[llgo] Roll gofrontend forward

Switch gofrontend to using go.googlesource.com, and
update to 81eb6a3f425b2158c67ee32c0cc973a72ce9d6be.

There are various changes required to update to the
go 1.5 runtime:

typemap.go is changed to accommodate the change in representation for equal/hash algorithms, and the removal of the zero value/type.
CMakeLists.txt is updated to add the build tree to the package search path, so internal packages, which are not installed, are found.
various files changes due to removal of __go_new_nopointers; the same change as in D11863, but with NoUnwindAttribute added to the added runtime functions which are called with "callOnly".
minor cleanups in ssa.go while investigating issues with unwinding/panic handling.

Differential Revisision: http://reviews.llvm.org/D15188

llvm-svn: 263536
GitOrigin-RevId: 6436a4abd7a2f3a60b230453295dba199d8a59c3
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 9c137f9..206f182 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -63,6 +63,7 @@
   ${CMAKE_CURRENT_SOURCE_DIR}/third_party/gofrontend/libgo/go/cmd/go/http.go
   ${CMAKE_CURRENT_SOURCE_DIR}/third_party/gofrontend/libgo/go/cmd/go/list.go
   ${CMAKE_CURRENT_SOURCE_DIR}/third_party/gofrontend/libgo/go/cmd/go/main.go
+  ${CMAKE_CURRENT_SOURCE_DIR}/third_party/gofrontend/libgo/go/cmd/go/note.go
   ${CMAKE_CURRENT_SOURCE_DIR}/third_party/gofrontend/libgo/go/cmd/go/pkg.go
   ${CMAKE_CURRENT_SOURCE_DIR}/third_party/gofrontend/libgo/go/cmd/go/run.go
   ${CMAKE_CURRENT_SOURCE_DIR}/third_party/gofrontend/libgo/go/cmd/go/signal.go
@@ -78,6 +79,7 @@
 
 add_custom_command(OUTPUT ${CMAKE_BINARY_DIR}/bin/llgo-go${CMAKE_EXECUTABLE_SUFFIX}
   COMMAND ${CMAKE_BINARY_DIR}/bin/llgo -static-libgo
+          -I ${CMAKE_CURRENT_BINARY_DIR}/libgo
           -o ${CMAKE_BINARY_DIR}/bin/llgo-go${CMAKE_EXECUTABLE_SUFFIX}
           ${LLGO_GO_SOURCES}
           ${CMAKE_CURRENT_BINARY_DIR}/libgo/zstdpkglist.go
diff --git a/autoconf/config.sub b/autoconf/config.sub
new file mode 100644
index 0000000..2583c90
--- /dev/null
+++ b/autoconf/config.sub
@@ -0,0 +1,1770 @@
+#! /bin/sh
+# Configuration validation subroutine script.
+#   Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
+#   2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
+#   2011 Free Software Foundation, Inc.
+
+timestamp='2011-11-02'
+
+# This file is (in principle) common to ALL GNU software.
+# The presence of a machine in this file suggests that SOME GNU software
+# can handle that machine.  It does not imply ALL GNU software can.
+#
+# This file is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
+# 02110-1301, USA.
+#
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+
+# Please send patches to <config-patches@gnu.org>.  Submit a context
+# diff and a properly formatted GNU ChangeLog entry.
+#
+# Configuration subroutine to validate and canonicalize a configuration type.
+# Supply the specified configuration type as an argument.
+# If it is invalid, we print an error message on stderr and exit with code 1.
+# Otherwise, we print the canonical config type on stdout and succeed.
+
+# You can get the latest version of this script from:
+# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD
+
+# This file is supposed to be the same for all GNU packages
+# and recognize all the CPU types, system types and aliases
+# that are meaningful with *any* GNU software.
+# Each package is responsible for reporting which valid configurations
+# it does not support.  The user should be able to distinguish
+# a failure to support a valid configuration from a meaningless
+# configuration.
+
+# The goal of this file is to map all the various variations of a given
+# machine specification into a single specification in the form:
+#	CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM
+# or in some cases, the newer four-part form:
+#	CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM
+# It is wrong to echo any other type of specification.
+
+me=`echo "$0" | sed -e 's,.*/,,'`
+
+usage="\
+Usage: $0 [OPTION] CPU-MFR-OPSYS
+       $0 [OPTION] ALIAS
+
+Canonicalize a configuration name.
+
+Operation modes:
+  -h, --help         print this help, then exit
+  -t, --time-stamp   print date of last modification, then exit
+  -v, --version      print version number, then exit
+
+Report bugs and patches to <config-patches@gnu.org>."
+
+version="\
+GNU config.sub ($timestamp)
+
+Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
+2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free
+Software Foundation, Inc.
+
+This is free software; see the source for copying conditions.  There is NO
+warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
+
+help="
+Try \`$me --help' for more information."
+
+# Parse command line
+while test $# -gt 0 ; do
+  case $1 in
+    --time-stamp | --time* | -t )
+       echo "$timestamp" ; exit ;;
+    --version | -v )
+       echo "$version" ; exit ;;
+    --help | --h* | -h )
+       echo "$usage"; exit ;;
+    -- )     # Stop option processing
+       shift; break ;;
+    - )	# Use stdin as input.
+       break ;;
+    -* )
+       echo "$me: invalid option $1$help"
+       exit 1 ;;
+
+    *local*)
+       # First pass through any local machine types.
+       echo $1
+       exit ;;
+
+    * )
+       break ;;
+  esac
+done
+
+case $# in
+ 0) echo "$me: missing argument$help" >&2
+    exit 1;;
+ 1) ;;
+ *) echo "$me: too many arguments$help" >&2
+    exit 1;;
+esac
+
+# Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any).
+# Here we must recognize all the valid KERNEL-OS combinations.
+maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'`
+case $maybe_os in
+  nto-qnx* | linux-gnu* | linux-android* | linux-dietlibc | linux-newlib* | \
+  linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | \
+  knetbsd*-gnu* | netbsd*-gnu* | \
+  kopensolaris*-gnu* | \
+  storm-chaos* | os2-emx* | rtmk-nova*)
+    os=-$maybe_os
+    basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`
+    ;;
+  *)
+    basic_machine=`echo $1 | sed 's/-[^-]*$//'`
+    if [ $basic_machine != $1 ]
+    then os=`echo $1 | sed 's/.*-/-/'`
+    else os=; fi
+    ;;
+esac
+
+### Let's recognize common machines as not being operating systems so
+### that things like config.sub decstation-3100 work.  We also
+### recognize some manufacturers as not being operating systems, so we
+### can provide default operating systems below.
+case $os in
+	-sun*os*)
+		# Prevent following clause from handling this invalid input.
+		;;
+	-dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \
+	-att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \
+	-unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \
+	-convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\
+	-c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \
+	-harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \
+	-apple | -axis | -knuth | -cray | -microblaze)
+		os=
+		basic_machine=$1
+		;;
+	-bluegene*)
+		os=-cnk
+		;;
+	-sim | -cisco | -oki | -wec | -winbond)
+		os=
+		basic_machine=$1
+		;;
+	-scout)
+		;;
+	-wrs)
+		os=-vxworks
+		basic_machine=$1
+		;;
+	-chorusos*)
+		os=-chorusos
+		basic_machine=$1
+		;;
+	-chorusrdb)
+		os=-chorusrdb
+		basic_machine=$1
+		;;
+	-hiux*)
+		os=-hiuxwe2
+		;;
+	-sco6)
+		os=-sco5v6
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-sco5)
+		os=-sco3.2v5
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-sco4)
+		os=-sco3.2v4
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-sco3.2.[4-9]*)
+		os=`echo $os | sed -e 's/sco3.2./sco3.2v/'`
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-sco3.2v[4-9]*)
+		# Don't forget version if it is 3.2v4 or newer.
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-sco5v6*)
+		# Don't forget version if it is 3.2v4 or newer.
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-sco*)
+		os=-sco3.2v2
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-udk*)
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-isc)
+		os=-isc2.2
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-clix*)
+		basic_machine=clipper-intergraph
+		;;
+	-isc*)
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-lynx*)
+		os=-lynxos
+		;;
+	-ptx*)
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'`
+		;;
+	-windowsnt*)
+		os=`echo $os | sed -e 's/windowsnt/winnt/'`
+		;;
+	-psos*)
+		os=-psos
+		;;
+	-mint | -mint[0-9]*)
+		basic_machine=m68k-atari
+		os=-mint
+		;;
+esac
+
+# Decode aliases for certain CPU-COMPANY combinations.
+case $basic_machine in
+	# Recognize the basic CPU types without company name.
+	# Some are omitted here because they have special meanings below.
+	1750a | 580 \
+	| a29k \
+	| alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \
+	| alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \
+	| am33_2.0 \
+	| arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr | avr32 \
+   | aarch64 | aarch64_be \
+   | be32 | be64 \
+	| bfin \
+	| c4x | clipper \
+	| d10v | d30v | dlx | dsp16xx \
+	| fido | fr30 | frv \
+	| hexagon \
+	| h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \
+	| i370 | i860 | i960 | ia64 \
+	| ip2k | iq2000 \
+	| le32 | le64 \
+	| lm32 \
+	| m32c | m32r | m32rle | m68000 | m68k | m88k \
+	| maxq | mb | microblaze | mcore | mep | metag \
+	| mips | mipsbe | mipseb | mipsel | mipsle \
+	| mips16 \
+	| mips64 | mips64el \
+	| mips64octeon | mips64octeonel \
+	| mips64orion | mips64orionel \
+	| mips64r5900 | mips64r5900el \
+	| mips64vr | mips64vrel \
+	| mips64vr4100 | mips64vr4100el \
+	| mips64vr4300 | mips64vr4300el \
+	| mips64vr5000 | mips64vr5000el \
+	| mips64vr5900 | mips64vr5900el \
+	| mipsisa32 | mipsisa32el \
+	| mipsisa32r2 | mipsisa32r2el \
+	| mipsisa64 | mipsisa64el \
+	| mipsisa64r2 | mipsisa64r2el \
+	| mipsisa64sb1 | mipsisa64sb1el \
+	| mipsisa64sr71k | mipsisa64sr71kel \
+	| mipstx39 | mipstx39el \
+	| mn10200 | mn10300 \
+	| moxie \
+	| mt \
+	| msp430 \
+	| nds32 | nds32le | nds32be \
+	| nios | nios2 \
+	| ns16k | ns32k \
+	| open8 \
+	| or32 \
+	| pdp10 | pdp11 | pj | pjl \
+	| powerpc | powerpc64 | powerpc64le | powerpcle \
+	| pyramid \
+	| rx \
+	| score \
+	| sh | sh[1234] | sh[24]a | sh[24]aeb | sh[23]e | sh[34]eb | sheb | shbe | shle | sh[1234]le | sh3ele \
+	| sh64 | sh64le \
+	| sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \
+	| sparcv8 | sparcv9 | sparcv9b | sparcv9v \
+	| spu \
+	| tahoe | tic4x | tic54x | tic55x | tic6x | tic80 | tron \
+	| ubicom32 \
+	| v850 | v850e | v850e1 | v850e2 | v850es | v850e2v3 \
+	| we32k \
+	| x86 | xc16x | xstormy16 | xtensa \
+	| z8k | z80)
+		basic_machine=$basic_machine-unknown
+		;;
+	c54x)
+		basic_machine=tic54x-unknown
+		;;
+	c55x)
+		basic_machine=tic55x-unknown
+		;;
+	c6x)
+		basic_machine=tic6x-unknown
+		;;
+	m6811 | m68hc11 | m6812 | m68hc12 | picochip)
+		# Motorola 68HC11/12.
+		basic_machine=$basic_machine-unknown
+		os=-none
+		;;
+	m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k)
+		;;
+	ms1)
+		basic_machine=mt-unknown
+		;;
+
+	strongarm | thumb | xscale)
+		basic_machine=arm-unknown
+		;;
+
+	xscaleeb)
+		basic_machine=armeb-unknown
+		;;
+
+	xscaleel)
+		basic_machine=armel-unknown
+		;;
+
+	# We use `pc' rather than `unknown'
+	# because (1) that's what they normally are, and
+	# (2) the word "unknown" tends to confuse beginning users.
+	i*86 | x86_64)
+	  basic_machine=$basic_machine-pc
+	  ;;
+	# Object if more than one company name word.
+	*-*-*)
+		echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2
+		exit 1
+		;;
+	# Recognize the basic CPU types with company name.
+	580-* \
+	| a29k-* \
+	| alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \
+	| alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \
+	| alphapca5[67]-* | alpha64pca5[67]-* | arc-* \
+	| arm-*  | armbe-* | armle-* | armeb-* | armv*-* \
+   | aarch64-* | aarch64_be-* \
+	| avr-* | avr32-* \
+	| be32-* | be64-* \
+	| bfin-* | bs2000-* \
+	| c[123]* | c30-* | [cjt]90-* | c4x-* \
+	| clipper-* | craynv-* | cydra-* \
+	| d10v-* | d30v-* | dlx-* \
+	| elxsi-* \
+	| f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \
+	| h8300-* | h8500-* \
+	| hexagon-* \
+	| hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \
+	| i*86-* | i860-* | i960-* | ia64-* \
+	| ip2k-* | iq2000-* \
+	| le32-* | le64-* \
+	| lm32-* \
+	| m32c-* | m32r-* | m32rle-* \
+	| m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \
+	| m88110-* | m88k-* | maxq-* | mcore-* | metag-* | microblaze-* \
+	| mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \
+	| mips16-* \
+	| mips64-* | mips64el-* \
+	| mips64octeon-* | mips64octeonel-* \
+	| mips64orion-* | mips64orionel-* \
+	| mips64r5900-* | mips64r5900el-* \
+	| mips64vr-* | mips64vrel-* \
+	| mips64vr4100-* | mips64vr4100el-* \
+	| mips64vr4300-* | mips64vr4300el-* \
+	| mips64vr5000-* | mips64vr5000el-* \
+	| mips64vr5900-* | mips64vr5900el-* \
+	| mipsisa32-* | mipsisa32el-* \
+	| mipsisa32r2-* | mipsisa32r2el-* \
+	| mipsisa64-* | mipsisa64el-* \
+	| mipsisa64r2-* | mipsisa64r2el-* \
+	| mipsisa64sb1-* | mipsisa64sb1el-* \
+	| mipsisa64sr71k-* | mipsisa64sr71kel-* \
+	| mipstx39-* | mipstx39el-* \
+	| mmix-* \
+	| mt-* \
+	| msp430-* \
+	| nds32-* | nds32le-* | nds32be-* \
+	| nios-* | nios2-* \
+	| none-* | np1-* | ns16k-* | ns32k-* \
+	| open8-* \
+	| orion-* \
+	| pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \
+	| powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* \
+	| pyramid-* \
+	| romp-* | rs6000-* | rx-* \
+	| sh-* | sh[1234]-* | sh[24]a-* | sh[24]aeb-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \
+	| shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \
+	| sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \
+	| sparclite-* \
+	| sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | sv1-* | sx?-* \
+	| tahoe-* \
+	| tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \
+	| tile*-* \
+	| tron-* \
+	| ubicom32-* \
+	| v850-* | v850e-* | v850e1-* | v850es-* | v850e2-* | v850e2v3-* \
+	| vax-* \
+	| we32k-* \
+	| x86-* | x86_64-* | xc16x-* | xps100-* \
+	| xstormy16-* | xtensa*-* \
+	| ymp-* \
+	| z8k-* | z80-*)
+		;;
+	# Recognize the basic CPU types without company name, with glob match.
+	xtensa*)
+		basic_machine=$basic_machine-unknown
+		;;
+	# Recognize the various machine names and aliases which stand
+	# for a CPU type and a company and sometimes even an OS.
+	386bsd)
+		basic_machine=i386-unknown
+		os=-bsd
+		;;
+	3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc)
+		basic_machine=m68000-att
+		;;
+	3b*)
+		basic_machine=we32k-att
+		;;
+	a29khif)
+		basic_machine=a29k-amd
+		os=-udi
+		;;
+	abacus)
+		basic_machine=abacus-unknown
+		;;
+	adobe68k)
+		basic_machine=m68010-adobe
+		os=-scout
+		;;
+	alliant | fx80)
+		basic_machine=fx80-alliant
+		;;
+	altos | altos3068)
+		basic_machine=m68k-altos
+		;;
+	am29k)
+		basic_machine=a29k-none
+		os=-bsd
+		;;
+	amd64)
+		basic_machine=x86_64-pc
+		;;
+	amd64-*)
+		basic_machine=x86_64-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	amdahl)
+		basic_machine=580-amdahl
+		os=-sysv
+		;;
+	amiga | amiga-*)
+		basic_machine=m68k-unknown
+		;;
+	amigaos | amigados)
+		basic_machine=m68k-unknown
+		os=-amigaos
+		;;
+	amigaunix | amix)
+		basic_machine=m68k-unknown
+		os=-sysv4
+		;;
+	apollo68)
+		basic_machine=m68k-apollo
+		os=-sysv
+		;;
+	apollo68bsd)
+		basic_machine=m68k-apollo
+		os=-bsd
+		;;
+	aros)
+		basic_machine=i386-pc
+		os=-aros
+		;;
+	aux)
+		basic_machine=m68k-apple
+		os=-aux
+		;;
+	balance)
+		basic_machine=ns32k-sequent
+		os=-dynix
+		;;
+	blackfin)
+		basic_machine=bfin-unknown
+		os=-linux
+		;;
+	blackfin-*)
+		basic_machine=bfin-`echo $basic_machine | sed 's/^[^-]*-//'`
+		os=-linux
+		;;
+	bluegene*)
+		basic_machine=powerpc-ibm
+		os=-cnk
+		;;
+	c54x-*)
+		basic_machine=tic54x-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	c55x-*)
+		basic_machine=tic55x-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	c6x-*)
+		basic_machine=tic6x-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	c90)
+		basic_machine=c90-cray
+		os=-unicos
+		;;
+	cegcc)
+		basic_machine=arm-unknown
+		os=-cegcc
+		;;
+	convex-c1)
+		basic_machine=c1-convex
+		os=-bsd
+		;;
+	convex-c2)
+		basic_machine=c2-convex
+		os=-bsd
+		;;
+	convex-c32)
+		basic_machine=c32-convex
+		os=-bsd
+		;;
+	convex-c34)
+		basic_machine=c34-convex
+		os=-bsd
+		;;
+	convex-c38)
+		basic_machine=c38-convex
+		os=-bsd
+		;;
+	cray | j90)
+		basic_machine=j90-cray
+		os=-unicos
+		;;
+	craynv)
+		basic_machine=craynv-cray
+		os=-unicosmp
+		;;
+	cr16 | cr16-*)
+		basic_machine=cr16-unknown
+		os=-elf
+		;;
+	crds | unos)
+		basic_machine=m68k-crds
+		;;
+	crisv32 | crisv32-* | etraxfs*)
+		basic_machine=crisv32-axis
+		;;
+	cris | cris-* | etrax*)
+		basic_machine=cris-axis
+		;;
+	crx)
+		basic_machine=crx-unknown
+		os=-elf
+		;;
+	da30 | da30-*)
+		basic_machine=m68k-da30
+		;;
+	decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn)
+		basic_machine=mips-dec
+		;;
+	decsystem10* | dec10*)
+		basic_machine=pdp10-dec
+		os=-tops10
+		;;
+	decsystem20* | dec20*)
+		basic_machine=pdp10-dec
+		os=-tops20
+		;;
+	delta | 3300 | motorola-3300 | motorola-delta \
+	      | 3300-motorola | delta-motorola)
+		basic_machine=m68k-motorola
+		;;
+	delta88)
+		basic_machine=m88k-motorola
+		os=-sysv3
+		;;
+	dicos)
+		basic_machine=i686-pc
+		os=-dicos
+		;;
+	djgpp)
+		basic_machine=i586-pc
+		os=-msdosdjgpp
+		;;
+	dpx20 | dpx20-*)
+		basic_machine=rs6000-bull
+		os=-bosx
+		;;
+	dpx2* | dpx2*-bull)
+		basic_machine=m68k-bull
+		os=-sysv3
+		;;
+	ebmon29k)
+		basic_machine=a29k-amd
+		os=-ebmon
+		;;
+	elxsi)
+		basic_machine=elxsi-elxsi
+		os=-bsd
+		;;
+	encore | umax | mmax)
+		basic_machine=ns32k-encore
+		;;
+	es1800 | OSE68k | ose68k | ose | OSE)
+		basic_machine=m68k-ericsson
+		os=-ose
+		;;
+	fx2800)
+		basic_machine=i860-alliant
+		;;
+	genix)
+		basic_machine=ns32k-ns
+		;;
+	gmicro)
+		basic_machine=tron-gmicro
+		os=-sysv
+		;;
+	go32)
+		basic_machine=i386-pc
+		os=-go32
+		;;
+	h3050r* | hiux*)
+		basic_machine=hppa1.1-hitachi
+		os=-hiuxwe2
+		;;
+	h8300hms)
+		basic_machine=h8300-hitachi
+		os=-hms
+		;;
+	h8300xray)
+		basic_machine=h8300-hitachi
+		os=-xray
+		;;
+	h8500hms)
+		basic_machine=h8500-hitachi
+		os=-hms
+		;;
+	harris)
+		basic_machine=m88k-harris
+		os=-sysv3
+		;;
+	hp300-*)
+		basic_machine=m68k-hp
+		;;
+	hp300bsd)
+		basic_machine=m68k-hp
+		os=-bsd
+		;;
+	hp300hpux)
+		basic_machine=m68k-hp
+		os=-hpux
+		;;
+	hp3k9[0-9][0-9] | hp9[0-9][0-9])
+		basic_machine=hppa1.0-hp
+		;;
+	hp9k2[0-9][0-9] | hp9k31[0-9])
+		basic_machine=m68000-hp
+		;;
+	hp9k3[2-9][0-9])
+		basic_machine=m68k-hp
+		;;
+	hp9k6[0-9][0-9] | hp6[0-9][0-9])
+		basic_machine=hppa1.0-hp
+		;;
+	hp9k7[0-79][0-9] | hp7[0-79][0-9])
+		basic_machine=hppa1.1-hp
+		;;
+	hp9k78[0-9] | hp78[0-9])
+		# FIXME: really hppa2.0-hp
+		basic_machine=hppa1.1-hp
+		;;
+	hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893)
+		# FIXME: really hppa2.0-hp
+		basic_machine=hppa1.1-hp
+		;;
+	hp9k8[0-9][13679] | hp8[0-9][13679])
+		basic_machine=hppa1.1-hp
+		;;
+	hp9k8[0-9][0-9] | hp8[0-9][0-9])
+		basic_machine=hppa1.0-hp
+		;;
+	hppa-next)
+		os=-nextstep3
+		;;
+	hppaosf)
+		basic_machine=hppa1.1-hp
+		os=-osf
+		;;
+	hppro)
+		basic_machine=hppa1.1-hp
+		os=-proelf
+		;;
+	i370-ibm* | ibm*)
+		basic_machine=i370-ibm
+		;;
+# I'm not sure what "Sysv32" means.  Should this be sysv3.2?
+	i*86v32)
+		basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+		os=-sysv32
+		;;
+	i*86v4*)
+		basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+		os=-sysv4
+		;;
+	i*86v)
+		basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+		os=-sysv
+		;;
+	i*86sol2)
+		basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+		os=-solaris2
+		;;
+	i386mach)
+		basic_machine=i386-mach
+		os=-mach
+		;;
+	i386-vsta | vsta)
+		basic_machine=i386-unknown
+		os=-vsta
+		;;
+	iris | iris4d)
+		basic_machine=mips-sgi
+		case $os in
+		    -irix*)
+			;;
+		    *)
+			os=-irix4
+			;;
+		esac
+		;;
+	isi68 | isi)
+		basic_machine=m68k-isi
+		os=-sysv
+		;;
+	m68knommu)
+		basic_machine=m68k-unknown
+		os=-linux
+		;;
+	m68knommu-*)
+		basic_machine=m68k-`echo $basic_machine | sed 's/^[^-]*-//'`
+		os=-linux
+		;;
+	m88k-omron*)
+		basic_machine=m88k-omron
+		;;
+	magnum | m3230)
+		basic_machine=mips-mips
+		os=-sysv
+		;;
+	merlin)
+		basic_machine=ns32k-utek
+		os=-sysv
+		;;
+	microblaze)
+		basic_machine=microblaze-xilinx
+		;;
+	mingw32)
+		basic_machine=i386-pc
+		os=-mingw32
+		;;
+	mingw32ce)
+		basic_machine=arm-unknown
+		os=-mingw32ce
+		;;
+	miniframe)
+		basic_machine=m68000-convergent
+		;;
+	*mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*)
+		basic_machine=m68k-atari
+		os=-mint
+		;;
+	mips3*-*)
+		basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`
+		;;
+	mips3*)
+		basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown
+		;;
+	monitor)
+		basic_machine=m68k-rom68k
+		os=-coff
+		;;
+	morphos)
+		basic_machine=powerpc-unknown
+		os=-morphos
+		;;
+	msdos)
+		basic_machine=i386-pc
+		os=-msdos
+		;;
+	ms1-*)
+		basic_machine=`echo $basic_machine | sed -e 's/ms1-/mt-/'`
+		;;
+	mvs)
+		basic_machine=i370-ibm
+		os=-mvs
+		;;
+	nacl)
+		basic_machine=le32-unknown
+		os=-nacl
+		;;
+	ncr3000)
+		basic_machine=i486-ncr
+		os=-sysv4
+		;;
+	netbsd386)
+		basic_machine=i386-unknown
+		os=-netbsd
+		;;
+	netwinder)
+		basic_machine=armv4l-rebel
+		os=-linux
+		;;
+	news | news700 | news800 | news900)
+		basic_machine=m68k-sony
+		os=-newsos
+		;;
+	news1000)
+		basic_machine=m68030-sony
+		os=-newsos
+		;;
+	news-3600 | risc-news)
+		basic_machine=mips-sony
+		os=-newsos
+		;;
+	necv70)
+		basic_machine=v70-nec
+		os=-sysv
+		;;
+	next | m*-next )
+		basic_machine=m68k-next
+		case $os in
+		    -nextstep* )
+			;;
+		    -ns2*)
+		      os=-nextstep2
+			;;
+		    *)
+		      os=-nextstep3
+			;;
+		esac
+		;;
+	nh3000)
+		basic_machine=m68k-harris
+		os=-cxux
+		;;
+	nh[45]000)
+		basic_machine=m88k-harris
+		os=-cxux
+		;;
+	nindy960)
+		basic_machine=i960-intel
+		os=-nindy
+		;;
+	mon960)
+		basic_machine=i960-intel
+		os=-mon960
+		;;
+	nonstopux)
+		basic_machine=mips-compaq
+		os=-nonstopux
+		;;
+	np1)
+		basic_machine=np1-gould
+		;;
+	neo-tandem)
+		basic_machine=neo-tandem
+		;;
+	nse-tandem)
+		basic_machine=nse-tandem
+		;;
+	nsr-tandem)
+		basic_machine=nsr-tandem
+		;;
+	op50n-* | op60c-*)
+		basic_machine=hppa1.1-oki
+		os=-proelf
+		;;
+	openrisc | openrisc-*)
+		basic_machine=or32-unknown
+		;;
+	os400)
+		basic_machine=powerpc-ibm
+		os=-os400
+		;;
+	OSE68000 | ose68000)
+		basic_machine=m68000-ericsson
+		os=-ose
+		;;
+	os68k)
+		basic_machine=m68k-none
+		os=-os68k
+		;;
+	pa-hitachi)
+		basic_machine=hppa1.1-hitachi
+		os=-hiuxwe2
+		;;
+	paragon)
+		basic_machine=i860-intel
+		os=-osf
+		;;
+	parisc)
+		basic_machine=hppa-unknown
+		os=-linux
+		;;
+	parisc-*)
+		basic_machine=hppa-`echo $basic_machine | sed 's/^[^-]*-//'`
+		os=-linux
+		;;
+	pbd)
+		basic_machine=sparc-tti
+		;;
+	pbb)
+		basic_machine=m68k-tti
+		;;
+	pc532 | pc532-*)
+		basic_machine=ns32k-pc532
+		;;
+	pc98)
+		basic_machine=i386-pc
+		;;
+	pc98-*)
+		basic_machine=i386-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	pentium | p5 | k5 | k6 | nexgen | viac3)
+		basic_machine=i586-pc
+		;;
+	pentiumpro | p6 | 6x86 | athlon | athlon_*)
+		basic_machine=i686-pc
+		;;
+	pentiumii | pentium2 | pentiumiii | pentium3)
+		basic_machine=i686-pc
+		;;
+	pentium4)
+		basic_machine=i786-pc
+		;;
+	pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*)
+		basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	pentiumpro-* | p6-* | 6x86-* | athlon-*)
+		basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*)
+		basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	pentium4-*)
+		basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	pn)
+		basic_machine=pn-gould
+		;;
+	power)	basic_machine=power-ibm
+		;;
+	ppc | ppcbe)	basic_machine=powerpc-unknown
+		;;
+	ppc-* | ppcbe-*)
+		basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	ppcle | powerpclittle | ppc-le | powerpc-little)
+		basic_machine=powerpcle-unknown
+		;;
+	ppcle-* | powerpclittle-*)
+		basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	ppc64)	basic_machine=powerpc64-unknown
+		;;
+	ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	ppc64le | powerpc64little | ppc64-le | powerpc64-little)
+		basic_machine=powerpc64le-unknown
+		;;
+	ppc64le-* | powerpc64little-*)
+		basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	ps2)
+		basic_machine=i386-ibm
+		;;
+	pw32)
+		basic_machine=i586-unknown
+		os=-pw32
+		;;
+	rdos)
+		basic_machine=i386-pc
+		os=-rdos
+		;;
+	rom68k)
+		basic_machine=m68k-rom68k
+		os=-coff
+		;;
+	rm[46]00)
+		basic_machine=mips-siemens
+		;;
+	rtpc | rtpc-*)
+		basic_machine=romp-ibm
+		;;
+	s390 | s390-*)
+		basic_machine=s390-ibm
+		;;
+	s390x | s390x-*)
+		basic_machine=s390x-ibm
+		;;
+	sa29200)
+		basic_machine=a29k-amd
+		os=-udi
+		;;
+	sb1)
+		basic_machine=mipsisa64sb1-unknown
+		;;
+	sb1el)
+		basic_machine=mipsisa64sb1el-unknown
+		;;
+	sde)
+		basic_machine=mipsisa32-sde
+		os=-elf
+		;;
+	sei)
+		basic_machine=mips-sei
+		os=-seiux
+		;;
+	sequent)
+		basic_machine=i386-sequent
+		;;
+	sh)
+		basic_machine=sh-hitachi
+		os=-hms
+		;;
+	sh5el)
+		basic_machine=sh5le-unknown
+		;;
+	sh64)
+		basic_machine=sh64-unknown
+		;;
+	sparclite-wrs | simso-wrs)
+		basic_machine=sparclite-wrs
+		os=-vxworks
+		;;
+	sps7)
+		basic_machine=m68k-bull
+		os=-sysv2
+		;;
+	spur)
+		basic_machine=spur-unknown
+		;;
+	st2000)
+		basic_machine=m68k-tandem
+		;;
+	stratus)
+		basic_machine=i860-stratus
+		os=-sysv4
+		;;
+	strongarm-* | thumb-*)
+		basic_machine=arm-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	sun2)
+		basic_machine=m68000-sun
+		;;
+	sun2os3)
+		basic_machine=m68000-sun
+		os=-sunos3
+		;;
+	sun2os4)
+		basic_machine=m68000-sun
+		os=-sunos4
+		;;
+	sun3os3)
+		basic_machine=m68k-sun
+		os=-sunos3
+		;;
+	sun3os4)
+		basic_machine=m68k-sun
+		os=-sunos4
+		;;
+	sun4os3)
+		basic_machine=sparc-sun
+		os=-sunos3
+		;;
+	sun4os4)
+		basic_machine=sparc-sun
+		os=-sunos4
+		;;
+	sun4sol2)
+		basic_machine=sparc-sun
+		os=-solaris2
+		;;
+	sun3 | sun3-*)
+		basic_machine=m68k-sun
+		;;
+	sun4)
+		basic_machine=sparc-sun
+		;;
+	sun386 | sun386i | roadrunner)
+		basic_machine=i386-sun
+		;;
+	sv1)
+		basic_machine=sv1-cray
+		os=-unicos
+		;;
+	symmetry)
+		basic_machine=i386-sequent
+		os=-dynix
+		;;
+	t3e)
+		basic_machine=alphaev5-cray
+		os=-unicos
+		;;
+	t90)
+		basic_machine=t90-cray
+		os=-unicos
+		;;
+	tile*)
+		basic_machine=$basic_machine-unknown
+		os=-linux-gnu
+		;;
+	tx39)
+		basic_machine=mipstx39-unknown
+		;;
+	tx39el)
+		basic_machine=mipstx39el-unknown
+		;;
+	toad1)
+		basic_machine=pdp10-xkl
+		os=-tops20
+		;;
+	tower | tower-32)
+		basic_machine=m68k-ncr
+		;;
+	tpf)
+		basic_machine=s390x-ibm
+		os=-tpf
+		;;
+	udi29k)
+		basic_machine=a29k-amd
+		os=-udi
+		;;
+	ultra3)
+		basic_machine=a29k-nyu
+		os=-sym1
+		;;
+	v810 | necv810)
+		basic_machine=v810-nec
+		os=-none
+		;;
+	vaxv)
+		basic_machine=vax-dec
+		os=-sysv
+		;;
+	vms)
+		basic_machine=vax-dec
+		os=-vms
+		;;
+	vpp*|vx|vx-*)
+		basic_machine=f301-fujitsu
+		;;
+	vxworks960)
+		basic_machine=i960-wrs
+		os=-vxworks
+		;;
+	vxworks68)
+		basic_machine=m68k-wrs
+		os=-vxworks
+		;;
+	vxworks29k)
+		basic_machine=a29k-wrs
+		os=-vxworks
+		;;
+	w65*)
+		basic_machine=w65-wdc
+		os=-none
+		;;
+	w89k-*)
+		basic_machine=hppa1.1-winbond
+		os=-proelf
+		;;
+	xbox)
+		basic_machine=i686-pc
+		os=-mingw32
+		;;
+	xps | xps100)
+		basic_machine=xps100-honeywell
+		;;
+	xscale-* | xscalee[bl]-*)
+		basic_machine=`echo $basic_machine | sed 's/^xscale/arm/'`
+		;;
+	ymp)
+		basic_machine=ymp-cray
+		os=-unicos
+		;;
+	z8k-*-coff)
+		basic_machine=z8k-unknown
+		os=-sim
+		;;
+	z80-*-coff)
+		basic_machine=z80-unknown
+		os=-sim
+		;;
+	none)
+		basic_machine=none-none
+		os=-none
+		;;
+
+# Here we handle the default manufacturer of certain CPU types.  It is in
+# some cases the only manufacturer, in others, it is the most popular.
+	w89k)
+		basic_machine=hppa1.1-winbond
+		;;
+	op50n)
+		basic_machine=hppa1.1-oki
+		;;
+	op60c)
+		basic_machine=hppa1.1-oki
+		;;
+	romp)
+		basic_machine=romp-ibm
+		;;
+	mmix)
+		basic_machine=mmix-knuth
+		;;
+	rs6000)
+		basic_machine=rs6000-ibm
+		;;
+	vax)
+		basic_machine=vax-dec
+		;;
+	pdp10)
+		# there are many clones, so DEC is not a safe bet
+		basic_machine=pdp10-unknown
+		;;
+	pdp11)
+		basic_machine=pdp11-dec
+		;;
+	we32k)
+		basic_machine=we32k-att
+		;;
+	sh[1234] | sh[24]a | sh[24]aeb | sh[34]eb | sh[1234]le | sh[23]ele)
+		basic_machine=sh-unknown
+		;;
+	sparc | sparcv8 | sparcv9 | sparcv9b | sparcv9v)
+		basic_machine=sparc-sun
+		;;
+	cydra)
+		basic_machine=cydra-cydrome
+		;;
+	orion)
+		basic_machine=orion-highlevel
+		;;
+	orion105)
+		basic_machine=clipper-highlevel
+		;;
+	mac | mpw | mac-mpw)
+		basic_machine=m68k-apple
+		;;
+	pmac | pmac-mpw)
+		basic_machine=powerpc-apple
+		;;
+	*-unknown)
+		# Make sure to match an already-canonicalized machine name.
+		;;
+	*)
+		echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2
+		exit 1
+		;;
+esac
+
+# Here we canonicalize certain aliases for manufacturers.
+case $basic_machine in
+	*-digital*)
+		basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'`
+		;;
+	*-commodore*)
+		basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'`
+		;;
+	*)
+		;;
+esac
+
+# Decode manufacturer-specific aliases for certain operating systems.
+
+if [ x"$os" != x"" ]
+then
+case $os in
+	# First match some system type aliases
+	# that might get confused with valid system types.
+	# -solaris* is a basic system type, with this one exception.
+	-auroraux)
+		os=-auroraux
+		;;
+	-solaris1 | -solaris1.*)
+		os=`echo $os | sed -e 's|solaris1|sunos4|'`
+		;;
+	-solaris)
+		os=-solaris2
+		;;
+	-svr4*)
+		os=-sysv4
+		;;
+	-unixware*)
+		os=-sysv4.2uw
+		;;
+	-gnu/linux*)
+		os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'`
+		;;
+	# First accept the basic system types.
+	# The portable systems comes first.
+	# Each alternative MUST END IN A *, to match a version number.
+	# -sysv* is not here because it comes later, after sysvr4.
+	-gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \
+	      | -*vms* | -sco* | -esix* | -isc* | -aix* | -cnk* | -sunos | -sunos[34]*\
+	      | -hpux* | -unos* | -osf* | -luna* | -dgux* | -auroraux* | -solaris* \
+	      | -sym* | -kopensolaris* \
+	      | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \
+	      | -aos* | -aros* \
+	      | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \
+	      | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \
+	      | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \
+	      | -openbsd* | -solidbsd* \
+	      | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \
+	      | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \
+	      | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \
+	      | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \
+	      | -chorusos* | -chorusrdb* | -cegcc* \
+	      | -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
+	      | -mingw32* | -linux-gnu* | -linux-android* \
+	      | -linux-newlib* | -linux-uclibc* \
+	      | -uxpv* | -beos* | -mpeix* | -udk* \
+	      | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \
+	      | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \
+	      | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \
+	      | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \
+	      | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \
+	      | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \
+	      | -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -es* | -bitrig*)
+	# Remember, each alternative MUST END IN *, to match a version number.
+		;;
+	-qnx*)
+		case $basic_machine in
+		    x86-* | i*86-*)
+			;;
+		    *)
+			os=-nto$os
+			;;
+		esac
+		;;
+	-nto-qnx*)
+		;;
+	-nto*)
+		os=`echo $os | sed -e 's|nto|nto-qnx|'`
+		;;
+	-sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \
+	      | -windows* | -osx | -abug | -netware* | -os9* | -beos* | -haiku* \
+	      | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*)
+		;;
+	-mac*)
+		os=`echo $os | sed -e 's|mac|macos|'`
+		;;
+	-linux-dietlibc)
+		os=-linux-dietlibc
+		;;
+	-linux*)
+		os=`echo $os | sed -e 's|linux|linux-gnu|'`
+		;;
+	-sunos5*)
+		os=`echo $os | sed -e 's|sunos5|solaris2|'`
+		;;
+	-sunos6*)
+		os=`echo $os | sed -e 's|sunos6|solaris3|'`
+		;;
+	-opened*)
+		os=-openedition
+		;;
+	-os400*)
+		os=-os400
+		;;
+	-wince*)
+		os=-wince
+		;;
+	-osfrose*)
+		os=-osfrose
+		;;
+	-osf*)
+		os=-osf
+		;;
+	-utek*)
+		os=-bsd
+		;;
+	-dynix*)
+		os=-bsd
+		;;
+	-acis*)
+		os=-aos
+		;;
+	-atheos*)
+		os=-atheos
+		;;
+	-syllable*)
+		os=-syllable
+		;;
+	-386bsd)
+		os=-bsd
+		;;
+	-ctix* | -uts*)
+		os=-sysv
+		;;
+	-nova*)
+		os=-rtmk-nova
+		;;
+	-ns2 )
+		os=-nextstep2
+		;;
+	-nsk*)
+		os=-nsk
+		;;
+	# Preserve the version number of sinix5.
+	-sinix5.*)
+		os=`echo $os | sed -e 's|sinix|sysv|'`
+		;;
+	-sinix*)
+		os=-sysv4
+		;;
+	-tpf*)
+		os=-tpf
+		;;
+	-triton*)
+		os=-sysv3
+		;;
+	-oss*)
+		os=-sysv3
+		;;
+	-svr4)
+		os=-sysv4
+		;;
+	-svr3)
+		os=-sysv3
+		;;
+	-sysvr4)
+		os=-sysv4
+		;;
+	# This must come after -sysvr4.
+	-sysv*)
+		;;
+	-ose*)
+		os=-ose
+		;;
+	-es1800*)
+		os=-ose
+		;;
+	-xenix)
+		os=-xenix
+		;;
+	-*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)
+		os=-mint
+		;;
+	-aros*)
+		os=-aros
+		;;
+	-kaos*)
+		os=-kaos
+		;;
+	-zvmoe)
+		os=-zvmoe
+		;;
+	-dicos*)
+		os=-dicos
+		;;
+	-nacl*)
+		;;
+	-ps4)
+		;;
+	-none)
+		;;
+	*)
+		# Get rid of the `-' at the beginning of $os.
+		os=`echo $os | sed 's/[^-]*-//'`
+		echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2
+		exit 1
+		;;
+esac
+else
+
+# Here we handle the default operating systems that come with various machines.
+# The value should be what the vendor currently ships out the door with their
+# machine or put another way, the most popular os provided with the machine.
+
+# Note that if you're going to try to match "-MANUFACTURER" here (say,
+# "-sun"), then you have to tell the case statement up towards the top
+# that MANUFACTURER isn't an operating system.  Otherwise, code above
+# will signal an error saying that MANUFACTURER isn't an operating
+# system, and we'll never get to this point.
+
+case $basic_machine in
+	score-*)
+		os=-elf
+		;;
+	spu-*)
+		os=-elf
+		;;
+	*-acorn)
+		os=-riscix1.2
+		;;
+	arm*-rebel)
+		os=-linux
+		;;
+	arm*-semi)
+		os=-aout
+		;;
+	c4x-* | tic4x-*)
+		os=-coff
+		;;
+	tic54x-*)
+		os=-coff
+		;;
+	tic55x-*)
+		os=-coff
+		;;
+	tic6x-*)
+		os=-coff
+		;;
+	# This must come before the *-dec entry.
+	pdp10-*)
+		os=-tops20
+		;;
+	pdp11-*)
+		os=-none
+		;;
+	*-dec | vax-*)
+		os=-ultrix4.2
+		;;
+	m68*-apollo)
+		os=-domain
+		;;
+	i386-sun)
+		os=-sunos4.0.2
+		;;
+	m68000-sun)
+		os=-sunos3
+		# This also exists in the configure program, but was not the
+		# default.
+		# os=-sunos4
+		;;
+	m68*-cisco)
+		os=-aout
+		;;
+	mep-*)
+		os=-elf
+		;;
+	mips*-cisco)
+		os=-elf
+		;;
+	mips*-*)
+		os=-elf
+		;;
+	or32-*)
+		os=-coff
+		;;
+	*-tti)	# must be before sparc entry or we get the wrong os.
+		os=-sysv3
+		;;
+	sparc-* | *-sun)
+		os=-sunos4.1.1
+		;;
+	*-be)
+		os=-beos
+		;;
+	*-haiku)
+		os=-haiku
+		;;
+	*-ibm)
+		os=-aix
+		;;
+	*-knuth)
+		os=-mmixware
+		;;
+	*-wec)
+		os=-proelf
+		;;
+	*-winbond)
+		os=-proelf
+		;;
+	*-oki)
+		os=-proelf
+		;;
+	*-hp)
+		os=-hpux
+		;;
+	*-hitachi)
+		os=-hiux
+		;;
+	i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent)
+		os=-sysv
+		;;
+	*-cbm)
+		os=-amigaos
+		;;
+	*-dg)
+		os=-dgux
+		;;
+	*-dolphin)
+		os=-sysv3
+		;;
+	m68k-ccur)
+		os=-rtu
+		;;
+	m88k-omron*)
+		os=-luna
+		;;
+	*-next )
+		os=-nextstep
+		;;
+	*-sequent)
+		os=-ptx
+		;;
+	*-crds)
+		os=-unos
+		;;
+	*-ns)
+		os=-genix
+		;;
+	i370-*)
+		os=-mvs
+		;;
+	*-next)
+		os=-nextstep3
+		;;
+	*-gould)
+		os=-sysv
+		;;
+	*-highlevel)
+		os=-bsd
+		;;
+	*-encore)
+		os=-bsd
+		;;
+	*-sgi)
+		os=-irix
+		;;
+	*-siemens)
+		os=-sysv4
+		;;
+	*-masscomp)
+		os=-rtu
+		;;
+	f30[01]-fujitsu | f700-fujitsu)
+		os=-uxpv
+		;;
+	*-rom68k)
+		os=-coff
+		;;
+	*-*bug)
+		os=-coff
+		;;
+	*-apple)
+		os=-macos
+		;;
+	*-atari*)
+		os=-mint
+		;;
+	*)
+		os=-none
+		;;
+esac
+fi
+
+# Here we handle the case where we know the os, and the CPU type, but not the
+# manufacturer.  We pick the logical manufacturer.
+vendor=unknown
+case $basic_machine in
+	*-unknown)
+		case $os in
+			-riscix*)
+				vendor=acorn
+				;;
+			-sunos*)
+				vendor=sun
+				;;
+			-cnk*|-aix*)
+				vendor=ibm
+				;;
+			-beos*)
+				vendor=be
+				;;
+			-hpux*)
+				vendor=hp
+				;;
+			-mpeix*)
+				vendor=hp
+				;;
+			-hiux*)
+				vendor=hitachi
+				;;
+			-unos*)
+				vendor=crds
+				;;
+			-dgux*)
+				vendor=dg
+				;;
+			-luna*)
+				vendor=omron
+				;;
+			-genix*)
+				vendor=ns
+				;;
+			-mvs* | -opened*)
+				vendor=ibm
+				;;
+			-os400*)
+				vendor=ibm
+				;;
+			-ptx*)
+				vendor=sequent
+				;;
+			-tpf*)
+				vendor=ibm
+				;;
+			-vxsim* | -vxworks* | -windiss*)
+				vendor=wrs
+				;;
+			-aux*)
+				vendor=apple
+				;;
+			-hms*)
+				vendor=hitachi
+				;;
+			-mpw* | -macos*)
+				vendor=apple
+				;;
+			-*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)
+				vendor=atari
+				;;
+			-vos*)
+				vendor=stratus
+				;;
+		esac
+		basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"`
+		;;
+esac
+
+echo $basic_machine$os
+exit
+
+# Local variables:
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "timestamp='"
+# time-stamp-format: "%:y-%02m-%02d"
+# time-stamp-end: "'"
+# End:
diff --git a/cmd/gllgo/gllgo.go b/cmd/gllgo/gllgo.go
index 11038a3..a93cb1d 100644
--- a/cmd/gllgo/gllgo.go
+++ b/cmd/gllgo/gllgo.go
@@ -487,9 +487,6 @@
 	pmb.SetOptLevel(opts.optLevel)
 	pmb.SetSizeLevel(opts.sizeLevel)
 
-	target := tm.TargetData()
-	mpm.Add(target)
-	fpm.Add(target)
 	tm.AddAnalysisPasses(mpm)
 	tm.AddAnalysisPasses(fpm)
 
@@ -746,7 +743,7 @@
 			if opts.staticLibgo {
 				args = append(args, "-Wl,-Bstatic", "-lgo-llgo", "-Wl,-Bdynamic", "-lpthread", "-lm")
 			} else {
-				args = append(args, "-lgo-llgo")
+				args = append(args, "-lgo-llgo", "-lm")
 			}
 		} else {
 			linkerPath = opts.gccgoPath
diff --git a/irgen/runtime.go b/irgen/runtime.go
index c58d9df..6e131ce 100644
--- a/irgen/runtime.go
+++ b/irgen/runtime.go
@@ -64,6 +64,7 @@
 	// Runtime intrinsics
 	append,
 	assertInterface,
+	byteArrayToString,
 	canRecover,
 	chanCap,
 	chanLen,
@@ -92,7 +93,6 @@
 	New,
 	newChannel,
 	newMap,
-	NewNopointers,
 	newSelect,
 	panic,
 	printBool,
@@ -121,6 +121,7 @@
 	stringiter2,
 	stringPlus,
 	stringSlice,
+	stringToByteArray,
 	stringToIntArray,
 	typeDescriptorsEqual,
 	undefer runtimeFnInfo
@@ -141,6 +142,7 @@
 	UnsafePointer := types.Typ[types.UnsafePointer]
 
 	EmptyInterface := types.NewInterface(nil, nil)
+	ByteSlice := types.NewSlice(types.Typ[types.Byte])
 	IntSlice := types.NewSlice(types.Typ[types.Int])
 
 	for _, rt := range [...]struct {
@@ -162,6 +164,13 @@
 			res:  []types.Type{UnsafePointer},
 		},
 		{
+			name:  "__go_byte_array_to_string",
+			rfi:   &ri.byteArrayToString,
+			args:  []types.Type{UnsafePointer, Int},
+			res:   []types.Type{String},
+			attrs: []llvm.Attribute{llvm.NoUnwindAttribute},
+		},
+		{
 			name: "__go_can_recover",
 			rfi:  &ri.canRecover,
 			args: []types.Type{UnsafePointer},
@@ -301,10 +310,11 @@
 			res:  []types.Type{Int},
 		},
 		{
-			name: "__go_new",
-			rfi:  &ri.New,
-			args: []types.Type{UnsafePointer, Uintptr},
-			res:  []types.Type{UnsafePointer},
+			name:  "__go_new",
+			rfi:   &ri.New,
+			args:  []types.Type{UnsafePointer, Uintptr},
+			res:   []types.Type{UnsafePointer},
+			attrs: []llvm.Attribute{llvm.NoUnwindAttribute},
 		},
 		{
 			name: "__go_new_channel",
@@ -319,12 +329,6 @@
 			res:  []types.Type{UnsafePointer},
 		},
 		{
-			name: "__go_new_nopointers",
-			rfi:  &ri.NewNopointers,
-			args: []types.Type{UnsafePointer, Uintptr},
-			res:  []types.Type{UnsafePointer},
-		},
-		{
 			name: "runtime.newselect",
 			rfi:  &ri.newSelect,
 			args: []types.Type{Int32},
@@ -466,6 +470,13 @@
 			res:  []types.Type{String},
 		},
 		{
+			name:  "__go_string_to_byte_array",
+			rfi:   &ri.stringToByteArray,
+			args:  []types.Type{String},
+			res:   []types.Type{ByteSlice},
+			attrs: []llvm.Attribute{llvm.NoUnwindAttribute},
+		},
+		{
 			name: "__go_string_to_int_array",
 			rfi:  &ri.stringToIntArray,
 			args: []types.Type{String},
@@ -563,12 +574,6 @@
 	return v
 }
 
-func (fr *frame) createMalloc(size llvm.Value) llvm.Value {
-	return fr.runtime.NewNopointers.callOnly(fr,
-		llvm.ConstNull(llvm.PointerType(llvm.Int8Type(), 0)),
-		fr.createZExtOrTrunc(size, fr.target.IntPtrType(), ""))[0]
-}
-
 func (fr *frame) createTypeMalloc(t types.Type) llvm.Value {
 	size := llvm.ConstInt(fr.target.IntPtrType(), uint64(fr.llvmtypes.Sizeof(t)), false)
 	malloc := fr.runtime.New.callOnly(fr, fr.types.ToRuntime(t), size)[0]
diff --git a/irgen/ssa.go b/irgen/ssa.go
index 04570a8..4c7b1a6 100644
--- a/irgen/ssa.go
+++ b/irgen/ssa.go
@@ -402,7 +402,7 @@
 	// an unwind block. We can short-circuit the check for defers with
 	// f.Recover != nil.
 	if f.Recover != nil || hasDefer(f) {
-		fr.unwindBlock = llvm.AddBasicBlock(fr.function, "")
+		fr.unwindBlock = llvm.AddBasicBlock(fr.function, "unwind")
 		fr.frameptr = fr.builder.CreateAlloca(llvm.Int8Type(), "")
 	}
 
@@ -432,7 +432,7 @@
 	fr.fixupPhis()
 
 	if !fr.unwindBlock.IsNil() {
-		fr.setupUnwindBlock(f.Recover, f.Signature.Results())
+		fr.setupUnwindBlock(f.Recover)
 	}
 
 	// The init function needs to register the GC roots first. We do this
@@ -623,19 +623,12 @@
 	fr.runtime.undefer.invoke(fr, retrylpad, fr.frameptr)
 }
 
-func (fr *frame) setupUnwindBlock(rec *ssa.BasicBlock, results *types.Tuple) {
-	recoverbb := llvm.AddBasicBlock(fr.function, "")
+func (fr *frame) setupUnwindBlock(rec *ssa.BasicBlock) {
+	var recoverbb llvm.BasicBlock
 	if rec != nil {
-		fr.translateBlock(rec, recoverbb)
-	} else if results.Len() == 0 || results.At(0).Anonymous() {
-		// TODO(pcc): Remove this code after https://codereview.appspot.com/87210044/ lands
-		fr.builder.SetInsertPointAtEnd(recoverbb)
-		values := make([]llvm.Value, results.Len())
-		for i := range values {
-			values[i] = llvm.ConstNull(fr.llvmtypes.ToLLVM(results.At(i).Type()))
-		}
-		fr.retInf.encode(llvm.GlobalContext(), fr.allocaBuilder, fr.builder, values)
+		recoverbb = fr.blocks[rec.Index]
 	} else {
+		recoverbb = llvm.AddBasicBlock(fr.function, "recover")
 		fr.builder.SetInsertPointAtEnd(recoverbb)
 		fr.builder.CreateUnreachable()
 	}
diff --git a/irgen/targets.go b/irgen/targets.go
index 3571cbe..2f4fccb 100644
--- a/irgen/targets.go
+++ b/irgen/targets.go
@@ -36,9 +36,11 @@
 				llvm.RelocDefault,
 				llvm.CodeModelDefault,
 			)
-			target := machine.TargetData().String()
+			targetData := machine.CreateTargetData()
+			targetDataLayout := targetData.String()
+			targetData.Dispose()
 			machine.Dispose()
-			return target, nil
+			return targetDataLayout, nil
 		}
 	}
 	return "", fmt.Errorf("Invalid target triple: %s", triple)
diff --git a/irgen/typemap.go b/irgen/typemap.go
index 486ee6f..2ae1a4e 100644
--- a/irgen/typemap.go
+++ b/irgen/typemap.go
@@ -71,13 +71,20 @@
 
 	typeSliceType, methodSliceType, imethodSliceType, structFieldSliceType llvm.Type
 
+	funcValType             llvm.Type
 	hashFnType, equalFnType llvm.Type
 
-	hashFnEmptyInterface, hashFnInterface, hashFnFloat, hashFnComplex, hashFnString, hashFnIdentity, hashFnError        llvm.Value
-	equalFnEmptyInterface, equalFnInterface, equalFnFloat, equalFnComplex, equalFnString, equalFnIdentity, equalFnError llvm.Value
+	algsEmptyInterface,
+	algsInterface,
+	algsFloat,
+	algsComplex,
+	algsString,
+	algsIdentity,
+	algsError algorithms
+}
 
-	zeroType  llvm.Type
-	zeroValue llvm.Value
+type algorithms struct {
+	hash, hashDescriptor, equal, equalDescriptor llvm.Value
 }
 
 func NewLLVMTypeMap(ctx llvm.Context, target llvm.TargetData) *llvmTypeMap {
@@ -117,35 +124,38 @@
 	boolType := llvm.Int8Type()
 	stringPtrType := llvm.PointerType(tm.stringType, 0)
 
-	// Create runtime algorithm function types.
+	tm.funcValType = tm.ctx.StructCreateNamed("funcVal")
+	tm.funcValType.StructSetBody([]llvm.Type{
+		llvm.PointerType(llvm.FunctionType(llvm.VoidType(), []llvm.Type{}, false), 0),
+	}, false)
+
 	params := []llvm.Type{voidPtrType, uintptrType}
 	tm.hashFnType = llvm.FunctionType(uintptrType, params, false)
 	params = []llvm.Type{voidPtrType, voidPtrType, uintptrType}
 	tm.equalFnType = llvm.FunctionType(boolType, params, false)
 
-	tm.hashFnEmptyInterface = llvm.AddFunction(tm.module, "__go_type_hash_empty_interface", tm.hashFnType)
-	tm.hashFnInterface = llvm.AddFunction(tm.module, "__go_type_hash_interface", tm.hashFnType)
-	tm.hashFnFloat = llvm.AddFunction(tm.module, "__go_type_hash_float", tm.hashFnType)
-	tm.hashFnComplex = llvm.AddFunction(tm.module, "__go_type_hash_complex", tm.hashFnType)
-	tm.hashFnString = llvm.AddFunction(tm.module, "__go_type_hash_string", tm.hashFnType)
-	tm.hashFnIdentity = llvm.AddFunction(tm.module, "__go_type_hash_identity", tm.hashFnType)
-	tm.hashFnError = llvm.AddFunction(tm.module, "__go_type_hash_error", tm.hashFnType)
-
-	tm.equalFnEmptyInterface = llvm.AddFunction(tm.module, "__go_type_equal_empty_interface", tm.equalFnType)
-	tm.equalFnInterface = llvm.AddFunction(tm.module, "__go_type_equal_interface", tm.equalFnType)
-	tm.equalFnFloat = llvm.AddFunction(tm.module, "__go_type_equal_float", tm.equalFnType)
-	tm.equalFnComplex = llvm.AddFunction(tm.module, "__go_type_equal_complex", tm.equalFnType)
-	tm.equalFnString = llvm.AddFunction(tm.module, "__go_type_equal_string", tm.equalFnType)
-	tm.equalFnIdentity = llvm.AddFunction(tm.module, "__go_type_equal_identity", tm.equalFnType)
-	tm.equalFnError = llvm.AddFunction(tm.module, "__go_type_equal_error", tm.equalFnType)
-
-	// The body of this type is set in emitTypeDescInitializers once we have scanned
-	// every type, as it needs to be as large and well aligned as the
-	// largest/most aligned type.
-	tm.zeroType = tm.ctx.StructCreateNamed("zero")
-	tm.zeroValue = llvm.AddGlobal(tm.module, tm.zeroType, "go$zerovalue")
-	tm.zeroValue.SetLinkage(llvm.CommonLinkage)
-	tm.zeroValue.SetInitializer(llvm.ConstNull(tm.zeroType))
+	typeAlgorithms := [...]struct {
+		Name string
+		*algorithms
+	}{
+		{"empty_interface", &tm.algsEmptyInterface},
+		{"interface", &tm.algsInterface},
+		{"float", &tm.algsFloat},
+		{"complex", &tm.algsComplex},
+		{"string", &tm.algsString},
+		{"identity", &tm.algsIdentity},
+		{"error", &tm.algsError},
+	}
+	for _, typeAlgs := range typeAlgorithms {
+		hashFnName := "__go_type_hash_" + typeAlgs.Name
+		hashDescriptorName := hashFnName + "_descriptor"
+		equalFnName := "__go_type_equal_" + typeAlgs.Name
+		equalDescriptorName := equalFnName + "_descriptor"
+		typeAlgs.hash = llvm.AddGlobal(tm.module, tm.hashFnType, hashFnName)
+		typeAlgs.hashDescriptor = llvm.AddGlobal(tm.module, tm.funcValType, hashDescriptorName)
+		typeAlgs.equal = llvm.AddGlobal(tm.module, tm.equalFnType, equalFnName)
+		typeAlgs.equalDescriptor = llvm.AddGlobal(tm.module, tm.funcValType, equalDescriptorName)
+	}
 
 	tm.commonTypeType = tm.ctx.StructCreateNamed("commonType")
 	commonTypeTypePtr := llvm.PointerType(tm.commonTypeType, 0)
@@ -174,13 +184,12 @@
 		tm.ctx.Int8Type(),                        // fieldAlign
 		uintptrType,                              // size
 		tm.ctx.Int32Type(),                       // hash
-		llvm.PointerType(tm.hashFnType, 0),       // hashfn
-		llvm.PointerType(tm.equalFnType, 0),      // equalfn
+		llvm.PointerType(tm.funcValType, 0),      // hashfn
+		llvm.PointerType(tm.funcValType, 0),      // equalfn
 		voidPtrType,                              // gc
 		stringPtrType,                            // string
 		llvm.PointerType(tm.uncommonTypeType, 0), // uncommonType
 		commonTypeTypePtr,                        // ptrToThis
-		llvm.PointerType(tm.zeroType, 0),         // zero
 	}, false)
 
 	tm.typeSliceType = tm.makeNamedSliceType("typeSlice", commonTypeTypePtr)
@@ -1096,9 +1105,6 @@
 			}
 		}
 	}
-
-	tm.zeroType.StructSetBody([]llvm.Type{llvm.ArrayType(tm.ctx.Int8Type(), int(maxSize))}, false)
-	tm.zeroValue.SetAlignment(int(maxAlign))
 }
 
 const (
@@ -1234,24 +1240,20 @@
 	}
 }
 
-type algorithmFns struct {
-	hash, equal llvm.Value
-}
-
-func (tm *TypeMap) getStructAlgorithmFunctions(st *types.Struct) (hash, equal llvm.Value) {
-	if algs, ok := tm.algs.At(st).(algorithmFns); ok {
-		return algs.hash, algs.equal
+func (tm *TypeMap) getStructAlgorithms(st *types.Struct) algorithms {
+	if algs, ok := tm.algs.At(st).(algorithms); ok {
+		return algs
 	}
 
 	hashes := make([]llvm.Value, st.NumFields())
 	equals := make([]llvm.Value, st.NumFields())
 
 	for i := range hashes {
-		fhash, fequal := tm.getAlgorithmFunctions(st.Field(i).Type())
-		if fhash == tm.hashFnError {
-			return fhash, fequal
+		algs := tm.getAlgorithms(st.Field(i).Type())
+		if algs.hashDescriptor == tm.algsError.hashDescriptor {
+			return algs
 		}
-		hashes[i], equals[i] = fhash, fequal
+		hashes[i], equals[i] = algs.hash, algs.equal
 	}
 
 	i8ptr := llvm.PointerType(tm.ctx.Int8Type(), 0)
@@ -1260,8 +1262,11 @@
 	builder := tm.ctx.NewBuilder()
 	defer builder.Dispose()
 
-	hash = llvm.AddFunction(tm.module, tm.mc.mangleHashFunctionName(st), tm.hashFnType)
+	hashFunctionName := tm.mc.mangleHashFunctionName(st)
+	hash := llvm.AddFunction(tm.module, hashFunctionName, tm.hashFnType)
 	hash.SetLinkage(llvm.LinkOnceODRLinkage)
+	hashDescriptor := tm.createAlgorithmDescriptor(hashFunctionName+"_descriptor", hash)
+
 	builder.SetInsertPointAtEnd(llvm.AddBasicBlock(hash, "entry"))
 	sptr := builder.CreateBitCast(hash.Param(0), llsptrty, "")
 
@@ -1271,9 +1276,7 @@
 	for i, fhash := range hashes {
 		fptr := builder.CreateStructGEP(sptr, i, "")
 		fptr = builder.CreateBitCast(fptr, i8ptr, "")
-
 		fsize := llvm.ConstInt(tm.inttype, uint64(tm.sizes.Sizeof(st.Field(i).Type())), false)
-
 		hashcall := builder.CreateCall(fhash, []llvm.Value{fptr, fsize}, "")
 		hashval = builder.CreateMul(hashval, i33, "")
 		hashval = builder.CreateAdd(hashval, hashcall, "")
@@ -1281,11 +1284,13 @@
 
 	builder.CreateRet(hashval)
 
-	equal = llvm.AddFunction(tm.module, tm.mc.mangleEqualFunctionName(st), tm.equalFnType)
+	equalFunctionName := tm.mc.mangleEqualFunctionName(st)
+	equal := llvm.AddFunction(tm.module, equalFunctionName, tm.equalFnType)
 	equal.SetLinkage(llvm.LinkOnceODRLinkage)
+	equalDescriptor := tm.createAlgorithmDescriptor(equalFunctionName+"_descriptor", equal)
+
 	eqentrybb := llvm.AddBasicBlock(equal, "entry")
 	eqretzerobb := llvm.AddBasicBlock(equal, "retzero")
-
 	builder.SetInsertPointAtEnd(eqentrybb)
 	s1ptr := builder.CreateBitCast(equal.Param(0), llsptrty, "")
 	s2ptr := builder.CreateBitCast(equal.Param(1), llsptrty, "")
@@ -1298,15 +1303,11 @@
 		f1ptr = builder.CreateBitCast(f1ptr, i8ptr, "")
 		f2ptr := builder.CreateStructGEP(s2ptr, i, "")
 		f2ptr = builder.CreateBitCast(f2ptr, i8ptr, "")
-
 		fsize := llvm.ConstInt(tm.inttype, uint64(tm.sizes.Sizeof(st.Field(i).Type())), false)
-
 		equalcall := builder.CreateCall(fequal, []llvm.Value{f1ptr, f2ptr, fsize}, "")
 		equaleqzero := builder.CreateICmp(llvm.IntEQ, equalcall, zerobool, "")
-
 		contbb := llvm.AddBasicBlock(equal, "cont")
 		builder.CreateCondBr(equaleqzero, eqretzerobb, contbb)
-
 		builder.SetInsertPointAtEnd(contbb)
 	}
 
@@ -1315,18 +1316,24 @@
 	builder.SetInsertPointAtEnd(eqretzerobb)
 	builder.CreateRet(zerobool)
 
-	tm.algs.Set(st, algorithmFns{hash, equal})
-	return
+	algs := algorithms{
+		hash:            hash,
+		hashDescriptor:  hashDescriptor,
+		equal:           equal,
+		equalDescriptor: equalDescriptor,
+	}
+	tm.algs.Set(st, algs)
+	return algs
 }
 
-func (tm *TypeMap) getArrayAlgorithmFunctions(at *types.Array) (hash, equal llvm.Value) {
-	if algs, ok := tm.algs.At(at).(algorithmFns); ok {
-		return algs.hash, algs.equal
+func (tm *TypeMap) getArrayAlgorithms(at *types.Array) algorithms {
+	if algs, ok := tm.algs.At(at).(algorithms); ok {
+		return algs
 	}
 
-	ehash, eequal := tm.getAlgorithmFunctions(at.Elem())
-	if ehash == tm.hashFnError {
-		return ehash, eequal
+	elemAlgs := tm.getAlgorithms(at.Elem())
+	if elemAlgs.hashDescriptor == tm.algsError.hashDescriptor {
+		return elemAlgs
 	}
 
 	i8ptr := llvm.PointerType(tm.ctx.Int8Type(), 0)
@@ -1339,8 +1346,22 @@
 	builder := tm.ctx.NewBuilder()
 	defer builder.Dispose()
 
-	hash = llvm.AddFunction(tm.module, tm.mc.mangleHashFunctionName(at), tm.hashFnType)
+	hashFunctionName := tm.mc.mangleHashFunctionName(at)
+	hash := llvm.AddFunction(tm.module, hashFunctionName, tm.hashFnType)
 	hash.SetLinkage(llvm.LinkOnceODRLinkage)
+	hashDescriptor := tm.createAlgorithmDescriptor(hashFunctionName+"_descriptor", hash)
+	equalFunctionName := tm.mc.mangleHashFunctionName(at)
+	equal := llvm.AddFunction(tm.module, equalFunctionName, tm.equalFnType)
+	equal.SetLinkage(llvm.LinkOnceODRLinkage)
+	equalDescriptor := tm.createAlgorithmDescriptor(equalFunctionName+"_descriptor", equal)
+	algs := algorithms{
+		hash:            hash,
+		hashDescriptor:  hashDescriptor,
+		equal:           equal,
+		equalDescriptor: equalDescriptor,
+	}
+	tm.algs.Set(at, algs)
+
 	hashentrybb := llvm.AddBasicBlock(hash, "entry")
 	builder.SetInsertPointAtEnd(hashentrybb)
 	if at.Len() == 0 {
@@ -1363,7 +1384,7 @@
 		eptr := builder.CreateGEP(aptr, []llvm.Value{index}, "")
 		eptr = builder.CreateBitCast(eptr, i8ptr, "")
 
-		hashcall := builder.CreateCall(ehash, []llvm.Value{eptr, esize}, "")
+		hashcall := builder.CreateCall(elemAlgs.hash, []llvm.Value{eptr, esize}, "")
 		hashval = builder.CreateMul(hashval, i33, "")
 		hashval = builder.CreateAdd(hashval, hashcall, "")
 
@@ -1388,8 +1409,6 @@
 	zerobool := llvm.ConstNull(tm.ctx.Int8Type())
 	onebool := llvm.ConstInt(tm.ctx.Int8Type(), 1, false)
 
-	equal = llvm.AddFunction(tm.module, tm.mc.mangleEqualFunctionName(at), tm.equalFnType)
-	equal.SetLinkage(llvm.LinkOnceODRLinkage)
 	eqentrybb := llvm.AddBasicBlock(equal, "entry")
 	builder.SetInsertPointAtEnd(eqentrybb)
 	if at.Len() == 0 {
@@ -1412,7 +1431,7 @@
 		e2ptr := builder.CreateGEP(a2ptr, []llvm.Value{index}, "")
 		e2ptr = builder.CreateBitCast(e2ptr, i8ptr, "")
 
-		equalcall := builder.CreateCall(eequal, []llvm.Value{e1ptr, e2ptr, esize}, "")
+		equalcall := builder.CreateCall(elemAlgs.equal, []llvm.Value{e1ptr, e2ptr, esize}, "")
 		equaleqzero := builder.CreateICmp(llvm.IntEQ, equalcall, zerobool, "")
 
 		contbb := llvm.AddBasicBlock(equal, "cont")
@@ -1437,48 +1456,45 @@
 		builder.CreateRet(zerobool)
 	}
 
-	tm.algs.Set(at, algorithmFns{hash, equal})
-	return
+	return algs
 }
 
-func (tm *TypeMap) getAlgorithmFunctions(t types.Type) (hash, equal llvm.Value) {
+func (tm *TypeMap) createAlgorithmDescriptor(name string, fn llvm.Value) llvm.Value {
+	d := llvm.AddGlobal(tm.module, tm.funcValType, name)
+	d.SetLinkage(llvm.LinkOnceODRLinkage)
+	d.SetGlobalConstant(true)
+	fn = llvm.ConstBitCast(fn, tm.funcValType.StructElementTypes()[0])
+	init := llvm.ConstNull(tm.funcValType)
+	init = llvm.ConstInsertValue(init, fn, []uint32{0})
+	d.SetInitializer(init)
+	return d
+}
+
+func (tm *TypeMap) getAlgorithms(t types.Type) algorithms {
 	switch t := t.Underlying().(type) {
 	case *types.Interface:
 		if t.NumMethods() == 0 {
-			hash = tm.hashFnEmptyInterface
-			equal = tm.equalFnEmptyInterface
-		} else {
-			hash = tm.hashFnInterface
-			equal = tm.equalFnInterface
+			return tm.algsEmptyInterface
 		}
+		return tm.algsInterface
 	case *types.Basic:
 		switch t.Kind() {
 		case types.Float32, types.Float64:
-			hash = tm.hashFnFloat
-			equal = tm.equalFnFloat
+			return tm.algsFloat
 		case types.Complex64, types.Complex128:
-			hash = tm.hashFnComplex
-			equal = tm.equalFnComplex
+			return tm.algsComplex
 		case types.String:
-			hash = tm.hashFnString
-			equal = tm.equalFnString
-		default:
-			hash = tm.hashFnIdentity
-			equal = tm.equalFnIdentity
+			return tm.algsString
 		}
+		return tm.algsIdentity
 	case *types.Signature, *types.Map, *types.Slice:
-		hash = tm.hashFnError
-		equal = tm.equalFnError
+		return tm.algsError
 	case *types.Struct:
-		hash, equal = tm.getStructAlgorithmFunctions(t)
+		return tm.getStructAlgorithms(t)
 	case *types.Array:
-		hash, equal = tm.getArrayAlgorithmFunctions(t)
-	default:
-		hash = tm.hashFnIdentity
-		equal = tm.equalFnIdentity
+		return tm.getArrayAlgorithms(t)
 	}
-
-	return
+	return tm.algsIdentity
 }
 
 func (tm *TypeMap) getTypeDescInfo(t types.Type) *typeDescInfo {
@@ -1704,27 +1720,26 @@
 }
 
 func (tm *TypeMap) makeCommonType(t types.Type) llvm.Value {
-	var vals [12]llvm.Value
+	var vals [11]llvm.Value
 	vals[0] = llvm.ConstInt(tm.ctx.Int8Type(), uint64(runtimeTypeKind(t)), false)
 	vals[1] = llvm.ConstInt(tm.ctx.Int8Type(), uint64(tm.Alignof(t)), false)
 	vals[2] = vals[1]
 	vals[3] = llvm.ConstInt(tm.inttype, uint64(tm.Sizeof(t)), false)
 	vals[4] = llvm.ConstInt(tm.ctx.Int32Type(), uint64(tm.getTypeHash(t)), false)
-	hash, equal := tm.getAlgorithmFunctions(t)
-	vals[5] = hash
-	vals[6] = equal
+	algs := tm.getAlgorithms(t)
+	vals[5] = algs.hashDescriptor
+	vals[6] = algs.equalDescriptor
 	vals[7] = tm.getGcPointer(t)
 	var b bytes.Buffer
 	tm.writeType(t, &b)
 	vals[8] = tm.globalStringPtr(b.String())
 	vals[9] = tm.makeUncommonTypePtr(t)
-	if _, ok := t.(*types.Named); ok {
+	switch t.(type) {
+	case *types.Named, *types.Struct:
 		vals[10] = tm.getTypeDescriptorPointer(types.NewPointer(t))
-	} else {
+	default:
 		vals[10] = llvm.ConstPointerNull(llvm.PointerType(tm.commonTypeType, 0))
 	}
-	vals[11] = tm.zeroValue
-
 	return llvm.ConstNamedStruct(tm.commonTypeType, vals[:])
 }
 
diff --git a/irgen/value.go b/irgen/value.go
index 366069b..e6bc589 100644
--- a/irgen/value.go
+++ b/irgen/value.go
@@ -17,6 +17,7 @@
 import (
 	"fmt"
 	"go/token"
+
 	"llvm.org/llgo/third_party/gotools/go/exact"
 	"llvm.org/llgo/third_party/gotools/go/types"
 	"llvm.org/llvm/bindings/go/llvm"
@@ -480,20 +481,8 @@
 
 		// string -> []byte
 		if isSlice(dsttyp, types.Byte) {
-			value := v.value
-			strdata := fr.builder.CreateExtractValue(value, 0, "")
-			strlen := fr.builder.CreateExtractValue(value, 1, "")
-
-			// Data must be copied, to prevent changes in
-			// the byte slice from mutating the string.
-			newdata := fr.createMalloc(strlen)
-			fr.memcpy(newdata, strdata, strlen)
-
-			struct_ := llvm.Undef(fr.types.ToLLVM(dsttyp))
-			struct_ = fr.builder.CreateInsertValue(struct_, newdata, 0, "")
-			struct_ = fr.builder.CreateInsertValue(struct_, strlen, 1, "")
-			struct_ = fr.builder.CreateInsertValue(struct_, strlen, 2, "")
-			return newValue(struct_, origdsttyp)
+			sliceValue := fr.runtime.stringToByteArray.callOnly(fr, v.value)[0]
+			return newValue(sliceValue, origdsttyp)
 		}
 
 		// string -> []rune
@@ -504,19 +493,10 @@
 
 	// []byte -> string
 	if isSlice(srctyp, types.Byte) && isString(dsttyp) {
-		value := v.value
-		data := fr.builder.CreateExtractValue(value, 0, "")
-		len := fr.builder.CreateExtractValue(value, 1, "")
-
-		// Data must be copied, to prevent changes in
-		// the byte slice from mutating the string.
-		newdata := fr.createMalloc(len)
-		fr.memcpy(newdata, data, len)
-
-		struct_ := llvm.Undef(fr.types.ToLLVM(types.Typ[types.String]))
-		struct_ = fr.builder.CreateInsertValue(struct_, newdata, 0, "")
-		struct_ = fr.builder.CreateInsertValue(struct_, len, 1, "")
-		return newValue(struct_, types.Typ[types.String])
+		data := fr.builder.CreateExtractValue(v.value, 0, "")
+		len := fr.builder.CreateExtractValue(v.value, 1, "")
+		stringValue := fr.runtime.byteArrayToString.callOnly(fr, data, len)[0]
+		return newValue(stringValue, dsttyp)
 	}
 
 	// []rune -> string
diff --git a/libgo-check-failures.diff b/libgo-check-failures.diff
index bf8f026..519bddf 100644
--- a/libgo-check-failures.diff
+++ b/libgo-check-failures.diff
@@ -47,15 +47,3 @@
  		select {
  		case <-ch:
  		case <-time.After(time.Second * 4):
-diff -r a6e10414311a libgo/go/runtime/runtime_test.go
---- a/libgo/go/runtime/runtime_test.go	Fri Jan 16 07:57:02 2015 -0800
-+++ b/libgo/go/runtime/runtime_test.go	Fri Apr 03 15:07:47 2015 -0700
-@@ -176,6 +176,8 @@
- }
- 
- func TestSetPanicOnFault(t *testing.T) {
-+	t.Skip("skipping for llgo due to lack of non-call exception support")
-+
- 	// This currently results in a fault in the signal trampoline on
- 	// dragonfly/386 - see issue 7421.
- 	if GOOS == "dragonfly" && GOARCH == "386" {
diff --git a/third_party/gofrontend/config.guess b/third_party/gofrontend/config.guess
index 73d671b..8bf4226 100755
--- a/third_party/gofrontend/config.guess
+++ b/third_party/gofrontend/config.guess
@@ -810,6 +810,9 @@
     *:MINGW*:*)
 	echo ${UNAME_MACHINE}-pc-mingw32
 	exit ;;
+    *:MSYS*:*)
+	echo ${UNAME_MACHINE}-pc-msys
+	exit ;;
     i*:windows32*:*)
 	# uname -m includes "-pc" on this system.
 	echo ${UNAME_MACHINE}-mingw32
@@ -1200,6 +1203,9 @@
     BePC:Haiku:*:*)	# Haiku running on Intel PC compatible.
 	echo i586-pc-haiku
 	exit ;;
+    x86_64:Haiku:*:*) # Haiku running on x86_64.
+	echo x86_64-unknown-haiku
+	exit ;;
     SX-4:SUPER-UX:*:*)
 	echo sx4-nec-superux${UNAME_RELEASE}
 	exit ;;
diff --git a/third_party/gofrontend/libgo/MERGE b/third_party/gofrontend/libgo/MERGE
index 260f8cf..ea32fc1 100644
--- a/third_party/gofrontend/libgo/MERGE
+++ b/third_party/gofrontend/libgo/MERGE
@@ -1,4 +1,4 @@
-883bc6ed0ea815293fe6309d66f967ea60630e87
+f2e4c8b5fb3660d793b2c545ef207153db0a34b1
 
 The first line of this file holds the git revision number of the
 last merge done from the master library sources.
diff --git a/third_party/gofrontend/libgo/Makefile.am b/third_party/gofrontend/libgo/Makefile.am
index cbaf08e..9080a29 100644
--- a/third_party/gofrontend/libgo/Makefile.am
+++ b/third_party/gofrontend/libgo/Makefile.am
@@ -105,7 +105,7 @@
 toolexeclib_LIBRARIES = libgobegin-llgo.a
 else
 toolexeclib_LTLIBRARIES = libgo.la
-toolexeclib_LIBRARIES = libgobegin.a
+toolexeclib_LIBRARIES = libgobegin.a libgolibbegin.a libnetgo.a
 endif
 
 toolexeclibgo_DATA = \
@@ -233,12 +233,15 @@
 toolexeclibgogo_DATA = \
 	go/ast.gox \
 	go/build.gox \
+	go/constant.gox \
 	go/doc.gox \
 	go/format.gox \
+	go/importer.gox \
 	go/parser.gox \
 	go/printer.gox \
 	go/scanner.gox \
-	go/token.gox
+	go/token.gox \
+	go/types.gox
 
 toolexeclibgohashdir = $(toolexeclibgodir)/hash
 
@@ -292,7 +295,8 @@
 toolexeclibgomimedir = $(toolexeclibgodir)/mime
 
 toolexeclibgomime_DATA = \
-	mime/multipart.gox
+	mime/multipart.gox \
+	mime/quotedprintable.gox
 
 toolexeclibgonetdir = $(toolexeclibgodir)/net
 
@@ -676,46 +680,74 @@
 	go/math/tanh.go \
 	go/math/unsafe.go
 
+if LIBGO_IS_OPENBSD
+go_mime_type_file = go/mime/type_openbsd.go
+else
+if LIBGO_IS_FREEBSD
+go_mime_type_file = go/mime/type_freebsd.go
+else
+if LIBGO_IS_DRAGONFLY
+go_mime_type_file = go/mime/type_dragonfly.go
+else
+go_mime_type_file =
+endif
+endif
+endif
+
 go_mime_files = \
+	go/mime/encodedword.go \
 	go/mime/grammar.go \
 	go/mime/mediatype.go \
 	go/mime/type.go \
-	go/mime/type_unix.go
+	go/mime/type_unix.go \
+	$(go_mime_type_file)
 
 if LIBGO_IS_LINUX
 go_net_cgo_file = go/net/cgo_linux.go
 go_net_sock_file = go/net/sock_linux.go
 go_net_sockopt_file = go/net/sockopt_linux.go
 go_net_sockoptip_file = go/net/sockoptip_linux.go go/net/sockoptip_posix.go
+go_net_cgo_sock_file = go/net/cgo_socknew.go
+go_net_cgo_res_file = go/net/cgo_resnew.go
 else
 if LIBGO_IS_IRIX
 go_net_cgo_file = go/net/cgo_linux.go
 go_net_sock_file = go/net/sock_linux.go
 go_net_sockopt_file = go/net/sockopt_linux.go
 go_net_sockoptip_file = go/net/sockoptip_linux.go go/net/sockoptip_posix.go
+go_net_cgo_sock_file = go/net/cgo_socknew.go
+go_net_cgo_res_file = go/net/cgo_resnew.go
 else
 if LIBGO_IS_SOLARIS
-go_net_cgo_file = go/net/cgo_linux.go
+go_net_cgo_file = go/net/cgo_solaris.go
 go_net_sock_file = go/net/sock_stub.go
 go_net_sockopt_file = go/net/sockopt_solaris.go
 go_net_sockoptip_file = go/net/sockoptip_stub.go
+go_net_cgo_sock_file = go/net/cgo_socknew.go
+go_net_cgo_res_file = go/net/cgo_resnew.go
 else
 if LIBGO_IS_FREEBSD
 go_net_cgo_file = go/net/cgo_bsd.go
 go_net_sock_file = go/net/sock_bsd.go
 go_net_sockopt_file = go/net/sockopt_bsd.go
 go_net_sockoptip_file = go/net/sockoptip_bsd.go go/net/sockoptip_posix.go
+go_net_cgo_sock_file = go/net/cgo_sockold.go
+go_net_cgo_res_file = go/net/cgo_resold.go
 else
 if LIBGO_IS_NETBSD
 go_net_cgo_file = go/net/cgo_netbsd.go
 go_net_sock_file = go/net/sock_bsd.go
 go_net_sockopt_file = go/net/sockopt_bsd.go
 go_net_sockoptip_file = go/net/sockoptip_bsd.go go/net/sockoptip_posix.go
+go_net_cgo_sock_file = go/net/cgo_sockold.go
+go_net_cgo_res_file = go/net/cgo_resnew.go
 else
 go_net_cgo_file = go/net/cgo_bsd.go
 go_net_sock_file = go/net/sock_bsd.go
 go_net_sockopt_file = go/net/sockopt_bsd.go
 go_net_sockoptip_file = go/net/sockoptip_bsd.go go/net/sockoptip_posix.go
+go_net_cgo_sock_file = go/net/cgo_sockold.go
+go_net_cgo_res_file = go/net/cgo_resold.go
 endif
 endif
 endif
@@ -731,10 +763,14 @@
 if LIBGO_IS_DRAGONFLY
 go_net_sendfile_file = go/net/sendfile_dragonfly.go
 else
+if LIBGO_IS_SOLARIS
+go_net_sendfile_file = go/net/sendfile_solaris.go
+else
 go_net_sendfile_file = go/net/sendfile_stub.go
 endif
 endif
 endif
+endif
 
 if LIBGO_IS_LINUX
 go_net_interface_file = go/net/interface_linux.go
@@ -751,10 +787,14 @@
 endif
 
 if LIBGO_IS_LINUX
-go_net_cloexec_file = go/net/sock_cloexec.go
+go_net_cloexec_file = go/net/sock_cloexec.go go/net/hook_cloexec.go
+else
+if LIBGO_IS_FREEBSD
+go_net_cloexec_file = go/net/sock_cloexec.go go/net/hook_cloexec.go
 else
 go_net_cloexec_file = go/net/sys_cloexec.go
 endif
+endif
 
 if LIBGO_IS_OPENBSD
 go_net_tcpsockopt_file = go/net/tcpsockopt_openbsd.go
@@ -774,18 +814,22 @@
 endif
 endif
 
-go_net_files = \
-	go/net/cgo_unix.go \
-	$(go_net_cgo_file) \
+go_net_common_files = \
+	go/net/addrselect.go \
 	$(go_net_cloexec_file) \
+	go/net/conf.go \
 	go/net/dial.go \
 	go/net/dnsclient.go \
 	go/net/dnsclient_unix.go \
 	go/net/dnsconfig_unix.go \
 	go/net/dnsmsg.go \
 	go/net/fd_mutex.go \
+	go/net/fd_posix.go \
 	go/net/fd_unix.go \
+	go/net/file.go \
 	go/net/file_unix.go \
+	go/net/hook.go \
+	go/net/hook_unix.go \
 	go/net/hosts.go \
 	go/net/interface.go \
 	$(go_net_interface_file) \
@@ -798,6 +842,7 @@
 	go/net/lookup_unix.go \
 	go/net/mac.go \
 	go/net/net.go \
+	go/net/nss.go \
 	go/net/parse.go \
 	go/net/pipe.go \
 	go/net/fd_poll_runtime.go \
@@ -805,7 +850,6 @@
 	go/net/port_unix.go \
 	go/net/race0.go \
 	$(go_net_sendfile_file) \
-	go/net/singleflight.go \
 	go/net/sock_posix.go \
 	$(go_net_sock_file) \
 	go/net/sockopt_posix.go \
@@ -820,6 +864,17 @@
 	go/net/unixsock.go \
 	go/net/unixsock_posix.go
 
+go_net_files = \
+	go/net/cgo_unix.go \
+	$(go_net_cgo_file) \
+	$(go_net_cgo_res_file) \
+	$(go_net_cgo_sock_file) \
+	$(go_net_common_files)
+
+go_netgo_files = \
+	go/net/cgo_stub.go \
+	$(go_net_common_files)
+
 if LIBGO_IS_SOLARIS
 if LIBGO_IS_386
 go_os_dir_file = go/os/dir_largefile.go
@@ -873,7 +928,11 @@
 endif
 
 if LIBGO_IS_SOLARIS
+if HAVE_STAT_TIMESPEC
+go_os_stat_file = go/os/stat_atim.go
+else
 go_os_stat_file = go/os/stat_solaris.go
+endif
 else
 if LIBGO_IS_LINUX
 go_os_stat_file = go/os/stat_atim.go
@@ -908,6 +967,32 @@
 go_os_pipe_file = go/os/pipe_bsd.go
 endif
 
+if LIBGO_IS_DARWIN
+go_os_sticky_file = go/os/sticky_bsd.go
+else
+if LIBGO_IS_DRAGONFLY
+go_os_sticky_file = go/os/sticky_bsd.go
+else
+if LIBGO_IS_FREEBSD
+go_os_sticky_file = go/os/sticky_bsd.go
+else
+if LIBGO_IS_NETBSD
+go_os_sticky_file = go/os/sticky_bsd.go
+else
+if LIBGO_IS_OPENBSD
+go_os_sticky_file = go/os/sticky_bsd.go
+else
+if LIBGO_IS_SOLARIS
+go_os_sticky_file = go/os/sticky_bsd.go
+else
+go_os_sticky_file = go/os/sticky_notbsd.go
+endif
+endif
+endif
+endif
+endif
+endif
+
 go_os_files = \
 	$(go_os_dir_file) \
 	go/os/dir.go \
@@ -928,6 +1013,7 @@
 	$(go_os_pipe_file) \
 	go/os/proc.go \
 	$(go_os_stat_file) \
+	$(go_os_sticky_file) \
 	go/os/str.go \
 	$(go_os_sys_file) \
 	$(go_os_cloexec_file) \
@@ -948,6 +1034,7 @@
 	go/reflect/makefunc_ffi_c.c
 
 go_regexp_files = \
+	go/regexp/backtrack.go \
 	go/regexp/exec.go \
 	go/regexp/onepass.go \
 	go/regexp/regexp.go
@@ -963,7 +1050,6 @@
 	go/runtime/error.go \
 	go/runtime/extern.go \
 	go/runtime/mem.go \
-	go/runtime/softfloat64.go \
 	version.go
 
 version.go: s-version; @true
@@ -1001,6 +1087,7 @@
 	go/strconv/atof.go \
 	go/strconv/atoi.go \
 	go/strconv/decimal.go \
+	go/strconv/doc.go \
 	go/strconv/extfloat.go \
 	go/strconv/ftoa.go \
 	go/strconv/isprint.go \
@@ -1008,6 +1095,7 @@
 	go/strconv/quote.go
 
 go_strings_files = \
+	go/strings/compare.go \
 	go/strings/reader.go \
 	go/strings/replace.go \
 	go/strings/search.go \
@@ -1037,6 +1125,7 @@
 endif
 
 go_log_syslog_files = \
+	go/log/syslog/doc.go \
 	go/log/syslog/syslog.go \
 	$(go_syslog_file)
 go_syslog_c_files = \
@@ -1175,6 +1264,7 @@
 endif
 
 go_crypto_rand_files = \
+	go/crypto/rand/eagain.go \
 	go/crypto/rand/rand.go \
 	go/crypto/rand/rand_unix.go \
 	$(crypto_rand_file) \
@@ -1211,6 +1301,37 @@
 	go/crypto/tls/prf.go \
 	go/crypto/tls/ticket.go \
 	go/crypto/tls/tls.go
+
+if LIBGO_IS_LINUX
+go_crypto_x509_root_file = go/crypto/x509/root_linux.go
+else
+if LIBGO_IS_SOLARIS
+go_crypto_x509_root_file = go/crypto/x509/root_solaris.go
+else
+if LIBGO_IS_DRAGONFLY
+go_crypto_x509_root_file = go/crypto/x509/root_bsd.go
+else
+if LIBGO_IS_FREEBSD
+go_crypto_x509_root_file = go/crypto/x509/root_bsd.go
+else
+if LIBGO_IS_NETBSD
+go_crypto_x509_root_file = go/crypto/x509/root_bsd.go
+else
+if LIBGO_IS_OPENBSD
+go_crypto_x509_root_file = go/crypto/x509/root_bsd.go
+else
+if LIBGO_IS_DARWIN
+go_crypto_x509_root_file = go/crypto/x509/root_darwin.go
+else
+go_crypto_x509_root_file =
+endif
+endif
+endif
+endif
+endif
+endif
+endif
+
 go_crypto_x509_files = \
 	go/crypto/x509/cert_pool.go \
 	go/crypto/x509/pem_decrypt.go \
@@ -1218,6 +1339,7 @@
 	go/crypto/x509/pkcs8.go \
 	go/crypto/x509/root.go \
 	go/crypto/x509/root_unix.go \
+	$(go_crypto_x509_root_file) \
 	go/crypto/x509/sec1.go \
 	go/crypto/x509/verify.go \
 	go/crypto/x509/x509.go
@@ -1235,6 +1357,7 @@
 
 go_debug_dwarf_files = \
 	go/debug/dwarf/buf.go \
+	go/debug/dwarf/class_string.go \
 	go/debug/dwarf/const.go \
 	go/debug/dwarf/entry.go \
 	go/debug/dwarf/line.go \
@@ -1326,6 +1449,9 @@
 	go/go/build/doc.go \
 	go/go/build/read.go \
 	go/go/build/syslist.go
+go_go_constant_files = \
+	go/go/constant/go14.go \
+	go/go/constant/value.go
 go_go_doc_files = \
 	go/go/doc/comment.go \
 	go/go/doc/doc.go \
@@ -1336,6 +1462,8 @@
 	go/go/doc/synopsis.go
 go_go_format_files = \
 	go/go/format/format.go
+go_go_importer_files = \
+	go/go/importer/importer.go
 go_go_parser_files = \
 	go/go/parser/interface.go \
 	go/go/parser/parser.go
@@ -1349,6 +1477,47 @@
 	go/go/token/position.go \
 	go/go/token/serialize.go \
 	go/go/token/token.go
+go_go_types_files = \
+	go/go/types/api.go \
+	go/go/types/assignments.go \
+	go/go/types/builtins.go \
+	go/go/types/call.go \
+	go/go/types/check.go \
+	go/go/types/conversions.go \
+	go/go/types/decl.go \
+	go/go/types/errors.go \
+	go/go/types/eval.go \
+	go/go/types/expr.go \
+	go/go/types/exprstring.go \
+	go/go/types/go12.go \
+	go/go/types/initorder.go \
+	go/go/types/labels.go \
+	go/go/types/lookup.go \
+	go/go/types/methodset.go \
+	go/go/types/object.go \
+	go/go/types/objset.go \
+	go/go/types/operand.go \
+	go/go/types/ordering.go \
+	go/go/types/package.go \
+	go/go/types/predicates.go \
+	go/go/types/resolver.go \
+	go/go/types/return.go \
+	go/go/types/scope.go \
+	go/go/types/selection.go \
+	go/go/types/stmt.go \
+	go/go/types/sizes.go \
+	go/go/types/type.go \
+	go/go/types/typestring.go \
+	go/go/types/typexpr.go \
+	go/go/types/universe.go
+
+go_go_internal_gcimporter_files = \
+	go/go/internal/gcimporter/exportdata.go \
+	go/go/internal/gcimporter/gcimporter.go
+go_go_internal_gccgoimporter_files = \
+	go/go/internal/gccgoimporter/gccgoinstallation.go \
+	go/go/internal/gccgoimporter/importer.go \
+	go/go/internal/gccgoimporter/parser.go
 
 go_hash_adler32_files = \
 	go/hash/adler32/adler32.go
@@ -1388,6 +1557,10 @@
 	go/image/gif/reader.go \
 	go/image/gif/writer.go
 
+go_image_internal_imageutil_files = \
+	go/image/internal/imageutil/imageutil.go \
+	go/image/internal/imageutil/impl.go
+
 go_image_jpeg_files = \
 	go/image/jpeg/fdct.go \
 	go/image/jpeg/huffman.go \
@@ -1405,15 +1578,46 @@
 	go/index/suffixarray/qsufsort.go \
 	go/index/suffixarray/suffixarray.go
 
+go_internal_format_files = \
+	go/internal/format/format.go
+go_internal_singleflight_files = \
+	go/internal/singleflight/singleflight.go
+
+if LIBGO_IS_LINUX
+internal_syscall_unix_getrandom_file = go/internal/syscall/unix/getrandom_linux.go
+else
+internal_syscall_unix_getrandom_file =
+endif
+
+go_internal_syscall_unix_files = \
+	go/internal/syscall/unix/dummy.go \
+	$(internal_syscall_unix_getrandom_file)
+
+go_internal_testenv_files = \
+	go/internal/testenv/testenv.go
+go_internal_trace_files = \
+	go/internal/trace/goroutines.go \
+	go/internal/trace/parser.go
+
 go_io_ioutil_files = \
 	go/io/ioutil/ioutil.go \
 	go/io/ioutil/tempfile.go
 
 go_math_big_files = \
+	go/math/big/accuracy_string.go \
 	go/math/big/arith.go \
+	go/math/big/arith_decl_pure.go \
+	go/math/big/decimal.go \
+	go/math/big/float.go \
+	go/math/big/floatconv.go \
+	go/math/big/ftoa.go \
 	go/math/big/int.go \
+	go/math/big/intconv.go \
 	go/math/big/nat.go \
-	go/math/big/rat.go
+	go/math/big/natconv.go \
+	go/math/big/rat.go \
+	go/math/big/ratconv.go \
+	go/math/big/roundingmode_string.go
 go_math_cmplx_files = \
 	go/math/cmplx/abs.go \
 	go/math/cmplx/asin.go \
@@ -1439,9 +1643,12 @@
 go_mime_multipart_files = \
 	go/mime/multipart/formdata.go \
 	go/mime/multipart/multipart.go \
-	go/mime/multipart/quotedprintable.go \
 	go/mime/multipart/writer.go
 
+go_mime_quotedprintable_files = \
+	go/mime/quotedprintable/reader.go \
+	go/mime/quotedprintable/writer.go
+
 go_net_http_files = \
 	go/net/http/client.go \
 	go/net/http/cookie.go \
@@ -1493,6 +1700,23 @@
 go_net_http_internal_files = \
 	go/net/http/internal/chunked.go
 
+if LIBGO_IS_LINUX
+go_net_internal_socktest_sys = go/net/internal/socktest/sys_cloexec.go
+else
+if LIBGO_IS_FREEBSD
+go_net_internal_socktest_sys = go/net/internal/socktest/sys_cloexec.go
+else
+go_net_internal_socktest_sys =
+endif
+endif
+
+go_net_internal_socktest_files = \
+	go/net/internal/socktest/switch.go \
+	go/net/internal/socktest/switch_posix.go \
+	go/net/internal/socktest/switch_unix.go \
+	go/net/internal/socktest/sys_unix.go \
+	$(go_net_internal_socktest_sys)
+
 go_old_regexp_files = \
 	go/old/regexp/regexp.go
 go_old_template_files = \
@@ -1503,6 +1727,7 @@
 
 go_os_exec_files = \
 	go/os/exec/exec.go \
+	go/os/exec/exec_posix.go \
 	go/os/exec/lp_unix.go
 
 go_os_signal_files = \
@@ -1554,6 +1779,7 @@
 	go/text/template/exec.go \
 	go/text/template/funcs.go \
 	go/text/template/helper.go \
+	go/text/template/option.go \
 	go/text/template/template.go
 go_text_template_parse_files = \
 	go/text/template/parse/lex.go \
@@ -1669,7 +1895,17 @@
 # Define socket sizes and types.
 if LIBGO_IS_LINUX
 syscall_socket_file = go/syscall/socket_linux.go epoll.go
+if LIBGO_IS_PPC64LE
+syscall_socket_type_file = go/syscall/socket_linux_ppc64x_type.go
 else
+if LIBGO_IS_PPC64
+syscall_socket_type_file = go/syscall/socket_linux_ppc64x_type.go
+else
+syscall_socket_type_file = go/syscall/socket_linux_type.go
+endif
+endif
+else
+syscall_socket_type_file =
 if LIBGO_IS_SOLARIS
 syscall_socket_file = go/syscall/socket_solaris.go
 else
@@ -1721,6 +1957,17 @@
 syscall_lsf_file =
 endif
 
+# GNU/Linux specific ustat support.
+if LIBGO_IS_LINUX
+if LIBGO_IS_ARM64
+syscall_ustat_file =
+else
+syscall_ustat_file = go/syscall/libcall_linux_ustat.go
+endif
+else
+syscall_ustat_file =
+endif
+
 # GNU/Linux specific utimesnano support.
 if LIBGO_IS_LINUX
 syscall_utimesnano_file = go/syscall/libcall_linux_utimesnano.go
@@ -1735,6 +1982,18 @@
 syscall_creds_test_file =
 endif
 
+if LIBGO_IS_LINUX
+syscall_exec_test_file = go/syscall/exec_linux_test.go go/syscall/syscall_linux_test.go
+else
+syscall_exec_test_file =
+endif
+
+if LIBGO_IS_LINUX
+syscall_os_file =
+else
+syscall_os_file = go/syscall/libcall_bsd.go
+endif
+
 go_base_syscall_files = \
 	go/syscall/env_unix.go \
 	go/syscall/syscall_errno.go \
@@ -1753,11 +2012,14 @@
 	$(syscall_sleep_file) \
 	$(syscall_errstr_file) \
 	$(syscall_size_file) \
+	$(syscall_os_file) \
 	$(syscall_socket_file) \
 	$(syscall_socket_os_file) \
+	$(syscall_socket_type_file) \
 	$(syscall_uname_file) \
 	$(syscall_netlink_file) \
 	$(syscall_lsf_file) \
+	$(syscall_ustat_file) \
 	$(syscall_utimesnano_file) \
 	$(GO_LIBCALL_OS_FILE) \
 	$(GO_LIBCALL_OS_ARCH_FILE) \
@@ -1776,21 +2038,14 @@
 
 go_syscall_test_files = \
 	$(syscall_creds_test_file) \
+	$(syscall_exec_test_file) \
+	go/syscall/exec_unix_test.go \
 	go/syscall/export_test.go \
+	go/syscall/export_unix_test.go \
 	go/syscall/mmap_unix_test.go \
 	go/syscall/syscall_test.go \
 	go/syscall/syscall_unix_test.go
 
-if LIBGO_IS_LINUX
-internal_syscall_getrandom_file = go/internal/syscall/getrandom_linux.go
-else
-internal_syscall_getrandom_file =
-endif
-
-go_internal_syscall_files = \
-	go/internal/syscall/dummy.go \
-	$(internal_syscall_getrandom_file)
-
 libcalls.go: s-libcalls; @true
 s-libcalls: libcalls-list go/syscall/mksyscall.awk $(go_base_syscall_files)
 	rm -f libcalls.go.tmp
@@ -1944,12 +2199,17 @@
 	html/template.lo \
 	go/ast.lo \
 	go/build.lo \
+	go/constant.lo \
 	go/doc.lo \
 	go/format.lo \
+	go/importer.lo \
+	go/internal/gcimporter.lo \
+	go/internal/gccgoimporter.lo \
 	go/parser.lo \
 	go/printer.lo \
 	go/scanner.lo \
 	go/token.lo \
+	go/types.lo \
 	hash/adler32.lo \
 	hash/crc32.lo \
 	hash/crc64.lo \
@@ -1965,10 +2225,15 @@
 	image/color/palette.lo \
 	image/draw.lo \
 	image/gif.lo \
+	image/internal/imageutil.lo \
 	image/jpeg.lo \
 	image/png.lo \
 	index/suffixarray.lo \
-	internal/syscall.lo \
+	internal/format.lo \
+	internal/singleflight.lo \
+	internal/syscall/unix.lo \
+	internal/testenv.lo \
+	internal/trace.lo \
 	io/ioutil.lo \
 	log/syslog.lo \
 	log/syslog/syslog_c.lo \
@@ -1976,7 +2241,9 @@
 	math/cmplx.lo \
 	math/rand.lo \
 	mime/multipart.lo \
+	mime/quotedprintable.lo \
 	net/http.lo \
+	net/internal/socktest.lo \
 	net/mail.lo \
 	net/rpc.lo \
 	net/smtp.lo \
@@ -2025,10 +2292,22 @@
 libgobegin_llgo_a_SOURCES = \
 	runtime/go-main.c
 
+# Use -fPIC for libgobegin so that it can be put in a PIE.
+libgobegin_a_CFLAGS = $(AM_CFLAGS) -fPIC
+libgobegin_llgo_a_CFLAGS = $(AM_CFLAGS) -fPIC
+
+libgolibbegin_a_SOURCES = \
+	runtime/go-libmain.c
+
+libgolibbegin_a_CFLAGS = $(AM_CFLAGS) -fPIC
+
+libnetgo_a_SOURCES = $(go_netgo_files)
+libnetgo_a_LIBADD = netgo.o
+
 LTLDFLAGS = $(shell $(SHELL) $(top_srcdir)/../libtool-ldflags $(LDFLAGS))
 
 GOCFLAGS = $(CFLAGS)
-AM_GOCFLAGS = $(STRINGOPS_FLAG)
+AM_GOCFLAGS = $(STRINGOPS_FLAG) $(GO_SPLIT_STACK)
 GOCOMPILE = $(GOC) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_GOCFLAGS) $(GOCFLAGS)
 
 LTGOCOMPILE = $(LIBTOOL) --tag GO --mode=compile $(GOC) $(INCLUDES) \
@@ -2049,6 +2328,12 @@
 	files=`echo $^ | sed -e 's/[^ ]*\.gox//g'`; \
 	$(LTGOCOMPILE) -I . -c -fgo-pkgpath=`echo $@ | sed -e 's/.lo$$//' -e 's/-go$$//'` -o $@ $$files
 
+# Build netgo.o.
+BUILDNETGO = \
+	$(MKDIR_P) $(@D); \
+	files=`echo $^ | sed -e 's/[^ ]*\.gox//g'`; \
+	$(GOCOMPILE) -I . -c -fPIC -fgo-pkgpath=net -o $@ $$files
+
 GOTESTFLAGS =
 GOBENCH = 
 
@@ -2069,11 +2354,11 @@
 	$(MKDIR_P) $(@D); \
 	rm -f $@-testsum $@-testlog; \
 	if test "$(USE_DEJAGNU)" = "yes"; then \
-	  $(SHELL) $(srcdir)/testsuite/gotest --dejagnu=yes --basedir=$(srcdir) --srcdir=$(srcdir)/go/$(@D) --pkgpath="$(@D)" --pkgfiles="$(go_$(subst /,_,$(@D))_files)" --testname="$(@D)" --goarch="$(GOARCH)" $(GOTESTFLAGS) $(go_$(subst /,_,$(@D))_test_files); \
+	  $(SHELL) $(srcdir)/testsuite/gotest --goarch=$(GOARCH) --goos=$(GOOS) --dejagnu=yes --basedir=$(srcdir) --srcdir=$(srcdir)/go/$(@D) --pkgpath="$(@D)" --pkgfiles="$(go_$(subst /,_,$(@D))_files)" --testname="$(@D)" $(GOTESTFLAGS) $(go_$(subst /,_,$(@D))_test_files); \
 	elif test "$(GOBENCH)" != ""; then \
-	  $(SHELL) $(srcdir)/testsuite/gotest --basedir=$(srcdir) --srcdir=$(srcdir)/go/$(@D) --pkgpath="$(@D)" --pkgfiles="$(go_$(subst /,_,$(@D))_files)" --goarch="$(GOARCH)" --bench="$(GOBENCH)" $(GOTESTFLAGS) $(go_$(subst /,_,$(@D))_test_files); \
+	  $(SHELL) $(srcdir)/testsuite/gotest --goarch=$(GOARCH) --goos=$(GOOS) --basedir=$(srcdir) --srcdir=$(srcdir)/go/$(@D) --pkgpath="$(@D)" --pkgfiles="$(go_$(subst /,_,$(@D))_files)" --bench="$(GOBENCH)" $(GOTESTFLAGS) $(go_$(subst /,_,$(@D))_test_files); \
 	else \
-	  if $(SHELL) $(srcdir)/testsuite/gotest --basedir=$(srcdir) --srcdir=$(srcdir)/go/$(@D) --pkgpath="$(@D)" --pkgfiles="$(go_$(subst /,_,$(@D))_files)" --goarch="$(GOARCH)" $(GOTESTFLAGS) $(go_$(subst /,_,$(@D))_test_files) >>$@-testlog 2>&1; then \
+	  if $(SHELL) $(srcdir)/testsuite/gotest --goarch=$(GOARCH) --goos=$(GOOS) --basedir=$(srcdir) --srcdir=$(srcdir)/go/$(@D) --pkgpath="$(@D)" --pkgfiles="$(go_$(subst /,_,$(@D))_files)" $(GOTESTFLAGS) $(go_$(subst /,_,$(@D))_test_files) >>$@-testlog 2>&1; then \
 	    echo "PASS: $(@D)" >> $@-testlog; \
 	    echo "PASS: $(@D)"; \
 	    echo "PASS: $(@D)" > $@-testsum; \
@@ -2270,6 +2555,12 @@
 	@$(CHECK)
 .PHONY: net/check
 
+@go_include@ netgo.o.dep
+netgo.o.dep: $(go_netgo_files)
+	$(BUILDDEPS)
+netgo.o: $(go_netgo_files)
+	$(BUILDNETGO)
+
 @go_include@ os.lo.dep
 os.lo.dep: $(go_os_files)
 	$(BUILDDEPS)
@@ -2852,6 +3143,15 @@
 	@$(CHECK)
 .PHONY: go/build/check
 
+@go_include@ go/constant.lo.dep
+go/constant.lo.dep: $(go_go_constant_files)
+	$(BUILDDEPS)
+go/constant.lo: $(go_go_constant_files)
+	$(BUILDPACKAGE)
+go/constant/check: $(CHECK_DEPS)
+	@$(CHECK)
+.PHONY: go/constant/check
+
 @go_include@ go/doc.lo.dep
 go/doc.lo.dep: $(go_go_doc_files)
 	$(BUILDDEPS)
@@ -2870,6 +3170,15 @@
 	@$(CHECK)
 .PHONY: go/format/check
 
+@go_include@ go/importer.lo.dep
+go/importer.lo.dep: $(go_go_importer_files)
+	$(BUILDDEPS)
+go/importer.lo: $(go_go_importer_files)
+	$(BUILDPACKAGE)
+go/importer/check: $(CHECK_DEPS)
+	@$(CHECK)
+.PHONY: go/importer/check
+
 @go_include@ go/parser.lo.dep
 go/parser.lo.dep: $(go_go_parser_files)
 	$(BUILDDEPS)
@@ -2906,6 +3215,33 @@
 	@$(CHECK)
 .PHONY: go/token/check
 
+@go_include@ go/types.lo.dep
+go/types.lo.dep: $(go_go_types_files)
+	$(BUILDDEPS)
+go/types.lo: $(go_go_types_files)
+	$(BUILDPACKAGE)
+go/types/check: $(CHECK_DEPS)
+	@$(CHECK)
+.PHONY: go/types/check
+
+@go_include@ go/internal/gcimporter.lo.dep
+go/internal/gcimporter.lo.dep: $(go_go_internal_gcimporter_files)
+	$(BUILDDEPS)
+go/internal/gcimporter.lo: $(go_go_internal_gcimporter_files)
+	$(BUILDPACKAGE)
+go/internal/gcimporter/check: $(CHECK_DEPS)
+	@$(CHECK)
+.PHONY: go/internal/gcimporter/check
+
+@go_include@ go/internal/gccgoimporter.lo.dep
+go/internal/gccgoimporter.lo.dep: $(go_go_internal_gccgoimporter_files)
+	$(BUILDDEPS)
+go/internal/gccgoimporter.lo: $(go_go_internal_gccgoimporter_files)
+	$(BUILDPACKAGE)
+go/internal/gccgoimporter/check: $(CHECK_DEPS)
+	@$(CHECK)
+.PHONY: go/internal/gccgoimporter/check
+
 @go_include@ hash/adler32.lo.dep
 hash/adler32.lo.dep: $(go_hash_adler32_files)
 	$(BUILDDEPS)
@@ -2978,6 +3314,15 @@
 	@$(CHECK)
 .PHONY: image/gif/check
 
+@go_include@ image/internal/imageutil.lo.dep
+image/internal/imageutil.lo.dep: $(go_image_internal_imageutil_files)
+	$(BUILDDEPS)
+image/internal/imageutil.lo: $(go_image_internal_imageutil_files)
+	$(BUILDPACKAGE)
+image/internal/imageutil/check: $(CHECK_DEPS)
+	@$(CHECK)
+.PHONY: image/internal/imageutil/check
+
 @go_include@ image/jpeg.lo.dep
 image/jpeg.lo.dep: $(go_image_jpeg_files)
 	$(BUILDDEPS)
@@ -3005,6 +3350,51 @@
 	@$(CHECK)
 .PHONY: index/suffixarray/check
 
+@go_include@ internal/format.lo.dep
+internal/format.lo.dep: $(go_internal_format_files)
+	$(BUILDDEPS)
+internal/format.lo: $(go_internal_format_files)
+	$(BUILDPACKAGE)
+internal/format/check: $(CHECK_DEPS)
+	@$(CHECK)
+.PHONY: internal/format/check
+
+@go_include@ internal/singleflight.lo.dep
+internal/singleflight.lo.dep: $(go_internal_singleflight_files)
+	$(BUILDDEPS)
+internal/singleflight.lo: $(go_internal_singleflight_files)
+	$(BUILDPACKAGE)
+internal/singleflight/check: $(CHECK_DEPS)
+	@$(CHECK)
+.PHONY: internal/singleflight/check
+
+@go_include@ internal/syscall/unix.lo.dep
+internal/syscall/unix.lo.dep: $(go_internal_syscall_unix_files)
+	$(BUILDDEPS)
+internal/syscall/unix.lo: $(go_internal_syscall_unix_files)
+	$(BUILDPACKAGE)
+internal/syscall/unix/check: $(CHECK_DEPS)
+	@$(CHECK)
+.PHONY: internal/syscall/unix/check
+
+@go_include@ internal/testenv.lo.dep
+internal/testenv.lo.dep: $(go_internal_testenv_files)
+	$(BUILDDEPS)
+internal/testenv.lo: $(go_internal_testenv_files)
+	$(BUILDPACKAGE)
+internal/testenv/check: $(CHECK_DEPS)
+	@$(CHECK)
+.PHONY: internal/testenv/check
+
+@go_include@ internal/trace.lo.dep
+internal/trace.lo.dep: $(go_internal_trace_files)
+	$(BUILDDEPS)
+internal/trace.lo: $(go_internal_trace_files)
+	$(BUILDPACKAGE)
+internal/trace/check: $(CHECK_DEPS)
+	@$(CHECK)
+.PHONY: internal/trace/check
+
 @go_include@ io/ioutil.lo.dep
 io/ioutil.lo.dep: $(go_io_ioutil_files)
 	$(BUILDDEPS)
@@ -3062,6 +3452,15 @@
 	@$(CHECK)
 .PHONY: mime/multipart/check
 
+@go_include@ mime/quotedprintable.lo.dep
+mime/quotedprintable.lo.dep: $(go_mime_quotedprintable_files)
+	$(BUILDDEPS)
+mime/quotedprintable.lo: $(go_mime_quotedprintable_files)
+	$(BUILDPACKAGE)
+mime/quotedprintable/check: $(CHECK_DEPS)
+	@$(CHECK)
+.PHONY: mime/quotedprintable/check
+
 @go_include@ net/http.lo.dep
 net/http.lo.dep: $(go_net_http_files)
 	$(BUILDDEPS)
@@ -3179,6 +3578,15 @@
 	@$(CHECK)
 .PHONY: net/http/pprof/check
 
+@go_include@ net/internal/socktest.lo.dep
+net/internal/socktest.lo.dep: $(go_net_internal_socktest_files)
+	$(BUILDDEPS)
+net/internal/socktest.lo: $(go_net_internal_socktest_files)
+	$(BUILDPACKAGE)
+net/internal/socktest/check: $(CHECK_DEPS)
+	@$(CHECK)
+.PHONY: net/internal/socktest/check
+
 @go_include@ net/rpc/jsonrpc.lo.dep
 net/rpc/jsonrpc.lo.dep: $(go_net_rpc_jsonrpc_files)
 	$(BUILDDEPS)
@@ -3374,15 +3782,6 @@
 	@$(CHECK)
 .PHONY: syscall/check
 
-@go_include@ internal/syscall.lo.dep
-internal/syscall.lo.dep: $(go_internal_syscall_files)
-	$(BUILDDEPS)
-internal/syscall.lo: $(go_internal_syscall_files)
-	$(BUILDPACKAGE)
-internal/syscall/check: $(CHECK_DEPS)
-	@$(CHECK)
-.PHONY: internal/syscall/check
-
 # How to build a .gox file from a .lo file.
 BUILDGOX = \
 	f=`echo $< | sed -e 's/.lo$$/.o/'`; \
@@ -3562,10 +3961,14 @@
 	$(BUILDGOX)
 go/build.gox: go/build.lo
 	$(BUILDGOX)
+go/constant.gox: go/constant.lo
+	$(BUILDGOX)
 go/doc.gox: go/doc.lo
 	$(BUILDGOX)
 go/format.gox: go/format.lo
 	$(BUILDGOX)
+go/importer.gox: go/importer.lo
+	$(BUILDGOX)
 go/parser.gox: go/parser.lo
 	$(BUILDGOX)
 go/printer.gox: go/printer.lo
@@ -3574,6 +3977,13 @@
 	$(BUILDGOX)
 go/token.gox: go/token.lo
 	$(BUILDGOX)
+go/types.gox: go/types.lo
+	$(BUILDGOX)
+
+go/internal/gcimporter.gox: go/internal/gcimporter.lo
+	$(BUILDGOX)
+go/internal/gccgoimporter.gox: go/internal/gccgoimporter.lo
+	$(BUILDGOX)
 
 hash/adler32.gox: hash/adler32.lo
 	$(BUILDGOX)
@@ -3590,6 +4000,8 @@
 	$(BUILDGOX)
 image/gif.gox: image/gif.lo
 	$(BUILDGOX)
+image/internal/imageutil.gox: image/internal/imageutil.lo
+	$(BUILDGOX)
 image/jpeg.gox: image/jpeg.lo
 	$(BUILDGOX)
 image/png.gox: image/png.lo
@@ -3601,6 +4013,17 @@
 index/suffixarray.gox: index/suffixarray.lo
 	$(BUILDGOX)
 
+internal/format.gox: internal/format.lo
+	$(BUILDGOX)
+internal/singleflight.gox: internal/singleflight.lo
+	$(BUILDGOX)
+internal/syscall/unix.gox: internal/syscall/unix.lo
+	$(BUILDGOX)
+internal/testenv.gox: internal/testenv.lo
+	$(BUILDGOX)
+internal/trace.gox: internal/trace.lo
+	$(BUILDGOX)
+
 io/ioutil.gox: io/ioutil.lo
 	$(BUILDGOX)
 
@@ -3616,6 +4039,8 @@
 
 mime/multipart.gox: mime/multipart.lo
 	$(BUILDGOX)
+mime/quotedprintable.gox: mime/quotedprintable.lo
+	$(BUILDGOX)
 
 net/http.gox: net/http.lo
 	$(BUILDGOX)
@@ -3646,6 +4071,9 @@
 net/http/internal.gox: net/http/internal.lo
 	$(BUILDGOX)
 
+net/internal/socktest.gox: net/internal/socktest.lo
+	$(BUILDGOX)
+
 net/rpc/jsonrpc.gox: net/rpc/jsonrpc.lo
 	$(BUILDGOX)
 
@@ -3675,9 +4103,6 @@
 sync/atomic.gox: sync/atomic.lo
 	$(BUILDGOX)
 
-internal/syscall.gox: internal/syscall.lo
-	$(BUILDGOX)
-
 text/scanner.gox: text/scanner.lo
 	$(BUILDGOX)
 text/tabwriter.gox: text/tabwriter.lo
@@ -3771,13 +4196,17 @@
 	exp/terminal/check \
 	html/template/check \
 	go/ast/check \
-	$(go_build_check_omitted_since_it_calls_6g) \
+	go/build/check \
+	go/constant/check \
 	go/doc/check \
 	go/format/check \
+	go/internal/gcimporter/check \
+	go/internal/gccgoimporter/check \
 	go/parser/check \
 	go/printer/check \
 	go/scanner/check \
 	go/token/check \
+	go/types/check \
 	hash/adler32/check \
 	hash/crc32/check \
 	hash/crc64/check \
@@ -3787,12 +4216,15 @@
 	image/jpeg/check \
 	image/png/check \
 	index/suffixarray/check \
+	internal/singleflight/check \
+	internal/trace/check \
 	io/ioutil/check \
 	log/syslog/check \
 	math/big/check \
 	math/cmplx/check \
 	math/rand/check \
 	mime/multipart/check \
+	mime/quotedprintable/check \
 	net/http/check \
 	net/http/cgi/check \
 	net/http/cookiejar/check \
@@ -3800,6 +4232,7 @@
 	net/http/httptest/check \
 	net/http/httputil/check \
 	net/http/internal/check \
+	net/internal/socktest/check \
 	net/mail/check \
 	net/rpc/check \
 	net/smtp/check \
diff --git a/third_party/gofrontend/libgo/Makefile.in b/third_party/gofrontend/libgo/Makefile.in
index 532bc46..8a80798 100644
--- a/third_party/gofrontend/libgo/Makefile.in
+++ b/third_party/gofrontend/libgo/Makefile.in
@@ -1,9 +1,9 @@
-# Makefile.in generated by automake 1.11.1 from Makefile.am.
+# Makefile.in generated by automake 1.11.6 from Makefile.am.
 # @configure_input@
 
 # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
-# 2003, 2004, 2005, 2006, 2007, 2008, 2009  Free Software Foundation,
-# Inc.
+# 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software
+# Foundation, Inc.
 # This Makefile.in is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
 # with or without modifications, as long as this notice is preserved.
@@ -26,6 +26,23 @@
 
 
 VPATH = @srcdir@
+am__make_dryrun = \
+  { \
+    am__dry=no; \
+    case $$MAKEFLAGS in \
+      *\\[\ \	]*) \
+        echo 'am--echo: ; @echo "AM"  OK' | $(MAKE) -f - 2>/dev/null \
+          | grep '^AM OK$$' >/dev/null || am__dry=yes;; \
+      *) \
+        for am__flg in $$MAKEFLAGS; do \
+          case $$am__flg in \
+            *=*|--*) ;; \
+            *n*) am__dry=yes; break;; \
+          esac; \
+        done;; \
+    esac; \
+    test $$am__dry = yes; \
+  }
 pkgdatadir = $(datadir)/@PACKAGE@
 pkgincludedir = $(includedir)/@PACKAGE@
 pkglibdir = $(libdir)/@PACKAGE@
@@ -91,6 +108,12 @@
 am__base_list = \
   sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
   sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
+am__uninstall_files_from_dir = { \
+  test -z "$$files" \
+    || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
+    || { echo " ( cd '$$dir' && rm -f" $$files ")"; \
+         $(am__cd) "$$dir" && rm -f $$files; }; \
+  }
 am__installdirs = "$(DESTDIR)$(toolexeclibdir)" \
 	"$(DESTDIR)$(toolexeclibdir)" "$(DESTDIR)$(toolexeclibgodir)" \
 	"$(DESTDIR)$(toolexeclibgoarchivedir)" \
@@ -130,12 +153,25 @@
 ARFLAGS = cru
 libgobegin_llgo_a_AR = $(AR) $(ARFLAGS)
 libgobegin_llgo_a_LIBADD =
-am_libgobegin_llgo_a_OBJECTS = go-main.$(OBJEXT)
+am_libgobegin_llgo_a_OBJECTS = libgobegin_llgo_a-go-main.$(OBJEXT)
 libgobegin_llgo_a_OBJECTS = $(am_libgobegin_llgo_a_OBJECTS)
 libgobegin_a_AR = $(AR) $(ARFLAGS)
 libgobegin_a_LIBADD =
-am_libgobegin_a_OBJECTS = go-main.$(OBJEXT)
+am_libgobegin_a_OBJECTS = libgobegin_a-go-main.$(OBJEXT)
 libgobegin_a_OBJECTS = $(am_libgobegin_a_OBJECTS)
+libgolibbegin_a_AR = $(AR) $(ARFLAGS)
+libgolibbegin_a_LIBADD =
+am_libgolibbegin_a_OBJECTS = libgolibbegin_a-go-libmain.$(OBJEXT)
+libgolibbegin_a_OBJECTS = $(am_libgolibbegin_a_OBJECTS)
+libnetgo_a_AR = $(AR) $(ARFLAGS)
+libnetgo_a_DEPENDENCIES = netgo.o
+am__objects_1 =
+am__objects_2 = $(am__objects_1) $(am__objects_1) $(am__objects_1) \
+	$(am__objects_1) $(am__objects_1) $(am__objects_1) \
+	$(am__objects_1)
+am__objects_3 = $(am__objects_2)
+am_libnetgo_a_OBJECTS = $(am__objects_3)
+libnetgo_a_OBJECTS = $(am_libnetgo_a_OBJECTS)
 LTLIBRARIES = $(toolexeclib_LTLIBRARIES)
 am__DEPENDENCIES_1 =
 am__DEPENDENCIES_2 = bufio.lo bytes.lo bytes/index.lo crypto.lo \
@@ -160,16 +196,21 @@
 	encoding/binary.lo encoding/csv.lo encoding/gob.lo \
 	encoding/hex.lo encoding/json.lo encoding/pem.lo \
 	encoding/xml.lo exp/proxy.lo exp/terminal.lo html/template.lo \
-	go/ast.lo go/build.lo go/doc.lo go/format.lo go/parser.lo \
-	go/printer.lo go/scanner.lo go/token.lo hash/adler32.lo \
+	go/ast.lo go/build.lo go/constant.lo go/doc.lo go/format.lo \
+	go/importer.lo go/internal/gcimporter.lo \
+	go/internal/gccgoimporter.lo go/parser.lo go/printer.lo \
+	go/scanner.lo go/token.lo go/types.lo hash/adler32.lo \
 	hash/crc32.lo hash/crc64.lo hash/fnv.lo net/http/cgi.lo \
 	net/http/cookiejar.lo net/http/fcgi.lo net/http/httptest.lo \
 	net/http/httputil.lo net/http/internal.lo net/http/pprof.lo \
 	image/color.lo image/color/palette.lo image/draw.lo \
-	image/gif.lo image/jpeg.lo image/png.lo index/suffixarray.lo \
-	internal/syscall.lo io/ioutil.lo log/syslog.lo \
-	log/syslog/syslog_c.lo math/big.lo math/cmplx.lo math/rand.lo \
-	mime/multipart.lo net/http.lo net/mail.lo net/rpc.lo \
+	image/gif.lo image/internal/imageutil.lo image/jpeg.lo \
+	image/png.lo index/suffixarray.lo internal/format.lo \
+	internal/singleflight.lo internal/syscall/unix.lo \
+	internal/testenv.lo internal/trace.lo io/ioutil.lo \
+	log/syslog.lo log/syslog/syslog_c.lo math/big.lo math/cmplx.lo \
+	math/rand.lo mime/multipart.lo mime/quotedprintable.lo \
+	net/http.lo net/internal/socktest.lo net/mail.lo net/rpc.lo \
 	net/smtp.lo net/textproto.lo net/url.lo old/regexp.lo \
 	old/template.lo os/exec.lo $(am__DEPENDENCIES_1) os/signal.lo \
 	os/user.lo path/filepath.lo regexp/syntax.lo \
@@ -183,23 +224,23 @@
 	$(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
 	$(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1)
 libgo_llgo_la_DEPENDENCIES = $(am__DEPENDENCIES_3)
-@LIBGO_IS_LINUX_FALSE@am__objects_1 = lock_sema.lo thread-sema.lo
-@LIBGO_IS_LINUX_TRUE@am__objects_1 = lock_futex.lo thread-linux.lo
-@HAVE_SYS_MMAN_H_FALSE@am__objects_2 = mem_posix_memalign.lo
-@HAVE_SYS_MMAN_H_TRUE@am__objects_2 = mem.lo
-@LIBGO_IS_LINUX_FALSE@@LIBGO_IS_SOLARIS_FALSE@am__objects_3 = netpoll_kqueue.lo
-@LIBGO_IS_LINUX_FALSE@@LIBGO_IS_SOLARIS_TRUE@am__objects_3 = netpoll_select.lo
-@LIBGO_IS_LINUX_TRUE@am__objects_3 = netpoll_epoll.lo
-@LIBGO_IS_RTEMS_TRUE@am__objects_4 = rtems-task-variable-add.lo
-@LIBGO_IS_DARWIN_FALSE@@LIBGO_IS_FREEBSD_FALSE@@LIBGO_IS_IRIX_FALSE@@LIBGO_IS_LINUX_FALSE@@LIBGO_IS_NETBSD_FALSE@@LIBGO_IS_SOLARIS_FALSE@am__objects_5 = getncpu-none.lo
-@LIBGO_IS_DARWIN_FALSE@@LIBGO_IS_FREEBSD_FALSE@@LIBGO_IS_IRIX_FALSE@@LIBGO_IS_LINUX_FALSE@@LIBGO_IS_NETBSD_TRUE@@LIBGO_IS_SOLARIS_FALSE@am__objects_5 = getncpu-bsd.lo
-@LIBGO_IS_DARWIN_FALSE@@LIBGO_IS_FREEBSD_TRUE@@LIBGO_IS_IRIX_FALSE@@LIBGO_IS_LINUX_FALSE@@LIBGO_IS_SOLARIS_FALSE@am__objects_5 = getncpu-bsd.lo
-@LIBGO_IS_DARWIN_FALSE@@LIBGO_IS_IRIX_FALSE@@LIBGO_IS_LINUX_FALSE@@LIBGO_IS_SOLARIS_TRUE@am__objects_5 = getncpu-solaris.lo
-@LIBGO_IS_DARWIN_FALSE@@LIBGO_IS_IRIX_TRUE@@LIBGO_IS_LINUX_FALSE@am__objects_5 = getncpu-irix.lo
-@LIBGO_IS_DARWIN_TRUE@@LIBGO_IS_LINUX_FALSE@am__objects_5 =  \
+@LIBGO_IS_LINUX_FALSE@am__objects_4 = lock_sema.lo thread-sema.lo
+@LIBGO_IS_LINUX_TRUE@am__objects_4 = lock_futex.lo thread-linux.lo
+@HAVE_SYS_MMAN_H_FALSE@am__objects_5 = mem_posix_memalign.lo
+@HAVE_SYS_MMAN_H_TRUE@am__objects_5 = mem.lo
+@LIBGO_IS_LINUX_FALSE@@LIBGO_IS_SOLARIS_FALSE@am__objects_6 = netpoll_kqueue.lo
+@LIBGO_IS_LINUX_FALSE@@LIBGO_IS_SOLARIS_TRUE@am__objects_6 = netpoll_select.lo
+@LIBGO_IS_LINUX_TRUE@am__objects_6 = netpoll_epoll.lo
+@LIBGO_IS_RTEMS_TRUE@am__objects_7 = rtems-task-variable-add.lo
+@LIBGO_IS_DARWIN_FALSE@@LIBGO_IS_FREEBSD_FALSE@@LIBGO_IS_IRIX_FALSE@@LIBGO_IS_LINUX_FALSE@@LIBGO_IS_NETBSD_FALSE@@LIBGO_IS_SOLARIS_FALSE@am__objects_8 = getncpu-none.lo
+@LIBGO_IS_DARWIN_FALSE@@LIBGO_IS_FREEBSD_FALSE@@LIBGO_IS_IRIX_FALSE@@LIBGO_IS_LINUX_FALSE@@LIBGO_IS_NETBSD_TRUE@@LIBGO_IS_SOLARIS_FALSE@am__objects_8 = getncpu-bsd.lo
+@LIBGO_IS_DARWIN_FALSE@@LIBGO_IS_FREEBSD_TRUE@@LIBGO_IS_IRIX_FALSE@@LIBGO_IS_LINUX_FALSE@@LIBGO_IS_SOLARIS_FALSE@am__objects_8 = getncpu-bsd.lo
+@LIBGO_IS_DARWIN_FALSE@@LIBGO_IS_IRIX_FALSE@@LIBGO_IS_LINUX_FALSE@@LIBGO_IS_SOLARIS_TRUE@am__objects_8 = getncpu-solaris.lo
+@LIBGO_IS_DARWIN_FALSE@@LIBGO_IS_IRIX_TRUE@@LIBGO_IS_LINUX_FALSE@am__objects_8 = getncpu-irix.lo
+@LIBGO_IS_DARWIN_TRUE@@LIBGO_IS_LINUX_FALSE@am__objects_8 =  \
 @LIBGO_IS_DARWIN_TRUE@@LIBGO_IS_LINUX_FALSE@	getncpu-bsd.lo
-@LIBGO_IS_LINUX_TRUE@am__objects_5 = getncpu-linux.lo
-am__objects_6 = go-append.lo go-assert.lo go-assert-interface.lo \
+@LIBGO_IS_LINUX_TRUE@am__objects_8 = getncpu-linux.lo
+am__objects_9 = go-append.lo go-assert.lo go-assert-interface.lo \
 	go-byte-array-to-string.lo go-breakpoint.lo go-caller.lo \
 	go-callers.lo go-can-convert-interface.lo go-cdiv.lo go-cgo.lo \
 	go-check-interface.lo go-construct-map.lo \
@@ -221,21 +262,21 @@
 	go-type-string.lo go-typedesc-equal.lo go-unsafe-new.lo \
 	go-unsafe-newarray.lo go-unsafe-pointer.lo go-unsetenv.lo \
 	go-unwind.lo go-varargs.lo env_posix.lo heapdump.lo \
-	$(am__objects_1) mcache.lo mcentral.lo $(am__objects_2) \
-	mfixalloc.lo mgc0.lo mheap.lo msize.lo $(am__objects_3) \
+	$(am__objects_4) mcache.lo mcentral.lo $(am__objects_5) \
+	mfixalloc.lo mgc0.lo mheap.lo msize.lo $(am__objects_6) \
 	panic.lo parfor.lo print.lo proc.lo runtime.lo signal_unix.lo \
-	thread.lo yield.lo $(am__objects_4) chan.lo cpuprof.lo \
+	thread.lo yield.lo $(am__objects_7) chan.lo cpuprof.lo \
 	go-iface.lo lfstack.lo malloc.lo map.lo mprof.lo netpoll.lo \
 	rdebug.lo reflect.lo runtime1.lo sema.lo sigqueue.lo string.lo \
-	time.lo $(am__objects_5)
-am_libgo_llgo_la_OBJECTS = $(am__objects_6)
+	time.lo $(am__objects_8)
+am_libgo_llgo_la_OBJECTS = $(am__objects_9)
 libgo_llgo_la_OBJECTS = $(am_libgo_llgo_la_OBJECTS)
 libgo_llgo_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \
 	$(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
 	$(libgo_llgo_la_LDFLAGS) $(LDFLAGS) -o $@
 @GOC_IS_LLGO_TRUE@am_libgo_llgo_la_rpath = -rpath $(toolexeclibdir)
 libgo_la_DEPENDENCIES = $(am__DEPENDENCIES_3)
-am_libgo_la_OBJECTS = $(am__objects_6)
+am_libgo_la_OBJECTS = $(am__objects_9)
 libgo_la_OBJECTS = $(am_libgo_la_OBJECTS)
 libgo_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
 	--mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(libgo_la_LDFLAGS) \
@@ -255,6 +296,7 @@
 	--mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \
 	$(LDFLAGS) -o $@
 SOURCES = $(libgobegin_llgo_a_SOURCES) $(libgobegin_a_SOURCES) \
+	$(libgolibbegin_a_SOURCES) $(libnetgo_a_SOURCES) \
 	$(libgo_llgo_la_SOURCES) $(libgo_la_SOURCES)
 MULTISRCTOP = 
 MULTIBUILDTOP = 
@@ -269,6 +311,11 @@
 	install-pdf-recursive install-ps-recursive install-recursive \
 	installcheck-recursive installdirs-recursive pdf-recursive \
 	ps-recursive uninstall-recursive
+am__can_run_installinfo = \
+  case $$AM_UPDATE_INFO_DIR in \
+    n|no|NO) false;; \
+    *) (install-info --version) >/dev/null 2>&1;; \
+  esac
 DATA = $(noinst_DATA) $(toolexeclibgo_DATA) \
 	$(toolexeclibgoarchive_DATA) $(toolexeclibgocompress_DATA) \
 	$(toolexeclibgocontainer_DATA) $(toolexeclibgocrypto_DATA) \
@@ -324,6 +371,7 @@
 GOOS = @GOOS@
 GO_LIBCALL_OS_ARCH_FILE = @GO_LIBCALL_OS_ARCH_FILE@
 GO_LIBCALL_OS_FILE = @GO_LIBCALL_OS_FILE@
+GO_SPLIT_STACK = @GO_SPLIT_STACK@
 GO_SYSCALL_OS_ARCH_FILE = @GO_SYSCALL_OS_ARCH_FILE@
 GO_SYSCALL_OS_FILE = @GO_SYSCALL_OS_FILE@
 GREP = @GREP@
@@ -522,7 +570,7 @@
 FLAGS_TO_PASS = $(AM_MAKEFLAGS)
 @GOC_IS_LLGO_FALSE@toolexeclib_LTLIBRARIES = libgo.la
 @GOC_IS_LLGO_TRUE@toolexeclib_LTLIBRARIES = libgo-llgo.la
-@GOC_IS_LLGO_FALSE@toolexeclib_LIBRARIES = libgobegin.a
+@GOC_IS_LLGO_FALSE@toolexeclib_LIBRARIES = libgobegin.a libgolibbegin.a libnetgo.a
 @GOC_IS_LLGO_TRUE@toolexeclib_LIBRARIES = libgobegin-llgo.a
 toolexeclibgo_DATA = \
 	bufio.gox \
@@ -638,12 +686,15 @@
 toolexeclibgogo_DATA = \
 	go/ast.gox \
 	go/build.gox \
+	go/constant.gox \
 	go/doc.gox \
 	go/format.gox \
+	go/importer.gox \
 	go/parser.gox \
 	go/printer.gox \
 	go/scanner.gox \
-	go/token.gox
+	go/token.gox \
+	go/types.gox
 
 toolexeclibgohashdir = $(toolexeclibgodir)/hash
 toolexeclibgohash_DATA = \
@@ -688,7 +739,8 @@
 
 toolexeclibgomimedir = $(toolexeclibgodir)/mime
 toolexeclibgomime_DATA = \
-	mime/multipart.gox
+	mime/multipart.gox \
+	mime/quotedprintable.gox
 
 toolexeclibgonetdir = $(toolexeclibgodir)/net
 toolexeclibgonet_DATA = \
@@ -980,16 +1032,22 @@
 	go/math/tanh.go \
 	go/math/unsafe.go
 
+@LIBGO_IS_DRAGONFLY_FALSE@@LIBGO_IS_FREEBSD_FALSE@@LIBGO_IS_OPENBSD_FALSE@go_mime_type_file = 
+@LIBGO_IS_DRAGONFLY_TRUE@@LIBGO_IS_FREEBSD_FALSE@@LIBGO_IS_OPENBSD_FALSE@go_mime_type_file = go/mime/type_dragonfly.go
+@LIBGO_IS_FREEBSD_TRUE@@LIBGO_IS_OPENBSD_FALSE@go_mime_type_file = go/mime/type_freebsd.go
+@LIBGO_IS_OPENBSD_TRUE@go_mime_type_file = go/mime/type_openbsd.go
 go_mime_files = \
+	go/mime/encodedword.go \
 	go/mime/grammar.go \
 	go/mime/mediatype.go \
 	go/mime/type.go \
-	go/mime/type_unix.go
+	go/mime/type_unix.go \
+	$(go_mime_type_file)
 
 @LIBGO_IS_FREEBSD_FALSE@@LIBGO_IS_IRIX_FALSE@@LIBGO_IS_LINUX_FALSE@@LIBGO_IS_NETBSD_FALSE@@LIBGO_IS_SOLARIS_FALSE@go_net_cgo_file = go/net/cgo_bsd.go
 @LIBGO_IS_FREEBSD_FALSE@@LIBGO_IS_IRIX_FALSE@@LIBGO_IS_LINUX_FALSE@@LIBGO_IS_NETBSD_TRUE@@LIBGO_IS_SOLARIS_FALSE@go_net_cgo_file = go/net/cgo_netbsd.go
 @LIBGO_IS_FREEBSD_TRUE@@LIBGO_IS_IRIX_FALSE@@LIBGO_IS_LINUX_FALSE@@LIBGO_IS_SOLARIS_FALSE@go_net_cgo_file = go/net/cgo_bsd.go
-@LIBGO_IS_IRIX_FALSE@@LIBGO_IS_LINUX_FALSE@@LIBGO_IS_SOLARIS_TRUE@go_net_cgo_file = go/net/cgo_linux.go
+@LIBGO_IS_IRIX_FALSE@@LIBGO_IS_LINUX_FALSE@@LIBGO_IS_SOLARIS_TRUE@go_net_cgo_file = go/net/cgo_solaris.go
 @LIBGO_IS_IRIX_TRUE@@LIBGO_IS_LINUX_FALSE@go_net_cgo_file = go/net/cgo_linux.go
 @LIBGO_IS_LINUX_TRUE@go_net_cgo_file = go/net/cgo_linux.go
 @LIBGO_IS_FREEBSD_FALSE@@LIBGO_IS_IRIX_FALSE@@LIBGO_IS_LINUX_FALSE@@LIBGO_IS_NETBSD_FALSE@@LIBGO_IS_SOLARIS_FALSE@go_net_sock_file = go/net/sock_bsd.go
@@ -1010,7 +1068,20 @@
 @LIBGO_IS_IRIX_FALSE@@LIBGO_IS_LINUX_FALSE@@LIBGO_IS_SOLARIS_TRUE@go_net_sockoptip_file = go/net/sockoptip_stub.go
 @LIBGO_IS_IRIX_TRUE@@LIBGO_IS_LINUX_FALSE@go_net_sockoptip_file = go/net/sockoptip_linux.go go/net/sockoptip_posix.go
 @LIBGO_IS_LINUX_TRUE@go_net_sockoptip_file = go/net/sockoptip_linux.go go/net/sockoptip_posix.go
-@LIBGO_IS_DRAGONFLY_FALSE@@LIBGO_IS_FREEBSD_FALSE@@LIBGO_IS_LINUX_FALSE@go_net_sendfile_file = go/net/sendfile_stub.go
+@LIBGO_IS_FREEBSD_FALSE@@LIBGO_IS_IRIX_FALSE@@LIBGO_IS_LINUX_FALSE@@LIBGO_IS_NETBSD_FALSE@@LIBGO_IS_SOLARIS_FALSE@go_net_cgo_sock_file = go/net/cgo_sockold.go
+@LIBGO_IS_FREEBSD_FALSE@@LIBGO_IS_IRIX_FALSE@@LIBGO_IS_LINUX_FALSE@@LIBGO_IS_NETBSD_TRUE@@LIBGO_IS_SOLARIS_FALSE@go_net_cgo_sock_file = go/net/cgo_sockold.go
+@LIBGO_IS_FREEBSD_TRUE@@LIBGO_IS_IRIX_FALSE@@LIBGO_IS_LINUX_FALSE@@LIBGO_IS_SOLARIS_FALSE@go_net_cgo_sock_file = go/net/cgo_sockold.go
+@LIBGO_IS_IRIX_FALSE@@LIBGO_IS_LINUX_FALSE@@LIBGO_IS_SOLARIS_TRUE@go_net_cgo_sock_file = go/net/cgo_socknew.go
+@LIBGO_IS_IRIX_TRUE@@LIBGO_IS_LINUX_FALSE@go_net_cgo_sock_file = go/net/cgo_socknew.go
+@LIBGO_IS_LINUX_TRUE@go_net_cgo_sock_file = go/net/cgo_socknew.go
+@LIBGO_IS_FREEBSD_FALSE@@LIBGO_IS_IRIX_FALSE@@LIBGO_IS_LINUX_FALSE@@LIBGO_IS_NETBSD_FALSE@@LIBGO_IS_SOLARIS_FALSE@go_net_cgo_res_file = go/net/cgo_resold.go
+@LIBGO_IS_FREEBSD_FALSE@@LIBGO_IS_IRIX_FALSE@@LIBGO_IS_LINUX_FALSE@@LIBGO_IS_NETBSD_TRUE@@LIBGO_IS_SOLARIS_FALSE@go_net_cgo_res_file = go/net/cgo_resnew.go
+@LIBGO_IS_FREEBSD_TRUE@@LIBGO_IS_IRIX_FALSE@@LIBGO_IS_LINUX_FALSE@@LIBGO_IS_SOLARIS_FALSE@go_net_cgo_res_file = go/net/cgo_resold.go
+@LIBGO_IS_IRIX_FALSE@@LIBGO_IS_LINUX_FALSE@@LIBGO_IS_SOLARIS_TRUE@go_net_cgo_res_file = go/net/cgo_resnew.go
+@LIBGO_IS_IRIX_TRUE@@LIBGO_IS_LINUX_FALSE@go_net_cgo_res_file = go/net/cgo_resnew.go
+@LIBGO_IS_LINUX_TRUE@go_net_cgo_res_file = go/net/cgo_resnew.go
+@LIBGO_IS_DRAGONFLY_FALSE@@LIBGO_IS_FREEBSD_FALSE@@LIBGO_IS_LINUX_FALSE@@LIBGO_IS_SOLARIS_FALSE@go_net_sendfile_file = go/net/sendfile_stub.go
+@LIBGO_IS_DRAGONFLY_FALSE@@LIBGO_IS_FREEBSD_FALSE@@LIBGO_IS_LINUX_FALSE@@LIBGO_IS_SOLARIS_TRUE@go_net_sendfile_file = go/net/sendfile_solaris.go
 @LIBGO_IS_DRAGONFLY_TRUE@@LIBGO_IS_FREEBSD_FALSE@@LIBGO_IS_LINUX_FALSE@go_net_sendfile_file = go/net/sendfile_dragonfly.go
 @LIBGO_IS_FREEBSD_TRUE@@LIBGO_IS_LINUX_FALSE@go_net_sendfile_file = go/net/sendfile_freebsd.go
 @LIBGO_IS_LINUX_TRUE@go_net_sendfile_file = go/net/sendfile_linux.go
@@ -1018,25 +1089,30 @@
 @LIBGO_IS_DRAGONFLY_TRUE@@LIBGO_IS_LINUX_FALSE@@LIBGO_IS_NETBSD_FALSE@go_net_interface_file = go/net/interface_dragonfly.go
 @LIBGO_IS_LINUX_FALSE@@LIBGO_IS_NETBSD_TRUE@go_net_interface_file = go/net/interface_netbsd.go
 @LIBGO_IS_LINUX_TRUE@go_net_interface_file = go/net/interface_linux.go
-@LIBGO_IS_LINUX_FALSE@go_net_cloexec_file = go/net/sys_cloexec.go
-@LIBGO_IS_LINUX_TRUE@go_net_cloexec_file = go/net/sock_cloexec.go
+@LIBGO_IS_FREEBSD_FALSE@@LIBGO_IS_LINUX_FALSE@go_net_cloexec_file = go/net/sys_cloexec.go
+@LIBGO_IS_FREEBSD_TRUE@@LIBGO_IS_LINUX_FALSE@go_net_cloexec_file = go/net/sock_cloexec.go go/net/hook_cloexec.go
+@LIBGO_IS_LINUX_TRUE@go_net_cloexec_file = go/net/sock_cloexec.go go/net/hook_cloexec.go
 @LIBGO_IS_DARWIN_FALSE@@LIBGO_IS_DRAGONFLY_FALSE@@LIBGO_IS_OPENBSD_FALSE@@LIBGO_IS_SOLARIS_FALSE@go_net_tcpsockopt_file = go/net/tcpsockopt_unix.go
 @LIBGO_IS_DARWIN_FALSE@@LIBGO_IS_DRAGONFLY_TRUE@@LIBGO_IS_OPENBSD_FALSE@@LIBGO_IS_SOLARIS_FALSE@go_net_tcpsockopt_file = go/net/tcpsockopt_dragonfly.go
 @LIBGO_IS_DARWIN_FALSE@@LIBGO_IS_OPENBSD_FALSE@@LIBGO_IS_SOLARIS_TRUE@go_net_tcpsockopt_file = go/net/tcpsockopt_solaris.go
 @LIBGO_IS_DARWIN_TRUE@@LIBGO_IS_OPENBSD_FALSE@go_net_tcpsockopt_file = go/net/tcpsockopt_darwin.go
 @LIBGO_IS_OPENBSD_TRUE@go_net_tcpsockopt_file = go/net/tcpsockopt_openbsd.go
-go_net_files = \
-	go/net/cgo_unix.go \
-	$(go_net_cgo_file) \
+go_net_common_files = \
+	go/net/addrselect.go \
 	$(go_net_cloexec_file) \
+	go/net/conf.go \
 	go/net/dial.go \
 	go/net/dnsclient.go \
 	go/net/dnsclient_unix.go \
 	go/net/dnsconfig_unix.go \
 	go/net/dnsmsg.go \
 	go/net/fd_mutex.go \
+	go/net/fd_posix.go \
 	go/net/fd_unix.go \
+	go/net/file.go \
 	go/net/file_unix.go \
+	go/net/hook.go \
+	go/net/hook_unix.go \
 	go/net/hosts.go \
 	go/net/interface.go \
 	$(go_net_interface_file) \
@@ -1049,6 +1125,7 @@
 	go/net/lookup_unix.go \
 	go/net/mac.go \
 	go/net/net.go \
+	go/net/nss.go \
 	go/net/parse.go \
 	go/net/pipe.go \
 	go/net/fd_poll_runtime.go \
@@ -1056,7 +1133,6 @@
 	go/net/port_unix.go \
 	go/net/race0.go \
 	$(go_net_sendfile_file) \
-	go/net/singleflight.go \
 	go/net/sock_posix.go \
 	$(go_net_sock_file) \
 	go/net/sockopt_posix.go \
@@ -1071,6 +1147,17 @@
 	go/net/unixsock.go \
 	go/net/unixsock_posix.go
 
+go_net_files = \
+	go/net/cgo_unix.go \
+	$(go_net_cgo_file) \
+	$(go_net_cgo_res_file) \
+	$(go_net_cgo_sock_file) \
+	$(go_net_common_files)
+
+go_netgo_files = \
+	go/net/cgo_stub.go \
+	$(go_net_common_files)
+
 @LIBGO_IS_386_FALSE@@LIBGO_IS_SOLARIS_TRUE@@LIBGO_IS_SPARC_FALSE@go_os_dir_file = go/os/dir_regfile.go
 @LIBGO_IS_386_FALSE@@LIBGO_IS_SOLARIS_TRUE@@LIBGO_IS_SPARC_TRUE@go_os_dir_file = go/os/dir_largefile.go
 @LIBGO_IS_386_TRUE@@LIBGO_IS_SOLARIS_TRUE@go_os_dir_file = go/os/dir_largefile.go
@@ -1086,6 +1173,8 @@
 @LIBGO_IS_DARWIN_FALSE@@LIBGO_IS_FREEBSD_FALSE@go_os_cloexec_file = go/os/sys_unix.go
 @LIBGO_IS_DARWIN_TRUE@@LIBGO_IS_FREEBSD_FALSE@go_os_cloexec_file = go/os/sys_darwin.go
 @LIBGO_IS_FREEBSD_TRUE@go_os_cloexec_file = go/os/sys_freebsd.go
+@HAVE_STAT_TIMESPEC_FALSE@@LIBGO_IS_SOLARIS_TRUE@go_os_stat_file = go/os/stat_solaris.go
+@HAVE_STAT_TIMESPEC_TRUE@@LIBGO_IS_SOLARIS_TRUE@go_os_stat_file = go/os/stat_atim.go
 @LIBGO_IS_DARWIN_FALSE@@LIBGO_IS_DRAGONFLY_FALSE@@LIBGO_IS_FREEBSD_FALSE@@LIBGO_IS_LINUX_FALSE@@LIBGO_IS_NETBSD_FALSE@@LIBGO_IS_OPENBSD_FALSE@@LIBGO_IS_SOLARIS_FALSE@go_os_stat_file = go/os/stat.go
 @LIBGO_IS_DARWIN_FALSE@@LIBGO_IS_DRAGONFLY_TRUE@@LIBGO_IS_FREEBSD_FALSE@@LIBGO_IS_LINUX_FALSE@@LIBGO_IS_NETBSD_FALSE@@LIBGO_IS_OPENBSD_FALSE@@LIBGO_IS_SOLARIS_FALSE@go_os_stat_file = go/os/stat_dragonfly.go
 @LIBGO_IS_DARWIN_FALSE@@LIBGO_IS_FREEBSD_FALSE@@LIBGO_IS_LINUX_FALSE@@LIBGO_IS_NETBSD_TRUE@@LIBGO_IS_OPENBSD_FALSE@@LIBGO_IS_SOLARIS_FALSE@go_os_stat_file = go/os/stat_atimespec.go
@@ -1093,9 +1182,15 @@
 @LIBGO_IS_DARWIN_TRUE@@LIBGO_IS_LINUX_FALSE@@LIBGO_IS_OPENBSD_FALSE@@LIBGO_IS_SOLARIS_FALSE@go_os_stat_file = go/os/stat_atimespec.go
 @LIBGO_IS_LINUX_FALSE@@LIBGO_IS_OPENBSD_TRUE@@LIBGO_IS_SOLARIS_FALSE@go_os_stat_file = go/os/stat_atim.go
 @LIBGO_IS_LINUX_TRUE@@LIBGO_IS_SOLARIS_FALSE@go_os_stat_file = go/os/stat_atim.go
-@LIBGO_IS_SOLARIS_TRUE@go_os_stat_file = go/os/stat_solaris.go
 @LIBGO_IS_LINUX_FALSE@go_os_pipe_file = go/os/pipe_bsd.go
 @LIBGO_IS_LINUX_TRUE@go_os_pipe_file = go/os/pipe_linux.go
+@LIBGO_IS_DARWIN_FALSE@@LIBGO_IS_DRAGONFLY_FALSE@@LIBGO_IS_FREEBSD_FALSE@@LIBGO_IS_NETBSD_FALSE@@LIBGO_IS_OPENBSD_FALSE@@LIBGO_IS_SOLARIS_FALSE@go_os_sticky_file = go/os/sticky_notbsd.go
+@LIBGO_IS_DARWIN_FALSE@@LIBGO_IS_DRAGONFLY_FALSE@@LIBGO_IS_FREEBSD_FALSE@@LIBGO_IS_NETBSD_FALSE@@LIBGO_IS_OPENBSD_FALSE@@LIBGO_IS_SOLARIS_TRUE@go_os_sticky_file = go/os/sticky_bsd.go
+@LIBGO_IS_DARWIN_FALSE@@LIBGO_IS_DRAGONFLY_FALSE@@LIBGO_IS_FREEBSD_FALSE@@LIBGO_IS_NETBSD_FALSE@@LIBGO_IS_OPENBSD_TRUE@go_os_sticky_file = go/os/sticky_bsd.go
+@LIBGO_IS_DARWIN_FALSE@@LIBGO_IS_DRAGONFLY_FALSE@@LIBGO_IS_FREEBSD_FALSE@@LIBGO_IS_NETBSD_TRUE@go_os_sticky_file = go/os/sticky_bsd.go
+@LIBGO_IS_DARWIN_FALSE@@LIBGO_IS_DRAGONFLY_FALSE@@LIBGO_IS_FREEBSD_TRUE@go_os_sticky_file = go/os/sticky_bsd.go
+@LIBGO_IS_DARWIN_FALSE@@LIBGO_IS_DRAGONFLY_TRUE@go_os_sticky_file = go/os/sticky_bsd.go
+@LIBGO_IS_DARWIN_TRUE@go_os_sticky_file = go/os/sticky_bsd.go
 go_os_files = \
 	$(go_os_dir_file) \
 	go/os/dir.go \
@@ -1116,6 +1211,7 @@
 	$(go_os_pipe_file) \
 	go/os/proc.go \
 	$(go_os_stat_file) \
+	$(go_os_sticky_file) \
 	go/os/str.go \
 	$(go_os_sys_file) \
 	$(go_os_cloexec_file) \
@@ -1137,6 +1233,7 @@
 	go/reflect/makefunc_ffi_c.c
 
 go_regexp_files = \
+	go/regexp/backtrack.go \
 	go/regexp/exec.go \
 	go/regexp/onepass.go \
 	go/regexp/regexp.go
@@ -1152,7 +1249,6 @@
 	go/runtime/error.go \
 	go/runtime/extern.go \
 	go/runtime/mem.go \
-	go/runtime/softfloat64.go \
 	version.go
 
 noinst_DATA = zstdpkglist.go
@@ -1165,6 +1261,7 @@
 	go/strconv/atof.go \
 	go/strconv/atoi.go \
 	go/strconv/decimal.go \
+	go/strconv/doc.go \
 	go/strconv/extfloat.go \
 	go/strconv/ftoa.go \
 	go/strconv/isprint.go \
@@ -1172,6 +1269,7 @@
 	go/strconv/quote.go
 
 go_strings_files = \
+	go/strings/compare.go \
 	go/strings/reader.go \
 	go/strings/replace.go \
 	go/strings/search.go \
@@ -1195,6 +1293,7 @@
 @LIBGO_IS_IRIX_TRUE@@LIBGO_IS_SOLARIS_FALSE@go_syslog_file = go/log/syslog/syslog_libc.go
 @LIBGO_IS_SOLARIS_TRUE@go_syslog_file = go/log/syslog/syslog_libc.go
 go_log_syslog_files = \
+	go/log/syslog/doc.go \
 	go/log/syslog/syslog.go \
 	$(go_syslog_file)
 
@@ -1324,6 +1423,7 @@
 @LIBGO_IS_LINUX_FALSE@crypto_rand_file = 
 @LIBGO_IS_LINUX_TRUE@crypto_rand_file = go/crypto/rand/rand_linux.go
 go_crypto_rand_files = \
+	go/crypto/rand/eagain.go \
 	go/crypto/rand/rand.go \
 	go/crypto/rand/rand_unix.go \
 	$(crypto_rand_file) \
@@ -1367,6 +1467,14 @@
 	go/crypto/tls/ticket.go \
 	go/crypto/tls/tls.go
 
+@LIBGO_IS_DARWIN_FALSE@@LIBGO_IS_DRAGONFLY_FALSE@@LIBGO_IS_FREEBSD_FALSE@@LIBGO_IS_LINUX_FALSE@@LIBGO_IS_NETBSD_FALSE@@LIBGO_IS_OPENBSD_FALSE@@LIBGO_IS_SOLARIS_FALSE@go_crypto_x509_root_file = 
+@LIBGO_IS_DARWIN_TRUE@@LIBGO_IS_DRAGONFLY_FALSE@@LIBGO_IS_FREEBSD_FALSE@@LIBGO_IS_LINUX_FALSE@@LIBGO_IS_NETBSD_FALSE@@LIBGO_IS_OPENBSD_FALSE@@LIBGO_IS_SOLARIS_FALSE@go_crypto_x509_root_file = go/crypto/x509/root_darwin.go
+@LIBGO_IS_DRAGONFLY_FALSE@@LIBGO_IS_FREEBSD_FALSE@@LIBGO_IS_LINUX_FALSE@@LIBGO_IS_NETBSD_FALSE@@LIBGO_IS_OPENBSD_TRUE@@LIBGO_IS_SOLARIS_FALSE@go_crypto_x509_root_file = go/crypto/x509/root_bsd.go
+@LIBGO_IS_DRAGONFLY_FALSE@@LIBGO_IS_FREEBSD_FALSE@@LIBGO_IS_LINUX_FALSE@@LIBGO_IS_NETBSD_TRUE@@LIBGO_IS_SOLARIS_FALSE@go_crypto_x509_root_file = go/crypto/x509/root_bsd.go
+@LIBGO_IS_DRAGONFLY_FALSE@@LIBGO_IS_FREEBSD_TRUE@@LIBGO_IS_LINUX_FALSE@@LIBGO_IS_SOLARIS_FALSE@go_crypto_x509_root_file = go/crypto/x509/root_bsd.go
+@LIBGO_IS_DRAGONFLY_TRUE@@LIBGO_IS_LINUX_FALSE@@LIBGO_IS_SOLARIS_FALSE@go_crypto_x509_root_file = go/crypto/x509/root_bsd.go
+@LIBGO_IS_LINUX_FALSE@@LIBGO_IS_SOLARIS_TRUE@go_crypto_x509_root_file = go/crypto/x509/root_solaris.go
+@LIBGO_IS_LINUX_TRUE@go_crypto_x509_root_file = go/crypto/x509/root_linux.go
 go_crypto_x509_files = \
 	go/crypto/x509/cert_pool.go \
 	go/crypto/x509/pem_decrypt.go \
@@ -1374,6 +1482,7 @@
 	go/crypto/x509/pkcs8.go \
 	go/crypto/x509/root.go \
 	go/crypto/x509/root_unix.go \
+	$(go_crypto_x509_root_file) \
 	go/crypto/x509/sec1.go \
 	go/crypto/x509/verify.go \
 	go/crypto/x509/x509.go
@@ -1391,6 +1500,7 @@
 
 go_debug_dwarf_files = \
 	go/debug/dwarf/buf.go \
+	go/debug/dwarf/class_string.go \
 	go/debug/dwarf/const.go \
 	go/debug/dwarf/entry.go \
 	go/debug/dwarf/line.go \
@@ -1500,6 +1610,10 @@
 	go/go/build/read.go \
 	go/go/build/syslist.go
 
+go_go_constant_files = \
+	go/go/constant/go14.go \
+	go/go/constant/value.go
+
 go_go_doc_files = \
 	go/go/doc/comment.go \
 	go/go/doc/doc.go \
@@ -1512,6 +1626,9 @@
 go_go_format_files = \
 	go/go/format/format.go
 
+go_go_importer_files = \
+	go/go/importer/importer.go
+
 go_go_parser_files = \
 	go/go/parser/interface.go \
 	go/go/parser/parser.go
@@ -1529,6 +1646,49 @@
 	go/go/token/serialize.go \
 	go/go/token/token.go
 
+go_go_types_files = \
+	go/go/types/api.go \
+	go/go/types/assignments.go \
+	go/go/types/builtins.go \
+	go/go/types/call.go \
+	go/go/types/check.go \
+	go/go/types/conversions.go \
+	go/go/types/decl.go \
+	go/go/types/errors.go \
+	go/go/types/eval.go \
+	go/go/types/expr.go \
+	go/go/types/exprstring.go \
+	go/go/types/go12.go \
+	go/go/types/initorder.go \
+	go/go/types/labels.go \
+	go/go/types/lookup.go \
+	go/go/types/methodset.go \
+	go/go/types/object.go \
+	go/go/types/objset.go \
+	go/go/types/operand.go \
+	go/go/types/ordering.go \
+	go/go/types/package.go \
+	go/go/types/predicates.go \
+	go/go/types/resolver.go \
+	go/go/types/return.go \
+	go/go/types/scope.go \
+	go/go/types/selection.go \
+	go/go/types/stmt.go \
+	go/go/types/sizes.go \
+	go/go/types/type.go \
+	go/go/types/typestring.go \
+	go/go/types/typexpr.go \
+	go/go/types/universe.go
+
+go_go_internal_gcimporter_files = \
+	go/go/internal/gcimporter/exportdata.go \
+	go/go/internal/gcimporter/gcimporter.go
+
+go_go_internal_gccgoimporter_files = \
+	go/go/internal/gccgoimporter/gccgoinstallation.go \
+	go/go/internal/gccgoimporter/importer.go \
+	go/go/internal/gccgoimporter/parser.go
+
 go_hash_adler32_files = \
 	go/hash/adler32/adler32.go
 
@@ -1570,6 +1730,10 @@
 	go/image/gif/reader.go \
 	go/image/gif/writer.go
 
+go_image_internal_imageutil_files = \
+	go/image/internal/imageutil/imageutil.go \
+	go/image/internal/imageutil/impl.go
+
 go_image_jpeg_files = \
 	go/image/jpeg/fdct.go \
 	go/image/jpeg/huffman.go \
@@ -1587,15 +1751,44 @@
 	go/index/suffixarray/qsufsort.go \
 	go/index/suffixarray/suffixarray.go
 
+go_internal_format_files = \
+	go/internal/format/format.go
+
+go_internal_singleflight_files = \
+	go/internal/singleflight/singleflight.go
+
+@LIBGO_IS_LINUX_FALSE@internal_syscall_unix_getrandom_file = 
+@LIBGO_IS_LINUX_TRUE@internal_syscall_unix_getrandom_file = go/internal/syscall/unix/getrandom_linux.go
+go_internal_syscall_unix_files = \
+	go/internal/syscall/unix/dummy.go \
+	$(internal_syscall_unix_getrandom_file)
+
+go_internal_testenv_files = \
+	go/internal/testenv/testenv.go
+
+go_internal_trace_files = \
+	go/internal/trace/goroutines.go \
+	go/internal/trace/parser.go
+
 go_io_ioutil_files = \
 	go/io/ioutil/ioutil.go \
 	go/io/ioutil/tempfile.go
 
 go_math_big_files = \
+	go/math/big/accuracy_string.go \
 	go/math/big/arith.go \
+	go/math/big/arith_decl_pure.go \
+	go/math/big/decimal.go \
+	go/math/big/float.go \
+	go/math/big/floatconv.go \
+	go/math/big/ftoa.go \
 	go/math/big/int.go \
+	go/math/big/intconv.go \
 	go/math/big/nat.go \
-	go/math/big/rat.go
+	go/math/big/natconv.go \
+	go/math/big/rat.go \
+	go/math/big/ratconv.go \
+	go/math/big/roundingmode_string.go
 
 go_math_cmplx_files = \
 	go/math/cmplx/abs.go \
@@ -1623,9 +1816,12 @@
 go_mime_multipart_files = \
 	go/mime/multipart/formdata.go \
 	go/mime/multipart/multipart.go \
-	go/mime/multipart/quotedprintable.go \
 	go/mime/multipart/writer.go
 
+go_mime_quotedprintable_files = \
+	go/mime/quotedprintable/reader.go \
+	go/mime/quotedprintable/writer.go
+
 go_net_http_files = \
 	go/net/http/client.go \
 	go/net/http/cookie.go \
@@ -1687,6 +1883,16 @@
 go_net_http_internal_files = \
 	go/net/http/internal/chunked.go
 
+@LIBGO_IS_FREEBSD_FALSE@@LIBGO_IS_LINUX_FALSE@go_net_internal_socktest_sys = 
+@LIBGO_IS_FREEBSD_TRUE@@LIBGO_IS_LINUX_FALSE@go_net_internal_socktest_sys = go/net/internal/socktest/sys_cloexec.go
+@LIBGO_IS_LINUX_TRUE@go_net_internal_socktest_sys = go/net/internal/socktest/sys_cloexec.go
+go_net_internal_socktest_files = \
+	go/net/internal/socktest/switch.go \
+	go/net/internal/socktest/switch_posix.go \
+	go/net/internal/socktest/switch_unix.go \
+	go/net/internal/socktest/sys_unix.go \
+	$(go_net_internal_socktest_sys)
+
 go_old_regexp_files = \
 	go/old/regexp/regexp.go
 
@@ -1698,6 +1904,7 @@
 
 go_os_exec_files = \
 	go/os/exec/exec.go \
+	go/os/exec/exec_posix.go \
 	go/os/exec/lp_unix.go
 
 go_os_signal_files = \
@@ -1747,6 +1954,7 @@
 	go/text/template/exec.go \
 	go/text/template/funcs.go \
 	go/text/template/helper.go \
+	go/text/template/option.go \
 	go/text/template/template.go
 
 go_text_template_parse_files = \
@@ -1827,6 +2035,10 @@
 
 # Define socket sizes and types.
 @LIBGO_IS_LINUX_TRUE@syscall_socket_file = go/syscall/socket_linux.go epoll.go
+@LIBGO_IS_LINUX_FALSE@syscall_socket_type_file = 
+@LIBGO_IS_LINUX_TRUE@@LIBGO_IS_PPC64LE_FALSE@@LIBGO_IS_PPC64_FALSE@syscall_socket_type_file = go/syscall/socket_linux_type.go
+@LIBGO_IS_LINUX_TRUE@@LIBGO_IS_PPC64LE_FALSE@@LIBGO_IS_PPC64_TRUE@syscall_socket_type_file = go/syscall/socket_linux_ppc64x_type.go
+@LIBGO_IS_LINUX_TRUE@@LIBGO_IS_PPC64LE_TRUE@syscall_socket_type_file = go/syscall/socket_linux_ppc64x_type.go
 @LIBGO_IS_SOLARIS_FALSE@syscall_socket_os_file = go/syscall/socket_posix.go
 
 # Define socket functions.
@@ -1849,6 +2061,11 @@
 
 # GNU/Linux specific socket filters.
 @LIBGO_IS_LINUX_TRUE@syscall_lsf_file = go/syscall/lsf_linux.go
+@LIBGO_IS_ARM64_FALSE@@LIBGO_IS_LINUX_TRUE@syscall_ustat_file = go/syscall/libcall_linux_ustat.go
+
+# GNU/Linux specific ustat support.
+@LIBGO_IS_ARM64_TRUE@@LIBGO_IS_LINUX_TRUE@syscall_ustat_file = 
+@LIBGO_IS_LINUX_FALSE@syscall_ustat_file = 
 @LIBGO_IS_LINUX_FALSE@syscall_utimesnano_file = go/syscall/libcall_posix_utimesnano.go
 
 # GNU/Linux specific utimesnano support.
@@ -1857,6 +2074,10 @@
 
 # Test files.
 @LIBGO_IS_LINUX_TRUE@syscall_creds_test_file = go/syscall/creds_test.go
+@LIBGO_IS_LINUX_FALSE@syscall_exec_test_file = 
+@LIBGO_IS_LINUX_TRUE@syscall_exec_test_file = go/syscall/exec_linux_test.go go/syscall/syscall_linux_test.go
+@LIBGO_IS_LINUX_FALSE@syscall_os_file = go/syscall/libcall_bsd.go
+@LIBGO_IS_LINUX_TRUE@syscall_os_file = 
 go_base_syscall_files = \
 	go/syscall/env_unix.go \
 	go/syscall/syscall_errno.go \
@@ -1875,11 +2096,14 @@
 	$(syscall_sleep_file) \
 	$(syscall_errstr_file) \
 	$(syscall_size_file) \
+	$(syscall_os_file) \
 	$(syscall_socket_file) \
 	$(syscall_socket_os_file) \
+	$(syscall_socket_type_file) \
 	$(syscall_uname_file) \
 	$(syscall_netlink_file) \
 	$(syscall_lsf_file) \
+	$(syscall_ustat_file) \
 	$(syscall_utimesnano_file) \
 	$(GO_LIBCALL_OS_FILE) \
 	$(GO_LIBCALL_OS_ARCH_FILE) \
@@ -1899,17 +2123,14 @@
 
 go_syscall_test_files = \
 	$(syscall_creds_test_file) \
+	$(syscall_exec_test_file) \
+	go/syscall/exec_unix_test.go \
 	go/syscall/export_test.go \
+	go/syscall/export_unix_test.go \
 	go/syscall/mmap_unix_test.go \
 	go/syscall/syscall_test.go \
 	go/syscall/syscall_unix_test.go
 
-@LIBGO_IS_LINUX_FALSE@internal_syscall_getrandom_file = 
-@LIBGO_IS_LINUX_TRUE@internal_syscall_getrandom_file = go/internal/syscall/getrandom_linux.go
-go_internal_syscall_files = \
-	go/internal/syscall/dummy.go \
-	$(internal_syscall_getrandom_file)
-
 @LIBGO_IS_LINUX_FALSE@os_lib_inotify_lo = 
 
 # os_lib_inotify_lo = os/inotify.lo
@@ -2002,12 +2223,17 @@
 	html/template.lo \
 	go/ast.lo \
 	go/build.lo \
+	go/constant.lo \
 	go/doc.lo \
 	go/format.lo \
+	go/importer.lo \
+	go/internal/gcimporter.lo \
+	go/internal/gccgoimporter.lo \
 	go/parser.lo \
 	go/printer.lo \
 	go/scanner.lo \
 	go/token.lo \
+	go/types.lo \
 	hash/adler32.lo \
 	hash/crc32.lo \
 	hash/crc64.lo \
@@ -2023,10 +2249,15 @@
 	image/color/palette.lo \
 	image/draw.lo \
 	image/gif.lo \
+	image/internal/imageutil.lo \
 	image/jpeg.lo \
 	image/png.lo \
 	index/suffixarray.lo \
-	internal/syscall.lo \
+	internal/format.lo \
+	internal/singleflight.lo \
+	internal/syscall/unix.lo \
+	internal/testenv.lo \
+	internal/trace.lo \
 	io/ioutil.lo \
 	log/syslog.lo \
 	log/syslog/syslog_c.lo \
@@ -2034,7 +2265,9 @@
 	math/cmplx.lo \
 	math/rand.lo \
 	mime/multipart.lo \
+	mime/quotedprintable.lo \
 	net/http.lo \
+	net/internal/socktest.lo \
 	net/mail.lo \
 	net/rpc.lo \
 	net/smtp.lo \
@@ -2081,8 +2314,18 @@
 libgobegin_llgo_a_SOURCES = \
 	runtime/go-main.c
 
+
+# Use -fPIC for libgobegin so that it can be put in a PIE.
+libgobegin_a_CFLAGS = $(AM_CFLAGS) -fPIC
+libgobegin_llgo_a_CFLAGS = $(AM_CFLAGS) -fPIC
+libgolibbegin_a_SOURCES = \
+	runtime/go-libmain.c
+
+libgolibbegin_a_CFLAGS = $(AM_CFLAGS) -fPIC
+libnetgo_a_SOURCES = $(go_netgo_files)
+libnetgo_a_LIBADD = netgo.o
 LTLDFLAGS = $(shell $(SHELL) $(top_srcdir)/../libtool-ldflags $(LDFLAGS))
-AM_GOCFLAGS = $(STRINGOPS_FLAG)
+AM_GOCFLAGS = $(STRINGOPS_FLAG) $(GO_SPLIT_STACK)
 GOCOMPILE = $(GOC) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_GOCFLAGS) $(GOCFLAGS)
 LTGOCOMPILE = $(LIBTOOL) --tag GO --mode=compile $(GOC) $(INCLUDES) \
 	$(AM_GOCFLAGS) $(GOCFLAGS)
@@ -2104,6 +2347,13 @@
 	files=`echo $^ | sed -e 's/[^ ]*\.gox//g'`; \
 	$(LTGOCOMPILE) -I . -c -fgo-pkgpath=`echo $@ | sed -e 's/.lo$$//' -e 's/-go$$//'` -o $@ $$files
 
+
+# Build netgo.o.
+BUILDNETGO = \
+	$(MKDIR_P) $(@D); \
+	files=`echo $^ | sed -e 's/[^ ]*\.gox//g'`; \
+	$(GOCOMPILE) -I . -c -fPIC -fgo-pkgpath=net -o $@ $$files
+
 GOTESTFLAGS = 
 GOBENCH = 
 
@@ -2124,11 +2374,11 @@
 	$(MKDIR_P) $(@D); \
 	rm -f $@-testsum $@-testlog; \
 	if test "$(USE_DEJAGNU)" = "yes"; then \
-	  $(SHELL) $(srcdir)/testsuite/gotest --dejagnu=yes --basedir=$(srcdir) --srcdir=$(srcdir)/go/$(@D) --pkgpath="$(@D)" --pkgfiles="$(go_$(subst /,_,$(@D))_files)" --testname="$(@D)" --goarch="$(GOARCH)" $(GOTESTFLAGS) $(go_$(subst /,_,$(@D))_test_files); \
+	  $(SHELL) $(srcdir)/testsuite/gotest --goarch=$(GOARCH) --goos=$(GOOS) --dejagnu=yes --basedir=$(srcdir) --srcdir=$(srcdir)/go/$(@D) --pkgpath="$(@D)" --pkgfiles="$(go_$(subst /,_,$(@D))_files)" --testname="$(@D)" $(GOTESTFLAGS) $(go_$(subst /,_,$(@D))_test_files); \
 	elif test "$(GOBENCH)" != ""; then \
-	  $(SHELL) $(srcdir)/testsuite/gotest --basedir=$(srcdir) --srcdir=$(srcdir)/go/$(@D) --pkgpath="$(@D)" --pkgfiles="$(go_$(subst /,_,$(@D))_files)" --goarch="$(GOARCH)" --bench="$(GOBENCH)" $(GOTESTFLAGS) $(go_$(subst /,_,$(@D))_test_files); \
+	  $(SHELL) $(srcdir)/testsuite/gotest --goarch=$(GOARCH) --goos=$(GOOS) --basedir=$(srcdir) --srcdir=$(srcdir)/go/$(@D) --pkgpath="$(@D)" --pkgfiles="$(go_$(subst /,_,$(@D))_files)" --bench="$(GOBENCH)" $(GOTESTFLAGS) $(go_$(subst /,_,$(@D))_test_files); \
 	else \
-	  if $(SHELL) $(srcdir)/testsuite/gotest --basedir=$(srcdir) --srcdir=$(srcdir)/go/$(@D) --pkgpath="$(@D)" --pkgfiles="$(go_$(subst /,_,$(@D))_files)" --goarch="$(GOARCH)" $(GOTESTFLAGS) $(go_$(subst /,_,$(@D))_test_files) >>$@-testlog 2>&1; then \
+	  if $(SHELL) $(srcdir)/testsuite/gotest --goarch=$(GOARCH) --goos=$(GOOS) --basedir=$(srcdir) --srcdir=$(srcdir)/go/$(@D) --pkgpath="$(@D)" --pkgfiles="$(go_$(subst /,_,$(@D))_files)" $(GOTESTFLAGS) $(go_$(subst /,_,$(@D))_test_files) >>$@-testlog 2>&1; then \
 	    echo "PASS: $(@D)" >> $@-testlog; \
 	    echo "PASS: $(@D)"; \
 	    echo "PASS: $(@D)" > $@-testsum; \
@@ -2240,13 +2490,17 @@
 	exp/terminal/check \
 	html/template/check \
 	go/ast/check \
-	$(go_build_check_omitted_since_it_calls_6g) \
+	go/build/check \
+	go/constant/check \
 	go/doc/check \
 	go/format/check \
+	go/internal/gcimporter/check \
+	go/internal/gccgoimporter/check \
 	go/parser/check \
 	go/printer/check \
 	go/scanner/check \
 	go/token/check \
+	go/types/check \
 	hash/adler32/check \
 	hash/crc32/check \
 	hash/crc64/check \
@@ -2256,12 +2510,15 @@
 	image/jpeg/check \
 	image/png/check \
 	index/suffixarray/check \
+	internal/singleflight/check \
+	internal/trace/check \
 	io/ioutil/check \
 	log/syslog/check \
 	math/big/check \
 	math/cmplx/check \
 	math/rand/check \
 	mime/multipart/check \
+	mime/quotedprintable/check \
 	net/http/check \
 	net/http/cgi/check \
 	net/http/cookiejar/check \
@@ -2269,6 +2526,7 @@
 	net/http/httptest/check \
 	net/http/httputil/check \
 	net/http/internal/check \
+	net/internal/socktest/check \
 	net/mail/check \
 	net/rpc/check \
 	net/smtp/check \
@@ -2298,7 +2556,7 @@
 
 .SUFFIXES:
 .SUFFIXES: .c .go .gox .o .obj .lo .a
-am--refresh:
+am--refresh: Makefile
 	@:
 $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am  $(am__configure_deps)
 	@for dep in $?; do \
@@ -2334,10 +2592,8 @@
 $(am__aclocal_m4_deps):
 
 config.h: stamp-h1
-	@if test ! -f $@; then \
-	  rm -f stamp-h1; \
-	  $(MAKE) $(AM_MAKEFLAGS) stamp-h1; \
-	else :; fi
+	@if test ! -f $@; then rm -f stamp-h1; else :; fi
+	@if test ! -f $@; then $(MAKE) $(AM_MAKEFLAGS) stamp-h1; else :; fi
 
 stamp-h1: $(srcdir)/config.h.in $(top_builddir)/config.status
 	@rm -f stamp-h1
@@ -2351,7 +2607,6 @@
 	-rm -f config.h stamp-h1
 install-toolexeclibLIBRARIES: $(toolexeclib_LIBRARIES)
 	@$(NORMAL_INSTALL)
-	test -z "$(toolexeclibdir)" || $(MKDIR_P) "$(DESTDIR)$(toolexeclibdir)"
 	@list='$(toolexeclib_LIBRARIES)'; test -n "$(toolexeclibdir)" || list=; \
 	list2=; for p in $$list; do \
 	  if test -f $$p; then \
@@ -2359,6 +2614,8 @@
 	  else :; fi; \
 	done; \
 	test -z "$$list2" || { \
+	  echo " $(MKDIR_P) '$(DESTDIR)$(toolexeclibdir)'"; \
+	  $(MKDIR_P) "$(DESTDIR)$(toolexeclibdir)" || exit 1; \
 	  echo " $(INSTALL_DATA) $$list2 '$(DESTDIR)$(toolexeclibdir)'"; \
 	  $(INSTALL_DATA) $$list2 "$(DESTDIR)$(toolexeclibdir)" || exit $$?; }
 	@$(POST_INSTALL)
@@ -2375,23 +2632,28 @@
 	@$(NORMAL_UNINSTALL)
 	@list='$(toolexeclib_LIBRARIES)'; test -n "$(toolexeclibdir)" || list=; \
 	files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
-	test -n "$$files" || exit 0; \
-	echo " ( cd '$(DESTDIR)$(toolexeclibdir)' && rm -f "$$files" )"; \
-	cd "$(DESTDIR)$(toolexeclibdir)" && rm -f $$files
+	dir='$(DESTDIR)$(toolexeclibdir)'; $(am__uninstall_files_from_dir)
 
 clean-toolexeclibLIBRARIES:
 	-test -z "$(toolexeclib_LIBRARIES)" || rm -f $(toolexeclib_LIBRARIES)
-libgobegin-llgo.a: $(libgobegin_llgo_a_OBJECTS) $(libgobegin_llgo_a_DEPENDENCIES) 
+libgobegin-llgo.a: $(libgobegin_llgo_a_OBJECTS) $(libgobegin_llgo_a_DEPENDENCIES) $(EXTRA_libgobegin_llgo_a_DEPENDENCIES) 
 	-rm -f libgobegin-llgo.a
 	$(libgobegin_llgo_a_AR) libgobegin-llgo.a $(libgobegin_llgo_a_OBJECTS) $(libgobegin_llgo_a_LIBADD)
 	$(RANLIB) libgobegin-llgo.a
-libgobegin.a: $(libgobegin_a_OBJECTS) $(libgobegin_a_DEPENDENCIES) 
+libgobegin.a: $(libgobegin_a_OBJECTS) $(libgobegin_a_DEPENDENCIES) $(EXTRA_libgobegin_a_DEPENDENCIES) 
 	-rm -f libgobegin.a
 	$(libgobegin_a_AR) libgobegin.a $(libgobegin_a_OBJECTS) $(libgobegin_a_LIBADD)
 	$(RANLIB) libgobegin.a
+libgolibbegin.a: $(libgolibbegin_a_OBJECTS) $(libgolibbegin_a_DEPENDENCIES) $(EXTRA_libgolibbegin_a_DEPENDENCIES) 
+	-rm -f libgolibbegin.a
+	$(libgolibbegin_a_AR) libgolibbegin.a $(libgolibbegin_a_OBJECTS) $(libgolibbegin_a_LIBADD)
+	$(RANLIB) libgolibbegin.a
+libnetgo.a: $(libnetgo_a_OBJECTS) $(libnetgo_a_DEPENDENCIES) $(EXTRA_libnetgo_a_DEPENDENCIES) 
+	-rm -f libnetgo.a
+	$(libnetgo_a_AR) libnetgo.a $(libnetgo_a_OBJECTS) $(libnetgo_a_LIBADD)
+	$(RANLIB) libnetgo.a
 install-toolexeclibLTLIBRARIES: $(toolexeclib_LTLIBRARIES)
 	@$(NORMAL_INSTALL)
-	test -z "$(toolexeclibdir)" || $(MKDIR_P) "$(DESTDIR)$(toolexeclibdir)"
 	@list='$(toolexeclib_LTLIBRARIES)'; test -n "$(toolexeclibdir)" || list=; \
 	list2=; for p in $$list; do \
 	  if test -f $$p; then \
@@ -2399,6 +2661,8 @@
 	  else :; fi; \
 	done; \
 	test -z "$$list2" || { \
+	  echo " $(MKDIR_P) '$(DESTDIR)$(toolexeclibdir)'"; \
+	  $(MKDIR_P) "$(DESTDIR)$(toolexeclibdir)" || exit 1; \
 	  echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(toolexeclibdir)'"; \
 	  $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(toolexeclibdir)"; \
 	}
@@ -2420,9 +2684,9 @@
 	  echo "rm -f \"$${dir}/so_locations\""; \
 	  rm -f "$${dir}/so_locations"; \
 	done
-libgo-llgo.la: $(libgo_llgo_la_OBJECTS) $(libgo_llgo_la_DEPENDENCIES) 
+libgo-llgo.la: $(libgo_llgo_la_OBJECTS) $(libgo_llgo_la_DEPENDENCIES) $(EXTRA_libgo_llgo_la_DEPENDENCIES) 
 	$(libgo_llgo_la_LINK) $(am_libgo_llgo_la_rpath) $(libgo_llgo_la_OBJECTS) $(libgo_llgo_la_LIBADD) $(LIBS)
-libgo.la: $(libgo_la_OBJECTS) $(libgo_la_DEPENDENCIES) 
+libgo.la: $(libgo_la_OBJECTS) $(libgo_la_DEPENDENCIES) $(EXTRA_libgo_la_DEPENDENCIES) 
 	$(libgo_la_LINK) $(am_libgo_la_rpath) $(libgo_la_OBJECTS) $(libgo_la_LIBADD) $(LIBS)
 
 mostlyclean-compile:
@@ -2465,7 +2729,6 @@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/go-interface-compare.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/go-interface-eface-compare.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/go-interface-val-compare.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/go-main.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/go-make-slice.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/go-map-delete.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/go-map-index.Plo@am__quote@
@@ -2509,6 +2772,9 @@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/go-varargs.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/heapdump.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lfstack.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgobegin_a-go-main.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgobegin_llgo_a-go-main.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgolibbegin_a-go-libmain.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lock_futex.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lock_sema.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/malloc.Plo@am__quote@
@@ -2566,19 +2832,47 @@
 @AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
 @am__fastdepCC_FALSE@	$(LTCOMPILE) -c -o $@ $<
 
-go-main.o: runtime/go-main.c
-@am__fastdepCC_TRUE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT go-main.o -MD -MP -MF $(DEPDIR)/go-main.Tpo -c -o go-main.o `test -f 'runtime/go-main.c' || echo '$(srcdir)/'`runtime/go-main.c
-@am__fastdepCC_TRUE@	$(am__mv) $(DEPDIR)/go-main.Tpo $(DEPDIR)/go-main.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='runtime/go-main.c' object='go-main.o' libtool=no @AMDEPBACKSLASH@
+libgobegin_llgo_a-go-main.o: runtime/go-main.c
+@am__fastdepCC_TRUE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgobegin_llgo_a_CFLAGS) $(CFLAGS) -MT libgobegin_llgo_a-go-main.o -MD -MP -MF $(DEPDIR)/libgobegin_llgo_a-go-main.Tpo -c -o libgobegin_llgo_a-go-main.o `test -f 'runtime/go-main.c' || echo '$(srcdir)/'`runtime/go-main.c
+@am__fastdepCC_TRUE@	$(am__mv) $(DEPDIR)/libgobegin_llgo_a-go-main.Tpo $(DEPDIR)/libgobegin_llgo_a-go-main.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='runtime/go-main.c' object='libgobegin_llgo_a-go-main.o' libtool=no @AMDEPBACKSLASH@
 @AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o go-main.o `test -f 'runtime/go-main.c' || echo '$(srcdir)/'`runtime/go-main.c
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgobegin_llgo_a_CFLAGS) $(CFLAGS) -c -o libgobegin_llgo_a-go-main.o `test -f 'runtime/go-main.c' || echo '$(srcdir)/'`runtime/go-main.c
 
-go-main.obj: runtime/go-main.c
-@am__fastdepCC_TRUE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT go-main.obj -MD -MP -MF $(DEPDIR)/go-main.Tpo -c -o go-main.obj `if test -f 'runtime/go-main.c'; then $(CYGPATH_W) 'runtime/go-main.c'; else $(CYGPATH_W) '$(srcdir)/runtime/go-main.c'; fi`
-@am__fastdepCC_TRUE@	$(am__mv) $(DEPDIR)/go-main.Tpo $(DEPDIR)/go-main.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='runtime/go-main.c' object='go-main.obj' libtool=no @AMDEPBACKSLASH@
+libgobegin_llgo_a-go-main.obj: runtime/go-main.c
+@am__fastdepCC_TRUE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgobegin_llgo_a_CFLAGS) $(CFLAGS) -MT libgobegin_llgo_a-go-main.obj -MD -MP -MF $(DEPDIR)/libgobegin_llgo_a-go-main.Tpo -c -o libgobegin_llgo_a-go-main.obj `if test -f 'runtime/go-main.c'; then $(CYGPATH_W) 'runtime/go-main.c'; else $(CYGPATH_W) '$(srcdir)/runtime/go-main.c'; fi`
+@am__fastdepCC_TRUE@	$(am__mv) $(DEPDIR)/libgobegin_llgo_a-go-main.Tpo $(DEPDIR)/libgobegin_llgo_a-go-main.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='runtime/go-main.c' object='libgobegin_llgo_a-go-main.obj' libtool=no @AMDEPBACKSLASH@
 @AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o go-main.obj `if test -f 'runtime/go-main.c'; then $(CYGPATH_W) 'runtime/go-main.c'; else $(CYGPATH_W) '$(srcdir)/runtime/go-main.c'; fi`
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgobegin_llgo_a_CFLAGS) $(CFLAGS) -c -o libgobegin_llgo_a-go-main.obj `if test -f 'runtime/go-main.c'; then $(CYGPATH_W) 'runtime/go-main.c'; else $(CYGPATH_W) '$(srcdir)/runtime/go-main.c'; fi`
+
+libgobegin_a-go-main.o: runtime/go-main.c
+@am__fastdepCC_TRUE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgobegin_a_CFLAGS) $(CFLAGS) -MT libgobegin_a-go-main.o -MD -MP -MF $(DEPDIR)/libgobegin_a-go-main.Tpo -c -o libgobegin_a-go-main.o `test -f 'runtime/go-main.c' || echo '$(srcdir)/'`runtime/go-main.c
+@am__fastdepCC_TRUE@	$(am__mv) $(DEPDIR)/libgobegin_a-go-main.Tpo $(DEPDIR)/libgobegin_a-go-main.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='runtime/go-main.c' object='libgobegin_a-go-main.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgobegin_a_CFLAGS) $(CFLAGS) -c -o libgobegin_a-go-main.o `test -f 'runtime/go-main.c' || echo '$(srcdir)/'`runtime/go-main.c
+
+libgobegin_a-go-main.obj: runtime/go-main.c
+@am__fastdepCC_TRUE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgobegin_a_CFLAGS) $(CFLAGS) -MT libgobegin_a-go-main.obj -MD -MP -MF $(DEPDIR)/libgobegin_a-go-main.Tpo -c -o libgobegin_a-go-main.obj `if test -f 'runtime/go-main.c'; then $(CYGPATH_W) 'runtime/go-main.c'; else $(CYGPATH_W) '$(srcdir)/runtime/go-main.c'; fi`
+@am__fastdepCC_TRUE@	$(am__mv) $(DEPDIR)/libgobegin_a-go-main.Tpo $(DEPDIR)/libgobegin_a-go-main.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='runtime/go-main.c' object='libgobegin_a-go-main.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgobegin_a_CFLAGS) $(CFLAGS) -c -o libgobegin_a-go-main.obj `if test -f 'runtime/go-main.c'; then $(CYGPATH_W) 'runtime/go-main.c'; else $(CYGPATH_W) '$(srcdir)/runtime/go-main.c'; fi`
+
+libgolibbegin_a-go-libmain.o: runtime/go-libmain.c
+@am__fastdepCC_TRUE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgolibbegin_a_CFLAGS) $(CFLAGS) -MT libgolibbegin_a-go-libmain.o -MD -MP -MF $(DEPDIR)/libgolibbegin_a-go-libmain.Tpo -c -o libgolibbegin_a-go-libmain.o `test -f 'runtime/go-libmain.c' || echo '$(srcdir)/'`runtime/go-libmain.c
+@am__fastdepCC_TRUE@	$(am__mv) $(DEPDIR)/libgolibbegin_a-go-libmain.Tpo $(DEPDIR)/libgolibbegin_a-go-libmain.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='runtime/go-libmain.c' object='libgolibbegin_a-go-libmain.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgolibbegin_a_CFLAGS) $(CFLAGS) -c -o libgolibbegin_a-go-libmain.o `test -f 'runtime/go-libmain.c' || echo '$(srcdir)/'`runtime/go-libmain.c
+
+libgolibbegin_a-go-libmain.obj: runtime/go-libmain.c
+@am__fastdepCC_TRUE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgolibbegin_a_CFLAGS) $(CFLAGS) -MT libgolibbegin_a-go-libmain.obj -MD -MP -MF $(DEPDIR)/libgolibbegin_a-go-libmain.Tpo -c -o libgolibbegin_a-go-libmain.obj `if test -f 'runtime/go-libmain.c'; then $(CYGPATH_W) 'runtime/go-libmain.c'; else $(CYGPATH_W) '$(srcdir)/runtime/go-libmain.c'; fi`
+@am__fastdepCC_TRUE@	$(am__mv) $(DEPDIR)/libgolibbegin_a-go-libmain.Tpo $(DEPDIR)/libgolibbegin_a-go-libmain.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='runtime/go-libmain.c' object='libgolibbegin_a-go-libmain.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgolibbegin_a_CFLAGS) $(CFLAGS) -c -o libgolibbegin_a-go-libmain.obj `if test -f 'runtime/go-libmain.c'; then $(CYGPATH_W) 'runtime/go-libmain.c'; else $(CYGPATH_W) '$(srcdir)/runtime/go-libmain.c'; fi`
 
 go-append.lo: runtime/go-append.c
 @am__fastdepCC_TRUE@	$(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT go-append.lo -MD -MP -MF $(DEPDIR)/go-append.Tpo -c -o go-append.lo `test -f 'runtime/go-append.c' || echo '$(srcdir)/'`runtime/go-append.c
@@ -3286,8 +3580,11 @@
 	$(MULTICLEAN) $(AM_MAKEFLAGS) DO=maintainer-clean multi-clean # $(MAKE)
 install-toolexeclibgoDATA: $(toolexeclibgo_DATA)
 	@$(NORMAL_INSTALL)
-	test -z "$(toolexeclibgodir)" || $(MKDIR_P) "$(DESTDIR)$(toolexeclibgodir)"
 	@list='$(toolexeclibgo_DATA)'; test -n "$(toolexeclibgodir)" || list=; \
+	if test -n "$$list"; then \
+	  echo " $(MKDIR_P) '$(DESTDIR)$(toolexeclibgodir)'"; \
+	  $(MKDIR_P) "$(DESTDIR)$(toolexeclibgodir)" || exit 1; \
+	fi; \
 	for p in $$list; do \
 	  if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
 	  echo "$$d$$p"; \
@@ -3301,13 +3598,14 @@
 	@$(NORMAL_UNINSTALL)
 	@list='$(toolexeclibgo_DATA)'; test -n "$(toolexeclibgodir)" || list=; \
 	files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
-	test -n "$$files" || exit 0; \
-	echo " ( cd '$(DESTDIR)$(toolexeclibgodir)' && rm -f" $$files ")"; \
-	cd "$(DESTDIR)$(toolexeclibgodir)" && rm -f $$files
+	dir='$(DESTDIR)$(toolexeclibgodir)'; $(am__uninstall_files_from_dir)
 install-toolexeclibgoarchiveDATA: $(toolexeclibgoarchive_DATA)
 	@$(NORMAL_INSTALL)
-	test -z "$(toolexeclibgoarchivedir)" || $(MKDIR_P) "$(DESTDIR)$(toolexeclibgoarchivedir)"
 	@list='$(toolexeclibgoarchive_DATA)'; test -n "$(toolexeclibgoarchivedir)" || list=; \
+	if test -n "$$list"; then \
+	  echo " $(MKDIR_P) '$(DESTDIR)$(toolexeclibgoarchivedir)'"; \
+	  $(MKDIR_P) "$(DESTDIR)$(toolexeclibgoarchivedir)" || exit 1; \
+	fi; \
 	for p in $$list; do \
 	  if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
 	  echo "$$d$$p"; \
@@ -3321,13 +3619,14 @@
 	@$(NORMAL_UNINSTALL)
 	@list='$(toolexeclibgoarchive_DATA)'; test -n "$(toolexeclibgoarchivedir)" || list=; \
 	files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
-	test -n "$$files" || exit 0; \
-	echo " ( cd '$(DESTDIR)$(toolexeclibgoarchivedir)' && rm -f" $$files ")"; \
-	cd "$(DESTDIR)$(toolexeclibgoarchivedir)" && rm -f $$files
+	dir='$(DESTDIR)$(toolexeclibgoarchivedir)'; $(am__uninstall_files_from_dir)
 install-toolexeclibgocompressDATA: $(toolexeclibgocompress_DATA)
 	@$(NORMAL_INSTALL)
-	test -z "$(toolexeclibgocompressdir)" || $(MKDIR_P) "$(DESTDIR)$(toolexeclibgocompressdir)"
 	@list='$(toolexeclibgocompress_DATA)'; test -n "$(toolexeclibgocompressdir)" || list=; \
+	if test -n "$$list"; then \
+	  echo " $(MKDIR_P) '$(DESTDIR)$(toolexeclibgocompressdir)'"; \
+	  $(MKDIR_P) "$(DESTDIR)$(toolexeclibgocompressdir)" || exit 1; \
+	fi; \
 	for p in $$list; do \
 	  if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
 	  echo "$$d$$p"; \
@@ -3341,13 +3640,14 @@
 	@$(NORMAL_UNINSTALL)
 	@list='$(toolexeclibgocompress_DATA)'; test -n "$(toolexeclibgocompressdir)" || list=; \
 	files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
-	test -n "$$files" || exit 0; \
-	echo " ( cd '$(DESTDIR)$(toolexeclibgocompressdir)' && rm -f" $$files ")"; \
-	cd "$(DESTDIR)$(toolexeclibgocompressdir)" && rm -f $$files
+	dir='$(DESTDIR)$(toolexeclibgocompressdir)'; $(am__uninstall_files_from_dir)
 install-toolexeclibgocontainerDATA: $(toolexeclibgocontainer_DATA)
 	@$(NORMAL_INSTALL)
-	test -z "$(toolexeclibgocontainerdir)" || $(MKDIR_P) "$(DESTDIR)$(toolexeclibgocontainerdir)"
 	@list='$(toolexeclibgocontainer_DATA)'; test -n "$(toolexeclibgocontainerdir)" || list=; \
+	if test -n "$$list"; then \
+	  echo " $(MKDIR_P) '$(DESTDIR)$(toolexeclibgocontainerdir)'"; \
+	  $(MKDIR_P) "$(DESTDIR)$(toolexeclibgocontainerdir)" || exit 1; \
+	fi; \
 	for p in $$list; do \
 	  if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
 	  echo "$$d$$p"; \
@@ -3361,13 +3661,14 @@
 	@$(NORMAL_UNINSTALL)
 	@list='$(toolexeclibgocontainer_DATA)'; test -n "$(toolexeclibgocontainerdir)" || list=; \
 	files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
-	test -n "$$files" || exit 0; \
-	echo " ( cd '$(DESTDIR)$(toolexeclibgocontainerdir)' && rm -f" $$files ")"; \
-	cd "$(DESTDIR)$(toolexeclibgocontainerdir)" && rm -f $$files
+	dir='$(DESTDIR)$(toolexeclibgocontainerdir)'; $(am__uninstall_files_from_dir)
 install-toolexeclibgocryptoDATA: $(toolexeclibgocrypto_DATA)
 	@$(NORMAL_INSTALL)
-	test -z "$(toolexeclibgocryptodir)" || $(MKDIR_P) "$(DESTDIR)$(toolexeclibgocryptodir)"
 	@list='$(toolexeclibgocrypto_DATA)'; test -n "$(toolexeclibgocryptodir)" || list=; \
+	if test -n "$$list"; then \
+	  echo " $(MKDIR_P) '$(DESTDIR)$(toolexeclibgocryptodir)'"; \
+	  $(MKDIR_P) "$(DESTDIR)$(toolexeclibgocryptodir)" || exit 1; \
+	fi; \
 	for p in $$list; do \
 	  if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
 	  echo "$$d$$p"; \
@@ -3381,13 +3682,14 @@
 	@$(NORMAL_UNINSTALL)
 	@list='$(toolexeclibgocrypto_DATA)'; test -n "$(toolexeclibgocryptodir)" || list=; \
 	files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
-	test -n "$$files" || exit 0; \
-	echo " ( cd '$(DESTDIR)$(toolexeclibgocryptodir)' && rm -f" $$files ")"; \
-	cd "$(DESTDIR)$(toolexeclibgocryptodir)" && rm -f $$files
+	dir='$(DESTDIR)$(toolexeclibgocryptodir)'; $(am__uninstall_files_from_dir)
 install-toolexeclibgocryptox509DATA: $(toolexeclibgocryptox509_DATA)
 	@$(NORMAL_INSTALL)
-	test -z "$(toolexeclibgocryptox509dir)" || $(MKDIR_P) "$(DESTDIR)$(toolexeclibgocryptox509dir)"
 	@list='$(toolexeclibgocryptox509_DATA)'; test -n "$(toolexeclibgocryptox509dir)" || list=; \
+	if test -n "$$list"; then \
+	  echo " $(MKDIR_P) '$(DESTDIR)$(toolexeclibgocryptox509dir)'"; \
+	  $(MKDIR_P) "$(DESTDIR)$(toolexeclibgocryptox509dir)" || exit 1; \
+	fi; \
 	for p in $$list; do \
 	  if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
 	  echo "$$d$$p"; \
@@ -3401,13 +3703,14 @@
 	@$(NORMAL_UNINSTALL)
 	@list='$(toolexeclibgocryptox509_DATA)'; test -n "$(toolexeclibgocryptox509dir)" || list=; \
 	files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
-	test -n "$$files" || exit 0; \
-	echo " ( cd '$(DESTDIR)$(toolexeclibgocryptox509dir)' && rm -f" $$files ")"; \
-	cd "$(DESTDIR)$(toolexeclibgocryptox509dir)" && rm -f $$files
+	dir='$(DESTDIR)$(toolexeclibgocryptox509dir)'; $(am__uninstall_files_from_dir)
 install-toolexeclibgodatabaseDATA: $(toolexeclibgodatabase_DATA)
 	@$(NORMAL_INSTALL)
-	test -z "$(toolexeclibgodatabasedir)" || $(MKDIR_P) "$(DESTDIR)$(toolexeclibgodatabasedir)"
 	@list='$(toolexeclibgodatabase_DATA)'; test -n "$(toolexeclibgodatabasedir)" || list=; \
+	if test -n "$$list"; then \
+	  echo " $(MKDIR_P) '$(DESTDIR)$(toolexeclibgodatabasedir)'"; \
+	  $(MKDIR_P) "$(DESTDIR)$(toolexeclibgodatabasedir)" || exit 1; \
+	fi; \
 	for p in $$list; do \
 	  if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
 	  echo "$$d$$p"; \
@@ -3421,13 +3724,14 @@
 	@$(NORMAL_UNINSTALL)
 	@list='$(toolexeclibgodatabase_DATA)'; test -n "$(toolexeclibgodatabasedir)" || list=; \
 	files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
-	test -n "$$files" || exit 0; \
-	echo " ( cd '$(DESTDIR)$(toolexeclibgodatabasedir)' && rm -f" $$files ")"; \
-	cd "$(DESTDIR)$(toolexeclibgodatabasedir)" && rm -f $$files
+	dir='$(DESTDIR)$(toolexeclibgodatabasedir)'; $(am__uninstall_files_from_dir)
 install-toolexeclibgodatabasesqlDATA: $(toolexeclibgodatabasesql_DATA)
 	@$(NORMAL_INSTALL)
-	test -z "$(toolexeclibgodatabasesqldir)" || $(MKDIR_P) "$(DESTDIR)$(toolexeclibgodatabasesqldir)"
 	@list='$(toolexeclibgodatabasesql_DATA)'; test -n "$(toolexeclibgodatabasesqldir)" || list=; \
+	if test -n "$$list"; then \
+	  echo " $(MKDIR_P) '$(DESTDIR)$(toolexeclibgodatabasesqldir)'"; \
+	  $(MKDIR_P) "$(DESTDIR)$(toolexeclibgodatabasesqldir)" || exit 1; \
+	fi; \
 	for p in $$list; do \
 	  if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
 	  echo "$$d$$p"; \
@@ -3441,13 +3745,14 @@
 	@$(NORMAL_UNINSTALL)
 	@list='$(toolexeclibgodatabasesql_DATA)'; test -n "$(toolexeclibgodatabasesqldir)" || list=; \
 	files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
-	test -n "$$files" || exit 0; \
-	echo " ( cd '$(DESTDIR)$(toolexeclibgodatabasesqldir)' && rm -f" $$files ")"; \
-	cd "$(DESTDIR)$(toolexeclibgodatabasesqldir)" && rm -f $$files
+	dir='$(DESTDIR)$(toolexeclibgodatabasesqldir)'; $(am__uninstall_files_from_dir)
 install-toolexeclibgodebugDATA: $(toolexeclibgodebug_DATA)
 	@$(NORMAL_INSTALL)
-	test -z "$(toolexeclibgodebugdir)" || $(MKDIR_P) "$(DESTDIR)$(toolexeclibgodebugdir)"
 	@list='$(toolexeclibgodebug_DATA)'; test -n "$(toolexeclibgodebugdir)" || list=; \
+	if test -n "$$list"; then \
+	  echo " $(MKDIR_P) '$(DESTDIR)$(toolexeclibgodebugdir)'"; \
+	  $(MKDIR_P) "$(DESTDIR)$(toolexeclibgodebugdir)" || exit 1; \
+	fi; \
 	for p in $$list; do \
 	  if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
 	  echo "$$d$$p"; \
@@ -3461,13 +3766,14 @@
 	@$(NORMAL_UNINSTALL)
 	@list='$(toolexeclibgodebug_DATA)'; test -n "$(toolexeclibgodebugdir)" || list=; \
 	files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
-	test -n "$$files" || exit 0; \
-	echo " ( cd '$(DESTDIR)$(toolexeclibgodebugdir)' && rm -f" $$files ")"; \
-	cd "$(DESTDIR)$(toolexeclibgodebugdir)" && rm -f $$files
+	dir='$(DESTDIR)$(toolexeclibgodebugdir)'; $(am__uninstall_files_from_dir)
 install-toolexeclibgoencodingDATA: $(toolexeclibgoencoding_DATA)
 	@$(NORMAL_INSTALL)
-	test -z "$(toolexeclibgoencodingdir)" || $(MKDIR_P) "$(DESTDIR)$(toolexeclibgoencodingdir)"
 	@list='$(toolexeclibgoencoding_DATA)'; test -n "$(toolexeclibgoencodingdir)" || list=; \
+	if test -n "$$list"; then \
+	  echo " $(MKDIR_P) '$(DESTDIR)$(toolexeclibgoencodingdir)'"; \
+	  $(MKDIR_P) "$(DESTDIR)$(toolexeclibgoencodingdir)" || exit 1; \
+	fi; \
 	for p in $$list; do \
 	  if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
 	  echo "$$d$$p"; \
@@ -3481,13 +3787,14 @@
 	@$(NORMAL_UNINSTALL)
 	@list='$(toolexeclibgoencoding_DATA)'; test -n "$(toolexeclibgoencodingdir)" || list=; \
 	files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
-	test -n "$$files" || exit 0; \
-	echo " ( cd '$(DESTDIR)$(toolexeclibgoencodingdir)' && rm -f" $$files ")"; \
-	cd "$(DESTDIR)$(toolexeclibgoencodingdir)" && rm -f $$files
+	dir='$(DESTDIR)$(toolexeclibgoencodingdir)'; $(am__uninstall_files_from_dir)
 install-toolexeclibgoexpDATA: $(toolexeclibgoexp_DATA)
 	@$(NORMAL_INSTALL)
-	test -z "$(toolexeclibgoexpdir)" || $(MKDIR_P) "$(DESTDIR)$(toolexeclibgoexpdir)"
 	@list='$(toolexeclibgoexp_DATA)'; test -n "$(toolexeclibgoexpdir)" || list=; \
+	if test -n "$$list"; then \
+	  echo " $(MKDIR_P) '$(DESTDIR)$(toolexeclibgoexpdir)'"; \
+	  $(MKDIR_P) "$(DESTDIR)$(toolexeclibgoexpdir)" || exit 1; \
+	fi; \
 	for p in $$list; do \
 	  if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
 	  echo "$$d$$p"; \
@@ -3501,13 +3808,14 @@
 	@$(NORMAL_UNINSTALL)
 	@list='$(toolexeclibgoexp_DATA)'; test -n "$(toolexeclibgoexpdir)" || list=; \
 	files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
-	test -n "$$files" || exit 0; \
-	echo " ( cd '$(DESTDIR)$(toolexeclibgoexpdir)' && rm -f" $$files ")"; \
-	cd "$(DESTDIR)$(toolexeclibgoexpdir)" && rm -f $$files
+	dir='$(DESTDIR)$(toolexeclibgoexpdir)'; $(am__uninstall_files_from_dir)
 install-toolexeclibgogoDATA: $(toolexeclibgogo_DATA)
 	@$(NORMAL_INSTALL)
-	test -z "$(toolexeclibgogodir)" || $(MKDIR_P) "$(DESTDIR)$(toolexeclibgogodir)"
 	@list='$(toolexeclibgogo_DATA)'; test -n "$(toolexeclibgogodir)" || list=; \
+	if test -n "$$list"; then \
+	  echo " $(MKDIR_P) '$(DESTDIR)$(toolexeclibgogodir)'"; \
+	  $(MKDIR_P) "$(DESTDIR)$(toolexeclibgogodir)" || exit 1; \
+	fi; \
 	for p in $$list; do \
 	  if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
 	  echo "$$d$$p"; \
@@ -3521,13 +3829,14 @@
 	@$(NORMAL_UNINSTALL)
 	@list='$(toolexeclibgogo_DATA)'; test -n "$(toolexeclibgogodir)" || list=; \
 	files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
-	test -n "$$files" || exit 0; \
-	echo " ( cd '$(DESTDIR)$(toolexeclibgogodir)' && rm -f" $$files ")"; \
-	cd "$(DESTDIR)$(toolexeclibgogodir)" && rm -f $$files
+	dir='$(DESTDIR)$(toolexeclibgogodir)'; $(am__uninstall_files_from_dir)
 install-toolexeclibgohashDATA: $(toolexeclibgohash_DATA)
 	@$(NORMAL_INSTALL)
-	test -z "$(toolexeclibgohashdir)" || $(MKDIR_P) "$(DESTDIR)$(toolexeclibgohashdir)"
 	@list='$(toolexeclibgohash_DATA)'; test -n "$(toolexeclibgohashdir)" || list=; \
+	if test -n "$$list"; then \
+	  echo " $(MKDIR_P) '$(DESTDIR)$(toolexeclibgohashdir)'"; \
+	  $(MKDIR_P) "$(DESTDIR)$(toolexeclibgohashdir)" || exit 1; \
+	fi; \
 	for p in $$list; do \
 	  if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
 	  echo "$$d$$p"; \
@@ -3541,13 +3850,14 @@
 	@$(NORMAL_UNINSTALL)
 	@list='$(toolexeclibgohash_DATA)'; test -n "$(toolexeclibgohashdir)" || list=; \
 	files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
-	test -n "$$files" || exit 0; \
-	echo " ( cd '$(DESTDIR)$(toolexeclibgohashdir)' && rm -f" $$files ")"; \
-	cd "$(DESTDIR)$(toolexeclibgohashdir)" && rm -f $$files
+	dir='$(DESTDIR)$(toolexeclibgohashdir)'; $(am__uninstall_files_from_dir)
 install-toolexeclibgohtmlDATA: $(toolexeclibgohtml_DATA)
 	@$(NORMAL_INSTALL)
-	test -z "$(toolexeclibgohtmldir)" || $(MKDIR_P) "$(DESTDIR)$(toolexeclibgohtmldir)"
 	@list='$(toolexeclibgohtml_DATA)'; test -n "$(toolexeclibgohtmldir)" || list=; \
+	if test -n "$$list"; then \
+	  echo " $(MKDIR_P) '$(DESTDIR)$(toolexeclibgohtmldir)'"; \
+	  $(MKDIR_P) "$(DESTDIR)$(toolexeclibgohtmldir)" || exit 1; \
+	fi; \
 	for p in $$list; do \
 	  if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
 	  echo "$$d$$p"; \
@@ -3561,13 +3871,14 @@
 	@$(NORMAL_UNINSTALL)
 	@list='$(toolexeclibgohtml_DATA)'; test -n "$(toolexeclibgohtmldir)" || list=; \
 	files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
-	test -n "$$files" || exit 0; \
-	echo " ( cd '$(DESTDIR)$(toolexeclibgohtmldir)' && rm -f" $$files ")"; \
-	cd "$(DESTDIR)$(toolexeclibgohtmldir)" && rm -f $$files
+	dir='$(DESTDIR)$(toolexeclibgohtmldir)'; $(am__uninstall_files_from_dir)
 install-toolexeclibgoimageDATA: $(toolexeclibgoimage_DATA)
 	@$(NORMAL_INSTALL)
-	test -z "$(toolexeclibgoimagedir)" || $(MKDIR_P) "$(DESTDIR)$(toolexeclibgoimagedir)"
 	@list='$(toolexeclibgoimage_DATA)'; test -n "$(toolexeclibgoimagedir)" || list=; \
+	if test -n "$$list"; then \
+	  echo " $(MKDIR_P) '$(DESTDIR)$(toolexeclibgoimagedir)'"; \
+	  $(MKDIR_P) "$(DESTDIR)$(toolexeclibgoimagedir)" || exit 1; \
+	fi; \
 	for p in $$list; do \
 	  if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
 	  echo "$$d$$p"; \
@@ -3581,13 +3892,14 @@
 	@$(NORMAL_UNINSTALL)
 	@list='$(toolexeclibgoimage_DATA)'; test -n "$(toolexeclibgoimagedir)" || list=; \
 	files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
-	test -n "$$files" || exit 0; \
-	echo " ( cd '$(DESTDIR)$(toolexeclibgoimagedir)' && rm -f" $$files ")"; \
-	cd "$(DESTDIR)$(toolexeclibgoimagedir)" && rm -f $$files
+	dir='$(DESTDIR)$(toolexeclibgoimagedir)'; $(am__uninstall_files_from_dir)
 install-toolexeclibgoimagecolorDATA: $(toolexeclibgoimagecolor_DATA)
 	@$(NORMAL_INSTALL)
-	test -z "$(toolexeclibgoimagecolordir)" || $(MKDIR_P) "$(DESTDIR)$(toolexeclibgoimagecolordir)"
 	@list='$(toolexeclibgoimagecolor_DATA)'; test -n "$(toolexeclibgoimagecolordir)" || list=; \
+	if test -n "$$list"; then \
+	  echo " $(MKDIR_P) '$(DESTDIR)$(toolexeclibgoimagecolordir)'"; \
+	  $(MKDIR_P) "$(DESTDIR)$(toolexeclibgoimagecolordir)" || exit 1; \
+	fi; \
 	for p in $$list; do \
 	  if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
 	  echo "$$d$$p"; \
@@ -3601,13 +3913,14 @@
 	@$(NORMAL_UNINSTALL)
 	@list='$(toolexeclibgoimagecolor_DATA)'; test -n "$(toolexeclibgoimagecolordir)" || list=; \
 	files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
-	test -n "$$files" || exit 0; \
-	echo " ( cd '$(DESTDIR)$(toolexeclibgoimagecolordir)' && rm -f" $$files ")"; \
-	cd "$(DESTDIR)$(toolexeclibgoimagecolordir)" && rm -f $$files
+	dir='$(DESTDIR)$(toolexeclibgoimagecolordir)'; $(am__uninstall_files_from_dir)
 install-toolexeclibgoindexDATA: $(toolexeclibgoindex_DATA)
 	@$(NORMAL_INSTALL)
-	test -z "$(toolexeclibgoindexdir)" || $(MKDIR_P) "$(DESTDIR)$(toolexeclibgoindexdir)"
 	@list='$(toolexeclibgoindex_DATA)'; test -n "$(toolexeclibgoindexdir)" || list=; \
+	if test -n "$$list"; then \
+	  echo " $(MKDIR_P) '$(DESTDIR)$(toolexeclibgoindexdir)'"; \
+	  $(MKDIR_P) "$(DESTDIR)$(toolexeclibgoindexdir)" || exit 1; \
+	fi; \
 	for p in $$list; do \
 	  if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
 	  echo "$$d$$p"; \
@@ -3621,13 +3934,14 @@
 	@$(NORMAL_UNINSTALL)
 	@list='$(toolexeclibgoindex_DATA)'; test -n "$(toolexeclibgoindexdir)" || list=; \
 	files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
-	test -n "$$files" || exit 0; \
-	echo " ( cd '$(DESTDIR)$(toolexeclibgoindexdir)' && rm -f" $$files ")"; \
-	cd "$(DESTDIR)$(toolexeclibgoindexdir)" && rm -f $$files
+	dir='$(DESTDIR)$(toolexeclibgoindexdir)'; $(am__uninstall_files_from_dir)
 install-toolexeclibgoioDATA: $(toolexeclibgoio_DATA)
 	@$(NORMAL_INSTALL)
-	test -z "$(toolexeclibgoiodir)" || $(MKDIR_P) "$(DESTDIR)$(toolexeclibgoiodir)"
 	@list='$(toolexeclibgoio_DATA)'; test -n "$(toolexeclibgoiodir)" || list=; \
+	if test -n "$$list"; then \
+	  echo " $(MKDIR_P) '$(DESTDIR)$(toolexeclibgoiodir)'"; \
+	  $(MKDIR_P) "$(DESTDIR)$(toolexeclibgoiodir)" || exit 1; \
+	fi; \
 	for p in $$list; do \
 	  if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
 	  echo "$$d$$p"; \
@@ -3641,13 +3955,14 @@
 	@$(NORMAL_UNINSTALL)
 	@list='$(toolexeclibgoio_DATA)'; test -n "$(toolexeclibgoiodir)" || list=; \
 	files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
-	test -n "$$files" || exit 0; \
-	echo " ( cd '$(DESTDIR)$(toolexeclibgoiodir)' && rm -f" $$files ")"; \
-	cd "$(DESTDIR)$(toolexeclibgoiodir)" && rm -f $$files
+	dir='$(DESTDIR)$(toolexeclibgoiodir)'; $(am__uninstall_files_from_dir)
 install-toolexeclibgologDATA: $(toolexeclibgolog_DATA)
 	@$(NORMAL_INSTALL)
-	test -z "$(toolexeclibgologdir)" || $(MKDIR_P) "$(DESTDIR)$(toolexeclibgologdir)"
 	@list='$(toolexeclibgolog_DATA)'; test -n "$(toolexeclibgologdir)" || list=; \
+	if test -n "$$list"; then \
+	  echo " $(MKDIR_P) '$(DESTDIR)$(toolexeclibgologdir)'"; \
+	  $(MKDIR_P) "$(DESTDIR)$(toolexeclibgologdir)" || exit 1; \
+	fi; \
 	for p in $$list; do \
 	  if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
 	  echo "$$d$$p"; \
@@ -3661,13 +3976,14 @@
 	@$(NORMAL_UNINSTALL)
 	@list='$(toolexeclibgolog_DATA)'; test -n "$(toolexeclibgologdir)" || list=; \
 	files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
-	test -n "$$files" || exit 0; \
-	echo " ( cd '$(DESTDIR)$(toolexeclibgologdir)' && rm -f" $$files ")"; \
-	cd "$(DESTDIR)$(toolexeclibgologdir)" && rm -f $$files
+	dir='$(DESTDIR)$(toolexeclibgologdir)'; $(am__uninstall_files_from_dir)
 install-toolexeclibgomathDATA: $(toolexeclibgomath_DATA)
 	@$(NORMAL_INSTALL)
-	test -z "$(toolexeclibgomathdir)" || $(MKDIR_P) "$(DESTDIR)$(toolexeclibgomathdir)"
 	@list='$(toolexeclibgomath_DATA)'; test -n "$(toolexeclibgomathdir)" || list=; \
+	if test -n "$$list"; then \
+	  echo " $(MKDIR_P) '$(DESTDIR)$(toolexeclibgomathdir)'"; \
+	  $(MKDIR_P) "$(DESTDIR)$(toolexeclibgomathdir)" || exit 1; \
+	fi; \
 	for p in $$list; do \
 	  if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
 	  echo "$$d$$p"; \
@@ -3681,13 +3997,14 @@
 	@$(NORMAL_UNINSTALL)
 	@list='$(toolexeclibgomath_DATA)'; test -n "$(toolexeclibgomathdir)" || list=; \
 	files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
-	test -n "$$files" || exit 0; \
-	echo " ( cd '$(DESTDIR)$(toolexeclibgomathdir)' && rm -f" $$files ")"; \
-	cd "$(DESTDIR)$(toolexeclibgomathdir)" && rm -f $$files
+	dir='$(DESTDIR)$(toolexeclibgomathdir)'; $(am__uninstall_files_from_dir)
 install-toolexeclibgomimeDATA: $(toolexeclibgomime_DATA)
 	@$(NORMAL_INSTALL)
-	test -z "$(toolexeclibgomimedir)" || $(MKDIR_P) "$(DESTDIR)$(toolexeclibgomimedir)"
 	@list='$(toolexeclibgomime_DATA)'; test -n "$(toolexeclibgomimedir)" || list=; \
+	if test -n "$$list"; then \
+	  echo " $(MKDIR_P) '$(DESTDIR)$(toolexeclibgomimedir)'"; \
+	  $(MKDIR_P) "$(DESTDIR)$(toolexeclibgomimedir)" || exit 1; \
+	fi; \
 	for p in $$list; do \
 	  if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
 	  echo "$$d$$p"; \
@@ -3701,13 +4018,14 @@
 	@$(NORMAL_UNINSTALL)
 	@list='$(toolexeclibgomime_DATA)'; test -n "$(toolexeclibgomimedir)" || list=; \
 	files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
-	test -n "$$files" || exit 0; \
-	echo " ( cd '$(DESTDIR)$(toolexeclibgomimedir)' && rm -f" $$files ")"; \
-	cd "$(DESTDIR)$(toolexeclibgomimedir)" && rm -f $$files
+	dir='$(DESTDIR)$(toolexeclibgomimedir)'; $(am__uninstall_files_from_dir)
 install-toolexeclibgonetDATA: $(toolexeclibgonet_DATA)
 	@$(NORMAL_INSTALL)
-	test -z "$(toolexeclibgonetdir)" || $(MKDIR_P) "$(DESTDIR)$(toolexeclibgonetdir)"
 	@list='$(toolexeclibgonet_DATA)'; test -n "$(toolexeclibgonetdir)" || list=; \
+	if test -n "$$list"; then \
+	  echo " $(MKDIR_P) '$(DESTDIR)$(toolexeclibgonetdir)'"; \
+	  $(MKDIR_P) "$(DESTDIR)$(toolexeclibgonetdir)" || exit 1; \
+	fi; \
 	for p in $$list; do \
 	  if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
 	  echo "$$d$$p"; \
@@ -3721,13 +4039,14 @@
 	@$(NORMAL_UNINSTALL)
 	@list='$(toolexeclibgonet_DATA)'; test -n "$(toolexeclibgonetdir)" || list=; \
 	files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
-	test -n "$$files" || exit 0; \
-	echo " ( cd '$(DESTDIR)$(toolexeclibgonetdir)' && rm -f" $$files ")"; \
-	cd "$(DESTDIR)$(toolexeclibgonetdir)" && rm -f $$files
+	dir='$(DESTDIR)$(toolexeclibgonetdir)'; $(am__uninstall_files_from_dir)
 install-toolexeclibgonethttpDATA: $(toolexeclibgonethttp_DATA)
 	@$(NORMAL_INSTALL)
-	test -z "$(toolexeclibgonethttpdir)" || $(MKDIR_P) "$(DESTDIR)$(toolexeclibgonethttpdir)"
 	@list='$(toolexeclibgonethttp_DATA)'; test -n "$(toolexeclibgonethttpdir)" || list=; \
+	if test -n "$$list"; then \
+	  echo " $(MKDIR_P) '$(DESTDIR)$(toolexeclibgonethttpdir)'"; \
+	  $(MKDIR_P) "$(DESTDIR)$(toolexeclibgonethttpdir)" || exit 1; \
+	fi; \
 	for p in $$list; do \
 	  if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
 	  echo "$$d$$p"; \
@@ -3741,13 +4060,14 @@
 	@$(NORMAL_UNINSTALL)
 	@list='$(toolexeclibgonethttp_DATA)'; test -n "$(toolexeclibgonethttpdir)" || list=; \
 	files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
-	test -n "$$files" || exit 0; \
-	echo " ( cd '$(DESTDIR)$(toolexeclibgonethttpdir)' && rm -f" $$files ")"; \
-	cd "$(DESTDIR)$(toolexeclibgonethttpdir)" && rm -f $$files
+	dir='$(DESTDIR)$(toolexeclibgonethttpdir)'; $(am__uninstall_files_from_dir)
 install-toolexeclibgonetrpcDATA: $(toolexeclibgonetrpc_DATA)
 	@$(NORMAL_INSTALL)
-	test -z "$(toolexeclibgonetrpcdir)" || $(MKDIR_P) "$(DESTDIR)$(toolexeclibgonetrpcdir)"
 	@list='$(toolexeclibgonetrpc_DATA)'; test -n "$(toolexeclibgonetrpcdir)" || list=; \
+	if test -n "$$list"; then \
+	  echo " $(MKDIR_P) '$(DESTDIR)$(toolexeclibgonetrpcdir)'"; \
+	  $(MKDIR_P) "$(DESTDIR)$(toolexeclibgonetrpcdir)" || exit 1; \
+	fi; \
 	for p in $$list; do \
 	  if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
 	  echo "$$d$$p"; \
@@ -3761,13 +4081,14 @@
 	@$(NORMAL_UNINSTALL)
 	@list='$(toolexeclibgonetrpc_DATA)'; test -n "$(toolexeclibgonetrpcdir)" || list=; \
 	files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
-	test -n "$$files" || exit 0; \
-	echo " ( cd '$(DESTDIR)$(toolexeclibgonetrpcdir)' && rm -f" $$files ")"; \
-	cd "$(DESTDIR)$(toolexeclibgonetrpcdir)" && rm -f $$files
+	dir='$(DESTDIR)$(toolexeclibgonetrpcdir)'; $(am__uninstall_files_from_dir)
 install-toolexeclibgooldDATA: $(toolexeclibgoold_DATA)
 	@$(NORMAL_INSTALL)
-	test -z "$(toolexeclibgoolddir)" || $(MKDIR_P) "$(DESTDIR)$(toolexeclibgoolddir)"
 	@list='$(toolexeclibgoold_DATA)'; test -n "$(toolexeclibgoolddir)" || list=; \
+	if test -n "$$list"; then \
+	  echo " $(MKDIR_P) '$(DESTDIR)$(toolexeclibgoolddir)'"; \
+	  $(MKDIR_P) "$(DESTDIR)$(toolexeclibgoolddir)" || exit 1; \
+	fi; \
 	for p in $$list; do \
 	  if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
 	  echo "$$d$$p"; \
@@ -3781,13 +4102,14 @@
 	@$(NORMAL_UNINSTALL)
 	@list='$(toolexeclibgoold_DATA)'; test -n "$(toolexeclibgoolddir)" || list=; \
 	files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
-	test -n "$$files" || exit 0; \
-	echo " ( cd '$(DESTDIR)$(toolexeclibgoolddir)' && rm -f" $$files ")"; \
-	cd "$(DESTDIR)$(toolexeclibgoolddir)" && rm -f $$files
+	dir='$(DESTDIR)$(toolexeclibgoolddir)'; $(am__uninstall_files_from_dir)
 install-toolexeclibgoosDATA: $(toolexeclibgoos_DATA)
 	@$(NORMAL_INSTALL)
-	test -z "$(toolexeclibgoosdir)" || $(MKDIR_P) "$(DESTDIR)$(toolexeclibgoosdir)"
 	@list='$(toolexeclibgoos_DATA)'; test -n "$(toolexeclibgoosdir)" || list=; \
+	if test -n "$$list"; then \
+	  echo " $(MKDIR_P) '$(DESTDIR)$(toolexeclibgoosdir)'"; \
+	  $(MKDIR_P) "$(DESTDIR)$(toolexeclibgoosdir)" || exit 1; \
+	fi; \
 	for p in $$list; do \
 	  if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
 	  echo "$$d$$p"; \
@@ -3801,13 +4123,14 @@
 	@$(NORMAL_UNINSTALL)
 	@list='$(toolexeclibgoos_DATA)'; test -n "$(toolexeclibgoosdir)" || list=; \
 	files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
-	test -n "$$files" || exit 0; \
-	echo " ( cd '$(DESTDIR)$(toolexeclibgoosdir)' && rm -f" $$files ")"; \
-	cd "$(DESTDIR)$(toolexeclibgoosdir)" && rm -f $$files
+	dir='$(DESTDIR)$(toolexeclibgoosdir)'; $(am__uninstall_files_from_dir)
 install-toolexeclibgopathDATA: $(toolexeclibgopath_DATA)
 	@$(NORMAL_INSTALL)
-	test -z "$(toolexeclibgopathdir)" || $(MKDIR_P) "$(DESTDIR)$(toolexeclibgopathdir)"
 	@list='$(toolexeclibgopath_DATA)'; test -n "$(toolexeclibgopathdir)" || list=; \
+	if test -n "$$list"; then \
+	  echo " $(MKDIR_P) '$(DESTDIR)$(toolexeclibgopathdir)'"; \
+	  $(MKDIR_P) "$(DESTDIR)$(toolexeclibgopathdir)" || exit 1; \
+	fi; \
 	for p in $$list; do \
 	  if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
 	  echo "$$d$$p"; \
@@ -3821,13 +4144,14 @@
 	@$(NORMAL_UNINSTALL)
 	@list='$(toolexeclibgopath_DATA)'; test -n "$(toolexeclibgopathdir)" || list=; \
 	files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
-	test -n "$$files" || exit 0; \
-	echo " ( cd '$(DESTDIR)$(toolexeclibgopathdir)' && rm -f" $$files ")"; \
-	cd "$(DESTDIR)$(toolexeclibgopathdir)" && rm -f $$files
+	dir='$(DESTDIR)$(toolexeclibgopathdir)'; $(am__uninstall_files_from_dir)
 install-toolexeclibgoregexpDATA: $(toolexeclibgoregexp_DATA)
 	@$(NORMAL_INSTALL)
-	test -z "$(toolexeclibgoregexpdir)" || $(MKDIR_P) "$(DESTDIR)$(toolexeclibgoregexpdir)"
 	@list='$(toolexeclibgoregexp_DATA)'; test -n "$(toolexeclibgoregexpdir)" || list=; \
+	if test -n "$$list"; then \
+	  echo " $(MKDIR_P) '$(DESTDIR)$(toolexeclibgoregexpdir)'"; \
+	  $(MKDIR_P) "$(DESTDIR)$(toolexeclibgoregexpdir)" || exit 1; \
+	fi; \
 	for p in $$list; do \
 	  if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
 	  echo "$$d$$p"; \
@@ -3841,13 +4165,14 @@
 	@$(NORMAL_UNINSTALL)
 	@list='$(toolexeclibgoregexp_DATA)'; test -n "$(toolexeclibgoregexpdir)" || list=; \
 	files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
-	test -n "$$files" || exit 0; \
-	echo " ( cd '$(DESTDIR)$(toolexeclibgoregexpdir)' && rm -f" $$files ")"; \
-	cd "$(DESTDIR)$(toolexeclibgoregexpdir)" && rm -f $$files
+	dir='$(DESTDIR)$(toolexeclibgoregexpdir)'; $(am__uninstall_files_from_dir)
 install-toolexeclibgoruntimeDATA: $(toolexeclibgoruntime_DATA)
 	@$(NORMAL_INSTALL)
-	test -z "$(toolexeclibgoruntimedir)" || $(MKDIR_P) "$(DESTDIR)$(toolexeclibgoruntimedir)"
 	@list='$(toolexeclibgoruntime_DATA)'; test -n "$(toolexeclibgoruntimedir)" || list=; \
+	if test -n "$$list"; then \
+	  echo " $(MKDIR_P) '$(DESTDIR)$(toolexeclibgoruntimedir)'"; \
+	  $(MKDIR_P) "$(DESTDIR)$(toolexeclibgoruntimedir)" || exit 1; \
+	fi; \
 	for p in $$list; do \
 	  if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
 	  echo "$$d$$p"; \
@@ -3861,13 +4186,14 @@
 	@$(NORMAL_UNINSTALL)
 	@list='$(toolexeclibgoruntime_DATA)'; test -n "$(toolexeclibgoruntimedir)" || list=; \
 	files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
-	test -n "$$files" || exit 0; \
-	echo " ( cd '$(DESTDIR)$(toolexeclibgoruntimedir)' && rm -f" $$files ")"; \
-	cd "$(DESTDIR)$(toolexeclibgoruntimedir)" && rm -f $$files
+	dir='$(DESTDIR)$(toolexeclibgoruntimedir)'; $(am__uninstall_files_from_dir)
 install-toolexeclibgosyncDATA: $(toolexeclibgosync_DATA)
 	@$(NORMAL_INSTALL)
-	test -z "$(toolexeclibgosyncdir)" || $(MKDIR_P) "$(DESTDIR)$(toolexeclibgosyncdir)"
 	@list='$(toolexeclibgosync_DATA)'; test -n "$(toolexeclibgosyncdir)" || list=; \
+	if test -n "$$list"; then \
+	  echo " $(MKDIR_P) '$(DESTDIR)$(toolexeclibgosyncdir)'"; \
+	  $(MKDIR_P) "$(DESTDIR)$(toolexeclibgosyncdir)" || exit 1; \
+	fi; \
 	for p in $$list; do \
 	  if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
 	  echo "$$d$$p"; \
@@ -3881,13 +4207,14 @@
 	@$(NORMAL_UNINSTALL)
 	@list='$(toolexeclibgosync_DATA)'; test -n "$(toolexeclibgosyncdir)" || list=; \
 	files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
-	test -n "$$files" || exit 0; \
-	echo " ( cd '$(DESTDIR)$(toolexeclibgosyncdir)' && rm -f" $$files ")"; \
-	cd "$(DESTDIR)$(toolexeclibgosyncdir)" && rm -f $$files
+	dir='$(DESTDIR)$(toolexeclibgosyncdir)'; $(am__uninstall_files_from_dir)
 install-toolexeclibgotestingDATA: $(toolexeclibgotesting_DATA)
 	@$(NORMAL_INSTALL)
-	test -z "$(toolexeclibgotestingdir)" || $(MKDIR_P) "$(DESTDIR)$(toolexeclibgotestingdir)"
 	@list='$(toolexeclibgotesting_DATA)'; test -n "$(toolexeclibgotestingdir)" || list=; \
+	if test -n "$$list"; then \
+	  echo " $(MKDIR_P) '$(DESTDIR)$(toolexeclibgotestingdir)'"; \
+	  $(MKDIR_P) "$(DESTDIR)$(toolexeclibgotestingdir)" || exit 1; \
+	fi; \
 	for p in $$list; do \
 	  if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
 	  echo "$$d$$p"; \
@@ -3901,13 +4228,14 @@
 	@$(NORMAL_UNINSTALL)
 	@list='$(toolexeclibgotesting_DATA)'; test -n "$(toolexeclibgotestingdir)" || list=; \
 	files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
-	test -n "$$files" || exit 0; \
-	echo " ( cd '$(DESTDIR)$(toolexeclibgotestingdir)' && rm -f" $$files ")"; \
-	cd "$(DESTDIR)$(toolexeclibgotestingdir)" && rm -f $$files
+	dir='$(DESTDIR)$(toolexeclibgotestingdir)'; $(am__uninstall_files_from_dir)
 install-toolexeclibgotextDATA: $(toolexeclibgotext_DATA)
 	@$(NORMAL_INSTALL)
-	test -z "$(toolexeclibgotextdir)" || $(MKDIR_P) "$(DESTDIR)$(toolexeclibgotextdir)"
 	@list='$(toolexeclibgotext_DATA)'; test -n "$(toolexeclibgotextdir)" || list=; \
+	if test -n "$$list"; then \
+	  echo " $(MKDIR_P) '$(DESTDIR)$(toolexeclibgotextdir)'"; \
+	  $(MKDIR_P) "$(DESTDIR)$(toolexeclibgotextdir)" || exit 1; \
+	fi; \
 	for p in $$list; do \
 	  if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
 	  echo "$$d$$p"; \
@@ -3921,13 +4249,14 @@
 	@$(NORMAL_UNINSTALL)
 	@list='$(toolexeclibgotext_DATA)'; test -n "$(toolexeclibgotextdir)" || list=; \
 	files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
-	test -n "$$files" || exit 0; \
-	echo " ( cd '$(DESTDIR)$(toolexeclibgotextdir)' && rm -f" $$files ")"; \
-	cd "$(DESTDIR)$(toolexeclibgotextdir)" && rm -f $$files
+	dir='$(DESTDIR)$(toolexeclibgotextdir)'; $(am__uninstall_files_from_dir)
 install-toolexeclibgotexttemplateDATA: $(toolexeclibgotexttemplate_DATA)
 	@$(NORMAL_INSTALL)
-	test -z "$(toolexeclibgotexttemplatedir)" || $(MKDIR_P) "$(DESTDIR)$(toolexeclibgotexttemplatedir)"
 	@list='$(toolexeclibgotexttemplate_DATA)'; test -n "$(toolexeclibgotexttemplatedir)" || list=; \
+	if test -n "$$list"; then \
+	  echo " $(MKDIR_P) '$(DESTDIR)$(toolexeclibgotexttemplatedir)'"; \
+	  $(MKDIR_P) "$(DESTDIR)$(toolexeclibgotexttemplatedir)" || exit 1; \
+	fi; \
 	for p in $$list; do \
 	  if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
 	  echo "$$d$$p"; \
@@ -3941,13 +4270,14 @@
 	@$(NORMAL_UNINSTALL)
 	@list='$(toolexeclibgotexttemplate_DATA)'; test -n "$(toolexeclibgotexttemplatedir)" || list=; \
 	files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
-	test -n "$$files" || exit 0; \
-	echo " ( cd '$(DESTDIR)$(toolexeclibgotexttemplatedir)' && rm -f" $$files ")"; \
-	cd "$(DESTDIR)$(toolexeclibgotexttemplatedir)" && rm -f $$files
+	dir='$(DESTDIR)$(toolexeclibgotexttemplatedir)'; $(am__uninstall_files_from_dir)
 install-toolexeclibgounicodeDATA: $(toolexeclibgounicode_DATA)
 	@$(NORMAL_INSTALL)
-	test -z "$(toolexeclibgounicodedir)" || $(MKDIR_P) "$(DESTDIR)$(toolexeclibgounicodedir)"
 	@list='$(toolexeclibgounicode_DATA)'; test -n "$(toolexeclibgounicodedir)" || list=; \
+	if test -n "$$list"; then \
+	  echo " $(MKDIR_P) '$(DESTDIR)$(toolexeclibgounicodedir)'"; \
+	  $(MKDIR_P) "$(DESTDIR)$(toolexeclibgounicodedir)" || exit 1; \
+	fi; \
 	for p in $$list; do \
 	  if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
 	  echo "$$d$$p"; \
@@ -3961,9 +4291,7 @@
 	@$(NORMAL_UNINSTALL)
 	@list='$(toolexeclibgounicode_DATA)'; test -n "$(toolexeclibgounicodedir)" || list=; \
 	files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
-	test -n "$$files" || exit 0; \
-	echo " ( cd '$(DESTDIR)$(toolexeclibgounicodedir)' && rm -f" $$files ")"; \
-	cd "$(DESTDIR)$(toolexeclibgounicodedir)" && rm -f $$files
+	dir='$(DESTDIR)$(toolexeclibgounicodedir)'; $(am__uninstall_files_from_dir)
 
 # This directory's subdirectories are mostly independent; you can cd
 # into them and run `make' without going through this Makefile.
@@ -4118,10 +4446,15 @@
 
 installcheck: installcheck-recursive
 install-strip:
-	$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
-	  install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
-	  `test -z '$(STRIP)' || \
-	    echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+	if test -z '$(STRIP)'; then \
+	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	      install; \
+	else \
+	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	    "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+	fi
 mostlyclean-generic:
 
 clean-generic:
@@ -4613,6 +4946,12 @@
 	@$(CHECK)
 .PHONY: net/check
 
+@go_include@ netgo.o.dep
+netgo.o.dep: $(go_netgo_files)
+	$(BUILDDEPS)
+netgo.o: $(go_netgo_files)
+	$(BUILDNETGO)
+
 @go_include@ os.lo.dep
 os.lo.dep: $(go_os_files)
 	$(BUILDDEPS)
@@ -5195,6 +5534,15 @@
 	@$(CHECK)
 .PHONY: go/build/check
 
+@go_include@ go/constant.lo.dep
+go/constant.lo.dep: $(go_go_constant_files)
+	$(BUILDDEPS)
+go/constant.lo: $(go_go_constant_files)
+	$(BUILDPACKAGE)
+go/constant/check: $(CHECK_DEPS)
+	@$(CHECK)
+.PHONY: go/constant/check
+
 @go_include@ go/doc.lo.dep
 go/doc.lo.dep: $(go_go_doc_files)
 	$(BUILDDEPS)
@@ -5213,6 +5561,15 @@
 	@$(CHECK)
 .PHONY: go/format/check
 
+@go_include@ go/importer.lo.dep
+go/importer.lo.dep: $(go_go_importer_files)
+	$(BUILDDEPS)
+go/importer.lo: $(go_go_importer_files)
+	$(BUILDPACKAGE)
+go/importer/check: $(CHECK_DEPS)
+	@$(CHECK)
+.PHONY: go/importer/check
+
 @go_include@ go/parser.lo.dep
 go/parser.lo.dep: $(go_go_parser_files)
 	$(BUILDDEPS)
@@ -5249,6 +5606,33 @@
 	@$(CHECK)
 .PHONY: go/token/check
 
+@go_include@ go/types.lo.dep
+go/types.lo.dep: $(go_go_types_files)
+	$(BUILDDEPS)
+go/types.lo: $(go_go_types_files)
+	$(BUILDPACKAGE)
+go/types/check: $(CHECK_DEPS)
+	@$(CHECK)
+.PHONY: go/types/check
+
+@go_include@ go/internal/gcimporter.lo.dep
+go/internal/gcimporter.lo.dep: $(go_go_internal_gcimporter_files)
+	$(BUILDDEPS)
+go/internal/gcimporter.lo: $(go_go_internal_gcimporter_files)
+	$(BUILDPACKAGE)
+go/internal/gcimporter/check: $(CHECK_DEPS)
+	@$(CHECK)
+.PHONY: go/internal/gcimporter/check
+
+@go_include@ go/internal/gccgoimporter.lo.dep
+go/internal/gccgoimporter.lo.dep: $(go_go_internal_gccgoimporter_files)
+	$(BUILDDEPS)
+go/internal/gccgoimporter.lo: $(go_go_internal_gccgoimporter_files)
+	$(BUILDPACKAGE)
+go/internal/gccgoimporter/check: $(CHECK_DEPS)
+	@$(CHECK)
+.PHONY: go/internal/gccgoimporter/check
+
 @go_include@ hash/adler32.lo.dep
 hash/adler32.lo.dep: $(go_hash_adler32_files)
 	$(BUILDDEPS)
@@ -5321,6 +5705,15 @@
 	@$(CHECK)
 .PHONY: image/gif/check
 
+@go_include@ image/internal/imageutil.lo.dep
+image/internal/imageutil.lo.dep: $(go_image_internal_imageutil_files)
+	$(BUILDDEPS)
+image/internal/imageutil.lo: $(go_image_internal_imageutil_files)
+	$(BUILDPACKAGE)
+image/internal/imageutil/check: $(CHECK_DEPS)
+	@$(CHECK)
+.PHONY: image/internal/imageutil/check
+
 @go_include@ image/jpeg.lo.dep
 image/jpeg.lo.dep: $(go_image_jpeg_files)
 	$(BUILDDEPS)
@@ -5348,6 +5741,51 @@
 	@$(CHECK)
 .PHONY: index/suffixarray/check
 
+@go_include@ internal/format.lo.dep
+internal/format.lo.dep: $(go_internal_format_files)
+	$(BUILDDEPS)
+internal/format.lo: $(go_internal_format_files)
+	$(BUILDPACKAGE)
+internal/format/check: $(CHECK_DEPS)
+	@$(CHECK)
+.PHONY: internal/format/check
+
+@go_include@ internal/singleflight.lo.dep
+internal/singleflight.lo.dep: $(go_internal_singleflight_files)
+	$(BUILDDEPS)
+internal/singleflight.lo: $(go_internal_singleflight_files)
+	$(BUILDPACKAGE)
+internal/singleflight/check: $(CHECK_DEPS)
+	@$(CHECK)
+.PHONY: internal/singleflight/check
+
+@go_include@ internal/syscall/unix.lo.dep
+internal/syscall/unix.lo.dep: $(go_internal_syscall_unix_files)
+	$(BUILDDEPS)
+internal/syscall/unix.lo: $(go_internal_syscall_unix_files)
+	$(BUILDPACKAGE)
+internal/syscall/unix/check: $(CHECK_DEPS)
+	@$(CHECK)
+.PHONY: internal/syscall/unix/check
+
+@go_include@ internal/testenv.lo.dep
+internal/testenv.lo.dep: $(go_internal_testenv_files)
+	$(BUILDDEPS)
+internal/testenv.lo: $(go_internal_testenv_files)
+	$(BUILDPACKAGE)
+internal/testenv/check: $(CHECK_DEPS)
+	@$(CHECK)
+.PHONY: internal/testenv/check
+
+@go_include@ internal/trace.lo.dep
+internal/trace.lo.dep: $(go_internal_trace_files)
+	$(BUILDDEPS)
+internal/trace.lo: $(go_internal_trace_files)
+	$(BUILDPACKAGE)
+internal/trace/check: $(CHECK_DEPS)
+	@$(CHECK)
+.PHONY: internal/trace/check
+
 @go_include@ io/ioutil.lo.dep
 io/ioutil.lo.dep: $(go_io_ioutil_files)
 	$(BUILDDEPS)
@@ -5405,6 +5843,15 @@
 	@$(CHECK)
 .PHONY: mime/multipart/check
 
+@go_include@ mime/quotedprintable.lo.dep
+mime/quotedprintable.lo.dep: $(go_mime_quotedprintable_files)
+	$(BUILDDEPS)
+mime/quotedprintable.lo: $(go_mime_quotedprintable_files)
+	$(BUILDPACKAGE)
+mime/quotedprintable/check: $(CHECK_DEPS)
+	@$(CHECK)
+.PHONY: mime/quotedprintable/check
+
 @go_include@ net/http.lo.dep
 net/http.lo.dep: $(go_net_http_files)
 	$(BUILDDEPS)
@@ -5522,6 +5969,15 @@
 	@$(CHECK)
 .PHONY: net/http/pprof/check
 
+@go_include@ net/internal/socktest.lo.dep
+net/internal/socktest.lo.dep: $(go_net_internal_socktest_files)
+	$(BUILDDEPS)
+net/internal/socktest.lo: $(go_net_internal_socktest_files)
+	$(BUILDPACKAGE)
+net/internal/socktest/check: $(CHECK_DEPS)
+	@$(CHECK)
+.PHONY: net/internal/socktest/check
+
 @go_include@ net/rpc/jsonrpc.lo.dep
 net/rpc/jsonrpc.lo.dep: $(go_net_rpc_jsonrpc_files)
 	$(BUILDDEPS)
@@ -5713,15 +6169,6 @@
 	@$(CHECK)
 .PHONY: syscall/check
 
-@go_include@ internal/syscall.lo.dep
-internal/syscall.lo.dep: $(go_internal_syscall_files)
-	$(BUILDDEPS)
-internal/syscall.lo: $(go_internal_syscall_files)
-	$(BUILDPACKAGE)
-internal/syscall/check: $(CHECK_DEPS)
-	@$(CHECK)
-.PHONY: internal/syscall/check
-
 bufio.gox: bufio.lo
 	$(BUILDGOX)
 bytes.gox: bytes.lo
@@ -5896,10 +6343,14 @@
 	$(BUILDGOX)
 go/build.gox: go/build.lo
 	$(BUILDGOX)
+go/constant.gox: go/constant.lo
+	$(BUILDGOX)
 go/doc.gox: go/doc.lo
 	$(BUILDGOX)
 go/format.gox: go/format.lo
 	$(BUILDGOX)
+go/importer.gox: go/importer.lo
+	$(BUILDGOX)
 go/parser.gox: go/parser.lo
 	$(BUILDGOX)
 go/printer.gox: go/printer.lo
@@ -5908,6 +6359,13 @@
 	$(BUILDGOX)
 go/token.gox: go/token.lo
 	$(BUILDGOX)
+go/types.gox: go/types.lo
+	$(BUILDGOX)
+
+go/internal/gcimporter.gox: go/internal/gcimporter.lo
+	$(BUILDGOX)
+go/internal/gccgoimporter.gox: go/internal/gccgoimporter.lo
+	$(BUILDGOX)
 
 hash/adler32.gox: hash/adler32.lo
 	$(BUILDGOX)
@@ -5924,6 +6382,8 @@
 	$(BUILDGOX)
 image/gif.gox: image/gif.lo
 	$(BUILDGOX)
+image/internal/imageutil.gox: image/internal/imageutil.lo
+	$(BUILDGOX)
 image/jpeg.gox: image/jpeg.lo
 	$(BUILDGOX)
 image/png.gox: image/png.lo
@@ -5935,6 +6395,17 @@
 index/suffixarray.gox: index/suffixarray.lo
 	$(BUILDGOX)
 
+internal/format.gox: internal/format.lo
+	$(BUILDGOX)
+internal/singleflight.gox: internal/singleflight.lo
+	$(BUILDGOX)
+internal/syscall/unix.gox: internal/syscall/unix.lo
+	$(BUILDGOX)
+internal/testenv.gox: internal/testenv.lo
+	$(BUILDGOX)
+internal/trace.gox: internal/trace.lo
+	$(BUILDGOX)
+
 io/ioutil.gox: io/ioutil.lo
 	$(BUILDGOX)
 
@@ -5950,6 +6421,8 @@
 
 mime/multipart.gox: mime/multipart.lo
 	$(BUILDGOX)
+mime/quotedprintable.gox: mime/quotedprintable.lo
+	$(BUILDGOX)
 
 net/http.gox: net/http.lo
 	$(BUILDGOX)
@@ -5980,6 +6453,9 @@
 net/http/internal.gox: net/http/internal.lo
 	$(BUILDGOX)
 
+net/internal/socktest.gox: net/internal/socktest.lo
+	$(BUILDGOX)
+
 net/rpc/jsonrpc.gox: net/rpc/jsonrpc.lo
 	$(BUILDGOX)
 
@@ -6009,9 +6485,6 @@
 sync/atomic.gox: sync/atomic.lo
 	$(BUILDGOX)
 
-internal/syscall.gox: internal/syscall.lo
-	$(BUILDGOX)
-
 text/scanner.gox: text/scanner.lo
 	$(BUILDGOX)
 text/tabwriter.gox: text/tabwriter.lo
diff --git a/third_party/gofrontend/libgo/VERSION b/third_party/gofrontend/libgo/VERSION
index bcab27e..77af434 100644
--- a/third_party/gofrontend/libgo/VERSION
+++ b/third_party/gofrontend/libgo/VERSION
@@ -1 +1 @@
-go1.4.2
\ No newline at end of file
+go1.5.1
\ No newline at end of file
diff --git a/third_party/gofrontend/libgo/aclocal.m4 b/third_party/gofrontend/libgo/aclocal.m4
index ca453c6..aefbad2 100644
--- a/third_party/gofrontend/libgo/aclocal.m4
+++ b/third_party/gofrontend/libgo/aclocal.m4
@@ -1,7 +1,8 @@
-# generated automatically by aclocal 1.11.1 -*- Autoconf -*-
+# generated automatically by aclocal 1.11.6 -*- Autoconf -*-
 
 # Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
-# 2005, 2006, 2007, 2008, 2009  Free Software Foundation, Inc.
+# 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software Foundation,
+# Inc.
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
 # with or without modifications, as long as this notice is preserved.
@@ -19,12 +20,15 @@
 If you have problems, you may need to regenerate the build system entirely.
 To do so, use the procedure documented by the package, typically `autoreconf'.])])
 
-# Copyright (C) 2002, 2003, 2005, 2006, 2007, 2008  Free Software Foundation, Inc.
+# Copyright (C) 2002, 2003, 2005, 2006, 2007, 2008, 2011 Free Software
+# Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
 # with or without modifications, as long as this notice is preserved.
 
+# serial 1
+
 # AM_AUTOMAKE_VERSION(VERSION)
 # ----------------------------
 # Automake X.Y traces this macro to ensure aclocal.m4 has been
@@ -34,7 +38,7 @@
 [am__api_version='1.11'
 dnl Some users find AM_AUTOMAKE_VERSION and mistake it for a way to
 dnl require some minimum version.  Point them to the right macro.
-m4_if([$1], [1.11.1], [],
+m4_if([$1], [1.11.6], [],
       [AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl
 ])
 
@@ -50,19 +54,21 @@
 # Call AM_AUTOMAKE_VERSION and AM_AUTOMAKE_VERSION so they can be traced.
 # This function is AC_REQUIREd by AM_INIT_AUTOMAKE.
 AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION],
-[AM_AUTOMAKE_VERSION([1.11.1])dnl
+[AM_AUTOMAKE_VERSION([1.11.6])dnl
 m4_ifndef([AC_AUTOCONF_VERSION],
   [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl
 _AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))])
 
 # AM_AUX_DIR_EXPAND                                         -*- Autoconf -*-
 
-# Copyright (C) 2001, 2003, 2005  Free Software Foundation, Inc.
+# Copyright (C) 2001, 2003, 2005, 2011 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
 # with or without modifications, as long as this notice is preserved.
 
+# serial 1
+
 # For projects using AC_CONFIG_AUX_DIR([foo]), Autoconf sets
 # $ac_aux_dir to `$srcdir/foo'.  In other projects, it is set to
 # `$srcdir', `$srcdir/..', or `$srcdir/../..'.
@@ -144,14 +150,14 @@
 Usually this means the macro was only invoked conditionally.]])
 fi])])
 
-# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2009
-# Free Software Foundation, Inc.
+# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2009,
+# 2010, 2011 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
 # with or without modifications, as long as this notice is preserved.
 
-# serial 10
+# serial 12
 
 # There are a few dirty hacks below to avoid letting `AC_PROG_CC' be
 # written in clear, in which case automake, when reading aclocal.m4,
@@ -191,6 +197,7 @@
   # instance it was reported that on HP-UX the gcc test will end up
   # making a dummy file named `D' -- because `-MD' means `put the output
   # in D'.
+  rm -rf conftest.dir
   mkdir conftest.dir
   # Copy depcomp to subdir because otherwise we won't find it if we're
   # using a relative directory.
@@ -255,7 +262,7 @@
 	break
       fi
       ;;
-    msvisualcpp | msvcmsys)
+    msvc7 | msvc7msys | msvisualcpp | msvcmsys)
       # This compiler won't grok `-c -o', but also, the minuso test has
       # not run yet.  These depmodes are late enough in the game, and
       # so weak that their functioning should not be impacted.
@@ -320,10 +327,13 @@
 if test "x$enable_dependency_tracking" != xno; then
   am_depcomp="$ac_aux_dir/depcomp"
   AMDEPBACKSLASH='\'
+  am__nodep='_no'
 fi
 AM_CONDITIONAL([AMDEP], [test "x$enable_dependency_tracking" != xno])
 AC_SUBST([AMDEPBACKSLASH])dnl
 _AM_SUBST_NOTMAKE([AMDEPBACKSLASH])dnl
+AC_SUBST([am__nodep])dnl
+_AM_SUBST_NOTMAKE([am__nodep])dnl
 ])
 
 # Generate code to set up dependency tracking.              -*- Autoconf -*-
@@ -545,12 +555,15 @@
 done
 echo "timestamp for $_am_arg" >`AS_DIRNAME(["$_am_arg"])`/stamp-h[]$_am_stamp_count])
 
-# Copyright (C) 2001, 2003, 2005, 2008  Free Software Foundation, Inc.
+# Copyright (C) 2001, 2003, 2005, 2008, 2011 Free Software Foundation,
+# Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
 # with or without modifications, as long as this notice is preserved.
 
+# serial 1
+
 # AM_PROG_INSTALL_SH
 # ------------------
 # Define $install_sh.
@@ -569,8 +582,8 @@
 # Add --enable-maintainer-mode option to configure.         -*- Autoconf -*-
 # From Jim Meyering
 
-# Copyright (C) 1996, 1998, 2000, 2001, 2002, 2003, 2004, 2005, 2008
-# Free Software Foundation, Inc.
+# Copyright (C) 1996, 1998, 2000, 2001, 2002, 2003, 2004, 2005, 2008,
+# 2011 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -590,7 +603,7 @@
        [disable], [m4_define([am_maintainer_other], [enable])],
        [m4_define([am_maintainer_other], [enable])
         m4_warn([syntax], [unexpected argument to AM@&t@_MAINTAINER_MODE: $1])])
-AC_MSG_CHECKING([whether to am_maintainer_other maintainer-specific portions of Makefiles])
+AC_MSG_CHECKING([whether to enable maintainer-specific portions of Makefiles])
   dnl maintainer-mode's default is 'disable' unless 'enable' is passed
   AC_ARG_ENABLE([maintainer-mode],
 [  --][am_maintainer_other][-maintainer-mode  am_maintainer_other make rules and dependencies not useful
@@ -701,12 +714,15 @@
 fi
 ])
 
-# Copyright (C) 2003, 2004, 2005, 2006  Free Software Foundation, Inc.
+# Copyright (C) 2003, 2004, 2005, 2006, 2011 Free Software Foundation,
+# Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
 # with or without modifications, as long as this notice is preserved.
 
+# serial 1
+
 # AM_PROG_MKDIR_P
 # ---------------
 # Check for `mkdir -p'.
@@ -729,13 +745,14 @@
 
 # Helper functions for option handling.                     -*- Autoconf -*-
 
-# Copyright (C) 2001, 2002, 2003, 2005, 2008  Free Software Foundation, Inc.
+# Copyright (C) 2001, 2002, 2003, 2005, 2008, 2010 Free Software
+# Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
 # with or without modifications, as long as this notice is preserved.
 
-# serial 4
+# serial 5
 
 # _AM_MANGLE_OPTION(NAME)
 # -----------------------
@@ -743,13 +760,13 @@
 [[_AM_OPTION_]m4_bpatsubst($1, [[^a-zA-Z0-9_]], [_])])
 
 # _AM_SET_OPTION(NAME)
-# ------------------------------
+# --------------------
 # Set option NAME.  Presently that only means defining a flag for this option.
 AC_DEFUN([_AM_SET_OPTION],
 [m4_define(_AM_MANGLE_OPTION([$1]), 1)])
 
 # _AM_SET_OPTIONS(OPTIONS)
-# ----------------------------------
+# ------------------------
 # OPTIONS is a space-separated list of Automake options.
 AC_DEFUN([_AM_SET_OPTIONS],
 [m4_foreach_w([_AM_Option], [$1], [_AM_SET_OPTION(_AM_Option)])])
@@ -825,12 +842,14 @@
 fi
 AC_MSG_RESULT(yes)])
 
-# Copyright (C) 2001, 2003, 2005  Free Software Foundation, Inc.
+# Copyright (C) 2001, 2003, 2005, 2011 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
 # with or without modifications, as long as this notice is preserved.
 
+# serial 1
+
 # AM_PROG_INSTALL_STRIP
 # ---------------------
 # One issue with vendor `install' (even GNU) is that you can't
@@ -853,13 +872,13 @@
 INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s"
 AC_SUBST([INSTALL_STRIP_PROGRAM])])
 
-# Copyright (C) 2006, 2008  Free Software Foundation, Inc.
+# Copyright (C) 2006, 2008, 2010 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
 # with or without modifications, as long as this notice is preserved.
 
-# serial 2
+# serial 3
 
 # _AM_SUBST_NOTMAKE(VARIABLE)
 # ---------------------------
@@ -868,13 +887,13 @@
 AC_DEFUN([_AM_SUBST_NOTMAKE])
 
 # AM_SUBST_NOTMAKE(VARIABLE)
-# ---------------------------
+# --------------------------
 # Public sister of _AM_SUBST_NOTMAKE.
 AC_DEFUN([AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE($@)])
 
 # Check how to create a tarball.                            -*- Autoconf -*-
 
-# Copyright (C) 2004, 2005  Free Software Foundation, Inc.
+# Copyright (C) 2004, 2005, 2012 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -896,10 +915,11 @@
 # a tarball read from stdin.
 #     $(am__untar) < result.tar
 AC_DEFUN([_AM_PROG_TAR],
-[# Always define AMTAR for backward compatibility.
-AM_MISSING_PROG([AMTAR], [tar])
+[# Always define AMTAR for backward compatibility.  Yes, it's still used
+# in the wild :-(  We should find a proper way to deprecate it ...
+AC_SUBST([AMTAR], ['$${TAR-tar}'])
 m4_if([$1], [v7],
-     [am__tar='${AMTAR} chof - "$$tardir"'; am__untar='${AMTAR} xf -'],
+     [am__tar='$${TAR-tar} chof - "$$tardir"' am__untar='$${TAR-tar} xf -'],
      [m4_case([$1], [ustar],, [pax],,
               [m4_fatal([Unknown tar format])])
 AC_MSG_CHECKING([how to create a $1 tar archive])
diff --git a/third_party/gofrontend/libgo/config.h.in b/third_party/gofrontend/libgo/config.h.in
index 629c603..298b8d6 100644
--- a/third_party/gofrontend/libgo/config.h.in
+++ b/third_party/gofrontend/libgo/config.h.in
@@ -337,9 +337,6 @@
 /* Define to 1 if you have the `wait4' function. */
 #undef HAVE_WAIT4
 
-/* Define if the C++ compiler is configured for setjmp/longjmp exceptions. */
-#undef LIBGO_SJLJ_EXCEPTIONS
-
 /* Define if the linker support split stack adjustments */
 #undef LINKER_SUPPORTS_SPLIT_STACK
 
diff --git a/third_party/gofrontend/libgo/configure b/third_party/gofrontend/libgo/configure
index 377179d..e024b2f 100755
--- a/third_party/gofrontend/libgo/configure
+++ b/third_party/gofrontend/libgo/configure
@@ -602,6 +602,8 @@
 am__EXEEXT_TRUE
 LTLIBOBJS
 LIBOBJS
+HAVE_STAT_TIMESPEC_FALSE
+HAVE_STAT_TIMESPEC_TRUE
 STRUCT_EPOLL_EVENT_FD_OFFSET
 SIZEOF_STRUCT_EPOLL_EVENT
 MATH_FLAG
@@ -618,6 +620,7 @@
 MATH_LIBS
 GOC_IS_LLGO_FALSE
 GOC_IS_LLGO_TRUE
+GO_SPLIT_STACK
 USING_SPLIT_STACK_FALSE
 USING_SPLIT_STACK_TRUE
 SPLIT_STACK
@@ -723,6 +726,7 @@
 am__fastdepCC_FALSE
 am__fastdepCC_TRUE
 CCDEPMODE
+am__nodep
 AMDEPBACKSLASH
 AMDEP_FALSE
 AMDEP_TRUE
@@ -828,7 +832,6 @@
 with_libffi
 with_libatomic
 with_system_libunwind
-enable_sjlj_exceptions
 '
       ac_precious_vars='build_alias
 host_alias
@@ -1469,8 +1472,6 @@
   --enable-version-specific-runtime-libs
                           Specify that runtime libraries should be installed
                           in a compiler-specific directory
-  --enable-sjlj-exceptions
-                          force use of builtin_setjmp for exceptions
 
 Optional Packages:
   --with-PACKAGE[=ARG]    use PACKAGE [ARG=yes]
@@ -2511,7 +2512,7 @@
 ac_config_headers="$ac_config_headers config.h"
 
 
-libtool_VERSION=7:0:0
+libtool_VERSION=8:0:0
 
 
 # Default to --enable-multilib
@@ -3147,11 +3148,11 @@
 
 # We need awk for the "check" target.  The system "awk" is bad on
 # some platforms.
-# Always define AMTAR for backward compatibility.
+# Always define AMTAR for backward compatibility.  Yes, it's still used
+# in the wild :-(  We should find a proper way to deprecate it ...
+AMTAR='$${TAR-tar}'
 
-AMTAR=${AMTAR-"${am_missing_run}tar"}
-
-am__tar='${AMTAR} chof - "$$tardir"'; am__untar='${AMTAR} xf -'
+am__tar='$${TAR-tar} chof - "$$tardir"' am__untar='$${TAR-tar} xf -'
 
 
 
@@ -3978,6 +3979,7 @@
 if test "x$enable_dependency_tracking" != xno; then
   am_depcomp="$ac_aux_dir/depcomp"
   AMDEPBACKSLASH='\'
+  am__nodep='_no'
 fi
  if test "x$enable_dependency_tracking" != xno; then
   AMDEP_TRUE=
@@ -4002,6 +4004,7 @@
   # instance it was reported that on HP-UX the gcc test will end up
   # making a dummy file named `D' -- because `-MD' means `put the output
   # in D'.
+  rm -rf conftest.dir
   mkdir conftest.dir
   # Copy depcomp to subdir because otherwise we won't find it if we're
   # using a relative directory.
@@ -4061,7 +4064,7 @@
 	break
       fi
       ;;
-    msvisualcpp | msvcmsys)
+    msvc7 | msvc7msys | msvisualcpp | msvcmsys)
       # This compiler won't grok `-c -o', but also, the minuso test has
       # not run yet.  These depmodes are late enough in the game, and
       # so weak that their functioning should not be impacted.
@@ -11121,7 +11124,7 @@
   lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
   lt_status=$lt_dlunknown
   cat > conftest.$ac_ext <<_LT_EOF
-#line 11124 "configure"
+#line 11127 "configure"
 #include "confdefs.h"
 
 #if HAVE_DLFCN_H
@@ -11227,7 +11230,7 @@
   lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
   lt_status=$lt_dlunknown
   cat > conftest.$ac_ext <<_LT_EOF
-#line 11230 "configure"
+#line 11233 "configure"
 #include "confdefs.h"
 
 #if HAVE_DLFCN_H
@@ -14005,7 +14008,32 @@
 fi
 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $libgo_cv_c_split_stack_supported" >&5
 $as_echo "$libgo_cv_c_split_stack_supported" >&6; }
-if test "$libgo_cv_c_split_stack_supported" = yes; then
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether linker supports split/non-split linked together" >&5
+$as_echo_n "checking whether linker supports split/non-split linked together... " >&6; }
+if test "${libgo_cv_c_linker_split_non_split+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat > conftest1.c << EOF
+extern void f();
+int main() { f(); return 0; }
+EOF
+cat > conftest2.c << EOF
+void f() {}
+EOF
+$CC -c -fsplit-stack $CFLAGS $CPPFLAGS conftest1.c
+$CC -c $CFLAGS $CPPFLAGS conftest2.c
+if $CC -o conftest conftest1.$ac_objext conftest2.$ac_objext; then
+  libgo_cv_c_linker_split_non_split=yes
+else
+  libgo_cv_c_linker_split_non_split=no
+fi
+rm -f conftest1.* conftest2.* conftest
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $libgo_cv_c_linker_split_non_split" >&5
+$as_echo "$libgo_cv_c_linker_split_non_split" >&6; }
+
+if test "$libgo_cv_c_split_stack_supported" = yes -a "$libgo_cv_c_linker_split_non_split" = yes; then
   SPLIT_STACK=-fsplit-stack
 
 $as_echo "#define USING_SPLIT_STACK 1" >>confdefs.h
@@ -14014,7 +14042,7 @@
   SPLIT_STACK=
 fi
 
- if test "$libgo_cv_c_split_stack_supported" = yes; then
+ if test "$libgo_cv_c_split_stack_supported" = yes -a "$libgo_cv_c_linker_split_non_split" = yes; then
   USING_SPLIT_STACK_TRUE=
   USING_SPLIT_STACK_FALSE='#'
 else
@@ -14023,6 +14051,13 @@
 fi
 
 
+if test "$libgo_cv_c_split_stack_supported" = yes -a "$libgo_cv_c_linker_split_non_split" = no; then
+  GO_SPLIT_STACK=-fno-split-stack
+else
+  GO_SPLIT_STACK=
+fi
+
+
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether linker supports split stack" >&5
 $as_echo_n "checking whether linker supports split stack... " >&6; }
 if test "${libgo_cv_c_linker_supports_split_stack+set}" = set; then :
@@ -14214,6 +14249,46 @@
 fi
 
    unset ac_cv_func_gethostbyname
+   ac_fn_c_check_func "$LINENO" "sendfile" "ac_cv_func_sendfile"
+if test "x$ac_cv_func_sendfile" = x""yes; then :
+
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for main in -lsendfile" >&5
+$as_echo_n "checking for main in -lsendfile... " >&6; }
+if test "${ac_cv_lib_sendfile_main+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lsendfile  $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+
+int
+main ()
+{
+return main ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_lib_sendfile_main=yes
+else
+  ac_cv_lib_sendfile_main=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_sendfile_main" >&5
+$as_echo "$ac_cv_lib_sendfile_main" >&6; }
+if test "x$ac_cv_lib_sendfile_main" = x""yes; then :
+  libgo_cv_lib_sockets="$libgo_cv_lib_sockets -lsendfile"
+fi
+
+fi
+
    LIBS=$libgo_old_libs
 
 fi
@@ -14404,6 +14479,62 @@
 
 fi
 
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing clock_gettime" >&5
+$as_echo_n "checking for library containing clock_gettime... " >&6; }
+if test "${ac_cv_search_clock_gettime+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_func_search_save_LIBS=$LIBS
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char clock_gettime ();
+int
+main ()
+{
+return clock_gettime ();
+  ;
+  return 0;
+}
+_ACEOF
+for ac_lib in '' rt; do
+  if test -z "$ac_lib"; then
+    ac_res="none required"
+  else
+    ac_res=-l$ac_lib
+    LIBS="-l$ac_lib  $ac_func_search_save_LIBS"
+  fi
+  if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_search_clock_gettime=$ac_res
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext
+  if test "${ac_cv_search_clock_gettime+set}" = set; then :
+  break
+fi
+done
+if test "${ac_cv_search_clock_gettime+set}" = set; then :
+
+else
+  ac_cv_search_clock_gettime=no
+fi
+rm conftest.$ac_ext
+LIBS=$ac_func_search_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_clock_gettime" >&5
+$as_echo "$ac_cv_search_clock_gettime" >&6; }
+ac_res=$ac_cv_search_clock_gettime
+if test "$ac_res" != no; then :
+  test "$ac_res" = "none required" || LIBS="$ac_res $LIBS"
+
+fi
+
 
  { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether byte ordering is bigendian" >&5
 $as_echo_n "checking whether byte ordering is bigendian... " >&6; }
@@ -14667,68 +14798,6 @@
   fi
 
 
-# Check whether --enable-sjlj-exceptions was given.
-if test "${enable_sjlj_exceptions+set}" = set; then :
-  enableval=$enable_sjlj_exceptions; case "$enableval" in
-   yes|no|auto) ;;
-   *) as_fn_error "unknown argument to --enable-sjlj-exceptions" "$LINENO" 5 ;;
-   esac
-else
-  enable_sjlj_exceptions=auto
-fi
-
-
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to use setjmp/longjmp exceptions" >&5
-$as_echo_n "checking whether to use setjmp/longjmp exceptions... " >&6; }
-if test "${libgo_cv_lib_sjlj_exceptions+set}" = set; then :
-  $as_echo_n "(cached) " >&6
-else
-  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
-
-void bar ();
-void clean (int *);
-void foo ()
-{
-  int i __attribute__ ((cleanup (clean)));
-  bar();
-}
-
-_ACEOF
-CFLAGS_hold=$CFLAGS
-CFLAGS="--save-temps -fexceptions"
-libgo_cv_lib_sjlj_exceptions=unknown
-if ac_fn_c_try_compile; then :
-  if grep _Unwind_SjLj_Resume conftest.s >/dev/null 2>&1; then
-    libgo_cv_lib_sjlj_exceptions=yes
-  elif grep _Unwind_Resume conftest.s >/dev/null 2>&1; then
-    libgo_cv_lib_sjlj_exceptions=no
-  fi
-fi
-CFLAGS=$CFLAGS_hold
-rm -f conftest*
-
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $libgo_cv_lib_sjlj_exceptions" >&5
-$as_echo "$libgo_cv_lib_sjlj_exceptions" >&6; }
-
-if test "$enable_sjlj_exceptions" = "auto"; then
-  enable_sjlj_exceptions=$libgo_cv_lib_sjlj_exceptions
-fi
-
-case $enable_sjlj_exceptions in
-yes)
-
-$as_echo "#define LIBGO_SJLJ_EXCEPTIONS 1" >>confdefs.h
-
-  ;;
-no)
-  ;;
-*)
-  as_fn_error "unable to detect exception model" "$LINENO" 5
-  ;;
-esac
-
 for ac_header in sched.h sys/file.h sys/mman.h syscall.h sys/epoll.h sys/inotify.h sys/ptrace.h sys/syscall.h sys/user.h sys/utsname.h sys/select.h sys/socket.h net/if.h net/if_arp.h net/route.h netpacket/packet.h sys/prctl.h sys/mount.h sys/vfs.h sys/statfs.h sys/timex.h sys/sysinfo.h utime.h linux/ether.h linux/fs.h linux/reboot.h netinet/icmp6.h netinet/in_syst.h netinet/ip.h netinet/ip_mroute.h netinet/if_ether.h
 do :
   as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
@@ -15141,6 +15210,28 @@
 STRUCT_EPOLL_EVENT_FD_OFFSET=${libgo_cv_c_epoll_event_fd_offset}
 
 
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <sys/stat.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "timespec_t.*st_atim" >/dev/null 2>&1; then :
+  have_stat_timespec=yes
+else
+  have_stat_timespec=no
+fi
+rm -f conftest*
+
+ if test $have_stat_timespec = yes; then
+  HAVE_STAT_TIMESPEC_TRUE=
+  HAVE_STAT_TIMESPEC_FALSE='#'
+else
+  HAVE_STAT_TIMESPEC_TRUE='#'
+  HAVE_STAT_TIMESPEC_FALSE=
+fi
+
+
 ac_fn_c_check_type "$LINENO" "struct exception" "ac_cv_type_struct_exception" "#include <math.h>
 "
 if test "x$ac_cv_type_struct_exception" = x""yes; then :
@@ -15761,6 +15852,10 @@
   as_fn_error "conditional \"HAVE_WAIT4\" was never defined.
 Usually this means the macro was only invoked conditionally." "$LINENO" 5
 fi
+if test -z "${HAVE_STAT_TIMESPEC_TRUE}" && test -z "${HAVE_STAT_TIMESPEC_FALSE}"; then
+  as_fn_error "conditional \"HAVE_STAT_TIMESPEC\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
 
 : ${CONFIG_STATUS=./config.status}
 ac_write_fail=0
diff --git a/third_party/gofrontend/libgo/configure.ac b/third_party/gofrontend/libgo/configure.ac
index 0baff41..6eddb86 100644
--- a/third_party/gofrontend/libgo/configure.ac
+++ b/third_party/gofrontend/libgo/configure.ac
@@ -11,7 +11,7 @@
 AC_CONFIG_SRCDIR(Makefile.am)
 AC_CONFIG_HEADER(config.h)
 
-libtool_VERSION=7:0:0
+libtool_VERSION=8:0:0
 AC_SUBST(libtool_VERSION)
 
 AM_ENABLE_MULTILIB(, ..)
@@ -374,7 +374,29 @@
 [libgo_cv_c_split_stack_supported=yes],
 [libgo_cv_c_split_stack_supported=no])
 CFLAGS=$CFLAGS_hold])
-if test "$libgo_cv_c_split_stack_supported" = yes; then
+
+dnl Make sure the linker permits -fsplit-stack.  Old versions of gold will
+dnl reject split-stack code calling non-split-stack code on targets
+dnl they don't support.
+AC_CACHE_CHECK([whether linker supports split/non-split linked together],
+[libgo_cv_c_linker_split_non_split],
+[cat > conftest1.c << EOF
+extern void f();
+int main() { f(); return 0; }
+EOF
+cat > conftest2.c << EOF
+void f() {}
+EOF
+$CC -c -fsplit-stack $CFLAGS $CPPFLAGS conftest1.c
+$CC -c $CFLAGS $CPPFLAGS conftest2.c
+if $CC -o conftest conftest1.$ac_objext conftest2.$ac_objext; then
+  libgo_cv_c_linker_split_non_split=yes
+else
+  libgo_cv_c_linker_split_non_split=no
+fi
+rm -f conftest1.* conftest2.* conftest])
+
+if test "$libgo_cv_c_split_stack_supported" = yes -a "$libgo_cv_c_linker_split_non_split" = yes; then
   SPLIT_STACK=-fsplit-stack
   AC_DEFINE(USING_SPLIT_STACK, 1,
 		[Define if the compiler supports -fsplit-stack])
@@ -383,13 +405,24 @@
 fi
 AC_SUBST(SPLIT_STACK)
 AM_CONDITIONAL(USING_SPLIT_STACK,
-	test "$libgo_cv_c_split_stack_supported" = yes)
+	test "$libgo_cv_c_split_stack_supported" = yes -a "$libgo_cv_c_linker_split_non_split" = yes)
+
+dnl If the compiler supports split-stack but the linker does not, then
+dnl we need to explicitly disable split-stack for Go.
+if test "$libgo_cv_c_split_stack_supported" = yes -a "$libgo_cv_c_linker_split_non_split" = no; then
+  GO_SPLIT_STACK=-fno-split-stack
+else
+  GO_SPLIT_STACK=
+fi
+AC_SUBST(GO_SPLIT_STACK)
 
 dnl Check whether the linker does stack munging when calling from
 dnl split-stack into non-split-stack code.  We check this by looking
 dnl at the --help output.  FIXME: This is only half right: it's
 dnl possible for the linker to support this for some targets but not
 dnl others.
+dnl This is slightly different from the above check, which is whether
+dnl the linker permits the call at all.
 AC_CACHE_CHECK([whether linker supports split stack],
 [libgo_cv_c_linker_supports_split_stack],
 [libgo_cv_c_linker_supports_split_stack=no
@@ -440,6 +473,9 @@
 		 [AC_CHECK_LIB(nsl, main,
 		 	[libgo_cv_lib_sockets="$libgo_cv_lib_sockets -lnsl"])])
    unset ac_cv_func_gethostbyname
+   AC_CHECK_FUNC(sendfile, ,
+		 [AC_CHECK_LIB(sendfile, main,
+		 	[libgo_cv_lib_sockets="$libgo_cv_lib_sockets -lsendfile"])])
    LIBS=$libgo_old_libs
 ])
 NET_LIBS="$libgo_cv_lib_sockets"
@@ -465,64 +501,15 @@
 AC_CHECK_LIB([pthread], [pthread_create], PTHREAD_LIBS=-lpthread)
 AC_SUBST(PTHREAD_LIBS)
 
-dnl Test if -lrt is required for sched_yield and/or nanosleep.
+dnl Test if -lrt is required for sched_yield or nanosleep or clock_gettime.
 AC_SEARCH_LIBS([sched_yield], [rt])
 AC_SEARCH_LIBS([nanosleep], [rt])
+AC_SEARCH_LIBS([clock_gettime], [rt])
 
 AC_C_BIGENDIAN
 
 GCC_CHECK_UNWIND_GETIPINFO
 
-AC_ARG_ENABLE(sjlj-exceptions,
-  AC_HELP_STRING([--enable-sjlj-exceptions],
-		 [force use of builtin_setjmp for exceptions]),
-  [case "$enableval" in
-   yes|no|auto) ;;
-   *) AC_MSG_ERROR([unknown argument to --enable-sjlj-exceptions]) ;;
-   esac],
-  [enable_sjlj_exceptions=auto])
-
-AC_CACHE_CHECK([whether to use setjmp/longjmp exceptions],
-[libgo_cv_lib_sjlj_exceptions],
-[AC_LANG_CONFTEST(
-  [AC_LANG_SOURCE([
-void bar ();
-void clean (int *);
-void foo ()
-{
-  int i __attribute__ ((cleanup (clean)));
-  bar();
-}
-])])
-CFLAGS_hold=$CFLAGS
-CFLAGS="--save-temps -fexceptions"
-libgo_cv_lib_sjlj_exceptions=unknown
-AS_IF([ac_fn_c_try_compile],
-  [if grep _Unwind_SjLj_Resume conftest.s >/dev/null 2>&1; then
-    libgo_cv_lib_sjlj_exceptions=yes
-  elif grep _Unwind_Resume conftest.s >/dev/null 2>&1; then
-    libgo_cv_lib_sjlj_exceptions=no
-  fi])
-CFLAGS=$CFLAGS_hold
-rm -f conftest*
-])
-
-if test "$enable_sjlj_exceptions" = "auto"; then
-  enable_sjlj_exceptions=$libgo_cv_lib_sjlj_exceptions
-fi
-
-case $enable_sjlj_exceptions in
-yes)
-  AC_DEFINE(LIBGO_SJLJ_EXCEPTIONS, 1,
-	[Define if the C++ compiler is configured for setjmp/longjmp exceptions.])
-  ;;
-no)
-  ;;
-*)
-  AC_MSG_ERROR([unable to detect exception model])
-  ;;
-esac
-
 AC_CHECK_HEADERS(sched.h sys/file.h sys/mman.h syscall.h sys/epoll.h sys/inotify.h sys/ptrace.h sys/syscall.h sys/user.h sys/utsname.h sys/select.h sys/socket.h net/if.h net/if_arp.h net/route.h netpacket/packet.h sys/prctl.h sys/mount.h sys/vfs.h sys/statfs.h sys/timex.h sys/sysinfo.h utime.h linux/ether.h linux/fs.h linux/reboot.h netinet/icmp6.h netinet/in_syst.h netinet/ip.h netinet/ip_mroute.h netinet/if_ether.h)
 
 AC_CHECK_HEADERS([linux/filter.h linux/if_addr.h linux/if_ether.h linux/if_tun.h linux/netlink.h linux/rtnetlink.h], [], [],
@@ -695,6 +682,12 @@
 STRUCT_EPOLL_EVENT_FD_OFFSET=${libgo_cv_c_epoll_event_fd_offset}
 AC_SUBST(STRUCT_EPOLL_EVENT_FD_OFFSET)
 
+dnl Check if <sys/stat.h> uses timespec_t for st_?tim members.  Introduced
+dnl in Solaris 12 for XPG7 compatibility.
+AC_EGREP_HEADER([timespec_t.*st_atim], [sys/stat.h],
+		[have_stat_timespec=yes], [have_stat_timespec=no])
+AM_CONDITIONAL(HAVE_STAT_TIMESPEC, test $have_stat_timespec = yes)
+
 dnl See if struct exception is defined in <math.h>.
 AC_CHECK_TYPE([struct exception],
 [libgo_has_struct_exception=yes],
diff --git a/third_party/gofrontend/libgo/go/archive/tar/common.go b/third_party/gofrontend/libgo/go/archive/tar/common.go
index e363aa7..c31df06 100644
--- a/third_party/gofrontend/libgo/go/archive/tar/common.go
+++ b/third_party/gofrontend/libgo/go/archive/tar/common.go
@@ -139,8 +139,8 @@
 	}
 
 	switch fi.h.Typeflag {
-	case TypeLink, TypeSymlink:
-		// hard link, symbolic link
+	case TypeSymlink:
+		// symbolic link
 		mode |= os.ModeSymlink
 	case TypeChar:
 		// character device node
@@ -249,6 +249,30 @@
 	if fm&os.ModeSticky != 0 {
 		h.Mode |= c_ISVTX
 	}
+	// If possible, populate additional fields from OS-specific
+	// FileInfo fields.
+	if sys, ok := fi.Sys().(*Header); ok {
+		// This FileInfo came from a Header (not the OS). Use the
+		// original Header to populate all remaining fields.
+		h.Uid = sys.Uid
+		h.Gid = sys.Gid
+		h.Uname = sys.Uname
+		h.Gname = sys.Gname
+		h.AccessTime = sys.AccessTime
+		h.ChangeTime = sys.ChangeTime
+		if sys.Xattrs != nil {
+			h.Xattrs = make(map[string]string)
+			for k, v := range sys.Xattrs {
+				h.Xattrs[k] = v
+			}
+		}
+		if sys.Typeflag == TypeLink {
+			// hard link
+			h.Typeflag = TypeLink
+			h.Size = 0
+			h.Linkname = sys.Linkname
+		}
+	}
 	if sysStat != nil {
 		return h, sysStat(fi, h)
 	}
diff --git a/third_party/gofrontend/libgo/go/archive/tar/reader.go b/third_party/gofrontend/libgo/go/archive/tar/reader.go
index a27559d..67daca2 100644
--- a/third_party/gofrontend/libgo/go/archive/tar/reader.go
+++ b/third_party/gofrontend/libgo/go/archive/tar/reader.go
@@ -85,6 +85,8 @@
 func NewReader(r io.Reader) *Reader { return &Reader{r: r} }
 
 // Next advances to the next entry in the tar archive.
+//
+// io.EOF is returned at the end of the input.
 func (tr *Reader) Next() (*Header, error) {
 	var hdr *Header
 	if tr.err == nil {
@@ -108,7 +110,13 @@
 		// We actually read the whole file,
 		// but this skips alignment padding
 		tr.skipUnread()
+		if tr.err != nil {
+			return nil, tr.err
+		}
 		hdr = tr.readHeader()
+		if hdr == nil {
+			return nil, tr.err
+		}
 		mergePAX(hdr, headers)
 
 		// Check for a PAX format sparse file
@@ -331,7 +339,7 @@
 		}
 		// Parse the first token as a decimal integer.
 		n, err := strconv.ParseInt(string(buf[:sp]), 10, 0)
-		if err != nil {
+		if err != nil || n < 5 || int64(len(buf)) < n {
 			return nil, ErrHeader
 		}
 		// Extract everything between the decimal and the n -1 on the
@@ -461,6 +469,10 @@
 	hdr.Uid = int(tr.octal(s.next(8)))
 	hdr.Gid = int(tr.octal(s.next(8)))
 	hdr.Size = tr.octal(s.next(12))
+	if hdr.Size < 0 {
+		tr.err = ErrHeader
+		return nil
+	}
 	hdr.ModTime = time.Unix(tr.octal(s.next(12)), 0)
 	s.next(8) // chksum
 	hdr.Typeflag = s.next(1)[0]
@@ -785,6 +797,9 @@
 		// Otherwise, we're at the end of the file
 		return 0, io.EOF
 	}
+	if sfr.tot < sfr.sp[0].offset {
+		return 0, io.ErrUnexpectedEOF
+	}
 	if sfr.pos < sfr.sp[0].offset {
 		// We're in a hole
 		n = sfr.readHole(b, sfr.sp[0].offset)
diff --git a/third_party/gofrontend/libgo/go/archive/tar/reader_test.go b/third_party/gofrontend/libgo/go/archive/tar/reader_test.go
index 9601ffe..da01f26 100644
--- a/third_party/gofrontend/libgo/go/archive/tar/reader_test.go
+++ b/third_party/gofrontend/libgo/go/archive/tar/reader_test.go
@@ -462,9 +462,14 @@
 			t.Error("Buffer wasn't consumed")
 		}
 	}
-	badHeader := bytes.NewReader([]byte("3 somelongkey="))
-	if _, err := parsePAX(badHeader); err != ErrHeader {
-		t.Fatal("Unexpected success when parsing bad header")
+	badHeaderTests := [][]byte{
+		[]byte("3 somelongkey=\n"),
+		[]byte("50 tooshort=\n"),
+	}
+	for _, test := range badHeaderTests {
+		if _, err := parsePAX(bytes.NewReader(test)); err != ErrHeader {
+			t.Fatal("Unexpected success when parsing bad header")
+		}
 	}
 }
 
@@ -741,3 +746,53 @@
 	}
 
 }
+
+// Negative header size should not cause panic.
+// Issues 10959 and 10960.
+func TestNegativeHdrSize(t *testing.T) {
+	f, err := os.Open("testdata/neg-size.tar")
+	if err != nil {
+		t.Fatal(err)
+	}
+	defer f.Close()
+	r := NewReader(f)
+	_, err = r.Next()
+	if err != ErrHeader {
+		t.Error("want ErrHeader, got", err)
+	}
+	io.Copy(ioutil.Discard, r)
+}
+
+// This used to hang in (*sparseFileReader).readHole due to missing
+// verification of sparse offsets against file size.
+func TestIssue10968(t *testing.T) {
+	f, err := os.Open("testdata/issue10968.tar")
+	if err != nil {
+		t.Fatal(err)
+	}
+	defer f.Close()
+	r := NewReader(f)
+	_, err = r.Next()
+	if err != nil {
+		t.Fatal(err)
+	}
+	_, err = io.Copy(ioutil.Discard, r)
+	if err != io.ErrUnexpectedEOF {
+		t.Fatalf("expected %q, got %q", io.ErrUnexpectedEOF, err)
+	}
+}
+
+// Do not panic if there are errors in header blocks after the pax header.
+// Issue 11169
+func TestIssue11169(t *testing.T) {
+	f, err := os.Open("testdata/issue11169.tar")
+	if err != nil {
+		t.Fatal(err)
+	}
+	defer f.Close()
+	r := NewReader(f)
+	_, err = r.Next()
+	if err == nil {
+		t.Fatal("Unexpected success")
+	}
+}
diff --git a/third_party/gofrontend/libgo/go/archive/tar/tar_test.go b/third_party/gofrontend/libgo/go/archive/tar/tar_test.go
index ed333f3..d63c072 100644
--- a/third_party/gofrontend/libgo/go/archive/tar/tar_test.go
+++ b/third_party/gofrontend/libgo/go/archive/tar/tar_test.go
@@ -147,17 +147,6 @@
 			},
 			fm: 0644,
 		},
-		// hard link.
-		{
-			h: &Header{
-				Name:     "hard.txt",
-				Mode:     0644 | c_ISLNK,
-				Size:     0,
-				ModTime:  time.Unix(1360600916, 0),
-				Typeflag: TypeLink,
-			},
-			fm: 0644 | os.ModeSymlink,
-		},
 		// symbolic link.
 		{
 			h: &Header{
@@ -246,6 +235,33 @@
 			},
 			fm: 0600 | os.ModeSticky,
 		},
+		// hard link.
+		{
+			h: &Header{
+				Name:     "hard.txt",
+				Mode:     0644 | c_ISREG,
+				Size:     0,
+				Linkname: "file.txt",
+				ModTime:  time.Unix(1360600916, 0),
+				Typeflag: TypeLink,
+			},
+			fm: 0644,
+		},
+		// More information.
+		{
+			h: &Header{
+				Name:     "info.txt",
+				Mode:     0600 | c_ISREG,
+				Size:     0,
+				Uid:      1000,
+				Gid:      1000,
+				ModTime:  time.Unix(1360602540, 0),
+				Uname:    "slartibartfast",
+				Gname:    "users",
+				Typeflag: TypeReg,
+			},
+			fm: 0600,
+		},
 	}
 
 	for i, g := range golden {
@@ -268,12 +284,37 @@
 		if got, want := h2.Size, g.h.Size; got != want {
 			t.Errorf("i=%d: Size: got %v, want %v", i, got, want)
 		}
+		if got, want := h2.Uid, g.h.Uid; got != want {
+			t.Errorf("i=%d: Uid: got %d, want %d", i, got, want)
+		}
+		if got, want := h2.Gid, g.h.Gid; got != want {
+			t.Errorf("i=%d: Gid: got %d, want %d", i, got, want)
+		}
+		if got, want := h2.Uname, g.h.Uname; got != want {
+			t.Errorf("i=%d: Uname: got %q, want %q", i, got, want)
+		}
+		if got, want := h2.Gname, g.h.Gname; got != want {
+			t.Errorf("i=%d: Gname: got %q, want %q", i, got, want)
+		}
+		if got, want := h2.Linkname, g.h.Linkname; got != want {
+			t.Errorf("i=%d: Linkname: got %v, want %v", i, got, want)
+		}
+		if got, want := h2.Typeflag, g.h.Typeflag; got != want {
+			t.Logf("%#v %#v", g.h, fi.Sys())
+			t.Errorf("i=%d: Typeflag: got %q, want %q", i, got, want)
+		}
 		if got, want := h2.Mode, g.h.Mode; got != want {
 			t.Errorf("i=%d: Mode: got %o, want %o", i, got, want)
 		}
 		if got, want := fi.Mode(), g.fm; got != want {
 			t.Errorf("i=%d: fi.Mode: got %o, want %o", i, got, want)
 		}
+		if got, want := h2.AccessTime, g.h.AccessTime; got != want {
+			t.Errorf("i=%d: AccessTime: got %v, want %v", i, got, want)
+		}
+		if got, want := h2.ChangeTime, g.h.ChangeTime; got != want {
+			t.Errorf("i=%d: ChangeTime: got %v, want %v", i, got, want)
+		}
 		if got, want := h2.ModTime, g.h.ModTime; got != want {
 			t.Errorf("i=%d: ModTime: got %v, want %v", i, got, want)
 		}
diff --git a/third_party/gofrontend/libgo/go/archive/tar/testdata/hardlink.tar b/third_party/gofrontend/libgo/go/archive/tar/testdata/hardlink.tar
new file mode 100644
index 0000000..9cd1a26
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/archive/tar/testdata/hardlink.tar
Binary files differ
diff --git a/third_party/gofrontend/libgo/go/archive/tar/testdata/issue10968.tar b/third_party/gofrontend/libgo/go/archive/tar/testdata/issue10968.tar
new file mode 100644
index 0000000..1cc837b
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/archive/tar/testdata/issue10968.tar
Binary files differ
diff --git a/third_party/gofrontend/libgo/go/archive/tar/testdata/issue11169.tar b/third_party/gofrontend/libgo/go/archive/tar/testdata/issue11169.tar
new file mode 100644
index 0000000..4d71fa1
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/archive/tar/testdata/issue11169.tar
Binary files differ
diff --git a/third_party/gofrontend/libgo/go/archive/tar/testdata/neg-size.tar b/third_party/gofrontend/libgo/go/archive/tar/testdata/neg-size.tar
new file mode 100644
index 0000000..5deea3d
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/archive/tar/testdata/neg-size.tar
Binary files differ
diff --git a/third_party/gofrontend/libgo/go/archive/tar/writer.go b/third_party/gofrontend/libgo/go/archive/tar/writer.go
index dafb2ca..9dbc01a 100644
--- a/third_party/gofrontend/libgo/go/archive/tar/writer.go
+++ b/third_party/gofrontend/libgo/go/archive/tar/writer.go
@@ -355,7 +355,7 @@
 // hdr.Size bytes are written after WriteHeader.
 func (tw *Writer) Write(b []byte) (n int, err error) {
 	if tw.closed {
-		err = ErrWriteTooLong
+		err = ErrWriteAfterClose
 		return
 	}
 	overwrite := false
diff --git a/third_party/gofrontend/libgo/go/archive/tar/writer_test.go b/third_party/gofrontend/libgo/go/archive/tar/writer_test.go
index 5e42e32..fe46a67 100644
--- a/third_party/gofrontend/libgo/go/archive/tar/writer_test.go
+++ b/third_party/gofrontend/libgo/go/archive/tar/writer_test.go
@@ -147,6 +147,44 @@
 			},
 		},
 	},
+	// This file was produced using gnu tar 1.26
+	// echo "Slartibartfast" > file.txt
+	// ln file.txt hard.txt
+	// tar -b 1 --format=ustar -c -f hardlink.tar file.txt hard.txt
+	{
+		file: "testdata/hardlink.tar",
+		entries: []*writerTestEntry{
+			{
+				header: &Header{
+					Name:     "file.txt",
+					Mode:     0644,
+					Uid:      1000,
+					Gid:      100,
+					Size:     15,
+					ModTime:  time.Unix(1425484303, 0),
+					Typeflag: '0',
+					Uname:    "vbatts",
+					Gname:    "users",
+				},
+				contents: "Slartibartfast\n",
+			},
+			{
+				header: &Header{
+					Name:     "hard.txt",
+					Mode:     0644,
+					Uid:      1000,
+					Gid:      100,
+					Size:     0,
+					ModTime:  time.Unix(1425484303, 0),
+					Typeflag: '1',
+					Linkname: "file.txt",
+					Uname:    "vbatts",
+					Gname:    "users",
+				},
+				// no contents
+			},
+		},
+	},
 }
 
 // Render byte array in a two-character hexadecimal string, spaced for easy visual inspection.
@@ -489,3 +527,20 @@
 		}
 	}
 }
+
+func TestWriteAfterClose(t *testing.T) {
+	var buffer bytes.Buffer
+	tw := NewWriter(&buffer)
+
+	hdr := &Header{
+		Name: "small.txt",
+		Size: 5,
+	}
+	if err := tw.WriteHeader(hdr); err != nil {
+		t.Fatalf("Failed to write header: %s", err)
+	}
+	tw.Close()
+	if _, err := tw.Write([]byte("Kilts")); err != ErrWriteAfterClose {
+		t.Fatalf("Write: got %v; want ErrWriteAfterClose", err)
+	}
+}
diff --git a/third_party/gofrontend/libgo/go/archive/zip/reader.go b/third_party/gofrontend/libgo/go/archive/zip/reader.go
index 8136b84..519748b 100644
--- a/third_party/gofrontend/libgo/go/archive/zip/reader.go
+++ b/third_party/gofrontend/libgo/go/archive/zip/reader.go
@@ -8,6 +8,7 @@
 	"bufio"
 	"encoding/binary"
 	"errors"
+	"fmt"
 	"hash"
 	"hash/crc32"
 	"io"
@@ -77,6 +78,9 @@
 	if err != nil {
 		return err
 	}
+	if end.directoryRecords > uint64(size)/fileHeaderLen {
+		return fmt.Errorf("archive/zip: TOC declares impossible %d files in %d byte zip", end.directoryRecords, size)
+	}
 	z.r = r
 	z.File = make([]*File, 0, end.directoryRecords)
 	z.Comment = end.comment
@@ -146,16 +150,22 @@
 	if f.hasDataDescriptor() {
 		desr = io.NewSectionReader(f.zipr, f.headerOffset+bodyOffset+size, dataDescriptorLen)
 	}
-	rc = &checksumReader{rc, crc32.NewIEEE(), f, desr, nil}
+	rc = &checksumReader{
+		rc:   rc,
+		hash: crc32.NewIEEE(),
+		f:    f,
+		desr: desr,
+	}
 	return
 }
 
 type checksumReader struct {
-	rc   io.ReadCloser
-	hash hash.Hash32
-	f    *File
-	desr io.Reader // if non-nil, where to read the data descriptor
-	err  error     // sticky error
+	rc    io.ReadCloser
+	hash  hash.Hash32
+	nread uint64 // number of bytes read so far
+	f     *File
+	desr  io.Reader // if non-nil, where to read the data descriptor
+	err   error     // sticky error
 }
 
 func (r *checksumReader) Read(b []byte) (n int, err error) {
@@ -164,13 +174,21 @@
 	}
 	n, err = r.rc.Read(b)
 	r.hash.Write(b[:n])
+	r.nread += uint64(n)
 	if err == nil {
 		return
 	}
 	if err == io.EOF {
+		if r.nread != r.f.UncompressedSize64 {
+			return 0, io.ErrUnexpectedEOF
+		}
 		if r.desr != nil {
 			if err1 := readDataDescriptor(r.desr, r.f); err1 != nil {
-				err = err1
+				if err1 == io.EOF {
+					err = io.ErrUnexpectedEOF
+				} else {
+					err = err1
+				}
 			} else if r.hash.Sum32() != r.f.CRC32 {
 				err = ErrChecksum
 			}
diff --git a/third_party/gofrontend/libgo/go/archive/zip/reader_test.go b/third_party/gofrontend/libgo/go/archive/zip/reader_test.go
index 29d0652..547dd39 100644
--- a/third_party/gofrontend/libgo/go/archive/zip/reader_test.go
+++ b/third_party/gofrontend/libgo/go/archive/zip/reader_test.go
@@ -531,3 +531,77 @@
 		}
 	}
 }
+
+// Verify we return ErrUnexpectedEOF when length is short.
+func TestIssue10957(t *testing.T) {
+	data := []byte("PK\x03\x040000000PK\x01\x0200000" +
+		"0000000000000000000\x00" +
+		"\x00\x00\x00\x00\x00000000000000PK\x01" +
+		"\x020000000000000000000" +
+		"00000\v\x00\x00\x00\x00\x00000000000" +
+		"00000000000000PK\x01\x0200" +
+		"00000000000000000000" +
+		"00\v\x00\x00\x00\x00\x00000000000000" +
+		"00000000000PK\x01\x020000<" +
+		"0\x00\x0000000000000000\v\x00\v" +
+		"\x00\x00\x00\x00\x0000000000\x00\x00\x00\x00000" +
+		"00000000PK\x01\x0200000000" +
+		"0000000000000000\v\x00\x00\x00" +
+		"\x00\x0000PK\x05\x06000000\x05\x000000" +
+		"\v\x00\x00\x00\x00\x00")
+	z, err := NewReader(bytes.NewReader(data), int64(len(data)))
+	if err != nil {
+		t.Fatal(err)
+	}
+	for i, f := range z.File {
+		r, err := f.Open()
+		if err != nil {
+			continue
+		}
+		if f.UncompressedSize64 < 1e6 {
+			n, err := io.Copy(ioutil.Discard, r)
+			if i == 3 && err != io.ErrUnexpectedEOF {
+				t.Errorf("File[3] error = %v; want io.ErrUnexpectedEOF", err)
+			}
+			if err == nil && uint64(n) != f.UncompressedSize64 {
+				t.Errorf("file %d: bad size: copied=%d; want=%d", i, n, f.UncompressedSize64)
+			}
+		}
+		r.Close()
+	}
+}
+
+// Verify the number of files is sane.
+func TestIssue10956(t *testing.T) {
+	data := []byte("PK\x06\x06PK\x06\a0000\x00\x00\x00\x00\x00\x00\x00\x00" +
+		"0000PK\x05\x06000000000000" +
+		"0000\v\x00000\x00\x00\x00\x00\x00\x00\x000")
+	_, err := NewReader(bytes.NewReader(data), int64(len(data)))
+	const want = "TOC declares impossible 3472328296227680304 files in 57 byte"
+	if err == nil && !strings.Contains(err.Error(), want) {
+		t.Errorf("error = %v; want %q", err, want)
+	}
+}
+
+// Verify we return ErrUnexpectedEOF when reading truncated data descriptor.
+func TestIssue11146(t *testing.T) {
+	data := []byte("PK\x03\x040000000000000000" +
+		"000000\x01\x00\x00\x000\x01\x00\x00\xff\xff0000" +
+		"0000000000000000PK\x01\x02" +
+		"0000\b0\b\x00000000000000" +
+		"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x000000PK\x05\x06\x00\x00" +
+		"\x00\x0000\x01\x0000008\x00\x00\x00\x00\x00")
+	z, err := NewReader(bytes.NewReader(data), int64(len(data)))
+	if err != nil {
+		t.Fatal(err)
+	}
+	r, err := z.File[0].Open()
+	if err != nil {
+		t.Fatal(err)
+	}
+	_, err = ioutil.ReadAll(r)
+	if err != io.ErrUnexpectedEOF {
+		t.Errorf("File[0] error = %v; want io.ErrUnexpectedEOF", err)
+	}
+	r.Close()
+}
diff --git a/third_party/gofrontend/libgo/go/archive/zip/struct.go b/third_party/gofrontend/libgo/go/archive/zip/struct.go
index cb28e83..137d049 100644
--- a/third_party/gofrontend/libgo/go/archive/zip/struct.go
+++ b/third_party/gofrontend/libgo/go/archive/zip/struct.go
@@ -81,8 +81,8 @@
 	ModifiedTime       uint16 // MS-DOS time
 	ModifiedDate       uint16 // MS-DOS date
 	CRC32              uint32
-	CompressedSize     uint32 // deprecated; use CompressedSize64
-	UncompressedSize   uint32 // deprecated; use UncompressedSize64
+	CompressedSize     uint32 // Deprecated: Use CompressedSize64 instead.
+	UncompressedSize   uint32 // Deprecated: Use UncompressedSize64 instead.
 	CompressedSize64   uint64
 	UncompressedSize64 uint64
 	Extra              []byte
@@ -233,7 +233,7 @@
 	}
 }
 
-// isZip64 returns true if the file size exceeds the 32 bit limit
+// isZip64 reports whether the file size exceeds the 32 bit limit
 func (fh *FileHeader) isZip64() bool {
 	return fh.CompressedSize64 > uint32max || fh.UncompressedSize64 > uint32max
 }
diff --git a/third_party/gofrontend/libgo/go/archive/zip/testdata/readme.notzip b/third_party/gofrontend/libgo/go/archive/zip/testdata/readme.notzip
index 06668c4..8173727 100644
--- a/third_party/gofrontend/libgo/go/archive/zip/testdata/readme.notzip
+++ b/third_party/gofrontend/libgo/go/archive/zip/testdata/readme.notzip
Binary files differ
diff --git a/third_party/gofrontend/libgo/go/archive/zip/testdata/readme.zip b/third_party/gofrontend/libgo/go/archive/zip/testdata/readme.zip
index db3bb90..5642a67 100644
--- a/third_party/gofrontend/libgo/go/archive/zip/testdata/readme.zip
+++ b/third_party/gofrontend/libgo/go/archive/zip/testdata/readme.zip
Binary files differ
diff --git a/third_party/gofrontend/libgo/go/archive/zip/writer.go b/third_party/gofrontend/libgo/go/archive/zip/writer.go
index 170beec..3be2b5f 100644
--- a/third_party/gofrontend/libgo/go/archive/zip/writer.go
+++ b/third_party/gofrontend/libgo/go/archive/zip/writer.go
@@ -34,6 +34,17 @@
 	return &Writer{cw: &countWriter{w: bufio.NewWriter(w)}}
 }
 
+// SetOffset sets the offset of the beginning of the zip data within the
+// underlying writer. It should be used when the zip data is appended to an
+// existing file, such as a binary executable.
+// It must be called before any data is written.
+func (w *Writer) SetOffset(n int64) {
+	if w.cw.count != 0 {
+		panic("zip: SetOffset called after data was written")
+	}
+	w.cw.count = n
+}
+
 // Flush flushes any buffered data to the underlying writer.
 // Calling Flush is not normally necessary; calling Close is sufficient.
 func (w *Writer) Flush() error {
@@ -122,15 +133,15 @@
 
 		// zip64 end of central directory record
 		b.uint32(directory64EndSignature)
-		b.uint64(directory64EndLen)
-		b.uint16(zipVersion45) // version made by
-		b.uint16(zipVersion45) // version needed to extract
-		b.uint32(0)            // number of this disk
-		b.uint32(0)            // number of the disk with the start of the central directory
-		b.uint64(records)      // total number of entries in the central directory on this disk
-		b.uint64(records)      // total number of entries in the central directory
-		b.uint64(size)         // size of the central directory
-		b.uint64(offset)       // offset of start of central directory with respect to the starting disk number
+		b.uint64(directory64EndLen - 12) // length minus signature (uint32) and length fields (uint64)
+		b.uint16(zipVersion45)           // version made by
+		b.uint16(zipVersion45)           // version needed to extract
+		b.uint32(0)                      // number of this disk
+		b.uint32(0)                      // number of the disk with the start of the central directory
+		b.uint64(records)                // total number of entries in the central directory on this disk
+		b.uint64(records)                // total number of entries in the central directory
+		b.uint64(size)                   // size of the central directory
+		b.uint64(offset)                 // offset of start of central directory with respect to the starting disk number
 
 		// zip64 end of central directory locator
 		b.uint32(directory64LocSignature)
@@ -184,14 +195,20 @@
 // CreateHeader adds a file to the zip file using the provided FileHeader
 // for the file metadata.
 // It returns a Writer to which the file contents should be written.
+//
 // The file's contents must be written to the io.Writer before the next
-// call to Create, CreateHeader, or Close.
+// call to Create, CreateHeader, or Close. The provided FileHeader fh
+// must not be modified after a call to CreateHeader.
 func (w *Writer) CreateHeader(fh *FileHeader) (io.Writer, error) {
 	if w.last != nil && !w.last.closed {
 		if err := w.last.close(); err != nil {
 			return nil, err
 		}
 	}
+	if len(w.dir) > 0 && w.dir[len(w.dir)-1].FileHeader == fh {
+		// See https://golang.org/issue/11144 confusion.
+		return nil, errors.New("archive/zip: invalid duplicate FileHeader")
+	}
 
 	fh.Flags |= 0x8 // we will write a data descriptor
 
diff --git a/third_party/gofrontend/libgo/go/archive/zip/writer_test.go b/third_party/gofrontend/libgo/go/archive/zip/writer_test.go
index 184a7d9..01b63f2 100644
--- a/third_party/gofrontend/libgo/go/archive/zip/writer_test.go
+++ b/third_party/gofrontend/libgo/go/archive/zip/writer_test.go
@@ -87,6 +87,41 @@
 	}
 }
 
+func TestWriterOffset(t *testing.T) {
+	largeData := make([]byte, 1<<17)
+	for i := range largeData {
+		largeData[i] = byte(rand.Int())
+	}
+	writeTests[1].Data = largeData
+	defer func() {
+		writeTests[1].Data = nil
+	}()
+
+	// write a zip file
+	buf := new(bytes.Buffer)
+	existingData := []byte{1, 2, 3, 1, 2, 3, 1, 2, 3}
+	n, _ := buf.Write(existingData)
+	w := NewWriter(buf)
+	w.SetOffset(int64(n))
+
+	for _, wt := range writeTests {
+		testCreate(t, w, &wt)
+	}
+
+	if err := w.Close(); err != nil {
+		t.Fatal(err)
+	}
+
+	// read it back
+	r, err := NewReader(bytes.NewReader(buf.Bytes()), int64(buf.Len()))
+	if err != nil {
+		t.Fatal(err)
+	}
+	for i, wt := range writeTests {
+		testReadFile(t, r.File[i], &wt)
+	}
+}
+
 func TestWriterFlush(t *testing.T) {
 	var buf bytes.Buffer
 	w := NewWriter(struct{ io.Writer }{&buf})
diff --git a/third_party/gofrontend/libgo/go/archive/zip/zip_test.go b/third_party/gofrontend/libgo/go/archive/zip/zip_test.go
index 32a16a7..f00ff47 100644
--- a/third_party/gofrontend/libgo/go/archive/zip/zip_test.go
+++ b/third_party/gofrontend/libgo/go/archive/zip/zip_test.go
@@ -229,10 +229,11 @@
 		t.Skip("slow test; skipping")
 	}
 	const size = 1 << 32 // before the "END\n" part
-	testZip64(t, size)
+	buf := testZip64(t, size)
+	testZip64DirectoryRecordLength(buf, t)
 }
 
-func testZip64(t testing.TB, size int64) {
+func testZip64(t testing.TB, size int64) *rleBuffer {
 	const chunkSize = 1024
 	chunks := int(size / chunkSize)
 	// write 2^32 bytes plus "END\n" to a zip file
@@ -302,6 +303,37 @@
 	if got, want := f0.UncompressedSize64, uint64(size)+uint64(len(end)); got != want {
 		t.Errorf("UncompressedSize64 %d, want %d", got, want)
 	}
+
+	return buf
+}
+
+// Issue 9857
+func testZip64DirectoryRecordLength(buf *rleBuffer, t *testing.T) {
+	d := make([]byte, 1024)
+	if _, err := buf.ReadAt(d, buf.Size()-int64(len(d))); err != nil {
+		t.Fatal("read:", err)
+	}
+
+	sigOff := findSignatureInBlock(d)
+	dirOff, err := findDirectory64End(buf, buf.Size()-int64(len(d))+int64(sigOff))
+	if err != nil {
+		t.Fatal("findDirectory64End:", err)
+	}
+
+	d = make([]byte, directory64EndLen)
+	if _, err := buf.ReadAt(d, dirOff); err != nil {
+		t.Fatal("read:", err)
+	}
+
+	b := readBuf(d)
+	if sig := b.uint32(); sig != directory64EndSignature {
+		t.Fatalf("Expected directory64EndSignature (%d), got %d", directory64EndSignature, sig)
+	}
+
+	size := b.uint64()
+	if size != directory64EndLen-12 {
+		t.Fatalf("Expected length of %d, got %d", directory64EndLen-12, size)
+	}
 }
 
 func testInvalidHeader(h *FileHeader, t *testing.T) {
diff --git a/third_party/gofrontend/libgo/go/bufio/bufio.go b/third_party/gofrontend/libgo/go/bufio/bufio.go
index d3c68fe..3bbb933 100644
--- a/third_party/gofrontend/libgo/go/bufio/bufio.go
+++ b/third_party/gofrontend/libgo/go/bufio/bufio.go
@@ -144,6 +144,39 @@
 	return b.buf[b.r : b.r+n], err
 }
 
+// Discard skips the next n bytes, returning the number of bytes discarded.
+//
+// If Discard skips fewer than n bytes, it also returns an error.
+// If 0 <= n <= b.Buffered(), Discard is guaranteed to succeed without
+// reading from the underlying io.Reader.
+func (b *Reader) Discard(n int) (discarded int, err error) {
+	if n < 0 {
+		return 0, ErrNegativeCount
+	}
+	if n == 0 {
+		return
+	}
+	remain := n
+	for {
+		skip := b.Buffered()
+		if skip == 0 {
+			b.fill()
+			skip = b.Buffered()
+		}
+		if skip > remain {
+			skip = remain
+		}
+		b.r += skip
+		remain -= skip
+		if remain == 0 {
+			return n, nil
+		}
+		if b.err != nil {
+			return n - remain, b.readErr()
+		}
+	}
+}
+
 // Read reads data into p.
 // It returns the number of bytes read into p.
 // It calls Read at most once on the underlying Reader,
@@ -367,7 +400,6 @@
 	// accumulating full buffers.
 	var frag []byte
 	var full [][]byte
-	err = nil
 
 	for {
 		var e error
diff --git a/third_party/gofrontend/libgo/go/bufio/bufio_test.go b/third_party/gofrontend/libgo/go/bufio/bufio_test.go
index 550dac9..666c44e 100644
--- a/third_party/gofrontend/libgo/go/bufio/bufio_test.go
+++ b/third_party/gofrontend/libgo/go/bufio/bufio_test.go
@@ -1268,6 +1268,135 @@
 	}
 }
 
+func TestReaderDiscard(t *testing.T) {
+	tests := []struct {
+		name     string
+		r        io.Reader
+		bufSize  int // 0 means 16
+		peekSize int
+
+		n int // input to Discard
+
+		want    int   // from Discard
+		wantErr error // from Discard
+
+		wantBuffered int
+	}{
+		{
+			name:         "normal case",
+			r:            strings.NewReader("abcdefghijklmnopqrstuvwxyz"),
+			peekSize:     16,
+			n:            6,
+			want:         6,
+			wantBuffered: 10,
+		},
+		{
+			name:         "discard causing read",
+			r:            strings.NewReader("abcdefghijklmnopqrstuvwxyz"),
+			n:            6,
+			want:         6,
+			wantBuffered: 10,
+		},
+		{
+			name:         "discard all without peek",
+			r:            strings.NewReader("abcdefghijklmnopqrstuvwxyz"),
+			n:            26,
+			want:         26,
+			wantBuffered: 0,
+		},
+		{
+			name:         "discard more than end",
+			r:            strings.NewReader("abcdefghijklmnopqrstuvwxyz"),
+			n:            27,
+			want:         26,
+			wantErr:      io.EOF,
+			wantBuffered: 0,
+		},
+		// Any error from filling shouldn't show up until we
+		// get past the valid bytes. Here we return we return 5 valid bytes at the same time
+		// as an error, but test that we don't see the error from Discard.
+		{
+			name: "fill error, discard less",
+			r: newScriptedReader(func(p []byte) (n int, err error) {
+				if len(p) < 5 {
+					panic("unexpected small read")
+				}
+				return 5, errors.New("5-then-error")
+			}),
+			n:            4,
+			want:         4,
+			wantErr:      nil,
+			wantBuffered: 1,
+		},
+		{
+			name: "fill error, discard equal",
+			r: newScriptedReader(func(p []byte) (n int, err error) {
+				if len(p) < 5 {
+					panic("unexpected small read")
+				}
+				return 5, errors.New("5-then-error")
+			}),
+			n:            5,
+			want:         5,
+			wantErr:      nil,
+			wantBuffered: 0,
+		},
+		{
+			name: "fill error, discard more",
+			r: newScriptedReader(func(p []byte) (n int, err error) {
+				if len(p) < 5 {
+					panic("unexpected small read")
+				}
+				return 5, errors.New("5-then-error")
+			}),
+			n:            6,
+			want:         5,
+			wantErr:      errors.New("5-then-error"),
+			wantBuffered: 0,
+		},
+		// Discard of 0 shouldn't cause a read:
+		{
+			name:         "discard zero",
+			r:            newScriptedReader(), // will panic on Read
+			n:            0,
+			want:         0,
+			wantErr:      nil,
+			wantBuffered: 0,
+		},
+		{
+			name:         "discard negative",
+			r:            newScriptedReader(), // will panic on Read
+			n:            -1,
+			want:         0,
+			wantErr:      ErrNegativeCount,
+			wantBuffered: 0,
+		},
+	}
+	for _, tt := range tests {
+		br := NewReaderSize(tt.r, tt.bufSize)
+		if tt.peekSize > 0 {
+			peekBuf, err := br.Peek(tt.peekSize)
+			if err != nil {
+				t.Errorf("%s: Peek(%d): %v", tt.name, tt.peekSize, err)
+				continue
+			}
+			if len(peekBuf) != tt.peekSize {
+				t.Errorf("%s: len(Peek(%d)) = %v; want %v", tt.name, tt.peekSize, len(peekBuf), tt.peekSize)
+				continue
+			}
+		}
+		discarded, err := br.Discard(tt.n)
+		if ge, we := fmt.Sprint(err), fmt.Sprint(tt.wantErr); discarded != tt.want || ge != we {
+			t.Errorf("%s: Discard(%d) = (%v, %v); want (%v, %v)", tt.name, tt.n, discarded, ge, tt.want, we)
+			continue
+		}
+		if bn := br.Buffered(); bn != tt.wantBuffered {
+			t.Errorf("%s: after Discard, Buffered = %d; want %d", tt.name, bn, tt.wantBuffered)
+		}
+	}
+
+}
+
 // An onlyReader only implements io.Reader, no matter what other methods the underlying implementation may have.
 type onlyReader struct {
 	io.Reader
@@ -1278,6 +1407,23 @@
 	io.Writer
 }
 
+// A scriptedReader is an io.Reader that executes its steps sequentially.
+type scriptedReader []func(p []byte) (n int, err error)
+
+func (sr *scriptedReader) Read(p []byte) (n int, err error) {
+	if len(*sr) == 0 {
+		panic("too many Read calls on scripted Reader. No steps remain.")
+	}
+	step := (*sr)[0]
+	*sr = (*sr)[1:]
+	return step(p)
+}
+
+func newScriptedReader(steps ...func(p []byte) (n int, err error)) io.Reader {
+	sr := scriptedReader(steps)
+	return &sr
+}
+
 func BenchmarkReaderCopyOptimal(b *testing.B) {
 	// Optimal case is where the underlying reader implements io.WriterTo
 	srcBuf := bytes.NewBuffer(make([]byte, 8192))
diff --git a/third_party/gofrontend/libgo/go/bufio/scan.go b/third_party/gofrontend/libgo/go/bufio/scan.go
index 364d159..7a349fa 100644
--- a/third_party/gofrontend/libgo/go/bufio/scan.go
+++ b/third_party/gofrontend/libgo/go/bufio/scan.go
@@ -109,7 +109,7 @@
 // After Scan returns false, the Err method will return any error that
 // occurred during scanning, except that if it was io.EOF, Err
 // will return nil.
-// Split panics if the split function returns 100 empty tokens without
+// Scan panics if the split function returns 100 empty tokens without
 // advancing the input. This is a common error mode for scanners.
 func (s *Scanner) Scan() bool {
 	// Loop until we have a token.
diff --git a/third_party/gofrontend/libgo/go/builtin/builtin.go b/third_party/gofrontend/libgo/go/builtin/builtin.go
index 51550a4..d63ad22 100644
--- a/third_party/gofrontend/libgo/go/builtin/builtin.go
+++ b/third_party/gofrontend/libgo/go/builtin/builtin.go
@@ -236,14 +236,14 @@
 // panicking.
 func recover() interface{}
 
-// The print built-in function formats its arguments in an implementation-
-// specific way and writes the result to standard error.
+// The print built-in function formats its arguments in an
+// implementation-specific way and writes the result to standard error.
 // Print is useful for bootstrapping and debugging; it is not guaranteed
 // to stay in the language.
 func print(args ...Type)
 
-// The println built-in function formats its arguments in an implementation-
-// specific way and writes the result to standard error.
+// The println built-in function formats its arguments in an
+// implementation-specific way and writes the result to standard error.
 // Spaces are always added between arguments and a newline is appended.
 // Println is useful for bootstrapping and debugging; it is not guaranteed
 // to stay in the language.
diff --git a/third_party/gofrontend/libgo/go/bytes/buffer.go b/third_party/gofrontend/libgo/go/bytes/buffer.go
index 46ca1d5..4db9386 100644
--- a/third_party/gofrontend/libgo/go/bytes/buffer.go
+++ b/third_party/gofrontend/libgo/go/bytes/buffer.go
@@ -56,6 +56,10 @@
 // b.Len() == len(b.Bytes()).
 func (b *Buffer) Len() int { return len(b.buf) - b.off }
 
+// Cap returns the capacity of the buffer's underlying byte slice, that is, the
+// total space allocated for the buffer's data.
+func (b *Buffer) Cap() int { return cap(b.buf) }
+
 // Truncate discards all but the first n unread bytes from the buffer.
 // It panics if n is negative or greater than the length of the buffer.
 func (b *Buffer) Truncate(n int) {
diff --git a/third_party/gofrontend/libgo/go/bytes/buffer_test.go b/third_party/gofrontend/libgo/go/bytes/buffer_test.go
index 75145b0..7de17ae 100644
--- a/third_party/gofrontend/libgo/go/bytes/buffer_test.go
+++ b/third_party/gofrontend/libgo/go/bytes/buffer_test.go
@@ -231,6 +231,23 @@
 	empty(t, "TestMixedReadsAndWrites (2)", &buf, s, make([]byte, buf.Len()))
 }
 
+func TestCapWithPreallocatedSlice(t *testing.T) {
+	buf := NewBuffer(make([]byte, 10))
+	n := buf.Cap()
+	if n != 10 {
+		t.Errorf("expected 10, got %d", n)
+	}
+}
+
+func TestCapWithSliceAndWrittenData(t *testing.T) {
+	buf := NewBuffer(make([]byte, 0, 10))
+	buf.Write([]byte("test"))
+	n := buf.Cap()
+	if n != 10 {
+		t.Errorf("expected 10, got %d", n)
+	}
+}
+
 func TestNil(t *testing.T) {
 	var b *Buffer
 	if b.String() != "<nil>" {
diff --git a/third_party/gofrontend/libgo/go/bytes/bytes.go b/third_party/gofrontend/libgo/go/bytes/bytes.go
index 7634707..b868240 100644
--- a/third_party/gofrontend/libgo/go/bytes/bytes.go
+++ b/third_party/gofrontend/libgo/go/bytes/bytes.go
@@ -23,7 +23,7 @@
 	return true
 }
 
-// explode splits s into a slice of UTF-8 sequences, one per Unicode character (still slices of bytes),
+// explode splits s into a slice of UTF-8 sequences, one per Unicode code point (still slices of bytes),
 // up to a maximum of n byte slices. Invalid UTF-8 sequences are chopped into individual bytes.
 func explode(s []byte, n int) [][]byte {
 	if n <= 0 {
@@ -47,6 +47,7 @@
 }
 
 // Count counts the number of non-overlapping instances of sep in s.
+// If sep is an empty slice, Count returns 1 + the number of Unicode code points in s.
 func Count(s, sep []byte) int {
 	n := len(sep)
 	if n == 0 {
@@ -137,6 +138,16 @@
 	return -1
 }
 
+// LastIndexByte returns the index of the last instance of c in s, or -1 if c is not present in s.
+func LastIndexByte(s []byte, c byte) int {
+	for i := len(s) - 1; i >= 0; i-- {
+		if s[i] == c {
+			return i
+		}
+	}
+	return -1
+}
+
 // IndexRune interprets s as a sequence of UTF-8-encoded Unicode code points.
 // It returns the byte index of the first occurrence in s of the given rune.
 // It returns -1 if rune is not present in s.
@@ -442,7 +453,7 @@
 // Title returns a copy of s with all Unicode letters that begin words
 // mapped to their title case.
 //
-// BUG: The rule Title uses for word boundaries does not handle Unicode punctuation properly.
+// BUG(rsc): The rule Title uses for word boundaries does not handle Unicode punctuation properly.
 func Title(s []byte) []byte {
 	// Use a closure here to remember state.
 	// Hackish but effective. Depends on Map scanning in order and calling
diff --git a/third_party/gofrontend/libgo/go/bytes/bytes_decl.go b/third_party/gofrontend/libgo/go/bytes/bytes_decl.go
index 617d748..b453f21 100644
--- a/third_party/gofrontend/libgo/go/bytes/bytes_decl.go
+++ b/third_party/gofrontend/libgo/go/bytes/bytes_decl.go
@@ -21,4 +21,4 @@
 // Compare returns an integer comparing two byte slices lexicographically.
 // The result will be 0 if a==b, -1 if a < b, and +1 if a > b.
 // A nil argument is equivalent to an empty slice.
-func Compare(a, b []byte) int // ../runtime/noasm_arm.goc or ../runtime/asm_{386,amd64}.s
+func Compare(a, b []byte) int // ../runtime/noasm.go or ../runtime/asm_{386,amd64}.s
diff --git a/third_party/gofrontend/libgo/go/bytes/bytes_test.go b/third_party/gofrontend/libgo/go/bytes/bytes_test.go
index 980c41d..6245e48 100644
--- a/third_party/gofrontend/libgo/go/bytes/bytes_test.go
+++ b/third_party/gofrontend/libgo/go/bytes/bytes_test.go
@@ -265,6 +265,23 @@
 	}
 }
 
+func TestLastIndexByte(t *testing.T) {
+	testCases := []BinOpTest{
+		{"", "q", -1},
+		{"abcdef", "q", -1},
+		{"abcdefabcdef", "a", len("abcdef")},      // something in the middle
+		{"abcdefabcdef", "f", len("abcdefabcde")}, // last byte
+		{"zabcdefabcdef", "z", 0},                 // first byte
+		{"a☺b☻c☹d", "b", len("a☺")},               // non-ascii
+	}
+	for _, test := range testCases {
+		actual := LastIndexByte([]byte(test.a), test.b[0])
+		if actual != test.i {
+			t.Errorf("LastIndexByte(%q,%c) = %v; want %v", test.a, test.b[0], actual, test.i)
+		}
+	}
+}
+
 // test a larger buffer with different sizes and alignments
 func TestIndexByteBig(t *testing.T) {
 	var n = 1024
diff --git a/third_party/gofrontend/libgo/go/bytes/compare_test.go b/third_party/gofrontend/libgo/go/bytes/compare_test.go
index 6352237..f2d81d5 100644
--- a/third_party/gofrontend/libgo/go/bytes/compare_test.go
+++ b/third_party/gofrontend/libgo/go/bytes/compare_test.go
@@ -17,6 +17,8 @@
 	{[]byte("a"), []byte(""), 1},
 	{[]byte(""), []byte("a"), -1},
 	{[]byte("abc"), []byte("abc"), 0},
+	{[]byte("abd"), []byte("abc"), 1},
+	{[]byte("abc"), []byte("abd"), -1},
 	{[]byte("ab"), []byte("abc"), -1},
 	{[]byte("abc"), []byte("ab"), 1},
 	{[]byte("x"), []byte("ab"), 1},
@@ -27,6 +29,7 @@
 	{[]byte("abcdefgh"), []byte("abcdefgh"), 0},
 	{[]byte("abcdefghi"), []byte("abcdefghi"), 0},
 	{[]byte("abcdefghi"), []byte("abcdefghj"), -1},
+	{[]byte("abcdefghj"), []byte("abcdefghi"), 1},
 	// nil tests
 	{nil, nil, 0},
 	{[]byte(""), nil, 0},
diff --git a/third_party/gofrontend/libgo/go/bytes/export_test.go b/third_party/gofrontend/libgo/go/bytes/export_test.go
index 3b915d5..f61523e 100644
--- a/third_party/gofrontend/libgo/go/bytes/export_test.go
+++ b/third_party/gofrontend/libgo/go/bytes/export_test.go
@@ -7,7 +7,3 @@
 // Export func for testing
 var IndexBytePortable = indexBytePortable
 var EqualPortable = equalPortable
-
-func (b *Buffer) Cap() int {
-	return cap(b.buf)
-}
diff --git a/third_party/gofrontend/libgo/go/bytes/reader.go b/third_party/gofrontend/libgo/go/bytes/reader.go
index d2d40fa..b89d154 100644
--- a/third_party/gofrontend/libgo/go/bytes/reader.go
+++ b/third_party/gofrontend/libgo/go/bytes/reader.go
@@ -29,6 +29,12 @@
 	return int(int64(len(r.s)) - r.i)
 }
 
+// Size returns the original length of the underlying byte slice.
+// Size is the number of bytes available for reading via ReadAt.
+// The returned value is always the same and is not affected by calls
+// to any other method.
+func (r *Reader) Size() int64 { return int64(len(r.s)) }
+
 func (r *Reader) Read(b []byte) (n int, err error) {
 	if len(b) == 0 {
 		return 0, nil
diff --git a/third_party/gofrontend/libgo/go/bytes/reader_test.go b/third_party/gofrontend/libgo/go/bytes/reader_test.go
index d3dce53..b929a28 100644
--- a/third_party/gofrontend/libgo/go/bytes/reader_test.go
+++ b/third_party/gofrontend/libgo/go/bytes/reader_test.go
@@ -244,3 +244,15 @@
 		t.Errorf("behavior differs: with = %#v; without: %#v", with, withOut)
 	}
 }
+
+// tests that Len is affected by reads, but Size is not.
+func TestReaderLenSize(t *testing.T) {
+	r := NewReader([]byte("abc"))
+	io.CopyN(ioutil.Discard, r, 1)
+	if r.Len() != 2 {
+		t.Errorf("Len = %d; want 2", r.Len())
+	}
+	if r.Size() != 3 {
+		t.Errorf("Size = %d; want 3", r.Size())
+	}
+}
diff --git a/third_party/gofrontend/libgo/go/cmd/cgo/ast.go b/third_party/gofrontend/libgo/go/cmd/cgo/ast.go
index 10e2278..8bbd1cc 100644
--- a/third_party/gofrontend/libgo/go/cmd/cgo/ast.go
+++ b/third_party/gofrontend/libgo/go/cmd/cgo/ast.go
@@ -235,9 +235,17 @@
 			error_(c.Pos(), "export comment has wrong name %q, want %q", name, n.Name.Name)
 		}
 
+		doc := ""
+		for _, c1 := range n.Doc.List {
+			if c1 != c {
+				doc += c1.Text + "\n"
+			}
+		}
+
 		f.ExpFunc = append(f.ExpFunc, &ExpFunc{
 			Func:    n,
 			ExpName: name,
+			Doc:     doc,
 		})
 		break
 	}
diff --git a/third_party/gofrontend/libgo/go/cmd/cgo/doc.go b/third_party/gofrontend/libgo/go/cmd/cgo/doc.go
index 6179c7a..b2a5428 100644
--- a/third_party/gofrontend/libgo/go/cmd/cgo/doc.go
+++ b/third_party/gofrontend/libgo/go/cmd/cgo/doc.go
@@ -20,16 +20,23 @@
 	// #include <errno.h>
 	import "C"
 
+The preamble may contain any C code, including function and variable
+declarations and definitions.  These may then be referred to from Go
+code as though they were defined in the package "C".  All names
+declared in the preamble may be used, even if they start with a
+lower-case letter.  Exception: static variables in the preamble may
+not be referenced from Go code; static functions are permitted.
+
 See $GOROOT/misc/cgo/stdio and $GOROOT/misc/cgo/gmp for examples.  See
 "C? Go? Cgo!" for an introduction to using cgo:
-http://golang.org/doc/articles/c_go_cgo.html.
+https://golang.org/doc/articles/c_go_cgo.html.
 
 CFLAGS, CPPFLAGS, CXXFLAGS and LDFLAGS may be defined with pseudo #cgo
 directives within these comments to tweak the behavior of the C or C++
 compiler.  Values defined in multiple directives are concatenated
 together.  The directive can include a list of build constraints limiting its
 effect to systems satisfying one of the constraints
-(see http://golang.org/pkg/go/build/#hdr-Build_Constraints for details about the constraint syntax).
+(see https://golang.org/pkg/go/build/#hdr-Build_Constraints for details about the constraint syntax).
 For example:
 
 	// #cgo CFLAGS: -DPNG_DEBUG=1
@@ -60,6 +67,18 @@
 concatenated and sent to pkg-config simultaneously to add to each appropriate
 set of command-line flags.
 
+When the cgo directives are parsed, any occurrence of the string ${SRCDIR}
+will be replaced by the absolute path to the directory containing the source
+file. This allows pre-compiled static libraries to be included in the package
+directory and linked properly.
+For example if package foo is in the directory /go/src/foo:
+
+       // #cgo LDFLAGS: -L${SRCDIR}/libs -lfoo
+
+Will be expanded to:
+
+       // #cgo LDFLAGS: -L/go/src/foo/libs -lfoo
+
 When the Go tool sees that one or more Go files use the special import
 "C", it will look for other non-Go files in the directory and compile
 them as part of the Go package.  Any .c, .s, or .S files will be
@@ -71,17 +90,19 @@
 respectively; those environment variables may include command line
 options.
 
-To enable cgo during cross compiling builds, set the CGO_ENABLED
-environment variable to 1 when building the Go tools with make.bash.
-Also, set CC_FOR_TARGET to the C cross compiler for the target.  CC will
-be used for compiling for the host.
+The cgo tool is enabled by default for native builds on systems where
+it is expected to work.  It is disabled by default when
+cross-compiling.  You can control this by setting the CGO_ENABLED
+environment variable when running the go tool: set it to 1 to enable
+the use of cgo, and to 0 to disable it.  The go tool will set the
+build constraint "cgo" if cgo is enabled.
 
-After the Go tools are built, when running the go command, CC_FOR_TARGET is
-ignored.  The value of CC_FOR_TARGET when running make.bash is the default
-compiler.  However, you can set the environment variable CC, not CC_FOR_TARGET,
-to control the compiler when running the go tool.
-
-CXX_FOR_TARGET works in a similar way for C++ code.
+When cross-compiling, you must specify a C cross-compiler for cgo to
+use.  You can do this by setting the CC_FOR_TARGET environment
+variable when building the toolchain using make.bash, or by setting
+the CC environment variable any time you run the go tool.  The
+CXX_FOR_TARGET and CXX environment variables work in a similar way for
+C++ code.
 
 Go references to C
 
@@ -195,16 +216,18 @@
 
 Using //export in a file places a restriction on the preamble:
 since it is copied into two different C output files, it must not
-contain any definitions, only declarations. Definitions must be
-placed in preambles in other files, or in C source files.
+contain any definitions, only declarations. If a file contains both
+definitions and declarations, then the two output files will produce
+duplicate symbols and the linker will fail. To avoid this, definitions
+must be placed in preambles in other files, or in C source files.
 
 Using cgo directly
 
 Usage:
-	go tool cgo [cgo options] [-- compiler options] file.go
+	go tool cgo [cgo options] [-- compiler options] gofiles...
 
-Cgo transforms the input file.go into four output files: two Go source
-files, a C file for 6c (or 8c or 5c), and a C file for gcc.
+Cgo transforms the specified input Go source files into several output
+Go and C source files.
 
 The compiler options are passed through uninterpreted when
 invoking the C compiler to compile the C parts of the package.
@@ -217,18 +240,23 @@
 		build when building a cgo package.
 	-dynout file
 		Write -dynimport output to file.
+	-dynpackage package
+		Set Go package for -dynimport output.
 	-dynlinker
 		Write dynamic linker as part of -dynimport output.
 	-godefs
 		Write out input file in Go syntax replacing C package
 		names with real values. Used to generate files in the
 		syscall package when bootstrapping a new target.
-	-cdefs
-		Like -godefs, but write file in C syntax.
-		Used to generate files in the runtime package when
-		bootstrapping a new target.
 	-objdir directory
 		Put all generated files in directory.
+	-importpath string
+		The import path for the Go package. Optional; used for
+		nicer comments in the generated files.
+	-exportheader file
+		If there are any exported functions, write the
+		generated export declarations to file.
+		C code can #include this to see the declarations.
 	-gccgo
 		Generate output for the gccgo compiler rather than the
 		gc compiler.
@@ -363,9 +391,9 @@
 
 Translating Go
 
-[The rest of this comment refers to 6g and 6c, the Go and C compilers
-that are part of the amd64 port of the gc Go toolchain. Everything here
-applies to another architecture's compilers as well.]
+[The rest of this comment refers to 6g, the Go compiler that is part
+of the amd64 port of the gc Go toolchain. Everything here applies to
+another architecture's compilers as well.]
 
 Given the input Go files x.go and y.go, cgo generates these source
 files:
@@ -373,44 +401,41 @@
 	x.cgo1.go       # for 6g
 	y.cgo1.go       # for 6g
 	_cgo_gotypes.go # for 6g
-	_cgo_defun.c    # for 6c
+	_cgo_import.go  # for 6g (if -dynout _cgo_import.go)
 	x.cgo2.c        # for gcc
 	y.cgo2.c        # for gcc
+	_cgo_defun.c    # for gcc (if -gccgo)
 	_cgo_export.c   # for gcc
+	_cgo_export.h   # for gcc
 	_cgo_main.c     # for gcc
+	_cgo_flags      # for alternative build tools
 
 The file x.cgo1.go is a copy of x.go with the import "C" removed and
 references to C.xxx replaced with names like _Cfunc_xxx or _Ctype_xxx.
 The definitions of those identifiers, written as Go functions, types,
 or variables, are provided in _cgo_gotypes.go.
 
-Here is a _cgo_gotypes.go containing definitions for C.flush (provided
-in the preamble) and C.puts (from stdio):
+Here is a _cgo_gotypes.go containing definitions for needed C types:
 
 	type _Ctype_char int8
 	type _Ctype_int int32
 	type _Ctype_void [0]byte
 
-	func _Cfunc_CString(string) *_Ctype_char
-	func _Cfunc_flush() _Ctype_void
-	func _Cfunc_puts(*_Ctype_char) _Ctype_int
-
-For functions, cgo only writes an external declaration in the Go
-output. The implementation is in a combination of C for 6c (meaning
-any gc-toolchain compiler) and C for gcc.
-
-The 6c file contains the definitions of the functions. They all have
-similar bodies that invoke runtime·cgocall to make a switch from the
-Go runtime world to the system C (GCC-based) world.
+The _cgo_gotypes.go file also contains the definitions of the
+functions.  They all have similar bodies that invoke runtime·cgocall
+to make a switch from the Go runtime world to the system C (GCC-based)
+world.
 
 For example, here is the definition of _Cfunc_puts:
 
-	void _cgo_be59f0f25121_Cfunc_puts(void*);
+	//go:cgo_import_static _cgo_be59f0f25121_Cfunc_puts
+	//go:linkname __cgofn__cgo_be59f0f25121_Cfunc_puts _cgo_be59f0f25121_Cfunc_puts
+	var __cgofn__cgo_be59f0f25121_Cfunc_puts byte
+	var _cgo_be59f0f25121_Cfunc_puts = unsafe.Pointer(&__cgofn__cgo_be59f0f25121_Cfunc_puts)
 
-	void
-	·_Cfunc_puts(struct{uint8 x[1];}p)
-	{
-		runtime·cgocall(_cgo_be59f0f25121_Cfunc_puts, &p);
+	func _Cfunc_puts(p0 *_Ctype_char) (r1 _Ctype_int) {
+		_cgo_runtime_cgocall(_cgo_be59f0f25121_Cfunc_puts, uintptr(unsafe.Pointer(&p0)))
+		return
 	}
 
 The hexadecimal number is a hash of cgo's input, chosen to be
@@ -421,6 +446,7 @@
 	void
 	_cgo_be59f0f25121_Cfunc_puts(void *v)
 	{
+		_cgo_wait_runtime_init_done();
 		struct {
 			char* p0;
 			int r;
@@ -429,7 +455,8 @@
 		a->r = puts((void*)a->p0);
 	}
 
-It extracts the arguments from the pointer to _Cfunc_puts's argument
+It waits for Go runtime to be initialized (required for shared libraries),
+extracts the arguments from the pointer to _Cfunc_puts's argument
 frame, invokes the system C function (in this case, puts), stores the
 result in the frame, and returns.
 
@@ -448,6 +475,7 @@
 
 	int main() { return 0; }
 	void crosscall2(void(*fn)(void*, int), void *a, int c) { }
+	void _cgo_wait_runtime_init_done() { }
 	void _cgo_allocate(void *a, int c) { }
 	void _cgo_panic(void *a, int c) { }
 
@@ -456,23 +484,21 @@
 _cgo_export.c and *.cgo2.c, into a dynamic executable and then lets
 cgo examine the executable. Cgo records the list of shared library
 references and resolved names and writes them into a new file
-_cgo_import.c, which looks like:
+_cgo_import.go, which looks like:
 
-	#pragma cgo_dynamic_linker "/lib64/ld-linux-x86-64.so.2"
-	#pragma cgo_import_dynamic puts puts#GLIBC_2.2.5 "libc.so.6"
-	#pragma cgo_import_dynamic __libc_start_main __libc_start_main#GLIBC_2.2.5 "libc.so.6"
-	#pragma cgo_import_dynamic stdout stdout#GLIBC_2.2.5 "libc.so.6"
-	#pragma cgo_import_dynamic fflush fflush#GLIBC_2.2.5 "libc.so.6"
-	#pragma cgo_import_dynamic _ _ "libpthread.so.0"
-	#pragma cgo_import_dynamic _ _ "libc.so.6"
+	//go:cgo_dynamic_linker "/lib64/ld-linux-x86-64.so.2"
+	//go:cgo_import_dynamic puts puts#GLIBC_2.2.5 "libc.so.6"
+	//go:cgo_import_dynamic __libc_start_main __libc_start_main#GLIBC_2.2.5 "libc.so.6"
+	//go:cgo_import_dynamic stdout stdout#GLIBC_2.2.5 "libc.so.6"
+	//go:cgo_import_dynamic fflush fflush#GLIBC_2.2.5 "libc.so.6"
+	//go:cgo_import_dynamic _ _ "libpthread.so.0"
+	//go:cgo_import_dynamic _ _ "libc.so.6"
 
 In the end, the compiled Go package, which will eventually be
 presented to 6l as part of a larger program, contains:
 
-	_go_.6        # 6g-compiled object for _cgo_gotypes.go *.cgo1.go
-	_cgo_defun.6  # 6c-compiled object for _cgo_defun.c
+	_go_.6        # 6g-compiled object for _cgo_gotypes.go, _cgo_import.go, *.cgo1.go
 	_all.o        # gcc-compiled object for _cgo_export.c, *.cgo2.c
-	_cgo_import.6 # 6c-compiled object for _cgo_import.c
 
 The final program will be a dynamic executable, so that 6l can avoid
 needing to process arbitrary .o files. It only needs to process the .o
@@ -496,20 +522,21 @@
 
 When using cgo, Go must not assume that it owns all details of the
 process. In particular it needs to coordinate with C in the use of
-threads and thread-local storage. The runtime package, in its own
-(6c-compiled) C code, declares a few uninitialized (default bss)
+threads and thread-local storage. The runtime package declares a few
 variables:
 
-	bool	runtime·iscgo;
-	void	(*libcgo_thread_start)(void*);
-	void	(*initcgo)(G*);
+	var (
+		iscgo             bool
+		_cgo_init         unsafe.Pointer
+		_cgo_thread_start unsafe.Pointer
+	)
 
 Any package using cgo imports "runtime/cgo", which provides
-initializations for these variables. It sets iscgo to 1, initcgo to a
-gcc-compiled function that can be called early during program startup,
-and libcgo_thread_start to a gcc-compiled function that can be used to
-create a new thread, in place of the runtime's usual direct system
-calls.
+initializations for these variables. It sets iscgo to true, _cgo_init
+to a gcc-compiled function that can be called early during program
+startup, and _cgo_thread_start to a gcc-compiled function that can be
+used to create a new thread, in place of the runtime's usual direct
+system calls.
 
 Internal and External Linking
 
@@ -522,12 +549,12 @@
 using internal linking, 6l can generate Go binaries by itself.
 
 In order to allow linking arbitrary object files without requiring
-dynamic libraries, cgo will soon support an "external" linking mode
-too. In external linking mode, 6l does not process any host object
-files. Instead, it collects all the Go code and writes a single go.o
-object file containing it. Then it invokes the host linker (usually
-gcc) to combine the go.o object file and any supporting non-Go code
-into a final executable. External linking avoids the dynamic library
+dynamic libraries, cgo supports an "external" linking mode too. In
+external linking mode, 6l does not process any host object files.
+Instead, it collects all the Go code and writes a single go.o object
+file containing it. Then it invokes the host linker (usually gcc) to
+combine the go.o object file and any supporting non-Go code into a
+final executable. External linking avoids the dynamic library
 requirement but introduces a requirement that the host linker be
 present to create such a binary.
 
@@ -555,13 +582,13 @@
 Linking Directives
 
 In either linking mode, package-specific directives must be passed
-through to 6l. These are communicated by writing #pragma directives
-in a C source file compiled by 6c. The directives are copied into the .6 object file
-and then processed by the linker.
+through to 6l. These are communicated by writing //go: directives in a
+Go source file compiled by 6g. The directives are copied into the .6
+object file and then processed by the linker.
 
 The directives are:
 
-#pragma cgo_import_dynamic <local> [<remote> ["<library>"]]
+//go:cgo_import_dynamic <local> [<remote> ["<library>"]]
 
 	In internal linking mode, allow an unresolved reference to
 	<local>, assuming it will be resolved by a dynamic library
@@ -572,9 +599,9 @@
 	In the <remote>, # or @ can be used to introduce a symbol version.
 
 	Examples:
-	#pragma cgo_import_dynamic puts
-	#pragma cgo_import_dynamic puts puts#GLIBC_2.2.5
-	#pragma cgo_import_dynamic puts puts#GLIBC_2.2.5 "libc.so.6"
+	//go:cgo_import_dynamic puts
+	//go:cgo_import_dynamic puts puts#GLIBC_2.2.5
+	//go:cgo_import_dynamic puts puts#GLIBC_2.2.5 "libc.so.6"
 
 	A side effect of the cgo_import_dynamic directive with a
 	library is to make the final binary depend on that dynamic
@@ -582,12 +609,12 @@
 	symbols, use _ for local and remote.
 
 	Example:
-	#pragma cgo_import_dynamic _ _ "libc.so.6"
+	//go:cgo_import_dynamic _ _ "libc.so.6"
 
 	For compatibility with current versions of SWIG,
-	#pragma dynimport is an alias for #pragma cgo_import_dynamic.
+	#pragma dynimport is an alias for //go:cgo_import_dynamic.
 
-#pragma cgo_dynamic_linker "<path>"
+//go:cgo_dynamic_linker "<path>"
 
 	In internal linking mode, use "<path>" as the dynamic linker
 	in the final binary. This directive is only needed from one
@@ -595,9 +622,9 @@
 	supplied by runtime/cgo.
 
 	Example:
-	#pragma cgo_dynamic_linker "/lib/ld-linux.so.2"
+	//go:cgo_dynamic_linker "/lib/ld-linux.so.2"
 
-#pragma cgo_export_dynamic <local> <remote>
+//go:cgo_export_dynamic <local> <remote>
 
 	In internal linking mode, put the Go symbol
 	named <local> into the program's exported symbol table as
@@ -606,9 +633,9 @@
 	to share Go's data.
 
 	For compatibility with current versions of SWIG,
-	#pragma dynexport is an alias for #pragma cgo_export_dynamic.
+	#pragma dynexport is an alias for //go:cgo_export_dynamic.
 
-#pragma cgo_import_static <local>
+//go:cgo_import_static <local>
 
 	In external linking mode, allow unresolved references to
 	<local> in the go.o object file prepared for the host linker,
@@ -616,9 +643,9 @@
 	other object files that will be linked with go.o.
 
 	Example:
-	#pragma cgo_import_static puts_wrapper
+	//go:cgo_import_static puts_wrapper
 
-#pragma cgo_export_static <local> <remote>
+//go:cgo_export_static <local> <remote>
 
 	In external linking mode, put the Go symbol
 	named <local> into the program's exported symbol table as
@@ -626,15 +653,15 @@
 	mechanism makes it possible for C code to call back into Go or
 	to share Go's data.
 
-#pragma cgo_ldflag "<arg>"
+//go:cgo_ldflag "<arg>"
 
 	In external linking mode, invoke the host linker (usually gcc)
 	with "<arg>" as a command-line argument following the .o files.
 	Note that the arguments are for "gcc", not "ld".
 
 	Example:
-	#pragma cgo_ldflag "-lpthread"
-	#pragma cgo_ldflag "-L/usr/local/sqlite3/lib"
+	//go:cgo_ldflag "-lpthread"
+	//go:cgo_ldflag "-L/usr/local/sqlite3/lib"
 
 A package compiled with cgo will include directives for both
 internal and external linking; the linker will select the appropriate
@@ -647,22 +674,18 @@
 
 	// compiled by 6g
 
+	//go:cgo_ldflag "-lm"
+
 	type _Ctype_double float64
-	func _Cfunc_sin(_Ctype_double) _Ctype_double
 
-	// compiled by 6c
+	//go:cgo_import_static _cgo_gcc_Cfunc_sin
+	//go:linkname __cgo_gcc_Cfunc_sin _cgo_gcc_Cfunc_sin
+	var __cgo_gcc_Cfunc_sin byte
+	var _cgo_gcc_Cfunc_sin = unsafe.Pointer(&__cgo_gcc_Cfunc_sin)
 
-	#pragma cgo_import_dynamic sin sin#GLIBC_2.2.5 "libm.so.6"
-
-	#pragma cgo_import_static _cgo_gcc_Cfunc_sin
-	#pragma cgo_ldflag "-lm"
-
-	void _cgo_gcc_Cfunc_sin(void*);
-
-	void
-	·_Cfunc_sin(struct{uint8 x[16];}p)
-	{
-		runtime·cgocall(_cgo_gcc_Cfunc_sin, &p);
+	func _Cfunc_sin(p0 _Ctype_double) (r1 _Ctype_double) {
+		_cgo_runtime_cgocall(_cgo_gcc_Cfunc_sin, uintptr(unsafe.Pointer(&p0)))
+		return
 	}
 
 	// compiled by gcc, into foo.cgo2.o
@@ -682,8 +705,8 @@
 "external only" mode, then the final link will be an external one.
 Otherwise the link will be an internal one.
 
-The directives in the 6c-compiled file are used according to the kind
-of final link used.
+The linking directives are used according to the kind of final link
+used.
 
 In internal mode, 6l itself processes all the host object files, in
 particular foo.cgo2.o. To do so, it uses the cgo_import_dynamic and
@@ -694,10 +717,10 @@
 runtime dynamic linker.
 
 In external mode, 6l does not process any host object files, in
-particular foo.cgo2.o. It links together the 6g- and 6c-generated
-object files, along with any other Go code, into a go.o file. While
-doing that, 6l will discover that there is no definition for
-_cgo_gcc_Cfunc_sin, referred to by the 6c-compiled source file. This
+particular foo.cgo2.o. It links together the 6g-generated object
+files, along with any other Go code, into a go.o file. While doing
+that, 6l will discover that there is no definition for
+_cgo_gcc_Cfunc_sin, referred to by the 6g-compiled source file. This
 is okay, because 6l also processes the cgo_import_static directive and
 knows that _cgo_gcc_Cfunc_sin is expected to be supplied by a host
 object file, so 6l does not treat the missing symbol as an error when
diff --git a/third_party/gofrontend/libgo/go/cmd/cgo/gcc.go b/third_party/gofrontend/libgo/go/cmd/cgo/gcc.go
index abdd369..e0b89ec 100644
--- a/third_party/gofrontend/libgo/go/cmd/cgo/gcc.go
+++ b/third_party/gofrontend/libgo/go/cmd/cgo/gcc.go
@@ -154,20 +154,6 @@
 	return args, err
 }
 
-var safeBytes = []byte(`+-.,/0123456789:=ABCDEFGHIJKLMNOPQRSTUVWXYZ\_abcdefghijklmnopqrstuvwxyz`)
-
-func safeName(s string) bool {
-	if s == "" {
-		return false
-	}
-	for i := 0; i < len(s); i++ {
-		if c := s[i]; c < 0x80 && bytes.IndexByte(safeBytes, c) < 0 {
-			return false
-		}
-	}
-	return true
-}
-
 // Translate rewrites f.AST, the original Go input, to remove
 // references to the imported package C, replacing them with
 // references to the equivalent Go types, functions, and variables.
@@ -213,6 +199,10 @@
 			val = strings.TrimSpace(line[tabIndex:])
 		}
 
+		if key == "__clang__" {
+			p.GccIsClang = true
+		}
+
 		if n := f.Name[key]; n != nil {
 			if *debugDefine {
 				fmt.Fprintf(os.Stderr, "#define %s %s\n", key, val)
@@ -500,6 +490,11 @@
 			name, _ := e.Val(dwarf.AttrName).(string)
 			typOff, _ := e.Val(dwarf.AttrType).(dwarf.Offset)
 			if name == "" || typOff == 0 {
+				if e.Val(dwarf.AttrSpecification) != nil {
+					// Since we are reading all the DWARF,
+					// assume we will see the variable elsewhere.
+					break
+				}
 				fatalf("malformed DWARF TagVariable entry")
 			}
 			if !strings.HasPrefix(name, "__cgo__") {
@@ -582,7 +577,7 @@
 
 // rewriteRef rewrites all the C.xxx references in f.AST to refer to the
 // Go equivalents, now that we have figured out the meaning of all
-// the xxx.  In *godefs or *cdefs mode, rewriteRef replaces the names
+// the xxx.  In *godefs mode, rewriteRef replaces the names
 // with full definitions instead of mangled names.
 func (p *Package) rewriteRef(f *File) {
 	// Keep a list of all the functions, to remove the ones
@@ -673,6 +668,13 @@
 				expr = &ast.StarExpr{Star: (*r.Expr).Pos(), X: expr}
 			}
 
+		case "selector":
+			if r.Name.Kind == "var" {
+				expr = &ast.StarExpr{Star: (*r.Expr).Pos(), X: expr}
+			} else {
+				error_(r.Pos(), "only C variables allowed in selector expression", fixGo(r.Name.Go))
+			}
+
 		case "type":
 			if r.Name.Kind != "type" {
 				error_(r.Pos(), "expression C.%s used as type", fixGo(r.Name.Go))
@@ -688,7 +690,7 @@
 				error_(r.Pos(), "must call C.%s", fixGo(r.Name.Go))
 			}
 		}
-		if *godefs || *cdefs {
+		if *godefs {
 			// Substitute definition for mangled type name.
 			if id, ok := expr.(*ast.Ident); ok {
 				if t := typedef[id.Name]; t != nil {
@@ -746,6 +748,10 @@
 		return []string{"-m32"}
 	case "arm":
 		return []string{"-marm"} // not thumb
+	case "s390":
+		return []string{"-m31"}
+	case "s390x":
+		return []string{"-m64"}
 	}
 	return nil
 }
@@ -765,7 +771,7 @@
 		"-c",          // do not link
 		"-xc",         // input language is C
 	)
-	if strings.Contains(c[0], "clang") {
+	if p.GccIsClang {
 		c = append(c,
 			"-ferror-limit=0",
 			// Apple clang version 1.7 (tags/Apple/clang-77) (based on LLVM 2.9svn)
@@ -780,7 +786,7 @@
 			// incorrectly typed unsigned long. We work around that
 			// by disabling the builtin functions (this is safe as
 			// it won't affect the actual compilation of the C code).
-			// See: http://golang.org/issue/6506.
+			// See: https://golang.org/issue/6506.
 			"-fno-builtin",
 		)
 	}
@@ -992,8 +998,8 @@
 	c.goVoid = c.Ident("_Ctype_void")
 
 	// Normally cgo translates void* to unsafe.Pointer,
-	// but for historical reasons -cdefs and -godefs use *byte instead.
-	if *cdefs || *godefs {
+	// but for historical reasons -godefs uses *byte instead.
+	if *godefs {
 		c.goVoidPtr = &ast.StarExpr{X: c.byte}
 	} else {
 		c.goVoidPtr = c.Ident("unsafe.Pointer")
@@ -1045,7 +1051,7 @@
 	return fmt.Sprintf(tr.Repr, tr.FormatArgs...)
 }
 
-// Empty returns true if the result of String would be "".
+// Empty reports whether the result of String would be "".
 func (tr *TypeRepr) Empty() bool {
 	return len(tr.Repr) == 0
 }
@@ -1334,8 +1340,8 @@
 		// If sub.Go.Name is "_Ctype_struct_foo" or "_Ctype_union_foo" or "_Ctype_class_foo",
 		// use that as the Go form for this typedef too, so that the typedef will be interchangeable
 		// with the base type.
-		// In -godefs and -cdefs mode, do this for all typedefs.
-		if isStructUnionClass(sub.Go) || *godefs || *cdefs {
+		// In -godefs mode, do this for all typedefs.
+		if isStructUnionClass(sub.Go) || *godefs {
 			t.Go = sub.Go
 
 			if isStructUnionClass(sub.Go) {
@@ -1397,7 +1403,7 @@
 			name := c.Ident("_Ctype_" + s)
 			tt := *t
 			typedef[name.Name] = &tt
-			if !*godefs && !*cdefs {
+			if !*godefs {
 				t.Go = name
 			}
 		}
@@ -1543,14 +1549,16 @@
 }
 
 // Add padding of given size to fld.
-func (c *typeConv) pad(fld []*ast.Field, size int64) []*ast.Field {
+func (c *typeConv) pad(fld []*ast.Field, sizes []int64, size int64) ([]*ast.Field, []int64) {
 	n := len(fld)
 	fld = fld[0 : n+1]
 	fld[n] = &ast.Field{Names: []*ast.Ident{c.Ident("_")}, Type: c.Opaque(size)}
-	return fld
+	sizes = sizes[0 : n+1]
+	sizes[n] = size
+	return fld, sizes
 }
 
-// Struct conversion: return Go and (6g) C syntax for type.
+// Struct conversion: return Go and (gc) C syntax for type.
 func (c *typeConv) Struct(dt *dwarf.StructType, pos token.Pos) (expr *ast.StructType, csyntax string, align int64) {
 	// Minimum alignment for a struct is 1 byte.
 	align = 1
@@ -1558,6 +1566,7 @@
 	var buf bytes.Buffer
 	buf.WriteString("struct {")
 	fld := make([]*ast.Field, 0, 2*len(dt.Field)+1) // enough for padding around every field
+	sizes := make([]int64, 0, 2*len(dt.Field)+1)
 	off := int64(0)
 
 	// Rename struct fields that happen to be named Go keywords into
@@ -1573,7 +1582,7 @@
 		used[f.Name] = true
 	}
 
-	if !*godefs && !*cdefs {
+	if !*godefs {
 		for cid, goid := range ident {
 			if token.Lookup(goid).IsKeyword() {
 				// Avoid keyword
@@ -1593,19 +1602,19 @@
 	anon := 0
 	for _, f := range dt.Field {
 		if f.ByteOffset > off {
-			fld = c.pad(fld, f.ByteOffset-off)
+			fld, sizes = c.pad(fld, sizes, f.ByteOffset-off)
 			off = f.ByteOffset
 		}
 
 		name := f.Name
 		ft := f.Type
 
-		// In godefs or cdefs mode, if this field is a C11
+		// In godefs mode, if this field is a C11
 		// anonymous union then treat the first field in the
 		// union as the field in the struct.  This handles
 		// cases like the glibc <sys/resource.h> file; see
 		// issue 6677.
-		if *godefs || *cdefs {
+		if *godefs {
 			if st, ok := f.Type.(*dwarf.StructType); ok && name == "" && st.Kind == "union" && len(st.Field) > 0 && !used[st.Field[0].Name] {
 				name = st.Field[0].Name
 				ident[name] = name
@@ -1635,14 +1644,12 @@
 			talign = size
 		}
 
-		if talign > 0 && f.ByteOffset%talign != 0 && !*cdefs {
+		if talign > 0 && f.ByteOffset%talign != 0 {
 			// Drop misaligned fields, the same way we drop integer bit fields.
 			// The goal is to make available what can be made available.
 			// Otherwise one bad and unneeded field in an otherwise okay struct
 			// makes the whole program not compile. Much of the time these
 			// structs are in system headers that cannot be corrected.
-			// Exception: In -cdefs mode, we use #pragma pack, so misaligned
-			// fields should still work.
 			continue
 		}
 		n := len(fld)
@@ -1653,6 +1660,8 @@
 			ident[name] = name
 		}
 		fld[n] = &ast.Field{Names: []*ast.Ident{c.Ident(ident[name])}, Type: tgo}
+		sizes = sizes[0 : n+1]
+		sizes[n] = size
 		off += size
 		buf.WriteString(t.C.String())
 		buf.WriteString(" ")
@@ -1663,16 +1672,29 @@
 		}
 	}
 	if off < dt.ByteSize {
-		fld = c.pad(fld, dt.ByteSize-off)
+		fld, sizes = c.pad(fld, sizes, dt.ByteSize-off)
 		off = dt.ByteSize
 	}
+
+	// If the last field in a non-zero-sized struct is zero-sized
+	// the compiler is going to pad it by one (see issue 9401).
+	// We can't permit that, because then the size of the Go
+	// struct will not be the same as the size of the C struct.
+	// Our only option in such a case is to remove the field,
+	// which means that it can not be referenced from Go.
+	for off > 0 && sizes[len(sizes)-1] == 0 {
+		n := len(sizes)
+		fld = fld[0 : n-1]
+		sizes = sizes[0 : n-1]
+	}
+
 	if off != dt.ByteSize {
 		fatalf("%s: struct size calculation error off=%d bytesize=%d", lineno(pos), off, dt.ByteSize)
 	}
 	buf.WriteString("}")
 	csyntax = buf.String()
 
-	if *godefs || *cdefs {
+	if *godefs {
 		godefsFields(fld)
 	}
 	expr = &ast.StructType{Fields: &ast.FieldList{List: fld}}
@@ -1707,9 +1729,7 @@
 				n.Name = "Pad_cgo_" + strconv.Itoa(npad)
 				npad++
 			}
-			if !*cdefs {
-				n.Name = upper(n.Name)
-			}
+			n.Name = upper(n.Name)
 		}
 	}
 }
@@ -1721,9 +1741,6 @@
 // package syscall's data structures, we drop a common prefix
 // (so sec, usec, which will get turned into Sec, Usec for exporting).
 func fieldPrefix(fld []*ast.Field) string {
-	if *cdefs {
-		return ""
-	}
 	prefix := ""
 	for _, f := range fld {
 		for _, n := range f.Names {
diff --git a/third_party/gofrontend/libgo/go/cmd/cgo/godefs.go b/third_party/gofrontend/libgo/go/cmd/cgo/godefs.go
index ce5ac27..1b0ece2 100644
--- a/third_party/gofrontend/libgo/go/cmd/cgo/godefs.go
+++ b/third_party/gofrontend/libgo/go/cmd/cgo/godefs.go
@@ -114,173 +114,6 @@
 	return buf.String()
 }
 
-// cdefs returns the output for -cdefs mode.
-// The easiest way to do this is to translate the godefs Go to C.
-func (p *Package) cdefs(f *File, srcfile string) string {
-	godefsOutput := p.godefs(f, srcfile)
-
-	lines := strings.Split(godefsOutput, "\n")
-	lines[0] = "// Created by cgo -cdefs - DO NOT EDIT"
-
-	for i, line := range lines {
-		lines[i] = strings.TrimSpace(line)
-	}
-
-	var out bytes.Buffer
-	printf := func(format string, args ...interface{}) { fmt.Fprintf(&out, format, args...) }
-
-	didTypedef := false
-	for i := 0; i < len(lines); i++ {
-		line := lines[i]
-
-		// Delete
-		//	package x
-		if strings.HasPrefix(line, "package ") {
-			continue
-		}
-
-		// Convert
-		//	const (
-		//		A = 1
-		//		B = 2
-		//	)
-		//
-		// to
-		//
-		//	enum {
-		//		A = 1,
-		//		B = 2,
-		//	};
-		if line == "const (" {
-			printf("enum {\n")
-			for i++; i < len(lines) && lines[i] != ")"; i++ {
-				line = lines[i]
-				if line != "" {
-					printf("\t%s,", line)
-				}
-				printf("\n")
-			}
-			printf("};\n")
-			continue
-		}
-
-		// Convert
-		//	const A = 1
-		// to
-		//	enum { A = 1 };
-		if strings.HasPrefix(line, "const ") {
-			printf("enum { %s };\n", line[len("const "):])
-			continue
-		}
-
-		// On first type definition, typedef all the structs
-		// in case there are dependencies between them.
-		if !didTypedef && strings.HasPrefix(line, "type ") {
-			didTypedef = true
-			for _, line := range lines {
-				line = strings.TrimSpace(line)
-				if strings.HasPrefix(line, "type ") && strings.HasSuffix(line, " struct {") {
-					s := strings.TrimSuffix(strings.TrimPrefix(line, "type "), " struct {")
-					printf("typedef struct %s %s;\n", s, s)
-				}
-			}
-			printf("\n")
-			printf("#pragma pack on\n")
-			printf("\n")
-		}
-
-		// Convert
-		//	type T struct {
-		//		X int64
-		//		Y *int32
-		//		Z [4]byte
-		//	}
-		//
-		// to
-		//
-		//	struct T {
-		//		int64 X;
-		//		int32 *Y;
-		//		byte Z[4];
-		//	}
-		if strings.HasPrefix(line, "type ") && strings.HasSuffix(line, " struct {") {
-			if len(lines) > i+1 && lines[i+1] == "}" {
-				// do not output empty struct
-				i++
-				continue
-			}
-			s := line[len("type ") : len(line)-len(" struct {")]
-			printf("struct %s {\n", s)
-			for i++; i < len(lines) && lines[i] != "}"; i++ {
-				line := lines[i]
-				if line != "" {
-					f := strings.Fields(line)
-					if len(f) != 2 {
-						fmt.Fprintf(os.Stderr, "cgo: cannot parse struct field: %s\n", line)
-						nerrors++
-						continue
-					}
-					printf("\t%s;", cdecl(f[0], f[1]))
-				}
-				printf("\n")
-			}
-			printf("};\n")
-			continue
-		}
-
-		// Convert
-		//	type T int
-		// to
-		//	typedef int T;
-		if strings.HasPrefix(line, "type ") {
-			f := strings.Fields(line[len("type "):])
-			if len(f) != 2 {
-				fmt.Fprintf(os.Stderr, "cgo: cannot parse type definition: %s\n", line)
-				nerrors++
-				continue
-			}
-			printf("typedef\t%s;\n", cdecl(f[0], f[1]))
-			continue
-		}
-
-		printf("%s\n", line)
-	}
-
-	if didTypedef {
-		printf("\n")
-		printf("#pragma pack off\n")
-	}
-
-	return out.String()
-}
-
-// cdecl returns the C declaration for the given Go name and type.
-// It only handles the specific cases necessary for converting godefs output.
-func cdecl(name, typ string) string {
-	// X *[0]byte -> X *void
-	if strings.HasPrefix(typ, "*[0]") {
-		typ = "*void"
-	}
-	// X [4]byte -> X[4] byte
-	for strings.HasPrefix(typ, "[") {
-		i := strings.Index(typ, "]") + 1
-		name = name + typ[:i]
-		typ = typ[i:]
-	}
-	// X *byte -> *X byte
-	for strings.HasPrefix(typ, "*") {
-		name = "*" + name
-		typ = typ[1:]
-	}
-	// X T -> T X
-	// Handle the special case: 'unsafe.Pointer' is 'void *'
-	if typ == "unsafe.Pointer" {
-		typ = "void"
-		name = "*" + name
-	}
-	return typ + "\t" + name
-}
-
 var gofmtBuf bytes.Buffer
 
 // gofmt returns the gofmt-formatted string for an AST node.
diff --git a/third_party/gofrontend/libgo/go/cmd/cgo/main.go b/third_party/gofrontend/libgo/go/cmd/cgo/main.go
index 48257fc..c8cd161 100644
--- a/third_party/gofrontend/libgo/go/cmd/cgo/main.go
+++ b/third_party/gofrontend/libgo/go/cmd/cgo/main.go
@@ -6,7 +6,7 @@
 
 // TODO(rsc):
 //	Emit correct line number annotations.
-//	Make 6g understand the annotations.
+//	Make gc understand the annotations.
 
 package main
 
@@ -33,6 +33,7 @@
 	PtrSize     int64
 	IntSize     int64
 	GccOptions  []string
+	GccIsClang  bool
 	CgoFlags    map[string][]string // #cgo flags (CFLAGS, LDFLAGS)
 	Written     map[string]bool
 	Name        map[string]*Name // accumulated Name from Files
@@ -87,7 +88,7 @@
 	Const    string // constant definition
 }
 
-// IsVar returns true if Kind is either "var" or "fpvar"
+// IsVar reports whether Kind is either "var" or "fpvar"
 func (n *Name) IsVar() bool {
 	return n.Kind == "var" || n.Kind == "fpvar"
 }
@@ -98,6 +99,7 @@
 type ExpFunc struct {
 	Func    *ast.FuncDecl
 	ExpName string // name to use from C
+	Doc     string
 }
 
 // A TypeRepr contains the string representation of a type.
@@ -174,15 +176,18 @@
 var fset = token.NewFileSet()
 
 var dynobj = flag.String("dynimport", "", "if non-empty, print dynamic import data for that file")
-var dynout = flag.String("dynout", "", "write -dynobj output to this file")
-var dynlinker = flag.Bool("dynlinker", false, "record dynamic linker information in dynimport mode")
+var dynout = flag.String("dynout", "", "write -dynimport output to this file")
+var dynpackage = flag.String("dynpackage", "main", "set Go package for -dynimport output")
+var dynlinker = flag.Bool("dynlinker", false, "record dynamic linker information in -dynimport mode")
 
-// These flags are for bootstrapping a new Go implementation,
-// to generate Go and C headers that match the data layout and
+// This flag is for bootstrapping a new Go implementation,
+// to generate Go types that match the data layout and
 // constant values used in the host's C libraries and system calls.
 var godefs = flag.Bool("godefs", false, "for bootstrap: write Go definitions for C file to standard output")
-var cdefs = flag.Bool("cdefs", false, "for bootstrap: write C definitions for C file to standard output")
+
 var objDir = flag.String("objdir", "", "object directory")
+var importPath = flag.String("importpath", "", "import path of package being built (for comments in generated files)")
+var exportHeader = flag.String("exportheader", "", "where to write export header if any exported functions")
 
 var gccgo = flag.Bool("gccgo", false, "generate files for use with gccgo")
 var gccgoprefix = flag.String("gccgoprefix", "", "-fgo-prefix option used with gccgo")
@@ -208,12 +213,7 @@
 		return
 	}
 
-	if *godefs && *cdefs {
-		fmt.Fprintf(os.Stderr, "cgo: cannot use -cdefs and -godefs together\n")
-		os.Exit(2)
-	}
-
-	if *godefs || *cdefs {
+	if *godefs {
 		// Generating definitions pulled from header files,
 		// to be checked into Go repositories.
 		// Line numbers are just noise.
@@ -305,14 +305,12 @@
 		p.Record(f)
 		if *godefs {
 			os.Stdout.WriteString(p.godefs(f, input))
-		} else if *cdefs {
-			os.Stdout.WriteString(p.cdefs(f, input))
 		} else {
 			p.writeOutput(f, input)
 		}
 	}
 
-	if !*godefs && !*cdefs {
+	if !*godefs {
 		p.writeDefs()
 	}
 	if nerrors > 0 {
diff --git a/third_party/gofrontend/libgo/go/cmd/cgo/out.go b/third_party/gofrontend/libgo/go/cmd/cgo/out.go
index d92bed9..90a7441 100644
--- a/third_party/gofrontend/libgo/go/cmd/cgo/out.go
+++ b/third_party/gofrontend/libgo/go/cmd/cgo/out.go
@@ -13,6 +13,7 @@
 	"go/ast"
 	"go/printer"
 	"go/token"
+	"io"
 	"os"
 	"sort"
 	"strings"
@@ -20,11 +21,17 @@
 
 var conf = printer.Config{Mode: printer.SourcePos, Tabwidth: 8}
 
-// writeDefs creates output files to be compiled by 6g, 6c, and gcc.
-// (The comments here say 6g and 6c but the code applies to the 8 and 5 tools too.)
+// writeDefs creates output files to be compiled by gc and gcc.
 func (p *Package) writeDefs() {
-	fgo2 := creat(*objDir + "_cgo_gotypes.go")
-	fc := creat(*objDir + "_cgo_defun.c")
+	var fgo2, fc io.Writer
+	f := creat(*objDir + "_cgo_gotypes.go")
+	defer f.Close()
+	fgo2 = f
+	if *gccgo {
+		f := creat(*objDir + "_cgo_defun.c")
+		defer f.Close()
+		fc = f
+	}
 	fm := creat(*objDir + "_cgo_main.c")
 
 	var gccgoInit bytes.Buffer
@@ -34,7 +41,7 @@
 		fmt.Fprintf(fflg, "_CGO_%s=%s\n", k, strings.Join(v, " "))
 		if k == "LDFLAGS" && !*gccgo {
 			for _, arg := range v {
-				fmt.Fprintf(fc, "#pragma cgo_ldflag %q\n", arg)
+				fmt.Fprintf(fgo2, "//go:cgo_ldflag %q\n", arg)
 			}
 		}
 	}
@@ -44,14 +51,17 @@
 	fmt.Fprintf(fm, "int main() { return 0; }\n")
 	if *importRuntimeCgo {
 		fmt.Fprintf(fm, "void crosscall2(void(*fn)(void*, int), void *a, int c) { }\n")
+		fmt.Fprintf(fm, "void _cgo_wait_runtime_init_done() { }\n")
 		fmt.Fprintf(fm, "char* _cgo_topofstack(void) { return (char*)0; }\n")
 	} else {
 		// If we're not importing runtime/cgo, we *are* runtime/cgo,
-		// which provides crosscall2.  We just need a prototype.
+		// which provides these functions.  We just need a prototype.
 		fmt.Fprintf(fm, "void crosscall2(void(*fn)(void*, int), void *a, int c);\n")
+		fmt.Fprintf(fm, "void _cgo_wait_runtime_init_done();\n")
 	}
 	fmt.Fprintf(fm, "void _cgo_allocate(void *a, int c) { }\n")
 	fmt.Fprintf(fm, "void _cgo_panic(void *a, int c) { }\n")
+	fmt.Fprintf(fm, "void _cgo_reginit(void) { }\n")
 
 	// Write second Go output: definitions of _C_xxx.
 	// In a separate file so that the import of "unsafe" does not
@@ -68,6 +78,13 @@
 	}
 	fmt.Fprintf(fgo2, "func _Cgo_ptr(ptr unsafe.Pointer) unsafe.Pointer { return ptr }\n\n")
 
+	if !*gccgo {
+		fmt.Fprintf(fgo2, "//go:linkname _Cgo_always_false runtime.cgoAlwaysFalse\n")
+		fmt.Fprintf(fgo2, "var _Cgo_always_false bool\n")
+		fmt.Fprintf(fgo2, "//go:linkname _Cgo_use runtime.cgoUse\n")
+		fmt.Fprintf(fgo2, "func _Cgo_use(interface{})\n")
+	}
+
 	typedefNames := make([]string, 0, len(typedef))
 	for name := range typedef {
 		typedefNames = append(typedefNames, name)
@@ -88,7 +105,6 @@
 	if *gccgo {
 		fmt.Fprint(fc, p.cPrologGccgo())
 	} else {
-		fmt.Fprint(fc, cProlog)
 		fmt.Fprint(fgo2, goProlog)
 	}
 
@@ -102,44 +118,44 @@
 		}
 
 		if !cVars[n.C] {
-			fmt.Fprintf(fm, "extern char %s[];\n", n.C)
-			fmt.Fprintf(fm, "void *_cgohack_%s = %s;\n\n", n.C, n.C)
-
-			if !*gccgo {
-				fmt.Fprintf(fc, "#pragma cgo_import_static %s\n", n.C)
+			if *gccgo {
+				fmt.Fprintf(fc, "extern byte *%s;\n", n.C)
+			} else {
+				fmt.Fprintf(fm, "extern char %s[];\n", n.C)
+				fmt.Fprintf(fm, "void *_cgohack_%s = %s;\n\n", n.C, n.C)
+				fmt.Fprintf(fgo2, "//go:linkname __cgo_%s %s\n", n.C, n.C)
+				fmt.Fprintf(fgo2, "//go:cgo_import_static %s\n", n.C)
+				fmt.Fprintf(fgo2, "var __cgo_%s byte\n", n.C)
 			}
-
-			fmt.Fprintf(fc, "extern byte *%s;\n", n.C)
-
 			cVars[n.C] = true
 		}
-		var amp string
+
 		var node ast.Node
 		if n.Kind == "var" {
-			amp = "&"
 			node = &ast.StarExpr{X: n.Type.Go}
 		} else if n.Kind == "fpvar" {
 			node = n.Type.Go
-			if *gccgo {
-				amp = "&"
-			}
 		} else {
 			panic(fmt.Errorf("invalid var kind %q", n.Kind))
 		}
 		if *gccgo {
 			fmt.Fprintf(fc, `extern void *%s __asm__("%s.%s");`, n.Mangle, gccgoSymbolPrefix, n.Mangle)
-			fmt.Fprintf(&gccgoInit, "\t%s = %s%s;\n", n.Mangle, amp, n.C)
-		} else {
-			fmt.Fprintf(fc, "#pragma dataflag NOPTR /* C pointer, not heap pointer */ \n")
-			fmt.Fprintf(fc, "void *·%s = %s%s;\n", n.Mangle, amp, n.C)
+			fmt.Fprintf(&gccgoInit, "\t%s = &%s;\n", n.Mangle, n.C)
+			fmt.Fprintf(fc, "\n")
 		}
-		fmt.Fprintf(fc, "\n")
 
 		fmt.Fprintf(fgo2, "var %s ", n.Mangle)
 		conf.Fprint(fgo2, fset, node)
+		if !*gccgo {
+			fmt.Fprintf(fgo2, " = (")
+			conf.Fprint(fgo2, fset, node)
+			fmt.Fprintf(fgo2, ")(unsafe.Pointer(&__cgo_%s))", n.C)
+		}
 		fmt.Fprintf(fgo2, "\n")
 	}
-	fmt.Fprintf(fc, "\n")
+	if *gccgo {
+		fmt.Fprintf(fc, "\n")
+	}
 
 	for _, key := range nameKeys(p.Name) {
 		n := p.Name[key]
@@ -152,14 +168,37 @@
 	for _, key := range nameKeys(p.Name) {
 		n := p.Name[key]
 		if n.FuncType != nil {
-			p.writeDefsFunc(fc, fgo2, n)
+			p.writeDefsFunc(fgo2, n)
 		}
 	}
 
+	fgcc := creat(*objDir + "_cgo_export.c")
+	fgcch := creat(*objDir + "_cgo_export.h")
 	if *gccgo {
-		p.writeGccgoExports(fgo2, fc, fm)
+		p.writeGccgoExports(fgo2, fm, fgcc, fgcch)
 	} else {
-		p.writeExports(fgo2, fc, fm)
+		p.writeExports(fgo2, fm, fgcc, fgcch)
+	}
+	if err := fgcc.Close(); err != nil {
+		fatalf("%s", err)
+	}
+	if err := fgcch.Close(); err != nil {
+		fatalf("%s", err)
+	}
+
+	if *exportHeader != "" && len(p.ExpFunc) > 0 {
+		fexp := creat(*exportHeader)
+		fgcch, err := os.Open(*objDir + "_cgo_export.h")
+		if err != nil {
+			fatalf("%s", err)
+		}
+		_, err = io.Copy(fexp, fgcch)
+		if err != nil {
+			fatalf("%s", err)
+		}
+		if err = fexp.Close(); err != nil {
+			fatalf("%s", err)
+		}
 	}
 
 	init := gccgoInit.String()
@@ -169,9 +208,6 @@
 		fmt.Fprint(fc, init)
 		fmt.Fprintln(fc, "}")
 	}
-
-	fgo2.Close()
-	fc.Close()
 }
 
 func dynimport(obj string) {
@@ -184,13 +220,15 @@
 		stdout = f
 	}
 
+	fmt.Fprintf(stdout, "package %s\n", *dynpackage)
+
 	if f, err := elf.Open(obj); err == nil {
 		if *dynlinker {
 			// Emit the cgo_dynamic_linker line.
 			if sec := f.Section(".interp"); sec != nil {
 				if data, err := sec.Data(); err == nil && len(data) > 1 {
 					// skip trailing \0 in data
-					fmt.Fprintf(stdout, "#pragma cgo_dynamic_linker %q\n", string(data[:len(data)-1]))
+					fmt.Fprintf(stdout, "//go:cgo_dynamic_linker %q\n", string(data[:len(data)-1]))
 				}
 			}
 		}
@@ -203,14 +241,14 @@
 			if s.Version != "" {
 				targ += "#" + s.Version
 			}
-			fmt.Fprintf(stdout, "#pragma cgo_import_dynamic %s %s %q\n", s.Name, targ, s.Library)
+			fmt.Fprintf(stdout, "//go:cgo_import_dynamic %s %s %q\n", s.Name, targ, s.Library)
 		}
 		lib, err := f.ImportedLibraries()
 		if err != nil {
 			fatalf("cannot load imported libraries from ELF file %s: %v", obj, err)
 		}
 		for _, l := range lib {
-			fmt.Fprintf(stdout, "#pragma cgo_import_dynamic _ _ %q\n", l)
+			fmt.Fprintf(stdout, "//go:cgo_import_dynamic _ _ %q\n", l)
 		}
 		return
 	}
@@ -224,14 +262,14 @@
 			if len(s) > 0 && s[0] == '_' {
 				s = s[1:]
 			}
-			fmt.Fprintf(stdout, "#pragma cgo_import_dynamic %s %s %q\n", s, s, "")
+			fmt.Fprintf(stdout, "//go:cgo_import_dynamic %s %s %q\n", s, s, "")
 		}
 		lib, err := f.ImportedLibraries()
 		if err != nil {
 			fatalf("cannot load imported libraries from Mach-O file %s: %v", obj, err)
 		}
 		for _, l := range lib {
-			fmt.Fprintf(stdout, "#pragma cgo_import_dynamic _ _ %q\n", l)
+			fmt.Fprintf(stdout, "//go:cgo_import_dynamic _ _ %q\n", l)
 		}
 		return
 	}
@@ -244,7 +282,7 @@
 		for _, s := range sym {
 			ss := strings.Split(s, ":")
 			name := strings.Split(ss[0], "@")[0]
-			fmt.Fprintf(stdout, "#pragma cgo_import_dynamic %s %s %q\n", name, ss[0], strings.ToLower(ss[1]))
+			fmt.Fprintf(stdout, "//go:cgo_import_dynamic %s %s %q\n", name, ss[0], strings.ToLower(ss[1]))
 		}
 		return
 	}
@@ -252,10 +290,10 @@
 	fatalf("cannot parse %s as ELF, Mach-O or PE", obj)
 }
 
-// Construct a gcc struct matching the 6c argument frame.
+// Construct a gcc struct matching the gc argument frame.
 // Assumes that in gcc, char is 1 byte, short 2 bytes, int 4 bytes, long long 8 bytes.
 // These assumptions are checked by the gccProlog.
-// Also assumes that 6c convention is to word-align the
+// Also assumes that gc convention is to word-align the
 // input and output parameters.
 func (p *Package) structType(n *Name) (string, int64) {
 	var buf bytes.Buffer
@@ -304,7 +342,7 @@
 	return buf.String(), off
 }
 
-func (p *Package) writeDefsFunc(fc, fgo2 *os.File, n *Name) {
+func (p *Package) writeDefsFunc(fgo2 io.Writer, n *Name) {
 	name := n.Go
 	gtype := n.FuncType.Go
 	void := gtype.Results == nil || len(gtype.Results.List) == 0
@@ -396,11 +434,11 @@
 		return
 	}
 
-	// C wrapper calls into gcc, passing a pointer to the argument frame.
-	fmt.Fprintf(fc, "#pragma cgo_import_static %s\n", cname)
-	fmt.Fprintf(fc, "void %s(void*);\n", cname)
-	fmt.Fprintf(fc, "#pragma dataflag NOPTR\n")
-	fmt.Fprintf(fc, "void *·%s = %s;\n", cname, cname)
+	// Wrapper calls into gcc, passing a pointer to the argument frame.
+	fmt.Fprintf(fgo2, "//go:cgo_import_static %s\n", cname)
+	fmt.Fprintf(fgo2, "//go:linkname __cgofn_%s %s\n", cname, cname)
+	fmt.Fprintf(fgo2, "var __cgofn_%s byte\n", cname)
+	fmt.Fprintf(fgo2, "var %s = unsafe.Pointer(&__cgofn_%s)\n", cname, cname)
 
 	nret := 0
 	if !void {
@@ -412,7 +450,6 @@
 	}
 
 	fmt.Fprint(fgo2, "\n")
-	fmt.Fprintf(fgo2, "var %s unsafe.Pointer\n", cname)
 	conf.Fprint(fgo2, fset, d)
 	fmt.Fprint(fgo2, " {\n")
 
@@ -428,16 +465,20 @@
 	if n.AddError {
 		prefix = "errno := "
 	}
-	fmt.Fprintf(fgo2, "\t%s_cgo_runtime_cgocall_errno(%s, %s)\n", prefix, cname, arg)
+	fmt.Fprintf(fgo2, "\t%s_cgo_runtime_cgocall(%s, %s)\n", prefix, cname, arg)
 	if n.AddError {
 		fmt.Fprintf(fgo2, "\tif errno != 0 { r2 = syscall.Errno(errno) }\n")
 	}
+	fmt.Fprintf(fgo2, "\tif _Cgo_always_false {\n")
+	for i := range d.Type.Params.List {
+		fmt.Fprintf(fgo2, "\t\t_Cgo_use(p%d)\n", i)
+	}
+	fmt.Fprintf(fgo2, "\t}\n")
 	fmt.Fprintf(fgo2, "\treturn\n")
 	fmt.Fprintf(fgo2, "}\n")
 }
 
-// writeOutput creates stubs for a specific source file to be compiled by 6g
-// (The comments here say 6g and 6c but the code applies to the 8 and 5 tools too.)
+// writeOutput creates stubs for a specific source file to be compiled by gc
 func (p *Package) writeOutput(f *File, srcfile string) {
 	base := srcfile
 	if strings.HasSuffix(base, ".go") {
@@ -454,7 +495,7 @@
 	fmt.Fprintf(fgo1, "// Created by cgo - DO NOT EDIT\n\n")
 	conf.Fprint(fgo1, fset, f.AST)
 
-	// While we process the vars and funcs, also write 6c and gcc output.
+	// While we process the vars and funcs, also write gcc output.
 	// Gcc output starts with the preamble.
 	fmt.Fprintf(fgcc, "%s\n", f.Preamble)
 	fmt.Fprintf(fgcc, "%s\n", gccProlog)
@@ -516,7 +557,7 @@
 	if n.AddError {
 		fmt.Fprintf(fgcc, "\terrno = 0;\n")
 	}
-	// We're trying to write a gcc struct that matches 6c/8c/5c's layout.
+	// We're trying to write a gcc struct that matches gc's layout.
 	// Use packed attribute to force no padding in this struct in case
 	// gcc has different packing requirements.
 	fmt.Fprintf(fgcc, "\t%s %v *a = v;\n", ctype, p.packedAttribute())
@@ -612,13 +653,13 @@
 }
 
 // packedAttribute returns host compiler struct attribute that will be
-// used to match 6c/8c/5c's struct layout. For example, on 386 Windows,
-// gcc wants to 8-align int64s, but 8c does not.
+// used to match gc's struct layout. For example, on 386 Windows,
+// gcc wants to 8-align int64s, but gc does not.
 // Use __gcc_struct__ to work around http://gcc.gnu.org/PR52991 on x86,
-// and http://golang.org/issue/5603.
+// and https://golang.org/issue/5603.
 func (p *Package) packedAttribute() string {
 	s := "__attribute__((__packed__"
-	if !strings.Contains(p.gccBaseCmd()[0], "clang") && (goarch == "amd64" || goarch == "386") {
+	if !p.GccIsClang && (goarch == "amd64" || goarch == "386") {
 		s += ", __gcc_struct__"
 	}
 	return s + "))"
@@ -626,23 +667,19 @@
 
 // Write out the various stubs we need to support functions exported
 // from Go so that they are callable from C.
-func (p *Package) writeExports(fgo2, fc, fm *os.File) {
-	fgcc := creat(*objDir + "_cgo_export.c")
-	fgcch := creat(*objDir + "_cgo_export.h")
-
-	fmt.Fprintf(fgcch, "/* Created by cgo - DO NOT EDIT. */\n")
-	fmt.Fprintf(fgcch, "%s\n", p.Preamble)
-	fmt.Fprintf(fgcch, "%s\n", p.gccExportHeaderProlog())
+func (p *Package) writeExports(fgo2, fm, fgcc, fgcch io.Writer) {
+	p.writeExportHeader(fgcch)
 
 	fmt.Fprintf(fgcc, "/* Created by cgo - DO NOT EDIT. */\n")
-	fmt.Fprintf(fgcc, "#include \"_cgo_export.h\"\n")
+	fmt.Fprintf(fgcc, "#include \"_cgo_export.h\"\n\n")
 
-	fmt.Fprintf(fgcc, "\nextern void crosscall2(void (*fn)(void *, int), void *, int);\n\n")
+	fmt.Fprintf(fgcc, "extern void crosscall2(void (*fn)(void *, int), void *, int);\n")
+	fmt.Fprintf(fgcc, "extern void _cgo_wait_runtime_init_done();\n\n")
 
 	for _, exp := range p.ExpFunc {
 		fn := exp.Func
 
-		// Construct a gcc struct matching the 6c argument and
+		// Construct a gcc struct matching the gc argument and
 		// result frame.  The gcc struct will be compiled with
 		// __attribute__((packed)) so all padding must be accounted
 		// for explicitly.
@@ -728,11 +765,16 @@
 				s += fmt.Sprintf("%s p%d", p.cgoType(atype).C, i)
 			})
 		s += ")"
+
+		if len(exp.Doc) > 0 {
+			fmt.Fprintf(fgcch, "\n%s", exp.Doc)
+		}
 		fmt.Fprintf(fgcch, "\nextern %s;\n", s)
 
 		fmt.Fprintf(fgcc, "extern void _cgoexp%s_%s(void *, int);\n", cPrefix, exp.ExpName)
 		fmt.Fprintf(fgcc, "\n%s\n", s)
 		fmt.Fprintf(fgcc, "{\n")
+		fmt.Fprintf(fgcc, "\t_cgo_wait_runtime_init_done();\n")
 		fmt.Fprintf(fgcc, "\t%s %v a;\n", ctype, p.packedAttribute())
 		if gccResult != "void" && (len(fntype.Results.List) > 1 || len(fntype.Results.List[0].Names) > 1) {
 			fmt.Fprintf(fgcc, "\t%s r;\n", gccResult)
@@ -758,20 +800,21 @@
 		}
 		fmt.Fprintf(fgcc, "}\n")
 
-		// Build the wrapper function compiled by 6c/8c
+		// Build the wrapper function compiled by gc.
 		goname := exp.Func.Name.Name
 		if fn.Recv != nil {
 			goname = "_cgoexpwrap" + cPrefix + "_" + fn.Recv.List[0].Names[0].Name + "_" + goname
 		}
-		fmt.Fprintf(fc, "#pragma cgo_export_dynamic %s\n", goname)
-		fmt.Fprintf(fc, "extern void ·%s();\n\n", goname)
-		fmt.Fprintf(fc, "#pragma cgo_export_static _cgoexp%s_%s\n", cPrefix, exp.ExpName)
-		fmt.Fprintf(fc, "#pragma textflag 7\n") // no split stack, so no use of m or g
-		fmt.Fprintf(fc, "void\n")
-		fmt.Fprintf(fc, "_cgoexp%s_%s(void *a, int32 n)\n", cPrefix, exp.ExpName)
-		fmt.Fprintf(fc, "{\n")
-		fmt.Fprintf(fc, "\truntime·cgocallback(·%s, a, n);\n", goname)
-		fmt.Fprintf(fc, "}\n")
+		fmt.Fprintf(fgo2, "//go:cgo_export_dynamic %s\n", goname)
+		fmt.Fprintf(fgo2, "//go:linkname _cgoexp%s_%s _cgoexp%s_%s\n", cPrefix, exp.ExpName, cPrefix, exp.ExpName)
+		fmt.Fprintf(fgo2, "//go:cgo_export_static _cgoexp%s_%s\n", cPrefix, exp.ExpName)
+		fmt.Fprintf(fgo2, "//go:nosplit\n") // no split stack, so no use of m or g
+		fmt.Fprintf(fgo2, "//go:norace\n")  // must not have race detector calls inserted
+		fmt.Fprintf(fgo2, "func _cgoexp%s_%s(a unsafe.Pointer, n int32) {", cPrefix, exp.ExpName)
+		fmt.Fprintf(fgo2, "\tfn := %s\n", goname)
+		// The indirect here is converting from a Go function pointer to a C function pointer.
+		fmt.Fprintf(fgo2, "\t_cgo_runtime_cgocallback(**(**unsafe.Pointer)(unsafe.Pointer(&fn)), a, uintptr(n));\n")
+		fmt.Fprintf(fgo2, "}\n")
 
 		fmt.Fprintf(fm, "int _cgoexp%s_%s;\n", cPrefix, exp.ExpName)
 
@@ -814,23 +857,20 @@
 			fmt.Fprint(fgo2, "}\n")
 		}
 	}
+
+	fmt.Fprintf(fgcch, "%s", gccExportHeaderEpilog)
 }
 
 // Write out the C header allowing C code to call exported gccgo functions.
-func (p *Package) writeGccgoExports(fgo2, fc, fm *os.File) {
-	fgcc := creat(*objDir + "_cgo_export.c")
-	fgcch := creat(*objDir + "_cgo_export.h")
-
+func (p *Package) writeGccgoExports(fgo2, fm, fgcc, fgcch io.Writer) {
 	gccgoSymbolPrefix := p.gccgoSymbolPrefix()
 
-	fmt.Fprintf(fgcch, "/* Created by cgo - DO NOT EDIT. */\n")
-	fmt.Fprintf(fgcch, "%s\n", p.Preamble)
-	fmt.Fprintf(fgcch, "%s\n", p.gccExportHeaderProlog())
+	p.writeExportHeader(fgcch)
 
 	fmt.Fprintf(fgcc, "/* Created by cgo - DO NOT EDIT. */\n")
 	fmt.Fprintf(fgcc, "#include \"_cgo_export.h\"\n")
 
-	fmt.Fprintf(fm, "#include \"_cgo_export.h\"\n")
+	fmt.Fprintf(fgcc, "%s\n", gccgoExportFileProlog)
 
 	for _, exp := range p.ExpFunc {
 		fn := exp.Func
@@ -851,6 +891,7 @@
 				})
 		default:
 			// Declare a result struct.
+			fmt.Fprintf(fgcch, "\n/* Return type for %s */\n", exp.ExpName)
 			fmt.Fprintf(fgcch, "struct %s_result {\n", exp.ExpName)
 			forFieldList(fntype.Results,
 				func(i int, atype ast.Expr) {
@@ -880,6 +921,10 @@
 		fmt.Fprintf(cdeclBuf, ")")
 		cParams := cdeclBuf.String()
 
+		if len(exp.Doc) > 0 {
+			fmt.Fprintf(fgcch, "\n%s", exp.Doc)
+		}
+
 		// We need to use a name that will be exported by the
 		// Go code; otherwise gccgo will make it static and we
 		// will not be able to link against it from the C
@@ -900,6 +945,8 @@
 
 		fmt.Fprint(fgcc, "\n")
 		fmt.Fprintf(fgcc, "%s %s %s {\n", cRet, exp.ExpName, cParams)
+		fmt.Fprintf(fgcc, "\tif(_cgo_wait_runtime_init_done)\n")
+		fmt.Fprintf(fgcc, "\t\t_cgo_wait_runtime_init_done();\n")
 		fmt.Fprint(fgcc, "\t")
 		if resultCount > 0 {
 			fmt.Fprint(fgcc, "return ")
@@ -919,7 +966,8 @@
 		fmt.Fprint(fgcc, "}\n")
 
 		// Dummy declaration for _cgo_main.c
-		fmt.Fprintf(fm, "%s %s %s {}\n", cRet, goName, cParams)
+		fmt.Fprintf(fm, `char %s[1] __asm__("%s.%s");`, goName, gccgoSymbolPrefix, goName)
+		fmt.Fprint(fm, "\n")
 
 		// For gccgo we use a wrapper function in Go, in order
 		// to call CgocallBack and CgocallBackDone.
@@ -974,6 +1022,24 @@
 		fmt.Fprint(fgo2, ")\n")
 		fmt.Fprint(fgo2, "}\n")
 	}
+
+	fmt.Fprintf(fgcch, "%s", gccExportHeaderEpilog)
+}
+
+// writeExportHeader writes out the start of the _cgo_export.h file.
+func (p *Package) writeExportHeader(fgcch io.Writer) {
+	fmt.Fprintf(fgcch, "/* Created by \"go tool cgo\" - DO NOT EDIT. */\n\n")
+	pkg := *importPath
+	if pkg == "" {
+		pkg = p.PackagePath
+	}
+	fmt.Fprintf(fgcch, "/* package %s */\n\n", pkg)
+
+	fmt.Fprintf(fgcch, "/* Start of preamble from import \"C\" comments.  */\n\n")
+	fmt.Fprintf(fgcch, "%s\n", p.Preamble)
+	fmt.Fprintf(fgcch, "\n/* End of preamble from import \"C\" comments.  */\n\n")
+
+	fmt.Fprintf(fgcch, "%s\n", p.gccExportHeaderProlog())
 }
 
 // Return the package prefix when using gccgo.
@@ -1164,60 +1230,39 @@
 void *_CMalloc(size_t);
 `
 
-const cProlog = `
-#include "runtime.h"
-#include "cgocall.h"
-#include "textflag.h"
-
-#pragma dataflag NOPTR
-static void *cgocall_errno = runtime·cgocall_errno;
-#pragma dataflag NOPTR
-void *·_cgo_runtime_cgocall_errno = &cgocall_errno;
-
-#pragma dataflag NOPTR
-static void *runtime_gostring = runtime·gostring;
-#pragma dataflag NOPTR
-void *·_cgo_runtime_gostring = &runtime_gostring;
-
-#pragma dataflag NOPTR
-static void *runtime_gostringn = runtime·gostringn;
-#pragma dataflag NOPTR
-void *·_cgo_runtime_gostringn = &runtime_gostringn;
-
-#pragma dataflag NOPTR
-static void *runtime_gobytes = runtime·gobytes;
-#pragma dataflag NOPTR
-void *·_cgo_runtime_gobytes = &runtime_gobytes;
-
-#pragma dataflag NOPTR
-static void *runtime_cmalloc = runtime·cmalloc;
-#pragma dataflag NOPTR
-void *·_cgo_runtime_cmalloc = &runtime_cmalloc;
-
-void ·_Cerrno(void*, int32);
-`
-
 const goProlog = `
-var _cgo_runtime_cgocall_errno func(unsafe.Pointer, uintptr) int32
-var _cgo_runtime_cmalloc func(uintptr) unsafe.Pointer
+//go:linkname _cgo_runtime_cgocall runtime.cgocall
+func _cgo_runtime_cgocall(unsafe.Pointer, uintptr) int32
+
+//go:linkname _cgo_runtime_cmalloc runtime.cmalloc
+func _cgo_runtime_cmalloc(uintptr) unsafe.Pointer
+
+//go:linkname _cgo_runtime_cgocallback runtime.cgocallback
+func _cgo_runtime_cgocallback(unsafe.Pointer, unsafe.Pointer, uintptr)
 `
 
 const goStringDef = `
-var _cgo_runtime_gostring func(*_Ctype_char) string
+//go:linkname _cgo_runtime_gostring runtime.gostring
+func _cgo_runtime_gostring(*_Ctype_char) string
+
 func _Cfunc_GoString(p *_Ctype_char) string {
 	return _cgo_runtime_gostring(p)
 }
 `
 
 const goStringNDef = `
-var _cgo_runtime_gostringn func(*_Ctype_char, int) string
+//go:linkname _cgo_runtime_gostringn runtime.gostringn
+func _cgo_runtime_gostringn(*_Ctype_char, int) string
+
 func _Cfunc_GoStringN(p *_Ctype_char, l _Ctype_int) string {
 	return _cgo_runtime_gostringn(p, int(l))
 }
 `
 
 const goBytesDef = `
-var _cgo_runtime_gobytes func(unsafe.Pointer, int) []byte
+//go:linkname _cgo_runtime_gobytes runtime.gobytes
+func _cgo_runtime_gobytes(unsafe.Pointer, int) []byte
+
 func _Cfunc_GoBytes(p unsafe.Pointer, l _Ctype_int) []byte {
 	return _cgo_runtime_gobytes(p, int(l))
 }
@@ -1310,6 +1355,11 @@
 }
 
 const gccExportHeaderProlog = `
+/* Start of boilerplate cgo prologue.  */
+
+#ifndef GO_CGO_PROLOGUE_H
+#define GO_CGO_PROLOGUE_H
+
 typedef signed char GoInt8;
 typedef unsigned char GoUint8;
 typedef short GoInt16;
@@ -1326,9 +1376,44 @@
 typedef __complex float GoComplex64;
 typedef __complex double GoComplex128;
 
+// static assertion to make sure the file is being used on architecture
+// at least with matching size of GoInt.
+typedef char _check_for_GOINTBITS_bit_pointer_matching_GoInt[sizeof(void*)==GOINTBITS/8 ? 1:-1];
+
 typedef struct { char *p; GoInt n; } GoString;
 typedef void *GoMap;
 typedef void *GoChan;
 typedef struct { void *t; void *v; } GoInterface;
 typedef struct { void *data; GoInt len; GoInt cap; } GoSlice;
+
+#endif
+
+/* End of boilerplate cgo prologue.  */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+`
+
+// gccExportHeaderEpilog goes at the end of the generated header file.
+const gccExportHeaderEpilog = `
+#ifdef __cplusplus
+}
+#endif
+`
+
+// gccgoExportFileProlog is written to the _cgo_export.c file when
+// using gccgo.
+// We use weak declarations, and test the addresses, so that this code
+// works with older versions of gccgo.
+const gccgoExportFileProlog = `
+extern _Bool runtime_iscgo __attribute__ ((weak));
+
+static void GoInit(void) __attribute__ ((constructor));
+static void GoInit(void) {
+	if(&runtime_iscgo)
+		runtime_iscgo = 1;
+}
+
+extern void _cgo_wait_runtime_init_done() __attribute__ ((weak));
 `
diff --git a/third_party/gofrontend/libgo/go/cmd/cgo/util.go b/third_party/gofrontend/libgo/go/cmd/cgo/util.go
index 4e7800d..3adb8e8 100644
--- a/third_party/gofrontend/libgo/go/cmd/cgo/util.go
+++ b/third_party/gofrontend/libgo/go/cmd/cgo/util.go
@@ -55,7 +55,7 @@
 	fmt.Fprintf(os.Stderr, "\n")
 }
 
-// isName returns true if s is a valid C identifier
+// isName reports whether s is a valid C identifier
 func isName(s string) bool {
 	for i, v := range s {
 		if v != '_' && (v < 'A' || v > 'Z') && (v < 'a' || v > 'z') && (v < '0' || v > '9') {
diff --git a/third_party/gofrontend/libgo/go/cmd/go/alldocs.go b/third_party/gofrontend/libgo/go/cmd/go/alldocs.go
new file mode 100644
index 0000000..1134997
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/cmd/go/alldocs.go
@@ -0,0 +1,1481 @@
+// Copyright 2011 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.
+
+// DO NOT EDIT THIS FILE. GENERATED BY mkalldocs.sh.
+// Edit the documentation in other files and rerun mkalldocs.sh to generate this one.
+
+/*
+Go is a tool for managing Go source code.
+
+Usage:
+
+	go command [arguments]
+
+The commands are:
+
+	build       compile packages and dependencies
+	clean       remove object files
+	doc         show documentation for package or symbol
+	env         print Go environment information
+	fix         run go tool fix on packages
+	fmt         run gofmt on package sources
+	generate    generate Go files by processing source
+	get         download and install packages and dependencies
+	install     compile and install packages and dependencies
+	list        list packages
+	run         compile and run Go program
+	test        test packages
+	tool        run specified go tool
+	version     print Go version
+	vet         run go tool vet on packages
+
+Use "go help [command]" for more information about a command.
+
+Additional help topics:
+
+	c           calling between Go and C
+	buildmode   description of build modes
+	filetype    file types
+	gopath      GOPATH environment variable
+	environment environment variables
+	importpath  import path syntax
+	packages    description of package lists
+	testflag    description of testing flags
+	testfunc    description of testing functions
+
+Use "go help [topic]" for more information about that topic.
+
+
+Compile packages and dependencies
+
+Usage:
+
+	go build [-o output] [-i] [build flags] [packages]
+
+Build compiles the packages named by the import paths,
+along with their dependencies, but it does not install the results.
+
+If the arguments to build are a list of .go files, build treats
+them as a list of source files specifying a single package.
+
+When compiling a single main package, build writes
+the resulting executable to an output file named after
+the first source file ('go build ed.go rx.go' writes 'ed' or 'ed.exe')
+or the source code directory ('go build unix/sam' writes 'sam' or 'sam.exe').
+The '.exe' suffix is added when writing a Windows executable.
+
+When compiling multiple packages or a single non-main package,
+build compiles the packages but discards the resulting object,
+serving only as a check that the packages can be built.
+
+The -o flag, only allowed when compiling a single package,
+forces build to write the resulting executable or object
+to the named output file, instead of the default behavior described
+in the last two paragraphs.
+
+The -i flag installs the packages that are dependencies of the target.
+
+The build flags are shared by the build, clean, get, install, list, run,
+and test commands:
+
+	-a
+		force rebuilding of packages that are already up-to-date.
+	-n
+		print the commands but do not run them.
+	-p n
+		the number of builds that can be run in parallel.
+		The default is the number of CPUs available, except
+		on darwin/arm which defaults to 1.
+	-race
+		enable data race detection.
+		Supported only on linux/amd64, freebsd/amd64, darwin/amd64 and windows/amd64.
+	-v
+		print the names of packages as they are compiled.
+	-work
+		print the name of the temporary work directory and
+		do not delete it when exiting.
+	-x
+		print the commands.
+
+	-asmflags 'flag list'
+		arguments to pass on each go tool asm invocation.
+	-buildmode mode
+		build mode to use. See 'go help buildmode' for more.
+	-compiler name
+		name of compiler to use, as in runtime.Compiler (gccgo or gc).
+	-gccgoflags 'arg list'
+		arguments to pass on each gccgo compiler/linker invocation.
+	-gcflags 'arg list'
+		arguments to pass on each go tool compile invocation.
+	-installsuffix suffix
+		a suffix to use in the name of the package installation directory,
+		in order to keep output separate from default builds.
+		If using the -race flag, the install suffix is automatically set to race
+		or, if set explicitly, has _race appended to it.  Using a -buildmode
+		option that requires non-default compile flags has a similar effect.
+	-ldflags 'flag list'
+		arguments to pass on each go tool link invocation.
+	-linkshared
+		link against shared libraries previously created with
+		-buildmode=shared
+	-pkgdir dir
+		install and load all packages from dir instead of the usual locations.
+		For example, when building with a non-standard configuration,
+		use -pkgdir to keep generated packages in a separate location.
+	-tags 'tag list'
+		a list of build tags to consider satisfied during the build.
+		For more information about build tags, see the description of
+		build constraints in the documentation for the go/build package.
+	-toolexec 'cmd args'
+		a program to use to invoke toolchain programs like vet and asm.
+		For example, instead of running asm, the go command will run
+		'cmd args /path/to/asm <arguments for asm>'.
+
+The list flags accept a space-separated list of strings. To embed spaces
+in an element in the list, surround it with either single or double quotes.
+
+For more about specifying packages, see 'go help packages'.
+For more about where packages and binaries are installed,
+run 'go help gopath'.
+For more about calling between Go and C/C++, run 'go help c'.
+
+Note: Build adheres to certain conventions such as those described
+by 'go help gopath'. Not all projects can follow these conventions,
+however. Installations that have their own conventions or that use
+a separate software build system may choose to use lower-level
+invocations such as 'go tool compile' and 'go tool link' to avoid
+some of the overheads and design decisions of the build tool.
+
+See also: go install, go get, go clean.
+
+
+Remove object files
+
+Usage:
+
+	go clean [-i] [-r] [-n] [-x] [build flags] [packages]
+
+Clean removes object files from package source directories.
+The go command builds most objects in a temporary directory,
+so go clean is mainly concerned with object files left by other
+tools or by manual invocations of go build.
+
+Specifically, clean removes the following files from each of the
+source directories corresponding to the import paths:
+
+	_obj/            old object directory, left from Makefiles
+	_test/           old test directory, left from Makefiles
+	_testmain.go     old gotest file, left from Makefiles
+	test.out         old test log, left from Makefiles
+	build.out        old test log, left from Makefiles
+	*.[568ao]        object files, left from Makefiles
+
+	DIR(.exe)        from go build
+	DIR.test(.exe)   from go test -c
+	MAINFILE(.exe)   from go build MAINFILE.go
+	*.so             from SWIG
+
+In the list, DIR represents the final path element of the
+directory, and MAINFILE is the base name of any Go source
+file in the directory that is not included when building
+the package.
+
+The -i flag causes clean to remove the corresponding installed
+archive or binary (what 'go install' would create).
+
+The -n flag causes clean to print the remove commands it would execute,
+but not run them.
+
+The -r flag causes clean to be applied recursively to all the
+dependencies of the packages named by the import paths.
+
+The -x flag causes clean to print remove commands as it executes them.
+
+For more about build flags, see 'go help build'.
+
+For more about specifying packages, see 'go help packages'.
+
+
+Show documentation for package or symbol
+
+Usage:
+
+	go doc [-u] [-c] [package|[package.]symbol[.method]]
+
+Doc prints the documentation comments associated with the item identified by its
+arguments (a package, const, func, type, var, or method) followed by a one-line
+summary of each of the first-level items "under" that item (package-level
+declarations for a package, methods for a type, etc.).
+
+Doc accepts zero, one, or two arguments.
+
+Given no arguments, that is, when run as
+
+	go doc
+
+it prints the package documentation for the package in the current directory.
+If the package is a command (package main), the exported symbols of the package
+are elided from the presentation unless the -cmd flag is provided.
+
+When run with one argument, the argument is treated as a Go-syntax-like
+representation of the item to be documented. What the argument selects depends
+on what is installed in GOROOT and GOPATH, as well as the form of the argument,
+which is schematically one of these:
+
+	go doc <pkg>
+	go doc <sym>[.<method>]
+	go doc [<pkg>].<sym>[.<method>]
+
+The first item in this list matched by the argument is the one whose
+documentation is printed. (See the examples below.) For packages, the order of
+scanning is determined lexically, but the GOROOT tree is always scanned before
+GOPATH.
+
+If there is no package specified or matched, the package in the current
+directory is selected, so "go doc Foo" shows the documentation for symbol Foo in
+the current package.
+
+The package path must be either a qualified path or a proper suffix of a
+path. The go tool's usual package mechanism does not apply: package path
+elements like . and ... are not implemented by go doc.
+
+When run with two arguments, the first must be a full package path (not just a
+suffix), and the second is a symbol or symbol and method; this is similar to the
+syntax accepted by godoc:
+
+	go doc <pkg> <sym>[.<method>]
+
+In all forms, when matching symbols, lower-case letters in the argument match
+either case but upper-case letters match exactly. This means that there may be
+multiple matches of a lower-case argument in a package if different symbols have
+different cases. If this occurs, documentation for all matches is printed.
+
+Examples:
+	go doc
+		Show documentation for current package.
+	go doc Foo
+		Show documentation for Foo in the current package.
+		(Foo starts with a capital letter so it cannot match
+		a package path.)
+	go doc encoding/json
+		Show documentation for the encoding/json package.
+	go doc json
+		Shorthand for encoding/json.
+	go doc json.Number (or go doc json.number)
+		Show documentation and method summary for json.Number.
+	go doc json.Number.Int64 (or go doc json.number.int64)
+		Show documentation for json.Number's Int64 method.
+	go doc cmd/doc
+		Show package docs for the doc command.
+	go doc -cmd cmd/doc
+		Show package docs and exported symbols within the doc command.
+	go doc template.new
+		Show documentation for html/template's New function.
+		(html/template is lexically before text/template)
+	go doc text/template.new # One argument
+		Show documentation for text/template's New function.
+	go doc text/template new # Two arguments
+		Show documentation for text/template's New function.
+
+Flags:
+	-c
+		Respect case when matching symbols.
+	-cmd
+		Treat a command (package main) like a regular package.
+		Otherwise package main's exported symbols are hidden
+		when showing the package's top-level documentation.
+	-u
+		Show documentation for unexported as well as exported
+		symbols and methods.
+
+
+Print Go environment information
+
+Usage:
+
+	go env [var ...]
+
+Env prints Go environment information.
+
+By default env prints information as a shell script
+(on Windows, a batch file).  If one or more variable
+names is given as arguments,  env prints the value of
+each named variable on its own line.
+
+
+Run go tool fix on packages
+
+Usage:
+
+	go fix [packages]
+
+Fix runs the Go fix command on the packages named by the import paths.
+
+For more about fix, see 'go doc cmd/fix'.
+For more about specifying packages, see 'go help packages'.
+
+To run fix with specific options, run 'go tool fix'.
+
+See also: go fmt, go vet.
+
+
+Run gofmt on package sources
+
+Usage:
+
+	go fmt [-n] [-x] [packages]
+
+Fmt runs the command 'gofmt -l -w' on the packages named
+by the import paths.  It prints the names of the files that are modified.
+
+For more about gofmt, see 'go doc cmd/gofmt'.
+For more about specifying packages, see 'go help packages'.
+
+The -n flag prints commands that would be executed.
+The -x flag prints commands as they are executed.
+
+To run gofmt with specific options, run gofmt itself.
+
+See also: go fix, go vet.
+
+
+Generate Go files by processing source
+
+Usage:
+
+	go generate [-run regexp] [file.go... | packages]
+
+Generate runs commands described by directives within existing
+files. Those commands can run any process but the intent is to
+create or update Go source files, for instance by running yacc.
+
+Go generate is never run automatically by go build, go get, go test,
+and so on. It must be run explicitly.
+
+Go generate scans the file for directives, which are lines of
+the form,
+
+	//go:generate command argument...
+
+(note: no leading spaces and no space in "//go") where command
+is the generator to be run, corresponding to an executable file
+that can be run locally. It must either be in the shell path
+(gofmt), a fully qualified path (/usr/you/bin/mytool), or a
+command alias, described below.
+
+Note that go generate does not parse the file, so lines that look
+like directives in comments or multiline strings will be treated
+as directives.
+
+The arguments to the directive are space-separated tokens or
+double-quoted strings passed to the generator as individual
+arguments when it is run.
+
+Quoted strings use Go syntax and are evaluated before execution; a
+quoted string appears as a single argument to the generator.
+
+Go generate sets several variables when it runs the generator:
+
+	$GOARCH
+		The execution architecture (arm, amd64, etc.)
+	$GOOS
+		The execution operating system (linux, windows, etc.)
+	$GOFILE
+		The base name of the file.
+	$GOLINE
+		The line number of the directive in the source file.
+	$GOPACKAGE
+		The name of the package of the file containing the directive.
+	$DOLLAR
+		A dollar sign.
+
+Other than variable substitution and quoted-string evaluation, no
+special processing such as "globbing" is performed on the command
+line.
+
+As a last step before running the command, any invocations of any
+environment variables with alphanumeric names, such as $GOFILE or
+$HOME, are expanded throughout the command line. The syntax for
+variable expansion is $NAME on all operating systems.  Due to the
+order of evaluation, variables are expanded even inside quoted
+strings. If the variable NAME is not set, $NAME expands to the
+empty string.
+
+A directive of the form,
+
+	//go:generate -command xxx args...
+
+specifies, for the remainder of this source file only, that the
+string xxx represents the command identified by the arguments. This
+can be used to create aliases or to handle multiword generators.
+For example,
+
+	//go:generate -command yacc go tool yacc
+
+specifies that the command "yacc" represents the generator
+"go tool yacc".
+
+Generate processes packages in the order given on the command line,
+one at a time. If the command line lists .go files, they are treated
+as a single package. Within a package, generate processes the
+source files in a package in file name order, one at a time. Within
+a source file, generate runs generators in the order they appear
+in the file, one at a time.
+
+If any generator returns an error exit status, "go generate" skips
+all further processing for that package.
+
+The generator is run in the package's source directory.
+
+Go generate accepts one specific flag:
+
+	-run=""
+		if non-empty, specifies a regular expression to select
+		directives whose full original source text (excluding
+		any trailing spaces and final newline) matches the
+		expression.
+
+It also accepts the standard build flags -v, -n, and -x.
+The -v flag prints the names of packages and files as they are
+processed.
+The -n flag prints commands that would be executed.
+The -x flag prints commands as they are executed.
+
+For more about specifying packages, see 'go help packages'.
+
+
+Download and install packages and dependencies
+
+Usage:
+
+	go get [-d] [-f] [-fix] [-insecure] [-t] [-u] [build flags] [packages]
+
+Get downloads and installs the packages named by the import paths,
+along with their dependencies.
+
+The -d flag instructs get to stop after downloading the packages; that is,
+it instructs get not to install the packages.
+
+The -f flag, valid only when -u is set, forces get -u not to verify that
+each package has been checked out from the source control repository
+implied by its import path. This can be useful if the source is a local fork
+of the original.
+
+The -fix flag instructs get to run the fix tool on the downloaded packages
+before resolving dependencies or building the code.
+
+The -insecure flag permits fetching from repositories and resolving
+custom domains using insecure schemes such as HTTP. Use with caution.
+
+The -t flag instructs get to also download the packages required to build
+the tests for the specified packages.
+
+The -u flag instructs get to use the network to update the named packages
+and their dependencies.  By default, get uses the network to check out
+missing packages but does not use it to look for updates to existing packages.
+
+Get also accepts build flags to control the installation. See 'go help build'.
+
+When checking out or updating a package, get looks for a branch or tag
+that matches the locally installed version of Go. The most important
+rule is that if the local installation is running version "go1", get
+searches for a branch or tag named "go1". If no such version exists it
+retrieves the most recent version of the package.
+
+If the vendoring experiment is enabled (see 'go help gopath'),
+then when go get checks out or updates a Git repository,
+it also updates any git submodules referenced by the repository.
+
+For more about specifying packages, see 'go help packages'.
+
+For more about how 'go get' finds source code to
+download, see 'go help importpath'.
+
+See also: go build, go install, go clean.
+
+
+Compile and install packages and dependencies
+
+Usage:
+
+	go install [build flags] [packages]
+
+Install compiles and installs the packages named by the import paths,
+along with their dependencies.
+
+For more about the build flags, see 'go help build'.
+For more about specifying packages, see 'go help packages'.
+
+See also: go build, go get, go clean.
+
+
+List packages
+
+Usage:
+
+	go list [-e] [-f format] [-json] [build flags] [packages]
+
+List lists the packages named by the import paths, one per line.
+
+The default output shows the package import path:
+
+    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
+'{{.ImportPath}}'. The struct being passed to the template is:
+
+    type Package struct {
+        Dir           string // directory containing package sources
+        ImportPath    string // import path of package in dir
+        ImportComment string // path in import comment on package statement
+        Name          string // package name
+        Doc           string // package documentation string
+        Target        string // install path
+        Shlib         string // the shared library that contains this package (only set when -linkshared)
+        Goroot        bool   // is this package in the Go root?
+        Standard      bool   // is this package part of the standard Go library?
+        Stale         bool   // would 'go install' do anything for this package?
+        Root          string // Go root or Go path dir containing this package
+
+        // Source files
+        GoFiles        []string // .go source files (excluding CgoFiles, TestGoFiles, XTestGoFiles)
+        CgoFiles       []string // .go sources files that import "C"
+        IgnoredGoFiles []string // .go sources ignored due to build constraints
+        CFiles         []string // .c source files
+        CXXFiles       []string // .cc, .cxx and .cpp source files
+        MFiles         []string // .m source files
+        HFiles         []string // .h, .hh, .hpp and .hxx source files
+        SFiles         []string // .s source files
+        SwigFiles      []string // .swig files
+        SwigCXXFiles   []string // .swigcxx files
+        SysoFiles      []string // .syso object files to add to archive
+
+        // Cgo directives
+        CgoCFLAGS    []string // cgo: flags for C compiler
+        CgoCPPFLAGS  []string // cgo: flags for C preprocessor
+        CgoCXXFLAGS  []string // cgo: flags for C++ compiler
+        CgoLDFLAGS   []string // cgo: flags for linker
+        CgoPkgConfig []string // cgo: pkg-config names
+
+        // Dependency information
+        Imports []string // import paths used by this package
+        Deps    []string // all (recursively) imported dependencies
+
+        // Error information
+        Incomplete bool            // this package or a dependency has an error
+        Error      *PackageError   // error loading package
+        DepsErrors []*PackageError // errors loading dependencies
+
+        TestGoFiles  []string // _test.go files in package
+        TestImports  []string // imports from TestGoFiles
+        XTestGoFiles []string // _test.go files outside package
+        XTestImports []string // imports from XTestGoFiles
+    }
+
+The template function "join" calls strings.Join.
+
+The template function "context" returns the build context, defined as:
+
+	type Context struct {
+		GOARCH        string   // target architecture
+		GOOS          string   // target operating system
+		GOROOT        string   // Go root
+		GOPATH        string   // Go path
+		CgoEnabled    bool     // whether cgo can be used
+		UseAllFiles   bool     // use files regardless of +build lines, file names
+		Compiler      string   // compiler to assume when computing target paths
+		BuildTags     []string // build constraints to match in +build lines
+		ReleaseTags   []string // releases the current release is compatible with
+		InstallSuffix string   // suffix to use in the name of the install dir
+	}
+
+For more information about the meaning of these fields see the documentation
+for the go/build package's Context type.
+
+The -json flag causes the package data to be printed in JSON format
+instead of using the template format.
+
+The -e flag changes the handling of erroneous packages, those that
+cannot be found or are malformed.  By default, the list command
+prints an error to standard error for each erroneous package and
+omits the packages from consideration during the usual printing.
+With the -e flag, the list command never prints errors to standard
+error and instead processes the erroneous packages with the usual
+printing.  Erroneous packages will have a non-empty ImportPath and
+a non-nil Error field; other information may or may not be missing
+(zeroed).
+
+For more about build flags, see 'go help build'.
+
+For more about specifying packages, see 'go help packages'.
+
+
+Compile and run Go program
+
+Usage:
+
+	go run [build flags] [-exec xprog] gofiles... [arguments...]
+
+Run compiles and runs the main package comprising the named Go source files.
+A Go source file is defined to be a file ending in a literal ".go" suffix.
+
+By default, 'go run' runs the compiled binary directly: 'a.out arguments...'.
+If the -exec flag is given, 'go run' invokes the binary using xprog:
+	'xprog a.out arguments...'.
+If the -exec flag is not given, GOOS or GOARCH is different from the system
+default, and a program named go_$GOOS_$GOARCH_exec can be found
+on the current search path, 'go run' invokes the binary using that program,
+for example 'go_nacl_386_exec a.out arguments...'. This allows execution of
+cross-compiled programs when a simulator or other execution method is
+available.
+
+For more about build flags, see 'go help build'.
+
+See also: go build.
+
+
+Test packages
+
+Usage:
+
+	go test [-c] [-i] [build and test flags] [packages] [flags for test binary]
+
+'Go test' automates testing the packages named by the import paths.
+It prints a summary of the test results in the format:
+
+	ok   archive/tar   0.011s
+	FAIL archive/zip   0.022s
+	ok   compress/gzip 0.033s
+	...
+
+followed by detailed output for each failed package.
+
+'Go test' recompiles each package along with any files with names matching
+the file pattern "*_test.go".
+Files whose names begin with "_" (including "_test.go") or "." are ignored.
+These additional files can contain test functions, benchmark functions, and
+example functions.  See 'go help testfunc' for more.
+Each listed package causes the execution of a separate test binary.
+
+Test files that declare a package with the suffix "_test" will be compiled as a
+separate package, and then linked and run with the main test binary.
+
+By default, go test needs no arguments.  It compiles and tests the package
+with source in the current directory, including tests, and runs the tests.
+
+The package is built in a temporary directory so it does not interfere with the
+non-test installation.
+
+In addition to the build flags, the flags handled by 'go test' itself are:
+
+	-c
+		Compile the test binary to pkg.test but do not run it
+		(where pkg is the last element of the package's import path).
+		The file name can be changed with the -o flag.
+
+	-exec xprog
+	    Run the test binary using xprog. The behavior is the same as
+	    in 'go run'. See 'go help run' for details.
+
+	-i
+	    Install packages that are dependencies of the test.
+	    Do not run the test.
+
+	-o file
+		Compile the test binary to the named file.
+		The test still runs (unless -c or -i is specified).
+
+The test binary also accepts flags that control execution of the test; these
+flags are also accessible by 'go test'. See 'go help testflag' for details.
+
+If the test binary needs any other flags, they should be presented after the
+package names. The go tool treats as a flag the first argument that begins with
+a minus sign that it does not recognize itself; that argument and all subsequent
+arguments are passed as arguments to the test binary.
+
+For more about build flags, see 'go help build'.
+For more about specifying packages, see 'go help packages'.
+
+See also: go build, go vet.
+
+
+Run specified go tool
+
+Usage:
+
+	go tool [-n] command [args...]
+
+Tool runs the go tool command identified by the arguments.
+With no arguments it prints the list of known tools.
+
+The -n flag causes tool to print the command that would be
+executed but not execute it.
+
+For more about each tool command, see 'go tool command -h'.
+
+
+Print Go version
+
+Usage:
+
+	go version
+
+Version prints the Go version, as reported by runtime.Version.
+
+
+Run go tool vet on packages
+
+Usage:
+
+	go vet [-n] [-x] [build flags] [packages]
+
+Vet runs the Go vet command on the packages named by the import paths.
+
+For more about vet, see 'go doc cmd/vet'.
+For more about specifying packages, see 'go help packages'.
+
+To run the vet tool with specific options, run 'go tool vet'.
+
+The -n flag prints commands that would be executed.
+The -x flag prints commands as they are executed.
+
+For more about build flags, see 'go help build'.
+
+See also: go fmt, go fix.
+
+
+Calling between Go and C
+
+There are two different ways to call between Go and C/C++ code.
+
+The first is the cgo tool, which is part of the Go distribution.  For
+information on how to use it see the cgo documentation (go doc cmd/cgo).
+
+The second is the SWIG program, which is a general tool for
+interfacing between languages.  For information on SWIG see
+http://swig.org/.  When running go build, any file with a .swig
+extension will be passed to SWIG.  Any file with a .swigcxx extension
+will be passed to SWIG with the -c++ option.
+
+When either cgo or SWIG is used, go build will pass any .c, .m, .s,
+or .S files to the C compiler, and any .cc, .cpp, .cxx files to the C++
+compiler.  The CC or CXX environment variables may be set to determine
+the C or C++ compiler, respectively, to use.
+
+
+Description of build modes
+
+The 'go build' and 'go install' commands take a -buildmode argument which
+indicates which kind of object file is to be built. Currently supported values
+are:
+
+	-buildmode=archive
+		Build the listed non-main packages into .a files. Packages named
+		main are ignored.
+
+	-buildmode=c-archive
+		Build the listed main package, plus all packages it imports,
+		into a C archive file. The only callable symbols will be those
+		functions exported using a cgo //export comment. Requires
+		exactly one main package to be listed.
+
+	-buildmode=c-shared
+		Build the listed main packages, plus all packages that they
+		import, into C shared libraries. The only callable symbols will
+		be those functions exported using a cgo //export comment.
+		Non-main packages are ignored.
+
+	-buildmode=default
+		Listed main packages are built into executables and listed
+		non-main packages are built into .a files (the default
+		behavior).
+
+	-buildmode=shared
+		Combine all the listed non-main packages into a single shared
+		library that will be used when building with the -linkshared
+		option. Packages named main are ignored.
+
+	-buildmode=exe
+		Build the listed main packages and everything they import into
+		executables. Packages not named main are ignored.
+
+
+File types
+
+The go command examines the contents of a restricted set of files
+in each directory. It identifies which files to examine based on
+the extension of the file name. These extensions are:
+
+	.go
+		Go source files.
+	.c, .h
+		C source files.
+		If the package uses cgo or SWIG, these will be compiled with the
+		OS-native compiler (typically gcc); otherwise they will
+		trigger an error.
+	.cc, .cpp, .cxx, .hh, .hpp, .hxx
+		C++ source files. Only useful with cgo or SWIG, and always
+		compiled with the OS-native compiler.
+	.m
+		Objective-C source files. Only useful with cgo, and always
+		compiled with the OS-native compiler.
+	.s, .S
+		Assembler source files.
+		If the package uses cgo or SWIG, these will be assembled with the
+		OS-native assembler (typically gcc (sic)); otherwise they
+		will be assembled with the Go assembler.
+	.swig, .swigcxx
+		SWIG definition files.
+	.syso
+		System object files.
+
+Files of each of these types except .syso may contain build
+constraints, but the go command stops scanning for build constraints
+at the first item in the file that is not a blank line or //-style
+line comment.
+
+
+GOPATH environment variable
+
+The Go path is used to resolve import statements.
+It is implemented by and documented in the go/build package.
+
+The GOPATH environment variable lists places to look for Go code.
+On Unix, the value is a colon-separated string.
+On Windows, the value is a semicolon-separated string.
+On Plan 9, the value is a list.
+
+GOPATH must be set to get, build and install packages outside the
+standard Go tree.
+
+Each directory listed in GOPATH must have a prescribed structure:
+
+The src directory holds source code.  The path below src
+determines the import path or executable name.
+
+The pkg directory holds installed package objects.
+As in the Go tree, each target operating system and
+architecture pair has its own subdirectory of pkg
+(pkg/GOOS_GOARCH).
+
+If DIR is a directory listed in the GOPATH, a package with
+source in DIR/src/foo/bar can be imported as "foo/bar" and
+has its compiled form installed to "DIR/pkg/GOOS_GOARCH/foo/bar.a".
+
+The bin directory holds compiled commands.
+Each command is named for its source directory, but only
+the final element, not the entire path.  That is, the
+command with source in DIR/src/foo/quux is installed into
+DIR/bin/quux, not DIR/bin/foo/quux.  The "foo/" prefix is stripped
+so that you can add DIR/bin to your PATH to get at the
+installed commands.  If the GOBIN environment variable is
+set, commands are installed to the directory it names instead
+of DIR/bin.
+
+Here's an example directory layout:
+
+    GOPATH=/home/user/gocode
+
+    /home/user/gocode/
+        src/
+            foo/
+                bar/               (go code in package bar)
+                    x.go
+                quux/              (go code in package main)
+                    y.go
+        bin/
+            quux                   (installed command)
+        pkg/
+            linux_amd64/
+                foo/
+                    bar.a          (installed package object)
+
+Go searches each directory listed in GOPATH to find source code,
+but new packages are always downloaded into the first directory
+in the list.
+
+See https://golang.org/doc/code.html for an example.
+
+Internal Directories
+
+Code in or below a directory named "internal" is importable only
+by code in the directory tree rooted at the parent of "internal".
+Here's an extended version of the directory layout above:
+
+    /home/user/gocode/
+        src/
+            crash/
+                bang/              (go code in package bang)
+                    b.go
+            foo/                   (go code in package foo)
+                f.go
+                bar/               (go code in package bar)
+                    x.go
+                internal/
+                    baz/           (go code in package baz)
+                        z.go
+                quux/              (go code in package main)
+                    y.go
+
+
+The code in z.go is imported as "foo/internal/baz", but that
+import statement can only appear in source files in the subtree
+rooted at foo. The source files foo/f.go, foo/bar/x.go, and
+foo/quux/y.go can all import "foo/internal/baz", but the source file
+crash/bang/b.go cannot.
+
+See https://golang.org/s/go14internal for details.
+
+Vendor Directories
+
+Go 1.5 includes experimental support for using local copies
+of external dependencies to satisfy imports of those dependencies,
+often referred to as vendoring. Setting the environment variable
+GO15VENDOREXPERIMENT=1 enables that experimental support.
+
+When the vendor experiment is enabled,
+code below a directory named "vendor" is importable only
+by code in the directory tree rooted at the parent of "vendor",
+and only using an import path that omits the prefix up to and
+including the vendor element.
+
+Here's the example from the previous section,
+but with the "internal" directory renamed to "vendor"
+and a new foo/vendor/crash/bang directory added:
+
+    /home/user/gocode/
+        src/
+            crash/
+                bang/              (go code in package bang)
+                    b.go
+            foo/                   (go code in package foo)
+                f.go
+                bar/               (go code in package bar)
+                    x.go
+                vendor/
+                    crash/
+                        bang/      (go code in package bang)
+                            b.go
+                    baz/           (go code in package baz)
+                        z.go
+                quux/              (go code in package main)
+                    y.go
+
+The same visibility rules apply as for internal, but the code
+in z.go is imported as "baz", not as "foo/vendor/baz".
+
+Code in vendor directories deeper in the source tree shadows
+code in higher directories. Within the subtree rooted at foo, an import
+of "crash/bang" resolves to "foo/vendor/crash/bang", not the
+top-level "crash/bang".
+
+Code in vendor directories is not subject to import path
+checking (see 'go help importpath').
+
+When the vendor experiment is enabled, 'go get' checks out
+submodules when checking out or updating a git repository
+(see 'go help get').
+
+The vendoring semantics are an experiment, and they may change
+in future releases. Once settled, they will be on by default.
+
+See https://golang.org/s/go15vendor for details.
+
+
+Environment variables
+
+The go command, and the tools it invokes, examine a few different
+environment variables. For many of these, you can see the default
+value of on your system by running 'go env NAME', where NAME is the
+name of the variable.
+
+General-purpose environment variables:
+
+	GCCGO
+		The gccgo command to run for 'go build -compiler=gccgo'.
+	GOARCH
+		The architecture, or processor, for which to compile code.
+		Examples are amd64, 386, arm, ppc64.
+	GOBIN
+		The directory where 'go install' will install a command.
+	GOOS
+		The operating system for which to compile code.
+		Examples are linux, darwin, windows, netbsd.
+	GOPATH
+		See 'go help gopath'.
+	GORACE
+		Options for the race detector.
+		See https://golang.org/doc/articles/race_detector.html.
+	GOROOT
+		The root of the go tree.
+
+Environment variables for use with cgo:
+
+	CC
+		The command to use to compile C code.
+	CGO_ENABLED
+		Whether the cgo command is supported.  Either 0 or 1.
+	CGO_CFLAGS
+		Flags that cgo will pass to the compiler when compiling
+		C code.
+	CGO_CPPFLAGS
+		Flags that cgo will pass to the compiler when compiling
+		C or C++ code.
+	CGO_CXXFLAGS
+		Flags that cgo will pass to the compiler when compiling
+		C++ code.
+	CGO_LDFLAGS
+		Flags that cgo will pass to the compiler when linking.
+	CXX
+		The command to use to compile C++ code.
+
+Architecture-specific environment variables:
+
+	GOARM
+		For GOARCH=arm, the ARM architecture for which to compile.
+		Valid values are 5, 6, 7.
+	GO386
+		For GOARCH=386, the floating point instruction set.
+		Valid values are 387, sse2.
+
+Special-purpose environment variables:
+
+	GOROOT_FINAL
+		The root of the installed Go tree, when it is
+		installed in a location other than where it is built.
+		File names in stack traces are rewritten from GOROOT to
+		GOROOT_FINAL.
+	GO15VENDOREXPERIMENT
+		Set to 1 to enable the Go 1.5 vendoring experiment.
+	GO_EXTLINK_ENABLED
+		Whether the linker should use external linking mode
+		when using -linkmode=auto with code that uses cgo.
+		Set to 0 to disable external linking mode, 1 to enable it.
+
+
+Import path syntax
+
+An import path (see 'go help packages') denotes a package
+stored in the local file system.  In general, an import path denotes
+either a standard package (such as "unicode/utf8") or a package
+found in one of the work spaces (see 'go help gopath').
+
+Relative import paths
+
+An import path beginning with ./ or ../ is called a relative path.
+The toolchain supports relative import paths as a shortcut in two ways.
+
+First, a relative path can be used as a shorthand on the command line.
+If you are working in the directory containing the code imported as
+"unicode" and want to run the tests for "unicode/utf8", you can type
+"go test ./utf8" instead of needing to specify the full path.
+Similarly, in the reverse situation, "go test .." will test "unicode" from
+the "unicode/utf8" directory. Relative patterns are also allowed, like
+"go test ./..." to test all subdirectories. See 'go help packages' for details
+on the pattern syntax.
+
+Second, if you are compiling a Go program not in a work space,
+you can use a relative path in an import statement in that program
+to refer to nearby code also not in a work space.
+This makes it easy to experiment with small multipackage programs
+outside of the usual work spaces, but such programs cannot be
+installed with "go install" (there is no work space in which to install them),
+so they are rebuilt from scratch each time they are built.
+To avoid ambiguity, Go programs cannot use relative import paths
+within a work space.
+
+Remote import paths
+
+Certain import paths also
+describe how to obtain the source code for the package using
+a revision control system.
+
+A few common code hosting sites have special syntax:
+
+	Bitbucket (Git, Mercurial)
+
+		import "bitbucket.org/user/project"
+		import "bitbucket.org/user/project/sub/directory"
+
+	GitHub (Git)
+
+		import "github.com/user/project"
+		import "github.com/user/project/sub/directory"
+
+	Google Code Project Hosting (Git, Mercurial, Subversion)
+
+		import "code.google.com/p/project"
+		import "code.google.com/p/project/sub/directory"
+
+		import "code.google.com/p/project.subrepository"
+		import "code.google.com/p/project.subrepository/sub/directory"
+
+	Launchpad (Bazaar)
+
+		import "launchpad.net/project"
+		import "launchpad.net/project/series"
+		import "launchpad.net/project/series/sub/directory"
+
+		import "launchpad.net/~user/project/branch"
+		import "launchpad.net/~user/project/branch/sub/directory"
+
+	IBM DevOps Services (Git)
+
+		import "hub.jazz.net/git/user/project"
+		import "hub.jazz.net/git/user/project/sub/directory"
+
+For code hosted on other servers, import paths may either be qualified
+with the version control type, or the go tool can dynamically fetch
+the import path over https/http and discover where the code resides
+from a <meta> tag in the HTML.
+
+To declare the code location, an import path of the form
+
+	repository.vcs/path
+
+specifies the given repository, with or without the .vcs suffix,
+using the named version control system, and then the path inside
+that repository.  The supported version control systems are:
+
+	Bazaar      .bzr
+	Git         .git
+	Mercurial   .hg
+	Subversion  .svn
+
+For example,
+
+	import "example.org/user/foo.hg"
+
+denotes the root directory of the Mercurial repository at
+example.org/user/foo or foo.hg, and
+
+	import "example.org/repo.git/foo/bar"
+
+denotes the foo/bar directory of the Git repository at
+example.org/repo or repo.git.
+
+When a version control system supports multiple protocols,
+each is tried in turn when downloading.  For example, a Git
+download tries https://, then git+ssh://.
+
+If the import path is not a known code hosting site and also lacks a
+version control qualifier, the go tool attempts to fetch the import
+over https/http and looks for a <meta> tag in the document's HTML
+<head>.
+
+The meta tag has the form:
+
+	<meta name="go-import" content="import-prefix vcs repo-root">
+
+The import-prefix is the import path corresponding to the repository
+root. It must be a prefix or an exact match of the package being
+fetched with "go get". If it's not an exact match, another http
+request is made at the prefix to verify the <meta> tags match.
+
+The meta tag should appear as early in the file as possible.
+In particular, it should appear before any raw JavaScript or CSS,
+to avoid confusing the go command's restricted parser.
+
+The vcs is one of "git", "hg", "svn", etc,
+
+The repo-root is the root of the version control system
+containing a scheme and not containing a .vcs qualifier.
+
+For example,
+
+	import "example.org/pkg/foo"
+
+will result in the following requests:
+
+	https://example.org/pkg/foo?go-get=1 (preferred)
+	http://example.org/pkg/foo?go-get=1  (fallback, only with -insecure)
+
+If that page contains the meta tag
+
+	<meta name="go-import" content="example.org git https://code.org/r/p/exproj">
+
+the go tool will verify that https://example.org/?go-get=1 contains the
+same meta tag and then git clone https://code.org/r/p/exproj into
+GOPATH/src/example.org.
+
+New downloaded packages are written to the first directory
+listed in the GOPATH environment variable (see 'go help gopath').
+
+The go command attempts to download the version of the
+package appropriate for the Go release being used.
+Run 'go help get' for more.
+
+Import path checking
+
+When the custom import path feature described above redirects to a
+known code hosting site, each of the resulting packages has two possible
+import paths, using the custom domain or the known hosting site.
+
+A package statement is said to have an "import comment" if it is immediately
+followed (before the next newline) by a comment of one of these two forms:
+
+	package math // import "path"
+	package math /* import "path" * /
+
+The go command will refuse to install a package with an import comment
+unless it is being referred to by that import path. In this way, import comments
+let package authors make sure the custom import path is used and not a
+direct path to the underlying code hosting site.
+
+If the vendoring experiment is enabled (see 'go help gopath'),
+then import path checking is disabled for code found within vendor trees.
+This makes it possible to copy code into alternate locations in vendor trees
+without needing to update import comments.
+
+See https://golang.org/s/go14customimport for details.
+
+
+Description of package lists
+
+Many commands apply to a set of packages:
+
+	go action [packages]
+
+Usually, [packages] is a list of import paths.
+
+An import path that is a rooted path or that begins with
+a . or .. element is interpreted as a file system path and
+denotes the package in that directory.
+
+Otherwise, the import path P denotes the package found in
+the directory DIR/src/P for some DIR listed in the GOPATH
+environment variable (see 'go help gopath').
+
+If no import paths are given, the action applies to the
+package in the current directory.
+
+There are four reserved names for paths that should not be used
+for packages to be built with the go tool:
+
+- "main" denotes the top-level package in a stand-alone executable.
+
+- "all" expands to all package directories found in all the GOPATH
+trees. For example, 'go list all' lists all the packages on the local
+system.
+
+- "std" is like all but expands to just the packages in the standard
+Go library.
+
+- "cmd" expands to the Go repository's commands and their
+internal libraries.
+
+An import path is a pattern if it includes one or more "..." wildcards,
+each of which can match any string, including the empty string and
+strings containing slashes.  Such a pattern expands to all package
+directories found in the GOPATH trees with names matching the
+patterns.  As a special case, x/... matches x as well as x's subdirectories.
+For example, net/... expands to net and packages in its subdirectories.
+
+An import path can also name a package to be downloaded from
+a remote repository.  Run 'go help importpath' for details.
+
+Every package in a program must have a unique import path.
+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 '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
+package made up of exactly those files, ignoring any build constraints
+in those files and ignoring any other files in the directory.
+
+Directory and file names that begin with "." or "_" are ignored
+by the go tool, as are directories named "testdata".
+
+
+Description of testing flags
+
+The 'go test' command takes both flags that apply to 'go test' itself
+and flags that apply to the resulting test binary.
+
+Several of the flags control profiling and write an execution profile
+suitable for "go tool pprof"; run "go tool pprof -h" for more
+information.  The --alloc_space, --alloc_objects, and --show_bytes
+options of pprof control how the information is presented.
+
+The following flags are recognized by the 'go test' command and
+control the execution of any test:
+
+	-bench regexp
+	    Run benchmarks matching the regular expression.
+	    By default, no benchmarks run. To run all benchmarks,
+	    use '-bench .' or '-bench=.'.
+
+	-benchmem
+	    Print memory allocation statistics for benchmarks.
+
+	-benchtime t
+	    Run enough iterations of each benchmark to take t, specified
+	    as a time.Duration (for example, -benchtime 1h30s).
+	    The default is 1 second (1s).
+
+	-blockprofile block.out
+	    Write a goroutine blocking profile to the specified file
+	    when all tests are complete.
+	    Writes test binary as -c would.
+
+	-blockprofilerate n
+	    Control the detail provided in goroutine blocking profiles by
+	    calling runtime.SetBlockProfileRate with n.
+	    See 'go doc runtime.SetBlockProfileRate'.
+	    The profiler aims to sample, on average, one blocking event every
+	    n nanoseconds the program spends blocked.  By default,
+	    if -test.blockprofile is set without this flag, all blocking events
+	    are recorded, equivalent to -test.blockprofilerate=1.
+
+	-count n
+	    Run each test and benchmark n times (default 1).
+	    If -cpu is set, run n times for each GOMAXPROCS value.
+	    Examples are always run once.
+
+	-cover
+	    Enable coverage analysis.
+
+	-covermode set,count,atomic
+	    Set the mode for coverage analysis for the package[s]
+	    being tested. The default is "set" unless -race is enabled,
+	    in which case it is "atomic".
+	    The values:
+		set: bool: does this statement run?
+		count: int: how many times does this statement run?
+		atomic: int: count, but correct in multithreaded tests;
+			significantly more expensive.
+	    Sets -cover.
+
+	-coverpkg pkg1,pkg2,pkg3
+	    Apply coverage analysis in each test to the given list of packages.
+	    The default is for each test to analyze only the package being tested.
+	    Packages are specified as import paths.
+	    Sets -cover.
+
+	-coverprofile cover.out
+	    Write a coverage profile to the file after all tests have passed.
+	    Sets -cover.
+
+	-cpu 1,2,4
+	    Specify a list of GOMAXPROCS values for which the tests or
+	    benchmarks should be executed.  The default is the current value
+	    of GOMAXPROCS.
+
+	-cpuprofile cpu.out
+	    Write a CPU profile to the specified file before exiting.
+	    Writes test binary as -c would.
+
+	-memprofile mem.out
+	    Write a memory profile to the file after all tests have passed.
+	    Writes test binary as -c would.
+
+	-memprofilerate n
+	    Enable more precise (and expensive) memory profiles by setting
+	    runtime.MemProfileRate.  See 'go doc runtime.MemProfileRate'.
+	    To profile all memory allocations, use -test.memprofilerate=1
+	    and pass --alloc_space flag to the pprof tool.
+
+	-outputdir directory
+	    Place output files from profiling in the specified directory,
+	    by default the directory in which "go test" is running.
+
+	-parallel n
+	    Allow parallel execution of test functions that call t.Parallel.
+	    The value of this flag is the maximum number of tests to run
+	    simultaneously; by default, it is set to the value of GOMAXPROCS.
+
+	-run regexp
+	    Run only those tests and examples matching the regular
+	    expression.
+
+	-short
+	    Tell long-running tests to shorten their run time.
+	    It is off by default but set during all.bash so that installing
+	    the Go tree can run a sanity check but not spend time running
+	    exhaustive tests.
+
+	-timeout t
+	    If a test runs longer than t, panic.
+	    The default is 10 minutes (10m).
+
+	-trace trace.out
+	    Write an execution trace to the specified file before exiting.
+	    Writes test binary as -c would.
+
+	-v
+	    Verbose output: log all tests as they are run. Also print all
+	    text from Log and Logf calls even if the test succeeds.
+
+The test binary, called pkg.test where pkg is the name of the
+directory containing the package sources, can be invoked directly
+after building it with 'go test -c'. When invoking the test binary
+directly, each of the standard flag names must be prefixed with 'test.',
+as in -test.run=TestMyFunc or -test.v.
+
+When running 'go test', flags not listed above are passed through
+unaltered. For instance, the command
+
+	go test -x -v -cpuprofile=prof.out -dir=testdata -update
+
+will compile the test binary and then run it as
+
+	pkg.test -test.v -test.cpuprofile=prof.out -dir=testdata -update
+
+The test flags that generate profiles (other than for coverage) also
+leave the test binary in pkg.test for use when analyzing the profiles.
+
+Flags not recognized by 'go test' must be placed after any specified packages.
+
+
+Description of testing functions
+
+The 'go test' command expects to find test, benchmark, and example functions
+in the "*_test.go" files corresponding to the package under test.
+
+A test function is one named TestXXX (where XXX is any alphanumeric string
+not starting with a lower case letter) and should have the signature,
+
+	func TestXXX(t *testing.T) { ... }
+
+A benchmark function is one named BenchmarkXXX and should have the signature,
+
+	func BenchmarkXXX(b *testing.B) { ... }
+
+An example function is similar to a test function but, instead of using
+*testing.T to report success or failure, prints output to os.Stdout.
+That output is compared against the function's "Output:" comment, which
+must be the last comment in the function body (see example below). An
+example with no such comment, or with no text after "Output:" is compiled
+but not executed.
+
+Godoc displays the body of ExampleXXX to demonstrate the use
+of the function, constant, or variable XXX.  An example of a method M with
+receiver type T or *T is named ExampleT_M.  There may be multiple examples
+for a given function, constant, or variable, distinguished by a trailing _xxx,
+where xxx is a suffix not beginning with an upper case letter.
+
+Here is an example of an example:
+
+	func ExamplePrintln() {
+		Println("The output of\nthis example.")
+		// Output: The output of
+		// this example.
+	}
+
+The entire test file is presented as the example when it contains a single
+example function, at least one other function, type, variable, or constant
+declaration, and no test or benchmark functions.
+
+See the documentation of the testing package for more information.
+
+
+*/
+package main
diff --git a/third_party/gofrontend/libgo/go/cmd/go/bootstrap.go b/third_party/gofrontend/libgo/go/cmd/go/bootstrap.go
index dc7ed5f..1686df7 100644
--- a/third_party/gofrontend/libgo/go/cmd/go/bootstrap.go
+++ b/third_party/gofrontend/libgo/go/cmd/go/bootstrap.go
@@ -17,11 +17,19 @@
 
 var errHTTP = errors.New("no http in bootstrap go command")
 
+type httpError struct {
+	statusCode int
+}
+
+func (e *httpError) Error() string {
+	panic("unreachable")
+}
+
 func httpGET(url string) ([]byte, error) {
 	return nil, errHTTP
 }
 
-func httpsOrHTTP(importPath string) (string, io.ReadCloser, error) {
+func httpsOrHTTP(importPath string, security securityMode) (string, io.ReadCloser, error) {
 	return "", nil, errHTTP
 }
 
diff --git a/third_party/gofrontend/libgo/go/cmd/go/build.go b/third_party/gofrontend/libgo/go/cmd/go/build.go
index 781a43b..865871c 100644
--- a/third_party/gofrontend/libgo/go/cmd/go/build.go
+++ b/third_party/gofrontend/libgo/go/cmd/go/build.go
@@ -8,6 +8,7 @@
 	"bufio"
 	"bytes"
 	"container/heap"
+	"debug/elf"
 	"errors"
 	"flag"
 	"fmt"
@@ -34,21 +35,23 @@
 Build compiles the packages named by the import paths,
 along with their dependencies, but it does not install the results.
 
-If the arguments are a list of .go files, build treats them as a list
-of source files specifying a single package.
+If the arguments to build are a list of .go files, build treats
+them as a list of source files specifying a single package.
 
-When the command line specifies a single main package,
-build writes the resulting executable to output.
-Otherwise build compiles the packages but discards the results,
+When compiling a single main package, build writes
+the resulting executable to an output file named after
+the first source file ('go build ed.go rx.go' writes 'ed' or 'ed.exe')
+or the source code directory ('go build unix/sam' writes 'sam' or 'sam.exe').
+The '.exe' suffix is added when writing a Windows executable.
+
+When compiling multiple packages or a single non-main package,
+build compiles the packages but discards the resulting object,
 serving only as a check that the packages can be built.
 
-The -o flag specifies the output file name. If not specified, the
-output file name depends on the arguments and derives from the name
-of the package, such as p.a for package p, unless p is 'main'. If
-the package is main and file names are provided, the file name
-derives from the first file name mentioned, such as f1 for 'go build
-f1.go f2.go'; with no files provided ('go build'), the output file
-name is the base name of the containing directory.
+The -o flag, only allowed when compiling a single package,
+forces build to write the resulting executable or object
+to the named output file, instead of the default behavior described
+in the last two paragraphs.
 
 The -i flag installs the packages that are dependencies of the target.
 
@@ -57,12 +60,12 @@
 
 	-a
 		force rebuilding of packages that are already up-to-date.
-		In Go releases, does not apply to the standard library.
 	-n
 		print the commands but do not run them.
 	-p n
 		the number of builds that can be run in parallel.
-		The default is the number of CPUs available.
+		The default is the number of CPUs available, except
+		on darwin/arm which defaults to 1.
 	-race
 		enable data race detection.
 		Supported only on linux/amd64, freebsd/amd64, darwin/amd64 and windows/amd64.
@@ -74,33 +77,54 @@
 	-x
 		print the commands.
 
-	-ccflags 'arg list'
-		arguments to pass on each 5c, 6c, or 8c compiler invocation.
+	-asmflags 'flag list'
+		arguments to pass on each go tool asm invocation.
+	-buildmode mode
+		build mode to use. See 'go help buildmode' for more.
 	-compiler name
 		name of compiler to use, as in runtime.Compiler (gccgo or gc).
 	-gccgoflags 'arg list'
 		arguments to pass on each gccgo compiler/linker invocation.
 	-gcflags 'arg list'
-		arguments to pass on each 5g, 6g, or 8g compiler invocation.
+		arguments to pass on each go tool compile invocation.
 	-installsuffix suffix
 		a suffix to use in the name of the package installation directory,
 		in order to keep output separate from default builds.
 		If using the -race flag, the install suffix is automatically set to race
-		or, if set explicitly, has _race appended to it.
+		or, if set explicitly, has _race appended to it.  Using a -buildmode
+		option that requires non-default compile flags has a similar effect.
 	-ldflags 'flag list'
-		arguments to pass on each 5l, 6l, or 8l linker invocation.
+		arguments to pass on each go tool link invocation.
+	-linkshared
+		link against shared libraries previously created with
+		-buildmode=shared
+	-pkgdir dir
+		install and load all packages from dir instead of the usual locations.
+		For example, when building with a non-standard configuration,
+		use -pkgdir to keep generated packages in a separate location.
 	-tags 'tag list'
 		a list of build tags to consider satisfied during the build.
 		For more information about build tags, see the description of
 		build constraints in the documentation for the go/build package.
+	-toolexec 'cmd args'
+		a program to use to invoke toolchain programs like vet and asm.
+		For example, instead of running asm, the go command will run
+		'cmd args /path/to/asm <arguments for asm>'.
 
 The list flags accept a space-separated list of strings. To embed spaces
 in an element in the list, surround it with either single or double quotes.
 
 For more about specifying packages, see 'go help packages'.
 For more about where packages and binaries are installed,
-run 'go help gopath'.  For more about calling between Go and C/C++,
-run 'go help c'.
+run 'go help gopath'.
+For more about calling between Go and C/C++, run 'go help c'.
+
+Note: Build adheres to certain conventions such as those described
+by 'go help gopath'. Not all projects can follow these conventions,
+however. Installations that have their own conventions or that use
+a separate software build system may choose to use lower-level
+invocations such as 'go tool compile' and 'go tool link' to avoid
+some of the overheads and design decisions of the build tool.
 
 See also: go install, go get, go clean.
 	`,
@@ -115,6 +139,17 @@
 
 	addBuildFlags(cmdBuild)
 	addBuildFlags(cmdInstall)
+
+	if buildContext.GOOS == "darwin" {
+		switch buildContext.GOARCH {
+		case "arm", "arm64":
+			// darwin/arm cannot run multiple tests simultaneously.
+			// Parallelism is limited in go_darwin_arm_exec, but
+			// also needs to be limited here so go test std does not
+			// timeout tests that waiting to run.
+			buildP = 1
+		}
+	}
 }
 
 // Flags set by multiple commands.
@@ -126,16 +161,21 @@
 var buildI bool               // -i flag
 var buildO = cmdBuild.Flag.String("o", "", "output file")
 var buildWork bool           // -work flag
+var buildAsmflags []string   // -asmflags flag
 var buildGcflags []string    // -gcflags flag
-var buildCcflags []string    // -ccflags flag
 var buildLdflags []string    // -ldflags flag
 var buildGccgoflags []string // -gccgoflags flag
 var buildRace bool           // -race flag
+var buildToolExec []string   // -toolexec flag
+var buildBuildmode string    // -buildmode flag
+var buildLinkshared bool     // -linkshared flag
+var buildPkgdir string       // -pkgdir flag
 
 // Require the source for go std packages
 var reqStdPkgSrc bool
 var buildContext = build.Default
 var buildToolchain toolchain = noToolchain{}
+var ldBuildmode string
 
 // buildCompiler implements flag.Var.
 // It implements Set by updating both
@@ -171,21 +211,25 @@
 // addBuildFlags adds the flags common to the build, clean, get,
 // install, list, run, and test commands.
 func addBuildFlags(cmd *Command) {
-	// NOTE: If you add flags here, also add them to testflag.go.
 	cmd.Flag.BoolVar(&buildA, "a", false, "")
 	cmd.Flag.BoolVar(&buildN, "n", false, "")
 	cmd.Flag.IntVar(&buildP, "p", buildP, "")
-	cmd.Flag.StringVar(&buildContext.InstallSuffix, "installsuffix", "", "")
 	cmd.Flag.BoolVar(&buildV, "v", false, "")
 	cmd.Flag.BoolVar(&buildX, "x", false, "")
-	cmd.Flag.BoolVar(&buildWork, "work", false, "")
-	cmd.Flag.Var((*stringsFlag)(&buildGcflags), "gcflags", "")
-	cmd.Flag.Var((*stringsFlag)(&buildCcflags), "ccflags", "")
-	cmd.Flag.Var((*stringsFlag)(&buildLdflags), "ldflags", "")
-	cmd.Flag.Var((*stringsFlag)(&buildGccgoflags), "gccgoflags", "")
-	cmd.Flag.Var((*stringsFlag)(&buildContext.BuildTags), "tags", "")
+
+	cmd.Flag.Var((*stringsFlag)(&buildAsmflags), "asmflags", "")
 	cmd.Flag.Var(buildCompiler{}, "compiler", "")
+	cmd.Flag.StringVar(&buildBuildmode, "buildmode", "default", "")
+	cmd.Flag.Var((*stringsFlag)(&buildGcflags), "gcflags", "")
+	cmd.Flag.Var((*stringsFlag)(&buildGccgoflags), "gccgoflags", "")
+	cmd.Flag.StringVar(&buildContext.InstallSuffix, "installsuffix", "", "")
+	cmd.Flag.Var((*stringsFlag)(&buildLdflags), "ldflags", "")
+	cmd.Flag.BoolVar(&buildLinkshared, "linkshared", false, "")
+	cmd.Flag.StringVar(&buildPkgdir, "pkgdir", "", "")
 	cmd.Flag.BoolVar(&buildRace, "race", false, "")
+	cmd.Flag.Var((*stringsFlag)(&buildContext.BuildTags), "tags", "")
+	cmd.Flag.Var((*stringsFlag)(&buildToolExec), "toolexec", "")
+	cmd.Flag.BoolVar(&buildWork, "work", false, "")
 	switch build.Default.Compiler {
 	case "gc":
 		reqStdPkgSrc = true
@@ -266,8 +310,113 @@
 	return "<stringsFlag>"
 }
 
+func pkgsMain(pkgs []*Package) (res []*Package) {
+	for _, p := range pkgs {
+		if p.Name == "main" {
+			res = append(res, p)
+		}
+	}
+	return res
+}
+
+func pkgsNotMain(pkgs []*Package) (res []*Package) {
+	for _, p := range pkgs {
+		if p.Name != "main" {
+			res = append(res, p)
+		}
+	}
+	return res
+}
+
+var pkgsFilter = func(pkgs []*Package) []*Package { return pkgs }
+
+func buildModeInit() {
+	_, gccgo := buildToolchain.(gccgoToolchain)
+	var codegenArg string
+	platform := goos + "/" + goarch
+	switch buildBuildmode {
+	case "archive":
+		pkgsFilter = pkgsNotMain
+	case "c-archive":
+		pkgsFilter = func(p []*Package) []*Package {
+			if len(p) != 1 || p[0].Name != "main" {
+				fatalf("-buildmode=c-archive requires exactly one main package")
+			}
+			return p
+		}
+		exeSuffix = ".a"
+		ldBuildmode = "c-archive"
+	case "c-shared":
+		pkgsFilter = pkgsMain
+		if gccgo {
+			codegenArg = "-fPIC"
+		} else {
+			switch platform {
+			case "linux/amd64":
+				codegenArg = "-shared"
+			case "linux/arm":
+				buildAsmflags = append(buildAsmflags, "-shared")
+			case "darwin/amd64":
+			case "android/arm":
+			default:
+				fatalf("-buildmode=c-shared not supported on %s\n", platform)
+			}
+		}
+		ldBuildmode = "c-shared"
+	case "default":
+		ldBuildmode = "exe"
+	case "exe":
+		pkgsFilter = pkgsMain
+		ldBuildmode = "exe"
+	case "shared":
+		pkgsFilter = pkgsNotMain
+		if gccgo {
+			codegenArg = "-fPIC"
+		} else {
+			switch platform {
+			case "linux/amd64":
+			default:
+				fatalf("-buildmode=shared not supported on %s\n", platform)
+			}
+			codegenArg = "-dynlink"
+		}
+		if *buildO != "" {
+			fatalf("-buildmode=shared and -o not supported together")
+		}
+		ldBuildmode = "shared"
+	default:
+		fatalf("buildmode=%s not supported", buildBuildmode)
+	}
+	if buildLinkshared {
+		if gccgo {
+			codegenArg = "-fPIC"
+		} else {
+			if platform != "linux/amd64" {
+				fmt.Fprintf(os.Stderr, "go %s: -linkshared is only supported on linux/amd64\n", flag.Args()[0])
+				os.Exit(2)
+			}
+			codegenArg = "-dynlink"
+			// TODO(mwhudson): remove -w when that gets fixed in linker.
+			buildLdflags = append(buildLdflags, "-linkshared", "-w")
+		}
+	}
+	if codegenArg != "" {
+		if gccgo {
+			buildGccgoflags = append(buildGccgoflags, codegenArg)
+		} else {
+			buildAsmflags = append(buildAsmflags, codegenArg)
+			buildGcflags = append(buildGcflags, codegenArg)
+		}
+		if buildContext.InstallSuffix != "" {
+			buildContext.InstallSuffix += "_"
+		}
+		buildContext.InstallSuffix += codegenArg[1:]
+	}
+}
+
 func runBuild(cmd *Command, args []string) {
 	raceInit()
+	buildModeInit()
 	var b builder
 	b.init()
 
@@ -305,16 +454,21 @@
 			fatalf("no packages to build")
 		}
 		p := pkgs[0]
-		p.target = "" // must build - not up to date
+		p.target = *buildO
+		p.Stale = true // must build - not up to date
 		a := b.action(modeInstall, depMode, p)
-		a.target = *buildO
 		b.do(a)
 		return
 	}
 
-	a := &action{}
-	for _, p := range packages(args) {
-		a.deps = append(a.deps, b.action(modeBuild, depMode, p))
+	var a *action
+	if buildBuildmode == "shared" {
+		a = b.libaction(libname(args), pkgsFilter(packages(args)), modeBuild, depMode)
+	} else {
+		a = &action{}
+		for _, p := range pkgsFilter(packages(args)) {
+			a.deps = append(a.deps, b.action(modeBuild, depMode, p))
+		}
 	}
 	b.do(a)
 }
@@ -333,18 +487,47 @@
 	`,
 }
 
+// libname returns the filename to use for the shared library when using
+// -buildmode=shared.  The rules we use are:
+//  1) Drop any trailing "/..."s if present
+//  2) Change / to -
+//  3) Join arguments with ,
+// So std -> libstd.so
+//    a b/... -> liba,b.so
+//    gopkg.in/tomb.v2 -> libgopkg.in-tomb.v2.so
+func libname(args []string) string {
+	var libname string
+	for _, arg := range args {
+		arg = strings.TrimSuffix(arg, "/...")
+		arg = strings.Replace(arg, "/", "-", -1)
+		if libname == "" {
+			libname = arg
+		} else {
+			libname += "," + arg
+		}
+	}
+	// TODO(mwhudson): Needs to change for platforms that use different naming
+	// conventions...
+	return "lib" + libname + ".so"
+}
+
 func runInstall(cmd *Command, args []string) {
 	raceInit()
-	pkgs := packagesForBuild(args)
+	buildModeInit()
+	pkgs := pkgsFilter(packagesForBuild(args))
 
 	for _, p := range pkgs {
 		if p.Target == "" && (!p.Standard || p.ImportPath != "unsafe") {
-			if p.cmdline {
+			switch {
+			case p.gobinSubdir:
+				errorf("go install: cannot install cross-compiled binaries when GOBIN is set")
+			case p.cmdline:
 				errorf("go install: no install location for .go files listed on command line (GOBIN not set)")
-			} else if p.ConflictDir != "" {
+			case p.ConflictDir != "":
 				errorf("go install: no install location for %s: hidden by %s", p.Dir, p.ConflictDir)
-			} else {
-				errorf("go install: no install location for directory %s outside GOPATH", p.Dir)
+			default:
+				errorf("go install: no install location for directory %s outside GOPATH\n"+
+					"\tFor more details see: go help gopath", p.Dir)
 			}
 		}
 	}
@@ -352,18 +535,68 @@
 
 	var b builder
 	b.init()
-	a := &action{}
-	for _, p := range pkgs {
-		a.deps = append(a.deps, b.action(modeInstall, modeInstall, p))
+	var a *action
+	if buildBuildmode == "shared" {
+		a = b.libaction(libname(args), pkgs, modeInstall, modeInstall)
+	} else {
+		a = &action{}
+		var tools []*action
+		for _, p := range pkgs {
+			// If p is a tool, delay the installation until the end of the build.
+			// This avoids installing assemblers/compilers that are being executed
+			// by other steps in the build.
+			// cmd/cgo is handled specially in b.action, so that we can
+			// both build and use it in the same 'go install'.
+			action := b.action(modeInstall, modeInstall, p)
+			if goTools[p.ImportPath] == toTool && p.ImportPath != "cmd/cgo" {
+				a.deps = append(a.deps, action.deps...)
+				action.deps = append(action.deps, a)
+				tools = append(tools, action)
+				continue
+			}
+			a.deps = append(a.deps, action)
+		}
+		if len(tools) > 0 {
+			a = &action{
+				deps: tools,
+			}
+		}
 	}
 	b.do(a)
+	exitIfErrors()
+
+	// Success. If this command is 'go install' with no arguments
+	// and the current directory (the implicit argument) is a command,
+	// remove any leftover command binary from a previous 'go build'.
+	// The binary is installed; it's not needed here anymore.
+	// And worse it might be a stale copy, which you don't want to find
+	// instead of the installed one if $PATH contains dot.
+	// One way to view this behavior is that it is as if 'go install' first
+	// runs 'go build' and the moves the generated file to the install dir.
+	// See issue 9645.
+	if len(args) == 0 && len(pkgs) == 1 && pkgs[0].Name == "main" {
+		// Compute file 'go build' would have created.
+		// If it exists and is an executable file, remove it.
+		_, targ := filepath.Split(pkgs[0].ImportPath)
+		targ += exeSuffix
+		if filepath.Join(pkgs[0].Dir, targ) != pkgs[0].Target { // maybe $GOBIN is the current directory
+			fi, err := os.Stat(targ)
+			if err == nil {
+				m := fi.Mode()
+				if m.IsRegular() {
+					if m&0111 != 0 || goos == "windows" { // windows never sets executable bit
+						os.Remove(targ)
+					}
+				}
+			}
+		}
+	}
 }
 
 // Global build parameters (used during package load)
 var (
 	goarch    string
 	goos      string
-	archChar  string
 	exeSuffix string
 )
 
@@ -373,16 +606,6 @@
 	if goos == "windows" {
 		exeSuffix = ".exe"
 	}
-	var err error
-	archChar, err = build.ArchChar(goarch)
-	if err != nil {
-		if _, isgc := buildToolchain.(gcToolchain); isgc {
-			fatalf("%s", err)
-		}
-		// archChar is only required for gcToolchain, if we're using
-		// another toolchain leave it blank.
-		archChar = ""
-	}
 }
 
 // A builder holds global state about a build.
@@ -429,8 +652,9 @@
 
 // cacheKey is the key for the action cache.
 type cacheKey struct {
-	mode buildMode
-	p    *Package
+	mode  buildMode
+	p     *Package
+	shlib string
 }
 
 // buildMode specifies the build mode:
@@ -505,6 +729,9 @@
 			fatalf("%s is a directory, should be a Go file", file)
 		}
 		dir1, _ := filepath.Split(file)
+		if dir1 == "" {
+			dir1 = "./"
+		}
 		if dir == "" {
 			dir = dir1
 		} else if dir != dir1 {
@@ -541,11 +768,8 @@
 		if gobin != "" {
 			pkg.target = filepath.Join(gobin, exe)
 		}
-	} else {
-		if *buildO == "" {
-			*buildO = pkg.Name + ".a"
-		}
 	}
+
 	pkg.Target = pkg.target
 	pkg.Stale = true
 
@@ -553,24 +777,88 @@
 	return pkg
 }
 
+// readpkglist returns the list of packages that were built into the shared library
+// at shlibpath. For the native toolchain this list is stored, newline separated, in
+// an ELF note with name "Go\x00\x00" and type 1. For GCCGO it is extracted from the
+// .go_export section.
+func readpkglist(shlibpath string) (pkgs []*Package) {
+	var stk importStack
+	if _, gccgo := buildToolchain.(gccgoToolchain); gccgo {
+		f, _ := elf.Open(shlibpath)
+		sect := f.Section(".go_export")
+		data, _ := sect.Data()
+		scanner := bufio.NewScanner(bytes.NewBuffer(data))
+		for scanner.Scan() {
+			t := scanner.Text()
+			if strings.HasPrefix(t, "pkgpath ") {
+				t = strings.TrimPrefix(t, "pkgpath ")
+				t = strings.TrimSuffix(t, ";")
+				pkgs = append(pkgs, loadPackage(t, &stk))
+			}
+		}
+	} else {
+		pkglistbytes, err := readELFNote(shlibpath, "Go\x00\x00", 1)
+		if err != nil {
+			fatalf("readELFNote failed: %v", err)
+		}
+		scanner := bufio.NewScanner(bytes.NewBuffer(pkglistbytes))
+		for scanner.Scan() {
+			t := scanner.Text()
+			pkgs = append(pkgs, loadPackage(t, &stk))
+		}
+	}
+	return
+}
+
 // action returns the action for applying the given operation (mode) to the package.
 // depMode is the action to use when building dependencies.
+// action never looks for p in a shared library.
 func (b *builder) action(mode buildMode, depMode buildMode, p *Package) *action {
-	key := cacheKey{mode, p}
+	return b.action1(mode, depMode, p, false)
+}
+
+// action1 returns the action for applying the given operation (mode) to the package.
+// depMode is the action to use when building dependencies.
+// action1 will look for p in a shared library if lookshared is true.
+func (b *builder) action1(mode buildMode, depMode buildMode, p *Package, lookshared bool) *action {
+	shlib := ""
+	if lookshared {
+		shlib = p.Shlib
+	}
+	key := cacheKey{mode, p, shlib}
+
 	a := b.actionCache[key]
 	if a != nil {
 		return a
 	}
+	if shlib != "" {
+		key2 := cacheKey{modeInstall, nil, shlib}
+		a = b.actionCache[key2]
+		if a != nil {
+			b.actionCache[key] = a
+			return a
+		}
+		pkgs := readpkglist(shlib)
+		a = b.libaction(filepath.Base(shlib), pkgs, modeInstall, depMode)
+		b.actionCache[key2] = a
+		b.actionCache[key] = a
+		return a
+	}
 
 	a = &action{p: p, pkgdir: p.build.PkgRoot}
 	if p.pkgdir != "" { // overrides p.t
 		a.pkgdir = p.pkgdir
 	}
-
 	b.actionCache[key] = a
 
 	for _, p1 := range p.imports {
-		a.deps = append(a.deps, b.action(depMode, depMode, p1))
+		ls := buildLinkshared
+		// If p1 is part of the same shared library as p, we need the action
+		// that builds p here, not the shared libary or we get action loops.
+		if p1.Shlib == p.Shlib {
+			ls = false
+		}
+		a.deps = append(a.deps, b.action1(depMode, depMode, p1, ls))
 	}
 
 	// If we are not doing a cross-build, then record the binary we'll
@@ -578,18 +866,15 @@
 	// using cgo, to make sure we do not overwrite the binary while
 	// a package is using it.  If this is a cross-build, then the cgo we
 	// are writing is not the cgo we need to use.
-
-	if goos == runtime.GOOS && goarch == runtime.GOARCH && !buildRace {
-		if reqStdPkgSrc {
-			if len(p.CgoFiles) > 0 || p.Standard && p.ImportPath == "runtime/cgo" {
-				var stk importStack
-				p1 := loadPackage("cmd/cgo", &stk)
-				if p1.Error != nil {
-					fatalf("load cmd/cgo: %v", p1.Error)
-				}
-				a.cgo = b.action(depMode, depMode, p1)
-				a.deps = append(a.deps, a.cgo)
+	if goos == runtime.GOOS && goarch == runtime.GOARCH && !buildRace && reqStdPkgSrc {
+		if (len(p.CgoFiles) > 0 || p.Standard && p.ImportPath == "runtime/cgo") && !buildLinkshared && buildBuildmode != "shared" {
+			var stk importStack
+			p1 := loadPackage("cmd/cgo", &stk)
+			if p1.Error != nil {
+				fatalf("load cmd/cgo: %v", p1.Error)
 			}
+			a.cgo = b.action(depMode, depMode, p1)
+			a.deps = append(a.deps, a.cgo)
 		}
 	}
 
@@ -629,8 +914,22 @@
 	switch mode {
 	case modeInstall:
 		a.f = (*builder).install
-		a.deps = []*action{b.action(modeBuild, depMode, p)}
+		a.deps = []*action{b.action1(modeBuild, depMode, p, lookshared)}
 		a.target = a.p.target
+
+		// Install header for cgo in c-archive and c-shared modes.
+		if p.usesCgo() && (buildBuildmode == "c-archive" || buildBuildmode == "c-shared") {
+			ah := &action{
+				p:      a.p,
+				deps:   []*action{a.deps[0]},
+				f:      (*builder).installHeader,
+				pkgdir: a.pkgdir,
+				objdir: a.objdir,
+				target: a.target[:len(a.target)-len(filepath.Ext(a.target))] + ".h",
+			}
+			a.deps = append(a.deps, ah)
+		}
+
 	case modeBuild:
 		a.f = (*builder).build
 		a.target = a.objpkg
@@ -645,6 +944,13 @@
 			name := "a.out"
 			if p.exeName != "" {
 				name = p.exeName
+			} else if goos == "darwin" && buildBuildmode == "c-shared" && p.target != "" {
+				// On OS X, the linker output name gets recorded in the
+				// shared library's LC_ID_DYLIB load command.
+				// The code invoking the linker knows to pass only the final
+				// path element. Arrange that the path element matches what
+				// we'll install it as; otherwise the library is only loadable as "a.out".
+				_, name = filepath.Split(p.target)
 			}
 			a.target = a.objdir + filepath.Join("exe", name) + exeSuffix
 		}
@@ -653,6 +959,100 @@
 	return a
 }
 
+func (b *builder) libaction(libname string, pkgs []*Package, mode, depMode buildMode) *action {
+	a := &action{}
+	if mode == modeBuild {
+		a.f = (*builder).linkShared
+		a.target = filepath.Join(b.work, libname)
+		for _, p := range pkgs {
+			if p.target == "" {
+				continue
+			}
+			a.deps = append(a.deps, b.action(depMode, depMode, p))
+		}
+	} else if mode == modeInstall {
+		// Currently build mode shared forces external linking mode, and
+		// external linking mode forces an import of runtime/cgo. So if it
+		// was not passed on the command line and it is not present in
+		// another shared library, add it here.
+		seencgo := false
+		_, gccgo := buildToolchain.(gccgoToolchain)
+		if !gccgo {
+			for _, p := range pkgs {
+				seencgo = seencgo || (p.Standard && p.ImportPath == "runtime/cgo")
+			}
+			if !seencgo {
+				var stk importStack
+				p := loadPackage("runtime/cgo", &stk)
+				if p.Error != nil {
+					fatalf("load runtime/cgo: %v", p.Error)
+				}
+				computeStale(p)
+				// If runtime/cgo is in another shared library, then that's
+				// also the shared library that contains runtime, so
+				// something will depend on it and so runtime/cgo's staleness
+				// will be checked when processing that library.
+				if p.Shlib == "" || p.Shlib == libname {
+					pkgs = append([]*Package{}, pkgs...)
+					pkgs = append(pkgs, p)
+				}
+			}
+		}
+
+		// Figure out where the library will go.
+		var libdir string
+		for _, p := range pkgs {
+			plibdir := p.build.PkgTargetRoot
+			if gccgo {
+				plibdir = filepath.Join(plibdir, "shlibs")
+			}
+			if libdir == "" {
+				libdir = plibdir
+			} else if libdir != plibdir {
+				fatalf("multiple roots %s & %s", libdir, plibdir)
+			}
+		}
+		a.target = filepath.Join(libdir, libname)
+
+		// Now we can check whether we need to rebuild it.
+		stale := false
+		var built time.Time
+		if fi, err := os.Stat(a.target); err == nil {
+			built = fi.ModTime()
+		}
+		for _, p := range pkgs {
+			if p.target == "" {
+				continue
+			}
+			stale = stale || p.Stale
+			lstat, err := os.Stat(p.target)
+			if err != nil || lstat.ModTime().After(built) {
+				stale = true
+			}
+			a.deps = append(a.deps, b.action(depMode, depMode, p))
+		}
+
+		if stale {
+			a.f = (*builder).install
+			buildAction := b.libaction(libname, pkgs, modeBuild, depMode)
+			a.deps = []*action{buildAction}
+			for _, p := range pkgs {
+				if p.target == "" {
+					continue
+				}
+				shlibnameaction := &action{}
+				shlibnameaction.f = (*builder).installShlibname
+				shlibnameaction.target = p.target[:len(p.target)-2] + ".shlibname"
+				a.deps = append(a.deps, shlibnameaction)
+				shlibnameaction.deps = append(shlibnameaction.deps, buildAction)
+			}
+		}
+	} else {
+		fatalf("unregonized mode %v", mode)
+	}
+	return a
+}
+
 // actionList returns the list of actions in the dag rooted at root
 // as visited in a depth-first post-order traversal.
 func actionList(root *action) []*action {
@@ -673,6 +1073,31 @@
 	return all
 }
 
+// allArchiveActions returns a list of the archive dependencies of root.
+// This is needed because if package p depends on package q that is in libr.so, the
+// action graph looks like p->libr.so->q and so just scanning through p's
+// dependencies does not find the import dir for q.
+func allArchiveActions(root *action) []*action {
+	seen := map[*action]bool{}
+	r := []*action{}
+	var walk func(*action)
+	walk = func(a *action) {
+		if seen[a] {
+			return
+		}
+		seen[a] = true
+		if strings.HasSuffix(a.target, ".so") || a == root {
+			for _, a1 := range a.deps {
+				walk(a1)
+			}
+		} else if strings.HasSuffix(a.target, ".a") {
+			r = append(r, a)
+		}
+	}
+	walk(root)
+	return r
+}
+
 // do runs the action graph rooted at root.
 func (b *builder) do(root *action) {
 	// Build list of all actions, assigning depth-first post-order priority.
@@ -793,9 +1218,7 @@
 func (b *builder) build(a *action) (err error) {
 	// Return an error if the package has CXX files but it's not using
 	// cgo nor SWIG, since the CXX files can only be processed by cgo
-	// and SWIG (it's possible to have packages with C files without
-	// using cgo, they will get compiled with the plan9 C compiler and
-	// linked with the rest of the package).
+	// and SWIG.
 	if len(a.p.CXXFiles) > 0 && !a.p.usesCgo() && !a.p.usesSwig() {
 		return fmt.Errorf("can't build package %s because it contains C++ files (%s) but it's not using cgo nor SWIG",
 			a.p.ImportPath, strings.Join(a.p.CXXFiles, ","))
@@ -824,7 +1247,8 @@
 	}
 
 	if a.p.Standard && a.p.ImportPath == "runtime" && buildContext.Compiler == "gc" &&
-		!hasString(a.p.HFiles, "zasm_"+buildContext.GOOS+"_"+buildContext.GOARCH+".h") {
+		(!hasString(a.p.GoFiles, "zgoos_"+buildContext.GOOS+".go") ||
+			!hasString(a.p.GoFiles, "zgoarch_"+buildContext.GOARCH+".go")) {
 		return fmt.Errorf("%s/%s must be bootstrapped using make%v", buildContext.GOOS, buildContext.GOARCH, defaultSuffix())
 	}
 
@@ -842,19 +1266,35 @@
 		}
 	}
 
-	var gofiles, cfiles, sfiles, objects, cgoObjects, pcCFLAGS, pcLDFLAGS []string
+	var gofiles, cgofiles, cfiles, sfiles, cxxfiles, objects, cgoObjects, pcCFLAGS, pcLDFLAGS []string
 
 	gofiles = append(gofiles, a.p.GoFiles...)
+	cgofiles = append(cgofiles, a.p.CgoFiles...)
 	cfiles = append(cfiles, a.p.CFiles...)
 	sfiles = append(sfiles, a.p.SFiles...)
+	cxxfiles = append(cxxfiles, a.p.CXXFiles...)
 
 	if a.p.usesCgo() || a.p.usesSwig() {
 		if pcCFLAGS, pcLDFLAGS, err = b.getPkgConfigFlags(a.p); err != nil {
 			return
 		}
 	}
+
+	// Run SWIG on each .swig and .swigcxx file.
+	// Each run will generate two files, a .go file and a .c or .cxx file.
+	// The .go file will use import "C" and is to be processed by cgo.
+	if a.p.usesSwig() {
+		outGo, outC, outCXX, err := b.swig(a.p, obj, pcCFLAGS)
+		if err != nil {
+			return err
+		}
+		cgofiles = append(cgofiles, outGo...)
+		cfiles = append(cfiles, outC...)
+		cxxfiles = append(cxxfiles, outCXX...)
+	}
+
 	// Run cgo.
-	if a.p.usesCgo() {
+	if a.p.usesCgo() || a.p.usesSwig() {
 		// In a package using cgo, cgo compiles the C, C++ and assembly files with gcc.
 		// There is one exception: runtime/cgo's job is to bridge the
 		// cgo and non-cgo worlds, so it necessarily has files in both.
@@ -883,31 +1323,7 @@
 		if a.cgo != nil && a.cgo.target != "" {
 			cgoExe = a.cgo.target
 		}
-		outGo, outObj, err := b.cgo(a.p, cgoExe, obj, pcCFLAGS, pcLDFLAGS, gccfiles, a.p.CXXFiles, a.p.MFiles)
-		if err != nil {
-			return err
-		}
-		cgoObjects = append(cgoObjects, outObj...)
-		gofiles = append(gofiles, outGo...)
-	}
-
-	// Run SWIG.
-	if a.p.usesSwig() {
-		// In a package using SWIG, any .c or .s files are
-		// compiled with gcc.
-		gccfiles := append(cfiles, sfiles...)
-		cxxfiles, mfiles := a.p.CXXFiles, a.p.MFiles
-		cfiles = nil
-		sfiles = nil
-
-		// Don't build c/c++ files twice if cgo is enabled (mainly for pkg-config).
-		if a.p.usesCgo() {
-			cxxfiles = nil
-			gccfiles = nil
-			mfiles = nil
-		}
-
-		outGo, outObj, err := b.swig(a.p, obj, pcCFLAGS, gccfiles, cxxfiles, mfiles)
+		outGo, outObj, err := b.cgo(a.p, cgoExe, obj, pcCFLAGS, pcLDFLAGS, cgofiles, gccfiles, cxxfiles, a.p.MFiles)
 		if err != nil {
 			return err
 		}
@@ -949,10 +1365,10 @@
 	}
 
 	// Prepare Go import path list.
-	inc := b.includeArgs("-I", a.deps)
+	inc := b.includeArgs("-I", allArchiveActions(a))
 
 	// Compile Go.
-	ofile, out, err := buildToolchain.gc(b, a.p, a.objpkg, obj, inc, gofiles)
+	ofile, out, err := buildToolchain.gc(b, a.p, a.objpkg, obj, len(sfiles) > 0, inc, gofiles)
 	if len(out) > 0 {
 		b.showOutput(a.p.Dir, a.p.ImportPath, b.processOutput(out))
 		if err != nil {
@@ -977,29 +1393,24 @@
 		switch {
 		case strings.HasSuffix(name, _goos_goarch):
 			targ := file[:len(name)-len(_goos_goarch)] + "_GOOS_GOARCH." + ext
-			if err := b.copyFile(a, obj+targ, filepath.Join(a.p.Dir, file), 0644); err != nil {
+			if err := b.copyFile(a, obj+targ, filepath.Join(a.p.Dir, file), 0644, true); err != nil {
 				return err
 			}
 		case strings.HasSuffix(name, _goarch):
 			targ := file[:len(name)-len(_goarch)] + "_GOARCH." + ext
-			if err := b.copyFile(a, obj+targ, filepath.Join(a.p.Dir, file), 0644); err != nil {
+			if err := b.copyFile(a, obj+targ, filepath.Join(a.p.Dir, file), 0644, true); err != nil {
 				return err
 			}
 		case strings.HasSuffix(name, _goos):
 			targ := file[:len(name)-len(_goos)] + "_GOOS." + ext
-			if err := b.copyFile(a, obj+targ, filepath.Join(a.p.Dir, file), 0644); err != nil {
+			if err := b.copyFile(a, obj+targ, filepath.Join(a.p.Dir, file), 0644, true); err != nil {
 				return err
 			}
 		}
 	}
 
-	objExt := archChar
-	if _, ok := buildToolchain.(gccgoToolchain); ok {
-		objExt = "o"
-	}
-
 	for _, file := range cfiles {
-		out := file[:len(file)-len(".c")] + "." + objExt
+		out := file[:len(file)-len(".c")] + ".o"
 		if err := buildToolchain.cc(b, a.p, obj, obj+out, file); err != nil {
 			return err
 		}
@@ -1008,7 +1419,7 @@
 
 	// Assemble .s files.
 	for _, file := range sfiles {
-		out := file[:len(file)-len(".s")] + "." + objExt
+		out := file[:len(file)-len(".s")] + ".o"
 		if err := buildToolchain.asm(b, a.p, obj, obj+out, file); err != nil {
 			return err
 		}
@@ -1018,7 +1429,7 @@
 	// NOTE(rsc): On Windows, it is critically important that the
 	// gcc-compiled objects (cgoObjects) be listed after the ordinary
 	// objects in the archive.  I do not know why this is.
-	// http://golang.org/issue/2601
+	// https://golang.org/issue/2601
 	objects = append(objects, cgoObjects...)
 
 	// Add system object files.
@@ -1043,7 +1454,7 @@
 		// linker needs the whole dependency tree.
 		all := actionList(a)
 		all = all[:len(all)-1] // drop a
-		if err := buildToolchain.ld(b, a.p, a.target, all, a.objpkg, objects); err != nil {
+		if err := buildToolchain.ld(b, a, a.target, all, a.objpkg, objects); err != nil {
 			return err
 		}
 	}
@@ -1079,6 +1490,24 @@
 	return
 }
 
+func (b *builder) installShlibname(a *action) error {
+	a1 := a.deps[0]
+	err := ioutil.WriteFile(a.target, []byte(filepath.Base(a1.target)+"\n"), 0644)
+	if err != nil {
+		return err
+	}
+	if buildX {
+		b.showcmd("", "echo '%s' > %s # internal", filepath.Base(a1.target), a.target)
+	}
+	return nil
+}
+
+func (b *builder) linkShared(a *action) (err error) {
+	allactions := actionList(a)
+	allactions = allactions[:len(allactions)-1]
+	return buildToolchain.ldShared(b, a.deps, a.target, allactions)
+}
+
 // install is the action for installing a single package or executable.
 func (b *builder) install(a *action) (err error) {
 	defer func() {
@@ -1089,7 +1518,11 @@
 	a1 := a.deps[0]
 	perm := os.FileMode(0644)
 	if a1.link {
-		perm = 0755
+		switch buildBuildmode {
+		case "c-archive", "c-shared":
+		default:
+			perm = 0755
+		}
 	}
 
 	// make target directory
@@ -1109,7 +1542,7 @@
 		defer os.Remove(a1.target)
 	}
 
-	return b.moveOrCopyFile(a, a.target, a1.target, perm)
+	return b.moveOrCopyFile(a, a.target, a1.target, perm, false)
 }
 
 // includeArgs returns the -I or -L directory list for access
@@ -1126,6 +1559,9 @@
 	// This is the $WORK/my/package/_test directory for the
 	// package being built, so there are few of these.
 	for _, a1 := range all {
+		if a1.p == nil {
+			continue
+		}
 		if dir := a1.pkgdir; dir != a1.p.build.PkgRoot && !incMap[dir] {
 			incMap[dir] = true
 			inc = append(inc, flag, dir)
@@ -1138,17 +1574,12 @@
 
 	// Finally, look in the installed package directories for each action.
 	for _, a1 := range all {
+		if a1.p == nil {
+			continue
+		}
 		if dir := a1.pkgdir; dir == a1.p.build.PkgRoot && !incMap[dir] {
 			incMap[dir] = true
-			if _, ok := buildToolchain.(gccgoToolchain); ok {
-				dir = filepath.Join(dir, "gccgo_"+goos+"_"+goarch)
-			} else {
-				dir = filepath.Join(dir, goos+"_"+goarch)
-				if buildContext.InstallSuffix != "" {
-					dir += "_" + buildContext.InstallSuffix
-				}
-			}
-			inc = append(inc, flag, dir)
+			inc = append(inc, flag, a1.p.build.PkgTargetRoot)
 		}
 	}
 
@@ -1156,7 +1587,7 @@
 }
 
 // moveOrCopyFile is like 'mv src dst' or 'cp src dst'.
-func (b *builder) moveOrCopyFile(a *action, dst, src string, perm os.FileMode) error {
+func (b *builder) moveOrCopyFile(a *action, dst, src string, perm os.FileMode, force bool) error {
 	if buildN {
 		b.showcmd("", "mv %s %s", src, dst)
 		return nil
@@ -1173,11 +1604,11 @@
 		}
 	}
 
-	return b.copyFile(a, dst, src, perm)
+	return b.copyFile(a, dst, src, perm, force)
 }
 
 // copyFile is like 'cp src dst'.
-func (b *builder) copyFile(a *action, dst, src string, perm os.FileMode) error {
+func (b *builder) copyFile(a *action, dst, src string, perm os.FileMode, force bool) error {
 	if buildN || buildX {
 		b.showcmd("", "cp %s %s", src, dst)
 		if buildN {
@@ -1198,7 +1629,7 @@
 		if fi.IsDir() {
 			return fmt.Errorf("build output %q already exists and is a directory", dst)
 		}
-		if !isObject(dst) {
+		if !force && !isObject(dst) {
 			return fmt.Errorf("build output %q already exists and is not an object file", dst)
 		}
 	}
@@ -1235,10 +1666,30 @@
 	return nil
 }
 
+// Install the cgo export header file, if there is one.
+func (b *builder) installHeader(a *action) error {
+	src := a.objdir + "_cgo_install.h"
+	if _, err := os.Stat(src); os.IsNotExist(err) {
+		// If the file does not exist, there are no exported
+		// functions, and we do not install anything.
+		return nil
+	}
+
+	dir, _ := filepath.Split(a.target)
+	if dir != "" {
+		if err := b.mkdir(dir); err != nil {
+			return err
+		}
+	}
+
+	return b.moveOrCopyFile(a, a.target, src, 0644, true)
+}
+
 // cover runs, in effect,
 //	go tool cover -mode=b.coverMode -var="varName" -o dst.go src.go
 func (b *builder) cover(a *action, dst, src string, perm os.FileMode, varName string) error {
 	return b.run(a.objdir, "cover "+a.p.ImportPath, nil,
+		buildToolExec,
 		tool("cover"),
 		"-mode", a.p.coverMode,
 		"-var", varName,
@@ -1247,15 +1698,15 @@
 }
 
 var objectMagic = [][]byte{
-	{'!', '<', 'a', 'r', 'c', 'h', '>', '\n'},        // Package archive
-	{'\x7F', 'E', 'L', 'F'},                          // ELF
-	{0xFE, 0xED, 0xFA, 0xCE},                         // Mach-O big-endian 32-bit
-	{0xFE, 0xED, 0xFA, 0xCF},                         // Mach-O big-endian 64-bit
-	{0xCE, 0xFA, 0xED, 0xFE},                         // Mach-O little-endian 32-bit
-	{0xCF, 0xFA, 0xED, 0xFE},                         // Mach-O little-endian 64-bit
-	{0x4d, 0x5a, 0x90, 0x00, 0x03, 0x00, 0x04, 0x00}, // PE (Windows) as generated by 6l/8l
-	{0x00, 0x00, 0x01, 0xEB},                         // Plan 9 i386
-	{0x00, 0x00, 0x8a, 0x97},                         // Plan 9 amd64
+	{'!', '<', 'a', 'r', 'c', 'h', '>', '\n'}, // Package archive
+	{'\x7F', 'E', 'L', 'F'},                   // ELF
+	{0xFE, 0xED, 0xFA, 0xCE},                  // Mach-O big-endian 32-bit
+	{0xFE, 0xED, 0xFA, 0xCF},                  // Mach-O big-endian 64-bit
+	{0xCE, 0xFA, 0xED, 0xFE},                  // Mach-O little-endian 32-bit
+	{0xCF, 0xFA, 0xED, 0xFE},                  // Mach-O little-endian 64-bit
+	{0x4d, 0x5a, 0x90, 0x00, 0x03, 0x00},      // PE (Windows) as generated by 6l/8l and gcc
+	{0x00, 0x00, 0x01, 0xEB},                  // Plan 9 i386
+	{0x00, 0x00, 0x8a, 0x97},                  // Plan 9 amd64
 }
 
 func isObject(s string) bool {
@@ -1436,7 +1887,7 @@
 		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
@@ -1478,7 +1929,7 @@
 		// Sleeping when we observe the race seems to be the most reliable
 		// option we have.
 		//
-		// http://golang.org/issue/3001
+		// https://golang.org/issue/3001
 		//
 		if err != nil && nbusy < 3 && strings.Contains(err.Error(), "text file busy") {
 			time.Sleep(100 * time.Millisecond << uint(nbusy))
@@ -1561,7 +2012,7 @@
 	// gc runs the compiler in a specific directory on a set of files
 	// and returns the name of the generated output file.
 	// The compiler runs in the directory dir.
-	gc(b *builder, p *Package, archive, obj string, importArgs []string, gofiles []string) (ofile string, out []byte, err error)
+	gc(b *builder, p *Package, archive, obj string, asmhdr bool, importArgs []string, gofiles []string) (ofile string, out []byte, err error)
 	// cc runs the toolchain's C compiler in a directory on a C file
 	// to produce an output file.
 	cc(b *builder, p *Package, objdir, ofile, cfile string) error
@@ -1574,8 +2025,10 @@
 	// an archive from a set of object files.
 	// typically it is run in the object directory.
 	pack(b *builder, p *Package, objDir, afile string, ofiles []string) error
-	// ld runs the linker to create a package starting at mainpkg.
-	ld(b *builder, p *Package, out string, allactions []*action, mainpkg string, ofiles []string) error
+	// ld runs the linker to create an executable starting at mainpkg.
+	ld(b *builder, root *action, out string, allactions []*action, mainpkg string, ofiles []string) error
+	// ldShared runs the linker to create a shared library containing the pkgs built by toplevelactions
+	ldShared(b *builder, toplevelactions []*action, out string, allactions []*action) error
 
 	compiler() string
 	linker() string
@@ -1598,7 +2051,7 @@
 	return ""
 }
 
-func (noToolchain) gc(b *builder, p *Package, archive, obj string, importArgs []string, gofiles []string) (ofile string, out []byte, err error) {
+func (noToolchain) gc(b *builder, p *Package, archive, obj string, asmhdr bool, importArgs []string, gofiles []string) (ofile string, out []byte, err error) {
 	return "", nil, noCompiler()
 }
 
@@ -1615,7 +2068,11 @@
 	return noCompiler()
 }
 
-func (noToolchain) ld(b *builder, p *Package, out string, allactions []*action, mainpkg string, ofiles []string) error {
+func (noToolchain) ld(b *builder, root *action, out string, allactions []*action, mainpkg string, ofiles []string) error {
+	return noCompiler()
+}
+
+func (noToolchain) ldShared(b *builder, toplevelactions []*action, out string, allactions []*action) error {
 	return noCompiler()
 }
 
@@ -1627,24 +2084,27 @@
 type gcToolchain struct{}
 
 func (gcToolchain) compiler() string {
-	return tool(archChar + "g")
+	return tool("compile")
 }
 
 func (gcToolchain) linker() string {
-	return tool(archChar + "l")
+	return tool("link")
 }
 
-func (gcToolchain) gc(b *builder, p *Package, archive, obj string, importArgs []string, gofiles []string) (ofile string, output []byte, err error) {
+func (gcToolchain) gc(b *builder, p *Package, archive, obj string, asmhdr bool, importArgs []string, gofiles []string) (ofile string, output []byte, err error) {
 	if archive != "" {
 		ofile = archive
 	} else {
-		out := "_go_." + archChar
+		out := "_go_.o"
 		ofile = obj + out
 	}
 
 	gcargs := []string{"-p", p.ImportPath}
+	if p.Name == "main" {
+		gcargs[1] = "main"
+	}
 	if p.Standard && p.ImportPath == "runtime" {
-		// runtime compiles with a special 6g flag to emit
+		// runtime compiles with a special gc flag to emit
 		// additional reflect type data.
 		gcargs = append(gcargs, "-+")
 	}
@@ -1666,24 +2126,76 @@
 	if buildContext.InstallSuffix != "" {
 		gcargs = append(gcargs, "-installsuffix", buildContext.InstallSuffix)
 	}
+	if p.buildID != "" {
+		gcargs = append(gcargs, "-buildid", p.buildID)
+	}
 
-	args := stringList(tool(archChar+"g"), "-o", ofile, "-trimpath", b.work, buildGcflags, gcargs, "-D", p.localPrefix, importArgs)
+	for _, path := range p.Imports {
+		if i := strings.LastIndex(path, "/vendor/"); i >= 0 {
+			gcargs = append(gcargs, "-importmap", path[i+len("/vendor/"):]+"="+path)
+		} else if strings.HasPrefix(path, "vendor/") {
+			gcargs = append(gcargs, "-importmap", path[len("vendor/"):]+"="+path)
+		}
+	}
+
+	for _, path := range p.Imports {
+		if i := strings.LastIndex(path, "/vendor/"); i >= 0 {
+			gcargs = append(gcargs, "-importmap", path[i+len("/vendor/"):]+"="+path)
+		} else if strings.HasPrefix(path, "vendor/") {
+			gcargs = append(gcargs, "-importmap", path[len("vendor/"):]+"="+path)
+		}
+	}
+
+	args := []interface{}{buildToolExec, tool("compile"), "-o", ofile, "-trimpath", b.work, buildGcflags, gcargs, "-D", p.localPrefix, importArgs}
 	if ofile == archive {
 		args = append(args, "-pack")
 	}
+	if asmhdr {
+		args = append(args, "-asmhdr", obj+"go_asm.h")
+	}
 	for _, f := range gofiles {
 		args = append(args, mkAbs(p.Dir, f))
 	}
 
-	output, err = b.runOut(p.Dir, p.ImportPath, nil, args)
+	output, err = b.runOut(p.Dir, p.ImportPath, nil, args...)
 	return ofile, output, err
 }
 
 func (gcToolchain) asm(b *builder, p *Package, obj, ofile, sfile string) error {
 	// Add -I pkg/GOOS_GOARCH so #include "textflag.h" works in .s files.
-	inc := filepath.Join(goroot, "pkg", fmt.Sprintf("%s_%s", goos, goarch))
+	inc := filepath.Join(goroot, "pkg", "include")
 	sfile = mkAbs(p.Dir, sfile)
-	return b.run(p.Dir, p.ImportPath, nil, tool(archChar+"a"), "-trimpath", b.work, "-I", obj, "-I", inc, "-o", ofile, "-D", "GOOS_"+goos, "-D", "GOARCH_"+goarch, sfile)
+	args := []interface{}{buildToolExec, tool("asm"), "-o", ofile, "-trimpath", b.work, "-I", obj, "-I", inc, "-D", "GOOS_" + goos, "-D", "GOARCH_" + goarch, buildAsmflags, sfile}
+	if err := b.run(p.Dir, p.ImportPath, nil, args...); err != nil {
+		return err
+	}
+	return nil
+}
+
+// toolVerify checks that the command line args writes the same output file
+// if run using newTool instead.
+// Unused now but kept around for future use.
+func toolVerify(b *builder, p *Package, newTool string, ofile string, args []interface{}) error {
+	newArgs := make([]interface{}, len(args))
+	copy(newArgs, args)
+	newArgs[1] = tool(newTool)
+	newArgs[3] = ofile + ".new" // x.6 becomes x.6.new
+	if err := b.run(p.Dir, p.ImportPath, nil, newArgs...); err != nil {
+		return err
+	}
+	data1, err := ioutil.ReadFile(ofile)
+	if err != nil {
+		return err
+	}
+	data2, err := ioutil.ReadFile(ofile + ".new")
+	if err != nil {
+		return err
+	}
+	if !bytes.Equal(data1, data2) {
+		return fmt.Errorf("%s and %s produced different output files:\n%s\n%s", filepath.Base(args[1].(string)), newTool, strings.Join(stringList(args...), " "), strings.Join(stringList(newArgs...), " "))
+	}
+	os.Remove(ofile + ".new")
+	return nil
 }
 
 func (gcToolchain) pkgpath(basedir string, p *Package) string {
@@ -1722,7 +2234,7 @@
 
 	// Need actual pack.
 	cmdline[0] = tool("pack")
-	return b.run(p.Dir, p.ImportPath, nil, cmdline)
+	return b.run(p.Dir, p.ImportPath, nil, buildToolExec, cmdline)
 }
 
 func packInternal(b *builder, afile string, ofiles []string) error {
@@ -1775,21 +2287,49 @@
 	return dst.Close()
 }
 
-func (gcToolchain) ld(b *builder, p *Package, out string, allactions []*action, mainpkg string, ofiles []string) error {
+// setextld sets the appropriate linker flags for the specified compiler.
+func setextld(ldflags []string, compiler []string) []string {
+	for _, f := range ldflags {
+		if f == "-extld" || strings.HasPrefix(f, "-extld=") {
+			// don't override -extld if supplied
+			return ldflags
+		}
+	}
+	ldflags = append(ldflags, "-extld="+compiler[0])
+	if len(compiler) > 1 {
+		extldflags := false
+		add := strings.Join(compiler[1:], " ")
+		for i, f := range ldflags {
+			if f == "-extldflags" && i+1 < len(ldflags) {
+				ldflags[i+1] = add + " " + ldflags[i+1]
+				extldflags = true
+				break
+			} else if strings.HasPrefix(f, "-extldflags=") {
+				ldflags[i] = "-extldflags=" + add + " " + ldflags[i][len("-extldflags="):]
+				extldflags = true
+				break
+			}
+		}
+		if !extldflags {
+			ldflags = append(ldflags, "-extldflags="+add)
+		}
+	}
+	return ldflags
+}
+
+func (gcToolchain) ld(b *builder, root *action, out string, allactions []*action, mainpkg string, ofiles []string) error {
 	importArgs := b.includeArgs("-L", allactions)
-	cxx := len(p.CXXFiles) > 0
+	cxx := len(root.p.CXXFiles) > 0 || len(root.p.SwigCXXFiles) > 0
 	for _, a := range allactions {
-		if a.p != nil && len(a.p.CXXFiles) > 0 {
+		if a.p != nil && (len(a.p.CXXFiles) > 0 || len(a.p.SwigCXXFiles) > 0) {
 			cxx = true
 		}
 	}
-	ldflags := buildLdflags
-	// Limit slice capacity so that concurrent appends do not race on the shared array.
-	ldflags = ldflags[:len(ldflags):len(ldflags)]
+	var ldflags []string
 	if buildContext.InstallSuffix != "" {
 		ldflags = append(ldflags, "-installsuffix", buildContext.InstallSuffix)
 	}
-	if p.omitDWARF {
+	if root.p.omitDWARF {
 		ldflags = append(ldflags, "-w")
 	}
 
@@ -1797,56 +2337,67 @@
 	// appropriate linker. In case of C++ code, use the compiler named
 	// by the CXX environment variable or defaultCXX if CXX is not set.
 	// Else, use the CC environment variable and defaultCC as fallback.
-	extld := false
-	for _, f := range ldflags {
-		if f == "-extld" || strings.HasPrefix(f, "-extld=") {
-			extld = true
-			break
+	var compiler []string
+	if cxx {
+		compiler = envList("CXX", defaultCXX)
+	} else {
+		compiler = envList("CC", defaultCC)
+	}
+	ldflags = setextld(ldflags, compiler)
+	ldflags = append(ldflags, "-buildmode="+ldBuildmode)
+	if root.p.buildID != "" {
+		ldflags = append(ldflags, "-buildid="+root.p.buildID)
+	}
+	ldflags = append(ldflags, buildLdflags...)
+
+	// On OS X when using external linking to build a shared library,
+	// the argument passed here to -o ends up recorded in the final
+	// shared library in the LC_ID_DYLIB load command.
+	// To avoid putting the temporary output directory name there
+	// (and making the resulting shared library useless),
+	// run the link in the output directory so that -o can name
+	// just the final path element.
+	dir := "."
+	if goos == "darwin" && buildBuildmode == "c-shared" {
+		dir, out = filepath.Split(out)
+	}
+
+	return b.run(dir, root.p.ImportPath, nil, buildToolExec, tool("link"), "-o", out, importArgs, ldflags, mainpkg)
+}
+
+func (gcToolchain) ldShared(b *builder, toplevelactions []*action, out string, allactions []*action) error {
+	importArgs := b.includeArgs("-L", allactions)
+	ldflags := []string{"-installsuffix", buildContext.InstallSuffix}
+	ldflags = append(ldflags, "-buildmode=shared")
+	ldflags = append(ldflags, buildLdflags...)
+	cxx := false
+	for _, a := range allactions {
+		if a.p != nil && (len(a.p.CXXFiles) > 0 || len(a.p.SwigCXXFiles) > 0) {
+			cxx = true
 		}
 	}
-	if !extld {
-		var compiler []string
-		if cxx {
-			compiler = envList("CXX", defaultCXX)
-		} else {
-			compiler = envList("CC", defaultCC)
-		}
-		ldflags = append(ldflags, "-extld="+compiler[0])
-		if len(compiler) > 1 {
-			extldflags := false
-			add := strings.Join(compiler[1:], " ")
-			for i, f := range ldflags {
-				if f == "-extldflags" && i+1 < len(ldflags) {
-					ldflags[i+1] = add + " " + ldflags[i+1]
-					extldflags = true
-					break
-				} else if strings.HasPrefix(f, "-extldflags=") {
-					ldflags[i] = "-extldflags=" + add + " " + ldflags[i][len("-extldflags="):]
-					extldflags = true
-					break
-				}
-			}
-			if !extldflags {
-				ldflags = append(ldflags, "-extldflags="+add)
-			}
-		}
+	// If the user has not specified the -extld option, then specify the
+	// appropriate linker. In case of C++ code, use the compiler named
+	// by the CXX environment variable or defaultCXX if CXX is not set.
+	// Else, use the CC environment variable and defaultCC as fallback.
+	var compiler []string
+	if cxx {
+		compiler = envList("CXX", defaultCXX)
+	} else {
+		compiler = envList("CC", defaultCC)
 	}
-	return b.run(".", p.ImportPath, nil, tool(archChar+"l"), "-o", out, importArgs, ldflags, mainpkg)
+	ldflags = setextld(ldflags, compiler)
+	for _, d := range toplevelactions {
+		if !strings.HasSuffix(d.target, ".a") { // omit unsafe etc and actions for other shared libraries
+			continue
+		}
+		ldflags = append(ldflags, d.p.ImportPath+"="+d.target)
+	}
+	return b.run(".", out, nil, buildToolExec, tool("link"), "-o", out, importArgs, ldflags)
 }
 
 func (gcToolchain) cc(b *builder, p *Package, objdir, ofile, cfile string) error {
-	inc := filepath.Join(goroot, "pkg", fmt.Sprintf("%s_%s", goos, goarch))
-	cfile = mkAbs(p.Dir, cfile)
-	warn := []string{"-w"}
-	if p.usesSwig() {
-		// When using SWIG, this compiler is only used to
-		// compile the C files generated by SWIG.
-		// We don't want warnings.
-		// See issue 9065 for details.
-		warn = nil
-	}
-	args := stringList(tool(archChar+"c"), "-F", "-V", warn, "-trimpath", b.work, "-I", objdir, "-I", inc, "-o", ofile, buildCcflags, "-D", "GOOS_"+goos, "-D", "GOARCH_"+goarch, cfile)
-	return b.run(p.Dir, p.ImportPath, nil, args)
+	return fmt.Errorf("%s: C source files not supported without cgo", mkAbs(p.Dir, cfile))
 }
 
 // The Gccgo toolchain.
@@ -1870,7 +2421,7 @@
 	return gccgoBin
 }
 
-func (tools gccgoToolchain) gc(b *builder, p *Package, archive, obj string, importArgs []string, gofiles []string) (ofile string, output []byte, err error) {
+func (tools gccgoToolchain) gc(b *builder, p *Package, archive, obj string, asmhdr bool, importArgs []string, gofiles []string) (ofile string, output []byte, err error) {
 	out := "_go_.o"
 	ofile = obj + out
 	gcargs := []string{"-g"}
@@ -1896,8 +2447,8 @@
 	if pkgpath := gccgoCleanPkgpath(p); pkgpath != "" {
 		defs = append(defs, `-D`, `GOPKGPATH="`+pkgpath+`"`)
 	}
+	defs = tools.maybePIC(defs)
 	defs = append(defs, b.gccArchArgs()...)
-
 	return b.run(p.Dir, p.ImportPath, nil, tools.compiler(), "-c", "-I", obj, "-o", ofile, defs, sfile)
 }
 
@@ -1916,30 +2467,46 @@
 	return b.run(p.Dir, p.ImportPath, nil, "ar", "cru", mkAbs(objDir, afile), absOfiles)
 }
 
-func (tools gccgoToolchain) ld(b *builder, p *Package, out string, allactions []*action, mainpkg string, ofiles []string) error {
+func (tools gccgoToolchain) ld(b *builder, root *action, out string, allactions []*action, mainpkg string, ofiles []string) error {
 	// gccgo needs explicit linking with all package dependencies,
 	// and all LDFLAGS from cgo dependencies.
 	apackagesSeen := make(map[*Package]bool)
 	afiles := []string{}
+	shlibs := []string{}
 	xfiles := []string{}
 	ldflags := b.gccArchArgs()
 	cgoldflags := []string{}
 	usesCgo := false
-	cxx := len(p.CXXFiles) > 0
-	objc := len(p.MFiles) > 0
+	cxx := len(root.p.CXXFiles) > 0 || len(root.p.SwigCXXFiles) > 0
+	objc := len(root.p.MFiles) > 0
 
-	// Prefer the output of an install action to the output of a build action,
-	// because the install action will delete the output of the build action.
-	// Iterate over the list backward (reverse dependency order) so that we
-	// always see the install before the build.
-	for i := len(allactions) - 1; i >= 0; i-- {
-		a := allactions[i]
-		if !a.p.Standard {
-			if a.p != nil && !apackagesSeen[a.p] {
+	actionsSeen := make(map[*action]bool)
+	// Make a pre-order depth-first traversal of the action graph, taking note of
+	// whether a shared library action has been seen on the way to an action (the
+	// construction of the graph means that if any path to a node passes through
+	// a shared library action, they all do).
+	var walk func(a *action, seenShlib bool)
+	walk = func(a *action, seenShlib bool) {
+		if actionsSeen[a] {
+			return
+		}
+		actionsSeen[a] = true
+		if a.p != nil && !seenShlib {
+			if a.p.Standard {
+				return
+			}
+			// We record the target of the first time we see a .a file
+			// for a package to make sure that we prefer the 'install'
+			// rather than the 'build' location (which may not exist any
+			// more). We still need to traverse the dependencies of the
+			// build action though so saying
+			// if apackagesSeen[a.p] { return }
+			// doesn't work.
+			if !apackagesSeen[a.p] {
 				apackagesSeen[a.p] = true
 				if a.p.fake && a.p.external {
 					// external _tests, if present must come before
-					// internal _tests. Store these on a seperate list
+					// internal _tests. Store these on a separate list
 					// and place them at the head after this loop.
 					xfiles = append(xfiles, a.target)
 				} else if a.p.fake {
@@ -1950,54 +2517,174 @@
 				}
 			}
 		}
+		if strings.HasSuffix(a.target, ".so") {
+			shlibs = append(shlibs, a.target)
+			seenShlib = true
+		}
+		for _, a1 := range a.deps {
+			walk(a1, seenShlib)
+		}
+	}
+	for _, a1 := range root.deps {
+		walk(a1, false)
 	}
 	afiles = append(xfiles, afiles...)
 
 	for _, a := range allactions {
-		if a.p != nil {
+		// Gather CgoLDFLAGS, but not from standard packages.
+		// The go tool can dig up runtime/cgo from GOROOT and
+		// think that it should use its CgoLDFLAGS, but gccgo
+		// doesn't use runtime/cgo.
+		if a.p == nil {
+			continue
+		}
+		if !a.p.Standard {
 			cgoldflags = append(cgoldflags, a.p.CgoLDFLAGS...)
-			if len(a.p.CgoFiles) > 0 {
-				usesCgo = true
-			}
-			if a.p.usesSwig() {
-				usesCgo = true
-			}
-			if len(a.p.CXXFiles) > 0 {
-				cxx = true
-			}
-			if len(a.p.MFiles) > 0 {
-				objc = true
-			}
+		}
+		if len(a.p.CgoFiles) > 0 {
+			usesCgo = true
+		}
+		if a.p.usesSwig() {
+			usesCgo = true
+		}
+		if len(a.p.CXXFiles) > 0 || len(a.p.SwigCXXFiles) > 0 {
+			cxx = true
+		}
+		if len(a.p.MFiles) > 0 {
+			objc = true
 		}
 	}
+
+	ldflags = append(ldflags, "-Wl,--whole-archive")
 	ldflags = append(ldflags, afiles...)
+	ldflags = append(ldflags, "-Wl,--no-whole-archive")
+
 	ldflags = append(ldflags, cgoldflags...)
 	ldflags = append(ldflags, envList("CGO_LDFLAGS", "")...)
-	ldflags = append(ldflags, p.CgoLDFLAGS...)
-	if usesCgo && goos == "linux" {
-		ldflags = append(ldflags, "-Wl,-E")
+	ldflags = append(ldflags, root.p.CgoLDFLAGS...)
+
+	ldflags = stringList("-Wl,-(", ldflags, "-Wl,-)")
+
+	for _, shlib := range shlibs {
+		ldflags = append(
+			ldflags,
+			"-L"+filepath.Dir(shlib),
+			"-Wl,-rpath="+filepath.Dir(shlib),
+			"-l"+strings.TrimSuffix(
+				strings.TrimPrefix(filepath.Base(shlib), "lib"),
+				".so"))
 	}
-	if cxx {
-		ldflags = append(ldflags, "-lstdc++")
+
+	var realOut string
+	switch ldBuildmode {
+	case "exe":
+		if usesCgo && goos == "linux" {
+			ldflags = append(ldflags, "-Wl,-E")
+		}
+
+	case "c-archive":
+		// Link the Go files into a single .o, and also link
+		// in -lgolibbegin.
+		//
+		// We need to use --whole-archive with -lgolibbegin
+		// because it doesn't define any symbols that will
+		// cause the contents to be pulled in; it's just
+		// initialization code.
+		//
+		// The user remains responsible for linking against
+		// -lgo -lpthread -lm in the final link.  We can't use
+		// -r to pick them up because we can't combine
+		// split-stack and non-split-stack code in a single -r
+		// link, and libgo picks up non-split-stack code from
+		// libffi.
+		ldflags = append(ldflags, "-Wl,-r", "-nostdlib", "-Wl,--whole-archive", "-lgolibbegin", "-Wl,--no-whole-archive")
+
+		// We are creating an object file, so we don't want a build ID.
+		ldflags = b.disableBuildID(ldflags)
+
+		realOut = out
+		out = out + ".o"
+
+	case "c-shared":
+		ldflags = append(ldflags, "-shared", "-nostdlib", "-Wl,--whole-archive", "-lgolibbegin", "-Wl,--no-whole-archive", "-lgo", "-lgcc_s", "-lgcc")
+
+	default:
+		fatalf("-buildmode=%s not supported for gccgo", ldBuildmode)
 	}
-	if objc {
-		ldflags = append(ldflags, "-lobjc")
+
+	switch ldBuildmode {
+	case "exe", "c-shared":
+		if cxx {
+			ldflags = append(ldflags, "-lstdc++")
+		}
+		if objc {
+			ldflags = append(ldflags, "-lobjc")
+		}
 	}
-	return b.run(".", p.ImportPath, nil, tools.linker(), "-o", out, ofiles, "-Wl,-(", ldflags, "-Wl,-)", buildGccgoflags)
+
+	if err := b.run(".", root.p.ImportPath, nil, tools.linker(), "-o", out, ofiles, ldflags, buildGccgoflags); err != nil {
+		return err
+	}
+
+	switch ldBuildmode {
+	case "c-archive":
+		if err := b.run(".", root.p.ImportPath, nil, "ar", "rc", realOut, out); err != nil {
+			return err
+		}
+	}
+	return nil
 }
 
-func (gccgoToolchain) cc(b *builder, p *Package, objdir, ofile, cfile string) error {
-	inc := filepath.Join(goroot, "pkg", fmt.Sprintf("%s_%s", goos, goarch))
+func (tools gccgoToolchain) ldShared(b *builder, toplevelactions []*action, out string, allactions []*action) error {
+	args := []string{"-o", out, "-shared", "-nostdlib", "-zdefs", "-Wl,--whole-archive"}
+	for _, a := range toplevelactions {
+		args = append(args, a.target)
+	}
+	args = append(args, "-Wl,--no-whole-archive", "-shared", "-nostdlib", "-lgo", "-lgcc_s", "-lgcc", "-lc")
+	shlibs := []string{}
+	for _, a := range allactions {
+		if strings.HasSuffix(a.target, ".so") {
+			shlibs = append(shlibs, a.target)
+		}
+	}
+	for _, shlib := range shlibs {
+		args = append(
+			args,
+			"-L"+filepath.Dir(shlib),
+			"-Wl,-rpath="+filepath.Dir(shlib),
+			"-l"+strings.TrimSuffix(
+				strings.TrimPrefix(filepath.Base(shlib), "lib"),
+				".so"))
+	}
+	return b.run(".", out, nil, tools.linker(), args, buildGccgoflags)
+}
+
+func (tools gccgoToolchain) cc(b *builder, p *Package, objdir, ofile, cfile string) error {
+	inc := filepath.Join(goroot, "pkg", "include")
 	cfile = mkAbs(p.Dir, cfile)
 	defs := []string{"-D", "GOOS_" + goos, "-D", "GOARCH_" + goarch}
 	defs = append(defs, b.gccArchArgs()...)
 	if pkgpath := gccgoCleanPkgpath(p); pkgpath != "" {
 		defs = append(defs, `-D`, `GOPKGPATH="`+pkgpath+`"`)
 	}
+	switch goarch {
+	case "386", "amd64":
+		defs = append(defs, "-fsplit-stack")
+	}
+	defs = tools.maybePIC(defs)
 	return b.run(p.Dir, p.ImportPath, nil, envList("CC", defaultCC), "-Wall", "-g",
 		"-I", objdir, "-I", inc, "-o", ofile, defs, "-c", cfile)
 }
 
+// maybePIC adds -fPIC to the list of arguments if needed.
+func (tools gccgoToolchain) maybePIC(args []string) []string {
+	switch buildBuildmode {
+	case "c-shared", "shared":
+		args = append(args, "-fPIC")
+	}
+	return args
+}
+
 func gccgoPkgpath(p *Package) string {
 	if p.build.IsCommand() && !p.forceLibrary {
 		return ""
@@ -2073,7 +2760,7 @@
 // gccld runs the gcc linker to create an executable from a set of object files.
 func (b *builder) gccld(p *Package, out string, flags []string, obj []string) error {
 	var cmd []string
-	if len(p.CXXFiles) > 0 {
+	if len(p.CXXFiles) > 0 || len(p.SwigCXXFiles) > 0 {
 		cmd = b.gxxCmd(p.Dir)
 	} else {
 		cmd = b.gccCmd(p.Dir)
@@ -2132,7 +2819,7 @@
 
 	// On OS X, some of the compilers behave as if -fno-common
 	// is always set, and the Mach-O linker in 6l/8l assumes this.
-	// See http://golang.org/issue/3253.
+	// See https://golang.org/issue/3253.
 	if goos == "darwin" {
 		a = append(a, "-fno-common")
 	}
@@ -2142,12 +2829,12 @@
 
 // gccArchArgs returns arguments to pass to gcc based on the architecture.
 func (b *builder) gccArchArgs() []string {
-	switch archChar {
-	case "8":
+	switch goarch {
+	case "386":
 		return []string{"-m32"}
-	case "6":
+	case "amd64", "amd64p32":
 		return []string{"-m64"}
-	case "5":
+	case "arm":
 		return []string{"-marm"} // not thumb
 	}
 	return nil
@@ -2185,7 +2872,7 @@
 	cgoLibGccFileOnce sync.Once
 )
 
-func (b *builder) cgo(p *Package, cgoExe, obj string, pcCFLAGS, pcLDFLAGS, gccfiles, gxxfiles, mfiles []string) (outGo, outObj []string, err error) {
+func (b *builder) cgo(p *Package, cgoExe, obj string, pcCFLAGS, pcLDFLAGS, cgofiles, gccfiles, gxxfiles, mfiles []string) (outGo, outObj []string, err error) {
 	cgoCPPFLAGS, cgoCFLAGS, cgoCXXFLAGS, cgoLDFLAGS := b.cflags(p, true)
 	_, cgoexeCFLAGS, _, _ := b.cflags(p, false)
 	cgoCPPFLAGS = append(cgoCPPFLAGS, pcCFLAGS...)
@@ -2202,7 +2889,7 @@
 	// TODO: CGOPKGPATH, CGO_FLAGS?
 	gofiles := []string{obj + "_cgo_gotypes.go"}
 	cfiles := []string{"_cgo_main.c", "_cgo_export.c"}
-	for _, fn := range p.CgoFiles {
+	for _, fn := range cgofiles {
 		f := cgoRe.ReplaceAllString(fn[:len(fn)-2], "_")
 		gofiles = append(gofiles, obj+f+"cgo1.go")
 		cfiles = append(cfiles, f+"cgo2.c")
@@ -2212,8 +2899,6 @@
 	cgoflags := []string{}
 	// TODO: make cgo not depend on $GOARCH?
 
-	objExt := archChar
-
 	if p.Standard && p.ImportPath == "runtime/cgo" {
 		cgoflags = append(cgoflags, "-import_runtime_cgo=false")
 	}
@@ -2232,23 +2917,38 @@
 	}
 
 	if _, ok := buildToolchain.(gccgoToolchain); ok {
+		switch goarch {
+		case "386", "amd64":
+			cgoCFLAGS = append(cgoCFLAGS, "-fsplit-stack")
+		}
 		cgoflags = append(cgoflags, "-gccgo")
 		if pkgpath := gccgoPkgpath(p); pkgpath != "" {
 			cgoflags = append(cgoflags, "-gccgopkgpath="+pkgpath)
 		}
-		objExt = "o"
 	}
-	if err := b.run(p.Dir, p.ImportPath, cgoenv, cgoExe, "-objdir", obj, cgoflags, "--", cgoCPPFLAGS, cgoexeCFLAGS, p.CgoFiles); err != nil {
+
+	switch buildBuildmode {
+	case "c-archive", "c-shared":
+		// Tell cgo that if there are any exported functions
+		// it should generate a header file that C code can
+		// #include.
+		cgoflags = append(cgoflags, "-exportheader="+obj+"_cgo_install.h")
+	}
+
+	if err := b.run(p.Dir, p.ImportPath, cgoenv, buildToolExec, cgoExe, "-objdir", obj, "-importpath", p.ImportPath, cgoflags, "--", cgoCPPFLAGS, cgoexeCFLAGS, cgofiles); err != nil {
 		return nil, nil, err
 	}
 	outGo = append(outGo, gofiles...)
 
 	// cc _cgo_defun.c
-	defunObj := obj + "_cgo_defun." + objExt
-	if err := buildToolchain.cc(b, p, obj, defunObj, defunC); err != nil {
-		return nil, nil, err
+	_, gccgo := buildToolchain.(gccgoToolchain)
+	if gccgo {
+		defunObj := obj + "_cgo_defun.o"
+		if err := buildToolchain.cc(b, p, obj, defunObj, defunC); err != nil {
+			return nil, nil, err
+		}
+		outObj = append(outObj, defunObj)
 	}
-	outObj = append(outObj, defunObj)
 
 	// gcc
 	var linkobj []string
@@ -2362,20 +3062,15 @@
 	}
 
 	// cgo -dynimport
-	importC := obj + "_cgo_import.c"
+	importGo := obj + "_cgo_import.go"
 	cgoflags = []string{}
 	if p.Standard && p.ImportPath == "runtime/cgo" {
 		cgoflags = append(cgoflags, "-dynlinker") // record path to dynamic linker
 	}
-	if err := b.run(p.Dir, p.ImportPath, nil, cgoExe, "-objdir", obj, "-dynimport", dynobj, "-dynout", importC, cgoflags); err != nil {
+	if err := b.run(p.Dir, p.ImportPath, nil, buildToolExec, cgoExe, "-objdir", obj, "-dynpackage", p.Name, "-dynimport", dynobj, "-dynout", importGo, cgoflags); err != nil {
 		return nil, nil, err
 	}
-
-	// cc _cgo_import.ARCH
-	importObj := obj + "_cgo_import." + objExt
-	if err := buildToolchain.cc(b, p, obj, importObj, importC); err != nil {
-		return nil, nil, err
-	}
+	outGo = append(outGo, importGo)
 
 	ofile := obj + "_all.o"
 	var gccObjs, nonGccObjs []string
@@ -2388,19 +3083,8 @@
 	}
 	ldflags := stringList(bareLDFLAGS, "-Wl,-r", "-nostdlib", staticLibs)
 
-	// Some systems, such as Ubuntu, always add --build-id to
-	// every link, but we don't want a build ID since we are
-	// producing an object file.  On some of those system a plain
-	// -r (not -Wl,-r) will turn off --build-id, but clang 3.0
-	// doesn't support a plain -r.  I don't know how to turn off
-	// --build-id when using clang other than passing a trailing
-	// --build-id=none.  So that is what we do, but only on
-	// systems likely to support it, which is to say, systems that
-	// normally use gold or the GNU linker.
-	switch goos {
-	case "android", "dragonfly", "linux", "netbsd":
-		ldflags = append(ldflags, "-Wl,--build-id=none")
-	}
+	// We are creating an object file, so we don't want a build ID.
+	ldflags = b.disableBuildID(ldflags)
 
 	if err := b.gccld(p, ofile, ldflags, gccObjs); err != nil {
 		return nil, nil, err
@@ -2408,8 +3092,8 @@
 
 	// NOTE(rsc): The importObj is a 5c/6c/8c object and on Windows
 	// must be processed before the gcc-generated objects.
-	// Put it first.  http://golang.org/issue/2601
-	outObj = stringList(importObj, nonGccObjs, ofile)
+	// Put it first.  https://golang.org/issue/2601
+	outObj = stringList(nonGccObjs, ofile)
 
 	return outGo, outObj, nil
 }
@@ -2417,77 +3101,41 @@
 // Run SWIG on all SWIG input files.
 // TODO: Don't build a shared library, once SWIG emits the necessary
 // pragmas for external linking.
-func (b *builder) swig(p *Package, obj string, pcCFLAGS, gccfiles, gxxfiles, mfiles []string) (outGo, outObj []string, err error) {
-	cgoCPPFLAGS, cgoCFLAGS, cgoCXXFLAGS, _ := b.cflags(p, true)
-	cflags := stringList(cgoCPPFLAGS, cgoCFLAGS)
-	cxxflags := stringList(cgoCPPFLAGS, cgoCXXFLAGS)
-
-	for _, file := range gccfiles {
-		ofile := obj + cgoRe.ReplaceAllString(file[:len(file)-1], "_") + "o"
-		if err := b.gcc(p, ofile, cflags, file); err != nil {
-			return nil, nil, err
-		}
-		outObj = append(outObj, ofile)
-	}
-
-	for _, file := range gxxfiles {
-		// Append .o to the file, just in case the pkg has file.c and file.cpp
-		ofile := obj + cgoRe.ReplaceAllString(file, "_") + ".o"
-		if err := b.gxx(p, ofile, cxxflags, file); err != nil {
-			return nil, nil, err
-		}
-		outObj = append(outObj, ofile)
-	}
-
-	for _, file := range mfiles {
-		// Append .o to the file, just in case the pkg has file.c and file.cpp
-		ofile := obj + cgoRe.ReplaceAllString(file, "_") + ".o"
-		if err := b.gcc(p, ofile, cflags, file); err != nil {
-			return nil, nil, err
-		}
-		outObj = append(outObj, ofile)
-	}
-
+func (b *builder) swig(p *Package, obj string, pcCFLAGS []string) (outGo, outC, outCXX []string, err error) {
 	if err := b.swigVersionCheck(); err != nil {
-		return nil, nil, err
+		return nil, nil, nil, err
 	}
 
 	intgosize, err := b.swigIntSize(obj)
 	if err != nil {
-		return nil, nil, err
+		return nil, nil, nil, err
 	}
 
 	for _, f := range p.SwigFiles {
-		goFile, objFile, gccObjFile, err := b.swigOne(p, f, obj, pcCFLAGS, false, intgosize)
+		goFile, cFile, err := b.swigOne(p, f, obj, pcCFLAGS, false, intgosize)
 		if err != nil {
-			return nil, nil, err
+			return nil, nil, nil, err
 		}
 		if goFile != "" {
 			outGo = append(outGo, goFile)
 		}
-		if objFile != "" {
-			outObj = append(outObj, objFile)
-		}
-		if gccObjFile != "" {
-			outObj = append(outObj, gccObjFile)
+		if cFile != "" {
+			outC = append(outC, cFile)
 		}
 	}
 	for _, f := range p.SwigCXXFiles {
-		goFile, objFile, gccObjFile, err := b.swigOne(p, f, obj, pcCFLAGS, true, intgosize)
+		goFile, cxxFile, err := b.swigOne(p, f, obj, pcCFLAGS, true, intgosize)
 		if err != nil {
-			return nil, nil, err
+			return nil, nil, nil, err
 		}
 		if goFile != "" {
 			outGo = append(outGo, goFile)
 		}
-		if objFile != "" {
-			outObj = append(outObj, objFile)
-		}
-		if gccObjFile != "" {
-			outObj = append(outObj, gccObjFile)
+		if cxxFile != "" {
+			outCXX = append(outCXX, cxxFile)
 		}
 	}
-	return outGo, outObj, nil
+	return outGo, outC, outCXX, nil
 }
 
 // Make sure SWIG is new enough.
@@ -2501,20 +3149,51 @@
 	if err != nil {
 		return err
 	}
-	re := regexp.MustCompile(`[vV]ersion +([\d])`)
+	re := regexp.MustCompile(`[vV]ersion +([\d]+)([.][\d]+)?([.][\d]+)?`)
 	matches := re.FindSubmatch(out)
 	if matches == nil {
 		// Can't find version number; hope for the best.
 		return nil
 	}
+
 	major, err := strconv.Atoi(string(matches[1]))
 	if err != nil {
 		// Can't find version number; hope for the best.
 		return nil
 	}
+	const errmsg = "must have SWIG version >= 3.0.6"
 	if major < 3 {
-		return errors.New("must have SWIG version >= 3.0")
+		return errors.New(errmsg)
 	}
+	if major > 3 {
+		// 4.0 or later
+		return nil
+	}
+
+	// We have SWIG version 3.x.
+	if len(matches[2]) > 0 {
+		minor, err := strconv.Atoi(string(matches[2][1:]))
+		if err != nil {
+			return nil
+		}
+		if minor > 0 {
+			// 3.1 or later
+			return nil
+		}
+	}
+
+	// We have SWIG version 3.0.x.
+	if len(matches[3]) > 0 {
+		patch, err := strconv.Atoi(string(matches[3][1:]))
+		if err != nil {
+			return nil
+		}
+		if patch < 6 {
+			// Before 3.0.6.
+			return errors.New(errmsg)
+		}
+	}
+
 	return nil
 }
 
@@ -2545,14 +3224,14 @@
 
 	p := goFilesPackage(srcs)
 
-	if _, _, e := buildToolchain.gc(b, p, "", obj, nil, srcs); e != nil {
+	if _, _, e := buildToolchain.gc(b, p, "", obj, false, nil, srcs); e != nil {
 		return "32", nil
 	}
 	return "64", nil
 }
 
 // Run SWIG on one SWIG input file.
-func (b *builder) swigOne(p *Package, file, obj string, pcCFLAGS []string, cxx bool, intgosize string) (outGo, outObj, objGccObj string, err error) {
+func (b *builder) swigOne(p *Package, file, obj string, pcCFLAGS []string, cxx bool, intgosize string) (outGo, outC string, err error) {
 	cgoCPPFLAGS, cgoCFLAGS, cgoCXXFLAGS, _ := b.cflags(p, true)
 	var cflags []string
 	if cxx {
@@ -2567,7 +3246,6 @@
 	}
 	base := file[:len(file)-n]
 	goFile := base + ".go"
-	cBase := base + "_gc."
 	gccBase := base + "_wrap."
 	gccExt := "c"
 	if cxx {
@@ -2579,6 +3257,7 @@
 	// swig
 	args := []string{
 		"-go",
+		"-cgo",
 		"-intgosize", intgosize,
 		"-module", base,
 		"-o", obj + gccBase + gccExt,
@@ -2601,39 +3280,40 @@
 		args = append(args, "-c++")
 	}
 
-	if out, err := b.runOut(p.Dir, p.ImportPath, nil, "swig", args, file); err != nil {
+	out, err := b.runOut(p.Dir, p.ImportPath, nil, "swig", args, file)
+	if err != nil {
 		if len(out) > 0 {
-			if bytes.Contains(out, []byte("Unrecognized option -intgosize")) {
-				return "", "", "", errors.New("must have SWIG version >= 3.0")
+			if bytes.Contains(out, []byte("-intgosize")) || bytes.Contains(out, []byte("-cgo")) {
+				return "", "", errors.New("must have SWIG version >= 3.0.6")
 			}
-			b.showOutput(p.Dir, p.ImportPath, b.processOutput(out))
-			return "", "", "", errPrintedOutput
+			b.showOutput(p.Dir, p.ImportPath, b.processOutput(out)) // swig error
+			return "", "", errPrintedOutput
 		}
-		return "", "", "", err
+		return "", "", err
+	}
+	if len(out) > 0 {
+		b.showOutput(p.Dir, p.ImportPath, b.processOutput(out)) // swig warning
 	}
 
-	var cObj string
-	if !gccgo {
-		// cc
-		cObj = obj + cBase + archChar
-		if err := buildToolchain.cc(b, p, obj, cObj, obj+cBase+"c"); err != nil {
-			return "", "", "", err
-		}
-	}
+	return obj + goFile, obj + gccBase + gccExt, nil
+}
 
-	// gcc
-	gccObj := obj + gccBase + "o"
-	if !cxx {
-		if err := b.gcc(p, gccObj, cflags, obj+gccBase+gccExt); err != nil {
-			return "", "", "", err
-		}
-	} else {
-		if err := b.gxx(p, gccObj, cflags, obj+gccBase+gccExt); err != nil {
-			return "", "", "", err
-		}
+// disableBuildID adjusts a linker command line to avoid creating a
+// build ID when creating an object file rather than an executable or
+// shared library.  Some systems, such as Ubuntu, always add
+// --build-id to every link, but we don't want a build ID when we are
+// producing an object file.  On some of those system a plain -r (not
+// -Wl,-r) will turn off --build-id, but clang 3.0 doesn't support a
+// plain -r.  I don't know how to turn off --build-id when using clang
+// other than passing a trailing --build-id=none.  So that is what we
+// do, but only on systems likely to support it, which is to say,
+// systems that normally use gold or the GNU linker.
+func (b *builder) disableBuildID(ldflags []string) []string {
+	switch goos {
+	case "android", "dragonfly", "linux", "netbsd":
+		ldflags = append(ldflags, "-Wl,--build-id=none")
 	}
-
-	return obj + goFile, cObj, gccObj, nil
+	return ldflags
 }
 
 // An actionQueue is a priority queue of actions.
@@ -2669,7 +3349,6 @@
 	}
 	buildGcflags = append(buildGcflags, "-race")
 	buildLdflags = append(buildLdflags, "-race")
-	buildCcflags = append(buildCcflags, "-D", "RACE")
 	if buildContext.InstallSuffix != "" {
 		buildContext.InstallSuffix += "_"
 	}
diff --git a/third_party/gofrontend/libgo/go/cmd/go/doc.go b/third_party/gofrontend/libgo/go/cmd/go/doc.go
index 7191ee0..4a07dfe 100644
--- a/third_party/gofrontend/libgo/go/cmd/go/doc.go
+++ b/third_party/gofrontend/libgo/go/cmd/go/doc.go
@@ -1,1131 +1,103 @@
-// Copyright 2011 The Go Authors.  All rights reserved.
+// 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.
 
-// DO NOT EDIT THIS FILE. GENERATED BY mkdoc.sh.
-// Edit the documentation in other files and rerun mkdoc.sh to generate this one.
-
-/*
-Go is a tool for managing Go source code.
-
-Usage:
-
-	go command [arguments]
-
-The commands are:
-
-    build       compile packages and dependencies
-    clean       remove object files
-    env         print Go environment information
-    fix         run go tool fix on packages
-    fmt         run gofmt on package sources
-    generate    generate Go files by processing source
-    get         download and install packages and dependencies
-    install     compile and install packages and dependencies
-    list        list packages
-    run         compile and run Go program
-    test        test packages
-    tool        run specified go tool
-    version     print Go version
-    vet         run go tool vet on packages
-
-Use "go help [command]" for more information about a command.
-
-Additional help topics:
-
-    c           calling between Go and C
-    filetype    file types
-    gopath      GOPATH environment variable
-    importpath  import path syntax
-    packages    description of package lists
-    testflag    description of testing flags
-    testfunc    description of testing functions
-
-Use "go help [topic]" for more information about that topic.
-
-
-Compile packages and dependencies
-
-Usage:
-
-	go build [-o output] [-i] [build flags] [packages]
-
-Build compiles the packages named by the import paths,
-along with their dependencies, but it does not install the results.
-
-If the arguments are a list of .go files, build treats them as a list
-of source files specifying a single package.
-
-When the command line specifies a single main package,
-build writes the resulting executable to output.
-Otherwise build compiles the packages but discards the results,
-serving only as a check that the packages can be built.
-
-The -o flag specifies the output file name. If not specified, the
-output file name depends on the arguments and derives from the name
-of the package, such as p.a for package p, unless p is 'main'. If
-the package is main and file names are provided, the file name
-derives from the first file name mentioned, such as f1 for 'go build
-f1.go f2.go'; with no files provided ('go build'), the output file
-name is the base name of the containing directory.
-
-The -i flag installs the packages that are dependencies of the target.
-
-The build flags are shared by the build, clean, get, install, list, run,
-and test commands:
-
-	-a
-		force rebuilding of packages that are already up-to-date.
-		In Go releases, does not apply to the standard library.
-	-n
-		print the commands but do not run them.
-	-p n
-		the number of builds that can be run in parallel.
-		The default is the number of CPUs available.
-	-race
-		enable data race detection.
-		Supported only on linux/amd64, freebsd/amd64, darwin/amd64 and windows/amd64.
-	-v
-		print the names of packages as they are compiled.
-	-work
-		print the name of the temporary work directory and
-		do not delete it when exiting.
-	-x
-		print the commands.
-
-	-ccflags 'arg list'
-		arguments to pass on each 5c, 6c, or 8c compiler invocation.
-	-compiler name
-		name of compiler to use, as in runtime.Compiler (gccgo or gc).
-	-gccgoflags 'arg list'
-		arguments to pass on each gccgo compiler/linker invocation.
-	-gcflags 'arg list'
-		arguments to pass on each 5g, 6g, or 8g compiler invocation.
-	-installsuffix suffix
-		a suffix to use in the name of the package installation directory,
-		in order to keep output separate from default builds.
-		If using the -race flag, the install suffix is automatically set to race
-		or, if set explicitly, has _race appended to it.
-	-ldflags 'flag list'
-		arguments to pass on each 5l, 6l, or 8l linker invocation.
-	-tags 'tag list'
-		a list of build tags to consider satisfied during the build.
-		For more information about build tags, see the description of
-		build constraints in the documentation for the go/build package.
-
-The list flags accept a space-separated list of strings. To embed spaces
-in an element in the list, surround it with either single or double quotes.
-
-For more about specifying packages, see 'go help packages'.
-For more about where packages and binaries are installed,
-run 'go help gopath'.  For more about calling between Go and C/C++,
-run 'go help c'.
-
-See also: go install, go get, go clean.
-
-
-Remove object files
-
-Usage:
-
-	go clean [-i] [-r] [-n] [-x] [build flags] [packages]
-
-Clean removes object files from package source directories.
-The go command builds most objects in a temporary directory,
-so go clean is mainly concerned with object files left by other
-tools or by manual invocations of go build.
-
-Specifically, clean removes the following files from each of the
-source directories corresponding to the import paths:
-
-	_obj/            old object directory, left from Makefiles
-	_test/           old test directory, left from Makefiles
-	_testmain.go     old gotest file, left from Makefiles
-	test.out         old test log, left from Makefiles
-	build.out        old test log, left from Makefiles
-	*.[568ao]        object files, left from Makefiles
-
-	DIR(.exe)        from go build
-	DIR.test(.exe)   from go test -c
-	MAINFILE(.exe)   from go build MAINFILE.go
-	*.so             from SWIG
-
-In the list, DIR represents the final path element of the
-directory, and MAINFILE is the base name of any Go source
-file in the directory that is not included when building
-the package.
-
-The -i flag causes clean to remove the corresponding installed
-archive or binary (what 'go install' would create).
-
-The -n flag causes clean to print the remove commands it would execute,
-but not run them.
-
-The -r flag causes clean to be applied recursively to all the
-dependencies of the packages named by the import paths.
-
-The -x flag causes clean to print remove commands as it executes them.
-
-For more about build flags, see 'go help build'.
-
-For more about specifying packages, see 'go help packages'.
-
-
-Print Go environment information
-
-Usage:
-
-	go env [var ...]
-
-Env prints Go environment information.
-
-By default env prints information as a shell script
-(on Windows, a batch file).  If one or more variable
-names is given as arguments,  env prints the value of
-each named variable on its own line.
-
-
-Run go tool fix on packages
-
-Usage:
-
-	go fix [packages]
-
-Fix runs the Go fix command on the packages named by the import paths.
-
-For more about fix, see 'godoc fix'.
-For more about specifying packages, see 'go help packages'.
-
-To run fix with specific options, run 'go tool fix'.
-
-See also: go fmt, go vet.
-
-
-Run gofmt on package sources
-
-Usage:
-
-	go fmt [-n] [-x] [packages]
-
-Fmt runs the command 'gofmt -l -w' on the packages named
-by the import paths.  It prints the names of the files that are modified.
-
-For more about gofmt, see 'godoc gofmt'.
-For more about specifying packages, see 'go help packages'.
-
-The -n flag prints commands that would be executed.
-The -x flag prints commands as they are executed.
-
-To run gofmt with specific options, run gofmt itself.
-
-See also: go fix, go vet.
-
-
-Generate Go files by processing source
-
-Usage:
-
-	go generate [-run regexp] [file.go... | packages]
-
-Generate runs commands described by directives within existing
-files. Those commands can run any process but the intent is to
-create or update Go source files, for instance by running yacc.
-
-Go generate is never run automatically by go build, go get, go test,
-and so on. It must be run explicitly.
-
-Go generate scans the file for directives, which are lines of
-the form,
-
-	//go:generate command argument...
-
-(note: no leading spaces and no space in "//go") where command
-is the generator to be run, corresponding to an executable file
-that can be run locally. It must either be in the shell path
-(gofmt), a fully qualified path (/usr/you/bin/mytool), or a
-command alias, described below.
-
-Note that go generate does not parse the file, so lines that look
-like directives in comments or multiline strings will be treated
-as directives.
-
-The arguments to the directive are space-separated tokens or
-double-quoted strings passed to the generator as individual
-arguments when it is run.
-
-Quoted strings use Go syntax and are evaluated before execution; a
-quoted string appears as a single argument to the generator.
-
-Go generate sets several variables when it runs the generator:
-
-	$GOARCH
-		The execution architecture (arm, amd64, etc.)
-	$GOOS
-		The execution operating system (linux, windows, etc.)
-	$GOFILE
-		The base name of the file.
-	$GOPACKAGE
-		The name of the package of the file containing the directive.
-
-Other than variable substitution and quoted-string evaluation, no
-special processing such as "globbing" is performed on the command
-line.
-
-As a last step before running the command, any invocations of any
-environment variables with alphanumeric names, such as $GOFILE or
-$HOME, are expanded throughout the command line. The syntax for
-variable expansion is $NAME on all operating systems.  Due to the
-order of evaluation, variables are expanded even inside quoted
-strings. If the variable NAME is not set, $NAME expands to the
-empty string.
-
-A directive of the form,
-
-	//go:generate -command xxx args...
-
-specifies, for the remainder of this source file only, that the
-string xxx represents the command identified by the arguments. This
-can be used to create aliases or to handle multiword generators.
-For example,
-
-	//go:generate -command yacc go tool yacc
-
-specifies that the command "yacc" represents the generator
-"go tool yacc".
-
-Generate processes packages in the order given on the command line,
-one at a time. If the command line lists .go files, they are treated
-as a single package. Within a package, generate processes the
-source files in a package in file name order, one at a time. Within
-a source file, generate runs generators in the order they appear
-in the file, one at a time.
-
-If any generator returns an error exit status, "go generate" skips
-all further processing for that package.
-
-The generator is run in the package's source directory.
-
-Go generate accepts one specific flag:
-
-	-run=""
-		TODO: This flag is unimplemented.
-		if non-empty, specifies a regular expression to
-		select directives whose command matches the expression.
-
-It also accepts the standard build flags -v, -n, and -x.
-The -v flag prints the names of packages and files as they are
-processed.
-The -n flag prints commands that would be executed.
-The -x flag prints commands as they are executed.
-
-For more about specifying packages, see 'go help packages'.
-
-
-Download and install packages and dependencies
-
-Usage:
-
-	go get [-d] [-f] [-fix] [-t] [-u] [build flags] [packages]
-
-Get downloads and installs the packages named by the import paths,
-along with their dependencies.
-
-The -d flag instructs get to stop after downloading the packages; that is,
-it instructs get not to install the packages.
-
-The -f flag, valid only when -u is set, forces get -u not to verify that
-each package has been checked out from the source control repository
-implied by its import path. This can be useful if the source is a local fork
-of the original.
-
-The -fix flag instructs get to run the fix tool on the downloaded packages
-before resolving dependencies or building the code.
-
-The -t flag instructs get to also download the packages required to build
-the tests for the specified packages.
-
-The -u flag instructs get to use the network to update the named packages
-and their dependencies.  By default, get uses the network to check out
-missing packages but does not use it to look for updates to existing packages.
-
-Get also accepts build flags to control the installation. See 'go help build'.
-
-When checking out or updating a package, get looks for a branch or tag
-that matches the locally installed version of Go. The most important
-rule is that if the local installation is running version "go1", get
-searches for a branch or tag named "go1". If no such version exists it
-retrieves the most recent version of the package.
-
-For more about specifying packages, see 'go help packages'.
-
-For more about how 'go get' finds source code to
-download, see 'go help importpath'.
-
-See also: go build, go install, go clean.
-
-
-Compile and install packages and dependencies
-
-Usage:
-
-	go install [build flags] [packages]
-
-Install compiles and installs the packages named by the import paths,
-along with their dependencies.
-
-For more about the build flags, see 'go help build'.
-For more about specifying packages, see 'go help packages'.
-
-See also: go build, go get, go clean.
-
-
-List packages
-
-Usage:
-
-	go list [-e] [-f format] [-json] [build flags] [packages]
-
-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
-
-The -f flag specifies an alternate format for the list, using the
-syntax of package template.  The default output is equivalent to -f
-'{{.ImportPath}}'. The struct being passed to the template is:
-
-    type Package struct {
-        Dir           string // directory containing package sources
-        ImportPath    string // import path of package in dir
-        ImportComment string // path in import comment on package statement
-        Name          string // package name
-        Doc           string // package documentation string
-        Target        string // install path
-        Goroot        bool   // is this package in the Go root?
-        Standard      bool   // is this package part of the standard Go library?
-        Stale         bool   // would 'go install' do anything for this package?
-        Root          string // Go root or Go path dir containing this package
-
-        // Source files
-        GoFiles        []string // .go source files (excluding CgoFiles, TestGoFiles, XTestGoFiles)
-        CgoFiles       []string // .go sources files that import "C"
-        IgnoredGoFiles []string // .go sources ignored due to build constraints
-        CFiles         []string // .c source files
-        CXXFiles       []string // .cc, .cxx and .cpp source files
-        MFiles         []string // .m source files
-        HFiles         []string // .h, .hh, .hpp and .hxx source files
-        SFiles         []string // .s source files
-        SwigFiles      []string // .swig files
-        SwigCXXFiles   []string // .swigcxx files
-        SysoFiles      []string // .syso object files to add to archive
-
-        // Cgo directives
-        CgoCFLAGS    []string // cgo: flags for C compiler
-        CgoCPPFLAGS  []string // cgo: flags for C preprocessor
-        CgoCXXFLAGS  []string // cgo: flags for C++ compiler
-        CgoLDFLAGS   []string // cgo: flags for linker
-        CgoPkgConfig []string // cgo: pkg-config names
-
-        // Dependency information
-        Imports []string // import paths used by this package
-        Deps    []string // all (recursively) imported dependencies
-
-        // Error information
-        Incomplete bool            // this package or a dependency has an error
-        Error      *PackageError   // error loading package
-        DepsErrors []*PackageError // errors loading dependencies
-
-        TestGoFiles  []string // _test.go files in package
-        TestImports  []string // imports from TestGoFiles
-        XTestGoFiles []string // _test.go files outside package
-        XTestImports []string // imports from XTestGoFiles
-    }
-
-The template function "join" calls strings.Join.
-
-The template function "context" returns the build context, defined as:
-
-	type Context struct {
-		GOARCH        string   // target architecture
-		GOOS          string   // target operating system
-		GOROOT        string   // Go root
-		GOPATH        string   // Go path
-		CgoEnabled    bool     // whether cgo can be used
-		UseAllFiles   bool     // use files regardless of +build lines, file names
-		Compiler      string   // compiler to assume when computing target paths
-		BuildTags     []string // build constraints to match in +build lines
-		ReleaseTags   []string // releases the current release is compatible with
-		InstallSuffix string   // suffix to use in the name of the install dir
-	}
-
-For more information about the meaning of these fields see the documentation
-for the go/build package's Context type.
-
-The -json flag causes the package data to be printed in JSON format
-instead of using the template format.
-
-The -e flag changes the handling of erroneous packages, those that
-cannot be found or are malformed.  By default, the list command
-prints an error to standard error for each erroneous package and
-omits the packages from consideration during the usual printing.
-With the -e flag, the list command never prints errors to standard
-error and instead processes the erroneous packages with the usual
-printing.  Erroneous packages will have a non-empty ImportPath and
-a non-nil Error field; other information may or may not be missing
-(zeroed).
-
-For more about build flags, see 'go help build'.
-
-For more about specifying packages, see 'go help packages'.
-
-
-Compile and run Go program
-
-Usage:
-
-	go run [build flags] [-exec xprog] gofiles... [arguments...]
-
-Run compiles and runs the main package comprising the named Go source files.
-A Go source file is defined to be a file ending in a literal ".go" suffix.
-
-By default, 'go run' runs the compiled binary directly: 'a.out arguments...'.
-If the -exec flag is given, 'go run' invokes the binary using xprog: 'xprog a.out arguments...'.
-If the -exec flag is not given, GOOS or GOARCH is different from the system
-default, and a program named go_$GOOS_$GOARCH_exec can be found
-on the current search path, 'go run' invokes the binary using that program,
-for example 'go_nacl_386_exec a.out arguments...'. This allows execution of
-cross-compiled programs when a simulator or other execution method is
-available.
-
-For more about build flags, see 'go help build'.
-
-See also: go build.
-
-
-Test packages
-
-Usage:
-
-	go test [-c] [-i] [build and test flags] [packages] [flags for test binary]
-
-'Go test' automates testing the packages named by the import paths.
-It prints a summary of the test results in the format:
-
-	ok   archive/tar   0.011s
-	FAIL archive/zip   0.022s
-	ok   compress/gzip 0.033s
-	...
-
-followed by detailed output for each failed package.
-
-'Go test' recompiles each package along with any files with names matching
-the file pattern "*_test.go".
-Files whose names begin with "_" (including "_test.go") or "." are ignored.
-These additional files can contain test functions, benchmark functions, and
-example functions.  See 'go help testfunc' for more.
-Each listed package causes the execution of a separate test binary.
-
-Test files that declare a package with the suffix "_test" will be compiled as a
-separate package, and then linked and run with the main test binary.
-
-By default, go test needs no arguments.  It compiles and tests the package
-with source in the current directory, including tests, and runs the tests.
-
-The package is built in a temporary directory so it does not interfere with the
-non-test installation.
-
-In addition to the build flags, the flags handled by 'go test' itself are:
-
-	-c
-		Compile the test binary to pkg.test but do not run it
-		(where pkg is the last element of the package's import path).
-		The file name can be changed with the -o flag.
-
-	-exec xprog
-	    Run the test binary using xprog. The behavior is the same as
-	    in 'go run'. See 'go help run' for details.
-
-	-i
-	    Install packages that are dependencies of the test.
-	    Do not run the test.
-
-	-o file
-		Compile the test binary to the named file.
-		The test still runs (unless -c or -i is specified).
-
-
-The test binary also accepts flags that control execution of the test; these
-flags are also accessible by 'go test'.  See 'go help testflag' for details.
-
-If the test binary needs any other flags, they should be presented after the
-package names. The go tool treats as a flag the first argument that begins with
-a minus sign that it does not recognize itself; that argument and all subsequent
-arguments are passed as arguments to the test binary.
-
-For more about build flags, see 'go help build'.
-For more about specifying packages, see 'go help packages'.
-
-See also: go build, go vet.
-
-
-Run specified go tool
-
-Usage:
-
-	go tool [-n] command [args...]
-
-Tool runs the go tool command identified by the arguments.
-With no arguments it prints the list of known tools.
-
-The -n flag causes tool to print the command that would be
-executed but not execute it.
-
-For more about each tool command, see 'go tool command -h'.
-
-
-Print Go version
-
-Usage:
-
-	go version
-
-Version prints the Go version, as reported by runtime.Version.
-
-
-Run go tool vet on packages
-
-Usage:
-
-	go vet [-n] [-x] [packages]
-
-Vet runs the Go vet command on the packages named by the import paths.
-
-For more about vet, see 'godoc golang.org/x/tools/cmd/vet'.
-For more about specifying packages, see 'go help packages'.
-
-To run the vet tool with specific options, run 'go tool vet'.
-
-The -n flag prints commands that would be executed.
-The -x flag prints commands as they are executed.
-
-See also: go fmt, go fix.
-
-
-Calling between Go and C
-
-There are two different ways to call between Go and C/C++ code.
-
-The first is the cgo tool, which is part of the Go distribution.  For
-information on how to use it see the cgo documentation (godoc cmd/cgo).
-
-The second is the SWIG program, which is a general tool for
-interfacing between languages.  For information on SWIG see
-http://swig.org/.  When running go build, any file with a .swig
-extension will be passed to SWIG.  Any file with a .swigcxx extension
-will be passed to SWIG with the -c++ option.
-
-When either cgo or SWIG is used, go build will pass any .c, .m, .s,
-or .S files to the C compiler, and any .cc, .cpp, .cxx files to the C++
-compiler.  The CC or CXX environment variables may be set to determine
-the C or C++ compiler, respectively, to use.
-
-
-File types
-
-The go command examines the contents of a restricted set of files
-in each directory. It identifies which files to examine based on
-the extension of the file name. These extensions are:
-
-	.go
-		Go source files.
-	.c, .h
-		C source files.
-		If the package uses cgo, these will be compiled with the
-		OS-native compiler (typically gcc); otherwise they will be
-		compiled with the Go-specific support compiler,
-		5c, 6c, or 8c, etc. as appropriate.
-	.cc, .cpp, .cxx, .hh, .hpp, .hxx
-		C++ source files. Only useful with cgo or SWIG, and always
-		compiled with the OS-native compiler.
-	.m
-		Objective-C source files. Only useful with cgo, and always
-		compiled with the OS-native compiler.
-	.s, .S
-		Assembler source files.
-		If the package uses cgo, these will be assembled with the
-		OS-native assembler (typically gcc (sic)); otherwise they
-		will be assembled with the Go-specific support assembler,
-		5a, 6a, or 8a, etc., as appropriate.
-	.swig, .swigcxx
-		SWIG definition files.
-	.syso
-		System object files.
-
-Files of each of these types except .syso may contain build
-constraints, but the go command stops scanning for build constraints
-at the first item in the file that is not a blank line or //-style
-line comment.
-
-
-GOPATH environment variable
-
-The Go path is used to resolve import statements.
-It is implemented by and documented in the go/build package.
-
-The GOPATH environment variable lists places to look for Go code.
-On Unix, the value is a colon-separated string.
-On Windows, the value is a semicolon-separated string.
-On Plan 9, the value is a list.
-
-GOPATH must be set to get, build and install packages outside the
-standard Go tree.
-
-Each directory listed in GOPATH must have a prescribed structure:
-
-The src/ directory holds source code.  The path below 'src'
-determines the import path or executable name.
-
-The pkg/ directory holds installed package objects.
-As in the Go tree, each target operating system and
-architecture pair has its own subdirectory of pkg
-(pkg/GOOS_GOARCH).
-
-If DIR is a directory listed in the GOPATH, a package with
-source in DIR/src/foo/bar can be imported as "foo/bar" and
-has its compiled form installed to "DIR/pkg/GOOS_GOARCH/foo/bar.a".
-
-The bin/ directory holds compiled commands.
-Each command is named for its source directory, but only
-the final element, not the entire path.  That is, the
-command with source in DIR/src/foo/quux is installed into
-DIR/bin/quux, not DIR/bin/foo/quux.  The foo/ is stripped
-so that you can add DIR/bin to your PATH to get at the
-installed commands.  If the GOBIN environment variable is
-set, commands are installed to the directory it names instead
-of DIR/bin.
-
-Here's an example directory layout:
-
-    GOPATH=/home/user/gocode
-
-    /home/user/gocode/
-        src/
-            foo/
-                bar/               (go code in package bar)
-                    x.go
-                quux/              (go code in package main)
-                    y.go
-        bin/
-            quux                   (installed command)
-        pkg/
-            linux_amd64/
-                foo/
-                    bar.a          (installed package object)
-
-Go searches each directory listed in GOPATH to find source code,
-but new packages are always downloaded into the first directory
-in the list.
-
-
-Import path syntax
-
-An import path (see 'go help packages') denotes a package
-stored in the local file system.  In general, an import path denotes
-either a standard package (such as "unicode/utf8") or a package
-found in one of the work spaces (see 'go help gopath').
-
-Relative import paths
-
-An import path beginning with ./ or ../ is called a relative path.
-The toolchain supports relative import paths as a shortcut in two ways.
-
-First, a relative path can be used as a shorthand on the command line.
-If you are working in the directory containing the code imported as
-"unicode" and want to run the tests for "unicode/utf8", you can type
-"go test ./utf8" instead of needing to specify the full path.
-Similarly, in the reverse situation, "go test .." will test "unicode" from
-the "unicode/utf8" directory. Relative patterns are also allowed, like
-"go test ./..." to test all subdirectories. See 'go help packages' for details
-on the pattern syntax.
-
-Second, if you are compiling a Go program not in a work space,
-you can use a relative path in an import statement in that program
-to refer to nearby code also not in a work space.
-This makes it easy to experiment with small multipackage programs
-outside of the usual work spaces, but such programs cannot be
-installed with "go install" (there is no work space in which to install them),
-so they are rebuilt from scratch each time they are built.
-To avoid ambiguity, Go programs cannot use relative import paths
-within a work space.
-
-Remote import paths
-
-Certain import paths also
-describe how to obtain the source code for the package using
-a revision control system.
-
-A few common code hosting sites have special syntax:
-
-	Bitbucket (Git, Mercurial)
-
-		import "bitbucket.org/user/project"
-		import "bitbucket.org/user/project/sub/directory"
-
-	GitHub (Git)
-
-		import "github.com/user/project"
-		import "github.com/user/project/sub/directory"
-
-	Google Code Project Hosting (Git, Mercurial, Subversion)
-
-		import "code.google.com/p/project"
-		import "code.google.com/p/project/sub/directory"
-
-		import "code.google.com/p/project.subrepository"
-		import "code.google.com/p/project.subrepository/sub/directory"
-
-	Launchpad (Bazaar)
-
-		import "launchpad.net/project"
-		import "launchpad.net/project/series"
-		import "launchpad.net/project/series/sub/directory"
-
-		import "launchpad.net/~user/project/branch"
-		import "launchpad.net/~user/project/branch/sub/directory"
-
-	IBM DevOps Services (Git)
-
-		import "hub.jazz.net/git/user/project"
-		import "hub.jazz.net/git/user/project/sub/directory"
-
-For code hosted on other servers, import paths may either be qualified
-with the version control type, or the go tool can dynamically fetch
-the import path over https/http and discover where the code resides
-from a <meta> tag in the HTML.
-
-To declare the code location, an import path of the form
-
-	repository.vcs/path
-
-specifies the given repository, with or without the .vcs suffix,
-using the named version control system, and then the path inside
-that repository.  The supported version control systems are:
-
-	Bazaar      .bzr
-	Git         .git
-	Mercurial   .hg
-	Subversion  .svn
-
-For example,
-
-	import "example.org/user/foo.hg"
-
-denotes the root directory of the Mercurial repository at
-example.org/user/foo or foo.hg, and
-
-	import "example.org/repo.git/foo/bar"
-
-denotes the foo/bar directory of the Git repository at
-example.org/repo or repo.git.
-
-When a version control system supports multiple protocols,
-each is tried in turn when downloading.  For example, a Git
-download tries git://, then https://, then http://.
-
-If the import path is not a known code hosting site and also lacks a
-version control qualifier, the go tool attempts to fetch the import
-over https/http and looks for a <meta> tag in the document's HTML
-<head>.
-
-The meta tag has the form:
-
-	<meta name="go-import" content="import-prefix vcs repo-root">
-
-The import-prefix is the import path corresponding to the repository
-root. It must be a prefix or an exact match of the package being
-fetched with "go get". If it's not an exact match, another http
-request is made at the prefix to verify the <meta> tags match.
-
-The vcs is one of "git", "hg", "svn", etc,
-
-The repo-root is the root of the version control system
-containing a scheme and not containing a .vcs qualifier.
-
-For example,
-
-	import "example.org/pkg/foo"
-
-will result in the following request(s):
-
-	https://example.org/pkg/foo?go-get=1 (preferred)
-	http://example.org/pkg/foo?go-get=1  (fallback)
-
-If that page contains the meta tag
-
-	<meta name="go-import" content="example.org git https://code.org/r/p/exproj">
-
-the go tool will verify that https://example.org/?go-get=1 contains the
-same meta tag and then git clone https://code.org/r/p/exproj into
-GOPATH/src/example.org.
-
-New downloaded packages are written to the first directory
-listed in the GOPATH environment variable (see 'go help gopath').
-
-The go command attempts to download the version of the
-package appropriate for the Go release being used.
-Run 'go help get' for more.
-
-Import path checking
-
-When the custom import path feature described above redirects to a
-known code hosting site, each of the resulting packages has two possible
-import paths, using the custom domain or the known hosting site.
-
-A package statement is said to have an "import comment" if it is immediately
-followed (before the next newline) by a comment of one of these two forms:
-
-	package math // import "path"
-	package math /* import "path" * /
-
-The go command will refuse to install a package with an import comment
-unless it is being referred to by that import path. In this way, import comments
-let package authors make sure the custom import path is used and not a
-direct path to the underlying code hosting site.
-
-See https://golang.org/s/go14customimport for details.
-
-
-Description of package lists
-
-Many commands apply to a set of packages:
-
-	go action [packages]
-
-Usually, [packages] is a list of import paths.
-
-An import path that is a rooted path or that begins with
-a . or .. element is interpreted as a file system path and
-denotes the package in that directory.
-
-Otherwise, the import path P denotes the package found in
-the directory DIR/src/P for some DIR listed in the GOPATH
-environment variable (see 'go help gopath').
-
-If no import paths are given, the action applies to the
-package in the current directory.
-
-There are three reserved names for paths that should not be used
-for packages to be built with the go tool:
-
-- "main" denotes the top-level package in a stand-alone executable.
-
-- "all" expands to all package directories found in all the GOPATH
-trees. For example, 'go list all' lists all the packages on the local
-system.
-
-- "std" is like all but expands to just the packages in the standard
-Go library.
-
-An import path is a pattern if it includes one or more "..." wildcards,
-each of which can match any string, including the empty string and
-strings containing slashes.  Such a pattern expands to all package
-directories found in the GOPATH trees with names matching the
-patterns.  As a special case, x/... matches x as well as x's subdirectories.
-For example, net/... expands to net and packages in its subdirectories.
-
-An import path can also name a package to be downloaded from
-a remote repository.  Run 'go help importpath' for details.
-
-Every package in a program must have a unique import path.
-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'.
-
-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
-package made up of exactly those files, ignoring any build constraints
-in those files and ignoring any other files in the directory.
-
-Directory and file names that begin with "." or "_" are ignored
-by the go tool, as are directories named "testdata".
-
-
-Description of testing flags
-
-The 'go test' command takes both flags that apply to 'go test' itself
-and flags that apply to the resulting test binary.
-
-Several of the flags control profiling and write an execution profile
-suitable for "go tool pprof"; run "go tool pprof help" for more
-information.  The --alloc_space, --alloc_objects, and --show_bytes
-options of pprof control how the information is presented.
-
-The following flags are recognized by the 'go test' command and
-control the execution of any test:
-
-	-bench regexp
-	    Run benchmarks matching the regular expression.
-	    By default, no benchmarks run. To run all benchmarks,
-	    use '-bench .' or '-bench=.'.
-
-	-benchmem
-	    Print memory allocation statistics for benchmarks.
-
-	-benchtime t
-	    Run enough iterations of each benchmark to take t, specified
-	    as a time.Duration (for example, -benchtime 1h30s).
-	    The default is 1 second (1s).
-
-	-blockprofile block.out
-	    Write a goroutine blocking profile to the specified file
-	    when all tests are complete.
-	    Writes test binary as -c would.
-
-	-blockprofilerate n
-	    Control the detail provided in goroutine blocking profiles by
-	    calling runtime.SetBlockProfileRate with n.
-	    See 'godoc runtime SetBlockProfileRate'.
-	    The profiler aims to sample, on average, one blocking event every
-	    n nanoseconds the program spends blocked.  By default,
-	    if -test.blockprofile is set without this flag, all blocking events
-	    are recorded, equivalent to -test.blockprofilerate=1.
-
-	-cover
-	    Enable coverage analysis.
-
-	-covermode set,count,atomic
-	    Set the mode for coverage analysis for the package[s]
-	    being tested. The default is "set" unless -race is enabled,
-	    in which case it is "atomic".
-	    The values:
-		set: bool: does this statement run?
-		count: int: how many times does this statement run?
-		atomic: int: count, but correct in multithreaded tests;
-			significantly more expensive.
-	    Sets -cover.
-
-	-coverpkg pkg1,pkg2,pkg3
-	    Apply coverage analysis in each test to the given list of packages.
-	    The default is for each test to analyze only the package being tested.
-	    Packages are specified as import paths.
-	    Sets -cover.
-
-	-coverprofile cover.out
-	    Write a coverage profile to the file after all tests have passed.
-	    Sets -cover.
-
-	-cpu 1,2,4
-	    Specify a list of GOMAXPROCS values for which the tests or
-	    benchmarks should be executed.  The default is the current value
-	    of GOMAXPROCS.
-
-	-cpuprofile cpu.out
-	    Write a CPU profile to the specified file before exiting.
-	    Writes test binary as -c would.
-
-	-memprofile mem.out
-	    Write a memory profile to the file after all tests have passed.
-	    Writes test binary as -c would.
-
-	-memprofilerate n
-	    Enable more precise (and expensive) memory profiles by setting
-	    runtime.MemProfileRate.  See 'godoc runtime MemProfileRate'.
-	    To profile all memory allocations, use -test.memprofilerate=1
-	    and pass --alloc_space flag to the pprof tool.
-
-	-outputdir directory
-	    Place output files from profiling in the specified directory,
-	    by default the directory in which "go test" is running.
-
-	-parallel n
-	    Allow parallel execution of test functions that call t.Parallel.
-	    The value of this flag is the maximum number of tests to run
-	    simultaneously; by default, it is set to the value of GOMAXPROCS.
-
-	-run regexp
-	    Run only those tests and examples matching the regular
-	    expression.
-
-	-short
-	    Tell long-running tests to shorten their run time.
-	    It is off by default but set during all.bash so that installing
-	    the Go tree can run a sanity check but not spend time running
-	    exhaustive tests.
-
-	-timeout t
-	    If a test runs longer than t, panic.
-
-	-v
-	    Verbose output: log all tests as they are run. Also print all
-	    text from Log and Logf calls even if the test succeeds.
-
-The test binary, called pkg.test where pkg is the name of the
-directory containing the package sources, can be invoked directly
-after building it with 'go test -c'. When invoking the test binary
-directly, each of the standard flag names must be prefixed with 'test.',
-as in -test.run=TestMyFunc or -test.v.
-
-When running 'go test', flags not listed above are passed through
-unaltered. For instance, the command
-
-	go test -x -v -cpuprofile=prof.out -dir=testdata -update
-
-will compile the test binary and then run it as
-
-	pkg.test -test.v -test.cpuprofile=prof.out -dir=testdata -update
-
-The test flags that generate profiles (other than for coverage) also
-leave the test binary in pkg.test for use when analyzing the profiles.
-
-Flags not recognized by 'go test' must be placed after any specified packages.
-
-
-Description of testing functions
-
-The 'go test' command expects to find test, benchmark, and example functions
-in the "*_test.go" files corresponding to the package under test.
-
-A test function is one named TestXXX (where XXX is any alphanumeric string
-not starting with a lower case letter) and should have the signature,
-
-	func TestXXX(t *testing.T) { ... }
-
-A benchmark function is one named BenchmarkXXX and should have the signature,
-
-	func BenchmarkXXX(b *testing.B) { ... }
-
-An example function is similar to a test function but, instead of using
-*testing.T to report success or failure, prints output to os.Stdout.
-That output is compared against the function's "Output:" comment, which
-must be the last comment in the function body (see example below). An
-example with no such comment, or with no text after "Output:" is compiled
-but not executed.
-
-Godoc displays the body of ExampleXXX to demonstrate the use
-of the function, constant, or variable XXX.  An example of a method M with
-receiver type T or *T is named ExampleT_M.  There may be multiple examples
-for a given function, constant, or variable, distinguished by a trailing _xxx,
-where xxx is a suffix not beginning with an upper case letter.
-
-Here is an example of an example:
-
-	func ExamplePrintln() {
-		Println("The output of\nthis example.")
-		// Output: The output of
-		// this example.
-	}
-
-The entire test file is presented as the example when it contains a single
-example function, at least one other function, type, variable, or constant
-declaration, and no test or benchmark functions.
-
-See the documentation of the testing package for more information.
-
-
-*/
 package main
+
+var cmdDoc = &Command{
+	Run:         runDoc,
+	UsageLine:   "doc [-u] [-c] [package|[package.]symbol[.method]]",
+	CustomFlags: true,
+	Short:       "show documentation for package or symbol",
+	Long: `
+Doc prints the documentation comments associated with the item identified by its
+arguments (a package, const, func, type, var, or method) followed by a one-line
+summary of each of the first-level items "under" that item (package-level
+declarations for a package, methods for a type, etc.).
+
+Doc accepts zero, one, or two arguments.
+
+Given no arguments, that is, when run as
+
+	go doc
+
+it prints the package documentation for the package in the current directory.
+If the package is a command (package main), the exported symbols of the package
+are elided from the presentation unless the -cmd flag is provided.
+
+When run with one argument, the argument is treated as a Go-syntax-like
+representation of the item to be documented. What the argument selects depends
+on what is installed in GOROOT and GOPATH, as well as the form of the argument,
+which is schematically one of these:
+
+	go doc <pkg>
+	go doc <sym>[.<method>]
+	go doc [<pkg>].<sym>[.<method>]
+
+The first item in this list matched by the argument is the one whose
+documentation is printed. (See the examples below.) For packages, the order of
+scanning is determined lexically, but the GOROOT tree is always scanned before
+GOPATH.
+
+If there is no package specified or matched, the package in the current
+directory is selected, so "go doc Foo" shows the documentation for symbol Foo in
+the current package.
+
+The package path must be either a qualified path or a proper suffix of a
+path. The go tool's usual package mechanism does not apply: package path
+elements like . and ... are not implemented by go doc.
+
+When run with two arguments, the first must be a full package path (not just a
+suffix), and the second is a symbol or symbol and method; this is similar to the
+syntax accepted by godoc:
+
+	go doc <pkg> <sym>[.<method>]
+
+In all forms, when matching symbols, lower-case letters in the argument match
+either case but upper-case letters match exactly. This means that there may be
+multiple matches of a lower-case argument in a package if different symbols have
+different cases. If this occurs, documentation for all matches is printed.
+
+Examples:
+	go doc
+		Show documentation for current package.
+	go doc Foo
+		Show documentation for Foo in the current package.
+		(Foo starts with a capital letter so it cannot match
+		a package path.)
+	go doc encoding/json
+		Show documentation for the encoding/json package.
+	go doc json
+		Shorthand for encoding/json.
+	go doc json.Number (or go doc json.number)
+		Show documentation and method summary for json.Number.
+	go doc json.Number.Int64 (or go doc json.number.int64)
+		Show documentation for json.Number's Int64 method.
+	go doc cmd/doc
+		Show package docs for the doc command.
+	go doc -cmd cmd/doc
+		Show package docs and exported symbols within the doc command.
+	go doc template.new
+		Show documentation for html/template's New function.
+		(html/template is lexically before text/template)
+	go doc text/template.new # One argument
+		Show documentation for text/template's New function.
+	go doc text/template new # Two arguments
+		Show documentation for text/template's New function.
+
+Flags:
+	-c
+		Respect case when matching symbols.
+	-cmd
+		Treat a command (package main) like a regular package.
+		Otherwise package main's exported symbols are hidden
+		when showing the package's top-level documentation.
+	-u
+		Show documentation for unexported as well as exported
+		symbols and methods.
+`,
+}
+
+func runDoc(cmd *Command, args []string) {
+	run(buildToolExec, tool("doc"), args)
+}
diff --git a/third_party/gofrontend/libgo/go/cmd/go/env.go b/third_party/gofrontend/libgo/go/cmd/go/env.go
index 26d37df..600acca 100644
--- a/third_party/gofrontend/libgo/go/cmd/go/env.go
+++ b/third_party/gofrontend/libgo/go/cmd/go/env.go
@@ -36,7 +36,6 @@
 	env := []envVar{
 		{"GOARCH", goarch},
 		{"GOBIN", gobin},
-		{"GOCHAR", archChar},
 		{"GOEXE", exeSuffix},
 		{"GOHOSTARCH", runtime.GOARCH},
 		{"GOHOSTOS", runtime.GOOS},
@@ -45,6 +44,7 @@
 		{"GORACE", os.Getenv("GORACE")},
 		{"GOROOT", goroot},
 		{"GOTOOLDIR", toolDir},
+		{"GO15VENDOREXPERIMENT", os.Getenv("GO15VENDOREXPERIMENT")},
 
 		// disable escape codes in clang errors
 		{"TERM", "dumb"},
diff --git a/third_party/gofrontend/libgo/go/cmd/go/fix.go b/third_party/gofrontend/libgo/go/cmd/go/fix.go
index 8736cce..94fd22e 100644
--- a/third_party/gofrontend/libgo/go/cmd/go/fix.go
+++ b/third_party/gofrontend/libgo/go/cmd/go/fix.go
@@ -11,7 +11,7 @@
 	Long: `
 Fix runs the Go fix command on the packages named by the import paths.
 
-For more about fix, see 'godoc fix'.
+For more about fix, see 'go doc cmd/fix'.
 For more about specifying packages, see 'go help packages'.
 
 To run fix with specific options, run 'go tool fix'.
@@ -25,6 +25,6 @@
 		// Use pkg.gofiles instead of pkg.Dir so that
 		// the command only applies to this package,
 		// not to packages in subdirectories.
-		run(stringList(tool("fix"), relPaths(pkg.allgofiles)))
+		run(stringList(buildToolExec, tool("fix"), relPaths(pkg.allgofiles)))
 	}
 }
diff --git a/third_party/gofrontend/libgo/go/cmd/go/fmt.go b/third_party/gofrontend/libgo/go/cmd/go/fmt.go
index 65dc3ca..57c02ad 100644
--- a/third_party/gofrontend/libgo/go/cmd/go/fmt.go
+++ b/third_party/gofrontend/libgo/go/cmd/go/fmt.go
@@ -4,6 +4,11 @@
 
 package main
 
+import (
+	"os"
+	"path/filepath"
+)
+
 func init() {
 	addBuildFlagsNX(cmdFmt)
 }
@@ -16,7 +21,7 @@
 Fmt runs the command 'gofmt -l -w' on the packages named
 by the import paths.  It prints the names of the files that are modified.
 
-For more about gofmt, see 'godoc gofmt'.
+For more about gofmt, see 'go doc cmd/gofmt'.
 For more about specifying packages, see 'go help packages'.
 
 The -n flag prints commands that would be executed.
@@ -29,10 +34,31 @@
 }
 
 func runFmt(cmd *Command, args []string) {
+	gofmt := gofmtPath()
 	for _, pkg := range packages(args) {
 		// Use pkg.gofiles instead of pkg.Dir so that
 		// the command only applies to this package,
 		// not to packages in subdirectories.
-		run(stringList("gofmt", "-l", "-w", relPaths(pkg.allgofiles)))
+		run(stringList(gofmt, "-l", "-w", relPaths(pkg.allgofiles)))
 	}
 }
+
+func gofmtPath() string {
+	gofmt := "gofmt"
+	if toolIsWindows {
+		gofmt += toolWindowsExtension
+	}
+
+	gofmtPath := filepath.Join(gobin, gofmt)
+	if _, err := os.Stat(gofmtPath); err == nil {
+		return gofmtPath
+	}
+
+	gofmtPath = filepath.Join(goroot, "bin", gofmt)
+	if _, err := os.Stat(gofmtPath); err == nil {
+		return gofmtPath
+	}
+
+	// fallback to looking for gofmt in $PATH
+	return "gofmt"
+}
diff --git a/third_party/gofrontend/libgo/go/cmd/go/generate.go b/third_party/gofrontend/libgo/go/cmd/go/generate.go
index 3c0af87..efdc229 100644
--- a/third_party/gofrontend/libgo/go/cmd/go/generate.go
+++ b/third_party/gofrontend/libgo/go/cmd/go/generate.go
@@ -13,11 +13,11 @@
 	"os"
 	"os/exec"
 	"path/filepath"
+	"regexp"
 	"runtime"
 	"strconv"
 	"strings"
 	"unicode"
-	"unicode/utf8"
 )
 
 var cmdGenerate = &Command{
@@ -62,8 +62,12 @@
 		The execution operating system (linux, windows, etc.)
 	$GOFILE
 		The base name of the file.
+	$GOLINE
+		The line number of the directive in the source file.
 	$GOPACKAGE
 		The name of the package of the file containing the directive.
+	$DOLLAR
+		A dollar sign.
 
 Other than variable substitution and quoted-string evaluation, no
 special processing such as "globbing" is performed on the command
@@ -106,9 +110,10 @@
 Go generate accepts one specific flag:
 
 	-run=""
-		TODO: This flag is unimplemented.
-		if non-empty, specifies a regular expression to
-		select directives whose command matches the expression.
+		if non-empty, specifies a regular expression to select
+		directives whose full original source text (excluding
+		any trailing spaces and final newline) matches the
+		expression.
 
 It also accepts the standard build flags -v, -n, and -x.
 The -v flag prints the names of packages and files as they are
@@ -120,7 +125,10 @@
 	`,
 }
 
-var generateRunFlag string // generate -run flag
+var (
+	generateRunFlag string         // generate -run flag
+	generateRunRE   *regexp.Regexp // compiled expression for -run
+)
 
 func init() {
 	addBuildFlags(cmdGenerate)
@@ -128,6 +136,13 @@
 }
 
 func runGenerate(cmd *Command, args []string) {
+	if generateRunFlag != "" {
+		var err error
+		generateRunRE, err = regexp.Compile(generateRunFlag)
+		if err != nil {
+			log.Fatalf("generate: %s", err)
+		}
+	}
 	// Even if the arguments are .go files, this loop suffices.
 	for _, pkg := range packages(args) {
 		for _, file := range pkg.gofiles {
@@ -163,7 +178,7 @@
 	file     string // base name of file.
 	pkg      string
 	commands map[string][]string
-	lineNum  int
+	lineNum  int // current line number.
 }
 
 // run runs the generators in the current file.
@@ -221,6 +236,11 @@
 		if !isGoGenerate(buf) {
 			continue
 		}
+		if generateRunFlag != "" {
+			if !generateRunRE.Match(bytes.TrimSpace(buf)) {
+				continue
+			}
+		}
 
 		words := g.split(string(buf))
 		if len(words) == 0 {
@@ -306,7 +326,7 @@
 	}
 	// Substitute environment variables.
 	for i, word := range words {
-		words[i] = g.expandEnv(word)
+		words[i] = os.Expand(word, g.expandVar)
 	}
 	return words
 }
@@ -322,38 +342,25 @@
 	panic(stop)
 }
 
-// expandEnv expands any $XXX invocations in word.
-func (g *Generator) expandEnv(word string) string {
-	if !strings.ContainsRune(word, '$') {
-		return word
+// expandVar expands the $XXX invocation in word. It is called
+// by os.Expand.
+func (g *Generator) expandVar(word string) string {
+	switch word {
+	case "GOARCH":
+		return buildContext.GOARCH
+	case "GOOS":
+		return buildContext.GOOS
+	case "GOFILE":
+		return g.file
+	case "GOLINE":
+		return fmt.Sprint(g.lineNum)
+	case "GOPACKAGE":
+		return g.pkg
+	case "DOLLAR":
+		return "$"
+	default:
+		return os.Getenv(word)
 	}
-	var buf bytes.Buffer
-	var w int
-	var r rune
-	for i := 0; i < len(word); i += w {
-		r, w = utf8.DecodeRuneInString(word[i:])
-		if r != '$' {
-			buf.WriteRune(r)
-			continue
-		}
-		w += g.identLength(word[i+w:])
-		envVar := word[i+1 : i+w]
-		var sub string
-		switch envVar {
-		case "GOARCH":
-			sub = runtime.GOARCH
-		case "GOOS":
-			sub = runtime.GOOS
-		case "GOFILE":
-			sub = g.file
-		case "GOPACKAGE":
-			sub = g.pkg
-		default:
-			sub = os.Getenv(envVar)
-		}
-		buf.WriteString(sub)
-	}
-	return buf.String()
 }
 
 // identLength returns the length of the identifier beginning the string.
@@ -395,7 +402,7 @@
 		"GOFILE=" + g.file,
 		"GOPACKAGE=" + g.pkg,
 	}
-	cmd.Env = mergeEnvLists(env, os.Environ())
+	cmd.Env = mergeEnvLists(env, origEnv)
 	err := cmd.Run()
 	if err != nil {
 		g.errorf("running %q: %s", words[0], err)
diff --git a/third_party/gofrontend/libgo/go/cmd/go/generate_test.go b/third_party/gofrontend/libgo/go/cmd/go/generate_test.go
index 2ec5486..169d71c 100644
--- a/third_party/gofrontend/libgo/go/cmd/go/generate_test.go
+++ b/third_party/gofrontend/libgo/go/cmd/go/generate_test.go
@@ -26,6 +26,7 @@
 	{"$GOPACKAGE", []string{"sys"}},
 	{"a $XXNOTDEFINEDXX b", []string{"a", "", "b"}},
 	{"/$XXNOTDEFINED/", []string{"//"}},
+	{"/$DOLLAR/", []string{"/$/"}},
 	{"yacc -o $GOARCH/yacc_$GOFILE", []string{"go", "tool", "yacc", "-o", runtime.GOARCH + "/yacc_proc.go"}},
 }
 
diff --git a/third_party/gofrontend/libgo/go/cmd/go/get.go b/third_party/gofrontend/libgo/go/cmd/go/get.go
index 50e0ca9..e95201a 100644
--- a/third_party/gofrontend/libgo/go/cmd/go/get.go
+++ b/third_party/gofrontend/libgo/go/cmd/go/get.go
@@ -16,7 +16,7 @@
 )
 
 var cmdGet = &Command{
-	UsageLine: "get [-d] [-f] [-fix] [-t] [-u] [build flags] [packages]",
+	UsageLine: "get [-d] [-f] [-fix] [-insecure] [-t] [-u] [build flags] [packages]",
 	Short:     "download and install packages and dependencies",
 	Long: `
 Get downloads and installs the packages named by the import paths,
@@ -33,6 +33,9 @@
 The -fix flag instructs get to run the fix tool on the downloaded packages
 before resolving dependencies or building the code.
 
+The -insecure flag permits fetching from repositories and resolving
+custom domains using insecure schemes such as HTTP. Use with caution.
+
 The -t flag instructs get to also download the packages required to build
 the tests for the specified packages.
 
@@ -48,6 +51,10 @@
 searches for a branch or tag named "go1". If no such version exists it
 retrieves the most recent version of the package.
 
+If the vendoring experiment is enabled (see 'go help gopath'),
+then when go get checks out or updates a Git repository,
+it also updates any git submodules referenced by the repository.
+
 For more about specifying packages, see 'go help packages'.
 
 For more about how 'go get' finds source code to
@@ -62,6 +69,7 @@
 var getT = cmdGet.Flag.Bool("t", false, "")
 var getU = cmdGet.Flag.Bool("u", false, "")
 var getFix = cmdGet.Flag.Bool("fix", false, "")
+var getInsecure = cmdGet.Flag.Bool("insecure", false, "")
 
 func init() {
 	addBuildFlags(cmdGet)
@@ -73,10 +81,20 @@
 		fatalf("go get: cannot use -f flag without -u")
 	}
 
+	// Disable any prompting for passwords by Git.
+	// Only has an effect for 2.3.0 or later, but avoiding
+	// the prompt in earlier versions is just too hard.
+	// See golang.org/issue/9341.
+	os.Setenv("GIT_TERMINAL_PROMPT", "0")
+
 	// Phase 1.  Download/update.
 	var stk importStack
+	mode := 0
+	if *getT {
+		mode |= getTestDeps
+	}
 	for _, arg := range downloadPaths(args) {
-		download(arg, &stk, *getT)
+		download(arg, nil, &stk, mode)
 	}
 	exitIfErrors()
 
@@ -92,12 +110,13 @@
 	}
 
 	args = importPaths(args)
+	packagesForBuild(args)
 
 	// Phase 3.  Install.
 	if *getD {
 		// Download only.
 		// Check delayed until now so that importPaths
-		// has a chance to print errors.
+		// and packagesForBuild have a chance to print errors.
 		return
 	}
 
@@ -148,13 +167,30 @@
 
 // download runs the download half of the get command
 // for the package named by the argument.
-func download(arg string, stk *importStack, getTestDeps bool) {
-	p := loadPackage(arg, stk)
+func download(arg string, parent *Package, stk *importStack, mode int) {
+	load := func(path string, mode int) *Package {
+		if parent == nil {
+			return loadPackage(path, stk)
+		}
+		return loadImport(path, parent.Dir, parent, stk, nil, mode)
+	}
+
+	p := load(arg, mode)
 	if p.Error != nil && p.Error.hard {
 		errorf("%s", p.Error)
 		return
 	}
 
+	// loadPackage inferred the canonical ImportPath from arg.
+	// Use that in the following to prevent hysteresis effects
+	// in e.g. downloadCache and packageCache.
+	// This allows invocations such as:
+	//   mkdir -p $GOPATH/src/github.com/user
+	//   cd $GOPATH/src/github.com/user
+	//   go get ./foo
+	// see: golang.org/issue/9767
+	arg = p.ImportPath
+
 	// There's nothing to do if this is a package in the standard library.
 	if p.Standard {
 		return
@@ -163,7 +199,7 @@
 	// Only process each package once.
 	// (Unless we're fetching test dependencies for this package,
 	// in which case we want to process it again.)
-	if downloadCache[arg] && !getTestDeps {
+	if downloadCache[arg] && mode&getTestDeps == 0 {
 		return
 	}
 	downloadCache[arg] = true
@@ -175,7 +211,7 @@
 	// Download if the package is missing, or update if we're using -u.
 	if p.Dir == "" || *getU {
 		// The actual download.
-		stk.push(p.ImportPath)
+		stk.push(arg)
 		err := downloadPackage(p)
 		if err != nil {
 			errorf("%s", &PackageError{ImportStack: stk.copy(), Err: err.Error()})
@@ -183,6 +219,17 @@
 			return
 		}
 
+		// Warn that code.google.com is shutting down.  We
+		// issue the warning here because this is where we
+		// have the import stack.
+		if strings.HasPrefix(p.ImportPath, "code.google.com") {
+			fmt.Fprintf(os.Stderr, "warning: code.google.com is shutting down; import path %v will stop working\n", p.ImportPath)
+			if len(*stk) > 1 {
+				fmt.Fprintf(os.Stderr, "warning: package %v\n", strings.Join(*stk, "\n\timports "))
+			}
+		}
+		stk.pop()
+
 		args := []string{arg}
 		// If the argument has a wildcard in it, re-evaluate the wildcard.
 		// We delay this until after reloadPackage so that the old entry
@@ -208,9 +255,10 @@
 
 		pkgs = pkgs[:0]
 		for _, arg := range args {
-			stk.push(arg)
-			p := loadPackage(arg, stk)
-			stk.pop()
+			// Note: load calls loadPackage or loadImport,
+			// which push arg onto stk already.
+			// Do not push here too, or else stk will say arg imports arg.
+			p := load(arg, mode)
 			if p.Error != nil {
 				errorf("%s", p.Error)
 				continue
@@ -223,7 +271,7 @@
 	// due to wildcard expansion.
 	for _, p := range pkgs {
 		if *getFix {
-			run(stringList(tool("fix"), relPaths(p.allgofiles)))
+			run(buildToolExec, stringList(tool("fix"), relPaths(p.allgofiles)))
 
 			// The imports might have changed, so reload again.
 			p = reloadPackage(arg, stk)
@@ -240,18 +288,31 @@
 		}
 
 		// Process dependencies, now that we know what they are.
-		for _, dep := range p.deps {
+		for _, path := range p.Imports {
+			if path == "C" {
+				continue
+			}
 			// Don't get test dependencies recursively.
-			download(dep.ImportPath, stk, false)
+			// Imports is already vendor-expanded.
+			download(path, p, stk, 0)
 		}
-		if getTestDeps {
+		if mode&getTestDeps != 0 {
 			// Process test dependencies when -t is specified.
 			// (Don't get test dependencies for test dependencies.)
+			// We pass useVendor here because p.load does not
+			// vendor-expand TestImports and XTestImports.
+			// The call to loadImport inside download needs to do that.
 			for _, path := range p.TestImports {
-				download(path, stk, false)
+				if path == "C" {
+					continue
+				}
+				download(path, p, stk, useVendor)
 			}
 			for _, path := range p.XTestImports {
-				download(path, stk, false)
+				if path == "C" {
+					continue
+				}
+				download(path, p, stk, useVendor)
 			}
 		}
 
@@ -269,6 +330,12 @@
 		repo, rootPath string
 		err            error
 	)
+
+	security := secure
+	if *getInsecure {
+		security = insecure
+	}
+
 	if p.build.SrcRoot != "" {
 		// Directory exists.  Look for checkout along path to src.
 		vcs, rootPath, err = vcsForDir(p)
@@ -278,10 +345,15 @@
 		repo = "<local>" // should be unused; make distinctive
 
 		// Double-check where it came from.
-		if *getU && vcs.remoteRepo != nil && !*getF {
+		if *getU && vcs.remoteRepo != nil {
 			dir := filepath.Join(p.build.SrcRoot, rootPath)
-			if remote, err := vcs.remoteRepo(vcs, dir); err == nil {
-				if rr, err := repoRootForImportPath(p.ImportPath); err == nil {
+			remote, err := vcs.remoteRepo(vcs, dir)
+			if err != nil {
+				return err
+			}
+			repo = remote
+			if !*getF {
+				if rr, err := repoRootForImportPath(p.ImportPath, security); err == nil {
 					repo := rr.repo
 					if rr.vcs.resolveRepo != nil {
 						resolved, err := rr.vcs.resolveRepo(rr.vcs, dir, repo)
@@ -289,7 +361,7 @@
 							repo = resolved
 						}
 					}
-					if remote != repo {
+					if remote != repo && p.ImportComment != "" {
 						return fmt.Errorf("%s is a custom import path for %s, but %s is checked out from %s", rr.root, repo, dir, remote)
 					}
 				}
@@ -298,12 +370,15 @@
 	} else {
 		// Analyze the import path to determine the version control system,
 		// repository, and the import path for the root of the repository.
-		rr, err := repoRootForImportPath(p.ImportPath)
+		rr, err := repoRootForImportPath(p.ImportPath, security)
 		if err != nil {
 			return err
 		}
 		vcs, repo, rootPath = rr.vcs, rr.repo, rr.root
 	}
+	if !vcs.isSecure(repo) && !*getInsecure {
+		return fmt.Errorf("cannot download, %v uses insecure protocol", repo)
+	}
 
 	if p.build.SrcRoot == "" {
 		// Package not found.  Put in first directory of $GOPATH.
diff --git a/third_party/gofrontend/libgo/go/cmd/go/go_test.go b/third_party/gofrontend/libgo/go/cmd/go/go_test.go
new file mode 100644
index 0000000..77b2628
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/cmd/go/go_test.go
@@ -0,0 +1,2389 @@
+// 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_test
+
+import (
+	"bytes"
+	"flag"
+	"fmt"
+	"go/build"
+	"go/format"
+	"internal/testenv"
+	"io"
+	"io/ioutil"
+	"os"
+	"os/exec"
+	"path/filepath"
+	"regexp"
+	"runtime"
+	"strconv"
+	"strings"
+	"testing"
+	"time"
+)
+
+var (
+	canRun  = true  // whether we can run go or ./testgo
+	canRace = false // whether we can run the race detector
+	canCgo  = false // whether we can use cgo
+
+	exeSuffix string // ".exe" on Windows
+
+	builder             = testenv.Builder()
+	skipExternalBuilder = false // skip external tests on this builder
+)
+
+func init() {
+	switch runtime.GOOS {
+	case "android", "nacl":
+		canRun = false
+	case "darwin":
+		switch runtime.GOARCH {
+		case "arm", "arm64":
+			canRun = false
+		}
+	}
+
+	if strings.HasPrefix(builder+"-", "freebsd-arm-") {
+		skipExternalBuilder = true
+		canRun = false
+	}
+
+	switch runtime.GOOS {
+	case "windows":
+		exeSuffix = ".exe"
+	}
+}
+
+// The TestMain function creates a go command for testing purposes and
+// deletes it after the tests have been run.
+func TestMain(m *testing.M) {
+	flag.Parse()
+
+	if canRun {
+		out, err := exec.Command("go", "build", "-tags", "testgo", "-o", "testgo"+exeSuffix).CombinedOutput()
+		if err != nil {
+			fmt.Fprintf(os.Stderr, "building testgo failed: %v\n%s", err, out)
+			os.Exit(2)
+		}
+
+		if out, err := exec.Command("./testgo"+exeSuffix, "env", "CGO_ENABLED").Output(); err != nil {
+			fmt.Fprintf(os.Stderr, "running testgo failed: %v\n", err)
+			canRun = false
+		} else {
+			canCgo, err = strconv.ParseBool(strings.TrimSpace(string(out)))
+			if err != nil {
+				fmt.Fprintf(os.Stderr, "can't parse go env CGO_ENABLED output: %v\n", strings.TrimSpace(string(out)))
+			}
+		}
+
+		switch runtime.GOOS {
+		case "linux", "darwin", "freebsd", "windows":
+			canRace = canCgo && runtime.GOARCH == "amd64"
+		}
+
+		measureTick("./testgo" + exeSuffix)
+	}
+
+	// Don't let these environment variables confuse the test.
+	os.Unsetenv("GOBIN")
+	os.Unsetenv("GOPATH")
+
+	r := m.Run()
+
+	if canRun {
+		os.Remove("testgo" + exeSuffix)
+	}
+
+	os.Exit(r)
+}
+
+// The length of an mtime tick on this system.  This is an estimate of
+// how long we need to sleep to ensure that the mtime of two files is
+// different.
+var mtimeTick time.Duration
+
+// measureTick sets mtimeTick by looking at the rounding of the mtime
+// of a file.
+func measureTick(path string) {
+	st, err := os.Stat(path)
+	if err != nil {
+		// Default to one second, the most conservative value.
+		mtimeTick = time.Second
+		return
+	}
+	mtime := st.ModTime()
+	t := time.Microsecond
+	for mtime.Round(t).Equal(mtime) && t < time.Second {
+		t *= 10
+	}
+	mtimeTick = t
+}
+
+// Manage a single run of the testgo binary.
+type testgoData struct {
+	t              *testing.T
+	temps          []string
+	wd             string
+	env            []string
+	tempdir        string
+	ran            bool
+	inParallel     bool
+	stdout, stderr bytes.Buffer
+}
+
+// testgo sets up for a test that runs testgo.
+func testgo(t *testing.T) *testgoData {
+	testenv.MustHaveGoBuild(t)
+
+	if skipExternalBuilder {
+		t.Skip("skipping external tests on %s builder", builder)
+	}
+
+	return &testgoData{t: t}
+}
+
+// must gives a fatal error if err is not nil.
+func (tg *testgoData) must(err error) {
+	if err != nil {
+		tg.t.Fatal(err)
+	}
+}
+
+// check gives a test non-fatal error if err is not nil.
+func (tg *testgoData) check(err error) {
+	if err != nil {
+		tg.t.Error(err)
+	}
+}
+
+// parallel runs the test in parallel by calling t.Parallel.
+func (tg *testgoData) parallel() {
+	if tg.ran {
+		tg.t.Fatal("internal testsuite error: call to parallel after run")
+	}
+	if tg.wd != "" {
+		tg.t.Fatal("internal testsuite error: call to parallel after cd")
+	}
+	for _, e := range tg.env {
+		if strings.HasPrefix(e, "GOROOT=") || strings.HasPrefix(e, "GOPATH=") || strings.HasPrefix(e, "GOBIN=") {
+			val := e[strings.Index(e, "=")+1:]
+			if strings.HasPrefix(val, "testdata") || strings.HasPrefix(val, "./testdata") {
+				tg.t.Fatalf("internal testsuite error: call to parallel with testdata in environment (%s)", e)
+			}
+		}
+	}
+	tg.inParallel = true
+	tg.t.Parallel()
+}
+
+// pwd returns the current directory.
+func (tg *testgoData) pwd() string {
+	wd, err := os.Getwd()
+	if err != nil {
+		tg.t.Fatalf("could not get working directory: %v", err)
+	}
+	return wd
+}
+
+// cd changes the current directory to the named directory.  Note that
+// using this means that the test must not be run in parallel with any
+// other tests.
+func (tg *testgoData) cd(dir string) {
+	if tg.inParallel {
+		tg.t.Fatal("internal testsuite error: changing directory when running in parallel")
+	}
+	if tg.wd == "" {
+		tg.wd = tg.pwd()
+	}
+	abs, err := filepath.Abs(dir)
+	tg.must(os.Chdir(dir))
+	if err == nil {
+		tg.setenv("PWD", abs)
+	}
+}
+
+// sleep sleeps for one tick, where a tick is a conservative estimate
+// of how long it takes for a file modification to get a different
+// mtime.
+func (tg *testgoData) sleep() {
+	time.Sleep(mtimeTick)
+}
+
+// setenv sets an environment variable to use when running the test go
+// command.
+func (tg *testgoData) setenv(name, val string) {
+	if tg.inParallel && (name == "GOROOT" || name == "GOPATH" || name == "GOBIN") && (strings.HasPrefix(val, "testdata") || strings.HasPrefix(val, "./testdata")) {
+		tg.t.Fatalf("internal testsuite error: call to setenv with testdata (%s=%s) after parallel", name, val)
+	}
+	tg.unsetenv(name)
+	tg.env = append(tg.env, name+"="+val)
+}
+
+// unsetenv removes an environment variable.
+func (tg *testgoData) unsetenv(name string) {
+	if tg.env == nil {
+		tg.env = append([]string(nil), os.Environ()...)
+	}
+	for i, v := range tg.env {
+		if strings.HasPrefix(v, name+"=") {
+			tg.env = append(tg.env[:i], tg.env[i+1:]...)
+			break
+		}
+	}
+}
+
+// doRun runs the test go command, recording stdout and stderr and
+// returning exit status.
+func (tg *testgoData) doRun(args []string) error {
+	if !canRun {
+		panic("testgoData.doRun called but canRun false")
+	}
+	if tg.inParallel {
+		for _, arg := range args {
+			if strings.HasPrefix(arg, "testdata") || strings.HasPrefix(arg, "./testdata") {
+				tg.t.Fatal("internal testsuite error: parallel run using testdata")
+			}
+		}
+	}
+	tg.t.Logf("running testgo %v", args)
+	var prog string
+	if tg.wd == "" {
+		prog = "./testgo" + exeSuffix
+	} else {
+		prog = filepath.Join(tg.wd, "testgo"+exeSuffix)
+	}
+	cmd := exec.Command(prog, args...)
+	tg.stdout.Reset()
+	tg.stderr.Reset()
+	cmd.Stdout = &tg.stdout
+	cmd.Stderr = &tg.stderr
+	cmd.Env = tg.env
+	status := cmd.Run()
+	if tg.stdout.Len() > 0 {
+		tg.t.Log("standard output:")
+		tg.t.Log(tg.stdout.String())
+	}
+	if tg.stderr.Len() > 0 {
+		tg.t.Log("standard error:")
+		tg.t.Log(tg.stderr.String())
+	}
+	tg.ran = true
+	return status
+}
+
+// run runs the test go command, and expects it to succeed.
+func (tg *testgoData) run(args ...string) {
+	if status := tg.doRun(args); status != nil {
+		tg.t.Logf("go %v failed unexpectedly: %v", args, status)
+		tg.t.FailNow()
+	}
+}
+
+// runFail runs the test go command, and expects it to fail.
+func (tg *testgoData) runFail(args ...string) {
+	if status := tg.doRun(args); status == nil {
+		tg.t.Fatal("testgo succeeded unexpectedly")
+	} else {
+		tg.t.Log("testgo failed as expected:", status)
+	}
+}
+
+// runGit runs a git command, and expects it to succeed.
+func (tg *testgoData) runGit(dir string, args ...string) {
+	cmd := exec.Command("git", args...)
+	tg.stdout.Reset()
+	tg.stderr.Reset()
+	cmd.Stdout = &tg.stdout
+	cmd.Stderr = &tg.stderr
+	cmd.Dir = dir
+	cmd.Env = tg.env
+	status := cmd.Run()
+	if tg.stdout.Len() > 0 {
+		tg.t.Log("git standard output:")
+		tg.t.Log(tg.stdout.String())
+	}
+	if tg.stderr.Len() > 0 {
+		tg.t.Log("git standard error:")
+		tg.t.Log(tg.stderr.String())
+	}
+	if status != nil {
+		tg.t.Logf("git %v failed unexpectedly: %v", args, status)
+		tg.t.FailNow()
+	}
+}
+
+// getStdout returns standard output of the testgo run as a string.
+func (tg *testgoData) getStdout() string {
+	if !tg.ran {
+		tg.t.Fatal("internal testsuite error: stdout called before run")
+	}
+	return tg.stdout.String()
+}
+
+// getStderr returns standard error of the testgo run as a string.
+func (tg *testgoData) getStderr() string {
+	if !tg.ran {
+		tg.t.Fatal("internal testsuite error: stdout called before run")
+	}
+	return tg.stderr.String()
+}
+
+// doGrepMatch looks for a regular expression in a buffer, and returns
+// whether it is found.  The regular expression is matched against
+// each line separately, as with the grep command.
+func (tg *testgoData) doGrepMatch(match string, b *bytes.Buffer) bool {
+	if !tg.ran {
+		tg.t.Fatal("internal testsuite error: grep called before run")
+	}
+	re := regexp.MustCompile(match)
+	for _, ln := range bytes.Split(b.Bytes(), []byte{'\n'}) {
+		if re.Match(ln) {
+			return true
+		}
+	}
+	return false
+}
+
+// doGrep looks for a regular expression in a buffer and fails if it
+// is not found.  The name argument is the name of the output we are
+// searching, "output" or "error".  The msg argument is logged on
+// failure.
+func (tg *testgoData) doGrep(match string, b *bytes.Buffer, name, msg string) {
+	if !tg.doGrepMatch(match, b) {
+		tg.t.Log(msg)
+		tg.t.Logf("pattern %v not found in standard %s", match, name)
+		tg.t.FailNow()
+	}
+}
+
+// grepStdout looks for a regular expression in the test run's
+// standard output and fails, logging msg, if it is not found.
+func (tg *testgoData) grepStdout(match, msg string) {
+	tg.doGrep(match, &tg.stdout, "output", msg)
+}
+
+// grepStderr looks for a regular expression in the test run's
+// standard error and fails, logging msg, if it is not found.
+func (tg *testgoData) grepStderr(match, msg string) {
+	tg.doGrep(match, &tg.stderr, "error", msg)
+}
+
+// grepBoth looks for a regular expression in the test run's standard
+// output or stand error and fails, logging msg, if it is not found.
+func (tg *testgoData) grepBoth(match, msg string) {
+	if !tg.doGrepMatch(match, &tg.stdout) && !tg.doGrepMatch(match, &tg.stderr) {
+		tg.t.Log(msg)
+		tg.t.Logf("pattern %v not found in standard output or standard error", match)
+		tg.t.FailNow()
+	}
+}
+
+// doGrepNot looks for a regular expression in a buffer and fails if
+// it is found.  The name and msg arguments are as for doGrep.
+func (tg *testgoData) doGrepNot(match string, b *bytes.Buffer, name, msg string) {
+	if tg.doGrepMatch(match, b) {
+		tg.t.Log(msg)
+		tg.t.Logf("pattern %v found unexpectedly in standard %s", match, name)
+		tg.t.FailNow()
+	}
+}
+
+// grepStdoutNot looks for a regular expression in the test run's
+// standard output and fails, logging msg, if it is found.
+func (tg *testgoData) grepStdoutNot(match, msg string) {
+	tg.doGrepNot(match, &tg.stdout, "output", msg)
+}
+
+// grepStderrNot looks for a regular expression in the test run's
+// standard error and fails, logging msg, if it is found.
+func (tg *testgoData) grepStderrNot(match, msg string) {
+	tg.doGrepNot(match, &tg.stderr, "error", msg)
+}
+
+// grepBothNot looks for a regular expression in the test run's
+// standard output or stand error and fails, logging msg, if it is
+// found.
+func (tg *testgoData) grepBothNot(match, msg string) {
+	if tg.doGrepMatch(match, &tg.stdout) || tg.doGrepMatch(match, &tg.stderr) {
+		tg.t.Log(msg)
+		tg.t.Fatalf("pattern %v found unexpectedly in standard output or standard error", match)
+	}
+}
+
+// doGrepCount counts the number of times a regexp is seen in a buffer.
+func (tg *testgoData) doGrepCount(match string, b *bytes.Buffer) int {
+	if !tg.ran {
+		tg.t.Fatal("internal testsuite error: doGrepCount called before run")
+	}
+	re := regexp.MustCompile(match)
+	c := 0
+	for _, ln := range bytes.Split(b.Bytes(), []byte{'\n'}) {
+		if re.Match(ln) {
+			c++
+		}
+	}
+	return c
+}
+
+// grepCountStdout returns the number of times a regexp is seen in
+// standard output.
+func (tg *testgoData) grepCountStdout(match string) int {
+	return tg.doGrepCount(match, &tg.stdout)
+}
+
+// grepCountStderr returns the number of times a regexp is seen in
+// standard error.
+func (tg *testgoData) grepCountStderr(match string) int {
+	return tg.doGrepCount(match, &tg.stderr)
+}
+
+// grepCountBoth returns the number of times a regexp is seen in both
+// standard output and standard error.
+func (tg *testgoData) grepCountBoth(match string) int {
+	return tg.doGrepCount(match, &tg.stdout) + tg.doGrepCount(match, &tg.stderr)
+}
+
+// creatingTemp records that the test plans to create a temporary file
+// or directory.  If the file or directory exists already, it will be
+// removed.  When the test completes, the file or directory will be
+// removed if it exists.
+func (tg *testgoData) creatingTemp(path string) {
+	if filepath.IsAbs(path) && !strings.HasPrefix(path, tg.tempdir) {
+		tg.t.Fatal("internal testsuite error: creatingTemp(%q) with absolute path not in temporary directory", path)
+	}
+	// If we have changed the working directory, make sure we have
+	// an absolute path, because we are going to change directory
+	// back before we remove the temporary.
+	if tg.wd != "" && !filepath.IsAbs(path) {
+		path = filepath.Join(tg.pwd(), path)
+	}
+	tg.must(os.RemoveAll(path))
+	tg.temps = append(tg.temps, path)
+}
+
+// makeTempdir makes a temporary directory for a run of testgo.  If
+// the temporary directory was already created, this does nothing.
+func (tg *testgoData) makeTempdir() {
+	if tg.tempdir == "" {
+		var err error
+		tg.tempdir, err = ioutil.TempDir("", "gotest")
+		tg.must(err)
+	}
+}
+
+// tempFile adds a temporary file for a run of testgo.
+func (tg *testgoData) tempFile(path, contents string) {
+	tg.makeTempdir()
+	tg.must(os.MkdirAll(filepath.Join(tg.tempdir, filepath.Dir(path)), 0755))
+	bytes := []byte(contents)
+	if strings.HasSuffix(path, ".go") {
+		formatted, err := format.Source(bytes)
+		if err == nil {
+			bytes = formatted
+		}
+	}
+	tg.must(ioutil.WriteFile(filepath.Join(tg.tempdir, path), bytes, 0644))
+}
+
+// tempDir adds a temporary directory for a run of testgo.
+func (tg *testgoData) tempDir(path string) {
+	tg.makeTempdir()
+	if err := os.MkdirAll(filepath.Join(tg.tempdir, path), 0755); err != nil && !os.IsExist(err) {
+		tg.t.Fatal(err)
+	}
+}
+
+// path returns the absolute pathname to file with the temporary
+// directory.
+func (tg *testgoData) path(name string) string {
+	if tg.tempdir == "" {
+		tg.t.Fatalf("internal testsuite error: path(%q) with no tempdir", name)
+	}
+	if name == "." {
+		return tg.tempdir
+	}
+	return filepath.Join(tg.tempdir, name)
+}
+
+// mustNotExist fails if path exists.
+func (tg *testgoData) mustNotExist(path string) {
+	if _, err := os.Stat(path); err == nil || !os.IsNotExist(err) {
+		tg.t.Fatalf("%s exists but should not (%v)", path, err)
+	}
+}
+
+// wantExecutable fails with msg if path is not executable.
+func (tg *testgoData) wantExecutable(path, msg string) {
+	if st, err := os.Stat(path); err != nil {
+		if !os.IsNotExist(err) {
+			tg.t.Log(err)
+		}
+		tg.t.Fatal(msg)
+	} else {
+		if runtime.GOOS != "windows" && st.Mode()&0111 == 0 {
+			tg.t.Fatalf("binary %s exists but is not executable", path)
+		}
+	}
+}
+
+// wantArchive fails if path is not an archive.
+func (tg *testgoData) wantArchive(path string) {
+	f, err := os.Open(path)
+	if err != nil {
+		tg.t.Fatal(err)
+	}
+	buf := make([]byte, 100)
+	io.ReadFull(f, buf)
+	f.Close()
+	if !bytes.HasPrefix(buf, []byte("!<arch>\n")) {
+		tg.t.Fatalf("file %s exists but is not an archive", path)
+	}
+}
+
+// isStale returns whether pkg is stale.
+func (tg *testgoData) isStale(pkg string) bool {
+	tg.run("list", "-f", "{{.Stale}}", pkg)
+	switch v := strings.TrimSpace(tg.getStdout()); v {
+	case "true":
+		return true
+	case "false":
+		return false
+	default:
+		tg.t.Fatalf("unexpected output checking staleness of package %v: %v", pkg, v)
+		panic("unreachable")
+	}
+}
+
+// wantStale fails with msg if pkg is not stale.
+func (tg *testgoData) wantStale(pkg, msg string) {
+	if !tg.isStale(pkg) {
+		tg.t.Fatal(msg)
+	}
+}
+
+// wantNotStale fails with msg if pkg is stale.
+func (tg *testgoData) wantNotStale(pkg, msg string) {
+	if tg.isStale(pkg) {
+		tg.t.Fatal(msg)
+	}
+}
+
+// cleanup cleans up a test that runs testgo.
+func (tg *testgoData) cleanup() {
+	if tg.wd != "" {
+		if err := os.Chdir(tg.wd); err != nil {
+			// We are unlikely to be able to continue.
+			fmt.Fprintln(os.Stderr, "could not restore working directory, crashing:", err)
+			os.Exit(2)
+		}
+	}
+	for _, path := range tg.temps {
+		tg.check(os.RemoveAll(path))
+	}
+	if tg.tempdir != "" {
+		tg.check(os.RemoveAll(tg.tempdir))
+	}
+}
+
+// resetReadOnlyFlagAll resets windows read-only flag
+// set on path and any children it contains.
+// The flag is set by git and has to be removed.
+// os.Remove refuses to remove files with read-only flag set.
+func (tg *testgoData) resetReadOnlyFlagAll(path string) {
+	fi, err := os.Stat(path)
+	if err != nil {
+		tg.t.Fatalf("resetReadOnlyFlagAll(%q) failed: %v", path, err)
+	}
+	if !fi.IsDir() {
+		err := os.Chmod(path, 0666)
+		if err != nil {
+			tg.t.Fatalf("resetReadOnlyFlagAll(%q) failed: %v", path, err)
+		}
+	}
+	fd, err := os.Open(path)
+	if err != nil {
+		tg.t.Fatalf("resetReadOnlyFlagAll(%q) failed: %v", path, err)
+	}
+	defer fd.Close()
+	names, _ := fd.Readdirnames(-1)
+	for _, name := range names {
+		tg.resetReadOnlyFlagAll(path + string(filepath.Separator) + name)
+	}
+}
+
+// failSSH puts an ssh executable in the PATH that always fails.
+// This is to stub out uses of ssh by go get.
+func (tg *testgoData) failSSH() {
+	wd, err := os.Getwd()
+	if err != nil {
+		tg.t.Fatal(err)
+	}
+	fail := filepath.Join(wd, "testdata/failssh")
+	tg.setenv("PATH", fmt.Sprintf("%v%c%v", fail, filepath.ListSeparator, os.Getenv("PATH")))
+}
+
+func TestFileLineInErrorMessages(t *testing.T) {
+	tg := testgo(t)
+	defer tg.cleanup()
+	tg.parallel()
+	tg.tempFile("err.go", `package main; import "bar"`)
+	path := tg.path("err.go")
+	tg.runFail("run", path)
+	shortPath := path
+	if rel, err := filepath.Rel(tg.pwd(), path); err == nil && len(rel) < len(path) {
+		shortPath = rel
+	}
+	tg.grepStderr("^"+regexp.QuoteMeta(shortPath)+":", "missing file:line in error message")
+}
+
+func TestProgramNameInCrashMessages(t *testing.T) {
+	tg := testgo(t)
+	defer tg.cleanup()
+	tg.parallel()
+	tg.tempFile("triv.go", `package main; func main() {}`)
+	tg.runFail("build", "-ldflags", "-crash_for_testing", tg.path("triv.go"))
+	tg.grepStderr(`[/\\]tool[/\\].*[/\\]link`, "missing linker name in error message")
+}
+
+func TestBrokenTestsWithoutTestFunctionsAllFail(t *testing.T) {
+	tg := testgo(t)
+	defer tg.cleanup()
+	tg.runFail("test", "./testdata/src/badtest/...")
+	tg.grepBothNot("^ok", "test passed unexpectedly")
+	tg.grepBoth("FAIL.*badtest/badexec", "test did not run everything")
+	tg.grepBoth("FAIL.*badtest/badsyntax", "test did not run everything")
+	tg.grepBoth("FAIL.*badtest/badvar", "test did not run everything")
+}
+
+func TestGoBuildDashAInDevBranch(t *testing.T) {
+	if testing.Short() {
+		t.Skip("don't rebuild the standard library in short mode")
+	}
+
+	tg := testgo(t)
+	defer tg.cleanup()
+	tg.run("install", "math") // should be up to date already but just in case
+	tg.setenv("TESTGO_IS_GO_RELEASE", "0")
+	tg.run("build", "-v", "-a", "math")
+	tg.grepStderr("runtime", "testgo build -a math in dev branch DID NOT build runtime, but should have")
+}
+
+func TestGoBuilDashAInReleaseBranch(t *testing.T) {
+	if testing.Short() {
+		t.Skip("don't rebuild the standard library in short mode")
+	}
+
+	tg := testgo(t)
+	defer tg.cleanup()
+	tg.run("install", "math") // should be up to date already but just in case
+	tg.setenv("TESTGO_IS_GO_RELEASE", "1")
+	tg.run("build", "-v", "-a", "math")
+	tg.grepStderr("runtime", "testgo build -a math in dev branch did not build runtime, but should have")
+}
+
+func TestGoInstallCleansUpAfterGoBuild(t *testing.T) {
+	tg := testgo(t)
+	defer tg.cleanup()
+	tg.tempFile("src/mycmd/main.go", `package main; func main(){}`)
+	tg.setenv("GOPATH", tg.path("."))
+	tg.cd(tg.path("src/mycmd"))
+
+	doesNotExist := func(file, msg string) {
+		if _, err := os.Stat(file); err == nil {
+			t.Fatal(msg)
+		} else if !os.IsNotExist(err) {
+			t.Fatal(msg, "error:", err)
+		}
+	}
+
+	tg.run("build")
+	tg.wantExecutable("mycmd"+exeSuffix, "testgo build did not write command binary")
+	tg.run("install")
+	doesNotExist("mycmd"+exeSuffix, "testgo install did not remove command binary")
+	tg.run("build")
+	tg.wantExecutable("mycmd"+exeSuffix, "testgo build did not write command binary (second time)")
+	// Running install with arguments does not remove the target,
+	// even in the same directory.
+	tg.run("install", "mycmd")
+	tg.wantExecutable("mycmd"+exeSuffix, "testgo install mycmd removed command binary when run in mycmd")
+	tg.run("build")
+	tg.wantExecutable("mycmd"+exeSuffix, "testgo build did not write command binary (third time)")
+	// And especially not outside the directory.
+	tg.cd(tg.path("."))
+	if data, err := ioutil.ReadFile("src/mycmd/mycmd" + exeSuffix); err != nil {
+		t.Fatal("could not read file:", err)
+	} else {
+		if err := ioutil.WriteFile("mycmd"+exeSuffix, data, 0555); err != nil {
+			t.Fatal("could not write file:", err)
+		}
+	}
+	tg.run("install", "mycmd")
+	tg.wantExecutable("src/mycmd/mycmd"+exeSuffix, "testgo install mycmd removed command binary from its source dir when run outside mycmd")
+	tg.wantExecutable("mycmd"+exeSuffix, "testgo install mycmd removed command binary from current dir when run outside mycmd")
+}
+
+func TestGoInstallRebuildsStalePackagesInOtherGOPATH(t *testing.T) {
+	tg := testgo(t)
+	defer tg.cleanup()
+	tg.parallel()
+	tg.tempFile("d1/src/p1/p1.go", `package p1
+		import "p2"
+		func F() { p2.F() }`)
+	tg.tempFile("d2/src/p2/p2.go", `package p2
+		func F() {}`)
+	sep := string(filepath.ListSeparator)
+	tg.setenv("GOPATH", tg.path("d1")+sep+tg.path("d2"))
+	tg.run("install", "p1")
+	tg.wantNotStale("p1", "./testgo list mypkg claims p1 is stale, incorrectly")
+	tg.wantNotStale("p2", "./testgo list mypkg claims p2 is stale, incorrectly")
+	tg.sleep()
+	if f, err := os.OpenFile(tg.path("d2/src/p2/p2.go"), os.O_WRONLY|os.O_APPEND, 0); err != nil {
+		t.Fatal(err)
+	} else if _, err = f.WriteString(`func G() {}`); err != nil {
+		t.Fatal(err)
+	} else {
+		tg.must(f.Close())
+	}
+	tg.wantStale("p2", "./testgo list mypkg claims p2 is NOT stale, incorrectly")
+	tg.wantStale("p1", "./testgo list mypkg claims p1 is NOT stale, incorrectly")
+
+	tg.run("install", "p1")
+	tg.wantNotStale("p2", "./testgo list mypkg claims p2 is stale after reinstall, incorrectly")
+	tg.wantNotStale("p1", "./testgo list mypkg claims p1 is stale after reinstall, incorrectly")
+}
+
+func TestGoInstallDetectsRemovedFiles(t *testing.T) {
+	tg := testgo(t)
+	defer tg.cleanup()
+	tg.parallel()
+	tg.tempFile("src/mypkg/x.go", `package mypkg`)
+	tg.tempFile("src/mypkg/y.go", `package mypkg`)
+	tg.tempFile("src/mypkg/z.go", `// +build missingtag
+
+		package mypkg`)
+	tg.setenv("GOPATH", tg.path("."))
+	tg.run("install", "mypkg")
+	tg.wantNotStale("mypkg", "./testgo list mypkg claims mypkg is stale, incorrectly")
+	// z.go was not part of the build; removing it is okay.
+	tg.must(os.Remove(tg.path("src/mypkg/z.go")))
+	tg.wantNotStale("mypkg", "./testgo list mypkg claims mypkg is stale after removing z.go; should not be stale")
+	// y.go was part of the package; removing it should be detected.
+	tg.must(os.Remove(tg.path("src/mypkg/y.go")))
+	tg.wantStale("mypkg", "./testgo list mypkg claims mypkg is NOT stale after removing y.go; should be stale")
+}
+
+func TestGoInstallErrorOnCrossCompileToBin(t *testing.T) {
+	if testing.Short() {
+		t.Skip("don't install into GOROOT in short mode")
+	}
+
+	tg := testgo(t)
+	defer tg.cleanup()
+	tg.tempFile("src/mycmd/x.go", `package main
+		func main() {}`)
+	tg.setenv("GOPATH", tg.path("."))
+	tg.cd(tg.path("src/mycmd"))
+
+	tg.run("build", "mycmd")
+
+	goarch := "386"
+	if runtime.GOARCH == "386" {
+		goarch = "amd64"
+	}
+	tg.setenv("GOOS", "linux")
+	tg.setenv("GOARCH", goarch)
+	tg.run("install", "mycmd")
+	tg.setenv("GOBIN", tg.path("."))
+	tg.runFail("install", "mycmd")
+	tg.run("install", "cmd/pack")
+}
+
+func TestGoInstallDetectsRemovedFilesInPackageMain(t *testing.T) {
+	tg := testgo(t)
+	defer tg.cleanup()
+	tg.parallel()
+	tg.tempFile("src/mycmd/x.go", `package main
+		func main() {}`)
+	tg.tempFile("src/mycmd/y.go", `package main`)
+	tg.tempFile("src/mycmd/z.go", `// +build missingtag
+
+		package main`)
+	tg.setenv("GOPATH", tg.path("."))
+	tg.run("install", "mycmd")
+	tg.wantNotStale("mycmd", "./testgo list mypkg claims mycmd is stale, incorrectly")
+	// z.go was not part of the build; removing it is okay.
+	tg.must(os.Remove(tg.path("src/mycmd/z.go")))
+	tg.wantNotStale("mycmd", "./testgo list mycmd claims mycmd is stale after removing z.go; should not be stale")
+	// y.go was part of the package; removing it should be detected.
+	tg.must(os.Remove(tg.path("src/mycmd/y.go")))
+	tg.wantStale("mycmd", "./testgo list mycmd claims mycmd is NOT stale after removing y.go; should be stale")
+}
+
+func testLocalRun(tg *testgoData, exepath, local, match string) {
+	out, err := exec.Command(exepath).Output()
+	if err != nil {
+		tg.t.Fatalf("error running %v: %v", exepath, err)
+	}
+	if !regexp.MustCompile(match).Match(out) {
+		tg.t.Log(string(out))
+		tg.t.Errorf("testdata/%s/easy.go did not generate expected output", local)
+	}
+}
+
+func testLocalEasy(tg *testgoData, local string) {
+	exepath := "./easy" + exeSuffix
+	tg.creatingTemp(exepath)
+	tg.run("build", "-o", exepath, filepath.Join("testdata", local, "easy.go"))
+	testLocalRun(tg, exepath, local, `(?m)^easysub\.Hello`)
+}
+
+func testLocalEasySub(tg *testgoData, local string) {
+	exepath := "./easysub" + exeSuffix
+	tg.creatingTemp(exepath)
+	tg.run("build", "-o", exepath, filepath.Join("testdata", local, "easysub", "main.go"))
+	testLocalRun(tg, exepath, local, `(?m)^easysub\.Hello`)
+}
+
+func testLocalHard(tg *testgoData, local string) {
+	exepath := "./hard" + exeSuffix
+	tg.creatingTemp(exepath)
+	tg.run("build", "-o", exepath, filepath.Join("testdata", local, "hard.go"))
+	testLocalRun(tg, exepath, local, `(?m)^sub\.Hello`)
+}
+
+func testLocalInstall(tg *testgoData, local string) {
+	tg.runFail("install", filepath.Join("testdata", local, "easy.go"))
+}
+
+func TestLocalImportsEasy(t *testing.T) {
+	tg := testgo(t)
+	defer tg.cleanup()
+	testLocalEasy(tg, "local")
+}
+
+func TestLocalImportsEasySub(t *testing.T) {
+	tg := testgo(t)
+	defer tg.cleanup()
+	testLocalEasySub(tg, "local")
+}
+
+func TestLocalImportsHard(t *testing.T) {
+	tg := testgo(t)
+	defer tg.cleanup()
+	testLocalHard(tg, "local")
+}
+
+func TestLocalImportsGoInstallShouldFail(t *testing.T) {
+	tg := testgo(t)
+	defer tg.cleanup()
+	testLocalInstall(tg, "local")
+}
+
+const badDirName = `#$%:, &()*;<=>?\^{}`
+
+func copyBad(tg *testgoData) {
+	if runtime.GOOS == "windows" {
+		tg.t.Skipf("skipping test because %q is an invalid directory name", badDirName)
+	}
+
+	tg.must(filepath.Walk("testdata/local",
+		func(path string, info os.FileInfo, err error) error {
+			if err != nil {
+				return err
+			}
+			if info.IsDir() {
+				return nil
+			}
+			var data []byte
+			data, err = ioutil.ReadFile(path)
+			if err != nil {
+				return err
+			}
+			newpath := strings.Replace(path, "local", badDirName, 1)
+			tg.tempFile(newpath, string(data))
+			return nil
+		}))
+	tg.cd(tg.path("."))
+}
+
+func TestBadImportsEasy(t *testing.T) {
+	tg := testgo(t)
+	defer tg.cleanup()
+	copyBad(tg)
+	testLocalEasy(tg, badDirName)
+}
+
+func TestBadImportsEasySub(t *testing.T) {
+	tg := testgo(t)
+	defer tg.cleanup()
+	copyBad(tg)
+	testLocalEasySub(tg, badDirName)
+}
+
+func TestBadImportsHard(t *testing.T) {
+	tg := testgo(t)
+	defer tg.cleanup()
+	copyBad(tg)
+	testLocalHard(tg, badDirName)
+}
+
+func TestBadImportsGoInstallShouldFail(t *testing.T) {
+	tg := testgo(t)
+	defer tg.cleanup()
+	copyBad(tg)
+	testLocalInstall(tg, badDirName)
+}
+
+func TestInternalPackagesInGOROOTAreRespected(t *testing.T) {
+	tg := testgo(t)
+	defer tg.cleanup()
+	tg.runFail("build", "-v", "./testdata/testinternal")
+	tg.grepBoth("use of internal package not allowed", "wrong error message for testdata/testinternal")
+}
+
+func TestInternalPackagesOutsideGOROOTAreRespected(t *testing.T) {
+	tg := testgo(t)
+	defer tg.cleanup()
+	tg.runFail("build", "-v", "./testdata/testinternal2")
+	tg.grepBoth("use of internal package not allowed", "wrote error message for testdata/testinternal2")
+}
+
+func testMove(t *testing.T, vcs, url, base, config string) {
+	testenv.MustHaveExternalNetwork(t)
+
+	tg := testgo(t)
+	defer tg.cleanup()
+	tg.parallel()
+	tg.tempDir("src")
+	tg.setenv("GOPATH", tg.path("."))
+	tg.run("get", "-d", url)
+	tg.run("get", "-d", "-u", url)
+	switch vcs {
+	case "svn":
+		// SVN doesn't believe in text files so we can't just edit the config.
+		// Check out a different repo into the wrong place.
+		tg.must(os.RemoveAll(tg.path("src/code.google.com/p/rsc-svn")))
+		tg.run("get", "-d", "-u", "code.google.com/p/rsc-svn2/trunk")
+		tg.must(os.Rename(tg.path("src/code.google.com/p/rsc-svn2"), tg.path("src/code.google.com/p/rsc-svn")))
+	default:
+		path := tg.path(filepath.Join("src", config))
+		data, err := ioutil.ReadFile(path)
+		tg.must(err)
+		data = bytes.Replace(data, []byte(base), []byte(base+"XXX"), -1)
+		tg.must(ioutil.WriteFile(path, data, 0644))
+	}
+	if vcs == "git" {
+		// git will ask for a username and password when we
+		// run go get -d -f -u.  An empty username and
+		// password will work.  Prevent asking by setting
+		// GIT_ASKPASS.
+		tg.creatingTemp("sink" + exeSuffix)
+		tg.tempFile("src/sink/sink.go", `package main; func main() {}`)
+		tg.run("build", "-o", "sink"+exeSuffix, "sink")
+		tg.setenv("GIT_ASKPASS", filepath.Join(tg.pwd(), "sink"+exeSuffix))
+	}
+	tg.runFail("get", "-d", "-u", url)
+	tg.grepStderr("is a custom import path for", "go get -d -u "+url+" failed for wrong reason")
+	tg.runFail("get", "-d", "-f", "-u", url)
+	tg.grepStderr("validating server certificate|not found", "go get -d -f -u "+url+" failed for wrong reason")
+}
+
+func TestInternalPackageErrorsAreHandled(t *testing.T) {
+	tg := testgo(t)
+	defer tg.cleanup()
+	tg.run("list", "./testdata/testinternal3")
+}
+
+func TestInternalCache(t *testing.T) {
+	tg := testgo(t)
+	defer tg.cleanup()
+	tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata/testinternal4"))
+	tg.runFail("build", "p")
+	tg.grepStderr("internal", "did not fail to build p")
+}
+
+func TestMoveGit(t *testing.T) {
+	testMove(t, "git", "rsc.io/pdf", "pdf", "rsc.io/pdf/.git/config")
+}
+
+// TODO(rsc): Set up a test case on bitbucket for hg.
+// func TestMoveHG(t *testing.T) {
+// 	testMove(t, "hg", "rsc.io/x86/x86asm", "x86", "rsc.io/x86/.hg/hgrc")
+// }
+
+// TODO(rsc): Set up a test case on SourceForge (?) for svn.
+// func testMoveSVN(t *testing.T) {
+//	testMove(t, "svn", "code.google.com/p/rsc-svn/trunk", "-", "-")
+// }
+
+func TestImportCommandMatch(t *testing.T) {
+	tg := testgo(t)
+	defer tg.cleanup()
+	tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata/importcom"))
+	tg.run("build", "./testdata/importcom/works.go")
+}
+
+func TestImportCommentMismatch(t *testing.T) {
+	tg := testgo(t)
+	defer tg.cleanup()
+	tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata/importcom"))
+	tg.runFail("build", "./testdata/importcom/wrongplace.go")
+	tg.grepStderr(`wrongplace expects import "my/x"`, "go build did not mention incorrect import")
+}
+
+func TestImportCommentSyntaxError(t *testing.T) {
+	tg := testgo(t)
+	defer tg.cleanup()
+	tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata/importcom"))
+	tg.runFail("build", "./testdata/importcom/bad.go")
+	tg.grepStderr("cannot parse import comment", "go build did not mention syntax error")
+}
+
+func TestImportCommentConflict(t *testing.T) {
+	tg := testgo(t)
+	defer tg.cleanup()
+	tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata/importcom"))
+	tg.runFail("build", "./testdata/importcom/conflict.go")
+	tg.grepStderr("found import comments", "go build did not mention comment conflict")
+}
+
+// cmd/go: custom import path checking should not apply to github.com/xxx/yyy.
+func TestIssue10952(t *testing.T) {
+	testenv.MustHaveExternalNetwork(t)
+
+	if _, err := exec.LookPath("git"); err != nil {
+		t.Skip("skipping because git binary not found")
+	}
+
+	tg := testgo(t)
+	defer tg.cleanup()
+	tg.parallel()
+	tg.tempDir("src")
+	tg.setenv("GOPATH", tg.path("."))
+	const importPath = "github.com/zombiezen/go-get-issue-10952"
+	tg.run("get", "-d", "-u", importPath)
+	repoDir := tg.path("src/" + importPath)
+	defer tg.resetReadOnlyFlagAll(repoDir)
+	tg.runGit(repoDir, "remote", "set-url", "origin", "https://"+importPath+".git")
+	tg.run("get", "-d", "-u", importPath)
+}
+
+func TestDisallowedCSourceFiles(t *testing.T) {
+	tg := testgo(t)
+	defer tg.cleanup()
+	tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata"))
+	tg.runFail("build", "badc")
+	tg.grepStderr("C source files not allowed", "go test did not say C source files not allowed")
+}
+
+func TestErrorMessageForSyntaxErrorInTestGoFileSaysFAIL(t *testing.T) {
+	tg := testgo(t)
+	defer tg.cleanup()
+	tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata"))
+	tg.runFail("test", "syntaxerror")
+	tg.grepStderr("FAIL", "go test did not say FAIL")
+}
+
+func TestWildcardsDoNotLookInUselessDirectories(t *testing.T) {
+	tg := testgo(t)
+	defer tg.cleanup()
+	tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata"))
+	tg.runFail("list", "...")
+	tg.grepBoth("badpkg", "go list ... failure does not mention badpkg")
+	tg.run("list", "m...")
+}
+
+func TestRelativeImportsGoTest(t *testing.T) {
+	tg := testgo(t)
+	defer tg.cleanup()
+	tg.run("test", "./testdata/testimport")
+}
+
+func TestRelativeImportsGoTestDashI(t *testing.T) {
+	tg := testgo(t)
+	defer tg.cleanup()
+	tg.run("test", "-i", "./testdata/testimport")
+}
+
+func TestRelativeImportsInCommandLinePackage(t *testing.T) {
+	tg := testgo(t)
+	defer tg.cleanup()
+	files, err := filepath.Glob("./testdata/testimport/*.go")
+	tg.must(err)
+	tg.run(append([]string{"test"}, files...)...)
+}
+
+func TestVersionControlErrorMessageIncludesCorrectDirectory(t *testing.T) {
+	tg := testgo(t)
+	defer tg.cleanup()
+	tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata/shadow/root1"))
+	tg.runFail("get", "-u", "foo")
+
+	// TODO(iant): We should not have to use strconv.Quote here.
+	// The code in vcs.go should be changed so that it is not required.
+	quoted := strconv.Quote(filepath.Join("testdata", "shadow", "root1", "src", "foo"))
+	quoted = quoted[1 : len(quoted)-1]
+
+	tg.grepStderr(regexp.QuoteMeta(quoted), "go get -u error does not mention shadow/root1/src/foo")
+}
+
+func TestInstallFailsWithNoBuildableFiles(t *testing.T) {
+	tg := testgo(t)
+	defer tg.cleanup()
+	tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata"))
+	tg.setenv("CGO_ENABLED", "0")
+	tg.runFail("install", "cgotest")
+	tg.grepStderr("no buildable Go source files", "go install cgotest did not report 'no buildable Go Source files'")
+}
+
+// Test that without $GOBIN set, binaries get installed
+// into the GOPATH bin directory.
+func TestInstallIntoGOPATH(t *testing.T) {
+	tg := testgo(t)
+	defer tg.cleanup()
+	tg.creatingTemp("testdata/bin/go-cmd-test" + exeSuffix)
+	tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata"))
+	tg.run("install", "go-cmd-test")
+	tg.wantExecutable("testdata/bin/go-cmd-test"+exeSuffix, "go install go-cmd-test did not write to testdata/bin/go-cmd-test")
+}
+
+func TestPackageMainTestImportsArchiveNotBinary(t *testing.T) {
+	tg := testgo(t)
+	defer tg.cleanup()
+	gobin := filepath.Join(tg.pwd(), "testdata", "bin")
+	tg.creatingTemp(gobin)
+	tg.setenv("GOBIN", gobin)
+	tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata"))
+	tg.must(os.Chtimes("./testdata/src/main_test/m.go", time.Now(), time.Now()))
+	tg.sleep()
+	tg.run("test", "main_test")
+	tg.run("install", "main_test")
+	tg.wantNotStale("main_test", "after go install, main listed as stale")
+	tg.run("test", "main_test")
+}
+
+// With $GOBIN set, binaries get installed to $GOBIN.
+func TestInstallIntoGOBIN(t *testing.T) {
+	tg := testgo(t)
+	defer tg.cleanup()
+	gobin := filepath.Join(tg.pwd(), "testdata", "bin1")
+	tg.creatingTemp(gobin)
+	tg.setenv("GOBIN", gobin)
+	tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata"))
+	tg.run("install", "go-cmd-test")
+	tg.wantExecutable("testdata/bin1/go-cmd-test"+exeSuffix, "go install go-cmd-test did not write to testdata/bin1/go-cmd-test")
+}
+
+// Issue 11065
+func TestInstallToCurrentDirectoryCreatesExecutable(t *testing.T) {
+	tg := testgo(t)
+	defer tg.cleanup()
+	pkg := filepath.Join(tg.pwd(), "testdata", "src", "go-cmd-test")
+	tg.creatingTemp(filepath.Join(pkg, "go-cmd-test"+exeSuffix))
+	tg.setenv("GOBIN", pkg)
+	tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata"))
+	tg.cd(pkg)
+	tg.run("install")
+	tg.wantExecutable("go-cmd-test"+exeSuffix, "go install did not write to current directory")
+}
+
+// Without $GOBIN set, installing a program outside $GOPATH should fail
+// (there is nowhere to install it).
+func TestInstallWithoutDestinationFails(t *testing.T) {
+	tg := testgo(t)
+	defer tg.cleanup()
+	tg.runFail("install", "testdata/src/go-cmd-test/helloworld.go")
+	tg.grepStderr("no install location for .go files listed on command line", "wrong error")
+}
+
+// With $GOBIN set, should install there.
+func TestInstallToGOBINCommandLinePackage(t *testing.T) {
+	tg := testgo(t)
+	defer tg.cleanup()
+	gobin := filepath.Join(tg.pwd(), "testdata", "bin1")
+	tg.creatingTemp(gobin)
+	tg.setenv("GOBIN", gobin)
+	tg.run("install", "testdata/src/go-cmd-test/helloworld.go")
+	tg.wantExecutable("testdata/bin1/helloworld"+exeSuffix, "go install testdata/src/go-cmd-test/helloworld.go did not write testdata/bin1/helloworld")
+}
+
+func TestGodocInstalls(t *testing.T) {
+	testenv.MustHaveExternalNetwork(t)
+
+	// godoc installs into GOBIN
+	tg := testgo(t)
+	defer tg.cleanup()
+	tg.parallel()
+	tg.tempDir("gobin")
+	tg.setenv("GOPATH", tg.path("."))
+	tg.setenv("GOBIN", tg.path("gobin"))
+	tg.run("get", "golang.org/x/tools/cmd/godoc")
+	tg.wantExecutable(tg.path("gobin/godoc"), "did not install godoc to $GOBIN")
+	tg.unsetenv("GOBIN")
+
+	// godoc installs into GOROOT
+	goroot := runtime.GOROOT()
+	tg.setenv("GOROOT", goroot)
+	tg.check(os.RemoveAll(filepath.Join(goroot, "bin", "godoc")))
+	tg.run("install", "golang.org/x/tools/cmd/godoc")
+	tg.wantExecutable(filepath.Join(goroot, "bin", "godoc"), "did not install godoc to $GOROOT/bin")
+}
+
+func TestGoGetNonPkg(t *testing.T) {
+	testenv.MustHaveExternalNetwork(t)
+
+	tg := testgo(t)
+	defer tg.cleanup()
+	tg.tempDir("gobin")
+	tg.setenv("GOPATH", tg.path("."))
+	tg.setenv("GOBIN", tg.path("gobin"))
+	tg.runFail("get", "-d", "golang.org/x/tools")
+	tg.grepStderr("golang.org/x/tools: no buildable Go source files", "missing error")
+	tg.runFail("get", "-d", "-u", "golang.org/x/tools")
+	tg.grepStderr("golang.org/x/tools: no buildable Go source files", "missing error")
+	tg.runFail("get", "-d", "golang.org/x/tools")
+	tg.grepStderr("golang.org/x/tools: no buildable Go source files", "missing error")
+}
+
+func TestInstalls(t *testing.T) {
+	if testing.Short() {
+		t.Skip("don't install into GOROOT in short mode")
+	}
+
+	tg := testgo(t)
+	defer tg.cleanup()
+	tg.parallel()
+	tg.tempDir("gobin")
+	tg.setenv("GOPATH", tg.path("."))
+	goroot := runtime.GOROOT()
+	tg.setenv("GOROOT", goroot)
+
+	// cmd/fix installs into tool
+	tg.run("env", "GOOS")
+	goos := strings.TrimSpace(tg.getStdout())
+	tg.setenv("GOOS", goos)
+	tg.run("env", "GOARCH")
+	goarch := strings.TrimSpace(tg.getStdout())
+	tg.setenv("GOARCH", goarch)
+	fixbin := filepath.Join(goroot, "pkg", "tool", goos+"_"+goarch, "fix") + exeSuffix
+	tg.must(os.RemoveAll(fixbin))
+	tg.run("install", "cmd/fix")
+	tg.wantExecutable(fixbin, "did not install cmd/fix to $GOROOT/pkg/tool")
+	tg.must(os.Remove(fixbin))
+	tg.setenv("GOBIN", tg.path("gobin"))
+	tg.run("install", "cmd/fix")
+	tg.wantExecutable(fixbin, "did not install cmd/fix to $GOROOT/pkg/tool with $GOBIN set")
+	tg.unsetenv("GOBIN")
+
+	// gopath program installs into GOBIN
+	tg.tempFile("src/progname/p.go", `package main; func main() {}`)
+	tg.setenv("GOBIN", tg.path("gobin"))
+	tg.run("install", "progname")
+	tg.unsetenv("GOBIN")
+	tg.wantExecutable(tg.path("gobin/progname")+exeSuffix, "did not install progname to $GOBIN/progname")
+
+	// gopath program installs into GOPATH/bin
+	tg.run("install", "progname")
+	tg.wantExecutable(tg.path("bin/progname")+exeSuffix, "did not install progname to $GOPATH/bin/progname")
+}
+
+func TestRejectRelativeDotPathInGOPATHCommandLinePackage(t *testing.T) {
+	tg := testgo(t)
+	defer tg.cleanup()
+	tg.setenv("GOPATH", ".")
+	tg.runFail("build", "testdata/src/go-cmd-test/helloworld.go")
+	tg.grepStderr("GOPATH entry is relative", "expected an error message rejecting relative GOPATH entries")
+}
+
+func TestRejectRelativePathsInGOPATH(t *testing.T) {
+	tg := testgo(t)
+	defer tg.cleanup()
+	sep := string(filepath.ListSeparator)
+	tg.setenv("GOPATH", sep+filepath.Join(tg.pwd(), "testdata")+sep+".")
+	tg.runFail("build", "go-cmd-test")
+	tg.grepStderr("GOPATH entry is relative", "expected an error message rejecting relative GOPATH entries")
+}
+
+func TestRejectRelativePathsInGOPATHCommandLinePackage(t *testing.T) {
+	tg := testgo(t)
+	defer tg.cleanup()
+	tg.setenv("GOPATH", "testdata")
+	tg.runFail("build", "testdata/src/go-cmd-test/helloworld.go")
+	tg.grepStderr("GOPATH entry is relative", "expected an error message rejecting relative GOPATH entries")
+}
+
+// Issue 4104.
+func TestGoTestWithPackageListedMultipleTimes(t *testing.T) {
+	tg := testgo(t)
+	defer tg.cleanup()
+	tg.parallel()
+	tg.run("test", "errors", "errors", "errors", "errors", "errors")
+	if strings.Index(strings.TrimSpace(tg.getStdout()), "\n") != -1 {
+		t.Error("go test errors errors errors errors errors tested the same package multiple times")
+	}
+}
+
+func TestGoListHasAConsistentOrder(t *testing.T) {
+	tg := testgo(t)
+	defer tg.cleanup()
+	tg.run("list", "std")
+	first := tg.getStdout()
+	tg.run("list", "std")
+	if first != tg.getStdout() {
+		t.Error("go list std ordering is inconsistent")
+	}
+}
+
+func TestGoListStdDoesNotIncludeCommands(t *testing.T) {
+	tg := testgo(t)
+	defer tg.cleanup()
+	tg.run("list", "std")
+	tg.grepStdoutNot("cmd/", "go list std shows commands")
+}
+
+func TestGoListCmdOnlyShowsCommands(t *testing.T) {
+	tg := testgo(t)
+	defer tg.cleanup()
+	tg.run("list", "cmd")
+	out := strings.TrimSpace(tg.getStdout())
+	for _, line := range strings.Split(out, "\n") {
+		if strings.Index(line, "cmd/") == -1 {
+			t.Error("go list cmd shows non-commands")
+			break
+		}
+	}
+}
+
+// Issue 4096. Validate the output of unsuccessful go install foo/quxx.
+func TestUnsuccessfulGoInstallShouldMentionMissingPackage(t *testing.T) {
+	tg := testgo(t)
+	defer tg.cleanup()
+	tg.runFail("install", "foo/quxx")
+	if tg.grepCountBoth(`cannot find package "foo/quxx" in any of`) != 1 {
+		t.Error(`go install foo/quxx expected error: .*cannot find package "foo/quxx" in any of`)
+	}
+}
+
+func TestGOROOTSearchFailureReporting(t *testing.T) {
+	tg := testgo(t)
+	defer tg.cleanup()
+	tg.runFail("install", "foo/quxx")
+	if tg.grepCountBoth(regexp.QuoteMeta(filepath.Join("foo", "quxx"))+` \(from \$GOROOT\)$`) != 1 {
+		t.Error(`go install foo/quxx expected error: .*foo/quxx (from $GOROOT)`)
+	}
+}
+
+func TestMultipleGOPATHEntriesReportedSeparately(t *testing.T) {
+	tg := testgo(t)
+	defer tg.cleanup()
+	sep := string(filepath.ListSeparator)
+	tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata", "a")+sep+filepath.Join(tg.pwd(), "testdata", "b"))
+	tg.runFail("install", "foo/quxx")
+	if tg.grepCountBoth(`testdata[/\\].[/\\]src[/\\]foo[/\\]quxx`) != 2 {
+		t.Error(`go install foo/quxx expected error: .*testdata/a/src/foo/quxx (from $GOPATH)\n.*testdata/b/src/foo/quxx`)
+	}
+}
+
+// Test (from $GOPATH) annotation is reported for the first GOPATH entry,
+func TestMentionGOPATHInFirstGOPATHEntry(t *testing.T) {
+	tg := testgo(t)
+	defer tg.cleanup()
+	sep := string(filepath.ListSeparator)
+	tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata", "a")+sep+filepath.Join(tg.pwd(), "testdata", "b"))
+	tg.runFail("install", "foo/quxx")
+	if tg.grepCountBoth(regexp.QuoteMeta(filepath.Join("testdata", "a", "src", "foo", "quxx"))+` \(from \$GOPATH\)$`) != 1 {
+		t.Error(`go install foo/quxx expected error: .*testdata/a/src/foo/quxx (from $GOPATH)`)
+	}
+}
+
+// but not on the second.
+func TestMentionGOPATHNotOnSecondEntry(t *testing.T) {
+	tg := testgo(t)
+	defer tg.cleanup()
+	sep := string(filepath.ListSeparator)
+	tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata", "a")+sep+filepath.Join(tg.pwd(), "testdata", "b"))
+	tg.runFail("install", "foo/quxx")
+	if tg.grepCountBoth(regexp.QuoteMeta(filepath.Join("testdata", "b", "src", "foo", "quxx"))+`$`) != 1 {
+		t.Error(`go install foo/quxx expected error: .*testdata/b/src/foo/quxx`)
+	}
+}
+
+// Test missing GOPATH is reported.
+func TestMissingGOPATHIsReported(t *testing.T) {
+	tg := testgo(t)
+	defer tg.cleanup()
+	tg.setenv("GOPATH", "")
+	tg.runFail("install", "foo/quxx")
+	if tg.grepCountBoth(`\(\$GOPATH not set\)$`) != 1 {
+		t.Error(`go install foo/quxx expected error: ($GOPATH not set)`)
+	}
+}
+
+// Issue 4186.  go get cannot be used to download packages to $GOROOT.
+// Test that without GOPATH set, go get should fail.
+func TestWithoutGOPATHGoGetFails(t *testing.T) {
+	testenv.MustHaveExternalNetwork(t)
+
+	tg := testgo(t)
+	defer tg.cleanup()
+	tg.parallel()
+	tg.tempDir("src")
+	tg.setenv("GOPATH", "")
+	tg.setenv("GOROOT", tg.path("."))
+	tg.runFail("get", "-d", "golang.org/x/codereview/cmd/hgpatch")
+}
+
+// Test that with GOPATH=$GOROOT, go get should fail.
+func TestWithGOPATHEqualsGOROOTGoGetFails(t *testing.T) {
+	testenv.MustHaveExternalNetwork(t)
+
+	tg := testgo(t)
+	defer tg.cleanup()
+	tg.parallel()
+	tg.tempDir("src")
+	tg.setenv("GOPATH", tg.path("."))
+	tg.setenv("GOROOT", tg.path("."))
+	tg.runFail("get", "-d", "golang.org/x/codereview/cmd/hgpatch")
+}
+
+func TestLdflagsArgumentsWithSpacesIssue3941(t *testing.T) {
+	tg := testgo(t)
+	defer tg.cleanup()
+	tg.parallel()
+	tg.tempFile("main.go", `package main
+		var extern string
+		func main() {
+			println(extern)
+		}`)
+	tg.run("run", "-ldflags", `-X main.extern "hello world"`, tg.path("main.go"))
+	tg.grepStderr("^hello world", `ldflags -X main.extern 'hello world' failed`)
+}
+
+func TestGoTestCpuprofileLeavesBinaryBehind(t *testing.T) {
+	tg := testgo(t)
+	defer tg.cleanup()
+	tg.makeTempdir()
+	tg.cd(tg.path("."))
+	tg.run("test", "-cpuprofile", "errors.prof", "errors")
+	tg.wantExecutable("errors.test"+exeSuffix, "go test -cpuprofile did not create errors.test")
+}
+
+func TestGoTestCpuprofileDashOControlsBinaryLocation(t *testing.T) {
+	tg := testgo(t)
+	defer tg.cleanup()
+	tg.makeTempdir()
+	tg.cd(tg.path("."))
+	tg.run("test", "-cpuprofile", "errors.prof", "-o", "myerrors.test"+exeSuffix, "errors")
+	tg.wantExecutable("myerrors.test"+exeSuffix, "go test -cpuprofile -o myerrors.test did not create myerrors.test")
+}
+
+func TestGoTestDashCDashOControlsBinaryLocation(t *testing.T) {
+	tg := testgo(t)
+	defer tg.cleanup()
+	tg.parallel()
+	tg.makeTempdir()
+	tg.run("test", "-c", "-o", tg.path("myerrors.test"+exeSuffix), "errors")
+	tg.wantExecutable(tg.path("myerrors.test"+exeSuffix), "go test -c -o myerrors.test did not create myerrors.test")
+}
+
+func TestGoTestDashOWritesBinary(t *testing.T) {
+	tg := testgo(t)
+	defer tg.cleanup()
+	tg.parallel()
+	tg.makeTempdir()
+	tg.run("test", "-o", tg.path("myerrors.test"+exeSuffix), "errors")
+	tg.wantExecutable(tg.path("myerrors.test"+exeSuffix), "go test -o myerrors.test did not create myerrors.test")
+}
+
+// Issue 4568.
+func TestSymlinksDoNotConfuseGoList(t *testing.T) {
+	switch runtime.GOOS {
+	case "plan9", "windows":
+		t.Skipf("skipping symlink test on %s", runtime.GOOS)
+	}
+
+	tg := testgo(t)
+	defer tg.cleanup()
+	tg.tempDir("src")
+	tg.must(os.Symlink(tg.path("."), tg.path("src/dir1")))
+	tg.tempFile("src/dir1/p.go", "package p")
+	tg.setenv("GOPATH", tg.path("."))
+	tg.cd(tg.path("src"))
+	tg.run("list", "-f", "{{.Root}}", "dir1")
+	if strings.TrimSpace(tg.getStdout()) != tg.path(".") {
+		t.Error("confused by symlinks")
+	}
+}
+
+// Issue 4515.
+func TestInstallWithTags(t *testing.T) {
+	tg := testgo(t)
+	defer tg.cleanup()
+	tg.parallel()
+	tg.tempDir("bin")
+	tg.tempFile("src/example/a/main.go", `package main
+		func main() {}`)
+	tg.tempFile("src/example/b/main.go", `// +build mytag
+
+		package main
+		func main() {}`)
+	tg.setenv("GOPATH", tg.path("."))
+	tg.run("install", "-tags", "mytag", "example/a", "example/b")
+	tg.wantExecutable(tg.path("bin/a"+exeSuffix), "go install example/a example/b did not install binaries")
+	tg.wantExecutable(tg.path("bin/b"+exeSuffix), "go install example/a example/b did not install binaries")
+	tg.must(os.Remove(tg.path("bin/a" + exeSuffix)))
+	tg.must(os.Remove(tg.path("bin/b" + exeSuffix)))
+	tg.run("install", "-tags", "mytag", "example/...")
+	tg.wantExecutable(tg.path("bin/a"+exeSuffix), "go install example/... did not install binaries")
+	tg.wantExecutable(tg.path("bin/b"+exeSuffix), "go install example/... did not install binaries")
+	tg.run("list", "-tags", "mytag", "example/b...")
+	if strings.TrimSpace(tg.getStdout()) != "example/b" {
+		t.Error("go list example/b did not find example/b")
+	}
+}
+
+// Issue 4773
+func TestCaseCollisions(t *testing.T) {
+	tg := testgo(t)
+	defer tg.cleanup()
+	tg.parallel()
+	tg.tempDir("src/example/a/pkg")
+	tg.tempDir("src/example/a/Pkg")
+	tg.tempDir("src/example/b")
+	tg.setenv("GOPATH", tg.path("."))
+	tg.tempFile("src/example/a/a.go", `package p
+		import (
+			_ "example/a/pkg"
+			_ "example/a/Pkg"
+		)`)
+	tg.tempFile("src/example/a/pkg/pkg.go", `package pkg`)
+	tg.tempFile("src/example/a/Pkg/pkg.go", `package pkg`)
+	tg.runFail("list", "example/a")
+	tg.grepStderr("case-insensitive import collision", "go list example/a did not report import collision")
+	tg.tempFile("src/example/b/file.go", `package b`)
+	tg.tempFile("src/example/b/FILE.go", `package b`)
+	f, err := os.Open(tg.path("src/example/b"))
+	tg.must(err)
+	names, err := f.Readdirnames(0)
+	tg.must(err)
+	tg.check(f.Close())
+	args := []string{"list"}
+	if len(names) == 2 {
+		// case-sensitive file system, let directory read find both files
+		args = append(args, "example/b")
+	} else {
+		// case-insensitive file system, list files explicitly on command line
+		args = append(args, tg.path("src/example/b/file.go"), tg.path("src/example/b/FILE.go"))
+	}
+	tg.runFail(args...)
+	tg.grepStderr("case-insensitive file name collision", "go list example/b did not report file name collision")
+}
+
+// Issue 8181.
+func TestGoGetDashTIssue8181(t *testing.T) {
+	if testing.Short() {
+		t.Skip("skipping test that uses network in short mode")
+	}
+
+	tg := testgo(t)
+	defer tg.cleanup()
+	tg.parallel()
+	tg.makeTempdir()
+	tg.setenv("GOPATH", tg.path("."))
+	tg.run("get", "-v", "-t", "github.com/rsc/go-get-issue-8181/a", "github.com/rsc/go-get-issue-8181/b")
+	tg.run("list", "...")
+	tg.grepStdout("x/build/cmd/cl", "missing expected x/build/cmd/cl")
+}
+
+func TestIssue11307(t *testing.T) {
+	// go get -u was not working except in checkout directory
+	if testing.Short() {
+		t.Skip("skipping test that uses network in short mode")
+	}
+
+	tg := testgo(t)
+	defer tg.cleanup()
+	tg.parallel()
+	tg.makeTempdir()
+	tg.setenv("GOPATH", tg.path("."))
+	tg.run("get", "github.com/rsc/go-get-issue-11307")
+	tg.run("get", "-u", "github.com/rsc/go-get-issue-11307") // was failing
+}
+
+func TestShadowingLogic(t *testing.T) {
+	tg := testgo(t)
+	defer tg.cleanup()
+	pwd := tg.pwd()
+	sep := string(filepath.ListSeparator)
+	tg.setenv("GOPATH", filepath.Join(pwd, "testdata", "shadow", "root1")+sep+filepath.Join(pwd, "testdata", "shadow", "root2"))
+
+	// The math in root1 is not "math" because the standard math is.
+	tg.run("list", "-f", "({{.ImportPath}}) ({{.ConflictDir}})", "./testdata/shadow/root1/src/math")
+	pwdForwardSlash := strings.Replace(pwd, string(os.PathSeparator), "/", -1)
+	if !strings.HasPrefix(pwdForwardSlash, "/") {
+		pwdForwardSlash = "/" + pwdForwardSlash
+	}
+	// The output will have makeImportValid applies, but we only
+	// bother to deal with characters we might reasonably see.
+	pwdForwardSlash = strings.Replace(pwdForwardSlash, ":", "_", -1)
+	want := "(_" + pwdForwardSlash + "/testdata/shadow/root1/src/math) (" + filepath.Join(runtime.GOROOT(), "src", "math") + ")"
+	if strings.TrimSpace(tg.getStdout()) != want {
+		t.Error("shadowed math is not shadowed; looking for", want)
+	}
+
+	// The foo in root1 is "foo".
+	tg.run("list", "-f", "({{.ImportPath}}) ({{.ConflictDir}})", "./testdata/shadow/root1/src/foo")
+	if strings.TrimSpace(tg.getStdout()) != "(foo) ()" {
+		t.Error("unshadowed foo is shadowed")
+	}
+
+	// The foo in root2 is not "foo" because the foo in root1 got there first.
+	tg.run("list", "-f", "({{.ImportPath}}) ({{.ConflictDir}})", "./testdata/shadow/root2/src/foo")
+	want = "(_" + pwdForwardSlash + "/testdata/shadow/root2/src/foo) (" + filepath.Join(pwd, "testdata", "shadow", "root1", "src", "foo") + ")"
+	if strings.TrimSpace(tg.getStdout()) != want {
+		t.Error("shadowed foo is not shadowed; looking for", want)
+	}
+
+	// The error for go install should mention the conflicting directory.
+	tg.runFail("install", "./testdata/shadow/root2/src/foo")
+	want = "go install: no install location for " + filepath.Join(pwd, "testdata", "shadow", "root2", "src", "foo") + ": hidden by " + filepath.Join(pwd, "testdata", "shadow", "root1", "src", "foo")
+	if strings.TrimSpace(tg.getStderr()) != want {
+		t.Error("wrong shadowed install error; looking for", want)
+	}
+}
+
+// Only succeeds if source order is preserved.
+func TestSourceFileNameOrderPreserved(t *testing.T) {
+	tg := testgo(t)
+	defer tg.cleanup()
+	tg.run("test", "testdata/example1_test.go", "testdata/example2_test.go")
+}
+
+// Check that coverage analysis works at all.
+// Don't worry about the exact numbers but require not 0.0%.
+func checkCoverage(tg *testgoData, data string) {
+	if regexp.MustCompile(`[^0-9]0\.0%`).MatchString(data) {
+		tg.t.Error("some coverage results are 0.0%")
+	}
+	tg.t.Log(data)
+}
+
+func TestCoverageRuns(t *testing.T) {
+	if testing.Short() {
+		t.Skip("don't build libraries for coverage in short mode")
+	}
+	tg := testgo(t)
+	defer tg.cleanup()
+	tg.run("test", "-short", "-coverpkg=strings", "strings", "regexp")
+	data := tg.getStdout() + tg.getStderr()
+	tg.run("test", "-short", "-cover", "strings", "math", "regexp")
+	data += tg.getStdout() + tg.getStderr()
+	checkCoverage(tg, data)
+}
+
+// Check that coverage analysis uses set mode.
+func TestCoverageUsesSetMode(t *testing.T) {
+	if testing.Short() {
+		t.Skip("don't build libraries for coverage in short mode")
+	}
+	tg := testgo(t)
+	defer tg.cleanup()
+	tg.creatingTemp("testdata/cover.out")
+	tg.run("test", "-short", "-cover", "encoding/binary", "-coverprofile=testdata/cover.out")
+	data := tg.getStdout() + tg.getStderr()
+	if out, err := ioutil.ReadFile("testdata/cover.out"); err != nil {
+		t.Error(err)
+	} else {
+		if !bytes.Contains(out, []byte("mode: set")) {
+			t.Error("missing mode: set")
+		}
+	}
+	checkCoverage(tg, data)
+}
+
+func TestCoverageUsesAtomicModeForRace(t *testing.T) {
+	if testing.Short() {
+		t.Skip("don't build libraries for coverage in short mode")
+	}
+	if !canRace {
+		t.Skip("skipping because race detector not supported")
+	}
+
+	tg := testgo(t)
+	defer tg.cleanup()
+	tg.creatingTemp("testdata/cover.out")
+	tg.run("test", "-short", "-race", "-cover", "encoding/binary", "-coverprofile=testdata/cover.out")
+	data := tg.getStdout() + tg.getStderr()
+	if out, err := ioutil.ReadFile("testdata/cover.out"); err != nil {
+		t.Error(err)
+	} else {
+		if !bytes.Contains(out, []byte("mode: atomic")) {
+			t.Error("missing mode: atomic")
+		}
+	}
+	checkCoverage(tg, data)
+}
+
+func TestCoverageUsesActualSettingToOverrideEvenForRace(t *testing.T) {
+	if testing.Short() {
+		t.Skip("don't build libraries for coverage in short mode")
+	}
+	if !canRace {
+		t.Skip("skipping because race detector not supported")
+	}
+
+	tg := testgo(t)
+	defer tg.cleanup()
+	tg.creatingTemp("testdata/cover.out")
+	tg.run("test", "-short", "-race", "-cover", "encoding/binary", "-covermode=count", "-coverprofile=testdata/cover.out")
+	data := tg.getStdout() + tg.getStderr()
+	if out, err := ioutil.ReadFile("testdata/cover.out"); err != nil {
+		t.Error(err)
+	} else {
+		if !bytes.Contains(out, []byte("mode: count")) {
+			t.Error("missing mode: count")
+		}
+	}
+	checkCoverage(tg, data)
+}
+
+func TestCoverageWithCgo(t *testing.T) {
+	if !canCgo {
+		t.Skip("skipping because cgo not enabled")
+	}
+
+	tg := testgo(t)
+	defer tg.cleanup()
+	tg.run("test", "-short", "-cover", "./testdata/cgocover")
+	data := tg.getStdout() + tg.getStderr()
+	checkCoverage(tg, data)
+}
+
+func TestCgoDependsOnSyscall(t *testing.T) {
+	if testing.Short() {
+		t.Skip("skipping test that removes $GOROOT/pkg/*_race in short mode")
+	}
+	if !canCgo {
+		t.Skip("skipping because cgo not enabled")
+	}
+	if !canRace {
+		t.Skip("skipping because race detector not supported")
+	}
+
+	tg := testgo(t)
+	defer tg.cleanup()
+	files, err := filepath.Glob(filepath.Join(runtime.GOROOT(), "pkg", "*_race"))
+	tg.must(err)
+	for _, file := range files {
+		tg.check(os.RemoveAll(file))
+	}
+	tg.tempFile("src/foo/foo.go", `
+		package foo
+		//#include <stdio.h>
+		import "C"`)
+	tg.setenv("GOPATH", tg.path("."))
+	tg.run("build", "-race", "foo")
+}
+
+func TestCgoShowsFullPathNames(t *testing.T) {
+	if !canCgo {
+		t.Skip("skipping because cgo not enabled")
+	}
+
+	tg := testgo(t)
+	defer tg.cleanup()
+	tg.parallel()
+	tg.tempFile("src/x/y/dirname/foo.go", `
+		package foo
+		import "C"
+		func f() {`)
+	tg.setenv("GOPATH", tg.path("."))
+	tg.runFail("build", "x/y/dirname")
+	tg.grepBoth("x/y/dirname", "error did not use full path")
+}
+
+func TestCgoHandlesWlORIGIN(t *testing.T) {
+	if !canCgo {
+		t.Skip("skipping because cgo not enabled")
+	}
+
+	tg := testgo(t)
+	defer tg.cleanup()
+	tg.parallel()
+	tg.tempFile("src/origin/origin.go", `package origin
+		// #cgo !darwin LDFLAGS: -Wl,-rpath -Wl,$ORIGIN
+		// void f(void) {}
+		import "C"
+		func f() { C.f() }`)
+	tg.setenv("GOPATH", tg.path("."))
+	tg.run("build", "origin")
+}
+
+// "go test -c -test.bench=XXX errors" should not hang
+func TestIssue6480(t *testing.T) {
+	tg := testgo(t)
+	defer tg.cleanup()
+	tg.makeTempdir()
+	tg.cd(tg.path("."))
+	tg.run("test", "-c", "-test.bench=XXX", "errors")
+}
+
+// cmd/cgo: undefined reference when linking a C-library using gccgo
+func TestIssue7573(t *testing.T) {
+	if _, err := exec.LookPath("gccgo"); err != nil {
+		t.Skip("skipping because no gccgo compiler found")
+	}
+
+	tg := testgo(t)
+	defer tg.cleanup()
+	tg.parallel()
+	tg.tempFile("src/cgoref/cgoref.go", `
+package main
+// #cgo LDFLAGS: -L alibpath -lalib
+// void f(void) {}
+import "C"
+
+func main() { C.f() }`)
+	tg.setenv("GOPATH", tg.path("."))
+	tg.run("build", "-n", "-compiler", "gccgo", "cgoref")
+	tg.grepStderr(`gccgo.*\-L alibpath \-lalib`, `no Go-inline "#cgo LDFLAGS:" ("-L alibpath -lalib") passed to gccgo linking stage`)
+}
+
+func TestListTemplateCanUseContextFunction(t *testing.T) {
+	tg := testgo(t)
+	defer tg.cleanup()
+	tg.run("list", "-f", "GOARCH: {{context.GOARCH}}")
+}
+
+// cmd/go: "go test" should fail if package does not build
+func TestIssue7108(t *testing.T) {
+	tg := testgo(t)
+	defer tg.cleanup()
+	tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata"))
+	tg.runFail("test", "notest")
+}
+
+// cmd/go: go test -a foo does not rebuild regexp.
+func TestIssue6844(t *testing.T) {
+	if testing.Short() {
+		t.Skip("don't rebuild the standard libary in short mode")
+	}
+
+	tg := testgo(t)
+	defer tg.cleanup()
+	tg.creatingTemp("deps.test" + exeSuffix)
+	tg.run("test", "-x", "-a", "-c", "testdata/dep_test.go")
+	tg.grepStderr("regexp", "go test -x -a -c testdata/dep-test.go did not rebuild regexp")
+}
+
+func TestBuildDashIInstallsDependencies(t *testing.T) {
+	tg := testgo(t)
+	defer tg.cleanup()
+	tg.parallel()
+	tg.tempFile("src/x/y/foo/foo.go", `package foo
+		func F() {}`)
+	tg.tempFile("src/x/y/bar/bar.go", `package bar
+		import "x/y/foo"
+		func F() { foo.F() }`)
+	tg.setenv("GOPATH", tg.path("."))
+
+	checkbar := func(desc string) {
+		tg.sleep()
+		tg.must(os.Chtimes(tg.path("src/x/y/foo/foo.go"), time.Now(), time.Now()))
+		tg.sleep()
+		tg.run("build", "-v", "-i", "x/y/bar")
+		tg.grepBoth("x/y/foo", "first build -i "+desc+" did not build x/y/foo")
+		tg.run("build", "-v", "-i", "x/y/bar")
+		tg.grepBothNot("x/y/foo", "second build -i "+desc+" built x/y/foo")
+	}
+	checkbar("pkg")
+	tg.creatingTemp("bar" + exeSuffix)
+	tg.tempFile("src/x/y/bar/bar.go", `package main
+		import "x/y/foo"
+		func main() { foo.F() }`)
+	checkbar("cmd")
+}
+
+func TestGoBuildInTestOnlyDirectoryFailsWithAGoodError(t *testing.T) {
+	tg := testgo(t)
+	defer tg.cleanup()
+	tg.runFail("build", "./testdata/testonly")
+	tg.grepStderr("no buildable Go", "go build ./testdata/testonly produced unexpected error")
+}
+
+func TestGoTestDetectsTestOnlyImportCycles(t *testing.T) {
+	tg := testgo(t)
+	defer tg.cleanup()
+	tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata"))
+	tg.runFail("test", "-c", "testcycle/p3")
+	tg.grepStderr("import cycle not allowed in test", "go test testcycle/p3 produced unexpected error")
+
+	tg.runFail("test", "-c", "testcycle/q1")
+	tg.grepStderr("import cycle not allowed in test", "go test testcycle/q1 produced unexpected error")
+}
+
+func TestGoTestFooTestWorks(t *testing.T) {
+	tg := testgo(t)
+	defer tg.cleanup()
+	tg.run("test", "testdata/standalone_test.go")
+}
+
+func TestGoTestXtestonlyWorks(t *testing.T) {
+	tg := testgo(t)
+	defer tg.cleanup()
+	tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata"))
+	tg.run("clean", "-i", "xtestonly")
+	tg.run("test", "xtestonly")
+}
+
+func TestGoTestBuildsAnXtestContainingOnlyNonRunnableExamples(t *testing.T) {
+	tg := testgo(t)
+	defer tg.cleanup()
+	tg.run("test", "-v", "./testdata/norunexample")
+	tg.grepStdout("File with non-runnable example was built.", "file with non-runnable example was not built")
+}
+
+func TestGoGenerateHandlesSimpleCommand(t *testing.T) {
+	if runtime.GOOS == "windows" {
+		t.Skip("skipping because windows has no echo command")
+	}
+
+	tg := testgo(t)
+	defer tg.cleanup()
+	tg.run("generate", "./testdata/generate/test1.go")
+	tg.grepStdout("Success", "go generate ./testdata/generate/test1.go generated wrong output")
+}
+
+func TestGoGenerateHandlesCommandAlias(t *testing.T) {
+	if runtime.GOOS == "windows" {
+		t.Skip("skipping because windows has no echo command")
+	}
+
+	tg := testgo(t)
+	defer tg.cleanup()
+	tg.run("generate", "./testdata/generate/test2.go")
+	tg.grepStdout("Now is the time for all good men", "go generate ./testdata/generate/test2.go generated wrong output")
+}
+
+func TestGoGenerateVariableSubstitution(t *testing.T) {
+	if runtime.GOOS == "windows" {
+		t.Skip("skipping because windows has no echo command")
+	}
+
+	tg := testgo(t)
+	defer tg.cleanup()
+	tg.run("generate", "./testdata/generate/test3.go")
+	tg.grepStdout(runtime.GOARCH+" test3.go:7 pabc xyzp/test3.go/123", "go generate ./testdata/generate/test3.go generated wrong output")
+}
+
+func TestGoGenerateRunFlag(t *testing.T) {
+	if runtime.GOOS == "windows" {
+		t.Skip("skipping because windows has no echo command")
+	}
+
+	tg := testgo(t)
+	defer tg.cleanup()
+	tg.run("generate", "-run", "y.s", "./testdata/generate/test4.go")
+	tg.grepStdout("yes", "go generate -run yes ./testdata/generate/test4.go did not select yes")
+	tg.grepStdoutNot("no", "go generate -run yes ./testdata/generate/test4.go selected no")
+}
+
+func TestGoGetCustomDomainWildcard(t *testing.T) {
+	testenv.MustHaveExternalNetwork(t)
+
+	tg := testgo(t)
+	defer tg.cleanup()
+	tg.makeTempdir()
+	tg.setenv("GOPATH", tg.path("."))
+	tg.run("get", "-u", "rsc.io/pdf/...")
+	tg.wantExecutable(tg.path("bin/pdfpasswd"+exeSuffix), "did not build rsc/io/pdf/pdfpasswd")
+}
+
+func TestGoGetInternalWildcard(t *testing.T) {
+	testenv.MustHaveExternalNetwork(t)
+
+	tg := testgo(t)
+	defer tg.cleanup()
+	tg.makeTempdir()
+	tg.setenv("GOPATH", tg.path("."))
+	// used to fail with errors about internal packages
+	tg.run("get", "github.com/rsc/go-get-issue-11960/...")
+}
+
+func TestGoVetWithExternalTests(t *testing.T) {
+	testenv.MustHaveExternalNetwork(t)
+
+	tg := testgo(t)
+	defer tg.cleanup()
+	tg.makeTempdir()
+	tg.setenv("GOPATH", tg.path("."))
+	tg.run("get", "golang.org/x/tools/cmd/vet")
+	tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata"))
+	tg.runFail("vet", "vetpkg")
+	tg.grepBoth("missing argument for Printf", "go vet vetpkg did not find missing argument for Printf")
+}
+
+func TestGoVetWithTags(t *testing.T) {
+	testenv.MustHaveExternalNetwork(t)
+
+	tg := testgo(t)
+	defer tg.cleanup()
+	tg.makeTempdir()
+	tg.setenv("GOPATH", tg.path("."))
+	tg.run("get", "golang.org/x/tools/cmd/vet")
+	tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata"))
+	tg.runFail("vet", "-tags", "tagtest", "vetpkg")
+	tg.grepBoth(`c\.go.*wrong number of args for format`, "go get vetpkg did not run scan tagged file")
+}
+
+// Issue 9767.
+func TestGoGetRscIoToolstash(t *testing.T) {
+	testenv.MustHaveExternalNetwork(t)
+
+	tg := testgo(t)
+	defer tg.cleanup()
+	tg.tempDir("src/rsc.io")
+	tg.setenv("GOPATH", tg.path("."))
+	tg.cd(tg.path("src/rsc.io"))
+	tg.run("get", "./toolstash")
+}
+
+// Test that you can not import a main package.
+func TestIssue4210(t *testing.T) {
+	tg := testgo(t)
+	defer tg.cleanup()
+	tg.tempFile("src/x/main.go", `package main
+		var X int
+		func main() {}`)
+	tg.tempFile("src/y/main.go", `package main
+		import "fmt"
+		import xmain "x"
+		func main() {
+			fmt.Println(xmain.X)
+		}`)
+	tg.setenv("GOPATH", tg.path("."))
+	tg.runFail("build", "y")
+	tg.grepBoth("is a program", `did not find expected error message ("is a program")`)
+}
+
+func TestGoGetInsecure(t *testing.T) {
+	testenv.MustHaveExternalNetwork(t)
+
+	tg := testgo(t)
+	defer tg.cleanup()
+	tg.makeTempdir()
+	tg.setenv("GOPATH", tg.path("."))
+	tg.failSSH()
+
+	const repo = "wh3rd.net/git.git"
+
+	// Try go get -d of HTTP-only repo (should fail).
+	tg.runFail("get", "-d", repo)
+
+	// Try again with -insecure (should succeed).
+	tg.run("get", "-d", "-insecure", repo)
+
+	// Try updating without -insecure (should fail).
+	tg.runFail("get", "-d", "-u", "-f", repo)
+}
+
+func TestGoGetUpdateInsecure(t *testing.T) {
+	testenv.MustHaveExternalNetwork(t)
+
+	tg := testgo(t)
+	defer tg.cleanup()
+	tg.makeTempdir()
+	tg.setenv("GOPATH", tg.path("."))
+
+	const repo = "github.com/golang/example"
+
+	// Clone the repo via HTTP manually.
+	cmd := exec.Command("git", "clone", "-q", "http://"+repo, tg.path("src/"+repo))
+	if out, err := cmd.CombinedOutput(); err != nil {
+		t.Fatalf("cloning %v repo: %v\n%s", repo, err, out)
+	}
+
+	// Update without -insecure should fail.
+	// Update with -insecure should succeed.
+	// We need -f to ignore import comments.
+	const pkg = repo + "/hello"
+	tg.runFail("get", "-d", "-u", "-f", pkg)
+	tg.run("get", "-d", "-u", "-f", "-insecure", pkg)
+}
+
+func TestGoGetInsecureCustomDomain(t *testing.T) {
+	testenv.MustHaveExternalNetwork(t)
+
+	tg := testgo(t)
+	defer tg.cleanup()
+	tg.makeTempdir()
+	tg.setenv("GOPATH", tg.path("."))
+
+	const repo = "wh3rd.net/repo"
+	tg.runFail("get", "-d", repo)
+	tg.run("get", "-d", "-insecure", repo)
+}
+
+func TestIssue10193(t *testing.T) {
+	testenv.MustHaveExternalNetwork(t)
+
+	tg := testgo(t)
+	defer tg.cleanup()
+	tg.parallel()
+	tg.tempDir("src")
+	tg.setenv("GOPATH", tg.path("."))
+	tg.runFail("get", "code.google.com/p/rsc/pdf")
+	tg.grepStderr("is shutting down", "missed warning about code.google.com")
+}
+
+func TestGoRunDirs(t *testing.T) {
+	tg := testgo(t)
+	defer tg.cleanup()
+	tg.cd("testdata/rundir")
+	tg.runFail("run", "x.go", "sub/sub.go")
+	tg.grepStderr("named files must all be in one directory; have ./ and sub/", "wrong output")
+	tg.runFail("run", "sub/sub.go", "x.go")
+	tg.grepStderr("named files must all be in one directory; have sub/ and ./", "wrong output")
+}
+
+func TestGoInstallPkgdir(t *testing.T) {
+	tg := testgo(t)
+	defer tg.cleanup()
+	tg.makeTempdir()
+	pkg := tg.path(".")
+	tg.run("install", "-pkgdir", pkg, "errors")
+	_, err := os.Stat(filepath.Join(pkg, "errors.a"))
+	tg.must(err)
+	_, err = os.Stat(filepath.Join(pkg, "runtime.a"))
+	tg.must(err)
+}
+
+func TestGoTestRaceInstallCgo(t *testing.T) {
+	switch sys := runtime.GOOS + "/" + runtime.GOARCH; sys {
+	case "darwin/amd64", "freebsd/amd64", "linux/amd64", "windows/amd64":
+		// ok
+	default:
+		t.Skip("no race detector on %s", sys)
+	}
+
+	if !build.Default.CgoEnabled {
+		t.Skip("no race detector without cgo")
+	}
+
+	// golang.org/issue/10500.
+	// This used to install a race-enabled cgo.
+	tg := testgo(t)
+	defer tg.cleanup()
+	tg.run("tool", "-n", "cgo")
+	cgo := strings.TrimSpace(tg.stdout.String())
+	old, err := os.Stat(cgo)
+	tg.must(err)
+	tg.run("test", "-race", "-i", "runtime/race")
+	new, err := os.Stat(cgo)
+	tg.must(err)
+	if new.ModTime() != old.ModTime() {
+		t.Fatalf("go test -i runtime/race reinstalled cmd/cgo")
+	}
+}
+
+func TestGoTestImportErrorStack(t *testing.T) {
+	const out = `package testdep/p1 (test)
+	imports testdep/p2
+	imports testdep/p3: no buildable Go source files`
+
+	tg := testgo(t)
+	defer tg.cleanup()
+	tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata"))
+	tg.runFail("test", "testdep/p1")
+	if !strings.Contains(tg.stderr.String(), out) {
+		t.Fatal("did not give full import stack:\n\n%s", tg.stderr.String())
+	}
+}
+
+func TestGoGetUpdate(t *testing.T) {
+	// golang.org/issue/9224.
+	// The recursive updating was trying to walk to
+	// former dependencies, not current ones.
+
+	testenv.MustHaveExternalNetwork(t)
+
+	tg := testgo(t)
+	defer tg.cleanup()
+	tg.makeTempdir()
+	tg.setenv("GOPATH", tg.path("."))
+
+	rewind := func() {
+		tg.run("get", "github.com/rsc/go-get-issue-9224-cmd")
+		cmd := exec.Command("git", "reset", "--hard", "HEAD~")
+		cmd.Dir = tg.path("src/github.com/rsc/go-get-issue-9224-lib")
+		out, err := cmd.CombinedOutput()
+		if err != nil {
+			t.Fatalf("git: %v\n%s", err, out)
+		}
+	}
+
+	rewind()
+	tg.run("get", "-u", "github.com/rsc/go-get-issue-9224-cmd")
+
+	// Again with -d -u.
+	rewind()
+	tg.run("get", "-d", "-u", "github.com/rsc/go-get-issue-9224-cmd")
+}
+
+func TestGoGetDomainRoot(t *testing.T) {
+	// golang.org/issue/9357.
+	// go get foo.io (not foo.io/subdir) was not working consistently.
+
+	testenv.MustHaveExternalNetwork(t)
+
+	tg := testgo(t)
+	defer tg.cleanup()
+	tg.makeTempdir()
+	tg.setenv("GOPATH", tg.path("."))
+
+	// go-get-issue-9357.appspot.com is running
+	// the code at github.com/rsc/go-get-issue-9357,
+	// a trivial Go on App Engine app that serves a
+	// <meta> tag for the domain root.
+	tg.run("get", "-d", "go-get-issue-9357.appspot.com")
+	tg.run("get", "go-get-issue-9357.appspot.com")
+	tg.run("get", "-u", "go-get-issue-9357.appspot.com")
+
+	tg.must(os.RemoveAll(tg.path("src/go-get-issue-9357.appspot.com")))
+	tg.run("get", "go-get-issue-9357.appspot.com")
+
+	tg.must(os.RemoveAll(tg.path("src/go-get-issue-9357.appspot.com")))
+	tg.run("get", "-u", "go-get-issue-9357.appspot.com")
+}
+
+func TestGoInstallShadowedGOPATH(t *testing.T) {
+	// golang.org/issue/3652.
+	// go get foo.io (not foo.io/subdir) was not working consistently.
+
+	testenv.MustHaveExternalNetwork(t)
+
+	tg := testgo(t)
+	defer tg.cleanup()
+	tg.makeTempdir()
+	tg.setenv("GOPATH", tg.path("gopath1")+string(filepath.ListSeparator)+tg.path("gopath2"))
+
+	tg.tempDir("gopath1/src/test")
+	tg.tempDir("gopath2/src/test")
+	tg.tempFile("gopath2/src/test/main.go", "package main\nfunc main(){}\n")
+
+	tg.cd(tg.path("gopath2/src/test"))
+	tg.runFail("install")
+	tg.grepStderr("no install location for.*gopath2.src.test: hidden by .*gopath1.src.test", "missing error")
+}
+
+func TestIssue11709(t *testing.T) {
+	tg := testgo(t)
+	defer tg.cleanup()
+	tg.tempFile("run.go", `
+		package main
+		import "os"
+		func main() {
+			if os.Getenv("TERM") != "" {
+				os.Exit(1)
+			}
+		}`)
+	tg.unsetenv("TERM")
+	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()
+
+	tg.makeTempdir()
+	tg.cd(tg.path("."))
+
+	nonExeSuffix := ".exe"
+	if exeSuffix == ".exe" {
+		nonExeSuffix = ""
+	}
+
+	tg.tempFile("x.go", "package main\nfunc main(){}\n")
+	tg.run("build", "x.go")
+	tg.wantExecutable("x"+exeSuffix, "go build x.go did not write x"+exeSuffix)
+	tg.must(os.Remove(tg.path("x" + exeSuffix)))
+	tg.mustNotExist("x" + nonExeSuffix)
+
+	tg.run("build", "-o", "myprog", "x.go")
+	tg.mustNotExist("x")
+	tg.mustNotExist("x.exe")
+	tg.wantExecutable("myprog", "go build -o myprog x.go did not write myprog")
+	tg.mustNotExist("myprog.exe")
+
+	tg.tempFile("p.go", "package p\n")
+	tg.run("build", "p.go")
+	tg.mustNotExist("p")
+	tg.mustNotExist("p.a")
+	tg.mustNotExist("p.o")
+	tg.mustNotExist("p.exe")
+
+	tg.run("build", "-o", "p.a", "p.go")
+	tg.wantArchive("p.a")
+
+	tg.run("build", "cmd/gofmt")
+	tg.wantExecutable("gofmt"+exeSuffix, "go build cmd/gofmt did not write gofmt"+exeSuffix)
+	tg.must(os.Remove(tg.path("gofmt" + exeSuffix)))
+	tg.mustNotExist("gofmt" + nonExeSuffix)
+
+	tg.run("build", "-o", "mygofmt", "cmd/gofmt")
+	tg.wantExecutable("mygofmt", "go build -o mygofmt cmd/gofmt did not write mygofmt")
+	tg.mustNotExist("mygofmt.exe")
+	tg.mustNotExist("gofmt")
+	tg.mustNotExist("gofmt.exe")
+
+	tg.run("build", "sync/atomic")
+	tg.mustNotExist("atomic")
+	tg.mustNotExist("atomic.exe")
+
+	tg.run("build", "-o", "myatomic.a", "sync/atomic")
+	tg.wantArchive("myatomic.a")
+	tg.mustNotExist("atomic")
+	tg.mustNotExist("atomic.a")
+	tg.mustNotExist("atomic.exe")
+
+	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/third_party/gofrontend/libgo/go/cmd/go/help.go b/third_party/gofrontend/libgo/go/cmd/go/help.go
index c590fdb..5dff267 100644
--- a/third_party/gofrontend/libgo/go/cmd/go/help.go
+++ b/third_party/gofrontend/libgo/go/cmd/go/help.go
@@ -11,7 +11,7 @@
 There are two different ways to call between Go and C/C++ code.
 
 The first is the cgo tool, which is part of the Go distribution.  For
-information on how to use it see the cgo documentation (godoc cmd/cgo).
+information on how to use it see the cgo documentation (go doc cmd/cgo).
 
 The second is the SWIG program, which is a general tool for
 interfacing between languages.  For information on SWIG see
@@ -47,7 +47,7 @@
 If no import paths are given, the action applies to the
 package in the current directory.
 
-There are three reserved names for paths that should not be used
+There are four reserved names for paths that should not be used
 for packages to be built with the go tool:
 
 - "main" denotes the top-level package in a stand-alone executable.
@@ -59,6 +59,9 @@
 - "std" is like all but expands to just the packages in the standard
 Go library.
 
+- "cmd" expands to the Go repository's commands and their
+internal libraries.
+
 An import path is a pattern if it includes one or more "..." wildcards,
 each of which can match any string, including the empty string and
 strings containing slashes.  Such a pattern expands to all package
@@ -74,7 +77,7 @@
 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
@@ -192,7 +195,7 @@
 
 When a version control system supports multiple protocols,
 each is tried in turn when downloading.  For example, a Git
-download tries git://, then https://, then http://.
+download tries https://, then git+ssh://.
 
 If the import path is not a known code hosting site and also lacks a
 version control qualifier, the go tool attempts to fetch the import
@@ -208,6 +211,10 @@
 fetched with "go get". If it's not an exact match, another http
 request is made at the prefix to verify the <meta> tags match.
 
+The meta tag should appear as early in the file as possible.
+In particular, it should appear before any raw JavaScript or CSS,
+to avoid confusing the go command's restricted parser.
+
 The vcs is one of "git", "hg", "svn", etc,
 
 The repo-root is the root of the version control system
@@ -217,10 +224,10 @@
 
 	import "example.org/pkg/foo"
 
-will result in the following request(s):
+will result in the following requests:
 
 	https://example.org/pkg/foo?go-get=1 (preferred)
-	http://example.org/pkg/foo?go-get=1  (fallback)
+	http://example.org/pkg/foo?go-get=1  (fallback, only with -insecure)
 
 If that page contains the meta tag
 
@@ -254,6 +261,11 @@
 let package authors make sure the custom import path is used and not a
 direct path to the underlying code hosting site.
 
+If the vendoring experiment is enabled (see 'go help gopath'),
+then import path checking is disabled for code found within vendor trees.
+This makes it possible to copy code into alternate locations in vendor trees
+without needing to update import comments.
+
 See https://golang.org/s/go14customimport for details.
 	`,
 }
@@ -275,10 +287,10 @@
 
 Each directory listed in GOPATH must have a prescribed structure:
 
-The src/ directory holds source code.  The path below 'src'
+The src directory holds source code.  The path below src
 determines the import path or executable name.
 
-The pkg/ directory holds installed package objects.
+The pkg directory holds installed package objects.
 As in the Go tree, each target operating system and
 architecture pair has its own subdirectory of pkg
 (pkg/GOOS_GOARCH).
@@ -287,11 +299,11 @@
 source in DIR/src/foo/bar can be imported as "foo/bar" and
 has its compiled form installed to "DIR/pkg/GOOS_GOARCH/foo/bar.a".
 
-The bin/ directory holds compiled commands.
+The bin directory holds compiled commands.
 Each command is named for its source directory, but only
 the final element, not the entire path.  That is, the
 command with source in DIR/src/foo/quux is installed into
-DIR/bin/quux, not DIR/bin/foo/quux.  The foo/ is stripped
+DIR/bin/quux, not DIR/bin/foo/quux.  The "foo/" prefix is stripped
 so that you can add DIR/bin to your PATH to get at the
 installed commands.  If the GOBIN environment variable is
 set, commands are installed to the directory it names instead
@@ -318,6 +330,168 @@
 Go searches each directory listed in GOPATH to find source code,
 but new packages are always downloaded into the first directory
 in the list.
+
+See https://golang.org/doc/code.html for an example.
+
+Internal Directories
+
+Code in or below a directory named "internal" is importable only
+by code in the directory tree rooted at the parent of "internal".
+Here's an extended version of the directory layout above:
+
+    /home/user/gocode/
+        src/
+            crash/
+                bang/              (go code in package bang)
+                    b.go
+            foo/                   (go code in package foo)
+                f.go
+                bar/               (go code in package bar)
+                    x.go
+                internal/
+                    baz/           (go code in package baz)
+                        z.go
+                quux/              (go code in package main)
+                    y.go
+
+
+The code in z.go is imported as "foo/internal/baz", but that
+import statement can only appear in source files in the subtree
+rooted at foo. The source files foo/f.go, foo/bar/x.go, and
+foo/quux/y.go can all import "foo/internal/baz", but the source file
+crash/bang/b.go cannot.
+
+See https://golang.org/s/go14internal for details.
+
+Vendor Directories
+
+Go 1.5 includes experimental support for using local copies
+of external dependencies to satisfy imports of those dependencies,
+often referred to as vendoring. Setting the environment variable
+GO15VENDOREXPERIMENT=1 enables that experimental support.
+
+When the vendor experiment is enabled,
+code below a directory named "vendor" is importable only
+by code in the directory tree rooted at the parent of "vendor",
+and only using an import path that omits the prefix up to and
+including the vendor element.
+
+Here's the example from the previous section,
+but with the "internal" directory renamed to "vendor"
+and a new foo/vendor/crash/bang directory added:
+
+    /home/user/gocode/
+        src/
+            crash/
+                bang/              (go code in package bang)
+                    b.go
+            foo/                   (go code in package foo)
+                f.go
+                bar/               (go code in package bar)
+                    x.go
+                vendor/
+                    crash/
+                        bang/      (go code in package bang)
+                            b.go
+                    baz/           (go code in package baz)
+                        z.go
+                quux/              (go code in package main)
+                    y.go
+
+The same visibility rules apply as for internal, but the code
+in z.go is imported as "baz", not as "foo/vendor/baz".
+
+Code in vendor directories deeper in the source tree shadows
+code in higher directories. Within the subtree rooted at foo, an import
+of "crash/bang" resolves to "foo/vendor/crash/bang", not the
+top-level "crash/bang".
+
+Code in vendor directories is not subject to import path
+checking (see 'go help importpath').
+
+When the vendor experiment is enabled, 'go get' checks out
+submodules when checking out or updating a git repository
+(see 'go help get').
+
+The vendoring semantics are an experiment, and they may change
+in future releases. Once settled, they will be on by default.
+
+See https://golang.org/s/go15vendor for details.
+	`,
+}
+
+var helpEnvironment = &Command{
+	UsageLine: "environment",
+	Short:     "environment variables",
+	Long: `
+
+The go command, and the tools it invokes, examine a few different
+environment variables. For many of these, you can see the default
+value of on your system by running 'go env NAME', where NAME is the
+name of the variable.
+
+General-purpose environment variables:
+
+	GCCGO
+		The gccgo command to run for 'go build -compiler=gccgo'.
+	GOARCH
+		The architecture, or processor, for which to compile code.
+		Examples are amd64, 386, arm, ppc64.
+	GOBIN
+		The directory where 'go install' will install a command.
+	GOOS
+		The operating system for which to compile code.
+		Examples are linux, darwin, windows, netbsd.
+	GOPATH
+		See 'go help gopath'.
+	GORACE
+		Options for the race detector.
+		See https://golang.org/doc/articles/race_detector.html.
+	GOROOT
+		The root of the go tree.
+
+Environment variables for use with cgo:
+
+	CC
+		The command to use to compile C code.
+	CGO_ENABLED
+		Whether the cgo command is supported.  Either 0 or 1.
+	CGO_CFLAGS
+		Flags that cgo will pass to the compiler when compiling
+		C code.
+	CGO_CPPFLAGS
+		Flags that cgo will pass to the compiler when compiling
+		C or C++ code.
+	CGO_CXXFLAGS
+		Flags that cgo will pass to the compiler when compiling
+		C++ code.
+	CGO_LDFLAGS
+		Flags that cgo will pass to the compiler when linking.
+	CXX
+		The command to use to compile C++ code.
+
+Architecture-specific environment variables:
+
+	GOARM
+		For GOARCH=arm, the ARM architecture for which to compile.
+		Valid values are 5, 6, 7.
+	GO386
+		For GOARCH=386, the floating point instruction set.
+		Valid values are 387, sse2.
+
+Special-purpose environment variables:
+
+	GOROOT_FINAL
+		The root of the installed Go tree, when it is
+		installed in a location other than where it is built.
+		File names in stack traces are rewritten from GOROOT to
+		GOROOT_FINAL.
+	GO15VENDOREXPERIMENT
+		Set to 1 to enable the Go 1.5 vendoring experiment.
+	GO_EXTLINK_ENABLED
+		Whether the linker should use external linking mode
+		when using -linkmode=auto with code that uses cgo.
+		Set to 0 to disable external linking mode, 1 to enable it.
 	`,
 }
 
@@ -333,10 +507,9 @@
 		Go source files.
 	.c, .h
 		C source files.
-		If the package uses cgo, these will be compiled with the
-		OS-native compiler (typically gcc); otherwise they will be
-		compiled with the Go-specific support compiler,
-		5c, 6c, or 8c, etc. as appropriate.
+		If the package uses cgo or SWIG, these will be compiled with the
+		OS-native compiler (typically gcc); otherwise they will
+		trigger an error.
 	.cc, .cpp, .cxx, .hh, .hpp, .hxx
 		C++ source files. Only useful with cgo or SWIG, and always
 		compiled with the OS-native compiler.
@@ -345,10 +518,9 @@
 		compiled with the OS-native compiler.
 	.s, .S
 		Assembler source files.
-		If the package uses cgo, these will be assembled with the
+		If the package uses cgo or SWIG, these will be assembled with the
 		OS-native assembler (typically gcc (sic)); otherwise they
-		will be assembled with the Go-specific support assembler,
-		5a, 6a, or 8a, etc., as appropriate.
+		will be assembled with the Go assembler.
 	.swig, .swigcxx
 		SWIG definition files.
 	.syso
@@ -360,3 +532,43 @@
 line comment.
 	`,
 }
+
+var helpBuildmode = &Command{
+	UsageLine: "buildmode",
+	Short:     "description of build modes",
+	Long: `
+The 'go build' and 'go install' commands take a -buildmode argument which
+indicates which kind of object file is to be built. Currently supported values
+are:
+
+	-buildmode=archive
+		Build the listed non-main packages into .a files. Packages named
+		main are ignored.
+
+	-buildmode=c-archive
+		Build the listed main package, plus all packages it imports,
+		into a C archive file. The only callable symbols will be those
+		functions exported using a cgo //export comment. Requires
+		exactly one main package to be listed.
+
+	-buildmode=c-shared
+		Build the listed main packages, plus all packages that they
+		import, into C shared libraries. The only callable symbols will
+		be those functions exported using a cgo //export comment.
+		Non-main packages are ignored.
+
+	-buildmode=default
+		Listed main packages are built into executables and listed
+		non-main packages are built into .a files (the default
+		behavior).
+
+	-buildmode=shared
+		Combine all the listed non-main packages into a single shared
+		library that will be used when building with the -linkshared
+		option. Packages named main are ignored.
+
+	-buildmode=exe
+		Build the listed main packages and everything they import into
+		executables. Packages not named main are ignored.
+`,
+}
diff --git a/third_party/gofrontend/libgo/go/cmd/go/http.go b/third_party/gofrontend/libgo/go/cmd/go/http.go
index 107b820..7979c41 100644
--- a/third_party/gofrontend/libgo/go/cmd/go/http.go
+++ b/third_party/gofrontend/libgo/go/cmd/go/http.go
@@ -18,11 +18,25 @@
 	"log"
 	"net/http"
 	"net/url"
+	"time"
 )
 
 // httpClient is the default HTTP client, but a variable so it can be
 // changed by tests, without modifying http.DefaultClient.
 var httpClient = http.DefaultClient
+var impatientHTTPClient = &http.Client{
+	Timeout: time.Duration(5 * time.Second),
+}
+
+type httpError struct {
+	status     string
+	statusCode int
+	url        string
+}
+
+func (e *httpError) Error() string {
+	return fmt.Sprintf("%s: %s", e.url, e.status)
+}
 
 // httpGET returns the data from an HTTP GET request for the given URL.
 func httpGET(url string) ([]byte, error) {
@@ -32,7 +46,9 @@
 	}
 	defer resp.Body.Close()
 	if resp.StatusCode != 200 {
-		return nil, fmt.Errorf("%s: %s", url, resp.Status)
+		err := &httpError{status: resp.Status, statusCode: resp.StatusCode, url: url}
+
+		return nil, err
 	}
 	b, err := ioutil.ReadAll(resp.Body)
 	if err != nil {
@@ -43,7 +59,7 @@
 
 // httpsOrHTTP returns the body of either the importPath's
 // https resource or, if unavailable, the http resource.
-func httpsOrHTTP(importPath string) (urlStr string, body io.ReadCloser, err error) {
+func httpsOrHTTP(importPath string, security securityMode) (urlStr string, body io.ReadCloser, err error) {
 	fetch := func(scheme string) (urlStr string, res *http.Response, err error) {
 		u, err := url.Parse(scheme + "://" + importPath)
 		if err != nil {
@@ -54,7 +70,11 @@
 		if buildV {
 			log.Printf("Fetching %s", urlStr)
 		}
-		res, err = httpClient.Get(urlStr)
+		if security == insecure && scheme == "https" { // fail earlier
+			res, err = impatientHTTPClient.Get(urlStr)
+		} else {
+			res, err = httpClient.Get(urlStr)
+		}
 		return
 	}
 	closeBody := func(res *http.Response) {
@@ -72,7 +92,9 @@
 			}
 		}
 		closeBody(res)
-		urlStr, res, err = fetch("http")
+		if security == insecure {
+			urlStr, res, err = fetch("http")
+		}
 	}
 	if err != nil {
 		closeBody(res)
diff --git a/third_party/gofrontend/libgo/go/cmd/go/list.go b/third_party/gofrontend/libgo/go/cmd/go/list.go
index fbf9616..35c7cc4 100644
--- a/third_party/gofrontend/libgo/go/cmd/go/list.go
+++ b/third_party/gofrontend/libgo/go/cmd/go/list.go
@@ -21,9 +21,10 @@
 
 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
@@ -36,6 +37,7 @@
         Name          string // package name
         Doc           string // package documentation string
         Target        string // install path
+        Shlib         string // the shared library that contains this package (only set when -linkshared)
         Goroot        bool   // is this package in the Go root?
         Standard      bool   // is this package part of the standard Go library?
         Stale         bool   // would 'go install' do anything for this package?
@@ -126,6 +128,7 @@
 var nl = []byte{'\n'}
 
 func runList(cmd *Command, args []string) {
+	buildModeInit()
 	out := newTrackingWriter(os.Stdout)
 	defer out.w.Flush()
 
@@ -173,6 +176,10 @@
 	}
 
 	for _, pkg := range load(args) {
+		// Show vendor-expanded paths in listing
+		pkg.TestImports = pkg.vendored(pkg.TestImports)
+		pkg.XTestImports = pkg.vendored(pkg.XTestImports)
+
 		do(pkg)
 	}
 }
diff --git a/third_party/gofrontend/libgo/go/cmd/go/main.go b/third_party/gofrontend/libgo/go/cmd/go/main.go
index 9691f39..8ebde89 100644
--- a/third_party/gofrontend/libgo/go/cmd/go/main.go
+++ b/third_party/gofrontend/libgo/go/cmd/go/main.go
@@ -5,6 +5,7 @@
 package main
 
 import (
+	"bufio"
 	"bytes"
 	"flag"
 	"fmt"
@@ -76,6 +77,7 @@
 var commands = []*Command{
 	cmdBuild,
 	cmdClean,
+	cmdDoc,
 	cmdEnv,
 	cmdFix,
 	cmdFmt,
@@ -90,8 +92,10 @@
 	cmdVet,
 
 	helpC,
+	helpBuildmode,
 	helpFileType,
 	helpGopath,
+	helpEnvironment,
 	helpImportPath,
 	helpPackages,
 	helpTestflag,
@@ -109,6 +113,8 @@
 	exitMu.Unlock()
 }
 
+var origEnv []string
+
 func main() {
 	_ = go11tag
 	flag.Usage = usage
@@ -139,7 +145,7 @@
 				fmt.Fprintf(os.Stderr, "go: GOPATH entry cannot start with shell metacharacter '~': %q\n", p)
 				os.Exit(2)
 			}
-			if build.IsLocalImport(p) {
+			if !filepath.IsAbs(p) {
 				fmt.Fprintf(os.Stderr, "go: GOPATH entry is relative; must be absolute path: %q.\nRun 'go help gopath' for usage.\n", p)
 				os.Exit(2)
 			}
@@ -151,8 +157,20 @@
 		os.Exit(2)
 	}
 
+	// Set environment (GOOS, GOARCH, etc) explicitly.
+	// In theory all the commands we invoke should have
+	// the same default computation of these as we do,
+	// but in practice there might be skew
+	// This makes sure we all agree.
+	origEnv = os.Environ()
+	for _, env := range mkEnv() {
+		if os.Getenv(env.name) != env.value {
+			os.Setenv(env.name, env.value)
+		}
+	}
+
 	for _, cmd := range commands {
-		if cmd.Name() == args[0] && cmd.Run != nil {
+		if cmd.Name() == args[0] && cmd.Runnable() {
 			cmd.Flag.Usage = func() { cmd.Usage() }
 			if cmd.CustomFlags {
 				args = args[1:]
@@ -179,13 +197,13 @@
 
 The commands are:
 {{range .}}{{if .Runnable}}
-    {{.Name | printf "%-11s"}} {{.Short}}{{end}}{{end}}
+	{{.Name | printf "%-11s"}} {{.Short}}{{end}}{{end}}
 
 Use "go help [command]" for more information about a command.
 
 Additional help topics:
 {{range .}}{{if not .Runnable}}
-    {{.Name | printf "%-11s"}} {{.Short}}{{end}}{{end}}
+	{{.Name | printf "%-11s"}} {{.Short}}{{end}}{{end}}
 
 Use "go help [topic]" for more information about that topic.
 
@@ -200,8 +218,8 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-// DO NOT EDIT THIS FILE. GENERATED BY mkdoc.sh.
-// Edit the documentation in other files and rerun mkdoc.sh to generate this one.
+// DO NOT EDIT THIS FILE. GENERATED BY mkalldocs.sh.
+// Edit the documentation in other files and rerun mkalldocs.sh to generate this one.
 
 /*
 {{range .}}{{if .Short}}{{.Short | capitalize}}
@@ -217,12 +235,35 @@
 package main
 `
 
+// An errWriter wraps a writer, recording whether a write error occurred.
+type errWriter struct {
+	w   io.Writer
+	err error
+}
+
+func (w *errWriter) Write(b []byte) (int, error) {
+	n, err := w.w.Write(b)
+	if err != nil {
+		w.err = err
+	}
+	return n, err
+}
+
 // tmpl executes the given template text on data, writing the result to w.
 func tmpl(w io.Writer, text string, data interface{}) {
 	t := template.New("top")
 	t.Funcs(template.FuncMap{"trim": strings.TrimSpace, "capitalize": capitalize})
 	template.Must(t.Parse(text))
-	if err := t.Execute(w, data); err != nil {
+	ew := &errWriter{w: w}
+	err := t.Execute(ew, data)
+	if ew.err != nil {
+		// I/O error writing. Ignore write on closed pipe.
+		if strings.Contains(ew.err.Error(), "pipe") {
+			os.Exit(1)
+		}
+		fatalf("writing output: %v", ew.err)
+	}
+	if err != nil {
 		panic(err)
 	}
 }
@@ -236,13 +277,17 @@
 }
 
 func printUsage(w io.Writer) {
-	tmpl(w, usageTemplate, commands)
+	bw := bufio.NewWriter(w)
+	tmpl(bw, usageTemplate, commands)
+	bw.Flush()
 }
 
 func usage() {
 	// special case "go test -h"
 	if len(os.Args) > 1 && os.Args[1] == "test" {
-		help([]string{"testflag"})
+		os.Stdout.WriteString(testUsage + "\n\n" +
+			strings.TrimSpace(testFlag1) + "\n\n" +
+			strings.TrimSpace(testFlag2) + "\n")
 		os.Exit(2)
 	}
 	printUsage(os.Stderr)
@@ -308,7 +353,7 @@
 		} else {
 			a = path.Clean(a)
 		}
-		if a == "all" || a == "std" {
+		if a == "all" || a == "std" || a == "cmd" {
 			out = append(out, allPackages(a)...)
 			continue
 		}
@@ -401,11 +446,10 @@
 // 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
@@ -458,6 +502,28 @@
 	}
 }
 
+// hasFilePathPrefix reports whether the filesystem path s begins with the
+// elements in prefix.
+func hasFilePathPrefix(s, prefix string) bool {
+	sv := strings.ToUpper(filepath.VolumeName(s))
+	pv := strings.ToUpper(filepath.VolumeName(prefix))
+	s = s[len(sv):]
+	prefix = prefix[len(pv):]
+	switch {
+	default:
+		return false
+	case sv != pv:
+		return false
+	case len(s) == len(prefix):
+		return s == prefix
+	case len(s) > len(prefix):
+		if prefix != "" && prefix[len(prefix)-1] == filepath.Separator {
+			return strings.HasPrefix(s, prefix)
+		}
+		return s[len(prefix)] == filepath.Separator && s[:len(prefix)] == prefix
+	}
+}
+
 // treeCanMatchPattern(pattern)(name) reports whether
 // name or children of name can possibly match pattern.
 // Pattern is the same limited glob accepted by matchPattern.
@@ -475,8 +541,8 @@
 
 // allPackages returns all the packages that can be found
 // under the $GOPATH directories and $GOROOT matching pattern.
-// The pattern is either "all" (all packages), "std" (standard packages)
-// or a path including "...".
+// The pattern is either "all" (all packages), "std" (standard packages),
+// "cmd" (standard commands), or a path including "...".
 func allPackages(pattern string) []string {
 	pkgs := matchPackages(pattern)
 	if len(pkgs) == 0 {
@@ -488,7 +554,7 @@
 func matchPackages(pattern string) []string {
 	match := func(string) bool { return true }
 	treeCanMatch := func(string) bool { return true }
-	if pattern != "all" && pattern != "std" {
+	if pattern != "all" && pattern != "std" && pattern != "cmd" {
 		match = matchPattern(pattern)
 		treeCanMatch = treeCanMatchPattern(pattern)
 	}
@@ -501,47 +567,16 @@
 	}
 	var pkgs []string
 
-	// Commands
-	cmd := filepath.Join(goroot, "src/cmd") + string(filepath.Separator)
-	filepath.Walk(cmd, func(path string, fi os.FileInfo, err error) error {
-		if err != nil || !fi.IsDir() || path == cmd {
-			return nil
-		}
-		name := path[len(cmd):]
-		if !treeCanMatch(name) {
-			return filepath.SkipDir
-		}
-		// Commands are all in cmd/, not in subdirectories.
-		if strings.Contains(name, string(filepath.Separator)) {
-			return filepath.SkipDir
-		}
-
-		// We use, e.g., cmd/gofmt as the pseudo import path for gofmt.
-		name = "cmd/" + name
-		if have[name] {
-			return nil
-		}
-		have[name] = true
-		if !match(name) {
-			return nil
-		}
-		_, err = buildContext.ImportDir(path, 0)
-		if err != nil {
-			if _, noGo := err.(*build.NoGoError); !noGo {
-				log.Print(err)
-			}
-			return nil
-		}
-		pkgs = append(pkgs, name)
-		return nil
-	})
-
 	for _, src := range buildContext.SrcDirs() {
-		if pattern == "std" && src != gorootSrc {
+		if (pattern == "std" || pattern == "cmd") && src != gorootSrc {
 			continue
 		}
 		src = filepath.Clean(src) + string(filepath.Separator)
-		filepath.Walk(src, func(path string, fi os.FileInfo, err error) error {
+		root := src
+		if pattern == "cmd" {
+			root += "cmd" + string(filepath.Separator)
+		}
+		filepath.Walk(root, func(path string, fi os.FileInfo, err error) error {
 			if err != nil || !fi.IsDir() || path == src {
 				return nil
 			}
@@ -553,7 +588,10 @@
 			}
 
 			name := filepath.ToSlash(path[len(src):])
-			if pattern == "std" && strings.Contains(name, ".") {
+			if pattern == "std" && (strings.Contains(name, ".") || name == "cmd") {
+				// The name "std" is only the standard library.
+				// If the name has a dot, assume it's a domain name for go get,
+				// and if the name is cmd, it's the root of the command tree.
 				return filepath.SkipDir
 			}
 			if !treeCanMatch(name) {
@@ -659,7 +697,7 @@
 		case string:
 			x = append(x, arg)
 		default:
-			panic("stringList: invalid argument")
+			panic("stringList: invalid argument of type " + fmt.Sprintf("%T", arg))
 		}
 	}
 	return x
diff --git a/third_party/gofrontend/libgo/go/cmd/go/note.go b/third_party/gofrontend/libgo/go/cmd/go/note.go
new file mode 100644
index 0000000..97e1865
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/cmd/go/note.go
@@ -0,0 +1,116 @@
+// 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 (
+	"bytes"
+	"debug/elf"
+	"encoding/binary"
+	"fmt"
+	"io"
+	"os"
+)
+
+func readAligned4(r io.Reader, sz int32) ([]byte, error) {
+	full := (sz + 3) &^ 3
+	data := make([]byte, full)
+	_, err := io.ReadFull(r, data)
+	if err != nil {
+		return nil, err
+	}
+	data = data[:sz]
+	return data, nil
+}
+
+func readELFNote(filename, name string, typ int32) ([]byte, error) {
+	f, err := elf.Open(filename)
+	if err != nil {
+		return nil, err
+	}
+	for _, sect := range f.Sections {
+		if sect.Type != elf.SHT_NOTE {
+			continue
+		}
+		r := sect.Open()
+		for {
+			var namesize, descsize, noteType int32
+			err = binary.Read(r, f.ByteOrder, &namesize)
+			if err != nil {
+				if err == io.EOF {
+					break
+				}
+				return nil, fmt.Errorf("read namesize failed: %v", err)
+			}
+			err = binary.Read(r, f.ByteOrder, &descsize)
+			if err != nil {
+				return nil, fmt.Errorf("read descsize failed: %v", err)
+			}
+			err = binary.Read(r, f.ByteOrder, &noteType)
+			if err != nil {
+				return nil, fmt.Errorf("read type failed: %v", err)
+			}
+			noteName, err := readAligned4(r, namesize)
+			if err != nil {
+				return nil, fmt.Errorf("read name failed: %v", err)
+			}
+			desc, err := readAligned4(r, descsize)
+			if err != nil {
+				return nil, fmt.Errorf("read desc failed: %v", err)
+			}
+			if name == string(noteName) && typ == noteType {
+				return desc, nil
+			}
+		}
+	}
+	return nil, nil
+}
+
+var elfGoNote = []byte("Go\x00\x00")
+
+// readELFGoBuildID the Go build ID string from an ELF binary.
+// The Go build ID is stored in a note described by an ELF PT_NOTE prog header.
+// The caller has already opened filename, to get f, and read the first 4 kB out, in data.
+func readELFGoBuildID(filename string, f *os.File, data []byte) (buildid string, err error) {
+	// Assume the note content is in the first 4 kB, already read.
+	// Rewrite the ELF header to set shnum to 0, so that we can pass
+	// the data to elf.NewFile and it will decode the Prog list but not
+	// try to read the section headers and the string table from disk.
+	// That's a waste of I/O when all we care about is the Prog list
+	// and the one ELF note.
+	switch elf.Class(data[elf.EI_CLASS]) {
+	case elf.ELFCLASS32:
+		data[48] = 0
+		data[49] = 0
+	case elf.ELFCLASS64:
+		data[60] = 0
+		data[61] = 0
+	}
+
+	const elfGoBuildIDTag = 4
+
+	ef, err := elf.NewFile(bytes.NewReader(data))
+	if err != nil {
+		return "", &os.PathError{Path: filename, Op: "parse", Err: err}
+	}
+	for _, p := range ef.Progs {
+		if p.Type != elf.PT_NOTE || p.Off >= uint64(len(data)) || p.Off+p.Filesz >= uint64(len(data)) || p.Filesz < 16 {
+			continue
+		}
+
+		note := data[p.Off : p.Off+p.Filesz]
+		nameSize := ef.ByteOrder.Uint32(note)
+		valSize := ef.ByteOrder.Uint32(note[4:])
+		tag := ef.ByteOrder.Uint32(note[8:])
+		name := note[12:16]
+		if nameSize != 4 || 16+valSize > uint32(len(note)) || tag != elfGoBuildIDTag || !bytes.Equal(name, elfGoNote) {
+			continue
+		}
+
+		return string(note[16 : 16+valSize]), nil
+	}
+
+	// No note. Treat as successful but build ID empty.
+	return "", nil
+}
diff --git a/third_party/gofrontend/libgo/go/cmd/go/note_test.go b/third_party/gofrontend/libgo/go/cmd/go/note_test.go
new file mode 100644
index 0000000..3d64451
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/cmd/go/note_test.go
@@ -0,0 +1,49 @@
+// 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_test
+
+import (
+	main "cmd/go"
+	"runtime"
+	"testing"
+)
+
+func TestNoteReading(t *testing.T) {
+	tg := testgo(t)
+	defer tg.cleanup()
+	tg.tempFile("hello.go", `package main; func main() { print("hello, world\n") }`)
+	const buildID = "TestNoteReading-Build-ID"
+	tg.run("build", "-ldflags", "-buildid="+buildID, "-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: %v", err)
+	}
+	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/third_party/gofrontend/libgo/go/cmd/go/pkg.go b/third_party/gofrontend/libgo/go/cmd/go/pkg.go
index ef440dd..3270a8b 100644
--- a/third_party/gofrontend/libgo/go/cmd/go/pkg.go
+++ b/third_party/gofrontend/libgo/go/cmd/go/pkg.go
@@ -6,18 +6,21 @@
 
 import (
 	"bytes"
+	"crypto/sha1"
 	"errors"
 	"fmt"
 	"go/build"
 	"go/scanner"
 	"go/token"
+	"io"
+	"io/ioutil"
 	"os"
 	pathpkg "path"
 	"path/filepath"
 	"runtime"
 	"sort"
+	"strconv"
 	"strings"
-	"time"
 	"unicode"
 )
 
@@ -32,6 +35,7 @@
 	Name          string `json:",omitempty"` // package name
 	Doc           string `json:",omitempty"` // package documentation string
 	Target        string `json:",omitempty"` // install path
+	Shlib         string `json:",omitempty"` // the shared library that contains this package (only set when -linkshared)
 	Goroot        bool   `json:",omitempty"` // is this package found in the Go root?
 	Standard      bool   `json:",omitempty"` // is this package part of the standard Go library?
 	Stale         bool   `json:",omitempty"` // would 'go install' do anything for this package?
@@ -93,6 +97,35 @@
 	coverMode    string               // preprocess Go source files with the coverage tool in this mode
 	coverVars    map[string]*CoverVar // variables created by coverage analysis
 	omitDWARF    bool                 // tell linker not to write DWARF information
+	buildID      string               // expected build ID for generated package
+	gobinSubdir  bool                 // install target would be subdir of GOBIN
+}
+
+// vendored returns the vendor-resolved version of imports,
+// which should be p.TestImports or p.XTestImports, NOT p.Imports.
+// The imports in p.TestImports and p.XTestImports are not recursively
+// loaded during the initial load of p, so they list the imports found in
+// the source file, but most processing should be over the vendor-resolved
+// import paths. We do this resolution lazily both to avoid file system work
+// and because the eventual real load of the test imports (during 'go test')
+// can produce better error messages if it starts with the original paths.
+// The initial load of p loads all the non-test imports and rewrites
+// the vendored paths, so nothing should ever call p.vendored(p.Imports).
+func (p *Package) vendored(imports []string) []string {
+	if len(imports) > 0 && len(p.Imports) > 0 && &imports[0] == &p.Imports[0] {
+		panic("internal error: p.vendored(p.Imports) called")
+	}
+	seen := make(map[string]bool)
+	var all []string
+	for _, path := range imports {
+		path, _ = vendoredImportPath(p, path)
+		if !seen[path] {
+			seen[path] = true
+			all = append(all, path)
+		}
+	}
+	sort.Strings(all)
+	return all
 }
 
 // CoverVar holds the name of the generated coverage variables targeting the named file.
@@ -104,6 +137,13 @@
 func (p *Package) copyBuild(pp *build.Package) {
 	p.build = pp
 
+	if pp.PkgTargetRoot != "" && buildPkgdir != "" {
+		old := pp.PkgTargetRoot
+		pp.PkgRoot = buildPkgdir
+		pp.PkgTargetRoot = buildPkgdir
+		pp.PkgObj = filepath.Join(buildPkgdir, strings.TrimPrefix(pp.PkgObj, old))
+	}
+
 	p.Dir = pp.Dir
 	p.ImportPath = pp.ImportPath
 	p.ImportComment = pp.ImportComment
@@ -181,7 +221,7 @@
 	return append([]string{}, *s...)
 }
 
-// shorterThan returns true if sp is shorter than t.
+// shorterThan reports whether sp is shorter than t.
 // We use this to record the shortest import sequence
 // that leads to a particular package.
 func (sp *importStack) shorterThan(t []string) bool {
@@ -214,6 +254,12 @@
 	return loadPackage(arg, stk)
 }
 
+// The Go 1.5 vendoring experiment is enabled by setting GO15VENDOREXPERIMENT=1.
+// The variable is obnoxiously long so that years from now when people find it in
+// their profiles and wonder what it does, there is some chance that a web search
+// might answer the question.
+var go15VendorExperiment = os.Getenv("GO15VENDOREXPERIMENT") == "1"
+
 // dirToImportPath returns the pseudo-import path we use for a package
 // outside the Go path.  It begins with _/ and then contains the full path
 // to the directory.  If the package lives in c:\home\gopher\my\pkg then
@@ -234,11 +280,29 @@
 	return r
 }
 
+// Mode flags for loadImport and download (in get.go).
+const (
+	// useVendor means that loadImport should do vendor expansion
+	// (provided the vendoring experiment is enabled).
+	// That is, useVendor means that the import path came from
+	// a source file and has not been vendor-expanded yet.
+	// Every import path should be loaded initially with useVendor,
+	// and then the expanded version (with the /vendor/ in it) gets
+	// recorded as the canonical import path. At that point, future loads
+	// of that package must not pass useVendor, because
+	// disallowVendor will reject direct use of paths containing /vendor/.
+	useVendor = 1 << iota
+
+	// getTestDeps is for download (part of "go get") and indicates
+	// that test dependencies should be fetched too.
+	getTestDeps
+)
+
 // loadImport scans the directory named by path, which must be an import path,
 // but possibly a local import path (an absolute file system path or one beginning
 // with ./ or ../).  A local relative path is interpreted relative to srcDir.
 // It returns a *Package describing the package found in that directory.
-func loadImport(path string, srcDir string, stk *importStack, importPos []token.Position) *Package {
+func loadImport(path, srcDir string, parent *Package, stk *importStack, importPos []token.Position, mode int) *Package {
 	stk.push(path)
 	defer stk.pop()
 
@@ -246,15 +310,27 @@
 	// For a local import the identifier is the pseudo-import path
 	// we create from the full directory to the package.
 	// Otherwise it is the usual import path.
+	// For vendored imports, it is the expanded form.
 	importPath := path
+	origPath := path
 	isLocal := build.IsLocalImport(path)
+	var vendorSearch []string
 	if isLocal {
 		importPath = dirToImportPath(filepath.Join(srcDir, path))
+	} else if mode&useVendor != 0 {
+		path, vendorSearch = vendoredImportPath(parent, path)
+		importPath = path
 	}
+
 	if p := packageCache[importPath]; p != nil {
 		if perr := disallowInternal(srcDir, p, stk); perr != p {
 			return perr
 		}
+		if mode&useVendor != 0 {
+			if perr := disallowVendor(srcDir, origPath, p, stk); perr != p {
+				return perr
+			}
+		}
 		return reusePackage(p, stk)
 	}
 
@@ -270,11 +346,34 @@
 	// TODO: After Go 1, decide when to pass build.AllowBinary here.
 	// See issue 3268 for mistakes to avoid.
 	bp, err := buildContext.Import(path, srcDir, build.ImportComment)
+
+	// If we got an error from go/build about package not found,
+	// it contains the directories from $GOROOT and $GOPATH that
+	// were searched. Add to that message the vendor directories
+	// that were searched.
+	if err != nil && len(vendorSearch) > 0 {
+		// NOTE(rsc): The direct text manipulation here is fairly awful,
+		// but it avoids defining new go/build API (an exported error type)
+		// late in the Go 1.5 release cycle. If this turns out to be a more general
+		// problem we could define a real error type when the decision can be
+		// considered more carefully.
+		text := err.Error()
+		if strings.Contains(text, "cannot find package \"") && strings.Contains(text, "\" in any of:\n\t") {
+			old := strings.SplitAfter(text, "\n")
+			lines := []string{old[0]}
+			for _, dir := range vendorSearch {
+				lines = append(lines, "\t"+dir+" (vendor tree)\n")
+			}
+			lines = append(lines, old[1:]...)
+			err = errors.New(strings.Join(lines, ""))
+		}
+	}
 	bp.ImportPath = importPath
 	if gobin != "" {
 		bp.BinDir = gobin
 	}
-	if err == nil && !isLocal && bp.ImportComment != "" && bp.ImportComment != path {
+	if err == nil && !isLocal && bp.ImportComment != "" && bp.ImportComment != path &&
+		(!go15VendorExperiment || (!strings.Contains(path, "/vendor/") && !strings.HasPrefix(path, "vendor/"))) {
 		err = fmt.Errorf("code in directory %s expects import %q", bp.Dir, bp.ImportComment)
 	}
 	p.load(stk, bp, err)
@@ -287,10 +386,83 @@
 	if perr := disallowInternal(srcDir, p, stk); perr != p {
 		return perr
 	}
+	if mode&useVendor != 0 {
+		if perr := disallowVendor(srcDir, origPath, p, stk); perr != p {
+			return perr
+		}
+	}
 
 	return p
 }
 
+var isDirCache = map[string]bool{}
+
+func isDir(path string) bool {
+	result, ok := isDirCache[path]
+	if ok {
+		return result
+	}
+
+	fi, err := os.Stat(path)
+	result = err == nil && fi.IsDir()
+	isDirCache[path] = result
+	return result
+}
+
+// vendoredImportPath returns the expansion of path when it appears in parent.
+// If parent is x/y/z, then path might expand to x/y/z/vendor/path, x/y/vendor/path,
+// x/vendor/path, vendor/path, or else stay x/y/z if none of those exist.
+// vendoredImportPath returns the expanded path or, if no expansion is found, the original.
+// If no expansion is found, vendoredImportPath also returns a list of vendor directories
+// it searched along the way, to help prepare a useful error message should path turn
+// out not to exist.
+func vendoredImportPath(parent *Package, path string) (found string, searched []string) {
+	if parent == nil || parent.Root == "" || !go15VendorExperiment {
+		return path, nil
+	}
+	dir := filepath.Clean(parent.Dir)
+	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))
+	}
+	vpath := "vendor/" + path
+	for i := len(dir); i >= len(root); i-- {
+		if i < len(dir) && dir[i] != filepath.Separator {
+			continue
+		}
+		// Note: checking for the vendor directory before checking
+		// for the vendor/path directory helps us hit the
+		// isDir cache more often. It also helps us prepare a more useful
+		// list of places we looked, to report when an import is not found.
+		if !isDir(filepath.Join(dir[:i], "vendor")) {
+			continue
+		}
+		targ := filepath.Join(dir[:i], vpath)
+		if isDir(targ) {
+			// We started with parent's dir c:\gopath\src\foo\bar\baz\quux\xyzzy.
+			// We know the import path for parent's dir.
+			// We chopped off some number of path elements and
+			// added vendor\path to produce c:\gopath\src\foo\bar\baz\vendor\path.
+			// Now we want to know the import path for that directory.
+			// Construct it by chopping the same number of path elements
+			// (actually the same number of bytes) from parent's import path
+			// and then append /vendor/path.
+			chopped := len(dir) - i
+			if chopped == len(parent.ImportPath)+1 {
+				// We walked up from c:\gopath\src\foo\bar
+				// and found c:\gopath\src\vendor\path.
+				// We chopped \foo\bar (length 8) but the import path is "foo/bar" (length 7).
+				// Use "vendor/path" without any prefix.
+				return vpath, nil
+			}
+			return parent.ImportPath[:len(parent.ImportPath)-chopped] + "/" + vpath, nil
+		}
+		// Note the existence of a vendor directory in case path is not found anywhere.
+		searched = append(searched, targ)
+	}
+	return path, searched
+}
+
 // reusePackage reuses package p to satisfy the import at the top
 // of the import stack stk.  If this use causes an import loop,
 // reusePackage updates p's error information to record the loop.
@@ -324,11 +496,9 @@
 	// An import of a path containing the element “internal”
 	// is disallowed if the importing code is outside the tree
 	// rooted at the parent of the “internal” directory.
-	//
-	// ... For Go 1.4, we will implement the rule first for $GOROOT, but not $GOPATH.
 
-	// Only applies to $GOROOT.
-	if !p.Standard {
+	// There was an error loading the package; stop here.
+	if p.Error != nil {
 		return p
 	}
 
@@ -385,6 +555,105 @@
 	return 0, false
 }
 
+// disallowVendor checks that srcDir is allowed to import p as path.
+// If the import is allowed, disallowVendor returns the original package p.
+// If not, it returns a new package containing just an appropriate error.
+func disallowVendor(srcDir, path string, p *Package, stk *importStack) *Package {
+	if !go15VendorExperiment {
+		return p
+	}
+
+	// The stack includes p.ImportPath.
+	// If that's the only thing on the stack, we started
+	// with a name given on the command line, not an
+	// import. Anything listed on the command line is fine.
+	if len(*stk) == 1 {
+		return p
+	}
+
+	if perr := disallowVendorVisibility(srcDir, p, stk); perr != p {
+		return perr
+	}
+
+	// Paths like x/vendor/y must be imported as y, never as x/vendor/y.
+	if i, ok := findVendor(path); ok {
+		perr := *p
+		perr.Error = &PackageError{
+			ImportStack: stk.copy(),
+			Err:         "must be imported as " + path[i+len("vendor/"):],
+		}
+		perr.Incomplete = true
+		return &perr
+	}
+
+	return p
+}
+
+// disallowVendorVisibility checks that srcDir is allowed to import p.
+// The rules are the same as for /internal/ except that a path ending in /vendor
+// is not subject to the rules, only subdirectories of vendor.
+// This allows people to have packages and commands named vendor,
+// for maximal compatibility with existing source trees.
+func disallowVendorVisibility(srcDir string, p *Package, stk *importStack) *Package {
+	// The stack includes p.ImportPath.
+	// If that's the only thing on the stack, we started
+	// with a name given on the command line, not an
+	// import. Anything listed on the command line is fine.
+	if len(*stk) == 1 {
+		return p
+	}
+
+	// Check for "vendor" element.
+	i, ok := findVendor(p.ImportPath)
+	if !ok {
+		return p
+	}
+
+	// Vendor is present.
+	// Map import path back to directory corresponding to parent of vendor.
+	if i > 0 {
+		i-- // rewind over slash in ".../vendor"
+	}
+	truncateTo := i + len(p.Dir) - len(p.ImportPath)
+	if truncateTo < 0 || len(p.Dir) < truncateTo {
+		return p
+	}
+	parent := p.Dir[:truncateTo]
+	if hasPathPrefix(filepath.ToSlash(srcDir), filepath.ToSlash(parent)) {
+		return p
+	}
+
+	// Vendor is present, and srcDir is outside parent's tree. Not allowed.
+	perr := *p
+	perr.Error = &PackageError{
+		ImportStack: stk.copy(),
+		Err:         "use of vendored package not allowed",
+	}
+	perr.Incomplete = true
+	return &perr
+}
+
+// findVendor looks for the last non-terminating "vendor" path element in the given import path.
+// If there isn't one, findVendor returns ok=false.
+// Otherwise, findInternal returns ok=true and the index of the "vendor".
+//
+// Note that terminating "vendor" elements don't count: "x/vendor" is its own package,
+// not the vendored copy of an import "" (the empty import path).
+// This will allow people to have packages or commands named vendor.
+// This may help reduce breakage, or it may just be confusing. We'll see.
+func findVendor(path string) (index int, ok bool) {
+	// Two cases, depending on internal at start of string or not.
+	// The order matters: we must return the index of the final element,
+	// because the final one is where the effective import path starts.
+	switch {
+	case strings.Contains(path, "/vendor/"):
+		return strings.LastIndex(path, "/vendor/") + 1, true
+	case strings.HasPrefix(path, "vendor/"):
+		return 0, true
+	}
+	return 0, false
+}
+
 type targetDir int
 
 const (
@@ -398,17 +667,23 @@
 var goTools = map[string]targetDir{
 	"cmd/addr2line":                        toTool,
 	"cmd/api":                              toTool,
+	"cmd/asm":                              toTool,
+	"cmd/compile":                          toTool,
 	"cmd/cgo":                              toTool,
+	"cmd/cover":                            toTool,
+	"cmd/dist":                             toTool,
+	"cmd/doc":                              toTool,
 	"cmd/fix":                              toTool,
 	"cmd/link":                             toTool,
+	"cmd/newlink":                          toTool,
 	"cmd/nm":                               toTool,
 	"cmd/objdump":                          toTool,
 	"cmd/pack":                             toTool,
 	"cmd/pprof":                            toTool,
+	"cmd/trace":                            toTool,
+	"cmd/vet":                              toTool,
 	"cmd/yacc":                             toTool,
-	"golang.org/x/tools/cmd/cover":         toTool,
 	"golang.org/x/tools/cmd/godoc":         toBin,
-	"golang.org/x/tools/cmd/vet":           toTool,
 	"code.google.com/p/go.tools/cmd/cover": stalePath,
 	"code.google.com/p/go.tools/cmd/godoc": stalePath,
 	"code.google.com/p/go.tools/cmd/vet":   stalePath,
@@ -471,7 +746,15 @@
 		return p
 	}
 
-	if p.Name == "main" {
+	useBindir := p.Name == "main"
+	if !p.Standard {
+		switch buildBuildmode {
+		case "c-archive", "c-shared":
+			useBindir = false
+		}
+	}
+
+	if useBindir {
 		// Report an error when the old code.google.com/p/go.tools paths are used.
 		if goTools[p.ImportPath] == stalePath {
 			newPath := strings.Replace(p.ImportPath, "code.google.com/p/go.", "golang.org/x/", 1)
@@ -493,11 +776,20 @@
 		} else if p.build.BinDir != "" {
 			// Install to GOBIN or bin of GOPATH entry.
 			p.target = filepath.Join(p.build.BinDir, elem)
+			if !p.Goroot && strings.Contains(elem, "/") && gobin != "" {
+				// Do not create $GOBIN/goos_goarch/elem.
+				p.target = ""
+				p.gobinSubdir = true
+			}
 		}
 		if goTools[p.ImportPath] == toTool {
 			// This is for 'go tool'.
 			// Override all the usual logic and force it into the tool directory.
-			p.target = filepath.Join(gorootPkg, "tool", full)
+			if buildContext.Compiler == "gccgo" {
+				p.target = filepath.Join(runtime.GCCGOTOOLDIR, elem)
+			} else {
+				p.target = filepath.Join(gorootPkg, "tool", full)
+			}
 		}
 		if p.target != "" && buildContext.GOOS == "windows" {
 			p.target += ".exe"
@@ -508,6 +800,21 @@
 		p.target = ""
 	} else {
 		p.target = p.build.PkgObj
+		if buildLinkshared {
+			shlibnamefile := p.target[:len(p.target)-2] + ".shlibname"
+			shlib, err := ioutil.ReadFile(shlibnamefile)
+			if err == nil {
+				libname := strings.TrimSpace(string(shlib))
+				if buildContext.Compiler == "gccgo" {
+					p.Shlib = filepath.Join(p.build.PkgTargetRoot, "shlibs", libname)
+				} else {
+					p.Shlib = filepath.Join(p.build.PkgTargetRoot, libname)
+
+				}
+			} else if !os.IsNotExist(err) {
+				fatalf("unexpected error reading %s: %v", shlibnamefile, err)
+			}
+		}
 	}
 
 	importPaths := p.Imports
@@ -521,6 +828,14 @@
 	if len(p.CgoFiles) > 0 && (!p.Standard || !cgoSyscallExclude[p.ImportPath]) {
 		importPaths = append(importPaths, "syscall")
 	}
+
+	// Currently build mode c-shared, or -linkshared, forces
+	// external linking mode, and external linking mode forces an
+	// import of runtime/cgo.
+	if p.Name == "main" && !p.Goroot && (buildBuildmode == "c-shared" || buildLinkshared) {
+		importPaths = append(importPaths, "runtime/cgo")
+	}
+
 	// Everything depends on runtime, except runtime and unsafe.
 	if !p.Standard || (p.ImportPath != "runtime" && p.ImportPath != "unsafe") {
 		importPaths = append(importPaths, "runtime")
@@ -529,6 +844,10 @@
 		if buildRace && (!p.Standard || !raceExclude[p.ImportPath]) {
 			importPaths = append(importPaths, "runtime/race")
 		}
+		// On ARM with GOARM=5, everything depends on math for the link.
+		if p.Name == "main" && goarch == "arm" {
+			importPaths = append(importPaths, "math")
+		}
 	}
 
 	// Build list of full paths to all Go files in the package,
@@ -586,10 +905,20 @@
 		if path == "C" {
 			continue
 		}
-		p1 := loadImport(path, p.Dir, stk, p.build.ImportPos[path])
+		p1 := loadImport(path, p.Dir, p, stk, p.build.ImportPos[path], useVendor)
 		if !reqStdPkgSrc && p1.Standard {
 			continue
 		}
+		if p1.Name == "main" {
+			p.Error = &PackageError{
+				ImportStack: stk.copy(),
+				Err:         fmt.Sprintf("import %q is a program, not an importable package", path),
+			}
+			pos := p.build.ImportPos[path]
+			if len(pos) > 0 {
+				p.Error.Pos = pos[0].String()
+			}
+		}
 		if p1.local {
 			if !p.local && p.Error == nil {
 				p.Error = &PackageError{
@@ -601,13 +930,21 @@
 					p.Error.Pos = pos[0].String()
 				}
 			}
-			path = p1.ImportPath
-			importPaths[i] = path
+		}
+		path = p1.ImportPath
+		importPaths[i] = path
+		if i < len(p.Imports) {
+			p.Imports[i] = path
 		}
 		deps[path] = p1
 		imports = append(imports, p1)
 		for _, dep := range p1.deps {
-			deps[dep.ImportPath] = dep
+			// The same import path could produce an error or not,
+			// depending on what tries to import it.
+			// Prefer to record entries with errors, so we can report them.
+			if deps[dep.ImportPath] == nil || dep.Error != nil {
+				deps[dep.ImportPath] = dep
+			}
 		}
 		if p1.Incomplete {
 			p.Incomplete = true
@@ -637,12 +974,11 @@
 	}
 	p.Target = p.target
 
-	// Check for C code compiled with Plan 9 C compiler.
-	// No longer allowed except in runtime and runtime/cgo, for now.
-	if len(p.CFiles) > 0 && !p.usesCgo() && (!p.Standard || p.ImportPath != "runtime") {
+	// The gc toolchain only permits C source files with cgo.
+	if len(p.CFiles) > 0 && !p.usesCgo() && !p.usesSwig() && buildContext.Compiler == "gc" {
 		p.Error = &PackageError{
 			ImportStack: stk.copy(),
-			Err:         fmt.Sprintf("C source files not allowed when not using cgo: %s", strings.Join(p.CFiles, " ")),
+			Err:         fmt.Sprintf("C source files not allowed when not using cgo or SWIG: %s", strings.Join(p.CFiles, " ")),
 		}
 		return p
 	}
@@ -660,6 +996,7 @@
 		}
 	}
 
+	computeBuildID(p)
 	return p
 }
 
@@ -698,13 +1035,8 @@
 // computeStale computes the Stale flag in the package dag that starts
 // at the named pkgs (command-line arguments).
 func computeStale(pkgs ...*Package) {
-	topRoot := map[string]bool{}
-	for _, p := range pkgs {
-		topRoot[p.Root] = true
-	}
-
 	for _, p := range packageList(pkgs) {
-		p.Stale = isStale(p, topRoot)
+		p.Stale = isStale(p)
 	}
 }
 
@@ -714,8 +1046,269 @@
 // inspecting the version.
 var isGoRelease = strings.HasPrefix(runtime.Version(), "go1")
 
+// isStale and computeBuildID
+//
+// Theory of Operation
+//
+// There is an installed copy of the package (or binary).
+// Can we reuse the installed copy, or do we need to build a new one?
+//
+// We can use the installed copy if it matches what we'd get
+// by building a new one. The hard part is predicting that without
+// actually running a build.
+//
+// To start, we must know the set of inputs to the build process that can
+// affect the generated output. At a minimum, that includes the source
+// files for the package and also any compiled packages imported by those
+// source files. The *Package has these, and we use them. One might also
+// argue for including in the input set: the build tags, whether the race
+// detector is in use, the target operating system and architecture, the
+// compiler and linker binaries being used, the additional flags being
+// passed to those, the cgo binary being used, the additional flags cgo
+// passes to the host C compiler, the host C compiler being used, the set
+// of host C include files and installed C libraries, and so on.
+// We include some but not all of this information.
+//
+// Once we have decided on a set of inputs, we must next decide how to
+// tell whether the content of that set has changed since the last build
+// of p. If there have been no changes, then we assume a new build would
+// produce the same result and reuse the installed package or binary.
+// But if there have been changes, then we assume a new build might not
+// produce the same result, so we rebuild.
+//
+// There are two common ways to decide whether the content of the set has
+// changed: modification times and content hashes. We use a mixture of both.
+//
+// The use of modification times (mtimes) was pioneered by make:
+// assuming that a file's mtime is an accurate record of when that file was last written,
+// and assuming that the modification time of an installed package or
+// binary is the time that it was built, if the mtimes of the inputs
+// predate the mtime of the installed object, then the build of that
+// object saw those versions of the files, and therefore a rebuild using
+// those same versions would produce the same object. In contrast, if any
+// mtime of an input is newer than the mtime of the installed object, a
+// change has occurred since the build, and the build should be redone.
+//
+// Modification times are attractive because the logic is easy to
+// understand and the file system maintains the mtimes automatically
+// (less work for us). Unfortunately, there are a variety of ways in
+// which the mtime approach fails to detect a change and reuses a stale
+// object file incorrectly. (Making the opposite mistake, rebuilding
+// unnecessarily, is only a performance problem and not a correctness
+// problem, so we ignore that one.)
+//
+// As a warmup, one problem is that to be perfectly precise, we need to
+// compare the input mtimes against the time at the beginning of the
+// build, but the object file time is the time at the end of the build.
+// If an input file changes after being read but before the object is
+// written, the next build will see an object newer than the input and
+// will incorrectly decide that the object is up to date. We make no
+// attempt to detect or solve this problem.
+//
+// Another problem is that due to file system imprecision, an input and
+// output that are actually ordered in time have the same mtime.
+// This typically happens on file systems with 1-second (or, worse,
+// 2-second) mtime granularity and with automated scripts that write an
+// input and then immediately run a build, or vice versa. If an input and
+// an output have the same mtime, the conservative behavior is to treat
+// the output as out-of-date and rebuild. This can cause one or more
+// spurious rebuilds, but only for 1 second, until the object finally has
+// an mtime later than the input.
+//
+// Another problem is that binary distributions often set the mtime on
+// all files to the same time. If the distribution includes both inputs
+// and cached build outputs, the conservative solution to the previous
+// problem will cause unnecessary rebuilds. Worse, in such a binary
+// distribution, those rebuilds might not even have permission to update
+// the cached build output. To avoid these write errors, if an input and
+// output have the same mtime, we assume the output is up-to-date.
+// This is the opposite of what the previous problem would have us do,
+// but binary distributions are more common than instances of the
+// previous problem.
+//
+// A variant of the last problem is that some binary distributions do not
+// set the mtime on all files to the same time. Instead they let the file
+// system record mtimes as the distribution is unpacked. If the outputs
+// are unpacked before the inputs, they'll be older and a build will try
+// to rebuild them. That rebuild might hit the same write errors as in
+// the last scenario. We don't make any attempt to solve this, and we
+// haven't had many reports of it. Perhaps the only time this happens is
+// when people manually unpack the distribution, and most of the time
+// that's done as the same user who will be using it, so an initial
+// rebuild on first use succeeds quietly.
+//
+// More generally, people and programs change mtimes on files. The last
+// few problems were specific examples of this, but it's a general problem.
+// For example, instead of a binary distribution, copying a home
+// directory from one directory or machine to another might copy files
+// but not preserve mtimes. If the inputs are new than the outputs on the
+// first machine but copied first, they end up older than the outputs on
+// the second machine.
+//
+// Because many other build systems have the same sensitivity to mtimes,
+// most programs manipulating source code take pains not to break the
+// mtime assumptions. For example, Git does not set the mtime of files
+// during a checkout operation, even when checking out an old version of
+// the code. This decision was made specifically to work well with
+// mtime-based build systems.
+//
+// The killer problem, though, for mtime-based build systems is that the
+// build only has access to the mtimes of the inputs that still exist.
+// If it is possible to remove an input without changing any other inputs,
+// a later build will think the object is up-to-date when it is not.
+// This happens for Go because a package is made up of all source
+// files in a directory. If a source file is removed, there is no newer
+// mtime available recording that fact. The mtime on the directory could
+// be used, but it also changes when unrelated files are added to or
+// removed from the directory, so including the directory mtime would
+// cause unnecessary rebuilds, possibly many. It would also exacerbate
+// the problems mentioned earlier, since even programs that are careful
+// to maintain mtimes on files rarely maintain mtimes on directories.
+//
+// A variant of the last problem is when the inputs change for other
+// reasons. For example, Go 1.4 and Go 1.5 both install $GOPATH/src/mypkg
+// into the same target, $GOPATH/pkg/$GOOS_$GOARCH/mypkg.a.
+// If Go 1.4 has built mypkg into mypkg.a, a build using Go 1.5 must
+// rebuild mypkg.a, but from mtimes alone mypkg.a looks up-to-date.
+// If Go 1.5 has just been installed, perhaps the compiler will have a
+// newer mtime; since the compiler is considered an input, that would
+// trigger a rebuild. But only once, and only the last Go 1.4 build of
+// mypkg.a happened before Go 1.5 was installed. If a user has the two
+// versions installed in different locations and flips back and forth,
+// mtimes alone cannot tell what to do. Changing the toolchain is
+// changing the set of inputs, without affecting any mtimes.
+//
+// To detect the set of inputs changing, we turn away from mtimes and to
+// an explicit data comparison. Specifically, we build a list of the
+// inputs to the build, compute its SHA1 hash, and record that as the
+// ``build ID'' in the generated object. At the next build, we can
+// recompute the buid ID and compare it to the one in the generated
+// object. If they differ, the list of inputs has changed, so the object
+// is out of date and must be rebuilt.
+//
+// Because this build ID is computed before the build begins, the
+// comparison does not have the race that mtime comparison does.
+//
+// Making the build sensitive to changes in other state is
+// straightforward: include the state in the build ID hash, and if it
+// changes, so does the build ID, triggering a rebuild.
+//
+// To detect changes in toolchain, we include the toolchain version in
+// the build ID hash for package runtime, and then we include the build
+// IDs of all imported packages in the build ID for p.
+//
+// It is natural to think about including build tags in the build ID, but
+// the naive approach of just dumping the tags into the hash would cause
+// spurious rebuilds. For example, 'go install' and 'go install -tags neverusedtag'
+// produce the same binaries (assuming neverusedtag is never used).
+// A more precise approach would be to include only tags that have an
+// effect on the build. But the effect of a tag on the build is to
+// include or exclude a file from the compilation, and that file list is
+// already in the build ID hash. So the build ID is already tag-sensitive
+// in a perfectly precise way. So we do NOT explicitly add build tags to
+// the build ID hash.
+//
+// We do not include as part of the build ID the operating system,
+// architecture, or whether the race detector is enabled, even though all
+// three have an effect on the output, because that information is used
+// to decide the install location. Binaries for linux and binaries for
+// darwin are written to different directory trees; including that
+// information in the build ID is unnecessary (although it would be
+// harmless).
+//
+// TODO(rsc): Investigate the cost of putting source file content into
+// the build ID hash as a replacement for the use of mtimes. Using the
+// file content would avoid all the mtime problems, but it does require
+// reading all the source files, something we avoid today (we read the
+// beginning to find the build tags and the imports, but we stop as soon
+// as we see the import block is over). If the package is stale, the compiler
+// is going to read the files anyway. But if the package is up-to-date, the
+// read is overhead.
+//
+// TODO(rsc): Investigate the complexity of making the build more
+// precise about when individual results are needed. To be fully precise,
+// there are two results of a compilation: the entire .a file used by the link
+// and the subpiece used by later compilations (__.PKGDEF only).
+// If a rebuild is needed but produces the previous __.PKGDEF, then
+// no more recompilation due to the rebuilt package is needed, only
+// relinking. To date, there is nothing in the Go command to express this.
+//
+// Special Cases
+//
+// When the go command makes the wrong build decision and does not
+// rebuild something it should, users fall back to adding the -a flag.
+// Any common use of the -a flag should be considered prima facie evidence
+// that isStale is returning an incorrect false result in some important case.
+// Bugs reported in the behavior of -a itself should prompt the question
+// ``Why is -a being used at all? What bug does that indicate?''
+//
+// There is a long history of changes to isStale to try to make -a into a
+// suitable workaround for bugs in the mtime-based decisions.
+// It is worth recording that history to inform (and, as much as possible, deter) future changes.
+//
+// (1) Before the build IDs were introduced, building with alternate tags
+// would happily reuse installed objects built without those tags.
+// For example, "go build -tags netgo myprog.go" would use the installed
+// copy of package net, even if that copy had been built without netgo.
+// (The netgo tag controls whether package net uses cgo or pure Go for
+// functionality such as name resolution.)
+// Using the installed non-netgo package defeats the purpose.
+//
+// Users worked around this with "go build -tags netgo -a myprog.go".
+//
+// Build IDs have made that workaround unnecessary:
+// "go build -tags netgo myprog.go"
+// cannot use a non-netgo copy of package net.
+//
+// (2) Before the build IDs were introduced, building with different toolchains,
+// especially changing between toolchains, tried to reuse objects stored in
+// $GOPATH/pkg, resulting in link-time errors about object file mismatches.
+//
+// Users worked around this with "go install -a ./...".
+//
+// Build IDs have made that workaround unnecessary:
+// "go install ./..." will rebuild any objects it finds that were built against
+// a different toolchain.
+//
+// (3) The common use of "go install -a ./..." led to reports of problems
+// when the -a forced the rebuild of the standard library, which for some
+// users was not writable. Because we didn't understand that the real
+// problem was the bug -a was working around, we changed -a not to
+// apply to the standard library.
+//
+// (4) The common use of "go build -tags netgo -a myprog.go" broke
+// when we changed -a not to apply to the standard library, because
+// if go build doesn't rebuild package net, it uses the non-netgo version.
+//
+// Users worked around this with "go build -tags netgo -installsuffix barf myprog.go".
+// The -installsuffix here is making the go command look for packages
+// in pkg/$GOOS_$GOARCH_barf instead of pkg/$GOOS_$GOARCH.
+// Since the former presumably doesn't exist, go build decides to rebuild
+// everything, including the standard library. Since go build doesn't
+// install anything it builds, nothing is ever written to pkg/$GOOS_$GOARCH_barf,
+// so repeated invocations continue to work.
+//
+// If the use of -a wasn't a red flag, the use of -installsuffix to point to
+// a non-existent directory in a command that installs nothing should
+// have been.
+//
+// (5) Now that (1) and (2) no longer need -a, we have removed the kludge
+// introduced in (3): once again, -a means ``rebuild everything,'' not
+// ``rebuild everything except the standard library.'' Only Go 1.4 had
+// the restricted meaning.
+//
+// In addition to these cases trying to trigger rebuilds, there are
+// special cases trying NOT to trigger rebuilds. The main one is that for
+// a variety of reasons (see above), the install process for a Go release
+// cannot be relied upon to set the mtimes such that the go command will
+// think the standard library is up to date. So the mtime evidence is
+// ignored for the standard library if we find ourselves in a release
+// version of Go. Build ID-based staleness checks still apply to the
+// standard library, even in release versions. This makes
+// 'go build -tags netgo' work, among other things.
+
 // isStale reports whether package p needs to be rebuilt.
-func isStale(p *Package, topRoot map[string]bool) bool {
+func isStale(p *Package) bool {
 	if p.Standard && (p.ImportPath == "unsafe" || buildContext.Compiler == "gccgo") {
 		// fake, builtin package
 		return false
@@ -734,28 +1327,68 @@
 		return false
 	}
 
-	// If we are running a release copy of Go, do not rebuild the standard packages.
-	// They may not be writable anyway, but they are certainly not changing.
-	// This makes 'go build -a' skip the standard packages when using an official release.
-	// See issue 4106 and issue 8290.
-	pkgBuildA := buildA
-	if p.Standard && isGoRelease {
-		pkgBuildA = false
+	// If the -a flag is given, rebuild everything.
+	if buildA {
+		return true
 	}
 
-	if pkgBuildA || p.target == "" || p.Stale {
+	// If there's no install target or it's already marked stale, we have to rebuild.
+	if p.target == "" || p.Stale {
 		return true
 	}
 
 	// Package is stale if completely unbuilt.
-	var built time.Time
-	if fi, err := os.Stat(p.target); err == nil {
-		built = fi.ModTime()
-	}
-	if built.IsZero() {
+	fi, err := os.Stat(p.target)
+	if err != nil {
 		return true
 	}
 
+	// Package is stale if the expected build ID differs from the
+	// recorded build ID. This catches changes like a source file
+	// being removed from a package directory. See issue 3895.
+	// It also catches changes in build tags that affect the set of
+	// files being compiled. See issue 9369.
+	// It also catches changes in toolchain, like when flipping between
+	// two versions of Go compiling a single GOPATH.
+	// See issue 8290 and issue 10702.
+	targetBuildID, err := readBuildID(p)
+	if err == nil && targetBuildID != p.buildID {
+		return true
+	}
+
+	// Package is stale if a dependency is.
+	for _, p1 := range p.deps {
+		if p1.Stale {
+			return true
+		}
+	}
+
+	// The checks above are content-based staleness.
+	// We assume they are always accurate.
+	//
+	// The checks below are mtime-based staleness.
+	// We hope they are accurate, but we know that they fail in the case of
+	// prebuilt Go installations that don't preserve the build mtimes
+	// (for example, if the pkg/ mtimes are before the src/ mtimes).
+	// See the large comment above isStale for details.
+
+	// If we are running a release copy of Go and didn't find a content-based
+	// reason to rebuild the standard packages, do not rebuild them.
+	// They may not be writable anyway, but they are certainly not changing.
+	// This makes 'go build' skip the standard packages when
+	// using an official release, even when the mtimes have been changed.
+	// See issue 3036, issue 3149, issue 4106, issue 8290.
+	// (If a change to a release tree must be made by hand, the way to force the
+	// install is to run make.bash, which will remove the old package archives
+	// before rebuilding.)
+	if p.Standard && isGoRelease {
+		return false
+	}
+
+	// Time-based staleness.
+
+	built := fi.ModTime()
+
 	olderThan := func(file string) bool {
 		fi, err := os.Stat(file)
 		return err != nil || fi.ModTime().After(built)
@@ -763,7 +1396,7 @@
 
 	// Package is stale if a dependency is, or if a dependency is newer.
 	for _, p1 := range p.deps {
-		if p1.Stale || p1.target != "" && olderThan(p1.target) {
+		if p1.target != "" && olderThan(p1.target) {
 			return true
 		}
 	}
@@ -775,8 +1408,12 @@
 	// back-dated, as some binary distributions may do, but it does handle
 	// a very common case.
 	// See issue 3036.
-	// Assume code in $GOROOT is up to date, since it may not be writeable.
-	// See issue 4106.
+	// Exclude $GOROOT, under the assumption that people working on
+	// the compiler may want to control when everything gets rebuilt,
+	// and people updating the Go repository will run make.bash or all.bash
+	// and get a full rebuild anyway.
+	// Excluding $GOROOT used to also fix issue 4106, but that's now
+	// taken care of above (at least when the installed Go is a released version).
 	if p.Root != goroot {
 		if olderThan(buildToolchain.compiler()) {
 			return true
@@ -786,19 +1423,43 @@
 		}
 	}
 
-	// Have installed copy, probably built using current compilers,
-	// and built after its imported packages.  The only reason now
-	// that we'd have to rebuild it is if the sources were newer than
-	// the package.   If a package p is not in the same tree as any
-	// package named on the command-line, assume it is up-to-date
-	// no matter what the modification times on the source files indicate.
-	// This avoids rebuilding $GOROOT packages when people are
-	// working outside the Go root, and it effectively makes each tree
-	// listed in $GOPATH a separate compilation world.
-	// See issue 3149.
-	if p.Root != "" && !topRoot[p.Root] {
-		return false
-	}
+	// Note: Until Go 1.5, we had an additional shortcut here.
+	// We built a list of the workspace roots ($GOROOT, each $GOPATH)
+	// containing targets directly named on the command line,
+	// and if p were not in any of those, it would be treated as up-to-date
+	// as long as it is built. The goal was to avoid rebuilding a system-installed
+	// $GOROOT, unless something from $GOROOT were explicitly named
+	// on the command line (like go install math).
+	// That's now handled by the isGoRelease clause above.
+	// The other effect of the shortcut was to isolate different entries in
+	// $GOPATH from each other. This had the unfortunate effect that
+	// if you had (say), GOPATH listing two entries, one for commands
+	// and one for libraries, and you did a 'git pull' in the library one
+	// and then tried 'go install commands/...', it would build the new libraries
+	// during the first build (because they wouldn't have been installed at all)
+	// but then subsequent builds would not rebuild the libraries, even if the
+	// mtimes indicate they are stale, because the different GOPATH entries
+	// were treated differently. This behavior was confusing when using
+	// non-trivial GOPATHs, which were particularly common with some
+	// code management conventions, like the original godep.
+	// Since the $GOROOT case (the original motivation) is handled separately,
+	// we no longer put a barrier between the different $GOPATH entries.
+	//
+	// One implication of this is that if there is a system directory for
+	// non-standard Go packages that is included in $GOPATH, the mtimes
+	// on those compiled packages must be no earlier than the mtimes
+	// on the source files. Since most distributions use the same mtime
+	// for all files in a tree, they will be unaffected. People using plain
+	// tar x to extract system-installed packages will need to adjust mtimes,
+	// but it's better to force them to get the mtimes right than to ignore
+	// the mtimes and thereby do the wrong thing in common use cases.
+	//
+	// So there is no GOPATH vs GOPATH shortcut here anymore.
+	//
+	// If something needs to come back here, we could try writing a dummy
+	// file with a random name to the $GOPATH/pkg directory (and removing it)
+	// to test for write access, and then skip GOPATH roots we don't have write
+	// access to. But hopefully we can just use the mtimes always.
 
 	srcs := stringList(p.GoFiles, p.CFiles, p.CXXFiles, p.MFiles, p.HFiles, p.SFiles, p.CgoFiles, p.SysoFiles, p.SwigFiles, p.SwigCXXFiles)
 	for _, src := range srcs {
@@ -810,6 +1471,53 @@
 	return false
 }
 
+// computeBuildID computes the build ID for p, leaving it in p.buildID.
+// Build ID is a hash of the information we want to detect changes in.
+// See the long comment in isStale for details.
+func computeBuildID(p *Package) {
+	h := sha1.New()
+
+	// Include the list of files compiled as part of the package.
+	// This lets us detect removed files. See issue 3895.
+	inputFiles := stringList(
+		p.GoFiles,
+		p.CgoFiles,
+		p.CFiles,
+		p.CXXFiles,
+		p.MFiles,
+		p.HFiles,
+		p.SFiles,
+		p.SysoFiles,
+		p.SwigFiles,
+		p.SwigCXXFiles,
+	)
+	for _, file := range inputFiles {
+		fmt.Fprintf(h, "file %s\n", file)
+	}
+
+	// Include the content of runtime/zversion.go in the hash
+	// for package runtime. This will give package runtime a
+	// different build ID in each Go release.
+	if p.Standard && p.ImportPath == "runtime" {
+		data, _ := ioutil.ReadFile(filepath.Join(p.Dir, "zversion.go"))
+		fmt.Fprintf(h, "zversion %q\n", string(data))
+	}
+
+	// Include the build IDs of any dependencies in the hash.
+	// This, combined with the runtime/zversion content,
+	// will cause packages to have different build IDs when
+	// compiled with different Go releases.
+	// This helps the go command know to recompile when
+	// people use the same GOPATH but switch between
+	// different Go releases. See issue 10702.
+	// This is also a better fix for issue 8290.
+	for _, p1 := range p.deps {
+		fmt.Fprintf(h, "dep %s %s\n", p1.ImportPath, p1.buildID)
+	}
+
+	p.buildID = fmt.Sprintf("%x", h.Sum(nil))
+}
+
 var cwd, _ = os.Getwd()
 
 var cmdCache = map[string]*Package{}
@@ -872,7 +1580,7 @@
 		}
 	}
 
-	return loadImport(arg, cwd, stk, nil)
+	return loadImport(arg, cwd, nil, stk, nil, 0)
 }
 
 // packages returns the packages named by the
@@ -942,6 +1650,23 @@
 		}
 	}
 	exitIfErrors()
+
+	// Check for duplicate loads of the same package.
+	// That should be impossible, but if it does happen then
+	// we end up trying to build the same package twice,
+	// usually in parallel overwriting the same files,
+	// which doesn't work very well.
+	seen := map[string]bool{}
+	reported := map[string]bool{}
+	for _, pkg := range packageList(pkgs) {
+		if seen[pkg.ImportPath] && !reported[pkg.ImportPath] {
+			reported[pkg.ImportPath] = true
+			errorf("internal error: duplicate loads of %s", pkg.ImportPath)
+		}
+		seen[pkg.ImportPath] = true
+	}
+	exitIfErrors()
+
 	return pkgs
 }
 
@@ -967,3 +1692,170 @@
 	}
 	return filepath.ToSlash(dir[len(root):]), true
 }
+
+var (
+	errBuildIDToolchain = fmt.Errorf("build ID only supported in gc toolchain")
+	errBuildIDMalformed = fmt.Errorf("malformed object file")
+	errBuildIDUnknown   = fmt.Errorf("lost build ID")
+)
+
+var (
+	bangArch = []byte("!<arch>")
+	pkgdef   = []byte("__.PKGDEF")
+	goobject = []byte("go object ")
+	buildid  = []byte("build id ")
+)
+
+// readBuildID reads the build ID from an archive or binary.
+// It only supports the gc toolchain.
+// Other toolchain maintainers should adjust this function.
+func readBuildID(p *Package) (id string, err error) {
+	if buildToolchain != (gcToolchain{}) {
+		return "", errBuildIDToolchain
+	}
+
+	// For commands, read build ID directly from binary.
+	if p.Name == "main" {
+		return ReadBuildIDFromBinary(p.Target)
+	}
+
+	// Otherwise, we expect to have an archive (.a) file,
+	// and we can read the build ID from the Go export data.
+	if !strings.HasSuffix(p.Target, ".a") {
+		return "", &os.PathError{Op: "parse", Path: p.Target, Err: errBuildIDUnknown}
+	}
+
+	// Read just enough of the target to fetch the build ID.
+	// The archive is expected to look like:
+	//
+	//	!<arch>
+	//	__.PKGDEF       0           0     0     644     7955      `
+	//	go object darwin amd64 devel X:none
+	//	build id "b41e5c45250e25c9fd5e9f9a1de7857ea0d41224"
+	//
+	// The variable-sized strings are GOOS, GOARCH, and the experiment list (X:none).
+	// Reading the first 1024 bytes should be plenty.
+	f, err := os.Open(p.Target)
+	if err != nil {
+		return "", err
+	}
+	data := make([]byte, 1024)
+	n, err := io.ReadFull(f, data)
+	f.Close()
+
+	if err != nil && n == 0 {
+		return "", err
+	}
+
+	bad := func() (string, error) {
+		return "", &os.PathError{Op: "parse", Path: p.Target, Err: errBuildIDMalformed}
+	}
+
+	// Archive header.
+	for i := 0; ; i++ { // returns during i==3
+		j := bytes.IndexByte(data, '\n')
+		if j < 0 {
+			return bad()
+		}
+		line := data[:j]
+		data = data[j+1:]
+		switch i {
+		case 0:
+			if !bytes.Equal(line, bangArch) {
+				return bad()
+			}
+		case 1:
+			if !bytes.HasPrefix(line, pkgdef) {
+				return bad()
+			}
+		case 2:
+			if !bytes.HasPrefix(line, goobject) {
+				return bad()
+			}
+		case 3:
+			if !bytes.HasPrefix(line, buildid) {
+				// Found the object header, just doesn't have a build id line.
+				// Treat as successful, with empty build id.
+				return "", nil
+			}
+			id, err := strconv.Unquote(string(line[len(buildid):]))
+			if err != nil {
+				return bad()
+			}
+			return id, nil
+		}
+	}
+}
+
+var (
+	goBuildPrefix = []byte("\xff Go build ID: \"")
+	goBuildEnd    = []byte("\"\n \xff")
+
+	elfPrefix = []byte("\x7fELF")
+)
+
+// ReadBuildIDFromBinary reads the build ID from a binary.
+//
+// ELF binaries store the build ID in a proper PT_NOTE section.
+//
+// Other binary formats are not so flexible. For those, the linker
+// stores the build ID as non-instruction bytes at the very beginning
+// of the text segment, which should appear near the beginning
+// of the file. This is clumsy but fairly portable. Custom locations
+// can be added for other binary types as needed, like we did for ELF.
+func ReadBuildIDFromBinary(filename string) (id string, err error) {
+	if filename == "" {
+		return "", &os.PathError{Op: "parse", Path: filename, Err: errBuildIDUnknown}
+	}
+
+	// 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 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
+	// world compiled for each different object format today:
+	//
+	//	Plan 9: 0x20
+	//	Windows: 0x600
+	//	Mach-O: 0x2000
+	//
+	f, err := os.Open(filename)
+	if err != nil {
+		return "", err
+	}
+	defer f.Close()
+
+	data := make([]byte, 16*1024)
+	_, err = io.ReadFull(f, data)
+	if err == io.ErrUnexpectedEOF {
+		err = nil
+	}
+	if err != nil {
+		return "", err
+	}
+
+	if bytes.HasPrefix(data, elfPrefix) {
+		return readELFGoBuildID(filename, f, data)
+	}
+
+	i := bytes.Index(data, goBuildPrefix)
+	if i < 0 {
+		// Missing. Treat as successful but build ID empty.
+		return "", nil
+	}
+
+	j := bytes.Index(data[i+len(goBuildPrefix):], goBuildEnd)
+	if j < 0 {
+		return "", &os.PathError{Op: "parse", Path: filename, Err: errBuildIDMalformed}
+	}
+
+	quoted := data[i+len(goBuildPrefix)-1 : i+len(goBuildPrefix)+j+1]
+	id, err = strconv.Unquote(string(quoted))
+	if err != nil {
+		return "", &os.PathError{Op: "parse", Path: filename, Err: errBuildIDMalformed}
+	}
+
+	return id, nil
+}
diff --git a/third_party/gofrontend/libgo/go/cmd/go/run.go b/third_party/gofrontend/libgo/go/cmd/go/run.go
index ef8aa95..f6da373 100644
--- a/third_party/gofrontend/libgo/go/cmd/go/run.go
+++ b/third_party/gofrontend/libgo/go/cmd/go/run.go
@@ -37,7 +37,8 @@
 A Go source file is defined to be a file ending in a literal ".go" suffix.
 
 By default, 'go run' runs the compiled binary directly: 'a.out arguments...'.
-If the -exec flag is given, 'go run' invokes the binary using xprog: 'xprog a.out arguments...'.
+If the -exec flag is given, 'go run' invokes the binary using xprog:
+	'xprog a.out arguments...'.
 If the -exec flag is not given, GOOS or GOARCH is different from the system
 default, and a program named go_$GOOS_$GOARCH_exec can be found
 on the current search path, 'go run' invokes the binary using that program,
@@ -64,6 +65,7 @@
 
 func runRun(cmd *Command, args []string) {
 	raceInit()
+	buildModeInit()
 	var b builder
 	b.init()
 	b.print = printStderr
@@ -136,6 +138,7 @@
 	cmd.Stdin = os.Stdin
 	cmd.Stdout = os.Stdout
 	cmd.Stderr = os.Stderr
+	cmd.Env = origEnv
 	startSigHandlers()
 	if err := cmd.Run(); err != nil {
 		errorf("%v", err)
diff --git a/third_party/gofrontend/libgo/go/cmd/go/test.go b/third_party/gofrontend/libgo/go/cmd/go/test.go
index 5cf7aaf..aadfdf6 100644
--- a/third_party/gofrontend/libgo/go/cmd/go/test.go
+++ b/third_party/gofrontend/libgo/go/cmd/go/test.go
@@ -33,9 +33,11 @@
 	cmdTest.Run = runTest
 }
 
+const testUsage = "test [-c] [-i] [build and test flags] [packages] [flags for test binary]"
+
 var cmdTest = &Command{
 	CustomFlags: true,
-	UsageLine:   "test [-c] [-i] [build and test flags] [packages] [flags for test binary]",
+	UsageLine:   testUsage,
 	Short:       "test packages",
 	Long: `
 'Go test' automates testing the packages named by the import paths.
@@ -64,6 +66,21 @@
 The package is built in a temporary directory so it does not interfere with the
 non-test installation.
 
+` + strings.TrimSpace(testFlag1) + ` See 'go help testflag' for details.
+
+If the test binary needs any other flags, they should be presented after the
+package names. The go tool treats as a flag the first argument that begins with
+a minus sign that it does not recognize itself; that argument and all subsequent
+arguments are passed as arguments to the test binary.
+
+For more about build flags, see 'go help build'.
+For more about specifying packages, see 'go help packages'.
+
+See also: go build, go vet.
+`,
+}
+
+const testFlag1 = `
 In addition to the build flags, the flags handled by 'go test' itself are:
 
 	-c
@@ -83,21 +100,9 @@
 		Compile the test binary to the named file.
 		The test still runs (unless -c or -i is specified).
 
-
 The test binary also accepts flags that control execution of the test; these
-flags are also accessible by 'go test'.  See 'go help testflag' for details.
-
-If the test binary needs any other flags, they should be presented after the
-package names. The go tool treats as a flag the first argument that begins with
-a minus sign that it does not recognize itself; that argument and all subsequent
-arguments are passed as arguments to the test binary.
-
-For more about build flags, see 'go help build'.
-For more about specifying packages, see 'go help packages'.
-
-See also: go build, go vet.
-`,
-}
+flags are also accessible by 'go test'.
+`
 
 var helpTestflag = &Command{
 	UsageLine: "testflag",
@@ -107,13 +112,18 @@
 and flags that apply to the resulting test binary.
 
 Several of the flags control profiling and write an execution profile
-suitable for "go tool pprof"; run "go tool pprof help" for more
+suitable for "go tool pprof"; run "go tool pprof -h" for more
 information.  The --alloc_space, --alloc_objects, and --show_bytes
 options of pprof control how the information is presented.
 
 The following flags are recognized by the 'go test' command and
 control the execution of any test:
 
+	` + strings.TrimSpace(testFlag2) + `
+`,
+}
+
+const testFlag2 = `
 	-bench regexp
 	    Run benchmarks matching the regular expression.
 	    By default, no benchmarks run. To run all benchmarks,
@@ -135,12 +145,17 @@
 	-blockprofilerate n
 	    Control the detail provided in goroutine blocking profiles by
 	    calling runtime.SetBlockProfileRate with n.
-	    See 'godoc runtime SetBlockProfileRate'.
+	    See 'go doc runtime.SetBlockProfileRate'.
 	    The profiler aims to sample, on average, one blocking event every
 	    n nanoseconds the program spends blocked.  By default,
 	    if -test.blockprofile is set without this flag, all blocking events
 	    are recorded, equivalent to -test.blockprofilerate=1.
 
+	-count n
+	    Run each test and benchmark n times (default 1).
+	    If -cpu is set, run n times for each GOMAXPROCS value.
+	    Examples are always run once.
+
 	-cover
 	    Enable coverage analysis.
 
@@ -180,7 +195,7 @@
 
 	-memprofilerate n
 	    Enable more precise (and expensive) memory profiles by setting
-	    runtime.MemProfileRate.  See 'godoc runtime MemProfileRate'.
+	    runtime.MemProfileRate.  See 'go doc runtime.MemProfileRate'.
 	    To profile all memory allocations, use -test.memprofilerate=1
 	    and pass --alloc_space flag to the pprof tool.
 
@@ -205,6 +220,11 @@
 
 	-timeout t
 	    If a test runs longer than t, panic.
+	    The default is 10 minutes (10m).
+
+	-trace trace.out
+	    Write an execution trace to the specified file before exiting.
+	    Writes test binary as -c would.
 
 	-v
 	    Verbose output: log all tests as they are run. Also print all
@@ -229,8 +249,7 @@
 leave the test binary in pkg.test for use when analyzing the profiles.
 
 Flags not recognized by 'go test' must be placed after any specified packages.
-`,
-}
+`
 
 var helpTestfunc = &Command{
 	UsageLine: "testfunc",
@@ -310,6 +329,7 @@
 	findExecCmd() // initialize cached result
 
 	raceInit()
+	buildModeInit()
 	pkgs := packagesForBuild(pkgArgs)
 	if len(pkgs) == 0 {
 		fatalf("no packages to test")
@@ -342,11 +362,11 @@
 	// been given on the command line (implicit current directory)
 	// or when benchmarking.
 	// Also stream if we're showing output anyway with a
-	// single package under test.  In that case, streaming the
-	// output produces the same result as not streaming,
-	// just more immediately.
+	// single package under test or if parallelism is set to 1.
+	// In these cases, streaming the output produces the same result
+	// as not streaming, just more immediately.
 	testStreamOutput = len(pkgArgs) == 0 || testBench ||
-		(len(pkgs) <= 1 && testShowPass)
+		(testShowPass && (len(pkgs) == 1 || buildP == 1))
 
 	var b builder
 	b.init()
@@ -364,10 +384,10 @@
 			for _, path := range p.Imports {
 				deps[path] = true
 			}
-			for _, path := range p.TestImports {
+			for _, path := range p.vendored(p.TestImports) {
 				deps[path] = true
 			}
-			for _, path := range p.XTestImports {
+			for _, path := range p.vendored(p.XTestImports) {
 				deps[path] = true
 			}
 		}
@@ -376,7 +396,7 @@
 		if deps["C"] {
 			delete(deps, "C")
 			deps["runtime/cgo"] = true
-			if buildContext.GOOS == runtime.GOOS && buildContext.GOARCH == runtime.GOARCH {
+			if goos == runtime.GOOS && goarch == runtime.GOARCH && !buildRace {
 				deps["cmd/cgo"] = true
 			}
 		}
@@ -428,6 +448,10 @@
 
 		// Mark all the coverage packages for rebuilding with coverage.
 		for _, p := range testCoverPkgs {
+			// There is nothing to cover in package unsafe; it comes from the compiler.
+			if p.ImportPath == "unsafe" {
+				continue
+			}
 			p.Stale = true // rebuild
 			p.fake = true  // do not warn about rebuild
 			p.coverMode = testCoverMode
@@ -562,15 +586,20 @@
 	var imports, ximports []*Package
 	var stk importStack
 	stk.push(p.ImportPath + " (test)")
-	for _, path := range p.TestImports {
-		p1 := loadImport(path, p.Dir, &stk, p.build.TestImportPos[path])
+	for i, path := range p.TestImports {
+		p1 := loadImport(path, p.Dir, p, &stk, p.build.TestImportPos[path], useVendor)
 		if !reqStdPkgSrc && p1.Standard {
 			continue
 		}
 		if p1.Error != nil {
 			return nil, nil, nil, p1.Error
 		}
-		if contains(p1.Deps, p.ImportPath) {
+		if len(p1.DepsErrors) > 0 {
+			err := p1.DepsErrors[0]
+			err.Pos = "" // show full import stack
+			return nil, nil, nil, err
+		}
+		if contains(p1.Deps, p.ImportPath) || p1.ImportPath == p.ImportPath {
 			// Same error that loadPackage returns (via reusePackage) in pkg.go.
 			// Can't change that code, because that code is only for loading the
 			// non-test copy of a package.
@@ -581,24 +610,31 @@
 			}
 			return nil, nil, nil, err
 		}
+		p.TestImports[i] = p1.ImportPath
 		imports = append(imports, p1)
 	}
 	stk.pop()
 	stk.push(p.ImportPath + "_test")
 	pxtestNeedsPtest := false
-	for _, path := range p.XTestImports {
-		if path == p.ImportPath {
-			pxtestNeedsPtest = true
-			continue
-		}
-		p1 := loadImport(path, p.Dir, &stk, p.build.XTestImportPos[path])
+	for i, path := range p.XTestImports {
+		p1 := loadImport(path, p.Dir, p, &stk, p.build.XTestImportPos[path], useVendor)
 		if !reqStdPkgSrc && p1.Standard {
 			continue
 		}
 		if p1.Error != nil {
 			return nil, nil, nil, p1.Error
 		}
-		ximports = append(ximports, p1)
+		if len(p1.DepsErrors) > 0 {
+			err := p1.DepsErrors[0]
+			err.Pos = "" // show full import stack
+			return nil, nil, nil, err
+		}
+		if p1.ImportPath == p.ImportPath {
+			pxtestNeedsPtest = true
+		} else {
+			ximports = append(ximports, p1)
+		}
+		p.XTestImports[i] = p1.ImportPath
 	}
 	stk.pop()
 
@@ -723,7 +759,7 @@
 		if dep == ptest.ImportPath {
 			pmain.imports = append(pmain.imports, ptest)
 		} else {
-			p1 := loadImport(dep, "", &stk, nil)
+			p1 := loadImport(dep, "", nil, &stk, nil, 0)
 			if !reqStdPkgSrc && p1.Standard {
 				continue
 			}
@@ -781,6 +817,12 @@
 		recompileForTest(pmain, p, ptest, testDir)
 	}
 
+	if buildContext.GOOS == "darwin" {
+		if buildContext.GOARCH == "arm" || buildContext.GOARCH == "arm64" {
+			t.NeedCgo = true
+		}
+	}
+
 	for _, cp := range pmain.imports {
 		if len(cp.coverVars) > 0 {
 			t.Cover = append(t.Cover, coverInfo{cp, cp.coverVars})
@@ -997,7 +1039,7 @@
 
 	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
@@ -1216,6 +1258,7 @@
 	NeedTest    bool
 	ImportXtest bool
 	NeedXtest   bool
+	NeedCgo     bool
 	Cover       []coverInfo
 }
 
@@ -1319,6 +1362,10 @@
 {{range $i, $p := .Cover}}
 	_cover{{$i}} {{$p.Package.ImportPath | printf "%q"}}
 {{end}}
+
+{{if .NeedCgo}}
+	_ "runtime/cgo"
+{{end}}
 )
 
 var tests = []testing.InternalTest{
diff --git a/third_party/gofrontend/libgo/go/cmd/go/testdata/generate/test3.go b/third_party/gofrontend/libgo/go/cmd/go/testdata/generate/test3.go
index 41ffb7e..3d6a8a5 100644
--- a/third_party/gofrontend/libgo/go/cmd/go/testdata/generate/test3.go
+++ b/third_party/gofrontend/libgo/go/cmd/go/testdata/generate/test3.go
@@ -4,6 +4,6 @@
 
 // Test go generate variable substitution.
 
-//go:generate echo $GOARCH $GOFILE $GOPACKAGE xyz$GOPACKAGE/$GOFILE/123
+//go:generate echo $GOARCH $GOFILE:$GOLINE ${GOPACKAGE}abc xyz$GOPACKAGE/$GOFILE/123
 
 package p
diff --git a/third_party/gofrontend/libgo/go/cmd/go/testdata/generate/test4.go b/third_party/gofrontend/libgo/go/cmd/go/testdata/generate/test4.go
new file mode 100644
index 0000000..a7631c4
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/cmd/go/testdata/generate/test4.go
@@ -0,0 +1,10 @@
+// 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.
+
+// Test -run flag
+
+//go:generate echo oh yes my man
+//go:generate echo no, no, a thousand times no
+
+package p
diff --git a/third_party/gofrontend/libgo/go/cmd/go/testdata/rundir/sub/sub.go b/third_party/gofrontend/libgo/go/cmd/go/testdata/rundir/sub/sub.go
new file mode 100644
index 0000000..06ab7d0
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/cmd/go/testdata/rundir/sub/sub.go
@@ -0,0 +1 @@
+package main
diff --git a/third_party/gofrontend/libgo/go/cmd/go/testdata/rundir/x.go b/third_party/gofrontend/libgo/go/cmd/go/testdata/rundir/x.go
new file mode 100644
index 0000000..06ab7d0
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/cmd/go/testdata/rundir/x.go
@@ -0,0 +1 @@
+package main
diff --git a/third_party/gofrontend/libgo/go/cmd/go/testdata/src/testcycle/q1/q1.go b/third_party/gofrontend/libgo/go/cmd/go/testdata/src/testcycle/q1/q1.go
new file mode 100644
index 0000000..7a471f0
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/cmd/go/testdata/src/testcycle/q1/q1.go
@@ -0,0 +1 @@
+package q1
diff --git a/third_party/gofrontend/libgo/go/cmd/go/testdata/src/testcycle/q1/q1_test.go b/third_party/gofrontend/libgo/go/cmd/go/testdata/src/testcycle/q1/q1_test.go
new file mode 100644
index 0000000..ca81bd2
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/cmd/go/testdata/src/testcycle/q1/q1_test.go
@@ -0,0 +1,6 @@
+package q1
+
+import "testing"
+import _ "testcycle/q1"
+
+func Test(t *testing.T) {}
diff --git a/third_party/gofrontend/libgo/go/cmd/go/testdata/src/testdep/p1/p1.go b/third_party/gofrontend/libgo/go/cmd/go/testdata/src/testdep/p1/p1.go
new file mode 100644
index 0000000..a457035
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/cmd/go/testdata/src/testdep/p1/p1.go
@@ -0,0 +1 @@
+package p1
diff --git a/third_party/gofrontend/libgo/go/cmd/go/testdata/src/testdep/p1/p1_test.go b/third_party/gofrontend/libgo/go/cmd/go/testdata/src/testdep/p1/p1_test.go
new file mode 100644
index 0000000..8be7533
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/cmd/go/testdata/src/testdep/p1/p1_test.go
@@ -0,0 +1,3 @@
+package p1
+
+import _ "testdep/p2"
diff --git a/third_party/gofrontend/libgo/go/cmd/go/testdata/src/testdep/p2/p2.go b/third_party/gofrontend/libgo/go/cmd/go/testdata/src/testdep/p2/p2.go
new file mode 100644
index 0000000..15ba2ea
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/cmd/go/testdata/src/testdep/p2/p2.go
@@ -0,0 +1,3 @@
+package p2
+
+import _ "testdep/p3"
diff --git a/third_party/gofrontend/libgo/go/cmd/go/testdata/src/testdep/p3/p3.go b/third_party/gofrontend/libgo/go/cmd/go/testdata/src/testdep/p3/p3.go
new file mode 100644
index 0000000..0219e7f
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/cmd/go/testdata/src/testdep/p3/p3.go
@@ -0,0 +1,3 @@
+// +build ignore
+
+package ignored
diff --git a/third_party/gofrontend/libgo/go/cmd/go/testdata/src/vend/bad.go b/third_party/gofrontend/libgo/go/cmd/go/testdata/src/vend/bad.go
new file mode 100644
index 0000000..57cc595
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/cmd/go/testdata/src/vend/bad.go
@@ -0,0 +1,3 @@
+package vend
+
+import _ "r"
diff --git a/third_party/gofrontend/libgo/go/cmd/go/testdata/src/vend/good.go b/third_party/gofrontend/libgo/go/cmd/go/testdata/src/vend/good.go
new file mode 100644
index 0000000..952ada3
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/cmd/go/testdata/src/vend/good.go
@@ -0,0 +1,3 @@
+package vend
+
+import _ "p"
diff --git a/third_party/gofrontend/libgo/go/cmd/go/testdata/src/vend/hello/hello.go b/third_party/gofrontend/libgo/go/cmd/go/testdata/src/vend/hello/hello.go
new file mode 100644
index 0000000..41dc03e
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/cmd/go/testdata/src/vend/hello/hello.go
@@ -0,0 +1,10 @@
+package main
+
+import (
+	"fmt"
+	"strings" // really ../vendor/strings
+)
+
+func main() {
+	fmt.Printf("%s\n", strings.Msg)
+}
diff --git a/third_party/gofrontend/libgo/go/cmd/go/testdata/src/vend/hello/hello_test.go b/third_party/gofrontend/libgo/go/cmd/go/testdata/src/vend/hello/hello_test.go
new file mode 100644
index 0000000..5e72ada
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/cmd/go/testdata/src/vend/hello/hello_test.go
@@ -0,0 +1,12 @@
+package main
+
+import (
+	"strings" // really ../vendor/strings
+	"testing"
+)
+
+func TestMsgInternal(t *testing.T) {
+	if strings.Msg != "hello, world" {
+		t.Fatal("unexpected msg: %v", strings.Msg)
+	}
+}
diff --git a/third_party/gofrontend/libgo/go/cmd/go/testdata/src/vend/hello/hellox_test.go b/third_party/gofrontend/libgo/go/cmd/go/testdata/src/vend/hello/hellox_test.go
new file mode 100644
index 0000000..96e6049
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/cmd/go/testdata/src/vend/hello/hellox_test.go
@@ -0,0 +1,12 @@
+package main_test
+
+import (
+	"strings" // really ../vendor/strings
+	"testing"
+)
+
+func TestMsgExternal(t *testing.T) {
+	if strings.Msg != "hello, world" {
+		t.Fatal("unexpected msg: %v", strings.Msg)
+	}
+}
diff --git a/third_party/gofrontend/libgo/go/cmd/go/testdata/src/vend/subdir/bad.go b/third_party/gofrontend/libgo/go/cmd/go/testdata/src/vend/subdir/bad.go
new file mode 100644
index 0000000..d0ddaac
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/cmd/go/testdata/src/vend/subdir/bad.go
@@ -0,0 +1,3 @@
+package subdir
+
+import _ "r"
diff --git a/third_party/gofrontend/libgo/go/cmd/go/testdata/src/vend/subdir/good.go b/third_party/gofrontend/libgo/go/cmd/go/testdata/src/vend/subdir/good.go
new file mode 100644
index 0000000..edd0454
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/cmd/go/testdata/src/vend/subdir/good.go
@@ -0,0 +1,3 @@
+package subdir
+
+import _ "p"
diff --git a/third_party/gofrontend/libgo/go/cmd/go/testdata/src/vend/vendor/p/p.go b/third_party/gofrontend/libgo/go/cmd/go/testdata/src/vend/vendor/p/p.go
new file mode 100644
index 0000000..c89cd18
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/cmd/go/testdata/src/vend/vendor/p/p.go
@@ -0,0 +1 @@
+package p
diff --git a/third_party/gofrontend/libgo/go/cmd/go/testdata/src/vend/vendor/q/q.go b/third_party/gofrontend/libgo/go/cmd/go/testdata/src/vend/vendor/q/q.go
new file mode 100644
index 0000000..946e6d9
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/cmd/go/testdata/src/vend/vendor/q/q.go
@@ -0,0 +1 @@
+package q
diff --git a/third_party/gofrontend/libgo/go/cmd/go/testdata/src/vend/vendor/strings/msg.go b/third_party/gofrontend/libgo/go/cmd/go/testdata/src/vend/vendor/strings/msg.go
new file mode 100644
index 0000000..438126b
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/cmd/go/testdata/src/vend/vendor/strings/msg.go
@@ -0,0 +1,3 @@
+package strings
+
+var Msg = "hello, world"
diff --git a/third_party/gofrontend/libgo/go/cmd/go/testdata/src/vend/x/invalid/invalid.go b/third_party/gofrontend/libgo/go/cmd/go/testdata/src/vend/x/invalid/invalid.go
new file mode 100644
index 0000000..e250d5b
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/cmd/go/testdata/src/vend/x/invalid/invalid.go
@@ -0,0 +1,3 @@
+package invalid
+
+import "vend/x/invalid/vendor/foo"
diff --git a/third_party/gofrontend/libgo/go/cmd/go/testdata/src/vend/x/vendor/p/p.go b/third_party/gofrontend/libgo/go/cmd/go/testdata/src/vend/x/vendor/p/p.go
new file mode 100644
index 0000000..c89cd18
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/cmd/go/testdata/src/vend/x/vendor/p/p.go
@@ -0,0 +1 @@
+package p
diff --git a/third_party/gofrontend/libgo/go/cmd/go/testdata/src/vend/x/vendor/p/p/p.go b/third_party/gofrontend/libgo/go/cmd/go/testdata/src/vend/x/vendor/p/p/p.go
new file mode 100644
index 0000000..e12e12c
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/cmd/go/testdata/src/vend/x/vendor/p/p/p.go
@@ -0,0 +1,3 @@
+package p
+
+import _ "notfound"
diff --git a/third_party/gofrontend/libgo/go/cmd/go/testdata/src/vend/x/vendor/r/r.go b/third_party/gofrontend/libgo/go/cmd/go/testdata/src/vend/x/vendor/r/r.go
new file mode 100644
index 0000000..838c177
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/cmd/go/testdata/src/vend/x/vendor/r/r.go
@@ -0,0 +1 @@
+package r
diff --git a/third_party/gofrontend/libgo/go/cmd/go/testdata/src/vend/x/x.go b/third_party/gofrontend/libgo/go/cmd/go/testdata/src/vend/x/x.go
new file mode 100644
index 0000000..ae526eb
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/cmd/go/testdata/src/vend/x/x.go
@@ -0,0 +1,5 @@
+package x
+
+import _ "p"
+import _ "q"
+import _ "r"
diff --git a/third_party/gofrontend/libgo/go/cmd/go/testdata/src/vetpkg/c.go b/third_party/gofrontend/libgo/go/cmd/go/testdata/src/vetpkg/c.go
new file mode 100644
index 0000000..ef5648f
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/cmd/go/testdata/src/vetpkg/c.go
@@ -0,0 +1,9 @@
+// +build tagtest
+
+package p
+
+import "fmt"
+
+func g() {
+	fmt.Printf("%d", 3, 4)
+}
diff --git a/third_party/gofrontend/libgo/go/cmd/go/testdata/testinternal3/t.go b/third_party/gofrontend/libgo/go/cmd/go/testdata/testinternal3/t.go
new file mode 100644
index 0000000..8576a4b
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/cmd/go/testdata/testinternal3/t.go
@@ -0,0 +1,3 @@
+package t
+
+import _ "internal/does-not-exist"
diff --git a/third_party/gofrontend/libgo/go/cmd/go/testdata/testinternal4/src/p/p.go b/third_party/gofrontend/libgo/go/cmd/go/testdata/testinternal4/src/p/p.go
new file mode 100644
index 0000000..6bdee27
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/cmd/go/testdata/testinternal4/src/p/p.go
@@ -0,0 +1,6 @@
+package p
+
+import (
+	_ "q/internal/x"
+	_ "q/j"
+)
diff --git a/third_party/gofrontend/libgo/go/cmd/go/testdata/testinternal4/src/q/internal/x/x.go b/third_party/gofrontend/libgo/go/cmd/go/testdata/testinternal4/src/q/internal/x/x.go
new file mode 100644
index 0000000..823aafd
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/cmd/go/testdata/testinternal4/src/q/internal/x/x.go
@@ -0,0 +1 @@
+package x
diff --git a/third_party/gofrontend/libgo/go/cmd/go/testdata/testinternal4/src/q/j/j.go b/third_party/gofrontend/libgo/go/cmd/go/testdata/testinternal4/src/q/j/j.go
new file mode 100644
index 0000000..9f07543
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/cmd/go/testdata/testinternal4/src/q/j/j.go
@@ -0,0 +1,3 @@
+package j
+
+import _ "q/internal/x"
diff --git a/third_party/gofrontend/libgo/go/cmd/go/testdata/testvendor/src/p/p.go b/third_party/gofrontend/libgo/go/cmd/go/testdata/testvendor/src/p/p.go
new file mode 100644
index 0000000..e740715
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/cmd/go/testdata/testvendor/src/p/p.go
@@ -0,0 +1,6 @@
+package p
+
+import (
+	_ "q/y"
+	_ "q/z"
+)
diff --git a/third_party/gofrontend/libgo/go/cmd/go/testdata/testvendor/src/q/vendor/x/x.go b/third_party/gofrontend/libgo/go/cmd/go/testdata/testvendor/src/q/vendor/x/x.go
new file mode 100644
index 0000000..823aafd
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/cmd/go/testdata/testvendor/src/q/vendor/x/x.go
@@ -0,0 +1 @@
+package x
diff --git a/third_party/gofrontend/libgo/go/cmd/go/testdata/testvendor/src/q/y/y.go b/third_party/gofrontend/libgo/go/cmd/go/testdata/testvendor/src/q/y/y.go
new file mode 100644
index 0000000..4f84223
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/cmd/go/testdata/testvendor/src/q/y/y.go
@@ -0,0 +1,3 @@
+package y
+
+import _ "x"
diff --git a/third_party/gofrontend/libgo/go/cmd/go/testdata/testvendor/src/q/z/z.go b/third_party/gofrontend/libgo/go/cmd/go/testdata/testvendor/src/q/z/z.go
new file mode 100644
index 0000000..a8d4924
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/cmd/go/testdata/testvendor/src/q/z/z.go
@@ -0,0 +1,3 @@
+package z
+
+import _ "q/vendor/x"
diff --git a/third_party/gofrontend/libgo/go/cmd/go/testdata/testvendor2/src/p/p.go b/third_party/gofrontend/libgo/go/cmd/go/testdata/testvendor2/src/p/p.go
new file mode 100644
index 0000000..220b2b2
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/cmd/go/testdata/testvendor2/src/p/p.go
@@ -0,0 +1,3 @@
+package p
+
+import "x"
diff --git a/third_party/gofrontend/libgo/go/cmd/go/testdata/testvendor2/vendor/x/x.go b/third_party/gofrontend/libgo/go/cmd/go/testdata/testvendor2/vendor/x/x.go
new file mode 100644
index 0000000..823aafd
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/cmd/go/testdata/testvendor2/vendor/x/x.go
@@ -0,0 +1 @@
+package x
diff --git a/third_party/gofrontend/libgo/go/cmd/go/testflag.go b/third_party/gofrontend/libgo/go/cmd/go/testflag.go
index 6da74b9..1f3e3d3 100644
--- a/third_party/gofrontend/libgo/go/cmd/go/testflag.go
+++ b/third_party/gofrontend/libgo/go/cmd/go/testflag.go
@@ -5,6 +5,7 @@
 package main
 
 import (
+	"flag"
 	"fmt"
 	"os"
 	"strconv"
@@ -16,46 +17,11 @@
 // our command line are for us, and some are for 6.out, and
 // some are for both.
 
-var usageMessage = `Usage of go test:
-  -c=false: compile but do not run the test binary
-  -file=file_test.go: specify file to use for tests;
-      use multiple times for multiple files
-  -p=n: build and test up to n packages in parallel
-  -x=false: print command lines as they are executed
-
-  // These flags can be passed with or without a "test." prefix: -v or -test.v.
-  -bench="": passes -test.bench to test
-  -benchmem=false: print memory allocation statistics for benchmarks
-  -benchtime=1s: passes -test.benchtime to test
-  -cover=false: enable coverage analysis
-  -covermode="set": specifies mode for coverage analysis
-  -coverpkg="": comma-separated list of packages for coverage analysis
-  -coverprofile="": passes -test.coverprofile to test if -cover
-  -cpu="": passes -test.cpu to test
-  -cpuprofile="": passes -test.cpuprofile to test
-  -memprofile="": passes -test.memprofile to test
-  -memprofilerate=0: passes -test.memprofilerate to test
-  -blockprofile="": pases -test.blockprofile to test
-  -blockprofilerate=0: passes -test.blockprofilerate to test
-  -outputdir=$PWD: passes -test.outputdir to test
-  -parallel=0: passes -test.parallel to test
-  -run="": passes -test.run to test
-  -short=false: passes -test.short to test
-  -timeout=0: passes -test.timeout to test
-  -v=false: passes -test.v to test
-`
-
-// usage prints a usage message and exits.
-func testUsage() {
-	fmt.Fprint(os.Stderr, usageMessage)
-	setExitStatus(2)
-	exit()
-}
-
 // testFlagSpec defines a flag we know about.
 type testFlagSpec struct {
 	name       string
 	boolVar    *bool
+	flagValue  flag.Value
 	passToTest bool // pass to Test
 	multiOK    bool // OK to have multiple instances
 	present    bool // flag has been seen
@@ -65,32 +31,18 @@
 var testFlagDefn = []*testFlagSpec{
 	// local.
 	{name: "c", boolVar: &testC},
-	{name: "cover", boolVar: &testCover},
-	{name: "coverpkg"},
-	{name: "o"},
-
-	// build flags.
-	{name: "a", boolVar: &buildA},
-	{name: "n", boolVar: &buildN},
-	{name: "p"},
-	{name: "x", boolVar: &buildX},
 	{name: "i", boolVar: &buildI},
-	{name: "work", boolVar: &buildWork},
-	{name: "ccflags"},
-	{name: "gcflags"},
+	{name: "o"},
+	{name: "cover", boolVar: &testCover},
+	{name: "covermode"},
+	{name: "coverpkg"},
 	{name: "exec"},
-	{name: "ldflags"},
-	{name: "gccgoflags"},
-	{name: "tags"},
-	{name: "compiler"},
-	{name: "race", boolVar: &buildRace},
-	{name: "installsuffix"},
 
 	// passed to 6.out, adding a "test." prefix to the name if necessary: -v becomes -test.v.
 	{name: "bench", passToTest: true},
 	{name: "benchmem", boolVar: new(bool), passToTest: true},
 	{name: "benchtime", passToTest: true},
-	{name: "covermode"},
+	{name: "count", passToTest: true},
 	{name: "coverprofile", passToTest: true},
 	{name: "cpu", passToTest: true},
 	{name: "cpuprofile", passToTest: true},
@@ -103,9 +55,26 @@
 	{name: "run", passToTest: true},
 	{name: "short", boolVar: new(bool), passToTest: true},
 	{name: "timeout", passToTest: true},
+	{name: "trace", passToTest: true},
 	{name: "v", boolVar: &testV, passToTest: true},
 }
 
+// add build flags to testFlagDefn
+func init() {
+	var cmd Command
+	addBuildFlags(&cmd)
+	cmd.Flag.VisitAll(func(f *flag.Flag) {
+		if f.Name == "v" {
+			// test overrides the build -v flag
+			return
+		}
+		testFlagDefn = append(testFlagDefn, &testFlagSpec{
+			name:      f.Name,
+			flagValue: f.Value,
+		})
+	})
+}
+
 // testFlags processes the command line, grabbing -x and -c, rewriting known flags
 // to have "test" before them, and reading the command line for the 6.out.
 // Unfortunately for us, we need to do our own flag processing because go test
@@ -148,73 +117,55 @@
 			passToTest = append(passToTest, args[i])
 			continue
 		}
-		var err error
-		switch f.name {
-		// bool flags.
-		case "a", "c", "i", "n", "x", "v", "race", "cover", "work":
-			setBoolFlag(f.boolVar, value)
-		case "o":
-			testO = value
-			testNeedBinary = true
-		case "p":
-			setIntFlag(&buildP, value)
-		case "exec":
-			execCmd, err = splitQuotedFields(value)
-			if err != nil {
+		if f.flagValue != nil {
+			if err := f.flagValue.Set(value); err != nil {
 				fatalf("invalid flag argument for -%s: %v", f.name, err)
 			}
-		case "ccflags":
-			buildCcflags, err = splitQuotedFields(value)
-			if err != nil {
-				fatalf("invalid flag argument for -%s: %v", f.name, err)
+		} else {
+			// Test-only flags.
+			// Arguably should be handled by f.flagValue, but aren't.
+			var err error
+			switch f.name {
+			// bool flags.
+			case "c", "i", "v", "cover":
+				setBoolFlag(f.boolVar, value)
+			case "o":
+				testO = value
+				testNeedBinary = true
+			case "exec":
+				execCmd, err = splitQuotedFields(value)
+				if err != nil {
+					fatalf("invalid flag argument for -%s: %v", f.name, err)
+				}
+			case "bench":
+				// record that we saw the flag; don't care about the value
+				testBench = true
+			case "timeout":
+				testTimeout = value
+			case "blockprofile", "cpuprofile", "memprofile", "trace":
+				testProfile = true
+				testNeedBinary = true
+			case "coverpkg":
+				testCover = true
+				if value == "" {
+					testCoverPaths = nil
+				} else {
+					testCoverPaths = strings.Split(value, ",")
+				}
+			case "coverprofile":
+				testCover = true
+				testProfile = true
+			case "covermode":
+				switch value {
+				case "set", "count", "atomic":
+					testCoverMode = value
+				default:
+					fatalf("invalid flag argument for -covermode: %q", value)
+				}
+				testCover = true
+			case "outputdir":
+				outputDir = value
 			}
-		case "gcflags":
-			buildGcflags, err = splitQuotedFields(value)
-			if err != nil {
-				fatalf("invalid flag argument for -%s: %v", f.name, err)
-			}
-		case "ldflags":
-			buildLdflags, err = splitQuotedFields(value)
-			if err != nil {
-				fatalf("invalid flag argument for -%s: %v", f.name, err)
-			}
-		case "gccgoflags":
-			buildGccgoflags, err = splitQuotedFields(value)
-			if err != nil {
-				fatalf("invalid flag argument for -%s: %v", f.name, err)
-			}
-		case "tags":
-			buildContext.BuildTags = strings.Fields(value)
-		case "compiler":
-			buildCompiler{}.Set(value)
-		case "bench":
-			// record that we saw the flag; don't care about the value
-			testBench = true
-		case "timeout":
-			testTimeout = value
-		case "blockprofile", "cpuprofile", "memprofile":
-			testProfile = true
-			testNeedBinary = true
-		case "coverpkg":
-			testCover = true
-			if value == "" {
-				testCoverPaths = nil
-			} else {
-				testCoverPaths = strings.Split(value, ",")
-			}
-		case "coverprofile":
-			testCover = true
-			testProfile = true
-		case "covermode":
-			switch value {
-			case "set", "count", "atomic":
-				testCoverMode = value
-			default:
-				fatalf("invalid flag argument for -cover: %q", value)
-			}
-			testCover = true
-		case "outputdir":
-			outputDir = value
 		}
 		if extraWord {
 			i++
@@ -267,7 +218,7 @@
 	for _, f = range testFlagDefn {
 		if name == f.name {
 			// Booleans are special because they have modes -x, -x=true, -x=false.
-			if f.boolVar != nil {
+			if f.boolVar != nil || isBoolFlag(f.flagValue) {
 				if equals < 0 { // otherwise, it's been set and will be verified in setBoolFlag
 					value = "true"
 				} else {
@@ -294,6 +245,17 @@
 	return
 }
 
+// isBoolFlag reports whether v is a bool flag.
+func isBoolFlag(v flag.Value) bool {
+	vv, ok := v.(interface {
+		IsBoolFlag() bool
+	})
+	if ok {
+		return vv.IsBoolFlag()
+	}
+	return false
+}
+
 // setBoolFlag sets the addressed boolean to the value.
 func setBoolFlag(flag *bool, value string) {
 	x, err := strconv.ParseBool(value)
diff --git a/third_party/gofrontend/libgo/go/cmd/go/tool.go b/third_party/gofrontend/libgo/go/cmd/go/tool.go
index 3f11c3e..4b94939 100644
--- a/third_party/gofrontend/libgo/go/cmd/go/tool.go
+++ b/third_party/gofrontend/libgo/go/cmd/go/tool.go
@@ -39,6 +39,12 @@
 	toolN bool
 )
 
+// List of go tools found in the gccgo tool directory.
+// Other binaries could be in the same directory so don't
+// show those with the 'go tool' command.
+
+var gccgoTools = []string{"cgo", "fix", "cover", "godoc", "vet"}
+
 func init() {
 	cmdTool.Flag.BoolVar(&toolN, "n", false, "")
 }
@@ -50,6 +56,9 @@
 	if toolIsWindows {
 		toolPath += toolWindowsExtension
 	}
+	if len(buildToolExec) > 0 {
+		return toolPath
+	}
 	// Give a nice message if there is no tool with that name.
 	if _, err := os.Stat(toolPath); err != nil {
 		if isInGoToolsRepo(toolName) {
@@ -64,10 +73,6 @@
 }
 
 func isInGoToolsRepo(toolName string) bool {
-	switch toolName {
-	case "cover", "vet":
-		return true
-	}
 	return false
 }
 
@@ -92,7 +97,11 @@
 		return
 	}
 	if toolN {
-		fmt.Printf("%s %s\n", toolPath, strings.Join(args[1:], " "))
+		cmd := toolPath
+		if len(args) > 1 {
+			cmd += " " + strings.Join(args[1:], " ")
+		}
+		fmt.Printf("%s\n", cmd)
 		return
 	}
 	toolCmd := &exec.Cmd{
@@ -101,6 +110,8 @@
 		Stdin:  os.Stdin,
 		Stdout: os.Stdout,
 		Stderr: os.Stderr,
+		// Set $GOROOT, mainly for go tool dist.
+		Env: mergeEnvLists([]string{"GOROOT=" + goroot}, os.Environ()),
 	}
 	err := toolCmd.Run()
 	if err != nil {
@@ -141,6 +152,21 @@
 		if toolIsWindows && strings.HasSuffix(name, toolWindowsExtension) {
 			name = name[:len(name)-len(toolWindowsExtension)]
 		}
-		fmt.Println(name)
+
+		// The tool directory used by gccgo will have other binaries
+		// in additions to go tools.  Only display go tools for this list.
+
+		if buildContext.Compiler == "gccgo" {
+			for _, tool := range gccgoTools {
+				if tool == name {
+					fmt.Println(name)
+				}
+			}
+		} else {
+
+			// Not gccgo, list all the tools found in this dir
+
+			fmt.Println(name)
+		}
 	}
 }
diff --git a/third_party/gofrontend/libgo/go/cmd/go/vcs.go b/third_party/gofrontend/libgo/go/cmd/go/vcs.go
index 1cac613..28a7540 100644
--- a/third_party/gofrontend/libgo/go/cmd/go/vcs.go
+++ b/third_party/gofrontend/libgo/go/cmd/go/vcs.go
@@ -9,12 +9,15 @@
 	"encoding/json"
 	"errors"
 	"fmt"
+	"internal/singleflight"
 	"log"
+	"net/url"
 	"os"
 	"os/exec"
 	"path/filepath"
 	"regexp"
 	"strings"
+	"sync"
 )
 
 // A vcsCmd describes how to use a version control system
@@ -23,13 +26,13 @@
 	name string
 	cmd  string // name of binary to invoke command
 
-	createCmd   string // command to download a fresh copy of a repository
-	downloadCmd string // command to download updates into an existing repository
+	createCmd   []string // commands to download a fresh copy of a repository
+	downloadCmd []string // commands to download updates into an existing repository
 
 	tagCmd         []tagCmd // commands to list tags
 	tagLookupCmd   []tagCmd // commands to lookup tags before running tagSyncCmd
-	tagSyncCmd     string   // command to sync to specific tag
-	tagSyncDefault string   // command to sync to default tag
+	tagSyncCmd     []string // commands to sync to specific tag
+	tagSyncDefault []string // commands to sync to default tag
 
 	scheme  []string
 	pingCmd string
@@ -38,6 +41,23 @@
 	resolveRepo func(v *vcsCmd, rootDir, remoteRepo string) (realRepo string, err error)
 }
 
+var isSecureScheme = map[string]bool{
+	"https":   true,
+	"git+ssh": true,
+	"bzr+ssh": true,
+	"svn+ssh": true,
+	"ssh":     true,
+}
+
+func (v *vcsCmd) isSecure(repo string) bool {
+	u, err := url.Parse(repo)
+	if err != nil {
+		// If repo is not a URL, it's not secure.
+		return false
+	}
+	return isSecureScheme[u.Scheme]
+}
+
 // A tagCmd describes a command to list available tags
 // that can be passed to tagSyncCmd.
 type tagCmd struct {
@@ -69,8 +89,8 @@
 	name: "Mercurial",
 	cmd:  "hg",
 
-	createCmd:   "clone -U {repo} {dir}",
-	downloadCmd: "pull",
+	createCmd:   []string{"clone -U {repo} {dir}"},
+	downloadCmd: []string{"pull"},
 
 	// We allow both tag and branch names as 'tags'
 	// for selecting a version.  This lets people have
@@ -81,8 +101,8 @@
 		{"tags", `^(\S+)`},
 		{"branches", `^(\S+)`},
 	},
-	tagSyncCmd:     "update -r {tag}",
-	tagSyncDefault: "update default",
+	tagSyncCmd:     []string{"update -r {tag}"},
+	tagSyncDefault: []string{"update default"},
 
 	scheme:     []string{"https", "http", "ssh"},
 	pingCmd:    "identify {scheme}://{repo}",
@@ -102,8 +122,8 @@
 	name: "Git",
 	cmd:  "git",
 
-	createCmd:   "clone {repo} {dir}",
-	downloadCmd: "pull --ff-only",
+	createCmd:   []string{"clone {repo} {dir}", "--git-dir={dir}/.git submodule update --init --recursive"},
+	downloadCmd: []string{"pull --ff-only", "submodule update --init --recursive"},
 
 	tagCmd: []tagCmd{
 		// tags/xxx matches a git tag named xxx
@@ -113,41 +133,64 @@
 	tagLookupCmd: []tagCmd{
 		{"show-ref tags/{tag} origin/{tag}", `((?:tags|origin)/\S+)$`},
 	},
-	tagSyncCmd:     "checkout {tag}",
-	tagSyncDefault: "checkout master",
+	tagSyncCmd: []string{"checkout {tag}", "submodule update --init --recursive"},
+	// both createCmd and downloadCmd update the working dir.
+	// No need to do more here. We used to 'checkout master'
+	// but that doesn't work if the default branch is not named master.
+	// See golang.org/issue/9032.
+	tagSyncDefault: []string{"checkout master", "submodule update --init --recursive"},
 
-	scheme:     []string{"git", "https", "http", "git+ssh"},
+	scheme:     []string{"git", "https", "http", "git+ssh", "ssh"},
 	pingCmd:    "ls-remote {scheme}://{repo}",
 	remoteRepo: gitRemoteRepo,
 }
 
+// scpSyntaxRe matches the SCP-like addresses used by Git to access
+// repositories by SSH.
+var scpSyntaxRe = regexp.MustCompile(`^([a-zA-Z0-9_]+)@([a-zA-Z0-9._-]+):(.*)$`)
+
 func gitRemoteRepo(vcsGit *vcsCmd, rootDir string) (remoteRepo string, err error) {
-	outb, err := vcsGit.runOutput(rootDir, "remote -v")
+	cmd := "config remote.origin.url"
+	errParse := errors.New("unable to parse output of git " + cmd)
+	errRemoteOriginNotFound := errors.New("remote origin not found")
+	outb, err := vcsGit.run1(rootDir, cmd, nil, false)
 	if err != nil {
+		// if it doesn't output any message, it means the config argument is correct,
+		// but the config value itself doesn't exist
+		if outb != nil && len(outb) == 0 {
+			return "", errRemoteOriginNotFound
+		}
 		return "", err
 	}
-	out := string(outb)
+	out := strings.TrimSpace(string(outb))
 
-	// Expect:
-	// origin	https://github.com/rsc/pdf (fetch)
-	// origin	https://github.com/rsc/pdf (push)
-	// use first line only.
+	var repoURL *url.URL
+	if m := scpSyntaxRe.FindStringSubmatch(out); m != nil {
+		// Match SCP-like syntax and convert it to a URL.
+		// Eg, "git@github.com:user/repo" becomes
+		// "ssh://git@github.com/user/repo".
+		repoURL = &url.URL{
+			Scheme:  "ssh",
+			User:    url.User(m[1]),
+			Host:    m[2],
+			RawPath: m[3],
+		}
+	} else {
+		repoURL, err = url.Parse(out)
+		if err != nil {
+			return "", err
+		}
+	}
 
-	if !strings.HasPrefix(out, "origin\t") {
-		return "", fmt.Errorf("unable to parse output of git remote -v")
+	// Iterate over insecure schemes too, because this function simply
+	// reports the state of the repo. If we can't see insecure schemes then
+	// we can't report the actual repo URL.
+	for _, s := range vcsGit.scheme {
+		if repoURL.Scheme == s {
+			return repoURL.String(), nil
+		}
 	}
-	out = strings.TrimPrefix(out, "origin\t")
-	i := strings.Index(out, "\n")
-	if i < 0 {
-		return "", fmt.Errorf("unable to parse output of git remote -v")
-	}
-	out = out[:i]
-	i = strings.LastIndex(out, " ")
-	if i < 0 {
-		return "", fmt.Errorf("unable to parse output of git remote -v")
-	}
-	out = out[:i]
-	return strings.TrimSpace(string(out)), nil
+	return "", errParse
 }
 
 // vcsBzr describes how to use Bazaar.
@@ -155,15 +198,15 @@
 	name: "Bazaar",
 	cmd:  "bzr",
 
-	createCmd: "branch {repo} {dir}",
+	createCmd: []string{"branch {repo} {dir}"},
 
 	// Without --overwrite bzr will not pull tags that changed.
 	// Replace by --overwrite-tags after http://pad.lv/681792 goes in.
-	downloadCmd: "pull --overwrite",
+	downloadCmd: []string{"pull --overwrite"},
 
 	tagCmd:         []tagCmd{{"tags", `^(\S+)`}},
-	tagSyncCmd:     "update -r {tag}",
-	tagSyncDefault: "update -r revno:-1",
+	tagSyncCmd:     []string{"update -r {tag}"},
+	tagSyncDefault: []string{"update -r revno:-1"},
 
 	scheme:      []string{"https", "http", "bzr", "bzr+ssh"},
 	pingCmd:     "info {scheme}://{repo}",
@@ -217,8 +260,8 @@
 	name: "Subversion",
 	cmd:  "svn",
 
-	createCmd:   "checkout {repo} {dir}",
-	downloadCmd: "update",
+	createCmd:   []string{"checkout {repo} {dir}"},
+	downloadCmd: []string{"update"},
 
 	// There is no tag command in subversion.
 	// The branch information is all in the path names.
@@ -294,14 +337,14 @@
 	_, err := exec.LookPath(v.cmd)
 	if err != nil {
 		fmt.Fprintf(os.Stderr,
-			"go: missing %s command. See http://golang.org/s/gogetcmd\n",
+			"go: missing %s command. See https://golang.org/s/gogetcmd\n",
 			v.name)
 		return nil, err
 	}
 
 	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, " "))
@@ -316,7 +359,7 @@
 			fmt.Fprintf(os.Stderr, "# cd %s; %s %s\n", dir, v.cmd, strings.Join(args, " "))
 			os.Stderr.Write(out)
 		}
-		return nil, err
+		return out, err
 	}
 	return out, nil
 }
@@ -329,7 +372,15 @@
 // create creates a new copy of repo in dir.
 // The parent of dir must exist; dir must not.
 func (v *vcsCmd) create(dir, repo string) error {
-	return v.run(".", v.createCmd, "dir", dir, "repo", repo)
+	for _, cmd := range v.createCmd {
+		if !go15VendorExperiment && strings.Contains(cmd, "submodule") {
+			continue
+		}
+		if err := v.run(".", cmd, "dir", dir, "repo", repo); err != nil {
+			return err
+		}
+	}
+	return nil
 }
 
 // download downloads any new changes for the repo in dir.
@@ -337,7 +388,15 @@
 	if err := v.fixDetachedHead(dir); err != nil {
 		return err
 	}
-	return v.run(dir, v.downloadCmd)
+	for _, cmd := range v.downloadCmd {
+		if !go15VendorExperiment && strings.Contains(cmd, "submodule") {
+			continue
+		}
+		if err := v.run(dir, cmd); err != nil {
+			return err
+		}
+	}
+	return nil
 }
 
 // fixDetachedHead switches a Git repository in dir from a detached head to the master branch.
@@ -383,7 +442,7 @@
 // tagSync syncs the repo in dir to the named tag,
 // which either is a tag returned by tags or is v.tagDefault.
 func (v *vcsCmd) tagSync(dir, tag string) error {
-	if v.tagSyncCmd == "" {
+	if v.tagSyncCmd == nil {
 		return nil
 	}
 	if tag != "" {
@@ -400,10 +459,28 @@
 			}
 		}
 	}
-	if tag == "" && v.tagSyncDefault != "" {
-		return v.run(dir, v.tagSyncDefault)
+
+	if tag == "" && v.tagSyncDefault != nil {
+		for _, cmd := range v.tagSyncDefault {
+			if !go15VendorExperiment && strings.Contains(cmd, "submodule") {
+				continue
+			}
+			if err := v.run(dir, cmd); err != nil {
+				return err
+			}
+		}
+		return nil
 	}
-	return v.run(dir, v.tagSyncCmd, "tag", tag)
+
+	for _, cmd := range v.tagSyncCmd {
+		if !go15VendorExperiment && strings.Contains(cmd, "submodule") {
+			continue
+		}
+		if err := v.run(dir, cmd, "tag", tag); err != nil {
+			return err
+		}
+	}
+	return nil
 }
 
 // A vcsPath describes how to convert an import path into a
@@ -467,10 +544,20 @@
 
 var httpPrefixRE = regexp.MustCompile(`^https?:`)
 
+// securityMode specifies whether a function should make network
+// calls using insecure transports (eg, plain text HTTP).
+// The zero value is "secure".
+type securityMode int
+
+const (
+	secure securityMode = iota
+	insecure
+)
+
 // repoRootForImportPath analyzes importPath to determine the
 // version control system, and code repository to use.
-func repoRootForImportPath(importPath string) (*repoRoot, error) {
-	rr, err := repoRootForImportPathStatic(importPath, "")
+func repoRootForImportPath(importPath string, security securityMode) (*repoRoot, error) {
+	rr, err := repoRootFromVCSPaths(importPath, "", security, vcsPaths)
 	if err == errUnknownSite {
 		// If there are wildcards, look up the thing before the wildcard,
 		// hoping it applies to the wildcarded parts too.
@@ -479,7 +566,7 @@
 		if i := strings.Index(lookup, "/.../"); i >= 0 {
 			lookup = lookup[:i]
 		}
-		rr, err = repoRootForImportDynamic(lookup)
+		rr, err = repoRootForImportDynamic(lookup, security)
 
 		// repoRootForImportDynamic returns error detail
 		// that is irrelevant if the user didn't intend to use a
@@ -492,6 +579,13 @@
 			err = fmt.Errorf("unrecognized import path %q", importPath)
 		}
 	}
+	if err != nil {
+		rr1, err1 := repoRootFromVCSPaths(importPath, "", security, vcsPathsAfterDynamic)
+		if err1 == nil {
+			rr = rr1
+			err = nil
+		}
+	}
 
 	if err == nil && strings.Contains(importPath, "...") && strings.Contains(rr.root, "...") {
 		// Do not allow wildcards in the repo root.
@@ -503,13 +597,10 @@
 
 var errUnknownSite = errors.New("dynamic lookup required to find mapping")
 
-// repoRootForImportPathStatic attempts to map importPath to a
-// repoRoot using the commonly-used VCS hosting sites in vcsPaths
-// (github.com/user/dir), or from a fully-qualified importPath already
-// containing its VCS type (foo.com/repo.git/dir)
-//
+// repoRootFromVCSPaths attempts to map importPath to a repoRoot
+// using the mappings defined in vcsPaths.
 // If scheme is non-empty, that scheme is forced.
-func repoRootForImportPathStatic(importPath, scheme string) (*repoRoot, error) {
+func repoRootFromVCSPaths(importPath, scheme string, security securityMode, vcsPaths []*vcsPath) (*repoRoot, error) {
 	// A common error is to use https://packagepath because that's what
 	// hg and git require. Diagnose this helpfully.
 	if loc := httpPrefixRE.FindStringIndex(importPath); loc != nil {
@@ -559,6 +650,9 @@
 				match["repo"] = scheme + "://" + match["repo"]
 			} else {
 				for _, scheme := range vcs.scheme {
+					if security == secure && !isSecureScheme[scheme] {
+						continue
+					}
 					if vcs.ping(scheme, match["repo"]) == nil {
 						match["repo"] = scheme + "://" + match["repo"]
 						break
@@ -579,26 +673,31 @@
 // repoRootForImportDynamic finds a *repoRoot for a custom domain that's not
 // statically known by repoRootForImportPathStatic.
 //
-// This handles "vanity import paths" like "name.tld/pkg/foo".
-func repoRootForImportDynamic(importPath string) (*repoRoot, error) {
+// This handles custom import paths like "name.tld/pkg/foo" or just "name.tld".
+func repoRootForImportDynamic(importPath string, security securityMode) (*repoRoot, error) {
 	slash := strings.Index(importPath, "/")
 	if slash < 0 {
-		return nil, errors.New("import path does not contain a slash")
+		slash = len(importPath)
 	}
 	host := importPath[:slash]
 	if !strings.Contains(host, ".") {
 		return nil, errors.New("import path does not begin with hostname")
 	}
-	urlStr, body, err := httpsOrHTTP(importPath)
+	urlStr, body, err := httpsOrHTTP(importPath, security)
 	if err != nil {
-		return nil, fmt.Errorf("http/https fetch: %v", err)
+		msg := "https fetch: %v"
+		if security == insecure {
+			msg = "http/" + msg
+		}
+		return nil, fmt.Errorf(msg, err)
 	}
 	defer body.Close()
 	imports, err := parseMetaGoImports(body)
 	if err != nil {
 		return nil, fmt.Errorf("parsing %s: %v", importPath, err)
 	}
-	metaImport, err := matchGoImport(imports, importPath)
+	// Find the matched meta import.
+	mmi, err := matchGoImport(imports, importPath)
 	if err != nil {
 		if err != errNoMatch {
 			return nil, fmt.Errorf("parse %s: %v", urlStr, err)
@@ -606,7 +705,7 @@
 		return nil, fmt.Errorf("parse %s: no go-import meta tags", urlStr)
 	}
 	if buildV {
-		log.Printf("get %q: found meta tag %#v at %s", importPath, metaImport, urlStr)
+		log.Printf("get %q: found meta tag %#v at %s", importPath, mmi, urlStr)
 	}
 	// If the import was "uni.edu/bob/project", which said the
 	// prefix was "uni.edu" and the RepoRoot was "evilroot.com",
@@ -614,42 +713,89 @@
 	// "uni.edu" yet (possibly overwriting/preempting another
 	// non-evil student).  Instead, first verify the root and see
 	// if it matches Bob's claim.
-	if metaImport.Prefix != importPath {
+	if mmi.Prefix != importPath {
 		if buildV {
 			log.Printf("get %q: verifying non-authoritative meta tag", importPath)
 		}
 		urlStr0 := urlStr
-		urlStr, body, err = httpsOrHTTP(metaImport.Prefix)
+		var imports []metaImport
+		urlStr, imports, err = metaImportsForPrefix(mmi.Prefix, security)
 		if err != nil {
-			return nil, fmt.Errorf("fetch %s: %v", urlStr, err)
-		}
-		imports, err := parseMetaGoImports(body)
-		if err != nil {
-			return nil, fmt.Errorf("parsing %s: %v", importPath, err)
-		}
-		if len(imports) == 0 {
-			return nil, fmt.Errorf("fetch %s: no go-import meta tag", urlStr)
+			return nil, err
 		}
 		metaImport2, err := matchGoImport(imports, importPath)
-		if err != nil || metaImport != metaImport2 {
-			return nil, fmt.Errorf("%s and %s disagree about go-import for %s", urlStr0, urlStr, metaImport.Prefix)
+		if err != nil || mmi != metaImport2 {
+			return nil, fmt.Errorf("%s and %s disagree about go-import for %s", urlStr0, urlStr, mmi.Prefix)
 		}
 	}
 
-	if !strings.Contains(metaImport.RepoRoot, "://") {
-		return nil, fmt.Errorf("%s: invalid repo root %q; no scheme", urlStr, metaImport.RepoRoot)
+	if !strings.Contains(mmi.RepoRoot, "://") {
+		return nil, fmt.Errorf("%s: invalid repo root %q; no scheme", urlStr, mmi.RepoRoot)
 	}
 	rr := &repoRoot{
-		vcs:  vcsByCmd(metaImport.VCS),
-		repo: metaImport.RepoRoot,
-		root: metaImport.Prefix,
+		vcs:  vcsByCmd(mmi.VCS),
+		repo: mmi.RepoRoot,
+		root: mmi.Prefix,
 	}
 	if rr.vcs == nil {
-		return nil, fmt.Errorf("%s: unknown vcs %q", urlStr, metaImport.VCS)
+		return nil, fmt.Errorf("%s: unknown vcs %q", urlStr, mmi.VCS)
 	}
 	return rr, nil
 }
 
+var fetchGroup singleflight.Group
+var (
+	fetchCacheMu sync.Mutex
+	fetchCache   = map[string]fetchResult{} // key is metaImportsForPrefix's importPrefix
+)
+
+// metaImportsForPrefix takes a package's root import path as declared in a <meta> tag
+// and returns its HTML discovery URL and the parsed metaImport lines
+// found on the page.
+//
+// The importPath is of the form "golang.org/x/tools".
+// It is an error if no imports are found.
+// urlStr will still be valid if err != nil.
+// The returned urlStr will be of the form "https://golang.org/x/tools?go-get=1"
+func metaImportsForPrefix(importPrefix string, security securityMode) (urlStr string, imports []metaImport, err error) {
+	setCache := func(res fetchResult) (fetchResult, error) {
+		fetchCacheMu.Lock()
+		defer fetchCacheMu.Unlock()
+		fetchCache[importPrefix] = res
+		return res, nil
+	}
+
+	resi, _, _ := fetchGroup.Do(importPrefix, func() (resi interface{}, err error) {
+		fetchCacheMu.Lock()
+		if res, ok := fetchCache[importPrefix]; ok {
+			fetchCacheMu.Unlock()
+			return res, nil
+		}
+		fetchCacheMu.Unlock()
+
+		urlStr, body, err := httpsOrHTTP(importPrefix, security)
+		if err != nil {
+			return setCache(fetchResult{urlStr: urlStr, err: fmt.Errorf("fetch %s: %v", urlStr, err)})
+		}
+		imports, err := parseMetaGoImports(body)
+		if err != nil {
+			return setCache(fetchResult{urlStr: urlStr, err: fmt.Errorf("parsing %s: %v", urlStr, err)})
+		}
+		if len(imports) == 0 {
+			err = fmt.Errorf("fetch %s: no go-import meta tag", urlStr)
+		}
+		return setCache(fetchResult{urlStr: urlStr, imports: imports, err: err})
+	})
+	res := resi.(fetchResult)
+	return res.urlStr, res.imports, res.err
+}
+
+type fetchResult struct {
+	urlStr  string // e.g. "https://foo.com/x/bar?go-get=1"
+	imports []metaImport
+	err     error
+}
+
 // metaImport represents the parsed <meta name="go-import"
 // content="prefix vcs reporoot" /> tags from HTML files.
 type metaImport struct {
@@ -689,7 +835,10 @@
 	return s
 }
 
-// vcsPaths lists the known vcs paths.
+// vcsPaths defines the meaning of import paths referring to
+// commonly-used VCS hosting sites (github.com/user/dir)
+// and import paths referring to a fully-qualified importPath
+// containing a VCS type (foo.com/repo.git/dir)
 var vcsPaths = []*vcsPath{
 	// Google Code - new syntax
 	{
@@ -722,15 +871,6 @@
 		check:  bitbucketVCS,
 	},
 
-	// Launchpad
-	{
-		prefix: "launchpad.net/",
-		re:     `^(?P<root>launchpad\.net/((?P<project>[A-Za-z0-9_.\-]+)(?P<series>/[A-Za-z0-9_.\-]+)?|~[A-Za-z0-9_.\-]+/(\+junk|[A-Za-z0-9_.\-]+)/[A-Za-z0-9_.\-]+))(/[A-Za-z0-9_.\-]+)*$`,
-		vcs:    "bzr",
-		repo:   "https://{root}",
-		check:  launchpadVCS,
-	},
-
 	// IBM DevOps Services (JazzHub)
 	{
 		prefix: "hub.jazz.net/git",
@@ -740,13 +880,37 @@
 		check:  noVCSSuffix,
 	},
 
+	// Git at Apache
+	{
+		prefix: "git.apache.org",
+		re:     `^(?P<root>git.apache.org/[a-z0-9_.\-]+\.git)(/[A-Za-z0-9_.\-]+)*$`,
+		vcs:    "git",
+		repo:   "https://{root}",
+	},
+
 	// General syntax for any server.
+	// Must be last.
 	{
 		re:   `^(?P<root>(?P<repo>([a-z0-9.\-]+\.)+[a-z0-9.\-]+(:[0-9]+)?/[A-Za-z0-9_.\-/]*?)\.(?P<vcs>bzr|git|hg|svn))(/[A-Za-z0-9_.\-]+)*$`,
 		ping: true,
 	},
 }
 
+// vcsPathsAfterDynamic gives additional vcsPaths entries
+// to try after the dynamic HTML check.
+// This gives those sites a chance to introduce <meta> tags
+// as part of a graceful transition away from the hard-coded logic.
+var vcsPathsAfterDynamic = []*vcsPath{
+	// Launchpad. See golang.org/issue/11436.
+	{
+		prefix: "launchpad.net/",
+		re:     `^(?P<root>launchpad\.net/((?P<project>[A-Za-z0-9_.\-]+)(?P<series>/[A-Za-z0-9_.\-]+)?|~[A-Za-z0-9_.\-]+/(\+junk|[A-Za-z0-9_.\-]+)/[A-Za-z0-9_.\-]+))(/[A-Za-z0-9_.\-]+)*$`,
+		vcs:    "bzr",
+		repo:   "https://{root}",
+		check:  launchpadVCS,
+	},
+}
+
 func init() {
 	// fill in cached regexps.
 	// Doing this eagerly discovers invalid regexp syntax
@@ -754,6 +918,9 @@
 	for _, srv := range vcsPaths {
 		srv.regexp = regexp.MustCompile(srv.re)
 	}
+	for _, srv := range vcsPathsAfterDynamic {
+		srv.regexp = regexp.MustCompile(srv.re)
+	}
 }
 
 // noVCSSuffix checks that the repository name does not
@@ -821,10 +988,25 @@
 	url := expand(match, "https://api.bitbucket.org/1.0/repositories/{bitname}")
 	data, err := httpGET(url)
 	if err != nil {
-		return err
-	}
-	if err := json.Unmarshal(data, &resp); err != nil {
-		return fmt.Errorf("decoding %s: %v", url, err)
+		if httpErr, ok := err.(*httpError); ok && httpErr.statusCode == 403 {
+			// this may be a private repository. If so, attempt to determine which
+			// VCS it uses. See issue 5375.
+			root := match["root"]
+			for _, vcs := range []string{"git", "hg"} {
+				if vcsByCmd(vcs).ping("https", root) == nil {
+					resp.SCM = vcs
+					break
+				}
+			}
+		}
+
+		if resp.SCM == "" {
+			return err
+		}
+	} else {
+		if err := json.Unmarshal(data, &resp); err != nil {
+			return fmt.Errorf("decoding %s: %v", url, err)
+		}
 	}
 
 	if vcsByCmd(resp.SCM) != nil {
diff --git a/third_party/gofrontend/libgo/go/cmd/go/vcs_test.go b/third_party/gofrontend/libgo/go/cmd/go/vcs_test.go
index 14d681b..f5d5e4f 100644
--- a/third_party/gofrontend/libgo/go/cmd/go/vcs_test.go
+++ b/third_party/gofrontend/libgo/go/cmd/go/vcs_test.go
@@ -5,20 +5,15 @@
 package main
 
 import (
-	"runtime"
+	"internal/testenv"
 	"testing"
 )
 
 // Test that RepoRootForImportPath creates the correct RepoRoot for a given importPath.
 // TODO(cmang): Add tests for SVN and BZR.
 func TestRepoRootForImportPath(t *testing.T) {
-	if testing.Short() {
-		t.Skip("skipping test to avoid external network")
-	}
-	switch runtime.GOOS {
-	case "nacl", "android":
-		t.Skipf("no networking available on %s", runtime.GOOS)
-	}
+	testenv.MustHaveExternalNetwork(t)
+
 	tests := []struct {
 		path string
 		want *repoRoot
@@ -101,10 +96,34 @@
 			"hub.jazz.net/git/USER/pkgname",
 			nil,
 		},
+		// Spaces are not valid in package name
+		{
+			"git.apache.org/package name/path/to/lib",
+			nil,
+		},
+		// Should have ".git" suffix
+		{
+			"git.apache.org/package-name/path/to/lib",
+			nil,
+		},
+		{
+			"git.apache.org/package-name.git",
+			&repoRoot{
+				vcs:  vcsGit,
+				repo: "https://git.apache.org/package-name.git",
+			},
+		},
+		{
+			"git.apache.org/package-name_2.x.git/path/to/lib",
+			&repoRoot{
+				vcs:  vcsGit,
+				repo: "https://git.apache.org/package-name_2.x.git",
+			},
+		},
 	}
 
 	for _, test := range tests {
-		got, err := repoRootForImportPath(test.path)
+		got, err := repoRootForImportPath(test.path, secure)
 		want := test.want
 
 		if want == nil {
@@ -122,3 +141,35 @@
 		}
 	}
 }
+
+func TestIsSecure(t *testing.T) {
+	tests := []struct {
+		vcs    *vcsCmd
+		url    string
+		secure bool
+	}{
+		{vcsGit, "http://example.com/foo.git", false},
+		{vcsGit, "https://example.com/foo.git", true},
+		{vcsBzr, "http://example.com/foo.bzr", false},
+		{vcsBzr, "https://example.com/foo.bzr", true},
+		{vcsSvn, "http://example.com/svn", false},
+		{vcsSvn, "https://example.com/svn", true},
+		{vcsHg, "http://example.com/foo.hg", false},
+		{vcsHg, "https://example.com/foo.hg", true},
+		{vcsGit, "ssh://user@example.com/foo.git", true},
+		{vcsGit, "user@server:path/to/repo.git", false},
+		{vcsGit, "user@server:", false},
+		{vcsGit, "server:repo.git", false},
+		{vcsGit, "server:path/to/repo.git", false},
+		{vcsGit, "example.com:path/to/repo.git", false},
+		{vcsGit, "path/that/contains/a:colon/repo.git", false},
+		{vcsHg, "ssh://user@example.com/path/to/repo.hg", true},
+	}
+
+	for _, test := range tests {
+		secure := test.vcs.isSecure(test.url)
+		if secure != test.secure {
+			t.Errorf("%s isSecure(%q) = %t; want %t", test.vcs, test.url, secure, test.secure)
+		}
+	}
+}
diff --git a/third_party/gofrontend/libgo/go/cmd/go/vendor_test.go b/third_party/gofrontend/libgo/go/cmd/go/vendor_test.go
new file mode 100644
index 0000000..1e8cf9c
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/cmd/go/vendor_test.go
@@ -0,0 +1,258 @@
+// 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.
+
+// Tests for vendoring semantics.
+
+package main_test
+
+import (
+	"bytes"
+	"fmt"
+	"internal/testenv"
+	"path/filepath"
+	"regexp"
+	"strings"
+	"testing"
+)
+
+func TestVendorImports(t *testing.T) {
+	tg := testgo(t)
+	defer tg.cleanup()
+	tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata"))
+	tg.setenv("GO15VENDOREXPERIMENT", "1")
+	tg.run("list", "-f", "{{.ImportPath}} {{.Imports}}", "vend/...")
+	want := `
+		vend [vend/vendor/p r]
+		vend/hello [fmt vend/vendor/strings]
+		vend/subdir [vend/vendor/p r]
+		vend/vendor/p []
+		vend/vendor/q []
+		vend/vendor/strings []
+		vend/x [vend/x/vendor/p vend/vendor/q vend/x/vendor/r]
+		vend/x/invalid [vend/x/invalid/vendor/foo]
+		vend/x/vendor/p []
+		vend/x/vendor/p/p [notfound]
+		vend/x/vendor/r []
+	`
+	want = strings.Replace(want+"\t", "\n\t\t", "\n", -1)
+	want = strings.TrimPrefix(want, "\n")
+
+	have := tg.stdout.String()
+
+	if have != want {
+		t.Errorf("incorrect go list output:\n%s", diffSortedOutputs(have, want))
+	}
+}
+
+func TestVendorRun(t *testing.T) {
+	tg := testgo(t)
+	defer tg.cleanup()
+	tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata"))
+	tg.setenv("GO15VENDOREXPERIMENT", "1")
+	tg.cd(filepath.Join(tg.pwd(), "testdata/src/vend/hello"))
+	tg.run("run", "hello.go")
+	tg.grepStdout("hello, world", "missing hello world output")
+}
+
+func TestVendorGOPATH(t *testing.T) {
+	tg := testgo(t)
+	defer tg.cleanup()
+	changeVolume := func(s string, f func(s string) string) string {
+		vol := filepath.VolumeName(s)
+		return f(vol) + s[len(vol):]
+	}
+	gopath := changeVolume(filepath.Join(tg.pwd(), "testdata"), strings.ToLower)
+	tg.setenv("GOPATH", gopath)
+	tg.setenv("GO15VENDOREXPERIMENT", "1")
+	cd := changeVolume(filepath.Join(tg.pwd(), "testdata/src/vend/hello"), strings.ToUpper)
+	tg.cd(cd)
+	tg.run("run", "hello.go")
+	tg.grepStdout("hello, world", "missing hello world output")
+}
+
+func TestVendorTest(t *testing.T) {
+	tg := testgo(t)
+	defer tg.cleanup()
+	tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata"))
+	tg.setenv("GO15VENDOREXPERIMENT", "1")
+	tg.cd(filepath.Join(tg.pwd(), "testdata/src/vend/hello"))
+	tg.run("test", "-v")
+	tg.grepStdout("TestMsgInternal", "missing use in internal test")
+	tg.grepStdout("TestMsgExternal", "missing use in external test")
+}
+
+func TestVendorInvalid(t *testing.T) {
+	tg := testgo(t)
+	defer tg.cleanup()
+	tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata"))
+	tg.setenv("GO15VENDOREXPERIMENT", "1")
+
+	tg.runFail("build", "vend/x/invalid")
+	tg.grepStderr("must be imported as foo", "missing vendor import error")
+}
+
+func TestVendorImportError(t *testing.T) {
+	tg := testgo(t)
+	defer tg.cleanup()
+	tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata"))
+	tg.setenv("GO15VENDOREXPERIMENT", "1")
+
+	tg.runFail("build", "vend/x/vendor/p/p")
+
+	re := regexp.MustCompile(`cannot find package "notfound" in any of:
+	.*[\\/]testdata[\\/]src[\\/]vend[\\/]x[\\/]vendor[\\/]notfound \(vendor tree\)
+	.*[\\/]testdata[\\/]src[\\/]vend[\\/]vendor[\\/]notfound \(vendor tree\)
+	.*[\\/]src[\\/]notfound \(from \$GOROOT\)
+	.*[\\/]testdata[\\/]src[\\/]notfound \(from \$GOPATH\)`)
+
+	if !re.MatchString(tg.stderr.String()) {
+		t.Errorf("did not find expected search list in error text")
+	}
+}
+
+// diffSortedOutput prepares a diff of the already sorted outputs haveText and wantText.
+// The diff shows common lines prefixed by a tab, lines present only in haveText
+// prefixed by "unexpected: ", and lines present only in wantText prefixed by "missing: ".
+func diffSortedOutputs(haveText, wantText string) string {
+	var diff bytes.Buffer
+	have := splitLines(haveText)
+	want := splitLines(wantText)
+	for len(have) > 0 || len(want) > 0 {
+		if len(want) == 0 || len(have) > 0 && have[0] < want[0] {
+			fmt.Fprintf(&diff, "unexpected: %s\n", have[0])
+			have = have[1:]
+			continue
+		}
+		if len(have) == 0 || len(want) > 0 && want[0] < have[0] {
+			fmt.Fprintf(&diff, "missing: %s\n", want[0])
+			want = want[1:]
+			continue
+		}
+		fmt.Fprintf(&diff, "\t%s\n", want[0])
+		want = want[1:]
+		have = have[1:]
+	}
+	return diff.String()
+}
+
+func splitLines(s string) []string {
+	x := strings.Split(s, "\n")
+	if x[len(x)-1] == "" {
+		x = x[:len(x)-1]
+	}
+	return x
+}
+
+func TestVendorGet(t *testing.T) {
+	tg := testgo(t)
+	defer tg.cleanup()
+	tg.tempFile("src/v/m.go", `
+		package main
+		import ("fmt"; "vendor.org/p")
+		func main() {
+			fmt.Println(p.C)
+		}`)
+	tg.tempFile("src/v/m_test.go", `
+		package main
+		import ("fmt"; "testing"; "vendor.org/p")
+		func TestNothing(t *testing.T) {
+			fmt.Println(p.C)
+		}`)
+	tg.tempFile("src/v/vendor/vendor.org/p/p.go", `
+		package p
+		const C = 1`)
+	tg.setenv("GOPATH", tg.path("."))
+	tg.setenv("GO15VENDOREXPERIMENT", "1")
+	tg.cd(tg.path("src/v"))
+	tg.run("run", "m.go")
+	tg.run("test")
+	tg.run("list", "-f", "{{.Imports}}")
+	tg.grepStdout("v/vendor/vendor.org/p", "import not in vendor directory")
+	tg.run("list", "-f", "{{.TestImports}}")
+	tg.grepStdout("v/vendor/vendor.org/p", "test import not in vendor directory")
+	tg.run("get")
+	tg.run("get", "-t")
+}
+
+func TestVendorGetUpdate(t *testing.T) {
+	testenv.MustHaveExternalNetwork(t)
+
+	tg := testgo(t)
+	defer tg.cleanup()
+	tg.makeTempdir()
+	tg.setenv("GOPATH", tg.path("."))
+	tg.setenv("GO15VENDOREXPERIMENT", "1")
+	tg.run("get", "github.com/rsc/go-get-issue-11864")
+	tg.run("get", "-u", "github.com/rsc/go-get-issue-11864")
+}
+
+func TestVendorCache(t *testing.T) {
+	tg := testgo(t)
+	defer tg.cleanup()
+	tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata/testvendor"))
+	tg.setenv("GO15VENDOREXPERIMENT", "1")
+	tg.runFail("build", "p")
+	tg.grepStderr("must be imported as x", "did not fail to build p")
+}
+
+func TestVendorTest2(t *testing.T) {
+	testenv.MustHaveExternalNetwork(t)
+
+	tg := testgo(t)
+	defer tg.cleanup()
+	tg.makeTempdir()
+	tg.setenv("GOPATH", tg.path("."))
+	tg.setenv("GO15VENDOREXPERIMENT", "1")
+	tg.run("get", "github.com/rsc/go-get-issue-11864")
+
+	// build -i should work
+	tg.run("build", "-i", "github.com/rsc/go-get-issue-11864")
+	tg.run("build", "-i", "github.com/rsc/go-get-issue-11864/t")
+
+	// test -i should work like build -i (golang.org/issue/11988)
+	tg.run("test", "-i", "github.com/rsc/go-get-issue-11864")
+	tg.run("test", "-i", "github.com/rsc/go-get-issue-11864/t")
+
+	// test should work too
+	tg.run("test", "github.com/rsc/go-get-issue-11864")
+	tg.run("test", "github.com/rsc/go-get-issue-11864/t")
+
+	// external tests should observe internal test exports (golang.org/issue/11977)
+	tg.run("test", "github.com/rsc/go-get-issue-11864/vendor/vendor.org/tx2")
+}
+
+func TestVendorList(t *testing.T) {
+	testenv.MustHaveExternalNetwork(t)
+
+	tg := testgo(t)
+	defer tg.cleanup()
+	tg.makeTempdir()
+	tg.setenv("GOPATH", tg.path("."))
+	tg.setenv("GO15VENDOREXPERIMENT", "1")
+	tg.run("get", "github.com/rsc/go-get-issue-11864")
+
+	tg.run("list", "-f", `{{join .TestImports "\n"}}`, "github.com/rsc/go-get-issue-11864/t")
+	tg.grepStdout("go-get-issue-11864/vendor/vendor.org/p", "did not find vendor-expanded p")
+
+	tg.run("list", "-f", `{{join .XTestImports "\n"}}`, "github.com/rsc/go-get-issue-11864/tx")
+	tg.grepStdout("go-get-issue-11864/vendor/vendor.org/p", "did not find vendor-expanded p")
+
+	tg.run("list", "-f", `{{join .XTestImports "\n"}}`, "github.com/rsc/go-get-issue-11864/vendor/vendor.org/tx2")
+	tg.grepStdout("go-get-issue-11864/vendor/vendor.org/tx2", "did not find vendor-expanded tx2")
+
+	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/third_party/gofrontend/libgo/go/cmd/go/vet.go b/third_party/gofrontend/libgo/go/cmd/go/vet.go
index 02ff54b..81b978e 100644
--- a/third_party/gofrontend/libgo/go/cmd/go/vet.go
+++ b/third_party/gofrontend/libgo/go/cmd/go/vet.go
@@ -7,17 +7,17 @@
 import "path/filepath"
 
 func init() {
-	addBuildFlagsNX(cmdVet)
+	addBuildFlags(cmdVet)
 }
 
 var cmdVet = &Command{
 	Run:       runVet,
-	UsageLine: "vet [-n] [-x] [packages]",
+	UsageLine: "vet [-n] [-x] [build flags] [packages]",
 	Short:     "run go tool vet on packages",
 	Long: `
 Vet runs the Go vet command on the packages named by the import paths.
 
-For more about vet, see 'godoc golang.org/x/tools/cmd/vet'.
+For more about vet, see 'go doc cmd/vet'.
 For more about specifying packages, see 'go help packages'.
 
 To run the vet tool with specific options, run 'go tool vet'.
@@ -25,6 +25,8 @@
 The -n flag prints commands that would be executed.
 The -x flag prints commands as they are executed.
 
+For more about build flags, see 'go help build'.
+
 See also: go fmt, go fix.
 	`,
 }
@@ -46,5 +48,5 @@
 	for i := range files {
 		files[i] = filepath.Join(p.Dir, files[i])
 	}
-	run(tool("vet"), relPaths(files))
+	run(buildToolExec, tool("vet"), relPaths(files))
 }
diff --git a/third_party/gofrontend/libgo/go/cmd/gofmt/doc.go b/third_party/gofrontend/libgo/go/cmd/gofmt/doc.go
index 3fc0439..9d0cd32 100644
--- a/third_party/gofrontend/libgo/go/cmd/gofmt/doc.go
+++ b/third_party/gofrontend/libgo/go/cmd/gofmt/doc.go
@@ -87,6 +87,13 @@
 		for x, _ = range v {...}
 	will be simplified to:
 		for x = range v {...}
+
+	A range of the form:
+		for _ = range v {...}
+	will be simplified to:
+		for range v {...}
+
+This may result in changes that are incompatible with earlier versions of Go.
 */
 package main
 
diff --git a/third_party/gofrontend/libgo/go/cmd/gofmt/gofmt.go b/third_party/gofrontend/libgo/go/cmd/gofmt/gofmt.go
index 81da21f..b2805ac 100644
--- a/third_party/gofrontend/libgo/go/cmd/gofmt/gofmt.go
+++ b/third_party/gofrontend/libgo/go/cmd/gofmt/gofmt.go
@@ -13,6 +13,7 @@
 	"go/printer"
 	"go/scanner"
 	"go/token"
+	"internal/format"
 	"io"
 	"io/ioutil"
 	"os"
@@ -87,7 +88,7 @@
 		return err
 	}
 
-	file, sourceAdj, indentAdj, err := parse(fileSet, filename, src, stdin)
+	file, sourceAdj, indentAdj, err := format.Parse(fileSet, filename, src, stdin)
 	if err != nil {
 		return err
 	}
@@ -106,7 +107,7 @@
 		simplify(file)
 	}
 
-	res, err := format(fileSet, file, sourceAdj, indentAdj, src, printer.Config{Mode: printerMode, Tabwidth: tabWidth})
+	res, err := format.Format(fileSet, file, sourceAdj, indentAdj, src, printer.Config{Mode: printerMode, Tabwidth: tabWidth})
 	if err != nil {
 		return err
 	}
@@ -234,154 +235,3 @@
 	return
 
 }
-
-// ----------------------------------------------------------------------------
-// Support functions
-//
-// The functions parse, format, and isSpace below are identical to the
-// respective functions in src/go/format/format.go - keep them in sync!
-//
-// TODO(gri) Factor out this functionality, eventually.
-
-// parse parses src, which was read from the named file,
-// as a Go source file, declaration, or statement list.
-func parse(fset *token.FileSet, filename string, src []byte, fragmentOk bool) (
-	file *ast.File,
-	sourceAdj func(src []byte, indent int) []byte,
-	indentAdj int,
-	err error,
-) {
-	// Try as whole source file.
-	file, err = parser.ParseFile(fset, filename, src, parserMode)
-	// If there's no error, return.  If the error is that the source file didn't begin with a
-	// package line and source fragments are ok, fall through to
-	// try as a source fragment.  Stop and return on any other error.
-	if err == nil || !fragmentOk || !strings.Contains(err.Error(), "expected 'package'") {
-		return
-	}
-
-	// If this is a declaration list, make it a source file
-	// by inserting a package clause.
-	// Insert using a ;, not a newline, so that the line numbers
-	// in psrc match the ones in src.
-	psrc := append([]byte("package p;"), src...)
-	file, err = parser.ParseFile(fset, filename, psrc, parserMode)
-	if err == nil {
-		sourceAdj = func(src []byte, indent int) []byte {
-			// Remove the package clause.
-			// Gofmt has turned the ; into a \n.
-			src = src[indent+len("package p\n"):]
-			return bytes.TrimSpace(src)
-		}
-		return
-	}
-	// If the error is that the source file didn't begin with a
-	// declaration, fall through to try as a statement list.
-	// Stop and return on any other error.
-	if !strings.Contains(err.Error(), "expected declaration") {
-		return
-	}
-
-	// If this is a statement list, make it a source file
-	// by inserting a package clause and turning the list
-	// into a function body.  This handles expressions too.
-	// Insert using a ;, not a newline, so that the line numbers
-	// in fsrc match the ones in src.
-	fsrc := append(append([]byte("package p; func _() {"), src...), '\n', '}')
-	file, err = parser.ParseFile(fset, filename, fsrc, parserMode)
-	if err == nil {
-		sourceAdj = func(src []byte, indent int) []byte {
-			// Cap adjusted indent to zero.
-			if indent < 0 {
-				indent = 0
-			}
-			// Remove the wrapping.
-			// Gofmt has turned the ; into a \n\n.
-			// There will be two non-blank lines with indent, hence 2*indent.
-			src = src[2*indent+len("package p\n\nfunc _() {"):]
-			src = src[:len(src)-(indent+len("\n}\n"))]
-			return bytes.TrimSpace(src)
-		}
-		// Gofmt has also indented the function body one level.
-		// Adjust that with indentAdj.
-		indentAdj = -1
-	}
-
-	// Succeeded, or out of options.
-	return
-}
-
-// format formats the given package file originally obtained from src
-// and adjusts the result based on the original source via sourceAdj
-// and indentAdj.
-func format(
-	fset *token.FileSet,
-	file *ast.File,
-	sourceAdj func(src []byte, indent int) []byte,
-	indentAdj int,
-	src []byte,
-	cfg printer.Config,
-) ([]byte, error) {
-	if sourceAdj == nil {
-		// Complete source file.
-		var buf bytes.Buffer
-		err := cfg.Fprint(&buf, fset, file)
-		if err != nil {
-			return nil, err
-		}
-		return buf.Bytes(), nil
-	}
-
-	// Partial source file.
-	// Determine and prepend leading space.
-	i, j := 0, 0
-	for j < len(src) && isSpace(src[j]) {
-		if src[j] == '\n' {
-			i = j + 1 // byte offset of last line in leading space
-		}
-		j++
-	}
-	var res []byte
-	res = append(res, src[:i]...)
-
-	// Determine and prepend indentation of first code line.
-	// Spaces are ignored unless there are no tabs,
-	// in which case spaces count as one tab.
-	indent := 0
-	hasSpace := false
-	for _, b := range src[i:j] {
-		switch b {
-		case ' ':
-			hasSpace = true
-		case '\t':
-			indent++
-		}
-	}
-	if indent == 0 && hasSpace {
-		indent = 1
-	}
-	for i := 0; i < indent; i++ {
-		res = append(res, '\t')
-	}
-
-	// Format the source.
-	// Write it without any leading and trailing space.
-	cfg.Indent = indent + indentAdj
-	var buf bytes.Buffer
-	err := cfg.Fprint(&buf, fset, file)
-	if err != nil {
-		return nil, err
-	}
-	res = append(res, sourceAdj(buf.Bytes(), cfg.Indent)...)
-
-	// Determine and append trailing space.
-	i = len(src)
-	for i > 0 && isSpace(src[i-1]) {
-		i--
-	}
-	return append(res, src[i:]...), nil
-}
-
-func isSpace(b byte) bool {
-	return b == ' ' || b == '\t' || b == '\n' || b == '\r'
-}
diff --git a/third_party/gofrontend/libgo/go/cmd/gofmt/long_test.go b/third_party/gofrontend/libgo/go/cmd/gofmt/long_test.go
index 237b860..df9a878 100644
--- a/third_party/gofrontend/libgo/go/cmd/gofmt/long_test.go
+++ b/third_party/gofrontend/libgo/go/cmd/gofmt/long_test.go
@@ -15,6 +15,7 @@
 	"go/ast"
 	"go/printer"
 	"go/token"
+	"internal/format"
 	"io"
 	"os"
 	"path/filepath"
@@ -32,7 +33,7 @@
 )
 
 func gofmt(fset *token.FileSet, filename string, src *bytes.Buffer) error {
-	f, _, _, err := parse(fset, filename, src.Bytes(), false)
+	f, _, _, err := format.Parse(fset, filename, src.Bytes(), false)
 	if err != nil {
 		return err
 	}
@@ -60,7 +61,7 @@
 
 	// exclude files w/ syntax errors (typically test cases)
 	fset := token.NewFileSet()
-	if _, _, _, err = parse(fset, filename, b1.Bytes(), false); err != nil {
+	if _, _, _, err = format.Parse(fset, filename, b1.Bytes(), false); err != nil {
 		if *verbose {
 			fmt.Fprintf(os.Stderr, "ignoring %s\n", err)
 		}
diff --git a/third_party/gofrontend/libgo/go/cmd/gofmt/rewrite.go b/third_party/gofrontend/libgo/go/cmd/gofmt/rewrite.go
index d267cfc..069f966 100644
--- a/third_party/gofrontend/libgo/go/cmd/gofmt/rewrite.go
+++ b/third_party/gofrontend/libgo/go/cmd/gofmt/rewrite.go
@@ -154,7 +154,7 @@
 	return size == len(s) && unicode.IsLower(rune)
 }
 
-// match returns true if pattern matches val,
+// match reports whether pattern matches val,
 // recording wildcard submatches in m.
 // If m == nil, match checks whether pattern == val.
 func match(m map[string]reflect.Value, pattern, val reflect.Value) bool {
diff --git a/third_party/gofrontend/libgo/go/compress/bzip2/bzip2.go b/third_party/gofrontend/libgo/go/compress/bzip2/bzip2.go
index 15575d2..6897957 100644
--- a/third_party/gofrontend/libgo/go/compress/bzip2/bzip2.go
+++ b/third_party/gofrontend/libgo/go/compress/bzip2/bzip2.go
@@ -353,7 +353,7 @@
 	// variables accumulate the repeat count. See the Wikipedia page for
 	// details.
 	repeat := 0
-	repeat_power := 0
+	repeatPower := 0
 
 	// The `C' array (used by the inverse BWT) needs to be zero initialized.
 	for i := range bz2.c {
@@ -380,10 +380,10 @@
 		if v < 2 {
 			// This is either the RUNA or RUNB symbol.
 			if repeat == 0 {
-				repeat_power = 1
+				repeatPower = 1
 			}
-			repeat += repeat_power << v
-			repeat_power <<= 1
+			repeat += repeatPower << v
+			repeatPower <<= 1
 
 			// This limit of 2 million comes from the bzip2 source
 			// code. It prevents repeat from overflowing.
diff --git a/third_party/gofrontend/libgo/go/compress/bzip2/bzip2_test.go b/third_party/gofrontend/libgo/go/compress/bzip2/bzip2_test.go
index fb79d08..77c50df 100644
--- a/third_party/gofrontend/libgo/go/compress/bzip2/bzip2_test.go
+++ b/third_party/gofrontend/libgo/go/compress/bzip2/bzip2_test.go
@@ -200,7 +200,7 @@
 func BenchmarkDecodeTwain(b *testing.B)  { benchmarkDecode(b, twain) }
 
 func TestBufferOverrun(t *testing.T) {
-	// Tests https://code.google.com/p/go/issues/detail?id=5747.
+	// Tests https://golang.org/issue/5747.
 	buffer := bytes.NewReader([]byte(bufferOverrunBase64))
 	decoder := base64.NewDecoder(base64.StdEncoding, buffer)
 	decompressor := NewReader(decoder)
@@ -209,7 +209,7 @@
 }
 
 func TestOutOfRangeSelector(t *testing.T) {
-	// Tests https://code.google.com/p/go/issues/detail?id=8363.
+	// Tests https://golang.org/issue/8363.
 	buffer := bytes.NewReader(outOfRangeSelector)
 	decompressor := NewReader(buffer)
 	// This shouldn't panic.
diff --git a/third_party/gofrontend/libgo/go/compress/flate/deflate.go b/third_party/gofrontend/libgo/go/compress/flate/deflate.go
index 8c79df0..169a0c7 100644
--- a/third_party/gofrontend/libgo/go/compress/flate/deflate.go
+++ b/third_party/gofrontend/libgo/go/compress/flate/deflate.go
@@ -24,7 +24,7 @@
 	maxMatchLength     = 258 // The longest match for the compressor
 	minOffsetSize      = 1   // The shortest offset that makes any sense
 
-	// The maximum number of tokens we put into a single flat block, just too
+	// The maximum number of tokens we put into a single flat block, just to
 	// stop things from getting too large.
 	maxFlateBlockTokens = 1 << 14
 	maxStoreBlockSize   = 65535
diff --git a/third_party/gofrontend/libgo/go/compress/flate/deflate_test.go b/third_party/gofrontend/libgo/go/compress/flate/deflate_test.go
index 730234c..d5d6e73 100644
--- a/third_party/gofrontend/libgo/go/compress/flate/deflate_test.go
+++ b/third_party/gofrontend/libgo/go/compress/flate/deflate_test.go
@@ -407,7 +407,7 @@
 	}
 }
 
-// See http://code.google.com/p/go/issues/detail?id=2508
+// See https://golang.org/issue/2508
 func TestRegression2508(t *testing.T) {
 	if testing.Short() {
 		t.Logf("test disabled with -short")
diff --git a/third_party/gofrontend/libgo/go/compress/flate/flate_test.go b/third_party/gofrontend/libgo/go/compress/flate/flate_test.go
index 0687663..3f67025 100644
--- a/third_party/gofrontend/libgo/go/compress/flate/flate_test.go
+++ b/third_party/gofrontend/libgo/go/compress/flate/flate_test.go
@@ -10,29 +10,18 @@
 
 import (
 	"bytes"
+	"encoding/hex"
+	"io/ioutil"
 	"testing"
 )
 
-func TestUncompressedSource(t *testing.T) {
-	decoder := NewReader(bytes.NewReader([]byte{0x01, 0x01, 0x00, 0xfe, 0xff, 0x11}))
-	output := make([]byte, 1)
-	n, error := decoder.Read(output)
-	if n != 1 || error != nil {
-		t.Fatalf("decoder.Read() = %d, %v, want 1, nil", n, error)
-	}
-	if output[0] != 0x11 {
-		t.Errorf("output[0] = %x, want 0x11", output[0])
-	}
-}
-
 // The following test should not panic.
 func TestIssue5915(t *testing.T) {
 	bits := []int{4, 0, 0, 6, 4, 3, 2, 3, 3, 4, 4, 5, 0, 0, 0, 0, 5, 5, 6,
 		0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 		0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 8, 6, 0, 11, 0, 8, 0, 6, 6, 10, 8}
-	h := new(huffmanDecoder)
-	ok := h.init(bits)
-	if ok == true {
+	var h huffmanDecoder
+	if h.init(bits) {
 		t.Fatalf("Given sequence of bits is bad, and should not succeed.")
 	}
 }
@@ -41,9 +30,8 @@
 func TestIssue5962(t *testing.T) {
 	bits := []int{4, 0, 0, 6, 4, 3, 2, 3, 3, 4, 4, 5, 0, 0, 0, 0,
 		5, 5, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11}
-	h := new(huffmanDecoder)
-	ok := h.init(bits)
-	if ok == true {
+	var h huffmanDecoder
+	if h.init(bits) {
 		t.Fatalf("Given sequence of bits is bad, and should not succeed.")
 	}
 }
@@ -52,7 +40,7 @@
 func TestIssue6255(t *testing.T) {
 	bits1 := []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 11}
 	bits2 := []int{11, 13}
-	h := new(huffmanDecoder)
+	var h huffmanDecoder
 	if !h.init(bits1) {
 		t.Fatalf("Given sequence of bits is good and should succeed.")
 	}
@@ -60,3 +48,213 @@
 		t.Fatalf("Given sequence of bits is bad and should not succeed.")
 	}
 }
+
+func TestInvalidEncoding(t *testing.T) {
+	// Initialize Huffman decoder to recognize "0".
+	var h huffmanDecoder
+	if !h.init([]int{1}) {
+		t.Fatal("Failed to initialize Huffman decoder")
+	}
+
+	// Initialize decompressor with invalid Huffman coding.
+	var f decompressor
+	f.r = bytes.NewReader([]byte{0xff})
+
+	_, err := f.huffSym(&h)
+	if err == nil {
+		t.Fatal("Should have rejected invalid bit sequence")
+	}
+}
+
+func TestInvalidBits(t *testing.T) {
+	oversubscribed := []int{1, 2, 3, 4, 4, 5}
+	incomplete := []int{1, 2, 4, 4}
+	var h huffmanDecoder
+	if h.init(oversubscribed) {
+		t.Fatal("Should reject oversubscribed bit-length set")
+	}
+	if h.init(incomplete) {
+		t.Fatal("Should reject incomplete bit-length set")
+	}
+}
+
+func TestStreams(t *testing.T) {
+	// To verify any of these hexstrings as valid or invalid flate streams
+	// according to the C zlib library, you can use the Python wrapper library:
+	// >>> hex_string = "010100feff11"
+	// >>> import zlib
+	// >>> zlib.decompress(hex_string.decode("hex"), -15) # Negative means raw DEFLATE
+	// '\x11'
+
+	testCases := []struct {
+		desc   string // Description of the stream
+		stream string // Hexstring of the input DEFLATE stream
+		want   string // Expected result. Use "fail" to expect failure
+	}{{
+		"degenerate HCLenTree",
+		"05e0010000000000100000000000000000000000000000000000000000000000" +
+			"00000000000000000004",
+		"fail",
+	}, {
+		"complete HCLenTree, empty HLitTree, empty HDistTree",
+		"05e0010400000000000000000000000000000000000000000000000000000000" +
+			"00000000000000000010",
+		"fail",
+	}, {
+		"empty HCLenTree",
+		"05e0010000000000000000000000000000000000000000000000000000000000" +
+			"00000000000000000010",
+		"fail",
+	}, {
+		"complete HCLenTree, complete HLitTree, empty HDistTree, use missing HDist symbol",
+		"000100feff000de0010400000000100000000000000000000000000000000000" +
+			"0000000000000000000000000000002c",
+		"fail",
+	}, {
+		"complete HCLenTree, complete HLitTree, degenerate HDistTree, use missing HDist symbol",
+		"000100feff000de0010000000000000000000000000000000000000000000000" +
+			"00000000000000000610000000004070",
+		"fail",
+	}, {
+		"complete HCLenTree, empty HLitTree, empty HDistTree",
+		"05e0010400000000100400000000000000000000000000000000000000000000" +
+			"0000000000000000000000000008",
+		"fail",
+	}, {
+		"complete HCLenTree, empty HLitTree, degenerate HDistTree",
+		"05e0010400000000100400000000000000000000000000000000000000000000" +
+			"0000000000000000000800000008",
+		"fail",
+	}, {
+		"complete HCLenTree, degenerate HLitTree, degenerate HDistTree, use missing HLit symbol",
+		"05e0010400000000100000000000000000000000000000000000000000000000" +
+			"0000000000000000001c",
+		"fail",
+	}, {
+		"complete HCLenTree, complete HLitTree, too large HDistTree",
+		"edff870500000000200400000000000000000000000000000000000000000000" +
+			"000000000000000000080000000000000004",
+		"fail",
+	}, {
+		"complete HCLenTree, complete HLitTree, empty HDistTree, excessive repeater code",
+		"edfd870500000000200400000000000000000000000000000000000000000000" +
+			"000000000000000000e8b100",
+		"fail",
+	}, {
+		"complete HCLenTree, complete HLitTree, empty HDistTree of normal length 30",
+		"05fd01240000000000f8ffffffffffffffffffffffffffffffffffffffffffff" +
+			"ffffffffffffffffff07000000fe01",
+		"",
+	}, {
+		"complete HCLenTree, complete HLitTree, empty HDistTree of excessive length 31",
+		"05fe01240000000000f8ffffffffffffffffffffffffffffffffffffffffffff" +
+			"ffffffffffffffffff07000000fc03",
+		"fail",
+	}, {
+		"complete HCLenTree, over-subscribed HLitTree, empty HDistTree",
+		"05e001240000000000fcffffffffffffffffffffffffffffffffffffffffffff" +
+			"ffffffffffffffffff07f00f",
+		"fail",
+	}, {
+		"complete HCLenTree, under-subscribed HLitTree, empty HDistTree",
+		"05e001240000000000fcffffffffffffffffffffffffffffffffffffffffffff" +
+			"fffffffffcffffffff07f00f",
+		"fail",
+	}, {
+		"complete HCLenTree, complete HLitTree with single code, empty HDistTree",
+		"05e001240000000000f8ffffffffffffffffffffffffffffffffffffffffffff" +
+			"ffffffffffffffffff07f00f",
+		"01",
+	}, {
+		"complete HCLenTree, complete HLitTree with multiple codes, empty HDistTree",
+		"05e301240000000000f8ffffffffffffffffffffffffffffffffffffffffffff" +
+			"ffffffffffffffffff07807f",
+		"01",
+	}, {
+		"complete HCLenTree, complete HLitTree, degenerate HDistTree, use valid HDist symbol",
+		"000100feff000de0010400000000100000000000000000000000000000000000" +
+			"0000000000000000000000000000003c",
+		"00000000",
+	}, {
+		"complete HCLenTree, degenerate HLitTree, degenerate HDistTree",
+		"05e0010400000000100000000000000000000000000000000000000000000000" +
+			"0000000000000000000c",
+		"",
+	}, {
+		"complete HCLenTree, degenerate HLitTree, empty HDistTree",
+		"05e0010400000000100000000000000000000000000000000000000000000000" +
+			"00000000000000000004",
+		"",
+	}, {
+		"complete HCLenTree, complete HLitTree, empty HDistTree, spanning repeater code",
+		"edfd870500000000200400000000000000000000000000000000000000000000" +
+			"000000000000000000e8b000",
+		"",
+	}, {
+		"complete HCLenTree with length codes, complete HLitTree, empty HDistTree",
+		"ede0010400000000100000000000000000000000000000000000000000000000" +
+			"0000000000000000000400004000",
+		"",
+	}, {
+		"complete HCLenTree, complete HLitTree, degenerate HDistTree, use valid HLit symbol 284 with count 31",
+		"000100feff00ede0010400000000100000000000000000000000000000000000" +
+			"000000000000000000000000000000040000407f00",
+		"0000000000000000000000000000000000000000000000000000000000000000" +
+			"0000000000000000000000000000000000000000000000000000000000000000" +
+			"0000000000000000000000000000000000000000000000000000000000000000" +
+			"0000000000000000000000000000000000000000000000000000000000000000" +
+			"0000000000000000000000000000000000000000000000000000000000000000" +
+			"0000000000000000000000000000000000000000000000000000000000000000" +
+			"0000000000000000000000000000000000000000000000000000000000000000" +
+			"0000000000000000000000000000000000000000000000000000000000000000" +
+			"000000",
+	}, {
+		"complete HCLenTree, complete HLitTree, degenerate HDistTree, use valid HLit and HDist symbols",
+		"0cc2010d00000082b0ac4aff0eb07d27060000ffff",
+		"616263616263",
+	}, {
+		"fixed block, use reserved symbol 287",
+		"33180700",
+		"fail",
+	}, {
+		"raw block",
+		"010100feff11",
+		"11",
+	}, {
+		"issue 10426 - over-subscribed HCLenTree causes a hang",
+		"344c4a4e494d4b070000ff2e2eff2e2e2e2e2eff",
+		"fail",
+	}, {
+		"issue 11030 - empty HDistTree unexpectedly leads to error",
+		"05c0070600000080400fff37a0ca",
+		"",
+	}, {
+		"issue 11033 - empty HDistTree unexpectedly leads to error",
+		"050fb109c020cca5d017dcbca044881ee1034ec149c8980bbc413c2ab35be9dc" +
+			"b1473449922449922411202306ee97b0383a521b4ffdcf3217f9f7d3adb701",
+		"3130303634342068652e706870005d05355f7ed957ff084a90925d19e3ebc6d0" +
+			"c6d7",
+	}}
+
+	for i, tc := range testCases {
+		data, err := hex.DecodeString(tc.stream)
+		if err != nil {
+			t.Fatal(err)
+		}
+		data, err = ioutil.ReadAll(NewReader(bytes.NewReader(data)))
+		if tc.want == "fail" {
+			if err == nil {
+				t.Errorf("#%d (%s): got nil error, want non-nil", i, tc.desc)
+			}
+		} else {
+			if err != nil {
+				t.Errorf("#%d (%s): %v", i, tc.desc, err)
+				continue
+			}
+			if got := hex.EncodeToString(data); got != tc.want {
+				t.Errorf("#%d (%s):\ngot  %q\nwant %q", i, tc.desc, got, tc.want)
+			}
+
+		}
+	}
+}
diff --git a/third_party/gofrontend/libgo/go/compress/flate/gen.go b/third_party/gofrontend/libgo/go/compress/flate/gen.go
index 6288ecd..154c89a 100644
--- a/third_party/gofrontend/libgo/go/compress/flate/gen.go
+++ b/third_party/gofrontend/libgo/go/compress/flate/gen.go
@@ -45,7 +45,20 @@
 }
 
 // Initialize Huffman decoding tables from array of code lengths.
+// Following this function, h is guaranteed to be initialized into a complete
+// tree (i.e., neither over-subscribed nor under-subscribed). The exception is a
+// degenerate case where the tree has only a single symbol with length 1. Empty
+// trees are permitted.
 func (h *huffmanDecoder) init(bits []int) bool {
+	// Sanity enables additional runtime tests during Huffman
+	// table construction.  It's intended to be used during
+	// development to supplement the currently ad-hoc unit tests.
+	const sanity = false
+
+	if h.min != 0 {
+		*h = huffmanDecoder{}
+	}
+
 	// Count number of codes of each length,
 	// compute min and max length.
 	var count [maxCodeLen]int
@@ -62,37 +75,53 @@
 		}
 		count[n]++
 	}
+
+	// Empty tree. The decompressor.huffSym function will fail later if the tree
+	// is used. Technically, an empty tree is only valid for the HDIST tree and
+	// not the HCLEN and HLIT tree. However, a stream with an empty HCLEN tree
+	// is guaranteed to fail since it will attempt to use the tree to decode the
+	// codes for the HLIT and HDIST trees. Similarly, an empty HLIT tree is
+	// guaranteed to fail later since the compressed data section must be
+	// composed of at least one symbol (the end-of-block marker).
 	if max == 0 {
+		return true
+	}
+
+	code := 0
+	var nextcode [maxCodeLen]int
+	for i := min; i <= max; i++ {
+		code <<= 1
+		nextcode[i] = code
+		code += count[i]
+	}
+
+	// Check that the coding is complete (i.e., that we've
+	// assigned all 2-to-the-max possible bit sequences).
+	// Exception: To be compatible with zlib, we also need to
+	// accept degenerate single-code codings.  See also
+	// TestDegenerateHuffmanCoding.
+	if code != 1<<uint(max) && !(code == 1 && max == 1) {
 		return false
 	}
 
 	h.min = min
-	var linkBits uint
-	var numLinks int
 	if max > huffmanChunkBits {
-		linkBits = uint(max) - huffmanChunkBits
-		numLinks = 1 << linkBits
+		numLinks := 1 << (uint(max) - huffmanChunkBits)
 		h.linkMask = uint32(numLinks - 1)
-	}
-	code := 0
-	var nextcode [maxCodeLen]int
-	for i := min; i <= max; i++ {
-		if i == huffmanChunkBits+1 {
-			// create link tables
-			link := code >> 1
-			h.links = make([][]uint32, huffmanNumChunks-link)
-			for j := uint(link); j < huffmanNumChunks; j++ {
-				reverse := int(reverseByte[j>>8]) | int(reverseByte[j&0xff])<<8
-				reverse >>= uint(16 - huffmanChunkBits)
-				off := j - uint(link)
-				h.chunks[reverse] = uint32(off<<huffmanValueShift + uint(i))
-				h.links[off] = make([]uint32, 1<<linkBits)
+
+		// create link tables
+		link := nextcode[huffmanChunkBits+1] >> 1
+		h.links = make([][]uint32, huffmanNumChunks-link)
+		for j := uint(link); j < huffmanNumChunks; j++ {
+			reverse := int(reverseByte[j>>8]) | int(reverseByte[j&0xff])<<8
+			reverse >>= uint(16 - huffmanChunkBits)
+			off := j - uint(link)
+			if sanity && h.chunks[reverse] != 0 {
+				panic("impossible: overwriting existing chunk")
 			}
+			h.chunks[reverse] = uint32(off<<huffmanValueShift | (huffmanChunkBits + 1))
+			h.links[off] = make([]uint32, numLinks)
 		}
-		n := count[i]
-		nextcode[i] = code
-		code += n
-		code <<= 1
 	}
 
 	for i, n := range bits {
@@ -105,17 +134,60 @@
 		reverse := int(reverseByte[code>>8]) | int(reverseByte[code&0xff])<<8
 		reverse >>= uint(16 - n)
 		if n <= huffmanChunkBits {
-			for off := reverse; off < huffmanNumChunks; off += 1 << uint(n) {
+			for off := reverse; off < len(h.chunks); off += 1 << uint(n) {
+				// We should never need to overwrite
+				// an existing chunk.  Also, 0 is
+				// never a valid chunk, because the
+				// lower 4 "count" bits should be
+				// between 1 and 15.
+				if sanity && h.chunks[off] != 0 {
+					panic("impossible: overwriting existing chunk")
+				}
 				h.chunks[off] = chunk
 			}
 		} else {
-			linktab := h.links[h.chunks[reverse&(huffmanNumChunks-1)]>>huffmanValueShift]
+			j := reverse & (huffmanNumChunks - 1)
+			if sanity && h.chunks[j]&huffmanCountMask != huffmanChunkBits+1 {
+				// Longer codes should have been
+				// associated with a link table above.
+				panic("impossible: not an indirect chunk")
+			}
+			value := h.chunks[j] >> huffmanValueShift
+			linktab := h.links[value]
 			reverse >>= huffmanChunkBits
-			for off := reverse; off < numLinks; off += 1 << uint(n-huffmanChunkBits) {
+			for off := reverse; off < len(linktab); off += 1 << uint(n-huffmanChunkBits) {
+				if sanity && linktab[off] != 0 {
+					panic("impossible: overwriting existing chunk")
+				}
 				linktab[off] = chunk
 			}
 		}
 	}
+
+	if sanity {
+		// Above we've sanity checked that we never overwrote
+		// an existing entry.  Here we additionally check that
+		// we filled the tables completely.
+		for i, chunk := range h.chunks {
+			if chunk == 0 {
+				// As an exception, in the degenerate
+				// single-code case, we allow odd
+				// chunks to be missing.
+				if code == 1 && i%2 == 1 {
+					continue
+				}
+				panic("impossible: missing chunk")
+			}
+		}
+		for _, linktab := range h.links {
+			for _, chunk := range linktab {
+				if chunk == 0 {
+					panic("impossible: missing chunk")
+				}
+			}
+		}
+	}
+
 	return true
 }
 
@@ -138,6 +210,9 @@
 		bits[i] = 8
 	}
 	h.init(bits[:])
+	if h.links != nil {
+		log.Fatal("Unexpected links table in fixed Huffman decoder")
+	}
 
 	var buf bytes.Buffer
 
diff --git a/third_party/gofrontend/libgo/go/compress/flate/huffman_bit_writer.go b/third_party/gofrontend/libgo/go/compress/flate/huffman_bit_writer.go
index b182a71..6164404 100644
--- a/third_party/gofrontend/libgo/go/compress/flate/huffman_bit_writer.go
+++ b/third_party/gofrontend/libgo/go/compress/flate/huffman_bit_writer.go
@@ -87,11 +87,11 @@
 func newHuffmanBitWriter(w io.Writer) *huffmanBitWriter {
 	return &huffmanBitWriter{
 		w:               w,
-		literalFreq:     make([]int32, maxLit),
+		literalFreq:     make([]int32, maxNumLit),
 		offsetFreq:      make([]int32, offsetCodeCount),
-		codegen:         make([]uint8, maxLit+offsetCodeCount+1),
+		codegen:         make([]uint8, maxNumLit+offsetCodeCount+1),
 		codegenFreq:     make([]int32, codegenCodeCount),
-		literalEncoding: newHuffmanEncoder(maxLit),
+		literalEncoding: newHuffmanEncoder(maxNumLit),
 		offsetEncoding:  newHuffmanEncoder(offsetCodeCount),
 		codegenEncoding: newHuffmanEncoder(codegenCodeCount),
 	}
diff --git a/third_party/gofrontend/libgo/go/compress/flate/huffman_code.go b/third_party/gofrontend/libgo/go/compress/flate/huffman_code.go
index 3b9fce4..50ec79c 100644
--- a/third_party/gofrontend/libgo/go/compress/flate/huffman_code.go
+++ b/third_party/gofrontend/libgo/go/compress/flate/huffman_code.go
@@ -47,11 +47,11 @@
 
 // Generates a HuffmanCode corresponding to the fixed literal table
 func generateFixedLiteralEncoding() *huffmanEncoder {
-	h := newHuffmanEncoder(maxLit)
+	h := newHuffmanEncoder(maxNumLit)
 	codeBits := h.codeBits
 	code := h.code
 	var ch uint16
-	for ch = 0; ch < maxLit; ch++ {
+	for ch = 0; ch < maxNumLit; ch++ {
 		var bits uint16
 		var size uint8
 		switch {
diff --git a/third_party/gofrontend/libgo/go/compress/flate/inflate.go b/third_party/gofrontend/libgo/go/compress/flate/inflate.go
index 76519bb..04372de 100644
--- a/third_party/gofrontend/libgo/go/compress/flate/inflate.go
+++ b/third_party/gofrontend/libgo/go/compress/flate/inflate.go
@@ -18,10 +18,12 @@
 const (
 	maxCodeLen = 16    // max length of Huffman code
 	maxHist    = 32768 // max history required
-	// The next three numbers come from the RFC, section 3.2.7.
-	maxLit   = 286
-	maxDist  = 32
-	numCodes = 19 // number of codes in Huffman meta-code
+	// The next three numbers come from the RFC section 3.2.7, with the
+	// additional proviso in section 3.2.5 which implies that distance codes
+	// 30 and 31 should never occur in compressed data.
+	maxNumLit  = 286
+	maxNumDist = 30
+	numCodes   = 19 // number of codes in Huffman meta-code
 )
 
 // A CorruptInputError reports the presence of corrupt input at a given offset.
@@ -101,7 +103,16 @@
 }
 
 // Initialize Huffman decoding tables from array of code lengths.
+// Following this function, h is guaranteed to be initialized into a complete
+// tree (i.e., neither over-subscribed nor under-subscribed). The exception is a
+// degenerate case where the tree has only a single symbol with length 1. Empty
+// trees are permitted.
 func (h *huffmanDecoder) init(bits []int) bool {
+	// Sanity enables additional runtime tests during Huffman
+	// table construction.  It's intended to be used during
+	// development to supplement the currently ad-hoc unit tests.
+	const sanity = false
+
 	if h.min != 0 {
 		*h = huffmanDecoder{}
 	}
@@ -122,40 +133,53 @@
 		}
 		count[n]++
 	}
+
+	// Empty tree. The decompressor.huffSym function will fail later if the tree
+	// is used. Technically, an empty tree is only valid for the HDIST tree and
+	// not the HCLEN and HLIT tree. However, a stream with an empty HCLEN tree
+	// is guaranteed to fail since it will attempt to use the tree to decode the
+	// codes for the HLIT and HDIST trees. Similarly, an empty HLIT tree is
+	// guaranteed to fail later since the compressed data section must be
+	// composed of at least one symbol (the end-of-block marker).
 	if max == 0 {
+		return true
+	}
+
+	code := 0
+	var nextcode [maxCodeLen]int
+	for i := min; i <= max; i++ {
+		code <<= 1
+		nextcode[i] = code
+		code += count[i]
+	}
+
+	// Check that the coding is complete (i.e., that we've
+	// assigned all 2-to-the-max possible bit sequences).
+	// Exception: To be compatible with zlib, we also need to
+	// accept degenerate single-code codings.  See also
+	// TestDegenerateHuffmanCoding.
+	if code != 1<<uint(max) && !(code == 1 && max == 1) {
 		return false
 	}
 
 	h.min = min
-	var linkBits uint
-	var numLinks int
 	if max > huffmanChunkBits {
-		linkBits = uint(max) - huffmanChunkBits
-		numLinks = 1 << linkBits
+		numLinks := 1 << (uint(max) - huffmanChunkBits)
 		h.linkMask = uint32(numLinks - 1)
-	}
-	code := 0
-	var nextcode [maxCodeLen]int
-	for i := min; i <= max; i++ {
-		if i == huffmanChunkBits+1 {
-			// create link tables
-			link := code >> 1
-			if huffmanNumChunks < link {
-				return false
+
+		// create link tables
+		link := nextcode[huffmanChunkBits+1] >> 1
+		h.links = make([][]uint32, huffmanNumChunks-link)
+		for j := uint(link); j < huffmanNumChunks; j++ {
+			reverse := int(reverseByte[j>>8]) | int(reverseByte[j&0xff])<<8
+			reverse >>= uint(16 - huffmanChunkBits)
+			off := j - uint(link)
+			if sanity && h.chunks[reverse] != 0 {
+				panic("impossible: overwriting existing chunk")
 			}
-			h.links = make([][]uint32, huffmanNumChunks-link)
-			for j := uint(link); j < huffmanNumChunks; j++ {
-				reverse := int(reverseByte[j>>8]) | int(reverseByte[j&0xff])<<8
-				reverse >>= uint(16 - huffmanChunkBits)
-				off := j - uint(link)
-				h.chunks[reverse] = uint32(off<<huffmanValueShift + uint(i))
-				h.links[off] = make([]uint32, 1<<linkBits)
-			}
+			h.chunks[reverse] = uint32(off<<huffmanValueShift | (huffmanChunkBits + 1))
+			h.links[off] = make([]uint32, numLinks)
 		}
-		n := count[i]
-		nextcode[i] = code
-		code += n
-		code <<= 1
 	}
 
 	for i, n := range bits {
@@ -168,21 +192,60 @@
 		reverse := int(reverseByte[code>>8]) | int(reverseByte[code&0xff])<<8
 		reverse >>= uint(16 - n)
 		if n <= huffmanChunkBits {
-			for off := reverse; off < huffmanNumChunks; off += 1 << uint(n) {
+			for off := reverse; off < len(h.chunks); off += 1 << uint(n) {
+				// We should never need to overwrite
+				// an existing chunk.  Also, 0 is
+				// never a valid chunk, because the
+				// lower 4 "count" bits should be
+				// between 1 and 15.
+				if sanity && h.chunks[off] != 0 {
+					panic("impossible: overwriting existing chunk")
+				}
 				h.chunks[off] = chunk
 			}
 		} else {
-			value := h.chunks[reverse&(huffmanNumChunks-1)] >> huffmanValueShift
-			if value >= uint32(len(h.links)) {
-				return false
+			j := reverse & (huffmanNumChunks - 1)
+			if sanity && h.chunks[j]&huffmanCountMask != huffmanChunkBits+1 {
+				// Longer codes should have been
+				// associated with a link table above.
+				panic("impossible: not an indirect chunk")
 			}
+			value := h.chunks[j] >> huffmanValueShift
 			linktab := h.links[value]
 			reverse >>= huffmanChunkBits
-			for off := reverse; off < numLinks; off += 1 << uint(n-huffmanChunkBits) {
+			for off := reverse; off < len(linktab); off += 1 << uint(n-huffmanChunkBits) {
+				if sanity && linktab[off] != 0 {
+					panic("impossible: overwriting existing chunk")
+				}
 				linktab[off] = chunk
 			}
 		}
 	}
+
+	if sanity {
+		// Above we've sanity checked that we never overwrote
+		// an existing entry.  Here we additionally check that
+		// we filled the tables completely.
+		for i, chunk := range h.chunks {
+			if chunk == 0 {
+				// As an exception, in the degenerate
+				// single-code case, we allow odd
+				// chunks to be missing.
+				if code == 1 && i%2 == 1 {
+					continue
+				}
+				panic("impossible: missing chunk")
+			}
+		}
+		for _, linktab := range h.links {
+			for _, chunk := range linktab {
+				if chunk == 0 {
+					panic("impossible: missing chunk")
+				}
+			}
+		}
+	}
+
 	return true
 }
 
@@ -209,7 +272,7 @@
 	h1, h2 huffmanDecoder
 
 	// Length arrays used to define Huffman codes.
-	bits     *[maxLit + maxDist]int
+	bits     *[maxNumLit + maxNumDist]int
 	codebits *[numCodes]int
 
 	// Output history, buffer.
@@ -307,12 +370,14 @@
 		}
 	}
 	nlit := int(f.b&0x1F) + 257
-	if nlit > maxLit {
+	if nlit > maxNumLit {
 		return CorruptInputError(f.roffset)
 	}
 	f.b >>= 5
 	ndist := int(f.b&0x1F) + 1
-	// maxDist is 32, so ndist is always valid.
+	if ndist > maxNumDist {
+		return CorruptInputError(f.roffset)
+	}
 	f.b >>= 5
 	nclen := int(f.b&0xF) + 4
 	// numCodes is 19, so nclen is always valid.
@@ -443,9 +508,12 @@
 		case v < 285:
 			length = v*32 - (281*32 - 131)
 			n = 5
-		default:
+		case v < maxNumLit:
 			length = 258
 			n = 0
+		default:
+			f.err = CorruptInputError(f.roffset)
+			return
 		}
 		if n > 0 {
 			for f.nb < n {
@@ -480,10 +548,7 @@
 		switch {
 		case dist < 4:
 			dist++
-		case dist >= 30:
-			f.err = CorruptInputError(f.roffset)
-			return
-		default:
+		case dist < maxNumDist:
 			nb := uint(dist-2) >> 1
 			// have 1 bit in bottom of dist, need nb more.
 			extra := (dist & 1) << nb
@@ -497,6 +562,9 @@
 			f.b >>= nb
 			f.nb -= nb
 			dist = 1<<(nb+1) + 1 + extra
+		default:
+			f.err = CorruptInputError(f.roffset)
+			return
 		}
 
 		// Copy history[-dist:-dist+length] into output.
@@ -643,6 +711,10 @@
 
 // Read the next Huffman-encoded symbol from f according to h.
 func (f *decompressor) huffSym(h *huffmanDecoder) (int, error) {
+	// Since a huffmanDecoder can be empty or be composed of a degenerate tree
+	// with single element, huffSym must error on these two edge cases. In both
+	// cases, the chunks slice will be 0 for the invalid sequence, leading it
+	// satisfy the n == 0 check below.
 	n := uint(h.min)
 	for {
 		for f.nb < n {
@@ -655,12 +727,12 @@
 		if n > huffmanChunkBits {
 			chunk = h.links[chunk>>huffmanValueShift][(f.b>>huffmanChunkBits)&h.linkMask]
 			n = uint(chunk & huffmanCountMask)
+		}
+		if n <= f.nb {
 			if n == 0 {
 				f.err = CorruptInputError(f.roffset)
 				return 0, f.err
 			}
-		}
-		if n <= f.nb {
 			f.b >>= n
 			f.nb -= n
 			return int(chunk >> huffmanValueShift), nil
@@ -712,7 +784,7 @@
 // The ReadCloser returned by NewReader also implements Resetter.
 func NewReader(r io.Reader) io.ReadCloser {
 	var f decompressor
-	f.bits = new([maxLit + maxDist]int)
+	f.bits = new([maxNumLit + maxNumDist]int)
 	f.codebits = new([numCodes]int)
 	f.r = makeReader(r)
 	f.hist = new([maxHist]byte)
@@ -731,7 +803,7 @@
 	var f decompressor
 	f.r = makeReader(r)
 	f.hist = new([maxHist]byte)
-	f.bits = new([maxLit + maxDist]int)
+	f.bits = new([maxNumLit + maxNumDist]int)
 	f.codebits = new([numCodes]int)
 	f.step = (*decompressor).nextBlock
 	f.setDict(dict)
diff --git a/third_party/gofrontend/libgo/go/compress/lzw/reader.go b/third_party/gofrontend/libgo/go/compress/lzw/reader.go
index 526620c..1353831 100644
--- a/third_party/gofrontend/libgo/go/compress/lzw/reader.go
+++ b/third_party/gofrontend/libgo/go/compress/lzw/reader.go
@@ -139,6 +139,7 @@
 				err = io.ErrUnexpectedEOF
 			}
 			d.err = err
+			d.flush()
 			return
 		}
 		switch {
@@ -190,6 +191,7 @@
 			}
 		default:
 			d.err = errors.New("lzw: invalid code")
+			d.flush()
 			return
 		}
 		d.last, d.hi = code, d.hi+1
@@ -213,7 +215,7 @@
 	d.o = 0
 }
 
-var errClosed = errors.New("compress/lzw: reader/writer is closed")
+var errClosed = errors.New("lzw: reader/writer is closed")
 
 func (d *decoder) Close() error {
 	d.err = errClosed // in case any Reads come along
@@ -227,7 +229,8 @@
 // It is the caller's responsibility to call Close on the ReadCloser when
 // finished reading.
 // The number of bits to use for literal codes, litWidth, must be in the
-// range [2,8] and is typically 8.
+// range [2,8] and is typically 8. It must equal the litWidth
+// used during compression.
 func NewReader(r io.Reader, order Order, litWidth int) io.ReadCloser {
 	d := new(decoder)
 	switch order {
diff --git a/third_party/gofrontend/libgo/go/compress/lzw/reader_test.go b/third_party/gofrontend/libgo/go/compress/lzw/reader_test.go
index 9006c91..c3a5c3a 100644
--- a/third_party/gofrontend/libgo/go/compress/lzw/reader_test.go
+++ b/third_party/gofrontend/libgo/go/compress/lzw/reader_test.go
@@ -98,13 +98,20 @@
 		defer rc.Close()
 		b.Reset()
 		n, err := io.Copy(&b, rc)
+		s := b.String()
 		if err != nil {
 			if err != tt.err {
 				t.Errorf("%s: io.Copy: %v want %v", tt.desc, err, tt.err)
 			}
+			if err == io.ErrUnexpectedEOF {
+				// Even if the input is truncated, we should still return the
+				// partial decoded result.
+				if n == 0 || !strings.HasPrefix(tt.raw, s) {
+					t.Errorf("got %d bytes (%q), want a non-empty prefix of %q", n, s, tt.raw)
+				}
+			}
 			continue
 		}
-		s := b.String()
 		if s != tt.raw {
 			t.Errorf("%s: got %d-byte %q want %d-byte %q", tt.desc, n, s, len(tt.raw), tt.raw)
 		}
diff --git a/third_party/gofrontend/libgo/go/compress/lzw/writer.go b/third_party/gofrontend/libgo/go/compress/lzw/writer.go
index 961b25f..7367c29 100644
--- a/third_party/gofrontend/libgo/go/compress/lzw/writer.go
+++ b/third_party/gofrontend/libgo/go/compress/lzw/writer.go
@@ -138,16 +138,23 @@
 	if len(p) == 0 {
 		return 0, nil
 	}
+	if maxLit := uint8(1<<e.litWidth - 1); maxLit != 0xff {
+		for _, x := range p {
+			if x > maxLit {
+				e.err = errors.New("lzw: input byte too large for the litWidth")
+				return 0, e.err
+			}
+		}
+	}
 	n = len(p)
-	litMask := uint32(1<<e.litWidth - 1)
 	code := e.savedCode
 	if code == invalidCode {
 		// The first code sent is always a literal code.
-		code, p = uint32(p[0])&litMask, p[1:]
+		code, p = uint32(p[0]), p[1:]
 	}
 loop:
 	for _, x := range p {
-		literal := uint32(x) & litMask
+		literal := uint32(x)
 		key := code<<8 | literal
 		// If there is a hash table hit for this key then we continue the loop
 		// and do not emit a code yet.
@@ -230,7 +237,7 @@
 // It is the caller's responsibility to call Close on the WriteCloser when
 // finished writing.
 // The number of bits to use for literal codes, litWidth, must be in the
-// range [2,8] and is typically 8.
+// range [2,8] and is typically 8. Input bytes must be less than 1<<litWidth.
 func NewWriter(w io.Writer, order Order, litWidth int) io.WriteCloser {
 	var write func(*encoder, uint32) error
 	switch order {
diff --git a/third_party/gofrontend/libgo/go/compress/lzw/writer_test.go b/third_party/gofrontend/libgo/go/compress/lzw/writer_test.go
index 3e4e6de..c20d058 100644
--- a/third_party/gofrontend/libgo/go/compress/lzw/writer_test.go
+++ b/third_party/gofrontend/libgo/go/compress/lzw/writer_test.go
@@ -104,6 +104,16 @@
 	}
 }
 
+func TestSmallLitWidth(t *testing.T) {
+	w := NewWriter(ioutil.Discard, LSB, 2)
+	if _, err := w.Write([]byte{0x03}); err != nil {
+		t.Fatalf("write a byte < 1<<2: %v", err)
+	}
+	if _, err := w.Write([]byte{0x04}); err == nil {
+		t.Fatal("write a byte >= 1<<2: got nil error, want non-nil")
+	}
+}
+
 func benchmarkEncoder(b *testing.B, n int) {
 	b.StopTimer()
 	b.SetBytes(int64(n))
diff --git a/third_party/gofrontend/libgo/go/crypto/cipher/cipher.go b/third_party/gofrontend/libgo/go/crypto/cipher/cipher.go
index 67afdb1..7d27fde 100644
--- a/third_party/gofrontend/libgo/go/crypto/cipher/cipher.go
+++ b/third_party/gofrontend/libgo/go/crypto/cipher/cipher.go
@@ -29,6 +29,9 @@
 type Stream interface {
 	// XORKeyStream XORs each byte in the given slice with a byte from the
 	// cipher's key stream. Dst and src may point to the same memory.
+	// If len(dst) < len(src), XORKeyStream should panic. It is acceptable
+	// to pass a dst bigger than src, and in that case, XORKeyStream will
+	// only update dst[:len(src)] and will not touch the rest of dst.
 	XORKeyStream(dst, src []byte)
 }
 
diff --git a/third_party/gofrontend/libgo/go/crypto/cipher/gcm.go b/third_party/gofrontend/libgo/go/crypto/cipher/gcm.go
index bdafd85..bbdf9f5 100644
--- a/third_party/gofrontend/libgo/go/crypto/cipher/gcm.go
+++ b/third_party/gofrontend/libgo/go/crypto/cipher/gcm.go
@@ -52,14 +52,26 @@
 // gcm represents a Galois Counter Mode with a specific key. See
 // http://csrc.nist.gov/groups/ST/toolkit/BCM/documents/proposedmodes/gcm/gcm-revised-spec.pdf
 type gcm struct {
-	cipher Block
+	cipher    Block
+	nonceSize int
 	// productTable contains the first sixteen powers of the key, H.
-	// However, they are in bit reversed order. See NewGCM.
+	// However, they are in bit reversed order. See NewGCMWithNonceSize.
 	productTable [16]gcmFieldElement
 }
 
-// NewGCM returns the given 128-bit, block cipher wrapped in Galois Counter Mode.
+// NewGCM returns the given 128-bit, block cipher wrapped in Galois Counter Mode
+// with the standard nonce length.
 func NewGCM(cipher Block) (AEAD, error) {
+	return NewGCMWithNonceSize(cipher, gcmStandardNonceSize)
+}
+
+// NewGCMWithNonceSize returns the given 128-bit, block cipher wrapped in Galois
+// Counter Mode, which accepts nonces of the given length.
+//
+// Only use this function if you require compatibility with an existing
+// cryptosystem that uses non-standard nonce lengths. All other users should use
+// NewGCM, which is faster and more resistant to misuse.
+func NewGCMWithNonceSize(cipher Block, size int) (AEAD, error) {
 	if cipher.BlockSize() != gcmBlockSize {
 		return nil, errors.New("cipher: NewGCM requires 128-bit block cipher")
 	}
@@ -67,7 +79,7 @@
 	var key [gcmBlockSize]byte
 	cipher.Encrypt(key[:], key[:])
 
-	g := &gcm{cipher: cipher}
+	g := &gcm{cipher: cipher, nonceSize: size}
 
 	// We precompute 16 multiples of |key|. However, when we do lookups
 	// into this table we'll be using bits from a field element and
@@ -89,13 +101,13 @@
 }
 
 const (
-	gcmBlockSize = 16
-	gcmTagSize   = 16
-	gcmNonceSize = 12
+	gcmBlockSize         = 16
+	gcmTagSize           = 16
+	gcmStandardNonceSize = 12
 )
 
-func (*gcm) NonceSize() int {
-	return gcmNonceSize
+func (g *gcm) NonceSize() int {
+	return g.nonceSize
 }
 
 func (*gcm) Overhead() int {
@@ -103,16 +115,13 @@
 }
 
 func (g *gcm) Seal(dst, nonce, plaintext, data []byte) []byte {
-	if len(nonce) != gcmNonceSize {
+	if len(nonce) != g.nonceSize {
 		panic("cipher: incorrect nonce length given to GCM")
 	}
-
 	ret, out := sliceForAppend(dst, len(plaintext)+gcmTagSize)
 
-	// See GCM spec, section 7.1.
 	var counter, tagMask [gcmBlockSize]byte
-	copy(counter[:], nonce)
-	counter[gcmBlockSize-1] = 1
+	g.deriveCounter(&counter, nonce)
 
 	g.cipher.Encrypt(tagMask[:], counter[:])
 	gcmInc32(&counter)
@@ -126,7 +135,7 @@
 var errOpen = errors.New("cipher: message authentication failed")
 
 func (g *gcm) Open(dst, nonce, ciphertext, data []byte) ([]byte, error) {
-	if len(nonce) != gcmNonceSize {
+	if len(nonce) != g.nonceSize {
 		panic("cipher: incorrect nonce length given to GCM")
 	}
 
@@ -136,10 +145,8 @@
 	tag := ciphertext[len(ciphertext)-gcmTagSize:]
 	ciphertext = ciphertext[:len(ciphertext)-gcmTagSize]
 
-	// See GCM spec, section 7.1.
 	var counter, tagMask [gcmBlockSize]byte
-	copy(counter[:], nonce)
-	counter[gcmBlockSize-1] = 1
+	g.deriveCounter(&counter, nonce)
 
 	g.cipher.Encrypt(tagMask[:], counter[:])
 	gcmInc32(&counter)
@@ -198,7 +205,7 @@
 	0xe100, 0xfd20, 0xd940, 0xc560, 0x9180, 0x8da0, 0xa9c0, 0xb5e0,
 }
 
-// mul sets y to y*H, where H is the GCM key, fixed during NewGCM.
+// mul sets y to y*H, where H is the GCM key, fixed during NewGCMWithNonceSize.
 func (g *gcm) mul(y *gcmFieldElement) {
 	var z gcmFieldElement
 
@@ -219,7 +226,7 @@
 
 			// the values in |table| are ordered for
 			// little-endian bit positions. See the comment
-			// in NewGCM.
+			// in NewGCMWithNonceSize.
 			t := &g.productTable[word&0xf]
 
 			z.low ^= t.low
@@ -301,6 +308,29 @@
 	}
 }
 
+// deriveCounter computes the initial GCM counter state from the given nonce.
+// See NIST SP 800-38D, section 7.1. This assumes that counter is filled with
+// zeros on entry.
+func (g *gcm) deriveCounter(counter *[gcmBlockSize]byte, nonce []byte) {
+	// GCM has two modes of operation with respect to the initial counter
+	// state: a "fast path" for 96-bit (12-byte) nonces, and a "slow path"
+	// for nonces of other lengths. For a 96-bit nonce, the nonce, along
+	// with a four-byte big-endian counter starting at one, is used
+	// directly as the starting counter. For other nonce sizes, the counter
+	// is computed by passing it through the GHASH function.
+	if len(nonce) == gcmStandardNonceSize {
+		copy(counter[:], nonce)
+		counter[gcmBlockSize-1] = 1
+	} else {
+		var y gcmFieldElement
+		g.update(&y, nonce)
+		y.high ^= uint64(len(nonce)) * 8
+		g.mul(&y)
+		putUint64(counter[:8], y.low)
+		putUint64(counter[8:], y.high)
+	}
+}
+
 // auth calculates GHASH(ciphertext, additionalData), masks the result with
 // tagMask and writes the result to out.
 func (g *gcm) auth(out, ciphertext, additionalData []byte, tagMask *[gcmTagSize]byte) {
diff --git a/third_party/gofrontend/libgo/go/crypto/cipher/gcm_test.go b/third_party/gofrontend/libgo/go/crypto/cipher/gcm_test.go
index 0c502ce..81b9aa2 100644
--- a/third_party/gofrontend/libgo/go/crypto/cipher/gcm_test.go
+++ b/third_party/gofrontend/libgo/go/crypto/cipher/gcm_test.go
@@ -101,6 +101,35 @@
 		"",
 		"b2051c80014f42f08735a7b0cd38e6bcd29962e5f2c13626b85a877101",
 	},
+	// These cases test non-standard nonce sizes.
+	{
+		"1672c3537afa82004c6b8a46f6f0d026",
+		"05",
+		"",
+		"",
+		"8e2ad721f9455f74d8b53d3141f27e8e",
+	},
+	{
+		"9a4fea86a621a91ab371e492457796c0",
+		"75",
+		"ca6131faf0ff210e4e693d6c31c109fc5b6f54224eb120f37de31dc59ec669b6",
+		"4f6e2585c161f05a9ae1f2f894e9f0ab52b45d0f",
+		"5698c0a384241d30004290aac56bb3ece6fe8eacc5c4be98954deb9c3ff6aebf5d50e1af100509e1fba2a5e8a0af9670",
+	},
+	{
+		"d0f1f4defa1e8c08b4b26d576392027c",
+		"42b4f01eb9f5a1ea5b1eb73b0fb0baed54f387ecaa0393c7d7dffc6af50146ecc021abf7eb9038d4303d91f8d741a11743166c0860208bcc02c6258fd9511a2fa626f96d60b72fcff773af4e88e7a923506e4916ecbd814651e9f445adef4ad6a6b6c7290cc13b956130eef5b837c939fcac0cbbcc9656cd75b13823ee5acdac",
+		"",
+		"",
+		"7ab49b57ddf5f62c427950111c5c4f0d",
+	},
+	{
+		"4a0c00a3d284dea9d4bf8b8dde86685e",
+		"f8cbe82588e784bcacbe092cd9089b51e01527297f635bf294b3aa787d91057ef23869789698ac960707857f163ecb242135a228ad93964f5dc4a4d7f88fd7b3b07dd0a5b37f9768fb05a523639f108c34c661498a56879e501a2321c8a4a94d7e1b89db255ac1f685e185263368e99735ebe62a7f2931b47282be8eb165e4d7",
+		"6d4bf87640a6a48a50d28797b7",
+		"8d8c7ffc55086d539b5a8f0d1232654c",
+		"0d803ec309482f35b8e6226f2b56303239298e06b281c2d51aaba3c125",
+	},
 }
 
 func TestAESGCM(t *testing.T) {
@@ -114,7 +143,7 @@
 		nonce, _ := hex.DecodeString(test.nonce)
 		plaintext, _ := hex.DecodeString(test.plaintext)
 		ad, _ := hex.DecodeString(test.ad)
-		aesgcm, err := cipher.NewGCM(aes)
+		aesgcm, err := cipher.NewGCMWithNonceSize(aes, len(nonce))
 		if err != nil {
 			t.Fatal(err)
 		}
diff --git a/third_party/gofrontend/libgo/go/crypto/crypto.go b/third_party/gofrontend/libgo/go/crypto/crypto.go
index 59b23e9..184ea9d 100644
--- a/third_party/gofrontend/libgo/go/crypto/crypto.go
+++ b/third_party/gofrontend/libgo/go/crypto/crypto.go
@@ -21,36 +21,40 @@
 }
 
 const (
-	MD4       Hash = 1 + iota // import golang.org/x/crypto/md4
-	MD5                       // import crypto/md5
-	SHA1                      // import crypto/sha1
-	SHA224                    // import crypto/sha256
-	SHA256                    // import crypto/sha256
-	SHA384                    // import crypto/sha512
-	SHA512                    // import crypto/sha512
-	MD5SHA1                   // no implementation; MD5+SHA1 used for TLS RSA
-	RIPEMD160                 // import golang.org/x/crypto/ripemd160
-	SHA3_224                  // import golang.org/x/crypto/sha3
-	SHA3_256                  // import golang.org/x/crypto/sha3
-	SHA3_384                  // import golang.org/x/crypto/sha3
-	SHA3_512                  // import golang.org/x/crypto/sha3
+	MD4        Hash = 1 + iota // import golang.org/x/crypto/md4
+	MD5                        // import crypto/md5
+	SHA1                       // import crypto/sha1
+	SHA224                     // import crypto/sha256
+	SHA256                     // import crypto/sha256
+	SHA384                     // import crypto/sha512
+	SHA512                     // import crypto/sha512
+	MD5SHA1                    // no implementation; MD5+SHA1 used for TLS RSA
+	RIPEMD160                  // import golang.org/x/crypto/ripemd160
+	SHA3_224                   // import golang.org/x/crypto/sha3
+	SHA3_256                   // import golang.org/x/crypto/sha3
+	SHA3_384                   // import golang.org/x/crypto/sha3
+	SHA3_512                   // import golang.org/x/crypto/sha3
+	SHA512_224                 // import crypto/sha512
+	SHA512_256                 // import crypto/sha512
 	maxHash
 )
 
 var digestSizes = []uint8{
-	MD4:       16,
-	MD5:       16,
-	SHA1:      20,
-	SHA224:    28,
-	SHA256:    32,
-	SHA384:    48,
-	SHA512:    64,
-	SHA3_224:  28,
-	SHA3_256:  32,
-	SHA3_384:  48,
-	SHA3_512:  64,
-	MD5SHA1:   36,
-	RIPEMD160: 20,
+	MD4:        16,
+	MD5:        16,
+	SHA1:       20,
+	SHA224:     28,
+	SHA256:     32,
+	SHA384:     48,
+	SHA512:     64,
+	SHA512_224: 28,
+	SHA512_256: 32,
+	SHA3_224:   28,
+	SHA3_256:   32,
+	SHA3_384:   48,
+	SHA3_512:   64,
+	MD5SHA1:    36,
+	RIPEMD160:  20,
 }
 
 // Size returns the length, in bytes, of a digest resulting from the given hash
@@ -124,3 +128,19 @@
 	// hashing was done.
 	HashFunc() Hash
 }
+
+// Decrypter is an interface for an opaque private key that can be used for
+// asymmetric decryption operations. An example would be an RSA key
+// kept in a hardware module.
+type Decrypter interface {
+	// Public returns the public key corresponding to the opaque,
+	// private key.
+	Public() PublicKey
+
+	// Decrypt decrypts msg. The opts argument should be appropriate for
+	// the primitive used. See the documentation in each implementation for
+	// details.
+	Decrypt(rand io.Reader, msg []byte, opts DecrypterOpts) (plaintext []byte, err error)
+}
+
+type DecrypterOpts interface{}
diff --git a/third_party/gofrontend/libgo/go/crypto/ecdsa/ecdsa.go b/third_party/gofrontend/libgo/go/crypto/ecdsa/ecdsa.go
index d613553..8d66477 100644
--- a/third_party/gofrontend/libgo/go/crypto/ecdsa/ecdsa.go
+++ b/third_party/gofrontend/libgo/go/crypto/ecdsa/ecdsa.go
@@ -4,22 +4,33 @@
 
 // Package ecdsa implements the Elliptic Curve Digital Signature Algorithm, as
 // defined in FIPS 186-3.
+//
+// This implementation  derives the nonce from an AES-CTR CSPRNG keyed by
+// ChopMD(256, SHA2-512(priv.D || entropy || hash)). The CSPRNG key is IRO by
+// a result of Coron; the AES-CTR stream is IRO under standard assumptions.
 package ecdsa
 
 // References:
 //   [NSA]: Suite B implementer's guide to FIPS 186-3,
 //     http://www.nsa.gov/ia/_files/ecdsa.pdf
 //   [SECG]: SECG, SEC1
-//     http://www.secg.org/download/aid-780/sec1-v2.pdf
+//     http://www.secg.org/sec1-v2.pdf
 
 import (
 	"crypto"
+	"crypto/aes"
+	"crypto/cipher"
 	"crypto/elliptic"
+	"crypto/sha512"
 	"encoding/asn1"
 	"io"
 	"math/big"
 )
 
+const (
+	aesIV = "IV for ECDSA CTR"
+)
+
 // PublicKey represents an ECDSA public key.
 type PublicKey struct {
 	elliptic.Curve
@@ -123,6 +134,38 @@
 // pair of integers. The security of the private key depends on the entropy of
 // rand.
 func Sign(rand io.Reader, priv *PrivateKey, hash []byte) (r, s *big.Int, err error) {
+	// Get max(log2(q) / 2, 256) bits of entropy from rand.
+	entropylen := (priv.Curve.Params().BitSize + 7) / 16
+	if entropylen > 32 {
+		entropylen = 32
+	}
+	entropy := make([]byte, entropylen)
+	_, err = io.ReadFull(rand, entropy)
+	if err != nil {
+		return
+	}
+
+	// Initialize an SHA-512 hash context; digest ...
+	md := sha512.New()
+	md.Write(priv.D.Bytes()) // the private key,
+	md.Write(entropy)        // the entropy,
+	md.Write(hash)           // and the input hash;
+	key := md.Sum(nil)[:32]  // and compute ChopMD-256(SHA-512),
+	// which is an indifferentiable MAC.
+
+	// Create an AES-CTR instance to use as a CSPRNG.
+	block, err := aes.NewCipher(key)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	// Create a CSPRNG that xors a stream of zeros with
+	// the output of the AES-CTR instance.
+	csprng := cipher.StreamReader{
+		R: zeroReader,
+		S: cipher.NewCTR(block, []byte(aesIV)),
+	}
+
 	// See [NSA] 3.4.1
 	c := priv.PublicKey.Curve
 	N := c.Params().N
@@ -130,7 +173,7 @@
 	var k, kInv *big.Int
 	for {
 		for {
-			k, err = randFieldElement(c, rand)
+			k, err = randFieldElement(c, csprng)
 			if err != nil {
 				r = nil
 				return
@@ -187,3 +230,17 @@
 	x.Mod(x, N)
 	return x.Cmp(r) == 0
 }
+
+type zr struct {
+	io.Reader
+}
+
+// Read replaces the contents of dst with zeros.
+func (z *zr) Read(dst []byte) (n int, err error) {
+	for i := range dst {
+		dst[i] = 0
+	}
+	return len(dst), nil
+}
+
+var zeroReader = &zr{}
diff --git a/third_party/gofrontend/libgo/go/crypto/ecdsa/ecdsa_test.go b/third_party/gofrontend/libgo/go/crypto/ecdsa/ecdsa_test.go
index 0c06431..169944d 100644
--- a/third_party/gofrontend/libgo/go/crypto/ecdsa/ecdsa_test.go
+++ b/third_party/gofrontend/libgo/go/crypto/ecdsa/ecdsa_test.go
@@ -72,6 +72,78 @@
 	testSignAndVerify(t, elliptic.P521(), "p521")
 }
 
+func testNonceSafety(t *testing.T, c elliptic.Curve, tag string) {
+	priv, _ := GenerateKey(c, rand.Reader)
+
+	hashed := []byte("testing")
+	r0, s0, err := Sign(zeroReader, priv, hashed)
+	if err != nil {
+		t.Errorf("%s: error signing: %s", tag, err)
+		return
+	}
+
+	hashed = []byte("testing...")
+	r1, s1, err := Sign(zeroReader, priv, hashed)
+	if err != nil {
+		t.Errorf("%s: error signing: %s", tag, err)
+		return
+	}
+
+	if s0.Cmp(s1) == 0 {
+		// This should never happen.
+		t.Errorf("%s: the signatures on two different messages were the same")
+	}
+
+	if r0.Cmp(r1) == 0 {
+		t.Errorf("%s: the nonce used for two diferent messages was the same")
+	}
+}
+
+func TestNonceSafety(t *testing.T) {
+	testNonceSafety(t, elliptic.P224(), "p224")
+	if testing.Short() {
+		return
+	}
+	testNonceSafety(t, elliptic.P256(), "p256")
+	testNonceSafety(t, elliptic.P384(), "p384")
+	testNonceSafety(t, elliptic.P521(), "p521")
+}
+
+func testINDCCA(t *testing.T, c elliptic.Curve, tag string) {
+	priv, _ := GenerateKey(c, rand.Reader)
+
+	hashed := []byte("testing")
+	r0, s0, err := Sign(rand.Reader, priv, hashed)
+	if err != nil {
+		t.Errorf("%s: error signing: %s", tag, err)
+		return
+	}
+
+	r1, s1, err := Sign(rand.Reader, priv, hashed)
+	if err != nil {
+		t.Errorf("%s: error signing: %s", tag, err)
+		return
+	}
+
+	if s0.Cmp(s1) == 0 {
+		t.Errorf("%s: two signatures of the same message produced the same result")
+	}
+
+	if r0.Cmp(r1) == 0 {
+		t.Errorf("%s: two signatures of the same message produced the same nonce")
+	}
+}
+
+func TestINDCCA(t *testing.T) {
+	testINDCCA(t, elliptic.P224(), "p224")
+	if testing.Short() {
+		return
+	}
+	testINDCCA(t, elliptic.P256(), "p256")
+	testINDCCA(t, elliptic.P384(), "p384")
+	testINDCCA(t, elliptic.P521(), "p521")
+}
+
 func fromHex(s string) *big.Int {
 	r, ok := new(big.Int).SetString(s, 16)
 	if !ok {
diff --git a/third_party/gofrontend/libgo/go/crypto/elliptic/elliptic.go b/third_party/gofrontend/libgo/go/crypto/elliptic/elliptic.go
index ba673f8..e6b59c5 100644
--- a/third_party/gofrontend/libgo/go/crypto/elliptic/elliptic.go
+++ b/third_party/gofrontend/libgo/go/crypto/elliptic/elliptic.go
@@ -24,7 +24,7 @@
 type Curve interface {
 	// Params returns the parameters for the curve.
 	Params() *CurveParams
-	// IsOnCurve returns true if the given (x,y) lies on the curve.
+	// IsOnCurve reports whether the given (x,y) lies on the curve.
 	IsOnCurve(x, y *big.Int) bool
 	// Add returns the sum of (x1,y1) and (x2,y2)
 	Add(x1, y1, x2, y2 *big.Int) (x, y *big.Int)
@@ -45,6 +45,7 @@
 	B       *big.Int // the constant of the curve equation
 	Gx, Gy  *big.Int // (x,y) of the base point
 	BitSize int      // the size of the underlying field
+	Name    string   // the canonical name of the curve
 }
 
 func (curve *CurveParams) Params() *CurveParams {
@@ -307,7 +308,8 @@
 	return ret
 }
 
-// Unmarshal converts a point, serialized by Marshal, into an x, y pair. On error, x = nil.
+// Unmarshal converts a point, serialized by Marshal, into an x, y pair.
+// It is an error if the point is not on the curve. On error, x = nil.
 func Unmarshal(curve Curve, data []byte) (x, y *big.Int) {
 	byteLen := (curve.Params().BitSize + 7) >> 3
 	if len(data) != 1+2*byteLen {
@@ -318,6 +320,9 @@
 	}
 	x = new(big.Int).SetBytes(data[1 : 1+byteLen])
 	y = new(big.Int).SetBytes(data[1+byteLen:])
+	if !curve.IsOnCurve(x, y) {
+		x, y = nil, nil
+	}
 	return
 }
 
@@ -334,7 +339,7 @@
 
 func initP384() {
 	// See FIPS 186-3, section D.2.4
-	p384 = new(CurveParams)
+	p384 = &CurveParams{Name: "P-384"}
 	p384.P, _ = new(big.Int).SetString("39402006196394479212279040100143613805079739270465446667948293404245721771496870329047266088258938001861606973112319", 10)
 	p384.N, _ = new(big.Int).SetString("39402006196394479212279040100143613805079739270465446667946905279627659399113263569398956308152294913554433653942643", 10)
 	p384.B, _ = new(big.Int).SetString("b3312fa7e23ee7e4988e056be3f82d19181d9c6efe8141120314088f5013875ac656398d8a2ed19d2a85c8edd3ec2aef", 16)
@@ -345,7 +350,7 @@
 
 func initP521() {
 	// See FIPS 186-3, section D.2.5
-	p521 = new(CurveParams)
+	p521 = &CurveParams{Name: "P-521"}
 	p521.P, _ = new(big.Int).SetString("6864797660130609714981900799081393217269435300143305409394463459185543183397656052122559640661454554977296311391480858037121987999716643812574028291115057151", 10)
 	p521.N, _ = new(big.Int).SetString("6864797660130609714981900799081393217269435300143305409394463459185543183397655394245057746333217197532963996371363321113864768612440380340372808892707005449", 10)
 	p521.B, _ = new(big.Int).SetString("051953eb9618e1c9a1f929a21a0b68540eea2da725b99b315f3b8b489918ef109e156193951ec7e937b1652c0bd3bb1bf073573df883d2c34f1ef451fd46b503f00", 16)
diff --git a/third_party/gofrontend/libgo/go/crypto/elliptic/elliptic_test.go b/third_party/gofrontend/libgo/go/crypto/elliptic/elliptic_test.go
index 4dc27c9..7e27913 100644
--- a/third_party/gofrontend/libgo/go/crypto/elliptic/elliptic_test.go
+++ b/third_party/gofrontend/libgo/go/crypto/elliptic/elliptic_test.go
@@ -19,6 +19,19 @@
 	}
 }
 
+func TestOffCurve(t *testing.T) {
+	p224 := P224()
+	x, y := new(big.Int).SetInt64(1), new(big.Int).SetInt64(1)
+	if p224.IsOnCurve(x, y) {
+		t.Errorf("FAIL: point off curve is claimed to be on the curve")
+	}
+	b := Marshal(p224, x, y)
+	x1, y1 := Unmarshal(p224, b)
+	if x1 != nil || y1 != nil {
+		t.Errorf("FAIL: unmarshalling a point not on the curve succeeded")
+	}
+}
+
 type baseMultTest struct {
 	k    string
 	x, y string
diff --git a/third_party/gofrontend/libgo/go/crypto/elliptic/p224.go b/third_party/gofrontend/libgo/go/crypto/elliptic/p224.go
index 1f7ff3f..2d3fac7 100644
--- a/third_party/gofrontend/libgo/go/crypto/elliptic/p224.go
+++ b/third_party/gofrontend/libgo/go/crypto/elliptic/p224.go
@@ -22,7 +22,7 @@
 
 func initP224() {
 	// See FIPS 186-3, section D.2.2
-	p224.CurveParams = new(CurveParams)
+	p224.CurveParams = &CurveParams{Name: "P-224"}
 	p224.P, _ = new(big.Int).SetString("26959946667150639794667015087019630673557916260026308143510066298881", 10)
 	p224.N, _ = new(big.Int).SetString("26959946667150639794667015087019625940457807714424391721682722368061", 10)
 	p224.B, _ = new(big.Int).SetString("b4050a850c04b3abf54132565044b0b7d7bfd8ba270b39432355ffb4", 16)
diff --git a/third_party/gofrontend/libgo/go/crypto/elliptic/p256.go b/third_party/gofrontend/libgo/go/crypto/elliptic/p256.go
index 82be51e..82bc7b3 100644
--- a/third_party/gofrontend/libgo/go/crypto/elliptic/p256.go
+++ b/third_party/gofrontend/libgo/go/crypto/elliptic/p256.go
@@ -23,7 +23,7 @@
 
 func initP256() {
 	// See FIPS 186-3, section D.2.3
-	p256.CurveParams = new(CurveParams)
+	p256.CurveParams = &CurveParams{Name: "P-256"}
 	p256.P, _ = new(big.Int).SetString("115792089210356248762697446949407573530086143415290314195533631308867097853951", 10)
 	p256.N, _ = new(big.Int).SetString("115792089210356248762697446949407573529996955224135760342422259061068512044369", 10)
 	p256.B, _ = new(big.Int).SetString("5ac635d8aa3a93e7b3ebbd55769886bc651d06b0cc53b0f63bce3c3e27d2604b", 16)
diff --git a/third_party/gofrontend/libgo/go/crypto/hmac/hmac.go b/third_party/gofrontend/libgo/go/crypto/hmac/hmac.go
index b6f4919..e0cc1d6 100644
--- a/third_party/gofrontend/libgo/go/crypto/hmac/hmac.go
+++ b/third_party/gofrontend/libgo/go/crypto/hmac/hmac.go
@@ -11,7 +11,7 @@
 Receivers should be careful to use Equal to compare MACs in order to avoid
 timing side-channels:
 
-	// CheckMAC returns true if messageMAC is a valid HMAC tag for message.
+	// CheckMAC reports whether messageMAC is a valid HMAC tag for message.
 	func CheckMAC(message, messageMAC, key []byte) bool {
 		mac := hmac.New(sha256.New, key)
 		mac.Write(message)
diff --git a/third_party/gofrontend/libgo/go/crypto/rand/eagain.go b/third_party/gofrontend/libgo/go/crypto/rand/eagain.go
new file mode 100644
index 0000000..2c853d0
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/crypto/rand/eagain.go
@@ -0,0 +1,27 @@
+// 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.
+
+// +build darwin dragonfly freebsd linux nacl netbsd openbsd solaris
+
+package rand
+
+import (
+	"os"
+	"syscall"
+)
+
+func init() {
+	isEAGAIN = unixIsEAGAIN
+}
+
+// unixIsEAGAIN reports whether err is a syscall.EAGAIN wrapped in a PathError.
+// See golang.org/issue/9205
+func unixIsEAGAIN(err error) bool {
+	if pe, ok := err.(*os.PathError); ok {
+		if errno, ok := pe.Err.(syscall.Errno); ok && errno == syscall.EAGAIN {
+			return true
+		}
+	}
+	return false
+}
diff --git a/third_party/gofrontend/libgo/go/crypto/rand/rand.go b/third_party/gofrontend/libgo/go/crypto/rand/rand.go
index 4da3adb..ee32fa0 100644
--- a/third_party/gofrontend/libgo/go/crypto/rand/rand.go
+++ b/third_party/gofrontend/libgo/go/crypto/rand/rand.go
@@ -10,7 +10,9 @@
 
 // Reader is a global, shared instance of a cryptographically
 // strong pseudo-random generator.
+//
 // On Unix-like systems, Reader reads from /dev/urandom.
+// On Linux, Reader uses getrandom(2) if available, /dev/urandom otherwise.
 // On Windows systems, Reader uses the CryptGenRandom API.
 var Reader io.Reader
 
diff --git a/third_party/gofrontend/libgo/go/crypto/rand/rand_linux.go b/third_party/gofrontend/libgo/go/crypto/rand/rand_linux.go
index 8cb59c7..7d6d9e8 100644
--- a/third_party/gofrontend/libgo/go/crypto/rand/rand_linux.go
+++ b/third_party/gofrontend/libgo/go/crypto/rand/rand_linux.go
@@ -5,7 +5,7 @@
 package rand
 
 import (
-	"internal/syscall"
+	"internal/syscall/unix"
 	"sync"
 )
 
@@ -25,7 +25,7 @@
 	// - the machine has no entropy available (early boot + no hardware
 	//   entropy source?) and we want to avoid blocking later.
 	var buf [1]byte
-	n, err := syscall.GetRandom(buf[:], syscall.GRND_NONBLOCK)
+	n, err := unix.GetRandom(buf[:], unix.GRND_NONBLOCK)
 	useSyscall = n == 1 && err == nil
 }
 
@@ -34,6 +34,6 @@
 	if !useSyscall {
 		return false
 	}
-	n, err := syscall.GetRandom(p, 0)
+	n, err := unix.GetRandom(p, 0)
 	return n == len(p) && err == nil
 }
diff --git a/third_party/gofrontend/libgo/go/crypto/rand/rand_unix.go b/third_party/gofrontend/libgo/go/crypto/rand/rand_unix.go
index 62d0fbd..75c36e0 100644
--- a/third_party/gofrontend/libgo/go/crypto/rand/rand_unix.go
+++ b/third_party/gofrontend/libgo/go/crypto/rand/rand_unix.go
@@ -58,12 +58,28 @@
 		if runtime.GOOS == "plan9" {
 			r.f = f
 		} else {
-			r.f = bufio.NewReader(f)
+			r.f = bufio.NewReader(hideAgainReader{f})
 		}
 	}
 	return r.f.Read(b)
 }
 
+var isEAGAIN func(error) bool // set by eagain.go on unix systems
+
+// hideAgainReader masks EAGAIN reads from /dev/urandom.
+// See golang.org/issue/9205
+type hideAgainReader struct {
+	r io.Reader
+}
+
+func (hr hideAgainReader) Read(p []byte) (n int, err error) {
+	n, err = hr.r.Read(p)
+	if err != nil && isEAGAIN != nil && isEAGAIN(err) {
+		err = nil
+	}
+	return
+}
+
 // Alternate pseudo-random implementation for use on
 // systems without a reliable /dev/urandom.
 
diff --git a/third_party/gofrontend/libgo/go/crypto/rand/util_test.go b/third_party/gofrontend/libgo/go/crypto/rand/util_test.go
index 1e2a4dd..2f7cba8 100644
--- a/third_party/gofrontend/libgo/go/crypto/rand/util_test.go
+++ b/third_party/gofrontend/libgo/go/crypto/rand/util_test.go
@@ -10,7 +10,7 @@
 	"testing"
 )
 
-// http://golang.org/issue/6849.
+// https://golang.org/issue/6849.
 func TestPrimeSmall(t *testing.T) {
 	for n := 2; n < 10; n++ {
 		p, err := rand.Prime(rand.Reader, n)
diff --git a/third_party/gofrontend/libgo/go/crypto/rsa/pkcs1v15.go b/third_party/gofrontend/libgo/go/crypto/rsa/pkcs1v15.go
index 59e8bb5..34037b0 100644
--- a/third_party/gofrontend/libgo/go/crypto/rsa/pkcs1v15.go
+++ b/third_party/gofrontend/libgo/go/crypto/rsa/pkcs1v15.go
@@ -14,6 +14,16 @@
 
 // This file implements encryption and decryption using PKCS#1 v1.5 padding.
 
+// PKCS1v15DecrypterOpts is for passing options to PKCS#1 v1.5 decryption using
+// the crypto.Decrypter interface.
+type PKCS1v15DecryptOptions struct {
+	// SessionKeyLen is the length of the session key that is being
+	// decrypted. If not zero, then a padding error during decryption will
+	// cause a random plaintext of this length to be returned rather than
+	// an error. These alternatives happen in constant time.
+	SessionKeyLen int
+}
+
 // EncryptPKCS1v15 encrypts the given message with RSA and the padding scheme from PKCS#1 v1.5.
 // The message must be no longer than the length of the public modulus minus 11 bytes.
 // WARNING: use of this function to encrypt plaintexts other than session keys
diff --git a/third_party/gofrontend/libgo/go/crypto/rsa/pkcs1v15_test.go b/third_party/gofrontend/libgo/go/crypto/rsa/pkcs1v15_test.go
index 2dc5dbc..8925375 100644
--- a/third_party/gofrontend/libgo/go/crypto/rsa/pkcs1v15_test.go
+++ b/third_party/gofrontend/libgo/go/crypto/rsa/pkcs1v15_test.go
@@ -51,14 +51,25 @@
 }
 
 func TestDecryptPKCS1v15(t *testing.T) {
-	for i, test := range decryptPKCS1v15Tests {
-		out, err := DecryptPKCS1v15(nil, rsaPrivateKey, decodeBase64(test.in))
-		if err != nil {
-			t.Errorf("#%d error decrypting", i)
-		}
-		want := []byte(test.out)
-		if !bytes.Equal(out, want) {
-			t.Errorf("#%d got:%#v want:%#v", i, out, want)
+	decryptionFuncs := []func([]byte) ([]byte, error){
+		func(ciphertext []byte) (plaintext []byte, err error) {
+			return DecryptPKCS1v15(nil, rsaPrivateKey, ciphertext)
+		},
+		func(ciphertext []byte) (plaintext []byte, err error) {
+			return rsaPrivateKey.Decrypt(nil, ciphertext, nil)
+		},
+	}
+
+	for _, decryptFunc := range decryptionFuncs {
+		for i, test := range decryptPKCS1v15Tests {
+			out, err := decryptFunc(decodeBase64(test.in))
+			if err != nil {
+				t.Errorf("#%d error decrypting", i)
+			}
+			want := []byte(test.out)
+			if !bytes.Equal(out, want) {
+				t.Errorf("#%d got:%#v want:%#v", i, out, want)
+			}
 		}
 	}
 }
@@ -138,6 +149,22 @@
 	}
 }
 
+func TestEncryptPKCS1v15DecrypterSessionKey(t *testing.T) {
+	for i, test := range decryptPKCS1v15SessionKeyTests {
+		plaintext, err := rsaPrivateKey.Decrypt(rand.Reader, decodeBase64(test.in), &PKCS1v15DecryptOptions{SessionKeyLen: 4})
+		if err != nil {
+			t.Fatalf("#%d: error decrypting: %s", i, err)
+		}
+		if len(plaintext) != 4 {
+			t.Fatalf("#%d: incorrect length plaintext: got %d, want 4", i, len(plaintext))
+		}
+
+		if test.out != "FAIL" && !bytes.Equal(plaintext, []byte(test.out)) {
+			t.Errorf("#%d: incorrect plaintext: got %x, want %x", plaintext, test.out)
+		}
+	}
+}
+
 func TestNonZeroRandomBytes(t *testing.T) {
 	random := rand.Reader
 
diff --git a/third_party/gofrontend/libgo/go/crypto/rsa/pss.go b/third_party/gofrontend/libgo/go/crypto/rsa/pss.go
index e9f2908..0a41814 100644
--- a/third_party/gofrontend/libgo/go/crypto/rsa/pss.go
+++ b/third_party/gofrontend/libgo/go/crypto/rsa/pss.go
@@ -255,7 +255,7 @@
 		saltLength = hash.Size()
 	}
 
-	if opts.Hash != 0 {
+	if opts != nil && opts.Hash != 0 {
 		hash = opts.Hash
 	}
 
diff --git a/third_party/gofrontend/libgo/go/crypto/rsa/pss_test.go b/third_party/gofrontend/libgo/go/crypto/rsa/pss_test.go
index 32e6fc3..cae24e5 100644
--- a/third_party/gofrontend/libgo/go/crypto/rsa/pss_test.go
+++ b/third_party/gofrontend/libgo/go/crypto/rsa/pss_test.go
@@ -189,6 +189,15 @@
 	}
 }
 
+func TestPSSNilOpts(t *testing.T) {
+	hash := crypto.SHA256
+	h := hash.New()
+	h.Write([]byte("testing"))
+	hashed := h.Sum(nil)
+
+	SignPSS(rand.Reader, rsaPrivateKey, hash, hashed, nil)
+}
+
 func TestPSSSigning(t *testing.T) {
 	var saltLengthCombinations = []struct {
 		signSaltLength, verifySaltLength int
diff --git a/third_party/gofrontend/libgo/go/crypto/rsa/rsa.go b/third_party/gofrontend/libgo/go/crypto/rsa/rsa.go
index 2702311..1293b78 100644
--- a/third_party/gofrontend/libgo/go/crypto/rsa/rsa.go
+++ b/third_party/gofrontend/libgo/go/crypto/rsa/rsa.go
@@ -24,6 +24,16 @@
 	E int      // public exponent
 }
 
+// OAEPOptions is an interface for passing options to OAEP decryption using the
+// crypto.Decrypter interface.
+type OAEPOptions struct {
+	// Hash is the hash function that will be used when generating the mask.
+	Hash crypto.Hash
+	// Label is an arbitrary byte string that must be equal to the value
+	// used when encrypting.
+	Label []byte
+}
+
 var (
 	errPublicModulus       = errors.New("crypto/rsa: missing public modulus")
 	errPublicExponentSmall = errors.New("crypto/rsa: public exponent too small")
@@ -77,6 +87,37 @@
 	return SignPKCS1v15(rand, priv, opts.HashFunc(), msg)
 }
 
+// Decrypt decrypts ciphertext with priv. If opts is nil or of type
+// *PKCS1v15DecryptOptions then PKCS#1 v1.5 decryption is performed. Otherwise
+// opts must have type *OAEPOptions and OAEP decryption is done.
+func (priv *PrivateKey) Decrypt(rand io.Reader, ciphertext []byte, opts crypto.DecrypterOpts) (plaintext []byte, err error) {
+	if opts == nil {
+		return DecryptPKCS1v15(rand, priv, ciphertext)
+	}
+
+	switch opts := opts.(type) {
+	case *OAEPOptions:
+		return DecryptOAEP(opts.Hash.New(), rand, priv, ciphertext, opts.Label)
+
+	case *PKCS1v15DecryptOptions:
+		if l := opts.SessionKeyLen; l > 0 {
+			plaintext = make([]byte, l)
+			if _, err := io.ReadFull(rand, plaintext); err != nil {
+				return nil, err
+			}
+			if err := DecryptPKCS1v15SessionKey(rand, priv, ciphertext, plaintext); err != nil {
+				return nil, err
+			}
+			return plaintext, nil
+		} else {
+			return DecryptPKCS1v15(rand, priv, ciphertext)
+		}
+
+	default:
+		return nil, errors.New("crypto/rsa: invalid options for Decrypt")
+	}
+}
+
 type PrecomputedValues struct {
 	Dp, Dq *big.Int // D mod (P-1) (or mod Q-1)
 	Qinv   *big.Int // Q^-1 mod P
@@ -88,7 +129,7 @@
 	CRTValues []CRTValue
 }
 
-// CRTValue contains the precomputed chinese remainder theorem values.
+// CRTValue contains the precomputed Chinese remainder theorem values.
 type CRTValue struct {
 	Exp   *big.Int // D mod (prime-1).
 	Coeff *big.Int // R·Coeff ≡ 1 mod Prime.
@@ -102,19 +143,13 @@
 		return err
 	}
 
-	// Check that the prime factors are actually prime. Note that this is
-	// just a sanity check. Since the random witnesses chosen by
-	// ProbablyPrime are deterministic, given the candidate number, it's
-	// easy for an attack to generate composites that pass this test.
-	for _, prime := range priv.Primes {
-		if !prime.ProbablyPrime(20) {
-			return errors.New("crypto/rsa: prime factor is composite")
-		}
-	}
-
 	// Check that Πprimes == n.
 	modulus := new(big.Int).Set(bigOne)
 	for _, prime := range priv.Primes {
+		// Any primes ≤ 1 will cause divide-by-zero panics later.
+		if prime.Cmp(bigOne) <= 0 {
+			return errors.New("crypto/rsa: invalid prime value")
+		}
 		modulus.Mul(modulus, prime)
 	}
 	if modulus.Cmp(priv.N) != 0 {
diff --git a/third_party/gofrontend/libgo/go/crypto/sha512/sha512.go b/third_party/gofrontend/libgo/go/crypto/sha512/sha512.go
index bca7a91..e7781fd 100644
--- a/third_party/gofrontend/libgo/go/crypto/sha512/sha512.go
+++ b/third_party/gofrontend/libgo/go/crypto/sha512/sha512.go
@@ -2,8 +2,8 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-// Package sha512 implements the SHA384 and SHA512 hash algorithms as defined
-// in FIPS 180-2.
+// Package sha512 implements the SHA-384, SHA-512, SHA-512/224, and SHA-512/256
+// hash algorithms as defined in FIPS 180-4.
 package sha512
 
 import (
@@ -14,16 +14,27 @@
 func init() {
 	crypto.RegisterHash(crypto.SHA384, New384)
 	crypto.RegisterHash(crypto.SHA512, New)
+	crypto.RegisterHash(crypto.SHA512_224, New512_224)
+	crypto.RegisterHash(crypto.SHA512_256, New512_256)
 }
 
-// The size of a SHA512 checksum in bytes.
-const Size = 64
+const (
+	// Size is the size, in bytes, of a SHA-512 checksum.
+	Size = 64
 
-// The size of a SHA384 checksum in bytes.
-const Size384 = 48
+	// Size224 is the size, in bytes, of a SHA-512/224 checksum.
+	Size224 = 28
 
-// The blocksize of SHA512 and SHA384 in bytes.
-const BlockSize = 128
+	// Size256 is the size, in bytes, of a SHA-512/256 checksum.
+	Size256 = 32
+
+	// Size384 is the size, in bytes, of a SHA-384 checksum.
+	Size384 = 48
+
+	// BlockSize is the block size, in bytes, of the SHA-512/224,
+	// SHA-512/256, SHA-384 and SHA-512 hash functions.
+	BlockSize = 128
+)
 
 const (
 	chunk     = 128
@@ -35,6 +46,22 @@
 	init5     = 0x9b05688c2b3e6c1f
 	init6     = 0x1f83d9abfb41bd6b
 	init7     = 0x5be0cd19137e2179
+	init0_224 = 0x8c3d37c819544da2
+	init1_224 = 0x73e1996689dcd4d6
+	init2_224 = 0x1dfab7ae32ff9c82
+	init3_224 = 0x679dd514582f9fcf
+	init4_224 = 0x0f6d2b697bd44da8
+	init5_224 = 0x77e36f7304c48942
+	init6_224 = 0x3f9d85a86a1d36c8
+	init7_224 = 0x1112e6ad91d692a1
+	init0_256 = 0x22312194fc2bf72c
+	init1_256 = 0x9f555fa3c84c64c2
+	init2_256 = 0x2393b86b6f53b151
+	init3_256 = 0x963877195940eabd
+	init4_256 = 0x96283ee2a88effe3
+	init5_256 = 0xbe5e1e2553863992
+	init6_256 = 0x2b0199fc2c85b8aa
+	init7_256 = 0x0eb72ddc81c52ca2
 	init0_384 = 0xcbbb9d5dc1059ed8
 	init1_384 = 0x629a292a367cd507
 	init2_384 = 0x9159015a3070dd17
@@ -47,24 +74,16 @@
 
 // digest represents the partial evaluation of a checksum.
 type digest struct {
-	h     [8]uint64
-	x     [chunk]byte
-	nx    int
-	len   uint64
-	is384 bool // mark if this digest is SHA-384
+	h        [8]uint64
+	x        [chunk]byte
+	nx       int
+	len      uint64
+	function crypto.Hash
 }
 
 func (d *digest) Reset() {
-	if !d.is384 {
-		d.h[0] = init0
-		d.h[1] = init1
-		d.h[2] = init2
-		d.h[3] = init3
-		d.h[4] = init4
-		d.h[5] = init5
-		d.h[6] = init6
-		d.h[7] = init7
-	} else {
+	switch d.function {
+	case crypto.SHA384:
 		d.h[0] = init0_384
 		d.h[1] = init1_384
 		d.h[2] = init2_384
@@ -73,31 +92,77 @@
 		d.h[5] = init5_384
 		d.h[6] = init6_384
 		d.h[7] = init7_384
+	case crypto.SHA512_224:
+		d.h[0] = init0_224
+		d.h[1] = init1_224
+		d.h[2] = init2_224
+		d.h[3] = init3_224
+		d.h[4] = init4_224
+		d.h[5] = init5_224
+		d.h[6] = init6_224
+		d.h[7] = init7_224
+	case crypto.SHA512_256:
+		d.h[0] = init0_256
+		d.h[1] = init1_256
+		d.h[2] = init2_256
+		d.h[3] = init3_256
+		d.h[4] = init4_256
+		d.h[5] = init5_256
+		d.h[6] = init6_256
+		d.h[7] = init7_256
+	default:
+		d.h[0] = init0
+		d.h[1] = init1
+		d.h[2] = init2
+		d.h[3] = init3
+		d.h[4] = init4
+		d.h[5] = init5
+		d.h[6] = init6
+		d.h[7] = init7
 	}
 	d.nx = 0
 	d.len = 0
 }
 
-// New returns a new hash.Hash computing the SHA512 checksum.
+// New returns a new hash.Hash computing the SHA-512 checksum.
 func New() hash.Hash {
-	d := new(digest)
+	d := &digest{function: crypto.SHA512}
 	d.Reset()
 	return d
 }
 
-// New384 returns a new hash.Hash computing the SHA384 checksum.
+// New512_224 returns a new hash.Hash computing the SHA-512/224 checksum.
+func New512_224() hash.Hash {
+	d := &digest{function: crypto.SHA512_224}
+	d.Reset()
+	return d
+}
+
+// New512_256 returns a new hash.Hash computing the SHA-512/256 checksum.
+func New512_256() hash.Hash {
+	d := &digest{function: crypto.SHA512_256}
+	d.Reset()
+	return d
+}
+
+// New384 returns a new hash.Hash computing the SHA-384 checksum.
 func New384() hash.Hash {
-	d := new(digest)
-	d.is384 = true
+	d := &digest{function: crypto.SHA384}
 	d.Reset()
 	return d
 }
 
 func (d *digest) Size() int {
-	if !d.is384 {
+	switch d.function {
+	case crypto.SHA512_224:
+		return Size224
+	case crypto.SHA512_256:
+		return Size256
+	case crypto.SHA384:
+		return Size384
+	default:
 		return Size
 	}
-	return Size384
 }
 
 func (d *digest) BlockSize() int { return BlockSize }
@@ -130,10 +195,16 @@
 	d := new(digest)
 	*d = *d0
 	hash := d.checkSum()
-	if d.is384 {
+	switch d.function {
+	case crypto.SHA384:
 		return append(in, hash[:Size384]...)
+	case crypto.SHA512_224:
+		return append(in, hash[:Size224]...)
+	case crypto.SHA512_256:
+		return append(in, hash[:Size256]...)
+	default:
+		return append(in, hash[:]...)
 	}
-	return append(in, hash[:]...)
 }
 
 func (d *digest) checkSum() [Size]byte {
@@ -159,7 +230,7 @@
 	}
 
 	h := d.h[:]
-	if d.is384 {
+	if d.function == crypto.SHA384 {
 		h = d.h[:6]
 	}
 
@@ -180,7 +251,7 @@
 
 // Sum512 returns the SHA512 checksum of the data.
 func Sum512(data []byte) [Size]byte {
-	var d digest
+	d := digest{function: crypto.SHA512}
 	d.Reset()
 	d.Write(data)
 	return d.checkSum()
@@ -188,11 +259,30 @@
 
 // Sum384 returns the SHA384 checksum of the data.
 func Sum384(data []byte) (sum384 [Size384]byte) {
-	var d digest
-	d.is384 = true
+	d := digest{function: crypto.SHA384}
 	d.Reset()
 	d.Write(data)
 	sum := d.checkSum()
 	copy(sum384[:], sum[:Size384])
 	return
 }
+
+// Sum512_224 returns the Sum512/224 checksum of the data.
+func Sum512_224(data []byte) (sum224 [Size224]byte) {
+	d := digest{function: crypto.SHA512_224}
+	d.Reset()
+	d.Write(data)
+	sum := d.checkSum()
+	copy(sum224[:], sum[:Size224])
+	return
+}
+
+// Sum512_256 returns the Sum512/256 checksum of the data.
+func Sum512_256(data []byte) (sum256 [Size256]byte) {
+	d := digest{function: crypto.SHA512_256}
+	d.Reset()
+	d.Write(data)
+	sum := d.checkSum()
+	copy(sum256[:], sum[:Size256])
+	return
+}
diff --git a/third_party/gofrontend/libgo/go/crypto/sha512/sha512_test.go b/third_party/gofrontend/libgo/go/crypto/sha512/sha512_test.go
index 541860f..04b3d4a 100644
--- a/third_party/gofrontend/libgo/go/crypto/sha512/sha512_test.go
+++ b/third_party/gofrontend/libgo/go/crypto/sha512/sha512_test.go
@@ -2,133 +2,279 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-// SHA512 hash algorithm.  See FIPS 180-2.
+// SHA512 hash algorithm.  See FIPS 180-4.
 
 package sha512
 
 import (
-	"fmt"
+	"encoding/hex"
+	"hash"
 	"io"
 	"testing"
 )
 
 type sha512Test struct {
-	out string
-	in  string
+	in     string
+	out224 string
+	out256 string
+	out384 string
+	out512 string
 }
 
 var golden = []sha512Test{
-	{"cf83e1357eefb8bdf1542850d66d8007d620e4050b5715dc83f4a921d36ce9ce47d0d13c5d85f2b0ff8318d2877eec2f63b931bd47417a81a538327af927da3e", ""},
-	{"1f40fc92da241694750979ee6cf582f2d5d7d28e18335de05abc54d0560e0f5302860c652bf08d560252aa5e74210546f369fbbbce8c12cfc7957b2652fe9a75", "a"},
-	{"2d408a0717ec188158278a796c689044361dc6fdde28d6f04973b80896e1823975cdbf12eb63f9e0591328ee235d80e9b5bf1aa6a44f4617ff3caf6400eb172d", "ab"},
-	{"ddaf35a193617abacc417349ae20413112e6fa4e89a97ea20a9eeee64b55d39a2192992a274fc1a836ba3c23a3feebbd454d4423643ce80e2a9ac94fa54ca49f", "abc"},
-	{"d8022f2060ad6efd297ab73dcc5355c9b214054b0d1776a136a669d26a7d3b14f73aa0d0ebff19ee333368f0164b6419a96da49e3e481753e7e96b716bdccb6f", "abcd"},
-	{"878ae65a92e86cac011a570d4c30a7eaec442b85ce8eca0c2952b5e3cc0628c2e79d889ad4d5c7c626986d452dd86374b6ffaa7cd8b67665bef2289a5c70b0a1", "abcde"},
-	{"e32ef19623e8ed9d267f657a81944b3d07adbb768518068e88435745564e8d4150a0a703be2a7d88b61e3d390c2bb97e2d4c311fdc69d6b1267f05f59aa920e7", "abcdef"},
-	{"d716a4188569b68ab1b6dfac178e570114cdf0ea3a1cc0e31486c3e41241bc6a76424e8c37ab26f096fc85ef9886c8cb634187f4fddff645fb099f1ff54c6b8c", "abcdefg"},
-	{"a3a8c81bc97c2560010d7389bc88aac974a104e0e2381220c6e084c4dccd1d2d17d4f86db31c2a851dc80e6681d74733c55dcd03dd96f6062cdda12a291ae6ce", "abcdefgh"},
-	{"f22d51d25292ca1d0f68f69aedc7897019308cc9db46efb75a03dd494fc7f126c010e8ade6a00a0c1a5f1b75d81e0ed5a93ce98dc9b833db7839247b1d9c24fe", "abcdefghi"},
-	{"ef6b97321f34b1fea2169a7db9e1960b471aa13302a988087357c520be957ca119c3ba68e6b4982c019ec89de3865ccf6a3cda1fe11e59f98d99f1502c8b9745", "abcdefghij"},
-	{"2210d99af9c8bdecda1b4beff822136753d8342505ddce37f1314e2cdbb488c6016bdaa9bd2ffa513dd5de2e4b50f031393d8ab61f773b0e0130d7381e0f8a1d", "Discard medicine more than two years old."},
-	{"a687a8985b4d8d0a24f115fe272255c6afaf3909225838546159c1ed685c211a203796ae8ecc4c81a5b6315919b3a64f10713da07e341fcdbb08541bf03066ce", "He who has a shady past knows that nice guys finish last."},
-	{"8ddb0392e818b7d585ab22769a50df660d9f6d559cca3afc5691b8ca91b8451374e42bcdabd64589ed7c91d85f626596228a5c8572677eb98bc6b624befb7af8", "I wouldn't marry him with a ten foot pole."},
-	{"26ed8f6ca7f8d44b6a8a54ae39640fa8ad5c673f70ee9ce074ba4ef0d483eea00bab2f61d8695d6b34df9c6c48ae36246362200ed820448bdc03a720366a87c6", "Free! Free!/A trip/to Mars/for 900/empty jars/Burma Shave"},
-	{"e5a14bf044be69615aade89afcf1ab0389d5fc302a884d403579d1386a2400c089b0dbb387ed0f463f9ee342f8244d5a38cfbc0e819da9529fbff78368c9a982", "The days of the digital watch are numbered.  -Tom Stoppard"},
-	{"420a1faa48919e14651bed45725abe0f7a58e0f099424c4e5a49194946e38b46c1f8034b18ef169b2e31050d1648e0b982386595f7df47da4b6fd18e55333015", "Nepal premier won't resign."},
-	{"d926a863beadb20134db07683535c72007b0e695045876254f341ddcccde132a908c5af57baa6a6a9c63e6649bba0c213dc05fadcf9abccea09f23dcfb637fbe", "For every action there is an equal and opposite government program."},
-	{"9a98dd9bb67d0da7bf83da5313dff4fd60a4bac0094f1b05633690ffa7f6d61de9a1d4f8617937d560833a9aaa9ccafe3fd24db418d0e728833545cadd3ad92d", "His money is twice tainted: 'taint yours and 'taint mine."},
-	{"d7fde2d2351efade52f4211d3746a0780a26eec3df9b2ed575368a8a1c09ec452402293a8ea4eceb5a4f60064ea29b13cdd86918cd7a4faf366160b009804107", "There is no reason for any individual to have a computer in their home. -Ken Olsen, 1977"},
-	{"b0f35ffa2697359c33a56f5c0cf715c7aeed96da9905ca2698acadb08fbc9e669bf566b6bd5d61a3e86dc22999bcc9f2224e33d1d4f32a228cf9d0349e2db518", "It's a tiny change to the code and not completely disgusting. - Bob Manchek"},
-	{"3d2e5f91778c9e66f7e061293aaa8a8fc742dd3b2e4f483772464b1144189b49273e610e5cccd7a81a19ca1fa70f16b10f1a100a4d8c1372336be8484c64b311", "size:  a.out:  bad magic"},
-	{"b2f68ff58ac015efb1c94c908b0d8c2bf06f491e4de8e6302c49016f7f8a33eac3e959856c7fddbc464de618701338a4b46f76dbfaf9a1e5262b5f40639771c7", "The major problem is with sendmail.  -Mark Horton"},
-	{"d8c92db5fdf52cf8215e4df3b4909d29203ff4d00e9ad0b64a6a4e04dec5e74f62e7c35c7fb881bd5de95442123df8f57a489b0ae616bd326f84d10021121c57", "Give me a rock, paper and scissors and I will move the world.  CCFestoon"},
-	{"19a9f8dc0a233e464e8566ad3ca9b91e459a7b8c4780985b015776e1bf239a19bc233d0556343e2b0a9bc220900b4ebf4f8bdf89ff8efeaf79602d6849e6f72e", "If the enemy is within range, then so are you."},
-	{"00b4c41f307bde87301cdc5b5ab1ae9a592e8ecbb2021dd7bc4b34e2ace60741cc362560bec566ba35178595a91932b8d5357e2c9cec92d393b0fa7831852476", "It's well we cannot hear the screams/That we create in others' dreams."},
-	{"91eccc3d5375fd026e4d6787874b1dce201cecd8a27dbded5065728cb2d09c58a3d467bb1faf353bf7ba567e005245d5321b55bc344f7c07b91cb6f26c959be7", "You remind me of a TV show, but that's all right: I watch it anyway."},
-	{"fabbbe22180f1f137cfdc9556d2570e775d1ae02a597ded43a72a40f9b485d500043b7be128fb9fcd982b83159a0d99aa855a9e7cc4240c00dc01a9bdf8218d7", "C is as portable as Stonehedge!!"},
-	{"2ecdec235c1fa4fc2a154d8fba1dddb8a72a1ad73838b51d792331d143f8b96a9f6fcb0f34d7caa351fe6d88771c4f105040e0392f06e0621689d33b2f3ba92e", "Even if I could be Shakespeare, I think I should still choose to be Faraday. - A. Huxley"},
-	{"7ad681f6f96f82f7abfa7ecc0334e8fa16d3dc1cdc45b60b7af43fe4075d2357c0c1d60e98350f1afb1f2fe7a4d7cd2ad55b88e458e06b73c40b437331f5dab4", "The fugacity of a constituent in a mixture of gases at a given temperature is proportional to its mole fraction.  Lewis-Randall Rule"},
-	{"833f9248ab4a3b9e5131f745fda1ffd2dd435b30e965957e78291c7ab73605fd1912b0794e5c233ab0a12d205a39778d19b83515d6a47003f19cdee51d98c7e0", "How can you write a big system without C++?  -Paul Glick"},
+	{
+		"",
+		"6ed0dd02806fa89e25de060c19d3ac86cabb87d6a0ddd05c333b84f4",
+		"c672b8d1ef56ed28ab87c3622c5114069bdd3ad7b8f9737498d0c01ecef0967a",
+		"38b060a751ac96384cd9327eb1b1e36a21fdb71114be07434c0cc7bf63f6e1da274edebfe76f65fbd51ad2f14898b95b",
+		"cf83e1357eefb8bdf1542850d66d8007d620e4050b5715dc83f4a921d36ce9ce47d0d13c5d85f2b0ff8318d2877eec2f63b931bd47417a81a538327af927da3e",
+	},
+	{
+		"a",
+		"d5cdb9ccc769a5121d4175f2bfdd13d6310e0d3d361ea75d82108327",
+		"455e518824bc0601f9fb858ff5c37d417d67c2f8e0df2babe4808858aea830f8",
+		"54a59b9f22b0b80880d8427e548b7c23abd873486e1f035dce9cd697e85175033caa88e6d57bc35efae0b5afd3145f31",
+		"1f40fc92da241694750979ee6cf582f2d5d7d28e18335de05abc54d0560e0f5302860c652bf08d560252aa5e74210546f369fbbbce8c12cfc7957b2652fe9a75",
+	},
+	{
+		"ab",
+		"b35878d07bfedf39fc638af08547eb5d1072d8546319f247b442fbf5",
+		"22d4d37ec6370571af7109fb12eae79673d5f7c83e6e677083faa3cfac3b2c14",
+		"c7be03ba5bcaa384727076db0018e99248e1a6e8bd1b9ef58a9ec9dd4eeebb3f48b836201221175befa74ddc3d35afdd",
+		"2d408a0717ec188158278a796c689044361dc6fdde28d6f04973b80896e1823975cdbf12eb63f9e0591328ee235d80e9b5bf1aa6a44f4617ff3caf6400eb172d",
+	},
+	{
+		"abc",
+		"4634270f707b6a54daae7530460842e20e37ed265ceee9a43e8924aa",
+		"53048e2681941ef99b2e29b76b4c7dabe4c2d0c634fc6d46e0e2f13107e7af23",
+		"cb00753f45a35e8bb5a03d699ac65007272c32ab0eded1631a8b605a43ff5bed8086072ba1e7cc2358baeca134c825a7",
+		"ddaf35a193617abacc417349ae20413112e6fa4e89a97ea20a9eeee64b55d39a2192992a274fc1a836ba3c23a3feebbd454d4423643ce80e2a9ac94fa54ca49f",
+	},
+	{
+		"abcd",
+		"0c9f157ab030fb06e957c14e3938dc5908962e5dd7b66f04a36fc534",
+		"d2891c7978be0e24948f37caa415b87cb5cbe2b26b7bad9dc6391b8a6f6ddcc9",
+		"1165b3406ff0b52a3d24721f785462ca2276c9f454a116c2b2ba20171a7905ea5a026682eb659c4d5f115c363aa3c79b",
+		"d8022f2060ad6efd297ab73dcc5355c9b214054b0d1776a136a669d26a7d3b14f73aa0d0ebff19ee333368f0164b6419a96da49e3e481753e7e96b716bdccb6f",
+	},
+	{
+		"abcde",
+		"880e79bb0a1d2c9b7528d851edb6b8342c58c831de98123b432a4515",
+		"de8322b46e78b67d4431997070703e9764e03a1237b896fd8b379ed4576e8363",
+		"4c525cbeac729eaf4b4665815bc5db0c84fe6300068a727cf74e2813521565abc0ec57a37ee4d8be89d097c0d2ad52f0",
+		"878ae65a92e86cac011a570d4c30a7eaec442b85ce8eca0c2952b5e3cc0628c2e79d889ad4d5c7c626986d452dd86374b6ffaa7cd8b67665bef2289a5c70b0a1",
+	},
+	{
+		"abcdef",
+		"236c829cfea4fd6d4de61ad15fcf34dca62342adaf9f2001c16f29b8",
+		"e4fdcb11d1ac14e698743acd8805174cea5ddc0d312e3e47f6372032571bad84",
+		"c6a4c65b227e7387b9c3e839d44869c4cfca3ef583dea64117859b808c1e3d8ae689e1e314eeef52a6ffe22681aa11f5",
+		"e32ef19623e8ed9d267f657a81944b3d07adbb768518068e88435745564e8d4150a0a703be2a7d88b61e3d390c2bb97e2d4c311fdc69d6b1267f05f59aa920e7",
+	},
+	{
+		"abcdefg",
+		"4767af672b3ed107f25018dc22d6fa4b07d156e13b720971e2c4f6bf",
+		"a8117f680bdceb5d1443617cbdae9255f6900075422326a972fdd2f65ba9bee3",
+		"9f11fc131123f844c1226f429b6a0a6af0525d9f40f056c7fc16cdf1b06bda08e302554417a59fa7dcf6247421959d22",
+		"d716a4188569b68ab1b6dfac178e570114cdf0ea3a1cc0e31486c3e41241bc6a76424e8c37ab26f096fc85ef9886c8cb634187f4fddff645fb099f1ff54c6b8c",
+	},
+	{
+		"abcdefgh",
+		"792e25e0ae286d123a38950007e037d3122e76c4ee201668c385edab",
+		"a29b9645d2a02a8b582888d044199787220e316bf2e89d1422d3df26bf545bbe",
+		"9000cd7cada59d1d2eb82912f7f24e5e69cc5517f68283b005fa27c285b61e05edf1ad1a8a9bded6fd29eb87d75ad806",
+		"a3a8c81bc97c2560010d7389bc88aac974a104e0e2381220c6e084c4dccd1d2d17d4f86db31c2a851dc80e6681d74733c55dcd03dd96f6062cdda12a291ae6ce",
+	},
+	{
+		"abcdefghi",
+		"56b275d36127dc070cda4019baf2ce2579a25d8c67fa2bc9be61b539",
+		"b955095330f9c8188d11884ec1679dc44c9c5b25ff9bda700416df9cdd39188f",
+		"ef54915b60cf062b8dd0c29ae3cad69abe6310de63ac081f46ef019c5c90897caefd79b796cfa81139788a260ded52df",
+		"f22d51d25292ca1d0f68f69aedc7897019308cc9db46efb75a03dd494fc7f126c010e8ade6a00a0c1a5f1b75d81e0ed5a93ce98dc9b833db7839247b1d9c24fe",
+	},
+	{
+		"abcdefghij",
+		"f809423cbb25e81a2a64aecee2cd5fdc7d91d5db583901fbf1db3116",
+		"550762913d51eefbcd1a55068fcfc9b154fd11c1078b996df0d926ea59d2a68d",
+		"a12070030a02d86b0ddacd0d3a5b598344513d0a051e7355053e556a0055489c1555399b03342845c4adde2dc44ff66c",
+		"ef6b97321f34b1fea2169a7db9e1960b471aa13302a988087357c520be957ca119c3ba68e6b4982c019ec89de3865ccf6a3cda1fe11e59f98d99f1502c8b9745",
+	},
+	{
+		"Discard medicine more than two years old.",
+		"4c46e10b5b72204e509c3c06072cea970bc020cd45a61a0acdfa97ac",
+		"690c8ad3916cefd3ad29226d9875965e3ee9ec0d4482eacc248f2ff4aa0d8e5b",
+		"86f58ec2d74d1b7f8eb0c2ff0967316699639e8d4eb129de54bdf34c96cdbabe200d052149f2dd787f43571ba74670d4",
+		"2210d99af9c8bdecda1b4beff822136753d8342505ddce37f1314e2cdbb488c6016bdaa9bd2ffa513dd5de2e4b50f031393d8ab61f773b0e0130d7381e0f8a1d",
+	},
+	{
+		"He who has a shady past knows that nice guys finish last.",
+		"cb0cef13c1848d91a6d02637c7c520de1914ad4a7aea824671cc328e",
+		"25938ca49f7ef1178ce81620842b65e576245fcaed86026a36b516b80bb86b3b",
+		"ae4a2b639ca9bfa04b1855d5a05fe7f230994f790891c6979103e2605f660c4c1262a48142dcbeb57a1914ba5f7c3fa7",
+		"a687a8985b4d8d0a24f115fe272255c6afaf3909225838546159c1ed685c211a203796ae8ecc4c81a5b6315919b3a64f10713da07e341fcdbb08541bf03066ce",
+	},
+	{
+		"I wouldn't marry him with a ten foot pole.",
+		"6c7bd0f3a6544ea698006c2ea583a85f80ea2913590a186db8bb2f1b",
+		"698e420c3a7038e53d8e73f4be2b02e03b93464ac1a61ebe69f557079921ef65",
+		"40ae213df6436eca952aa6841886fcdb82908ef1576a99c8f49bb9dd5023169f7c53035abdda0b54c302f4974e2105e7",
+		"8ddb0392e818b7d585ab22769a50df660d9f6d559cca3afc5691b8ca91b8451374e42bcdabd64589ed7c91d85f626596228a5c8572677eb98bc6b624befb7af8",
+	},
+	{
+		"Free! Free!/A trip/to Mars/for 900/empty jars/Burma Shave",
+		"981323be3eca6ccfa598e58dd74ed8cb05d5f7f6653b7604b684f904",
+		"839b414d7e3900ee243aa3d1f9b6955720e64041f5ab9bedd3eb0a08da5a2ca8",
+		"e7cf8b873c9bc950f06259aa54309f349cefa72c00d597aebf903e6519a50011dfe355afff064a10701c705693848df9",
+		"26ed8f6ca7f8d44b6a8a54ae39640fa8ad5c673f70ee9ce074ba4ef0d483eea00bab2f61d8695d6b34df9c6c48ae36246362200ed820448bdc03a720366a87c6",
+	},
+	{
+		"The days of the digital watch are numbered.  -Tom Stoppard",
+		"e6fbf82df5138bf361e826903cadf0612cb2986649ba47a57e1bca99",
+		"5625ecb9d284e54c00b257b67a8cacb25a78db2845c60ef2d29e43c84f236e8e",
+		"c3d4f0f4047181c7d39d34703365f7bf70207183caf2c2f6145f04da895ef69124d9cdeb635da636c3a474e61024e29b",
+		"e5a14bf044be69615aade89afcf1ab0389d5fc302a884d403579d1386a2400c089b0dbb387ed0f463f9ee342f8244d5a38cfbc0e819da9529fbff78368c9a982",
+	},
+	{
+		"Nepal premier won't resign.",
+		"6ec2cb2ecafc1a9bddaf4caf57344d853e6ded398927d5694fd7714f",
+		"9b81d06bca2f985e6ad3249096ff3c0f2a9ec5bb16ef530d738d19d81e7806f2",
+		"a097aab567e167d5cf93676ed73252a69f9687cb3179bb2d27c9878119e94bf7b7c4b58dc90582edfaf66e11388ed714",
+		"420a1faa48919e14651bed45725abe0f7a58e0f099424c4e5a49194946e38b46c1f8034b18ef169b2e31050d1648e0b982386595f7df47da4b6fd18e55333015",
+	},
+	{
+		"For every action there is an equal and opposite government program.",
+		"7f62f36e716e0badaf4a4658da9d09bea26357a1bc6aeb8cf7c3ae35",
+		"08241df8d91edfcd68bb1a1dada6e0ae1475a5c6e7b8f12d8e24ca43a38240a9",
+		"5026ca45c41fc64712eb65065da92f6467541c78f8966d3fe2c8e3fb769a3ec14215f819654b47bd64f7f0eac17184f3",
+		"d926a863beadb20134db07683535c72007b0e695045876254f341ddcccde132a908c5af57baa6a6a9c63e6649bba0c213dc05fadcf9abccea09f23dcfb637fbe",
+	},
+	{
+		"His money is twice tainted: 'taint yours and 'taint mine.",
+		"45adffcb86a05ee4d91263a6115dda011b805d442c60836963cb8378",
+		"4ff74d9213a8117745f5d37b5353a774ec81c5dfe65c4c8986a56fc01f2c551e",
+		"ac1cc0f5ac8d5f5514a7b738ac322b7fb52a161b449c3672e9b6a6ad1a5e4b26b001cf3bad24c56598676ca17d4b445a",
+		"9a98dd9bb67d0da7bf83da5313dff4fd60a4bac0094f1b05633690ffa7f6d61de9a1d4f8617937d560833a9aaa9ccafe3fd24db418d0e728833545cadd3ad92d",
+	},
+	{
+		"There is no reason for any individual to have a computer in their home. -Ken Olsen, 1977",
+		"51cb518f1f68daa901a3075a0a5e1acc755b4e5c82cb47687537f880",
+		"b5baf747c307f98849ec881cf0d48605ae4edd386372aea9b26e71db517e650b",
+		"722d10c5de371ec0c8c4b5247ac8a5f1d240d68c73f8da13d8b25f0166d6f309bf9561979a111a0049405771d201941a",
+		"d7fde2d2351efade52f4211d3746a0780a26eec3df9b2ed575368a8a1c09ec452402293a8ea4eceb5a4f60064ea29b13cdd86918cd7a4faf366160b009804107",
+	},
+	{
+		"It's a tiny change to the code and not completely disgusting. - Bob Manchek",
+		"3b59c5e64b0da7bfc18d7017bf458d90f2c83601ff1afc6263ac0993",
+		"7eef0538ebd7ecf18611d23b0e1cd26a74d65b929a2e374197dc66e755ca4944",
+		"dc2d3ea18bfa10549c63bf2b75b39b5167a80c12aff0e05443168ea87ff149fb0eda5e0bd234eb5d48c7d02ffc5807f1",
+		"b0f35ffa2697359c33a56f5c0cf715c7aeed96da9905ca2698acadb08fbc9e669bf566b6bd5d61a3e86dc22999bcc9f2224e33d1d4f32a228cf9d0349e2db518",
+	},
+	{
+		"size:  a.out:  bad magic",
+		"6a9525c0fac0f91b489bc4f0f539b9ec4a156a4e98bc15b655c2c881",
+		"d05600964f83f55323104aadab434f32391c029718a7690d08ddb2d7e8708443",
+		"1d67c969e2a945ae5346d2139760261504d4ba164c522443afe19ef3e29b152a4c52445489cfc9d7215e5a450e8e1e4e",
+		"3d2e5f91778c9e66f7e061293aaa8a8fc742dd3b2e4f483772464b1144189b49273e610e5cccd7a81a19ca1fa70f16b10f1a100a4d8c1372336be8484c64b311",
+	},
+	{
+		"The major problem is with sendmail.  -Mark Horton",
+		"a1b2b2905b1527d682049c6a76e35c7d8c72551abfe7833ac1be595f",
+		"53ed5f9b5c0b674ac0f3425d9f9a5d462655b07cc90f5d0f692eec093884a607",
+		"5ff8e075e465646e7b73ef36d812c6e9f7d60fa6ea0e533e5569b4f73cde53cdd2cc787f33540af57cca3fe467d32fe0",
+		"b2f68ff58ac015efb1c94c908b0d8c2bf06f491e4de8e6302c49016f7f8a33eac3e959856c7fddbc464de618701338a4b46f76dbfaf9a1e5262b5f40639771c7",
+	},
+	{
+		"Give me a rock, paper and scissors and I will move the world.  CCFestoon",
+		"76cf045c76a5f2e3d64d56c3cdba6a25479334611bc375460526f8c1",
+		"5a0147685a44eea2435dbd582724efca7637acd9c428e5e1a05115bc3bc2a0e0",
+		"5bd0a997a67c9ae1979a894eb0cde403dde003c9b6f2c03cf21925c42ff4e1176e6df1ca005381612ef18457b9b7ec3b",
+		"d8c92db5fdf52cf8215e4df3b4909d29203ff4d00e9ad0b64a6a4e04dec5e74f62e7c35c7fb881bd5de95442123df8f57a489b0ae616bd326f84d10021121c57",
+	},
+	{
+		"If the enemy is within range, then so are you.",
+		"4473671daeecfdb6f6c5bc06b26374aa5e497cc37119fe14144c430c",
+		"1152c9b27a99dbf4057d21438f4e63dd0cd0977d5ff12317c64d3b97fcac875a",
+		"1eee6da33e7e54fc5be52ae23b94b16ba4d2a947ae4505c6a3edfc7401151ea5205ac01b669b56f27d8ef7f175ed7762",
+		"19a9f8dc0a233e464e8566ad3ca9b91e459a7b8c4780985b015776e1bf239a19bc233d0556343e2b0a9bc220900b4ebf4f8bdf89ff8efeaf79602d6849e6f72e",
+	},
+	{
+		"It's well we cannot hear the screams/That we create in others' dreams.",
+		"6accb6394758523fcd453d47d37ebd10868957a0a9e81c796736abf8",
+		"105e890f5d5cf1748d9a7b4cdaf58b69855779deebc2097747c2210a17b2cb51",
+		"76b06e9dea66bfbb1a96029426dc0dfd7830bd297eb447ff5358d94a87cd00c88b59df2493fef56ecbb5231073892ea9",
+		"00b4c41f307bde87301cdc5b5ab1ae9a592e8ecbb2021dd7bc4b34e2ace60741cc362560bec566ba35178595a91932b8d5357e2c9cec92d393b0fa7831852476",
+	},
+	{
+		"You remind me of a TV show, but that's all right: I watch it anyway.",
+		"6f173f4b6eac7f2a73eaa0833c4563752df2c869dc00b7d30219e12e",
+		"74644ead770da1434365cd912656fe1aca2056d3039d39f10eb1151bddb32cf3",
+		"12acaf21452cff586143e3f5db0bfdf7802c057e1adf2a619031c4e1b0ccc4208cf6cef8fe722bbaa2fb46a30d9135d8",
+		"91eccc3d5375fd026e4d6787874b1dce201cecd8a27dbded5065728cb2d09c58a3d467bb1faf353bf7ba567e005245d5321b55bc344f7c07b91cb6f26c959be7",
+	},
+	{
+		"C is as portable as Stonehedge!!",
+		"db05bf4d0f73325208755f4af96cfac6cb3db5dbfc323d675d68f938",
+		"50a234625de5587581883dad9ef399460928032a5ea6bd005d7dc7b68d8cc3d6",
+		"0fc23d7f4183efd186f0bc4fc5db867e026e2146b06cb3d52f4bdbd57d1740122caa853b41868b197b2ac759db39df88",
+		"fabbbe22180f1f137cfdc9556d2570e775d1ae02a597ded43a72a40f9b485d500043b7be128fb9fcd982b83159a0d99aa855a9e7cc4240c00dc01a9bdf8218d7",
+	},
+	{
+		"Even if I could be Shakespeare, I think I should still choose to be Faraday. - A. Huxley",
+		"05ffa71bb02e855de1aaee1777b3bdbaf7507646f19c4c6aa29933d0",
+		"a7a3846005f8a9935a0a2d43e7fd56d95132a9a3609bf3296ef80b8218acffa0",
+		"bc805578a7f85d34a86a32976e1c34fe65cf815186fbef76f46ef99cda10723f971f3f1464d488243f5e29db7488598d",
+		"2ecdec235c1fa4fc2a154d8fba1dddb8a72a1ad73838b51d792331d143f8b96a9f6fcb0f34d7caa351fe6d88771c4f105040e0392f06e0621689d33b2f3ba92e",
+	},
+	{
+		"The fugacity of a constituent in a mixture of gases at a given temperature is proportional to its mole fraction.  Lewis-Randall Rule",
+		"3ad3c89e15b91e6273534c5d18adadbb528e7b840b288f64e81b8c6d",
+		"688ff03e367680757aa9906cb1e2ad218c51f4526dc0426ea229a5ba9d002c69",
+		"b23918399a12ebf4431559eec3813eaf7412e875fd7464f16d581e473330842d2e96c6be49a7ce3f9bb0b8bc0fcbe0fe",
+		"7ad681f6f96f82f7abfa7ecc0334e8fa16d3dc1cdc45b60b7af43fe4075d2357c0c1d60e98350f1afb1f2fe7a4d7cd2ad55b88e458e06b73c40b437331f5dab4",
+	},
+	{
+		"How can you write a big system without C++?  -Paul Glick",
+		"e3763669d1b760c1be7bfcb6625f92300a8430419d1dbad57ec9f53c",
+		"3fa46d52094b01021cff5af9a438982b887a5793f624c0a6644149b6b7c3f485",
+		"1764b700eb1ead52a2fc33cc28975c2180f1b8faa5038d94cffa8d78154aab16e91dd787e7b0303948ebed62561542c8",
+		"833f9248ab4a3b9e5131f745fda1ffd2dd435b30e965957e78291c7ab73605fd1912b0794e5c233ab0a12d205a39778d19b83515d6a47003f19cdee51d98c7e0",
+	},
 }
 
-var golden384 = []sha512Test{
-	{"38b060a751ac96384cd9327eb1b1e36a21fdb71114be07434c0cc7bf63f6e1da274edebfe76f65fbd51ad2f14898b95b", ""},
-	{"54a59b9f22b0b80880d8427e548b7c23abd873486e1f035dce9cd697e85175033caa88e6d57bc35efae0b5afd3145f31", "a"},
-	{"c7be03ba5bcaa384727076db0018e99248e1a6e8bd1b9ef58a9ec9dd4eeebb3f48b836201221175befa74ddc3d35afdd", "ab"},
-	{"cb00753f45a35e8bb5a03d699ac65007272c32ab0eded1631a8b605a43ff5bed8086072ba1e7cc2358baeca134c825a7", "abc"},
-	{"1165b3406ff0b52a3d24721f785462ca2276c9f454a116c2b2ba20171a7905ea5a026682eb659c4d5f115c363aa3c79b", "abcd"},
-	{"4c525cbeac729eaf4b4665815bc5db0c84fe6300068a727cf74e2813521565abc0ec57a37ee4d8be89d097c0d2ad52f0", "abcde"},
-	{"c6a4c65b227e7387b9c3e839d44869c4cfca3ef583dea64117859b808c1e3d8ae689e1e314eeef52a6ffe22681aa11f5", "abcdef"},
-	{"9f11fc131123f844c1226f429b6a0a6af0525d9f40f056c7fc16cdf1b06bda08e302554417a59fa7dcf6247421959d22", "abcdefg"},
-	{"9000cd7cada59d1d2eb82912f7f24e5e69cc5517f68283b005fa27c285b61e05edf1ad1a8a9bded6fd29eb87d75ad806", "abcdefgh"},
-	{"ef54915b60cf062b8dd0c29ae3cad69abe6310de63ac081f46ef019c5c90897caefd79b796cfa81139788a260ded52df", "abcdefghi"},
-	{"a12070030a02d86b0ddacd0d3a5b598344513d0a051e7355053e556a0055489c1555399b03342845c4adde2dc44ff66c", "abcdefghij"},
-	{"86f58ec2d74d1b7f8eb0c2ff0967316699639e8d4eb129de54bdf34c96cdbabe200d052149f2dd787f43571ba74670d4", "Discard medicine more than two years old."},
-	{"ae4a2b639ca9bfa04b1855d5a05fe7f230994f790891c6979103e2605f660c4c1262a48142dcbeb57a1914ba5f7c3fa7", "He who has a shady past knows that nice guys finish last."},
-	{"40ae213df6436eca952aa6841886fcdb82908ef1576a99c8f49bb9dd5023169f7c53035abdda0b54c302f4974e2105e7", "I wouldn't marry him with a ten foot pole."},
-	{"e7cf8b873c9bc950f06259aa54309f349cefa72c00d597aebf903e6519a50011dfe355afff064a10701c705693848df9", "Free! Free!/A trip/to Mars/for 900/empty jars/Burma Shave"},
-	{"c3d4f0f4047181c7d39d34703365f7bf70207183caf2c2f6145f04da895ef69124d9cdeb635da636c3a474e61024e29b", "The days of the digital watch are numbered.  -Tom Stoppard"},
-	{"a097aab567e167d5cf93676ed73252a69f9687cb3179bb2d27c9878119e94bf7b7c4b58dc90582edfaf66e11388ed714", "Nepal premier won't resign."},
-	{"5026ca45c41fc64712eb65065da92f6467541c78f8966d3fe2c8e3fb769a3ec14215f819654b47bd64f7f0eac17184f3", "For every action there is an equal and opposite government program."},
-	{"ac1cc0f5ac8d5f5514a7b738ac322b7fb52a161b449c3672e9b6a6ad1a5e4b26b001cf3bad24c56598676ca17d4b445a", "His money is twice tainted: 'taint yours and 'taint mine."},
-	{"722d10c5de371ec0c8c4b5247ac8a5f1d240d68c73f8da13d8b25f0166d6f309bf9561979a111a0049405771d201941a", "There is no reason for any individual to have a computer in their home. -Ken Olsen, 1977"},
-	{"dc2d3ea18bfa10549c63bf2b75b39b5167a80c12aff0e05443168ea87ff149fb0eda5e0bd234eb5d48c7d02ffc5807f1", "It's a tiny change to the code and not completely disgusting. - Bob Manchek"},
-	{"1d67c969e2a945ae5346d2139760261504d4ba164c522443afe19ef3e29b152a4c52445489cfc9d7215e5a450e8e1e4e", "size:  a.out:  bad magic"},
-	{"5ff8e075e465646e7b73ef36d812c6e9f7d60fa6ea0e533e5569b4f73cde53cdd2cc787f33540af57cca3fe467d32fe0", "The major problem is with sendmail.  -Mark Horton"},
-	{"5bd0a997a67c9ae1979a894eb0cde403dde003c9b6f2c03cf21925c42ff4e1176e6df1ca005381612ef18457b9b7ec3b", "Give me a rock, paper and scissors and I will move the world.  CCFestoon"},
-	{"1eee6da33e7e54fc5be52ae23b94b16ba4d2a947ae4505c6a3edfc7401151ea5205ac01b669b56f27d8ef7f175ed7762", "If the enemy is within range, then so are you."},
-	{"76b06e9dea66bfbb1a96029426dc0dfd7830bd297eb447ff5358d94a87cd00c88b59df2493fef56ecbb5231073892ea9", "It's well we cannot hear the screams/That we create in others' dreams."},
-	{"12acaf21452cff586143e3f5db0bfdf7802c057e1adf2a619031c4e1b0ccc4208cf6cef8fe722bbaa2fb46a30d9135d8", "You remind me of a TV show, but that's all right: I watch it anyway."},
-	{"0fc23d7f4183efd186f0bc4fc5db867e026e2146b06cb3d52f4bdbd57d1740122caa853b41868b197b2ac759db39df88", "C is as portable as Stonehedge!!"},
-	{"bc805578a7f85d34a86a32976e1c34fe65cf815186fbef76f46ef99cda10723f971f3f1464d488243f5e29db7488598d", "Even if I could be Shakespeare, I think I should still choose to be Faraday. - A. Huxley"},
-	{"b23918399a12ebf4431559eec3813eaf7412e875fd7464f16d581e473330842d2e96c6be49a7ce3f9bb0b8bc0fcbe0fe", "The fugacity of a constituent in a mixture of gases at a given temperature is proportional to its mole fraction.  Lewis-Randall Rule"},
-	{"1764b700eb1ead52a2fc33cc28975c2180f1b8faa5038d94cffa8d78154aab16e91dd787e7b0303948ebed62561542c8", "How can you write a big system without C++?  -Paul Glick"},
+func testHash(t *testing.T, name, in, outHex string, oneShotResult []byte, digestFunc hash.Hash) {
+	if calculated := hex.EncodeToString(oneShotResult); calculated != outHex {
+		t.Errorf("one-shot result for %s(%q) = %q, but expected %q", name, in, calculated, outHex)
+		return
+	}
+
+	for pass := 0; pass < 3; pass++ {
+		if pass < 2 {
+			io.WriteString(digestFunc, in)
+		} else {
+			io.WriteString(digestFunc, in[:len(in)/2])
+			digestFunc.Sum(nil)
+			io.WriteString(digestFunc, in[len(in)/2:])
+		}
+
+		if calculated := hex.EncodeToString(digestFunc.Sum(nil)); calculated != outHex {
+			t.Errorf("%s(%q) = %q (in pass #%d), but expected %q", name, in, calculated, pass, outHex)
+		}
+		digestFunc.Reset()
+	}
 }
 
 func TestGolden(t *testing.T) {
-	for i := 0; i < len(golden); i++ {
-		g := golden[i]
-		s := fmt.Sprintf("%x", Sum512([]byte(g.in)))
-		if s != g.out {
-			t.Fatalf("Sum512 function: sha512(%s) = %s want %s", g.in, s, g.out)
-		}
-		c := New()
-		for j := 0; j < 3; j++ {
-			if j < 2 {
-				io.WriteString(c, g.in)
-			} else {
-				io.WriteString(c, g.in[0:len(g.in)/2])
-				c.Sum(nil)
-				io.WriteString(c, g.in[len(g.in)/2:])
-			}
-			s := fmt.Sprintf("%x", c.Sum(nil))
-			if s != g.out {
-				t.Fatalf("sha512[%d](%s) = %s want %s", j, g.in, s, g.out)
-			}
-			c.Reset()
-		}
-	}
-	for i := 0; i < len(golden384); i++ {
-		g := golden384[i]
-		s := fmt.Sprintf("%x", Sum384([]byte(g.in)))
-		if s != g.out {
-			t.Fatalf("Sum384 function: sha384(%s) = %s want %s", g.in, s, g.out)
-		}
-		c := New384()
-		for j := 0; j < 3; j++ {
-			if j < 2 {
-				io.WriteString(c, g.in)
-			} else {
-				io.WriteString(c, g.in[0:len(g.in)/2])
-				c.Sum(nil)
-				io.WriteString(c, g.in[len(g.in)/2:])
-			}
-			s := fmt.Sprintf("%x", c.Sum(nil))
-			if s != g.out {
-				t.Fatalf("sha384[%d](%s) = %s want %s", j, g.in, s, g.out)
-			}
-			c.Reset()
-		}
+	for _, test := range golden {
+		in := []byte(test.in)
+
+		sum224 := Sum512_224(in)
+		sum256 := Sum512_256(in)
+		sum384 := Sum384(in)
+		sum512 := Sum512(in)
+		testHash(t, "SHA512/224", test.in, test.out224, sum224[:], New512_224())
+		testHash(t, "SHA512/256", test.in, test.out256, sum256[:], New512_256())
+		testHash(t, "SHA384", test.in, test.out384, sum384[:], New384())
+		testHash(t, "SHA512", test.in, test.out512, sum512[:], New())
 	}
 }
 
@@ -141,6 +287,14 @@
 	if got := c.Size(); got != Size384 {
 		t.Errorf("New384.Size = %d; want %d", got, Size384)
 	}
+	c = New512_224()
+	if got := c.Size(); got != Size224 {
+		t.Errorf("New512224.Size = %d; want %d", got, Size224)
+	}
+	c = New512_256()
+	if got := c.Size(); got != Size256 {
+		t.Errorf("New512256.Size = %d; want %d", got, Size256)
+	}
 }
 
 func TestBlockSize(t *testing.T) {
diff --git a/third_party/gofrontend/libgo/go/crypto/tls/cipher_suites.go b/third_party/gofrontend/libgo/go/crypto/tls/cipher_suites.go
index 226e06d..a5fed29 100644
--- a/third_party/gofrontend/libgo/go/crypto/tls/cipher_suites.go
+++ b/third_party/gofrontend/libgo/go/crypto/tls/cipher_suites.go
@@ -48,6 +48,12 @@
 	// suiteTLS12 indicates that the cipher suite should only be advertised
 	// and accepted when using TLS 1.2.
 	suiteTLS12
+	// suiteSHA384 indicates that the cipher suite uses SHA384 as the
+	// handshake hash.
+	suiteSHA384
+	// suiteDefaultOff indicates that this cipher suite is not included by
+	// default.
+	suiteDefaultOff
 )
 
 // A cipherSuite is a specific combination of key agreement, cipher and MAC
@@ -71,13 +77,15 @@
 	// and RC4 comes before AES (because of the Lucky13 attack).
 	{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 16, 0, 4, ecdheRSAKA, suiteECDHE | suiteTLS12, nil, nil, aeadAESGCM},
 	{TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 16, 0, 4, ecdheECDSAKA, suiteECDHE | suiteECDSA | suiteTLS12, nil, nil, aeadAESGCM},
-	{TLS_ECDHE_RSA_WITH_RC4_128_SHA, 16, 20, 0, ecdheRSAKA, suiteECDHE, cipherRC4, macSHA1, nil},
-	{TLS_ECDHE_ECDSA_WITH_RC4_128_SHA, 16, 20, 0, ecdheECDSAKA, suiteECDHE | suiteECDSA, cipherRC4, macSHA1, nil},
+	{TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, 32, 0, 4, ecdheRSAKA, suiteECDHE | suiteTLS12 | suiteSHA384, nil, nil, aeadAESGCM},
+	{TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, 32, 0, 4, ecdheECDSAKA, suiteECDHE | suiteECDSA | suiteTLS12 | suiteSHA384, nil, nil, aeadAESGCM},
+	{TLS_ECDHE_RSA_WITH_RC4_128_SHA, 16, 20, 0, ecdheRSAKA, suiteECDHE | suiteDefaultOff, cipherRC4, macSHA1, nil},
+	{TLS_ECDHE_ECDSA_WITH_RC4_128_SHA, 16, 20, 0, ecdheECDSAKA, suiteECDHE | suiteECDSA | suiteDefaultOff, cipherRC4, macSHA1, nil},
 	{TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, 16, 20, 16, ecdheRSAKA, suiteECDHE, cipherAES, macSHA1, nil},
 	{TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, 16, 20, 16, ecdheECDSAKA, suiteECDHE | suiteECDSA, cipherAES, macSHA1, nil},
 	{TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, 32, 20, 16, ecdheRSAKA, suiteECDHE, cipherAES, macSHA1, nil},
 	{TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, 32, 20, 16, ecdheECDSAKA, suiteECDHE | suiteECDSA, cipherAES, macSHA1, nil},
-	{TLS_RSA_WITH_RC4_128_SHA, 16, 20, 0, rsaKA, 0, cipherRC4, macSHA1, nil},
+	{TLS_RSA_WITH_RC4_128_SHA, 16, 20, 0, rsaKA, suiteDefaultOff, cipherRC4, macSHA1, nil},
 	{TLS_RSA_WITH_AES_128_CBC_SHA, 16, 20, 16, rsaKA, 0, cipherAES, macSHA1, nil},
 	{TLS_RSA_WITH_AES_256_CBC_SHA, 32, 20, 16, rsaKA, 0, cipherAES, macSHA1, nil},
 	{TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA, 24, 20, 8, ecdheRSAKA, suiteECDHE, cipher3DES, macSHA1, nil},
@@ -267,6 +275,8 @@
 	TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA      uint16 = 0xc014
 	TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256   uint16 = 0xc02f
 	TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 uint16 = 0xc02b
+	TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384   uint16 = 0xc030
+	TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 uint16 = 0xc02c
 
 	// TLS_FALLBACK_SCSV isn't a standard cipher suite but an indicator
 	// that the client is doing version fallback. See
diff --git a/third_party/gofrontend/libgo/go/crypto/tls/common.go b/third_party/gofrontend/libgo/go/crypto/tls/common.go
index 776b70c..a3d75d6 100644
--- a/third_party/gofrontend/libgo/go/crypto/tls/common.go
+++ b/third_party/gofrontend/libgo/go/crypto/tls/common.go
@@ -8,7 +8,9 @@
 	"container/list"
 	"crypto"
 	"crypto/rand"
+	"crypto/sha512"
 	"crypto/x509"
+	"errors"
 	"fmt"
 	"io"
 	"math/big"
@@ -30,7 +32,7 @@
 	recordHeaderLen = 5            // record header length
 	maxHandshake    = 65536        // maximum handshake we support (protocol max is 16 MB)
 
-	minVersion = VersionSSL30
+	minVersion = VersionTLS10
 	maxVersion = VersionTLS12
 )
 
@@ -73,6 +75,7 @@
 	extensionSupportedPoints     uint16 = 11
 	extensionSignatureAlgorithms uint16 = 13
 	extensionALPN                uint16 = 16
+	extensionSCT                 uint16 = 18 // https://tools.ietf.org/html/rfc6962#section-6
 	extensionSessionTicket       uint16 = 35
 	extensionNextProtoNeg        uint16 = 13172 // not IANA assigned
 	extensionRenegotiationInfo   uint16 = 0xff01
@@ -123,6 +126,7 @@
 const (
 	hashSHA1   uint8 = 2
 	hashSHA256 uint8 = 4
+	hashSHA384 uint8 = 5
 )
 
 // Signature algorithms for TLS 1.2 (See RFC 5246, section A.4.1)
@@ -137,34 +141,31 @@
 	hash, signature uint8
 }
 
-// supportedSKXSignatureAlgorithms contains the signature and hash algorithms
-// that the code advertises as supported in a TLS 1.2 ClientHello.
-var supportedSKXSignatureAlgorithms = []signatureAndHash{
+// supportedSignatureAlgorithms contains the signature and hash algorithms that
+// the code advertises as supported in a TLS 1.2 ClientHello and in a TLS 1.2
+// CertificateRequest.
+var supportedSignatureAlgorithms = []signatureAndHash{
 	{hashSHA256, signatureRSA},
 	{hashSHA256, signatureECDSA},
+	{hashSHA384, signatureRSA},
+	{hashSHA384, signatureECDSA},
 	{hashSHA1, signatureRSA},
 	{hashSHA1, signatureECDSA},
 }
 
-// supportedClientCertSignatureAlgorithms contains the signature and hash
-// algorithms that the code advertises as supported in a TLS 1.2
-// CertificateRequest.
-var supportedClientCertSignatureAlgorithms = []signatureAndHash{
-	{hashSHA256, signatureRSA},
-	{hashSHA256, signatureECDSA},
-}
-
 // ConnectionState records basic TLS details about the connection.
 type ConnectionState struct {
-	Version                    uint16                // TLS version used by the connection (e.g. VersionTLS12)
-	HandshakeComplete          bool                  // TLS handshake is complete
-	DidResume                  bool                  // connection resumes a previous TLS connection
-	CipherSuite                uint16                // cipher suite in use (TLS_RSA_WITH_RC4_128_SHA, ...)
-	NegotiatedProtocol         string                // negotiated next protocol (from Config.NextProtos)
-	NegotiatedProtocolIsMutual bool                  // negotiated protocol was advertised by server
-	ServerName                 string                // server name requested by client, if any (server side only)
-	PeerCertificates           []*x509.Certificate   // certificate chain presented by remote peer
-	VerifiedChains             [][]*x509.Certificate // verified chains built from PeerCertificates
+	Version                     uint16                // TLS version used by the connection (e.g. VersionTLS12)
+	HandshakeComplete           bool                  // TLS handshake is complete
+	DidResume                   bool                  // connection resumes a previous TLS connection
+	CipherSuite                 uint16                // cipher suite in use (TLS_RSA_WITH_RC4_128_SHA, ...)
+	NegotiatedProtocol          string                // negotiated next protocol (from Config.NextProtos)
+	NegotiatedProtocolIsMutual  bool                  // negotiated protocol was advertised by server
+	ServerName                  string                // server name requested by client, if any (server side only)
+	PeerCertificates            []*x509.Certificate   // certificate chain presented by remote peer
+	VerifiedChains              [][]*x509.Certificate // verified chains built from PeerCertificates
+	SignedCertificateTimestamps [][]byte              // SCTs from the server, if any
+	OCSPResponse                []byte                // stapled OCSP response from server, if any
 
 	// TLSUnique contains the "tls-unique" channel binding value (see RFC
 	// 5929, section 3). For resumed sessions this value will be nil
@@ -190,11 +191,12 @@
 // ClientSessionState contains the state needed by clients to resume TLS
 // sessions.
 type ClientSessionState struct {
-	sessionTicket      []uint8             // Encrypted ticket used for session resumption with server
-	vers               uint16              // SSL/TLS version negotiated for the session
-	cipherSuite        uint16              // Ciphersuite negotiated for the session
-	masterSecret       []byte              // MasterSecret generated by client on a full handshake
-	serverCertificates []*x509.Certificate // Certificate chain presented by the server
+	sessionTicket      []uint8               // Encrypted ticket used for session resumption with server
+	vers               uint16                // SSL/TLS version negotiated for the session
+	cipherSuite        uint16                // Ciphersuite negotiated for the session
+	masterSecret       []byte                // MasterSecret generated by client on a full handshake
+	serverCertificates []*x509.Certificate   // Certificate chain presented by the server
+	verifiedChains     [][]*x509.Certificate // Certificate chains we built for verification
 }
 
 // ClientSessionCache is a cache of ClientSessionState objects that can be used
@@ -265,10 +267,12 @@
 	NameToCertificate map[string]*Certificate
 
 	// GetCertificate returns a Certificate based on the given
-	// ClientHelloInfo. If GetCertificate is nil or returns nil, then the
-	// certificate is retrieved from NameToCertificate. If
-	// NameToCertificate is nil, the first element of Certificates will be
-	// used.
+	// ClientHelloInfo. It will only be called if the client supplies SNI
+	// information or if Certificates is empty.
+	//
+	// If GetCertificate is nil or returns nil, then the certificate is
+	// retrieved from NameToCertificate. If NameToCertificate is nil, the
+	// first element of Certificates will be used.
 	GetCertificate func(clientHello *ClientHelloInfo) (*Certificate, error)
 
 	// RootCAs defines the set of root certificate authorities
@@ -330,7 +334,7 @@
 	ClientSessionCache ClientSessionCache
 
 	// MinVersion contains the minimum SSL/TLS version that is acceptable.
-	// If zero, then SSLv3 is taken as the minimum.
+	// If zero, then TLS 1.0 is taken as the minimum.
 	MinVersion uint16
 
 	// MaxVersion contains the maximum SSL/TLS version that is acceptable.
@@ -344,6 +348,38 @@
 	CurvePreferences []CurveID
 
 	serverInitOnce sync.Once // guards calling (*Config).serverInit
+
+	// mutex protects sessionTicketKeys
+	mutex sync.RWMutex
+	// sessionTicketKeys contains zero or more ticket keys. If the length
+	// is zero, SessionTicketsDisabled must be true. The first key is used
+	// for new tickets and any subsequent keys can be used to decrypt old
+	// tickets.
+	sessionTicketKeys []ticketKey
+}
+
+// ticketKeyNameLen is the number of bytes of identifier that is prepended to
+// an encrypted session ticket in order to identify the key used to encrypt it.
+const ticketKeyNameLen = 16
+
+// ticketKey is the internal representation of a session ticket key.
+type ticketKey struct {
+	// keyName is an opaque byte string that serves to identify the session
+	// ticket key. It's exposed as plaintext in every session ticket.
+	keyName [ticketKeyNameLen]byte
+	aesKey  [16]byte
+	hmacKey [16]byte
+}
+
+// ticketKeyFromBytes converts from the external representation of a session
+// ticket key to a ticketKey. Externally, session ticket keys are 32 random
+// bytes and this function expands that into sufficient name and key material.
+func ticketKeyFromBytes(b [32]byte) (key ticketKey) {
+	hashed := sha512.Sum512(b[:])
+	copy(key.keyName[:], hashed[:ticketKeyNameLen])
+	copy(key.aesKey[:], hashed[ticketKeyNameLen:ticketKeyNameLen+16])
+	copy(key.hmacKey[:], hashed[ticketKeyNameLen+16:ticketKeyNameLen+32])
+	return key
 }
 
 func (c *Config) serverInit() {
@@ -351,16 +387,51 @@
 		return
 	}
 
-	// If the key has already been set then we have nothing to do.
+	alreadySet := false
 	for _, b := range c.SessionTicketKey {
 		if b != 0 {
+			alreadySet = true
+			break
+		}
+	}
+
+	if !alreadySet {
+		if _, err := io.ReadFull(c.rand(), c.SessionTicketKey[:]); err != nil {
+			c.SessionTicketsDisabled = true
 			return
 		}
 	}
 
-	if _, err := io.ReadFull(c.rand(), c.SessionTicketKey[:]); err != nil {
-		c.SessionTicketsDisabled = true
+	c.sessionTicketKeys = []ticketKey{ticketKeyFromBytes(c.SessionTicketKey)}
+}
+
+func (c *Config) ticketKeys() []ticketKey {
+	c.mutex.RLock()
+	// c.sessionTicketKeys is constant once created. SetSessionTicketKeys
+	// will only update it by replacing it with a new value.
+	ret := c.sessionTicketKeys
+	c.mutex.RUnlock()
+	return ret
+}
+
+// SetSessionTicketKeys updates the session ticket keys for a server. The first
+// key will be used when creating new tickets, while all keys can be used for
+// decrypting tickets. It is safe to call this function while the server is
+// running in order to rotate the session ticket keys. The function will panic
+// if keys is empty.
+func (c *Config) SetSessionTicketKeys(keys [][32]byte) {
+	if len(keys) == 0 {
+		panic("tls: keys must have at least one key")
 	}
+
+	newKeys := make([]ticketKey, len(keys))
+	for i, bytes := range keys {
+		newKeys[i] = ticketKeyFromBytes(bytes)
+	}
+
+	c.mutex.Lock()
+	c.sessionTicketKeys = newKeys
+	c.mutex.Unlock()
 }
 
 func (c *Config) rand() io.Reader {
@@ -428,13 +499,18 @@
 // getCertificate returns the best certificate for the given ClientHelloInfo,
 // defaulting to the first element of c.Certificates.
 func (c *Config) getCertificate(clientHello *ClientHelloInfo) (*Certificate, error) {
-	if c.GetCertificate != nil {
+	if c.GetCertificate != nil &&
+		(len(c.Certificates) == 0 || len(clientHello.ServerName) > 0) {
 		cert, err := c.GetCertificate(clientHello)
 		if cert != nil || err != nil {
 			return cert, err
 		}
 	}
 
+	if len(c.Certificates) == 0 {
+		return nil, errors.New("crypto/tls: no certificates configured")
+	}
+
 	if len(c.Certificates) == 1 || c.NameToCertificate == nil {
 		// There's only one choice, so no point doing any work.
 		return &c.Certificates[0], nil
@@ -488,14 +564,17 @@
 type Certificate struct {
 	Certificate [][]byte
 	// PrivateKey contains the private key corresponding to the public key
-	// in Leaf. For a server, this must be a *rsa.PrivateKey or
-	// *ecdsa.PrivateKey. For a client doing client authentication, this
-	// can be any type that implements crypto.Signer (which includes RSA
-	// and ECDSA private keys).
+	// in Leaf. For a server, this must implement crypto.Signer and/or
+	// crypto.Decrypter, with an RSA or ECDSA PublicKey. For a client
+	// (performing client authentication), this must be a crypto.Signer
+	// with an RSA or ECDSA PublicKey.
 	PrivateKey crypto.PrivateKey
 	// OCSPStaple contains an optional OCSP response which will be served
 	// to clients that request it.
 	OCSPStaple []byte
+	// SignedCertificateTimestamps contains an optional list of Signed
+	// Certificate Timestamps which will be served to clients that request it.
+	SignedCertificateTimestamps [][]byte
 	// Leaf is the parsed form of the leaf certificate, which may be
 	// initialized using x509.ParseCertificate to reduce per-handshake
 	// processing for TLS clients doing client authentication. If nil, the
@@ -610,12 +689,24 @@
 }
 
 func initDefaultCipherSuites() {
-	varDefaultCipherSuites = make([]uint16, len(cipherSuites))
-	for i, suite := range cipherSuites {
-		varDefaultCipherSuites[i] = suite.id
+	varDefaultCipherSuites = make([]uint16, 0, len(cipherSuites))
+	for _, suite := range cipherSuites {
+		if suite.flags&suiteDefaultOff != 0 {
+			continue
+		}
+		varDefaultCipherSuites = append(varDefaultCipherSuites, suite.id)
 	}
 }
 
 func unexpectedMessageError(wanted, got interface{}) error {
 	return fmt.Errorf("tls: received unexpected handshake message of type %T when waiting for %T", got, wanted)
 }
+
+func isSupportedSignatureAndHash(sigHash signatureAndHash, sigHashes []signatureAndHash) bool {
+	for _, s := range sigHashes {
+		if s == sigHash {
+			return true
+		}
+	}
+	return false
+}
diff --git a/third_party/gofrontend/libgo/go/crypto/tls/conn.go b/third_party/gofrontend/libgo/go/crypto/tls/conn.go
index ba8e4c2..e3dcf15 100644
--- a/third_party/gofrontend/libgo/go/crypto/tls/conn.go
+++ b/third_party/gofrontend/libgo/go/crypto/tls/conn.go
@@ -35,7 +35,8 @@
 	handshakeComplete bool
 	didResume         bool // whether this connection was a session resumption
 	cipherSuite       uint16
-	ocspResponse      []byte // stapled OCSP response
+	ocspResponse      []byte   // stapled OCSP response
+	scts              [][]byte // signed certificate timestamps from server
 	peerCertificates  []*x509.Certificate
 	// verifiedChains contains the certificate chains that we built, as
 	// opposed to the ones presented by the server.
@@ -570,15 +571,11 @@
 		return c.in.setErrorLocked(fmt.Errorf("tls: oversized record received with length %d", n))
 	}
 	if !c.haveVers {
-		// First message, be extra suspicious:
-		// this might not be a TLS client.
-		// Bail out before reading a full 'body', if possible.
-		// The current max version is 3.1.
-		// If the version is >= 16.0, it's probably not real.
-		// Similarly, a clientHello message encodes in
-		// well under a kilobyte.  If the length is >= 12 kB,
+		// First message, be extra suspicious: this might not be a TLS
+		// client. Bail out before reading a full 'body', if possible.
+		// The current max version is 3.3 so if the version is >= 16.0,
 		// it's probably not real.
-		if (typ != recordTypeAlert && typ != want) || vers >= 0x1000 || n >= 0x3000 {
+		if (typ != recordTypeAlert && typ != want) || vers >= 0x1000 {
 			c.sendAlert(alertUnexpectedMessage)
 			return c.in.setErrorLocked(fmt.Errorf("tls: first record does not look like a TLS handshake"))
 		}
@@ -926,7 +923,7 @@
 		// tried to reuse the HTTP connection for a new
 		// request.
 		// See https://codereview.appspot.com/76400046
-		// and http://golang.org/issue/3514
+		// and https://golang.org/issue/3514
 		if ri := c.rawInput; ri != nil &&
 			n != 0 && err == nil &&
 			c.input == nil && len(ri.data) > 0 && recordType(ri.data[0]) == recordTypeAlert {
@@ -997,6 +994,8 @@
 		state.PeerCertificates = c.peerCertificates
 		state.VerifiedChains = c.verifiedChains
 		state.ServerName = c.serverName
+		state.SignedCertificateTimestamps = c.scts
+		state.OCSPResponse = c.ocspResponse
 		if !c.didResume {
 			state.TLSUnique = c.firstFinished[:]
 		}
@@ -1026,5 +1025,8 @@
 	if !c.handshakeComplete {
 		return errors.New("tls: handshake has not yet been performed")
 	}
+	if len(c.verifiedChains) == 0 {
+		return errors.New("tls: handshake did not verify certificate chain")
+	}
 	return c.peerCertificates[0].VerifyHostname(host)
 }
diff --git a/third_party/gofrontend/libgo/go/crypto/tls/handshake_client.go b/third_party/gofrontend/libgo/go/crypto/tls/handshake_client.go
index 7f662e9..0b591d7 100644
--- a/third_party/gofrontend/libgo/go/crypto/tls/handshake_client.go
+++ b/third_party/gofrontend/libgo/go/crypto/tls/handshake_client.go
@@ -54,6 +54,7 @@
 		compressionMethods:  []uint8{compressionNone},
 		random:              make([]byte, 32),
 		ocspStapling:        true,
+		scts:                true,
 		serverName:          c.config.ServerName,
 		supportedCurves:     c.config.curvePreferences(),
 		supportedPoints:     []uint8{pointFormatUncompressed},
@@ -88,7 +89,7 @@
 	}
 
 	if hello.vers >= VersionTLS12 {
-		hello.signatureAndHashes = supportedSKXSignatureAlgorithms
+		hello.signatureAndHashes = supportedSignatureAlgorithms
 	}
 
 	var session *ClientSessionState
@@ -168,18 +169,26 @@
 		serverHello:  serverHello,
 		hello:        hello,
 		suite:        suite,
-		finishedHash: newFinishedHash(c.vers),
+		finishedHash: newFinishedHash(c.vers, suite),
 		session:      session,
 	}
 
-	hs.finishedHash.Write(hs.hello.marshal())
-	hs.finishedHash.Write(hs.serverHello.marshal())
-
 	isResume, err := hs.processServerHello()
 	if err != nil {
 		return err
 	}
 
+	// No signatures of the handshake are needed in a resumption.
+	// Otherwise, in a full handshake, if we don't have any certificates
+	// configured then we will never send a CertificateVerify message and
+	// thus no signatures are needed in that case either.
+	if isResume || len(c.config.Certificates) == 0 {
+		hs.finishedHash.discardHandshakeBuffer()
+	}
+
+	hs.finishedHash.Write(hs.hello.marshal())
+	hs.finishedHash.Write(hs.serverHello.marshal())
+
 	if isResume {
 		if err := hs.establishKeys(); err != nil {
 			return err
@@ -423,7 +432,6 @@
 	}
 
 	if chainToSend != nil {
-		var signed []byte
 		certVerify := &certificateVerifyMsg{
 			hasSignatureAndHash: c.vers >= VersionTLS12,
 		}
@@ -433,31 +441,42 @@
 			c.sendAlert(alertInternalError)
 			return fmt.Errorf("tls: client certificate private key of type %T does not implement crypto.Signer", chainToSend.PrivateKey)
 		}
+
+		var signatureType uint8
 		switch key.Public().(type) {
 		case *ecdsa.PublicKey:
-			digest, hashFunc, hashId := hs.finishedHash.hashForClientCertificate(signatureECDSA)
-			signed, err = key.Sign(c.config.rand(), digest, hashFunc)
-			certVerify.signatureAndHash.signature = signatureECDSA
-			certVerify.signatureAndHash.hash = hashId
+			signatureType = signatureECDSA
 		case *rsa.PublicKey:
-			digest, hashFunc, hashId := hs.finishedHash.hashForClientCertificate(signatureRSA)
-			signed, err = key.Sign(c.config.rand(), digest, hashFunc)
-			certVerify.signatureAndHash.signature = signatureRSA
-			certVerify.signatureAndHash.hash = hashId
+			signatureType = signatureRSA
 		default:
-			err = fmt.Errorf("tls: unknown client certificate key type: %T", key)
+			c.sendAlert(alertInternalError)
+			return fmt.Errorf("tls: failed to sign handshake with client certificate: unknown client certificate key type: %T", key)
 		}
+
+		certVerify.signatureAndHash, err = hs.finishedHash.selectClientCertSignatureAlgorithm(certReq.signatureAndHashes, signatureType)
 		if err != nil {
 			c.sendAlert(alertInternalError)
-			return errors.New("tls: failed to sign handshake with client certificate: " + err.Error())
+			return err
 		}
-		certVerify.signature = signed
+		digest, hashFunc, err := hs.finishedHash.hashForClientCertificate(certVerify.signatureAndHash, hs.masterSecret)
+		if err != nil {
+			c.sendAlert(alertInternalError)
+			return err
+		}
+		certVerify.signature, err = key.Sign(c.config.rand(), digest, hashFunc)
+		if err != nil {
+			c.sendAlert(alertInternalError)
+			return err
+		}
 
 		hs.finishedHash.Write(certVerify.marshal())
 		c.writeRecord(recordTypeHandshake, certVerify.marshal())
 	}
 
-	hs.masterSecret = masterFromPreMasterSecret(c.vers, preMasterSecret, hs.hello.random, hs.serverHello.random)
+	hs.masterSecret = masterFromPreMasterSecret(c.vers, hs.suite, preMasterSecret, hs.hello.random, hs.serverHello.random)
+
+	hs.finishedHash.discardHandshakeBuffer()
+
 	return nil
 }
 
@@ -465,7 +484,7 @@
 	c := hs.c
 
 	clientMAC, serverMAC, clientKey, serverKey, clientIV, serverIV :=
-		keysFromMasterSecret(c.vers, hs.masterSecret, hs.hello.random, hs.serverHello.random, hs.suite.macLen, hs.suite.keyLen, hs.suite.ivLen)
+		keysFromMasterSecret(c.vers, hs.suite, hs.masterSecret, hs.hello.random, hs.serverHello.random, hs.suite.macLen, hs.suite.keyLen, hs.suite.ivLen)
 	var clientCipher, serverCipher interface{}
 	var clientHash, serverHash macFunction
 	if hs.suite.cipher != nil {
@@ -522,11 +541,13 @@
 		c.clientProtocol = hs.serverHello.alpnProtocol
 		c.clientProtocolFallback = false
 	}
+	c.scts = hs.serverHello.scts
 
 	if hs.serverResumedSession() {
 		// Restore masterSecret and peerCerts from previous state
 		hs.masterSecret = hs.session.masterSecret
 		c.peerCertificates = hs.session.serverCertificates
+		c.verifiedChains = hs.session.verifiedChains
 		return true, nil
 	}
 	return false, nil
@@ -584,6 +605,7 @@
 		cipherSuite:        hs.suite.id,
 		masterSecret:       hs.masterSecret,
 		serverCertificates: c.peerCertificates,
+		verifiedChains:     c.verifiedChains,
 	}
 
 	return nil
diff --git a/third_party/gofrontend/libgo/go/crypto/tls/handshake_client_test.go b/third_party/gofrontend/libgo/go/crypto/tls/handshake_client_test.go
index e5eaa7d..664fe8d 100644
--- a/third_party/gofrontend/libgo/go/crypto/tls/handshake_client_test.go
+++ b/third_party/gofrontend/libgo/go/crypto/tls/handshake_client_test.go
@@ -9,6 +9,8 @@
 	"crypto/ecdsa"
 	"crypto/rsa"
 	"crypto/x509"
+	"encoding/base64"
+	"encoding/binary"
 	"encoding/pem"
 	"fmt"
 	"io"
@@ -49,6 +51,10 @@
 	// key, if not nil, contains either a *rsa.PrivateKey or
 	// *ecdsa.PrivateKey which is the private key for the reference server.
 	key interface{}
+	// extensions, if not nil, contains a list of extension data to be returned
+	// from the ServerHello. The data should be in standard TLS format with
+	// a 2-byte uint16 type, 2-byte data length, followed by the extension data.
+	extensions [][]byte
 	// validate, if not nil, is a function that will be called with the
 	// ConnectionState of the resulting connection. It returns a non-nil
 	// error if the ConnectionState is unacceptable.
@@ -111,6 +117,19 @@
 	const serverPort = 24323
 	command = append(command, "-accept", strconv.Itoa(serverPort))
 
+	if len(test.extensions) > 0 {
+		var serverInfo bytes.Buffer
+		for _, ext := range test.extensions {
+			pem.Encode(&serverInfo, &pem.Block{
+				Type:  fmt.Sprintf("SERVERINFO FOR EXTENSION %d", binary.BigEndian.Uint16(ext)),
+				Bytes: ext,
+			})
+		}
+		serverInfoPath := tempFile(serverInfo.String())
+		defer os.Remove(serverInfoPath)
+		command = append(command, "-serverinfo", serverInfoPath)
+	}
+
 	cmd := exec.Command(command[0], command[1:]...)
 	stdin = blockingSource(make(chan bool))
 	cmd.Stdin = stdin
@@ -127,7 +146,6 @@
 	// connection.
 	var tcpConn net.Conn
 	for i := uint(0); i < 5; i++ {
-		var err error
 		tcpConn, err = net.DialTCP("tcp", nil, &net.TCPAddr{
 			IP:   net.IPv4(127, 0, 0, 1),
 			Port: serverPort,
@@ -137,7 +155,7 @@
 		}
 		time.Sleep((1 << i) * 5 * time.Millisecond)
 	}
-	if tcpConn == nil {
+	if err != nil {
 		close(stdin)
 		out.WriteTo(os.Stdout)
 		cmd.Process.Kill()
@@ -190,11 +208,11 @@
 	doneChan := make(chan bool)
 	go func() {
 		if _, err := client.Write([]byte("hello\n")); err != nil {
-			t.Logf("Client.Write failed: %s", err)
+			t.Errorf("Client.Write failed: %s", err)
 		}
 		if test.validate != nil {
 			if err := test.validate(client.ConnectionState()); err != nil {
-				t.Logf("validate callback returned error: %s", err)
+				t.Errorf("validate callback returned error: %s", err)
 			}
 		}
 		client.Close()
@@ -311,6 +329,16 @@
 	runClientTestTLS12(t, test)
 }
 
+func TestHandshakeClientAES256GCMSHA384(t *testing.T) {
+	test := &clientTest{
+		name:    "ECDHE-ECDSA-AES256-GCM-SHA384",
+		command: []string{"openssl", "s_server", "-cipher", "ECDHE-ECDSA-AES256-GCM-SHA384"},
+		cert:    testECDSACertificate,
+		key:     testECDSAPrivateKey,
+	}
+	runClientTestTLS12(t, test)
+}
+
 func TestHandshakeClientCertRSA(t *testing.T) {
 	config := *testConfig
 	cert, _ := X509KeyPair([]byte(clientCertificatePEM), []byte(clientKeyPEM))
@@ -335,6 +363,16 @@
 
 	runClientTestTLS10(t, test)
 	runClientTestTLS12(t, test)
+
+	test = &clientTest{
+		name:    "ClientCert-RSA-AES256-GCM-SHA384",
+		command: []string{"openssl", "s_server", "-cipher", "ECDHE-RSA-AES256-GCM-SHA384", "-verify", "1"},
+		config:  &config,
+		cert:    testRSACertificate,
+		key:     testRSAPrivateKey,
+	}
+
+	runClientTestTLS12(t, test)
 }
 
 func TestHandshakeClientCertECDSA(t *testing.T) {
@@ -368,31 +406,67 @@
 		CipherSuites: []uint16{TLS_RSA_WITH_RC4_128_SHA, TLS_ECDHE_RSA_WITH_RC4_128_SHA},
 		Certificates: testConfig.Certificates,
 	}
+
+	issuer, err := x509.ParseCertificate(testRSACertificateIssuer)
+	if err != nil {
+		panic(err)
+	}
+
+	rootCAs := x509.NewCertPool()
+	rootCAs.AddCert(issuer)
+
 	clientConfig := &Config{
 		CipherSuites:       []uint16{TLS_RSA_WITH_RC4_128_SHA},
-		InsecureSkipVerify: true,
 		ClientSessionCache: NewLRUClientSessionCache(32),
+		RootCAs:            rootCAs,
+		ServerName:         "example.golang",
 	}
 
 	testResumeState := func(test string, didResume bool) {
-		hs, err := testHandshake(clientConfig, serverConfig)
+		_, hs, err := testHandshake(clientConfig, serverConfig)
 		if err != nil {
 			t.Fatalf("%s: handshake failed: %s", test, err)
 		}
 		if hs.DidResume != didResume {
 			t.Fatalf("%s resumed: %v, expected: %v", test, hs.DidResume, didResume)
 		}
+		if didResume && (hs.PeerCertificates == nil || hs.VerifiedChains == nil) {
+			t.Fatalf("expected non-nil certificates after resumption. Got peerCertificates: %#v, verifedCertificates: %#v", hs.PeerCertificates, hs.VerifiedChains)
+		}
+	}
+
+	getTicket := func() []byte {
+		return clientConfig.ClientSessionCache.(*lruSessionCache).q.Front().Value.(*lruSessionCacheEntry).state.sessionTicket
+	}
+	randomKey := func() [32]byte {
+		var k [32]byte
+		if _, err := io.ReadFull(serverConfig.rand(), k[:]); err != nil {
+			t.Fatalf("Failed to read new SessionTicketKey: %s", err)
+		}
+		return k
 	}
 
 	testResumeState("Handshake", false)
+	ticket := getTicket()
 	testResumeState("Resume", true)
-
-	if _, err := io.ReadFull(serverConfig.rand(), serverConfig.SessionTicketKey[:]); err != nil {
-		t.Fatalf("Failed to invalidate SessionTicketKey")
+	if !bytes.Equal(ticket, getTicket()) {
+		t.Fatal("first ticket doesn't match ticket after resumption")
 	}
+
+	key2 := randomKey()
+	serverConfig.SetSessionTicketKeys([][32]byte{key2})
+
 	testResumeState("InvalidSessionTicketKey", false)
 	testResumeState("ResumeAfterInvalidSessionTicketKey", true)
 
+	serverConfig.SetSessionTicketKeys([][32]byte{randomKey(), key2})
+	ticket = getTicket()
+	testResumeState("KeyChange", true)
+	if bytes.Equal(ticket, getTicket()) {
+		t.Fatal("new ticket wasn't included while resuming")
+	}
+	testResumeState("KeyChangeFinish", true)
+
 	clientConfig.CipherSuites = []uint16{TLS_ECDHE_RSA_WITH_RC4_128_SHA}
 	testResumeState("DifferentCipherSuite", false)
 	testResumeState("DifferentCipherSuiteRecovers", true)
@@ -488,3 +562,41 @@
 	}
 	runClientTestTLS12(t, test)
 }
+
+// sctsBase64 contains data from `openssl s_client -serverinfo 18 -connect ritter.vg:443`
+const sctsBase64 = "ABIBaQFnAHUApLkJkLQYWBSHuxOizGdwCjw1mAT5G9+443fNDsgN3BAAAAFHl5nuFgAABAMARjBEAiAcS4JdlW5nW9sElUv2zvQyPoZ6ejKrGGB03gjaBZFMLwIgc1Qbbn+hsH0RvObzhS+XZhr3iuQQJY8S9G85D9KeGPAAdgBo9pj4H2SCvjqM7rkoHUz8cVFdZ5PURNEKZ6y7T0/7xAAAAUeX4bVwAAAEAwBHMEUCIDIhFDgG2HIuADBkGuLobU5a4dlCHoJLliWJ1SYT05z6AiEAjxIoZFFPRNWMGGIjskOTMwXzQ1Wh2e7NxXE1kd1J0QsAdgDuS723dc5guuFCaR+r4Z5mow9+X7By2IMAxHuJeqj9ywAAAUhcZIqHAAAEAwBHMEUCICmJ1rBT09LpkbzxtUC+Hi7nXLR0J+2PmwLp+sJMuqK+AiEAr0NkUnEVKVhAkccIFpYDqHOlZaBsuEhWWrYpg2RtKp0="
+
+func TestHandshakClientSCTs(t *testing.T) {
+	config := *testConfig
+
+	scts, err := base64.StdEncoding.DecodeString(sctsBase64)
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	test := &clientTest{
+		name: "SCT",
+		// Note that this needs OpenSSL 1.0.2 because that is the first
+		// version that supports the -serverinfo flag.
+		command:    []string{"openssl", "s_server"},
+		config:     &config,
+		extensions: [][]byte{scts},
+		validate: func(state ConnectionState) error {
+			expectedSCTs := [][]byte{
+				scts[8:125],
+				scts[127:245],
+				scts[247:],
+			}
+			if n := len(state.SignedCertificateTimestamps); n != len(expectedSCTs) {
+				return fmt.Errorf("Got %d scts, wanted %d", n, len(expectedSCTs))
+			}
+			for i, expected := range expectedSCTs {
+				if sct := state.SignedCertificateTimestamps[i]; !bytes.Equal(sct, expected) {
+					return fmt.Errorf("SCT #%d contained %x, expected %x", i, sct, expected)
+				}
+			}
+			return nil
+		},
+	}
+	runClientTestTLS12(t, test)
+}
diff --git a/third_party/gofrontend/libgo/go/crypto/tls/handshake_messages.go b/third_party/gofrontend/libgo/go/crypto/tls/handshake_messages.go
index 5d14871..799a776 100644
--- a/third_party/gofrontend/libgo/go/crypto/tls/handshake_messages.go
+++ b/third_party/gofrontend/libgo/go/crypto/tls/handshake_messages.go
@@ -16,6 +16,7 @@
 	nextProtoNeg        bool
 	serverName          string
 	ocspStapling        bool
+	scts                bool
 	supportedCurves     []CurveID
 	supportedPoints     []uint8
 	ticketSupported     bool
@@ -40,6 +41,7 @@
 		m.nextProtoNeg == m1.nextProtoNeg &&
 		m.serverName == m1.serverName &&
 		m.ocspStapling == m1.ocspStapling &&
+		m.scts == m1.scts &&
 		eqCurveIDs(m.supportedCurves, m1.supportedCurves) &&
 		bytes.Equal(m.supportedPoints, m1.supportedPoints) &&
 		m.ticketSupported == m1.ticketSupported &&
@@ -99,6 +101,9 @@
 		}
 		numExtensions++
 	}
+	if m.scts {
+		numExtensions++
+	}
 	if numExtensions > 0 {
 		extensionsLength += 4 * numExtensions
 		length += 2 + extensionsLength
@@ -271,6 +276,13 @@
 		lengths[0] = byte(stringsLength >> 8)
 		lengths[1] = byte(stringsLength)
 	}
+	if m.scts {
+		// https://tools.ietf.org/html/rfc6962#section-3.3.1
+		z[0] = byte(extensionSCT >> 8)
+		z[1] = byte(extensionSCT)
+		// zero uint16 for the zero-length extension_data
+		z = z[4:]
+	}
 
 	m.raw = x
 
@@ -326,6 +338,7 @@
 	m.sessionTicket = nil
 	m.signatureAndHashes = nil
 	m.alpnProtocols = nil
+	m.scts = false
 
 	if len(data) == 0 {
 		// ClientHello is optionally followed by extension data
@@ -354,12 +367,16 @@
 
 		switch extension {
 		case extensionServerName:
-			if length < 2 {
+			d := data[:length]
+			if len(d) < 2 {
 				return false
 			}
-			numNames := int(data[0])<<8 | int(data[1])
-			d := data[2:]
-			for i := 0; i < numNames; i++ {
+			namesLen := int(d[0])<<8 | int(d[1])
+			d = d[2:]
+			if len(d) != namesLen {
+				return false
+			}
+			for len(d) > 0 {
 				if len(d) < 3 {
 					return false
 				}
@@ -370,7 +387,7 @@
 					return false
 				}
 				if nameType == 0 {
-					m.serverName = string(d[0:nameLen])
+					m.serverName = string(d[:nameLen])
 					break
 				}
 				d = d[nameLen:]
@@ -430,7 +447,7 @@
 				m.signatureAndHashes[i].signature = d[1]
 				d = d[2:]
 			}
-		case extensionRenegotiationInfo + 1:
+		case extensionRenegotiationInfo:
 			if length != 1 || data[0] != 0 {
 				return false
 			}
@@ -453,6 +470,11 @@
 				m.alpnProtocols = append(m.alpnProtocols, string(d[:stringLen]))
 				d = d[stringLen:]
 			}
+		case extensionSCT:
+			m.scts = true
+			if length != 0 {
+				return false
+			}
 		}
 		data = data[length:]
 	}
@@ -470,6 +492,7 @@
 	nextProtoNeg        bool
 	nextProtos          []string
 	ocspStapling        bool
+	scts                [][]byte
 	ticketSupported     bool
 	secureRenegotiation bool
 	alpnProtocol        string
@@ -481,6 +504,15 @@
 		return false
 	}
 
+	if len(m.scts) != len(m1.scts) {
+		return false
+	}
+	for i, sct := range m.scts {
+		if !bytes.Equal(sct, m1.scts[i]) {
+			return false
+		}
+	}
+
 	return bytes.Equal(m.raw, m1.raw) &&
 		m.vers == m1.vers &&
 		bytes.Equal(m.random, m1.random) &&
@@ -530,6 +562,14 @@
 		extensionsLength += 2 + 1 + alpnLen
 		numExtensions++
 	}
+	sctLen := 0
+	if len(m.scts) > 0 {
+		for _, sct := range m.scts {
+			sctLen += len(sct) + 2
+		}
+		extensionsLength += 2 + sctLen
+		numExtensions++
+	}
 
 	if numExtensions > 0 {
 		extensionsLength += 4 * numExtensions
@@ -605,6 +645,23 @@
 		copy(z[7:], []byte(m.alpnProtocol))
 		z = z[7+alpnLen:]
 	}
+	if sctLen > 0 {
+		z[0] = byte(extensionSCT >> 8)
+		z[1] = byte(extensionSCT)
+		l := sctLen + 2
+		z[2] = byte(l >> 8)
+		z[3] = byte(l)
+		z[4] = byte(sctLen >> 8)
+		z[5] = byte(sctLen)
+
+		z = z[6:]
+		for _, sct := range m.scts {
+			z[0] = byte(len(sct) >> 8)
+			z[1] = byte(len(sct))
+			copy(z[2:], sct)
+			z = z[len(sct)+2:]
+		}
+	}
 
 	m.raw = x
 
@@ -634,6 +691,7 @@
 	m.nextProtoNeg = false
 	m.nextProtos = nil
 	m.ocspStapling = false
+	m.scts = nil
 	m.ticketSupported = false
 	m.alpnProtocol = ""
 
@@ -706,6 +764,34 @@
 			}
 			d = d[1:]
 			m.alpnProtocol = string(d)
+		case extensionSCT:
+			d := data[:length]
+
+			if len(d) < 2 {
+				return false
+			}
+			l := int(d[0])<<8 | int(d[1])
+			d = d[2:]
+			if len(d) != l {
+				return false
+			}
+			if l == 0 {
+				continue
+			}
+
+			m.scts = make([][]byte, 0, 3)
+			for len(d) != 0 {
+				if len(d) < 2 {
+					return false
+				}
+				sctLen := int(d[0])<<8 | int(d[1])
+				d = d[2:]
+				if len(d) < sctLen {
+					return false
+				}
+				m.scts = append(m.scts, d[:sctLen])
+				d = d[sctLen:]
+			}
 		}
 		data = data[length:]
 	}
diff --git a/third_party/gofrontend/libgo/go/crypto/tls/handshake_messages_test.go b/third_party/gofrontend/libgo/go/crypto/tls/handshake_messages_test.go
index a96e95c..95d825b 100644
--- a/third_party/gofrontend/libgo/go/crypto/tls/handshake_messages_test.go
+++ b/third_party/gofrontend/libgo/go/crypto/tls/handshake_messages_test.go
@@ -136,12 +136,15 @@
 		}
 	}
 	if rand.Intn(10) > 5 {
-		m.signatureAndHashes = supportedSKXSignatureAlgorithms
+		m.signatureAndHashes = supportedSignatureAlgorithms
 	}
 	m.alpnProtocols = make([]string, rand.Intn(5))
 	for i := range m.alpnProtocols {
 		m.alpnProtocols[i] = randomString(rand.Intn(20)+1, rand)
 	}
+	if rand.Intn(10) > 5 {
+		m.scts = true
+	}
 
 	return reflect.ValueOf(m)
 }
@@ -172,6 +175,14 @@
 	}
 	m.alpnProtocol = randomString(rand.Intn(32)+1, rand)
 
+	if rand.Intn(10) > 5 {
+		numSCTs := rand.Intn(4)
+		m.scts = make([][]byte, numSCTs)
+		for i := range m.scts {
+			m.scts[i] = randomBytes(rand.Intn(500), rand)
+		}
+	}
+
 	return reflect.ValueOf(m)
 }
 
diff --git a/third_party/gofrontend/libgo/go/crypto/tls/handshake_server.go b/third_party/gofrontend/libgo/go/crypto/tls/handshake_server.go
index 0d90765..e16cddc 100644
--- a/third_party/gofrontend/libgo/go/crypto/tls/handshake_server.go
+++ b/third_party/gofrontend/libgo/go/crypto/tls/handshake_server.go
@@ -25,6 +25,8 @@
 	suite           *cipherSuite
 	ellipticOk      bool
 	ecdsaOk         bool
+	rsaDecryptOk    bool
+	rsaSignOk       bool
 	sessionState    *sessionState
 	finishedHash    finishedHash
 	masterSecret    []byte
@@ -57,6 +59,14 @@
 		if err := hs.establishKeys(); err != nil {
 			return err
 		}
+		// ticketSupported is set in a resumption handshake if the
+		// ticket from the client was encrypted with an old session
+		// ticket key and thus a refreshed ticket should be sent.
+		if hs.hello.ticketSupported {
+			if err := hs.sendSessionTicket(); err != nil {
+				return err
+			}
+		}
 		if err := hs.sendFinished(c.firstFinished[:]); err != nil {
 			return err
 		}
@@ -111,9 +121,6 @@
 	}
 	c.haveVers = true
 
-	hs.finishedHash = newFinishedHash(c.vers)
-	hs.finishedHash.Write(hs.clientHello.marshal())
-
 	hs.hello = new(serverHelloMsg)
 
 	supportedCurve := false
@@ -173,32 +180,46 @@
 		// Although sending an empty NPN extension is reasonable, Firefox has
 		// had a bug around this. Best to send nothing at all if
 		// config.NextProtos is empty. See
-		// https://code.google.com/p/go/issues/detail?id=5445.
+		// https://golang.org/issue/5445.
 		if hs.clientHello.nextProtoNeg && len(config.NextProtos) > 0 {
 			hs.hello.nextProtoNeg = true
 			hs.hello.nextProtos = config.NextProtos
 		}
 	}
 
-	if len(config.Certificates) == 0 {
+	if hs.cert, err = config.getCertificate(&ClientHelloInfo{
+		CipherSuites:    hs.clientHello.cipherSuites,
+		ServerName:      hs.clientHello.serverName,
+		SupportedCurves: hs.clientHello.supportedCurves,
+		SupportedPoints: hs.clientHello.supportedPoints,
+	}); err != nil {
 		c.sendAlert(alertInternalError)
-		return false, errors.New("tls: no certificates configured")
+		return false, err
 	}
-	hs.cert = &config.Certificates[0]
-	if len(hs.clientHello.serverName) > 0 {
-		chi := &ClientHelloInfo{
-			CipherSuites:    hs.clientHello.cipherSuites,
-			ServerName:      hs.clientHello.serverName,
-			SupportedCurves: hs.clientHello.supportedCurves,
-			SupportedPoints: hs.clientHello.supportedPoints,
-		}
-		if hs.cert, err = config.getCertificate(chi); err != nil {
-			c.sendAlert(alertInternalError)
-			return false, err
-		}
+	if hs.clientHello.scts {
+		hs.hello.scts = hs.cert.SignedCertificateTimestamps
 	}
 
-	_, hs.ecdsaOk = hs.cert.PrivateKey.(*ecdsa.PrivateKey)
+	if priv, ok := hs.cert.PrivateKey.(crypto.Signer); ok {
+		switch priv.Public().(type) {
+		case *ecdsa.PublicKey:
+			hs.ecdsaOk = true
+		case *rsa.PublicKey:
+			hs.rsaSignOk = true
+		default:
+			c.sendAlert(alertInternalError)
+			return false, fmt.Errorf("crypto/tls: unsupported signing key type (%T)", priv.Public())
+		}
+	}
+	if priv, ok := hs.cert.PrivateKey.(crypto.Decrypter); ok {
+		switch priv.Public().(type) {
+		case *rsa.PublicKey:
+			hs.rsaDecryptOk = true
+		default:
+			c.sendAlert(alertInternalError)
+			return false, fmt.Errorf("crypto/tls: unsupported decryption key type (%T)", priv.Public())
+		}
+	}
 
 	if hs.checkForResumption() {
 		return true, nil
@@ -214,7 +235,7 @@
 	}
 
 	for _, id := range preferenceList {
-		if hs.suite = c.tryCipherSuite(id, supportedList, c.vers, hs.ellipticOk, hs.ecdsaOk); hs.suite != nil {
+		if hs.setCipherSuite(id, supportedList, c.vers) {
 			break
 		}
 	}
@@ -228,9 +249,9 @@
 	for _, id := range hs.clientHello.cipherSuites {
 		if id == TLS_FALLBACK_SCSV {
 			// The client is doing a fallback connection.
-			if hs.clientHello.vers < c.config.MaxVersion {
+			if hs.clientHello.vers < c.config.maxVersion() {
 				c.sendAlert(alertInappropriateFallback)
-				return false, errors.New("tls: client using inppropriate protocol fallback")
+				return false, errors.New("tls: client using inappropriate protocol fallback")
 			}
 			break
 		}
@@ -239,7 +260,7 @@
 	return false, nil
 }
 
-// checkForResumption returns true if we should perform resumption on this connection.
+// checkForResumption reports whether we should perform resumption on this connection.
 func (hs *serverHandshakeState) checkForResumption() bool {
 	c := hs.c
 
@@ -248,7 +269,8 @@
 	}
 
 	var ok bool
-	if hs.sessionState, ok = c.decryptTicket(hs.clientHello.sessionTicket); !ok {
+	var sessionTicket = append([]uint8{}, hs.clientHello.sessionTicket...)
+	if hs.sessionState, ok = c.decryptTicket(sessionTicket); !ok {
 		return false
 	}
 
@@ -272,8 +294,7 @@
 	}
 
 	// Check that we also support the ciphersuite from the session.
-	hs.suite = c.tryCipherSuite(hs.sessionState.cipherSuite, c.config.cipherSuites(), hs.sessionState.vers, hs.ellipticOk, hs.ecdsaOk)
-	if hs.suite == nil {
+	if !hs.setCipherSuite(hs.sessionState.cipherSuite, c.config.cipherSuites(), hs.sessionState.vers) {
 		return false
 	}
 
@@ -296,6 +317,10 @@
 	// We echo the client's session ID in the ServerHello to let it know
 	// that we're doing a resumption.
 	hs.hello.sessionId = hs.clientHello.sessionId
+	hs.hello.ticketSupported = hs.sessionState.usedOldKey
+	hs.finishedHash = newFinishedHash(c.vers, hs.suite)
+	hs.finishedHash.discardHandshakeBuffer()
+	hs.finishedHash.Write(hs.clientHello.marshal())
 	hs.finishedHash.Write(hs.hello.marshal())
 	c.writeRecord(recordTypeHandshake, hs.hello.marshal())
 
@@ -320,6 +345,14 @@
 
 	hs.hello.ticketSupported = hs.clientHello.ticketSupported && !config.SessionTicketsDisabled
 	hs.hello.cipherSuite = hs.suite.id
+
+	hs.finishedHash = newFinishedHash(hs.c.vers, hs.suite)
+	if config.ClientAuth == NoClientCert {
+		// No need to keep a full record of the handshake if client
+		// certificates won't be used.
+		hs.finishedHash.discardHandshakeBuffer()
+	}
+	hs.finishedHash.Write(hs.clientHello.marshal())
 	hs.finishedHash.Write(hs.hello.marshal())
 	c.writeRecord(recordTypeHandshake, hs.hello.marshal())
 
@@ -356,7 +389,7 @@
 		}
 		if c.vers >= VersionTLS12 {
 			certReq.hasSignatureAndHash = true
-			certReq.signatureAndHashes = supportedClientCertSignatureAlgorithms
+			certReq.signatureAndHashes = supportedSignatureAlgorithms
 		}
 
 		// An empty list of certificateAuthorities signals to
@@ -420,6 +453,13 @@
 	}
 	hs.finishedHash.Write(ckx.marshal())
 
+	preMasterSecret, err := keyAgreement.processClientKeyExchange(config, hs.cert, ckx, c.vers)
+	if err != nil {
+		c.sendAlert(alertHandshakeFailure)
+		return err
+	}
+	hs.masterSecret = masterFromPreMasterSecret(c.vers, hs.suite, preMasterSecret, hs.clientHello.random, hs.hello.random)
+
 	// If we received a client cert in response to our certificate request message,
 	// the client will send us a certificateVerifyMsg immediately after the
 	// clientKeyExchangeMsg.  This message is a digest of all preceding
@@ -437,8 +477,31 @@
 			return unexpectedMessageError(certVerify, msg)
 		}
 
+		// Determine the signature type.
+		var signatureAndHash signatureAndHash
+		if certVerify.hasSignatureAndHash {
+			signatureAndHash = certVerify.signatureAndHash
+			if !isSupportedSignatureAndHash(signatureAndHash, supportedSignatureAlgorithms) {
+				return errors.New("tls: unsupported hash function for client certificate")
+			}
+		} else {
+			// Before TLS 1.2 the signature algorithm was implicit
+			// from the key type, and only one hash per signature
+			// algorithm was possible. Leave the hash as zero.
+			switch pub.(type) {
+			case *ecdsa.PublicKey:
+				signatureAndHash.signature = signatureECDSA
+			case *rsa.PublicKey:
+				signatureAndHash.signature = signatureRSA
+			}
+		}
+
 		switch key := pub.(type) {
 		case *ecdsa.PublicKey:
+			if signatureAndHash.signature != signatureECDSA {
+				err = errors.New("bad signature type for client's ECDSA certificate")
+				break
+			}
 			ecdsaSig := new(ecdsaSignature)
 			if _, err = asn1.Unmarshal(certVerify.signature, ecdsaSig); err != nil {
 				break
@@ -447,29 +510,34 @@
 				err = errors.New("ECDSA signature contained zero or negative values")
 				break
 			}
-			digest, _, _ := hs.finishedHash.hashForClientCertificate(signatureECDSA)
-			if !ecdsa.Verify(key, digest, ecdsaSig.R, ecdsaSig.S) {
-				err = errors.New("ECDSA verification failure")
+			var digest []byte
+			if digest, _, err = hs.finishedHash.hashForClientCertificate(signatureAndHash, hs.masterSecret); err != nil {
 				break
 			}
+			if !ecdsa.Verify(key, digest, ecdsaSig.R, ecdsaSig.S) {
+				err = errors.New("ECDSA verification failure")
+			}
 		case *rsa.PublicKey:
-			digest, hashFunc, _ := hs.finishedHash.hashForClientCertificate(signatureRSA)
+			if signatureAndHash.signature != signatureRSA {
+				err = errors.New("bad signature type for client's RSA certificate")
+				break
+			}
+			var digest []byte
+			var hashFunc crypto.Hash
+			if digest, hashFunc, err = hs.finishedHash.hashForClientCertificate(signatureAndHash, hs.masterSecret); err != nil {
+				break
+			}
 			err = rsa.VerifyPKCS1v15(key, hashFunc, digest, certVerify.signature)
 		}
 		if err != nil {
 			c.sendAlert(alertBadCertificate)
-			return errors.New("could not validate signature of connection nonces: " + err.Error())
+			return errors.New("tls: could not validate signature of connection nonces: " + err.Error())
 		}
 
 		hs.finishedHash.Write(certVerify.marshal())
 	}
 
-	preMasterSecret, err := keyAgreement.processClientKeyExchange(config, hs.cert, ckx, c.vers)
-	if err != nil {
-		c.sendAlert(alertHandshakeFailure)
-		return err
-	}
-	hs.masterSecret = masterFromPreMasterSecret(c.vers, preMasterSecret, hs.clientHello.random, hs.hello.random)
+	hs.finishedHash.discardHandshakeBuffer()
 
 	return nil
 }
@@ -478,7 +546,7 @@
 	c := hs.c
 
 	clientMAC, serverMAC, clientKey, serverKey, clientIV, serverIV :=
-		keysFromMasterSecret(c.vers, hs.masterSecret, hs.clientHello.random, hs.hello.random, hs.suite.macLen, hs.suite.keyLen, hs.suite.ivLen)
+		keysFromMasterSecret(c.vers, hs.suite, hs.masterSecret, hs.clientHello.random, hs.hello.random, hs.suite.macLen, hs.suite.keyLen, hs.suite.ivLen)
 
 	var clientCipher, serverCipher interface{}
 	var clientHash, serverHash macFunction
@@ -619,18 +687,6 @@
 			return nil, errors.New("tls: failed to verify client's certificate: " + err.Error())
 		}
 
-		ok := false
-		for _, ku := range certs[0].ExtKeyUsage {
-			if ku == x509.ExtKeyUsageClientAuth {
-				ok = true
-				break
-			}
-		}
-		if !ok {
-			c.sendAlert(alertHandshakeFailure)
-			return nil, errors.New("tls: client's certificate's extended key usage doesn't permit it to be used for client authentication")
-		}
-
 		c.verifiedChains = chains
 	}
 
@@ -650,9 +706,10 @@
 	return nil, nil
 }
 
-// tryCipherSuite returns a cipherSuite with the given id if that cipher suite
-// is acceptable to use.
-func (c *Conn) tryCipherSuite(id uint16, supportedCipherSuites []uint16, version uint16, ellipticOk, ecdsaOk bool) *cipherSuite {
+// setCipherSuite sets a cipherSuite with the given id as the serverHandshakeState
+// suite if that cipher suite is acceptable to use.
+// It returns a bool indicating if the suite was set.
+func (hs *serverHandshakeState) setCipherSuite(id uint16, supportedCipherSuites []uint16, version uint16) bool {
 	for _, supported := range supportedCipherSuites {
 		if id == supported {
 			var candidate *cipherSuite
@@ -668,18 +725,26 @@
 			}
 			// Don't select a ciphersuite which we can't
 			// support for this client.
-			if (candidate.flags&suiteECDHE != 0) && !ellipticOk {
-				continue
-			}
-			if (candidate.flags&suiteECDSA != 0) != ecdsaOk {
+			if candidate.flags&suiteECDHE != 0 {
+				if !hs.ellipticOk {
+					continue
+				}
+				if candidate.flags&suiteECDSA != 0 {
+					if !hs.ecdsaOk {
+						continue
+					}
+				} else if !hs.rsaSignOk {
+					continue
+				}
+			} else if !hs.rsaDecryptOk {
 				continue
 			}
 			if version < VersionTLS12 && candidate.flags&suiteTLS12 != 0 {
 				continue
 			}
-			return candidate
+			hs.suite = candidate
+			return true
 		}
 	}
-
-	return nil
+	return false
 }
diff --git a/third_party/gofrontend/libgo/go/crypto/tls/handshake_server_test.go b/third_party/gofrontend/libgo/go/crypto/tls/handshake_server_test.go
index 0338af4..20c2bd6 100644
--- a/third_party/gofrontend/libgo/go/crypto/tls/handshake_server_test.go
+++ b/third_party/gofrontend/libgo/go/crypto/tls/handshake_server_test.go
@@ -37,6 +37,15 @@
 
 var testConfig *Config
 
+func allCipherSuites() []uint16 {
+	ids := make([]uint16, len(cipherSuites))
+	for i, suite := range cipherSuites {
+		ids[i] = suite.id
+	}
+
+	return ids
+}
+
 func init() {
 	testConfig = &Config{
 		Time:               func() time.Time { return time.Unix(0, 0) },
@@ -45,6 +54,7 @@
 		InsecureSkipVerify: true,
 		MinVersion:         VersionSSL30,
 		MaxVersion:         VersionTLS12,
+		CipherSuites:       allCipherSuites(),
 	}
 	testConfig.Certificates[0].Certificate = [][]byte{testRSACertificate}
 	testConfig.Certificates[0].PrivateKey = testRSAPrivateKey
@@ -53,7 +63,11 @@
 	testConfig.BuildNameToCertificate()
 }
 
-func testClientHelloFailure(t *testing.T, m handshakeMessage, expectedSubStr string) {
+func testClientHello(t *testing.T, serverConfig *Config, m handshakeMessage) {
+	testClientHelloFailure(t, serverConfig, m, "")
+}
+
+func testClientHelloFailure(t *testing.T, serverConfig *Config, m handshakeMessage, expectedSubStr string) {
 	// Create in-memory network connection,
 	// send message to server.  Should return
 	// expected error.
@@ -66,22 +80,26 @@
 		cli.writeRecord(recordTypeHandshake, m.marshal())
 		c.Close()
 	}()
-	err := Server(s, testConfig).Handshake()
+	err := Server(s, serverConfig).Handshake()
 	s.Close()
-	if err == nil || !strings.Contains(err.Error(), expectedSubStr) {
+	if len(expectedSubStr) == 0 {
+		if err != nil && err != io.EOF {
+			t.Errorf("Got error: %s; expected to succeed", err, expectedSubStr)
+		}
+	} else if err == nil || !strings.Contains(err.Error(), expectedSubStr) {
 		t.Errorf("Got error: %s; expected to match substring '%s'", err, expectedSubStr)
 	}
 }
 
 func TestSimpleError(t *testing.T) {
-	testClientHelloFailure(t, &serverHelloDoneMsg{}, "unexpected handshake message")
+	testClientHelloFailure(t, testConfig, &serverHelloDoneMsg{}, "unexpected handshake message")
 }
 
 var badProtocolVersions = []uint16{0x0000, 0x0005, 0x0100, 0x0105, 0x0200, 0x0205}
 
 func TestRejectBadProtocolVersion(t *testing.T) {
 	for _, v := range badProtocolVersions {
-		testClientHelloFailure(t, &clientHelloMsg{vers: v}, "unsupported, maximum protocol version")
+		testClientHelloFailure(t, testConfig, &clientHelloMsg{vers: v}, "unsupported, maximum protocol version")
 	}
 }
 
@@ -91,7 +109,7 @@
 		cipherSuites:       []uint16{0xff00},
 		compressionMethods: []uint8{0},
 	}
-	testClientHelloFailure(t, clientHello, "no cipher suite supported by both client and server")
+	testClientHelloFailure(t, testConfig, clientHello, "no cipher suite supported by both client and server")
 }
 
 func TestNoCompressionOverlap(t *testing.T) {
@@ -100,7 +118,117 @@
 		cipherSuites:       []uint16{TLS_RSA_WITH_RC4_128_SHA},
 		compressionMethods: []uint8{0xff},
 	}
-	testClientHelloFailure(t, clientHello, "client does not support uncompressed connections")
+	testClientHelloFailure(t, testConfig, clientHello, "client does not support uncompressed connections")
+}
+
+func TestNoRC4ByDefault(t *testing.T) {
+	clientHello := &clientHelloMsg{
+		vers:               0x0301,
+		cipherSuites:       []uint16{TLS_RSA_WITH_RC4_128_SHA},
+		compressionMethods: []uint8{0},
+	}
+	serverConfig := *testConfig
+	// Reset the enabled cipher suites to nil in order to test the
+	// defaults.
+	serverConfig.CipherSuites = nil
+	testClientHelloFailure(t, &serverConfig, clientHello, "no cipher suite supported by both client and server")
+}
+
+func TestDontSelectECDSAWithRSAKey(t *testing.T) {
+	// Test that, even when both sides support an ECDSA cipher suite, it
+	// won't be selected if the server's private key doesn't support it.
+	clientHello := &clientHelloMsg{
+		vers:               0x0301,
+		cipherSuites:       []uint16{TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA},
+		compressionMethods: []uint8{0},
+		supportedCurves:    []CurveID{CurveP256},
+		supportedPoints:    []uint8{pointFormatUncompressed},
+	}
+	serverConfig := *testConfig
+	serverConfig.CipherSuites = clientHello.cipherSuites
+	serverConfig.Certificates = make([]Certificate, 1)
+	serverConfig.Certificates[0].Certificate = [][]byte{testECDSACertificate}
+	serverConfig.Certificates[0].PrivateKey = testECDSAPrivateKey
+	serverConfig.BuildNameToCertificate()
+	// First test that it *does* work when the server's key is ECDSA.
+	testClientHello(t, &serverConfig, clientHello)
+
+	// Now test that switching to an RSA key causes the expected error (and
+	// not an internal error about a signing failure).
+	serverConfig.Certificates = testConfig.Certificates
+	testClientHelloFailure(t, &serverConfig, clientHello, "no cipher suite supported by both client and server")
+}
+
+func TestDontSelectRSAWithECDSAKey(t *testing.T) {
+	// Test that, even when both sides support an RSA cipher suite, it
+	// won't be selected if the server's private key doesn't support it.
+	clientHello := &clientHelloMsg{
+		vers:               0x0301,
+		cipherSuites:       []uint16{TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA},
+		compressionMethods: []uint8{0},
+		supportedCurves:    []CurveID{CurveP256},
+		supportedPoints:    []uint8{pointFormatUncompressed},
+	}
+	serverConfig := *testConfig
+	serverConfig.CipherSuites = clientHello.cipherSuites
+	// First test that it *does* work when the server's key is RSA.
+	testClientHello(t, &serverConfig, clientHello)
+
+	// Now test that switching to an ECDSA key causes the expected error
+	// (and not an internal error about a signing failure).
+	serverConfig.Certificates = make([]Certificate, 1)
+	serverConfig.Certificates[0].Certificate = [][]byte{testECDSACertificate}
+	serverConfig.Certificates[0].PrivateKey = testECDSAPrivateKey
+	serverConfig.BuildNameToCertificate()
+	testClientHelloFailure(t, &serverConfig, clientHello, "no cipher suite supported by both client and server")
+}
+
+func TestRenegotiationExtension(t *testing.T) {
+	clientHello := &clientHelloMsg{
+		vers:                VersionTLS12,
+		compressionMethods:  []uint8{compressionNone},
+		random:              make([]byte, 32),
+		secureRenegotiation: true,
+		cipherSuites:        []uint16{TLS_RSA_WITH_RC4_128_SHA},
+	}
+
+	var buf []byte
+	c, s := net.Pipe()
+
+	go func() {
+		cli := Client(c, testConfig)
+		cli.vers = clientHello.vers
+		cli.writeRecord(recordTypeHandshake, clientHello.marshal())
+
+		buf = make([]byte, 1024)
+		n, err := c.Read(buf)
+		if err != nil {
+			t.Fatalf("Server read returned error: %s", err)
+		}
+		buf = buf[:n]
+		c.Close()
+	}()
+
+	Server(s, testConfig).Handshake()
+
+	if len(buf) < 5+4 {
+		t.Fatalf("Server returned short message of length %d", len(buf))
+	}
+	// buf contains a TLS record, with a 5 byte record header and a 4 byte
+	// handshake header. The length of the ServerHello is taken from the
+	// handshake header.
+	serverHelloLen := int(buf[6])<<16 | int(buf[7])<<8 | int(buf[8])
+
+	var serverHello serverHelloMsg
+	// unmarshal expects to be given the handshake header, but
+	// serverHelloLen doesn't include it.
+	if !serverHello.unmarshal(buf[5 : 9+serverHelloLen]) {
+		t.Fatalf("Failed to parse ServerHello")
+	}
+
+	if !serverHello.secureRenegotiation {
+		t.Errorf("Secure renegotiation extension was not echoed.")
+	}
 }
 
 func TestTLS12OnlyCipherSuites(t *testing.T) {
@@ -175,19 +303,20 @@
 	}
 }
 
-func testHandshake(clientConfig, serverConfig *Config) (state ConnectionState, err error) {
+func testHandshake(clientConfig, serverConfig *Config) (serverState, clientState ConnectionState, err error) {
 	c, s := net.Pipe()
 	done := make(chan bool)
 	go func() {
 		cli := Client(c, clientConfig)
 		cli.Handshake()
+		clientState = cli.ConnectionState()
 		c.Close()
 		done <- true
 	}()
 	server := Server(s, serverConfig)
 	err = server.Handshake()
 	if err == nil {
-		state = server.ConnectionState()
+		serverState = server.ConnectionState()
 	}
 	s.Close()
 	<-done
@@ -202,7 +331,7 @@
 	clientConfig := &Config{
 		InsecureSkipVerify: true,
 	}
-	state, err := testHandshake(clientConfig, serverConfig)
+	state, _, err := testHandshake(clientConfig, serverConfig)
 	if err != nil {
 		t.Fatalf("handshake failed: %s", err)
 	}
@@ -221,7 +350,7 @@
 		CipherSuites:       []uint16{TLS_RSA_WITH_AES_128_CBC_SHA, TLS_RSA_WITH_RC4_128_SHA},
 		InsecureSkipVerify: true,
 	}
-	state, err := testHandshake(clientConfig, serverConfig)
+	state, _, err := testHandshake(clientConfig, serverConfig)
 	if err != nil {
 		t.Fatalf("handshake failed: %s", err)
 	}
@@ -231,7 +360,7 @@
 	}
 
 	serverConfig.PreferServerCipherSuites = true
-	state, err = testHandshake(clientConfig, serverConfig)
+	state, _, err = testHandshake(clientConfig, serverConfig)
 	if err != nil {
 		t.Fatalf("handshake failed: %s", err)
 	}
@@ -240,6 +369,33 @@
 	}
 }
 
+func TestSCTHandshake(t *testing.T) {
+	expected := [][]byte{[]byte("certificate"), []byte("transparency")}
+	serverConfig := &Config{
+		Certificates: []Certificate{{
+			Certificate:                 [][]byte{testRSACertificate},
+			PrivateKey:                  testRSAPrivateKey,
+			SignedCertificateTimestamps: expected,
+		}},
+	}
+	clientConfig := &Config{
+		InsecureSkipVerify: true,
+	}
+	_, state, err := testHandshake(clientConfig, serverConfig)
+	if err != nil {
+		t.Fatalf("handshake failed: %s", err)
+	}
+	actual := state.SignedCertificateTimestamps
+	if len(actual) != len(expected) {
+		t.Fatalf("got %d scts, want %d", len(actual), len(expected))
+	}
+	for i, sct := range expected {
+		if !bytes.Equal(sct, actual[i]) {
+			t.Fatalf("SCT #%d was %x, but expected %x", i, actual[i], sct)
+		}
+	}
+}
+
 // Note: see comment in handshake_test.go for details of how the reference
 // tests work.
 
@@ -257,9 +413,6 @@
 	expectedPeerCerts []string
 	// config, if not nil, contains a custom Config to use for this test.
 	config *Config
-	// expectAlert, if true, indicates that a fatal alert should be returned
-	// when handshaking with the server.
-	expectAlert bool
 	// expectHandshakeErrorIncluding, when not empty, contains a string
 	// that must be a substring of the error resulting from the handshake.
 	expectHandshakeErrorIncluding string
@@ -384,9 +537,7 @@
 	if !write {
 		flows, err := test.loadData()
 		if err != nil {
-			if !test.expectAlert {
-				t.Fatalf("%s: failed to load data from %s", test.name, test.dataPath())
-			}
+			t.Fatalf("%s: failed to load data from %s", test.name, test.dataPath())
 		}
 		for i, b := range flows {
 			if i%2 == 0 {
@@ -395,17 +546,11 @@
 			}
 			bb := make([]byte, len(b))
 			n, err := io.ReadFull(clientConn, bb)
-			if test.expectAlert {
-				if err == nil {
-					t.Fatal("Expected read failure but read succeeded")
-				}
-			} else {
-				if err != nil {
-					t.Fatalf("%s #%d: %s\nRead %d, wanted %d, got %x, wanted %x\n", test.name, i+1, err, n, len(bb), bb[:n], b)
-				}
-				if !bytes.Equal(b, bb) {
-					t.Fatalf("%s #%d: mismatch on read: got:%x want:%x", test.name, i+1, bb, b)
-				}
+			if err != nil {
+				t.Fatalf("%s #%d: %s\nRead %d, wanted %d, got %x, wanted %x\n", test.name, i+1, err, n, len(bb), bb[:n], b)
+			}
+			if !bytes.Equal(b, bb) {
+				t.Fatalf("%s #%d: mismatch on read: got:%x want:%x", test.name, i+1, bb, b)
 			}
 		}
 		clientConn.Close()
@@ -516,6 +661,14 @@
 	runServerTestTLS12(t, test)
 }
 
+func TestHandshakeServerAES256GCMSHA384(t *testing.T) {
+	test := &serverTest{
+		name:    "RSA-AES256-GCM-SHA384",
+		command: []string{"openssl", "s_client", "-no_ticket", "-cipher", "ECDHE-RSA-AES256-GCM-SHA384"},
+	}
+	runServerTestTLS12(t, test)
+}
+
 func TestHandshakeServerECDHEECDSAAES(t *testing.T) {
 	config := *testConfig
 	config.Certificates = make([]Certificate, 1)
@@ -599,7 +752,7 @@
 		return cert, nil
 	}
 	test := &serverTest{
-		name:    "SNI",
+		name:    "SNI-GetCertificate",
 		command: []string{"openssl", "s_client", "-no_ticket", "-cipher", "AES128-SHA", "-servername", "snitest.com"},
 		config:  &config,
 	}
@@ -617,7 +770,7 @@
 		return nil, nil
 	}
 	test := &serverTest{
-		name:    "SNI",
+		name:    "SNI-GetCertificateNotFound",
 		command: []string{"openssl", "s_client", "-no_ticket", "-cipher", "AES128-SHA", "-servername", "snitest.com"},
 		config:  &config,
 	}
@@ -627,18 +780,50 @@
 // TestHandshakeServerSNICertForNameError tests to make sure that errors in
 // GetCertificate result in a tls alert.
 func TestHandshakeServerSNIGetCertificateError(t *testing.T) {
-	config := *testConfig
+	const errMsg = "TestHandshakeServerSNIGetCertificateError error"
 
-	config.GetCertificate = func(clientHello *ClientHelloInfo) (*Certificate, error) {
-		return nil, fmt.Errorf("Test error in GetCertificate")
+	serverConfig := *testConfig
+	serverConfig.GetCertificate = func(clientHello *ClientHelloInfo) (*Certificate, error) {
+		return nil, errors.New(errMsg)
 	}
-	test := &serverTest{
-		name:        "SNI",
-		command:     []string{"openssl", "s_client", "-no_ticket", "-cipher", "AES128-SHA", "-servername", "snitest.com"},
-		config:      &config,
-		expectAlert: true,
+
+	clientHello := &clientHelloMsg{
+		vers:               0x0301,
+		cipherSuites:       []uint16{TLS_RSA_WITH_RC4_128_SHA},
+		compressionMethods: []uint8{0},
+		serverName:         "test",
 	}
-	runServerTestTLS12(t, test)
+	testClientHelloFailure(t, &serverConfig, clientHello, errMsg)
+}
+
+// TestHandshakeServerEmptyCertificates tests that GetCertificates is called in
+// the case that Certificates is empty, even without SNI.
+func TestHandshakeServerEmptyCertificates(t *testing.T) {
+	const errMsg = "TestHandshakeServerEmptyCertificates error"
+
+	serverConfig := *testConfig
+	serverConfig.GetCertificate = func(clientHello *ClientHelloInfo) (*Certificate, error) {
+		return nil, errors.New(errMsg)
+	}
+	serverConfig.Certificates = nil
+
+	clientHello := &clientHelloMsg{
+		vers:               0x0301,
+		cipherSuites:       []uint16{TLS_RSA_WITH_RC4_128_SHA},
+		compressionMethods: []uint8{0},
+	}
+	testClientHelloFailure(t, &serverConfig, clientHello, errMsg)
+
+	// With an empty Certificates and a nil GetCertificate, the server
+	// should always return a “no certificates” error.
+	serverConfig.GetCertificate = nil
+
+	clientHello = &clientHelloMsg{
+		vers:               0x0301,
+		cipherSuites:       []uint16{TLS_RSA_WITH_RC4_128_SHA},
+		compressionMethods: []uint8{0},
+	}
+	testClientHelloFailure(t, &serverConfig, clientHello, "no certificates")
 }
 
 // TestCipherSuiteCertPreferance ensures that we select an RSA ciphersuite with
@@ -716,11 +901,15 @@
 }
 
 func TestFallbackSCSV(t *testing.T) {
+	serverConfig := &Config{
+		Certificates: testConfig.Certificates,
+	}
 	test := &serverTest{
-		name: "FallbackSCSV",
+		name:   "FallbackSCSV",
+		config: serverConfig,
 		// OpenSSL 1.0.1j is needed for the -fallback_scsv option.
 		command: []string{"openssl", "s_client", "-fallback_scsv"},
-		expectHandshakeErrorIncluding: "inppropriate protocol fallback",
+		expectHandshakeErrorIncluding: "inappropriate protocol fallback",
 	}
 	runServerTestTLS11(t, test)
 }
@@ -840,7 +1029,9 @@
 	return b
 }
 
-var testRSACertificate = fromHex("308202b030820219a00302010202090085b0bba48a7fb8ca300d06092a864886f70d01010505003045310b3009060355040613024155311330110603550408130a536f6d652d53746174653121301f060355040a1318496e7465726e6574205769646769747320507479204c7464301e170d3130303432343039303933385a170d3131303432343039303933385a3045310b3009060355040613024155311330110603550408130a536f6d652d53746174653121301f060355040a1318496e7465726e6574205769646769747320507479204c746430819f300d06092a864886f70d010101050003818d0030818902818100bb79d6f517b5e5bf4610d0dc69bee62b07435ad0032d8a7a4385b71452e7a5654c2c78b8238cb5b482e5de1f953b7e62a52ca533d6fe125c7a56fcf506bffa587b263fb5cd04d3d0c921964ac7f4549f5abfef427100fe1899077f7e887d7df10439c4a22edb51c97ce3c04c3b326601cfafb11db8719a1ddbdb896baeda2d790203010001a381a73081a4301d0603551d0e04160414b1ade2855acfcb28db69ce2369ded3268e18883930750603551d23046e306c8014b1ade2855acfcb28db69ce2369ded3268e188839a149a4473045310b3009060355040613024155311330110603550408130a536f6d652d53746174653121301f060355040a1318496e7465726e6574205769646769747320507479204c746482090085b0bba48a7fb8ca300c0603551d13040530030101ff300d06092a864886f70d010105050003818100086c4524c76bb159ab0c52ccf2b014d7879d7a6475b55a9566e4c52b8eae12661feb4f38b36e60d392fdf74108b52513b1187a24fb301dbaed98b917ece7d73159db95d31d78ea50565cd5825a2d5a5f33c4b6d8c97590968c0f5298b5cd981f89205ff2a01ca31b9694dda9fd57e970e8266d71999b266e3850296c90a7bdd9")
+var testRSACertificate = fromHex("30820263308201cca003020102020900a273000c8100cbf3300d06092a864886f70d01010b0500302b31173015060355040a130e476f6f676c652054455354494e473110300e06035504031307476f20526f6f74301e170d3135303130313030303030305a170d3235303130313030303030305a302631173015060355040a130e476f6f676c652054455354494e47310b300906035504031302476f30819f300d06092a864886f70d010101050003818d0030818902818100af8788f6201b95656c14ab4405af3b4514e3b76dfd00634d957ffe6a623586c04af9187cf6aa255e7a64316600baf48e92afc76bd876d4f35f41cb6e5615971b97c13c123921663d2b16d1bcdb1cc0a7dab7caadbadacbd52150ecde8dabd16b814b8902f3c4bec16c89b14484bd21d1047d9d164df98215f6effad60947f2fb0203010001a38193308190300e0603551d0f0101ff0404030205a0301d0603551d250416301406082b0601050507030106082b06010505070302300c0603551d130101ff0402300030190603551d0e0412041012508d896f1bd1dc544d6ecb695e06f4301b0603551d23041430128010bf3db6a966f2b840cfeab40378481a4130190603551d1104123010820e6578616d706c652e676f6c616e67300d06092a864886f70d01010b050003818100927caf91551218965931a64840d52dd5eebb02a0f5c21e7c9bb3307d3cdc76da4f3dc0faae2d33246b037b1b67591121b511bc77b9d9e06ea82d2e35fa645f223e63106bbeff14866d0df01531a814381e3b84872ccb98ed5176b9b14fdddb9b84048640fa51ddbab48debe346de46b94f86c7f9a4c24134acccf6eab0ab3918")
+
+var testRSACertificateIssuer = fromHex("3082024d308201b6a003020102020827326bd913b7c43d300d06092a864886f70d01010b0500302b31173015060355040a130e476f6f676c652054455354494e473110300e06035504031307476f20526f6f74301e170d3135303130313030303030305a170d3235303130313030303030305a302b31173015060355040a130e476f6f676c652054455354494e473110300e06035504031307476f20526f6f7430819f300d06092a864886f70d010101050003818d0030818902818100f0429a7b9f66a222c8453800452db355b34c4409fee09af2510a6589bfa35bdb4d453200d1de24338d6d5e5a91cc8301628445d6eb4e675927b9c1ea5c0f676acfb0f708ce4f19827e321c1898bf86df9823d5f0b05df2b6779888eff8abbc7f41c6e7d2667386a579b8cbaad3f6fd597cd7c4b187911a425aed1b555c1965190203010001a37a3078300e0603551d0f0101ff040403020204301d0603551d250416301406082b0601050507030106082b06010505070302300f0603551d130101ff040530030101ff30190603551d0e04120410bf3db6a966f2b840cfeab40378481a41301b0603551d23041430128010bf3db6a966f2b840cfeab40378481a41300d06092a864886f70d01010b050003818100586e68c1219ed4f5782b7cfd53cf1a55750a98781b2023f8694bb831fff6d7d4aad1f0ac782b1ec787f00a8956bdd06b4a1063444fcafe955c07d679163a730802c568886a2cf8a3c2ab41176957131c4b9e077ebd7ffbb91fdad8b08b932e9aeefac04923ffdc0aa145563f7f061995317400203578f350e3e566deb29dec5e")
 
 var testECDSACertificate = fromHex("3082020030820162020900b8bf2d47a0d2ebf4300906072a8648ce3d04013045310b3009060355040613024155311330110603550408130a536f6d652d53746174653121301f060355040a1318496e7465726e6574205769646769747320507479204c7464301e170d3132313132323135303633325a170d3232313132303135303633325a3045310b3009060355040613024155311330110603550408130a536f6d652d53746174653121301f060355040a1318496e7465726e6574205769646769747320507479204c746430819b301006072a8648ce3d020106052b81040023038186000400c4a1edbe98f90b4873367ec316561122f23d53c33b4d213dcd6b75e6f6b0dc9adf26c1bcb287f072327cb3642f1c90bcea6823107efee325c0483a69e0286dd33700ef0462dd0da09c706283d881d36431aa9e9731bd96b068c09b23de76643f1a5c7fe9120e5858b65f70dd9bd8ead5d7f5d5ccb9b69f30665b669a20e227e5bffe3b300906072a8648ce3d040103818c0030818802420188a24febe245c5487d1bacf5ed989dae4770c05e1bb62fbdf1b64db76140d311a2ceee0b7e927eff769dc33b7ea53fcefa10e259ec472d7cacda4e970e15a06fd00242014dfcbe67139c2d050ebd3fa38c25c13313830d9406bbd4377af6ec7ac9862eddd711697f857c56defb31782be4c7780daecbbe9e4e3624317b6a0f399512078f2a")
 
@@ -848,13 +1039,13 @@
 
 var testRSAPrivateKey = &rsa.PrivateKey{
 	PublicKey: rsa.PublicKey{
-		N: bigFromString("131650079503776001033793877885499001334664249354723305978524647182322416328664556247316495448366990052837680518067798333412266673813370895702118944398081598789828837447552603077848001020611640547221687072142537202428102790818451901395596882588063427854225330436740647715202971973145151161964464812406232198521"),
+		N: bigFromString("123260960069105588390096594560395120585636206567569540256061833976822892593755073841963170165000086278069699238754008398039246547214989242849418349143232951701395321381739566687846006911427966669790845430647688107009232778985142860108863460556510585049041936029324503323373417214453307648498561956908810892027L"),
 		E: 65537,
 	},
-	D: bigFromString("29354450337804273969007277378287027274721892607543397931919078829901848876371746653677097639302788129485893852488285045793268732234230875671682624082413996177431586734171663258657462237320300610850244186316880055243099640544518318093544057213190320837094958164973959123058337475052510833916491060913053867729"),
+	D: bigFromString("73196363031103823625826315929954946106043759818067219550565550066527203472294428548476778865091068522665312037075674791871635825938217363523103946045078950060973913307430314113074463630778799389010335923241901501086246276485964417618981733827707048660375428006201525399194575538037883519254056917253456403553L"),
 	Primes: []*big.Int{
-		bigFromString("11969277782311800166562047708379380720136961987713178380670422671426759650127150688426177829077494755200794297055316163155755835813760102405344560929062149"),
-		bigFromString("10998999429884441391899182616418192492905073053684657075974935218461686523870125521822756579792315215543092255516093840728890783887287417039645833477273829"),
+		bigFromString("11157426355495284553529769521954035649776033703833034489026848970480272318436419662860715175517581249375929775774910501512841707465207184924996975125010787L"),
+		bigFromString("11047436580963564307160117670964629323534448585520694947919342920137706075617545637058809770319843170934495909554506529982972972247390145716507031692656521L"),
 	},
 }
 
diff --git a/third_party/gofrontend/libgo/go/crypto/tls/key_agreement.go b/third_party/gofrontend/libgo/go/crypto/tls/key_agreement.go
index 0974fc6..0e6a7c2 100644
--- a/third_party/gofrontend/libgo/go/crypto/tls/key_agreement.go
+++ b/third_party/gofrontend/libgo/go/crypto/tls/key_agreement.go
@@ -11,7 +11,6 @@
 	"crypto/md5"
 	"crypto/rsa"
 	"crypto/sha1"
-	"crypto/sha256"
 	"crypto/x509"
 	"encoding/asn1"
 	"errors"
@@ -31,12 +30,6 @@
 }
 
 func (ka rsaKeyAgreement) processClientKeyExchange(config *Config, cert *Certificate, ckx *clientKeyExchangeMsg, version uint16) ([]byte, error) {
-	preMasterSecret := make([]byte, 48)
-	_, err := io.ReadFull(config.rand(), preMasterSecret[2:])
-	if err != nil {
-		return nil, err
-	}
-
 	if len(ckx.ciphertext) < 2 {
 		return nil, errClientKeyExchange
 	}
@@ -49,8 +42,12 @@
 		}
 		ciphertext = ckx.ciphertext[2:]
 	}
-
-	err = rsa.DecryptPKCS1v15SessionKey(config.rand(), cert.PrivateKey.(*rsa.PrivateKey), ciphertext, preMasterSecret)
+	priv, ok := cert.PrivateKey.(crypto.Decrypter)
+	if !ok {
+		return nil, errors.New("tls: certificate private key does not implement crypto.Decrypter")
+	}
+	// Perform constant time RSA PKCS#1 v1.5 decryption
+	preMasterSecret, err := priv.Decrypt(config.rand(), ciphertext, &rsa.PKCS1v15DecryptOptions{SessionKeyLen: 48})
 	if err != nil {
 		return nil, err
 	}
@@ -110,30 +107,26 @@
 	return md5sha1
 }
 
-// sha256Hash implements TLS 1.2's hash function.
-func sha256Hash(slices [][]byte) []byte {
-	h := sha256.New()
-	for _, slice := range slices {
-		h.Write(slice)
-	}
-	return h.Sum(nil)
-}
-
 // hashForServerKeyExchange hashes the given slices and returns their digest
-// and the identifier of the hash function used. The hashFunc argument is only
-// used for >= TLS 1.2 and precisely identifies the hash function to use.
-func hashForServerKeyExchange(sigType, hashFunc uint8, version uint16, slices ...[]byte) ([]byte, crypto.Hash, error) {
+// and the identifier of the hash function used. The sigAndHash argument is
+// only used for >= TLS 1.2 and precisely identifies the hash function to use.
+func hashForServerKeyExchange(sigAndHash signatureAndHash, version uint16, slices ...[]byte) ([]byte, crypto.Hash, error) {
 	if version >= VersionTLS12 {
-		switch hashFunc {
-		case hashSHA256:
-			return sha256Hash(slices), crypto.SHA256, nil
-		case hashSHA1:
-			return sha1Hash(slices), crypto.SHA1, nil
-		default:
-			return nil, crypto.Hash(0), errors.New("tls: unknown hash function used by peer")
+		if !isSupportedSignatureAndHash(sigAndHash, supportedSignatureAlgorithms) {
+			return nil, crypto.Hash(0), errors.New("tls: unsupported hash function used by peer")
 		}
+		hashFunc, err := lookupTLSHash(sigAndHash.hash)
+		if err != nil {
+			return nil, crypto.Hash(0), err
+		}
+		h := hashFunc.New()
+		for _, slice := range slices {
+			h.Write(slice)
+		}
+		digest := h.Sum(nil)
+		return digest, hashFunc, nil
 	}
-	if sigType == signatureECDSA {
+	if sigAndHash.signature == signatureECDSA {
 		return sha1Hash(slices), crypto.SHA1, nil
 	}
 	return md5SHA1Hash(slices), crypto.MD5SHA1, nil
@@ -142,20 +135,19 @@
 // pickTLS12HashForSignature returns a TLS 1.2 hash identifier for signing a
 // ServerKeyExchange given the signature type being used and the client's
 // advertised list of supported signature and hash combinations.
-func pickTLS12HashForSignature(sigType uint8, clientSignatureAndHashes []signatureAndHash) (uint8, error) {
-	if len(clientSignatureAndHashes) == 0 {
+func pickTLS12HashForSignature(sigType uint8, clientList []signatureAndHash) (uint8, error) {
+	if len(clientList) == 0 {
 		// If the client didn't specify any signature_algorithms
 		// extension then we can assume that it supports SHA1. See
 		// http://tools.ietf.org/html/rfc5246#section-7.4.1.4.1
 		return hashSHA1, nil
 	}
 
-	for _, sigAndHash := range clientSignatureAndHashes {
+	for _, sigAndHash := range clientList {
 		if sigAndHash.signature != sigType {
 			continue
 		}
-		switch sigAndHash.hash {
-		case hashSHA1, hashSHA256:
+		if isSupportedSignatureAndHash(sigAndHash, supportedSignatureAlgorithms) {
 			return sigAndHash.hash, nil
 		}
 	}
@@ -228,41 +220,42 @@
 	serverECDHParams[3] = byte(len(ecdhePublic))
 	copy(serverECDHParams[4:], ecdhePublic)
 
-	var tls12HashId uint8
+	sigAndHash := signatureAndHash{signature: ka.sigType}
+
 	if ka.version >= VersionTLS12 {
-		if tls12HashId, err = pickTLS12HashForSignature(ka.sigType, clientHello.signatureAndHashes); err != nil {
+		if sigAndHash.hash, err = pickTLS12HashForSignature(ka.sigType, clientHello.signatureAndHashes); err != nil {
 			return nil, err
 		}
 	}
 
-	digest, hashFunc, err := hashForServerKeyExchange(ka.sigType, tls12HashId, ka.version, clientHello.random, hello.random, serverECDHParams)
+	digest, hashFunc, err := hashForServerKeyExchange(sigAndHash, ka.version, clientHello.random, hello.random, serverECDHParams)
 	if err != nil {
 		return nil, err
 	}
+
+	priv, ok := cert.PrivateKey.(crypto.Signer)
+	if !ok {
+		return nil, errors.New("tls: certificate private key does not implement crypto.Signer")
+	}
 	var sig []byte
 	switch ka.sigType {
 	case signatureECDSA:
-		privKey, ok := cert.PrivateKey.(*ecdsa.PrivateKey)
+		_, ok := priv.Public().(*ecdsa.PublicKey)
 		if !ok {
-			return nil, errors.New("ECDHE ECDSA requires an ECDSA server private key")
+			return nil, errors.New("ECDHE ECDSA requires an ECDSA server key")
 		}
-		r, s, err := ecdsa.Sign(config.rand(), privKey, digest)
-		if err != nil {
-			return nil, errors.New("failed to sign ECDHE parameters: " + err.Error())
-		}
-		sig, err = asn1.Marshal(ecdsaSignature{r, s})
 	case signatureRSA:
-		privKey, ok := cert.PrivateKey.(*rsa.PrivateKey)
+		_, ok := priv.Public().(*rsa.PublicKey)
 		if !ok {
-			return nil, errors.New("ECDHE RSA requires a RSA server private key")
-		}
-		sig, err = rsa.SignPKCS1v15(config.rand(), privKey, hashFunc, digest)
-		if err != nil {
-			return nil, errors.New("failed to sign ECDHE parameters: " + err.Error())
+			return nil, errors.New("ECDHE RSA requires a RSA server key")
 		}
 	default:
 		return nil, errors.New("unknown ECDHE signature algorithm")
 	}
+	sig, err = priv.Sign(config.rand(), digest, hashFunc)
+	if err != nil {
+		return nil, errors.New("failed to sign ECDHE parameters: " + err.Error())
+	}
 
 	skx := new(serverKeyExchangeMsg)
 	sigAndHashLen := 0
@@ -273,8 +266,8 @@
 	copy(skx.key, serverECDHParams)
 	k := skx.key[len(serverECDHParams):]
 	if ka.version >= VersionTLS12 {
-		k[0] = tls12HashId
-		k[1] = ka.sigType
+		k[0] = sigAndHash.hash
+		k[1] = sigAndHash.signature
 		k = k[2:]
 	}
 	k[0] = byte(len(sig) >> 8)
@@ -335,15 +328,14 @@
 		return errServerKeyExchange
 	}
 
-	var tls12HashId uint8
+	sigAndHash := signatureAndHash{signature: ka.sigType}
 	if ka.version >= VersionTLS12 {
 		// handle SignatureAndHashAlgorithm
-		var sigAndHash []uint8
-		sigAndHash, sig = sig[:2], sig[2:]
-		if sigAndHash[1] != ka.sigType {
+		sigAndHash = signatureAndHash{hash: sig[0], signature: sig[1]}
+		if sigAndHash.signature != ka.sigType {
 			return errServerKeyExchange
 		}
-		tls12HashId = sigAndHash[0]
+		sig = sig[2:]
 		if len(sig) < 2 {
 			return errServerKeyExchange
 		}
@@ -354,7 +346,7 @@
 	}
 	sig = sig[2:]
 
-	digest, hashFunc, err := hashForServerKeyExchange(ka.sigType, tls12HashId, ka.version, clientHello.random, serverHello.random, serverECDHParams)
+	digest, hashFunc, err := hashForServerKeyExchange(sigAndHash, ka.version, clientHello.random, serverHello.random, serverECDHParams)
 	if err != nil {
 		return err
 	}
diff --git a/third_party/gofrontend/libgo/go/crypto/tls/prf.go b/third_party/gofrontend/libgo/go/crypto/tls/prf.go
index fb8b3ab..6127c1c 100644
--- a/third_party/gofrontend/libgo/go/crypto/tls/prf.go
+++ b/third_party/gofrontend/libgo/go/crypto/tls/prf.go
@@ -10,6 +10,8 @@
 	"crypto/md5"
 	"crypto/sha1"
 	"crypto/sha256"
+	"crypto/sha512"
+	"errors"
 	"hash"
 )
 
@@ -65,12 +67,14 @@
 }
 
 // prf12 implements the TLS 1.2 pseudo-random function, as defined in RFC 5246, section 5.
-func prf12(result, secret, label, seed []byte) {
-	labelAndSeed := make([]byte, len(label)+len(seed))
-	copy(labelAndSeed, label)
-	copy(labelAndSeed[len(label):], seed)
+func prf12(hashFunc func() hash.Hash) func(result, secret, label, seed []byte) {
+	return func(result, secret, label, seed []byte) {
+		labelAndSeed := make([]byte, len(label)+len(seed))
+		copy(labelAndSeed, label)
+		copy(labelAndSeed[len(label):], seed)
 
-	pHash(result, secret, labelAndSeed, sha256.New)
+		pHash(result, secret, labelAndSeed, hashFunc)
+	}
 }
 
 // prf30 implements the SSL 3.0 pseudo-random function, as defined in
@@ -117,41 +121,49 @@
 var clientFinishedLabel = []byte("client finished")
 var serverFinishedLabel = []byte("server finished")
 
-func prfForVersion(version uint16) func(result, secret, label, seed []byte) {
+func prfAndHashForVersion(version uint16, suite *cipherSuite) (func(result, secret, label, seed []byte), crypto.Hash) {
 	switch version {
 	case VersionSSL30:
-		return prf30
+		return prf30, crypto.Hash(0)
 	case VersionTLS10, VersionTLS11:
-		return prf10
+		return prf10, crypto.Hash(0)
 	case VersionTLS12:
-		return prf12
+		if suite.flags&suiteSHA384 != 0 {
+			return prf12(sha512.New384), crypto.SHA384
+		}
+		return prf12(sha256.New), crypto.SHA256
 	default:
 		panic("unknown version")
 	}
 }
 
+func prfForVersion(version uint16, suite *cipherSuite) func(result, secret, label, seed []byte) {
+	prf, _ := prfAndHashForVersion(version, suite)
+	return prf
+}
+
 // masterFromPreMasterSecret generates the master secret from the pre-master
 // secret. See http://tools.ietf.org/html/rfc5246#section-8.1
-func masterFromPreMasterSecret(version uint16, preMasterSecret, clientRandom, serverRandom []byte) []byte {
+func masterFromPreMasterSecret(version uint16, suite *cipherSuite, preMasterSecret, clientRandom, serverRandom []byte) []byte {
 	var seed [tlsRandomLength * 2]byte
 	copy(seed[0:len(clientRandom)], clientRandom)
 	copy(seed[len(clientRandom):], serverRandom)
 	masterSecret := make([]byte, masterSecretLength)
-	prfForVersion(version)(masterSecret, preMasterSecret, masterSecretLabel, seed[0:])
+	prfForVersion(version, suite)(masterSecret, preMasterSecret, masterSecretLabel, seed[0:])
 	return masterSecret
 }
 
 // keysFromMasterSecret generates the connection keys from the master
 // secret, given the lengths of the MAC key, cipher key and IV, as defined in
 // RFC 2246, section 6.3.
-func keysFromMasterSecret(version uint16, masterSecret, clientRandom, serverRandom []byte, macLen, keyLen, ivLen int) (clientMAC, serverMAC, clientKey, serverKey, clientIV, serverIV []byte) {
+func keysFromMasterSecret(version uint16, suite *cipherSuite, masterSecret, clientRandom, serverRandom []byte, macLen, keyLen, ivLen int) (clientMAC, serverMAC, clientKey, serverKey, clientIV, serverIV []byte) {
 	var seed [tlsRandomLength * 2]byte
 	copy(seed[0:len(clientRandom)], serverRandom)
 	copy(seed[len(serverRandom):], clientRandom)
 
 	n := 2*macLen + 2*keyLen + 2*ivLen
 	keyMaterial := make([]byte, n)
-	prfForVersion(version)(keyMaterial, masterSecret, keyExpansionLabel, seed[0:])
+	prfForVersion(version, suite)(keyMaterial, masterSecret, keyExpansionLabel, seed[0:])
 	clientMAC = keyMaterial[:macLen]
 	keyMaterial = keyMaterial[macLen:]
 	serverMAC = keyMaterial[:macLen]
@@ -166,11 +178,33 @@
 	return
 }
 
-func newFinishedHash(version uint16) finishedHash {
-	if version >= VersionTLS12 {
-		return finishedHash{sha256.New(), sha256.New(), nil, nil, version}
+// lookupTLSHash looks up the corresponding crypto.Hash for a given
+// TLS hash identifier.
+func lookupTLSHash(hash uint8) (crypto.Hash, error) {
+	switch hash {
+	case hashSHA1:
+		return crypto.SHA1, nil
+	case hashSHA256:
+		return crypto.SHA256, nil
+	case hashSHA384:
+		return crypto.SHA384, nil
+	default:
+		return 0, errors.New("tls: unsupported hash algorithm")
 	}
-	return finishedHash{sha1.New(), sha1.New(), md5.New(), md5.New(), version}
+}
+
+func newFinishedHash(version uint16, cipherSuite *cipherSuite) finishedHash {
+	var buffer []byte
+	if version == VersionSSL30 || version >= VersionTLS12 {
+		buffer = []byte{}
+	}
+
+	prf, hash := prfAndHashForVersion(version, cipherSuite)
+	if hash != 0 {
+		return finishedHash{hash.New(), hash.New(), nil, nil, buffer, version, prf}
+	}
+
+	return finishedHash{sha1.New(), sha1.New(), md5.New(), md5.New(), buffer, version, prf}
 }
 
 // A finishedHash calculates the hash of a set of handshake messages suitable
@@ -183,10 +217,14 @@
 	clientMD5 hash.Hash
 	serverMD5 hash.Hash
 
+	// In TLS 1.2, a full buffer is sadly required.
+	buffer []byte
+
 	version uint16
+	prf     func(result, secret, label, seed []byte)
 }
 
-func (h finishedHash) Write(msg []byte) (n int, err error) {
+func (h *finishedHash) Write(msg []byte) (n int, err error) {
 	h.client.Write(msg)
 	h.server.Write(msg)
 
@@ -194,14 +232,29 @@
 		h.clientMD5.Write(msg)
 		h.serverMD5.Write(msg)
 	}
+
+	if h.buffer != nil {
+		h.buffer = append(h.buffer, msg...)
+	}
+
 	return len(msg), nil
 }
 
+func (h finishedHash) Sum() []byte {
+	if h.version >= VersionTLS12 {
+		return h.client.Sum(nil)
+	}
+
+	out := make([]byte, 0, md5.Size+sha1.Size)
+	out = h.clientMD5.Sum(out)
+	return h.client.Sum(out)
+}
+
 // finishedSum30 calculates the contents of the verify_data member of a SSLv3
 // Finished message given the MD5 and SHA1 hashes of a set of handshake
 // messages.
-func finishedSum30(md5, sha1 hash.Hash, masterSecret []byte, magic [4]byte) []byte {
-	md5.Write(magic[:])
+func finishedSum30(md5, sha1 hash.Hash, masterSecret []byte, magic []byte) []byte {
+	md5.Write(magic)
 	md5.Write(masterSecret)
 	md5.Write(ssl30Pad1[:])
 	md5Digest := md5.Sum(nil)
@@ -212,7 +265,7 @@
 	md5.Write(md5Digest)
 	md5Digest = md5.Sum(nil)
 
-	sha1.Write(magic[:])
+	sha1.Write(magic)
 	sha1.Write(masterSecret)
 	sha1.Write(ssl30Pad1[:40])
 	sha1Digest := sha1.Sum(nil)
@@ -236,19 +289,11 @@
 // Finished message.
 func (h finishedHash) clientSum(masterSecret []byte) []byte {
 	if h.version == VersionSSL30 {
-		return finishedSum30(h.clientMD5, h.client, masterSecret, ssl3ClientFinishedMagic)
+		return finishedSum30(h.clientMD5, h.client, masterSecret, ssl3ClientFinishedMagic[:])
 	}
 
 	out := make([]byte, finishedVerifyLength)
-	if h.version >= VersionTLS12 {
-		seed := h.client.Sum(nil)
-		prf12(out, masterSecret, clientFinishedLabel, seed)
-	} else {
-		seed := make([]byte, 0, md5.Size+sha1.Size)
-		seed = h.clientMD5.Sum(seed)
-		seed = h.client.Sum(seed)
-		prf10(out, masterSecret, clientFinishedLabel, seed)
-	}
+	h.prf(out, masterSecret, clientFinishedLabel, h.Sum())
 	return out
 }
 
@@ -256,36 +301,67 @@
 // Finished message.
 func (h finishedHash) serverSum(masterSecret []byte) []byte {
 	if h.version == VersionSSL30 {
-		return finishedSum30(h.serverMD5, h.server, masterSecret, ssl3ServerFinishedMagic)
+		return finishedSum30(h.serverMD5, h.server, masterSecret, ssl3ServerFinishedMagic[:])
 	}
 
 	out := make([]byte, finishedVerifyLength)
-	if h.version >= VersionTLS12 {
-		seed := h.server.Sum(nil)
-		prf12(out, masterSecret, serverFinishedLabel, seed)
-	} else {
-		seed := make([]byte, 0, md5.Size+sha1.Size)
-		seed = h.serverMD5.Sum(seed)
-		seed = h.server.Sum(seed)
-		prf10(out, masterSecret, serverFinishedLabel, seed)
-	}
+	h.prf(out, masterSecret, serverFinishedLabel, h.Sum())
 	return out
 }
 
+// selectClientCertSignatureAlgorithm returns a signatureAndHash to sign a
+// client's CertificateVerify with, or an error if none can be found.
+func (h finishedHash) selectClientCertSignatureAlgorithm(serverList []signatureAndHash, sigType uint8) (signatureAndHash, error) {
+	if h.version < VersionTLS12 {
+		// Nothing to negotiate before TLS 1.2.
+		return signatureAndHash{signature: sigType}, nil
+	}
+
+	for _, v := range serverList {
+		if v.signature == sigType && isSupportedSignatureAndHash(v, supportedSignatureAlgorithms) {
+			return v, nil
+		}
+	}
+	return signatureAndHash{}, errors.New("tls: no supported signature algorithm found for signing client certificate")
+}
+
 // hashForClientCertificate returns a digest, hash function, and TLS 1.2 hash
 // id suitable for signing by a TLS client certificate.
-func (h finishedHash) hashForClientCertificate(sigType uint8) ([]byte, crypto.Hash, uint8) {
-	if h.version >= VersionTLS12 {
-		digest := h.server.Sum(nil)
-		return digest, crypto.SHA256, hashSHA256
-	}
-	if sigType == signatureECDSA {
-		digest := h.server.Sum(nil)
-		return digest, crypto.SHA1, hashSHA1
+func (h finishedHash) hashForClientCertificate(signatureAndHash signatureAndHash, masterSecret []byte) ([]byte, crypto.Hash, error) {
+	if (h.version == VersionSSL30 || h.version >= VersionTLS12) && h.buffer == nil {
+		panic("a handshake hash for a client-certificate was requested after discarding the handshake buffer")
 	}
 
-	digest := make([]byte, 0, 36)
-	digest = h.serverMD5.Sum(digest)
-	digest = h.server.Sum(digest)
-	return digest, crypto.MD5SHA1, 0 /* not specified in TLS 1.2. */
+	if h.version == VersionSSL30 {
+		if signatureAndHash.signature != signatureRSA {
+			return nil, 0, errors.New("tls: unsupported signature type for client certificate")
+		}
+
+		md5Hash := md5.New()
+		md5Hash.Write(h.buffer)
+		sha1Hash := sha1.New()
+		sha1Hash.Write(h.buffer)
+		return finishedSum30(md5Hash, sha1Hash, masterSecret, nil), crypto.MD5SHA1, nil
+	}
+	if h.version >= VersionTLS12 {
+		hashAlg, err := lookupTLSHash(signatureAndHash.hash)
+		if err != nil {
+			return nil, 0, err
+		}
+		hash := hashAlg.New()
+		hash.Write(h.buffer)
+		return hash.Sum(nil), hashAlg, nil
+	}
+
+	if signatureAndHash.signature == signatureECDSA {
+		return h.server.Sum(nil), crypto.SHA1, nil
+	}
+
+	return h.Sum(), crypto.MD5SHA1, nil
+}
+
+// discardHandshakeBuffer is called when there is no more need to
+// buffer the entirety of the handshake messages.
+func (h *finishedHash) discardHandshakeBuffer() {
+	h.buffer = nil
 }
diff --git a/third_party/gofrontend/libgo/go/crypto/tls/prf_test.go b/third_party/gofrontend/libgo/go/crypto/tls/prf_test.go
index a9b6c9e..0a1b1bc 100644
--- a/third_party/gofrontend/libgo/go/crypto/tls/prf_test.go
+++ b/third_party/gofrontend/libgo/go/crypto/tls/prf_test.go
@@ -35,6 +35,7 @@
 
 type testKeysFromTest struct {
 	version                    uint16
+	suite                      *cipherSuite
 	preMasterSecret            string
 	clientRandom, serverRandom string
 	masterSecret               string
@@ -49,13 +50,13 @@
 		clientRandom, _ := hex.DecodeString(test.clientRandom)
 		serverRandom, _ := hex.DecodeString(test.serverRandom)
 
-		masterSecret := masterFromPreMasterSecret(test.version, in, clientRandom, serverRandom)
+		masterSecret := masterFromPreMasterSecret(test.version, test.suite, in, clientRandom, serverRandom)
 		if s := hex.EncodeToString(masterSecret); s != test.masterSecret {
 			t.Errorf("#%d: bad master secret %s, want %s", i, s, test.masterSecret)
 			continue
 		}
 
-		clientMAC, serverMAC, clientKey, serverKey, _, _ := keysFromMasterSecret(test.version, masterSecret, clientRandom, serverRandom, test.macLen, test.keyLen, 0)
+		clientMAC, serverMAC, clientKey, serverKey, _, _ := keysFromMasterSecret(test.version, test.suite, masterSecret, clientRandom, serverRandom, test.macLen, test.keyLen, 0)
 		clientMACString := hex.EncodeToString(clientMAC)
 		serverMACString := hex.EncodeToString(serverMAC)
 		clientKeyString := hex.EncodeToString(clientKey)
@@ -69,10 +70,20 @@
 	}
 }
 
+func cipherSuiteById(id uint16) *cipherSuite {
+	for _, cipherSuite := range cipherSuites {
+		if cipherSuite.id == id {
+			return cipherSuite
+		}
+	}
+	panic("ciphersuite not found")
+}
+
 // These test vectors were generated from GnuTLS using `gnutls-cli --insecure -d 9 `
 var testKeysFromTests = []testKeysFromTest{
 	{
 		VersionTLS10,
+		cipherSuiteById(TLS_RSA_WITH_RC4_128_SHA),
 		"0302cac83ad4b1db3b9ab49ad05957de2a504a634a386fc600889321e1a971f57479466830ac3e6f468e87f5385fa0c5",
 		"4ae66303755184a3917fcb44880605fcc53baa01912b22ed94473fc69cebd558",
 		"4ae663020ec16e6bb5130be918cfcafd4d765979a3136a5d50c593446e4e44db",
@@ -86,6 +97,7 @@
 	},
 	{
 		VersionTLS10,
+		cipherSuiteById(TLS_RSA_WITH_RC4_128_SHA),
 		"03023f7527316bc12cbcd69e4b9e8275d62c028f27e65c745cfcddc7ce01bd3570a111378b63848127f1c36e5f9e4890",
 		"4ae66364b5ea56b20ce4e25555aed2d7e67f42788dd03f3fee4adae0459ab106",
 		"4ae66363ab815cbf6a248b87d6b556184e945e9b97fbdf247858b0bdafacfa1c",
@@ -99,6 +111,7 @@
 	},
 	{
 		VersionTLS10,
+		cipherSuiteById(TLS_RSA_WITH_RC4_128_SHA),
 		"832d515f1d61eebb2be56ba0ef79879efb9b527504abb386fb4310ed5d0e3b1f220d3bb6b455033a2773e6d8bdf951d278a187482b400d45deb88a5d5a6bb7d6a7a1decc04eb9ef0642876cd4a82d374d3b6ff35f0351dc5d411104de431375355addc39bfb1f6329fb163b0bc298d658338930d07d313cd980a7e3d9196cac1",
 		"4ae663b2ee389c0de147c509d8f18f5052afc4aaf9699efe8cb05ece883d3a5e",
 		"4ae664d503fd4cff50cfc1fb8fc606580f87b0fcdac9554ba0e01d785bdf278e",
@@ -112,6 +125,7 @@
 	},
 	{
 		VersionSSL30,
+		cipherSuiteById(TLS_RSA_WITH_RC4_128_SHA),
 		"832d515f1d61eebb2be56ba0ef79879efb9b527504abb386fb4310ed5d0e3b1f220d3bb6b455033a2773e6d8bdf951d278a187482b400d45deb88a5d5a6bb7d6a7a1decc04eb9ef0642876cd4a82d374d3b6ff35f0351dc5d411104de431375355addc39bfb1f6329fb163b0bc298d658338930d07d313cd980a7e3d9196cac1",
 		"4ae663b2ee389c0de147c509d8f18f5052afc4aaf9699efe8cb05ece883d3a5e",
 		"4ae664d503fd4cff50cfc1fb8fc606580f87b0fcdac9554ba0e01d785bdf278e",
diff --git a/third_party/gofrontend/libgo/go/crypto/tls/testdata/Client-TLSv10-ClientCert-ECDSA-ECDSA b/third_party/gofrontend/libgo/go/crypto/tls/testdata/Client-TLSv10-ClientCert-ECDSA-ECDSA
index 00722cb..4bad786 100644
--- a/third_party/gofrontend/libgo/go/crypto/tls/testdata/Client-TLSv10-ClientCert-ECDSA-ECDSA
+++ b/third_party/gofrontend/libgo/go/crypto/tls/testdata/Client-TLSv10-ClientCert-ECDSA-ECDSA
@@ -1,18 +1,19 @@
 >>> Flow 1 (client to server)
-00000000  16 03 01 00 75 01 00 00  71 03 03 00 00 00 00 00  |....u...q.......|
+00000000  16 03 01 00 81 01 00 00  7d 03 03 00 00 00 00 00  |........}.......|
 00000010  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
-00000020  00 00 00 00 00 00 00 00  00 00 00 00 00 1a c0 2f  |.............../|
-00000030  c0 2b c0 11 c0 07 c0 13  c0 09 c0 14 c0 0a 00 05  |.+..............|
-00000040  00 2f 00 35 c0 12 00 0a  01 00 00 2e 00 05 00 05  |./.5............|
-00000050  01 00 00 00 00 00 0a 00  08 00 06 00 17 00 18 00  |................|
-00000060  19 00 0b 00 02 01 00 00  0d 00 0a 00 08 04 01 04  |................|
-00000070  03 02 01 02 03 ff 01 00  01 00                    |..........|
+00000020  00 00 00 00 00 00 00 00  00 00 00 00 00 1e c0 2f  |.............../|
+00000030  c0 2b c0 30 c0 2c c0 11  c0 07 c0 13 c0 09 c0 14  |.+.0.,..........|
+00000040  c0 0a 00 05 00 2f 00 35  c0 12 00 0a 01 00 00 36  |...../.5.......6|
+00000050  00 05 00 05 01 00 00 00  00 00 0a 00 08 00 06 00  |................|
+00000060  17 00 18 00 19 00 0b 00  02 01 00 00 0d 00 0e 00  |................|
+00000070  0c 04 01 04 03 05 01 05  03 02 01 02 03 ff 01 00  |................|
+00000080  01 00 00 12 00 00                                 |......|
 >>> Flow 2 (server to client)
-00000000  16 03 01 00 59 02 00 00  55 03 01 53 04 f1 03 46  |....Y...U..S...F|
-00000010  0f 84 c4 cb 55 ef 85 f6  4f d7 0e e1 4b 10 d4 bb  |....U...O...K...|
-00000020  35 87 2d f3 d7 18 ec 4e  95 4b f4 20 28 82 94 d9  |5.-....N.K. (...|
-00000030  df c4 fc ee 21 23 c1 e2  76 3e 7b 09 af 2c 39 23  |....!#..v>{..,9#|
-00000040  f8 46 6c 31 88 42 f0 79  de 37 2b 00 c0 09 00 00  |.Fl1.B.y.7+.....|
+00000000  16 03 01 00 59 02 00 00  55 03 01 c0 e1 5c 5b 45  |....Y...U....\[E|
+00000010  70 fc a1 73 44 e7 69 b6  83 a1 71 bc 03 21 2e cc  |p..sD.i...q..!..|
+00000020  21 7a 28 20 82 6b 2f 77  7d 40 c7 20 0d e4 19 db  |!z( .k/w}@. ....|
+00000030  35 cd 75 a4 e7 e5 6c 3e  c9 d5 fe 9d c5 88 78 7b  |5.u...l>......x{|
+00000040  c4 fc 04 9a c1 10 7a 15  d9 e9 4a 95 c0 09 00 00  |......z...J.....|
 00000050  0d ff 01 00 01 00 00 0b  00 04 03 00 01 02 16 03  |................|
 00000060  01 02 0e 0b 00 02 0a 00  02 07 00 02 04 30 82 02  |.............0..|
 00000070  00 30 82 01 62 02 09 00  b8 bf 2d 47 a0 d2 eb f4  |.0..b.....-G....|
@@ -47,21 +48,21 @@
 00000240  13 83 0d 94 06 bb d4 37  7a f6 ec 7a c9 86 2e dd  |.......7z..z....|
 00000250  d7 11 69 7f 85 7c 56 de  fb 31 78 2b e4 c7 78 0d  |..i..|V..1x+..x.|
 00000260  ae cb be 9e 4e 36 24 31  7b 6a 0f 39 95 12 07 8f  |....N6$1{j.9....|
-00000270  2a 16 03 01 00 d5 0c 00  00 d1 03 00 17 41 04 4f  |*............A.O|
-00000280  47 16 72 98 9e 9f 2e 8e  78 e9 0f fe 95 83 7b aa  |G.r.....x.....{.|
-00000290  e5 3d c0 7d cf 83 bd 22  0b fd 48 f1 a7 49 a5 7d  |.=.}..."..H..I.}|
-000002a0  8e 0c 83 7f e1 2d 71 03  cc 90 09 ab f7 35 81 48  |.....-q......5.H|
-000002b0  a4 1e 7d 87 21 23 12 58  2c 47 f3 af c7 6c 71 00  |..}.!#.X,G...lq.|
-000002c0  8a 30 81 87 02 42 00 b4  03 38 60 43 d9 32 ef 64  |.0...B...8`C.2.d|
-000002d0  5a 9c 91 95 0d 10 21 53  c7 78 f8 bf 50 ed 13 5d  |Z.....!S.x..P..]|
-000002e0  c3 e7 71 d6 11 04 f1 e4  9d ce 17 99 8d 1a 87 1f  |..q.............|
-000002f0  cb dd f8 1b ae cd bc 4a  77 ab 7c 50 bf 73 c3 ea  |.......Jw.|P.s..|
-00000300  d6 df 88 56 f6 b1 03 83  02 41 66 3d fb 4e 7e af  |...V.....Af=.N~.|
-00000310  4e c1 60 fe 09 fa 7e 74  99 66 7f de b4 b2 74 89  |N.`...~t.f....t.|
-00000320  1c a4 cf 74 1a 55 a5 be  74 f9 36 21 3d ae c8 c3  |...t.U..t.6!=...|
-00000330  24 8e ad db a3 26 67 8f  98 27 e3 93 ee d9 5c fb  |$....&g..'....\.|
-00000340  85 82 e2 13 c3 50 ab e9  f6 39 2b 16 03 01 00 0e  |.....P...9+.....|
-00000350  0d 00 00 06 03 01 02 40  00 00 0e 00 00 00        |.......@......|
+00000270  2a 16 03 01 00 d6 0c 00  00 d2 03 00 17 41 04 01  |*............A..|
+00000280  74 83 af 3a 65 7a ad 1a  63 1f 13 82 9d f4 de 06  |t..:ez..c.......|
+00000290  4e 3a 03 81 61 72 ff f8  58 da 7b f5 81 6d 81 57  |N:..ar..X.{..m.W|
+000002a0  d9 d1 b1 6d e3 97 db 86  72 17 15 18 16 d4 ec 04  |...m....r.......|
+000002b0  32 7c 38 90 6b a4 3c e9  35 79 2d 4c 39 5e 2d 00  |2|8.k.<.5y-L9^-.|
+000002c0  8b 30 81 88 02 42 01 44  78 e1 2a bb 95 f7 45 58  |.0...B.Dx.*...EX|
+000002d0  d4 0d b6 e4 4e ff 48 b3  11 14 ee d5 6c bb 5f 0c  |....N.H.....l._.|
+000002e0  90 b6 ef bc 05 77 f6 05  42 b4 d8 a6 70 e6 8c 90  |.....w..B...p...|
+000002f0  f0 4b 3b c9 d3 4e 0c 85  65 b4 e0 fe b5 10 09 9b  |.K;..N..e.......|
+00000300  e1 08 84 ea 93 96 8e a4  02 42 01 c7 15 ee 9d 98  |.........B......|
+00000310  b7 25 eb 07 ff f6 94 7e  e7 9d a5 17 9e 37 93 40  |.%.....~.....7.@|
+00000320  4c 9f eb 6b a3 7a 57 d8  81 c6 d9 09 34 aa 96 8c  |L..k.zW.....4...|
+00000330  4d 28 2e 9f f7 0b 1c 09  e1 d1 d8 48 6e 8a 8e 9c  |M(.........Hn...|
+00000340  01 4c e7 2d 53 8f 8e 71  61 82 ff ff 16 03 01 00  |.L.-S..qa.......|
+00000350  0e 0d 00 00 06 03 01 02  40 00 00 0e 00 00 00     |........@......|
 >>> Flow 3 (client to server)
 00000000  16 03 01 02 0a 0b 00 02  06 00 02 03 00 02 00 30  |...............0|
 00000010  82 01 fc 30 82 01 5e 02  09 00 9a 30 84 6c 26 35  |...0..^....0.l&5|
@@ -100,30 +101,30 @@
 00000220  51 88 35 75 71 b5 e5 54  5b 12 2e 8f 09 67 fd a7  |Q.5uq..T[....g..|
 00000230  24 20 3e b2 56 1c ce 97  28 5e f8 2b 2d 4f 9e f1  |$ >.V...(^.+-O..|
 00000240  07 9f 6c 4b 5b 83 56 e2  32 42 e9 58 b6 d7 49 a6  |..lK[.V.2B.X..I.|
-00000250  b5 68 1a 41 03 56 6b dc  5a 89 16 03 01 00 90 0f  |.h.A.Vk.Z.......|
-00000260  00 00 8c 00 8a 30 81 87  02 42 00 c6 85 8e 06 b7  |.....0...B......|
-00000270  04 04 e9 cd 9e 3e cb 66  23 95 b4 42 9c 64 81 39  |.....>.f#..B.d.9|
-00000280  05 3f b5 21 f8 28 af 60  6b 4d 3d ba a1 4b 5e 77  |.?.!.(.`kM=..K^w|
-00000290  ef e7 59 28 fe 1d c1 27  a2 ff a8 de 33 48 b3 c1  |..Y(...'....3H..|
-000002a0  85 6a 42 9b f9 7e 7e 31  c2 e5 bd 66 02 41 4b 49  |.jB..~~1...f.AKI|
-000002b0  c6 cd 02 e3 83 f7 03 50  18 6d b4 c9 51 02 c0 ab  |.......P.m..Q...|
-000002c0  87 bc e0 3e 4b 89 53 3a  e2 65 89 97 02 c1 87 f1  |...>K.S:.e......|
-000002d0  67 d0 f2 06 28 4e 51 4e  fd f0 01 be 41 3c 52 42  |g...(NQN....A<RB|
-000002e0  10 44 73 88 3e 44 24 bb  2e 77 01 77 6f a8 ac 14  |.Ds.>D$..w.wo...|
-000002f0  03 01 00 01 01 16 03 01  00 30 a3 da 45 22 96 83  |.........0..E"..|
-00000300  59 90 e9 6b ec 3b 77 50  05 89 e6 0c 61 d1 1d 2b  |Y..k.;wP....a..+|
-00000310  da d4 49 bf b9 c6 dd ad  c3 9c 82 bd 53 62 e8 57  |..I.........Sb.W|
-00000320  a4 6a e7 9f b1 d5 39 77  88 6d                    |.j....9w.m|
+00000250  b5 68 1a 41 03 56 6b dc  5a 89 16 03 01 00 91 0f  |.h.A.Vk.Z.......|
+00000260  00 00 8d 00 8b 30 81 88  02 42 01 91 2d e9 99 a4  |.....0...B..-...|
+00000270  88 5c 03 9c ea 8b 64 07  f2 c9 e7 ad 5b a3 fb 27  |.\....d.....[..'|
+00000280  fd 19 9b 78 bd 7b 9d 0a  cc 8a 61 c5 83 33 02 29  |...x.{....a..3.)|
+00000290  c3 66 24 9d 5f bc 03 d9  2a 49 aa 59 51 83 49 72  |.f$._...*I.YQ.Ir|
+000002a0  13 be ea 82 5a 5c 09 2f  da 23 bc 18 02 42 01 0d  |....Z\./.#...B..|
+000002b0  a1 15 4d fe 18 ec 90 d5  4e 9a 75 60 05 67 10 5e  |..M.....N.u`.g.^|
+000002c0  3c 34 00 e8 18 33 8f 90  26 2e d3 a9 81 6c 43 17  |<4...3..&....lC.|
+000002d0  80 9e c5 bd 23 c9 24 96  a1 29 23 a4 13 3f ad d2  |....#.$..)#..?..|
+000002e0  45 19 0b 56 56 4b c1 f1  cc 70 c8 af 44 ff 34 96  |E..VVK...p..D.4.|
+000002f0  14 03 01 00 01 01 16 03  01 00 30 c4 0c 67 53 06  |..........0..gS.|
+00000300  49 b3 c9 5c 2e 72 f6 54  ba ad ac a8 80 55 17 01  |I..\.r.T.....U..|
+00000310  5c 44 71 7d ad 15 34 95  9a 7f 7b 95 0e 08 70 ce  |\Dq}..4...{...p.|
+00000320  5a 33 f4 3b 4e 80 06 43  70 93 17                 |Z3.;N..Cp..|
 >>> Flow 4 (server to client)
-00000000  14 03 01 00 01 01 16 03  01 00 30 a4 45 dd 99 df  |..........0.E...|
-00000010  66 ae f5 c7 bd 1a eb 6a  ff ac a6 38 14 81 b5 07  |f......j...8....|
-00000020  86 24 80 f1 09 59 ad 33  3d 43 ed 9e 43 b1 1e 9f  |.$...Y.3=C..C...|
-00000030  bd 8c b3 e0 41 83 a1 34  91 c5 a1                 |....A..4...|
+00000000  14 03 01 00 01 01 16 03  01 00 30 3b ba 6c 73 ec  |..........0;.ls.|
+00000010  11 5b 44 46 1d bb 31 1b  1b e8 d8 51 4f 95 b0 40  |.[DF..1....QO..@|
+00000020  87 49 33 73 40 98 61 1c  94 02 48 9b 80 d3 6c af  |.I3s@.a...H...l.|
+00000030  e2 31 63 11 a7 c8 db ed  7a a4 4d                 |.1c.....z.M|
 >>> Flow 5 (client to server)
-00000000  17 03 01 00 20 ae e3 ae  7f 2d e3 a2 f7 1b 4e 69  |.... ....-....Ni|
-00000010  cb 18 c6 68 42 f8 de 61  92 4c fa d6 19 7c 8c 09  |...hB..a.L...|..|
-00000020  82 e2 f2 32 19 17 03 01  00 20 2a 77 65 1f c1 fd  |...2..... *we...|
-00000030  5e 37 b7 15 f6 1f 4c 7f  5f 89 52 b4 32 27 4d 17  |^7....L._.R.2'M.|
-00000040  33 c6 e8 50 ac 70 c8 b9  2d 0a 15 03 01 00 20 e0  |3..P.p..-..... .|
-00000050  cb ce 07 80 55 a0 46 ca  a7 25 4c 5f 9d 7c 73 37  |....U.F..%L_.|s7|
-00000060  de 72 6d 36 a8 e4 be fd  2a e7 f8 8d 14 80 b7     |.rm6....*......|
+00000000  17 03 01 00 20 2e f7 66  f0 ce 50 d7 38 7a d4 fd  |.... ..f..P.8z..|
+00000010  e3 66 b1 76 76 59 ad bc  b0 0a 75 1d f0 92 6e e3  |.f.vvY....u...n.|
+00000020  21 1d 13 dc ad 17 03 01  00 20 f1 b2 0f 3b 26 91  |!........ ...;&.|
+00000030  ed ff 9f fc 41 04 7e 47  17 02 af 0c 2b e8 b7 31  |....A.~G....+..1|
+00000040  ae 29 71 f9 a8 89 84 f3  e8 da 15 03 01 00 20 1f  |.)q........... .|
+00000050  26 64 cf 34 c1 48 6b 79  61 e2 77 57 9d 27 14 45  |&d.4.Hkya.wW.'.E|
+00000060  46 24 ad 2d 35 57 db 2b  32 03 e2 68 b0 1a 5a     |F$.-5W.+2..h..Z|
diff --git a/third_party/gofrontend/libgo/go/crypto/tls/testdata/Client-TLSv10-ClientCert-ECDSA-RSA b/third_party/gofrontend/libgo/go/crypto/tls/testdata/Client-TLSv10-ClientCert-ECDSA-RSA
index c0be824..0e420a6 100644
--- a/third_party/gofrontend/libgo/go/crypto/tls/testdata/Client-TLSv10-ClientCert-ECDSA-RSA
+++ b/third_party/gofrontend/libgo/go/crypto/tls/testdata/Client-TLSv10-ClientCert-ECDSA-RSA
@@ -1,18 +1,19 @@
 >>> Flow 1 (client to server)
-00000000  16 03 01 00 75 01 00 00  71 03 03 00 00 00 00 00  |....u...q.......|
+00000000  16 03 01 00 81 01 00 00  7d 03 03 00 00 00 00 00  |........}.......|
 00000010  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
-00000020  00 00 00 00 00 00 00 00  00 00 00 00 00 1a c0 2f  |.............../|
-00000030  c0 2b c0 11 c0 07 c0 13  c0 09 c0 14 c0 0a 00 05  |.+..............|
-00000040  00 2f 00 35 c0 12 00 0a  01 00 00 2e 00 05 00 05  |./.5............|
-00000050  01 00 00 00 00 00 0a 00  08 00 06 00 17 00 18 00  |................|
-00000060  19 00 0b 00 02 01 00 00  0d 00 0a 00 08 04 01 04  |................|
-00000070  03 02 01 02 03 ff 01 00  01 00                    |..........|
+00000020  00 00 00 00 00 00 00 00  00 00 00 00 00 1e c0 2f  |.............../|
+00000030  c0 2b c0 30 c0 2c c0 11  c0 07 c0 13 c0 09 c0 14  |.+.0.,..........|
+00000040  c0 0a 00 05 00 2f 00 35  c0 12 00 0a 01 00 00 36  |...../.5.......6|
+00000050  00 05 00 05 01 00 00 00  00 00 0a 00 08 00 06 00  |................|
+00000060  17 00 18 00 19 00 0b 00  02 01 00 00 0d 00 0e 00  |................|
+00000070  0c 04 01 04 03 05 01 05  03 02 01 02 03 ff 01 00  |................|
+00000080  01 00 00 12 00 00                                 |......|
 >>> Flow 2 (server to client)
-00000000  16 03 01 00 51 02 00 00  4d 03 01 53 04 f1 02 ed  |....Q...M..S....|
-00000010  86 9c 56 84 5a d3 7d d7  f3 4e 6f 2c 69 0d f0 59  |..V.Z.}..No,i..Y|
-00000020  a5 d1 de 2d 03 2f dd 63  c3 ab fa 20 30 d6 5a 24  |...-./.c... 0.Z$|
-00000030  5c 31 67 36 8d 4c 43 e1  64 c4 8a 2c a5 fd 39 92  |\1g6.LC.d..,..9.|
-00000040  c5 6f 58 47 a3 fe 63 14  98 92 11 90 00 05 00 00  |.oXG..c.........|
+00000000  16 03 01 00 51 02 00 00  4d 03 01 b7 de 52 5a 07  |....Q...M....RZ.|
+00000010  43 b8 72 1d d9 6f 5c a5  70 da ee 27 b7 a9 50 9d  |C.r..o\.p..'..P.|
+00000020  e7 75 ad 61 a5 2f 69 47  2a d8 2e 20 a8 b0 64 6b  |.u.a./iG*.. ..dk|
+00000030  4d 25 ec 50 2b 8e a7 9b  0c f9 f5 3c 62 96 a3 53  |M%.P+......<b..S|
+00000040  a7 4b af 33 1e e7 f8 43  b9 be 6e e7 00 05 00 00  |.K.3...C..n.....|
 00000050  05 ff 01 00 01 00 16 03  01 02 be 0b 00 02 ba 00  |................|
 00000060  02 b7 00 02 b4 30 82 02  b0 30 82 02 19 a0 03 02  |.....0...0......|
 00000070  01 02 02 09 00 85 b0 bb  a4 8a 7f b8 ca 30 0d 06  |.............0..|
@@ -101,25 +102,25 @@
 00000260  ce 39 4c 9c 86 00 08 c2  4b e2 c6 ec 2f f7 ce e6  |.9L.....K.../...|
 00000270  bd 77 82 6f 23 b6 e0 bd  a2 92 b7 3a ac e8 56 f1  |.w.o#......:..V.|
 00000280  af 54 5e 46 87 e9 3b 33  e7 b8 28 b7 d6 c8 90 35  |.T^F..;3..(....5|
-00000290  d4 1c 43 d1 30 6f 55 4e  0a 70 16 03 01 00 90 0f  |..C.0oUN.p......|
-000002a0  00 00 8c 00 8a 30 81 87  02 42 00 c6 85 8e 06 b7  |.....0...B......|
-000002b0  04 04 e9 cd 9e 3e cb 66  23 95 b4 42 9c 64 81 39  |.....>.f#..B.d.9|
-000002c0  05 3f b5 21 f8 28 af 60  6b 4d 3d ba a1 4b 5e 77  |.?.!.(.`kM=..K^w|
-000002d0  ef e7 59 28 fe 1d c1 27  a2 ff a8 de 33 48 b3 c1  |..Y(...'....3H..|
-000002e0  85 6a 42 9b f9 7e 7e 31  c2 e5 bd 66 02 41 4b 49  |.jB..~~1...f.AKI|
-000002f0  c6 cd 02 e3 83 f7 03 50  18 6d b4 c9 51 02 c0 ab  |.......P.m..Q...|
-00000300  87 bc e0 3e 4b 89 53 3a  e2 65 89 97 02 c1 87 f1  |...>K.S:.e......|
-00000310  67 d0 f2 06 28 4e 51 4e  fd f0 01 47 e7 c9 d9 23  |g...(NQN...G...#|
-00000320  21 6b 87 d2 55 e3 c9 f7  eb 86 d5 1e 50 df d5 14  |!k..U.......P...|
-00000330  03 01 00 01 01 16 03 01  00 24 95 62 42 be 90 39  |.........$.bB..9|
-00000340  68 ae f5 77 47 21 14 b9  ac ee 81 2d e3 9e c7 34  |h..wG!.....-...4|
-00000350  3a 00 5c c9 12 1d c0 5a  7c e7 ef e0 cd fd        |:.\....Z|.....|
+00000290  d4 1c 43 d1 30 6f 55 4e  0a 70 16 03 01 00 91 0f  |..C.0oUN.p......|
+000002a0  00 00 8d 00 8b 30 81 88  02 42 00 b5 1a 9d 48 90  |.....0...B....H.|
+000002b0  2f d9 1a 04 66 f7 3b 4d  d7 ae d9 1e dd 3c fa 24  |/...f.;M.....<.$|
+000002c0  0f 24 97 b2 61 46 16 d9  a0 35 f9 f7 54 45 92 fd  |.$..aF...5..TE..|
+000002d0  10 56 ab 26 d7 b5 10 80  8b 88 95 ef c6 73 1c d2  |.V.&.........s..|
+000002e0  ff e9 20 cd 18 a8 40 c4  4d 83 c2 e2 02 42 01 8c  |.. ...@.M....B..|
+000002f0  d2 13 4c cc e5 38 37 17  6c 83 d6 ad c1 dc af ec  |..L..87.l.......|
+00000300  8d 06 75 b8 08 ad 56 4a  8f b9 03 59 80 f8 81 d4  |..u...VJ...Y....|
+00000310  f3 91 89 eb 9c 27 5d e1  dc 6d ef d6 20 da e7 9c  |.....']..m.. ...|
+00000320  71 75 cb 2a f9 e4 05 46  c8 85 ca 7b 9c 97 e8 6d  |qu.*...F...{...m|
+00000330  14 03 01 00 01 01 16 03  01 00 24 9f 67 4e 22 04  |..........$.gN".|
+00000340  10 f4 28 55 3e 50 88 90  61 07 42 29 f5 9b f5 32  |..(U>P..a.B)...2|
+00000350  16 3d ea c1 8f aa a1 4c  b5 72 26 d8 32 cd 50     |.=.....L.r&.2.P|
 >>> Flow 4 (server to client)
-00000000  14 03 01 00 01 01 16 03  01 00 24 ea 98 c0 fb 86  |..........$.....|
-00000010  87 7a 2e e1 c7 68 61 3e  5b cc da 1f d6 7b ab 5a  |.z...ha>[....{.Z|
-00000020  a0 ae a2 cf d0 54 44 19  12 db 75 2b 8c 73 8c     |.....TD...u+.s.|
+00000000  14 03 01 00 01 01 16 03  01 00 24 df 8d f1 07 6d  |..........$....m|
+00000010  63 39 fc ba b1 67 3b 68  85 b9 37 7d d3 67 19 76  |c9...g;h..7}.g.v|
+00000020  34 a4 1b 86 31 bd fe 06  72 00 d8 2b f2 65 3d     |4...1...r..+.e=|
 >>> Flow 5 (client to server)
-00000000  17 03 01 00 1a f3 28 77  31 33 4c b3 7c 4b 75 61  |......(w13L.|Kua|
-00000010  38 69 6b ae c9 36 ab 2e  56 16 29 6a 9a 00 2f 15  |8ik..6..V.)j../.|
-00000020  03 01 00 16 6b ed 68 18  ed ff 44 39 9b 4a e4 a2  |....k.h...D9.J..|
-00000030  cd 79 ef 2a 3e 5a 4d b1  5d 56                    |.y.*>ZM.]V|
+00000000  17 03 01 00 1a 60 cc 81  4f 8b 73 b3 7f 34 bf f1  |.....`..O.s..4..|
+00000010  7c d8 32 0a ef 2a 26 f9  b8 69 84 83 48 21 ee 15  ||.2..*&..i..H!..|
+00000020  03 01 00 16 23 7a 0c 65  3a 66 1a 75 03 e4 85 3f  |....#z.e:f.u...?|
+00000030  83 cd 55 70 99 f4 44 dc  67 ba                    |..Up..D.g.|
diff --git a/third_party/gofrontend/libgo/go/crypto/tls/testdata/Client-TLSv10-ClientCert-RSA-ECDSA b/third_party/gofrontend/libgo/go/crypto/tls/testdata/Client-TLSv10-ClientCert-RSA-ECDSA
index 3e6dbc2..7e33edc 100644
--- a/third_party/gofrontend/libgo/go/crypto/tls/testdata/Client-TLSv10-ClientCert-RSA-ECDSA
+++ b/third_party/gofrontend/libgo/go/crypto/tls/testdata/Client-TLSv10-ClientCert-RSA-ECDSA
@@ -1,18 +1,19 @@
 >>> Flow 1 (client to server)
-00000000  16 03 01 00 75 01 00 00  71 03 03 00 00 00 00 00  |....u...q.......|
+00000000  16 03 01 00 81 01 00 00  7d 03 03 00 00 00 00 00  |........}.......|
 00000010  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
-00000020  00 00 00 00 00 00 00 00  00 00 00 00 00 1a c0 2f  |.............../|
-00000030  c0 2b c0 11 c0 07 c0 13  c0 09 c0 14 c0 0a 00 05  |.+..............|
-00000040  00 2f 00 35 c0 12 00 0a  01 00 00 2e 00 05 00 05  |./.5............|
-00000050  01 00 00 00 00 00 0a 00  08 00 06 00 17 00 18 00  |................|
-00000060  19 00 0b 00 02 01 00 00  0d 00 0a 00 08 04 01 04  |................|
-00000070  03 02 01 02 03 ff 01 00  01 00                    |..........|
+00000020  00 00 00 00 00 00 00 00  00 00 00 00 00 1e c0 2f  |.............../|
+00000030  c0 2b c0 30 c0 2c c0 11  c0 07 c0 13 c0 09 c0 14  |.+.0.,..........|
+00000040  c0 0a 00 05 00 2f 00 35  c0 12 00 0a 01 00 00 36  |...../.5.......6|
+00000050  00 05 00 05 01 00 00 00  00 00 0a 00 08 00 06 00  |................|
+00000060  17 00 18 00 19 00 0b 00  02 01 00 00 0d 00 0e 00  |................|
+00000070  0c 04 01 04 03 05 01 05  03 02 01 02 03 ff 01 00  |................|
+00000080  01 00 00 12 00 00                                 |......|
 >>> Flow 2 (server to client)
-00000000  16 03 01 00 59 02 00 00  55 03 01 53 04 f1 02 4f  |....Y...U..S...O|
-00000010  73 06 2d 72 41 36 a1 b2  d3 50 97 55 8c c5 f1 43  |s.-rA6...P.U...C|
-00000020  37 1f 1a 2a fe 51 70 0b  2f 25 9e 20 50 61 86 80  |7..*.Qp./%. Pa..|
-00000030  9a 9c 6d 6f c9 ea 5c ce  0c b7 7c ce e3 be d0 e5  |..mo..\...|.....|
-00000040  be d0 c4 80 78 c3 c7 17  0c 2d 8e c8 c0 09 00 00  |....x....-......|
+00000000  16 03 01 00 59 02 00 00  55 03 01 dc a9 22 c2 a2  |....Y...U...."..|
+00000010  05 ba c4 66 9a 71 aa 0f  92 6a fc df b0 29 4d 36  |...f.q...j...)M6|
+00000020  39 2e f8 39 ed 8e f6 7f  8f 17 13 20 f8 9c f3 3d  |9..9....... ...=|
+00000030  0a 41 8f 30 c7 5d cd 17  c5 ad 1c 52 45 a3 47 8c  |.A.0.].....RE.G.|
+00000040  07 4c 48 e1 00 2b 32 38  01 c8 79 b7 c0 09 00 00  |.LH..+28..y.....|
 00000050  0d ff 01 00 01 00 00 0b  00 04 03 00 01 02 16 03  |................|
 00000060  01 02 0e 0b 00 02 0a 00  02 07 00 02 04 30 82 02  |.............0..|
 00000070  00 30 82 01 62 02 09 00  b8 bf 2d 47 a0 d2 eb f4  |.0..b.....-G....|
@@ -47,21 +48,21 @@
 00000240  13 83 0d 94 06 bb d4 37  7a f6 ec 7a c9 86 2e dd  |.......7z..z....|
 00000250  d7 11 69 7f 85 7c 56 de  fb 31 78 2b e4 c7 78 0d  |..i..|V..1x+..x.|
 00000260  ae cb be 9e 4e 36 24 31  7b 6a 0f 39 95 12 07 8f  |....N6$1{j.9....|
-00000270  2a 16 03 01 00 d6 0c 00  00 d2 03 00 17 41 04 b1  |*............A..|
-00000280  0f 0f 4a 18 ed 25 32 b3  a3 19 ed 4b 61 b6 eb e4  |..J..%2....Ka...|
-00000290  d3 f7 77 13 ac 9f 60 c7  8d 6d cb f1 ee 99 1a 71  |..w...`..m.....q|
-000002a0  68 aa d3 a7 70 7f 38 d0  f6 23 ab 9a f6 dd 19 4f  |h...p.8..#.....O|
-000002b0  ce 10 ef d5 cf 64 85 2f  75 f6 20 06 4b f0 b9 00  |.....d./u. .K...|
-000002c0  8b 30 81 88 02 42 01 00  b9 6b 80 91 59 0a 48 3f  |.0...B...k..Y.H?|
-000002d0  72 16 96 8f 21 2c 28 e4  6d 03 74 66 35 16 7d ec  |r...!,(.m.tf5.}.|
-000002e0  c7 08 9b 52 b5 05 d9 38  d8 b7 51 42 a7 4a 9f 9b  |...R...8..QB.J..|
-000002f0  1a 37 14 de c5 f5 16 96  83 81 58 d3 a6 1e ce 8a  |.7........X.....|
-00000300  bc 19 47 30 fe c5 85 55  02 42 01 4f 61 59 68 85  |..G0...U.B.OaYh.|
-00000310  c7 64 23 22 f6 83 53 cc  58 38 25 b5 ce 74 c1 68  |.d#"..S.X8%..t.h|
-00000320  9f 32 72 33 ea c9 62 e0  26 63 92 e3 5f 34 10 0b  |.2r3..b.&c.._4..|
-00000330  3c d5 83 fe 9f 67 69 ef  33 6b 19 c1 ec d6 6c 35  |<....gi.3k....l5|
-00000340  89 33 17 d3 9d 93 e2 e5  6e 89 9a a1 16 03 01 00  |.3......n.......|
-00000350  0e 0d 00 00 06 03 01 02  40 00 00 0e 00 00 00     |........@......|
+00000270  2a 16 03 01 00 d5 0c 00  00 d1 03 00 17 41 04 89  |*............A..|
+00000280  95 9a 90 82 59 ab 29 bf  10 06 8c 6c 0d 67 cf b1  |....Y.)....l.g..|
+00000290  66 8b 5e 43 b8 46 56 3a  8d 30 92 35 28 82 f2 38  |f.^C.FV:.0.5(..8|
+000002a0  6e 19 5d 37 f0 ab fc 78  15 6a 6a 73 ca dc a6 f2  |n.]7...x.jjs....|
+000002b0  68 5d b3 ab 6d 68 44 3b  80 d2 d9 cd 78 0a ed 00  |h]..mhD;....x...|
+000002c0  8a 30 81 87 02 42 01 80  63 4a 22 4c 8e 66 4e 25  |.0...B..cJ"L.fN%|
+000002d0  e1 86 27 81 de eb b3 a0  c4 dc dc e2 a0 94 2a b6  |..'...........*.|
+000002e0  b3 e9 e7 42 e1 1d 1a c0  43 8d a1 d6 8d 77 84 06  |...B....C....w..|
+000002f0  ba 95 99 e3 54 80 59 4e  3c fb 0c f3 b7 d3 a8 d2  |....T.YN<.......|
+00000300  ce 49 97 fb e2 79 91 93  02 41 2b 2c b7 9f 81 ea  |.I...y...A+,....|
+00000310  de 17 12 af 4d 20 bc a1  43 1d 60 a0 37 52 a2 7b  |....M ..C.`.7R.{|
+00000320  a8 4c de fd 1d fe 37 3b  00 23 61 ce d2 80 47 43  |.L....7;.#a...GC|
+00000330  b0 3a f3 1f aa c7 07 b1  68 5b d8 f3 03 a9 56 5c  |.:......h[....V\|
+00000340  63 ef 83 1d 9c 9c 8d 29  81 e9 3b 16 03 01 00 0e  |c......)..;.....|
+00000350  0d 00 00 06 03 01 02 40  00 00 0e 00 00 00        |.......@......|
 >>> Flow 3 (client to server)
 00000000  16 03 01 01 fb 0b 00 01  f7 00 01 f4 00 01 f1 30  |...............0|
 00000010  82 01 ed 30 82 01 58 a0  03 02 01 02 02 01 00 30  |...0..X........0|
@@ -100,29 +101,29 @@
 00000220  a7 24 20 3e b2 56 1c ce  97 28 5e f8 2b 2d 4f 9e  |.$ >.V...(^.+-O.|
 00000230  f1 07 9f 6c 4b 5b 83 56  e2 32 42 e9 58 b6 d7 49  |...lK[.V.2B.X..I|
 00000240  a6 b5 68 1a 41 03 56 6b  dc 5a 89 16 03 01 00 86  |..h.A.Vk.Z......|
-00000250  0f 00 00 82 00 80 20 2c  5a 08 3a 00 33 50 19 b2  |...... ,Z.:.3P..|
-00000260  0f ba 6c 76 7f 5c 92 e2  78 55 3e 32 32 bb 33 bc  |..lv.\..xU>22.3.|
-00000270  ab a9 34 e0 83 cf 82 cd  9e 6b 3f 9d e6 49 61 29  |..4......k?..Ia)|
-00000280  8b b4 ed e8 12 cd a9 52  86 11 48 64 08 61 72 8d  |.......R..Hd.ar.|
-00000290  d6 6a ac 42 cc e4 07 5f  08 56 9f 2f c5 35 d3 9b  |.j.B..._.V./.5..|
-000002a0  e9 0d 91 82 c0 e9 bb 9f  a9 8f df 96 85 08 9a 69  |...............i|
-000002b0  a4 93 b3 72 37 ba f9 b1  a4 0b b0 9f 43 6a 15 ec  |...r7.......Cj..|
-000002c0  79 b8 fd 9c 1f 5f 0d 2c  56 33 c7 15 d5 4a b7 82  |y...._.,V3...J..|
-000002d0  ea 44 80 20 c5 80 14 03  01 00 01 01 16 03 01 00  |.D. ............|
-000002e0  30 c9 c0 7c d7 57 d3 00  ab 87 eb 78 56 6b a1 69  |0..|.W.....xVk.i|
-000002f0  1d fa ec ae 38 f3 ef 5d  49 19 0d 4b f0 73 63 af  |....8..]I..K.sc.|
-00000300  89 b6 cb 76 cf fb b9 c1  99 98 06 0a 54 67 a0 6e  |...v........Tg.n|
-00000310  e7                                                |.|
+00000250  0f 00 00 82 00 80 0e 80  9c 3a 6e 40 51 09 39 d4  |.........:n@Q.9.|
+00000260  40 58 10 da 7f 32 12 08  9e f0 4d 9a d7 20 a2 9c  |@X...2....M.. ..|
+00000270  b0 95 3a 33 4e f8 b1 a3  74 62 ab 51 7d 23 d4 32  |..:3N...tb.Q}#.2|
+00000280  a2 af b8 5a 3b b0 23 e4  7a f1 eb 4d b7 bb 23 d5  |...Z;.#.z..M..#.|
+00000290  a9 0d b4 81 d2 b4 45 bd  15 52 ad 58 da 92 a2 c4  |......E..R.X....|
+000002a0  30 66 87 f2 ae c5 e4 8c  fa ba a0 40 76 b8 3f 72  |0f.........@v.?r|
+000002b0  2a d9 95 2a 2d c6 05 3c  1e 2f 11 ef c5 3c 11 e4  |*..*-..<./...<..|
+000002c0  be 5a de 37 43 7f 74 52  6e ee 3c 39 cc f1 14 05  |.Z.7C.tRn.<9....|
+000002d0  2d 91 c2 3d c4 7c 14 03  01 00 01 01 16 03 01 00  |-..=.|..........|
+000002e0  30 cd 3c 92 f8 b9 36 7a  e7 8a fb 0f 2f b8 2c 7b  |0.<...6z..../.,{|
+000002f0  10 59 45 14 0a b0 6a 8c  31 b2 89 5b ac 19 dc 12  |.YE...j.1..[....|
+00000300  73 8c 8c 10 49 5a bf 9f  bc 58 82 32 11 ba c5 38  |s...IZ...X.2...8|
+00000310  ff                                                |.|
 >>> Flow 4 (server to client)
-00000000  14 03 01 00 01 01 16 03  01 00 30 20 db fd ed ed  |..........0 ....|
-00000010  7c d5 bf 8f 06 3b 86 1b  c1 60 7d a4 74 e9 a6 c9  ||....;...`}.t...|
-00000020  f5 7c c7 f4 65 91 06 d5  53 88 d7 57 a4 22 b6 1f  |.|..e...S..W."..|
-00000030  f1 02 e9 79 36 e6 a1 22  51 3a 4c                 |...y6.."Q:L|
+00000000  14 03 01 00 01 01 16 03  01 00 30 da 45 99 fe 52  |..........0.E..R|
+00000010  4f cd d0 e6 30 19 f4 bd  80 6d 5c 8a 72 03 d3 88  |O...0....m\.r...|
+00000020  38 63 e9 c9 39 ee ab 3f  52 26 84 b0 4d cb 5c a4  |8c..9..?R&..M.\.|
+00000030  0d 51 c7 47 48 43 3a bf  89 c7 13                 |.Q.GHC:....|
 >>> Flow 5 (client to server)
-00000000  17 03 01 00 20 00 66 51  6a 14 ca ea e2 21 48 74  |.... .fQj....!Ht|
-00000010  c4 c1 6e b9 8b 23 af 7c  33 c9 00 f8 0b ec ab 35  |..n..#.|3......5|
-00000020  e7 42 0a d1 ae 17 03 01  00 20 00 1c 6d 60 75 5d  |.B....... ..m`u]|
-00000030  b3 fb 40 2e e0 b7 0d 48  f4 87 ac d4 bf ea 01 0d  |..@....H........|
-00000040  fe 10 0d 05 04 43 6b 19  ed f2 15 03 01 00 20 f8  |.....Ck....... .|
-00000050  03 ac 62 4b 1f db 2e d2  4e 00 c3 a4 57 3c 0a 62  |..bK....N...W<.b|
-00000060  05 a0 ef bd 2b 9b 9a 63  27 72 d7 d8 f1 8d 84     |....+..c'r.....|
+00000000  17 03 01 00 20 4d d9 1d  0d 3d 8b 73 91 b9 4e 5e  |.... M...=.s..N^|
+00000010  35 71 4f 67 79 d2 f7 39  35 ea 23 d0 6d 64 de a5  |5qOgy..95.#.md..|
+00000020  59 fb 75 1f c9 17 03 01  00 20 ba bd 3c b4 d7 be  |Y.u...... ..<...|
+00000030  24 64 68 1e 8c b2 bf 6f  78 9f ad 7f fa dd 89 a6  |$dh....ox.......|
+00000040  f9 e7 5e 70 db e9 db 3a  62 b2 15 03 01 00 20 2a  |..^p...:b..... *|
+00000050  82 f4 8b 45 fc 76 35 6c  54 48 62 2f 52 55 f2 d9  |...E.v5lTHb/RU..|
+00000060  99 b2 b5 2d 5f a0 05 ab  f1 93 58 75 4a 87 35     |...-_.....XuJ.5|
diff --git a/third_party/gofrontend/libgo/go/crypto/tls/testdata/Client-TLSv10-ClientCert-RSA-RSA b/third_party/gofrontend/libgo/go/crypto/tls/testdata/Client-TLSv10-ClientCert-RSA-RSA
index 94e6860..9b1a553 100644
--- a/third_party/gofrontend/libgo/go/crypto/tls/testdata/Client-TLSv10-ClientCert-RSA-RSA
+++ b/third_party/gofrontend/libgo/go/crypto/tls/testdata/Client-TLSv10-ClientCert-RSA-RSA
@@ -1,18 +1,19 @@
 >>> Flow 1 (client to server)
-00000000  16 03 01 00 75 01 00 00  71 03 03 00 00 00 00 00  |....u...q.......|
+00000000  16 03 01 00 81 01 00 00  7d 03 03 00 00 00 00 00  |........}.......|
 00000010  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
-00000020  00 00 00 00 00 00 00 00  00 00 00 00 00 1a c0 2f  |.............../|
-00000030  c0 2b c0 11 c0 07 c0 13  c0 09 c0 14 c0 0a 00 05  |.+..............|
-00000040  00 2f 00 35 c0 12 00 0a  01 00 00 2e 00 05 00 05  |./.5............|
-00000050  01 00 00 00 00 00 0a 00  08 00 06 00 17 00 18 00  |................|
-00000060  19 00 0b 00 02 01 00 00  0d 00 0a 00 08 04 01 04  |................|
-00000070  03 02 01 02 03 ff 01 00  01 00                    |..........|
+00000020  00 00 00 00 00 00 00 00  00 00 00 00 00 1e c0 2f  |.............../|
+00000030  c0 2b c0 30 c0 2c c0 11  c0 07 c0 13 c0 09 c0 14  |.+.0.,..........|
+00000040  c0 0a 00 05 00 2f 00 35  c0 12 00 0a 01 00 00 36  |...../.5.......6|
+00000050  00 05 00 05 01 00 00 00  00 00 0a 00 08 00 06 00  |................|
+00000060  17 00 18 00 19 00 0b 00  02 01 00 00 0d 00 0e 00  |................|
+00000070  0c 04 01 04 03 05 01 05  03 02 01 02 03 ff 01 00  |................|
+00000080  01 00 00 12 00 00                                 |......|
 >>> Flow 2 (server to client)
-00000000  16 03 01 00 51 02 00 00  4d 03 01 53 04 f1 02 73  |....Q...M..S...s|
-00000010  ee 5f 70 a4 aa 0d be d7  46 a3 25 3f e3 5d ef 7b  |._p.....F.%?.].{|
-00000020  73 49 7c b6 82 4d 99 2f  31 fc 8b 20 2d a3 33 7c  |sI|..M./1.. -.3||
-00000030  a5 c3 85 86 ba 61 4d 05  b0 5e d3 5e 88 6e c3 4b  |.....aM..^.^.n.K|
-00000040  95 d3 e9 67 f1 96 24 58  7a 6f e6 c5 00 05 00 00  |...g..$Xzo......|
+00000000  16 03 01 00 51 02 00 00  4d 03 01 90 e6 e1 c6 bd  |....Q...M.......|
+00000010  86 08 db 33 94 f3 bd 0b  2d fc e0 ba 89 a7 c5 66  |...3....-......f|
+00000020  a5 19 78 33 2b b9 c4 22  d8 e0 63 20 2e 85 53 25  |..x3+.."..c ..S%|
+00000030  f2 22 e3 ca 79 94 9e 50  00 13 da 9d 21 33 49 27  |."..y..P....!3I'|
+00000040  9b 44 c5 10 bc e8 44 01  04 31 02 81 00 05 00 00  |.D....D..1......|
 00000050  05 ff 01 00 01 00 16 03  01 02 be 0b 00 02 ba 00  |................|
 00000060  02 b7 00 02 b4 30 82 02  b0 30 82 02 19 a0 03 02  |.....0...0......|
 00000070  01 02 02 09 00 85 b0 bb  a4 8a 7f b8 ca 30 0d 06  |.............0..|
@@ -101,24 +102,24 @@
 00000260  e6 bd 77 82 6f 23 b6 e0  bd a2 92 b7 3a ac e8 56  |..w.o#......:..V|
 00000270  f1 af 54 5e 46 87 e9 3b  33 e7 b8 28 b7 d6 c8 90  |..T^F..;3..(....|
 00000280  35 d4 1c 43 d1 30 6f 55  4e 0a 70 16 03 01 00 86  |5..C.0oUN.p.....|
-00000290  0f 00 00 82 00 80 0f 4c  d2 b2 f0 94 6d 61 d1 2c  |.......L....ma.,|
-000002a0  db 6f 79 03 bd 40 b2 d2  1d 61 ef 83 1b 4a 0c 7b  |.oy..@...a...J.{|
-000002b0  c5 73 1e 1a 81 e7 67 0a  d6 aa 2d 04 04 cc 0e 4b  |.s....g...-....K|
-000002c0  2e da 96 7f 15 6c 05 ee  c4 53 7e 33 89 28 7d db  |.....l...S~3.(}.|
-000002d0  a1 77 43 ba a3 51 a9 1c  b9 f5 ec 9a 8d eb 2c 46  |.wC..Q........,F|
-000002e0  5c 33 59 6b 16 af de f4  9b 80 76 a3 22 30 5d bb  |\3Yk......v."0].|
-000002f0  02 b9 77 96 8a db 36 9f  54 95 00 d8 58 e1 aa 04  |..w...6.T...X...|
-00000300  98 c9 0c 32 ae 62 81 12  0c f6 1b 76 c6 58 a7 8c  |...2.b.....v.X..|
-00000310  0e d8 b7 8e ed 0f 14 03  01 00 01 01 16 03 01 00  |................|
-00000320  24 1d c0 20 02 2d da 69  54 29 8c ff af 5c 56 a8  |$.. .-.iT)...\V.|
-00000330  eb d0 09 95 29 8f 52 8c  e2 7b 9f 36 3e 47 a0 33  |....).R..{.6>G.3|
-00000340  2e 63 a2 24 93                                    |.c.$.|
+00000290  0f 00 00 82 00 80 10 19  57 14 c3 ee 2d da cb de  |........W...-...|
+000002a0  f3 70 c5 62 91 2f ad 62  dd 10 f1 65 20 a2 cf d5  |.p.b./.b...e ...|
+000002b0  cd 6d 5f e4 b3 3e 38 e8  d0 1a f7 f0 e7 7e b6 5d  |.m_..>8......~.]|
+000002c0  c3 6c ad f6 0d 05 1e 41  35 2d 04 15 3c 36 96 00  |.l.....A5-..<6..|
+000002d0  e8 02 b2 01 b8 9f 21 4b  34 85 ef 5e 4c 87 ef 49  |......!K4..^L..I|
+000002e0  df d1 9a b6 b2 bd b8 90  fd 3f 31 93 0c dc c7 18  |.........?1.....|
+000002f0  ff f6 76 bd 5b 74 76 b3  62 87 6a df ff 63 15 d5  |..v.[tv.b.j..c..|
+00000300  94 d5 fe fd 4c 12 df f1  35 07 f1 8a f1 77 7a 35  |....L...5....wz5|
+00000310  cd 99 1d 2a d7 9a 14 03  01 00 01 01 16 03 01 00  |...*............|
+00000320  24 8d db 0c 87 b5 df fd  68 de fe 46 3e e4 41 b5  |$.......h..F>.A.|
+00000330  19 64 68 3c c4 e2 2b 43  50 e4 ee 52 75 34 d3 c1  |.dh<..+CP..Ru4..|
+00000340  51 18 c0 b2 5f                                    |Q..._|
 >>> Flow 4 (server to client)
-00000000  14 03 01 00 01 01 16 03  01 00 24 99 e8 fb 65 f4  |..........$...e.|
-00000010  95 ae 8b 71 cc 5d a4 95  a7 27 98 fd 16 3f 7a 1a  |...q.]...'...?z.|
-00000020  b6 bd bf 0a 58 72 77 97  1f 8e b1 dd 4b 12 12     |....Xrw.....K..|
+00000000  14 03 01 00 01 01 16 03  01 00 24 0b a4 04 46 60  |..........$...F`|
+00000010  15 fb 9a 9f 47 51 6d b4  4b c6 e7 2a 1b 98 b4 8a  |....GQm.K..*....|
+00000020  8a 1a 03 cf f4 16 7d 80  70 27 e5 e8 d5 9f ad     |......}.p'.....|
 >>> Flow 5 (client to server)
-00000000  17 03 01 00 1a 42 70 c0  89 78 12 5c 91 7e 88 2d  |.....Bp..x.\.~.-|
-00000010  2f 8f be f2 f2 12 9d 81  ae 78 08 38 5e 6d 1b 15  |/........x.8^m..|
-00000020  03 01 00 16 1a 64 b1 6f  8a ff d3 63 6a c7 b8 95  |.....d.o...cj...|
-00000030  3d b0 87 bc 62 e9 88 5b  26 bd                    |=...b..[&.|
+00000000  17 03 01 00 1a 6f 84 50  27 c7 f1 aa b0 04 7d 80  |.....o.P'.....}.|
+00000010  6d a7 20 8a 73 cf d9 de  9a d6 f5 e9 36 13 7c 15  |m. .s.......6.|.|
+00000020  03 01 00 16 e8 0b e0 a6  3b 1e 21 24 65 4e 49 b2  |........;.!$eNI.|
+00000030  2d a3 41 2b 98 23 4e d5  4b fd                    |-.A+.#N.K.|
diff --git a/third_party/gofrontend/libgo/go/crypto/tls/testdata/Client-TLSv10-ECDHE-ECDSA-AES b/third_party/gofrontend/libgo/go/crypto/tls/testdata/Client-TLSv10-ECDHE-ECDSA-AES
index 30c4c6b..937c290 100644
--- a/third_party/gofrontend/libgo/go/crypto/tls/testdata/Client-TLSv10-ECDHE-ECDSA-AES
+++ b/third_party/gofrontend/libgo/go/crypto/tls/testdata/Client-TLSv10-ECDHE-ECDSA-AES
@@ -1,18 +1,19 @@
 >>> Flow 1 (client to server)
-00000000  16 03 01 00 75 01 00 00  71 03 03 00 00 00 00 00  |....u...q.......|
+00000000  16 03 01 00 81 01 00 00  7d 03 03 00 00 00 00 00  |........}.......|
 00000010  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
-00000020  00 00 00 00 00 00 00 00  00 00 00 00 00 1a c0 2f  |.............../|
-00000030  c0 2b c0 11 c0 07 c0 13  c0 09 c0 14 c0 0a 00 05  |.+..............|
-00000040  00 2f 00 35 c0 12 00 0a  01 00 00 2e 00 05 00 05  |./.5............|
-00000050  01 00 00 00 00 00 0a 00  08 00 06 00 17 00 18 00  |................|
-00000060  19 00 0b 00 02 01 00 00  0d 00 0a 00 08 04 01 04  |................|
-00000070  03 02 01 02 03 ff 01 00  01 00                    |..........|
+00000020  00 00 00 00 00 00 00 00  00 00 00 00 00 1e c0 2f  |.............../|
+00000030  c0 2b c0 30 c0 2c c0 11  c0 07 c0 13 c0 09 c0 14  |.+.0.,..........|
+00000040  c0 0a 00 05 00 2f 00 35  c0 12 00 0a 01 00 00 36  |...../.5.......6|
+00000050  00 05 00 05 01 00 00 00  00 00 0a 00 08 00 06 00  |................|
+00000060  17 00 18 00 19 00 0b 00  02 01 00 00 0d 00 0e 00  |................|
+00000070  0c 04 01 04 03 05 01 05  03 02 01 02 03 ff 01 00  |................|
+00000080  01 00 00 12 00 00                                 |......|
 >>> Flow 2 (server to client)
-00000000  16 03 01 00 59 02 00 00  55 03 01 53 04 f1 02 b2  |....Y...U..S....|
-00000010  e0 f6 f6 b5 c9 5b 28 d0  5d 58 1b 6f 4e 2b 9d 05  |.....[(.]X.oN+..|
-00000020  2a b9 b4 da 45 cf f3 10  b2 23 44 20 f8 4d 59 05  |*...E....#D .MY.|
-00000030  ad 27 f2 a0 ee 7f ec cc  20 dc e7 a2 1b 07 b3 a5  |.'...... .......|
-00000040  37 7e 61 3d d6 5c 03 cf  cc f5 9b ca c0 09 00 00  |7~a=.\..........|
+00000000  16 03 01 00 59 02 00 00  55 03 01 f5 8f 8d 8e ca  |....Y...U.......|
+00000010  30 6b fe 63 c9 84 57 c0  f1 c8 a5 d8 10 56 14 62  |0k.c..W......V.b|
+00000020  c8 02 b2 89 21 5c 09 67  86 d8 9b 20 dc 3f 55 54  |....!\.g... .?UT|
+00000030  33 29 47 45 d3 e0 87 1a  4b 1b 75 30 89 e0 4d 01  |3)GE....K.u0..M.|
+00000040  a1 6a 46 f7 8f 23 d6 74  fd 90 2f 53 c0 09 00 00  |.jF..#.t../S....|
 00000050  0d ff 01 00 01 00 00 0b  00 04 03 00 01 02 16 03  |................|
 00000060  01 02 0e 0b 00 02 0a 00  02 07 00 02 04 30 82 02  |.............0..|
 00000070  00 30 82 01 62 02 09 00  b8 bf 2d 47 a0 d2 eb f4  |.0..b.....-G....|
@@ -47,20 +48,20 @@
 00000240  13 83 0d 94 06 bb d4 37  7a f6 ec 7a c9 86 2e dd  |.......7z..z....|
 00000250  d7 11 69 7f 85 7c 56 de  fb 31 78 2b e4 c7 78 0d  |..i..|V..1x+..x.|
 00000260  ae cb be 9e 4e 36 24 31  7b 6a 0f 39 95 12 07 8f  |....N6$1{j.9....|
-00000270  2a 16 03 01 00 d5 0c 00  00 d1 03 00 17 41 04 da  |*............A..|
-00000280  5a fd 09 e5 d6 c0 70 41  5e 3a 87 eb df 0c ad 90  |Z.....pA^:......|
-00000290  22 8a 2f 90 81 0c 24 00  68 92 f3 d5 95 2f 93 43  |"./...$.h..../.C|
-000002a0  e9 58 2d 18 28 62 ee 33  5b 21 2e 49 87 21 4d 32  |.X-.(b.3[!.I.!M2|
-000002b0  32 19 b3 ba fe 2d 9a 85  12 0e a1 77 08 06 75 00  |2....-.....w..u.|
-000002c0  8a 30 81 87 02 42 01 91  14 fc 68 74 95 10 4b d4  |.0...B....ht..K.|
-000002d0  67 60 12 46 bb b0 f6 98  77 a3 41 b8 01 5c 49 54  |g`.F....w.A..\IT|
-000002e0  9e 3e 81 e7 97 a3 b9 73  6e 15 74 67 be e5 d9 eb  |.>.....sn.tg....|
-000002f0  8b 87 c5 22 ab ab 58 28  4f d1 b6 80 94 1b f5 f7  |..."..X(O.......|
-00000300  12 43 ef 0a c7 3e 1a 76  02 41 7a 00 49 cb 9f 3b  |.C...>.v.Az.I..;|
-00000310  91 6e 38 58 0a d3 d0 d1  ee 67 f0 b6 5d cd fa 23  |.n8X.....g..]..#|
-00000320  b6 98 43 af 9c 71 90 1e  1d 50 a2 6e 61 5b f2 92  |..C..q...P.na[..|
-00000330  b4 69 73 f2 3b 54 bf 1c  9d 05 19 97 e4 4e 41 9e  |.is.;T.......NA.|
-00000340  f2 9a 76 77 9a 86 43 1f  1f 30 a2 16 03 01 00 04  |..vw..C..0......|
+00000270  2a 16 03 01 00 d5 0c 00  00 d1 03 00 17 41 04 22  |*............A."|
+00000280  8a 47 c6 d3 7a c4 30 a4  8e 41 11 ac b3 2d 2f 45  |.G..z.0..A...-/E|
+00000290  61 54 9b 1f 2e 03 5d 50  eb fc 5b 44 a0 a7 48 78  |aT....]P..[D..Hx|
+000002a0  ce 14 d5 39 a7 c4 ed f5  4d 8f da 9d 71 52 69 70  |...9....M...qRip|
+000002b0  7e 52 29 ad 80 8a 19 ad  4c 5d 1c f1 22 7e 1a 00  |~R).....L].."~..|
+000002c0  8a 30 81 87 02 42 00 97  8b 6d f7 87 c1 a9 a6 55  |.0...B...m.....U|
+000002d0  0f 61 c2 f2 e1 05 26 a8  83 16 1c 0b 69 3b 95 57  |.a....&.....i;.W|
+000002e0  76 5b eb 45 7a bd 6a f1  3e a0 93 49 fa 74 32 fd  |v[.Ez.j.>..I.t2.|
+000002f0  dc 20 3a bb e3 ee 6d b8  56 aa e9 d2 7d 6a ec b7  |. :...m.V...}j..|
+00000300  0a bd aa dc d7 b0 69 65  02 41 4d 19 61 16 d8 5f  |......ie.AM.a.._|
+00000310  1d c1 32 25 15 26 eb 88  5b c1 dd 9a 12 40 fa f1  |..2%.&..[....@..|
+00000320  81 5e 7d b8 2b 6e 60 63  1a 9e 86 cb d5 64 96 d4  |.^}.+n`c.....d..|
+00000330  75 fc 02 33 e0 66 60 b2  40 47 cf e6 6d 25 9c 83  |u..3.f`.@G..m%..|
+00000340  23 d3 4b e2 eb ac f1 56  44 f8 3f 16 03 01 00 04  |#.K....VD.?.....|
 00000350  0e 00 00 00                                       |....|
 >>> Flow 3 (client to server)
 00000000  16 03 01 00 46 10 00 00  42 41 04 1e 18 37 ef 0d  |....F...BA...7..|
@@ -68,20 +69,20 @@
 00000020  a7 24 20 3e b2 56 1c ce  97 28 5e f8 2b 2d 4f 9e  |.$ >.V...(^.+-O.|
 00000030  f1 07 9f 6c 4b 5b 83 56  e2 32 42 e9 58 b6 d7 49  |...lK[.V.2B.X..I|
 00000040  a6 b5 68 1a 41 03 56 6b  dc 5a 89 14 03 01 00 01  |..h.A.Vk.Z......|
-00000050  01 16 03 01 00 30 88 60  65 b2 d7 51 1f ad 96 56  |.....0.`e..Q...V|
-00000060  4e 0a 20 eb b5 b0 1a dd  4c f6 1a cf d4 5c 47 c4  |N. .....L....\G.|
-00000070  9c 7c a0 36 dd d1 1b 96  91 99 c0 a7 2d 9a 7c 42  |.|.6........-.|B|
-00000080  51 d1 de 87 2b a4                                 |Q...+.|
+00000050  01 16 03 01 00 30 cc 86  f1 7e 6e a8 c9 b5 02 5f  |.....0...~n...._|
+00000060  fb b2 3b ea 74 bf a8 da  e4 6a 69 50 a2 5a 78 4f  |..;.t....jiP.ZxO|
+00000070  35 e1 cc 87 c3 fb 1f 5e  f6 a4 5c 63 cc 59 12 3e  |5......^..\c.Y.>|
+00000080  07 c3 a8 d7 87 ba                                 |......|
 >>> Flow 4 (server to client)
-00000000  14 03 01 00 01 01 16 03  01 00 30 86 6c b5 94 69  |..........0.l..i|
-00000010  2e e0 55 a2 4d a8 63 f2  5b 1f ae 34 21 c8 21 6a  |..U.M.c.[..4!.!j|
-00000020  00 b6 56 ed 4e 2a b0 ff  01 2f da ce a1 c0 41 03  |..V.N*.../....A.|
-00000030  a9 1b 6e 2e e1 88 50 ba  62 14 88                 |..n...P.b..|
+00000000  14 03 01 00 01 01 16 03  01 00 30 e8 b6 20 b9 c1  |..........0.. ..|
+00000010  07 38 38 bb 42 b2 b2 a1  c5 8d 92 62 db 67 ab fc  |.88.B......b.g..|
+00000020  f6 64 3f 71 83 1d a0 86  bb 2d e3 4f 65 d5 44 52  |.d?q.....-.Oe.DR|
+00000030  4d f5 62 80 3c af 95 87  19 7c 20                 |M.b.<....| |
 >>> Flow 5 (client to server)
-00000000  17 03 01 00 20 a6 63 0a  2f a5 dc e1 fb cb 7b 1f  |.... .c./.....{.|
-00000010  f2 da 74 c3 ff e9 f5 8b  9c 5f 0c d3 f7 1f 44 e6  |..t......_....D.|
-00000020  90 13 5c 48 50 17 03 01  00 20 c7 75 b5 ff bc 09  |..\HP.... .u....|
-00000030  34 f2 45 db 0d 22 08 8e  f1 35 cd b6 0f b0 eb 2a  |4.E.."...5.....*|
-00000040  b7 1a d0 8e 14 a4 54 84  f9 dc 15 03 01 00 20 e0  |......T....... .|
-00000050  36 3d aa b3 a9 b4 20 23  ca 9e 8c 5d fc a8 c8 b7  |6=.... #...]....|
-00000060  f5 c2 b6 d0 5a e2 ce a5  7b 68 a0 48 86 95 6a     |....Z...{h.H..j|
+00000000  17 03 01 00 20 bd 65 61  28 e5 ea 1b 81 db 75 92  |.... .ea(.....u.|
+00000010  ad a7 3b 01 a3 23 0e 3b  60 10 8a 1e 04 91 fb 9e  |..;..#.;`.......|
+00000020  7a cf 1f cf 9c 17 03 01  00 20 87 9c dc ed 0d 08  |z........ ......|
+00000030  56 40 23 8b c5 2c d8 7e  42 82 3c 0a c9 f3 77 6d  |V@#..,.~B.<...wm|
+00000040  8d 9a 30 d1 9c c4 ae 04  fb b7 15 03 01 00 20 f7  |..0........... .|
+00000050  f0 12 0d e5 03 c1 80 4e  7e 21 d7 75 55 1c 91 89  |.......N~!.uU...|
+00000060  e7 e1 45 fc 7d d8 fc b1  d0 e7 dc e2 4c ba f4     |..E.}.......L..|
diff --git a/third_party/gofrontend/libgo/go/crypto/tls/testdata/Client-TLSv10-ECDHE-RSA-AES b/third_party/gofrontend/libgo/go/crypto/tls/testdata/Client-TLSv10-ECDHE-RSA-AES
index 868f0ce..f8183f1 100644
--- a/third_party/gofrontend/libgo/go/crypto/tls/testdata/Client-TLSv10-ECDHE-RSA-AES
+++ b/third_party/gofrontend/libgo/go/crypto/tls/testdata/Client-TLSv10-ECDHE-RSA-AES
@@ -1,18 +1,19 @@
 >>> Flow 1 (client to server)
-00000000  16 03 01 00 75 01 00 00  71 03 03 00 00 00 00 00  |....u...q.......|
+00000000  16 03 01 00 81 01 00 00  7d 03 03 00 00 00 00 00  |........}.......|
 00000010  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
-00000020  00 00 00 00 00 00 00 00  00 00 00 00 00 1a c0 2f  |.............../|
-00000030  c0 2b c0 11 c0 07 c0 13  c0 09 c0 14 c0 0a 00 05  |.+..............|
-00000040  00 2f 00 35 c0 12 00 0a  01 00 00 2e 00 05 00 05  |./.5............|
-00000050  01 00 00 00 00 00 0a 00  08 00 06 00 17 00 18 00  |................|
-00000060  19 00 0b 00 02 01 00 00  0d 00 0a 00 08 04 01 04  |................|
-00000070  03 02 01 02 03 ff 01 00  01 00                    |..........|
+00000020  00 00 00 00 00 00 00 00  00 00 00 00 00 1e c0 2f  |.............../|
+00000030  c0 2b c0 30 c0 2c c0 11  c0 07 c0 13 c0 09 c0 14  |.+.0.,..........|
+00000040  c0 0a 00 05 00 2f 00 35  c0 12 00 0a 01 00 00 36  |...../.5.......6|
+00000050  00 05 00 05 01 00 00 00  00 00 0a 00 08 00 06 00  |................|
+00000060  17 00 18 00 19 00 0b 00  02 01 00 00 0d 00 0e 00  |................|
+00000070  0c 04 01 04 03 05 01 05  03 02 01 02 03 ff 01 00  |................|
+00000080  01 00 00 12 00 00                                 |......|
 >>> Flow 2 (server to client)
-00000000  16 03 01 00 59 02 00 00  55 03 01 53 04 f1 02 21  |....Y...U..S...!|
-00000010  67 b5 2b 34 fb 62 d7 36  4f cf 68 2e 29 39 d0 28  |g.+4.b.6O.h.)9.(|
-00000020  3a 02 32 82 8f 95 de 62  d6 03 77 20 e6 98 56 cd  |:.2....b..w ..V.|
-00000030  96 24 d1 b9 4d eb 51 19  bb b7 71 f4 9c 29 32 d4  |.$..M.Q...q..)2.|
-00000040  e5 c6 0a 54 e0 4a 20 29  3e bd 06 0d c0 13 00 00  |...T.J )>.......|
+00000000  16 03 01 00 59 02 00 00  55 03 01 5c 69 d0 60 d6  |....Y...U..\i.`.|
+00000010  b3 f4 23 19 5e 3e 26 d8  29 ea c3 94 e4 ed 51 f6  |..#.^>&.).....Q.|
+00000020  58 a2 e3 9c 79 a1 0b 6d  29 90 32 20 23 5b 47 b1  |X...y..m).2 #[G.|
+00000030  8f 22 bc 06 aa ee f7 c3  97 ca 93 df b1 90 7d b4  |."............}.|
+00000040  8c c0 d9 54 35 ca 5b 11  98 37 84 ea c0 13 00 00  |...T5.[..7......|
 00000050  0d ff 01 00 01 00 00 0b  00 04 03 00 01 02 16 03  |................|
 00000060  01 02 be 0b 00 02 ba 00  02 b7 00 02 b4 30 82 02  |.............0..|
 00000070  b0 30 82 02 19 a0 03 02  01 02 02 09 00 85 b0 bb  |.0..............|
@@ -58,40 +59,40 @@
 000002f0  5f 33 c4 b6 d8 c9 75 90  96 8c 0f 52 98 b5 cd 98  |_3....u....R....|
 00000300  1f 89 20 5f f2 a0 1c a3  1b 96 94 dd a9 fd 57 e9  |.. _..........W.|
 00000310  70 e8 26 6d 71 99 9b 26  6e 38 50 29 6c 90 a7 bd  |p.&mq..&n8P)l...|
-00000320  d9 16 03 01 00 cb 0c 00  00 c7 03 00 17 41 04 05  |.............A..|
-00000330  45 33 f8 4b e9 96 0e 4a  fd ec 54 76 21 9b 24 8a  |E3.K...J..Tv!.$.|
-00000340  75 0b 80 84 c7 30 2b 22  f0 85 57 a4 a9 79 d6 f6  |u....0+"..W..y..|
-00000350  6d 80 b0 71 d9 66 c9 6c  dd 76 fc 32 d0 c6 bc 52  |m..q.f.l.v.2...R|
-00000360  2f f1 c9 62 17 53 76 ec  be a6 1c 93 f2 b4 5d 00  |/..b.Sv.......].|
-00000370  80 72 d9 20 52 70 7c 03  b1 33 fa 51 23 cd 05 97  |.r. Rp|..3.Q#...|
-00000380  6f d6 89 2f 8d 2e 3a 17  32 eb f2 ff 6b 39 70 5e  |o../..:.2...k9p^|
-00000390  21 41 8d 69 02 c8 9a 17  19 e4 48 9b 51 c3 7f 9b  |!A.i......H.Q...|
-000003a0  8d 4a 83 97 07 0e 30 f1  8b 6b e9 92 12 01 d6 96  |.J....0..k......|
-000003b0  f2 1a a2 10 7f 59 87 16  1a fb 55 67 68 fc 78 c6  |.....Y....Ugh.x.|
-000003c0  57 ac 05 dd f3 6f 77 84  eb ae b0 33 2d 19 2c ba  |W....ow....3-.,.|
-000003d0  b8 ae 9f 95 69 85 95 45  5e 37 f4 17 17 9b 03 c1  |....i..E^7......|
-000003e0  50 b1 36 42 bd 60 5c 8b  d8 b6 f3 c8 34 c8 9d 9d  |P.6B.`\.....4...|
-000003f0  75 16 03 01 00 04 0e 00  00 00                    |u.........|
+00000320  d9 16 03 01 00 cb 0c 00  00 c7 03 00 17 41 04 a6  |.............A..|
+00000330  57 60 8d 63 4e 4d 3f 48  e0 5d ad 9a 9c f7 e6 8c  |W`.cNM?H.]......|
+00000340  00 18 9c eb 34 ea f0 5c  d5 77 3f af 81 a9 50 d9  |....4..\.w?...P.|
+00000350  05 cf b9 bf 88 5c 70 29  24 61 6f d8 77 11 21 57  |.....\p)$ao.w.!W|
+00000360  a0 4d e1 4b 8e 55 06 50  7f a2 30 c1 c2 b9 c6 00  |.M.K.U.P..0.....|
+00000370  80 68 7c e4 1a bc a4 1e  16 b9 3e 4a 59 39 a9 54  |.h|.......>JY9.T|
+00000380  6f c7 17 b2 f5 af b5 73  5b db cc 71 f2 1b aa dc  |o......s[..q....|
+00000390  9d 64 3c 0f 82 e6 da 1a  6b 96 19 e2 f0 15 b0 df  |.d<.....k.......|
+000003a0  8a 2d 96 09 63 52 f6 53  ef 12 d4 3b 35 b7 0b 43  |.-..cR.S...;5..C|
+000003b0  2c 6e 58 4c c8 2f b8 55  84 89 c9 39 81 7a 7a 7d  |,nXL./.U...9.zz}|
+000003c0  88 68 db eb d7 81 aa 2e  b2 25 ba 98 6c 46 b7 85  |.h.......%..lF..|
+000003d0  8a 21 17 b9 36 23 c0 84  94 af 3b 9b 04 5d ec 31  |.!..6#....;..].1|
+000003e0  f5 75 84 d8 77 d7 80 37  ae c3 5c 26 41 f6 72 af  |.u..w..7..\&A.r.|
+000003f0  88 16 03 01 00 04 0e 00  00 00                    |..........|
 >>> Flow 3 (client to server)
 00000000  16 03 01 00 46 10 00 00  42 41 04 1e 18 37 ef 0d  |....F...BA...7..|
 00000010  19 51 88 35 75 71 b5 e5  54 5b 12 2e 8f 09 67 fd  |.Q.5uq..T[....g.|
 00000020  a7 24 20 3e b2 56 1c ce  97 28 5e f8 2b 2d 4f 9e  |.$ >.V...(^.+-O.|
 00000030  f1 07 9f 6c 4b 5b 83 56  e2 32 42 e9 58 b6 d7 49  |...lK[.V.2B.X..I|
 00000040  a6 b5 68 1a 41 03 56 6b  dc 5a 89 14 03 01 00 01  |..h.A.Vk.Z......|
-00000050  01 16 03 01 00 30 ca d1  1b 08 27 9b 44 e7 e9 b4  |.....0....'.D...|
-00000060  90 16 4d 30 4e 65 5c 0d  47 ba 46 86 cf c9 80 e7  |..M0Ne\.G.F.....|
-00000070  64 31 f5 a1 9e dc 39 15  d3 be 16 4f c7 90 b6 62  |d1....9....O...b|
-00000080  5d 6d 7f 41 4e 3e                                 |]m.AN>|
+00000050  01 16 03 01 00 30 d2 5b  27 5a f5 64 49 31 d5 aa  |.....0.['Z.dI1..|
+00000060  a3 72 ae c9 af 0b aa 75  af ac f3 45 f4 e3 03 fa  |.r.....u...E....|
+00000070  e8 97 88 7b 51 a9 ae 61  40 c8 11 74 3e d8 9a b6  |...{Q..a@..t>...|
+00000080  e7 6a 5e 71 84 7e                                 |.j^q.~|
 >>> Flow 4 (server to client)
-00000000  14 03 01 00 01 01 16 03  01 00 30 98 81 24 8e cd  |..........0..$..|
-00000010  b6 48 2f 80 de 8e 24 3c  cd 02 67 80 34 97 d7 92  |.H/...$<..g.4...|
-00000020  78 c2 44 3d 5d 05 eb 88  76 79 46 7a c3 fa ca 73  |x.D=]...vyFz...s|
-00000030  45 82 ad c1 81 00 ca 40  c1 2f 13                 |E......@./.|
+00000000  14 03 01 00 01 01 16 03  01 00 30 8d 63 fc 58 2e  |..........0.c.X.|
+00000010  50 f7 60 2c 9f 5a 8e 58  29 6c a6 3a 8d 2b a7 2b  |P.`,.Z.X)l.:.+.+|
+00000020  1c 12 8a 53 3f d5 60 79  12 c3 78 e3 aa 50 15 45  |...S?.`y..x..P.E|
+00000030  07 da 2d c7 a9 c3 45 07  48 00 78                 |..-...E.H.x|
 >>> Flow 5 (client to server)
-00000000  17 03 01 00 20 ee 19 59  67 67 a9 8b db 99 87 50  |.... ..Ygg.....P|
-00000010  01 e2 02 c1 d5 6d 36 79  af aa ec 1b 80 0e b6 5e  |.....m6y.......^|
-00000020  5f fa 03 01 cc 17 03 01  00 20 ec e2 04 b7 3b a5  |_........ ....;.|
-00000030  f2 e0 13 1f 17 48 e7 6e  d3 eb f0 fa 36 ef 6e 2e  |.....H.n....6.n.|
-00000040  fb ea c8 39 c4 5f 4b 28  d4 50 15 03 01 00 20 c7  |...9._K(.P.... .|
-00000050  45 ff fb c7 07 0c d8 0e  35 a3 c5 31 47 b7 03 0e  |E.......5..1G...|
-00000060  14 c8 29 fd 53 70 5f 15  ac d2 1c 4c 69 fb d6     |..).Sp_....Li..|
+00000000  17 03 01 00 20 40 91 8d  e6 95 2f 97 c8 0c 94 5c  |.... @..../....\|
+00000010  46 a7 d3 31 82 3d dc 7e  86 5b dd df 3f 3b 5b 9c  |F..1.=.~.[..?;[.|
+00000020  d5 0d 52 5a 53 17 03 01  00 20 1d 18 da 6b e8 66  |..RZS.... ...k.f|
+00000030  ce 58 18 81 4b 69 8c f6  db 1a ee d0 78 fb f5 68  |.X..Ki......x..h|
+00000040  2c 99 48 47 65 15 2a ae  ff 4e 15 03 01 00 20 68  |,.HGe.*..N.... h|
+00000050  aa 7f 75 33 45 7a 1a 33  18 35 5a 5b 14 b0 f6 83  |..u3Ez.3.5Z[....|
+00000060  97 85 3f b2 dc 78 68 eb  43 ef 92 7f 38 bd f8     |..?..xh.C...8..|
diff --git a/third_party/gofrontend/libgo/go/crypto/tls/testdata/Client-TLSv10-RSA-RC4 b/third_party/gofrontend/libgo/go/crypto/tls/testdata/Client-TLSv10-RSA-RC4
index 395d53b..b5deaeb 100644
--- a/third_party/gofrontend/libgo/go/crypto/tls/testdata/Client-TLSv10-RSA-RC4
+++ b/third_party/gofrontend/libgo/go/crypto/tls/testdata/Client-TLSv10-RSA-RC4
@@ -1,18 +1,19 @@
 >>> Flow 1 (client to server)
-00000000  16 03 01 00 75 01 00 00  71 03 03 00 00 00 00 00  |....u...q.......|
+00000000  16 03 01 00 81 01 00 00  7d 03 03 00 00 00 00 00  |........}.......|
 00000010  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
-00000020  00 00 00 00 00 00 00 00  00 00 00 00 00 1a c0 2f  |.............../|
-00000030  c0 2b c0 11 c0 07 c0 13  c0 09 c0 14 c0 0a 00 05  |.+..............|
-00000040  00 2f 00 35 c0 12 00 0a  01 00 00 2e 00 05 00 05  |./.5............|
-00000050  01 00 00 00 00 00 0a 00  08 00 06 00 17 00 18 00  |................|
-00000060  19 00 0b 00 02 01 00 00  0d 00 0a 00 08 04 01 04  |................|
-00000070  03 02 01 02 03 ff 01 00  01 00                    |..........|
+00000020  00 00 00 00 00 00 00 00  00 00 00 00 00 1e c0 2f  |.............../|
+00000030  c0 2b c0 30 c0 2c c0 11  c0 07 c0 13 c0 09 c0 14  |.+.0.,..........|
+00000040  c0 0a 00 05 00 2f 00 35  c0 12 00 0a 01 00 00 36  |...../.5.......6|
+00000050  00 05 00 05 01 00 00 00  00 00 0a 00 08 00 06 00  |................|
+00000060  17 00 18 00 19 00 0b 00  02 01 00 00 0d 00 0e 00  |................|
+00000070  0c 04 01 04 03 05 01 05  03 02 01 02 03 ff 01 00  |................|
+00000080  01 00 00 12 00 00                                 |......|
 >>> Flow 2 (server to client)
-00000000  16 03 01 00 51 02 00 00  4d 03 01 53 04 f1 02 76  |....Q...M..S...v|
-00000010  e8 45 7f 57 f3 42 4b 33  0b 06 fa a6 fa c4 3d 84  |.E.W.BK3......=.|
-00000020  5a 45 dc 93 41 a5 8d 79  6e 8f 11 20 e7 c6 29 2b  |ZE..A..yn.. ..)+|
-00000030  ff 4a 6e 63 67 a6 10 cb  49 19 46 1e 5e 0a d5 70  |.Jncg...I.F.^..p|
-00000040  96 88 9a 32 48 ef c3 4a  45 4c 6d e0 00 05 00 00  |...2H..JELm.....|
+00000000  16 03 01 00 51 02 00 00  4d 03 01 a9 b0 bf 24 3f  |....Q...M.....$?|
+00000010  98 c6 0f 83 23 2b b6 e4  3f d5 5b 10 9a 6f b8 63  |....#+..?.[..o.c|
+00000020  4c 3c d6 4d 05 c0 08 85  f7 72 72 20 ab 85 8c ff  |L<.M.....rr ....|
+00000030  f7 bb 95 ab 69 37 3d b6  79 cb 46 ad 4e 22 e7 c6  |....i7=.y.F.N"..|
+00000040  a5 9b 72 92 32 ff a5 f7  ed dc 30 41 00 05 00 00  |..r.2.....0A....|
 00000050  05 ff 01 00 01 00 16 03  01 02 be 0b 00 02 ba 00  |................|
 00000060  02 b7 00 02 b4 30 82 02  b0 30 82 02 19 a0 03 02  |.....0...0......|
 00000070  01 02 02 09 00 85 b0 bb  a4 8a 7f b8 ca 30 0d 06  |.............0..|
@@ -69,15 +70,15 @@
 00000060  e6 bd 77 82 6f 23 b6 e0  bd a2 92 b7 3a ac e8 56  |..w.o#......:..V|
 00000070  f1 af 54 5e 46 87 e9 3b  33 e7 b8 28 b7 d6 c8 90  |..T^F..;3..(....|
 00000080  35 d4 1c 43 d1 30 6f 55  4e 0a 70 14 03 01 00 01  |5..C.0oUN.p.....|
-00000090  01 16 03 01 00 24 cd c0  68 dc 2e 69 cc c7 5b c5  |.....$..h..i..[.|
-000000a0  3f bd 40 cf a0 0f 41 34  ce 16 37 10 26 c8 3f d1  |?.@...A4..7.&.?.|
-000000b0  46 3b ad 7b b0 31 f3 c5  36 e7                    |F;.{.1..6.|
+00000090  01 16 03 01 00 24 4d 1d  d7 8c d6 c7 65 a6 ce af  |.....$M.....e...|
+000000a0  e7 59 0d 7e dc d9 96 1c  ed 9c 57 94 84 b8 3f b5  |.Y.~......W...?.|
+000000b0  34 e1 61 a5 61 f3 5d 09  bc ff                    |4.a.a.]...|
 >>> Flow 4 (server to client)
-00000000  14 03 01 00 01 01 16 03  01 00 24 ea 77 6f 3c 42  |..........$.wo<B|
-00000010  12 16 51 de e8 b6 f9 85  06 d9 6d 05 75 50 2b 27  |..Q.......m.uP+'|
-00000020  93 b7 6b 65 e9 14 99 48  53 3e be e4 be 03 5d     |..ke...HS>....]|
+00000000  14 03 01 00 01 01 16 03  01 00 24 13 81 89 61 5c  |..........$...a\|
+00000010  fb 0a 9c a1 4b db 94 6b  8b 41 6e 63 d6 aa db 88  |....K..k.Anc....|
+00000020  03 b7 b5 19 b8 12 cf 5e  17 54 79 2f 03 91 7e     |.......^.Ty/..~|
 >>> Flow 5 (client to server)
-00000000  17 03 01 00 1a 9e ae ca  55 df c4 d9 47 04 55 dd  |........U...G.U.|
-00000010  3b 33 e1 a6 16 6f a1 94  b1 9b 4d 0d cb 6c 3b 15  |;3...o....M..l;.|
-00000020  03 01 00 16 92 5d 76 07  e9 b7 31 29 09 c5 b1 09  |.....]v...1)....|
-00000030  2d 64 3d 85 8d f1 d1 40  54 b8                    |-d=....@T.|
+00000000  17 03 01 00 1a b3 2b da  ce 45 ec b2 9d 3b 18 d9  |......+..E...;..|
+00000010  7a cb 99 ea ff 4d 91 b5  48 df 6f 8b 2f 85 c7 15  |z....M..H.o./...|
+00000020  03 01 00 16 19 1c 72 74  36 cf 22 0f a0 a7 18 96  |......rt6.".....|
+00000030  3a 67 cb 22 16 f1 a8 7b  57 37                    |:g."...{W7|
diff --git a/third_party/gofrontend/libgo/go/crypto/tls/testdata/Client-TLSv11-ECDHE-ECDSA-AES b/third_party/gofrontend/libgo/go/crypto/tls/testdata/Client-TLSv11-ECDHE-ECDSA-AES
index 9f941f8..a4a2930 100644
--- a/third_party/gofrontend/libgo/go/crypto/tls/testdata/Client-TLSv11-ECDHE-ECDSA-AES
+++ b/third_party/gofrontend/libgo/go/crypto/tls/testdata/Client-TLSv11-ECDHE-ECDSA-AES
@@ -1,18 +1,19 @@
 >>> Flow 1 (client to server)
-00000000  16 03 01 00 75 01 00 00  71 03 03 00 00 00 00 00  |....u...q.......|
+00000000  16 03 01 00 81 01 00 00  7d 03 03 00 00 00 00 00  |........}.......|
 00000010  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
-00000020  00 00 00 00 00 00 00 00  00 00 00 00 00 1a c0 2f  |.............../|
-00000030  c0 2b c0 11 c0 07 c0 13  c0 09 c0 14 c0 0a 00 05  |.+..............|
-00000040  00 2f 00 35 c0 12 00 0a  01 00 00 2e 00 05 00 05  |./.5............|
-00000050  01 00 00 00 00 00 0a 00  08 00 06 00 17 00 18 00  |................|
-00000060  19 00 0b 00 02 01 00 00  0d 00 0a 00 08 04 01 04  |................|
-00000070  03 02 01 02 03 ff 01 00  01 00                    |..........|
+00000020  00 00 00 00 00 00 00 00  00 00 00 00 00 1e c0 2f  |.............../|
+00000030  c0 2b c0 30 c0 2c c0 11  c0 07 c0 13 c0 09 c0 14  |.+.0.,..........|
+00000040  c0 0a 00 05 00 2f 00 35  c0 12 00 0a 01 00 00 36  |...../.5.......6|
+00000050  00 05 00 05 01 00 00 00  00 00 0a 00 08 00 06 00  |................|
+00000060  17 00 18 00 19 00 0b 00  02 01 00 00 0d 00 0e 00  |................|
+00000070  0c 04 01 04 03 05 01 05  03 02 01 02 03 ff 01 00  |................|
+00000080  01 00 00 12 00 00                                 |......|
 >>> Flow 2 (server to client)
-00000000  16 03 02 00 59 02 00 00  55 03 02 53 04 f1 02 1c  |....Y...U..S....|
-00000010  d1 1c 6a 5f 7a 5c 26 69  92 cd ee c3 57 ed 96 90  |..j_z\&i....W...|
-00000020  e3 c5 f1 ee 8b ee 99 5f  46 2c e6 20 c8 50 6a a4  |......._F,. .Pj.|
-00000030  4b 93 e6 da ba 6d d4 87  f6 75 a8 9d 44 db b5 43  |K....m...u..D..C|
-00000040  df 12 57 de a4 f1 bc fb  b8 7a 3f 6a c0 09 00 00  |..W......z?j....|
+00000000  16 03 02 00 59 02 00 00  55 03 02 5a 52 92 23 05  |....Y...U..ZR.#.|
+00000010  58 68 b2 1e 77 a2 a8 16  e9 88 85 ea 38 b3 63 c2  |Xh..w.......8.c.|
+00000020  40 f8 de 37 3c d4 b9 51  11 2d d1 20 12 fd 95 b3  |@..7<..Q.-. ....|
+00000030  2a 54 40 c0 23 3a 4e 4e  f6 7b f8 77 04 6e e7 d7  |*T@.#:NN.{.w.n..|
+00000040  3b 9a 45 32 e0 af df aa  ff bf 78 8b c0 09 00 00  |;.E2......x.....|
 00000050  0d ff 01 00 01 00 00 0b  00 04 03 00 01 02 16 03  |................|
 00000060  02 02 0e 0b 00 02 0a 00  02 07 00 02 04 30 82 02  |.............0..|
 00000070  00 30 82 01 62 02 09 00  b8 bf 2d 47 a0 d2 eb f4  |.0..b.....-G....|
@@ -47,21 +48,21 @@
 00000240  13 83 0d 94 06 bb d4 37  7a f6 ec 7a c9 86 2e dd  |.......7z..z....|
 00000250  d7 11 69 7f 85 7c 56 de  fb 31 78 2b e4 c7 78 0d  |..i..|V..1x+..x.|
 00000260  ae cb be 9e 4e 36 24 31  7b 6a 0f 39 95 12 07 8f  |....N6$1{j.9....|
-00000270  2a 16 03 02 00 d4 0c 00  00 d0 03 00 17 41 04 7b  |*............A.{|
-00000280  c4 00 37 35 51 de c3 f2  a4 95 2c 19 21 3e a6 94  |..75Q.....,.!>..|
-00000290  7b fd 04 d7 b7 1c 56 e6  af 3c ee 36 cb 55 e6 f0  |{.....V..<.6.U..|
-000002a0  e6 24 34 6b 8a 02 66 71  f9 e2 f5 a6 c9 d7 6c dc  |.$4k..fq......l.|
-000002b0  65 59 ff 1c c9 ec a9 8b  07 d6 52 2c 01 3c c3 00  |eY........R,.<..|
-000002c0  89 30 81 86 02 41 74 89  1a 31 72 e6 8b c0 4a ce  |.0...At..1r...J.|
-000002d0  8f 5a 49 a7 52 2d 6d b9  8b 50 17 62 2a 99 d6 3b  |.ZI.R-m..P.b*..;|
-000002e0  02 85 41 4d 34 53 b5 09  bd e3 ac 16 c1 9b e9 83  |..AM4S..........|
-000002f0  cc 83 e3 9c 23 34 67 71  72 d4 05 a2 34 f7 08 29  |....#4gqr...4..)|
-00000300  62 43 2e cc bc 08 01 02  41 59 de 5a d0 dd d7 6b  |bC......AY.Z...k|
-00000310  db 9c 35 29 79 f8 96 91  56 74 1f 18 7b ee 25 83  |..5)y...Vt..{.%.|
-00000320  f2 37 0e 77 ab 38 fb 5e  04 0b 09 d9 b4 1f 3f be  |.7.w.8.^......?.|
-00000330  2e e3 60 e3 96 f3 29 c1  6d 8f 56 1b fd 62 14 48  |..`...).m.V..b.H|
-00000340  e3 d9 2a ea 2f be 93 d0  8b 31 16 03 02 00 04 0e  |..*./....1......|
-00000350  00 00 00                                          |...|
+00000270  2a 16 03 02 00 d5 0c 00  00 d1 03 00 17 41 04 c3  |*............A..|
+00000280  55 86 65 95 83 02 4b 69  6e 95 f4 52 46 83 21 86  |U.e...Kin..RF.!.|
+00000290  9e 99 cf 81 d9 b8 20 7a  87 b3 07 48 14 04 20 d9  |...... z...H.. .|
+000002a0  6c 2e 22 5a b5 b4 ef de  15 b3 08 ef 1e 18 ea 67  |l."Z...........g|
+000002b0  eb 45 fd e1 27 43 ed 41  ea 05 7e f3 f9 ee 23 00  |.E..'C.A..~...#.|
+000002c0  8a 30 81 87 02 42 00 b0  9c 06 85 83 b2 bf 42 22  |.0...B........B"|
+000002d0  6e 57 7a 31 fe a9 d9 28  be 0a a9 80 49 a2 14 c1  |nWz1...(....I...|
+000002e0  a9 99 76 b7 f9 76 d0 3c  d3 0c c7 42 34 d7 94 a9  |..v..v.<...B4...|
+000002f0  15 66 7e 6b 83 6e b2 b4  5b 22 c9 4e a0 96 db 2b  |.f~k.n..[".N...+|
+00000300  ad 77 33 1e 4a 5c 2f 2e  02 41 26 0c 1a 5a b4 07  |.w3.J\/..A&..Z..|
+00000310  95 99 ec 0b 5b 2e bb db  0e d5 26 c4 b3 eb c2 30  |....[.....&....0|
+00000320  b0 7b c1 07 97 a0 99 3f  db 4e b0 c4 b8 bb 5e be  |.{.....?.N....^.|
+00000330  2a e4 b3 a4 5c ad d1 d7  7a 2d fb ae 73 ee 0c 1e  |*...\...z-..s...|
+00000340  3b 64 e1 74 14 bc c0 1e  8b f3 26 16 03 02 00 04  |;d.t......&.....|
+00000350  0e 00 00 00                                       |....|
 >>> Flow 3 (client to server)
 00000000  16 03 02 00 46 10 00 00  42 41 04 1e 18 37 ef 0d  |....F...BA...7..|
 00000010  19 51 88 35 75 71 b5 e5  54 5b 12 2e 8f 09 67 fd  |.Q.5uq..T[....g.|
@@ -69,21 +70,21 @@
 00000030  f1 07 9f 6c 4b 5b 83 56  e2 32 42 e9 58 b6 d7 49  |...lK[.V.2B.X..I|
 00000040  a6 b5 68 1a 41 03 56 6b  dc 5a 89 14 03 02 00 01  |..h.A.Vk.Z......|
 00000050  01 16 03 02 00 40 00 00  00 00 00 00 00 00 00 00  |.....@..........|
-00000060  00 00 00 00 00 00 b6 98  a2 a9 48 34 12 6b 0a 94  |..........H4.k..|
-00000070  89 fc 38 04 63 5a 6f 63  36 3e d9 35 12 64 8c 28  |..8.cZoc6>.5.d.(|
-00000080  99 a6 cf 2e 57 e3 14 6d  0a 8a ab f0 a6 58 37 7c  |....W..m.....X7||
-00000090  96 04 d3 71 bc d4                                 |...q..|
+00000060  00 00 00 00 00 00 33 07  8a af e1 94 ef f9 08 3a  |......3........:|
+00000070  33 5f b3 e6 42 07 85 af  40 e2 8b 34 53 62 1a 10  |3_..B...@..4Sb..|
+00000080  bb 08 7e 75 d4 21 12 2d  54 87 33 1c 4e 13 27 72  |..~u.!.-T.3.N.'r|
+00000090  3f 9e 9f cc de 47                                 |?....G|
 >>> Flow 4 (server to client)
-00000000  14 03 02 00 01 01 16 03  02 00 40 c5 01 c9 0a b0  |..........@.....|
-00000010  d8 ca 5e c1 19 dc 37 6c  2e a0 b3 11 a8 87 65 5a  |..^...7l......eZ|
-00000020  09 41 b9 fe 53 c4 c9 76  97 6d 7f ac c0 be d2 07  |.A..S..v.m......|
-00000030  84 e5 5b 78 37 34 ee da  3b cb 3e 82 52 79 91 44  |..[x74..;.>.Ry.D|
-00000040  b4 e4 1c ec 3a c0 c0 9d  cd ff 13                 |....:......|
+00000000  14 03 02 00 01 01 16 03  02 00 40 4f 47 0d 43 54  |..........@OG.CT|
+00000010  50 69 3a c8 21 a6 6e 28  78 cc 01 b4 5d eb f7 2b  |Pi:.!.n(x...]..+|
+00000020  8b 7e 26 6e cf 56 98 65  ad bf 0f a0 b4 67 13 70  |.~&n.V.e.....g.p|
+00000030  de b5 b5 91 df d6 df 8c  53 c6 54 3d 5d 98 e4 25  |........S.T=]..%|
+00000040  47 a0 0f 91 c7 08 96 17  48 bd 0f                 |G.......H..|
 >>> Flow 5 (client to server)
 00000000  17 03 02 00 30 00 00 00  00 00 00 00 00 00 00 00  |....0...........|
-00000010  00 00 00 00 00 46 60 13  39 2b 2f 72 95 ed 0e aa  |.....F`.9+/r....|
-00000020  69 6e b4 64 3e 83 43 d0  f9 7f 37 7c 1d b9 ce 11  |in.d>.C...7|....|
-00000030  d9 41 66 60 6d 15 03 02  00 30 00 00 00 00 00 00  |.Af`m....0......|
-00000040  00 00 00 00 00 00 00 00  00 00 b1 26 d0 5d 08 98  |...........&.]..|
-00000050  eb 28 42 74 31 58 42 95  c5 ad 1a 92 0a f5 5f ed  |.(Bt1XB......._.|
-00000060  45 98 e0 90 e5 a3 b6 8b  8d 18                    |E.........|
+00000010  00 00 00 00 00 4e fe 12  d7 4b d7 3f 86 5a 2c f6  |.....N...K.?.Z,.|
+00000020  86 03 2a bd 1a 98 d7 bb  9f 59 6c 6d 4d 57 b0 50  |..*......YlmMW.P|
+00000030  d6 97 7e d4 b6 15 03 02  00 30 00 00 00 00 00 00  |..~......0......|
+00000040  00 00 00 00 00 00 00 00  00 00 65 8b b5 ae 86 90  |..........e.....|
+00000050  00 4e 1e 3f bc ac ed 49  f4 5e 73 49 e6 d8 37 83  |.N.?...I.^sI..7.|
+00000060  cf 4f e5 7b 5e c9 1d c8  c9 dc                    |.O.{^.....|
diff --git a/third_party/gofrontend/libgo/go/crypto/tls/testdata/Client-TLSv11-ECDHE-RSA-AES b/third_party/gofrontend/libgo/go/crypto/tls/testdata/Client-TLSv11-ECDHE-RSA-AES
index fc72339..103f1d8 100644
--- a/third_party/gofrontend/libgo/go/crypto/tls/testdata/Client-TLSv11-ECDHE-RSA-AES
+++ b/third_party/gofrontend/libgo/go/crypto/tls/testdata/Client-TLSv11-ECDHE-RSA-AES
@@ -1,18 +1,19 @@
 >>> Flow 1 (client to server)
-00000000  16 03 01 00 75 01 00 00  71 03 03 00 00 00 00 00  |....u...q.......|
+00000000  16 03 01 00 81 01 00 00  7d 03 03 00 00 00 00 00  |........}.......|
 00000010  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
-00000020  00 00 00 00 00 00 00 00  00 00 00 00 00 1a c0 2f  |.............../|
-00000030  c0 2b c0 11 c0 07 c0 13  c0 09 c0 14 c0 0a 00 05  |.+..............|
-00000040  00 2f 00 35 c0 12 00 0a  01 00 00 2e 00 05 00 05  |./.5............|
-00000050  01 00 00 00 00 00 0a 00  08 00 06 00 17 00 18 00  |................|
-00000060  19 00 0b 00 02 01 00 00  0d 00 0a 00 08 04 01 04  |................|
-00000070  03 02 01 02 03 ff 01 00  01 00                    |..........|
+00000020  00 00 00 00 00 00 00 00  00 00 00 00 00 1e c0 2f  |.............../|
+00000030  c0 2b c0 30 c0 2c c0 11  c0 07 c0 13 c0 09 c0 14  |.+.0.,..........|
+00000040  c0 0a 00 05 00 2f 00 35  c0 12 00 0a 01 00 00 36  |...../.5.......6|
+00000050  00 05 00 05 01 00 00 00  00 00 0a 00 08 00 06 00  |................|
+00000060  17 00 18 00 19 00 0b 00  02 01 00 00 0d 00 0e 00  |................|
+00000070  0c 04 01 04 03 05 01 05  03 02 01 02 03 ff 01 00  |................|
+00000080  01 00 00 12 00 00                                 |......|
 >>> Flow 2 (server to client)
-00000000  16 03 02 00 59 02 00 00  55 03 02 53 04 f1 02 fe  |....Y...U..S....|
-00000010  17 8b 79 ad 93 2e d3 89  66 9b 5d 9b b4 03 3e ba  |..y.....f.]...>.|
-00000020  65 2a f1 55 f9 3c 33 de  2c a7 47 20 fa 4f 82 11  |e*.U.<3.,.G .O..|
-00000030  96 81 d0 70 2e 65 b3 68  2e 3a 6d d7 6c 74 22 33  |...p.e.h.:m.lt"3|
-00000040  d4 ae 6c aa c8 f0 c7 20  8b 10 21 e7 c0 13 00 00  |..l.... ..!.....|
+00000000  16 03 02 00 59 02 00 00  55 03 02 e3 ed 49 27 a3  |....Y...U....I'.|
+00000010  28 c5 8c 30 27 c2 ed 57  9b f7 37 a1 6d 2b 88 c2  |(..0'..W..7.m+..|
+00000020  df a7 2d 01 01 00 9a 09  da c2 1f 20 ee 33 87 03  |..-........ .3..|
+00000030  28 93 1c 16 99 5b b1 e0  bf 87 e8 77 4a 72 c9 92  |(....[.....wJr..|
+00000040  8a bc b2 3e 24 e1 f6 e8  f4 3f a2 24 c0 13 00 00  |...>$....?.$....|
 00000050  0d ff 01 00 01 00 00 0b  00 04 03 00 01 02 16 03  |................|
 00000060  02 02 be 0b 00 02 ba 00  02 b7 00 02 b4 30 82 02  |.............0..|
 00000070  b0 30 82 02 19 a0 03 02  01 02 02 09 00 85 b0 bb  |.0..............|
@@ -58,20 +59,20 @@
 000002f0  5f 33 c4 b6 d8 c9 75 90  96 8c 0f 52 98 b5 cd 98  |_3....u....R....|
 00000300  1f 89 20 5f f2 a0 1c a3  1b 96 94 dd a9 fd 57 e9  |.. _..........W.|
 00000310  70 e8 26 6d 71 99 9b 26  6e 38 50 29 6c 90 a7 bd  |p.&mq..&n8P)l...|
-00000320  d9 16 03 02 00 cb 0c 00  00 c7 03 00 17 41 04 26  |.............A.&|
-00000330  56 18 02 e5 66 d4 aa 24  7e ae 39 e5 ca 78 6c c1  |V...f..$~.9..xl.|
-00000340  90 02 c3 c4 ad 79 2c 47  a8 bf 54 e2 8a 22 b6 ef  |.....y,G..T.."..|
-00000350  99 d4 7a 7f 8f 78 6a 78  4e 14 2a 16 0d bb 54 38  |..z..xjxN.*...T8|
-00000360  59 1f 7a 53 1b c7 73 10  89 4b de c3 66 39 7a 00  |Y.zS..s..K..f9z.|
-00000370  80 3a 88 38 c8 15 07 ab  2f 0f 0d cb 19 07 84 ac  |.:.8..../.......|
-00000380  24 fd 8b d2 9d 05 45 c6  11 c3 d6 84 58 95 5a 08  |$.....E.....X.Z.|
-00000390  b9 a4 2c c0 41 4e 34 e0  b2 24 98 94 b7 67 27 50  |..,.AN4..$...g'P|
-000003a0  ba 82 35 28 a9 bf 16 ee  e3 7b 49 9c 4c 81 80 69  |..5(.....{I.L..i|
-000003b0  d7 aa ed 46 ea 9a 68 c4  97 b7 11 d4 35 91 74 5e  |...F..h.....5.t^|
-000003c0  54 10 34 83 cd c4 06 18  49 7d 7a 28 c9 53 06 73  |T.4.....I}z(.S.s|
-000003d0  00 7b 04 b6 d8 36 a7 4b  67 7f 81 30 94 de 40 4d  |.{...6.Kg..0..@M|
-000003e0  18 f8 c4 b7 02 00 44 8e  bc 72 06 24 53 15 74 72  |......D..r.$S.tr|
-000003f0  8d 16 03 02 00 04 0e 00  00 00                    |..........|
+00000320  d9 16 03 02 00 cb 0c 00  00 c7 03 00 17 41 04 f7  |.............A..|
+00000330  75 c1 b9 58 a0 7d 50 48  e9 85 79 db 89 76 4c d7  |u..X.}PH..y..vL.|
+00000340  84 5b 94 9a 15 d8 92 32  74 d2 3e ce 76 5a bd 0e  |.[.....2t.>.vZ..|
+00000350  24 e7 a6 d0 77 5d 8e 3d  9f 94 7a ea 15 46 3c 5c  |$...w].=..z..F<\|
+00000360  61 28 76 4a ff 81 97 2b  3a 0c b7 aa b4 0e cb 00  |a(vJ...+:.......|
+00000370  80 19 00 a8 fe 0a ea 35  30 51 a3 77 37 08 68 10  |.......50Q.w7.h.|
+00000380  5a e9 07 2d 83 67 77 4c  3a 25 14 1c 5b c1 2e 80  |Z..-.gwL:%..[...|
+00000390  30 6d ba 26 c1 f9 c6 3e  fc 55 34 8c d2 9f 2b a6  |0m.&...>.U4...+.|
+000003a0  46 0c 9d 58 2c 9c 2b ce  6f 03 d7 49 4e df 21 ce  |F..X,.+.o..IN.!.|
+000003b0  3f 8b 19 fe 3e 71 23 51  c3 ec 30 c8 3e 3c 3c 50  |?...>q#Q..0.><<P|
+000003c0  da 08 52 c0 10 9f e3 4a  be e0 97 aa de 5e 13 22  |..R....J.....^."|
+000003d0  b2 77 ee 5d 2d d4 ff fb  7f c3 1e e7 51 fe fc 4b  |.w.]-.......Q..K|
+000003e0  56 5b 8f 50 ad cc 34 7a  a9 dd 24 0a d0 c7 b9 bf  |V[.P..4z..$.....|
+000003f0  1a 16 03 02 00 04 0e 00  00 00                    |..........|
 >>> Flow 3 (client to server)
 00000000  16 03 02 00 46 10 00 00  42 41 04 1e 18 37 ef 0d  |....F...BA...7..|
 00000010  19 51 88 35 75 71 b5 e5  54 5b 12 2e 8f 09 67 fd  |.Q.5uq..T[....g.|
@@ -79,21 +80,21 @@
 00000030  f1 07 9f 6c 4b 5b 83 56  e2 32 42 e9 58 b6 d7 49  |...lK[.V.2B.X..I|
 00000040  a6 b5 68 1a 41 03 56 6b  dc 5a 89 14 03 02 00 01  |..h.A.Vk.Z......|
 00000050  01 16 03 02 00 40 00 00  00 00 00 00 00 00 00 00  |.....@..........|
-00000060  00 00 00 00 00 00 8a 87  81 38 35 c0 4c bb f8 12  |.........85.L...|
-00000070  fa 75 04 cd 1e 3a 61 96  93 c8 fb 07 d1 6d b4 55  |.u...:a......m.U|
-00000080  0f b5 0f 07 35 0a 96 ce  5c 6f 24 62 d3 68 e4 b0  |....5...\o$b.h..|
-00000090  5d be 81 37 c2 9c                                 |]..7..|
+00000060  00 00 00 00 00 00 1e 0b  cd 40 fa 0f ed fa 55 74  |.........@....Ut|
+00000070  4e ad 10 d1 b5 e1 41 8c  c0 93 81 38 f3 83 f1 37  |N.....A....8...7|
+00000080  6a d4 6c ea ba 5b 9e 38  d3 c1 bb 41 45 fb f0 48  |j.l..[.8...AE..H|
+00000090  c1 06 31 64 e0 65                                 |..1d.e|
 >>> Flow 4 (server to client)
-00000000  14 03 02 00 01 01 16 03  02 00 40 66 36 8d f8 8c  |..........@f6...|
-00000010  7f db 38 e8 39 df f8 2f  cb 88 9c 14 d9 89 10 b4  |..8.9../........|
-00000020  be 59 88 d7 f3 73 62 af  a3 42 66 6e 74 38 64 9f  |.Y...sb..Bfnt8d.|
-00000030  16 79 09 d7 14 7e 91 8a  70 73 63 28 30 58 fe cc  |.y...~..psc(0X..|
-00000040  42 45 d6 37 fb 9e 8c c1  01 af 34                 |BE.7......4|
+00000000  14 03 02 00 01 01 16 03  02 00 40 17 d1 79 f8 e0  |..........@..y..|
+00000010  d4 40 15 85 df 4d a6 d5  60 90 1f d6 52 58 e7 ae  |.@...M..`...RX..|
+00000020  05 eb a2 ea ed c9 be ae  b5 54 39 de 05 66 27 67  |.........T9..f'g|
+00000030  59 07 03 e7 10 f9 3f da  d8 85 8b 2f 7b 33 9f f5  |Y.....?..../{3..|
+00000040  43 50 b9 9c 6e dd 01 ae  d8 c9 1d                 |CP..n......|
 >>> Flow 5 (client to server)
 00000000  17 03 02 00 30 00 00 00  00 00 00 00 00 00 00 00  |....0...........|
-00000010  00 00 00 00 00 31 0b e3  9d 2a 05 83 19 7d 10 36  |.....1...*...}.6|
-00000020  23 dc da fe 00 ab d3 aa  8f ce 28 5f 08 fd b7 59  |#.........(_...Y|
-00000030  1e 00 2e 25 5a 15 03 02  00 30 00 00 00 00 00 00  |...%Z....0......|
-00000040  00 00 00 00 00 00 00 00  00 00 10 91 fd fa 59 07  |..............Y.|
-00000050  df 2c 92 25 15 7b 7c 83  44 89 0d 4f 65 43 99 2e  |.,.%.{|.D..OeC..|
-00000060  41 5d 51 c9 09 89 ed 02  08 bc                    |A]Q.......|
+00000010  00 00 00 00 00 65 81 63  71 55 1c 46 8a 60 46 d9  |.....e.cqU.F.`F.|
+00000020  7d 71 a2 62 b8 a8 3b 06  3d a2 f4 53 a4 46 a8 9e  |}q.b..;.=..S.F..|
+00000030  b7 89 8a 42 ce 15 03 02  00 30 00 00 00 00 00 00  |...B.....0......|
+00000040  00 00 00 00 00 00 00 00  00 00 7a 78 a4 e7 2f 40  |..........zx../@|
+00000050  df 42 9b 76 7a 45 0a 86  40 af 3c 40 c6 69 ba e1  |.B.vzE..@.<@.i..|
+00000060  23 82 fa 44 fd 73 fc 5b  f7 b9                    |#..D.s.[..|
diff --git a/third_party/gofrontend/libgo/go/crypto/tls/testdata/Client-TLSv11-RSA-RC4 b/third_party/gofrontend/libgo/go/crypto/tls/testdata/Client-TLSv11-RSA-RC4
index f7be3f7..729391f 100644
--- a/third_party/gofrontend/libgo/go/crypto/tls/testdata/Client-TLSv11-RSA-RC4
+++ b/third_party/gofrontend/libgo/go/crypto/tls/testdata/Client-TLSv11-RSA-RC4
@@ -1,18 +1,19 @@
 >>> Flow 1 (client to server)
-00000000  16 03 01 00 75 01 00 00  71 03 03 00 00 00 00 00  |....u...q.......|
+00000000  16 03 01 00 81 01 00 00  7d 03 03 00 00 00 00 00  |........}.......|
 00000010  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
-00000020  00 00 00 00 00 00 00 00  00 00 00 00 00 1a c0 2f  |.............../|
-00000030  c0 2b c0 11 c0 07 c0 13  c0 09 c0 14 c0 0a 00 05  |.+..............|
-00000040  00 2f 00 35 c0 12 00 0a  01 00 00 2e 00 05 00 05  |./.5............|
-00000050  01 00 00 00 00 00 0a 00  08 00 06 00 17 00 18 00  |................|
-00000060  19 00 0b 00 02 01 00 00  0d 00 0a 00 08 04 01 04  |................|
-00000070  03 02 01 02 03 ff 01 00  01 00                    |..........|
+00000020  00 00 00 00 00 00 00 00  00 00 00 00 00 1e c0 2f  |.............../|
+00000030  c0 2b c0 30 c0 2c c0 11  c0 07 c0 13 c0 09 c0 14  |.+.0.,..........|
+00000040  c0 0a 00 05 00 2f 00 35  c0 12 00 0a 01 00 00 36  |...../.5.......6|
+00000050  00 05 00 05 01 00 00 00  00 00 0a 00 08 00 06 00  |................|
+00000060  17 00 18 00 19 00 0b 00  02 01 00 00 0d 00 0e 00  |................|
+00000070  0c 04 01 04 03 05 01 05  03 02 01 02 03 ff 01 00  |................|
+00000080  01 00 00 12 00 00                                 |......|
 >>> Flow 2 (server to client)
-00000000  16 03 02 00 51 02 00 00  4d 03 02 53 04 f1 02 d4  |....Q...M..S....|
-00000010  69 65 aa 96 3d 42 96 eb  9e 7d 8a 18 af 4c 7c 5d  |ie..=B...}...L|]|
-00000020  fb 97 5f da 94 62 13 69  1f 66 06 20 aa 52 e3 08  |.._..b.i.f. .R..|
-00000030  35 0a 87 d5 ef 93 49 ab  1a 74 dd 90 bd 69 70 d1  |5.....I..t...ip.|
-00000040  e9 f1 44 17 3a dc 33 98  f5 e5 ab 93 00 05 00 00  |..D.:.3.........|
+00000000  16 03 02 00 51 02 00 00  4d 03 02 7e 38 ae 3c 50  |....Q...M..~8.<P|
+00000010  03 96 3d 54 2f cd 86 21  98 7f 87 43 d8 58 aa a3  |..=T/..!...C.X..|
+00000020  d5 9f e7 25 a6 ab 34 7f  10 5f 99 20 56 c5 a8 dd  |...%..4.._. V...|
+00000030  37 17 0d 51 f1 0d c4 4e  76 0f 01 26 56 c9 0c 20  |7..Q...Nv..&V.. |
+00000040  28 ef cd ac 38 ea d3 7f  6f aa 7c b8 00 05 00 00  |(...8...o.|.....|
 00000050  05 ff 01 00 01 00 16 03  02 02 be 0b 00 02 ba 00  |................|
 00000060  02 b7 00 02 b4 30 82 02  b0 30 82 02 19 a0 03 02  |.....0...0......|
 00000070  01 02 02 09 00 85 b0 bb  a4 8a 7f b8 ca 30 0d 06  |.............0..|
@@ -69,15 +70,15 @@
 00000060  e6 bd 77 82 6f 23 b6 e0  bd a2 92 b7 3a ac e8 56  |..w.o#......:..V|
 00000070  f1 af 54 5e 46 87 e9 3b  33 e7 b8 28 b7 d6 c8 90  |..T^F..;3..(....|
 00000080  35 d4 1c 43 d1 30 6f 55  4e 0a 70 14 03 02 00 01  |5..C.0oUN.p.....|
-00000090  01 16 03 02 00 24 07 9f  dc df 2d c3 a6 88 06 28  |.....$....-....(|
-000000a0  21 e0 e0 d3 31 99 fc 89  b8 82 6e 95 f4 4b 9e e2  |!...1.....n..K..|
-000000b0  d9 36 5c 14 ce d7 db e2  78 4e                    |.6\.....xN|
+00000090  01 16 03 02 00 24 b9 df  85 a1 6d a7 14 b5 bc f5  |.....$....m.....|
+000000a0  c2 1d 40 fc 1e 19 f2 36  2d ec 6b 59 c5 6d ae c7  |..@....6-.kY.m..|
+000000b0  1c ad 7e a3 5b 4d 12 e5  58 5a                    |..~.[M..XZ|
 >>> Flow 4 (server to client)
-00000000  14 03 02 00 01 01 16 03  02 00 24 81 72 75 80 d4  |..........$.ru..|
-00000010  1b 1a 32 00 89 bf 9e 79  30 b9 6b 67 e0 8e c7 eb  |..2....y0.kg....|
-00000020  73 f2 e4 93 51 65 9b 5f  91 b1 b4 b1 f7 44 76     |s...Qe._.....Dv|
+00000000  14 03 02 00 01 01 16 03  02 00 24 a3 f3 22 a8 32  |..........$..".2|
+00000010  63 c3 88 5c 0f fb 2d 47  21 0d 62 e2 db aa ed ae  |c..\..-G!.b.....|
+00000020  b6 5f e3 c8 98 fc 91 5e  04 83 cf c3 21 17 ce     |._.....^....!..|
 >>> Flow 5 (client to server)
-00000000  17 03 02 00 1a b2 91 39  63 c0 38 3c 4d 25 fd 14  |.......9c.8<M%..|
-00000010  b9 b6 e1 23 21 b4 8d 17  9e 1f d8 33 92 69 c2 15  |...#!......3.i..|
-00000020  03 02 00 16 4b 10 25 4d  9d 09 c2 11 96 be f7 5b  |....K.%M.......[|
-00000030  c2 9b 99 fd 1f 8e af 0f  2c 51                    |........,Q|
+00000000  17 03 02 00 1a f1 e4 46  c7 14 91 4b c6 25 fd aa  |.......F...K.%..|
+00000010  5d dd 3f 61 ac 9c 79 68  bc e6 0f a1 e4 f3 73 15  |].?a..yh......s.|
+00000020  03 02 00 16 6b 8d 23 3c  99 b4 c2 23 3c 27 fd 41  |....k.#<...#<'.A|
+00000030  cc 04 e5 fc e7 f9 d9 81  0a b8                    |..........|
diff --git a/third_party/gofrontend/libgo/go/crypto/tls/testdata/Client-TLSv12-ALPN b/third_party/gofrontend/libgo/go/crypto/tls/testdata/Client-TLSv12-ALPN
index f09a4f1..9ecb065 100644
--- a/third_party/gofrontend/libgo/go/crypto/tls/testdata/Client-TLSv12-ALPN
+++ b/third_party/gofrontend/libgo/go/crypto/tls/testdata/Client-TLSv12-ALPN
@@ -1,20 +1,20 @@
 >>> Flow 1 (client to server)
-00000000  16 03 01 00 8d 01 00 00  89 03 03 00 00 00 00 00  |................|
+00000000  16 03 01 00 99 01 00 00  95 03 03 00 00 00 00 00  |................|
 00000010  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
-00000020  00 00 00 00 00 00 00 00  00 00 00 00 00 1a c0 2f  |.............../|
-00000030  c0 2b c0 11 c0 07 c0 13  c0 09 c0 14 c0 0a 00 05  |.+..............|
-00000040  00 2f 00 35 c0 12 00 0a  01 00 00 46 33 74 00 00  |./.5.......F3t..|
-00000050  00 05 00 05 01 00 00 00  00 00 0a 00 08 00 06 00  |................|
-00000060  17 00 18 00 19 00 0b 00  02 01 00 00 0d 00 0a 00  |................|
-00000070  08 04 01 04 03 02 01 02  03 ff 01 00 01 00 00 10  |................|
-00000080  00 10 00 0e 06 70 72 6f  74 6f 32 06 70 72 6f 74  |.....proto2.prot|
-00000090  6f 31                                             |o1|
+00000020  00 00 00 00 00 00 00 00  00 00 00 00 00 1e c0 2f  |.............../|
+00000030  c0 2b c0 30 c0 2c c0 11  c0 07 c0 13 c0 09 c0 14  |.+.0.,..........|
+00000040  c0 0a 00 05 00 2f 00 35  c0 12 00 0a 01 00 00 4e  |...../.5.......N|
+00000050  33 74 00 00 00 05 00 05  01 00 00 00 00 00 0a 00  |3t..............|
+00000060  08 00 06 00 17 00 18 00  19 00 0b 00 02 01 00 00  |................|
+00000070  0d 00 0e 00 0c 04 01 04  03 05 01 05 03 02 01 02  |................|
+00000080  03 ff 01 00 01 00 00 10  00 10 00 0e 06 70 72 6f  |.............pro|
+00000090  74 6f 32 06 70 72 6f 74  6f 31 00 12 00 00        |to2.proto1....|
 >>> Flow 2 (server to client)
-00000000  16 03 03 00 66 02 00 00  62 03 03 77 a9 7d 9c 4b  |....f...b..w.}.K|
-00000010  69 65 aa dc 95 cb 78 08  3d d2 1a 0a 45 69 23 73  |ie....x.=...Ei#s|
-00000020  4f 41 4f 24 12 2e 57 47  b7 53 64 20 82 9a f8 e7  |OAO$..WG.Sd ....|
-00000030  79 f8 13 2c 9d cd b5 cb  cb 9a 95 56 0e e9 cb a8  |y..,.......V....|
-00000040  e4 a2 8a d6 bc dc fa 25  b3 57 cc cf c0 2f 00 00  |.......%.W.../..|
+00000000  16 03 03 00 66 02 00 00  62 03 03 56 83 34 0f 9e  |....f...b..V.4..|
+00000010  dd 02 1c 4f 4f 09 d0 2c  df e6 c1 d2 4a c0 6a e7  |...OO..,....J.j.|
+00000020  1e 65 51 c2 42 01 05 70  4a 6c 97 20 0f a8 fb d8  |.eQ.B..pJl. ....|
+00000030  2f 0f 75 21 17 f8 dd 63  28 4a 18 f6 b1 e5 6f 7c  |/.u!...c(J....o||
+00000040  1d 09 d4 13 bf 66 3a bd  c5 48 14 fc c0 2f 00 00  |.....f:..H.../..|
 00000050  1a ff 01 00 01 00 00 0b  00 04 03 00 01 02 00 10  |................|
 00000060  00 09 00 07 06 70 72 6f  74 6f 31 16 03 03 02 be  |.....proto1.....|
 00000070  0b 00 02 ba 00 02 b7 00  02 b4 30 82 02 b0 30 82  |..........0...0.|
@@ -61,19 +61,19 @@
 00000300  b6 d8 c9 75 90 96 8c 0f  52 98 b5 cd 98 1f 89 20  |...u....R...... |
 00000310  5f f2 a0 1c a3 1b 96 94  dd a9 fd 57 e9 70 e8 26  |_..........W.p.&|
 00000320  6d 71 99 9b 26 6e 38 50  29 6c 90 a7 bd d9 16 03  |mq..&n8P)l......|
-00000330  03 00 cd 0c 00 00 c9 03  00 17 41 04 1b 42 c3 ae  |..........A..B..|
-00000340  44 19 d3 84 7c 6c 98 cb  b9 22 a2 67 63 95 aa cc  |D...|l...".gc...|
-00000350  bd e4 1e f8 08 e6 60 f3  bc 83 9f 81 da 9c 1c 8c  |......`.........|
-00000360  ff 6f f4 3e 1e e5 3b f6  49 61 f9 70 43 7f c1 69  |.o.>..;.Ia.pC..i|
-00000370  de 73 98 4b bd 5c c3 78  24 18 a8 ec 04 01 00 80  |.s.K.\.x$.......|
-00000380  70 d2 5b e1 39 cf 4d 54  de d2 74 4e 5e a8 b3 ca  |p.[.9.MT..tN^...|
-00000390  e1 f2 4e 76 3c 77 8b ef  f7 d1 df b9 ad c1 70 39  |..Nv<w........p9|
-000003a0  c7 a3 1e 0f 7b 6c 78 2e  c1 86 d2 67 36 d8 25 e0  |....{lx....g6.%.|
-000003b0  e8 e5 cc 35 a2 96 a1 b4  b7 06 68 1e aa c7 06 97  |...5......h.....|
-000003c0  b7 c2 83 ce c0 17 dd 4f  9e 6f 7a bd cd c7 6e 7f  |.......O.oz...n.|
-000003d0  cb 80 d1 7d 06 2d f9 f1  fb 5f cc bb d8 62 5b f0  |...}.-..._...b[.|
-000003e0  27 12 57 d5 9b 55 aa 55  4b 9a 5a f6 a5 aa c1 82  |'.W..U.UK.Z.....|
-000003f0  39 11 6b dc 83 7f a8 47  28 5a 0f 3d 3f 0f c2 22  |9.k....G(Z.=?.."|
+00000330  03 00 cd 0c 00 00 c9 03  00 17 41 04 85 b7 f7 7c  |..........A....||
+00000340  49 4e 97 14 07 51 bc 56  2d 3f cf 1d 29 08 ac 6a  |IN...Q.V-?..)..j|
+00000350  b4 e7 0d 62 d8 fd 4d 03  29 0d f8 6c 36 6f 4d 5f  |...b..M.)..l6oM_|
+00000360  b7 5a 8e 37 3e c2 d9 dc  f4 15 52 e9 87 71 0f e5  |.Z.7>.....R..q..|
+00000370  4e a6 88 0e 54 35 e0 8b  50 91 e1 c4 04 01 00 80  |N...T5..P.......|
+00000380  51 eb f8 d6 52 ba f5 b5  0a 22 5f 91 fe f7 ee 43  |Q...R...."_....C|
+00000390  f8 af 52 b6 27 2c fc 14  e2 fb 41 61 ff 7c b9 be  |..R.',....Aa.|..|
+000003a0  f9 78 be dc 18 32 8c 4d  ef 46 c0 5a a7 91 6a 1b  |.x...2.M.F.Z..j.|
+000003b0  47 78 46 39 47 81 8a 2d  b4 cb fd bb 44 3e a7 b7  |GxF9G..-....D>..|
+000003c0  cc 4e df 17 7b 2b 38 49  fa 9d 9f 4e cd ed f2 16  |.N..{+8I...N....|
+000003d0  03 d9 68 cf c9 5a 08 32  f8 ed 02 30 54 61 f6 c0  |..h..Z.2...0Ta..|
+000003e0  f6 78 bc ad 04 9c 8e 90  7d 3d f5 35 86 aa 6e e9  |.x......}=.5..n.|
+000003f0  a2 9a d3 86 27 9f 2d 6e  ea 6e ad 82 0e aa ef 97  |....'.-n.n......|
 00000400  16 03 03 00 04 0e 00 00  00                       |.........|
 >>> Flow 3 (client to server)
 00000000  16 03 03 00 46 10 00 00  42 41 04 1e 18 37 ef 0d  |....F...BA...7..|
@@ -81,17 +81,17 @@
 00000020  a7 24 20 3e b2 56 1c ce  97 28 5e f8 2b 2d 4f 9e  |.$ >.V...(^.+-O.|
 00000030  f1 07 9f 6c 4b 5b 83 56  e2 32 42 e9 58 b6 d7 49  |...lK[.V.2B.X..I|
 00000040  a6 b5 68 1a 41 03 56 6b  dc 5a 89 14 03 03 00 01  |..h.A.Vk.Z......|
-00000050  01 16 03 03 00 28 00 00  00 00 00 00 00 00 35 9d  |.....(........5.|
-00000060  92 e8 bf df 7f a7 77 1b  cf 03 2a bf e2 6c 62 2b  |......w...*..lb+|
-00000070  26 f0 fb 93 d3 df fd 55  84 d3 ed 88 31 cb        |&......U....1.|
+00000050  01 16 03 03 00 28 00 00  00 00 00 00 00 00 47 18  |.....(........G.|
+00000060  39 03 93 d9 5b 27 29 70  52 68 15 79 f2 60 e6 58  |9...[')pRh.y.`.X|
+00000070  d9 98 cd ce a1 8f 4d ee  2c f0 34 9f fa 73        |......M.,.4..s|
 >>> Flow 4 (server to client)
-00000000  14 03 03 00 01 01 16 03  03 00 28 c8 c0 78 09 73  |..........(..x.s|
-00000010  58 41 73 66 88 cf db f3  fe c6 57 ab 45 be 2e d8  |XAsf......W.E...|
-00000020  4e e5 ff 42 57 13 74 d2  cc c2 62 07 39 8b 06 46  |N..BW.t...b.9..F|
-00000030  1d 8f 88                                          |...|
+00000000  14 03 03 00 01 01 16 03  03 00 28 39 76 15 70 f1  |..........(9v.p.|
+00000010  73 c9 9a 1e 76 40 bc de  de 49 be 3e 10 4d 6a 42  |s...v@...I.>.MjB|
+00000020  1b 9b bd 07 6b 19 ff f9  2c 19 3c c8 e7 06 fa c8  |....k...,.<.....|
+00000030  3d 52 b4                                          |=R.|
 >>> Flow 5 (client to server)
-00000000  17 03 03 00 1e 00 00 00  00 00 00 00 01 10 c3 5f  |..............._|
-00000010  3f c8 92 6c 7a a7 23 05  f3 d8 31 20 01 52 f1 99  |?..lz.#...1 .R..|
-00000020  33 c1 2a 15 03 03 00 1a  00 00 00 00 00 00 00 02  |3.*.............|
-00000030  cc ef eb 78 e4 e1 9d 90  05 6d 95 ac f2 49 ba 8e  |...x.....m...I..|
-00000040  6b 8d                                             |k.|
+00000000  17 03 03 00 1e 00 00 00  00 00 00 00 01 14 96 ec  |................|
+00000010  f4 bb ae 45 81 0c 39 10  e2 3a 91 51 04 2c 01 a8  |...E..9..:.Q.,..|
+00000020  8b a3 25 15 03 03 00 1a  00 00 00 00 00 00 00 02  |..%.............|
+00000030  fe 1a 53 01 17 ad a1 30  0a 73 17 9f 39 b4 30 ac  |..S....0.s..9.0.|
+00000040  91 ee                                             |..|
diff --git a/third_party/gofrontend/libgo/go/crypto/tls/testdata/Client-TLSv12-ALPN-NoMatch b/third_party/gofrontend/libgo/go/crypto/tls/testdata/Client-TLSv12-ALPN-NoMatch
index f24a70c..a22ffae 100644
--- a/third_party/gofrontend/libgo/go/crypto/tls/testdata/Client-TLSv12-ALPN-NoMatch
+++ b/third_party/gofrontend/libgo/go/crypto/tls/testdata/Client-TLSv12-ALPN-NoMatch
@@ -1,19 +1,20 @@
 >>> Flow 1 (client to server)
-00000000  16 03 01 00 86 01 00 00  82 03 03 00 00 00 00 00  |................|
+00000000  16 03 01 00 92 01 00 00  8e 03 03 00 00 00 00 00  |................|
 00000010  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
-00000020  00 00 00 00 00 00 00 00  00 00 00 00 00 1a c0 2f  |.............../|
-00000030  c0 2b c0 11 c0 07 c0 13  c0 09 c0 14 c0 0a 00 05  |.+..............|
-00000040  00 2f 00 35 c0 12 00 0a  01 00 00 3f 33 74 00 00  |./.5.......?3t..|
-00000050  00 05 00 05 01 00 00 00  00 00 0a 00 08 00 06 00  |................|
-00000060  17 00 18 00 19 00 0b 00  02 01 00 00 0d 00 0a 00  |................|
-00000070  08 04 01 04 03 02 01 02  03 ff 01 00 01 00 00 10  |................|
-00000080  00 09 00 07 06 70 72 6f  74 6f 33                 |.....proto3|
+00000020  00 00 00 00 00 00 00 00  00 00 00 00 00 1e c0 2f  |.............../|
+00000030  c0 2b c0 30 c0 2c c0 11  c0 07 c0 13 c0 09 c0 14  |.+.0.,..........|
+00000040  c0 0a 00 05 00 2f 00 35  c0 12 00 0a 01 00 00 47  |...../.5.......G|
+00000050  33 74 00 00 00 05 00 05  01 00 00 00 00 00 0a 00  |3t..............|
+00000060  08 00 06 00 17 00 18 00  19 00 0b 00 02 01 00 00  |................|
+00000070  0d 00 0e 00 0c 04 01 04  03 05 01 05 03 02 01 02  |................|
+00000080  03 ff 01 00 01 00 00 10  00 09 00 07 06 70 72 6f  |.............pro|
+00000090  74 6f 33 00 12 00 00                              |to3....|
 >>> Flow 2 (server to client)
-00000000  16 03 03 00 59 02 00 00  55 03 03 69 84 d1 d3 44  |....Y...U..i...D|
-00000010  e9 66 08 48 bc 70 d8 ae  40 0b 17 69 e7 27 f6 7a  |.f.H.p..@..i.'.z|
-00000020  d5 ee 86 74 54 9e a8 bb  79 76 89 20 57 53 1b 02  |...tT...yv. WS..|
-00000030  5b 70 81 a6 f1 53 bc 9d  b7 42 5e ac 92 93 b5 20  |[p...S...B^.... |
-00000040  8a bb 36 cc 8f cb 7e a0  61 a2 e8 ef c0 2f 00 00  |..6...~.a..../..|
+00000000  16 03 03 00 59 02 00 00  55 03 03 94 d7 79 73 82  |....Y...U....ys.|
+00000010  87 7c 85 6e 8a 1b 7d bf  69 c9 98 0c 44 bd f6 78  |.|.n..}.i...D..x|
+00000020  d2 80 dc d8 7d 80 bb 91  4b d4 ed 20 fe 9f 2f 7b  |....}...K.. ../{|
+00000030  f2 1a 44 36 cd ce af f1  b5 01 8a ac 18 e4 2b 23  |..D6..........+#|
+00000040  a8 ab 1a 32 23 8b 0b e2  81 a8 0a 40 c0 2f 00 00  |...2#......@./..|
 00000050  0d ff 01 00 01 00 00 0b  00 04 03 00 01 02 16 03  |................|
 00000060  03 02 be 0b 00 02 ba 00  02 b7 00 02 b4 30 82 02  |.............0..|
 00000070  b0 30 82 02 19 a0 03 02  01 02 02 09 00 85 b0 bb  |.0..............|
@@ -59,37 +60,37 @@
 000002f0  5f 33 c4 b6 d8 c9 75 90  96 8c 0f 52 98 b5 cd 98  |_3....u....R....|
 00000300  1f 89 20 5f f2 a0 1c a3  1b 96 94 dd a9 fd 57 e9  |.. _..........W.|
 00000310  70 e8 26 6d 71 99 9b 26  6e 38 50 29 6c 90 a7 bd  |p.&mq..&n8P)l...|
-00000320  d9 16 03 03 00 cd 0c 00  00 c9 03 00 17 41 04 04  |.............A..|
-00000330  be 27 08 6f 12 83 1b 04  76 fa 5f 16 d6 e3 64 76  |.'.o....v._...dv|
-00000340  ad 0a 77 37 71 64 44 4c  3f 1a be dc 85 ce 46 c8  |..w7qdDL?.....F.|
-00000350  29 a1 e2 24 78 66 1f 35  90 05 46 c0 91 d1 fd dd  |)..$xf.5..F.....|
-00000360  b5 5b 87 d7 6d 9d 77 a7  f7 b3 df 68 27 fd 6d 04  |.[..m.w....h'.m.|
-00000370  01 00 80 7b 9b fd 0d 62  57 07 ef 97 f5 ff a9 00  |...{...bW.......|
-00000380  a0 89 35 5a 8a e6 e7 ae  7b 55 c5 dc 21 64 87 6e  |..5Z....{U..!d.n|
-00000390  0f ab 85 6d 82 e8 83 fd  7d 3b 49 a7 ae 92 5f 6d  |...m....};I..._m|
-000003a0  a3 42 ce ff ef a6 00 6a  33 32 1f 7b eb b7 c2 5c  |.B.....j32.{...\|
-000003b0  2d 38 cf 10 4b 59 69 4d  15 e0 68 49 39 ba cb 2a  |-8..KYiM..hI9..*|
-000003c0  d9 b9 f3 fe 33 01 4f 7e  ac 69 02 35 a5 e0 33 8d  |....3.O~.i.5..3.|
-000003d0  b3 74 34 14 45 9c 89 ad  41 2d d0 27 22 90 58 c6  |.t4.E...A-.'".X.|
-000003e0  e0 2c b4 6e 19 04 e4 46  26 ec 13 35 48 a6 3f 64  |.,.n...F&..5H.?d|
-000003f0  dc 85 2b 16 03 03 00 04  0e 00 00 00              |..+.........|
+00000320  d9 16 03 03 00 cd 0c 00  00 c9 03 00 17 41 04 7d  |.............A.}|
+00000330  75 a5 53 0b a5 4d a6 81  e0 df c4 11 c9 b5 31 ba  |u.S..M........1.|
+00000340  9f 7b 51 04 57 c6 e0 b9  b0 bc 4f bc 71 74 8a 2e  |.{Q.W.....O.qt..|
+00000350  d1 f6 39 36 94 4e c7 d3  a7 1b 2c b5 55 04 71 01  |..96.N....,.U.q.|
+00000360  9e 2b 42 1e 8b a4 40 b2  13 4f 03 1f 51 9e 5c 04  |.+B...@..O..Q.\.|
+00000370  01 00 80 68 05 c7 4a ca  df 00 85 2b 53 f7 4f c3  |...h..J....+S.O.|
+00000380  b4 0f e8 f7 b8 30 b7 36  56 65 7b 03 6a 72 f1 aa  |.....0.6Ve{.jr..|
+00000390  54 30 90 9e c7 dc fc 03  96 15 70 67 13 12 a4 f4  |T0........pg....|
+000003a0  42 f0 f9 a1 48 c0 44 44  77 0e ea fd cb b5 6e 19  |B...H.DDw.....n.|
+000003b0  89 94 a7 12 67 87 47 19  c3 00 2d c4 9b d4 dc 66  |....g.G...-....f|
+000003c0  fa ca d7 97 79 9b 28 7f  74 d4 37 c0 06 63 d4 9e  |....y.(.t.7..c..|
+000003d0  a1 53 16 5a 8e d7 a5 cc  90 4d 63 f9 0c 18 85 7f  |.S.Z.....Mc.....|
+000003e0  0e 35 3a 49 73 88 82 51  41 e5 2d 58 aa 38 3e bd  |.5:Is..QA.-X.8>.|
+000003f0  3d d8 da 16 03 03 00 04  0e 00 00 00              |=...........|
 >>> Flow 3 (client to server)
 00000000  16 03 03 00 46 10 00 00  42 41 04 1e 18 37 ef 0d  |....F...BA...7..|
 00000010  19 51 88 35 75 71 b5 e5  54 5b 12 2e 8f 09 67 fd  |.Q.5uq..T[....g.|
 00000020  a7 24 20 3e b2 56 1c ce  97 28 5e f8 2b 2d 4f 9e  |.$ >.V...(^.+-O.|
 00000030  f1 07 9f 6c 4b 5b 83 56  e2 32 42 e9 58 b6 d7 49  |...lK[.V.2B.X..I|
 00000040  a6 b5 68 1a 41 03 56 6b  dc 5a 89 14 03 03 00 01  |..h.A.Vk.Z......|
-00000050  01 16 03 03 00 28 00 00  00 00 00 00 00 00 88 0d  |.....(..........|
-00000060  04 8b 8e 93 55 58 d6 75  ca 16 26 42 a3 60 20 67  |....UX.u..&B.` g|
-00000070  84 cf d7 b3 10 fe 63 6c  2f 40 64 0c d6 78        |......cl/@d..x|
+00000050  01 16 03 03 00 28 00 00  00 00 00 00 00 00 a8 da  |.....(..........|
+00000060  74 a6 d0 a5 26 86 f3 5f  89 a4 af ac 9c 1a 01 1f  |t...&.._........|
+00000070  89 8a 1c fc cf 68 3e a5  a3 20 1a b3 78 af        |.....h>.. ..x.|
 >>> Flow 4 (server to client)
-00000000  14 03 03 00 01 01 16 03  03 00 28 bd 6c 2f 70 b9  |..........(.l/p.|
-00000010  2f 9c 29 70 af 34 49 4c  5b 25 c3 14 b6 6d 28 81  |/.)p.4IL[%...m(.|
-00000020  ff 54 d9 71 8d 2c c7 38  dd 44 27 6b 54 1e 53 7b  |.T.q.,.8.D'kT.S{|
-00000030  22 cb 65                                          |".e|
+00000000  14 03 03 00 01 01 16 03  03 00 28 1a f2 a9 e8 71  |..........(....q|
+00000010  b2 a6 ca 36 4a ea 55 f6  20 03 fd f7 90 c3 af 30  |...6J.U. ......0|
+00000020  d3 29 c3 d7 1b d6 4d 3e  61 55 94 0d 4e 3e 83 1a  |.)....M>aU..N>..|
+00000030  97 dd 19                                          |...|
 >>> Flow 5 (client to server)
-00000000  17 03 03 00 1e 00 00 00  00 00 00 00 01 7f 0d d7  |................|
-00000010  d9 4b 87 7b 36 fb 24 92  69 22 43 50 1e 46 fb c4  |.K.{6.$.i"CP.F..|
-00000020  86 64 6f 15 03 03 00 1a  00 00 00 00 00 00 00 02  |.do.............|
-00000030  37 d5 2d 0a be c5 a8 ae  d4 bd 2b 09 34 18 a0 87  |7.-.......+.4...|
-00000040  08 a6                                             |..|
+00000000  17 03 03 00 1e 00 00 00  00 00 00 00 01 94 5b 5e  |..............[^|
+00000010  51 a1 52 ee 19 78 78 ef  12 0d 9c 66 bf e2 48 cb  |Q.R..xx....f..H.|
+00000020  f6 00 1e 15 03 03 00 1a  00 00 00 00 00 00 00 02  |................|
+00000030  cd 5d 31 58 d9 5a 12 65  5b c6 7e 4e e2 04 e7 1d  |.]1X.Z.e[.~N....|
+00000040  b1 4c                                             |.L|
diff --git a/third_party/gofrontend/libgo/go/crypto/tls/testdata/Client-TLSv12-ClientCert-ECDSA-ECDSA b/third_party/gofrontend/libgo/go/crypto/tls/testdata/Client-TLSv12-ClientCert-ECDSA-ECDSA
index 2073270..1470ba7 100644
--- a/third_party/gofrontend/libgo/go/crypto/tls/testdata/Client-TLSv12-ClientCert-ECDSA-ECDSA
+++ b/third_party/gofrontend/libgo/go/crypto/tls/testdata/Client-TLSv12-ClientCert-ECDSA-ECDSA
@@ -1,18 +1,19 @@
 >>> Flow 1 (client to server)
-00000000  16 03 01 00 75 01 00 00  71 03 03 00 00 00 00 00  |....u...q.......|
+00000000  16 03 01 00 81 01 00 00  7d 03 03 00 00 00 00 00  |........}.......|
 00000010  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
-00000020  00 00 00 00 00 00 00 00  00 00 00 00 00 1a c0 2f  |.............../|
-00000030  c0 2b c0 11 c0 07 c0 13  c0 09 c0 14 c0 0a 00 05  |.+..............|
-00000040  00 2f 00 35 c0 12 00 0a  01 00 00 2e 00 05 00 05  |./.5............|
-00000050  01 00 00 00 00 00 0a 00  08 00 06 00 17 00 18 00  |................|
-00000060  19 00 0b 00 02 01 00 00  0d 00 0a 00 08 04 01 04  |................|
-00000070  03 02 01 02 03 ff 01 00  01 00                    |..........|
+00000020  00 00 00 00 00 00 00 00  00 00 00 00 00 1e c0 2f  |.............../|
+00000030  c0 2b c0 30 c0 2c c0 11  c0 07 c0 13 c0 09 c0 14  |.+.0.,..........|
+00000040  c0 0a 00 05 00 2f 00 35  c0 12 00 0a 01 00 00 36  |...../.5.......6|
+00000050  00 05 00 05 01 00 00 00  00 00 0a 00 08 00 06 00  |................|
+00000060  17 00 18 00 19 00 0b 00  02 01 00 00 0d 00 0e 00  |................|
+00000070  0c 04 01 04 03 05 01 05  03 02 01 02 03 ff 01 00  |................|
+00000080  01 00 00 12 00 00                                 |......|
 >>> Flow 2 (server to client)
-00000000  16 03 03 00 59 02 00 00  55 03 03 53 04 f1 03 6f  |....Y...U..S...o|
-00000010  c6 4b 55 27 fe e8 fe 4d  7c 0e d4 20 98 b8 7c 81  |.KU'...M|.. ..|.|
-00000020  3d 31 f8 35 66 2f 0a 0b  f1 2c e3 20 86 4d 12 32  |=1.5f/...,. .M.2|
-00000030  73 e3 ba be 25 50 a4 a2  a1 7b f1 9a 76 7a 75 fb  |s...%P...{..vzu.|
-00000040  e2 64 a2 12 ec f3 e7 9d  9a 24 6e 94 c0 09 00 00  |.d.......$n.....|
+00000000  16 03 03 00 59 02 00 00  55 03 03 a5 28 60 99 bf  |....Y...U...(`..|
+00000010  c7 54 04 87 60 ad c5 32  f6 bf ed 11 47 de 4d ff  |.T..`..2....G.M.|
+00000020  99 e1 8f 88 f6 af 10 6e  29 74 0a 20 1d 39 cb e0  |.......n)t. .9..|
+00000030  a5 11 fe 8e 23 11 83 c7  a6 53 fc 97 03 9d ff 7c  |....#....S.....||
+00000040  cf 51 ba 41 64 61 38 22  5c c6 4a 04 c0 09 00 00  |.Q.Ada8"\.J.....|
 00000050  0d ff 01 00 01 00 00 0b  00 04 03 00 01 02 16 03  |................|
 00000060  03 02 0e 0b 00 02 0a 00  02 07 00 02 04 30 82 02  |.............0..|
 00000070  00 30 82 01 62 02 09 00  b8 bf 2d 47 a0 d2 eb f4  |.0..b.....-G....|
@@ -47,24 +48,23 @@
 00000240  13 83 0d 94 06 bb d4 37  7a f6 ec 7a c9 86 2e dd  |.......7z..z....|
 00000250  d7 11 69 7f 85 7c 56 de  fb 31 78 2b e4 c7 78 0d  |..i..|V..1x+..x.|
 00000260  ae cb be 9e 4e 36 24 31  7b 6a 0f 39 95 12 07 8f  |....N6$1{j.9....|
-00000270  2a 16 03 03 00 d7 0c 00  00 d3 03 00 17 41 04 a3  |*............A..|
-00000280  03 8c de d2 b0 68 c8 25  0e 85 ea d7 ae 13 0d 79  |.....h.%.......y|
-00000290  ec 59 0d b5 4d 51 96 d9  7f 64 36 fb 4c d5 6a 26  |.Y..MQ...d6.L.j&|
-000002a0  ae 0e 48 61 df 5c 2b d4  ff 09 41 15 c4 14 8e 1b  |..Ha.\+...A.....|
-000002b0  84 a8 c8 cd ef 10 97 95  66 67 85 dd fd dc 2a 04  |........fg....*.|
-000002c0  03 00 8a 30 81 87 02 41  11 75 5d bc bd 08 28 d4  |...0...A.u]...(.|
-000002d0  5b 1b 45 7f 9c d3 8d 0b  91 fa f6 82 ba 59 bd 3e  |[.E..........Y.>|
-000002e0  96 01 c6 1d 38 db fe 08  e7 56 89 fc 10 b0 37 6a  |....8....V....7j|
-000002f0  3d d6 c9 50 16 53 f7 c2  a2 60 67 82 1f 74 b8 d5  |=..P.S...`g..t..|
-00000300  bc 02 ec 96 db 82 18 8c  87 02 42 01 0d df f7 b7  |..........B.....|
-00000310  05 3c 8c 56 f0 1d 33 18  cf c5 4c 80 7e 0b d9 f9  |.<.V..3...L.~...|
-00000320  f0 51 69 fe 5d b8 0b 64  c0 c7 0d f4 75 65 ae 07  |.Qi.]..d....ue..|
-00000330  9d cf f4 4b ad 52 f6 b8  10 26 18 bd d6 e2 0d a8  |...K.R...&......|
-00000340  80 10 50 34 15 cd 72 0b  7d a9 94 de 4c 16 03 03  |..P4..r.}...L...|
-00000350  00 30 0d 00 00 28 03 01  02 40 00 20 06 01 06 02  |.0...(...@. ....|
+00000270  2a 16 03 03 00 d7 0c 00  00 d3 03 00 17 41 04 c4  |*............A..|
+00000280  0a 40 05 84 eb 90 3c 13  d0 90 af 69 fa 5c 20 75  |.@....<....i.\ u|
+00000290  e1 9b f2 30 f7 df cc 75  2c 35 7e 38 16 99 7d 57  |...0...u,5~8..}W|
+000002a0  6d d7 f0 93 2d 1d c8 03  89 6e 52 3b 20 e5 8a 5f  |m...-....nR; .._|
+000002b0  6d ca 6e 6a ca 51 f8 a4  dc 1d ec 3e 73 c9 72 04  |m.nj.Q.....>s.r.|
+000002c0  03 00 8a 30 81 87 02 41  37 bf 0d 1d c1 9a 37 39  |...0...A7.....79|
+000002d0  4d 4a f8 17 50 5d 4c 78  d4 25 99 9d 81 48 98 a8  |MJ..P]Lx.%...H..|
+000002e0  ff 2d 3f 98 4b 9f d8 96  2b fa 37 cc e8 66 25 0e  |.-?.K...+.7..f%.|
+000002f0  d3 5e 53 c5 3b ad 17 3f  21 ce d2 45 d8 93 95 6c  |.^S.;..?!..E...l|
+00000300  25 f9 5a 10 9f 37 c8 14  a6 02 42 00 e6 bd 9a 89  |%.Z..7....B.....|
+00000310  8e 73 40 f4 90 e6 d8 e2  98 51 10 23 fb 98 e5 47  |.s@......Q.#...G|
+00000320  0c 2a 7a 2f 02 66 a8 20  e4 cb 4f ba 14 1d 9e 3a  |.*z/.f. ..O....:|
+00000330  2f 09 47 44 02 e0 9f 30  21 71 f0 99 09 de 23 d2  |/.GD...0!q....#.|
+00000340  f5 f0 b2 93 70 a3 8f 79  b9 4f 88 0b 35 16 03 03  |....p..y.O..5...|
+00000350  00 2e 0d 00 00 26 03 01  02 40 00 1e 06 01 06 02  |.....&...@......|
 00000360  06 03 05 01 05 02 05 03  04 01 04 02 04 03 03 01  |................|
-00000370  03 02 03 03 02 01 02 02  02 03 01 01 00 00 0e 00  |................|
-00000380  00 00                                             |..|
+00000370  03 02 03 03 02 01 02 02  02 03 00 00 0e 00 00 00  |................|
 >>> Flow 3 (client to server)
 00000000  16 03 03 02 0a 0b 00 02  06 00 02 03 00 02 00 30  |...............0|
 00000010  82 01 fc 30 82 01 5e 02  09 00 9a 30 84 6c 26 35  |...0..^....0.l&5|
@@ -104,31 +104,31 @@
 00000230  24 20 3e b2 56 1c ce 97  28 5e f8 2b 2d 4f 9e f1  |$ >.V...(^.+-O..|
 00000240  07 9f 6c 4b 5b 83 56 e2  32 42 e9 58 b6 d7 49 a6  |..lK[.V.2B.X..I.|
 00000250  b5 68 1a 41 03 56 6b dc  5a 89 16 03 03 00 92 0f  |.h.A.Vk.Z.......|
-00000260  00 00 8e 04 03 00 8a 30  81 87 02 42 00 c6 85 8e  |.......0...B....|
-00000270  06 b7 04 04 e9 cd 9e 3e  cb 66 23 95 b4 42 9c 64  |.......>.f#..B.d|
-00000280  81 39 05 3f b5 21 f8 28  af 60 6b 4d 3d ba a1 4b  |.9.?.!.(.`kM=..K|
-00000290  5e 77 ef e7 59 28 fe 1d  c1 27 a2 ff a8 de 33 48  |^w..Y(...'....3H|
-000002a0  b3 c1 85 6a 42 9b f9 7e  7e 31 c2 e5 bd 66 02 41  |...jB..~~1...f.A|
-000002b0  4b 49 c6 cd 02 e3 83 f7  03 50 18 6d b4 c9 51 02  |KI.......P.m..Q.|
-000002c0  c0 ab 87 bc e0 3e 4b 89  53 3a e2 65 89 97 02 c1  |.....>K.S:.e....|
-000002d0  88 0d 64 db 8e 4f 73 4e  ea 29 0b ed a0 f5 ce 3d  |..d..OsN.).....=|
-000002e0  5f cc 20 ef 0a 22 02 82  f2 14 2a b7 42 68 bd c7  |_. .."....*.Bh..|
-000002f0  4d 14 03 03 00 01 01 16  03 03 00 40 00 00 00 00  |M..........@....|
-00000300  00 00 00 00 00 00 00 00  00 00 00 00 f0 cc 4f c7  |..............O.|
-00000310  b6 0f c9 38 4d 4b 97 2c  4f be 53 08 4c d6 5b 4e  |...8MK.,O.S.L.[N|
-00000320  24 70 30 81 82 3a 7f 62  95 03 4d fc 54 78 ec 13  |$p0..:.b..M.Tx..|
-00000330  b2 a1 00 85 2b 04 e4 1d  7b 6e 87 60              |....+...{n.`|
+00000260  00 00 8e 05 03 00 8a 30  81 87 02 42 00 cc a4 ad  |.......0...B....|
+00000270  0b ff 09 40 8f 2c a6 37  72 1d f7 d2 19 74 85 ad  |...@.,.7r....t..|
+00000280  ac 33 b0 b8 5b 56 39 cf  b0 ef 46 68 94 39 4c d0  |.3..[V9...Fh.9L.|
+00000290  f4 97 32 10 99 36 c5 95  c8 14 23 37 78 46 5c a9  |..2..6....#7xF\.|
+000002a0  20 95 65 47 ff 54 02 f1  aa 1d d7 bc 39 2d 02 41  | .eG.T......9-.A|
+000002b0  2e f9 d6 8c e8 c5 a9 6f  10 4f d6 5f 4e 88 e9 71  |.......o.O._N..q|
+000002c0  23 5b 6f b8 ab 19 d3 dd  ec f3 32 e3 3b fa 41 a2  |#[o.......2.;.A.|
+000002d0  e8 ae dc 27 8d 4e 79 f4  47 ef c9 8f bf 0b 41 3b  |...'.Ny.G.....A;|
+000002e0  94 16 cb 8f 1e b5 f3 4e  6e 42 46 35 1a 0c ca 79  |.......NnBF5...y|
+000002f0  4b 14 03 03 00 01 01 16  03 03 00 40 00 00 00 00  |K..........@....|
+00000300  00 00 00 00 00 00 00 00  00 00 00 00 64 1c d9 9f  |............d...|
+00000310  34 ec c2 74 76 7a 9f cf  95 19 be 8d 6a 2f 25 96  |4..tvz......j/%.|
+00000320  df de 18 ca 0e c9 d4 2f  e4 b0 34 10 5b 72 7a 18  |......./..4.[rz.|
+00000330  5c 64 d7 fc 2e 1b 28 10  ae a6 31 e9              |\d....(...1.|
 >>> Flow 4 (server to client)
-00000000  14 03 03 00 01 01 16 03  03 00 40 d5 2a 76 79 1c  |..........@.*vy.|
-00000010  e7 d5 b1 5c 65 6b d1 45  73 53 4c 05 3a 6c 5d 81  |...\ek.EsSL.:l].|
-00000020  dd 2f f0 74 62 e4 8e f8  ed 21 99 c7 4f d6 28 40  |./.tb....!..O.(@|
-00000030  63 d9 6d e5 b0 04 73 27  7a 1d 08 19 31 10 da ef  |c.m...s'z...1...|
-00000040  79 26 33 fb 45 23 be a4  7c 03 66                 |y&3.E#..|.f|
+00000000  14 03 03 00 01 01 16 03  03 00 40 27 6f 24 a3 0c  |..........@'o$..|
+00000010  6d d7 68 4a fb 43 b0 97  02 6c 22 7e 2f a1 f1 7a  |m.hJ.C...l"~/..z|
+00000020  37 bf 38 82 dc a0 83 24  01 4b c0 4f 15 e1 7c 4c  |7.8....$.K.O..|L|
+00000030  d4 cd b8 e2 71 af f5 20  7d f9 4a 48 4b f0 a1 f3  |....q.. }.JHK...|
+00000040  7b 02 29 18 c0 87 a5 dd  c4 73 8e                 |{.)......s.|
 >>> Flow 5 (client to server)
 00000000  17 03 03 00 30 00 00 00  00 00 00 00 00 00 00 00  |....0...........|
-00000010  00 00 00 00 00 e2 53 bd  c0 ef 9e e6 44 94 ea 5d  |......S.....D..]|
-00000020  f5 c5 a9 4b ed eb 1c 49  9f 79 44 f9 cd d7 de 02  |...K...I.yD.....|
-00000030  51 10 ae 87 7d 15 03 03  00 30 00 00 00 00 00 00  |Q...}....0......|
-00000040  00 00 00 00 00 00 00 00  00 00 d3 95 13 7f 5f 58  |.............._X|
-00000050  ab d6 17 ea 01 2c 2a ea  5d 7c 44 61 4a 27 97 52  |.....,*.]|DaJ'.R|
-00000060  cc 9b 86 f6 37 42 2b 94  01 49                    |....7B+..I|
+00000010  00 00 00 00 00 bf 7a e1  23 0d d0 13 6e 96 81 6d  |......z.#...n..m|
+00000020  32 56 0f 75 7e 01 88 5f  6d e6 d6 ca ec 3c 17 e9  |2V.u~.._m....<..|
+00000030  44 a9 c0 1c a4 15 03 03  00 30 00 00 00 00 00 00  |D........0......|
+00000040  00 00 00 00 00 00 00 00  00 00 76 be 7a 77 29 01  |..........v.zw).|
+00000050  8e 13 02 66 81 43 a0 55  03 35 22 09 de ea 52 bb  |...f.C.U.5"...R.|
+00000060  51 cc c1 09 0e 9b 4d bd  94 85                    |Q.....M...|
diff --git a/third_party/gofrontend/libgo/go/crypto/tls/testdata/Client-TLSv12-ClientCert-ECDSA-RSA b/third_party/gofrontend/libgo/go/crypto/tls/testdata/Client-TLSv12-ClientCert-ECDSA-RSA
index c3b753a..95c5782 100644
--- a/third_party/gofrontend/libgo/go/crypto/tls/testdata/Client-TLSv12-ClientCert-ECDSA-RSA
+++ b/third_party/gofrontend/libgo/go/crypto/tls/testdata/Client-TLSv12-ClientCert-ECDSA-RSA
@@ -1,18 +1,19 @@
 >>> Flow 1 (client to server)
-00000000  16 03 01 00 75 01 00 00  71 03 03 00 00 00 00 00  |....u...q.......|
+00000000  16 03 01 00 81 01 00 00  7d 03 03 00 00 00 00 00  |........}.......|
 00000010  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
-00000020  00 00 00 00 00 00 00 00  00 00 00 00 00 1a c0 2f  |.............../|
-00000030  c0 2b c0 11 c0 07 c0 13  c0 09 c0 14 c0 0a 00 05  |.+..............|
-00000040  00 2f 00 35 c0 12 00 0a  01 00 00 2e 00 05 00 05  |./.5............|
-00000050  01 00 00 00 00 00 0a 00  08 00 06 00 17 00 18 00  |................|
-00000060  19 00 0b 00 02 01 00 00  0d 00 0a 00 08 04 01 04  |................|
-00000070  03 02 01 02 03 ff 01 00  01 00                    |..........|
+00000020  00 00 00 00 00 00 00 00  00 00 00 00 00 1e c0 2f  |.............../|
+00000030  c0 2b c0 30 c0 2c c0 11  c0 07 c0 13 c0 09 c0 14  |.+.0.,..........|
+00000040  c0 0a 00 05 00 2f 00 35  c0 12 00 0a 01 00 00 36  |...../.5.......6|
+00000050  00 05 00 05 01 00 00 00  00 00 0a 00 08 00 06 00  |................|
+00000060  17 00 18 00 19 00 0b 00  02 01 00 00 0d 00 0e 00  |................|
+00000070  0c 04 01 04 03 05 01 05  03 02 01 02 03 ff 01 00  |................|
+00000080  01 00 00 12 00 00                                 |......|
 >>> Flow 2 (server to client)
-00000000  16 03 03 00 51 02 00 00  4d 03 03 53 04 f1 03 b0  |....Q...M..S....|
-00000010  43 00 97 24 a7 a8 ea b2  24 fe 96 24 a1 49 64 fd  |C..$....$..$.Id.|
-00000020  1c a3 30 35 2d 85 a7 40  42 86 6b 20 af 27 7f ac  |..05-..@B.k .'..|
-00000030  8b 16 89 6c 78 b7 f5 29  02 58 a6 8b 61 43 c2 b0  |...lx..).X..aC..|
-00000040  e0 a8 96 c8 fa 2b 26 ad  9a 5f 2d d6 00 05 00 00  |.....+&.._-.....|
+00000000  16 03 03 00 51 02 00 00  4d 03 03 79 e8 35 e3 d2  |....Q...M..y.5..|
+00000010  c0 5e 39 d1 46 da 9c 94  56 20 e2 06 d6 9b f6 dd  |.^9.F...V ......|
+00000020  4f 7a c1 e8 34 a1 9f 8b  c2 e1 fb 20 66 9c 5a 9a  |Oz..4...... f.Z.|
+00000030  3d 22 ab 8e d8 81 03 94  68 a0 6c 72 d8 23 0b 4b  |="......h.lr.#.K|
+00000040  fe 9d c7 49 a7 7c bd fa  b5 7a 5e 5b 00 05 00 00  |...I.|...z^[....|
 00000050  05 ff 01 00 01 00 16 03  03 02 be 0b 00 02 ba 00  |................|
 00000060  02 b7 00 02 b4 30 82 02  b0 30 82 02 19 a0 03 02  |.....0...0......|
 00000070  01 02 02 09 00 85 b0 bb  a4 8a 7f b8 ca 30 0d 06  |.............0..|
@@ -57,10 +58,10 @@
 000002e0  50 56 5c d5 82 5a 2d 5a  5f 33 c4 b6 d8 c9 75 90  |PV\..Z-Z_3....u.|
 000002f0  96 8c 0f 52 98 b5 cd 98  1f 89 20 5f f2 a0 1c a3  |...R...... _....|
 00000300  1b 96 94 dd a9 fd 57 e9  70 e8 26 6d 71 99 9b 26  |......W.p.&mq..&|
-00000310  6e 38 50 29 6c 90 a7 bd  d9 16 03 03 00 30 0d 00  |n8P)l........0..|
-00000320  00 28 03 01 02 40 00 20  06 01 06 02 06 03 05 01  |.(...@. ........|
+00000310  6e 38 50 29 6c 90 a7 bd  d9 16 03 03 00 2e 0d 00  |n8P)l...........|
+00000320  00 26 03 01 02 40 00 1e  06 01 06 02 06 03 05 01  |.&...@..........|
 00000330  05 02 05 03 04 01 04 02  04 03 03 01 03 02 03 03  |................|
-00000340  02 01 02 02 02 03 01 01  00 00 0e 00 00 00        |..............|
+00000340  02 01 02 02 02 03 00 00  0e 00 00 00              |............|
 >>> Flow 3 (client to server)
 00000000  16 03 03 02 0a 0b 00 02  06 00 02 03 00 02 00 30  |...............0|
 00000010  82 01 fc 30 82 01 5e 02  09 00 9a 30 84 6c 26 35  |...0..^....0.l&5|
@@ -104,24 +105,24 @@
 00000270  bd 77 82 6f 23 b6 e0 bd  a2 92 b7 3a ac e8 56 f1  |.w.o#......:..V.|
 00000280  af 54 5e 46 87 e9 3b 33  e7 b8 28 b7 d6 c8 90 35  |.T^F..;3..(....5|
 00000290  d4 1c 43 d1 30 6f 55 4e  0a 70 16 03 03 00 92 0f  |..C.0oUN.p......|
-000002a0  00 00 8e 04 03 00 8a 30  81 87 02 42 00 c6 85 8e  |.......0...B....|
-000002b0  06 b7 04 04 e9 cd 9e 3e  cb 66 23 95 b4 42 9c 64  |.......>.f#..B.d|
-000002c0  81 39 05 3f b5 21 f8 28  af 60 6b 4d 3d ba a1 4b  |.9.?.!.(.`kM=..K|
-000002d0  5e 77 ef e7 59 28 fe 1d  c1 27 a2 ff a8 de 33 48  |^w..Y(...'....3H|
-000002e0  b3 c1 85 6a 42 9b f9 7e  7e 31 c2 e5 bd 66 02 41  |...jB..~~1...f.A|
-000002f0  4b 49 c6 cd 02 e3 83 f7  03 50 18 6d b4 c9 51 02  |KI.......P.m..Q.|
-00000300  c0 ab 87 bc e0 3e 4b 89  53 3a e2 65 89 97 02 c1  |.....>K.S:.e....|
-00000310  88 5a 97 82 3e 55 6b 7c  d8 db b8 cc 1b 30 84 0a  |.Z..>Uk|.....0..|
-00000320  7a 97 71 e4 10 bb a4 39  8c 2a cf f5 88 c7 d1 95  |z.q....9.*......|
-00000330  73 14 03 03 00 01 01 16  03 03 00 24 9f 1e f0 72  |s..........$...r|
-00000340  92 ea dc f7 56 96 37 e4  69 db db 66 1d f6 94 c4  |....V.7.i..f....|
-00000350  18 31 4f d0 5d c5 f4 53  21 aa 98 b1 dc 08 94 94  |.1O.]..S!.......|
+000002a0  00 00 8e 05 03 00 8a 30  81 87 02 41 19 c7 50 06  |.......0...A..P.|
+000002b0  42 82 f9 e5 ec 0b f7 65  7e b1 19 53 5f 23 ab 19  |B......e~..S_#..|
+000002c0  54 08 ec d2 a7 22 dd 83  7c 97 76 59 a5 6b f4 1d  |T...."..|.vY.k..|
+000002d0  92 86 34 2d ce 71 bb 01  d2 8a 67 0e a8 fb 51 e4  |..4-.q....g...Q.|
+000002e0  69 9c 27 23 74 b9 fd 6f  b6 5e 48 a0 cc 02 42 01  |i.'#t..o.^H...B.|
+000002f0  50 97 b7 95 14 f4 a6 f2  95 63 17 38 59 a1 51 95  |P........c.8Y.Q.|
+00000300  1e bc 99 fb fd 82 8b ab  cb 4d 8e 17 a9 f8 e9 c2  |.........M......|
+00000310  9b 93 15 02 50 e6 c2 05  54 e7 8a ec 6f 93 1f 79  |....P...T...o..y|
+00000320  8d 67 e7 2d d6 65 ab 97  fd be 20 97 bd 6b c4 fc  |.g.-.e.... ..k..|
+00000330  02 14 03 03 00 01 01 16  03 03 00 24 24 df 52 6e  |...........$$.Rn|
+00000340  c1 35 48 fe 60 77 28 69  36 fe 96 a1 72 db a2 f5  |.5H.`w(i6...r...|
+00000350  d0 b7 c3 d9 67 e5 ee f2  d9 18 bf f0 35 80 06 c2  |....g.......5...|
 >>> Flow 4 (server to client)
-00000000  14 03 03 00 01 01 16 03  03 00 24 ee 68 c1 87 9f  |..........$.h...|
-00000010  d7 90 94 f1 3b 6d 26 0b  3d 89 7a 45 3b 52 5d 3c  |....;m&.=.zE;R]<|
-00000020  dd 7c c1 4e 57 3e a9 ee  91 be cf 2b a3 98 9d     |.|.NW>.....+...|
+00000000  14 03 03 00 01 01 16 03  03 00 24 40 5b dc 01 59  |..........$@[..Y|
+00000010  33 6e 61 5a 6d fc c8 a5  f5 00 9b 55 77 c5 e6 f2  |3naZm......Uw...|
+00000020  c6 5c b6 2f 94 3c 72 5b  b5 0c 3e 78 88 e6 44     |.\./.<r[..>x..D|
 >>> Flow 5 (client to server)
-00000000  17 03 03 00 1a 88 33 3e  2b 22 6b 92 d0 bb 8a 1e  |......3>+"k.....|
-00000010  9b f4 9e aa 91 8b 2b 95  ea 53 c8 03 0a 93 58 15  |......+..S....X.|
-00000020  03 03 00 16 c4 67 79 ba  ec cf 90 b1 f9 ac ec 64  |.....gy........d|
-00000030  72 01 08 8f 3a 98 aa 66  25 00                    |r...:..f%.|
+00000000  17 03 03 00 1a cd 2f 11  b1 3a e4 1c 31 95 9b c4  |....../..:..1...|
+00000010  37 20 9f 03 d3 45 a4 15  e1 09 1e 0c f6 5d d3 15  |7 ...E.......]..|
+00000020  03 03 00 16 d7 f6 a1 d0  ad 41 69 73 c0 40 22 f2  |.........Ais.@".|
+00000030  5f e8 c3 50 f9 35 fc 59  e0 3a                    |_..P.5.Y.:|
diff --git a/third_party/gofrontend/libgo/go/crypto/tls/testdata/Client-TLSv12-ClientCert-RSA-AES256-GCM-SHA384 b/third_party/gofrontend/libgo/go/crypto/tls/testdata/Client-TLSv12-ClientCert-RSA-AES256-GCM-SHA384
new file mode 100644
index 0000000..52e3bef
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/crypto/tls/testdata/Client-TLSv12-ClientCert-RSA-AES256-GCM-SHA384
@@ -0,0 +1,139 @@
+>>> Flow 1 (client to server)
+00000000  16 03 01 00 81 01 00 00  7d 03 03 00 00 00 00 00  |........}.......|
+00000010  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
+00000020  00 00 00 00 00 00 00 00  00 00 00 00 00 1e c0 2f  |.............../|
+00000030  c0 2b c0 30 c0 2c c0 11  c0 07 c0 13 c0 09 c0 14  |.+.0.,..........|
+00000040  c0 0a 00 05 00 2f 00 35  c0 12 00 0a 01 00 00 36  |...../.5.......6|
+00000050  00 05 00 05 01 00 00 00  00 00 0a 00 08 00 06 00  |................|
+00000060  17 00 18 00 19 00 0b 00  02 01 00 00 0d 00 0e 00  |................|
+00000070  0c 04 01 04 03 05 01 05  03 02 01 02 03 ff 01 00  |................|
+00000080  01 00 00 12 00 00                                 |......|
+>>> Flow 2 (server to client)
+00000000  16 03 03 00 59 02 00 00  55 03 03 74 fe 19 af 4b  |....Y...U..t...K|
+00000010  f3 d8 92 62 5a df 90 2c  cc 09 fd 79 45 26 cd 52  |...bZ..,...yE&.R|
+00000020  9a e6 da 16 99 fe 1d 91  79 a7 a0 20 b3 13 e9 03  |........y.. ....|
+00000030  52 23 5f f0 55 59 f1 9e  00 a7 77 97 90 ed 2b fb  |R#_.UY....w...+.|
+00000040  9c ab fe b1 db ea 16 95  95 68 b0 e9 c0 30 00 00  |.........h...0..|
+00000050  0d ff 01 00 01 00 00 0b  00 04 03 00 01 02 16 03  |................|
+00000060  03 02 be 0b 00 02 ba 00  02 b7 00 02 b4 30 82 02  |.............0..|
+00000070  b0 30 82 02 19 a0 03 02  01 02 02 09 00 85 b0 bb  |.0..............|
+00000080  a4 8a 7f b8 ca 30 0d 06  09 2a 86 48 86 f7 0d 01  |.....0...*.H....|
+00000090  01 05 05 00 30 45 31 0b  30 09 06 03 55 04 06 13  |....0E1.0...U...|
+000000a0  02 41 55 31 13 30 11 06  03 55 04 08 13 0a 53 6f  |.AU1.0...U....So|
+000000b0  6d 65 2d 53 74 61 74 65  31 21 30 1f 06 03 55 04  |me-State1!0...U.|
+000000c0  0a 13 18 49 6e 74 65 72  6e 65 74 20 57 69 64 67  |...Internet Widg|
+000000d0  69 74 73 20 50 74 79 20  4c 74 64 30 1e 17 0d 31  |its Pty Ltd0...1|
+000000e0  30 30 34 32 34 30 39 30  39 33 38 5a 17 0d 31 31  |00424090938Z..11|
+000000f0  30 34 32 34 30 39 30 39  33 38 5a 30 45 31 0b 30  |0424090938Z0E1.0|
+00000100  09 06 03 55 04 06 13 02  41 55 31 13 30 11 06 03  |...U....AU1.0...|
+00000110  55 04 08 13 0a 53 6f 6d  65 2d 53 74 61 74 65 31  |U....Some-State1|
+00000120  21 30 1f 06 03 55 04 0a  13 18 49 6e 74 65 72 6e  |!0...U....Intern|
+00000130  65 74 20 57 69 64 67 69  74 73 20 50 74 79 20 4c  |et Widgits Pty L|
+00000140  74 64 30 81 9f 30 0d 06  09 2a 86 48 86 f7 0d 01  |td0..0...*.H....|
+00000150  01 01 05 00 03 81 8d 00  30 81 89 02 81 81 00 bb  |........0.......|
+00000160  79 d6 f5 17 b5 e5 bf 46  10 d0 dc 69 be e6 2b 07  |y......F...i..+.|
+00000170  43 5a d0 03 2d 8a 7a 43  85 b7 14 52 e7 a5 65 4c  |CZ..-.zC...R..eL|
+00000180  2c 78 b8 23 8c b5 b4 82  e5 de 1f 95 3b 7e 62 a5  |,x.#........;~b.|
+00000190  2c a5 33 d6 fe 12 5c 7a  56 fc f5 06 bf fa 58 7b  |,.3...\zV.....X{|
+000001a0  26 3f b5 cd 04 d3 d0 c9  21 96 4a c7 f4 54 9f 5a  |&?......!.J..T.Z|
+000001b0  bf ef 42 71 00 fe 18 99  07 7f 7e 88 7d 7d f1 04  |..Bq......~.}}..|
+000001c0  39 c4 a2 2e db 51 c9 7c  e3 c0 4c 3b 32 66 01 cf  |9....Q.|..L;2f..|
+000001d0  af b1 1d b8 71 9a 1d db  db 89 6b ae da 2d 79 02  |....q.....k..-y.|
+000001e0  03 01 00 01 a3 81 a7 30  81 a4 30 1d 06 03 55 1d  |.......0..0...U.|
+000001f0  0e 04 16 04 14 b1 ad e2  85 5a cf cb 28 db 69 ce  |.........Z..(.i.|
+00000200  23 69 de d3 26 8e 18 88  39 30 75 06 03 55 1d 23  |#i..&...90u..U.#|
+00000210  04 6e 30 6c 80 14 b1 ad  e2 85 5a cf cb 28 db 69  |.n0l......Z..(.i|
+00000220  ce 23 69 de d3 26 8e 18  88 39 a1 49 a4 47 30 45  |.#i..&...9.I.G0E|
+00000230  31 0b 30 09 06 03 55 04  06 13 02 41 55 31 13 30  |1.0...U....AU1.0|
+00000240  11 06 03 55 04 08 13 0a  53 6f 6d 65 2d 53 74 61  |...U....Some-Sta|
+00000250  74 65 31 21 30 1f 06 03  55 04 0a 13 18 49 6e 74  |te1!0...U....Int|
+00000260  65 72 6e 65 74 20 57 69  64 67 69 74 73 20 50 74  |ernet Widgits Pt|
+00000270  79 20 4c 74 64 82 09 00  85 b0 bb a4 8a 7f b8 ca  |y Ltd...........|
+00000280  30 0c 06 03 55 1d 13 04  05 30 03 01 01 ff 30 0d  |0...U....0....0.|
+00000290  06 09 2a 86 48 86 f7 0d  01 01 05 05 00 03 81 81  |..*.H...........|
+000002a0  00 08 6c 45 24 c7 6b b1  59 ab 0c 52 cc f2 b0 14  |..lE$.k.Y..R....|
+000002b0  d7 87 9d 7a 64 75 b5 5a  95 66 e4 c5 2b 8e ae 12  |...zdu.Z.f..+...|
+000002c0  66 1f eb 4f 38 b3 6e 60  d3 92 fd f7 41 08 b5 25  |f..O8.n`....A..%|
+000002d0  13 b1 18 7a 24 fb 30 1d  ba ed 98 b9 17 ec e7 d7  |...z$.0.........|
+000002e0  31 59 db 95 d3 1d 78 ea  50 56 5c d5 82 5a 2d 5a  |1Y....x.PV\..Z-Z|
+000002f0  5f 33 c4 b6 d8 c9 75 90  96 8c 0f 52 98 b5 cd 98  |_3....u....R....|
+00000300  1f 89 20 5f f2 a0 1c a3  1b 96 94 dd a9 fd 57 e9  |.. _..........W.|
+00000310  70 e8 26 6d 71 99 9b 26  6e 38 50 29 6c 90 a7 bd  |p.&mq..&n8P)l...|
+00000320  d9 16 03 03 00 cd 0c 00  00 c9 03 00 17 41 04 22  |.............A."|
+00000330  84 e9 5e 6e 35 92 a3 83  73 0a d6 0d 1a c1 4d ab  |..^n5...s.....M.|
+00000340  1f ab c2 dc 3f 53 a5 7d  38 c0 92 a4 82 e1 3c c5  |....?S.}8.....<.|
+00000350  24 60 20 a5 3b c5 65 ba  9c f1 b9 a5 b9 c2 70 73  |$` .;.e.......ps|
+00000360  19 74 a6 d1 0f 75 b4 75  e0 e8 60 20 e9 23 fe 04  |.t...u.u..` .#..|
+00000370  01 00 80 92 e0 56 3f 48  0d 10 23 48 b5 95 b6 91  |.....V?H..#H....|
+00000380  3e 8a 2e c7 02 e2 85 0e  59 c8 03 24 d9 1a 1a 25  |>.......Y..$...%|
+00000390  8e 12 bb 0b 83 ac 51 36  81 3f bc 0e be b9 3b 1d  |......Q6.?....;.|
+000003a0  67 56 21 4d 24 36 84 05  61 e7 70 60 d5 8e ae 97  |gV!M$6..a.p`....|
+000003b0  b8 3a d3 b1 94 72 52 cd  b0 0d dd 46 b1 15 3b 58  |.:...rR....F..;X|
+000003c0  c1 a4 63 2c 4c 31 f9 c7  4f 27 c1 0f f0 24 36 72  |..c,L1..O'...$6r|
+000003d0  e0 f8 51 12 86 c2 13 ed  6b 84 a8 15 c3 d0 39 55  |..Q.....k.....9U|
+000003e0  a4 60 50 88 c9 1e 60 60  aa 8d a5 31 3e 35 c3 f8  |.`P...``...1>5..|
+000003f0  2c 90 1c 16 03 03 00 2e  0d 00 00 26 03 01 02 40  |,..........&...@|
+00000400  00 1e 06 01 06 02 06 03  05 01 05 02 05 03 04 01  |................|
+00000410  04 02 04 03 03 01 03 02  03 03 02 01 02 02 02 03  |................|
+00000420  00 00 0e 00 00 00                                 |......|
+>>> Flow 3 (client to server)
+00000000  16 03 03 01 fb 0b 00 01  f7 00 01 f4 00 01 f1 30  |...............0|
+00000010  82 01 ed 30 82 01 58 a0  03 02 01 02 02 01 00 30  |...0..X........0|
+00000020  0b 06 09 2a 86 48 86 f7  0d 01 01 05 30 26 31 10  |...*.H......0&1.|
+00000030  30 0e 06 03 55 04 0a 13  07 41 63 6d 65 20 43 6f  |0...U....Acme Co|
+00000040  31 12 30 10 06 03 55 04  03 13 09 31 32 37 2e 30  |1.0...U....127.0|
+00000050  2e 30 2e 31 30 1e 17 0d  31 31 31 32 30 38 30 37  |.0.10...11120807|
+00000060  35 35 31 32 5a 17 0d 31  32 31 32 30 37 30 38 30  |5512Z..121207080|
+00000070  30 31 32 5a 30 26 31 10  30 0e 06 03 55 04 0a 13  |012Z0&1.0...U...|
+00000080  07 41 63 6d 65 20 43 6f  31 12 30 10 06 03 55 04  |.Acme Co1.0...U.|
+00000090  03 13 09 31 32 37 2e 30  2e 30 2e 31 30 81 9c 30  |...127.0.0.10..0|
+000000a0  0b 06 09 2a 86 48 86 f7  0d 01 01 01 03 81 8c 00  |...*.H..........|
+000000b0  30 81 88 02 81 80 4e d0  7b 31 e3 82 64 d9 59 c0  |0.....N.{1..d.Y.|
+000000c0  c2 87 a4 5e 1e 8b 73 33  c7 63 53 df 66 92 06 84  |...^..s3.cS.f...|
+000000d0  f6 64 d5 8f e4 36 a7 1d  2b e8 b3 20 36 45 23 b5  |.d...6..+.. 6E#.|
+000000e0  e3 95 ae ed e0 f5 20 9c  8d 95 df 7f 5a 12 ef 87  |...... .....Z...|
+000000f0  e4 5b 68 e4 e9 0e 74 ec  04 8a 7f de 93 27 c4 01  |.[h...t......'..|
+00000100  19 7a bd f2 dc 3d 14 ab  d0 54 ca 21 0c d0 4d 6e  |.z...=...T.!..Mn|
+00000110  87 2e 5c c5 d2 bb 4d 4b  4f ce b6 2c f7 7e 88 ec  |..\...MKO..,.~..|
+00000120  7c d7 02 91 74 a6 1e 0c  1a da e3 4a 5a 2e de 13  ||...t......JZ...|
+00000130  9c 4c 40 88 59 93 02 03  01 00 01 a3 32 30 30 30  |.L@.Y.......2000|
+00000140  0e 06 03 55 1d 0f 01 01  ff 04 04 03 02 00 a0 30  |...U...........0|
+00000150  0d 06 03 55 1d 0e 04 06  04 04 01 02 03 04 30 0f  |...U..........0.|
+00000160  06 03 55 1d 23 04 08 30  06 80 04 01 02 03 04 30  |..U.#..0.......0|
+00000170  0b 06 09 2a 86 48 86 f7  0d 01 01 05 03 81 81 00  |...*.H..........|
+00000180  36 1f b3 7a 0c 75 c9 6e  37 46 61 2b d5 bd c0 a7  |6..z.u.n7Fa+....|
+00000190  4b cc 46 9a 81 58 7c 85  79 29 c8 c8 c6 67 dd 32  |K.F..X|.y)...g.2|
+000001a0  56 45 2b 75 b6 e9 24 a9  50 9a be 1f 5a fa 1a 15  |VE+u..$.P...Z...|
+000001b0  d9 cc 55 95 72 16 83 b9  c2 b6 8f fd 88 8c 38 84  |..U.r.........8.|
+000001c0  1d ab 5d 92 31 13 4f fd  83 3b c6 9d f1 11 62 b6  |..].1.O..;....b.|
+000001d0  8b ec ab 67 be c8 64 b0  11 50 46 58 17 6b 99 1c  |...g..d..PFX.k..|
+000001e0  d3 1d fc 06 f1 0e e5 96  a8 0c f9 78 20 b7 44 18  |...........x .D.|
+000001f0  51 8d 10 7e 4f 94 67 df  a3 4e 70 73 8e 90 91 85  |Q..~O.g..Nps....|
+00000200  16 03 03 00 46 10 00 00  42 41 04 1e 18 37 ef 0d  |....F...BA...7..|
+00000210  19 51 88 35 75 71 b5 e5  54 5b 12 2e 8f 09 67 fd  |.Q.5uq..T[....g.|
+00000220  a7 24 20 3e b2 56 1c ce  97 28 5e f8 2b 2d 4f 9e  |.$ >.V...(^.+-O.|
+00000230  f1 07 9f 6c 4b 5b 83 56  e2 32 42 e9 58 b6 d7 49  |...lK[.V.2B.X..I|
+00000240  a6 b5 68 1a 41 03 56 6b  dc 5a 89 16 03 03 00 88  |..h.A.Vk.Z......|
+00000250  0f 00 00 84 05 01 00 80  33 bb 8e 67 64 03 e7 7e  |........3..gd..~|
+00000260  be a5 b1 bc cf 7a 07 24  01 17 c3 3d 4b 72 dd c3  |.....z.$...=Kr..|
+00000270  64 a7 36 e8 49 ab b6 87  ce d6 af 9e 07 22 76 e8  |d.6.I........"v.|
+00000280  0d 44 a3 36 c9 eb a4 49  85 cf 72 67 e8 2a a7 5b  |.D.6...I..rg.*.[|
+00000290  d3 f2 46 af 53 48 c6 13  f7 0b 5b 9c c7 4d 3e 05  |..F.SH....[..M>.|
+000002a0  3c 0f 69 a7 40 3a e8 70  04 01 1c 29 b2 42 0f 5f  |<.i.@:.p...).B._|
+000002b0  1c d5 b7 5c c2 17 07 7f  bd a2 b3 9a 95 81 51 24  |...\..........Q$|
+000002c0  54 5c 42 d6 a4 76 c0 d7  54 d2 11 54 bf fd dc a0  |T\B..v..T..T....|
+000002d0  ee 95 26 64 59 a0 fc 51  14 03 03 00 01 01 16 03  |..&dY..Q........|
+000002e0  03 00 28 00 00 00 00 00  00 00 00 af f4 8a be d9  |..(.............|
+000002f0  ff f1 44 e4 41 ab 9b b3  d8 b0 3d 3f 6b c5 1d b6  |..D.A.....=?k...|
+00000300  1d 9e 35 f5 20 f4 2a af  e8 35 77                 |..5. .*..5w|
+>>> Flow 4 (server to client)
+00000000  14 03 03 00 01 01 16 03  03 00 28 ff 0d 47 63 2b  |..........(..Gc+|
+00000010  bd 00 3a ad 82 e3 a7 b3  b0 84 4a 26 f4 30 78 20  |..:.......J&.0x |
+00000020  80 f2 2b 15 98 61 1c cb  8b 17 67 8a 11 96 aa 93  |..+..a....g.....|
+00000030  68 f7 fb                                          |h..|
+>>> Flow 5 (client to server)
+00000000  17 03 03 00 1e 00 00 00  00 00 00 00 01 a6 8d 7b  |...............{|
+00000010  99 5e a2 e1 95 bb 5f e4  01 f4 0e 20 52 b4 64 4e  |.^...._.... R.dN|
+00000020  86 b1 3f 15 03 03 00 1a  00 00 00 00 00 00 00 02  |..?.............|
+00000030  61 98 eb d0 7c ac bd 00  ac 7a e1 32 20 3e 81 b6  |a...|....z.2 >..|
+00000040  9d d5                                             |..|
diff --git a/third_party/gofrontend/libgo/go/crypto/tls/testdata/Client-TLSv12-ClientCert-RSA-ECDSA b/third_party/gofrontend/libgo/go/crypto/tls/testdata/Client-TLSv12-ClientCert-RSA-ECDSA
index 0037af6..23bf29d 100644
--- a/third_party/gofrontend/libgo/go/crypto/tls/testdata/Client-TLSv12-ClientCert-RSA-ECDSA
+++ b/third_party/gofrontend/libgo/go/crypto/tls/testdata/Client-TLSv12-ClientCert-RSA-ECDSA
@@ -1,18 +1,19 @@
 >>> Flow 1 (client to server)
-00000000  16 03 01 00 75 01 00 00  71 03 03 00 00 00 00 00  |....u...q.......|
+00000000  16 03 01 00 81 01 00 00  7d 03 03 00 00 00 00 00  |........}.......|
 00000010  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
-00000020  00 00 00 00 00 00 00 00  00 00 00 00 00 1a c0 2f  |.............../|
-00000030  c0 2b c0 11 c0 07 c0 13  c0 09 c0 14 c0 0a 00 05  |.+..............|
-00000040  00 2f 00 35 c0 12 00 0a  01 00 00 2e 00 05 00 05  |./.5............|
-00000050  01 00 00 00 00 00 0a 00  08 00 06 00 17 00 18 00  |................|
-00000060  19 00 0b 00 02 01 00 00  0d 00 0a 00 08 04 01 04  |................|
-00000070  03 02 01 02 03 ff 01 00  01 00                    |..........|
+00000020  00 00 00 00 00 00 00 00  00 00 00 00 00 1e c0 2f  |.............../|
+00000030  c0 2b c0 30 c0 2c c0 11  c0 07 c0 13 c0 09 c0 14  |.+.0.,..........|
+00000040  c0 0a 00 05 00 2f 00 35  c0 12 00 0a 01 00 00 36  |...../.5.......6|
+00000050  00 05 00 05 01 00 00 00  00 00 0a 00 08 00 06 00  |................|
+00000060  17 00 18 00 19 00 0b 00  02 01 00 00 0d 00 0e 00  |................|
+00000070  0c 04 01 04 03 05 01 05  03 02 01 02 03 ff 01 00  |................|
+00000080  01 00 00 12 00 00                                 |......|
 >>> Flow 2 (server to client)
-00000000  16 03 03 00 59 02 00 00  55 03 03 53 04 f1 02 fd  |....Y...U..S....|
-00000010  41 bd ef ee f3 da fc 1a  31 8c 77 f2 e9 66 54 a0  |A.......1.w..fT.|
-00000020  f4 15 b1 1c 84 0d 6d 74  87 ac 7d 20 78 17 8b 08  |......mt..} x...|
-00000030  10 20 c9 44 e4 8a 43 af  4a c7 b8 3d 99 f2 f7 af  |. .D..C.J..=....|
-00000040  bb a3 21 2f 40 cc ed b6  da a8 a1 d5 c0 09 00 00  |..!/@...........|
+00000000  16 03 03 00 59 02 00 00  55 03 03 b3 7f 4e e7 11  |....Y...U....N..|
+00000010  6d bc 56 ec 9c a8 61 08  d6 5a 2a 42 7b f1 94 0a  |m.V...a..Z*B{...|
+00000020  29 35 8b 7e 23 a0 6c 59  23 cf 39 20 84 09 b6 5b  |)5.~#.lY#.9 ...[|
+00000030  2f 46 80 3b 26 92 fd 81  e9 24 8c e2 b8 64 a2 03  |/F.;&....$...d..|
+00000040  3a 68 c3 7b 44 f8 28 41  e2 d3 6c 7c c0 09 00 00  |:h.{D.(A..l|....|
 00000050  0d ff 01 00 01 00 00 0b  00 04 03 00 01 02 16 03  |................|
 00000060  03 02 0e 0b 00 02 0a 00  02 07 00 02 04 30 82 02  |.............0..|
 00000070  00 30 82 01 62 02 09 00  b8 bf 2d 47 a0 d2 eb f4  |.0..b.....-G....|
@@ -47,24 +48,23 @@
 00000240  13 83 0d 94 06 bb d4 37  7a f6 ec 7a c9 86 2e dd  |.......7z..z....|
 00000250  d7 11 69 7f 85 7c 56 de  fb 31 78 2b e4 c7 78 0d  |..i..|V..1x+..x.|
 00000260  ae cb be 9e 4e 36 24 31  7b 6a 0f 39 95 12 07 8f  |....N6$1{j.9....|
-00000270  2a 16 03 03 00 d8 0c 00  00 d4 03 00 17 41 04 a9  |*............A..|
-00000280  19 8b d9 9b 5c 7c 6a 7d  85 d2 70 4e 89 7e 0b 5b  |....\|j}..pN.~.[|
-00000290  dd 5e a1 63 8d 15 bc 0b  0c 47 3d 4d e8 a7 56 88  |.^.c.....G=M..V.|
-000002a0  2e f6 7f e2 4d fc ed cc  03 ed a1 2d ac ae 81 a5  |....M......-....|
-000002b0  e2 6d 7f 9f a3 93 e9 10  c1 0e 48 1b f3 f4 38 04  |.m........H...8.|
-000002c0  03 00 8b 30 81 88 02 42  00 87 fe 7e 63 82 14 57  |...0...B...~c..W|
-000002d0  dc 7d e2 0f cc 97 2d ba  3c a7 56 4a 17 a8 09 6a  |.}....-.<.VJ...j|
-000002e0  28 2e f2 66 1a 3f 2d 48  2b 6f 79 a1 60 cd 5e 10  |(..f.?-H+oy.`.^.|
-000002f0  0b 0a 28 f2 5f e4 3f 4f  f9 c9 91 34 d9 dc bc fc  |..(._.?O...4....|
-00000300  98 ea 77 0b 99 f8 a2 11  c4 bd 02 42 01 a0 b0 dc  |..w........B....|
-00000310  db 5b c2 09 99 bd ee a0  b9 aa 31 b9 10 84 22 be  |.[........1...".|
-00000320  5a 63 12 5a 43 00 8e c1  33 cc 91 bb c2 70 7a 63  |Zc.ZC...3....pzc|
-00000330  19 82 c0 74 48 a1 c7 3d  1f f1 6f 4a 6f 6a 8c 3f  |...tH..=..oJoj.?|
-00000340  28 31 a8 0c 65 19 26 62  4b 7a 7c 4b ea 1a 16 03  |(1..e.&bKz|K....|
-00000350  03 00 30 0d 00 00 28 03  01 02 40 00 20 06 01 06  |..0...(...@. ...|
-00000360  02 06 03 05 01 05 02 05  03 04 01 04 02 04 03 03  |................|
-00000370  01 03 02 03 03 02 01 02  02 02 03 01 01 00 00 0e  |................|
-00000380  00 00 00                                          |...|
+00000270  2a 16 03 03 00 d7 0c 00  00 d3 03 00 17 41 04 0f  |*............A..|
+00000280  4d b0 41 d4 dc 6b 8a 85  52 eb eb 18 4a 8f a7 e6  |M.A..k..R...J...|
+00000290  24 52 e5 86 be 57 d7 0a  e7 23 84 a8 a9 6c 96 08  |$R...W...#...l..|
+000002a0  4b f7 47 32 79 d9 df 81  f6 05 40 63 3b 14 67 3b  |K.G2y.....@c;.g;|
+000002b0  ea 01 a0 0d 43 1a 36 29  b3 51 7a e4 af 1b 67 04  |....C.6).Qz...g.|
+000002c0  03 00 8a 30 81 87 02 42  01 8e 57 8a b8 b7 5b 2f  |...0...B..W...[/|
+000002d0  9c 31 74 d8 7d 68 d7 6e  83 73 5f fb d0 cd de 66  |.1t.}h.n.s_....f|
+000002e0  60 fa 0a 0a 15 0b 30 3b  08 b6 f1 3e 4f 20 13 62  |`.....0;...>O .b|
+000002f0  b5 ff 86 81 dc 42 a1 4c  af c8 ff b3 24 81 d8 e1  |.....B.L....$...|
+00000300  d1 09 0c 32 11 92 5e dd  3f 87 02 41 76 a7 29 48  |...2..^.?..Av.)H|
+00000310  52 68 1c 72 4d d5 39 bf  fa 61 ec b2 27 ce 10 4e  |Rh.rM.9..a..'..N|
+00000320  86 12 3d 1e 04 9c 11 b7  b4 0c cf 98 9d 01 c3 93  |..=.............|
+00000330  cf 83 9e 92 9a ca fd 8f  b1 9f 1b 20 c4 fb a4 46  |........... ...F|
+00000340  60 fc fd d5 33 b0 8f b5  b5 c8 a4 70 c5 16 03 03  |`...3......p....|
+00000350  00 2e 0d 00 00 26 03 01  02 40 00 1e 06 01 06 02  |.....&...@......|
+00000360  06 03 05 01 05 02 05 03  04 01 04 02 04 03 03 01  |................|
+00000370  03 02 03 03 02 01 02 02  02 03 00 00 0e 00 00 00  |................|
 >>> Flow 3 (client to server)
 00000000  16 03 03 01 fb 0b 00 01  f7 00 01 f4 00 01 f1 30  |...............0|
 00000010  82 01 ed 30 82 01 58 a0  03 02 01 02 02 01 00 30  |...0..X........0|
@@ -103,31 +103,31 @@
 00000220  a7 24 20 3e b2 56 1c ce  97 28 5e f8 2b 2d 4f 9e  |.$ >.V...(^.+-O.|
 00000230  f1 07 9f 6c 4b 5b 83 56  e2 32 42 e9 58 b6 d7 49  |...lK[.V.2B.X..I|
 00000240  a6 b5 68 1a 41 03 56 6b  dc 5a 89 16 03 03 00 88  |..h.A.Vk.Z......|
-00000250  0f 00 00 84 04 01 00 80  38 f2 16 e5 b5 86 16 62  |........8......b|
-00000260  86 e1 7d 01 f1 a8 e1 f7  e7 85 b1 a0 17 ee 84 25  |..}............%|
-00000270  cb 3c 46 61 1a 78 7b 1e  ee 32 bc d9 6c fa 6b 76  |.<Fa.x{..2..l.kv|
-00000280  67 a7 9e c8 7a 4c e8 79  0d 22 27 ad e7 98 6a 98  |g...zL.y."'...j.|
-00000290  89 88 8b a9 69 5b 6f c6  00 48 9a 21 77 a9 7c 15  |....i[o..H.!w.|.|
-000002a0  ba 47 16 74 8d 6c 67 dc  6d f1 98 b6 61 e8 bc 08  |.G.t.lg.m...a...|
-000002b0  18 53 a6 93 bf fc 27 5e  b7 4d d2 eb 68 e9 23 ee  |.S....'^.M..h.#.|
-000002c0  d2 70 d2 55 2c c7 99 7d  c0 66 b5 1c ea 38 71 5c  |.p.U,..}.f...8q\|
-000002d0  a6 57 1f 52 e4 8e e8 51  14 03 03 00 01 01 16 03  |.W.R...Q........|
+00000250  0f 00 00 84 05 01 00 80  02 19 16 cc 97 ad 70 20  |..............p |
+00000260  bd 64 63 dd b6 81 a0 16  b3 46 4b 42 ff 21 58 2c  |.dc......FKB.!X,|
+00000270  bb 2b 4c e1 4e d7 49 4d  5c 7c 63 32 3e ef e6 ad  |.+L.N.IM\|c2>...|
+00000280  85 3f ab b4 5c 2a 37 76  8b 28 56 08 4f 08 b9 51  |.?..\*7v.(V.O..Q|
+00000290  71 14 07 27 47 45 11 a0  03 cf 72 7d 67 ef 31 8d  |q..'GE....r}g.1.|
+000002a0  e7 db 36 76 b1 b3 f4 bf  aa 6c c4 56 94 35 71 e1  |..6v.....l.V.5q.|
+000002b0  dd 88 6d 15 90 c8 70 ad  d8 95 55 42 9b c1 45 19  |..m...p...UB..E.|
+000002c0  36 ce 87 c6 fd 94 8a d4  98 6e ec 18 d5 da 59 54  |6........n....YT|
+000002d0  80 a7 8c 90 ae 55 20 1c  14 03 03 00 01 01 16 03  |.....U .........|
 000002e0  03 00 40 00 00 00 00 00  00 00 00 00 00 00 00 00  |..@.............|
-000002f0  00 00 00 5e e7 6e 1c a2  02 24 34 f0 a6 b6 27 ea  |...^.n...$4...'.|
-00000300  69 d5 0e 2e a8 ad 5c ad  6c 06 78 68 39 92 27 f1  |i.....\.l.xh9.'.|
-00000310  e8 35 49 67 4d fb 5d 8a  31 2e 4e 3f 19 ed ea 30  |.5IgM.].1.N?...0|
-00000320  20 60 e1                                          | `.|
+000002f0  00 00 00 58 fe bc 5c ba  b2 a9 96 77 2f 95 c9 10  |...X..\....w/...|
+00000300  fd 6d fc 6a 88 8c df 82  c3 a4 3d cc 28 f4 bf 7d  |.m.j......=.(..}|
+00000310  4a f8 3d 97 36 e5 a0 76  92 94 da dd cc f5 e4 0e  |J.=.6..v........|
+00000320  7a c4 2c                                          |z.,|
 >>> Flow 4 (server to client)
-00000000  14 03 03 00 01 01 16 03  03 00 40 ee a8 82 bc 3f  |..........@....?|
-00000010  bf ab a6 e4 30 e0 3d f1  2f 19 a2 ac 7a 81 57 f1  |....0.=./...z.W.|
-00000020  ee 67 3f 55 2b 30 fa 72  b5 10 03 ec 8d 0a 8f bb  |.g?U+0.r........|
-00000030  24 f5 45 f5 4e 53 4b 93  a5 0d 42 6c 46 69 98 fb  |$.E.NSK...BlFi..|
-00000040  63 c5 9f 95 65 d1 b6 f0  a4 15 bd                 |c...e......|
+00000000  14 03 03 00 01 01 16 03  03 00 40 81 ab 5a 66 a8  |..........@..Zf.|
+00000010  0f a5 d3 07 00 66 45 1f  31 a9 ef f7 a0 d9 23 46  |.....fE.1.....#F|
+00000020  f0 3e 50 18 99 e3 5a bd  eb b7 1d 81 d5 95 d5 ee  |.>P...Z.........|
+00000030  21 31 41 4b 19 92 b5 95  36 da 21 c0 4a 2a a0 1c  |!1AK....6.!.J*..|
+00000040  a3 9f 8e a0 6f 9d 37 5e  12 11 03                 |....o.7^...|
 >>> Flow 5 (client to server)
 00000000  17 03 03 00 30 00 00 00  00 00 00 00 00 00 00 00  |....0...........|
-00000010  00 00 00 00 00 cb 4e bc  d1 a9 58 ef c8 39 a9 36  |......N...X..9.6|
-00000020  f4 35 05 96 8e a4 50 bc  f4 15 06 f9 fd 41 6d 1e  |.5....P......Am.|
-00000030  5e 7c 82 63 94 15 03 03  00 30 00 00 00 00 00 00  |^|.c.....0......|
-00000040  00 00 00 00 00 00 00 00  00 00 bd 77 87 a5 5a d4  |...........w..Z.|
-00000050  b8 59 e6 6b 0f dd ea f9  ed 18 b2 9f a9 61 b4 3a  |.Y.k.........a.:|
-00000060  47 15 15 3b 83 ef e1 6d  db a8                    |G..;...m..|
+00000010  00 00 00 00 00 a9 51 94  19 72 ab 9f 3e 97 5e 99  |......Q..r..>.^.|
+00000020  2c ec 13 48 3e 10 54 5f  8a 85 88 4d 1a a8 f5 ed  |,..H>.T_...M....|
+00000030  c3 4f a9 59 a3 15 03 03  00 30 00 00 00 00 00 00  |.O.Y.....0......|
+00000040  00 00 00 00 00 00 00 00  00 00 25 00 6d 2f a0 f6  |..........%.m/..|
+00000050  ce 8a 30 ba 53 da 97 c6  11 f3 d2 f3 9e 66 d6 dd  |..0.S........f..|
+00000060  19 f3 ee 07 03 d3 e6 f1  30 32                    |........02|
diff --git a/third_party/gofrontend/libgo/go/crypto/tls/testdata/Client-TLSv12-ClientCert-RSA-RSA b/third_party/gofrontend/libgo/go/crypto/tls/testdata/Client-TLSv12-ClientCert-RSA-RSA
index df3eaa4..ff79aa2 100644
--- a/third_party/gofrontend/libgo/go/crypto/tls/testdata/Client-TLSv12-ClientCert-RSA-RSA
+++ b/third_party/gofrontend/libgo/go/crypto/tls/testdata/Client-TLSv12-ClientCert-RSA-RSA
@@ -1,18 +1,19 @@
 >>> Flow 1 (client to server)
-00000000  16 03 01 00 75 01 00 00  71 03 03 00 00 00 00 00  |....u...q.......|
+00000000  16 03 01 00 81 01 00 00  7d 03 03 00 00 00 00 00  |........}.......|
 00000010  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
-00000020  00 00 00 00 00 00 00 00  00 00 00 00 00 1a c0 2f  |.............../|
-00000030  c0 2b c0 11 c0 07 c0 13  c0 09 c0 14 c0 0a 00 05  |.+..............|
-00000040  00 2f 00 35 c0 12 00 0a  01 00 00 2e 00 05 00 05  |./.5............|
-00000050  01 00 00 00 00 00 0a 00  08 00 06 00 17 00 18 00  |................|
-00000060  19 00 0b 00 02 01 00 00  0d 00 0a 00 08 04 01 04  |................|
-00000070  03 02 01 02 03 ff 01 00  01 00                    |..........|
+00000020  00 00 00 00 00 00 00 00  00 00 00 00 00 1e c0 2f  |.............../|
+00000030  c0 2b c0 30 c0 2c c0 11  c0 07 c0 13 c0 09 c0 14  |.+.0.,..........|
+00000040  c0 0a 00 05 00 2f 00 35  c0 12 00 0a 01 00 00 36  |...../.5.......6|
+00000050  00 05 00 05 01 00 00 00  00 00 0a 00 08 00 06 00  |................|
+00000060  17 00 18 00 19 00 0b 00  02 01 00 00 0d 00 0e 00  |................|
+00000070  0c 04 01 04 03 05 01 05  03 02 01 02 03 ff 01 00  |................|
+00000080  01 00 00 12 00 00                                 |......|
 >>> Flow 2 (server to client)
-00000000  16 03 03 00 51 02 00 00  4d 03 03 53 04 f1 02 1d  |....Q...M..S....|
-00000010  0e dc 86 e5 a9 07 71 46  15 34 af 47 15 3f 03 9c  |......qF.4.G.?..|
-00000020  fc d6 fd 44 7c f4 f1 c7  8d 6f f8 20 28 ea 3c dc  |...D|....o. (.<.|
-00000030  b2 4c b7 ba 20 88 c4 db  a5 73 ea 93 ab 3a 85 a6  |.L.. ....s...:..|
-00000040  8f 59 49 d9 a9 31 14 d5  a6 2b 4f d1 00 05 00 00  |.YI..1...+O.....|
+00000000  16 03 03 00 51 02 00 00  4d 03 03 b3 b2 22 69 e4  |....Q...M...."i.|
+00000010  1a a1 56 94 26 0c 43 b7  89 0c 34 ce dc 5a c8 ca  |..V.&.C...4..Z..|
+00000020  e2 42 92 5c 75 9a b3 22  22 64 38 20 6d 2c 26 0b  |.B.\u..""d8 m,&.|
+00000030  34 b6 b8 20 36 e2 58 e5  ee 1f e2 9f a0 75 f6 d9  |4.. 6.X......u..|
+00000040  0c e4 39 ce 3c 8e 2e f8  e8 d1 a2 16 00 05 00 00  |..9.<...........|
 00000050  05 ff 01 00 01 00 16 03  03 02 be 0b 00 02 ba 00  |................|
 00000060  02 b7 00 02 b4 30 82 02  b0 30 82 02 19 a0 03 02  |.....0...0......|
 00000070  01 02 02 09 00 85 b0 bb  a4 8a 7f b8 ca 30 0d 06  |.............0..|
@@ -57,10 +58,10 @@
 000002e0  50 56 5c d5 82 5a 2d 5a  5f 33 c4 b6 d8 c9 75 90  |PV\..Z-Z_3....u.|
 000002f0  96 8c 0f 52 98 b5 cd 98  1f 89 20 5f f2 a0 1c a3  |...R...... _....|
 00000300  1b 96 94 dd a9 fd 57 e9  70 e8 26 6d 71 99 9b 26  |......W.p.&mq..&|
-00000310  6e 38 50 29 6c 90 a7 bd  d9 16 03 03 00 30 0d 00  |n8P)l........0..|
-00000320  00 28 03 01 02 40 00 20  06 01 06 02 06 03 05 01  |.(...@. ........|
+00000310  6e 38 50 29 6c 90 a7 bd  d9 16 03 03 00 2e 0d 00  |n8P)l...........|
+00000320  00 26 03 01 02 40 00 1e  06 01 06 02 06 03 05 01  |.&...@..........|
 00000330  05 02 05 03 04 01 04 02  04 03 03 01 03 02 03 03  |................|
-00000340  02 01 02 02 02 03 01 01  00 00 0e 00 00 00        |..............|
+00000340  02 01 02 02 02 03 00 00  0e 00 00 00              |............|
 >>> Flow 3 (client to server)
 00000000  16 03 03 01 fb 0b 00 01  f7 00 01 f4 00 01 f1 30  |...............0|
 00000010  82 01 ed 30 82 01 58 a0  03 02 01 02 02 01 00 30  |...0..X........0|
@@ -103,24 +104,24 @@
 00000260  e6 bd 77 82 6f 23 b6 e0  bd a2 92 b7 3a ac e8 56  |..w.o#......:..V|
 00000270  f1 af 54 5e 46 87 e9 3b  33 e7 b8 28 b7 d6 c8 90  |..T^F..;3..(....|
 00000280  35 d4 1c 43 d1 30 6f 55  4e 0a 70 16 03 03 00 88  |5..C.0oUN.p.....|
-00000290  0f 00 00 84 04 01 00 80  2a 1f ae 48 9f 86 16 dc  |........*..H....|
-000002a0  c2 55 1f 5f 95 81 ed 56  00 5d 35 46 e5 b6 57 d5  |.U._...V.]5F..W.|
-000002b0  a6 3e 32 38 8b e2 c6 1c  b9 b1 38 b2 da 66 45 ed  |.>28......8..fE.|
-000002c0  58 6a 7f 43 41 93 a5 09  da b9 04 ce 3f 13 8a 19  |Xj.CA.......?...|
-000002d0  13 e9 2c 1f c5 e7 35 b4  2d ea 7c 81 90 33 c0 66  |..,...5.-.|..3.f|
-000002e0  dc 41 8b 23 08 8f 69 d4  d6 a2 5f c1 bd 26 e6 2e  |.A.#..i..._..&..|
-000002f0  7f c8 7c a8 2d d4 08 95  ce 6e 58 54 04 a2 a6 63  |..|.-....nXT...c|
-00000300  54 72 67 f2 7f 61 0a 6b  58 46 d4 88 95 38 37 f2  |Trg..a.kXF...87.|
-00000310  93 95 48 56 14 a7 b9 7c  14 03 03 00 01 01 16 03  |..HV...|........|
-00000320  03 00 24 64 bb 41 3a cb  a2 2f 95 53 5c 2f f7 83  |..$d.A:../.S\/..|
-00000330  a2 35 18 f6 d0 8d 6f e2  54 ed 2f 07 10 f4 36 e2  |.5....o.T./...6.|
-00000340  3d e5 30 1d e3 63 01                              |=.0..c.|
+00000290  0f 00 00 84 05 01 00 80  01 24 8d bb 05 61 2d 29  |.........$...a-)|
+000002a0  12 11 90 f5 57 21 be b7  29 76 55 63 94 8e 7b 4d  |....W!..)vUc..{M|
+000002b0  3b 3d 89 5b 1f b9 e1 8c  36 68 6f 31 21 50 af e4  |;=.[....6ho1!P..|
+000002c0  9f ca a5 68 55 b9 eb 36  75 3a 0c be 11 30 28 c8  |...hU..6u:...0(.|
+000002d0  8b 82 93 9a 71 37 4d 4e  4f d2 0c 2f 13 36 ad c3  |....q7MNO../.6..|
+000002e0  df 8a 1b 59 b2 f9 8b a7  74 63 75 4a f4 9d e0 6b  |...Y....tcuJ...k|
+000002f0  42 02 5a a9 6e a4 a8 24  d3 23 f7 09 ee b0 dc c4  |B.Z.n..$.#......|
+00000300  6f 87 58 72 e7 e3 87 b3  6b 15 ba 7f dd 9b 93 91  |o.Xr....k.......|
+00000310  5b 21 a0 31 31 bd 15 b5  14 03 03 00 01 01 16 03  |[!.11...........|
+00000320  03 00 24 fc 0e 7c e8 3e  8b b5 dc c9 3d 38 61 a1  |..$..|.>....=8a.|
+00000330  24 d6 77 1f 06 1f 30 32  ba dd 05 68 45 f1 4f 0d  |$.w...02...hE.O.|
+00000340  2e 24 09 ad c1 e5 b7                              |.$.....|
 >>> Flow 4 (server to client)
-00000000  14 03 03 00 01 01 16 03  03 00 24 0a 22 b6 bc da  |..........$."...|
-00000010  34 38 53 8e 80 e2 25 7b  31 2f 70 8e 3a db e8 a3  |48S...%{1/p.:...|
-00000020  70 0e 88 22 b4 a8 be d4  a3 e3 cc 13 94 ef 47     |p.."..........G|
+00000000  14 03 03 00 01 01 16 03  03 00 24 d7 b6 b3 0a e6  |..........$.....|
+00000010  86 9a 25 e4 38 de d0 57  ff 93 0b f4 de 76 3d 00  |..%.8..W.....v=.|
+00000020  64 35 cf 70 f6 ea 74 2d  b0 71 2d 92 e2 df eb     |d5.p..t-.q-....|
 >>> Flow 5 (client to server)
-00000000  17 03 03 00 1a b4 9c b1  57 ea 01 03 fe 01 e7 1e  |........W.......|
-00000010  c4 a7 0f 25 14 99 00 4f  88 51 c1 98 6e 99 01 15  |...%...O.Q..n...|
-00000020  03 03 00 16 2e c4 11 8b  1a fc 37 81 18 33 e4 9f  |..........7..3..|
-00000030  48 a3 29 e3 ad 9b 9b ec  9f 99                    |H.).......|
+00000000  17 03 03 00 1a db bd 43  12 7c b5 83 b5 18 9d 6a  |.......C.|.....j|
+00000010  70 3f 5a eb cb d0 ba d4  03 3e a0 7b 25 f0 41 15  |p?Z......>.{%.A.|
+00000020  03 03 00 16 f8 f2 a3 27  a5 c7 25 d9 6c 08 b1 96  |.......'..%.l...|
+00000030  38 22 38 df 16 fb e2 9f  61 a3                    |8"8.....a.|
diff --git a/third_party/gofrontend/libgo/go/crypto/tls/testdata/Client-TLSv12-ECDHE-ECDSA-AES b/third_party/gofrontend/libgo/go/crypto/tls/testdata/Client-TLSv12-ECDHE-ECDSA-AES
index 7644590..e700e16 100644
--- a/third_party/gofrontend/libgo/go/crypto/tls/testdata/Client-TLSv12-ECDHE-ECDSA-AES
+++ b/third_party/gofrontend/libgo/go/crypto/tls/testdata/Client-TLSv12-ECDHE-ECDSA-AES
@@ -1,18 +1,19 @@
 >>> Flow 1 (client to server)
-00000000  16 03 01 00 75 01 00 00  71 03 03 00 00 00 00 00  |....u...q.......|
+00000000  16 03 01 00 81 01 00 00  7d 03 03 00 00 00 00 00  |........}.......|
 00000010  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
-00000020  00 00 00 00 00 00 00 00  00 00 00 00 00 1a c0 2f  |.............../|
-00000030  c0 2b c0 11 c0 07 c0 13  c0 09 c0 14 c0 0a 00 05  |.+..............|
-00000040  00 2f 00 35 c0 12 00 0a  01 00 00 2e 00 05 00 05  |./.5............|
-00000050  01 00 00 00 00 00 0a 00  08 00 06 00 17 00 18 00  |................|
-00000060  19 00 0b 00 02 01 00 00  0d 00 0a 00 08 04 01 04  |................|
-00000070  03 02 01 02 03 ff 01 00  01 00                    |..........|
+00000020  00 00 00 00 00 00 00 00  00 00 00 00 00 1e c0 2f  |.............../|
+00000030  c0 2b c0 30 c0 2c c0 11  c0 07 c0 13 c0 09 c0 14  |.+.0.,..........|
+00000040  c0 0a 00 05 00 2f 00 35  c0 12 00 0a 01 00 00 36  |...../.5.......6|
+00000050  00 05 00 05 01 00 00 00  00 00 0a 00 08 00 06 00  |................|
+00000060  17 00 18 00 19 00 0b 00  02 01 00 00 0d 00 0e 00  |................|
+00000070  0c 04 01 04 03 05 01 05  03 02 01 02 03 ff 01 00  |................|
+00000080  01 00 00 12 00 00                                 |......|
 >>> Flow 2 (server to client)
-00000000  16 03 03 00 59 02 00 00  55 03 03 53 04 f1 02 a0  |....Y...U..S....|
-00000010  5f bd a4 8d 98 93 b8 da  08 86 9f b2 be 9a a4 91  |_...............|
-00000020  2b 3c 1f 18 f0 75 7c a9  a8 a0 f7 20 4a 89 9a d2  |+<...u|.... J...|
-00000030  34 3b d9 b1 c2 fd 61 bd  97 19 22 ce b9 d1 5b a7  |4;....a..."...[.|
-00000040  83 80 9c 19 d0 f5 a0 aa  4c ac 06 20 c0 09 00 00  |........L.. ....|
+00000000  16 03 03 00 59 02 00 00  55 03 03 21 9b eb 15 24  |....Y...U..!...$|
+00000010  46 b6 c1 85 f5 be c5 0d  e2 6b 60 bc ee 73 b1 fb  |F........k`..s..|
+00000020  34 6f f0 b8 f0 9e 1c 26  a4 4b 0f 20 cb 2b 84 a2  |4o.....&.K. .+..|
+00000030  cb a5 48 70 fe 84 25 b0  16 20 14 a1 83 21 fc f9  |..Hp..%.. ...!..|
+00000040  82 fc 9e 1a d1 3b 56 69  ab c5 0e 2c c0 09 00 00  |.....;Vi...,....|
 00000050  0d ff 01 00 01 00 00 0b  00 04 03 00 01 02 16 03  |................|
 00000060  03 02 0e 0b 00 02 0a 00  02 07 00 02 04 30 82 02  |.............0..|
 00000070  00 30 82 01 62 02 09 00  b8 bf 2d 47 a0 d2 eb f4  |.0..b.....-G....|
@@ -47,21 +48,21 @@
 00000240  13 83 0d 94 06 bb d4 37  7a f6 ec 7a c9 86 2e dd  |.......7z..z....|
 00000250  d7 11 69 7f 85 7c 56 de  fb 31 78 2b e4 c7 78 0d  |..i..|V..1x+..x.|
 00000260  ae cb be 9e 4e 36 24 31  7b 6a 0f 39 95 12 07 8f  |....N6$1{j.9....|
-00000270  2a 16 03 03 00 d7 0c 00  00 d3 03 00 17 41 04 3c  |*............A.<|
-00000280  8f 35 1e 47 5d 7b ad 13  0c e9 5c c0 97 c7 83 06  |.5.G]{....\.....|
-00000290  49 0f 6c cf e5 4d 3b ed  f7 1b c6 96 8d ba 54 35  |I.l..M;.......T5|
-000002a0  7f df 35 e3 6e 28 e9 71  f2 24 b5 ab 17 2b 4b 2b  |..5.n(.q.$...+K+|
-000002b0  0c 8f 9f 48 89 73 8f 09  69 84 af 7f ec 43 7a 04  |...H.s..i....Cz.|
-000002c0  03 00 8a 30 81 87 02 41  79 84 43 0c 78 fa 7e e2  |...0...Ay.C.x.~.|
-000002d0  c5 51 c1 60 88 c4 4a 59  7d 02 fa dc 19 68 33 ed  |.Q.`..JY}....h3.|
-000002e0  19 ef a1 df ef 6b 21 a6  98 aa ba a9 13 70 91 0f  |.....k!......p..|
-000002f0  cc 6c 5c 1e 99 53 1b 42  51 6c 06 a7 3c c4 04 22  |.l\..S.BQl..<.."|
-00000300  5d 0d c1 30 ab e3 ec b4  54 02 42 01 15 15 1a 6e  |]..0....T.B....n|
-00000310  6f f1 c6 b1 10 84 2c c8  04 de 2b 52 d5 b4 f7 c9  |o.....,...+R....|
-00000320  4f 6d 0e 0e 26 45 1d 7a  28 59 2b 8b f6 92 3a 23  |Om..&E.z(Y+...:#|
-00000330  7a 39 9c d5 4e cc 5d c5  45 92 9c d0 5f 33 12 e3  |z9..N.].E..._3..|
-00000340  2b 29 39 52 bb 16 aa e1  72 9e b5 fe 99 16 03 03  |+)9R....r.......|
-00000350  00 04 0e 00 00 00                                 |......|
+00000270  2a 16 03 03 00 d8 0c 00  00 d4 03 00 17 41 04 b6  |*............A..|
+00000280  3f 37 33 68 cb 79 c0 86  f4 9d 12 ac c4 9d 8c 9b  |?73h.y..........|
+00000290  59 1c d4 a9 01 9f 2d cb  80 24 02 ec e0 ff d1 8c  |Y.....-..$......|
+000002a0  bd 82 67 3f 47 58 1a 2e  6b 61 f6 8e 4e 27 7f 49  |..g?GX..ka..N'.I|
+000002b0  b5 45 f1 0b 9a 33 ff 53  ac 65 e2 82 7a 18 5c 04  |.E...3.S.e..z.\.|
+000002c0  03 00 8b 30 81 88 02 42  00 e1 2d ff 5d e7 77 f1  |...0...B..-.].w.|
+000002d0  12 d9 e4 c2 4d cd 9c b5  ee e4 fd 21 b2 d8 53 a9  |....M......!..S.|
+000002e0  42 e7 c5 9b 51 c3 59 37  a5 08 d4 e6 29 12 c5 56  |B...Q.Y7....)..V|
+000002f0  b8 fe f0 bb 77 87 a3 ee  09 b0 8c cd 1c 39 9e b5  |....w........9..|
+00000300  d9 15 63 53 cb d7 f1 55  5b 48 02 42 01 19 10 8a  |..cS...U[H.B....|
+00000310  7a ee 95 b1 77 44 d4 a3  bf d1 f3 f1 b0 d8 c7 7e  |z...wD.........~|
+00000320  42 c0 83 04 f5 f7 9c c0  ce 6a 98 47 9d 21 29 84  |B........j.G.!).|
+00000330  c8 be 6b 67 4e fc c6 26  ec 63 df 00 33 e6 d2 f7  |..kgN..&.c..3...|
+00000340  34 93 85 9b 1b 0f e0 89  42 b6 0b 94 1b 80 16 03  |4.......B.......|
+00000350  03 00 04 0e 00 00 00                              |.......|
 >>> Flow 3 (client to server)
 00000000  16 03 03 00 46 10 00 00  42 41 04 1e 18 37 ef 0d  |....F...BA...7..|
 00000010  19 51 88 35 75 71 b5 e5  54 5b 12 2e 8f 09 67 fd  |.Q.5uq..T[....g.|
@@ -69,21 +70,21 @@
 00000030  f1 07 9f 6c 4b 5b 83 56  e2 32 42 e9 58 b6 d7 49  |...lK[.V.2B.X..I|
 00000040  a6 b5 68 1a 41 03 56 6b  dc 5a 89 14 03 03 00 01  |..h.A.Vk.Z......|
 00000050  01 16 03 03 00 40 00 00  00 00 00 00 00 00 00 00  |.....@..........|
-00000060  00 00 00 00 00 00 20 a3  f8 5a e2 ea f3 09 19 3e  |...... ..Z.....>|
-00000070  4a 54 69 70 06 5b 17 35  0f ed e7 30 3b 6f eb a1  |JTip.[.5...0;o..|
-00000080  cb 9c 35 81 10 2e 34 f7  12 a5 e4 63 20 b2 65 31  |..5...4....c .e1|
-00000090  19 da 30 43 39 59                                 |..0C9Y|
+00000060  00 00 00 00 00 00 50 73  9c 9f a8 d7 78 ac 06 14  |......Ps....x...|
+00000070  8f ae fc fb ef 7d 99 db  b7 c9 91 dd f2 fe da 1b  |.....}..........|
+00000080  aa 9e 7d e4 5c 2f 5f dd  74 aa fe 03 51 e7 cd 98  |..}.\/_.t...Q...|
+00000090  e9 21 19 c9 6f 59                                 |.!..oY|
 >>> Flow 4 (server to client)
-00000000  14 03 03 00 01 01 16 03  03 00 40 8d 4d 31 07 df  |..........@.M1..|
-00000010  ab 41 f5 19 9c 1a 57 fc  33 ab 5f e6 bd 45 b9 fa  |.A....W.3._..E..|
-00000020  7f db c0 df 72 f2 3b ef  aa d4 5e 34 e6 3d 44 7c  |....r.;...^4.=D||
-00000030  12 05 c7 57 da 54 b1 e3  66 f0 0a ab cd 15 a5 bf  |...W.T..f.......|
-00000040  c5 c2 07 a9 d9 a7 2e 5e  29 da da                 |.......^)..|
+00000000  14 03 03 00 01 01 16 03  03 00 40 47 18 b5 1b 75  |..........@G...u|
+00000010  b8 a3 63 ab 77 d3 47 cb  14 26 b4 88 fe 15 db 22  |..c.w.G..&....."|
+00000020  76 3b 25 d3 68 8e f2 a7  d5 03 2b 82 7b b1 0f 10  |v;%.h.....+.{...|
+00000030  49 6a 3d 95 d0 4b 55 0e  14 eb bb a7 34 bb 57 b3  |Ij=..KU.....4.W.|
+00000040  5d fb 7e 15 80 5a fa f3  3a df 90                 |].~..Z..:..|
 >>> Flow 5 (client to server)
 00000000  17 03 03 00 30 00 00 00  00 00 00 00 00 00 00 00  |....0...........|
-00000010  00 00 00 00 00 dc 03 7b  29 2c 49 64 58 2d dc f7  |.......{),IdX-..|
-00000020  26 a1 3b ec 2d e8 30 c4  6c a3 ff e2 bc b5 a4 a6  |&.;.-.0.l.......|
-00000030  93 ce 14 bd da 15 03 03  00 30 00 00 00 00 00 00  |.........0......|
-00000040  00 00 00 00 00 00 00 00  00 00 a6 77 10 30 15 eb  |...........w.0..|
-00000050  ed cf 73 5b 74 5d 09 52  4a 5b e2 f0 e4 67 f8 7a  |..s[t].RJ[...g.z|
-00000060  5e 5e fc ba 7f 80 0a d2  f4 fb                    |^^........|
+00000010  00 00 00 00 00 70 74 e2  60 fc 3a 7a b7 5e 16 07  |.....pt.`.:z.^..|
+00000020  22 92 07 fe 92 53 c4 43  1b 8f 94 07 84 48 2b 50  |"....S.C.....H+P|
+00000030  ab 1d 6d 49 ed 15 03 03  00 30 00 00 00 00 00 00  |..mI.....0......|
+00000040  00 00 00 00 00 00 00 00  00 00 ce a8 ba 91 0b e4  |................|
+00000050  8c 38 23 9b 8b 2c 0a 0c  63 79 61 f4 b6 25 f7 41  |.8#..,..cya..%.A|
+00000060  04 9f b0 8f e0 e5 24 44  2f e9                    |......$D/.|
diff --git a/third_party/gofrontend/libgo/go/crypto/tls/testdata/Client-TLSv12-ECDHE-ECDSA-AES-GCM b/third_party/gofrontend/libgo/go/crypto/tls/testdata/Client-TLSv12-ECDHE-ECDSA-AES-GCM
index fb5af17..607ecdc 100644
--- a/third_party/gofrontend/libgo/go/crypto/tls/testdata/Client-TLSv12-ECDHE-ECDSA-AES-GCM
+++ b/third_party/gofrontend/libgo/go/crypto/tls/testdata/Client-TLSv12-ECDHE-ECDSA-AES-GCM
@@ -1,18 +1,19 @@
 >>> Flow 1 (client to server)
-00000000  16 03 01 00 75 01 00 00  71 03 03 00 00 00 00 00  |....u...q.......|
+00000000  16 03 01 00 81 01 00 00  7d 03 03 00 00 00 00 00  |........}.......|
 00000010  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
-00000020  00 00 00 00 00 00 00 00  00 00 00 00 00 1a c0 2f  |.............../|
-00000030  c0 2b c0 11 c0 07 c0 13  c0 09 c0 14 c0 0a 00 05  |.+..............|
-00000040  00 2f 00 35 c0 12 00 0a  01 00 00 2e 00 05 00 05  |./.5............|
-00000050  01 00 00 00 00 00 0a 00  08 00 06 00 17 00 18 00  |................|
-00000060  19 00 0b 00 02 01 00 00  0d 00 0a 00 08 04 01 04  |................|
-00000070  03 02 01 02 03 ff 01 00  01 00                    |..........|
+00000020  00 00 00 00 00 00 00 00  00 00 00 00 00 1e c0 2f  |.............../|
+00000030  c0 2b c0 30 c0 2c c0 11  c0 07 c0 13 c0 09 c0 14  |.+.0.,..........|
+00000040  c0 0a 00 05 00 2f 00 35  c0 12 00 0a 01 00 00 36  |...../.5.......6|
+00000050  00 05 00 05 01 00 00 00  00 00 0a 00 08 00 06 00  |................|
+00000060  17 00 18 00 19 00 0b 00  02 01 00 00 0d 00 0e 00  |................|
+00000070  0c 04 01 04 03 05 01 05  03 02 01 02 03 ff 01 00  |................|
+00000080  01 00 00 12 00 00                                 |......|
 >>> Flow 2 (server to client)
-00000000  16 03 03 00 59 02 00 00  55 03 03 53 04 f1 02 48  |....Y...U..S...H|
-00000010  03 36 01 05 56 6f f0 54  d2 c3 d3 41 c2 e2 69 7b  |.6..Vo.T...A..i{|
-00000020  50 f8 03 ef 3f 5d 7c e6  9c cb fe 20 82 a0 81 fd  |P...?]|.... ....|
-00000030  72 4b b8 e6 29 76 3b 0f  1d 0a b7 82 9d 0b cf a0  |rK..)v;.........|
-00000040  65 b1 56 53 c9 d5 58 7b  f0 b6 2d cf c0 2b 00 00  |e.VS..X{..-..+..|
+00000000  16 03 03 00 59 02 00 00  55 03 03 91 8a 4f 94 29  |....Y...U....O.)|
+00000010  32 fa 66 7a 7f b8 a7 04  5c 34 b9 7e 12 83 35 1f  |2.fz....\4.~..5.|
+00000020  93 b0 af e0 9f 71 07 5e  2f d7 ca 20 52 dc 0d e7  |.....q.^/.. R...|
+00000030  f8 16 db 90 9a 78 2f 03  0b f0 ae a7 2f c6 b4 4c  |.....x/...../..L|
+00000040  62 e7 de 32 d5 68 61 f3  07 e4 60 d2 c0 2b 00 00  |b..2.ha...`..+..|
 00000050  0d ff 01 00 01 00 00 0b  00 04 03 00 01 02 16 03  |................|
 00000060  03 02 0e 0b 00 02 0a 00  02 07 00 02 04 30 82 02  |.............0..|
 00000070  00 30 82 01 62 02 09 00  b8 bf 2d 47 a0 d2 eb f4  |.0..b.....-G....|
@@ -47,38 +48,38 @@
 00000240  13 83 0d 94 06 bb d4 37  7a f6 ec 7a c9 86 2e dd  |.......7z..z....|
 00000250  d7 11 69 7f 85 7c 56 de  fb 31 78 2b e4 c7 78 0d  |..i..|V..1x+..x.|
 00000260  ae cb be 9e 4e 36 24 31  7b 6a 0f 39 95 12 07 8f  |....N6$1{j.9....|
-00000270  2a 16 03 03 00 d7 0c 00  00 d3 03 00 17 41 04 86  |*............A..|
-00000280  36 b4 78 76 87 70 ed ae  0d 34 70 3d 16 e5 a4 db  |6.xv.p...4p=....|
-00000290  ae 28 58 4c 01 5a 56 73  a7 0d 34 59 a7 04 75 69  |.(XL.ZVs..4Y..ui|
-000002a0  f2 55 24 40 b0 33 c6 93  ff ae e0 14 f5 4b ce a8  |.U$@.3.......K..|
-000002b0  e2 e6 9a 67 1d 66 fb 8f  fd 56 59 e7 73 f2 2c 04  |...g.f...VY.s.,.|
-000002c0  03 00 8a 30 81 87 02 41  73 ab a8 3c 64 17 69 9f  |...0...As..<d.i.|
-000002d0  4d b2 9b 55 12 60 33 94  cf f3 83 40 2b 7b 1b af  |M..U.`3....@+{..|
-000002e0  5c f4 cd 02 66 fb 83 04  35 fd ab 74 98 1a 7d f6  |\...f...5..t..}.|
-000002f0  9e 50 98 c3 98 e8 56 9c  f2 2a b0 30 9d 05 14 58  |.P....V..*.0...X|
-00000300  68 6a 88 04 49 07 78 bf  3a 02 42 01 be b2 05 9e  |hj..I.x.:.B.....|
-00000310  67 da 1e e9 5a 36 98 52  21 9f 43 75 43 ba bb 9a  |g...Z6.R!.CuC...|
-00000320  e6 e2 65 f4 e0 44 45 08  5a 1e 54 06 dd 5f 60 2e  |..e..DE.Z.T.._`.|
-00000330  7d e7 55 08 d3 7b 4e 0a  c7 da d4 27 34 d4 bd b0  |}.U..{N....'4...|
-00000340  12 2f 41 7a ed 71 32 ef  ee 12 74 66 00 16 03 03  |./Az.q2...tf....|
-00000350  00 04 0e 00 00 00                                 |......|
+00000270  2a 16 03 03 00 d8 0c 00  00 d4 03 00 17 41 04 26  |*............A.&|
+00000280  c1 67 14 4b 9e b0 45 8c  27 bf a3 a2 78 5b 56 ad  |.g.K..E.'...x[V.|
+00000290  d1 21 56 53 df 86 e9 91  de e3 f9 5d e6 f6 5d 79  |.!VS.......]..]y|
+000002a0  11 8b 60 f9 c2 9a c6 3f  6b 72 cd 7c d7 0e 13 64  |..`....?kr.|...d|
+000002b0  af e8 9f 40 35 e6 fb 04  0c 60 aa 19 61 dd 24 04  |...@5....`..a.$.|
+000002c0  03 00 8b 30 81 88 02 42  00 9d e1 02 5d 8b b1 45  |...0...B....]..E|
+000002d0  e5 c7 b6 94 27 df 36 31  fd 5e 47 fe c8 0f 5f 17  |....'.61.^G..._.|
+000002e0  b1 92 56 76 29 45 3d 90  be 91 6e 2c a7 b2 e1 33  |..Vv)E=...n,...3|
+000002f0  3b f9 3c bb 80 58 c2 d8  a8 59 82 16 dc 9e dd 60  |;.<..X...Y.....`|
+00000300  ff 82 b9 0c 5a ca ff f3  02 2c 02 42 00 a4 c0 d3  |....Z....,.B....|
+00000310  aa 1d 69 52 c0 06 fa 93  e8 50 da a4 2f 72 c9 4a  |..iR.....P../r.J|
+00000320  2c 43 7f 95 05 f7 7a f3  4a 2e 2d ce 13 be 80 40  |,C....z.J.-....@|
+00000330  a4 3b b2 f0 73 8d f1 d4  7b a3 ff 01 e1 58 71 31  |.;..s...{....Xq1|
+00000340  fc d8 2f b3 ef 62 2e b7  ac f5 c4 bc b8 68 16 03  |../..b.......h..|
+00000350  03 00 04 0e 00 00 00                              |.......|
 >>> Flow 3 (client to server)
 00000000  16 03 03 00 46 10 00 00  42 41 04 1e 18 37 ef 0d  |....F...BA...7..|
 00000010  19 51 88 35 75 71 b5 e5  54 5b 12 2e 8f 09 67 fd  |.Q.5uq..T[....g.|
 00000020  a7 24 20 3e b2 56 1c ce  97 28 5e f8 2b 2d 4f 9e  |.$ >.V...(^.+-O.|
 00000030  f1 07 9f 6c 4b 5b 83 56  e2 32 42 e9 58 b6 d7 49  |...lK[.V.2B.X..I|
 00000040  a6 b5 68 1a 41 03 56 6b  dc 5a 89 14 03 03 00 01  |..h.A.Vk.Z......|
-00000050  01 16 03 03 00 28 00 00  00 00 00 00 00 00 87 7a  |.....(.........z|
-00000060  82 d7 46 25 1d a6 bb c2  a8 a8 4e a5 d1 f8 02 db  |..F%......N.....|
-00000070  33 33 ca 78 b6 d3 bd 77  8a 33 23 a7 95 fb        |33.x...w.3#...|
+00000050  01 16 03 03 00 28 00 00  00 00 00 00 00 00 83 cf  |.....(..........|
+00000060  ef 50 c2 e7 da b9 74 7f  1c e0 b8 fb dc 39 c9 98  |.P....t......9..|
+00000070  0c a3 7d 8c c6 fa 6f f2  ee 44 a0 a0 03 18        |..}...o..D....|
 >>> Flow 4 (server to client)
-00000000  14 03 03 00 01 01 16 03  03 00 28 ce a1 9d 01 c0  |..........(.....|
-00000010  31 e5 d5 57 16 e1 a6 b3  8b 25 58 0f fa 2a de 3e  |1..W.....%X..*.>|
-00000020  0c d9 06 11 a6 b0 d7 b0  33 ad 31 73 5b 26 b4 d2  |........3.1s[&..|
-00000030  12 56 c8                                          |.V.|
+00000000  14 03 03 00 01 01 16 03  03 00 28 73 c4 48 24 3d  |..........(s.H$=|
+00000010  8f 5f f3 8c fc fd 63 be  64 39 d5 56 67 bd d7 c4  |._....c.d9.Vg...|
+00000020  0d 57 88 1a 45 a6 f3 ad  11 b2 5a 41 58 33 f3 d3  |.W..E.....ZAX3..|
+00000030  58 fa 21                                          |X.!|
 >>> Flow 5 (client to server)
-00000000  17 03 03 00 1e 00 00 00  00 00 00 00 01 d5 04 4c  |...............L|
-00000010  7b 35 b4 d7 90 ae fe 00  d2 f2 4b 76 f1 36 5e 24  |{5........Kv.6^$|
-00000020  4a aa 94 15 03 03 00 1a  00 00 00 00 00 00 00 02  |J...............|
-00000030  d3 1c 41 37 ab f6 17 79  f0 01 a4 19 a5 75 7a 8e  |..A7...y.....uz.|
-00000040  a3 b2                                             |..|
+00000000  17 03 03 00 1e 00 00 00  00 00 00 00 01 65 5e 55  |.............e^U|
+00000010  32 be 00 77 6e 1d 8e 8f  95 33 24 3d 7a c2 b0 3f  |2..wn....3$=z..?|
+00000020  ca aa 97 15 03 03 00 1a  00 00 00 00 00 00 00 02  |................|
+00000030  b2 71 6e 42 6a 0d cf c9  ac 14 a4 b5 9c c9 71 60  |.qnBj.........q`|
+00000040  d7 c2                                             |..|
diff --git a/third_party/gofrontend/libgo/go/crypto/tls/testdata/Client-TLSv12-ECDHE-ECDSA-AES256-GCM-SHA384 b/third_party/gofrontend/libgo/go/crypto/tls/testdata/Client-TLSv12-ECDHE-ECDSA-AES256-GCM-SHA384
new file mode 100644
index 0000000..df2f737
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/crypto/tls/testdata/Client-TLSv12-ECDHE-ECDSA-AES256-GCM-SHA384
@@ -0,0 +1,85 @@
+>>> Flow 1 (client to server)
+00000000  16 03 01 00 81 01 00 00  7d 03 03 00 00 00 00 00  |........}.......|
+00000010  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
+00000020  00 00 00 00 00 00 00 00  00 00 00 00 00 1e c0 2f  |.............../|
+00000030  c0 2b c0 30 c0 2c c0 11  c0 07 c0 13 c0 09 c0 14  |.+.0.,..........|
+00000040  c0 0a 00 05 00 2f 00 35  c0 12 00 0a 01 00 00 36  |...../.5.......6|
+00000050  00 05 00 05 01 00 00 00  00 00 0a 00 08 00 06 00  |................|
+00000060  17 00 18 00 19 00 0b 00  02 01 00 00 0d 00 0e 00  |................|
+00000070  0c 04 01 04 03 05 01 05  03 02 01 02 03 ff 01 00  |................|
+00000080  01 00 00 12 00 00                                 |......|
+>>> Flow 2 (server to client)
+00000000  16 03 03 00 59 02 00 00  55 03 03 11 50 81 a7 ef  |....Y...U...P...|
+00000010  3f bd a5 a9 41 11 e6 86  b2 a3 d8 bf 29 c3 d4 f4  |?...A.......)...|
+00000020  b6 20 2d cb 94 1b 0e dd  99 d1 0b 20 78 92 23 31  |. -........ x.#1|
+00000030  e3 fc 99 67 1f fd f3 2a  fc 9c 4c 74 6e 32 e4 f8  |...g...*..Ltn2..|
+00000040  ed 6d 2e 6d ad a9 a9 bf  63 27 7e 44 c0 2c 00 00  |.m.m....c'~D.,..|
+00000050  0d ff 01 00 01 00 00 0b  00 04 03 00 01 02 16 03  |................|
+00000060  03 02 0e 0b 00 02 0a 00  02 07 00 02 04 30 82 02  |.............0..|
+00000070  00 30 82 01 62 02 09 00  b8 bf 2d 47 a0 d2 eb f4  |.0..b.....-G....|
+00000080  30 09 06 07 2a 86 48 ce  3d 04 01 30 45 31 0b 30  |0...*.H.=..0E1.0|
+00000090  09 06 03 55 04 06 13 02  41 55 31 13 30 11 06 03  |...U....AU1.0...|
+000000a0  55 04 08 13 0a 53 6f 6d  65 2d 53 74 61 74 65 31  |U....Some-State1|
+000000b0  21 30 1f 06 03 55 04 0a  13 18 49 6e 74 65 72 6e  |!0...U....Intern|
+000000c0  65 74 20 57 69 64 67 69  74 73 20 50 74 79 20 4c  |et Widgits Pty L|
+000000d0  74 64 30 1e 17 0d 31 32  31 31 32 32 31 35 30 36  |td0...1211221506|
+000000e0  33 32 5a 17 0d 32 32 31  31 32 30 31 35 30 36 33  |32Z..22112015063|
+000000f0  32 5a 30 45 31 0b 30 09  06 03 55 04 06 13 02 41  |2Z0E1.0...U....A|
+00000100  55 31 13 30 11 06 03 55  04 08 13 0a 53 6f 6d 65  |U1.0...U....Some|
+00000110  2d 53 74 61 74 65 31 21  30 1f 06 03 55 04 0a 13  |-State1!0...U...|
+00000120  18 49 6e 74 65 72 6e 65  74 20 57 69 64 67 69 74  |.Internet Widgit|
+00000130  73 20 50 74 79 20 4c 74  64 30 81 9b 30 10 06 07  |s Pty Ltd0..0...|
+00000140  2a 86 48 ce 3d 02 01 06  05 2b 81 04 00 23 03 81  |*.H.=....+...#..|
+00000150  86 00 04 00 c4 a1 ed be  98 f9 0b 48 73 36 7e c3  |...........Hs6~.|
+00000160  16 56 11 22 f2 3d 53 c3  3b 4d 21 3d cd 6b 75 e6  |.V.".=S.;M!=.ku.|
+00000170  f6 b0 dc 9a df 26 c1 bc  b2 87 f0 72 32 7c b3 64  |.....&.....r2|.d|
+00000180  2f 1c 90 bc ea 68 23 10  7e fe e3 25 c0 48 3a 69  |/....h#.~..%.H:i|
+00000190  e0 28 6d d3 37 00 ef 04  62 dd 0d a0 9c 70 62 83  |.(m.7...b....pb.|
+000001a0  d8 81 d3 64 31 aa 9e 97  31 bd 96 b0 68 c0 9b 23  |...d1...1...h..#|
+000001b0  de 76 64 3f 1a 5c 7f e9  12 0e 58 58 b6 5f 70 dd  |.vd?.\....XX._p.|
+000001c0  9b d8 ea d5 d7 f5 d5 cc  b9 b6 9f 30 66 5b 66 9a  |...........0f[f.|
+000001d0  20 e2 27 e5 bf fe 3b 30  09 06 07 2a 86 48 ce 3d  | .'...;0...*.H.=|
+000001e0  04 01 03 81 8c 00 30 81  88 02 42 01 88 a2 4f eb  |......0...B...O.|
+000001f0  e2 45 c5 48 7d 1b ac f5  ed 98 9d ae 47 70 c0 5e  |.E.H}.......Gp.^|
+00000200  1b b6 2f bd f1 b6 4d b7  61 40 d3 11 a2 ce ee 0b  |../...M.a@......|
+00000210  7e 92 7e ff 76 9d c3 3b  7e a5 3f ce fa 10 e2 59  |~.~.v..;~.?....Y|
+00000220  ec 47 2d 7c ac da 4e 97  0e 15 a0 6f d0 02 42 01  |.G-|..N....o..B.|
+00000230  4d fc be 67 13 9c 2d 05  0e bd 3f a3 8c 25 c1 33  |M..g..-...?..%.3|
+00000240  13 83 0d 94 06 bb d4 37  7a f6 ec 7a c9 86 2e dd  |.......7z..z....|
+00000250  d7 11 69 7f 85 7c 56 de  fb 31 78 2b e4 c7 78 0d  |..i..|V..1x+..x.|
+00000260  ae cb be 9e 4e 36 24 31  7b 6a 0f 39 95 12 07 8f  |....N6$1{j.9....|
+00000270  2a 16 03 03 00 d7 0c 00  00 d3 03 00 17 41 04 fc  |*............A..|
+00000280  e6 25 27 3c 76 10 a8 9e  d3 a4 a8 68 31 06 85 fc  |.%'<v......h1...|
+00000290  35 2a 76 b3 ad 08 c5 70  ed 3d 61 e0 29 cc 47 52  |5*v....p.=a.).GR|
+000002a0  68 21 ab 48 19 f9 28 ba  54 8c 56 8e b0 7d 55 7f  |h!.H..(.T.V..}U.|
+000002b0  75 f5 42 38 61 ff e2 06  98 1a ae fc bc a0 3a 04  |u.B8a.........:.|
+000002c0  03 00 8a 30 81 87 02 42  01 0c b2 7f c9 d3 1b 83  |...0...B........|
+000002d0  1e 24 a3 d7 1c 81 f0 02  ae ed 42 6f e9 d9 91 4d  |.$........Bo...M|
+000002e0  16 5f aa 8e 5a de 3b 00  0e e6 2d fb 05 30 f3 cf  |._..Z.;...-..0..|
+000002f0  31 a2 ec 99 87 ea 42 03  0a 57 82 e5 12 27 98 8a  |1.....B..W...'..|
+00000300  c6 56 4b 9a 0b d7 37 5f  46 50 02 41 57 61 13 3c  |.VK...7_FP.AWa.<|
+00000310  48 d0 b3 b0 d5 21 72 49  80 7b d7 ef 8f 0d a0 c5  |H....!rI.{......|
+00000320  88 a1 5d ca 61 6d fb 8b  51 15 5d e5 a2 61 c4 78  |..].am..Q.]..a.x|
+00000330  8f d9 e3 78 df 7d a0 8f  0c c0 cc 18 36 41 e6 bb  |...x.}......6A..|
+00000340  6d e3 9d 04 c2 c4 d0 66  35 45 9a 08 b2 16 03 03  |m......f5E......|
+00000350  00 04 0e 00 00 00                                 |......|
+>>> Flow 3 (client to server)
+00000000  16 03 03 00 46 10 00 00  42 41 04 1e 18 37 ef 0d  |....F...BA...7..|
+00000010  19 51 88 35 75 71 b5 e5  54 5b 12 2e 8f 09 67 fd  |.Q.5uq..T[....g.|
+00000020  a7 24 20 3e b2 56 1c ce  97 28 5e f8 2b 2d 4f 9e  |.$ >.V...(^.+-O.|
+00000030  f1 07 9f 6c 4b 5b 83 56  e2 32 42 e9 58 b6 d7 49  |...lK[.V.2B.X..I|
+00000040  a6 b5 68 1a 41 03 56 6b  dc 5a 89 14 03 03 00 01  |..h.A.Vk.Z......|
+00000050  01 16 03 03 00 28 00 00  00 00 00 00 00 00 a3 3f  |.....(.........?|
+00000060  be 65 91 cd fe 37 43 e0  ea 6f 15 9d c2 aa 6a 02  |.e...7C..o....j.|
+00000070  20 b8 bc b5 c8 9a 1c d4  c4 e5 9b 2e 39 e7        | ...........9.|
+>>> Flow 4 (server to client)
+00000000  14 03 03 00 01 01 16 03  03 00 28 7c b7 1f 13 9e  |..........(|....|
+00000010  21 d2 eb db 32 fc 36 d0  53 e1 11 04 ce d0 61 33  |!...2.6.S.....a3|
+00000020  1e 30 3d 91 c3 6a 0d 98  55 f5 e0 5c ca 77 fa 72  |.0=..j..U..\.w.r|
+00000030  63 6a be                                          |cj.|
+>>> Flow 5 (client to server)
+00000000  17 03 03 00 1e 00 00 00  00 00 00 00 01 d9 db db  |................|
+00000010  4b 3a ae 5c a4 dc 96 33  ed b5 a0 70 64 1f 96 2f  |K:.\...3...pd../|
+00000020  b6 cd 1e 15 03 03 00 1a  00 00 00 00 00 00 00 02  |................|
+00000030  18 a0 d1 98 a6 71 c9 56  36 bd 1a 46 4b 5b 45 29  |.....q.V6..FK[E)|
+00000040  1f dd                                             |..|
diff --git a/third_party/gofrontend/libgo/go/crypto/tls/testdata/Client-TLSv12-ECDHE-RSA-AES b/third_party/gofrontend/libgo/go/crypto/tls/testdata/Client-TLSv12-ECDHE-RSA-AES
index 5336bbb..994ebb1 100644
--- a/third_party/gofrontend/libgo/go/crypto/tls/testdata/Client-TLSv12-ECDHE-RSA-AES
+++ b/third_party/gofrontend/libgo/go/crypto/tls/testdata/Client-TLSv12-ECDHE-RSA-AES
@@ -1,18 +1,19 @@
 >>> Flow 1 (client to server)
-00000000  16 03 01 00 75 01 00 00  71 03 03 00 00 00 00 00  |....u...q.......|
+00000000  16 03 01 00 81 01 00 00  7d 03 03 00 00 00 00 00  |........}.......|
 00000010  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
-00000020  00 00 00 00 00 00 00 00  00 00 00 00 00 1a c0 2f  |.............../|
-00000030  c0 2b c0 11 c0 07 c0 13  c0 09 c0 14 c0 0a 00 05  |.+..............|
-00000040  00 2f 00 35 c0 12 00 0a  01 00 00 2e 00 05 00 05  |./.5............|
-00000050  01 00 00 00 00 00 0a 00  08 00 06 00 17 00 18 00  |................|
-00000060  19 00 0b 00 02 01 00 00  0d 00 0a 00 08 04 01 04  |................|
-00000070  03 02 01 02 03 ff 01 00  01 00                    |..........|
+00000020  00 00 00 00 00 00 00 00  00 00 00 00 00 1e c0 2f  |.............../|
+00000030  c0 2b c0 30 c0 2c c0 11  c0 07 c0 13 c0 09 c0 14  |.+.0.,..........|
+00000040  c0 0a 00 05 00 2f 00 35  c0 12 00 0a 01 00 00 36  |...../.5.......6|
+00000050  00 05 00 05 01 00 00 00  00 00 0a 00 08 00 06 00  |................|
+00000060  17 00 18 00 19 00 0b 00  02 01 00 00 0d 00 0e 00  |................|
+00000070  0c 04 01 04 03 05 01 05  03 02 01 02 03 ff 01 00  |................|
+00000080  01 00 00 12 00 00                                 |......|
 >>> Flow 2 (server to client)
-00000000  16 03 03 00 59 02 00 00  55 03 03 53 04 f1 02 41  |....Y...U..S...A|
-00000010  95 cc 56 30 65 46 24 75  d5 9e 3c a7 5b 6c 99 fe  |..V0eF$u..<.[l..|
-00000020  86 35 23 42 3a 8f 4d 4c  b9 98 7d 20 a7 46 43 72  |.5#B:.ML..} .FCr|
-00000030  66 bb b6 ad ff ad cf 63  37 fe 6b b4 78 94 08 49  |f......c7.k.x..I|
-00000040  54 06 ed f4 85 73 38 4a  c6 fe b6 98 c0 13 00 00  |T....s8J........|
+00000000  16 03 03 00 59 02 00 00  55 03 03 e6 ae 89 0d 22  |....Y...U......"|
+00000010  e5 e0 cd 57 a3 ca 71 4f  17 2f 64 77 f8 30 89 ef  |...W..qO./dw.0..|
+00000020  e8 19 70 ac dd 2c c5 9f  84 7d 1d 20 1c 59 3c fe  |..p..,...}. .Y<.|
+00000030  a9 ec 10 dd 38 3b 43 fe  6b 09 e5 e4 83 d9 7a 78  |....8;C.k.....zx|
+00000040  86 08 33 da 9b e1 09 d8  c9 07 34 19 c0 13 00 00  |..3.......4.....|
 00000050  0d ff 01 00 01 00 00 0b  00 04 03 00 01 02 16 03  |................|
 00000060  03 02 be 0b 00 02 ba 00  02 b7 00 02 b4 30 82 02  |.............0..|
 00000070  b0 30 82 02 19 a0 03 02  01 02 02 09 00 85 b0 bb  |.0..............|
@@ -58,20 +59,20 @@
 000002f0  5f 33 c4 b6 d8 c9 75 90  96 8c 0f 52 98 b5 cd 98  |_3....u....R....|
 00000300  1f 89 20 5f f2 a0 1c a3  1b 96 94 dd a9 fd 57 e9  |.. _..........W.|
 00000310  70 e8 26 6d 71 99 9b 26  6e 38 50 29 6c 90 a7 bd  |p.&mq..&n8P)l...|
-00000320  d9 16 03 03 00 cd 0c 00  00 c9 03 00 17 41 04 48  |.............A.H|
-00000330  68 d8 8a 10 b4 bf eb 8d  d1 98 b0 a6 f4 47 5d 91  |h............G].|
-00000340  61 da 50 d9 85 7b 5d 90  02 2c 38 c9 af 81 d3 55  |a.P..{]..,8....U|
-00000350  07 62 b1 62 58 7f 39 94  d7 91 96 a8 1f 47 60 a5  |.b.bX.9......G`.|
-00000360  c0 04 f2 fb cb 15 75 a6  16 3f 94 53 7c ff dd 04  |......u..?.S|...|
-00000370  01 00 80 b9 82 fa 0b f8  8c 94 2c 6e 05 81 7d 80  |..........,n..}.|
-00000380  5d 9a 77 78 af c8 33 5d  89 7e 2e 3c e5 72 66 a8  |].wx..3].~.<.rf.|
-00000390  f1 5c 02 04 02 70 76 7b  45 ff 0d 29 a0 cb 0d db  |.\...pv{E..)....|
-000003a0  7a 4c c4 13 19 cd 47 b2  f1 c9 43 4f 95 d2 f1 c6  |zL....G...CO....|
-000003b0  bc ae 31 4a 9d de 80 b2  a4 b7 b6 dd 8c 03 3e 2a  |..1J..........>*|
-000003c0  46 5e d1 e7 5b c5 9e 06  58 f3 55 b2 77 09 f3 98  |F^..[...X.U.w...|
-000003d0  d5 7f 5a 74 64 7e 48 22  8f 7d a8 68 b6 1d 90 df  |..Ztd~H".}.h....|
-000003e0  2c 91 d7 c5 07 3d d1 6f  e9 c1 91 03 3c 23 5a 56  |,....=.o....<#ZV|
-000003f0  3b b2 c2 16 03 03 00 04  0e 00 00 00              |;...........|
+00000320  d9 16 03 03 00 cd 0c 00  00 c9 03 00 17 41 04 77  |.............A.w|
+00000330  87 a7 ad f6 f8 34 82 05  ef bb 14 6d c7 8b 7b 2a  |.....4.....m..{*|
+00000340  4d ca 41 65 58 3c 83 fa  4d ce 0c 74 46 85 fe 38  |M.AeX<..M..tF..8|
+00000350  95 80 ee 7c c2 bf f2 be  a3 c6 bf f3 aa 07 23 40  |...|..........#@|
+00000360  7e cc 74 4a 4e 2e 69 af  6b e0 42 8a fc 41 be 04  |~.tJN.i.k.B..A..|
+00000370  01 00 80 99 ed a8 3a ef  93 1b 4c 17 80 9e cc eb  |......:...L.....|
+00000380  da 39 fb c8 9a 73 e1 96  20 3e 41 fa 8b 1a b1 68  |.9...s.. >A....h|
+00000390  cd 47 bc 4b 7b 0c 14 da  87 d3 36 09 5e 37 33 88  |.G.K{.....6.^73.|
+000003a0  7f 88 07 87 46 ec e5 72  a8 59 92 07 fa 4d 02 dc  |....F..r.Y...M..|
+000003b0  bf 3a f5 e4 77 0b a6 85  ce 43 ee 1b 90 30 7f ec  |.:..w....C...0..|
+000003c0  88 79 f8 88 59 af 6b 7f  2d 88 de 92 cd c8 36 cf  |.y..Y.k.-.....6.|
+000003d0  ba b9 08 6a c4 3d d7 9a  48 50 e1 67 d0 62 a5 b3  |...j.=..HP.g.b..|
+000003e0  b0 5f 2e 16 ee 4d 7d a2  cf d9 93 19 89 b7 64 0f  |._...M}.......d.|
+000003f0  0f 8e 3d 16 03 03 00 04  0e 00 00 00              |..=.........|
 >>> Flow 3 (client to server)
 00000000  16 03 03 00 46 10 00 00  42 41 04 1e 18 37 ef 0d  |....F...BA...7..|
 00000010  19 51 88 35 75 71 b5 e5  54 5b 12 2e 8f 09 67 fd  |.Q.5uq..T[....g.|
@@ -79,21 +80,21 @@
 00000030  f1 07 9f 6c 4b 5b 83 56  e2 32 42 e9 58 b6 d7 49  |...lK[.V.2B.X..I|
 00000040  a6 b5 68 1a 41 03 56 6b  dc 5a 89 14 03 03 00 01  |..h.A.Vk.Z......|
 00000050  01 16 03 03 00 40 00 00  00 00 00 00 00 00 00 00  |.....@..........|
-00000060  00 00 00 00 00 00 59 e6  92 05 27 ec 09 2c b0 a5  |......Y...'..,..|
-00000070  2a fb 7e f1 03 53 16 63  68 a1 86 13 bb da 98 27  |*.~..S.ch......'|
-00000080  6d 42 08 35 6a ec 58 61  2a 4d 44 ec ae c5 b9 d2  |mB.5j.Xa*MD.....|
-00000090  76 57 1f 75 9f 8d                                 |vW.u..|
+00000060  00 00 00 00 00 00 f2 20  58 ec f1 88 a6 26 79 9d  |....... X....&y.|
+00000070  2e 9b 02 b5 5e da e2 c1  c5 8d c8 93 6f 6d 07 4e  |....^.......om.N|
+00000080  fa dd ee cb b1 ae c7 3b  09 b2 cc 64 7a cd 98 91  |.......;...dz...|
+00000090  cb f8 3c 34 3b ed                                 |..<4;.|
 >>> Flow 4 (server to client)
-00000000  14 03 03 00 01 01 16 03  03 00 40 6e 03 d0 e6 98  |..........@n....|
-00000010  1f f5 39 7b 06 9f 95 f0  7a 88 35 7c 55 db c3 2f  |..9{....z.5|U../|
-00000020  00 ef 5b d3 62 87 a2 94  da 2f f6 4a 89 c9 a8 3d  |..[.b..../.J...=|
-00000030  3a 92 db 77 35 92 01 4b  f5 c5 6b 95 09 9f cd 79  |:..w5..K..k....y|
-00000040  3c af 37 5b 27 bf 93 3e  04 55 71                 |<.7['..>.Uq|
+00000000  14 03 03 00 01 01 16 03  03 00 40 4c a1 8d bd 49  |..........@L...I|
+00000010  33 d3 72 fb 2f 23 7e 11  29 fc d2 ff 9b 67 30 c8  |3.r./#~.)....g0.|
+00000020  be c1 bc 51 6e 92 a5 f4  9d e3 b3 f9 d2 d4 c4 a5  |...Qn...........|
+00000030  83 23 90 b3 17 00 35 18  c5 ef 8b 18 a3 cf ed 9d  |.#....5.........|
+00000040  a9 52 c9 11 0a c9 55 c2  76 df 78                 |.R....U.v.x|
 >>> Flow 5 (client to server)
 00000000  17 03 03 00 30 00 00 00  00 00 00 00 00 00 00 00  |....0...........|
-00000010  00 00 00 00 00 bc c9 d0  8e 80 14 de 32 18 49 e8  |............2.I.|
-00000020  20 dc 5e 6c e4 6d 14 00  df 51 71 fb 86 95 16 4c  | .^l.m...Qq....L|
-00000030  04 8e 71 e1 48 15 03 03  00 30 00 00 00 00 00 00  |..q.H....0......|
-00000040  00 00 00 00 00 00 00 00  00 00 b7 6d 30 72 61 53  |...........m0raS|
-00000050  d8 0a d4 1d ae e5 d4 22  46 c9 d5 4e 4a 86 f5 ac  |......."F..NJ...|
-00000060  72 98 c6 db 38 29 97 2c  84 0b                    |r...8).,..|
+00000010  00 00 00 00 00 60 40 d0  bf 8f ef 05 2b 89 d7 bb  |.....`@.....+...|
+00000020  27 d0 1f b2 cf c3 ff 8e  be 69 16 a9 b3 03 e8 3c  |'........i.....<|
+00000030  30 1d 58 39 4a 15 03 03  00 30 00 00 00 00 00 00  |0.X9J....0......|
+00000040  00 00 00 00 00 00 00 00  00 00 de 61 51 a1 3c fc  |...........aQ.<.|
+00000050  1c 7b e6 f2 7d e0 aa 80  2d 9c e9 22 09 5c dd 8a  |.{..}...-..".\..|
+00000060  55 cc c4 77 34 97 05 88  98 d3                    |U..w4.....|
diff --git a/third_party/gofrontend/libgo/go/crypto/tls/testdata/Client-TLSv12-RSA-RC4 b/third_party/gofrontend/libgo/go/crypto/tls/testdata/Client-TLSv12-RSA-RC4
index 0377f05..73e34c0 100644
--- a/third_party/gofrontend/libgo/go/crypto/tls/testdata/Client-TLSv12-RSA-RC4
+++ b/third_party/gofrontend/libgo/go/crypto/tls/testdata/Client-TLSv12-RSA-RC4
@@ -1,18 +1,19 @@
 >>> Flow 1 (client to server)
-00000000  16 03 01 00 75 01 00 00  71 03 03 00 00 00 00 00  |....u...q.......|
+00000000  16 03 01 00 81 01 00 00  7d 03 03 00 00 00 00 00  |........}.......|
 00000010  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
-00000020  00 00 00 00 00 00 00 00  00 00 00 00 00 1a c0 2f  |.............../|
-00000030  c0 2b c0 11 c0 07 c0 13  c0 09 c0 14 c0 0a 00 05  |.+..............|
-00000040  00 2f 00 35 c0 12 00 0a  01 00 00 2e 00 05 00 05  |./.5............|
-00000050  01 00 00 00 00 00 0a 00  08 00 06 00 17 00 18 00  |................|
-00000060  19 00 0b 00 02 01 00 00  0d 00 0a 00 08 04 01 04  |................|
-00000070  03 02 01 02 03 ff 01 00  01 00                    |..........|
+00000020  00 00 00 00 00 00 00 00  00 00 00 00 00 1e c0 2f  |.............../|
+00000030  c0 2b c0 30 c0 2c c0 11  c0 07 c0 13 c0 09 c0 14  |.+.0.,..........|
+00000040  c0 0a 00 05 00 2f 00 35  c0 12 00 0a 01 00 00 36  |...../.5.......6|
+00000050  00 05 00 05 01 00 00 00  00 00 0a 00 08 00 06 00  |................|
+00000060  17 00 18 00 19 00 0b 00  02 01 00 00 0d 00 0e 00  |................|
+00000070  0c 04 01 04 03 05 01 05  03 02 01 02 03 ff 01 00  |................|
+00000080  01 00 00 12 00 00                                 |......|
 >>> Flow 2 (server to client)
-00000000  16 03 03 00 51 02 00 00  4d 03 03 53 04 f1 02 9d  |....Q...M..S....|
-00000010  2e 4e d9 17 4a 35 fa 9d  94 f6 45 0a f6 6b 5d 1c  |.N..J5....E..k].|
-00000020  1e 15 19 8d 6d 94 cc 90  d9 39 94 20 8b 4b de 76  |....m....9. .K.v|
-00000030  d5 64 5d b7 19 df e7 eb  7e a0 22 c4 09 38 a0 12  |.d].....~."..8..|
-00000040  d5 59 10 c8 31 06 dc fc  e4 9d d1 80 00 05 00 00  |.Y..1...........|
+00000000  16 03 03 00 51 02 00 00  4d 03 03 e8 ae 4c 97 41  |....Q...M....L.A|
+00000010  78 0f 08 84 d4 4a 80 6d  a2 e1 d0 67 40 8f 01 8b  |x....J.m...g@...|
+00000020  20 54 cb 28 16 52 04 fd  3c c2 84 20 30 96 f0 51  | T.(.R..<.. 0..Q|
+00000030  72 86 6a d8 47 b9 47 e3  a4 ad 97 77 a9 77 1a f9  |r.j.G.G....w.w..|
+00000040  ba 63 33 32 4f 43 09 1c  e1 bd 1b 3b 00 05 00 00  |.c32OC.....;....|
 00000050  05 ff 01 00 01 00 16 03  03 02 be 0b 00 02 ba 00  |................|
 00000060  02 b7 00 02 b4 30 82 02  b0 30 82 02 19 a0 03 02  |.....0...0......|
 00000070  01 02 02 09 00 85 b0 bb  a4 8a 7f b8 ca 30 0d 06  |.............0..|
@@ -69,15 +70,15 @@
 00000060  e6 bd 77 82 6f 23 b6 e0  bd a2 92 b7 3a ac e8 56  |..w.o#......:..V|
 00000070  f1 af 54 5e 46 87 e9 3b  33 e7 b8 28 b7 d6 c8 90  |..T^F..;3..(....|
 00000080  35 d4 1c 43 d1 30 6f 55  4e 0a 70 14 03 03 00 01  |5..C.0oUN.p.....|
-00000090  01 16 03 03 00 24 37 14  b2 97 7b b5 f0 9a 38 05  |.....$7...{...8.|
-000000a0  22 35 69 9c 95 2f 86 4b  37 98 22 db 4e 9a 46 9c  |"5i../.K7.".N.F.|
-000000b0  b9 81 74 72 58 18 53 0c  5c 3c                    |..trX.S.\<|
+00000090  01 16 03 03 00 24 54 8c  7f 71 03 7c 98 e5 97 65  |.....$T..q.|...e|
+000000a0  51 13 b2 9d 4a b8 c9 c1  e6 11 1b 50 c8 1b c0 46  |Q...J......P...F|
+000000b0  a7 cb 13 97 92 a0 51 d4  a9 e5                    |......Q...|
 >>> Flow 4 (server to client)
-00000000  14 03 03 00 01 01 16 03  03 00 24 3c b3 e7 77 5a  |..........$<..wZ|
-00000010  7c 36 5a 74 74 26 8d 5b  5a 09 96 60 e8 24 45 2f  ||6Ztt&.[Z..`.$E/|
-00000020  c2 39 14 5e db 58 12 49  ad a8 b6 ea ef 58 16     |.9.^.X.I.....X.|
+00000000  14 03 03 00 01 01 16 03  03 00 24 37 ca ae 55 79  |..........$7..Uy|
+00000010  e7 0a 70 55 1e d1 76 61  57 46 d2 c0 d0 ed 3d 70  |..pU..vaWF....=p|
+00000020  1f 02 f2 06 5b 3e 50 ec  13 4b 67 e2 7c bd 45     |....[>P..Kg.|.E|
 >>> Flow 5 (client to server)
-00000000  17 03 03 00 1a 6d 29 d7  ba 2f 85 02 b6 f0 82 64  |.....m)../.....d|
-00000010  6c 55 ae ab f6 fd 14 ff  b8 38 f0 f8 a6 ea cc 15  |lU.......8......|
-00000020  03 03 00 16 10 c5 d9 41  7b e2 89 67 dc 29 8e f8  |.......A{..g.)..|
-00000030  b5 ab 32 91 44 2c 27 84  49 f7                    |..2.D,'.I.|
+00000000  17 03 03 00 1a c4 13 68  ec e0 38 a1 07 35 da d7  |.......h..8..5..|
+00000010  c4 6b f9 5c ed a7 8a cb  96 7a 22 7c ca a5 30 15  |.k.\.....z"|..0.|
+00000020  03 03 00 16 f7 a7 8d 41  b0 c1 4b 61 60 b0 b2 ed  |.......A..Ka`...|
+00000030  4a ab c3 54 d5 20 eb 67  b7 8f                    |J..T. .g..|
diff --git a/third_party/gofrontend/libgo/go/crypto/tls/testdata/Client-TLSv12-SCT b/third_party/gofrontend/libgo/go/crypto/tls/testdata/Client-TLSv12-SCT
new file mode 100644
index 0000000..826c9f0
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/crypto/tls/testdata/Client-TLSv12-SCT
@@ -0,0 +1,118 @@
+>>> Flow 1 (client to server)
+00000000  16 03 01 00 81 01 00 00  7d 03 03 00 00 00 00 00  |........}.......|
+00000010  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
+00000020  00 00 00 00 00 00 00 00  00 00 00 00 00 1e c0 2f  |.............../|
+00000030  c0 2b c0 30 c0 2c c0 11  c0 07 c0 13 c0 09 c0 14  |.+.0.,..........|
+00000040  c0 0a 00 05 00 2f 00 35  c0 12 00 0a 01 00 00 36  |...../.5.......6|
+00000050  00 05 00 05 01 00 00 00  00 00 0a 00 08 00 06 00  |................|
+00000060  17 00 18 00 19 00 0b 00  02 01 00 00 0d 00 0e 00  |................|
+00000070  0c 04 01 04 03 05 01 05  03 02 01 02 03 ff 01 00  |................|
+00000080  01 00 00 12 00 00                                 |......|
+>>> Flow 2 (server to client)
+00000000  16 03 03 01 c6 02 00 01  c2 03 03 1b f6 69 c1 c2  |.............i..|
+00000010  36 77 72 32 69 95 c9 e7  db 9b 5d bd 59 ba 08 02  |6wr2i.....].Y...|
+00000020  1e 76 11 c4 8e 49 08 22  8e 8a 5a 20 44 ec d9 13  |.v...I."..Z D...|
+00000030  23 ad 05 45 48 29 00 c6  11 3d 5a 5c a1 ee 34 2b  |#..EH)...=Z\..4+|
+00000040  58 ef 34 5b 7e 42 08 84  23 66 56 ee c0 2f 00 01  |X.4[~B..#fV../..|
+00000050  7a ff 01 00 01 00 00 0b  00 04 03 00 01 02 00 12  |z...............|
+00000060  01 69 01 67 00 75 00 a4  b9 09 90 b4 18 58 14 87  |.i.g.u.......X..|
+00000070  bb 13 a2 cc 67 70 0a 3c  35 98 04 f9 1b df b8 e3  |....gp.<5.......|
+00000080  77 cd 0e c8 0d dc 10 00  00 01 47 97 99 ee 16 00  |w.........G.....|
+00000090  00 04 03 00 46 30 44 02  20 1c 4b 82 5d 95 6e 67  |....F0D. .K.].ng|
+000000a0  5b db 04 95 4b f6 ce f4  32 3e 86 7a 7a 32 ab 18  |[...K...2>.zz2..|
+000000b0  60 74 de 08 da 05 91 4c  2f 02 20 73 54 1b 6e 7f  |`t.....L/. sT.n.|
+000000c0  a1 b0 7d 11 bc e6 f3 85  2f 97 66 1a f7 8a e4 10  |..}...../.f.....|
+000000d0  25 8f 12 f4 6f 39 0f d2  9e 18 f0 00 76 00 68 f6  |%...o9......v.h.|
+000000e0  98 f8 1f 64 82 be 3a 8c  ee b9 28 1d 4c fc 71 51  |...d..:...(.L.qQ|
+000000f0  5d 67 93 d4 44 d1 0a 67  ac bb 4f 4f fb c4 00 00  |]g..D..g..OO....|
+00000100  01 47 97 e1 b5 70 00 00  04 03 00 47 30 45 02 20  |.G...p.....G0E. |
+00000110  32 21 14 38 06 d8 72 2e  00 30 64 1a e2 e8 6d 4e  |2!.8..r..0d...mN|
+00000120  5a e1 d9 42 1e 82 4b 96  25 89 d5 26 13 d3 9c fa  |Z..B..K.%..&....|
+00000130  02 21 00 8f 12 28 64 51  4f 44 d5 8c 18 62 23 b2  |.!...(dQOD...b#.|
+00000140  43 93 33 05 f3 43 55 a1  d9 ee cd c5 71 35 91 dd  |C.3..CU.....q5..|
+00000150  49 d1 0b 00 76 00 ee 4b  bd b7 75 ce 60 ba e1 42  |I...v..K..u.`..B|
+00000160  69 1f ab e1 9e 66 a3 0f  7e 5f b0 72 d8 83 00 c4  |i....f..~_.r....|
+00000170  7b 89 7a a8 fd cb 00 00  01 48 5c 64 8a 87 00 00  |{.z......H\d....|
+00000180  04 03 00 47 30 45 02 20  29 89 d6 b0 53 d3 d2 e9  |...G0E. )...S...|
+00000190  91 bc f1 b5 40 be 1e 2e  e7 5c b4 74 27 ed 8f 9b  |....@....\.t'...|
+000001a0  02 e9 fa c2 4c ba a2 be  02 21 00 af 43 64 52 71  |....L....!..CdRq|
+000001b0  15 29 58 40 91 c7 08 16  96 03 a8 73 a5 65 a0 6c  |.)X@.......s.e.l|
+000001c0  b8 48 56 5a b6 29 83 64  6d 2a 9d 16 03 03 02 be  |.HVZ.).dm*......|
+000001d0  0b 00 02 ba 00 02 b7 00  02 b4 30 82 02 b0 30 82  |..........0...0.|
+000001e0  02 19 a0 03 02 01 02 02  09 00 85 b0 bb a4 8a 7f  |................|
+000001f0  b8 ca 30 0d 06 09 2a 86  48 86 f7 0d 01 01 05 05  |..0...*.H.......|
+00000200  00 30 45 31 0b 30 09 06  03 55 04 06 13 02 41 55  |.0E1.0...U....AU|
+00000210  31 13 30 11 06 03 55 04  08 13 0a 53 6f 6d 65 2d  |1.0...U....Some-|
+00000220  53 74 61 74 65 31 21 30  1f 06 03 55 04 0a 13 18  |State1!0...U....|
+00000230  49 6e 74 65 72 6e 65 74  20 57 69 64 67 69 74 73  |Internet Widgits|
+00000240  20 50 74 79 20 4c 74 64  30 1e 17 0d 31 30 30 34  | Pty Ltd0...1004|
+00000250  32 34 30 39 30 39 33 38  5a 17 0d 31 31 30 34 32  |24090938Z..11042|
+00000260  34 30 39 30 39 33 38 5a  30 45 31 0b 30 09 06 03  |4090938Z0E1.0...|
+00000270  55 04 06 13 02 41 55 31  13 30 11 06 03 55 04 08  |U....AU1.0...U..|
+00000280  13 0a 53 6f 6d 65 2d 53  74 61 74 65 31 21 30 1f  |..Some-State1!0.|
+00000290  06 03 55 04 0a 13 18 49  6e 74 65 72 6e 65 74 20  |..U....Internet |
+000002a0  57 69 64 67 69 74 73 20  50 74 79 20 4c 74 64 30  |Widgits Pty Ltd0|
+000002b0  81 9f 30 0d 06 09 2a 86  48 86 f7 0d 01 01 01 05  |..0...*.H.......|
+000002c0  00 03 81 8d 00 30 81 89  02 81 81 00 bb 79 d6 f5  |.....0.......y..|
+000002d0  17 b5 e5 bf 46 10 d0 dc  69 be e6 2b 07 43 5a d0  |....F...i..+.CZ.|
+000002e0  03 2d 8a 7a 43 85 b7 14  52 e7 a5 65 4c 2c 78 b8  |.-.zC...R..eL,x.|
+000002f0  23 8c b5 b4 82 e5 de 1f  95 3b 7e 62 a5 2c a5 33  |#........;~b.,.3|
+00000300  d6 fe 12 5c 7a 56 fc f5  06 bf fa 58 7b 26 3f b5  |...\zV.....X{&?.|
+00000310  cd 04 d3 d0 c9 21 96 4a  c7 f4 54 9f 5a bf ef 42  |.....!.J..T.Z..B|
+00000320  71 00 fe 18 99 07 7f 7e  88 7d 7d f1 04 39 c4 a2  |q......~.}}..9..|
+00000330  2e db 51 c9 7c e3 c0 4c  3b 32 66 01 cf af b1 1d  |..Q.|..L;2f.....|
+00000340  b8 71 9a 1d db db 89 6b  ae da 2d 79 02 03 01 00  |.q.....k..-y....|
+00000350  01 a3 81 a7 30 81 a4 30  1d 06 03 55 1d 0e 04 16  |....0..0...U....|
+00000360  04 14 b1 ad e2 85 5a cf  cb 28 db 69 ce 23 69 de  |......Z..(.i.#i.|
+00000370  d3 26 8e 18 88 39 30 75  06 03 55 1d 23 04 6e 30  |.&...90u..U.#.n0|
+00000380  6c 80 14 b1 ad e2 85 5a  cf cb 28 db 69 ce 23 69  |l......Z..(.i.#i|
+00000390  de d3 26 8e 18 88 39 a1  49 a4 47 30 45 31 0b 30  |..&...9.I.G0E1.0|
+000003a0  09 06 03 55 04 06 13 02  41 55 31 13 30 11 06 03  |...U....AU1.0...|
+000003b0  55 04 08 13 0a 53 6f 6d  65 2d 53 74 61 74 65 31  |U....Some-State1|
+000003c0  21 30 1f 06 03 55 04 0a  13 18 49 6e 74 65 72 6e  |!0...U....Intern|
+000003d0  65 74 20 57 69 64 67 69  74 73 20 50 74 79 20 4c  |et Widgits Pty L|
+000003e0  74 64 82 09 00 85 b0 bb  a4 8a 7f b8 ca 30 0c 06  |td...........0..|
+000003f0  03 55 1d 13 04 05 30 03  01 01 ff 30 0d 06 09 2a  |.U....0....0...*|
+00000400  86 48 86 f7 0d 01 01 05  05 00 03 81 81 00 08 6c  |.H.............l|
+00000410  45 24 c7 6b b1 59 ab 0c  52 cc f2 b0 14 d7 87 9d  |E$.k.Y..R.......|
+00000420  7a 64 75 b5 5a 95 66 e4  c5 2b 8e ae 12 66 1f eb  |zdu.Z.f..+...f..|
+00000430  4f 38 b3 6e 60 d3 92 fd  f7 41 08 b5 25 13 b1 18  |O8.n`....A..%...|
+00000440  7a 24 fb 30 1d ba ed 98  b9 17 ec e7 d7 31 59 db  |z$.0.........1Y.|
+00000450  95 d3 1d 78 ea 50 56 5c  d5 82 5a 2d 5a 5f 33 c4  |...x.PV\..Z-Z_3.|
+00000460  b6 d8 c9 75 90 96 8c 0f  52 98 b5 cd 98 1f 89 20  |...u....R...... |
+00000470  5f f2 a0 1c a3 1b 96 94  dd a9 fd 57 e9 70 e8 26  |_..........W.p.&|
+00000480  6d 71 99 9b 26 6e 38 50  29 6c 90 a7 bd d9 16 03  |mq..&n8P)l......|
+00000490  03 00 cd 0c 00 00 c9 03  00 17 41 04 d7 61 5b 05  |..........A..a[.|
+000004a0  de 22 d3 3d 00 72 a5 be  0a c1 76 94 a1 34 41 6e  |.".=.r....v..4An|
+000004b0  55 f2 74 91 d2 6f 5c 47  87 c8 4b eb ab ab 10 b9  |U.t..o\G..K.....|
+000004c0  f9 0a bc 63 03 5f 90 5b  e3 6f e1 44 97 cc bf d2  |...c._.[.o.D....|
+000004d0  e8 0d f5 9c 2e 9d 07 2c  b2 00 90 0b 04 01 00 80  |.......,........|
+000004e0  67 3d c7 73 42 b9 b2 fd  4b dd 02 57 87 95 20 75  |g=.sB...K..W.. u|
+000004f0  da c1 e7 d3 33 09 01 5d  e9 32 d7 20 7f 92 a9 dd  |....3..].2. ....|
+00000500  bb 17 c5 ee f2 07 b2 04  1d 5e 1f c2 41 66 3f 14  |.........^..Af?.|
+00000510  90 cd 84 ac 49 46 04 3e  ce 89 7d 79 42 2a 8c 56  |....IF.>..}yB*.V|
+00000520  93 d3 9c 3b 57 38 9e 91  af 62 ad 86 40 29 3d 46  |...;W8...b..@)=F|
+00000530  c7 cc f4 3f a1 7d ee 53  3d 94 1c 85 b9 1d a9 5f  |...?.}.S=......_|
+00000540  10 8e ee 38 5e 98 5d 39  31 79 83 cd f9 02 a8 a9  |...8^.]91y......|
+00000550  b8 82 21 33 40 ed 27 54  a3 6e 64 cb e9 ce dd e1  |..!3@.'T.nd.....|
+00000560  16 03 03 00 04 0e 00 00  00                       |.........|
+>>> Flow 3 (client to server)
+00000000  16 03 03 00 46 10 00 00  42 41 04 1e 18 37 ef 0d  |....F...BA...7..|
+00000010  19 51 88 35 75 71 b5 e5  54 5b 12 2e 8f 09 67 fd  |.Q.5uq..T[....g.|
+00000020  a7 24 20 3e b2 56 1c ce  97 28 5e f8 2b 2d 4f 9e  |.$ >.V...(^.+-O.|
+00000030  f1 07 9f 6c 4b 5b 83 56  e2 32 42 e9 58 b6 d7 49  |...lK[.V.2B.X..I|
+00000040  a6 b5 68 1a 41 03 56 6b  dc 5a 89 14 03 03 00 01  |..h.A.Vk.Z......|
+00000050  01 16 03 03 00 28 00 00  00 00 00 00 00 00 60 0e  |.....(........`.|
+00000060  49 99 7a 9f 28 6e 46 03  a8 fd 0e b7 ed bb 9c ba  |I.z.(nF.........|
+00000070  07 9c 4d cc 26 2b c2 70  a0 26 38 a0 f2 a0        |..M.&+.p.&8...|
+>>> Flow 4 (server to client)
+00000000  14 03 03 00 01 01 16 03  03 00 28 d2 ef 8f f4 7b  |..........(....{|
+00000010  7a 9b c8 98 a4 36 f2 be  61 46 0e af f4 6f 63 71  |z....6..aF...ocq|
+00000020  6e bd 87 ea 1b f2 95 ad  36 7d a3 52 7f b2 b6 45  |n.......6}.R...E|
+00000030  3f 0b 62                                          |?.b|
+>>> Flow 5 (client to server)
+00000000  17 03 03 00 1e 00 00 00  00 00 00 00 01 53 a1 85  |.............S..|
+00000010  ce 3c c1 64 39 80 fb db  67 ec 48 20 7f e9 82 f4  |.<.d9...g.H ....|
+00000020  2d 69 0a 15 03 03 00 1a  00 00 00 00 00 00 00 02  |-i..............|
+00000030  ab 78 11 1b 80 55 23 db  07 c5 7f c3 5e 19 d8 b3  |.x...U#.....^...|
+00000040  f8 c6                                             |..|
diff --git a/third_party/gofrontend/libgo/go/crypto/tls/testdata/Server-SSLv3-RSA-3DES b/third_party/gofrontend/libgo/go/crypto/tls/testdata/Server-SSLv3-RSA-3DES
index a6c7a41..20520f5 100644
--- a/third_party/gofrontend/libgo/go/crypto/tls/testdata/Server-SSLv3-RSA-3DES
+++ b/third_party/gofrontend/libgo/go/crypto/tls/testdata/Server-SSLv3-RSA-3DES
@@ -1,83 +1,78 @@
 >>> Flow 1 (client to server)
-00000000  16 03 00 00 2f 01 00 00  2b 03 00 52 cc 57 59 d8  |..../...+..R.WY.|
-00000010  86 d6 07 ae e0 8d 63 b7  1e cb aa c6 67 32 c8 dd  |......c.....g2..|
-00000020  68 03 d8 3d 37 18 72 c3  c0 f1 9d 00 00 04 00 0a  |h..=7.r.........|
+00000000  16 03 00 00 2f 01 00 00  2b 03 00 10 71 68 59 99  |..../...+...qhY.|
+00000010  9c a6 e7 36 8b 0d 03 be  f5 42 ab 7c d0 3b 76 3e  |...6.....B.|.;v>|
+00000020  46 7c 6c a3 94 09 b7 1b  0e 42 27 00 00 04 00 0a  |F|l......B'.....|
 00000030  00 ff 01 00                                       |....|
 >>> Flow 2 (server to client)
 00000000  16 03 00 00 31 02 00 00  2d 03 00 00 00 00 00 00  |....1...-.......|
 00000010  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
 00000020  00 00 00 00 00 00 00 00  00 00 00 00 00 0a 00 00  |................|
-00000030  05 ff 01 00 01 00 16 03  00 02 be 0b 00 02 ba 00  |................|
-00000040  02 b7 00 02 b4 30 82 02  b0 30 82 02 19 a0 03 02  |.....0...0......|
-00000050  01 02 02 09 00 85 b0 bb  a4 8a 7f b8 ca 30 0d 06  |.............0..|
-00000060  09 2a 86 48 86 f7 0d 01  01 05 05 00 30 45 31 0b  |.*.H........0E1.|
-00000070  30 09 06 03 55 04 06 13  02 41 55 31 13 30 11 06  |0...U....AU1.0..|
-00000080  03 55 04 08 13 0a 53 6f  6d 65 2d 53 74 61 74 65  |.U....Some-State|
-00000090  31 21 30 1f 06 03 55 04  0a 13 18 49 6e 74 65 72  |1!0...U....Inter|
-000000a0  6e 65 74 20 57 69 64 67  69 74 73 20 50 74 79 20  |net Widgits Pty |
-000000b0  4c 74 64 30 1e 17 0d 31  30 30 34 32 34 30 39 30  |Ltd0...100424090|
-000000c0  39 33 38 5a 17 0d 31 31  30 34 32 34 30 39 30 39  |938Z..1104240909|
-000000d0  33 38 5a 30 45 31 0b 30  09 06 03 55 04 06 13 02  |38Z0E1.0...U....|
-000000e0  41 55 31 13 30 11 06 03  55 04 08 13 0a 53 6f 6d  |AU1.0...U....Som|
-000000f0  65 2d 53 74 61 74 65 31  21 30 1f 06 03 55 04 0a  |e-State1!0...U..|
-00000100  13 18 49 6e 74 65 72 6e  65 74 20 57 69 64 67 69  |..Internet Widgi|
-00000110  74 73 20 50 74 79 20 4c  74 64 30 81 9f 30 0d 06  |ts Pty Ltd0..0..|
-00000120  09 2a 86 48 86 f7 0d 01  01 01 05 00 03 81 8d 00  |.*.H............|
-00000130  30 81 89 02 81 81 00 bb  79 d6 f5 17 b5 e5 bf 46  |0.......y......F|
-00000140  10 d0 dc 69 be e6 2b 07  43 5a d0 03 2d 8a 7a 43  |...i..+.CZ..-.zC|
-00000150  85 b7 14 52 e7 a5 65 4c  2c 78 b8 23 8c b5 b4 82  |...R..eL,x.#....|
-00000160  e5 de 1f 95 3b 7e 62 a5  2c a5 33 d6 fe 12 5c 7a  |....;~b.,.3...\z|
-00000170  56 fc f5 06 bf fa 58 7b  26 3f b5 cd 04 d3 d0 c9  |V.....X{&?......|
-00000180  21 96 4a c7 f4 54 9f 5a  bf ef 42 71 00 fe 18 99  |!.J..T.Z..Bq....|
-00000190  07 7f 7e 88 7d 7d f1 04  39 c4 a2 2e db 51 c9 7c  |..~.}}..9....Q.||
-000001a0  e3 c0 4c 3b 32 66 01 cf  af b1 1d b8 71 9a 1d db  |..L;2f......q...|
-000001b0  db 89 6b ae da 2d 79 02  03 01 00 01 a3 81 a7 30  |..k..-y........0|
-000001c0  81 a4 30 1d 06 03 55 1d  0e 04 16 04 14 b1 ad e2  |..0...U.........|
-000001d0  85 5a cf cb 28 db 69 ce  23 69 de d3 26 8e 18 88  |.Z..(.i.#i..&...|
-000001e0  39 30 75 06 03 55 1d 23  04 6e 30 6c 80 14 b1 ad  |90u..U.#.n0l....|
-000001f0  e2 85 5a cf cb 28 db 69  ce 23 69 de d3 26 8e 18  |..Z..(.i.#i..&..|
-00000200  88 39 a1 49 a4 47 30 45  31 0b 30 09 06 03 55 04  |.9.I.G0E1.0...U.|
-00000210  06 13 02 41 55 31 13 30  11 06 03 55 04 08 13 0a  |...AU1.0...U....|
-00000220  53 6f 6d 65 2d 53 74 61  74 65 31 21 30 1f 06 03  |Some-State1!0...|
-00000230  55 04 0a 13 18 49 6e 74  65 72 6e 65 74 20 57 69  |U....Internet Wi|
-00000240  64 67 69 74 73 20 50 74  79 20 4c 74 64 82 09 00  |dgits Pty Ltd...|
-00000250  85 b0 bb a4 8a 7f b8 ca  30 0c 06 03 55 1d 13 04  |........0...U...|
-00000260  05 30 03 01 01 ff 30 0d  06 09 2a 86 48 86 f7 0d  |.0....0...*.H...|
-00000270  01 01 05 05 00 03 81 81  00 08 6c 45 24 c7 6b b1  |..........lE$.k.|
-00000280  59 ab 0c 52 cc f2 b0 14  d7 87 9d 7a 64 75 b5 5a  |Y..R.......zdu.Z|
-00000290  95 66 e4 c5 2b 8e ae 12  66 1f eb 4f 38 b3 6e 60  |.f..+...f..O8.n`|
-000002a0  d3 92 fd f7 41 08 b5 25  13 b1 18 7a 24 fb 30 1d  |....A..%...z$.0.|
-000002b0  ba ed 98 b9 17 ec e7 d7  31 59 db 95 d3 1d 78 ea  |........1Y....x.|
-000002c0  50 56 5c d5 82 5a 2d 5a  5f 33 c4 b6 d8 c9 75 90  |PV\..Z-Z_3....u.|
-000002d0  96 8c 0f 52 98 b5 cd 98  1f 89 20 5f f2 a0 1c a3  |...R...... _....|
-000002e0  1b 96 94 dd a9 fd 57 e9  70 e8 26 6d 71 99 9b 26  |......W.p.&mq..&|
-000002f0  6e 38 50 29 6c 90 a7 bd  d9 16 03 00 00 04 0e 00  |n8P)l...........|
-00000300  00 00                                             |..|
+00000030  05 ff 01 00 01 00 16 03  00 02 71 0b 00 02 6d 00  |..........q...m.|
+00000040  02 6a 00 02 67 30 82 02  63 30 82 01 cc a0 03 02  |.j..g0..c0......|
+00000050  01 02 02 09 00 a2 73 00  0c 81 00 cb f3 30 0d 06  |......s......0..|
+00000060  09 2a 86 48 86 f7 0d 01  01 0b 05 00 30 2b 31 17  |.*.H........0+1.|
+00000070  30 15 06 03 55 04 0a 13  0e 47 6f 6f 67 6c 65 20  |0...U....Google |
+00000080  54 45 53 54 49 4e 47 31  10 30 0e 06 03 55 04 03  |TESTING1.0...U..|
+00000090  13 07 47 6f 20 52 6f 6f  74 30 1e 17 0d 31 35 30  |..Go Root0...150|
+000000a0  31 30 31 30 30 30 30 30  30 5a 17 0d 32 35 30 31  |101000000Z..2501|
+000000b0  30 31 30 30 30 30 30 30  5a 30 26 31 17 30 15 06  |01000000Z0&1.0..|
+000000c0  03 55 04 0a 13 0e 47 6f  6f 67 6c 65 20 54 45 53  |.U....Google TES|
+000000d0  54 49 4e 47 31 0b 30 09  06 03 55 04 03 13 02 47  |TING1.0...U....G|
+000000e0  6f 30 81 9f 30 0d 06 09  2a 86 48 86 f7 0d 01 01  |o0..0...*.H.....|
+000000f0  01 05 00 03 81 8d 00 30  81 89 02 81 81 00 af 87  |.......0........|
+00000100  88 f6 20 1b 95 65 6c 14  ab 44 05 af 3b 45 14 e3  |.. ..el..D..;E..|
+00000110  b7 6d fd 00 63 4d 95 7f  fe 6a 62 35 86 c0 4a f9  |.m..cM...jb5..J.|
+00000120  18 7c f6 aa 25 5e 7a 64  31 66 00 ba f4 8e 92 af  |.|..%^zd1f......|
+00000130  c7 6b d8 76 d4 f3 5f 41  cb 6e 56 15 97 1b 97 c1  |.k.v.._A.nV.....|
+00000140  3c 12 39 21 66 3d 2b 16  d1 bc db 1c c0 a7 da b7  |<.9!f=+.........|
+00000150  ca ad ba da cb d5 21 50  ec de 8d ab d1 6b 81 4b  |......!P.....k.K|
+00000160  89 02 f3 c4 be c1 6c 89  b1 44 84 bd 21 d1 04 7d  |......l..D..!..}|
+00000170  9d 16 4d f9 82 15 f6 ef  fa d6 09 47 f2 fb 02 03  |..M........G....|
+00000180  01 00 01 a3 81 93 30 81  90 30 0e 06 03 55 1d 0f  |......0..0...U..|
+00000190  01 01 ff 04 04 03 02 05  a0 30 1d 06 03 55 1d 25  |.........0...U.%|
+000001a0  04 16 30 14 06 08 2b 06  01 05 05 07 03 01 06 08  |..0...+.........|
+000001b0  2b 06 01 05 05 07 03 02  30 0c 06 03 55 1d 13 01  |+.......0...U...|
+000001c0  01 ff 04 02 30 00 30 19  06 03 55 1d 0e 04 12 04  |....0.0...U.....|
+000001d0  10 12 50 8d 89 6f 1b d1  dc 54 4d 6e cb 69 5e 06  |..P..o...TMn.i^.|
+000001e0  f4 30 1b 06 03 55 1d 23  04 14 30 12 80 10 bf 3d  |.0...U.#..0....=|
+000001f0  b6 a9 66 f2 b8 40 cf ea  b4 03 78 48 1a 41 30 19  |..f..@....xH.A0.|
+00000200  06 03 55 1d 11 04 12 30  10 82 0e 65 78 61 6d 70  |..U....0...examp|
+00000210  6c 65 2e 67 6f 6c 61 6e  67 30 0d 06 09 2a 86 48  |le.golang0...*.H|
+00000220  86 f7 0d 01 01 0b 05 00  03 81 81 00 92 7c af 91  |.............|..|
+00000230  55 12 18 96 59 31 a6 48  40 d5 2d d5 ee bb 02 a0  |U...Y1.H@.-.....|
+00000240  f5 c2 1e 7c 9b b3 30 7d  3c dc 76 da 4f 3d c0 fa  |...|..0}<.v.O=..|
+00000250  ae 2d 33 24 6b 03 7b 1b  67 59 11 21 b5 11 bc 77  |.-3$k.{.gY.!...w|
+00000260  b9 d9 e0 6e a8 2d 2e 35  fa 64 5f 22 3e 63 10 6b  |...n.-.5.d_">c.k|
+00000270  be ff 14 86 6d 0d f0 15  31 a8 14 38 1e 3b 84 87  |....m...1..8.;..|
+00000280  2c cb 98 ed 51 76 b9 b1  4f dd db 9b 84 04 86 40  |,...Qv..O......@|
+00000290  fa 51 dd ba b4 8d eb e3  46 de 46 b9 4f 86 c7 f9  |.Q......F.F.O...|
+000002a0  a4 c2 41 34 ac cc f6 ea  b0 ab 39 18 16 03 00 00  |..A4......9.....|
+000002b0  04 0e 00 00 00                                    |.....|
 >>> Flow 3 (client to server)
-00000000  16 03 00 00 84 10 00 00  80 75 e0 c9 76 d6 e9 34  |.........u..v..4|
-00000010  1d e3 31 9e db 3b 03 41  93 e8 db 73 7c e9 3f 6a  |..1..;.A...s|.?j|
-00000020  d8 2a 7b 25 83 4f 45 de  3f 78 3f b6 53 a7 b4 6c  |.*{%.OE.?x?.S..l|
-00000030  e3 87 c4 c3 70 55 71 79  55 dc 74 98 84 21 19 13  |....pUqyU.t..!..|
-00000040  be d5 8e 0a ff 2f 9f 7a  6b d4 6c ef 78 d1 cb 65  |...../.zk.l.x..e|
-00000050  32 4c 0c c5 29 b9 60 94  c6 79 56 a2 aa 2d d9 ad  |2L..).`..yV..-..|
-00000060  51 2c 54 1b 28 23 33 54  cd 48 cb 80 13 45 3d 4a  |Q,T.(#3T.H...E=J|
-00000070  8e 2f f2 da bd 68 3e 1b  eb 73 f9 2d 35 6b b1 40  |./...h>..s.-5k.@|
-00000080  2e 6d 9d 1c e9 c1 02 80  37 14 03 00 00 01 01 16  |.m......7.......|
-00000090  03 00 00 40 f7 c3 dd a4  64 3d 81 24 de a2 81 7d  |...@....d=.$...}|
-000000a0  e4 df 78 46 e7 ba 93 6c  36 43 05 96 fc 75 ef ec  |..xF...l6C...u..|
-000000b0  a5 46 6d 47 a5 be 74 ad  15 93 d9 87 4f 1d e2 b3  |.FmG..t.....O...|
-000000c0  03 ff 2e 89 6e 50 f4 d6  a6 e2 b3 54 cb 74 07 f7  |....nP.....T.t..|
-000000d0  ca 1b 8c 0a                                       |....|
+00000000  16 03 00 00 84 10 00 00  80 1b 62 18 c8 60 0b f7  |..........b..`..|
+00000010  4a b8 ec 98 56 eb aa 4b  d9 05 c0 f1 be b9 a5 28  |J...V..K.......(|
+00000020  62 e8 3e 25 08 9f 28 dd  08 1f 04 80 5f 10 81 cf  |b.>%..(....._...|
+00000030  aa 2f 55 cd f1 0f ec 5b  90 0a 1f 49 bc a3 96 38  |./U....[...I...8|
+00000040  c7 32 b6 0a da b3 a5 7a  76 28 82 19 30 f4 6b ae  |.2.....zv(..0.k.|
+00000050  fb 81 cc b4 ad 92 f8 c6  20 da 27 89 45 f4 43 c2  |........ .'.E.C.|
+00000060  16 7e de 29 03 dc 90 dd  3a 23 58 4c 35 be 11 a5  |.~.)....:#XL5...|
+00000070  52 18 79 13 e6 b3 2d e6  8e f5 76 60 0c c1 92 bb  |R.y...-...v`....|
+00000080  07 67 c5 24 12 1b aa d6  53 14 03 00 00 01 01 16  |.g.$....S.......|
+00000090  03 00 00 40 5f 64 da b6  24 19 07 44 32 85 f3 c0  |...@_d..$..D2...|
+000000a0  9b c6 2c ad b1 d1 0f 4b  52 20 2f ea 6f 15 80 44  |..,....KR /.o..D|
+000000b0  78 34 44 02 67 e0 2e b4  b8 df 7b 3f 21 dd 66 9b  |x4D.g.....{?!.f.|
+000000c0  e7 5f 71 ff 5f 30 fb 5b  5a 19 f0 24 f8 21 bc 7c  |._q._0.[Z..$.!.||
+000000d0  00 e1 1f e8                                       |....|
 >>> Flow 4 (server to client)
-00000000  14 03 00 00 01 01 16 03  00 00 40 6d 3d d8 d5 cf  |..........@m=...|
-00000010  05 7d 98 8c 28 28 e2 43  ab ad 4a fa ae bf ec c3  |.}..((.C..J.....|
-00000020  9c 0a 13 4d 28 a4 45 c4  b9 f2 bc c5 12 a2 68 91  |...M(.E.......h.|
-00000030  77 fa 72 f8 9e 4e b7 1f  b4 02 02 e3 5d 57 b0 8b  |w.r..N......]W..|
-00000040  d8 90 0c 9d e6 df 5b 90  92 a1 0d 17 03 00 00 18  |......[.........|
-00000050  91 48 8a e1 d6 bf 79 1c  d5 0a 70 d5 94 20 25 78  |.H....y...p.. %x|
-00000060  d8 84 c8 6e 54 f0 99 01  17 03 00 00 28 74 19 90  |...nT.......(t..|
-00000070  41 44 53 27 bb fb 1f fd  71 34 20 61 a0 eb a4 7c  |ADS'....q4 a...||
-00000080  fe 36 f8 4b d7 b0 27 d3  b9 36 e1 67 af 2d 0e 23  |.6.K..'..6.g.-.#|
-00000090  2b 76 a7 2f c3 15 03 00  00 18 db fc e9 fd 87 5f  |+v./..........._|
-000000a0  92 a8 3d 4b 35 f5 c6 48  2c b4 42 50 c3 81 28 f0  |..=K5..H,.BP..(.|
-000000b0  2b 41                                             |+A|
+00000000  14 03 00 00 01 01 16 03  00 00 40 48 01 fc 08 a0  |..........@H....|
+00000010  fa 0e 63 58 25 18 06 3c  54 5c 60 ce 35 f6 ec b8  |..cX%..<T\`.5...|
+00000020  ed f8 97 c7 b0 5f 96 6b  d1 10 53 e9 23 20 44 56  |....._.k..S.# DV|
+00000030  d7 ee 11 e1 6f b7 1e fb  33 94 7f f0 78 f5 2e 02  |....o...3...x...|
+00000040  37 7a 43 cf e7 c7 52 b3  c6 8d 8e 17 03 00 00 18  |7zC...R.........|
+00000050  f7 3c 05 79 4b 55 8c d7  2c 50 82 f0 61 34 f6 c7  |.<.yKU..,P..a4..|
+00000060  f3 71 e1 76 1d f0 65 b6  17 03 00 00 28 50 ce 6c  |.q.v..e.....(P.l|
+00000070  96 97 70 88 b7 3c 74 a9  cb a3 0e ae 3a 7f 85 99  |..p..<t.....:...|
+00000080  58 36 10 7f 1a e8 f8 7d  83 75 24 7e b1 6a 8e b0  |X6.....}.u$~.j..|
+00000090  f1 cc 06 19 f7 15 03 00  00 18 2c 1d 87 1d ce 08  |..........,.....|
+000000a0  8f 10 09 6e bd fc ad e0  1d a7 47 d5 b9 8f 3e b8  |...n......G...>.|
+000000b0  b3 fa                                             |..|
diff --git a/third_party/gofrontend/libgo/go/crypto/tls/testdata/Server-SSLv3-RSA-AES b/third_party/gofrontend/libgo/go/crypto/tls/testdata/Server-SSLv3-RSA-AES
index 4885b26..e0fe956 100644
--- a/third_party/gofrontend/libgo/go/crypto/tls/testdata/Server-SSLv3-RSA-AES
+++ b/third_party/gofrontend/libgo/go/crypto/tls/testdata/Server-SSLv3-RSA-AES
@@ -1,84 +1,79 @@
 >>> Flow 1 (client to server)
-00000000  16 03 00 00 2f 01 00 00  2b 03 00 52 cc 57 59 30  |..../...+..R.WY0|
-00000010  e1 ee 8c 60 5b 40 dd 95  bd b4 84 87 2f 01 15 e7  |...`[@....../...|
-00000020  50 88 4c 82 6b 6d 93 8a  57 d0 27 00 00 04 00 2f  |P.L.km..W.'..../|
+00000000  16 03 00 00 2f 01 00 00  2b 03 00 37 cd 49 a6 9f  |..../...+..7.I..|
+00000010  e9 19 6a 39 cd 75 ce 6c  f1 1b 96 d3 d4 f0 33 0c  |..j9.u.l......3.|
+00000020  8f 53 b2 06 c4 0e 39 86  e3 98 7e 00 00 04 00 2f  |.S....9...~..../|
 00000030  00 ff 01 00                                       |....|
 >>> Flow 2 (server to client)
 00000000  16 03 00 00 31 02 00 00  2d 03 00 00 00 00 00 00  |....1...-.......|
 00000010  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
 00000020  00 00 00 00 00 00 00 00  00 00 00 00 00 2f 00 00  |............./..|
-00000030  05 ff 01 00 01 00 16 03  00 02 be 0b 00 02 ba 00  |................|
-00000040  02 b7 00 02 b4 30 82 02  b0 30 82 02 19 a0 03 02  |.....0...0......|
-00000050  01 02 02 09 00 85 b0 bb  a4 8a 7f b8 ca 30 0d 06  |.............0..|
-00000060  09 2a 86 48 86 f7 0d 01  01 05 05 00 30 45 31 0b  |.*.H........0E1.|
-00000070  30 09 06 03 55 04 06 13  02 41 55 31 13 30 11 06  |0...U....AU1.0..|
-00000080  03 55 04 08 13 0a 53 6f  6d 65 2d 53 74 61 74 65  |.U....Some-State|
-00000090  31 21 30 1f 06 03 55 04  0a 13 18 49 6e 74 65 72  |1!0...U....Inter|
-000000a0  6e 65 74 20 57 69 64 67  69 74 73 20 50 74 79 20  |net Widgits Pty |
-000000b0  4c 74 64 30 1e 17 0d 31  30 30 34 32 34 30 39 30  |Ltd0...100424090|
-000000c0  39 33 38 5a 17 0d 31 31  30 34 32 34 30 39 30 39  |938Z..1104240909|
-000000d0  33 38 5a 30 45 31 0b 30  09 06 03 55 04 06 13 02  |38Z0E1.0...U....|
-000000e0  41 55 31 13 30 11 06 03  55 04 08 13 0a 53 6f 6d  |AU1.0...U....Som|
-000000f0  65 2d 53 74 61 74 65 31  21 30 1f 06 03 55 04 0a  |e-State1!0...U..|
-00000100  13 18 49 6e 74 65 72 6e  65 74 20 57 69 64 67 69  |..Internet Widgi|
-00000110  74 73 20 50 74 79 20 4c  74 64 30 81 9f 30 0d 06  |ts Pty Ltd0..0..|
-00000120  09 2a 86 48 86 f7 0d 01  01 01 05 00 03 81 8d 00  |.*.H............|
-00000130  30 81 89 02 81 81 00 bb  79 d6 f5 17 b5 e5 bf 46  |0.......y......F|
-00000140  10 d0 dc 69 be e6 2b 07  43 5a d0 03 2d 8a 7a 43  |...i..+.CZ..-.zC|
-00000150  85 b7 14 52 e7 a5 65 4c  2c 78 b8 23 8c b5 b4 82  |...R..eL,x.#....|
-00000160  e5 de 1f 95 3b 7e 62 a5  2c a5 33 d6 fe 12 5c 7a  |....;~b.,.3...\z|
-00000170  56 fc f5 06 bf fa 58 7b  26 3f b5 cd 04 d3 d0 c9  |V.....X{&?......|
-00000180  21 96 4a c7 f4 54 9f 5a  bf ef 42 71 00 fe 18 99  |!.J..T.Z..Bq....|
-00000190  07 7f 7e 88 7d 7d f1 04  39 c4 a2 2e db 51 c9 7c  |..~.}}..9....Q.||
-000001a0  e3 c0 4c 3b 32 66 01 cf  af b1 1d b8 71 9a 1d db  |..L;2f......q...|
-000001b0  db 89 6b ae da 2d 79 02  03 01 00 01 a3 81 a7 30  |..k..-y........0|
-000001c0  81 a4 30 1d 06 03 55 1d  0e 04 16 04 14 b1 ad e2  |..0...U.........|
-000001d0  85 5a cf cb 28 db 69 ce  23 69 de d3 26 8e 18 88  |.Z..(.i.#i..&...|
-000001e0  39 30 75 06 03 55 1d 23  04 6e 30 6c 80 14 b1 ad  |90u..U.#.n0l....|
-000001f0  e2 85 5a cf cb 28 db 69  ce 23 69 de d3 26 8e 18  |..Z..(.i.#i..&..|
-00000200  88 39 a1 49 a4 47 30 45  31 0b 30 09 06 03 55 04  |.9.I.G0E1.0...U.|
-00000210  06 13 02 41 55 31 13 30  11 06 03 55 04 08 13 0a  |...AU1.0...U....|
-00000220  53 6f 6d 65 2d 53 74 61  74 65 31 21 30 1f 06 03  |Some-State1!0...|
-00000230  55 04 0a 13 18 49 6e 74  65 72 6e 65 74 20 57 69  |U....Internet Wi|
-00000240  64 67 69 74 73 20 50 74  79 20 4c 74 64 82 09 00  |dgits Pty Ltd...|
-00000250  85 b0 bb a4 8a 7f b8 ca  30 0c 06 03 55 1d 13 04  |........0...U...|
-00000260  05 30 03 01 01 ff 30 0d  06 09 2a 86 48 86 f7 0d  |.0....0...*.H...|
-00000270  01 01 05 05 00 03 81 81  00 08 6c 45 24 c7 6b b1  |..........lE$.k.|
-00000280  59 ab 0c 52 cc f2 b0 14  d7 87 9d 7a 64 75 b5 5a  |Y..R.......zdu.Z|
-00000290  95 66 e4 c5 2b 8e ae 12  66 1f eb 4f 38 b3 6e 60  |.f..+...f..O8.n`|
-000002a0  d3 92 fd f7 41 08 b5 25  13 b1 18 7a 24 fb 30 1d  |....A..%...z$.0.|
-000002b0  ba ed 98 b9 17 ec e7 d7  31 59 db 95 d3 1d 78 ea  |........1Y....x.|
-000002c0  50 56 5c d5 82 5a 2d 5a  5f 33 c4 b6 d8 c9 75 90  |PV\..Z-Z_3....u.|
-000002d0  96 8c 0f 52 98 b5 cd 98  1f 89 20 5f f2 a0 1c a3  |...R...... _....|
-000002e0  1b 96 94 dd a9 fd 57 e9  70 e8 26 6d 71 99 9b 26  |......W.p.&mq..&|
-000002f0  6e 38 50 29 6c 90 a7 bd  d9 16 03 00 00 04 0e 00  |n8P)l...........|
-00000300  00 00                                             |..|
+00000030  05 ff 01 00 01 00 16 03  00 02 71 0b 00 02 6d 00  |..........q...m.|
+00000040  02 6a 00 02 67 30 82 02  63 30 82 01 cc a0 03 02  |.j..g0..c0......|
+00000050  01 02 02 09 00 a2 73 00  0c 81 00 cb f3 30 0d 06  |......s......0..|
+00000060  09 2a 86 48 86 f7 0d 01  01 0b 05 00 30 2b 31 17  |.*.H........0+1.|
+00000070  30 15 06 03 55 04 0a 13  0e 47 6f 6f 67 6c 65 20  |0...U....Google |
+00000080  54 45 53 54 49 4e 47 31  10 30 0e 06 03 55 04 03  |TESTING1.0...U..|
+00000090  13 07 47 6f 20 52 6f 6f  74 30 1e 17 0d 31 35 30  |..Go Root0...150|
+000000a0  31 30 31 30 30 30 30 30  30 5a 17 0d 32 35 30 31  |101000000Z..2501|
+000000b0  30 31 30 30 30 30 30 30  5a 30 26 31 17 30 15 06  |01000000Z0&1.0..|
+000000c0  03 55 04 0a 13 0e 47 6f  6f 67 6c 65 20 54 45 53  |.U....Google TES|
+000000d0  54 49 4e 47 31 0b 30 09  06 03 55 04 03 13 02 47  |TING1.0...U....G|
+000000e0  6f 30 81 9f 30 0d 06 09  2a 86 48 86 f7 0d 01 01  |o0..0...*.H.....|
+000000f0  01 05 00 03 81 8d 00 30  81 89 02 81 81 00 af 87  |.......0........|
+00000100  88 f6 20 1b 95 65 6c 14  ab 44 05 af 3b 45 14 e3  |.. ..el..D..;E..|
+00000110  b7 6d fd 00 63 4d 95 7f  fe 6a 62 35 86 c0 4a f9  |.m..cM...jb5..J.|
+00000120  18 7c f6 aa 25 5e 7a 64  31 66 00 ba f4 8e 92 af  |.|..%^zd1f......|
+00000130  c7 6b d8 76 d4 f3 5f 41  cb 6e 56 15 97 1b 97 c1  |.k.v.._A.nV.....|
+00000140  3c 12 39 21 66 3d 2b 16  d1 bc db 1c c0 a7 da b7  |<.9!f=+.........|
+00000150  ca ad ba da cb d5 21 50  ec de 8d ab d1 6b 81 4b  |......!P.....k.K|
+00000160  89 02 f3 c4 be c1 6c 89  b1 44 84 bd 21 d1 04 7d  |......l..D..!..}|
+00000170  9d 16 4d f9 82 15 f6 ef  fa d6 09 47 f2 fb 02 03  |..M........G....|
+00000180  01 00 01 a3 81 93 30 81  90 30 0e 06 03 55 1d 0f  |......0..0...U..|
+00000190  01 01 ff 04 04 03 02 05  a0 30 1d 06 03 55 1d 25  |.........0...U.%|
+000001a0  04 16 30 14 06 08 2b 06  01 05 05 07 03 01 06 08  |..0...+.........|
+000001b0  2b 06 01 05 05 07 03 02  30 0c 06 03 55 1d 13 01  |+.......0...U...|
+000001c0  01 ff 04 02 30 00 30 19  06 03 55 1d 0e 04 12 04  |....0.0...U.....|
+000001d0  10 12 50 8d 89 6f 1b d1  dc 54 4d 6e cb 69 5e 06  |..P..o...TMn.i^.|
+000001e0  f4 30 1b 06 03 55 1d 23  04 14 30 12 80 10 bf 3d  |.0...U.#..0....=|
+000001f0  b6 a9 66 f2 b8 40 cf ea  b4 03 78 48 1a 41 30 19  |..f..@....xH.A0.|
+00000200  06 03 55 1d 11 04 12 30  10 82 0e 65 78 61 6d 70  |..U....0...examp|
+00000210  6c 65 2e 67 6f 6c 61 6e  67 30 0d 06 09 2a 86 48  |le.golang0...*.H|
+00000220  86 f7 0d 01 01 0b 05 00  03 81 81 00 92 7c af 91  |.............|..|
+00000230  55 12 18 96 59 31 a6 48  40 d5 2d d5 ee bb 02 a0  |U...Y1.H@.-.....|
+00000240  f5 c2 1e 7c 9b b3 30 7d  3c dc 76 da 4f 3d c0 fa  |...|..0}<.v.O=..|
+00000250  ae 2d 33 24 6b 03 7b 1b  67 59 11 21 b5 11 bc 77  |.-3$k.{.gY.!...w|
+00000260  b9 d9 e0 6e a8 2d 2e 35  fa 64 5f 22 3e 63 10 6b  |...n.-.5.d_">c.k|
+00000270  be ff 14 86 6d 0d f0 15  31 a8 14 38 1e 3b 84 87  |....m...1..8.;..|
+00000280  2c cb 98 ed 51 76 b9 b1  4f dd db 9b 84 04 86 40  |,...Qv..O......@|
+00000290  fa 51 dd ba b4 8d eb e3  46 de 46 b9 4f 86 c7 f9  |.Q......F.F.O...|
+000002a0  a4 c2 41 34 ac cc f6 ea  b0 ab 39 18 16 03 00 00  |..A4......9.....|
+000002b0  04 0e 00 00 00                                    |.....|
 >>> Flow 3 (client to server)
-00000000  16 03 00 00 84 10 00 00  80 74 50 05 6f f5 83 c9  |.........tP.o...|
-00000010  f5 0c 5a 65 c7 4e c6 f3  87 96 d7 5d 3e 88 27 32  |..Ze.N.....]>.'2|
-00000020  89 12 ba ec db ef c0 85  70 84 ed b6 83 03 8f 44  |........p......D|
-00000030  f5 6f fa fa d0 1f 95 30  d1 ae a7 71 cf ee e9 b1  |.o.....0...q....|
-00000040  80 7b 34 a9 ea 1b 5e e5  71 40 3f e8 7d 30 d1 8b  |.{4...^.q@?.}0..|
-00000050  11 f1 68 1f c8 25 f0 77  c5 af b3 92 6e d9 81 cc  |..h..%.w....n...|
-00000060  f8 fd 82 95 cc 1f 4a b1  05 15 7a b3 a1 22 33 09  |......J...z.."3.|
-00000070  e7 a5 c2 89 7f 03 e0 91  b6 61 a3 a0 4e 17 0d 7a  |.........a..N..z|
-00000080  13 01 c4 b6 50 c7 d9 81  15 14 03 00 00 01 01 16  |....P...........|
-00000090  03 00 00 40 56 da 56 ab  e6 26 98 58 53 1f 36 b5  |...@V.V..&.XS.6.|
-000000a0  03 14 bd 42 29 ee 9c 7c  e4 48 26 82 68 ae fd fe  |...B)..|.H&.h...|
-000000b0  5e a4 43 22 75 95 7b c8  77 88 fd d6 d4 9b c9 b5  |^.C"u.{.w.......|
-000000c0  ee 3e a6 e8 c5 04 90 63  3f ac be 56 67 da 30 d4  |.>.....c?..Vg.0.|
-000000d0  64 fb a8 a0                                       |d...|
+00000000  16 03 00 00 84 10 00 00  80 4d 3f 93 aa 84 d8 ad  |.........M?.....|
+00000010  93 2c 63 02 66 2f 96 88  b8 5c 09 1e 63 e2 e5 96  |.,c.f/...\..c...|
+00000020  26 d8 07 14 86 26 62 f4  0c 04 68 1c bf bb b1 53  |&....&b...h....S|
+00000030  97 96 43 59 4a 57 65 12  88 45 34 2b 86 2b 05 aa  |..CYJWe..E4+.+..|
+00000040  9b 2b b9 aa 13 30 5c 91  c0 9f 03 8a 96 61 dd 87  |.+...0\......a..|
+00000050  ae e3 ad 6a 7b 8a 18 23  67 c9 df ad f2 47 eb 8b  |...j{..#g....G..|
+00000060  7d 24 95 47 f1 4e b5 c6  15 b4 12 2a 42 df b3 99  |}$.G.N.....*B...|
+00000070  d1 b8 60 ce 6a cf 98 c1  13 a1 68 e6 92 ee 92 a2  |..`.j.....h.....|
+00000080  1d 2f 63 66 f3 b9 1b fc  33 14 03 00 00 01 01 16  |./cf....3.......|
+00000090  03 00 00 40 75 48 68 7d  8f f5 5a c0 cb 90 a5 9e  |...@uHh}..Z.....|
+000000a0  94 bb eb 61 b5 36 aa ce  09 7a 11 ba 22 56 2a d7  |...a.6...z.."V*.|
+000000b0  91 a3 99 73 5b c5 b2 b7  b9 92 56 c6 cb fe 13 73  |...s[.....V....s|
+000000c0  28 30 03 26 62 63 7e 8a  d2 58 c8 e7 52 03 26 67  |(0.&bc~..X..R.&g|
+000000d0  48 21 4f 21                                       |H!O!|
 >>> Flow 4 (server to client)
-00000000  14 03 00 00 01 01 16 03  00 00 40 96 af fb 79 96  |..........@...y.|
-00000010  92 97 2d d0 67 46 1e 08  b5 35 65 ef dc bc 8e 57  |..-.gF...5e....W|
-00000020  53 b7 36 58 74 d7 88 b1  55 fc eb fa 2e f3 17 b7  |S.6Xt...U.......|
-00000030  62 58 a0 9d 99 e1 85 d4  33 e0 b4 1f 1d 94 f2 88  |bX......3.......|
-00000040  d5 9a 34 5b 74 cd d2 ff  87 bd 52 17 03 00 00 20  |..4[t.....R.... |
-00000050  c6 61 c2 28 ac d2 0c 08  7f f1 c2 62 af 37 7e 78  |.a.(.......b.7~x|
-00000060  e8 e2 a1 54 f2 3a 80 97  f8 47 64 f2 cd 94 dd 0b  |...T.:...Gd.....|
-00000070  17 03 00 00 30 b8 40 8f  a3 18 ff 03 84 d4 1c 28  |....0.@........(|
-00000080  82 ce d8 9a 81 3a dd 23  7c 65 d8 ca f7 f1 46 1b  |.....:.#|e....F.|
-00000090  70 f0 d7 d9 54 a7 71 e6  4d d4 25 61 5a e4 30 d3  |p...T.q.M.%aZ.0.|
-000000a0  4a 42 ae 26 a5 15 03 00  00 20 c4 e8 ed 40 57 00  |JB.&..... ...@W.|
-000000b0  dc a5 0e 82 90 47 92 08  dd 7e 50 6b 30 66 5e 90  |.....G...~Pk0f^.|
-000000c0  73 7c 81 93 8d 24 b1 06  e7 39                    |s|...$...9|
+00000000  14 03 00 00 01 01 16 03  00 00 40 84 8f 6e 80 35  |..........@..n.5|
+00000010  57 73 64 ef 29 bb 25 ff  5d 9d c7 55 38 b7 18 b3  |Wsd.).%.]..U8...|
+00000020  13 d1 ac 20 e0 1e f8 48  47 7a 40 2d bc a7 f2 af  |... ...HGz@-....|
+00000030  ed a6 26 48 f4 51 b4 b6  56 60 9b c3 d9 43 00 95  |..&H.Q..V`...C..|
+00000040  86 be 6c 4e 49 6b f9 10  99 51 22 17 03 00 00 20  |..lNIk...Q".... |
+00000050  d4 7e dc 50 7b c2 26 ee  79 09 84 9f d7 e0 52 b1  |.~.P{.&.y.....R.|
+00000060  e8 9c 92 30 b7 34 06 c6  e5 86 57 a1 fb 8d 06 d6  |...0.4....W.....|
+00000070  17 03 00 00 30 93 0a 3d  64 26 3d a2 74 bc 8f d1  |....0..=d&=.t...|
+00000080  16 38 d0 6b 62 eb 82 b0  9a 50 68 aa 7e f7 45 32  |.8.kb....Ph.~.E2|
+00000090  43 cb 84 2d 95 39 6c bc  c8 a0 2d aa ea fe f5 84  |C..-.9l...-.....|
+000000a0  c8 e4 8b 93 a1 15 03 00  00 20 03 7b 3e 43 1d 0a  |......... .{>C..|
+000000b0  9b 9b e3 17 0f de be 75  e5 6e 2f 5b e8 8d a8 68  |.......u.n/[...h|
+000000c0  4e f0 82 49 00 dd b6 95  b4 22                    |N..I....."|
diff --git a/third_party/gofrontend/libgo/go/crypto/tls/testdata/Server-SSLv3-RSA-RC4 b/third_party/gofrontend/libgo/go/crypto/tls/testdata/Server-SSLv3-RSA-RC4
index 1314b65..39124c6 100644
--- a/third_party/gofrontend/libgo/go/crypto/tls/testdata/Server-SSLv3-RSA-RC4
+++ b/third_party/gofrontend/libgo/go/crypto/tls/testdata/Server-SSLv3-RSA-RC4
@@ -1,79 +1,74 @@
 >>> Flow 1 (client to server)
-00000000  16 03 00 00 2f 01 00 00  2b 03 00 52 cc 57 59 79  |..../...+..R.WYy|
-00000010  b9 3b ef df 53 fb 09 f6  01 e5 18 0a fc 3d 65 bb  |.;..S........=e.|
-00000020  cf 9c 4c 77 b1 e8 6b 4f  5f c7 94 00 00 04 00 05  |..Lw..kO_.......|
+00000000  16 03 00 00 2f 01 00 00  2b 03 00 a7 1d 3d ed 0f  |..../...+....=..|
+00000010  2c 7b 1f f1 c8 1c a9 17  ce 69 e2 73 a2 07 d2 91  |,{.......i.s....|
+00000020  e9 27 fa 70 11 6f 18 6d  2a 25 f1 00 00 04 00 05  |.'.p.o.m*%......|
 00000030  00 ff 01 00                                       |....|
 >>> Flow 2 (server to client)
 00000000  16 03 00 00 31 02 00 00  2d 03 00 00 00 00 00 00  |....1...-.......|
 00000010  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
 00000020  00 00 00 00 00 00 00 00  00 00 00 00 00 05 00 00  |................|
-00000030  05 ff 01 00 01 00 16 03  00 02 be 0b 00 02 ba 00  |................|
-00000040  02 b7 00 02 b4 30 82 02  b0 30 82 02 19 a0 03 02  |.....0...0......|
-00000050  01 02 02 09 00 85 b0 bb  a4 8a 7f b8 ca 30 0d 06  |.............0..|
-00000060  09 2a 86 48 86 f7 0d 01  01 05 05 00 30 45 31 0b  |.*.H........0E1.|
-00000070  30 09 06 03 55 04 06 13  02 41 55 31 13 30 11 06  |0...U....AU1.0..|
-00000080  03 55 04 08 13 0a 53 6f  6d 65 2d 53 74 61 74 65  |.U....Some-State|
-00000090  31 21 30 1f 06 03 55 04  0a 13 18 49 6e 74 65 72  |1!0...U....Inter|
-000000a0  6e 65 74 20 57 69 64 67  69 74 73 20 50 74 79 20  |net Widgits Pty |
-000000b0  4c 74 64 30 1e 17 0d 31  30 30 34 32 34 30 39 30  |Ltd0...100424090|
-000000c0  39 33 38 5a 17 0d 31 31  30 34 32 34 30 39 30 39  |938Z..1104240909|
-000000d0  33 38 5a 30 45 31 0b 30  09 06 03 55 04 06 13 02  |38Z0E1.0...U....|
-000000e0  41 55 31 13 30 11 06 03  55 04 08 13 0a 53 6f 6d  |AU1.0...U....Som|
-000000f0  65 2d 53 74 61 74 65 31  21 30 1f 06 03 55 04 0a  |e-State1!0...U..|
-00000100  13 18 49 6e 74 65 72 6e  65 74 20 57 69 64 67 69  |..Internet Widgi|
-00000110  74 73 20 50 74 79 20 4c  74 64 30 81 9f 30 0d 06  |ts Pty Ltd0..0..|
-00000120  09 2a 86 48 86 f7 0d 01  01 01 05 00 03 81 8d 00  |.*.H............|
-00000130  30 81 89 02 81 81 00 bb  79 d6 f5 17 b5 e5 bf 46  |0.......y......F|
-00000140  10 d0 dc 69 be e6 2b 07  43 5a d0 03 2d 8a 7a 43  |...i..+.CZ..-.zC|
-00000150  85 b7 14 52 e7 a5 65 4c  2c 78 b8 23 8c b5 b4 82  |...R..eL,x.#....|
-00000160  e5 de 1f 95 3b 7e 62 a5  2c a5 33 d6 fe 12 5c 7a  |....;~b.,.3...\z|
-00000170  56 fc f5 06 bf fa 58 7b  26 3f b5 cd 04 d3 d0 c9  |V.....X{&?......|
-00000180  21 96 4a c7 f4 54 9f 5a  bf ef 42 71 00 fe 18 99  |!.J..T.Z..Bq....|
-00000190  07 7f 7e 88 7d 7d f1 04  39 c4 a2 2e db 51 c9 7c  |..~.}}..9....Q.||
-000001a0  e3 c0 4c 3b 32 66 01 cf  af b1 1d b8 71 9a 1d db  |..L;2f......q...|
-000001b0  db 89 6b ae da 2d 79 02  03 01 00 01 a3 81 a7 30  |..k..-y........0|
-000001c0  81 a4 30 1d 06 03 55 1d  0e 04 16 04 14 b1 ad e2  |..0...U.........|
-000001d0  85 5a cf cb 28 db 69 ce  23 69 de d3 26 8e 18 88  |.Z..(.i.#i..&...|
-000001e0  39 30 75 06 03 55 1d 23  04 6e 30 6c 80 14 b1 ad  |90u..U.#.n0l....|
-000001f0  e2 85 5a cf cb 28 db 69  ce 23 69 de d3 26 8e 18  |..Z..(.i.#i..&..|
-00000200  88 39 a1 49 a4 47 30 45  31 0b 30 09 06 03 55 04  |.9.I.G0E1.0...U.|
-00000210  06 13 02 41 55 31 13 30  11 06 03 55 04 08 13 0a  |...AU1.0...U....|
-00000220  53 6f 6d 65 2d 53 74 61  74 65 31 21 30 1f 06 03  |Some-State1!0...|
-00000230  55 04 0a 13 18 49 6e 74  65 72 6e 65 74 20 57 69  |U....Internet Wi|
-00000240  64 67 69 74 73 20 50 74  79 20 4c 74 64 82 09 00  |dgits Pty Ltd...|
-00000250  85 b0 bb a4 8a 7f b8 ca  30 0c 06 03 55 1d 13 04  |........0...U...|
-00000260  05 30 03 01 01 ff 30 0d  06 09 2a 86 48 86 f7 0d  |.0....0...*.H...|
-00000270  01 01 05 05 00 03 81 81  00 08 6c 45 24 c7 6b b1  |..........lE$.k.|
-00000280  59 ab 0c 52 cc f2 b0 14  d7 87 9d 7a 64 75 b5 5a  |Y..R.......zdu.Z|
-00000290  95 66 e4 c5 2b 8e ae 12  66 1f eb 4f 38 b3 6e 60  |.f..+...f..O8.n`|
-000002a0  d3 92 fd f7 41 08 b5 25  13 b1 18 7a 24 fb 30 1d  |....A..%...z$.0.|
-000002b0  ba ed 98 b9 17 ec e7 d7  31 59 db 95 d3 1d 78 ea  |........1Y....x.|
-000002c0  50 56 5c d5 82 5a 2d 5a  5f 33 c4 b6 d8 c9 75 90  |PV\..Z-Z_3....u.|
-000002d0  96 8c 0f 52 98 b5 cd 98  1f 89 20 5f f2 a0 1c a3  |...R...... _....|
-000002e0  1b 96 94 dd a9 fd 57 e9  70 e8 26 6d 71 99 9b 26  |......W.p.&mq..&|
-000002f0  6e 38 50 29 6c 90 a7 bd  d9 16 03 00 00 04 0e 00  |n8P)l...........|
-00000300  00 00                                             |..|
+00000030  05 ff 01 00 01 00 16 03  00 02 71 0b 00 02 6d 00  |..........q...m.|
+00000040  02 6a 00 02 67 30 82 02  63 30 82 01 cc a0 03 02  |.j..g0..c0......|
+00000050  01 02 02 09 00 a2 73 00  0c 81 00 cb f3 30 0d 06  |......s......0..|
+00000060  09 2a 86 48 86 f7 0d 01  01 0b 05 00 30 2b 31 17  |.*.H........0+1.|
+00000070  30 15 06 03 55 04 0a 13  0e 47 6f 6f 67 6c 65 20  |0...U....Google |
+00000080  54 45 53 54 49 4e 47 31  10 30 0e 06 03 55 04 03  |TESTING1.0...U..|
+00000090  13 07 47 6f 20 52 6f 6f  74 30 1e 17 0d 31 35 30  |..Go Root0...150|
+000000a0  31 30 31 30 30 30 30 30  30 5a 17 0d 32 35 30 31  |101000000Z..2501|
+000000b0  30 31 30 30 30 30 30 30  5a 30 26 31 17 30 15 06  |01000000Z0&1.0..|
+000000c0  03 55 04 0a 13 0e 47 6f  6f 67 6c 65 20 54 45 53  |.U....Google TES|
+000000d0  54 49 4e 47 31 0b 30 09  06 03 55 04 03 13 02 47  |TING1.0...U....G|
+000000e0  6f 30 81 9f 30 0d 06 09  2a 86 48 86 f7 0d 01 01  |o0..0...*.H.....|
+000000f0  01 05 00 03 81 8d 00 30  81 89 02 81 81 00 af 87  |.......0........|
+00000100  88 f6 20 1b 95 65 6c 14  ab 44 05 af 3b 45 14 e3  |.. ..el..D..;E..|
+00000110  b7 6d fd 00 63 4d 95 7f  fe 6a 62 35 86 c0 4a f9  |.m..cM...jb5..J.|
+00000120  18 7c f6 aa 25 5e 7a 64  31 66 00 ba f4 8e 92 af  |.|..%^zd1f......|
+00000130  c7 6b d8 76 d4 f3 5f 41  cb 6e 56 15 97 1b 97 c1  |.k.v.._A.nV.....|
+00000140  3c 12 39 21 66 3d 2b 16  d1 bc db 1c c0 a7 da b7  |<.9!f=+.........|
+00000150  ca ad ba da cb d5 21 50  ec de 8d ab d1 6b 81 4b  |......!P.....k.K|
+00000160  89 02 f3 c4 be c1 6c 89  b1 44 84 bd 21 d1 04 7d  |......l..D..!..}|
+00000170  9d 16 4d f9 82 15 f6 ef  fa d6 09 47 f2 fb 02 03  |..M........G....|
+00000180  01 00 01 a3 81 93 30 81  90 30 0e 06 03 55 1d 0f  |......0..0...U..|
+00000190  01 01 ff 04 04 03 02 05  a0 30 1d 06 03 55 1d 25  |.........0...U.%|
+000001a0  04 16 30 14 06 08 2b 06  01 05 05 07 03 01 06 08  |..0...+.........|
+000001b0  2b 06 01 05 05 07 03 02  30 0c 06 03 55 1d 13 01  |+.......0...U...|
+000001c0  01 ff 04 02 30 00 30 19  06 03 55 1d 0e 04 12 04  |....0.0...U.....|
+000001d0  10 12 50 8d 89 6f 1b d1  dc 54 4d 6e cb 69 5e 06  |..P..o...TMn.i^.|
+000001e0  f4 30 1b 06 03 55 1d 23  04 14 30 12 80 10 bf 3d  |.0...U.#..0....=|
+000001f0  b6 a9 66 f2 b8 40 cf ea  b4 03 78 48 1a 41 30 19  |..f..@....xH.A0.|
+00000200  06 03 55 1d 11 04 12 30  10 82 0e 65 78 61 6d 70  |..U....0...examp|
+00000210  6c 65 2e 67 6f 6c 61 6e  67 30 0d 06 09 2a 86 48  |le.golang0...*.H|
+00000220  86 f7 0d 01 01 0b 05 00  03 81 81 00 92 7c af 91  |.............|..|
+00000230  55 12 18 96 59 31 a6 48  40 d5 2d d5 ee bb 02 a0  |U...Y1.H@.-.....|
+00000240  f5 c2 1e 7c 9b b3 30 7d  3c dc 76 da 4f 3d c0 fa  |...|..0}<.v.O=..|
+00000250  ae 2d 33 24 6b 03 7b 1b  67 59 11 21 b5 11 bc 77  |.-3$k.{.gY.!...w|
+00000260  b9 d9 e0 6e a8 2d 2e 35  fa 64 5f 22 3e 63 10 6b  |...n.-.5.d_">c.k|
+00000270  be ff 14 86 6d 0d f0 15  31 a8 14 38 1e 3b 84 87  |....m...1..8.;..|
+00000280  2c cb 98 ed 51 76 b9 b1  4f dd db 9b 84 04 86 40  |,...Qv..O......@|
+00000290  fa 51 dd ba b4 8d eb e3  46 de 46 b9 4f 86 c7 f9  |.Q......F.F.O...|
+000002a0  a4 c2 41 34 ac cc f6 ea  b0 ab 39 18 16 03 00 00  |..A4......9.....|
+000002b0  04 0e 00 00 00                                    |.....|
 >>> Flow 3 (client to server)
-00000000  16 03 00 00 84 10 00 00  80 4d 66 7a f3 f8 ab 86  |.........Mfz....|
-00000010  43 4c 5f 7c 52 ca e7 3f  ba 62 b3 82 88 16 7d ca  |CL_|R..?.b....}.|
-00000020  3a 66 15 c0 36 55 2c ab  bf 30 6b cd 9c d8 b9 48  |:f..6U,..0k....H|
-00000030  03 c9 d0 98 ab 0b a6 5b  39 c8 fe 82 8e bb f0 16  |.......[9.......|
-00000040  6f 96 62 81 f2 dc 52 02  c9 de e4 47 73 21 6e 1e  |o.b...R....Gs!n.|
-00000050  3a 11 89 7a e2 6b 9e 04  64 72 15 ba 2d 10 a2 69  |:..z.k..dr..-..i|
-00000060  07 e6 ba 17 cf 54 d6 4e  5f 99 e8 59 8b 54 ce 8e  |.....T.N_..Y.T..|
-00000070  6b 58 ba 83 68 46 4a 5f  43 3e 9b e1 32 a2 19 42  |kX..hFJ_C>..2..B|
-00000080  46 0f e4 47 1a 3b 16 5f  e1 14 03 00 00 01 01 16  |F..G.;._........|
-00000090  03 00 00 3c 78 7e ee da  0d 38 0b 1a d6 d4 8e d5  |...<x~...8......|
-000000a0  6a c5 3a 0f 85 e7 37 a6  3c 8d 1e 4b da 02 94 bf  |j.:...7.<..K....|
-000000b0  ae 2c 50 3b 4e 1c 0c 3c  4f cc d5 1c da 33 13 43  |.,P;N..<O....3.C|
-000000c0  37 64 44 ac 26 43 28 0b  d0 c2 04 09 b5 0f 23 1d  |7dD.&C(.......#.|
+00000000  16 03 00 00 84 10 00 00  80 25 85 a3 22 29 e4 fb  |.........%..")..|
+00000010  53 b9 a3 6b ed 70 2b 35  7f db 08 35 b8 4c 95 cd  |S..k.p+5...5.L..|
+00000020  00 ec 5e a1 2e ba e9 ac  a6 d4 ef ca 74 a0 12 1b  |..^.........t...|
+00000030  a7 ec 76 22 2c 63 71 1a  3a 50 94 ce 96 c4 d7 76  |..v",cq.:P.....v|
+00000040  1f 47 58 c7 57 98 af ea  7e 57 05 68 d3 f9 87 02  |.GX.W...~W.h....|
+00000050  35 72 35 66 08 b4 cf 48  24 15 92 d5 ba 46 8d 60  |5r5f...H$....F.`|
+00000060  5a 53 0b e4 9b 53 44 55  dc 77 d1 e4 e0 25 51 f6  |ZS...SDU.w...%Q.|
+00000070  f1 7c 96 0b 32 d4 8c 04  d3 3d e6 70 c7 d6 60 a7  |.|..2....=.p..`.|
+00000080  ae 69 22 69 41 1a 8d 12  67 14 03 00 00 01 01 16  |.i"iA...g.......|
+00000090  03 00 00 3c 32 dd 86 fd  5b 53 74 ea 01 45 5b 9e  |...<2...[St..E[.|
+000000a0  32 d0 9d 27 e8 ce 4c d5  a1 c2 d3 2e 0a e9 e5 d2  |2..'..L.........|
+000000b0  04 8c 77 a3 ff e9 8b 02  14 16 af 54 db ec c4 98  |..w........T....|
+000000c0  72 50 f7 65 fa eb ac 11  07 81 d7 fa 4e 18 34 bc  |rP.e........N.4.|
 >>> Flow 4 (server to client)
-00000000  14 03 00 00 01 01 16 03  00 00 3c 23 29 64 62 23  |..........<#)db#|
-00000010  19 20 f8 2e 15 07 ee c8  f4 ab f0 3e 66 c3 ed 7b  |. .........>f..{|
-00000020  7c a7 c2 7e c3 25 3c 8f  f3 04 dc 37 e8 fc 0a 1d  ||..~.%<....7....|
-00000030  fa 7a 09 d4 21 11 e3 24  21 4b 37 d1 85 cc 40 bf  |.z..!..$!K7...@.|
-00000040  bd bd f8 59 6b cd 73 17  03 00 00 21 47 1d ac 54  |...Yk.s....!G..T|
-00000050  bd 58 a6 c0 04 e2 0c 6b  66 64 5a 85 09 0e 47 fc  |.X.....kfdZ...G.|
-00000060  0b 57 ee f1 24 b6 89 57  46 be 6b 0d f2 15 03 00  |.W..$..WF.k.....|
-00000070  00 16 b4 f7 34 99 19 43  b6 b3 5a 8b c3 d2 67 2f  |....4..C..Z...g/|
-00000080  3b 19 1c 31 d4 f9 bd 96                           |;..1....|
+00000000  14 03 00 00 01 01 16 03  00 00 3c 29 af 2c 96 3a  |..........<).,.:|
+00000010  be a0 91 a8 e4 66 6b 30  ba e2 80 fc a2 8a 09 b4  |.....fk0........|
+00000020  28 14 3b 36 c2 3b 3e 88  e2 10 da 93 af 71 9a 06  |(.;6.;>......q..|
+00000030  1c 8d 97 04 05 ec e2 69  cf 28 20 0f ec 4c a7 f3  |.......i.( ..L..|
+00000040  18 4e 6b 5b 88 9c a9 17  03 00 00 21 5e 0b b4 2d  |.Nk[.......!^..-|
+00000050  a6 b5 0b 3a 86 de 8a e7  87 f3 4c f6 74 7e 0d 16  |...:......L.t~..|
+00000060  9b fc 0c 42 6b f4 9e 15  8b 6a c5 97 88 15 03 00  |...Bk....j......|
+00000070  00 16 f0 a4 e2 16 bf 81  05 ad 1d f5 1c 89 d9 ab  |................|
+00000080  48 23 ab 96 ea 92 aa cd                           |H#......|
diff --git a/third_party/gofrontend/libgo/go/crypto/tls/testdata/Server-TLSv10-ECDHE-ECDSA-AES b/third_party/gofrontend/libgo/go/crypto/tls/testdata/Server-TLSv10-ECDHE-ECDSA-AES
index 9b8cb4d..f81ffc2 100644
--- a/third_party/gofrontend/libgo/go/crypto/tls/testdata/Server-TLSv10-ECDHE-ECDSA-AES
+++ b/third_party/gofrontend/libgo/go/crypto/tls/testdata/Server-TLSv10-ECDHE-ECDSA-AES
@@ -1,12 +1,13 @@
 >>> Flow 1 (client to server)
-00000000  16 03 01 00 76 01 00 00  72 03 01 53 04 f0 f9 4b  |....v...r..S...K|
-00000010  30 a8 68 d0 79 13 14 69  ee 3b 5d 05 cb 71 63 43  |0.h.y..i.;]..qcC|
-00000020  4a 55 6b 05 25 53 19 ba  e0 2f b1 00 00 04 c0 0a  |JUk.%S.../......|
-00000030  00 ff 01 00 00 45 00 0b  00 04 03 00 01 02 00 0a  |.....E..........|
-00000040  00 34 00 32 00 0e 00 0d  00 19 00 0b 00 0c 00 18  |.4.2............|
-00000050  00 09 00 0a 00 16 00 17  00 08 00 06 00 07 00 14  |................|
-00000060  00 15 00 04 00 05 00 12  00 13 00 01 00 02 00 03  |................|
-00000070  00 0f 00 10 00 11 00 0f  00 01 01                 |...........|
+00000000  16 03 01 00 7d 01 00 00  79 03 01 65 14 3f 40 e4  |....}...y..e.?@.|
+00000010  2f 74 65 7e d0 c8 87 03  59 61 9d c3 84 5e c9 62  |/te~....Ya...^.b|
+00000020  e6 46 b8 0c 4a 5e 3f 33  43 a5 dd 00 00 04 c0 0a  |.F..J^?3C.......|
+00000030  00 ff 02 01 00 00 4b 00  0b 00 04 03 00 01 02 00  |......K.........|
+00000040  0a 00 3a 00 38 00 0e 00  0d 00 19 00 1c 00 0b 00  |..:.8...........|
+00000050  0c 00 1b 00 18 00 09 00  0a 00 1a 00 16 00 17 00  |................|
+00000060  08 00 06 00 07 00 14 00  15 00 04 00 05 00 12 00  |................|
+00000070  13 00 01 00 02 00 03 00  0f 00 10 00 11 00 0f 00  |................|
+00000080  01 01                                             |..|
 >>> Flow 2 (server to client)
 00000000  16 03 01 00 31 02 00 00  2d 03 01 00 00 00 00 00  |....1...-.......|
 00000010  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
@@ -49,36 +50,36 @@
 00000260  75 71 b5 e5 54 5b 12 2e  8f 09 67 fd a7 24 20 3e  |uq..T[....g..$ >|
 00000270  b2 56 1c ce 97 28 5e f8  2b 2d 4f 9e f1 07 9f 6c  |.V...(^.+-O....l|
 00000280  4b 5b 83 56 e2 32 42 e9  58 b6 d7 49 a6 b5 68 1a  |K[.V.2B.X..I..h.|
-00000290  41 03 56 6b dc 5a 89 00  8b 30 81 88 02 42 00 c6  |A.Vk.Z...0...B..|
-000002a0  85 8e 06 b7 04 04 e9 cd  9e 3e cb 66 23 95 b4 42  |.........>.f#..B|
-000002b0  9c 64 81 39 05 3f b5 21  f8 28 af 60 6b 4d 3d ba  |.d.9.?.!.(.`kM=.|
-000002c0  a1 4b 5e 77 ef e7 59 28  fe 1d c1 27 a2 ff a8 de  |.K^w..Y(...'....|
-000002d0  33 48 b3 c1 85 6a 42 9b  f9 7e 7e 31 c2 e5 bd 66  |3H...jB..~~1...f|
-000002e0  02 42 00 ad 7d 06 35 ab  ec 8d ac d4 ba 1b 49 5e  |.B..}.5.......I^|
-000002f0  05 5f f0 97 93 82 b8 2b  8d 91 98 63 8e b4 14 62  |._.....+...c...b|
-00000300  db 1e c9 2b 30 f8 41 9b  a6 e6 bc de 0e 68 30 21  |...+0.A......h0!|
-00000310  d8 ef 2f 05 42 da f2 e0  2c 06 33 1d 0d 9a 1a 75  |../.B...,.3....u|
-00000320  59 a7 3a bc 16 03 01 00  04 0e 00 00 00           |Y.:..........|
+00000290  41 03 56 6b dc 5a 89 00  8b 30 81 88 02 42 01 3e  |A.Vk.Z...0...B.>|
+000002a0  79 81 6e 89 cd 3e 3f ec  e4 b5 75 17 28 ee fb 09  |y.n..>?...u.(...|
+000002b0  21 19 6f 3c e6 ca 1e f2  18 b6 47 f8 37 05 1c 85  |!.o<......G.7...|
+000002c0  0f a4 b8 6b 40 04 50 77  e3 05 9b 24 b8 93 e8 4d  |...k@.Pw...$...M|
+000002d0  ef 30 cd 51 90 58 a2 49  71 b3 3f b9 46 ab a9 72  |.0.Q.X.Iq.?.F..r|
+000002e0  02 42 01 58 ef 20 c1 0a  33 f8 fd 50 9e 65 f5 ef  |.B.X. ..3..P.e..|
+000002f0  f4 91 49 2d d2 de 66 2b  97 69 7d b1 d0 ef d6 91  |..I-..f+.i}.....|
+00000300  0f fc 57 2b 73 b9 49 01  33 d2 1b 5b 9a 2c 51 35  |..W+s.I.3..[.,Q5|
+00000310  0e eb 38 53 fa 20 07 84  52 b3 43 24 09 5a 32 c0  |..8S. ..R.C$.Z2.|
+00000320  32 17 34 6c 16 03 01 00  04 0e 00 00 00           |2.4l.........|
 >>> Flow 3 (client to server)
-00000000  16 03 01 00 46 10 00 00  42 41 04 08 28 cf bd 3c  |....F...BA..(..<|
-00000010  3c cc 98 9e 73 3f 92 a7  cb 22 83 3b c7 61 46 0e  |<...s?...".;.aF.|
-00000020  4d 7c 30 b5 06 85 2f 01  be b5 40 e2 64 1e 45 c1  |M|0.../...@.d.E.|
-00000030  9d 73 95 d5 65 92 0b 9b  e7 6f c6 91 ab b6 fa be  |.s..e....o......|
-00000040  61 83 a7 f2 eb f5 65 31  fe 24 7b 14 03 01 00 01  |a.....e1.${.....|
-00000050  01 16 03 01 00 30 15 d1  c4 ca 0b 01 84 13 5a ba  |.....0........Z.|
-00000060  89 04 87 73 7c bb d8 89  7e 10 27 ba 6f 5d dc d3  |...s|...~.'.o]..|
-00000070  b5 ef 32 86 58 cc fb eb  5c 32 9e 95 ef 01 1c ac  |..2.X...\2......|
-00000080  dc 8e df 7f fe 0a                                 |......|
+00000000  16 03 01 00 46 10 00 00  42 41 04 31 74 f8 f6 18  |....F...BA.1t...|
+00000010  55 6a 9b 3b 78 0a 0e f0  c9 91 aa 8e 77 39 0a 88  |Uj.;x.......w9..|
+00000020  a4 d4 f6 04 9d de 89 18  b6 50 12 72 26 9c 8f e1  |.........P.r&...|
+00000030  f0 b2 e6 df ce 3b 46 be  e9 2a 9a e3 7f d1 d5 92  |.....;F..*......|
+00000040  ff e3 ae 0a 2d a1 3b 07  f6 04 59 14 03 01 00 01  |....-.;...Y.....|
+00000050  01 16 03 01 00 30 02 4f  df 41 30 97 6f f7 18 ca  |.....0.O.A0.o...|
+00000060  05 35 17 a1 a2 a5 71 61  b1 d8 dd 9a c6 f3 54 53  |.5....qa......TS|
+00000070  84 f6 fb 93 1e 0e 9d e7  fe 35 85 9e 73 d0 2e a1  |.........5..s...|
+00000080  a7 63 d9 40 c6 ac                                 |.c.@..|
 >>> Flow 4 (server to client)
-00000000  14 03 01 00 01 01 16 03  01 00 30 e8 48 86 81 3c  |..........0.H..<|
-00000010  f5 25 5c 94 a9 06 c4 5c  71 62 b1 43 76 ec 2c 44  |.%\....\qb.Cv.,D|
-00000020  95 b5 8c 95 d2 ff 82 92  b6 fc 52 75 03 c6 a1 f0  |..........Ru....|
-00000030  99 6d b1 ed ec 68 6c d7  9f 18 50 17 03 01 00 20  |.m...hl...P.... |
-00000040  32 d9 26 8a 81 b8 9d a5  7b fd d5 4e 7a db 2e 29  |2.&.....{..Nz..)|
-00000050  58 9a 4f 6a 27 18 bc dc  c2 49 b8 65 cb 8e 16 5a  |X.Oj'....I.e...Z|
-00000060  17 03 01 00 30 c4 56 0a  ad 9a 82 cb 3e 32 f1 7c  |....0.V.....>2.||
-00000070  95 6e dd cd e9 4d f0 e5  2d c9 a3 f7 de bb d7 fd  |.n...M..-.......|
-00000080  84 bb df 34 8c 64 1f 03  58 64 19 4a 5b 7a a8 81  |...4.d..Xd.J[z..|
-00000090  52 bb 51 0a 43 15 03 01  00 20 89 18 7a 40 ec 49  |R.Q.C.... ..z@.I|
-000000a0  52 d5 d3 20 ac 07 eb e9  4a 78 23 cf e7 21 32 74  |R.. ....Jx#..!2t|
-000000b0  ec 40 8d a8 f4 33 1c ae  93 cf                    |.@...3....|
+00000000  14 03 01 00 01 01 16 03  01 00 30 07 7e 4e 9c 19  |..........0.~N..|
+00000010  f0 35 cd 02 b7 a6 0a 1a  b1 a8 11 a3 f9 b1 35 7b  |.5............5{|
+00000020  96 7f e6 e1 00 c6 6d 9e  e6 8a bb a2 b8 bd a3 9d  |......m.........|
+00000030  05 22 1b f1 f5 28 4a 00  6e f1 71 17 03 01 00 20  |."...(J.n.q.... |
+00000040  ad c7 4c dc f4 81 1a 39  3d 86 5e 8e f5 0d a3 33  |..L....9=.^....3|
+00000050  88 32 e7 be 8b 6a 8d 44  29 7b 47 fd e5 33 01 1e  |.2...j.D){G..3..|
+00000060  17 03 01 00 30 61 47 ee  ae 89 25 ac 85 3b 8a 84  |....0aG...%..;..|
+00000070  47 61 ea 3e 4c 70 57 07  d6 f1 1c 21 cb 44 7e de  |Ga.>LpW....!.D~.|
+00000080  b5 01 9e fb fe ad bc be  74 c0 65 a0 6b c1 0c 8c  |........t.e.k...|
+00000090  2b 00 24 c6 b7 15 03 01  00 20 b7 8b 6b e5 77 ab  |+.$...... ..k.w.|
+000000a0  f6 50 9e 88 4d 56 a8 25  8d 02 db cb 68 8b 3f 62  |.P..MV.%....h.?b|
+000000b0  be aa 02 24 75 b1 e5 4b  18 c9                    |...$u..K..|
diff --git a/third_party/gofrontend/libgo/go/crypto/tls/testdata/Server-TLSv10-RSA-3DES b/third_party/gofrontend/libgo/go/crypto/tls/testdata/Server-TLSv10-RSA-3DES
index c0e6241..55cb487 100644
--- a/third_party/gofrontend/libgo/go/crypto/tls/testdata/Server-TLSv10-RSA-3DES
+++ b/third_party/gofrontend/libgo/go/crypto/tls/testdata/Server-TLSv10-RSA-3DES
@@ -1,79 +1,74 @@
 >>> Flow 1 (client to server)
-00000000  16 03 01 00 36 01 00 00  32 03 01 52 cc 57 59 13  |....6...2..R.WY.|
-00000010  8b e6 5b a3 1d cb 94 ef  48 e4 59 7e 20 6d 07 67  |..[.....H.Y~ m.g|
-00000020  1e 28 6d 31 a2 e7 96 b3  7d 32 cc 00 00 04 00 0a  |.(m1....}2......|
+00000000  16 03 01 00 36 01 00 00  32 03 01 35 4a e8 32 84  |....6...2..5J.2.|
+00000010  51 68 04 7e d0 0f 43 94  c7 5d 44 d2 95 a3 12 63  |Qh.~..C..]D....c|
+00000020  77 c5 ce 78 5a 25 a3 81  df c4 6b 00 00 04 00 0a  |w..xZ%....k.....|
 00000030  00 ff 01 00 00 05 00 0f  00 01 01                 |...........|
 >>> Flow 2 (server to client)
 00000000  16 03 01 00 31 02 00 00  2d 03 01 00 00 00 00 00  |....1...-.......|
 00000010  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
 00000020  00 00 00 00 00 00 00 00  00 00 00 00 00 0a 00 00  |................|
-00000030  05 ff 01 00 01 00 16 03  01 02 be 0b 00 02 ba 00  |................|
-00000040  02 b7 00 02 b4 30 82 02  b0 30 82 02 19 a0 03 02  |.....0...0......|
-00000050  01 02 02 09 00 85 b0 bb  a4 8a 7f b8 ca 30 0d 06  |.............0..|
-00000060  09 2a 86 48 86 f7 0d 01  01 05 05 00 30 45 31 0b  |.*.H........0E1.|
-00000070  30 09 06 03 55 04 06 13  02 41 55 31 13 30 11 06  |0...U....AU1.0..|
-00000080  03 55 04 08 13 0a 53 6f  6d 65 2d 53 74 61 74 65  |.U....Some-State|
-00000090  31 21 30 1f 06 03 55 04  0a 13 18 49 6e 74 65 72  |1!0...U....Inter|
-000000a0  6e 65 74 20 57 69 64 67  69 74 73 20 50 74 79 20  |net Widgits Pty |
-000000b0  4c 74 64 30 1e 17 0d 31  30 30 34 32 34 30 39 30  |Ltd0...100424090|
-000000c0  39 33 38 5a 17 0d 31 31  30 34 32 34 30 39 30 39  |938Z..1104240909|
-000000d0  33 38 5a 30 45 31 0b 30  09 06 03 55 04 06 13 02  |38Z0E1.0...U....|
-000000e0  41 55 31 13 30 11 06 03  55 04 08 13 0a 53 6f 6d  |AU1.0...U....Som|
-000000f0  65 2d 53 74 61 74 65 31  21 30 1f 06 03 55 04 0a  |e-State1!0...U..|
-00000100  13 18 49 6e 74 65 72 6e  65 74 20 57 69 64 67 69  |..Internet Widgi|
-00000110  74 73 20 50 74 79 20 4c  74 64 30 81 9f 30 0d 06  |ts Pty Ltd0..0..|
-00000120  09 2a 86 48 86 f7 0d 01  01 01 05 00 03 81 8d 00  |.*.H............|
-00000130  30 81 89 02 81 81 00 bb  79 d6 f5 17 b5 e5 bf 46  |0.......y......F|
-00000140  10 d0 dc 69 be e6 2b 07  43 5a d0 03 2d 8a 7a 43  |...i..+.CZ..-.zC|
-00000150  85 b7 14 52 e7 a5 65 4c  2c 78 b8 23 8c b5 b4 82  |...R..eL,x.#....|
-00000160  e5 de 1f 95 3b 7e 62 a5  2c a5 33 d6 fe 12 5c 7a  |....;~b.,.3...\z|
-00000170  56 fc f5 06 bf fa 58 7b  26 3f b5 cd 04 d3 d0 c9  |V.....X{&?......|
-00000180  21 96 4a c7 f4 54 9f 5a  bf ef 42 71 00 fe 18 99  |!.J..T.Z..Bq....|
-00000190  07 7f 7e 88 7d 7d f1 04  39 c4 a2 2e db 51 c9 7c  |..~.}}..9....Q.||
-000001a0  e3 c0 4c 3b 32 66 01 cf  af b1 1d b8 71 9a 1d db  |..L;2f......q...|
-000001b0  db 89 6b ae da 2d 79 02  03 01 00 01 a3 81 a7 30  |..k..-y........0|
-000001c0  81 a4 30 1d 06 03 55 1d  0e 04 16 04 14 b1 ad e2  |..0...U.........|
-000001d0  85 5a cf cb 28 db 69 ce  23 69 de d3 26 8e 18 88  |.Z..(.i.#i..&...|
-000001e0  39 30 75 06 03 55 1d 23  04 6e 30 6c 80 14 b1 ad  |90u..U.#.n0l....|
-000001f0  e2 85 5a cf cb 28 db 69  ce 23 69 de d3 26 8e 18  |..Z..(.i.#i..&..|
-00000200  88 39 a1 49 a4 47 30 45  31 0b 30 09 06 03 55 04  |.9.I.G0E1.0...U.|
-00000210  06 13 02 41 55 31 13 30  11 06 03 55 04 08 13 0a  |...AU1.0...U....|
-00000220  53 6f 6d 65 2d 53 74 61  74 65 31 21 30 1f 06 03  |Some-State1!0...|
-00000230  55 04 0a 13 18 49 6e 74  65 72 6e 65 74 20 57 69  |U....Internet Wi|
-00000240  64 67 69 74 73 20 50 74  79 20 4c 74 64 82 09 00  |dgits Pty Ltd...|
-00000250  85 b0 bb a4 8a 7f b8 ca  30 0c 06 03 55 1d 13 04  |........0...U...|
-00000260  05 30 03 01 01 ff 30 0d  06 09 2a 86 48 86 f7 0d  |.0....0...*.H...|
-00000270  01 01 05 05 00 03 81 81  00 08 6c 45 24 c7 6b b1  |..........lE$.k.|
-00000280  59 ab 0c 52 cc f2 b0 14  d7 87 9d 7a 64 75 b5 5a  |Y..R.......zdu.Z|
-00000290  95 66 e4 c5 2b 8e ae 12  66 1f eb 4f 38 b3 6e 60  |.f..+...f..O8.n`|
-000002a0  d3 92 fd f7 41 08 b5 25  13 b1 18 7a 24 fb 30 1d  |....A..%...z$.0.|
-000002b0  ba ed 98 b9 17 ec e7 d7  31 59 db 95 d3 1d 78 ea  |........1Y....x.|
-000002c0  50 56 5c d5 82 5a 2d 5a  5f 33 c4 b6 d8 c9 75 90  |PV\..Z-Z_3....u.|
-000002d0  96 8c 0f 52 98 b5 cd 98  1f 89 20 5f f2 a0 1c a3  |...R...... _....|
-000002e0  1b 96 94 dd a9 fd 57 e9  70 e8 26 6d 71 99 9b 26  |......W.p.&mq..&|
-000002f0  6e 38 50 29 6c 90 a7 bd  d9 16 03 01 00 04 0e 00  |n8P)l...........|
-00000300  00 00                                             |..|
+00000030  05 ff 01 00 01 00 16 03  01 02 71 0b 00 02 6d 00  |..........q...m.|
+00000040  02 6a 00 02 67 30 82 02  63 30 82 01 cc a0 03 02  |.j..g0..c0......|
+00000050  01 02 02 09 00 a2 73 00  0c 81 00 cb f3 30 0d 06  |......s......0..|
+00000060  09 2a 86 48 86 f7 0d 01  01 0b 05 00 30 2b 31 17  |.*.H........0+1.|
+00000070  30 15 06 03 55 04 0a 13  0e 47 6f 6f 67 6c 65 20  |0...U....Google |
+00000080  54 45 53 54 49 4e 47 31  10 30 0e 06 03 55 04 03  |TESTING1.0...U..|
+00000090  13 07 47 6f 20 52 6f 6f  74 30 1e 17 0d 31 35 30  |..Go Root0...150|
+000000a0  31 30 31 30 30 30 30 30  30 5a 17 0d 32 35 30 31  |101000000Z..2501|
+000000b0  30 31 30 30 30 30 30 30  5a 30 26 31 17 30 15 06  |01000000Z0&1.0..|
+000000c0  03 55 04 0a 13 0e 47 6f  6f 67 6c 65 20 54 45 53  |.U....Google TES|
+000000d0  54 49 4e 47 31 0b 30 09  06 03 55 04 03 13 02 47  |TING1.0...U....G|
+000000e0  6f 30 81 9f 30 0d 06 09  2a 86 48 86 f7 0d 01 01  |o0..0...*.H.....|
+000000f0  01 05 00 03 81 8d 00 30  81 89 02 81 81 00 af 87  |.......0........|
+00000100  88 f6 20 1b 95 65 6c 14  ab 44 05 af 3b 45 14 e3  |.. ..el..D..;E..|
+00000110  b7 6d fd 00 63 4d 95 7f  fe 6a 62 35 86 c0 4a f9  |.m..cM...jb5..J.|
+00000120  18 7c f6 aa 25 5e 7a 64  31 66 00 ba f4 8e 92 af  |.|..%^zd1f......|
+00000130  c7 6b d8 76 d4 f3 5f 41  cb 6e 56 15 97 1b 97 c1  |.k.v.._A.nV.....|
+00000140  3c 12 39 21 66 3d 2b 16  d1 bc db 1c c0 a7 da b7  |<.9!f=+.........|
+00000150  ca ad ba da cb d5 21 50  ec de 8d ab d1 6b 81 4b  |......!P.....k.K|
+00000160  89 02 f3 c4 be c1 6c 89  b1 44 84 bd 21 d1 04 7d  |......l..D..!..}|
+00000170  9d 16 4d f9 82 15 f6 ef  fa d6 09 47 f2 fb 02 03  |..M........G....|
+00000180  01 00 01 a3 81 93 30 81  90 30 0e 06 03 55 1d 0f  |......0..0...U..|
+00000190  01 01 ff 04 04 03 02 05  a0 30 1d 06 03 55 1d 25  |.........0...U.%|
+000001a0  04 16 30 14 06 08 2b 06  01 05 05 07 03 01 06 08  |..0...+.........|
+000001b0  2b 06 01 05 05 07 03 02  30 0c 06 03 55 1d 13 01  |+.......0...U...|
+000001c0  01 ff 04 02 30 00 30 19  06 03 55 1d 0e 04 12 04  |....0.0...U.....|
+000001d0  10 12 50 8d 89 6f 1b d1  dc 54 4d 6e cb 69 5e 06  |..P..o...TMn.i^.|
+000001e0  f4 30 1b 06 03 55 1d 23  04 14 30 12 80 10 bf 3d  |.0...U.#..0....=|
+000001f0  b6 a9 66 f2 b8 40 cf ea  b4 03 78 48 1a 41 30 19  |..f..@....xH.A0.|
+00000200  06 03 55 1d 11 04 12 30  10 82 0e 65 78 61 6d 70  |..U....0...examp|
+00000210  6c 65 2e 67 6f 6c 61 6e  67 30 0d 06 09 2a 86 48  |le.golang0...*.H|
+00000220  86 f7 0d 01 01 0b 05 00  03 81 81 00 92 7c af 91  |.............|..|
+00000230  55 12 18 96 59 31 a6 48  40 d5 2d d5 ee bb 02 a0  |U...Y1.H@.-.....|
+00000240  f5 c2 1e 7c 9b b3 30 7d  3c dc 76 da 4f 3d c0 fa  |...|..0}<.v.O=..|
+00000250  ae 2d 33 24 6b 03 7b 1b  67 59 11 21 b5 11 bc 77  |.-3$k.{.gY.!...w|
+00000260  b9 d9 e0 6e a8 2d 2e 35  fa 64 5f 22 3e 63 10 6b  |...n.-.5.d_">c.k|
+00000270  be ff 14 86 6d 0d f0 15  31 a8 14 38 1e 3b 84 87  |....m...1..8.;..|
+00000280  2c cb 98 ed 51 76 b9 b1  4f dd db 9b 84 04 86 40  |,...Qv..O......@|
+00000290  fa 51 dd ba b4 8d eb e3  46 de 46 b9 4f 86 c7 f9  |.Q......F.F.O...|
+000002a0  a4 c2 41 34 ac cc f6 ea  b0 ab 39 18 16 03 01 00  |..A4......9.....|
+000002b0  04 0e 00 00 00                                    |.....|
 >>> Flow 3 (client to server)
-00000000  16 03 01 00 86 10 00 00  82 00 80 2e af d2 61 f6  |..............a.|
-00000010  e2 b8 24 da 28 17 55 99  fd 11 bd 7a ab 98 dd f2  |..$.(.U....z....|
-00000020  f6 5f e0 11 6b 12 61 6f  86 48 b2 6e db f0 dd d5  |._..k.ao.H.n....|
-00000030  07 88 e5 95 f4 2d 6b 0c  d0 09 1a 5e 5f 50 1f dc  |.....-k....^_P..|
-00000040  f2 e7 02 7d 5e a0 70 29  80 ef 87 aa cc 95 3f 2e  |...}^.p)......?.|
-00000050  24 d1 40 b6 62 53 1d 25  31 87 1e 2f 77 d3 e1 1c  |$.@.bS.%1../w...|
-00000060  c4 99 89 bc 99 09 e9 ad  1f ce 09 e6 36 1c 3e 97  |............6.>.|
-00000070  be 62 69 a0 4e 14 20 9c  82 2a 3e fc 7e 9b c4 7a  |.bi.N. ..*>.~..z|
-00000080  5a f7 ad 1a 03 17 2a f8  7a 5f 44 14 03 01 00 01  |Z.....*.z_D.....|
-00000090  01 16 03 01 00 28 49 6b  da 73 07 ad 85 9a 0e fb  |.....(Ik.s......|
-000000a0  dd e0 69 ef c9 22 2d 86  91 51 26 63 d0 24 7d 16  |..i.."-..Q&c.$}.|
-000000b0  3c db 9b 00 c9 7e 64 e2  69 02 85 7d f7 47        |<....~d.i..}.G|
+00000000  16 03 01 00 86 10 00 00  82 00 80 1f 4d 12 64 f2  |............M.d.|
+00000010  72 22 86 4a 16 05 3f d2  1b e5 ed a7 f1 19 c4 6d  |r".J..?........m|
+00000020  1d 3a 5c f6 46 8f b9 4d  9e c4 d4 19 95 0a 63 9f  |.:\.F..M......c.|
+00000030  8a 41 1f fc d5 98 45 ca  69 33 37 64 d5 c8 0e 5a  |.A....E.i37d...Z|
+00000040  12 9f 06 54 8a 61 8b 13  f0 d8 fb b9 97 fb cd 1d  |...T.a..........|
+00000050  bd 6c 88 cc 98 57 c3 66  3a 86 04 c9 b9 21 c6 f2  |.l...W.f:....!..|
+00000060  f3 43 7d 4e bf 28 d5 a2  d7 39 e0 78 cb eb b4 af  |.C}N.(...9.x....|
+00000070  21 0e ae 4c 16 9b b3 49  5f 81 02 55 59 97 d9 d2  |!..L...I_..UY...|
+00000080  c4 e2 4c be 0a a6 41 62  48 1d 66 14 03 01 00 01  |..L...AbH.f.....|
+00000090  01 16 03 01 00 28 9d e0  c3 31 82 c2 48 5d fb 47  |.....(...1..H].G|
+000000a0  85 60 d4 17 d2 4f 4d 3c  64 db e4 49 1f a9 66 93  |.`...OM<d..I..f.|
+000000b0  72 6c 32 06 a5 0c 1f db  64 6d 54 71 fd 30        |rl2.....dmTq.0|
 >>> Flow 4 (server to client)
-00000000  14 03 01 00 01 01 16 03  01 00 28 dc 60 83 43 6c  |..........(.`.Cl|
-00000010  37 79 ab 6e 92 1f 66 d0  b1 12 ce c1 64 9d 2b 68  |7y.n..f.....d.+h|
-00000020  c7 1a e5 1f 8c 80 08 d2  86 3e a1 2c e3 7e f4 64  |.........>.,.~.d|
-00000030  e7 96 b2 17 03 01 00 18  8d b5 7c 03 78 cf dc 09  |..........|.x...|
-00000040  95 06 4b a6 82 f9 30 d2  6b 26 cb 0a 9a 9d 47 9f  |..K...0.k&....G.|
-00000050  17 03 01 00 28 30 a9 55  dd b9 4d 6a 76 00 39 96  |....(0.U..Mjv.9.|
-00000060  a3 94 6a df e5 af 1e a2  eb bb e4 ac 95 2c f7 93  |..j..........,..|
-00000070  ef d1 b5 13 d8 e2 06 1a  ad 5c 00 dd 0c 15 03 01  |.........\......|
-00000080  00 18 a5 62 e4 8b 51 1d  28 46 bc 8a c8 50 a3 32  |...b..Q.(F...P.2|
-00000090  6b 7b f1 b6 19 43 63 1f  7d 38                    |k{...Cc.}8|
+00000000  14 03 01 00 01 01 16 03  01 00 28 94 66 8f ad 8f  |..........(.f...|
+00000010  9f 00 72 f6 af 51 47 67  63 df 3f dd 17 09 0a c5  |..r..QGgc.?.....|
+00000020  bf f8 4d 66 39 f9 b5 47  01 f8 e8 6d ed b4 17 39  |..Mf9..G...m...9|
+00000030  ff 0a ca 17 03 01 00 18  68 93 94 51 12 b9 17 0b  |........h..Q....|
+00000040  d1 a0 22 fc cc c4 76 1a  1e 02 c6 20 5e 74 83 4c  |.."...v.... ^t.L|
+00000050  17 03 01 00 28 08 bd 86  07 84 90 78 bd 1d 90 ce  |....(......x....|
+00000060  09 80 bb d8 de fd 39 82  4b c4 0d 06 f3 65 f5 5b  |......9.K....e.[|
+00000070  3d c3 fd 69 80 1f 51 ce  1d 98 f1 05 fa 15 03 01  |=..i..Q.........|
+00000080  00 18 ed 48 04 21 85 77  d7 b6 29 e3 25 af ea ec  |...H.!.w..).%...|
+00000090  3e 41 82 a0 ca 7d 44 79  8a 0b                    |>A...}Dy..|
diff --git a/third_party/gofrontend/libgo/go/crypto/tls/testdata/Server-TLSv10-RSA-AES b/third_party/gofrontend/libgo/go/crypto/tls/testdata/Server-TLSv10-RSA-AES
index 1670997..4671302 100644
--- a/third_party/gofrontend/libgo/go/crypto/tls/testdata/Server-TLSv10-RSA-AES
+++ b/third_party/gofrontend/libgo/go/crypto/tls/testdata/Server-TLSv10-RSA-AES
@@ -1,82 +1,77 @@
 >>> Flow 1 (client to server)
-00000000  16 03 01 00 36 01 00 00  32 03 01 52 cc 57 59 5d  |....6...2..R.WY]|
-00000010  0d 77 24 3e b3 32 3d ba  0f b0 aa 1d e3 13 06 f6  |.w$>.2=.........|
-00000020  0f be 3c 92 ba 93 bd a6  6d 69 53 00 00 04 00 2f  |..<.....miS..../|
+00000000  16 03 01 00 36 01 00 00  32 03 01 8c 5a 87 31 6a  |....6...2...Z.1j|
+00000010  8c 7a d5 26 4b 94 17 27  fc a2 c0 5f b5 bc 3f 10  |.z.&K..'..._..?.|
+00000020  80 0e e0 1e 36 80 4b 91  61 77 d4 00 00 04 00 2f  |....6.K.aw...../|
 00000030  00 ff 01 00 00 05 00 0f  00 01 01                 |...........|
 >>> Flow 2 (server to client)
 00000000  16 03 01 00 31 02 00 00  2d 03 01 00 00 00 00 00  |....1...-.......|
 00000010  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
 00000020  00 00 00 00 00 00 00 00  00 00 00 00 00 2f 00 00  |............./..|
-00000030  05 ff 01 00 01 00 16 03  01 02 be 0b 00 02 ba 00  |................|
-00000040  02 b7 00 02 b4 30 82 02  b0 30 82 02 19 a0 03 02  |.....0...0......|
-00000050  01 02 02 09 00 85 b0 bb  a4 8a 7f b8 ca 30 0d 06  |.............0..|
-00000060  09 2a 86 48 86 f7 0d 01  01 05 05 00 30 45 31 0b  |.*.H........0E1.|
-00000070  30 09 06 03 55 04 06 13  02 41 55 31 13 30 11 06  |0...U....AU1.0..|
-00000080  03 55 04 08 13 0a 53 6f  6d 65 2d 53 74 61 74 65  |.U....Some-State|
-00000090  31 21 30 1f 06 03 55 04  0a 13 18 49 6e 74 65 72  |1!0...U....Inter|
-000000a0  6e 65 74 20 57 69 64 67  69 74 73 20 50 74 79 20  |net Widgits Pty |
-000000b0  4c 74 64 30 1e 17 0d 31  30 30 34 32 34 30 39 30  |Ltd0...100424090|
-000000c0  39 33 38 5a 17 0d 31 31  30 34 32 34 30 39 30 39  |938Z..1104240909|
-000000d0  33 38 5a 30 45 31 0b 30  09 06 03 55 04 06 13 02  |38Z0E1.0...U....|
-000000e0  41 55 31 13 30 11 06 03  55 04 08 13 0a 53 6f 6d  |AU1.0...U....Som|
-000000f0  65 2d 53 74 61 74 65 31  21 30 1f 06 03 55 04 0a  |e-State1!0...U..|
-00000100  13 18 49 6e 74 65 72 6e  65 74 20 57 69 64 67 69  |..Internet Widgi|
-00000110  74 73 20 50 74 79 20 4c  74 64 30 81 9f 30 0d 06  |ts Pty Ltd0..0..|
-00000120  09 2a 86 48 86 f7 0d 01  01 01 05 00 03 81 8d 00  |.*.H............|
-00000130  30 81 89 02 81 81 00 bb  79 d6 f5 17 b5 e5 bf 46  |0.......y......F|
-00000140  10 d0 dc 69 be e6 2b 07  43 5a d0 03 2d 8a 7a 43  |...i..+.CZ..-.zC|
-00000150  85 b7 14 52 e7 a5 65 4c  2c 78 b8 23 8c b5 b4 82  |...R..eL,x.#....|
-00000160  e5 de 1f 95 3b 7e 62 a5  2c a5 33 d6 fe 12 5c 7a  |....;~b.,.3...\z|
-00000170  56 fc f5 06 bf fa 58 7b  26 3f b5 cd 04 d3 d0 c9  |V.....X{&?......|
-00000180  21 96 4a c7 f4 54 9f 5a  bf ef 42 71 00 fe 18 99  |!.J..T.Z..Bq....|
-00000190  07 7f 7e 88 7d 7d f1 04  39 c4 a2 2e db 51 c9 7c  |..~.}}..9....Q.||
-000001a0  e3 c0 4c 3b 32 66 01 cf  af b1 1d b8 71 9a 1d db  |..L;2f......q...|
-000001b0  db 89 6b ae da 2d 79 02  03 01 00 01 a3 81 a7 30  |..k..-y........0|
-000001c0  81 a4 30 1d 06 03 55 1d  0e 04 16 04 14 b1 ad e2  |..0...U.........|
-000001d0  85 5a cf cb 28 db 69 ce  23 69 de d3 26 8e 18 88  |.Z..(.i.#i..&...|
-000001e0  39 30 75 06 03 55 1d 23  04 6e 30 6c 80 14 b1 ad  |90u..U.#.n0l....|
-000001f0  e2 85 5a cf cb 28 db 69  ce 23 69 de d3 26 8e 18  |..Z..(.i.#i..&..|
-00000200  88 39 a1 49 a4 47 30 45  31 0b 30 09 06 03 55 04  |.9.I.G0E1.0...U.|
-00000210  06 13 02 41 55 31 13 30  11 06 03 55 04 08 13 0a  |...AU1.0...U....|
-00000220  53 6f 6d 65 2d 53 74 61  74 65 31 21 30 1f 06 03  |Some-State1!0...|
-00000230  55 04 0a 13 18 49 6e 74  65 72 6e 65 74 20 57 69  |U....Internet Wi|
-00000240  64 67 69 74 73 20 50 74  79 20 4c 74 64 82 09 00  |dgits Pty Ltd...|
-00000250  85 b0 bb a4 8a 7f b8 ca  30 0c 06 03 55 1d 13 04  |........0...U...|
-00000260  05 30 03 01 01 ff 30 0d  06 09 2a 86 48 86 f7 0d  |.0....0...*.H...|
-00000270  01 01 05 05 00 03 81 81  00 08 6c 45 24 c7 6b b1  |..........lE$.k.|
-00000280  59 ab 0c 52 cc f2 b0 14  d7 87 9d 7a 64 75 b5 5a  |Y..R.......zdu.Z|
-00000290  95 66 e4 c5 2b 8e ae 12  66 1f eb 4f 38 b3 6e 60  |.f..+...f..O8.n`|
-000002a0  d3 92 fd f7 41 08 b5 25  13 b1 18 7a 24 fb 30 1d  |....A..%...z$.0.|
-000002b0  ba ed 98 b9 17 ec e7 d7  31 59 db 95 d3 1d 78 ea  |........1Y....x.|
-000002c0  50 56 5c d5 82 5a 2d 5a  5f 33 c4 b6 d8 c9 75 90  |PV\..Z-Z_3....u.|
-000002d0  96 8c 0f 52 98 b5 cd 98  1f 89 20 5f f2 a0 1c a3  |...R...... _....|
-000002e0  1b 96 94 dd a9 fd 57 e9  70 e8 26 6d 71 99 9b 26  |......W.p.&mq..&|
-000002f0  6e 38 50 29 6c 90 a7 bd  d9 16 03 01 00 04 0e 00  |n8P)l...........|
-00000300  00 00                                             |..|
+00000030  05 ff 01 00 01 00 16 03  01 02 71 0b 00 02 6d 00  |..........q...m.|
+00000040  02 6a 00 02 67 30 82 02  63 30 82 01 cc a0 03 02  |.j..g0..c0......|
+00000050  01 02 02 09 00 a2 73 00  0c 81 00 cb f3 30 0d 06  |......s......0..|
+00000060  09 2a 86 48 86 f7 0d 01  01 0b 05 00 30 2b 31 17  |.*.H........0+1.|
+00000070  30 15 06 03 55 04 0a 13  0e 47 6f 6f 67 6c 65 20  |0...U....Google |
+00000080  54 45 53 54 49 4e 47 31  10 30 0e 06 03 55 04 03  |TESTING1.0...U..|
+00000090  13 07 47 6f 20 52 6f 6f  74 30 1e 17 0d 31 35 30  |..Go Root0...150|
+000000a0  31 30 31 30 30 30 30 30  30 5a 17 0d 32 35 30 31  |101000000Z..2501|
+000000b0  30 31 30 30 30 30 30 30  5a 30 26 31 17 30 15 06  |01000000Z0&1.0..|
+000000c0  03 55 04 0a 13 0e 47 6f  6f 67 6c 65 20 54 45 53  |.U....Google TES|
+000000d0  54 49 4e 47 31 0b 30 09  06 03 55 04 03 13 02 47  |TING1.0...U....G|
+000000e0  6f 30 81 9f 30 0d 06 09  2a 86 48 86 f7 0d 01 01  |o0..0...*.H.....|
+000000f0  01 05 00 03 81 8d 00 30  81 89 02 81 81 00 af 87  |.......0........|
+00000100  88 f6 20 1b 95 65 6c 14  ab 44 05 af 3b 45 14 e3  |.. ..el..D..;E..|
+00000110  b7 6d fd 00 63 4d 95 7f  fe 6a 62 35 86 c0 4a f9  |.m..cM...jb5..J.|
+00000120  18 7c f6 aa 25 5e 7a 64  31 66 00 ba f4 8e 92 af  |.|..%^zd1f......|
+00000130  c7 6b d8 76 d4 f3 5f 41  cb 6e 56 15 97 1b 97 c1  |.k.v.._A.nV.....|
+00000140  3c 12 39 21 66 3d 2b 16  d1 bc db 1c c0 a7 da b7  |<.9!f=+.........|
+00000150  ca ad ba da cb d5 21 50  ec de 8d ab d1 6b 81 4b  |......!P.....k.K|
+00000160  89 02 f3 c4 be c1 6c 89  b1 44 84 bd 21 d1 04 7d  |......l..D..!..}|
+00000170  9d 16 4d f9 82 15 f6 ef  fa d6 09 47 f2 fb 02 03  |..M........G....|
+00000180  01 00 01 a3 81 93 30 81  90 30 0e 06 03 55 1d 0f  |......0..0...U..|
+00000190  01 01 ff 04 04 03 02 05  a0 30 1d 06 03 55 1d 25  |.........0...U.%|
+000001a0  04 16 30 14 06 08 2b 06  01 05 05 07 03 01 06 08  |..0...+.........|
+000001b0  2b 06 01 05 05 07 03 02  30 0c 06 03 55 1d 13 01  |+.......0...U...|
+000001c0  01 ff 04 02 30 00 30 19  06 03 55 1d 0e 04 12 04  |....0.0...U.....|
+000001d0  10 12 50 8d 89 6f 1b d1  dc 54 4d 6e cb 69 5e 06  |..P..o...TMn.i^.|
+000001e0  f4 30 1b 06 03 55 1d 23  04 14 30 12 80 10 bf 3d  |.0...U.#..0....=|
+000001f0  b6 a9 66 f2 b8 40 cf ea  b4 03 78 48 1a 41 30 19  |..f..@....xH.A0.|
+00000200  06 03 55 1d 11 04 12 30  10 82 0e 65 78 61 6d 70  |..U....0...examp|
+00000210  6c 65 2e 67 6f 6c 61 6e  67 30 0d 06 09 2a 86 48  |le.golang0...*.H|
+00000220  86 f7 0d 01 01 0b 05 00  03 81 81 00 92 7c af 91  |.............|..|
+00000230  55 12 18 96 59 31 a6 48  40 d5 2d d5 ee bb 02 a0  |U...Y1.H@.-.....|
+00000240  f5 c2 1e 7c 9b b3 30 7d  3c dc 76 da 4f 3d c0 fa  |...|..0}<.v.O=..|
+00000250  ae 2d 33 24 6b 03 7b 1b  67 59 11 21 b5 11 bc 77  |.-3$k.{.gY.!...w|
+00000260  b9 d9 e0 6e a8 2d 2e 35  fa 64 5f 22 3e 63 10 6b  |...n.-.5.d_">c.k|
+00000270  be ff 14 86 6d 0d f0 15  31 a8 14 38 1e 3b 84 87  |....m...1..8.;..|
+00000280  2c cb 98 ed 51 76 b9 b1  4f dd db 9b 84 04 86 40  |,...Qv..O......@|
+00000290  fa 51 dd ba b4 8d eb e3  46 de 46 b9 4f 86 c7 f9  |.Q......F.F.O...|
+000002a0  a4 c2 41 34 ac cc f6 ea  b0 ab 39 18 16 03 01 00  |..A4......9.....|
+000002b0  04 0e 00 00 00                                    |.....|
 >>> Flow 3 (client to server)
-00000000  16 03 01 00 86 10 00 00  82 00 80 20 e6 80 f7 48  |........... ...H|
-00000010  7e 7d 08 08 54 e1 b4 e3  98 27 5f 90 9d 3b e3 c2  |~}..T....'_..;..|
-00000020  c8 8b dc 9e ff 75 fa fc  60 e1 9e 67 7c c4 08 27  |.....u..`..g|..'|
-00000030  cc 6f 15 6c bc 7c 96 de  83 8f 98 6d 4a c7 b7 20  |.o.l.|.....mJ.. |
-00000040  8c 19 47 5a ff 76 92 0a  df df 66 d2 b6 9d 2d 06  |..GZ.v....f...-.|
-00000050  fb ac 07 cf 38 08 f1 fd  0d fe 07 d7 69 3e 8a 79  |....8.......i>.y|
-00000060  dc 2d ab bb f7 18 3c 51  14 6e c6 70 95 a2 59 b1  |.-....<Q.n.p..Y.|
-00000070  39 04 9f ae f3 5f fb a7  2b d3 5a c0 96 d9 4d 2a  |9...._..+.Z...M*|
-00000080  2a 6c 6d 39 ee fc ce 76  1a 92 1b 14 03 01 00 01  |*lm9...v........|
-00000090  01 16 03 01 00 30 10 20  90 7b 0e e6 c2 05 81 c3  |.....0. .{......|
-000000a0  bc da 84 67 dd 5f 97 e2  74 c4 35 4e bf d2 1b 90  |...g._..t.5N....|
-000000b0  2f e0 af dd 6b f5 52 db  36 cd 3e e1 e6 bd 99 30  |/...k.R.6.>....0|
-000000c0  ed c6 bc c2 38 b6                                 |....8.|
+00000000  16 03 01 00 86 10 00 00  82 00 80 31 f5 2e e4 c7  |...........1....|
+00000010  f5 76 d6 f7 2d 1b 8d 4d  a9 2a 43 84 b2 0b 08 d6  |.v..-..M.*C.....|
+00000020  4d d9 9a eb 4b 01 49 6e  11 45 43 0d 31 a7 c3 66  |M...K.In.EC.1..f|
+00000030  da 1c 92 68 fb 3d 36 27  94 2f 67 ae 3d 31 a3 8f  |...h.=6'./g.=1..|
+00000040  01 5a d9 17 92 bc 20 7c  cb ae b4 ca 4c ce d4 a9  |.Z.... |....L...|
+00000050  2c 1d fe fc 3c a9 14 31  1d 65 08 d8 6e 8d ac 9d  |,...<..1.e..n...|
+00000060  21 ee 63 4a e2 da 3c 0e  b1 34 8f 6e 20 dd d4 d4  |!.cJ..<..4.n ...|
+00000070  d8 16 27 5d 02 54 e6 ec  5f 43 84 5b 21 24 ef 5d  |..'].T.._C.[!$.]|
+00000080  45 c4 2b 2c 98 7d 50 dc  0b fc 76 14 03 01 00 01  |E.+,.}P...v.....|
+00000090  01 16 03 01 00 30 ef 50  ea 3c e3 b7 a8 5b 9a d2  |.....0.P.<...[..|
+000000a0  11 69 0f d0 5e 79 c8 cb  68 4a ac 16 ef b4 de 1f  |.i..^y..hJ......|
+000000b0  21 0b 8e 91 cb 70 3f 02  bd 45 c1 34 02 e0 66 8a  |!....p?..E.4..f.|
+000000c0  00 ea 6c 5a 96 41                                 |..lZ.A|
 >>> Flow 4 (server to client)
-00000000  14 03 01 00 01 01 16 03  01 00 30 5d 0c a2 18 13  |..........0]....|
-00000010  40 a1 84 ce c5 d8 4e fc  a4 8a 14 b5 94 18 b1 86  |@.....N.........|
-00000020  da 6a 7d 26 08 d6 a0 f8  78 5b 42 7e f8 83 54 56  |.j}&....x[B~..TV|
-00000030  36 a4 91 37 67 5a d7 68  37 c4 4f 17 03 01 00 20  |6..7gZ.h7.O.... |
-00000040  fd aa 5e cf 4b 12 c5 be  a4 a2 65 5d 6e 65 46 5f  |..^.K.....e]neF_|
-00000050  d2 fe 46 e7 77 2d 9c 1e  0b 39 40 48 c2 2f be 21  |..F.w-...9@H./.!|
-00000060  17 03 01 00 30 03 af 9e  6b d6 76 ed 9e 1d 8b 8b  |....0...k.v.....|
-00000070  2e 2a 5d da c4 73 95 ac  0e 6f 69 cb 63 df 50 27  |.*]..s...oi.c.P'|
-00000080  30 de 2e 55 86 85 ad 3e  33 22 49 72 f2 e2 9f 8f  |0..U...>3"Ir....|
-00000090  ba cf 4e 30 34 15 03 01  00 20 4c 4c 97 61 70 ea  |..N04.... LL.ap.|
-000000a0  ae fc a2 e9 c6 c2 b6 2e  4d 85 f6 ae 2b 56 46 82  |........M...+VF.|
-000000b0  9d d8 a5 82 17 fa 3e 62  67 7e                    |......>bg~|
+00000000  14 03 01 00 01 01 16 03  01 00 30 99 2c 65 32 5f  |..........0.,e2_|
+00000010  53 37 d8 c2 98 87 f4 68  b6 d7 52 6a 14 c7 df 6e  |S7.....h..Rj...n|
+00000020  bb ce ae 31 d4 04 24 4d  e9 c2 39 7b 68 a7 fa 90  |...1..$M..9{h...|
+00000030  c1 30 14 a2 20 c0 8d e1  2a dc 22 17 03 01 00 20  |.0.. ...*.".... |
+00000040  41 c5 03 05 20 53 e9 fa  0a 26 38 ab 84 6a 5e 36  |A... S...&8..j^6|
+00000050  1b 03 80 2f c3 5c 0b 2c  bd 7f 79 68 bb ab 4d 70  |.../.\.,..yh..Mp|
+00000060  17 03 01 00 30 a1 04 3e  f4 a2 54 7a e7 09 0f 20  |....0..>..Tz... |
+00000070  38 f8 9e bb 1b 61 28 bf  46 e8 75 56 b4 c3 93 b9  |8....a(.F.uV....|
+00000080  8c 18 3e 8e af 9f 59 1a  96 be db 61 80 56 c6 09  |..>...Y....a.V..|
+00000090  3c 21 02 37 d2 15 03 01  00 20 13 d1 81 7d ca 04  |<!.7..... ...}..|
+000000a0  2b c3 fc fa 06 5b b4 98  59 27 0d 07 2a 39 3c 6f  |+....[..Y'..*9<o|
+000000b0  8d 64 83 17 0f ba ec 22  21 36                    |.d....."!6|
diff --git a/third_party/gofrontend/libgo/go/crypto/tls/testdata/Server-TLSv10-RSA-RC4 b/third_party/gofrontend/libgo/go/crypto/tls/testdata/Server-TLSv10-RSA-RC4
index d653561..b5cb479 100644
--- a/third_party/gofrontend/libgo/go/crypto/tls/testdata/Server-TLSv10-RSA-RC4
+++ b/third_party/gofrontend/libgo/go/crypto/tls/testdata/Server-TLSv10-RSA-RC4
@@ -1,76 +1,71 @@
 >>> Flow 1 (client to server)
-00000000  16 03 01 00 36 01 00 00  32 03 01 52 cc 57 59 cf  |....6...2..R.WY.|
-00000010  00 a1 49 a4 37 69 74 d8  a7 93 ea 8d e7 50 b7 b3  |..I.7it......P..|
-00000020  8c ec e5 56 fb dc 5f 1a  2e ab 18 00 00 04 00 05  |...V.._.........|
+00000000  16 03 01 00 36 01 00 00  32 03 01 c5 fc 32 c0 09  |....6...2....2..|
+00000010  47 0b a9 f3 72 c9 6c 3a  e0 94 33 48 35 ac b9 3b  |G...r.l:..3H5..;|
+00000020  da 5f 8b 6e 0c 54 c3 16  f0 39 bd 00 00 04 00 05  |._.n.T...9......|
 00000030  00 ff 01 00 00 05 00 0f  00 01 01                 |...........|
 >>> Flow 2 (server to client)
 00000000  16 03 01 00 31 02 00 00  2d 03 01 00 00 00 00 00  |....1...-.......|
 00000010  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
 00000020  00 00 00 00 00 00 00 00  00 00 00 00 00 05 00 00  |................|
-00000030  05 ff 01 00 01 00 16 03  01 02 be 0b 00 02 ba 00  |................|
-00000040  02 b7 00 02 b4 30 82 02  b0 30 82 02 19 a0 03 02  |.....0...0......|
-00000050  01 02 02 09 00 85 b0 bb  a4 8a 7f b8 ca 30 0d 06  |.............0..|
-00000060  09 2a 86 48 86 f7 0d 01  01 05 05 00 30 45 31 0b  |.*.H........0E1.|
-00000070  30 09 06 03 55 04 06 13  02 41 55 31 13 30 11 06  |0...U....AU1.0..|
-00000080  03 55 04 08 13 0a 53 6f  6d 65 2d 53 74 61 74 65  |.U....Some-State|
-00000090  31 21 30 1f 06 03 55 04  0a 13 18 49 6e 74 65 72  |1!0...U....Inter|
-000000a0  6e 65 74 20 57 69 64 67  69 74 73 20 50 74 79 20  |net Widgits Pty |
-000000b0  4c 74 64 30 1e 17 0d 31  30 30 34 32 34 30 39 30  |Ltd0...100424090|
-000000c0  39 33 38 5a 17 0d 31 31  30 34 32 34 30 39 30 39  |938Z..1104240909|
-000000d0  33 38 5a 30 45 31 0b 30  09 06 03 55 04 06 13 02  |38Z0E1.0...U....|
-000000e0  41 55 31 13 30 11 06 03  55 04 08 13 0a 53 6f 6d  |AU1.0...U....Som|
-000000f0  65 2d 53 74 61 74 65 31  21 30 1f 06 03 55 04 0a  |e-State1!0...U..|
-00000100  13 18 49 6e 74 65 72 6e  65 74 20 57 69 64 67 69  |..Internet Widgi|
-00000110  74 73 20 50 74 79 20 4c  74 64 30 81 9f 30 0d 06  |ts Pty Ltd0..0..|
-00000120  09 2a 86 48 86 f7 0d 01  01 01 05 00 03 81 8d 00  |.*.H............|
-00000130  30 81 89 02 81 81 00 bb  79 d6 f5 17 b5 e5 bf 46  |0.......y......F|
-00000140  10 d0 dc 69 be e6 2b 07  43 5a d0 03 2d 8a 7a 43  |...i..+.CZ..-.zC|
-00000150  85 b7 14 52 e7 a5 65 4c  2c 78 b8 23 8c b5 b4 82  |...R..eL,x.#....|
-00000160  e5 de 1f 95 3b 7e 62 a5  2c a5 33 d6 fe 12 5c 7a  |....;~b.,.3...\z|
-00000170  56 fc f5 06 bf fa 58 7b  26 3f b5 cd 04 d3 d0 c9  |V.....X{&?......|
-00000180  21 96 4a c7 f4 54 9f 5a  bf ef 42 71 00 fe 18 99  |!.J..T.Z..Bq....|
-00000190  07 7f 7e 88 7d 7d f1 04  39 c4 a2 2e db 51 c9 7c  |..~.}}..9....Q.||
-000001a0  e3 c0 4c 3b 32 66 01 cf  af b1 1d b8 71 9a 1d db  |..L;2f......q...|
-000001b0  db 89 6b ae da 2d 79 02  03 01 00 01 a3 81 a7 30  |..k..-y........0|
-000001c0  81 a4 30 1d 06 03 55 1d  0e 04 16 04 14 b1 ad e2  |..0...U.........|
-000001d0  85 5a cf cb 28 db 69 ce  23 69 de d3 26 8e 18 88  |.Z..(.i.#i..&...|
-000001e0  39 30 75 06 03 55 1d 23  04 6e 30 6c 80 14 b1 ad  |90u..U.#.n0l....|
-000001f0  e2 85 5a cf cb 28 db 69  ce 23 69 de d3 26 8e 18  |..Z..(.i.#i..&..|
-00000200  88 39 a1 49 a4 47 30 45  31 0b 30 09 06 03 55 04  |.9.I.G0E1.0...U.|
-00000210  06 13 02 41 55 31 13 30  11 06 03 55 04 08 13 0a  |...AU1.0...U....|
-00000220  53 6f 6d 65 2d 53 74 61  74 65 31 21 30 1f 06 03  |Some-State1!0...|
-00000230  55 04 0a 13 18 49 6e 74  65 72 6e 65 74 20 57 69  |U....Internet Wi|
-00000240  64 67 69 74 73 20 50 74  79 20 4c 74 64 82 09 00  |dgits Pty Ltd...|
-00000250  85 b0 bb a4 8a 7f b8 ca  30 0c 06 03 55 1d 13 04  |........0...U...|
-00000260  05 30 03 01 01 ff 30 0d  06 09 2a 86 48 86 f7 0d  |.0....0...*.H...|
-00000270  01 01 05 05 00 03 81 81  00 08 6c 45 24 c7 6b b1  |..........lE$.k.|
-00000280  59 ab 0c 52 cc f2 b0 14  d7 87 9d 7a 64 75 b5 5a  |Y..R.......zdu.Z|
-00000290  95 66 e4 c5 2b 8e ae 12  66 1f eb 4f 38 b3 6e 60  |.f..+...f..O8.n`|
-000002a0  d3 92 fd f7 41 08 b5 25  13 b1 18 7a 24 fb 30 1d  |....A..%...z$.0.|
-000002b0  ba ed 98 b9 17 ec e7 d7  31 59 db 95 d3 1d 78 ea  |........1Y....x.|
-000002c0  50 56 5c d5 82 5a 2d 5a  5f 33 c4 b6 d8 c9 75 90  |PV\..Z-Z_3....u.|
-000002d0  96 8c 0f 52 98 b5 cd 98  1f 89 20 5f f2 a0 1c a3  |...R...... _....|
-000002e0  1b 96 94 dd a9 fd 57 e9  70 e8 26 6d 71 99 9b 26  |......W.p.&mq..&|
-000002f0  6e 38 50 29 6c 90 a7 bd  d9 16 03 01 00 04 0e 00  |n8P)l...........|
-00000300  00 00                                             |..|
+00000030  05 ff 01 00 01 00 16 03  01 02 71 0b 00 02 6d 00  |..........q...m.|
+00000040  02 6a 00 02 67 30 82 02  63 30 82 01 cc a0 03 02  |.j..g0..c0......|
+00000050  01 02 02 09 00 a2 73 00  0c 81 00 cb f3 30 0d 06  |......s......0..|
+00000060  09 2a 86 48 86 f7 0d 01  01 0b 05 00 30 2b 31 17  |.*.H........0+1.|
+00000070  30 15 06 03 55 04 0a 13  0e 47 6f 6f 67 6c 65 20  |0...U....Google |
+00000080  54 45 53 54 49 4e 47 31  10 30 0e 06 03 55 04 03  |TESTING1.0...U..|
+00000090  13 07 47 6f 20 52 6f 6f  74 30 1e 17 0d 31 35 30  |..Go Root0...150|
+000000a0  31 30 31 30 30 30 30 30  30 5a 17 0d 32 35 30 31  |101000000Z..2501|
+000000b0  30 31 30 30 30 30 30 30  5a 30 26 31 17 30 15 06  |01000000Z0&1.0..|
+000000c0  03 55 04 0a 13 0e 47 6f  6f 67 6c 65 20 54 45 53  |.U....Google TES|
+000000d0  54 49 4e 47 31 0b 30 09  06 03 55 04 03 13 02 47  |TING1.0...U....G|
+000000e0  6f 30 81 9f 30 0d 06 09  2a 86 48 86 f7 0d 01 01  |o0..0...*.H.....|
+000000f0  01 05 00 03 81 8d 00 30  81 89 02 81 81 00 af 87  |.......0........|
+00000100  88 f6 20 1b 95 65 6c 14  ab 44 05 af 3b 45 14 e3  |.. ..el..D..;E..|
+00000110  b7 6d fd 00 63 4d 95 7f  fe 6a 62 35 86 c0 4a f9  |.m..cM...jb5..J.|
+00000120  18 7c f6 aa 25 5e 7a 64  31 66 00 ba f4 8e 92 af  |.|..%^zd1f......|
+00000130  c7 6b d8 76 d4 f3 5f 41  cb 6e 56 15 97 1b 97 c1  |.k.v.._A.nV.....|
+00000140  3c 12 39 21 66 3d 2b 16  d1 bc db 1c c0 a7 da b7  |<.9!f=+.........|
+00000150  ca ad ba da cb d5 21 50  ec de 8d ab d1 6b 81 4b  |......!P.....k.K|
+00000160  89 02 f3 c4 be c1 6c 89  b1 44 84 bd 21 d1 04 7d  |......l..D..!..}|
+00000170  9d 16 4d f9 82 15 f6 ef  fa d6 09 47 f2 fb 02 03  |..M........G....|
+00000180  01 00 01 a3 81 93 30 81  90 30 0e 06 03 55 1d 0f  |......0..0...U..|
+00000190  01 01 ff 04 04 03 02 05  a0 30 1d 06 03 55 1d 25  |.........0...U.%|
+000001a0  04 16 30 14 06 08 2b 06  01 05 05 07 03 01 06 08  |..0...+.........|
+000001b0  2b 06 01 05 05 07 03 02  30 0c 06 03 55 1d 13 01  |+.......0...U...|
+000001c0  01 ff 04 02 30 00 30 19  06 03 55 1d 0e 04 12 04  |....0.0...U.....|
+000001d0  10 12 50 8d 89 6f 1b d1  dc 54 4d 6e cb 69 5e 06  |..P..o...TMn.i^.|
+000001e0  f4 30 1b 06 03 55 1d 23  04 14 30 12 80 10 bf 3d  |.0...U.#..0....=|
+000001f0  b6 a9 66 f2 b8 40 cf ea  b4 03 78 48 1a 41 30 19  |..f..@....xH.A0.|
+00000200  06 03 55 1d 11 04 12 30  10 82 0e 65 78 61 6d 70  |..U....0...examp|
+00000210  6c 65 2e 67 6f 6c 61 6e  67 30 0d 06 09 2a 86 48  |le.golang0...*.H|
+00000220  86 f7 0d 01 01 0b 05 00  03 81 81 00 92 7c af 91  |.............|..|
+00000230  55 12 18 96 59 31 a6 48  40 d5 2d d5 ee bb 02 a0  |U...Y1.H@.-.....|
+00000240  f5 c2 1e 7c 9b b3 30 7d  3c dc 76 da 4f 3d c0 fa  |...|..0}<.v.O=..|
+00000250  ae 2d 33 24 6b 03 7b 1b  67 59 11 21 b5 11 bc 77  |.-3$k.{.gY.!...w|
+00000260  b9 d9 e0 6e a8 2d 2e 35  fa 64 5f 22 3e 63 10 6b  |...n.-.5.d_">c.k|
+00000270  be ff 14 86 6d 0d f0 15  31 a8 14 38 1e 3b 84 87  |....m...1..8.;..|
+00000280  2c cb 98 ed 51 76 b9 b1  4f dd db 9b 84 04 86 40  |,...Qv..O......@|
+00000290  fa 51 dd ba b4 8d eb e3  46 de 46 b9 4f 86 c7 f9  |.Q......F.F.O...|
+000002a0  a4 c2 41 34 ac cc f6 ea  b0 ab 39 18 16 03 01 00  |..A4......9.....|
+000002b0  04 0e 00 00 00                                    |.....|
 >>> Flow 3 (client to server)
-00000000  16 03 01 00 86 10 00 00  82 00 80 b1 96 7b 6f f5  |.............{o.|
-00000010  a0 cb 0d 60 9b 64 d3 f5  17 76 47 7b bc a5 0e 96  |...`.d...vG{....|
-00000020  53 af 68 0c 96 22 f7 28  0c 24 37 9c 51 69 ed b2  |S.h..".(.$7.Qi..|
-00000030  47 14 ba 33 c5 79 6b 96  f2 ab 3c 02 5c 37 a4 97  |G..3.yk...<.\7..|
-00000040  23 fc 7f d3 95 2d 85 99  1a 10 1b 38 e5 f1 83 55  |#....-.....8...U|
-00000050  4a ab 60 f8 89 0a 6a c4  eb 45 f5 b0 f4 f8 09 31  |J.`...j..E.....1|
-00000060  6e f0 25 30 fd 5e 68 61  bc cb 0d 9e 05 73 0a f4  |n.%0.^ha.....s..|
-00000070  a5 2e d9 d5 4e 08 f6 3b  8d 2d 21 f5 79 b6 97 55  |....N..;.-!.y..U|
-00000080  b9 99 03 49 ea 96 36 49  21 56 bf 14 03 01 00 01  |...I..6I!V......|
-00000090  01 16 03 01 00 24 f0 4f  30 06 c3 25 01 93 34 ab  |.....$.O0..%..4.|
-000000a0  93 8f 59 26 83 6e 8a fd  5a a6 cf af ad b1 a2 83  |..Y&.n..Z.......|
-000000b0  28 ff c2 66 5f ac e5 a5  a5 03                    |(..f_.....|
+00000000  16 03 01 00 86 10 00 00  82 00 80 6a ad 7f e3 26  |...........j...&|
+00000010  71 da 48 af 11 63 de 2e  e8 50 f9 6a be 04 3d 17  |q.H..c...P.j..=.|
+00000020  d1 29 fe 2c 7f b6 26 c1  7e 0b 18 1c 41 62 5c 91  |.).,..&.~...Ab\.|
+00000030  ee 26 9c 92 f5 d1 e9 29  e1 ca a7 01 6a 41 b9 00  |.&.....)....jA..|
+00000040  34 1d 5b c6 28 0e 1a 8f  32 c5 03 e7 a1 8f 89 1b  |4.[.(...2.......|
+00000050  af 13 22 2b 5b e8 76 2d  00 ac da 27 75 95 75 e7  |.."+[.v-...'u.u.|
+00000060  00 00 39 2c bf f2 01 57  e6 29 e3 26 b1 6b ae c5  |..9,...W.).&.k..|
+00000070  8d ce d2 36 b2 94 1f 9c  30 5e b2 16 3d 20 cf 4d  |...6....0^..= .M|
+00000080  88 f5 ac 4c 27 e3 f5 86  ef 9e dc 14 03 01 00 01  |...L'...........|
+00000090  01 16 03 01 00 24 48 d8  80 c4 37 22 31 99 53 30  |.....$H...7"1.S0|
+000000a0  5b 00 07 7e 87 2e 59 9a  d9 0c 42 9e dd ed da 89  |[..~..Y...B.....|
+000000b0  1a 1f cb ab 55 0c ba d9  a9 c0                    |....U.....|
 >>> Flow 4 (server to client)
-00000000  14 03 01 00 01 01 16 03  01 00 24 9d b4 ea d8 be  |..........$.....|
-00000010  b5 9f 00 fd b5 99 04 12  6b 7a 3f b8 52 d7 52 a9  |........kz?.R.R.|
-00000020  e9 bd 5b 63 ad b0 53 ac  46 80 be 48 6e dd ee 17  |..[c..S.F..Hn...|
-00000030  03 01 00 21 07 ac c4 fb  21 e4 b8 6b 64 3b b5 27  |...!....!..kd;.'|
-00000040  29 67 a1 10 2e d2 71 d5  59 5e fc 1d 84 31 15 6e  |)g....q.Y^...1.n|
-00000050  4d 4b dc a9 3a 15 03 01  00 16 25 22 a5 78 23 5a  |MK..:.....%".x#Z|
-00000060  69 6f 99 a1 b3 1c 8d bf  f3 bd 1b c8 1c 57 15 75  |io...........W.u|
+00000000  14 03 01 00 01 01 16 03  01 00 24 ae 00 c8 14 67  |..........$....g|
+00000010  4b b5 21 96 98 91 d6 27  40 9b 5e a5 86 53 56 f3  |K.!....'@.^..SV.|
+00000020  f6 dc 7e b2 49 78 4b 4d  57 7c 62 a5 f2 16 8f 17  |..~.IxKMW|b.....|
+00000030  03 01 00 21 34 e3 48 58  1c 67 fb 3a 46 28 5d a1  |...!4.HX.g.:F(].|
+00000040  19 66 58 b1 bb fb e7 17  71 07 3f 0a d0 7c c9 24  |.fX.....q.?..|.$|
+00000050  c7 ef 41 af 62 15 03 01  00 16 dd dc 16 dc 16 cc  |..A.b...........|
+00000060  0d f3 2c 29 00 c0 4f 01  68 05 92 a0 f7 ad e2 63  |..,)..O.h......c|
diff --git a/third_party/gofrontend/libgo/go/crypto/tls/testdata/Server-TLSv11-RSA-RC4 b/third_party/gofrontend/libgo/go/crypto/tls/testdata/Server-TLSv11-RSA-RC4
index 9237db0..dc5e765 100644
--- a/third_party/gofrontend/libgo/go/crypto/tls/testdata/Server-TLSv11-RSA-RC4
+++ b/third_party/gofrontend/libgo/go/crypto/tls/testdata/Server-TLSv11-RSA-RC4
@@ -1,76 +1,71 @@
 >>> Flow 1 (client to server)
-00000000  16 03 01 00 36 01 00 00  32 03 02 52 cc 57 59 bd  |....6...2..R.WY.|
-00000010  cd 9d 1e 17 38 43 a5 e3  e7 30 e4 2b 2a ef f7 5b  |....8C...0.+*..[|
-00000020  81 91 0c 0b 52 f8 2d 2c  61 d3 13 00 00 04 00 05  |....R.-,a.......|
+00000000  16 03 01 00 36 01 00 00  32 03 02 ff e1 a1 04 0b  |....6...2.......|
+00000010  c2 dc fb 7d 07 61 44 9b  00 67 fe 38 73 f5 fc 4e  |...}.aD..g.8s..N|
+00000020  35 94 0a d5 c1 d0 e7 54  dc 44 1f 00 00 04 00 05  |5......T.D......|
 00000030  00 ff 01 00 00 05 00 0f  00 01 01                 |...........|
 >>> Flow 2 (server to client)
 00000000  16 03 02 00 31 02 00 00  2d 03 02 00 00 00 00 00  |....1...-.......|
 00000010  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
 00000020  00 00 00 00 00 00 00 00  00 00 00 00 00 05 00 00  |................|
-00000030  05 ff 01 00 01 00 16 03  02 02 be 0b 00 02 ba 00  |................|
-00000040  02 b7 00 02 b4 30 82 02  b0 30 82 02 19 a0 03 02  |.....0...0......|
-00000050  01 02 02 09 00 85 b0 bb  a4 8a 7f b8 ca 30 0d 06  |.............0..|
-00000060  09 2a 86 48 86 f7 0d 01  01 05 05 00 30 45 31 0b  |.*.H........0E1.|
-00000070  30 09 06 03 55 04 06 13  02 41 55 31 13 30 11 06  |0...U....AU1.0..|
-00000080  03 55 04 08 13 0a 53 6f  6d 65 2d 53 74 61 74 65  |.U....Some-State|
-00000090  31 21 30 1f 06 03 55 04  0a 13 18 49 6e 74 65 72  |1!0...U....Inter|
-000000a0  6e 65 74 20 57 69 64 67  69 74 73 20 50 74 79 20  |net Widgits Pty |
-000000b0  4c 74 64 30 1e 17 0d 31  30 30 34 32 34 30 39 30  |Ltd0...100424090|
-000000c0  39 33 38 5a 17 0d 31 31  30 34 32 34 30 39 30 39  |938Z..1104240909|
-000000d0  33 38 5a 30 45 31 0b 30  09 06 03 55 04 06 13 02  |38Z0E1.0...U....|
-000000e0  41 55 31 13 30 11 06 03  55 04 08 13 0a 53 6f 6d  |AU1.0...U....Som|
-000000f0  65 2d 53 74 61 74 65 31  21 30 1f 06 03 55 04 0a  |e-State1!0...U..|
-00000100  13 18 49 6e 74 65 72 6e  65 74 20 57 69 64 67 69  |..Internet Widgi|
-00000110  74 73 20 50 74 79 20 4c  74 64 30 81 9f 30 0d 06  |ts Pty Ltd0..0..|
-00000120  09 2a 86 48 86 f7 0d 01  01 01 05 00 03 81 8d 00  |.*.H............|
-00000130  30 81 89 02 81 81 00 bb  79 d6 f5 17 b5 e5 bf 46  |0.......y......F|
-00000140  10 d0 dc 69 be e6 2b 07  43 5a d0 03 2d 8a 7a 43  |...i..+.CZ..-.zC|
-00000150  85 b7 14 52 e7 a5 65 4c  2c 78 b8 23 8c b5 b4 82  |...R..eL,x.#....|
-00000160  e5 de 1f 95 3b 7e 62 a5  2c a5 33 d6 fe 12 5c 7a  |....;~b.,.3...\z|
-00000170  56 fc f5 06 bf fa 58 7b  26 3f b5 cd 04 d3 d0 c9  |V.....X{&?......|
-00000180  21 96 4a c7 f4 54 9f 5a  bf ef 42 71 00 fe 18 99  |!.J..T.Z..Bq....|
-00000190  07 7f 7e 88 7d 7d f1 04  39 c4 a2 2e db 51 c9 7c  |..~.}}..9....Q.||
-000001a0  e3 c0 4c 3b 32 66 01 cf  af b1 1d b8 71 9a 1d db  |..L;2f......q...|
-000001b0  db 89 6b ae da 2d 79 02  03 01 00 01 a3 81 a7 30  |..k..-y........0|
-000001c0  81 a4 30 1d 06 03 55 1d  0e 04 16 04 14 b1 ad e2  |..0...U.........|
-000001d0  85 5a cf cb 28 db 69 ce  23 69 de d3 26 8e 18 88  |.Z..(.i.#i..&...|
-000001e0  39 30 75 06 03 55 1d 23  04 6e 30 6c 80 14 b1 ad  |90u..U.#.n0l....|
-000001f0  e2 85 5a cf cb 28 db 69  ce 23 69 de d3 26 8e 18  |..Z..(.i.#i..&..|
-00000200  88 39 a1 49 a4 47 30 45  31 0b 30 09 06 03 55 04  |.9.I.G0E1.0...U.|
-00000210  06 13 02 41 55 31 13 30  11 06 03 55 04 08 13 0a  |...AU1.0...U....|
-00000220  53 6f 6d 65 2d 53 74 61  74 65 31 21 30 1f 06 03  |Some-State1!0...|
-00000230  55 04 0a 13 18 49 6e 74  65 72 6e 65 74 20 57 69  |U....Internet Wi|
-00000240  64 67 69 74 73 20 50 74  79 20 4c 74 64 82 09 00  |dgits Pty Ltd...|
-00000250  85 b0 bb a4 8a 7f b8 ca  30 0c 06 03 55 1d 13 04  |........0...U...|
-00000260  05 30 03 01 01 ff 30 0d  06 09 2a 86 48 86 f7 0d  |.0....0...*.H...|
-00000270  01 01 05 05 00 03 81 81  00 08 6c 45 24 c7 6b b1  |..........lE$.k.|
-00000280  59 ab 0c 52 cc f2 b0 14  d7 87 9d 7a 64 75 b5 5a  |Y..R.......zdu.Z|
-00000290  95 66 e4 c5 2b 8e ae 12  66 1f eb 4f 38 b3 6e 60  |.f..+...f..O8.n`|
-000002a0  d3 92 fd f7 41 08 b5 25  13 b1 18 7a 24 fb 30 1d  |....A..%...z$.0.|
-000002b0  ba ed 98 b9 17 ec e7 d7  31 59 db 95 d3 1d 78 ea  |........1Y....x.|
-000002c0  50 56 5c d5 82 5a 2d 5a  5f 33 c4 b6 d8 c9 75 90  |PV\..Z-Z_3....u.|
-000002d0  96 8c 0f 52 98 b5 cd 98  1f 89 20 5f f2 a0 1c a3  |...R...... _....|
-000002e0  1b 96 94 dd a9 fd 57 e9  70 e8 26 6d 71 99 9b 26  |......W.p.&mq..&|
-000002f0  6e 38 50 29 6c 90 a7 bd  d9 16 03 02 00 04 0e 00  |n8P)l...........|
-00000300  00 00                                             |..|
+00000030  05 ff 01 00 01 00 16 03  02 02 71 0b 00 02 6d 00  |..........q...m.|
+00000040  02 6a 00 02 67 30 82 02  63 30 82 01 cc a0 03 02  |.j..g0..c0......|
+00000050  01 02 02 09 00 a2 73 00  0c 81 00 cb f3 30 0d 06  |......s......0..|
+00000060  09 2a 86 48 86 f7 0d 01  01 0b 05 00 30 2b 31 17  |.*.H........0+1.|
+00000070  30 15 06 03 55 04 0a 13  0e 47 6f 6f 67 6c 65 20  |0...U....Google |
+00000080  54 45 53 54 49 4e 47 31  10 30 0e 06 03 55 04 03  |TESTING1.0...U..|
+00000090  13 07 47 6f 20 52 6f 6f  74 30 1e 17 0d 31 35 30  |..Go Root0...150|
+000000a0  31 30 31 30 30 30 30 30  30 5a 17 0d 32 35 30 31  |101000000Z..2501|
+000000b0  30 31 30 30 30 30 30 30  5a 30 26 31 17 30 15 06  |01000000Z0&1.0..|
+000000c0  03 55 04 0a 13 0e 47 6f  6f 67 6c 65 20 54 45 53  |.U....Google TES|
+000000d0  54 49 4e 47 31 0b 30 09  06 03 55 04 03 13 02 47  |TING1.0...U....G|
+000000e0  6f 30 81 9f 30 0d 06 09  2a 86 48 86 f7 0d 01 01  |o0..0...*.H.....|
+000000f0  01 05 00 03 81 8d 00 30  81 89 02 81 81 00 af 87  |.......0........|
+00000100  88 f6 20 1b 95 65 6c 14  ab 44 05 af 3b 45 14 e3  |.. ..el..D..;E..|
+00000110  b7 6d fd 00 63 4d 95 7f  fe 6a 62 35 86 c0 4a f9  |.m..cM...jb5..J.|
+00000120  18 7c f6 aa 25 5e 7a 64  31 66 00 ba f4 8e 92 af  |.|..%^zd1f......|
+00000130  c7 6b d8 76 d4 f3 5f 41  cb 6e 56 15 97 1b 97 c1  |.k.v.._A.nV.....|
+00000140  3c 12 39 21 66 3d 2b 16  d1 bc db 1c c0 a7 da b7  |<.9!f=+.........|
+00000150  ca ad ba da cb d5 21 50  ec de 8d ab d1 6b 81 4b  |......!P.....k.K|
+00000160  89 02 f3 c4 be c1 6c 89  b1 44 84 bd 21 d1 04 7d  |......l..D..!..}|
+00000170  9d 16 4d f9 82 15 f6 ef  fa d6 09 47 f2 fb 02 03  |..M........G....|
+00000180  01 00 01 a3 81 93 30 81  90 30 0e 06 03 55 1d 0f  |......0..0...U..|
+00000190  01 01 ff 04 04 03 02 05  a0 30 1d 06 03 55 1d 25  |.........0...U.%|
+000001a0  04 16 30 14 06 08 2b 06  01 05 05 07 03 01 06 08  |..0...+.........|
+000001b0  2b 06 01 05 05 07 03 02  30 0c 06 03 55 1d 13 01  |+.......0...U...|
+000001c0  01 ff 04 02 30 00 30 19  06 03 55 1d 0e 04 12 04  |....0.0...U.....|
+000001d0  10 12 50 8d 89 6f 1b d1  dc 54 4d 6e cb 69 5e 06  |..P..o...TMn.i^.|
+000001e0  f4 30 1b 06 03 55 1d 23  04 14 30 12 80 10 bf 3d  |.0...U.#..0....=|
+000001f0  b6 a9 66 f2 b8 40 cf ea  b4 03 78 48 1a 41 30 19  |..f..@....xH.A0.|
+00000200  06 03 55 1d 11 04 12 30  10 82 0e 65 78 61 6d 70  |..U....0...examp|
+00000210  6c 65 2e 67 6f 6c 61 6e  67 30 0d 06 09 2a 86 48  |le.golang0...*.H|
+00000220  86 f7 0d 01 01 0b 05 00  03 81 81 00 92 7c af 91  |.............|..|
+00000230  55 12 18 96 59 31 a6 48  40 d5 2d d5 ee bb 02 a0  |U...Y1.H@.-.....|
+00000240  f5 c2 1e 7c 9b b3 30 7d  3c dc 76 da 4f 3d c0 fa  |...|..0}<.v.O=..|
+00000250  ae 2d 33 24 6b 03 7b 1b  67 59 11 21 b5 11 bc 77  |.-3$k.{.gY.!...w|
+00000260  b9 d9 e0 6e a8 2d 2e 35  fa 64 5f 22 3e 63 10 6b  |...n.-.5.d_">c.k|
+00000270  be ff 14 86 6d 0d f0 15  31 a8 14 38 1e 3b 84 87  |....m...1..8.;..|
+00000280  2c cb 98 ed 51 76 b9 b1  4f dd db 9b 84 04 86 40  |,...Qv..O......@|
+00000290  fa 51 dd ba b4 8d eb e3  46 de 46 b9 4f 86 c7 f9  |.Q......F.F.O...|
+000002a0  a4 c2 41 34 ac cc f6 ea  b0 ab 39 18 16 03 02 00  |..A4......9.....|
+000002b0  04 0e 00 00 00                                    |.....|
 >>> Flow 3 (client to server)
-00000000  16 03 02 00 86 10 00 00  82 00 80 71 2b 19 25 86  |...........q+.%.|
-00000010  a0 ff ba d5 1c a6 0c 8b  6b 0a b8 e9 42 93 2f 55  |........k...B./U|
-00000020  a8 ee 62 fa ed bc 6d e2  9d e3 76 a6 73 d7 99 58  |..b...m...v.s..X|
-00000030  cc 0b 14 42 96 7c b6 c7  8f 21 16 cf 71 9b 2b b9  |...B.|...!..q.+.|
-00000040  e0 34 57 76 22 d5 87 8a  ce 1f ea 26 6e 1e e6 ca  |.4Wv"......&n...|
-00000050  55 3b 20 cd cf 42 26 b1  51 3e 8c 1d a2 ae c4 63  |U; ..B&.Q>.....c|
-00000060  f5 ce 27 3c 1e c3 e0 e3  b1 16 c1 8a 62 bd 21 7f  |..'<........b.!.|
-00000070  38 b5 b7 3a 3c bb 03 37  e1 a5 ff f1 29 e2 21 0a  |8..:<..7....).!.|
-00000080  8c 20 02 e0 c0 82 97 9d  18 6d f8 14 03 02 00 01  |. .......m......|
-00000090  01 16 03 02 00 24 bc 19  16 6e fd 0b db 9e d5 1d  |.....$...n......|
-000000a0  65 b6 57 1c 58 b5 6a ac  f7 4f f0 cd a1 a9 0c c0  |e.W.X.j..O......|
-000000b0  df e6 eb d5 00 f7 fd 43  bb 27                    |.......C.'|
+00000000  16 03 02 00 86 10 00 00  82 00 80 4c e0 4d 6a 19  |...........L.Mj.|
+00000010  a2 72 2a 3d 41 14 a7 b3  0a 25 11 bf c9 9f cf 8c  |.r*=A....%......|
+00000020  3c 0b 01 49 aa f1 59 4b  60 ac e5 72 9b ec 20 41  |<..I..YK`..r.. A|
+00000030  2f 7e ef bf e0 fe 13 c0  1d fd 51 c5 08 c6 9a 9e  |/~........Q.....|
+00000040  74 88 c7 e3 36 99 73 fd  00 2d a2 6a bd 25 f2 d7  |t...6.s..-.j.%..|
+00000050  24 fd fd ab 0c e0 18 38  ba 7b f0 c9 c0 58 a6 d0  |$......8.{...X..|
+00000060  4e e2 59 70 aa f4 52 34  12 a0 ec a4 53 1e 8b ee  |N.Yp..R4....S...|
+00000070  3e bf a4 87 da 02 4c 95  bd 10 af e8 88 c9 ce 87  |>.....L.........|
+00000080  3c 9e 91 70 91 a0 85 18  84 e4 e0 14 03 02 00 01  |<..p............|
+00000090  01 16 03 02 00 24 c5 c0  27 71 49 ad ed 37 e6 5d  |.....$..'qI..7.]|
+000000a0  1b 78 3e 74 15 b7 61 e5  f3 af 1e d0 a2 85 b3 13  |.x>t..a.........|
+000000b0  6e 5e 9a c7 3d 47 32 4d  1b 8d                    |n^..=G2M..|
 >>> Flow 4 (server to client)
-00000000  14 03 02 00 01 01 16 03  02 00 24 cf 4f e4 27 b0  |..........$.O.'.|
-00000010  3d 17 34 b1 3c 37 6e c5  2b 3d 4a c3 46 50 44 b4  |=.4.<7n.+=J.FPD.|
-00000020  de 77 18 10 4f 60 b3 4e  dc 06 fd 25 ec 05 15 17  |.w..O`.N...%....|
-00000030  03 02 00 21 a5 c9 32 f2  21 fb 94 7e 0d 15 65 fd  |...!..2.!..~..e.|
-00000040  3e fe e4 c1 a5 e9 88 72  b2 f1 26 39 a6 48 59 97  |>......r..&9.HY.|
-00000050  65 e3 f0 cb 46 15 03 02  00 16 4b 02 ec cd ca 30  |e...F.....K....0|
-00000060  42 cf 3d a0 4a fa 8e 79  bb ed b0 59 40 9b 2c 1a  |B.=.J..y...Y@.,.|
+00000000  14 03 02 00 01 01 16 03  02 00 24 31 22 76 4d 43  |..........$1"vMC|
+00000010  7a 8a 58 2c 7d 1c 41 39  bf 08 7e 82 17 55 52 b3  |z.X,}.A9..~..UR.|
+00000020  81 bd 7a f8 3c bf 9c 2b  f0 9b 3f 65 f5 42 15 17  |..z.<..+..?e.B..|
+00000030  03 02 00 21 b1 cc e5 56  16 70 58 0b 91 3c 8c 46  |...!...V.pX..<.F|
+00000040  0e 3b b6 fe 32 5d 2e b0  8c 6a 1c a0 82 c9 43 81  |.;..2]...j....C.|
+00000050  cf 07 25 47 c9 15 03 02  00 16 53 91 04 70 ba 03  |..%G......S..p..|
+00000060  53 69 57 86 3b 2f 8b 97  37 7c b8 85 46 b6 72 42  |SiW.;/..7|..F.rB|
diff --git a/third_party/gofrontend/libgo/go/crypto/tls/testdata/Server-TLSv12-ALPN b/third_party/gofrontend/libgo/go/crypto/tls/testdata/Server-TLSv12-ALPN
index 106244d..cbfeb42 100644
--- a/third_party/gofrontend/libgo/go/crypto/tls/testdata/Server-TLSv12-ALPN
+++ b/third_party/gofrontend/libgo/go/crypto/tls/testdata/Server-TLSv12-ALPN
@@ -1,122 +1,109 @@
 >>> Flow 1 (client to server)
-00000000  16 03 01 01 8a 01 00 01  86 03 03 34 54 69 f3 d7  |...........4Ti..|
-00000010  20 9d 1d 74 db 72 e9 2f  51 7c c2 82 0a 9b cb 6d  | ..t.r./Q|.....m|
-00000020  90 b4 8e a2 1f 2f c7 66  74 8f 33 00 00 d6 c0 30  |...../.ft.3....0|
-00000030  c0 2c c0 28 c0 24 c0 14  c0 0a c0 22 c0 21 c0 20  |.,.(.$.....".!. |
-00000040  00 a5 00 a3 00 a1 00 9f  00 6b 00 6a 00 69 00 68  |.........k.j.i.h|
-00000050  00 39 00 38 00 37 00 36  00 88 00 87 00 86 00 85  |.9.8.7.6........|
-00000060  c0 32 c0 2e c0 2a c0 26  c0 0f c0 05 00 9d 00 3d  |.2...*.&.......=|
-00000070  00 35 00 84 c0 2f c0 2b  c0 27 c0 23 c0 13 c0 09  |.5.../.+.'.#....|
-00000080  c0 1f c0 1e c0 1d 00 a4  00 a2 00 a0 00 9e 00 67  |...............g|
-00000090  00 40 00 3f 00 3e 00 33  00 32 00 31 00 30 00 9a  |.@.?.>.3.2.1.0..|
-000000a0  00 99 00 98 00 97 00 45  00 44 00 43 00 42 c0 31  |.......E.D.C.B.1|
-000000b0  c0 2d c0 29 c0 25 c0 0e  c0 04 00 9c 00 3c 00 2f  |.-.).%.......<./|
-000000c0  00 96 00 41 00 07 c0 11  c0 07 c0 0c c0 02 00 05  |...A............|
-000000d0  00 04 c0 12 c0 08 c0 1c  c0 1b c0 1a 00 16 00 13  |................|
-000000e0  00 10 00 0d c0 0d c0 03  00 0a 00 15 00 12 00 0f  |................|
-000000f0  00 0c 00 09 00 14 00 11  00 0e 00 0b 00 08 00 06  |................|
-00000100  00 03 00 ff 01 00 00 87  00 0b 00 04 03 00 01 02  |................|
-00000110  00 0a 00 3a 00 38 00 0e  00 0d 00 19 00 1c 00 0b  |...:.8..........|
-00000120  00 0c 00 1b 00 18 00 09  00 0a 00 1a 00 16 00 17  |................|
-00000130  00 08 00 06 00 07 00 14  00 15 00 04 00 05 00 12  |................|
-00000140  00 13 00 01 00 02 00 03  00 0f 00 10 00 11 00 23  |...............#|
-00000150  00 00 00 0d 00 20 00 1e  06 01 06 02 06 03 05 01  |..... ..........|
-00000160  05 02 05 03 04 01 04 02  04 03 03 01 03 02 03 03  |................|
-00000170  02 01 02 02 02 03 00 0f  00 01 01 00 10 00 10 00  |................|
-00000180  0e 06 70 72 6f 74 6f 32  06 70 72 6f 74 6f 31     |..proto2.proto1|
+00000000  16 03 01 01 4c 01 00 01  48 03 03 44 3b 24 ee 2f  |....L...H..D;$./|
+00000010  63 3d ca bd 3e c5 bf a2  24 f1 59 c3 54 dc f0 43  |c=..>...$.Y.T..C|
+00000020  15 c4 51 f2 29 ea 1b ce  2c fe af 00 00 b6 c0 30  |..Q.)...,......0|
+00000030  c0 2c c0 28 c0 24 c0 14  c0 0a 00 a5 00 a3 00 a1  |.,.(.$..........|
+00000040  00 9f 00 6b 00 6a 00 69  00 68 00 39 00 38 00 37  |...k.j.i.h.9.8.7|
+00000050  00 36 00 88 00 87 00 86  00 85 c0 32 c0 2e c0 2a  |.6.........2...*|
+00000060  c0 26 c0 0f c0 05 00 9d  00 3d 00 35 00 84 c0 2f  |.&.......=.5.../|
+00000070  c0 2b c0 27 c0 23 c0 13  c0 09 00 a4 00 a2 00 a0  |.+.'.#..........|
+00000080  00 9e 00 67 00 40 00 3f  00 3e 00 33 00 32 00 31  |...g.@.?.>.3.2.1|
+00000090  00 30 00 9a 00 99 00 98  00 97 00 45 00 44 00 43  |.0.........E.D.C|
+000000a0  00 42 c0 31 c0 2d c0 29  c0 25 c0 0e c0 04 00 9c  |.B.1.-.).%......|
+000000b0  00 3c 00 2f 00 96 00 41  00 07 c0 11 c0 07 c0 0c  |.<./...A........|
+000000c0  c0 02 00 05 00 04 c0 12  c0 08 00 16 00 13 00 10  |................|
+000000d0  00 0d c0 0d c0 03 00 0a  00 15 00 12 00 0f 00 0c  |................|
+000000e0  00 09 00 ff 01 00 00 69  00 0b 00 04 03 00 01 02  |.......i........|
+000000f0  00 0a 00 1c 00 1a 00 17  00 19 00 1c 00 1b 00 18  |................|
+00000100  00 1a 00 16 00 0e 00 0d  00 0b 00 0c 00 09 00 0a  |................|
+00000110  00 23 00 00 00 0d 00 20  00 1e 06 01 06 02 06 03  |.#..... ........|
+00000120  05 01 05 02 05 03 04 01  04 02 04 03 03 01 03 02  |................|
+00000130  03 03 02 01 02 02 02 03  00 0f 00 01 01 00 10 00  |................|
+00000140  10 00 0e 06 70 72 6f 74  6f 32 06 70 72 6f 74 6f  |....proto2.proto|
+00000150  31                                                |1|
 >>> Flow 2 (server to client)
 00000000  16 03 03 00 42 02 00 00  3e 03 03 00 00 00 00 00  |....B...>.......|
 00000010  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
-00000020  00 00 00 00 00 00 00 00  00 00 00 00 c0 14 00 00  |................|
+00000020  00 00 00 00 00 00 00 00  00 00 00 00 c0 30 00 00  |.............0..|
 00000030  16 00 23 00 00 ff 01 00  01 00 00 10 00 09 00 07  |..#.............|
-00000040  06 70 72 6f 74 6f 31 16  03 03 02 be 0b 00 02 ba  |.proto1.........|
-00000050  00 02 b7 00 02 b4 30 82  02 b0 30 82 02 19 a0 03  |......0...0.....|
-00000060  02 01 02 02 09 00 85 b0  bb a4 8a 7f b8 ca 30 0d  |..............0.|
-00000070  06 09 2a 86 48 86 f7 0d  01 01 05 05 00 30 45 31  |..*.H........0E1|
-00000080  0b 30 09 06 03 55 04 06  13 02 41 55 31 13 30 11  |.0...U....AU1.0.|
-00000090  06 03 55 04 08 13 0a 53  6f 6d 65 2d 53 74 61 74  |..U....Some-Stat|
-000000a0  65 31 21 30 1f 06 03 55  04 0a 13 18 49 6e 74 65  |e1!0...U....Inte|
-000000b0  72 6e 65 74 20 57 69 64  67 69 74 73 20 50 74 79  |rnet Widgits Pty|
-000000c0  20 4c 74 64 30 1e 17 0d  31 30 30 34 32 34 30 39  | Ltd0...10042409|
-000000d0  30 39 33 38 5a 17 0d 31  31 30 34 32 34 30 39 30  |0938Z..110424090|
-000000e0  39 33 38 5a 30 45 31 0b  30 09 06 03 55 04 06 13  |938Z0E1.0...U...|
-000000f0  02 41 55 31 13 30 11 06  03 55 04 08 13 0a 53 6f  |.AU1.0...U....So|
-00000100  6d 65 2d 53 74 61 74 65  31 21 30 1f 06 03 55 04  |me-State1!0...U.|
-00000110  0a 13 18 49 6e 74 65 72  6e 65 74 20 57 69 64 67  |...Internet Widg|
-00000120  69 74 73 20 50 74 79 20  4c 74 64 30 81 9f 30 0d  |its Pty Ltd0..0.|
-00000130  06 09 2a 86 48 86 f7 0d  01 01 01 05 00 03 81 8d  |..*.H...........|
-00000140  00 30 81 89 02 81 81 00  bb 79 d6 f5 17 b5 e5 bf  |.0.......y......|
-00000150  46 10 d0 dc 69 be e6 2b  07 43 5a d0 03 2d 8a 7a  |F...i..+.CZ..-.z|
-00000160  43 85 b7 14 52 e7 a5 65  4c 2c 78 b8 23 8c b5 b4  |C...R..eL,x.#...|
-00000170  82 e5 de 1f 95 3b 7e 62  a5 2c a5 33 d6 fe 12 5c  |.....;~b.,.3...\|
-00000180  7a 56 fc f5 06 bf fa 58  7b 26 3f b5 cd 04 d3 d0  |zV.....X{&?.....|
-00000190  c9 21 96 4a c7 f4 54 9f  5a bf ef 42 71 00 fe 18  |.!.J..T.Z..Bq...|
-000001a0  99 07 7f 7e 88 7d 7d f1  04 39 c4 a2 2e db 51 c9  |...~.}}..9....Q.|
-000001b0  7c e3 c0 4c 3b 32 66 01  cf af b1 1d b8 71 9a 1d  ||..L;2f......q..|
-000001c0  db db 89 6b ae da 2d 79  02 03 01 00 01 a3 81 a7  |...k..-y........|
-000001d0  30 81 a4 30 1d 06 03 55  1d 0e 04 16 04 14 b1 ad  |0..0...U........|
-000001e0  e2 85 5a cf cb 28 db 69  ce 23 69 de d3 26 8e 18  |..Z..(.i.#i..&..|
-000001f0  88 39 30 75 06 03 55 1d  23 04 6e 30 6c 80 14 b1  |.90u..U.#.n0l...|
-00000200  ad e2 85 5a cf cb 28 db  69 ce 23 69 de d3 26 8e  |...Z..(.i.#i..&.|
-00000210  18 88 39 a1 49 a4 47 30  45 31 0b 30 09 06 03 55  |..9.I.G0E1.0...U|
-00000220  04 06 13 02 41 55 31 13  30 11 06 03 55 04 08 13  |....AU1.0...U...|
-00000230  0a 53 6f 6d 65 2d 53 74  61 74 65 31 21 30 1f 06  |.Some-State1!0..|
-00000240  03 55 04 0a 13 18 49 6e  74 65 72 6e 65 74 20 57  |.U....Internet W|
-00000250  69 64 67 69 74 73 20 50  74 79 20 4c 74 64 82 09  |idgits Pty Ltd..|
-00000260  00 85 b0 bb a4 8a 7f b8  ca 30 0c 06 03 55 1d 13  |.........0...U..|
-00000270  04 05 30 03 01 01 ff 30  0d 06 09 2a 86 48 86 f7  |..0....0...*.H..|
-00000280  0d 01 01 05 05 00 03 81  81 00 08 6c 45 24 c7 6b  |...........lE$.k|
-00000290  b1 59 ab 0c 52 cc f2 b0  14 d7 87 9d 7a 64 75 b5  |.Y..R.......zdu.|
-000002a0  5a 95 66 e4 c5 2b 8e ae  12 66 1f eb 4f 38 b3 6e  |Z.f..+...f..O8.n|
-000002b0  60 d3 92 fd f7 41 08 b5  25 13 b1 18 7a 24 fb 30  |`....A..%...z$.0|
-000002c0  1d ba ed 98 b9 17 ec e7  d7 31 59 db 95 d3 1d 78  |.........1Y....x|
-000002d0  ea 50 56 5c d5 82 5a 2d  5a 5f 33 c4 b6 d8 c9 75  |.PV\..Z-Z_3....u|
-000002e0  90 96 8c 0f 52 98 b5 cd  98 1f 89 20 5f f2 a0 1c  |....R...... _...|
-000002f0  a3 1b 96 94 dd a9 fd 57  e9 70 e8 26 6d 71 99 9b  |.......W.p.&mq..|
-00000300  26 6e 38 50 29 6c 90 a7  bd d9 16 03 03 00 cd 0c  |&n8P)l..........|
-00000310  00 00 c9 03 00 17 41 04  1e 18 37 ef 0d 19 51 88  |......A...7...Q.|
-00000320  35 75 71 b5 e5 54 5b 12  2e 8f 09 67 fd a7 24 20  |5uq..T[....g..$ |
-00000330  3e b2 56 1c ce 97 28 5e  f8 2b 2d 4f 9e f1 07 9f  |>.V...(^.+-O....|
-00000340  6c 4b 5b 83 56 e2 32 42  e9 58 b6 d7 49 a6 b5 68  |lK[.V.2B.X..I..h|
-00000350  1a 41 03 56 6b dc 5a 89  04 01 00 80 2d a0 6e 47  |.A.Vk.Z.....-.nG|
-00000360  93 a2 19 17 32 f5 42 58  93 f6 4f d4 e9 4d a4 0f  |....2.BX..O..M..|
-00000370  fe 4e d7 2c 62 b6 fb 83  37 a3 09 60 4b 69 e2 4c  |.N.,b...7..`Ki.L|
-00000380  fc b8 4c d1 a6 9a 89 a0  c5 76 f5 62 b7 e8 eb c2  |..L......v.b....|
-00000390  fa 0f 0e 61 86 bc 70 da  13 72 8d 87 94 16 9a 8d  |...a..p..r......|
-000003a0  5f 80 82 92 77 37 4f 9e  55 5d dc 35 42 a3 75 5c  |_...w7O.U].5B.u\|
-000003b0  ec a4 58 78 66 97 97 da  49 67 2e b6 7e 11 de fb  |..Xxf...Ig..~...|
-000003c0  e3 8f e8 bf 1d 91 1e 91  20 1b 2a df c6 58 e4 82  |........ .*..X..|
-000003d0  ce 37 dd 6f a5 ac 51 3d  65 db 3f f5 16 03 03 00  |.7.o..Q=e.?.....|
-000003e0  04 0e 00 00 00                                    |.....|
+00000040  06 70 72 6f 74 6f 31 16  03 03 02 71 0b 00 02 6d  |.proto1....q...m|
+00000050  00 02 6a 00 02 67 30 82  02 63 30 82 01 cc a0 03  |..j..g0..c0.....|
+00000060  02 01 02 02 09 00 a2 73  00 0c 81 00 cb f3 30 0d  |.......s......0.|
+00000070  06 09 2a 86 48 86 f7 0d  01 01 0b 05 00 30 2b 31  |..*.H........0+1|
+00000080  17 30 15 06 03 55 04 0a  13 0e 47 6f 6f 67 6c 65  |.0...U....Google|
+00000090  20 54 45 53 54 49 4e 47  31 10 30 0e 06 03 55 04  | TESTING1.0...U.|
+000000a0  03 13 07 47 6f 20 52 6f  6f 74 30 1e 17 0d 31 35  |...Go Root0...15|
+000000b0  30 31 30 31 30 30 30 30  30 30 5a 17 0d 32 35 30  |0101000000Z..250|
+000000c0  31 30 31 30 30 30 30 30  30 5a 30 26 31 17 30 15  |101000000Z0&1.0.|
+000000d0  06 03 55 04 0a 13 0e 47  6f 6f 67 6c 65 20 54 45  |..U....Google TE|
+000000e0  53 54 49 4e 47 31 0b 30  09 06 03 55 04 03 13 02  |STING1.0...U....|
+000000f0  47 6f 30 81 9f 30 0d 06  09 2a 86 48 86 f7 0d 01  |Go0..0...*.H....|
+00000100  01 01 05 00 03 81 8d 00  30 81 89 02 81 81 00 af  |........0.......|
+00000110  87 88 f6 20 1b 95 65 6c  14 ab 44 05 af 3b 45 14  |... ..el..D..;E.|
+00000120  e3 b7 6d fd 00 63 4d 95  7f fe 6a 62 35 86 c0 4a  |..m..cM...jb5..J|
+00000130  f9 18 7c f6 aa 25 5e 7a  64 31 66 00 ba f4 8e 92  |..|..%^zd1f.....|
+00000140  af c7 6b d8 76 d4 f3 5f  41 cb 6e 56 15 97 1b 97  |..k.v.._A.nV....|
+00000150  c1 3c 12 39 21 66 3d 2b  16 d1 bc db 1c c0 a7 da  |.<.9!f=+........|
+00000160  b7 ca ad ba da cb d5 21  50 ec de 8d ab d1 6b 81  |.......!P.....k.|
+00000170  4b 89 02 f3 c4 be c1 6c  89 b1 44 84 bd 21 d1 04  |K......l..D..!..|
+00000180  7d 9d 16 4d f9 82 15 f6  ef fa d6 09 47 f2 fb 02  |}..M........G...|
+00000190  03 01 00 01 a3 81 93 30  81 90 30 0e 06 03 55 1d  |.......0..0...U.|
+000001a0  0f 01 01 ff 04 04 03 02  05 a0 30 1d 06 03 55 1d  |..........0...U.|
+000001b0  25 04 16 30 14 06 08 2b  06 01 05 05 07 03 01 06  |%..0...+........|
+000001c0  08 2b 06 01 05 05 07 03  02 30 0c 06 03 55 1d 13  |.+.......0...U..|
+000001d0  01 01 ff 04 02 30 00 30  19 06 03 55 1d 0e 04 12  |.....0.0...U....|
+000001e0  04 10 12 50 8d 89 6f 1b  d1 dc 54 4d 6e cb 69 5e  |...P..o...TMn.i^|
+000001f0  06 f4 30 1b 06 03 55 1d  23 04 14 30 12 80 10 bf  |..0...U.#..0....|
+00000200  3d b6 a9 66 f2 b8 40 cf  ea b4 03 78 48 1a 41 30  |=..f..@....xH.A0|
+00000210  19 06 03 55 1d 11 04 12  30 10 82 0e 65 78 61 6d  |...U....0...exam|
+00000220  70 6c 65 2e 67 6f 6c 61  6e 67 30 0d 06 09 2a 86  |ple.golang0...*.|
+00000230  48 86 f7 0d 01 01 0b 05  00 03 81 81 00 92 7c af  |H.............|.|
+00000240  91 55 12 18 96 59 31 a6  48 40 d5 2d d5 ee bb 02  |.U...Y1.H@.-....|
+00000250  a0 f5 c2 1e 7c 9b b3 30  7d 3c dc 76 da 4f 3d c0  |....|..0}<.v.O=.|
+00000260  fa ae 2d 33 24 6b 03 7b  1b 67 59 11 21 b5 11 bc  |..-3$k.{.gY.!...|
+00000270  77 b9 d9 e0 6e a8 2d 2e  35 fa 64 5f 22 3e 63 10  |w...n.-.5.d_">c.|
+00000280  6b be ff 14 86 6d 0d f0  15 31 a8 14 38 1e 3b 84  |k....m...1..8.;.|
+00000290  87 2c cb 98 ed 51 76 b9  b1 4f dd db 9b 84 04 86  |.,...Qv..O......|
+000002a0  40 fa 51 dd ba b4 8d eb  e3 46 de 46 b9 4f 86 c7  |@.Q......F.F.O..|
+000002b0  f9 a4 c2 41 34 ac cc f6  ea b0 ab 39 18 16 03 03  |...A4......9....|
+000002c0  00 cd 0c 00 00 c9 03 00  17 41 04 1e 18 37 ef 0d  |.........A...7..|
+000002d0  19 51 88 35 75 71 b5 e5  54 5b 12 2e 8f 09 67 fd  |.Q.5uq..T[....g.|
+000002e0  a7 24 20 3e b2 56 1c ce  97 28 5e f8 2b 2d 4f 9e  |.$ >.V...(^.+-O.|
+000002f0  f1 07 9f 6c 4b 5b 83 56  e2 32 42 e9 58 b6 d7 49  |...lK[.V.2B.X..I|
+00000300  a6 b5 68 1a 41 03 56 6b  dc 5a 89 05 01 00 80 40  |..h.A.Vk.Z.....@|
+00000310  93 b2 1f 79 3d 56 c0 ae  94 87 c0 a7 28 ef 1d 15  |...y=V......(...|
+00000320  be 4b fb 66 e0 60 2c a3  57 ee 56 7d d6 89 b8 8e  |.K.f.`,.W.V}....|
+00000330  8f 0f 3f 1b c6 9f a4 1d  34 60 b6 9c e9 9b a9 27  |..?.....4`.....'|
+00000340  d0 45 7b 04 71 2d db 9c  67 1b d5 d4 fe 19 69 59  |.E{.q-..g.....iY|
+00000350  71 8a 35 75 33 a8 c9 f2  4d c4 8f 40 17 a7 25 53  |q.5u3...M..@..%S|
+00000360  57 c5 cd ee df a9 3b a3  61 ab e2 a2 ca de 5c 08  |W.....;.a.....\.|
+00000370  3d 5b a2 ef cd c8 bc 16  1f 1d 0f 83 9e b7 20 f5  |=[............ .|
+00000380  89 3f 09 ba 2e da 12 34  81 e5 2f 8d 3c 90 89 16  |.?.....4../.<...|
+00000390  03 03 00 04 0e 00 00 00                           |........|
 >>> Flow 3 (client to server)
-00000000  16 03 03 00 46 10 00 00  42 41 04 f3 fc ea d8 50  |....F...BA.....P|
-00000010  e6 15 b0 e7 11 c7 6d ee  09 ad 80 d5 54 eb 4f 62  |......m.....T.Ob|
-00000020  7d bb a7 2d 28 0c 66 33  42 09 cf 2b 58 f8 58 41  |}..-(.f3B..+X.XA|
-00000030  bd 46 51 0a f0 7d 8c 0c  98 9e 26 77 20 fd 5e c1  |.FQ..}....&w .^.|
-00000040  a9 b3 e5 c3 6c 05 97 e3  81 fd db 14 03 03 00 01  |....l...........|
-00000050  01 16 03 03 00 40 02 2a  28 41 e3 9c 5d 45 d4 45  |.....@.*(A..]E.E|
-00000060  51 8c 7a c0 ba b1 8e a4  84 2c f3 83 cd c4 55 5c  |Q.z......,....U\|
-00000070  d6 5c 6f 72 ab 89 7a c6  d7 9c 2a 54 f0 c4 20 ee  |.\or..z...*T.. .|
-00000080  37 74 9b b6 8c f7 e4 37  2c eb d4 9f 5c 5e 55 a0  |7t.....7,...\^U.|
-00000090  e2 5a fe 1e c8 67                                 |.Z...g|
+00000000  16 03 03 00 46 10 00 00  42 41 04 8b a2 de a6 1e  |....F...BA......|
+00000010  d9 22 3c 03 4a be 49 2f  40 e3 1e e0 b4 76 7f 78  |."<.J.I/@....v.x|
+00000020  96 22 8d 8d c9 45 3b d8  7a ce e3 16 3d 37 ec 80  |."...E;.z...=7..|
+00000030  aa 3f d5 19 de c1 2c 7b  7f eb 3c fc 5d c3 52 3b  |.?....,{..<.].R;|
+00000040  d4 22 25 1c c7 1f 39 c5  23 bd 73 14 03 03 00 01  |."%...9.#.s.....|
+00000050  01 16 03 03 00 28 c8 53  0a ad c2 f6 7e 18 08 a3  |.....(.S....~...|
+00000060  29 27 20 1c 6c 1d 6c d8  8f 05 31 de e6 ab 7f 22  |)' .l.l...1...."|
+00000070  93 6a fb ef b0 f8 43 a9  d3 4f 9d 04 b5 9a        |.j....C..O....|
 >>> Flow 4 (server to client)
-00000000  16 03 03 00 72 04 00 00  6e 00 00 00 00 00 68 00  |....r...n.....h.|
-00000010  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 65  |...............e|
-00000020  ea 8b c0 ef ba 59 31 75  33 96 f1 f8 c9 e1 ef 30  |.....Y1u3......0|
-00000030  00 a3 a9 1d ab c8 4b 29  94 f2 c8 c8 8d 03 57 ab  |......K)......W.|
-00000040  56 df 0f 4e 0d 30 13 09  c9 e4 fa 51 4e b3 26 ad  |V..N.0.....QN.&.|
-00000050  43 9f ae 62 d5 59 23 05  9b 69 8f 5b a8 ba 39 f1  |C..b.Y#..i.[..9.|
-00000060  90 84 35 bf 8f 8d d5 39  93 98 ee b9 75 03 3f 91  |..5....9....u.?.|
-00000070  e8 56 0b cb 44 a6 7a 14  03 03 00 01 01 16 03 03  |.V..D.z.........|
-00000080  00 40 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |.@..............|
-00000090  00 00 f9 a0 8e 23 34 f1  61 15 a8 4e ae c4 f3 2a  |.....#4.a..N...*|
-000000a0  a6 f8 ee 1b 65 c4 c0 ff  93 14 74 ed 82 ae 48 a8  |....e.....t...H.|
-000000b0  42 fb a9 24 5d dd fd 98  b8 65 73 03 88 99 e1 ed  |B..$]....es.....|
-000000c0  02 95 17 03 03 00 40 00  00 00 00 00 00 00 00 00  |......@.........|
-000000d0  00 00 00 00 00 00 00 b9  b3 f5 41 84 3b 2a a9 c3  |..........A.;*..|
-000000e0  9c e3 d4 38 90 76 c1 8c  f0 4f 10 1b 04 b5 07 fe  |...8.v...O......|
-000000f0  79 3d 7b 77 a4 17 0f 4e  df 64 70 70 9e 34 8e b6  |y={w...N.dpp.4..|
-00000100  db b2 b6 fd 41 fe b3 15  03 03 00 30 00 00 00 00  |....A......0....|
-00000110  00 00 00 00 00 00 00 00  00 00 00 00 02 73 de fe  |.............s..|
-00000120  fa 4b 69 6d 30 69 79 96  7e 4f 2f 04 67 36 96 27  |.Kim0iy.~O/.g6.'|
-00000130  67 23 2b dc 7a c4 6c 34  ea fc 79 fd              |g#+.z.l4..y.|
+00000000  16 03 03 00 82 04 00 00  7e 00 00 00 00 00 78 50  |........~.....xP|
+00000010  46 ad c1 db a8 38 86 7b  2b bb fd d0 c3 42 3e 00  |F....8.{+....B>.|
+00000020  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 94  |................|
+00000030  6f ec 80 83 61 8e d9 64  ac a2 ee 3b 69 31 79 e1  |o...a..d...;i1y.|
+00000040  53 0a 92 1d aa 23 09 c2  49 02 2d 0d 1d c1 63 d6  |S....#..I.-...c.|
+00000050  21 56 c7 24 02 28 d5 f1  11 b0 e7 1b 4a 7c 55 af  |!V.$.(......J|U.|
+00000060  1b c8 32 4c 5b 33 94 b0  ed b0 2f 52 c4 52 81 ee  |..2L[3..../R.R..|
+00000070  60 6f 66 fb f5 db dd f9  1e 30 11 d4 ca 75 0e 2b  |`of......0...u.+|
+00000080  ff d0 e5 f2 68 a4 e7 14  03 03 00 01 01 16 03 03  |....h...........|
+00000090  00 28 00 00 00 00 00 00  00 00 67 3b 4a ba f3 27  |.(........g;J..'|
+000000a0  c8 45 94 68 36 5a 40 e1  dc 67 9b d4 45 58 e9 24  |.E.h6Z@..g..EX.$|
+000000b0  31 85 3a f8 5d cb 84 8e  64 05 17 03 03 00 25 00  |1.:.]...d.....%.|
+000000c0  00 00 00 00 00 00 01 35  d9 ba 0a e2 3e fd a2 80  |.......5....>...|
+000000d0  10 0e 38 7b ad 85 85 48  6a 2a ab 2a 46 c3 59 96  |..8{...Hj*.*F.Y.|
+000000e0  fd 75 11 5d 15 03 03 00  1a 00 00 00 00 00 00 00  |.u.]............|
+000000f0  02 0b 4d a5 89 4d 86 47  14 60 27 f8 09 bc c9 4d  |..M..M.G.`'....M|
+00000100  00 31 cb                                          |.1.|
diff --git a/third_party/gofrontend/libgo/go/crypto/tls/testdata/Server-TLSv12-ALPN-NoMatch b/third_party/gofrontend/libgo/go/crypto/tls/testdata/Server-TLSv12-ALPN-NoMatch
index db5881b..af75445 100644
--- a/third_party/gofrontend/libgo/go/crypto/tls/testdata/Server-TLSv12-ALPN-NoMatch
+++ b/third_party/gofrontend/libgo/go/crypto/tls/testdata/Server-TLSv12-ALPN-NoMatch
@@ -1,121 +1,108 @@
 >>> Flow 1 (client to server)
-00000000  16 03 01 01 8a 01 00 01  86 03 03 0a a8 82 53 61  |..............Sa|
-00000010  68 e0 83 91 71 36 f9 c1  19 ff e8 09 fc 21 9f 03  |h...q6.......!..|
-00000020  31 f3 87 4a 04 8c 3d c2  6e 00 32 00 00 d6 c0 30  |1..J..=.n.2....0|
-00000030  c0 2c c0 28 c0 24 c0 14  c0 0a c0 22 c0 21 c0 20  |.,.(.$.....".!. |
-00000040  00 a5 00 a3 00 a1 00 9f  00 6b 00 6a 00 69 00 68  |.........k.j.i.h|
-00000050  00 39 00 38 00 37 00 36  00 88 00 87 00 86 00 85  |.9.8.7.6........|
-00000060  c0 32 c0 2e c0 2a c0 26  c0 0f c0 05 00 9d 00 3d  |.2...*.&.......=|
-00000070  00 35 00 84 c0 2f c0 2b  c0 27 c0 23 c0 13 c0 09  |.5.../.+.'.#....|
-00000080  c0 1f c0 1e c0 1d 00 a4  00 a2 00 a0 00 9e 00 67  |...............g|
-00000090  00 40 00 3f 00 3e 00 33  00 32 00 31 00 30 00 9a  |.@.?.>.3.2.1.0..|
-000000a0  00 99 00 98 00 97 00 45  00 44 00 43 00 42 c0 31  |.......E.D.C.B.1|
-000000b0  c0 2d c0 29 c0 25 c0 0e  c0 04 00 9c 00 3c 00 2f  |.-.).%.......<./|
-000000c0  00 96 00 41 00 07 c0 11  c0 07 c0 0c c0 02 00 05  |...A............|
-000000d0  00 04 c0 12 c0 08 c0 1c  c0 1b c0 1a 00 16 00 13  |................|
-000000e0  00 10 00 0d c0 0d c0 03  00 0a 00 15 00 12 00 0f  |................|
-000000f0  00 0c 00 09 00 14 00 11  00 0e 00 0b 00 08 00 06  |................|
-00000100  00 03 00 ff 01 00 00 87  00 0b 00 04 03 00 01 02  |................|
-00000110  00 0a 00 3a 00 38 00 0e  00 0d 00 19 00 1c 00 0b  |...:.8..........|
-00000120  00 0c 00 1b 00 18 00 09  00 0a 00 1a 00 16 00 17  |................|
-00000130  00 08 00 06 00 07 00 14  00 15 00 04 00 05 00 12  |................|
-00000140  00 13 00 01 00 02 00 03  00 0f 00 10 00 11 00 23  |...............#|
-00000150  00 00 00 0d 00 20 00 1e  06 01 06 02 06 03 05 01  |..... ..........|
-00000160  05 02 05 03 04 01 04 02  04 03 03 01 03 02 03 03  |................|
-00000170  02 01 02 02 02 03 00 0f  00 01 01 00 10 00 10 00  |................|
-00000180  0e 06 70 72 6f 74 6f 32  06 70 72 6f 74 6f 31     |..proto2.proto1|
+00000000  16 03 01 01 4c 01 00 01  48 03 03 1d 1a f7 e5 ad  |....L...H.......|
+00000010  a4 5c fd 61 b4 c2 25 33  c7 b9 fc fb 2b a5 4b fe  |.\.a..%3....+.K.|
+00000020  16 84 55 4b 9f 68 73 61  b8 92 4d 00 00 b6 c0 30  |..UK.hsa..M....0|
+00000030  c0 2c c0 28 c0 24 c0 14  c0 0a 00 a5 00 a3 00 a1  |.,.(.$..........|
+00000040  00 9f 00 6b 00 6a 00 69  00 68 00 39 00 38 00 37  |...k.j.i.h.9.8.7|
+00000050  00 36 00 88 00 87 00 86  00 85 c0 32 c0 2e c0 2a  |.6.........2...*|
+00000060  c0 26 c0 0f c0 05 00 9d  00 3d 00 35 00 84 c0 2f  |.&.......=.5.../|
+00000070  c0 2b c0 27 c0 23 c0 13  c0 09 00 a4 00 a2 00 a0  |.+.'.#..........|
+00000080  00 9e 00 67 00 40 00 3f  00 3e 00 33 00 32 00 31  |...g.@.?.>.3.2.1|
+00000090  00 30 00 9a 00 99 00 98  00 97 00 45 00 44 00 43  |.0.........E.D.C|
+000000a0  00 42 c0 31 c0 2d c0 29  c0 25 c0 0e c0 04 00 9c  |.B.1.-.).%......|
+000000b0  00 3c 00 2f 00 96 00 41  00 07 c0 11 c0 07 c0 0c  |.<./...A........|
+000000c0  c0 02 00 05 00 04 c0 12  c0 08 00 16 00 13 00 10  |................|
+000000d0  00 0d c0 0d c0 03 00 0a  00 15 00 12 00 0f 00 0c  |................|
+000000e0  00 09 00 ff 01 00 00 69  00 0b 00 04 03 00 01 02  |.......i........|
+000000f0  00 0a 00 1c 00 1a 00 17  00 19 00 1c 00 1b 00 18  |................|
+00000100  00 1a 00 16 00 0e 00 0d  00 0b 00 0c 00 09 00 0a  |................|
+00000110  00 23 00 00 00 0d 00 20  00 1e 06 01 06 02 06 03  |.#..... ........|
+00000120  05 01 05 02 05 03 04 01  04 02 04 03 03 01 03 02  |................|
+00000130  03 03 02 01 02 02 02 03  00 0f 00 01 01 00 10 00  |................|
+00000140  10 00 0e 06 70 72 6f 74  6f 32 06 70 72 6f 74 6f  |....proto2.proto|
+00000150  31                                                |1|
 >>> Flow 2 (server to client)
 00000000  16 03 03 00 35 02 00 00  31 03 03 00 00 00 00 00  |....5...1.......|
 00000010  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
-00000020  00 00 00 00 00 00 00 00  00 00 00 00 c0 14 00 00  |................|
-00000030  09 00 23 00 00 ff 01 00  01 00 16 03 03 02 be 0b  |..#.............|
-00000040  00 02 ba 00 02 b7 00 02  b4 30 82 02 b0 30 82 02  |.........0...0..|
-00000050  19 a0 03 02 01 02 02 09  00 85 b0 bb a4 8a 7f b8  |................|
-00000060  ca 30 0d 06 09 2a 86 48  86 f7 0d 01 01 05 05 00  |.0...*.H........|
-00000070  30 45 31 0b 30 09 06 03  55 04 06 13 02 41 55 31  |0E1.0...U....AU1|
-00000080  13 30 11 06 03 55 04 08  13 0a 53 6f 6d 65 2d 53  |.0...U....Some-S|
-00000090  74 61 74 65 31 21 30 1f  06 03 55 04 0a 13 18 49  |tate1!0...U....I|
-000000a0  6e 74 65 72 6e 65 74 20  57 69 64 67 69 74 73 20  |nternet Widgits |
-000000b0  50 74 79 20 4c 74 64 30  1e 17 0d 31 30 30 34 32  |Pty Ltd0...10042|
-000000c0  34 30 39 30 39 33 38 5a  17 0d 31 31 30 34 32 34  |4090938Z..110424|
-000000d0  30 39 30 39 33 38 5a 30  45 31 0b 30 09 06 03 55  |090938Z0E1.0...U|
-000000e0  04 06 13 02 41 55 31 13  30 11 06 03 55 04 08 13  |....AU1.0...U...|
-000000f0  0a 53 6f 6d 65 2d 53 74  61 74 65 31 21 30 1f 06  |.Some-State1!0..|
-00000100  03 55 04 0a 13 18 49 6e  74 65 72 6e 65 74 20 57  |.U....Internet W|
-00000110  69 64 67 69 74 73 20 50  74 79 20 4c 74 64 30 81  |idgits Pty Ltd0.|
-00000120  9f 30 0d 06 09 2a 86 48  86 f7 0d 01 01 01 05 00  |.0...*.H........|
-00000130  03 81 8d 00 30 81 89 02  81 81 00 bb 79 d6 f5 17  |....0.......y...|
-00000140  b5 e5 bf 46 10 d0 dc 69  be e6 2b 07 43 5a d0 03  |...F...i..+.CZ..|
-00000150  2d 8a 7a 43 85 b7 14 52  e7 a5 65 4c 2c 78 b8 23  |-.zC...R..eL,x.#|
-00000160  8c b5 b4 82 e5 de 1f 95  3b 7e 62 a5 2c a5 33 d6  |........;~b.,.3.|
-00000170  fe 12 5c 7a 56 fc f5 06  bf fa 58 7b 26 3f b5 cd  |..\zV.....X{&?..|
-00000180  04 d3 d0 c9 21 96 4a c7  f4 54 9f 5a bf ef 42 71  |....!.J..T.Z..Bq|
-00000190  00 fe 18 99 07 7f 7e 88  7d 7d f1 04 39 c4 a2 2e  |......~.}}..9...|
-000001a0  db 51 c9 7c e3 c0 4c 3b  32 66 01 cf af b1 1d b8  |.Q.|..L;2f......|
-000001b0  71 9a 1d db db 89 6b ae  da 2d 79 02 03 01 00 01  |q.....k..-y.....|
-000001c0  a3 81 a7 30 81 a4 30 1d  06 03 55 1d 0e 04 16 04  |...0..0...U.....|
-000001d0  14 b1 ad e2 85 5a cf cb  28 db 69 ce 23 69 de d3  |.....Z..(.i.#i..|
-000001e0  26 8e 18 88 39 30 75 06  03 55 1d 23 04 6e 30 6c  |&...90u..U.#.n0l|
-000001f0  80 14 b1 ad e2 85 5a cf  cb 28 db 69 ce 23 69 de  |......Z..(.i.#i.|
-00000200  d3 26 8e 18 88 39 a1 49  a4 47 30 45 31 0b 30 09  |.&...9.I.G0E1.0.|
-00000210  06 03 55 04 06 13 02 41  55 31 13 30 11 06 03 55  |..U....AU1.0...U|
-00000220  04 08 13 0a 53 6f 6d 65  2d 53 74 61 74 65 31 21  |....Some-State1!|
-00000230  30 1f 06 03 55 04 0a 13  18 49 6e 74 65 72 6e 65  |0...U....Interne|
-00000240  74 20 57 69 64 67 69 74  73 20 50 74 79 20 4c 74  |t Widgits Pty Lt|
-00000250  64 82 09 00 85 b0 bb a4  8a 7f b8 ca 30 0c 06 03  |d...........0...|
-00000260  55 1d 13 04 05 30 03 01  01 ff 30 0d 06 09 2a 86  |U....0....0...*.|
-00000270  48 86 f7 0d 01 01 05 05  00 03 81 81 00 08 6c 45  |H.............lE|
-00000280  24 c7 6b b1 59 ab 0c 52  cc f2 b0 14 d7 87 9d 7a  |$.k.Y..R.......z|
-00000290  64 75 b5 5a 95 66 e4 c5  2b 8e ae 12 66 1f eb 4f  |du.Z.f..+...f..O|
-000002a0  38 b3 6e 60 d3 92 fd f7  41 08 b5 25 13 b1 18 7a  |8.n`....A..%...z|
-000002b0  24 fb 30 1d ba ed 98 b9  17 ec e7 d7 31 59 db 95  |$.0.........1Y..|
-000002c0  d3 1d 78 ea 50 56 5c d5  82 5a 2d 5a 5f 33 c4 b6  |..x.PV\..Z-Z_3..|
-000002d0  d8 c9 75 90 96 8c 0f 52  98 b5 cd 98 1f 89 20 5f  |..u....R...... _|
-000002e0  f2 a0 1c a3 1b 96 94 dd  a9 fd 57 e9 70 e8 26 6d  |..........W.p.&m|
-000002f0  71 99 9b 26 6e 38 50 29  6c 90 a7 bd d9 16 03 03  |q..&n8P)l.......|
-00000300  00 cd 0c 00 00 c9 03 00  17 41 04 1e 18 37 ef 0d  |.........A...7..|
-00000310  19 51 88 35 75 71 b5 e5  54 5b 12 2e 8f 09 67 fd  |.Q.5uq..T[....g.|
-00000320  a7 24 20 3e b2 56 1c ce  97 28 5e f8 2b 2d 4f 9e  |.$ >.V...(^.+-O.|
-00000330  f1 07 9f 6c 4b 5b 83 56  e2 32 42 e9 58 b6 d7 49  |...lK[.V.2B.X..I|
-00000340  a6 b5 68 1a 41 03 56 6b  dc 5a 89 04 01 00 80 b9  |..h.A.Vk.Z......|
-00000350  0f 79 8a 16 f4 da 8f 27  b4 16 fc c0 51 db ae d1  |.y.....'....Q...|
-00000360  af 79 77 d5 d5 a2 13 05  45 20 cc eb ac ed cb 30  |.yw.....E .....0|
-00000370  32 2e 2c bd fa 1c 4d b5  32 a6 37 43 c8 5c 2d f8  |2.,...M.2.7C.\-.|
-00000380  6e 85 f5 cd 54 92 29 ad  13 7d d5 9e 8c 1d b7 d0  |n...T.)..}......|
-00000390  c1 c7 3d e8 ba 4a 0f 9a  a6 3e 25 5f 27 62 b1 00  |..=..J...>%_'b..|
-000003a0  91 d9 23 48 3f 10 fe c5  e3 07 9a 58 57 6d cc 10  |..#H?......XWm..|
-000003b0  3b f8 1a d5 6e 8b 1f 03  6f 82 84 98 b5 f7 71 5d  |;...n...o.....q]|
-000003c0  c2 ad 60 14 c1 88 07 5a  3d 99 fd a8 c9 9a 03 16  |..`....Z=.......|
-000003d0  03 03 00 04 0e 00 00 00                           |........|
+00000020  00 00 00 00 00 00 00 00  00 00 00 00 c0 30 00 00  |.............0..|
+00000030  09 00 23 00 00 ff 01 00  01 00 16 03 03 02 71 0b  |..#...........q.|
+00000040  00 02 6d 00 02 6a 00 02  67 30 82 02 63 30 82 01  |..m..j..g0..c0..|
+00000050  cc a0 03 02 01 02 02 09  00 a2 73 00 0c 81 00 cb  |..........s.....|
+00000060  f3 30 0d 06 09 2a 86 48  86 f7 0d 01 01 0b 05 00  |.0...*.H........|
+00000070  30 2b 31 17 30 15 06 03  55 04 0a 13 0e 47 6f 6f  |0+1.0...U....Goo|
+00000080  67 6c 65 20 54 45 53 54  49 4e 47 31 10 30 0e 06  |gle TESTING1.0..|
+00000090  03 55 04 03 13 07 47 6f  20 52 6f 6f 74 30 1e 17  |.U....Go Root0..|
+000000a0  0d 31 35 30 31 30 31 30  30 30 30 30 30 5a 17 0d  |.150101000000Z..|
+000000b0  32 35 30 31 30 31 30 30  30 30 30 30 5a 30 26 31  |250101000000Z0&1|
+000000c0  17 30 15 06 03 55 04 0a  13 0e 47 6f 6f 67 6c 65  |.0...U....Google|
+000000d0  20 54 45 53 54 49 4e 47  31 0b 30 09 06 03 55 04  | TESTING1.0...U.|
+000000e0  03 13 02 47 6f 30 81 9f  30 0d 06 09 2a 86 48 86  |...Go0..0...*.H.|
+000000f0  f7 0d 01 01 01 05 00 03  81 8d 00 30 81 89 02 81  |...........0....|
+00000100  81 00 af 87 88 f6 20 1b  95 65 6c 14 ab 44 05 af  |...... ..el..D..|
+00000110  3b 45 14 e3 b7 6d fd 00  63 4d 95 7f fe 6a 62 35  |;E...m..cM...jb5|
+00000120  86 c0 4a f9 18 7c f6 aa  25 5e 7a 64 31 66 00 ba  |..J..|..%^zd1f..|
+00000130  f4 8e 92 af c7 6b d8 76  d4 f3 5f 41 cb 6e 56 15  |.....k.v.._A.nV.|
+00000140  97 1b 97 c1 3c 12 39 21  66 3d 2b 16 d1 bc db 1c  |....<.9!f=+.....|
+00000150  c0 a7 da b7 ca ad ba da  cb d5 21 50 ec de 8d ab  |..........!P....|
+00000160  d1 6b 81 4b 89 02 f3 c4  be c1 6c 89 b1 44 84 bd  |.k.K......l..D..|
+00000170  21 d1 04 7d 9d 16 4d f9  82 15 f6 ef fa d6 09 47  |!..}..M........G|
+00000180  f2 fb 02 03 01 00 01 a3  81 93 30 81 90 30 0e 06  |..........0..0..|
+00000190  03 55 1d 0f 01 01 ff 04  04 03 02 05 a0 30 1d 06  |.U...........0..|
+000001a0  03 55 1d 25 04 16 30 14  06 08 2b 06 01 05 05 07  |.U.%..0...+.....|
+000001b0  03 01 06 08 2b 06 01 05  05 07 03 02 30 0c 06 03  |....+.......0...|
+000001c0  55 1d 13 01 01 ff 04 02  30 00 30 19 06 03 55 1d  |U.......0.0...U.|
+000001d0  0e 04 12 04 10 12 50 8d  89 6f 1b d1 dc 54 4d 6e  |......P..o...TMn|
+000001e0  cb 69 5e 06 f4 30 1b 06  03 55 1d 23 04 14 30 12  |.i^..0...U.#..0.|
+000001f0  80 10 bf 3d b6 a9 66 f2  b8 40 cf ea b4 03 78 48  |...=..f..@....xH|
+00000200  1a 41 30 19 06 03 55 1d  11 04 12 30 10 82 0e 65  |.A0...U....0...e|
+00000210  78 61 6d 70 6c 65 2e 67  6f 6c 61 6e 67 30 0d 06  |xample.golang0..|
+00000220  09 2a 86 48 86 f7 0d 01  01 0b 05 00 03 81 81 00  |.*.H............|
+00000230  92 7c af 91 55 12 18 96  59 31 a6 48 40 d5 2d d5  |.|..U...Y1.H@.-.|
+00000240  ee bb 02 a0 f5 c2 1e 7c  9b b3 30 7d 3c dc 76 da  |.......|..0}<.v.|
+00000250  4f 3d c0 fa ae 2d 33 24  6b 03 7b 1b 67 59 11 21  |O=...-3$k.{.gY.!|
+00000260  b5 11 bc 77 b9 d9 e0 6e  a8 2d 2e 35 fa 64 5f 22  |...w...n.-.5.d_"|
+00000270  3e 63 10 6b be ff 14 86  6d 0d f0 15 31 a8 14 38  |>c.k....m...1..8|
+00000280  1e 3b 84 87 2c cb 98 ed  51 76 b9 b1 4f dd db 9b  |.;..,...Qv..O...|
+00000290  84 04 86 40 fa 51 dd ba  b4 8d eb e3 46 de 46 b9  |...@.Q......F.F.|
+000002a0  4f 86 c7 f9 a4 c2 41 34  ac cc f6 ea b0 ab 39 18  |O.....A4......9.|
+000002b0  16 03 03 00 cd 0c 00 00  c9 03 00 17 41 04 1e 18  |............A...|
+000002c0  37 ef 0d 19 51 88 35 75  71 b5 e5 54 5b 12 2e 8f  |7...Q.5uq..T[...|
+000002d0  09 67 fd a7 24 20 3e b2  56 1c ce 97 28 5e f8 2b  |.g..$ >.V...(^.+|
+000002e0  2d 4f 9e f1 07 9f 6c 4b  5b 83 56 e2 32 42 e9 58  |-O....lK[.V.2B.X|
+000002f0  b6 d7 49 a6 b5 68 1a 41  03 56 6b dc 5a 89 05 01  |..I..h.A.Vk.Z...|
+00000300  00 80 36 d2 96 c8 27 66  d8 bd 6c 28 29 30 b3 be  |..6...'f..l()0..|
+00000310  0a bb b2 fe 9d c3 59 47  34 cf de fe f4 ab 5d 79  |......YG4.....]y|
+00000320  24 a9 9d c9 b5 e9 50 6a  3b 96 e3 29 cb d7 37 06  |$.....Pj;..)..7.|
+00000330  19 08 88 15 29 c2 55 03  62 75 1d 35 c2 8e 25 a2  |....).U.bu.5..%.|
+00000340  86 20 bf 18 46 15 81 f2  74 4b bb dd 3d e3 a5 f6  |. ..F...tK..=...|
+00000350  28 18 41 89 c8 39 13 f9  c0 88 fd cc f0 6e 9e 3d  |(.A..9.......n.=|
+00000360  cb 29 ad 26 5b d1 e6 11  5c 64 7d b6 df d7 39 87  |.).&[...\d}...9.|
+00000370  24 df 9f 62 17 ef f2 b3  3a b3 88 a4 f0 91 ea f2  |$..b....:.......|
+00000380  5d c9 16 03 03 00 04 0e  00 00 00                 |]..........|
 >>> Flow 3 (client to server)
-00000000  16 03 03 00 46 10 00 00  42 41 04 76 aa 4e b9 f9  |....F...BA.v.N..|
-00000010  68 85 81 74 7c d9 f9 64  7f bd 09 83 08 5b 4f 76  |h..t|..d.....[Ov|
-00000020  6e be 79 b6 4e 97 17 63  e4 b5 1c 77 e5 85 76 8a  |n.y.N..c...w..v.|
-00000030  5d 9f f1 21 88 ec f9 a7  7c 41 af f9 c5 fe 11 81  |]..!....|A......|
-00000040  11 51 8e a7 20 33 5f cf  e7 90 90 14 03 03 00 01  |.Q.. 3_.........|
-00000050  01 16 03 03 00 40 44 3e  32 01 71 ac 5a b5 1f 2c  |.....@D>2.q.Z..,|
-00000060  37 d9 4b 70 72 91 89 d4  d7 c2 c3 e7 ff dc 72 2a  |7.Kpr.........r*|
-00000070  ba f5 30 b0 e9 dd 48 10  3d cd 98 48 a3 e3 ca de  |..0...H.=..H....|
-00000080  15 0e 90 8e e5 04 14 74  42 b8 b0 12 cc 68 7b 7d  |.......tB....h{}|
-00000090  6c 43 72 60 05 0d                                 |lCr`..|
+00000000  16 03 03 00 46 10 00 00  42 41 04 b0 22 15 73 fc  |....F...BA..".s.|
+00000010  1c fd 24 4a 36 69 8a be  ac bd 72 30 bb 6b e1 9b  |..$J6i....r0.k..|
+00000020  42 e8 56 7a 86 b1 8d cb  9c 3e 2d 63 13 57 a8 13  |B.Vz.....>-c.W..|
+00000030  71 3b a2 01 86 af f8 76  40 0b 44 4f 0a 0f 5a da  |q;.....v@.DO..Z.|
+00000040  31 36 3b 13 c0 10 6c 96  64 a7 24 14 03 03 00 01  |16;...l.d.$.....|
+00000050  01 16 03 03 00 28 10 2d  45 93 5c 37 34 d9 2a a0  |.....(.-E.\74.*.|
+00000060  b6 37 13 bc a6 1f 0c ce  2e 55 c1 ad 36 b8 60 72  |.7.......U..6.`r|
+00000070  81 cb 1a 7a 5b 26 49 ad  77 ef 62 e8 fc 00        |...z[&I.w.b...|
 >>> Flow 4 (server to client)
-00000000  16 03 03 00 72 04 00 00  6e 00 00 00 00 00 68 00  |....r...n.....h.|
-00000010  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 65  |...............e|
-00000020  ea 8b c0 ef ba 12 45 17  61 24 cd d2 4c 22 bb 3b  |......E.a$..L".;|
-00000030  e3 0e d0 ff 83 e9 7c b7  8f 10 3c 16 1c fc c2 44  |......|...<....D|
-00000040  ef 45 f8 27 30 56 db ea  eb ae f5 b6 17 b2 ef f9  |.E.'0V..........|
-00000050  96 0d 2d db e4 59 23 0a  fc fa e3 13 48 57 e5 b3  |..-..Y#.....HW..|
-00000060  3a d1 f5 5e ca ef d7 3f  7b b5 f4 69 85 c3 bd da  |:..^...?{..i....|
-00000070  fd 9c 50 05 2f 86 ce 14  03 03 00 01 01 16 03 03  |..P./...........|
-00000080  00 40 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |.@..............|
-00000090  00 00 60 25 1c ed 6f c6  a5 bd b2 29 39 4e 09 d1  |..`%..o....)9N..|
-000000a0  64 cc 75 cd df 91 a8 90  9d 03 aa 92 07 f2 d0 8a  |d.u.............|
-000000b0  60 bb 3e 85 21 22 fe f8  dc 52 3c 4e 82 77 14 14  |`.>.!"...R<N.w..|
-000000c0  0f 1f 17 03 03 00 40 00  00 00 00 00 00 00 00 00  |......@.........|
-000000d0  00 00 00 00 00 00 00 0b  87 12 62 3e e5 3e 7d 74  |..........b>.>}t|
-000000e0  0d ac c4 a9 df 67 1c 5a  ad 3e 01 34 03 88 2f 39  |.....g.Z.>.4../9|
-000000f0  f7 3c 06 e4 f6 81 43 66  b1 1b ed a5 e5 b6 a8 43  |.<....Cf.......C|
-00000100  7f 36 2f b2 da 45 9a 15  03 03 00 30 00 00 00 00  |.6/..E.....0....|
-00000110  00 00 00 00 00 00 00 00  00 00 00 00 fa 63 4e c5  |.............cN.|
-00000120  77 89 71 56 e3 0a cf 98  da 2f 89 8f 74 8e 76 24  |w.qV...../..t.v$|
-00000130  e2 40 a5 9f 29 1b b2 11  ef 7a 55 7f              |.@..)....zU.|
+00000000  16 03 03 00 82 04 00 00  7e 00 00 00 00 00 78 50  |........~.....xP|
+00000010  46 ad c1 db a8 38 86 7b  2b bb fd d0 c3 42 3e 00  |F....8.{+....B>.|
+00000020  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 94  |................|
+00000030  6f ec 80 83 61 05 33 d2  9d 95 89 7b 28 54 50 50  |o...a.3....{(TPP|
+00000040  b3 3c 99 5c 82 ab cf 88  24 e8 48 81 db 4a 22 79  |.<.\....$.H..J"y|
+00000050  0b fa 33 50 ed 82 a1 7c  33 0e f2 ff 6d a7 d6 88  |..3P...|3...m...|
+00000060  29 65 74 e3 27 33 94 97  66 0c 86 ce fc ca 0e 2a  |)et.'3..f......*|
+00000070  96 fa fe 19 a3 01 64 d9  4d 8e 58 95 5b 74 a6 aa  |......d.M.X.[t..|
+00000080  f4 9f c1 34 97 2d e5 14  03 03 00 01 01 16 03 03  |...4.-..........|
+00000090  00 28 00 00 00 00 00 00  00 00 4d 56 6d d5 6f cc  |.(........MVm.o.|
+000000a0  3d d4 85 32 3c 07 ea 3c  52 61 88 8e dd d5 d3 d0  |=..2<..<Ra......|
+000000b0  f9 4e 1b b1 c1 d1 67 cb  1a e8 17 03 03 00 25 00  |.N....g.......%.|
+000000c0  00 00 00 00 00 00 01 c3  43 ab 0c ab 59 30 e9 d4  |........C...Y0..|
+000000d0  eb 65 c2 7f 9a 5a 1e 09  06 a4 9d 69 bb 3f 0b 06  |.e...Z.....i.?..|
+000000e0  87 b8 09 39 15 03 03 00  1a 00 00 00 00 00 00 00  |...9............|
+000000f0  02 c2 6f f4 88 f0 7a 59  a6 49 3e 44 a3 7b 6e 36  |..o...zY.I>D.{n6|
+00000100  ae 66 87                                          |.f.|
diff --git a/third_party/gofrontend/libgo/go/crypto/tls/testdata/Server-TLSv12-CipherSuiteCertPreferenceECDSA b/third_party/gofrontend/libgo/go/crypto/tls/testdata/Server-TLSv12-CipherSuiteCertPreferenceECDSA
index 0ab8b8d..344d973 100644
--- a/third_party/gofrontend/libgo/go/crypto/tls/testdata/Server-TLSv12-CipherSuiteCertPreferenceECDSA
+++ b/third_party/gofrontend/libgo/go/crypto/tls/testdata/Server-TLSv12-CipherSuiteCertPreferenceECDSA
@@ -1,91 +1,98 @@
 >>> Flow 1 (client to server)
-00000000  16 03 01 00 ca 01 00 00  c6 03 03 53 04 f1 3f 5f  |...........S..?_|
-00000010  f4 ef 1f b3 41 0b 54 e4  4d 56 0a 31 22 b8 5c 73  |....A.T.MV.1".\s|
-00000020  a3 cb b5 b2 9d 43 f1 83  bc d3 bd 00 00 32 c0 30  |.....C.......2.0|
-00000030  c0 2c c0 28 c0 24 c0 14  c0 0a c0 22 c0 21 00 a3  |.,.(.$.....".!..|
-00000040  00 9f 00 6b 00 6a 00 39  00 38 00 88 00 87 c0 32  |...k.j.9.8.....2|
-00000050  c0 2e c0 2a c0 26 c0 0f  c0 05 00 9d 00 3d 00 35  |...*.&.......=.5|
-00000060  01 00 00 6b 00 0b 00 04  03 00 01 02 00 0a 00 34  |...k...........4|
-00000070  00 32 00 0e 00 0d 00 19  00 0b 00 0c 00 18 00 09  |.2..............|
-00000080  00 0a 00 16 00 17 00 08  00 06 00 07 00 14 00 15  |................|
-00000090  00 04 00 05 00 12 00 13  00 01 00 02 00 03 00 0f  |................|
-000000a0  00 10 00 11 00 0d 00 22  00 20 06 01 06 02 06 03  |.......". ......|
-000000b0  05 01 05 02 05 03 04 01  04 02 04 03 03 01 03 02  |................|
-000000c0  03 03 02 01 02 02 02 03  01 01 00 0f 00 01 01     |...............|
+00000000  16 03 01 01 34 01 00 01  30 03 03 78 08 b2 d4 18  |....4...0..x....|
+00000010  8e b1 6b a2 d2 e0 c6 41  02 c5 93 f1 b9 60 94 e8  |..k....A.....`..|
+00000020  f2 64 6c 97 50 2d 24 a3  cd c0 36 00 00 b6 c0 30  |.dl.P-$...6....0|
+00000030  c0 2c c0 28 c0 24 c0 14  c0 0a 00 a5 00 a3 00 a1  |.,.(.$..........|
+00000040  00 9f 00 6b 00 6a 00 69  00 68 00 39 00 38 00 37  |...k.j.i.h.9.8.7|
+00000050  00 36 00 88 00 87 00 86  00 85 c0 32 c0 2e c0 2a  |.6.........2...*|
+00000060  c0 26 c0 0f c0 05 00 9d  00 3d 00 35 00 84 c0 2f  |.&.......=.5.../|
+00000070  c0 2b c0 27 c0 23 c0 13  c0 09 00 a4 00 a2 00 a0  |.+.'.#..........|
+00000080  00 9e 00 67 00 40 00 3f  00 3e 00 33 00 32 00 31  |...g.@.?.>.3.2.1|
+00000090  00 30 00 9a 00 99 00 98  00 97 00 45 00 44 00 43  |.0.........E.D.C|
+000000a0  00 42 c0 31 c0 2d c0 29  c0 25 c0 0e c0 04 00 9c  |.B.1.-.).%......|
+000000b0  00 3c 00 2f 00 96 00 41  00 07 c0 11 c0 07 c0 0c  |.<./...A........|
+000000c0  c0 02 00 05 00 04 c0 12  c0 08 00 16 00 13 00 10  |................|
+000000d0  00 0d c0 0d c0 03 00 0a  00 15 00 12 00 0f 00 0c  |................|
+000000e0  00 09 00 ff 01 00 00 51  00 0b 00 04 03 00 01 02  |.......Q........|
+000000f0  00 0a 00 1c 00 1a 00 17  00 19 00 1c 00 1b 00 18  |................|
+00000100  00 1a 00 16 00 0e 00 0d  00 0b 00 0c 00 09 00 0a  |................|
+00000110  00 0d 00 20 00 1e 06 01  06 02 06 03 05 01 05 02  |... ............|
+00000120  05 03 04 01 04 02 04 03  03 01 03 02 03 03 02 01  |................|
+00000130  02 02 02 03 00 0f 00 01  01                       |.........|
 >>> Flow 2 (server to client)
-00000000  16 03 03 00 2a 02 00 00  26 03 03 00 00 00 00 00  |....*...&.......|
+00000000  16 03 03 00 31 02 00 00  2d 03 03 00 00 00 00 00  |....1...-.......|
 00000010  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
-00000020  00 00 00 00 00 00 00 00  00 00 00 00 c0 0a 00 16  |................|
-00000030  03 03 02 0e 0b 00 02 0a  00 02 07 00 02 04 30 82  |..............0.|
-00000040  02 00 30 82 01 62 02 09  00 b8 bf 2d 47 a0 d2 eb  |..0..b.....-G...|
-00000050  f4 30 09 06 07 2a 86 48  ce 3d 04 01 30 45 31 0b  |.0...*.H.=..0E1.|
-00000060  30 09 06 03 55 04 06 13  02 41 55 31 13 30 11 06  |0...U....AU1.0..|
-00000070  03 55 04 08 13 0a 53 6f  6d 65 2d 53 74 61 74 65  |.U....Some-State|
-00000080  31 21 30 1f 06 03 55 04  0a 13 18 49 6e 74 65 72  |1!0...U....Inter|
-00000090  6e 65 74 20 57 69 64 67  69 74 73 20 50 74 79 20  |net Widgits Pty |
-000000a0  4c 74 64 30 1e 17 0d 31  32 31 31 32 32 31 35 30  |Ltd0...121122150|
-000000b0  36 33 32 5a 17 0d 32 32  31 31 32 30 31 35 30 36  |632Z..2211201506|
-000000c0  33 32 5a 30 45 31 0b 30  09 06 03 55 04 06 13 02  |32Z0E1.0...U....|
-000000d0  41 55 31 13 30 11 06 03  55 04 08 13 0a 53 6f 6d  |AU1.0...U....Som|
-000000e0  65 2d 53 74 61 74 65 31  21 30 1f 06 03 55 04 0a  |e-State1!0...U..|
-000000f0  13 18 49 6e 74 65 72 6e  65 74 20 57 69 64 67 69  |..Internet Widgi|
-00000100  74 73 20 50 74 79 20 4c  74 64 30 81 9b 30 10 06  |ts Pty Ltd0..0..|
-00000110  07 2a 86 48 ce 3d 02 01  06 05 2b 81 04 00 23 03  |.*.H.=....+...#.|
-00000120  81 86 00 04 00 c4 a1 ed  be 98 f9 0b 48 73 36 7e  |............Hs6~|
-00000130  c3 16 56 11 22 f2 3d 53  c3 3b 4d 21 3d cd 6b 75  |..V.".=S.;M!=.ku|
-00000140  e6 f6 b0 dc 9a df 26 c1  bc b2 87 f0 72 32 7c b3  |......&.....r2|.|
-00000150  64 2f 1c 90 bc ea 68 23  10 7e fe e3 25 c0 48 3a  |d/....h#.~..%.H:|
-00000160  69 e0 28 6d d3 37 00 ef  04 62 dd 0d a0 9c 70 62  |i.(m.7...b....pb|
-00000170  83 d8 81 d3 64 31 aa 9e  97 31 bd 96 b0 68 c0 9b  |....d1...1...h..|
-00000180  23 de 76 64 3f 1a 5c 7f  e9 12 0e 58 58 b6 5f 70  |#.vd?.\....XX._p|
-00000190  dd 9b d8 ea d5 d7 f5 d5  cc b9 b6 9f 30 66 5b 66  |............0f[f|
-000001a0  9a 20 e2 27 e5 bf fe 3b  30 09 06 07 2a 86 48 ce  |. .'...;0...*.H.|
-000001b0  3d 04 01 03 81 8c 00 30  81 88 02 42 01 88 a2 4f  |=......0...B...O|
-000001c0  eb e2 45 c5 48 7d 1b ac  f5 ed 98 9d ae 47 70 c0  |..E.H}.......Gp.|
-000001d0  5e 1b b6 2f bd f1 b6 4d  b7 61 40 d3 11 a2 ce ee  |^../...M.a@.....|
-000001e0  0b 7e 92 7e ff 76 9d c3  3b 7e a5 3f ce fa 10 e2  |.~.~.v..;~.?....|
-000001f0  59 ec 47 2d 7c ac da 4e  97 0e 15 a0 6f d0 02 42  |Y.G-|..N....o..B|
-00000200  01 4d fc be 67 13 9c 2d  05 0e bd 3f a3 8c 25 c1  |.M..g..-...?..%.|
-00000210  33 13 83 0d 94 06 bb d4  37 7a f6 ec 7a c9 86 2e  |3.......7z..z...|
-00000220  dd d7 11 69 7f 85 7c 56  de fb 31 78 2b e4 c7 78  |...i..|V..1x+..x|
-00000230  0d ae cb be 9e 4e 36 24  31 7b 6a 0f 39 95 12 07  |.....N6$1{j.9...|
-00000240  8f 2a 16 03 03 00 d8 0c  00 00 d4 03 00 17 41 04  |.*............A.|
-00000250  1e 18 37 ef 0d 19 51 88  35 75 71 b5 e5 54 5b 12  |..7...Q.5uq..T[.|
-00000260  2e 8f 09 67 fd a7 24 20  3e b2 56 1c ce 97 28 5e  |...g..$ >.V...(^|
-00000270  f8 2b 2d 4f 9e f1 07 9f  6c 4b 5b 83 56 e2 32 42  |.+-O....lK[.V.2B|
-00000280  e9 58 b6 d7 49 a6 b5 68  1a 41 03 56 6b dc 5a 89  |.X..I..h.A.Vk.Z.|
-00000290  04 03 00 8b 30 81 88 02  42 00 c6 85 8e 06 b7 04  |....0...B.......|
-000002a0  04 e9 cd 9e 3e cb 66 23  95 b4 42 9c 64 81 39 05  |....>.f#..B.d.9.|
-000002b0  3f b5 21 f8 28 af 60 6b  4d 3d ba a1 4b 5e 77 ef  |?.!.(.`kM=..K^w.|
-000002c0  e7 59 28 fe 1d c1 27 a2  ff a8 de 33 48 b3 c1 85  |.Y(...'....3H...|
-000002d0  6a 42 9b f9 7e 7e 31 c2  e5 bd 66 02 42 00 ad 7d  |jB..~~1...f.B..}|
-000002e0  06 35 ab ec 8d ac d4 ba  1b 49 5e 05 5f f0 97 93  |.5.......I^._...|
-000002f0  82 b8 2b 8d 91 98 63 8e  b4 14 62 db 1e c9 2b 64  |..+...c...b...+d|
-00000300  e9 e6 bf 15 5b 67 c2 40  90 c6 1f b7 92 db 4b f6  |....[g.@......K.|
-00000310  f4 db ae 82 f1 4f 02 75  52 40 38 10 ff 35 f0 16  |.....O.uR@8..5..|
-00000320  03 03 00 04 0e 00 00 00                           |........|
+00000020  00 00 00 00 00 00 00 00  00 00 00 00 c0 0a 00 00  |................|
+00000030  05 ff 01 00 01 00 16 03  03 02 0e 0b 00 02 0a 00  |................|
+00000040  02 07 00 02 04 30 82 02  00 30 82 01 62 02 09 00  |.....0...0..b...|
+00000050  b8 bf 2d 47 a0 d2 eb f4  30 09 06 07 2a 86 48 ce  |..-G....0...*.H.|
+00000060  3d 04 01 30 45 31 0b 30  09 06 03 55 04 06 13 02  |=..0E1.0...U....|
+00000070  41 55 31 13 30 11 06 03  55 04 08 13 0a 53 6f 6d  |AU1.0...U....Som|
+00000080  65 2d 53 74 61 74 65 31  21 30 1f 06 03 55 04 0a  |e-State1!0...U..|
+00000090  13 18 49 6e 74 65 72 6e  65 74 20 57 69 64 67 69  |..Internet Widgi|
+000000a0  74 73 20 50 74 79 20 4c  74 64 30 1e 17 0d 31 32  |ts Pty Ltd0...12|
+000000b0  31 31 32 32 31 35 30 36  33 32 5a 17 0d 32 32 31  |1122150632Z..221|
+000000c0  31 32 30 31 35 30 36 33  32 5a 30 45 31 0b 30 09  |120150632Z0E1.0.|
+000000d0  06 03 55 04 06 13 02 41  55 31 13 30 11 06 03 55  |..U....AU1.0...U|
+000000e0  04 08 13 0a 53 6f 6d 65  2d 53 74 61 74 65 31 21  |....Some-State1!|
+000000f0  30 1f 06 03 55 04 0a 13  18 49 6e 74 65 72 6e 65  |0...U....Interne|
+00000100  74 20 57 69 64 67 69 74  73 20 50 74 79 20 4c 74  |t Widgits Pty Lt|
+00000110  64 30 81 9b 30 10 06 07  2a 86 48 ce 3d 02 01 06  |d0..0...*.H.=...|
+00000120  05 2b 81 04 00 23 03 81  86 00 04 00 c4 a1 ed be  |.+...#..........|
+00000130  98 f9 0b 48 73 36 7e c3  16 56 11 22 f2 3d 53 c3  |...Hs6~..V.".=S.|
+00000140  3b 4d 21 3d cd 6b 75 e6  f6 b0 dc 9a df 26 c1 bc  |;M!=.ku......&..|
+00000150  b2 87 f0 72 32 7c b3 64  2f 1c 90 bc ea 68 23 10  |...r2|.d/....h#.|
+00000160  7e fe e3 25 c0 48 3a 69  e0 28 6d d3 37 00 ef 04  |~..%.H:i.(m.7...|
+00000170  62 dd 0d a0 9c 70 62 83  d8 81 d3 64 31 aa 9e 97  |b....pb....d1...|
+00000180  31 bd 96 b0 68 c0 9b 23  de 76 64 3f 1a 5c 7f e9  |1...h..#.vd?.\..|
+00000190  12 0e 58 58 b6 5f 70 dd  9b d8 ea d5 d7 f5 d5 cc  |..XX._p.........|
+000001a0  b9 b6 9f 30 66 5b 66 9a  20 e2 27 e5 bf fe 3b 30  |...0f[f. .'...;0|
+000001b0  09 06 07 2a 86 48 ce 3d  04 01 03 81 8c 00 30 81  |...*.H.=......0.|
+000001c0  88 02 42 01 88 a2 4f eb  e2 45 c5 48 7d 1b ac f5  |..B...O..E.H}...|
+000001d0  ed 98 9d ae 47 70 c0 5e  1b b6 2f bd f1 b6 4d b7  |....Gp.^../...M.|
+000001e0  61 40 d3 11 a2 ce ee 0b  7e 92 7e ff 76 9d c3 3b  |a@......~.~.v..;|
+000001f0  7e a5 3f ce fa 10 e2 59  ec 47 2d 7c ac da 4e 97  |~.?....Y.G-|..N.|
+00000200  0e 15 a0 6f d0 02 42 01  4d fc be 67 13 9c 2d 05  |...o..B.M..g..-.|
+00000210  0e bd 3f a3 8c 25 c1 33  13 83 0d 94 06 bb d4 37  |..?..%.3.......7|
+00000220  7a f6 ec 7a c9 86 2e dd  d7 11 69 7f 85 7c 56 de  |z..z......i..|V.|
+00000230  fb 31 78 2b e4 c7 78 0d  ae cb be 9e 4e 36 24 31  |.1x+..x.....N6$1|
+00000240  7b 6a 0f 39 95 12 07 8f  2a 16 03 03 00 d8 0c 00  |{j.9....*.......|
+00000250  00 d4 03 00 17 41 04 1e  18 37 ef 0d 19 51 88 35  |.....A...7...Q.5|
+00000260  75 71 b5 e5 54 5b 12 2e  8f 09 67 fd a7 24 20 3e  |uq..T[....g..$ >|
+00000270  b2 56 1c ce 97 28 5e f8  2b 2d 4f 9e f1 07 9f 6c  |.V...(^.+-O....l|
+00000280  4b 5b 83 56 e2 32 42 e9  58 b6 d7 49 a6 b5 68 1a  |K[.V.2B.X..I..h.|
+00000290  41 03 56 6b dc 5a 89 05  03 00 8b 30 81 88 02 42  |A.Vk.Z.....0...B|
+000002a0  00 91 b4 4a f2 9d 13 a1  6d 3b ee 46 2f 3b 97 50  |...J....m;.F/;.P|
+000002b0  b9 3e 28 7a 51 7a 8b 3b  a6 16 03 d6 1f 92 0a ec  |.>(zQz.;........|
+000002c0  5b 9b b5 48 98 ce d8 22  bd 7d eb cb 14 7b 14 73  |[..H...".}...{.s|
+000002d0  2d 5f 01 8c dc 5a 63 34  92 4e 59 4a 90 f9 b1 c9  |-_...Zc4.NYJ....|
+000002e0  d8 18 02 42 01 89 e4 e4  39 d0 52 d1 70 19 fe d7  |...B....9.R.p...|
+000002f0  c6 70 10 36 94 1e 45 fd  b4 03 37 79 c7 db cf 6d  |.p.6..E...7y...m|
+00000300  33 5d 80 fe 04 de d1 78  bf c4 dd cf 91 82 57 14  |3].....x......W.|
+00000310  14 09 e3 2d dd d2 78 9c  53 cc 1f f7 40 6c 4a 59  |...-..x.S...@lJY|
+00000320  49 a8 a1 06 24 18 16 03  03 00 04 0e 00 00 00     |I...$..........|
 >>> Flow 3 (client to server)
-00000000  16 03 03 00 46 10 00 00  42 41 04 d8 94 c4 05 26  |....F...BA.....&|
-00000010  76 29 2d 0e ec 47 b6 50  d5 a3 da 2a ba 02 11 37  |v)-..G.P...*...7|
-00000020  3d ef e6 2a db d0 47 47  a7 9a 5f 43 2d 98 78 26  |=..*..GG.._C-.x&|
-00000030  81 e2 f1 ba fe f7 66 c6  61 cb c1 b7 60 62 34 a5  |......f.a...`b4.|
-00000040  78 67 50 3d 9a 0e 4a 8c  8f d7 10 14 03 03 00 01  |xgP=..J.........|
-00000050  01 16 03 03 00 40 5e 46  b0 5d 30 f6 da 8f 9e 67  |.....@^F.]0....g|
-00000060  f5 3e bd fe c9 b8 53 b2  10 d5 7c 0e 34 e3 93 6d  |.>....S...|.4..m|
-00000070  0e 8e 8a 2b df fb 9a 0f  a5 23 55 e7 0a 4b e2 d3  |...+.....#U..K..|
-00000080  db 15 e8 52 74 26 78 b3  b0 56 65 63 ac ae 1e c0  |...Rt&x..Vec....|
-00000090  0b f4 92 56 a9 04                                 |...V..|
+00000000  16 03 03 00 46 10 00 00  42 41 04 66 37 3a ce 68  |....F...BA.f7:.h|
+00000010  23 0f b2 d0 cb 20 24 26  37 d5 84 46 4a 2e 59 80  |#.... $&7..FJ.Y.|
+00000020  87 b3 10 7e 36 fd af 7c  99 07 99 dd 18 af 6d 7c  |...~6..|......m||
+00000030  b5 b2 b7 93 45 95 d9 98  1a 13 5b a2 12 e8 b7 95  |....E.....[.....|
+00000040  ed a1 3a 6d aa 8f fc b6  b5 b4 41 14 03 03 00 01  |..:m......A.....|
+00000050  01 16 03 03 00 40 b0 12  69 00 a4 3a 6d bd 56 40  |.....@..i..:m.V@|
+00000060  6e 9d 5e a8 1b 0f 59 c5  09 48 b2 07 d8 bc 7b 02  |n.^...Y..H....{.|
+00000070  70 61 f6 1b a9 27 55 8c  16 4d 69 4c ca 31 30 9f  |pa...'U..MiL.10.|
+00000080  d3 62 ba d4 1b 11 ee 0a  a0 f3 61 be c6 64 c3 dc  |.b........a..d..|
+00000090  97 50 47 27 ed 09                                 |.PG'..|
 >>> Flow 4 (server to client)
 00000000  14 03 03 00 01 01 16 03  03 00 40 00 00 00 00 00  |..........@.....|
-00000010  00 00 00 00 00 00 00 00  00 00 00 16 a9 63 0a 99  |.............c..|
-00000020  21 8a fc 5c b3 ee 05 71  4e 75 c0 d9 40 54 0d 3e  |!..\...qNu..@T.>|
-00000030  4e 5d 44 b7 4b 5d a9 e7  5a 30 ed b6 d5 08 50 b1  |N]D.K]..Z0....P.|
-00000040  e8 8c 54 eb 1b 39 7a f9  3b ac 2e 17 03 03 00 40  |..T..9z.;......@|
+00000010  00 00 00 00 00 00 00 00  00 00 00 09 34 9a eb 7c  |............4..||
+00000020  6a 6d 6a 02 7b 50 14 b8  f7 b0 93 30 ea 0b 61 4a  |jmj.{P.....0..aJ|
+00000030  0b 75 10 39 41 78 46 9d  ba 8e d3 e9 e4 ab dc 1f  |.u.9AxF.........|
+00000040  c9 43 95 e8 f9 d6 3a d3  5d 7d 09 17 03 03 00 40  |.C....:.]}.....@|
 00000050  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
-00000060  96 03 20 2b 20 c4 c1 9a  76 7b f3 96 bd 33 ed e6  |.. + ...v{...3..|
-00000070  38 48 ea 53 d5 e0 62 b5  7e 1a 36 a8 dd 9f 2d 4b  |8H.S..b.~.6...-K|
-00000080  06 0d ae f6 bc 99 14 b3  93 14 27 63 e2 a0 c8 76  |..........'c...v|
+00000060  b4 64 88 d5 53 f9 1e 47  d4 d8 c4 fa 0e c2 76 a6  |.d..S..G......v.|
+00000070  ed 5c 17 ba ea 76 72 cb  c5 73 a3 c5 44 21 3c 40  |.\...vr..s..D!<@|
+00000080  33 27 09 37 73 3b 0e a3  7b 95 72 10 8d 74 85 19  |3'.7s;..{.r..t..|
 00000090  15 03 03 00 30 00 00 00  00 00 00 00 00 00 00 00  |....0...........|
-000000a0  00 00 00 00 00 48 af e1  e4 11 e1 b7 03 19 b0 e3  |.....H..........|
-000000b0  e6 a9 66 d8 ac af aa 03  f6 0d 51 df 9a 27 78 3a  |..f.......Q..'x:|
-000000c0  56 5a 03 1a 4c                                    |VZ..L|
+000000a0  00 00 00 00 00 b3 c0 05  e9 ec 05 06 52 ef 09 b7  |............R...|
+000000b0  52 29 04 88 ed 11 bb bd  36 a3 0f ce 2c 55 a2 87  |R)......6...,U..|
+000000c0  7e 2b 0c aa 83                                    |~+...|
diff --git a/third_party/gofrontend/libgo/go/crypto/tls/testdata/Server-TLSv12-CipherSuiteCertPreferenceRSA b/third_party/gofrontend/libgo/go/crypto/tls/testdata/Server-TLSv12-CipherSuiteCertPreferenceRSA
index 88abb15..10624c0 100644
--- a/third_party/gofrontend/libgo/go/crypto/tls/testdata/Server-TLSv12-CipherSuiteCertPreferenceRSA
+++ b/third_party/gofrontend/libgo/go/crypto/tls/testdata/Server-TLSv12-CipherSuiteCertPreferenceRSA
@@ -1,101 +1,104 @@
 >>> Flow 1 (client to server)
-00000000  16 03 01 00 ca 01 00 00  c6 03 03 53 04 f1 3f cc  |...........S..?.|
-00000010  41 74 00 07 cb ae 3b 30  79 48 51 60 41 a3 8c ab  |At....;0yHQ`A...|
-00000020  dc 76 f9 74 52 1e c5 fb  a9 69 c2 00 00 32 c0 30  |.v.tR....i...2.0|
-00000030  c0 2c c0 28 c0 24 c0 14  c0 0a c0 22 c0 21 00 a3  |.,.(.$.....".!..|
-00000040  00 9f 00 6b 00 6a 00 39  00 38 00 88 00 87 c0 32  |...k.j.9.8.....2|
-00000050  c0 2e c0 2a c0 26 c0 0f  c0 05 00 9d 00 3d 00 35  |...*.&.......=.5|
-00000060  01 00 00 6b 00 0b 00 04  03 00 01 02 00 0a 00 34  |...k...........4|
-00000070  00 32 00 0e 00 0d 00 19  00 0b 00 0c 00 18 00 09  |.2..............|
-00000080  00 0a 00 16 00 17 00 08  00 06 00 07 00 14 00 15  |................|
-00000090  00 04 00 05 00 12 00 13  00 01 00 02 00 03 00 0f  |................|
-000000a0  00 10 00 11 00 0d 00 22  00 20 06 01 06 02 06 03  |.......". ......|
-000000b0  05 01 05 02 05 03 04 01  04 02 04 03 03 01 03 02  |................|
-000000c0  03 03 02 01 02 02 02 03  01 01 00 0f 00 01 01     |...............|
+00000000  16 03 01 01 34 01 00 01  30 03 03 10 5e c8 3f c6  |....4...0...^.?.|
+00000010  fe 44 c4 f0 13 c5 bd ad  06 21 65 e5 a8 40 b5 1d  |.D.......!e..@..|
+00000020  21 07 99 34 5b ef 70 85  29 92 7d 00 00 b6 c0 30  |!..4[.p.).}....0|
+00000030  c0 2c c0 28 c0 24 c0 14  c0 0a 00 a5 00 a3 00 a1  |.,.(.$..........|
+00000040  00 9f 00 6b 00 6a 00 69  00 68 00 39 00 38 00 37  |...k.j.i.h.9.8.7|
+00000050  00 36 00 88 00 87 00 86  00 85 c0 32 c0 2e c0 2a  |.6.........2...*|
+00000060  c0 26 c0 0f c0 05 00 9d  00 3d 00 35 00 84 c0 2f  |.&.......=.5.../|
+00000070  c0 2b c0 27 c0 23 c0 13  c0 09 00 a4 00 a2 00 a0  |.+.'.#..........|
+00000080  00 9e 00 67 00 40 00 3f  00 3e 00 33 00 32 00 31  |...g.@.?.>.3.2.1|
+00000090  00 30 00 9a 00 99 00 98  00 97 00 45 00 44 00 43  |.0.........E.D.C|
+000000a0  00 42 c0 31 c0 2d c0 29  c0 25 c0 0e c0 04 00 9c  |.B.1.-.).%......|
+000000b0  00 3c 00 2f 00 96 00 41  00 07 c0 11 c0 07 c0 0c  |.<./...A........|
+000000c0  c0 02 00 05 00 04 c0 12  c0 08 00 16 00 13 00 10  |................|
+000000d0  00 0d c0 0d c0 03 00 0a  00 15 00 12 00 0f 00 0c  |................|
+000000e0  00 09 00 ff 01 00 00 51  00 0b 00 04 03 00 01 02  |.......Q........|
+000000f0  00 0a 00 1c 00 1a 00 17  00 19 00 1c 00 1b 00 18  |................|
+00000100  00 1a 00 16 00 0e 00 0d  00 0b 00 0c 00 09 00 0a  |................|
+00000110  00 0d 00 20 00 1e 06 01  06 02 06 03 05 01 05 02  |... ............|
+00000120  05 03 04 01 04 02 04 03  03 01 03 02 03 03 02 01  |................|
+00000130  02 02 02 03 00 0f 00 01  01                       |.........|
 >>> Flow 2 (server to client)
-00000000  16 03 03 00 2a 02 00 00  26 03 03 00 00 00 00 00  |....*...&.......|
+00000000  16 03 03 00 31 02 00 00  2d 03 03 00 00 00 00 00  |....1...-.......|
 00000010  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
-00000020  00 00 00 00 00 00 00 00  00 00 00 00 c0 14 00 16  |................|
-00000030  03 03 02 be 0b 00 02 ba  00 02 b7 00 02 b4 30 82  |..............0.|
-00000040  02 b0 30 82 02 19 a0 03  02 01 02 02 09 00 85 b0  |..0.............|
-00000050  bb a4 8a 7f b8 ca 30 0d  06 09 2a 86 48 86 f7 0d  |......0...*.H...|
-00000060  01 01 05 05 00 30 45 31  0b 30 09 06 03 55 04 06  |.....0E1.0...U..|
-00000070  13 02 41 55 31 13 30 11  06 03 55 04 08 13 0a 53  |..AU1.0...U....S|
-00000080  6f 6d 65 2d 53 74 61 74  65 31 21 30 1f 06 03 55  |ome-State1!0...U|
-00000090  04 0a 13 18 49 6e 74 65  72 6e 65 74 20 57 69 64  |....Internet Wid|
-000000a0  67 69 74 73 20 50 74 79  20 4c 74 64 30 1e 17 0d  |gits Pty Ltd0...|
-000000b0  31 30 30 34 32 34 30 39  30 39 33 38 5a 17 0d 31  |100424090938Z..1|
-000000c0  31 30 34 32 34 30 39 30  39 33 38 5a 30 45 31 0b  |10424090938Z0E1.|
-000000d0  30 09 06 03 55 04 06 13  02 41 55 31 13 30 11 06  |0...U....AU1.0..|
-000000e0  03 55 04 08 13 0a 53 6f  6d 65 2d 53 74 61 74 65  |.U....Some-State|
-000000f0  31 21 30 1f 06 03 55 04  0a 13 18 49 6e 74 65 72  |1!0...U....Inter|
-00000100  6e 65 74 20 57 69 64 67  69 74 73 20 50 74 79 20  |net Widgits Pty |
-00000110  4c 74 64 30 81 9f 30 0d  06 09 2a 86 48 86 f7 0d  |Ltd0..0...*.H...|
-00000120  01 01 01 05 00 03 81 8d  00 30 81 89 02 81 81 00  |.........0......|
-00000130  bb 79 d6 f5 17 b5 e5 bf  46 10 d0 dc 69 be e6 2b  |.y......F...i..+|
-00000140  07 43 5a d0 03 2d 8a 7a  43 85 b7 14 52 e7 a5 65  |.CZ..-.zC...R..e|
-00000150  4c 2c 78 b8 23 8c b5 b4  82 e5 de 1f 95 3b 7e 62  |L,x.#........;~b|
-00000160  a5 2c a5 33 d6 fe 12 5c  7a 56 fc f5 06 bf fa 58  |.,.3...\zV.....X|
-00000170  7b 26 3f b5 cd 04 d3 d0  c9 21 96 4a c7 f4 54 9f  |{&?......!.J..T.|
-00000180  5a bf ef 42 71 00 fe 18  99 07 7f 7e 88 7d 7d f1  |Z..Bq......~.}}.|
-00000190  04 39 c4 a2 2e db 51 c9  7c e3 c0 4c 3b 32 66 01  |.9....Q.|..L;2f.|
-000001a0  cf af b1 1d b8 71 9a 1d  db db 89 6b ae da 2d 79  |.....q.....k..-y|
-000001b0  02 03 01 00 01 a3 81 a7  30 81 a4 30 1d 06 03 55  |........0..0...U|
-000001c0  1d 0e 04 16 04 14 b1 ad  e2 85 5a cf cb 28 db 69  |..........Z..(.i|
-000001d0  ce 23 69 de d3 26 8e 18  88 39 30 75 06 03 55 1d  |.#i..&...90u..U.|
-000001e0  23 04 6e 30 6c 80 14 b1  ad e2 85 5a cf cb 28 db  |#.n0l......Z..(.|
-000001f0  69 ce 23 69 de d3 26 8e  18 88 39 a1 49 a4 47 30  |i.#i..&...9.I.G0|
-00000200  45 31 0b 30 09 06 03 55  04 06 13 02 41 55 31 13  |E1.0...U....AU1.|
-00000210  30 11 06 03 55 04 08 13  0a 53 6f 6d 65 2d 53 74  |0...U....Some-St|
-00000220  61 74 65 31 21 30 1f 06  03 55 04 0a 13 18 49 6e  |ate1!0...U....In|
-00000230  74 65 72 6e 65 74 20 57  69 64 67 69 74 73 20 50  |ternet Widgits P|
-00000240  74 79 20 4c 74 64 82 09  00 85 b0 bb a4 8a 7f b8  |ty Ltd..........|
-00000250  ca 30 0c 06 03 55 1d 13  04 05 30 03 01 01 ff 30  |.0...U....0....0|
-00000260  0d 06 09 2a 86 48 86 f7  0d 01 01 05 05 00 03 81  |...*.H..........|
-00000270  81 00 08 6c 45 24 c7 6b  b1 59 ab 0c 52 cc f2 b0  |...lE$.k.Y..R...|
-00000280  14 d7 87 9d 7a 64 75 b5  5a 95 66 e4 c5 2b 8e ae  |....zdu.Z.f..+..|
-00000290  12 66 1f eb 4f 38 b3 6e  60 d3 92 fd f7 41 08 b5  |.f..O8.n`....A..|
-000002a0  25 13 b1 18 7a 24 fb 30  1d ba ed 98 b9 17 ec e7  |%...z$.0........|
-000002b0  d7 31 59 db 95 d3 1d 78  ea 50 56 5c d5 82 5a 2d  |.1Y....x.PV\..Z-|
-000002c0  5a 5f 33 c4 b6 d8 c9 75  90 96 8c 0f 52 98 b5 cd  |Z_3....u....R...|
-000002d0  98 1f 89 20 5f f2 a0 1c  a3 1b 96 94 dd a9 fd 57  |... _..........W|
-000002e0  e9 70 e8 26 6d 71 99 9b  26 6e 38 50 29 6c 90 a7  |.p.&mq..&n8P)l..|
-000002f0  bd d9 16 03 03 00 cd 0c  00 00 c9 03 00 17 41 04  |..............A.|
-00000300  1e 18 37 ef 0d 19 51 88  35 75 71 b5 e5 54 5b 12  |..7...Q.5uq..T[.|
-00000310  2e 8f 09 67 fd a7 24 20  3e b2 56 1c ce 97 28 5e  |...g..$ >.V...(^|
-00000320  f8 2b 2d 4f 9e f1 07 9f  6c 4b 5b 83 56 e2 32 42  |.+-O....lK[.V.2B|
-00000330  e9 58 b6 d7 49 a6 b5 68  1a 41 03 56 6b dc 5a 89  |.X..I..h.A.Vk.Z.|
-00000340  04 01 00 80 9d 84 09 35  73 fb f6 ea 94 7b 49 fb  |.......5s....{I.|
-00000350  c2 70 b1 11 64 5b 93 9f  d9 8c f5 56 98 f6 d3 66  |.p..d[.....V...f|
-00000360  a6 1d 18 56 88 87 71 3f  b0 38 9d 44 1f ad 2c 0d  |...V..q?.8.D..,.|
-00000370  3a a7 e8 d4 3e 33 3c 41  20 f3 3f 5c e5 fb e3 23  |:...>3<A .?\...#|
-00000380  12 48 ff d2 c4 30 7c 8a  51 3f 9f 19 6e 34 d7 60  |.H...0|.Q?..n4.`|
-00000390  7d 12 8a aa 90 0f 50 d9  0b 9a b2 d7 66 b1 c6 84  |}.....P.....f...|
-000003a0  af 5c e2 5e 16 3e 36 61  73 84 64 89 b3 c1 6d 50  |.\.^.>6as.d...mP|
-000003b0  33 55 c7 e1 c5 a5 4c 32  5c 95 dc 07 43 60 49 11  |3U....L2\...C`I.|
-000003c0  e9 98 cc ba 16 03 03 00  04 0e 00 00 00           |.............|
+00000020  00 00 00 00 00 00 00 00  00 00 00 00 c0 14 00 00  |................|
+00000030  05 ff 01 00 01 00 16 03  03 02 71 0b 00 02 6d 00  |..........q...m.|
+00000040  02 6a 00 02 67 30 82 02  63 30 82 01 cc a0 03 02  |.j..g0..c0......|
+00000050  01 02 02 09 00 a2 73 00  0c 81 00 cb f3 30 0d 06  |......s......0..|
+00000060  09 2a 86 48 86 f7 0d 01  01 0b 05 00 30 2b 31 17  |.*.H........0+1.|
+00000070  30 15 06 03 55 04 0a 13  0e 47 6f 6f 67 6c 65 20  |0...U....Google |
+00000080  54 45 53 54 49 4e 47 31  10 30 0e 06 03 55 04 03  |TESTING1.0...U..|
+00000090  13 07 47 6f 20 52 6f 6f  74 30 1e 17 0d 31 35 30  |..Go Root0...150|
+000000a0  31 30 31 30 30 30 30 30  30 5a 17 0d 32 35 30 31  |101000000Z..2501|
+000000b0  30 31 30 30 30 30 30 30  5a 30 26 31 17 30 15 06  |01000000Z0&1.0..|
+000000c0  03 55 04 0a 13 0e 47 6f  6f 67 6c 65 20 54 45 53  |.U....Google TES|
+000000d0  54 49 4e 47 31 0b 30 09  06 03 55 04 03 13 02 47  |TING1.0...U....G|
+000000e0  6f 30 81 9f 30 0d 06 09  2a 86 48 86 f7 0d 01 01  |o0..0...*.H.....|
+000000f0  01 05 00 03 81 8d 00 30  81 89 02 81 81 00 af 87  |.......0........|
+00000100  88 f6 20 1b 95 65 6c 14  ab 44 05 af 3b 45 14 e3  |.. ..el..D..;E..|
+00000110  b7 6d fd 00 63 4d 95 7f  fe 6a 62 35 86 c0 4a f9  |.m..cM...jb5..J.|
+00000120  18 7c f6 aa 25 5e 7a 64  31 66 00 ba f4 8e 92 af  |.|..%^zd1f......|
+00000130  c7 6b d8 76 d4 f3 5f 41  cb 6e 56 15 97 1b 97 c1  |.k.v.._A.nV.....|
+00000140  3c 12 39 21 66 3d 2b 16  d1 bc db 1c c0 a7 da b7  |<.9!f=+.........|
+00000150  ca ad ba da cb d5 21 50  ec de 8d ab d1 6b 81 4b  |......!P.....k.K|
+00000160  89 02 f3 c4 be c1 6c 89  b1 44 84 bd 21 d1 04 7d  |......l..D..!..}|
+00000170  9d 16 4d f9 82 15 f6 ef  fa d6 09 47 f2 fb 02 03  |..M........G....|
+00000180  01 00 01 a3 81 93 30 81  90 30 0e 06 03 55 1d 0f  |......0..0...U..|
+00000190  01 01 ff 04 04 03 02 05  a0 30 1d 06 03 55 1d 25  |.........0...U.%|
+000001a0  04 16 30 14 06 08 2b 06  01 05 05 07 03 01 06 08  |..0...+.........|
+000001b0  2b 06 01 05 05 07 03 02  30 0c 06 03 55 1d 13 01  |+.......0...U...|
+000001c0  01 ff 04 02 30 00 30 19  06 03 55 1d 0e 04 12 04  |....0.0...U.....|
+000001d0  10 12 50 8d 89 6f 1b d1  dc 54 4d 6e cb 69 5e 06  |..P..o...TMn.i^.|
+000001e0  f4 30 1b 06 03 55 1d 23  04 14 30 12 80 10 bf 3d  |.0...U.#..0....=|
+000001f0  b6 a9 66 f2 b8 40 cf ea  b4 03 78 48 1a 41 30 19  |..f..@....xH.A0.|
+00000200  06 03 55 1d 11 04 12 30  10 82 0e 65 78 61 6d 70  |..U....0...examp|
+00000210  6c 65 2e 67 6f 6c 61 6e  67 30 0d 06 09 2a 86 48  |le.golang0...*.H|
+00000220  86 f7 0d 01 01 0b 05 00  03 81 81 00 92 7c af 91  |.............|..|
+00000230  55 12 18 96 59 31 a6 48  40 d5 2d d5 ee bb 02 a0  |U...Y1.H@.-.....|
+00000240  f5 c2 1e 7c 9b b3 30 7d  3c dc 76 da 4f 3d c0 fa  |...|..0}<.v.O=..|
+00000250  ae 2d 33 24 6b 03 7b 1b  67 59 11 21 b5 11 bc 77  |.-3$k.{.gY.!...w|
+00000260  b9 d9 e0 6e a8 2d 2e 35  fa 64 5f 22 3e 63 10 6b  |...n.-.5.d_">c.k|
+00000270  be ff 14 86 6d 0d f0 15  31 a8 14 38 1e 3b 84 87  |....m...1..8.;..|
+00000280  2c cb 98 ed 51 76 b9 b1  4f dd db 9b 84 04 86 40  |,...Qv..O......@|
+00000290  fa 51 dd ba b4 8d eb e3  46 de 46 b9 4f 86 c7 f9  |.Q......F.F.O...|
+000002a0  a4 c2 41 34 ac cc f6 ea  b0 ab 39 18 16 03 03 00  |..A4......9.....|
+000002b0  cd 0c 00 00 c9 03 00 17  41 04 1e 18 37 ef 0d 19  |........A...7...|
+000002c0  51 88 35 75 71 b5 e5 54  5b 12 2e 8f 09 67 fd a7  |Q.5uq..T[....g..|
+000002d0  24 20 3e b2 56 1c ce 97  28 5e f8 2b 2d 4f 9e f1  |$ >.V...(^.+-O..|
+000002e0  07 9f 6c 4b 5b 83 56 e2  32 42 e9 58 b6 d7 49 a6  |..lK[.V.2B.X..I.|
+000002f0  b5 68 1a 41 03 56 6b dc  5a 89 05 01 00 80 6a 4b  |.h.A.Vk.Z.....jK|
+00000300  b1 7d 23 cd 0e cb 26 02  d4 ee 90 f2 e0 4a 47 3d  |.}#...&......JG=|
+00000310  b3 36 90 8d 01 42 98 92  ad 75 87 71 02 70 02 a8  |.6...B...u.q.p..|
+00000320  0c b0 06 ee bd 6a 1f 3f  6c 4b 4b 6b 75 41 23 b4  |.....j.?lKKkuA#.|
+00000330  f9 c2 a6 60 e2 de 55 b6  d4 85 62 e9 8f 20 70 ed  |...`..U...b.. p.|
+00000340  9a b8 bb dd 1f 19 87 e9  ad b3 30 3f 7c 63 51 f1  |..........0?|cQ.|
+00000350  59 ab d1 a0 a1 80 22 56  ca 68 52 f8 0f 80 c6 a6  |Y....."V.hR.....|
+00000360  9e 12 51 ed 29 d0 6d c2  1a e5 37 dc 76 e3 f3 53  |..Q.).m...7.v..S|
+00000370  1b 07 0b ea a6 11 af dc  54 d3 ee 25 cc 27 16 03  |........T..%.'..|
+00000380  03 00 04 0e 00 00 00                              |.......|
 >>> Flow 3 (client to server)
-00000000  16 03 03 00 46 10 00 00  42 41 04 28 02 84 d5 b4  |....F...BA.(....|
-00000010  58 07 47 d5 a0 d6 0b 1d  37 91 e6 34 a4 ad 0b ad  |X.G.....7..4....|
-00000020  22 01 82 77 a7 32 86 78  83 3a da 75 2f e5 68 7a  |"..w.2.x.:.u/.hz|
-00000030  de e4 05 e0 02 47 40 4e  38 d2 2c c3 7b da 53 73  |.....G@N8.,.{.Ss|
-00000040  19 cb 8b 73 34 72 4d 33  71 39 c8 14 03 03 00 01  |...s4rM3q9......|
-00000050  01 16 03 03 00 40 10 63  43 76 83 bd 36 e4 1e 4d  |.....@.cCv..6..M|
-00000060  7e 13 b0 ac aa c8 ec 90  31 df 84 46 49 68 39 5a  |~.......1..FIh9Z|
-00000070  05 8b 73 32 86 15 3a 18  57 d8 e2 2c 2d 05 89 93  |..s2..:.W..,-...|
-00000080  37 b8 dd 73 33 92 ff a7  b2 53 27 94 b7 25 56 64  |7..s3....S'..%Vd|
-00000090  a1 d3 2c f7 6b 71                                 |..,.kq|
+00000000  16 03 03 00 46 10 00 00  42 41 04 2d 4b 0c 6b 65  |....F...BA.-K.ke|
+00000010  82 32 95 8b 77 ec f0 f2  b2 ba d1 38 74 ed 82 49  |.2..w......8t..I|
+00000020  fb ce 8f 66 97 9d b6 97  d8 ae f5 19 af ad 47 b9  |...f..........G.|
+00000030  db 7b d2 c9 4e 10 68 14  ed 23 a5 98 94 f9 2a 00  |.{..N.h..#....*.|
+00000040  b6 44 b3 44 01 29 6c 56  da bb a8 14 03 03 00 01  |.D.D.)lV........|
+00000050  01 16 03 03 00 40 f4 fd  de d6 20 2e 18 80 4e 73  |.....@.... ...Ns|
+00000060  af dd 97 42 08 3b 51 80  e9 26 00 48 6b 8b 21 99  |...B.;Q..&.Hk.!.|
+00000070  a8 60 1f 64 51 d0 5a 90  8b b0 69 b8 6b 29 59 21  |.`.dQ.Z...i.k)Y!|
+00000080  b1 13 19 13 07 01 e1 2c  c3 6b 17 2d 01 a5 be d6  |.......,.k.-....|
+00000090  b0 0d 3d 6a 8c fe                                 |..=j..|
 >>> Flow 4 (server to client)
 00000000  14 03 03 00 01 01 16 03  03 00 40 00 00 00 00 00  |..........@.....|
-00000010  00 00 00 00 00 00 00 00  00 00 00 21 5c 31 b1 4b  |...........!\1.K|
-00000020  96 96 30 8f 79 35 3a 3a  2d 26 67 d0 70 48 be 30  |..0.y5::-&g.pH.0|
-00000030  f8 3e e8 c1 cb 1d d5 89  f6 9c 72 bb 1c f9 4d 90  |.>........r...M.|
-00000040  9c d7 c6 fa 40 76 a5 61  46 61 24 17 03 03 00 40  |....@v.aFa$....@|
+00000010  00 00 00 00 00 00 00 00  00 00 00 84 e2 7f e3 b4  |................|
+00000020  53 d7 d0 30 c4 e5 ea 09  df ba 33 b0 02 34 eb 2e  |S..0......3..4..|
+00000030  b2 ec 47 0d e7 20 76 12  fa 53 3b 44 86 e1 e1 63  |..G.. v..S;D...c|
+00000040  06 29 57 98 ce 87 18 ad  02 17 01 17 03 03 00 40  |.)W............@|
 00000050  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
-00000060  94 8a 14 04 06 b9 30 a0  67 fd b2 4c 84 f4 10 93  |......0.g..L....|
-00000070  7d d4 2b 23 f0 e9 62 93  c2 20 a2 f2 7c 07 21 4b  |}.+#..b.. ..|.!K|
-00000080  94 ba 7b 7d cb 77 da 85  93 bd 53 ee ca db 9b 3e  |..{}.w....S....>|
+00000060  b0 3a f5 90 90 30 9c b3  39 5b b4 56 f6 b9 30 7e  |.:...0..9[.V..0~|
+00000070  8e a8 2d 60 47 b6 57 8a  20 61 02 f2 8e 43 c2 01  |..-`G.W. a...C..|
+00000080  ee f0 be 5a 93 52 2f ea  03 2a 4f 01 ea 9e 1c a2  |...Z.R/..*O.....|
 00000090  15 03 03 00 30 00 00 00  00 00 00 00 00 00 00 00  |....0...........|
-000000a0  00 00 00 00 00 17 3f 53  8d b3 35 b4 84 ed bb 12  |......?S..5.....|
-000000b0  cf 73 25 25 7c c3 d3 bb  1f 5a 6b 73 9a 8a b1 a2  |.s%%|....Zks....|
-000000c0  ba 99 f8 0e 43                                    |....C|
+000000a0  00 00 00 00 00 c0 7e 61  51 a1 76 15 8a 7e 20 5f  |......~aQ.v..~ _|
+000000b0  d4 a4 c6 3e 6c 50 18 c6  63 88 d0 ac 4c fa 31 b3  |...>lP..c...L.1.|
+000000c0  e7 c9 77 11 7a                                    |..w.z|
diff --git a/third_party/gofrontend/libgo/go/crypto/tls/testdata/Server-TLSv12-ClientAuthRequestedAndECDSAGiven b/third_party/gofrontend/libgo/go/crypto/tls/testdata/Server-TLSv12-ClientAuthRequestedAndECDSAGiven
index 547f798..56c3c82 100644
--- a/third_party/gofrontend/libgo/go/crypto/tls/testdata/Server-TLSv12-ClientAuthRequestedAndECDSAGiven
+++ b/third_party/gofrontend/libgo/go/crypto/tls/testdata/Server-TLSv12-ClientAuthRequestedAndECDSAGiven
@@ -1,62 +1,57 @@
 >>> Flow 1 (client to server)
-00000000  16 03 01 00 5c 01 00 00  58 03 03 52 cc 57 59 65  |....\...X..R.WYe|
-00000010  ae b3 ec a4 7a 05 f7 ec  39 22 7d 8c 91 96 6b e0  |....z...9"}...k.|
-00000020  69 81 ff 88 28 17 60 ac  94 19 ff 00 00 04 00 05  |i...(.`.........|
-00000030  00 ff 01 00 00 2b 00 0d  00 22 00 20 06 01 06 02  |.....+...". ....|
+00000000  16 03 01 00 5a 01 00 00  56 03 03 80 13 c8 83 43  |....Z...V......C|
+00000010  94 79 15 01 6e 0a 9f c5  0f e7 f6 d8 b1 94 de b4  |.y..n...........|
+00000020  57 8c 4f a8 08 48 ee 9b  b4 d2 43 00 00 04 00 05  |W.O..H....C.....|
+00000030  00 ff 01 00 00 29 00 0d  00 20 00 1e 06 01 06 02  |.....)... ......|
 00000040  06 03 05 01 05 02 05 03  04 01 04 02 04 03 03 01  |................|
-00000050  03 02 03 03 02 01 02 02  02 03 01 01 00 0f 00 01  |................|
-00000060  01                                                |.|
+00000050  03 02 03 03 02 01 02 02  02 03 00 0f 00 01 01     |...............|
 >>> Flow 2 (server to client)
 00000000  16 03 03 00 31 02 00 00  2d 03 03 00 00 00 00 00  |....1...-.......|
 00000010  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
 00000020  00 00 00 00 00 00 00 00  00 00 00 00 00 05 00 00  |................|
-00000030  05 ff 01 00 01 00 16 03  03 02 be 0b 00 02 ba 00  |................|
-00000040  02 b7 00 02 b4 30 82 02  b0 30 82 02 19 a0 03 02  |.....0...0......|
-00000050  01 02 02 09 00 85 b0 bb  a4 8a 7f b8 ca 30 0d 06  |.............0..|
-00000060  09 2a 86 48 86 f7 0d 01  01 05 05 00 30 45 31 0b  |.*.H........0E1.|
-00000070  30 09 06 03 55 04 06 13  02 41 55 31 13 30 11 06  |0...U....AU1.0..|
-00000080  03 55 04 08 13 0a 53 6f  6d 65 2d 53 74 61 74 65  |.U....Some-State|
-00000090  31 21 30 1f 06 03 55 04  0a 13 18 49 6e 74 65 72  |1!0...U....Inter|
-000000a0  6e 65 74 20 57 69 64 67  69 74 73 20 50 74 79 20  |net Widgits Pty |
-000000b0  4c 74 64 30 1e 17 0d 31  30 30 34 32 34 30 39 30  |Ltd0...100424090|
-000000c0  39 33 38 5a 17 0d 31 31  30 34 32 34 30 39 30 39  |938Z..1104240909|
-000000d0  33 38 5a 30 45 31 0b 30  09 06 03 55 04 06 13 02  |38Z0E1.0...U....|
-000000e0  41 55 31 13 30 11 06 03  55 04 08 13 0a 53 6f 6d  |AU1.0...U....Som|
-000000f0  65 2d 53 74 61 74 65 31  21 30 1f 06 03 55 04 0a  |e-State1!0...U..|
-00000100  13 18 49 6e 74 65 72 6e  65 74 20 57 69 64 67 69  |..Internet Widgi|
-00000110  74 73 20 50 74 79 20 4c  74 64 30 81 9f 30 0d 06  |ts Pty Ltd0..0..|
-00000120  09 2a 86 48 86 f7 0d 01  01 01 05 00 03 81 8d 00  |.*.H............|
-00000130  30 81 89 02 81 81 00 bb  79 d6 f5 17 b5 e5 bf 46  |0.......y......F|
-00000140  10 d0 dc 69 be e6 2b 07  43 5a d0 03 2d 8a 7a 43  |...i..+.CZ..-.zC|
-00000150  85 b7 14 52 e7 a5 65 4c  2c 78 b8 23 8c b5 b4 82  |...R..eL,x.#....|
-00000160  e5 de 1f 95 3b 7e 62 a5  2c a5 33 d6 fe 12 5c 7a  |....;~b.,.3...\z|
-00000170  56 fc f5 06 bf fa 58 7b  26 3f b5 cd 04 d3 d0 c9  |V.....X{&?......|
-00000180  21 96 4a c7 f4 54 9f 5a  bf ef 42 71 00 fe 18 99  |!.J..T.Z..Bq....|
-00000190  07 7f 7e 88 7d 7d f1 04  39 c4 a2 2e db 51 c9 7c  |..~.}}..9....Q.||
-000001a0  e3 c0 4c 3b 32 66 01 cf  af b1 1d b8 71 9a 1d db  |..L;2f......q...|
-000001b0  db 89 6b ae da 2d 79 02  03 01 00 01 a3 81 a7 30  |..k..-y........0|
-000001c0  81 a4 30 1d 06 03 55 1d  0e 04 16 04 14 b1 ad e2  |..0...U.........|
-000001d0  85 5a cf cb 28 db 69 ce  23 69 de d3 26 8e 18 88  |.Z..(.i.#i..&...|
-000001e0  39 30 75 06 03 55 1d 23  04 6e 30 6c 80 14 b1 ad  |90u..U.#.n0l....|
-000001f0  e2 85 5a cf cb 28 db 69  ce 23 69 de d3 26 8e 18  |..Z..(.i.#i..&..|
-00000200  88 39 a1 49 a4 47 30 45  31 0b 30 09 06 03 55 04  |.9.I.G0E1.0...U.|
-00000210  06 13 02 41 55 31 13 30  11 06 03 55 04 08 13 0a  |...AU1.0...U....|
-00000220  53 6f 6d 65 2d 53 74 61  74 65 31 21 30 1f 06 03  |Some-State1!0...|
-00000230  55 04 0a 13 18 49 6e 74  65 72 6e 65 74 20 57 69  |U....Internet Wi|
-00000240  64 67 69 74 73 20 50 74  79 20 4c 74 64 82 09 00  |dgits Pty Ltd...|
-00000250  85 b0 bb a4 8a 7f b8 ca  30 0c 06 03 55 1d 13 04  |........0...U...|
-00000260  05 30 03 01 01 ff 30 0d  06 09 2a 86 48 86 f7 0d  |.0....0...*.H...|
-00000270  01 01 05 05 00 03 81 81  00 08 6c 45 24 c7 6b b1  |..........lE$.k.|
-00000280  59 ab 0c 52 cc f2 b0 14  d7 87 9d 7a 64 75 b5 5a  |Y..R.......zdu.Z|
-00000290  95 66 e4 c5 2b 8e ae 12  66 1f eb 4f 38 b3 6e 60  |.f..+...f..O8.n`|
-000002a0  d3 92 fd f7 41 08 b5 25  13 b1 18 7a 24 fb 30 1d  |....A..%...z$.0.|
-000002b0  ba ed 98 b9 17 ec e7 d7  31 59 db 95 d3 1d 78 ea  |........1Y....x.|
-000002c0  50 56 5c d5 82 5a 2d 5a  5f 33 c4 b6 d8 c9 75 90  |PV\..Z-Z_3....u.|
-000002d0  96 8c 0f 52 98 b5 cd 98  1f 89 20 5f f2 a0 1c a3  |...R...... _....|
-000002e0  1b 96 94 dd a9 fd 57 e9  70 e8 26 6d 71 99 9b 26  |......W.p.&mq..&|
-000002f0  6e 38 50 29 6c 90 a7 bd  d9 16 03 03 00 0f 0d 00  |n8P)l...........|
-00000300  00 0b 02 01 40 00 04 04  01 04 03 00 00 16 03 03  |....@...........|
-00000310  00 04 0e 00 00 00                                 |......|
+00000030  05 ff 01 00 01 00 16 03  03 02 71 0b 00 02 6d 00  |..........q...m.|
+00000040  02 6a 00 02 67 30 82 02  63 30 82 01 cc a0 03 02  |.j..g0..c0......|
+00000050  01 02 02 09 00 a2 73 00  0c 81 00 cb f3 30 0d 06  |......s......0..|
+00000060  09 2a 86 48 86 f7 0d 01  01 0b 05 00 30 2b 31 17  |.*.H........0+1.|
+00000070  30 15 06 03 55 04 0a 13  0e 47 6f 6f 67 6c 65 20  |0...U....Google |
+00000080  54 45 53 54 49 4e 47 31  10 30 0e 06 03 55 04 03  |TESTING1.0...U..|
+00000090  13 07 47 6f 20 52 6f 6f  74 30 1e 17 0d 31 35 30  |..Go Root0...150|
+000000a0  31 30 31 30 30 30 30 30  30 5a 17 0d 32 35 30 31  |101000000Z..2501|
+000000b0  30 31 30 30 30 30 30 30  5a 30 26 31 17 30 15 06  |01000000Z0&1.0..|
+000000c0  03 55 04 0a 13 0e 47 6f  6f 67 6c 65 20 54 45 53  |.U....Google TES|
+000000d0  54 49 4e 47 31 0b 30 09  06 03 55 04 03 13 02 47  |TING1.0...U....G|
+000000e0  6f 30 81 9f 30 0d 06 09  2a 86 48 86 f7 0d 01 01  |o0..0...*.H.....|
+000000f0  01 05 00 03 81 8d 00 30  81 89 02 81 81 00 af 87  |.......0........|
+00000100  88 f6 20 1b 95 65 6c 14  ab 44 05 af 3b 45 14 e3  |.. ..el..D..;E..|
+00000110  b7 6d fd 00 63 4d 95 7f  fe 6a 62 35 86 c0 4a f9  |.m..cM...jb5..J.|
+00000120  18 7c f6 aa 25 5e 7a 64  31 66 00 ba f4 8e 92 af  |.|..%^zd1f......|
+00000130  c7 6b d8 76 d4 f3 5f 41  cb 6e 56 15 97 1b 97 c1  |.k.v.._A.nV.....|
+00000140  3c 12 39 21 66 3d 2b 16  d1 bc db 1c c0 a7 da b7  |<.9!f=+.........|
+00000150  ca ad ba da cb d5 21 50  ec de 8d ab d1 6b 81 4b  |......!P.....k.K|
+00000160  89 02 f3 c4 be c1 6c 89  b1 44 84 bd 21 d1 04 7d  |......l..D..!..}|
+00000170  9d 16 4d f9 82 15 f6 ef  fa d6 09 47 f2 fb 02 03  |..M........G....|
+00000180  01 00 01 a3 81 93 30 81  90 30 0e 06 03 55 1d 0f  |......0..0...U..|
+00000190  01 01 ff 04 04 03 02 05  a0 30 1d 06 03 55 1d 25  |.........0...U.%|
+000001a0  04 16 30 14 06 08 2b 06  01 05 05 07 03 01 06 08  |..0...+.........|
+000001b0  2b 06 01 05 05 07 03 02  30 0c 06 03 55 1d 13 01  |+.......0...U...|
+000001c0  01 ff 04 02 30 00 30 19  06 03 55 1d 0e 04 12 04  |....0.0...U.....|
+000001d0  10 12 50 8d 89 6f 1b d1  dc 54 4d 6e cb 69 5e 06  |..P..o...TMn.i^.|
+000001e0  f4 30 1b 06 03 55 1d 23  04 14 30 12 80 10 bf 3d  |.0...U.#..0....=|
+000001f0  b6 a9 66 f2 b8 40 cf ea  b4 03 78 48 1a 41 30 19  |..f..@....xH.A0.|
+00000200  06 03 55 1d 11 04 12 30  10 82 0e 65 78 61 6d 70  |..U....0...examp|
+00000210  6c 65 2e 67 6f 6c 61 6e  67 30 0d 06 09 2a 86 48  |le.golang0...*.H|
+00000220  86 f7 0d 01 01 0b 05 00  03 81 81 00 92 7c af 91  |.............|..|
+00000230  55 12 18 96 59 31 a6 48  40 d5 2d d5 ee bb 02 a0  |U...Y1.H@.-.....|
+00000240  f5 c2 1e 7c 9b b3 30 7d  3c dc 76 da 4f 3d c0 fa  |...|..0}<.v.O=..|
+00000250  ae 2d 33 24 6b 03 7b 1b  67 59 11 21 b5 11 bc 77  |.-3$k.{.gY.!...w|
+00000260  b9 d9 e0 6e a8 2d 2e 35  fa 64 5f 22 3e 63 10 6b  |...n.-.5.d_">c.k|
+00000270  be ff 14 86 6d 0d f0 15  31 a8 14 38 1e 3b 84 87  |....m...1..8.;..|
+00000280  2c cb 98 ed 51 76 b9 b1  4f dd db 9b 84 04 86 40  |,...Qv..O......@|
+00000290  fa 51 dd ba b4 8d eb e3  46 de 46 b9 4f 86 c7 f9  |.Q......F.F.O...|
+000002a0  a4 c2 41 34 ac cc f6 ea  b0 ab 39 18 16 03 03 00  |..A4......9.....|
+000002b0  17 0d 00 00 13 02 01 40  00 0c 04 01 04 03 05 01  |.......@........|
+000002c0  05 03 02 01 02 03 00 00  16 03 03 00 04 0e 00 00  |................|
+000002d0  00                                                |.|
 >>> Flow 3 (client to server)
 00000000  16 03 03 02 0a 0b 00 02  06 00 02 03 00 02 00 30  |...............0|
 00000010  82 01 fc 30 82 01 5e 02  09 00 9a 30 84 6c 26 35  |...0..^....0.l&5|
@@ -91,32 +86,32 @@
 000001e0  be e8 91 b3 da 1a f5 5d  a3 23 f5 26 8b 45 70 8d  |.......].#.&.Ep.|
 000001f0  65 62 9b 7e 01 99 3d 18  f6 10 9a 38 61 9b 2e 57  |eb.~..=....8a..W|
 00000200  e4 fa cc b1 8a ce e2 23  a0 87 f0 e1 67 51 eb 16  |.......#....gQ..|
-00000210  03 03 00 86 10 00 00 82  00 80 47 5a 2f b8 78 46  |..........GZ/.xF|
-00000220  9f 3c fc ab 8b 35 c9 77  da c3 96 78 31 7c 2b 4f  |.<...5.w...x1|+O|
-00000230  56 be 0f 33 bd 17 bc 1c  86 5a ae b3 0f 8b 18 2f  |V..3.....Z...../|
-00000240  48 0d e0 0a 20 d3 53 96  88 d2 8a 7d b6 58 13 44  |H... .S....}.X.D|
-00000250  a5 e8 19 6d 02 df a6 1b  79 c5 54 c2 ef 4d 41 4f  |...m....y.T..MAO|
-00000260  04 1c eb 37 55 b7 2b f4  7c 6d 37 9c f1 89 a0 2c  |...7U.+.|m7....,|
-00000270  0f ba 10 09 e4 a1 ee 0a  7e 9a fd 2c 32 63 1c 55  |........~..,2c.U|
-00000280  85 38 de d0 7b 5f 46 03  1f cc 4d 69 51 97 d8 d7  |.8..{_F...MiQ...|
-00000290  88 6f ba 43 04 b0 42 09  61 5e 16 03 03 00 92 0f  |.o.C..B.a^......|
-000002a0  00 00 8e 04 03 00 8a 30  81 87 02 41 14 3d 4c 71  |.......0...A.=Lq|
-000002b0  c2 32 4a 20 ee b7 69 17  55 e8 99 55 11 76 51 7a  |.2J ..i.U..U.vQz|
-000002c0  74 55 e7 e8 c3 3b b3 70  db 1c 8e f6 8a d4 99 40  |tU...;.p.......@|
-000002d0  6e da 04 fd 7a 47 41 d6  ae c0 63 ad fd 91 a8 58  |n...zGA...c....X|
-000002e0  24 b9 ac 2f 7a 4c bf 5b  24 12 cb 3a f3 02 42 00  |$../zL.[$..:..B.|
-000002f0  90 f9 48 97 0e d4 33 99  09 9f 1d a8 97 16 60 82  |..H...3.......`.|
-00000300  85 cc 5a 5d 79 f7 2f 03  2a c0 b8 12 61 ac 9f 88  |..Z]y./.*...a...|
-00000310  1d 0d 9e 0a ee 28 a8 5a  e2 42 b7 94 e2 e6 0e 13  |.....(.Z.B......|
-00000320  c8 64 dc 4e d3 6b 10 d6  83 41 9c dc d4 53 c3 08  |.d.N.k...A...S..|
-00000330  19 14 03 03 00 01 01 16  03 03 00 24 ef bd e3 23  |...........$...#|
-00000340  10 23 ae 6e b5 12 eb 9c  21 78 db 36 fd bf 7f ee  |.#.n....!x.6....|
-00000350  6f c8 00 2d b6 35 cc 2f  38 73 ae a4 34 cf 0d df  |o..-.5./8s..4...|
+00000210  03 03 00 86 10 00 00 82  00 80 88 00 24 23 a5 c7  |............$#..|
+00000220  03 2d 86 37 91 f1 71 a9  5f fb 97 49 88 04 9b 0e  |.-.7..q._..I....|
+00000230  89 da 65 d0 56 71 e7 76  22 ef 8e 11 0e 6b 50 3d  |..e.Vq.v"....kP=|
+00000240  64 3f f7 9b e4 45 01 d9  12 cb da fe 10 da 4e b5  |d?...E........N.|
+00000250  b8 6a b5 bc 74 19 d3 4f  a9 bb ee 54 37 e4 70 d0  |.j..t..O...T7.p.|
+00000260  b6 e7 35 96 70 fe a5 2b  14 ac fb c6 1a fa 7d 12  |..5.p..+......}.|
+00000270  87 1b 63 9d 72 30 4d 2c  1a c9 29 32 72 b6 13 53  |..c.r0M,..)2r..S|
+00000280  96 05 de 78 bc f0 1a 74  e2 31 b9 ea db 62 62 6e  |...x...t.1...bbn|
+00000290  a0 a6 b2 c0 3e 2a 94 0d  6a f7 16 03 03 00 92 0f  |....>*..j.......|
+000002a0  00 00 8e 04 03 00 8a 30  81 87 02 42 01 71 5b 3b  |.......0...B.q[;|
+000002b0  a3 35 58 c0 b6 08 09 4f  ac af 89 e0 b3 d5 3d 45  |.5X....O......=E|
+000002c0  1f 49 7f 4a c9 bc 9d 0e  50 3a f5 79 bc 54 5d a9  |.I.J....P:.y.T].|
+000002d0  62 ed 85 c5 f3 47 36 03  cc f1 cd 33 c3 70 2a a6  |b....G6....3.p*.|
+000002e0  7c d9 6e 0c db 0d 1b 4f  6a 39 ba 77 bd ea 02 41  ||.n....Oj9.w...A|
+000002f0  00 f2 b7 06 df 2f 81 7e  98 24 46 06 59 4e 86 6a  |...../.~.$F.YN.j|
+00000300  b7 4f b6 4b 95 40 88 f0  8f f8 bd 16 f5 d5 82 7e  |.O.K.@.........~|
+00000310  82 51 6f 05 49 43 59 cd  1d 40 69 67 ff 65 a8 68  |.Qo.ICY..@ig.e.h|
+00000320  39 2f a1 ad a7 6a ef 5c  d5 69 5e 16 50 bb 2a b2  |9/...j.\.i^.P.*.|
+00000330  2f 14 03 03 00 01 01 16  03 03 00 24 55 f6 74 21  |/..........$U.t!|
+00000340  b4 08 a0 7f a2 dc 86 44  e3 f8 e3 0d e1 d6 5c 1c  |.......D......\.|
+00000350  22 1e 41 2b 30 cc 34 0f  a4 a1 7c a0 27 21 01 e0  |".A+0.4...|.'!..|
 >>> Flow 4 (server to client)
-00000000  14 03 03 00 01 01 16 03  03 00 24 a7 50 0f 50 b4  |..........$.P.P.|
-00000010  1c c3 4d f3 7a 64 df 65  ac 35 22 13 46 cc ec 36  |..M.zd.e.5".F..6|
-00000020  e6 d2 f3 67 94 6a 18 85  9f 4a 3c 44 a3 58 b0 17  |...g.j...J<D.X..|
-00000030  03 03 00 21 51 0a 41 8c  fd 50 e3 54 8b 6a 1f 83  |...!Q.A..P.T.j..|
-00000040  a5 37 98 e1 5b 1e ec 03  1d c7 0e 28 6d 79 3f 34  |.7..[......(my?4|
-00000050  de 1c 38 6d 7e 15 03 03  00 16 06 fc b1 7d ad 70  |..8m~........}.p|
-00000060  1a de d4 b7 b5 e7 a2 6d  1b 9a b0 31 0c cc 7b 70  |.......m...1..{p|
+00000000  14 03 03 00 01 01 16 03  03 00 24 6f 6b e7 fb f7  |..........$ok...|
+00000010  52 83 b3 6f ba 1b d7 e8  cb 0a 05 ee 90 04 2b c7  |R..o..........+.|
+00000020  c2 bd 0d 8e ee 42 88 40  ae 01 4a d0 07 4b f4 17  |.....B.@..J..K..|
+00000030  03 03 00 21 e0 8b bd 80  04 18 9c be 12 07 d4 4d  |...!...........M|
+00000040  58 d9 ec c3 f0 67 b5 b3  d1 78 25 e7 2e dd a0 0a  |X....g...x%.....|
+00000050  ac 0f a1 90 59 15 03 03  00 16 76 30 22 0b 00 83  |....Y.....v0"...|
+00000060  c4 31 29 1c ca 44 cb 9f  0e 48 17 21 43 f6 af 47  |.1)..D...H.!C..G|
diff --git a/third_party/gofrontend/libgo/go/crypto/tls/testdata/Server-TLSv12-ClientAuthRequestedAndGiven b/third_party/gofrontend/libgo/go/crypto/tls/testdata/Server-TLSv12-ClientAuthRequestedAndGiven
index 04a5b11..862e0be 100644
--- a/third_party/gofrontend/libgo/go/crypto/tls/testdata/Server-TLSv12-ClientAuthRequestedAndGiven
+++ b/third_party/gofrontend/libgo/go/crypto/tls/testdata/Server-TLSv12-ClientAuthRequestedAndGiven
@@ -1,62 +1,57 @@
 >>> Flow 1 (client to server)
-00000000  16 03 01 00 5c 01 00 00  58 03 03 52 cc 57 59 6b  |....\...X..R.WYk|
-00000010  11 07 04 39 77 20 c2 b4  3f cb 0a c9 53 fe 5b 3e  |...9w ..?...S.[>|
-00000020  5f 58 2c 7e 30 69 e1 8e  6c 9d c8 00 00 04 00 05  |_X,~0i..l.......|
-00000030  00 ff 01 00 00 2b 00 0d  00 22 00 20 06 01 06 02  |.....+...". ....|
+00000000  16 03 01 00 5a 01 00 00  56 03 03 b0 80 f6 7c 13  |....Z...V.....|.|
+00000010  30 5d 57 f0 11 3b 30 4b  0e 01 50 9a 44 0b 89 6f  |0]W..;0K..P.D..o|
+00000020  b6 f1 a3 34 b4 f1 b9 bf  fe 66 a5 00 00 04 00 05  |...4.....f......|
+00000030  00 ff 01 00 00 29 00 0d  00 20 00 1e 06 01 06 02  |.....)... ......|
 00000040  06 03 05 01 05 02 05 03  04 01 04 02 04 03 03 01  |................|
-00000050  03 02 03 03 02 01 02 02  02 03 01 01 00 0f 00 01  |................|
-00000060  01                                                |.|
+00000050  03 02 03 03 02 01 02 02  02 03 00 0f 00 01 01     |...............|
 >>> Flow 2 (server to client)
 00000000  16 03 03 00 31 02 00 00  2d 03 03 00 00 00 00 00  |....1...-.......|
 00000010  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
 00000020  00 00 00 00 00 00 00 00  00 00 00 00 00 05 00 00  |................|
-00000030  05 ff 01 00 01 00 16 03  03 02 be 0b 00 02 ba 00  |................|
-00000040  02 b7 00 02 b4 30 82 02  b0 30 82 02 19 a0 03 02  |.....0...0......|
-00000050  01 02 02 09 00 85 b0 bb  a4 8a 7f b8 ca 30 0d 06  |.............0..|
-00000060  09 2a 86 48 86 f7 0d 01  01 05 05 00 30 45 31 0b  |.*.H........0E1.|
-00000070  30 09 06 03 55 04 06 13  02 41 55 31 13 30 11 06  |0...U....AU1.0..|
-00000080  03 55 04 08 13 0a 53 6f  6d 65 2d 53 74 61 74 65  |.U....Some-State|
-00000090  31 21 30 1f 06 03 55 04  0a 13 18 49 6e 74 65 72  |1!0...U....Inter|
-000000a0  6e 65 74 20 57 69 64 67  69 74 73 20 50 74 79 20  |net Widgits Pty |
-000000b0  4c 74 64 30 1e 17 0d 31  30 30 34 32 34 30 39 30  |Ltd0...100424090|
-000000c0  39 33 38 5a 17 0d 31 31  30 34 32 34 30 39 30 39  |938Z..1104240909|
-000000d0  33 38 5a 30 45 31 0b 30  09 06 03 55 04 06 13 02  |38Z0E1.0...U....|
-000000e0  41 55 31 13 30 11 06 03  55 04 08 13 0a 53 6f 6d  |AU1.0...U....Som|
-000000f0  65 2d 53 74 61 74 65 31  21 30 1f 06 03 55 04 0a  |e-State1!0...U..|
-00000100  13 18 49 6e 74 65 72 6e  65 74 20 57 69 64 67 69  |..Internet Widgi|
-00000110  74 73 20 50 74 79 20 4c  74 64 30 81 9f 30 0d 06  |ts Pty Ltd0..0..|
-00000120  09 2a 86 48 86 f7 0d 01  01 01 05 00 03 81 8d 00  |.*.H............|
-00000130  30 81 89 02 81 81 00 bb  79 d6 f5 17 b5 e5 bf 46  |0.......y......F|
-00000140  10 d0 dc 69 be e6 2b 07  43 5a d0 03 2d 8a 7a 43  |...i..+.CZ..-.zC|
-00000150  85 b7 14 52 e7 a5 65 4c  2c 78 b8 23 8c b5 b4 82  |...R..eL,x.#....|
-00000160  e5 de 1f 95 3b 7e 62 a5  2c a5 33 d6 fe 12 5c 7a  |....;~b.,.3...\z|
-00000170  56 fc f5 06 bf fa 58 7b  26 3f b5 cd 04 d3 d0 c9  |V.....X{&?......|
-00000180  21 96 4a c7 f4 54 9f 5a  bf ef 42 71 00 fe 18 99  |!.J..T.Z..Bq....|
-00000190  07 7f 7e 88 7d 7d f1 04  39 c4 a2 2e db 51 c9 7c  |..~.}}..9....Q.||
-000001a0  e3 c0 4c 3b 32 66 01 cf  af b1 1d b8 71 9a 1d db  |..L;2f......q...|
-000001b0  db 89 6b ae da 2d 79 02  03 01 00 01 a3 81 a7 30  |..k..-y........0|
-000001c0  81 a4 30 1d 06 03 55 1d  0e 04 16 04 14 b1 ad e2  |..0...U.........|
-000001d0  85 5a cf cb 28 db 69 ce  23 69 de d3 26 8e 18 88  |.Z..(.i.#i..&...|
-000001e0  39 30 75 06 03 55 1d 23  04 6e 30 6c 80 14 b1 ad  |90u..U.#.n0l....|
-000001f0  e2 85 5a cf cb 28 db 69  ce 23 69 de d3 26 8e 18  |..Z..(.i.#i..&..|
-00000200  88 39 a1 49 a4 47 30 45  31 0b 30 09 06 03 55 04  |.9.I.G0E1.0...U.|
-00000210  06 13 02 41 55 31 13 30  11 06 03 55 04 08 13 0a  |...AU1.0...U....|
-00000220  53 6f 6d 65 2d 53 74 61  74 65 31 21 30 1f 06 03  |Some-State1!0...|
-00000230  55 04 0a 13 18 49 6e 74  65 72 6e 65 74 20 57 69  |U....Internet Wi|
-00000240  64 67 69 74 73 20 50 74  79 20 4c 74 64 82 09 00  |dgits Pty Ltd...|
-00000250  85 b0 bb a4 8a 7f b8 ca  30 0c 06 03 55 1d 13 04  |........0...U...|
-00000260  05 30 03 01 01 ff 30 0d  06 09 2a 86 48 86 f7 0d  |.0....0...*.H...|
-00000270  01 01 05 05 00 03 81 81  00 08 6c 45 24 c7 6b b1  |..........lE$.k.|
-00000280  59 ab 0c 52 cc f2 b0 14  d7 87 9d 7a 64 75 b5 5a  |Y..R.......zdu.Z|
-00000290  95 66 e4 c5 2b 8e ae 12  66 1f eb 4f 38 b3 6e 60  |.f..+...f..O8.n`|
-000002a0  d3 92 fd f7 41 08 b5 25  13 b1 18 7a 24 fb 30 1d  |....A..%...z$.0.|
-000002b0  ba ed 98 b9 17 ec e7 d7  31 59 db 95 d3 1d 78 ea  |........1Y....x.|
-000002c0  50 56 5c d5 82 5a 2d 5a  5f 33 c4 b6 d8 c9 75 90  |PV\..Z-Z_3....u.|
-000002d0  96 8c 0f 52 98 b5 cd 98  1f 89 20 5f f2 a0 1c a3  |...R...... _....|
-000002e0  1b 96 94 dd a9 fd 57 e9  70 e8 26 6d 71 99 9b 26  |......W.p.&mq..&|
-000002f0  6e 38 50 29 6c 90 a7 bd  d9 16 03 03 00 0f 0d 00  |n8P)l...........|
-00000300  00 0b 02 01 40 00 04 04  01 04 03 00 00 16 03 03  |....@...........|
-00000310  00 04 0e 00 00 00                                 |......|
+00000030  05 ff 01 00 01 00 16 03  03 02 71 0b 00 02 6d 00  |..........q...m.|
+00000040  02 6a 00 02 67 30 82 02  63 30 82 01 cc a0 03 02  |.j..g0..c0......|
+00000050  01 02 02 09 00 a2 73 00  0c 81 00 cb f3 30 0d 06  |......s......0..|
+00000060  09 2a 86 48 86 f7 0d 01  01 0b 05 00 30 2b 31 17  |.*.H........0+1.|
+00000070  30 15 06 03 55 04 0a 13  0e 47 6f 6f 67 6c 65 20  |0...U....Google |
+00000080  54 45 53 54 49 4e 47 31  10 30 0e 06 03 55 04 03  |TESTING1.0...U..|
+00000090  13 07 47 6f 20 52 6f 6f  74 30 1e 17 0d 31 35 30  |..Go Root0...150|
+000000a0  31 30 31 30 30 30 30 30  30 5a 17 0d 32 35 30 31  |101000000Z..2501|
+000000b0  30 31 30 30 30 30 30 30  5a 30 26 31 17 30 15 06  |01000000Z0&1.0..|
+000000c0  03 55 04 0a 13 0e 47 6f  6f 67 6c 65 20 54 45 53  |.U....Google TES|
+000000d0  54 49 4e 47 31 0b 30 09  06 03 55 04 03 13 02 47  |TING1.0...U....G|
+000000e0  6f 30 81 9f 30 0d 06 09  2a 86 48 86 f7 0d 01 01  |o0..0...*.H.....|
+000000f0  01 05 00 03 81 8d 00 30  81 89 02 81 81 00 af 87  |.......0........|
+00000100  88 f6 20 1b 95 65 6c 14  ab 44 05 af 3b 45 14 e3  |.. ..el..D..;E..|
+00000110  b7 6d fd 00 63 4d 95 7f  fe 6a 62 35 86 c0 4a f9  |.m..cM...jb5..J.|
+00000120  18 7c f6 aa 25 5e 7a 64  31 66 00 ba f4 8e 92 af  |.|..%^zd1f......|
+00000130  c7 6b d8 76 d4 f3 5f 41  cb 6e 56 15 97 1b 97 c1  |.k.v.._A.nV.....|
+00000140  3c 12 39 21 66 3d 2b 16  d1 bc db 1c c0 a7 da b7  |<.9!f=+.........|
+00000150  ca ad ba da cb d5 21 50  ec de 8d ab d1 6b 81 4b  |......!P.....k.K|
+00000160  89 02 f3 c4 be c1 6c 89  b1 44 84 bd 21 d1 04 7d  |......l..D..!..}|
+00000170  9d 16 4d f9 82 15 f6 ef  fa d6 09 47 f2 fb 02 03  |..M........G....|
+00000180  01 00 01 a3 81 93 30 81  90 30 0e 06 03 55 1d 0f  |......0..0...U..|
+00000190  01 01 ff 04 04 03 02 05  a0 30 1d 06 03 55 1d 25  |.........0...U.%|
+000001a0  04 16 30 14 06 08 2b 06  01 05 05 07 03 01 06 08  |..0...+.........|
+000001b0  2b 06 01 05 05 07 03 02  30 0c 06 03 55 1d 13 01  |+.......0...U...|
+000001c0  01 ff 04 02 30 00 30 19  06 03 55 1d 0e 04 12 04  |....0.0...U.....|
+000001d0  10 12 50 8d 89 6f 1b d1  dc 54 4d 6e cb 69 5e 06  |..P..o...TMn.i^.|
+000001e0  f4 30 1b 06 03 55 1d 23  04 14 30 12 80 10 bf 3d  |.0...U.#..0....=|
+000001f0  b6 a9 66 f2 b8 40 cf ea  b4 03 78 48 1a 41 30 19  |..f..@....xH.A0.|
+00000200  06 03 55 1d 11 04 12 30  10 82 0e 65 78 61 6d 70  |..U....0...examp|
+00000210  6c 65 2e 67 6f 6c 61 6e  67 30 0d 06 09 2a 86 48  |le.golang0...*.H|
+00000220  86 f7 0d 01 01 0b 05 00  03 81 81 00 92 7c af 91  |.............|..|
+00000230  55 12 18 96 59 31 a6 48  40 d5 2d d5 ee bb 02 a0  |U...Y1.H@.-.....|
+00000240  f5 c2 1e 7c 9b b3 30 7d  3c dc 76 da 4f 3d c0 fa  |...|..0}<.v.O=..|
+00000250  ae 2d 33 24 6b 03 7b 1b  67 59 11 21 b5 11 bc 77  |.-3$k.{.gY.!...w|
+00000260  b9 d9 e0 6e a8 2d 2e 35  fa 64 5f 22 3e 63 10 6b  |...n.-.5.d_">c.k|
+00000270  be ff 14 86 6d 0d f0 15  31 a8 14 38 1e 3b 84 87  |....m...1..8.;..|
+00000280  2c cb 98 ed 51 76 b9 b1  4f dd db 9b 84 04 86 40  |,...Qv..O......@|
+00000290  fa 51 dd ba b4 8d eb e3  46 de 46 b9 4f 86 c7 f9  |.Q......F.F.O...|
+000002a0  a4 c2 41 34 ac cc f6 ea  b0 ab 39 18 16 03 03 00  |..A4......9.....|
+000002b0  17 0d 00 00 13 02 01 40  00 0c 04 01 04 03 05 01  |.......@........|
+000002c0  05 03 02 01 02 03 00 00  16 03 03 00 04 0e 00 00  |................|
+000002d0  00                                                |.|
 >>> Flow 3 (client to server)
 00000000  16 03 03 01 fb 0b 00 01  f7 00 01 f4 00 01 f1 30  |...............0|
 00000010  82 01 ed 30 82 01 58 a0  03 02 01 02 02 01 00 30  |...0..X........0|
@@ -90,32 +85,32 @@
 000001d0  8b ec ab 67 be c8 64 b0  11 50 46 58 17 6b 99 1c  |...g..d..PFX.k..|
 000001e0  d3 1d fc 06 f1 0e e5 96  a8 0c f9 78 20 b7 44 18  |...........x .D.|
 000001f0  51 8d 10 7e 4f 94 67 df  a3 4e 70 73 8e 90 91 85  |Q..~O.g..Nps....|
-00000200  16 03 03 00 86 10 00 00  82 00 80 44 89 7d aa 26  |...........D.}.&|
-00000210  30 ce 6b db 25 70 b0 1e  16 fa 5b 3a dd 4a 4b bd  |0.k.%p....[:.JK.|
-00000220  ec ee 50 9d 21 ba 52 b5  51 4f a8 65 d8 2e 41 e2  |..P.!.R.QO.e..A.|
-00000230  e1 dc f3 1a df 58 4f 87  7a d3 e1 e1 1c 13 b2 0b  |.....XO.z.......|
-00000240  b7 43 b7 92 f2 df 19 bb  79 71 e0 71 44 ab 19 2f  |.C......yq.qD../|
-00000250  37 11 ac 62 50 b6 f1 53  fe aa b4 bc 29 8e 0b 4c  |7..bP..S....)..L|
-00000260  0b 12 8d d5 84 a9 fa a9  ea 16 aa c3 0d da 32 c8  |..............2.|
-00000270  e0 4c 9f 99 f8 69 cd a8  c3 b1 76 42 67 f3 ff 15  |.L...i....vBg...|
-00000280  52 95 43 66 da 49 43 25  9d e5 eb 16 03 03 00 88  |R.Cf.IC%........|
-00000290  0f 00 00 84 04 01 00 80  01 d5 0e 1c 75 97 89 52  |............u..R|
-000002a0  1a f0 cc ef 93 6e 71 b2  b1 38 8c 50 11 f7 a3 02  |.....nq..8.P....|
-000002b0  71 c4 d5 6f 8d 01 83 06  2e ea 5a 10 8a 0d d0 fc  |q..o......Z.....|
-000002c0  b6 a2 63 af 4f 99 b5 eb  ab fd 01 c2 fb 26 fc fd  |..c.O........&..|
-000002d0  ad 2c b3 63 b3 87 a6 f5  14 ea 7d e7 fe a8 e7 7e  |.,.c......}....~|
-000002e0  20 ab b9 f6 c3 58 bd c0  f3 96 eb 83 dc 42 6c 0d  | ....X.......Bl.|
-000002f0  5e e8 09 55 c7 b8 24 05  dd e1 7c af 9f 2c 22 6c  |^..U..$...|..,"l|
-00000300  fa b8 94 13 3b f1 09 e1  38 59 fc a1 8c cb aa ca  |....;...8Y......|
-00000310  f8 e0 2a 9c 36 f9 c3 2b  14 03 03 00 01 01 16 03  |..*.6..+........|
-00000320  03 00 24 d0 12 7c cc d2  3e 37 1f f4 7d b4 c0 fc  |..$..|..>7..}...|
-00000330  19 f6 c8 ea 62 12 e0 0d  af 62 d4 69 f7 96 5a c0  |....b....b.i..Z.|
-00000340  97 d3 bb b0 a3 f7 3f                              |......?|
+00000200  16 03 03 00 86 10 00 00  82 00 80 98 61 16 34 c4  |............a.4.|
+00000210  c6 0a 47 c1 de 87 b1 b7  70 1b 24 8d 7e 35 90 35  |..G.....p.$.~5.5|
+00000220  f7 a5 6f c7 c9 91 ad 46  4c 50 e5 7e 61 7c 49 66  |..o....FLP.~a|If|
+00000230  e9 fe 1e 2c 30 fa 22 03  36 8f 44 27 a7 d2 14 84  |...,0.".6.D'....|
+00000240  d0 1f 21 ca 40 35 d1 7d  31 3f e1 73 de 69 bc da  |..!.@5.}1?.s.i..|
+00000250  a5 96 8a b5 50 2b 4b 87  5a b3 fb e1 11 0a 29 59  |....P+K.Z.....)Y|
+00000260  13 2e e3 c2 05 d3 23 e8  09 0c 42 f6 8e 26 67 89  |......#...B..&g.|
+00000270  24 0f 08 2f 3d 24 2b 0c  a2 98 38 02 5c 95 9f ce  |$../=$+...8.\...|
+00000280  e3 75 ba 05 b5 f8 f0 07  e9 a1 44 16 03 03 00 88  |.u........D.....|
+00000290  0f 00 00 84 04 01 00 80  04 c0 bc 4b 23 59 ed 26  |...........K#Y.&|
+000002a0  8d 90 35 da 5b 55 88 e7  12 10 7b d7 1c 27 d1 c4  |..5.[U....{..'..|
+000002b0  d8 1b e2 e7 54 ad a4 be  00 6b 5b 61 2d ec 97 0c  |....T....k[a-...|
+000002c0  a5 9b ae ab 13 fa 94 53  1c 65 28 21 7d b5 c5 be  |.......S.e(!}...|
+000002d0  22 62 91 78 fc e3 de 84  5c 4e 0d f5 73 5e 20 49  |"b.x....\N..s^ I|
+000002e0  5a e2 f9 d3 2f 36 23 91  31 5b ee c7 0b 6f b3 35  |Z.../6#.1[...o.5|
+000002f0  2f 8a 51 84 3c fe 78 34  1f 8c 68 d3 fc 4f c6 5e  |/.Q.<.x4..h..O.^|
+00000300  7b fe b2 81 79 91 37 ee  7f f1 9b a4 88 5f 1b 44  |{...y.7......_.D|
+00000310  dc e9 36 bb d1 45 bb 1f  14 03 03 00 01 01 16 03  |..6..E..........|
+00000320  03 00 24 12 e7 8a 31 36  26 9f fe 45 95 cf 41 56  |..$...16&..E..AV|
+00000330  b4 69 ef e4 22 14 5a 4d  c8 79 a7 18 7b 68 a8 02  |.i..".ZM.y..{h..|
+00000340  75 ea 42 fe c4 a1 32                              |u.B...2|
 >>> Flow 4 (server to client)
-00000000  14 03 03 00 01 01 16 03  03 00 24 cd 20 85 1e 74  |..........$. ..t|
-00000010  18 b2 71 48 d5 10 61 c6  b0 18 26 83 c2 7f f1 b1  |..qH..a...&.....|
-00000020  2f b5 35 d0 47 a8 99 9a  9a a5 62 64 fb f9 29 17  |/.5.G.....bd..).|
-00000030  03 03 00 21 22 7b ed 61  e3 9b 6d 98 b9 23 98 e3  |...!"{.a..m..#..|
-00000040  55 11 b8 0f 7e 2b e1 c1  d4 f1 83 79 c3 f8 03 f0  |U...~+.....y....|
-00000050  02 5c 61 24 d7 15 03 03  00 16 14 2b a3 5a 56 f0  |.\a$.......+.ZV.|
-00000060  92 da d0 e6 32 91 d8 30  7a b4 d0 a2 93 f5 01 ea  |....2..0z.......|
+00000000  14 03 03 00 01 01 16 03  03 00 24 ae 6d 7b ac b6  |..........$.m{..|
+00000010  62 5c 40 65 6b 0e 5c 12  68 61 14 90 54 3e 24 78  |b\@ek.\.ha..T>$x|
+00000020  be 85 17 a0 9b de a0 00  e9 80 1b a9 0f e4 d7 17  |................|
+00000030  03 03 00 21 86 06 17 6b  62 02 a7 a0 71 fe c0 e4  |...!...kb...q...|
+00000040  44 00 54 dd cc a9 70 cf  bc 92 0d 40 07 62 f5 39  |D.T...p....@.b.9|
+00000050  2a 30 ab 7f cd 15 03 03  00 16 6f 8d c9 d4 62 02  |*0........o...b.|
+00000060  da 64 4c 89 32 86 9f 29  24 05 ed cc 77 9d e5 55  |.dL.2..)$...w..U|
diff --git a/third_party/gofrontend/libgo/go/crypto/tls/testdata/Server-TLSv12-ClientAuthRequestedNotGiven b/third_party/gofrontend/libgo/go/crypto/tls/testdata/Server-TLSv12-ClientAuthRequestedNotGiven
index 562fe1a..5de6dd8 100644
--- a/third_party/gofrontend/libgo/go/crypto/tls/testdata/Server-TLSv12-ClientAuthRequestedNotGiven
+++ b/third_party/gofrontend/libgo/go/crypto/tls/testdata/Server-TLSv12-ClientAuthRequestedNotGiven
@@ -1,81 +1,76 @@
 >>> Flow 1 (client to server)
-00000000  16 03 01 00 5c 01 00 00  58 03 03 52 cc 57 59 1b  |....\...X..R.WY.|
-00000010  08 fe f7 8a bf 07 84 2b  60 a6 13 2d 15 13 f8 b6  |.......+`..-....|
-00000020  d4 b6 3b f2 7a 98 ff 32  a0 68 7c 00 00 04 00 05  |..;.z..2.h|.....|
-00000030  00 ff 01 00 00 2b 00 0d  00 22 00 20 06 01 06 02  |.....+...". ....|
+00000000  16 03 01 00 5a 01 00 00  56 03 03 52 b6 c5 b4 e3  |....Z...V..R....|
+00000010  35 ce 4e b2 9c e0 38 09  e7 fe 00 a2 1a 0a 43 eb  |5.N...8.......C.|
+00000020  df 98 6a 34 71 f9 d0 f8  5d e7 5e 00 00 04 00 05  |..j4q...].^.....|
+00000030  00 ff 01 00 00 29 00 0d  00 20 00 1e 06 01 06 02  |.....)... ......|
 00000040  06 03 05 01 05 02 05 03  04 01 04 02 04 03 03 01  |................|
-00000050  03 02 03 03 02 01 02 02  02 03 01 01 00 0f 00 01  |................|
-00000060  01                                                |.|
+00000050  03 02 03 03 02 01 02 02  02 03 00 0f 00 01 01     |...............|
 >>> Flow 2 (server to client)
 00000000  16 03 03 00 31 02 00 00  2d 03 03 00 00 00 00 00  |....1...-.......|
 00000010  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
 00000020  00 00 00 00 00 00 00 00  00 00 00 00 00 05 00 00  |................|
-00000030  05 ff 01 00 01 00 16 03  03 02 be 0b 00 02 ba 00  |................|
-00000040  02 b7 00 02 b4 30 82 02  b0 30 82 02 19 a0 03 02  |.....0...0......|
-00000050  01 02 02 09 00 85 b0 bb  a4 8a 7f b8 ca 30 0d 06  |.............0..|
-00000060  09 2a 86 48 86 f7 0d 01  01 05 05 00 30 45 31 0b  |.*.H........0E1.|
-00000070  30 09 06 03 55 04 06 13  02 41 55 31 13 30 11 06  |0...U....AU1.0..|
-00000080  03 55 04 08 13 0a 53 6f  6d 65 2d 53 74 61 74 65  |.U....Some-State|
-00000090  31 21 30 1f 06 03 55 04  0a 13 18 49 6e 74 65 72  |1!0...U....Inter|
-000000a0  6e 65 74 20 57 69 64 67  69 74 73 20 50 74 79 20  |net Widgits Pty |
-000000b0  4c 74 64 30 1e 17 0d 31  30 30 34 32 34 30 39 30  |Ltd0...100424090|
-000000c0  39 33 38 5a 17 0d 31 31  30 34 32 34 30 39 30 39  |938Z..1104240909|
-000000d0  33 38 5a 30 45 31 0b 30  09 06 03 55 04 06 13 02  |38Z0E1.0...U....|
-000000e0  41 55 31 13 30 11 06 03  55 04 08 13 0a 53 6f 6d  |AU1.0...U....Som|
-000000f0  65 2d 53 74 61 74 65 31  21 30 1f 06 03 55 04 0a  |e-State1!0...U..|
-00000100  13 18 49 6e 74 65 72 6e  65 74 20 57 69 64 67 69  |..Internet Widgi|
-00000110  74 73 20 50 74 79 20 4c  74 64 30 81 9f 30 0d 06  |ts Pty Ltd0..0..|
-00000120  09 2a 86 48 86 f7 0d 01  01 01 05 00 03 81 8d 00  |.*.H............|
-00000130  30 81 89 02 81 81 00 bb  79 d6 f5 17 b5 e5 bf 46  |0.......y......F|
-00000140  10 d0 dc 69 be e6 2b 07  43 5a d0 03 2d 8a 7a 43  |...i..+.CZ..-.zC|
-00000150  85 b7 14 52 e7 a5 65 4c  2c 78 b8 23 8c b5 b4 82  |...R..eL,x.#....|
-00000160  e5 de 1f 95 3b 7e 62 a5  2c a5 33 d6 fe 12 5c 7a  |....;~b.,.3...\z|
-00000170  56 fc f5 06 bf fa 58 7b  26 3f b5 cd 04 d3 d0 c9  |V.....X{&?......|
-00000180  21 96 4a c7 f4 54 9f 5a  bf ef 42 71 00 fe 18 99  |!.J..T.Z..Bq....|
-00000190  07 7f 7e 88 7d 7d f1 04  39 c4 a2 2e db 51 c9 7c  |..~.}}..9....Q.||
-000001a0  e3 c0 4c 3b 32 66 01 cf  af b1 1d b8 71 9a 1d db  |..L;2f......q...|
-000001b0  db 89 6b ae da 2d 79 02  03 01 00 01 a3 81 a7 30  |..k..-y........0|
-000001c0  81 a4 30 1d 06 03 55 1d  0e 04 16 04 14 b1 ad e2  |..0...U.........|
-000001d0  85 5a cf cb 28 db 69 ce  23 69 de d3 26 8e 18 88  |.Z..(.i.#i..&...|
-000001e0  39 30 75 06 03 55 1d 23  04 6e 30 6c 80 14 b1 ad  |90u..U.#.n0l....|
-000001f0  e2 85 5a cf cb 28 db 69  ce 23 69 de d3 26 8e 18  |..Z..(.i.#i..&..|
-00000200  88 39 a1 49 a4 47 30 45  31 0b 30 09 06 03 55 04  |.9.I.G0E1.0...U.|
-00000210  06 13 02 41 55 31 13 30  11 06 03 55 04 08 13 0a  |...AU1.0...U....|
-00000220  53 6f 6d 65 2d 53 74 61  74 65 31 21 30 1f 06 03  |Some-State1!0...|
-00000230  55 04 0a 13 18 49 6e 74  65 72 6e 65 74 20 57 69  |U....Internet Wi|
-00000240  64 67 69 74 73 20 50 74  79 20 4c 74 64 82 09 00  |dgits Pty Ltd...|
-00000250  85 b0 bb a4 8a 7f b8 ca  30 0c 06 03 55 1d 13 04  |........0...U...|
-00000260  05 30 03 01 01 ff 30 0d  06 09 2a 86 48 86 f7 0d  |.0....0...*.H...|
-00000270  01 01 05 05 00 03 81 81  00 08 6c 45 24 c7 6b b1  |..........lE$.k.|
-00000280  59 ab 0c 52 cc f2 b0 14  d7 87 9d 7a 64 75 b5 5a  |Y..R.......zdu.Z|
-00000290  95 66 e4 c5 2b 8e ae 12  66 1f eb 4f 38 b3 6e 60  |.f..+...f..O8.n`|
-000002a0  d3 92 fd f7 41 08 b5 25  13 b1 18 7a 24 fb 30 1d  |....A..%...z$.0.|
-000002b0  ba ed 98 b9 17 ec e7 d7  31 59 db 95 d3 1d 78 ea  |........1Y....x.|
-000002c0  50 56 5c d5 82 5a 2d 5a  5f 33 c4 b6 d8 c9 75 90  |PV\..Z-Z_3....u.|
-000002d0  96 8c 0f 52 98 b5 cd 98  1f 89 20 5f f2 a0 1c a3  |...R...... _....|
-000002e0  1b 96 94 dd a9 fd 57 e9  70 e8 26 6d 71 99 9b 26  |......W.p.&mq..&|
-000002f0  6e 38 50 29 6c 90 a7 bd  d9 16 03 03 00 0f 0d 00  |n8P)l...........|
-00000300  00 0b 02 01 40 00 04 04  01 04 03 00 00 16 03 03  |....@...........|
-00000310  00 04 0e 00 00 00                                 |......|
+00000030  05 ff 01 00 01 00 16 03  03 02 71 0b 00 02 6d 00  |..........q...m.|
+00000040  02 6a 00 02 67 30 82 02  63 30 82 01 cc a0 03 02  |.j..g0..c0......|
+00000050  01 02 02 09 00 a2 73 00  0c 81 00 cb f3 30 0d 06  |......s......0..|
+00000060  09 2a 86 48 86 f7 0d 01  01 0b 05 00 30 2b 31 17  |.*.H........0+1.|
+00000070  30 15 06 03 55 04 0a 13  0e 47 6f 6f 67 6c 65 20  |0...U....Google |
+00000080  54 45 53 54 49 4e 47 31  10 30 0e 06 03 55 04 03  |TESTING1.0...U..|
+00000090  13 07 47 6f 20 52 6f 6f  74 30 1e 17 0d 31 35 30  |..Go Root0...150|
+000000a0  31 30 31 30 30 30 30 30  30 5a 17 0d 32 35 30 31  |101000000Z..2501|
+000000b0  30 31 30 30 30 30 30 30  5a 30 26 31 17 30 15 06  |01000000Z0&1.0..|
+000000c0  03 55 04 0a 13 0e 47 6f  6f 67 6c 65 20 54 45 53  |.U....Google TES|
+000000d0  54 49 4e 47 31 0b 30 09  06 03 55 04 03 13 02 47  |TING1.0...U....G|
+000000e0  6f 30 81 9f 30 0d 06 09  2a 86 48 86 f7 0d 01 01  |o0..0...*.H.....|
+000000f0  01 05 00 03 81 8d 00 30  81 89 02 81 81 00 af 87  |.......0........|
+00000100  88 f6 20 1b 95 65 6c 14  ab 44 05 af 3b 45 14 e3  |.. ..el..D..;E..|
+00000110  b7 6d fd 00 63 4d 95 7f  fe 6a 62 35 86 c0 4a f9  |.m..cM...jb5..J.|
+00000120  18 7c f6 aa 25 5e 7a 64  31 66 00 ba f4 8e 92 af  |.|..%^zd1f......|
+00000130  c7 6b d8 76 d4 f3 5f 41  cb 6e 56 15 97 1b 97 c1  |.k.v.._A.nV.....|
+00000140  3c 12 39 21 66 3d 2b 16  d1 bc db 1c c0 a7 da b7  |<.9!f=+.........|
+00000150  ca ad ba da cb d5 21 50  ec de 8d ab d1 6b 81 4b  |......!P.....k.K|
+00000160  89 02 f3 c4 be c1 6c 89  b1 44 84 bd 21 d1 04 7d  |......l..D..!..}|
+00000170  9d 16 4d f9 82 15 f6 ef  fa d6 09 47 f2 fb 02 03  |..M........G....|
+00000180  01 00 01 a3 81 93 30 81  90 30 0e 06 03 55 1d 0f  |......0..0...U..|
+00000190  01 01 ff 04 04 03 02 05  a0 30 1d 06 03 55 1d 25  |.........0...U.%|
+000001a0  04 16 30 14 06 08 2b 06  01 05 05 07 03 01 06 08  |..0...+.........|
+000001b0  2b 06 01 05 05 07 03 02  30 0c 06 03 55 1d 13 01  |+.......0...U...|
+000001c0  01 ff 04 02 30 00 30 19  06 03 55 1d 0e 04 12 04  |....0.0...U.....|
+000001d0  10 12 50 8d 89 6f 1b d1  dc 54 4d 6e cb 69 5e 06  |..P..o...TMn.i^.|
+000001e0  f4 30 1b 06 03 55 1d 23  04 14 30 12 80 10 bf 3d  |.0...U.#..0....=|
+000001f0  b6 a9 66 f2 b8 40 cf ea  b4 03 78 48 1a 41 30 19  |..f..@....xH.A0.|
+00000200  06 03 55 1d 11 04 12 30  10 82 0e 65 78 61 6d 70  |..U....0...examp|
+00000210  6c 65 2e 67 6f 6c 61 6e  67 30 0d 06 09 2a 86 48  |le.golang0...*.H|
+00000220  86 f7 0d 01 01 0b 05 00  03 81 81 00 92 7c af 91  |.............|..|
+00000230  55 12 18 96 59 31 a6 48  40 d5 2d d5 ee bb 02 a0  |U...Y1.H@.-.....|
+00000240  f5 c2 1e 7c 9b b3 30 7d  3c dc 76 da 4f 3d c0 fa  |...|..0}<.v.O=..|
+00000250  ae 2d 33 24 6b 03 7b 1b  67 59 11 21 b5 11 bc 77  |.-3$k.{.gY.!...w|
+00000260  b9 d9 e0 6e a8 2d 2e 35  fa 64 5f 22 3e 63 10 6b  |...n.-.5.d_">c.k|
+00000270  be ff 14 86 6d 0d f0 15  31 a8 14 38 1e 3b 84 87  |....m...1..8.;..|
+00000280  2c cb 98 ed 51 76 b9 b1  4f dd db 9b 84 04 86 40  |,...Qv..O......@|
+00000290  fa 51 dd ba b4 8d eb e3  46 de 46 b9 4f 86 c7 f9  |.Q......F.F.O...|
+000002a0  a4 c2 41 34 ac cc f6 ea  b0 ab 39 18 16 03 03 00  |..A4......9.....|
+000002b0  17 0d 00 00 13 02 01 40  00 0c 04 01 04 03 05 01  |.......@........|
+000002c0  05 03 02 01 02 03 00 00  16 03 03 00 04 0e 00 00  |................|
+000002d0  00                                                |.|
 >>> Flow 3 (client to server)
 00000000  16 03 03 00 07 0b 00 00  03 00 00 00 16 03 03 00  |................|
-00000010  86 10 00 00 82 00 80 6b  51 48 d3 18 7d 30 e0 0c  |.......kQH..}0..|
-00000020  20 8d f3 e4 39 47 30 0e  a5 85 79 f9 8b 11 50 9e  | ...9G0...y...P.|
-00000030  81 71 5c 26 c6 bb cb aa  d5 00 d1 89 79 b1 77 2d  |.q\&........y.w-|
-00000040  eb 9b 86 7c 52 c6 f7 b7  10 b0 b6 94 22 51 b8 12  |...|R......."Q..|
-00000050  3c 09 35 8e 1b cc f4 3b  b7 b8 78 ab 89 59 41 49  |<.5....;..x..YAI|
-00000060  21 31 eb f0 f8 94 63 3d  e6 96 8f b6 63 95 05 dd  |!1....c=....c...|
-00000070  46 b3 00 8a d6 83 75 99  1b 5a 48 0a 23 b5 10 c1  |F.....u..ZH.#...|
-00000080  95 b5 bc 15 72 b5 f5 a0  62 e2 1d c0 ff d2 87 a5  |....r...b.......|
-00000090  97 5c 33 49 a7 26 35 14  03 03 00 01 01 16 03 03  |.\3I.&5.........|
-000000a0  00 24 61 38 1f 9d fb d9  65 2e 02 07 fb be f9 85  |.$a8....e.......|
-000000b0  8d 15 34 c0 d1 0e 4e 10  3c 25 60 2f ac 04 21 66  |..4...N.<%`/..!f|
-000000c0  04 9d 9a 60 31 72                                 |...`1r|
+00000010  86 10 00 00 82 00 80 2e  8e cb 6c f5 db 45 5b f0  |..........l..E[.|
+00000020  67 7d b1 ac 87 c2 d6 e9  ea 37 40 15 2a ea a1 af  |g}.......7@.*...|
+00000030  ed 71 68 18 9c 6c 84 20  52 3e 38 94 8e d9 cd b3  |.qh..l. R>8.....|
+00000040  15 73 8b db d7 ff 1d 8a  ed a6 f4 00 7d d0 0a 1e  |.s..........}...|
+00000050  9a 1b 5c 59 f6 a0 29 62  03 a1 c6 bf 8a 57 14 06  |..\Y..)b.....W..|
+00000060  9a e8 03 72 bc cd cd 6f  6d e2 ce a8 41 7a f0 65  |...r...om...Az.e|
+00000070  42 0c 7b dd 93 d7 ab 37  f8 2a b3 c4 72 95 61 e1  |B.{....7.*..r.a.|
+00000080  75 98 f5 99 69 ef 0a d0  00 41 0f 05 87 13 d3 7d  |u...i....A.....}|
+00000090  ba 74 34 43 9a 6c d0 14  03 03 00 01 01 16 03 03  |.t4C.l..........|
+000000a0  00 24 87 7e 7d 48 ca 17  9c ad 30 b8 6a 05 2f d3  |.$.~}H....0.j./.|
+000000b0  fc 18 2e df fd f5 0e 38  c3 06 57 4c 27 66 02 af  |.......8..WL'f..|
+000000c0  6d 78 4d 2e b6 dc                                 |mxM...|
 >>> Flow 4 (server to client)
-00000000  14 03 03 00 01 01 16 03  03 00 24 fe 0e 3e 84 af  |..........$..>..|
-00000010  e5 6b 10 ed 41 9c 2b e0  ba e0 2b 53 61 36 1b 40  |.k..A.+...+Sa6.@|
-00000020  35 de 3a c7 c3 5c df 74  67 f7 05 74 84 f5 e1 17  |5.:..\.tg..t....|
-00000030  03 03 00 21 d3 8d 81 85  b7 1f 30 bd 89 33 f9 81  |...!......0..3..|
-00000040  89 f7 af d1 be b0 c1 46  e3 df 32 f6 dc 2f 4d 82  |.......F..2../M.|
-00000050  0a 84 9f 5b 03 15 03 03  00 16 13 af 37 91 82 67  |...[........7..g|
-00000060  b0 7c 5e 0e ec 8e cc 31  a0 ea a5 72 a4 2b 0b 73  |.|^....1...r.+.s|
+00000000  14 03 03 00 01 01 16 03  03 00 24 cf ee f6 28 ea  |..........$...(.|
+00000010  df e2 7e 9a 75 e0 f9 b4  c4 c2 57 3a 54 26 db 7f  |..~.u.....W:T&..|
+00000020  c4 19 6d b6 d6 c7 b1 05  7f 92 21 9e 51 1a 0a 17  |..m.......!.Q...|
+00000030  03 03 00 21 87 48 77 c4  eb 7c 5d 13 3b f4 8d 08  |...!.Hw..|].;...|
+00000040  f9 35 c3 d2 e5 c0 8c ea  15 c9 2d c5 e0 70 fd 7c  |.5........-..p.||
+00000050  de 93 4f 8c 8d 15 03 03  00 16 d4 8a d5 6a fc db  |..O..........j..|
+00000060  c7 1d 1f 76 64 b9 31 68  72 cc 58 de 9f 2a a6 45  |...vd.1hr.X..*.E|
diff --git a/third_party/gofrontend/libgo/go/crypto/tls/testdata/Server-TLSv12-ECDHE-ECDSA-AES b/third_party/gofrontend/libgo/go/crypto/tls/testdata/Server-TLSv12-ECDHE-ECDSA-AES
index aacbb86..3b7238a 100644
--- a/third_party/gofrontend/libgo/go/crypto/tls/testdata/Server-TLSv12-ECDHE-ECDSA-AES
+++ b/third_party/gofrontend/libgo/go/crypto/tls/testdata/Server-TLSv12-ECDHE-ECDSA-AES
@@ -1,15 +1,15 @@
 >>> Flow 1 (client to server)
-00000000  16 03 01 00 9c 01 00 00  98 03 03 53 04 f0 f9 09  |...........S....|
-00000010  13 56 01 37 84 b1 32 59  4c 73 b1 8e bb 02 1a 32  |.V.7..2YLs.....2|
-00000020  db ab 8c e6 ed ad 7f 52  9a 59 39 00 00 04 c0 0a  |.......R.Y9.....|
-00000030  00 ff 01 00 00 6b 00 0b  00 04 03 00 01 02 00 0a  |.....k..........|
-00000040  00 34 00 32 00 0e 00 0d  00 19 00 0b 00 0c 00 18  |.4.2............|
-00000050  00 09 00 0a 00 16 00 17  00 08 00 06 00 07 00 14  |................|
-00000060  00 15 00 04 00 05 00 12  00 13 00 01 00 02 00 03  |................|
-00000070  00 0f 00 10 00 11 00 0d  00 22 00 20 06 01 06 02  |.........". ....|
-00000080  06 03 05 01 05 02 05 03  04 01 04 02 04 03 03 01  |................|
-00000090  03 02 03 03 02 01 02 02  02 03 01 01 00 0f 00 01  |................|
-000000a0  01                                                |.|
+00000000  16 03 01 00 a1 01 00 00  9d 03 03 0f b7 07 5f c7  |.............._.|
+00000010  18 b8 39 6d 92 b3 90 ed  bf 5c 48 7c 6a 56 ee e9  |..9m.....\H|jV..|
+00000020  7a 5b 5f 71 a4 f0 7f 47  57 73 78 00 00 04 c0 0a  |z[_q...GWsx.....|
+00000030  00 ff 02 01 00 00 6f 00  0b 00 04 03 00 01 02 00  |......o.........|
+00000040  0a 00 3a 00 38 00 0e 00  0d 00 19 00 1c 00 0b 00  |..:.8...........|
+00000050  0c 00 1b 00 18 00 09 00  0a 00 1a 00 16 00 17 00  |................|
+00000060  08 00 06 00 07 00 14 00  15 00 04 00 05 00 12 00  |................|
+00000070  13 00 01 00 02 00 03 00  0f 00 10 00 11 00 0d 00  |................|
+00000080  20 00 1e 06 01 06 02 06  03 05 01 05 02 05 03 04  | ...............|
+00000090  01 04 02 04 03 03 01 03  02 03 03 02 01 02 02 02  |................|
+000000a0  03 00 0f 00 01 01                                 |......|
 >>> Flow 2 (server to client)
 00000000  16 03 03 00 31 02 00 00  2d 03 03 00 00 00 00 00  |....1...-.......|
 00000010  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
@@ -52,38 +52,38 @@
 00000260  75 71 b5 e5 54 5b 12 2e  8f 09 67 fd a7 24 20 3e  |uq..T[....g..$ >|
 00000270  b2 56 1c ce 97 28 5e f8  2b 2d 4f 9e f1 07 9f 6c  |.V...(^.+-O....l|
 00000280  4b 5b 83 56 e2 32 42 e9  58 b6 d7 49 a6 b5 68 1a  |K[.V.2B.X..I..h.|
-00000290  41 03 56 6b dc 5a 89 04  03 00 8b 30 81 88 02 42  |A.Vk.Z.....0...B|
-000002a0  00 c6 85 8e 06 b7 04 04  e9 cd 9e 3e cb 66 23 95  |...........>.f#.|
-000002b0  b4 42 9c 64 81 39 05 3f  b5 21 f8 28 af 60 6b 4d  |.B.d.9.?.!.(.`kM|
-000002c0  3d ba a1 4b 5e 77 ef e7  59 28 fe 1d c1 27 a2 ff  |=..K^w..Y(...'..|
-000002d0  a8 de 33 48 b3 c1 85 6a  42 9b f9 7e 7e 31 c2 e5  |..3H...jB..~~1..|
-000002e0  bd 66 02 42 00 ad 7d 06  35 ab ec 8d ac d4 ba 1b  |.f.B..}.5.......|
-000002f0  49 5e 05 5f f0 97 93 82  b8 2b 8d 91 98 63 8e b4  |I^._.....+...c..|
-00000300  14 62 db 1e c9 2c 13 ae  b7 d3 17 38 23 2f f6 7f  |.b...,.....8#/..|
-00000310  0c 4d d3 33 d2 79 d1 77  ee cb b1 c2 fc 34 b8 69  |.M.3.y.w.....4.i|
-00000320  f9 10 8b 61 89 85 16 03  03 00 04 0e 00 00 00     |...a...........|
+00000290  41 03 56 6b dc 5a 89 05  03 00 8b 30 81 88 02 42  |A.Vk.Z.....0...B|
+000002a0  00 d3 cf 21 cd 3c 2e 11  f5 f8 1d c8 c1 57 4b f8  |...!.<.......WK.|
+000002b0  1a c0 2b 1d 47 0f 2d a5  ac a1 c8 83 5d 76 87 05  |..+.G.-.....]v..|
+000002c0  2b 0d 36 d5 57 9f b9 8a  a0 a2 94 67 6a cd 29 db  |+.6.W......gj.).|
+000002d0  04 b0 6b 06 d9 f7 17 9f  1c 60 92 e7 4e 50 48 7f  |..k......`..NPH.|
+000002e0  dc d0 02 42 01 56 fd 38  bd 05 a5 16 6d 91 d1 ce  |...B.V.8....m...|
+000002f0  bb 8c 45 b2 76 2f 92 9c  8b 94 57 7d de 53 8b 7b  |..E.v/....W}.S.{|
+00000300  80 26 6c 4a 43 4b a6 c9  46 49 08 ab c7 57 f3 d9  |.&lJCK..FI...W..|
+00000310  fa 1d 55 fe 91 de 8a 0d  8b d1 44 96 87 85 cb 02  |..U.......D.....|
+00000320  76 9c 00 ad 5f b8 16 03  03 00 04 0e 00 00 00     |v..._..........|
 >>> Flow 3 (client to server)
-00000000  16 03 03 00 46 10 00 00  42 41 04 dd 22 68 a1 4e  |....F...BA.."h.N|
-00000010  04 1b 47 f9 c5 7d 04 1d  d8 fe 84 fa be 31 2e a7  |..G..}.......1..|
-00000020  f8 e5 b8 14 92 44 99 11  0e 34 97 fc e5 b1 91 cf  |.....D...4......|
-00000030  a4 d1 3f b4 71 94 c6 06  16 f0 98 c0 3e 05 f9 2f  |..?.q.......>../|
-00000040  0a 97 78 3d ef dc fa a2  d7 ee 7d 14 03 03 00 01  |..x=......}.....|
-00000050  01 16 03 03 00 40 90 bf  7f e9 c9 6e d1 80 f5 12  |.....@.....n....|
-00000060  6d c5 b7 c5 15 4b 18 a5  d3 18 1e f8 8c 4d 7e 6d  |m....K.......M~m|
-00000070  03 60 29 7c 45 7c b2 ca  8c 07 71 70 aa 23 fa 6e  |.`)|E|....qp.#.n|
-00000080  d9 0b 0a 32 4c 9e e5 00  f9 19 9b b6 8d dc d3 67  |...2L..........g|
-00000090  3d 0f bb b8 4b 9e                                 |=...K.|
+00000000  16 03 03 00 46 10 00 00  42 41 04 0b dc ea 22 05  |....F...BA....".|
+00000010  44 c2 09 47 65 31 3b 0b  e1 05 1a 87 8c 2d 3b 56  |D..Ge1;......-;V|
+00000020  49 34 27 3e d6 3b 93 e2  12 7f 5d 7b dc 85 c8 96  |I4'>.;....]{....|
+00000030  4c 8c f9 18 6f 15 cf db  6e 2c 14 6a c9 dd 1c 70  |L...o...n,.j...p|
+00000040  7e 05 c4 17 71 76 df 10  ee 8c b1 14 03 03 00 01  |~...qv..........|
+00000050  01 16 03 03 00 40 ff 12  88 36 3c 00 17 d1 b9 41  |.....@...6<....A|
+00000060  7a 12 25 94 4c 90 65 62  d8 09 ab f9 b4 ee c3 de  |z.%.L.eb........|
+00000070  46 2f cb ee 18 76 4f 76  8e dd 89 fc 7a 21 3b 5f  |F/...vOv....z!;_|
+00000080  ff ac 1c 03 aa be 96 82  82 ea 2e 22 2a 80 b3 86  |..........."*...|
+00000090  38 e4 4d 90 91 46                                 |8.M..F|
 >>> Flow 4 (server to client)
 00000000  14 03 03 00 01 01 16 03  03 00 40 00 00 00 00 00  |..........@.....|
-00000010  00 00 00 00 00 00 00 00  00 00 00 a1 6e e5 d1 ca  |............n...|
-00000020  03 f4 77 dc ec ee 5d f0  22 5e 7f 55 1a 8d ad 45  |..w...]."^.U...E|
-00000030  09 f1 3b b2 61 36 dc 3d  2a 1e 1f e5 a7 84 76 a9  |..;.a6.=*.....v.|
-00000040  41 5b 86 03 ac 22 18 20  9b a9 29 17 03 03 00 40  |A[...". ..)....@|
+00000010  00 00 00 00 00 00 00 00  00 00 00 e5 c1 f0 6a db  |..............j.|
+00000020  05 98 ed 33 94 73 7f 13  7f 78 17 7f d1 9e c5 a7  |...3.s...x......|
+00000030  62 7f 85 14 2c 7d b2 8e  ef 75 a9 df 92 cc 22 20  |b...,}...u...." |
+00000040  66 08 85 22 d3 ea 5c 4c  4c c8 d7 17 03 03 00 40  |f.."..\LL......@|
 00000050  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
-00000060  f5 cb 28 1e b5 bc 82 7f  82 38 54 14 e8 b9 6d 3b  |..(......8T...m;|
-00000070  bc 99 d6 0e f9 00 96 99  a8 92 2e 86 9d 62 4e 90  |.............bN.|
-00000080  27 52 58 45 20 93 90 a1  f3 a8 89 2b e7 21 24 16  |'RXE ......+.!$.|
+00000060  f2 20 07 d2 13 ca ed 01  c9 7b 91 14 01 2c 08 f5  |. .......{...,..|
+00000070  8a 69 94 bc 19 9a d9 65  6b 15 04 b4 45 17 ec 6f  |.i.....ek...E..o|
+00000080  85 de 31 dc a2 de 8b 4d  53 57 66 4a 29 21 5a 20  |..1....MSWfJ)!Z |
 00000090  15 03 03 00 30 00 00 00  00 00 00 00 00 00 00 00  |....0...........|
-000000a0  00 00 00 00 00 a8 2a ab  8f b0 ce 49 8b fd a5 c9  |......*....I....|
-000000b0  11 b2 04 83 18 f3 1d 6c  82 34 1d df dd 2f 45 3b  |.......l.4.../E;|
-000000c0  27 8a 0f 16 69                                    |'...i|
+000000a0  00 00 00 00 00 55 15 f7  89 8d 75 57 7e 92 db ec  |.....U....uW~...|
+000000b0  32 ec 07 5c 83 32 36 59  61 f1 9d a6 7a eb 76 c1  |2..\.26Ya...z.v.|
+000000c0  c7 96 3f 4d 0a                                    |..?M.|
diff --git a/third_party/gofrontend/libgo/go/crypto/tls/testdata/Server-TLSv12-IssueTicket b/third_party/gofrontend/libgo/go/crypto/tls/testdata/Server-TLSv12-IssueTicket
index e3e62f2..20a0731 100644
--- a/third_party/gofrontend/libgo/go/crypto/tls/testdata/Server-TLSv12-IssueTicket
+++ b/third_party/gofrontend/libgo/go/crypto/tls/testdata/Server-TLSv12-IssueTicket
@@ -1,87 +1,83 @@
 >>> Flow 1 (client to server)
-00000000  16 03 01 00 60 01 00 00  5c 03 03 52 cc 57 59 7e  |....`...\..R.WY~|
-00000010  43 5c 3b fd 50 ab 61 3f  64 a4 f9 bd ba 8c 28 e1  |C\;.P.a?d.....(.|
-00000020  f9 a1 45 7e 48 9e 62 af  25 de 0e 00 00 04 00 05  |..E~H.b.%.......|
-00000030  00 ff 01 00 00 2f 00 23  00 00 00 0d 00 22 00 20  |...../.#.....". |
+00000000  16 03 01 00 5e 01 00 00  5a 03 03 f0 0a 06 d0 65  |....^...Z......e|
+00000010  1c c3 90 ac dc 61 42 e5  b8 a9 17 fb e7 c3 1e bd  |.....aB.........|
+00000020  d9 09 5a 63 71 e2 f9 58  db 26 6e 00 00 04 00 05  |..Zcq..X.&n.....|
+00000030  00 ff 01 00 00 2d 00 23  00 00 00 0d 00 20 00 1e  |.....-.#..... ..|
 00000040  06 01 06 02 06 03 05 01  05 02 05 03 04 01 04 02  |................|
-00000050  04 03 03 01 03 02 03 03  02 01 02 02 02 03 01 01  |................|
-00000060  00 0f 00 01 01                                    |.....|
+00000050  04 03 03 01 03 02 03 03  02 01 02 02 02 03 00 0f  |................|
+00000060  00 01 01                                          |...|
 >>> Flow 2 (server to client)
 00000000  16 03 03 00 35 02 00 00  31 03 03 00 00 00 00 00  |....5...1.......|
 00000010  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
 00000020  00 00 00 00 00 00 00 00  00 00 00 00 00 05 00 00  |................|
-00000030  09 00 23 00 00 ff 01 00  01 00 16 03 03 02 be 0b  |..#.............|
-00000040  00 02 ba 00 02 b7 00 02  b4 30 82 02 b0 30 82 02  |.........0...0..|
-00000050  19 a0 03 02 01 02 02 09  00 85 b0 bb a4 8a 7f b8  |................|
-00000060  ca 30 0d 06 09 2a 86 48  86 f7 0d 01 01 05 05 00  |.0...*.H........|
-00000070  30 45 31 0b 30 09 06 03  55 04 06 13 02 41 55 31  |0E1.0...U....AU1|
-00000080  13 30 11 06 03 55 04 08  13 0a 53 6f 6d 65 2d 53  |.0...U....Some-S|
-00000090  74 61 74 65 31 21 30 1f  06 03 55 04 0a 13 18 49  |tate1!0...U....I|
-000000a0  6e 74 65 72 6e 65 74 20  57 69 64 67 69 74 73 20  |nternet Widgits |
-000000b0  50 74 79 20 4c 74 64 30  1e 17 0d 31 30 30 34 32  |Pty Ltd0...10042|
-000000c0  34 30 39 30 39 33 38 5a  17 0d 31 31 30 34 32 34  |4090938Z..110424|
-000000d0  30 39 30 39 33 38 5a 30  45 31 0b 30 09 06 03 55  |090938Z0E1.0...U|
-000000e0  04 06 13 02 41 55 31 13  30 11 06 03 55 04 08 13  |....AU1.0...U...|
-000000f0  0a 53 6f 6d 65 2d 53 74  61 74 65 31 21 30 1f 06  |.Some-State1!0..|
-00000100  03 55 04 0a 13 18 49 6e  74 65 72 6e 65 74 20 57  |.U....Internet W|
-00000110  69 64 67 69 74 73 20 50  74 79 20 4c 74 64 30 81  |idgits Pty Ltd0.|
-00000120  9f 30 0d 06 09 2a 86 48  86 f7 0d 01 01 01 05 00  |.0...*.H........|
-00000130  03 81 8d 00 30 81 89 02  81 81 00 bb 79 d6 f5 17  |....0.......y...|
-00000140  b5 e5 bf 46 10 d0 dc 69  be e6 2b 07 43 5a d0 03  |...F...i..+.CZ..|
-00000150  2d 8a 7a 43 85 b7 14 52  e7 a5 65 4c 2c 78 b8 23  |-.zC...R..eL,x.#|
-00000160  8c b5 b4 82 e5 de 1f 95  3b 7e 62 a5 2c a5 33 d6  |........;~b.,.3.|
-00000170  fe 12 5c 7a 56 fc f5 06  bf fa 58 7b 26 3f b5 cd  |..\zV.....X{&?..|
-00000180  04 d3 d0 c9 21 96 4a c7  f4 54 9f 5a bf ef 42 71  |....!.J..T.Z..Bq|
-00000190  00 fe 18 99 07 7f 7e 88  7d 7d f1 04 39 c4 a2 2e  |......~.}}..9...|
-000001a0  db 51 c9 7c e3 c0 4c 3b  32 66 01 cf af b1 1d b8  |.Q.|..L;2f......|
-000001b0  71 9a 1d db db 89 6b ae  da 2d 79 02 03 01 00 01  |q.....k..-y.....|
-000001c0  a3 81 a7 30 81 a4 30 1d  06 03 55 1d 0e 04 16 04  |...0..0...U.....|
-000001d0  14 b1 ad e2 85 5a cf cb  28 db 69 ce 23 69 de d3  |.....Z..(.i.#i..|
-000001e0  26 8e 18 88 39 30 75 06  03 55 1d 23 04 6e 30 6c  |&...90u..U.#.n0l|
-000001f0  80 14 b1 ad e2 85 5a cf  cb 28 db 69 ce 23 69 de  |......Z..(.i.#i.|
-00000200  d3 26 8e 18 88 39 a1 49  a4 47 30 45 31 0b 30 09  |.&...9.I.G0E1.0.|
-00000210  06 03 55 04 06 13 02 41  55 31 13 30 11 06 03 55  |..U....AU1.0...U|
-00000220  04 08 13 0a 53 6f 6d 65  2d 53 74 61 74 65 31 21  |....Some-State1!|
-00000230  30 1f 06 03 55 04 0a 13  18 49 6e 74 65 72 6e 65  |0...U....Interne|
-00000240  74 20 57 69 64 67 69 74  73 20 50 74 79 20 4c 74  |t Widgits Pty Lt|
-00000250  64 82 09 00 85 b0 bb a4  8a 7f b8 ca 30 0c 06 03  |d...........0...|
-00000260  55 1d 13 04 05 30 03 01  01 ff 30 0d 06 09 2a 86  |U....0....0...*.|
-00000270  48 86 f7 0d 01 01 05 05  00 03 81 81 00 08 6c 45  |H.............lE|
-00000280  24 c7 6b b1 59 ab 0c 52  cc f2 b0 14 d7 87 9d 7a  |$.k.Y..R.......z|
-00000290  64 75 b5 5a 95 66 e4 c5  2b 8e ae 12 66 1f eb 4f  |du.Z.f..+...f..O|
-000002a0  38 b3 6e 60 d3 92 fd f7  41 08 b5 25 13 b1 18 7a  |8.n`....A..%...z|
-000002b0  24 fb 30 1d ba ed 98 b9  17 ec e7 d7 31 59 db 95  |$.0.........1Y..|
-000002c0  d3 1d 78 ea 50 56 5c d5  82 5a 2d 5a 5f 33 c4 b6  |..x.PV\..Z-Z_3..|
-000002d0  d8 c9 75 90 96 8c 0f 52  98 b5 cd 98 1f 89 20 5f  |..u....R...... _|
-000002e0  f2 a0 1c a3 1b 96 94 dd  a9 fd 57 e9 70 e8 26 6d  |..........W.p.&m|
-000002f0  71 99 9b 26 6e 38 50 29  6c 90 a7 bd d9 16 03 03  |q..&n8P)l.......|
-00000300  00 04 0e 00 00 00                                 |......|
+00000030  09 00 23 00 00 ff 01 00  01 00 16 03 03 02 71 0b  |..#...........q.|
+00000040  00 02 6d 00 02 6a 00 02  67 30 82 02 63 30 82 01  |..m..j..g0..c0..|
+00000050  cc a0 03 02 01 02 02 09  00 a2 73 00 0c 81 00 cb  |..........s.....|
+00000060  f3 30 0d 06 09 2a 86 48  86 f7 0d 01 01 0b 05 00  |.0...*.H........|
+00000070  30 2b 31 17 30 15 06 03  55 04 0a 13 0e 47 6f 6f  |0+1.0...U....Goo|
+00000080  67 6c 65 20 54 45 53 54  49 4e 47 31 10 30 0e 06  |gle TESTING1.0..|
+00000090  03 55 04 03 13 07 47 6f  20 52 6f 6f 74 30 1e 17  |.U....Go Root0..|
+000000a0  0d 31 35 30 31 30 31 30  30 30 30 30 30 5a 17 0d  |.150101000000Z..|
+000000b0  32 35 30 31 30 31 30 30  30 30 30 30 5a 30 26 31  |250101000000Z0&1|
+000000c0  17 30 15 06 03 55 04 0a  13 0e 47 6f 6f 67 6c 65  |.0...U....Google|
+000000d0  20 54 45 53 54 49 4e 47  31 0b 30 09 06 03 55 04  | TESTING1.0...U.|
+000000e0  03 13 02 47 6f 30 81 9f  30 0d 06 09 2a 86 48 86  |...Go0..0...*.H.|
+000000f0  f7 0d 01 01 01 05 00 03  81 8d 00 30 81 89 02 81  |...........0....|
+00000100  81 00 af 87 88 f6 20 1b  95 65 6c 14 ab 44 05 af  |...... ..el..D..|
+00000110  3b 45 14 e3 b7 6d fd 00  63 4d 95 7f fe 6a 62 35  |;E...m..cM...jb5|
+00000120  86 c0 4a f9 18 7c f6 aa  25 5e 7a 64 31 66 00 ba  |..J..|..%^zd1f..|
+00000130  f4 8e 92 af c7 6b d8 76  d4 f3 5f 41 cb 6e 56 15  |.....k.v.._A.nV.|
+00000140  97 1b 97 c1 3c 12 39 21  66 3d 2b 16 d1 bc db 1c  |....<.9!f=+.....|
+00000150  c0 a7 da b7 ca ad ba da  cb d5 21 50 ec de 8d ab  |..........!P....|
+00000160  d1 6b 81 4b 89 02 f3 c4  be c1 6c 89 b1 44 84 bd  |.k.K......l..D..|
+00000170  21 d1 04 7d 9d 16 4d f9  82 15 f6 ef fa d6 09 47  |!..}..M........G|
+00000180  f2 fb 02 03 01 00 01 a3  81 93 30 81 90 30 0e 06  |..........0..0..|
+00000190  03 55 1d 0f 01 01 ff 04  04 03 02 05 a0 30 1d 06  |.U...........0..|
+000001a0  03 55 1d 25 04 16 30 14  06 08 2b 06 01 05 05 07  |.U.%..0...+.....|
+000001b0  03 01 06 08 2b 06 01 05  05 07 03 02 30 0c 06 03  |....+.......0...|
+000001c0  55 1d 13 01 01 ff 04 02  30 00 30 19 06 03 55 1d  |U.......0.0...U.|
+000001d0  0e 04 12 04 10 12 50 8d  89 6f 1b d1 dc 54 4d 6e  |......P..o...TMn|
+000001e0  cb 69 5e 06 f4 30 1b 06  03 55 1d 23 04 14 30 12  |.i^..0...U.#..0.|
+000001f0  80 10 bf 3d b6 a9 66 f2  b8 40 cf ea b4 03 78 48  |...=..f..@....xH|
+00000200  1a 41 30 19 06 03 55 1d  11 04 12 30 10 82 0e 65  |.A0...U....0...e|
+00000210  78 61 6d 70 6c 65 2e 67  6f 6c 61 6e 67 30 0d 06  |xample.golang0..|
+00000220  09 2a 86 48 86 f7 0d 01  01 0b 05 00 03 81 81 00  |.*.H............|
+00000230  92 7c af 91 55 12 18 96  59 31 a6 48 40 d5 2d d5  |.|..U...Y1.H@.-.|
+00000240  ee bb 02 a0 f5 c2 1e 7c  9b b3 30 7d 3c dc 76 da  |.......|..0}<.v.|
+00000250  4f 3d c0 fa ae 2d 33 24  6b 03 7b 1b 67 59 11 21  |O=...-3$k.{.gY.!|
+00000260  b5 11 bc 77 b9 d9 e0 6e  a8 2d 2e 35 fa 64 5f 22  |...w...n.-.5.d_"|
+00000270  3e 63 10 6b be ff 14 86  6d 0d f0 15 31 a8 14 38  |>c.k....m...1..8|
+00000280  1e 3b 84 87 2c cb 98 ed  51 76 b9 b1 4f dd db 9b  |.;..,...Qv..O...|
+00000290  84 04 86 40 fa 51 dd ba  b4 8d eb e3 46 de 46 b9  |...@.Q......F.F.|
+000002a0  4f 86 c7 f9 a4 c2 41 34  ac cc f6 ea b0 ab 39 18  |O.....A4......9.|
+000002b0  16 03 03 00 04 0e 00 00  00                       |.........|
 >>> Flow 3 (client to server)
-00000000  16 03 03 00 86 10 00 00  82 00 80 6e 2e 79 82 3a  |...........n.y.:|
-00000010  c4 68 72 f5 a2 42 3d 71  f9 ec 22 8c 0b fa f0 82  |.hr..B=q..".....|
-00000020  82 c0 cb fc 52 0a 51 03  04 8c eb 4a 4e 4f b6 49  |....R.Q....JNO.I|
-00000030  ef 94 65 21 3c f7 9d 46  85 6e 35 d5 17 6b ff a3  |..e!<..F.n5..k..|
-00000040  5e 4d c1 36 1a 2f 68 f5  06 d4 2d 73 4f 1c 3b 7b  |^M.6./h...-sO.;{|
-00000050  c1 fa 4e 7e 7c f9 6c 13  a6 f4 3a 43 e9 aa be 22  |..N~|.l...:C..."|
-00000060  85 6f 2f 7c 5b b0 08 e2  86 b2 ae cb a9 12 d8 32  |.o/|[..........2|
-00000070  80 1d e4 2e 5d c3 66 d1  19 e5 89 33 2a 88 24 40  |....].f....3*.$@|
-00000080  2a 6d 6b b5 f1 92 4b 66  06 b8 49 14 03 03 00 01  |*mk...Kf..I.....|
-00000090  01 16 03 03 00 24 16 49  e2 a0 67 31 cf 0d 72 cb  |.....$.I..g1..r.|
-000000a0  ac 16 2c 80 37 71 69 f7  5f c4 d3 00 19 b7 4b fb  |..,.7qi._.....K.|
-000000b0  e5 e9 74 8e 30 b3 1c c5  ae e6                    |..t.0.....|
+00000000  16 03 03 00 86 10 00 00  82 00 80 87 06 ba d7 1f  |................|
+00000010  68 0c f2 a6 51 b4 ae af  8c c5 5d d4 bd f1 82 6d  |h...Q.....]....m|
+00000020  1d dd ce 69 be 07 62 13  af 06 71 3a 47 a9 bd f7  |...i..b...q:G...|
+00000030  bb 27 f0 38 df 88 01 40  29 c9 bb 7b 5d 6d 28 bd  |.'.8...@)..{]m(.|
+00000040  c8 28 e6 6d ff 5c c9 d3  c6 f5 06 17 e5 e5 1c 5b  |.(.m.\.........[|
+00000050  a1 18 7a 34 92 0a 39 20  5a 22 44 6c cc 5c 8c 83  |..z4..9 Z"Dl.\..|
+00000060  d0 19 4c bb 4e dc e2 64  ec b2 b8 3f 18 3f 9d 65  |..L.N..d...?.?.e|
+00000070  5b 89 26 ae f6 fd 54 71  c4 45 e9 56 6a 28 42 a9  |[.&...Tq.E.Vj(B.|
+00000080  5b 9f 12 69 a4 08 83 53  95 04 18 14 03 03 00 01  |[..i...S........|
+00000090  01 16 03 03 00 24 55 80  0f 43 c3 08 45 99 c9 1b  |.....$U..C..E...|
+000000a0  fd fe dd e8 48 f2 89 99  86 ef f7 fd 5f 2a 4b 0b  |....H......._*K.|
+000000b0  33 0e 5f 17 bb b7 a2 3c  9d 30                    |3._....<.0|
 >>> Flow 4 (server to client)
-00000000  16 03 03 00 72 04 00 00  6e 00 00 00 00 00 68 00  |....r...n.....h.|
-00000010  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 65  |...............e|
-00000020  ea 4b d1 ef ba 06 38 1e  e1 88 82 3a cd 03 ac 3b  |.K....8....:...;|
-00000030  39 0a e0 19 fd af 6c 57  30 df 31 6e f7 92 38 4b  |9.....lW0.1n..8K|
-00000040  5d 77 90 39 ff 32 51 f5  ed 12 d7 b0 7c 4d 6c c5  |]w.9.2Q.....|Ml.|
-00000050  76 e4 72 48 3e 59 23 fe  0d 15 df f4 ba ea b9 67  |v.rH>Y#........g|
-00000060  16 23 8f 7d 15 b6 11 f1  ab d7 d4 cd a3 21 82 92  |.#.}.........!..|
-00000070  2a 12 cf 95 f3 60 b2 14  03 03 00 01 01 16 03 03  |*....`..........|
-00000080  00 24 89 ad 87 04 4f 08  dc 2a 71 37 fb f1 95 d1  |.$....O..*q7....|
-00000090  2e 3c c2 6e 0f 38 5d e4  0e c3 f7 27 d0 46 a3 c1  |.<.n.8]....'.F..|
-000000a0  a8 3b 06 ed 96 ec 17 03  03 00 21 30 d4 9f 0b 49  |.;........!0...I|
-000000b0  9f a2 a8 a1 2c 0a 79 93  56 2d 8a ee 85 ed 62 42  |....,.y.V-....bB|
-000000c0  8c 18 fe 7a 09 3a 24 c4  5e ed 7d 2a 15 03 03 00  |...z.:$.^.}*....|
-000000d0  16 a0 24 0a 8b 90 4c fc  99 ba 67 bb 04 1e 59 69  |..$...L...g...Yi|
-000000e0  c2 98 49 b5 00 0b e0                              |..I....|
+00000000  16 03 03 00 82 04 00 00  7e 00 00 00 00 00 78 50  |........~.....xP|
+00000010  46 ad c1 db a8 38 86 7b  2b bb fd d0 c3 42 3e 00  |F....8.{+....B>.|
+00000020  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 94  |................|
+00000030  6f 2c b5 83 61 c4 74 90  94 e5 6c fd 70 64 57 3a  |o,..a.t...l.pdW:|
+00000040  25 78 bf 9f a0 7c 51 bc  2a 69 1e b3 fd 71 34 b7  |%x...|Q.*i...q4.|
+00000050  9a ef cb 49 37 f8 5d 5e  7c cf 6d fc 13 c1 52 79  |...I7.]^|.m...Ry|
+00000060  8e ed c3 84 01 33 94 10  65 34 64 5e b4 9c 07 46  |.....3..e4d^...F|
+00000070  5b 9e d7 5e 55 df fd c0  e9 d2 e8 d3 c6 42 18 ef  |[..^U........B..|
+00000080  a5 6c be e8 d2 49 c6 14  03 03 00 01 01 16 03 03  |.l...I..........|
+00000090  00 24 66 94 4b b5 3f 5d  59 db 36 c1 dd 55 8c ee  |.$f.K.?]Y.6..U..|
+000000a0  de a4 bc d0 12 44 31 3e  e4 e7 4a 51 e3 62 69 ab  |.....D1>..JQ.bi.|
+000000b0  14 78 85 49 a3 97 17 03  03 00 21 dd 96 5d 21 e0  |.x.I......!..]!.|
+000000c0  2e 3d 33 dd 6c df bb 41  d7 bd 50 c7 1c 6f 97 34  |.=3.l..A..P..o.4|
+000000d0  6a 6e d6 1d 27 81 2d f7  fb 32 85 02 15 03 03 00  |jn..'.-..2......|
+000000e0  16 5e 4e 62 15 97 a7 a3  9b 1b 50 44 85 fb 28 66  |.^Nb......PD..(f|
+000000f0  aa 66 54 45 c9 dc 61                              |.fTE..a|
diff --git a/third_party/gofrontend/libgo/go/crypto/tls/testdata/Server-TLSv12-IssueTicketPreDisable b/third_party/gofrontend/libgo/go/crypto/tls/testdata/Server-TLSv12-IssueTicketPreDisable
index 30f0026..a8f7edf 100644
--- a/third_party/gofrontend/libgo/go/crypto/tls/testdata/Server-TLSv12-IssueTicketPreDisable
+++ b/third_party/gofrontend/libgo/go/crypto/tls/testdata/Server-TLSv12-IssueTicketPreDisable
@@ -1,87 +1,83 @@
 >>> Flow 1 (client to server)
-00000000  16 03 01 00 60 01 00 00  5c 03 03 54 23 54 02 17  |....`...\..T#T..|
-00000010  f3 53 13 3d 48 88 c3 19  b9 d1 3d 33 7f f5 99 56  |.S.=H.....=3...V|
-00000020  04 71 1b d9 d5 64 8a 0d  4a 54 00 00 00 04 00 05  |.q...d..JT......|
-00000030  00 ff 01 00 00 2f 00 23  00 00 00 0d 00 22 00 20  |...../.#.....". |
+00000000  16 03 01 00 5e 01 00 00  5a 03 03 62 f6 20 66 23  |....^...Z..b. f#|
+00000010  d5 71 0a c0 57 92 2e 80  b6 06 0c 54 5b 1c 77 a0  |.q..W......T[.w.|
+00000020  ce 0b b2 52 4a b9 f2 c6  97 33 42 00 00 04 00 05  |...RJ....3B.....|
+00000030  00 ff 01 00 00 2d 00 23  00 00 00 0d 00 20 00 1e  |.....-.#..... ..|
 00000040  06 01 06 02 06 03 05 01  05 02 05 03 04 01 04 02  |................|
-00000050  04 03 03 01 03 02 03 03  02 01 02 02 02 03 01 01  |................|
-00000060  00 0f 00 01 01                                    |.....|
+00000050  04 03 03 01 03 02 03 03  02 01 02 02 02 03 00 0f  |................|
+00000060  00 01 01                                          |...|
 >>> Flow 2 (server to client)
 00000000  16 03 03 00 35 02 00 00  31 03 03 00 00 00 00 00  |....5...1.......|
 00000010  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
 00000020  00 00 00 00 00 00 00 00  00 00 00 00 00 05 00 00  |................|
-00000030  09 00 23 00 00 ff 01 00  01 00 16 03 03 02 be 0b  |..#.............|
-00000040  00 02 ba 00 02 b7 00 02  b4 30 82 02 b0 30 82 02  |.........0...0..|
-00000050  19 a0 03 02 01 02 02 09  00 85 b0 bb a4 8a 7f b8  |................|
-00000060  ca 30 0d 06 09 2a 86 48  86 f7 0d 01 01 05 05 00  |.0...*.H........|
-00000070  30 45 31 0b 30 09 06 03  55 04 06 13 02 41 55 31  |0E1.0...U....AU1|
-00000080  13 30 11 06 03 55 04 08  13 0a 53 6f 6d 65 2d 53  |.0...U....Some-S|
-00000090  74 61 74 65 31 21 30 1f  06 03 55 04 0a 13 18 49  |tate1!0...U....I|
-000000a0  6e 74 65 72 6e 65 74 20  57 69 64 67 69 74 73 20  |nternet Widgits |
-000000b0  50 74 79 20 4c 74 64 30  1e 17 0d 31 30 30 34 32  |Pty Ltd0...10042|
-000000c0  34 30 39 30 39 33 38 5a  17 0d 31 31 30 34 32 34  |4090938Z..110424|
-000000d0  30 39 30 39 33 38 5a 30  45 31 0b 30 09 06 03 55  |090938Z0E1.0...U|
-000000e0  04 06 13 02 41 55 31 13  30 11 06 03 55 04 08 13  |....AU1.0...U...|
-000000f0  0a 53 6f 6d 65 2d 53 74  61 74 65 31 21 30 1f 06  |.Some-State1!0..|
-00000100  03 55 04 0a 13 18 49 6e  74 65 72 6e 65 74 20 57  |.U....Internet W|
-00000110  69 64 67 69 74 73 20 50  74 79 20 4c 74 64 30 81  |idgits Pty Ltd0.|
-00000120  9f 30 0d 06 09 2a 86 48  86 f7 0d 01 01 01 05 00  |.0...*.H........|
-00000130  03 81 8d 00 30 81 89 02  81 81 00 bb 79 d6 f5 17  |....0.......y...|
-00000140  b5 e5 bf 46 10 d0 dc 69  be e6 2b 07 43 5a d0 03  |...F...i..+.CZ..|
-00000150  2d 8a 7a 43 85 b7 14 52  e7 a5 65 4c 2c 78 b8 23  |-.zC...R..eL,x.#|
-00000160  8c b5 b4 82 e5 de 1f 95  3b 7e 62 a5 2c a5 33 d6  |........;~b.,.3.|
-00000170  fe 12 5c 7a 56 fc f5 06  bf fa 58 7b 26 3f b5 cd  |..\zV.....X{&?..|
-00000180  04 d3 d0 c9 21 96 4a c7  f4 54 9f 5a bf ef 42 71  |....!.J..T.Z..Bq|
-00000190  00 fe 18 99 07 7f 7e 88  7d 7d f1 04 39 c4 a2 2e  |......~.}}..9...|
-000001a0  db 51 c9 7c e3 c0 4c 3b  32 66 01 cf af b1 1d b8  |.Q.|..L;2f......|
-000001b0  71 9a 1d db db 89 6b ae  da 2d 79 02 03 01 00 01  |q.....k..-y.....|
-000001c0  a3 81 a7 30 81 a4 30 1d  06 03 55 1d 0e 04 16 04  |...0..0...U.....|
-000001d0  14 b1 ad e2 85 5a cf cb  28 db 69 ce 23 69 de d3  |.....Z..(.i.#i..|
-000001e0  26 8e 18 88 39 30 75 06  03 55 1d 23 04 6e 30 6c  |&...90u..U.#.n0l|
-000001f0  80 14 b1 ad e2 85 5a cf  cb 28 db 69 ce 23 69 de  |......Z..(.i.#i.|
-00000200  d3 26 8e 18 88 39 a1 49  a4 47 30 45 31 0b 30 09  |.&...9.I.G0E1.0.|
-00000210  06 03 55 04 06 13 02 41  55 31 13 30 11 06 03 55  |..U....AU1.0...U|
-00000220  04 08 13 0a 53 6f 6d 65  2d 53 74 61 74 65 31 21  |....Some-State1!|
-00000230  30 1f 06 03 55 04 0a 13  18 49 6e 74 65 72 6e 65  |0...U....Interne|
-00000240  74 20 57 69 64 67 69 74  73 20 50 74 79 20 4c 74  |t Widgits Pty Lt|
-00000250  64 82 09 00 85 b0 bb a4  8a 7f b8 ca 30 0c 06 03  |d...........0...|
-00000260  55 1d 13 04 05 30 03 01  01 ff 30 0d 06 09 2a 86  |U....0....0...*.|
-00000270  48 86 f7 0d 01 01 05 05  00 03 81 81 00 08 6c 45  |H.............lE|
-00000280  24 c7 6b b1 59 ab 0c 52  cc f2 b0 14 d7 87 9d 7a  |$.k.Y..R.......z|
-00000290  64 75 b5 5a 95 66 e4 c5  2b 8e ae 12 66 1f eb 4f  |du.Z.f..+...f..O|
-000002a0  38 b3 6e 60 d3 92 fd f7  41 08 b5 25 13 b1 18 7a  |8.n`....A..%...z|
-000002b0  24 fb 30 1d ba ed 98 b9  17 ec e7 d7 31 59 db 95  |$.0.........1Y..|
-000002c0  d3 1d 78 ea 50 56 5c d5  82 5a 2d 5a 5f 33 c4 b6  |..x.PV\..Z-Z_3..|
-000002d0  d8 c9 75 90 96 8c 0f 52  98 b5 cd 98 1f 89 20 5f  |..u....R...... _|
-000002e0  f2 a0 1c a3 1b 96 94 dd  a9 fd 57 e9 70 e8 26 6d  |..........W.p.&m|
-000002f0  71 99 9b 26 6e 38 50 29  6c 90 a7 bd d9 16 03 03  |q..&n8P)l.......|
-00000300  00 04 0e 00 00 00                                 |......|
+00000030  09 00 23 00 00 ff 01 00  01 00 16 03 03 02 71 0b  |..#...........q.|
+00000040  00 02 6d 00 02 6a 00 02  67 30 82 02 63 30 82 01  |..m..j..g0..c0..|
+00000050  cc a0 03 02 01 02 02 09  00 a2 73 00 0c 81 00 cb  |..........s.....|
+00000060  f3 30 0d 06 09 2a 86 48  86 f7 0d 01 01 0b 05 00  |.0...*.H........|
+00000070  30 2b 31 17 30 15 06 03  55 04 0a 13 0e 47 6f 6f  |0+1.0...U....Goo|
+00000080  67 6c 65 20 54 45 53 54  49 4e 47 31 10 30 0e 06  |gle TESTING1.0..|
+00000090  03 55 04 03 13 07 47 6f  20 52 6f 6f 74 30 1e 17  |.U....Go Root0..|
+000000a0  0d 31 35 30 31 30 31 30  30 30 30 30 30 5a 17 0d  |.150101000000Z..|
+000000b0  32 35 30 31 30 31 30 30  30 30 30 30 5a 30 26 31  |250101000000Z0&1|
+000000c0  17 30 15 06 03 55 04 0a  13 0e 47 6f 6f 67 6c 65  |.0...U....Google|
+000000d0  20 54 45 53 54 49 4e 47  31 0b 30 09 06 03 55 04  | TESTING1.0...U.|
+000000e0  03 13 02 47 6f 30 81 9f  30 0d 06 09 2a 86 48 86  |...Go0..0...*.H.|
+000000f0  f7 0d 01 01 01 05 00 03  81 8d 00 30 81 89 02 81  |...........0....|
+00000100  81 00 af 87 88 f6 20 1b  95 65 6c 14 ab 44 05 af  |...... ..el..D..|
+00000110  3b 45 14 e3 b7 6d fd 00  63 4d 95 7f fe 6a 62 35  |;E...m..cM...jb5|
+00000120  86 c0 4a f9 18 7c f6 aa  25 5e 7a 64 31 66 00 ba  |..J..|..%^zd1f..|
+00000130  f4 8e 92 af c7 6b d8 76  d4 f3 5f 41 cb 6e 56 15  |.....k.v.._A.nV.|
+00000140  97 1b 97 c1 3c 12 39 21  66 3d 2b 16 d1 bc db 1c  |....<.9!f=+.....|
+00000150  c0 a7 da b7 ca ad ba da  cb d5 21 50 ec de 8d ab  |..........!P....|
+00000160  d1 6b 81 4b 89 02 f3 c4  be c1 6c 89 b1 44 84 bd  |.k.K......l..D..|
+00000170  21 d1 04 7d 9d 16 4d f9  82 15 f6 ef fa d6 09 47  |!..}..M........G|
+00000180  f2 fb 02 03 01 00 01 a3  81 93 30 81 90 30 0e 06  |..........0..0..|
+00000190  03 55 1d 0f 01 01 ff 04  04 03 02 05 a0 30 1d 06  |.U...........0..|
+000001a0  03 55 1d 25 04 16 30 14  06 08 2b 06 01 05 05 07  |.U.%..0...+.....|
+000001b0  03 01 06 08 2b 06 01 05  05 07 03 02 30 0c 06 03  |....+.......0...|
+000001c0  55 1d 13 01 01 ff 04 02  30 00 30 19 06 03 55 1d  |U.......0.0...U.|
+000001d0  0e 04 12 04 10 12 50 8d  89 6f 1b d1 dc 54 4d 6e  |......P..o...TMn|
+000001e0  cb 69 5e 06 f4 30 1b 06  03 55 1d 23 04 14 30 12  |.i^..0...U.#..0.|
+000001f0  80 10 bf 3d b6 a9 66 f2  b8 40 cf ea b4 03 78 48  |...=..f..@....xH|
+00000200  1a 41 30 19 06 03 55 1d  11 04 12 30 10 82 0e 65  |.A0...U....0...e|
+00000210  78 61 6d 70 6c 65 2e 67  6f 6c 61 6e 67 30 0d 06  |xample.golang0..|
+00000220  09 2a 86 48 86 f7 0d 01  01 0b 05 00 03 81 81 00  |.*.H............|
+00000230  92 7c af 91 55 12 18 96  59 31 a6 48 40 d5 2d d5  |.|..U...Y1.H@.-.|
+00000240  ee bb 02 a0 f5 c2 1e 7c  9b b3 30 7d 3c dc 76 da  |.......|..0}<.v.|
+00000250  4f 3d c0 fa ae 2d 33 24  6b 03 7b 1b 67 59 11 21  |O=...-3$k.{.gY.!|
+00000260  b5 11 bc 77 b9 d9 e0 6e  a8 2d 2e 35 fa 64 5f 22  |...w...n.-.5.d_"|
+00000270  3e 63 10 6b be ff 14 86  6d 0d f0 15 31 a8 14 38  |>c.k....m...1..8|
+00000280  1e 3b 84 87 2c cb 98 ed  51 76 b9 b1 4f dd db 9b  |.;..,...Qv..O...|
+00000290  84 04 86 40 fa 51 dd ba  b4 8d eb e3 46 de 46 b9  |...@.Q......F.F.|
+000002a0  4f 86 c7 f9 a4 c2 41 34  ac cc f6 ea b0 ab 39 18  |O.....A4......9.|
+000002b0  16 03 03 00 04 0e 00 00  00                       |.........|
 >>> Flow 3 (client to server)
-00000000  16 03 03 00 86 10 00 00  82 00 80 27 e9 a4 f7 e7  |...........'....|
-00000010  df 25 de 84 8c 1f d6 e6  c3 11 28 55 9a c1 91 37  |.%........(U...7|
-00000020  84 f5 ba f8 80 0d ca 50  cb 1e 72 f7 97 6f c2 b2  |.......P..r..o..|
-00000030  04 4d 13 7c e0 6e a0 1f  91 e1 38 1b a2 c0 55 16  |.M.|.n....8...U.|
-00000040  7f 29 fc ed 1c 1a cf 72  14 c3 00 c1 dd 36 36 af  |.).....r.....66.|
-00000050  a6 e4 a8 be ba ec 13 d0  1e d0 1d fd e1 5b 27 fd  |.............['.|
-00000060  9a da 2e 12 c8 b0 b9 c2  b9 76 ec 7f 3c 98 b6 63  |.........v..<..c|
-00000070  bc da f0 07 7a 3d e7 61  f4 2f 12 80 3b f9 3b cc  |....z=.a./..;.;.|
-00000080  05 c8 2f 7e 28 b2 73 bf  97 61 29 14 03 03 00 01  |../~(.s..a).....|
-00000090  01 16 03 03 00 24 17 59  a9 45 53 46 33 96 50 dd  |.....$.Y.ESF3.P.|
-000000a0  3e 23 aa 91 38 f8 56 4a  2f 1a f2 b1 44 9b ce 17  |>#..8.VJ/...D...|
-000000b0  6b 8a 89 76 bc 67 b8 8b  ba 90                    |k..v.g....|
+00000000  16 03 03 00 86 10 00 00  82 00 80 5b 43 6f db 52  |...........[Co.R|
+00000010  56 e3 d9 4b 1e c8 95 8b  78 a6 19 00 44 9c 44 b4  |V..K....x...D.D.|
+00000020  f7 fe d4 3f 69 ea 9c 67  d3 48 b8 c5 93 bc 22 f1  |...?i..g.H....".|
+00000030  a9 0e 81 82 d0 cf dc 0b  ea f0 02 67 92 8d 72 40  |...........g..r@|
+00000040  25 bb f3 88 53 c0 2f ba  38 ef da d1 7c 73 84 ec  |%...S./.8...|s..|
+00000050  61 96 b9 d4 93 06 4a 06  7b 6d 40 e7 bb 15 59 6e  |a.....J.{m@...Yn|
+00000060  ad 31 71 eb cf 84 57 3b  0c ad aa 70 02 63 24 a9  |.1q...W;...p.c$.|
+00000070  7c a1 9a 6d b7 e0 4c d5  67 4c ce 53 9d b6 31 de  ||..m..L.gL.S..1.|
+00000080  69 b9 f5 ca a8 e3 ea d6  f5 a3 f3 14 03 03 00 01  |i...............|
+00000090  01 16 03 03 00 24 66 ae  13 67 70 20 f5 f5 76 03  |.....$f..gp ..v.|
+000000a0  11 6e 32 a6 73 a2 70 42  ab 4f 16 93 d2 fa a1 ac  |.n2.s.pB.O......|
+000000b0  4e b2 08 4a a9 b5 20 aa  80 b6                    |N..J.. ...|
 >>> Flow 4 (server to client)
-00000000  16 03 03 00 72 04 00 00  6e 00 00 00 00 00 68 00  |....r...n.....h.|
-00000010  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 65  |...............e|
-00000020  ea 4b d1 ef ba 2d db 0c  ba 9a d4 20 76 57 c8 ec  |.K...-..... vW..|
-00000030  dc 2d 77 fb fb 3b 93 5f  53 e0 14 4f 90 fb d6 55  |.-w..;._S..O...U|
-00000040  57 8c 8d 0d 25 ea 5d 0d  f2 91 e5 12 22 12 ec 7b  |W...%.]....."..{|
-00000050  5f b6 6e fd 07 59 23 24  fc b1 97 ca ea 56 a5 c2  |_.n..Y#$.....V..|
-00000060  a0 e4 9e 99 64 f2 64 d0  75 7a 46 63 e3 dc 21 ed  |....d.d.uzFc..!.|
-00000070  78 56 e9 e1 ab 66 80 14  03 03 00 01 01 16 03 03  |xV...f..........|
-00000080  00 24 fc 14 68 07 17 1f  df b7 84 cb fd c1 e0 e4  |.$..h...........|
-00000090  f2 1a ea 34 b5 00 7f 70  be c8 1c 0a d6 55 e3 57  |...4...p.....U.W|
-000000a0  50 4e 6d 7d 8a 5d 17 03  03 00 21 24 27 50 40 c1  |PNm}.]....!$'P@.|
-000000b0  c5 bd c7 9f 95 d9 ba 2e  7b 0e db ea a7 31 81 05  |........{....1..|
-000000c0  75 43 b1 63 cf b8 55 92  ef 76 98 a9 15 03 03 00  |uC.c..U..v......|
-000000d0  16 d7 ea 3c 79 e7 a6 2f  61 39 ec 4e 95 86 48 5e  |...<y../a9.N..H^|
-000000e0  75 a0 9e 41 42 89 67                              |u..AB.g|
+00000000  16 03 03 00 82 04 00 00  7e 00 00 00 00 00 78 50  |........~.....xP|
+00000010  46 ad c1 db a8 38 86 7b  2b bb fd d0 c3 42 3e 00  |F....8.{+....B>.|
+00000020  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 94  |................|
+00000030  6f 2c b5 83 61 bd 50 da  49 7f 8b 8f 58 57 00 a1  |o,..a.P.I...XW..|
+00000040  11 0d 4a 9d 8a 39 dd 85  23 c0 eb 9d 1a 45 93 92  |..J..9..#....E..|
+00000050  e7 af 15 a3 a4 48 da f9  a4 d8 8e cb 6c 3d 44 77  |.....H......l=Dw|
+00000060  f9 c4 83 89 85 33 94 c1  c6 20 9a 73 44 83 89 5e  |.....3... .sD..^|
+00000070  59 ee 05 c6 7e 8d e9 7d  7b f8 84 46 b6 7d 43 ec  |Y...~..}{..F.}C.|
+00000080  f1 af 1f 0f 35 b4 1c 14  03 03 00 01 01 16 03 03  |....5...........|
+00000090  00 24 8c 0d bd bc 34 93  ed ad 80 21 6d 08 e4 0e  |.$....4....!m...|
+000000a0  67 4f 99 8d df 2a 2d 4f  13 39 82 be a1 d2 1f 75  |gO...*-O.9.....u|
+000000b0  73 c8 b2 ce 41 0c 17 03  03 00 21 d8 c2 50 d6 11  |s...A.....!..P..|
+000000c0  bc 86 58 68 0e 60 4a 47  a5 d0 12 7e a3 b5 be 64  |..Xh.`JG...~...d|
+000000d0  e6 b1 bc 62 70 85 d4 7c  cd fe 67 cf 15 03 03 00  |...bp..|..g.....|
+000000e0  16 e4 1c d5 f4 f7 d0 f5  b2 b3 2b 3d b0 7d c0 23  |..........+=.}.#|
+000000f0  e2 5c a5 c7 a4 23 fa                              |.\...#.|
diff --git a/third_party/gofrontend/libgo/go/crypto/tls/testdata/Server-TLSv12-RSA-3DES b/third_party/gofrontend/libgo/go/crypto/tls/testdata/Server-TLSv12-RSA-3DES
index 5995b33..7457626 100644
--- a/third_party/gofrontend/libgo/go/crypto/tls/testdata/Server-TLSv12-RSA-3DES
+++ b/third_party/gofrontend/libgo/go/crypto/tls/testdata/Server-TLSv12-RSA-3DES
@@ -1,83 +1,77 @@
 >>> Flow 1 (client to server)
-00000000  16 03 01 00 5c 01 00 00  58 03 03 52 cc 57 59 68  |....\...X..R.WYh|
-00000010  11 72 a6 ec 6b 0a 47 1d  10 06 ec 75 af 07 38 a0  |.r..k.G....u..8.|
-00000020  30 9e 91 12 e1 9b 19 46  0d d4 45 00 00 04 00 0a  |0......F..E.....|
-00000030  00 ff 01 00 00 2b 00 0d  00 22 00 20 06 01 06 02  |.....+...". ....|
+00000000  16 03 01 00 5a 01 00 00  56 03 03 ac 1d 0b 6e f3  |....Z...V.....n.|
+00000010  25 04 00 97 a0 79 39 c5  ef 95 8b e3 c1 87 0d 1c  |%....y9.........|
+00000020  0b c3 39 3e ff 23 0e 3c  28 8f 75 00 00 04 00 0a  |..9>.#.<(.u.....|
+00000030  00 ff 01 00 00 29 00 0d  00 20 00 1e 06 01 06 02  |.....)... ......|
 00000040  06 03 05 01 05 02 05 03  04 01 04 02 04 03 03 01  |................|
-00000050  03 02 03 03 02 01 02 02  02 03 01 01 00 0f 00 01  |................|
-00000060  01                                                |.|
+00000050  03 02 03 03 02 01 02 02  02 03 00 0f 00 01 01     |...............|
 >>> Flow 2 (server to client)
 00000000  16 03 03 00 31 02 00 00  2d 03 03 00 00 00 00 00  |....1...-.......|
 00000010  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
 00000020  00 00 00 00 00 00 00 00  00 00 00 00 00 0a 00 00  |................|
-00000030  05 ff 01 00 01 00 16 03  03 02 be 0b 00 02 ba 00  |................|
-00000040  02 b7 00 02 b4 30 82 02  b0 30 82 02 19 a0 03 02  |.....0...0......|
-00000050  01 02 02 09 00 85 b0 bb  a4 8a 7f b8 ca 30 0d 06  |.............0..|
-00000060  09 2a 86 48 86 f7 0d 01  01 05 05 00 30 45 31 0b  |.*.H........0E1.|
-00000070  30 09 06 03 55 04 06 13  02 41 55 31 13 30 11 06  |0...U....AU1.0..|
-00000080  03 55 04 08 13 0a 53 6f  6d 65 2d 53 74 61 74 65  |.U....Some-State|
-00000090  31 21 30 1f 06 03 55 04  0a 13 18 49 6e 74 65 72  |1!0...U....Inter|
-000000a0  6e 65 74 20 57 69 64 67  69 74 73 20 50 74 79 20  |net Widgits Pty |
-000000b0  4c 74 64 30 1e 17 0d 31  30 30 34 32 34 30 39 30  |Ltd0...100424090|
-000000c0  39 33 38 5a 17 0d 31 31  30 34 32 34 30 39 30 39  |938Z..1104240909|
-000000d0  33 38 5a 30 45 31 0b 30  09 06 03 55 04 06 13 02  |38Z0E1.0...U....|
-000000e0  41 55 31 13 30 11 06 03  55 04 08 13 0a 53 6f 6d  |AU1.0...U....Som|
-000000f0  65 2d 53 74 61 74 65 31  21 30 1f 06 03 55 04 0a  |e-State1!0...U..|
-00000100  13 18 49 6e 74 65 72 6e  65 74 20 57 69 64 67 69  |..Internet Widgi|
-00000110  74 73 20 50 74 79 20 4c  74 64 30 81 9f 30 0d 06  |ts Pty Ltd0..0..|
-00000120  09 2a 86 48 86 f7 0d 01  01 01 05 00 03 81 8d 00  |.*.H............|
-00000130  30 81 89 02 81 81 00 bb  79 d6 f5 17 b5 e5 bf 46  |0.......y......F|
-00000140  10 d0 dc 69 be e6 2b 07  43 5a d0 03 2d 8a 7a 43  |...i..+.CZ..-.zC|
-00000150  85 b7 14 52 e7 a5 65 4c  2c 78 b8 23 8c b5 b4 82  |...R..eL,x.#....|
-00000160  e5 de 1f 95 3b 7e 62 a5  2c a5 33 d6 fe 12 5c 7a  |....;~b.,.3...\z|
-00000170  56 fc f5 06 bf fa 58 7b  26 3f b5 cd 04 d3 d0 c9  |V.....X{&?......|
-00000180  21 96 4a c7 f4 54 9f 5a  bf ef 42 71 00 fe 18 99  |!.J..T.Z..Bq....|
-00000190  07 7f 7e 88 7d 7d f1 04  39 c4 a2 2e db 51 c9 7c  |..~.}}..9....Q.||
-000001a0  e3 c0 4c 3b 32 66 01 cf  af b1 1d b8 71 9a 1d db  |..L;2f......q...|
-000001b0  db 89 6b ae da 2d 79 02  03 01 00 01 a3 81 a7 30  |..k..-y........0|
-000001c0  81 a4 30 1d 06 03 55 1d  0e 04 16 04 14 b1 ad e2  |..0...U.........|
-000001d0  85 5a cf cb 28 db 69 ce  23 69 de d3 26 8e 18 88  |.Z..(.i.#i..&...|
-000001e0  39 30 75 06 03 55 1d 23  04 6e 30 6c 80 14 b1 ad  |90u..U.#.n0l....|
-000001f0  e2 85 5a cf cb 28 db 69  ce 23 69 de d3 26 8e 18  |..Z..(.i.#i..&..|
-00000200  88 39 a1 49 a4 47 30 45  31 0b 30 09 06 03 55 04  |.9.I.G0E1.0...U.|
-00000210  06 13 02 41 55 31 13 30  11 06 03 55 04 08 13 0a  |...AU1.0...U....|
-00000220  53 6f 6d 65 2d 53 74 61  74 65 31 21 30 1f 06 03  |Some-State1!0...|
-00000230  55 04 0a 13 18 49 6e 74  65 72 6e 65 74 20 57 69  |U....Internet Wi|
-00000240  64 67 69 74 73 20 50 74  79 20 4c 74 64 82 09 00  |dgits Pty Ltd...|
-00000250  85 b0 bb a4 8a 7f b8 ca  30 0c 06 03 55 1d 13 04  |........0...U...|
-00000260  05 30 03 01 01 ff 30 0d  06 09 2a 86 48 86 f7 0d  |.0....0...*.H...|
-00000270  01 01 05 05 00 03 81 81  00 08 6c 45 24 c7 6b b1  |..........lE$.k.|
-00000280  59 ab 0c 52 cc f2 b0 14  d7 87 9d 7a 64 75 b5 5a  |Y..R.......zdu.Z|
-00000290  95 66 e4 c5 2b 8e ae 12  66 1f eb 4f 38 b3 6e 60  |.f..+...f..O8.n`|
-000002a0  d3 92 fd f7 41 08 b5 25  13 b1 18 7a 24 fb 30 1d  |....A..%...z$.0.|
-000002b0  ba ed 98 b9 17 ec e7 d7  31 59 db 95 d3 1d 78 ea  |........1Y....x.|
-000002c0  50 56 5c d5 82 5a 2d 5a  5f 33 c4 b6 d8 c9 75 90  |PV\..Z-Z_3....u.|
-000002d0  96 8c 0f 52 98 b5 cd 98  1f 89 20 5f f2 a0 1c a3  |...R...... _....|
-000002e0  1b 96 94 dd a9 fd 57 e9  70 e8 26 6d 71 99 9b 26  |......W.p.&mq..&|
-000002f0  6e 38 50 29 6c 90 a7 bd  d9 16 03 03 00 04 0e 00  |n8P)l...........|
-00000300  00 00                                             |..|
+00000030  05 ff 01 00 01 00 16 03  03 02 71 0b 00 02 6d 00  |..........q...m.|
+00000040  02 6a 00 02 67 30 82 02  63 30 82 01 cc a0 03 02  |.j..g0..c0......|
+00000050  01 02 02 09 00 a2 73 00  0c 81 00 cb f3 30 0d 06  |......s......0..|
+00000060  09 2a 86 48 86 f7 0d 01  01 0b 05 00 30 2b 31 17  |.*.H........0+1.|
+00000070  30 15 06 03 55 04 0a 13  0e 47 6f 6f 67 6c 65 20  |0...U....Google |
+00000080  54 45 53 54 49 4e 47 31  10 30 0e 06 03 55 04 03  |TESTING1.0...U..|
+00000090  13 07 47 6f 20 52 6f 6f  74 30 1e 17 0d 31 35 30  |..Go Root0...150|
+000000a0  31 30 31 30 30 30 30 30  30 5a 17 0d 32 35 30 31  |101000000Z..2501|
+000000b0  30 31 30 30 30 30 30 30  5a 30 26 31 17 30 15 06  |01000000Z0&1.0..|
+000000c0  03 55 04 0a 13 0e 47 6f  6f 67 6c 65 20 54 45 53  |.U....Google TES|
+000000d0  54 49 4e 47 31 0b 30 09  06 03 55 04 03 13 02 47  |TING1.0...U....G|
+000000e0  6f 30 81 9f 30 0d 06 09  2a 86 48 86 f7 0d 01 01  |o0..0...*.H.....|
+000000f0  01 05 00 03 81 8d 00 30  81 89 02 81 81 00 af 87  |.......0........|
+00000100  88 f6 20 1b 95 65 6c 14  ab 44 05 af 3b 45 14 e3  |.. ..el..D..;E..|
+00000110  b7 6d fd 00 63 4d 95 7f  fe 6a 62 35 86 c0 4a f9  |.m..cM...jb5..J.|
+00000120  18 7c f6 aa 25 5e 7a 64  31 66 00 ba f4 8e 92 af  |.|..%^zd1f......|
+00000130  c7 6b d8 76 d4 f3 5f 41  cb 6e 56 15 97 1b 97 c1  |.k.v.._A.nV.....|
+00000140  3c 12 39 21 66 3d 2b 16  d1 bc db 1c c0 a7 da b7  |<.9!f=+.........|
+00000150  ca ad ba da cb d5 21 50  ec de 8d ab d1 6b 81 4b  |......!P.....k.K|
+00000160  89 02 f3 c4 be c1 6c 89  b1 44 84 bd 21 d1 04 7d  |......l..D..!..}|
+00000170  9d 16 4d f9 82 15 f6 ef  fa d6 09 47 f2 fb 02 03  |..M........G....|
+00000180  01 00 01 a3 81 93 30 81  90 30 0e 06 03 55 1d 0f  |......0..0...U..|
+00000190  01 01 ff 04 04 03 02 05  a0 30 1d 06 03 55 1d 25  |.........0...U.%|
+000001a0  04 16 30 14 06 08 2b 06  01 05 05 07 03 01 06 08  |..0...+.........|
+000001b0  2b 06 01 05 05 07 03 02  30 0c 06 03 55 1d 13 01  |+.......0...U...|
+000001c0  01 ff 04 02 30 00 30 19  06 03 55 1d 0e 04 12 04  |....0.0...U.....|
+000001d0  10 12 50 8d 89 6f 1b d1  dc 54 4d 6e cb 69 5e 06  |..P..o...TMn.i^.|
+000001e0  f4 30 1b 06 03 55 1d 23  04 14 30 12 80 10 bf 3d  |.0...U.#..0....=|
+000001f0  b6 a9 66 f2 b8 40 cf ea  b4 03 78 48 1a 41 30 19  |..f..@....xH.A0.|
+00000200  06 03 55 1d 11 04 12 30  10 82 0e 65 78 61 6d 70  |..U....0...examp|
+00000210  6c 65 2e 67 6f 6c 61 6e  67 30 0d 06 09 2a 86 48  |le.golang0...*.H|
+00000220  86 f7 0d 01 01 0b 05 00  03 81 81 00 92 7c af 91  |.............|..|
+00000230  55 12 18 96 59 31 a6 48  40 d5 2d d5 ee bb 02 a0  |U...Y1.H@.-.....|
+00000240  f5 c2 1e 7c 9b b3 30 7d  3c dc 76 da 4f 3d c0 fa  |...|..0}<.v.O=..|
+00000250  ae 2d 33 24 6b 03 7b 1b  67 59 11 21 b5 11 bc 77  |.-3$k.{.gY.!...w|
+00000260  b9 d9 e0 6e a8 2d 2e 35  fa 64 5f 22 3e 63 10 6b  |...n.-.5.d_">c.k|
+00000270  be ff 14 86 6d 0d f0 15  31 a8 14 38 1e 3b 84 87  |....m...1..8.;..|
+00000280  2c cb 98 ed 51 76 b9 b1  4f dd db 9b 84 04 86 40  |,...Qv..O......@|
+00000290  fa 51 dd ba b4 8d eb e3  46 de 46 b9 4f 86 c7 f9  |.Q......F.F.O...|
+000002a0  a4 c2 41 34 ac cc f6 ea  b0 ab 39 18 16 03 03 00  |..A4......9.....|
+000002b0  04 0e 00 00 00                                    |.....|
 >>> Flow 3 (client to server)
-00000000  16 03 03 00 86 10 00 00  82 00 80 7a c0 73 ec cb  |...........z.s..|
-00000010  cf c2 a8 86 c0 7e 03 63  57 a1 ce 42 37 6d 78 54  |.....~.cW..B7mxT|
-00000020  29 f5 3e cc 57 c7 0d d9  69 e1 52 5c 3b 6b c4 c7  |).>.W...i.R\;k..|
-00000030  20 6d 59 ee c0 07 81 74  74 9f 62 41 64 f0 4d c8  | mY....tt.bAd.M.|
-00000040  9b aa 1a b9 da 56 07 f5  6c 1c 59 8c d3 f9 08 d9  |.....V..l.Y.....|
-00000050  08 f4 16 93 5d 9a e5 6f  fb 9f ba 3d 3c d6 81 ad  |....]..o...=<...|
-00000060  02 12 a7 28 b6 81 6a 77  c3 e9 d7 c7 54 d6 77 83  |...(..jw....T.w.|
-00000070  77 de 71 fb b3 f3 2d c4  a5 b1 e5 de aa 0e 21 bd  |w.q...-.......!.|
-00000080  91 a2 dc 7f f7 6f 90 82  54 b1 e7 14 03 03 00 01  |.....o..T.......|
-00000090  01 16 03 03 00 30 8f ee  bf fb c8 5c 54 f5 29 23  |.....0.....\T.)#|
-000000a0  d4 55 f6 98 a1 6e d5 43  e7 81 b2 36 f2 98 d8 1b  |.U...n.C...6....|
-000000b0  0d 76 cb 14 ba 32 d7 36  30 e6 ab 42 80 95 f6 8a  |.v...2.60..B....|
-000000c0  60 64 a0 6b 90 81                                 |`d.k..|
+00000000  16 03 03 00 86 10 00 00  82 00 80 15 75 c5 63 e0  |............u.c.|
+00000010  c3 a5 89 dd b3 bf 03 1d  bd 62 86 2e 10 98 79 cb  |.........b....y.|
+00000020  40 3d 9b 36 7e 55 65 d7  80 0a c5 24 ff ad 98 d5  |@=.6~Ue....$....|
+00000030  d4 d9 4e 1b ed 50 0a fa  8a 3e f3 01 c4 e3 47 f7  |..N..P...>....G.|
+00000040  bd 81 fc 33 0b 61 6b b5  3f 38 9b 24 cd 7d 46 66  |...3.ak.?8.$.}Ff|
+00000050  18 87 ea 67 04 b7 ad 23  ac 64 4e 21 cd 29 9f 60  |...g...#.dN!.).`|
+00000060  0e c1 ca 3d 25 d6 d5 2b  e2 60 dc b5 57 be c0 b8  |...=%..+.`..W...|
+00000070  b6 35 25 96 5b 36 55 53  86 b7 90 ef 6c bf 45 2a  |.5%.[6US....l.E*|
+00000080  3d a0 af 08 f0 8a 9c d0  d8 6b 88 14 03 03 00 01  |=........k......|
+00000090  01 16 03 03 00 30 c5 0f  b8 12 c6 5a 42 6a d8 3f  |.....0.....ZBj.?|
+000000a0  f5 49 e4 9a 5d b7 93 90  e7 09 1f 68 40 9d 33 a9  |.I..]......h@.3.|
+000000b0  21 fa 9c 12 c7 7c d4 bf  91 c2 f8 ac 27 b9 8b b6  |!....|......'...|
+000000c0  34 6e f3 c0 fb 83                                 |4n....|
 >>> Flow 4 (server to client)
 00000000  14 03 03 00 01 01 16 03  03 00 30 00 00 00 00 00  |..........0.....|
-00000010  00 00 00 2c 21 52 34 63  ac e3 a3 66 45 00 41 0c  |...,!R4c...fE.A.|
-00000020  93 5d 6a 74 5a 25 dc 69  1d 76 73 0c f4 42 6a 18  |.]jtZ%.i.vs..Bj.|
-00000030  5b 62 23 e7 fe 41 cf d4  9b 86 35 17 03 03 00 30  |[b#..A....5....0|
-00000040  00 00 00 00 00 00 00 00  7d 5d ce 43 85 5c 6b 89  |........}].C.\k.|
-00000050  c9 a5 0e 22 69 8e b9 4a  77 4c c0 4e cc 79 d9 7e  |..."i..JwL.N.y.~|
-00000060  a3 c8 d3 db 5c 53 f8 92  4d c4 5a 88 72 58 05 11  |....\S..M.Z.rX..|
-00000070  15 03 03 00 20 00 00 00  00 00 00 00 00 1d 63 8b  |.... .........c.|
-00000080  a7 74 fb 76 1d 47 31 93  1f ec 8c e2 18 8e 21 dd  |.t.v.G1.......!.|
-00000090  87 97 9f 1c ca                                    |.....|
+00000010  00 00 00 c1 a2 65 c1 36  63 85 cd ca 5a eb 50 ab  |.....e.6c...Z.P.|
+00000020  bb ec 43 30 37 8f 71 b9  b7 2d 1b bb a2 88 fa d5  |..C07.q..-......|
+00000030  b4 a5 c5 4b 19 71 53 46  7d bb d0 17 03 03 00 30  |...K.qSF}......0|
+00000040  00 00 00 00 00 00 00 00  6a a1 3d c6 35 a0 58 c4  |........j.=.5.X.|
+00000050  ef 12 f2 59 1e 02 42 33  42 5f fe 87 a2 1a ce b7  |...Y..B3B_......|
+00000060  0d d2 36 7c 7f 1a 4c 79  1f 38 34 58 b3 05 fb 96  |..6|..Ly.84X....|
+00000070  15 03 03 00 20 00 00 00  00 00 00 00 00 a1 89 42  |.... ..........B|
+00000080  bc 58 1f 2f 9b c4 d7 e2  d1 ce 1c c9 e0 a5 47 be  |.X./..........G.|
+00000090  63 0c a4 bf 26                                    |c...&|
diff --git a/third_party/gofrontend/libgo/go/crypto/tls/testdata/Server-TLSv12-RSA-AES b/third_party/gofrontend/libgo/go/crypto/tls/testdata/Server-TLSv12-RSA-AES
index a152a96..4ca860d 100644
--- a/third_party/gofrontend/libgo/go/crypto/tls/testdata/Server-TLSv12-RSA-AES
+++ b/third_party/gofrontend/libgo/go/crypto/tls/testdata/Server-TLSv12-RSA-AES
@@ -1,87 +1,81 @@
 >>> Flow 1 (client to server)
-00000000  16 03 01 00 5c 01 00 00  58 03 03 52 cc 57 59 d0  |....\...X..R.WY.|
-00000010  38 05 36 7e e3 1e 93 2a  5a bf dc c2 f8 0a 03 6f  |8.6~...*Z......o|
-00000020  1a fc 21 74 e5 8b 2a c3  9e 2c 26 00 00 04 00 2f  |..!t..*..,&..../|
-00000030  00 ff 01 00 00 2b 00 0d  00 22 00 20 06 01 06 02  |.....+...". ....|
+00000000  16 03 01 00 5a 01 00 00  56 03 03 be 9a 2f 46 66  |....Z...V..../Ff|
+00000010  a3 b3 10 62 63 b6 32 cb  de 1e eb 76 13 50 60 d0  |...bc.2....v.P`.|
+00000020  ee 40 a9 cd 50 ae d8 86  10 37 8b 00 00 04 00 2f  |.@..P....7...../|
+00000030  00 ff 01 00 00 29 00 0d  00 20 00 1e 06 01 06 02  |.....)... ......|
 00000040  06 03 05 01 05 02 05 03  04 01 04 02 04 03 03 01  |................|
-00000050  03 02 03 03 02 01 02 02  02 03 01 01 00 0f 00 01  |................|
-00000060  01                                                |.|
+00000050  03 02 03 03 02 01 02 02  02 03 00 0f 00 01 01     |...............|
 >>> Flow 2 (server to client)
 00000000  16 03 03 00 31 02 00 00  2d 03 03 00 00 00 00 00  |....1...-.......|
 00000010  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
 00000020  00 00 00 00 00 00 00 00  00 00 00 00 00 2f 00 00  |............./..|
-00000030  05 ff 01 00 01 00 16 03  03 02 be 0b 00 02 ba 00  |................|
-00000040  02 b7 00 02 b4 30 82 02  b0 30 82 02 19 a0 03 02  |.....0...0......|
-00000050  01 02 02 09 00 85 b0 bb  a4 8a 7f b8 ca 30 0d 06  |.............0..|
-00000060  09 2a 86 48 86 f7 0d 01  01 05 05 00 30 45 31 0b  |.*.H........0E1.|
-00000070  30 09 06 03 55 04 06 13  02 41 55 31 13 30 11 06  |0...U....AU1.0..|
-00000080  03 55 04 08 13 0a 53 6f  6d 65 2d 53 74 61 74 65  |.U....Some-State|
-00000090  31 21 30 1f 06 03 55 04  0a 13 18 49 6e 74 65 72  |1!0...U....Inter|
-000000a0  6e 65 74 20 57 69 64 67  69 74 73 20 50 74 79 20  |net Widgits Pty |
-000000b0  4c 74 64 30 1e 17 0d 31  30 30 34 32 34 30 39 30  |Ltd0...100424090|
-000000c0  39 33 38 5a 17 0d 31 31  30 34 32 34 30 39 30 39  |938Z..1104240909|
-000000d0  33 38 5a 30 45 31 0b 30  09 06 03 55 04 06 13 02  |38Z0E1.0...U....|
-000000e0  41 55 31 13 30 11 06 03  55 04 08 13 0a 53 6f 6d  |AU1.0...U....Som|
-000000f0  65 2d 53 74 61 74 65 31  21 30 1f 06 03 55 04 0a  |e-State1!0...U..|
-00000100  13 18 49 6e 74 65 72 6e  65 74 20 57 69 64 67 69  |..Internet Widgi|
-00000110  74 73 20 50 74 79 20 4c  74 64 30 81 9f 30 0d 06  |ts Pty Ltd0..0..|
-00000120  09 2a 86 48 86 f7 0d 01  01 01 05 00 03 81 8d 00  |.*.H............|
-00000130  30 81 89 02 81 81 00 bb  79 d6 f5 17 b5 e5 bf 46  |0.......y......F|
-00000140  10 d0 dc 69 be e6 2b 07  43 5a d0 03 2d 8a 7a 43  |...i..+.CZ..-.zC|
-00000150  85 b7 14 52 e7 a5 65 4c  2c 78 b8 23 8c b5 b4 82  |...R..eL,x.#....|
-00000160  e5 de 1f 95 3b 7e 62 a5  2c a5 33 d6 fe 12 5c 7a  |....;~b.,.3...\z|
-00000170  56 fc f5 06 bf fa 58 7b  26 3f b5 cd 04 d3 d0 c9  |V.....X{&?......|
-00000180  21 96 4a c7 f4 54 9f 5a  bf ef 42 71 00 fe 18 99  |!.J..T.Z..Bq....|
-00000190  07 7f 7e 88 7d 7d f1 04  39 c4 a2 2e db 51 c9 7c  |..~.}}..9....Q.||
-000001a0  e3 c0 4c 3b 32 66 01 cf  af b1 1d b8 71 9a 1d db  |..L;2f......q...|
-000001b0  db 89 6b ae da 2d 79 02  03 01 00 01 a3 81 a7 30  |..k..-y........0|
-000001c0  81 a4 30 1d 06 03 55 1d  0e 04 16 04 14 b1 ad e2  |..0...U.........|
-000001d0  85 5a cf cb 28 db 69 ce  23 69 de d3 26 8e 18 88  |.Z..(.i.#i..&...|
-000001e0  39 30 75 06 03 55 1d 23  04 6e 30 6c 80 14 b1 ad  |90u..U.#.n0l....|
-000001f0  e2 85 5a cf cb 28 db 69  ce 23 69 de d3 26 8e 18  |..Z..(.i.#i..&..|
-00000200  88 39 a1 49 a4 47 30 45  31 0b 30 09 06 03 55 04  |.9.I.G0E1.0...U.|
-00000210  06 13 02 41 55 31 13 30  11 06 03 55 04 08 13 0a  |...AU1.0...U....|
-00000220  53 6f 6d 65 2d 53 74 61  74 65 31 21 30 1f 06 03  |Some-State1!0...|
-00000230  55 04 0a 13 18 49 6e 74  65 72 6e 65 74 20 57 69  |U....Internet Wi|
-00000240  64 67 69 74 73 20 50 74  79 20 4c 74 64 82 09 00  |dgits Pty Ltd...|
-00000250  85 b0 bb a4 8a 7f b8 ca  30 0c 06 03 55 1d 13 04  |........0...U...|
-00000260  05 30 03 01 01 ff 30 0d  06 09 2a 86 48 86 f7 0d  |.0....0...*.H...|
-00000270  01 01 05 05 00 03 81 81  00 08 6c 45 24 c7 6b b1  |..........lE$.k.|
-00000280  59 ab 0c 52 cc f2 b0 14  d7 87 9d 7a 64 75 b5 5a  |Y..R.......zdu.Z|
-00000290  95 66 e4 c5 2b 8e ae 12  66 1f eb 4f 38 b3 6e 60  |.f..+...f..O8.n`|
-000002a0  d3 92 fd f7 41 08 b5 25  13 b1 18 7a 24 fb 30 1d  |....A..%...z$.0.|
-000002b0  ba ed 98 b9 17 ec e7 d7  31 59 db 95 d3 1d 78 ea  |........1Y....x.|
-000002c0  50 56 5c d5 82 5a 2d 5a  5f 33 c4 b6 d8 c9 75 90  |PV\..Z-Z_3....u.|
-000002d0  96 8c 0f 52 98 b5 cd 98  1f 89 20 5f f2 a0 1c a3  |...R...... _....|
-000002e0  1b 96 94 dd a9 fd 57 e9  70 e8 26 6d 71 99 9b 26  |......W.p.&mq..&|
-000002f0  6e 38 50 29 6c 90 a7 bd  d9 16 03 03 00 04 0e 00  |n8P)l...........|
-00000300  00 00                                             |..|
+00000030  05 ff 01 00 01 00 16 03  03 02 71 0b 00 02 6d 00  |..........q...m.|
+00000040  02 6a 00 02 67 30 82 02  63 30 82 01 cc a0 03 02  |.j..g0..c0......|
+00000050  01 02 02 09 00 a2 73 00  0c 81 00 cb f3 30 0d 06  |......s......0..|
+00000060  09 2a 86 48 86 f7 0d 01  01 0b 05 00 30 2b 31 17  |.*.H........0+1.|
+00000070  30 15 06 03 55 04 0a 13  0e 47 6f 6f 67 6c 65 20  |0...U....Google |
+00000080  54 45 53 54 49 4e 47 31  10 30 0e 06 03 55 04 03  |TESTING1.0...U..|
+00000090  13 07 47 6f 20 52 6f 6f  74 30 1e 17 0d 31 35 30  |..Go Root0...150|
+000000a0  31 30 31 30 30 30 30 30  30 5a 17 0d 32 35 30 31  |101000000Z..2501|
+000000b0  30 31 30 30 30 30 30 30  5a 30 26 31 17 30 15 06  |01000000Z0&1.0..|
+000000c0  03 55 04 0a 13 0e 47 6f  6f 67 6c 65 20 54 45 53  |.U....Google TES|
+000000d0  54 49 4e 47 31 0b 30 09  06 03 55 04 03 13 02 47  |TING1.0...U....G|
+000000e0  6f 30 81 9f 30 0d 06 09  2a 86 48 86 f7 0d 01 01  |o0..0...*.H.....|
+000000f0  01 05 00 03 81 8d 00 30  81 89 02 81 81 00 af 87  |.......0........|
+00000100  88 f6 20 1b 95 65 6c 14  ab 44 05 af 3b 45 14 e3  |.. ..el..D..;E..|
+00000110  b7 6d fd 00 63 4d 95 7f  fe 6a 62 35 86 c0 4a f9  |.m..cM...jb5..J.|
+00000120  18 7c f6 aa 25 5e 7a 64  31 66 00 ba f4 8e 92 af  |.|..%^zd1f......|
+00000130  c7 6b d8 76 d4 f3 5f 41  cb 6e 56 15 97 1b 97 c1  |.k.v.._A.nV.....|
+00000140  3c 12 39 21 66 3d 2b 16  d1 bc db 1c c0 a7 da b7  |<.9!f=+.........|
+00000150  ca ad ba da cb d5 21 50  ec de 8d ab d1 6b 81 4b  |......!P.....k.K|
+00000160  89 02 f3 c4 be c1 6c 89  b1 44 84 bd 21 d1 04 7d  |......l..D..!..}|
+00000170  9d 16 4d f9 82 15 f6 ef  fa d6 09 47 f2 fb 02 03  |..M........G....|
+00000180  01 00 01 a3 81 93 30 81  90 30 0e 06 03 55 1d 0f  |......0..0...U..|
+00000190  01 01 ff 04 04 03 02 05  a0 30 1d 06 03 55 1d 25  |.........0...U.%|
+000001a0  04 16 30 14 06 08 2b 06  01 05 05 07 03 01 06 08  |..0...+.........|
+000001b0  2b 06 01 05 05 07 03 02  30 0c 06 03 55 1d 13 01  |+.......0...U...|
+000001c0  01 ff 04 02 30 00 30 19  06 03 55 1d 0e 04 12 04  |....0.0...U.....|
+000001d0  10 12 50 8d 89 6f 1b d1  dc 54 4d 6e cb 69 5e 06  |..P..o...TMn.i^.|
+000001e0  f4 30 1b 06 03 55 1d 23  04 14 30 12 80 10 bf 3d  |.0...U.#..0....=|
+000001f0  b6 a9 66 f2 b8 40 cf ea  b4 03 78 48 1a 41 30 19  |..f..@....xH.A0.|
+00000200  06 03 55 1d 11 04 12 30  10 82 0e 65 78 61 6d 70  |..U....0...examp|
+00000210  6c 65 2e 67 6f 6c 61 6e  67 30 0d 06 09 2a 86 48  |le.golang0...*.H|
+00000220  86 f7 0d 01 01 0b 05 00  03 81 81 00 92 7c af 91  |.............|..|
+00000230  55 12 18 96 59 31 a6 48  40 d5 2d d5 ee bb 02 a0  |U...Y1.H@.-.....|
+00000240  f5 c2 1e 7c 9b b3 30 7d  3c dc 76 da 4f 3d c0 fa  |...|..0}<.v.O=..|
+00000250  ae 2d 33 24 6b 03 7b 1b  67 59 11 21 b5 11 bc 77  |.-3$k.{.gY.!...w|
+00000260  b9 d9 e0 6e a8 2d 2e 35  fa 64 5f 22 3e 63 10 6b  |...n.-.5.d_">c.k|
+00000270  be ff 14 86 6d 0d f0 15  31 a8 14 38 1e 3b 84 87  |....m...1..8.;..|
+00000280  2c cb 98 ed 51 76 b9 b1  4f dd db 9b 84 04 86 40  |,...Qv..O......@|
+00000290  fa 51 dd ba b4 8d eb e3  46 de 46 b9 4f 86 c7 f9  |.Q......F.F.O...|
+000002a0  a4 c2 41 34 ac cc f6 ea  b0 ab 39 18 16 03 03 00  |..A4......9.....|
+000002b0  04 0e 00 00 00                                    |.....|
 >>> Flow 3 (client to server)
-00000000  16 03 03 00 86 10 00 00  82 00 80 4b b4 28 bc 78  |...........K.(.x|
-00000010  41 34 f3 49 e8 74 07 74  42 ae 2e 55 9e 9a ce e5  |A4.I.t.tB..U....|
-00000020  4a 1b e7 55 c7 64 c4 9c  b3 dd 20 d6 f8 8e 67 b3  |J..U.d.... ...g.|
-00000030  7a 5c 3b 34 e4 1a f6 bd  65 fc 21 cd 9a de 64 77  |z\;4....e.!...dw|
-00000040  09 a5 92 e5 a4 f5 18 7b  23 5b 8b c1 95 23 97 6f  |.......{#[...#.o|
-00000050  76 55 04 34 22 7d 43 71  db cd eb f8 36 36 44 4b  |vU.4"}Cq....66DK|
-00000060  ae e3 cc ec 64 88 7b e1  ea d6 ab 49 35 94 a5 04  |....d.{....I5...|
-00000070  1e 83 c5 cf 21 bb ca 33  5f d4 bf 1d d3 4d 07 59  |....!..3_....M.Y|
-00000080  b4 39 b2 4b 7b 05 43 70  0d ba 7a 14 03 03 00 01  |.9.K{.Cp..z.....|
-00000090  01 16 03 03 00 40 74 4b  7d b2 53 49 ea 86 90 c3  |.....@tK}.SI....|
-000000a0  64 6b 64 31 1a 2a 3f 1a  37 1e 56 b8 dd 12 6d 56  |dkd1.*?.7.V...mV|
-000000b0  2a 61 92 5b 39 e7 e1 be  71 70 4b 9b b3 f0 71 e7  |*a.[9...qpK...q.|
-000000c0  47 2e 2e 17 c3 0a 66 9f  69 74 30 2d f0 a0 7f 84  |G.....f.it0-....|
-000000d0  25 db c1 81 ee cf                                 |%.....|
+00000000  16 03 03 00 86 10 00 00  82 00 80 61 b4 31 93 2b  |...........a.1.+|
+00000010  d5 e8 06 74 b1 f6 d6 5f  a3 92 78 b6 cf bf 7f ea  |...t..._..x.....|
+00000020  a2 07 1e 90 94 68 5b 19  ae d4 e3 11 78 96 58 fd  |.....h[.....x.X.|
+00000030  96 18 f2 09 58 dc 39 a1  d9 9e 83 f0 24 45 6e 6b  |....X.9.....$Enk|
+00000040  e6 5e e7 cb 94 42 00 10  64 d5 d2 bc 80 23 bd fe  |.^...B..d....#..|
+00000050  5c 3e 3a 80 ff 38 b8 dc  ff 25 ba b0 0a cc ef 94  |\>:..8...%......|
+00000060  a1 31 bd 04 93 91 86 6e  8b fd a1 9d 01 ee 91 a6  |.1.....n........|
+00000070  44 8b 21 55 52 67 3e b1  e4 6e bd 1f 07 85 e1 97  |D.!URg>..n......|
+00000080  7f 55 70 00 5f f4 4b e6  50 45 f7 14 03 03 00 01  |.Up._.K.PE......|
+00000090  01 16 03 03 00 40 71 ff  ab 6d 79 3c da dc 5b 34  |.....@q..my<..[4|
+000000a0  48 39 48 08 e3 29 cb 53  21 fd 67 93 0b f8 81 47  |H9H..).S!.g....G|
+000000b0  40 7f 23 50 5f 94 db 2b  7b 7e 9f 0b bf 38 59 d9  |@.#P_..+{~...8Y.|
+000000c0  6b 57 8f 1e 83 eb 93 2c  62 12 31 c6 f5 21 f2 22  |kW.....,b.1..!."|
+000000d0  7a 82 e9 e6 ec 38                                 |z....8|
 >>> Flow 4 (server to client)
 00000000  14 03 03 00 01 01 16 03  03 00 40 00 00 00 00 00  |..........@.....|
-00000010  00 00 00 00 00 00 00 00  00 00 00 f3 4d 5a fc 21  |............MZ.!|
-00000020  30 b5 a1 86 9d e2 ea 38  ac 54 57 fa 5a 54 97 b8  |0......8.TW.ZT..|
-00000030  bb 4d 64 09 ef ce a1 75  0c 50 8d ff 5c c2 e9 47  |.Md....u.P..\..G|
-00000040  95 93 53 c0 bd dc c5 9c  e0 59 17 17 03 03 00 40  |..S......Y.....@|
+00000010  00 00 00 00 00 00 00 00  00 00 00 45 87 33 41 c1  |...........E.3A.|
+00000020  b8 e7 4c 11 1c 1b 7b 55  51 85 06 01 c1 b6 87 6b  |..L...{UQ......k|
+00000030  01 b3 56 c4 5a 37 ea b6  3a c4 b0 da 1b 5c 15 d4  |..V.Z7..:....\..|
+00000040  03 5a 57 e9 9a 56 16 a5  fa 77 1c 17 03 03 00 40  |.ZW..V...w.....@|
 00000050  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
-00000060  69 c5 48 6e 45 cf 98 1b  2c 23 40 d1 ab a3 c2 e2  |i.HnE...,#@.....|
-00000070  10 7b b1 c8 21 3c f0 eb  96 bd 4f 78 b2 4a 7b 18  |.{..!<....Ox.J{.|
-00000080  4c b1 a6 67 bf 06 40 01  d0 8d 91 be 17 d8 0c 71  |L..g..@........q|
+00000060  6f 2e 7c ba 3d 85 4c 7b  1f 13 a5 d6 97 e6 67 f4  |o.|.=.L{......g.|
+00000070  24 d5 a8 d4 26 41 64 0a  fd b3 2e a0 a2 7a 2b 54  |$...&Ad......z+T|
+00000080  a4 1d 6e fe 4c c4 73 e3  76 d0 3a 60 52 df b0 53  |..n.L.s.v.:`R..S|
 00000090  15 03 03 00 30 00 00 00  00 00 00 00 00 00 00 00  |....0...........|
-000000a0  00 00 00 00 00 20 84 80  3d 70 fe ae ee d7 2f e9  |..... ..=p..../.|
-000000b0  bf 65 30 bf 0b dd 98 ea  bb ba 12 14 98 53 7f d5  |.e0..........S..|
-000000c0  56 ce 06 3c d0                                    |V..<.|
+000000a0  00 00 00 00 00 8b 0a 6d  14 3b 84 bc 7d c6 8d 9d  |.......m.;..}...|
+000000b0  d5 27 32 84 4b 14 75 42  0f aa 5e 88 ba fa a2 c7  |.'2.K.uB..^.....|
+000000c0  16 93 8a c4 fd                                    |.....|
diff --git a/third_party/gofrontend/libgo/go/crypto/tls/testdata/Server-TLSv12-RSA-AES-GCM b/third_party/gofrontend/libgo/go/crypto/tls/testdata/Server-TLSv12-RSA-AES-GCM
index 0ddfe02..7a26ebd 100644
--- a/third_party/gofrontend/libgo/go/crypto/tls/testdata/Server-TLSv12-RSA-AES-GCM
+++ b/third_party/gofrontend/libgo/go/crypto/tls/testdata/Server-TLSv12-RSA-AES-GCM
@@ -1,93 +1,87 @@
 >>> Flow 1 (client to server)
-00000000  16 03 01 00 9c 01 00 00  98 03 03 53 04 f1 30 73  |...........S..0s|
-00000010  a1 ea 8c d2 90 1c c6 d6  0d 3c af 58 21 65 90 25  |.........<.X!e.%|
-00000020  5e fa f4 27 22 65 c9 68  90 b9 04 00 00 04 c0 2f  |^..'"e.h......./|
-00000030  00 ff 01 00 00 6b 00 0b  00 04 03 00 01 02 00 0a  |.....k..........|
+00000000  16 03 01 00 9a 01 00 00  96 03 03 16 dc f8 f5 3a  |...............:|
+00000010  13 32 e6 1f bd f6 3c 66  b7 4c 67 17 ee b2 2a ba  |.2....<f.Lg...*.|
+00000020  68 5b 8e b1 7c 8f 71 d6  6c 30 e1 00 00 04 c0 2f  |h[..|.q.l0...../|
+00000030  00 ff 01 00 00 69 00 0b  00 04 03 00 01 02 00 0a  |.....i..........|
 00000040  00 34 00 32 00 0e 00 0d  00 19 00 0b 00 0c 00 18  |.4.2............|
 00000050  00 09 00 0a 00 16 00 17  00 08 00 06 00 07 00 14  |................|
 00000060  00 15 00 04 00 05 00 12  00 13 00 01 00 02 00 03  |................|
-00000070  00 0f 00 10 00 11 00 0d  00 22 00 20 06 01 06 02  |.........". ....|
+00000070  00 0f 00 10 00 11 00 0d  00 20 00 1e 06 01 06 02  |......... ......|
 00000080  06 03 05 01 05 02 05 03  04 01 04 02 04 03 03 01  |................|
-00000090  03 02 03 03 02 01 02 02  02 03 01 01 00 0f 00 01  |................|
-000000a0  01                                                |.|
+00000090  03 02 03 03 02 01 02 02  02 03 00 0f 00 01 01     |...............|
 >>> Flow 2 (server to client)
 00000000  16 03 03 00 31 02 00 00  2d 03 03 00 00 00 00 00  |....1...-.......|
 00000010  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
 00000020  00 00 00 00 00 00 00 00  00 00 00 00 c0 2f 00 00  |............./..|
-00000030  05 ff 01 00 01 00 16 03  03 02 be 0b 00 02 ba 00  |................|
-00000040  02 b7 00 02 b4 30 82 02  b0 30 82 02 19 a0 03 02  |.....0...0......|
-00000050  01 02 02 09 00 85 b0 bb  a4 8a 7f b8 ca 30 0d 06  |.............0..|
-00000060  09 2a 86 48 86 f7 0d 01  01 05 05 00 30 45 31 0b  |.*.H........0E1.|
-00000070  30 09 06 03 55 04 06 13  02 41 55 31 13 30 11 06  |0...U....AU1.0..|
-00000080  03 55 04 08 13 0a 53 6f  6d 65 2d 53 74 61 74 65  |.U....Some-State|
-00000090  31 21 30 1f 06 03 55 04  0a 13 18 49 6e 74 65 72  |1!0...U....Inter|
-000000a0  6e 65 74 20 57 69 64 67  69 74 73 20 50 74 79 20  |net Widgits Pty |
-000000b0  4c 74 64 30 1e 17 0d 31  30 30 34 32 34 30 39 30  |Ltd0...100424090|
-000000c0  39 33 38 5a 17 0d 31 31  30 34 32 34 30 39 30 39  |938Z..1104240909|
-000000d0  33 38 5a 30 45 31 0b 30  09 06 03 55 04 06 13 02  |38Z0E1.0...U....|
-000000e0  41 55 31 13 30 11 06 03  55 04 08 13 0a 53 6f 6d  |AU1.0...U....Som|
-000000f0  65 2d 53 74 61 74 65 31  21 30 1f 06 03 55 04 0a  |e-State1!0...U..|
-00000100  13 18 49 6e 74 65 72 6e  65 74 20 57 69 64 67 69  |..Internet Widgi|
-00000110  74 73 20 50 74 79 20 4c  74 64 30 81 9f 30 0d 06  |ts Pty Ltd0..0..|
-00000120  09 2a 86 48 86 f7 0d 01  01 01 05 00 03 81 8d 00  |.*.H............|
-00000130  30 81 89 02 81 81 00 bb  79 d6 f5 17 b5 e5 bf 46  |0.......y......F|
-00000140  10 d0 dc 69 be e6 2b 07  43 5a d0 03 2d 8a 7a 43  |...i..+.CZ..-.zC|
-00000150  85 b7 14 52 e7 a5 65 4c  2c 78 b8 23 8c b5 b4 82  |...R..eL,x.#....|
-00000160  e5 de 1f 95 3b 7e 62 a5  2c a5 33 d6 fe 12 5c 7a  |....;~b.,.3...\z|
-00000170  56 fc f5 06 bf fa 58 7b  26 3f b5 cd 04 d3 d0 c9  |V.....X{&?......|
-00000180  21 96 4a c7 f4 54 9f 5a  bf ef 42 71 00 fe 18 99  |!.J..T.Z..Bq....|
-00000190  07 7f 7e 88 7d 7d f1 04  39 c4 a2 2e db 51 c9 7c  |..~.}}..9....Q.||
-000001a0  e3 c0 4c 3b 32 66 01 cf  af b1 1d b8 71 9a 1d db  |..L;2f......q...|
-000001b0  db 89 6b ae da 2d 79 02  03 01 00 01 a3 81 a7 30  |..k..-y........0|
-000001c0  81 a4 30 1d 06 03 55 1d  0e 04 16 04 14 b1 ad e2  |..0...U.........|
-000001d0  85 5a cf cb 28 db 69 ce  23 69 de d3 26 8e 18 88  |.Z..(.i.#i..&...|
-000001e0  39 30 75 06 03 55 1d 23  04 6e 30 6c 80 14 b1 ad  |90u..U.#.n0l....|
-000001f0  e2 85 5a cf cb 28 db 69  ce 23 69 de d3 26 8e 18  |..Z..(.i.#i..&..|
-00000200  88 39 a1 49 a4 47 30 45  31 0b 30 09 06 03 55 04  |.9.I.G0E1.0...U.|
-00000210  06 13 02 41 55 31 13 30  11 06 03 55 04 08 13 0a  |...AU1.0...U....|
-00000220  53 6f 6d 65 2d 53 74 61  74 65 31 21 30 1f 06 03  |Some-State1!0...|
-00000230  55 04 0a 13 18 49 6e 74  65 72 6e 65 74 20 57 69  |U....Internet Wi|
-00000240  64 67 69 74 73 20 50 74  79 20 4c 74 64 82 09 00  |dgits Pty Ltd...|
-00000250  85 b0 bb a4 8a 7f b8 ca  30 0c 06 03 55 1d 13 04  |........0...U...|
-00000260  05 30 03 01 01 ff 30 0d  06 09 2a 86 48 86 f7 0d  |.0....0...*.H...|
-00000270  01 01 05 05 00 03 81 81  00 08 6c 45 24 c7 6b b1  |..........lE$.k.|
-00000280  59 ab 0c 52 cc f2 b0 14  d7 87 9d 7a 64 75 b5 5a  |Y..R.......zdu.Z|
-00000290  95 66 e4 c5 2b 8e ae 12  66 1f eb 4f 38 b3 6e 60  |.f..+...f..O8.n`|
-000002a0  d3 92 fd f7 41 08 b5 25  13 b1 18 7a 24 fb 30 1d  |....A..%...z$.0.|
-000002b0  ba ed 98 b9 17 ec e7 d7  31 59 db 95 d3 1d 78 ea  |........1Y....x.|
-000002c0  50 56 5c d5 82 5a 2d 5a  5f 33 c4 b6 d8 c9 75 90  |PV\..Z-Z_3....u.|
-000002d0  96 8c 0f 52 98 b5 cd 98  1f 89 20 5f f2 a0 1c a3  |...R...... _....|
-000002e0  1b 96 94 dd a9 fd 57 e9  70 e8 26 6d 71 99 9b 26  |......W.p.&mq..&|
-000002f0  6e 38 50 29 6c 90 a7 bd  d9 16 03 03 00 cd 0c 00  |n8P)l...........|
-00000300  00 c9 03 00 17 41 04 1e  18 37 ef 0d 19 51 88 35  |.....A...7...Q.5|
-00000310  75 71 b5 e5 54 5b 12 2e  8f 09 67 fd a7 24 20 3e  |uq..T[....g..$ >|
-00000320  b2 56 1c ce 97 28 5e f8  2b 2d 4f 9e f1 07 9f 6c  |.V...(^.+-O....l|
-00000330  4b 5b 83 56 e2 32 42 e9  58 b6 d7 49 a6 b5 68 1a  |K[.V.2B.X..I..h.|
-00000340  41 03 56 6b dc 5a 89 04  01 00 80 a2 54 61 84 29  |A.Vk.Z......Ta.)|
-00000350  3e 97 4b 97 9a 9f 5c c0  49 6d 86 d2 79 8e 95 a1  |>.K...\.Im..y...|
-00000360  0a 5a 36 73 34 bb 05 73  35 47 e1 2b 5d f3 ef 36  |.Z6s4..s5G.+]..6|
-00000370  a8 32 e2 7e ef aa 3f 1f  b3 64 60 d4 06 2e 98 e3  |.2.~..?..d`.....|
-00000380  11 e2 60 3c d6 20 17 63  b2 6f a0 cd 21 01 2b 4e  |..`<. .c.o..!.+N|
-00000390  b2 a8 55 04 39 37 5c 6c  71 66 4d a3 eb 1b 83 67  |..U.97\lqfM....g|
-000003a0  6b 15 a0 56 9a f1 a2 79  92 29 ce 58 3c 10 4d 65  |k..V...y.).X<.Me|
-000003b0  1f 22 e3 ea d8 74 aa 01  7e ca f3 89 23 41 4d bd  |."...t..~...#AM.|
-000003c0  df 77 4e 59 54 97 74 ad  07 ea c0 16 03 03 00 04  |.wNYT.t.........|
-000003d0  0e 00 00 00                                       |....|
+00000030  05 ff 01 00 01 00 16 03  03 02 71 0b 00 02 6d 00  |..........q...m.|
+00000040  02 6a 00 02 67 30 82 02  63 30 82 01 cc a0 03 02  |.j..g0..c0......|
+00000050  01 02 02 09 00 a2 73 00  0c 81 00 cb f3 30 0d 06  |......s......0..|
+00000060  09 2a 86 48 86 f7 0d 01  01 0b 05 00 30 2b 31 17  |.*.H........0+1.|
+00000070  30 15 06 03 55 04 0a 13  0e 47 6f 6f 67 6c 65 20  |0...U....Google |
+00000080  54 45 53 54 49 4e 47 31  10 30 0e 06 03 55 04 03  |TESTING1.0...U..|
+00000090  13 07 47 6f 20 52 6f 6f  74 30 1e 17 0d 31 35 30  |..Go Root0...150|
+000000a0  31 30 31 30 30 30 30 30  30 5a 17 0d 32 35 30 31  |101000000Z..2501|
+000000b0  30 31 30 30 30 30 30 30  5a 30 26 31 17 30 15 06  |01000000Z0&1.0..|
+000000c0  03 55 04 0a 13 0e 47 6f  6f 67 6c 65 20 54 45 53  |.U....Google TES|
+000000d0  54 49 4e 47 31 0b 30 09  06 03 55 04 03 13 02 47  |TING1.0...U....G|
+000000e0  6f 30 81 9f 30 0d 06 09  2a 86 48 86 f7 0d 01 01  |o0..0...*.H.....|
+000000f0  01 05 00 03 81 8d 00 30  81 89 02 81 81 00 af 87  |.......0........|
+00000100  88 f6 20 1b 95 65 6c 14  ab 44 05 af 3b 45 14 e3  |.. ..el..D..;E..|
+00000110  b7 6d fd 00 63 4d 95 7f  fe 6a 62 35 86 c0 4a f9  |.m..cM...jb5..J.|
+00000120  18 7c f6 aa 25 5e 7a 64  31 66 00 ba f4 8e 92 af  |.|..%^zd1f......|
+00000130  c7 6b d8 76 d4 f3 5f 41  cb 6e 56 15 97 1b 97 c1  |.k.v.._A.nV.....|
+00000140  3c 12 39 21 66 3d 2b 16  d1 bc db 1c c0 a7 da b7  |<.9!f=+.........|
+00000150  ca ad ba da cb d5 21 50  ec de 8d ab d1 6b 81 4b  |......!P.....k.K|
+00000160  89 02 f3 c4 be c1 6c 89  b1 44 84 bd 21 d1 04 7d  |......l..D..!..}|
+00000170  9d 16 4d f9 82 15 f6 ef  fa d6 09 47 f2 fb 02 03  |..M........G....|
+00000180  01 00 01 a3 81 93 30 81  90 30 0e 06 03 55 1d 0f  |......0..0...U..|
+00000190  01 01 ff 04 04 03 02 05  a0 30 1d 06 03 55 1d 25  |.........0...U.%|
+000001a0  04 16 30 14 06 08 2b 06  01 05 05 07 03 01 06 08  |..0...+.........|
+000001b0  2b 06 01 05 05 07 03 02  30 0c 06 03 55 1d 13 01  |+.......0...U...|
+000001c0  01 ff 04 02 30 00 30 19  06 03 55 1d 0e 04 12 04  |....0.0...U.....|
+000001d0  10 12 50 8d 89 6f 1b d1  dc 54 4d 6e cb 69 5e 06  |..P..o...TMn.i^.|
+000001e0  f4 30 1b 06 03 55 1d 23  04 14 30 12 80 10 bf 3d  |.0...U.#..0....=|
+000001f0  b6 a9 66 f2 b8 40 cf ea  b4 03 78 48 1a 41 30 19  |..f..@....xH.A0.|
+00000200  06 03 55 1d 11 04 12 30  10 82 0e 65 78 61 6d 70  |..U....0...examp|
+00000210  6c 65 2e 67 6f 6c 61 6e  67 30 0d 06 09 2a 86 48  |le.golang0...*.H|
+00000220  86 f7 0d 01 01 0b 05 00  03 81 81 00 92 7c af 91  |.............|..|
+00000230  55 12 18 96 59 31 a6 48  40 d5 2d d5 ee bb 02 a0  |U...Y1.H@.-.....|
+00000240  f5 c2 1e 7c 9b b3 30 7d  3c dc 76 da 4f 3d c0 fa  |...|..0}<.v.O=..|
+00000250  ae 2d 33 24 6b 03 7b 1b  67 59 11 21 b5 11 bc 77  |.-3$k.{.gY.!...w|
+00000260  b9 d9 e0 6e a8 2d 2e 35  fa 64 5f 22 3e 63 10 6b  |...n.-.5.d_">c.k|
+00000270  be ff 14 86 6d 0d f0 15  31 a8 14 38 1e 3b 84 87  |....m...1..8.;..|
+00000280  2c cb 98 ed 51 76 b9 b1  4f dd db 9b 84 04 86 40  |,...Qv..O......@|
+00000290  fa 51 dd ba b4 8d eb e3  46 de 46 b9 4f 86 c7 f9  |.Q......F.F.O...|
+000002a0  a4 c2 41 34 ac cc f6 ea  b0 ab 39 18 16 03 03 00  |..A4......9.....|
+000002b0  cd 0c 00 00 c9 03 00 17  41 04 1e 18 37 ef 0d 19  |........A...7...|
+000002c0  51 88 35 75 71 b5 e5 54  5b 12 2e 8f 09 67 fd a7  |Q.5uq..T[....g..|
+000002d0  24 20 3e b2 56 1c ce 97  28 5e f8 2b 2d 4f 9e f1  |$ >.V...(^.+-O..|
+000002e0  07 9f 6c 4b 5b 83 56 e2  32 42 e9 58 b6 d7 49 a6  |..lK[.V.2B.X..I.|
+000002f0  b5 68 1a 41 03 56 6b dc  5a 89 05 01 00 80 40 b3  |.h.A.Vk.Z.....@.|
+00000300  66 ee 53 3c 80 f4 da d1  de e6 fe 50 c8 89 60 d5  |f.S<.......P..`.|
+00000310  e4 80 73 39 91 79 6c cf  89 bb a5 da e4 c7 e5 0d  |..s9.yl.........|
+00000320  13 a6 76 24 65 1a a2 b8  cb 95 c2 c6 9d 66 74 57  |..v$e........ftW|
+00000330  9e 90 4f 48 77 88 3a b4  f3 fa 88 ab 61 22 d3 40  |..OHw.:.....a".@|
+00000340  08 c4 0a 69 19 ed c3 ea  d8 15 79 12 d5 ac 8d af  |...i......y.....|
+00000350  41 7d 87 4b a9 ff f8 cb  24 55 88 38 34 11 a5 bd  |A}.K....$U.84...|
+00000360  c1 d6 e5 86 d5 64 b5 f2  df c8 03 f2 a2 6b ff f4  |.....d.......k..|
+00000370  a8 38 e0 18 04 d4 cd bd  e0 cc 63 fc 3f 8b 16 03  |.8........c.?...|
+00000380  03 00 04 0e 00 00 00                              |.......|
 >>> Flow 3 (client to server)
-00000000  16 03 03 00 46 10 00 00  42 41 04 45 65 ce f7 b9  |....F...BA.Ee...|
-00000010  52 e3 fb 13 db 91 f2 65  43 84 57 f5 1a 19 a0 e6  |R......eC.W.....|
-00000020  89 2d bb 2c 83 6b 62 f6  6f 1f 26 ae 59 67 bd dc  |.-.,.kb.o.&.Yg..|
-00000030  c4 9e 0b dc 7d 6e f8 6b  95 8c 61 47 3d cd d1 df  |....}n.k..aG=...|
-00000040  82 45 30 81 c3 a3 49 5d  85 59 70 14 03 03 00 01  |.E0...I].Yp.....|
-00000050  01 16 03 03 00 28 3f aa  85 33 f9 c6 95 a0 56 ff  |.....(?..3....V.|
-00000060  1c f1 5a ba 6e 41 50 0c  ab 92 e1 e2 8e 89 1c f1  |..Z.nAP.........|
-00000070  fa 54 1b f1 f5 00 01 12  6d c4 96 78 b6 87        |.T......m..x..|
+00000000  16 03 03 00 46 10 00 00  42 41 04 de de ff 8c df  |....F...BA......|
+00000010  d8 4c 72 af 29 3c 4d e0  ed 0f 34 cc fd 2d 52 63  |.Lr.)<M...4..-Rc|
+00000020  94 e8 74 f1 0b 18 69 28  ed 1e f7 62 4e 4f 2c 14  |..t...i(...bNO,.|
+00000030  61 4b 9f 55 d8 70 59 8f  4b a8 ab c6 d2 cd aa 59  |aK.U.pY.K......Y|
+00000040  8a ef 9b b3 f6 ba 52 e5  51 bb a1 14 03 03 00 01  |......R.Q.......|
+00000050  01 16 03 03 00 28 44 1c  eb 89 59 bb ad fb 9f 3f  |.....(D...Y....?|
+00000060  56 06 54 ae 27 6d e4 47  3c 0c 60 30 db 0e d6 0e  |V.T.'m.G<.`0....|
+00000070  9d 0d a9 a0 e7 25 26 6e  99 d0 8f e0 1b 9d        |.....%&n......|
 >>> Flow 4 (server to client)
 00000000  14 03 03 00 01 01 16 03  03 00 28 00 00 00 00 00  |..........(.....|
-00000010  00 00 00 94 5c be 46 05  d6 d0 b0 3a 56 dc 2c 10  |....\.F....:V.,.|
-00000020  0f 6f 5d 33 33 7f a5 4e  74 84 bf 63 87 c4 f4 49  |.o]33..Nt..c...I|
-00000030  bc 6b ab 17 03 03 00 25  00 00 00 00 00 00 00 01  |.k.....%........|
-00000040  7e 4f f9 ae ae fe 6b a0  4a f8 0f 0b b4 b6 65 b6  |~O....k.J.....e.|
-00000050  be 24 5f 94 6d d1 db 54  11 07 b9 ce 01 15 03 03  |.$_.m..T........|
-00000060  00 1a 00 00 00 00 00 00  00 02 a8 1c d6 62 ac fd  |.............b..|
-00000070  77 ba 23 92 5d 34 f1 17  c7 e1 1c 99              |w.#.]4......|
+00000010  00 00 00 92 90 01 f0 70  fa 57 2e 40 d3 4c ef 6a  |.......p.W.@.L.j|
+00000020  03 0c 56 65 f7 c0 3b d0  8a db 48 c9 ae 58 3e 7c  |..Ve..;...H..X>||
+00000030  d1 48 67 17 03 03 00 25  00 00 00 00 00 00 00 01  |.Hg....%........|
+00000040  9e 35 a0 13 73 da 3f 26  ff 1d 90 08 e9 cc 40 7e  |.5..s.?&......@~|
+00000050  82 f3 5e 6e b4 8e 5a 39  7f a4 09 60 b2 15 03 03  |..^n..Z9...`....|
+00000060  00 1a 00 00 00 00 00 00  00 02 04 95 9b 2d 17 1c  |.............-..|
+00000070  6a bc 26 f7 6c 8e f1 c0  0e 82 4a 44              |j.&.l.....JD|
diff --git a/third_party/gofrontend/libgo/go/crypto/tls/testdata/Server-TLSv12-RSA-AES256-GCM-SHA384 b/third_party/gofrontend/libgo/go/crypto/tls/testdata/Server-TLSv12-RSA-AES256-GCM-SHA384
new file mode 100644
index 0000000..d59645c
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/crypto/tls/testdata/Server-TLSv12-RSA-AES256-GCM-SHA384
@@ -0,0 +1,87 @@
+>>> Flow 1 (client to server)
+00000000  16 03 01 00 9a 01 00 00  96 03 03 5d 6b 2a ff 74  |...........]k*.t|
+00000010  88 f1 68 8d 1b eb c3 84  34 b5 19 0a 7d f1 9a 0f  |..h.....4...}...|
+00000020  4d c3 0a d7 98 b8 72 e0  73 e4 38 00 00 04 c0 30  |M.....r.s.8....0|
+00000030  00 ff 01 00 00 69 00 0b  00 04 03 00 01 02 00 0a  |.....i..........|
+00000040  00 34 00 32 00 0e 00 0d  00 19 00 0b 00 0c 00 18  |.4.2............|
+00000050  00 09 00 0a 00 16 00 17  00 08 00 06 00 07 00 14  |................|
+00000060  00 15 00 04 00 05 00 12  00 13 00 01 00 02 00 03  |................|
+00000070  00 0f 00 10 00 11 00 0d  00 20 00 1e 06 01 06 02  |......... ......|
+00000080  06 03 05 01 05 02 05 03  04 01 04 02 04 03 03 01  |................|
+00000090  03 02 03 03 02 01 02 02  02 03 00 0f 00 01 01     |...............|
+>>> Flow 2 (server to client)
+00000000  16 03 03 00 31 02 00 00  2d 03 03 00 00 00 00 00  |....1...-.......|
+00000010  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
+00000020  00 00 00 00 00 00 00 00  00 00 00 00 c0 30 00 00  |.............0..|
+00000030  05 ff 01 00 01 00 16 03  03 02 71 0b 00 02 6d 00  |..........q...m.|
+00000040  02 6a 00 02 67 30 82 02  63 30 82 01 cc a0 03 02  |.j..g0..c0......|
+00000050  01 02 02 09 00 a2 73 00  0c 81 00 cb f3 30 0d 06  |......s......0..|
+00000060  09 2a 86 48 86 f7 0d 01  01 0b 05 00 30 2b 31 17  |.*.H........0+1.|
+00000070  30 15 06 03 55 04 0a 13  0e 47 6f 6f 67 6c 65 20  |0...U....Google |
+00000080  54 45 53 54 49 4e 47 31  10 30 0e 06 03 55 04 03  |TESTING1.0...U..|
+00000090  13 07 47 6f 20 52 6f 6f  74 30 1e 17 0d 31 35 30  |..Go Root0...150|
+000000a0  31 30 31 30 30 30 30 30  30 5a 17 0d 32 35 30 31  |101000000Z..2501|
+000000b0  30 31 30 30 30 30 30 30  5a 30 26 31 17 30 15 06  |01000000Z0&1.0..|
+000000c0  03 55 04 0a 13 0e 47 6f  6f 67 6c 65 20 54 45 53  |.U....Google TES|
+000000d0  54 49 4e 47 31 0b 30 09  06 03 55 04 03 13 02 47  |TING1.0...U....G|
+000000e0  6f 30 81 9f 30 0d 06 09  2a 86 48 86 f7 0d 01 01  |o0..0...*.H.....|
+000000f0  01 05 00 03 81 8d 00 30  81 89 02 81 81 00 af 87  |.......0........|
+00000100  88 f6 20 1b 95 65 6c 14  ab 44 05 af 3b 45 14 e3  |.. ..el..D..;E..|
+00000110  b7 6d fd 00 63 4d 95 7f  fe 6a 62 35 86 c0 4a f9  |.m..cM...jb5..J.|
+00000120  18 7c f6 aa 25 5e 7a 64  31 66 00 ba f4 8e 92 af  |.|..%^zd1f......|
+00000130  c7 6b d8 76 d4 f3 5f 41  cb 6e 56 15 97 1b 97 c1  |.k.v.._A.nV.....|
+00000140  3c 12 39 21 66 3d 2b 16  d1 bc db 1c c0 a7 da b7  |<.9!f=+.........|
+00000150  ca ad ba da cb d5 21 50  ec de 8d ab d1 6b 81 4b  |......!P.....k.K|
+00000160  89 02 f3 c4 be c1 6c 89  b1 44 84 bd 21 d1 04 7d  |......l..D..!..}|
+00000170  9d 16 4d f9 82 15 f6 ef  fa d6 09 47 f2 fb 02 03  |..M........G....|
+00000180  01 00 01 a3 81 93 30 81  90 30 0e 06 03 55 1d 0f  |......0..0...U..|
+00000190  01 01 ff 04 04 03 02 05  a0 30 1d 06 03 55 1d 25  |.........0...U.%|
+000001a0  04 16 30 14 06 08 2b 06  01 05 05 07 03 01 06 08  |..0...+.........|
+000001b0  2b 06 01 05 05 07 03 02  30 0c 06 03 55 1d 13 01  |+.......0...U...|
+000001c0  01 ff 04 02 30 00 30 19  06 03 55 1d 0e 04 12 04  |....0.0...U.....|
+000001d0  10 12 50 8d 89 6f 1b d1  dc 54 4d 6e cb 69 5e 06  |..P..o...TMn.i^.|
+000001e0  f4 30 1b 06 03 55 1d 23  04 14 30 12 80 10 bf 3d  |.0...U.#..0....=|
+000001f0  b6 a9 66 f2 b8 40 cf ea  b4 03 78 48 1a 41 30 19  |..f..@....xH.A0.|
+00000200  06 03 55 1d 11 04 12 30  10 82 0e 65 78 61 6d 70  |..U....0...examp|
+00000210  6c 65 2e 67 6f 6c 61 6e  67 30 0d 06 09 2a 86 48  |le.golang0...*.H|
+00000220  86 f7 0d 01 01 0b 05 00  03 81 81 00 92 7c af 91  |.............|..|
+00000230  55 12 18 96 59 31 a6 48  40 d5 2d d5 ee bb 02 a0  |U...Y1.H@.-.....|
+00000240  f5 c2 1e 7c 9b b3 30 7d  3c dc 76 da 4f 3d c0 fa  |...|..0}<.v.O=..|
+00000250  ae 2d 33 24 6b 03 7b 1b  67 59 11 21 b5 11 bc 77  |.-3$k.{.gY.!...w|
+00000260  b9 d9 e0 6e a8 2d 2e 35  fa 64 5f 22 3e 63 10 6b  |...n.-.5.d_">c.k|
+00000270  be ff 14 86 6d 0d f0 15  31 a8 14 38 1e 3b 84 87  |....m...1..8.;..|
+00000280  2c cb 98 ed 51 76 b9 b1  4f dd db 9b 84 04 86 40  |,...Qv..O......@|
+00000290  fa 51 dd ba b4 8d eb e3  46 de 46 b9 4f 86 c7 f9  |.Q......F.F.O...|
+000002a0  a4 c2 41 34 ac cc f6 ea  b0 ab 39 18 16 03 03 00  |..A4......9.....|
+000002b0  cd 0c 00 00 c9 03 00 17  41 04 1e 18 37 ef 0d 19  |........A...7...|
+000002c0  51 88 35 75 71 b5 e5 54  5b 12 2e 8f 09 67 fd a7  |Q.5uq..T[....g..|
+000002d0  24 20 3e b2 56 1c ce 97  28 5e f8 2b 2d 4f 9e f1  |$ >.V...(^.+-O..|
+000002e0  07 9f 6c 4b 5b 83 56 e2  32 42 e9 58 b6 d7 49 a6  |..lK[.V.2B.X..I.|
+000002f0  b5 68 1a 41 03 56 6b dc  5a 89 05 01 00 80 22 6b  |.h.A.Vk.Z....."k|
+00000300  87 4b f8 ba f2 09 91 ee  ce 81 67 d4 fd d8 b5 07  |.K........g.....|
+00000310  fe c3 88 96 ca e3 3a f0  87 cc ae 44 94 8e 8f 70  |......:....D...p|
+00000320  79 cd de a2 26 4e 17 45  d7 ea 0f 95 a6 c9 7b 17  |y...&N.E......{.|
+00000330  68 7c f5 e8 6c d5 87 6d  5a 7e 53 af 95 0c 42 91  |h|..l..mZ~S...B.|
+00000340  c0 07 18 75 fd 74 1c ad  ef df f8 41 b1 ad fc 36  |...u.t.....A...6|
+00000350  19 31 cf c8 3f 36 55 dd  54 ac 44 a9 3a d1 ae 23  |.1..?6U.T.D.:..#|
+00000360  0a 18 bf b7 6f c7 bc a6  70 50 5e 50 dd da ff 5b  |....o...pP^P...[|
+00000370  67 7d 0a f5 70 a0 8c 88  d9 38 d4 bf a9 c3 16 03  |g}..p....8......|
+00000380  03 00 04 0e 00 00 00                              |.......|
+>>> Flow 3 (client to server)
+00000000  16 03 03 00 46 10 00 00  42 41 04 d0 f7 11 ae 9f  |....F...BA......|
+00000010  ec 2e ac 8e 97 6c 58 0e  57 32 8e ac fa 3e af 36  |.....lX.W2...>.6|
+00000020  22 e1 41 2b d3 d1 9c c2  1d 51 c0 e4 20 b3 4c 85  |".A+.....Q.. .L.|
+00000030  b8 bd f2 d1 c6 2f 7d 83  c7 43 d9 31 36 1a 83 ca  |...../}..C.16...|
+00000040  c6 89 f8 ba 8c d1 7e 99  04 6e 92 14 03 03 00 01  |......~..n......|
+00000050  01 16 03 03 00 28 32 67  c1 6e 5e 1e 4b 51 1b 70  |.....(2g.n^.KQ.p|
+00000060  54 b9 1d 69 79 38 bd fa  7c 6b 58 71 af 72 08 2d  |T..iy8..|kXq.r.-|
+00000070  55 df 24 be 5b 41 0a ef  0e 90 cf d9 62 81        |U.$.[A......b.|
+>>> Flow 4 (server to client)
+00000000  14 03 03 00 01 01 16 03  03 00 28 00 00 00 00 00  |..........(.....|
+00000010  00 00 00 87 2a 3e 09 54  54 c3 58 c0 5b 7b 91 00  |....*>.TT.X.[{..|
+00000020  c4 07 98 9e de 1f f8 04  bb d7 42 04 55 7d 18 a4  |..........B.U}..|
+00000030  41 7c a6 17 03 03 00 25  00 00 00 00 00 00 00 01  |A|.....%........|
+00000040  ab 23 05 51 b4 60 a2 77  01 58 be a6 9f 89 2b b5  |.#.Q.`.w.X....+.|
+00000050  77 6b 19 23 67 f7 89 f1  ef d6 1b f5 e7 15 03 03  |wk.#g...........|
+00000060  00 1a 00 00 00 00 00 00  00 02 8a bf f0 fb 9f 56  |...............V|
+00000070  36 f1 92 49 a9 e5 40 87  f9 87 9e 4d              |6..I..@....M|
diff --git a/third_party/gofrontend/libgo/go/crypto/tls/testdata/Server-TLSv12-RSA-RC4 b/third_party/gofrontend/libgo/go/crypto/tls/testdata/Server-TLSv12-RSA-RC4
index b703a8f..13163d6 100644
--- a/third_party/gofrontend/libgo/go/crypto/tls/testdata/Server-TLSv12-RSA-RC4
+++ b/third_party/gofrontend/libgo/go/crypto/tls/testdata/Server-TLSv12-RSA-RC4
@@ -1,79 +1,73 @@
 >>> Flow 1 (client to server)
-00000000  16 03 01 00 5c 01 00 00  58 03 03 52 cc 57 59 c9  |....\...X..R.WY.|
-00000010  c3 13 fc 18 8a ee c2 0e  88 ff fb 4a 16 f2 eb eb  |...........J....|
-00000020  d4 f8 b3 5b cd bb 25 0e  0b cb 48 00 00 04 00 05  |...[..%...H.....|
-00000030  00 ff 01 00 00 2b 00 0d  00 22 00 20 06 01 06 02  |.....+...". ....|
+00000000  16 03 01 00 5a 01 00 00  56 03 03 8a fe f5 09 70  |....Z...V......p|
+00000010  8e 6b e3 2b 12 ff d1 b2  ae 15 bf 47 0e ca 5c b5  |.k.+.......G..\.|
+00000020  bb 0e ad af e5 a6 7e 36  c5 a4 c3 00 00 04 00 05  |......~6........|
+00000030  00 ff 01 00 00 29 00 0d  00 20 00 1e 06 01 06 02  |.....)... ......|
 00000040  06 03 05 01 05 02 05 03  04 01 04 02 04 03 03 01  |................|
-00000050  03 02 03 03 02 01 02 02  02 03 01 01 00 0f 00 01  |................|
-00000060  01                                                |.|
+00000050  03 02 03 03 02 01 02 02  02 03 00 0f 00 01 01     |...............|
 >>> Flow 2 (server to client)
 00000000  16 03 03 00 31 02 00 00  2d 03 03 00 00 00 00 00  |....1...-.......|
 00000010  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
 00000020  00 00 00 00 00 00 00 00  00 00 00 00 00 05 00 00  |................|
-00000030  05 ff 01 00 01 00 16 03  03 02 be 0b 00 02 ba 00  |................|
-00000040  02 b7 00 02 b4 30 82 02  b0 30 82 02 19 a0 03 02  |.....0...0......|
-00000050  01 02 02 09 00 85 b0 bb  a4 8a 7f b8 ca 30 0d 06  |.............0..|
-00000060  09 2a 86 48 86 f7 0d 01  01 05 05 00 30 45 31 0b  |.*.H........0E1.|
-00000070  30 09 06 03 55 04 06 13  02 41 55 31 13 30 11 06  |0...U....AU1.0..|
-00000080  03 55 04 08 13 0a 53 6f  6d 65 2d 53 74 61 74 65  |.U....Some-State|
-00000090  31 21 30 1f 06 03 55 04  0a 13 18 49 6e 74 65 72  |1!0...U....Inter|
-000000a0  6e 65 74 20 57 69 64 67  69 74 73 20 50 74 79 20  |net Widgits Pty |
-000000b0  4c 74 64 30 1e 17 0d 31  30 30 34 32 34 30 39 30  |Ltd0...100424090|
-000000c0  39 33 38 5a 17 0d 31 31  30 34 32 34 30 39 30 39  |938Z..1104240909|
-000000d0  33 38 5a 30 45 31 0b 30  09 06 03 55 04 06 13 02  |38Z0E1.0...U....|
-000000e0  41 55 31 13 30 11 06 03  55 04 08 13 0a 53 6f 6d  |AU1.0...U....Som|
-000000f0  65 2d 53 74 61 74 65 31  21 30 1f 06 03 55 04 0a  |e-State1!0...U..|
-00000100  13 18 49 6e 74 65 72 6e  65 74 20 57 69 64 67 69  |..Internet Widgi|
-00000110  74 73 20 50 74 79 20 4c  74 64 30 81 9f 30 0d 06  |ts Pty Ltd0..0..|
-00000120  09 2a 86 48 86 f7 0d 01  01 01 05 00 03 81 8d 00  |.*.H............|
-00000130  30 81 89 02 81 81 00 bb  79 d6 f5 17 b5 e5 bf 46  |0.......y......F|
-00000140  10 d0 dc 69 be e6 2b 07  43 5a d0 03 2d 8a 7a 43  |...i..+.CZ..-.zC|
-00000150  85 b7 14 52 e7 a5 65 4c  2c 78 b8 23 8c b5 b4 82  |...R..eL,x.#....|
-00000160  e5 de 1f 95 3b 7e 62 a5  2c a5 33 d6 fe 12 5c 7a  |....;~b.,.3...\z|
-00000170  56 fc f5 06 bf fa 58 7b  26 3f b5 cd 04 d3 d0 c9  |V.....X{&?......|
-00000180  21 96 4a c7 f4 54 9f 5a  bf ef 42 71 00 fe 18 99  |!.J..T.Z..Bq....|
-00000190  07 7f 7e 88 7d 7d f1 04  39 c4 a2 2e db 51 c9 7c  |..~.}}..9....Q.||
-000001a0  e3 c0 4c 3b 32 66 01 cf  af b1 1d b8 71 9a 1d db  |..L;2f......q...|
-000001b0  db 89 6b ae da 2d 79 02  03 01 00 01 a3 81 a7 30  |..k..-y........0|
-000001c0  81 a4 30 1d 06 03 55 1d  0e 04 16 04 14 b1 ad e2  |..0...U.........|
-000001d0  85 5a cf cb 28 db 69 ce  23 69 de d3 26 8e 18 88  |.Z..(.i.#i..&...|
-000001e0  39 30 75 06 03 55 1d 23  04 6e 30 6c 80 14 b1 ad  |90u..U.#.n0l....|
-000001f0  e2 85 5a cf cb 28 db 69  ce 23 69 de d3 26 8e 18  |..Z..(.i.#i..&..|
-00000200  88 39 a1 49 a4 47 30 45  31 0b 30 09 06 03 55 04  |.9.I.G0E1.0...U.|
-00000210  06 13 02 41 55 31 13 30  11 06 03 55 04 08 13 0a  |...AU1.0...U....|
-00000220  53 6f 6d 65 2d 53 74 61  74 65 31 21 30 1f 06 03  |Some-State1!0...|
-00000230  55 04 0a 13 18 49 6e 74  65 72 6e 65 74 20 57 69  |U....Internet Wi|
-00000240  64 67 69 74 73 20 50 74  79 20 4c 74 64 82 09 00  |dgits Pty Ltd...|
-00000250  85 b0 bb a4 8a 7f b8 ca  30 0c 06 03 55 1d 13 04  |........0...U...|
-00000260  05 30 03 01 01 ff 30 0d  06 09 2a 86 48 86 f7 0d  |.0....0...*.H...|
-00000270  01 01 05 05 00 03 81 81  00 08 6c 45 24 c7 6b b1  |..........lE$.k.|
-00000280  59 ab 0c 52 cc f2 b0 14  d7 87 9d 7a 64 75 b5 5a  |Y..R.......zdu.Z|
-00000290  95 66 e4 c5 2b 8e ae 12  66 1f eb 4f 38 b3 6e 60  |.f..+...f..O8.n`|
-000002a0  d3 92 fd f7 41 08 b5 25  13 b1 18 7a 24 fb 30 1d  |....A..%...z$.0.|
-000002b0  ba ed 98 b9 17 ec e7 d7  31 59 db 95 d3 1d 78 ea  |........1Y....x.|
-000002c0  50 56 5c d5 82 5a 2d 5a  5f 33 c4 b6 d8 c9 75 90  |PV\..Z-Z_3....u.|
-000002d0  96 8c 0f 52 98 b5 cd 98  1f 89 20 5f f2 a0 1c a3  |...R...... _....|
-000002e0  1b 96 94 dd a9 fd 57 e9  70 e8 26 6d 71 99 9b 26  |......W.p.&mq..&|
-000002f0  6e 38 50 29 6c 90 a7 bd  d9 16 03 03 00 04 0e 00  |n8P)l...........|
-00000300  00 00                                             |..|
+00000030  05 ff 01 00 01 00 16 03  03 02 71 0b 00 02 6d 00  |..........q...m.|
+00000040  02 6a 00 02 67 30 82 02  63 30 82 01 cc a0 03 02  |.j..g0..c0......|
+00000050  01 02 02 09 00 a2 73 00  0c 81 00 cb f3 30 0d 06  |......s......0..|
+00000060  09 2a 86 48 86 f7 0d 01  01 0b 05 00 30 2b 31 17  |.*.H........0+1.|
+00000070  30 15 06 03 55 04 0a 13  0e 47 6f 6f 67 6c 65 20  |0...U....Google |
+00000080  54 45 53 54 49 4e 47 31  10 30 0e 06 03 55 04 03  |TESTING1.0...U..|
+00000090  13 07 47 6f 20 52 6f 6f  74 30 1e 17 0d 31 35 30  |..Go Root0...150|
+000000a0  31 30 31 30 30 30 30 30  30 5a 17 0d 32 35 30 31  |101000000Z..2501|
+000000b0  30 31 30 30 30 30 30 30  5a 30 26 31 17 30 15 06  |01000000Z0&1.0..|
+000000c0  03 55 04 0a 13 0e 47 6f  6f 67 6c 65 20 54 45 53  |.U....Google TES|
+000000d0  54 49 4e 47 31 0b 30 09  06 03 55 04 03 13 02 47  |TING1.0...U....G|
+000000e0  6f 30 81 9f 30 0d 06 09  2a 86 48 86 f7 0d 01 01  |o0..0...*.H.....|
+000000f0  01 05 00 03 81 8d 00 30  81 89 02 81 81 00 af 87  |.......0........|
+00000100  88 f6 20 1b 95 65 6c 14  ab 44 05 af 3b 45 14 e3  |.. ..el..D..;E..|
+00000110  b7 6d fd 00 63 4d 95 7f  fe 6a 62 35 86 c0 4a f9  |.m..cM...jb5..J.|
+00000120  18 7c f6 aa 25 5e 7a 64  31 66 00 ba f4 8e 92 af  |.|..%^zd1f......|
+00000130  c7 6b d8 76 d4 f3 5f 41  cb 6e 56 15 97 1b 97 c1  |.k.v.._A.nV.....|
+00000140  3c 12 39 21 66 3d 2b 16  d1 bc db 1c c0 a7 da b7  |<.9!f=+.........|
+00000150  ca ad ba da cb d5 21 50  ec de 8d ab d1 6b 81 4b  |......!P.....k.K|
+00000160  89 02 f3 c4 be c1 6c 89  b1 44 84 bd 21 d1 04 7d  |......l..D..!..}|
+00000170  9d 16 4d f9 82 15 f6 ef  fa d6 09 47 f2 fb 02 03  |..M........G....|
+00000180  01 00 01 a3 81 93 30 81  90 30 0e 06 03 55 1d 0f  |......0..0...U..|
+00000190  01 01 ff 04 04 03 02 05  a0 30 1d 06 03 55 1d 25  |.........0...U.%|
+000001a0  04 16 30 14 06 08 2b 06  01 05 05 07 03 01 06 08  |..0...+.........|
+000001b0  2b 06 01 05 05 07 03 02  30 0c 06 03 55 1d 13 01  |+.......0...U...|
+000001c0  01 ff 04 02 30 00 30 19  06 03 55 1d 0e 04 12 04  |....0.0...U.....|
+000001d0  10 12 50 8d 89 6f 1b d1  dc 54 4d 6e cb 69 5e 06  |..P..o...TMn.i^.|
+000001e0  f4 30 1b 06 03 55 1d 23  04 14 30 12 80 10 bf 3d  |.0...U.#..0....=|
+000001f0  b6 a9 66 f2 b8 40 cf ea  b4 03 78 48 1a 41 30 19  |..f..@....xH.A0.|
+00000200  06 03 55 1d 11 04 12 30  10 82 0e 65 78 61 6d 70  |..U....0...examp|
+00000210  6c 65 2e 67 6f 6c 61 6e  67 30 0d 06 09 2a 86 48  |le.golang0...*.H|
+00000220  86 f7 0d 01 01 0b 05 00  03 81 81 00 92 7c af 91  |.............|..|
+00000230  55 12 18 96 59 31 a6 48  40 d5 2d d5 ee bb 02 a0  |U...Y1.H@.-.....|
+00000240  f5 c2 1e 7c 9b b3 30 7d  3c dc 76 da 4f 3d c0 fa  |...|..0}<.v.O=..|
+00000250  ae 2d 33 24 6b 03 7b 1b  67 59 11 21 b5 11 bc 77  |.-3$k.{.gY.!...w|
+00000260  b9 d9 e0 6e a8 2d 2e 35  fa 64 5f 22 3e 63 10 6b  |...n.-.5.d_">c.k|
+00000270  be ff 14 86 6d 0d f0 15  31 a8 14 38 1e 3b 84 87  |....m...1..8.;..|
+00000280  2c cb 98 ed 51 76 b9 b1  4f dd db 9b 84 04 86 40  |,...Qv..O......@|
+00000290  fa 51 dd ba b4 8d eb e3  46 de 46 b9 4f 86 c7 f9  |.Q......F.F.O...|
+000002a0  a4 c2 41 34 ac cc f6 ea  b0 ab 39 18 16 03 03 00  |..A4......9.....|
+000002b0  04 0e 00 00 00                                    |.....|
 >>> Flow 3 (client to server)
-00000000  16 03 03 00 86 10 00 00  82 00 80 35 b3 60 ba 14  |...........5.`..|
-00000010  5f 19 24 a0 24 de 4e 85  a9 64 78 3a 51 24 64 70  |_.$.$.N..dx:Q$dp|
-00000020  88 55 6d c3 11 b8 d3 9f  bc 7a 33 f8 3c 48 93 2f  |.Um......z3.<H./|
-00000030  66 69 11 33 39 37 7a 36  a3 1c ef b0 81 71 7d 25  |fi.397z6.....q}%|
-00000040  35 da 2c 42 e2 ab d3 b7  07 8b 4a 0d 6d 77 bd ae  |5.,B......J.mw..|
-00000050  02 51 7c a5 0d a6 03 4c  3c d0 ce 89 2c 83 6c de  |.Q|....L<...,.l.|
-00000060  40 15 cc 72 c7 95 c8 6d  ee 05 86 da 3e c6 7c d4  |@..r...m....>.|.|
-00000070  44 82 f4 24 03 22 40 00  64 27 53 15 41 8c 01 e9  |D..$."@.d'S.A...|
-00000080  39 32 fa 8e 2d f9 b4 89  34 15 d6 14 03 03 00 01  |92..-...4.......|
-00000090  01 16 03 03 00 24 f5 61  8b 24 bf b4 82 3a cf 49  |.....$.a.$...:.I|
-000000a0  99 a0 b1 1b a7 a7 a3 92  7c 84 85 e0 64 a3 3d bd  |........|...d.=.|
-000000b0  38 98 7d 97 a8 b9 2a 35  a9 09                    |8.}...*5..|
+00000000  16 03 03 00 86 10 00 00  82 00 80 1c f7 2c 18 38  |.............,.8|
+00000010  d9 41 b5 ab b7 35 2b 75  2d 66 ba c8 70 c2 19 1c  |.A...5+u-f..p...|
+00000020  f2 6d d9 a9 a8 40 8e b5  2c 75 99 06 a5 25 be 0d  |.m...@..,u...%..|
+00000030  b4 b0 9b aa fc 6b 12 a5  b3 e7 02 60 aa 25 e9 7f  |.....k.....`.%..|
+00000040  6b f5 c4 7a 1d 16 a5 d1  76 cc d5 a1 18 68 91 c3  |k..z....v....h..|
+00000050  57 b8 10 f2 b8 81 f3 1b  74 ef 6c 37 3e 81 41 09  |W.......t.l7>.A.|
+00000060  2a c5 15 e6 cc bb 74 4c  01 7a b9 82 5c e2 7f b7  |*.....tL.z..\...|
+00000070  ac 2d 76 30 18 30 c2 19  8c 5f f2 80 41 89 bb 47  |.-v0.0..._..A..G|
+00000080  28 3d 61 cc 3c 06 a8 76  93 57 71 14 03 03 00 01  |(=a.<..v.Wq.....|
+00000090  01 16 03 03 00 24 46 34  1f cc eb 53 c7 d2 04 28  |.....$F4...S...(|
+000000a0  b6 3d 3f 39 06 70 56 b7  db eb 53 9c 66 c3 45 9f  |.=?9.pV...S.f.E.|
+000000b0  69 ca 58 8f e7 ba a7 e6  5a 97                    |i.X.....Z.|
 >>> Flow 4 (server to client)
-00000000  14 03 03 00 01 01 16 03  03 00 24 c9 0b 84 e6 39  |..........$....9|
-00000010  f2 e0 f3 ac 9f 0f 17 92  5f 6d de 94 18 c4 60 d9  |........_m....`.|
-00000020  66 c3 0d 1a ae c2 8f 46  8f 7f f0 58 0e 4a 9b 17  |f......F...X.J..|
-00000030  03 03 00 21 8b 73 a1 6a  7e d9 7e 4f 1d cc b2 7d  |...!.s.j~.~O...}|
-00000040  3c 83 3f 52 f8 08 77 01  4c 65 11 6d 50 25 9a cc  |<.?R..w.Le.mP%..|
-00000050  e3 54 27 72 59 15 03 03  00 16 3d c8 ab 14 51 fa  |.T'rY.....=...Q.|
-00000060  97 f1 ef 5f b4 4f 44 58  d4 93 3b ae e5 61 1f a3  |..._.ODX..;..a..|
+00000000  14 03 03 00 01 01 16 03  03 00 24 78 c3 02 89 60  |..........$x...`|
+00000010  e7 72 9f 51 87 14 ca 2e  0d 79 98 eb 1e 39 62 f9  |.r.Q.....y...9b.|
+00000020  fc a5 c9 2c f8 0c 04 16  60 70 90 b7 31 f8 30 17  |...,....`p..1.0.|
+00000030  03 03 00 21 6a b7 24 73  a7 0d 17 04 d7 54 a8 ea  |...!j.$s.....T..|
+00000040  28 4e f2 0a ef 87 d5 a9  b8 84 81 46 8e 97 d1 ae  |(N.........F....|
+00000050  3c cc b1 6b 72 15 03 03  00 16 1a bb 2f df ae 3e  |<..kr......./..>|
+00000060  a7 89 69 3e 35 f2 f6 cd  35 60 29 3a 6f be 32 0d  |..i>5...5`):o.2.|
diff --git a/third_party/gofrontend/libgo/go/crypto/tls/testdata/Server-TLSv12-Resume b/third_party/gofrontend/libgo/go/crypto/tls/testdata/Server-TLSv12-Resume
index c495d4a..8cacd21 100644
--- a/third_party/gofrontend/libgo/go/crypto/tls/testdata/Server-TLSv12-Resume
+++ b/third_party/gofrontend/libgo/go/crypto/tls/testdata/Server-TLSv12-Resume
@@ -1,36 +1,37 @@
 >>> Flow 1 (client to server)
-00000000  16 03 01 00 e8 01 00 00  e4 03 03 52 cc 57 59 c3  |...........R.WY.|
-00000010  8b df 97 05 d8 5f 16 22  b4 b1 e7 cb 7d 2f 9b 58  |....._."....}/.X|
-00000020  a3 f4 d7 2c a4 c1 9d 49  ed 4b ba 20 90 da 90 3e  |...,...I.K. ...>|
-00000030  36 19 7a db 56 43 26 f7  dc 42 57 33 22 ed 9d a4  |6.z.VC&..BW3"...|
-00000040  9d 53 da f8 9d 4e 60 66  71 a0 2e 2e 00 04 00 05  |.S...N`fq.......|
-00000050  00 ff 01 00 00 97 00 23  00 68 00 00 00 00 00 00  |.......#.h......|
-00000060  00 00 00 00 00 00 00 00  00 00 65 ea 4b d1 ef ba  |..........e.K...|
-00000070  06 38 1e e1 88 82 3a cd  03 ac 3b 39 0a e0 19 fd  |.8....:...;9....|
-00000080  af 6c 57 30 df 31 6e f7  92 38 4b 5d 77 90 39 ff  |.lW0.1n..8K]w.9.|
-00000090  32 51 f5 ed 12 d7 b0 7c  4d 6c c5 76 e4 72 48 3e  |2Q.....|Ml.v.rH>|
-000000a0  59 23 fe 0d 15 df f4 ba  ea b9 67 16 23 8f 7d 15  |Y#........g.#.}.|
-000000b0  b6 11 f1 ab d7 d4 cd a3  21 82 92 2a 12 cf 95 f3  |........!..*....|
-000000c0  60 b2 00 0d 00 22 00 20  06 01 06 02 06 03 05 01  |`....". ........|
-000000d0  05 02 05 03 04 01 04 02  04 03 03 01 03 02 03 03  |................|
-000000e0  02 01 02 02 02 03 01 01  00 0f 00 01 01           |.............|
+00000000  16 03 01 00 f6 01 00 00  f2 03 03 53 1e 13 2e bd  |...........S....|
+00000010  ad 66 fd 77 1a ad 5f 4d  cb bd 2e ca b5 c2 45 1d  |.f.w.._M......E.|
+00000020  7c 83 9d 62 3e 39 9c ce  78 99 e7 20 b4 06 b0 ec  ||..b>9..x.. ....|
+00000030  cf b7 52 6e 38 10 31 37  b2 e6 58 0f fa e3 b0 cb  |..Rn8.17..X.....|
+00000040  20 a4 d2 4b f3 7d 92 e6  7e 13 37 08 00 04 00 05  | ..K.}..~.7.....|
+00000050  00 ff 01 00 00 a5 00 23  00 78 50 46 ad c1 db a8  |.......#.xPF....|
+00000060  38 86 7b 2b bb fd d0 c3  42 3e 00 00 00 00 00 00  |8.{+....B>......|
+00000070  00 00 00 00 00 00 00 00  00 00 94 6f 2c b5 83 61  |...........o,..a|
+00000080  c4 74 90 94 e5 6c fd 70  64 57 3a 25 78 bf 9f a0  |.t...l.pdW:%x...|
+00000090  7c 51 bc 2a 69 1e b3 fd  71 34 b7 9a ef cb 49 37  ||Q.*i...q4....I7|
+000000a0  f8 5d 5e 7c cf 6d fc 13  c1 52 79 8e ed c3 84 01  |.]^|.m...Ry.....|
+000000b0  33 94 10 65 34 64 5e b4  9c 07 46 5b 9e d7 5e 55  |3..e4d^...F[..^U|
+000000c0  df fd c0 e9 d2 e8 d3 c6  42 18 ef a5 6c be e8 d2  |........B...l...|
+000000d0  49 c6 00 0d 00 20 00 1e  06 01 06 02 06 03 05 01  |I.... ..........|
+000000e0  05 02 05 03 04 01 04 02  04 03 03 01 03 02 03 03  |................|
+000000f0  02 01 02 02 02 03 00 0f  00 01 01                 |...........|
 >>> Flow 2 (server to client)
 00000000  16 03 03 00 51 02 00 00  4d 03 03 00 00 00 00 00  |....Q...M.......|
 00000010  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
-00000020  00 00 00 00 00 00 00 00  00 00 00 20 90 da 90 3e  |........... ...>|
-00000030  36 19 7a db 56 43 26 f7  dc 42 57 33 22 ed 9d a4  |6.z.VC&..BW3"...|
-00000040  9d 53 da f8 9d 4e 60 66  71 a0 2e 2e 00 05 00 00  |.S...N`fq.......|
+00000020  00 00 00 00 00 00 00 00  00 00 00 20 b4 06 b0 ec  |........... ....|
+00000030  cf b7 52 6e 38 10 31 37  b2 e6 58 0f fa e3 b0 cb  |..Rn8.17..X.....|
+00000040  20 a4 d2 4b f3 7d 92 e6  7e 13 37 08 00 05 00 00  | ..K.}..~.7.....|
 00000050  05 ff 01 00 01 00 14 03  03 00 01 01 16 03 03 00  |................|
-00000060  24 11 12 ff 28 10 14 4c  e5 0e ad a7 fa f3 92 fb  |$...(..L........|
-00000070  13 7d ae f2 b2 4a 6b a1  9e 67 cf a8 f7 8c 6f a0  |.}...Jk..g....o.|
-00000080  6c 30 0e 18 55                                    |l0..U|
+00000060  24 24 31 13 8c 45 4f 8a  fc 71 50 94 b0 6f 02 5e  |$$1..EO..qP..o.^|
+00000070  da d3 a3 13 8b c8 53 fb  54 8d ef 90 f7 55 b1 be  |......S.T....U..|
+00000080  37 30 05 e5 5d                                    |70..]|
 >>> Flow 3 (client to server)
-00000000  14 03 03 00 01 01 16 03  03 00 24 0d 46 41 8b 24  |..........$.FA.$|
-00000010  36 01 a9 fd 8b ec fc e6  b1 83 96 df 0d 3e 53 54  |6............>ST|
-00000020  58 b8 43 f2 a6 25 5e 1a  ae 19 9e d2 28 44 92     |X.C..%^.....(D.|
+00000000  14 03 03 00 01 01 16 03  03 00 24 ed dd e4 a5 09  |..........$.....|
+00000010  0d 7c cb e4 90 9c a1 1c  21 f4 13 bd 45 8f f4 d8  |.|......!...E...|
+00000020  7e e2 89 7a 0d f4 75 99  66 8c 05 a3 1a e2 2b     |~..z..u.f.....+|
 >>> Flow 4 (server to client)
-00000000  17 03 03 00 21 c4 fb f6  53 bb 3e 04 cc 0b a0 03  |....!...S.>.....|
-00000010  fa 49 96 da b5 8d b2 f2  e5 d8 f3 5c 27 57 4f 9c  |.I.........\'WO.|
-00000020  30 00 34 fc 52 92 15 03  03 00 16 a3 02 7a 50 d2  |0.4.R........zP.|
-00000030  c6 b3 fc 69 8f e4 94 ae  ab 22 ad 05 1d 15 69 b9  |...i....."....i.|
-00000040  a5                                                |.|
+00000000  17 03 03 00 21 69 fa 9e  98 fb 7a 95 b1 8e e5 74  |....!i....z....t|
+00000010  03 02 d7 3d 69 c4 b8 c9  5b 49 e3 30 32 e3 c5 6a  |...=i...[I.02..j|
+00000020  fa 20 98 bd 01 ed 15 03  03 00 16 c9 b1 20 1f 30  |. ........... .0|
+00000030  c1 2f 15 75 cd 82 45 de  1a 81 cd dc 10 05 1c 45  |./.u..E........E|
+00000040  dc                                                |.|
diff --git a/third_party/gofrontend/libgo/go/crypto/tls/testdata/Server-TLSv12-ResumeDisabled b/third_party/gofrontend/libgo/go/crypto/tls/testdata/Server-TLSv12-ResumeDisabled
index db833f6..912c178 100644
--- a/third_party/gofrontend/libgo/go/crypto/tls/testdata/Server-TLSv12-ResumeDisabled
+++ b/third_party/gofrontend/libgo/go/crypto/tls/testdata/Server-TLSv12-ResumeDisabled
@@ -1,87 +1,83 @@
 >>> Flow 1 (client to server)
-00000000  16 03 01 00 e8 01 00 00  e4 03 03 54 23 54 02 a5  |...........T#T..|
-00000010  10 11 0f 6d e5 2d 2f e8  bb 52 b1 38 3f 65 01 43  |...m.-/..R.8?e.C|
-00000020  36 cc 48 f6 09 22 a1 85  20 28 3c 20 35 8b fe 7a  |6.H..".. (< 5..z|
-00000030  41 3b 59 3a 5d b9 b3 21  f0 62 e9 0d 7b af f5 5d  |A;Y:]..!.b..{..]|
-00000040  fa 65 1a 40 c8 ca cd 74  8c ef d2 fb 00 04 00 05  |.e.@...t........|
-00000050  00 ff 01 00 00 97 00 23  00 68 00 00 00 00 00 00  |.......#.h......|
-00000060  00 00 00 00 00 00 00 00  00 00 65 ea 4b d1 ef ba  |..........e.K...|
-00000070  2d db 0c ba 9a d4 20 76  57 c8 ec dc 2d 77 fb fb  |-..... vW...-w..|
-00000080  3b 93 5f 53 e0 14 4f 90  fb d6 55 57 8c 8d 0d 25  |;._S..O...UW...%|
-00000090  ea 5d 0d f2 91 e5 12 22  12 ec 7b 5f b6 6e fd 07  |.]....."..{_.n..|
-000000a0  59 23 24 fc b1 97 ca ea  56 a5 c2 a0 e4 9e 99 64  |Y#$.....V......d|
-000000b0  f2 64 d0 75 7a 46 63 e3  dc 21 ed 78 56 e9 e1 ab  |.d.uzFc..!.xV...|
-000000c0  66 80 00 0d 00 22 00 20  06 01 06 02 06 03 05 01  |f....". ........|
-000000d0  05 02 05 03 04 01 04 02  04 03 03 01 03 02 03 03  |................|
-000000e0  02 01 02 02 02 03 01 01  00 0f 00 01 01           |.............|
+00000000  16 03 01 00 f6 01 00 00  f2 03 03 aa 0c c2 75 42  |..............uB|
+00000010  62 2a 1d 14 a0 cc a1 e4  a7 19 77 50 80 2b f8 05  |b*........wP.+..|
+00000020  0b fa 60 3a a7 a7 84 d3  e1 68 26 20 68 97 0c ae  |..`:.....h& h...|
+00000030  7b 1d bc 13 14 a8 f6 c1  e1 96 1f 54 18 2c cb 99  |{..........T.,..|
+00000040  17 7d be 45 6a 39 53 c6  50 c7 8c 75 00 04 00 05  |.}.Ej9S.P..u....|
+00000050  00 ff 01 00 00 a5 00 23  00 78 50 46 ad c1 db a8  |.......#.xPF....|
+00000060  38 86 7b 2b bb fd d0 c3  42 3e 00 00 00 00 00 00  |8.{+....B>......|
+00000070  00 00 00 00 00 00 00 00  00 00 94 6f 2c b5 83 61  |...........o,..a|
+00000080  bd 50 da 49 7f 8b 8f 58  57 00 a1 11 0d 4a 9d 8a  |.P.I...XW....J..|
+00000090  39 dd 85 23 c0 eb 9d 1a  45 93 92 e7 af 15 a3 a4  |9..#....E.......|
+000000a0  48 da f9 a4 d8 8e cb 6c  3d 44 77 f9 c4 83 89 85  |H......l=Dw.....|
+000000b0  33 94 c1 c6 20 9a 73 44  83 89 5e 59 ee 05 c6 7e  |3... .sD..^Y...~|
+000000c0  8d e9 7d 7b f8 84 46 b6  7d 43 ec f1 af 1f 0f 35  |..}{..F.}C.....5|
+000000d0  b4 1c 00 0d 00 20 00 1e  06 01 06 02 06 03 05 01  |..... ..........|
+000000e0  05 02 05 03 04 01 04 02  04 03 03 01 03 02 03 03  |................|
+000000f0  02 01 02 02 02 03 00 0f  00 01 01                 |...........|
 >>> Flow 2 (server to client)
 00000000  16 03 03 00 31 02 00 00  2d 03 03 00 00 00 00 00  |....1...-.......|
 00000010  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
 00000020  00 00 00 00 00 00 00 00  00 00 00 00 00 05 00 00  |................|
-00000030  05 ff 01 00 01 00 16 03  03 02 be 0b 00 02 ba 00  |................|
-00000040  02 b7 00 02 b4 30 82 02  b0 30 82 02 19 a0 03 02  |.....0...0......|
-00000050  01 02 02 09 00 85 b0 bb  a4 8a 7f b8 ca 30 0d 06  |.............0..|
-00000060  09 2a 86 48 86 f7 0d 01  01 05 05 00 30 45 31 0b  |.*.H........0E1.|
-00000070  30 09 06 03 55 04 06 13  02 41 55 31 13 30 11 06  |0...U....AU1.0..|
-00000080  03 55 04 08 13 0a 53 6f  6d 65 2d 53 74 61 74 65  |.U....Some-State|
-00000090  31 21 30 1f 06 03 55 04  0a 13 18 49 6e 74 65 72  |1!0...U....Inter|
-000000a0  6e 65 74 20 57 69 64 67  69 74 73 20 50 74 79 20  |net Widgits Pty |
-000000b0  4c 74 64 30 1e 17 0d 31  30 30 34 32 34 30 39 30  |Ltd0...100424090|
-000000c0  39 33 38 5a 17 0d 31 31  30 34 32 34 30 39 30 39  |938Z..1104240909|
-000000d0  33 38 5a 30 45 31 0b 30  09 06 03 55 04 06 13 02  |38Z0E1.0...U....|
-000000e0  41 55 31 13 30 11 06 03  55 04 08 13 0a 53 6f 6d  |AU1.0...U....Som|
-000000f0  65 2d 53 74 61 74 65 31  21 30 1f 06 03 55 04 0a  |e-State1!0...U..|
-00000100  13 18 49 6e 74 65 72 6e  65 74 20 57 69 64 67 69  |..Internet Widgi|
-00000110  74 73 20 50 74 79 20 4c  74 64 30 81 9f 30 0d 06  |ts Pty Ltd0..0..|
-00000120  09 2a 86 48 86 f7 0d 01  01 01 05 00 03 81 8d 00  |.*.H............|
-00000130  30 81 89 02 81 81 00 bb  79 d6 f5 17 b5 e5 bf 46  |0.......y......F|
-00000140  10 d0 dc 69 be e6 2b 07  43 5a d0 03 2d 8a 7a 43  |...i..+.CZ..-.zC|
-00000150  85 b7 14 52 e7 a5 65 4c  2c 78 b8 23 8c b5 b4 82  |...R..eL,x.#....|
-00000160  e5 de 1f 95 3b 7e 62 a5  2c a5 33 d6 fe 12 5c 7a  |....;~b.,.3...\z|
-00000170  56 fc f5 06 bf fa 58 7b  26 3f b5 cd 04 d3 d0 c9  |V.....X{&?......|
-00000180  21 96 4a c7 f4 54 9f 5a  bf ef 42 71 00 fe 18 99  |!.J..T.Z..Bq....|
-00000190  07 7f 7e 88 7d 7d f1 04  39 c4 a2 2e db 51 c9 7c  |..~.}}..9....Q.||
-000001a0  e3 c0 4c 3b 32 66 01 cf  af b1 1d b8 71 9a 1d db  |..L;2f......q...|
-000001b0  db 89 6b ae da 2d 79 02  03 01 00 01 a3 81 a7 30  |..k..-y........0|
-000001c0  81 a4 30 1d 06 03 55 1d  0e 04 16 04 14 b1 ad e2  |..0...U.........|
-000001d0  85 5a cf cb 28 db 69 ce  23 69 de d3 26 8e 18 88  |.Z..(.i.#i..&...|
-000001e0  39 30 75 06 03 55 1d 23  04 6e 30 6c 80 14 b1 ad  |90u..U.#.n0l....|
-000001f0  e2 85 5a cf cb 28 db 69  ce 23 69 de d3 26 8e 18  |..Z..(.i.#i..&..|
-00000200  88 39 a1 49 a4 47 30 45  31 0b 30 09 06 03 55 04  |.9.I.G0E1.0...U.|
-00000210  06 13 02 41 55 31 13 30  11 06 03 55 04 08 13 0a  |...AU1.0...U....|
-00000220  53 6f 6d 65 2d 53 74 61  74 65 31 21 30 1f 06 03  |Some-State1!0...|
-00000230  55 04 0a 13 18 49 6e 74  65 72 6e 65 74 20 57 69  |U....Internet Wi|
-00000240  64 67 69 74 73 20 50 74  79 20 4c 74 64 82 09 00  |dgits Pty Ltd...|
-00000250  85 b0 bb a4 8a 7f b8 ca  30 0c 06 03 55 1d 13 04  |........0...U...|
-00000260  05 30 03 01 01 ff 30 0d  06 09 2a 86 48 86 f7 0d  |.0....0...*.H...|
-00000270  01 01 05 05 00 03 81 81  00 08 6c 45 24 c7 6b b1  |..........lE$.k.|
-00000280  59 ab 0c 52 cc f2 b0 14  d7 87 9d 7a 64 75 b5 5a  |Y..R.......zdu.Z|
-00000290  95 66 e4 c5 2b 8e ae 12  66 1f eb 4f 38 b3 6e 60  |.f..+...f..O8.n`|
-000002a0  d3 92 fd f7 41 08 b5 25  13 b1 18 7a 24 fb 30 1d  |....A..%...z$.0.|
-000002b0  ba ed 98 b9 17 ec e7 d7  31 59 db 95 d3 1d 78 ea  |........1Y....x.|
-000002c0  50 56 5c d5 82 5a 2d 5a  5f 33 c4 b6 d8 c9 75 90  |PV\..Z-Z_3....u.|
-000002d0  96 8c 0f 52 98 b5 cd 98  1f 89 20 5f f2 a0 1c a3  |...R...... _....|
-000002e0  1b 96 94 dd a9 fd 57 e9  70 e8 26 6d 71 99 9b 26  |......W.p.&mq..&|
-000002f0  6e 38 50 29 6c 90 a7 bd  d9 16 03 03 00 04 0e 00  |n8P)l...........|
-00000300  00 00                                             |..|
+00000030  05 ff 01 00 01 00 16 03  03 02 71 0b 00 02 6d 00  |..........q...m.|
+00000040  02 6a 00 02 67 30 82 02  63 30 82 01 cc a0 03 02  |.j..g0..c0......|
+00000050  01 02 02 09 00 a2 73 00  0c 81 00 cb f3 30 0d 06  |......s......0..|
+00000060  09 2a 86 48 86 f7 0d 01  01 0b 05 00 30 2b 31 17  |.*.H........0+1.|
+00000070  30 15 06 03 55 04 0a 13  0e 47 6f 6f 67 6c 65 20  |0...U....Google |
+00000080  54 45 53 54 49 4e 47 31  10 30 0e 06 03 55 04 03  |TESTING1.0...U..|
+00000090  13 07 47 6f 20 52 6f 6f  74 30 1e 17 0d 31 35 30  |..Go Root0...150|
+000000a0  31 30 31 30 30 30 30 30  30 5a 17 0d 32 35 30 31  |101000000Z..2501|
+000000b0  30 31 30 30 30 30 30 30  5a 30 26 31 17 30 15 06  |01000000Z0&1.0..|
+000000c0  03 55 04 0a 13 0e 47 6f  6f 67 6c 65 20 54 45 53  |.U....Google TES|
+000000d0  54 49 4e 47 31 0b 30 09  06 03 55 04 03 13 02 47  |TING1.0...U....G|
+000000e0  6f 30 81 9f 30 0d 06 09  2a 86 48 86 f7 0d 01 01  |o0..0...*.H.....|
+000000f0  01 05 00 03 81 8d 00 30  81 89 02 81 81 00 af 87  |.......0........|
+00000100  88 f6 20 1b 95 65 6c 14  ab 44 05 af 3b 45 14 e3  |.. ..el..D..;E..|
+00000110  b7 6d fd 00 63 4d 95 7f  fe 6a 62 35 86 c0 4a f9  |.m..cM...jb5..J.|
+00000120  18 7c f6 aa 25 5e 7a 64  31 66 00 ba f4 8e 92 af  |.|..%^zd1f......|
+00000130  c7 6b d8 76 d4 f3 5f 41  cb 6e 56 15 97 1b 97 c1  |.k.v.._A.nV.....|
+00000140  3c 12 39 21 66 3d 2b 16  d1 bc db 1c c0 a7 da b7  |<.9!f=+.........|
+00000150  ca ad ba da cb d5 21 50  ec de 8d ab d1 6b 81 4b  |......!P.....k.K|
+00000160  89 02 f3 c4 be c1 6c 89  b1 44 84 bd 21 d1 04 7d  |......l..D..!..}|
+00000170  9d 16 4d f9 82 15 f6 ef  fa d6 09 47 f2 fb 02 03  |..M........G....|
+00000180  01 00 01 a3 81 93 30 81  90 30 0e 06 03 55 1d 0f  |......0..0...U..|
+00000190  01 01 ff 04 04 03 02 05  a0 30 1d 06 03 55 1d 25  |.........0...U.%|
+000001a0  04 16 30 14 06 08 2b 06  01 05 05 07 03 01 06 08  |..0...+.........|
+000001b0  2b 06 01 05 05 07 03 02  30 0c 06 03 55 1d 13 01  |+.......0...U...|
+000001c0  01 ff 04 02 30 00 30 19  06 03 55 1d 0e 04 12 04  |....0.0...U.....|
+000001d0  10 12 50 8d 89 6f 1b d1  dc 54 4d 6e cb 69 5e 06  |..P..o...TMn.i^.|
+000001e0  f4 30 1b 06 03 55 1d 23  04 14 30 12 80 10 bf 3d  |.0...U.#..0....=|
+000001f0  b6 a9 66 f2 b8 40 cf ea  b4 03 78 48 1a 41 30 19  |..f..@....xH.A0.|
+00000200  06 03 55 1d 11 04 12 30  10 82 0e 65 78 61 6d 70  |..U....0...examp|
+00000210  6c 65 2e 67 6f 6c 61 6e  67 30 0d 06 09 2a 86 48  |le.golang0...*.H|
+00000220  86 f7 0d 01 01 0b 05 00  03 81 81 00 92 7c af 91  |.............|..|
+00000230  55 12 18 96 59 31 a6 48  40 d5 2d d5 ee bb 02 a0  |U...Y1.H@.-.....|
+00000240  f5 c2 1e 7c 9b b3 30 7d  3c dc 76 da 4f 3d c0 fa  |...|..0}<.v.O=..|
+00000250  ae 2d 33 24 6b 03 7b 1b  67 59 11 21 b5 11 bc 77  |.-3$k.{.gY.!...w|
+00000260  b9 d9 e0 6e a8 2d 2e 35  fa 64 5f 22 3e 63 10 6b  |...n.-.5.d_">c.k|
+00000270  be ff 14 86 6d 0d f0 15  31 a8 14 38 1e 3b 84 87  |....m...1..8.;..|
+00000280  2c cb 98 ed 51 76 b9 b1  4f dd db 9b 84 04 86 40  |,...Qv..O......@|
+00000290  fa 51 dd ba b4 8d eb e3  46 de 46 b9 4f 86 c7 f9  |.Q......F.F.O...|
+000002a0  a4 c2 41 34 ac cc f6 ea  b0 ab 39 18 16 03 03 00  |..A4......9.....|
+000002b0  04 0e 00 00 00                                    |.....|
 >>> Flow 3 (client to server)
-00000000  16 03 03 00 86 10 00 00  82 00 80 ae 02 dd 1f 1a  |................|
-00000010  86 83 f5 2f 82 46 4b 29  58 aa a1 b3 56 8b 4e 40  |.../.FK)X...V.N@|
-00000020  ef 23 65 67 ad 48 e5 e1  fd ae dd bf 68 fd bd a6  |.#eg.H......h...|
-00000030  13 a0 7e 05 ab f7 20 e1  6a 4e d1 37 93 08 1d c9  |..~... .jN.7....|
-00000040  37 e0 b5 34 28 bf 20 45  45 da 0f 7e 51 a7 c6 ae  |7..4(. EE..~Q...|
-00000050  61 6c 07 1b 73 ef da 6e  25 c4 ed be e3 3f da ae  |al..s..n%....?..|
-00000060  cd 3c 17 9c 2e ee fb 47  9d b3 a1 b2 c3 5d e0 83  |.<.....G.....]..|
-00000070  74 20 37 2d 72 d6 d0 4d  58 0e 26 1c 50 22 95 08  |t 7-r..MX.&.P"..|
-00000080  7d e0 5f 86 99 9e 2c 2e  a7 a0 7f 14 03 03 00 01  |}._...,.........|
-00000090  01 16 03 03 00 24 a2 ab  41 25 a5 cf 04 18 1d 98  |.....$..A%......|
-000000a0  88 6c 59 21 86 33 54 f4  35 b4 21 6e a5 29 d5 6e  |.lY!.3T.5.!n.).n|
-000000b0  3d 08 72 b0 af 46 b5 8f  6b 86                    |=.r..F..k.|
+00000000  16 03 03 00 86 10 00 00  82 00 80 ac 10 32 61 b0  |.............2a.|
+00000010  03 e3 1e 2f 89 91 5f d6  4c e0 82 a7 82 41 67 d3  |.../.._.L....Ag.|
+00000020  5f b3 68 2d c0 d1 6f 03  7b 79 94 cc bb 35 6c 8a  |_.h-..o.{y...5l.|
+00000030  bf 1c 83 ff 88 91 5c 04  64 cc a0 df 0b 08 8c 0f  |......\.d.......|
+00000040  72 13 17 9f 27 14 8d 9a  af 17 70 41 44 9f 89 8c  |r...'.....pAD...|
+00000050  fa e4 66 33 4d bd 2f 93  2a 1e 85 a1 af 9e 27 12  |..f3M./.*.....'.|
+00000060  59 a4 13 67 56 85 c2 86  47 f8 c5 49 8f a4 c2 6e  |Y..gV...G..I...n|
+00000070  04 78 0f 11 2b fb 7e 34  b8 eb 25 93 71 ab 9f f5  |.x..+.~4..%.q...|
+00000080  93 df 2b c3 1e 9e 6a 9e  e3 57 aa 14 03 03 00 01  |..+...j..W......|
+00000090  01 16 03 03 00 24 e0 13  15 10 4c db f3 b6 de d2  |.....$....L.....|
+000000a0  68 02 f5 ea 1f 8e 58 70  4a 5a 78 d9 66 c5 74 77  |h.....XpJZx.f.tw|
+000000b0  a0 3a ec d8 b7 42 e3 a5  d4 62                    |.:...B...b|
 >>> Flow 4 (server to client)
-00000000  14 03 03 00 01 01 16 03  03 00 24 59 20 4d c2 17  |..........$Y M..|
-00000010  8b 3c 9b 33 d9 f9 ef fb  80 18 1f 67 a7 58 12 89  |.<.3.......g.X..|
-00000020  4e 73 0f 2d 7b e6 c4 a6  79 73 01 da 22 e8 54 17  |Ns.-{...ys..".T.|
-00000030  03 03 00 21 36 ca 64 0f  4a 12 a5 50 3d 97 bb 39  |...!6.d.J..P=..9|
-00000040  02 fc ed d1 82 6a 9a 2e  21 79 f6 e1 b3 cc 32 db  |.....j..!y....2.|
-00000050  0f 5d b3 fb a5 15 03 03  00 16 51 f4 be 57 7a df  |.]........Q..Wz.|
-00000060  f1 f2 bd b5 51 5e 45 80  be 0b 9a 0c d1 19 3c 79  |....Q^E.......<y|
+00000000  14 03 03 00 01 01 16 03  03 00 24 e9 c1 1f 5b e6  |..........$...[.|
+00000010  c1 d5 8a 14 eb c6 41 c1  77 6d 59 83 b6 95 34 f9  |......A.wmY...4.|
+00000020  7b a1 c9 9d 58 a5 b2 1b  33 6e 04 ab e0 03 61 17  |{...X...3n....a.|
+00000030  03 03 00 21 67 8b 55 43  d7 a7 05 c9 1f a0 d3 65  |...!g.UC.......e|
+00000040  30 36 07 8f d8 52 7e 40  79 31 2e 1c 1a c2 a6 fe  |06...R~@y1......|
+00000050  e0 39 4d a0 5d 15 03 03  00 16 b8 94 fb 17 e5 1d  |.9M.]...........|
+00000060  2e 28 95 cf 02 85 8e 11  2e 16 b1 53 72 aa a4 94  |.(.........Sr...|
diff --git a/third_party/gofrontend/libgo/go/crypto/tls/testdata/Server-TLSv12-SNI b/third_party/gofrontend/libgo/go/crypto/tls/testdata/Server-TLSv12-SNI
index 61b17a1..aee5742 100644
--- a/third_party/gofrontend/libgo/go/crypto/tls/testdata/Server-TLSv12-SNI
+++ b/third_party/gofrontend/libgo/go/crypto/tls/testdata/Server-TLSv12-SNI
@@ -1,12 +1,12 @@
 >>> Flow 1 (client to server)
-00000000  16 03 01 00 70 01 00 00  6c 03 03 52 cc 57 59 2d  |....p...l..R.WY-|
-00000010  77 aa 75 35 fa ff 2a a2  bf 91 5e e3 7f 38 7d 7a  |w.u5..*...^..8}z|
-00000020  e3 93 d3 e8 8b 09 bb 06  c8 6d 91 00 00 04 00 2f  |.........m...../|
-00000030  00 ff 01 00 00 3f 00 00  00 10 00 0e 00 00 0b 73  |.....?.........s|
-00000040  6e 69 74 65 73 74 2e 63  6f 6d 00 0d 00 22 00 20  |nitest.com...". |
+00000000  16 03 01 00 6e 01 00 00  6a 03 03 be 99 22 5c d2  |....n...j...."\.|
+00000010  02 c7 a6 be f3 33 7a d4  76 1f cf 1e 39 0b 25 7c  |.....3z.v...9.%||
+00000020  32 70 e4 8c 49 a6 87 b9  c1 2f 6d 00 00 04 00 2f  |2p..I..../m..../|
+00000030  00 ff 01 00 00 3d 00 00  00 10 00 0e 00 00 0b 73  |.....=.........s|
+00000040  6e 69 74 65 73 74 2e 63  6f 6d 00 0d 00 20 00 1e  |nitest.com... ..|
 00000050  06 01 06 02 06 03 05 01  05 02 05 03 04 01 04 02  |................|
-00000060  04 03 03 01 03 02 03 03  02 01 02 02 02 03 01 01  |................|
-00000070  00 0f 00 01 01                                    |.....|
+00000060  04 03 03 01 03 02 03 03  02 01 02 02 02 03 00 0f  |................|
+00000070  00 01 01                                          |...|
 >>> Flow 2 (server to client)
 00000000  16 03 03 00 31 02 00 00  2d 03 03 00 00 00 00 00  |....1...-.......|
 00000010  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
@@ -46,31 +46,19 @@
 00000230  2c 65 25 d6 52 b6 e3 18  45 bd cc 16 03 03 00 04  |,e%.R...E.......|
 00000240  0e 00 00 00                                       |....|
 >>> Flow 3 (client to server)
-00000000  16 03 03 00 86 10 00 00  82 00 80 0d f2 bf 75 a9  |..............u.|
-00000010  aa db f3 25 55 d4 20 59  63 54 d1 70 82 f9 61 c5  |...%U. YcT.p..a.|
-00000020  b7 ae 3f 75 71 75 9d c5  01 a1 ed b1 07 66 9f 3f  |..?uqu.......f.?|
-00000030  cf c6 e6 ad 44 03 fd 18  6f 53 24 ce 76 01 bd fe  |....D...oS$.v...|
-00000040  e2 51 f7 df 8a 23 3a 21  c4 00 15 ff d0 e0 ff c8  |.Q...#:!........|
-00000050  8b 89 33 c6 8e e0 ce 97  ef b4 c6 f9 b0 ea 38 89  |..3...........8.|
-00000060  79 98 34 9e f7 bc c6 fd  d2 5d 56 84 5c d2 9a ce  |y.4......]V.\...|
-00000070  ae de 09 bc 24 25 fc 09  0c bc 0e 91 0d 6b 36 ae  |....$%.......k6.|
-00000080  ce 6b cd 14 ec b6 3c fa  d6 df fc 14 03 03 00 01  |.k....<.........|
-00000090  01 16 03 03 00 40 ad 21  13 2b 33 7a 4a 0d fb 0f  |.....@.!.+3zJ...|
-000000a0  eb d2 b6 85 29 1f 59 79  ba 86 53 5c 68 b4 c7 e3  |....).Yy..S\h...|
-000000b0  8a 6c 5c 18 04 4d e4 76  19 30 ba 92 b4 79 8c 64  |.l\..M.v.0...y.d|
-000000c0  00 a0 2e 13 96 45 9f e7  a9 e4 23 9e 9f 89 23 26  |.....E....#...#&|
-000000d0  36 20 82 fc 75 fe                                 |6 ..u.|
+00000000  16 03 03 00 86 10 00 00  82 00 80 6b 03 31 ca a0  |...........k.1..|
+00000010  62 a2 53 11 ce 13 d9 f6  e7 d4 ec 2e c3 0a 38 56  |b.S...........8V|
+00000020  23 22 67 23 c8 8d 16 b4  3c 0b 26 9f 1c 2d 65 13  |#"g#....<.&..-e.|
+00000030  c3 cb 65 69 b0 47 ff 87  e8 02 56 c4 77 8a 40 29  |..ei.G....V.w.@)|
+00000040  82 62 8b 06 61 0a 1c b3  c7 29 b6 aa c9 96 37 18  |.b..a....)....7.|
+00000050  d0 60 66 63 9b 62 4b 30  cc 03 9c 37 05 c6 32 98  |.`fc.bK0...7..2.|
+00000060  cb a0 e2 e4 38 60 d4 93  99 9a fc 03 66 fb b6 ef  |....8`......f...|
+00000070  8a 1e bb ca 13 c5 d9 7a  7c 3b 50 dc d0 ad 00 b5  |.......z|;P.....|
+00000080  2c dc 1a ef c4 5c af d3  4e cd e6 14 03 03 00 01  |,....\..N.......|
+00000090  01 16 03 03 00 40 42 31  83 8a 2c 86 22 c5 df e5  |.....@B1..,."...|
+000000a0  f2 0b f8 0c 2f 1e 82 f4  69 fe 1d bd 4c db f1 80  |..../...i...L...|
+000000b0  68 30 b7 e3 60 76 b3 f1  52 ae d6 e7 b3 cb 4a e0  |h0..`v..R.....J.|
+000000c0  27 0a c1 1a 72 ed 71 ab  0a fc 10 d9 5e 4d fd 10  |'...r.q.....^M..|
+000000d0  04 92 39 78 be 23                                 |..9x.#|
 >>> Flow 4 (server to client)
-00000000  14 03 03 00 01 01 16 03  03 00 40 00 00 00 00 00  |..........@.....|
-00000010  00 00 00 00 00 00 00 00  00 00 00 b7 87 61 10 03  |.............a..|
-00000020  b8 a4 42 d4 8b 49 bc 40  80 70 92 c8 25 b0 c6 7f  |..B..I.@.p..%...|
-00000030  b3 87 76 50 5a 59 b3 3c  d8 3e 23 24 aa 1a f3 36  |..vPZY.<.>#$...6|
-00000040  c9 2c 87 c1 22 d2 94 f8  2c fd ef 17 03 03 00 40  |.,.."...,......@|
-00000050  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
-00000060  e5 7f bd 3e ff 9f d4 1b  91 02 f8 69 6f 70 9d 51  |...>.......iop.Q|
-00000070  a5 ec ef 5b 10 3f 4e 3f  44 e5 9a 39 68 7c 3a b9  |...[.?N?D..9h|:.|
-00000080  69 38 31 ec 9c 45 bf 19  d1 5c 5e 2e 06 00 ca 19  |i81..E...\^.....|
-00000090  15 03 03 00 30 00 00 00  00 00 00 00 00 00 00 00  |....0...........|
-000000a0  00 00 00 00 00 63 5e 79  2c f2 05 dc 2b d7 5b ac  |.....c^y,...+.[.|
-000000b0  9d fc 75 94 03 16 ca 1f  b2 75 58 2d f1 2f f1 1e  |..u......uX-./..|
-000000c0  d2 f6 84 8f 2e                                    |.....|
+00000000  15 03 03 00 02 02 14                              |.......|
diff --git a/third_party/gofrontend/libgo/go/crypto/tls/testdata/Server-TLSv12-SNI-GetCertificate b/third_party/gofrontend/libgo/go/crypto/tls/testdata/Server-TLSv12-SNI-GetCertificate
new file mode 100644
index 0000000..40d3714
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/crypto/tls/testdata/Server-TLSv12-SNI-GetCertificate
@@ -0,0 +1,64 @@
+>>> Flow 1 (client to server)
+00000000  16 03 01 00 6e 01 00 00  6a 03 03 23 de 75 da 8e  |....n...j..#.u..|
+00000010  0a 4b 7b e4 cb 34 14 83  be d1 6a 95 25 86 f8 91  |.K{..4....j.%...|
+00000020  d8 bb ac 82 9e 19 d6 9f  52 26 f6 00 00 04 00 2f  |........R&...../|
+00000030  00 ff 01 00 00 3d 00 00  00 10 00 0e 00 00 0b 73  |.....=.........s|
+00000040  6e 69 74 65 73 74 2e 63  6f 6d 00 0d 00 20 00 1e  |nitest.com... ..|
+00000050  06 01 06 02 06 03 05 01  05 02 05 03 04 01 04 02  |................|
+00000060  04 03 03 01 03 02 03 03  02 01 02 02 02 03 00 0f  |................|
+00000070  00 01 01                                          |...|
+>>> Flow 2 (server to client)
+00000000  16 03 03 00 31 02 00 00  2d 03 03 00 00 00 00 00  |....1...-.......|
+00000010  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
+00000020  00 00 00 00 00 00 00 00  00 00 00 00 00 2f 00 00  |............./..|
+00000030  05 ff 01 00 01 00 16 03  03 02 00 0b 00 01 fc 00  |................|
+00000040  01 f9 00 01 f6 30 82 01  f2 30 82 01 5d a0 03 02  |.....0...0..]...|
+00000050  01 02 02 01 00 30 0b 06  09 2a 86 48 86 f7 0d 01  |.....0...*.H....|
+00000060  01 05 30 28 31 10 30 0e  06 03 55 04 0a 13 07 41  |..0(1.0...U....A|
+00000070  63 6d 65 20 43 6f 31 14  30 12 06 03 55 04 03 13  |cme Co1.0...U...|
+00000080  0b 73 6e 69 74 65 73 74  2e 63 6f 6d 30 1e 17 0d  |.snitest.com0...|
+00000090  31 32 30 34 31 31 31 37  34 30 33 35 5a 17 0d 31  |120411174035Z..1|
+000000a0  33 30 34 31 31 31 37 34  35 33 35 5a 30 28 31 10  |30411174535Z0(1.|
+000000b0  30 0e 06 03 55 04 0a 13  07 41 63 6d 65 20 43 6f  |0...U....Acme Co|
+000000c0  31 14 30 12 06 03 55 04  03 13 0b 73 6e 69 74 65  |1.0...U....snite|
+000000d0  73 74 2e 63 6f 6d 30 81  9d 30 0b 06 09 2a 86 48  |st.com0..0...*.H|
+000000e0  86 f7 0d 01 01 01 03 81  8d 00 30 81 89 02 81 81  |..........0.....|
+000000f0  00 bb 79 d6 f5 17 b5 e5  bf 46 10 d0 dc 69 be e6  |..y......F...i..|
+00000100  2b 07 43 5a d0 03 2d 8a  7a 43 85 b7 14 52 e7 a5  |+.CZ..-.zC...R..|
+00000110  65 4c 2c 78 b8 23 8c b5  b4 82 e5 de 1f 95 3b 7e  |eL,x.#........;~|
+00000120  62 a5 2c a5 33 d6 fe 12  5c 7a 56 fc f5 06 bf fa  |b.,.3...\zV.....|
+00000130  58 7b 26 3f b5 cd 04 d3  d0 c9 21 96 4a c7 f4 54  |X{&?......!.J..T|
+00000140  9f 5a bf ef 42 71 00 fe  18 99 07 7f 7e 88 7d 7d  |.Z..Bq......~.}}|
+00000150  f1 04 39 c4 a2 2e db 51  c9 7c e3 c0 4c 3b 32 66  |..9....Q.|..L;2f|
+00000160  01 cf af b1 1d b8 71 9a  1d db db 89 6b ae da 2d  |......q.....k..-|
+00000170  79 02 03 01 00 01 a3 32  30 30 30 0e 06 03 55 1d  |y......2000...U.|
+00000180  0f 01 01 ff 04 04 03 02  00 a0 30 0d 06 03 55 1d  |..........0...U.|
+00000190  0e 04 06 04 04 01 02 03  04 30 0f 06 03 55 1d 23  |.........0...U.#|
+000001a0  04 08 30 06 80 04 01 02  03 04 30 0b 06 09 2a 86  |..0.......0...*.|
+000001b0  48 86 f7 0d 01 01 05 03  81 81 00 89 c6 45 5f 1c  |H............E_.|
+000001c0  1f 5e f8 eb 1a b1 74 ee  24 39 05 9f 5c 42 59 bb  |.^....t.$9..\BY.|
+000001d0  1a 8d 86 cd b1 d0 56 f5  6a 71 7d a4 0e 95 ab 90  |......V.jq}.....|
+000001e0  f5 9e 8d ea f6 27 c1 57  99 50 94 db 08 02 26 6e  |.....'.W.P....&n|
+000001f0  b3 4f c6 84 2d ea 8a 4b  68 d9 c1 38 91 03 ab 84  |.O..-..Kh..8....|
+00000200  fb 9e 1f 85 d9 b5 d2 3f  f2 31 2c 86 70 fb b5 40  |.......?.1,.p..@|
+00000210  14 82 45 a4 eb af e2 64  d9 0c 8a 4c f4 f8 5b 0f  |..E....d...L..[.|
+00000220  ac 12 ac 2f c4 a3 15 4b  ad 52 46 28 68 af 96 c6  |.../...K.RF(h...|
+00000230  2c 65 25 d6 52 b6 e3 18  45 bd cc 16 03 03 00 04  |,e%.R...E.......|
+00000240  0e 00 00 00                                       |....|
+>>> Flow 3 (client to server)
+00000000  16 03 03 00 86 10 00 00  82 00 80 a2 99 61 c5 90  |.............a..|
+00000010  47 1a e7 47 56 51 59 e4  6e ab 82 01 18 78 ee 95  |G..GVQY.n....x..|
+00000020  b8 e2 c7 c7 f9 64 98 dd  84 8d 96 d9 2d 08 62 1e  |.....d......-.b.|
+00000030  4f 29 83 b6 93 68 77 7a  14 1b f0 b3 1a 67 7b 7a  |O)...hwz.....g{z|
+00000040  f9 54 f3 7e 6d eb b6 7a  c9 37 70 6a 83 68 f2 15  |.T.~m..z.7pj.h..|
+00000050  81 07 30 6e b8 fa 19 0e  46 dc d6 9a 4a 8e 8d f1  |..0n....F...J...|
+00000060  05 78 60 75 d4 00 d9 1e  11 5f 16 f7 bc 9f e8 8a  |.x`u....._......|
+00000070  c4 3e bd d9 1a b8 67 50  00 be 5f 43 ee 07 ad be  |.>....gP.._C....|
+00000080  f5 85 67 fc 8f c6 87 47  6d 6e b2 14 03 03 00 01  |..g....Gmn......|
+00000090  01 16 03 03 00 40 91 7d  7b 05 99 48 05 70 a9 67  |.....@.}{..H.p.g|
+000000a0  e9 7a 0a c3 6b bf b0 ad  68 65 17 fb 18 bf 8d bd  |.z..k...he......|
+000000b0  e1 4b 12 bf ea 82 9d a6  1e 3a c8 77 65 32 bd 5e  |.K.......:.we2.^|
+000000c0  c4 46 da e7 e1 ac 09 fe  4a ac bc 57 6a 17 7d dc  |.F......J..Wj.}.|
+000000d0  fe 9c d0 d0 6e fc                                 |....n.|
+>>> Flow 4 (server to client)
+00000000  15 03 03 00 02 02 14                              |.......|
diff --git a/third_party/gofrontend/libgo/go/crypto/tls/testdata/Server-TLSv12-SNI-GetCertificateNotFound b/third_party/gofrontend/libgo/go/crypto/tls/testdata/Server-TLSv12-SNI-GetCertificateNotFound
new file mode 100644
index 0000000..904f69e
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/crypto/tls/testdata/Server-TLSv12-SNI-GetCertificateNotFound
@@ -0,0 +1,64 @@
+>>> Flow 1 (client to server)
+00000000  16 03 01 00 6e 01 00 00  6a 03 03 27 db e3 e8 f4  |....n...j..'....|
+00000010  48 1d 45 d5 20 64 97 b2  20 a6 67 94 7a 1e 87 12  |H.E. d.. .g.z...|
+00000020  25 b1 53 94 27 78 ed ae  58 2f 1b 00 00 04 00 2f  |%.S.'x..X/...../|
+00000030  00 ff 01 00 00 3d 00 00  00 10 00 0e 00 00 0b 73  |.....=.........s|
+00000040  6e 69 74 65 73 74 2e 63  6f 6d 00 0d 00 20 00 1e  |nitest.com... ..|
+00000050  06 01 06 02 06 03 05 01  05 02 05 03 04 01 04 02  |................|
+00000060  04 03 03 01 03 02 03 03  02 01 02 02 02 03 00 0f  |................|
+00000070  00 01 01                                          |...|
+>>> Flow 2 (server to client)
+00000000  16 03 03 00 31 02 00 00  2d 03 03 00 00 00 00 00  |....1...-.......|
+00000010  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
+00000020  00 00 00 00 00 00 00 00  00 00 00 00 00 2f 00 00  |............./..|
+00000030  05 ff 01 00 01 00 16 03  03 02 00 0b 00 01 fc 00  |................|
+00000040  01 f9 00 01 f6 30 82 01  f2 30 82 01 5d a0 03 02  |.....0...0..]...|
+00000050  01 02 02 01 00 30 0b 06  09 2a 86 48 86 f7 0d 01  |.....0...*.H....|
+00000060  01 05 30 28 31 10 30 0e  06 03 55 04 0a 13 07 41  |..0(1.0...U....A|
+00000070  63 6d 65 20 43 6f 31 14  30 12 06 03 55 04 03 13  |cme Co1.0...U...|
+00000080  0b 73 6e 69 74 65 73 74  2e 63 6f 6d 30 1e 17 0d  |.snitest.com0...|
+00000090  31 32 30 34 31 31 31 37  34 30 33 35 5a 17 0d 31  |120411174035Z..1|
+000000a0  33 30 34 31 31 31 37 34  35 33 35 5a 30 28 31 10  |30411174535Z0(1.|
+000000b0  30 0e 06 03 55 04 0a 13  07 41 63 6d 65 20 43 6f  |0...U....Acme Co|
+000000c0  31 14 30 12 06 03 55 04  03 13 0b 73 6e 69 74 65  |1.0...U....snite|
+000000d0  73 74 2e 63 6f 6d 30 81  9d 30 0b 06 09 2a 86 48  |st.com0..0...*.H|
+000000e0  86 f7 0d 01 01 01 03 81  8d 00 30 81 89 02 81 81  |..........0.....|
+000000f0  00 bb 79 d6 f5 17 b5 e5  bf 46 10 d0 dc 69 be e6  |..y......F...i..|
+00000100  2b 07 43 5a d0 03 2d 8a  7a 43 85 b7 14 52 e7 a5  |+.CZ..-.zC...R..|
+00000110  65 4c 2c 78 b8 23 8c b5  b4 82 e5 de 1f 95 3b 7e  |eL,x.#........;~|
+00000120  62 a5 2c a5 33 d6 fe 12  5c 7a 56 fc f5 06 bf fa  |b.,.3...\zV.....|
+00000130  58 7b 26 3f b5 cd 04 d3  d0 c9 21 96 4a c7 f4 54  |X{&?......!.J..T|
+00000140  9f 5a bf ef 42 71 00 fe  18 99 07 7f 7e 88 7d 7d  |.Z..Bq......~.}}|
+00000150  f1 04 39 c4 a2 2e db 51  c9 7c e3 c0 4c 3b 32 66  |..9....Q.|..L;2f|
+00000160  01 cf af b1 1d b8 71 9a  1d db db 89 6b ae da 2d  |......q.....k..-|
+00000170  79 02 03 01 00 01 a3 32  30 30 30 0e 06 03 55 1d  |y......2000...U.|
+00000180  0f 01 01 ff 04 04 03 02  00 a0 30 0d 06 03 55 1d  |..........0...U.|
+00000190  0e 04 06 04 04 01 02 03  04 30 0f 06 03 55 1d 23  |.........0...U.#|
+000001a0  04 08 30 06 80 04 01 02  03 04 30 0b 06 09 2a 86  |..0.......0...*.|
+000001b0  48 86 f7 0d 01 01 05 03  81 81 00 89 c6 45 5f 1c  |H............E_.|
+000001c0  1f 5e f8 eb 1a b1 74 ee  24 39 05 9f 5c 42 59 bb  |.^....t.$9..\BY.|
+000001d0  1a 8d 86 cd b1 d0 56 f5  6a 71 7d a4 0e 95 ab 90  |......V.jq}.....|
+000001e0  f5 9e 8d ea f6 27 c1 57  99 50 94 db 08 02 26 6e  |.....'.W.P....&n|
+000001f0  b3 4f c6 84 2d ea 8a 4b  68 d9 c1 38 91 03 ab 84  |.O..-..Kh..8....|
+00000200  fb 9e 1f 85 d9 b5 d2 3f  f2 31 2c 86 70 fb b5 40  |.......?.1,.p..@|
+00000210  14 82 45 a4 eb af e2 64  d9 0c 8a 4c f4 f8 5b 0f  |..E....d...L..[.|
+00000220  ac 12 ac 2f c4 a3 15 4b  ad 52 46 28 68 af 96 c6  |.../...K.RF(h...|
+00000230  2c 65 25 d6 52 b6 e3 18  45 bd cc 16 03 03 00 04  |,e%.R...E.......|
+00000240  0e 00 00 00                                       |....|
+>>> Flow 3 (client to server)
+00000000  16 03 03 00 86 10 00 00  82 00 80 72 23 e9 89 70  |...........r#..p|
+00000010  97 02 08 58 0d 28 96 5b  19 73 dd 4f 6e 4c 11 dd  |...X.(.[.s.OnL..|
+00000020  cb 56 14 f4 8f c8 e5 84  03 f5 7e f0 a4 08 44 8c  |.V........~...D.|
+00000030  22 74 01 5c e4 9d e0 38  53 90 66 e3 df bb 09 a8  |"t.\...8S.f.....|
+00000040  11 97 0a 44 01 d2 70 85  14 a1 9a 2f 02 34 40 6d  |...D..p..../.4@m|
+00000050  66 80 72 9a 97 98 5c 91  0e dc 42 ac c2 90 2f 30  |f.r...\...B.../0|
+00000060  ca 39 25 94 da 6e b6 5f  94 a9 94 66 7f 32 6a bb  |.9%..n._...f.2j.|
+00000070  5d 43 20 c3 74 f7 52 29  1f d5 62 6b a4 a1 8c 25  |]C .t.R)..bk...%|
+00000080  46 69 22 a5 68 54 f4 68  30 e2 52 14 03 03 00 01  |Fi".hT.h0.R.....|
+00000090  01 16 03 03 00 40 51 d2  78 64 e3 59 ee b7 5f 95  |.....@Q.xd.Y.._.|
+000000a0  4c 49 7f 0d 49 3f 55 71  8c 3b 24 e3 81 22 4a d1  |LI..I?Uq.;$.."J.|
+000000b0  ab 84 4e df 02 9d 56 ea  2a 14 71 e1 dc 1d 5c 1d  |..N...V.*.q...\.|
+000000c0  54 ce cb 58 f6 4d e7 73  44 0d 99 95 a5 2d 7c 2f  |T..X.M.sD....-|/|
+000000d0  15 f5 8f fd 97 40                                 |.....@|
+>>> Flow 4 (server to client)
+00000000  15 03 03 00 02 02 14                              |.......|
diff --git a/third_party/gofrontend/libgo/go/crypto/tls/ticket.go b/third_party/gofrontend/libgo/go/crypto/tls/ticket.go
index 0923027..7be50ce 100644
--- a/third_party/gofrontend/libgo/go/crypto/tls/ticket.go
+++ b/third_party/gofrontend/libgo/go/crypto/tls/ticket.go
@@ -22,6 +22,9 @@
 	cipherSuite  uint16
 	masterSecret []byte
 	certificates [][]byte
+	// usedOldKey is true if the ticket from which this session came from
+	// was encrypted with an older key and thus should be refreshed.
+	usedOldKey bool
 }
 
 func (s *sessionState) equal(i interface{}) bool {
@@ -132,20 +135,23 @@
 
 func (c *Conn) encryptTicket(state *sessionState) ([]byte, error) {
 	serialized := state.marshal()
-	encrypted := make([]byte, aes.BlockSize+len(serialized)+sha256.Size)
-	iv := encrypted[:aes.BlockSize]
+	encrypted := make([]byte, ticketKeyNameLen+aes.BlockSize+len(serialized)+sha256.Size)
+	keyName := encrypted[:ticketKeyNameLen]
+	iv := encrypted[ticketKeyNameLen : ticketKeyNameLen+aes.BlockSize]
 	macBytes := encrypted[len(encrypted)-sha256.Size:]
 
 	if _, err := io.ReadFull(c.config.rand(), iv); err != nil {
 		return nil, err
 	}
-	block, err := aes.NewCipher(c.config.SessionTicketKey[:16])
+	key := c.config.ticketKeys()[0]
+	copy(keyName, key.keyName[:])
+	block, err := aes.NewCipher(key.aesKey[:])
 	if err != nil {
 		return nil, errors.New("tls: failed to create cipher while encrypting ticket: " + err.Error())
 	}
-	cipher.NewCTR(block, iv).XORKeyStream(encrypted[aes.BlockSize:], serialized)
+	cipher.NewCTR(block, iv).XORKeyStream(encrypted[ticketKeyNameLen+aes.BlockSize:], serialized)
 
-	mac := hmac.New(sha256.New, c.config.SessionTicketKey[16:32])
+	mac := hmac.New(sha256.New, key.hmacKey[:])
 	mac.Write(encrypted[:len(encrypted)-sha256.Size])
 	mac.Sum(macBytes[:0])
 
@@ -154,14 +160,29 @@
 
 func (c *Conn) decryptTicket(encrypted []byte) (*sessionState, bool) {
 	if c.config.SessionTicketsDisabled ||
-		len(encrypted) < aes.BlockSize+sha256.Size {
+		len(encrypted) < ticketKeyNameLen+aes.BlockSize+sha256.Size {
 		return nil, false
 	}
 
-	iv := encrypted[:aes.BlockSize]
+	keyName := encrypted[:ticketKeyNameLen]
+	iv := encrypted[ticketKeyNameLen : ticketKeyNameLen+aes.BlockSize]
 	macBytes := encrypted[len(encrypted)-sha256.Size:]
 
-	mac := hmac.New(sha256.New, c.config.SessionTicketKey[16:32])
+	keys := c.config.ticketKeys()
+	keyIndex := -1
+	for i, candidateKey := range keys {
+		if bytes.Equal(keyName, candidateKey.keyName[:]) {
+			keyIndex = i
+			break
+		}
+	}
+
+	if keyIndex == -1 {
+		return nil, false
+	}
+	key := &keys[keyIndex]
+
+	mac := hmac.New(sha256.New, key.hmacKey[:])
 	mac.Write(encrypted[:len(encrypted)-sha256.Size])
 	expected := mac.Sum(nil)
 
@@ -169,15 +190,15 @@
 		return nil, false
 	}
 
-	block, err := aes.NewCipher(c.config.SessionTicketKey[:16])
+	block, err := aes.NewCipher(key.aesKey[:])
 	if err != nil {
 		return nil, false
 	}
-	ciphertext := encrypted[aes.BlockSize : len(encrypted)-sha256.Size]
+	ciphertext := encrypted[ticketKeyNameLen+aes.BlockSize : len(encrypted)-sha256.Size]
 	plaintext := ciphertext
 	cipher.NewCTR(block, iv).XORKeyStream(plaintext, ciphertext)
 
-	state := new(sessionState)
+	state := &sessionState{usedOldKey: keyIndex > 0}
 	ok := state.unmarshal(plaintext)
 	return state, ok
 }
diff --git a/third_party/gofrontend/libgo/go/crypto/tls/tls.go b/third_party/gofrontend/libgo/go/crypto/tls/tls.go
index d50e120..0b1c377 100644
--- a/third_party/gofrontend/libgo/go/crypto/tls/tls.go
+++ b/third_party/gofrontend/libgo/go/crypto/tls/tls.go
@@ -167,22 +167,24 @@
 
 // LoadX509KeyPair reads and parses a public/private key pair from a pair of
 // files. The files must contain PEM encoded data.
-func LoadX509KeyPair(certFile, keyFile string) (cert Certificate, err error) {
+func LoadX509KeyPair(certFile, keyFile string) (Certificate, error) {
 	certPEMBlock, err := ioutil.ReadFile(certFile)
 	if err != nil {
-		return
+		return Certificate{}, err
 	}
 	keyPEMBlock, err := ioutil.ReadFile(keyFile)
 	if err != nil {
-		return
+		return Certificate{}, err
 	}
 	return X509KeyPair(certPEMBlock, keyPEMBlock)
 }
 
 // X509KeyPair parses a public/private key pair from a pair of
 // PEM encoded data.
-func X509KeyPair(certPEMBlock, keyPEMBlock []byte) (cert Certificate, err error) {
+func X509KeyPair(certPEMBlock, keyPEMBlock []byte) (Certificate, error) {
+	var cert Certificate
 	var certDERBlock *pem.Block
+	fail := func(err error) (Certificate, error) { return Certificate{}, err }
 	for {
 		certDERBlock, certPEMBlock = pem.Decode(certPEMBlock)
 		if certDERBlock == nil {
@@ -194,62 +196,56 @@
 	}
 
 	if len(cert.Certificate) == 0 {
-		err = errors.New("crypto/tls: failed to parse certificate PEM data")
-		return
+		return fail(errors.New("crypto/tls: failed to parse certificate PEM data"))
 	}
 
 	var keyDERBlock *pem.Block
 	for {
 		keyDERBlock, keyPEMBlock = pem.Decode(keyPEMBlock)
 		if keyDERBlock == nil {
-			err = errors.New("crypto/tls: failed to parse key PEM data")
-			return
+			return fail(errors.New("crypto/tls: failed to parse key PEM data"))
 		}
 		if keyDERBlock.Type == "PRIVATE KEY" || strings.HasSuffix(keyDERBlock.Type, " PRIVATE KEY") {
 			break
 		}
 	}
 
+	var err error
 	cert.PrivateKey, err = parsePrivateKey(keyDERBlock.Bytes)
 	if err != nil {
-		return
+		return fail(err)
 	}
 
 	// We don't need to parse the public key for TLS, but we so do anyway
 	// to check that it looks sane and matches the private key.
 	x509Cert, err := x509.ParseCertificate(cert.Certificate[0])
 	if err != nil {
-		return
+		return fail(err)
 	}
 
 	switch pub := x509Cert.PublicKey.(type) {
 	case *rsa.PublicKey:
 		priv, ok := cert.PrivateKey.(*rsa.PrivateKey)
 		if !ok {
-			err = errors.New("crypto/tls: private key type does not match public key type")
-			return
+			return fail(errors.New("crypto/tls: private key type does not match public key type"))
 		}
 		if pub.N.Cmp(priv.N) != 0 {
-			err = errors.New("crypto/tls: private key does not match public key")
-			return
+			return fail(errors.New("crypto/tls: private key does not match public key"))
 		}
 	case *ecdsa.PublicKey:
 		priv, ok := cert.PrivateKey.(*ecdsa.PrivateKey)
 		if !ok {
-			err = errors.New("crypto/tls: private key type does not match public key type")
-			return
+			return fail(errors.New("crypto/tls: private key type does not match public key type"))
 
 		}
 		if pub.X.Cmp(priv.X) != 0 || pub.Y.Cmp(priv.Y) != 0 {
-			err = errors.New("crypto/tls: private key does not match public key")
-			return
+			return fail(errors.New("crypto/tls: private key does not match public key"))
 		}
 	default:
-		err = errors.New("crypto/tls: unknown public key algorithm")
-		return
+		return fail(errors.New("crypto/tls: unknown public key algorithm"))
 	}
 
-	return
+	return cert, nil
 }
 
 // Attempt to parse the given private key DER block. OpenSSL 0.9.8 generates
diff --git a/third_party/gofrontend/libgo/go/crypto/tls/tls_test.go b/third_party/gofrontend/libgo/go/crypto/tls/tls_test.go
index e82579e..c45c103 100644
--- a/third_party/gofrontend/libgo/go/crypto/tls/tls_test.go
+++ b/third_party/gofrontend/libgo/go/crypto/tls/tls_test.go
@@ -7,6 +7,7 @@
 import (
 	"bytes"
 	"fmt"
+	"internal/testenv"
 	"io"
 	"net"
 	"strings"
@@ -40,7 +41,7 @@
 `
 
 // keyPEM is the same as rsaKeyPEM, but declares itself as just
-// "PRIVATE KEY", not "RSA PRIVATE KEY".  http://golang.org/issue/4477
+// "PRIVATE KEY", not "RSA PRIVATE KEY".  https://golang.org/issue/4477
 var keyPEM = `-----BEGIN PRIVATE KEY-----
 MIIBOwIBAAJBANLJhPHhITqQbPklG3ibCVxwGMRfp/v4XqhfdQHdcVfHap6NQ5Wo
 k/4xIA+ui35/MmNartNuC+BdZ1tMuVCPFZcCAwEAAQJAEJ2N+zsR0Xn8/Q6twa4G
@@ -280,3 +281,54 @@
 		t.Error("client and server channel bindings differ when session resumption is used")
 	}
 }
+
+func TestVerifyHostname(t *testing.T) {
+	testenv.MustHaveExternalNetwork(t)
+
+	c, err := Dial("tcp", "www.google.com:https", nil)
+	if err != nil {
+		t.Fatal(err)
+	}
+	if err := c.VerifyHostname("www.google.com"); err != nil {
+		t.Fatalf("verify www.google.com: %v", err)
+	}
+	if err := c.VerifyHostname("www.yahoo.com"); err == nil {
+		t.Fatalf("verify www.yahoo.com succeeded")
+	}
+
+	c, err = Dial("tcp", "www.google.com:https", &Config{InsecureSkipVerify: true})
+	if err != nil {
+		t.Fatal(err)
+	}
+	if err := c.VerifyHostname("www.google.com"); err == nil {
+		t.Fatalf("verify www.google.com succeeded with InsecureSkipVerify=true")
+	}
+	if err := c.VerifyHostname("www.yahoo.com"); err == nil {
+		t.Fatalf("verify www.google.com succeeded with InsecureSkipVerify=true")
+	}
+}
+
+func TestVerifyHostnameResumed(t *testing.T) {
+	testenv.MustHaveExternalNetwork(t)
+
+	config := &Config{
+		ClientSessionCache: NewLRUClientSessionCache(32),
+	}
+	for i := 0; i < 2; i++ {
+		c, err := Dial("tcp", "www.google.com:https", config)
+		if err != nil {
+			t.Fatalf("Dial #%d: %v", i, err)
+		}
+		cs := c.ConnectionState()
+		if i > 0 && !cs.DidResume {
+			t.Fatalf("Subsequent connection unexpectedly didn't resume")
+		}
+		if cs.VerifiedChains == nil {
+			t.Fatalf("Dial #%d: cs.VerifiedChains == nil", i)
+		}
+		if err := c.VerifyHostname("www.google.com"); err != nil {
+			t.Fatalf("verify www.google.com #%d: %v", i, err)
+		}
+		c.Close()
+	}
+}
diff --git a/third_party/gofrontend/libgo/go/crypto/x509/cert_pool.go b/third_party/gofrontend/libgo/go/crypto/x509/cert_pool.go
index babe94d..2362e84 100644
--- a/third_party/gofrontend/libgo/go/crypto/x509/cert_pool.go
+++ b/third_party/gofrontend/libgo/go/crypto/x509/cert_pool.go
@@ -77,7 +77,7 @@
 }
 
 // AppendCertsFromPEM attempts to parse a series of PEM encoded certificates.
-// It appends any certificates found to s and returns true if any certificates
+// It appends any certificates found to s and reports whether any certificates
 // were successfully parsed.
 //
 // On many Linux systems, /etc/ssl/cert.pem will contain the system wide set
diff --git a/third_party/gofrontend/libgo/go/crypto/x509/pem_decrypt.go b/third_party/gofrontend/libgo/go/crypto/x509/pem_decrypt.go
index 194c81b..49ceadb 100644
--- a/third_party/gofrontend/libgo/go/crypto/x509/pem_decrypt.go
+++ b/third_party/gofrontend/libgo/go/crypto/x509/pem_decrypt.go
@@ -108,7 +108,10 @@
 // encrypt it and returns a slice of decrypted DER encoded bytes. It inspects
 // the DEK-Info header to determine the algorithm used for decryption. If no
 // DEK-Info header is present, an error is returned. If an incorrect password
-// is detected an IncorrectPasswordError is returned.
+// is detected an IncorrectPasswordError is returned. Because of deficiencies
+// in the encrypted-PEM format, it's not always possible to detect an incorrect
+// password. In these cases no error will be returned but the decrypted DER
+// bytes will be random noise.
 func DecryptPEMBlock(b *pem.Block, password []byte) ([]byte, error) {
 	dek, ok := b.Headers["DEK-Info"]
 	if !ok {
@@ -141,6 +144,10 @@
 		return nil, err
 	}
 
+	if len(b.Bytes)%block.BlockSize() != 0 {
+		return nil, errors.New("x509: encrypted PEM data is not a multiple of the block size")
+	}
+
 	data := make([]byte, len(b.Bytes))
 	dec := cipher.NewCBCDecrypter(block, iv)
 	dec.CryptBlocks(data, b.Bytes)
diff --git a/third_party/gofrontend/libgo/go/crypto/x509/pem_decrypt_test.go b/third_party/gofrontend/libgo/go/crypto/x509/pem_decrypt_test.go
index 13e4700..685d5ee 100644
--- a/third_party/gofrontend/libgo/go/crypto/x509/pem_decrypt_test.go
+++ b/third_party/gofrontend/libgo/go/crypto/x509/pem_decrypt_test.go
@@ -9,6 +9,7 @@
 	"crypto/rand"
 	"encoding/base64"
 	"encoding/pem"
+	"strings"
 	"testing"
 )
 
@@ -221,3 +222,26 @@
 jryIst8=`,
 	},
 }
+
+const incompleteBlockPEM = `
+-----BEGIN RSA PRIVATE KEY-----
+Proc-Type: 4,ENCRYPTED
+DEK-Info: AES-128-CBC,74611ABC2571AF11B1BF9B69E62C89E7
+
+6L8yXK2MTQUWBk4ZD6OvCiYp+mXyR1594TQ1K38MxGvDw5pwcDME2Lek8RrR5fd40P2XsL2Z4KKt
+ai+OP1BZUetfK6AW4MiqB2FDyIdOAJ8XeWuZy21Wtsh8wPD6yYOFM/w7WZL8weX3Y0TSeG/T
+-----END RSA PRIVATE KEY-----`
+
+func TestIncompleteBlock(t *testing.T) {
+	// incompleteBlockPEM contains ciphertext that is not a multiple of the
+	// block size. This previously panicked. See #11215.
+	block, _ := pem.Decode([]byte(incompleteBlockPEM))
+	_, err := DecryptPEMBlock(block, []byte("foo"))
+	if err == nil {
+		t.Fatal("Bad PEM data decrypted successfully")
+	}
+	const expectedSubstr = "block size"
+	if e := err.Error(); !strings.Contains(e, expectedSubstr) {
+		t.Fatalf("Expected error containing %q but got: %q", expectedSubstr, e)
+	}
+}
diff --git a/third_party/gofrontend/libgo/go/crypto/x509/pkix/pkix.go b/third_party/gofrontend/libgo/go/crypto/x509/pkix/pkix.go
index 8768b78..5add4e5 100644
--- a/third_party/gofrontend/libgo/go/crypto/x509/pkix/pkix.go
+++ b/third_party/gofrontend/libgo/go/crypto/x509/pkix/pkix.go
@@ -46,14 +46,17 @@
 }
 
 // Name represents an X.509 distinguished name. This only includes the common
-// elements of a DN.  Additional elements in the name are ignored.
+// elements of a DN. When parsing, all elements are stored in Names and
+// non-standard elements can be extracted from there. When marshaling, elements
+// in ExtraNames are appended and override other values with the same OID.
 type Name struct {
 	Country, Organization, OrganizationalUnit []string
 	Locality, Province                        []string
 	StreetAddress, PostalCode                 []string
 	SerialNumber, CommonName                  string
 
-	Names []AttributeTypeAndValue
+	Names      []AttributeTypeAndValue
+	ExtraNames []AttributeTypeAndValue
 }
 
 func (n *Name) FillFromRDNSequence(rdns *RDNSequence) {
@@ -110,8 +113,8 @@
 // and returns the new value. The relativeDistinguishedNameSET contains an
 // attributeTypeAndValue for each of the given values. See RFC 5280, A.1, and
 // search for AttributeTypeAndValue.
-func appendRDNs(in RDNSequence, values []string, oid asn1.ObjectIdentifier) RDNSequence {
-	if len(values) == 0 {
+func (n Name) appendRDNs(in RDNSequence, values []string, oid asn1.ObjectIdentifier) RDNSequence {
+	if len(values) == 0 || oidInAttributeTypeAndValue(oid, n.ExtraNames) {
 		return in
 	}
 
@@ -125,23 +128,37 @@
 }
 
 func (n Name) ToRDNSequence() (ret RDNSequence) {
-	ret = appendRDNs(ret, n.Country, oidCountry)
-	ret = appendRDNs(ret, n.Organization, oidOrganization)
-	ret = appendRDNs(ret, n.OrganizationalUnit, oidOrganizationalUnit)
-	ret = appendRDNs(ret, n.Locality, oidLocality)
-	ret = appendRDNs(ret, n.Province, oidProvince)
-	ret = appendRDNs(ret, n.StreetAddress, oidStreetAddress)
-	ret = appendRDNs(ret, n.PostalCode, oidPostalCode)
+	ret = n.appendRDNs(ret, n.Country, oidCountry)
+	ret = n.appendRDNs(ret, n.Organization, oidOrganization)
+	ret = n.appendRDNs(ret, n.OrganizationalUnit, oidOrganizationalUnit)
+	ret = n.appendRDNs(ret, n.Locality, oidLocality)
+	ret = n.appendRDNs(ret, n.Province, oidProvince)
+	ret = n.appendRDNs(ret, n.StreetAddress, oidStreetAddress)
+	ret = n.appendRDNs(ret, n.PostalCode, oidPostalCode)
 	if len(n.CommonName) > 0 {
-		ret = appendRDNs(ret, []string{n.CommonName}, oidCommonName)
+		ret = n.appendRDNs(ret, []string{n.CommonName}, oidCommonName)
 	}
 	if len(n.SerialNumber) > 0 {
-		ret = appendRDNs(ret, []string{n.SerialNumber}, oidSerialNumber)
+		ret = n.appendRDNs(ret, []string{n.SerialNumber}, oidSerialNumber)
+	}
+	for _, atv := range n.ExtraNames {
+		ret = append(ret, []AttributeTypeAndValue{atv})
 	}
 
 	return ret
 }
 
+// oidInAttributeTypeAndValue returns whether a type with the given OID exists
+// in atv.
+func oidInAttributeTypeAndValue(oid asn1.ObjectIdentifier, atv []AttributeTypeAndValue) bool {
+	for _, a := range atv {
+		if a.Type.Equal(oid) {
+			return true
+		}
+	}
+	return false
+}
+
 // CertificateList represents the ASN.1 structure of the same name. See RFC
 // 5280, section 5.1. Use Certificate.CheckCRLSignature to verify the
 // signature.
@@ -160,7 +177,7 @@
 // 5280, section 5.1.
 type TBSCertificateList struct {
 	Raw                 asn1.RawContent
-	Version             int `asn1:"optional,default:2"`
+	Version             int `asn1:"optional,default:1"`
 	Signature           AlgorithmIdentifier
 	Issuer              RDNSequence
 	ThisUpdate          time.Time
diff --git a/third_party/gofrontend/libgo/go/crypto/x509/root_bsd.go b/third_party/gofrontend/libgo/go/crypto/x509/root_bsd.go
new file mode 100644
index 0000000..9317283
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/crypto/x509/root_bsd.go
@@ -0,0 +1,14 @@
+// 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 dragonfly freebsd netbsd openbsd
+
+package x509
+
+// Possible certificate files; stop after finding one.
+var certFiles = []string{
+	"/usr/local/share/certs/ca-root-nss.crt", // FreeBSD/DragonFly
+	"/etc/ssl/cert.pem",                      // OpenBSD
+	"/etc/openssl/certs/ca-certificates.crt", // NetBSD
+}
diff --git a/third_party/gofrontend/libgo/go/crypto/x509/root_cgo_darwin.go b/third_party/gofrontend/libgo/go/crypto/x509/root_cgo_darwin.go
index bdcc2c1..bf4a5cd 100644
--- a/third_party/gofrontend/libgo/go/crypto/x509/root_cgo_darwin.go
+++ b/third_party/gofrontend/libgo/go/crypto/x509/root_cgo_darwin.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 cgo
+// +build cgo,!arm,!arm64,!ios
 
 package x509
 
diff --git a/third_party/gofrontend/libgo/go/crypto/x509/root_darwin.go b/third_party/gofrontend/libgo/go/crypto/x509/root_darwin.go
index 2a61d36..78de56c 100644
--- a/third_party/gofrontend/libgo/go/crypto/x509/root_darwin.go
+++ b/third_party/gofrontend/libgo/go/crypto/x509/root_darwin.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.
 
+//go:generate go run root_darwin_arm_gen.go -output root_darwin_armx.go
+
 package x509
 
 import "os/exec"
diff --git a/third_party/gofrontend/libgo/go/crypto/x509/root_darwin_arm_gen.go b/third_party/gofrontend/libgo/go/crypto/x509/root_darwin_arm_gen.go
new file mode 100644
index 0000000..5817158
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/crypto/x509/root_darwin_arm_gen.go
@@ -0,0 +1,191 @@
+// 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 ignore
+
+// Generates root_darwin_armx.go.
+//
+// As of iOS 8, there is no API for querying the system trusted X.509 root
+// certificates. We could use SecTrustEvaluate to verify that a trust chain
+// exists for a certificate, but the x509 API requires returning the entire
+// chain.
+//
+// Apple publishes the list of trusted root certificates for iOS on
+// support.apple.com. So we parse the list and extract the certificates from
+// an OS X machine and embed them into the x509 package.
+package main
+
+import (
+	"bytes"
+	"crypto/x509"
+	"encoding/pem"
+	"flag"
+	"fmt"
+	"go/format"
+	"io/ioutil"
+	"log"
+	"math/big"
+	"net/http"
+	"os/exec"
+	"strings"
+)
+
+var output = flag.String("output", "root_darwin_armx.go", "file name to write")
+
+func main() {
+	certs, err := selectCerts()
+	if err != nil {
+		log.Fatal(err)
+	}
+
+	buf := new(bytes.Buffer)
+
+	fmt.Fprintf(buf, "// Created by root_darwin_arm_gen --output %s; DO NOT EDIT\n", *output)
+	fmt.Fprintf(buf, "%s", header)
+
+	fmt.Fprintf(buf, "const systemRootsPEM = `\n")
+	for _, cert := range certs {
+		b := &pem.Block{
+			Type:  "CERTIFICATE",
+			Bytes: cert.Raw,
+		}
+		if err := pem.Encode(buf, b); err != nil {
+			log.Fatal(err)
+		}
+	}
+	fmt.Fprintf(buf, "`")
+
+	source, err := format.Source(buf.Bytes())
+	if err != nil {
+		log.Fatal("source format error:", err)
+	}
+	if err := ioutil.WriteFile(*output, source, 0644); err != nil {
+		log.Fatal(err)
+	}
+}
+
+func selectCerts() ([]*x509.Certificate, error) {
+	ids, err := fetchCertIDs()
+	if err != nil {
+		return nil, err
+	}
+
+	scerts, err := sysCerts()
+	if err != nil {
+		return nil, err
+	}
+
+	var certs []*x509.Certificate
+	for _, id := range ids {
+		sn, ok := big.NewInt(0).SetString(id.serialNumber, 0) // 0x prefix selects hex
+		if !ok {
+			return nil, fmt.Errorf("invalid serial number: %q", id.serialNumber)
+		}
+		ski, ok := big.NewInt(0).SetString(id.subjectKeyID, 0)
+		if !ok {
+			return nil, fmt.Errorf("invalid Subject Key ID: %q", id.subjectKeyID)
+		}
+
+		for _, cert := range scerts {
+			if sn.Cmp(cert.SerialNumber) != 0 {
+				continue
+			}
+			cski := big.NewInt(0).SetBytes(cert.SubjectKeyId)
+			if ski.Cmp(cski) != 0 {
+				continue
+			}
+			certs = append(certs, cert)
+			break
+		}
+	}
+	return certs, nil
+}
+
+func sysCerts() (certs []*x509.Certificate, err error) {
+	cmd := exec.Command("/usr/bin/security", "find-certificate", "-a", "-p", "/System/Library/Keychains/SystemRootCertificates.keychain")
+	data, err := cmd.Output()
+	if err != nil {
+		return nil, err
+	}
+	for len(data) > 0 {
+		var block *pem.Block
+		block, data = pem.Decode(data)
+		if block == nil {
+			break
+		}
+		if block.Type != "CERTIFICATE" || len(block.Headers) != 0 {
+			continue
+		}
+
+		cert, err := x509.ParseCertificate(block.Bytes)
+		if err != nil {
+			continue
+		}
+		certs = append(certs, cert)
+	}
+	return certs, nil
+}
+
+type certID struct {
+	serialNumber string
+	subjectKeyID string
+}
+
+// fetchCertIDs fetches IDs of iOS X509 certificates from apple.com.
+func fetchCertIDs() ([]certID, error) {
+	resp, err := http.Get("https://support.apple.com/en-us/HT204132")
+	if err != nil {
+		return nil, err
+	}
+	defer resp.Body.Close()
+	body, err := ioutil.ReadAll(resp.Body)
+	if err != nil {
+		return nil, err
+	}
+	text := string(body)
+	text = text[strings.Index(text, "<section id=trusted"):]
+	text = text[:strings.Index(text, "</section>")]
+
+	lines := strings.Split(text, "\n")
+	var ids []certID
+	var id certID
+	for i, ln := range lines {
+		if i == len(lines)-1 {
+			break
+		}
+		const sn = "Serial Number:"
+		if ln == sn {
+			id.serialNumber = "0x" + strings.Replace(strings.TrimSpace(lines[i+1]), ":", "", -1)
+			continue
+		}
+		if strings.HasPrefix(ln, sn) {
+			// extract hex value from parentheses.
+			id.serialNumber = ln[strings.Index(ln, "(")+1 : len(ln)-1]
+			continue
+		}
+		if strings.TrimSpace(ln) == "X509v3 Subject Key Identifier:" {
+			id.subjectKeyID = "0x" + strings.Replace(strings.TrimSpace(lines[i+1]), ":", "", -1)
+			ids = append(ids, id)
+			id = certID{}
+		}
+	}
+	return ids, nil
+}
+
+const header = `
+// 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 cgo
+// +build darwin
+// +build arm arm64
+
+package x509
+
+func initSystemRoots() {
+	systemRoots = NewCertPool()
+	systemRoots.AppendCertsFromPEM([]byte(systemRootsPEM))
+}
+`
diff --git a/third_party/gofrontend/libgo/go/crypto/x509/root_darwin_armx.go b/third_party/gofrontend/libgo/go/crypto/x509/root_darwin_armx.go
new file mode 100644
index 0000000..37675b4
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/crypto/x509/root_darwin_armx.go
@@ -0,0 +1,4907 @@
+// Created by root_darwin_arm_gen --output root_darwin_armx.go; DO NOT EDIT
+
+// 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 cgo
+// +build darwin
+// +build arm arm64 ios
+
+package x509
+
+func initSystemRoots() {
+	systemRoots = NewCertPool()
+	systemRoots.AppendCertsFromPEM([]byte(systemRootsPEM))
+}
+
+const systemRootsPEM = `
+-----BEGIN CERTIFICATE-----
+MIIF8DCCA9igAwIBAgIPBuhGJy8fCo/RhFzjafbVMA0GCSqGSIb3DQEBBQUAMDgx
+CzAJBgNVBAYTAkVTMRQwEgYDVQQKDAtJWkVOUEUgUy5BLjETMBEGA1UEAwwKSXpl
+bnBlLmNvbTAeFw0wNzEyMTMxMzA4MjdaFw0zNzEyMTMwODI3MjVaMDgxCzAJBgNV
+BAYTAkVTMRQwEgYDVQQKDAtJWkVOUEUgUy5BLjETMBEGA1UEAwwKSXplbnBlLmNv
+bTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAMnTesoPHqynhugWZWqx
+whtFMnGV2f4QW8yv56V5AY+Jw8ryVXH3d753lPNypCxE2J6SmxQ6oeckkAoKVo7F
+2CaU4dlI4S0+2gpy3aOZFdqBoof0e24md4lYrdbrDLJBenNubdt6eEHpCIgSfocu
+ZhFjbFT7PJ1ywLwu/8K33Q124zrX97RovqL144FuwUZvXY3gTcZUVYkaMzEKsVe5
+o4qYw+w7NMWVQWl+dcI8IMVhulFHoCCQk6GQS/NOfIVFVJrRBSZBsLVNHTO+xAPI
+JXzBcNs79AktVCdIrC/hxKw+yMuSTFM5NyPs0wH54AlETU1kwOENWocivK0bo/4m
+tRXzp/yEGensoYi0RGmEg/OJ0XQGqcwL1sLeJ4VQJsoXuMl6h1YsGgEebL4TrRCs
+tST1OJGh1kva8bvS3ke18byB9llrzxlT6Y0Vy0rLqW9E5RtBz+GGp8rQap+8TI0G
+M1qiheWQNaBiXBZO8OOi+gMatCxxs1gs3nsL2xoP694hHwZ3BgOwye+Z/MC5TwuG
+KP7Suerj2qXDR2kS4Nvw9hmL7Xtw1wLW7YcYKCwEJEx35EiKGsY7mtQPyvp10gFA
+Wo15v4vPS8+qFsGV5K1Mij4XkdSxYuWC5YAEpAN+jb/af6IPl08M0w3719Hlcn4c
+yHf/W5oPt64FRuXxqBbsR6QXAgMBAAGjgfYwgfMwgbAGA1UdEQSBqDCBpYEPaW5m
+b0BpemVucGUuY29tpIGRMIGOMUcwRQYDVQQKDD5JWkVOUEUgUy5BLiAtIENJRiBB
+MDEzMzcyNjAtUk1lcmMuVml0b3JpYS1HYXN0ZWl6IFQxMDU1IEY2MiBTODFDMEEG
+A1UECQw6QXZkYSBkZWwgTWVkaXRlcnJhbmVvIEV0b3JiaWRlYSAxNCAtIDAxMDEw
+IFZpdG9yaWEtR2FzdGVpejAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIB
+BjAdBgNVHQ4EFgQUHRxlDqjyJXu0kc/ksbHmvVV0bAUwDQYJKoZIhvcNAQEFBQAD
+ggIBAMeBRm8hGE+gBe/n1bqXUKJg7aWSFBpSm/nxiEqg3Hh10dUflU7F57dp5iL0
++CmoKom+z892j+Mxc50m0xwbRxYpB2iEitL7sRskPtKYGCwkjq/2e+pEFhsqxPqg
+l+nqbFik73WrAGLRne0TNtsiC7bw0fRue0aHwp28vb5CO7dz0JoqPLRbEhYArxk5
+ja2DUBzIgU+9Ag89njWW7u/kwgN8KRwCfr00J16vU9adF79XbOnQgxCvv11N75B7
+XSus7Op9ACYXzAJcY9cZGKfsK8eKPlgOiofmg59OsjQerFQJTx0CCzl+gQgVuaBp
+E8gyK+OtbBPWg50jLbJtooiGfqgNASYJQNntKE6MkyQP2/EeTXp6WuKlWPHcj1+Z
+ggwuz7LdmMySlD/5CbOlliVbN/UShUHiGUzGigjB3Bh6Dx4/glmimj4/+eAJn/3B
+kUtdyXvWton83x18hqrNA/ILUpLxYm9/h+qrdslsUMIZgq+qHfUgKGgu1fxkN0/P
+pUTEvnK0jHS0bKf68r10OEMr3q/53NjgnZ/cPcqlY0S/kqJPTIAcuxrDmkoEVU3K
+7iYLHL8CxWTTnn7S05EcS6L1HOUXHA0MUqORH5zwIe0ClG+poEnK6EOMxPQ02nwi
+o8ZmPrgbBYhdurz3vOXcFD2nhqi2WVIhA16L4wTtSyoeo09Q
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIEKjCCAxKgAwIBAgIEOGPe+DANBgkqhkiG9w0BAQUFADCBtDEUMBIGA1UEChML
+RW50cnVzdC5uZXQxQDA+BgNVBAsUN3d3dy5lbnRydXN0Lm5ldC9DUFNfMjA0OCBp
+bmNvcnAuIGJ5IHJlZi4gKGxpbWl0cyBsaWFiLikxJTAjBgNVBAsTHChjKSAxOTk5
+IEVudHJ1c3QubmV0IExpbWl0ZWQxMzAxBgNVBAMTKkVudHJ1c3QubmV0IENlcnRp
+ZmljYXRpb24gQXV0aG9yaXR5ICgyMDQ4KTAeFw05OTEyMjQxNzUwNTFaFw0yOTA3
+MjQxNDE1MTJaMIG0MRQwEgYDVQQKEwtFbnRydXN0Lm5ldDFAMD4GA1UECxQ3d3d3
+LmVudHJ1c3QubmV0L0NQU18yMDQ4IGluY29ycC4gYnkgcmVmLiAobGltaXRzIGxp
+YWIuKTElMCMGA1UECxMcKGMpIDE5OTkgRW50cnVzdC5uZXQgTGltaXRlZDEzMDEG
+A1UEAxMqRW50cnVzdC5uZXQgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgKDIwNDgp
+MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEArU1LqRKGsuqjIAcVFmQq
+K0vRvwtKTY7tgHalZ7d4QMBzQshowNtTK91euHaYNZOLGp18EzoOH1u3Hs/lJBQe
+sYGpjX24zGtLA/ECDNyrpUAkAH90lKGdCCmziAv1h3edVc3kw37XamSrhRSGlVuX
+MlBvPci6Zgzj/L24ScF2iUkZ/cCovYmjZy/Gn7xxGWC4LeksyZB2ZnuU4q941mVT
+XTzWnLLPKQP5L6RQstRIzgUyVYr9smRMDuSYB3Xbf9+5CFVghTAp+XtIpGmG4zU/
+HoZdenoVve8AjhUiVBcAkCaTvA5JaJG/+EfTnZVCwQ5N328mz8MYIWJmQ3DW1cAH
+4QIDAQABo0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNV
+HQ4EFgQUVeSB0RGAvtiJuQijMfmhJAkWuXAwDQYJKoZIhvcNAQEFBQADggEBADub
+j1abMOdTmXx6eadNl9cZlZD7Bh/KM3xGY4+WZiT6QBshJ8rmcnPyT/4xmf3IDExo
+U8aAghOY+rat2l098c5u9hURlIIM7j+VrxGrD9cv3h8Dj1csHsm7mhpElesYT6Yf
+zX1XEC+bBAlahLVu2B064dae0Wx5XnkcFMXj0EyTO2U87d89vqbllRrDtRnDvV5b
+u/8j72gZyxKTJ1wDLW8w0B62GqzeWvfRqqgnpv55gcR5mTNXuhKwqeBCbJPKVt7+
+bYQLCIt+jerXmCHG8+c8eS9enNFMFY3h7CI3zJpDC5fcgJCNs2ebb0gIFVbPv/Er
+fF6adulZkMV8gzURZVE=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIFwTCCA6mgAwIBAgIITrIAZwwDXU8wDQYJKoZIhvcNAQEFBQAwSTELMAkGA1UE
+BhMCQ0gxFTATBgNVBAoTDFN3aXNzU2lnbiBBRzEjMCEGA1UEAxMaU3dpc3NTaWdu
+IFBsYXRpbnVtIENBIC0gRzIwHhcNMDYxMDI1MDgzNjAwWhcNMzYxMDI1MDgzNjAw
+WjBJMQswCQYDVQQGEwJDSDEVMBMGA1UEChMMU3dpc3NTaWduIEFHMSMwIQYDVQQD
+ExpTd2lzc1NpZ24gUGxhdGludW0gQ0EgLSBHMjCCAiIwDQYJKoZIhvcNAQEBBQAD
+ggIPADCCAgoCggIBAMrfogLi2vj8Bxax3mCq3pZcZB/HL37PZ/pEQtZ2Y5Wu669y
+IIpFR4ZieIbWIDkm9K6j/SPnpZy1IiEZtzeTIsBQnIJ71NUERFzLtMKfkr4k2Htn
+IuJpX+UFeNSH2XFwMyVTtIc7KZAoNppVRDBopIOXfw0enHb/FZ1glwCNioUD7IC+
+6ixuEFGSzH7VozPY1kneWCqv9hbrS3uQMpe5up1Y8fhXSQQeol0GcN1x2/ndi5ob
+jM89o03Oy3z2u5yg+gnOI2Ky6Q0f4nIoj5+saCB9bzuohTEJfwvH6GXp43gOCWcw
+izSC+13gzJ2BbWLuCB4ELE6b7P6pT1/9aXjvCR+htL/68++QHkwFix7qepF6w9fl
++zC8bBsQWJj3Gl/QKTIDE0ZNYWqFTFJ0LwYfexHihJfGmfNtf9dng34TaNhxKFrY
+zt3oEBSa/m0jh26OWnA81Y0JAKeqvLAxN23IhBQeW71FYyBrS3SMvds6DsHPWhaP
+pZjydomyExI7C3d3rLvlPClKknLKYRorXkzig3R3+jVIeoVNjZpTxN94ypeRSCtF
+KwH3HBqi7Ri6Cr2D+m+8jVeTO9TUps4e8aCxzqv9KyiaTxvXw3LbpMS/XUz13XuW
+ae5ogObnmLo2t/5u7Su9IPhlGdpVCX4l3P5hYnL5fhgC72O00Puv5TtjjGePAgMB
+AAGjgawwgakwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0O
+BBYEFFCvzAeHFUdvOMW0ZdHelarp35zMMB8GA1UdIwQYMBaAFFCvzAeHFUdvOMW0
+ZdHelarp35zMMEYGA1UdIAQ/MD0wOwYJYIV0AVkBAQEBMC4wLAYIKwYBBQUHAgEW
+IGh0dHA6Ly9yZXBvc2l0b3J5LnN3aXNzc2lnbi5jb20vMA0GCSqGSIb3DQEBBQUA
+A4ICAQAIhab1Fgz8RBrBY+D5VUYI/HAcQiiWjrfFwUF1TglxeeVtlspLpYhg0DB0
+uMoI3LQwnkAHFmtllXcBrqS3NQuB2nEVqXQXOHtYyvkv+8Bldo1bAbl93oI9ZLi+
+FHSjClTTLJUYFzX1UWs/j6KWYTl4a0vlpqD4U99REJNi54Av4tHgvI42Rncz7Lj7
+jposiU0xEQ8mngS7twSNC/K5/FqdOxa3L8iYq/6KUFkuozv8KV2LwUvJ4ooTHbG/
+u0IdUt1O2BReEMYxB+9xJ/cbOQncguqLs5WGXv312l0xpuAxtpTmREl0xRbl9x8D
+YSjFyMsSoEJL+WuICI20MhjzdZ/EfwBPBZWcoxcCw7NTm6ogOSkrZvqdr16zktK1
+puEa+S1BaYEUtLS17Yk9zvupnTVCRLEcFHOBzyoBNZox1S2PbYTfgE1X4z/FhHXa
+icYwu+uPyyIIoK6q8QNsOktNCaUOcsZWayFCTiMlFGiudgp8DAdwZPmaL/YFOSbG
+DI8Zf0NebvRbFS/bYV3mZy8/CJT5YLSYMdp08YSTcU1f+2BY0fvEwW2JorsgH51x
+kcsymxM9Pn2SUjWskpSi0xjCfMfqr3YFFt1nJ8J+HAciIfNAChs0B0QTwoRqjt8Z
+Wr9/6x3iGjjRXK9HkmuAtTClyY3YqzGBH9/CZjfTk6mFhnll0g==
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIFuzCCA6OgAwIBAgIIVwoRl0LE48wwDQYJKoZIhvcNAQELBQAwazELMAkGA1UE
+BhMCSVQxDjAMBgNVBAcMBU1pbGFuMSMwIQYDVQQKDBpBY3RhbGlzIFMucC5BLi8w
+MzM1ODUyMDk2NzEnMCUGA1UEAwweQWN0YWxpcyBBdXRoZW50aWNhdGlvbiBSb290
+IENBMB4XDTExMDkyMjExMjIwMloXDTMwMDkyMjExMjIwMlowazELMAkGA1UEBhMC
+SVQxDjAMBgNVBAcMBU1pbGFuMSMwIQYDVQQKDBpBY3RhbGlzIFMucC5BLi8wMzM1
+ODUyMDk2NzEnMCUGA1UEAwweQWN0YWxpcyBBdXRoZW50aWNhdGlvbiBSb290IENB
+MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAp8bEpSmkLO/lGMWwUKNv
+UTufClrJwkg4CsIcoBh/kbWHuUA/3R1oHwiD1S0eiKD4j1aPbZkCkpAW1V8IbInX
+4ay8IMKx4INRimlNAJZaby/ARH6jDuSRzVju3PvHHkVH3Se5CAGfpiEd9UEtL0z9
+KK3giq0itFZljoZUj5NDKd45RnijMCO6zfB9E1fAXdKDa0hMxKufgFpbOr3JpyI/
+gCczWw63igxdBzcIy2zSekciRDXFzMwujt0q7bd9Zg1fYVEiVRvjRuPjPdA1Yprb
+rxTIW6HMiRvhMCb8oJsfgadHHwTrozmSBp+Z07/T6k9QnBn+locePGX2oxgkg4YQ
+51Q+qDp2JE+BIcXjDwL4k5RHILv+1A7TaLndxHqEguNTVHnd25zS8gebLra8Pu2F
+be8lEfKXGkJh90qX6IuxEAf6ZYGyojnP9zz/GPvG8VqLWeICrHuS0E4UT1lF9gxe
+KF+w6D9Fz8+vm2/7hNN3WpVvrJSEnu68wEqPSpP4RCHiMUVhUE4Q2OM1fEwZtN4F
+v6MGn8i1zeQf1xcGDXqVdFUNaBr8EBtiZJ1t4JWgw5QHVw0U5r0F+7if5t+L4sbn
+fpb2U8WANFAoWPASUHEXMLrmeGO89LKtmyuy/uE5jF66CyCU3nuDuP/jVo23Eek7
+jPKxwV2dpAtMK9myGPW1n0sCAwEAAaNjMGEwHQYDVR0OBBYEFFLYiDrIn3hm7Ynz
+ezhwlMkCAjbQMA8GA1UdEwEB/wQFMAMBAf8wHwYDVR0jBBgwFoAUUtiIOsifeGbt
+ifN7OHCUyQICNtAwDgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3DQEBCwUAA4ICAQAL
+e3KHwGCmSUyIWOYdiPcUZEim2FgKDk8TNd81HdTtBjHIgT5q1d07GjLukD0R0i70
+jsNjLiNmsGe+b7bAEzlgqqI0JZN1Ut6nna0Oh4lScWoWPBkdg/iaKWW+9D+a2fDz
+WochcYBNy+A4mz+7+uAwTc+G02UQGRjRlwKxK3JCaKygvU5a2hi/a5iB0P2avl4V
+SM0RFbnAKVy06Ij3Pjaut2L9HmLecHgQHEhb2rykOLpn7VU+Xlff1ANATIGk0k9j
+pwlCCRT8AKnCgHNPLsBA2RF7SOp6AsDT6ygBJlh0wcBzIm2Tlf05fbsq4/aC4yyX
+X04fkZT6/iyj2HYauE2yOE+b+h1IYHkm4vP9qdCa6HCPSXrW5b0KDtst842/6+Ok
+fcvHlXHo2qN8xcL4dJIEG4aspCJTQLas/kx2z/uUMsA1n3Y/buWQbqCmJqK4LL7R
+K4X9p2jIugErsWx0Hbhzlefut8cl8ABMALJ+tguLHPPAUJ4lueAI3jZm/zel0btU
+ZCzJJ7VLkn5l/9Mt4blOvH+kQSGQQXemOR/qnuOf0GZvBeyqdn6/axag67XH/JJU
+LysRJyU3eExRarDzzFhdFPFqSBX/wge2sY0PjlxQRrM9vwGYT7JZVEc+NHt4bVaT
+LnPqZih4zR0Uv6CPLy64Lo7yFIrM6bV8+2ydDKXhlg==
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIDTDCCAjSgAwIBAgIIfE8EORzUmS0wDQYJKoZIhvcNAQEFBQAwRDELMAkGA1UE
+BhMCVVMxFDASBgNVBAoMC0FmZmlybVRydXN0MR8wHQYDVQQDDBZBZmZpcm1UcnVz
+dCBOZXR3b3JraW5nMB4XDTEwMDEyOTE0MDgyNFoXDTMwMTIzMTE0MDgyNFowRDEL
+MAkGA1UEBhMCVVMxFDASBgNVBAoMC0FmZmlybVRydXN0MR8wHQYDVQQDDBZBZmZp
+cm1UcnVzdCBOZXR3b3JraW5nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC
+AQEAtITMMxcua5Rsa2FSoOujz3mUTOWUgJnLVWREZY9nZOIG41w3SfYvm4SEHi3y
+YJ0wTsyEheIszx6e/jarM3c1RNg1lho9Nuh6DtjVR6FqaYvZ/Ls6rnla1fTWcbua
+kCNrmreIdIcMHl+5ni36q1Mr3Lt2PpNMCAiMHqIjHNRqrSK6mQEubWXLviRmVSRL
+QESxG9fhwoXA3hA/Pe24/PHxI1Pcv2WXb9n5QHGNfb2V1M6+oF4nI979ptAmDgAp
+6zxG8D1gvz9Q0twmQVGeFDdCBKNwV6gbh+0t+nvujArjqWaJGctB+d1ENmHP4ndG
+yH329JKBNv3bNPFyfvMMFr20FQIDAQABo0IwQDAdBgNVHQ4EFgQUBx/S55zawm6i
+QLSwelAQUHTEyL0wDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwDQYJ
+KoZIhvcNAQEFBQADggEBAIlXshZ6qML91tmbmzTCnLQyFE2npN/svqe++EPbkTfO
+tDIuUFUaNU52Q3Eg75N3ThVwLofDwR1t3Mu1J9QsVtFSUzpE0nPIxBsFZVpikpzu
+QY0x2+c06lkh1QF612S4ZDnNye2v7UsDSKegmQGA3GWjNq5lWUhPgkvIZfFXHeVZ
+Lgo/bNjR9eUJtGxUAArgFU2HdW23WJZa3W3SAKD0m0i+wzekujbgfIeFlxoVot4u
+olu9rxj5kFDNcFn4J2dHy8egBzp90SxdbBk6ZrV9/ZFvgrG+CJPbFEfxojfHRZ48
+x3evZKiT3/Zpg4Jg8klCNO1aAFSFHBY2kgxc+qatv9s=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIEvTCCA6WgAwIBAgIBADANBgkqhkiG9w0BAQUFADB/MQswCQYDVQQGEwJFVTEn
+MCUGA1UEChMeQUMgQ2FtZXJmaXJtYSBTQSBDSUYgQTgyNzQzMjg3MSMwIQYDVQQL
+ExpodHRwOi8vd3d3LmNoYW1iZXJzaWduLm9yZzEiMCAGA1UEAxMZQ2hhbWJlcnMg
+b2YgQ29tbWVyY2UgUm9vdDAeFw0wMzA5MzAxNjEzNDNaFw0zNzA5MzAxNjEzNDRa
+MH8xCzAJBgNVBAYTAkVVMScwJQYDVQQKEx5BQyBDYW1lcmZpcm1hIFNBIENJRiBB
+ODI3NDMyODcxIzAhBgNVBAsTGmh0dHA6Ly93d3cuY2hhbWJlcnNpZ24ub3JnMSIw
+IAYDVQQDExlDaGFtYmVycyBvZiBDb21tZXJjZSBSb290MIIBIDANBgkqhkiG9w0B
+AQEFAAOCAQ0AMIIBCAKCAQEAtzZV5aVdGDDg2olUkfzIx1L4L1DZ77F1c2VHfRtb
+unXF/KGIJPov7coISjlUxFF6tdpg6jg8gbLL8bvZkSM/SAFwdakFKq0fcfPJVD0d
+BmpAPrMMhe5cG3nCYsS4No41XQEMIwRHNaqbYE6gZj3LJgqcQKH0XZi/caulAGgq
+7YN6D6IUtdQis4CwPAxaUWktWBiP7Zme8a7ileb2R6jWDA+wWFjbw2Y3npuRVDM3
+0pQcakjJyfKl2qUMI/cjDpwyVV5xnIQFUZot/eZOKjRa3spAN2cMVCFVd9oKDMyX
+roDclDZK9D7ONhMeU+SsTjoF7Nuucpw4i9A5O4kKPnf+dQIBA6OCAUQwggFAMBIG
+A1UdEwEB/wQIMAYBAf8CAQwwPAYDVR0fBDUwMzAxoC+gLYYraHR0cDovL2NybC5j
+aGFtYmVyc2lnbi5vcmcvY2hhbWJlcnNyb290LmNybDAdBgNVHQ4EFgQU45T1sU3p
+26EpW1eLTXYGduHRooowDgYDVR0PAQH/BAQDAgEGMBEGCWCGSAGG+EIBAQQEAwIA
+BzAnBgNVHREEIDAegRxjaGFtYmVyc3Jvb3RAY2hhbWJlcnNpZ24ub3JnMCcGA1Ud
+EgQgMB6BHGNoYW1iZXJzcm9vdEBjaGFtYmVyc2lnbi5vcmcwWAYDVR0gBFEwTzBN
+BgsrBgEEAYGHLgoDATA+MDwGCCsGAQUFBwIBFjBodHRwOi8vY3BzLmNoYW1iZXJz
+aWduLm9yZy9jcHMvY2hhbWJlcnNyb290Lmh0bWwwDQYJKoZIhvcNAQEFBQADggEB
+AAxBl8IahsAifJ/7kPMa0QOx7xP5IV8EnNrJpY0nbJaHkb5BkAFyk+cefV/2icZd
+p0AJPaxJRUXcLo0waLIJuvvDL8y6C98/d3tGfToSJI6WjzwFCm/SlCgdbQzALogi
+1djPHRPH8EjX1wWnz8dHnjs8NMiAT9QUu/wNUPf6s+xCX6ndbcj0dc97wXImsQEc
+XCz9ek60AcUFV7nnPKoF2YjpB0ZBzu9Bga5Y34OirsrXdx/nADydb47kMgkdTXg0
+eDQ8lJsm7U9xxhl6vSAiSFr+S30Dt+dYvsYyTnQeaN2oaFuzPu5ifdmA6Ap1erfu
+tGWaIZDgqtCYvDi1czyL+Nw=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIEMjCCAxqgAwIBAgIBATANBgkqhkiG9w0BAQUFADB7MQswCQYDVQQGEwJHQjEb
+MBkGA1UECAwSR3JlYXRlciBNYW5jaGVzdGVyMRAwDgYDVQQHDAdTYWxmb3JkMRow
+GAYDVQQKDBFDb21vZG8gQ0EgTGltaXRlZDEhMB8GA1UEAwwYQUFBIENlcnRpZmlj
+YXRlIFNlcnZpY2VzMB4XDTA0MDEwMTAwMDAwMFoXDTI4MTIzMTIzNTk1OVowezEL
+MAkGA1UEBhMCR0IxGzAZBgNVBAgMEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UE
+BwwHU2FsZm9yZDEaMBgGA1UECgwRQ29tb2RvIENBIExpbWl0ZWQxITAfBgNVBAMM
+GEFBQSBDZXJ0aWZpY2F0ZSBTZXJ2aWNlczCCASIwDQYJKoZIhvcNAQEBBQADggEP
+ADCCAQoCggEBAL5AnfRu4ep2hxxNRUSOvkbIgwadwSr+GB+O5AL686tdUIoWMQua
+BtDFcCLNSS1UY8y2bmhGC1Pqy0wkwLxyTurxFa70VJoSCsN6sjNg4tqJVfMiWPPe
+3M/vg4aijJRPn2jymJBGhCfHdr/jzDUsi14HZGWCwEiwqJH5YZ92IFCokcdmtet4
+YgNW8IoaE+oxox6gmf049vYnMlhvB/VruPsUK6+3qszWY19zjNoFmag4qMsXeDZR
+rOme9Hg6jc8P2ULimAyrL58OAd7vn5lJ8S3frHRNG5i1R8XlKdH5kBjHYpy+g8cm
+ez6KJcfA3Z3mNWgQIJ2P2N7Sw4ScDV7oL8kCAwEAAaOBwDCBvTAdBgNVHQ4EFgQU
+oBEKIz6W8Qfs4q8p74Klf9AwpLQwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQF
+MAMBAf8wewYDVR0fBHQwcjA4oDagNIYyaHR0cDovL2NybC5jb21vZG9jYS5jb20v
+QUFBQ2VydGlmaWNhdGVTZXJ2aWNlcy5jcmwwNqA0oDKGMGh0dHA6Ly9jcmwuY29t
+b2RvLm5ldC9BQUFDZXJ0aWZpY2F0ZVNlcnZpY2VzLmNybDANBgkqhkiG9w0BAQUF
+AAOCAQEACFb8AvCb6P+k+tZ7xkSAzk/ExfYAWMymtrwUSWgEdujm7l3sAg9g1o1Q
+GE8mTgHj5rCl7r+8dFRBv/38ErjHT1r0iWAFf2C3BUrz9vHCv8S5dIa2LX1rzNLz
+Rt0vxuBqw8M0Ayx9lt1awg6nCpnBBYurDC/zXDrPbDdVCYfeU0BsWO/8tqtlbgT2
+G9w84FoVxp7Z8VlIMCFlA2zs6SFz7JsDoeA3raAVGI/6ugLOpyypEBMs1OUIJqsi
+l2D4kF501KKaU73yqWjgom7C12yxow+ev+to51byrvLjKzg6CYG1a4XXvi3tPxq3
+smPi9WIsgtRqAEFQ8TmDn5XpNpaYbg==
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIEHTCCAwWgAwIBAgIQToEtioJl4AsC7j41AkblPTANBgkqhkiG9w0BAQUFADCB
+gTELMAkGA1UEBhMCR0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4G
+A1UEBxMHU2FsZm9yZDEaMBgGA1UEChMRQ09NT0RPIENBIExpbWl0ZWQxJzAlBgNV
+BAMTHkNPTU9ETyBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0wNjEyMDEwMDAw
+MDBaFw0yOTEyMzEyMzU5NTlaMIGBMQswCQYDVQQGEwJHQjEbMBkGA1UECBMSR3Jl
+YXRlciBNYW5jaGVzdGVyMRAwDgYDVQQHEwdTYWxmb3JkMRowGAYDVQQKExFDT01P
+RE8gQ0EgTGltaXRlZDEnMCUGA1UEAxMeQ09NT0RPIENlcnRpZmljYXRpb24gQXV0
+aG9yaXR5MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA0ECLi3LjkRv3
+UcEbVASY06m/weaKXTuH+7uIzg3jLz8GlvCiKVCZrts7oVewdFFxze1CkU1B/qnI
+2GqGd0S7WWaXUF601CxwRM/aN5VCaTwwxHGzUvAhTaHYujl8HJ6jJJ3ygxaYqhZ8
+Q5sVW7euNJH+1GImGEaaP+vB+fGQV+useg2L23IwambV4EajcNxo2f8ESIl33rXp
++2dtQem8Ob0y2WIC8bGoPW43nOIv4tOiJovGuFVDiOEjPqXSJDlqR6sA1KGzqSX+
+DT+nHbrTUcELpNqsOO9VUCQFZUaTNE8tja3G1CEZ0o7KBWFxB3NH5YoZEr0ETc5O
+nKVIrLsm9wIDAQABo4GOMIGLMB0GA1UdDgQWBBQLWOWLxkwVN6RAqTCpIb5HNlpW
+/zAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zBJBgNVHR8EQjBAMD6g
+PKA6hjhodHRwOi8vY3JsLmNvbW9kb2NhLmNvbS9DT01PRE9DZXJ0aWZpY2F0aW9u
+QXV0aG9yaXR5LmNybDANBgkqhkiG9w0BAQUFAAOCAQEAPpiem/Yb6dc5t3iuHXIY
+SdOH5EOC6z/JqvWote9VfCFSZfnVDeFs9D6Mk3ORLgLETgdxb8CPOGEIqB6BCsAv
+IC9Bi5HcSEW88cbeunZrM8gALTFGTO3nnc+IlP8zwFboJIYmuNg4ON8qa90SzMc/
+RxdMosIGlgnW2/4/PEZB31jiVg88O8EckzXZOFKs7sjsLjBOlDW0JB9LeGna8gI4
+zJVSk/BwJVmcIGfE7vmLV2H0knZ9P4SNVbfo5azV8fUZVqZa+5Acr5Pr5RzUZ5dd
+BA6+C4OmF4O5MBKgxTMVBbkN+8cFduPYSo38NBejxiEovjBFMR7HeL5YYTisO+IB
+ZQ==
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIDcDCCAligAwIBAgIBBTANBgkqhkiG9w0BAQUFADBbMQswCQYDVQQGEwJVUzEY
+MBYGA1UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb0QxDDAKBgNVBAsT
+A1BLSTEWMBQGA1UEAxMNRG9EIFJvb3QgQ0EgMjAeFw0wNDEyMTMxNTAwMTBaFw0y
+OTEyMDUxNTAwMTBaMFsxCzAJBgNVBAYTAlVTMRgwFgYDVQQKEw9VLlMuIEdvdmVy
+bm1lbnQxDDAKBgNVBAsTA0RvRDEMMAoGA1UECxMDUEtJMRYwFAYDVQQDEw1Eb0Qg
+Um9vdCBDQSAyMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAwCzB9o07
+rP8/PNZxvrh0IgfscEEV/KtA4weqwcPYn/7aTDq/P8jYKHtLNgHArEUlw9IOCo+F
+GGQQPRoTcCpvjtfcjZOzQQ84Ic2tq8I9KgXTVxE3Dc2MUfmT48xGSSGOFLTNyxQ+
+OM1yMe6rEvJl6jQuVl3/7mN1y226kTT8nvP0LRy+UMRC31mI/2qz+qhsPctWcXEF
+lrufgOWARVlnQbDrw61gpIB1BhecDvRD4JkOG/t/9bPMsoGCsf0ywbi+QaRktWA6
+WlEwjM7eQSwZR1xJEGS5dKmHQa99brrBuKG/ZTE6BGf5tbuOkooAY7ix5ow4X4P/
+UNU7ol1rshDMYwIDAQABoz8wPTAdBgNVHQ4EFgQUSXS7DF66ev4CVO97oMaVxgmA
+cJYwCwYDVR0PBAQDAgGGMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEFBQAD
+ggEBAJiRjT+JyLv1wGlzKTs1rLqzCHY9cAmS6YREIQF9FHYb7lFsHY0VNy17MWn0
+mkS4r0bMNPojywMnGdKDIXUr5+AbmSbchECV6KjSzPZYXGbvP0qXEIIdugqi3VsG
+K52nZE7rLgE1pLQ/E61V5NVzqGmbEfGY8jEeb0DU+HifjpGgb3AEkGaqBivO4XqS
+tX3h4NGW56E6LcyxnR8FRO2HmdNNGnA5wQQM5X7Z8a/XIA7xInolpHOZzD+kByeW
+qKKV7YK5FtOeC4fCwfKI9WLfaN/HvGlR7bFc3FRUKQ8JOZqsA8HbDE2ubwp6Fknx
+v5HSOJTT9pUst2zJQraNypCNhdk=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIDkjCCAnqgAwIBAgIRAIW9S/PY2uNp9pTXX8OlRCMwDQYJKoZIhvcNAQEFBQAw
+PTELMAkGA1UEBhMCRlIxETAPBgNVBAoTCENlcnRwbHVzMRswGQYDVQQDExJDbGFz
+cyAyIFByaW1hcnkgQ0EwHhcNOTkwNzA3MTcwNTAwWhcNMTkwNzA2MjM1OTU5WjA9
+MQswCQYDVQQGEwJGUjERMA8GA1UEChMIQ2VydHBsdXMxGzAZBgNVBAMTEkNsYXNz
+IDIgUHJpbWFyeSBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANxQ
+ltAS+DXSCHh6tlJw/W/uz7kRy1134ezpfgSN1sxvc0NXYKwzCkTsA18cgCSR5aiR
+VhKC9+Ar9NuuYS6JEI1rbLqzAr3VNsVINyPi8Fo3UjMXEuLRYE2+L0ER4/YXJQyL
+kcAbmXuZVg2v7tK8R1fjeUl7NIknJITesezpWE7+Tt9avkGtrAjFGA7v0lPubNCd
+EgETjdyAYveVqUSISnFOYFWe2yMZeVYHDD9jC1yw4r5+FfyUM1hBOHTE4Y+L3yas
+H7WLO7dDWWuwJKZtkIvEcupdM5i3y95ee++U8Rs+yskhwcWYAqqi9lt3m/V+llU0
+HGdpwPFC40es/CgcZlUCAwEAAaOBjDCBiTAPBgNVHRMECDAGAQH/AgEKMAsGA1Ud
+DwQEAwIBBjAdBgNVHQ4EFgQU43Mt38sOKAze3bOkynm4jrvoMIkwEQYJYIZIAYb4
+QgEBBAQDAgEGMDcGA1UdHwQwMC4wLKAqoCiGJmh0dHA6Ly93d3cuY2VydHBsdXMu
+Y29tL0NSTC9jbGFzczIuY3JsMA0GCSqGSIb3DQEBBQUAA4IBAQCnVM+IRBnL39R/
+AN9WM2K191EBkOvDP9GIROkkXe/nFL0gt5o8AP5tn9uQ3Nf0YtaLcF3n5QRIqWh8
+yfFC82x/xXp8HVGIutIKPidd3i1RTtMTZGnkLuPT55sJmabglZvOGtd/vjzOUrMR
+FcEPF80Du5wlFbqidon8BvEY0JNLDnyCt6X09l/+7UCmnYR0ObncHoUW2ikbhiMA
+ybuJfm6AiB4vFLQDJKgybwOaRywwvlbGp0ICcBvqQNi6BQNwB6SW//1IMwrh3KWB
+kJtN3X3n57LNXMhqlfil9o3EXXgIvnsG1knPGTZQIy4I5p4FTUcY1Rbpsda2ENW7
+l7+ijrRU
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIEPjCCAyagAwIBAgIESlOMKDANBgkqhkiG9w0BAQsFADCBvjELMAkGA1UEBhMC
+VVMxFjAUBgNVBAoTDUVudHJ1c3QsIEluYy4xKDAmBgNVBAsTH1NlZSB3d3cuZW50
+cnVzdC5uZXQvbGVnYWwtdGVybXMxOTA3BgNVBAsTMChjKSAyMDA5IEVudHJ1c3Qs
+IEluYy4gLSBmb3IgYXV0aG9yaXplZCB1c2Ugb25seTEyMDAGA1UEAxMpRW50cnVz
+dCBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IC0gRzIwHhcNMDkwNzA3MTcy
+NTU0WhcNMzAxMjA3MTc1NTU0WjCBvjELMAkGA1UEBhMCVVMxFjAUBgNVBAoTDUVu
+dHJ1c3QsIEluYy4xKDAmBgNVBAsTH1NlZSB3d3cuZW50cnVzdC5uZXQvbGVnYWwt
+dGVybXMxOTA3BgNVBAsTMChjKSAyMDA5IEVudHJ1c3QsIEluYy4gLSBmb3IgYXV0
+aG9yaXplZCB1c2Ugb25seTEyMDAGA1UEAxMpRW50cnVzdCBSb290IENlcnRpZmlj
+YXRpb24gQXV0aG9yaXR5IC0gRzIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK
+AoIBAQC6hLZy254Ma+KZ6TABp3bqMriVQRrJ2mFOWHLP/vaCeb9zYQYKpSfYs1/T
+RU4cctZOMvJyig/3gxnQaoCAAEUesMfnmr8SVycco2gvCoe9amsOXmXzHHfV1IWN
+cCG0szLni6LVhjkCsbjSR87kyUnEO6fe+1R9V77w6G7CebI6C1XiUJgWMhNcL3hW
+wcKUs/Ja5CeanyTXxuzQmyWC48zCxEXFjJd6BmsqEZ+pCm5IO2/b1BEZQvePB7/1
+U1+cPvQXLOZprE4yTGJ36rfo5bs0vBmLrpxR57d+tVOxMyLlbc9wPBr64ptntoP0
+jaWvYkxN4FisZDQSA/i2jZRjJKRxAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAP
+BgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBRqciZ60B7vfec7aVHUbI2fkBJmqzAN
+BgkqhkiG9w0BAQsFAAOCAQEAeZ8dlsa2eT8ijYfThwMEYGprmi5ZiXMRrEPR9RP/
+jTkrwPK9T3CMqS/qF8QLVJ7UG5aYMzyorWKiAHarWWluBh1+xLlEjZivEtRh2woZ
+Rkfz6/djwUAFQKXSt/S1mja/qYh2iARVBCuch38aNzx+LaUa2NSJXsq9rD1s2G2v
+1fN2D807iDginWyTmsQ9v4IbZT+mD12q/OWyFcq1rca8PdCE6OoGcrBNOTJ4vz4R
+nAuknZoh8/CbCzB428Hch0P+vGOaysXCHMnHjf87ElgI5rY97HosTvuDls4MPGmH
+VHOkc8KT/1EQrBVUAdj8BbGJoX90g5pJ19xOe4pIb4tF9g==
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIID9jCCAt6gAwIBAgIQZIKe/DcedF38l/+XyLH/QTANBgkqhkiG9w0BAQsFADCB
+lDELMAkGA1UEBhMCVVMxHTAbBgNVBAoTFFN5bWFudGVjIENvcnBvcmF0aW9uMR8w
+HQYDVQQLExZTeW1hbnRlYyBUcnVzdCBOZXR3b3JrMUUwQwYDVQQDEzxTeW1hbnRl
+YyBDbGFzcyAyIFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5
+IC0gRzYwHhcNMTExMDE4MDAwMDAwWhcNMzcxMjAxMjM1OTU5WjCBlDELMAkGA1UE
+BhMCVVMxHTAbBgNVBAoTFFN5bWFudGVjIENvcnBvcmF0aW9uMR8wHQYDVQQLExZT
+eW1hbnRlYyBUcnVzdCBOZXR3b3JrMUUwQwYDVQQDEzxTeW1hbnRlYyBDbGFzcyAy
+IFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IC0gRzYwggEi
+MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDNzOkFyGOFyz9AYxe9GPo15gRn
+V2WYKaRPyVyPDzTS+NqoE2KquB5QZ3iwFkygOakVeq7t0qLA8JA3KRgmXOgNPLZs
+ST/B4NzZS7YUGQum05bh1gnjGSYc+R9lS/kaQxwAg9bQqkmi1NvmYji6UBRDbfkx
++FYW2TgCkc/rbN27OU6Z4TBnRfHU8I3D3/7yOAchfQBeVkSz5GC9kSucq1sEcg+y
+KNlyqwUgQiWpWwNqIBDMMfAr2jUs0Pual07wgksr2F82owstr2MNHSV/oW5cYqGN
+KD6h/Bwg+AEvulWaEbAZ0shQeWsOagXXqgQ2sqPy4V93p3ec5R7c6d9qwWVdAgMB
+AAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQW
+BBSHjCCVyJhK0daABkqQNETfHE2/sDANBgkqhkiG9w0BAQsFAAOCAQEAgY6ypWaW
+tyGltu9vI1pf24HFQqV4wWn99DzX+VxrcHIa/FqXTQCAiIiCisNxDY7FiZss7Y0L
+0nJU9X3UXENX6fOupQIR9nYrgVfdfdp0MP1UR/bgFm6mtApI5ud1Bw8pGTnOefS2
+bMVfmdUfS/rfbSw8DVSAcPCIC4DPxmiiuB1w2XaM/O6lyc+tHc+ZJVdaYkXLFmu9
+Sc2lo4xpeSWuuExsi0BmSxY/zwIa3eFsawdhanYVKZl/G92IgMG/tY9zxaaWI4Sm
+KIYkM2oBLldzJbZev4/mHWGoQClnHYebHX+bn5nNMdZUvmK7OaxoEkiRIKXLsd3+
+b/xa5IJVWa8xqQ==
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIEdDCCA1ygAwIBAgIQRL4Mi1AAJLQR0zYq/mUK/TANBgkqhkiG9w0BAQUFADCB
+lzELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAlVUMRcwFQYDVQQHEw5TYWx0IExha2Ug
+Q2l0eTEeMBwGA1UEChMVVGhlIFVTRVJUUlVTVCBOZXR3b3JrMSEwHwYDVQQLExho
+dHRwOi8vd3d3LnVzZXJ0cnVzdC5jb20xHzAdBgNVBAMTFlVUTi1VU0VSRmlyc3Qt
+SGFyZHdhcmUwHhcNOTkwNzA5MTgxMDQyWhcNMTkwNzA5MTgxOTIyWjCBlzELMAkG
+A1UEBhMCVVMxCzAJBgNVBAgTAlVUMRcwFQYDVQQHEw5TYWx0IExha2UgQ2l0eTEe
+MBwGA1UEChMVVGhlIFVTRVJUUlVTVCBOZXR3b3JrMSEwHwYDVQQLExhodHRwOi8v
+d3d3LnVzZXJ0cnVzdC5jb20xHzAdBgNVBAMTFlVUTi1VU0VSRmlyc3QtSGFyZHdh
+cmUwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCx98M4P7Sof885glFn
+0G2f0v9Y8+efK+wNiVSZuTiZFvfgIXlIwrthdBKWHTxqctU8EGc6Oe0rE81m65UJ
+M6Rsl7HoxuzBdXmcRl6Nq9Bq/bkqVRcQVLMZ8Jr28bFdtqdt++BxF2uiiPsA3/4a
+MXcMmgF6sTLjKwEHOG7DpV4jvEWbe1DByTCP2+UretNb+zNAHqDVmBe8i4fDidNd
+oI6yqqr2jmmIBsX6iSHzCJ1pLgkzmykNRg+MzEk0sGlRvfkGzWitZky8PqxhvQqI
+DsjfPe58BEydCl5rkdbux+0ojatNh4lz0G6k0B4WixThdkQDf2Os5M1JnMWS9Ksy
+oUhbAgMBAAGjgbkwgbYwCwYDVR0PBAQDAgHGMA8GA1UdEwEB/wQFMAMBAf8wHQYD
+VR0OBBYEFKFyXyYbKJhDlV0HN9WFlp1L0sNFMEQGA1UdHwQ9MDswOaA3oDWGM2h0
+dHA6Ly9jcmwudXNlcnRydXN0LmNvbS9VVE4tVVNFUkZpcnN0LUhhcmR3YXJlLmNy
+bDAxBgNVHSUEKjAoBggrBgEFBQcDAQYIKwYBBQUHAwUGCCsGAQUFBwMGBggrBgEF
+BQcDBzANBgkqhkiG9w0BAQUFAAOCAQEARxkP3nTGmZev/K0oXnWO6y1n7k57K9cM
+//bey1WiCuFMVGWTYGufEpytXoMs61quwOQt9ABjHbjAbPLPSbtNk28Gpgoiskli
+CE7/yMgUsogWXecB5BKV5UU0s4tpvc+0hY91UZ59Ojg6FEgSxvunOxqNDYJAB+gE
+CJChicsZUN/KHAG8HQQZexB2lzvukJDKxA4fFm517zP4029bHpbj4HR3dHuKom4t
+3XbWOTCC8KucUvIqx69JXn7HaOWCgchqJ/kniCrVWFCVH/A7HFe7fRQ5YiuayZSS
+KqMiDP+JJn1fIytH1xUdqWqeUQ0qUZ6B+dQ7XnASfxAynB67nfhmqA==
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIDojCCAoqgAwIBAgIQE4Y1TR0/BvLB+WUF1ZAcYjANBgkqhkiG9w0BAQUFADBr
+MQswCQYDVQQGEwJVUzENMAsGA1UEChMEVklTQTEvMC0GA1UECxMmVmlzYSBJbnRl
+cm5hdGlvbmFsIFNlcnZpY2UgQXNzb2NpYXRpb24xHDAaBgNVBAMTE1Zpc2EgZUNv
+bW1lcmNlIFJvb3QwHhcNMDIwNjI2MDIxODM2WhcNMjIwNjI0MDAxNjEyWjBrMQsw
+CQYDVQQGEwJVUzENMAsGA1UEChMEVklTQTEvMC0GA1UECxMmVmlzYSBJbnRlcm5h
+dGlvbmFsIFNlcnZpY2UgQXNzb2NpYXRpb24xHDAaBgNVBAMTE1Zpc2EgZUNvbW1l
+cmNlIFJvb3QwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCvV95WHm6h
+2mCxlCfLF9sHP4CFT8icttD0b0/Pmdjh28JIXDqsOTPHH2qLJj0rNfVIsZHBAk4E
+lpF7sDPwsRROEW+1QK8bRaVK7362rPKgH1g/EkZgPI2h4H3PVz4zHvtH8aoVlwdV
+ZqW1LS7YgFmypw23RuwhY/81q6UCzyr0TP579ZRdhE2o8mCP2w4lPJ9zcc+U30rq
+299yOIzzlr3xF7zSujtFWsan9sYXiwGd/BmoKoMWuDpI/k4+oKsGGelT84ATB+0t
+vz8KPFUgOSwsAGl0lUq8ILKpeeUYiZGo3BxN77t+Nwtd/jmliFKMAGzsGHxBvfaL
+dXe6YJ2E5/4tAgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQD
+AgEGMB0GA1UdDgQWBBQVOIMPPyw/cDMezUb+B4wg4NfDtzANBgkqhkiG9w0BAQUF
+AAOCAQEAX/FBfXxcCLkr4NWSR/pnXKUTwwMhmytMiUbPWU3J/qVAtmPN3XEolWcR
+zCSs00Rsca4BIGsDoo8Ytyk6feUWYFN4PMCvFYP3j1IzJL1kk5fui/fbGKhtcbP3
+LBfQdCVp9/5rPJS+TUtBjE7ic9DjkCJzQ83z7+pzzkWKsKZJ/0x9nXGIxHYdkFsd
+7v3M9+79YKWxehZx0RbQfBI8bGmX265fOZpwLwU8GUYEmSA20GBuYQa7FkKMcPcw
+++DbZqMAAb3mLNqRX6BGi01qnD093QVG/na/oAo85ADmJ7f/hC3euiInlhBx6yLt
+398znM/jra6O1I7mT1GvFpLgXPYHDw==
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIFpDCCA4ygAwIBAgIBATANBgkqhkiG9w0BAQUFADBjMQswCQYDVQQGEwJVUzEc
+MBoGA1UEChMTQW1lcmljYSBPbmxpbmUgSW5jLjE2MDQGA1UEAxMtQW1lcmljYSBP
+bmxpbmUgUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAyMB4XDTAyMDUyODA2
+MDAwMFoXDTM3MDkyOTE0MDgwMFowYzELMAkGA1UEBhMCVVMxHDAaBgNVBAoTE0Ft
+ZXJpY2EgT25saW5lIEluYy4xNjA0BgNVBAMTLUFtZXJpY2EgT25saW5lIFJvb3Qg
+Q2VydGlmaWNhdGlvbiBBdXRob3JpdHkgMjCCAiIwDQYJKoZIhvcNAQEBBQADggIP
+ADCCAgoCggIBAMxBRR3pPU0Q9oyxQcngXssNt79Hc9PwVU3dxgz6sWYFas14tNwC
+206B89enfHG8dWOgXeMHDEjsJcQDIPT/DjsS/5uN4cbVG7RtIuOx238hZK+GvFci
+KtZHgVdEglZTvYYUAQv8f3SkWq7xuhG1m1hagLQ3eAkzfDJHA1zEpYNI9FdWboE2
+JxhP7JsowtS013wMPgwr38oE18aO6lhOqKSlGBxsRZijQdEt0sdtjRnxrXm3gT+9
+BoInLRBYBbV4Bbkv2wxrkJB+FFk4u5QkE+XRnRTf04JNRvCAOVIyD+OEsnpD8l7e
+Xz8d3eOyG6ChKiMDbi4BFYdcpnV1x5dhvt6G3NRI270qv0pV2uh9UPu0gBe4lL8B
+PeraunzgWGcXuVjgiIZGZ2ydEEdYMtA1fHkqkKJaEBEjNa0vzORKW6fIJ/KD3l67
+Xnfn6KVuY8INXWHQjNJsWiEOyiijzirplcdIz5ZvHZIlyMbGwcEMBawmxNJ10uEq
+Z8A9W6Wa6897GqidFEXlD6CaZd4vKL3Ob5Rmg0gp2OpljK+T2WSfVVcmv2/LNzGZ
+o2C7HK2JNDJiuEMhBnIMoVxtRsX6Kc8w3onccVvdtjc+31D1uAclJuW8tf48ArO3
++L5DwYcRlJ4jbBeKuIonDFRH8KmzwICMoCfrHRnjB453cMor9H124HhnAgMBAAGj
+YzBhMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFE1FwWg4u3OpaaEg5+31IqEj
+FNeeMB8GA1UdIwQYMBaAFE1FwWg4u3OpaaEg5+31IqEjFNeeMA4GA1UdDwEB/wQE
+AwIBhjANBgkqhkiG9w0BAQUFAAOCAgEAZ2sGuV9FOypLM7PmG2tZTiLMubekJcmn
+xPBUlgtk87FYT15R/LKXeydlwuXK5w0MJXti4/qftIe3RUavg6WXSIylvfEWK5t2
+LHo1YGwRgJfMqZJS5ivmae2p+DYtLHe/YUjRYwu5W1LtGLBDQiKmsXeu3mnFzccc
+obGlHBD7GL4acN3Bkku+KVqdPzW+5X1R+FXgJXUjhx5c3LqdsKyzadsXg8n33gy8
+CNyRnqjQ1xU3c6U1uPx+xURABsPr+CKAXEfOAuMRn0T//ZoyzH1kUQ7rVyZ2OuMe
+IjzCpjbdGe+n/BLzJsBZMYVMnNjP36TMzCmT/5RtdlwTCJfy7aULTd3oyWgOZtMA
+DjMSW7yV5TKQqLPGbIOtd+6Lfn6xqavT4fG2wLHqiMDn05DpKJKUe2h7lyoKZy2F
+AjgQ5ANh1NolNscIWC2hp1GvMApJ9aZphwctREZ2jirlmjvXGKL8nDgQzMY70rUX
+Om/9riW99XJZZLF0KjhfGEzfz3EEWjbUvy+ZnOjZurGV5gJLIaFb1cFPj65pbVPb
+AZO1XB4Y3WRayhgoPmMEEf0cjQAPuDffZ4qdZqkCapH/E8ovXYO8h5Ns3CRRFgQl
+Zvqz2cK6Kb6aSDiCmfS/O0oxGfm/jiEzFMpPVF/7zvuPcX/9XhmgD0uRuMRUvAaw
+RY8mkaKO/qk=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIECjCCAvKgAwIBAgIJAMJ+QwRORz8ZMA0GCSqGSIb3DQEBCwUAMIGCMQswCQYD
+VQQGEwJIVTERMA8GA1UEBwwIQnVkYXBlc3QxFjAUBgNVBAoMDU1pY3Jvc2VjIEx0
+ZC4xJzAlBgNVBAMMHk1pY3Jvc2VjIGUtU3ppZ25vIFJvb3QgQ0EgMjAwOTEfMB0G
+CSqGSIb3DQEJARYQaW5mb0BlLXN6aWduby5odTAeFw0wOTA2MTYxMTMwMThaFw0y
+OTEyMzAxMTMwMThaMIGCMQswCQYDVQQGEwJIVTERMA8GA1UEBwwIQnVkYXBlc3Qx
+FjAUBgNVBAoMDU1pY3Jvc2VjIEx0ZC4xJzAlBgNVBAMMHk1pY3Jvc2VjIGUtU3pp
+Z25vIFJvb3QgQ0EgMjAwOTEfMB0GCSqGSIb3DQEJARYQaW5mb0BlLXN6aWduby5o
+dTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAOn4j/NjrdqG2KfgQvvP
+kd6mJviZpWNwrZuuyjNAfW2WbqEORO7hE52UQlKavXWFdCyoDh2Tthi3jCyoz/tc
+cbna7P7ofo/kLx2yqHWH2Leh5TvPmUpG0IMZfcChEhyVbUr02MelTTMuhTlAdX4U
+fIASmFDHQWe4oIBhVKZsTh/gnQ4H6cm6M+f+wFUoLAKApxn1ntxVUwOXewdI/5n7
+N4okxFnMUBBjjqqpGrCEGob5X7uxUG6k0QrM1XF+H6cbfPVTbiJfyyvm1HxdrtbC
+xkzlBQHZ7Vf8wSN5/PrIJIOV87VqUQHQd9bpEqH5GoP7ghu5sJf0dgYzQ0mg/wu1
++rUCAwEAAaOBgDB+MA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0G
+A1UdDgQWBBTLD8bfQkPMPcu1SCOhGnqmKrs0aDAfBgNVHSMEGDAWgBTLD8bfQkPM
+Pcu1SCOhGnqmKrs0aDAbBgNVHREEFDASgRBpbmZvQGUtc3ppZ25vLmh1MA0GCSqG
+SIb3DQEBCwUAA4IBAQDJ0Q5eLtXMs3w+y/w9/w0olZMEyL/azXm4Q5DwpL7v8u8h
+mLzU1F0G9u5C7DBsoKqpyvGvivo/C3NqPuouQH4frlRheesuCDfXI/OMn74dseGk
+ddug4lQUsbocKaQY9hK6ohQU4zE1yED/t+AFdlfBHFny+L/k7SViXITwfn4fs775
+tyERzAMBVnCnEJIeGzSBHq2cGsMEPO0CYdYeBvNfOofyK/FFh+U9rNHHV4S9a67c
+2Pm2G2JwCz02yULyMtd6YebS2z3PyKnJm9zbWETXbzivf3jTo60adbocwTZ8jx5t
+HMN1Rq41Bab2XD0h7lbwyYIiLXpUq3DDfSJlgnCW
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIHqTCCBZGgAwIBAgIQYwaGp8U3ZaVDkKhqWMzUMjANBgkqhkiG9w0BAQUFADCB
+jzELMAkGA1UEBhMCTFYxNTAzBgNVBAoTLFZBUyBMYXR2aWphcyBQYXN0cyAtIFZp
+ZW4ucmVnLk5yLjQwMDAzMDUyNzkwMSMwIQYDVQQLExpTZXJ0aWZpa2FjaWphcyBw
+YWthbHBvanVtaTEkMCIGA1UEAxMbVkFTIExhdHZpamFzIFBhc3RzIFNTSShSQ0Ep
+MB4XDTA2MDkxMzA5MjIxMFoXDTI0MDkxMzA5Mjc1N1owgY8xCzAJBgNVBAYTAkxW
+MTUwMwYDVQQKEyxWQVMgTGF0dmlqYXMgUGFzdHMgLSBWaWVuLnJlZy5Oci40MDAw
+MzA1Mjc5MDEjMCEGA1UECxMaU2VydGlmaWthY2lqYXMgcGFrYWxwb2p1bWkxJDAi
+BgNVBAMTG1ZBUyBMYXR2aWphcyBQYXN0cyBTU0koUkNBKTCCAiIwDQYJKoZIhvcN
+AQEBBQADggIPADCCAgoCggIBAJu4+f1hVS9PpKUUtS6OuSSPrPuxVD9A/0/F5YZo
+e1OT+zWCNahQLpRSoNuDPnXaFXCsCc/ugkmtNkm5tHGLtAChQgbKCApjl7YI/O60
+3Jh4GYLJ+H9kPqrJ/rGN67Bk9bzzxD46kOpOjj8bGbxqg8ORPGxV+wpSwOjhXXeF
+M8VJ3+xqv79sN/6OSaIVGM6LjmseOKMwb4iBfnJWRBrEejkP9sSPltSy6wBOXN67
+5zu35iQFk2tN5pFEv+6YG8eFGxFBeyI2p74+6Ho33BjekJ2PzbLXmj/iF39bDOHv
+P2Y9biTksM7DDIhslNo4JXxSOeNzFLMARWOaDEJAXgTG93JkzsluM7Pk020klTeT
+fvIAXRmLH/NDc6ifRdIGqey0Qrv67gzHTz9RH9Gv0KwYf4eBIv6p3QeWbXz4TtlN
+OlBp1UF+xdp02I5z5X6D4cMZgbe9v0COvi6aogyqTgIuuyrhCF0xA8msJ7Cv3NXI
+FH1AnVWJIfmQzNTJYEFzq+jN2DpVOQqCmf6b9fU8HJHLwPpGVK4h/CqsXHveepdx
+/WxrzUiapNuBfBg3L5B9YZS9F8lctlQWd8oJSqrpvE+UdQFaVryS0o+515feVnQB
+9xZxSbH1GEaZQe5i4bMsZXVpKXJDA/ibH/o49J7sQBCOrJfVsDO+nxjcLfdBeFRK
+YkTnAgMBAAGjggH9MIIB+TAOBgNVHQ8BAf8EBAMCAQYwGAYIKwYBBQUHAQMEDDAK
+MAgGBgQAjkYBATAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBTMw/Vm/3OsOFqW
+GyGJuIFMH8teJTAQBgkrBgEEAYI3FQEEAwIBADCCAYkGA1UdIASCAYAwggF8MIIB
+eAYLKwYBBAGBxFkBAQIwggFnMIIBOAYIKwYBBQUHAgIwggEqHoIBJgBTAGkAcwAg
+AGkAcgAgAHMAZQByAHQAaQBmAGkAawBhAHQAcwAsACAAawBvACAAaQB6AGQAZQB2
+AGkAcwAgAFYAQQBTACAATABhAHQAdgBpAGoAYQBzACAAUABhAHMAdABzACwAIABu
+AG8AZAByAG8AcwBpAG4AbwB0ACAAYQB0AGIAaQBsAHMAdABpAGIAdQAgAEUAbABl
+AGsAdAByAG8AbgBpAHMAawBvACAAZABvAGsAdQBtAGUAbgB0AHUAIABsAGkAawB1
+AG0AYQBtACAAdQBuACAARQBpAHIAbwBwAGEAcwAgAFAAYQByAGwAYQBtAGUAbgB0
+AGEAIABkAGkAcgBlAGsAdABpAHYAYQBpACAAMQA5ADkAOQAvADkAMwAvAEUASzAp
+BggrBgEFBQcCARYdaHR0cDovL3d3dy5lLW1lLmx2L3JlcG9zaXRvcnkwDQYJKoZI
+hvcNAQEFBQADggIBAB8oSjWQIWNoCi94r6MegiaXoz8nGdJLo0J6BhNlW8EEy+t9
+fO+U8vGJ9bffUgIhadLqljTloM+XuJxVDhCFoxReLAX4tTp28/l6uN62DCdp8suU
+kQsdudWOb5kvzfIZVjk6SFbwAf+Cdbay/dHU9fJjV0xNoX7MELoEae/0FPyzlx9F
+7m9KKH/Rxie8x6Opa3vtghNvq94P+3HrXBEaqSzQMJ/8NjdW75XpurcTtq6fAmGt
+nuxrBG82nw+Z98LJyEwouSjUIdeeVNXAzvSO5FWUe48kxjj8q3qkVnc9qEXvZJKk
+0Ep+u3OL9A1Sc7g6SF5DgNOpcHdi/8coHHMeQ+YnJFtJueY2pI79xS0veqV5EnrX
+IbIlbcgPosNhS+VI4le6n/KKId3bZPDaGd/OwJuAOcJ3d2MVU3KE+qSPBzeGIX1Q
++j1qN9uRDjez/c4Lynth0Jx0nH04aG3pex3W8Sq07ztgUncF5gLCX4xbvPB9t3PH
+kWuyKrNjozTVq60lcUf/Gj56to2VdsPups0DCWzuRWeYz5lIdsHOinSaaFIBNCLI
+7eIUC4S9bhCMsXKbvugI11fVf+q0AT1O5OLoZ+eMfunnQhHvlUbIkda+JxeAGTSY
+58bfHvwhX56GPbx+8Jy9cp70R4JbcWfz+txUTKhc2FnH0AcOEzMnvPRp8Gsh
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIEDzCCAvegAwIBAgIBATANBgkqhkiG9w0BAQUFADBKMQswCQYDVQQGEwJTSzET
+MBEGA1UEBxMKQnJhdGlzbGF2YTETMBEGA1UEChMKRGlzaWcgYS5zLjERMA8GA1UE
+AxMIQ0EgRGlzaWcwHhcNMDYwMzIyMDEzOTM0WhcNMTYwMzIyMDEzOTM0WjBKMQsw
+CQYDVQQGEwJTSzETMBEGA1UEBxMKQnJhdGlzbGF2YTETMBEGA1UEChMKRGlzaWcg
+YS5zLjERMA8GA1UEAxMIQ0EgRGlzaWcwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAw
+ggEKAoIBAQCS9jHBfYj9mQGp2HvycXXxMcbzdWb6UShGhJd4NLxs/LxFWYgmGErE
+Nx+hSkS943EE9UQX4j/8SFhvXJ56CbpRNyIjZkMhsDxkovhqFQ4/61HhVKndBpnX
+mjxUizkDPw/Fzsbrg3ICqB9x8y34dQjbYkzo+s7552oftms1grrijxaSfQUMbEYD
+XcDtab86wYqg6I7ZuUUohwjstMoVvoLdtUSLLa2GDGhibYVW8qwUYzrG0ZmsNHhW
+S8+2rT+MitcE5eN4TPWGqvWP+j1scaMtymfraHtuM6kMgiioTGohQBUgDCZbg8Kp
+FhXAJIJdKxatymP2dACw30PEEGBWZ2NFAgMBAAGjgf8wgfwwDwYDVR0TAQH/BAUw
+AwEB/zAdBgNVHQ4EFgQUjbJJaJ1yCCW5wCf1UJNWSEZx+Y8wDgYDVR0PAQH/BAQD
+AgEGMDYGA1UdEQQvMC2BE2Nhb3BlcmF0b3JAZGlzaWcuc2uGFmh0dHA6Ly93d3cu
+ZGlzaWcuc2svY2EwZgYDVR0fBF8wXTAtoCugKYYnaHR0cDovL3d3dy5kaXNpZy5z
+ay9jYS9jcmwvY2FfZGlzaWcuY3JsMCygKqAohiZodHRwOi8vY2EuZGlzaWcuc2sv
+Y2EvY3JsL2NhX2Rpc2lnLmNybDAaBgNVHSAEEzARMA8GDSuBHpGT5goAAAABAQEw
+DQYJKoZIhvcNAQEFBQADggEBAF00dGFMrzvY/59tWDYcPQuBDRIrRhCA/ec8J9B6
+yKm2fnQwM6M6int0wHl5QpNt/7EpFIKrIYwvF/k/Ji/1WcbvgAa3mkkp7M5+cTxq
+EEHA9tOasnxakZzArFvITV734VP/Q3f8nktnbNfzg9Gg4H8l37iYC5oyOGwwoPP/
+CBUz91BKez6jPiCp3C9WgArtQVCwyfTssuMmRAAOb54GvCKWU3BlxFAKRmukLyeB
+EicTXxChds6KezfqwzlhA5WYOudsiCUI/HloDYd9Yvi0X/vF2Ey9WLw/Q1vUHgFN
+PGO+I++MzVpQuGhU+QqZMxEA4Z7CRneC9VkGjCFMhwnN5ag=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIDXTCCAkWgAwIBAgIDAOJCMA0GCSqGSIb3DQEBBQUAMFUxCzAJBgNVBAYTAkFU
+MRAwDgYDVQQKEwdBLVRydXN0MRkwFwYDVQQLExBBLVRydXN0LW5RdWFsLTAxMRkw
+FwYDVQQDExBBLVRydXN0LW5RdWFsLTAxMB4XDTA0MTEzMDIzMDAwMFoXDTE0MTEz
+MDIzMDAwMFowVTELMAkGA1UEBhMCQVQxEDAOBgNVBAoTB0EtVHJ1c3QxGTAXBgNV
+BAsTEEEtVHJ1c3QtblF1YWwtMDExGTAXBgNVBAMTEEEtVHJ1c3QtblF1YWwtMDEw
+ggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQD/9RyAEZ6eHmhYzNJ328f0
+jmdSUFi6EqRqOxb3jHNPTIpK82CR6z5lmSnZQNUuCPD+htbNZffd2DKVB06NOyZ1
+2zcOMCgj4GtkZoqE0zPpPT3bpoE55nkZZe/qWEX/64wz/L/4EdkvKDSKG/UsP75M
+tmCVY5m2Eg73RVFRz4ccBIMpHel4lzEqSkdDtZOY5fnkrE333hx67nxq21vY8Eyf
+8O4fPQ5RtN8eohQCcPQ1z6ypU1R7N9jPRpnI+yzMOiwd3+QcKhHi1miCzo0pkOaB
+1CwmfsTyNl8qU0NJUL9Ta6cea7WThwTiWol2yD88cd2cy388xpbNkfrCPmZNGLoV
+AgMBAAGjNjA0MA8GA1UdEwEB/wQFMAMBAf8wEQYDVR0OBAoECE5ZzscCMocwMA4G
+A1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQUFAAOCAQEA69I9R1hU9Gbl9vV7W7AH
+QpUJAlFAvv2It/eY8p2ouQUPVaSZikaKtAYrCD/arzfXB43Qet+dM6CpHsn8ikYR
+vQKePjXv3Evf+C1bxwJAimcnZV6W+bNOTpdo8lXljxkmfN+Z5S+XzvK2ttUtP4Et
+YOVaxHw2mPMNbvDeY+foJkiBn3KYjGabMaR8moZqof5ofj4iS/WyamTZti6v/fKx
+n1vII+/uWkcxV5DT5+r9HLon0NYF0Vg317Wh+gWDV59VZo+dcwJDb+keYqMFYoqp
+77SGkZGu41S8NGYkQY3X9rNHRkDbLfpKYDmy6NanpOE1EHW1/sNSFAs43qZZKJEQ
+xg==
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIEojCCA4qgAwIBAgIQRL4Mi1AAJLQR0zYlJWfJiTANBgkqhkiG9w0BAQUFADCB
+rjELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAlVUMRcwFQYDVQQHEw5TYWx0IExha2Ug
+Q2l0eTEeMBwGA1UEChMVVGhlIFVTRVJUUlVTVCBOZXR3b3JrMSEwHwYDVQQLExho
+dHRwOi8vd3d3LnVzZXJ0cnVzdC5jb20xNjA0BgNVBAMTLVVUTi1VU0VSRmlyc3Qt
+Q2xpZW50IEF1dGhlbnRpY2F0aW9uIGFuZCBFbWFpbDAeFw05OTA3MDkxNzI4NTBa
+Fw0xOTA3MDkxNzM2NThaMIGuMQswCQYDVQQGEwJVUzELMAkGA1UECBMCVVQxFzAV
+BgNVBAcTDlNhbHQgTGFrZSBDaXR5MR4wHAYDVQQKExVUaGUgVVNFUlRSVVNUIE5l
+dHdvcmsxITAfBgNVBAsTGGh0dHA6Ly93d3cudXNlcnRydXN0LmNvbTE2MDQGA1UE
+AxMtVVROLVVTRVJGaXJzdC1DbGllbnQgQXV0aGVudGljYXRpb24gYW5kIEVtYWls
+MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAsjmFpPJ9q0E7YkY3rs3B
+YHW8OWX5ShpHornMSMxqmNVNNRm5pELlzkniii8efNIxB8dOtINknS4p1aJkxIW9
+hVE1eaROaJB7HHqkkqgX8pgV8pPMyaQylbsMTzC9mKALi+VuG6JG+ni8om+rWV6l
+L8/K2m2qL+usobNqqrcuZzWLeeEeaYji5kbNoKXqvgvOdjp6Dpvq/NonWz1zHyLm
+SGHGTPNpsaguG7bUMSAsvIKKjqQOpdeJQ/wWWq8dcdcRWdq6hw2v+vPhwvCkxWeM
+1tZUOt4KpLoDd7NlyP0e03RiqhjKaJMeoYV+9Udly/hNVyh00jT/MLbu9mIwFIws
+6wIDAQABo4G5MIG2MAsGA1UdDwQEAwIBxjAPBgNVHRMBAf8EBTADAQH/MB0GA1Ud
+DgQWBBSJgmd9xJ0mcABLtFBIfN49rgRufTBYBgNVHR8EUTBPME2gS6BJhkdodHRw
+Oi8vY3JsLnVzZXJ0cnVzdC5jb20vVVROLVVTRVJGaXJzdC1DbGllbnRBdXRoZW50
+aWNhdGlvbmFuZEVtYWlsLmNybDAdBgNVHSUEFjAUBggrBgEFBQcDAgYIKwYBBQUH
+AwQwDQYJKoZIhvcNAQEFBQADggEBALFtYV2mGn98q0rkMPxTbyUkxsrt4jFcKw7u
+7mFVbwQ+zznexRtJlOTrIEy05p5QLnLZjfWqo7NK2lYcYJeA3IKirUq9iiv/Cwm0
+xtcgBEXkzYABurorbs6q15L+5K/r9CYdFip/bDCVNy8zEqx/3cfREYxRmLLQo5HQ
+rfafnoOTHh1CuEava2bwm3/q4wMC5QJRwarVNZ1yQAOJujEdxRBoUp7fooXFXAim
+eOZTT7Hot9MUnpOmw2TjrH5xzbyf6QMbzPvprDHBr3wVdAKZw7JHpsIyYdfHb0gk
+USeh1YdV8nuPmD0Wnu51tvjQjvLzxq4oW6fw8zYX/MMF08oDSlQ=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIFRjCCAy6gAwIBAgIIbYwURrGmCu4wDQYJKoZIhvcNAQEMBQAwQTELMAkGA1UE
+BhMCVVMxFDASBgNVBAoMC0FmZmlybVRydXN0MRwwGgYDVQQDDBNBZmZpcm1UcnVz
+dCBQcmVtaXVtMB4XDTEwMDEyOTE0MTAzNloXDTQwMTIzMTE0MTAzNlowQTELMAkG
+A1UEBhMCVVMxFDASBgNVBAoMC0FmZmlybVRydXN0MRwwGgYDVQQDDBNBZmZpcm1U
+cnVzdCBQcmVtaXVtMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAxBLf
+qV/+Qd3d9Z+K4/as4Tx4mrzY8H96oDMq3I0gW64tb+eT2TZwamjPjlGjhVtnBKAQ
+JG9dKILBl1fYSCkTtuG+kU3fhQxTGJoeJKJPj/CihQvL9Cl/0qRY7iZNyaqoe5rZ
++jjeRFcV5fiMyNlI4g0WJx0eyIOFJbe6qlVBzAMiSy2RjYvmia9mx+n/K+k8rNrS
+s8PhaJyJ+HoAVt70VZVs+7pk3WKL3wt3MutizCaam7uqYoNMtAZ6MMgpv+0GTZe5
+HMQxK9VfvFMSF5yZVylmd2EhMQcuJUmdGPLu8ytxjLW6OQdJd/zvLpKQBY0tL3d7
+70O/Nbua2Plzpyzy0FfuKE4mX4+QaAkvuPjcBukumj5Rp9EixAqnOEhss/n/fauG
+V+O61oV4d7pD6kh/9ti+I20ev9E2bFhc8e6kGVQa9QPSdubhjL08s9NIS+LI+H+S
+qHZGnEJlPqQewQcDWkYtuJfzt9WyVSHvutxMAJf7FJUnM7/oQ0dG0giZFmA7mn7S
+5u046uwBHjxIVkkJx0w3AJ6IDsBz4W9m6XJHMD4Q5QsDyZpCAGzFlH5hxIrff4Ia
+C1nEWTJ3s7xgaVY5/bQGeyzWZDbZvUjthB9+pSKPKrhC9IK31FOQeE4tGv2Bb0TX
+OwF0lkLgAOIua+rF7nKsu7/+6qqo+Nz2snmKtmcCAwEAAaNCMEAwHQYDVR0OBBYE
+FJ3AZ6YMItkm9UWrpmVSESfYRaxjMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/
+BAQDAgEGMA0GCSqGSIb3DQEBDAUAA4ICAQCzV00QYk465KzquByvMiPIs0laUZx2
+KI15qldGF9X1Uva3ROgIRL8YhNILgM3FEv0AVQVhh0HctSSePMTYyPtwni94loMg
+Nt58D2kTiKV1NpgIpsbfrM7jWNa3Pt668+s0QNiigfV4Py/VpfzZotReBA4Xrf5B
+8OWycvpEgjNC6C1Y91aMYj+6QrCcDFx+LmUmXFNPALJ4fqENmS2NuB2OosSw/WDQ
+MKSOyARiqcTtNd56l+0OOF6SL5Nwpamcb6d9Ex1+xghIsV5n61EIJenmJWtSKZGc
+0jlzCFfemQa0W50QBuHCAKi4HEoCChTQwUHK+4w1IX2COPKpVJEZNZOUbWo6xbLQ
+u4mGk+ibyQ86p3q4ofB4Rvr8Ny/lioTz3/4E2aFooC8k4gmVBtWVyuEklut89pMF
+u+1z6S3RdTnX5yTb2E5fQ4+e0BQ5v1VwSJlXMbSc7kqYA5YwH2AG7hsj/oFgIxpH
+YoWlzBk0gG+zrBrjn/B7SK3VAdlntqlyk+otZrWyuOQ9PLLvTIzq6we/qzWaVYa8
+GKa1qF60g2xraUDTn9zxw2lrueFtCfTxqlB2Cnp9ehehVZZCmTEJ3WARjQUwfuaO
+RtGdFNrHF+QFlozEJLUbzxQHskD4o55BhrwE0GuWyCqANP2/7waj3VjFhT0+j/6e
+KeC2uAloGRwYQw==
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIEFTCCAv2gAwIBAgIBATANBgkqhkiG9w0BAQUFADBkMQswCQYDVQQGEwJTRTEU
+MBIGA1UEChMLQWRkVHJ1c3QgQUIxHTAbBgNVBAsTFEFkZFRydXN0IFRUUCBOZXR3
+b3JrMSAwHgYDVQQDExdBZGRUcnVzdCBQdWJsaWMgQ0EgUm9vdDAeFw0wMDA1MzAx
+MDQxNTBaFw0yMDA1MzAxMDQxNTBaMGQxCzAJBgNVBAYTAlNFMRQwEgYDVQQKEwtB
+ZGRUcnVzdCBBQjEdMBsGA1UECxMUQWRkVHJ1c3QgVFRQIE5ldHdvcmsxIDAeBgNV
+BAMTF0FkZFRydXN0IFB1YmxpYyBDQSBSb290MIIBIjANBgkqhkiG9w0BAQEFAAOC
+AQ8AMIIBCgKCAQEA6Rowj4OIFMEg2Dybjxt+A3S72mnTRqX4jsIMEZBRpS9mVEBV
+6tsfSlbunyNu9DnLoblv8n75XYcmYZ4c+OLspoH4IcUkzBEMP9smcnrHAZcHF/nX
+GCwwfQ56HmIexkvA/X1id9NEHif2P0tEs7c42TkfYNVRknMDtABp4/MUTu7R3AnP
+dzRGULD4EfL+OHn3Bzn+UZKXC1sIXzSGAa2Il+tmzV7R/9x98oTaunet3IAIx6eH
+1lWfl2royBFkuucZKT8Rs3iQhCBSWxHveNCD9tVIkNAwHM+A+WD+eeSI8t0A65RF
+62WUaUC6wNW0uLp9BBGo6zEFlpROWCGOn9Bg/QIDAQABo4HRMIHOMB0GA1UdDgQW
+BBSBPjfYkrAfd59ctKtzquf2NGAv+jALBgNVHQ8EBAMCAQYwDwYDVR0TAQH/BAUw
+AwEB/zCBjgYDVR0jBIGGMIGDgBSBPjfYkrAfd59ctKtzquf2NGAv+qFopGYwZDEL
+MAkGA1UEBhMCU0UxFDASBgNVBAoTC0FkZFRydXN0IEFCMR0wGwYDVQQLExRBZGRU
+cnVzdCBUVFAgTmV0d29yazEgMB4GA1UEAxMXQWRkVHJ1c3QgUHVibGljIENBIFJv
+b3SCAQEwDQYJKoZIhvcNAQEFBQADggEBAAP3FUr4JNojVhaTdt02KLmuG7jD8WS6
+IBh4lSknVwW8fCr0uVFV2ocC3g8WFzH4qnkuCRO7r7IgGRLlk/lL+YPoRNWyQSW/
+iHVv/xD8SlTQX/D67zZzfRs2RcYhbbQVuE7PnFylPVoAjgbjPGsye/Kf8Lb93/Ao
+GEjwxrzQvzSAlsJKsW2Ox5BF3i9nrEUEo3rcVZLJR2bYGozH7ZxOmuASu7VqTITh
+4SINhwBk/ox9Yjllpu9CtoAlEmEBqCQTcAARJl/6NVDFSMwGR+gn2HCNX2TmoUQm
+XiLsks3/QppEIW1cxeMiHV9HEufOX1362KqxMy3ZdvJOOjMMK7MtkAY=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIEajCCA1KgAwIBAgIBATANBgkqhkiG9w0BAQUFADBaMQswCQYDVQQGEwJKUDEN
+MAsGA1UECgwESlBLSTEpMCcGA1UECwwgUHJlZmVjdHVyYWwgQXNzb2NpYXRpb24g
+Rm9yIEpQS0kxETAPBgNVBAsMCEJyaWRnZUNBMB4XDTAzMTIyNzA1MDgxNVoXDTEz
+MTIyNjE0NTk1OVowWjELMAkGA1UEBhMCSlAxDTALBgNVBAoMBEpQS0kxKTAnBgNV
+BAsMIFByZWZlY3R1cmFsIEFzc29jaWF0aW9uIEZvciBKUEtJMREwDwYDVQQLDAhC
+cmlkZ2VDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANTnUmg7K3m8
+52vd77kwkq156euwoWm5no8E8kmaTSc7x2RABPpqNTlMKdZ6ttsyYrqREeDkcvPL
+yF7yf/I8+innasNtsytcTAy8xY8Avsbd4JkCGW9dyPjk9pzzc3yLQ64Rx2fujRn2
+agcEVdPCr/XpJygX8FD5bbhkZ0CVoiASBmlHOcC3YpFlfbT1QcpOSOb7o+VdKVEi
+MMfbBuU2IlYIaSr/R1nO7RPNtkqkFWJ1/nKjKHyzZje7j70qSxb+BTGcNgTHa1YA
+UrogKB+UpBftmb4ds+XlkEJ1dvwokiSbCDaWFKD+YD4B2s0bvjCbw8xuZFYGhNyR
+/2D5XfN1s2MCAwEAAaOCATkwggE1MA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8E
+BTADAQH/MG0GA1UdHwRmMGQwYqBgoF6kXDBaMQswCQYDVQQGEwJKUDENMAsGA1UE
+CgwESlBLSTEpMCcGA1UECwwgUHJlZmVjdHVyYWwgQXNzb2NpYXRpb24gRm9yIEpQ
+S0kxETAPBgNVBAsMCEJyaWRnZUNBMIGDBgNVHREEfDB6pHgwdjELMAkGA1UEBhMC
+SlAxJzAlBgNVBAoMHuWFrOeahOWAi+S6uuiqjeiovOOCteODvOODk+OCuTEeMBwG
+A1UECwwV6YO96YGT5bqc55yM5Y2U6K2w5LyaMR4wHAYDVQQLDBXjg5bjg6rjg4Pj
+grjoqo3oqLzlsYAwHQYDVR0OBBYEFNQXMiCqQNkR2OaZmQgLtf8mR8p8MA0GCSqG
+SIb3DQEBBQUAA4IBAQATjJo4reTNPC5CsvAKu1RYT8PyXFVYHbKsEpGt4GR8pDCg
+HEGAiAhHSNrGh9CagZMXADvlG0gmMOnXowriQQixrtpkmx0TB8tNAlZptZWkZC+R
+8TnjOkHrk2nFAEC3ezbdK0R7MR4tJLDQCnhEWbg50rf0wZ/aF8uAaVeEtHXa6W0M
+Xq3dSe0XAcrLbX4zZHQTaWvdpLAIjl6DZ3SCieRMyoWUL+LXaLFdTP5WBCd+No58
+IounD9X4xxze2aeRVaiV/WnQ0OSPNS7n7YXy6xQdnaOU4KRW/Lne1EDf5IfWC/ih
+bVAmhZMbcrkWWcsR6aCPG+2mV3zTD6AUzuKPal8Y
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIDdTCCAl2gAwIBAgILBAAAAAABFUtaw5QwDQYJKoZIhvcNAQEFBQAwVzELMAkG
+A1UEBhMCQkUxGTAXBgNVBAoTEEdsb2JhbFNpZ24gbnYtc2ExEDAOBgNVBAsTB1Jv
+b3QgQ0ExGzAZBgNVBAMTEkdsb2JhbFNpZ24gUm9vdCBDQTAeFw05ODA5MDExMjAw
+MDBaFw0yODAxMjgxMjAwMDBaMFcxCzAJBgNVBAYTAkJFMRkwFwYDVQQKExBHbG9i
+YWxTaWduIG52LXNhMRAwDgYDVQQLEwdSb290IENBMRswGQYDVQQDExJHbG9iYWxT
+aWduIFJvb3QgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDaDuaZ
+jc6j40+Kfvvxi4Mla+pIH/EqsLmVEQS98GPR4mdmzxzdzxtIK+6NiY6arymAZavp
+xy0Sy6scTHAHoT0KMM0VjU/43dSMUBUc71DuxC73/OlS8pF94G3VNTCOXkNz8kHp
+1Wrjsok6Vjk4bwY8iGlbKk3Fp1S4bInMm/k8yuX9ifUSPJJ4ltbcdG6TRGHRjcdG
+snUOhugZitVtbNV4FpWi6cgKOOvyJBNPc1STE4U6G7weNLWLBYy5d4ux2x8gkasJ
+U26Qzns3dLlwR5EiUWMWea6xrkEmCMgZK9FGqkjWZCrXgzT/LCrBbBlDSgeF59N8
+9iFo7+ryUp9/k5DPAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8E
+BTADAQH/MB0GA1UdDgQWBBRge2YaRQ2XyolQL30EzTSo//z9SzANBgkqhkiG9w0B
+AQUFAAOCAQEA1nPnfE920I2/7LqivjTFKDK1fPxsnCwrvQmeU79rXqoRSLblCKOz
+yj1hTdNGCbM+w6DjY1Ub8rrvrTnhQ7k4o+YviiY776BQVvnGCv04zcQLcFGUl5gE
+38NflNUVyRRBnMRddWQVDf9VMOyGj/8N7yy5Y0b2qvzfvGn9LhJIZJrglfCm7ymP
+AbEVtQwdpf5pLGkkeB6zpxxxYu7KyJesF12KwvhHhm4qxFYxldBniYUr+WymXUad
+DKqC5JlR3XC321Y9YeRq4VzW9v493kHMB65jUr9TU/Qr6cf9tveCX4XSQRjbgbME
+HMUfpIBvFSDJ3gyICh3WZlXi/EjJKSZp4A==
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIDdTCCAl2gAwIBAgILAgAAAAAA1ni3lAUwDQYJKoZIhvcNAQEEBQAwVzELMAkG
+A1UEBhMCQkUxGTAXBgNVBAoTEEdsb2JhbFNpZ24gbnYtc2ExEDAOBgNVBAsTB1Jv
+b3QgQ0ExGzAZBgNVBAMTEkdsb2JhbFNpZ24gUm9vdCBDQTAeFw05ODA5MDExMjAw
+MDBaFw0xNDAxMjgxMjAwMDBaMFcxCzAJBgNVBAYTAkJFMRkwFwYDVQQKExBHbG9i
+YWxTaWduIG52LXNhMRAwDgYDVQQLEwdSb290IENBMRswGQYDVQQDExJHbG9iYWxT
+aWduIFJvb3QgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDaDuaZ
+jc6j40+Kfvvxi4Mla+pIH/EqsLmVEQS98GPR4mdmzxzdzxtIK+6NiY6arymAZavp
+xy0Sy6scTHAHoT0KMM0VjU/43dSMUBUc71DuxC73/OlS8pF94G3VNTCOXkNz8kHp
+1Wrjsok6Vjk4bwY8iGlbKk3Fp1S4bInMm/k8yuX9ifUSPJJ4ltbcdG6TRGHRjcdG
+snUOhugZitVtbNV4FpWi6cgKOOvyJBNPc1STE4U6G7weNLWLBYy5d4ux2x8gkasJ
+U26Qzns3dLlwR5EiUWMWea6xrkEmCMgZK9FGqkjWZCrXgzT/LCrBbBlDSgeF59N8
+9iFo7+ryUp9/k5DPAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIABjAdBgNVHQ4EFgQU
+YHtmGkUNl8qJUC99BM00qP/8/UswDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0B
+AQQFAAOCAQEArqqf/LfSyx9fOSkoGJ40yWxPbxrwZKJwSk8ThptgKJ7ogUmYfQq7
+5bCdPTbbjwVR/wkxKh/diXeeDy5slQTthsu0AD+EAk2AaioteAuubyuig0SDH81Q
+gkwkr733pbTIWg/050deSY43lv6aiAU62cDbKYfmGZZHpzqmjIs8d/5GY6dT2iHR
+rH5Jokvmw2dZL7OKDrssvamqQnw1wdh/1acxOk5jQzmvCLBhNIzTmKlDNPYPhyk7
+ncJWWJh3w/cbrPad+D6qp1RF8PX51TFl/mtYnHGzHtdS6jIX/EBgHcl5JLL2bP2o
+Zg6C3ZjL2sJETy6ge/L3ayx2EYRGinij4w==
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIEKzCCAxOgAwIBAgIEOsylTDANBgkqhkiG9w0BAQUFADBDMQswCQYDVQQGEwJE
+SzEVMBMGA1UEChMMVERDIEludGVybmV0MR0wGwYDVQQLExRUREMgSW50ZXJuZXQg
+Um9vdCBDQTAeFw0wMTA0MDUxNjMzMTdaFw0yMTA0MDUxNzAzMTdaMEMxCzAJBgNV
+BAYTAkRLMRUwEwYDVQQKEwxUREMgSW50ZXJuZXQxHTAbBgNVBAsTFFREQyBJbnRl
+cm5ldCBSb290IENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAxLhA
+vJHVYx/XmaCLDEAedLdInUaMArLgJF/wGROnN4NrXceO+YQwzho7+vvOi20jxsNu
+Zp+Jpd/gQlBn+h9sHvTQBda/ytZO5GhgbEaqHF1j4QeGDmUApy6mcca8uYGoOn0a
+0vnRrEvLznWv3Hv6gXPU/Lq9QYjUdLP5Xjg6PEOo0pVOd20TDJ2PeAG3WiAfAzc1
+4izbSysseLlJ28TQx5yc5IogCSEWVmb/Bexb4/DPqyQkXsN/cHoSxNK1EKC2IeGN
+eGlVRGn1ypYcNIUXJXfi9i8nmHj9eQY6otZaQ8H/7AQ77hPv01ha/5Lr7K7a8jcD
+R0G2l8ktCkEiu7vmpwIDAQABo4IBJTCCASEwEQYJYIZIAYb4QgEBBAQDAgAHMGUG
+A1UdHwReMFwwWqBYoFakVDBSMQswCQYDVQQGEwJESzEVMBMGA1UEChMMVERDIElu
+dGVybmV0MR0wGwYDVQQLExRUREMgSW50ZXJuZXQgUm9vdCBDQTENMAsGA1UEAxME
+Q1JMMTArBgNVHRAEJDAigA8yMDAxMDQwNTE2MzMxN1qBDzIwMjEwNDA1MTcwMzE3
+WjALBgNVHQ8EBAMCAQYwHwYDVR0jBBgwFoAUbGQBx/2FbazI2p5QCIUItTxWqFAw
+HQYDVR0OBBYEFGxkAcf9hW2syNqeUAiFCLU8VqhQMAwGA1UdEwQFMAMBAf8wHQYJ
+KoZIhvZ9B0EABBAwDhsIVjUuMDo0LjADAgSQMA0GCSqGSIb3DQEBBQUAA4IBAQBO
+Q8zR3R0QGwZ/t6T609lN+yOfI1Rb5osvBCiLtSdtiaHsmGnc540mgwV5dOy0uaOX
+wTUA/RXaOYE6lTGQ3pfphqiZdwzlWqCE/xIWrG64jcN7ksKsLtB9KOy282A4aW8+
+2ARVPp7MVdK6/rtHBNcK2RYKNCn1WBPVT8+PVkuzHu7TmHnaCB4Mb7j4Fifvwm89
+9qNLPg7kbWzbO0ESm70NRyN/PErQr8Cv9u8btRXE64PECV90i9kR+8JWsTz4cMo0
+jUNAE4z9mQNUecYu6oah9jrUCbz0vGbMPVjQV0kK7iXiQe4T+Zs4NNEA9X7nlB38
+aQNiuJkFBT1reBK9sG9l
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIB4TCCAYegAwIBAgIRKjikHJYKBN5CsiilC+g0mAIwCgYIKoZIzj0EAwIwUDEk
+MCIGA1UECxMbR2xvYmFsU2lnbiBFQ0MgUm9vdCBDQSAtIFI0MRMwEQYDVQQKEwpH
+bG9iYWxTaWduMRMwEQYDVQQDEwpHbG9iYWxTaWduMB4XDTEyMTExMzAwMDAwMFoX
+DTM4MDExOTAzMTQwN1owUDEkMCIGA1UECxMbR2xvYmFsU2lnbiBFQ0MgUm9vdCBD
+QSAtIFI0MRMwEQYDVQQKEwpHbG9iYWxTaWduMRMwEQYDVQQDEwpHbG9iYWxTaWdu
+MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEuMZ5049sJQ6fLjkZHAOkrprlOQcJ
+FspjsbmG+IpXwVfOQvpzofdlQv8ewQCybnMO/8ch5RikqtlxP6jUuc6MHaNCMEAw
+DgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFFSwe61F
+uOJAf/sKbvu+M8k8o4TVMAoGCCqGSM49BAMCA0gAMEUCIQDckqGgE6bPA7DmxCGX
+kPoUVy0D7O48027KqGx2vKLeuwIgJ6iFJzWbVsaj8kfSt24bAgAXqmemFZHe+pTs
+ewv4n4Q=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIF0DCCBLigAwIBAgIEOrZQizANBgkqhkiG9w0BAQUFADB/MQswCQYDVQQGEwJC
+TTEZMBcGA1UEChMQUXVvVmFkaXMgTGltaXRlZDElMCMGA1UECxMcUm9vdCBDZXJ0
+aWZpY2F0aW9uIEF1dGhvcml0eTEuMCwGA1UEAxMlUXVvVmFkaXMgUm9vdCBDZXJ0
+aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0wMTAzMTkxODMzMzNaFw0yMTAzMTcxODMz
+MzNaMH8xCzAJBgNVBAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBMaW1pdGVkMSUw
+IwYDVQQLExxSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MS4wLAYDVQQDEyVR
+dW9WYWRpcyBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIIBIjANBgkqhkiG
+9w0BAQEFAAOCAQ8AMIIBCgKCAQEAv2G1lVO6V/z68mcLOhrfEYBklbTRvM16z/Yp
+li4kVEAkOPcahdxYTMukJ0KX0J+DisPkBgNbAKVRHnAEdOLB1Dqr1607BxgFjv2D
+rOpm2RgbaIr1VxqYuvXtdj182d6UajtLF8HVj71lODqV0D1VNk7feVcxKh7YWWVJ
+WCCYfqtffp/p1k3sg3Spx2zY7ilKhSoGFPlU5tPaZQeLYzcS19Dsw3sgQUSj7cug
+F+FxZc4dZjH3dgEZyH0DWLaVSR2mEiboxgx24ONmy+pdpibu5cxfvWenAScOospU
+xbF6lR1xHkopigPcakXBpBlebzbNw6Kwt/5cOOJSvPhEQ+aQuwIDAQABo4ICUjCC
+Ak4wPQYIKwYBBQUHAQEEMTAvMC0GCCsGAQUFBzABhiFodHRwczovL29jc3AucXVv
+dmFkaXNvZmZzaG9yZS5jb20wDwYDVR0TAQH/BAUwAwEB/zCCARoGA1UdIASCAREw
+ggENMIIBCQYJKwYBBAG+WAABMIH7MIHUBggrBgEFBQcCAjCBxxqBxFJlbGlhbmNl
+IG9uIHRoZSBRdW9WYWRpcyBSb290IENlcnRpZmljYXRlIGJ5IGFueSBwYXJ0eSBh
+c3N1bWVzIGFjY2VwdGFuY2Ugb2YgdGhlIHRoZW4gYXBwbGljYWJsZSBzdGFuZGFy
+ZCB0ZXJtcyBhbmQgY29uZGl0aW9ucyBvZiB1c2UsIGNlcnRpZmljYXRpb24gcHJh
+Y3RpY2VzLCBhbmQgdGhlIFF1b1ZhZGlzIENlcnRpZmljYXRlIFBvbGljeS4wIgYI
+KwYBBQUHAgEWFmh0dHA6Ly93d3cucXVvdmFkaXMuYm0wHQYDVR0OBBYEFItLbe3T
+KbkGGew5Oanwl4Rqy+/fMIGuBgNVHSMEgaYwgaOAFItLbe3TKbkGGew5Oanwl4Rq
+y+/foYGEpIGBMH8xCzAJBgNVBAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBMaW1p
+dGVkMSUwIwYDVQQLExxSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MS4wLAYD
+VQQDEyVRdW9WYWRpcyBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5ggQ6tlCL
+MA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQUFAAOCAQEAitQUtf70mpKnGdSk
+fnIYj9lofFIk3WdvOXrEql494liwTXCYhGHoG+NpGA7O+0dQoE7/8CQfvbLO9Sf8
+7C9TqnN7Az10buYWnuulLsS/VidQK2K6vkscPFVcQR0kvoIgR13VRH56FmjffU1R
+cHhXHTMe/QKZnAzNCgVPx7uOpHX6Sm2xgI4JVrmcGmD+XcHXetwReNDWXcG31a0y
+mQM6isxUJTkxgXsTIlG6Rmyhu576BGxJJnSP0nPrzDCi5upZIof4l/UO/erMkqQW
+xFIY6iHOsfHmhIHluqmGKPJDWl0Snawe2ajlCmqnf6CHKc/yiU3U7MXi5nrQNiOK
+SnQ2+Q==
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIDwzCCAqugAwIBAgIBATANBgkqhkiG9w0BAQsFADCBgjELMAkGA1UEBhMCREUx
+KzApBgNVBAoMIlQtU3lzdGVtcyBFbnRlcnByaXNlIFNlcnZpY2VzIEdtYkgxHzAd
+BgNVBAsMFlQtU3lzdGVtcyBUcnVzdCBDZW50ZXIxJTAjBgNVBAMMHFQtVGVsZVNl
+YyBHbG9iYWxSb290IENsYXNzIDIwHhcNMDgxMDAxMTA0MDE0WhcNMzMxMDAxMjM1
+OTU5WjCBgjELMAkGA1UEBhMCREUxKzApBgNVBAoMIlQtU3lzdGVtcyBFbnRlcnBy
+aXNlIFNlcnZpY2VzIEdtYkgxHzAdBgNVBAsMFlQtU3lzdGVtcyBUcnVzdCBDZW50
+ZXIxJTAjBgNVBAMMHFQtVGVsZVNlYyBHbG9iYWxSb290IENsYXNzIDIwggEiMA0G
+CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCqX9obX+hzkeXaXPSi5kfl82hVYAUd
+AqSzm1nzHoqvNK38DcLZSBnuaY/JIPwhqgcZ7bBcrGXHX+0CfHt8LRvWurmAwhiC
+FoT6ZrAIxlQjgeTNuUk/9k9uN0goOA/FvudocP05l03Sx5iRUKrERLMjfTlH6VJi
+1hKTXrcxlkIF+3anHqP1wvzpesVsqXFP6st4vGCvx9702cu+fjOlbpSD8DT6Iavq
+jnKgP6TeMFvvhk1qlVtDRKgQFRzlAVfFmPHmBiiRqiDFt1MmUUOyCxGVWOHAD3bZ
+wI18gfNycJ5v/hqO2V81xrJvNHy+SE/iWjnX2J14np+GPgNeGYtEotXHAgMBAAGj
+QjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBS/
+WSA2AHmgoCJrjNXyYdK4LMuCSjANBgkqhkiG9w0BAQsFAAOCAQEAMQOiYQsfdOhy
+NsZt+U2e+iKo4YFWz827n+qrkRk4r6p8FU3ztqONpfSO9kSpp+ghla0+AGIWiPAC
+uvxhI+YzmzB6azZie60EI4RYZeLbK4rnJVM3YlNfvNoBYimipidx5joifsFvHZVw
+IEoHNN/q/xWA5brXethbdXwFeilHfkCoMRN3zUA7tFFHei4R40cR3p1m0IvVVGb6
+g1XqfMIpiRvpb7PO4gWEyS8+eIVibslfwXhjdFjASBgMmTnrpMwatXlajRWc2BQN
+9noHV8cigwUtPJslJj0Ys6lDfMjIq2SPDqO/nBudMNva0Bkuqjzx+zOAduTNrRlP
+BSeOE6Fuwg==
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIFODCCAyCgAwIBAgIRAJW+FqD3LkbxezmCcvqLzZYwDQYJKoZIhvcNAQEFBQAw
+NzEUMBIGA1UECgwLVGVsaWFTb25lcmExHzAdBgNVBAMMFlRlbGlhU29uZXJhIFJv
+b3QgQ0EgdjEwHhcNMDcxMDE4MTIwMDUwWhcNMzIxMDE4MTIwMDUwWjA3MRQwEgYD
+VQQKDAtUZWxpYVNvbmVyYTEfMB0GA1UEAwwWVGVsaWFTb25lcmEgUm9vdCBDQSB2
+MTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAMK+6yfwIaPzaSZVfp3F
+VRaRXP3vIb9TgHot0pGMYzHw7CTww6XScnwQbfQ3t+XmfHnqjLWCi65ItqwA3GV1
+7CpNX8GH9SBlK4GoRz6JI5UwFpB/6FcHSOcZrr9FZ7E3GwYq/t75rH2D+1665I+X
+Z75Ljo1kB1c4VWk0Nj0TSO9P4tNmHqTPGrdeNjPUtAa9GAH9d4RQAEX1jF3oI7x+
+/jXh7VB7qTCNGdMJjmhnXb88lxhTuylixcpecsHHltTbLaC0H2kD7OriUPEMPPCs
+81Mt8Bz17Ww5OXOAFshSsCPN4D7c3TxHoLs1iuKYaIu+5b9y7tL6pe0S7fyYGKkm
+dtwoSxAgHNN/Fnct7W+A90m7UwW7XWjH1Mh1Fj+JWov3F0fUTPHSiXk+TT2YqGHe
+Oh7S+F4D4MHJHIzTjU3TlTazN19jY5szFPAtJmtTfImMMsJu7D0hADnJoWjiUIMu
+sDor8zagrC/kb2HCUQk5PotTubtn2txTuXZZNp1D5SDgPTJghSJRt8czu90VL6R4
+pgd7gUY2BIbdeTXHlSw7sKMXNeVzH7RcWe/a6hBle3rQf5+ztCo3O3CLm1u5K7fs
+slESl1MpWtTwEhDcTwK7EpIvYtQ/aUN8Ddb8WHUBiJ1YFkveupD/RwGJBmr2X7KQ
+arMCpgKIv7NHfirZ1fpoeDVNAgMBAAGjPzA9MA8GA1UdEwEB/wQFMAMBAf8wCwYD
+VR0PBAQDAgEGMB0GA1UdDgQWBBTwj1k4ALP1j5qWDNXr+nuqF+gTEjANBgkqhkiG
+9w0BAQUFAAOCAgEAvuRcYk4k9AwI//DTDGjkk0kiP0Qnb7tt3oNmzqjMDfz1mgbl
+dxSR651Be5kqhOX//CHBXfDkH1e3damhXwIm/9fH907eT/j3HEbAek9ALCI18Bmx
+0GtnLLCo4MBANzX2hFxc469CeP6nyQ1Q6g2EdvZR74NTxnr/DlZJLo961gzmJ1Tj
+TQpgcmLNkQfWpb/ImWvtxBnmq0wROMVvMeJuScg/doAmAyYp4Db29iBT4xdwNBed
+Y2gea+zDTYa4EzAvXUYNR0PVG6pZDrlcjQZIrXSHX8f8MVRBE+LHIQ6e4B4N4cB7
+Q4WQxYpYxmUKeFfyxiMPAdkgS94P+5KFdSpcc41teyWRyu5FrgZLAMzTsVlQ2jqI
+OylDRl6XK1TOU2+NSueW+r9xDkKLfP0ooNBIytrEgUy7onOTJsjrDNYmiLbAJM+7
+vVvrdX3pCI6GMyx5dwlppYn8s3CQh3aP0yK7Qs69cwsgJirQmz1wHiRszYd2qReW
+t88NkvuOGKmYSdGe/mBEciG5Ge3C9THxOUiIkCR1VBatzvT4aRRkOfujuLpwQMcn
+HL/EVlP6Y2XQ8xwOFvVrhlhNGNTkDY6lnVuR3HYkUD/GKvvZt5y11ubQ2egZixVx
+SK236thZiNSQvxaz2emsWWFUyBy6ysHK4bkgTI86k4mloMy/0/Z1pHWWbVY=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIEIDCCAwigAwIBAgIQNE7VVyDV7exJ9C/ON9srbTANBgkqhkiG9w0BAQUFADCB
+qTELMAkGA1UEBhMCVVMxFTATBgNVBAoTDHRoYXd0ZSwgSW5jLjEoMCYGA1UECxMf
+Q2VydGlmaWNhdGlvbiBTZXJ2aWNlcyBEaXZpc2lvbjE4MDYGA1UECxMvKGMpIDIw
+MDYgdGhhd3RlLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxHzAdBgNV
+BAMTFnRoYXd0ZSBQcmltYXJ5IFJvb3QgQ0EwHhcNMDYxMTE3MDAwMDAwWhcNMzYw
+NzE2MjM1OTU5WjCBqTELMAkGA1UEBhMCVVMxFTATBgNVBAoTDHRoYXd0ZSwgSW5j
+LjEoMCYGA1UECxMfQ2VydGlmaWNhdGlvbiBTZXJ2aWNlcyBEaXZpc2lvbjE4MDYG
+A1UECxMvKGMpIDIwMDYgdGhhd3RlLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNl
+IG9ubHkxHzAdBgNVBAMTFnRoYXd0ZSBQcmltYXJ5IFJvb3QgQ0EwggEiMA0GCSqG
+SIb3DQEBAQUAA4IBDwAwggEKAoIBAQCsoPD7gFnUnMekz52hWXMJEEUMDSxuaPFs
+W0hoSVk3/AszGcJ3f8wQLZU0HObrTQmnHNK4yZc2AreJ1CRfBsDMRJSUjQJib+ta
+3RGNKJpchJAQeg29dGYvajig4tVUROsdB58Hum/u6f1OCyn1PoSgAfGcq/gcfomk
+6KHYcWUNo1F77rzSImANuVud37r8UVsLr5iy6S7pBOhih94ryNdOwUxkHt3Ph1i6
+Sk/KaAcdHJ1KxtUvkcx8cXIcxcBn6zL9yZJclNqFwJu/U30rCfSMnZEfl2pSy94J
+NqR32HuHUETVPm4pafs5SSYeCaWAe0At6+gnhcn+Yf1+5nyXHdWdAgMBAAGjQjBA
+MA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBR7W0XP
+r87Lev0xkhpqtvNG61dIUDANBgkqhkiG9w0BAQUFAAOCAQEAeRHAS7ORtvzw6WfU
+DW5FvlXok9LOAz/t2iWwHVfLHjp2oEzsUHboZHIMpKnxuIvW1oeEuzLlQRHAd9mz
+YJ3rG9XRbkREqaYB7FViHXe4XI5ISXycO1cRrK1zN44veFyQaEfZYGDm/Ac9IiAX
+xPcW6cTYcvnIc3zfFi8VqT79aie2oetaupgf1eNNZAqdE8hhuvU5HIe6uL17In/2
+/qxAeeWsEG89jxt5dovEN7MhGITlNgDrYyCZuen+MwS7QcjBAvlEYyCegc5C09Y/
+LHbTY5xZ3Y+m4Q6gLkH3LpVHz7z9M/P2C2F+fpErgUfCJzDupxBdN49cOSvkBPB7
+jVaMaA==
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIDhDCCAmygAwIBAgIBCTANBgkqhkiG9w0BAQUFADAzMQswCQYDVQQGEwJDTjER
+MA8GA1UEChMIVW5pVHJ1c3QxETAPBgNVBAMTCFVDQSBSb290MB4XDTA0MDEwMTAw
+MDAwMFoXDTI5MTIzMTAwMDAwMFowMzELMAkGA1UEBhMCQ04xETAPBgNVBAoTCFVu
+aVRydXN0MREwDwYDVQQDEwhVQ0EgUm9vdDCCASIwDQYJKoZIhvcNAQEBBQADggEP
+ADCCAQoCggEBALNdB8qGJn1r4vs4CQ7MgsJqGgCiFV/W6dQBt1YDAVmP9ThpJHbC
+XivF9iu/r/tB/Q9a/KvXg3BNMJjRnrJ2u5LWu+kQKGkoNkTo8SzXWHwk1n8COvCB
+a2FgP/Qz3m3l6ihST/ypHWN8C7rqrsRoRuTej8GnsrZYWm0dLNmMOreIy4XU9+gD
+Xv2yTVDo1h//rgI/i0+WITyb1yXJHT/7mLFZ5PCpO6+zzYUs4mBGzG+OoOvwNMXx
+QhhgrhLtRnUc5dipllq+3lrWeGeWW5N3UPJuG96WUUqm1ktDdSFmjXfsAoR2XEQQ
+th1hbOSjIH23jboPkXXHjd+8AmCoKai9PUMCAwEAAaOBojCBnzALBgNVHQ8EBAMC
+AQYwDAYDVR0TBAUwAwEB/zBjBgNVHSUEXDBaBggrBgEFBQcDAQYIKwYBBQUHAwIG
+CCsGAQUFBwMDBggrBgEFBQcDBAYIKwYBBQUHAwUGCCsGAQUFBwMGBggrBgEFBQcD
+BwYIKwYBBQUHAwgGCCsGAQUFBwMJMB0GA1UdDgQWBBTbHzXza0z/QjFkm827Wh4d
+SBC37jANBgkqhkiG9w0BAQUFAAOCAQEAOGy3iPGt+lg3dNHocN6cJ1nL5BXXoMNg
+14iABMUwTD3UGusGXllH5rxmy+AI/Og17GJ9ysDawXiv5UZv+4mCI4/211NmVaDe
+JRI7cTYWVRJ2+z34VFsxugAG+H1V5ad2g6pcSpemKijfvcZsCyOVjjN/Hl5AHxNU
+LJzltQ7dFyiuawHTUin1Ih+QOfTcYmjwPIZH7LgFRbu3DJaUxmfLI3HQjnQi1kHr
+A6i26r7EARK1s11AdgYg1GS4KUYGis4fk5oQ7vuqWrTcL9Ury/bXBYSYBZELhPc9
++tb5evosFeo2gkO3t7jj83EB7UNDogVFwygFBzXjAaU4HoDU18PZ3g==
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIID8TCCAtmgAwIBAgIQQT1yx/RrH4FDffHSKFTfmjANBgkqhkiG9w0BAQUFADCB
+ijELMAkGA1UEBhMCQ0gxEDAOBgNVBAoTB1dJU2VLZXkxGzAZBgNVBAsTEkNvcHly
+aWdodCAoYykgMjAwNTEiMCAGA1UECxMZT0lTVEUgRm91bmRhdGlvbiBFbmRvcnNl
+ZDEoMCYGA1UEAxMfT0lTVEUgV0lTZUtleSBHbG9iYWwgUm9vdCBHQSBDQTAeFw0w
+NTEyMTExNjAzNDRaFw0zNzEyMTExNjA5NTFaMIGKMQswCQYDVQQGEwJDSDEQMA4G
+A1UEChMHV0lTZUtleTEbMBkGA1UECxMSQ29weXJpZ2h0IChjKSAyMDA1MSIwIAYD
+VQQLExlPSVNURSBGb3VuZGF0aW9uIEVuZG9yc2VkMSgwJgYDVQQDEx9PSVNURSBX
+SVNlS2V5IEdsb2JhbCBSb290IEdBIENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A
+MIIBCgKCAQEAy0+zAJs9Nt350UlqaxBJH+zYK7LG+DKBKUOVTJoZIyEVRd7jyBxR
+VVuuk+g3/ytr6dTqvirdqFEr12bDYVxgAsj1znJ7O7jyTmUIms2kahnBAbtzptf2
+w93NvKSLtZlhuAGio9RN1AU9ka34tAhxZK9w8RxrfvbDd50kc3vkDIzh2TbhmYsF
+mQvtRTEJysIA2/dyoJaqlYfQjse2YXMNdmaM3Bu0Y6Kff5MTMPGhJ9vZ/yxViJGg
+4E8HsChWjBgbl0SOid3gF27nKu+POQoxhILYQBRJLnpB5Kf+42TMwVlxSywhp1t9
+4B3RLoGbw9ho972WG6xwsRYUC9tguSYBBQIDAQABo1EwTzALBgNVHQ8EBAMCAYYw
+DwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUswN+rja8sHnR3JQmthG+IbJphpQw
+EAYJKwYBBAGCNxUBBAMCAQAwDQYJKoZIhvcNAQEFBQADggEBAEuh/wuHbrP5wUOx
+SPMowB0uyQlB+pQAHKSkq0lPjz0e701vvbyk9vImMMkQyh2I+3QZH4VFvbBsUfk2
+ftv1TDI6QU9bR8/oCy22xBmddMVHxjtqD6wU2zz0c5ypBd8A3HR4+vg1YFkCExh8
+vPtNsCBtQ7tgMHpnM1zFmdH4LTlSc/uMqpclXHLZCB6rTjzjgTGfA6b7wP4piFXa
+hNVQA7bihKOmNqoROgHhGEvWRGizPflTdISzRpFGlgC3gCy24eMQ4tui5yiPAZZi
+Fj4A4xylNoEYokxSdsARo27mHbrjWr42U8U+dY+GaSlYU7Wcu2+fXMUY7N0v4ZjJ
+/L7fCg0=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIDlDCCAnygAwIBAgIQWAsFbFMk27JQVxhf+eWmUDANBgkqhkiG9w0BAQUFADAn
+MQswCQYDVQQGEwJCRTEYMBYGA1UEAxMPQmVsZ2l1bSBSb290IENBMB4XDTAzMDEy
+NjIzMDAwMFoXDTE0MDEyNjIzMDAwMFowJzELMAkGA1UEBhMCQkUxGDAWBgNVBAMT
+D0JlbGdpdW0gUm9vdCBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB
+AMihcekcRkJ5eHFvna6pqKsot03HIOswkVp19eLSz8hMFJhCWK3HEcVAQGpa+XQS
+J4fpnOVxTiIs0RIYqjBeoiG52bv/9nTrMQHnO35YD5EWTXaJqAFPrSJmcPpLHZXB
+MFjqvNll2Jq0iOtJRlLf0lMVdssUXRlJsW9q09P9vMIt7EU/CT9YvvzU7wCMgTVy
+v/cY6pZifSsofxVsY9LKyn0FrMhtB20yvmi4BUCuVJhWPmbxMOjvxKuTXgfeMo8S
+dKpbNCNUwOpszv42kqgJF+qhLc9s44Qd3ocuMws8dOIhUDiVLlzg5cYx+dtA+mqh
+pIqTm6chBocdJ9PEoclMsG8CAwEAAaOBuzCBuDAOBgNVHQ8BAf8EBAMCAQYwDwYD
+VR0TAQH/BAUwAwEB/zBCBgNVHSAEOzA5MDcGBWA4AQEBMC4wLAYIKwYBBQUHAgEW
+IGh0dHA6Ly9yZXBvc2l0b3J5LmVpZC5iZWxnaXVtLmJlMB0GA1UdDgQWBBQQ8AxW
+m2HqVzq2NZdtn925FI7b5jARBglghkgBhvhCAQEEBAMCAAcwHwYDVR0jBBgwFoAU
+EPAMVpth6lc6tjWXbZ/duRSO2+YwDQYJKoZIhvcNAQEFBQADggEBAMhtIlGKYfgP
+lm7VILKB+MbcoxYA2s1q52sq+llIp0xJN9dzoWoBZV4yveeX09AuPHPTjHuD79ZC
+wT+oqV0PN7p20kC9zC0/00RBSZz9Wyn0AiMiW3Ebv1jZKE4tRfTa57VjRUQRDSp/
+M382SbTObqkCMa5c/ciJv0J71/Fg8teH9lcuen5qE4Ad3OPQYx49cTGxYNSeCMqr
+8JTHSHVUgfMbrXec6LKP24OsjzRr6L/D2fVDw2RV6xq9NoY2uiGMlxoh1OotO6y6
+7Kcdq765Sps1LxxcHVGnH1TtEpf/8m6HfUbJdNbv6z195lluBpQE5KJVhzgoaiJe
+4r50ErAEQyo=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIDTDCCAjSgAwIBAgIId3cGJyapsXwwDQYJKoZIhvcNAQELBQAwRDELMAkGA1UE
+BhMCVVMxFDASBgNVBAoMC0FmZmlybVRydXN0MR8wHQYDVQQDDBZBZmZpcm1UcnVz
+dCBDb21tZXJjaWFsMB4XDTEwMDEyOTE0MDYwNloXDTMwMTIzMTE0MDYwNlowRDEL
+MAkGA1UEBhMCVVMxFDASBgNVBAoMC0FmZmlybVRydXN0MR8wHQYDVQQDDBZBZmZp
+cm1UcnVzdCBDb21tZXJjaWFsMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC
+AQEA9htPZwcroRX1BiLLHwGy43NFBkRJLLtJJRTWzsO3qyxPxkEylFf6EqdbDuKP
+Hx6GGaeqtS25Xw2Kwq+FNXkyLbscYjfysVtKPcrNcV/pQr6U6Mje+SJIZMblq8Yr
+ba0F8PrVC8+a5fBQpIs7R6UjW3p6+DM/uO+Zl+MgwdYoic+U+7lF7eNAFxHUdPAL
+MeIrJmqbTFeurCA+ukV6BfO9m2kVrn1OIGPENXY6BwLJN/3HR+7o8XYdcxXyl6S1
+yHp52UKqK39c/s4mT6NmgTWvRLpUHhwwMmWd5jyTXlBOeuM61G7MGvv50jeuJCqr
+VwMiKA1JdX+3KNp1v47j3A55MQIDAQABo0IwQDAdBgNVHQ4EFgQUnZPGU4teyq8/
+nx4P5ZmVvCT2lI8wDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwDQYJ
+KoZIhvcNAQELBQADggEBAFis9AQOzcAN/wr91LoWXym9e2iZWEnStB03TX8nfUYG
+XUPGhi4+c7ImfU+TqbbEKpqrIZcUsd6M06uJFdhrJNTxFq7YpFzUf1GO7RgBsZNj
+vbz4YYCanrHOQnDiqX0GJX0nof5v7LMeJNrjS1UaADs1tDvZ110w/YETifLCBivt
+Z8SOyUOyXGsViQK8YvxO8rUzqrJv0wqiUOP2O+guRMLbZjipM1ZI8W0bM40NjD9g
+N53Tym1+NH4Nn3J2ixufcv1SNUFFApYvHLKac0khsUlHRUe072o0EclNmsxZt9YC
+nlpOZbWUrhvfKbAW8b8Angc6F2S1BLUjIZkKlTuXfO8=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIEQzCCAyugAwIBAgIDCYP0MA0GCSqGSIb3DQEBCwUAMFAxCzAJBgNVBAYTAkRF
+MRUwEwYDVQQKDAxELVRydXN0IEdtYkgxKjAoBgNVBAMMIUQtVFJVU1QgUm9vdCBD
+bGFzcyAzIENBIDIgRVYgMjAwOTAeFw0wOTExMDUwODUwNDZaFw0yOTExMDUwODUw
+NDZaMFAxCzAJBgNVBAYTAkRFMRUwEwYDVQQKDAxELVRydXN0IEdtYkgxKjAoBgNV
+BAMMIUQtVFJVU1QgUm9vdCBDbGFzcyAzIENBIDIgRVYgMjAwOTCCASIwDQYJKoZI
+hvcNAQEBBQADggEPADCCAQoCggEBAJnxhDRwui+3MKCOvXwEz75ivJn9gpfSegpn
+ljgJ9hBOlSJzmY3aFS3nBfwZcyK3jpgAvDw9rKFs+9Z5JUut8Mxk2og+KbgPCdM0
+3TP1YtHhzRnp7hhPTFiu4h7WDFsVWtg6uMQYZB7jM7K1iXdODL/ZlGsTl28So/6Z
+qQTMFexgaDbtCHu39b+T7WYxg4zGcTSHThfqr4uRjRxWQa4iN1438h3Z0S0NL2lR
+p75mpoo6Kr3HGrHhFPC+Oh25z1uxav60sUYgovseO3Dvk5h9jHOW8sXvhXCtKSb8
+HgQ+HKDYD8tSg2J87otTlZCpV6LqYQXY+U3EJ/pure3511H3a6UCAwEAAaOCASQw
+ggEgMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFNOUikxiEyoZLsyvcop9Ntea
+HNxnMA4GA1UdDwEB/wQEAwIBBjCB3QYDVR0fBIHVMIHSMIGHoIGEoIGBhn9sZGFw
+Oi8vZGlyZWN0b3J5LmQtdHJ1c3QubmV0L0NOPUQtVFJVU1QlMjBSb290JTIwQ2xh
+c3MlMjAzJTIwQ0ElMjAyJTIwRVYlMjAyMDA5LE89RC1UcnVzdCUyMEdtYkgsQz1E
+RT9jZXJ0aWZpY2F0ZXJldm9jYXRpb25saXN0MEagRKBChkBodHRwOi8vd3d3LmQt
+dHJ1c3QubmV0L2NybC9kLXRydXN0X3Jvb3RfY2xhc3NfM19jYV8yX2V2XzIwMDku
+Y3JsMA0GCSqGSIb3DQEBCwUAA4IBAQA07XtaPKSUiO8aEXUHL7P+PPoeUSbrh/Yp
+3uDx1MYkCenBz1UbtDDZzhr+BlGmFaQt77JLvyAoJUnRpjZ3NOhk31KxEcdzes05
+nsKtjHEh8lprr988TlWvsoRlFIm5d8sqMb7Po23Pb0iUMkZv53GMoKaEGTcH8gNF
+CSuGdXzfX2lXANtu2KZyIktQ1HWYVt+3GP9DQ1CuekR78HlR10M9p9OB0/DJT7na
+xpeG0ILD5EJt/rDiZE4OJudANCa1CInXCGNjOCd1HjPqbqjdn5lPdE2BiYBL3ZqX
+KVwvvoFBuYz/6n1gBp7N1z3TLqMVvKjmJuVvw9y4AyHqnxbxLFS1
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIF2TCCA8GgAwIBAgIQHp4o6Ejy5e/DfEoeWhhntjANBgkqhkiG9w0BAQsFADBk
+MQswCQYDVQQGEwJjaDERMA8GA1UEChMIU3dpc3Njb20xJTAjBgNVBAsTHERpZ2l0
+YWwgQ2VydGlmaWNhdGUgU2VydmljZXMxGzAZBgNVBAMTElN3aXNzY29tIFJvb3Qg
+Q0EgMjAeFw0xMTA2MjQwODM4MTRaFw0zMTA2MjUwNzM4MTRaMGQxCzAJBgNVBAYT
+AmNoMREwDwYDVQQKEwhTd2lzc2NvbTElMCMGA1UECxMcRGlnaXRhbCBDZXJ0aWZp
+Y2F0ZSBTZXJ2aWNlczEbMBkGA1UEAxMSU3dpc3Njb20gUm9vdCBDQSAyMIICIjAN
+BgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAlUJOhJ1R5tMJ6HJaI2nbeHCOFvEr
+jw0DzpPMLgAIe6szjPTpQOYXTKueuEcUMncy3SgM3hhLX3af+Dk7/E6J2HzFZ++r
+0rk0X2s682Q2zsKwzxNoysjL67XiPS4h3+os1OD5cJZM/2pYmLcX5BtS5X4HAB1f
+2uY+lQS3aYg5oUFgJWFLlTloYhyxCwWJwDaCFCE/rtuh/bxvHGCGtlOUSbkrRsVP
+ACu/obvLP+DHVxxX6NZp+MEkUp2IVd3Chy50I9AU/SpHWrumnf2U5NGKpV+GY3aF
+y6//SSj8gO1MedK75MDvAe5QQQg1I3ArqRa0jG6F6bYRzzHdUyYb3y1aSgJA/MTA
+tukxGggo5WDDH8SQjhBiYEQN7Aq+VRhxLKX0srwVYv8c474d2h5Xszx+zYIdkeNL
+6yxSNLCK/RJOlrDrcH+eOfdmQrGrrFLadkBXeyq96G4DsguAhYidDMfCd7Camlf0
+uPoTXGiTOmekl9AbmbeGMktg2M7v0Ax/lZ9vh0+Hio5fCHyqW/xavqGRn1V9TrAL
+acywlKinh/LTSlDcX3KwFnUey7QYYpqwpzmqm59m2I2mbJYV4+by+PGDYmy7Velh
+k6M99bFXi08jsJvllGov34zflVEpYKELKeRcVVi3qPyZ7iVNTA6z00yPhOgpD/0Q
+VAKFyPnlw4vP5w8CAwEAAaOBhjCBgzAOBgNVHQ8BAf8EBAMCAYYwHQYDVR0hBBYw
+FDASBgdghXQBUwIBBgdghXQBUwIBMBIGA1UdEwEB/wQIMAYBAf8CAQcwHQYDVR0O
+BBYEFE0mICKJS9PVpAqhb97iEoHF8TwuMB8GA1UdIwQYMBaAFE0mICKJS9PVpAqh
+b97iEoHF8TwuMA0GCSqGSIb3DQEBCwUAA4ICAQAyCrKkG8t9voJXiblqf/P0wS4R
+fbgZPnm3qKhyN2abGu2sEzsOv2LwnN+ee6FTSA5BesogpxcbtnjsQJHzQq0Qw1zv
+/2BZf82Fo4s9SBwlAjxnffUy6S8w5X2lejjQ82YqZh6NM4OKb3xuqFp1mrjX2lhI
+REeoTPpMSQpKwhI3qEAMw8jh0FcNlzKVxzqfl9NX+Ave5XLzo9v/tdhZsnPdTSpx
+srpJ9csc1fV5yJmz/MFMdOO0vSk3FQQoHt5FRnDsr7p4DooqzgB53MBfGWcsa0vv
+aGgLQ+OswWIJ76bdZWGgr4RVSJFSHMYlkSrQwSIjYVmvRRGFHQEkNI/Ps/8XciAT
+woCqISxxOQ7Qj1zB09GOInJGTB2Wrk9xseEFKZZZ9LuedT3PDTcNYtsmjGOpI99n
+Bjx8Oto0QuFmtEYE3saWmA9LSHokMnWRn6z3aOkquVVlzl1h0ydw2Df+n7mvoC5W
+t6NlUe07qxS/TFED6F+KBZvuim6c779o+sjaC+NCydAXFJy3SuCvkychVSa1ZC+N
+8f+mQAWFBVzKBxlcCxMoTFh/wqXvRdpg065lYZ1Tg3TCrvJcwhbtkj6EPnNgiLx2
+9CzP0H1907he0ZESEOnN3col49XtmS++dYFLJPlFRpTJKSFTnCZFqhMX5OfNeOI5
+wSsSnqaeG8XmDtkx2Q==
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIEZjCCA06gAwIBAgIQRL4Mi1AAJLQR0zYt4LNfGzANBgkqhkiG9w0BAQUFADCB
+lTELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAlVUMRcwFQYDVQQHEw5TYWx0IExha2Ug
+Q2l0eTEeMBwGA1UEChMVVGhlIFVTRVJUUlVTVCBOZXR3b3JrMSEwHwYDVQQLExho
+dHRwOi8vd3d3LnVzZXJ0cnVzdC5jb20xHTAbBgNVBAMTFFVUTi1VU0VSRmlyc3Qt
+T2JqZWN0MB4XDTk5MDcwOTE4MzEyMFoXDTE5MDcwOTE4NDAzNlowgZUxCzAJBgNV
+BAYTAlVTMQswCQYDVQQIEwJVVDEXMBUGA1UEBxMOU2FsdCBMYWtlIENpdHkxHjAc
+BgNVBAoTFVRoZSBVU0VSVFJVU1QgTmV0d29yazEhMB8GA1UECxMYaHR0cDovL3d3
+dy51c2VydHJ1c3QuY29tMR0wGwYDVQQDExRVVE4tVVNFUkZpcnN0LU9iamVjdDCC
+ASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAM6qgT+jo2F4qjEAVZURnicP
+HxzfOpuCaDDASmEd8S8O+r5596Uj71VRloTN2+O5bj4x2AogZ8f02b+U60cEPgLO
+KqJdhwQJ9jCdGIqXsqoc/EHSoTbL+z2RuufZcDX65OeQw5ujm9M89RKZd7G3CeBo
+5hy485RjiGpq/gt2yb70IuRnuasaXnfBhQfdDWy/7gbHd2pBnqcP1/vulBe3/IW+
+pKvEHDHd17bR5PDv3xaPslKT16HUiaEHLr/hARJCHhrh2JU022R5KP+6LhHC5ehb
+kkj7RwvCbNqtMoNB86XlQXD9ZZBt+vpRxPm9lisZBCzTbafc8H9vg2XiaquHhnUC
+AwEAAaOBrzCBrDALBgNVHQ8EBAMCAcYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4E
+FgQU2u1kdBScFDyr3ZmpvVsoTYs8ydgwQgYDVR0fBDswOTA3oDWgM4YxaHR0cDov
+L2NybC51c2VydHJ1c3QuY29tL1VUTi1VU0VSRmlyc3QtT2JqZWN0LmNybDApBgNV
+HSUEIjAgBggrBgEFBQcDAwYIKwYBBQUHAwgGCisGAQQBgjcKAwQwDQYJKoZIhvcN
+AQEFBQADggEBAAgfUrE3RHjb/c652pWWmKpVZIC1WkDdIaXFwfNfLEzIR1pp6ujw
+NTX00CXzyKakh0q9G7FzCL3Uw8q2NbtZhncxzaeAFK4T7/yxSPlrJSUtUbYsbUXB
+mMiKVl0+7kNOPmsnjtA6S4ULX9Ptaqd1y9Fahy85dRNacrACgZ++8A+EVCBibGnU
+4U3GDZlDAQ0Slox4nb9QorFEqmrPF3rPbw/U+CRVX/A0FklmPlBGyWNxODFiuGK5
+81OtbLUrohKqGU8J2l7nk8aOFAj+8DCAGKCGhU3IfdeLA/5u1fedFqySLKAj5ZyR
+Uh+U3xeUc8OzwcFxBSAAeL0TUh2oPs0AH8g=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIDjjCCAnagAwIBAgIIKv++n6Lw6YcwDQYJKoZIhvcNAQEFBQAwKDELMAkGA1UE
+BhMCQkUxGTAXBgNVBAMTEEJlbGdpdW0gUm9vdCBDQTIwHhcNMDcxMDA0MTAwMDAw
+WhcNMjExMjE1MDgwMDAwWjAoMQswCQYDVQQGEwJCRTEZMBcGA1UEAxMQQmVsZ2l1
+bSBSb290IENBMjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMZzQh6S
+/3UPi790hqc/7bIYLS2X+an7mEoj39WN4IzGMhwWLQdC1i22bi+n9fzGhYJdld61
+IgDMqFNAn68KNaJ6x+HK92AQZw6nUHMXU5WfIp8MXW+2QbyM69odRr2nlL/zGsvU
++40OHjPIltfsjFPekx40HopQcSZYtF3CiInaYNKJIT/e1wEYNm7hLHADBGXvmAYr
+XR5i3FVr/mZkIV/4L+HXmymvb82fqgxG0YjFnaKVn6w/Fa7yYd/vw2uaItgscf1Y
+HewApDgglVrH1Tdjuk+bqv5WRi5j2Qsj1Yr6tSPwiRuhFA0m2kHwOI8w7QUmecFL
+TqG4flVSOmlGhHUCAwEAAaOBuzCBuDAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/
+BAUwAwEB/zBCBgNVHSAEOzA5MDcGBWA4CQEBMC4wLAYIKwYBBQUHAgEWIGh0dHA6
+Ly9yZXBvc2l0b3J5LmVpZC5iZWxnaXVtLmJlMB0GA1UdDgQWBBSFiuv0xbu+DlkD
+lN7WgAEV4xCcOTARBglghkgBhvhCAQEEBAMCAAcwHwYDVR0jBBgwFoAUhYrr9MW7
+vg5ZA5Te1oABFeMQnDkwDQYJKoZIhvcNAQEFBQADggEBAFHYhd27V2/MoGy1oyCc
+UwnzSgEMdL8rs5qauhjyC4isHLMzr87lEwEnkoRYmhC598wUkmt0FoqW6FHvv/pK
+JaeJtmMrXZRY0c8RcrYeuTlBFk0pvDVTC9rejg7NqZV3JcqUWumyaa7YwBO+mPyW
+nIR/VRPmPIfjvCCkpDZoa01gZhz5v6yAlGYuuUGK02XThIAC71AdXkbc98m6tTR8
+KvPG2F9fVJ3bTc0R5/0UAoNmXsimABKgX77OFP67H6dh96tK8QYUn8pJQsKpvO2F
+sauBQeYNxUJpU4c5nUwfAA4+Bw11V0SoU7Q2dmSZ3G7rPUZuFF1eR1ONeE3gJ7uO
+hXY=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIFyjCCA7KgAwIBAgIEAJiWjDANBgkqhkiG9w0BAQsFADBaMQswCQYDVQQGEwJO
+TDEeMBwGA1UECgwVU3RhYXQgZGVyIE5lZGVybGFuZGVuMSswKQYDVQQDDCJTdGFh
+dCBkZXIgTmVkZXJsYW5kZW4gUm9vdCBDQSAtIEcyMB4XDTA4MDMyNjExMTgxN1oX
+DTIwMDMyNTExMDMxMFowWjELMAkGA1UEBhMCTkwxHjAcBgNVBAoMFVN0YWF0IGRl
+ciBOZWRlcmxhbmRlbjErMCkGA1UEAwwiU3RhYXQgZGVyIE5lZGVybGFuZGVuIFJv
+b3QgQ0EgLSBHMjCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAMVZ5291
+qj5LnLW4rJ4L5PnZyqtdj7U5EILXr1HgO+EASGrP2uEGQxGZqhQlEq0i6ABtQ8Sp
+uOUfiUtnvWFI7/3S4GCI5bkYYCjDdyutsDeqN95kWSpGV+RLufg3fNU254DBtvPU
+Z5uW6M7XxgpT0GtJlvOjCwV3SPcl5XCsMBQgJeN/dVrlSPhOewMHBPqCYYdu8DvE
+pMfQ9XQ+pV0aCPKbJdL2rAQmPlU6Yiile7Iwr/g3wtG61jj99O9JMDeZJiFIhQGp
+5Rbn3JBV3w/oOM2ZNyFPXfUib2rFEhZgF1XyZWampzCROME4HYYEhLoaJXhena/M
+UGDWE4dS7WMfbWV9whUYdMrhfmQpjHLYFhN9C0lK8SgbIHRrxT3dsKpICT0ugpTN
+GmXZK4iambwYfp/ufWZ8Pr2UuIHOzZgweMFvZ9C+X+Bo7d7iscksWXiSqt8rYGPy
+5V6548r6f1CGPqI0GAwJaCgRHOThuVw+R7oyPxjMW4T182t0xHJ04eOLoEq9jWYv
+6q012iDTiIJh8BIitrzQ1aTsr1SIJSQ8p22xcik/Plemf1WvbibG/ufMQFxRRIEK
+eN5KzlW/HdXZt1bv8Hb/C3m1r737qWmRRpdogBQ2HbN/uymYNqUg+oJgYjOk7Na6
+B6duxc8UpufWkjTYgfX8HV2qXB72o007uPc5AgMBAAGjgZcwgZQwDwYDVR0TAQH/
+BAUwAwEB/zBSBgNVHSAESzBJMEcGBFUdIAAwPzA9BggrBgEFBQcCARYxaHR0cDov
+L3d3dy5wa2lvdmVyaGVpZC5ubC9wb2xpY2llcy9yb290LXBvbGljeS1HMjAOBgNV
+HQ8BAf8EBAMCAQYwHQYDVR0OBBYEFJFoMocVHYnitfGsNig0jQt8YojrMA0GCSqG
+SIb3DQEBCwUAA4ICAQCoQUpnKpKBglBu4dfYszk78wIVCVBR7y29JHuIhjv5tLyS
+CZa59sCrI2AGeYwRTlHSeYAz+51IvuxBQ4EffkdAHOV6CMqqi3WtFMTC6GY8ggen
+5ieCWxjmD27ZUD6KQhgpxrRW/FYQoAUXvQwjf/ST7ZwaUb7dRUG/kSS0H4zpX897
+IZmflZ85OkYcbPnNe5yQzSipx6lVu6xiNGI1E0sUOlWDuYaNkqbG9AclVMwWVxJK
+gnjIFNkXgiYtXSAfea7+1HAWFpWD2DU5/1JddRwWxRNVz0fMdWVSSt7wsKfkCpYL
++63C4iWEst3kvX5ZbJvw8NjnyvLplzh+ib7M+zkXYT9y2zqR2GUBGR2tUKRXCnxL
+vJxxcypFURmFzI79R6d0lR2o0a9OF7FpJsKqeFdbxU2n5Z4FF5TKsl+gSRiNNOkm
+bEgeqmiSBeGCc1qb3AdbCG19ndeNIdn8FCCqwkXfP+cAslHkwvgFuXkajDTznlvk
+N1trSt8sV4pAWja63XVECDdCcAz+3F4hoKOKwJCcaNpQ5kUQR3i2TtJlycM33+FC
+Y7BXN0Ute4qcvwXqZVUz9zkQxSgqIXobisQk+T8VyJoVIPVVYpbtbZNQvOSqeK3Z
+ywplh6ZmwcSBo3c6WB4L7oOLnR7SUqTMHW+wmG2UMbX4cQrcufx9MmDm66+KAQ==
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIICHjCCAaSgAwIBAgIRYFlJ4CYuu1X5CneKcflK2GwwCgYIKoZIzj0EAwMwUDEk
+MCIGA1UECxMbR2xvYmFsU2lnbiBFQ0MgUm9vdCBDQSAtIFI1MRMwEQYDVQQKEwpH
+bG9iYWxTaWduMRMwEQYDVQQDEwpHbG9iYWxTaWduMB4XDTEyMTExMzAwMDAwMFoX
+DTM4MDExOTAzMTQwN1owUDEkMCIGA1UECxMbR2xvYmFsU2lnbiBFQ0MgUm9vdCBD
+QSAtIFI1MRMwEQYDVQQKEwpHbG9iYWxTaWduMRMwEQYDVQQDEwpHbG9iYWxTaWdu
+MHYwEAYHKoZIzj0CAQYFK4EEACIDYgAER0UOlvt9Xb/pOdEh+J8LttV7HpI6SFkc
+8GIxLcB6KP4ap1yztsyX50XUWPrRd21DosCHZTQKH3rd6zwzocWdTaRvQZU4f8ke
+hOvRnkmSh5SHDDqFSmafnVmTTZdhBoZKo0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYD
+VR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUPeYpSJvqB8ohREom3m7e0oPQn1kwCgYI
+KoZIzj0EAwMDaAAwZQIxAOVpEslu28YxuglB4Zf4+/2a4n0Sye18ZNPLBSWLVtmg
+515dTguDnFt2KaAJJiFqYgIwcdK1j1zqO+F4CYWodZI7yFz9SO8NdCKoCOJuxUnO
+xwy8p2Fp8fc74SrL+SvzZpA3
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIHSTCCBTGgAwIBAgIJAMnN0+nVfSPOMA0GCSqGSIb3DQEBBQUAMIGsMQswCQYD
+VQQGEwJFVTFDMEEGA1UEBxM6TWFkcmlkIChzZWUgY3VycmVudCBhZGRyZXNzIGF0
+IHd3dy5jYW1lcmZpcm1hLmNvbS9hZGRyZXNzKTESMBAGA1UEBRMJQTgyNzQzMjg3
+MRswGQYDVQQKExJBQyBDYW1lcmZpcm1hIFMuQS4xJzAlBgNVBAMTHkdsb2JhbCBD
+aGFtYmVyc2lnbiBSb290IC0gMjAwODAeFw0wODA4MDExMjMxNDBaFw0zODA3MzEx
+MjMxNDBaMIGsMQswCQYDVQQGEwJFVTFDMEEGA1UEBxM6TWFkcmlkIChzZWUgY3Vy
+cmVudCBhZGRyZXNzIGF0IHd3dy5jYW1lcmZpcm1hLmNvbS9hZGRyZXNzKTESMBAG
+A1UEBRMJQTgyNzQzMjg3MRswGQYDVQQKExJBQyBDYW1lcmZpcm1hIFMuQS4xJzAl
+BgNVBAMTHkdsb2JhbCBDaGFtYmVyc2lnbiBSb290IC0gMjAwODCCAiIwDQYJKoZI
+hvcNAQEBBQADggIPADCCAgoCggIBAMDfVtPkOpt2RbQT2//BthmLN0EYlVJH6xed
+KYiONWwGMi5HYvNJBL99RDaxccy9Wglz1dmFRP+RVyXfXjaOcNFccUMd2drvXNL7
+G706tcuto8xEpw2uIRU/uXpbknXYpBI4iRmKt4DS4jJvVpyR1ogQC7N0ZJJ0YPP2
+zxhPYLIj0Mc7zmFLmY/CDNBAspjcDahOo7kKrmCgrUVSY7pmvWjg+b4aqIG7HkF4
+ddPB/gBVsIdU6CeQNR1MM62X/JcumIS/LMmjv9GYERTtY/jKmIhYF5ntRQOXfjyG
+HoiMvvKRhI9lNNgATH23MRdaKXoKGCQwoze1eqkBfSbW+Q6OWfH9GzO1KTsXO0G2
+Id3UwD2ln58fQ1DJu7xsepeY7s2MH/ucUa6LcL0nn3HAa6x9kGbo1106DbDVwo3V
+yJ2dwW3Q0L9R5OP4wzg2rtandeavhENdk5IMagfeOx2YItaswTXbo6Al/3K1dh3e
+beksZixShNBFks4c5eUzHdwHU1SjqoI7mjcv3N2gZOnm3b2u/GSFHTynyQbehP9r
+6GsaPMWis0L7iwk+XwhSx2LE1AVxv8Rk5Pihg+g+EpuoHtQ2TS9x9o0o9oOpE9Jh
+wZG7SMA0j0GMS0zbaRL/UJScIINZc+18ofLx/d33SdNDWKBWY8o9PeU1VlnpDsog
+zCtLkykPAgMBAAGjggFqMIIBZjASBgNVHRMBAf8ECDAGAQH/AgEMMB0GA1UdDgQW
+BBS5CcqcHtvTbDprru1U8VuTBjUuXjCB4QYDVR0jBIHZMIHWgBS5CcqcHtvTbDpr
+ru1U8VuTBjUuXqGBsqSBrzCBrDELMAkGA1UEBhMCRVUxQzBBBgNVBAcTOk1hZHJp
+ZCAoc2VlIGN1cnJlbnQgYWRkcmVzcyBhdCB3d3cuY2FtZXJmaXJtYS5jb20vYWRk
+cmVzcykxEjAQBgNVBAUTCUE4Mjc0MzI4NzEbMBkGA1UEChMSQUMgQ2FtZXJmaXJt
+YSBTLkEuMScwJQYDVQQDEx5HbG9iYWwgQ2hhbWJlcnNpZ24gUm9vdCAtIDIwMDiC
+CQDJzdPp1X0jzjAOBgNVHQ8BAf8EBAMCAQYwPQYDVR0gBDYwNDAyBgRVHSAAMCow
+KAYIKwYBBQUHAgEWHGh0dHA6Ly9wb2xpY3kuY2FtZXJmaXJtYS5jb20wDQYJKoZI
+hvcNAQEFBQADggIBAICIf3DekijZBZRG/5BXqfEv3xoNa/p8DhxJJHkn2EaqbylZ
+UohwEurdPfWbU1Rv4WCiqAm57OtZfMY18dwY6fFn5a+6ReAJ3spED8IXDneRRXoz
+X1+WLGiLwUePmJs9wOzL9dWCkoQ10b42OFZyMVtHLaoXpGNR6woBrX/sdZ7LoR/x
+fxKxueRkf2fWIyr0uDldmOghp+G9PUIadJpwr2hsUF1Jz//7Dl3mLEfXgTpZALVz
+a2Mg9jFFCDkO9HB+QHBaP9BrQql0PSgvAm11cpUJjUhjxsYjV5KTXjXBjfkK9yyd
+Yhz2rXzdpjEetrHHfoUm+qRqtdpjMNHvkzeyZi99Bffnt0uYlDXA2TopwZ2yUDMd
+SqlapskD7+3056huirRXhOukP9DuqqqHW2Pok+JrqNS4cnhrG+055F3Lm6qH1U9O
+AP7Zap88MQ8oAgF9mOinsKJknnn4SPIVqczmyETrP3iZ8ntxPjzxmKfFGBI/5rso
+M0LpRQp8bfKGeS/Fghl9CYl8slR2iK7ewfPM4W7bMdaTrpmg7yVqc5iJWzouE4ge
+v8CSlDQb4ye3ix5vQv/n6TebUB0tovkC7stYWDpxvGjjqsGvHCgfotwjZT+B6q6Z
+09gwzxMNTxXJhLynSC34MCN32EZLeW32jO06f2ARePTpm67VVMB0gNELQp/B
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIF3zCCA8egAwIBAgIOGTMAAQACKBqaBLzyVUUwDQYJKoZIhvcNAQEFBQAwejEL
+MAkGA1UEBhMCREUxHDAaBgNVBAoTE1RDIFRydXN0Q2VudGVyIEdtYkgxJDAiBgNV
+BAsTG1RDIFRydXN0Q2VudGVyIFVuaXZlcnNhbCBDQTEnMCUGA1UEAxMeVEMgVHJ1
+c3RDZW50ZXIgVW5pdmVyc2FsIENBIElJMB4XDTA2MDMyMjE1NTgzNFoXDTMwMTIz
+MTIyNTk1OVowejELMAkGA1UEBhMCREUxHDAaBgNVBAoTE1RDIFRydXN0Q2VudGVy
+IEdtYkgxJDAiBgNVBAsTG1RDIFRydXN0Q2VudGVyIFVuaXZlcnNhbCBDQTEnMCUG
+A1UEAxMeVEMgVHJ1c3RDZW50ZXIgVW5pdmVyc2FsIENBIElJMIICIjANBgkqhkiG
+9w0BAQEFAAOCAg8AMIICCgKCAgEAi9R3azRs5TbYalxeOO781R15Azt7g2JEgk6I
+7d6D/+7MUGIFBZWZdpj2ufJf2AaRksL2LWYXH/1TA+iojWOpbuHWG4y8mLOLO9Tk
+Lsp9hUkmW3m4GotAnn+7yT9jLM/RWny6KCJBElpN+Rd3/IX9wkngKhh/6aAsnPlE
+/AxoOUL1JwW+jhV6YJ3wO8c85j4WvK923mq3ouGrRkXrjGV90ZfzlxElq1nroCLZ
+gt2Y7X7i+qBhCkoy3iwX921E6oFHWZdXNwM53V6CItQzuPomCba8OYgvURVOm8M7
+3xOCiN1LNPIz1pDp81PcNXzAw9l8eLPNcD+NauCjgUjkKa1juPD8KGQ7mbN9/pqd
+iPaZIgiRRxaJNXhdd6HPv0nh/SSUK2k2e+gc5iqQilvVOzRZQtxtz7sPQRxVzfUN
+Wy4WIibvYR6X/OJTyM9bo8ep8boOhhLLE8oVx+zkNo3aXBM9ZdIOXXB03L+PemrB
+Lg/Txl4PK1lszGFs/sBhTtnmT0ayWuIZFHCE+CAA7QGnl37DvRJckiMXoKUdRRcV
+I5qSCLUiiI3cKyTr4LEXaNOvYb3ZhXj2jbp4yjeNY77nrB/fpUcJucglMVRGURFV
+DYlcjdrSGC1z8rjVJ/VIIjfRYvd7Dcg4i6FKsPzQ8eu3hmPn4A5zf/1yUbXpfeJV
+BWR4Z38CAwEAAaNjMGEwHwYDVR0jBBgwFoAUzdeQoW6jv9sw1toyJZAM5jkegGUw
+DwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAYYwHQYDVR0OBBYEFM3XkKFu
+o7/bMNbaMiWQDOY5HoBlMA0GCSqGSIb3DQEBBQUAA4ICAQB+FojoEw42zG4qhQc4
+xlaJeuNHIWZMUAgxWlHQ/KZeFHXeTDvs8e3MfhEHSmHu6rOOOqQzxu2KQmZP8Tx7
+yaUFQZmx7Cxb7tyW0ohTS3g0uW7muw/FeqZ8Dhjfbw90TNGp8aHp2FRkzF6WeKJW
+GsFzshXGVwXf2vdIJIqOf2qp+U3pPmrOYCx9LZAI9mOPFdAtnIz/8f38DBZQVhT7
+upeG7rRJA1TuG1l/MDoCgoYhrv7wFfLfToPmmcW6NfcgkIw47XXP4S73BDD7Ua2O
+giRAyn0pXdXZ92Vk/KqfdLh9kl3ShCngE+qK99CrxK7vFcXCifJ7tjtJmGHzTnKR
+N4xJkunI7Cqg90lufA0kxmts8jgvynAF5X/fxisrgIDV2m/LQLvYG/AkyRDIRAJ+
+LtOYqqIN8SvQ2vqOHP9U6OFKbt2o1ni1N6WsZNUUI8cOpevhCTjXwHxgpV2Yj4wC
+1dxWqPNNWKkL1HxkdAEy8t8PSoqpAqKiHYR3wvHMl700GXRd4nQ+dSf3r7/ufA5t
+VIimVuImrTESPB5BeW0X6hNeH/Vcn0lZo7Ivo0LD+qh+v6WfSMlgYmIK371F3uNC
+tVGW/cT1Gpm4UqJEzS1hjBWPgdVdotSQPYxuQGHDWV3Y2eH2dEcieXR92sqjbzcV
+NvAsGnE8EXbfXRo+VGN4a2V+Hw==
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIF2TCCA8GgAwIBAgIQXAuFXAvnWUHfV8w/f52oNjANBgkqhkiG9w0BAQUFADBk
+MQswCQYDVQQGEwJjaDERMA8GA1UEChMIU3dpc3Njb20xJTAjBgNVBAsTHERpZ2l0
+YWwgQ2VydGlmaWNhdGUgU2VydmljZXMxGzAZBgNVBAMTElN3aXNzY29tIFJvb3Qg
+Q0EgMTAeFw0wNTA4MTgxMjA2MjBaFw0yNTA4MTgyMjA2MjBaMGQxCzAJBgNVBAYT
+AmNoMREwDwYDVQQKEwhTd2lzc2NvbTElMCMGA1UECxMcRGlnaXRhbCBDZXJ0aWZp
+Y2F0ZSBTZXJ2aWNlczEbMBkGA1UEAxMSU3dpc3Njb20gUm9vdCBDQSAxMIICIjAN
+BgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA0LmwqAzZuz8h+BvVM5OAFmUgdbI9
+m2BtRsiMMW8Xw/qabFbtPMWRV8PNq5ZJkCoZSx6jbVfd8StiKHVFXqrWW/oLJdih
+FvkcxC7mlSpnzNApbjyFNDhhSbEAn9Y6cV9Nbc5fuankiX9qUvrKm/LcqfmdmUc/
+TilftKaNXXsLmREDA/7n29uj/x2lzZAeAR81sH8A25Bvxn570e56eqeqDFdvpG3F
+EzuwpdntMhy0XmeLVNxzh+XTF3xmUHJd1BpYwdnP2IkCb6dJtDZd0KTeByy2dbco
+kdaXvij1mB7qWybJvbCXc9qukSbraMH5ORXWZ0sKbU/Lz7DkQnGMU3nn7uHbHaBu
+HYwadzVcFh4rUx80i9Fs/PJnB3r1re3WmquhsUvhzDdf/X/NTa64H5xD+SpYVUNF
+vJbNcA78yeNmuk6NO4HLFWR7uZToXTNShXEuT46iBhFRyePLoW4xCGQMwtI89Tbo
+19AOeCMgkckkKmUpWyL3Ic6DXqTz3kvTaI9GdVyDCW4pa8RwjPWd1yAv/0bSKzjC
+L3UcPX7ape8eYIVpQtPM+GP+HkM5haa2Y0EQs3MevNP6yn0WR+Kn1dCjigoIlmJW
+bjTb2QK5MHXjBNLnj8KwEUAKrNVxAmKLMb7dxiNYMUJDLXT5xp6mig/p/r+D5kNX
+JLrvRjSq1xIBOO0CAwEAAaOBhjCBgzAOBgNVHQ8BAf8EBAMCAYYwHQYDVR0hBBYw
+FDASBgdghXQBUwABBgdghXQBUwABMBIGA1UdEwEB/wQIMAYBAf8CAQcwHwYDVR0j
+BBgwFoAUAyUv3m+CATpcLNwroWm1Z9SM0/0wHQYDVR0OBBYEFAMlL95vggE6XCzc
+K6FptWfUjNP9MA0GCSqGSIb3DQEBBQUAA4ICAQA1EMvspgQNDQ/NwNurqPKIlwzf
+ky9NfEBWMXrrpA9gzXrzvsMnjgM+pN0S734edAY8PzHyHHuRMSG08NBsl9Tpl7Ik
+Vh5WwzW9iAUPWxAaZOHHgjD5Mq2eUCzneAXQMbFamIp1TpBcahQq4FJHgmDmHtqB
+sfsUC1rxn9KVuj7QG9YVHaO+htXbD8BJZLsuUBlL0iT43R4HVtA4oJVwIHaM190e
+3p9xxCPvgxNcoyQVTSlAPGrEqdi3pkSlDfTgnXceQHAm/NrZNuR55LU/vJtlvrsR
+ls/bxig5OgjOR1tTWsWZ/l2p3e9M1MalrQLmjAcSHm8D0W+go/MpvRLHUKKwf4ip
+mXeascClOS5cfGniLLDqN2qk4Vrh9VDlg++luyqI54zb/W1elxmofmZ1a3Hqv7HH
+b6D0jqTsNFFbjCYDcKF31QESVwA12yPeDooomf2xEG9L/zgtYE4snOtnta1J7ksf
+rK/7DZBaZmBwXarNeNQk7shBoJMBkpxqnvy5JMWzFYJ+vq6VK+uxwNrjAWALXmms
+hFZhvnEX/h0TD/7Gh0Xp/jKgGg0TpJRVcaUWi7rKibCyx/yP2FS1k2Kdzs9Z+z0Y
+zirLNRWCXf9UIltxUvu3yf5gmwBBZPCqKuy2QkPOiWaByIufOVQDJdMWNY6E0F/6
+MBr1mmz0DlP5OlvRHA==
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIEXjCCA0agAwIBAgIQRL4Mi1AAIbQR0ypoBqmtaTANBgkqhkiG9w0BAQUFADCB
+kzELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAlVUMRcwFQYDVQQHEw5TYWx0IExha2Ug
+Q2l0eTEeMBwGA1UEChMVVGhlIFVTRVJUUlVTVCBOZXR3b3JrMSEwHwYDVQQLExho
+dHRwOi8vd3d3LnVzZXJ0cnVzdC5jb20xGzAZBgNVBAMTElVUTiAtIERBVEFDb3Jw
+IFNHQzAeFw05OTA2MjQxODU3MjFaFw0xOTA2MjQxOTA2MzBaMIGTMQswCQYDVQQG
+EwJVUzELMAkGA1UECBMCVVQxFzAVBgNVBAcTDlNhbHQgTGFrZSBDaXR5MR4wHAYD
+VQQKExVUaGUgVVNFUlRSVVNUIE5ldHdvcmsxITAfBgNVBAsTGGh0dHA6Ly93d3cu
+dXNlcnRydXN0LmNvbTEbMBkGA1UEAxMSVVROIC0gREFUQUNvcnAgU0dDMIIBIjAN
+BgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA3+5YEKIrblXEjr8uRgnn4AgPLit6
+E5Qbvfa2gI5lBZMAHryv4g+OGQ0SR+ysraP6LnD43m77VkIVni5c7yPeIbkFdicZ
+D0/Ww5y0vpQZY/KmEQrrU0icvvIpOxboGqBMpsn0GFlowHDyUwDAXlCCpVZvNvlK
+4ESGoE1O1kduSUrLZ9emxAW5jh70/P/N5zbgnAVssjMiFdC04MwXwLLA9P4yPykq
+lXvY8qdOD1R8oQ2AswkDwf9c3V6aPryuvEeKaq5xyh+xKrhfQgUL7EYw0XILyulW
+bfXv33i+Ybqypa4ETLyorGkVl73v67SMvzX41MPRKA5cOp9wGDMgd8SirwIDAQAB
+o4GrMIGoMAsGA1UdDwQEAwIBxjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBRT
+MtGzz3/64PGgXYVOktKeRR20TzA9BgNVHR8ENjA0MDKgMKAuhixodHRwOi8vY3Js
+LnVzZXJ0cnVzdC5jb20vVVROLURBVEFDb3JwU0dDLmNybDAqBgNVHSUEIzAhBggr
+BgEFBQcDAQYKKwYBBAGCNwoDAwYJYIZIAYb4QgQBMA0GCSqGSIb3DQEBBQUAA4IB
+AQAnNZcAiosovcYzMB4p/OL31ZjUQLtgyr+rFywJNn9Q+kHcrpY6CiM+iVnJowft
+Gzet/Hy+UUla3joKVAgWRcKZsYfNjGjgaQPpxE6YsjuMFrMOoAyYUJuTqXAJyCyj
+j98C5OBxOvG0I3KgqgHf35g+FFCgMSa9KOlaMCZ1+XtgHI3zzVAmbQQnmt/VDUVH
+KWss5nbZqSl9Mt3JNjy9rjXxEZ4du5A/EkdOjtd+D2JzHVImOBwYSf0wdJrE5SIv
+2MCN7ZF6TACPcn9d2t0bi0Vr591pl6jFVkwPDPafepE39peC4N1xaf92P2BNPM/3
+mfnGV/TJVTl4uix5yaaIK/QI
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIEBDCCAuygAwIBAgIIGHqpqMKWIQwwDQYJKoZIhvcNAQELBQAwYjELMAkGA1UE
+BhMCVVMxEzARBgNVBAoTCkFwcGxlIEluYy4xJjAkBgNVBAsTHUFwcGxlIENlcnRp
+ZmljYXRpb24gQXV0aG9yaXR5MRYwFAYDVQQDEw1BcHBsZSBSb290IENBMB4XDTEy
+MDIwMTIyMTIxNVoXDTI3MDIwMTIyMTIxNVoweTEtMCsGA1UEAwwkRGV2ZWxvcGVy
+IElEIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MSYwJAYDVQQLDB1BcHBsZSBDZXJ0
+aWZpY2F0aW9uIEF1dGhvcml0eTETMBEGA1UECgwKQXBwbGUgSW5jLjELMAkGA1UE
+BhMCVVMwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCJdk8GW5pB7qUj
+KwKjX9dzP8A1sIuECj8GJH+nlT/rTw6Tr7QO0Mg+5W0Ysx/oiUe/1wkI5P9WmCkV
+55SduTWjCs20wOHiYPTK7Cl4RWlpYGtfipL8niPmOsIiszFPHLrytjRZQu6wqQID
+GJEEtrN4LjMfgEUNRW+7Dlpbfzrn2AjXCw4ybfuGNuRsq8QRinCEJqqfRNHxuMZ7
+lBebSPcLWBa6I8WfFTl+yl3DMl8P4FJ/QOq+rAhklVvJGpzlgMofakQcbD7EsCYf
+Hex7r16gaj1HqVgSMT8gdihtHRywwk4RaSaLy9bQEYLJTg/xVnTQ2QhLZniiq6yn
+4tJMh1nJAgMBAAGjgaYwgaMwHQYDVR0OBBYEFFcX7aLP3HyYoRDg/L6HLSzy4xdU
+MA8GA1UdEwEB/wQFMAMBAf8wHwYDVR0jBBgwFoAUK9BpR5R2Cf70a40uQKb3R01/
+CF4wLgYDVR0fBCcwJTAjoCGgH4YdaHR0cDovL2NybC5hcHBsZS5jb20vcm9vdC5j
+cmwwDgYDVR0PAQH/BAQDAgGGMBAGCiqGSIb3Y2QGAgYEAgUAMA0GCSqGSIb3DQEB
+CwUAA4IBAQBCOXRrodzGpI83KoyzHQpEvJUsf7xZuKxh+weQkjK51L87wVA5akR0
+ouxbH3Dlqt1LbBwjcS1f0cWTvu6binBlgp0W4xoQF4ktqM39DHhYSQwofzPuAHob
+tHastrW7T9+oG53IGZdKC1ZnL8I+trPEgzrwd210xC4jUe6apQNvYPSlSKcGwrta
+4h8fRkV+5Jf1JxC3ICJyb3LaxlB1xT0lj12jAOmfNoxIOY+zO+qQgC6VmmD0eM70
+DgpTPqL6T9geroSVjTK8Vk2J6XgY4KyaQrp6RhuEoonOFOiI0ViL9q5WxCwFKkWv
+C9lLqQIPNKyIx2FViUTJJ3MH7oLlTvVw
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIEvTCCA6WgAwIBAgIBATANBgkqhkiG9w0BAQUFADCBhTELMAkGA1UEBhMCVVMx
+IDAeBgNVBAoMF1dlbGxzIEZhcmdvIFdlbGxzU2VjdXJlMRwwGgYDVQQLDBNXZWxs
+cyBGYXJnbyBCYW5rIE5BMTYwNAYDVQQDDC1XZWxsc1NlY3VyZSBQdWJsaWMgUm9v
+dCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkwHhcNMDcxMjEzMTcwNzU0WhcNMjIxMjE0
+MDAwNzU0WjCBhTELMAkGA1UEBhMCVVMxIDAeBgNVBAoMF1dlbGxzIEZhcmdvIFdl
+bGxzU2VjdXJlMRwwGgYDVQQLDBNXZWxscyBGYXJnbyBCYW5rIE5BMTYwNAYDVQQD
+DC1XZWxsc1NlY3VyZSBQdWJsaWMgUm9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkw
+ggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDub7S9eeKPCCGeOARBJe+r
+WxxTkqxtnt3CxC5FlAM1iGd0V+PfjLindo8796jE2yljDpFoNoqXjopxaAkH5OjU
+Dk/41itMpBb570OYj7OeUt9tkTmPOL13i0Nj67eT/DBMHAGTthP796EfvyXhdDcs
+HqRePGj4S78NuR4uNuip5Kf4D8uCdXw1LSLWwr8L87T8bJVhHlfXBIEyg1J55oNj
+z7fLY4sR4r1e6/aN7ZVyKLSsEmLpSjPmgzKuBXWVvYSV2ypcm44uDLiBK0HmOFaf
+SZtsdvqKXfcBeYF8wYNABf5x/Qw/zE5gCQ5lRxAvAcAFP4/4s0HvWkJ+We/Slwxl
+AgMBAAGjggE0MIIBMDAPBgNVHRMBAf8EBTADAQH/MDkGA1UdHwQyMDAwLqAsoCqG
+KGh0dHA6Ly9jcmwucGtpLndlbGxzZmFyZ28uY29tL3dzcHJjYS5jcmwwDgYDVR0P
+AQH/BAQDAgHGMB0GA1UdDgQWBBQmlRkQ2eihl5H/3BnZtQQ+0nMKajCBsgYDVR0j
+BIGqMIGngBQmlRkQ2eihl5H/3BnZtQQ+0nMKaqGBi6SBiDCBhTELMAkGA1UEBhMC
+VVMxIDAeBgNVBAoMF1dlbGxzIEZhcmdvIFdlbGxzU2VjdXJlMRwwGgYDVQQLDBNX
+ZWxscyBGYXJnbyBCYW5rIE5BMTYwNAYDVQQDDC1XZWxsc1NlY3VyZSBQdWJsaWMg
+Um9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHmCAQEwDQYJKoZIhvcNAQEFBQADggEB
+ALkVsUSRzCPIK0134/iaeycNzXK7mQDKfGYZUMbVmO2rvwNa5U3lHshPcZeG1eMd
+/ZDJPHV3V3p9+N701NX3leZ0bh08rnyd2wIDBSxxSyU+B+NemvVmFymIGjifz6pB
+A4SXa5M4esowRBskRDPQ5NHcKDj0E0M1NSljqHyita04pO2t/caaH/+Xc/77szWn
+k4bGdpEA5qxRFsQnMlzbc9qlk1eOPm01JghZ1edE13YgY+esE2fDbbFwRnzVlhE9
+iW9dqKHrjQrawx0zbKPqZxmamX9LPYNRKh3KL4YMon4QLSvUFpULB6ouFJJJtylv
+2G0xffX8oRAHh84vWdw+WNs=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIICqDCCAi2gAwIBAgIQIW4zpcvTiKRvKQe0JzzE2DAKBggqhkjOPQQDAzCBlDEL
+MAkGA1UEBhMCVVMxHTAbBgNVBAoTFFN5bWFudGVjIENvcnBvcmF0aW9uMR8wHQYD
+VQQLExZTeW1hbnRlYyBUcnVzdCBOZXR3b3JrMUUwQwYDVQQDEzxTeW1hbnRlYyBD
+bGFzcyAxIFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IC0g
+RzQwHhcNMTExMDA1MDAwMDAwWhcNMzgwMTE4MjM1OTU5WjCBlDELMAkGA1UEBhMC
+VVMxHTAbBgNVBAoTFFN5bWFudGVjIENvcnBvcmF0aW9uMR8wHQYDVQQLExZTeW1h
+bnRlYyBUcnVzdCBOZXR3b3JrMUUwQwYDVQQDEzxTeW1hbnRlYyBDbGFzcyAxIFB1
+YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IC0gRzQwdjAQBgcq
+hkjOPQIBBgUrgQQAIgNiAATXZrUb266zYO5G6ohjdTsqlG3zXxL24w+etgoUU0hS
+yNw6s8tIICYSTvqJhNTfkeQpfSgB2dsYQ2mhH7XThhbcx39nI9/fMTGDAzVwsUu3
+yBe7UcvclBfb6gk7dhLeqrWjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8E
+BTADAQH/MB0GA1UdDgQWBBRlwI0l9Qy6l3eQP54u4Fr1ztXh5DAKBggqhkjOPQQD
+AwNpADBmAjEApa7jRlP4mDbjIvouKEkN7jB+M/PsP3FezFWJeJmssv3cHFwzjim5
+axfIEWi13IMHAjEAnMhE2mnCNsNUGRCFAtqdR+9B52wmnQk9922Q0QVEL7C8g5No
+8gxFSTm/mQQc0xCg
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIID3TCCAsWgAwIBAgIOHaIAAQAC7LdggHiNtgYwDQYJKoZIhvcNAQEFBQAweTEL
+MAkGA1UEBhMCREUxHDAaBgNVBAoTE1RDIFRydXN0Q2VudGVyIEdtYkgxJDAiBgNV
+BAsTG1RDIFRydXN0Q2VudGVyIFVuaXZlcnNhbCBDQTEmMCQGA1UEAxMdVEMgVHJ1
+c3RDZW50ZXIgVW5pdmVyc2FsIENBIEkwHhcNMDYwMzIyMTU1NDI4WhcNMjUxMjMx
+MjI1OTU5WjB5MQswCQYDVQQGEwJERTEcMBoGA1UEChMTVEMgVHJ1c3RDZW50ZXIg
+R21iSDEkMCIGA1UECxMbVEMgVHJ1c3RDZW50ZXIgVW5pdmVyc2FsIENBMSYwJAYD
+VQQDEx1UQyBUcnVzdENlbnRlciBVbml2ZXJzYWwgQ0EgSTCCASIwDQYJKoZIhvcN
+AQEBBQADggEPADCCAQoCggEBAKR3I5ZEr5D0MacQ9CaHnPM42Q9e3s9B6DGtxnSR
+JJZ4Hgmgm5qVSkr1YnwCqMqs+1oEdjneX/H5s7/zA1hV0qq34wQi0fiU2iIIAI3T
+fCZdzHd55yx4Oagmcw6iXSVphU9VDprvxrlE4Vc93x9UIuVvZaozhDrzznq+VZeu
+jRIPFDPiUHDDSYcTvFHe15gSWu86gzOSBnWLknwSaHtwag+1m7Z3W0hZneTvWq3z
+wZ7U10VOylY0Ibw+F1tvdwxIAUMpsN0/lm7mlaoMwCC2/T42J5zjXM9OgdwZu5GQ
+fezmlwQek8wiSdeXhrYTCjxDI3d+8NzmzSQfO4ObNDqDNOMCAwEAAaNjMGEwHwYD
+VR0jBBgwFoAUkqR1LKSevoFE63n8isWVpesQdXMwDwYDVR0TAQH/BAUwAwEB/zAO
+BgNVHQ8BAf8EBAMCAYYwHQYDVR0OBBYEFJKkdSyknr6BROt5/IrFlaXrEHVzMA0G
+CSqGSIb3DQEBBQUAA4IBAQAo0uCG1eb4e/CX3CJrO5UUVg8RMKWaTzqwOuAGy2X1
+7caXJ/4l8lfmXpWMPmRgFVp/Lw0BxbFg/UU1z/CyvwbZ71q+s2IhtNerNXxTPqYn
+8aEt2hojnczd7Dwtnic0XQ/CNnm8yUpiLe1r2X1BQ3y2qsrtYbE3ghUJGooWMNjs
+ydZHcnhLEEYUjl8Or+zHL6sQ17bxbuyGssLoDZJz3KL0Dzq/YSMQiZxIQG5wALPT
+ujdEWBF6AmqI8Dc08BnprNRlc/ZpjGSUOnmFKbAWKwyCPwacx/0QK54PLLae4xW/
+2TYcuiUaUj0a7CIMHOCkoj3w6DnPgcB77V0fb8XQC9eY
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIDtjCCAp6gAwIBAgIOBcAAAQACQdAGCk3OdRAwDQYJKoZIhvcNAQEFBQAwdjEL
+MAkGA1UEBhMCREUxHDAaBgNVBAoTE1RDIFRydXN0Q2VudGVyIEdtYkgxIjAgBgNV
+BAsTGVRDIFRydXN0Q2VudGVyIENsYXNzIDQgQ0ExJTAjBgNVBAMTHFRDIFRydXN0
+Q2VudGVyIENsYXNzIDQgQ0EgSUkwHhcNMDYwMzIzMTQxMDIzWhcNMjUxMjMxMjI1
+OTU5WjB2MQswCQYDVQQGEwJERTEcMBoGA1UEChMTVEMgVHJ1c3RDZW50ZXIgR21i
+SDEiMCAGA1UECxMZVEMgVHJ1c3RDZW50ZXIgQ2xhc3MgNCBDQTElMCMGA1UEAxMc
+VEMgVHJ1c3RDZW50ZXIgQ2xhc3MgNCBDQSBJSTCCASIwDQYJKoZIhvcNAQEBBQAD
+ggEPADCCAQoCggEBALXNTJytrlG7fEjFDSmGehSt2VA9CXIgDRS2Y8b+WJ7gIV7z
+jyIZ3E6RIM1viCmis8GsKnK6i1S4QF/yqvhDhsIwXMynXX/GCEnkDjkvjhjWkd0j
+FnmA22xIHbzB3ygQY9GB493fL3l1oht48pQB5hBiecugfQLANIJ7x8CtHUzXapZ2
+W78mhEj9h/aECqqSB5lIPGG8ToVYx5ct/YFKocabEvVCUNFkPologiJw3fX64yhC
+L04y87OjNopq1mJcrPoBbbTgci6VaLTxkwzGioLSHVPqfOA/QrcSWrjN2qUGZ8uh
+d32llvCSHmcOHUJG5vnt+0dTf1cERh9GX8eu4I8CAwEAAaNCMEAwDwYDVR0TAQH/
+BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAYYwHQYDVR0OBBYEFB/quz4lGwa9pd1iBX7G
+TFq/6A9DMA0GCSqGSIb3DQEBBQUAA4IBAQBYpCubTPfkpJKknGWYGWIi/HIy6QRd
+xMRwLVpG3kxHiiW5ot3u6hKvSI3vK2fbO8w0mCr3CEf/Iq978fTr4jgCMxh1KBue
+dmWsiANy8jhHHYz1nwqIUxAUu4DlDLNdjRfuHhkcho0UZ3iMksseIUn3f9MYv5x5
++F0IebWqak2SNmy8eesOPXmK2PajVnBd3ttPedJ60pVchidlvqDTB4FAVd0Qy+BL
+iILAkH0457+W4Ze6mqtCD9Of2J4VMxHL94J59bXAQVaS4d9VA61Iz9PyLrHHLVZM
+ZHQqMc7cdalUR6SnQnIJ5+ECpkeyBM1CE+FhDOB4OiIgohxgQoaH96Xm
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIEGDCCAwCgAwIBAgIBATANBgkqhkiG9w0BAQUFADBlMQswCQYDVQQGEwJTRTEU
+MBIGA1UEChMLQWRkVHJ1c3QgQUIxHTAbBgNVBAsTFEFkZFRydXN0IFRUUCBOZXR3
+b3JrMSEwHwYDVQQDExhBZGRUcnVzdCBDbGFzcyAxIENBIFJvb3QwHhcNMDAwNTMw
+MTAzODMxWhcNMjAwNTMwMTAzODMxWjBlMQswCQYDVQQGEwJTRTEUMBIGA1UEChML
+QWRkVHJ1c3QgQUIxHTAbBgNVBAsTFEFkZFRydXN0IFRUUCBOZXR3b3JrMSEwHwYD
+VQQDExhBZGRUcnVzdCBDbGFzcyAxIENBIFJvb3QwggEiMA0GCSqGSIb3DQEBAQUA
+A4IBDwAwggEKAoIBAQCWltQhSWDia+hBBwzexODcEyPNwTXH+9ZOEQpnXvUGW2ul
+CDtbKRY654eyNAbFvAWlA3yCyykQruGIgb3WntP+LVbBFc7jJp0VLhD7Bo8wBN6n
+tGO0/7Gcrjyvd7ZWxbWroulpOj0OM3kyP3CCkplhbY0wCI9xP6ZIVxn4JdxLZlyl
+dI+Yrsj5wAYi56xz36Uu+1LcsRVlIPo1Zmne3yzxbrww2ywkEtvrNTVokMsAsJch
+PXQhI2U0K7t4WaPW4XY5mqRJjox0r26kmqPZm9I4XJuiGMx1I4S+6+JNM3GOGvDC
++Mcdoq0Dlyz4zyXG9rgkMbFjXZJ/Y/AlyVMuH79NAgMBAAGjgdIwgc8wHQYDVR0O
+BBYEFJWxtPCUtr3H2tERCSG+wa9J/RB7MAsGA1UdDwQEAwIBBjAPBgNVHRMBAf8E
+BTADAQH/MIGPBgNVHSMEgYcwgYSAFJWxtPCUtr3H2tERCSG+wa9J/RB7oWmkZzBl
+MQswCQYDVQQGEwJTRTEUMBIGA1UEChMLQWRkVHJ1c3QgQUIxHTAbBgNVBAsTFEFk
+ZFRydXN0IFRUUCBOZXR3b3JrMSEwHwYDVQQDExhBZGRUcnVzdCBDbGFzcyAxIENB
+IFJvb3SCAQEwDQYJKoZIhvcNAQEFBQADggEBACxtZBsfzQ3duQH6lmM0MkhHma6X
+7f1yFqZzR1r0693p9db7RcwpiURdv0Y5PejuvE1Uhh4dbOMXJ0PhiVYrqW9yTkkz
+43J8KiOavD7/KCrto/8cI7pDVwlnTUtiBi34/2ydYB7YHEt9tTEv2dB8Xfjea4MY
+eDdXL+gzB2ffHsdrKpV2ro9Xo/D0UrSpUwjP4E/TelOL/bscVjby/rK25Xa71SJl
+pz/+0WatC7xrmYbvP33zGDLKe8bjq2RGlfgmadlVg3sslgf/WSxEo8bl6ancoWOA
+WiFeIc9TVPC6b4nbqKqVz4vjccweGyBECMB6tkD9xOQ14R0WHNC8K47Wcdk=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIDpDCCAoygAwIBAgIBATANBgkqhkiG9w0BAQUFADBjMQswCQYDVQQGEwJVUzEc
+MBoGA1UEChMTQW1lcmljYSBPbmxpbmUgSW5jLjE2MDQGA1UEAxMtQW1lcmljYSBP
+bmxpbmUgUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAxMB4XDTAyMDUyODA2
+MDAwMFoXDTM3MTExOTIwNDMwMFowYzELMAkGA1UEBhMCVVMxHDAaBgNVBAoTE0Ft
+ZXJpY2EgT25saW5lIEluYy4xNjA0BgNVBAMTLUFtZXJpY2EgT25saW5lIFJvb3Qg
+Q2VydGlmaWNhdGlvbiBBdXRob3JpdHkgMTCCASIwDQYJKoZIhvcNAQEBBQADggEP
+ADCCAQoCggEBAKgv6KRpBgNHw+kqmP8ZonCaxlCyfqXfaE0bfA+2l2h9LaaLl+lk
+hsmj76CGv2BlnEtUiMJIxUo5vxTjWVXlGbR0yLQFOVwWpeKVBeASrlmLojNoWBym
+1BW32J/X3HGrfpq/m44zDyL9Hy7nBzbvYjnF3cu6JRQj3gzGPTzOggjmZj7aUTsW
+OqMFf6Dch9Wc/HKpoH145LcxVR5lu9RhsCFg7RAycsWSJR74kEoYeEfffjA3PlAb
+2xzTa5qGUwew76wGePiEmf4hjUyAtgyC9mZweRrTT6PP8c9GsEsPPt2IYriMqQko
+O3rHl+Ee5fSfwMCuJKDIodkP1nsmgmkyPacCAwEAAaNjMGEwDwYDVR0TAQH/BAUw
+AwEB/zAdBgNVHQ4EFgQUAK3Zo/Z59m50qX8zPYEX10zPM94wHwYDVR0jBBgwFoAU
+AK3Zo/Z59m50qX8zPYEX10zPM94wDgYDVR0PAQH/BAQDAgGGMA0GCSqGSIb3DQEB
+BQUAA4IBAQB8itEfGDeC4Liwo+1WlchiYZwFos3CYiZhzRAW18y0ZTTQEYqtqKkF
+Zu90821fnZmv9ov761KyBZiibyrFVL0lvV+uyIbqRizBs73B6UlwGBaXCBOMIOAb
+LjpHyx7kADCVW/RFo8AasAFOq73AI25jP4BKxQft3OJvx8Fi8eNy1gTIdGcL+oir
+oQHIb/AUr9KZzVGTfu0uOMe9zkZQPXLjeSWdm4grECDdpbgyn43gKd8hdIaC2y+C
+MMbHNYaz+ZZfRtsMRf3zUMNvxsNIrUam4SdHCh0Om7bCd39j8uB9Gr784N/Xx6ds
+sPmuujz9dLQR6FgNgLzTqIA6me11zEZ7
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIFkDCCA3igAwIBAgIQBZsbV56OITLiOQe9p3d1XDANBgkqhkiG9w0BAQwFADBi
+MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3
+d3cuZGlnaWNlcnQuY29tMSEwHwYDVQQDExhEaWdpQ2VydCBUcnVzdGVkIFJvb3Qg
+RzQwHhcNMTMwODAxMTIwMDAwWhcNMzgwMTE1MTIwMDAwWjBiMQswCQYDVQQGEwJV
+UzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQu
+Y29tMSEwHwYDVQQDExhEaWdpQ2VydCBUcnVzdGVkIFJvb3QgRzQwggIiMA0GCSqG
+SIb3DQEBAQUAA4ICDwAwggIKAoICAQC/5pBzaN675F1KPDAiMGkz7MKnJS7JIT3y
+ithZwuEppz1Yq3aaza57G4QNxDAf8xukOBbrVsaXbR2rsnnyyhHS5F/WBTxSD1If
+xp4VpX6+n6lXFllVcq9ok3DCsrp1mWpzMpTREEQQLt+C8weE5nQ7bXHiLQwb7iDV
+ySAdYyktzuxeTsiT+CFhmzTrBcZe7FsavOvJz82sNEBfsXpm7nfISKhmV1efVFiO
+DCu3T6cw2Vbuyntd463JT17lNecxy9qTXtyOj4DatpGYQJB5w3jHtrHEtWoYOAMQ
+jdjUN6QuBX2I9YI+EJFwq1WCQTLX2wRzKm6RAXwhTNS8rhsDdV14Ztk6MUSaM0C/
+CNdaSaTC5qmgZ92kJ7yhTzm1EVgX9yRcRo9k98FpiHaYdj1ZXUJ2h4mXaXpI8OCi
+EhtmmnTK3kse5w5jrubU75KSOp493ADkRSWJtppEGSt+wJS00mFt6zPZxd9LBADM
+fRyVw4/3IbKyEbe7f/LVjHAsQWCqsWMYRJUadmJ+9oCw++hkpjPRiQfhvbfmQ6QY
+uKZ3AeEPlAwhHbJUKSWJbOUOUlFHdL4mrLZBdd56rF+NP8m800ERElvlEFDrMcXK
+chYiCd98THU/Y+whX8QgUWtvsauGi0/C1kVfnSD8oR7FwI+isX4KJpn15GkvmB0t
+9dmpsh3lGwIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIB
+hjAdBgNVHQ4EFgQU7NfjgtJxXWRM3y5nP+e6mK4cD08wDQYJKoZIhvcNAQEMBQAD
+ggIBALth2X2pbL4XxJEbw6GiAI3jZGgPVs93rnD5/ZpKmbnJeFwMDF/k5hQpVgs2
+SV1EY+CtnJYYZhsjDT156W1r1lT40jzBQ0CuHVD1UvyQO7uYmWlrx8GnqGikJ9yd
++SeuMIW59mdNOj6PWTkiU0TryF0Dyu1Qen1iIQqAyHNm0aAFYF/opbSnr6j3bTWc
+fFqK1qI4mfN4i/RN0iAL3gTujJtHgXINwBQy7zBZLq7gcfJW5GqXb5JQbZaNaHqa
+sjYUegbyJLkJEVDXCLG4iXqEI2FCKeWjzaIgQdfRnGTZ6iahixTXTBmyUEFxPT9N
+cCOGDErcgdLMMpSEDQgJlxxPwO5rIHQw0uA5NBCFIRUBCOhVMt5xSdkoF1BN5r5N
+0XWs0Mr7QbhDparTwwVETyw2m+L64kW4I1NsBm9nVX9GtUw/bihaeSbSpKhil9Ie
+4u1Ki7wb/UdKDd9nZn6yW0HQO+T0O/QEY+nvwlQAUaCKKsnOeMzV6ocEGLPOr0mI
+r/OSmbaz5mEP0oUA51Aa5BuVnRmhuZyxm7EAHu/QD09CbMkKvO5D+jpxpchNJqU1
+/YldvIViHTLSoCtU7ZpXwdv6EM8Zt4tKG48BtieVU+i2iW1bvGjUI+iLUaJW+fCm
+gKDWHrO8Dw9TdSmq6hN35N6MgSGtBxBHEa2HPQfRdbzP82Z+
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIEuzCCA6OgAwIBAgIBAjANBgkqhkiG9w0BAQUFADBiMQswCQYDVQQGEwJVUzET
+MBEGA1UEChMKQXBwbGUgSW5jLjEmMCQGA1UECxMdQXBwbGUgQ2VydGlmaWNhdGlv
+biBBdXRob3JpdHkxFjAUBgNVBAMTDUFwcGxlIFJvb3QgQ0EwHhcNMDYwNDI1MjE0
+MDM2WhcNMzUwMjA5MjE0MDM2WjBiMQswCQYDVQQGEwJVUzETMBEGA1UEChMKQXBw
+bGUgSW5jLjEmMCQGA1UECxMdQXBwbGUgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkx
+FjAUBgNVBAMTDUFwcGxlIFJvb3QgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAw
+ggEKAoIBAQDkkakJH5HbHkdQ6wXtXnmELes2oldMVeyLGYne+Uts9QerIjAC6Bg+
++FAJ039BqJj50cpmnCRrEdCju+QbKsMflZ56DKRHi1vUFjczy8QPTc4UadHJGXL1
+XQ7Vf1+b8iUDulWPTV0N8WQ1IxVLFVkds5T39pyez1C6wVhQZ48ItCD3y6wsIG9w
+tj8BMIy3Q88PnT3zK0koGsj+zrW5DtleHNbLPbU6rfQPDgCSC7EhFi501TwN22IW
+q6NxkkdTVcGvL0Gz+PvjcM3mo0xFfh9Ma1CWQYnEdGILEINBhzOKgbEwWOxaBDKM
+aLOPHd5lc/9nXmW8Sdh2nzMUZaF3lMktAgMBAAGjggF6MIIBdjAOBgNVHQ8BAf8E
+BAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUK9BpR5R2Cf70a40uQKb3
+R01/CF4wHwYDVR0jBBgwFoAUK9BpR5R2Cf70a40uQKb3R01/CF4wggERBgNVHSAE
+ggEIMIIBBDCCAQAGCSqGSIb3Y2QFATCB8jAqBggrBgEFBQcCARYeaHR0cHM6Ly93
+d3cuYXBwbGUuY29tL2FwcGxlY2EvMIHDBggrBgEFBQcCAjCBthqBs1JlbGlhbmNl
+IG9uIHRoaXMgY2VydGlmaWNhdGUgYnkgYW55IHBhcnR5IGFzc3VtZXMgYWNjZXB0
+YW5jZSBvZiB0aGUgdGhlbiBhcHBsaWNhYmxlIHN0YW5kYXJkIHRlcm1zIGFuZCBj
+b25kaXRpb25zIG9mIHVzZSwgY2VydGlmaWNhdGUgcG9saWN5IGFuZCBjZXJ0aWZp
+Y2F0aW9uIHByYWN0aWNlIHN0YXRlbWVudHMuMA0GCSqGSIb3DQEBBQUAA4IBAQBc
+NplMLXi37Yyb3PN3m/J20ncwT8EfhYOFG5k9RzfyqZtAjizUsZAS2L70c5vu0mQP
+y3lPNNiiPvl4/2vIB+x9OYOLUyDTOMSxv5pPCmv/K/xZpwUJfBdAVhEedNO3iyM7
+R6PVbyTi69G3cN8PReEnyvFteO3ntRcXqNx+IjXKJdXZD9Zr1KIkIxH3oayPc4Fg
+xhtbCS+SsvhESPBgOJ4V9T0mZyCKM2r3DYLP3uujL/lTaltkwGMzd/c6ByxW69oP
+IQ7aunMZT7XZNn/Bh1XZp5m5MkL72NVxnn6hUrcbvZNCJBIqxw8dtk2cXmPIS4AX
+UKqK1drk/NAJBzewdXUh
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIID9zCCAt+gAwIBAgIESJ8AATANBgkqhkiG9w0BAQUFADCBijELMAkGA1UEBhMC
+Q04xMjAwBgNVBAoMKUNoaW5hIEludGVybmV0IE5ldHdvcmsgSW5mb3JtYXRpb24g
+Q2VudGVyMUcwRQYDVQQDDD5DaGluYSBJbnRlcm5ldCBOZXR3b3JrIEluZm9ybWF0
+aW9uIENlbnRlciBFViBDZXJ0aWZpY2F0ZXMgUm9vdDAeFw0xMDA4MzEwNzExMjVa
+Fw0zMDA4MzEwNzExMjVaMIGKMQswCQYDVQQGEwJDTjEyMDAGA1UECgwpQ2hpbmEg
+SW50ZXJuZXQgTmV0d29yayBJbmZvcm1hdGlvbiBDZW50ZXIxRzBFBgNVBAMMPkNo
+aW5hIEludGVybmV0IE5ldHdvcmsgSW5mb3JtYXRpb24gQ2VudGVyIEVWIENlcnRp
+ZmljYXRlcyBSb290MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAm35z
+7r07eKpkQ0H1UN+U8i6yjUqORlTSIRLIOTJCBumD1Z9S7eVnAztUwYyZmczpwA//
+DdmEEbK40ctb3B75aDFk4Zv6dOtouSCV98YPjUesWgbdYavi7NifFy2cyjw1l1Vx
+zUOFsUcW9SxTgHbP0wBkvUCZ3czY28Sf1hNfQYOL+Q2HklY0bBoQCxfVWhyXWIQ8
+hBouXJE0bhlffxdpxWXvayHG1VA6v2G5BY3vbzQ6sm8UY78WO5upKv23KzhmBsUs
+4qpnHkWnjQRmQvaPK++IIGmPMowUc9orhpFjIpryp9vOiYurXccUwVswah+xt54u
+gQEC7c+WXmPbqOY4twIDAQABo2MwYTAfBgNVHSMEGDAWgBR8cks5x8DbYqVPm6oY
+NJKiyoOCWTAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4E
+FgQUfHJLOcfA22KlT5uqGDSSosqDglkwDQYJKoZIhvcNAQEFBQADggEBACrDx0M3
+j92tpLIM7twUbY8opJhJywyA6vPtI2Z1fcXTIWd50XPFtQO3WKwMVC/GVhMPMdoG
+52U7HW8228gd+f2ABsqjPWYWqJ1MFn3AlUa1UeTiH9fqBk1jjZaM7+czV0I664zB
+echNdn3e9rG3geCg+aF4RhcaVpjwTj2rHO3sOdwHSPdj/gauwqRcalsyiMXHM4Ws
+ZkJHwlgkmeHlPuV1LI5D1l08eB6olYIpUNHRFrrvwb562bTYzB5MRuF3sTGrvSrI
+zo9uoV1/A3U05K2JRVRevq4opbs/eHnrc7MKDf2+yfdWrPa37S+bISnHOLaVxATy
+wy39FCqQmbkHzJ8=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIFtzCCA5+gAwIBAgICBQkwDQYJKoZIhvcNAQEFBQAwRTELMAkGA1UEBhMCQk0x
+GTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxGzAZBgNVBAMTElF1b1ZhZGlzIFJv
+b3QgQ0EgMjAeFw0wNjExMjQxODI3MDBaFw0zMTExMjQxODIzMzNaMEUxCzAJBgNV
+BAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBMaW1pdGVkMRswGQYDVQQDExJRdW9W
+YWRpcyBSb290IENBIDIwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCa
+GMpLlA0ALa8DKYrwD4HIrkwZhR0In6spRIXzL4GtMh6QRr+jhiYaHv5+HBg6XJxg
+Fyo6dIMzMH1hVBHL7avg5tKifvVrbxi3Cgst/ek+7wrGsxDp3MJGF/hd/aTa/55J
+WpzmM+Yklvc/ulsrHHo1wtZn/qtmUIttKGAr79dgw8eTvI02kfN/+NsRE8Scd3bB
+rrcCaoF6qUWD4gXmuVbBlDePSHFjIuwXZQeVikvfj8ZaCuWw419eaxGrDPmF60Tp
++ARz8un+XJiM9XOva7R+zdRcAitMOeGylZUtQofX1bOQQ7dsE/He3fbE+Ik/0XX1
+ksOR1YqI0JDs3G3eicJlcZaLDQP9nL9bFqyS2+r+eXyt66/3FsvbzSUr5R/7mp/i
+Ucw6UwxI5g69ybR2BlLmEROFcmMDBOAENisgGQLodKcftslWZvB1JdxnwQ5hYIiz
+PtGo/KPaHbDRsSNU30R2be1B2MGyIrZTHN81Hdyhdyox5C315eXbyOD/5YDXC2Og
+/zOhD7osFRXql7PSorW+8oyWHhqPHWykYTe5hnMz15eWniN9gqRMgeKh0bpnX5UH
+oycR7hYQe7xFSkyyBNKr79X9DFHOUGoIMfmR2gyPZFwDwzqLID9ujWc9Otb+fVuI
+yV77zGHcizN300QyNQliBJIWENieJ0f7OyHj+OsdWwIDAQABo4GwMIGtMA8GA1Ud
+EwEB/wQFMAMBAf8wCwYDVR0PBAQDAgEGMB0GA1UdDgQWBBQahGK8SEwzJQTU7tD2
+A8QZRtGUazBuBgNVHSMEZzBlgBQahGK8SEwzJQTU7tD2A8QZRtGUa6FJpEcwRTEL
+MAkGA1UEBhMCQk0xGTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxGzAZBgNVBAMT
+ElF1b1ZhZGlzIFJvb3QgQ0EgMoICBQkwDQYJKoZIhvcNAQEFBQADggIBAD4KFk2f
+BluornFdLwUvZ+YTRYPENvbzwCYMDbVHZF34tHLJRqUDGCdViXh9duqWNIAXINzn
+g/iN/Ae42l9NLmeyhP3ZRPx3UIHmfLTJDQtyU/h2BwdBR5YM++CCJpNVjP4iH2Bl
+fF/nJrP3MpCYUNQ3cVX2kiF495V5+vgtJodmVjB3pjd4M1IQWK4/YY7yarHvGH5K
+WWPKjaJW1acvvFYfzznB4vsKqBUsfU16Y8Zsl0Q80m/DShcK+JDSV6IZUaUtl0Ha
+B0+pUNqQjZRG4T7wlP0QADj1O+hA4bRuVhogzG9Yje0uRY/W6ZM/57Es3zrWIozc
+hLsib9D45MY56QSIPMO661V6bYCZJPVsAfv4l7CUW+v90m/xd2gNNWQjrLhVoQPR
+TUIZ3Ph1WVaj+ahJefivDrkRoHy3au000LYmYjgahwz46P0u05B/B5EqHdZ+XIWD
+mbA4CD/pXvk1B+TJYm5Xf6dQlfe6yJvmjqIBxdZmv3lh8zwc4bmCXF2gw+nYSL0Z
+ohEUGW6yhhtoPkg3Goi3XZZenMfvJ2II4pEZXNLxId26F0KCl3GBUzGpn/Z9Yr9y
+4aOTHcyKJloJONDO1w2AFrR4pTqHTI2KpdVGl/IsELm8VCLAAVBpQ570su9t+Oza
+8eOx79+Rj1QqCyXBJhnEUhAFZdWCEOrCMc0u
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIE5jCCA86gAwIBAgIEO45L/DANBgkqhkiG9w0BAQUFADBdMRgwFgYJKoZIhvcN
+AQkBFglwa2lAc2suZWUxCzAJBgNVBAYTAkVFMSIwIAYDVQQKExlBUyBTZXJ0aWZp
+dHNlZXJpbWlza2Vza3VzMRAwDgYDVQQDEwdKdXVyLVNLMB4XDTAxMDgzMDE0MjMw
+MVoXDTE2MDgyNjE0MjMwMVowXTEYMBYGCSqGSIb3DQEJARYJcGtpQHNrLmVlMQsw
+CQYDVQQGEwJFRTEiMCAGA1UEChMZQVMgU2VydGlmaXRzZWVyaW1pc2tlc2t1czEQ
+MA4GA1UEAxMHSnV1ci1TSzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB
+AIFxNj4zB9bjMI0TfncyRsvPGbJgMUaXhvSYRqTCZUXP00B841oiqBB4M8yIsdOB
+SvZiF3tfTQou0M+LI+5PAk676w7KvRhj6IAcjeEcjT3g/1tf6mTll+g/mX8MCgkz
+ABpTpyHhOEvWgxutr2TC+Rx6jGZITWYfGAriPrsfB2WThbkasLnE+w0R9vXW+RvH
+LCu3GFH+4Hv2qEivbDtPL+/40UceJlfwUR0zlv/vWT3aTdEVNMfqPxZIe5EcgEMP
+PbgFPtGzlc3Yyg/CQ2fbt5PgIoIuvvVoKIO5wTtpeyDaTpxt4brNj3pssAki14sL
+2xzVWiZbDcDq5WDQn/413z8CAwEAAaOCAawwggGoMA8GA1UdEwEB/wQFMAMBAf8w
+ggEWBgNVHSAEggENMIIBCTCCAQUGCisGAQQBzh8BAQEwgfYwgdAGCCsGAQUFBwIC
+MIHDHoHAAFMAZQBlACAAcwBlAHIAdABpAGYAaQBrAGEAYQB0ACAAbwBuACAAdgDk
+AGwAagBhAHMAdABhAHQAdQBkACAAQQBTAC0AaQBzACAAUwBlAHIAdABpAGYAaQB0
+AHMAZQBlAHIAaQBtAGkAcwBrAGUAcwBrAHUAcwAgAGEAbABhAG0ALQBTAEsAIABz
+AGUAcgB0AGkAZgBpAGsAYQBhAHQAaQBkAGUAIABrAGkAbgBuAGkAdABhAG0AaQBz
+AGUAawBzMCEGCCsGAQUFBwIBFhVodHRwOi8vd3d3LnNrLmVlL2Nwcy8wKwYDVR0f
+BCQwIjAgoB6gHIYaaHR0cDovL3d3dy5zay5lZS9qdXVyL2NybC8wHQYDVR0OBBYE
+FASqekej5ImvGs8KQKcYP2/v6X2+MB8GA1UdIwQYMBaAFASqekej5ImvGs8KQKcY
+P2/v6X2+MA4GA1UdDwEB/wQEAwIB5jANBgkqhkiG9w0BAQUFAAOCAQEAe8EYlFOi
+CfP+JmeaUOTDBS8rNXiRTHyoERF5TElZrMj3hWVcRrs7EKACr81Ptcw2Kuxd/u+g
+kcm2k298gFTsxwhwDY77guwqYHhpNjbRxZyLabVAyJRld/JXIWY7zoVAtjNjGr95
+HvxcHdMdkxuLDF2FvZkwMhgJkVLpfKG6/2SSmuz+Ne6ML678IIbsSt4beDI3poHS
+na9aEhbKmVv8b20OxaAehsmR0FyYgl9jDIpaq9iVpszLita/ZEuOyoqysOkhMp6q
+qIWYNIE5ITuoOlIyPfZrN4YGWhWY3PARZv40ILcD9EEQfTmEeZZyY7aWAuVrua0Z
+TbvGRNs2yyqcjg==
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIICQzCCAcmgAwIBAgIILcX8iNLFS5UwCgYIKoZIzj0EAwMwZzEbMBkGA1UEAwwS
+QXBwbGUgUm9vdCBDQSAtIEczMSYwJAYDVQQLDB1BcHBsZSBDZXJ0aWZpY2F0aW9u
+IEF1dGhvcml0eTETMBEGA1UECgwKQXBwbGUgSW5jLjELMAkGA1UEBhMCVVMwHhcN
+MTQwNDMwMTgxOTA2WhcNMzkwNDMwMTgxOTA2WjBnMRswGQYDVQQDDBJBcHBsZSBS
+b290IENBIC0gRzMxJjAkBgNVBAsMHUFwcGxlIENlcnRpZmljYXRpb24gQXV0aG9y
+aXR5MRMwEQYDVQQKDApBcHBsZSBJbmMuMQswCQYDVQQGEwJVUzB2MBAGByqGSM49
+AgEGBSuBBAAiA2IABJjpLz1AcqTtkyJygRMc3RCV8cWjTnHcFBbZDuWmBSp3ZHtf
+TjjTuxxEtX/1H7YyYl3J6YRbTzBPEVoA/VhYDKX1DyxNB0cTddqXl5dvMVztK517
+IDvYuVTZXpmkOlEKMaNCMEAwHQYDVR0OBBYEFLuw3qFYM4iapIqZ3r6966/ayySr
+MA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMAoGCCqGSM49BAMDA2gA
+MGUCMQCD6cHEFl4aXTQY2e3v9GwOAEZLuN+yRhHFD/3meoyhpmvOwgPUnPWTxnS4
+at+qIxUCMG1mihDK1A3UT82NQz60imOlM27jbdoXt2QfyFMm+YhidDkLF1vLUagM
+6BgD56KyKA==
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIExTCCA62gAwIBAgIBADANBgkqhkiG9w0BAQUFADB9MQswCQYDVQQGEwJFVTEn
+MCUGA1UEChMeQUMgQ2FtZXJmaXJtYSBTQSBDSUYgQTgyNzQzMjg3MSMwIQYDVQQL
+ExpodHRwOi8vd3d3LmNoYW1iZXJzaWduLm9yZzEgMB4GA1UEAxMXR2xvYmFsIENo
+YW1iZXJzaWduIFJvb3QwHhcNMDMwOTMwMTYxNDE4WhcNMzcwOTMwMTYxNDE4WjB9
+MQswCQYDVQQGEwJFVTEnMCUGA1UEChMeQUMgQ2FtZXJmaXJtYSBTQSBDSUYgQTgy
+NzQzMjg3MSMwIQYDVQQLExpodHRwOi8vd3d3LmNoYW1iZXJzaWduLm9yZzEgMB4G
+A1UEAxMXR2xvYmFsIENoYW1iZXJzaWduIFJvb3QwggEgMA0GCSqGSIb3DQEBAQUA
+A4IBDQAwggEIAoIBAQCicKLQn0KuWxfH2H3PFIP8T8mhtxOviteePgQKkotgVvq0
+Mi+ITaFgCPS3CU6gSS9J1tPfnZdan5QEcOw/Wdm3zGaLmFIoCQLfxS+EjXqXd7/s
+QJ0lcqu1PzKY+7e3/HKE5TWH+VX6ox8Oby4o3Wmg2UIQxvi1RMLQQ3/bvOSiPGpV
+eAp3qdjqGTK3L/5cPxvusZjsyq16aUXjlg9V9ubtdepl6DJWk0aJqCWKZQbua795
+B9Dxt6/tLE2Su8CoX6dnfQTyFQhwrJLWfQTSM/tMtgsL+xrJxI0DqX5c8lCrEqWh
+z0hQpe/SyBoT+rB/sYIcd2oPX9wLlY/vQ37mRQklAgEDo4IBUDCCAUwwEgYDVR0T
+AQH/BAgwBgEB/wIBDDA/BgNVHR8EODA2MDSgMqAwhi5odHRwOi8vY3JsLmNoYW1i
+ZXJzaWduLm9yZy9jaGFtYmVyc2lnbnJvb3QuY3JsMB0GA1UdDgQWBBRDnDafsJ4w
+TcbOX60Qq+UDpfqpFDAOBgNVHQ8BAf8EBAMCAQYwEQYJYIZIAYb4QgEBBAQDAgAH
+MCoGA1UdEQQjMCGBH2NoYW1iZXJzaWducm9vdEBjaGFtYmVyc2lnbi5vcmcwKgYD
+VR0SBCMwIYEfY2hhbWJlcnNpZ25yb290QGNoYW1iZXJzaWduLm9yZzBbBgNVHSAE
+VDBSMFAGCysGAQQBgYcuCgEBMEEwPwYIKwYBBQUHAgEWM2h0dHA6Ly9jcHMuY2hh
+bWJlcnNpZ24ub3JnL2Nwcy9jaGFtYmVyc2lnbnJvb3QuaHRtbDANBgkqhkiG9w0B
+AQUFAAOCAQEAPDtwkfkEVCeR4e3t/mh/YV3lQWVPMvEYBZRqHN4fcNs+ezICNLUM
+bKGKfKX0j//U2K0X1S0E0T9YgOKBWYi+wONGkyT+kL0mojAt6JcmVzWJdJYY9hXi
+ryQZVgICsroPFOrGimbBhkVVi76SvpykBMdJPJ7oKXqJ1/6v/2j1pReQvayZzKWG
+VwlnRtvWFsJG8eSpUPWP0ZIV018+xgBJOm5YstHRJw0lyDL4IBHNfTIzSJRUTN3c
+ecQwn+uOuFW114hcxWokPbLTBQNRxgfvzBRydD1ucs4YKIxKoHflCStFREest2d/
+AYoFWpO+ocH/+OcOZ6RHSXZddZAa9SaP8A==
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIEMzCCAxugAwIBAgIDCYPzMA0GCSqGSIb3DQEBCwUAME0xCzAJBgNVBAYTAkRF
+MRUwEwYDVQQKDAxELVRydXN0IEdtYkgxJzAlBgNVBAMMHkQtVFJVU1QgUm9vdCBD
+bGFzcyAzIENBIDIgMjAwOTAeFw0wOTExMDUwODM1NThaFw0yOTExMDUwODM1NTha
+ME0xCzAJBgNVBAYTAkRFMRUwEwYDVQQKDAxELVRydXN0IEdtYkgxJzAlBgNVBAMM
+HkQtVFJVU1QgUm9vdCBDbGFzcyAzIENBIDIgMjAwOTCCASIwDQYJKoZIhvcNAQEB
+BQADggEPADCCAQoCggEBANOySs96R+91myP6Oi/WUEWJNTrGa9v+2wBoqOADER03
+UAifTUpolDWzU9GUY6cgVq/eUXjsKj3zSEhQPgrfRlWLJ23DEE0NkVJD2IfgXU42
+tSHKXzlABF9bfsyjxiupQB7ZNoTWSPOSHjRGICTBpFGOShrvUD9pXRl/RcPHAY9R
+ySPocq60vFYJfxLLHLGvKZAKyVXMD9O0Gu1HNVpK7ZxzBCHQqr0ME7UAyiZsxGsM
+lFqVlNpQmvH/pStmMaTJOKDfHR+4CS7zp+hnUquVH+BGPtikw8paxTGA6Eian5Rp
+/hnd2HN8gcqW3o7tszIFZYQ05ub9VxC1X3a/L7AQDcUCAwEAAaOCARowggEWMA8G
+A1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFP3aFMSfMN4hvR5COfyrYyNJ4PGEMA4G
+A1UdDwEB/wQEAwIBBjCB0wYDVR0fBIHLMIHIMIGAoH6gfIZ6bGRhcDovL2RpcmVj
+dG9yeS5kLXRydXN0Lm5ldC9DTj1ELVRSVVNUJTIwUm9vdCUyMENsYXNzJTIwMyUy
+MENBJTIwMiUyMDIwMDksTz1ELVRydXN0JTIwR21iSCxDPURFP2NlcnRpZmljYXRl
+cmV2b2NhdGlvbmxpc3QwQ6BBoD+GPWh0dHA6Ly93d3cuZC10cnVzdC5uZXQvY3Js
+L2QtdHJ1c3Rfcm9vdF9jbGFzc18zX2NhXzJfMjAwOS5jcmwwDQYJKoZIhvcNAQEL
+BQADggEBAH+X2zDI36ScfSF6gHDOFBJpiBSVYEQBrLLpME+bUMJm2H6NMLVwMeni
+acfzcNsgFYbQDfC+rAF1hM5+n02/t2A7nPPKHeJeaNijnZflQGDSNiH+0LS4F9p0
+o3/U37CYAqxva2ssJSRyoWXuJVrl5jLn8t+rSfrzkGkj2wTZ51xY/GXUl77M/C4K
+zCUqNQT4YJEVdT1B/yMfGchs64JTBKbkTCJNjYy6zltz7GRUUG3RnFX7acM2w4y8
+PIWmawomDeCTmGCufsYkl4phX5GOZpIJhzbNi5stPvZR1FDUWSi9g/LMKHtThm3Y
+Johw1+qRzT65ysCQblrGXnRl11z+o+I=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIDuDCCAqCgAwIBAgIQDPCOXAgWpa1Cf/DrJxhZ0DANBgkqhkiG9w0BAQUFADBI
+MQswCQYDVQQGEwJVUzEgMB4GA1UEChMXU2VjdXJlVHJ1c3QgQ29ycG9yYXRpb24x
+FzAVBgNVBAMTDlNlY3VyZVRydXN0IENBMB4XDTA2MTEwNzE5MzExOFoXDTI5MTIz
+MTE5NDA1NVowSDELMAkGA1UEBhMCVVMxIDAeBgNVBAoTF1NlY3VyZVRydXN0IENv
+cnBvcmF0aW9uMRcwFQYDVQQDEw5TZWN1cmVUcnVzdCBDQTCCASIwDQYJKoZIhvcN
+AQEBBQADggEPADCCAQoCggEBAKukgeWVzfX2FI7CT8rU4niVWJxB4Q2ZQCQXOZEz
+Zum+4YOvYlyJ0fwkW2Gz4BERQRwdbvC4u/jep4G6pkjGnx29vo6pQT64lO0pGtSO
+0gMdA+9tDWccV9cGrcrI9f4Or2YlSASWC12juhbDCE/RRvgUXPLIXgGZbf2IzIao
+wW8xQmxSPmjL8xk037uHGFaAJsTQ3MBv396gwpEWoGQRS0S8Hvbn+mPeZqx2pHGj
+7DaUaHp3pLHnDi+BeuK1cobvomuL8A/b01k/unK8RCSc43Oz969XL0Imnal0ugBS
+8kvNU3xHCzaFDmapCJcWNFfBZveA4+1wVMeT4C4oFVmHursCAwEAAaOBnTCBmjAT
+BgkrBgEEAYI3FAIEBh4EAEMAQTALBgNVHQ8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB
+/zAdBgNVHQ4EFgQUQjK2FvoE/f5dS3rD/fdMQB1aQ68wNAYDVR0fBC0wKzApoCeg
+JYYjaHR0cDovL2NybC5zZWN1cmV0cnVzdC5jb20vU1RDQS5jcmwwEAYJKwYBBAGC
+NxUBBAMCAQAwDQYJKoZIhvcNAQEFBQADggEBADDtT0rhWDpSclu1pqNlGKa7UTt3
+6Z3q059c4EVlew3KW+JwULKUBRSuSceNQQcSc5R+DCMh/bwQf2AQWnL1mA6s7Ll/
+3XpvXdMc9P+IBWlCqQVxyLesJugutIxq/3HcuLHfmbx8IVQr5Fiiu1cprp6poxkm
+D5kuCLDv/WnPmRoJjeOnnyvJNjR7JLN4TJUXpAYmHrZkUjZfYGfZnMUFdAvnZyPS
+CPyI6a6Lf+Ew9Dd+/cYy2i2eRDAwbO4H3tI0/NL/QPZL9GZGBlSm8jIKYyYwa5vR
+3ItHuuG51WLQoqD0ZwV4KWMabwTW+MZMo5qxN7SN5ShLHZ4swrhovO0C7jE=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIDczCCAlugAwIBAgIBBDANBgkqhkiG9w0BAQUFADBkMQswCQYDVQQGEwJLUjEN
+MAsGA1UECgwES0lTQTEuMCwGA1UECwwlS29yZWEgQ2VydGlmaWNhdGlvbiBBdXRo
+b3JpdHkgQ2VudHJhbDEWMBQGA1UEAwwNS0lTQSBSb290Q0EgMTAeFw0wNTA4MjQw
+ODA1NDZaFw0yNTA4MjQwODA1NDZaMGQxCzAJBgNVBAYTAktSMQ0wCwYDVQQKDARL
+SVNBMS4wLAYDVQQLDCVLb3JlYSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSBDZW50
+cmFsMRYwFAYDVQQDDA1LSVNBIFJvb3RDQSAxMIIBIDANBgkqhkiG9w0BAQEFAAOC
+AQ0AMIIBCAKCAQEAvATk+hM58DSWIGtsaLv623f/J/es7C/n/fB/bW+MKs0lCVsk
+9KFo/CjsySXirO3eyDOE9bClCTqnsUdIxcxPjHmc+QZXfd3uOPbPFLKc6tPAXXdi
+8EcNuRpAU1xkcK8IWsD3z3X5bI1kKB4g/rcbGdNaZoNy4rCbvdMlFQ0yb2Q3lIVG
+yHK+d9VuHygvx2nt54OJM1jT3qC/QOhDUO7cTWu8peqmyGGO9cNkrwYV3CmLP3WM
+vHFE2/yttRcdbYmDz8Yzvb9Fov4Kn6MRXw+5H5wawkbMnChmn3AmPC7fqoD+jMUE
+CSVPzZNHPDfqAmeS/vwiJFys0izgXAEzisEZ2wIBA6MyMDAwHQYDVR0OBBYEFL+2
+J9gDWnZlTGEBQVYx5Yt7OtnMMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEF
+BQADggEBABOvUQveimpb5poKyLGQSk6hAp3MiNKrZr097LuxQpVqslxa/6FjZJap
+aBV/JV6K+KRzwYCKhQoOUugy50X4TmWAkZl0Q+VFnUkq8JSV3enhMNITbslOsXfl
+BM+tWh6UCVrXPAgcrnrpFDLBRa3SJkhyrKhB2vAhhzle3/xk/2F0KpzZm4tfwjeT
+2KM3LzuTa7IbB6d/CVDv0zq+IWuKkDsnSlFOa56ch534eJAx7REnxqhZvvwYC/uO
+fi5C4e3nCSG9uRPFVmf0JqZCQ5BEVLRxm3bkGhKsGigA35vB1fjbXKP4krG9tNT5
+UNkAAk/bg9ART6RCVmE6fhMy04Qfybo=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIEMTCCAxmgAwIBAgIBADANBgkqhkiG9w0BAQUFADCBlTELMAkGA1UEBhMCR1Ix
+RDBCBgNVBAoTO0hlbGxlbmljIEFjYWRlbWljIGFuZCBSZXNlYXJjaCBJbnN0aXR1
+dGlvbnMgQ2VydC4gQXV0aG9yaXR5MUAwPgYDVQQDEzdIZWxsZW5pYyBBY2FkZW1p
+YyBhbmQgUmVzZWFyY2ggSW5zdGl0dXRpb25zIFJvb3RDQSAyMDExMB4XDTExMTIw
+NjEzNDk1MloXDTMxMTIwMTEzNDk1MlowgZUxCzAJBgNVBAYTAkdSMUQwQgYDVQQK
+EztIZWxsZW5pYyBBY2FkZW1pYyBhbmQgUmVzZWFyY2ggSW5zdGl0dXRpb25zIENl
+cnQuIEF1dGhvcml0eTFAMD4GA1UEAxM3SGVsbGVuaWMgQWNhZGVtaWMgYW5kIFJl
+c2VhcmNoIEluc3RpdHV0aW9ucyBSb290Q0EgMjAxMTCCASIwDQYJKoZIhvcNAQEB
+BQADggEPADCCAQoCggEBAKlTAOMupvaO+mDYLZU++CwqVE7NuYRhlFhPjz2L5EPz
+dYmNUeTDN9KKiE15HrcS3UN4SoqS5tdI1Q+kOilENbgH9mgdVc04UfCMJDGFr4PJ
+fel3r+0ae50X+bOdOFAPplp5kYCvN66m0zH7tSYJnTxa71HFK9+WXesyHgLacEns
+bgzImjeN9/E2YEsmLIKe0HjzDQ9jpFEw4fkrJxIH2Oq9GGKYsFk3fb7u8yBRQlqD
+75O6aRXxYp2fmTmCobd0LovUxQt7L/DICto9eQqakxylKHJzkUOap9FNhYS5qXSP
+FEDH3N6sQWRstBmbAmNtJGSPRLIl6s5ddAxjMlyNh+UCAwEAAaOBiTCBhjAPBgNV
+HRMBAf8EBTADAQH/MAsGA1UdDwQEAwIBBjAdBgNVHQ4EFgQUppFC/RNhSiOeCKQp
+5dgTBCPuQSUwRwYDVR0eBEAwPqA8MAWCAy5ncjAFggMuZXUwBoIELmVkdTAGggQu
+b3JnMAWBAy5ncjAFgQMuZXUwBoEELmVkdTAGgQQub3JnMA0GCSqGSIb3DQEBBQUA
+A4IBAQAf73lB4XtuP7KMhjdCSk4cNx6NZrokgclPEg8hwAOXhiVtXdMiKahsog2p
+6z0GW5k6x8zDmjR/qw7IThzh+uTczQ2+vyT+bOdrwg3IBp5OjWEopmr95fZi6hg8
+TqBTnbI6nOulnJEWtk2C4AwFSKls9cz4y51JtPACpf1wA+2KIaWuE4ZJwzNzvoc7
+dIsXRSZMFpGD/md9zU1jZ/rzAxKWeAaNsWftjj++n08C9bMJL/NMh98qy5V8Acys
+Nnq/onN694/BtZqhFLKPM58N7yLcZnuEvUUXBj08yrl3NI/K6s8/MT7jiOOASSXI
+l7WdmplNsDz4SgCbZN2fOUvRJ9e4
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIEFTCCAv2gAwIBAgIGSUEs5AAQMA0GCSqGSIb3DQEBCwUAMIGnMQswCQYDVQQG
+EwJIVTERMA8GA1UEBwwIQnVkYXBlc3QxFTATBgNVBAoMDE5ldExvY2sgS2Z0LjE3
+MDUGA1UECwwuVGFuw7pzw610dsOhbnlraWFkw7NrIChDZXJ0aWZpY2F0aW9uIFNl
+cnZpY2VzKTE1MDMGA1UEAwwsTmV0TG9jayBBcmFueSAoQ2xhc3MgR29sZCkgRsWR
+dGFuw7pzw610dsOhbnkwHhcNMDgxMjExMTUwODIxWhcNMjgxMjA2MTUwODIxWjCB
+pzELMAkGA1UEBhMCSFUxETAPBgNVBAcMCEJ1ZGFwZXN0MRUwEwYDVQQKDAxOZXRM
+b2NrIEtmdC4xNzA1BgNVBAsMLlRhbsO6c8OtdHbDoW55a2lhZMOzayAoQ2VydGlm
+aWNhdGlvbiBTZXJ2aWNlcykxNTAzBgNVBAMMLE5ldExvY2sgQXJhbnkgKENsYXNz
+IEdvbGQpIEbFkXRhbsO6c8OtdHbDoW55MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A
+MIIBCgKCAQEAxCRec75LbRTDofTjl5Bu0jBFHjzuZ9lk4BqKf8owyoPjIMHj9DrT
+lF8afFttvzBPhCf2nx9JvMaZCpDyD/V/Q4Q3Y1GLeqVw/HpYzY6b7cNGbIRwXdrz
+AZAj/E4wqX7hJ2Pn7WQ8oLjJM2P+FpD/sLj916jAwJRDC7bVWaaeVtAkH3B5r9s5
+VA1lddkVQZQBr17s9o3x/61k/iCa11zr/qYfCGSji3ZVrR47KGAuhyXoqq8fxmRG
+ILdwfzzeSNuWU7c5d+Qa4scWhHaXWy+7GRWF+GmF9ZmnqfI0p6m2pgP8b4Y9VHx2
+BJtr+UBdADTHLpl1neWIA6pN+APSQnbAGwIDAKiLo0UwQzASBgNVHRMBAf8ECDAG
+AQH/AgEEMA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUzPpnk/C2uNClwB7zU/2M
+U9+D15YwDQYJKoZIhvcNAQELBQADggEBAKt/7hwWqZw8UQCgwBEIBaeZ5m8BiFRh
+bvG5GK1Krf6BQCOUL/t1fC8oS2IkgYIL9WHxHG64YTjrgfpioTtaYtOUZcTh5m2C
++C8lcLIhJsFyUR+MLMOEkMNaj7rP9KdlpeuY0fsFskZ1FSNqb4VjMIDw1Z4fKRzC
+bLBQWV2QWzuoDTDPv31/zvGdg73JRm4gpvlhUbohL3u+pRVjodSVh/GeufOJ8z2F
+uLjbvrW5KfnaNwUASZQDhETnv0Mxz3WLJdH0pmT1kvarBes96aULNmLazAZfNou2
+XjG4Kvte9nHfRCaexOYNkbQudZWAUWpLMKawYqGT8ZvYzsRjdT9ZR7E=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIEPzCCAyegAwIBAgIBATANBgkqhkiG9w0BAQUFADB+MQswCQYDVQQGEwJHQjEb
+MBkGA1UECAwSR3JlYXRlciBNYW5jaGVzdGVyMRAwDgYDVQQHDAdTYWxmb3JkMRow
+GAYDVQQKDBFDb21vZG8gQ0EgTGltaXRlZDEkMCIGA1UEAwwbU2VjdXJlIENlcnRp
+ZmljYXRlIFNlcnZpY2VzMB4XDTA0MDEwMTAwMDAwMFoXDTI4MTIzMTIzNTk1OVow
+fjELMAkGA1UEBhMCR0IxGzAZBgNVBAgMEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4G
+A1UEBwwHU2FsZm9yZDEaMBgGA1UECgwRQ29tb2RvIENBIExpbWl0ZWQxJDAiBgNV
+BAMMG1NlY3VyZSBDZXJ0aWZpY2F0ZSBTZXJ2aWNlczCCASIwDQYJKoZIhvcNAQEB
+BQADggEPADCCAQoCggEBAMBxM4KK0HDrc4eCQNUd5MvJDkKQ+d40uaG6EfQlhfPM
+cm3ye5drswfxdySRXyWP9nQ95IDC+DwN879A6vfIUtFyb+/Iq0G4bi4XKpVpDM3S
+HpR7LZQdqnXXs5jLrLxkU0C8j6ysNstcrbvd4JQX7NFc0L/vpZXJkMWwrPsbQ996
+CF23uPJAGysnnlDOXmWCiIxe004MeuoIkbY2qitC++rCoznl2yY4rYsK7hljxxwk
+3wN42ubqwUcaCwtGCd0C/N7Lh1/XMGNooa7cMqG6vv5Eq2i2pRcV/b3Vp6ea5EQz
+6YiO/O1R65NxTq0B50SOqy3LqP4BSUjwwN3HaNiS/j0CAwEAAaOBxzCBxDAdBgNV
+HQ4EFgQUPNiTiMLAggnMAZkGkyDpnnAJY08wDgYDVR0PAQH/BAQDAgEGMA8GA1Ud
+EwEB/wQFMAMBAf8wgYEGA1UdHwR6MHgwO6A5oDeGNWh0dHA6Ly9jcmwuY29tb2Rv
+Y2EuY29tL1NlY3VyZUNlcnRpZmljYXRlU2VydmljZXMuY3JsMDmgN6A1hjNodHRw
+Oi8vY3JsLmNvbW9kby5uZXQvU2VjdXJlQ2VydGlmaWNhdGVTZXJ2aWNlcy5jcmww
+DQYJKoZIhvcNAQEFBQADggEBAIcBbSMdflsXfcFhMs+P5/OKlFlm4J4oqF7Tt/Q0
+5qo5spcWxYJvMqTpjOev/e/C6LlLqqP05tqNZSH7uoDrJiiFGv45jN5bBAS0VPmj
+Z55B+glSzAVIqMk/IQQezkhr/IXownuvf7fM+F86/TXGDe+X3EyrEeFryzHRbPtI
+gKvcnDe4IRRLDXE97IMzbtFuMhbsmMcWi1mmNKsFVy2T96oTy9IT4rcuO81rUBcJ
+aD61JlfutuC23bkpgHl9j6PwpCikFcSF9CfUa7/lXORlAnZUtOM3ZiTTGWHIUhDl
+izeauan5Hb/qmZJhlv8BzaFfDbxxvA6sCx1HRR3B7Hzs/Sk=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIF0zCCA7ugAwIBAgIVALhZFHE/V9+PMcAzPdLWGXojF7TrMA0GCSqGSIb3DQEB
+DQUAMIGAMQswCQYDVQQGEwJQTDEiMCAGA1UEChMZVW5pemV0byBUZWNobm9sb2dp
+ZXMgUy5BLjEnMCUGA1UECxMeQ2VydHVtIENlcnRpZmljYXRpb24gQXV0aG9yaXR5
+MSQwIgYDVQQDExtDZXJ0dW0gVHJ1c3RlZCBOZXR3b3JrIENBIDIwHhcNMTExMDA2
+MDgzOTU2WhcNNDYxMDA2MDgzOTU2WjCBgDELMAkGA1UEBhMCUEwxIjAgBgNVBAoT
+GVVuaXpldG8gVGVjaG5vbG9naWVzIFMuQS4xJzAlBgNVBAsTHkNlcnR1bSBDZXJ0
+aWZpY2F0aW9uIEF1dGhvcml0eTEkMCIGA1UEAxMbQ2VydHVtIFRydXN0ZWQgTmV0
+d29yayBDQSAyMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAvfl4+ObV
+gAxknYYblmRnPyI6HnUBfe/7XGeMycxca6mR5rlC5SBLm9qbe7mZXdmbgEvXhEAr
+J9PoujC7Pgkap0mV7ytAJMKXx6fumyXvqAoAl4Vaqp3cKcniNQfrcE1K1sGzVrih
+QTib0fsxf4/gX+GxPw+OFklg1waNGPmqJhCrKtPQ0WeNG0a+RzDVLnLRxWPa52N5
+RH5LYySJhi40PylMUosqp8DikSiJucBb+R3Z5yet/5oCl8HGUJKbAiy9qbk0WQq/
+hEr/3/6zn+vZnuCYI+yma3cWKtvMrTscpIfcRnNeGWJoRVfkkIJCu0LW8GHgwaM9
+ZqNd9BjuiMmNF0UpmTJ1AjHuKSbIawLmtWJFfzcVWiNoidQ+3k4nsPBADLxNF8tN
+orMe0AZa3faTz1d1mfX6hhpneLO/lv403L3nUlbls+V1e9dBkQXcXWnjlQ1DufyD
+ljmVe2yAWk8TcsbXfSl6RLpSpCrVQUYJIP4ioLZbMI28iQzV13D4h1L92u+sUS4H
+s07+0AnacO+Y+lbmbdu1V0vc5SwlFcieLnhO+NqcnoYsylfzGuXIkosagpZ6w7xQ
+EmnYDlpGizrrJvojybawgb5CAKT41v4wLsfSRvbljnX98sy50IdbzAYQYLuDNbde
+Z95H7JlI8aShFf6tjGKOOVVPORa5sWOd/7cCAwEAAaNCMEAwDwYDVR0TAQH/BAUw
+AwEB/zAdBgNVHQ4EFgQUtqFUOQLDoD+Oirz61PgcptE6Dv0wDgYDVR0PAQH/BAQD
+AgEGMA0GCSqGSIb3DQEBDQUAA4ICAQCdU8KBJdw1LK4K3VqbRjBWu9S0bEuG5gql
+0pKKmo3cj7TudvQDy+ubAXirKmu1uiNOMXy1LN0taWczbmNdORgS+KAoU0SHq2rE
+kpYfKqIcup3dJ/tSTbCPWujtjcNo45KgJgyHkLAD6mplKAjERnjgW7oO8DPcJ7Z+
+iD29kqSWfkGogAh71jYSvBAVmyS8q619EYkvMe340s9Tjuu0U6fnBMovpiLEEdzr
+mMkiXUFq3ApSBFu8LqB9x7aSuySg8zfRK0OozPFoeBp+b2OQe590yGvZC1X2eQM9
+g8dBQJL7dgs3JRc8rz76PFwbhvlKDD+KxF4OmPGt7s/g/SE1xzNhzKI3GEN8M+mu
+doKCB0VIO8lnbq2jheiWVs+8u/qry7dXJ40aL5nzIzM0jspTY9NXNFBPz0nBBbrF
+qId744aP+0OiEumsUewEdkzw+o+5MRPpCLckCfmgtwc2WFfPxLt+SWaVNQS2dzW4
+qVMpX5KF+FLEWk79BmE5+33QdkeSzOwrvYRu5ptFwX1isVMtnnWg58koUNflvKiq
+B3hquXS0YPOEjQPcrpHadEQNe0Kpd9YrfKHGbBNTIqkSmqX5TyhFNbCXT0ZlhcX0
+/WKiomr8NDAGft8M4HOBlslEKt4fguxscletKWSk8cYpjjVgU85r2QK+OTB14Pdc
+Y2rwQMEsjQ==
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIDQzCCAiugAwIBAgIQX/h7KCtU3I1CoxW1aMmt/zANBgkqhkiG9w0BAQUFADA1
+MRYwFAYDVQQKEw1DaXNjbyBTeXN0ZW1zMRswGQYDVQQDExJDaXNjbyBSb290IENB
+IDIwNDgwHhcNMDQwNTE0MjAxNzEyWhcNMjkwNTE0MjAyNTQyWjA1MRYwFAYDVQQK
+Ew1DaXNjbyBTeXN0ZW1zMRswGQYDVQQDExJDaXNjbyBSb290IENBIDIwNDgwggEg
+MA0GCSqGSIb3DQEBAQUAA4IBDQAwggEIAoIBAQCwmrmrp68Kd6ficba0ZmKUeIhH
+xmJVhEAyv8CrLqUccda8bnuoqrpu0hWISEWdovyD0My5jOAmaHBKeN8hF570YQXJ
+FcjPFto1YYmUQ6iEqDGYeJu5Tm8sUxJszR2tKyS7McQr/4NEb7Y9JHcJ6r8qqB9q
+VvYgDxFUl4F1pyXOWWqCZe+36ufijXWLbvLdT6ZeYpzPEApk0E5tzivMW/VgpSdH
+jWn0f84bcN5wGyDWbs2mAag8EtKpP6BrXruOIIt6keO1aO6g58QBdKhTCytKmg9l
+Eg6CTY5j/e/rmxrbU6YTYK/CfdfHbBcl1HP7R2RQgYCUTOG/rksc35LtLgXfAgED
+o1EwTzALBgNVHQ8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUJ/PI
+FR5umgIJFq0roIlgX9p7L6owEAYJKwYBBAGCNxUBBAMCAQAwDQYJKoZIhvcNAQEF
+BQADggEBAJ2dhISjQal8dwy3U8pORFBi71R803UXHOjgxkhLtv5MOhmBVrBW7hmW
+Yqpao2TB9k5UM8Z3/sUcuuVdJcr18JOagxEu5sv4dEX+5wW4q+ffy0vhN4TauYuX
+cB7w4ovXsNgOnbFp1iqRe6lJT37mjpXYgyc81WhJDtSd9i7rp77rMKSsH0T8lasz
+Bvt9YAretIpjsJyp8qS5UwGH0GikJ3+r/+n6yUA4iGe0OcaEb1fJU9u6ju7AQ7L4
+CYNu/2bPPu8Xs1gYJQk0XuPL1hS27PKSb3TkL4Eq1ZKR4OCXPDJoBYVL0fdX4lId
+kxpUnwVwwEpxYB5DC2Ae/qPOgRnhCzU=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIID3TCCAsWgAwIBAgIBADANBgkqhkiG9w0BAQsFADCBjzELMAkGA1UEBhMCVVMx
+EDAOBgNVBAgTB0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxJTAjBgNVBAoT
+HFN0YXJmaWVsZCBUZWNobm9sb2dpZXMsIEluYy4xMjAwBgNVBAMTKVN0YXJmaWVs
+ZCBSb290IENlcnRpZmljYXRlIEF1dGhvcml0eSAtIEcyMB4XDTA5MDkwMTAwMDAw
+MFoXDTM3MTIzMTIzNTk1OVowgY8xCzAJBgNVBAYTAlVTMRAwDgYDVQQIEwdBcml6
+b25hMRMwEQYDVQQHEwpTY290dHNkYWxlMSUwIwYDVQQKExxTdGFyZmllbGQgVGVj
+aG5vbG9naWVzLCBJbmMuMTIwMAYDVQQDEylTdGFyZmllbGQgUm9vdCBDZXJ0aWZp
+Y2F0ZSBBdXRob3JpdHkgLSBHMjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC
+ggEBAL3twQP89o/8ArFvW59I2Z154qK3A2FWGMNHttfKPTUuiUP3oWmb3ooa/RMg
+nLRJdzIpVv257IzdIvpy3Cdhl+72WoTsbhm5iSzchFvVdPtrX8WJpRBSiUZV9Lh1
+HOZ/5FSuS/hVclcCGfgXcVnrHigHdMWdSL5stPSksPNkN3mSwOxGXn/hbVNMYq/N
+Hwtjuzqd+/x5AJhhdM8mgkBj87JyahkNmcrUDnXMN/uLicFZ8WJ/X7NfZTD4p7dN
+dloedl40wOiWVpmKs/B/pM293DIxfJHP4F8R+GuqSVzRmZTRouNjWwl2tVZi4Ut0
+HZbUJtQIBFnQmA4O5t78w+wfkPECAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAO
+BgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFHwMMh+n2TB/xH1oo2Kooc6rB1snMA0G
+CSqGSIb3DQEBCwUAA4IBAQARWfolTwNvlJk7mh+ChTnUdgWUXuEok21iXQnCoKjU
+sHU48TRqneSfioYmUeYs0cYtbpUgSpIB7LiKZ3sx4mcujJUDJi5DnUox9g61DLu3
+4jd/IroAow57UvtruzvE03lRTs2Q9GcHGcg8RnoNAX3FWOdt5oUwF5okxBDgBPfg
+8n/Uqgr/Qh037ZTlZFkSIHc40zI+OIF1lnP6aI+xy84fxez6nH7PfrHxBy22/L/K
+pL/QlwVKvOoYKAKQvVR4CSFx09F9HdkWsKlhPdAKACL8x3vLCWRFCztAgfd9fDL1
+mMpYjn0q7pBZc2T5NnReJaH1ZgUufzkVqSr7UIuOhWn0
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIDzzCCAregAwIBAgIDAWweMA0GCSqGSIb3DQEBBQUAMIGNMQswCQYDVQQGEwJB
+VDFIMEYGA1UECgw/QS1UcnVzdCBHZXMuIGYuIFNpY2hlcmhlaXRzc3lzdGVtZSBp
+bSBlbGVrdHIuIERhdGVudmVya2VociBHbWJIMRkwFwYDVQQLDBBBLVRydXN0LW5R
+dWFsLTAzMRkwFwYDVQQDDBBBLVRydXN0LW5RdWFsLTAzMB4XDTA1MDgxNzIyMDAw
+MFoXDTE1MDgxNzIyMDAwMFowgY0xCzAJBgNVBAYTAkFUMUgwRgYDVQQKDD9BLVRy
+dXN0IEdlcy4gZi4gU2ljaGVyaGVpdHNzeXN0ZW1lIGltIGVsZWt0ci4gRGF0ZW52
+ZXJrZWhyIEdtYkgxGTAXBgNVBAsMEEEtVHJ1c3QtblF1YWwtMDMxGTAXBgNVBAMM
+EEEtVHJ1c3QtblF1YWwtMDMwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB
+AQCtPWFuA/OQO8BBC4SAzewqo51ru27CQoT3URThoKgtUaNR8t4j8DRE/5TrzAUj
+lUC5B3ilJfYKvUWG6Nm9wASOhURh73+nyfrBJcyFLGM/BWBzSQXgYHiVEEvc+RFZ
+znF/QJuKqiTfC0Li21a8StKlDJu3Qz7dg9MmEALP6iPESU7l0+m0iKsMrmKS1GWH
+2WrX9IWf5DMiJaXlyDO6w8dB3F/GaswADm0yqLaHNgBid5seHzTLkDx4iHQF63n1
+k3Flyp3HaxgtPVxO59X4PzF9j4fsCiIvI+n+u33J4PTs63zEsMMtYrWacdaxaujs
+2e3Vcuy+VwHOBVWf3tFgiBCzAgMBAAGjNjA0MA8GA1UdEwEB/wQFMAMBAf8wEQYD
+VR0OBAoECERqlWdVeRFPMA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQUFAAOC
+AQEAVdRU0VlIXLOThaq/Yy/kgM40ozRiPvbY7meIMQQDbwvUB/tOdQ/TLtPAF8fG
+KOwGDREkDg6lXb+MshOWcdzUzg4NCmgybLlBMRmrsQd7TZjTXLDR8KdCoLXEjq/+
+8T/0709GAHbrAvv5ndJAlseIOrifEXnzgGWovR/TeIGgUUw3tKZdJXDRZslo+S4R
+FGjxVJgIrCaSD96JntT6s3kr0qN51OyLrIdTaEJMUVF0HhsnLuP1Hyl0Te2v9+GS
+mYHovjrHF1D2t8b8m7CKa9aIA5GPBnc6hQLdmNVDeD/GMBWsm2vLV7eJUYs66MmE
+DNuxUCAKGkq6ahq97BvIxYSazQ==
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIEKjCCAxKgAwIBAgIQYAGXt0an6rS0mtZLL/eQ+zANBgkqhkiG9w0BAQsFADCB
+rjELMAkGA1UEBhMCVVMxFTATBgNVBAoTDHRoYXd0ZSwgSW5jLjEoMCYGA1UECxMf
+Q2VydGlmaWNhdGlvbiBTZXJ2aWNlcyBEaXZpc2lvbjE4MDYGA1UECxMvKGMpIDIw
+MDggdGhhd3RlLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxJDAiBgNV
+BAMTG3RoYXd0ZSBQcmltYXJ5IFJvb3QgQ0EgLSBHMzAeFw0wODA0MDIwMDAwMDBa
+Fw0zNzEyMDEyMzU5NTlaMIGuMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMdGhhd3Rl
+LCBJbmMuMSgwJgYDVQQLEx9DZXJ0aWZpY2F0aW9uIFNlcnZpY2VzIERpdmlzaW9u
+MTgwNgYDVQQLEy8oYykgMjAwOCB0aGF3dGUsIEluYy4gLSBGb3IgYXV0aG9yaXpl
+ZCB1c2Ugb25seTEkMCIGA1UEAxMbdGhhd3RlIFByaW1hcnkgUm9vdCBDQSAtIEcz
+MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAsr8nLPvb2FvdeHsbnndm
+gcs+vHyu86YnmjSjaDFxODNi5PNxZnmxqWWjpYvVj2AtP0LMqmsywCPLLEHd5N/8
+YZzic7IilRFDGF/Eth9XbAoFWCLINkw6fKXRz4aviKdEAhN0cXMKQlkC+BsUa0Lf
+b1+6a4KinVvnSr0eAXLbS3ToO39/fR8EtCab4LRarEc9VbjXsCZSKAExQGbY2SS9
+9irY7CFJXJv2eul/VTV+lmuNk5Mny5K76qxAwJ/C+IDPXfRa3M50hqY+bAtTyr2S
+zhkGcuYMXDhpxwTWvGzOW/b3aJzcJRVIiKHpqfiYnODz1TEoYRFsZ5aNOZnLwkUk
+OQIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNV
+HQ4EFgQUrWyqlGCc7eT/+j4KdCtjA/e2Wb8wDQYJKoZIhvcNAQELBQADggEBABpA
+2JVlrAmSicY59BDlqQ5mU1143vokkbvnRFHfxhY0Cu9qRFHqKweKA3rD6z8KLFIW
+oCtDuSWQP3CpMyVtRRooOyfPqsMpQhvfO0zAMzRbQYi/aytlryjvsvXDqmbOe1bu
+t8jLZ8HJnBoYuMTDSQPxYA5QzUbF83d597YV4Djbxy8ooAw/dyZ02SUS2jHaGh7c
+KUGRIjxpp7sC8rZcJwOJ9Abqm+RyguOhCcHpABnTPtRwa7pxpqpYrvS76Wy274fM
+m7v/OeZWYdMKp8RcTGB7BXcmer/YB1IsYvdwY9k5vG8cwnncdimvzsUsZAReiDZu
+MdRAGmI0Nj81Aa6sY6A=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIFHjCCBAagAwIBAgIEAKA3oDANBgkqhkiG9w0BAQsFADCBtzELMAkGA1UEBhMC
+Q1oxOjA4BgNVBAMMMUkuQ0EgLSBRdWFsaWZpZWQgQ2VydGlmaWNhdGlvbiBBdXRo
+b3JpdHksIDA5LzIwMDkxLTArBgNVBAoMJFBydm7DrSBjZXJ0aWZpa2HEjW7DrSBh
+dXRvcml0YSwgYS5zLjE9MDsGA1UECww0SS5DQSAtIEFjY3JlZGl0ZWQgUHJvdmlk
+ZXIgb2YgQ2VydGlmaWNhdGlvbiBTZXJ2aWNlczAeFw0wOTA5MDEwMDAwMDBaFw0x
+OTA5MDEwMDAwMDBaMIG3MQswCQYDVQQGEwJDWjE6MDgGA1UEAwwxSS5DQSAtIFF1
+YWxpZmllZCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSwgMDkvMjAwOTEtMCsGA1UE
+CgwkUHJ2bsOtIGNlcnRpZmlrYcSNbsOtIGF1dG9yaXRhLCBhLnMuMT0wOwYDVQQL
+DDRJLkNBIC0gQWNjcmVkaXRlZCBQcm92aWRlciBvZiBDZXJ0aWZpY2F0aW9uIFNl
+cnZpY2VzMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAtTaEy0KC8M9l
+4lSaWHMs4+sVV1LwzyJYiIQNeCrv1HHm/YpGIdY/Z640ceankjQvIX7m23BK4OSC
+6KO8kZYA3zopOz6GFCOKV2PvLukbc+c2imF6kLHEv6qNA8WxhPbR3xKwlHDwB2yh
+Wzo7V3QVgDRG83sugqQntKYC3LnlTGbJpNP+Az72gpO9AHUn/IBhFk4ksc8lYS2L
+9GCy9CsmdKSBP78p9w8Lx7vDLqkDgt1/zBrcUWmSSb7AE/BPEeMryQV1IdI6nlGn
+BhWkXOYf6GSdayJw86btuxC7viDKNrbp44HjQRaSxnp6O3eto1x4DfiYdw/YbJFe
+7EjkxSQBywIDAQABo4IBLjCCASowDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8E
+BAMCAQYwgecGA1UdIASB3zCB3DCB2QYEVR0gADCB0DCBzQYIKwYBBQUHAgIwgcAa
+gb1UZW50byBjZXJ0aWZpa2F0IGplIHZ5ZGFuIGpha28ga3ZhbGlmaWtvdmFueSBz
+eXN0ZW1vdnkgY2VydGlmaWthdCBwb2RsZSB6YWtvbmEgYy4gMjI3LzIwMDAgU2Iu
+IHYgcGxhdG5lbSB6bmVuaS9UaGlzIGlzIHF1YWxpZmllZCBzeXN0ZW0gY2VydGlm
+aWNhdGUgYWNjb3JkaW5nIHRvIEN6ZWNoIEFjdCBOby4gMjI3LzIwMDAgQ29sbC4w
+HQYDVR0OBBYEFHnL0CPpOmdwkXRP01Hi4CD94Sj7MA0GCSqGSIb3DQEBCwUAA4IB
+AQB9laU214hYaBHPZftbDS/2dIGLWdmdSbj1OZbJ8LIPBMxYjPoEMqzAR74tw96T
+i6aWRa5WdOWaS6I/qibEKFZhJAVXX5mkx2ewGFLJ+0Go+eTxnjLOnhVF2V2s+57b
+m8c8j6/bS6Ij6DspcHEYpfjjh64hE2r0aSpZDjGzKFM6YpqsCJN8qYe2X1qmGMLQ
+wvNdjG+nPzCJOOuUEypIWt555ZDLXqS5F7ZjBjlfyDZjEfS2Es9Idok8alf563Mi
+9/o+Ba46wMYOkk3P1IlU0RqCajdbliioACKDztAqubONU1guZVzV8tuMASVzbJeL
+/GAB7ECTwe1RuKrLYtglMKI9
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIHyTCCBbGgAwIBAgIBATANBgkqhkiG9w0BAQUFADB9MQswCQYDVQQGEwJJTDEW
+MBQGA1UEChMNU3RhcnRDb20gTHRkLjErMCkGA1UECxMiU2VjdXJlIERpZ2l0YWwg
+Q2VydGlmaWNhdGUgU2lnbmluZzEpMCcGA1UEAxMgU3RhcnRDb20gQ2VydGlmaWNh
+dGlvbiBBdXRob3JpdHkwHhcNMDYwOTE3MTk0NjM2WhcNMzYwOTE3MTk0NjM2WjB9
+MQswCQYDVQQGEwJJTDEWMBQGA1UEChMNU3RhcnRDb20gTHRkLjErMCkGA1UECxMi
+U2VjdXJlIERpZ2l0YWwgQ2VydGlmaWNhdGUgU2lnbmluZzEpMCcGA1UEAxMgU3Rh
+cnRDb20gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwggIiMA0GCSqGSIb3DQEBAQUA
+A4ICDwAwggIKAoICAQDBiNsJvGxGfHiflXu1M5DycmLWwTYgIiRezul38kMKogZk
+pMyONvg45iPwbm2xPN1yo4UcodM9tDMr0y+v/uqwQVlntsQGfQqedIXWeUyAN3rf
+OQVSWff0G0ZDpNKFhdLDcfN1YjS6LIp/Ho/u7TTQEceWzVI9ujPW3U3eCztKS5/C
+Ji/6tRYccjV3yjxd5srhJosaNnZcAdt0FCX+7bWgiA/deMotHweXMAEtcnn6RtYT
+Kqi5pquDSR3l8u/d5AGOGAqPY1MWhWKpDhk6zLVmpsJrdAfkK+F2PrRt2PZE4XNi
+HzvEvqBTViVsUQn3qqvKv3b9bZvzndu/PWa8DFaqr5hIlTpL36dYUNk4dalb6kMM
+Av+Z6+hsTXBbKWWc3apdzK8BMewM69KN6Oqce+Zu9ydmDBpI125C4z/eIT574Q1w
++2OqqGwaVLRcJXrJosmLFqa7LH4XXgVNWG4SHQHuEhANxjJ/GP/89PrNbpHoNkm+
+Gkhpi8KWTRoSsmkXwQqQ1vp5Iki/untp+HDH+no32NgN0nZPV/+Qt+OR0t3vwmC3
+Zzrd/qqc8NSLf3Iizsafl7b4r4qgEKjZ+xjGtrVcUjyJthkqcwEKDwOzEmDyei+B
+26Nu/yYwl/WL3YlXtq09s68rxbd2AvCl1iuahhQqcvbjM4xdCUsT37uMdBNSSwID
+AQABo4ICUjCCAk4wDAYDVR0TBAUwAwEB/zALBgNVHQ8EBAMCAa4wHQYDVR0OBBYE
+FE4L7xqkQFulF2mHMMo0aEPQQa7yMGQGA1UdHwRdMFswLKAqoCiGJmh0dHA6Ly9j
+ZXJ0LnN0YXJ0Y29tLm9yZy9zZnNjYS1jcmwuY3JsMCugKaAnhiVodHRwOi8vY3Js
+LnN0YXJ0Y29tLm9yZy9zZnNjYS1jcmwuY3JsMIIBXQYDVR0gBIIBVDCCAVAwggFM
+BgsrBgEEAYG1NwEBATCCATswLwYIKwYBBQUHAgEWI2h0dHA6Ly9jZXJ0LnN0YXJ0
+Y29tLm9yZy9wb2xpY3kucGRmMDUGCCsGAQUFBwIBFilodHRwOi8vY2VydC5zdGFy
+dGNvbS5vcmcvaW50ZXJtZWRpYXRlLnBkZjCB0AYIKwYBBQUHAgIwgcMwJxYgU3Rh
+cnQgQ29tbWVyY2lhbCAoU3RhcnRDb20pIEx0ZC4wAwIBARqBl0xpbWl0ZWQgTGlh
+YmlsaXR5LCByZWFkIHRoZSBzZWN0aW9uICpMZWdhbCBMaW1pdGF0aW9ucyogb2Yg
+dGhlIFN0YXJ0Q29tIENlcnRpZmljYXRpb24gQXV0aG9yaXR5IFBvbGljeSBhdmFp
+bGFibGUgYXQgaHR0cDovL2NlcnQuc3RhcnRjb20ub3JnL3BvbGljeS5wZGYwEQYJ
+YIZIAYb4QgEBBAQDAgAHMDgGCWCGSAGG+EIBDQQrFilTdGFydENvbSBGcmVlIFNT
+TCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTANBgkqhkiG9w0BAQUFAAOCAgEAFmyZ
+9GYMNPXQhV59CuzaEE44HF7fpiUFS5Eyweg78T3dRAlbB0mKKctmArexmvclmAk8
+jhvh3TaHK0u7aNM5Zj2gJsfyOZEdUauCe37Vzlrk4gNXcGmXCPleWKYK34wGmkUW
+FjgKXlf2Ysd6AgXmvB618p70qSmD+LIU424oh0TDkBreOKk8rENNZEXO3SipXPJz
+ewT4F+irsfMuXGRuczE6Eri8sxHkfY+BUZo7jYn0TZNmezwD7dOaHZrzZVD1oNB1
+ny+v8OqCQ5j4aZyJecRDjkZy42Q2Eq/3JR44iZB3fsNrarnDy0RLrHiQi+fHLB5L
+EUTINFInzQpdn4XBidUaePKVEFMy3YCEZnXZtWgo+2EuvoSoOMCZEoalHmdkrQYu
+L6lwhceWD3yJZfWOQ1QOq92lgDmUYMA0yZZwLKMS9R9Ie70cfmu3nZD0Ijuu+Pwq
+yvqCUqDvr0tVk+vBtfAii6w0TiYiBKGHLHVKt+V9E9e4DGTANtLJL4YSjCMJwRuC
+O3NJo2pXh5Tl1njFmUNj403gdy3hZZlyaQQaRwnmDwFWJPsfvw55qVguucQJAX6V
+um0ABj6y6koQOdjQK/W/7HW/lwLFCRsI3FU34oH7N4RDYiDK51ZLZer+bMEkkySh
+NOsF/5oirpt9P/FlUQqmMGqz9IgcgA38corog14=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIHhzCCBW+gAwIBAgIBLTANBgkqhkiG9w0BAQsFADB9MQswCQYDVQQGEwJJTDEW
+MBQGA1UEChMNU3RhcnRDb20gTHRkLjErMCkGA1UECxMiU2VjdXJlIERpZ2l0YWwg
+Q2VydGlmaWNhdGUgU2lnbmluZzEpMCcGA1UEAxMgU3RhcnRDb20gQ2VydGlmaWNh
+dGlvbiBBdXRob3JpdHkwHhcNMDYwOTE3MTk0NjM3WhcNMzYwOTE3MTk0NjM2WjB9
+MQswCQYDVQQGEwJJTDEWMBQGA1UEChMNU3RhcnRDb20gTHRkLjErMCkGA1UECxMi
+U2VjdXJlIERpZ2l0YWwgQ2VydGlmaWNhdGUgU2lnbmluZzEpMCcGA1UEAxMgU3Rh
+cnRDb20gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwggIiMA0GCSqGSIb3DQEBAQUA
+A4ICDwAwggIKAoICAQDBiNsJvGxGfHiflXu1M5DycmLWwTYgIiRezul38kMKogZk
+pMyONvg45iPwbm2xPN1yo4UcodM9tDMr0y+v/uqwQVlntsQGfQqedIXWeUyAN3rf
+OQVSWff0G0ZDpNKFhdLDcfN1YjS6LIp/Ho/u7TTQEceWzVI9ujPW3U3eCztKS5/C
+Ji/6tRYccjV3yjxd5srhJosaNnZcAdt0FCX+7bWgiA/deMotHweXMAEtcnn6RtYT
+Kqi5pquDSR3l8u/d5AGOGAqPY1MWhWKpDhk6zLVmpsJrdAfkK+F2PrRt2PZE4XNi
+HzvEvqBTViVsUQn3qqvKv3b9bZvzndu/PWa8DFaqr5hIlTpL36dYUNk4dalb6kMM
+Av+Z6+hsTXBbKWWc3apdzK8BMewM69KN6Oqce+Zu9ydmDBpI125C4z/eIT574Q1w
++2OqqGwaVLRcJXrJosmLFqa7LH4XXgVNWG4SHQHuEhANxjJ/GP/89PrNbpHoNkm+
+Gkhpi8KWTRoSsmkXwQqQ1vp5Iki/untp+HDH+no32NgN0nZPV/+Qt+OR0t3vwmC3
+Zzrd/qqc8NSLf3Iizsafl7b4r4qgEKjZ+xjGtrVcUjyJthkqcwEKDwOzEmDyei+B
+26Nu/yYwl/WL3YlXtq09s68rxbd2AvCl1iuahhQqcvbjM4xdCUsT37uMdBNSSwID
+AQABo4ICEDCCAgwwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYD
+VR0OBBYEFE4L7xqkQFulF2mHMMo0aEPQQa7yMB8GA1UdIwQYMBaAFE4L7xqkQFul
+F2mHMMo0aEPQQa7yMIIBWgYDVR0gBIIBUTCCAU0wggFJBgsrBgEEAYG1NwEBATCC
+ATgwLgYIKwYBBQUHAgEWImh0dHA6Ly93d3cuc3RhcnRzc2wuY29tL3BvbGljeS5w
+ZGYwNAYIKwYBBQUHAgEWKGh0dHA6Ly93d3cuc3RhcnRzc2wuY29tL2ludGVybWVk
+aWF0ZS5wZGYwgc8GCCsGAQUFBwICMIHCMCcWIFN0YXJ0IENvbW1lcmNpYWwgKFN0
+YXJ0Q29tKSBMdGQuMAMCAQEagZZMaW1pdGVkIExpYWJpbGl0eSwgcmVhZCB0aGUg
+c2VjdGlvbiAqTGVnYWwgTGltaXRhdGlvbnMqIG9mIHRoZSBTdGFydENvbSBDZXJ0
+aWZpY2F0aW9uIEF1dGhvcml0eSBQb2xpY3kgYXZhaWxhYmxlIGF0IGh0dHA6Ly93
+d3cuc3RhcnRzc2wuY29tL3BvbGljeS5wZGYwEQYJYIZIAYb4QgEBBAQDAgAHMDgG
+CWCGSAGG+EIBDQQrFilTdGFydENvbSBGcmVlIFNTTCBDZXJ0aWZpY2F0aW9uIEF1
+dGhvcml0eTANBgkqhkiG9w0BAQsFAAOCAgEAjo/n3JR5fPGFf59Jb2vKXfuM/gTF
+wWLRfUKKvFO3lANmMD+x5wqnUCBVJX92ehQN6wQOQOY+2IirByeDqXWmN3PH/UvS
+Ta0XQMhGvjt/UfzDtgUx3M2FIk5xt/JxXrAaxrqTi3iSSoX4eA+D/i+tLPfkpLst
+0OcNOrg+zvZ49q5HJMqjNTbOx8aHmNrs++myziebiMMEofYLWWivydsQD032ZGNc
+pRJvkrKTlMeIFw6Ttn5ii5B/q06f/ON1FE8qMt9bDeD1e5MNq6HPh+GlBEXoPBKl
+CcWw0bdT82AUuoVpaiF8H3VhFyAXe2w7QSlc4axa0c2Mm+tgHRns9+Ww2vl5GKVF
+P0lDV9LdJNUso/2RjSe15esUBppMeyG7Oq0wBhjA2MFrLH9ZXF2RsXAiV+uKa0hK
+1Q8p7MZAwC+ITGgBF3f0JBlPvfrhsiAhS90a2Cl9qrjeVOwhVYBsHvUwyKMQ5bLm
+KhQxw4UtjJixhlpPiVktucf3HMiKf8CdBUrmQk9io20ppB+Fq9vlgcitKj1MXVuE
+JnHEhV5xJMqlG2zYYdMa4FTbzrqpMrUi9nNBCV24F10OD5mQ1kfabwo6YigUZ4LZ
+8dCAWZvLMdibD4x3TrVoivJs9iQOLWxwxXPR3hTQcY+203sC9uO41Alua551hDnm
+fyWl8kgAwKQB2j8=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIDrzCCApegAwIBAgIQCDvgVpBCRrGhdWrJWZHHSjANBgkqhkiG9w0BAQUFADBh
+MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3
+d3cuZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBD
+QTAeFw0wNjExMTAwMDAwMDBaFw0zMTExMTAwMDAwMDBaMGExCzAJBgNVBAYTAlVT
+MRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5j
+b20xIDAeBgNVBAMTF0RpZ2lDZXJ0IEdsb2JhbCBSb290IENBMIIBIjANBgkqhkiG
+9w0BAQEFAAOCAQ8AMIIBCgKCAQEA4jvhEXLeqKTTo1eqUKKPC3eQyaKl7hLOllsB
+CSDMAZOnTjC3U/dDxGkAV53ijSLdhwZAAIEJzs4bg7/fzTtxRuLWZscFs3YnFo97
+nh6Vfe63SKMI2tavegw5BmV/Sl0fvBf4q77uKNd0f3p4mVmFaG5cIzJLv07A6Fpt
+43C/dxC//AH2hdmoRBBYMql1GNXRor5H4idq9Joz+EkIYIvUX7Q6hL+hqkpMfT7P
+T19sdl6gSzeRntwi5m3OFBqOasv+zbMUZBfHWymeMr/y7vrTC0LUq7dBMtoM1O/4
+gdW7jVg/tRvoSSiicNoxBN33shbyTApOB6jtSj1etX+jkMOvJwIDAQABo2MwYTAO
+BgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUA95QNVbR
+TLtm8KPiGxvDl7I90VUwHwYDVR0jBBgwFoAUA95QNVbRTLtm8KPiGxvDl7I90VUw
+DQYJKoZIhvcNAQEFBQADggEBAMucN6pIExIK+t1EnE9SsPTfrgT1eXkIoyQY/Esr
+hMAtudXH/vTBH1jLuG2cenTnmCmrEbXjcKChzUyImZOMkXDiqw8cvpOp/2PV5Adg
+06O/nVsJ8dWO41P0jmP6P6fbtGbfYmbW0W5BjfIttep3Sp+dWOIrWcBAI+0tKIJF
+PnlUkiaY4IBIqDfv8NZ5YBberOgOzW6sRBc4L0na4UU+Krk2U886UAb3LujEV0ls
+YSEY1QSteDwsOoBrp+uvFRTp2InBuThs4pFsiv9kuXclVzDAGySj4dzp30d8tbQk
+CAUw7C29C79Fv1C5qfPrmAESrciIxpg0X40KPMbp1ZWVbd4=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIDkzCCAnugAwIBAgIQFBOWgxRVjOp7Y+X8NId3RDANBgkqhkiG9w0BAQUFADA0
+MRMwEQYDVQQDEwpDb21TaWduIENBMRAwDgYDVQQKEwdDb21TaWduMQswCQYDVQQG
+EwJJTDAeFw0wNDAzMjQxMTMyMThaFw0yOTAzMTkxNTAyMThaMDQxEzARBgNVBAMT
+CkNvbVNpZ24gQ0ExEDAOBgNVBAoTB0NvbVNpZ24xCzAJBgNVBAYTAklMMIIBIjAN
+BgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA8ORUaSvTx49qROR+WCf4C9DklBKK
+8Rs4OC8fMZwG1Cyn3gsqrhqg455qv588x26i+YtkbDqthVVRVKU4VbirgwTyP2Q2
+98CNQ0NqZtH3FyrV7zb6MBBC11PN+fozc0yz6YQgitZBJzXkOPqUm7h65HkfM/sb
+2CEJKHxNGGleZIp6GZPKfuzzcuc3B1hZKKxC+cX/zT/npfo4sdAMx9lSGlPWgcxC
+ejVb7Us6eva1jsz/D3zkYDaHL63woSV9/9JLEYhwVKZBqGdTUkJe5DSe5L6j7Kpi
+Xd3DTKaCQeQzC6zJMw9kglcq/QytNuEMrkvF7zuZ2SOzW120V+x0cAwqTwIDAQAB
+o4GgMIGdMAwGA1UdEwQFMAMBAf8wPQYDVR0fBDYwNDAyoDCgLoYsaHR0cDovL2Zl
+ZGlyLmNvbXNpZ24uY28uaWwvY3JsL0NvbVNpZ25DQS5jcmwwDgYDVR0PAQH/BAQD
+AgGGMB8GA1UdIwQYMBaAFEsBmz5WGmU2dst7l6qSBe4y5ygxMB0GA1UdDgQWBBRL
+AZs+VhplNnbLe5eqkgXuMucoMTANBgkqhkiG9w0BAQUFAAOCAQEA0Nmlfv4pYEWd
+foPPbrxHbvUanlR2QnG0PFg/LUAlQvaBnPGJEMgOqnhPOAlXsDzACPw1jvFIUY0M
+cXS6hMTXcpuEfDhOZAYnKuGntewImbQKDdSFc8gS4TXt8QUxHXOZDOuWyt3T5oWq
+8Ir7dcHyCTxlZWTzTNity4hp8+SDtwy9F1qWF8pb/627HOkthIDYIb6FUtnUdLlp
+hbpN7Sgy6/lhSuTENh4Z3G+EER+V9YMoGKgzkkMn3V0TBEVPh9VGzT2ouvDzuFYk
+Res3x+F2T3I5GN9+dHLHcy056mDmrRGiVod7w2ia/viMcKjfZTL0pECMocJEAw6U
+AGegcQCCSA==
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIEZDCCA0ygAwIBAgIQRL4Mi1AAJLQR0zYwS8AzdzANBgkqhkiG9w0BAQUFADCB
+ozELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAlVUMRcwFQYDVQQHEw5TYWx0IExha2Ug
+Q2l0eTEeMBwGA1UEChMVVGhlIFVTRVJUUlVTVCBOZXR3b3JrMSEwHwYDVQQLExho
+dHRwOi8vd3d3LnVzZXJ0cnVzdC5jb20xKzApBgNVBAMTIlVUTi1VU0VSRmlyc3Qt
+TmV0d29yayBBcHBsaWNhdGlvbnMwHhcNOTkwNzA5MTg0ODM5WhcNMTkwNzA5MTg1
+NzQ5WjCBozELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAlVUMRcwFQYDVQQHEw5TYWx0
+IExha2UgQ2l0eTEeMBwGA1UEChMVVGhlIFVTRVJUUlVTVCBOZXR3b3JrMSEwHwYD
+VQQLExhodHRwOi8vd3d3LnVzZXJ0cnVzdC5jb20xKzApBgNVBAMTIlVUTi1VU0VS
+Rmlyc3QtTmV0d29yayBBcHBsaWNhdGlvbnMwggEiMA0GCSqGSIb3DQEBAQUAA4IB
+DwAwggEKAoIBAQCz+5Gh5DZVhawGNFugmliy+LUPBXeDrjKxdpJo7CNKyXY/45y2
+N3kDuatpjQclthln5LAbGHNhSuh+zdMvZOOmfAz6F4CjDUeJT1FxL+78P/m4FoCH
+iZMlIJpDgmkkdihZNaEdwH+DBmQWICzTSaSFtMBhf1EI+GgVkYDLpdXuOzr0hARe
+YFmnjDRy7rh4xdE7EkpvfmUnuaRVxblvQ6TFHSyZwFKkeEwVs0CYCGtDxgGwenv1
+axwiP8vv/6jQOkt2FZ7S0cYu49tXGzKiuG/ohqY/cKvlcJKrRB5AUPuco2LkbG6g
+yN7igEL66S/ozjIEj3yNtxyjNTwV3Z7DrpelAgMBAAGjgZEwgY4wCwYDVR0PBAQD
+AgHGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFPqGydvguul49Uuo1hXf8NPh
+ahQ8ME8GA1UdHwRIMEYwRKBCoECGPmh0dHA6Ly9jcmwudXNlcnRydXN0LmNvbS9V
+VE4tVVNFUkZpcnN0LU5ldHdvcmtBcHBsaWNhdGlvbnMuY3JsMA0GCSqGSIb3DQEB
+BQUAA4IBAQCk8yXM0dSRgyLQzDKrm5ZONJFUICU0YV8qAhXhi6r/fWRRzwr/vH3Y
+IWp4yy9Rb/hCHTO967V7lMPDqaAt39EpHx3+jz+7qEUqf9FuVSTiuwL7MT++6Lzs
+QCv4AdRWOOTKRIK1YSAhZ2X28AvnNPilwpyjXEAfhZOVBt5P1CeptqX8Fs1zMT+4
+ZSfP1FMa8Kxun08FDAOBp4QpxFq9ZFdyrTvPNximmMatBrTcCKME1SmklpoSZ0qM
+YEWd8SOasACcaLWYUNPvji6SZbFIPiG+FTAqDbUMo2s/rn9X9R+WfN9v3YIwLGUb
+QErNaLly7HF27FSOH4UMAWr6pjisH8SE
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIDtzCCAp+gAwIBAgIQDOfg5RfYRv6P5WD8G/AwOTANBgkqhkiG9w0BAQUFADBl
+MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3
+d3cuZGlnaWNlcnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJv
+b3QgQ0EwHhcNMDYxMTEwMDAwMDAwWhcNMzExMTEwMDAwMDAwWjBlMQswCQYDVQQG
+EwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNl
+cnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3QgQ0EwggEi
+MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCtDhXO5EOAXLGH87dg+XESpa7c
+JpSIqvTO9SA5KFhgDPiA2qkVlTJhPLWxKISKityfCgyDF3qPkKyK53lTXDGEKvYP
+mDI2dsze3Tyoou9q+yHyUmHfnyDXH+Kx2f4YZNISW1/5WBg1vEfNoTb5a3/UsDg+
+wRvDjDPZ2C8Y/igPs6eD1sNuRMBhNZYW/lmci3Zt1/GiSw0r/wty2p5g0I6QNcZ4
+VYcgoc/lbQrISXwxmDNsIumH0DJaoroTghHtORedmTpyoeb6pNnVFzF1roV9Iq4/
+AUaG9ih5yLHa5FcXxH4cDrC0kqZWs72yl+2qp/C3xag/lRbQ/6GW6whfGHdPAgMB
+AAGjYzBhMA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQW
+BBRF66Kv9JLLgjEtUYunpyGd823IDzAfBgNVHSMEGDAWgBRF66Kv9JLLgjEtUYun
+pyGd823IDzANBgkqhkiG9w0BAQUFAAOCAQEAog683+Lt8ONyc3pklL/3cmbYMuRC
+dWKuh+vy1dneVrOfzM4UKLkNl2BcEkxY5NM9g0lFWJc1aRqoR+pWxnmrEthngYTf
+fwk8lOa4JiwgvT2zKIn3X/8i4peEH+ll74fg38FnSbNd67IJKusm7Xi+fT8r87cm
+NW1fiQG2SVufAQWbqz0lwcy2f8Lxb4bG+mRo64EtlOtCt/qMHt1i8b5QZ7dsvfPx
+H2sMNgcWfzd8qVttevESRmCD1ycEvkvOl77DZypoEd+A5wwzZr8TDRRu838fYxAe
++o0bJW1sj6W3YQGx0qMmoRBxna3iw/nDmVG3KwcIzi7mULKn+gpFL6Lw8g==
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIICiDCCAg2gAwIBAgIQNfwmXNmET8k9Jj1Xm67XVjAKBggqhkjOPQQDAzCBhDEL
+MAkGA1UEBhMCVVMxFTATBgNVBAoTDHRoYXd0ZSwgSW5jLjE4MDYGA1UECxMvKGMp
+IDIwMDcgdGhhd3RlLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxJDAi
+BgNVBAMTG3RoYXd0ZSBQcmltYXJ5IFJvb3QgQ0EgLSBHMjAeFw0wNzExMDUwMDAw
+MDBaFw0zODAxMTgyMzU5NTlaMIGEMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMdGhh
+d3RlLCBJbmMuMTgwNgYDVQQLEy8oYykgMjAwNyB0aGF3dGUsIEluYy4gLSBGb3Ig
+YXV0aG9yaXplZCB1c2Ugb25seTEkMCIGA1UEAxMbdGhhd3RlIFByaW1hcnkgUm9v
+dCBDQSAtIEcyMHYwEAYHKoZIzj0CAQYFK4EEACIDYgAEotWcgnuVnfFSeIf+iha/
+BebfowJPDQfGAFG6DAJSLSKkQjnE/o/qycG+1E3/n3qe4rF8mq2nhglzh9HnmuN6
+papu+7qzcMBniKI11KOasf2twu8x+qi58/sIxpHR+ymVo0IwQDAPBgNVHRMBAf8E
+BTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUmtgAMADna3+FGO6Lts6K
+DPgR4bswCgYIKoZIzj0EAwMDaQAwZgIxAN344FdHW6fmCsO99YCKlzUNG4k8VIZ3
+KMqh9HneteY4sPBlcIx/AlTCv//YoT7ZzwIxAMSNlPzcU9LcnXgWHxUzI1NS41ox
+XZ3Krr0TKUQNJ1uo52icEvdYPy5yAlejj6EULg==
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIETTCCAzWgAwIBAgIBATANBgkqhkiG9w0BAQUFADBtMQswCQYDVQQGEwJDSDEO
+MAwGA1UEChMFYWRtaW4xETAPBgNVBAsTCFNlcnZpY2VzMSIwIAYDVQQLExlDZXJ0
+aWZpY2F0aW9uIEF1dGhvcml0aWVzMRcwFQYDVQQDEw5BZG1pbkNBLUNELVQwMTAe
+Fw0wNjAxMjUxMzM2MTlaFw0xNjAxMjUxMjM2MTlaMG0xCzAJBgNVBAYTAkNIMQ4w
+DAYDVQQKEwVhZG1pbjERMA8GA1UECxMIU2VydmljZXMxIjAgBgNVBAsTGUNlcnRp
+ZmljYXRpb24gQXV0aG9yaXRpZXMxFzAVBgNVBAMTDkFkbWluQ0EtQ0QtVDAxMIIB
+IjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA0jQlMZmpLDhV+GNR9TAoSNle
+JgQB4xAXJELQf5/ySMfoFA4MmjKqYXQkB6MGPuQKwR9XRRSPf61vqb8YPsdjRmgp
+byHBcUd5t0N8RX6wRZUnPMW+bCCo2VqAU4XFbnlc2gHKaam0wdTtbBTXEkv0ieIH
+fxCfFxXqSsSr60IkF/2/xbrAgV/QD5yHk6Ie8feAVWwi5UtaFqtu4LiFEh2QMyxs
+Oyz1OcvKzkM2g873tyiE7jzMgZP+Ww3tibk2F9+e6ZeiB37TLOmVtvgpmrws4fiI
+rFNXEYSWBVrUTbn81U47yWzOgf5fEHP07bRV5QOCzCm99qNimsbL6CG7nT78CQID
+AQABo4H3MIH0MBIGA1UdEwEB/wQIMAYBAf8CAQAwga4GA1UdIASBpjCBozCBoAYI
+YIV0AREDFQEwgZMwSAYIKwYBBQUHAgIwPBo6VGhpcyBpcyB0aGUgQWRtaW5DQS1D
+RC1UMDEgQ2VydGlmaWNhdGUgUHJhY3RpY2UgU3RhdGVtZW50LjBHBggrBgEFBQcC
+ARY7aHR0cDovL3d3dy5wa2kuYWRtaW4uY2gvcG9saWN5L0NQU18yXzE2Xzc1Nl8x
+XzE3XzNfMjFfMS5wZGYwDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBQqxGkKocZV
+xgNucM6GgbOkD6oZ2zANBgkqhkiG9w0BAQUFAAOCAQEAn356bbusjI5glGXRQ1DR
+v21qQf0S4s3GHyZm7cqdOkFleM70ArBT+kOP5Nm7rlSAFyVgEkmBdOg7s9tlXClU
+yeZFnp6UEYRUcijPN8D1VaNRK6PIUObpDBQT0C+kAfxG9z4v29T0SxT4sgAdC/xQ
+Fyv58Fp9bPn7owuKwKcyCH1XSyi/Bp4XFELlLOaigBZO/w+dPBz4FcJSdZjU+BaJ
+0E3nKAjHlShO5ouBSZnaJz3p+nkw2Wyo36s6GxCK0XbkSP45iniIG4FmwwZkonYF
+ypQntHbx2oL7tUQQY0PDo8bGBMcPy/G2j+dciqZRlsnfgMy10SCzQ9MUx92xUG2V
+eg==
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIFVTCCBD2gAwIBAgIEO/OB0DANBgkqhkiG9w0BAQUFADBsMQswCQYDVQQGEwJj
+aDEOMAwGA1UEChMFYWRtaW4xETAPBgNVBAsTCFNlcnZpY2VzMSIwIAYDVQQLExlD
+ZXJ0aWZpY2F0aW9uIEF1dGhvcml0aWVzMRYwFAYDVQQDEw1BZG1pbi1Sb290LUNB
+MB4XDTAxMTExNTA4NTEwN1oXDTIxMTExMDA3NTEwN1owbDELMAkGA1UEBhMCY2gx
+DjAMBgNVBAoTBWFkbWluMREwDwYDVQQLEwhTZXJ2aWNlczEiMCAGA1UECxMZQ2Vy
+dGlmaWNhdGlvbiBBdXRob3JpdGllczEWMBQGA1UEAxMNQWRtaW4tUm9vdC1DQTCC
+ASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMvgr0QUIv5qF0nyXZ3PXAJi
+C4C5Wr+oVTN7oxIkXkxvO0GJToM9n7OVJjSmzBL0zJ2HXj0MDRcvhSY+KiZZc6Go
+vDvr5Ua481l7ILFeQAFtumeza+vvxeL5Nd0Maga2miiacLNAKXbAcUYRa0Ov5VZB
+++YcOYNNt/aisWbJqA2y8He+NsEgJzK5zNdayvYXQTZN+7tVgWOck16Da3+4FXdy
+fH1NCWtZlebtMKtERtkVAaVbiWW24CjZKAiVfggjsiLo3yVMPGj3budLx5D9hEEm
+vlyDOtcjebca+AcZglppWMX/iHIrx7740y0zd6cWEqiLIcZCrnpkr/KzwO135GkC
+AwEAAaOCAf0wggH5MA8GA1UdEwEB/wQFMAMBAf8wgZkGA1UdIASBkTCBjjCBiwYI
+YIV0AREDAQAwfzArBggrBgEFBQcCAjAfGh1UaGlzIGlzIHRoZSBBZG1pbi1Sb290
+LUNBIENQUzBQBggrBgEFBQcCARZEaHR0cDovL3d3dy5pbmZvcm1hdGlrLmFkbWlu
+LmNoL1BLSS9saW5rcy9DUFNfMl8xNl83NTZfMV8xN18zXzFfMC5wZGYwfwYDVR0f
+BHgwdjB0oHKgcKRuMGwxFjAUBgNVBAMTDUFkbWluLVJvb3QtQ0ExIjAgBgNVBAsT
+GUNlcnRpZmljYXRpb24gQXV0aG9yaXRpZXMxETAPBgNVBAsTCFNlcnZpY2VzMQ4w
+DAYDVQQKEwVhZG1pbjELMAkGA1UEBhMCY2gwHQYDVR0OBBYEFIKf+iNzIPGXi7JM
+Tb5CxX9mzWToMIGZBgNVHSMEgZEwgY6AFIKf+iNzIPGXi7JMTb5CxX9mzWTooXCk
+bjBsMQswCQYDVQQGEwJjaDEOMAwGA1UEChMFYWRtaW4xETAPBgNVBAsTCFNlcnZp
+Y2VzMSIwIAYDVQQLExlDZXJ0aWZpY2F0aW9uIEF1dGhvcml0aWVzMRYwFAYDVQQD
+Ew1BZG1pbi1Sb290LUNBggQ784HQMA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0B
+AQUFAAOCAQEAeE96XCYRpy6umkPKXDWCRn7INo96ZrWpMggcDORuofHIwdTkgOeM
+vWOxDN/yuT7CC3FAaUajbPRbDw0hRMcqKz0aC8CgwcyIyhw/rFK29mfNTG3EviP9
+QSsEbnelFnjpm1wjz4EaBiFjatwpUbI6+Zv3XbEt9QQXBn+c6DeFLe4xvC4B+MTr
+a440xTk59pSYux8OHhEvqIwHCkiijGqZhTS3KmGFeBopaR+dJVBRBMoXwzk4B3Hn
+0Zib1dEYFZa84vPJZyvxCbLOnPRDJgH6V2uQqbG+6DXVaf/wORVOvF/wzzv0viM/
+RWbEtJZdvo8N3sdtCULzifnxP/V0T9+4ZQ==
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIG0TCCBbmgAwIBAgIBezANBgkqhkiG9w0BAQUFADCByTELMAkGA1UEBhMCSFUx
+ETAPBgNVBAcTCEJ1ZGFwZXN0MScwJQYDVQQKEx5OZXRMb2NrIEhhbG96YXRiaXp0
+b25zYWdpIEtmdC4xGjAYBgNVBAsTEVRhbnVzaXR2YW55a2lhZG9rMUIwQAYDVQQD
+EzlOZXRMb2NrIE1pbm9zaXRldHQgS296amVneXpvaSAoQ2xhc3MgUUEpIFRhbnVz
+aXR2YW55a2lhZG8xHjAcBgkqhkiG9w0BCQEWD2luZm9AbmV0bG9jay5odTAeFw0w
+MzAzMzAwMTQ3MTFaFw0yMjEyMTUwMTQ3MTFaMIHJMQswCQYDVQQGEwJIVTERMA8G
+A1UEBxMIQnVkYXBlc3QxJzAlBgNVBAoTHk5ldExvY2sgSGFsb3phdGJpenRvbnNh
+Z2kgS2Z0LjEaMBgGA1UECxMRVGFudXNpdHZhbnlraWFkb2sxQjBABgNVBAMTOU5l
+dExvY2sgTWlub3NpdGV0dCBLb3pqZWd5em9pIChDbGFzcyBRQSkgVGFudXNpdHZh
+bnlraWFkbzEeMBwGCSqGSIb3DQEJARYPaW5mb0BuZXRsb2NrLmh1MIIBIjANBgkq
+hkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAx1Ilstg91IRVCacbvWy5FPSKAtt2/Goq
+eKvld/Bu4IwjZ9ulZJm53QE+b+8tmjwi8F3JV6BVQX/yQ15YglMxZc4e8ia6AFQe
+r7C8HORSjKAyr7c3sVNnaHRnUPYtLmTeriZ539+Zhqurf4XsoPuAzPS4DB6TRWO5
+3Lhbm+1bOdRfYrCnjnxmOCyqsQhjF2d9zL2z8cM/z1A57dEZgxXbhxInlrfa6uWd
+vLrqOU+L73Sa58XQ0uqGURzk/mQIKAR5BevKxXEOC++r6uwSEaEYBTJp0QwsGj0l
+mT+1fMptsK6ZmfoIYOcZwvK9UdPM0wKswREMgM6r3JSda6M5UzrWhQIDAMV9o4IC
+wDCCArwwEgYDVR0TAQH/BAgwBgEB/wIBBDAOBgNVHQ8BAf8EBAMCAQYwggJ1Bglg
+hkgBhvhCAQ0EggJmFoICYkZJR1lFTEVNISBFemVuIHRhbnVzaXR2YW55IGEgTmV0
+TG9jayBLZnQuIE1pbm9zaXRldHQgU3pvbGdhbHRhdGFzaSBTemFiYWx5emF0YWJh
+biBsZWlydCBlbGphcmFzb2sgYWxhcGphbiBrZXN6dWx0LiBBIG1pbm9zaXRldHQg
+ZWxla3Ryb25pa3VzIGFsYWlyYXMgam9naGF0YXMgZXJ2ZW55ZXN1bGVzZW5laywg
+dmFsYW1pbnQgZWxmb2dhZGFzYW5hayBmZWx0ZXRlbGUgYSBNaW5vc2l0ZXR0IFN6
+b2xnYWx0YXRhc2kgU3phYmFseXphdGJhbiwgYXogQWx0YWxhbm9zIFN6ZXJ6b2Rl
+c2kgRmVsdGV0ZWxla2JlbiBlbG9pcnQgZWxsZW5vcnplc2kgZWxqYXJhcyBtZWd0
+ZXRlbGUuIEEgZG9rdW1lbnR1bW9rIG1lZ3RhbGFsaGF0b2sgYSBodHRwczovL3d3
+dy5uZXRsb2NrLmh1L2RvY3MvIGNpbWVuIHZhZ3kga2VyaGV0b2sgYXogaW5mb0Bu
+ZXRsb2NrLm5ldCBlLW1haWwgY2ltZW4uIFdBUk5JTkchIFRoZSBpc3N1YW5jZSBh
+bmQgdGhlIHVzZSBvZiB0aGlzIGNlcnRpZmljYXRlIGFyZSBzdWJqZWN0IHRvIHRo
+ZSBOZXRMb2NrIFF1YWxpZmllZCBDUFMgYXZhaWxhYmxlIGF0IGh0dHBzOi8vd3d3
+Lm5ldGxvY2suaHUvZG9jcy8gb3IgYnkgZS1tYWlsIGF0IGluZm9AbmV0bG9jay5u
+ZXQwHQYDVR0OBBYEFAlqYhaSsFq7VQ7LdTI6MuWyIckoMA0GCSqGSIb3DQEBBQUA
+A4IBAQCRalCc23iBmz+LQuM7/KbD7kPgz/PigDVJRXYC4uMvBcXxKufAQTPGtpvQ
+MznNwNuhrWw3AkxYQTvyl5LGSKjN5Yo5iWH5Upfpvfb5lHTocQ68d4bDBsxafEp+
+NFAwLvt/MpqNPfMgW/hqyobzMUwsWYACff44yTB1HLdV47yfuqhthCgFdbOLDcCR
+VCHnpgu0mfVRQdzNo0ci2ccBgcTcR08m6h/t280NmPSjnLRzMkqWmf68f8glWPhY
+83ZmiVSkpj7EUFy6iRiCdUgh0k8T6GB+B3bbELVR5qq5aKrN9p2QdRLqOBrKROi3
+macqaJVmlaut74nLYKkGEsaUR+ko
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIICPzCCAcWgAwIBAgIQBVVWvPJepDU1w6QP1atFcjAKBggqhkjOPQQDAzBhMQsw
+CQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cu
+ZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBHMzAe
+Fw0xMzA4MDExMjAwMDBaFw0zODAxMTUxMjAwMDBaMGExCzAJBgNVBAYTAlVTMRUw
+EwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5jb20x
+IDAeBgNVBAMTF0RpZ2lDZXJ0IEdsb2JhbCBSb290IEczMHYwEAYHKoZIzj0CAQYF
+K4EEACIDYgAE3afZu4q4C/sLfyHS8L6+c/MzXRq8NOrexpu80JX28MzQC7phW1FG
+fp4tn+6OYwwX7Adw9c+ELkCDnOg/QW07rdOkFFk2eJ0DQ+4QE2xy3q6Ip6FrtUPO
+Z9wj/wMco+I+o0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBhjAd
+BgNVHQ4EFgQUs9tIpPmhxdiuNkHMEWNpYim8S8YwCgYIKoZIzj0EAwMDaAAwZQIx
+AK288mw/EkrRLTnDCgmXc/SINoyIJ7vmiI1Qhadj+Z4y3maTD/HMsQmP3Wyr+mt/
+oAIwOWZbwmSNuJ5Q3KjVSaLtx9zRSX8XAbjIho9OjIgrqJqpisXRAL34VOKa5Vt8
+sycX
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIFkjCCA3qgAwIBAgIBCDANBgkqhkiG9w0BAQUFADA6MQswCQYDVQQGEwJDTjER
+MA8GA1UEChMIVW5pVHJ1c3QxGDAWBgNVBAMTD1VDQSBHbG9iYWwgUm9vdDAeFw0w
+ODAxMDEwMDAwMDBaFw0zNzEyMzEwMDAwMDBaMDoxCzAJBgNVBAYTAkNOMREwDwYD
+VQQKEwhVbmlUcnVzdDEYMBYGA1UEAxMPVUNBIEdsb2JhbCBSb290MIICIjANBgkq
+hkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA2rPlBlA/9nP3xDK/RqUlYjOHsGj+p9+I
+A2N9Apb964fJ7uIIu527u+RBj8cwiQ9tJMAEbBSUgU2gDXRm8/CFr/hkGd656YGT
+0CiFmUdCSiw8OCdKzP/5bBnXtfPvm65bNAbXj6ITBpyKhELVs6OQaG2BkO5NhOxM
+cE4t3iQ5zhkAQ5N4+QiGHUPR9HK8BcBn+sBR0smFBySuOR56zUHSNqth6iur8CBV
+mTxtLRwuLnWW2HKX4AzKaXPudSsVCeCObbvaE/9GqOgADKwHLx25urnRoPeZnnRc
+GQVmMc8+KlL+b5/zub35wYH1N9ouTIElXfbZlJrTNYsgKDdfUet9Ysepk9H50DTL
+qScmLCiQkjtVY7cXDlRzq6987DqrcDOsIfsiJrOGrCOp139tywgg8q9A9f9ER3Hd
+J90TKKHqdjn5EKCgTUCkJ7JZFStsLSS3JGN490MYeg9NEePorIdCjedYcaSrbqLA
+l3y74xNLytu7awj5abQEctXDRrl36v+6++nwOgw19o8PrgaEFt2UVdTvyie3AzzF
+HCYq9TyopZWbhvGKiWf4xwxmse1Bv4KmAGg6IjTuHuvlb4l0T2qqaqhXZ1LUIGHB
+zlPL/SR/XybfoQhplqCe/klD4tPq2sTxiDEhbhzhzfN1DiBEFsx9c3Q1RSw7gdQg
+7LYJjD5IskkCAwEAAaOBojCBnzALBgNVHQ8EBAMCAQYwDAYDVR0TBAUwAwEB/zBj
+BgNVHSUEXDBaBggrBgEFBQcDAQYIKwYBBQUHAwIGCCsGAQUFBwMDBggrBgEFBQcD
+BAYIKwYBBQUHAwUGCCsGAQUFBwMGBggrBgEFBQcDBwYIKwYBBQUHAwgGCCsGAQUF
+BwMJMB0GA1UdDgQWBBTZw9P4gJJnzF3SOqLXcaK0xDiALTANBgkqhkiG9w0BAQUF
+AAOCAgEA0Ih5ygiq9ws0oE4Jwul+NUiJcIQjL1HDKy9e21NrW3UIKlS6Mg7VxnGF
+sZdJgPaE0PC6t3GUyHlrpsVE6EKirSUtVy/m1jEp+hmJVCl+t35HNmktbjK81HXa
+QnO4TuWDQHOyXd/URHOmYgvbqm4FjMh/Rk85hZCdvBtUKayl1/7lWFZXbSyZoUkh
+1WHGjGHhdSTBAd0tGzbDLxLMC9Z4i3WA6UG5iLHKPKkWxk4V43I29tSgQYWvimVw
+TbVEEFDs7d9t5tnGwBLxSzovc+k8qe4bqi81pZufTcU0hF8mFGmzI7GJchT46U1R
+IgP/SobEHOh7eQrbRyWBfvw0hKxZuFhD5D1DCVR0wtD92e9uWfdyYJl2b/Unp7uD
+pEqB7CmB9HdL4UISVdSGKhK28FWbAS7d9qjjGcPORy/AeGEYWsdl/J1GW1fcfA67
+loMQfFUYCQSu0feLKj6g5lDWMDbX54s4U+xJRODPpN/xU3uLWrb2EZBL1nXz/gLz
+Ka/wI3J9FO2pXd96gZ6bkiL8HvgBRUGXx2sBYb4zaPKgZYRmvOAqpGjTcezHCN6j
+w8k2SjTxF+KAryAhk5Qe5hXTVGLxtTgv48y5ZwSpuuXu+RBuyy5+E6+SFP7zJ3N7
+OPxzbbm5iPZujAv1/P8JDrMtXnt145Ik4ubhWD5LKAN1axibRww=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIDdjCCAl6gAwIBAgIEOhsEBTANBgkqhkiG9w0BAQUFADBRMQswCQYDVQQGEwJE
+SzEMMAoGA1UEChMDS01EMQ8wDQYDVQQLEwZLTUQtQ0ExIzAhBgNVBAMTGktNRC1D
+QSBLdmFsaWZpY2VyZXQgUGVyc29uMB4XDTAwMTEyMTIzMjQ1OVoXDTE1MTEyMjIz
+MjQ1OVowUTELMAkGA1UEBhMCREsxDDAKBgNVBAoTA0tNRDEPMA0GA1UECxMGS01E
+LUNBMSMwIQYDVQQDExpLTUQtQ0EgS3ZhbGlmaWNlcmV0IFBlcnNvbjCCASIwDQYJ
+KoZIhvcNAQEBBQADggEPADCCAQoCggEBANriF4Xd6yD7ZlBE317UBDObn+vRMVc6
+p3wNQODdEDJe2z1ncCz9NJvhoLGdOJhyg7VVPh0P2c+KZ9WI9mWOKZI2bp2WkLju
+jCcxbhTrurY3Wfc6gwLBqqFV8wWgaZKmvVWizjw9Kyi25f3yX4fOho6Qq2lvVbub
+tvVFXAd51GJ+/2Yed+a4Or2bz2RcqHS81B3pywsD4mgJR5xREv5jqPfwNP+V7bkc
+X+pfO4kVhZ/V+8MSPdQHgcV/iB3wP2mwgWyIBNc1reBidGTiz8unnWu55hcNfsvt
+LJbTs9OHhsR7naRuy+S402nDnD5vnONOFEsiHn46w+T0rtu7h6j4OvkCAwEAAaNW
+MFQwEgYDVR0TAQH/BAgwBgEB/wIBADAdBgNVHQ4EFgQUeWLqmhI42Jxj7DifDsW+
+DlQhKD0wHwYDVR0jBBgwFoAUeWLqmhI42Jxj7DifDsW+DlQhKD0wDQYJKoZIhvcN
+AQEFBQADggEBANML/P42OuJ9aUV/0fItuIyc1JhqWvSqn5bXj+9eyEegcp8bHLHY
+42D1O+z0lNipdjYPSdMJ0wZOEUhr+150SdDQ1P/zQL8AUaLEBkRt7ZdzXPVH3PER
+qnf9IrpYBknZKfCAoVchA6Rr9WU3Sd8bMoRfMLKg8c0M8G6EPwCTcOFriSkbtvNG
+zd8r8I+WfUYIN/p8DI9JT9qfjVODnYPRMUm6KPvq27TsrGruKrqyaV94kWc8co8A
+v3zFLeCtghvUiRBdx+8Q7m5t4CkuSr0WINrqjIPFW2QrM1r82y09Fd16RkqL4LOg
+Lh6vB5KnTApv62rWdw7zWwYnjY6/vXYY1Aw=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIF4DCCA8igAwIBAgIRAPL6ZOJ0Y9ON/RAdBB92ylgwDQYJKoZIhvcNAQELBQAw
+ZzELMAkGA1UEBhMCY2gxETAPBgNVBAoTCFN3aXNzY29tMSUwIwYDVQQLExxEaWdp
+dGFsIENlcnRpZmljYXRlIFNlcnZpY2VzMR4wHAYDVQQDExVTd2lzc2NvbSBSb290
+IEVWIENBIDIwHhcNMTEwNjI0MDk0NTA4WhcNMzEwNjI1MDg0NTA4WjBnMQswCQYD
+VQQGEwJjaDERMA8GA1UEChMIU3dpc3Njb20xJTAjBgNVBAsTHERpZ2l0YWwgQ2Vy
+dGlmaWNhdGUgU2VydmljZXMxHjAcBgNVBAMTFVN3aXNzY29tIFJvb3QgRVYgQ0Eg
+MjCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAMT3HS9X6lds93BdY7Bx
+UglgRCgzo3pOCvrY6myLURYaVa5UJsTMRQdBTxB5f3HSek4/OE6zAMaVylvNwSqD
+1ycfMQ4jFrclyxy0uYAyXhqdk/HoPGAsp15XGVhRXrwsVgu42O+LgrQ8uMIkqBPH
+oCE2G3pXKSinLr9xJZDzRINpUKTk4RtiGZQJo/PDvO/0vezbE53PnUgJUmfANykR
+HvvSEaeFGHR55E+FFOtSN+KxRdjMDUN/rhPSays/p8LiqG12W0OfvrSdsyaGOx9/
+5fLoZigWJdBLlzin5M8J0TbDC77aO0RYjb7xnglrPvMyxyuHxuxenPaHZa0zKcQv
+idm5y8kDnftslFGXEBuGCxobP/YCfnvUxVFkKJ3106yDgYjTdLRZncHrYTNaRdHL
+OdAGalNgHa/2+2m8atwBz735j9m9W8E6X47aD0upm50qKGsaCnw8qyIL5XctcfaC
+NYGu+HuB5ur+rPQam3Rc6I8k9l2dRsQs0h4rIWqDJ2dVSqTjyDKXZpBy2uPUZC5f
+46Fq9mDU5zXNysRojddxyNMkM3OxbPlq4SjbX8Y96L5V5jcb7STZDxmPX2MYWFCB
+UWVv8p9+agTnNCRxunZLWB4ZvRVgRaoMEkABnRDixzgHcgplwLa7JSnaFp6LNYth
+7eVxV4O1PHGf40+/fh6Bn0GXAgMBAAGjgYYwgYMwDgYDVR0PAQH/BAQDAgGGMB0G
+A1UdIQQWMBQwEgYHYIV0AVMCAgYHYIV0AVMCAjASBgNVHRMBAf8ECDAGAQH/AgED
+MB0GA1UdDgQWBBRF2aWBbj2ITY1x0kbBbkUe88SAnTAfBgNVHSMEGDAWgBRF2aWB
+bj2ITY1x0kbBbkUe88SAnTANBgkqhkiG9w0BAQsFAAOCAgEAlDpzBp9SSzBc1P6x
+XCX5145v9Ydkn+0UjrgEjihLj6p7jjm02Vj2e6E1CqGdivdj5eu9OYLU43otb98T
+PLr+flaYC/NUn81ETm484T4VvwYmneTwkLbUwp4wLh/vx3rEUMfqe9pQy3omywC0
+Wqu1kx+AiYQElY2NfwmTv9SoqORjbdlk5LgpWgi/UOGED1V7XwgiG/W9mR4U9s70
+WBCCswo9GcG/W6uqmdjyMb3lOGbcWAXH7WMaLgqXfIeTK7KK4/HsGOV1timH59yL
+Gn602MnTihdsfSlEvoqq9X46Lmgxk7lq2prg2+kupYTNHAq4Sgj5nPFhJpiTt3tm
+7JFe3VE/23MPrQRYCd0EApUKPtN236YQHoA96M2kZNEzx5LH4k5E4wnJTsJdhw4S
+nr8PyQUQ3nqjsTzyP6WqJ3mtMX0f/fwZacXduT98zca0wjAefm6S139hdlqP65VN
+vBFuIXxZN5nQBrz5Bm0yFqXZaajh3DyAHmBR3NdUIR7KYndP+tiPsys6DXhyyWhB
+WkdKwqPrGtcKqzwyVcgKEZzfdNbwQBUdyLmPtTbFr/giuMod89a2GQ+fYWVq6nTI
+fI/DT11lgh/ZDYnadXL77/FHZxOzyNEZiCcmmpl5fx7kLD977vHeTYuWl8PVP3wb
+I+2ksx0WckNLIOFZfsLorSa/ovc=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIF8TCCA9mgAwIBAgIQALC3WhZIX7/hy/WL1xnmfTANBgkqhkiG9w0BAQsFADA4
+MQswCQYDVQQGEwJFUzEUMBIGA1UECgwLSVpFTlBFIFMuQS4xEzARBgNVBAMMCkl6
+ZW5wZS5jb20wHhcNMDcxMjEzMTMwODI4WhcNMzcxMjEzMDgyNzI1WjA4MQswCQYD
+VQQGEwJFUzEUMBIGA1UECgwLSVpFTlBFIFMuQS4xEzARBgNVBAMMCkl6ZW5wZS5j
+b20wggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDJ03rKDx6sp4boFmVq
+scIbRTJxldn+EFvMr+eleQGPicPK8lVx93e+d5TzcqQsRNiekpsUOqHnJJAKClaO
+xdgmlOHZSOEtPtoKct2jmRXagaKH9HtuJneJWK3W6wyyQXpzbm3benhB6QiIEn6H
+LmYRY2xU+zydcsC8Lv/Ct90NduM61/e0aL6i9eOBbsFGb12N4E3GVFWJGjMxCrFX
+uaOKmMPsOzTFlUFpfnXCPCDFYbpRR6AgkJOhkEvzTnyFRVSa0QUmQbC1TR0zvsQD
+yCV8wXDbO/QJLVQnSKwv4cSsPsjLkkxTOTcj7NMB+eAJRE1NZMDhDVqHIrytG6P+
+JrUV86f8hBnp7KGItERphIPzidF0BqnMC9bC3ieFUCbKF7jJeodWLBoBHmy+E60Q
+rLUk9TiRodZL2vG70t5HtfG8gfZZa88ZU+mNFctKy6lvROUbQc/hhqfK0GqfvEyN
+BjNaooXlkDWgYlwWTvDjovoDGrQscbNYLN57C9saD+veIR8GdwYDsMnvmfzAuU8L
+hij+0rnq49qlw0dpEuDb8PYZi+17cNcC1u2HGCgsBCRMd+RIihrGO5rUD8r6ddIB
+QFqNeb+Lz0vPqhbBleStTIo+F5HUsWLlguWABKQDfo2/2n+iD5dPDNMN+9fR5XJ+
+HMh3/1uaD7euBUbl8agW7EekFwIDAQABo4H2MIHzMIGwBgNVHREEgagwgaWBD2lu
+Zm9AaXplbnBlLmNvbaSBkTCBjjFHMEUGA1UECgw+SVpFTlBFIFMuQS4gLSBDSUYg
+QTAxMzM3MjYwLVJNZXJjLlZpdG9yaWEtR2FzdGVpeiBUMTA1NSBGNjIgUzgxQzBB
+BgNVBAkMOkF2ZGEgZGVsIE1lZGl0ZXJyYW5lbyBFdG9yYmlkZWEgMTQgLSAwMTAx
+MCBWaXRvcmlhLUdhc3RlaXowDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMC
+AQYwHQYDVR0OBBYEFB0cZQ6o8iV7tJHP5LGx5r1VdGwFMA0GCSqGSIb3DQEBCwUA
+A4ICAQB4pgwWSp9MiDrAyw6lFn2fuUhfGI8NYjb2zRlrrKvV9pF9rnHzP7MOeIWb
+laQnIUdCSnxIOvVFfLMMjlF4rJUT3sb9fbgakEyrkgPH7UIBzg/YsfqikuFgba56
+awmqxinuaElnMIAkejEWOVt+8Rwu3WwJrfIxwYJOubv5vr8qhT/AQKM6WfxZSzwo
+JNu0FXWuDYi6LnPAvViH5ULy617uHjAimcs30cQhbIHsvm0m5hzkQiCeR7Csg1lw
+LDXWrzY0tM07+DKo7+N4ifuNRSzanLh+QBxh5z6ikixL8s36mLYp//Pye6kfLqCT
+VyvehQP5aTfLnnhqBbTFMXiJ7HqnheG5ezzevh55hM6fcA5ZwjUukCox2eRFekGk
+LhObNA5me0mrZJfQRsN5nXJQY6aYWwa9SG3YOYNw6DXwBdGqvOPbyALqfP2C2sJb
+UjWumDqtujWTI6cfSN01RpiyEGjkpTHCClguGYEQyVB1/OpaFs4R1+7vUIgtYf8/
+QnMFlEPVjjxOAToZpR9GTnfQXeWBIiGH/pR9hNiTrdZoQ0iy2+tzJOeRf1SktoA+
+naM8THLCV8Sg1Mw4J87VBp6iSNnpn86CcDaTmjvfliHjWbcM2pE38P1ZWrOZyGls
+QyYBNWNgVYkDOnXYukrZVP/u3oDYLdE41V4tC5h9Pmzb/CaIxw==
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIDczCCAlugAwIBAgIQMDAwMDk3Mzc1NzM4NjAwMDANBgkqhkiG9w0BAQUFADBV
+MQswCQYDVQQGEwJGUjETMBEGA1UEChMKQ2VydGlOb21pczEcMBoGA1UECxMTQUMg
+UmFjaW5lIC0gUm9vdCBDQTETMBEGA1UEAxMKQ2VydGlOb21pczAeFw0wMDExMDkw
+MDAwMDBaFw0xMjExMDkwMDAwMDBaMFUxCzAJBgNVBAYTAkZSMRMwEQYDVQQKEwpD
+ZXJ0aU5vbWlzMRwwGgYDVQQLExNBQyBSYWNpbmUgLSBSb290IENBMRMwEQYDVQQD
+EwpDZXJ0aU5vbWlzMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA8SWb
+4mS5RXB3ENSIcfrEzCj/TRUQuT1tMCU0YUfXFSgcPdWglIzCv3kvh07QoB+8xMl+
+fQHvSSduAxnNewz0GBY9rApCPKlP6CcnJr74OSVZIiWt9wLfl4wwhNhZOiikIpZp
+EdOXWqRc84P5cUlN3Lwmr1sjCWmHfTSS4cAKxfDbFLfE61etosyoFZUTQbIhb1Bf
+JL5xRXAUZudQiU42n/yAoSUrN4FLUfPQNlOe1AB81pIgX8g2ojwxDjfgqSs1JmBF
+uLKJ45uVLEenQBPmQCGjL3maV86IRmR3a9UGlgvKAk0NBdh8mrQyQvcUlLBIQBCm
+l7wppt6maQHUNEPQSwIDAQABoz8wPTALBgNVHQ8EBAMCAYYwDwYDVR0TAQH/BAUw
+AwEB/zAdBgNVHQ4EFgQU+F4ho6ijFeb4tRG7/kIEXU2OgnowDQYJKoZIhvcNAQEF
+BQADggEBACe9FJayK6bXkJQrilBFMh75QPdFOks9PJuo86OMUlBDZGYFTCh9Arex
+N3KYCnAEzazYIALwr7eASJJDIQMu1Q+pkx/7ACde4kP47F27M2rm+v5HnGooCLz2
+s7Fe/WUycTQqgwF5lNp03m1ce/TvovgkEZeVN5wM/7+SsZLJGDigXGeq48j2g2hn
+8OckX9Ciyo0U3/1IVeigNBisiaOlsHSZOEPBZQRiZULob+NVbXVPo8nM1OyP3aHI
+LQex1yYcCr9m93nOiZyKkur3Uedf1yMTBe+fflnPFKGYnVqvTGXCKVdHzQBfpILA
+AuaC+5ykZhSiSMf8nmL2oPMcLO7YQw4=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIDwzCCAqugAwIBAgIBATANBgkqhkiG9w0BAQsFADCBgjELMAkGA1UEBhMCREUx
+KzApBgNVBAoMIlQtU3lzdGVtcyBFbnRlcnByaXNlIFNlcnZpY2VzIEdtYkgxHzAd
+BgNVBAsMFlQtU3lzdGVtcyBUcnVzdCBDZW50ZXIxJTAjBgNVBAMMHFQtVGVsZVNl
+YyBHbG9iYWxSb290IENsYXNzIDMwHhcNMDgxMDAxMTAyOTU2WhcNMzMxMDAxMjM1
+OTU5WjCBgjELMAkGA1UEBhMCREUxKzApBgNVBAoMIlQtU3lzdGVtcyBFbnRlcnBy
+aXNlIFNlcnZpY2VzIEdtYkgxHzAdBgNVBAsMFlQtU3lzdGVtcyBUcnVzdCBDZW50
+ZXIxJTAjBgNVBAMMHFQtVGVsZVNlYyBHbG9iYWxSb290IENsYXNzIDMwggEiMA0G
+CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC9dZPwYiJvJK7genasfb3ZJNW4t/zN
+8ELg63iIVl6bmlQdTQyK9tPPcPRStdiTBONGhnFBSivwKixVA9ZIw+A5OO3yXDw/
+RLyTPWGrTs0NvvAgJ1gORH8EGoel15YUNpDQSXuhdfsaa3Ox+M6pCSzyU9XDFES4
+hqX2iys52qMzVNn6chr3IhUciJFrf2blw2qAsCTz34ZFiP0Zf3WHHx+xGwpzJFu5
+ZeAsVMhg02YXP+HMVDNzkQI6pn97djmiH5a2OK61yJN0HZ65tOVgnS9W0eDrXltM
+EnAMbEQgqxHY9Bn20pxSN+f6tsIxO0rUFJmtxxr1XV/6B7h8DR/Wgx6zAgMBAAGj
+QjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBS1
+A/d2O2GCahKqGFPrAyGUv/7OyjANBgkqhkiG9w0BAQsFAAOCAQEAVj3vlNW92nOy
+WL6ukK2YJ5f+AbGwUgC4TeQbIXQbfsDuXmkqJa9c1h3a0nnJ85cp4IaH3gRZD/FZ
+1GSFS5mvJQQeyUapl96Cshtwn5z2r3Ex3XsFpSzTucpH9sry9uetuUg/vBa3wW30
+6gmv7PO15wWeph6KU1HWk4HMdJP2udqmJQV0eVp+QD6CSyYRMG7hP0HHRwA11fXT
+91Q+gT3aSWqas+8QPebrb9HIIkfLzM8BMZLZGOMivgkeGj5asuRrDFR6fUNOuIml
+e9eiPZaGzPImNC1qkp2aGtAw4l1OBLBfiyB+d8E9lYLRRpo7PHi4b6HQDWSieB4p
+TpPDpFQUWw==
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIDujCCAqKgAwIBAgILBAAAAAABD4Ym5g0wDQYJKoZIhvcNAQEFBQAwTDEgMB4G
+A1UECxMXR2xvYmFsU2lnbiBSb290IENBIC0gUjIxEzARBgNVBAoTCkdsb2JhbFNp
+Z24xEzARBgNVBAMTCkdsb2JhbFNpZ24wHhcNMDYxMjE1MDgwMDAwWhcNMjExMjE1
+MDgwMDAwWjBMMSAwHgYDVQQLExdHbG9iYWxTaWduIFJvb3QgQ0EgLSBSMjETMBEG
+A1UEChMKR2xvYmFsU2lnbjETMBEGA1UEAxMKR2xvYmFsU2lnbjCCASIwDQYJKoZI
+hvcNAQEBBQADggEPADCCAQoCggEBAKbPJA6+Lm8omUVCxKs+IVSbC9N/hHD6ErPL
+v4dfxn+G07IwXNb9rfF73OX4YJYJkhD10FPe+3t+c4isUoh7SqbKSaZeqKeMWhG8
+eoLrvozps6yWJQeXSpkqBy+0Hne/ig+1AnwblrjFuTosvNYSuetZfeLQBoZfXklq
+tTleiDTsvHgMCJiEbKjNS7SgfQx5TfC4LcshytVsW33hoCmEofnTlEnLJGKRILzd
+C9XZzPnqJworc5HGnRusyMvo4KD0L5CLTfuwNhv2GXqF4G3yYROIXJ/gkwpRl4pa
+zq+r1feqCapgvdzZX99yqWATXgAByUr6P6TqBwMhAo6CygPCm48CAwEAAaOBnDCB
+mTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUm+IH
+V2ccHsBqBt5ZtJot39wZhi4wNgYDVR0fBC8wLTAroCmgJ4YlaHR0cDovL2NybC5n
+bG9iYWxzaWduLm5ldC9yb290LXIyLmNybDAfBgNVHSMEGDAWgBSb4gdXZxwewGoG
+3lm0mi3f3BmGLjANBgkqhkiG9w0BAQUFAAOCAQEAmYFThxxol4aR7OBKuEQLq4Gs
+J0/WwbgcQ3izDJr86iw8bmEbTUsp9Z8FHSbBuOmDAGJFtqkIk7mpM0sYmsL4h4hO
+291xNBrBVNpGP+DTKqttVCL1OmLNIG+6KYnX3ZHu01yiPqFbQfXf5WRDLenVOavS
+ot+3i9DAgBkcRcAtjOj4LaR0VknFBbVPFd5uRHg5h6h+u/N5GJG79G+dwfCMNYxd
+AfvDbbnvRG15RjF+Cv6pgsH/76tuIMRQyV+dTZsXjAzlAcmgQWpzU/qlULRuJQ/7
+TBj0/VLZjmmx6BEP3ojY+x1J96relc8geMJgEtslQIxq/H5COEBkEveegeGTLg==
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIDoTCCAomgAwIBAgIQKTZHquOKrIZKI1byyrdhrzANBgkqhkiG9w0BAQUFADBO
+MQswCQYDVQQGEwJ1czEYMBYGA1UEChMPVS5TLiBHb3Zlcm5tZW50MQ0wCwYDVQQL
+EwRGQkNBMRYwFAYDVQQDEw1Db21tb24gUG9saWN5MB4XDTA3MTAxNTE1NTgwMFoX
+DTI3MTAxNTE2MDgwMFowTjELMAkGA1UEBhMCdXMxGDAWBgNVBAoTD1UuUy4gR292
+ZXJubWVudDENMAsGA1UECxMERkJDQTEWMBQGA1UEAxMNQ29tbW9uIFBvbGljeTCC
+ASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAJeNvTMn5K1b+3i9L0dHbsd4
+6ZOcpN7JHP0vGzk4rEcXwH53KQA7Ax9oD81Npe53uCxiazH2+nIJfTApBnznfKM9
+hBiKHa4skqgf6F5PjY7rPxr4nApnnbBnTfAu0DDew5SwoM8uCjR/VAnTNr2kSVdS
+c+md/uRIeUYbW40y5KVIZPMiDZKdCBW/YDyD90ciJSKtKXG3d+8XyaK2lF7IMJCk
+FEhcVlcLQUwF1CpMP64Sm1kRdXAHImktLNMxzJJ+zM2kfpRHqpwJCPZLr1LoakCR
+xVW9QLHIbVeGlRfmH3O+Ry4+i0wXubklHKVSFzYIWcBCvgortFZRPBtVyYyQd+sC
+AwEAAaN7MHkwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0O
+BBYEFC9Yl9ipBZilVh/72at17wI8NjTHMBIGCSsGAQQBgjcVAQQFAgMBAAEwIwYJ
+KwYBBAGCNxUCBBYEFHa3YJbdFFYprHWF03BjwbxHhhyLMA0GCSqGSIb3DQEBBQUA
+A4IBAQBgrvNIFkBypgiIybxHLCRLXaCRc+1leJDwZ5B6pb8KrbYq+Zln34PFdx80
+CTj5fp5B4Ehg/uKqXYeI6oj9XEWyyWrafaStsU+/HA2fHprA1RRzOCuKeEBuMPdi
+4c2Z/FFpZ2wR3bgQo2jeJqVW/TZsN5hs++58PGxrcD/3SDcJjwtCga1GRrgLgwb0
+Gzigf0/NC++DiYeXHIowZ9z9VKEDfgHLhUyxCynDvux84T8PCVI8L6eaSP436REG
+WOE2QYrEtr+O3c5Ks7wawM36GpnScZv6z7zyxFSjiDV2zBssRm8MtNHDYXaSdBHq
+S4CNHIkRi+xb/xfJSPzn4AYR4oRe
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIFYzCCA0ugAwIBAgIBOzANBgkqhkiG9w0BAQsFADBTMQswCQYDVQQGEwJJTDEW
+MBQGA1UEChMNU3RhcnRDb20gTHRkLjEsMCoGA1UEAxMjU3RhcnRDb20gQ2VydGlm
+aWNhdGlvbiBBdXRob3JpdHkgRzIwHhcNMTAwMTAxMDEwMDAxWhcNMzkxMjMxMjM1
+OTAxWjBTMQswCQYDVQQGEwJJTDEWMBQGA1UEChMNU3RhcnRDb20gTHRkLjEsMCoG
+A1UEAxMjU3RhcnRDb20gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgRzIwggIiMA0G
+CSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQC2iTZbB7cgNr2Cu+EWIAOVeq8Oo1XJ
+JZlKxdBWQYeQTSFgpBSHO839sj60ZwNq7eEPS8CRhXBF4EKe3ikj1AENoBB5uNsD
+vfOpL9HG4A/LnooUCri99lZi8cVytjIl2bLzvWXFDSxu1ZJvGIsAQRSCb0AgJnoo
+D/Uefyf3lLE3PbfHkffiAez9lInhzG7TNtYKGXmu1zSCZf98Qru23QumNK9LYP5/
+Q0kGi4xDuFby2X8hQxfqp0iVAXV16iulQ5XqFYSdCI0mblWbq9zSOdIxHWDirMxW
+RST1HFSr7obdljKF+ExP6JV2tgXdNiNnvP8V4so75qbsO+wmETRIjfaAKxojAuuK
+HDp2KntWFhxyKrOq42ClAJ8Em+JvHhRYW6Vsi1g8w7pOOlz34ZYrPu8HvKTlXcxN
+nw3h3Kq74W4a7I/htkxNeXJdFzULHdfBR9qWJODQcqhaX2YtENwvKhOuJv4KHBnM
+0D4LnMgJLvlblnpHnOl68wVQdJVznjAJ85eCXuaPOQgeWeU1FEIT/wCc976qUM/i
+UUjXuG+v+E5+M5iSFGI6dWPPe/regjupuznixL0sAA7IF6wT700ljtizkC+p2il9
+Ha90OrInwMEePnWjFqmveiJdnxMaz6eg6+OGCtP95paV1yPIN93EfKo2rJgaErHg
+TuixO/XWb/Ew1wIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQE
+AwIBBjAdBgNVHQ4EFgQUS8W0QGutHLOlHGVuRjaJhwUMDrYwDQYJKoZIhvcNAQEL
+BQADggIBAHNXPyzVlTJ+N9uWkusZXn5T50HsEbZH77Xe7XRcxfGOSeD8bpkTzZ+K
+2s06Ctg6Wgk/XzTQLwPSZh0avZyQN8gMjgdalEVGKua+etqhqaRpEpKwfTbURIfX
+UfEpY9Z1zRbkJ4kd+MIySP3bmdCPX1R0zKxnNBFi2QwKN4fRoxdIjtIXHfbX/dtl
+6/2o1PXWT6RbdejF0mCy2wl+JYt7ulKSnj7oxXehPOBKc2thz4bcQ///If4jXSRK
+9dNtD2IEBVeC2m6kMyV5Sy5UGYvMLD0w6dEG/+gyRr61M3Z3qAFdlsHB1b6uJcDJ
+HgoJIIihDsnzb02CVAAgp9KP5DlUFy6NHrgbuxu9mk47EDTcnIhT76IxW1hPkWLI
+wpqazRVdOKnWvvgTtZ8SafJQYqz7Fzf07rh1Z2AQ+4NQ+US1dZxAF7L+/XldblhY
+XzD8AK6vM8EOTmy6p6ahfzLbOOCxchcKK5HsamMm7YnUeMx0HgX4a/6ManY5Ka5l
+IxKVCCIcl85bBu4M4ru8H0ST9tg4RQUh7eStqxK2A6RCLi3ECToDZ2mEmuFZkIoo
+hdVddLHRDiBYmxOlsGOm7XtH/UVVMKTumtTm4ofvmMkyghEpIrwACjFeLQ/Ajulr
+so8uBtjRkcfGEvRM/TAXw8HaOFvjqermobp573PYtlNXLfbQ4ddI
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIDIDCCAgigAwIBAgIBHTANBgkqhkiG9w0BAQUFADA5MQswCQYDVQQGEwJGSTEP
+MA0GA1UEChMGU29uZXJhMRkwFwYDVQQDExBTb25lcmEgQ2xhc3MyIENBMB4XDTAx
+MDQwNjA3Mjk0MFoXDTIxMDQwNjA3Mjk0MFowOTELMAkGA1UEBhMCRkkxDzANBgNV
+BAoTBlNvbmVyYTEZMBcGA1UEAxMQU29uZXJhIENsYXNzMiBDQTCCASIwDQYJKoZI
+hvcNAQEBBQADggEPADCCAQoCggEBAJAXSjWdyvANlsdE+hY3/Ei9vX+ALTU74W+o
+Z6m/AxxNjG8yR9VBaKQTBME1DJqEQ/xcHf+Js+gXGM2RX/uJ4+q/Tl18GybTdXnt
+5oTjV+WtKcT0OijnpXuENmmz/V52vaMtmdOQTiMofRhj8VQ7Jp12W5dCsv+u8E7s
+3TmVToMGf+dJQMjFAbJUWmYdPfz56TwKnoG4cPABi+QjVHzIrviQHgCWctRUz2Ej
+vOr7nQKV0ba5cTppCD8PtOFCx4j1P5iop7oc4HFx71hXgVB6XGt0Rg6DA5jDjqhu
+8nYybieDwnPz3BjotJPqdURrBGAgcVeHnfO+oJAjPYok4doh28MCAwEAAaMzMDEw
+DwYDVR0TAQH/BAUwAwEB/zARBgNVHQ4ECgQISqCqWITTXjwwCwYDVR0PBAQDAgEG
+MA0GCSqGSIb3DQEBBQUAA4IBAQBazof5FnIVV0sd2ZvnoiYw7JNn39Yt0jSv9zil
+zqsWuasvfDXLrNAPtEwr/IDva4yRXzZ299uzGxnq9LIR/WFxRL8oszodv7ND6J+/
+3DEIcbCdjdY0RzKQxmUk96BKfARzjzlvF4xytb1LyHr4e4PDKE6cCepnP7JnBBvD
+FNr450kkkdAdavphOe9r5yF1BgfYErQhIHBCcYHaPJo2vqZbDWpsmh+Re/n570K6
+Tk6ezAyNlNzZRZxe7EJQY670XcSxEtzKO6gunRRaBXW37Ndj4ro1tgQIkejanZz2
+ZrUYrAqmVCY0M9IbwdR/GjqOC6oybtv8TyWf2TLHllpwrN9M
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIDoDCCAoigAwIBAgIBMTANBgkqhkiG9w0BAQUFADA5MQswCQYDVQQGEwJKUDEO
+MAwGA1UEChMFTEdQS0kxGjAYBgNVBAsTEUFwcGxpY2F0aW9uIENBIEcyMB4XDTA2
+MDMzMTE1MDAwMFoXDTE2MDMzMTE0NTk1OVowOTELMAkGA1UEBhMCSlAxDjAMBgNV
+BAoTBUxHUEtJMRowGAYDVQQLExFBcHBsaWNhdGlvbiBDQSBHMjCCASIwDQYJKoZI
+hvcNAQEBBQADggEPADCCAQoCggEBALk1xhD422jbB8RATLAdHjbcw0H2z1UVbQh/
+XMZoVeXnV/GWUebhTXgPbkAVcDtl/hHf59PWWDU74Z8C/JRSRi6znmCbAp7JgtL2
+464JT4REtmKbAFFouDqt7GTRMkvplESDtA7OIYlrsDbAmMZLnMI+W2AqCTErLatM
+3rGg/VhWwoMdILzEhAmHe6iVl8YljoPgPpMN0cd9c6mo/BkAQC4iuHozQfV4/Vpx
+54LZSIhc7KiFhy1tgIlnGmm+EMBaju2IfT5vLDhrN85H2KIxMN5+U2Vsi4ZTQSBs
+vUilfq8AWlYSWIHR3IlZ+bXu+E2a2EQpi3mn9yKq6nxctBaIIA0CAwEAAaOBsjCB
+rzAdBgNVHQ4EFgQUf7hdjsQYa8Z9zC7prs405xdd4KEwDgYDVR0PAQH/BAQDAgEG
+MEwGA1UdHwRFMEMwQaA/oD2kOzA5MQswCQYDVQQGEwJKUDEOMAwGA1UEChMFTEdQ
+S0kxGjAYBgNVBAsTEUFwcGxpY2F0aW9uIENBIEcyMA8GA1UdEwEB/wQFMAMBAf8w
+HwYDVR0jBBgwFoAUf7hdjsQYa8Z9zC7prs405xdd4KEwDQYJKoZIhvcNAQEFBQAD
+ggEBADzYczZABkhKVBn1J0g5JaVuQue2zRvLOTS3m+xPKr535MqE/B3rmyJA1fT7
+aIdy/Eddag5SSuO1XUjGIpbmM21tq/bN18skWoyoRZ4+YYJ9lNUF8Bo1X3EvLlS1
+QQXvhg1S75yYG/EsTDrR84bTjD56L4ZFjoMyJlu/U8oOUVbcmsJaMBkNp57Vqpsg
+OWl4IfSXbdEOEUwu0xtasPmXeFwqj1Jl7kxCJcI3MA5tKzWUgwbor0U7BGanMLv5
+4CE7Y259RF06alPvERck/VSyWmxzViHJbC2XpEKzJ2EFIWNt6ii8TxpvQtyYq1XT
+HhvAkj+bweY7F1bixJhDJe62ywA=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIICZzCCAdCgAwIBAgIBBDANBgkqhkiG9w0BAQUFADBhMQswCQYDVQQGEwJVUzEY
+MBYGA1UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb0QxDDAKBgNVBAsT
+A1BLSTEcMBoGA1UEAxMTRG9EIENMQVNTIDMgUm9vdCBDQTAeFw0wMDA1MTkxMzEz
+MDBaFw0yMDA1MTQxMzEzMDBaMGExCzAJBgNVBAYTAlVTMRgwFgYDVQQKEw9VLlMu
+IEdvdmVybm1lbnQxDDAKBgNVBAsTA0RvRDEMMAoGA1UECxMDUEtJMRwwGgYDVQQD
+ExNEb0QgQ0xBU1MgMyBSb290IENBMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKB
+gQC1MP5kvurMbe2BLPd/6Rm6DmlqKOGpqcuVWB/x5pppU+CIP5HFUbljl6jmIYwT
+XjY8qFf6+HAsTGrLvzCnTBbkMlz4ErBR+BZXjS+0TfouqJToKmHUVw1Hzm4sL36Y
+Z8wACKu2lhY1woWR5VugCsdmUmLzYXWVF668KlYppeArUwIDAQABoy8wLTAdBgNV
+HQ4EFgQUbJyl8FyPbUGNxBc7kFfCD6PNbf4wDAYDVR0TBAUwAwEB/zANBgkqhkiG
+9w0BAQUFAAOBgQCvcUT5lyPMaGmMQwdBuoggsyIAQciYoFUczT9usZNcrfoYmrsc
+c2/9JEKPh59Rz76Gn+nXikhPCNlplKw/5g8tlw8ok3ZPYt//oM1h+KaGDDE0INx/
+L6j7Ob6V7jhZAmLB3mwVT+DfnbvkeXMk/WNklfdKqJkfSGWVx3u/eDLneg==
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIFUjCCBDqgAwIBAgIBAjANBgkqhkiG9w0BAQUFADBkMQswCQYDVQQGEwJLUjEN
+MAsGA1UEChMES0lTQTEuMCwGA1UECxMlS29yZWEgQ2VydGlmaWNhdGlvbiBBdXRo
+b3JpdHkgQ2VudHJhbDEWMBQGA1UEAxMNS0lTQSBSb290Q0EgMzAeFw0wNDExMTkw
+NjM5NTFaFw0xNDExMTkwNjM5NTFaMGQxCzAJBgNVBAYTAktSMQ0wCwYDVQQKEwRL
+SVNBMS4wLAYDVQQLEyVLb3JlYSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSBDZW50
+cmFsMRYwFAYDVQQDEw1LSVNBIFJvb3RDQSAzMIIBIDANBgkqhkiG9w0BAQEFAAOC
+AQ0AMIIBCAKCAQEA3rrtF2Wu0b1KPazbgHLMWOHn4ZPazDB6z+8Lri2nQ6u/p0LP
+CFYIpEcdffqG79gwlyY0YTyADvjU65/8IjAboW0+40zSVU4WQDfC9gdu2we1pYyW
+geKbXH6UYcjOhDyx+gDmctMJhXfp3F4hT7TkTvTiF6tQrxz/oTlYdVsSspa5jfBw
+YkhbVigqpYeRNrkeJPW5unu2UlFbF1pgBWycwubGjD756t08jP+J3kNwrB248XXN
+OMpTDUdoasY8GMq94bS+DvTQ49IT+rBRERHUQavo9DmO4TSETwuTqmo4/OXGeEeu
+dhf6oYA3BgAVCP1rI476cg2V1ktisWjC3TSbXQIBA6OCAg8wggILMB8GA1UdIwQY
+MBaAFI+B8NqmzXQ8vmb0FWtGpP4GKMyqMB0GA1UdDgQWBBSPgfDaps10PL5m9BVr
+RqT+BijMqjAOBgNVHQ8BAf8EBAMCAQYwggEuBgNVHSAEggElMIIBITCCAR0GBFUd
+IAAwggETMDAGCCsGAQUFBwIBFiRodHRwOi8vd3d3LnJvb3RjYS5vci5rci9yY2Ev
+Y3BzLmh0bWwwgd4GCCsGAQUFBwICMIHRHoHOx3QAIMd4yZ3BHLKUACCs9cd4x3jJ
+ncEcx4WyyLLkACgAVABoAGkAcwAgAGMAZQByAHQAaQBmAGkAYwBhAHQAZQAgAGkA
+cwAgAGEAYwBjAHIAZQBkAGkAdABlAGQAIAB1AG4AZABlAHIAIABFAGwAZQBjAHQA
+cgBvAG4AaQBjACAAUwBpAGcAbgBhAHQAdQByAGUAIABBAGMAdAAgAG8AZgAgAHQA
+aABlACAAUgBlAHAAdQBiAGwAaQBjACAAbwBmACAASwBvAHIAZQBhACkwMwYDVR0R
+BCwwKqQoMCYxJDAiBgNVBAMMG+2VnOq1reygleuztOuztO2YuOynhO2dpeybkDAz
+BgNVHRIELDAqpCgwJjEkMCIGA1UEAwwb7ZWc6rWt7KCV67O067O07Zi47KeE7Z2l
+7JuQMA8GA1UdEwEB/wQFMAMBAf8wDAYDVR0kBAUwA4ABADANBgkqhkiG9w0BAQUF
+AAOCAQEAz9b3Dv2wjG4FFY6oXCuyWtEeV6ZeGKqCEQj8mbdbp+PI0qLT+SQ09+Pk
+rolUR9NpScmAwRHr4inH9gaLX7riXs+rw87P7pIl3J85Hg4D9N6QW6FwmVzHc07J
+pHVJeyWhn4KSjU3sYcUMMqfHODiAVToqgx2cZHm5Dac1Smjvj/8F2LpOVmHY+Epw
+mAiWk9hgxzrsX58dKzVPSBShmrtv7tIDhlPxEMcHVGJeNo7iHCsdF03m9VrvirqC
+6HfZKBF+N4dKlArJQOk1pTr7ZD7yXxZ683bXzu4/RB1Fql8RqlMcOh9SUWJUD6OQ
+Nc9Nb7rHviwJ8TX4Absk3TC8SA/u2Q==
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIDXzCCAkegAwIBAgILBAAAAAABIVhTCKIwDQYJKoZIhvcNAQELBQAwTDEgMB4G
+A1UECxMXR2xvYmFsU2lnbiBSb290IENBIC0gUjMxEzARBgNVBAoTCkdsb2JhbFNp
+Z24xEzARBgNVBAMTCkdsb2JhbFNpZ24wHhcNMDkwMzE4MTAwMDAwWhcNMjkwMzE4
+MTAwMDAwWjBMMSAwHgYDVQQLExdHbG9iYWxTaWduIFJvb3QgQ0EgLSBSMzETMBEG
+A1UEChMKR2xvYmFsU2lnbjETMBEGA1UEAxMKR2xvYmFsU2lnbjCCASIwDQYJKoZI
+hvcNAQEBBQADggEPADCCAQoCggEBAMwldpB5BngiFvXAg7aEyiie/QV2EcWtiHL8
+RgJDx7KKnQRfJMsuS+FggkbhUqsMgUdwbN1k0ev1LKMPgj0MK66X17YUhhB5uzsT
+gHeMCOFJ0mpiLx9e+pZo34knlTifBtc+ycsmWQ1z3rDI6SYOgxXG71uL0gRgykmm
+KPZpO/bLyCiR5Z2KYVc3rHQU3HTgOu5yLy6c+9C7v/U9AOEGM+iCK65TpjoWc4zd
+QQ4gOsC0p6Hpsk+QLjJg6VfLuQSSaGjlOCZgdbKfd/+RFO+uIEn8rUAVSNECMWEZ
+XriX7613t2Saer9fwRPvm2L7DWzgVGkWqQPabumDk3F2xmmFghcCAwEAAaNCMEAw
+DgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFI/wS3+o
+LkUkrk1Q+mOai97i3Ru8MA0GCSqGSIb3DQEBCwUAA4IBAQBLQNvAUKr+yAzv95ZU
+RUm7lgAJQayzE4aGKAczymvmdLm6AC2upArT9fHxD4q/c2dKg8dEe3jgr25sbwMp
+jjM5RcOO5LlXbKr8EpbsU8Yt5CRsuZRj+9xTaGdWPoO4zzUhw8lo/s7awlOqzJCK
+6fBdRoyV3XpYKBovHd7NADdBj+1EbddTKJd+82cEHhXXipa0095MJ6RMG3NzdvQX
+mcIfeg7jLQitChws/zyrVQ4PkX4268NXSb7hLi18YIvDQVETI53O9zJrlAGomecs
+Mx86OyXShkDOOyyGeMlhLxS67ttVb9+E7gUJTb0o2HLO02JQZR7rkpeDMdmztcpH
+WD9f
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIC+TCCAoCgAwIBAgINAKaLeSkAAAAAUNCR+TAKBggqhkjOPQQDAzCBvzELMAkG
+A1UEBhMCVVMxFjAUBgNVBAoTDUVudHJ1c3QsIEluYy4xKDAmBgNVBAsTH1NlZSB3
+d3cuZW50cnVzdC5uZXQvbGVnYWwtdGVybXMxOTA3BgNVBAsTMChjKSAyMDEyIEVu
+dHJ1c3QsIEluYy4gLSBmb3IgYXV0aG9yaXplZCB1c2Ugb25seTEzMDEGA1UEAxMq
+RW50cnVzdCBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IC0gRUMxMB4XDTEy
+MTIxODE1MjUzNloXDTM3MTIxODE1NTUzNlowgb8xCzAJBgNVBAYTAlVTMRYwFAYD
+VQQKEw1FbnRydXN0LCBJbmMuMSgwJgYDVQQLEx9TZWUgd3d3LmVudHJ1c3QubmV0
+L2xlZ2FsLXRlcm1zMTkwNwYDVQQLEzAoYykgMjAxMiBFbnRydXN0LCBJbmMuIC0g
+Zm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxMzAxBgNVBAMTKkVudHJ1c3QgUm9vdCBD
+ZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAtIEVDMTB2MBAGByqGSM49AgEGBSuBBAAi
+A2IABIQTydC6bUF74mzQ61VfZgIaJPRbiWlH47jCffHyAsWfoPZb1YsGGYZPUxBt
+ByQnoaD41UcZYUx9ypMn6nQM72+WCf5j7HBdNq1nd67JnXxVRDqiY1Ef9eNi1KlH
+Bz7MIKNCMEAwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0O
+BBYEFLdj5xrdjekIplWDpOBqUEFlEUJJMAoGCCqGSM49BAMDA2cAMGQCMGF52OVC
+R98crlOZF7ZvHH3hvxGU0QOIdeSNiaSKd0bebWHvAvX7td/M/k7//qnmpwIwW5nX
+hTcGtXsI/esni0qU+eH6p44mCOh8kmhtc9hvJqwhAriZtyZBWyVgrtBIGu4G
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIHTzCCBTegAwIBAgIJAKPaQn6ksa7aMA0GCSqGSIb3DQEBBQUAMIGuMQswCQYD
+VQQGEwJFVTFDMEEGA1UEBxM6TWFkcmlkIChzZWUgY3VycmVudCBhZGRyZXNzIGF0
+IHd3dy5jYW1lcmZpcm1hLmNvbS9hZGRyZXNzKTESMBAGA1UEBRMJQTgyNzQzMjg3
+MRswGQYDVQQKExJBQyBDYW1lcmZpcm1hIFMuQS4xKTAnBgNVBAMTIENoYW1iZXJz
+IG9mIENvbW1lcmNlIFJvb3QgLSAyMDA4MB4XDTA4MDgwMTEyMjk1MFoXDTM4MDcz
+MTEyMjk1MFowga4xCzAJBgNVBAYTAkVVMUMwQQYDVQQHEzpNYWRyaWQgKHNlZSBj
+dXJyZW50IGFkZHJlc3MgYXQgd3d3LmNhbWVyZmlybWEuY29tL2FkZHJlc3MpMRIw
+EAYDVQQFEwlBODI3NDMyODcxGzAZBgNVBAoTEkFDIENhbWVyZmlybWEgUy5BLjEp
+MCcGA1UEAxMgQ2hhbWJlcnMgb2YgQ29tbWVyY2UgUm9vdCAtIDIwMDgwggIiMA0G
+CSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCvAMtwNyuAWko6bHiUfaN/Gh/2NdW9
+28sNRHI+JrKQUrpjOyhYb6WzbZSm891kDFX29ufyIiKAXuFixrYp4YFs8r/lfTJq
+VKAyGVn+H4vXPWCGhSRv4xGzdz4gljUha7MI2XAuZPeEklPWDrCQiorjh40G072Q
+DuKZoRuGDtqaCrsLYVAGUvGef3bsyw/QHg3PmTA9HMRFEFis1tPo1+XqxQEHd9ZR
+5gN/ikilTWh1uem8nk4ZcfUyS5xtYBkL+8ydddy/Js2Pk3g5eXNeJQ7KXOt3EgfL
+ZEFHcpOrUMPrCXZkNNI5t3YRCQ12RcSprj1qr7V9ZS+UWBDsXHyvfuK2GNnQm05a
+Sd+pZgvMPMZ4fKecHePOjlO+Bd5gD2vlGts/4+EhySnB8esHnFIbAURRPHsl18Tl
+UlRdJQfKFiC4reRB7noI/plvg6aRArBsNlVq5331lubKgdaX8ZSD6e2wsWsSaR6s
++12pxZjptFtYer49okQ6Y1nUCyXeG0+95QGezdIp1Z8XGQpvvwyQ0wlf2eOKNcx5
+Wk0ZN5K3xMGtr/R5JJqyAQuxr1yW84Ay+1w9mPGgP0revq+ULtlVmhduYJ1jbLhj
+ya6BXBg14JC7vjxPNyK5fuvPnnchpj04gftI2jE9K+OJ9dC1vX7gUMQSibMjmhAx
+hduub+84Mxh2EQIDAQABo4IBbDCCAWgwEgYDVR0TAQH/BAgwBgEB/wIBDDAdBgNV
+HQ4EFgQU+SSsD7K1+HnA+mCIG8TZTQKeFxkwgeMGA1UdIwSB2zCB2IAU+SSsD7K1
++HnA+mCIG8TZTQKeFxmhgbSkgbEwga4xCzAJBgNVBAYTAkVVMUMwQQYDVQQHEzpN
+YWRyaWQgKHNlZSBjdXJyZW50IGFkZHJlc3MgYXQgd3d3LmNhbWVyZmlybWEuY29t
+L2FkZHJlc3MpMRIwEAYDVQQFEwlBODI3NDMyODcxGzAZBgNVBAoTEkFDIENhbWVy
+ZmlybWEgUy5BLjEpMCcGA1UEAxMgQ2hhbWJlcnMgb2YgQ29tbWVyY2UgUm9vdCAt
+IDIwMDiCCQCj2kJ+pLGu2jAOBgNVHQ8BAf8EBAMCAQYwPQYDVR0gBDYwNDAyBgRV
+HSAAMCowKAYIKwYBBQUHAgEWHGh0dHA6Ly9wb2xpY3kuY2FtZXJmaXJtYS5jb20w
+DQYJKoZIhvcNAQEFBQADggIBAJASryI1wqM58C7e6bXpeHxIvj99RZJe6dqxGfwW
+PJ+0W2aeaufDuV2I6A+tzyMP3iU6XsxPpcG1Lawk0lgH3qLPaYRgM+gQDROpI9CF
+5Y57pp49chNyM/WqfcZjHwj0/gF/JM8rLFQJ3uIrbZLGOU8W6jx+ekbURWpGqOt1
+glanq6B8aBMz9p0w8G8nOSQjKpD9kCk18pPfNKXG9/jvjA9iSnyu0/VU+I22mlaH
+FoI6M6taIgj3grrqLuBHmrS1RaMFO9ncLkVAO+rcf+g769HsJtg1pDDFOqxXnrN2
+pSB7+R5KBWIBpih1YJeSDW4+TTdDDZIVnBgizVGZoCkaPF+KMjNbMMeJL0eYD6MD
+xvbxrN8y8NmBGuScvfaAFPDRLLmF9dijscilIeUcE5fuDr3fKanvNFNb0+RqE4QG
+tjICxFKuItLcsiFCGtpA8CnJ7AoMXOLQusxI0zcKzBIKinmwPQN/aUv0NCB9szTq
+jktk9T79syNnFQ0EuPAtwQlRPLJsFfClI9eDdOTlLsn+mCdCxqvGnrDQWzilm1De
+fhiYtUU79nm06PcaewaD+9CL2rvHvRirCG88gGtAPxkZumWK5r7VXNM21+9AUiRg
+OGcEMeyP84LG3rlV8zsxkVrctQgVrXYlCg17LofiDKYGvCYQbTed7N14jHyAxfDZ
+d0jQ
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIFujCCA6KgAwIBAgIJALtAHEP1Xk+wMA0GCSqGSIb3DQEBBQUAMEUxCzAJBgNV
+BAYTAkNIMRUwEwYDVQQKEwxTd2lzc1NpZ24gQUcxHzAdBgNVBAMTFlN3aXNzU2ln
+biBHb2xkIENBIC0gRzIwHhcNMDYxMDI1MDgzMDM1WhcNMzYxMDI1MDgzMDM1WjBF
+MQswCQYDVQQGEwJDSDEVMBMGA1UEChMMU3dpc3NTaWduIEFHMR8wHQYDVQQDExZT
+d2lzc1NpZ24gR29sZCBDQSAtIEcyMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIIC
+CgKCAgEAr+TufoskDhJuqVAtFkQ7kpJcyrhdhJJCEyq8ZVeCQD5XJM1QiyUqt2/8
+76LQwB8CJEoTlo8jE+YoWACjR8cGp4QjK7u9lit/VcyLwVcfDmJlD909Vopz2q5+
+bbqBHH5CjCA12UNNhPqE21Is8w4ndwtrvxEvcnifLtg+5hg3Wipy+dpikJKVyh+c
+6bM8K8vzARO/Ws/BtQpgvd21mWRTuKCWs2/iJneRjOBiEAKfNA+k1ZIzUd6+jbqE
+emA8atufK+ze3gE/bk3lUIbLtK/tREDFylqM2tIrfKjuvqblCqoOpd8FUrdVxyJd
+MmqXl2MT28nbeTZ7hTpKxVKJ+STnnXepgv9VHKVxaSvRAiTysybUa9oEVeXBCsdt
+MDeQKuSeFDNeFhdVxVu1yzSJkvGdJo+hB9TGsnhQ2wwMC3wLjEHXuendjIj3o02y
+MszYF9rNt85mndT9Xv+9lz4pded+p2JYryU0pUHHPbwNUMoDAw8IWh+Vc3hiv69y
+FGkOpeUDDniOJihC8AcLYiAQZzlG+qkDzAQ4embvIIO1jEpWjpEA/I5cgt6IoMPi
+aG59je883WX0XaxR7ySArqpWl2/5rX3aYT+YdzylkbYcjCbaZaIJbcHiVOO5ykxM
+gI93e2CaHt+28kgeDrpOVG2Y4OGiGqJ3UM/EY5LsRxmd6+ZrzsECAwEAAaOBrDCB
+qTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUWyV7
+lqRlUX64OfPAeGZe6Drn8O4wHwYDVR0jBBgwFoAUWyV7lqRlUX64OfPAeGZe6Drn
+8O4wRgYDVR0gBD8wPTA7BglghXQBWQECAQEwLjAsBggrBgEFBQcCARYgaHR0cDov
+L3JlcG9zaXRvcnkuc3dpc3NzaWduLmNvbS8wDQYJKoZIhvcNAQEFBQADggIBACe6
+45R88a7A3hfm5djV9VSwg/S7zV4Fe0+fdWavPOhWfvxyeDgD2StiGwC5+OlgzczO
+UYrHUDFu4Up+GC9pWbY9ZIEr44OE5iKHjn3g7gKZYbge9LgriBIWhMIxkziWMaa5
+O1M/wySTVltpkuzFwbs4AOPsF6m43Md8AYOfMke6UiI0HTJ6CVanfCU2qT1L2sCC
+bwq7EsiHSycR+R4tx5M/nttfJmtS2S6K8RTGRI0Vqbe/vd6mGu6uLftIdxf+u+yv
+GPUqUfA5hJeVbG4bwyvEdGB5JbAKJ9/fXtI5z0V9QkvfsywexcZdylU6oJxpmo/a
+77KwPJ+HbBIrZXAVUjEaJM9vMSNQH4xPjyPDdEFjHFWoFN0+4FFQz/EbMFYOkrCC
+hdiDyyJkvC24JdVUorgG6q2SpCSgwYa1ShNqR88uC1aVVMvOmttqtKay20EIhid3
+92qgQmwLOM7XdVAyksLfKzAiSNDVQTglXaTpXZ/GlHXQRf0wl0OPkKsKx4ZzYEpp
+Ld6leNcG2mqeSz53OiATIgHQv2ieY2BrNU0LbbqhPcCT4H8js1WtciVORvnSFu+w
+ZMEBnunKoGqYDs/YYPIvSbjkQuE4NRb0yG5P94FW6LqjviOvrv1vA+ACOzB2+htt
+Qc8Bsem4yWb02ybzOqR08kkkW8mw0FfB+j564ZfJ
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIDqDCCApCgAwIBAgIJAP7c4wEPyUj/MA0GCSqGSIb3DQEBBQUAMDQxCzAJBgNV
+BAYTAkZSMRIwEAYDVQQKDAlEaGlteW90aXMxETAPBgNVBAMMCENlcnRpZ25hMB4X
+DTA3MDYyOTE1MTMwNVoXDTI3MDYyOTE1MTMwNVowNDELMAkGA1UEBhMCRlIxEjAQ
+BgNVBAoMCURoaW15b3RpczERMA8GA1UEAwwIQ2VydGlnbmEwggEiMA0GCSqGSIb3
+DQEBAQUAA4IBDwAwggEKAoIBAQDIaPHJ1tazNHUmgh7stL7qXOEm7RFHYeGifBZ4
+QCHkYJ5ayGPhxLGWkv8YbWkj4Sti993iNi+RB7lIzw7sebYs5zRLcAglozyHGxny
+gQcPOJAZ0xH+hrTy0V4eHpbNgGzOOzGTtvKg0KmVEn2lmsxryIRWijOp5yIVUxbw
+zBfsV1/pogqYCd7jX5xv3EjjhQsVWqa6n6xI4wmy9/Qy3l40vhx4XUJbzg4ij02Q
+130yGLMLLGq/jj8UEYkgDncUtT2UCIf3JR7VsmAA7G8qKCVuKj4YYxclPz5EIBb2
+JsglrgVKtOdjLPOMFlN+XPsRGgjBRmKfIrjxwo1p3Po6WAbfAgMBAAGjgbwwgbkw
+DwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUGu3+QTmQtCRZvgHyUtVF9lo53BEw
+ZAYDVR0jBF0wW4AUGu3+QTmQtCRZvgHyUtVF9lo53BGhOKQ2MDQxCzAJBgNVBAYT
+AkZSMRIwEAYDVQQKDAlEaGlteW90aXMxETAPBgNVBAMMCENlcnRpZ25hggkA/tzj
+AQ/JSP8wDgYDVR0PAQH/BAQDAgEGMBEGCWCGSAGG+EIBAQQEAwIABzANBgkqhkiG
+9w0BAQUFAAOCAQEAhQMeknH2Qq/ho2Ge6/PAD/Kl1NqV5ta+aDY9fm4fTIrv0Q8h
+bV6lUmPOEvjvKtpv6zf+EwLHyzs+ImvaYS5/1HI93TDhHkxAGYwP15zRgzB7mFnc
+fca5DClMoTOi62c6ZYTTluLtdkVwj7Ur3vkj1kluPBS1xp81HlDQwY9qcEQCYsuu
+HWhBp6pX6FOqB9IG9tUUBguRA3UsbHK1YZWaDYu5Def131TN3ubY1gkIl2PlwS6w
+t0QmwCbAr1UwnjvVNioZBPRcHv/PLLf/0P2HQBHVESO7SMAhqaQoLf0V+LBOK/Qw
+WyH8EZE0vkHve52Xdf+XlcCWWC/qu0bXu+TZLg==
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIDUzCCAjugAwIBAgIBAjANBgkqhkiG9w0BAQUFADBLMQswCQYDVQQGEwJOTzEd
+MBsGA1UECgwUQnV5cGFzcyBBUy05ODMxNjMzMjcxHTAbBgNVBAMMFEJ1eXBhc3Mg
+Q2xhc3MgMyBDQSAxMB4XDTA1MDUwOTE0MTMwM1oXDTE1MDUwOTE0MTMwM1owSzEL
+MAkGA1UEBhMCTk8xHTAbBgNVBAoMFEJ1eXBhc3MgQVMtOTgzMTYzMzI3MR0wGwYD
+VQQDDBRCdXlwYXNzIENsYXNzIDMgQ0EgMTCCASIwDQYJKoZIhvcNAQEBBQADggEP
+ADCCAQoCggEBAKSO13TZKWTeXx+HgJHqTjnmGcZEC4DVC69TB4sSveZn8AKxifZg
+isRbsELRwCGoy+Gb72RRtqfPFfV0gGgEkKBYouZ0plNTVUhjP5JW3SROjvi6K//z
+NIqeKNc0n6wv1g/xpC+9UrJJhW05NfBEMJNGJPO251P7vGGvqaMU+8IXF4Rs4HyI
++MkcVyzwPX6UvCWThOiaAJpFBUJXgPROztmuOfbIUxAMZTpHe2DC1vqRycZxbL2R
+hzyRhkmr8w+gbCZ2Xhysm3HljbybIR6c1jh+JIAVMYKWsUnTYjdbiAwKYjT+p0h+
+mbEwi5A3lRyoH6UsjfRVyNvdWQrCrXig9IsCAwEAAaNCMEAwDwYDVR0TAQH/BAUw
+AwEB/zAdBgNVHQ4EFgQUOBTmyPCppAP0Tj4io1vy1uCtQHQwDgYDVR0PAQH/BAQD
+AgEGMA0GCSqGSIb3DQEBBQUAA4IBAQABZ6OMySU9E2NdFm/soT4JXJEVKirZgCFP
+Bdy7pYmrEzMqnji3jG8CcmPHc3ceCQa6Oyh7pEfJYWsICCD8igWKH7y6xsL+z27s
+EzNxZy5p+qksP2bAEllNC1QCkoS72xLvg3BweMhT+t/Gxv/ciC8HwEmdMldg0/L2
+mSlf56oBzKwzqBwKu5HEA6BvtjT5htOzdlSY9EqBs1OdTUDs5XcTRa9bqh/YL0yC
+e/4qxFi7T/ye/QNlGioOw6UgFpRreaaiErS7GqQjel/wroQk5PMr+4okoyeYZdow
+dXb8GZHo2+ubPzK/QJcHJrrM85SFSnonk8+QQtS4Wxam58tAA915
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIDqzCCApOgAwIBAgIRAMcoRwmzuGxFjB36JPU2TukwDQYJKoZIhvcNAQEFBQAw
+PDEbMBkGA1UEAxMSQ29tU2lnbiBTZWN1cmVkIENBMRAwDgYDVQQKEwdDb21TaWdu
+MQswCQYDVQQGEwJJTDAeFw0wNDAzMjQxMTM3MjBaFw0yOTAzMTYxNTA0NTZaMDwx
+GzAZBgNVBAMTEkNvbVNpZ24gU2VjdXJlZCBDQTEQMA4GA1UEChMHQ29tU2lnbjEL
+MAkGA1UEBhMCSUwwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDGtWhf
+HZQVw6QIVS3joFd67+l0Kru5fFdJGhFeTymHDEjWaueP1H5XJLkGieQcPOqs49oh
+gHMhCu95mGwfCP+hUH3ymBvJVG8+pSjsIQQPRbsHPaHA+iqYHU4Gk/v1iDurX8sW
+v+bznkqH7Rnqwp9D5PGBpX8QTz7RSmKtUxvLg/8HZaWSLWapW7ha9B20IZFKF3ue
+Mv5WJDmyVIRD9YTC2LxBkMyd1mja6YJQqTtoz7VdApRgFrFD2UNd3V2Hbuq7s8lr
+9gOUCXDeFhF6K+h2j0kQmHe5Y1yLM5d19guMsqtb3nQgJT/j8xH5h2iGNXHDHYwt
+6+UarA9z1YJZQIDTAgMBAAGjgacwgaQwDAYDVR0TBAUwAwEB/zBEBgNVHR8EPTA7
+MDmgN6A1hjNodHRwOi8vZmVkaXIuY29tc2lnbi5jby5pbC9jcmwvQ29tU2lnblNl
+Y3VyZWRDQS5jcmwwDgYDVR0PAQH/BAQDAgGGMB8GA1UdIwQYMBaAFMFL7XC29z58
+ADsAj8c+DkWfHl3sMB0GA1UdDgQWBBTBS+1wtvc+fAA7AI/HPg5Fnx5d7DANBgkq
+hkiG9w0BAQUFAAOCAQEAFs/ukhNQq3sUnjO2QiBq1BW9Cav8cujvR3qQrFHBZE7p
+iL1DRYHjZiM/EoZNGeQFsOY3wo3aBijJD4mkU6l1P7CW+6tMM1X5eCZGbxs2mPtC
+dsGCuY7e+0X5YxtiOzkGynd6qDwJz2w2PQ8KRUtpFhpFfTMDZflScZAmlaxMDPWL
+kz/MdXSFmLr/YnpNH4n+rr2UAJm/EaXc4HnFFgt9AmEd6oX5AhVP51qJThRv4zdL
+hfXBPGHg/QVBspJ/wx2g0K5SZGBrGMYmnNj1ZOQ2GmKfig8+/21OGVZOIJFsnzQz
+OjRXUDpvgV4GxvU+fE6OK85lBi5d0ipTdF7Tbieejw==
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIID/jCCAuagAwIBAgIQFaxulBmyeUtB9iepwxgPHzANBgkqhkiG9w0BAQsFADCB
+mDELMAkGA1UEBhMCVVMxFjAUBgNVBAoTDUdlb1RydXN0IEluYy4xOTA3BgNVBAsT
+MChjKSAyMDA4IEdlb1RydXN0IEluYy4gLSBGb3IgYXV0aG9yaXplZCB1c2Ugb25s
+eTE2MDQGA1UEAxMtR2VvVHJ1c3QgUHJpbWFyeSBDZXJ0aWZpY2F0aW9uIEF1dGhv
+cml0eSAtIEczMB4XDTA4MDQwMjAwMDAwMFoXDTM3MTIwMTIzNTk1OVowgZgxCzAJ
+BgNVBAYTAlVTMRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMTkwNwYDVQQLEzAoYykg
+MjAwOCBHZW9UcnVzdCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxNjA0
+BgNVBAMTLUdlb1RydXN0IFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkg
+LSBHMzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANziXmJYHTNXOTIz
++uvLh4yn1ErdBojqZI4xmKU4kB6Yzy5jK/BGvESyiaHAKAxJcCGVn2TAppMSAmUm
+hsalifD614SgcK9PGpc/BkTVyetyEH3kMSj7HGHmKAdEc5IiaacDiGydY8hS2pgn
+5whMcD60yRLBxWeDXTPzAxHsatBT4tG6NmCUgLthY2xbF37fQJQeqw3CIShwiP/W
+JmxsYAQlTlV+fe+/lEjetx3dcI0FX4ilm/LC7urRQEFtYjgdVgbFA0dRIBn8exAL
+DmKudlW/X3e+PkkBUz2YJQN2JFodtNuJ6nnltrM7P7pMKEF/BqxqjsHQ9gUdfeZC
+huOl1UcCAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYw
+HQYDVR0OBBYEFMR5yo6hTgMdHNxr2zFblD4/MH8tMA0GCSqGSIb3DQEBCwUAA4IB
+AQAtxRPPVoB7eni9n64smefv2t+UXglpp+duaIy9cr5HqQ6XErhK8WTTOd8lNNTB
+zU6B8A8ExCSzNJbGpqow32hhc9f5joWJ7w5elShKKiePEI4ufIbEAp7aDHdlDkQN
+kv39sxY2+hENHYwOB4lqKVb3cvTdFZx3NWZXqxNT2I7BQMXXExZacse3aQHEerGD
+AWh9jUGhlBjBJVz88P6DAod8DQ3PLghcSkANPuyBYeYk28rgDi0Hsj5W3I31QYUH
+SJsMC8tJP33st/3LjWeJGqvtux6jAAgIFyqCXDFdRootD4abdNlF+9RAsXqqaC2G
+spki4cErx5z481+oghLrGREt
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIFsDCCA5igAwIBAgIQFci9ZUdcr7iXAF7kBtK8nTANBgkqhkiG9w0BAQUFADBe
+MQswCQYDVQQGEwJUVzEjMCEGA1UECgwaQ2h1bmdod2EgVGVsZWNvbSBDby4sIEx0
+ZC4xKjAoBgNVBAsMIWVQS0kgUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAe
+Fw0wNDEyMjAwMjMxMjdaFw0zNDEyMjAwMjMxMjdaMF4xCzAJBgNVBAYTAlRXMSMw
+IQYDVQQKDBpDaHVuZ2h3YSBUZWxlY29tIENvLiwgTHRkLjEqMCgGA1UECwwhZVBL
+SSBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIICIjANBgkqhkiG9w0BAQEF
+AAOCAg8AMIICCgKCAgEA4SUP7o3biDN1Z82tH306Tm2d0y8U82N0ywEhajfqhFAH
+SyZbCUNsIZ5qyNUD9WBpj8zwIuQf5/dqIjG3LBXy4P4AakP/h2XGtRrBp0xtInAh
+ijHyl3SJCRImHJ7K2RKilTza6We/CKBk49ZCt0Xvl/T29de1ShUCWH2YWEtgvM3X
+DZoTM1PRYfl61dd4s5oz9wCGzh1NlDivqOx4UXCKXBCDUSH3ET00hl7lSM2XgYI1
+TBnsZfZrxQWh7kcT1rMhJ5QQCtkkO7q+RBNGMD+XPNjX12ruOzjjK9SXDrkb5wdJ
+fzcq+Xd4z1TtW0ado4AOkUPB1ltfFLqfpo0kR0BZv3I4sjZsN/+Z0V0OWQqraffA
+sgRFelQArr5T9rXn4fg8ozHSqf4hUmTFpmfwdQcGlBSBVcYn5AGPF8Fqcde+S/uU
+WH1+ETOxQvdibBjWzwloPn9s9h6PYq2lY9sJpx8iQkEeb5mKPtf5P0B6ebClAZLS
+nT0IFaUQAS2zMnaolQ2zepr7BxB4EW/hj8e6DyUadCrlHJhBmd8hh+iVBmoKs2pH
+dmX2Os+PYhcZewoozRrSgx4hxyy/vv9haLdnG7t4TY3OZ+XkwY63I2binZB1NJip
+NiuKmpS5nezMirH4JYlcWrYvjB9teSSnUmjDhDXiZo1jDiVN1Rmy5nk3pyKdVDEC
+AwEAAaNqMGgwHQYDVR0OBBYEFB4M97Zn8uGSJglFwFU5Lnc/QkqiMAwGA1UdEwQF
+MAMBAf8wOQYEZyoHAAQxMC8wLQIBADAJBgUrDgMCGgUAMAcGBWcqAwAABBRFsMLH
+ClZ87lt4DJX5GFPBphzYEDANBgkqhkiG9w0BAQUFAAOCAgEACbODU1kBPpVJufGB
+uvl2ICO1J2B01GqZNF5sAFPZn/KmsSQHRGoqxqWOeBLoR9lYGxMqXnmbnwoqZ6Yl
+PwZpVnPDimZI+ymBV3QGypzqKOg4ZyYr8dW1P2WT+DZdjo2NQCCHGervJ8A9tDkP
+JXtoUHRVnAxZfVo9QZQlUgjgRywVMRnVvwdVxrsStZf0X4OFunHB2WyBEXYKCrC/
+gpf36j36+uwtqSiUO1bd0lEursC9CBWMd1I0ltabrNMdjmEPNXubrjlpC2JgQCA2
+j6/7Nu4tCEoduL+bXPjqpRugc6bY+G7gMwRfaKonh+3ZwZCc7b3jajWvY9+rGNm6
+5ulK6lCKD2GTHuItGeIwlDWSXQ62B68ZgI9HkFFLLk3dheLSClIKF5r8GrBQAuUB
+o2M3IUxExJtRmREOc5wGj1QupyheRDmHVi03vYVElOEMSyycw5KFNGHLD7ibSkNS
+/jQ6fbjpKdx2qcgw+BRxgMYeNkh0IkFch4LoGHGLQYlE535YW6i4jRPpp2zDR+2z
+Gp1iro2C6pSe3VkQw63d4k3jMdXH7OjysP6SHhYKGvzZ8/gntsm+HbRsZJB/9OTE
+W9c3rkIO3aQab3yIVMUWbuF6aC74Or8NpDyJO3inTmODBCEIZ43ygknQW/2xzQ+D
+hNQ+IIX3Sj0rnP0qCglN6oH4EZw=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIEXzCCA0egAwIBAgIBATANBgkqhkiG9w0BAQUFADCB0DELMAkGA1UEBhMCRVMx
+SDBGBgNVBAoTP0laRU5QRSBTLkEuIC0gQ0lGIEEtMDEzMzcyNjAtUk1lcmMuVml0
+b3JpYS1HYXN0ZWl6IFQxMDU1IEY2MiBTODFCMEAGA1UEBxM5QXZkYSBkZWwgTWVk
+aXRlcnJhbmVvIEV0b3JiaWRlYSAzIC0gMDEwMTAgVml0b3JpYS1HYXN0ZWl6MRMw
+EQYDVQQDEwpJemVucGUuY29tMR4wHAYJKoZIhvcNAQkBFg9JbmZvQGl6ZW5wZS5j
+b20wHhcNMDMwMTMwMjMwMDAwWhcNMTgwMTMwMjMwMDAwWjCB0DELMAkGA1UEBhMC
+RVMxSDBGBgNVBAoTP0laRU5QRSBTLkEuIC0gQ0lGIEEtMDEzMzcyNjAtUk1lcmMu
+Vml0b3JpYS1HYXN0ZWl6IFQxMDU1IEY2MiBTODFCMEAGA1UEBxM5QXZkYSBkZWwg
+TWVkaXRlcnJhbmVvIEV0b3JiaWRlYSAzIC0gMDEwMTAgVml0b3JpYS1HYXN0ZWl6
+MRMwEQYDVQQDEwpJemVucGUuY29tMR4wHAYJKoZIhvcNAQkBFg9JbmZvQGl6ZW5w
+ZS5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC1btoCXXhp3xIW
+D+Bxl8nUCxkyiazWfpt0e68t+Qt9+lZjKZSdEw2Omj4qvr+ovRmDXO3iWpWVOWDl
+3JHJjAzFCe8ZEBNDH+QNYwZHmPBaMYFOYFdbAFVHWvys152C308hcFJ6xWWGmjvl
+2eMiEl9P2nR2LWue368DCu+ak7j3gjAXaCOdP1a7Bfr+RW3X2SC5R4Xyp8iHlL5J
+PHJD/WBkLrezwzQPdACw8m9EG7q9kUwlNpL32mROujS3ZkT6mQTzJieLiE3X04s0
+uIUqVkk5MhjcHFf7al0N5CzjtTcnXYJKN2Z9EDVskk4olAdGi46eSoZXbjUOP5gk
+Ej6wVZAXAgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEG
+MB0GA1UdDgQWBBTqVk/sPIOhFIh4gbIrBSLAB0FbQjANBgkqhkiG9w0BAQUFAAOC
+AQEAYp7mEzzhw6o5Hf5+T5kcI+t4BJyiIWy7vHlLs/G8dLYXO81aN/Mzg928eMTR
+TxxYZL8dd9uwsJ50TVfX6L0R4Dyw6wikh3fHRrat9ufXi63j5K91Ysr7aXqnF38d
+iAgHYkrwC3kuxHBb9C0KBz6h8Q45/KCyN7d37wWAq38yyhPDlaOvyoE6bdUuK5hT
+m5EYA5JmPyrhQ1moDOyueWBAjxzMEMj+OAY1H90cLv6wszsqerxRrdTOHBdv7MjB
+EIpvEEQkXUxVXAzFuuT6m2t91Lfnwfl/IvljHaVC7DlyyhRYHD6D4Rx+4QKp4tWL
+vpw6LkI+gKNJ/YdMCsRZQzEEFA==
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIID5jCCAs6gAwIBAgIQV8szb8JcFuZHFhfjkDFo4DANBgkqhkiG9w0BAQUFADBi
+MQswCQYDVQQGEwJVUzEhMB8GA1UEChMYTmV0d29yayBTb2x1dGlvbnMgTC5MLkMu
+MTAwLgYDVQQDEydOZXR3b3JrIFNvbHV0aW9ucyBDZXJ0aWZpY2F0ZSBBdXRob3Jp
+dHkwHhcNMDYxMjAxMDAwMDAwWhcNMjkxMjMxMjM1OTU5WjBiMQswCQYDVQQGEwJV
+UzEhMB8GA1UEChMYTmV0d29yayBTb2x1dGlvbnMgTC5MLkMuMTAwLgYDVQQDEydO
+ZXR3b3JrIFNvbHV0aW9ucyBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkwggEiMA0GCSqG
+SIb3DQEBAQUAA4IBDwAwggEKAoIBAQDkvH6SMG3G2I4rC7xGzuAnlt7e+foS0zwz
+c7MEL7xxjOWftiJgPl9dzgn/ggwbmlFQGiaJ3dVhXRncEg8tCqJDXRfQNJIg6nPP
+OCwGJgl6cvf6UDL4wpPTaaIjzkGxzOTVHzbRijr4jGPiFFlp7Q3Tf2vouAPlT2rl
+mGNpSAW+Lv8ztumXWWn4Zxmuk2GWRBXTcrA/vGp97Eh/jcOrqnErU2lBUzS1sLnF
+BgrEsEX1QV1uiUV7PTsmjHTC5dLRfbIR1PtYMiKagMnc/Qzpf14Dl847ABSHJ3A4
+qY5usyd2mFHgBeMhqxrVhSI8KbWaFsWAqPS7azCPL0YCorEMIuDTAgMBAAGjgZcw
+gZQwHQYDVR0OBBYEFCEwyfsA106Y2oeqKtCnLrFAMadMMA4GA1UdDwEB/wQEAwIB
+BjAPBgNVHRMBAf8EBTADAQH/MFIGA1UdHwRLMEkwR6BFoEOGQWh0dHA6Ly9jcmwu
+bmV0c29sc3NsLmNvbS9OZXR3b3JrU29sdXRpb25zQ2VydGlmaWNhdGVBdXRob3Jp
+dHkuY3JsMA0GCSqGSIb3DQEBBQUAA4IBAQC7rkvnt1frf6ott3NHhWrB5KUd5Oc8
+6fRZZXe1eltajSU24HqXLjjAV2CDmAaDn7l2em5Q4LqILPxFzBiwmZVRDuwduIj/
+h1AcgsLj4DKAv6ALR8jDMe+ZZzKATxcheQxpXN5eNK4CtSbqUN9/GGUsyfJj4akH
+/nxxH2szJGoeBfcFaMBqEssuXmHLrijTfsK0ZpEmXzwuJF/LWA/rKOyvEZbz3Htv
+wKeI8lN3s2Berq4o2jUsbzRF0ybh3uxbTydrFny9RAQYgrOJeRcQcT16ohZO9QHN
+pGxlaKFJdlxDydi8NmdspZS11My5vWo1ViHe2MPr+8ukYEywVaCge1ey
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIEuTCCA6GgAwIBAgIQQBrEZCGzEyEDDrvkEhrFHTANBgkqhkiG9w0BAQsFADCB
+vTELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQL
+ExZWZXJpU2lnbiBUcnVzdCBOZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwOCBWZXJp
+U2lnbiwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5MTgwNgYDVQQDEy9W
+ZXJpU2lnbiBVbml2ZXJzYWwgUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAe
+Fw0wODA0MDIwMDAwMDBaFw0zNzEyMDEyMzU5NTlaMIG9MQswCQYDVQQGEwJVUzEX
+MBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlTaWduIFRydXN0
+IE5ldHdvcmsxOjA4BgNVBAsTMShjKSAyMDA4IFZlcmlTaWduLCBJbmMuIC0gRm9y
+IGF1dGhvcml6ZWQgdXNlIG9ubHkxODA2BgNVBAMTL1ZlcmlTaWduIFVuaXZlcnNh
+bCBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIIBIjANBgkqhkiG9w0BAQEF
+AAOCAQ8AMIIBCgKCAQEAx2E3XrEBNNti1xWb/1hajCMj1mCOkdeQmIN65lgZOIzF
+9uVkhbSicfvtvbnazU0AtMgtc6XHaXGVHzk8skQHnOgO+k1KxCHfKWGPMiJhgsWH
+H26MfF8WIFFE0XBPV+rjHOPMee5Y2A7Cs0WTwCznmhcrewA3ekEzeOEz4vMQGn+H
+LL729fdC4uW/h2KJXwBL38Xd5HVEMkE6HnFuacsLdUYI0crSK5XQz/u5QGtkjFdN
+/BMReYTtXlT2NJ8IAfMQJQYXStrxHXpma5hgZqTZ79IugvHw7wnqRMkVauIDbjPT
+rJ9VAMf2CGqUuV/c4DPxhGD5WycRtPwW8rtWaoAljQIDAQABo4GyMIGvMA8GA1Ud
+EwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMG0GCCsGAQUFBwEMBGEwX6FdoFsw
+WTBXMFUWCWltYWdlL2dpZjAhMB8wBwYFKw4DAhoEFI/l0xqGrI2Oa8PPgGrUSBgs
+exkuMCUWI2h0dHA6Ly9sb2dvLnZlcmlzaWduLmNvbS92c2xvZ28uZ2lmMB0GA1Ud
+DgQWBBS2d/ppSEefUxLVwuoHMnYH0ZcHGTANBgkqhkiG9w0BAQsFAAOCAQEASvj4
+sAPmLGd75JR3Y8xuTPl9Dg3cyLk1uXBPY/ok+myDjEedO2Pzmvl2MpWRsXe8rJq+
+seQxIcaBlVZaDrHC1LGmWazxY8u4TB1ZkErvkBYoH1quEPuBUDgMbMzxPcP1Y+Oz
+4yHJJDnp/RVmRvQbEdBNc6N9Rvk97ahfYtTxP/jgdFcrGJ2BtMQo2pSXpXDrrB2+
+BxHw1dvd5Yzw1TKwg+ZX4o+/vqGqvz0dtdQ46tewXDpPaj+PwGZsY6rp2aQW9IHR
+lRQOfc2VNNnSj3BzgXucfr2YYdhFh5iQxeuGMMY1v/D/w1WIg0vvBZIGcfK4mJO3
+7M2CYfE45k+XmCpajQ==
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIECTCCAvGgAwIBAgIQDV6ZCtadt3js2AdWO4YV2TANBgkqhkiG9w0BAQUFADBb
+MQswCQYDVQQGEwJVUzEgMB4GA1UEChMXRGlnaXRhbCBTaWduYXR1cmUgVHJ1c3Qx
+ETAPBgNVBAsTCERTVCBBQ0VTMRcwFQYDVQQDEw5EU1QgQUNFUyBDQSBYNjAeFw0w
+MzExMjAyMTE5NThaFw0xNzExMjAyMTE5NThaMFsxCzAJBgNVBAYTAlVTMSAwHgYD
+VQQKExdEaWdpdGFsIFNpZ25hdHVyZSBUcnVzdDERMA8GA1UECxMIRFNUIEFDRVMx
+FzAVBgNVBAMTDkRTVCBBQ0VTIENBIFg2MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A
+MIIBCgKCAQEAuT31LMmU3HWKlV1j6IR3dma5WZFcRt2SPp/5DgO0PWGSvSMmtWPu
+ktKe1jzIDZBfZIGxqAgNTNj50wUoUrQBJcWVHAx+PhCEdc/BGZFjz+iokYi5Q1K7
+gLFViYsx+tC3dr5BPTCapCIlF3PoHuLTrCq9Wzgh1SpL11V94zpVvddtawJXa+ZH
+fAjIgrrep4c9oW24MFbCswKBXy314powGCi4ZtPLAZZv6opFVdbgnf9nKxcCpk4a
+ahELfrd755jWjHZvwTvbUJN+5dCOHze4vbrGn2zpfDPyMjwmR/onJALJfh1biEIT
+ajV8fTXpLmaRcpPVMibEdPVTo7NdmvYJywIDAQABo4HIMIHFMA8GA1UdEwEB/wQF
+MAMBAf8wDgYDVR0PAQH/BAQDAgHGMB8GA1UdEQQYMBaBFHBraS1vcHNAdHJ1c3Rk
+c3QuY29tMGIGA1UdIARbMFkwVwYKYIZIAWUDAgEBATBJMEcGCCsGAQUFBwIBFjto
+dHRwOi8vd3d3LnRydXN0ZHN0LmNvbS9jZXJ0aWZpY2F0ZXMvcG9saWN5L0FDRVMt
+aW5kZXguaHRtbDAdBgNVHQ4EFgQUCXIGThhDD+XWzMNqizF7eI+og7gwDQYJKoZI
+hvcNAQEFBQADggEBAKPYjtay284F5zLNAdMEA+V25FYrnJmQ6AgwbN99Pe7lv7Uk
+QIRJ4dEorsTCOlMwiPH1d25Ryvr/ma8kXxug/fKshMrfqfBfBC6tFr8hlxCBPeP/
+h40y3JTlR4peahPJlJU90u7INJXQgNStMgiAVDzgvVJT11J8smk/f3rPanTK+gQq
+nExaBqXpIK1FZg9p8d2/6eMyi/rgwYZNcjwu2JN4Cir42NInPRmJX1p7ijvMDNpR
+rscL9yuwNwXsvFcj4jjSm2jzVhKIT0J8uDHEtdvkyCE06UgRNe76x5JXxZ805Mf2
+9w4LTJxoeHtxMcfrHuBnQfO3oKfN5XozNmr6mis=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIDljCCAn6gAwIBAgIQC5McOtY5Z+pnI7/Dr5r0SzANBgkqhkiG9w0BAQsFADBl
+MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3
+d3cuZGlnaWNlcnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJv
+b3QgRzIwHhcNMTMwODAxMTIwMDAwWhcNMzgwMTE1MTIwMDAwWjBlMQswCQYDVQQG
+EwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNl
+cnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3QgRzIwggEi
+MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDZ5ygvUj82ckmIkzTz+GoeMVSA
+n61UQbVH35ao1K+ALbkKz3X9iaV9JPrjIgwrvJUXCzO/GU1BBpAAvQxNEP4Htecc
+biJVMWWXvdMX0h5i89vqbFCMP4QMls+3ywPgym2hFEwbid3tALBSfK+RbLE4E9Hp
+EgjAALAcKxHad3A2m67OeYfcgnDmCXRwVWmvo2ifv922ebPynXApVfSr/5Vh88lA
+bx3RvpO704gqu52/clpWcTs/1PPRCv4o76Pu2ZmvA9OPYLfykqGxvYmJHzDNw6Yu
+YjOuFgJ3RFrngQo8p0Quebg/BLxcoIfhG69Rjs3sLPr4/m3wOnyqi+RnlTGNAgMB
+AAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgGGMB0GA1UdDgQW
+BBTOw0q5mVXyuNtgv6l+vVa1lzan1jANBgkqhkiG9w0BAQsFAAOCAQEAyqVVjOPI
+QW5pJ6d1Ee88hjZv0p3GeDgdaZaikmkuOGybfQTUiaWxMTeKySHMq2zNixya1r9I
+0jJmwYrA8y8678Dj1JGG0VDjA9tzd29KOVPt3ibHtX2vK0LRdWLjSisCx1BL4Gni
+lmwORGYQRI+tBev4eaymG+g3NJ1TyWGqolKvSnAWhsI6yLETcDbYz+70CjTVW0z9
+B5yiutkBclzzTcHdDrEcDcRjvq30FPuJ7KJBDkzMyFdA0G4Dqs0MjomZmWzwPDCv
+ON9vvKO+KSAnq3T/EyJ43pdSVR6DtVQgA+6uwE9W3jfMw3+qBCe703e4YtsXfJwo
+IhNzbM8m9Yop5w==
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIDezCCAmOgAwIBAgIBATANBgkqhkiG9w0BAQUFADBfMQswCQYDVQQGEwJUVzES
+MBAGA1UECgwJVEFJV0FOLUNBMRAwDgYDVQQLDAdSb290IENBMSowKAYDVQQDDCFU
+V0NBIFJvb3QgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMDgwODI4MDcyNDMz
+WhcNMzAxMjMxMTU1OTU5WjBfMQswCQYDVQQGEwJUVzESMBAGA1UECgwJVEFJV0FO
+LUNBMRAwDgYDVQQLDAdSb290IENBMSowKAYDVQQDDCFUV0NBIFJvb3QgQ2VydGlm
+aWNhdGlvbiBBdXRob3JpdHkwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB
+AQCwfnK4pAOU5qfeCTiRShFAh6d8WWQUe7UREN3+v9XAu1bihSX0NXIP+FPQQeFE
+AcK0HMMxQhZHhTMidrIKbw/lJVBPhYa+v5guEGcevhEFhgWQxFnQfHgQsIBct+HH
+K3XLfJ+utdGdIzdjp9xCoi2SBBtQwXu4PhvJVgSLL1KbralW6cH/ralYhzC2gfeX
+RfwZVzsrb+RH9JlF/h3x+JejiB03HFyP4HYlmlD4oFT/RJB2I9IyxsOrBr/8+7/z
+rX2SYgJbKdM1o5OaQ2RgXbL6Mv87BK9NQGr5x+PvI/1ry+UPizgN7gr8/g+YnzAx
+3WxSZfmLgb4i4RxYA7qRG4kHAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNV
+HRMBAf8EBTADAQH/MB0GA1UdDgQWBBRqOFsmjd6LWvJPelSDGRjjCDWmujANBgkq
+hkiG9w0BAQUFAAOCAQEAPNV3PdrfibqHDAhUaiBQkr6wQT25JmSDCi/oQMCXKCeC
+MErJk/9q56YAf4lCmtYR5VPOL8zy2gXE/uJQxDqGfczafhAJO5I1KlOy/usrBdls
+XebQ79NqZp4VKIV66IIArB6nCWlWQtNoURi+VJq/REG6Sb4gumlc7rh3zc5sH62D
+lhh9DrUUOYTxKOkto557HnpyWoOzeW/vtPzQCqVYT0bf+215WfKEIlKuD8z7fDvn
+aspHYcN6+NOSBB+4IIThNlQWx0DeO4pz3N/GCUzf7Nr/1FNCocnyYh0igzyXxfkZ
+YiesZSLX0zzG5Y6yU8xJzrww/nsOM5D77dIUkR8Hrw==
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIE5zCCA8+gAwIBAgIBADANBgkqhkiG9w0BAQUFADCBjTELMAkGA1UEBhMCQ0Ex
+EDAOBgNVBAgTB09udGFyaW8xEDAOBgNVBAcTB1Rvcm9udG8xHTAbBgNVBAoTFEVj
+aG93b3J4IENvcnBvcmF0aW9uMR8wHQYDVQQLExZDZXJ0aWZpY2F0aW9uIFNlcnZp
+Y2VzMRowGAYDVQQDExFFY2hvd29yeCBSb290IENBMjAeFw0wNTEwMDYxMDQ5MTNa
+Fw0zMDEwMDcxMDQ5MTNaMIGNMQswCQYDVQQGEwJDQTEQMA4GA1UECBMHT250YXJp
+bzEQMA4GA1UEBxMHVG9yb250bzEdMBsGA1UEChMURWNob3dvcnggQ29ycG9yYXRp
+b24xHzAdBgNVBAsTFkNlcnRpZmljYXRpb24gU2VydmljZXMxGjAYBgNVBAMTEUVj
+aG93b3J4IFJvb3QgQ0EyMIIBIDANBgkqhkiG9w0BAQEFAAOCAQ0AMIIBCAKCAQEA
+utU/5BkV15UBf+s+JQruKQxr77s3rjp/RpOtmhHILIiO5gsEWP8MMrfrVEiidjI6
+Qh6ans0KAWc2Dw0/j4qKAQzOSyAZgjcdypNTBZ7muv212DA2Pu41rXqwMrlBrVi/
+KTghfdLlNRu6JrC5y8HarrnRFSKF1Thbzz921kLDRoCi+FVs5eVuK5LvIfkhNAqA
+byrTgO3T9zfZgk8upmEkANPDL1+8y7dGPB/d6lk0I5mv8PESKX02TlvwgRSIiTHR
+k8++iOPLBWlGp7ZfqTEXkPUZhgrQQvxcrwCUo6mk8TqgxCDP5FgPoHFiPLef5szP
+ZLBJDWp7GLyE1PmkQI6WiwIBA6OCAVAwggFMMA8GA1UdEwEB/wQFMAMBAf8wCwYD
+VR0PBAQDAgEGMB0GA1UdDgQWBBQ74YEboKs/OyGC1eISrq5QqxSlEzCBugYDVR0j
+BIGyMIGvgBQ74YEboKs/OyGC1eISrq5QqxSlE6GBk6SBkDCBjTELMAkGA1UEBhMC
+Q0ExEDAOBgNVBAgTB09udGFyaW8xEDAOBgNVBAcTB1Rvcm9udG8xHTAbBgNVBAoT
+FEVjaG93b3J4IENvcnBvcmF0aW9uMR8wHQYDVQQLExZDZXJ0aWZpY2F0aW9uIFNl
+cnZpY2VzMRowGAYDVQQDExFFY2hvd29yeCBSb290IENBMoIBADBQBgNVHSAESTBH
+MEUGCysGAQQB+REKAQMBMDYwNAYIKwYBBQUHAgEWKGh0dHA6Ly93d3cuZWNob3dv
+cnguY29tL2NhL3Jvb3QyL2Nwcy5wZGYwDQYJKoZIhvcNAQEFBQADggEBAG+nrPi/
+0RpfEzrj02C6JGPUar4nbjIhcY6N7DWNeqBoUulBSIH/PYGNHYx7/lnJefiixPGE
+7TQ5xPgElxb9bK8zoAApO7U33OubqZ7M7DlHnFeCoOoIAZnG1kuwKwD5CXKB2a74
+HzcqNnFW0IsBFCYqrVh/rQgJOzDA8POGbH0DeD0xjwBBooAolkKT+7ZItJF1Pb56
+QpDL9G+16F7GkmnKlAIYT3QTS3yFGYChnJcd+6txUPhKi9sSOOmAIaKHnkH9Scz+
+A2cSi4A3wUYXVatuVNHpRb2lygfH3SuCX9MU8Ure3zBlSU1LALtMqI4JmcQmQpIq
+zIzvO2jHyu9PQqo=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIEqjCCA5KgAwIBAgIOLmoAAQACH9dSISwRXDswDQYJKoZIhvcNAQEFBQAwdjEL
+MAkGA1UEBhMCREUxHDAaBgNVBAoTE1RDIFRydXN0Q2VudGVyIEdtYkgxIjAgBgNV
+BAsTGVRDIFRydXN0Q2VudGVyIENsYXNzIDIgQ0ExJTAjBgNVBAMTHFRDIFRydXN0
+Q2VudGVyIENsYXNzIDIgQ0EgSUkwHhcNMDYwMTEyMTQzODQzWhcNMjUxMjMxMjI1
+OTU5WjB2MQswCQYDVQQGEwJERTEcMBoGA1UEChMTVEMgVHJ1c3RDZW50ZXIgR21i
+SDEiMCAGA1UECxMZVEMgVHJ1c3RDZW50ZXIgQ2xhc3MgMiBDQTElMCMGA1UEAxMc
+VEMgVHJ1c3RDZW50ZXIgQ2xhc3MgMiBDQSBJSTCCASIwDQYJKoZIhvcNAQEBBQAD
+ggEPADCCAQoCggEBAKuAh5uO8MN8h9foJIIRszzdQ2Lu+MNF2ujhoF/RKrLqk2jf
+tMjWQ+nEdVl//OEd+DFwIxuInie5e/060smp6RQvkL4DUsFJzfb95AhmC1eKokKg
+uNV/aVyQMrKXDcpK3EY+AlWJU+MaWss2xgdW94zPEfRMuzBwBJWl9jmM/XOBCH2J
+XjIeIqkiRUuwZi4wzJ9l/fzLganx4Duvo4bRierERXlQXa7pIXSSTYtZgo+U4+lK
+8edJsBTj9WLL1XK9H7nSn6DNqPoByNkN39r8R52zyFTfSUrxIan+GE7uSNQZu+99
+5OKdy1u2bv/jzVrndIIFuoAlOMvkaZ6vQaoahPUCAwEAAaOCATQwggEwMA8GA1Ud
+EwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBTjq1RMgKHbVkO3
+kUrL84J6E1wIqzCB7QYDVR0fBIHlMIHiMIHfoIHcoIHZhjVodHRwOi8vd3d3LnRy
+dXN0Y2VudGVyLmRlL2NybC92Mi90Y19jbGFzc18yX2NhX0lJLmNybIaBn2xkYXA6
+Ly93d3cudHJ1c3RjZW50ZXIuZGUvQ049VEMlMjBUcnVzdENlbnRlciUyMENsYXNz
+JTIwMiUyMENBJTIwSUksTz1UQyUyMFRydXN0Q2VudGVyJTIwR21iSCxPVT1yb290
+Y2VydHMsREM9dHJ1c3RjZW50ZXIsREM9ZGU/Y2VydGlmaWNhdGVSZXZvY2F0aW9u
+TGlzdD9iYXNlPzANBgkqhkiG9w0BAQUFAAOCAQEAjNfffu4bgBCzg/XbEeprS6iS
+GNn3Bzn1LL4GdXpoUxUc6krtXvwjshOg0wn/9vYua0Fxec3ibf2uWWuFHbhOIprt
+ZjluS5TmVfwLG4t3wVMTZonZKNaL80VKY7f9ewthXbhtvsPcW3nS7Yblok2+XnR8
+au0WOB9/WIFaGusyiC2y8zl3gK9etmF1KdsjTYjKUCjLhdLTEKJZbtOTVAB6okaV
+hgWcqRmY5TFyDADiZ9lA4CQze28suVyrZZ0srHbqNZn1l7kPJOzHdiEoZa5X6AeI
+dUpWoNIFOqTmjZKILPPy4cHGYdtBxceb9w4aUUXCYWvcZCcXjFq32nQozZfkvQ==
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIEMDCCAxigAwIBAgIQUJRs7Bjq1ZxN1ZfvdY+grTANBgkqhkiG9w0BAQUFADCB
+gjELMAkGA1UEBhMCVVMxHjAcBgNVBAsTFXd3dy54cmFtcHNlY3VyaXR5LmNvbTEk
+MCIGA1UEChMbWFJhbXAgU2VjdXJpdHkgU2VydmljZXMgSW5jMS0wKwYDVQQDEyRY
+UmFtcCBHbG9iYWwgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMDQxMTAxMTcx
+NDA0WhcNMzUwMTAxMDUzNzE5WjCBgjELMAkGA1UEBhMCVVMxHjAcBgNVBAsTFXd3
+dy54cmFtcHNlY3VyaXR5LmNvbTEkMCIGA1UEChMbWFJhbXAgU2VjdXJpdHkgU2Vy
+dmljZXMgSW5jMS0wKwYDVQQDEyRYUmFtcCBHbG9iYWwgQ2VydGlmaWNhdGlvbiBB
+dXRob3JpdHkwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCYJB69FbS6
+38eMpSe2OAtp87ZOqCwuIR1cRN8hXX4jdP5efrRKt6atH67gBhbim1vZZ3RrXYCP
+KZ2GG9mcDZhtdhAoWORlsH9KmHmf4MMxfoArtYzAQDsRhtDLooY2YKTVMIJt2W7Q
+DxIEM5dfT2Fa8OT5kavnHTu86M/0ay00fOJIYRyO82FEzG+gSqmUsE3a56k0enI4
+qEHMPJQRfevIpoy3hsvKMzvZPTeL+3o+hiznc9cKV6xkmxnr9A8ECIqsAxcZZPRa
+JSKNNCyy9mgdEm3Tih4U2sSPpuIjhdV6Db1q4Ons7Be7QhtnqiXtRYMh/MHJfNVi
+PvryxS3T/dRlAgMBAAGjgZ8wgZwwEwYJKwYBBAGCNxQCBAYeBABDAEEwCwYDVR0P
+BAQDAgGGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFMZPoj0GY4QJnM5i5ASs
+jVy16bYbMDYGA1UdHwQvMC0wK6ApoCeGJWh0dHA6Ly9jcmwueHJhbXBzZWN1cml0
+eS5jb20vWEdDQS5jcmwwEAYJKwYBBAGCNxUBBAMCAQEwDQYJKoZIhvcNAQEFBQAD
+ggEBAJEVOQMBG2f7Shz5CmBbodpNl2L5JFMn14JkTpAuw0kbK5rc/Kh4ZzXxHfAR
+vbdI4xD2Dd8/0sm2qlWkSLoC295ZLhVbO50WfUfXN+pfTXYSNrsf16GBBEYgoyxt
+qZ4Bfj8pzgCT3/3JknOJiWSe5yvkHJEs0rnOfc5vMZnT5r7SHpDwCRR5XCOrTdLa
+IR9NmXmd4c8nnxCbHIgNsIpkQTG4DmyQJKSbXHGPurt+HBvbaoAPIbzp26a3QPSy
+i6mx5O+aGtA9aZnuqCij4Tyz8LIRnM98QObd50N9otg6tamN8jSZxNQQ4Qb9CYQQ
+O+7ETPTsJ3xCwnR8gooJybQDJbw=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIDOzCCAiOgAwIBAgIRANAeRlAAACmMAAAAAgAAAAIwDQYJKoZIhvcNAQEFBQAw
+PzEkMCIGA1UEChMbRGlnaXRhbCBTaWduYXR1cmUgVHJ1c3QgQ28uMRcwFQYDVQQD
+Ew5EU1QgUm9vdCBDQSBYNDAeFw0wMDA5MTMwNjIyNTBaFw0yMDA5MTMwNjIyNTBa
+MD8xJDAiBgNVBAoTG0RpZ2l0YWwgU2lnbmF0dXJlIFRydXN0IENvLjEXMBUGA1UE
+AxMORFNUIFJvb3QgQ0EgWDQwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB
+AQCthX3OFEYY8gSeIYur0O4ypOT68HnDrjLfIutL5PZHRwQGjzCPb9PFo/ihboJ8
+RvfGhBAqpQCo47zwYEhpWm1jB+L/OE/dBBiyn98krfU2NiBKSom2J58RBeAwHGEy
+cO+lewyjVvbDDLUy4CheY059vfMjPAftCRXjqSZIolQb9FdPcAoa90mFwB7rKniE
+J7vppdrUScSS0+eBrHSUPLdvwyn4RGp+lSwbWYcbg5EpSpE0GRJdchic0YDjvIoC
+YHpe7Rkj93PYRTQyU4bhC88ck8tMqbvRYqMRqR+vobbkrj5LLCOQCHV5WEoxWh+0
+E2SpIFe7RkV++MmpIAc0h1tZAgMBAAGjMjAwMA8GA1UdEwEB/wQFMAMBAf8wHQYD
+VR0OBBYEFPCD6nPIP1ubWzdf9UyPWvf0hki9MA0GCSqGSIb3DQEBBQUAA4IBAQCE
+G85wl5eEWd7adH6XW/ikGN5salvpq/Fix6yVTzE6CrhlP5LBdkf6kx1bSPL18M45
+g0rw2zA/MWOhJ3+S6U+BE0zPGCuu8YQaZibR7snm3HiHUaZNMu5c8D0x0bcMxDjY
+AVVcHCoNiL53Q4PLW27nbY6wwG0ffFKmgV3blxrYWfuUDgGpyPwHwkfVFvz9qjaV
+mf12VJffL6W8omBPtgteb6UaT/k1oJ7YI0ldGf+ngpVbRhD+LC3cUtT6GO/BEPZu
+8YTV/hbiDH5v3khVqMIeKT6o8IuXGG7F6a6vKwP1F1FwTXf4UC/ivhme7vdUH7B/
+Vv4AEbT8dNfEeFxrkDbh
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIEQzCCAyugAwIBAgIBATANBgkqhkiG9w0BAQUFADB/MQswCQYDVQQGEwJHQjEb
+MBkGA1UECAwSR3JlYXRlciBNYW5jaGVzdGVyMRAwDgYDVQQHDAdTYWxmb3JkMRow
+GAYDVQQKDBFDb21vZG8gQ0EgTGltaXRlZDElMCMGA1UEAwwcVHJ1c3RlZCBDZXJ0
+aWZpY2F0ZSBTZXJ2aWNlczAeFw0wNDAxMDEwMDAwMDBaFw0yODEyMzEyMzU5NTla
+MH8xCzAJBgNVBAYTAkdCMRswGQYDVQQIDBJHcmVhdGVyIE1hbmNoZXN0ZXIxEDAO
+BgNVBAcMB1NhbGZvcmQxGjAYBgNVBAoMEUNvbW9kbyBDQSBMaW1pdGVkMSUwIwYD
+VQQDDBxUcnVzdGVkIENlcnRpZmljYXRlIFNlcnZpY2VzMIIBIjANBgkqhkiG9w0B
+AQEFAAOCAQ8AMIIBCgKCAQEA33FvNlhTWvI2VFeAxHQIIO0Yfyod5jWaHiWsnOWW
+fnJSoBVC21ndZHoa0Lh73TkVvFVIxO06AOoxEbrycXQaZ7jPM8yoMa+j49d/vzMt
+TGo87IvDktJTdyR0nAducPy9C1t2ul/y/9c3S0pgePfw+spwtOpZqqPOSC+pw7IL
+fhdyFgymBwwbOM/JYrc/oJOlh0Hyt3BAd9i+FHzjqMB6juljatEPmsbS9Is6FARW
+1O24zG71++IsWL1/T2sr92AkWCTOJu80kTrV44HQsvAEAtdbtz6SrGsSivnkBbA7
+kUlcsutT6vifR4buv5XAwAaf0lteERv0xwQ1KdJVXOTt6wIDAQABo4HJMIHGMB0G
+A1UdDgQWBBTFe1i97doladL3WRaoszLAeydb9DAOBgNVHQ8BAf8EBAMCAQYwDwYD
+VR0TAQH/BAUwAwEB/zCBgwYDVR0fBHwwejA8oDqgOIY2aHR0cDovL2NybC5jb21v
+ZG9jYS5jb20vVHJ1c3RlZENlcnRpZmljYXRlU2VydmljZXMuY3JsMDqgOKA2hjRo
+dHRwOi8vY3JsLmNvbW9kby5uZXQvVHJ1c3RlZENlcnRpZmljYXRlU2VydmljZXMu
+Y3JsMA0GCSqGSIb3DQEBBQUAA4IBAQDIk4E7ibSvuIQSTI3S8NtwuleGFTQQuS9/
+HrCoiWChisJ3DFBKmwCL2Iv0QeLQg4pKHBQGsKNoBXAxMKdTmw7pSqBYaWcOrp32
+pSxBvzwGa+RZzG0Q8ZZvH9/0BAKkn0U+yNj6NkZEUD+Cl5EfKNsYEYwq5GWDVxIS
+jBc/lDb+XbDABHcTuPQV1T84zJQ6VdCsmPW6AF/ghhmBeC8owH7TzEIK9a5QoNE+
+xqFx7D+gIIxmOom0jtTYsU0lR+4viMi14QVFwL4Ucd56/Y57fU0IlqUSc/Atyjcn
+dBInTMu2l+nZrghtWjlA3QVHdWpaIbOjGM9O9y5Xt5hwXsjEeLBi
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIDvDCCAqSgAwIBAgIQB1YipOjUiolN9BPI8PjqpTANBgkqhkiG9w0BAQUFADBK
+MQswCQYDVQQGEwJVUzEgMB4GA1UEChMXU2VjdXJlVHJ1c3QgQ29ycG9yYXRpb24x
+GTAXBgNVBAMTEFNlY3VyZSBHbG9iYWwgQ0EwHhcNMDYxMTA3MTk0MjI4WhcNMjkx
+MjMxMTk1MjA2WjBKMQswCQYDVQQGEwJVUzEgMB4GA1UEChMXU2VjdXJlVHJ1c3Qg
+Q29ycG9yYXRpb24xGTAXBgNVBAMTEFNlY3VyZSBHbG9iYWwgQ0EwggEiMA0GCSqG
+SIb3DQEBAQUAA4IBDwAwggEKAoIBAQCvNS7YrGxVaQZx5RNoJLNP2MwhR/jxYDiJ
+iQPpvepeRlMJ3Fz1Wuj3RSoC6zFh1ykzTM7HfAo3fg+6MpjhHZevj8fcyTiW89sa
+/FHtaMbQbqR8JNGuQsiWUGMu4P51/pinX0kuleM5M2SOHqRfkNJnPLLZ/kG5VacJ
+jnIFHovdRIWCQtBJwB1g8NEXLJXr9qXBkqPFwqcIYA1gBBCWeZ4WNOaptvolRTnI
+HmX5k/Wq8VLcmZg9pYYaDDUz+kulBAYVHDGA76oYa8J719rO+TMg1fW9ajMtgQT7
+sFzUnKPiXB3jqUJ1XnvUd+85VLrJChgbEplJL4hL/VBi0XPnj3pDAgMBAAGjgZ0w
+gZowEwYJKwYBBAGCNxQCBAYeBABDAEEwCwYDVR0PBAQDAgGGMA8GA1UdEwEB/wQF
+MAMBAf8wHQYDVR0OBBYEFK9EBMJBfkiD2045AuzshHrmzsmkMDQGA1UdHwQtMCsw
+KaAnoCWGI2h0dHA6Ly9jcmwuc2VjdXJldHJ1c3QuY29tL1NHQ0EuY3JsMBAGCSsG
+AQQBgjcVAQQDAgEAMA0GCSqGSIb3DQEBBQUAA4IBAQBjGghAfaReUw132HquHw0L
+URYD7xh8yOOvaliTFGCRsoTciE6+OYo68+aCiV0BN7OrJKQVDpI1WkpEXk5X+nXO
+H0jOZvQ8QCaSmGwb7iRGDBezUqXbpZGRzzfTb+cnCDpOGR86p1hcF895P4vkp9Mm
+I50mD1hp/Ed+stCNi5O/KU9DaXR2Z0vPB4zmAve14bRDtUstFJ/53CYNv6ZHdAbY
+iNE6KTCEztI5gGIbqMdXSbxqVVFnFUq+NQfk1XWYN3kwFNspnWzFacxHVaIw98xc
+f8LDmBxrThaA63p4ZUWiABqvDA1VZDRIuJK58bRQKfJPIx/abKwfROHdI3hRW8cW
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIID+TCCAuGgAwIBAgIQW1fXqEywr9nTb0ugMbTW4jANBgkqhkiG9w0BAQUFADB5
+MQswCQYDVQQGEwJVUzENMAsGA1UEChMEVklTQTEvMC0GA1UECxMmVmlzYSBJbnRl
+cm5hdGlvbmFsIFNlcnZpY2UgQXNzb2NpYXRpb24xKjAoBgNVBAMTIVZpc2EgSW5m
+b3JtYXRpb24gRGVsaXZlcnkgUm9vdCBDQTAeFw0wNTA2MjcxNzQyNDJaFw0yNTA2
+MjkxNzQyNDJaMHkxCzAJBgNVBAYTAlVTMQ0wCwYDVQQKEwRWSVNBMS8wLQYDVQQL
+EyZWaXNhIEludGVybmF0aW9uYWwgU2VydmljZSBBc3NvY2lhdGlvbjEqMCgGA1UE
+AxMhVmlzYSBJbmZvcm1hdGlvbiBEZWxpdmVyeSBSb290IENBMIIBIjANBgkqhkiG
+9w0BAQEFAAOCAQ8AMIIBCgKCAQEAyREA4R/QkkfpLx0cYjga/EhIPZpchH0MZsRZ
+FfP6C2ITtf/Wc+MtgD4yTK0yoiXvni3d+aCtEgK3GDvkdgYrgF76ROJFZwUQjQ9l
+x42gRT05DbXvWFoy7dTglCZ9z/Tt2Cnktv9oxKgmkeHY/CyfpCBg1S8xth2JlGMR
+0ug/GMO5zANuegZOv438p5Lt5So+du2Gl+RMFQqEPwqN5uJSqAe0VtmB4gWdQ8on
+Bj2ZAM2R73QW7UW0Igt2vA4JaSiNtaAG/Y/58VXWHGgbq7rDtNK1R30X0kJV0rGA
+ib3RSwB3LpG7bOjbIucV5mQgJoVjoA1e05w6g1x/KmNTmOGRVwIDAQABo30wezAP
+BgNVHRMBAf8EBTADAQH/MDkGA1UdIAQyMDAwLgYFZ4EDAgEwJTAVBggrBgEFBQcC
+ARYJMS4yLjMuNC41MAwGCCsGAQUFBwICMAAwDgYDVR0PAQH/BAQDAgEGMB0GA1Ud
+DgQWBBRPitp2/2d3I5qmgH1924h1hfeBejANBgkqhkiG9w0BAQUFAAOCAQEACUW1
+QdUHdDJydgDPmYt+telnG/Su+DPaf1cregzlN43bJaJosMP7NwjoJY/H2He4XLWb
+5rXEkl+xH1UyUwF7mtaUoxbGxEvt8hPZSTB4da2mzXgwKvXuHyzF5Qjy1hOB0/pS
+WaF9ARpVKJJ7TOJQdGKBsF2Ty4fSCLqZLgfxbqwMsd9sysXI3rDXjIhekqvbgeLz
+PqZr+pfgFhwCCLSMQWl5Ll3u7Qk9wR094DZ6jj6+JCVCRUS3HyabH4OlM0Vc2K+j
+INsF/64Or7GNtRf9HYEJvrPxHINxl3JVwhYj4ASeaO4KwhVbwtw94Tc/XrGcexDo
+c5lC3rAi4/UZqweYCw==
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIID7zCCAtegAwIBAgIBADANBgkqhkiG9w0BAQsFADCBmDELMAkGA1UEBhMCVVMx
+EDAOBgNVBAgTB0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxJTAjBgNVBAoT
+HFN0YXJmaWVsZCBUZWNobm9sb2dpZXMsIEluYy4xOzA5BgNVBAMTMlN0YXJmaWVs
+ZCBTZXJ2aWNlcyBSb290IENlcnRpZmljYXRlIEF1dGhvcml0eSAtIEcyMB4XDTA5
+MDkwMTAwMDAwMFoXDTM3MTIzMTIzNTk1OVowgZgxCzAJBgNVBAYTAlVTMRAwDgYD
+VQQIEwdBcml6b25hMRMwEQYDVQQHEwpTY290dHNkYWxlMSUwIwYDVQQKExxTdGFy
+ZmllbGQgVGVjaG5vbG9naWVzLCBJbmMuMTswOQYDVQQDEzJTdGFyZmllbGQgU2Vy
+dmljZXMgUm9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkgLSBHMjCCASIwDQYJKoZI
+hvcNAQEBBQADggEPADCCAQoCggEBANUMOsQq+U7i9b4Zl1+OiFOxHz/Lz58gE20p
+OsgPfTz3a3Y4Y9k2YKibXlwAgLIvWX/2h/klQ4bnaRtSmpDhcePYLQ1Ob/bISdm2
+8xpWriu2dBTrz/sm4xq6HZYuajtYlIlHVv8loJNwU4PahHQUw2eeBGg6345AWh1K
+Ts9DkTvnVtYAcMtS7nt9rjrnvDH5RfbCYM8TWQIrgMw0R9+53pBlbQLPLJGmpufe
+hRhJfGZOozptqbXuNC66DQO4M99H67FrjSXZm86B0UVGMpZwh94CDklDhbZsc7tk
+6mFBrMnUVN+HL8cisibMn1lUaJ/8viovxFUcdUBgF4UCVTmLfwUCAwEAAaNCMEAw
+DwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFJxfAN+q
+AdcwKziIorhtSpzyEZGDMA0GCSqGSIb3DQEBCwUAA4IBAQBLNqaEd2ndOxmfZyMI
+bw5hyf2E3F/YNoHN2BtBLZ9g3ccaaNnRbobhiCPPE95Dz+I0swSdHynVv/heyNXB
+ve6SbzJ08pGCL72CQnqtKrcgfU28elUSwhXqvfdqlS5sdJ/PHLTyxQGjhdByPq1z
+qwubdQxtRbeOlKyWN7Wg0I8VRw7j6IPdj/3vQQF3zCepYoUz8jcI73HPdwbeyBkd
+iEDPfUYd/x7H4c7/I9vG+o1VTqkC50cRRj70/b17KSa7qWFiNyi2LSr2EIZkyXCn
+0q23KXB56jzaYyWf/Wi3MOxw+3WKt21gZ7IeyLnp2KhvAotnDU0mV3HaIPzBSlCN
+sSi6
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIEDzCCAvegAwIBAgIBADANBgkqhkiG9w0BAQUFADBoMQswCQYDVQQGEwJVUzEl
+MCMGA1UEChMcU3RhcmZpZWxkIFRlY2hub2xvZ2llcywgSW5jLjEyMDAGA1UECxMp
+U3RhcmZpZWxkIENsYXNzIDIgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMDQw
+NjI5MTczOTE2WhcNMzQwNjI5MTczOTE2WjBoMQswCQYDVQQGEwJVUzElMCMGA1UE
+ChMcU3RhcmZpZWxkIFRlY2hub2xvZ2llcywgSW5jLjEyMDAGA1UECxMpU3RhcmZp
+ZWxkIENsYXNzIDIgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwggEgMA0GCSqGSIb3
+DQEBAQUAA4IBDQAwggEIAoIBAQC3Msj+6XGmBIWtDBFk385N78gDGIc/oav7PKaf
+8MOh2tTYbitTkPskpD6E8J7oX+zlJ0T1KKY/e97gKvDIr1MvnsoFAZMej2YcOadN
++lq2cwQlZut3f+dZxkqZJRRU6ybH838Z1TBwj6+wRir/resp7defqgSHo9T5iaU0
+X9tDkYI22WY8sbi5gv2cOj4QyDvvBmVmepsZGD3/cVE8MC5fvj13c7JdBmzDI1aa
+K4UmkhynArPkPw2vCHmCuDY96pzTNbO8acr1zJ3o/WSNF4Azbl5KXZnJHoe0nRrA
+1W4TNSNe35tfPe/W93bC6j67eA0cQmdrBNj41tpvi/JEoAGrAgEDo4HFMIHCMB0G
+A1UdDgQWBBS/X7fRzt0fhvRbVazc1xDCDqmI5zCBkgYDVR0jBIGKMIGHgBS/X7fR
+zt0fhvRbVazc1xDCDqmI56FspGowaDELMAkGA1UEBhMCVVMxJTAjBgNVBAoTHFN0
+YXJmaWVsZCBUZWNobm9sb2dpZXMsIEluYy4xMjAwBgNVBAsTKVN0YXJmaWVsZCBD
+bGFzcyAyIENlcnRpZmljYXRpb24gQXV0aG9yaXR5ggEAMAwGA1UdEwQFMAMBAf8w
+DQYJKoZIhvcNAQEFBQADggEBAAWdP4id0ckaVaGsafPzWdqbAYcaT1epoXkJKtv3
+L7IezMdeatiDh6GX70k1PncGQVhiv45YuApnP+yz3SFmH8lU+nLMPUxA2IGvd56D
+eruix/U0F47ZEUD0/CwqTRV/p2JdLiXTAAsgGh1o+Re49L2L7ShZ3U0WixeDyLJl
+xy16paq8U4Zt3VekyvggQQto8PT7dL5WXXp59fkdheMtlb71cZBDzI0fmgAKhynp
+VSJYACPq4xJDKVtHCN2MQWplBqjlIapBtJUhlbl90TSrE9atvNziPTnNvT51cKEY
+WQPJIrSPnNVeKtelttQKbfi3QBFGmh95DmK/D5fs4C8fF5Q=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIEqjCCA5KgAwIBAgIOSkcAAQAC5aBd1j8AUb8wDQYJKoZIhvcNAQEFBQAwdjEL
+MAkGA1UEBhMCREUxHDAaBgNVBAoTE1RDIFRydXN0Q2VudGVyIEdtYkgxIjAgBgNV
+BAsTGVRDIFRydXN0Q2VudGVyIENsYXNzIDMgQ0ExJTAjBgNVBAMTHFRDIFRydXN0
+Q2VudGVyIENsYXNzIDMgQ0EgSUkwHhcNMDYwMTEyMTQ0MTU3WhcNMjUxMjMxMjI1
+OTU5WjB2MQswCQYDVQQGEwJERTEcMBoGA1UEChMTVEMgVHJ1c3RDZW50ZXIgR21i
+SDEiMCAGA1UECxMZVEMgVHJ1c3RDZW50ZXIgQ2xhc3MgMyBDQTElMCMGA1UEAxMc
+VEMgVHJ1c3RDZW50ZXIgQ2xhc3MgMyBDQSBJSTCCASIwDQYJKoZIhvcNAQEBBQAD
+ggEPADCCAQoCggEBALTgu1G7OVyLBMVMeRwjhjEQY0NVJz/GRcekPewJDRoeIMJW
+Ht4bNwcwIi9v8Qbxq63WyKthoy9DxLCyLfzDlml7forkzMA5EpBCYMnMNWju2l+Q
+Vl/NHE1bWEnrDgFPZPosPIlY2C8u4rBo6SI7dYnWRBpl8huXJh0obazovVkdKyT2
+1oQDZogkAHhg8fir/gKya/si+zXmFtGt9i4S5Po1auUZuV3bOx4a+9P/FRQI2Alq
+ukWdFHlgfa9Aigdzs5OW03Q0jTo3Kd5c7PXuLjHCINy+8U9/I1LZW+Jk2ZyqBwi1
+Rb3R0DHBq1SfqdLDYmAD8bs5SpJKPQq5ncWg/jcCAwEAAaOCATQwggEwMA8GA1Ud
+EwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBTUovyfs8PYA9NX
+XAek0CSnwPIA1DCB7QYDVR0fBIHlMIHiMIHfoIHcoIHZhjVodHRwOi8vd3d3LnRy
+dXN0Y2VudGVyLmRlL2NybC92Mi90Y19jbGFzc18zX2NhX0lJLmNybIaBn2xkYXA6
+Ly93d3cudHJ1c3RjZW50ZXIuZGUvQ049VEMlMjBUcnVzdENlbnRlciUyMENsYXNz
+JTIwMyUyMENBJTIwSUksTz1UQyUyMFRydXN0Q2VudGVyJTIwR21iSCxPVT1yb290
+Y2VydHMsREM9dHJ1c3RjZW50ZXIsREM9ZGU/Y2VydGlmaWNhdGVSZXZvY2F0aW9u
+TGlzdD9iYXNlPzANBgkqhkiG9w0BAQUFAAOCAQEANmDkcPcGIEPZIxpC8vijsrlN
+irTzwppVMXzEO2eatN9NDoqTSheLG43KieHPOh6sHfGcMrSOWXaiQYUlN6AT0PV8
+TtXqluJucsG7Kv5sbviRmEb8yRtXW+rIGjs/sFGYPAfaLFkB2otE6OF0/ado3VS6
+g0bsyEa1+K+XwDsJHI/OcpY9M1ZwvJbL2NV9IJqDnxrcOfHFcqMRA/07QlIp2+gB
+95tejNaNhk4Z+rwcvsUhpYeeeC422wlxo3I0+GzjBgnyXlal092Y+tTmBvTwtiBj
+S+opvaqCZh77gaqnN60TGOaSw4HBM7uIHqHn4rS9MWwOUT1v+5ZWgOI2F9Hc5A==
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIDfDCCAmSgAwIBAgIQGKy1av1pthU6Y2yv2vrEoTANBgkqhkiG9w0BAQUFADBY
+MQswCQYDVQQGEwJVUzEWMBQGA1UEChMNR2VvVHJ1c3QgSW5jLjExMC8GA1UEAxMo
+R2VvVHJ1c3QgUHJpbWFyeSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0wNjEx
+MjcwMDAwMDBaFw0zNjA3MTYyMzU5NTlaMFgxCzAJBgNVBAYTAlVTMRYwFAYDVQQK
+Ew1HZW9UcnVzdCBJbmMuMTEwLwYDVQQDEyhHZW9UcnVzdCBQcmltYXJ5IENlcnRp
+ZmljYXRpb24gQXV0aG9yaXR5MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC
+AQEAvrgVe//UfH1nrYNke8hCUy3f9oQIIGHWAVlqnEQRr+92/ZV+zmEwu3qDXwK9
+AWbK7hWNb6EwnL2hhZ6UOvNWiAAxz9juapYC2e0DjPt1befquFUWBRaa9OBesYjA
+ZIVcFU2Ix7e64HXprQU9nceJSOC7KMgD4TCTZF5SwFlwIjVXiIrxlQqD17wxcwE0
+7e9GceBrAqg1cmuXm2bgyxx5X9gaBGgeRwLmnWDiNpcB3841kt++Z8dtd1k7j53W
+kBWUvEI0EME5+bEnPn7WinXFsq+W06Lem+SYvn3h6YGttm/81w7a4DSwDRp35+MI
+mO9Y+pyEtzavwt+s0vQQBnBxNQIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4G
+A1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQULNVQQZcVi/CPNmFbSvtr2ZnJM5IwDQYJ
+KoZIhvcNAQEFBQADggEBAFpwfyzdtzRP9YZRqSa+S7iq8XEN3GHHoOo0Hnp3DwQ1
+6CePbJC/kRYkRj5KTs4rFtULUh38H2eiAkUxT87z+gOneZ1TatnaYzr4gNfTmeGl
+4b7UVXGYNTq+k+qurUKykG/g/CFNNWMziUnWm07Kx+dOCQD32sfvmWKZd7aVIl6K
+oKv0uHiYyjgZmclynnjNS6yvGaBzEi38wkG6gZHaFloxt/m0cYASSJlyc1pZU8Fj
+UjPtp8nSOQJw+uCxQmYpqptR7TBUIhRf2asdweSU8Pj1K/fqynhG1riR/aYNKxoU
+AT6A8EKglQdebc3MS6RFjasS6LPeWuWgfOgPIh1a6Vk=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIFvTCCA6WgAwIBAgIITxvUL1S7L0swDQYJKoZIhvcNAQEFBQAwRzELMAkGA1UE
+BhMCQ0gxFTATBgNVBAoTDFN3aXNzU2lnbiBBRzEhMB8GA1UEAxMYU3dpc3NTaWdu
+IFNpbHZlciBDQSAtIEcyMB4XDTA2MTAyNTA4MzI0NloXDTM2MTAyNTA4MzI0Nlow
+RzELMAkGA1UEBhMCQ0gxFTATBgNVBAoTDFN3aXNzU2lnbiBBRzEhMB8GA1UEAxMY
+U3dpc3NTaWduIFNpbHZlciBDQSAtIEcyMIICIjANBgkqhkiG9w0BAQEFAAOCAg8A
+MIICCgKCAgEAxPGHf9N4Mfc4yfjDmUO8x/e8N+dOcbpLj6VzHVxumK4DV644N0Mv
+Fz0fyM5oEMF4rhkDKxD6LHmD9ui5aLlV8gREpzn5/ASLHvGiTSf5YXu6t+WiE7br
+YT7QbNHm+/pe7R20nqA1W6GSy/BJkv6FCgU+5tkL4k+73JU3/JHpMjUi0R86TieF
+nbAVlDLaYQ1HTWBCrpJH6INaUFjpiou5XaHc3ZlKHzZnu0jkg7Y360g6rw9njxcH
+6ATK72oxh9TAtvmUcXtnZLi2kUpCe2UuMGoM9ZDulebyzYLs2aFK7PayS+VFheZt
+eJMELpyCbTapxDFkH4aDCyr0NQp4yVXPQbBH6TCfmb5hqAaEuSh6XzjZG6k4sIN/
+c8HDO0gqgg8hm7jMqDXDhBuDsz6+pJVpATqJAHgE2cn0mRmrVn5bi4Y5FZGkECwJ
+MoBgs5PAKrYYC51+jUnyEEp/+dVGLxmSo5mnJqy7jDzmDrxHB9xzUfFwZC8I+bRH
+HTBsROopN4WSaGa8gzj+ezku01DwH/teYLappvonQfGbGHLy9YR0SslnxFSuSGTf
+jNFusB3hB48IHpmccelM2KX3RxIfdNFRnobzwqIjQAtz20um53MGjMGg6cFZrEb6
+5i/4z3GcRm25xBWNOHkDRUjvxF3XCO6HOSKGsg0PWEP3calILv3q1h8CAwEAAaOB
+rDCBqTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQU
+F6DNweRBtjpbO8tFnb0cwpj6hlgwHwYDVR0jBBgwFoAUF6DNweRBtjpbO8tFnb0c
+wpj6hlgwRgYDVR0gBD8wPTA7BglghXQBWQEDAQEwLjAsBggrBgEFBQcCARYgaHR0
+cDovL3JlcG9zaXRvcnkuc3dpc3NzaWduLmNvbS8wDQYJKoZIhvcNAQEFBQADggIB
+AHPGgeAn0i0P4JUw4ppBf1AsX19iYamGamkYDHRJ1l2E6kFSGG9YrVBWIGrGvShp
+WJHckRE1qTodvBqlYJ7YH39FkWnZfrt4csEGDyrOj4VwYaygzQu4OSlWhDJOhrs9
+xCrZ1x9y7v5RoSJBsXECYxqCsGKrXlcSH9/L3XWgwF15kIwb4FDm3jH+mHtwX6WQ
+2K34ArZv02DdQEsixT2tOnqfGhpHkXkzuoLcMmkDlm4fS/Bx/uNncqCxv1yL5PqZ
+IseEuRuNI5c/7SXgz2W79WEE790eslpBIlqhn10s6FvJbakMDHiqYMZWjwFaDGi8
+aRl5xB9+lwW/xekkUV7U1UtT7dkjWjYDZaPBA61BMPNGG4WQr2W11bHkFlt4dR2X
+em1ZqSqPe97Dh4kQmUlzeMg9vVE1dCrV8X5pGyq7O70luJpaPXJhkGaH7gzWTdQR
+dAtq/gsD/KNVV4n+SsuuWxcFyPKNIzFTONItaj+CuY0IavdeQXRuwxF+B6wpYJE/
+OMpXEA29MC/HpeZBoNquBYeaoKRlbEwJDIm6uNO5wJOKMPqN5ZprFQFOZ6raYlY+
+hAhm0sQ2fac+EPyI4NSA5QC9qvNOBqN6avlicuMJT+ubDgEj8Z+7fNzcbBGXJbLy
+tGMU0gYqZ4yD9c7qB9iaah7s5Aq7KkzrCWA5zspi2C5u
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIEAzCCAuugAwIBAgIQVID5oHPtPwBMyonY43HmSjANBgkqhkiG9w0BAQUFADB1
+MQswCQYDVQQGEwJFRTEiMCAGA1UECgwZQVMgU2VydGlmaXRzZWVyaW1pc2tlc2t1
+czEoMCYGA1UEAwwfRUUgQ2VydGlmaWNhdGlvbiBDZW50cmUgUm9vdCBDQTEYMBYG
+CSqGSIb3DQEJARYJcGtpQHNrLmVlMCIYDzIwMTAxMDMwMTAxMDMwWhgPMjAzMDEy
+MTcyMzU5NTlaMHUxCzAJBgNVBAYTAkVFMSIwIAYDVQQKDBlBUyBTZXJ0aWZpdHNl
+ZXJpbWlza2Vza3VzMSgwJgYDVQQDDB9FRSBDZXJ0aWZpY2F0aW9uIENlbnRyZSBS
+b290IENBMRgwFgYJKoZIhvcNAQkBFglwa2lAc2suZWUwggEiMA0GCSqGSIb3DQEB
+AQUAA4IBDwAwggEKAoIBAQDIIMDs4MVLqwd4lfNE7vsLDP90jmG7sWLqI9iroWUy
+euuOF0+W2Ap7kaJjbMeMTC55v6kF/GlclY1i+blw7cNRfdCT5mzrMEvhvH2/UpvO
+bntl8jixwKIy72KyaOBhU8E2lf/slLo2rpwcpzIP5Xy0xm90/XsY6KxX7QYgSzIw
+WFv9zajmofxwvI6Sc9uXp3whrj3B9UiHbCe9nyV0gVWw93X2PaRka9ZP585ArQ/d
+MtO8ihJTmMmJ+xAdTX7Nfh9WDSFwhfYggx/2uh8Ej+p3iDXE/+pOoYtNP2MbRMNE
+1CV2yreN1x5KZmTNXMWcg+HCCIia7E6j8T4cLNlsHaFLAgMBAAGjgYowgYcwDwYD
+VR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFBLyWj7qVhy/
+zQas8fElyalL1BSZMEUGA1UdJQQ+MDwGCCsGAQUFBwMCBggrBgEFBQcDAQYIKwYB
+BQUHAwMGCCsGAQUFBwMEBggrBgEFBQcDCAYIKwYBBQUHAwkwDQYJKoZIhvcNAQEF
+BQADggEBAHv25MANqhlHt01Xo/6tu7Fq1Q+e2+RjxY6hUFaTlrg4wCQiZrxTFGGV
+v9DHKpY5P30osxBAIWrEr7BSdxjhlthWXePdNl4dp1BUoMUq5KqMlIpPnTX/dqQG
+E5Gion0ARD9V04I8GtVbvFZMIi5GQ4okQC3zErg7cBqklrkar4dBGmoYDQZPxz5u
+uSlNDUmJEYcyW+ZLBMjkXOZ0c5RdFpgTlf7727FE5TpwrDdr5rMzcijJs1eg9gIW
+iAYLtqZLICjU3j2LrTcFU3T+bsy8QxdxXvnFzBqpYe73dgzzcvRyrc9yAjYHR8/v
+GVCJYMzpJJUPwssd8m92kMfMdcGWxZ0=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIE0zCCA7ugAwIBAgIQGNrRniZ96LtKIVjNzGs7SjANBgkqhkiG9w0BAQUFADCB
+yjELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQL
+ExZWZXJpU2lnbiBUcnVzdCBOZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwNiBWZXJp
+U2lnbiwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5MUUwQwYDVQQDEzxW
+ZXJpU2lnbiBDbGFzcyAzIFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0
+aG9yaXR5IC0gRzUwHhcNMDYxMTA4MDAwMDAwWhcNMzYwNzE2MjM1OTU5WjCByjEL
+MAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQLExZW
+ZXJpU2lnbiBUcnVzdCBOZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwNiBWZXJpU2ln
+biwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5MUUwQwYDVQQDEzxWZXJp
+U2lnbiBDbGFzcyAzIFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9y
+aXR5IC0gRzUwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCvJAgIKXo1
+nmAMqudLO07cfLw8RRy7K+D+KQL5VwijZIUVJ/XxrcgxiV0i6CqqpkKzj/i5Vbex
+t0uz/o9+B1fs70PbZmIVYc9gDaTY3vjgw2IIPVQT60nKWVSFJuUrjxuf6/WhkcIz
+SdhDY2pSS9KP6HBRTdGJaXvHcPaz3BJ023tdS1bTlr8Vd6Gw9KIl8q8ckmcY5fQG
+BO+QueQA5N06tRn/Arr0PO7gi+s3i+z016zy9vA9r911kTMZHRxAy3QkGSGT2RT+
+rCpSx4/VBEnkjWNHiDxpg8v+R70rfk/Fla4OndTRQ8Bnc+MUCH7lP59zuDMKz10/
+NIeWiu5T6CUVAgMBAAGjgbIwga8wDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8E
+BAMCAQYwbQYIKwYBBQUHAQwEYTBfoV2gWzBZMFcwVRYJaW1hZ2UvZ2lmMCEwHzAH
+BgUrDgMCGgQUj+XTGoasjY5rw8+AatRIGCx7GS4wJRYjaHR0cDovL2xvZ28udmVy
+aXNpZ24uY29tL3ZzbG9nby5naWYwHQYDVR0OBBYEFH/TZafC3ey78DAJ80M5+gKv
+MzEzMA0GCSqGSIb3DQEBBQUAA4IBAQCTJEowX2LP2BqYLz3q3JktvXf2pXkiOOzE
+p6B4Eq1iDkVwZMXnl2YtmAl+X6/WzChl8gGqCBpH3vn5fJJaCGkgDdk+bW48DW7Y
+5gaRQBi5+MHt39tBquCWIMnNZBU4gcmU7qKEKQsTb47bDN0lAtukixlE0kF6BWlK
+WE9gyn6CagsCqiUXObXbf+eEZSqVir2G3l6BFoMtEMze/aiCKm0oHw0LxOXnGiYZ
+4fQRbxC1lfznQgUy286dUV4otp6F01vvpX1FQHKOtw5rDgb7MzVIcbidJ4vEZV8N
+hnacRHr2lVz2XTIIM6RUthg/aFzyQkqFOFSDX9HoLPKsEdao7WNq
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIDoDCCAoigAwIBAgIBMTANBgkqhkiG9w0BAQUFADBDMQswCQYDVQQGEwJKUDEc
+MBoGA1UEChMTSmFwYW5lc2UgR292ZXJubWVudDEWMBQGA1UECxMNQXBwbGljYXRp
+b25DQTAeFw0wNzEyMTIxNTAwMDBaFw0xNzEyMTIxNTAwMDBaMEMxCzAJBgNVBAYT
+AkpQMRwwGgYDVQQKExNKYXBhbmVzZSBHb3Zlcm5tZW50MRYwFAYDVQQLEw1BcHBs
+aWNhdGlvbkNBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAp23gdE6H
+j6UG3mii24aZS2QNcfAKBZuOquHMLtJqO8F6tJdhjYq+xpqcBrSGUeQ3DnR4fl+K
+f5Sk10cI/VBaVuRorChzoHvpfxiSQE8tnfWuREhzNgaeZCw7NCPbXCbkcXmP1G55
+IrmTwcrNwVbtiGrXoDkhBFcsovW8R0FPXjQilbUfKW1eSvNNcr5BViCH/OlQR9cw
+FO5cjFW6WY2H/CPek9AEjP3vbb3QesmlOmpyM8ZKDQUXKi17safY1vC+9D/qDiht
+QWEjdnjDuGWk81quzMKq2edY3rZ+nYVunyoKb58DKTCXKB28t89UKU5RMfkntigm
+/qJj5kEW8DOYRwIDAQABo4GeMIGbMB0GA1UdDgQWBBRUWssmP3HMlEYNllPqa0jQ
+k/5CdTAOBgNVHQ8BAf8EBAMCAQYwWQYDVR0RBFIwUKROMEwxCzAJBgNVBAYTAkpQ
+MRgwFgYDVQQKDA/ml6XmnKzlm73mlL/lupwxIzAhBgNVBAsMGuOCouODl+ODquOC
+seODvOOCt+ODp+ODs0NBMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEFBQAD
+ggEBADlqRHZ3ODrso2dGD/mLBqj7apAxzn7s2tGJfHrrLgy9mTLnsCTWw//1sogJ
+hyzjVOGjprIIC8CFqMjSnHH2HZ9g/DgzE+Ge3Atf2hZQKXsvcJEPmbo0NI2VdMV+
+eKlmXb3KIXdCEKxmJj3ekav9FfBv7WxfEPjzFvYDio+nEhEMy/0/ecGc/WLuo89U
+DNErXxc+4z6/wCs+CZv+iKZ+tJIX/COUgb1up8WMwusRRdv4QcmWdupwX3kSa+Sj
+B1oF7ydJzyGfikwJcGapJsErEU4z0g781mzSDjJkaP+tBXhfAx2o45CsJOAPQKdL
+rosot4LKGAfmt1t06SAZf7IbiVQ=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIDIDCCAgigAwIBAgIBJDANBgkqhkiG9w0BAQUFADA5MQswCQYDVQQGEwJGSTEP
+MA0GA1UEChMGU29uZXJhMRkwFwYDVQQDExBTb25lcmEgQ2xhc3MxIENBMB4XDTAx
+MDQwNjEwNDkxM1oXDTIxMDQwNjEwNDkxM1owOTELMAkGA1UEBhMCRkkxDzANBgNV
+BAoTBlNvbmVyYTEZMBcGA1UEAxMQU29uZXJhIENsYXNzMSBDQTCCASIwDQYJKoZI
+hvcNAQEBBQADggEPADCCAQoCggEBALWJHytPZwp5/8Ue+H887dF+2rDNbS82rDTG
+29lkFwhjMDMiikzujrsPDUJVyZ0upe/3p4zDq7mXy47vPxVnqIJyY1MPQYx9EJUk
+oVqlBvqSV536pQHydekfvFYmUk54GWVYVQNYwBSujHxVX3BbdyMGNpfzJLWaRpXk
+3w0LBUXl0fIdgrvGE+D+qnr9aTCU89JFhfzyMlsy3uhsXR/LpCJ0sICOXZT3BgBL
+qdReLjVQCfOAl/QMF6452F/NM8EcyonCIvdFEu1eEpOdY6uCLrnrQkFEy0oaAIIN
+nvmLVz5MxxftLItyM19yejhW1ebZrgUaHXVFsculJRwSVzb9IjcCAwEAAaMzMDEw
+DwYDVR0TAQH/BAUwAwEB/zARBgNVHQ4ECgQIR+IMi/ZTiFIwCwYDVR0PBAQDAgEG
+MA0GCSqGSIb3DQEBBQUAA4IBAQCLGrLJXWG04bkruVPRsoWdd44W7hE928Jj2VuX
+ZfsSZ9gqXLar5V7DtxYvyOirHYr9qxp81V9jz9yw3Xe5qObSIjiHBxTZ/75Wtf0H
+DjxVyhbMp6Z3N/vbXB9OWQaHowND9Rart4S9Tu+fMTfwRvFAttEMpWT4Y14h21VO
+TzF2nBBhjrZTOqMRvq9tfB69ri3iDGnHhVNoomG6xT60eVR4ngrHAr5i0RGCS2Uv
+kVrCqIexVmiUefkl98HVrhq4uz2PqYo4Ffdz0Fpg0YCw8NzVUM1O7pJIae2yIx4w
+zMiUyLb1O4Z/P6Yun/Y+LLWSlj7fLJOK/4GMDw9ZIRlXvVWa
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIDSjCCAjKgAwIBAgIQRK+wgNajJ7qJMDmGLvhAazANBgkqhkiG9w0BAQUFADA/
+MSQwIgYDVQQKExtEaWdpdGFsIFNpZ25hdHVyZSBUcnVzdCBDby4xFzAVBgNVBAMT
+DkRTVCBSb290IENBIFgzMB4XDTAwMDkzMDIxMTIxOVoXDTIxMDkzMDE0MDExNVow
+PzEkMCIGA1UEChMbRGlnaXRhbCBTaWduYXR1cmUgVHJ1c3QgQ28uMRcwFQYDVQQD
+Ew5EU1QgUm9vdCBDQSBYMzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB
+AN+v6ZdQCINXtMxiZfaQguzH0yxrMMpb7NnDfcdAwRgUi+DoM3ZJKuM/IUmTrE4O
+rz5Iy2Xu/NMhD2XSKtkyj4zl93ewEnu1lcCJo6m67XMuegwGMoOifooUMM0RoOEq
+OLl5CjH9UL2AZd+3UWODyOKIYepLYYHsUmu5ouJLGiifSKOeDNoJjj4XLh7dIN9b
+xiqKqy69cK3FCxolkHRyxXtqqzTWMIn/5WgTe1QLyNau7Fqckh49ZLOMxt+/yUFw
+7BZy1SbsOFU5Q9D8/RhcQPGX69Wam40dutolucbY38EVAjqr2m7xPi71XAicPNaD
+aeQQmxkqtilX4+U9m5/wAl0CAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNV
+HQ8BAf8EBAMCAQYwHQYDVR0OBBYEFMSnsaR7LHH62+FLkHX/xBVghYkQMA0GCSqG
+SIb3DQEBBQUAA4IBAQCjGiybFwBcqR7uKGY3Or+Dxz9LwwmglSBd49lZRNI+DT69
+ikugdB/OEIKcdBodfpga3csTS7MgROSR6cz8faXbauX+5v3gTt23ADq1cEmv8uXr
+AvHRAosZy5Q6XkjEGB5YGV8eAlrwDPGxrancWYaLbumR9YbK+rlmM6pZW87ipxZz
+R8srzJmwN0jP41ZL9c8PDHIyh8bwRLtTcm1D9SZImlJnt1ir/md2cXjbDaJWFBM5
+JDGFoqgCWjBH4d1QB7wCCZAA62RjYJsWvIjJEubSfZGL+T0yjWW06XyxV3bqxbYo
+Ob8VZRzI9neWagqNdwvYkQsEjgfbKbYK7p2CNTUQ
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIFGTCCBAGgAwIBAgIEPki9xDANBgkqhkiG9w0BAQUFADAxMQswCQYDVQQGEwJE
+SzEMMAoGA1UEChMDVERDMRQwEgYDVQQDEwtUREMgT0NFUyBDQTAeFw0wMzAyMTEw
+ODM5MzBaFw0zNzAyMTEwOTA5MzBaMDExCzAJBgNVBAYTAkRLMQwwCgYDVQQKEwNU
+REMxFDASBgNVBAMTC1REQyBPQ0VTIENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A
+MIIBCgKCAQEArGL2YSCyz8DGhdfjeebM7fI5kqSXLmSjhFuHnEz9pPPEXyG9VhDr
+2y5h7JNp46PMvZnDBfwGuMo2HP6QjklMxFaaL1a8z3sM8W9Hpg1DTeLpHTk0zY0s
+2RKY+ePhwUp8hjjEqcRhiNJerxomTdXkoCJHhNlktxmW/OwZ5LKXJk5KTMuPJItU
+GBxIYXvViGjaXbXqzRowwYCDdlCqT9HU3Tjw7xb04QxQBr/q+3pJoSgrHPb8FTKj
+dGqPqcNiKXEx5TukYBdedObaE+3pHx8b0bJoc8YQNHVGEBDjkAB2QMuLt0MJIf+r
+TpPGWOmlgtt3xDqZsXKVSQTwtyv6e1mO3QIDAQABo4ICNzCCAjMwDwYDVR0TAQH/
+BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwgewGA1UdIASB5DCB4TCB3gYIKoFQgSkB
+AQEwgdEwLwYIKwYBBQUHAgEWI2h0dHA6Ly93d3cuY2VydGlmaWthdC5kay9yZXBv
+c2l0b3J5MIGdBggrBgEFBQcCAjCBkDAKFgNUREMwAwIBARqBgUNlcnRpZmlrYXRl
+ciBmcmEgZGVubmUgQ0EgdWRzdGVkZXMgdW5kZXIgT0lEIDEuMi4yMDguMTY5LjEu
+MS4xLiBDZXJ0aWZpY2F0ZXMgZnJvbSB0aGlzIENBIGFyZSBpc3N1ZWQgdW5kZXIg
+T0lEIDEuMi4yMDguMTY5LjEuMS4xLjARBglghkgBhvhCAQEEBAMCAAcwgYEGA1Ud
+HwR6MHgwSKBGoESkQjBAMQswCQYDVQQGEwJESzEMMAoGA1UEChMDVERDMRQwEgYD
+VQQDEwtUREMgT0NFUyBDQTENMAsGA1UEAxMEQ1JMMTAsoCqgKIYmaHR0cDovL2Ny
+bC5vY2VzLmNlcnRpZmlrYXQuZGsvb2Nlcy5jcmwwKwYDVR0QBCQwIoAPMjAwMzAy
+MTEwODM5MzBagQ8yMDM3MDIxMTA5MDkzMFowHwYDVR0jBBgwFoAUYLWF7FZkfhIZ
+J2cdUBVLc647+RIwHQYDVR0OBBYEFGC1hexWZH4SGSdnHVAVS3OuO/kSMB0GCSqG
+SIb2fQdBAAQQMA4bCFY2LjA6NC4wAwIEkDANBgkqhkiG9w0BAQUFAAOCAQEACrom
+JkbTc6gJ82sLMJn9iuFXehHTuJTXCRBuo7E4A9G28kNBKWKnctj7fAXmMXAnVBhO
+inxO5dHKjHiIzxvTkIvmI/gLDjNDfZziChmPyQE+dF10yYscA+UYyAFMP8uXBV2Y
+caaYb7Z8vTd/vuGTJW1v8AqtFxjhA7wHKcitJuj4YfD9IQl+mo6paH1IYnK9AOoB
+mbgGglGBTvH1tJFUuSN6AJqfXY3gPGS5GhKSKseCRHI53OI8xthV9RVOyAUO28bQ
+YqbsFbS1AoLbrIyigfCbmTH1ICCoiGEKB5+U/NDXG8wuF/MEJ3Zn61SD/aSQfgY9
+BKNDLdr8C2LqL19iUw==
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIDYTCCAkmgAwIBAgIQCgEBAQAAAnwAAAAKAAAAAjANBgkqhkiG9w0BAQUFADA6
+MRkwFwYDVQQKExBSU0EgU2VjdXJpdHkgSW5jMR0wGwYDVQQLExRSU0EgU2VjdXJp
+dHkgMjA0OCBWMzAeFw0wMTAyMjIyMDM5MjNaFw0yNjAyMjIyMDM5MjNaMDoxGTAX
+BgNVBAoTEFJTQSBTZWN1cml0eSBJbmMxHTAbBgNVBAsTFFJTQSBTZWN1cml0eSAy
+MDQ4IFYzMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAt49VcdKA3Xtp
+eafwGFAyPGJn9gqVB93mG/Oe2dJBVGutn3y+Gc37RqtBaB4Y6lXIL5F4iSj7Jylg
+/9+PjDvJSZu1pJTOAeo+tWN7fyb9Gd3AIb2E0S1PRsNO3Ng3OTsor8udGuorryGl
+wSMiuLgbWhOHV4PR8CDn6E8jQrAApX2J6elhc5SYcSa8LWrg903w8bYqODGBDSnh
+AMFRD0xS+ARaqn1y07iHKrtjEAMqs6FPDVpeRrc9DvV07Jmf+T0kgYim3WBU6JU2
+PcYJk5qjEoAAVZkZR73QpXzDuvsf9/UP+Ky5tfQ3mBMY3oVbtwyCO4dvlTlYMNpu
+AWgXIszACwIDAQABo2MwYTAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIB
+BjAfBgNVHSMEGDAWgBQHw1EwpKrpRa41JPr/JCwz0LGdjDAdBgNVHQ4EFgQUB8NR
+MKSq6UWuNST6/yQsM9CxnYwwDQYJKoZIhvcNAQEFBQADggEBAF8+hnZuuDU8TjYc
+HnmYv/3VEhF5Ug7uMYm83X/50cYVIeiKAVQNOvtUudZj1LGqlk2iQk3UUx+LEN5/
+Zb5gEydxiKRz44Rj0aRV4VCT5hsOedBnvEbIvz8XDZXmxpBp3ue0L96VfdASPz0+
+f00/FGj1EVDVwfSQpQgdMWD/YIwjVAqv/qFuxdF6Kmh4zx6CCiC0H63lhbJqaHVO
+rSU3lIW+vaHU6rcMSzyd6BIA8F+sDeGscGNz9395nzIlQnQFgCi/vcEkllgVsRch
+6YlL2weIZ/QVrXA+L02FO8K32/6YaCOJ4XQP3vTFhGMpG8zLB8kApKnXwiJPZ9d3
+7CAFYd4=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIGFDCCA/ygAwIBAgIIU+w77vuySF8wDQYJKoZIhvcNAQEFBQAwUTELMAkGA1UE
+BhMCRVMxQjBABgNVBAMMOUF1dG9yaWRhZCBkZSBDZXJ0aWZpY2FjaW9uIEZpcm1h
+cHJvZmVzaW9uYWwgQ0lGIEE2MjYzNDA2ODAeFw0wOTA1MjAwODM4MTVaFw0zMDEy
+MzEwODM4MTVaMFExCzAJBgNVBAYTAkVTMUIwQAYDVQQDDDlBdXRvcmlkYWQgZGUg
+Q2VydGlmaWNhY2lvbiBGaXJtYXByb2Zlc2lvbmFsIENJRiBBNjI2MzQwNjgwggIi
+MA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDKlmuO6vj78aI14H9M2uDDUtd9
+thDIAl6zQyrET2qyyhxdKJp4ERppWVevtSBC5IsP5t9bpgOSL/UR5GLXMnE42QQM
+cas9UX4PB99jBVzpv5RvwSmCwLTaUbDBPLutN0pcyvFLNg4kq7/DhHf9qFD0sefG
+L9ItWY16Ck6WaVICqjaY7Pz6FIMMNx/Jkjd/14Et5cS54D40/mf0PmbR0/RAz15i
+NA9wBj4gGFrO93IbJWyTdBSTo3OxDqqHECNZXyAFGUftaI6SEspd/NYrspI8IM/h
+X68gvqB2f3bl7BqGYTM+53u0P6APjqK5am+5hyZvQWyIplD9amML9ZMWGxmPsu2b
+m8mQ9QEM3xk9Dz44I8kvjwzRAv4bVdZO0I08r0+k8/6vKtMFnXkIoctXMbScyJCy
+Z/QYFpM6/EfY0XiWMR+6KwxfXZmtY4laJCB22N/9q06mIqqdXuYnin1oKaPnirja
+EbsXLZmdEyRG98Xi2J+Of8ePdG1asuhy9azuJBCtLxTa/y2aRnFHvkLfuwHb9H/T
+KI8xWVvTyQKmtFLKbpf7Q8UIJm+K9Lv9nyiqDdVF8xM6HdjAeI9BZzwelGSuewvF
+6NkBiDkal4ZkQdU7hwxu+g/GvUgUvzlN1J5Bto+WHWOWk9mVBngxaJ43BjuAiUVh
+OSPHG0SjFeUc+JIwuwIDAQABo4HvMIHsMBIGA1UdEwEB/wQIMAYBAf8CAQEwDgYD
+VR0PAQH/BAQDAgEGMB0GA1UdDgQWBBRlzeurNR4APn7VdMActHNHDhpkLzCBpgYD
+VR0gBIGeMIGbMIGYBgRVHSAAMIGPMC8GCCsGAQUFBwIBFiNodHRwOi8vd3d3LmZp
+cm1hcHJvZmVzaW9uYWwuY29tL2NwczBcBggrBgEFBQcCAjBQHk4AUABhAHMAZQBv
+ACAAZABlACAAbABhACAAQgBvAG4AYQBuAG8AdgBhACAANAA3ACAAQgBhAHIAYwBl
+AGwAbwBuAGEAIAAwADgAMAAxADcwDQYJKoZIhvcNAQEFBQADggIBABd9oPm03cXF
+661LJLWhAqvdpYhKsg9VSytXjDvlMd3+xDLx51tkljYyGOylMnfX40S2wBEqgLk9
+am58m9Ot/MPWo+ZkKXzR4Tgegiv/J2Wv+xYVxC5xhOW1//qkR71kMrv2JYSiJ0L1
+ILDCExARzRAVukKQKtJE4ZYm6zFIEv0q2skGz3QeqUvVhyj5eTSSPi5E6PaPT481
+PyWzOdxjKpBrIF/EUhJOlywqrJ2X3kjyo2bbwtKDlaZmp54lD+kLM5FlClrD2VQS
+3a/DTg4fJl4N3LON7NWBcN7STyQF82xO9UxJZo3R/9ILJUFI/lGExkKvgATP0H5k
+SeTy36LssUzAKh3ntLFlosS88Zj0qnAHY7S42jtM+kAiMFsRpvAFDsYCA0irhpuF
+3dvd6qJ2gHN99ZwExEWN57kci57q13XRcrHedUTnQn3iV2t93Jm8PYMo6oCTjcVM
+ZcFwgbg4/EMxsvYDNEeyrPsiBsse3RdHHF9mudMaotoRsaS8I8nkvof/uZS2+F0g
+StRf571oe2XyFR7SOqkt6dhrJKyXWERHrVkY8SFlcN7ONGCoQPHzPKTDKCOM/icz
+Q0CgFzzr6juwcqajuUpLXhZI9LK8yIySxZ2frHI2vDSANGupi5LAuBft7HZT9SQB
+jLMi6Et8Vcad+qMUu2WFbm5PEn4KPJ2V
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIENjCCAx6gAwIBAgIBATANBgkqhkiG9w0BAQUFADBvMQswCQYDVQQGEwJTRTEU
+MBIGA1UEChMLQWRkVHJ1c3QgQUIxJjAkBgNVBAsTHUFkZFRydXN0IEV4dGVybmFs
+IFRUUCBOZXR3b3JrMSIwIAYDVQQDExlBZGRUcnVzdCBFeHRlcm5hbCBDQSBSb290
+MB4XDTAwMDUzMDEwNDgzOFoXDTIwMDUzMDEwNDgzOFowbzELMAkGA1UEBhMCU0Ux
+FDASBgNVBAoTC0FkZFRydXN0IEFCMSYwJAYDVQQLEx1BZGRUcnVzdCBFeHRlcm5h
+bCBUVFAgTmV0d29yazEiMCAGA1UEAxMZQWRkVHJ1c3QgRXh0ZXJuYWwgQ0EgUm9v
+dDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALf3GjPm8gAELTngTlvt
+H7xsD821+iO2zt6bETOXpClMfZOfvUq8k+0DGuOPz+VtUFrWlymUWoCwSXrbLpX9
+uMq/NzgtHj6RQa1wVsfwTz/oMp50ysiQVOnGXw94nZpAPA6sYapeFI+eh6FqUNzX
+mk6vBbOmcZSccbNQYArHE504B4YCqOmoaSYYkKtMsE8jqzpPhNjfzp/haW+710LX
+a0Tkx63ubUFfclpxCDezeWWkWaCUN/cALw3CknLa0Dhy2xSoRcRdKn23tNbE7qzN
+E0S3ySvdQwAl+mG5aWpYIxG3pzOPVnVZ9c0p10a3CitlttNCbxWyuHv77+ldU9U0
+WicCAwEAAaOB3DCB2TAdBgNVHQ4EFgQUrb2YejS0Jvf6xCZU7wO94CTLVBowCwYD
+VR0PBAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wgZkGA1UdIwSBkTCBjoAUrb2YejS0
+Jvf6xCZU7wO94CTLVBqhc6RxMG8xCzAJBgNVBAYTAlNFMRQwEgYDVQQKEwtBZGRU
+cnVzdCBBQjEmMCQGA1UECxMdQWRkVHJ1c3QgRXh0ZXJuYWwgVFRQIE5ldHdvcmsx
+IjAgBgNVBAMTGUFkZFRydXN0IEV4dGVybmFsIENBIFJvb3SCAQEwDQYJKoZIhvcN
+AQEFBQADggEBALCb4IUlwtYj4g+WBpKdQZic2YR5gdkeWxQHIzZlj7DYd7usQWxH
+YINRsPkyPef89iYTx4AWpb9a/IfPeHmJIZriTAcKhjW88t5RxNKWt9x+Tu5w/Rw5
+6wwCURQtjr0W4MHfRnXnJK3s9EK0hZNwEGe6nQY1ShjTK3rMUUKhemPR5ruhxSvC
+Nr4TDea9Y355e6cJDUCrat2PisP29owaQgVR1EX1n6diIWgVIEM8med8vSTYqZEX
+c4g/VhsxOBi0cQ+azcgOno4uG+GMmIPLHzHxREzGBHNJdmAPx/i9F4BrLunMTA5a
+mnkPIAou1Z5jJh5VkpTYghdae9C8x49OhgQ=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIICgjCCAeugAwIBAgIBBDANBgkqhkiG9w0BAQQFADBTMQswCQYDVQQGEwJVUzEc
+MBoGA1UEChMTRXF1aWZheCBTZWN1cmUgSW5jLjEmMCQGA1UEAxMdRXF1aWZheCBT
+ZWN1cmUgZUJ1c2luZXNzIENBLTEwHhcNOTkwNjIxMDQwMDAwWhcNMjAwNjIxMDQw
+MDAwWjBTMQswCQYDVQQGEwJVUzEcMBoGA1UEChMTRXF1aWZheCBTZWN1cmUgSW5j
+LjEmMCQGA1UEAxMdRXF1aWZheCBTZWN1cmUgZUJ1c2luZXNzIENBLTEwgZ8wDQYJ
+KoZIhvcNAQEBBQADgY0AMIGJAoGBAM4vGbwXt3fek6lfWg0XTzQaDJj0ItlZ1MRo
+RvC0NcWFAyDGr0WlIVFFQesWWDYyb+JQYmT5/VGcqiTZ9J2DKocKIdMSODRsjQBu
+WqDZQu4aIZX5UkxVWsUPOE9G+m34LjXWHXzr4vCwdYDIqROsvojvOm6rXyo4YgKw
+Env+j6YDAgMBAAGjZjBkMBEGCWCGSAGG+EIBAQQEAwIABzAPBgNVHRMBAf8EBTAD
+AQH/MB8GA1UdIwQYMBaAFEp4MlIR21kWNl7fwRQ2QGpHfEyhMB0GA1UdDgQWBBRK
+eDJSEdtZFjZe38EUNkBqR3xMoTANBgkqhkiG9w0BAQQFAAOBgQB1W6ibAxHm6VZM
+zfmpTMANmvPMZWnmJXbMWbfWVMMdzZmsGd20hdXgPfxiIKeES1hl8eL5lSE/9dR+
+WB5Hh1Q+WKG1tfgq73HnvMP2sUlG4tega+VWeponmHxGYhTnyfxuAxJ5gDgdSIKN
+/Bf+KpYrtWKmpj29f5JZzVoqgrI3eQ==
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIDuzCCAqOgAwIBAgIDBETAMA0GCSqGSIb3DQEBBQUAMH4xCzAJBgNVBAYTAlBM
+MSIwIAYDVQQKExlVbml6ZXRvIFRlY2hub2xvZ2llcyBTLkEuMScwJQYDVQQLEx5D
+ZXJ0dW0gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkxIjAgBgNVBAMTGUNlcnR1bSBU
+cnVzdGVkIE5ldHdvcmsgQ0EwHhcNMDgxMDIyMTIwNzM3WhcNMjkxMjMxMTIwNzM3
+WjB+MQswCQYDVQQGEwJQTDEiMCAGA1UEChMZVW5pemV0byBUZWNobm9sb2dpZXMg
+Uy5BLjEnMCUGA1UECxMeQ2VydHVtIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MSIw
+IAYDVQQDExlDZXJ0dW0gVHJ1c3RlZCBOZXR3b3JrIENBMIIBIjANBgkqhkiG9w0B
+AQEFAAOCAQ8AMIIBCgKCAQEA4/t9o3K6wvDJFIf1awFO4W5AB7ptJ11/91sts1rH
+UV+rpDKmYYe2bg+G0jACl/jXaVehGDldamR5xgFZrDwxSjh80gTSSyjoIF87B6LM
+TXPb865Px1bVWqeWifrzq2jUI4ZZJ88JJ7ysbnKDHDBy3+Ci6dLhdHUZvSqeexVU
+BBvXQzmtVSjF4hq79MDkrjhJM8x2hZ85RdKknvISjFH4fOQtf/WsX+sWn7Et0brM
+kUJ3TCXJkDhv2/DM+44el1k+1WBO5gUo7Ul5E0u6SNsv+XLTOcr+H9g0cvW0QM8x
+AcPs3hEtF10fuFDRXhmnad4HMyjKUJX5p1TLVIZQRan5SQIDAQABo0IwQDAPBgNV
+HRMBAf8EBTADAQH/MB0GA1UdDgQWBBQIds3LB/8k9sXN7buQvOKEN0Z19zAOBgNV
+HQ8BAf8EBAMCAQYwDQYJKoZIhvcNAQEFBQADggEBAKaorSLOAT2mo/9i0Eidi15y
+sHhE49wcrwn9I0j6vSrEuVUEtRCjjSfeC4Jj0O7eDDd5QVsisrCaQVymcODU0HfL
+I9MA4GxWL+FpDQ3Zqr8hgVDZBqWo/5U30Kr+4rP1mS1FhIrlQgnXdAIv94nYmem8
+J9RHjboNRhx3zxSkHLmkMcScKHQDNP8zGSal6Q10tz6XxnboJ5ajZt3hrvJBW8qY
+VoNzcOSGGtIxQbovvi0TWnZvTuhOgQ4/WwMioBK+ZlgRSssDxLQqKi2WF+A5VLxI
+03YnnZotBqbJ7DnSq9ufmgsnAjUpsUCV5/nonFWIGUbWtzT1fs45mtk48VH3Tyw=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIDxTCCAq2gAwIBAgIBADANBgkqhkiG9w0BAQsFADCBgzELMAkGA1UEBhMCVVMx
+EDAOBgNVBAgTB0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxGjAYBgNVBAoT
+EUdvRGFkZHkuY29tLCBJbmMuMTEwLwYDVQQDEyhHbyBEYWRkeSBSb290IENlcnRp
+ZmljYXRlIEF1dGhvcml0eSAtIEcyMB4XDTA5MDkwMTAwMDAwMFoXDTM3MTIzMTIz
+NTk1OVowgYMxCzAJBgNVBAYTAlVTMRAwDgYDVQQIEwdBcml6b25hMRMwEQYDVQQH
+EwpTY290dHNkYWxlMRowGAYDVQQKExFHb0RhZGR5LmNvbSwgSW5jLjExMC8GA1UE
+AxMoR28gRGFkZHkgUm9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkgLSBHMjCCASIw
+DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAL9xYgjx+lk09xvJGKP3gElY6SKD
+E6bFIEMBO4Tx5oVJnyfq9oQbTqC023CYxzIBsQU+B07u9PpPL1kwIuerGVZr4oAH
+/PMWdYA5UXvl+TW2dE6pjYIT5LY/qQOD+qK+ihVqf94Lw7YZFAXK6sOoBJQ7Rnwy
+DfMAZiLIjWltNowRGLfTshxgtDj6AozO091GB94KPutdfMh8+7ArU6SSYmlRJQVh
+GkSBjCypQ5Yj36w6gZoOKcUcqeldHraenjAKOc7xiID7S13MMuyFYkMlNAJWJwGR
+tDtwKj9useiciAF9n9T521NtYJ2/LOdYq7hfRvzOxBsDPAnrSTFcaUaz4EcCAwEA
+AaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYE
+FDqahQcQZyi27/a9BUFuIMGU2g/eMA0GCSqGSIb3DQEBCwUAA4IBAQCZ21151fmX
+WWcDYfF+OwYxdS2hII5PZYe096acvNjpL9DbWu7PdIxztDhC2gV7+AJ1uP2lsdeu
+9tfeE8tTEH6KRtGX+rcuKxGrkLAngPnon1rpN5+r5N9ss4UXnT3ZJE95kTXWXwTr
+gIOrmgIttRD02JDHBHNA7XIloKmf7J6raBKZV8aPEjoJpL1E/QYVN8Gb5DKj7Tjo
+2GTzLH4U/ALqn83/B2gX2yKQOC16jdFU8WnjXzPKej17CuPKf1855eJ1usV2GDPO
+LPAvTK33sefOT6jEm0pUBsV/fdUID+Ic/n4XuKxe9tQWskMJDE32p2u0mYRlynqI
+4uJEvlz36hz1
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIFkjCCA3qgAwIBAgIBATANBgkqhkiG9w0BAQsFADBaMQswCQYDVQQGEwJGUjET
+MBEGA1UEChMKQ2VydGlub21pczEXMBUGA1UECxMOMDAwMiA0MzM5OTg5MDMxHTAb
+BgNVBAMTFENlcnRpbm9taXMgLSBSb290IENBMB4XDTEzMTAyMTA5MTcxOFoXDTMz
+MTAyMTA5MTcxOFowWjELMAkGA1UEBhMCRlIxEzARBgNVBAoTCkNlcnRpbm9taXMx
+FzAVBgNVBAsTDjAwMDIgNDMzOTk4OTAzMR0wGwYDVQQDExRDZXJ0aW5vbWlzIC0g
+Um9vdCBDQTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBANTMCQosP5L2
+fxSeC5yaah1AMGT9qt8OHgZbn1CF6s2Nq0Nn3rD6foCWnoR4kkjW4znuzuRZWJfl
+LieY6pOod5tK8O90gC3rMB+12ceAnGInkYjwSond3IjmFPnVAy//ldu9n+ws+hQV
+WZUKxkd8aRi5pwP5ynapz8dvtF4F/u7BUrJ1Mofs7SlmO/NKFoL21prbcpjp3vDF
+TKWrteoB4owuZH9kb/2jJZOLyKIOSY008B/sWEUuNKqEUL3nskoTuLAPrjhdsKkb
+5nPJWqHZZkCqqU2mNAKthH6yI8H7KsZn9DS2sJVqM09xRLWtwHkziOC/7aOgFLSc
+CbAK42C++PhmiM1b8XcF4LVzbsF9Ri6OSyemzTUK/eVNfaoqoynHWmgE6OXWk6Ri
+wsXm9E/G+Z8ajYJJGYrKWUM66A0ywfRMEwNvbqY/kXPLynNvEiCL7sCCeN5LLsJJ
+wx3tFvYk9CcbXFcx3FXuqB5vbKziRcxXV4p1VxngtViZSTYxPDMBbRZKzbgqg4SG
+m/lg0h9tkQPTYKbVPZrdd5A9NaSfD171UkRpucC63M9933zZxKyGIjK8e2uR73r4
+F2iw4lNVYC2vPsKD2NkJK/DAZNuHi5HMkesE/Xa0lZrmFAYb1TQdvtj/dBxThZng
+WVJKYe2InmtJiUZ+IFrZ50rlau7SZRFDAgMBAAGjYzBhMA4GA1UdDwEB/wQEAwIB
+BjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBTvkUz1pcMw6C8I6tNxIqSSaHh0
+2TAfBgNVHSMEGDAWgBTvkUz1pcMw6C8I6tNxIqSSaHh02TANBgkqhkiG9w0BAQsF
+AAOCAgEAfj1U2iJdGlg+O1QnurrMyOMaauo++RLrVl89UM7g6kgmJs95Vn6RHJk/
+0KGRHCwPT5iVWVO90CLYiF2cN/z7ZMF4jIuaYAnq1fohX9B0ZedQxb8uuQsLrbWw
+F6YSjNRieOpWauwK0kDDPAUwPk2Ut59KA9N9J0u2/kTO+hkzGm2kQtHdzMjI1xZS
+g081lLMSVX3l4kLr5JyTCcBMWwerx20RoFAXlCOotQqSD7J6wWAsOMwaplv/8gzj
+qh8c3LigkyfeY+N/IZ865Z764BNqdeuWXGKRlI5nU7aJ+BIJy29SWwNyhlCVCNSN
+h4YVH5Uk2KRvms6knZtt0rJ2BobGVgjF6wnaNsIbW0G+YSrjcOa4pvi2WsS9Iff/
+ql+hbHY5ZtbqTFXhADObE5hjyW/QASAJN1LnDE8+zbz1X5YnpyACleAu6AdBBR8V
+btaw5BngDwKTACdyxYvRVB9dSsNAl35VpnzBMwQUAR1JIGkLGZOdblgi90AMRgwj
+Y/M50n92Uaf0yKHxDHYiI0ZSKS3io0EHVmmY0gUJvGnHWmHNj4FgFU2A3ZDifcRQ
+8ow7bkrHxuaAKzyBvBGAFhAn1/DNP3nMcyrDflOR1m749fPH0FFNjkulW+YZFzvW
+gQncItzujrnEj1PhZ7szuIgVRs/taTX/dQ1G885x4cVrhkIGuUE=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIFujCCBKKgAwIBAgIBATANBgkqhkiG9w0BAQUFADCBhjELMAkGA1UEBhMCVVMx
+HTAbBgNVBAoTFEFwcGxlIENvbXB1dGVyLCBJbmMuMS0wKwYDVQQLEyRBcHBsZSBD
+b21wdXRlciBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkxKTAnBgNVBAMTIEFwcGxlIFJv
+b3QgQ2VydGlmaWNhdGUgQXV0aG9yaXR5MB4XDTA1MDIxMDAwMTgxNFoXDTI1MDIx
+MDAwMTgxNFowgYYxCzAJBgNVBAYTAlVTMR0wGwYDVQQKExRBcHBsZSBDb21wdXRl
+ciwgSW5jLjEtMCsGA1UECxMkQXBwbGUgQ29tcHV0ZXIgQ2VydGlmaWNhdGUgQXV0
+aG9yaXR5MSkwJwYDVQQDEyBBcHBsZSBSb290IENlcnRpZmljYXRlIEF1dGhvcml0
+eTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAOSRqQkfkdseR1DrBe1e
+eYQt6zaiV0xV7IsZid75S2z1B6siMALoGD74UAnTf0GomPnRymacJGsR0KO75Bsq
+wx+VnnoMpEeLW9QWNzPLxA9NzhRp0ckZcvVdDtV/X5vyJQO6VY9NXQ3xZDUjFUsV
+WR2zlPf2nJ7PULrBWFBnjwi0IPfLrCwgb3C2PwEwjLdDzw+dPfMrSSgayP7OtbkO
+2V4c1ss9tTqt9A8OAJILsSEWLnTVPA3bYharo3GSR1NVwa8vQbP4++NwzeajTEV+
+H0xrUJZBicR0YgsQg0GHM4qBsTBY7FoEMoxos48d3mVz/2deZbxJ2HafMxRloXeU
+yS0CAwEAAaOCAi8wggIrMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/
+MB0GA1UdDgQWBBQr0GlHlHYJ/vRrjS5ApvdHTX8IXjAfBgNVHSMEGDAWgBQr0GlH
+lHYJ/vRrjS5ApvdHTX8IXjCCASkGA1UdIASCASAwggEcMIIBGAYJKoZIhvdjZAUB
+MIIBCTBBBggrBgEFBQcCARY1aHR0cHM6Ly93d3cuYXBwbGUuY29tL2NlcnRpZmlj
+YXRlYXV0aG9yaXR5L3Rlcm1zLmh0bWwwgcMGCCsGAQUFBwICMIG2GoGzUmVsaWFu
+Y2Ugb24gdGhpcyBjZXJ0aWZpY2F0ZSBieSBhbnkgcGFydHkgYXNzdW1lcyBhY2Nl
+cHRhbmNlIG9mIHRoZSB0aGVuIGFwcGxpY2FibGUgc3RhbmRhcmQgdGVybXMgYW5k
+IGNvbmRpdGlvbnMgb2YgdXNlLCBjZXJ0aWZpY2F0ZSBwb2xpY3kgYW5kIGNlcnRp
+ZmljYXRpb24gcHJhY3RpY2Ugc3RhdGVtZW50cy4wRAYDVR0fBD0wOzA5oDegNYYz
+aHR0cHM6Ly93d3cuYXBwbGUuY29tL2NlcnRpZmljYXRlYXV0aG9yaXR5L3Jvb3Qu
+Y3JsMFUGCCsGAQUFBwEBBEkwRzBFBggrBgEFBQcwAoY5aHR0cHM6Ly93d3cuYXBw
+bGUuY29tL2NlcnRpZmljYXRlYXV0aG9yaXR5L2Nhc2lnbmVycy5odG1sMA0GCSqG
+SIb3DQEBBQUAA4IBAQCd2i0oWC99dgS5BNM+zrdmY06PL9T+S61yvaM5xlJNBZhS
+9YlRASR5vhoy9+VEi0tEBzmC1lrKtCBe2a4VXR2MHTK/ODFiSF3H4ZCx+CRA+F9Y
+m1FdV53B5f88zHIhbsTp6aF31ywXJsM/65roCwO66bNKcuszCVut5mIxauivL9Wv
+Hld2j383LS4CXN1jyfJxuCZA3xWNdUQ/eb3mHZnhQyw+rW++uaT+DjUZUWOxw961
+kj5ReAFziqQjyqSI8R5cH0EWLX6VCqrpiUGYGxrdyyC/R14MJsVVNU3GMIuZZxTH
+CR+6R8faAQmHJEKVvRNgGQrv6n8Obs3BREM6StXj
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIGZjCCBE6gAwIBAgIPB35Sk3vgFeNX8GmMy+wMMA0GCSqGSIb3DQEBBQUAMHsx
+CzAJBgNVBAYTAkNPMUcwRQYDVQQKDD5Tb2NpZWRhZCBDYW1lcmFsIGRlIENlcnRp
+ZmljYWNpw7NuIERpZ2l0YWwgLSBDZXJ0aWPDoW1hcmEgUy5BLjEjMCEGA1UEAwwa
+QUMgUmHDrXogQ2VydGljw6FtYXJhIFMuQS4wHhcNMDYxMTI3MjA0NjI5WhcNMzAw
+NDAyMjE0MjAyWjB7MQswCQYDVQQGEwJDTzFHMEUGA1UECgw+U29jaWVkYWQgQ2Ft
+ZXJhbCBkZSBDZXJ0aWZpY2FjacOzbiBEaWdpdGFsIC0gQ2VydGljw6FtYXJhIFMu
+QS4xIzAhBgNVBAMMGkFDIFJhw616IENlcnRpY8OhbWFyYSBTLkEuMIICIjANBgkq
+hkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAq2uJo1PMSCMI+8PPUZYILrgIem08kBeG
+qentLhM0R7LQcNzJPNCNyu5LF6vQhbCnIwTLqKL85XXbQMpiiY9QngE9JlsYhBzL
+fDe3fezTf3MZsGqy2IiKLUV0qPezuMDU2s0iiXRNWhU5cxh0T7XrmafBHoi0wpOQ
+Y5fzp6cSsgkiBzPZkc0OnB8OIMfuuzONj8LSWKdf/WU34ojC2I+GdV75LaeHM/J4
+Ny+LvB2GNzmxlPLYvEqcgxhaBvzz1NS6jBUJJfD5to0EfhcSM2tXSExP2yYe68yQ
+54v5aHxwD6Mq0Do43zeX4lvegGHTgNiRg0JaTASJaBE8rF9ogEHMYELODVoqDA+b
+MMCm8Ibbq0nXl21Ii/kDwFJnmxL3wvIumGVC2daa49AZMQyth9VXAnow6IYm+48j
+ilSH5L887uvDdUhfHjlvgWJsxS3EF1QZtzeNnDeRyPYL1epjb4OsOMLzP96a++Ej
+YfDIJss2yKHzMI+ko6Kh3VOz3vCaMh+DkXkwwakfU5tTohVTP92dsxA7SH2JD/zt
+A/X7JWR1DhcZDY8AFmd5ekD8LVkH2ZD6mq093ICK5lw1omdMEWux+IBkAC1vImHF
+rEsm5VoQgpukg3s0956JkSCXjrdCx2bD0Omk1vUgjcTDlaxECp1bczwmPS9KvqfJ
+pxAe+59QafMCAwEAAaOB5jCB4zAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQE
+AwIBBjAdBgNVHQ4EFgQU0QnQ6dfOeXRU+Tows/RtLAMDG2gwgaAGA1UdIASBmDCB
+lTCBkgYEVR0gADCBiTArBggrBgEFBQcCARYfaHR0cDovL3d3dy5jZXJ0aWNhbWFy
+YS5jb20vZHBjLzBaBggrBgEFBQcCAjBOGkxMaW1pdGFjaW9uZXMgZGUgZ2FyYW50
+7WFzIGRlIGVzdGUgY2VydGlmaWNhZG8gc2UgcHVlZGVuIGVuY29udHJhciBlbiBs
+YSBEUEMuMA0GCSqGSIb3DQEBBQUAA4ICAQBclLW4RZFNjmEfAygPU3zmpFmps4p6
+xbD/CHwso3EcIRNnoZUSQDWDg4902zNc8El2CoFS3UnUmjIz75uny3XlesuXEpBc
+unvFm9+7OSPI/5jOCk0iAUgHforA1SBClETvv3eiiWdIG0ADBaGJ7M9i4z0ldma/
+Jre7Ir5v/zlXdLp6yQGVwZVR6Kss+LGGIOk/yzVb0hfpKv6DExdA7ohiZVvVO2Dp
+ezy4ydV/NgIlqmjCMRW3MGXrfx1IebHPOeJCgBbT9ZMj/EyXyVo3bHwi2ErN0o42
+gzmRkBDI8ck1fj+404HGIGQatlDCIaR43NAvO2STdPCWkPHv+wlaNECW8DYSwaN0
+jJN+Qd53i+yG2dIPPy3RzECiiWZIHiCznCNZc6lEc7wkeZBWN7PGKX6jD/EpOe9+
+XCgycDWs2rjIdWb8m0w5R44bb5tNAlQiM+9hup4phO9OSzNHdpdqy35f/RWmnkJD
+W2ZaiogN9xa5P1FlK2Zqi9E4UqLWRhH6/JocdJ6PlwsCT2TG9WjTSy3/pDceiz+/
+RL5hRqGEPQgnTIEgd4kI6mdAXmwIUV80WoyWaM3X94nCHNMyAK9Sy9NgWyo6R35r
+MDOhYil/SrnhLecUIw4OGEfhefwVVdCx/CVxY3UzHCMrr1zZ7Ud3YA47Dx7SwNxk
+BYn8eNZcLCZDqQ==
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIDUzCCAjugAwIBAgIBATANBgkqhkiG9w0BAQUFADBLMQswCQYDVQQGEwJOTzEd
+MBsGA1UECgwUQnV5cGFzcyBBUy05ODMxNjMzMjcxHTAbBgNVBAMMFEJ1eXBhc3Mg
+Q2xhc3MgMiBDQSAxMB4XDTA2MTAxMzEwMjUwOVoXDTE2MTAxMzEwMjUwOVowSzEL
+MAkGA1UEBhMCTk8xHTAbBgNVBAoMFEJ1eXBhc3MgQVMtOTgzMTYzMzI3MR0wGwYD
+VQQDDBRCdXlwYXNzIENsYXNzIDIgQ0EgMTCCASIwDQYJKoZIhvcNAQEBBQADggEP
+ADCCAQoCggEBAIs8B0XY9t/mx8q6jUPFR42wWsE425KEHK8T1A9vNkYgxC7McXA0
+ojTTNy7Y3Tp3L8DrKehc0rWpkTSHIln+zNvnma+WwajHQN2lFYxuyHyXA8vmIPLX
+l18xoS830r7uvqmtqEyeIWZDO6i88wmjONVZJMHCR3axiFyCO7srpgTXjAePzdVB
+HfCuuCkslFJgNJQ72uA40Z0zPhX0kzLFANq1KWYOOngPIVJfAuWSeyXTkh4vFZ2B
+5J2O6O+JzhRMVB0cgRJNcKi+EAUXfh/RuFdV7c27UsKwHnjCTTZoy1YmwVLBvXb3
+WNVyfh9EdrsAiR0WnVE1703CVu9r4Iw7DekCAwEAAaNCMEAwDwYDVR0TAQH/BAUw
+AwEB/zAdBgNVHQ4EFgQUP42aWYv8e3uco684sDntkHGA1sgwDgYDVR0PAQH/BAQD
+AgEGMA0GCSqGSIb3DQEBBQUAA4IBAQAVGn4TirnoB6NLJzKyQJHyIdFkhb5jatLP
+gcIV1Xp+DCmsNx4cfHZSldq1fyOhKXdlyTKdqC5Wq2B2zha0jX94wNWZUYN/Xtm+
+DKhQ7SLHrQVMdvvt7h5HZPb3J31cKA9FxVxiXqaakZG3Uxcu3K1gnZZkOb1naLKu
+BctN518fV4bVIJwo+28TOPX2EZL2fZleHwzoq0QkKXJAPTZSr4xYkHPB7GEseaHs
+h7U/2k3ZIQAw3pDaDtMaSKk+hQsUi4y8QZ5q9w5wwDX3OaJdZtB7WZ+oRxKaJyOk
+LY4ng5IgodcVf/EuGO70SH8vf/GhGLWhC5SgYiAynB321O+/TIho
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIFnDCCA4SgAwIBAgIBATANBgkqhkiG9w0BAQUFADBjMQswCQYDVQQGEwJGUjET
+MBEGA1UEChMKQ2VydGlub21pczEXMBUGA1UECxMOMDAwMiA0MzM5OTg5MDMxJjAk
+BgNVBAMMHUNlcnRpbm9taXMgLSBBdXRvcml0w6kgUmFjaW5lMB4XDTA4MDkxNzA4
+Mjg1OVoXDTI4MDkxNzA4Mjg1OVowYzELMAkGA1UEBhMCRlIxEzARBgNVBAoTCkNl
+cnRpbm9taXMxFzAVBgNVBAsTDjAwMDIgNDMzOTk4OTAzMSYwJAYDVQQDDB1DZXJ0
+aW5vbWlzIC0gQXV0b3JpdMOpIFJhY2luZTCCAiIwDQYJKoZIhvcNAQEBBQADggIP
+ADCCAgoCggIBAJ2Fn4bT46/HsmtuM+Cet0I0VZ35gb5j2CN2DpdUzZlMGvE5x4jY
+F1AMnmHawE5V3udauHpOd4cN5bjr+p5eex7Ezyh0x5P1FMYiKAT5kcOrJ3NqDi5N
+8y4oH3DfVS9O7cdxbwlyLu3VMpfQ8Vh30WC8Tl7bmoT2R2FFK/ZQpn9qcSdIhDWe
+rP5pqZ56XjUl+rSnSTV3lqc2W+HN3yNw2F1MpQiD8aYkOBOo7C+ooWfHpi2GR+6K
+/OybDnT0K0kCe5B1jPyZOQE51kqJ5Z52qz6WKDgmi92NjMD2AR5vpTESOH2VwnHu
+7XSu5DaiQ3XV8QCb4uTXzEIDS3h65X27uK4uIJPT5GHfceF2Z5c/tt9qc1pkIuVC
+28+BA5PY9OMQ4HL2AHCs8MF6DwV/zzRpRbWT5BnbUhYjBYkOjUjkJW+zeL9i9Qf6
+lSTClrLooyPCXQP8w9PlfMl1I9f09bze5N/NgL+RiH2nE7Q5uiy6vdFrzPOlKO1E
+nn1So2+WLhl+HPNbxxaOu2B9d2ZHVIIAEWBsMsGoOBvrbpgT1u449fCfDu/+MYHB
+0iSVL1N6aaLwD4ZFjliCK0wi1F6g530mJ0jfJUaNSih8hp75mxpZuWW/Bd22Ql09
+5gBIgl4g9xGC3srYn+Y3RyYe63j3YcNBZFgCQfna4NH4+ej9Uji29YnfAgMBAAGj
+WzBZMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBQN
+jLZh2kS40RR9w759XkjwzspqsDAXBgNVHSAEEDAOMAwGCiqBegFWAgIAAQEwDQYJ
+KoZIhvcNAQEFBQADggIBACQ+YAZ+He86PtvqrxyaLAEL9MW12Ukx9F1BjYkMTv9s
+ov3/4gbIOZ/xWqndIlgVqIrTseYyCYIDbNc/CMf4uboAbbnW/FIyXaR/pDGUu7ZM
+OH8oMDX/nyNTt7buFHAAQCvaR6s0fl6nVjBhK4tDrP22iCj1a7Y+YEq6QpA0Z43q
+619FVDsXrIvkxmUP7tCMXWY5zjKn2BCXwH40nJ+U8/aGH88bc62UeYdocMMzpXDn
+2NU4lG9jeeu/Cg4I58UvD0KgKxRA/yHgBcUn4YQRE7rWhh1BCxMjidPJC+iKunqj
+o3M3NYB9Ergzd0A4wPpeMNLytqOx1qKVl4GbUu1pTP+A5FPbVFsDbVRfsbjvJL1v
+nxHDx2TCDyhihWZeGnuyt++uNckZM6i4J9szVb9o4XVIRFb7zdNIu0eJOqxp9YDG
+5ERQL1TEqkPFMTFYvZbF6nVsmnWxTfj3l/+WFvKXTej28xH5On2KOG4Ey+HTRRWq
+pdEdnV1j6CTmNhTih60bWfVEm/vXd3wfAXBioSAaosUaKPQhA+4u2cGA6rnZgtZb
+dsLLO7XSAPCjDuGtbkD326C00EauFddEwk01+dIL8hf2rGbVJLJP0RyZwG71fet0
+BLj5TXcJ17TPBzAJ8bgAVtkXFhYKK4bfjwEZGuW7gmP/vgt2Fl43N+bYdJeimUV5
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIDODCCAiCgAwIBAgIGIAYFFnACMA0GCSqGSIb3DQEBBQUAMDsxCzAJBgNVBAYT
+AlJPMREwDwYDVQQKEwhjZXJ0U0lHTjEZMBcGA1UECxMQY2VydFNJR04gUk9PVCBD
+QTAeFw0wNjA3MDQxNzIwMDRaFw0zMTA3MDQxNzIwMDRaMDsxCzAJBgNVBAYTAlJP
+MREwDwYDVQQKEwhjZXJ0U0lHTjEZMBcGA1UECxMQY2VydFNJR04gUk9PVCBDQTCC
+ASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALczuX7IJUqOtdu0KBuqV5Do
+0SLTZLrTk+jUrIZhQGpgV2hUhE28alQCBf/fm5oqrl0Hj0rDKH/v+yv6efHHrfAQ
+UySQi2bJqIirr1qjAOm+ukbuW3N7LBeCgV5iLKECZbO9xSsAfsT8AzNXDe3i+s5d
+RdY4zTW2ssHQnIFKquSyAVwdj1+ZxLGt24gh65AIgoDzMKND5pCCrlUoSe1b16kQ
+OA7+j0xbm0bqQfWwCHTD0IgztnzXdN/chNFDDnU5oSVAKOp4yw4sLjmdjItuFhwv
+JoIQ4uNllAoEwF73XVv4EOLQunpL+943AAAaWyjj0pxzPjKHmKHJUS/X3qwzs08C
+AwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAcYwHQYDVR0O
+BBYEFOCMm9slSbPxfIbWskKHC9BroNnkMA0GCSqGSIb3DQEBBQUAA4IBAQA+0hyJ
+LjX8+HXd5n9liPRyTMks1zJO890ZeUe9jjtbkw9QSSQTaxQGcu8J06Gh40CEyecY
+MnQ8SG4Pn0vU9x7Tk4ZkVJdjclDVVc/6IJMCopvDI5NOFlV2oHB5bc0hH88vLbwZ
+44gx+FkagQnIl6Z0x2DEW8xXjrJ1/RsCCdtZb3KTafcxQdaIOL+Hsr0Wefmq5L6I
+Jd1hJyMctTEHBDa0GpC9oHRxUIltvBTjD4au8as+x6AJzKNI0eDbZOeStc+vckNw
+i/nDhDwTqn6Sm1dTk/pwwpEOMfmbZ13pljheX7NzTogVZ96edhBiIL5VaZVDADlN
+9u6wWk5JRFRYX0KD
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIGnTCCBIWgAwIBAgICBcYwDQYJKoZIhvcNAQEFBQAwRTELMAkGA1UEBhMCQk0x
+GTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxGzAZBgNVBAMTElF1b1ZhZGlzIFJv
+b3QgQ0EgMzAeFw0wNjExMjQxOTExMjNaFw0zMTExMjQxOTA2NDRaMEUxCzAJBgNV
+BAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBMaW1pdGVkMRswGQYDVQQDExJRdW9W
+YWRpcyBSb290IENBIDMwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDM
+V0IWVJzmmNPTTe7+7cefQzlKZbPoFog02w1ZkXTPkrgEQK0CSzGrvI2RaNggDhoB
+4hp7Thdd4oq3P5kazethq8Jlph+3t723j/z9cI8LoGe+AaJZz3HmDyl2/7FWeUUr
+H556VOijKTVopAFPD6QuN+8bv+OPEKhyq1hX51SGyMnzW9os2l2ObjyjPtr7guXd
+8lyyBTNvijbO0BNO/79KDDRMpsMhvVAEVeuxu537RR5kFd5VAYwCdrXLoT9Cabwv
+vWhDFlaJKjdhkf2mrk7AyxRllDdLkgbvBNDInIjbC3uBr7E9KsRlOni27tyAsdLT
+mZw67mtaa7ONt9XOnMK+pUsvFrGeaDsGb659n/je7Mwpp5ijJUMv7/FfJuGITfhe
+btfZFG4ZM2mnO4SJk8RTVROhUXhA+LjJou57ulJCg54U7QVSWllWp5f8nT8KKdjc
+T5EOE7zelaTfi5m+rJsziO+1ga8bxiJTyPbH7pcUsMV8eFLI8M5ud2CEpukqdiDt
+WAEXMJPpGovgc2PZapKUSU60rUqFxKMiMPwJ7Wgic6aIDFUhWMXhOp8q3crhkODZ
+c6tsgLjoC2SToJyMGf+z0gzskSaHirOi4XCPLArlzW1oUevaPwV/izLmE1xr/l9A
+4iLItLRkT9a6fUg+qGkM17uGcclzuD87nSVL2v9A6wIDAQABo4IBlTCCAZEwDwYD
+VR0TAQH/BAUwAwEB/zCB4QYDVR0gBIHZMIHWMIHTBgkrBgEEAb5YAAMwgcUwgZMG
+CCsGAQUFBwICMIGGGoGDQW55IHVzZSBvZiB0aGlzIENlcnRpZmljYXRlIGNvbnN0
+aXR1dGVzIGFjY2VwdGFuY2Ugb2YgdGhlIFF1b1ZhZGlzIFJvb3QgQ0EgMyBDZXJ0
+aWZpY2F0ZSBQb2xpY3kgLyBDZXJ0aWZpY2F0aW9uIFByYWN0aWNlIFN0YXRlbWVu
+dC4wLQYIKwYBBQUHAgEWIWh0dHA6Ly93d3cucXVvdmFkaXNnbG9iYWwuY29tL2Nw
+czALBgNVHQ8EBAMCAQYwHQYDVR0OBBYEFPLAE+CCQz777i9nMpY1XNu4ywLQMG4G
+A1UdIwRnMGWAFPLAE+CCQz777i9nMpY1XNu4ywLQoUmkRzBFMQswCQYDVQQGEwJC
+TTEZMBcGA1UEChMQUXVvVmFkaXMgTGltaXRlZDEbMBkGA1UEAxMSUXVvVmFkaXMg
+Um9vdCBDQSAzggIFxjANBgkqhkiG9w0BAQUFAAOCAgEAT62gLEz6wPJv92ZVqyM0
+7ucp2sNbtrCD2dDQ4iH782CnO11gUyeim/YIIirnv6By5ZwkajGxkHon24QRiSem
+d1o417+shvzuXYO8BsbRd2sPbSQvS3pspweWyuOEn62Iix2rFo1bZhfZFvSLgNLd
++LJ2w/w4E6oM3kJpK27zPOuAJ9v1pkQNn1pVWQvVDVJIxa6f8i+AxeoyUDUSly7B
+4f/xI4hROJ/yZlZ25w9Rl6VSDE1JUZU2Pb+iSwwQHYaZTKrzchGT5Or2m9qoXadN
+t54CrnMAyNojA+j56hl0YgCUyyIgvpSnWbWCar6ZeXqp8kokUvd0/bpO5qgdAm6x
+DYBEwa7TIzdfu4V8K5Iu6H6li92Z4b8nby1dqnuH/grdS/yO9SbkbnBCbjPsMZ57
+k8HkyWkaPcBrTiJt7qtYTcbQQcEr6k8Sh17rRdhs9ZgC06DYVYoGmRmioHfRMJ6s
+zHXug/WwYjnPbFfiTNKRCw51KBuav/0aQ/HKd/s7j2G4aSgWQgRecCocIdiP4b0j
+Wy10QJLZYxkNc91pvGJHvOB0K7Lrfb5BG7XARsWhIstfTsEokt4YutUqKLsRixeT
+mJlglFwjz1onl14LBQaTNx47aTbrqZ5hHY8y2o4M1nQ+ewkk2gF3R8Q7zTSMmfXK
+4SVhM7JZG+Ju1zdXtg2pEto=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIDVTCCAj2gAwIBAgIESTMAATANBgkqhkiG9w0BAQUFADAyMQswCQYDVQQGEwJD
+TjEOMAwGA1UEChMFQ05OSUMxEzARBgNVBAMTCkNOTklDIFJPT1QwHhcNMDcwNDE2
+MDcwOTE0WhcNMjcwNDE2MDcwOTE0WjAyMQswCQYDVQQGEwJDTjEOMAwGA1UEChMF
+Q05OSUMxEzARBgNVBAMTCkNOTklDIFJPT1QwggEiMA0GCSqGSIb3DQEBAQUAA4IB
+DwAwggEKAoIBAQDTNfc/c3et6FtzF8LRb+1VvG7q6KR5smzDo+/hn7E7SIX1mlwh
+IhAsxYLO2uOabjfhhyzcuQxauohV3/2q2x8x6gHx3zkBwRP9SFIhxFXf2tizVHa6
+dLG3fdfA6PZZxU3Iva0fFNrfWEQlMhkqx35+jq44sDB7R3IJMfAw28Mbdim7aXZO
+V/kbZKKTVrdvmW7bCgScEeOAH8tjlBAKqeFkgjH5jCftppkA9nCTGPihNIaj3XrC
+GHn2emU1z5DrvTOTn1OrczvmmzQgLx3vqR1jGqCA2wMv+SYahtKNu6m+UjqHZ0gN
+v7Sg2Ca+I19zN38m5pIEo3/PIKe38zrKy5nLAgMBAAGjczBxMBEGCWCGSAGG+EIB
+AQQEAwIABzAfBgNVHSMEGDAWgBRl8jGtKvf33VKWCscCwQ7vptU7ETAPBgNVHRMB
+Af8EBTADAQH/MAsGA1UdDwQEAwIB/jAdBgNVHQ4EFgQUZfIxrSr3991SlgrHAsEO
+76bVOxEwDQYJKoZIhvcNAQEFBQADggEBAEs17szkrr/Dbq2flTtLP1se31cpolnK
+OOK5Gv+e5m4y3R6u6jW39ZORTtpC4cMXYFDy0VwmuYK36m3knITnA3kXr5g9lNvH
+ugDnuL8BV8F3RTIMO/G0HAiw/VGgod2aHRM2mm23xzy54cXZF/qD1T0VoDy7Hgvi
+yJA/qIYM/PmLXoXLT1tLYhFHxUV8BS9BsZ4QaRuZluBVeftOhpm4lNqGOGqTo+fL
+buXf6iFViZx9fX+Y9QCJ7uOEwFyWtcVG6kbghVW2G8kS1sHNzYDzAgE8yGnLRUhj
+2JTQ7IUOO04RZfSCjKY9ri4ilAnIXOo8gV0WKgOXFlUJ24pBgp5mmxE=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIDVDCCAjygAwIBAgIDAjRWMA0GCSqGSIb3DQEBBQUAMEIxCzAJBgNVBAYTAlVT
+MRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMRswGQYDVQQDExJHZW9UcnVzdCBHbG9i
+YWwgQ0EwHhcNMDIwNTIxMDQwMDAwWhcNMjIwNTIxMDQwMDAwWjBCMQswCQYDVQQG
+EwJVUzEWMBQGA1UEChMNR2VvVHJ1c3QgSW5jLjEbMBkGA1UEAxMSR2VvVHJ1c3Qg
+R2xvYmFsIENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA2swYYzD9
+9BcjGlZ+W988bDjkcbd4kdS8odhM+KhDtgPpTSEHCIjaWC9mOSm9BXiLnTjoBbdq
+fnGk5sRgprDvgOSJKA+eJdbtg/OtppHHmMlCGDUUna2YRpIuT8rxh0PBFpVXLVDv
+iS2Aelet8u5fa9IAjbkU+BQVNdnARqN7csiRv8lVK83Qlz6cJmTM386DGXHKTubU
+1XupGc1V3sjs0l44U+VcT4wt/lAjNvxm5suOpDkZALeVAjmRCw7+OC7RHQWa9k0+
+bw8HHa8sHo9gOeL6NlMTOdReJivbPagUvTLrGAMoUgRx5aszPeE4uwc2hGKceeoW
+MPRfwCvocWvk+QIDAQABo1MwUTAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBTA
+ephojYn7qwVkDBF9qn1luMrMTjAfBgNVHSMEGDAWgBTAephojYn7qwVkDBF9qn1l
+uMrMTjANBgkqhkiG9w0BAQUFAAOCAQEANeMpauUvXVSOKVCUn5kaFOSPeCpilKIn
+Z57QzxpeR+nBsqTP3UEaBU6bS+5Kb1VSsyShNwrrZHYqLizz/Tt1kL/6cdjHPTfS
+tQWVYrmm3ok9Nns4d0iXrKYgjy6myQzCsplFAMfOEVEiIuCl6rYVSAlk6l5PdPcF
+PseKUgzbFbS9bZvlxrFUaKnjaZC2mqUPuLk/IH2uSrW4nOQdtqvmlKXBx4Ot2/Un
+hw4EbNX/3aBd7YdStysVAq45pmp06drE57xNNB6pXE0zX5IJL4hmXXeXxx12E6nV
+5fEWCRE11azbJHFwLJhWC9kXtNHjUStedejV0NxPNO3CBWaAocvmMw==
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIDyzCCArOgAwIBAgIDAOJIMA0GCSqGSIb3DQEBBQUAMIGLMQswCQYDVQQGEwJB
+VDFIMEYGA1UECgw/QS1UcnVzdCBHZXMuIGYuIFNpY2hlcmhlaXRzc3lzdGVtZSBp
+bSBlbGVrdHIuIERhdGVudmVya2VociBHbWJIMRgwFgYDVQQLDA9BLVRydXN0LVF1
+YWwtMDIxGDAWBgNVBAMMD0EtVHJ1c3QtUXVhbC0wMjAeFw0wNDEyMDIyMzAwMDBa
+Fw0xNDEyMDIyMzAwMDBaMIGLMQswCQYDVQQGEwJBVDFIMEYGA1UECgw/QS1UcnVz
+dCBHZXMuIGYuIFNpY2hlcmhlaXRzc3lzdGVtZSBpbSBlbGVrdHIuIERhdGVudmVy
+a2VociBHbWJIMRgwFgYDVQQLDA9BLVRydXN0LVF1YWwtMDIxGDAWBgNVBAMMD0Et
+VHJ1c3QtUXVhbC0wMjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAJaR
+q9eOsFm4Ab20Hq2Z/aH86gyWa48uSUjY6eQkguHYuszr3gdcSMYZggFHQgnhfLmf
+ro/27l5rqKhWiDhWs+b+yZ1PNDhRPJy+86ycHMg9XJqErveULBSyZDdgjhSwOyrN
+ibUir/fkf+4sKzP5jjytTKJXD/uCxY4fAd9TjMEVpN3umpIS0ijpYhclYDHvzzGU
+833z5Dwhq5D8bc9jp8YSAHFJ1xzIoO1jmn3jjyjdYPnY5harJtHQL73nDQnfbtTs
+5ThT9GQLulrMgLU4WeyAWWWEMWpfVZFMJOUkmoOEer6A8e5fIAeqdxdsC+JVqpZ4
+CAKel/Arrlj1gFA//jsCAwEAAaM2MDQwDwYDVR0TAQH/BAUwAwEB/zARBgNVHQ4E
+CgQIQj0rJKbBRc4wDgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3DQEBBQUAA4IBAQBG
+yxFjUA2bPkXUSC2SfJ29tmrbiLKal+g6a9M8Xwd+Ejo+oYkNP6F4GfeDtAXpm7xb
+9Ly8lhdbHcpRhzCUQHJ1tBCiGdLgmhSx7TXjhhanKOdDgkdsC1T+++piuuYL72TD
+gUy2Sb1GHlJ1Nc6rvB4fpxSDAOHqGpUq9LWsc3tFkXqRqmQVtqtR77npKIFBioc6
+2jTBwDMPX3hDJDR1DSPc6BnZliaNw2IHdiMQ0mBoYeRnFdq+TyDKsjmJOOQPLzzL
+/saaw6F891+gBjLFEFquDyR73lAPJS279R3csi8WWk4ZYUC/1V8H3Ktip/J6ac8e
+qhLCbmJ81Lo92JGHz/ot
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIDdzCCAl+gAwIBAgIEAgAAuTANBgkqhkiG9w0BAQUFADBaMQswCQYDVQQGEwJJ
+RTESMBAGA1UEChMJQmFsdGltb3JlMRMwEQYDVQQLEwpDeWJlclRydXN0MSIwIAYD
+VQQDExlCYWx0aW1vcmUgQ3liZXJUcnVzdCBSb290MB4XDTAwMDUxMjE4NDYwMFoX
+DTI1MDUxMjIzNTkwMFowWjELMAkGA1UEBhMCSUUxEjAQBgNVBAoTCUJhbHRpbW9y
+ZTETMBEGA1UECxMKQ3liZXJUcnVzdDEiMCAGA1UEAxMZQmFsdGltb3JlIEN5YmVy
+VHJ1c3QgUm9vdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKMEuyKr
+mD1X6CZymrV51Cni4eiVgLGw41uOKymaZN+hXe2wCQVt2yguzmKiYv60iNoS6zjr
+IZ3AQSsBUnuId9Mcj8e6uYi1agnnc+gRQKfRzMpijS3ljwumUNKoUMMo6vWrJYeK
+mpYcqWe4PwzV9/lSEy/CG9VwcPCPwBLKBsua4dnKM3p31vjsufFoREJIE9LAwqSu
+XmD+tqYF/LTdB1kC1FkYmGP1pWPgkAx9XbIGevOF6uvUA65ehD5f/xXtabz5OTZy
+dc93Uk3zyZAsuT3lySNTPx8kmCFcB5kpvcY67Oduhjprl3RjM71oGDHweI12v/ye
+jl0qhqdNkNwnGjkCAwEAAaNFMEMwHQYDVR0OBBYEFOWdWTCCR1jMrPoIVDaGezq1
+BE3wMBIGA1UdEwEB/wQIMAYBAf8CAQMwDgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3
+DQEBBQUAA4IBAQCFDF2O5G9RaEIFoN27TyclhAO992T9Ldcw46QQF+vaKSm2eT92
+9hkTI7gQCvlYpNRhcL0EYWoSihfVCr3FvDB81ukMJY2GQE/szKN+OMY3EU/t3Wgx
+jkzSswF07r51XgdIGn9w/xZchMB5hbgF/X++ZRGjD8ACtPhSNzkE1akxehi/oCr0
+Epn3o0WC4zxe9Z2etciefC7IpJ5OCBRLbf1wbWsaY71k5h+3zvDyny67G7fyUIhz
+ksLi4xaNmjICq44Y3ekQEe5+NauQrz4wlHrQMz2nZQ/1/I6eYs9HRCwBXbsdtTLS
+R9I4LtD+gdwyah617jzV/OeBHRnDJELqYzmp
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIEkTCCA3mgAwIBAgIERWtQVDANBgkqhkiG9w0BAQUFADCBsDELMAkGA1UEBhMC
+VVMxFjAUBgNVBAoTDUVudHJ1c3QsIEluYy4xOTA3BgNVBAsTMHd3dy5lbnRydXN0
+Lm5ldC9DUFMgaXMgaW5jb3Jwb3JhdGVkIGJ5IHJlZmVyZW5jZTEfMB0GA1UECxMW
+KGMpIDIwMDYgRW50cnVzdCwgSW5jLjEtMCsGA1UEAxMkRW50cnVzdCBSb290IENl
+cnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTA2MTEyNzIwMjM0MloXDTI2MTEyNzIw
+NTM0MlowgbAxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1FbnRydXN0LCBJbmMuMTkw
+NwYDVQQLEzB3d3cuZW50cnVzdC5uZXQvQ1BTIGlzIGluY29ycG9yYXRlZCBieSBy
+ZWZlcmVuY2UxHzAdBgNVBAsTFihjKSAyMDA2IEVudHJ1c3QsIEluYy4xLTArBgNV
+BAMTJEVudHJ1c3QgUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTCCASIwDQYJ
+KoZIhvcNAQEBBQADggEPADCCAQoCggEBALaVtkNC+sZtKm9I35RMOVcF7sN5EUFo
+Nu3s/poBj6E4KPz3EEZmLk0eGrEaTsbRwJWIsMn/MYszA9u3g3s+IIRe7bJWKKf4
+4LlAcTfFy0cOlypowCKVYhXbR9n10Cv/gkvJrT7eTNuQgFA/CYqEAOwwCj0Yzfv9
+KlmaI5UXLEWeH25DeW0MXJj+SKfFI0dcXv1u5x609mhF0YaDW6KKjbHjKYD+JXGI
+rb68j6xSlkuqUY3kEzEZ6E5Nn9uss2rVvDlUccp6en+Q3X0dgNmBu1kmwhH+5pPi
+94DkZfs0Nw4pgHBNrziGLp5/V6+eF67rHMsoIV+2HNjnogQi+dPa2MsCAwEAAaOB
+sDCBrTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zArBgNVHRAEJDAi
+gA8yMDA2MTEyNzIwMjM0MlqBDzIwMjYxMTI3MjA1MzQyWjAfBgNVHSMEGDAWgBRo
+kORnpKZTgMeGZqTx90tD+4S9bTAdBgNVHQ4EFgQUaJDkZ6SmU4DHhmak8fdLQ/uE
+vW0wHQYJKoZIhvZ9B0EABBAwDhsIVjcuMTo0LjADAgSQMA0GCSqGSIb3DQEBBQUA
+A4IBAQCT1DCw1wMgKtD5Y+iRDAUgqV8ZyntyTtSx29CW+1RaGSwMCPeyvIWonX9t
+O1KzKtvn1ISMY/YPyyYBkVBs9F8U4pN0wBOeMDpQ47RgxRzwIkSNcUesyBrJ6Zua
+AGAT/3B+XxFNSRuzFVJ7yVTav52Vr2ua2J7p8eRDjeIRRDq/r72DQnNSi6q7pynP
+9WQcCk3RvKqsnyrQ/39/2n3qse0wJcGE2jTSW3iDVuycNsMm4hH2Z0kdkquM++v/
+eu6FSqdQgPCnXEqULl8FmTxSQeDNtGPPAUO6nIPcj2A781q0tHuu2guQOHXvgR1m
+0vdXcDazv/wor3ElhVsT/h5/WrQ8
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIICpzCCAi2gAwIBAgIQTHm1miicdjFk9YlE0JEC3jAKBggqhkjOPQQDAzCBlDEL
+MAkGA1UEBhMCVVMxHTAbBgNVBAoTFFN5bWFudGVjIENvcnBvcmF0aW9uMR8wHQYD
+VQQLExZTeW1hbnRlYyBUcnVzdCBOZXR3b3JrMUUwQwYDVQQDEzxTeW1hbnRlYyBD
+bGFzcyAzIFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IC0g
+RzQwHhcNMTIxMDE4MDAwMDAwWhcNMzcxMjAxMjM1OTU5WjCBlDELMAkGA1UEBhMC
+VVMxHTAbBgNVBAoTFFN5bWFudGVjIENvcnBvcmF0aW9uMR8wHQYDVQQLExZTeW1h
+bnRlYyBUcnVzdCBOZXR3b3JrMUUwQwYDVQQDEzxTeW1hbnRlYyBDbGFzcyAzIFB1
+YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IC0gRzQwdjAQBgcq
+hkjOPQIBBgUrgQQAIgNiAARXz+qzOU0/oSHgbi84csaHl/OFC0fnD1HI0fSZm8pZ
+Zf9M+eoLtyXV0vbsMS0yYhLXdoan+jjJZdT+c+KEOfhMSWIT3brViKBfPchPsD+P
+oVAR5JNGrcNfy/GkapVW6MCjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8E
+BTADAQH/MB0GA1UdDgQWBBQknbzScfcdwiW+IvGJpSwVOzQeXjAKBggqhkjOPQQD
+AwNoADBlAjEAuWZoZdsF0Dh9DvPIdWG40CjEsUozUVj78jwQyK5HeHbKZiQXhj5Q
+Vm6lLZmIuL0kAjAD6qfnqDzqnWLGX1TamPR3vU+PGJyRXEdrQE0QHbPhicoLIsga
+xcX+i93B3294n5E=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIDxTCCAq2gAwIBAgIQAqxcJmoLQJuPC3nyrkYldzANBgkqhkiG9w0BAQUFADBs
+MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3
+d3cuZGlnaWNlcnQuY29tMSswKQYDVQQDEyJEaWdpQ2VydCBIaWdoIEFzc3VyYW5j
+ZSBFViBSb290IENBMB4XDTA2MTExMDAwMDAwMFoXDTMxMTExMDAwMDAwMFowbDEL
+MAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQd3d3
+LmRpZ2ljZXJ0LmNvbTErMCkGA1UEAxMiRGlnaUNlcnQgSGlnaCBBc3N1cmFuY2Ug
+RVYgUm9vdCBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMbM5XPm
++9S75S0tMqbf5YE/yc0lSbZxKsPVlDRnogocsF9ppkCxxLeyj9CYpKlBWTrT3JTW
+PNt0OKRKzE0lgvdKpVMSOO7zSW1xkX5jtqumX8OkhPhPYlG++MXs2ziS4wblCJEM
+xChBVfvLWokVfnHoNb9Ncgk9vjo4UFt3MRuNs8ckRZqnrG0AFFoEt7oT61EKmEFB
+Ik5lYYeBQVCmeVyJ3hlKV9Uu5l0cUyx+mM0aBhakaHPQNAQTXKFx01p8VdteZOE3
+hzBWBOURtCmAEvF5OYiiAhF8J2a3iLd48soKqDirCmTCv2ZdlYTBoSUeh10aUAsg
+EsxBu24LUTi4S8sCAwEAAaNjMGEwDgYDVR0PAQH/BAQDAgGGMA8GA1UdEwEB/wQF
+MAMBAf8wHQYDVR0OBBYEFLE+w2kD+L9HAdSYJhoIAu9jZCvDMB8GA1UdIwQYMBaA
+FLE+w2kD+L9HAdSYJhoIAu9jZCvDMA0GCSqGSIb3DQEBBQUAA4IBAQAcGgaX3Nec
+nzyIZgYIVyHbIUf4KmeqvxgydkAQV8GK83rZEWWONfqe/EW1ntlMMUu4kehDLI6z
+eM7b41N5cdblIZQB2lWHmiRk9opmzN6cN82oNLFpmyPInngiK3BD41VHMWEZ71jF
+hS9OMPagMRYjyOfiZRYzy78aG6A9+MpeizGLYAiJLQwGXFK3xPkKmNEVX58Svnw2
+Yzi9RKR/5CYrCsSXaQ3pjOLAEFe4yHYSkVXySGnYvCoCWw9E1CAx2/S6cCZdkGCe
+vEsXCS+0yx5DaMkHJ8HSXPfqIbloEpw8nL+e/IBcm2PN7EeqJSdnoDfzAIJ9VNep
++OkuE6N36B9K
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIGHDCCBASgAwIBAgIES45gAzANBgkqhkiG9w0BAQsFADBFMQswCQYDVQQGEwJE
+SzESMBAGA1UEChMJVFJVU1QyNDA4MSIwIAYDVQQDExlUUlVTVDI0MDggT0NFUyBQ
+cmltYXJ5IENBMB4XDTEwMDMwMzEyNDEzNFoXDTM3MTIwMzEzMTEzNFowRTELMAkG
+A1UEBhMCREsxEjAQBgNVBAoTCVRSVVNUMjQwODEiMCAGA1UEAxMZVFJVU1QyNDA4
+IE9DRVMgUHJpbWFyeSBDQTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIB
+AJlJodr3U1Fa+v8HnyACHV81/wLevLS0KUk58VIABl6Wfs3LLNoj5soVAZv4LBi5
+gs7E8CZ9w0F2CopW8vzM8i5HLKE4eedPdnaFqHiBZ0q5aaaQArW+qKJx1rT/AaXt
+alMB63/yvJcYlXS2lpexk5H/zDBUXeEQyvfmK+slAySWT6wKxIPDwVapauFY9QaG
++VBhCa5jBstWS7A5gQfEvYqn6csZ3jW472kW6OFNz6ftBcTwufomGJBMkonf4ZLr
+6t0AdRi9jflBPz3MNNRGxyjIuAmFqGocYFA/OODBRjvSHB2DygqQ8k+9tlpvzMRr
+kU7jq3RKL+83G1dJ3/LTjCLz4ryEMIC/OJ/gNZfE0qXddpPtzflIPtUFVffXdbFV
+1t6XZFhJ+wBHQCpJobq/BjqLWUA86upsDbfwnePtmIPRCemeXkY0qabC+2Qmd2Fe
+xyZphwTyMnbqy6FG1tB65dYf3mOqStmLa3RcHn9+2dwNfUkh0tjO2FXD7drWcU0O
+I9DW8oAypiPhm/QCjMU6j6t+0pzqJ/S0tdAo+BeiXK5hwk6aR+sRb608QfBbRAs3
+U/q8jSPByenggac2BtTN6cl+AA1Mfcgl8iXWNFVGegzd/VS9vINClJCe3FNVoUnR
+YCKkj+x0fqxvBLopOkJkmuZw/yhgMxljUi2qYYGn90OzAgMBAAGjggESMIIBDjAP
+BgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjARBgNVHSAECjAIMAYGBFUd
+IAAwgZcGA1UdHwSBjzCBjDAsoCqgKIYmaHR0cDovL2NybC5vY2VzLnRydXN0MjQw
+OC5jb20vb2Nlcy5jcmwwXKBaoFikVjBUMQswCQYDVQQGEwJESzESMBAGA1UEChMJ
+VFJVU1QyNDA4MSIwIAYDVQQDExlUUlVTVDI0MDggT0NFUyBQcmltYXJ5IENBMQ0w
+CwYDVQQDEwRDUkwxMB8GA1UdIwQYMBaAFPZt+LFIs0FDAduGROUYBbdezAY3MB0G
+A1UdDgQWBBT2bfixSLNBQwHbhkTlGAW3XswGNzANBgkqhkiG9w0BAQsFAAOCAgEA
+VPAQGrT7dIjD3/sIbQW86f9CBPu0c7JKN6oUoRUtKqgJ2KCdcB5ANhCoyznHpu3m
+/dUfVUI5hc31CaPgZyY37hch1q4/c9INcELGZVE/FWfehkH+acpdNr7j8UoRZlkN
+15b/0UUBfGeiiJG/ugo4llfoPrp8bUmXEGggK3wyqIPcJatPtHwlb6ympfC2b/Ld
+v/0IdIOzIOm+A89Q0utx+1cOBq72OHy8gpGb6MfncVFMoL2fjP652Ypgtr8qN9Ka
+/XOazktiIf+2Pzp7hLi92hRc9QMYexrV/nnFSQoWdU8TqULFUoZ3zTEC3F/g2yj+
+FhbrgXHGo5/A4O74X+lpbY2XV47aSuw+DzcPt/EhMj2of7SA55WSgbjPMbmNX0rb
+oenSIte2HRFW5Tr2W+qqkc/StixgkKdyzGLoFx/xeTWdJkZKwyjqge2wJqws2upY
+EiThhC497+/mTiSuXd69eVUwKyqYp9SD2rTtNmF6TCghRM/dNsJOl+osxDVGcwvt
+WIVFF/Onlu5fu1NHXdqNEfzldKDUvCfii3L2iATTZyHwU9CALE+2eIA+PIaLgnM1
+1oCfUnYBkQurTrihvzz9PryCVkLxiqRmBVvUz+D4N5G/wvvKDS6t6cPCS+hqM482
+cbBsn0R9fFLO4El62S9eH1tqOzO20OAOK65yJIsOpSE=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIDWjCCAkKgAwIBAgIBADANBgkqhkiG9w0BAQUFADBQMQswCQYDVQQGEwJKUDEY
+MBYGA1UEChMPU0VDT00gVHJ1c3QubmV0MScwJQYDVQQLEx5TZWN1cml0eSBDb21t
+dW5pY2F0aW9uIFJvb3RDQTEwHhcNMDMwOTMwMDQyMDQ5WhcNMjMwOTMwMDQyMDQ5
+WjBQMQswCQYDVQQGEwJKUDEYMBYGA1UEChMPU0VDT00gVHJ1c3QubmV0MScwJQYD
+VQQLEx5TZWN1cml0eSBDb21tdW5pY2F0aW9uIFJvb3RDQTEwggEiMA0GCSqGSIb3
+DQEBAQUAA4IBDwAwggEKAoIBAQCzs/5/022x7xZ8V6UMbXaKL0u/ZPtM7orw8yl8
+9f/uKuDp6bpbZCKamm8sOiZpUQWZJtzVHGpxxpp9Hp3dfGzGjGdnSj74cbAZJ6kJ
+DKaVv0uMDPpVmDvY6CKhS3E4eayXkmmziX7qIWgGmBSWh9JhNrxtJ1aeV+7AwFb9
+Ms+k2Y7CI9eNqPPYJayX5HA49LY6tJ07lyZDo6G8SVlyTCMwhwFY9k6+HGhWZq/N
+QV3Is00qVUarH9oe4kA92819uZKAnDfdDJZkndwi92SL32HeFZRSFaB9UslLqCHJ
+xrHty8OVYNEP8Ktw+N/LTX7s1vqr2b1/VPKl6Xn62dZ2JChzAgMBAAGjPzA9MB0G
+A1UdDgQWBBSgc0mZaNyFW2XjmygvV5+9M7wHSDALBgNVHQ8EBAMCAQYwDwYDVR0T
+AQH/BAUwAwEB/zANBgkqhkiG9w0BAQUFAAOCAQEAaECpqLvkT115swW1F7NgE+vG
+kl3g0dNq/vu+m22/xwVtWSDEHPC32oRYAmP6SBbvT6UL90qY8j+eG61Ha2POCEfr
+Uj94nK9NrvjVT8+amCoQQTlSxN3Zmw7vkwGusi7KaEIkQmywszo+zenaSMQVy+n5
+Bw+SUEmK3TGXX8npN6o7WWWXlDLJs58+OmJYxUmtYg5xpTKqL8aJdkNAExNnPaJU
+JRDL8Try2frbSVa7pv6nQTXD4IhhyYjH3zYQIphZ6rBK+1YWc26sTfcioU+tHXot
+RSflMMFe8toTyyVCUZVHA4xsIcx0Qu1T/zOLjw9XARYvz6buyXAiFL39vmwLAw==
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIICkDCCAfmgAwIBAgIBATANBgkqhkiG9w0BAQQFADBaMQswCQYDVQQGEwJVUzEc
+MBoGA1UEChMTRXF1aWZheCBTZWN1cmUgSW5jLjEtMCsGA1UEAxMkRXF1aWZheCBT
+ZWN1cmUgR2xvYmFsIGVCdXNpbmVzcyBDQS0xMB4XDTk5MDYyMTA0MDAwMFoXDTIw
+MDYyMTA0MDAwMFowWjELMAkGA1UEBhMCVVMxHDAaBgNVBAoTE0VxdWlmYXggU2Vj
+dXJlIEluYy4xLTArBgNVBAMTJEVxdWlmYXggU2VjdXJlIEdsb2JhbCBlQnVzaW5l
+c3MgQ0EtMTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAuucXkAJlsTRVPEnC
+UdXfp9E3j9HngXNBUmCbnaEXJnitx7HoJpQytd4zjTov2/KaelpzmKNc6fuKcxtc
+58O/gGzNqfTWK8D3+ZmqY6KxRwIP1ORROhI8bIpaVIRw28HFkM9yRcuoWcDNM50/
+o5brhTMhHD4ePmBudpxnhcXIw2ECAwEAAaNmMGQwEQYJYIZIAYb4QgEBBAQDAgAH
+MA8GA1UdEwEB/wQFMAMBAf8wHwYDVR0jBBgwFoAUvqigdHJQa0S3ySPY+6j/s1dr
+aGwwHQYDVR0OBBYEFL6ooHRyUGtEt8kj2Puo/7NXa2hsMA0GCSqGSIb3DQEBBAUA
+A4GBADDiAVGqx+pf2rnQZQ8w1j7aDRRJbpGTJxQx78T3LUX47Me/okENI7SS+RkA
+Z70Br83gcfxaz2TE4JaY0KNA4gGK7ycH8WUBikQtBmV1UsCGECAhX2xrD2yuCRyv
+8qIYNMR1pHMc8Y3c7635s3a0kr/clRAevsvIO1qEYBlWlKlV
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIF5zCCA8+gAwIBAgIITK9zQhyOdAIwDQYJKoZIhvcNAQEFBQAwgYAxODA2BgNV
+BAMML0VCRyBFbGVrdHJvbmlrIFNlcnRpZmlrYSBIaXptZXQgU2HEn2xhecSxY8Sx
+c8SxMTcwNQYDVQQKDC5FQkcgQmlsacWfaW0gVGVrbm9sb2ppbGVyaSB2ZSBIaXpt
+ZXRsZXJpIEEuxZ4uMQswCQYDVQQGEwJUUjAeFw0wNjA4MTcwMDIxMDlaFw0xNjA4
+MTQwMDMxMDlaMIGAMTgwNgYDVQQDDC9FQkcgRWxla3Ryb25payBTZXJ0aWZpa2Eg
+SGl6bWV0IFNhxJ9sYXnEsWPEsXPEsTE3MDUGA1UECgwuRUJHIEJpbGnFn2ltIFRl
+a25vbG9qaWxlcmkgdmUgSGl6bWV0bGVyaSBBLsWeLjELMAkGA1UEBhMCVFIwggIi
+MA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDuoIRh0DpqZhAy2DE4f6en5f2h
+4fuXd7hxlugTlkaDT7byX3JWbhNgpQGR4lvFzVcfd2NR/y8927k/qqk153nQ9dAk
+tiHq6yOU/im/+4mRDGSaBUorzAzu8T2bgmmkTPiab+ci2hC6X5L8GCcKqKpE+i4s
+tPtGmggDg3KriORqcsnlZR9uKg+ds+g75AxuetpX/dfreYteIAbTdgtsApWjluTL
+dlHRKJ2hGvxEok3MenaoDT2/F08iiFD9rrbskFBKW5+VQarKD7JK/oCZTqNGFav4
+c0JqwmZ2sQomFd2TkuzbqV9UIlKRcF0T6kjsbgNs2d1s/OsNA/+mgxKb8amTD8Um
+TDGyY5lhcucqZJnSuOl14nypqZoaqsNW2xCaPINStnuWt6yHd6i58mcLlEOzrz5z
++kI2sSXFCjEmN1ZnuqMLfdb3ic1nobc6HmZP9qBVFCVMLDMNpkGMvQQxahByCp0O
+Lna9XvNRiYuoP1Vzv9s6xiQFlpJIqkuNKgPlV5EQ9GooFW5Hd4RcUXSfGenmHmMW
+OeMRFeNYGkS9y8RsZteEBt8w9DeiQyJ50hBs37vmExH8nYQKE3vwO9D8owrXieqW
+fo1IhR5kX9tUoqzVegJ5a9KK8GfaZXINFHDk6Y54jzJ0fFfy1tb0Nokb+Clsi7n2
+l9GkLqq+CxnCRelwXQIDAJ3Zo2MwYTAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB
+/wQEAwIBBjAdBgNVHQ4EFgQU587GT/wWZ5b6SqMHwQSny2re2kcwHwYDVR0jBBgw
+FoAU587GT/wWZ5b6SqMHwQSny2re2kcwDQYJKoZIhvcNAQEFBQADggIBAJuYml2+
+8ygjdsZs93/mQJ7ANtyVDR2tFcU22NU57/IeIl6zgrRdu0waypIN30ckHrMk2pGI
+6YNw3ZPX6bqz3xZaPt7gyPvT/Wwp+BVGoGgmzJNSroIBk5DKd8pNSe/iWtkqvTDO
+TLKBtjDOWU/aWR1qeqRFsIImgYZ29fUQALjuswnoT4cCB64kXPBfrAowzIpAoHME
+wfuJJPaaHFy3PApnNgUIMbOv2AFoKuB4j3TeuFGkjGwgPaL7s9QJ/XvCgKqTbCmY
+Iai7FvOpEl90tYeY8pUm3zTvilORiF0alKM/fCL414i6poyWqD1SNGKfAB5UVUJn
+xk1Gj7sURT0KlhaOEKGXmdXTMIXM3rRyt7yKPBgpaP3ccQfuJDlq+u2lrDgv+R4Q
+DgZxGhBM/nV+/x5XOULK1+EVoVZVWRvRo68R2E7DpSvvkL/A7IITW43WciyTTo9q
+Kd+FPNMN4KIYEsxVL0e3p5sC/kH2iExt2qkBR4NkJ2IQgtYSe14DHzSpyZH+r11t
+hie3I6p1GMog57AP14kOpmciY/SDQSsGS7tY1dHXt7kQY9iJSrSq3RZj9W6+YKH4
+7ejWkE8axsWgKdOnIaj1Wjz3x0miIZpKlVIglnKaZsv30oZDfCK+lvm9AahH3eU7
+QPl1K5srRmSGjR70j/sHd9DqSaIcjVIUpgqT
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIFFzCCA/+gAwIBAgIBETANBgkqhkiG9w0BAQUFADCCASsxCzAJBgNVBAYTAlRS
+MRgwFgYDVQQHDA9HZWJ6ZSAtIEtvY2FlbGkxRzBFBgNVBAoMPlTDvHJraXllIEJp
+bGltc2VsIHZlIFRla25vbG9qaWsgQXJhxZ90xLFybWEgS3VydW11IC0gVMOcQsSw
+VEFLMUgwRgYDVQQLDD9VbHVzYWwgRWxla3Ryb25payB2ZSBLcmlwdG9sb2ppIEFy
+YcWfdMSxcm1hIEVuc3RpdMO8c8O8IC0gVUVLQUUxIzAhBgNVBAsMGkthbXUgU2Vy
+dGlmaWthc3lvbiBNZXJrZXppMUowSAYDVQQDDEFUw5xCxLBUQUsgVUVLQUUgS8O2
+ayBTZXJ0aWZpa2EgSGl6bWV0IFNhxJ9sYXnEsWPEsXPEsSAtIFPDvHLDvG0gMzAe
+Fw0wNzA4MjQxMTM3MDdaFw0xNzA4MjExMTM3MDdaMIIBKzELMAkGA1UEBhMCVFIx
+GDAWBgNVBAcMD0dlYnplIC0gS29jYWVsaTFHMEUGA1UECgw+VMO8cmtpeWUgQmls
+aW1zZWwgdmUgVGVrbm9sb2ppayBBcmHFn3TEsXJtYSBLdXJ1bXUgLSBUw5xCxLBU
+QUsxSDBGBgNVBAsMP1VsdXNhbCBFbGVrdHJvbmlrIHZlIEtyaXB0b2xvamkgQXJh
+xZ90xLFybWEgRW5zdGl0w7xzw7wgLSBVRUtBRTEjMCEGA1UECwwaS2FtdSBTZXJ0
+aWZpa2FzeW9uIE1lcmtlemkxSjBIBgNVBAMMQVTDnELEsFRBSyBVRUtBRSBLw7Zr
+IFNlcnRpZmlrYSBIaXptZXQgU2HEn2xhecSxY8Sxc8SxIC0gU8O8csO8bSAzMIIB
+IjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAim1L/xCIOsP2fpTo6iBkcK4h
+gb46ezzb8R1Sf1n68yJMlaCQvEhOEav7t7WNeoMojCZG2E6VQIdhn8WebYGHV2yK
+O7Rm6sxA/OOqbLLLAdsyv9Lrhc+hDVXDWzhXcLh1xnnRFDDtG1hba+818qEhTsXO
+fJlfbLm4IpNQp81McGq+agV/E5wrHur+R84EpW+sky58K5+eeROR6Oqeyjh1jmKw
+lZMq5d/pXpduIF9fhHpEORlAHLpVK/swsoHvhOPc7Jg4OQOFCKlUAwUp8MmPi+oL
+hmUZEdPpCSPeaJMDyTYcIW7OjGbxmTDY17PDHfiBLqi9ggtm/oLL4eAagsNAgQID
+AQABo0IwQDAdBgNVHQ4EFgQUvYiHyY/2pAoLquvF/pEjnatKijIwDgYDVR0PAQH/
+BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEFBQADggEBAB18+kmP
+NOm3JpIWmgV050vQbTlswyb2zrgxvMTfvCr4N5EY3ATIZJkrGG2AA1nJrvhY0D7t
+wyOfaTyGOBye79oneNGEN3GKPEs5z35FBtYt2IpNeBLWrcLTy9LQQfMmNkqblWwM
+7uXRQydmwYj3erMgbOqwaSvHIOgMA8RBBZniP+Rr+KCGgceExh/VS4ESshYhLBOh
+gLJeDEoTniDYYkCrkOpkSi+sDQESeUWoL4cZaMjihccwsnX5OD+ywJO0a+IDRM5n
+oN+J1q2MdqMTw5RhK2vZbMEHCiIHhWyFJEapvj+LeISCfiQMnf2BN+MlqO02TpUs
+yZyQ2uypQjyttgI=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIEPTCCAyWgAwIBAgIBATANBgkqhkiG9w0BAQUFADCBvzE/MD0GA1UEAww2VMOc
+UktUUlVTVCBFbGVrdHJvbmlrIFNlcnRpZmlrYSBIaXptZXQgU2HEn2xhecSxY8Sx
+c8SxMQswCQYDVQQGEwJUUjEPMA0GA1UEBwwGQW5rYXJhMV4wXAYDVQQKDFVUw5xS
+S1RSVVNUIEJpbGdpIMSwbGV0acWfaW0gdmUgQmlsacWfaW0gR8O8dmVubGnEn2kg
+SGl6bWV0bGVyaSBBLsWeLiAoYykgQXJhbMSxayAyMDA3MB4XDTA3MTIyNTE4Mzcx
+OVoXDTE3MTIyMjE4MzcxOVowgb8xPzA9BgNVBAMMNlTDnFJLVFJVU1QgRWxla3Ry
+b25payBTZXJ0aWZpa2EgSGl6bWV0IFNhxJ9sYXnEsWPEsXPEsTELMAkGA1UEBhMC
+VFIxDzANBgNVBAcMBkFua2FyYTFeMFwGA1UECgxVVMOcUktUUlVTVCBCaWxnaSDE
+sGxldGnFn2ltIHZlIEJpbGnFn2ltIEfDvHZlbmxpxJ9pIEhpem1ldGxlcmkgQS7F
+ni4gKGMpIEFyYWzEsWsgMjAwNzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC
+ggEBAKu3PgqMyKVYFeaK7yc9SrToJdPNM8Ig3BnuiD9NYvDdE3ePYakqtdTyuTFY
+KTsvP2qcb3N2Je40IIDu6rfwxArNK4aUyeNgsURSsloptJGXg9i3phQvKUmi8wUG
++7RP2qFsmmaf8EMJyupyj+sA1zU511YXRxcw9L6/P8JorzZAwan0qafoEGsIiveG
+HtyaKhUG9qPw9ODHFNRRf8+0222vR5YXm3dx2KdxnSQM9pQ/hTEST7ruToK4uT6P
+IzdezKKqdfcYbwnTrqdUKDT74eA7YH2gvnmJhsifLfkKS8RQouf9eRbHegsYz85M
+733WB2+Y8a+xwXrXgTW4qhe04MsCAwEAAaNCMEAwHQYDVR0OBBYEFCnFkKslrxHk
+Yb+j/4hhkeYO/pyBMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MA0G
+CSqGSIb3DQEBBQUAA4IBAQAQDdr4Ouwo0RSVgrESLFF6QSU2TJ/sPx+EnWVUXKgW
+AkD6bho3hO9ynYYKVZ1WKKxmLNA6VpM0ByWtCLCPyA8JWcqdmBzlVPi5RX9ql2+I
+aE1KBiY3iAIOtsbWcpnOa3faYjGkVh+uX4132l32iPwa2Z61gfAyuOOI0JzzaqC5
+mxRZNTZPz/OOXl0XrRWV2N2y1RVuAE6zS89mlOTgzbUF2mNXi+WzqtvALhyQRNsa
+XRik7r4EW5nVcV9VZWRi1aKbBFmGyGJ353yCRWo9F7/snXUMrqNvWtMvmDb08PUZ
+qxFdyKbjKlhqQgnDvZImZjINXQhVdP+MmNAKpoRq0Tl9
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIEYDCCA0igAwIBAgICATAwDQYJKoZIhvcNAQELBQAwWTELMAkGA1UEBhMCVVMx
+GDAWBgNVBAoTD1UuUy4gR292ZXJubWVudDENMAsGA1UECxMERlBLSTEhMB8GA1UE
+AxMYRmVkZXJhbCBDb21tb24gUG9saWN5IENBMB4XDTEwMTIwMTE2NDUyN1oXDTMw
+MTIwMTE2NDUyN1owWTELMAkGA1UEBhMCVVMxGDAWBgNVBAoTD1UuUy4gR292ZXJu
+bWVudDENMAsGA1UECxMERlBLSTEhMB8GA1UEAxMYRmVkZXJhbCBDb21tb24gUG9s
+aWN5IENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA2HX7NRY0WkG/
+Wq9cMAQUHK14RLXqJup1YcfNNnn4fNi9KVFmWSHjeavUeL6wLbCh1bI1FiPQzB6+
+Duir3MPJ1hLXp3JoGDG4FyKyPn66CG3G/dFYLGmgA/Aqo/Y/ISU937cyxY4nsyOl
+4FKzXZbpsLjFxZ+7xaBugkC7xScFNknWJidpDDSPzyd6KgqjQV+NHQOGgxXgVcHF
+mCye7Bpy3EjBPvmE0oSCwRvDdDa3ucc2Mnr4MrbQNq4iGDGMUHMhnv6DOzCIJOPp
+wX7e7ZjHH5IQip9bYi+dpLzVhW86/clTpyBLqtsgqyFOHQ1O5piF5asRR12dP8Qj
+wOMUBm7+nQIDAQABo4IBMDCCASwwDwYDVR0TAQH/BAUwAwEB/zCB6QYIKwYBBQUH
+AQsEgdwwgdkwPwYIKwYBBQUHMAWGM2h0dHA6Ly9odHRwLmZwa2kuZ292L2ZjcGNh
+L2NhQ2VydHNJc3N1ZWRCeWZjcGNhLnA3YzCBlQYIKwYBBQUHMAWGgYhsZGFwOi8v
+bGRhcC5mcGtpLmdvdi9jbj1GZWRlcmFsJTIwQ29tbW9uJTIwUG9saWN5JTIwQ0Es
+b3U9RlBLSSxvPVUuUy4lMjBHb3Zlcm5tZW50LGM9VVM/Y0FDZXJ0aWZpY2F0ZTti
+aW5hcnksY3Jvc3NDZXJ0aWZpY2F0ZVBhaXI7YmluYXJ5MA4GA1UdDwEB/wQEAwIB
+BjAdBgNVHQ4EFgQUrQx6dVzl85jEeZgOrCj9l/TnAvwwDQYJKoZIhvcNAQELBQAD
+ggEBAI9z2uF/gLGH9uwsz9GEYx728Yi3mvIRte9UrYpuGDco71wb5O9Qt2wmGCMi
+TR0mRyDpCZzicGJxqxHPkYnos/UqoEfAFMtOQsHdDA4b8Idb7OV316rgVNdF9IU+
+7LQd3nyKf1tNnJaK0KIyn9psMQz4pO9+c+iR3Ah6cFqgr2KBWfgAdKLI3VTKQVZH
+venAT+0g3eOlCd+uKML80cgX2BLHb94u6b2akfI8WpQukSKAiaGMWMyDeiYZdQKl
+Dn0KJnNR6obLB6jI/WNaNZvSr79PMUjBhHDbNXuaGQ/lj/RqDG8z2esccKIN47lQ
+A2EC/0rskqTcLe4qNJMHtyznGI8=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIDhDCCAwqgAwIBAgIQL4D+I4wOIg9IZxIokYesszAKBggqhkjOPQQDAzCByjEL
+MAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQLExZW
+ZXJpU2lnbiBUcnVzdCBOZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwNyBWZXJpU2ln
+biwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5MUUwQwYDVQQDEzxWZXJp
+U2lnbiBDbGFzcyAzIFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9y
+aXR5IC0gRzQwHhcNMDcxMTA1MDAwMDAwWhcNMzgwMTE4MjM1OTU5WjCByjELMAkG
+A1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQLExZWZXJp
+U2lnbiBUcnVzdCBOZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwNyBWZXJpU2lnbiwg
+SW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5MUUwQwYDVQQDEzxWZXJpU2ln
+biBDbGFzcyAzIFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5
+IC0gRzQwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAASnVnp8Utpkmw4tXNherJI9/gHm
+GUo9FANL+mAnINmDiWn6VMaaGF5VKmTeBvaNSjutEDxlPZCIBIngMGGzrl0Bp3ve
+fLK+ymVhAIau2o970ImtTR1ZmkGxvEeA3J5iw/mjgbIwga8wDwYDVR0TAQH/BAUw
+AwEB/zAOBgNVHQ8BAf8EBAMCAQYwbQYIKwYBBQUHAQwEYTBfoV2gWzBZMFcwVRYJ
+aW1hZ2UvZ2lmMCEwHzAHBgUrDgMCGgQUj+XTGoasjY5rw8+AatRIGCx7GS4wJRYj
+aHR0cDovL2xvZ28udmVyaXNpZ24uY29tL3ZzbG9nby5naWYwHQYDVR0OBBYEFLMW
+kf3upm7ktS5Jj4d4gYDs5bG1MAoGCCqGSM49BAMDA2gAMGUCMGYhDBgmYFo4e1ZC
+4Kf8NoRRkSAsdk1DPcQdhCPQrNZ8NQbOzWm9kA3bbEhCHQ6qQgIxAJw9SDkjOVga
+FRJZap7v1VmyHVIsmXHNxynfGyphe3HR3vPA5Q06Sqotp9iGKt0uEA==
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIID4TCCAsmgAwIBAgIOYyUAAQACFI0zFQLkbPQwDQYJKoZIhvcNAQEFBQAwezEL
+MAkGA1UEBhMCREUxHDAaBgNVBAoTE1RDIFRydXN0Q2VudGVyIEdtYkgxJDAiBgNV
+BAsTG1RDIFRydXN0Q2VudGVyIFVuaXZlcnNhbCBDQTEoMCYGA1UEAxMfVEMgVHJ1
+c3RDZW50ZXIgVW5pdmVyc2FsIENBIElJSTAeFw0wOTA5MDkwODE1MjdaFw0yOTEy
+MzEyMzU5NTlaMHsxCzAJBgNVBAYTAkRFMRwwGgYDVQQKExNUQyBUcnVzdENlbnRl
+ciBHbWJIMSQwIgYDVQQLExtUQyBUcnVzdENlbnRlciBVbml2ZXJzYWwgQ0ExKDAm
+BgNVBAMTH1RDIFRydXN0Q2VudGVyIFVuaXZlcnNhbCBDQSBJSUkwggEiMA0GCSqG
+SIb3DQEBAQUAA4IBDwAwggEKAoIBAQDC2pxisLlxErALyBpXsq6DFJmzNEubkKLF
+5+cvAqBNLaT6hdqbJYUtQCggbergvbFIgyIpRJ9Og+41URNzdNW88jBmlFPAQDYv
+DIRlzg9uwliT6CwLOunBjvvya8o84pxOjuT5fdMnnxvVZ3iHLX8LR7PH6MlIfK8v
+zArZQe+f/prhsq75U7Xl6UafYOPfjdN/+5Z+s7Vy+EutCHnNaYlAJ/Uqwa1D7KRT
+yGG299J5KmcYdkhtWyUB0SbFt1dpIxVbYYqt8Bst2a9c8SaQaanVDED1M4BDj5yj
+dipFtK+/fz6HP3bFzSreIMUWWMv5G/UPyw0RUmS40nZid4PxWJ//AgMBAAGjYzBh
+MB8GA1UdIwQYMBaAFFbn4VslQ4Dg9ozhcbyO5YAvxEjiMA8GA1UdEwEB/wQFMAMB
+Af8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBRW5+FbJUOA4PaM4XG8juWAL8RI
+4jANBgkqhkiG9w0BAQUFAAOCAQEAg8ev6n9NCjw5sWi+e22JLumzCecYV42Fmhfz
+dkJQEw/HkG8zrcVJYCtsSVgZ1OK+t7+rSbyUyKu+KGwWaODIl0YgoGhnYIg5IFHY
+aAERzqf2EQf27OysGh+yZm5WZ2B6dF7AbZc2rrUNXWZzwCUyRdhKBgePxLcHsU0G
+DeGl6/R1yrqc0L2z0zIkTO5+4nYES0lT2PLpVDP85XEfPRRclkvxOvIAu2y0+pZV
+CIgJwcyRGSmwIC3/yzikQOEXvnlhgP8HA4ZMTnsGnxGGjYnuJ8Tb4rwZjgvDwxPH
+LQNjO9Po5KIqwoIIlBZU8O8fJ5AluA0OKBtHd0e9HKgl8ZS0Zg==
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIDcTCCAlmgAwIBAgIVAOYJ/nrqAGiM4CS07SAbH+9StETRMA0GCSqGSIb3DQEB
+BQUAMFAxCzAJBgNVBAYTAlBMMSgwJgYDVQQKDB9LcmFqb3dhIEl6YmEgUm96bGlj
+emVuaW93YSBTLkEuMRcwFQYDVQQDDA5TWkFGSVIgUk9PVCBDQTAeFw0xMTEyMDYx
+MTEwNTdaFw0zMTEyMDYxMTEwNTdaMFAxCzAJBgNVBAYTAlBMMSgwJgYDVQQKDB9L
+cmFqb3dhIEl6YmEgUm96bGljemVuaW93YSBTLkEuMRcwFQYDVQQDDA5TWkFGSVIg
+Uk9PVCBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKxHL49ZMTml
+6g3wpYwrvQKkvc0Kc6oJ5sxfgmp1qZfluwbv88BdocHSiXlY8NzrVYzuWBp7J/9K
+ULMAoWoTIzOQ6C9TNm4YbA9A1jdX1wYNL5Akylf8W5L/I4BXhT9KnlI6x+a7BVAm
+nr/Ttl+utT/Asms2fRfEsF2vZPMxH4UFqOAhFjxTkmJWf2Cu4nvRQJHcttB+cEAo
+ag/hERt/+tzo4URz6x6r19toYmxx4FjjBkUhWQw1X21re//Hof2+0YgiwYT84zLb
+eqDqCOMOXxvH480yGDkh/QoazWX3U75HQExT/iJlwnu7I1V6HXztKIwCBjsxffbH
+3jOshCJtywcCAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMC
+AQYwHQYDVR0OBBYEFFOSo33/gnbwM9TrkmdHYTMbaDsqMA0GCSqGSIb3DQEBBQUA
+A4IBAQA5UFWd5EL/pBviIMm1zD2JLUCpp0mJG7JkwznIOzawhGmFFaxGoxAhQBEg
+haP+E0KR66oAwVC6xe32QUVSHfWqWndzbODzLB8yj7WAR0cDM45ZngSBPBuFE3Wu
+GLJX9g100ETfIX+4YBR/4NR/uvTnpnd9ete7Whl0ZfY94yuu4xQqB5QFv+P7IXXV
+lTOjkjuGXEcyQAjQzbFaT9vIABSbeCXWBbjvOXukJy6WgAiclzGNSYprre8Ryydd
+fmjW9HIGwsIO03EldivvqEYL1Hv1w/Pur+6FUEOaL68PEIUovfgwIB2BAw+vZDuw
+cH0mX548PojGyg434cDjkSXa3mHF
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIEPDCCAySgAwIBAgIBATANBgkqhkiG9w0BAQUFADCBvjE/MD0GA1UEAww2VMOc
+UktUUlVTVCBFbGVrdHJvbmlrIFNlcnRpZmlrYSBIaXptZXQgU2HEn2xhecSxY8Sx
+c8SxMQswCQYDVQQGEwJUUjEPMA0GA1UEBwwGQW5rYXJhMV0wWwYDVQQKDFRUw5xS
+S1RSVVNUIEJpbGdpIMSwbGV0acWfaW0gdmUgQmlsacWfaW0gR8O8dmVubGnEn2kg
+SGl6bWV0bGVyaSBBLsWeLiAoYykgS2FzxLFtIDIwMDUwHhcNMDUxMTA3MTAwNzU3
+WhcNMTUwOTE2MTAwNzU3WjCBvjE/MD0GA1UEAww2VMOcUktUUlVTVCBFbGVrdHJv
+bmlrIFNlcnRpZmlrYSBIaXptZXQgU2HEn2xhecSxY8Sxc8SxMQswCQYDVQQGEwJU
+UjEPMA0GA1UEBwwGQW5rYXJhMV0wWwYDVQQKDFRUw5xSS1RSVVNUIEJpbGdpIMSw
+bGV0acWfaW0gdmUgQmlsacWfaW0gR8O8dmVubGnEn2kgSGl6bWV0bGVyaSBBLsWe
+LiAoYykgS2FzxLFtIDIwMDUwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB
+AQCpNn7DkUNMwxmYCMjHWHtPFoylzkkBH3MOrHUTpvqeLCDe2JAOCtFp0if7qnef
+J1Il4std2NiDUBd9irWCPwSOtNXwSadktx4uXyCcUHVPr+G1QRT0mJKIx+XlZEdh
+R3n9wFHxwZnn3M5q+6+1ATDcRhzviuyV79z/rxAc653YsKpqhRgNF8k+v/Gb0AmJ
+Qv2gQrSdiVFVKc8bcLyEVK3BEx+Y9C52YItdP5qtygy/p1Zbj3e41Z55SZI/4PGX
+JHpsmxcPbe9TmJEr5A++WXkHeLuXlfSfadRYhwqp48y2WBmfJiGxxFmNskF1wK1p
+zpwACPI2/z7woQ8arBT9pmAPAgMBAAGjQzBBMB0GA1UdDgQWBBTZN7NOBf3Zz58S
+Fq62iS/rJTqIHDAPBgNVHQ8BAf8EBQMDBwYAMA8GA1UdEwEB/wQFMAMBAf8wDQYJ
+KoZIhvcNAQEFBQADggEBAHJglrfJ3NgpXiOFX7KzLXb7iNcX/nttRbj2hWyfIvwq
+ECLsqrkw9qtY1jkQMZkpAL2JZkH7dN6RwRgLn7Vhy506vvWolKMiVW4XSf/SKfE4
+Jl3vpao6+XF75tpYHdN0wgH6PmlYX63LaL4ULptswLbcoCb6dxriJNoaN+BnrdFz
+gw2lGh1uEpJ+hGIAF728JRhX8tepb1mIvDS3LoV4nZbcFMMsilKbloxSZj2GFotH
+uFEJjOp9zYhys2AzsfAKRO8P9Qk3iCQOLGsgOqL6EfJANZxEaGM7rDNvY7wsu/LS
+y3Z9fYjYHcgFHW68lKlmjHdxx/qR+i9Rnuk5UrbnBEI=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIDfTCCAmWgAwIBAgIBADANBgkqhkiG9w0BAQUFADBgMQswCQYDVQQGEwJKUDEl
+MCMGA1UEChMcU0VDT00gVHJ1c3QgU3lzdGVtcyBDTy4sTFRELjEqMCgGA1UECxMh
+U2VjdXJpdHkgQ29tbXVuaWNhdGlvbiBFViBSb290Q0ExMB4XDTA3MDYwNjAyMTIz
+MloXDTM3MDYwNjAyMTIzMlowYDELMAkGA1UEBhMCSlAxJTAjBgNVBAoTHFNFQ09N
+IFRydXN0IFN5c3RlbXMgQ08uLExURC4xKjAoBgNVBAsTIVNlY3VyaXR5IENvbW11
+bmljYXRpb24gRVYgUm9vdENBMTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC
+ggEBALx/7FebJOD+nLpCeamIivqA4PUHKUPqjgo0No0c+qe1OXj/l3X3L+SqawSE
+RMqm4miO/VVQYg+kcQ7OBzgtQoVQrTyWb4vVog7P3kmJPdZkLjjlHmy1V4qe70gO
+zXppFodEtZDkBp2uoQSXWHnvIEqCa4wiv+wfD+mEce3xDuS4GBPMVjZd0ZoeUWs5
+bmB2iDQL87PRsJ3KYeJkHcFGB7hj3R4zZbOOCVVSPbW9/wfrrWFVGCypaZhKqkDF
+MxRldAD5kd6vA0jFQFTcD4SQaCDFkpbcLuUCRarAX1T4bepJz11sS6/vmsJWXMY1
+VkJqMF/Cq/biPT+zyRGPMUzXn0kCAwEAAaNCMEAwHQYDVR0OBBYEFDVK9U2vP9eC
+OKyrcWUXdYydVZPmMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MA0G
+CSqGSIb3DQEBBQUAA4IBAQCoh+ns+EBnXcPBZsdAS5f8hxOQWsTvoMpfi7ent/HW
+tWS3irO4G8za+6xmiEHO6Pzk2x6Ipu0nUBsCMCRGef4Eh3CXQHPRwMFXGZpppSeZ
+q51ihPZRwSzJIxXYKLerJRO1RuGGAv8mjMSIkh1W/hln8lXkgKNrnKt34VFxDSDb
+EJrbvXZ5B3eZKK2aXtqxT0QsNY6llsf9g/BYxnnWmHyojf6GPgcWkuF75x3sM3Z+
+Qi5KhfmRiWiEA4Glm5q+4zfFVKtWOxgtQaQM+ELbmaDgcm+7XeEWT1MKZPlO9L9O
+VL14bIjqv5wTJMJwaaJ/D8g8rQjJsJhAoyrniIPtd490
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIICqDCCAi2gAwIBAgIQNBdlEkA7t1aALYDLeVWmHjAKBggqhkjOPQQDAzCBlDEL
+MAkGA1UEBhMCVVMxHTAbBgNVBAoTFFN5bWFudGVjIENvcnBvcmF0aW9uMR8wHQYD
+VQQLExZTeW1hbnRlYyBUcnVzdCBOZXR3b3JrMUUwQwYDVQQDEzxTeW1hbnRlYyBD
+bGFzcyAyIFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IC0g
+RzQwHhcNMTExMDA1MDAwMDAwWhcNMzgwMTE4MjM1OTU5WjCBlDELMAkGA1UEBhMC
+VVMxHTAbBgNVBAoTFFN5bWFudGVjIENvcnBvcmF0aW9uMR8wHQYDVQQLExZTeW1h
+bnRlYyBUcnVzdCBOZXR3b3JrMUUwQwYDVQQDEzxTeW1hbnRlYyBDbGFzcyAyIFB1
+YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IC0gRzQwdjAQBgcq
+hkjOPQIBBgUrgQQAIgNiAATR2UqOTA2ESlG6fO/TzPo6mrWnYxM9AeBJPvrBR8mS
+szrX/m+c95o6D/UOCgrDP8jnEhSO1dVtmCyzcTIK6yq99tdqIAtnRZzSsr9TImYJ
+XdsR8/EFM1ij4rjPfM2Cm72jQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8E
+BTADAQH/MB0GA1UdDgQWBBQ9MvM6qQyQhPmijGkGYVQvh3L+BTAKBggqhkjOPQQD
+AwNpADBmAjEAyKapr0F/tckRQhZoaUxcuCcYtpjxwH+QbYfTjEYX8D5P/OqwCMR6
+S7wIL8fip29lAjEA1lnehs5fDspU1cbQFQ78i5Ry1I4AWFPPfrFLDeVQhuuea9//
+KabYR9mglhjb8kWz
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIFWTCCA0GgAwIBAgIBAjANBgkqhkiG9w0BAQsFADBOMQswCQYDVQQGEwJOTzEd
+MBsGA1UECgwUQnV5cGFzcyBBUy05ODMxNjMzMjcxIDAeBgNVBAMMF0J1eXBhc3Mg
+Q2xhc3MgMyBSb290IENBMB4XDTEwMTAyNjA4Mjg1OFoXDTQwMTAyNjA4Mjg1OFow
+TjELMAkGA1UEBhMCTk8xHTAbBgNVBAoMFEJ1eXBhc3MgQVMtOTgzMTYzMzI3MSAw
+HgYDVQQDDBdCdXlwYXNzIENsYXNzIDMgUm9vdCBDQTCCAiIwDQYJKoZIhvcNAQEB
+BQADggIPADCCAgoCggIBAKXaCpUWUOOV8l6ddjEGMnqb8RB2uACatVI2zSRHsJ8Y
+ZLya9vrVediQYkwiL944PdbgqOkcLNt4EemOaFEVcsfzM4fkoF0LXOBXByow9c3E
+N3coTRiR5r/VUv1xLXA+58bEiuPwKAv0dpihi4dVsjoT/Lc+JzeOIuOoTyrvYLs9
+tznDDgFHmV0ST9tD+leh7fmdvhFHJlsTmKtdFoqwNxxXnUX/iJY2v7vKB3tvh2PX
+0DJq1l1sDPGzbjniazEuOQAnFN44wOwZZoYS6J1yFhNkUsepNxz9gjDthBgd9K5c
+/3ATAOux9TN6S9ZV+AWNS2mw9bMoNlwUxFFzTWsL8TQH2xc519woe2v1n/MuwU8X
+KhDzzMro6/1rqy6any2CbgTUUgGTLT2G/H783+9CHaZr77kgxve9oKeV/afmiSTY
+zIw0bOIjL9kSGiG5VZFvC5F5GQytQIgLcOJ60g7YaEi7ghM5EFjp2CoHxhLbWNvS
+O1UQRwUVZ2J+GGOmRj8JDlQyXr8NYnon74Do29lLBlo3WiXQCBJ31G8JUJc9yB3D
+34xFMFbG02SrZvPAXpacw8Tvw3xrizp5f7NJzz3iiZ+gMEuFuZyUJHmPfWupRWgP
+K9Dx2hzLabjKSWJtyNBjYt1gD1iqj6G8BaVmos8bdrKEZLFMOVLAMLrwjEsCsLa3
+AgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFEe4zf/lb+74suwv
+Tg75JbCOPGvDMA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQsFAAOCAgEAACAj
+QTUEkMJAYmDv4jVM1z+s4jSQuKFvdvoWFqRINyzpkMLyPPgKn9iB5btb2iUspKdV
+cSQy9sgL8rxq+JOssgfCX5/bzMiKqr5qb+FJEMwx14C7u8jYog5kV+qi9cKpMRXS
+IGrs/CIBKM+GuIAeqcwRpTzyFrNHnfzSgCHEy9BHcEGhyoMZCCxt8l13nIoUE9Q2
+HJLw5QY33KbmkJs4j1xrG0aGQ0JfPgEHU1RdZX33inOhmlRaHylDFCfChQ+1iHsa
+O5S3HWCntZznKWlXWpuTekMwGwPXYshApqr8ZORK15FTAaggiG6cX0S5y2CBNOxv
+033aSF/rtJC8LakcC6wc1aJoIIAE1vyxjy+7SjENSoYc6+I2KSb12tjE8nVhz36u
+dmNKekBlk4f4HoCMhuWG1o8O/FMsYOgWYRqiPkN7zTlgVGr18okmAWiDSKIz6MkE
+kbIRNBE+6tBDGR8Dk5AM/1E9V/RBbuHLoL7ryWPNbczk+DaqaJ3tvV2XcEQNtg41
+3OEMXbugUZTLfhbrES+jkkXITHHZvMmZUldGL1DPvTVp9D0VzgalLA8+9oG6lLvD
+u79leNKGef9JOxqDDPDeeOzI8k1MGt6CKfjBWtrt7uYnXuhF0J0cUahoq0Tj0Itq
+4/g7u9xN12TyUb7mqqta6THuBrxzvxNiCp/HuZc=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIF9jCCA96gAwIBAgIQZWNxhdNvRcaPfzH5CYeSgjANBgkqhkiG9w0BAQwFADCB
+lDELMAkGA1UEBhMCVVMxHTAbBgNVBAoTFFN5bWFudGVjIENvcnBvcmF0aW9uMR8w
+HQYDVQQLExZTeW1hbnRlYyBUcnVzdCBOZXR3b3JrMUUwQwYDVQQDEzxTeW1hbnRl
+YyBDbGFzcyAzIFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5
+IC0gRzYwHhcNMTIxMDE4MDAwMDAwWhcNMzcxMjAxMjM1OTU5WjCBlDELMAkGA1UE
+BhMCVVMxHTAbBgNVBAoTFFN5bWFudGVjIENvcnBvcmF0aW9uMR8wHQYDVQQLExZT
+eW1hbnRlYyBUcnVzdCBOZXR3b3JrMUUwQwYDVQQDEzxTeW1hbnRlYyBDbGFzcyAz
+IFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IC0gRzYwggIi
+MA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQC3DrL6TbyachX7d1vb/UMPywv3
+YC6zK34Mu1PyzE5l8xm7/zUd99Opu0Attd141Kb5N+qFBXttt+YTSwZ8+3ZjjyAd
+LTgrBIXy6LDRX01KIclq2JTqHgJQpqqQB6BHIepm+QSg5oPwxPVeluInTWHDs8GM
+IrZmoQDRVin77cF/JMo9+lqUsITDx7pDHP1kDvEo+0dZ8ibhMblE+avd+76+LDfj
+rAsY0/wBovGkCjWCR0yrvYpe3xOF/CDMSFmvr0FvyyPNypOn3dVfyGQ7/wEDoApP
+LW49hL6vyDKyUymQFfewBZoKPPa5BpDJpeFdoDuw/qi2v/WJKFckOiGGceTciotB
+VeweMCRZ0cBZuHivqlp03iWAMJjtMERvIXAc2xJTDtamKGaTLB/MTzwbgcW59nhv
+0DI6CHLbaw5GF4WU87zvvPekXo7p6bVk5bdLRRIsTDe3YEMKTXEGAJQmNXQfu3o5
+XE475rgD4seTi4QsJUlF3X8jlGAfy+nN9quX92Hn+39igcjcCjBcGHzmzu/Hbh6H
+fLPpysh7avRo/IOlDFa0urKNSgrHl5fFiDAVPRAIVBVycmczM/R8t84AJ1NlziTx
+WmTnNi/yLgLCl99y6AIeoPc9tftoYAP6M6nmEm0G4amoXU48/tnnAGWsthlNe4N/
+NEfq4RhtsYsceavnnQIDAQABo0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/
+BAUwAwEB/zAdBgNVHQ4EFgQUOXEIAD7eyIbnkP/k/SEPziQZFvYwDQYJKoZIhvcN
+AQEMBQADggIBAFBriE1gSM5a4yLOZ3yEp80c/ekMA4w2rwqHDmquV64B0Da78v25
+c8FftaiuTKL6ScsHRhY2vePIVzh+OOS/JTNgxtw3nGO7XpgeGrKC8K6mdxGAREeh
+KcXwszrOmPC47NMOgAZ3IzBM/3lkYyJbd5NDS3Wz2ztuO0rd8ciutTeKlYg6EGhw
+OLlbcH7VQ8n8X0/l5ns27vAg7UdXEyYQXhQGDXt2B8LGLRb0rqdsD7yID08sAraj
+1yLmmUc12I2lT4ESOhF9s8wLdfMecKMbA+r6mujmLjY5zJnOOj8Mt674Q5mwk25v
+qtkPajGRu5zTtCj7g0x6c4JQZ9IOrO1gxbJdNZjPh34eWR0kvFa62qRa2MzmvB4Q
+jxuMjvPB27e+1LBbZY8WaPNWxSoZFk0PuGWHbSSDuGLc4EdhGoh7zk5//dzGDVqa
+pPO1TPbdMaboHREhMzAEYX0c4D5PjT+1ixIAWn2poQDUg+twuxj4pNIcgS23CBHI
+Jnu21OUPA0Zy1CVAHr5JXW2T8VyyO3VUaTqg7kwiuqya4gitRWMFSlI1dsQ09V4H
+Mq3cfCbRW4+t5OaqG3Wf61206MCpFXxOSgdy30bJ1JGSdVaw4e43NmUoxRXIK3bM
+bW8Zg/T92hXiQeczeUaDV/nxpbZt07zXU+fucW14qZen7iCcGRVyFT0E
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIICRjCCAc2gAwIBAgIQC6Fa+h3foLVJRK/NJKBs7DAKBggqhkjOPQQDAzBlMQsw
+CQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cu
+ZGlnaWNlcnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3Qg
+RzMwHhcNMTMwODAxMTIwMDAwWhcNMzgwMTE1MTIwMDAwWjBlMQswCQYDVQQGEwJV
+UzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQu
+Y29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3QgRzMwdjAQBgcq
+hkjOPQIBBgUrgQQAIgNiAAQZ57ysRGXtzbg/WPuNsVepRC0FFfLvC/8QdJ+1YlJf
+Zn4f5dwbRXkLzMZTCp2NXQLZqVneAlr2lSoOjThKiknGvMYDOAdfVdp+CW7if17Q
+RSAPWXYQ1qAk8C3eNvJsKTmjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/
+BAQDAgGGMB0GA1UdDgQWBBTL0L2p4ZgFUaFNN6KDec6NHSrkhDAKBggqhkjOPQQD
+AwNnADBkAjAlpIFFAmsSS3V0T8gj43DydXLefInwz5FyYZ5eEJJZVrmDxxDnOOlY
+JjZ91eQ0hjkCMHw2U/Aw5WJjOpnitqM7mzT6HtoQknFekROn3aRukswy1vUhZscv
+6pZjamVFkpUBtA==
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIEUzCCAzugAwIBAgIDAOJDMA0GCSqGSIb3DQEBBQUAMIHPMQswCQYDVQQGEwJB
+VDGBizCBiAYDVQQKHoGAAEEALQBUAHIAdQBzAHQAIABHAGUAcwAuACAAZgD8AHIA
+IABTAGkAYwBoAGUAcgBoAGUAaQB0AHMAcwB5AHMAdABlAG0AZQAgAGkAbQAgAGUA
+bABlAGsAdAByAC4AIABEAGEAdABlAG4AdgBlAHIAawBlAGgAcgAgAEcAbQBiAEgx
+GDAWBgNVBAsTD0EtVHJ1c3QtUXVhbC0wMTEYMBYGA1UEAxMPQS1UcnVzdC1RdWFs
+LTAxMB4XDTA0MTEzMDIzMDAwMFoXDTE0MTEzMDIzMDAwMFowgc8xCzAJBgNVBAYT
+AkFUMYGLMIGIBgNVBAoegYAAQQAtAFQAcgB1AHMAdAAgAEcAZQBzAC4AIABmAPwA
+cgAgAFMAaQBjAGgAZQByAGgAZQBpAHQAcwBzAHkAcwB0AGUAbQBlACAAaQBtACAA
+ZQBsAGUAawB0AHIALgAgAEQAYQB0AGUAbgB2AGUAcgBrAGUAaAByACAARwBtAGIA
+SDEYMBYGA1UECxMPQS1UcnVzdC1RdWFsLTAxMRgwFgYDVQQDEw9BLVRydXN0LVF1
+YWwtMDEwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCmhgdxIbxTGEOH
+fXGiewI3NFldAWKFWfLofO+5I1UbvA5avt7IgsGXz/tI/f5HGUbascI0i7xG0tqV
+lA5ctQgLRqxgxHtgTkMcqsAEYdsz3LZsCdXO1QrvEBGLTSABdxiL/gSWJ6z77CSw
+x7Xg02HwxPV82cjGkSF3ENGJntuIAAnRDWn/ORHjFatNRymoMbHaOEZXSGhf7Y5F
+rrHEqGyi9E6sv784De/T1aTvskn8cWeUmDzv//omiG/a/V9KQex/61XN8OthUQVn
+X+u/liL2NKx74I2C/GgHX5B0WkPNqsSOgmlvJ/cKuT0PveUgVFDAA0oYBgcE1KDM
+lBbN0kmPAgMBAAGjNjA0MA8GA1UdEwEB/wQFMAMBAf8wEQYDVR0OBAoECEs8jB2F
+6W+tMA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQUFAAOCAQEAIUusmJzMJRiQ
+8TAHrJAOelfuWoTGcqdIv7Tys/fNl2yF2fjvHT8J01aKialFVpbVeQ2XKb1O2bHO
+QYAKgsdZ2jZ/sdL2UVFRTHmidLu6PdgWCBRhJYQELQophO9QVvfhAA0TwbESYqTz
++nlI5Gr7CZe8f6HEmhJmCtUQsdQCufGglRh4T+tIGiNGcnyVEHZ93mSVepFr1VA2
+9CTRPteuGjA81jeAz9peYiFE1CXvxK9cJiv0BcALFLWmADCoRLzIRZhA+sAwYUmw
+M1rqVCPA3kBQvIC95tyQvNy2dG0Vs+O6PwLaNX/suSlElQ06X2l1VwMaYb4vZKFq
+N0bOhBXEVg==
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIJmzCCB4OgAwIBAgIBATANBgkqhkiG9w0BAQwFADCCAR4xPjA8BgNVBAMTNUF1
+dG9yaWRhZCBkZSBDZXJ0aWZpY2FjaW9uIFJhaXogZGVsIEVzdGFkbyBWZW5lem9s
+YW5vMQswCQYDVQQGEwJWRTEQMA4GA1UEBxMHQ2FyYWNhczEZMBcGA1UECBMQRGlz
+dHJpdG8gQ2FwaXRhbDE2MDQGA1UEChMtU2lzdGVtYSBOYWNpb25hbCBkZSBDZXJ0
+aWZpY2FjaW9uIEVsZWN0cm9uaWNhMUMwQQYDVQQLEzpTdXBlcmludGVuZGVuY2lh
+IGRlIFNlcnZpY2lvcyBkZSBDZXJ0aWZpY2FjaW9uIEVsZWN0cm9uaWNhMSUwIwYJ
+KoZIhvcNAQkBFhZhY3JhaXpAc3VzY2VydGUuZ29iLnZlMB4XDTEwMTIyMjE4MDgy
+MVoXDTMwMTIxNzIzNTk1OVowggEeMT4wPAYDVQQDEzVBdXRvcmlkYWQgZGUgQ2Vy
+dGlmaWNhY2lvbiBSYWl6IGRlbCBFc3RhZG8gVmVuZXpvbGFubzELMAkGA1UEBhMC
+VkUxEDAOBgNVBAcTB0NhcmFjYXMxGTAXBgNVBAgTEERpc3RyaXRvIENhcGl0YWwx
+NjA0BgNVBAoTLVNpc3RlbWEgTmFjaW9uYWwgZGUgQ2VydGlmaWNhY2lvbiBFbGVj
+dHJvbmljYTFDMEEGA1UECxM6U3VwZXJpbnRlbmRlbmNpYSBkZSBTZXJ2aWNpb3Mg
+ZGUgQ2VydGlmaWNhY2lvbiBFbGVjdHJvbmljYTElMCMGCSqGSIb3DQEJARYWYWNy
+YWl6QHN1c2NlcnRlLmdvYi52ZTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoC
+ggIBAME77xNS8ZlW47RsBeEaaRZhJoZ4rw785UAFCuPZOAVMqNS1wMYqzy95q6Gk
+UO81ER/ugiQX/KMcq/4HBn83fwdYWxPZfwBfK7BP2p/JsFgzYeFP0BXOLmvoJIzl
+Jb6FW+1MPwGBjuaZGFImWZsSmGUclb51mRYMZETh9/J5CLThR1exStxHQptwSzra
+zNFpkQY/zmj7+YZNA9yDoroVFv6sybYOZ7OxNDo7zkSLo45I7gMwtxqWZ8VkJZkC
+8+p0dX6mkhUT0QAV64Zc9HsZiH/oLhEkXjhrgZ28cF73MXIqLx1fyM4kPH1yOJi/
+R72nMwL7D+Sd6mZgI035TxuHXc2/uOwXfKrrTjaJDz8Jp6DdessOkxIgkKXRjP+F
+K3ze3n4NUIRGhGRtyvEjK95/2g02t6PeYiYVGur6ruS49n0RAaSS0/LJb6XzaAAe
+0mmO2evnEqxIKwy2mZRNPfAVW1l3wCnWiUwryBU6OsbFcFFrQm+00wOicXvOTHBM
+aiCVAVZTb9RSLyi+LJ1llzJZO3pq3IRiiBj38Nooo+2ZNbMEciSgmig7YXaUcmud
+SVQvLSL+Yw+SqawyezwZuASbp7d/0rutQ59d81zlbMt3J7yB567rT2IqIydQ8qBW
+k+fmXzghX+/FidYsh/aK+zZ7Wy68kKHuzEw1Vqkat5DGs+VzAgMBAAGjggLeMIIC
+2jASBgNVHRMBAf8ECDAGAQH/AgECMDcGA1UdEgQwMC6CD3N1c2NlcnRlLmdvYi52
+ZaAbBgVghl4CAqASDBBSSUYtRy0yMDAwNDAzNi0wMB0GA1UdDgQWBBStuyIdxuDS
+Aaj9dlBSk+2YwU2u0zCCAVAGA1UdIwSCAUcwggFDgBStuyIdxuDSAaj9dlBSk+2Y
+wU2u06GCASakggEiMIIBHjE+MDwGA1UEAxM1QXV0b3JpZGFkIGRlIENlcnRpZmlj
+YWNpb24gUmFpeiBkZWwgRXN0YWRvIFZlbmV6b2xhbm8xCzAJBgNVBAYTAlZFMRAw
+DgYDVQQHEwdDYXJhY2FzMRkwFwYDVQQIExBEaXN0cml0byBDYXBpdGFsMTYwNAYD
+VQQKEy1TaXN0ZW1hIE5hY2lvbmFsIGRlIENlcnRpZmljYWNpb24gRWxlY3Ryb25p
+Y2ExQzBBBgNVBAsTOlN1cGVyaW50ZW5kZW5jaWEgZGUgU2VydmljaW9zIGRlIENl
+cnRpZmljYWNpb24gRWxlY3Ryb25pY2ExJTAjBgkqhkiG9w0BCQEWFmFjcmFpekBz
+dXNjZXJ0ZS5nb2IudmWCAQEwDgYDVR0PAQH/BAQDAgEGMDcGA1UdEQQwMC6CD3N1
+c2NlcnRlLmdvYi52ZaAbBgVghl4CAqASDBBSSUYtRy0yMDAwNDAzNi0wMFQGA1Ud
+HwRNMEswJKAioCCGHmhodHA6Ly93d3cuc3VzY2VydGUuZ29iLnZlL2xjcjAjoCGg
+H4YdbGRhcDovL2FjcmFpei5zdXNjZXJ0ZS5nb2IudmUwNwYIKwYBBQUHAQEEKzAp
+MCcGCCsGAQUFBzABhhtoaHRwOi8vb2NzcC5zdXNjZXJ0ZS5nb2IudmUwQAYDVR0g
+BDkwNzA1BgVghl4BAjAsMCoGCCsGAQUFBwIBFh5odHRwOi8vd3d3LnN1c2NlcnRl
+LmdvYi52ZS9kcGMwDQYJKoZIhvcNAQEMBQADggIBAK4qy/zmZ9zBwfW3yOYtLcBT
+Oy4szJyPz7/RhNH3bPVH7HbDTGpi6JZ4YXdXMBeJE5qBF4a590Kgj8Rlnltt+Rbo
+OFQOU1UDqKuTdBsA//Zry5899fmn8jBUkg4nh09jhHHbLlaUScdz704Zz2+UVg7i
+s/r3Legxap60KzmdrmTAE9VKte1TQRgavQwVX5/2mO/J+SCas//UngI+h8SyOucq
+mjudYEgBrZaodUsagUfn/+AzFNrGLy+al+5nZeHb8JnCfLHWS0M9ZyhgoeO/czyn
+99+5G93VWNv4zfc4KiavHZKrkn8F9pg0ycIZh+OwPT/RE2zq4gTazBMlP3ACIe/p
+olkNaOEa8KvgzW96sjBZpMW49zFmyINYkcj+uaNCJrVGsXgdBmkuRGJNWFZ9r0cG
+woIaxViFBypsz045r1ESfYPlfDOavBhZ/giR/Xocm9CHkPRY2BApMMR0DUCyGETg
+Ql+L3kfdTKzuDjUp2DM9FqysQmaM81YDZufWkMhlZPfHwC7KbNougoLroa5Umeos
+bqAXWmk46SwIdWRPLLqbUpDTKooynZKpSYIkkotdgJoVZUUCY+RCO8jsVPEU6ece
+SxztNUm5UOta1OJPMwSAKRHOo3ilVb9c6lAixDdvV8MeNbqe6asM1mpCHWbJ/0rg
+5Ls9Cxx8hracyp0ev7b0
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIGATCCA+mgAwIBAgIRAI9hcRW6eVgXjH0ROqzW264wDQYJKoZIhvcNAQELBQAw
+RTEfMB0GA1UEAxMWQ29tU2lnbiBHbG9iYWwgUm9vdCBDQTEVMBMGA1UEChMMQ29t
+U2lnbiBMdGQuMQswCQYDVQQGEwJJTDAeFw0xMTA3MTgxMDI0NTRaFw0zNjA3MTYx
+MDI0NTVaMEUxHzAdBgNVBAMTFkNvbVNpZ24gR2xvYmFsIFJvb3QgQ0ExFTATBgNV
+BAoTDENvbVNpZ24gTHRkLjELMAkGA1UEBhMCSUwwggIiMA0GCSqGSIb3DQEBAQUA
+A4ICDwAwggIKAoICAQCyKClzKh3rm6n1nvigmV/VU1D4hSwYW2ro3VqpzpPo0Ph3
+3LguqjXd5juDwN4mpxTpD99d7Xu5X6KGTlMVtfN+bTbA4t3x7DU0Zqn0BE5XuOgs
+3GLH41Vmr5wox1bShVpM+IsjcN4E/hMnDtt/Bkb5s33xCG+ohz5dlq0gA9qfr/g4
+O9lkHZXTCeYrmVzd/il4x79CqNvGkdL3um+OKYl8rg1dPtD8UsytMaDgBAopKR+W
+igc16QJzCbvcinlETlrzP/Ny76BWPnAQgaYBULax/Q5thVU+N3sEOKp6uviTdD+X
+O6i96gARU4H0xxPFI75PK/YdHrHjfjQevXl4J37FJfPMSHAbgPBhHC+qn/014DOx
+46fEGXcdw2BFeIIIwbj2GH70VyJWmuk/xLMCHHpJ/nIF8w25BQtkPpkwESL6esaU
+b1CyB4Vgjyf16/0nRiCAKAyC/DY/Yh+rDWtXK8c6QkXD2XamrVJo43DVNFqGZzbf
+5bsUXqiVDOz71AxqqK+p4ek9374xPNMJ2rB5MLPAPycwI0bUuLHhLy6nAIFHLhut
+TNI+6Y/soYpi5JSaEjcY7pxI8WIkUAzr2r+6UoT0vAdyOt7nt1y8844a7szo/aKf
+woziHl2O1w6ZXUC30K+ptXVaOiW79pBDcbLZ9ZdbONhS7Ea3iH4HJNwktrBJLQID
+AQABo4HrMIHoMA8GA1UdEwEB/wQFMAMBAf8wgYQGA1UdHwR9MHswPKA6oDiGNmh0
+dHA6Ly9mZWRpci5jb21zaWduLmNvLmlsL2NybC9jb21zaWduZ2xvYmFscm9vdGNh
+LmNybDA7oDmgN4Y1aHR0cDovL2NybDEuY29tc2lnbi5jby5pbC9jcmwvY29tc2ln
+bmdsb2JhbHJvb3RjYS5jcmwwDgYDVR0PAQH/BAQDAgGGMB0GA1UdDgQWBBQCRZPY
+DUhirGm6rgZbPvuqJpFQsTAfBgNVHSMEGDAWgBQCRZPYDUhirGm6rgZbPvuqJpFQ
+sTANBgkqhkiG9w0BAQsFAAOCAgEAk1V5V9701xsfy4mfX+tP9Ln5e9h3N+QMwUfj
+kr+k3e8iXOqADjTpUHeBkEee5tJq09ZLp/43F5tZ2eHdYq2ZEX7iWHCnOQet6Yw9
+SU1TahsrGDA6JJD9sdPFnNZooGsU1520e0zNB0dNWwxrWAmu4RsBxvEpWCJbvzQL
+dOfyX85RWwli81OiVMBc5XvJ1mxsIIqli45oRynKtsWP7E+b0ISJ1n+XFLdQo/Nm
+WA/5sDfT0F5YPzWdZymudMbXitimxC+n4oQE4mbQ4Zm718Iwg3pP9gMMcSc7Qc1J
+kJHPH9O7gVubkKHuSYj9T3Ym6c6egL1pb4pz/uT7cT26Fiopc/jdqbe2EAfoJZkv
+hlp/zdzOoXTWjiKNA5zmgWnZn943FuE9KMRyKtyi/ezJXCh8ypnqLIKxeFfZl69C
+BwJsPXUTuqj8Fic0s3aZmmr7C4jXycP+Q8V+akMEIoHAxcd960b4wVWKqOcI/kZS
+Q0cYqWOY1LNjznRt9lweWEfwDBL3FhrHOmD4++1N3FkkM4W+Q1b2WOL24clDMj+i
+2n9Iw0lc1llHMSMvA5D0vpsXZpOgcCVahfXczQKi9wQ3oZyonJeWx4/rXdMtagAB
+VBYGFuMEUEQtybI+eIbnp5peO2WAAblQI4eTy/jMVowe5tfMEXovV3sz9ULgmGb3
+DscLP1I=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIICmDCCAgGgAwIBAgIBDjANBgkqhkiG9w0BAQUFADBLMQswCQYDVQQGEwJVUzEY
+MBYGA1UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNFQ0ExFDASBgNVBAMT
+C0VDQSBSb290IENBMB4XDTA0MDYxNDEwMjAwOVoXDTQwMDYxNDEwMjAwOVowSzEL
+MAkGA1UEBhMCVVMxGDAWBgNVBAoTD1UuUy4gR292ZXJubWVudDEMMAoGA1UECxMD
+RUNBMRQwEgYDVQQDEwtFQ0EgUm9vdCBDQTCBnzANBgkqhkiG9w0BAQEFAAOBjQAw
+gYkCgYEArkr2eXIS6oAKIpDkOlcQZdMGdncoygCEIU+ktqY3of5SVVXU7/it7kJ1
+EUzR4ii2vthQtbww9aAnpQxcEmXZk8eEyiGEPy+cCQMllBY+efOtKgjbQNDZ3lB9
+19qzUJwBl2BMxslU1XsJQw9SK10lPbQm4asa8E8e5zTUknZBWnECAwEAAaOBizCB
+iDAfBgNVHSMEGDAWgBT2uAQnDlYW2blj2f2hVGVBoAhILzAdBgNVHQ4EFgQU9rgE
+Jw5WFtm5Y9n9oVRlQaAISC8wDgYDVR0PAQH/BAQDAgGGMA8GA1UdEwEB/wQFMAMB
+Af8wJQYDVR0gBB4wHDAMBgpghkgBZQMCAQwBMAwGCmCGSAFlAwIBDAIwDQYJKoZI
+hvcNAQEFBQADgYEAHh0EQY2cZ209aBb5q0wW1ER0dc4OGzsLyqjHfaQ4TEaMmUwL
+AJRta/c4KVWLiwbODsvgJk+CaWmSL03gRW/ciVb/qDV7qh9Pyd1cOlanZTAnPog2
+i82yL3i2fK9DCC84uoxEQbgqK2jx9bIjFTwlAqITk9fGAm5mdT84IEwq1Gw=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIDjjCCAnagAwIBAgIQAzrx5qcRqaC7KGSxHQn65TANBgkqhkiG9w0BAQsFADBh
+MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3
+d3cuZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBH
+MjAeFw0xMzA4MDExMjAwMDBaFw0zODAxMTUxMjAwMDBaMGExCzAJBgNVBAYTAlVT
+MRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5j
+b20xIDAeBgNVBAMTF0RpZ2lDZXJ0IEdsb2JhbCBSb290IEcyMIIBIjANBgkqhkiG
+9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuzfNNNx7a8myaJCtSnX/RrohCgiN9RlUyfuI
+2/Ou8jqJkTx65qsGGmvPrC3oXgkkRLpimn7Wo6h+4FR1IAWsULecYxpsMNzaHxmx
+1x7e/dfgy5SDN67sH0NO3Xss0r0upS/kqbitOtSZpLYl6ZtrAGCSYP9PIUkY92eQ
+q2EGnI/yuum06ZIya7XzV+hdG82MHauVBJVJ8zUtluNJbd134/tJS7SsVQepj5Wz
+tCO7TG1F8PapspUwtP1MVYwnSlcUfIKdzXOS0xZKBgyMUNGPHgm+F6HmIcr9g+UQ
+vIOlCsRnKPZzFBQ9RnbDhxSJITRNrw9FDKZJobq7nMWxM4MphQIDAQABo0IwQDAP
+BgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBhjAdBgNVHQ4EFgQUTiJUIBiV
+5uNu5g/6+rkS7QYXjzkwDQYJKoZIhvcNAQELBQADggEBAGBnKJRvDkhj6zHd6mcY
+1Yl9PMWLSn/pvtsrF9+wX3N3KjITOYFnQoQj8kVnNeyIv/iPsGEMNKSuIEyExtv4
+NeF22d+mQrvHRAiGfzZ0JFrabA0UWTW98kndth/Jsw1HKj2ZL7tcu7XUIOGZX1NG
+Fdtom/DzMNU+MeKNhJ7jitralj41E6Vf8PlwUHBHQRFXGU7Aj64GxJUTFy8bJZ91
+8rGOmaFvE7FBcf6IKshPECBV1/MUReXgRPTqh5Uykw7+U0b6LJ3/iyK5S9kJRaTe
+pLiaWN0bfVKfjllDiIGknibVb63dDcY3fe0Dkhvld1927jyNxF1WW6LZZm6zNTfl
+MrY=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIFSzCCAzOgAwIBAgIRALZLiAfiI+7IXBKtpg4GofIwDQYJKoZIhvcNAQELBQAw
+PzELMAkGA1UEBhMCVFcxMDAuBgNVBAoMJ0dvdmVybm1lbnQgUm9vdCBDZXJ0aWZp
+Y2F0aW9uIEF1dGhvcml0eTAeFw0xMjA5MjgwODU4NTFaFw0zNzEyMzExNTU5NTla
+MD8xCzAJBgNVBAYTAlRXMTAwLgYDVQQKDCdHb3Zlcm5tZW50IFJvb3QgQ2VydGlm
+aWNhdGlvbiBBdXRob3JpdHkwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoIC
+AQC2/5c8gb4BWCQnr44BK9ZykjAyG1+bfNTUf+ihYHMwVxAA+lCWJP5Q5ow6ldFX
+eYTVZ1MMKoI+GFy4MCYa1l7GLbIEUQ7v3wxjR+vEEghRK5lxXtVpe+FdyXcdIOxW
+juVhYC386RyA3/pqg7sFtR4jEpyCygrzFB0g5AaPQySZn7YKk1pzGxY5vgW28Yyl
+ZJKPBeRcdvc5w88tvQ7Yy6gOMZvJRg9nU0MEj8iyyIOAX7ryD6uBNaIgIZfOD4k0
+eA/PH07p+4woPN405+2f0mb1xcoxeNLOUNFggmOd4Ez3B66DNJ1JSUPUfr0t4urH
+cWWACOQ2nnlwCjyHKenkkpTqBpIpJ3jmrdc96QoLXvTg1oadLXLLi2RW5vSueKWg
+OTNYPNyoj420ai39iHPplVBzBN8RiD5C1gJ0+yzEb7xs1uCAb9GGpTJXA9ZN9E4K
+mSJ2fkpAgvjJ5E7LUy3Hsbbi08J1J265DnGyNPy/HE7CPfg26QrMWJqhGIZO4uGq
+s3NZbl6dtMIIr69c/aQCb/+4DbvVq9dunxpPkUDwH0ZVbaCSw4nNt7H/HLPLo5wK
+4/7NqrwB7N1UypHdTxOHpPaY7/1J1lcqPKZc9mA3v9g+fk5oKiMyOr5u5CI9ByTP
+isubXVGzMNJxbc5Gim18SjNE2hIvNkvy6fFRCW3bapcOFwIDAQABo0IwQDAPBgNV
+HRMBAf8EBTADAQH/MB0GA1UdDgQWBBTVZx3gnHosnMvFmOcdByYqhux0zTAOBgNV
+HQ8BAf8EBAMCAQYwDQYJKoZIhvcNAQELBQADggIBAJA75cJTQijq9TFOjj2Rnk0J
+89ixUuZPrAwxIbvx6pnMg/y2KOTshAcOD06Xu29oRo8OURWV+Do7H1+CDgxxDryR
+T64zLiNB9CZrTxOH+nj2LsIPkQWXqmrBap+8hJ4IKifd2ocXhuGzyl3tOKkpboTe
+Rmv8JxlQpRJ6jH1i/NrnzLyfSa8GuCcn8on3Fj0Y5r3e9YwSkZ/jBI3+BxQaWqw5
+ghvxOBnhY+OvbLamURfr+kvriyL2l/4QOl+UoEtTcT9a4RD4co+WgN2NApgAYT2N
+vC2xR8zaXeEgp4wxXPHj2rkKhkfIoT0Hozymc26Uke1uJDr5yTDRB6iBfSZ9fYTf
+hsmL5a4NHr6JSFEVg5iWL0rrczTXdM3Jb9DCuiv2mv6Z3WAUjhv5nDk8f0OJU+jl
+wqu+Iq0nOJt3KLejY2OngeepaUXrjnhWzAWEx/uttjB8YwWfLYwkf0uLkvw4Hp+g
+pVezbp3YZLhwmmBScMip0P/GnO0QYV7Ngw5u6E0CQUridgR51lQ/ipgyFKDdLZzn
+uoJxo4ZVKZnSKdt1OvfbQ/+2W/u3fjWAjg1srnm3Ni2XUqGwB5wH5Ss2zQOXlL0t
+DjQG/MAWifw3VOTWzz0TBPKR2ck2Lj7FWtClTILD/y58Jnb38/1FoqVuVa4uzM8s
+iTTa9g3nkagQ6hed8vbs
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIB/jCCAYWgAwIBAgIIdJclisc/elQwCgYIKoZIzj0EAwMwRTELMAkGA1UEBhMC
+VVMxFDASBgNVBAoMC0FmZmlybVRydXN0MSAwHgYDVQQDDBdBZmZpcm1UcnVzdCBQ
+cmVtaXVtIEVDQzAeFw0xMDAxMjkxNDIwMjRaFw00MDEyMzExNDIwMjRaMEUxCzAJ
+BgNVBAYTAlVTMRQwEgYDVQQKDAtBZmZpcm1UcnVzdDEgMB4GA1UEAwwXQWZmaXJt
+VHJ1c3QgUHJlbWl1bSBFQ0MwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAAQNMF4bFZ0D
+0KF5Nbc6PJJ6yhUczWLznCZcBz3lVPqj1swS6vQUX+iOGasvLkjmrBhDeKzQN8O9
+ss0s5kfiGuZjuD0uL3jET9v0D6RoTFVya5UdThhClXjMNzyR4ptlKymjQjBAMB0G
+A1UdDgQWBBSaryl6wBE1NSZRMADDav5A1a7WPDAPBgNVHRMBAf8EBTADAQH/MA4G
+A1UdDwEB/wQEAwIBBjAKBggqhkjOPQQDAwNnADBkAjAXCfOHiFBar8jAQr9HX/Vs
+aobgxCd05DhT1wV/GzTjxi+zygk8N53X57hG8f2h4nECMEJZh0PUUd+60wkyWs6I
+flc9nF9Ca/UHLbXwgpP5WW+uZPpY5Yse42O+tYHNbwKMeQ==
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIFWTCCA0GgAwIBAgIBAjANBgkqhkiG9w0BAQsFADBOMQswCQYDVQQGEwJOTzEd
+MBsGA1UECgwUQnV5cGFzcyBBUy05ODMxNjMzMjcxIDAeBgNVBAMMF0J1eXBhc3Mg
+Q2xhc3MgMiBSb290IENBMB4XDTEwMTAyNjA4MzgwM1oXDTQwMTAyNjA4MzgwM1ow
+TjELMAkGA1UEBhMCTk8xHTAbBgNVBAoMFEJ1eXBhc3MgQVMtOTgzMTYzMzI3MSAw
+HgYDVQQDDBdCdXlwYXNzIENsYXNzIDIgUm9vdCBDQTCCAiIwDQYJKoZIhvcNAQEB
+BQADggIPADCCAgoCggIBANfHXvfBB9R3+0Mh9PT1aeTuMgHbo4Yf5FkNuud1g1Lr
+6hxhFUi7HQfKjK6w3Jad6sNgkoaCKHOcVgb/S2TwDCo3SbXlzwx87vFKu3MwZfPV
+L4O2fuPn9Z6rYPnT8Z2SdIrkHJasW4DptfQxh6NR/Md+oW+OU3fUl8FVM5I+GC91
+1K2GScuVr1QGbNgGE41b/+EmGVnAJLqBcXmQRFBoJJRfuLMR8SlBYaNByyM21cHx
+MlAQTn/0hpPshNOOvEu/XAFOBz3cFIqUCqTqc/sLUegTBxj6DvEr0VQVfTzh97QZ
+QmdiXnfgolXsttlpF9U6r0TtSsWe5HonfOV116rLJeffawrbD02TTqigzXsu8lkB
+arcNuAeBfos4GzjmCleZPe4h6KP1DBbdi+w0jpwqHAAVF41og9JwnxgIzRFo1clr
+Us3ERo/ctfPYV3Me6ZQ5BL/T3jjetFPsaRyifsSP5BtwrfKi+fv3FmRmaZ9JUaLi
+FRhnBkp/1Wy1TbMz4GHrXb7pmA8y1x1LPC5aAVKRCfLf6o3YBkBjqhHk/sM3nhRS
+P/TizPJhk9H9Z2vXUq6/aKtAQ6BXNVN48FP4YUIHZMbXb5tMOA1jrGKvNouicwoN
+9SG9dKpN6nIDSdvHXx1iY8f93ZHsM+71bbRuMGjeyNYmsHVee7QHIJihdjK4TWxP
+AgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFMmAd+BikoL1Rpzz
+uvdMw964o605MA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQsFAAOCAgEAU18h
+9bqwOlI5LJKwbADJ784g7wbylp7ppHR/ehb8t/W2+xUbP6umwHJdELFx7rxP462s
+A20ucS6vxOOto70MEae0/0qyexAQH6dXQbLArvQsWdZHEIjzIVEpMMpghq9Gqx3t
+OluwlN5E40EIosHsHdb9T7bWR9AUC8rmyrV7d35BH16Dx7aMOZawP5aBQW9gkOLo
++fsicdl9sz1Gv7SEr5AcD48Saq/v7h56rgJKihcrdv6sVIkkLE8/trKnToyokZf7
+KcZ7XC25y2a2t6hbElGFtQl+Ynhw/qlqYLYdDnkM/crqJIByw5c/8nerQyIKx+u2
+DISCLIBrQYoIwOula9+ZEsuK1V6ADJHgJgg2SMX6OBE1/yWDLfJ6v9r9jv6ly0Us
+H8SIU653DtmadsWOLB2jutXsMq7Aqqz30XpN69QH4kj3Io6wpJ9qzo6ysmD0oyLQ
+I+uUWnpp3Q+/QFesa1lQ2aOZ4W7+jQF5JyMV3pKdewlNWudLSDBaGOYKbeaP4NK7
+5t98biGCwWg5TbSYWGZizEqQXsP6JwSxeRV0mcy+rSDeJmAc61ZRpqPq5KM/p/9h
+3PFaTWwyI0PurKju7koSCTxdccK+efrCh2gdC/1cacwG0Jp9VJkqyTkaGa9LKkPz
+Y11aWOIv4x3kqdbQCtCev9eBCfHJxyYNrJgWVqA=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIFaTCCA1GgAwIBAgIJAMMDmu5QkG4oMA0GCSqGSIb3DQEBBQUAMFIxCzAJBgNV
+BAYTAlNLMRMwEQYDVQQHEwpCcmF0aXNsYXZhMRMwEQYDVQQKEwpEaXNpZyBhLnMu
+MRkwFwYDVQQDExBDQSBEaXNpZyBSb290IFIxMB4XDTEyMDcxOTA5MDY1NloXDTQy
+MDcxOTA5MDY1NlowUjELMAkGA1UEBhMCU0sxEzARBgNVBAcTCkJyYXRpc2xhdmEx
+EzARBgNVBAoTCkRpc2lnIGEucy4xGTAXBgNVBAMTEENBIERpc2lnIFJvb3QgUjEw
+ggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCqw3j33Jijp1pedxiy3QRk
+D2P9m5YJgNXoqqXinCaUOuiZc4yd39ffg/N4T0Dhf9Kn0uXKE5Pn7cZ3Xza1lK/o
+OI7bm+V8u8yN63Vz4STN5qctGS7Y1oprFOsIYgrY3LMATcMjfF9DCCMyEtztDK3A
+fQ+lekLZWnDZv6fXARz2m6uOt0qGeKAeVjGu74IKgEH3G8muqzIm1Cxr7X1r5OJe
+IgpFy4QxTaz+29FHuvlglzmxZcfe+5nkCiKxLU3lSCZpq+Kq8/v8kiky6bM+TR8n
+oc2OuRf7JT7JbvN32g0S9l3HuzYQ1VTW8+DiR0jm3hTaYVKvJrT1cU/J19IG32PK
+/yHoWQbgCNWEFVP3Q+V8xaCJmGtzxmjOZd69fwX3se72V6FglcXM6pM6vpmumwKj
+rckWtc7dXpl4fho5frLABaTAgqWjR56M6ly2vGfb5ipN0gTco65F97yLnByn1tUD
+3AjLLhbKXEAz6GfDLuemROoRRRw1ZS0eRWEkG4IupZ0zXWX4Qfkuy5Q/H6MMMSRE
+7cderVC6xkGbrPAXZcD4XW9boAo0PO7X6oifmPmvTiT6l7Jkdtqr9O3jw2Dv1fkC
+yC2fg69naQanMVXVz0tv/wQFx1isXxYb5dKj6zHbHzMVTdDypVP1y+E9Tmgt2BLd
+qvLmTZtJ5cUoobqwWsagtQIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1Ud
+DwEB/wQEAwIBBjAdBgNVHQ4EFgQUiQq0OJMa5qvum5EY+fU8PjXQ04IwDQYJKoZI
+hvcNAQEFBQADggIBADKL9p1Kyb4U5YysOMo6CdQbzoaz3evUuii+Eq5FLAR0rBNR
+xVgYZk2C2tXck8An4b58n1KeElb21Zyp9HWc+jcSjxyT7Ff+Bw+r1RL3D65hXlaA
+SfX8MPWbTx9BLxyE04nH4toCdu0Jz2zBuByDHBb6lM19oMgY0sidbvW9adRtPTXo
+HqJPYNcHKfyyo6SdbhWSVhlMCrDpfNIZTUJG7L399ldb3Zh+pE3McgODWF3vkzpB
+emOqfDqo9ayk0d2iLbYq/J8BjuIQscTK5GfbVSUZP/3oNn6z4eGBrxEWi1CXYBmC
+AMBrTXO40RMHPuq2MU/wQppt4hF05ZSsjYSVPCGvxdpHyN85YmLLW1AL14FABZyb
+7bq2ix4Eb5YgOe2kfSnbSM6C3NQCjR0EMVrHS/BsYVLXtFHCgWzN4funodKSds+x
+DzdYpPJScWc/DIh4gInByLUfkmO+p3qKViwaqKactV2zY9ATIKHrkWzQjX2v3wvk
+F7mGnjixlAxYjOBVqjtjbZqJYLhkKpLGN/R+Q0O3c+gB53+XD9fyexn9GtePyfqF
+a3qdnom2piiZk4hA9z7NUaPK6u95RyG1/jLix8NRb76AdPCkwzryT+lf3xkK8jsT
+Q6wxpLPn6/wY1gGp8yqPNg7rtLG8t0zJa7+h89n07eLw4+1knj0vllJPgFOL
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIID9jCCAt6gAwIBAgIQJDJ18h0v0gkz97RqytDzmDANBgkqhkiG9w0BAQsFADCB
+lDELMAkGA1UEBhMCVVMxHTAbBgNVBAoTFFN5bWFudGVjIENvcnBvcmF0aW9uMR8w
+HQYDVQQLExZTeW1hbnRlYyBUcnVzdCBOZXR3b3JrMUUwQwYDVQQDEzxTeW1hbnRl
+YyBDbGFzcyAxIFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5
+IC0gRzYwHhcNMTExMDE4MDAwMDAwWhcNMzcxMjAxMjM1OTU5WjCBlDELMAkGA1UE
+BhMCVVMxHTAbBgNVBAoTFFN5bWFudGVjIENvcnBvcmF0aW9uMR8wHQYDVQQLExZT
+eW1hbnRlYyBUcnVzdCBOZXR3b3JrMUUwQwYDVQQDEzxTeW1hbnRlYyBDbGFzcyAx
+IFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IC0gRzYwggEi
+MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDHOddJZKmZgiJM6kXZBxbje/SD
+6Jlz+muxNuCad6BAwoGNAcfMjL2Pffd543pMA03Z+/2HOCgs3ZqLVAjbZ/sbjP4o
+ki++t7JIp4Gh2F6Iw8w5QEFa0dzl2hCfL9oBTf0uRnz5LicKaTfukaMbasxEvxvH
+w9QRslBglwm9LiL1QYRmn81ApqkAgMEflZKf3vNI79sdd2H8f9/ulqRy0LY+/3gn
+r8uSFWkI22MQ4uaXrG7crPaizh5HmbmJtxLmodTNWRFnw2+F2EJOKL5ZVVkElauP
+N4C/DfD8HzpkMViBeNfiNfYgPym4jxZuPkjctUwH4fIa6n4KedaovetdhitNAgMB
+AAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQW
+BBQzQejIORIVk0jyljIuWvXalF9TYDANBgkqhkiG9w0BAQsFAAOCAQEAFeNzV7EX
+tl9JaUSm9l56Z6zS3nVJq/4lVcc6yUQVEG6/MWvL2QeTfxyFYwDjMhLgzMv7OWyP
+4lPiPEAz2aSMR+atWPuJr+PehilWNCxFuBL6RIluLRQlKCQBZdbqUqwFblYSCT3Q
+dPTXvQbKqDqNVkL6jXI+dPEDct+HG14OelWWLDi3mIXNTTNEyZSPWjEwN0ujOhKz
+5zbRIWhLLTjmU64cJVYIVgNnhJ3Gw84kYsdMNs+wBkS39V8C3dlU6S+QTnrIToNA
+DJqXPDe/v+z28LSFdyjBC8hnghAXOKK3Buqbvzr46SMHv3TgmDgVVXjucgBcGaP0
+0jPg/73RVDkpDw==
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIFaTCCA1GgAwIBAgIJAJK4iNuwisFjMA0GCSqGSIb3DQEBCwUAMFIxCzAJBgNV
+BAYTAlNLMRMwEQYDVQQHEwpCcmF0aXNsYXZhMRMwEQYDVQQKEwpEaXNpZyBhLnMu
+MRkwFwYDVQQDExBDQSBEaXNpZyBSb290IFIyMB4XDTEyMDcxOTA5MTUzMFoXDTQy
+MDcxOTA5MTUzMFowUjELMAkGA1UEBhMCU0sxEzARBgNVBAcTCkJyYXRpc2xhdmEx
+EzARBgNVBAoTCkRpc2lnIGEucy4xGTAXBgNVBAMTEENBIERpc2lnIFJvb3QgUjIw
+ggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCio8QACdaFXS1tFPbCw3Oe
+NcJxVX6B+6tGUODBfEl45qt5WDza/3wcn9iXAng+a0EE6UG9vgMsRfYvZNSrXaNH
+PWSb6WiaxswbP7q+sos0Ai6YVRn8jG+qX9pMzk0DIaPY0jSTVpbLTAwAFjxfGs3I
+x2ymrdMxp7zo5eFm1tL7A7RBZckQrg4FY8aAamkw/dLukO8NJ9+flXP04SXabBbe
+QTg06ov80egEFGEtQX6sx3dOy1FU+16SGBsEWmjGycT6txOgmLcRK7fWV8x8nhfR
+yyX+hk4kLlYMeE2eARKmK6cBZW58Yh2EhN/qwGu1pSqVg8NTEQxzHQuyRpDRQjrO
+QG6Vrf/GlK1ul4SOfW+eioANSW1z4nuSHsPzwfPrLgVv2RvPN3YEyLRa5Beny912
+H9AZdugsBbPWnDTYltxhh5EF5EQIM8HauQhl1K6yNg3ruji6DOWbnuuNZt2Zz9aJ
+QfYEkoopKW1rOhzndX0CcQ7zwOe9yxndnWCywmZgtrEE7snmhrmaZkCo5xHtgUUD
+i/ZnWejBBhG93c+AAk9lQHhcR1DIm+YfgXvkRKhbhZri3lrVx/k6RGZL5DJUfORs
+nLMOPReisjQS1n6yqEm70XooQL6iFh/f5DcfEXP7kAplQ6INfPgGAVUzfbANuPT1
+rqVCV3w2EYx7XsQDnYx5nQIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1Ud
+DwEB/wQEAwIBBjAdBgNVHQ4EFgQUtZn4r7CU9eMg1gqtzk5WpC5uQu0wDQYJKoZI
+hvcNAQELBQADggIBACYGXnDnZTPIgm7ZnBc6G3pmsgH2eDtpXi/q/075KMOYKmFM
+tCQSin1tERT3nLXK5ryeJ45MGcipvXrA1zYObYVybqjGom32+nNjf7xueQgcnYqf
+GopTpti72TVVsRHFqQOzVju5hJMiXn7B9hJSi+osZ7z+Nkz1uM/Rs0mSO9MpDpkb
+lvdhuDvEK7Z4bLQjb/D907JedR+Zlais9trhxTF7+9FGs9K8Z7RiVLoJ92Owk6Ka
++elSLotgEqv89WBW7xBci8QaQtyDW2QOy7W81k/BfDxujRNt+3vrMNDcTa/F1bal
+TFtxyegxvug4BkihGuLq0t4SOVga/4AOgnXmt8kHbA7v/zjxmHHEt38OFdAlab0i
+nSvtBfZGR6ztwPDUO+Ls7pZbkBNOHlY667DvlruWIxG68kOGdGSVyCh13x01utI3
+gzhTODY7z2zp+WsO0PsE6E9312UBeIYMej4hYvF/Y3EMyZ9E26gnonW+boE+18Dr
+G5gPcFw0sorMwIUY6256s/daoQe/qUKS82Ail+QUoQebTnbAjn39pCXHR+3/H3Os
+zMOl6W8KjptlwlCFtaOgUxLMVYdh84GuEEZhvUQhuMI9dM9+JDX6HAcOmz0iyu8x
+L4ysEr3vQCj8KWefshNPZiTEUxnpHikV7+ZtsH8tZ/3zbBt1RqPlShfppNcL
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIEADCCAuigAwIBAgIBADANBgkqhkiG9w0BAQUFADBjMQswCQYDVQQGEwJVUzEh
+MB8GA1UEChMYVGhlIEdvIERhZGR5IEdyb3VwLCBJbmMuMTEwLwYDVQQLEyhHbyBE
+YWRkeSBDbGFzcyAyIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTA0MDYyOTE3
+MDYyMFoXDTM0MDYyOTE3MDYyMFowYzELMAkGA1UEBhMCVVMxITAfBgNVBAoTGFRo
+ZSBHbyBEYWRkeSBHcm91cCwgSW5jLjExMC8GA1UECxMoR28gRGFkZHkgQ2xhc3Mg
+MiBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTCCASAwDQYJKoZIhvcNAQEBBQADggEN
+ADCCAQgCggEBAN6d1+pXGEmhW+vXX0iG6r7d/+TvZxz0ZWizV3GgXne77ZtJ6XCA
+PVYYYwhv2vLM0D9/AlQiVBDYsoHUwHU9S3/Hd8M+eKsaA7Ugay9qK7HFiH7Eux6w
+wdhFJ2+qN1j3hybX2C32qRe3H3I2TqYXP2WYktsqbl2i/ojgC95/5Y0V4evLOtXi
+EqITLdiOr18SPaAIBQi2XKVlOARFmR6jYGB0xUGlcmIbYsUfb18aQr4CUWWoriMY
+avx4A6lNf4DD+qta/KFApMoZFv6yyO9ecw3ud72a9nmYvLEHZ6IVDd2gWMZEewo+
+YihfukEHU1jPEX44dMX4/7VpkI+EdOqXG68CAQOjgcAwgb0wHQYDVR0OBBYEFNLE
+sNKR1EwRcbNhyz2h/t2oatTjMIGNBgNVHSMEgYUwgYKAFNLEsNKR1EwRcbNhyz2h
+/t2oatTjoWekZTBjMQswCQYDVQQGEwJVUzEhMB8GA1UEChMYVGhlIEdvIERhZGR5
+IEdyb3VwLCBJbmMuMTEwLwYDVQQLEyhHbyBEYWRkeSBDbGFzcyAyIENlcnRpZmlj
+YXRpb24gQXV0aG9yaXR5ggEAMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQAD
+ggEBADJL87LKPpH8EsahB4yOd6AzBhRckB4Y9wimPQoZ+YeAEW5p5JYXMP80kWNy
+OO7MHAGjHZQopDH2esRU1/blMVgDoszOYtuURXO1v0XJJLXVggKtI3lpjbi2Tc7P
+TMozI+gciKqdi0FuFskg5YmezTvacPd+mSYgFFQlq25zheabIZ0KbIIOqPjCDPoQ
+HmyW74cNxA9hi63ugyuV+I6ShHI56yDqg+2DzZduCLzrTia2cyvk0/ZM/iZx4mER
+dEr/VxqHD3VILs9RaRegAhJhldXRQLIQTO7ErBBDpqWeCtWVYpoNz4iCxTIM5Cuf
+ReYNnyicsbkqWletNw+vHX/bvZ8=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIEGjCCAwKgAwIBAgIDAYagMA0GCSqGSIb3DQEBBQUAMIGjMQswCQYDVQQGEwJG
+STEQMA4GA1UECBMHRmlubGFuZDEhMB8GA1UEChMYVmFlc3RvcmVraXN0ZXJpa2Vz
+a3VzIENBMSkwJwYDVQQLEyBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSBTZXJ2aWNl
+czEZMBcGA1UECxMQVmFybWVubmVwYWx2ZWx1dDEZMBcGA1UEAxMQVlJLIEdvdi4g
+Um9vdCBDQTAeFw0wMjEyMTgxMzUzMDBaFw0yMzEyMTgxMzUxMDhaMIGjMQswCQYD
+VQQGEwJGSTEQMA4GA1UECBMHRmlubGFuZDEhMB8GA1UEChMYVmFlc3RvcmVraXN0
+ZXJpa2Vza3VzIENBMSkwJwYDVQQLEyBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSBT
+ZXJ2aWNlczEZMBcGA1UECxMQVmFybWVubmVwYWx2ZWx1dDEZMBcGA1UEAxMQVlJL
+IEdvdi4gUm9vdCBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALCF
+FdrIAzfQo0Y3bBseljDCWoUSZyPyu5/nioFgJ/gTqTy894aqqvTzJSm0/nWuHoGG
+igWyHWWyOOi0zCia+xc28ZPVec7Bg4shT8MNrUHfeJ1I4x9CRPw8bSEga60ihCRC
+jxdNwlAfZM0tOSJWiP2yY51U2kJpwMhP1xjiPshphJQ9LIDGfM6911Mf64i5psu7
+hVfvV3ZdDIvTXhJBnyHAOfQmbQj6OLOhd7HuFtjQaNq0mKWgZUZKa41+qk1guPjI
+DfxxPu45h4G02fhukO4/DmHXHSto5i7hQkQmeCxY8n0Wf2HASSQqiYe2XS8pGfim
+545SnkFLWg6quMJmQlMCAwEAAaNVMFMwDwYDVR0TAQH/BAUwAwEB/zARBglghkgB
+hvhCAQEEBAMCAAcwDgYDVR0PAQH/BAQDAgHGMB0GA1UdDgQWBBTb6eGb0tEkC/yr
+46Bn6q6cS3f0sDANBgkqhkiG9w0BAQUFAAOCAQEArX1ID1QRnljurw2bEi8hpM2b
+uoRH5sklVSPj3xhYKizbXvfNVPVRJHtiZ+GxH0mvNNDrsczZog1Sf0JLiGCXzyVy
+t08pLWKfT6HAVVdWDsRol5EfnGTCKTIB6dTI2riBmCguGMcs/OubUpbf9MiQGS0j
+8/G7cdqehSO9Gu8u5Hp5t8OdhkktY7ktdM9lDzJmid87Ie4pbzlj2RXBbvbfgD5Q
+eBmK3QOjFKU3p7UsfLYRh+cF8ry23tT/l4EohP7+bEaFEEGfTXWMB9SZZ291im/k
+UJL2mdUQuMSpe/cXjUu/15WfCdxEDx4yw8DP03kN5Mc7h/CQNIghYkmSBAQfvA==
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIDujCCAqKgAwIBAgIEAJiWijANBgkqhkiG9w0BAQUFADBVMQswCQYDVQQGEwJO
+TDEeMBwGA1UEChMVU3RhYXQgZGVyIE5lZGVybGFuZGVuMSYwJAYDVQQDEx1TdGFh
+dCBkZXIgTmVkZXJsYW5kZW4gUm9vdCBDQTAeFw0wMjEyMTcwOTIzNDlaFw0xNTEy
+MTYwOTE1MzhaMFUxCzAJBgNVBAYTAk5MMR4wHAYDVQQKExVTdGFhdCBkZXIgTmVk
+ZXJsYW5kZW4xJjAkBgNVBAMTHVN0YWF0IGRlciBOZWRlcmxhbmRlbiBSb290IENB
+MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAmNK1URF6gaYUmHFtvszn
+ExvWJw56s2oYHLZhWtVhCb/ekBPHZ+7d89rFDBKeNVU+LCeIQGv33N0iYfXCxw71
+9tV2U02PjLwYdjeFnejKScfST5gTCaI+Ioicf9byEGW07l8Y1Rfj+MX94p2i71MO
+hXeiD+EwR+4A5zN9RGcaC1Hoi6CeUJhoNFIfLm0B8mBF8jHrqTFoKbt6QZ7GGX+U
+tFE5A3+y3qcym7RHjm+0Sq7lr7HcsBthvJly3uSJt3omXdozSVtSnA71iq3DuD3o
+BmrC1SoLbHuEvVYFy4ZlkuxEK7COudxwC0barbxjiDn622r+I/q85Ej0ZytqERAh
+SQIDAQABo4GRMIGOMAwGA1UdEwQFMAMBAf8wTwYDVR0gBEgwRjBEBgRVHSAAMDww
+OgYIKwYBBQUHAgEWLmh0dHA6Ly93d3cucGtpb3ZlcmhlaWQubmwvcG9saWNpZXMv
+cm9vdC1wb2xpY3kwDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBSofeu8Y6R0E3QA
+7Jbg0zTBLL9s+DANBgkqhkiG9w0BAQUFAAOCAQEABYSHVXQ2YcG70dTGFagTtJ+k
+/rvuFbQvBgwp8qiSpGEN/KtcCFtREytNwiphyPgJWPwtArI5fZlmgb9uXJVFIGzm
+eafR2Bwp/MIgJ1HI8XxdNGdphREwxgDS1/PTfLbwMVcoEoJz6TMvplW0C5GUR5z6
+u3pCMuiufi3IvKwUv9kP2Vv8wfl6leF9fpb8cbDCTMjfRTTJzg3ynGQI0DvDKcWy
+7ZAEwbEpkcUwb8GpcjPM/l0WFywRaed+/sWDCN+83CI6LiBpIzlWYGeQiy52OfsR
+iJf2fL1LuCAWZwWN4jvBcj+UlTfHXbme2JOhF4//DGYVwSR8MnwDHTuhWEUykw==
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIDdzCCAl+gAwIBAgIBADANBgkqhkiG9w0BAQsFADBdMQswCQYDVQQGEwJKUDEl
+MCMGA1UEChMcU0VDT00gVHJ1c3QgU3lzdGVtcyBDTy4sTFRELjEnMCUGA1UECxMe
+U2VjdXJpdHkgQ29tbXVuaWNhdGlvbiBSb290Q0EyMB4XDTA5MDUyOTA1MDAzOVoX
+DTI5MDUyOTA1MDAzOVowXTELMAkGA1UEBhMCSlAxJTAjBgNVBAoTHFNFQ09NIFRy
+dXN0IFN5c3RlbXMgQ08uLExURC4xJzAlBgNVBAsTHlNlY3VyaXR5IENvbW11bmlj
+YXRpb24gUm9vdENBMjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANAV
+OVKxUrO6xVmCxF1SrjpDZYBLx/KWvNs2l9amZIyoXvDjChz335c9S672XewhtUGr
+zbl+dp+++T42NKA7wfYxEUV0kz1XgMX5iZnK5atq1LXaQZAQwdbWQonCv/Q4EpVM
+VAX3NuRFg3sUZdbcDE3R3n4MqzvEFb46VqZab3ZpUql6ucjrappdUtAtCms1FgkQ
+hNBqyjoGADdH5H5XTz+L62e4iKrFvlNVspHEfbmwhRkGeC7bYRr6hfVKkaHnFtWO
+ojnflLhwHyg/i/xAXmODPIMqGplrz95Zajv8bxbXH/1KEOtOghY6rCcMU/Gt1SSw
+awNQwS08Ft1ENCcadfsCAwEAAaNCMEAwHQYDVR0OBBYEFAqFqXdlBZh8QIH4D5cs
+OPEK7DzPMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3
+DQEBCwUAA4IBAQBMOqNErLlFsceTfsgLCkLfZOoc7llsCLqJX2rKSpWeeo8HxdpF
+coJxDjrSzG+ntKEju/Ykn8sX/oymzsLS28yN/HH8AynBbF0zX2S2ZTuJbxh2ePXc
+okgfGT+Ok+vx+hfuzU7jBBJV1uXk3fs+BXziHV7Gp7yXT2g69ekuCkO2r1dcYmh8
+t/2jioSgrGK+KwmHNPBqAbubKVY8/gA3zyNs8U6qtnRGEmyR7jTV7JqR50S+kDFy
+1UkC9gLl9B/rfNmWVan/7Ir5mUf/NVoCqgTLiluHcSmRvaS0eg29mvVXIwAHIRc/
+SjnRBUkLp7Y3gaVdjKozXoEofKd9J+sAro03
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIEHjCCAwagAwIBAgIBATANBgkqhkiG9w0BAQUFADBnMQswCQYDVQQGEwJTRTEU
+MBIGA1UEChMLQWRkVHJ1c3QgQUIxHTAbBgNVBAsTFEFkZFRydXN0IFRUUCBOZXR3
+b3JrMSMwIQYDVQQDExpBZGRUcnVzdCBRdWFsaWZpZWQgQ0EgUm9vdDAeFw0wMDA1
+MzAxMDQ0NTBaFw0yMDA1MzAxMDQ0NTBaMGcxCzAJBgNVBAYTAlNFMRQwEgYDVQQK
+EwtBZGRUcnVzdCBBQjEdMBsGA1UECxMUQWRkVHJ1c3QgVFRQIE5ldHdvcmsxIzAh
+BgNVBAMTGkFkZFRydXN0IFF1YWxpZmllZCBDQSBSb290MIIBIjANBgkqhkiG9w0B
+AQEFAAOCAQ8AMIIBCgKCAQEA5B6a/twJWoekn0e+EV+vhDTbYjx5eLfpMLXsDBwq
+xBb/4Oxx64r1EW7tTw2R0hIYLUkVAcKkIhPHEWT/IhKauY5cLwjPcWqzZwFZ8V1G
+87B4pfYOQnrjfxvM0PC3KP0q6p6zsLkEqv32x7SxuCqg+1jxGaBvcCV+PmlKfw8i
+2O+tCBGaKZnhqkRFmhJePp1tUvznoD1oL/BLcHwTOK28FSXx1s6rosAx1i+f4P8U
+WfyEk9mHfExUE+uf0S0R+Bg6Ot4l2ffTQO2kBhLEO+GRwVY18BTcZTYJbqukB8c1
+0cIDMzZbdSZtQvESa0NvS3GU+jQd7RNuyoB/mC9suWXY6QIDAQABo4HUMIHRMB0G
+A1UdDgQWBBQ5lYtii1zJ1IC6WA+XPxUIQ8yYpzALBgNVHQ8EBAMCAQYwDwYDVR0T
+AQH/BAUwAwEB/zCBkQYDVR0jBIGJMIGGgBQ5lYtii1zJ1IC6WA+XPxUIQ8yYp6Fr
+pGkwZzELMAkGA1UEBhMCU0UxFDASBgNVBAoTC0FkZFRydXN0IEFCMR0wGwYDVQQL
+ExRBZGRUcnVzdCBUVFAgTmV0d29yazEjMCEGA1UEAxMaQWRkVHJ1c3QgUXVhbGlm
+aWVkIENBIFJvb3SCAQEwDQYJKoZIhvcNAQEFBQADggEBABmrder4i2VhlRO6aQTv
+hsoToMeqT2QbPxj2qC0sVY8FtzDqQmodwCVRLae/DLPt7wh/bDxGGuoYQ992zPlm
+hpwsaPXpF/gxsxjE1kh9I0xowX67ARRvxdlu3rsEQmr49lx95dr6h+sNNVJn0J6X
+dgWTP5XHAeZpVTh/EGGZyeNfpso+gmNIquIISD6q8rKFYqa0p9m9N5xotS1WfbC3
+P6CxB9bpT9zeRXEwMn8bLgn5v1Kh7sKAPgZcLlVAwRv1cEWw3F369nJad9Jjzc9Y
+iQBCYz95OdBEsIJuQRno3eDBiFrRHnGTHyQwdOUeqN48Jzd/g66ed8/wMLH/S5no
+xqE=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIEXDCCA0SgAwIBAgIEOGO5ZjANBgkqhkiG9w0BAQUFADCBtDEUMBIGA1UEChML
+RW50cnVzdC5uZXQxQDA+BgNVBAsUN3d3dy5lbnRydXN0Lm5ldC9DUFNfMjA0OCBp
+bmNvcnAuIGJ5IHJlZi4gKGxpbWl0cyBsaWFiLikxJTAjBgNVBAsTHChjKSAxOTk5
+IEVudHJ1c3QubmV0IExpbWl0ZWQxMzAxBgNVBAMTKkVudHJ1c3QubmV0IENlcnRp
+ZmljYXRpb24gQXV0aG9yaXR5ICgyMDQ4KTAeFw05OTEyMjQxNzUwNTFaFw0xOTEy
+MjQxODIwNTFaMIG0MRQwEgYDVQQKEwtFbnRydXN0Lm5ldDFAMD4GA1UECxQ3d3d3
+LmVudHJ1c3QubmV0L0NQU18yMDQ4IGluY29ycC4gYnkgcmVmLiAobGltaXRzIGxp
+YWIuKTElMCMGA1UECxMcKGMpIDE5OTkgRW50cnVzdC5uZXQgTGltaXRlZDEzMDEG
+A1UEAxMqRW50cnVzdC5uZXQgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgKDIwNDgp
+MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEArU1LqRKGsuqjIAcVFmQq
+K0vRvwtKTY7tgHalZ7d4QMBzQshowNtTK91euHaYNZOLGp18EzoOH1u3Hs/lJBQe
+sYGpjX24zGtLA/ECDNyrpUAkAH90lKGdCCmziAv1h3edVc3kw37XamSrhRSGlVuX
+MlBvPci6Zgzj/L24ScF2iUkZ/cCovYmjZy/Gn7xxGWC4LeksyZB2ZnuU4q941mVT
+XTzWnLLPKQP5L6RQstRIzgUyVYr9smRMDuSYB3Xbf9+5CFVghTAp+XtIpGmG4zU/
+HoZdenoVve8AjhUiVBcAkCaTvA5JaJG/+EfTnZVCwQ5N328mz8MYIWJmQ3DW1cAH
+4QIDAQABo3QwcjARBglghkgBhvhCAQEEBAMCAAcwHwYDVR0jBBgwFoAUVeSB0RGA
+vtiJuQijMfmhJAkWuXAwHQYDVR0OBBYEFFXkgdERgL7YibkIozH5oSQJFrlwMB0G
+CSqGSIb2fQdBAAQQMA4bCFY1LjA6NC4wAwIEkDANBgkqhkiG9w0BAQUFAAOCAQEA
+WUesIYSKF8mciVMeuoCFGsY8Tj6xnLZ8xpJdGGQC49MGCBFhfGPjK50xA3B20qMo
+oPS7mmNz7W3lKtvtFKkrxjYR0CvrB4ul2p5cGZ1WEvVUKcgF7bISKo30Axv/55IQ
+h7A6tcOdBTcSo8f0FbnVpDkWm1M6I5HxqIKiaohowXkCIryqptau37AUX7iH0N18
+f3v/rxzP5tsHrV7bhZ3QKw0z2wTR5klAEyt2+z7pnIkPFc4YsIV4IU9rTw76NmfN
+B/L/CNDi3tm/Kq+4h4YhPATKt5Rof8886ZjXOP/swNlQ8C5LWK5Gb9Auw2DaclVy
+vUxFnmG6v4SBkgPR0ml8xQ==
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIFkjCCA3qgAwIBAgIIAeDltYNno+AwDQYJKoZIhvcNAQEMBQAwZzEbMBkGA1UE
+AwwSQXBwbGUgUm9vdCBDQSAtIEcyMSYwJAYDVQQLDB1BcHBsZSBDZXJ0aWZpY2F0
+aW9uIEF1dGhvcml0eTETMBEGA1UECgwKQXBwbGUgSW5jLjELMAkGA1UEBhMCVVMw
+HhcNMTQwNDMwMTgxMDA5WhcNMzkwNDMwMTgxMDA5WjBnMRswGQYDVQQDDBJBcHBs
+ZSBSb290IENBIC0gRzIxJjAkBgNVBAsMHUFwcGxlIENlcnRpZmljYXRpb24gQXV0
+aG9yaXR5MRMwEQYDVQQKDApBcHBsZSBJbmMuMQswCQYDVQQGEwJVUzCCAiIwDQYJ
+KoZIhvcNAQEBBQADggIPADCCAgoCggIBANgREkhI2imKScUcx+xuM23+TfvgHN6s
+XuI2pyT5f1BrTM65MFQn5bPW7SXmMLYFN14UIhHF6Kob0vuy0gmVOKTvKkmMXT5x
+ZgM4+xb1hYjkWpIMBDLyyED7Ul+f9sDx47pFoFDVEovy3d6RhiPw9bZyLgHaC/Yu
+OQhfGaFjQQscp5TBhsRTL3b2CtcM0YM/GlMZ81fVJ3/8E7j4ko380yhDPLVoACVd
+J2LT3VXdRCCQgzWTxb+4Gftr49wIQuavbfqeQMpOhYV4SbHXw8EwOTKrfl+q04tv
+ny0aIWhwZ7Oj8ZhBbZF8+NfbqOdfIRqMM78xdLe40fTgIvS/cjTf94FNcX1RoeKz
+8NMoFnNvzcytN31O661A4T+B/fc9Cj6i8b0xlilZ3MIZgIxbdMYs0xBTJh0UT8TU
+gWY8h2czJxQI6bR3hDRSj4n4aJgXv8O7qhOTH11UL6jHfPsNFL4VPSQ08prcdUFm
+IrQB1guvkJ4M6mL4m1k8COKWNORj3rw31OsMiANDC1CvoDTdUE0V+1ok2Az6DGOe
+HwOx4e7hqkP0ZmUoNwIx7wHHHtHMn23KVDpA287PT0aLSmWaasZobNfMmRtHsHLD
+d4/E92GcdB/O/WuhwpyUgquUoue9G7q5cDmVF8Up8zlYNPXEpMZ7YLlmQ1A/bmH8
+DvmGqmAMQ0uVAgMBAAGjQjBAMB0GA1UdDgQWBBTEmRNsGAPCe8CjoA1/coB6HHcm
+jTAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQwF
+AAOCAgEAUabz4vS4PZO/Lc4Pu1vhVRROTtHlznldgX/+tvCHM/jvlOV+3Gp5pxy+
+8JS3ptEwnMgNCnWefZKVfhidfsJxaXwU6s+DDuQUQp50DhDNqxq6EWGBeNjxtUVA
+eKuowM77fWM3aPbn+6/Gw0vsHzYmE1SGlHKy6gLti23kDKaQwFd1z4xCfVzmMX3z
+ybKSaUYOiPjjLUKyOKimGY3xn83uamW8GrAlvacp/fQ+onVJv57byfenHmOZ4VxG
+/5IFjPoeIPmGlFYl5bRXOJ3riGQUIUkhOb9iZqmxospvPyFgxYnURTbImHy99v6Z
+SYA7LNKmp4gDBDEZt7Y6YUX6yfIjyGNzv1aJMbDZfGKnexWoiIqrOEDCzBL/FePw
+N983csvMmOa/orz6JopxVtfnJBtIRD6e/J/JzBrsQzwBvDR4yGn1xuZW7AYJNpDr
+FEobXsmII9oDMJELuDY++ee1KG++P+w8j2Ud5cAeh6Squpj9kuNsJnfdBrRkBof0
+Tta6SqoWqPQFZ2aWuuJVecMsXUmPgEkrihLHdoBR37q9ZV0+N0djMenl9MU/S60E
+inpxLK8JQzcPqOMyT/RFtm2XNuyE9QoB6he7hY1Ck3DDUOUUi78/w0EP3SIEIwiK
+um1xRKtzCTrJ+VKACd+66eYWyi4uTLLT3OUEVLLUNIAytbwPF+E=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIDtDCCApygAwIBAgIBADANBgkqhkiG9w0BAQUFADBjMQswCQYDVQQGEwJKUDEc
+MBoGA1UEChMTSmFwYW5lc2UgR292ZXJubWVudDEOMAwGA1UECxMFTVBIUFQxJjAk
+BgNVBAsTHU1QSFBUIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTAyMDMxNDA3
+NTAyNloXDTEyMDMxMzE0NTk1OVowYzELMAkGA1UEBhMCSlAxHDAaBgNVBAoTE0ph
+cGFuZXNlIEdvdmVybm1lbnQxDjAMBgNVBAsTBU1QSFBUMSYwJAYDVQQLEx1NUEhQ
+VCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTCCASIwDQYJKoZIhvcNAQEBBQADggEP
+ADCCAQoCggEBAI3GUWlK9G9FVm8DhpKu5t37oxZbj6lZcFvEZY07YrYojWO657ub
+z56WE7q/PI/6Sm7i7qYE+Vp80r6thJvfmn7SS3BENrRqiapSenhooYD12jIe3iZQ
+2SXqx7WgYwyBGdQwGaYTijzbRFpgc0K8o4a99fIoHhz9J8AKqXasddMCqfJRaH30
+YJ7HnOvRYGL6HBrGhJ7X4Rzijyk9a9+3VOBsYcnIlx9iODoiYhA6r0ojuIu8/JA1
+oTTZrS0MyU/SLdFdJze2O1wnqTULXQybzJz3ad6oC/F5a69c0m92akYd9nGBrPxj
+EhucaQynC/QoCLs3aciLgioAnEJqy7i3EgUCAwEAAaNzMHEwHwYDVR0jBBgwFoAU
+YML3pLoA0h93Yngl8Gb/UgAh73owHQYDVR0OBBYEFGDC96S6ANIfd2J4JfBm/1IA
+Ie96MAwGA1UdEwQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMBEGCWCGSAGG+EIBAQQE
+AwIABTANBgkqhkiG9w0BAQUFAAOCAQEANPR8DN66iWZBs/lSm1vOzhqRkXDLT6xL
+LvJtjPLqmE469szGyFSKzsof6y+/8YgZlOoeX1inF4ox/SH1ATnwdIIsPbXuRLjt
+axboXvBh5y2ffC3hmzJVvJ87tb6mVWQeL9VFUhNhAI0ib+9OIZVEYI/64MFkDk4e
+iWG5ts6oqIJH1V7dVZg6pQ1Tc0Ckhn6N1m1hD30S0/zoPn/20Wq6OCF3he8VJrRG
+dcW9BD/Bkesko1HKhMBDjHVrJ8cFwbnDSoo+Ki47eJWaz/cOzaSsaMVUsR5POava
+/abhhgHn/eOJdXiVslyK0DYscjsdB3aBUfwZlomxYOzG6CgjQPhJdw==
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIID9zCCAt+gAwIBAgILMTI1MzcyODI4MjgwDQYJKoZIhvcNAQELBQAwWDELMAkG
+A1UEBhMCSlAxHDAaBgNVBAoTE0phcGFuZXNlIEdvdmVybm1lbnQxDTALBgNVBAsT
+BEdQS0kxHDAaBgNVBAMTE0FwcGxpY2F0aW9uQ0EyIFJvb3QwHhcNMTMwMzEyMTUw
+MDAwWhcNMzMwMzEyMTUwMDAwWjBYMQswCQYDVQQGEwJKUDEcMBoGA1UEChMTSmFw
+YW5lc2UgR292ZXJubWVudDENMAsGA1UECxMER1BLSTEcMBoGA1UEAxMTQXBwbGlj
+YXRpb25DQTIgUm9vdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKaq
+rSVl1gAR1uh6dqr05rRL88zDUrSNrKZPtZJxb0a11a2LEiIXJc5F6BR6hZrkIxCo
++rFnUOVtR+BqiRPjrq418fRCxQX3TZd+PCj8sCaRHoweOBqW3FhEl2LjMsjRFUFN
+dZh4vqtoqV7tR76kuo6hApfek3SZbWe0BSXulMjtqqS6MmxCEeu+yxcGkOGThchk
+KM4fR8fAXWDudjbcMztR63vPctgPeKgZggiQPhqYjY60zxU2pm7dt+JNQCBT2XYq
+0HisifBPizJtROouurCp64ndt295D6uBbrjmiykLWa+2SQ1RLKn9nShjZrhwlXOa
+2Po7M7xCQhsyrLEy+z0CAwEAAaOBwTCBvjAdBgNVHQ4EFgQUVqesqgIdsqw9kA6g
+by5Bxnbne9owDgYDVR0PAQH/BAQDAgEGMHwGA1UdEQR1MHOkcTBvMQswCQYDVQQG
+EwJKUDEYMBYGA1UECgwP5pel5pys5Zu95pS/5bqcMRswGQYDVQQLDBLmlL/lupzo
+qo3oqLzln7rnm6QxKTAnBgNVBAMMIOOCouODl+ODquOCseODvOOCt+ODp+ODs0NB
+MiBSb290MA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEBAH+aCXWs
+B9FydC53VzDCBJzUgKaD56WgG5/+q/OAvdVKo6GPtkxgEefK4WCB10jBIFmlYTKL
+nZ6X02aD2mUuWD7b5S+lzYxzplG+WCigeVxpL0PfY7KJR8q73rk0EWOgDiUX5Yf0
+HbCwpc9BqHTG6FPVQvSCLVMJEWgmcZR1E02qdog8dLHW40xPYsNJTE5t8XB+w3+m
+Bcx4m+mB26jIx1ye/JKSLaaX8ji1bnOVDMA/zqaUMLX6BbfeniCq/BNkyYq6ZO/i
+Y+TYmK5rtT6mVbgzPixy+ywRAPtbFi+E0hOe+gXFwctyTiLdhMpLvNIthhoEdlkf
+SUJiOxMfFui61/0=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIDIDCCAomgAwIBAgIENd70zzANBgkqhkiG9w0BAQUFADBOMQswCQYDVQQGEwJV
+UzEQMA4GA1UEChMHRXF1aWZheDEtMCsGA1UECxMkRXF1aWZheCBTZWN1cmUgQ2Vy
+dGlmaWNhdGUgQXV0aG9yaXR5MB4XDTk4MDgyMjE2NDE1MVoXDTE4MDgyMjE2NDE1
+MVowTjELMAkGA1UEBhMCVVMxEDAOBgNVBAoTB0VxdWlmYXgxLTArBgNVBAsTJEVx
+dWlmYXggU2VjdXJlIENlcnRpZmljYXRlIEF1dGhvcml0eTCBnzANBgkqhkiG9w0B
+AQEFAAOBjQAwgYkCgYEAwV2xWGcIYu6gmi0fCG2RFGiYCh7+2gRvE4RiIcPRfM6f
+BeC4AfBONOziipUEZKzxa1NfBbPLZ4C/QgKO/t0BCezhABRP/PvwDN1Dulsr4R+A
+cJkVV5MW8Q+XarfCaCMczE1ZMKxRHjuvK9buY0V7xdlfUNLjUA86iOe/FP3gx7kC
+AwEAAaOCAQkwggEFMHAGA1UdHwRpMGcwZaBjoGGkXzBdMQswCQYDVQQGEwJVUzEQ
+MA4GA1UEChMHRXF1aWZheDEtMCsGA1UECxMkRXF1aWZheCBTZWN1cmUgQ2VydGlm
+aWNhdGUgQXV0aG9yaXR5MQ0wCwYDVQQDEwRDUkwxMBoGA1UdEAQTMBGBDzIwMTgw
+ODIyMTY0MTUxWjALBgNVHQ8EBAMCAQYwHwYDVR0jBBgwFoAUSOZo+SvSspXXR9gj
+IBBPM5iQn9QwHQYDVR0OBBYEFEjmaPkr0rKV10fYIyAQTzOYkJ/UMAwGA1UdEwQF
+MAMBAf8wGgYJKoZIhvZ9B0EABA0wCxsFVjMuMGMDAgbAMA0GCSqGSIb3DQEBBQUA
+A4GBAFjOKer89961zgK5F7WF0bnj4JXMJTENAKaSbn+2kmOeUJXRmm/kEd5jhW6Y
+7qj/WsjTVbJmcVfewCHrPSqnI0kBBIZCe/zuf6IWUrVnZ9NA2zsmWLIodz2uFHdh
+1voqZiegDfqnc1zqcPGUIWVEX/r87yloqaKHee9570+sB3c4
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIICrjCCAjWgAwIBAgIQPLL0SAoA4v7rJDteYD7DazAKBggqhkjOPQQDAzCBmDEL
+MAkGA1UEBhMCVVMxFjAUBgNVBAoTDUdlb1RydXN0IEluYy4xOTA3BgNVBAsTMChj
+KSAyMDA3IEdlb1RydXN0IEluYy4gLSBGb3IgYXV0aG9yaXplZCB1c2Ugb25seTE2
+MDQGA1UEAxMtR2VvVHJ1c3QgUHJpbWFyeSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0
+eSAtIEcyMB4XDTA3MTEwNTAwMDAwMFoXDTM4MDExODIzNTk1OVowgZgxCzAJBgNV
+BAYTAlVTMRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMTkwNwYDVQQLEzAoYykgMjAw
+NyBHZW9UcnVzdCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxNjA0BgNV
+BAMTLUdlb1RydXN0IFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgLSBH
+MjB2MBAGByqGSM49AgEGBSuBBAAiA2IABBWx6P0DFUPlrOuHNxFi79KDNlJ9RVcL
+So17VDs6bl8VAsBQps8lL33KSLjHUGMcKiEIfJo22Av+0SbFWDEwKCXzXV2juLal
+tJLtbCyf691DiaI8S0iRHVDsJt/WYC69IaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAO
+BgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFBVfNVdRVfslsq0DafwBo/q+EVXVMAoG
+CCqGSM49BAMDA2cAMGQCMGSWWaboCd6LuvpaiIjwH5HTRqjySkwCY/tsXzjbLkGT
+qQ7mndwxHLKgpxgceeHHNgIwOlavmnRs9vuD4DPTCF+hnMJbn0bWtsuRBmOiBucz
+rD6ogRLQy7rQkgu2npaqBA+K
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIFcDCCA1igAwIBAgIEAJiWjTANBgkqhkiG9w0BAQsFADBYMQswCQYDVQQGEwJO
+TDEeMBwGA1UECgwVU3RhYXQgZGVyIE5lZGVybGFuZGVuMSkwJwYDVQQDDCBTdGFh
+dCBkZXIgTmVkZXJsYW5kZW4gRVYgUm9vdCBDQTAeFw0xMDEyMDgxMTE5MjlaFw0y
+MjEyMDgxMTEwMjhaMFgxCzAJBgNVBAYTAk5MMR4wHAYDVQQKDBVTdGFhdCBkZXIg
+TmVkZXJsYW5kZW4xKTAnBgNVBAMMIFN0YWF0IGRlciBOZWRlcmxhbmRlbiBFViBS
+b290IENBMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA48d+ifkkSzrS
+M4M1LGns3Amk41GoJSt5uAg94JG6hIXGhaTK5skuU6TJJB79VWZxXSzFYGgEt9nC
+UiY4iKTWO0Cmws0/zZiTs1QUWJZV1VD+hq2kY39ch/aO5ieSZxeSAgMs3NZmdO3d
+Z//BYY1jTw+bbRcwJu+r0h8QoPnFfxZpgQNH7R5ojXKhTbImxrpsX23Wr9GxE46p
+rfNeaXUmGD5BKyF/7otdBwadQ8QpCiv8Kj6GyzyDOvnJDdrFmeK8eEEzduG/L13l
+pJhQDBXd4Pqcfzho0LKmeqfRMb1+ilgnQ7O6M5HTp5gVXJrm0w912fxBmJc+qiXb
+j5IusHsMX/FjqTf5m3VpTCgmJdrV8hJwRVXj33NeN/UhbJCONVrJ0yPr08C+eKxC
+KFhmpUZtcALXEPlLVPxdhkqHz3/KRawRWrUgUY0viEeXOcDPusBCAUCZSCELa6fS
+/ZbV0b5GnUngC6agIk440ME8MLxwjyx1zNDFjFE7PZQIZCZhfbnDZY8UnCHQqv0X
+cgOPvZuM5l5Tnrmd74K74bzickFbIZTTRTeU0d8JOV3nI6qaHcptqAqGhYqCvkIH
+1vI4gnPah1vlPNOePqc7nvQDs/nxfRN0Av+7oeX6AHkcpmZBiFxgV6YuCcS6/ZrP
+px9Aw7vMWgpVSzs4dlG4Y4uElBbmVvMCAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB
+/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFP6rAJCYniT8qcwaivsnuL8wbqg7
+MA0GCSqGSIb3DQEBCwUAA4ICAQDPdyxuVr5Os7aEAJSrR8kN0nbHhp8dB9O2tLsI
+eK9p0gtJ3jPFrK3CiAJ9Brc1AsFgyb/E6JTe1NOpEyVa/m6irn0F3H3zbPB+po3u
+2dfOWBfoqSmuc0iH55vKbimhZF8ZE/euBhD/UcabTVUlT5OZEAFTdfETzsemQUHS
+v4ilf0X8rLiltTMMgsT7B/Zq5SWEXwbKwYY5EdtYzXc7LMJMD16a4/CrPmEbUCTC
+wPTxGfARKbalGAKb12NMcIxHowNDXLldRqANb/9Zjr7dn3LDWyvfjFvO5QxGbJKy
+CqNMVEIYFRIYvdr8unRu/8G2oGTYqV9Vrp9canaW2HNnh/tNf1zuacpzEPuKqf2e
+vTY4SUmH9A4U8OmHuD+nT3pajnnUk+S7aFKErGzp85hwVXIy+TSrK0m1zSBi5Dp6
+Z2Orltxtrpfs/J92VoguZs9btsmksNcFuuEnL5O7Jiqik7Ab846+HUCjuTaPPoIa
+Gl6I6lD4WeKDRikL40Rc4ZW2aZCaFG+XroHPaO+Zmr615+F/+PoTRxZMzG0IQOeL
+eG9QgkRQP2YGiqtDhFZKDyAthg710tvSeopLzaXoTvFeJiUBWSOgftL2fiFX1ye8
+FVdMpEbB4IMeDExNH08GGeL5qPQ6gqGyeUN51q1veieQA6TqJIc/2b3Z6fJfUEkc
+7uzXLg==
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIDnzCCAoegAwIBAgIBJjANBgkqhkiG9w0BAQUFADBxMQswCQYDVQQGEwJERTEc
+MBoGA1UEChMTRGV1dHNjaGUgVGVsZWtvbSBBRzEfMB0GA1UECxMWVC1UZWxlU2Vj
+IFRydXN0IENlbnRlcjEjMCEGA1UEAxMaRGV1dHNjaGUgVGVsZWtvbSBSb290IENB
+IDIwHhcNOTkwNzA5MTIxMTAwWhcNMTkwNzA5MjM1OTAwWjBxMQswCQYDVQQGEwJE
+RTEcMBoGA1UEChMTRGV1dHNjaGUgVGVsZWtvbSBBRzEfMB0GA1UECxMWVC1UZWxl
+U2VjIFRydXN0IENlbnRlcjEjMCEGA1UEAxMaRGV1dHNjaGUgVGVsZWtvbSBSb290
+IENBIDIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCrC6M14IspFLEU
+ha88EOQ5bzVdSq7d6mGNlUn0b2SjGmBmpKlAIoTZ1KXleJMOaAGtuU1cOs7TuKhC
+QN/Po7qCWWqSG6wcmtoIKyUn+WkjR/Hg6yx6m/UTAtB+NHzCnjwAWav12gz1Mjwr
+rFDa1sPeg5TKqAyZMg4ISFZbavva4VhYAUlfckE8FQYBjl2tqriTtM2e66foai1S
+NNs671x1Udrb8zH57nGYMsRUFUQM+ZtV7a3fGAigo4aKSe5TBY8ZTNXeWHmb0moc
+QqvF1afPaA+W5OFhmHZhyJF81j4A4pFQh+GdCuatl9Idxjp9y7zaAzTVjlsB9WoH
+txa2bkp/AgMBAAGjQjBAMB0GA1UdDgQWBBQxw3kbuvVT1xfgiXotF2wKsyudMzAP
+BgNVHRMECDAGAQH/AgEFMA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQUFAAOC
+AQEAlGRZrTlk5ynrE/5aw4sTV8gEJPB0d8Bg42f76Ymmg7+Wgnxu1MM9756Abrsp
+tJh6sTtU6zkXR34ajgv8HzFZMQSyzhfzLMdiNlXiItiJVbSYSKpk+tYcNthEeFpa
+IzpXl/V6ME+un2pMSyuOoAPjPuCp1NJ70rOo4nI8rZ7/gFnkm0W09juwzTkZmDLl
+6iFhkOQxIY40sfcvNUqFENrnijchvllj4PKFiDFT1FQUhXB59C4Gdyd1Lx+4ivn+
+xbrYNuSD7Odlt79jWvNGr4GUN9RBjNYj1h7P9WgbRGOiWrqnNVmh5XAFmw4jV5mU
+Cm26OWMohpLzGITY+9HPBVZkVw==
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIGSzCCBDOgAwIBAgIIamg+nFGby1MwDQYJKoZIhvcNAQELBQAwgbIxCzAJBgNV
+BAYTAlRSMQ8wDQYDVQQHDAZBbmthcmExQDA+BgNVBAoMN0UtVHXEn3JhIEVCRyBC
+aWxpxZ9pbSBUZWtub2xvamlsZXJpIHZlIEhpem1ldGxlcmkgQS7Fni4xJjAkBgNV
+BAsMHUUtVHVncmEgU2VydGlmaWthc3lvbiBNZXJrZXppMSgwJgYDVQQDDB9FLVR1
+Z3JhIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTEzMDMwNTEyMDk0OFoXDTIz
+MDMwMzEyMDk0OFowgbIxCzAJBgNVBAYTAlRSMQ8wDQYDVQQHDAZBbmthcmExQDA+
+BgNVBAoMN0UtVHXEn3JhIEVCRyBCaWxpxZ9pbSBUZWtub2xvamlsZXJpIHZlIEhp
+em1ldGxlcmkgQS7Fni4xJjAkBgNVBAsMHUUtVHVncmEgU2VydGlmaWthc3lvbiBN
+ZXJrZXppMSgwJgYDVQQDDB9FLVR1Z3JhIENlcnRpZmljYXRpb24gQXV0aG9yaXR5
+MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA4vU/kwVRHoViVF56C/UY
+B4Oufq9899SKa6VjQzm5S/fDxmSJPZQuVIBSOTkHS0vdhQd2h8y/L5VMzH2nPbxH
+D5hw+IyFHnSOkm0bQNGZDbt1bsipa5rAhDGvykPL6ys06I+XawGb1Q5KCKpbknSF
+Q9OArqGIW66z6l7LFpp3RMih9lRozt6Plyu6W0ACDGQXwLWTzeHxE2bODHnv0ZEo
+q1+gElIwcxmOj+GMB6LDu0rw6h8VqO4lzKRG+Bsi77MOQ7osJLjFLFzUHPhdZL3D
+k14opz8n8Y4e0ypQBaNV2cvnOVPAmJ6MVGKLJrD3fY185MaeZkJVgkfnsliNZvcH
+fC425lAcP9tDJMW/hkd5s3kc91r0E+xs+D/iWR+V7kI+ua2oMoVJl0b+SzGPWsut
+dEcf6ZG33ygEIqDUD13ieU/qbIWGvaimzuT6w+Gzrt48Ue7LE3wBf4QOXVGUnhMM
+ti6lTPk5cDZvlsouDERVxcr6XQKj39ZkjFqzAQqptQpHF//vkUAqjqFGOjGY5RH8
+zLtJVor8udBhmm9lbObDyz51Sf6Pp+KJxWfXnUYTTjF2OySznhFlhqt/7x3U+Lzn
+rFpct1pHXFXOVbQicVtbC/DP3KBhZOqp12gKY6fgDT+gr9Oq0n7vUaDmUStVkhUX
+U8u3Zg5mTPj5dUyQ5xJwx0UCAwEAAaNjMGEwHQYDVR0OBBYEFC7j27JJ0JxUeVz6
+Jyr+zE7S6E5UMA8GA1UdEwEB/wQFMAMBAf8wHwYDVR0jBBgwFoAULuPbsknQnFR5
+XPonKv7MTtLoTlQwDgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3DQEBCwUAA4ICAQAF
+Nzr0TbdF4kV1JI+2d1LoHNgQk2Xz8lkGpD4eKexd0dCrfOAKkEh47U6YA5n+KGCR
+HTAduGN8qOY1tfrTYXbm1gdLymmasoR6d5NFFxWfJNCYExL/u6Au/U5Mh/jOXKqY
+GwXgAEZKgoClM4so3O0409/lPun++1ndYYRP0lSWE2ETPo+Aab6TR7U1Q9Jauz1c
+77NCR807VRMGsAnb/WP2OogKmW9+4c4bU2pEZiNRCHu8W1Ki/QY3OEBhj0qWuJA3
++GbHeJAAFS6LrVE1Uweoa2iu+U48BybNCAVwzDk/dr2l02cmAYamU9JgO3xDf1WK
+vJUawSg5TB9D0pH0clmKuVb8P7Sd2nCcdlqMQ1DujjByTd//SffGqWfZbawCEeI6
+FiWnWAjLb1NBnEg4R2gz0dfHj9R0IdTDBZB6/86WiLEVKV0jq9BgoRJP3vQXzTLl
+yb/IQ639Lo7xr+L0mPoSHyDYwKcMhcWQ9DstliaxLL5Mq+ux0orJ23gTDx4JnW2P
+AJ8C2sH6H3p6CcRK5ogql5+Ji/03X186zjhZhkuvcQu02PJwT58yE+Owp1fl2tpD
+y4Q08ijE6m30Ku/Ba3ba+367hTzSU8JNvnHhRdH9I2cNE3X7z2VnIp2usAnRCf8d
+NL/+I5c30jn6PQ0GC7TbO6Orb1wdtn7os4I07QZcJA==
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIDtTCCAp2gAwIBAgIIBhDCeat3PfIwDQYJKoZIhvcNAQEFBQAwdjELMAkGA1UE
+BhMCQ0gxEjAQBgNVBAoTCVN3aXNzU2lnbjEyMDAGA1UEAxMpU3dpc3NTaWduIENB
+IChSU0EgSUsgTWF5IDYgMTk5OSAxODowMDo1OCkxHzAdBgkqhkiG9w0BCQEWEGNh
+QFN3aXNzU2lnbi5jb20wHhcNMDAxMTI2MjMyNzQxWhcNMzExMTI2MjMyNzQxWjB2
+MQswCQYDVQQGEwJDSDESMBAGA1UEChMJU3dpc3NTaWduMTIwMAYDVQQDEylTd2lz
+c1NpZ24gQ0EgKFJTQSBJSyBNYXkgNiAxOTk5IDE4OjAwOjU4KTEfMB0GCSqGSIb3
+DQEJARYQY2FAU3dpc3NTaWduLmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC
+AQoCggEBAKw5fjnmNneLQlUCQG8jQLwwfbrOZoUwNX8cbNqhxK03/xUloFVgAt+S
+Te2RxNXaCAXLBPn5ZST35TLV57aLmbHCtifv3YZqaaQGvjedltIBMJihJhZ+h3LY
+SKsUb+xEJ3x5ZUf8jP+Q1g57y1s8SnBFWN/ni5NkF1Y1y31VwOi9wiOf/VISL+uu
+SC4i1CP1Kbz3BDs6Hht1GpRYCbJ/K0bc9oJSpWpT5PGONsGIawqMbJuyoDghsXQ1
+pbn2e8K64BSscGZVZTNooSGgNiHmACNJBYXiWVWrwXPF4l6SddmC3Rj0aKXjgECc
+FkHLDQcsM5JsK2ZLryTDUsQFbxVP2ikCAwEAAaNHMEUwCwYDVR0PBAQDAgEGMAwG
+A1UdEwQFMAMBAf8wHQYDVR0OBBYEFJbXcc05KtT8iLGKq1N4ae+PR34WMAkGA1Ud
+IwQCMAAwDQYJKoZIhvcNAQEFBQADggEBAKMy6W8HvZdS1fBpEUzl6Lvw50bgE1Xc
+HU1JypSBG9mhdcXZo5AlPB4sCvx9Dmfwhyrdsshc0TP2V3Vh6eQqnEF5qB4lVziT
+Bko9mW6Ot+pPnwsy4SHpx3rw6jCYnOqfUcZjWqqqRrq/3P1waz+Mn4cLMVEg3Xaz
+qYov/khvSqS0JniwjRlo2H6f/1oVUKZvP+dUhpQepfZrOqMAWZW4otp6FolyQyeU
+NN6UCRNiUKl5vTijbKwUUwfER/1Vci3M1/O1QCfttQ4vRN4Buc0xqYtGL3cd5WiO
+vWzyhlTzAI6VUdNkQhhHJSAyTpj6dmXDRzrryoFGa2PjgESxz7XBaSI=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIDZzCCAk+gAwIBAgIQGx+ttiD5JNM2a/fH8YygWTANBgkqhkiG9w0BAQUFADBF
+MQswCQYDVQQGEwJHQjEYMBYGA1UEChMPVHJ1c3RpcyBMaW1pdGVkMRwwGgYDVQQL
+ExNUcnVzdGlzIEZQUyBSb290IENBMB4XDTAzMTIyMzEyMTQwNloXDTI0MDEyMTEx
+MzY1NFowRTELMAkGA1UEBhMCR0IxGDAWBgNVBAoTD1RydXN0aXMgTGltaXRlZDEc
+MBoGA1UECxMTVHJ1c3RpcyBGUFMgUm9vdCBDQTCCASIwDQYJKoZIhvcNAQEBBQAD
+ggEPADCCAQoCggEBAMVQe547NdDfxIzNjpvto8A2mfRC6qc+gIMPpqdZh8mQRUN+
+AOqGeSoDvT03mYlmt+WKVoaTnGhLaASMk5MCPjDSNzoiYYkchU59j9WvezX2fihH
+iTHcDnlkH5nSW7r+f2C/revnPDgpai/lkQtV/+xvWNUtyd5MZnGPDNcE2gfmHhjj
+vSkCqPoc4Vu5g6hBSLwacY3nYuUtsuvffM/bq1rKMfFMIvMFE/eC+XN5DL7XSxzA
+0RU8k0Fk0ea+IxciAIleH2ulrG6nS4zto3Lmr2NNL4XSFDWaLk6M6jKYKIahkQlB
+OrTh4/L68MkKokHdqeMDx4gVOxzUGpTXn2RZEm0CAwEAAaNTMFEwDwYDVR0TAQH/
+BAUwAwEB/zAfBgNVHSMEGDAWgBS6+nEleYtXQSUhhgtx67JkDoshZzAdBgNVHQ4E
+FgQUuvpxJXmLV0ElIYYLceuyZA6LIWcwDQYJKoZIhvcNAQEFBQADggEBAH5Y//01
+GX2cGE+esCu8jowU/yyg2kdbw++BLa8F6nRIW/M+TgfHbcWzk88iNVy2P3UnXwmW
+zaD+vkAMXBJV+JOCyinpXj9WV4s4NvdFGkwozZ5BuO1WTISkQMi4sKUraXAEasP4
+1BIy+Q7DsdwyhEQsb8tGD+pmQQ9P8Vilpg0ND2HepZ5dfWWhPBfnqFVO76DH7cZE
+f1T1o+CP8HxVIo8ptoGj4W1OLBuAZ+ytIJ8MYmHVl/9D7S3B2l0pKoU/rGXuhg8F
+jZBf3+6f9L/uHfuY5H+QK4R4EA5sSVPvFVtlRkpdr7r7OnIdzfYliB6XzCGcKQEN
+ZetX2fNXlrtIzYE=
+-----END CERTIFICATE-----
+`
diff --git a/third_party/gofrontend/libgo/go/crypto/x509/root_linux.go b/third_party/gofrontend/libgo/go/crypto/x509/root_linux.go
new file mode 100644
index 0000000..cfeca69
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/crypto/x509/root_linux.go
@@ -0,0 +1,13 @@
+// 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 x509
+
+// Possible certificate files; stop after finding one.
+var certFiles = []string{
+	"/etc/ssl/certs/ca-certificates.crt", // Debian/Ubuntu/Gentoo etc.
+	"/etc/pki/tls/certs/ca-bundle.crt",   // Fedora/RHEL
+	"/etc/ssl/ca-bundle.pem",             // OpenSUSE
+	"/etc/pki/tls/cacert.pem",            // OpenELEC
+}
diff --git a/third_party/gofrontend/libgo/go/crypto/x509/root_nacl.go b/third_party/gofrontend/libgo/go/crypto/x509/root_nacl.go
new file mode 100644
index 0000000..4413f64
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/crypto/x509/root_nacl.go
@@ -0,0 +1,8 @@
+// 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 x509
+
+// Possible certificate files; stop after finding one.
+var certFiles = []string{}
diff --git a/third_party/gofrontend/libgo/go/crypto/x509/root_solaris.go b/third_party/gofrontend/libgo/go/crypto/x509/root_solaris.go
new file mode 100644
index 0000000..e6d4e61
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/crypto/x509/root_solaris.go
@@ -0,0 +1,12 @@
+// 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 x509
+
+// Possible certificate files; stop after finding one.
+var certFiles = []string{
+	"/etc/certs/ca-certificates.crt",     // Solaris 11.2+
+	"/etc/ssl/certs/ca-certificates.crt", // Joyent SmartOS
+	"/etc/ssl/cacert.pem",                // OmniOS
+}
diff --git a/third_party/gofrontend/libgo/go/crypto/x509/root_unix.go b/third_party/gofrontend/libgo/go/crypto/x509/root_unix.go
index f77d6c0..8d3b2fb 100644
--- a/third_party/gofrontend/libgo/go/crypto/x509/root_unix.go
+++ b/third_party/gofrontend/libgo/go/crypto/x509/root_unix.go
@@ -8,22 +8,10 @@
 
 import "io/ioutil"
 
-// Possible certificate files; stop after finding one.
-var certFiles = []string{
-	"/etc/ssl/certs/ca-certificates.crt",     // Debian/Ubuntu/Gentoo etc.
-	"/etc/pki/tls/certs/ca-bundle.crt",       // Fedora/RHEL
-	"/etc/ssl/ca-bundle.pem",                 // OpenSUSE
-	"/etc/ssl/cert.pem",                      // OpenBSD
-	"/usr/local/share/certs/ca-root-nss.crt", // FreeBSD/DragonFly
-	"/etc/pki/tls/cacert.pem",                // OpenELEC
-	"/etc/certs/ca-certificates.crt",         // Solaris 11.2+
-}
-
 // Possible directories with certificate files; stop after successfully
 // reading at least one file from a directory.
 var certDirectories = []string{
 	"/system/etc/security/cacerts", // Android
-
 }
 
 func (c *Certificate) systemVerify(opts *VerifyOptions) (chains [][]*Certificate, err error) {
diff --git a/third_party/gofrontend/libgo/go/crypto/x509/sec1.go b/third_party/gofrontend/libgo/go/crypto/x509/sec1.go
index 7de6675..c4d7ab6 100644
--- a/third_party/gofrontend/libgo/go/crypto/x509/sec1.go
+++ b/third_party/gofrontend/libgo/go/crypto/x509/sec1.go
@@ -18,7 +18,7 @@
 // ecPrivateKey reflects an ASN.1 Elliptic Curve Private Key Structure.
 // References:
 //   RFC5915
-//   SEC1 - http://www.secg.org/download/aid-780/sec1-v2.pdf
+//   SEC1 - http://www.secg.org/sec1-v2.pdf
 // Per RFC5915 the NamedCurveOID is marked as ASN.1 OPTIONAL, however in
 // most cases it is not.
 type ecPrivateKey struct {
diff --git a/third_party/gofrontend/libgo/go/crypto/x509/sha2_windows_test.go b/third_party/gofrontend/libgo/go/crypto/x509/sha2_windows_test.go
new file mode 100644
index 0000000..79dc685
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/crypto/x509/sha2_windows_test.go
@@ -0,0 +1,19 @@
+// 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 x509
+
+import "syscall"
+
+func init() {
+	v, err := syscall.GetVersion()
+	if err != nil {
+		return
+	}
+	if major := byte(v); major < 6 {
+		// Windows XP SP2 and Windows 2003 do not support SHA2.
+		// http://blogs.technet.com/b/pki/archive/2010/09/30/sha2-and-windows.aspx
+		supportSHA2 = false
+	}
+}
diff --git a/third_party/gofrontend/libgo/go/crypto/x509/verify.go b/third_party/gofrontend/libgo/go/crypto/x509/verify.go
index ec19814..21b870c 100644
--- a/third_party/gofrontend/libgo/go/crypto/x509/verify.go
+++ b/third_party/gofrontend/libgo/go/crypto/x509/verify.go
@@ -215,6 +215,10 @@
 		return c.systemVerify(&opts)
 	}
 
+	if len(c.UnhandledCriticalExtensions) > 0 {
+		return nil, UnhandledCriticalExtension{}
+	}
+
 	if opts.Roots == nil {
 		opts.Roots = systemRootsPool()
 		if opts.Roots == nil {
@@ -323,6 +327,9 @@
 }
 
 func matchHostnames(pattern, host string) bool {
+	host = strings.TrimSuffix(host, ".")
+	pattern = strings.TrimSuffix(pattern, ".")
+
 	if len(pattern) == 0 || len(host) == 0 {
 		return false
 	}
@@ -335,7 +342,7 @@
 	}
 
 	for i, patternPart := range patternParts {
-		if patternPart == "*" {
+		if i == 0 && patternPart == "*" {
 			continue
 		}
 		if patternPart != hostParts[i] {
diff --git a/third_party/gofrontend/libgo/go/crypto/x509/verify_test.go b/third_party/gofrontend/libgo/go/crypto/x509/verify_test.go
index 96b9d9b..694c140 100644
--- a/third_party/gofrontend/libgo/go/crypto/x509/verify_test.go
+++ b/third_party/gofrontend/libgo/go/crypto/x509/verify_test.go
@@ -14,6 +14,8 @@
 	"time"
 )
 
+var supportSHA2 = true
+
 type verifyTest struct {
 	leaf                 string
 	intermediates        []string
@@ -23,6 +25,7 @@
 	systemSkip           bool
 	keyUsages            []ExtKeyUsage
 	testSystemRootsError bool
+	sha2                 bool
 
 	errorCallback  func(*testing.T, int, error) bool
 	expectedChains [][]string
@@ -218,6 +221,11 @@
 		currentTime:   1397502195,
 		dnsName:       "api.moip.com.br",
 
+		// CryptoAPI can find alternative validation paths so we don't
+		// perform this test with system validation.
+		systemSkip: true,
+
+		sha2: true,
 		expectedChains: [][]string{
 			{
 				"api.moip.com.br",
@@ -297,6 +305,9 @@
 		if runtime.GOOS == "windows" && test.testSystemRootsError {
 			continue
 		}
+		if useSystemRoots && !supportSHA2 && test.sha2 {
+			continue
+		}
 
 		opts := VerifyOptions{
 			Intermediates: NewCertPool(),
diff --git a/third_party/gofrontend/libgo/go/crypto/x509/x509.go b/third_party/gofrontend/libgo/go/crypto/x509/x509.go
index 7a37b98..be6c013 100644
--- a/third_party/gofrontend/libgo/go/crypto/x509/x509.go
+++ b/third_party/gofrontend/libgo/go/crypto/x509/x509.go
@@ -12,7 +12,7 @@
 	"crypto/ecdsa"
 	"crypto/elliptic"
 	"crypto/rsa"
-	"crypto/sha1"
+	_ "crypto/sha1"
 	_ "crypto/sha256"
 	_ "crypto/sha512"
 	"crypto/x509/pkix"
@@ -37,8 +37,10 @@
 // typically found in PEM blocks with "BEGIN PUBLIC KEY".
 func ParsePKIXPublicKey(derBytes []byte) (pub interface{}, err error) {
 	var pki publicKeyInfo
-	if _, err = asn1.Unmarshal(derBytes, &pki); err != nil {
-		return
+	if rest, err := asn1.Unmarshal(derBytes, &pki); err != nil {
+		return nil, err
+	} else if len(rest) != 0 {
+		return nil, errors.New("x509: trailing data after ASN.1 of public-key")
 	}
 	algo := getPublicKeyAlgorithmFromOID(pki.Algorithm.Algorithm)
 	if algo == UnknownPublicKeyAlgorithm {
@@ -488,6 +490,16 @@
 	// field is not populated when parsing certificates, see Extensions.
 	ExtraExtensions []pkix.Extension
 
+	// UnhandledCriticalExtensions contains a list of extension IDs that
+	// were not (fully) processed when parsing. Verify will fail if this
+	// slice is non-empty, unless verification is delegated to an OS
+	// library which understands all the critical extensions.
+	//
+	// Users can access these extensions using Extensions and can remove
+	// elements from this slice if they believe that they have been
+	// handled.
+	UnhandledCriticalExtensions []asn1.ObjectIdentifier
+
 	ExtKeyUsage        []ExtKeyUsage           // Sequence of extended key usages.
 	UnknownExtKeyUsage []asn1.ObjectIdentifier // Encountered extended key usages unknown to this package.
 
@@ -619,6 +631,12 @@
 // CheckSignature verifies that signature is a valid signature over signed from
 // c's public key.
 func (c *Certificate) CheckSignature(algo SignatureAlgorithm, signed, signature []byte) (err error) {
+	return checkSignature(algo, signed, signature, c.PublicKey)
+}
+
+// CheckSignature verifies that signature is a valid signature over signed from
+// a crypto.PublicKey.
+func checkSignature(algo SignatureAlgorithm, signed, signature []byte, publicKey crypto.PublicKey) (err error) {
 	var hashType crypto.Hash
 
 	switch algo {
@@ -642,13 +660,15 @@
 	h.Write(signed)
 	digest := h.Sum(nil)
 
-	switch pub := c.PublicKey.(type) {
+	switch pub := publicKey.(type) {
 	case *rsa.PublicKey:
 		return rsa.VerifyPKCS1v15(pub, hashType, digest, signature)
 	case *dsa.PublicKey:
 		dsaSig := new(dsaSignature)
-		if _, err := asn1.Unmarshal(signature, dsaSig); err != nil {
+		if rest, err := asn1.Unmarshal(signature, dsaSig); err != nil {
 			return err
+		} else if len(rest) != 0 {
+			return errors.New("x509: trailing data after DSA signature")
 		}
 		if dsaSig.R.Sign() <= 0 || dsaSig.S.Sign() <= 0 {
 			return errors.New("x509: DSA signature contained zero or negative values")
@@ -659,8 +679,10 @@
 		return
 	case *ecdsa.PublicKey:
 		ecdsaSig := new(ecdsaSignature)
-		if _, err := asn1.Unmarshal(signature, ecdsaSig); err != nil {
+		if rest, err := asn1.Unmarshal(signature, ecdsaSig); err != nil {
 			return err
+		} else if len(rest) != 0 {
+			return errors.New("x509: trailing data after ECDSA signature")
 		}
 		if ecdsaSig.R.Sign() <= 0 || ecdsaSig.S.Sign() <= 0 {
 			return errors.New("x509: ECDSA signature contained zero or negative values")
@@ -729,10 +751,13 @@
 	switch algo {
 	case RSA:
 		p := new(rsaPublicKey)
-		_, err := asn1.Unmarshal(asn1Data, p)
+		rest, err := asn1.Unmarshal(asn1Data, p)
 		if err != nil {
 			return nil, err
 		}
+		if len(rest) != 0 {
+			return nil, errors.New("x509: trailing data after RSA public key")
+		}
 
 		if p.N.Sign() <= 0 {
 			return nil, errors.New("x509: RSA modulus is not a positive number")
@@ -748,16 +773,22 @@
 		return pub, nil
 	case DSA:
 		var p *big.Int
-		_, err := asn1.Unmarshal(asn1Data, &p)
+		rest, err := asn1.Unmarshal(asn1Data, &p)
 		if err != nil {
 			return nil, err
 		}
+		if len(rest) != 0 {
+			return nil, errors.New("x509: trailing data after DSA public key")
+		}
 		paramsData := keyData.Algorithm.Parameters.FullBytes
 		params := new(dsaAlgorithmParameters)
-		_, err = asn1.Unmarshal(paramsData, params)
+		rest, err = asn1.Unmarshal(paramsData, params)
 		if err != nil {
 			return nil, err
 		}
+		if len(rest) != 0 {
+			return nil, errors.New("x509: trailing data after DSA parameters")
+		}
 		if p.Sign() <= 0 || params.P.Sign() <= 0 || params.Q.Sign() <= 0 || params.G.Sign() <= 0 {
 			return nil, errors.New("x509: zero or negative DSA parameter")
 		}
@@ -773,10 +804,13 @@
 	case ECDSA:
 		paramsData := keyData.Algorithm.Parameters.FullBytes
 		namedCurveOID := new(asn1.ObjectIdentifier)
-		_, err := asn1.Unmarshal(paramsData, namedCurveOID)
+		rest, err := asn1.Unmarshal(paramsData, namedCurveOID)
 		if err != nil {
 			return nil, err
 		}
+		if len(rest) != 0 {
+			return nil, errors.New("x509: trailing data after ECDSA parameters")
+		}
 		namedCurve := namedCurveFromOID(*namedCurveOID)
 		if namedCurve == nil {
 			return nil, errors.New("x509: unsupported elliptic curve")
@@ -814,7 +848,11 @@
 	//      iPAddress                       [7]     OCTET STRING,
 	//      registeredID                    [8]     OBJECT IDENTIFIER }
 	var seq asn1.RawValue
-	if _, err = asn1.Unmarshal(value, &seq); err != nil {
+	var rest []byte
+	if rest, err = asn1.Unmarshal(value, &seq); err != nil {
+		return
+	} else if len(rest) != 0 {
+		err = errors.New("x509: trailing data after X.509 extension")
 		return
 	}
 	if !seq.IsCompound || seq.Tag != 16 || seq.Class != 0 {
@@ -822,7 +860,7 @@
 		return
 	}
 
-	rest := seq.Bytes
+	rest = seq.Bytes
 	for len(rest) > 0 {
 		var v asn1.RawValue
 		rest, err = asn1.Unmarshal(rest, &v)
@@ -876,11 +914,15 @@
 	out.SerialNumber = in.TBSCertificate.SerialNumber
 
 	var issuer, subject pkix.RDNSequence
-	if _, err := asn1.Unmarshal(in.TBSCertificate.Subject.FullBytes, &subject); err != nil {
+	if rest, err := asn1.Unmarshal(in.TBSCertificate.Subject.FullBytes, &subject); err != nil {
 		return nil, err
+	} else if len(rest) != 0 {
+		return nil, errors.New("x509: trailing data after X.509 subject")
 	}
-	if _, err := asn1.Unmarshal(in.TBSCertificate.Issuer.FullBytes, &issuer); err != nil {
+	if rest, err := asn1.Unmarshal(in.TBSCertificate.Issuer.FullBytes, &issuer); err != nil {
 		return nil, err
+	} else if len(rest) != 0 {
+		return nil, errors.New("x509: trailing data after X.509 subject")
 	}
 
 	out.Issuer.FillFromRDNSequence(&issuer)
@@ -891,47 +933,51 @@
 
 	for _, e := range in.TBSCertificate.Extensions {
 		out.Extensions = append(out.Extensions, e)
+		unhandled := false
 
 		if len(e.Id) == 4 && e.Id[0] == 2 && e.Id[1] == 5 && e.Id[2] == 29 {
 			switch e.Id[3] {
 			case 15:
 				// RFC 5280, 4.2.1.3
 				var usageBits asn1.BitString
-				_, err := asn1.Unmarshal(e.Value, &usageBits)
-
-				if err == nil {
-					var usage int
-					for i := 0; i < 9; i++ {
-						if usageBits.At(i) != 0 {
-							usage |= 1 << uint(i)
-						}
-					}
-					out.KeyUsage = KeyUsage(usage)
-					continue
+				if rest, err := asn1.Unmarshal(e.Value, &usageBits); err != nil {
+					return nil, err
+				} else if len(rest) != 0 {
+					return nil, errors.New("x509: trailing data after X.509 KeyUsage")
 				}
+
+				var usage int
+				for i := 0; i < 9; i++ {
+					if usageBits.At(i) != 0 {
+						usage |= 1 << uint(i)
+					}
+				}
+				out.KeyUsage = KeyUsage(usage)
+
 			case 19:
 				// RFC 5280, 4.2.1.9
 				var constraints basicConstraints
-				_, err := asn1.Unmarshal(e.Value, &constraints)
-
-				if err == nil {
-					out.BasicConstraintsValid = true
-					out.IsCA = constraints.IsCA
-					out.MaxPathLen = constraints.MaxPathLen
-					out.MaxPathLenZero = out.MaxPathLen == 0
-					continue
+				if rest, err := asn1.Unmarshal(e.Value, &constraints); err != nil {
+					return nil, err
+				} else if len(rest) != 0 {
+					return nil, errors.New("x509: trailing data after X.509 BasicConstraints")
 				}
+
+				out.BasicConstraintsValid = true
+				out.IsCA = constraints.IsCA
+				out.MaxPathLen = constraints.MaxPathLen
+				out.MaxPathLenZero = out.MaxPathLen == 0
+
 			case 17:
 				out.DNSNames, out.EmailAddresses, out.IPAddresses, err = parseSANExtension(e.Value)
 				if err != nil {
 					return nil, err
 				}
 
-				if len(out.DNSNames) > 0 || len(out.EmailAddresses) > 0 || len(out.IPAddresses) > 0 {
-					continue
+				if len(out.DNSNames) == 0 && len(out.EmailAddresses) == 0 && len(out.IPAddresses) == 0 {
+					// If we didn't parse anything then we do the critical check, below.
+					unhandled = true
 				}
-				// If we didn't parse any of the names then we
-				// fall through to the critical check below.
 
 			case 30:
 				// RFC 5280, 4.2.1.10
@@ -950,9 +996,10 @@
 				// BaseDistance ::= INTEGER (0..MAX)
 
 				var constraints nameConstraints
-				_, err := asn1.Unmarshal(e.Value, &constraints)
-				if err != nil {
+				if rest, err := asn1.Unmarshal(e.Value, &constraints); err != nil {
 					return nil, err
+				} else if len(rest) != 0 {
+					return nil, errors.New("x509: trailing data after X.509 NameConstraints")
 				}
 
 				if len(constraints.Excluded) > 0 && e.Critical {
@@ -968,7 +1015,6 @@
 					}
 					out.PermittedDNSDomains = append(out.PermittedDNSDomains, subtree.Name)
 				}
-				continue
 
 			case 31:
 				// RFC 5280, 4.2.1.14
@@ -985,33 +1031,35 @@
 				//     nameRelativeToCRLIssuer [1]     RelativeDistinguishedName }
 
 				var cdp []distributionPoint
-				_, err := asn1.Unmarshal(e.Value, &cdp)
-				if err != nil {
+				if rest, err := asn1.Unmarshal(e.Value, &cdp); err != nil {
 					return nil, err
+				} else if len(rest) != 0 {
+					return nil, errors.New("x509: trailing data after X.509 CRL distribution point")
 				}
 
 				for _, dp := range cdp {
 					var n asn1.RawValue
-					_, err = asn1.Unmarshal(dp.DistributionPoint.FullName.Bytes, &n)
-					if err != nil {
+					if _, err := asn1.Unmarshal(dp.DistributionPoint.FullName.Bytes, &n); err != nil {
 						return nil, err
 					}
+					// Trailing data after the fullName is
+					// allowed because other elements of
+					// the SEQUENCE can appear.
 
 					if n.Tag == 6 {
 						out.CRLDistributionPoints = append(out.CRLDistributionPoints, string(n.Bytes))
 					}
 				}
-				continue
 
 			case 35:
 				// RFC 5280, 4.2.1.1
 				var a authKeyId
-				_, err = asn1.Unmarshal(e.Value, &a)
-				if err != nil {
+				if rest, err := asn1.Unmarshal(e.Value, &a); err != nil {
 					return nil, err
+				} else if len(rest) != 0 {
+					return nil, errors.New("x509: trailing data after X.509 authority key-id")
 				}
 				out.AuthorityKeyId = a.Id
-				continue
 
 			case 37:
 				// RFC 5280, 4.2.1.12.  Extended Key Usage
@@ -1023,9 +1071,10 @@
 				// KeyPurposeId ::= OBJECT IDENTIFIER
 
 				var keyUsage []asn1.ObjectIdentifier
-				_, err = asn1.Unmarshal(e.Value, &keyUsage)
-				if err != nil {
+				if rest, err := asn1.Unmarshal(e.Value, &keyUsage); err != nil {
 					return nil, err
+				} else if len(rest) != 0 {
+					return nil, errors.New("x509: trailing data after X.509 ExtendedKeyUsage")
 				}
 
 				for _, u := range keyUsage {
@@ -1036,34 +1085,40 @@
 					}
 				}
 
-				continue
-
 			case 14:
 				// RFC 5280, 4.2.1.2
 				var keyid []byte
-				_, err = asn1.Unmarshal(e.Value, &keyid)
-				if err != nil {
+				if rest, err := asn1.Unmarshal(e.Value, &keyid); err != nil {
 					return nil, err
+				} else if len(rest) != 0 {
+					return nil, errors.New("x509: trailing data after X.509 authority key-id")
 				}
 				out.SubjectKeyId = keyid
-				continue
 
 			case 32:
 				// RFC 5280 4.2.1.4: Certificate Policies
 				var policies []policyInformation
-				if _, err = asn1.Unmarshal(e.Value, &policies); err != nil {
+				if rest, err := asn1.Unmarshal(e.Value, &policies); err != nil {
 					return nil, err
+				} else if len(rest) != 0 {
+					return nil, errors.New("x509: trailing data after X.509 certificate policies")
 				}
 				out.PolicyIdentifiers = make([]asn1.ObjectIdentifier, len(policies))
 				for i, policy := range policies {
 					out.PolicyIdentifiers[i] = policy.Policy
 				}
+
+			default:
+				// Unknown extensions are recorded if critical.
+				unhandled = true
 			}
 		} else if e.Id.Equal(oidExtensionAuthorityInfoAccess) {
 			// RFC 5280 4.2.2.1: Authority Information Access
 			var aia []authorityInfoAccess
-			if _, err = asn1.Unmarshal(e.Value, &aia); err != nil {
+			if rest, err := asn1.Unmarshal(e.Value, &aia); err != nil {
 				return nil, err
+			} else if len(rest) != 0 {
+				return nil, errors.New("x509: trailing data after X.509 authority information")
 			}
 
 			for _, v := range aia {
@@ -1077,10 +1132,13 @@
 					out.IssuingCertificateURL = append(out.IssuingCertificateURL, string(v.Location.Bytes))
 				}
 			}
+		} else {
+			// Unknown extensions are recorded if critical.
+			unhandled = true
 		}
 
-		if e.Critical {
-			return out, UnhandledCriticalExtension{}
+		if e.Critical && unhandled {
+			out.UnhandledCriticalExtensions = append(out.UnhandledCriticalExtensions, e.Id)
 		}
 	}
 
@@ -1135,6 +1193,26 @@
 	return b3
 }
 
+// asn1BitLength returns the bit-length of bitString by considering the
+// most-significant bit in a byte to be the "first" bit. This convention
+// matches ASN.1, but differs from almost everything else.
+func asn1BitLength(bitString []byte) int {
+	bitLen := len(bitString) * 8
+
+	for i := range bitString {
+		b := bitString[len(bitString)-i-1]
+
+		for bit := uint(0); bit < 8; bit++ {
+			if (b>>bit)&1 == 1 {
+				return bitLen
+			}
+			bitLen--
+		}
+	}
+
+	return 0
+}
+
 var (
 	oidExtensionSubjectKeyId          = []int{2, 5, 29, 14}
 	oidExtensionKeyUsage              = []int{2, 5, 29, 15}
@@ -1203,7 +1281,8 @@
 			l = 2
 		}
 
-		ret[n].Value, err = asn1.Marshal(asn1.BitString{Bytes: a[0:l], BitLength: l * 8})
+		bitString := a[:l]
+		ret[n].Value, err = asn1.Marshal(asn1.BitString{Bytes: bitString, BitLength: asn1BitLength(bitString)})
 		if err != nil {
 			return
 		}
@@ -1368,22 +1447,25 @@
 	return asn1.Marshal(cert.Subject.ToRDNSequence())
 }
 
-// signingParamsForPrivateKey returns the parameters to use for signing with
+// signingParamsForPublicKey returns the parameters to use for signing with
 // priv. If requestedSigAlgo is not zero then it overrides the default
 // signature algorithm.
-func signingParamsForPrivateKey(priv interface{}, requestedSigAlgo SignatureAlgorithm) (hashFunc crypto.Hash, sigAlgo pkix.AlgorithmIdentifier, err error) {
+func signingParamsForPublicKey(pub interface{}, requestedSigAlgo SignatureAlgorithm) (hashFunc crypto.Hash, sigAlgo pkix.AlgorithmIdentifier, err error) {
 	var pubType PublicKeyAlgorithm
 
-	switch priv := priv.(type) {
-	case *rsa.PrivateKey:
+	switch pub := pub.(type) {
+	case *rsa.PublicKey:
 		pubType = RSA
-		sigAlgo.Algorithm = oidSignatureSHA256WithRSA
 		hashFunc = crypto.SHA256
+		sigAlgo.Algorithm = oidSignatureSHA256WithRSA
+		sigAlgo.Parameters = asn1.RawValue{
+			Tag: 5,
+		}
 
-	case *ecdsa.PrivateKey:
+	case *ecdsa.PublicKey:
 		pubType = ECDSA
 
-		switch priv.Curve {
+		switch pub.Curve {
 		case elliptic.P224(), elliptic.P256():
 			hashFunc = crypto.SHA256
 			sigAlgo.Algorithm = oidSignatureECDSAWithSHA256
@@ -1398,7 +1480,7 @@
 		}
 
 	default:
-		err = errors.New("x509: only RSA and ECDSA private keys supported")
+		err = errors.New("x509: only RSA and ECDSA keys supported")
 	}
 
 	if err != nil {
@@ -1445,10 +1527,15 @@
 //
 // The returned slice is the certificate in DER encoding.
 //
-// The only supported key types are RSA and ECDSA (*rsa.PublicKey or
-// *ecdsa.PublicKey for pub, *rsa.PrivateKey or *ecdsa.PrivateKey for priv).
-func CreateCertificate(rand io.Reader, template, parent *Certificate, pub interface{}, priv interface{}) (cert []byte, err error) {
-	hashFunc, signatureAlgorithm, err := signingParamsForPrivateKey(priv, template.SignatureAlgorithm)
+// All keys types that are implemented via crypto.Signer are supported (This
+// includes *rsa.PublicKey and *ecdsa.PublicKey.)
+func CreateCertificate(rand io.Reader, template, parent *Certificate, pub, priv interface{}) (cert []byte, err error) {
+	key, ok := priv.(crypto.Signer)
+	if !ok {
+		return nil, errors.New("x509: certificate private key does not implement crypto.Signer")
+	}
+
+	hashFunc, signatureAlgorithm, err := signingParamsForPublicKey(key.Public(), template.SignatureAlgorithm)
 	if err != nil {
 		return nil, err
 	}
@@ -1458,10 +1545,6 @@
 		return nil, err
 	}
 
-	if err != nil {
-		return
-	}
-
 	if len(parent.SubjectKeyId) > 0 {
 		template.AuthorityKeyId = parent.SubjectKeyId
 	}
@@ -1505,30 +1588,17 @@
 	digest := h.Sum(nil)
 
 	var signature []byte
-
-	switch priv := priv.(type) {
-	case *rsa.PrivateKey:
-		signature, err = rsa.SignPKCS1v15(rand, priv, hashFunc, digest)
-	case *ecdsa.PrivateKey:
-		var r, s *big.Int
-		if r, s, err = ecdsa.Sign(rand, priv, digest); err == nil {
-			signature, err = asn1.Marshal(ecdsaSignature{r, s})
-		}
-	default:
-		panic("internal error")
-	}
-
+	signature, err = key.Sign(rand, digest, hashFunc)
 	if err != nil {
 		return
 	}
 
-	cert, err = asn1.Marshal(certificate{
+	return asn1.Marshal(certificate{
 		nil,
 		c,
 		signatureAlgorithm,
 		asn1.BitString{Bytes: signature, BitLength: len(signature) * 8},
 	})
-	return
 }
 
 // pemCRLPrefix is the magic string that indicates that we have a PEM encoded
@@ -1555,53 +1625,66 @@
 // ParseDERCRL parses a DER encoded CRL from the given bytes.
 func ParseDERCRL(derBytes []byte) (certList *pkix.CertificateList, err error) {
 	certList = new(pkix.CertificateList)
-	_, err = asn1.Unmarshal(derBytes, certList)
-	if err != nil {
-		certList = nil
+	if rest, err := asn1.Unmarshal(derBytes, certList); err != nil {
+		return nil, err
+	} else if len(rest) != 0 {
+		return nil, errors.New("x509: trailing data after CRL")
 	}
-	return
+	return certList, nil
 }
 
 // CreateCRL returns a DER encoded CRL, signed by this Certificate, that
 // contains the given list of revoked certificates.
-//
-// The only supported key type is RSA (*rsa.PrivateKey for priv).
 func (c *Certificate) CreateCRL(rand io.Reader, priv interface{}, revokedCerts []pkix.RevokedCertificate, now, expiry time.Time) (crlBytes []byte, err error) {
-	rsaPriv, ok := priv.(*rsa.PrivateKey)
+	key, ok := priv.(crypto.Signer)
 	if !ok {
-		return nil, errors.New("x509: non-RSA private keys not supported")
+		return nil, errors.New("x509: certificate private key does not implement crypto.Signer")
 	}
+
+	hashFunc, signatureAlgorithm, err := signingParamsForPublicKey(key.Public(), 0)
+	if err != nil {
+		return nil, err
+	}
+
 	tbsCertList := pkix.TBSCertificateList{
-		Version: 2,
-		Signature: pkix.AlgorithmIdentifier{
-			Algorithm: oidSignatureSHA1WithRSA,
-		},
+		Version:             1,
+		Signature:           signatureAlgorithm,
 		Issuer:              c.Subject.ToRDNSequence(),
 		ThisUpdate:          now.UTC(),
 		NextUpdate:          expiry.UTC(),
 		RevokedCertificates: revokedCerts,
 	}
 
+	// Authority Key Id
+	if len(c.SubjectKeyId) > 0 {
+		var aki pkix.Extension
+		aki.Id = oidExtensionAuthorityKeyId
+		aki.Value, err = asn1.Marshal(authKeyId{Id: c.SubjectKeyId})
+		if err != nil {
+			return
+		}
+		tbsCertList.Extensions = append(tbsCertList.Extensions, aki)
+	}
+
 	tbsCertListContents, err := asn1.Marshal(tbsCertList)
 	if err != nil {
 		return
 	}
 
-	h := sha1.New()
+	h := hashFunc.New()
 	h.Write(tbsCertListContents)
 	digest := h.Sum(nil)
 
-	signature, err := rsa.SignPKCS1v15(rand, rsaPriv, crypto.SHA1, digest)
+	var signature []byte
+	signature, err = key.Sign(rand, digest, hashFunc)
 	if err != nil {
 		return
 	}
 
 	return asn1.Marshal(pkix.CertificateList{
-		TBSCertList: tbsCertList,
-		SignatureAlgorithm: pkix.AlgorithmIdentifier{
-			Algorithm: oidSignatureSHA1WithRSA,
-		},
-		SignatureValue: asn1.BitString{Bytes: signature, BitLength: len(signature) * 8},
+		TBSCertList:        tbsCertList,
+		SignatureAlgorithm: signatureAlgorithm,
+		SignatureValue:     asn1.BitString{Bytes: signature, BitLength: len(signature) * 8},
 	})
 }
 
@@ -1650,11 +1733,11 @@
 // signature requests (see RFC 2986):
 
 type tbsCertificateRequest struct {
-	Raw        asn1.RawContent
-	Version    int
-	Subject    asn1.RawValue
-	PublicKey  publicKeyInfo
-	Attributes []pkix.AttributeTypeAndValueSET `asn1:"tag:0"`
+	Raw           asn1.RawContent
+	Version       int
+	Subject       asn1.RawValue
+	PublicKey     publicKeyInfo
+	RawAttributes []asn1.RawValue `asn1:"tag:0"`
 }
 
 type certificateRequest struct {
@@ -1668,6 +1751,36 @@
 // extensions in a CSR.
 var oidExtensionRequest = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 9, 14}
 
+// newRawAttributes converts AttributeTypeAndValueSETs from a template
+// CertificateRequest's Attributes into tbsCertificateRequest RawAttributes.
+func newRawAttributes(attributes []pkix.AttributeTypeAndValueSET) ([]asn1.RawValue, error) {
+	var rawAttributes []asn1.RawValue
+	b, err := asn1.Marshal(attributes)
+	rest, err := asn1.Unmarshal(b, &rawAttributes)
+	if err != nil {
+		return nil, err
+	}
+	if len(rest) != 0 {
+		return nil, errors.New("x509: failed to unmarshall raw CSR Attributes")
+	}
+	return rawAttributes, nil
+}
+
+// parseRawAttributes Unmarshals RawAttributes intos AttributeTypeAndValueSETs.
+func parseRawAttributes(rawAttributes []asn1.RawValue) []pkix.AttributeTypeAndValueSET {
+	var attributes []pkix.AttributeTypeAndValueSET
+	for _, rawAttr := range rawAttributes {
+		var attr pkix.AttributeTypeAndValueSET
+		rest, err := asn1.Unmarshal(rawAttr.FullBytes, &attr)
+		// Ignore attributes that don't parse into pkix.AttributeTypeAndValueSET
+		// (i.e.: challengePassword or unstructuredName).
+		if err == nil && len(rest) == 0 {
+			attributes = append(attributes, attr)
+		}
+	}
+	return attributes
+}
+
 // CreateCertificateRequest creates a new certificate based on a template. The
 // following members of template are used: Subject, Attributes,
 // SignatureAlgorithm, Extensions, DNSNames, EmailAddresses, and IPAddresses.
@@ -1675,26 +1788,24 @@
 //
 // The returned slice is the certificate request in DER encoding.
 //
-// The only supported key types are RSA (*rsa.PrivateKey) and ECDSA
-// (*ecdsa.PrivateKey).
+// All keys types that are implemented via crypto.Signer are supported (This
+// includes *rsa.PublicKey and *ecdsa.PublicKey.)
 func CreateCertificateRequest(rand io.Reader, template *CertificateRequest, priv interface{}) (csr []byte, err error) {
-	hashFunc, sigAlgo, err := signingParamsForPrivateKey(priv, template.SignatureAlgorithm)
+	key, ok := priv.(crypto.Signer)
+	if !ok {
+		return nil, errors.New("x509: certificate private key does not implement crypto.Signer")
+	}
+
+	var hashFunc crypto.Hash
+	var sigAlgo pkix.AlgorithmIdentifier
+	hashFunc, sigAlgo, err = signingParamsForPublicKey(key.Public(), template.SignatureAlgorithm)
 	if err != nil {
 		return nil, err
 	}
 
 	var publicKeyBytes []byte
 	var publicKeyAlgorithm pkix.AlgorithmIdentifier
-
-	switch priv := priv.(type) {
-	case *rsa.PrivateKey:
-		publicKeyBytes, publicKeyAlgorithm, err = marshalPublicKey(&priv.PublicKey)
-	case *ecdsa.PrivateKey:
-		publicKeyBytes, publicKeyAlgorithm, err = marshalPublicKey(&priv.PublicKey)
-	default:
-		panic("internal error")
-	}
-
+	publicKeyBytes, publicKeyAlgorithm, err = marshalPublicKey(key.Public())
 	if err != nil {
 		return nil, err
 	}
@@ -1782,6 +1893,11 @@
 		}
 	}
 
+	rawAttributes, err := newRawAttributes(attributes)
+	if err != nil {
+		return
+	}
+
 	tbsCSR := tbsCertificateRequest{
 		Version: 0, // PKCS #10, RFC 2986
 		Subject: asn1.RawValue{FullBytes: asn1Subject},
@@ -1792,7 +1908,7 @@
 				BitLength: len(publicKeyBytes) * 8,
 			},
 		},
-		Attributes: attributes,
+		RawAttributes: rawAttributes,
 	}
 
 	tbsCSRContents, err := asn1.Marshal(tbsCSR)
@@ -1806,18 +1922,7 @@
 	digest := h.Sum(nil)
 
 	var signature []byte
-	switch priv := priv.(type) {
-	case *rsa.PrivateKey:
-		signature, err = rsa.SignPKCS1v15(rand, priv, hashFunc, digest)
-	case *ecdsa.PrivateKey:
-		var r, s *big.Int
-		if r, s, err = ecdsa.Sign(rand, priv, digest); err == nil {
-			signature, err = asn1.Marshal(ecdsaSignature{r, s})
-		}
-	default:
-		panic("internal error")
-	}
-
+	signature, err = key.Sign(rand, digest, hashFunc)
 	if err != nil {
 		return
 	}
@@ -1860,7 +1965,7 @@
 		PublicKeyAlgorithm: getPublicKeyAlgorithmFromOID(in.TBSCSR.PublicKey.Algorithm.Algorithm),
 
 		Version:    in.TBSCSR.Version,
-		Attributes: in.TBSCSR.Attributes,
+		Attributes: parseRawAttributes(in.TBSCSR.RawAttributes),
 	}
 
 	var err error
@@ -1870,15 +1975,17 @@
 	}
 
 	var subject pkix.RDNSequence
-	if _, err := asn1.Unmarshal(in.TBSCSR.Subject.FullBytes, &subject); err != nil {
+	if rest, err := asn1.Unmarshal(in.TBSCSR.Subject.FullBytes, &subject); err != nil {
 		return nil, err
+	} else if len(rest) != 0 {
+		return nil, errors.New("x509: trailing data after X.509 Subject")
 	}
 
 	out.Subject.FillFromRDNSequence(&subject)
 
 	var extensions []pkix.AttributeTypeAndValue
 
-	for _, atvSet := range in.TBSCSR.Attributes {
+	for _, atvSet := range out.Attributes {
 		if !atvSet.Type.Equal(oidExtensionRequest) {
 			continue
 		}
@@ -1914,3 +2021,8 @@
 
 	return out, nil
 }
+
+// CheckSignature verifies that the signature on c is a valid signature
+func (c *CertificateRequest) CheckSignature() (err error) {
+	return checkSignature(c.SignatureAlgorithm, c.RawTBSCertificateRequest, c.Signature, c.PublicKey)
+}
diff --git a/third_party/gofrontend/libgo/go/crypto/x509/x509_test.go b/third_party/gofrontend/libgo/go/crypto/x509/x509_test.go
index 4f1f0c2..f4f9fa2 100644
--- a/third_party/gofrontend/libgo/go/crypto/x509/x509_test.go
+++ b/third_party/gofrontend/libgo/go/crypto/x509/x509_test.go
@@ -18,11 +18,11 @@
 	"encoding/base64"
 	"encoding/hex"
 	"encoding/pem"
+	"internal/testenv"
 	"math/big"
 	"net"
 	"os/exec"
 	"reflect"
-	"runtime"
 	"testing"
 	"time"
 )
@@ -41,6 +41,13 @@
 		priv.Primes[1].Cmp(rsaPrivateKey.Primes[1]) != 0 {
 		t.Errorf("got:%+v want:%+v", priv, rsaPrivateKey)
 	}
+
+	// This private key includes an invalid prime that
+	// rsa.PrivateKey.Validate should reject.
+	data := []byte("0\x16\x02\x00\x02\x02\u007f\x00\x02\x0200\x02\x0200\x02\x02\x00\x01\x02\x02\u007f\x00")
+	if _, err := ParsePKCS1PrivateKey(data); err == nil {
+		t.Errorf("parsing invalid private key did not result in an error")
+	}
 }
 
 func TestParsePKIXPublicKey(t *testing.T) {
@@ -162,17 +169,31 @@
 	{"a.b.c", "", false},
 	{"example.com", "example.com", true},
 	{"example.com", "www.example.com", false},
+	{"*.example.com", "example.com", false},
 	{"*.example.com", "www.example.com", true},
+	{"*.example.com", "www.example.com.", true},
 	{"*.example.com", "xyz.www.example.com", false},
-	{"*.*.example.com", "xyz.www.example.com", true},
-	{"*.www.*.com", "xyz.www.example.com", true},
+	{"*.*.example.com", "xyz.www.example.com", false},
+	{"*.www.*.com", "xyz.www.example.com", false},
+	{"*bar.example.com", "foobar.example.com", false},
+	{"f*.example.com", "foobar.example.com", false},
+	{"", ".", false},
+	{".", "", false},
+	{".", ".", false},
+	{"example.com", "example.com.", true},
+	{"example.com.", "example.com", true},
+	{"example.com.", "example.com.", true},
+	{"*.com.", "example.com.", true},
+	{"*.com.", "example.com", true},
+	{"*.com", "example.com", true},
+	{"*.com", "example.com.", true},
 }
 
 func TestMatchHostnames(t *testing.T) {
 	for i, test := range matchHostnamesTests {
 		r := matchHostnames(test.pattern, test.host)
 		if r != test.ok {
-			t.Errorf("#%d mismatch got: %t want: %t", i, r, test.ok)
+			t.Errorf("#%d mismatch got: %t want: %t when matching '%s' against '%s'", i, r, test.ok, test.host, test.pattern)
 		}
 	}
 }
@@ -326,6 +347,18 @@
 			Subject: pkix.Name{
 				CommonName:   commonName,
 				Organization: []string{"Σ Acme Co"},
+				Country:      []string{"US"},
+				ExtraNames: []pkix.AttributeTypeAndValue{
+					{
+						Type:  []int{2, 5, 4, 42},
+						Value: "Gopher",
+					},
+					// This should override the Country, above.
+					{
+						Type:  []int{2, 5, 4, 6},
+						Value: "NL",
+					},
+				},
 			},
 			NotBefore: time.Unix(1000, 0),
 			NotAfter:  time.Unix(100000, 0),
@@ -391,6 +424,21 @@
 			t.Errorf("%s: subject wasn't correctly copied from the template. Got %s, want %s", test.name, cert.Subject.CommonName, commonName)
 		}
 
+		if len(cert.Subject.Country) != 1 || cert.Subject.Country[0] != "NL" {
+			t.Errorf("%s: ExtraNames didn't override Country", test.name)
+		}
+
+		found := false
+		for _, atv := range cert.Subject.Names {
+			if atv.Type.Equal([]int{2, 5, 4, 42}) {
+				found = true
+				break
+			}
+		}
+		if !found {
+			t.Errorf("%s: Names didn't contain oid 2.5.4.42 from ExtraNames", test.name)
+		}
+
 		if cert.Issuer.CommonName != commonName {
 			t.Errorf("%s: issuer wasn't correctly copied from the template. Got %s, want %s", test.name, cert.Issuer.CommonName, commonName)
 		}
@@ -448,6 +496,74 @@
 	}
 }
 
+func TestUnknownCriticalExtension(t *testing.T) {
+	priv, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
+	if err != nil {
+		t.Fatalf("Failed to generate ECDSA key: %s", err)
+	}
+
+	oids := []asn1.ObjectIdentifier{
+		// This OID is in the PKIX arc, but unknown.
+		asn1.ObjectIdentifier{2, 5, 29, 999999},
+		// This is a nonsense, unassigned OID.
+		asn1.ObjectIdentifier{1, 2, 3, 4},
+	}
+
+	for _, oid := range oids {
+		template := Certificate{
+			SerialNumber: big.NewInt(1),
+			Subject: pkix.Name{
+				CommonName: "foo",
+			},
+			NotBefore: time.Unix(1000, 0),
+			NotAfter:  time.Now().AddDate(1, 0, 0),
+
+			BasicConstraintsValid: true,
+			IsCA: true,
+
+			KeyUsage:    KeyUsageCertSign,
+			ExtKeyUsage: []ExtKeyUsage{ExtKeyUsageServerAuth},
+
+			ExtraExtensions: []pkix.Extension{
+				{
+					Id:       oid,
+					Critical: true,
+					Value:    nil,
+				},
+			},
+		}
+
+		derBytes, err := CreateCertificate(rand.Reader, &template, &template, &priv.PublicKey, priv)
+		if err != nil {
+			t.Fatalf("failed to create certificate: %s", err)
+		}
+
+		cert, err := ParseCertificate(derBytes)
+		if err != nil {
+			t.Fatalf("Certificate with unknown critical extension was not parsed: %s", err)
+		}
+
+		roots := NewCertPool()
+		roots.AddCert(cert)
+
+		// Setting Roots ensures that Verify won't delegate to the OS
+		// library and thus the correct error should always be
+		// returned.
+		_, err = cert.Verify(VerifyOptions{Roots: roots})
+		if err == nil {
+			t.Fatal("Certificate with unknown critical extension was verified without error")
+		}
+		if _, ok := err.(UnhandledCriticalExtension); !ok {
+			t.Fatalf("Error was %#v, but wanted one of type UnhandledCriticalExtension", err)
+		}
+
+		cert.UnhandledCriticalExtensions = nil
+		if _, err = cert.Verify(VerifyOptions{Roots: roots}); err != nil {
+			t.Errorf("Certificate failed to verify after unhandled critical extensions were cleared: %s", err)
+		}
+	}
+}
+
 // Self-signed certificate using ECDSA with SHA1 & secp256r1
 var ecdsaSHA1CertPem = `
 -----BEGIN CERTIFICATE-----
@@ -739,11 +855,7 @@
 }
 
 func TestImports(t *testing.T) {
-	t.Skip("gccgo does not have a go command")
-	switch runtime.GOOS {
-	case "android", "nacl":
-		t.Skipf("skipping on %s", runtime.GOOS)
-	}
+	testenv.MustHaveGoRun(t)
 
 	if err := exec.Command("go", "run", "x509_test_import.go").Run(); err != nil {
 		t.Errorf("failed to run x509_test_import.go: %s", err)
@@ -813,6 +925,12 @@
 			continue
 		}
 
+		err = out.CheckSignature()
+		if err != nil {
+			t.Errorf("%s: failed to check certificate request signature: %s", test.name, err)
+			continue
+		}
+
 		if out.Subject.CommonName != template.Subject.CommonName {
 			t.Errorf("%s: output subject common name and template subject common name don't match", test.name)
 		} else if len(out.Subject.Organization) != len(template.Subject.Organization) {
@@ -924,33 +1042,35 @@
 }
 
 func TestParseCertificateRequest(t *testing.T) {
-	csrBytes := fromBase64(csrBase64)
-	csr, err := ParseCertificateRequest(csrBytes)
-	if err != nil {
-		t.Fatalf("failed to parse CSR: %s", err)
-	}
-
-	if len(csr.EmailAddresses) != 1 || csr.EmailAddresses[0] != "gopher@golang.org" {
-		t.Errorf("incorrect email addresses found: %v", csr.EmailAddresses)
-	}
-
-	if len(csr.DNSNames) != 1 || csr.DNSNames[0] != "test.example.com" {
-		t.Errorf("incorrect DNS names found: %v", csr.DNSNames)
-	}
-
-	if len(csr.Subject.Country) != 1 || csr.Subject.Country[0] != "AU" {
-		t.Errorf("incorrect Subject name: %v", csr.Subject)
-	}
-
-	found := false
-	for _, e := range csr.Extensions {
-		if e.Id.Equal(oidExtensionBasicConstraints) {
-			found = true
-			break
+	for _, csrBase64 := range csrBase64Array {
+		csrBytes := fromBase64(csrBase64)
+		csr, err := ParseCertificateRequest(csrBytes)
+		if err != nil {
+			t.Fatalf("failed to parse CSR: %s", err)
 		}
-	}
-	if !found {
-		t.Errorf("basic constraints extension not found in CSR")
+
+		if len(csr.EmailAddresses) != 1 || csr.EmailAddresses[0] != "gopher@golang.org" {
+			t.Errorf("incorrect email addresses found: %v", csr.EmailAddresses)
+		}
+
+		if len(csr.DNSNames) != 1 || csr.DNSNames[0] != "test.example.com" {
+			t.Errorf("incorrect DNS names found: %v", csr.DNSNames)
+		}
+
+		if len(csr.Subject.Country) != 1 || csr.Subject.Country[0] != "AU" {
+			t.Errorf("incorrect Subject name: %v", csr.Subject)
+		}
+
+		found := false
+		for _, e := range csr.Extensions {
+			if e.Id.Equal(oidExtensionBasicConstraints) {
+				found = true
+				break
+			}
+		}
+		if !found {
+			t.Errorf("basic constraints extension not found in CSR")
+		}
 	}
 }
 
@@ -1017,12 +1137,42 @@
 	}
 }
 
-// This CSR was generated with OpenSSL:
-//  openssl req -out CSR.csr -new -newkey rsa:2048 -nodes -keyout privateKey.key -config openssl.cnf
+func TestASN1BitLength(t *testing.T) {
+	tests := []struct {
+		bytes  []byte
+		bitLen int
+	}{
+		{nil, 0},
+		{[]byte{0x00}, 0},
+		{[]byte{0x00, 0x00}, 0},
+		{[]byte{0xf0}, 4},
+		{[]byte{0x88}, 5},
+		{[]byte{0xff}, 8},
+		{[]byte{0xff, 0x80}, 9},
+		{[]byte{0xff, 0x81}, 16},
+	}
+
+	for i, test := range tests {
+		if got := asn1BitLength(test.bytes); got != test.bitLen {
+			t.Errorf("#%d: calculated bit-length of %d for %x, wanted %d", i, got, test.bytes, test.bitLen)
+		}
+	}
+}
+
+// These CSR was generated with OpenSSL:
+//  openssl req -out CSR.csr -new -sha256 -nodes -keyout privateKey.key -config openssl.cnf
 //
-// The openssl.cnf needs to include this section:
+// With openssl.cnf containing the following sections:
 //   [ v3_req ]
 //   basicConstraints = CA:FALSE
 //   keyUsage = nonRepudiation, digitalSignature, keyEncipherment
 //   subjectAltName = email:gopher@golang.org,DNS:test.example.com
-const csrBase64 = "MIIC4zCCAcsCAQAwRTELMAkGA1UEBhMCQVUxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoMGEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAOY+MVedRg2JEnyeLcSzcsMv2VcsTfkB5+Etd6hihAh6MrGezNyASMMKuQN6YhCX1icQDiQtGsDLTtheNnSXK06tAhHjAP/hGlszRJp+5+rP2M58fDBAkUBEhskbCUWwpY14jFtVuGNJ8vF8h8IeczdolvQhX9lVai9G0EUXJMliMKdjA899H0mRs9PzHyidyrXFNiZlQXfD8Kg7gETn2Ny965iyI6ujAIYSCvam6TnxRHYH2MBKyVGvsYGbPYUQJCsgdgyajEg6ekihvQY3SzO1HSAlZAd7d1QYO4VeWJ2mY6Wu3Jpmh+AmG19S9CcHqGjd0bhuAX9cpPOKgnEmqn0CAwEAAaBZMFcGCSqGSIb3DQEJDjFKMEgwCQYDVR0TBAIwADALBgNVHQ8EBAMCBeAwLgYDVR0RBCcwJYERZ29waGVyQGdvbGFuZy5vcmeCEHRlc3QuZXhhbXBsZS5jb20wDQYJKoZIhvcNAQEFBQADggEBAC9+QpKfdabxwCWwf4IEe1cKjdXLS1ScSuw27a3kZzQiPV78WJMa6dB8dqhdH5BRwGZ/qsgLrO6ZHlNeIv2Ib41Ccq71ecHW/nXc94A1BzJ/bVdI9LZcmTUvR1/m1jCpN7UqQ0ml1u9VihK7Pe762hEYxuWDQzYEU0l15S/bXmqeq3eF1A59XT/2jwe5+NV0Wwf4UQlkTXsAQMsJ+KzrQafd8Qv2A49o048uRvmjeJDrXLawGVianZ7D5A6Fpd1rZh6XcjqBpmgLw41DRQWENOdzhy+HyphKRv1MlY8OLkNqpGMhu8DdgJVGoT16DGiickoEa7Z3UCPVNgdTkT9jq7U="
+//   [ req_attributes ]
+//   challengePassword = ignored challenge
+//   unstructuredName  = ignored unstructured name
+var csrBase64Array = [...]string{
+	// Just [ v3_req ]
+	"MIIDHDCCAgQCAQAwfjELMAkGA1UEBhMCQVUxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoMGEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZDEUMBIGA1UEAwwLQ29tbW9uIE5hbWUxITAfBgkqhkiG9w0BCQEWEnRlc3RAZW1haWwuYWRkcmVzczCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAK1GY4YFx2ujlZEOJxQVYmsjUnLsd5nFVnNpLE4cV+77sgv9NPNlB8uhn3MXt5leD34rm/2BisCHOifPucYlSrszo2beuKhvwn4+2FxDmWtBEMu/QA16L5IvoOfYZm/gJTsPwKDqvaR0tTU67a9OtxwNTBMI56YKtmwd/o8d3hYv9cg+9ZGAZ/gKONcg/OWYx/XRh6bd0g8DMbCikpWgXKDsvvK1Nk+VtkDO1JxuBaj4Lz/p/MifTfnHoqHxWOWl4EaTs4Ychxsv34/rSj1KD1tJqorIv5Xv2aqv4sjxfbrYzX4kvS5SC1goIovLnhj5UjmQ3Qy8u65eow/LLWw+YFcCAwEAAaBZMFcGCSqGSIb3DQEJDjFKMEgwCQYDVR0TBAIwADALBgNVHQ8EBAMCBeAwLgYDVR0RBCcwJYERZ29waGVyQGdvbGFuZy5vcmeCEHRlc3QuZXhhbXBsZS5jb20wDQYJKoZIhvcNAQELBQADggEBAB6VPMRrchvNW61Tokyq3ZvO6/NoGIbuwUn54q6l5VZW0Ep5Nq8juhegSSnaJ0jrovmUgKDN9vEo2KxuAtwG6udS6Ami3zP+hRd4k9Q8djJPb78nrjzWiindLK5Fps9U5mMoi1ER8ViveyAOTfnZt/jsKUaRsscY2FzE9t9/o5moE6LTcHUS4Ap1eheR+J72WOnQYn3cifYaemsA9MJuLko+kQ6xseqttbh9zjqd9fiCSh/LNkzos9c+mg2yMADitaZinAh+HZi50ooEbjaT3erNq9O6RqwJlgD00g6MQdoz9bTAryCUhCQfkIaepmQ7BxS0pqWNW3MMwfDwx/Snz6g=",
+	// Both [ v3_req ] and [ req_attributes ]
+	"MIIDaTCCAlECAQAwfjELMAkGA1UEBhMCQVUxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoMGEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZDEUMBIGA1UEAwwLQ29tbW9uIE5hbWUxITAfBgkqhkiG9w0BCQEWEnRlc3RAZW1haWwuYWRkcmVzczCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAK1GY4YFx2ujlZEOJxQVYmsjUnLsd5nFVnNpLE4cV+77sgv9NPNlB8uhn3MXt5leD34rm/2BisCHOifPucYlSrszo2beuKhvwn4+2FxDmWtBEMu/QA16L5IvoOfYZm/gJTsPwKDqvaR0tTU67a9OtxwNTBMI56YKtmwd/o8d3hYv9cg+9ZGAZ/gKONcg/OWYx/XRh6bd0g8DMbCikpWgXKDsvvK1Nk+VtkDO1JxuBaj4Lz/p/MifTfnHoqHxWOWl4EaTs4Ychxsv34/rSj1KD1tJqorIv5Xv2aqv4sjxfbrYzX4kvS5SC1goIovLnhj5UjmQ3Qy8u65eow/LLWw+YFcCAwEAAaCBpTAgBgkqhkiG9w0BCQcxEwwRaWdub3JlZCBjaGFsbGVuZ2UwKAYJKoZIhvcNAQkCMRsMGWlnbm9yZWQgdW5zdHJ1Y3R1cmVkIG5hbWUwVwYJKoZIhvcNAQkOMUowSDAJBgNVHRMEAjAAMAsGA1UdDwQEAwIF4DAuBgNVHREEJzAlgRFnb3BoZXJAZ29sYW5nLm9yZ4IQdGVzdC5leGFtcGxlLmNvbTANBgkqhkiG9w0BAQsFAAOCAQEAgxe2N5O48EMsYE7o0rZBB0wi3Ov5/yYfnmmVI22Y3sP6VXbLDW0+UWIeSccOhzUCcZ/G4qcrfhhx6gTZTeA01nP7TdTJURvWAH5iFqj9sQ0qnLq6nEcVHij3sG6M5+BxAIVClQBk6lTCzgphc835Fjj6qSLuJ20XHdL5UfUbiJxx299CHgyBRL+hBUIPfz8p+ZgamyAuDLfnj54zzcRVyLlrmMLNPZNll1Q70RxoU6uWvLH8wB8vQe3Q/guSGubLyLRTUQVPh+dw1L4t8MKFWfX/48jwRM4gIRHFHPeAAE9D9YAoqdIvj/iFm/eQ++7DP8MDwOZWsXeB6jjwHuLmkQ==",
+}
diff --git a/third_party/gofrontend/libgo/go/database/sql/fakedb_test.go b/third_party/gofrontend/libgo/go/database/sql/fakedb_test.go
index a993fd4..8cbbb29 100644
--- a/third_party/gofrontend/libgo/go/database/sql/fakedb_test.go
+++ b/third_party/gofrontend/libgo/go/database/sql/fakedb_test.go
@@ -89,7 +89,10 @@
 	stmtsMade   int
 	stmtsClosed int
 	numPrepare  int
-	bad         bool
+
+	// bad connection tests; see isBad()
+	bad       bool
+	stickyBad bool
 }
 
 func (c *fakeConn) incrStat(v *int) {
@@ -243,13 +246,15 @@
 }
 
 func (c *fakeConn) isBad() bool {
-	// if not simulating bad conn, do nothing
-	if !c.bad {
+	if c.stickyBad {
+		return true
+	} else if c.bad {
+		// alternate between bad conn and not bad conn
+		c.db.badConn = !c.db.badConn
+		return c.db.badConn
+	} else {
 		return false
 	}
-	// alternate between bad conn and not bad conn
-	c.db.badConn = !c.db.badConn
-	return c.db.badConn
 }
 
 func (c *fakeConn) Begin() (driver.Tx, error) {
@@ -466,7 +471,7 @@
 		panic("nil c.db; conn = " + fmt.Sprintf("%#v", c))
 	}
 
-	if hookPrepareBadConn != nil && hookPrepareBadConn() {
+	if c.stickyBad || (hookPrepareBadConn != nil && hookPrepareBadConn()) {
 		return nil, driver.ErrBadConn
 	}
 
@@ -529,7 +534,7 @@
 		return nil, errClosed
 	}
 
-	if hookExecBadConn != nil && hookExecBadConn() {
+	if s.c.stickyBad || (hookExecBadConn != nil && hookExecBadConn()) {
 		return nil, driver.ErrBadConn
 	}
 
@@ -613,7 +618,7 @@
 		return nil, errClosed
 	}
 
-	if hookQueryBadConn != nil && hookQueryBadConn() {
+	if s.c.stickyBad || (hookQueryBadConn != nil && hookQueryBadConn()) {
 		return nil, driver.ErrBadConn
 	}
 
diff --git a/third_party/gofrontend/libgo/go/database/sql/sql.go b/third_party/gofrontend/libgo/go/database/sql/sql.go
index 6e6f246..aaa4ea2 100644
--- a/third_party/gofrontend/libgo/go/database/sql/sql.go
+++ b/third_party/gofrontend/libgo/go/database/sql/sql.go
@@ -6,10 +6,10 @@
 // databases.
 //
 // The sql package must be used in conjunction with a database driver.
-// See http://golang.org/s/sqldrivers for a list of drivers.
+// See https://golang.org/s/sqldrivers for a list of drivers.
 //
 // For more usage examples, see the wiki page at
-// http://golang.org/s/sqlwiki.
+// https://golang.org/s/sqlwiki.
 package sql
 
 import (
@@ -20,14 +20,20 @@
 	"runtime"
 	"sort"
 	"sync"
+	"sync/atomic"
 )
 
-var drivers = make(map[string]driver.Driver)
+var (
+	driversMu sync.Mutex
+	drivers   = make(map[string]driver.Driver)
+)
 
 // Register makes a database driver available by the provided name.
 // If Register is called twice with the same name or if driver is nil,
 // it panics.
 func Register(name string, driver driver.Driver) {
+	driversMu.Lock()
+	defer driversMu.Unlock()
 	if driver == nil {
 		panic("sql: Register driver is nil")
 	}
@@ -38,12 +44,16 @@
 }
 
 func unregisterAllDrivers() {
+	driversMu.Lock()
+	defer driversMu.Unlock()
 	// For tests.
 	drivers = make(map[string]driver.Driver)
 }
 
 // Drivers returns a sorted list of the names of the registered drivers.
 func Drivers() []string {
+	driversMu.Lock()
+	defer driversMu.Unlock()
 	var list []string
 	for name := range drivers {
 		list = append(list, name)
@@ -211,6 +221,10 @@
 type DB struct {
 	driver driver.Driver
 	dsn    string
+	// numClosed is an atomic counter which represents a total number of
+	// closed connections. Stmt.openStmt checks it before cleaning closed
+	// connections in Stmt.css.
+	numClosed uint64
 
 	mu           sync.Mutex // protects following fields
 	freeConn     []*driverConn
@@ -230,6 +244,18 @@
 	maxOpen  int                    // <= 0 means unlimited
 }
 
+// connReuseStrategy determines how (*DB).conn returns database connections.
+type connReuseStrategy uint8
+
+const (
+	// alwaysNewConn forces a new connection to the database.
+	alwaysNewConn connReuseStrategy = iota
+	// cachedOrNewConn returns a cached connection, if available, else waits
+	// for one to become available (if MaxOpenConns has been reached) or
+	// creates a new database connection.
+	cachedOrNewConn
+)
+
 // driverConn wraps a driver.Conn with a mutex, to
 // be held during all calls into the Conn. (including any calls onto
 // interfaces returned via that Conn, such as calls on Tx, Stmt,
@@ -246,7 +272,7 @@
 	// guarded by db.mu
 	inUse      bool
 	onPut      []func() // code (with db.mu held) run when conn is next returned
-	dbmuClosed bool     // same as closed, but guarded by db.mu, for connIfFree
+	dbmuClosed bool     // same as closed, but guarded by db.mu, for removeClosedStmtLocked
 }
 
 func (dc *driverConn) releaseConn(err error) {
@@ -329,6 +355,7 @@
 	dc.db.maybeOpenNewConnections()
 	dc.db.mu.Unlock()
 
+	atomic.AddUint64(&dc.db.numClosed, 1)
 	return err
 }
 
@@ -427,7 +454,7 @@
 //
 // Most users will open a database via a driver-specific connection
 // helper function that returns a *DB. No database drivers are included
-// in the Go standard library. See http://golang.org/s/sqldrivers for
+// in the Go standard library. See https://golang.org/s/sqldrivers for
 // a list of third-party drivers.
 //
 // Open may just validate its arguments without creating a connection
@@ -439,7 +466,9 @@
 // function should be called just once. It is rarely necessary to
 // close a DB.
 func Open(driverName, dataSourceName string) (*DB, error) {
+	driversMu.Lock()
 	driveri, ok := drivers[driverName]
+	driversMu.Unlock()
 	if !ok {
 		return nil, fmt.Errorf("sql: unknown driver %q (forgotten import?)", driverName)
 	}
@@ -459,7 +488,7 @@
 	// TODO(bradfitz): give drivers an optional hook to implement
 	// this in a more efficient or more reliable way, if they
 	// have one.
-	dc, err := db.conn()
+	dc, err := db.conn(cachedOrNewConn)
 	if err != nil {
 		return err
 	}
@@ -566,6 +595,22 @@
 	}
 }
 
+// DBStats contains database statistics.
+type DBStats struct {
+	// OpenConnections is the number of open connections to the database.
+	OpenConnections int
+}
+
+// Stats returns database statistics.
+func (db *DB) Stats() DBStats {
+	db.mu.Lock()
+	stats := DBStats{
+		OpenConnections: db.numOpen,
+	}
+	db.mu.Unlock()
+	return stats
+}
+
 // Assumes db.mu is locked.
 // If there are connRequests and the connection limit hasn't been reached,
 // then tell the connectionOpener to open new connections.
@@ -629,36 +674,37 @@
 
 var errDBClosed = errors.New("sql: database is closed")
 
-// conn returns a newly-opened or cached *driverConn
-func (db *DB) conn() (*driverConn, error) {
+// conn returns a newly-opened or cached *driverConn.
+func (db *DB) conn(strategy connReuseStrategy) (*driverConn, error) {
 	db.mu.Lock()
 	if db.closed {
 		db.mu.Unlock()
 		return nil, errDBClosed
 	}
 
-	// If db.maxOpen > 0 and the number of open connections is over the limit
-	// and there are no free connection, make a request and wait.
-	if db.maxOpen > 0 && db.numOpen >= db.maxOpen && len(db.freeConn) == 0 {
+	// Prefer a free connection, if possible.
+	numFree := len(db.freeConn)
+	if strategy == cachedOrNewConn && numFree > 0 {
+		conn := db.freeConn[0]
+		copy(db.freeConn, db.freeConn[1:])
+		db.freeConn = db.freeConn[:numFree-1]
+		conn.inUse = true
+		db.mu.Unlock()
+		return conn, nil
+	}
+
+	// Out of free connections or we were asked not to use one.  If we're not
+	// allowed to open any more connections, make a request and wait.
+	if db.maxOpen > 0 && db.numOpen >= db.maxOpen {
 		// Make the connRequest channel. It's buffered so that the
 		// connectionOpener doesn't block while waiting for the req to be read.
 		req := make(chan connRequest, 1)
 		db.connRequests = append(db.connRequests, req)
-		db.maybeOpenNewConnections()
 		db.mu.Unlock()
 		ret := <-req
 		return ret.conn, ret.err
 	}
 
-	if c := len(db.freeConn); c > 0 {
-		conn := db.freeConn[0]
-		copy(db.freeConn, db.freeConn[1:])
-		db.freeConn = db.freeConn[:c-1]
-		conn.inUse = true
-		db.mu.Unlock()
-		return conn, nil
-	}
-
 	db.numOpen++ // optimistically
 	db.mu.Unlock()
 	ci, err := db.driver.Open(db.dsn)
@@ -684,42 +730,6 @@
 	errConnBusy   = errors.New("database/sql: internal sentinel error: conn is busy")
 )
 
-// connIfFree returns (wanted, nil) if wanted is still a valid conn and
-// isn't in use.
-//
-// The error is errConnClosed if the connection if the requested connection
-// is invalid because it's been closed.
-//
-// The error is errConnBusy if the connection is in use.
-func (db *DB) connIfFree(wanted *driverConn) (*driverConn, error) {
-	db.mu.Lock()
-	defer db.mu.Unlock()
-	if wanted.dbmuClosed {
-		return nil, errConnClosed
-	}
-	if wanted.inUse {
-		return nil, errConnBusy
-	}
-	idx := -1
-	for ii, v := range db.freeConn {
-		if v == wanted {
-			idx = ii
-			break
-		}
-	}
-	if idx >= 0 {
-		db.freeConn = append(db.freeConn[:idx], db.freeConn[idx+1:]...)
-		wanted.inUse = true
-		return wanted, nil
-	}
-	// TODO(bradfitz): shouldn't get here. After Go 1.1, change this to:
-	// panic("connIfFree call requested a non-closed, non-busy, non-free conn")
-	// Which passes all the tests, but I'm too paranoid to include this
-	// late in Go 1.1.
-	// Instead, treat it like a busy connection:
-	return nil, errConnBusy
-}
-
 // putConnHook is a hook for testing.
 var putConnHook func(*DB, *driverConn)
 
@@ -797,6 +807,9 @@
 // If a connRequest was fulfilled or the *driverConn was placed in the
 // freeConn list, then true is returned, otherwise false is returned.
 func (db *DB) putConnDBLocked(dc *driverConn, err error) bool {
+	if db.maxOpen > 0 && db.numOpen > db.maxOpen {
+		return false
+	}
 	if c := len(db.connRequests); c > 0 {
 		req := db.connRequests[0]
 		// This copy is O(n) but in practice faster than a linked list.
@@ -820,32 +833,38 @@
 }
 
 // maxBadConnRetries is the number of maximum retries if the driver returns
-// driver.ErrBadConn to signal a broken connection.
-const maxBadConnRetries = 10
+// driver.ErrBadConn to signal a broken connection before forcing a new
+// connection to be opened.
+const maxBadConnRetries = 2
 
 // Prepare creates a prepared statement for later queries or executions.
 // Multiple queries or executions may be run concurrently from the
 // returned statement.
+// The caller must call the statement's Close method
+// when the statement is no longer needed.
 func (db *DB) Prepare(query string) (*Stmt, error) {
 	var stmt *Stmt
 	var err error
 	for i := 0; i < maxBadConnRetries; i++ {
-		stmt, err = db.prepare(query)
+		stmt, err = db.prepare(query, cachedOrNewConn)
 		if err != driver.ErrBadConn {
 			break
 		}
 	}
+	if err == driver.ErrBadConn {
+		return db.prepare(query, alwaysNewConn)
+	}
 	return stmt, err
 }
 
-func (db *DB) prepare(query string) (*Stmt, error) {
+func (db *DB) prepare(query string, strategy connReuseStrategy) (*Stmt, error) {
 	// TODO: check if db.driver supports an optional
 	// driver.Preparer interface and call that instead, if so,
 	// otherwise we make a prepared statement that's bound
 	// to a connection, and to execute this prepared statement
 	// we either need to use this connection (if it's free), else
 	// get a new connection + re-prepare + execute on that one.
-	dc, err := db.conn()
+	dc, err := db.conn(strategy)
 	if err != nil {
 		return nil, err
 	}
@@ -857,9 +876,10 @@
 		return nil, err
 	}
 	stmt := &Stmt{
-		db:    db,
-		query: query,
-		css:   []connStmt{{dc, si}},
+		db:            db,
+		query:         query,
+		css:           []connStmt{{dc, si}},
+		lastNumClosed: atomic.LoadUint64(&db.numClosed),
 	}
 	db.addDep(stmt, stmt)
 	db.putConn(dc, nil)
@@ -872,16 +892,19 @@
 	var res Result
 	var err error
 	for i := 0; i < maxBadConnRetries; i++ {
-		res, err = db.exec(query, args)
+		res, err = db.exec(query, args, cachedOrNewConn)
 		if err != driver.ErrBadConn {
 			break
 		}
 	}
+	if err == driver.ErrBadConn {
+		return db.exec(query, args, alwaysNewConn)
+	}
 	return res, err
 }
 
-func (db *DB) exec(query string, args []interface{}) (res Result, err error) {
-	dc, err := db.conn()
+func (db *DB) exec(query string, args []interface{}, strategy connReuseStrategy) (res Result, err error) {
+	dc, err := db.conn(strategy)
 	if err != nil {
 		return nil, err
 	}
@@ -921,16 +944,19 @@
 	var rows *Rows
 	var err error
 	for i := 0; i < maxBadConnRetries; i++ {
-		rows, err = db.query(query, args)
+		rows, err = db.query(query, args, cachedOrNewConn)
 		if err != driver.ErrBadConn {
 			break
 		}
 	}
+	if err == driver.ErrBadConn {
+		return db.query(query, args, alwaysNewConn)
+	}
 	return rows, err
 }
 
-func (db *DB) query(query string, args []interface{}) (*Rows, error) {
-	ci, err := db.conn()
+func (db *DB) query(query string, args []interface{}, strategy connReuseStrategy) (*Rows, error) {
+	ci, err := db.conn(strategy)
 	if err != nil {
 		return nil, err
 	}
@@ -1009,16 +1035,19 @@
 	var tx *Tx
 	var err error
 	for i := 0; i < maxBadConnRetries; i++ {
-		tx, err = db.begin()
+		tx, err = db.begin(cachedOrNewConn)
 		if err != driver.ErrBadConn {
 			break
 		}
 	}
+	if err == driver.ErrBadConn {
+		return db.begin(alwaysNewConn)
+	}
 	return tx, err
 }
 
-func (db *DB) begin() (tx *Tx, err error) {
-	dc, err := db.conn()
+func (db *DB) begin(strategy connReuseStrategy) (tx *Tx, err error) {
+	dc, err := db.conn(strategy)
 	if err != nil {
 		return nil, err
 	}
@@ -1047,6 +1076,10 @@
 //
 // After a call to Commit or Rollback, all operations on the
 // transaction fail with ErrTxDone.
+//
+// The statements prepared for a transaction by calling
+// the transaction's Prepare or Stmt methods are closed
+// by the call to Commit or Rollback.
 type Tx struct {
 	db *DB
 
@@ -1182,6 +1215,9 @@
 //  tx, err := db.Begin()
 //  ...
 //  res, err := tx.Stmt(updateMoney).Exec(123.45, 98293203)
+//
+// The returned statement operates within the transaction and can no longer
+// be used once the transaction has been committed or rolled back.
 func (tx *Tx) Stmt(stmt *Stmt) *Stmt {
 	// TODO(bradfitz): optimize this. Currently this re-prepares
 	// each time.  This is fine for now to illustrate the API but
@@ -1273,7 +1309,8 @@
 	si driver.Stmt
 }
 
-// Stmt is a prepared statement. Stmt is safe for concurrent use by multiple goroutines.
+// Stmt is a prepared statement.
+// A Stmt is safe for concurrent use by multiple goroutines.
 type Stmt struct {
 	// Immutable:
 	db        *DB    // where we came from
@@ -1294,6 +1331,10 @@
 	// used if tx == nil and one is found that has idle
 	// connections.  If tx != nil, txsi is always used.
 	css []connStmt
+
+	// lastNumClosed is copied from db.numClosed when Stmt is created
+	// without tx and closed connections in css are removed.
+	lastNumClosed uint64
 }
 
 // Exec executes a prepared statement with the given arguments and
@@ -1347,6 +1388,32 @@
 	return driverResult{ds.Locker, resi}, nil
 }
 
+// removeClosedStmtLocked removes closed conns in s.css.
+//
+// To avoid lock contention on DB.mu, we do it only when
+// s.db.numClosed - s.lastNum is large enough.
+func (s *Stmt) removeClosedStmtLocked() {
+	t := len(s.css)/2 + 1
+	if t > 10 {
+		t = 10
+	}
+	dbClosed := atomic.LoadUint64(&s.db.numClosed)
+	if dbClosed-s.lastNumClosed < uint64(t) {
+		return
+	}
+
+	s.db.mu.Lock()
+	for i := 0; i < len(s.css); i++ {
+		if s.css[i].dc.dbmuClosed {
+			s.css[i] = s.css[len(s.css)-1]
+			s.css = s.css[:len(s.css)-1]
+			i--
+		}
+	}
+	s.db.mu.Unlock()
+	s.lastNumClosed = dbClosed
+}
+
 // connStmt returns a free driver connection on which to execute the
 // statement, a function to call to release the connection, and a
 // statement bound to that connection.
@@ -1373,35 +1440,15 @@
 		return ci, releaseConn, s.txsi.si, nil
 	}
 
-	for i := 0; i < len(s.css); i++ {
-		v := s.css[i]
-		_, err := s.db.connIfFree(v.dc)
-		if err == nil {
-			s.mu.Unlock()
-			return v.dc, v.dc.releaseConn, v.si, nil
-		}
-		if err == errConnClosed {
-			// Lazily remove dead conn from our freelist.
-			s.css[i] = s.css[len(s.css)-1]
-			s.css = s.css[:len(s.css)-1]
-			i--
-		}
-
-	}
+	s.removeClosedStmtLocked()
 	s.mu.Unlock()
 
-	// If all connections are busy, either wait for one to become available (if
-	// we've already hit the maximum number of open connections) or create a
-	// new one.
-	//
 	// TODO(bradfitz): or always wait for one? make configurable later?
-	dc, err := s.db.conn()
+	dc, err := s.db.conn(cachedOrNewConn)
 	if err != nil {
 		return nil, nil, nil, err
 	}
 
-	// Do another pass over the list to see whether this statement has
-	// already been prepared on the connection assigned to us.
 	s.mu.Lock()
 	for _, v := range s.css {
 		if v.dc == dc {
diff --git a/third_party/gofrontend/libgo/go/database/sql/sql_test.go b/third_party/gofrontend/libgo/go/database/sql/sql_test.go
index 34efdf2..432a641 100644
--- a/third_party/gofrontend/libgo/go/database/sql/sql_test.go
+++ b/third_party/gofrontend/libgo/go/database/sql/sql_test.go
@@ -497,7 +497,7 @@
 	}
 }
 
-// Issue: http://golang.org/issue/2784
+// Issue: https://golang.org/issue/2784
 // This test didn't fail before because we got lucky with the fakedb driver.
 // It was failing, and now not, in github.com/bradfitz/go-sql-test
 func TestTxQuery(t *testing.T) {
@@ -1070,6 +1070,57 @@
 	}
 }
 
+// Issue 9453: tests that SetMaxOpenConns can be lowered at runtime
+// and affects the subsequent release of connections.
+func TestMaxOpenConnsOnBusy(t *testing.T) {
+	defer setHookpostCloseConn(nil)
+	setHookpostCloseConn(func(_ *fakeConn, err error) {
+		if err != nil {
+			t.Errorf("Error closing fakeConn: %v", err)
+		}
+	})
+
+	db := newTestDB(t, "magicquery")
+	defer closeDB(t, db)
+
+	db.SetMaxOpenConns(3)
+
+	conn0, err := db.conn(cachedOrNewConn)
+	if err != nil {
+		t.Fatalf("db open conn fail: %v", err)
+	}
+
+	conn1, err := db.conn(cachedOrNewConn)
+	if err != nil {
+		t.Fatalf("db open conn fail: %v", err)
+	}
+
+	conn2, err := db.conn(cachedOrNewConn)
+	if err != nil {
+		t.Fatalf("db open conn fail: %v", err)
+	}
+
+	if g, w := db.numOpen, 3; g != w {
+		t.Errorf("free conns = %d; want %d", g, w)
+	}
+
+	db.SetMaxOpenConns(2)
+	if g, w := db.numOpen, 3; g != w {
+		t.Errorf("free conns = %d; want %d", g, w)
+	}
+
+	conn0.releaseConn(nil)
+	conn1.releaseConn(nil)
+	if g, w := db.numOpen, 2; g != w {
+		t.Errorf("free conns = %d; want %d", g, w)
+	}
+
+	conn2.releaseConn(nil)
+	if g, w := db.numOpen, 2; g != w {
+		t.Errorf("free conns = %d; want %d", g, w)
+	}
+}
+
 func TestSingleOpenConn(t *testing.T) {
 	db := newTestDB(t, "people")
 	defer closeDB(t, db)
@@ -1093,6 +1144,26 @@
 	}
 }
 
+func TestStats(t *testing.T) {
+	db := newTestDB(t, "people")
+	stats := db.Stats()
+	if got := stats.OpenConnections; got != 1 {
+		t.Errorf("stats.OpenConnections = %d; want 1", got)
+	}
+
+	tx, err := db.Begin()
+	if err != nil {
+		t.Fatal(err)
+	}
+	tx.Commit()
+
+	closeDB(t, db)
+	stats = db.Stats()
+	if got := stats.OpenConnections; got != 0 {
+		t.Errorf("stats.OpenConnections = %d; want 0", got)
+	}
+}
+
 // golang.org/issue/5323
 func TestStmtCloseDeps(t *testing.T) {
 	if testing.Short() {
@@ -1314,7 +1385,80 @@
 	}
 }
 
-// golang.org/issue/5781
+// Test cases where there's more than maxBadConnRetries bad connections in the
+// pool (issue 8834)
+func TestManyErrBadConn(t *testing.T) {
+	manyErrBadConnSetup := func() *DB {
+		db := newTestDB(t, "people")
+
+		nconn := maxBadConnRetries + 1
+		db.SetMaxIdleConns(nconn)
+		db.SetMaxOpenConns(nconn)
+		// open enough connections
+		func() {
+			for i := 0; i < nconn; i++ {
+				rows, err := db.Query("SELECT|people|age,name|")
+				if err != nil {
+					t.Fatal(err)
+				}
+				defer rows.Close()
+			}
+		}()
+
+		if db.numOpen != nconn {
+			t.Fatalf("unexpected numOpen %d (was expecting %d)", db.numOpen, nconn)
+		} else if len(db.freeConn) != nconn {
+			t.Fatalf("unexpected len(db.freeConn) %d (was expecting %d)", len(db.freeConn), nconn)
+		}
+		for _, conn := range db.freeConn {
+			conn.ci.(*fakeConn).stickyBad = true
+		}
+		return db
+	}
+
+	// Query
+	db := manyErrBadConnSetup()
+	defer closeDB(t, db)
+	rows, err := db.Query("SELECT|people|age,name|")
+	if err != nil {
+		t.Fatal(err)
+	}
+	if err = rows.Close(); err != nil {
+		t.Fatal(err)
+	}
+
+	// Exec
+	db = manyErrBadConnSetup()
+	defer closeDB(t, db)
+	_, err = db.Exec("INSERT|people|name=Julia,age=19")
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	// Begin
+	db = manyErrBadConnSetup()
+	defer closeDB(t, db)
+	tx, err := db.Begin()
+	if err != nil {
+		t.Fatal(err)
+	}
+	if err = tx.Rollback(); err != nil {
+		t.Fatal(err)
+	}
+
+	// Prepare
+	db = manyErrBadConnSetup()
+	defer closeDB(t, db)
+	stmt, err := db.Prepare("SELECT|people|age,name|")
+	if err != nil {
+		t.Fatal(err)
+	}
+	if err = stmt.Close(); err != nil {
+		t.Fatal(err)
+	}
+}
+
+// golang.org/issue/5718
 func TestErrBadConnReconnect(t *testing.T) {
 	db := newTestDB(t, "foo")
 	defer closeDB(t, db)
@@ -1764,56 +1908,6 @@
 	wg.Wait()
 }
 
-func manyConcurrentQueries(t testing.TB) {
-	maxProcs, numReqs := 16, 500
-	if testing.Short() {
-		maxProcs, numReqs = 4, 50
-	}
-	defer runtime.GOMAXPROCS(runtime.GOMAXPROCS(maxProcs))
-
-	db := newTestDB(t, "people")
-	defer closeDB(t, db)
-
-	stmt, err := db.Prepare("SELECT|people|name|")
-	if err != nil {
-		t.Fatal(err)
-	}
-	defer stmt.Close()
-
-	var wg sync.WaitGroup
-	wg.Add(numReqs)
-
-	reqs := make(chan bool)
-	defer close(reqs)
-
-	for i := 0; i < maxProcs*2; i++ {
-		go func() {
-			for range reqs {
-				rows, err := stmt.Query()
-				if err != nil {
-					t.Errorf("error on query:  %v", err)
-					wg.Done()
-					continue
-				}
-
-				var name string
-				for rows.Next() {
-					rows.Scan(&name)
-				}
-				rows.Close()
-
-				wg.Done()
-			}
-		}()
-	}
-
-	for i := 0; i < numReqs; i++ {
-		reqs <- true
-	}
-
-	wg.Wait()
-}
-
 func TestIssue6081(t *testing.T) {
 	db := newTestDB(t, "people")
 	defer closeDB(t, db)
@@ -1985,3 +2079,31 @@
 		doConcurrentTest(b, ct)
 	}
 }
+
+func BenchmarkManyConcurrentQueries(b *testing.B) {
+	b.ReportAllocs()
+	// To see lock contention in Go 1.4, 16~ cores and 128~ goroutines are required.
+	const parallelism = 16
+
+	db := newTestDB(b, "magicquery")
+	defer closeDB(b, db)
+	db.SetMaxIdleConns(runtime.GOMAXPROCS(0) * parallelism)
+
+	stmt, err := db.Prepare("SELECT|magicquery|op|op=?,millis=?")
+	if err != nil {
+		b.Fatal(err)
+	}
+	defer stmt.Close()
+
+	b.SetParallelism(parallelism)
+	b.RunParallel(func(pb *testing.PB) {
+		for pb.Next() {
+			rows, err := stmt.Query("sleep", 1)
+			if err != nil {
+				b.Error(err)
+				return
+			}
+			rows.Close()
+		}
+	})
+}
diff --git a/third_party/gofrontend/libgo/go/debug/dwarf/buf.go b/third_party/gofrontend/libgo/go/debug/dwarf/buf.go
index 53c46eb..2ade0bd 100644
--- a/third_party/gofrontend/libgo/go/debug/dwarf/buf.go
+++ b/third_party/gofrontend/libgo/go/debug/dwarf/buf.go
@@ -163,6 +163,17 @@
 	return 0
 }
 
+func (b *buf) unitLength() (length Offset, dwarf64 bool) {
+	length = Offset(b.uint32())
+	if length == 0xffffffff {
+		dwarf64 = true
+		length = Offset(b.uint64())
+	} else if length >= 0xfffffff0 {
+		b.error("unit length has reserved value")
+	}
+	return
+}
+
 func (b *buf) error(s string) {
 	if b.err == nil {
 		b.data = nil
diff --git a/third_party/gofrontend/libgo/go/debug/dwarf/class_string.go b/third_party/gofrontend/libgo/go/debug/dwarf/class_string.go
new file mode 100644
index 0000000..0b1206b
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/debug/dwarf/class_string.go
@@ -0,0 +1,17 @@
+// generated by stringer -type=Class; DO NOT EDIT
+
+package dwarf
+
+import "fmt"
+
+const _Class_name = "ClassAddressClassBlockClassConstantClassExprLocClassFlagClassLinePtrClassLocListPtrClassMacPtrClassRangeListPtrClassReferenceClassReferenceSigClassStringClassReferenceAltClassStringAlt"
+
+var _Class_index = [...]uint8{0, 12, 22, 35, 47, 56, 68, 83, 94, 111, 125, 142, 153, 170, 184}
+
+func (i Class) String() string {
+	i -= 1
+	if i < 0 || i+1 >= Class(len(_Class_index)) {
+		return fmt.Sprintf("Class(%d)", i+1)
+	}
+	return _Class_name[_Class_index[i]:_Class_index[i+1]]
+}
diff --git a/third_party/gofrontend/libgo/go/debug/dwarf/const.go b/third_party/gofrontend/libgo/go/debug/dwarf/const.go
index 6cc6bc9..2170db1 100644
--- a/third_party/gofrontend/libgo/go/debug/dwarf/const.go
+++ b/third_party/gofrontend/libgo/go/debug/dwarf/const.go
@@ -453,29 +453,30 @@
 	encImaginaryFloat = 0x09
 )
 
-// Line number opcodes.
+// Statement program standard opcode encodings.
 const (
-	LineExtendedOp     = 0
-	LineCopy           = 1
-	LineAdvancePC      = 2
-	LineAdvanceLine    = 3
-	LineSetFile        = 4
-	LineSetColumn      = 5
-	LineNegateStmt     = 6
-	LineSetBasicBlock  = 7
-	LineConstAddPC     = 8
-	LineFixedAdvancePC = 9
-	// next 3 are DWARF 3
-	LineSetPrologueEnd   = 10
-	LineSetEpilogueBegin = 11
-	LineSetISA           = 12
+	lnsCopy           = 1
+	lnsAdvancePC      = 2
+	lnsAdvanceLine    = 3
+	lnsSetFile        = 4
+	lnsSetColumn      = 5
+	lnsNegateStmt     = 6
+	lnsSetBasicBlock  = 7
+	lnsConstAddPC     = 8
+	lnsFixedAdvancePC = 9
+
+	// DWARF 3
+	lnsSetPrologueEnd   = 10
+	lnsSetEpilogueBegin = 11
+	lnsSetISA           = 12
 )
 
-// Line number extended opcodes.
+// Statement program extended opcode encodings.
 const (
-	LineExtEndSequence = 1
-	LineExtSetAddress  = 2
-	LineExtDefineFile  = 3
-	// next 1 is DWARF 4
-	LineExtSetDiscriminator = 4
+	lneEndSequence = 1
+	lneSetAddress  = 2
+	lneDefineFile  = 3
+
+	// DWARF 4
+	lneSetDiscriminator = 4
 )
diff --git a/third_party/gofrontend/libgo/go/debug/dwarf/entry.go b/third_party/gofrontend/libgo/go/debug/dwarf/entry.go
index b6ba8c0..d607e5b 100644
--- a/third_party/gofrontend/libgo/go/debug/dwarf/entry.go
+++ b/third_party/gofrontend/libgo/go/debug/dwarf/entry.go
@@ -23,8 +23,9 @@
 }
 
 type afield struct {
-	attr Attr
-	fmt  format
+	attr  Attr
+	fmt   format
+	class Class
 }
 
 // a map from entry format ids to their descriptions
@@ -32,7 +33,7 @@
 
 // ParseAbbrev returns the abbreviation table that starts at byte off
 // in the .debug_abbrev section.
-func (d *Data) parseAbbrev(off uint32) (abbrevTable, error) {
+func (d *Data) parseAbbrev(off uint32, vers int) (abbrevTable, error) {
 	if m, ok := d.abbrevCache[off]; ok {
 		return m, nil
 	}
@@ -80,6 +81,7 @@
 		for i := range a.field {
 			a.field[i].attr = Attr(b.uint())
 			a.field[i].fmt = format(b.uint())
+			a.field[i].class = formToClass(a.field[i].fmt, a.field[i].attr, vers, &b)
 		}
 		b.uint()
 		b.uint()
@@ -93,6 +95,118 @@
 	return m, nil
 }
 
+// attrIsExprloc indicates attributes that allow exprloc values that
+// are encoded as block values in DWARF 2 and 3. See DWARF 4, Figure
+// 20.
+var attrIsExprloc = map[Attr]bool{
+	AttrLocation:      true,
+	AttrByteSize:      true,
+	AttrBitOffset:     true,
+	AttrBitSize:       true,
+	AttrStringLength:  true,
+	AttrLowerBound:    true,
+	AttrReturnAddr:    true,
+	AttrStrideSize:    true,
+	AttrUpperBound:    true,
+	AttrCount:         true,
+	AttrDataMemberLoc: true,
+	AttrFrameBase:     true,
+	AttrSegment:       true,
+	AttrStaticLink:    true,
+	AttrUseLocation:   true,
+	AttrVtableElemLoc: true,
+	AttrAllocated:     true,
+	AttrAssociated:    true,
+	AttrDataLocation:  true,
+	AttrStride:        true,
+}
+
+// attrPtrClass indicates the *ptr class of attributes that have
+// encoding formSecOffset in DWARF 4 or formData* in DWARF 2 and 3.
+var attrPtrClass = map[Attr]Class{
+	AttrLocation:      ClassLocListPtr,
+	AttrStmtList:      ClassLinePtr,
+	AttrStringLength:  ClassLocListPtr,
+	AttrReturnAddr:    ClassLocListPtr,
+	AttrStartScope:    ClassRangeListPtr,
+	AttrDataMemberLoc: ClassLocListPtr,
+	AttrFrameBase:     ClassLocListPtr,
+	AttrMacroInfo:     ClassMacPtr,
+	AttrSegment:       ClassLocListPtr,
+	AttrStaticLink:    ClassLocListPtr,
+	AttrUseLocation:   ClassLocListPtr,
+	AttrVtableElemLoc: ClassLocListPtr,
+	AttrRanges:        ClassRangeListPtr,
+}
+
+// formToClass returns the DWARF 4 Class for the given form. If the
+// DWARF version is less then 4, it will disambiguate some forms
+// depending on the attribute.
+func formToClass(form format, attr Attr, vers int, b *buf) Class {
+	switch form {
+	default:
+		b.error("cannot determine class of unknown attribute form")
+		return 0
+
+	case formAddr:
+		return ClassAddress
+
+	case formDwarfBlock1, formDwarfBlock2, formDwarfBlock4, formDwarfBlock:
+		// In DWARF 2 and 3, ClassExprLoc was encoded as a
+		// block. DWARF 4 distinguishes ClassBlock and
+		// ClassExprLoc, but there are no attributes that can
+		// be both, so we also promote ClassBlock values in
+		// DWARF 4 that should be ClassExprLoc in case
+		// producers get this wrong.
+		if attrIsExprloc[attr] {
+			return ClassExprLoc
+		}
+		return ClassBlock
+
+	case formData1, formData2, formData4, formData8, formSdata, formUdata:
+		// In DWARF 2 and 3, ClassPtr was encoded as a
+		// constant. Unlike ClassExprLoc/ClassBlock, some
+		// DWARF 4 attributes need to distinguish Class*Ptr
+		// from ClassConstant, so we only do this promotion
+		// for versions 2 and 3.
+		if class, ok := attrPtrClass[attr]; vers < 4 && ok {
+			return class
+		}
+		return ClassConstant
+
+	case formFlag, formFlagPresent:
+		return ClassFlag
+
+	case formRefAddr, formRef1, formRef2, formRef4, formRef8, formRefUdata:
+		return ClassReference
+
+	case formRefSig8:
+		return ClassReferenceSig
+
+	case formString, formStrp:
+		return ClassString
+
+	case formSecOffset:
+		// DWARF 4 defines four *ptr classes, but doesn't
+		// distinguish them in the encoding. Disambiguate
+		// these classes using the attribute.
+		if class, ok := attrPtrClass[attr]; ok {
+			return class
+		}
+		b.error("cannot determine class of unknown attribute with formSecOffset")
+		return 0
+
+	case formExprloc:
+		return ClassExprLoc
+
+	case formGnuRefAlt:
+		return ClassReferenceAlt
+
+	case formGnuStrpAlt:
+		return ClassStringAlt
+	}
+}
+
 // An entry is a sequence of attribute/value pairs.
 type Entry struct {
 	Offset   Offset // offset of Entry in DWARF info
@@ -102,9 +216,115 @@
 }
 
 // A Field is a single attribute/value pair in an Entry.
+//
+// A value can be one of several "attribute classes" defined by DWARF.
+// The Go types corresponding to each class are:
+//
+//    DWARF class       Go type        Class
+//    -----------       -------        -----
+//    address           uint64         ClassAddress
+//    block             []byte         ClassBlock
+//    constant          int64          ClassConstant
+//    flag              bool           ClassFlag
+//    reference
+//      to info         dwarf.Offset   ClassReference
+//      to type unit    uint64         ClassReferenceSig
+//    string            string         ClassString
+//    exprloc           []byte         ClassExprLoc
+//    lineptr           int64          ClassLinePtr
+//    loclistptr        int64          ClassLocListPtr
+//    macptr            int64          ClassMacPtr
+//    rangelistptr      int64          ClassRangeListPtr
 type Field struct {
-	Attr Attr
-	Val  interface{}
+	Attr  Attr
+	Val   interface{}
+	Class Class
+}
+
+// A Class is the DWARF 4 class of an attibute value.
+//
+// In general, a given attribute's value may take on one of several
+// possible classes defined by DWARF, each of which leads to a
+// slightly different interpretation of the attribute.
+//
+// DWARF version 4 distinguishes attribute value classes more finely
+// than previous versions of DWARF. The reader will disambiguate
+// coarser classes from earlier versions of DWARF into the appropriate
+// DWARF 4 class. For example, DWARF 2 uses "constant" for constants
+// as well as all types of section offsets, but the reader will
+// canonicalize attributes in DWARF 2 files that refer to section
+// offsets to one of the Class*Ptr classes, even though these classes
+// were only defined in DWARF 3.
+type Class int
+
+const (
+	// ClassAddress represents values of type uint64 that are
+	// addresses on the target machine.
+	ClassAddress Class = 1 + iota
+
+	// ClassBlock represents values of type []byte whose
+	// interpretation depends on the attribute.
+	ClassBlock
+
+	// ClassConstant represents values of type int64 that are
+	// constants. The interpretation of this constant depends on
+	// the attribute.
+	ClassConstant
+
+	// ClassExprLoc represents values of type []byte that contain
+	// an encoded DWARF expression or location description.
+	ClassExprLoc
+
+	// ClassFlag represents values of type bool.
+	ClassFlag
+
+	// ClassLinePtr represents values that are an int64 offset
+	// into the "line" section.
+	ClassLinePtr
+
+	// ClassLocListPtr represents values that are an int64 offset
+	// into the "loclist" section.
+	ClassLocListPtr
+
+	// ClassMacPtr represents values that are an int64 offset into
+	// the "mac" section.
+	ClassMacPtr
+
+	// ClassMacPtr represents values that are an int64 offset into
+	// the "rangelist" section.
+	ClassRangeListPtr
+
+	// ClassReference represents values that are an Offset offset
+	// of an Entry in the info section (for use with Reader.Seek).
+	// The DWARF specification combines ClassReference and
+	// ClassReferenceSig into class "reference".
+	ClassReference
+
+	// ClassReferenceSig represents values that are a uint64 type
+	// signature referencing a type Entry.
+	ClassReferenceSig
+
+	// ClassString represents values that are strings. If the
+	// compilation unit specifies the AttrUseUTF8 flag (strongly
+	// recommended), the string value will be encoded in UTF-8.
+	// Otherwise, the encoding is unspecified.
+	ClassString
+
+	// ClassReferenceAlt represents values of type int64 that are
+	// an offset into the DWARF "info" section of an alternate
+	// object file.
+	ClassReferenceAlt
+
+	// ClassStringAlt represents values of type int64 that are an
+	// offset into the DWARF string section of an alternate object
+	// file.
+	ClassStringAlt
+)
+
+//go:generate stringer -type=Class
+
+func (i Class) GoString() string {
+	return "dwarf." + i.String()
 }
 
 // Val returns the value associated with attribute Attr in Entry,
@@ -112,12 +332,21 @@
 //
 // A common idiom is to merge the check for nil return with
 // the check that the value has the expected dynamic type, as in:
-//	v, ok := e.Val(AttrSibling).(int64);
+//	v, ok := e.Val(AttrSibling).(int64)
 //
 func (e *Entry) Val(a Attr) interface{} {
-	for _, f := range e.Field {
+	if f := e.AttrField(a); f != nil {
+		return f.Val
+	}
+	return nil
+}
+
+// AttrField returns the Field associated with attribute Attr in
+// Entry, or nil if there is no such attribute.
+func (e *Entry) AttrField(a Attr) *Field {
+	for i, f := range e.Field {
 		if f.Attr == a {
-			return f.Val
+			return &e.Field[i]
 		}
 	}
 	return nil
@@ -148,6 +377,7 @@
 	}
 	for i := range e.Field {
 		e.Field[i].Attr = a.field[i].attr
+		e.Field[i].Class = a.field[i].class
 		fmt := a.field[i].fmt
 		if fmt == formIndirect {
 			fmt = format(b.uint())
@@ -292,13 +522,10 @@
 	return r
 }
 
-// unitReader returns a new reader starting at a specific unit.
-func (d *Data) unitReader(i int) *Reader {
-	r := &Reader{d: d}
-	r.unit = i
-	u := &d.unit[i]
-	r.b = makeBuf(d, u, "info", u.off, u.data)
-	return r
+// AddressSize returns the size in bytes of addresses in the current compilation
+// unit.
+func (r *Reader) AddressSize() int {
+	return r.d.unit[r.unit].asize
 }
 
 // Seek positions the Reader at offset off in the encoded entry stream.
@@ -317,18 +544,14 @@
 		return
 	}
 
-	// TODO(rsc): binary search (maybe a new package)
-	var i int
-	var u *unit
-	for i = range d.unit {
-		u = &d.unit[i]
-		if u.off <= off && off < u.off+Offset(len(u.data)) {
-			r.unit = i
-			r.b = makeBuf(r.d, u, "info", off, u.data[off-u.off:])
-			return
-		}
+	i := d.offsetToUnit(off)
+	if i == -1 {
+		r.err = errors.New("offset out of range")
+		return
 	}
-	r.err = errors.New("offset out of range")
+	u := &d.unit[i]
+	r.unit = i
+	r.b = makeBuf(r.d, u, "info", off, u.data[off-u.off:])
 }
 
 // maybeNextUnit advances to the next unit if this one is finished.
diff --git a/third_party/gofrontend/libgo/go/debug/dwarf/line.go b/third_party/gofrontend/libgo/go/debug/dwarf/line.go
index c463c3b..ca64bbd 100644
--- a/third_party/gofrontend/libgo/go/debug/dwarf/line.go
+++ b/third_party/gofrontend/libgo/go/debug/dwarf/line.go
@@ -1,481 +1,590 @@
-// Copyright 2012 The Go Authors.  All rights reserved.
+// 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.
 
-// DWARF line number information.
-
 package dwarf
 
 import (
 	"errors"
-	"path/filepath"
-	"sort"
-	"strconv"
+	"fmt"
+	"io"
+	"path"
 )
 
-// A Line holds all the available information about the source code
-// corresponding to a specific program counter address.
-type Line struct {
-	Filename      string // source file name
-	OpIndex       int    // index of operation in VLIW instruction
-	Line          int    // line number
-	Column        int    // column number
-	ISA           int    // instruction set code
-	Discriminator int    // block discriminator
-	Stmt          bool   // instruction starts statement
-	Block         bool   // instruction starts basic block
-	EndPrologue   bool   // instruction ends function prologue
-	BeginEpilogue bool   // instruction begins function epilogue
+// A LineReader reads a sequence of LineEntry structures from a DWARF
+// "line" section for a single compilation unit. LineEntries occur in
+// order of increasing PC and each LineEntry gives metadata for the
+// instructions from that LineEntry's PC to just before the next
+// LineEntry's PC. The last entry will have its EndSequence field set.
+type LineReader struct {
+	buf buf
+
+	// Original .debug_line section data. Used by Seek.
+	section []byte
+
+	// Header information
+	version              uint16
+	minInstructionLength int
+	maxOpsPerInstruction int
+	defaultIsStmt        bool
+	lineBase             int
+	lineRange            int
+	opcodeBase           int
+	opcodeLengths        []int
+	directories          []string
+	fileEntries          []*LineFile
+
+	programOffset Offset // section offset of line number program
+	endOffset     Offset // section offset of byte following program
+
+	initialFileEntries int // initial length of fileEntries
+
+	// Current line number program state machine registers
+	state     LineEntry // public state
+	fileIndex int       // private state
 }
 
-// LineForPc returns the line number information for a program counter
-// address, if any.  When this returns multiple Line structures in a
-// context where only one can be used, the last one is the best.
-func (d *Data) LineForPC(pc uint64) ([]*Line, error) {
-	for i := range d.unit {
-		u := &d.unit[i]
-		if u.pc == nil {
-			if err := d.readUnitLine(i, u); err != nil {
-				return nil, err
-			}
-		}
-		for _, ar := range u.pc {
-			if pc >= ar.low && pc < ar.high {
-				return d.findLine(u, pc)
-			}
-		}
-	}
-	return nil, nil
+// A LineEntry is a row in a DWARF line table.
+type LineEntry struct {
+	// Address is the program-counter value of a machine
+	// instruction generated by the compiler. This LineEntry
+	// applies to each instruction from Address to just before the
+	// Address of the next LineEntry.
+	Address uint64
+
+	// OpIndex is the index of an operation within a VLIW
+	// instruction. The index of the first operation is 0. For
+	// non-VLIW architectures, it will always be 0. Address and
+	// OpIndex together form an operation pointer that can
+	// reference any individual operation within the instruction
+	// stream.
+	OpIndex int
+
+	// File is the source file corresponding to these
+	// instructions.
+	File *LineFile
+
+	// Line is the source code line number corresponding to these
+	// instructions. Lines are numbered beginning at 1. It may be
+	// 0 if these instructions cannot be attributed to any source
+	// line.
+	Line int
+
+	// Column is the column number within the source line of these
+	// instructions. Columns are numbered beginning at 1. It may
+	// be 0 to indicate the "left edge" of the line.
+	Column int
+
+	// IsStmt indicates that Address is a recommended breakpoint
+	// location, such as the beginning of a line, statement, or a
+	// distinct subpart of a statement.
+	IsStmt bool
+
+	// BasicBlock indicates that Address is the beginning of a
+	// basic block.
+	BasicBlock bool
+
+	// PrologueEnd indicates that Address is one (of possibly
+	// many) PCs where execution should be suspended for a
+	// breakpoint on entry to the containing function.
+	//
+	// Added in DWARF 3.
+	PrologueEnd bool
+
+	// EpilogueBegin indicates that Address is one (of possibly
+	// many) PCs where execution should be suspended for a
+	// breakpoint on exit from this function.
+	//
+	// Added in DWARF 3.
+	EpilogueBegin bool
+
+	// ISA is the instruction set architecture for these
+	// instructions. Possible ISA values should be defined by the
+	// applicable ABI specification.
+	//
+	// Added in DWARF 3.
+	ISA int
+
+	// Discriminator is an arbitrary integer indicating the block
+	// to which these instructions belong. It serves to
+	// distinguish among multiple blocks that may all have with
+	// the same source file, line, and column. Where only one
+	// block exists for a given source position, it should be 0.
+	//
+	// Added in DWARF 3.
+	Discriminator int
+
+	// EndSequence indicates that Address is the first byte after
+	// the end of a sequence of target machine instructions. If it
+	// is set, only this and the Address field are meaningful. A
+	// line number table may contain information for multiple
+	// potentially disjoint instruction sequences. The last entry
+	// in a line table should always have EndSequence set.
+	EndSequence bool
 }
 
-// readUnitLine reads in the line number information for a compilation
-// unit.
-func (d *Data) readUnitLine(i int, u *unit) error {
-	r := d.unitReader(i)
-	setLineOff := false
-	for {
-		e, err := r.Next()
-		if err != nil {
-			return err
-		}
-		if e == nil {
-			break
-		}
-		if r.unit != i {
-			break
-		}
-		switch e.Tag {
-		case TagCompileUnit, TagSubprogram, TagEntryPoint, TagInlinedSubroutine:
-			low, lowok := e.Val(AttrLowpc).(uint64)
-			var high uint64
-			var highok bool
-			switch v := e.Val(AttrHighpc).(type) {
-			case uint64:
-				high = v
-				highok = true
-			case int64:
-				high = low + uint64(v)
-				highok = true
-			}
-			if lowok && highok {
-				u.pc = append(u.pc, addrRange{low, high})
-			} else if off, ok := e.Val(AttrRanges).(Offset); ok {
-				if err := d.readAddressRanges(off, low, u); err != nil {
-					return err
-				}
-			}
-			val := e.Val(AttrStmtList)
-			if val != nil {
-				if off, ok := val.(int64); ok {
-					u.lineoff = Offset(off)
-					setLineOff = true
-				} else if off, ok := val.(Offset); ok {
-					u.lineoff = off
-					setLineOff = true
-				} else {
-					return errors.New("unrecognized format for DW_ATTR_stmt_list")
-				}
-			}
-			if dir, ok := e.Val(AttrCompDir).(string); ok {
-				u.dir = dir
-			}
-		}
-	}
-	if !setLineOff {
-		u.lineoff = Offset(0)
-		u.lineoff--
-	}
-	return nil
+// A LineFile is a source file referenced by a DWARF line table entry.
+type LineFile struct {
+	Name   string
+	Mtime  uint64 // Implementation defined modification time, or 0 if unknown
+	Length int    // File length, or 0 if unknown
 }
 
-// readAddressRanges adds address ranges to a unit.
-func (d *Data) readAddressRanges(off Offset, base uint64, u *unit) error {
-	b := makeBuf(d, u, "ranges", off, d.ranges[off:])
-	var highest uint64
-	switch u.addrsize() {
-	case 1:
-		highest = 0xff
-	case 2:
-		highest = 0xffff
-	case 4:
-		highest = 0xffffffff
-	case 8:
-		highest = 0xffffffffffffffff
-	default:
-		return errors.New("unknown address size")
+// LineReader returns a new reader for the line table of compilation
+// unit cu, which must be an Entry with tag TagCompileUnit.
+//
+// If this compilation unit has no line table, it returns nil, nil.
+func (d *Data) LineReader(cu *Entry) (*LineReader, error) {
+	if d.line == nil {
+		// No line tables available.
+		return nil, nil
 	}
-	for {
-		if b.err != nil {
-			return b.err
-		}
-		low := b.addr()
-		high := b.addr()
-		if low == 0 && high == 0 {
-			return b.err
-		} else if low == highest {
-			base = high
-		} else {
-			u.pc = append(u.pc, addrRange{low + base, high + base})
-		}
+
+	// Get line table information from cu.
+	off, ok := cu.Val(AttrStmtList).(int64)
+	if !ok {
+		// cu has no line table.
+		return nil, nil
 	}
+	if off > int64(len(d.line)) {
+		return nil, errors.New("AttrStmtList value out of range")
+	}
+	// AttrCompDir is optional if all file names are absolute. Use
+	// the empty string if it's not present.
+	compDir, _ := cu.Val(AttrCompDir).(string)
+
+	// Create the LineReader.
+	u := &d.unit[d.offsetToUnit(cu.Offset)]
+	buf := makeBuf(d, u, "line", Offset(off), d.line[off:])
+	// The compilation directory is implicitly directories[0].
+	r := LineReader{buf: buf, section: d.line, directories: []string{compDir}}
+
+	// Read the header.
+	if err := r.readHeader(); err != nil {
+		return nil, err
+	}
+
+	// Initialize line reader state.
+	r.Reset()
+
+	return &r, nil
 }
 
-// findLine finds the line information for a PC value, given the unit
-// containing the information.
-func (d *Data) findLine(u *unit, pc uint64) ([]*Line, error) {
-	if u.lines == nil {
-		if err := d.parseLine(u); err != nil {
-			return nil, err
-		}
+// readHeader reads the line number program header from r.buf and sets
+// all of the header fields in r.
+func (r *LineReader) readHeader() error {
+	buf := &r.buf
+
+	// Read basic header fields [DWARF2 6.2.4].
+	hdrOffset := buf.off
+	unitLength, dwarf64 := buf.unitLength()
+	r.endOffset = buf.off + unitLength
+	if r.endOffset > buf.off+Offset(len(buf.data)) {
+		return DecodeError{"line", hdrOffset, fmt.Sprintf("line table end %d exceeds section size %d", r.endOffset, buf.off+Offset(len(buf.data)))}
 	}
-
-	for _, ln := range u.lines {
-		if pc < ln.addrs[0].pc || pc > ln.addrs[len(ln.addrs)-1].pc {
-			continue
-		}
-		i := sort.Search(len(ln.addrs),
-			func(i int) bool { return ln.addrs[i].pc > pc })
-		i--
-		p := new(Line)
-		*p = ln.line
-		p.Line = ln.addrs[i].line
-		ret := []*Line{p}
-		for i++; i < len(ln.addrs) && ln.addrs[i].pc == pc; i++ {
-			p = new(Line)
-			*p = ln.line
-			p.Line = ln.addrs[i].line
-			ret = append(ret, p)
-		}
-		return ret, nil
+	r.version = buf.uint16()
+	if buf.err == nil && (r.version < 2 || r.version > 4) {
+		// DWARF goes to all this effort to make new opcodes
+		// backward-compatible, and then adds fields right in
+		// the middle of the header in new versions, so we're
+		// picky about only supporting known line table
+		// versions.
+		return DecodeError{"line", hdrOffset, fmt.Sprintf("unknown line table version %d", r.version)}
 	}
-
-	return nil, nil
-}
-
-// FileLine returns the file name and line number for a program
-// counter address, or "", 0 if unknown.
-func (d *Data) FileLine(pc uint64) (string, int, error) {
-	r, err := d.LineForPC(pc)
-	if err != nil {
-		return "", 0, err
-	}
-	if r == nil {
-		return "", 0, nil
-	}
-	ln := r[len(r)-1]
-	return ln.Filename, ln.Line, nil
-}
-
-// A mapLineInfo holds the PC values and line numbers associated with
-// a single Line structure.  This representation is chosen to reduce
-// memory usage based on typical debug info.
-type mapLineInfo struct {
-	line  Line      // line.Line will be zero
-	addrs lineAddrs // sorted by PC
-}
-
-// A list of lines.  This will be sorted by PC.
-type lineAddrs []oneLineInfo
-
-func (p lineAddrs) Len() int           { return len(p) }
-func (p lineAddrs) Less(i, j int) bool { return p[i].pc < p[j].pc }
-func (p lineAddrs) Swap(i, j int)      { p[i], p[j] = p[j], p[i] }
-
-// A oneLineInfo is a single PC and line number.
-type oneLineInfo struct {
-	pc   uint64
-	line int
-}
-
-// A lineHdr holds the relevant information from a line number
-// program header.
-type lineHdr struct {
-	version       uint16   // version of line number encoding
-	minInsnLen    uint8    // minimum instruction length
-	maxOpsPerInsn uint8    // maximum number of ops per instruction
-	defStmt       bool     // initial value of stmt register
-	lineBase      int8     // line adjustment base
-	lineRange     uint8    // line adjustment step
-	opBase        uint8    // base of special opcode values
-	opLen         []uint8  // lengths of standard opcodes
-	dirs          []string // directories
-	files         []string // file names
-}
-
-// parseLine parses the line number information for a compilation unit
-func (d *Data) parseLine(u *unit) error {
-	if u.lineoff+1 == 0 {
-		return errors.New("unknown line offset")
-	}
-	b := makeBuf(d, u, "line", u.lineoff, d.line[u.lineoff:])
-	len := uint64(b.uint32())
-	dwarf64 := false
-	if len == 0xffffffff {
-		len = b.uint64()
-		dwarf64 = true
-	}
-	end := b.off + Offset(len)
-	hdr := d.parseLineHdr(u, &b, dwarf64)
-	if b.err == nil {
-		d.parseLineProgram(u, &b, hdr, end)
-	}
-	return b.err
-}
-
-// parseLineHdr parses a line number program header.
-func (d *Data) parseLineHdr(u *unit, b *buf, dwarf64 bool) (hdr lineHdr) {
-	hdr.version = b.uint16()
-	if hdr.version < 2 || hdr.version > 4 {
-		b.error("unsupported DWARF version " + strconv.Itoa(int(hdr.version)))
-		return
-	}
-
-	var hlen Offset
+	var headerLength Offset
 	if dwarf64 {
-		hlen = Offset(b.uint64())
+		headerLength = Offset(buf.uint64())
 	} else {
-		hlen = Offset(b.uint32())
+		headerLength = Offset(buf.uint32())
 	}
-	end := b.off + hlen
-
-	hdr.minInsnLen = b.uint8()
-	if hdr.version < 4 {
-		hdr.maxOpsPerInsn = 1
+	r.programOffset = buf.off + headerLength
+	r.minInstructionLength = int(buf.uint8())
+	if r.version >= 4 {
+		// [DWARF4 6.2.4]
+		r.maxOpsPerInstruction = int(buf.uint8())
 	} else {
-		hdr.maxOpsPerInsn = b.uint8()
+		r.maxOpsPerInstruction = 1
+	}
+	r.defaultIsStmt = buf.uint8() != 0
+	r.lineBase = int(int8(buf.uint8()))
+	r.lineRange = int(buf.uint8())
+
+	// Validate header.
+	if buf.err != nil {
+		return buf.err
+	}
+	if r.maxOpsPerInstruction == 0 {
+		return DecodeError{"line", hdrOffset, "invalid maximum operations per instruction: 0"}
+	}
+	if r.lineRange == 0 {
+		return DecodeError{"line", hdrOffset, "invalid line range: 0"}
 	}
 
-	if b.uint8() == 0 {
-		hdr.defStmt = false
-	} else {
-		hdr.defStmt = true
-	}
-	hdr.lineBase = int8(b.uint8())
-	hdr.lineRange = b.uint8()
-	hdr.opBase = b.uint8()
-	hdr.opLen = b.bytes(int(hdr.opBase - 1))
-
-	for d := b.string(); len(d) > 0; d = b.string() {
-		hdr.dirs = append(hdr.dirs, d)
+	// Read standard opcode length table. This table starts with opcode 1.
+	r.opcodeBase = int(buf.uint8())
+	r.opcodeLengths = make([]int, r.opcodeBase)
+	for i := 1; i < r.opcodeBase; i++ {
+		r.opcodeLengths[i] = int(buf.uint8())
 	}
 
-	for f := b.string(); len(f) > 0; f = b.string() {
-		d := b.uint()
-		if !filepath.IsAbs(f) {
-			if d > 0 {
-				if d > uint64(len(hdr.dirs)) {
-					b.error("DWARF directory index out of range")
-					return
-				}
-				f = filepath.Join(hdr.dirs[d-1], f)
-			} else if u.dir != "" {
-				f = filepath.Join(u.dir, f)
-			}
+	// Validate opcode lengths.
+	if buf.err != nil {
+		return buf.err
+	}
+	for i, length := range r.opcodeLengths {
+		if known, ok := knownOpcodeLengths[i]; ok && known != length {
+			return DecodeError{"line", hdrOffset, fmt.Sprintf("opcode %d expected to have length %d, but has length %d", i, known, length)}
 		}
-		b.uint() // file's last mtime
-		b.uint() // file length
-		hdr.files = append(hdr.files, f)
 	}
 
-	if end > b.off {
-		b.bytes(int(end - b.off))
+	// Read include directories table. The caller already set
+	// directories[0] to the compilation directory.
+	for {
+		directory := buf.string()
+		if buf.err != nil {
+			return buf.err
+		}
+		if len(directory) == 0 {
+			break
+		}
+		if !path.IsAbs(directory) {
+			// Relative paths are implicitly relative to
+			// the compilation directory.
+			directory = path.Join(r.directories[0], directory)
+		}
+		r.directories = append(r.directories, directory)
 	}
 
-	return
+	// Read file name list. File numbering starts with 1, so leave
+	// the first entry nil.
+	r.fileEntries = make([]*LineFile, 1)
+	for {
+		if done, err := r.readFileEntry(); err != nil {
+			return err
+		} else if done {
+			break
+		}
+	}
+	r.initialFileEntries = len(r.fileEntries)
+
+	return buf.err
 }
 
-// parseLineProgram parses a line program, adding information to
-// d.lineInfo as it goes.
-func (d *Data) parseLineProgram(u *unit, b *buf, hdr lineHdr, end Offset) {
-	address := uint64(0)
-	line := 1
-	resetLineInfo := Line{
-		Filename:      "",
+// readFileEntry reads a file entry from either the header or a
+// DW_LNE_define_file extended opcode and adds it to r.fileEntries. A
+// true return value indicates that there are no more entries to read.
+func (r *LineReader) readFileEntry() (bool, error) {
+	name := r.buf.string()
+	if r.buf.err != nil {
+		return false, r.buf.err
+	}
+	if len(name) == 0 {
+		return true, nil
+	}
+	off := r.buf.off
+	dirIndex := int(r.buf.uint())
+	if !path.IsAbs(name) {
+		if dirIndex >= len(r.directories) {
+			return false, DecodeError{"line", off, "directory index too large"}
+		}
+		name = path.Join(r.directories[dirIndex], name)
+	}
+	mtime := r.buf.uint()
+	length := int(r.buf.uint())
+
+	r.fileEntries = append(r.fileEntries, &LineFile{name, mtime, length})
+	return false, nil
+}
+
+// updateFile updates r.state.File after r.fileIndex has
+// changed or r.fileEntries has changed.
+func (r *LineReader) updateFile() {
+	if r.fileIndex < len(r.fileEntries) {
+		r.state.File = r.fileEntries[r.fileIndex]
+	} else {
+		r.state.File = nil
+	}
+}
+
+// Next sets *entry to the next row in this line table and moves to
+// the next row. If there are no more entries and the line table is
+// properly terminated, it returns io.EOF.
+//
+// Rows are always in order of increasing entry.Address, but
+// entry.Line may go forward or backward.
+func (r *LineReader) Next(entry *LineEntry) error {
+	if r.buf.err != nil {
+		return r.buf.err
+	}
+
+	// Execute opcodes until we reach an opcode that emits a line
+	// table entry.
+	for {
+		if len(r.buf.data) == 0 {
+			return io.EOF
+		}
+		emit := r.step(entry)
+		if r.buf.err != nil {
+			return r.buf.err
+		}
+		if emit {
+			return nil
+		}
+	}
+}
+
+// knownOpcodeLengths gives the opcode lengths (in varint arguments)
+// of known standard opcodes.
+var knownOpcodeLengths = map[int]int{
+	lnsCopy:             0,
+	lnsAdvancePC:        1,
+	lnsAdvanceLine:      1,
+	lnsSetFile:          1,
+	lnsNegateStmt:       0,
+	lnsSetBasicBlock:    0,
+	lnsConstAddPC:       0,
+	lnsSetPrologueEnd:   0,
+	lnsSetEpilogueBegin: 0,
+	lnsSetISA:           1,
+	// lnsFixedAdvancePC takes a uint8 rather than a varint; it's
+	// unclear what length the header is supposed to claim, so
+	// ignore it.
+}
+
+// step processes the next opcode and updates r.state. If the opcode
+// emits a row in the line table, this updates *entry and returns
+// true.
+func (r *LineReader) step(entry *LineEntry) bool {
+	opcode := int(r.buf.uint8())
+
+	if opcode >= r.opcodeBase {
+		// Special opcode [DWARF2 6.2.5.1, DWARF4 6.2.5.1]
+		adjustedOpcode := opcode - r.opcodeBase
+		r.advancePC(adjustedOpcode / r.lineRange)
+		lineDelta := r.lineBase + int(adjustedOpcode)%r.lineRange
+		r.state.Line += lineDelta
+		goto emit
+	}
+
+	switch opcode {
+	case 0:
+		// Extended opcode [DWARF2 6.2.5.3]
+		length := Offset(r.buf.uint())
+		startOff := r.buf.off
+		opcode := r.buf.uint8()
+
+		switch opcode {
+		case lneEndSequence:
+			r.state.EndSequence = true
+			*entry = r.state
+			r.resetState()
+
+		case lneSetAddress:
+			r.state.Address = r.buf.addr()
+
+		case lneDefineFile:
+			if done, err := r.readFileEntry(); err != nil {
+				r.buf.err = err
+				return false
+			} else if done {
+				r.buf.err = DecodeError{"line", startOff, "malformed DW_LNE_define_file operation"}
+				return false
+			}
+			r.updateFile()
+
+		case lneSetDiscriminator:
+			// [DWARF4 6.2.5.3]
+			r.state.Discriminator = int(r.buf.uint())
+		}
+
+		r.buf.skip(int(startOff + length - r.buf.off))
+
+		if opcode == lneEndSequence {
+			return true
+		}
+
+	// Standard opcodes [DWARF2 6.2.5.2]
+	case lnsCopy:
+		goto emit
+
+	case lnsAdvancePC:
+		r.advancePC(int(r.buf.uint()))
+
+	case lnsAdvanceLine:
+		r.state.Line += int(r.buf.int())
+
+	case lnsSetFile:
+		r.fileIndex = int(r.buf.uint())
+		r.updateFile()
+
+	case lnsSetColumn:
+		r.state.Column = int(r.buf.uint())
+
+	case lnsNegateStmt:
+		r.state.IsStmt = !r.state.IsStmt
+
+	case lnsSetBasicBlock:
+		r.state.BasicBlock = true
+
+	case lnsConstAddPC:
+		r.advancePC((255 - r.opcodeBase) / r.lineRange)
+
+	case lnsFixedAdvancePC:
+		r.state.Address += uint64(r.buf.uint16())
+
+	// DWARF3 standard opcodes [DWARF3 6.2.5.2]
+	case lnsSetPrologueEnd:
+		r.state.PrologueEnd = true
+
+	case lnsSetEpilogueBegin:
+		r.state.EpilogueBegin = true
+
+	case lnsSetISA:
+		r.state.ISA = int(r.buf.uint())
+
+	default:
+		// Unhandled standard opcode. Skip the number of
+		// arguments that the prologue says this opcode has.
+		for i := 0; i < r.opcodeLengths[opcode]; i++ {
+			r.buf.uint()
+		}
+	}
+	return false
+
+emit:
+	*entry = r.state
+	r.state.BasicBlock = false
+	r.state.PrologueEnd = false
+	r.state.EpilogueBegin = false
+	r.state.Discriminator = 0
+	return true
+}
+
+// advancePC advances "operation pointer" (the combination of Address
+// and OpIndex) in r.state by opAdvance steps.
+func (r *LineReader) advancePC(opAdvance int) {
+	opIndex := r.state.OpIndex + opAdvance
+	r.state.Address += uint64(r.minInstructionLength * (opIndex / r.maxOpsPerInstruction))
+	r.state.OpIndex = opIndex % r.maxOpsPerInstruction
+}
+
+// A LineReaderPos represents a position in a line table.
+type LineReaderPos struct {
+	// off is the current offset in the DWARF line section.
+	off Offset
+	// numFileEntries is the length of fileEntries.
+	numFileEntries int
+	// state and fileIndex are the statement machine state at
+	// offset off.
+	state     LineEntry
+	fileIndex int
+}
+
+// Tell returns the current position in the line table.
+func (r *LineReader) Tell() LineReaderPos {
+	return LineReaderPos{r.buf.off, len(r.fileEntries), r.state, r.fileIndex}
+}
+
+// Seek restores the line table reader to a position returned by Tell.
+//
+// The argument pos must have been returned by a call to Tell on this
+// line table.
+func (r *LineReader) Seek(pos LineReaderPos) {
+	r.buf.off = pos.off
+	r.buf.data = r.section[r.buf.off:r.endOffset]
+	r.fileEntries = r.fileEntries[:pos.numFileEntries]
+	r.state = pos.state
+	r.fileIndex = pos.fileIndex
+}
+
+// Reset repositions the line table reader at the beginning of the
+// line table.
+func (r *LineReader) Reset() {
+	// Reset buffer to the line number program offset.
+	r.buf.off = r.programOffset
+	r.buf.data = r.section[r.buf.off:r.endOffset]
+
+	// Reset file entries list.
+	r.fileEntries = r.fileEntries[:r.initialFileEntries]
+
+	// Reset line number program state.
+	r.resetState()
+}
+
+// resetState resets r.state to its default values
+func (r *LineReader) resetState() {
+	// Reset the state machine registers to the defaults given in
+	// [DWARF4 6.2.2].
+	r.state = LineEntry{
+		Address:       0,
 		OpIndex:       0,
-		Line:          0,
+		File:          nil,
+		Line:          1,
 		Column:        0,
+		IsStmt:        r.defaultIsStmt,
+		BasicBlock:    false,
+		PrologueEnd:   false,
+		EpilogueBegin: false,
 		ISA:           0,
 		Discriminator: 0,
-		Stmt:          hdr.defStmt,
-		Block:         false,
-		EndPrologue:   false,
-		BeginEpilogue: false,
 	}
-	if len(hdr.files) > 0 {
-		resetLineInfo.Filename = hdr.files[0]
-	}
-	lineInfo := resetLineInfo
-
-	var lines []mapLineInfo
-
-	minInsnLen := uint64(hdr.minInsnLen)
-	maxOpsPerInsn := uint64(hdr.maxOpsPerInsn)
-	lineBase := int(hdr.lineBase)
-	lineRange := hdr.lineRange
-	newLineInfo := true
-	for b.off < end && b.err == nil {
-		op := b.uint8()
-		if op >= hdr.opBase {
-			// This is a special opcode.
-			op -= hdr.opBase
-			advance := uint64(op / hdr.lineRange)
-			opIndex := uint64(lineInfo.OpIndex)
-			address += minInsnLen * ((opIndex + advance) / maxOpsPerInsn)
-			newOpIndex := int((opIndex + advance) % maxOpsPerInsn)
-			line += lineBase + int(op%lineRange)
-			if newOpIndex != lineInfo.OpIndex {
-				lineInfo.OpIndex = newOpIndex
-				newLineInfo = true
-			}
-			lines, lineInfo, newLineInfo = d.addLine(lines, lineInfo, address, line, newLineInfo)
-		} else if op == LineExtendedOp {
-			c := b.uint()
-			op = b.uint8()
-			switch op {
-			case LineExtEndSequence:
-				u.lines = append(u.lines, lines...)
-				lineInfo = resetLineInfo
-				lines = nil
-				newLineInfo = true
-			case LineExtSetAddress:
-				address = b.addr()
-			case LineExtDefineFile:
-				f := b.string()
-				d := b.uint()
-				b.uint() // mtime
-				b.uint() // length
-				if d > 0 && !filepath.IsAbs(f) {
-					if d >= uint64(len(hdr.dirs)) {
-						b.error("DWARF directory index out of range")
-						return
-					}
-					f = filepath.Join(hdr.dirs[d-1], f)
-				}
-				hdr.files = append(hdr.files, f)
-			case LineExtSetDiscriminator:
-				lineInfo.Discriminator = int(b.uint())
-				newLineInfo = true
-			default:
-				if c > 0 {
-					b.bytes(int(c) - 1)
-				}
-			}
-		} else {
-			switch op {
-			case LineCopy:
-				lines, lineInfo, newLineInfo = d.addLine(lines, lineInfo, address, line, newLineInfo)
-			case LineAdvancePC:
-				advance := b.uint()
-				opIndex := uint64(lineInfo.OpIndex)
-				address += minInsnLen * ((opIndex + advance) / maxOpsPerInsn)
-				newOpIndex := int((opIndex + advance) % maxOpsPerInsn)
-				if newOpIndex != lineInfo.OpIndex {
-					lineInfo.OpIndex = newOpIndex
-					newLineInfo = true
-				}
-			case LineAdvanceLine:
-				line += int(b.int())
-			case LineSetFile:
-				i := b.uint()
-				if i > uint64(len(hdr.files)) {
-					b.error("DWARF file number out of range")
-					return
-				}
-				lineInfo.Filename = hdr.files[i-1]
-				newLineInfo = true
-			case LineSetColumn:
-				lineInfo.Column = int(b.uint())
-				newLineInfo = true
-			case LineNegateStmt:
-				lineInfo.Stmt = !lineInfo.Stmt
-				newLineInfo = true
-			case LineSetBasicBlock:
-				lineInfo.Block = true
-				newLineInfo = true
-			case LineConstAddPC:
-				op = 255 - hdr.opBase
-				advance := uint64(op / hdr.lineRange)
-				opIndex := uint64(lineInfo.OpIndex)
-				address += minInsnLen * ((opIndex + advance) / maxOpsPerInsn)
-				newOpIndex := int((opIndex + advance) % maxOpsPerInsn)
-				if newOpIndex != lineInfo.OpIndex {
-					lineInfo.OpIndex = newOpIndex
-					newLineInfo = true
-				}
-			case LineFixedAdvancePC:
-				address += uint64(b.uint16())
-				if lineInfo.OpIndex != 0 {
-					lineInfo.OpIndex = 0
-					newLineInfo = true
-				}
-			case LineSetPrologueEnd:
-				lineInfo.EndPrologue = true
-				newLineInfo = true
-			case LineSetEpilogueBegin:
-				lineInfo.BeginEpilogue = true
-				newLineInfo = true
-			case LineSetISA:
-				lineInfo.ISA = int(b.uint())
-				newLineInfo = true
-			default:
-				if int(op) >= len(hdr.opLen) {
-					b.error("DWARF line opcode has unknown length")
-					return
-				}
-				for i := hdr.opLen[op-1]; i > 0; i-- {
-					b.int()
-				}
-			}
-		}
-	}
+	r.fileIndex = 1
+	r.updateFile()
 }
 
-// addLine adds the current address and line to lines using lineInfo.
-// If newLineInfo is true this is a new lineInfo.  This returns the
-// updated lines, lineInfo, and newLineInfo.
-func (d *Data) addLine(lines []mapLineInfo, lineInfo Line, address uint64, line int, newLineInfo bool) ([]mapLineInfo, Line, bool) {
-	if newLineInfo {
-		if len(lines) > 0 {
-			sort.Sort(lines[len(lines)-1].addrs)
-			p := &lines[len(lines)-1]
-			if len(p.addrs) > 0 && address > p.addrs[len(p.addrs)-1].pc {
-				p.addrs = append(p.addrs, oneLineInfo{address, p.addrs[len(p.addrs)-1].line})
-			}
+// ErrUnknownPC is the error returned by LineReader.ScanPC when the
+// seek PC is not covered by any entry in the line table.
+var ErrUnknownPC = errors.New("ErrUnknownPC")
+
+// SeekPC sets *entry to the LineEntry that includes pc and positions
+// the reader on the next entry in the line table. If necessary, this
+// will seek backwards to find pc.
+//
+// If pc is not covered by any entry in this line table, SeekPC
+// returns ErrUnknownPC. In this case, *entry and the final seek
+// position are unspecified.
+//
+// Note that DWARF line tables only permit sequential, forward scans.
+// Hence, in the worst case, this takes time linear in the size of the
+// line table. If the caller wishes to do repeated fast PC lookups, it
+// should build an appropriate index of the line table.
+func (r *LineReader) SeekPC(pc uint64, entry *LineEntry) error {
+	if err := r.Next(entry); err != nil {
+		return err
+	}
+	if entry.Address > pc {
+		// We're too far. Start at the beginning of the table.
+		r.Reset()
+		if err := r.Next(entry); err != nil {
+			return err
 		}
-		lines = append(lines, mapLineInfo{line: lineInfo})
-	}
-	p := &lines[len(lines)-1]
-	p.addrs = append(p.addrs, oneLineInfo{address, line})
-
-	if lineInfo.Block || lineInfo.EndPrologue || lineInfo.BeginEpilogue || lineInfo.Discriminator != 0 {
-		lineInfo.Block = false
-		lineInfo.EndPrologue = false
-		lineInfo.BeginEpilogue = false
-		lineInfo.Discriminator = 0
-		newLineInfo = true
-	} else {
-		newLineInfo = false
+		if entry.Address > pc {
+			// The whole table starts after pc.
+			r.Reset()
+			return ErrUnknownPC
+		}
 	}
 
-	return lines, lineInfo, newLineInfo
+	// Scan until we pass pc, then back up one.
+	for {
+		var next LineEntry
+		pos := r.Tell()
+		if err := r.Next(&next); err != nil {
+			if err == io.EOF {
+				return ErrUnknownPC
+			}
+			return err
+		}
+		if next.Address > pc {
+			if entry.EndSequence {
+				// pc is in a hole in the table.
+				return ErrUnknownPC
+			}
+			// entry is the desired entry. Back up the
+			// cursor to "next" and return success.
+			r.Seek(pos)
+			return nil
+		}
+		*entry = next
+	}
 }
diff --git a/third_party/gofrontend/libgo/go/debug/dwarf/line_test.go b/third_party/gofrontend/libgo/go/debug/dwarf/line_test.go
index 2476a6f..4104b5d 100644
--- a/third_party/gofrontend/libgo/go/debug/dwarf/line_test.go
+++ b/third_party/gofrontend/libgo/go/debug/dwarf/line_test.go
@@ -1,4 +1,4 @@
-// Copyright 2012 The Go Authors.  All rights reserved.
+// 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.
 
@@ -6,48 +6,224 @@
 
 import (
 	. "debug/dwarf"
-	"path/filepath"
+	"io"
 	"testing"
 )
 
-type lineTest struct {
-	pc   uint64
-	file string
-	line int
+var (
+	file1C = &LineFile{Name: "/home/austin/go.dev/src/debug/dwarf/testdata/line1.c"}
+	file1H = &LineFile{Name: "/home/austin/go.dev/src/debug/dwarf/testdata/line1.h"}
+	file2C = &LineFile{Name: "/home/austin/go.dev/src/debug/dwarf/testdata/line2.c"}
+)
+
+func TestLineELFGCC(t *testing.T) {
+	// Generated by:
+	//   # gcc --version | head -n1
+	//   gcc (Ubuntu 4.8.2-19ubuntu1) 4.8.2
+	//   # gcc -g -o line-gcc.elf line*.c
+
+	// Line table based on readelf --debug-dump=rawline,decodedline
+	want := []LineEntry{
+		{Address: 0x40059d, File: file1H, Line: 2, IsStmt: true},
+		{Address: 0x4005a5, File: file1H, Line: 2, IsStmt: true},
+		{Address: 0x4005b4, File: file1H, Line: 5, IsStmt: true},
+		{Address: 0x4005bd, File: file1H, Line: 6, IsStmt: true, Discriminator: 2},
+		{Address: 0x4005c7, File: file1H, Line: 5, IsStmt: true, Discriminator: 2},
+		{Address: 0x4005cb, File: file1H, Line: 5, IsStmt: false, Discriminator: 1},
+		{Address: 0x4005d1, File: file1H, Line: 7, IsStmt: true},
+		{Address: 0x4005e7, File: file1C, Line: 6, IsStmt: true},
+		{Address: 0x4005eb, File: file1C, Line: 7, IsStmt: true},
+		{Address: 0x4005f5, File: file1C, Line: 8, IsStmt: true},
+		{Address: 0x4005ff, File: file1C, Line: 9, IsStmt: true},
+		{Address: 0x400601, EndSequence: true},
+
+		{Address: 0x400601, File: file2C, Line: 4, IsStmt: true},
+		{Address: 0x400605, File: file2C, Line: 5, IsStmt: true},
+		{Address: 0x40060f, File: file2C, Line: 6, IsStmt: true},
+		{Address: 0x400611, EndSequence: true},
+	}
+
+	testLineTable(t, want, elfData(t, "testdata/line-gcc.elf"))
 }
 
-var elfLineTests = [...]lineTest{
-	{0x4004c4, "typedef.c", 83},
-	{0x4004c8, "typedef.c", 84},
-	{0x4004ca, "typedef.c", 84},
-	{0x4003e0, "", 0},
+func TestLineELFClang(t *testing.T) {
+	// Generated by:
+	//   # clang --version | head -n1
+	//   Ubuntu clang version 3.4-1ubuntu3 (tags/RELEASE_34/final) (based on LLVM 3.4)
+	//   # clang -g -o line-clang.elf line*.
+
+	want := []LineEntry{
+		{Address: 0x400530, File: file1C, Line: 6, IsStmt: true},
+		{Address: 0x400534, File: file1C, Line: 7, IsStmt: true, PrologueEnd: true},
+		{Address: 0x400539, File: file1C, Line: 8, IsStmt: true},
+		{Address: 0x400545, File: file1C, Line: 9, IsStmt: true},
+		{Address: 0x400550, File: file1H, Line: 2, IsStmt: true},
+		{Address: 0x400554, File: file1H, Line: 5, IsStmt: true, PrologueEnd: true},
+		{Address: 0x400568, File: file1H, Line: 6, IsStmt: true},
+		{Address: 0x400571, File: file1H, Line: 5, IsStmt: true},
+		{Address: 0x400581, File: file1H, Line: 7, IsStmt: true},
+		{Address: 0x400583, EndSequence: true},
+
+		{Address: 0x400590, File: file2C, Line: 4, IsStmt: true},
+		{Address: 0x4005a0, File: file2C, Line: 5, IsStmt: true, PrologueEnd: true},
+		{Address: 0x4005a7, File: file2C, Line: 6, IsStmt: true},
+		{Address: 0x4005b0, EndSequence: true},
+	}
+
+	testLineTable(t, want, elfData(t, "testdata/line-clang.elf"))
 }
 
-var machoLineTests = [...]lineTest{
-	{0x0, "typedef.c", 83},
-}
+func TestLineSeek(t *testing.T) {
+	d := elfData(t, "testdata/line-gcc.elf")
 
-func TestLineElf(t *testing.T) {
-	testLine(t, elfData(t, "testdata/typedef.elf"), elfLineTests[:], "elf")
-}
+	// Get the line table for the first CU.
+	cu, err := d.Reader().Next()
+	if err != nil {
+		t.Fatal("d.Reader().Next:", err)
+	}
+	lr, err := d.LineReader(cu)
+	if err != nil {
+		t.Fatal("d.LineReader:", err)
+	}
 
-func TestLineMachO(t *testing.T) {
-	testLine(t, machoData(t, "testdata/typedef.macho"), machoLineTests[:], "macho")
-}
+	// Read entries forward.
+	var line LineEntry
+	var posTable []LineReaderPos
+	var table []LineEntry
+	for {
+		posTable = append(posTable, lr.Tell())
 
-func testLine(t *testing.T, d *Data, tests []lineTest, kind string) {
-	for _, v := range tests {
-		file, line, err := d.FileLine(v.pc)
+		err := lr.Next(&line)
 		if err != nil {
-			t.Errorf("%s: %v", kind, err)
+			if err == io.EOF {
+				break
+			}
+			t.Fatal("lr.Next:", err)
+		}
+		table = append(table, line)
+	}
+
+	// Test that Reset returns to the first line.
+	lr.Reset()
+	if err := lr.Next(&line); err != nil {
+		t.Fatal("lr.Next after Reset failed:", err)
+	} else if line != table[0] {
+		t.Fatal("lr.Next after Reset returned", line, "instead of", table[0])
+	}
+
+	// Check that entries match when seeking backward.
+	for i := len(posTable) - 1; i >= 0; i-- {
+		lr.Seek(posTable[i])
+		err := lr.Next(&line)
+		if i == len(posTable)-1 {
+			if err != io.EOF {
+				t.Fatal("expected io.EOF after seek to end, got", err)
+			}
+		} else if err != nil {
+			t.Fatal("lr.Next after seek to", posTable[i], "failed:", err)
+		} else if line != table[i] {
+			t.Fatal("lr.Next after seek to", posTable[i], "returned", line, "instead of", table[i])
+		}
+	}
+
+	// Check that seeking to a PC returns the right line.
+	if err := lr.SeekPC(table[0].Address-1, &line); err != ErrUnknownPC {
+		t.Fatalf("lr.SeekPC to %#x returned %v instead of ErrUnknownPC", table[0].Address-1, err)
+	}
+	for i, testLine := range table {
+		if testLine.EndSequence {
+			if err := lr.SeekPC(testLine.Address, &line); err != ErrUnknownPC {
+				t.Fatalf("lr.SeekPC to %#x returned %v instead of ErrUnknownPC", testLine.Address, err)
+			}
 			continue
 		}
-		if file != "" {
-			file = filepath.Base(file)
+
+		nextPC := table[i+1].Address
+		for pc := testLine.Address; pc < nextPC; pc++ {
+			if err := lr.SeekPC(pc, &line); err != nil {
+				t.Fatalf("lr.SeekPC to %#x failed: %v", pc, err)
+			} else if line != testLine {
+				t.Fatalf("lr.SeekPC to %#x returned %v instead of %v", pc, line, testLine)
+			}
 		}
-		if file != v.file || line != v.line {
-			t.Errorf("%s: for %d have %q:%d want %q:%d",
-				kind, v.pc, file, line, v.file, v.line)
+	}
+}
+
+func testLineTable(t *testing.T, want []LineEntry, d *Data) {
+	// Get line table from d.
+	var got []LineEntry
+	dr := d.Reader()
+	for {
+		ent, err := dr.Next()
+		if err != nil {
+			t.Fatal("dr.Next:", err)
+		} else if ent == nil {
+			break
 		}
+
+		if ent.Tag != TagCompileUnit {
+			dr.SkipChildren()
+			continue
+		}
+
+		// Decode CU's line table.
+		lr, err := d.LineReader(ent)
+		if err != nil {
+			t.Fatal("d.LineReader:", err)
+		} else if lr == nil {
+			continue
+		}
+
+		for {
+			var line LineEntry
+			err := lr.Next(&line)
+			if err != nil {
+				if err == io.EOF {
+					break
+				}
+				t.Fatal("lr.Next:", err)
+			}
+			got = append(got, line)
+		}
+	}
+
+	// Compare line tables.
+	if !compareLines(got, want) {
+		t.Log("Line tables do not match. Got:")
+		dumpLines(t, got)
+		t.Log("Want:")
+		dumpLines(t, want)
+		t.FailNow()
+	}
+}
+
+func compareLines(a, b []LineEntry) bool {
+	if len(a) != len(b) {
+		return false
+	}
+
+	for i := range a {
+		al, bl := a[i], b[i]
+		// If both are EndSequence, then the only other valid
+		// field is Address. Otherwise, test equality of all
+		// fields.
+		if al.EndSequence && bl.EndSequence && al.Address == bl.Address {
+			continue
+		}
+		if al.File.Name != bl.File.Name {
+			return false
+		}
+		al.File = nil
+		bl.File = nil
+		if al != bl {
+			return false
+		}
+	}
+	return true
+}
+
+func dumpLines(t *testing.T, lines []LineEntry) {
+	for _, l := range lines {
+		t.Logf("  %+v File:%+v", l, l.File)
 	}
 }
diff --git a/third_party/gofrontend/libgo/go/debug/dwarf/testdata/line-clang.elf b/third_party/gofrontend/libgo/go/debug/dwarf/testdata/line-clang.elf
new file mode 100755
index 0000000..b63cc78
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/debug/dwarf/testdata/line-clang.elf
Binary files differ
diff --git a/third_party/gofrontend/libgo/go/debug/dwarf/testdata/line-gcc.elf b/third_party/gofrontend/libgo/go/debug/dwarf/testdata/line-gcc.elf
new file mode 100755
index 0000000..50500a8
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/debug/dwarf/testdata/line-gcc.elf
Binary files differ
diff --git a/third_party/gofrontend/libgo/go/debug/dwarf/testdata/line1.c b/third_party/gofrontend/libgo/go/debug/dwarf/testdata/line1.c
new file mode 100644
index 0000000..f358647
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/debug/dwarf/testdata/line1.c
@@ -0,0 +1,9 @@
+#include "line1.h"
+
+void f2();
+
+int main()
+{
+	f1();
+	f2();
+}
diff --git a/third_party/gofrontend/libgo/go/debug/dwarf/testdata/line1.h b/third_party/gofrontend/libgo/go/debug/dwarf/testdata/line1.h
new file mode 100644
index 0000000..974d4c8
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/debug/dwarf/testdata/line1.h
@@ -0,0 +1,7 @@
+static void f1()
+{
+	char buf[10];
+	int i;
+	for(i = 0; i < 10; i++)
+		buf[i] = 1;
+}
diff --git a/third_party/gofrontend/libgo/go/debug/dwarf/testdata/line2.c b/third_party/gofrontend/libgo/go/debug/dwarf/testdata/line2.c
new file mode 100644
index 0000000..38d8998
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/debug/dwarf/testdata/line2.c
@@ -0,0 +1,6 @@
+#include <stdio.h>
+
+void f2()
+{
+	printf("hello\n");
+}
diff --git a/third_party/gofrontend/libgo/go/debug/dwarf/type.go b/third_party/gofrontend/libgo/go/debug/dwarf/type.go
index 6986b19..a5daa1d 100644
--- a/third_party/gofrontend/libgo/go/debug/dwarf/type.go
+++ b/third_party/gofrontend/libgo/go/debug/dwarf/type.go
@@ -268,6 +268,9 @@
 	Next() (*Entry, error)
 	clone() typeReader
 	offset() Offset
+	// AddressSize returns the size in bytes of addresses in the current
+	// compilation unit.
+	AddressSize() int
 }
 
 // Type reads the type at off in the DWARF ``info'' section.
@@ -286,6 +289,7 @@
 	if err != nil {
 		return nil, err
 	}
+	addressSize := r.AddressSize()
 	if e == nil || e.Offset != off {
 		return nil, DecodeError{name, off, "no type at offset"}
 	}
@@ -668,6 +672,12 @@
 		b, ok := e.Val(AttrByteSize).(int64)
 		if !ok {
 			b = -1
+			switch t := typ.(type) {
+			case *TypedefType:
+				b = t.Type.Size()
+			case *PtrType:
+				b = int64(addressSize)
+			}
 		}
 		typ.Common().ByteSize = b
 	}
diff --git a/third_party/gofrontend/libgo/go/debug/dwarf/typeunit.go b/third_party/gofrontend/libgo/go/debug/dwarf/typeunit.go
index 3fd1c99..9cfb4a8 100644
--- a/third_party/gofrontend/libgo/go/debug/dwarf/typeunit.go
+++ b/third_party/gofrontend/libgo/go/debug/dwarf/typeunit.go
@@ -27,21 +27,15 @@
 	b := makeBuf(d, unknownFormat{}, name, 0, types)
 	for len(b.data) > 0 {
 		base := b.off
-		dwarf64 := false
-		n := b.uint32()
-		if n == 0xffffffff {
-			n64 := b.uint64()
-			if n64 != uint64(uint32(n64)) {
-				b.error("type unit length overflow")
-				return b.err
-			}
-			n = uint32(n64)
-			dwarf64 = true
+		n, dwarf64 := b.unitLength()
+		if n != Offset(uint32(n)) {
+			b.error("type unit length overflow")
+			return b.err
 		}
 		hdroff := b.off
-		vers := b.uint16()
+		vers := int(b.uint16())
 		if vers != 4 {
-			b.error("unsupported DWARF version " + strconv.Itoa(int(vers)))
+			b.error("unsupported DWARF version " + strconv.Itoa(vers))
 			return b.err
 		}
 		var ao uint32
@@ -55,7 +49,7 @@
 			}
 			ao = uint32(ao64)
 		}
-		atable, err := d.parseAbbrev(ao)
+		atable, err := d.parseAbbrev(ao, vers)
 		if err != nil {
 			return err
 		}
@@ -79,7 +73,7 @@
 			unit: unit{
 				base:   base,
 				off:    boff,
-				data:   b.bytes(int(Offset(n) - (b.off - hdroff))),
+				data:   b.bytes(int(n - (b.off - hdroff))),
 				atable: atable,
 				asize:  int(asize),
 				vers:   int(vers),
@@ -135,6 +129,11 @@
 	tur.b = makeBuf(tur.d, tur.tu, tur.tu.name, off, tur.tu.data[doff:])
 }
 
+// AddressSize returns the size in bytes of addresses in the current type unit.
+func (tur *typeUnitReader) AddressSize() int {
+	return tur.tu.unit.asize
+}
+
 // Next reads the next Entry from the type unit.
 func (tur *typeUnitReader) Next() (*Entry, error) {
 	if tur.err != nil {
diff --git a/third_party/gofrontend/libgo/go/debug/dwarf/unit.go b/third_party/gofrontend/libgo/go/debug/dwarf/unit.go
index be60935..ceb6cdb 100644
--- a/third_party/gofrontend/libgo/go/debug/dwarf/unit.go
+++ b/third_party/gofrontend/libgo/go/debug/dwarf/unit.go
@@ -4,23 +4,22 @@
 
 package dwarf
 
-import "strconv"
+import (
+	"sort"
+	"strconv"
+)
 
 // DWARF debug info is split into a sequence of compilation units.
 // Each unit has its own abbreviation table and address size.
 
 type unit struct {
-	base    Offset // byte offset of header within the aggregate info
-	off     Offset // byte offset of data within the aggregate info
-	lineoff Offset // byte offset of data within the line info
-	data    []byte
-	atable  abbrevTable
-	asize   int
-	vers    int
-	is64    bool // True for 64-bit DWARF format
-	dir     string
-	pc      []addrRange   // PC ranges in this compilation unit
-	lines   []mapLineInfo // PC -> line mapping
+	base   Offset // byte offset of header within the aggregate info
+	off    Offset // byte offset of data within the aggregate info
+	data   []byte
+	atable abbrevTable
+	asize  int
+	vers   int
+	is64   bool // True for 64-bit DWARF format
 }
 
 // Implement the dataFormat interface.
@@ -37,25 +36,15 @@
 	return u.asize
 }
 
-// A range is an address range.
-type addrRange struct {
-	low  uint64
-	high uint64
-}
-
 func (d *Data) parseUnits() ([]unit, error) {
 	// Count units.
 	nunit := 0
 	b := makeBuf(d, unknownFormat{}, "info", 0, d.info)
 	for len(b.data) > 0 {
-		len := b.uint32()
-		if len == 0xffffffff {
-			len64 := b.uint64()
-			if len64 != uint64(uint32(len64)) {
-				b.error("unit length overflow")
-				break
-			}
-			len = uint32(len64)
+		len, _ := b.unitLength()
+		if len != Offset(uint32(len)) {
+			b.error("unit length overflow")
+			break
 		}
 		b.skip(int(len))
 		nunit++
@@ -70,18 +59,15 @@
 	for i := range units {
 		u := &units[i]
 		u.base = b.off
-		n := b.uint32()
-		if n == 0xffffffff {
-			u.is64 = true
-			n = uint32(b.uint64())
-		}
+		var n Offset
+		n, u.is64 = b.unitLength()
 		vers := b.uint16()
 		if vers != 2 && vers != 3 && vers != 4 {
 			b.error("unsupported DWARF version " + strconv.Itoa(int(vers)))
 			break
 		}
 		u.vers = int(vers)
-		atable, err := d.parseAbbrev(b.uint32())
+		atable, err := d.parseAbbrev(b.uint32(), u.vers)
 		if err != nil {
 			if b.err == nil {
 				b.err = err
@@ -98,3 +84,20 @@
 	}
 	return units, nil
 }
+
+// offsetToUnit returns the index of the unit containing offset off.
+// It returns -1 if no unit contains this offset.
+func (d *Data) offsetToUnit(off Offset) int {
+	// Find the unit after off
+	next := sort.Search(len(d.unit), func(i int) bool {
+		return d.unit[i].off > off
+	})
+	if next == 0 {
+		return -1
+	}
+	u := &d.unit[next-1]
+	if u.off <= off && off < u.off+Offset(len(u.data)) {
+		return next - 1
+	}
+	return -1
+}
diff --git a/third_party/gofrontend/libgo/go/debug/elf/elf.go b/third_party/gofrontend/libgo/go/debug/elf/elf.go
index a9466bb..c97ccaa 100644
--- a/third_party/gofrontend/libgo/go/debug/elf/elf.go
+++ b/third_party/gofrontend/libgo/go/debug/elf/elf.go
@@ -312,7 +312,7 @@
 	SHN_HIOS      SectionIndex = 0xff3f /* Last operating system-specific. */
 	SHN_ABS       SectionIndex = 0xfff1 /* Absolute values. */
 	SHN_COMMON    SectionIndex = 0xfff2 /* Common data. */
-	SHN_XINDEX    SectionIndex = 0xffff /* Escape -- index stored elsewhere. */
+	SHN_XINDEX    SectionIndex = 0xffff /* Escape; index stored elsewhere. */
 	SHN_HIRESERVE SectionIndex = 0xffff /* Last of reserved range. */
 )
 
@@ -1414,7 +1414,7 @@
 func (i R_PPC) String() string   { return stringName(uint32(i), rppcStrings, false) }
 func (i R_PPC) GoString() string { return stringName(uint32(i), rppcStrings, true) }
 
-// Relocation types for PowerPC 64.
+// Relocation types for 64-bit PowerPC or Power Architecture processors.
 type R_PPC64 int
 
 const (
diff --git a/third_party/gofrontend/libgo/go/debug/elf/file.go b/third_party/gofrontend/libgo/go/debug/elf/file.go
index 0135f7f..370c5e6 100644
--- a/third_party/gofrontend/libgo/go/debug/elf/file.go
+++ b/third_party/gofrontend/libgo/go/debug/elf/file.go
@@ -13,6 +13,7 @@
 	"fmt"
 	"io"
 	"os"
+	"strings"
 )
 
 // TODO: error reporting detail
@@ -523,26 +524,24 @@
 // applyRelocations applies relocations to dst. rels is a relocations section
 // in RELA format.
 func (f *File) applyRelocations(dst []byte, rels []byte) error {
-	if f.Class == ELFCLASS64 && f.Machine == EM_X86_64 {
+	switch {
+	case f.Class == ELFCLASS64 && f.Machine == EM_X86_64:
 		return f.applyRelocationsAMD64(dst, rels)
-	}
-	if f.Class == ELFCLASS32 && f.Machine == EM_386 {
+	case f.Class == ELFCLASS32 && f.Machine == EM_386:
 		return f.applyRelocations386(dst, rels)
-	}
-	if f.Class == ELFCLASS64 && f.Machine == EM_AARCH64 {
+	case f.Class == ELFCLASS32 && f.Machine == EM_ARM:
+		return f.applyRelocationsARM(dst, rels)
+	case f.Class == ELFCLASS64 && f.Machine == EM_AARCH64:
 		return f.applyRelocationsARM64(dst, rels)
-	}
-	if f.Class == ELFCLASS32 && f.Machine == EM_PPC {
+	case f.Class == ELFCLASS32 && f.Machine == EM_PPC:
 		return f.applyRelocationsPPC(dst, rels)
-	}
-	if f.Class == ELFCLASS64 && f.Machine == EM_PPC64 {
+	case f.Class == ELFCLASS64 && f.Machine == EM_PPC64:
 		return f.applyRelocationsPPC64(dst, rels)
-	}
-	if f.Class == ELFCLASS64 && f.Machine == EM_S390 {
+	case f.Class == ELFCLASS64 && f.Machine == EM_S390:
 		return f.applyRelocationsS390x(dst, rels)
+	default:
+		return errors.New("applyRelocations: not implemented")
 	}
-
-	return errors.New("not implemented")
 }
 
 func (f *File) applyRelocationsAMD64(dst []byte, rels []byte) error {
@@ -631,6 +630,44 @@
 	return nil
 }
 
+func (f *File) applyRelocationsARM(dst []byte, rels []byte) error {
+	// 8 is the size of Rel32.
+	if len(rels)%8 != 0 {
+		return errors.New("length of relocation section is not a multiple of 8")
+	}
+
+	symbols, _, err := f.getSymbols(SHT_SYMTAB)
+	if err != nil {
+		return err
+	}
+
+	b := bytes.NewReader(rels)
+	var rel Rel32
+
+	for b.Len() > 0 {
+		binary.Read(b, f.ByteOrder, &rel)
+		symNo := rel.Info >> 8
+		t := R_ARM(rel.Info & 0xff)
+
+		if symNo == 0 || symNo > uint32(len(symbols)) {
+			continue
+		}
+		sym := &symbols[symNo-1]
+
+		switch t {
+		case R_ARM_ABS32:
+			if rel.Off+4 >= uint32(len(dst)) {
+				continue
+			}
+			val := f.ByteOrder.Uint32(dst[rel.Off : rel.Off+4])
+			val += uint32(sym.Value)
+			f.ByteOrder.PutUint32(dst[rel.Off:rel.Off+4], val)
+		}
+	}
+
+	return nil
+}
+
 func (f *File) applyRelocationsARM64(dst []byte, rels []byte) error {
 	// 24 is the size of Rela64.
 	if len(rels)%24 != 0 {
@@ -807,53 +844,52 @@
 }
 
 func (f *File) DWARF() (*dwarf.Data, error) {
-	// There are many other DWARF sections, but these
-	// are the required ones, and the debug/dwarf package
-	// does not use the others, so don't bother loading them.
-	var names = [...]string{"abbrev", "info", "line", "ranges", "str"}
-	var dat [len(names)][]byte
-	for i, name := range names {
-		name = ".debug_" + name
-		s := f.Section(name)
-		if s == nil {
-			continue
-		}
+	// sectionData gets the data for s, checks its size, and
+	// applies any applicable relations.
+	sectionData := func(i int, s *Section) ([]byte, error) {
 		b, err := s.Data()
 		if err != nil && uint64(len(b)) < s.Size {
 			return nil, err
 		}
-		dat[i] = b
+
+		for _, r := range f.Sections {
+			if r.Type != SHT_RELA && r.Type != SHT_REL {
+				continue
+			}
+			if int(r.Info) != i {
+				continue
+			}
+			rd, err := r.Data()
+			if err != nil {
+				return nil, err
+			}
+			err = f.applyRelocations(b, rd)
+			if err != nil {
+				return nil, err
+			}
+		}
+		return b, nil
 	}
 
-	// If there's a relocation table for .debug_info, we have to process it
-	// now otherwise the data in .debug_info is invalid for x86-64 objects.
-	rela := f.Section(".rela.debug_info")
-	if rela != nil && rela.Type == SHT_RELA && (f.Machine == EM_X86_64 || f.Machine == EM_AARCH64 || f.Machine == EM_PPC || f.Machine == EM_PPC64 || f.Machine == EM_S390) {
-		data, err := rela.Data()
+	// There are many other DWARF sections, but these
+	// are the ones the debug/dwarf package uses.
+	// Don't bother loading others.
+	var dat = map[string][]byte{"abbrev": nil, "info": nil, "str": nil, "line": nil, "ranges": nil}
+	for i, s := range f.Sections {
+		if !strings.HasPrefix(s.Name, ".debug_") {
+			continue
+		}
+		if _, ok := dat[s.Name[7:]]; !ok {
+			continue
+		}
+		b, err := sectionData(i, s)
 		if err != nil {
 			return nil, err
 		}
-		err = f.applyRelocations(dat[1], data)
-		if err != nil {
-			return nil, err
-		}
+		dat[s.Name[7:]] = b
 	}
 
-	// When using clang we need to process relocations even for 386.
-	rel := f.Section(".rel.debug_info")
-	if rel != nil && rel.Type == SHT_REL && f.Machine == EM_386 {
-		data, err := rel.Data()
-		if err != nil {
-			return nil, err
-		}
-		err = f.applyRelocations(dat[1], data)
-		if err != nil {
-			return nil, err
-		}
-	}
-
-	abbrev, info, line, ranges, str := dat[0], dat[1], dat[2], dat[3], dat[4]
-	d, err := dwarf.New(abbrev, nil, nil, info, line, nil, ranges, str)
+	d, err := dwarf.New(dat["abbrev"], nil, nil, dat["info"], dat["line"], nil, dat["ranges"], dat["str"])
 	if err != nil {
 		return nil, err
 	}
@@ -861,28 +897,11 @@
 	// Look for DWARF4 .debug_types sections.
 	for i, s := range f.Sections {
 		if s.Name == ".debug_types" {
-			b, err := s.Data()
-			if err != nil && uint64(len(b)) < s.Size {
+			b, err := sectionData(i, s)
+			if err != nil {
 				return nil, err
 			}
 
-			for _, r := range f.Sections {
-				if r.Type != SHT_RELA && r.Type != SHT_REL {
-					continue
-				}
-				if int(r.Info) != i {
-					continue
-				}
-				rd, err := r.Data()
-				if err != nil {
-					return nil, err
-				}
-				err = f.applyRelocations(b, rd)
-				if err != nil {
-					return nil, err
-				}
-			}
-
 			err = d.AddTypes(fmt.Sprintf("types-%d", i), b)
 			if err != nil {
 				return nil, err
diff --git a/third_party/gofrontend/libgo/go/debug/elf/file_test.go b/third_party/gofrontend/libgo/go/debug/elf/file_test.go
index 56e2604..1ad4314 100644
--- a/third_party/gofrontend/libgo/go/debug/elf/file_test.go
+++ b/third_party/gofrontend/libgo/go/debug/elf/file_test.go
@@ -245,50 +245,62 @@
 	{
 		"testdata/go-relocation-test-gcc441-x86-64.obj",
 		[]relocationTestEntry{
-			{0, &dwarf.Entry{Offset: 0xb, Tag: dwarf.TagCompileUnit, Children: true, Field: []dwarf.Field{{Attr: dwarf.AttrProducer, Val: "GNU C 4.4.1"}, {Attr: dwarf.AttrLanguage, Val: int64(1)}, {Attr: dwarf.AttrName, Val: "go-relocation-test.c"}, {Attr: dwarf.AttrCompDir, Val: "/tmp"}, {Attr: dwarf.AttrLowpc, Val: uint64(0x0)}, {Attr: dwarf.AttrHighpc, Val: uint64(0x6)}, {Attr: dwarf.AttrStmtList, Val: int64(0)}}}},
+			{0, &dwarf.Entry{Offset: 0xb, Tag: dwarf.TagCompileUnit, Children: true, Field: []dwarf.Field{{Attr: dwarf.AttrProducer, Val: "GNU C 4.4.1", Class: dwarf.ClassString}, {Attr: dwarf.AttrLanguage, Val: int64(1), Class: dwarf.ClassConstant}, {Attr: dwarf.AttrName, Val: "go-relocation-test.c", Class: dwarf.ClassString}, {Attr: dwarf.AttrCompDir, Val: "/tmp", Class: dwarf.ClassString}, {Attr: dwarf.AttrLowpc, Val: uint64(0x0), Class: dwarf.ClassAddress}, {Attr: dwarf.AttrHighpc, Val: uint64(0x6), Class: dwarf.ClassAddress}, {Attr: dwarf.AttrStmtList, Val: int64(0), Class: dwarf.ClassLinePtr}}}},
 		},
 	},
 	{
 		"testdata/go-relocation-test-gcc441-x86.obj",
 		[]relocationTestEntry{
-			{0, &dwarf.Entry{Offset: 0xb, Tag: dwarf.TagCompileUnit, Children: true, Field: []dwarf.Field{{Attr: dwarf.AttrProducer, Val: "GNU C 4.4.1"}, {Attr: dwarf.AttrLanguage, Val: int64(1)}, {Attr: dwarf.AttrName, Val: "t.c"}, {Attr: dwarf.AttrCompDir, Val: "/tmp"}, {Attr: dwarf.AttrLowpc, Val: uint64(0x0)}, {Attr: dwarf.AttrHighpc, Val: uint64(0x5)}, {Attr: dwarf.AttrStmtList, Val: int64(0)}}}},
+			{0, &dwarf.Entry{Offset: 0xb, Tag: dwarf.TagCompileUnit, Children: true, Field: []dwarf.Field{{Attr: dwarf.AttrProducer, Val: "GNU C 4.4.1", Class: dwarf.ClassString}, {Attr: dwarf.AttrLanguage, Val: int64(1), Class: dwarf.ClassConstant}, {Attr: dwarf.AttrName, Val: "t.c", Class: dwarf.ClassString}, {Attr: dwarf.AttrCompDir, Val: "/tmp", Class: dwarf.ClassString}, {Attr: dwarf.AttrLowpc, Val: uint64(0x0), Class: dwarf.ClassAddress}, {Attr: dwarf.AttrHighpc, Val: uint64(0x5), Class: dwarf.ClassAddress}, {Attr: dwarf.AttrStmtList, Val: int64(0), Class: dwarf.ClassLinePtr}}}},
 		},
 	},
 	{
 		"testdata/go-relocation-test-gcc424-x86-64.obj",
 		[]relocationTestEntry{
-			{0, &dwarf.Entry{Offset: 0xb, Tag: dwarf.TagCompileUnit, Children: true, Field: []dwarf.Field{{Attr: dwarf.AttrProducer, Val: "GNU C 4.2.4 (Ubuntu 4.2.4-1ubuntu4)"}, {Attr: dwarf.AttrLanguage, Val: int64(1)}, {Attr: dwarf.AttrName, Val: "go-relocation-test-gcc424.c"}, {Attr: dwarf.AttrCompDir, Val: "/tmp"}, {Attr: dwarf.AttrLowpc, Val: uint64(0x0)}, {Attr: dwarf.AttrHighpc, Val: uint64(0x6)}, {Attr: dwarf.AttrStmtList, Val: int64(0)}}}},
-		},
-	},
-	{
-		"testdata/go-relocation-test-gcc5-ppc.obj",
-		[]relocationTestEntry{
-			{0, &dwarf.Entry{Offset: 0xb, Tag: dwarf.TagCompileUnit, Children: true, Field: []dwarf.Field{dwarf.Field{Attr: dwarf.AttrProducer, Val: "GNU C11 5.0.0 20150116 (experimental) -Asystem=linux -Asystem=unix -Asystem=posix -g"}, dwarf.Field{Attr: dwarf.AttrLanguage, Val: int64(12)}, dwarf.Field{Attr: dwarf.AttrName, Val: "go-relocation-test-gcc5-ppc.c"}, dwarf.Field{Attr: dwarf.AttrCompDir, Val: "/tmp"}, dwarf.Field{Attr: dwarf.AttrLowpc, Val: uint64(0x0)}, dwarf.Field{Attr: dwarf.AttrHighpc, Val: int64(0x44)}, dwarf.Field{Attr: dwarf.AttrStmtList, Val: int64(0)}}}},
-		},
-	},
-	{
-		"testdata/go-relocation-test-gcc482-ppc64le.obj",
-		[]relocationTestEntry{
-			{0, &dwarf.Entry{Offset: 0xb, Tag: dwarf.TagCompileUnit, Children: true, Field: []dwarf.Field{dwarf.Field{Attr: dwarf.AttrProducer, Val: "GNU C 4.8.2 -Asystem=linux -Asystem=unix -Asystem=posix -msecure-plt -mtune=power8 -mcpu=power7 -gdwarf-2 -fstack-protector"}, dwarf.Field{Attr: dwarf.AttrLanguage, Val: int64(1)}, dwarf.Field{Attr: dwarf.AttrName, Val: "go-relocation-test-gcc482-ppc64le.c"}, dwarf.Field{Attr: dwarf.AttrCompDir, Val: "/tmp"}, dwarf.Field{Attr: dwarf.AttrLowpc, Val: uint64(0x0)}, dwarf.Field{Attr: dwarf.AttrHighpc, Val: uint64(0x24)}, dwarf.Field{Attr: dwarf.AttrStmtList, Val: int64(0)}}}},
+			{0, &dwarf.Entry{Offset: 0xb, Tag: dwarf.TagCompileUnit, Children: true, Field: []dwarf.Field{{Attr: dwarf.AttrProducer, Val: "GNU C 4.2.4 (Ubuntu 4.2.4-1ubuntu4)", Class: dwarf.ClassString}, {Attr: dwarf.AttrLanguage, Val: int64(1), Class: dwarf.ClassConstant}, {Attr: dwarf.AttrName, Val: "go-relocation-test-gcc424.c", Class: dwarf.ClassString}, {Attr: dwarf.AttrCompDir, Val: "/tmp", Class: dwarf.ClassString}, {Attr: dwarf.AttrLowpc, Val: uint64(0x0), Class: dwarf.ClassAddress}, {Attr: dwarf.AttrHighpc, Val: uint64(0x6), Class: dwarf.ClassAddress}, {Attr: dwarf.AttrStmtList, Val: int64(0), Class: dwarf.ClassLinePtr}}}},
 		},
 	},
 	{
 		"testdata/go-relocation-test-gcc482-aarch64.obj",
 		[]relocationTestEntry{
-			{0, &dwarf.Entry{Offset: 0xb, Tag: dwarf.TagCompileUnit, Children: true, Field: []dwarf.Field{{Attr: dwarf.AttrProducer, Val: "GNU C 4.8.2 -g -fstack-protector"}, {Attr: dwarf.AttrLanguage, Val: int64(1)}, {Attr: dwarf.AttrName, Val: "go-relocation-test-gcc482.c"}, {Attr: dwarf.AttrCompDir, Val: "/tmp"}, {Attr: dwarf.AttrLowpc, Val: uint64(0x0)}, {Attr: dwarf.AttrHighpc, Val: int64(0x24)}, {Attr: dwarf.AttrStmtList, Val: int64(0)}}}},
+			{0, &dwarf.Entry{Offset: 0xb, Tag: dwarf.TagCompileUnit, Children: true, Field: []dwarf.Field{{Attr: dwarf.AttrProducer, Val: "GNU C 4.8.2 -g -fstack-protector", Class: dwarf.ClassString}, {Attr: dwarf.AttrLanguage, Val: int64(1), Class: dwarf.ClassConstant}, {Attr: dwarf.AttrName, Val: "go-relocation-test-gcc482.c", Class: dwarf.ClassString}, {Attr: dwarf.AttrCompDir, Val: "/tmp", Class: dwarf.ClassString}, {Attr: dwarf.AttrLowpc, Val: uint64(0x0), Class: dwarf.ClassAddress}, {Attr: dwarf.AttrHighpc, Val: int64(0x24), Class: dwarf.ClassConstant}, {Attr: dwarf.AttrStmtList, Val: int64(0), Class: dwarf.ClassLinePtr}}}},
+		},
+	},
+	{
+		"testdata/go-relocation-test-gcc492-arm.obj",
+		[]relocationTestEntry{
+			{0, &dwarf.Entry{Offset: 0xb, Tag: dwarf.TagCompileUnit, Children: true, Field: []dwarf.Field{{Attr: dwarf.AttrProducer, Val: "GNU C 4.9.2 20141224 (prerelease) -march=armv7-a -mfloat-abi=hard -mfpu=vfpv3-d16 -mtls-dialect=gnu -g", Class: dwarf.ClassString}, {Attr: dwarf.AttrLanguage, Val: int64(1), Class: dwarf.ClassConstant}, {Attr: dwarf.AttrName, Val: "go-relocation-test-gcc492.c", Class: dwarf.ClassString}, {Attr: dwarf.AttrCompDir, Val: "/root/go/src/debug/elf/testdata", Class: dwarf.ClassString}, {Attr: dwarf.AttrLowpc, Val: uint64(0x0), Class: dwarf.ClassAddress}, {Attr: dwarf.AttrHighpc, Val: int64(0x28), Class: dwarf.ClassConstant}, {Attr: dwarf.AttrStmtList, Val: int64(0), Class: dwarf.ClassLinePtr}}}},
+		},
+	},
+	{
+		"testdata/go-relocation-test-clang-arm.obj",
+		[]relocationTestEntry{
+			{0, &dwarf.Entry{Offset: 0xb, Tag: dwarf.TagCompileUnit, Children: true, Field: []dwarf.Field{dwarf.Field{Attr: dwarf.AttrProducer, Val: "Debian clang version 3.5.0-10 (tags/RELEASE_350/final) (based on LLVM 3.5.0)", Class: dwarf.ClassString}, dwarf.Field{Attr: dwarf.AttrLanguage, Val: int64(12), Class: dwarf.ClassConstant}, dwarf.Field{Attr: dwarf.AttrName, Val: "hello.c", Class: dwarf.ClassString}, dwarf.Field{Attr: dwarf.AttrStmtList, Val: int64(0x0), Class: dwarf.ClassLinePtr}, dwarf.Field{Attr: dwarf.AttrCompDir, Val: "/tmp", Class: dwarf.ClassString}, dwarf.Field{Attr: dwarf.AttrLowpc, Val: uint64(0x0), Class: dwarf.ClassAddress}, dwarf.Field{Attr: dwarf.AttrHighpc, Val: int64(48), Class: dwarf.ClassConstant}}}},
+		},
+	},
+	{
+		"testdata/go-relocation-test-gcc5-ppc.obj",
+		[]relocationTestEntry{
+			{0, &dwarf.Entry{Offset: 0xb, Tag: dwarf.TagCompileUnit, Children: true, Field: []dwarf.Field{dwarf.Field{Attr: dwarf.AttrProducer, Val: "GNU C11 5.0.0 20150116 (experimental) -Asystem=linux -Asystem=unix -Asystem=posix -g", Class: dwarf.ClassString}, dwarf.Field{Attr: dwarf.AttrLanguage, Val: int64(12), Class: dwarf.ClassConstant}, dwarf.Field{Attr: dwarf.AttrName, Val: "go-relocation-test-gcc5-ppc.c", Class: dwarf.ClassString}, dwarf.Field{Attr: dwarf.AttrCompDir, Val: "/tmp", Class: dwarf.ClassString}, dwarf.Field{Attr: dwarf.AttrLowpc, Val: uint64(0x0), Class: dwarf.ClassAddress}, dwarf.Field{Attr: dwarf.AttrHighpc, Val: int64(0x44), Class: dwarf.ClassConstant}, dwarf.Field{Attr: dwarf.AttrStmtList, Val: int64(0), Class: dwarf.ClassLinePtr}}}},
+		},
+	},
+	{
+		"testdata/go-relocation-test-gcc482-ppc64le.obj",
+		[]relocationTestEntry{
+			{0, &dwarf.Entry{Offset: 0xb, Tag: dwarf.TagCompileUnit, Children: true, Field: []dwarf.Field{dwarf.Field{Attr: dwarf.AttrProducer, Val: "GNU C 4.8.2 -Asystem=linux -Asystem=unix -Asystem=posix -msecure-plt -mtune=power8 -mcpu=power7 -gdwarf-2 -fstack-protector", Class: dwarf.ClassString}, dwarf.Field{Attr: dwarf.AttrLanguage, Val: int64(1), Class: dwarf.ClassConstant}, dwarf.Field{Attr: dwarf.AttrName, Val: "go-relocation-test-gcc482-ppc64le.c", Class: dwarf.ClassString}, dwarf.Field{Attr: dwarf.AttrCompDir, Val: "/tmp", Class: dwarf.ClassString}, dwarf.Field{Attr: dwarf.AttrLowpc, Val: uint64(0x0), Class: dwarf.ClassAddress}, dwarf.Field{Attr: dwarf.AttrHighpc, Val: uint64(0x24), Class: dwarf.ClassAddress}, dwarf.Field{Attr: dwarf.AttrStmtList, Val: int64(0), Class: dwarf.ClassLinePtr}}}},
 		},
 	},
 	{
 		"testdata/go-relocation-test-clang-x86.obj",
 		[]relocationTestEntry{
-			{0, &dwarf.Entry{Offset: 0xb, Tag: dwarf.TagCompileUnit, Children: true, Field: []dwarf.Field{{Attr: dwarf.AttrProducer, Val: "clang version google3-trunk (trunk r209387)"}, {Attr: dwarf.AttrLanguage, Val: int64(12)}, {Attr: dwarf.AttrName, Val: "go-relocation-test-clang.c"}, {Attr: dwarf.AttrStmtList, Val: int64(0)}, {Attr: dwarf.AttrCompDir, Val: "/tmp"}}}},
+			{0, &dwarf.Entry{Offset: 0xb, Tag: dwarf.TagCompileUnit, Children: true, Field: []dwarf.Field{{Attr: dwarf.AttrProducer, Val: "clang version google3-trunk (trunk r209387)", Class: dwarf.ClassString}, {Attr: dwarf.AttrLanguage, Val: int64(12), Class: dwarf.ClassConstant}, {Attr: dwarf.AttrName, Val: "go-relocation-test-clang.c", Class: dwarf.ClassString}, {Attr: dwarf.AttrStmtList, Val: int64(0), Class: dwarf.ClassLinePtr}, {Attr: dwarf.AttrCompDir, Val: "/tmp", Class: dwarf.ClassString}}}},
 		},
 	},
 	{
 		"testdata/gcc-amd64-openbsd-debug-with-rela.obj",
 		[]relocationTestEntry{
-			{203, &dwarf.Entry{Offset: 0xc62, Tag: dwarf.TagMember, Children: false, Field: []dwarf.Field{{Attr: dwarf.AttrName, Val: "it_interval"}, {Attr: dwarf.AttrDeclFile, Val: int64(7)}, {Attr: dwarf.AttrDeclLine, Val: int64(236)}, {Attr: dwarf.AttrType, Val: dwarf.Offset(0xb7f)}, {Attr: dwarf.AttrDataMemberLoc, Val: []byte{0x23, 0x0}}}}},
-			{204, &dwarf.Entry{Offset: 0xc70, Tag: dwarf.TagMember, Children: false, Field: []dwarf.Field{{Attr: dwarf.AttrName, Val: "it_value"}, {Attr: dwarf.AttrDeclFile, Val: int64(7)}, {Attr: dwarf.AttrDeclLine, Val: int64(237)}, {Attr: dwarf.AttrType, Val: dwarf.Offset(0xb7f)}, {Attr: dwarf.AttrDataMemberLoc, Val: []byte{0x23, 0x10}}}}},
+			{203, &dwarf.Entry{Offset: 0xc62, Tag: dwarf.TagMember, Children: false, Field: []dwarf.Field{{Attr: dwarf.AttrName, Val: "it_interval", Class: dwarf.ClassString}, {Attr: dwarf.AttrDeclFile, Val: int64(7), Class: dwarf.ClassConstant}, {Attr: dwarf.AttrDeclLine, Val: int64(236), Class: dwarf.ClassConstant}, {Attr: dwarf.AttrType, Val: dwarf.Offset(0xb7f), Class: dwarf.ClassReference}, {Attr: dwarf.AttrDataMemberLoc, Val: []byte{0x23, 0x0}, Class: dwarf.ClassExprLoc}}}},
+			{204, &dwarf.Entry{Offset: 0xc70, Tag: dwarf.TagMember, Children: false, Field: []dwarf.Field{{Attr: dwarf.AttrName, Val: "it_value", Class: dwarf.ClassString}, {Attr: dwarf.AttrDeclFile, Val: int64(7), Class: dwarf.ClassConstant}, {Attr: dwarf.AttrDeclLine, Val: int64(237), Class: dwarf.ClassConstant}, {Attr: dwarf.AttrType, Val: dwarf.Offset(0xb7f), Class: dwarf.ClassReference}, {Attr: dwarf.AttrDataMemberLoc, Val: []byte{0x23, 0x10}, Class: dwarf.ClassExprLoc}}}},
 		},
 	},
 }
diff --git a/third_party/gofrontend/libgo/go/debug/elf/testdata/go-relocation-test-clang-arm.obj b/third_party/gofrontend/libgo/go/debug/elf/testdata/go-relocation-test-clang-arm.obj
new file mode 100644
index 0000000..1cc7e4b
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/debug/elf/testdata/go-relocation-test-clang-arm.obj
Binary files differ
diff --git a/third_party/gofrontend/libgo/go/debug/elf/testdata/go-relocation-test-gcc492-arm.obj b/third_party/gofrontend/libgo/go/debug/elf/testdata/go-relocation-test-gcc492-arm.obj
new file mode 100644
index 0000000..ed45be2
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/debug/elf/testdata/go-relocation-test-gcc492-arm.obj
Binary files differ
diff --git a/third_party/gofrontend/libgo/go/debug/gosym/pclntab_test.go b/third_party/gofrontend/libgo/go/debug/gosym/pclntab_test.go
index 35502e8..53f3e95 100644
--- a/third_party/gofrontend/libgo/go/debug/gosym/pclntab_test.go
+++ b/third_party/gofrontend/libgo/go/debug/gosym/pclntab_test.go
@@ -6,7 +6,6 @@
 
 import (
 	"debug/elf"
-	"fmt"
 	"io/ioutil"
 	"os"
 	"os/exec"
@@ -30,10 +29,6 @@
 	if self && runtime.GOOS != "linux" {
 		return false
 	}
-	// Command below expects "sh", so Unix.
-	if runtime.GOOS == "windows" || runtime.GOOS == "plan9" {
-		return false
-	}
 	if pclinetestBinary != "" {
 		return true
 	}
@@ -49,9 +44,14 @@
 	// the resulting binary looks like it was built from pclinetest.s,
 	// but we have renamed it to keep it away from the go tool.
 	pclinetestBinary = filepath.Join(pclineTempDir, "pclinetest")
-	command := fmt.Sprintf("go tool 6a -o %s.6 pclinetest.asm && go tool 6l -H linux -E main -o %s %s.6",
-		pclinetestBinary, pclinetestBinary, pclinetestBinary)
-	cmd := exec.Command("sh", "-c", command)
+	cmd := exec.Command("go", "tool", "asm", "-o", pclinetestBinary+".o", "pclinetest.asm")
+	cmd.Stdout = os.Stdout
+	cmd.Stderr = os.Stderr
+	if err := cmd.Run(); err != nil {
+		panic(err)
+	}
+	cmd = exec.Command("go", "tool", "link", "-H", "linux", "-E", "main",
+		"-o", pclinetestBinary, pclinetestBinary+".o")
 	cmd.Stdout = os.Stdout
 	cmd.Stderr = os.Stderr
 	if err := cmd.Run(); err != nil {
@@ -84,7 +84,11 @@
 }
 
 func parse(file string, f *elf.File, t *testing.T) (*elf.File, *Table) {
-	symdat, err := f.Section(".gosymtab").Data()
+	s := f.Section(".gosymtab")
+	if s == nil {
+		t.Skip("no .gosymtab section")
+	}
+	symdat, err := s.Data()
 	if err != nil {
 		f.Close()
 		t.Fatalf("reading %s gosymtab: %v", file, err)
diff --git a/third_party/gofrontend/libgo/go/debug/gosym/symtab.go b/third_party/gofrontend/libgo/go/debug/gosym/symtab.go
index ee18499..46f0783 100644
--- a/third_party/gofrontend/libgo/go/debug/gosym/symtab.go
+++ b/third_party/gofrontend/libgo/go/debug/gosym/symtab.go
@@ -30,7 +30,7 @@
 	Type   byte
 	Name   string
 	GoType uint64
-	// If this symbol if a function symbol, the corresponding Func
+	// If this symbol is a function symbol, the corresponding Func
 	Func *Func
 }
 
diff --git a/third_party/gofrontend/libgo/go/debug/macho/file.go b/third_party/gofrontend/libgo/go/debug/macho/file.go
index da13c51..a7599aa 100644
--- a/third_party/gofrontend/libgo/go/debug/macho/file.go
+++ b/third_party/gofrontend/libgo/go/debug/macho/file.go
@@ -472,8 +472,8 @@
 // DWARF returns the DWARF debug information for the Mach-O file.
 func (f *File) DWARF() (*dwarf.Data, error) {
 	// There are many other DWARF sections, but these
-	// are the required ones, and the debug/dwarf package
-	// does not use the others, so don't bother loading them.
+	// are the ones the debug/dwarf package uses.
+	// Don't bother loading others.
 	var names = [...]string{"abbrev", "info", "line", "str"}
 	var dat [len(names)][]byte
 	for i, name := range names {
diff --git a/third_party/gofrontend/libgo/go/debug/pe/file.go b/third_party/gofrontend/libgo/go/debug/pe/file.go
index 759e567..3df4ae7 100644
--- a/third_party/gofrontend/libgo/go/debug/pe/file.go
+++ b/third_party/gofrontend/libgo/go/debug/pe/file.go
@@ -296,9 +296,9 @@
 
 func (f *File) DWARF() (*dwarf.Data, error) {
 	// There are many other DWARF sections, but these
-	// are the required ones, and the debug/dwarf package
-	// does not use the others, so don't bother loading them.
-	var names = [...]string{"abbrev", "info", "str"}
+	// are the ones the debug/dwarf package uses.
+	// Don't bother loading others.
+	var names = [...]string{"abbrev", "info", "line", "str"}
 	var dat [len(names)][]byte
 	for i, name := range names {
 		name = ".debug_" + name
@@ -310,11 +310,14 @@
 		if err != nil && uint32(len(b)) < s.Size {
 			return nil, err
 		}
+		if 0 < s.VirtualSize && s.VirtualSize < s.Size {
+			b = b[:s.VirtualSize]
+		}
 		dat[i] = b
 	}
 
-	abbrev, info, str := dat[0], dat[1], dat[2]
-	return dwarf.New(abbrev, nil, nil, info, nil, nil, nil, str)
+	abbrev, info, line, str := dat[0], dat[1], dat[2], dat[3]
+	return dwarf.New(abbrev, nil, nil, info, line, nil, nil, str)
 }
 
 // ImportedSymbols returns the names of all symbols
diff --git a/third_party/gofrontend/libgo/go/debug/pe/file_test.go b/third_party/gofrontend/libgo/go/debug/pe/file_test.go
index 0d73969..316a569 100644
--- a/third_party/gofrontend/libgo/go/debug/pe/file_test.go
+++ b/third_party/gofrontend/libgo/go/debug/pe/file_test.go
@@ -5,24 +5,30 @@
 package pe
 
 import (
+	"debug/dwarf"
+	"io/ioutil"
+	"os"
+	"os/exec"
+	"path/filepath"
 	"reflect"
+	"runtime"
 	"testing"
 )
 
 type fileTest struct {
-	file     string
-	hdr      FileHeader
-	opthdr   interface{}
-	sections []*SectionHeader
-	symbols  []*Symbol
+	file           string
+	hdr            FileHeader
+	opthdr         interface{}
+	sections       []*SectionHeader
+	symbols        []*Symbol
+	hasNoDwarfInfo bool
 }
 
 var fileTests = []fileTest{
 	{
-		"testdata/gcc-386-mingw-obj",
-		FileHeader{0x014c, 0x000c, 0x0, 0x64a, 0x1e, 0x0, 0x104},
-		nil,
-		[]*SectionHeader{
+		file: "testdata/gcc-386-mingw-obj",
+		hdr:  FileHeader{0x014c, 0x000c, 0x0, 0x64a, 0x1e, 0x0, 0x104},
+		sections: []*SectionHeader{
 			{".text", 0, 0, 36, 500, 1440, 0, 3, 0, 0x60300020},
 			{".data", 0, 0, 0, 0, 0, 0, 0, 0, 3224371264},
 			{".bss", 0, 0, 0, 0, 0, 0, 0, 0, 3224371328},
@@ -36,7 +42,7 @@
 			{".debug_pubtypes", 0, 0, 38, 1370, 1580, 0, 1, 0, 1108344832},
 			{".debug_aranges", 0, 0, 32, 1408, 1590, 0, 2, 0, 1108344832},
 		},
-		[]*Symbol{
+		symbols: []*Symbol{
 			{".file", 0x0, -2, 0x0, 0x67},
 			{"_main", 0x0, 1, 0x20, 0x2},
 			{".text", 0x0, 1, 0x0, 0x3},
@@ -56,9 +62,9 @@
 		},
 	},
 	{
-		"testdata/gcc-386-mingw-exec",
-		FileHeader{0x014c, 0x000f, 0x4c6a1b60, 0x3c00, 0x282, 0xe0, 0x107},
-		&OptionalHeader32{
+		file: "testdata/gcc-386-mingw-exec",
+		hdr:  FileHeader{0x014c, 0x000f, 0x4c6a1b60, 0x3c00, 0x282, 0xe0, 0x107},
+		opthdr: &OptionalHeader32{
 			0x10b, 0x2, 0x38, 0xe00, 0x1a00, 0x200, 0x1160, 0x1000, 0x2000, 0x400000, 0x1000, 0x200, 0x4, 0x0, 0x1, 0x0, 0x4, 0x0, 0x0, 0x10000, 0x400, 0x14abb, 0x3, 0x0, 0x200000, 0x1000, 0x100000, 0x1000, 0x0, 0x10,
 			[16]DataDirectory{
 				{0x0, 0x0},
@@ -79,7 +85,7 @@
 				{0x0, 0x0},
 			},
 		},
-		[]*SectionHeader{
+		sections: []*SectionHeader{
 			{".text", 0xcd8, 0x1000, 0xe00, 0x400, 0x0, 0x0, 0x0, 0x0, 0x60500060},
 			{".data", 0x10, 0x2000, 0x200, 0x1200, 0x0, 0x0, 0x0, 0x0, 0xc0300040},
 			{".rdata", 0x120, 0x3000, 0x200, 0x1400, 0x0, 0x0, 0x0, 0x0, 0x40300040},
@@ -96,13 +102,11 @@
 			{".debug_frame", 0x34, 0xe000, 0x200, 0x3800, 0x0, 0x0, 0x0, 0x0, 0x42300000},
 			{".debug_loc", 0x38, 0xf000, 0x200, 0x3a00, 0x0, 0x0, 0x0, 0x0, 0x42100000},
 		},
-		[]*Symbol{},
 	},
 	{
-		"testdata/gcc-amd64-mingw-obj",
-		FileHeader{0x8664, 0x6, 0x0, 0x198, 0x12, 0x0, 0x4},
-		nil,
-		[]*SectionHeader{
+		file: "testdata/gcc-amd64-mingw-obj",
+		hdr:  FileHeader{0x8664, 0x6, 0x0, 0x198, 0x12, 0x0, 0x4},
+		sections: []*SectionHeader{
 			{".text", 0x0, 0x0, 0x30, 0x104, 0x15c, 0x0, 0x3, 0x0, 0x60500020},
 			{".data", 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xc0500040},
 			{".bss", 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xc0500080},
@@ -110,7 +114,7 @@
 			{".xdata", 0x0, 0x0, 0xc, 0x144, 0x0, 0x0, 0x0, 0x0, 0x40300040},
 			{".pdata", 0x0, 0x0, 0xc, 0x150, 0x17a, 0x0, 0x3, 0x0, 0x40300040},
 		},
-		[]*Symbol{
+		symbols: []*Symbol{
 			{".file", 0x0, -2, 0x0, 0x67},
 			{"main", 0x0, 1, 0x20, 0x2},
 			{".text", 0x0, 1, 0x0, 0x3},
@@ -122,11 +126,12 @@
 			{"__main", 0x0, 0, 0x20, 0x2},
 			{"puts", 0x0, 0, 0x20, 0x2},
 		},
+		hasNoDwarfInfo: true,
 	},
 	{
-		"testdata/gcc-amd64-mingw-exec",
-		FileHeader{0x8664, 0x11, 0x53e4364f, 0x39600, 0x6fc, 0xf0, 0x27},
-		&OptionalHeader64{
+		file: "testdata/gcc-amd64-mingw-exec",
+		hdr:  FileHeader{0x8664, 0x11, 0x53e4364f, 0x39600, 0x6fc, 0xf0, 0x27},
+		opthdr: &OptionalHeader64{
 			0x20b, 0x2, 0x16, 0x6a00, 0x2400, 0x1600, 0x14e0, 0x1000, 0x400000, 0x1000, 0x200, 0x4, 0x0, 0x0, 0x0, 0x5, 0x2, 0x0, 0x45000, 0x600, 0x46f19, 0x3, 0x0, 0x200000, 0x1000, 0x100000, 0x1000, 0x0, 0x10,
 			[16]DataDirectory{
 				{0x0, 0x0},
@@ -146,7 +151,7 @@
 				{0x0, 0x0},
 				{0x0, 0x0},
 			}},
-		[]*SectionHeader{
+		sections: []*SectionHeader{
 			{".text", 0x6860, 0x1000, 0x6a00, 0x600, 0x0, 0x0, 0x0, 0x0, 0x60500020},
 			{".data", 0xe0, 0x8000, 0x200, 0x7000, 0x0, 0x0, 0x0, 0x0, 0xc0500040},
 			{".rdata", 0x6b0, 0x9000, 0x800, 0x7200, 0x0, 0x0, 0x0, 0x0, 0x40600040},
@@ -165,7 +170,6 @@
 			{".debug_loc", 0x13240, 0x30000, 0x13400, 0x25600, 0x0, 0x0, 0x0, 0x0, 0x42100040},
 			{".debug_ranges", 0xa70, 0x44000, 0xc00, 0x38a00, 0x0, 0x0, 0x0, 0x0, 0x42100040},
 		},
-		[]*Symbol{},
 	},
 }
 
@@ -231,6 +235,12 @@
 				t.Errorf("open %s, symbol %d:\n\thave %#v\n\twant %#v\n", tt.file, i, have, want)
 			}
 		}
+		if !tt.hasNoDwarfInfo {
+			_, err = f.DWARF()
+			if err != nil {
+				t.Errorf("fetching %s dwarf details failed: %v", tt.file, err)
+			}
+		}
 	}
 }
 
@@ -241,3 +251,59 @@
 		t.Errorf("open %s: succeeded unexpectedly", filename)
 	}
 }
+
+func TestDWARF(t *testing.T) {
+	if runtime.GOOS != "windows" {
+		t.Skip("skipping windows only test")
+	}
+
+	tmpdir, err := ioutil.TempDir("", "TestDWARF")
+	if err != nil {
+		t.Fatal("TempDir failed: ", err)
+	}
+	defer os.RemoveAll(tmpdir)
+
+	prog := `
+package main
+func main() {
+}
+`
+	src := filepath.Join(tmpdir, "a.go")
+	exe := filepath.Join(tmpdir, "a.exe")
+	err = ioutil.WriteFile(src, []byte(prog), 0644)
+	output, err := exec.Command("go", "build", "-o", exe, src).CombinedOutput()
+	if err != nil {
+		t.Fatalf("building test executable failed: %s %s", err, output)
+	}
+
+	f, err := Open(exe)
+	if err != nil {
+		t.Fatal(err)
+	}
+	defer f.Close()
+
+	d, err := f.DWARF()
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	// look for main.main
+	r := d.Reader()
+	for {
+		e, err := r.Next()
+		if err != nil {
+			t.Fatal("r.Next:", err)
+		}
+		if e == nil {
+			break
+		}
+		if e.Tag == dwarf.TagSubprogram {
+			for _, f := range e.Field {
+				if f.Attr == dwarf.AttrName && e.Val(dwarf.AttrName) == "main.main" {
+					return
+				}
+			}
+		}
+	}
+	t.Fatal("main.main not found")
+}
diff --git a/third_party/gofrontend/libgo/go/encoding/asn1/asn1.go b/third_party/gofrontend/libgo/go/encoding/asn1/asn1.go
index 8b3d1b3..2ac411a 100644
--- a/third_party/gofrontend/libgo/go/encoding/asn1/asn1.go
+++ b/third_party/gofrontend/libgo/go/encoding/asn1/asn1.go
@@ -20,11 +20,13 @@
 // everything by any means.
 
 import (
+	"errors"
 	"fmt"
 	"math/big"
 	"reflect"
 	"strconv"
 	"time"
+	"unicode/utf8"
 )
 
 // A StructuralError suggests that the ASN.1 data is valid, but the Go type
@@ -287,11 +289,23 @@
 
 func parseUTCTime(bytes []byte) (ret time.Time, err error) {
 	s := string(bytes)
-	ret, err = time.Parse("0601021504Z0700", s)
+
+	formatStr := "0601021504Z0700"
+	ret, err = time.Parse(formatStr, s)
 	if err != nil {
-		ret, err = time.Parse("060102150405Z0700", s)
+		formatStr = "060102150405Z0700"
+		ret, err = time.Parse(formatStr, s)
 	}
-	if err == nil && ret.Year() >= 2050 {
+	if err != nil {
+		return
+	}
+
+	if serialized := ret.Format(formatStr); serialized != s {
+		err = fmt.Errorf("asn1: time did not serialize back to the original value and may be invalid: given %q, but serialized as %q", s, serialized)
+		return
+	}
+
+	if ret.Year() >= 2050 {
 		// UTCTime only encodes times prior to 2050. See https://tools.ietf.org/html/rfc5280#section-4.1.2.5.1
 		ret = ret.AddDate(-100, 0, 0)
 	}
@@ -302,7 +316,18 @@
 // parseGeneralizedTime parses the GeneralizedTime from the given byte slice
 // and returns the resulting time.
 func parseGeneralizedTime(bytes []byte) (ret time.Time, err error) {
-	return time.Parse("20060102150405Z0700", string(bytes))
+	const formatStr = "20060102150405Z0700"
+	s := string(bytes)
+
+	if ret, err = time.Parse(formatStr, s); err != nil {
+		return
+	}
+
+	if serialized := ret.Format(formatStr); serialized != s {
+		err = fmt.Errorf("asn1: time did not serialize back to the original value and may be invalid: given %q, but serialized as %q", s, serialized)
+	}
+
+	return
 }
 
 // PrintableString
@@ -320,7 +345,7 @@
 	return
 }
 
-// isPrintable returns true iff the given b is in the ASN.1 PrintableString set.
+// isPrintable reports whether the given b is in the ASN.1 PrintableString set.
 func isPrintable(b byte) bool {
 	return 'a' <= b && b <= 'z' ||
 		'A' <= b && b <= 'Z' ||
@@ -365,6 +390,9 @@
 // parseUTF8String parses a ASN.1 UTF8String (raw UTF-8) from the given byte
 // array and returns it.
 func parseUTF8String(bytes []byte) (ret string, err error) {
+	if !utf8.Valid(bytes) {
+		return "", errors.New("asn1: invalid UTF-8 string")
+	}
 	return string(bytes), nil
 }
 
@@ -389,6 +417,12 @@
 // don't distinguish between ordered and unordered objects in this code.
 func parseTagAndLength(bytes []byte, initOffset int) (ret tagAndLength, offset int, err error) {
 	offset = initOffset
+	// parseTagAndLength should not be called without at least a single
+	// byte to read. Thus this check is for robustness:
+	if offset >= len(bytes) {
+		err = errors.New("asn1: internal error in parseTagAndLength")
+		return
+	}
 	b := bytes[offset]
 	offset++
 	ret.class = int(b >> 6)
@@ -579,6 +613,8 @@
 				result, err = parseObjectIdentifier(innerBytes)
 			case tagUTCTime:
 				result, err = parseUTCTime(innerBytes)
+			case tagGeneralizedTime:
+				result, err = parseGeneralizedTime(innerBytes)
 			case tagOctetString:
 				result = innerBytes
 			default:
@@ -609,6 +645,10 @@
 		if params.application {
 			expectedClass = classApplication
 		}
+		if offset == len(bytes) {
+			err = StructuralError{"explicit tag has no child"}
+			return
+		}
 		if t.class == expectedClass && t.tag == *params.tag && (t.length == 0 || t.isCompound) {
 			if t.length > 0 {
 				t, offset, err = parseTagAndLength(bytes, offset)
diff --git a/third_party/gofrontend/libgo/go/encoding/asn1/asn1_test.go b/third_party/gofrontend/libgo/go/encoding/asn1/asn1_test.go
index 4e864d0..893d080 100644
--- a/third_party/gofrontend/libgo/go/encoding/asn1/asn1_test.go
+++ b/third_party/gofrontend/libgo/go/encoding/asn1/asn1_test.go
@@ -9,6 +9,7 @@
 	"fmt"
 	"math/big"
 	"reflect"
+	"strings"
 	"testing"
 	"time"
 )
@@ -258,6 +259,24 @@
 	{"91050633444aZ", false, time.Time{}},
 	{"910506334461Z", false, time.Time{}},
 	{"910506334400Za", false, time.Time{}},
+	/* These are invalid times. However, the time package normalises times
+	 * and they were accepted in some versions. See #11134. */
+	{"000100000000Z", false, time.Time{}},
+	{"101302030405Z", false, time.Time{}},
+	{"100002030405Z", false, time.Time{}},
+	{"100100030405Z", false, time.Time{}},
+	{"100132030405Z", false, time.Time{}},
+	{"100231030405Z", false, time.Time{}},
+	{"100102240405Z", false, time.Time{}},
+	{"100102036005Z", false, time.Time{}},
+	{"100102030460Z", false, time.Time{}},
+	{"-100102030410Z", false, time.Time{}},
+	{"10-0102030410Z", false, time.Time{}},
+	{"10-0002030410Z", false, time.Time{}},
+	{"1001-02030410Z", false, time.Time{}},
+	{"100102-030410Z", false, time.Time{}},
+	{"10010203-0410Z", false, time.Time{}},
+	{"1001020304-10Z", false, time.Time{}},
 }
 
 func TestUTCTime(t *testing.T) {
@@ -287,6 +306,24 @@
 	{"20100102030405", false, time.Time{}},
 	{"20100102030405+0607", true, time.Date(2010, 01, 02, 03, 04, 05, 0, time.FixedZone("", 6*60*60+7*60))},
 	{"20100102030405-0607", true, time.Date(2010, 01, 02, 03, 04, 05, 0, time.FixedZone("", -6*60*60-7*60))},
+	/* These are invalid times. However, the time package normalises times
+	 * and they were accepted in some versions. See #11134. */
+	{"00000100000000Z", false, time.Time{}},
+	{"20101302030405Z", false, time.Time{}},
+	{"20100002030405Z", false, time.Time{}},
+	{"20100100030405Z", false, time.Time{}},
+	{"20100132030405Z", false, time.Time{}},
+	{"20100231030405Z", false, time.Time{}},
+	{"20100102240405Z", false, time.Time{}},
+	{"20100102036005Z", false, time.Time{}},
+	{"20100102030460Z", false, time.Time{}},
+	{"-20100102030410Z", false, time.Time{}},
+	{"2010-0102030410Z", false, time.Time{}},
+	{"2010-0002030410Z", false, time.Time{}},
+	{"201001-02030410Z", false, time.Time{}},
+	{"20100102-030410Z", false, time.Time{}},
+	{"2010010203-0410Z", false, time.Time{}},
+	{"201001020304-10Z", false, time.Time{}},
 }
 
 func TestGeneralizedTime(t *testing.T) {
@@ -297,7 +334,7 @@
 		}
 		if err == nil {
 			if !reflect.DeepEqual(test.out, ret) {
-				t.Errorf("#%d: Bad result: %v (expected %v)", i, ret, test.out)
+				t.Errorf("#%d: Bad result: %q → %v (expected %v)", i, test.in, ret, test.out)
 			}
 		}
 	}
@@ -358,6 +395,8 @@
 var parseFieldParametersTestData []parseFieldParametersTest = []parseFieldParametersTest{
 	{"", fieldParameters{}},
 	{"ia5", fieldParameters{stringType: tagIA5String}},
+	{"generalized", fieldParameters{timeType: tagGeneralizedTime}},
+	{"utc", fieldParameters{timeType: tagUTCTime}},
 	{"printable", fieldParameters{stringType: tagPrintableString}},
 	{"optional", fieldParameters{optional: true}},
 	{"explicit", fieldParameters{explicit: true, tag: new(int)}},
@@ -366,7 +405,7 @@
 	{"default:42", fieldParameters{defaultValue: newInt64(42)}},
 	{"tag:17", fieldParameters{tag: newInt(17)}},
 	{"optional,explicit,default:42,tag:17", fieldParameters{optional: true, explicit: true, defaultValue: newInt64(42), tag: newInt(17)}},
-	{"optional,explicit,default:42,tag:17,rubbish1", fieldParameters{true, true, false, newInt64(42), newInt(17), 0, false, false}},
+	{"optional,explicit,default:42,tag:17,rubbish1", fieldParameters{true, true, false, newInt64(42), newInt(17), 0, 0, false, false}},
 	{"set", fieldParameters{set: true}},
 }
 
@@ -865,3 +904,39 @@
 		t.Errorf("Wrong result. Got %v, want %v", result.Time, expected)
 	}
 }
+
+type truncatedExplicitTagTest struct {
+	Test int `asn1:"explicit,tag:0"`
+}
+
+func TestTruncatedExplicitTag(t *testing.T) {
+	// This crashed Unmarshal in the past. See #11154.
+	der := []byte{
+		0x30, // SEQUENCE
+		0x02, // two bytes long
+		0xa0, // context-specific, tag 0
+		0x30, // 48 bytes long
+	}
+
+	var result truncatedExplicitTagTest
+	if _, err := Unmarshal(der, &result); err == nil {
+		t.Error("Unmarshal returned without error")
+	}
+}
+
+type invalidUTF8Test struct {
+	Str string `asn1:"utf8"`
+}
+
+func TestUnmarshalInvalidUTF8(t *testing.T) {
+	data := []byte("0\x05\f\x03a\xc9c")
+	var result invalidUTF8Test
+	_, err := Unmarshal(data, &result)
+
+	const expectedSubstring = "UTF"
+	if err == nil {
+		t.Fatal("Successfully unmarshaled invalid UTF-8 data")
+	} else if !strings.Contains(err.Error(), expectedSubstring) {
+		t.Fatalf("Expected error to mention %q but error was %q", expectedSubstring, err.Error())
+	}
+}
diff --git a/third_party/gofrontend/libgo/go/encoding/asn1/common.go b/third_party/gofrontend/libgo/go/encoding/asn1/common.go
index 33a117e..ab85e04 100644
--- a/third_party/gofrontend/libgo/go/encoding/asn1/common.go
+++ b/third_party/gofrontend/libgo/go/encoding/asn1/common.go
@@ -74,6 +74,7 @@
 	defaultValue *int64 // a default value for INTEGER typed fields (maybe nil).
 	tag          *int   // the EXPLICIT or IMPLICIT tag (maybe nil).
 	stringType   int    // the string tag to use when marshaling.
+	timeType     int    // the time tag to use when marshaling.
 	set          bool   // true iff this should be encoded as a SET
 	omitEmpty    bool   // true iff this should be omitted if empty when marshaling.
 
@@ -94,6 +95,10 @@
 			if ret.tag == nil {
 				ret.tag = new(int)
 			}
+		case part == "generalized":
+			ret.timeType = tagGeneralizedTime
+		case part == "utc":
+			ret.timeType = tagUTCTime
 		case part == "ia5":
 			ret.stringType = tagIA5String
 		case part == "printable":
diff --git a/third_party/gofrontend/libgo/go/encoding/asn1/marshal.go b/third_party/gofrontend/libgo/go/encoding/asn1/marshal.go
index b2f104b..67a019d 100644
--- a/third_party/gofrontend/libgo/go/encoding/asn1/marshal.go
+++ b/third_party/gofrontend/libgo/go/encoding/asn1/marshal.go
@@ -18,7 +18,7 @@
 // A forkableWriter is an in-memory buffer that can be
 // 'forked' to create new forkableWriters that bracket the
 // original.  After
-//    pre, post := w.fork();
+//    pre, post := w.fork()
 // the overall sequence of bytes represented is logically w+pre+post.
 type forkableWriter struct {
 	*bytes.Buffer
@@ -410,9 +410,11 @@
 
 func marshalBody(out *forkableWriter, value reflect.Value, params fieldParameters) (err error) {
 	switch value.Type() {
+	case flagType:
+		return nil
 	case timeType:
 		t := value.Interface().(time.Time)
-		if outsideUTCRange(t) {
+		if params.timeType == tagGeneralizedTime || outsideUTCRange(t) {
 			return marshalGeneralizedTime(out, t)
 		} else {
 			return marshalUTCTime(out, t)
@@ -552,6 +554,10 @@
 	}
 	class := classUniversal
 
+	if params.timeType != 0 && tag != tagUTCTime {
+		return StructuralError{"explicit time type given to non-time member"}
+	}
+
 	if params.stringType != 0 && tag != tagPrintableString {
 		return StructuralError{"explicit string type given to non-string member"}
 	}
@@ -575,7 +581,7 @@
 			tag = params.stringType
 		}
 	case tagUTCTime:
-		if outsideUTCRange(v.Interface().(time.Time)) {
+		if params.timeType == tagGeneralizedTime || outsideUTCRange(v.Interface().(time.Time)) {
 			tag = tagGeneralizedTime
 		}
 	}
diff --git a/third_party/gofrontend/libgo/go/encoding/asn1/marshal_test.go b/third_party/gofrontend/libgo/go/encoding/asn1/marshal_test.go
index 5b0115f..cdca8aa 100644
--- a/third_party/gofrontend/libgo/go/encoding/asn1/marshal_test.go
+++ b/third_party/gofrontend/libgo/go/encoding/asn1/marshal_test.go
@@ -42,6 +42,14 @@
 	A int `asn1:"explicit,tag:5"`
 }
 
+type flagTest struct {
+	A Flag `asn1:"tag:0,optional"`
+}
+
+type generalizedTimeTest struct {
+	A time.Time `asn1:"generalized"`
+}
+
 type ia5StringTest struct {
 	A string `asn1:"ia5"`
 }
@@ -92,10 +100,13 @@
 	{[]byte{1, 2, 3}, "0403010203"},
 	{implicitTagTest{64}, "3003850140"},
 	{explicitTagTest{64}, "3005a503020140"},
+	{flagTest{true}, "30028000"},
+	{flagTest{false}, "3000"},
 	{time.Unix(0, 0).UTC(), "170d3730303130313030303030305a"},
 	{time.Unix(1258325776, 0).UTC(), "170d3039313131353232353631365a"},
 	{time.Unix(1258325776, 0).In(PST), "17113039313131353134353631362d30383030"},
 	{farFuture(), "180f32313030303430353132303130315a"},
+	{generalizedTimeTest{time.Unix(1258325776, 0).UTC()}, "3011180f32303039313131353232353631365a"},
 	{BitString{[]byte{0x80}, 1}, "03020780"},
 	{BitString{[]byte{0x81, 0xf0}, 12}, "03030481f0"},
 	{ObjectIdentifier([]int{1, 2, 3, 4}), "06032a0304"},
diff --git a/third_party/gofrontend/libgo/go/encoding/base64/base64.go b/third_party/gofrontend/libgo/go/encoding/base64/base64.go
index ad3abe6..3302fb4 100644
--- a/third_party/gofrontend/libgo/go/encoding/base64/base64.go
+++ b/third_party/gofrontend/libgo/go/encoding/base64/base64.go
@@ -6,10 +6,8 @@
 package base64
 
 import (
-	"bytes"
 	"io"
 	"strconv"
-	"strings"
 )
 
 /*
@@ -22,18 +20,32 @@
 // (RFC 1421).  RFC 4648 also defines an alternate encoding, which is
 // the standard encoding with - and _ substituted for + and /.
 type Encoding struct {
-	encode    string
+	encode    [64]byte
 	decodeMap [256]byte
+	padChar   rune
 }
 
+const (
+	StdPadding rune = '=' // Standard padding character
+	NoPadding  rune = -1  // No padding
+)
+
 const encodeStd = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
 const encodeURL = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_"
 
-// NewEncoding returns a new Encoding defined by the given alphabet,
+// NewEncoding returns a new padded Encoding defined by the given alphabet,
 // which must be a 64-byte string.
+// The resulting Encoding uses the default padding character ('='),
+// which may be changed or disabled via WithPadding.
 func NewEncoding(encoder string) *Encoding {
+	if len(encoder) != 64 {
+		panic("encoding alphabet is not 64-bytes long")
+	}
+
 	e := new(Encoding)
-	e.encode = encoder
+	e.padChar = StdPadding
+	copy(e.encode[:], encoder)
+
 	for i := 0; i < len(e.decodeMap); i++ {
 		e.decodeMap[i] = 0xFF
 	}
@@ -43,6 +55,13 @@
 	return e
 }
 
+// WithPadding creates a new encoding identical to enc except
+// with a specified padding character, or NoPadding to disable padding.
+func (enc Encoding) WithPadding(padding rune) *Encoding {
+	enc.padChar = padding
+	return &enc
+}
+
 // StdEncoding is the standard base64 encoding, as defined in
 // RFC 4648.
 var StdEncoding = NewEncoding(encodeStd)
@@ -51,12 +70,15 @@
 // It is typically used in URLs and file names.
 var URLEncoding = NewEncoding(encodeURL)
 
-var removeNewlinesMapper = func(r rune) rune {
-	if r == '\r' || r == '\n' {
-		return -1
-	}
-	return r
-}
+// RawStdEncoding is the standard raw, unpadded base64 encoding,
+// as defined in RFC 4648 section 3.2.
+// This is the same as StdEncoding but omits padding characters.
+var RawStdEncoding = StdEncoding.WithPadding(NoPadding)
+
+// URLEncoding is the unpadded alternate base64 encoding defined in RFC 4648.
+// It is typically used in URLs and file names.
+// This is the same as URLEncoding but omits padding characters.
+var RawURLEncoding = URLEncoding.WithPadding(NoPadding)
 
 /*
  * Encoder
@@ -73,42 +95,45 @@
 		return
 	}
 
-	for len(src) > 0 {
-		var b0, b1, b2, b3 byte
+	di, si := 0, 0
+	n := (len(src) / 3) * 3
+	for si < n {
+		// Convert 3x 8bit source bytes into 4 bytes
+		val := uint(src[si+0])<<16 | uint(src[si+1])<<8 | uint(src[si+2])
 
-		// Unpack 4x 6-bit source blocks into a 4 byte
-		// destination quantum
-		switch len(src) {
-		default:
-			b3 = src[2] & 0x3F
-			b2 = src[2] >> 6
-			fallthrough
-		case 2:
-			b2 |= (src[1] << 2) & 0x3F
-			b1 = src[1] >> 4
-			fallthrough
-		case 1:
-			b1 |= (src[0] << 4) & 0x3F
-			b0 = src[0] >> 2
+		dst[di+0] = enc.encode[val>>18&0x3F]
+		dst[di+1] = enc.encode[val>>12&0x3F]
+		dst[di+2] = enc.encode[val>>6&0x3F]
+		dst[di+3] = enc.encode[val&0x3F]
+
+		si += 3
+		di += 4
+	}
+
+	remain := len(src) - si
+	if remain == 0 {
+		return
+	}
+	// Add the remaining small block
+	val := uint(src[si+0]) << 16
+	if remain == 2 {
+		val |= uint(src[si+1]) << 8
+	}
+
+	dst[di+0] = enc.encode[val>>18&0x3F]
+	dst[di+1] = enc.encode[val>>12&0x3F]
+
+	switch remain {
+	case 2:
+		dst[di+2] = enc.encode[val>>6&0x3F]
+		if enc.padChar != NoPadding {
+			dst[di+3] = byte(enc.padChar)
 		}
-
-		// Encode 6-bit blocks using the base64 alphabet
-		dst[0] = enc.encode[b0]
-		dst[1] = enc.encode[b1]
-		dst[2] = enc.encode[b2]
-		dst[3] = enc.encode[b3]
-
-		// Pad the final quantum
-		if len(src) < 3 {
-			dst[3] = '='
-			if len(src) < 2 {
-				dst[2] = '='
-			}
-			break
+	case 1:
+		if enc.padChar != NoPadding {
+			dst[di+2] = byte(enc.padChar)
+			dst[di+3] = byte(enc.padChar)
 		}
-
-		src = src[3:]
-		dst = dst[4:]
 	}
 }
 
@@ -145,8 +170,8 @@
 		if e.nbuf < 3 {
 			return
 		}
-		e.enc.Encode(e.out[0:], e.buf[0:])
-		if _, e.err = e.w.Write(e.out[0:4]); e.err != nil {
+		e.enc.Encode(e.out[:], e.buf[:])
+		if _, e.err = e.w.Write(e.out[:4]); e.err != nil {
 			return n, e.err
 		}
 		e.nbuf = 0
@@ -159,7 +184,7 @@
 			nn = len(p)
 			nn -= nn % 3
 		}
-		e.enc.Encode(e.out[0:], p[0:nn])
+		e.enc.Encode(e.out[:], p[:nn])
 		if _, e.err = e.w.Write(e.out[0 : nn/3*4]); e.err != nil {
 			return n, e.err
 		}
@@ -181,9 +206,9 @@
 func (e *encoder) Close() error {
 	// If there's anything left in the buffer, flush it out
 	if e.err == nil && e.nbuf > 0 {
-		e.enc.Encode(e.out[0:], e.buf[0:e.nbuf])
+		e.enc.Encode(e.out[:], e.buf[:e.nbuf])
+		_, e.err = e.w.Write(e.out[:e.enc.EncodedLen(e.nbuf)])
 		e.nbuf = 0
-		_, e.err = e.w.Write(e.out[0:4])
 	}
 	return e.err
 }
@@ -199,7 +224,12 @@
 
 // EncodedLen returns the length in bytes of the base64 encoding
 // of an input buffer of length n.
-func (enc *Encoding) EncodedLen(n int) int { return (n + 2) / 3 * 4 }
+func (enc *Encoding) EncodedLen(n int) int {
+	if enc.padChar == NoPadding {
+		return (n*8 + 5) / 6 // minimum # chars at 6 bits per char
+	}
+	return (n + 2) / 3 * 4 // minimum # 4-char quanta, 3 bytes each
+}
 
 /*
  * Decoder
@@ -212,66 +242,86 @@
 }
 
 // decode is like Decode but returns an additional 'end' value, which
-// indicates if end-of-message padding was encountered and thus any
-// additional data is an error. This method assumes that src has been
-// stripped of all supported whitespace ('\r' and '\n').
+// indicates if end-of-message padding or a partial quantum was encountered
+// and thus any additional data is an error.
 func (enc *Encoding) decode(dst, src []byte) (n int, end bool, err error) {
-	olen := len(src)
-	for len(src) > 0 && !end {
+	si := 0
+
+	// skip over newlines
+	for si < len(src) && (src[si] == '\n' || src[si] == '\r') {
+		si++
+	}
+
+	for si < len(src) && !end {
 		// Decode quantum using the base64 alphabet
 		var dbuf [4]byte
-		dlen := 4
+		dinc, dlen := 3, 4
 
 		for j := range dbuf {
-			if len(src) == 0 {
-				return n, false, CorruptInputError(olen - len(src) - j)
+			if len(src) == si {
+				if enc.padChar != NoPadding || j < 2 {
+					return n, false, CorruptInputError(si - j)
+				}
+				dinc, dlen, end = j-1, j, true
+				break
 			}
-			in := src[0]
-			src = src[1:]
-			if in == '=' {
+			in := src[si]
+
+			si++
+			// skip over newlines
+			for si < len(src) && (src[si] == '\n' || src[si] == '\r') {
+				si++
+			}
+
+			if rune(in) == enc.padChar {
 				// We've reached the end and there's padding
 				switch j {
 				case 0, 1:
 					// incorrect padding
-					return n, false, CorruptInputError(olen - len(src) - 1)
+					return n, false, CorruptInputError(si - 1)
 				case 2:
 					// "==" is expected, the first "=" is already consumed.
-					if len(src) == 0 {
+					if si == len(src) {
 						// not enough padding
-						return n, false, CorruptInputError(olen)
+						return n, false, CorruptInputError(len(src))
 					}
-					if src[0] != '=' {
+					if rune(src[si]) != enc.padChar {
 						// incorrect padding
-						return n, false, CorruptInputError(olen - len(src) - 1)
+						return n, false, CorruptInputError(si - 1)
 					}
-					src = src[1:]
+
+					si++
+					// skip over newlines
+					for si < len(src) && (src[si] == '\n' || src[si] == '\r') {
+						si++
+					}
 				}
-				if len(src) > 0 {
+				if si < len(src) {
 					// trailing garbage
-					err = CorruptInputError(olen - len(src))
+					err = CorruptInputError(si)
 				}
-				dlen, end = j, true
+				dinc, dlen, end = 3, j, true
 				break
 			}
 			dbuf[j] = enc.decodeMap[in]
 			if dbuf[j] == 0xFF {
-				return n, false, CorruptInputError(olen - len(src) - 1)
+				return n, false, CorruptInputError(si - 1)
 			}
 		}
 
-		// Pack 4x 6-bit source blocks into 3 byte destination
-		// quantum
+		// Convert 4x 6bit source bytes into 3 bytes
+		val := uint(dbuf[0])<<18 | uint(dbuf[1])<<12 | uint(dbuf[2])<<6 | uint(dbuf[3])
 		switch dlen {
 		case 4:
-			dst[2] = dbuf[2]<<6 | dbuf[3]
+			dst[2] = byte(val >> 0)
 			fallthrough
 		case 3:
-			dst[1] = dbuf[1]<<4 | dbuf[2]>>2
+			dst[1] = byte(val >> 8)
 			fallthrough
 		case 2:
-			dst[0] = dbuf[0]<<2 | dbuf[1]>>4
+			dst[0] = byte(val >> 16)
 		}
-		dst = dst[3:]
+		dst = dst[dinc:]
 		n += dlen - 1
 	}
 
@@ -284,14 +334,12 @@
 // number of bytes successfully written and CorruptInputError.
 // New line characters (\r and \n) are ignored.
 func (enc *Encoding) Decode(dst, src []byte) (n int, err error) {
-	src = bytes.Map(removeNewlinesMapper, src)
 	n, _, err = enc.decode(dst, src)
 	return
 }
 
 // DecodeString returns the bytes represented by the base64 string s.
 func (enc *Encoding) DecodeString(s string) ([]byte, error) {
-	s = strings.Map(removeNewlinesMapper, s)
 	dbuf := make([]byte, enc.DecodedLen(len(s)))
 	n, _, err := enc.decode(dbuf, []byte(s))
 	return dbuf[:n], err
@@ -320,6 +368,8 @@
 		return n, nil
 	}
 
+	// This code assumes that d.r strips supported whitespace ('\r' and '\n').
+
 	// Read a chunk.
 	nn := len(p) / 3 * 4
 	if nn < 4 {
@@ -338,12 +388,12 @@
 	nr := d.nbuf / 4 * 4
 	nw := d.nbuf / 4 * 3
 	if nw > len(p) {
-		nw, d.end, d.err = d.enc.decode(d.outbuf[0:], d.buf[0:nr])
-		d.out = d.outbuf[0:nw]
+		nw, d.end, d.err = d.enc.decode(d.outbuf[:], d.buf[:nr])
+		d.out = d.outbuf[:nw]
 		n = copy(p, d.out)
 		d.out = d.out[n:]
 	} else {
-		n, d.end, d.err = d.enc.decode(p, d.buf[0:nr])
+		n, d.end, d.err = d.enc.decode(p, d.buf[:nr])
 	}
 	d.nbuf -= nr
 	for i := 0; i < d.nbuf; i++ {
@@ -364,7 +414,7 @@
 	n, err := r.wrapped.Read(p)
 	for n > 0 {
 		offset := 0
-		for i, b := range p[0:n] {
+		for i, b := range p[:n] {
 			if b != '\r' && b != '\n' {
 				if i != offset {
 					p[offset] = b
@@ -388,4 +438,11 @@
 
 // DecodedLen returns the maximum length in bytes of the decoded data
 // corresponding to n bytes of base64-encoded data.
-func (enc *Encoding) DecodedLen(n int) int { return n / 4 * 3 }
+func (enc *Encoding) DecodedLen(n int) int {
+	if enc.padChar == NoPadding {
+		// Unpadded data may end with partial block of 2-3 characters.
+		return (n*6 + 7) / 8
+	}
+	// Padded base64 should always be a multiple of 4 characters in length.
+	return n / 4 * 3
+}
diff --git a/third_party/gofrontend/libgo/go/encoding/base64/base64_test.go b/third_party/gofrontend/libgo/go/encoding/base64/base64_test.go
index 7d199bf..d144b96 100644
--- a/third_party/gofrontend/libgo/go/encoding/base64/base64_test.go
+++ b/third_party/gofrontend/libgo/go/encoding/base64/base64_test.go
@@ -45,6 +45,48 @@
 	{"sure.", "c3VyZS4="},
 }
 
+// Do nothing to a reference base64 string (leave in standard format)
+func stdRef(ref string) string {
+	return ref
+}
+
+// Convert a reference string to URL-encoding
+func urlRef(ref string) string {
+	ref = strings.Replace(ref, "+", "-", -1)
+	ref = strings.Replace(ref, "/", "_", -1)
+	return ref
+}
+
+// Convert a reference string to raw, unpadded format
+func rawRef(ref string) string {
+	return strings.TrimRight(ref, "=")
+}
+
+// Both URL and unpadding conversions
+func rawUrlRef(ref string) string {
+	return rawRef(urlRef(ref))
+}
+
+// A nonstandard encoding with a funny padding character, for testing
+var funnyEncoding = NewEncoding(encodeStd).WithPadding(rune('@'))
+
+func funnyRef(ref string) string {
+	return strings.Replace(ref, "=", "@", -1)
+}
+
+type encodingTest struct {
+	enc  *Encoding           // Encoding to test
+	conv func(string) string // Reference string converter
+}
+
+var encodingTests = []encodingTest{
+	encodingTest{StdEncoding, stdRef},
+	encodingTest{URLEncoding, urlRef},
+	encodingTest{RawStdEncoding, rawRef},
+	encodingTest{RawURLEncoding, rawUrlRef},
+	encodingTest{funnyEncoding, funnyRef},
+}
+
 var bigtest = testpair{
 	"Twas brillig, and the slithy toves",
 	"VHdhcyBicmlsbGlnLCBhbmQgdGhlIHNsaXRoeSB0b3Zlcw==",
@@ -60,8 +102,11 @@
 
 func TestEncode(t *testing.T) {
 	for _, p := range pairs {
-		got := StdEncoding.EncodeToString([]byte(p.decoded))
-		testEqual(t, "Encode(%q) = %q, want %q", p.decoded, got, p.encoded)
+		for _, tt := range encodingTests {
+			got := tt.enc.EncodeToString([]byte(p.decoded))
+			testEqual(t, "Encode(%q) = %q, want %q", p.decoded,
+				got, tt.conv(p.encoded))
+		}
 	}
 }
 
@@ -97,18 +142,21 @@
 
 func TestDecode(t *testing.T) {
 	for _, p := range pairs {
-		dbuf := make([]byte, StdEncoding.DecodedLen(len(p.encoded)))
-		count, end, err := StdEncoding.decode(dbuf, []byte(p.encoded))
-		testEqual(t, "Decode(%q) = error %v, want %v", p.encoded, err, error(nil))
-		testEqual(t, "Decode(%q) = length %v, want %v", p.encoded, count, len(p.decoded))
-		if len(p.encoded) > 0 {
-			testEqual(t, "Decode(%q) = end %v, want %v", p.encoded, end, (p.encoded[len(p.encoded)-1] == '='))
-		}
-		testEqual(t, "Decode(%q) = %q, want %q", p.encoded, string(dbuf[0:count]), p.decoded)
+		for _, tt := range encodingTests {
+			encoded := tt.conv(p.encoded)
+			dbuf := make([]byte, tt.enc.DecodedLen(len(encoded)))
+			count, end, err := tt.enc.decode(dbuf, []byte(encoded))
+			testEqual(t, "Decode(%q) = error %v, want %v", encoded, err, error(nil))
+			testEqual(t, "Decode(%q) = length %v, want %v", encoded, count, len(p.decoded))
+			if len(encoded) > 0 {
+				testEqual(t, "Decode(%q) = end %v, want %v", encoded, end, len(p.decoded)%3 != 0)
+			}
+			testEqual(t, "Decode(%q) = %q, want %q", encoded, string(dbuf[0:count]), p.decoded)
 
-		dbuf, err = StdEncoding.DecodeString(p.encoded)
-		testEqual(t, "DecodeString(%q) = error %v, want %v", p.encoded, err, error(nil))
-		testEqual(t, "DecodeString(%q) = %q, want %q", string(dbuf), p.decoded)
+			dbuf, err = tt.enc.DecodeString(encoded)
+			testEqual(t, "DecodeString(%q) = error %v, want %v", encoded, err, error(nil))
+			testEqual(t, "DecodeString(%q) = %q, want %q", string(dbuf), p.decoded)
+		}
 	}
 }
 
diff --git a/third_party/gofrontend/libgo/go/encoding/binary/binary.go b/third_party/gofrontend/libgo/go/encoding/binary/binary.go
index 466bf97..2bbe07c 100644
--- a/third_party/gofrontend/libgo/go/encoding/binary/binary.go
+++ b/third_party/gofrontend/libgo/go/encoding/binary/binary.go
@@ -13,7 +13,7 @@
 // The varint functions encode and decode single integer values using
 // a variable-length encoding; smaller values require fewer bytes.
 // For a specification, see
-// http://code.google.com/apis/protocolbuffers/docs/encoding.html.
+// https://developers.google.com/protocol-buffers/docs/encoding.
 //
 // This package favors simplicity over efficiency. Clients that require
 // high-performance serialization, especially for large data structures,
@@ -239,78 +239,62 @@
 		}
 		switch v := data.(type) {
 		case *int8:
-			bs = b[:1]
 			b[0] = byte(*v)
 		case int8:
-			bs = b[:1]
 			b[0] = byte(v)
 		case []int8:
 			for i, x := range v {
 				bs[i] = byte(x)
 			}
 		case *uint8:
-			bs = b[:1]
 			b[0] = *v
 		case uint8:
-			bs = b[:1]
 			b[0] = byte(v)
 		case []uint8:
 			bs = v
 		case *int16:
-			bs = b[:2]
 			order.PutUint16(bs, uint16(*v))
 		case int16:
-			bs = b[:2]
 			order.PutUint16(bs, uint16(v))
 		case []int16:
 			for i, x := range v {
 				order.PutUint16(bs[2*i:], uint16(x))
 			}
 		case *uint16:
-			bs = b[:2]
 			order.PutUint16(bs, *v)
 		case uint16:
-			bs = b[:2]
 			order.PutUint16(bs, v)
 		case []uint16:
 			for i, x := range v {
 				order.PutUint16(bs[2*i:], x)
 			}
 		case *int32:
-			bs = b[:4]
 			order.PutUint32(bs, uint32(*v))
 		case int32:
-			bs = b[:4]
 			order.PutUint32(bs, uint32(v))
 		case []int32:
 			for i, x := range v {
 				order.PutUint32(bs[4*i:], uint32(x))
 			}
 		case *uint32:
-			bs = b[:4]
 			order.PutUint32(bs, *v)
 		case uint32:
-			bs = b[:4]
 			order.PutUint32(bs, v)
 		case []uint32:
 			for i, x := range v {
 				order.PutUint32(bs[4*i:], x)
 			}
 		case *int64:
-			bs = b[:8]
 			order.PutUint64(bs, uint64(*v))
 		case int64:
-			bs = b[:8]
 			order.PutUint64(bs, uint64(v))
 		case []int64:
 			for i, x := range v {
 				order.PutUint64(bs[8*i:], uint64(x))
 			}
 		case *uint64:
-			bs = b[:8]
 			order.PutUint64(bs, *v)
 		case uint64:
-			bs = b[:8]
 			order.PutUint64(bs, v)
 		case []uint64:
 			for i, x := range v {
@@ -605,25 +589,25 @@
 // It returns zero if the type cannot be implemented by the fast path in Read or Write.
 func intDataSize(data interface{}) int {
 	switch data := data.(type) {
-	case int8, *int8, *uint8:
+	case int8, uint8, *int8, *uint8:
 		return 1
 	case []int8:
 		return len(data)
 	case []uint8:
 		return len(data)
-	case int16, *int16, *uint16:
+	case int16, uint16, *int16, *uint16:
 		return 2
 	case []int16:
 		return 2 * len(data)
 	case []uint16:
 		return 2 * len(data)
-	case int32, *int32, *uint32:
+	case int32, uint32, *int32, *uint32:
 		return 4
 	case []int32:
 		return 4 * len(data)
 	case []uint32:
 		return 4 * len(data)
-	case int64, *int64, *uint64:
+	case int64, uint64, *int64, *uint64:
 		return 8
 	case []int64:
 		return 8 * len(data)
diff --git a/third_party/gofrontend/libgo/go/encoding/csv/example_test.go b/third_party/gofrontend/libgo/go/encoding/csv/example_test.go
new file mode 100644
index 0000000..e3c3bd5
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/encoding/csv/example_test.go
@@ -0,0 +1,133 @@
+// 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 ignore
+
+package csv_test
+
+import (
+	"encoding/csv"
+	"fmt"
+	"io"
+	"log"
+	"os"
+	"strings"
+)
+
+func ExampleReader() {
+	in := `first_name,last_name,username
+"Rob","Pike",rob
+Ken,Thompson,ken
+"Robert","Griesemer","gri"
+`
+	r := csv.NewReader(strings.NewReader(in))
+
+	for {
+		record, err := r.Read()
+		if err == io.EOF {
+			break
+		}
+		if err != nil {
+			log.Fatal(err)
+		}
+
+		fmt.Println(record)
+	}
+	// Output:
+	// [first_name last_name username]
+	// [Rob Pike rob]
+	// [Ken Thompson ken]
+	// [Robert Griesemer gri]
+}
+
+// This example shows how csv.Reader can be configured to handle other
+// types of CSV files.
+func ExampleReader_options() {
+	in := `first_name;last_name;username
+"Rob";"Pike";rob
+# lines beginning with a # character are ignored
+Ken;Thompson;ken
+"Robert";"Griesemer";"gri"
+`
+	r := csv.NewReader(strings.NewReader(in))
+	r.Comma = ';'
+	r.Comment = '#'
+
+	records, err := r.ReadAll()
+	if err != nil {
+		log.Fatal(err)
+	}
+
+	fmt.Print(records)
+	// Output:
+	// [[first_name last_name username] [Rob Pike rob] [Ken Thompson ken] [Robert Griesemer gri]]
+}
+
+func ExampleReader_ReadAll() {
+	in := `first_name,last_name,username
+"Rob","Pike",rob
+Ken,Thompson,ken
+"Robert","Griesemer","gri"
+`
+	r := csv.NewReader(strings.NewReader(in))
+
+	records, err := r.ReadAll()
+	if err != nil {
+		log.Fatal(err)
+	}
+
+	fmt.Print(records)
+	// Output:
+	// [[first_name last_name username] [Rob Pike rob] [Ken Thompson ken] [Robert Griesemer gri]]
+}
+
+func ExampleWriter() {
+	records := [][]string{
+		{"first_name", "last_name", "username"},
+		{"Rob", "Pike", "rob"},
+		{"Ken", "Thompson", "ken"},
+		{"Robert", "Griesemer", "gri"},
+	}
+
+	w := csv.NewWriter(os.Stdout)
+
+	for _, record := range records {
+		if err := w.Write(record); err != nil {
+			log.Fatalln("error writing record to csv:", err)
+		}
+	}
+
+	// Write any buffered data to the underlying writer (standard output).
+	w.Flush()
+
+	if err := w.Error(); err != nil {
+		log.Fatal(err)
+	}
+	// Output:
+	// first_name,last_name,username
+	// Rob,Pike,rob
+	// Ken,Thompson,ken
+	// Robert,Griesemer,gri
+}
+
+func ExampleWriter_WriteAll() {
+	records := [][]string{
+		{"first_name", "last_name", "username"},
+		{"Rob", "Pike", "rob"},
+		{"Ken", "Thompson", "ken"},
+		{"Robert", "Griesemer", "gri"},
+	}
+
+	w := csv.NewWriter(os.Stdout)
+	w.WriteAll(records) // calls Flush internally
+
+	if err := w.Error(); err != nil {
+		log.Fatalln("error writing csv:", err)
+	}
+	// Output:
+	// first_name,last_name,username
+	// Rob,Pike,rob
+	// Ken,Thompson,ken
+	// Robert,Griesemer,gri
+}
diff --git a/third_party/gofrontend/libgo/go/encoding/csv/reader.go b/third_party/gofrontend/libgo/go/encoding/csv/reader.go
index d943295..37bf80c 100644
--- a/third_party/gofrontend/libgo/go/encoding/csv/reader.go
+++ b/third_party/gofrontend/libgo/go/encoding/csv/reader.go
@@ -215,7 +215,7 @@
 	r.column = -1
 
 	// Peek at the first rune.  If it is an error we are done.
-	// If we are support comments and it is the comment character
+	// If we support comments and it is the comment character
 	// then skip to the end of line.
 
 	r1, _, err := r.r.ReadRune()
@@ -232,6 +232,11 @@
 	for {
 		haveField, delim, err := r.parseField()
 		if haveField {
+			// If FieldsPerRecord is greater then 0 we can assume the final
+			// length of fields to be equal to FieldsPerRecord.
+			if r.FieldsPerRecord > 0 && fields == nil {
+				fields = make([]string, 0, r.FieldsPerRecord)
+			}
 			fields = append(fields, r.field.String())
 		}
 		if delim == '\n' || err == io.EOF {
diff --git a/third_party/gofrontend/libgo/go/encoding/csv/reader_test.go b/third_party/gofrontend/libgo/go/encoding/csv/reader_test.go
index 123df06..be1002d 100644
--- a/third_party/gofrontend/libgo/go/encoding/csv/reader_test.go
+++ b/third_party/gofrontend/libgo/go/encoding/csv/reader_test.go
@@ -87,6 +87,15 @@
 		},
 	},
 	{
+		Name:               "BlankLineFieldCount",
+		Input:              "a,b,c\n\nd,e,f\n\n",
+		UseFieldsPerRecord: true,
+		Output: [][]string{
+			{"a", "b", "c"},
+			{"d", "e", "f"},
+		},
+	},
+	{
 		Name:             "TrimSpace",
 		Input:            " a,  b,   c\n",
 		TrimLeadingSpace: true,
@@ -282,3 +291,25 @@
 		}
 	}
 }
+
+func BenchmarkRead(b *testing.B) {
+	data := `x,y,z,w
+x,y,z,
+x,y,,
+x,,,
+,,,
+"x","y","z","w"
+"x","y","z",""
+"x","y","",""
+"x","","",""
+"","","",""
+`
+
+	for i := 0; i < b.N; i++ {
+		_, err := NewReader(strings.NewReader(data)).ReadAll()
+
+		if err != nil {
+			b.Fatalf("could not read data: %s", err)
+		}
+	}
+}
diff --git a/third_party/gofrontend/libgo/go/encoding/csv/writer.go b/third_party/gofrontend/libgo/go/encoding/csv/writer.go
index 17e7bb7..353d91f 100644
--- a/third_party/gofrontend/libgo/go/encoding/csv/writer.go
+++ b/third_party/gofrontend/libgo/go/encoding/csv/writer.go
@@ -114,7 +114,7 @@
 	return w.w.Flush()
 }
 
-// fieldNeedsQuotes returns true if our field must be enclosed in quotes.
+// fieldNeedsQuotes reports whether our field must be enclosed in quotes.
 // Fields with a Comma, fields with a quote or newline, and
 // fields which start with a space must be enclosed in quotes.
 // We used to quote empty strings, but we do not anymore (as of Go 1.4).
@@ -125,7 +125,7 @@
 // CSV with quoted empty strings strictly less useful.
 // Not quoting the empty string also makes this package match the behavior
 // of Microsoft Excel and Google Drive.
-// For Postgres, quote the data termating string `\.`.
+// For Postgres, quote the data terminating string `\.`.
 func (w *Writer) fieldNeedsQuotes(field string) bool {
 	if field == "" {
 		return false
diff --git a/third_party/gofrontend/libgo/go/encoding/gob/codec_test.go b/third_party/gofrontend/libgo/go/encoding/gob/codec_test.go
index 56a7298..c2583bf 100644
--- a/third_party/gofrontend/libgo/go/encoding/gob/codec_test.go
+++ b/third_party/gofrontend/libgo/go/encoding/gob/codec_test.go
@@ -1473,3 +1473,22 @@
 		}
 	}
 }
+
+// Don't crash, just give error with invalid type id.
+// Issue 9649.
+func TestErrorInvalidTypeId(t *testing.T) {
+	data := []byte{0x01, 0x00, 0x01, 0x00}
+	d := NewDecoder(bytes.NewReader(data))
+	// When running d.Decode(&foo) the first time the decoder stops
+	// after []byte{0x01, 0x00} and reports an errBadType. Running
+	// d.Decode(&foo) again on exactly the same input sequence should
+	// give another errBadType, but instead caused a panic because
+	// decoderMap wasn't cleaned up properly after the first error.
+	for i := 0; i < 2; i++ {
+		var foo struct{}
+		err := d.Decode(&foo)
+		if err != errBadType {
+			t.Fatal("decode: expected %s, got %s", errBadType, err)
+		}
+	}
+}
diff --git a/third_party/gofrontend/libgo/go/encoding/gob/decode.go b/third_party/gofrontend/libgo/go/encoding/gob/decode.go
index a5bef93..e913f15 100644
--- a/third_party/gofrontend/libgo/go/encoding/gob/decode.go
+++ b/third_party/gofrontend/libgo/go/encoding/gob/decode.go
@@ -182,6 +182,17 @@
 	return int64(x >> 1)
 }
 
+// getLength decodes the next uint and makes sure it is a possible
+// size for a data item that follows, which means it must fit in a
+// non-negative int and fit in the buffer.
+func (state *decoderState) getLength() (int, bool) {
+	n := int(state.decodeUint())
+	if n < 0 || state.b.Len() < n || tooBig <= n {
+		return 0, false
+	}
+	return n, true
+}
+
 // decOp is the signature of a decoding operator for a given type.
 type decOp func(i *decInstr, state *decoderState, v reflect.Value)
 
@@ -363,16 +374,9 @@
 // describing the data.
 // uint8 slices are encoded as an unsigned count followed by the raw bytes.
 func decUint8Slice(i *decInstr, state *decoderState, value reflect.Value) {
-	u := state.decodeUint()
-	n := int(u)
-	if n < 0 || uint64(n) != u {
-		errorf("length of %s exceeds input size (%d bytes)", value.Type(), u)
-	}
-	if n > state.b.Len() {
-		errorf("%s data too long for buffer: %d", value.Type(), n)
-	}
-	if n > tooBig {
-		errorf("byte slice too big: %d", n)
+	n, ok := state.getLength()
+	if !ok {
+		errorf("bad %s slice length: %d", value.Type(), n)
 	}
 	if value.Cap() < n {
 		value.Set(reflect.MakeSlice(value.Type(), n, n))
@@ -388,13 +392,9 @@
 // describing the data.
 // Strings are encoded as an unsigned count followed by the raw bytes.
 func decString(i *decInstr, state *decoderState, value reflect.Value) {
-	u := state.decodeUint()
-	n := int(u)
-	if n < 0 || uint64(n) != u || n > state.b.Len() {
-		errorf("length of %s exceeds input size (%d bytes)", value.Type(), u)
-	}
-	if n > state.b.Len() {
-		errorf("%s data too long for buffer: %d", value.Type(), n)
+	n, ok := state.getLength()
+	if !ok {
+		errorf("bad %s slice length: %d", value.Type(), n)
 	}
 	// Read the data.
 	data := make([]byte, n)
@@ -406,7 +406,11 @@
 
 // ignoreUint8Array skips over the data for a byte slice value with no destination.
 func ignoreUint8Array(i *decInstr, state *decoderState, value reflect.Value) {
-	b := make([]byte, state.decodeUint())
+	n, ok := state.getLength()
+	if !ok {
+		errorf("slice length too large")
+	}
+	b := make([]byte, n)
 	state.b.Read(b)
 }
 
@@ -571,6 +575,9 @@
 func (dec *Decoder) ignoreArrayHelper(state *decoderState, elemOp decOp, length int) {
 	instr := &decInstr{elemOp, 0, nil, errors.New("no error")}
 	for i := 0; i < length; i++ {
+		if state.b.Len() == 0 {
+			errorf("decoding array or slice: length exceeds input size (%d elements)", length)
+		}
 		elemOp(instr, state, noValue)
 	}
 }
@@ -678,7 +685,11 @@
 // ignoreInterface discards the data for an interface value with no destination.
 func (dec *Decoder) ignoreInterface(state *decoderState) {
 	// Read the name of the concrete type.
-	b := make([]byte, state.decodeUint())
+	n, ok := state.getLength()
+	if !ok {
+		errorf("bad interface encoding: name too large for buffer")
+	}
+	b := make([]byte, n)
 	_, err := state.b.Read(b)
 	if err != nil {
 		error_(err)
@@ -688,14 +699,22 @@
 		error_(dec.err)
 	}
 	// At this point, the decoder buffer contains a delimited value. Just toss it.
-	state.b.Drop(int(state.decodeUint()))
+	n, ok = state.getLength()
+	if !ok {
+		errorf("bad interface encoding: data length too large for buffer")
+	}
+	state.b.Drop(n)
 }
 
 // decodeGobDecoder decodes something implementing the GobDecoder interface.
 // The data is encoded as a byte slice.
 func (dec *Decoder) decodeGobDecoder(ut *userTypeInfo, state *decoderState, value reflect.Value) {
 	// Read the bytes for the value.
-	b := make([]byte, state.decodeUint())
+	n, ok := state.getLength()
+	if !ok {
+		errorf("GobDecoder: length too large for buffer")
+	}
+	b := make([]byte, n)
 	_, err := state.b.Read(b)
 	if err != nil {
 		error_(err)
@@ -717,7 +736,11 @@
 // ignoreGobDecoder discards the data for a GobDecoder value with no destination.
 func (dec *Decoder) ignoreGobDecoder(state *decoderState) {
 	// Read the bytes for the value.
-	b := make([]byte, state.decodeUint())
+	n, ok := state.getLength()
+	if !ok {
+		errorf("GobDecoder: length too large for buffer")
+	}
+	b := make([]byte, n)
 	_, err := state.b.Read(b)
 	if err != nil {
 		error_(err)
@@ -840,16 +863,22 @@
 }
 
 // decIgnoreOpFor returns the decoding op for a field that has no destination.
-func (dec *Decoder) decIgnoreOpFor(wireId typeId) decOp {
+func (dec *Decoder) decIgnoreOpFor(wireId typeId, inProgress map[typeId]*decOp) *decOp {
+	// If this type is already in progress, it's a recursive type (e.g. map[string]*T).
+	// Return the pointer to the op we're already building.
+	if opPtr := inProgress[wireId]; opPtr != nil {
+		return opPtr
+	}
 	op, ok := decIgnoreOpMap[wireId]
 	if !ok {
+		inProgress[wireId] = &op
 		if wireId == tInterface {
 			// Special case because it's a method: the ignored item might
 			// define types and we need to record their state in the decoder.
 			op = func(i *decInstr, state *decoderState, value reflect.Value) {
 				state.dec.ignoreInterface(state)
 			}
-			return op
+			return &op
 		}
 		// Special cases
 		wire := dec.wireType[wireId]
@@ -858,25 +887,25 @@
 			errorf("bad data: undefined type %s", wireId.string())
 		case wire.ArrayT != nil:
 			elemId := wire.ArrayT.Elem
-			elemOp := dec.decIgnoreOpFor(elemId)
+			elemOp := dec.decIgnoreOpFor(elemId, inProgress)
 			op = func(i *decInstr, state *decoderState, value reflect.Value) {
-				state.dec.ignoreArray(state, elemOp, wire.ArrayT.Len)
+				state.dec.ignoreArray(state, *elemOp, wire.ArrayT.Len)
 			}
 
 		case wire.MapT != nil:
 			keyId := dec.wireType[wireId].MapT.Key
 			elemId := dec.wireType[wireId].MapT.Elem
-			keyOp := dec.decIgnoreOpFor(keyId)
-			elemOp := dec.decIgnoreOpFor(elemId)
+			keyOp := dec.decIgnoreOpFor(keyId, inProgress)
+			elemOp := dec.decIgnoreOpFor(elemId, inProgress)
 			op = func(i *decInstr, state *decoderState, value reflect.Value) {
-				state.dec.ignoreMap(state, keyOp, elemOp)
+				state.dec.ignoreMap(state, *keyOp, *elemOp)
 			}
 
 		case wire.SliceT != nil:
 			elemId := wire.SliceT.Elem
-			elemOp := dec.decIgnoreOpFor(elemId)
+			elemOp := dec.decIgnoreOpFor(elemId, inProgress)
 			op = func(i *decInstr, state *decoderState, value reflect.Value) {
-				state.dec.ignoreSlice(state, elemOp)
+				state.dec.ignoreSlice(state, *elemOp)
 			}
 
 		case wire.StructT != nil:
@@ -899,7 +928,7 @@
 	if op == nil {
 		errorf("bad data: ignore can't handle type %s", wireId.string())
 	}
-	return op
+	return &op
 }
 
 // gobDecodeOpFor returns the op for a type that is known to implement
@@ -1033,9 +1062,9 @@
 func (dec *Decoder) compileIgnoreSingle(remoteId typeId) (engine *decEngine, err error) {
 	engine = new(decEngine)
 	engine.instr = make([]decInstr, 1) // one item
-	op := dec.decIgnoreOpFor(remoteId)
+	op := dec.decIgnoreOpFor(remoteId, make(map[typeId]*decOp))
 	ovfl := overflow(dec.typeString(remoteId))
-	engine.instr[0] = decInstr{op, 0, nil, ovfl}
+	engine.instr[0] = decInstr{*op, 0, nil, ovfl}
 	engine.numInstr = 1
 	return
 }
@@ -1043,6 +1072,7 @@
 // compileDec compiles the decoder engine for a value.  If the value is not a struct,
 // it calls out to compileSingle.
 func (dec *Decoder) compileDec(remoteId typeId, ut *userTypeInfo) (engine *decEngine, err error) {
+	defer catchError(&err)
 	rt := ut.base
 	srt := rt
 	if srt.Kind() != reflect.Struct || ut.externalDec != 0 {
@@ -1077,8 +1107,8 @@
 		localField, present := srt.FieldByName(wireField.Name)
 		// TODO(r): anonymous names
 		if !present || !isExported(wireField.Name) {
-			op := dec.decIgnoreOpFor(wireField.Id)
-			engine.instr[fieldnum] = decInstr{op, fieldnum, nil, ovfl}
+			op := dec.decIgnoreOpFor(wireField.Id, make(map[typeId]*decOp))
+			engine.instr[fieldnum] = decInstr{*op, fieldnum, nil, ovfl}
 			continue
 		}
 		if !dec.compatibleType(localField.Type, wireField.Id, make(map[reflect.Type]typeId)) {
@@ -1116,7 +1146,7 @@
 
 var emptyStructType = reflect.TypeOf(emptyStruct{})
 
-// getDecEnginePtr returns the engine for the specified type when the value is to be discarded.
+// getIgnoreEnginePtr returns the engine for the specified type when the value is to be discarded.
 func (dec *Decoder) getIgnoreEnginePtr(wireId typeId) (enginePtr **decEngine, err error) {
 	var ok bool
 	if enginePtr, ok = dec.ignorerCache[wireId]; !ok {
@@ -1155,8 +1185,9 @@
 	value = decAlloc(value)
 	engine := *enginePtr
 	if st := base; st.Kind() == reflect.Struct && ut.externalDec == 0 {
+		wt := dec.wireType[wireId]
 		if engine.numInstr == 0 && st.NumField() > 0 &&
-			dec.wireType[wireId] != nil && len(dec.wireType[wireId].StructT.Field) > 0 {
+			wt != nil && len(wt.StructT.Field) > 0 {
 			name := base.Name()
 			errorf("type mismatch: no fields matched compiling decoder for %s", name)
 		}
diff --git a/third_party/gofrontend/libgo/go/encoding/gob/doc.go b/third_party/gofrontend/libgo/go/encoding/gob/doc.go
index d0acaba..4d3d007 100644
--- a/third_party/gofrontend/libgo/go/encoding/gob/doc.go
+++ b/third_party/gofrontend/libgo/go/encoding/gob/doc.go
@@ -6,7 +6,7 @@
 Package gob manages streams of gobs - binary values exchanged between an
 Encoder (transmitter) and a Decoder (receiver).  A typical use is transporting
 arguments and results of remote procedure calls (RPCs) such as those provided by
-package "rpc".
+package "net/rpc".
 
 The implementation compiles a custom codec for each data type in the stream and
 is most efficient when a single Encoder is used to transmit a stream of values,
@@ -83,7 +83,7 @@
 elements decoded.
 
 Functions and channels will not be sent in a gob. Attempting to encode such a value
-at top the level will fail. A struct field of chan or func type is treated exactly
+at the top level will fail. A struct field of chan or func type is treated exactly
 like an unexported field and is ignored.
 
 Gob can encode a value of any type implementing the GobEncoder or
@@ -111,11 +111,11 @@
 upward contain the value; bit 0 says whether they should be complemented upon
 receipt.  The encode algorithm looks like this:
 
-	uint u;
+	var u uint
 	if i < 0 {
-		u = (^i << 1) | 1	// complement i, bit 0 is 1
+		u = (^uint(i) << 1) | 1 // complement i, bit 0 is 1
 	} else {
-		u = (i << 1)	// do not complement i, bit 0 is 0
+		u = (uint(i) << 1) // do not complement i, bit 0 is 0
 	}
 	encodeUnsigned(u)
 
@@ -137,9 +137,9 @@
 elements using the standard gob encoding for their type, recursively.
 
 Maps are sent as an unsigned count followed by that many key, element
-pairs. Empty but non-nil maps are sent, so if the sender has allocated
-a map, the receiver will allocate a map even if no elements are
-transmitted.
+pairs. Empty but non-nil maps are sent, so if the receiver has not allocated
+one already, one will always be allocated on receipt unless the transmitted map
+is nil and not at the top level.
 
 Structs are sent as a sequence of (field number, field value) pairs.  The field
 value is sent using the standard gob encoding for its type, recursively.  If a
@@ -246,7 +246,7 @@
 be predefined or be defined before the value in the stream.
 
 See "Gobs of data" for a design discussion of the gob wire format:
-http://golang.org/doc/articles/gobs_of_data.html
+https://blog.golang.org/gobs-of-data
 */
 package gob
 
diff --git a/third_party/gofrontend/libgo/go/encoding/gob/encoder.go b/third_party/gofrontend/libgo/go/encoding/gob/encoder.go
index a340e47..62d0f42 100644
--- a/third_party/gofrontend/libgo/go/encoding/gob/encoder.go
+++ b/third_party/gofrontend/libgo/go/encoding/gob/encoder.go
@@ -5,6 +5,7 @@
 package gob
 
 import (
+	"errors"
 	"io"
 	"reflect"
 	"sync"
@@ -65,6 +66,11 @@
 	// it by hand.
 	message := b.Bytes()
 	messageLen := len(message) - maxLength
+	// Length cannot be bigger than the decoder can handle.
+	if messageLen >= tooBig {
+		enc.setError(errors.New("gob: encoder: message too big"))
+		return
+	}
 	// Encode the length.
 	enc.countState.b.Reset()
 	enc.countState.encodeUint(uint64(messageLen))
diff --git a/third_party/gofrontend/libgo/go/encoding/gob/encoder_test.go b/third_party/gofrontend/libgo/go/encoding/gob/encoder_test.go
index 0ea4c0e..dc65734 100644
--- a/third_party/gofrontend/libgo/go/encoding/gob/encoder_test.go
+++ b/third_party/gofrontend/libgo/go/encoding/gob/encoder_test.go
@@ -6,8 +6,8 @@
 
 import (
 	"bytes"
+	"encoding/hex"
 	"fmt"
-	"io"
 	"reflect"
 	"strings"
 	"testing"
@@ -187,24 +187,6 @@
 	badTypeCheck(new(ET4), true, "different type of field", t)
 }
 
-func corruptDataCheck(s string, err error, t *testing.T) {
-	b := bytes.NewBufferString(s)
-	dec := NewDecoder(b)
-	err1 := dec.Decode(new(ET2))
-	if err1 != err {
-		t.Errorf("from %q expected error %s; got %s", s, err, err1)
-	}
-}
-
-// Check that we survive bad data.
-func TestBadData(t *testing.T) {
-	corruptDataCheck("", io.EOF, t)
-	corruptDataCheck("\x7Fhi", io.ErrUnexpectedEOF, t)
-	corruptDataCheck("\x03now is the time for all good men", errBadType, t)
-	// issue 6323.
-	corruptDataCheck("\x04\x24foo", errRange, t)
-}
-
 // Types not supported at top level by the Encoder.
 var unsupportedValues = []interface{}{
 	make(chan int),
@@ -545,6 +527,30 @@
 	}
 }
 
+func TestIgnoreRecursiveType(t *testing.T) {
+	// It's hard to build a self-contained test for this because
+	// we can't build compatible types in one package with
+	// different items so something is ignored. Here is
+	// some data that represents, according to debug.go:
+	// type definition {
+	//	slice "recursiveSlice" id=106
+	//		elem id=106
+	// }
+	data := []byte{
+		0x1d, 0xff, 0xd3, 0x02, 0x01, 0x01, 0x0e, 0x72,
+		0x65, 0x63, 0x75, 0x72, 0x73, 0x69, 0x76, 0x65,
+		0x53, 0x6c, 0x69, 0x63, 0x65, 0x01, 0xff, 0xd4,
+		0x00, 0x01, 0xff, 0xd4, 0x00, 0x00, 0x07, 0xff,
+		0xd4, 0x00, 0x02, 0x01, 0x00, 0x00,
+	}
+	dec := NewDecoder(bytes.NewReader(data))
+	// Issue 10415: This caused infinite recursion.
+	err := dec.Decode(nil)
+	if err != nil {
+		t.Fatal(err)
+	}
+}
+
 // Another bug from golang-nuts, involving nested interfaces.
 type Bug0Outer struct {
 	Bug0Field interface{}
@@ -951,6 +957,64 @@
 		t.Fatal("decode: no error")
 	}
 	if !strings.Contains(err.Error(), "slice too big") {
-		t.Fatal("decode: expected slice too big error, got %s", err.Error())
+		t.Fatalf("decode: expected slice too big error, got %s", err.Error())
+	}
+}
+
+type badDataTest struct {
+	input string      // The input encoded as a hex string.
+	error string      // A substring of the error that should result.
+	data  interface{} // What to decode into.
+}
+
+var badDataTests = []badDataTest{
+	{"", "EOF", nil},
+	{"7F6869", "unexpected EOF", nil},
+	{"036e6f77206973207468652074696d6520666f7220616c6c20676f6f64206d656e", "unknown type id", new(ET2)},
+	{"0424666f6f", "field numbers out of bounds", new(ET2)}, // Issue 6323.
+	{"05100028557b02027f8302", "interface encoding", nil},   // Issue 10270.
+	// Issue 10273.
+	{"130a00fb5dad0bf8ff020263e70002fa28020202a89859", "slice length too large", nil},
+	{"0f1000fb285d003316020735ff023a65c5", "interface encoding", nil},
+	{"03fffb0616fffc00f902ff02ff03bf005d02885802a311a8120228022c028ee7", "GobDecoder", nil},
+	// Issue 10491.
+	{"10fe010f020102fe01100001fe010e000016fe010d030102fe010e00010101015801fe01100000000bfe011000f85555555555555555", "length exceeds input size", nil},
+}
+
+// TestBadData tests that various problems caused by malformed input
+// are caught as errors and do not cause panics.
+func TestBadData(t *testing.T) {
+	for i, test := range badDataTests {
+		data, err := hex.DecodeString(test.input)
+		if err != nil {
+			t.Fatalf("#%d: hex error: %s", i, err)
+		}
+		d := NewDecoder(bytes.NewReader(data))
+		err = d.Decode(test.data)
+		if err == nil {
+			t.Errorf("decode: no error")
+			continue
+		}
+		if !strings.Contains(err.Error(), test.error) {
+			t.Errorf("#%d: decode: expected %q error, got %s", i, test.error, err.Error())
+		}
+	}
+}
+
+// TestHugeWriteFails tests that enormous messages trigger an error.
+func TestHugeWriteFails(t *testing.T) {
+	if testing.Short() {
+		// Requires allocating a monster, so don't do this from all.bash.
+		t.Skip("skipping huge allocation in short mode")
+	}
+	huge := make([]byte, tooBig)
+	huge[0] = 7 // Make sure it's not all zeros.
+	buf := new(bytes.Buffer)
+	err := NewEncoder(buf).Encode(huge)
+	if err == nil {
+		t.Fatalf("expected error for huge slice")
+	}
+	if !strings.Contains(err.Error(), "message too big") {
+		t.Fatalf("expected 'too big' error; got %s\n", err.Error())
 	}
 }
diff --git a/third_party/gofrontend/libgo/go/encoding/json/bench_test.go b/third_party/gofrontend/libgo/go/encoding/json/bench_test.go
index 29dbc26..ed89d11 100644
--- a/third_party/gofrontend/libgo/go/encoding/json/bench_test.go
+++ b/third_party/gofrontend/libgo/go/encoding/json/bench_test.go
@@ -15,6 +15,7 @@
 	"compress/gzip"
 	"io/ioutil"
 	"os"
+	"strings"
 	"testing"
 )
 
@@ -126,6 +127,28 @@
 	b.SetBytes(int64(len(codeJSON)))
 }
 
+func BenchmarkDecoderStream(b *testing.B) {
+	b.StopTimer()
+	var buf bytes.Buffer
+	dec := NewDecoder(&buf)
+	buf.WriteString(`"` + strings.Repeat("x", 1000000) + `"` + "\n\n\n")
+	var x interface{}
+	if err := dec.Decode(&x); err != nil {
+		b.Fatal("Decode:", err)
+	}
+	ones := strings.Repeat(" 1\n", 300000) + "\n\n\n"
+	b.StartTimer()
+	for i := 0; i < b.N; i++ {
+		if i%300000 == 0 {
+			buf.WriteString(ones)
+		}
+		x = nil
+		if err := dec.Decode(&x); err != nil || x != 1.0 {
+			b.Fatalf("Decode: %v after %d", err, i)
+		}
+	}
+}
+
 func BenchmarkCodeUnmarshal(b *testing.B) {
 	if codeJSON == nil {
 		b.StopTimer()
@@ -187,3 +210,14 @@
 		}
 	}
 }
+
+func BenchmarkIssue10335(b *testing.B) {
+	b.ReportAllocs()
+	var s struct{}
+	j := []byte(`{"a":{ }}`)
+	for n := 0; n < b.N; n++ {
+		if err := Unmarshal(j, &s); err != nil {
+			b.Fatal(err)
+		}
+	}
+}
diff --git a/third_party/gofrontend/libgo/go/encoding/json/decode.go b/third_party/gofrontend/libgo/go/encoding/json/decode.go
index 705bc2e..530e852 100644
--- a/third_party/gofrontend/libgo/go/encoding/json/decode.go
+++ b/third_party/gofrontend/libgo/go/encoding/json/decode.go
@@ -48,6 +48,13 @@
 //	map[string]interface{}, for JSON objects
 //	nil for JSON null
 //
+// To unmarshal a JSON array into a slice, Unmarshal resets the slice to nil
+// and then appends each element to the slice.
+//
+// To unmarshal a JSON object into a map, Unmarshal replaces the map
+// with an empty map and then adds key-value pairs from the object to
+// the map.
+//
 // If a JSON value is not appropriate for a given target type,
 // or if a JSON number overflows the target type, Unmarshal
 // skips that field and completes the unmarshalling as best it can.
@@ -90,8 +97,9 @@
 // An UnmarshalTypeError describes a JSON value that was
 // not appropriate for a value of a specific Go type.
 type UnmarshalTypeError struct {
-	Value string       // description of JSON value - "bool", "array", "number -5"
-	Type  reflect.Type // type of Go value it could not be assigned to
+	Value  string       // description of JSON value - "bool", "array", "number -5"
+	Type   reflect.Type // type of Go value it could not be assigned to
+	Offset int64        // error occurred after reading Offset bytes
 }
 
 func (e *UnmarshalTypeError) Error() string {
@@ -377,7 +385,7 @@
 		return
 	}
 	if ut != nil {
-		d.saveError(&UnmarshalTypeError{"array", v.Type()})
+		d.saveError(&UnmarshalTypeError{"array", v.Type(), int64(d.off)})
 		d.off--
 		d.next()
 		return
@@ -396,7 +404,7 @@
 		// Otherwise it's invalid.
 		fallthrough
 	default:
-		d.saveError(&UnmarshalTypeError{"array", v.Type()})
+		d.saveError(&UnmarshalTypeError{"array", v.Type(), int64(d.off)})
 		d.off--
 		d.next()
 		return
@@ -485,7 +493,7 @@
 		return
 	}
 	if ut != nil {
-		d.saveError(&UnmarshalTypeError{"object", v.Type()})
+		d.saveError(&UnmarshalTypeError{"object", v.Type(), int64(d.off)})
 		d.off--
 		d.next() // skip over { } in input
 		return
@@ -504,7 +512,7 @@
 		// map must have string kind
 		t := v.Type()
 		if t.Key().Kind() != reflect.String {
-			d.saveError(&UnmarshalTypeError{"object", v.Type()})
+			d.saveError(&UnmarshalTypeError{"object", v.Type(), int64(d.off)})
 			d.off--
 			d.next() // skip over { } in input
 			return
@@ -515,7 +523,7 @@
 	case reflect.Struct:
 
 	default:
-		d.saveError(&UnmarshalTypeError{"object", v.Type()})
+		d.saveError(&UnmarshalTypeError{"object", v.Type(), int64(d.off)})
 		d.off--
 		d.next() // skip over { } in input
 		return
@@ -599,7 +607,7 @@
 			case string:
 				d.literalStore([]byte(qv), subv, true)
 			default:
-				d.saveError(fmt.Errorf("json: invalid use of ,string struct tag, trying to unmarshal unquoted value into %v", item, v.Type()))
+				d.saveError(fmt.Errorf("json: invalid use of ,string struct tag, trying to unmarshal unquoted value into %v", subv.Type()))
 			}
 		} else {
 			d.value(subv)
@@ -646,7 +654,7 @@
 	}
 	f, err := strconv.ParseFloat(s, 64)
 	if err != nil {
-		return nil, &UnmarshalTypeError{"number " + s, reflect.TypeOf(0.0)}
+		return nil, &UnmarshalTypeError{"number " + s, reflect.TypeOf(0.0), int64(d.off)}
 	}
 	return f, nil
 }
@@ -679,8 +687,9 @@
 			if fromQuoted {
 				d.saveError(fmt.Errorf("json: invalid use of ,string struct tag, trying to unmarshal %q into %v", item, v.Type()))
 			} else {
-				d.saveError(&UnmarshalTypeError{"string", v.Type()})
+				d.saveError(&UnmarshalTypeError{"string", v.Type(), int64(d.off)})
 			}
+			return
 		}
 		s, ok := unquoteBytes(item)
 		if !ok {
@@ -713,7 +722,7 @@
 			if fromQuoted {
 				d.saveError(fmt.Errorf("json: invalid use of ,string struct tag, trying to unmarshal %q into %v", item, v.Type()))
 			} else {
-				d.saveError(&UnmarshalTypeError{"bool", v.Type()})
+				d.saveError(&UnmarshalTypeError{"bool", v.Type(), int64(d.off)})
 			}
 		case reflect.Bool:
 			v.SetBool(value)
@@ -721,7 +730,7 @@
 			if v.NumMethod() == 0 {
 				v.Set(reflect.ValueOf(value))
 			} else {
-				d.saveError(&UnmarshalTypeError{"bool", v.Type()})
+				d.saveError(&UnmarshalTypeError{"bool", v.Type(), int64(d.off)})
 			}
 		}
 
@@ -736,10 +745,10 @@
 		}
 		switch v.Kind() {
 		default:
-			d.saveError(&UnmarshalTypeError{"string", v.Type()})
+			d.saveError(&UnmarshalTypeError{"string", v.Type(), int64(d.off)})
 		case reflect.Slice:
-			if v.Type() != byteSliceType {
-				d.saveError(&UnmarshalTypeError{"string", v.Type()})
+			if v.Type().Elem().Kind() != reflect.Uint8 {
+				d.saveError(&UnmarshalTypeError{"string", v.Type(), int64(d.off)})
 				break
 			}
 			b := make([]byte, base64.StdEncoding.DecodedLen(len(s)))
@@ -755,7 +764,7 @@
 			if v.NumMethod() == 0 {
 				v.Set(reflect.ValueOf(string(s)))
 			} else {
-				d.saveError(&UnmarshalTypeError{"string", v.Type()})
+				d.saveError(&UnmarshalTypeError{"string", v.Type(), int64(d.off)})
 			}
 		}
 
@@ -777,7 +786,7 @@
 			if fromQuoted {
 				d.error(fmt.Errorf("json: invalid use of ,string struct tag, trying to unmarshal %q into %v", item, v.Type()))
 			} else {
-				d.error(&UnmarshalTypeError{"number", v.Type()})
+				d.error(&UnmarshalTypeError{"number", v.Type(), int64(d.off)})
 			}
 		case reflect.Interface:
 			n, err := d.convertNumber(s)
@@ -786,7 +795,7 @@
 				break
 			}
 			if v.NumMethod() != 0 {
-				d.saveError(&UnmarshalTypeError{"number", v.Type()})
+				d.saveError(&UnmarshalTypeError{"number", v.Type(), int64(d.off)})
 				break
 			}
 			v.Set(reflect.ValueOf(n))
@@ -794,7 +803,7 @@
 		case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
 			n, err := strconv.ParseInt(s, 10, 64)
 			if err != nil || v.OverflowInt(n) {
-				d.saveError(&UnmarshalTypeError{"number " + s, v.Type()})
+				d.saveError(&UnmarshalTypeError{"number " + s, v.Type(), int64(d.off)})
 				break
 			}
 			v.SetInt(n)
@@ -802,7 +811,7 @@
 		case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
 			n, err := strconv.ParseUint(s, 10, 64)
 			if err != nil || v.OverflowUint(n) {
-				d.saveError(&UnmarshalTypeError{"number " + s, v.Type()})
+				d.saveError(&UnmarshalTypeError{"number " + s, v.Type(), int64(d.off)})
 				break
 			}
 			v.SetUint(n)
@@ -810,7 +819,7 @@
 		case reflect.Float32, reflect.Float64:
 			n, err := strconv.ParseFloat(s, v.Type().Bits())
 			if err != nil || v.OverflowFloat(n) {
-				d.saveError(&UnmarshalTypeError{"number " + s, v.Type()})
+				d.saveError(&UnmarshalTypeError{"number " + s, v.Type(), int64(d.off)})
 				break
 			}
 			v.SetFloat(n)
diff --git a/third_party/gofrontend/libgo/go/encoding/json/decode_test.go b/third_party/gofrontend/libgo/go/encoding/json/decode_test.go
index 7235969..51b15ef 100644
--- a/third_party/gofrontend/libgo/go/encoding/json/decode_test.go
+++ b/third_party/gofrontend/libgo/go/encoding/json/decode_test.go
@@ -9,6 +9,7 @@
 	"encoding"
 	"fmt"
 	"image"
+	"net"
 	"reflect"
 	"strings"
 	"testing"
@@ -117,6 +118,7 @@
 	Loop
 	Embed0p // has Point with X, Y, used
 	Embed0q // has Point with Z, used
+	embed   // contains exported field
 }
 
 type Embed0 struct {
@@ -147,6 +149,10 @@
 	Point
 }
 
+type embed struct {
+	Q int
+}
+
 type Loop struct {
 	Loop1 int `json:",omitempty"`
 	Loop2 int `json:",omitempty"`
@@ -216,6 +222,9 @@
 	Z interface{}
 }
 
+func sliceAddr(x []int) *[]int                 { return &x }
+func mapAddr(x map[string]int) *map[string]int { return &x }
+
 var unmarshalTests = []unmarshalTest{
 	// basic types
 	{in: `true`, ptr: new(bool), out: true},
@@ -231,7 +240,7 @@
 	{in: `"g-clef: \uD834\uDD1E"`, ptr: new(string), out: "g-clef: \U0001D11E"},
 	{in: `"invalid: \uD834x\uDD1E"`, ptr: new(string), out: "invalid: \uFFFDx\uFFFD"},
 	{in: "null", ptr: new(interface{}), out: nil},
-	{in: `{"X": [1,2,3], "Y": 4}`, ptr: new(T), out: T{Y: 4}, err: &UnmarshalTypeError{"array", reflect.TypeOf("")}},
+	{in: `{"X": [1,2,3], "Y": 4}`, ptr: new(T), out: T{Y: 4}, err: &UnmarshalTypeError{"array", reflect.TypeOf(""), 7}},
 	{in: `{"x": 1}`, ptr: new(tx), out: tx{}},
 	{in: `{"F1":1,"F2":2,"F3":3}`, ptr: new(V), out: V{F1: float64(1), F2: int32(2), F3: Number("3")}},
 	{in: `{"F1":1,"F2":2,"F3":3}`, ptr: new(V), out: V{F1: Number("1"), F2: int32(2), F3: Number("3")}, useNumber: true},
@@ -302,6 +311,12 @@
 	{in: `["X"]`, ptr: &umslicepT, out: &umsliceT},
 	{in: `{"M":"X"}`, ptr: &umstructT, out: umstructT},
 
+	// Overwriting of data.
+	// This is different from package xml, but it's what we've always done.
+	// Now documented and tested.
+	{in: `[2]`, ptr: sliceAddr([]int{1}), out: []int{2}},
+	{in: `{"key": 2}`, ptr: mapAddr(map[string]int{"old": 0, "key": 1}), out: map[string]int{"key": 2}},
+
 	{
 		in: `{
 			"Level0": 1,
@@ -321,7 +336,8 @@
 			"Loop2": 14,
 			"X": 15,
 			"Y": 16,
-			"Z": 17
+			"Z": 17,
+			"Q": 18
 		}`,
 		ptr: new(Top),
 		out: Top{
@@ -351,6 +367,9 @@
 			Embed0q: Embed0q{
 				Point: Point{Z: 17},
 			},
+			embed: embed{
+				Q: 18,
+			},
 		},
 	},
 	{
@@ -411,7 +430,7 @@
 	{
 		in:  `{"2009-11-10T23:00:00Z": "hello world"}`,
 		ptr: &map[time.Time]string{},
-		err: &UnmarshalTypeError{"object", reflect.TypeOf(map[time.Time]string{})},
+		err: &UnmarshalTypeError{"object", reflect.TypeOf(map[time.Time]string{}), 1},
 	},
 }
 
@@ -497,12 +516,15 @@
 		Embed0q: Embed0q{
 			Point: Point{Z: 17},
 		},
+		embed: embed{
+			Q: 18,
+		},
 	}
 	b, err := Marshal(top)
 	if err != nil {
 		t.Fatal(err)
 	}
-	want := "{\"Level0\":1,\"Level1b\":2,\"Level1c\":3,\"Level1a\":5,\"LEVEL1B\":6,\"e\":{\"Level1a\":8,\"Level1b\":9,\"Level1c\":10,\"Level1d\":11,\"x\":12},\"Loop1\":13,\"Loop2\":14,\"X\":15,\"Y\":16,\"Z\":17}"
+	want := "{\"Level0\":1,\"Level1b\":2,\"Level1c\":3,\"Level1a\":5,\"LEVEL1B\":6,\"e\":{\"Level1a\":8,\"Level1b\":9,\"Level1c\":10,\"Level1d\":11,\"x\":12},\"Loop1\":13,\"Loop2\":14,\"X\":15,\"Y\":16,\"Z\":17,\"Q\":18}"
 	if string(b) != want {
 		t.Errorf("Wrong marshal result.\n got: %q\nwant: %q", b, want)
 	}
@@ -688,6 +710,7 @@
 	{`{"result":"x"}`, `json: invalid use of ,string struct tag, trying to unmarshal "x" into string`},
 	{`{"result":"foo"}`, `json: invalid use of ,string struct tag, trying to unmarshal "foo" into string`},
 	{`{"result":"123"}`, `json: invalid use of ,string struct tag, trying to unmarshal "123" into string`},
+	{`{"result":123}`, `json: invalid use of ,string struct tag, trying to unmarshal unquoted value into string`},
 }
 
 // If people misuse the ,string modifier, the error message should be
@@ -1085,7 +1108,7 @@
 	*s.C = 2
 	err := Unmarshal(data, &s)
 	if err != nil {
-		t.Fatalf("Unmarshal: %v")
+		t.Fatalf("Unmarshal: %v", err)
 	}
 	if s.B != 1 || s.C != nil {
 		t.Fatalf("after Unmarshal, s.B=%d, s.C=%p, want 1, nil", s.B, s.C)
@@ -1206,7 +1229,28 @@
 	if !reflect.DeepEqual(m1, m2) {
 		t.Error("Items should be equal after encoding and then decoding")
 	}
+}
 
+// Custom types with []byte as underlying type could not be marshalled
+// and then unmarshalled.
+// Issue 8962.
+func TestByteKind(t *testing.T) {
+	type byteKind []byte
+
+	a := byteKind("hello")
+
+	data, err := Marshal(a)
+	if err != nil {
+		t.Error(err)
+	}
+	var b byteKind
+	err = Unmarshal(data, &b)
+	if err != nil {
+		t.Fatal(err)
+	}
+	if !reflect.DeepEqual(a, b) {
+		t.Errorf("expected %v == %v", a, b)
+	}
 }
 
 var decodeTypeErrorTests = []struct {
@@ -1371,3 +1415,51 @@
 		}
 	}
 }
+
+var invalidUnmarshalTextTests = []struct {
+	v    interface{}
+	want string
+}{
+	{nil, "json: Unmarshal(nil)"},
+	{struct{}{}, "json: Unmarshal(non-pointer struct {})"},
+	{(*int)(nil), "json: Unmarshal(nil *int)"},
+	{new(net.IP), "json: cannot unmarshal string into Go value of type *net.IP"},
+}
+
+func TestInvalidUnmarshalText(t *testing.T) {
+	buf := []byte(`123`)
+	for _, tt := range invalidUnmarshalTextTests {
+		err := Unmarshal(buf, tt.v)
+		if err == nil {
+			t.Errorf("Unmarshal expecting error, got nil")
+			continue
+		}
+		if got := err.Error(); got != tt.want {
+			t.Errorf("Unmarshal = %q; want %q", got, tt.want)
+		}
+	}
+}
+
+// Test that string option is ignored for invalid types.
+// Issue 9812.
+func TestInvalidStringOption(t *testing.T) {
+	num := 0
+	item := struct {
+		T time.Time         `json:",string"`
+		M map[string]string `json:",string"`
+		S []string          `json:",string"`
+		A [1]string         `json:",string"`
+		I interface{}       `json:",string"`
+		P *int              `json:",string"`
+	}{M: make(map[string]string), S: make([]string, 0), I: num, P: &num}
+
+	data, err := Marshal(item)
+	if err != nil {
+		t.Fatalf("Marshal: %v", err)
+	}
+
+	err = Unmarshal(data, &item)
+	if err != nil {
+		t.Fatalf("Unmarshal: %v", err)
+	}
+}
diff --git a/third_party/gofrontend/libgo/go/encoding/json/encode.go b/third_party/gofrontend/libgo/go/encoding/json/encode.go
index fca2a09..e829a93 100644
--- a/third_party/gofrontend/libgo/go/encoding/json/encode.go
+++ b/third_party/gofrontend/libgo/go/encoding/json/encode.go
@@ -7,7 +7,7 @@
 // in the documentation for the Marshal and Unmarshal functions.
 //
 // See "JSON and Go" for an introduction to this package:
-// http://golang.org/doc/articles/json_and_go.html
+// https://golang.org/doc/articles/json_and_go.html
 package json
 
 import (
@@ -79,8 +79,8 @@
 //
 // The "string" option signals that a field is stored as JSON inside a
 // JSON-encoded string. It applies only to fields of string, floating point,
-// or integer types. This extra level of encoding is sometimes used when
-// communicating with JavaScript programs:
+// integer, or boolean types. This extra level of encoding is sometimes used
+// when communicating with JavaScript programs:
 //
 //    Int64String int64 `json:",string"`
 //
@@ -113,8 +113,8 @@
 // a JSON tag of "-".
 //
 // Map values encode as JSON objects.
-// The map's key type must be string; the object keys are used directly
-// as map keys.
+// The map's key type must be string; the map keys are used as JSON object
+// keys, subject to the UTF-8 coercion described for string values above.
 //
 // Pointer values encode as the value pointed to.
 // A nil pointer encodes as the null JSON object.
@@ -275,8 +275,6 @@
 	panic(err)
 }
 
-var byteSliceType = reflect.TypeOf([]byte(nil))
-
 func isEmptyValue(v reflect.Value) bool {
 	switch v.Kind() {
 	case reflect.Array, reflect.Map, reflect.Slice, reflect.String:
@@ -1024,7 +1022,7 @@
 			// Scan f.typ for fields to include.
 			for i := 0; i < f.typ.NumField(); i++ {
 				sf := f.typ.Field(i)
-				if sf.PkgPath != "" { // unexported
+				if sf.PkgPath != "" && !sf.Anonymous { // unexported
 					continue
 				}
 				tag := sf.Tag.Get("json")
@@ -1045,6 +1043,19 @@
 					ft = ft.Elem()
 				}
 
+				// Only strings, floats, integers, and booleans can be quoted.
+				quoted := false
+				if opts.Contains("string") {
+					switch ft.Kind() {
+					case reflect.Bool,
+						reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64,
+						reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64,
+						reflect.Float32, reflect.Float64,
+						reflect.String:
+						quoted = true
+					}
+				}
+
 				// Record found field and index sequence.
 				if name != "" || !sf.Anonymous || ft.Kind() != reflect.Struct {
 					tagged := name != ""
@@ -1057,7 +1068,7 @@
 						index:     index,
 						typ:       ft,
 						omitEmpty: opts.Contains("omitempty"),
-						quoted:    opts.Contains("string"),
+						quoted:    quoted,
 					}))
 					if count[f.typ] > 1 {
 						// If there were multiple instances, add a second,
diff --git a/third_party/gofrontend/libgo/go/encoding/json/fold.go b/third_party/gofrontend/libgo/go/encoding/json/fold.go
index d6f77c9..9e17012 100644
--- a/third_party/gofrontend/libgo/go/encoding/json/fold.go
+++ b/third_party/gofrontend/libgo/go/encoding/json/fold.go
@@ -26,7 +26,7 @@
 // The letters S and K are special because they map to 3 runes, not just 2:
 //  * S maps to s and to U+017F 'ſ' Latin small letter long s
 //  * k maps to K and to U+212A 'K' Kelvin sign
-// See http://play.golang.org/p/tTxjOc0OGo
+// See https://play.golang.org/p/tTxjOc0OGo
 //
 // The returned function is specialized for matching against s and
 // should only be given s. It's not curried for performance reasons.
diff --git a/third_party/gofrontend/libgo/go/encoding/json/scanner.go b/third_party/gofrontend/libgo/go/encoding/json/scanner.go
index a4609c8..38d0b08 100644
--- a/third_party/gofrontend/libgo/go/encoding/json/scanner.go
+++ b/third_party/gofrontend/libgo/go/encoding/json/scanner.go
@@ -38,8 +38,15 @@
 	scan.reset()
 	for i, c := range data {
 		v := scan.step(scan, int(c))
-		if v >= scanEnd {
+		if v >= scanEndObject {
 			switch v {
+			// probe the scanner with a space to determine whether we will
+			// get scanEnd on the next character. Otherwise, if the next character
+			// is not a space, scanEndTop allocates a needless error.
+			case scanEndObject, scanEndArray:
+				if scan.step(scan, ' ') == scanEnd {
+					return data[:i+1], data[i+1:], nil
+				}
 			case scanError:
 				return nil, nil, scan.err
 			case scanEnd:
diff --git a/third_party/gofrontend/libgo/go/encoding/json/scanner_test.go b/third_party/gofrontend/libgo/go/encoding/json/scanner_test.go
index 7880342..66383ef 100644
--- a/third_party/gofrontend/libgo/go/encoding/json/scanner_test.go
+++ b/third_party/gofrontend/libgo/go/encoding/json/scanner_test.go
@@ -209,6 +209,7 @@
 
 func BenchmarkSkipValue(b *testing.B) {
 	initBig()
+	b.ResetTimer()
 	for i := 0; i < b.N; i++ {
 		nextValue(jsonBig, &benchScan)
 	}
diff --git a/third_party/gofrontend/libgo/go/encoding/json/stream.go b/third_party/gofrontend/libgo/go/encoding/json/stream.go
index 9566eca..dc53bce 100644
--- a/third_party/gofrontend/libgo/go/encoding/json/stream.go
+++ b/third_party/gofrontend/libgo/go/encoding/json/stream.go
@@ -12,11 +12,15 @@
 
 // A Decoder reads and decodes JSON objects from an input stream.
 type Decoder struct {
-	r    io.Reader
-	buf  []byte
-	d    decodeState
-	scan scanner
-	err  error
+	r     io.Reader
+	buf   []byte
+	d     decodeState
+	scanp int // start of unread data in buf
+	scan  scanner
+	err   error
+
+	tokenState int
+	tokenStack []int
 }
 
 // NewDecoder returns a new decoder that reads from r.
@@ -41,20 +45,29 @@
 		return dec.err
 	}
 
+	if err := dec.tokenPrepareForDecode(); err != nil {
+		return err
+	}
+
+	if !dec.tokenValueAllowed() {
+		return &SyntaxError{msg: "not at beginning of value"}
+	}
+
+	// Read whole value into buffer.
 	n, err := dec.readValue()
 	if err != nil {
 		return err
 	}
+	dec.d.init(dec.buf[dec.scanp : dec.scanp+n])
+	dec.scanp += n
 
 	// Don't save err from unmarshal into dec.err:
 	// the connection is still usable since we read a complete JSON
 	// object from it before the error happened.
-	dec.d.init(dec.buf[0:n])
 	err = dec.d.unmarshal(v)
 
-	// Slide rest of data down.
-	rest := copy(dec.buf, dec.buf[n:])
-	dec.buf = dec.buf[0:rest]
+	// fixup token streaming state
+	dec.tokenValueEnd()
 
 	return err
 }
@@ -62,7 +75,7 @@
 // Buffered returns a reader of the data remaining in the Decoder's
 // buffer. The reader is valid until the next call to Decode.
 func (dec *Decoder) Buffered() io.Reader {
-	return bytes.NewReader(dec.buf)
+	return bytes.NewReader(dec.buf[dec.scanp:])
 }
 
 // readValue reads a JSON value into dec.buf.
@@ -70,7 +83,7 @@
 func (dec *Decoder) readValue() (int, error) {
 	dec.scan.reset()
 
-	scanp := 0
+	scanp := dec.scanp
 	var err error
 Input:
 	for {
@@ -111,20 +124,35 @@
 			return 0, err
 		}
 
-		// Make room to read more into the buffer.
-		const minRead = 512
-		if cap(dec.buf)-len(dec.buf) < minRead {
-			newBuf := make([]byte, len(dec.buf), 2*cap(dec.buf)+minRead)
-			copy(newBuf, dec.buf)
-			dec.buf = newBuf
-		}
-
-		// Read.  Delay error for next iteration (after scan).
-		var n int
-		n, err = dec.r.Read(dec.buf[len(dec.buf):cap(dec.buf)])
-		dec.buf = dec.buf[0 : len(dec.buf)+n]
+		n := scanp - dec.scanp
+		err = dec.refill()
+		scanp = dec.scanp + n
 	}
-	return scanp, nil
+	return scanp - dec.scanp, nil
+}
+
+func (dec *Decoder) refill() error {
+	// Make room to read more into the buffer.
+	// First slide down data already consumed.
+	if dec.scanp > 0 {
+		n := copy(dec.buf, dec.buf[dec.scanp:])
+		dec.buf = dec.buf[:n]
+		dec.scanp = 0
+	}
+
+	// Grow buffer if not large enough.
+	const minRead = 512
+	if cap(dec.buf)-len(dec.buf) < minRead {
+		newBuf := make([]byte, len(dec.buf), 2*cap(dec.buf)+minRead)
+		copy(newBuf, dec.buf)
+		dec.buf = newBuf
+	}
+
+	// Read.  Delay error for next iteration (after scan).
+	n, err := dec.r.Read(dec.buf[len(dec.buf):cap(dec.buf)])
+	dec.buf = dec.buf[0 : len(dec.buf)+n]
+
+	return err
 }
 
 func nonSpace(b []byte) bool {
@@ -198,3 +226,255 @@
 
 var _ Marshaler = (*RawMessage)(nil)
 var _ Unmarshaler = (*RawMessage)(nil)
+
+// A Token holds a value of one of these types:
+//
+//	Delim, for the four JSON delimiters [ ] { }
+//	bool, for JSON booleans
+//	float64, for JSON numbers
+//	Number, for JSON numbers
+//	string, for JSON string literals
+//	nil, for JSON null
+//
+type Token interface{}
+
+const (
+	tokenTopValue = iota
+	tokenArrayStart
+	tokenArrayValue
+	tokenArrayComma
+	tokenObjectStart
+	tokenObjectKey
+	tokenObjectColon
+	tokenObjectValue
+	tokenObjectComma
+)
+
+// advance tokenstate from a separator state to a value state
+func (dec *Decoder) tokenPrepareForDecode() error {
+	// Note: Not calling peek before switch, to avoid
+	// putting peek into the standard Decode path.
+	// peek is only called when using the Token API.
+	switch dec.tokenState {
+	case tokenArrayComma:
+		c, err := dec.peek()
+		if err != nil {
+			return err
+		}
+		if c != ',' {
+			return &SyntaxError{"expected comma after array element", 0}
+		}
+		dec.scanp++
+		dec.tokenState = tokenArrayValue
+	case tokenObjectColon:
+		c, err := dec.peek()
+		if err != nil {
+			return err
+		}
+		if c != ':' {
+			return &SyntaxError{"expected colon after object key", 0}
+		}
+		dec.scanp++
+		dec.tokenState = tokenObjectValue
+	}
+	return nil
+}
+
+func (dec *Decoder) tokenValueAllowed() bool {
+	switch dec.tokenState {
+	case tokenTopValue, tokenArrayStart, tokenArrayValue, tokenObjectValue:
+		return true
+	}
+	return false
+}
+
+func (dec *Decoder) tokenValueEnd() {
+	switch dec.tokenState {
+	case tokenArrayStart, tokenArrayValue:
+		dec.tokenState = tokenArrayComma
+	case tokenObjectValue:
+		dec.tokenState = tokenObjectComma
+	}
+}
+
+// A Delim is a JSON array or object delimiter, one of [ ] { or }.
+type Delim rune
+
+func (d Delim) String() string {
+	return string(d)
+}
+
+// Token returns the next JSON token in the input stream.
+// At the end of the input stream, Token returns nil, io.EOF.
+//
+// Token guarantees that the delimiters [ ] { } it returns are
+// properly nested and matched: if Token encounters an unexpected
+// delimiter in the input, it will return an error.
+//
+// The input stream consists of basic JSON values—bool, string,
+// number, and null—along with delimiters [ ] { } of type Delim
+// to mark the start and end of arrays and objects.
+// Commas and colons are elided.
+func (dec *Decoder) Token() (Token, error) {
+	for {
+		c, err := dec.peek()
+		if err != nil {
+			return nil, err
+		}
+		switch c {
+		case '[':
+			if !dec.tokenValueAllowed() {
+				return dec.tokenError(c)
+			}
+			dec.scanp++
+			dec.tokenStack = append(dec.tokenStack, dec.tokenState)
+			dec.tokenState = tokenArrayStart
+			return Delim('['), nil
+
+		case ']':
+			if dec.tokenState != tokenArrayStart && dec.tokenState != tokenArrayComma {
+				return dec.tokenError(c)
+			}
+			dec.scanp++
+			dec.tokenState = dec.tokenStack[len(dec.tokenStack)-1]
+			dec.tokenStack = dec.tokenStack[:len(dec.tokenStack)-1]
+			dec.tokenValueEnd()
+			return Delim(']'), nil
+
+		case '{':
+			if !dec.tokenValueAllowed() {
+				return dec.tokenError(c)
+			}
+			dec.scanp++
+			dec.tokenStack = append(dec.tokenStack, dec.tokenState)
+			dec.tokenState = tokenObjectStart
+			return Delim('{'), nil
+
+		case '}':
+			if dec.tokenState != tokenObjectStart && dec.tokenState != tokenObjectComma {
+				return dec.tokenError(c)
+			}
+			dec.scanp++
+			dec.tokenState = dec.tokenStack[len(dec.tokenStack)-1]
+			dec.tokenStack = dec.tokenStack[:len(dec.tokenStack)-1]
+			dec.tokenValueEnd()
+			return Delim('}'), nil
+
+		case ':':
+			if dec.tokenState != tokenObjectColon {
+				return dec.tokenError(c)
+			}
+			dec.scanp++
+			dec.tokenState = tokenObjectValue
+			continue
+
+		case ',':
+			if dec.tokenState == tokenArrayComma {
+				dec.scanp++
+				dec.tokenState = tokenArrayValue
+				continue
+			}
+			if dec.tokenState == tokenObjectComma {
+				dec.scanp++
+				dec.tokenState = tokenObjectKey
+				continue
+			}
+			return dec.tokenError(c)
+
+		case '"':
+			if dec.tokenState == tokenObjectStart || dec.tokenState == tokenObjectKey {
+				var x string
+				old := dec.tokenState
+				dec.tokenState = tokenTopValue
+				err := dec.Decode(&x)
+				dec.tokenState = old
+				if err != nil {
+					clearOffset(err)
+					return nil, err
+				}
+				dec.tokenState = tokenObjectColon
+				return x, nil
+			}
+			fallthrough
+
+		default:
+			if !dec.tokenValueAllowed() {
+				return dec.tokenError(c)
+			}
+			var x interface{}
+			if err := dec.Decode(&x); err != nil {
+				clearOffset(err)
+				return nil, err
+			}
+			return x, nil
+		}
+	}
+}
+
+func clearOffset(err error) {
+	if s, ok := err.(*SyntaxError); ok {
+		s.Offset = 0
+	}
+}
+
+func (dec *Decoder) tokenError(c byte) (Token, error) {
+	var context string
+	switch dec.tokenState {
+	case tokenTopValue:
+		context = " looking for beginning of value"
+	case tokenArrayStart, tokenArrayValue, tokenObjectValue:
+		context = " looking for beginning of value"
+	case tokenArrayComma:
+		context = " after array element"
+	case tokenObjectKey:
+		context = " looking for beginning of object key string"
+	case tokenObjectColon:
+		context = " after object key"
+	case tokenObjectComma:
+		context = " after object key:value pair"
+	}
+	return nil, &SyntaxError{"invalid character " + quoteChar(int(c)) + " " + context, 0}
+}
+
+// More reports whether there is another element in the
+// current array or object being parsed.
+func (dec *Decoder) More() bool {
+	c, err := dec.peek()
+	return err == nil && c != ']' && c != '}'
+}
+
+func (dec *Decoder) peek() (byte, error) {
+	var err error
+	for {
+		for i := dec.scanp; i < len(dec.buf); i++ {
+			c := dec.buf[i]
+			if isSpace(rune(c)) {
+				continue
+			}
+			dec.scanp = i
+			return c, nil
+		}
+		// buffer has been scanned, now report any error
+		if err != nil {
+			return 0, err
+		}
+		err = dec.refill()
+	}
+}
+
+/*
+TODO
+
+// EncodeToken writes the given JSON token to the stream.
+// It returns an error if the delimiters [ ] { } are not properly used.
+//
+// EncodeToken does not call Flush, because usually it is part of
+// a larger operation such as Encode, and those will call Flush when finished.
+// Callers that create an Encoder and then invoke EncodeToken directly,
+// without using Encode, need to call Flush when finished to ensure that
+// the JSON is written to the underlying writer.
+func (e *Encoder) EncodeToken(t Token) error  {
+	...
+}
+
+*/
diff --git a/third_party/gofrontend/libgo/go/encoding/json/stream_test.go b/third_party/gofrontend/libgo/go/encoding/json/stream_test.go
index b562e87..c2e3040 100644
--- a/third_party/gofrontend/libgo/go/encoding/json/stream_test.go
+++ b/third_party/gofrontend/libgo/go/encoding/json/stream_test.go
@@ -6,8 +6,12 @@
 
 import (
 	"bytes"
+	"io"
 	"io/ioutil"
+	"log"
 	"net"
+	"net/http"
+	"net/http/httptest"
 	"reflect"
 	"strings"
 	"testing"
@@ -204,3 +208,147 @@
 		}
 	}
 }
+
+type tokenStreamCase struct {
+	json      string
+	expTokens []interface{}
+}
+
+type decodeThis struct {
+	v interface{}
+}
+
+var tokenStreamCases []tokenStreamCase = []tokenStreamCase{
+	// streaming token cases
+	{json: `10`, expTokens: []interface{}{float64(10)}},
+	{json: ` [10] `, expTokens: []interface{}{
+		Delim('['), float64(10), Delim(']')}},
+	{json: ` [false,10,"b"] `, expTokens: []interface{}{
+		Delim('['), false, float64(10), "b", Delim(']')}},
+	{json: `{ "a": 1 }`, expTokens: []interface{}{
+		Delim('{'), "a", float64(1), Delim('}')}},
+	{json: `{"a": 1, "b":"3"}`, expTokens: []interface{}{
+		Delim('{'), "a", float64(1), "b", "3", Delim('}')}},
+	{json: ` [{"a": 1},{"a": 2}] `, expTokens: []interface{}{
+		Delim('['),
+		Delim('{'), "a", float64(1), Delim('}'),
+		Delim('{'), "a", float64(2), Delim('}'),
+		Delim(']')}},
+	{json: `{"obj": {"a": 1}}`, expTokens: []interface{}{
+		Delim('{'), "obj", Delim('{'), "a", float64(1), Delim('}'),
+		Delim('}')}},
+	{json: `{"obj": [{"a": 1}]}`, expTokens: []interface{}{
+		Delim('{'), "obj", Delim('['),
+		Delim('{'), "a", float64(1), Delim('}'),
+		Delim(']'), Delim('}')}},
+
+	// streaming tokens with intermittent Decode()
+	{json: `{ "a": 1 }`, expTokens: []interface{}{
+		Delim('{'), "a",
+		decodeThis{float64(1)},
+		Delim('}')}},
+	{json: ` [ { "a" : 1 } ] `, expTokens: []interface{}{
+		Delim('['),
+		decodeThis{map[string]interface{}{"a": float64(1)}},
+		Delim(']')}},
+	{json: ` [{"a": 1},{"a": 2}] `, expTokens: []interface{}{
+		Delim('['),
+		decodeThis{map[string]interface{}{"a": float64(1)}},
+		decodeThis{map[string]interface{}{"a": float64(2)}},
+		Delim(']')}},
+	{json: `{ "obj" : [ { "a" : 1 } ] }`, expTokens: []interface{}{
+		Delim('{'), "obj", Delim('['),
+		decodeThis{map[string]interface{}{"a": float64(1)}},
+		Delim(']'), Delim('}')}},
+
+	{json: `{"obj": {"a": 1}}`, expTokens: []interface{}{
+		Delim('{'), "obj",
+		decodeThis{map[string]interface{}{"a": float64(1)}},
+		Delim('}')}},
+	{json: `{"obj": [{"a": 1}]}`, expTokens: []interface{}{
+		Delim('{'), "obj",
+		decodeThis{[]interface{}{
+			map[string]interface{}{"a": float64(1)},
+		}},
+		Delim('}')}},
+	{json: ` [{"a": 1} {"a": 2}] `, expTokens: []interface{}{
+		Delim('['),
+		decodeThis{map[string]interface{}{"a": float64(1)}},
+		decodeThis{&SyntaxError{"expected comma after array element", 0}},
+	}},
+	{json: `{ "a" 1 }`, expTokens: []interface{}{
+		Delim('{'), "a",
+		decodeThis{&SyntaxError{"expected colon after object key", 0}},
+	}},
+}
+
+func TestDecodeInStream(t *testing.T) {
+
+	for ci, tcase := range tokenStreamCases {
+
+		dec := NewDecoder(strings.NewReader(tcase.json))
+		for i, etk := range tcase.expTokens {
+
+			var tk interface{}
+			var err error
+
+			if dt, ok := etk.(decodeThis); ok {
+				etk = dt.v
+				err = dec.Decode(&tk)
+			} else {
+				tk, err = dec.Token()
+			}
+			if experr, ok := etk.(error); ok {
+				if err == nil || err.Error() != experr.Error() {
+					t.Errorf("case %v: Expected error %v in %q, but was %v", ci, experr, tcase.json, err)
+				}
+				break
+			} else if err == io.EOF {
+				t.Errorf("case %v: Unexpected EOF in %q", ci, tcase.json)
+				break
+			} else if err != nil {
+				t.Errorf("case %v: Unexpected error '%v' in %q", ci, err, tcase.json)
+				break
+			}
+			if !reflect.DeepEqual(tk, etk) {
+				t.Errorf(`case %v: %q @ %v expected %T(%v) was %T(%v)`, ci, tcase.json, i, etk, etk, tk, tk)
+				break
+			}
+		}
+	}
+
+}
+
+// Test from golang.org/issue/11893
+func TestHTTPDecoding(t *testing.T) {
+	const raw = `{ "foo": "bar" }`
+
+	ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
+		w.Write([]byte(raw))
+	}))
+	defer ts.Close()
+	res, err := http.Get(ts.URL)
+	if err != nil {
+		log.Fatalf("GET failed: %v", err)
+	}
+	defer res.Body.Close()
+
+	foo := struct {
+		Foo string
+	}{}
+
+	d := NewDecoder(res.Body)
+	err = d.Decode(&foo)
+	if err != nil {
+		t.Fatalf("Decode: %v", err)
+	}
+	if foo.Foo != "bar" {
+		t.Errorf("decoded %q; want \"bar\"", foo.Foo)
+	}
+
+	// make sure we get the EOF the second time
+	err = d.Decode(&foo)
+	if err != io.EOF {
+		t.Errorf("err = %v; want io.EOF", err)
+	}
+}
diff --git a/third_party/gofrontend/libgo/go/encoding/json/tagkey_test.go b/third_party/gofrontend/libgo/go/encoding/json/tagkey_test.go
index 23e71c7..85bb4ba 100644
--- a/third_party/gofrontend/libgo/go/encoding/json/tagkey_test.go
+++ b/third_party/gofrontend/libgo/go/encoding/json/tagkey_test.go
@@ -37,11 +37,11 @@
 }
 
 type percentSlashTag struct {
-	V string `json:"text/html%"` // http://golang.org/issue/2718
+	V string `json:"text/html%"` // https://golang.org/issue/2718
 }
 
 type punctuationTag struct {
-	V string `json:"!#$%&()*+-./:<=>?@[]^_{|}~"` // http://golang.org/issue/3546
+	V string `json:"!#$%&()*+-./:<=>?@[]^_{|}~"` // https://golang.org/issue/3546
 }
 
 type emptyTag struct {
diff --git a/third_party/gofrontend/libgo/go/encoding/pem/pem.go b/third_party/gofrontend/libgo/go/encoding/pem/pem.go
index 8ff7ee8..506196b 100644
--- a/third_party/gofrontend/libgo/go/encoding/pem/pem.go
+++ b/third_party/gofrontend/libgo/go/encoding/pem/pem.go
@@ -10,8 +10,10 @@
 import (
 	"bytes"
 	"encoding/base64"
+	"errors"
 	"io"
 	"sort"
+	"strings"
 )
 
 // A Block represents a PEM encoded structure.
@@ -110,27 +112,37 @@
 		}
 
 		// TODO(agl): need to cope with values that spread across lines.
-		key, val := line[0:i], line[i+1:]
+		key, val := line[:i], line[i+1:]
 		key = bytes.TrimSpace(key)
 		val = bytes.TrimSpace(val)
 		p.Headers[string(key)] = string(val)
 		rest = next
 	}
 
-	i := bytes.Index(rest, pemEnd)
-	if i < 0 {
+	var endIndex int
+	// If there were no headers, the END line might occur
+	// immediately, without a leading newline.
+	if len(p.Headers) == 0 && bytes.HasPrefix(rest, pemEnd[1:]) {
+		endIndex = 0
+	} else {
+		endIndex = bytes.Index(rest, pemEnd)
+	}
+
+	if endIndex < 0 {
 		return decodeError(data, rest)
 	}
-	base64Data := removeWhitespace(rest[0:i])
 
+	base64Data := removeWhitespace(rest[:endIndex])
 	p.Bytes = make([]byte, base64.StdEncoding.DecodedLen(len(base64Data)))
 	n, err := base64.StdEncoding.Decode(p.Bytes, base64Data)
 	if err != nil {
 		return decodeError(data, rest)
 	}
-	p.Bytes = p.Bytes[0:n]
+	p.Bytes = p.Bytes[:n]
 
-	_, rest = getLine(rest[i+len(pemEnd):])
+	// the -1 is because we might have only matched pemEnd without the
+	// leading newline if the PEM block was empty.
+	_, rest = getLine(rest[endIndex+len(pemEnd)-1:])
 
 	return
 }
@@ -171,6 +183,8 @@
 	out  io.Writer
 }
 
+var nl = []byte{'\n'}
+
 func (l *lineBreaker) Write(b []byte) (n int, err error) {
 	if l.used+len(b) < pemLineLength {
 		copy(l.line[l.used:], b)
@@ -190,7 +204,7 @@
 		return
 	}
 
-	n, err = l.out.Write([]byte{'\n'})
+	n, err = l.out.Write(nl)
 	if err != nil {
 		return
 	}
@@ -204,7 +218,7 @@
 		if err != nil {
 			return
 		}
-		_, err = l.out.Write([]byte{'\n'})
+		_, err = l.out.Write(nl)
 	}
 
 	return
@@ -244,11 +258,14 @@
 		// For consistency of output, write other headers sorted by key.
 		sort.Strings(h)
 		for _, k := range h {
+			if strings.Contains(k, ":") {
+				return errors.New("pem: cannot encode a header key that contains a colon")
+			}
 			if err := writeHeader(out, k, b.Headers[k]); err != nil {
 				return err
 			}
 		}
-		if _, err := out.Write([]byte{'\n'}); err != nil {
+		if _, err := out.Write(nl); err != nil {
 			return err
 		}
 	}
diff --git a/third_party/gofrontend/libgo/go/encoding/pem/pem_test.go b/third_party/gofrontend/libgo/go/encoding/pem/pem_test.go
index ccce42c..ab656c6 100644
--- a/third_party/gofrontend/libgo/go/encoding/pem/pem_test.go
+++ b/third_party/gofrontend/libgo/go/encoding/pem/pem_test.go
@@ -6,8 +6,11 @@
 
 import (
 	"bytes"
+	"io/ioutil"
 	"reflect"
+	"strings"
 	"testing"
+	"testing/quick"
 )
 
 type GetLineTest struct {
@@ -43,6 +46,32 @@
 	if !reflect.DeepEqual(result, privateKey) {
 		t.Errorf("#1 got:%#v want:%#v", result, privateKey)
 	}
+
+	isEmpty := func(block *Block) bool {
+		return block != nil && block.Type == "EMPTY" && len(block.Headers) == 0 && len(block.Bytes) == 0
+	}
+	result, remainder = Decode(remainder)
+	if !isEmpty(result) {
+		t.Errorf("#2 should be empty but got:%#v", result)
+	}
+	result, remainder = Decode(remainder)
+	if !isEmpty(result) {
+		t.Errorf("#3 should be empty but got:%#v", result)
+	}
+	result, remainder = Decode(remainder)
+	if !isEmpty(result) {
+		t.Errorf("#4 should be empty but got:%#v", result)
+	}
+
+	result, remainder = Decode(remainder)
+	if result == nil || result.Type != "HEADERS" || len(result.Headers) != 1 {
+		t.Errorf("#5 expected single header block but got :%v", result)
+	}
+
+	if len(remainder) != 0 {
+		t.Errorf("expected nothing remaining of pemData, but found %s", string(remainder))
+	}
+
 	result, _ = Decode([]byte(pemPrivateKey2))
 	if !reflect.DeepEqual(result, privateKey2) {
 		t.Errorf("#2 got:%#v want:%#v", result, privateKey2)
@@ -116,6 +145,62 @@
 	}
 }
 
+func TestFuzz(t *testing.T) {
+	testRoundtrip := func(block Block) bool {
+		for key := range block.Headers {
+			if strings.Contains(key, ":") {
+				// Keys with colons cannot be encoded.
+				return true
+			}
+		}
+
+		var buf bytes.Buffer
+		err := Encode(&buf, &block)
+		decoded, rest := Decode(buf.Bytes())
+
+		switch {
+		case err != nil:
+			t.Errorf("Encode of %#v resulted in error: %s", &block, err)
+		case !reflect.DeepEqual(&block, decoded):
+			t.Errorf("Encode of %#v decoded as %#v", &block, decoded)
+		case len(rest) != 0:
+			t.Errorf("Encode of %#v decoded correctly, but with %x left over", block, rest)
+		default:
+			return true
+		}
+		return false
+	}
+
+	// Explicitly test the empty block.
+	if !testRoundtrip(Block{
+		Type:    "EMPTY",
+		Headers: make(map[string]string),
+		Bytes:   []byte{},
+	}) {
+		return
+	}
+
+	quick.Check(testRoundtrip, nil)
+}
+
+func BenchmarkEncode(b *testing.B) {
+	data := &Block{Bytes: make([]byte, 65536)}
+	b.SetBytes(int64(len(data.Bytes)))
+	for i := 0; i < b.N; i++ {
+		Encode(ioutil.Discard, data)
+	}
+}
+
+func BenchmarkDecode(b *testing.B) {
+	block := &Block{Bytes: make([]byte, 65536)}
+	data := EncodeToMemory(block)
+	b.SetBytes(int64(len(data)))
+	b.ResetTimer()
+	for i := 0; i < b.N; i++ {
+		Decode(data)
+	}
+}
+
 var pemData = `verify return:0
 -----BEGIN CERTIFICATE-----
 sdlfkjskldfj
@@ -169,7 +254,32 @@
 wHFsZc20TzSdsVLBtwksUacpbDogcEVMctnNrB8FIrB3vZEv9Q0Z1VeY7nmTpF+6
 a+z2P7acL7j6A6Pr3+q8P9CPiPC7zFonVzuVPyB8GchGR2hytyiOVpuD9+k8hcuw
 ZWAaUoVtWIQ52aKS0p19G99hhb+IVANC4akkdHV4SP8i7MVNZhfUmg==
------END RSA PRIVATE KEY-----`
+-----END RSA PRIVATE KEY-----
+
+
+-----BEGIN EMPTY-----
+-----END EMPTY-----
+
+-----BEGIN EMPTY-----
+
+-----END EMPTY-----
+
+-----BEGIN EMPTY-----
+
+
+-----END EMPTY-----
+
+# This shouldn't be recognised because of the missing newline after the
+headers.
+-----BEGIN HEADERS-----
+Header: 1
+-----END HEADERS-----
+
+# This should be valid, however.
+-----BEGIN HEADERS-----
+Header: 1
+
+-----END HEADERS-----`
 
 var certificate = &Block{Type: "CERTIFICATE",
 	Headers: map[string]string{},
diff --git a/third_party/gofrontend/libgo/go/encoding/xml/marshal.go b/third_party/gofrontend/libgo/go/encoding/xml/marshal.go
index 8c63420..86d1422 100644
--- a/third_party/gofrontend/libgo/go/encoding/xml/marshal.go
+++ b/third_party/gofrontend/libgo/go/encoding/xml/marshal.go
@@ -173,6 +173,7 @@
 }
 
 var (
+	begComment   = []byte("<!--")
 	endComment   = []byte("-->")
 	endProcInst  = []byte("?>")
 	endDirective = []byte(">")
@@ -191,6 +192,7 @@
 // EncodeToken allows writing a ProcInst with Target set to "xml" only as the first token
 // in the stream.
 func (enc *Encoder) EncodeToken(t Token) error {
+
 	p := &enc.p
 	switch t := t.(type) {
 	case StartElement:
@@ -202,7 +204,7 @@
 			return err
 		}
 	case CharData:
-		EscapeText(p, t)
+		escapeText(p, t, false)
 	case Comment:
 		if bytes.Contains(t, endComment) {
 			return fmt.Errorf("xml: EncodeToken of Comment containing --> marker")
@@ -231,16 +233,59 @@
 		}
 		p.WriteString("?>")
 	case Directive:
-		if bytes.Contains(t, endDirective) {
-			return fmt.Errorf("xml: EncodeToken of Directive containing > marker")
+		if !isValidDirective(t) {
+			return fmt.Errorf("xml: EncodeToken of Directive containing wrong < or > markers")
 		}
 		p.WriteString("<!")
 		p.Write(t)
 		p.WriteString(">")
+	default:
+		return fmt.Errorf("xml: EncodeToken of invalid token type")
+
 	}
 	return p.cachedWriteError()
 }
 
+// isValidDirective reports whether dir is a valid directive text,
+// meaning angle brackets are matched, ignoring comments and strings.
+func isValidDirective(dir Directive) bool {
+	var (
+		depth     int
+		inquote   uint8
+		incomment bool
+	)
+	for i, c := range dir {
+		switch {
+		case incomment:
+			if c == '>' {
+				if n := 1 + i - len(endComment); n >= 0 && bytes.Equal(dir[n:i+1], endComment) {
+					incomment = false
+				}
+			}
+			// Just ignore anything in comment
+		case inquote != 0:
+			if c == inquote {
+				inquote = 0
+			}
+			// Just ignore anything within quotes
+		case c == '\'' || c == '"':
+			inquote = c
+		case c == '<':
+			if i+len(begComment) < len(dir) && bytes.Equal(dir[i:i+len(begComment)], begComment) {
+				incomment = true
+			} else {
+				depth++
+			}
+		case c == '>':
+			if depth == 0 {
+				return false
+			}
+			depth--
+		}
+	}
+	return depth == 0 && inquote == 0 && !incomment
+}
+
 // Flush flushes any buffered XML to the underlying writer.
 // See the EncodeToken documentation for details about when it is necessary.
 func (enc *Encoder) Flush() error {
@@ -724,6 +769,9 @@
 
 		switch finfo.flags & fMode {
 		case fCharData:
+			if err := s.trim(finfo.parents); err != nil {
+				return err
+			}
 			if vf.CanInterface() && vf.Type().Implements(textMarshalerType) {
 				data, err := vf.Interface().(encoding.TextMarshaler).MarshalText()
 				if err != nil {
@@ -767,6 +815,9 @@
 			continue
 
 		case fComment:
+			if err := s.trim(finfo.parents); err != nil {
+				return err
+			}
 			k := vf.Kind()
 			if !(k == reflect.String || k == reflect.Slice && vf.Type().Elem().Kind() == reflect.Uint8) {
 				return fmt.Errorf("xml: bad type for comment field of %s", val.Type())
@@ -894,7 +945,7 @@
 			return err
 		}
 	}
-	s.stack = parents[:split]
+	s.stack = s.stack[:split]
 	return nil
 }
 
diff --git a/third_party/gofrontend/libgo/go/encoding/xml/marshal_test.go b/third_party/gofrontend/libgo/go/encoding/xml/marshal_test.go
index 14f73a7..ef6c20e 100644
--- a/third_party/gofrontend/libgo/go/encoding/xml/marshal_test.go
+++ b/third_party/gofrontend/libgo/go/encoding/xml/marshal_test.go
@@ -12,6 +12,7 @@
 	"reflect"
 	"strconv"
 	"strings"
+	"sync"
 	"testing"
 	"time"
 )
@@ -138,6 +139,7 @@
 	EmbedC
 	EmbedB EmbedB
 	FieldA string
+	embedD
 }
 
 type EmbedB struct {
@@ -152,6 +154,11 @@
 	FieldC  string
 }
 
+type embedD struct {
+	fieldD string
+	FieldE string // Promoted and visible when embedD is embedded.
+}
+
 type NameCasing struct {
 	XMLName struct{} `xml:"casing"`
 	Xy      string
@@ -339,6 +346,16 @@
 	OuterStruct
 }
 
+type NestedAndChardata struct {
+	AB       []string `xml:"A>B"`
+	Chardata string   `xml:",chardata"`
+}
+
+type NestedAndComment struct {
+	AB      []string `xml:"A>B"`
+	Comment string   `xml:",comment"`
+}
+
 func ifaceptr(x interface{}) interface{} {
 	return &x
 }
@@ -617,6 +634,69 @@
 			`</service>`,
 		MarshalOnly: true,
 	},
+	{
+		Value: &struct {
+			XMLName struct{} `xml:"space top"`
+			A       string   `xml:"x>a"`
+			B       string   `xml:"x>b"`
+			C       string   `xml:"space x>c"`
+			C1      string   `xml:"space1 x>c"`
+			D1      string   `xml:"space1 x>d"`
+		}{
+			A:  "a",
+			B:  "b",
+			C:  "c",
+			C1: "c1",
+			D1: "d1",
+		},
+		ExpectXML: `<top xmlns="space">` +
+			`<x><a>a</a><b>b</b><c xmlns="space">c</c>` +
+			`<c xmlns="space1">c1</c>` +
+			`<d xmlns="space1">d1</d>` +
+			`</x>` +
+			`</top>`,
+	},
+	{
+		Value: &struct {
+			XMLName Name
+			A       string `xml:"x>a"`
+			B       string `xml:"x>b"`
+			C       string `xml:"space x>c"`
+			C1      string `xml:"space1 x>c"`
+			D1      string `xml:"space1 x>d"`
+		}{
+			XMLName: Name{
+				Space: "space0",
+				Local: "top",
+			},
+			A:  "a",
+			B:  "b",
+			C:  "c",
+			C1: "c1",
+			D1: "d1",
+		},
+		ExpectXML: `<top xmlns="space0">` +
+			`<x><a>a</a><b>b</b>` +
+			`<c xmlns="space">c</c>` +
+			`<c xmlns="space1">c1</c>` +
+			`<d xmlns="space1">d1</d>` +
+			`</x>` +
+			`</top>`,
+	},
+	{
+		Value: &struct {
+			XMLName struct{} `xml:"top"`
+			B       string   `xml:"space x>b"`
+			B1      string   `xml:"space1 x>b"`
+		}{
+			B:  "b",
+			B1: "b1",
+		},
+		ExpectXML: `<top>` +
+			`<x><b xmlns="space">b</b>` +
+			`<b xmlns="space1">b1</b></x>` +
+			`</top>`,
+	},
 
 	// Test struct embedding
 	{
@@ -637,6 +717,9 @@
 				},
 			},
 			FieldA: "A.A",
+			embedD: embedD{
+				FieldE: "A.D.E",
+			},
 		},
 		ExpectXML: `<EmbedA>` +
 			`<FieldB>A.C.B</FieldB>` +
@@ -650,6 +733,7 @@
 			`<FieldC>A.B.C.C</FieldC>` +
 			`</EmbedB>` +
 			`<FieldA>A.A</FieldA>` +
+			`<FieldE>A.D.E</FieldE>` +
 			`</EmbedA>`,
 	},
 
@@ -924,6 +1008,14 @@
 		ExpectXML: `<outer xmlns="testns" int="10"></outer>`,
 		Value:     &OuterOuterStruct{OuterStruct{IntAttr: 10}},
 	},
+	{
+		ExpectXML: `<NestedAndChardata><A><B></B><B></B></A>test</NestedAndChardata>`,
+		Value:     &NestedAndChardata{AB: make([]string, 2), Chardata: "test"},
+	},
+	{
+		ExpectXML: `<NestedAndComment><A><B></B><B></B></A><!--test--></NestedAndComment>`,
+		Value:     &NestedAndComment{AB: make([]string, 2), Comment: "test"},
+	},
 }
 
 func TestMarshal(t *testing.T) {
@@ -933,7 +1025,7 @@
 		}
 		data, err := Marshal(test.Value)
 		if err != nil {
-			t.Errorf("#%d: Error: %s", idx, err)
+			t.Errorf("#%d: marshal(%#v): %s", idx, test.Value, err)
 			continue
 		}
 		if got, want := string(data), test.ExpectXML; got != want {
@@ -1037,6 +1129,14 @@
 		if _, ok := test.Value.(*Plain); ok {
 			continue
 		}
+		if test.ExpectXML == `<top>`+
+			`<x><b xmlns="space">b</b>`+
+			`<b xmlns="space1">b1</b></x>`+
+			`</top>` {
+			// TODO(rogpeppe): re-enable this test in
+			// https://go-review.googlesource.com/#/c/5910/
+			continue
+		}
 
 		vt := reflect.TypeOf(test.Value)
 		dest := reflect.New(vt.Elem()).Interface()
@@ -1148,12 +1248,14 @@
 }
 
 func BenchmarkMarshal(b *testing.B) {
+	b.ReportAllocs()
 	for i := 0; i < b.N; i++ {
 		Marshal(atomValue)
 	}
 }
 
 func BenchmarkUnmarshal(b *testing.B) {
+	b.ReportAllocs()
 	xml := []byte(atomXml)
 	for i := 0; i < b.N; i++ {
 		Unmarshal(xml, &Feed{})
@@ -1192,41 +1294,369 @@
 }
 
 var encodeTokenTests = []struct {
-	tok  Token
+	desc string
+	toks []Token
 	want string
-	ok   bool
-}{
-	{StartElement{Name{"space", "local"}, nil}, "<local xmlns=\"space\">", true},
-	{StartElement{Name{"space", ""}, nil}, "", false},
-	{EndElement{Name{"space", ""}}, "", false},
-	{CharData("foo"), "foo", true},
-	{Comment("foo"), "<!--foo-->", true},
-	{Comment("foo-->"), "", false},
-	{ProcInst{"Target", []byte("Instruction")}, "<?Target Instruction?>", true},
-	{ProcInst{"", []byte("Instruction")}, "", false},
-	{ProcInst{"Target", []byte("Instruction?>")}, "", false},
-	{Directive("foo"), "<!foo>", true},
-	{Directive("foo>"), "", false},
-}
+	err  string
+}{{
+	desc: "start element with name space",
+	toks: []Token{
+		StartElement{Name{"space", "local"}, nil},
+	},
+	want: `<local xmlns="space">`,
+}, {
+	desc: "start element with no name",
+	toks: []Token{
+		StartElement{Name{"space", ""}, nil},
+	},
+	err: "xml: start tag with no name",
+}, {
+	desc: "end element with no name",
+	toks: []Token{
+		EndElement{Name{"space", ""}},
+	},
+	err: "xml: end tag with no name",
+}, {
+	desc: "char data",
+	toks: []Token{
+		CharData("foo"),
+	},
+	want: `foo`,
+}, {
+	desc: "char data with escaped chars",
+	toks: []Token{
+		CharData(" \t\n"),
+	},
+	want: " &#x9;\n",
+}, {
+	desc: "comment",
+	toks: []Token{
+		Comment("foo"),
+	},
+	want: `<!--foo-->`,
+}, {
+	desc: "comment with invalid content",
+	toks: []Token{
+		Comment("foo-->"),
+	},
+	err: "xml: EncodeToken of Comment containing --> marker",
+}, {
+	desc: "proc instruction",
+	toks: []Token{
+		ProcInst{"Target", []byte("Instruction")},
+	},
+	want: `<?Target Instruction?>`,
+}, {
+	desc: "proc instruction with empty target",
+	toks: []Token{
+		ProcInst{"", []byte("Instruction")},
+	},
+	err: "xml: EncodeToken of ProcInst with invalid Target",
+}, {
+	desc: "proc instruction with bad content",
+	toks: []Token{
+		ProcInst{"", []byte("Instruction?>")},
+	},
+	err: "xml: EncodeToken of ProcInst with invalid Target",
+}, {
+	desc: "directive",
+	toks: []Token{
+		Directive("foo"),
+	},
+	want: `<!foo>`,
+}, {
+	desc: "more complex directive",
+	toks: []Token{
+		Directive("DOCTYPE doc [ <!ELEMENT doc '>'> <!-- com>ment --> ]"),
+	},
+	want: `<!DOCTYPE doc [ <!ELEMENT doc '>'> <!-- com>ment --> ]>`,
+}, {
+	desc: "directive instruction with bad name",
+	toks: []Token{
+		Directive("foo>"),
+	},
+	err: "xml: EncodeToken of Directive containing wrong < or > markers",
+}, {
+	desc: "end tag without start tag",
+	toks: []Token{
+		EndElement{Name{"foo", "bar"}},
+	},
+	err: "xml: end tag </bar> without start tag",
+}, {
+	desc: "mismatching end tag local name",
+	toks: []Token{
+		StartElement{Name{"", "foo"}, nil},
+		EndElement{Name{"", "bar"}},
+	},
+	err:  "xml: end tag </bar> does not match start tag <foo>",
+	want: `<foo>`,
+}, {
+	desc: "mismatching end tag namespace",
+	toks: []Token{
+		StartElement{Name{"space", "foo"}, nil},
+		EndElement{Name{"another", "foo"}},
+	},
+	err:  "xml: end tag </foo> in namespace another does not match start tag <foo> in namespace space",
+	want: `<foo xmlns="space">`,
+}, {
+	desc: "start element with explicit namespace",
+	toks: []Token{
+		StartElement{Name{"space", "local"}, []Attr{
+			{Name{"xmlns", "x"}, "space"},
+			{Name{"space", "foo"}, "value"},
+		}},
+	},
+	want: `<local xmlns="space" xmlns:_xmlns="xmlns" _xmlns:x="space" xmlns:space="space" space:foo="value">`,
+}, {
+	desc: "start element with explicit namespace and colliding prefix",
+	toks: []Token{
+		StartElement{Name{"space", "local"}, []Attr{
+			{Name{"xmlns", "x"}, "space"},
+			{Name{"space", "foo"}, "value"},
+			{Name{"x", "bar"}, "other"},
+		}},
+	},
+	want: `<local xmlns="space" xmlns:_xmlns="xmlns" _xmlns:x="space" xmlns:space="space" space:foo="value" xmlns:x="x" x:bar="other">`,
+}, {
+	desc: "start element using previously defined namespace",
+	toks: []Token{
+		StartElement{Name{"", "local"}, []Attr{
+			{Name{"xmlns", "x"}, "space"},
+		}},
+		StartElement{Name{"space", "foo"}, []Attr{
+			{Name{"space", "x"}, "y"},
+		}},
+	},
+	want: `<local xmlns:_xmlns="xmlns" _xmlns:x="space"><foo xmlns="space" xmlns:space="space" space:x="y">`,
+}, {
+	desc: "nested name space with same prefix",
+	toks: []Token{
+		StartElement{Name{"", "foo"}, []Attr{
+			{Name{"xmlns", "x"}, "space1"},
+		}},
+		StartElement{Name{"", "foo"}, []Attr{
+			{Name{"xmlns", "x"}, "space2"},
+		}},
+		StartElement{Name{"", "foo"}, []Attr{
+			{Name{"space1", "a"}, "space1 value"},
+			{Name{"space2", "b"}, "space2 value"},
+		}},
+		EndElement{Name{"", "foo"}},
+		EndElement{Name{"", "foo"}},
+		StartElement{Name{"", "foo"}, []Attr{
+			{Name{"space1", "a"}, "space1 value"},
+			{Name{"space2", "b"}, "space2 value"},
+		}},
+	},
+	want: `<foo xmlns:_xmlns="xmlns" _xmlns:x="space1"><foo _xmlns:x="space2"><foo xmlns:space1="space1" space1:a="space1 value" xmlns:space2="space2" space2:b="space2 value"></foo></foo><foo xmlns:space1="space1" space1:a="space1 value" xmlns:space2="space2" space2:b="space2 value">`,
+}, {
+	desc: "start element defining several prefixes for the same name space",
+	toks: []Token{
+		StartElement{Name{"space", "foo"}, []Attr{
+			{Name{"xmlns", "a"}, "space"},
+			{Name{"xmlns", "b"}, "space"},
+			{Name{"space", "x"}, "value"},
+		}},
+	},
+	want: `<foo xmlns="space" xmlns:_xmlns="xmlns" _xmlns:a="space" _xmlns:b="space" xmlns:space="space" space:x="value">`,
+}, {
+	desc: "nested element redefines name space",
+	toks: []Token{
+		StartElement{Name{"", "foo"}, []Attr{
+			{Name{"xmlns", "x"}, "space"},
+		}},
+		StartElement{Name{"space", "foo"}, []Attr{
+			{Name{"xmlns", "y"}, "space"},
+			{Name{"space", "a"}, "value"},
+		}},
+	},
+	want: `<foo xmlns:_xmlns="xmlns" _xmlns:x="space"><foo xmlns="space" _xmlns:y="space" xmlns:space="space" space:a="value">`,
+}, {
+	desc: "nested element creates alias for default name space",
+	toks: []Token{
+		StartElement{Name{"space", "foo"}, []Attr{
+			{Name{"", "xmlns"}, "space"},
+		}},
+		StartElement{Name{"space", "foo"}, []Attr{
+			{Name{"xmlns", "y"}, "space"},
+			{Name{"space", "a"}, "value"},
+		}},
+	},
+	want: `<foo xmlns="space" xmlns="space"><foo xmlns="space" xmlns:_xmlns="xmlns" _xmlns:y="space" xmlns:space="space" space:a="value">`,
+}, {
+	desc: "nested element defines default name space with existing prefix",
+	toks: []Token{
+		StartElement{Name{"", "foo"}, []Attr{
+			{Name{"xmlns", "x"}, "space"},
+		}},
+		StartElement{Name{"space", "foo"}, []Attr{
+			{Name{"", "xmlns"}, "space"},
+			{Name{"space", "a"}, "value"},
+		}},
+	},
+	want: `<foo xmlns:_xmlns="xmlns" _xmlns:x="space"><foo xmlns="space" xmlns="space" xmlns:space="space" space:a="value">`,
+}, {
+	desc: "nested element uses empty attribute name space when default ns defined",
+	toks: []Token{
+		StartElement{Name{"space", "foo"}, []Attr{
+			{Name{"", "xmlns"}, "space"},
+		}},
+		StartElement{Name{"space", "foo"}, []Attr{
+			{Name{"", "attr"}, "value"},
+		}},
+	},
+	want: `<foo xmlns="space" xmlns="space"><foo xmlns="space" attr="value">`,
+}, {
+	desc: "redefine xmlns",
+	toks: []Token{
+		StartElement{Name{"", "foo"}, []Attr{
+			{Name{"foo", "xmlns"}, "space"},
+		}},
+	},
+	want: `<foo xmlns:foo="foo" foo:xmlns="space">`,
+}, {
+	desc: "xmlns with explicit name space #1",
+	toks: []Token{
+		StartElement{Name{"space", "foo"}, []Attr{
+			{Name{"xml", "xmlns"}, "space"},
+		}},
+	},
+	want: `<foo xmlns="space" xmlns:_xml="xml" _xml:xmlns="space">`,
+}, {
+	desc: "xmlns with explicit name space #2",
+	toks: []Token{
+		StartElement{Name{"space", "foo"}, []Attr{
+			{Name{xmlURL, "xmlns"}, "space"},
+		}},
+	},
+	want: `<foo xmlns="space" xml:xmlns="space">`,
+}, {
+	desc: "empty name space declaration is ignored",
+	toks: []Token{
+		StartElement{Name{"", "foo"}, []Attr{
+			{Name{"xmlns", "foo"}, ""},
+		}},
+	},
+	want: `<foo xmlns:_xmlns="xmlns" _xmlns:foo="">`,
+}, {
+	desc: "attribute with no name is ignored",
+	toks: []Token{
+		StartElement{Name{"", "foo"}, []Attr{
+			{Name{"", ""}, "value"},
+		}},
+	},
+	want: `<foo>`,
+}, {
+	desc: "namespace URL with non-valid name",
+	toks: []Token{
+		StartElement{Name{"/34", "foo"}, []Attr{
+			{Name{"/34", "x"}, "value"},
+		}},
+	},
+	want: `<foo xmlns="/34" xmlns:_="/34" _:x="value">`,
+}, {
+	desc: "nested element resets default namespace to empty",
+	toks: []Token{
+		StartElement{Name{"space", "foo"}, []Attr{
+			{Name{"", "xmlns"}, "space"},
+		}},
+		StartElement{Name{"", "foo"}, []Attr{
+			{Name{"", "xmlns"}, ""},
+			{Name{"", "x"}, "value"},
+			{Name{"space", "x"}, "value"},
+		}},
+	},
+	want: `<foo xmlns="space" xmlns="space"><foo xmlns="" x="value" xmlns:space="space" space:x="value">`,
+}, {
+	desc: "nested element requires empty default name space",
+	toks: []Token{
+		StartElement{Name{"space", "foo"}, []Attr{
+			{Name{"", "xmlns"}, "space"},
+		}},
+		StartElement{Name{"", "foo"}, nil},
+	},
+	want: `<foo xmlns="space" xmlns="space"><foo>`,
+}, {
+	desc: "attribute uses name space from xmlns",
+	toks: []Token{
+		StartElement{Name{"some/space", "foo"}, []Attr{
+			{Name{"", "attr"}, "value"},
+			{Name{"some/space", "other"}, "other value"},
+		}},
+	},
+	want: `<foo xmlns="some/space" attr="value" xmlns:space="some/space" space:other="other value">`,
+}, {
+	desc: "default name space should not be used by attributes",
+	toks: []Token{
+		StartElement{Name{"space", "foo"}, []Attr{
+			{Name{"", "xmlns"}, "space"},
+			{Name{"xmlns", "bar"}, "space"},
+			{Name{"space", "baz"}, "foo"},
+		}},
+		StartElement{Name{"space", "baz"}, nil},
+		EndElement{Name{"space", "baz"}},
+		EndElement{Name{"space", "foo"}},
+	},
+	want: `<foo xmlns="space" xmlns="space" xmlns:_xmlns="xmlns" _xmlns:bar="space" xmlns:space="space" space:baz="foo"><baz xmlns="space"></baz></foo>`,
+}, {
+	desc: "default name space not used by attributes, not explicitly defined",
+	toks: []Token{
+		StartElement{Name{"space", "foo"}, []Attr{
+			{Name{"", "xmlns"}, "space"},
+			{Name{"space", "baz"}, "foo"},
+		}},
+		StartElement{Name{"space", "baz"}, nil},
+		EndElement{Name{"space", "baz"}},
+		EndElement{Name{"space", "foo"}},
+	},
+	want: `<foo xmlns="space" xmlns="space" xmlns:space="space" space:baz="foo"><baz xmlns="space"></baz></foo>`,
+}, {
+	desc: "impossible xmlns declaration",
+	toks: []Token{
+		StartElement{Name{"", "foo"}, []Attr{
+			{Name{"", "xmlns"}, "space"},
+		}},
+		StartElement{Name{"space", "bar"}, []Attr{
+			{Name{"space", "attr"}, "value"},
+		}},
+	},
+	want: `<foo xmlns="space"><bar xmlns="space" xmlns:space="space" space:attr="value">`,
+}}
 
 func TestEncodeToken(t *testing.T) {
-	for _, tt := range encodeTokenTests {
+loop:
+	for i, tt := range encodeTokenTests {
 		var buf bytes.Buffer
 		enc := NewEncoder(&buf)
-		err := enc.EncodeToken(tt.tok)
+		var err error
+		for j, tok := range tt.toks {
+			err = enc.EncodeToken(tok)
+			if err != nil && j < len(tt.toks)-1 {
+				t.Errorf("#%d %s token #%d: %v", i, tt.desc, j, err)
+				continue loop
+			}
+		}
+		errorf := func(f string, a ...interface{}) {
+			t.Errorf("#%d %s token #%d:%s", i, tt.desc, len(tt.toks)-1, fmt.Sprintf(f, a...))
+		}
 		switch {
-		case !tt.ok && err == nil:
-			t.Errorf("enc.EncodeToken(%#v): expected error; got none", tt.tok)
-		case tt.ok && err != nil:
-			t.Fatalf("enc.EncodeToken: %v", err)
-		case !tt.ok && err != nil:
-			// expected error, got one
+		case tt.err != "" && err == nil:
+			errorf(" expected error; got none")
+			continue
+		case tt.err == "" && err != nil:
+			errorf(" got error: %v", err)
+			continue
+		case tt.err != "" && err != nil && tt.err != err.Error():
+			errorf(" error mismatch; got %v, want %v", err, tt.err)
+			continue
 		}
 		if err := enc.Flush(); err != nil {
-			t.Fatalf("enc.EncodeToken: %v", err)
+			errorf(" %v", err)
+			continue
 		}
 		if got := buf.String(); got != tt.want {
-			t.Errorf("enc.EncodeToken = %s; want: %s", got, tt.want)
+			errorf("\ngot  %v\nwant %v", got, tt.want)
+			continue
 		}
 	}
 }
@@ -1264,3 +1694,83 @@
 		}
 	}
 }
+
+// Issue 9796. Used to fail with GORACE="halt_on_error=1" -race.
+func TestRace9796(t *testing.T) {
+	type A struct{}
+	type B struct {
+		C []A `xml:"X>Y"`
+	}
+	var wg sync.WaitGroup
+	for i := 0; i < 2; i++ {
+		wg.Add(1)
+		go func() {
+			Marshal(B{[]A{A{}}})
+			wg.Done()
+		}()
+	}
+	wg.Wait()
+}
+
+func TestIsValidDirective(t *testing.T) {
+	testOK := []string{
+		"<>",
+		"< < > >",
+		"<!DOCTYPE '<' '>' '>' <!--nothing-->>",
+		"<!DOCTYPE doc [ <!ELEMENT doc ANY> <!ELEMENT doc ANY> ]>",
+		"<!DOCTYPE doc [ <!ELEMENT doc \"ANY> '<' <!E\" LEMENT '>' doc ANY> ]>",
+		"<!DOCTYPE doc <!-- just>>>> a < comment --> [ <!ITEM anything> ] >",
+	}
+	testKO := []string{
+		"<",
+		">",
+		"<!--",
+		"-->",
+		"< > > < < >",
+		"<!dummy <!-- > -->",
+		"<!DOCTYPE doc '>",
+		"<!DOCTYPE doc '>'",
+		"<!DOCTYPE doc <!--comment>",
+	}
+	for _, s := range testOK {
+		if !isValidDirective(Directive(s)) {
+			t.Errorf("Directive %q is expected to be valid", s)
+		}
+	}
+	for _, s := range testKO {
+		if isValidDirective(Directive(s)) {
+			t.Errorf("Directive %q is expected to be invalid", s)
+		}
+	}
+}
+
+// Issue 11719. EncodeToken used to silently eat tokens with an invalid type.
+func TestSimpleUseOfEncodeToken(t *testing.T) {
+	var buf bytes.Buffer
+	enc := NewEncoder(&buf)
+	if err := enc.EncodeToken(&StartElement{Name: Name{"", "object1"}}); err == nil {
+		t.Errorf("enc.EncodeToken: pointer type should be rejected")
+	}
+	if err := enc.EncodeToken(&EndElement{Name: Name{"", "object1"}}); err == nil {
+		t.Errorf("enc.EncodeToken: pointer type should be rejected")
+	}
+	if err := enc.EncodeToken(StartElement{Name: Name{"", "object2"}}); err != nil {
+		t.Errorf("enc.EncodeToken: StartElement %s", err)
+	}
+	if err := enc.EncodeToken(EndElement{Name: Name{"", "object2"}}); err != nil {
+		t.Errorf("enc.EncodeToken: EndElement %s", err)
+	}
+	if err := enc.EncodeToken(Universe{}); err == nil {
+		t.Errorf("enc.EncodeToken: invalid type not caught")
+	}
+	if err := enc.Flush(); err != nil {
+		t.Errorf("enc.Flush: %s", err)
+	}
+	if buf.Len() == 0 {
+		t.Errorf("enc.EncodeToken: empty buffer")
+	}
+	want := "<object2></object2>"
+	if buf.String() != want {
+		t.Errorf("enc.EncodeToken: expected %q; got %q", want, buf.String())
+	}
+}
diff --git a/third_party/gofrontend/libgo/go/encoding/xml/read_test.go b/third_party/gofrontend/libgo/go/encoding/xml/read_test.go
index 01f55d0..7d004dc 100644
--- a/third_party/gofrontend/libgo/go/encoding/xml/read_test.go
+++ b/third_party/gofrontend/libgo/go/encoding/xml/read_test.go
@@ -694,7 +694,7 @@
 	Pea interface{} `xml:"Pea"`
 }
 
-// https://code.google.com/p/go/issues/detail?id=6836
+// https://golang.org/issue/6836
 func TestUnmarshalIntoInterface(t *testing.T) {
 	pod := new(Pod)
 	pod.Pea = new(Pea)
diff --git a/third_party/gofrontend/libgo/go/encoding/xml/typeinfo.go b/third_party/gofrontend/libgo/go/encoding/xml/typeinfo.go
index 22248d2..6766b88 100644
--- a/third_party/gofrontend/libgo/go/encoding/xml/typeinfo.go
+++ b/third_party/gofrontend/libgo/go/encoding/xml/typeinfo.go
@@ -60,7 +60,7 @@
 		n := typ.NumField()
 		for i := 0; i < n; i++ {
 			f := typ.Field(i)
-			if f.PkgPath != "" || f.Tag.Get("xml") == "-" {
+			if (f.PkgPath != "" && !f.Anonymous) || f.Tag.Get("xml") == "-" {
 				continue // Private field
 			}
 
diff --git a/third_party/gofrontend/libgo/go/encoding/xml/xml.go b/third_party/gofrontend/libgo/go/encoding/xml/xml.go
index 8c15b98..0a21c93 100644
--- a/third_party/gofrontend/libgo/go/encoding/xml/xml.go
+++ b/third_party/gofrontend/libgo/go/encoding/xml/xml.go
@@ -549,7 +549,6 @@
 
 	case '?':
 		// <?: Processing instruction.
-		// TODO(rsc): Should parse the <?xml declaration to make sure the version is 1.0.
 		var target string
 		if target, ok = d.name(); !ok {
 			if d.err == nil {
@@ -574,7 +573,13 @@
 		data = data[0 : len(data)-2] // chop ?>
 
 		if target == "xml" {
-			enc := procInstEncoding(string(data))
+			content := string(data)
+			ver := procInst("version", content)
+			if ver != "" && ver != "1.0" {
+				d.err = fmt.Errorf("xml: unsupported version %q; only version 1.0 is supported", ver)
+				return nil, d.err
+			}
+			enc := procInst("encoding", content)
 			if enc != "" && enc != "utf-8" && enc != "UTF-8" {
 				if d.CharsetReader == nil {
 					d.err = fmt.Errorf("xml: encoding %q declared but Decoder.CharsetReader is nil", enc)
@@ -723,7 +728,7 @@
 		return nil, d.err
 	}
 
-	attr = make([]Attr, 0, 4)
+	attr = []Attr{}
 	for {
 		d.space()
 		if b, ok = d.mustgetc(); !ok {
@@ -747,7 +752,11 @@
 
 		n := len(attr)
 		if n >= cap(attr) {
-			nattr := make([]Attr, n, 2*cap(attr))
+			nCap := 2 * cap(attr)
+			if nCap == 0 {
+				nCap = 4
+			}
+			nattr := make([]Attr, n, nCap)
 			copy(nattr, attr)
 			attr = nattr
 		}
@@ -1119,12 +1128,12 @@
 	}
 
 	// Now we check the characters.
-	s = d.buf.String()
-	if !isName([]byte(s)) {
-		d.err = d.syntaxError("invalid XML name: " + s)
+	b := d.buf.Bytes()
+	if !isName(b) {
+		d.err = d.syntaxError("invalid XML name: " + string(b))
 		return "", false
 	}
-	return s, true
+	return string(b), true
 }
 
 // Read a name and append its bytes to d.buf.
@@ -1832,6 +1841,13 @@
 // EscapeText writes to w the properly escaped XML equivalent
 // of the plain text data s.
 func EscapeText(w io.Writer, s []byte) error {
+	return escapeText(w, s, true)
+}
+
+// escapeText writes to w the properly escaped XML equivalent
+// of the plain text data s. If escapeNewline is true, newline
+// characters will be escaped.
+func escapeText(w io.Writer, s []byte, escapeNewline bool) error {
 	var esc []byte
 	last := 0
 	for i := 0; i < len(s); {
@@ -1851,6 +1867,9 @@
 		case '\t':
 			esc = esc_tab
 		case '\n':
+			if !escapeNewline {
+				continue
+			}
 			esc = esc_nl
 		case '\r':
 			esc = esc_cr
@@ -1921,16 +1940,17 @@
 	EscapeText(w, s)
 }
 
-// procInstEncoding parses the `encoding="..."` or `encoding='...'`
+// procInst parses the `param="..."` or `param='...'`
 // value out of the provided string, returning "" if not found.
-func procInstEncoding(s string) string {
+func procInst(param, s string) string {
 	// TODO: this parsing is somewhat lame and not exact.
 	// It works for all actual cases, though.
-	idx := strings.Index(s, "encoding=")
+	param = param + "="
+	idx := strings.Index(s, param)
 	if idx == -1 {
 		return ""
 	}
-	v := s[idx+len("encoding="):]
+	v := s[idx+len(param):]
 	if v == "" {
 		return ""
 	}
diff --git a/third_party/gofrontend/libgo/go/encoding/xml/xml_test.go b/third_party/gofrontend/libgo/go/encoding/xml/xml_test.go
index be995c0..312a7c9 100644
--- a/third_party/gofrontend/libgo/go/encoding/xml/xml_test.go
+++ b/third_party/gofrontend/libgo/go/encoding/xml/xml_test.go
@@ -657,20 +657,23 @@
 }
 
 var procInstTests = []struct {
-	input, expect string
+	input  string
+	expect [2]string
 }{
-	{`version="1.0" encoding="utf-8"`, "utf-8"},
-	{`version="1.0" encoding='utf-8'`, "utf-8"},
-	{`version="1.0" encoding='utf-8' `, "utf-8"},
-	{`version="1.0" encoding=utf-8`, ""},
-	{`encoding="FOO" `, "FOO"},
+	{`version="1.0" encoding="utf-8"`, [2]string{"1.0", "utf-8"}},
+	{`version="1.0" encoding='utf-8'`, [2]string{"1.0", "utf-8"}},
+	{`version="1.0" encoding='utf-8' `, [2]string{"1.0", "utf-8"}},
+	{`version="1.0" encoding=utf-8`, [2]string{"1.0", ""}},
+	{`encoding="FOO" `, [2]string{"", "FOO"}},
 }
 
 func TestProcInstEncoding(t *testing.T) {
 	for _, test := range procInstTests {
-		got := procInstEncoding(test.input)
-		if got != test.expect {
-			t.Errorf("procInstEncoding(%q) = %q; want %q", test.input, got, test.expect)
+		if got := procInst("version", test.input); got != test.expect[0] {
+			t.Errorf("procInst(version, %q) = %q; want %q", test.input, got, test.expect[0])
+		}
+		if got := procInst("encoding", test.input); got != test.expect[1] {
+			t.Errorf("procInst(encoding, %q) = %q; want %q", test.input, got, test.expect[1])
 		}
 	}
 }
diff --git a/third_party/gofrontend/libgo/go/expvar/expvar.go b/third_party/gofrontend/libgo/go/expvar/expvar.go
index 9b6dab4..24c2d6b 100644
--- a/third_party/gofrontend/libgo/go/expvar/expvar.go
+++ b/third_party/gofrontend/libgo/go/expvar/expvar.go
@@ -26,12 +26,14 @@
 	"encoding/json"
 	"fmt"
 	"log"
+	"math"
 	"net/http"
 	"os"
 	"runtime"
 	"sort"
 	"strconv"
 	"sync"
+	"sync/atomic"
 )
 
 // Var is an abstract type for all exported variables.
@@ -41,52 +43,47 @@
 
 // Int is a 64-bit integer variable that satisfies the Var interface.
 type Int struct {
-	mu sync.RWMutex
-	i  int64
+	i int64
 }
 
 func (v *Int) String() string {
-	v.mu.RLock()
-	defer v.mu.RUnlock()
-	return strconv.FormatInt(v.i, 10)
+	return strconv.FormatInt(atomic.LoadInt64(&v.i), 10)
 }
 
 func (v *Int) Add(delta int64) {
-	v.mu.Lock()
-	defer v.mu.Unlock()
-	v.i += delta
+	atomic.AddInt64(&v.i, delta)
 }
 
 func (v *Int) Set(value int64) {
-	v.mu.Lock()
-	defer v.mu.Unlock()
-	v.i = value
+	atomic.StoreInt64(&v.i, value)
 }
 
 // Float is a 64-bit float variable that satisfies the Var interface.
 type Float struct {
-	mu sync.RWMutex
-	f  float64
+	f uint64
 }
 
 func (v *Float) String() string {
-	v.mu.RLock()
-	defer v.mu.RUnlock()
-	return strconv.FormatFloat(v.f, 'g', -1, 64)
+	return strconv.FormatFloat(
+		math.Float64frombits(atomic.LoadUint64(&v.f)), 'g', -1, 64)
 }
 
 // Add adds delta to v.
 func (v *Float) Add(delta float64) {
-	v.mu.Lock()
-	defer v.mu.Unlock()
-	v.f += delta
+	for {
+		cur := atomic.LoadUint64(&v.f)
+		curVal := math.Float64frombits(cur)
+		nxtVal := curVal + delta
+		nxt := math.Float64bits(nxtVal)
+		if atomic.CompareAndSwapUint64(&v.f, cur, nxt) {
+			return
+		}
+	}
 }
 
 // Set sets v to value.
 func (v *Float) Set(value float64) {
-	v.mu.Lock()
-	defer v.mu.Unlock()
-	v.f = value
+	atomic.StoreUint64(&v.f, math.Float64bits(value))
 }
 
 // Map is a string-to-Var map variable that satisfies the Var interface.
diff --git a/third_party/gofrontend/libgo/go/expvar/expvar_test.go b/third_party/gofrontend/libgo/go/expvar/expvar_test.go
index 765e3b7..8bc633e 100644
--- a/third_party/gofrontend/libgo/go/expvar/expvar_test.go
+++ b/third_party/gofrontend/libgo/go/expvar/expvar_test.go
@@ -7,8 +7,13 @@
 import (
 	"bytes"
 	"encoding/json"
+	"math"
+	"net"
 	"net/http/httptest"
+	"runtime"
 	"strconv"
+	"sync"
+	"sync/atomic"
 	"testing"
 )
 
@@ -47,6 +52,30 @@
 	}
 }
 
+func BenchmarkIntAdd(b *testing.B) {
+	var v Int
+
+	b.RunParallel(func(pb *testing.PB) {
+		for pb.Next() {
+			v.Add(1)
+		}
+	})
+}
+
+func BenchmarkIntSet(b *testing.B) {
+	var v Int
+
+	b.RunParallel(func(pb *testing.PB) {
+		for pb.Next() {
+			v.Set(1)
+		}
+	})
+}
+
+func (v *Float) val() float64 {
+	return math.Float64frombits(atomic.LoadUint64(&v.f))
+}
+
 func TestFloat(t *testing.T) {
 	RemoveAll()
 	reqs := NewFloat("requests-float")
@@ -59,8 +88,8 @@
 
 	reqs.Add(1.5)
 	reqs.Add(1.25)
-	if reqs.f != 2.75 {
-		t.Errorf("reqs.f = %v, want 2.75", reqs.f)
+	if v := reqs.val(); v != 2.75 {
+		t.Errorf("reqs.val() = %v, want 2.75", v)
 	}
 
 	if s := reqs.String(); s != "2.75" {
@@ -68,11 +97,31 @@
 	}
 
 	reqs.Add(-2)
-	if reqs.f != 0.75 {
-		t.Errorf("reqs.f = %v, want 0.75", reqs.f)
+	if v := reqs.val(); v != 0.75 {
+		t.Errorf("reqs.val() = %v, want 0.75", v)
 	}
 }
 
+func BenchmarkFloatAdd(b *testing.B) {
+	var f Float
+
+	b.RunParallel(func(pb *testing.PB) {
+		for pb.Next() {
+			f.Add(1.0)
+		}
+	})
+}
+
+func BenchmarkFloatSet(b *testing.B) {
+	var f Float
+
+	b.RunParallel(func(pb *testing.PB) {
+		for pb.Next() {
+			f.Set(1.0)
+		}
+	})
+}
+
 func TestString(t *testing.T) {
 	RemoveAll()
 	name := NewString("my-name")
@@ -90,6 +139,16 @@
 	}
 }
 
+func BenchmarkStringSet(b *testing.B) {
+	var s String
+
+	b.RunParallel(func(pb *testing.PB) {
+		for pb.Next() {
+			s.Set("red")
+		}
+	})
+}
+
 func TestMapCounter(t *testing.T) {
 	RemoveAll()
 	colors := NewMap("bike-shed-colors")
@@ -104,8 +163,8 @@
 	if x := colors.m["blue"].(*Int).i; x != 4 {
 		t.Errorf("colors.m[\"blue\"] = %v, want 4", x)
 	}
-	if x := colors.m[`green "midori"`].(*Float).f; x != 4.125 {
-		t.Errorf("colors.m[`green \"midori\"] = %v, want 3.14", x)
+	if x := colors.m[`green "midori"`].(*Float).val(); x != 4.125 {
+		t.Errorf("colors.m[`green \"midori\"] = %v, want 4.125", x)
 	}
 
 	// colors.String() should be '{"red":3, "blue":4}',
@@ -130,6 +189,38 @@
 	}
 }
 
+func BenchmarkMapSet(b *testing.B) {
+	m := new(Map).Init()
+
+	v := new(Int)
+
+	b.RunParallel(func(pb *testing.PB) {
+		for pb.Next() {
+			m.Set("red", v)
+		}
+	})
+}
+
+func BenchmarkMapAddSame(b *testing.B) {
+	for i := 0; i < b.N; i++ {
+		m := new(Map).Init()
+		m.Add("red", 1)
+		m.Add("red", 1)
+		m.Add("red", 1)
+		m.Add("red", 1)
+	}
+}
+
+func BenchmarkMapAddDifferent(b *testing.B) {
+	for i := 0; i < b.N; i++ {
+		m := new(Map).Init()
+		m.Add("red", 1)
+		m.Add("blue", 1)
+		m.Add("green", 1)
+		m.Add("yellow", 1)
+	}
+}
+
 func TestFunc(t *testing.T) {
 	RemoveAll()
 	var x interface{} = []string{"a", "b"}
@@ -165,3 +256,135 @@
 		t.Errorf("HTTP handler wrote:\n%s\nWant:\n%s", got, want)
 	}
 }
+
+func BenchmarkRealworldExpvarUsage(b *testing.B) {
+	var (
+		bytesSent Int
+		bytesRead Int
+	)
+
+	// The benchmark creates GOMAXPROCS client/server pairs.
+	// Each pair creates 4 goroutines: client reader/writer and server reader/writer.
+	// The benchmark stresses concurrent reading and writing to the same connection.
+	// Such pattern is used in net/http and net/rpc.
+
+	b.StopTimer()
+
+	P := runtime.GOMAXPROCS(0)
+	N := b.N / P
+	W := 1000
+
+	// Setup P client/server connections.
+	clients := make([]net.Conn, P)
+	servers := make([]net.Conn, P)
+	ln, err := net.Listen("tcp", "127.0.0.1:0")
+	if err != nil {
+		b.Fatalf("Listen failed: %v", err)
+	}
+	defer ln.Close()
+	done := make(chan bool)
+	go func() {
+		for p := 0; p < P; p++ {
+			s, err := ln.Accept()
+			if err != nil {
+				b.Errorf("Accept failed: %v", err)
+				return
+			}
+			servers[p] = s
+		}
+		done <- true
+	}()
+	for p := 0; p < P; p++ {
+		c, err := net.Dial("tcp", ln.Addr().String())
+		if err != nil {
+			b.Fatalf("Dial failed: %v", err)
+		}
+		clients[p] = c
+	}
+	<-done
+
+	b.StartTimer()
+
+	var wg sync.WaitGroup
+	wg.Add(4 * P)
+	for p := 0; p < P; p++ {
+		// Client writer.
+		go func(c net.Conn) {
+			defer wg.Done()
+			var buf [1]byte
+			for i := 0; i < N; i++ {
+				v := byte(i)
+				for w := 0; w < W; w++ {
+					v *= v
+				}
+				buf[0] = v
+				n, err := c.Write(buf[:])
+				if err != nil {
+					b.Errorf("Write failed: %v", err)
+					return
+				}
+
+				bytesSent.Add(int64(n))
+			}
+		}(clients[p])
+
+		// Pipe between server reader and server writer.
+		pipe := make(chan byte, 128)
+
+		// Server reader.
+		go func(s net.Conn) {
+			defer wg.Done()
+			var buf [1]byte
+			for i := 0; i < N; i++ {
+				n, err := s.Read(buf[:])
+
+				if err != nil {
+					b.Errorf("Read failed: %v", err)
+					return
+				}
+
+				bytesRead.Add(int64(n))
+				pipe <- buf[0]
+			}
+		}(servers[p])
+
+		// Server writer.
+		go func(s net.Conn) {
+			defer wg.Done()
+			var buf [1]byte
+			for i := 0; i < N; i++ {
+				v := <-pipe
+				for w := 0; w < W; w++ {
+					v *= v
+				}
+				buf[0] = v
+				n, err := s.Write(buf[:])
+				if err != nil {
+					b.Errorf("Write failed: %v", err)
+					return
+				}
+
+				bytesSent.Add(int64(n))
+			}
+			s.Close()
+		}(servers[p])
+
+		// Client reader.
+		go func(c net.Conn) {
+			defer wg.Done()
+			var buf [1]byte
+			for i := 0; i < N; i++ {
+				n, err := c.Read(buf[:])
+
+				if err != nil {
+					b.Errorf("Read failed: %v", err)
+					return
+				}
+
+				bytesRead.Add(int64(n))
+			}
+			c.Close()
+		}(clients[p])
+	}
+	wg.Wait()
+}
diff --git a/third_party/gofrontend/libgo/go/flag/flag.go b/third_party/gofrontend/libgo/go/flag/flag.go
index 60aef5d..3abc80e 100644
--- a/third_party/gofrontend/libgo/go/flag/flag.go
+++ b/third_party/gofrontend/libgo/go/flag/flag.go
@@ -31,7 +31,7 @@
 		fmt.Println("ip has value ", *ip)
 		fmt.Println("flagvar has value ", flagvar)
 
-	After parsing, the arguments after the flag are available as the
+	After parsing, the arguments following the flags are available as the
 	slice flag.Args() or individually as flag.Arg(i).
 	The arguments are indexed from 0 through flag.NArg()-1.
 
@@ -235,6 +235,8 @@
 // If a Value has an IsBoolFlag() bool method returning true,
 // the command-line parser makes -name equivalent to -name=true
 // rather than using the next command-line argument.
+//
+// Set is called once, in command line order, for each flag present.
 type Value interface {
 	String() string
 	Set(string) error
@@ -249,13 +251,14 @@
 	Get() interface{}
 }
 
-// ErrorHandling defines how to handle flag parsing errors.
+// ErrorHandling defines how FlagSet.Parse behaves if the parse fails.
 type ErrorHandling int
 
+// These constants cause FlagSet.Parse to behave as described if the parse fails.
 const (
-	ContinueOnError ErrorHandling = iota
-	ExitOnError
-	PanicOnError
+	ContinueOnError ErrorHandling = iota // Return a descriptive error.
+	ExitOnError                          // Call os.Exit(2).
+	PanicOnError                         // Call panic with a descriptive error.
 )
 
 // A FlagSet represents a set of defined flags.  The zero value of a FlagSet
@@ -373,20 +376,110 @@
 	return CommandLine.Set(name, value)
 }
 
-// PrintDefaults prints, to standard error unless configured
-// otherwise, the default values of all defined flags in the set.
+// isZeroValue guesses whether the string represents the zero
+// value for a flag. It is not accurate but in practice works OK.
+func isZeroValue(value string) bool {
+	switch value {
+	case "false":
+		return true
+	case "":
+		return true
+	case "0":
+		return true
+	}
+	return false
+}
+
+// UnquoteUsage extracts a back-quoted name from the usage
+// string for a flag and returns it and the un-quoted usage.
+// Given "a `name` to show" it returns ("name", "a name to show").
+// If there are no back quotes, the name is an educated guess of the
+// type of the flag's value, or the empty string if the flag is boolean.
+func UnquoteUsage(flag *Flag) (name string, usage string) {
+	// Look for a back-quoted name, but avoid the strings package.
+	usage = flag.Usage
+	for i := 0; i < len(usage); i++ {
+		if usage[i] == '`' {
+			for j := i + 1; j < len(usage); j++ {
+				if usage[j] == '`' {
+					name = usage[i+1 : j]
+					usage = usage[:i] + name + usage[j+1:]
+					return name, usage
+				}
+			}
+			break // Only one back quote; use type name.
+		}
+	}
+	// No explicit name, so use type if we can find one.
+	name = "value"
+	switch flag.Value.(type) {
+	case boolFlag:
+		name = ""
+	case *durationValue:
+		name = "duration"
+	case *float64Value:
+		name = "float"
+	case *intValue, *int64Value:
+		name = "int"
+	case *stringValue:
+		name = "string"
+	case *uintValue, *uint64Value:
+		name = "uint"
+	}
+	return
+}
+
+// PrintDefaults prints to standard error the default values of all
+// defined command-line flags in the set. See the documentation for
+// the global function PrintDefaults for more information.
 func (f *FlagSet) PrintDefaults() {
 	f.VisitAll(func(flag *Flag) {
-		format := "  -%s=%s: %s\n"
-		if _, ok := flag.Value.(*stringValue); ok {
-			// put quotes on the value
-			format = "  -%s=%q: %s\n"
+		s := fmt.Sprintf("  -%s", flag.Name) // Two spaces before -; see next two comments.
+		name, usage := UnquoteUsage(flag)
+		if len(name) > 0 {
+			s += " " + name
 		}
-		fmt.Fprintf(f.out(), format, flag.Name, flag.DefValue, flag.Usage)
+		// Boolean flags of one ASCII letter are so common we
+		// treat them specially, putting their usage on the same line.
+		if len(s) <= 4 { // space, space, '-', 'x'.
+			s += "\t"
+		} else {
+			// Four spaces before the tab triggers good alignment
+			// for both 4- and 8-space tab stops.
+			s += "\n    \t"
+		}
+		s += usage
+		if !isZeroValue(flag.DefValue) {
+			if _, ok := flag.Value.(*stringValue); ok {
+				// put quotes on the value
+				s += fmt.Sprintf(" (default %q)", flag.DefValue)
+			} else {
+				s += fmt.Sprintf(" (default %v)", flag.DefValue)
+			}
+		}
+		fmt.Fprint(f.out(), s, "\n")
 	})
 }
 
-// PrintDefaults prints to standard error the default values of all defined command-line flags.
+// PrintDefaults prints, to standard error unless configured otherwise,
+// a usage message showing the default settings of all defined
+// command-line flags.
+// For an integer valued flag x, the default output has the form
+//	-x int
+//		usage-message-for-x (default 7)
+// The usage message will appear on a separate line for anything but
+// a bool flag with a one-byte name. For bool flags, the type is
+// omitted and if the flag name is one byte the usage message appears
+// on the same line. The parenthetical default is omitted if the
+// default is the zero value for the type. The listed type, here int,
+// can be changed by placing a back-quoted name in the flag's usage
+// string; the first such item in the message is taken to be a parameter
+// name to show in the message and the back quotes are stripped from
+// the message when displayed. For instance, given
+//	flag.String("I", "", "search `directory` for include files")
+// the output will be
+//	-I directory
+//		search directory for include files.
 func PrintDefaults() {
 	CommandLine.PrintDefaults()
 }
@@ -408,6 +501,8 @@
 // Usage prints to standard error a usage message documenting all defined command-line flags.
 // It is called when an error occurs while parsing flags.
 // The function is a variable that may be changed to point to a custom function.
+// By default it prints a simple header and calls PrintDefaults; for details about the
+// format of the output and how to control it, see the documentation for PrintDefaults.
 var Usage = func() {
 	fmt.Fprintf(os.Stderr, "Usage of %s:\n", os.Args[0])
 	PrintDefaults()
@@ -420,7 +515,8 @@
 func NFlag() int { return len(CommandLine.actual) }
 
 // Arg returns the i'th argument.  Arg(0) is the first remaining argument
-// after flags have been processed.
+// after flags have been processed. Arg returns an empty string if the
+// requested element does not exist.
 func (f *FlagSet) Arg(i int) string {
 	if i < 0 || i >= len(f.args) {
 		return ""
@@ -429,7 +525,8 @@
 }
 
 // Arg returns the i'th command-line argument.  Arg(0) is the first remaining argument
-// after flags have been processed.
+// after flags have been processed. Arg returns an empty string if the
+// requested element does not exist.
 func Arg(i int) string {
 	return CommandLine.Arg(i)
 }
@@ -726,27 +823,27 @@
 	if len(s) == 0 || s[0] != '-' || len(s) == 1 {
 		return false, nil
 	}
-	num_minuses := 1
+	numMinuses := 1
 	if s[1] == '-' {
-		num_minuses++
+		numMinuses++
 		if len(s) == 2 { // "--" terminates the flags
 			f.args = f.args[1:]
 			return false, nil
 		}
 	}
-	name := s[num_minuses:]
+	name := s[numMinuses:]
 	if len(name) == 0 || name[0] == '-' || name[0] == '=' {
 		return false, f.failf("bad flag syntax: %s", s)
 	}
 
 	// it's a flag. does it have an argument?
 	f.args = f.args[1:]
-	has_value := false
+	hasValue := false
 	value := ""
 	for i := 1; i < len(name); i++ { // equals cannot be first
 		if name[i] == '=' {
 			value = name[i+1:]
-			has_value = true
+			hasValue = true
 			name = name[0:i]
 			break
 		}
@@ -762,21 +859,23 @@
 	}
 
 	if fv, ok := flag.Value.(boolFlag); ok && fv.IsBoolFlag() { // special case: doesn't need an arg
-		if has_value {
+		if hasValue {
 			if err := fv.Set(value); err != nil {
 				return false, f.failf("invalid boolean value %q for -%s: %v", value, name, err)
 			}
 		} else {
-			fv.Set("true")
+			if err := fv.Set("true"); err != nil {
+				return false, f.failf("invalid boolean flag %s: %v", name, err)
+			}
 		}
 	} else {
 		// It must have a value, which might be the next argument.
-		if !has_value && len(f.args) > 0 {
+		if !hasValue && len(f.args) > 0 {
 			// value is the next arg
-			has_value = true
+			hasValue = true
 			value, f.args = f.args[0], f.args[1:]
 		}
-		if !has_value {
+		if !hasValue {
 			return false, f.failf("flag needs an argument: -%s", name)
 		}
 		if err := flag.Value.Set(value); err != nil {
@@ -829,7 +928,7 @@
 	CommandLine.Parse(os.Args[1:])
 }
 
-// Parsed returns true if the command-line flags have been parsed.
+// Parsed reports whether the command-line flags have been parsed.
 func Parsed() bool {
 	return CommandLine.Parsed()
 }
diff --git a/third_party/gofrontend/libgo/go/flag/flag_test.go b/third_party/gofrontend/libgo/go/flag/flag_test.go
index 8c88c8c..e2319ec 100644
--- a/third_party/gofrontend/libgo/go/flag/flag_test.go
+++ b/third_party/gofrontend/libgo/go/flag/flag_test.go
@@ -377,3 +377,41 @@
 		t.Fatal("help was called; should not have been for defined help flag")
 	}
 }
+
+const defaultOutput = `  -A	for bootstrapping, allow 'any' type
+  -Alongflagname
+    	disable bounds checking
+  -C	a boolean defaulting to true (default true)
+  -D path
+    	set relative path for local imports
+  -F number
+    	a non-zero number (default 2.7)
+  -G float
+    	a float that defaults to zero
+  -N int
+    	a non-zero int (default 27)
+  -Z int
+    	an int that defaults to zero
+  -maxT timeout
+    	set timeout for dial
+`
+
+func TestPrintDefaults(t *testing.T) {
+	fs := NewFlagSet("print defaults test", ContinueOnError)
+	var buf bytes.Buffer
+	fs.SetOutput(&buf)
+	fs.Bool("A", false, "for bootstrapping, allow 'any' type")
+	fs.Bool("Alongflagname", false, "disable bounds checking")
+	fs.Bool("C", true, "a boolean defaulting to true")
+	fs.String("D", "", "set relative `path` for local imports")
+	fs.Float64("F", 2.7, "a non-zero `number`")
+	fs.Float64("G", 0, "a float that defaults to zero")
+	fs.Int("N", 27, "a non-zero int")
+	fs.Int("Z", 0, "an int that defaults to zero")
+	fs.Duration("maxT", 0, "set `timeout` for dial")
+	fs.PrintDefaults()
+	got := buf.String()
+	if got != defaultOutput {
+		t.Errorf("got %q want %q\n", got, defaultOutput)
+	}
+}
diff --git a/third_party/gofrontend/libgo/go/fmt/doc.go b/third_party/gofrontend/libgo/go/fmt/doc.go
index ee54463..ef91368 100644
--- a/third_party/gofrontend/libgo/go/fmt/doc.go
+++ b/third_party/gofrontend/libgo/go/fmt/doc.go
@@ -40,7 +40,7 @@
 		%F	synonym for %f
 		%g	%e for large exponents, %f otherwise
 		%G	%E for large exponents, %F otherwise
-	String and slice of bytes:
+	String and slice of bytes (treated equivalently with these verbs):
 		%s	the uninterpreted bytes of the string or slice
 		%q	a double-quoted string safely escaped with Go syntax
 		%x	base 16, lower-case, two characters per byte
@@ -66,13 +66,13 @@
 		maps:               map[key1:value1 key2:value2]
 		pointer to above:   &{}, &[], &map[]
 
-	Width is specified by an optional decimal number immediately following the verb.
+	Width is specified by an optional decimal number immediately preceding the verb.
 	If absent, the width is whatever is necessary to represent the value.
 	Precision is specified after the (optional) width by a period followed by a
 	decimal number. If no period is present, a default precision is used.
 	A period with no following number specifies a precision of zero.
 	Examples:
-		%f:    default width, default precision
+		%f     default width, default precision
 		%9f    width 9, default precision
 		%.2f   default width, precision 2
 		%9.2f  width 9, precision 2
@@ -138,20 +138,23 @@
 	formatting considerations apply for operands that implement
 	certain interfaces. In order of application:
 
-	1. If an operand implements the Formatter interface, it will
+	1. If the operand is a reflect.Value, the concrete value it
+	holds is printed as if it was the operand.
+
+	2. If an operand implements the Formatter interface, it will
 	be invoked. Formatter provides fine control of formatting.
 
-	2. If the %v verb is used with the # flag (%#v) and the operand
+	3. If the %v verb is used with the # flag (%#v) and the operand
 	implements the GoStringer interface, that will be invoked.
 
 	If the format (which is implicitly %v for Println etc.) is valid
 	for a string (%s %q %v %x %X), the following two rules apply:
 
-	3. If an operand implements the error interface, the Error method
+	4. If an operand implements the error interface, the Error method
 	will be invoked to convert the object to a string, which will then
 	be formatted as required by the verb (if any).
 
-	4. If an operand implements method String() string, that method
+	5. If an operand implements method String() string, that method
 	will be invoked to convert the object to a string, which will then
 	be formatted as required by the verb (if any).
 
@@ -161,6 +164,9 @@
 	of strings, and %6.2f will control formatting for each element
 	of a floating-point array.
 
+	However, when printing a byte slice with a string-like verb
+	(%s %q %x %X), it is treated identically to a string, as a single item.
+
 	To avoid recursion in cases such as
 		type X string
 		func (x X) String() string { return Sprintf("<%s>", x) }
@@ -178,8 +184,8 @@
 	However, the notation [n] immediately before the verb indicates that the
 	nth one-indexed argument is to be formatted instead. The same notation
 	before a '*' for a width or precision selects the argument index holding
-	the value. After processing a bracketed expression [n], arguments n+1,
-	n+2, etc. will be processed unless otherwise directed.
+	the value. After processing a bracketed expression [n], subsequent verbs
+	will use arguments n+1, n+2, etc. unless otherwise directed.
 
 	For example,
 		fmt.Sprintf("%[2]d %[1]d\n", 11, 22)
@@ -225,18 +231,33 @@
 		%!s(PANIC=bad)
 
 	The %!s just shows the print verb in use when the failure
-	occurred.
+	occurred. If the panic is caused by a nil receiver to an Error
+	or String method, however, the output is the undecorated
+	string, "<nil>".
 
 	Scanning
 
 	An analogous set of functions scans formatted text to yield
 	values.  Scan, Scanf and Scanln read from os.Stdin; Fscan,
 	Fscanf and Fscanln read from a specified io.Reader; Sscan,
-	Sscanf and Sscanln read from an argument string.  Scanln,
-	Fscanln and Sscanln stop scanning at a newline and require that
-	the items be followed by one; Scanf, Fscanf and Sscanf require
-	newlines in the input to match newlines in the format; the other
-	routines treat newlines as spaces.
+	Sscanf and Sscanln read from an argument string.
+
+	Scan, Fscan, Sscan treat newlines in the input as spaces.
+
+	Scanln, Fscanln and Sscanln stop scanning at a newline and
+	require that the items be followed by a newline or EOF.
+
+	Scanf, Fscanf and Sscanf require that (after skipping spaces)
+	newlines in the format are matched by newlines in the input
+	and vice versa.  This behavior differs from the corresponding
+	routines in C, which uniformly treat newlines as spaces.
+
+	When scanning with Scanf, Fscanf, and Sscanf, all non-empty
+	runs of space characters (except newline) are equivalent
+	to a single space in both the format and the input.  With
+	that proviso, text in the format string must match the input
+	text; scanning stops if it does not, with the return value
+	of the function indicating the number of arguments scanned.
 
 	Scanf, Fscanf, and Sscanf parse the arguments according to a
 	format string, analogous to that of Printf.  For example, %x
@@ -253,20 +274,18 @@
 		Flags # and + are not implemented.
 
 	The familiar base-setting prefixes 0 (octal) and 0x
-	(hexadecimal) are accepted when scanning integers without a
-	format or with the %v verb.
+	(hexadecimal) are accepted when scanning integers without
+	a format or with the %v verb.
 
-	Width is interpreted in the input text (%5s means at most
-	five runes of input will be read to scan a string) but there
-	is no syntax for scanning with a precision (no %5.2f, just
-	%5f).
-
-	When scanning with a format, all non-empty runs of space
-	characters (except newline) are equivalent to a single
-	space in both the format and the input.  With that proviso,
-	text in the format string must match the input text; scanning
-	stops if it does not, with the return value of the function
-	indicating the number of arguments scanned.
+	Width is interpreted in the input text but there is no
+	syntax for scanning with a precision (no %5.2f, just %5f).
+	If width is provided, it applies after leading spaces are
+	trimmed and specifies the maximum number of runes to read
+	to satisfy the verb. For example,
+	   Sscanf(" 1234567 ", "%5s%d", &s, &i)
+	will set s to "12345" and i to 67 while
+	   Sscanf(" 12 34 567 ", "%5s%d", &s, &i)
+	will set s to "12" and i to 34.
 
 	In all the scanning functions, a carriage return followed
 	immediately by a newline is treated as a plain newline
diff --git a/third_party/gofrontend/libgo/go/fmt/fmt_test.go b/third_party/gofrontend/libgo/go/fmt/fmt_test.go
index ccd8090..8f3587b 100644
--- a/third_party/gofrontend/libgo/go/fmt/fmt_test.go
+++ b/third_party/gofrontend/libgo/go/fmt/fmt_test.go
@@ -9,6 +9,7 @@
 	. "fmt"
 	"io"
 	"math"
+	"reflect"
 	"runtime"
 	"strings"
 	"testing"
@@ -135,27 +136,33 @@
 
 	// basic string
 	{"%s", "abc", "abc"},
+	{"%q", "abc", `"abc"`},
 	{"%x", "abc", "616263"},
+	{"%x", "\xff\xf0\x0f\xff", "fff00fff"},
+	{"%X", "\xff\xf0\x0f\xff", "FFF00FFF"},
 	{"%x", "xyz", "78797a"},
 	{"%X", "xyz", "78797A"},
-	{"%q", "abc", `"abc"`},
-	{"%#x", []byte("abc\xff"), "0x616263ff"},
-	{"%#X", []byte("abc\xff"), "0X616263FF"},
-	{"%# x", []byte("abc\xff"), "0x61 0x62 0x63 0xff"},
-	{"%# X", []byte("abc\xff"), "0X61 0X62 0X63 0XFF"},
+	{"% x", "xyz", "78 79 7a"},
+	{"% X", "xyz", "78 79 7A"},
+	{"%#x", "xyz", "0x78797a"},
+	{"%#X", "xyz", "0X78797A"},
+	{"%# x", "xyz", "0x78 0x79 0x7a"},
+	{"%# X", "xyz", "0X78 0X79 0X7A"},
 
 	// basic bytes
 	{"%s", []byte("abc"), "abc"},
+	{"%q", []byte("abc"), `"abc"`},
 	{"%x", []byte("abc"), "616263"},
-	{"% x", []byte("abc\xff"), "61 62 63 ff"},
-	{"%#x", []byte("abc\xff"), "0x616263ff"},
-	{"%#X", []byte("abc\xff"), "0X616263FF"},
-	{"%# x", []byte("abc\xff"), "0x61 0x62 0x63 0xff"},
-	{"%# X", []byte("abc\xff"), "0X61 0X62 0X63 0XFF"},
-	{"% X", []byte("abc\xff"), "61 62 63 FF"},
+	{"%x", []byte("\xff\xf0\x0f\xff"), "fff00fff"},
+	{"%X", []byte("\xff\xf0\x0f\xff"), "FFF00FFF"},
 	{"%x", []byte("xyz"), "78797a"},
 	{"%X", []byte("xyz"), "78797A"},
-	{"%q", []byte("abc"), `"abc"`},
+	{"% x", []byte("xyz"), "78 79 7a"},
+	{"% X", []byte("xyz"), "78 79 7A"},
+	{"%#x", []byte("xyz"), "0x78797a"},
+	{"%#X", []byte("xyz"), "0X78797A"},
+	{"%# x", []byte("xyz"), "0x78 0x79 0x7a"},
+	{"%# X", []byte("xyz"), "0X78 0X79 0X7A"},
 
 	// escaped strings
 	{"%#q", `abc`, "`abc`"},
@@ -388,6 +395,8 @@
 	{"%v", &slice, "&[1 2 3 4 5]"},
 	{"%v", &islice, "&[1 hello 2.5 <nil>]"},
 	{"%v", &bslice, "&[1 2 3 4 5]"},
+	{"%v", []byte{1}, "[1]"},
+	{"%v", []byte{}, "[]"},
 
 	// complexes with %v
 	{"%v", 1 + 2i, "(1+2i)"},
@@ -441,6 +450,32 @@
 	{"%d", []int{1, 2, 15}, `[1 2 15]`},
 	{"%d", []byte{1, 2, 15}, `[1 2 15]`},
 	{"%q", []string{"a", "b"}, `["a" "b"]`},
+	{"% 02x", []byte{1}, "01"},
+	{"% 02x", []byte{1, 2, 3}, "01 02 03"},
+	// Padding with byte slices.
+	{"%x", []byte{}, ""},
+	{"%02x", []byte{}, "00"},
+	{"% 02x", []byte{}, "00"},
+	{"%08x", []byte{0xab}, "000000ab"},
+	{"% 08x", []byte{0xab}, "000000ab"},
+	{"%08x", []byte{0xab, 0xcd}, "0000abcd"},
+	{"% 08x", []byte{0xab, 0xcd}, "000ab cd"},
+	{"%8x", []byte{0xab}, "      ab"},
+	{"% 8x", []byte{0xab}, "      ab"},
+	{"%8x", []byte{0xab, 0xcd}, "    abcd"},
+	{"% 8x", []byte{0xab, 0xcd}, "   ab cd"},
+	// Same for strings
+	{"%x", "", ""},
+	{"%02x", "", "00"},
+	{"% 02x", "", "00"},
+	{"%08x", "\xab", "000000ab"},
+	{"% 08x", "\xab", "000000ab"},
+	{"%08x", "\xab\xcd", "0000abcd"},
+	{"% 08x", "\xab\xcd", "000ab cd"},
+	{"%8x", "\xab", "      ab"},
+	{"% 8x", "\xab", "      ab"},
+	{"%8x", "\xab\xcd", "    abcd"},
+	{"% 8x", "\xab\xcd", "   ab cd"},
 
 	// renamings
 	{"%v", renamedBool(true), "true"},
@@ -522,6 +557,8 @@
 	{"%s", nil, "%!s(<nil>)"},
 	{"%T", nil, "<nil>"},
 	{"%-1", 100, "%!(NOVERB)%!(EXTRA int=100)"},
+	{"%017091901790959340919092959340919017929593813360", 0, "%!(NOVERB)%!(EXTRA int=0)"},
+	{"%184467440737095516170v", 0, "%!(NOVERB)%!(EXTRA int=0)"},
 
 	// The "<nil>" show up because maps are printed by
 	// first obtaining a list of keys and then looking up
@@ -540,6 +577,15 @@
 	{"%0.100f", 1.0, zeroFill("1.", 100, "")},
 	{"%0.100f", -1.0, zeroFill("-1.", 100, "")},
 
+	// Used to panic: integer function didn't look at f.prec, f.unicode, f.width or sign.
+	{"%#.80x", 42, "0x0000000000000000000000000000000000000000000000000000000000000000000000000000002a"},
+	{"%.80U", 42, "U+0000000000000000000000000000000000000000000000000000000000000000000000000000002A"},
+	{"%#.80U", '日', "U+000000000000000000000000000000000000000000000000000000000000000000000000000065E5 '日'"},
+	{"%.65d", -44, "-00000000000000000000000000000000000000000000000000000000000000044"},
+	{"%+.65d", 44, "+00000000000000000000000000000000000000000000000000000000000000044"},
+	{"% .65d", 44, " 00000000000000000000000000000000000000000000000000000000000000044"},
+	{"%  +.65d", 44, "+00000000000000000000000000000000000000000000000000000000000000044"},
+
 	// Comparison of padding rules with C printf.
 	/*
 		C program:
@@ -665,6 +711,20 @@
 	{"%x", byteFormatterSlice, "61626364"},
 	// This next case seems wrong, but the docs say the Formatter wins here.
 	{"%#v", byteFormatterSlice, "[]fmt_test.byteFormatter{X, X, X, X}"},
+
+	// reflect.Value handled specially in Go 1.5, making it possible to
+	// see inside non-exported fields (which cannot be accessed with Interface()).
+	// Issue 8965.
+	{"%v", reflect.ValueOf(A{}).Field(0).String(), "<int Value>"}, // Equivalent to the old way.
+	{"%v", reflect.ValueOf(A{}).Field(0), "0"},                    // Sees inside the field.
+
+	// verbs apply to the extracted value too.
+	{"%s", reflect.ValueOf("hello"), "hello"},
+	{"%q", reflect.ValueOf("hello"), `"hello"`},
+	{"%#04x", reflect.ValueOf(256), "0x0100"},
+
+	// invalid reflect.Value doesn't crash.
+	{"%v", reflect.Value{}, "<invalid reflect.Value>"},
 }
 
 // zeroFill generates zero-filled strings of the specified width. The length
@@ -791,6 +851,11 @@
 	{"%d %d %d %#[1]o %#o %#o %#o", SE{11, 12, 13}, "11 12 13 013 014 015 %!o(MISSING)"},
 	{"%[5]d %[2]d %d", SE{1, 2, 3}, "%!d(BADINDEX) 2 3"},
 	{"%d %[3]d %d", SE{1, 2}, "1 %!d(BADINDEX) 2"}, // Erroneous index does not affect sequence.
+	{"%.[]", SE{}, "%!](BADINDEX)"},                // Issue 10675
+	{"%.-3d", SE{42}, "%!-(int=42)3d"},             // TODO: Should this set return better error messages?
+	{"%2147483648d", SE{42}, "%!(NOVERB)%!(EXTRA int=42)"},
+	{"%-2147483648d", SE{42}, "%!(NOVERB)%!(EXTRA int=42)"},
+	{"%.2147483648d", SE{42}, "%!(NOVERB)%!(EXTRA int=42)"},
 }
 
 func TestReorder(t *testing.T) {
@@ -869,6 +934,15 @@
 	}
 }
 
+func BenchmarkFprintfBytes(b *testing.B) {
+	data := []byte(string("0123456789"))
+	var buf bytes.Buffer
+	for i := 0; i < b.N; i++ {
+		buf.Reset()
+		Fprintf(&buf, "%s", data)
+	}
+}
+
 func BenchmarkFprintIntNoAlloc(b *testing.B) {
 	var x interface{} = 123456
 	var buf bytes.Buffer
@@ -905,11 +979,13 @@
 var _ bytes.Buffer
 
 func TestCountMallocs(t *testing.T) {
-	if testing.Short() {
+	switch {
+	case testing.Short():
 		t.Skip("skipping malloc count in short mode")
-	}
-	if runtime.GOMAXPROCS(0) > 1 {
+	case runtime.GOMAXPROCS(0) > 1:
 		t.Skip("skipping; GOMAXPROCS>1")
+	case raceenabled:
+		t.Skip("skipping malloc count under race detector")
 	}
 	for _, mt := range mallocTest {
 		mallocs := testing.AllocsPerRun(100, mt.fn)
@@ -1108,14 +1184,20 @@
 	out string
 }{
 	{"%*d", args(4, 42), "  42"},
+	{"%-*d", args(4, 42), "42  "},
+	{"%*d", args(-4, 42), "42  "},
+	{"%-*d", args(-4, 42), "42  "},
 	{"%.*d", args(4, 42), "0042"},
 	{"%*.*d", args(8, 4, 42), "    0042"},
 	{"%0*d", args(4, 42), "0042"},
-	{"%-*d", args(4, 42), "42  "},
 
 	// erroneous
 	{"%*d", args(nil, 42), "%!(BADWIDTH)42"},
+	{"%*d", args(int(1e7), 42), "%!(BADWIDTH)42"},
+	{"%*d", args(int(-1e7), 42), "%!(BADWIDTH)42"},
 	{"%.*d", args(nil, 42), "%!(BADPREC)42"},
+	{"%.*d", args(-1, 42), "%!(BADPREC)42"},
+	{"%.*d", args(int(1e7), 42), "%!(BADPREC)42"},
 	{"%*d", args(5, "foo"), "%!d(string=  foo)"},
 	{"%*% %d", args(20, 5), "% 5"},
 	{"%*", args(4), "%!(NOVERB)"},
@@ -1233,7 +1315,7 @@
 	type B struct{}
 	var a *A = nil
 	var b B = B{}
-	got := Sprintf("%s %s %s %s %s", nil, a, nil, b, nil)
+	got := Sprintf("%s %s %s %s %s", nil, a, nil, b, nil) // go vet should complain about this line.
 	const expect = "%!s(<nil>) %!s(*fmt_test.A=<nil>) %!s(<nil>) {} %!s(<nil>)"
 	if got != expect {
 		t.Errorf("expected:\n\t%q\ngot:\n\t%q", expect, got)
diff --git a/third_party/gofrontend/libgo/go/fmt/format.go b/third_party/gofrontend/libgo/go/fmt/format.go
index 4d97d14..517b18f 100644
--- a/third_party/gofrontend/libgo/go/fmt/format.go
+++ b/third_party/gofrontend/libgo/go/fmt/format.go
@@ -162,24 +162,35 @@
 		return
 	}
 
+	negative := signedness == signed && a < 0
+	if negative {
+		a = -a
+	}
+
 	var buf []byte = f.intbuf[0:]
-	if f.widPresent {
-		width := f.wid
+	if f.widPresent || f.precPresent || f.plus || f.space {
+		width := f.wid + f.prec // Only one will be set, both are positive; this provides the maximum.
 		if base == 16 && f.sharp {
 			// Also adds "0x".
 			width += 2
 		}
+		if f.unicode {
+			// Also adds "U+".
+			width += 2
+			if f.uniQuote {
+				// Also adds " 'x'".
+				width += 1 + 1 + utf8.UTFMax + 1
+			}
+		}
+		if negative || f.plus || f.space {
+			width++
+		}
 		if width > nByte {
 			// We're going to need a bigger boat.
 			buf = make([]byte, width)
 		}
 	}
 
-	negative := signedness == signed && a < 0
-	if negative {
-		a = -a
-	}
-
 	// two ways to ask for extra leading zero digits: %.3d or %03d.
 	// apparently the first cancels the second.
 	prec := 0
diff --git a/third_party/gofrontend/libgo/go/fmt/norace_test.go b/third_party/gofrontend/libgo/go/fmt/norace_test.go
new file mode 100644
index 0000000..1267cc3
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/fmt/norace_test.go
@@ -0,0 +1,9 @@
+// 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 !race
+
+package fmt_test
+
+const raceenabled = false
diff --git a/third_party/gofrontend/libgo/go/fmt/print.go b/third_party/gofrontend/libgo/go/fmt/print.go
index 59a30d2..8d3e97c 100644
--- a/third_party/gofrontend/libgo/go/fmt/print.go
+++ b/third_party/gofrontend/libgo/go/fmt/print.go
@@ -285,12 +285,22 @@
 	return val
 }
 
+// tooLarge reports whether the magnitude of the integer is
+// too large to be used as a formatting width or precision.
+func tooLarge(x int) bool {
+	const max int = 1e6
+	return x > max || x < -max
+}
+
 // parsenum converts ASCII to integer.  num is 0 (and isnum is false) if no number present.
 func parsenum(s string, start, end int) (num int, isnum bool, newi int) {
 	if start >= end {
 		return 0, false, end
 	}
 	for newi = start; newi < end && '0' <= s[newi] && s[newi] <= '9'; newi++ {
+		if tooLarge(num) {
+			return 0, false, end // Overflow; crazy long number most likely.
+		}
 		num = num*10 + int(s[newi]-'0')
 		isnum = true
 	}
@@ -789,6 +799,8 @@
 	case []byte:
 		p.fmtBytes(f, verb, nil, depth)
 		wasString = verb == 's'
+	case reflect.Value:
+		return p.printReflectValue(f, verb, depth)
 	default:
 		// If the type is not simple, it might have methods.
 		if handled := p.handleMethods(verb, depth); handled {
@@ -845,6 +857,8 @@
 	p.value = value
 BigSwitch:
 	switch f := value; f.Kind() {
+	case reflect.Invalid:
+		p.buf.WriteString("<invalid reflect.Value>")
 	case reflect.Bool:
 		p.fmtBool(f.Bool(), verb)
 	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
@@ -1016,6 +1030,10 @@
 	if argNum < len(a) {
 		num, isInt = a[argNum].(int)
 		newArgNum = argNum + 1
+		if tooLarge(num) {
+			num = 0
+			isInt = false
+		}
 	}
 	return
 }
@@ -1027,6 +1045,11 @@
 // up to the closing paren, if present, and whether the number parsed
 // ok. The bytes to consume will be 1 if no closing paren is present.
 func parseArgNumber(format string) (index int, wid int, ok bool) {
+	// There must be at least 3 bytes: [n].
+	if len(format) < 3 {
+		return 0, 1, false
+	}
+
 	// Find closing bracket.
 	for i := 1; i < len(format); i++ {
 		if format[i] == ']' {
@@ -1053,7 +1076,7 @@
 		return index, i + wid, true
 	}
 	p.goodArgNum = false
-	return argNum, i + wid, true
+	return argNum, i + wid, ok
 }
 
 func (p *pp) doPrintf(format string, a []interface{}) {
@@ -1105,9 +1128,17 @@
 		if i < end && format[i] == '*' {
 			i++
 			p.fmt.wid, p.fmt.widPresent, argNum = intFromArg(a, argNum)
+
 			if !p.fmt.widPresent {
 				p.buf.Write(badWidthBytes)
 			}
+
+			// We have a negative width, so take its value and ensure
+			// that the minus flag is set
+			if p.fmt.wid < 0 {
+				p.fmt.wid = -p.fmt.wid
+				p.fmt.minus = true
+			}
 			afterIndex = false
 		} else {
 			p.fmt.wid, p.fmt.widPresent, i = parsenum(format, i, end)
@@ -1123,9 +1154,14 @@
 				p.goodArgNum = false
 			}
 			argNum, i, afterIndex = p.argNumber(argNum, format, i, len(a))
-			if format[i] == '*' {
+			if i < end && format[i] == '*' {
 				i++
 				p.fmt.prec, p.fmt.precPresent, argNum = intFromArg(a, argNum)
+				// Negative precision arguments don't make sense
+				if p.fmt.prec < 0 {
+					p.fmt.prec = 0
+					p.fmt.precPresent = false
+				}
 				if !p.fmt.precPresent {
 					p.buf.Write(badPrecBytes)
 				}
diff --git a/third_party/gofrontend/libgo/go/fmt/race_test.go b/third_party/gofrontend/libgo/go/fmt/race_test.go
new file mode 100644
index 0000000..ae3147a
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/fmt/race_test.go
@@ -0,0 +1,9 @@
+// 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 race
+
+package fmt_test
+
+const raceenabled = true
diff --git a/third_party/gofrontend/libgo/go/fmt/scan.go b/third_party/gofrontend/libgo/go/fmt/scan.go
index d7befea..e3e0fd0 100644
--- a/third_party/gofrontend/libgo/go/fmt/scan.go
+++ b/third_party/gofrontend/libgo/go/fmt/scan.go
@@ -34,16 +34,16 @@
 	ReadRune() (r rune, size int, err error)
 	// UnreadRune causes the next call to ReadRune to return the same rune.
 	UnreadRune() error
-	// SkipSpace skips space in the input. Newlines are treated as space
-	// unless the scan operation is Scanln, Fscanln or Sscanln, in which case
-	// a newline is treated as EOF.
+	// SkipSpace skips space in the input. Newlines are treated appropriately
+	// for the operation being performed; see the package documentation
+	// for more information.
 	SkipSpace()
 	// Token skips space in the input if skipSpace is true, then returns the
 	// run of Unicode code points c satisfying f(c).  If f is nil,
 	// !unicode.IsSpace(c) is used; that is, the token will hold non-space
-	// characters.  Newlines are treated as space unless the scan operation
-	// is Scanln, Fscanln or Sscanln, in which case a newline is treated as
-	// EOF.  The returned slice points to shared data that may be overwritten
+	// characters.  Newlines are treated appropriately for the operation being
+	// performed; see the package documentation for more information.
+	// The returned slice points to shared data that may be overwritten
 	// by the next call to Token, a call to a Scan function using the ScanState
 	// as input, or when the calling Scan method returns.
 	Token(skipSpace bool, f func(rune) bool) (token []byte, err error)
@@ -81,6 +81,10 @@
 // Scanf scans text read from standard input, storing successive
 // space-separated values into successive arguments as determined by
 // the format.  It returns the number of items successfully scanned.
+// If that is less than the number of arguments, err will report why.
+// Newlines in the input must match newlines in the format.
+// The one exception: the verb %c always scans the next rune in the
+// input, even if it is a space (or tab etc.) or newline.
 func Scanf(format string, a ...interface{}) (n int, err error) {
 	return Fscanf(os.Stdin, format, a...)
 }
@@ -113,6 +117,7 @@
 // Sscanf scans the argument string, storing successive space-separated
 // values into successive arguments as determined by the format.  It
 // returns the number of items successfully parsed.
+// Newlines in the input must match newlines in the format.
 func Sscanf(str string, format string, a ...interface{}) (n int, err error) {
 	return Fscanf((*stringReader)(&str), format, a...)
 }
@@ -140,6 +145,7 @@
 // Fscanf scans text read from r, storing successive space-separated
 // values into successive arguments as determined by the format.  It
 // returns the number of items successfully parsed.
+// Newlines in the input must match newlines in the format.
 func Fscanf(r io.Reader, format string, a ...interface{}) (n int, err error) {
 	s, old := newScanState(r, false, false)
 	n, err = s.doScanf(format, a)
@@ -387,17 +393,6 @@
 
 // newScanState allocates a new ss struct or grab a cached one.
 func newScanState(r io.Reader, nlIsSpace, nlIsEnd bool) (s *ss, old ssave) {
-	// If the reader is a *ss, then we've got a recursive
-	// call to Scan, so re-use the scan state.
-	s, ok := r.(*ss)
-	if ok {
-		old = s.ssave
-		s.limit = s.argLimit
-		s.nlIsEnd = nlIsEnd || s.nlIsEnd
-		s.nlIsSpace = nlIsSpace
-		return
-	}
-
 	s = ssFree.Get().(*ss)
 	if rr, ok := r.(io.RuneReader); ok {
 		s.rr = rr
@@ -875,34 +870,39 @@
 	return ""
 }
 
-// hexDigit returns the value of the hexadecimal digit
-func (s *ss) hexDigit(d rune) int {
+// hexDigit returns the value of the hexadecimal digit.
+func hexDigit(d rune) (int, bool) {
 	digit := int(d)
 	switch digit {
 	case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':
-		return digit - '0'
+		return digit - '0', true
 	case 'a', 'b', 'c', 'd', 'e', 'f':
-		return 10 + digit - 'a'
+		return 10 + digit - 'a', true
 	case 'A', 'B', 'C', 'D', 'E', 'F':
-		return 10 + digit - 'A'
+		return 10 + digit - 'A', true
 	}
-	s.errorString("illegal hex digit")
-	return 0
+	return -1, false
 }
 
 // hexByte returns the next hex-encoded (two-character) byte from the input.
-// There must be either two hexadecimal digits or a space character in the input.
+// It returns ok==false if the next bytes in the input do not encode a hex byte.
+// If the first byte is hex and the second is not, processing stops.
 func (s *ss) hexByte() (b byte, ok bool) {
 	rune1 := s.getRune()
 	if rune1 == eof {
 		return
 	}
-	if isSpace(rune1) {
+	value1, ok := hexDigit(rune1)
+	if !ok {
 		s.UnreadRune()
 		return
 	}
-	rune2 := s.mustReadRune()
-	return byte(s.hexDigit(rune1)<<4 | s.hexDigit(rune2)), true
+	value2, ok := hexDigit(s.mustReadRune())
+	if !ok {
+		s.errorString("illegal hex digit")
+		return
+	}
+	return byte(value1<<4 | value2), true
 }
 
 // hexString returns the space-delimited hexpair-encoded string.
@@ -1050,8 +1050,8 @@
 		s.scanOne('v', arg)
 		numProcessed++
 	}
-	// Check for newline if required.
-	if !s.nlIsSpace {
+	// Check for newline (or EOF) if required (Scanln etc.).
+	if s.nlIsEnd {
 		for {
 			r := s.getRune()
 			if r == '\n' || r == eof {
@@ -1067,12 +1067,13 @@
 }
 
 // advance determines whether the next characters in the input match
-// those of the format.  It returns the number of bytes (sic) consumed
-// in the format. Newlines included, all runs of space characters in
-// either input or format behave as a single space. This routine also
-// handles the %% case.  If the return value is zero, either format
-// starts with a % (with no following %) or the input is empty.
-// If it is negative, the input did not match the string.
+// those of the format. It returns the number of bytes (sic) consumed
+// in the format. All runs of space characters in either input or
+// format behave as a single space. Newlines are special, though:
+// newlines in the format must match those in the input and vice versa.
+// This routine also handles the %% case. If the return value is zero,
+// either format starts with a % (with no following %) or the input
+// is empty. If it is negative, the input did not match the string.
 func (s *ss) advance(format string) (i int) {
 	for i < len(format) {
 		fmtc, w := utf8.DecodeRuneInString(format[i:])
@@ -1085,24 +1086,45 @@
 			i += w // skip the first %
 		}
 		sawSpace := false
+		wasNewline := false
+		// Skip spaces in format but absorb at most one newline.
 		for isSpace(fmtc) && i < len(format) {
+			if fmtc == '\n' {
+				if wasNewline { // Already saw one; stop here.
+					break
+				}
+				wasNewline = true
+			}
 			sawSpace = true
 			i += w
 			fmtc, w = utf8.DecodeRuneInString(format[i:])
 		}
 		if sawSpace {
-			// There was space in the format, so there should be space (EOF)
+			// There was space in the format, so there should be space
 			// in the input.
 			inputc := s.getRune()
-			if inputc == eof || inputc == '\n' {
-				// If we've reached a newline, stop now; don't read ahead.
+			if inputc == eof {
 				return
 			}
 			if !isSpace(inputc) {
-				// Space in format but not in input: error
+				// Space in format but not in input.
 				s.errorString("expected space in input to match format")
 			}
-			s.skipSpace(true)
+			// Skip spaces but stop at newline.
+			for inputc != '\n' && isSpace(inputc) {
+				inputc = s.getRune()
+			}
+			if inputc == '\n' {
+				if !wasNewline {
+					s.errorString("newline in input does not match format")
+				}
+				// We've reached a newline, stop now; don't read further.
+				return
+			}
+			s.UnreadRune()
+			if wasNewline {
+				s.errorString("newline in format does not match input")
+			}
 			continue
 		}
 		inputc := s.mustReadRune()
@@ -1144,14 +1166,18 @@
 		if !widPresent {
 			s.maxWid = hugeWid
 		}
+
+		c, w := utf8.DecodeRuneInString(format[i:])
+		i += w
+
+		if c != 'c' {
+			s.SkipSpace()
+		}
 		s.argLimit = s.limit
 		if f := s.count + s.maxWid; f < s.argLimit {
 			s.argLimit = f
 		}
 
-		c, w := utf8.DecodeRuneInString(format[i:])
-		i += w
-
 		if numProcessed >= len(a) { // out of operands
 			s.errorString("too few operands for format %" + format[i-w:])
 			break
diff --git a/third_party/gofrontend/libgo/go/fmt/scan_test.go b/third_party/gofrontend/libgo/go/fmt/scan_test.go
index 541e12d..334c4a6 100644
--- a/third_party/gofrontend/libgo/go/fmt/scan_test.go
+++ b/third_party/gofrontend/libgo/go/fmt/scan_test.go
@@ -300,10 +300,13 @@
 	{"%2s", "sssss", &xVal, Xs("ss")},
 
 	// Fixed bugs
-	{"%d\n", "27\n", &intVal, 27},  // ok
-	{"%d\n", "28 \n", &intVal, 28}, // was: "unexpected newline"
-	{"%v", "0", &intVal, 0},        // was: "EOF"; 0 was taken as base prefix and not counted.
-	{"%v", "0", &uintVal, uint(0)}, // was: "EOF"; 0 was taken as base prefix and not counted.
+	{"%d\n", "27\n", &intVal, 27},      // ok
+	{"%d\n", "28 \n", &intVal, 28},     // was: "unexpected newline"
+	{"%v", "0", &intVal, 0},            // was: "EOF"; 0 was taken as base prefix and not counted.
+	{"%v", "0", &uintVal, uint(0)},     // was: "EOF"; 0 was taken as base prefix and not counted.
+	{"%c", " ", &uintVal, uint(' ')},   // %c must accept a blank.
+	{"%c", "\t", &uintVal, uint('\t')}, // %c must accept any space.
+	{"%c", "\n", &uintVal, uint('\n')}, // %c must accept any space.
 }
 
 var overflowTests = []ScanTest{
@@ -340,6 +343,8 @@
 	{"%6vX=%3fY", "3+2iX=2.5Y", args(&c, &f), args((3 + 2i), 2.5), ""},
 	{"%d%s", "123abc", args(&i, &s), args(123, "abc"), ""},
 	{"%c%c%c", "2\u50c2X", args(&r1, &r2, &r3), args('2', '\u50c2', 'X'), ""},
+	{"%5s%d", " 1234567 ", args(&s, &i), args("12345", 67), ""},
+	{"%5s%d", " 12 34 567 ", args(&s, &i), args("12", 34), ""},
 
 	// Custom scanners.
 	{"%e%f", "eefffff", args(&x, &y), args(Xs("ee"), Xs("fffff")), ""},
@@ -864,7 +869,7 @@
 		t.Fatal(err)
 	}
 	if n != 3 {
-		t.Fatalf("expected 3 items consumed, got %d")
+		t.Fatalf("expected 3 items consumed, got %d", n)
 	}
 	if a.rune != '1' || b.rune != '2' || c.rune != '➂' {
 		t.Errorf("bad scan rune: %q %q %q should be '1' '2' '➂'", a.rune, b.rune, c.rune)
@@ -990,3 +995,167 @@
 		b.StopTimer()
 	}
 }
+
+// Issue 9124.
+// %x on bytes couldn't handle non-space bytes terminating the scan.
+func TestHexBytes(t *testing.T) {
+	var a, b []byte
+	n, err := Sscanf("00010203", "%x", &a)
+	if n != 1 || err != nil {
+		t.Errorf("simple: got count, err = %d, %v; expected 1, nil", n, err)
+	}
+	check := func(msg string, x []byte) {
+		if len(x) != 4 {
+			t.Errorf("%s: bad length %d", msg, len(x))
+		}
+		for i, b := range x {
+			if int(b) != i {
+				t.Errorf("%s: bad x[%d] = %x", msg, i, x[i])
+			}
+		}
+	}
+	check("simple", a)
+	a = nil
+
+	n, err = Sscanf("00010203 00010203", "%x %x", &a, &b)
+	if n != 2 || err != nil {
+		t.Errorf("simple pair: got count, err = %d, %v; expected 2, nil", n, err)
+	}
+	check("simple pair a", a)
+	check("simple pair b", b)
+	a = nil
+	b = nil
+
+	n, err = Sscanf("00010203:", "%x", &a)
+	if n != 1 || err != nil {
+		t.Errorf("colon: got count, err = %d, %v; expected 1, nil", n, err)
+	}
+	check("colon", a)
+	a = nil
+
+	n, err = Sscanf("00010203:00010203", "%x:%x", &a, &b)
+	if n != 2 || err != nil {
+		t.Errorf("colon pair: got count, err = %d, %v; expected 2, nil", n, err)
+	}
+	check("colon pair a", a)
+	check("colon pair b", b)
+	a = nil
+	b = nil
+
+	// This one fails because there is a hex byte after the data,
+	// that is, an odd number of hex input bytes.
+	n, err = Sscanf("000102034:", "%x", &a)
+	if n != 0 || err == nil {
+		t.Errorf("odd count: got count, err = %d, %v; expected 0, error", n, err)
+	}
+}
+
+func TestScanNewlinesAreSpaces(t *testing.T) {
+	var a, b int
+	var tests = []struct {
+		name  string
+		text  string
+		count int
+	}{
+		{"newlines", "1\n2\n", 2},
+		{"no final newline", "1\n2", 2},
+		{"newlines with spaces ", "1  \n  2  \n", 2},
+		{"no final newline with spaces", "1  \n  2", 2},
+	}
+	for _, test := range tests {
+		n, err := Sscan(test.text, &a, &b)
+		if n != test.count {
+			t.Errorf("%s: expected to scan %d item(s), scanned %d", test.name, test.count, n)
+		}
+		if err != nil {
+			t.Errorf("%s: unexpected error: %s", test.name, err)
+		}
+	}
+}
+
+func TestScanlnNewlinesTerminate(t *testing.T) {
+	var a, b int
+	var tests = []struct {
+		name  string
+		text  string
+		count int
+		ok    bool
+	}{
+		{"one line one item", "1\n", 1, false},
+		{"one line two items with spaces ", "   1 2    \n", 2, true},
+		{"one line two items no newline", "   1 2", 2, true},
+		{"two lines two items", "1\n2\n", 1, false},
+	}
+	for _, test := range tests {
+		n, err := Sscanln(test.text, &a, &b)
+		if n != test.count {
+			t.Errorf("%s: expected to scan %d item(s), scanned %d", test.name, test.count, n)
+		}
+		if test.ok && err != nil {
+			t.Errorf("%s: unexpected error: %s", test.name, err)
+		}
+		if !test.ok && err == nil {
+			t.Errorf("%s: expected error; got none", test.name)
+		}
+	}
+}
+
+func TestScanfNewlineMatchFormat(t *testing.T) {
+	var a, b int
+	var tests = []struct {
+		name   string
+		text   string
+		format string
+		count  int
+		ok     bool
+	}{
+		{"newline in both", "1\n2", "%d\n%d\n", 2, true},
+		{"newline in input", "1\n2", "%d %d", 1, false},
+		{"space-newline in input", "1 \n2", "%d %d", 1, false},
+		{"newline in format", "1 2", "%d\n%d", 1, false},
+		{"space-newline in format", "1 2", "%d \n%d", 1, false},
+		{"space-newline in both", "1 \n2", "%d \n%d", 2, true},
+		{"extra space in format", "1\n2", "%d\n %d", 2, true},
+		{"two extra spaces in format", "1\n2", "%d \n %d", 2, true},
+	}
+	for _, test := range tests {
+		n, err := Sscanf(test.text, test.format, &a, &b)
+		if n != test.count {
+			t.Errorf("%s: expected to scan %d item(s), scanned %d", test.name, test.count, n)
+		}
+		if test.ok && err != nil {
+			t.Errorf("%s: unexpected error: %s", test.name, err)
+		}
+		if !test.ok && err == nil {
+			t.Errorf("%s: expected error; got none", test.name)
+		}
+	}
+}
+
+// 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/third_party/gofrontend/libgo/go/go/ast/ast.go b/third_party/gofrontend/libgo/go/go/ast/ast.go
index 312e3d1..5ab4283 100644
--- a/third_party/gofrontend/libgo/go/go/ast/ast.go
+++ b/third_party/gofrontend/libgo/go/go/ast/ast.go
@@ -486,7 +486,7 @@
 func (x *ChanType) End() token.Pos      { return x.Value.End() }
 
 // exprNode() ensures that only expression/type nodes can be
-// assigned to an ExprNode.
+// assigned to an Expr.
 //
 func (*BadExpr) exprNode()        {}
 func (*Ident) exprNode()          {}
@@ -562,10 +562,11 @@
 
 	// An EmptyStmt node represents an empty statement.
 	// The "position" of the empty statement is the position
-	// of the immediately preceding semicolon.
+	// of the immediately following (explicit or implicit) semicolon.
 	//
 	EmptyStmt struct {
-		Semicolon token.Pos // position of preceding ";"
+		Semicolon token.Pos // position of following ";"
+		Implicit  bool      // if set, ";" was omitted in the source
 	}
 
 	// A LabeledStmt node represents a labeled statement.
@@ -734,6 +735,9 @@
 func (s *BadStmt) End() token.Pos  { return s.To }
 func (s *DeclStmt) End() token.Pos { return s.Decl.End() }
 func (s *EmptyStmt) End() token.Pos {
+	if s.Implicit {
+		return s.Semicolon
+	}
 	return s.Semicolon + 1 /* len(";") */
 }
 func (s *LabeledStmt) End() token.Pos { return s.Stmt.End() }
@@ -783,7 +787,7 @@
 func (s *RangeStmt) End() token.Pos  { return s.Body.End() }
 
 // stmtNode() ensures that only statement nodes can be
-// assigned to a StmtNode.
+// assigned to a Stmt.
 //
 func (*BadStmt) stmtNode()        {}
 func (*DeclStmt) stmtNode()       {}
@@ -947,7 +951,7 @@
 }
 
 // declNode() ensures that only declaration nodes can be
-// assigned to a DeclNode.
+// assigned to a Decl.
 //
 func (*BadDecl) declNode()  {}
 func (*GenDecl) declNode()  {}
diff --git a/third_party/gofrontend/libgo/go/go/ast/filter.go b/third_party/gofrontend/libgo/go/go/ast/filter.go
index fc3eeb4..bb57116 100644
--- a/third_party/gofrontend/libgo/go/go/ast/filter.go
+++ b/third_party/gofrontend/libgo/go/go/ast/filter.go
@@ -23,8 +23,7 @@
 // body) are removed. Non-exported fields and methods of exported types are
 // stripped. The File.Comments list is not changed.
 //
-// FileExports returns true if there are exported declarations;
-// it returns false otherwise.
+// FileExports reports whether there are exported declarations.
 //
 func FileExports(src *File) bool {
 	return filterFile(src, exportFilter, true)
@@ -34,7 +33,7 @@
 // only exported nodes remain. The pkg.Files list is not changed, so that
 // file names and top-level package comments don't get lost.
 //
-// PackageExports returns true if there are exported declarations;
+// PackageExports reports whether there are exported declarations;
 // it returns false otherwise.
 //
 func PackageExports(pkg *Package) bool {
@@ -199,8 +198,8 @@
 // all names (including struct field and interface method names, but
 // not from parameter lists) that don't pass through the filter f.
 //
-// FilterDecl returns true if there are any declared names left after
-// filtering; it returns false otherwise.
+// FilterDecl reports whether there are any declared names left after
+// filtering.
 //
 func FilterDecl(decl Decl, f Filter) bool {
 	return filterDecl(decl, f, false)
@@ -221,11 +220,11 @@
 // names from top-level declarations (including struct field and
 // interface method names, but not from parameter lists) that don't
 // pass through the filter f. If the declaration is empty afterwards,
-// the declaration is removed from the AST. The File.Comments list
-// is not changed.
+// the declaration is removed from the AST. Import declarations are
+// always removed. The File.Comments list is not changed.
 //
-// FilterFile returns true if there are any top-level declarations
-// left after filtering; it returns false otherwise.
+// FilterFile reports whether there are any top-level declarations
+// left after filtering.
 //
 func FilterFile(src *File, f Filter) bool {
 	return filterFile(src, f, false)
@@ -251,8 +250,8 @@
 // changed, so that file names and top-level package comments don't get
 // lost.
 //
-// FilterPackage returns true if there are any top-level declarations
-// left after filtering; it returns false otherwise.
+// FilterPackage reports whether there are any top-level declarations
+// left after filtering.
 //
 func FilterPackage(pkg *Package, f Filter) bool {
 	return filterPackage(pkg, f, false)
diff --git a/third_party/gofrontend/libgo/go/go/ast/scope.go b/third_party/gofrontend/libgo/go/go/ast/scope.go
index df1529d..1ce5e2e 100644
--- a/third_party/gofrontend/libgo/go/go/ast/scope.go
+++ b/third_party/gofrontend/libgo/go/go/ast/scope.go
@@ -38,7 +38,7 @@
 // Insert attempts to insert a named object obj into the scope s.
 // If the scope already contains an object alt with the same name,
 // Insert leaves the scope unchanged and returns alt. Otherwise
-// it inserts obj and returns nil."
+// it inserts obj and returns nil.
 //
 func (s *Scope) Insert(obj *Object) (alt *Object) {
 	if alt = s.Objects[obj.Name]; alt == nil {
diff --git a/third_party/gofrontend/libgo/go/go/ast/walk.go b/third_party/gofrontend/libgo/go/go/ast/walk.go
index 73ac386..8ca2195 100644
--- a/third_party/gofrontend/libgo/go/go/ast/walk.go
+++ b/third_party/gofrontend/libgo/go/go/ast/walk.go
@@ -361,8 +361,7 @@
 		}
 
 	default:
-		fmt.Printf("ast.Walk: unexpected node type %T", n)
-		panic("ast.Walk")
+		panic(fmt.Sprintf("ast.Walk: unexpected node type %T", n))
 	}
 
 	v.Visit(nil)
@@ -379,7 +378,8 @@
 
 // Inspect traverses an AST in depth-first order: It starts by calling
 // f(node); node must not be nil. If f returns true, Inspect invokes f
-// for all the non-nil children of node, recursively.
+// recursively for each of the non-nil children of node, followed by a
+// call of f(nil).
 //
 func Inspect(node Node, f func(Node) bool) {
 	Walk(inspector(f), node)
diff --git a/third_party/gofrontend/libgo/go/go/build/build.go b/third_party/gofrontend/libgo/go/go/build/build.go
index e924727..42f1165 100644
--- a/third_party/gofrontend/libgo/go/go/build/build.go
+++ b/third_party/gofrontend/libgo/go/go/build/build.go
@@ -256,10 +256,12 @@
 // if set, or else the compiled code's GOARCH, GOOS, and GOROOT.
 var Default Context = defaultContext()
 
+// Also known to cmd/dist/build.go.
 var cgoEnabled = map[string]bool{
 	"darwin/386":      true,
 	"darwin/amd64":    true,
-	"dragonfly/386":   true,
+	"darwin/arm":      true,
+	"darwin/arm64":    true,
 	"dragonfly/amd64": true,
 	"freebsd/386":     true,
 	"freebsd/amd64":   true,
@@ -282,6 +284,7 @@
 	"netbsd/arm":      true,
 	"openbsd/386":     true,
 	"openbsd/amd64":   true,
+	"solaris/amd64":   true,
 	"windows/386":     true,
 	"windows/amd64":   true,
 }
@@ -300,11 +303,7 @@
 	// in all releases >= Go 1.x. Code that requires Go 1.x or later should
 	// say "+build go1.x", and code that should only be built before Go 1.x
 	// (perhaps it is the stub to use in that case) should say "+build !go1.x".
-	//
-	// When we reach Go 1.5 the line will read
-	//	c.ReleaseTags = []string{"go1.1", "go1.2", "go1.3", "go1.4", "go1.5"}
-	// and so on.
-	c.ReleaseTags = []string{"go1.1", "go1.2", "go1.3", "go1.4"}
+	c.ReleaseTags = []string{"go1.1", "go1.2", "go1.3", "go1.4", "go1.5"}
 
 	switch os.Getenv("CGO_ENABLED") {
 	case "1":
@@ -361,6 +360,7 @@
 	Root          string   // root of Go tree where this package lives
 	SrcRoot       string   // package source root directory ("" if unknown)
 	PkgRoot       string   // package install root directory ("" if unknown)
+	PkgTargetRoot string   // architecture dependent install root directory ("" if unknown)
 	BinDir        string   // command install directory ("" if unknown)
 	Goroot        bool     // package found in Go root
 	PkgObj        string   // installed .a file
@@ -469,18 +469,21 @@
 		return p, fmt.Errorf("import %q: invalid import path", path)
 	}
 
+	var pkgtargetroot string
 	var pkga string
 	var pkgerr error
+	suffix := ""
+	if ctxt.InstallSuffix != "" {
+		suffix = "_" + ctxt.InstallSuffix
+	}
 	switch ctxt.Compiler {
 	case "gccgo":
+		pkgtargetroot = "pkg/gccgo_" + ctxt.GOOS + "_" + ctxt.GOARCH + suffix
 		dir, elem := pathpkg.Split(p.ImportPath)
-		pkga = "pkg/gccgo_" + ctxt.GOOS + "_" + ctxt.GOARCH + "/" + dir + "lib" + elem + ".a"
+		pkga = pkgtargetroot + "/" + dir + "lib" + elem + ".a"
 	case "gc":
-		suffix := ""
-		if ctxt.InstallSuffix != "" {
-			suffix = "_" + ctxt.InstallSuffix
-		}
-		pkga = "pkg/" + ctxt.GOOS + "_" + ctxt.GOARCH + suffix + "/" + p.ImportPath + ".a"
+		pkgtargetroot = "pkg/" + ctxt.GOOS + "_" + ctxt.GOARCH + suffix
+		pkga = pkgtargetroot + "/" + p.ImportPath + ".a"
 	default:
 		// Save error for end of function.
 		pkgerr = fmt.Errorf("import %q: unknown compiler %q", path, ctxt.Compiler)
@@ -496,9 +499,13 @@
 			p.Dir = ctxt.joinPath(srcDir, path)
 		}
 		// Determine canonical import path, if any.
+		// Exclude results where the import path would include /testdata/.
+		inTestdata := func(sub string) bool {
+			return strings.Contains(sub, "/testdata/") || strings.HasSuffix(sub, "/testdata") || strings.HasPrefix(sub, "testdata/") || sub == "testdata"
+		}
 		if ctxt.GOROOT != "" {
 			root := ctxt.joinPath(ctxt.GOROOT, "src")
-			if sub, ok := ctxt.hasSubdir(root, p.Dir); ok {
+			if sub, ok := ctxt.hasSubdir(root, p.Dir); ok && !inTestdata(sub) {
 				p.Goroot = true
 				p.ImportPath = sub
 				p.Root = ctxt.GOROOT
@@ -508,7 +515,7 @@
 		all := ctxt.gopath()
 		for i, root := range all {
 			rootsrc := ctxt.joinPath(root, "src")
-			if sub, ok := ctxt.hasSubdir(rootsrc, p.Dir); ok {
+			if sub, ok := ctxt.hasSubdir(rootsrc, p.Dir); ok && !inTestdata(sub) {
 				// We found a potential import path for dir,
 				// but check that using it wouldn't find something
 				// else first.
@@ -597,6 +604,7 @@
 		p.PkgRoot = ctxt.joinPath(p.Root, "pkg")
 		p.BinDir = ctxt.joinPath(p.Root, "bin")
 		if pkga != "" {
+			p.PkgTargetRoot = ctxt.joinPath(p.Root, pkgtargetroot)
 			p.PkgObj = ctxt.joinPath(p.Root, pkga)
 		}
 	}
@@ -695,7 +703,11 @@
 			p.Name = pkg
 			firstFile = name
 		} else if pkg != p.Name {
-			return p, &MultiplePackageError{p.Dir, []string{firstFile, name}, []string{p.Name, pkg}}
+			return p, &MultiplePackageError{
+				Dir:      p.Dir,
+				Packages: []string{p.Name, pkg},
+				Files:    []string{firstFile, name},
+			}
 		}
 		if pf.Doc != nil && p.Doc == "" {
 			p.Doc = doc.Synopsis(pf.Doc.Text())
@@ -962,7 +974,7 @@
 	}
 
 	if strings.HasSuffix(filename, ".go") {
-		data, err = readImports(f, false)
+		data, err = readImports(f, false, nil)
 	} else {
 		data, err = readComments(f)
 	}
@@ -1075,9 +1087,6 @@
 // saveCgo saves the information from the #cgo lines in the import "C" comment.
 // These lines set CFLAGS, CPPFLAGS, CXXFLAGS and LDFLAGS and pkg-config directives
 // that affect the way cgo's C code is built.
-//
-// TODO(rsc): This duplicates code in cgo.
-// Once the dust settles, remove this code from cgo.
 func (ctxt *Context) saveCgo(filename string, di *Package, cg *ast.CommentGroup) error {
 	text := cg.Text()
 	for _, line := range strings.Split(text, "\n") {
@@ -1123,10 +1132,12 @@
 		if err != nil {
 			return fmt.Errorf("%s: invalid #cgo line: %s", filename, orig)
 		}
-		for _, arg := range args {
+		for i, arg := range args {
+			arg = expandSrcDir(arg, di.Dir)
 			if !safeCgoName(arg) {
 				return fmt.Errorf("%s: malformed #cgo argument: %s", filename, arg)
 			}
+			args[i] = arg
 		}
 
 		switch verb {
@@ -1147,6 +1158,14 @@
 	return nil
 }
 
+func expandSrcDir(str string, srcdir string) string {
+	// "\" delimited paths cause safeCgoName to fail
+	// so convert native paths with a different delimeter
+	// to "/" before starting (eg: on windows)
+	srcdir = filepath.ToSlash(srcdir)
+	return strings.Replace(str, "${SRCDIR}", srcdir, -1)
+}
+
 // NOTE: $ is not safe for the shell, but it is allowed here because of linker options like -Wl,$ORIGIN.
 // We never pass these arguments to a shell (just to programs we construct argv for), so this should be okay.
 // See golang.org/issue/6038.
@@ -1225,7 +1244,7 @@
 	return args, err
 }
 
-// match returns true if the name is one of:
+// match reports whether the name is one of:
 //
 //	$GOOS
 //	$GOARCH
@@ -1316,7 +1335,7 @@
 	// build tag "linux" in that file. For Go 1.4 and beyond, we require this
 	// auto-tagging to apply only to files with a non-empty prefix, so
 	// "foo_linux.go" is tagged but "linux.go" is not. This allows new operating
-	// sytems, such as android, to arrive without breaking existing code with
+	// systems, such as android, to arrive without breaking existing code with
 	// innocuous source code in "android.go". The easiest fix: cut everything
 	// in the name before the initial _.
 	i := strings.Index(name, "_")
@@ -1390,20 +1409,11 @@
 		strings.HasPrefix(path, "./") || strings.HasPrefix(path, "../")
 }
 
-// ArchChar returns the architecture character for the given goarch.
-// For example, ArchChar("amd64") returns "6".
+// ArchChar returns "?" and an error.
+// In earlier versions of Go, the returned string was used to derive
+// the compiler and linker tool names, the default object file suffix,
+// and the default linker output name. As of Go 1.5, those strings
+// no longer vary by architecture; they are compile, link, .o, and a.out, respectively.
 func ArchChar(goarch string) (string, error) {
-	switch goarch {
-	case "386":
-		return "8", nil
-	case "amd64", "amd64p32":
-		return "6", nil
-	case "arm":
-		return "5", nil
-	case "arm64":
-		return "7", nil
-	case "ppc64", "ppc64le":
-		return "9", nil
-	}
-	return "", errors.New("unsupported GOARCH " + goarch)
+	return "?", errors.New("architecture letter no longer used")
 }
diff --git a/third_party/gofrontend/libgo/go/go/build/build_test.go b/third_party/gofrontend/libgo/go/go/build/build_test.go
index a40def0..2709ca3 100644
--- a/third_party/gofrontend/libgo/go/go/build/build_test.go
+++ b/third_party/gofrontend/libgo/go/go/build/build_test.go
@@ -94,12 +94,29 @@
 
 func TestMultiplePackageImport(t *testing.T) {
 	_, err := Import(".", "testdata/multi", 0)
-	if _, ok := err.(*MultiplePackageError); !ok {
+	mpe, ok := err.(*MultiplePackageError)
+	if !ok {
 		t.Fatal(`Import("testdata/multi") did not return MultiplePackageError.`)
 	}
+	want := &MultiplePackageError{
+		Dir:      filepath.FromSlash("testdata/multi"),
+		Packages: []string{"main", "test_package"},
+		Files:    []string{"file.go", "file_appengine.go"},
+	}
+	if !reflect.DeepEqual(mpe, want) {
+		t.Errorf("got %#v; want %#v", mpe, want)
+	}
 }
 
 func TestLocalDirectory(t *testing.T) {
+	t.Skip("does not work with gccgo")
+	if runtime.GOOS == "darwin" {
+		switch runtime.GOARCH {
+		case "arm", "arm64":
+			t.Skipf("skipping on %s/%s, no valid GOROOT", runtime.GOOS, runtime.GOARCH)
+		}
+	}
+
 	cwd, err := os.Getwd()
 	if err != nil {
 		t.Fatal(err)
@@ -214,6 +231,14 @@
 }
 
 func TestImportCmd(t *testing.T) {
+	t.Skip("does not work with gccgo")
+	if runtime.GOOS == "darwin" {
+		switch runtime.GOARCH {
+		case "arm", "arm64":
+			t.Skipf("skipping on %s/%s, no valid GOROOT", runtime.GOOS, runtime.GOARCH)
+		}
+	}
+
 	p, err := Import("cmd/internal/objfile", "", 0)
 	if err != nil {
 		t.Fatal(err)
@@ -222,3 +247,33 @@
 		t.Fatalf("Import cmd/internal/objfile returned Dir=%q, want %q", filepath.ToSlash(p.Dir), ".../src/cmd/internal/objfile")
 	}
 }
+
+var (
+	expandSrcDirPath = filepath.Join(string(filepath.Separator)+"projects", "src", "add")
+)
+
+var expandSrcDirTests = []struct {
+	input, expected string
+}{
+	{"-L ${SRCDIR}/libs -ladd", "-L /projects/src/add/libs -ladd"},
+	{"${SRCDIR}/add_linux_386.a -pthread -lstdc++", "/projects/src/add/add_linux_386.a -pthread -lstdc++"},
+	{"Nothing to expand here!", "Nothing to expand here!"},
+	{"$", "$"},
+	{"$$", "$$"},
+	{"${", "${"},
+	{"$}", "$}"},
+	{"$FOO ${BAR}", "$FOO ${BAR}"},
+	{"Find me the $SRCDIRECTORY.", "Find me the $SRCDIRECTORY."},
+	{"$SRCDIR is missing braces", "$SRCDIR is missing braces"},
+}
+
+func TestExpandSrcDir(t *testing.T) {
+	for _, test := range expandSrcDirTests {
+		output := expandSrcDir(test.input, expandSrcDirPath)
+		if output != test.expected {
+			t.Errorf("%q expands to %q with SRCDIR=%q when %q is expected", test.input, output, expandSrcDirPath, test.expected)
+		} else {
+			t.Logf("%q expands to %q with SRCDIR=%q", test.input, output, expandSrcDirPath)
+		}
+	}
+}
diff --git a/third_party/gofrontend/libgo/go/go/build/deps_test.go b/third_party/gofrontend/libgo/go/go/build/deps_test.go
index a335eff..68969bb 100644
--- a/third_party/gofrontend/libgo/go/go/build/deps_test.go
+++ b/third_party/gofrontend/libgo/go/go/build/deps_test.go
@@ -8,8 +8,15 @@
 package build
 
 import (
+	"bytes"
+	"fmt"
+	"io/ioutil"
+	"os"
+	"path/filepath"
 	"runtime"
 	"sort"
+	"strconv"
+	"strings"
 	"testing"
 )
 
@@ -121,9 +128,12 @@
 	// End of linear dependency definitions.
 
 	// Operating system access.
-	"syscall":       {"L0", "unicode/utf16"},
-	"time":          {"L0", "syscall"},
-	"os":            {"L1", "os", "syscall", "time"},
+	"syscall":                           {"L0", "unicode/utf16"},
+	"internal/syscall/unix":             {"L0", "syscall"},
+	"internal/syscall/windows":          {"L0", "syscall"},
+	"internal/syscall/windows/registry": {"L0", "syscall", "unicode/utf16"},
+	"time":          {"L0", "syscall", "internal/syscall/windows/registry"},
+	"os":            {"L1", "os", "syscall", "time", "internal/syscall/windows"},
 	"path/filepath": {"L2", "os", "syscall"},
 	"io/ioutil":     {"L2", "os", "path/filepath", "time"},
 	"os/exec":       {"L2", "os", "path/filepath", "syscall"},
@@ -148,11 +158,13 @@
 	"regexp/syntax":  {"L2"},
 	"runtime/debug":  {"L2", "fmt", "io/ioutil", "os", "time"},
 	"runtime/pprof":  {"L2", "fmt", "text/tabwriter"},
+	"runtime/trace":  {"L0"},
 	"text/tabwriter": {"L2"},
 
-	"testing":        {"L2", "flag", "fmt", "os", "runtime/pprof", "time"},
-	"testing/iotest": {"L2", "log"},
-	"testing/quick":  {"L2", "flag", "fmt", "reflect"},
+	"testing":          {"L2", "flag", "fmt", "os", "runtime/pprof", "runtime/trace", "time"},
+	"testing/iotest":   {"L2", "log"},
+	"testing/quick":    {"L2", "flag", "fmt", "reflect"},
+	"internal/testenv": {"L2", "os", "testing"},
 
 	// L4 is defined as L3+fmt+log+time, because in general once
 	// you're using L3 packages, use of fmt, log, or time is not a big deal.
@@ -180,43 +192,60 @@
 		"go/token",
 	},
 
+	"go/format":       {"L4", "GOPARSER", "internal/format"},
+	"internal/format": {"L4", "GOPARSER"},
+
+	// Go type checking.
+	"go/constant":               {"L4", "go/token", "math/big"},
+	"go/importer":               {"L4", "go/internal/gcimporter", "go/internal/gccgoimporter", "go/types"},
+	"go/internal/gcimporter":    {"L4", "OS", "go/build", "go/constant", "go/token", "go/types", "text/scanner"},
+	"go/internal/gccgoimporter": {"L4", "OS", "debug/elf", "go/constant", "go/token", "go/types", "text/scanner"},
+	"go/types":                  {"L4", "GOPARSER", "container/heap", "go/constant"},
+
 	// One of a kind.
-	"archive/tar":         {"L4", "OS", "syscall"},
-	"archive/zip":         {"L4", "OS", "compress/flate"},
-	"compress/bzip2":      {"L4"},
-	"compress/flate":      {"L4"},
-	"compress/gzip":       {"L4", "compress/flate"},
-	"compress/lzw":        {"L4"},
-	"compress/zlib":       {"L4", "compress/flate"},
-	"database/sql":        {"L4", "container/list", "database/sql/driver"},
-	"database/sql/driver": {"L4", "time"},
-	"debug/dwarf":         {"L4"},
-	"debug/elf":           {"L4", "OS", "debug/dwarf"},
-	"debug/gosym":         {"L4"},
-	"debug/macho":         {"L4", "OS", "debug/dwarf"},
-	"debug/pe":            {"L4", "OS", "debug/dwarf"},
-	"encoding":            {"L4"},
-	"encoding/ascii85":    {"L4"},
-	"encoding/asn1":       {"L4", "math/big"},
-	"encoding/csv":        {"L4"},
-	"encoding/gob":        {"L4", "OS", "encoding"},
-	"encoding/hex":        {"L4"},
-	"encoding/json":       {"L4", "encoding"},
-	"encoding/pem":        {"L4"},
-	"encoding/xml":        {"L4", "encoding"},
-	"flag":                {"L4", "OS"},
-	"go/build":            {"L4", "OS", "GOPARSER"},
-	"html":                {"L4"},
-	"image/draw":          {"L4"},
-	"image/gif":           {"L4", "compress/lzw", "image/color/palette", "image/draw"},
-	"image/jpeg":          {"L4"},
-	"image/png":           {"L4", "compress/zlib"},
-	"index/suffixarray":   {"L4", "regexp"},
-	"math/big":            {"L4"},
-	"mime":                {"L4", "OS", "syscall"},
-	"net/url":             {"L4"},
-	"text/scanner":        {"L4", "OS"},
-	"text/template/parse": {"L4"},
+	"archive/tar":              {"L4", "OS", "syscall"},
+	"archive/zip":              {"L4", "OS", "compress/flate"},
+	"container/heap":           {"sort"},
+	"compress/bzip2":           {"L4"},
+	"compress/flate":           {"L4"},
+	"compress/gzip":            {"L4", "compress/flate"},
+	"compress/lzw":             {"L4"},
+	"compress/zlib":            {"L4", "compress/flate"},
+	"database/sql":             {"L4", "container/list", "database/sql/driver"},
+	"database/sql/driver":      {"L4", "time"},
+	"debug/dwarf":              {"L4"},
+	"debug/elf":                {"L4", "OS", "debug/dwarf"},
+	"debug/gosym":              {"L4"},
+	"debug/macho":              {"L4", "OS", "debug/dwarf"},
+	"debug/pe":                 {"L4", "OS", "debug/dwarf"},
+	"debug/plan9obj":           {"L4", "OS"},
+	"encoding":                 {"L4"},
+	"encoding/ascii85":         {"L4"},
+	"encoding/asn1":            {"L4", "math/big"},
+	"encoding/csv":             {"L4"},
+	"encoding/gob":             {"L4", "OS", "encoding"},
+	"encoding/hex":             {"L4"},
+	"encoding/json":            {"L4", "encoding"},
+	"encoding/pem":             {"L4"},
+	"encoding/xml":             {"L4", "encoding"},
+	"flag":                     {"L4", "OS"},
+	"go/build":                 {"L4", "OS", "GOPARSER"},
+	"html":                     {"L4"},
+	"image/draw":               {"L4", "image/internal/imageutil"},
+	"image/gif":                {"L4", "compress/lzw", "image/color/palette", "image/draw"},
+	"image/internal/imageutil": {"L4"},
+	"image/jpeg":               {"L4", "image/internal/imageutil"},
+	"image/png":                {"L4", "compress/zlib"},
+	"index/suffixarray":        {"L4", "regexp"},
+	"internal/singleflight":    {"sync"},
+	"internal/trace":           {"L4", "OS"},
+	"math/big":                 {"L4"},
+	"mime":                     {"L4", "OS", "syscall", "internal/syscall/windows/registry"},
+	"mime/quotedprintable":     {"L4"},
+	"net/internal/socktest":    {"L4", "OS", "syscall"},
+	"net/url":                  {"L4"},
+	"text/scanner":             {"L4", "OS"},
+	"text/template/parse":      {"L4"},
 
 	"html/template": {
 		"L4", "OS", "encoding/json", "html", "text/template",
@@ -234,13 +263,16 @@
 	// that shows up in programs that use cgo.
 	"C": {},
 
+	// Race detector uses cgo.
+	"runtime/race": {"C"},
+
 	// Plan 9 alone needs io/ioutil and os.
 	"os/user": {"L4", "CGO", "io/ioutil", "os", "syscall"},
 
 	// Basic networking.
 	// Because net must be used by any package that wants to
 	// do networking portably, it must have a small dependency set: just L1+basic os.
-	"net": {"L1", "CGO", "os", "syscall", "time"},
+	"net": {"L1", "CGO", "os", "syscall", "time", "internal/syscall/windows", "internal/singleflight"},
 
 	// NET enables use of basic network-related packages.
 	"NET": {
@@ -252,7 +284,7 @@
 
 	// Uses of networking.
 	"log/syslog":    {"L4", "OS", "net"},
-	"net/mail":      {"L4", "NET", "OS"},
+	"net/mail":      {"L4", "NET", "OS", "mime"},
 	"net/textproto": {"L4", "OS", "net"},
 
 	// Core crypto.
@@ -279,7 +311,7 @@
 	// Random byte, number generation.
 	// This would be part of core crypto except that it imports
 	// math/big, which imports fmt.
-	"crypto/rand": {"L4", "CRYPTO", "OS", "math/big", "syscall", "internal/syscall"},
+	"crypto/rand": {"L4", "CRYPTO", "OS", "math/big", "syscall", "internal/syscall/unix"},
 
 	// Mathematical crypto: dependencies on fmt (L4) and math/big.
 	// We could avoid some of the fmt, but math/big imports fmt anyway.
@@ -311,7 +343,7 @@
 	"crypto/x509/pkix": {"L4", "CRYPTO-MATH"},
 
 	// Simple net+crypto-aware packages.
-	"mime/multipart": {"L4", "OS", "mime", "crypto/rand", "net/textproto"},
+	"mime/multipart": {"L4", "OS", "mime", "crypto/rand", "net/textproto", "mime/quotedprintable"},
 	"net/smtp":       {"L4", "CRYPTO", "NET", "crypto/tls"},
 
 	// HTTP, kingpin of dependencies.
@@ -320,16 +352,18 @@
 		"compress/gzip", "crypto/tls", "mime/multipart", "runtime/debug",
 		"net/http/internal",
 	},
+	"net/http/internal": {"L4"},
 
 	// HTTP-using packages.
-	"expvar":            {"L4", "OS", "encoding/json", "net/http"},
-	"net/http/cgi":      {"L4", "NET", "OS", "crypto/tls", "net/http", "regexp"},
-	"net/http/fcgi":     {"L4", "NET", "OS", "net/http", "net/http/cgi"},
-	"net/http/httptest": {"L4", "NET", "OS", "crypto/tls", "flag", "net/http"},
-	"net/http/httputil": {"L4", "NET", "OS", "net/http", "net/http/internal"},
-	"net/http/pprof":    {"L4", "OS", "html/template", "net/http", "runtime/pprof"},
-	"net/rpc":           {"L4", "NET", "encoding/gob", "html/template", "net/http"},
-	"net/rpc/jsonrpc":   {"L4", "NET", "encoding/json", "net/rpc"},
+	"expvar":             {"L4", "OS", "encoding/json", "net/http"},
+	"net/http/cgi":       {"L4", "NET", "OS", "crypto/tls", "net/http", "regexp"},
+	"net/http/cookiejar": {"L4", "NET", "net/http"},
+	"net/http/fcgi":      {"L4", "NET", "OS", "net/http", "net/http/cgi"},
+	"net/http/httptest":  {"L4", "NET", "OS", "crypto/tls", "flag", "net/http"},
+	"net/http/httputil":  {"L4", "NET", "OS", "net/http", "net/http/internal"},
+	"net/http/pprof":     {"L4", "OS", "html/template", "net/http", "runtime/pprof", "runtime/trace"},
+	"net/rpc":            {"L4", "NET", "encoding/gob", "html/template", "net/http"},
+	"net/rpc/jsonrpc":    {"L4", "NET", "encoding/json", "net/rpc"},
 }
 
 // isMacro reports whether p is a package dependency macro
@@ -375,69 +409,112 @@
 	osPkg{"plan9", "log/syslog"}:   true,
 }
 
-func TestDependencies(t *testing.T) {
-	if runtime.GOOS == "nacl" {
-		// NaCl tests run in a limited file system and we do not
-		// provide access to every source file.
-		t.Skip("skipping on NaCl")
-	}
-	var all []string
+// listStdPkgs returns the same list of packages as "go list std".
+func listStdPkgs(goroot string) ([]string, error) {
+	// Based on cmd/go's matchPackages function.
+	var pkgs []string
 
-	for k := range pkgDeps {
-		all = append(all, k)
+	src := filepath.Join(goroot, "src") + string(filepath.Separator)
+	walkFn := func(path string, fi os.FileInfo, err error) error {
+		if err != nil || !fi.IsDir() || path == src {
+			return nil
+		}
+
+		base := filepath.Base(path)
+		if strings.HasPrefix(base, ".") || strings.HasPrefix(base, "_") || base == "testdata" {
+			return filepath.SkipDir
+		}
+
+		name := filepath.ToSlash(path[len(src):])
+		if name == "builtin" || name == "cmd" || strings.Contains(name, ".") {
+			return filepath.SkipDir
+		}
+
+		pkgs = append(pkgs, name)
+		return nil
+	}
+	if err := filepath.Walk(src, walkFn); err != nil {
+		return nil, err
+	}
+	return pkgs, nil
+}
+
+func TestDependencies(t *testing.T) {
+	iOS := runtime.GOOS == "darwin" && (runtime.GOARCH == "arm" || runtime.GOARCH == "arm64")
+	if runtime.GOOS == "nacl" || iOS {
+		// Tests run in a limited file system and we do not
+		// provide access to every source file.
+		t.Skipf("skipping on %s/%s, missing full GOROOT", runtime.GOOS, runtime.GOARCH)
+	}
+
+	ctxt := Default
+	all, err := listStdPkgs(ctxt.GOROOT)
+	if err != nil {
+		t.Fatal(err)
 	}
 	sort.Strings(all)
 
-	ctxt := Default
 	test := func(mustImport bool) {
 		for _, pkg := range all {
-			if isMacro(pkg) {
-				continue
-			}
-			if pkg == "runtime/cgo" && !ctxt.CgoEnabled {
-				continue
-			}
-			p, err := ctxt.Import(pkg, "", 0)
+			imports, err := findImports(pkg)
 			if err != nil {
-				if allowedErrors[osPkg{ctxt.GOOS, pkg}] {
-					continue
-				}
-				if !ctxt.CgoEnabled && pkg == "runtime/cgo" {
-					continue
-				}
-				// Some of the combinations we try might not
-				// be reasonable (like arm,plan9,cgo), so ignore
-				// errors for the auto-generated combinations.
-				if !mustImport {
-					continue
-				}
-				t.Errorf("%s/%s/cgo=%v %v", ctxt.GOOS, ctxt.GOARCH, ctxt.CgoEnabled, err)
+				t.Error(err)
 				continue
 			}
 			ok := allowed(pkg)
 			var bad []string
-			for _, imp := range p.Imports {
+			for _, imp := range imports {
 				if !ok[imp] {
 					bad = append(bad, imp)
 				}
 			}
 			if bad != nil {
-				t.Errorf("%s/%s/cgo=%v unexpected dependency: %s imports %v", ctxt.GOOS, ctxt.GOARCH, ctxt.CgoEnabled, pkg, bad)
+				t.Errorf("unexpected dependency: %s imports %v", pkg, bad)
 			}
 		}
 	}
 	test(true)
+}
 
-	if testing.Short() {
-		t.Logf("skipping other systems")
-		return
+var buildIgnore = []byte("\n// +build ignore")
+
+func findImports(pkg string) ([]string, error) {
+	dir := filepath.Join(Default.GOROOT, "src", pkg)
+	files, err := ioutil.ReadDir(dir)
+	if err != nil {
+		return nil, err
 	}
-
-	for _, ctxt.GOOS = range geese {
-		for _, ctxt.GOARCH = range goarches {
-			for _, ctxt.CgoEnabled = range bools {
-				test(false)
+	var imports []string
+	var haveImport = map[string]bool{}
+	for _, file := range files {
+		name := file.Name()
+		if !strings.HasSuffix(name, ".go") || strings.HasSuffix(name, "_test.go") {
+			continue
+		}
+		f, err := os.Open(filepath.Join(dir, name))
+		if err != nil {
+			return nil, err
+		}
+		var imp []string
+		data, err := readImports(f, false, &imp)
+		f.Close()
+		if err != nil {
+			return nil, fmt.Errorf("reading %v: %v", name, err)
+		}
+		if bytes.Contains(data, buildIgnore) {
+			continue
+		}
+		for _, quoted := range imp {
+			path, err := strconv.Unquote(quoted)
+			if err != nil {
+				continue
+			}
+			if !haveImport[path] {
+				haveImport[path] = true
+				imports = append(imports, path)
 			}
 		}
 	}
+	sort.Strings(imports)
+	return imports, nil
 }
diff --git a/third_party/gofrontend/libgo/go/go/build/doc.go b/third_party/gofrontend/libgo/go/go/build/doc.go
index 75a827b..233f8b9 100644
--- a/third_party/gofrontend/libgo/go/go/build/doc.go
+++ b/third_party/gofrontend/libgo/go/go/build/doc.go
@@ -101,6 +101,7 @@
 //	- "go1.2", from Go version 1.2 onward
 //	- "go1.3", from Go version 1.3 onward
 //	- "go1.4", from Go version 1.4 onward
+//	- "go1.5", from Go version 1.5 onward
 //	- any additional words listed in ctxt.BuildTags
 //
 // If a file's name, after stripping the extension and a possible _test suffix,
@@ -111,7 +112,7 @@
 // (example: source_windows_amd64.go) where GOOS and GOARCH represent
 // any known operating system and architecture values respectively, then
 // the file is considered to have an implicit build constraint requiring
-// those terms.
+// those terms (in addition to any explicit constraints in the file).
 //
 // To keep a file from being considered for the build:
 //
diff --git a/third_party/gofrontend/libgo/go/go/build/read.go b/third_party/gofrontend/libgo/go/go/build/read.go
index c8079df..1049ac5 100644
--- a/third_party/gofrontend/libgo/go/go/build/read.go
+++ b/third_party/gofrontend/libgo/go/go/build/read.go
@@ -146,11 +146,15 @@
 
 // readString reads a quoted string literal from the input.
 // If an identifier is not present, readString records a syntax error.
-func (r *importReader) readString() {
+func (r *importReader) readString(save *[]string) {
 	switch r.nextByte(true) {
 	case '`':
+		start := len(r.buf) - 1
 		for r.err == nil {
 			if r.nextByte(false) == '`' {
+				if save != nil {
+					*save = append(*save, string(r.buf[start:]))
+				}
 				break
 			}
 			if r.eof {
@@ -158,9 +162,13 @@
 			}
 		}
 	case '"':
+		start := len(r.buf) - 1
 		for r.err == nil {
 			c := r.nextByte(false)
 			if c == '"' {
+				if save != nil {
+					*save = append(*save, string(r.buf[start:]))
+				}
 				break
 			}
 			if r.eof || c == '\n' {
@@ -177,14 +185,14 @@
 
 // readImport reads an import clause - optional identifier followed by quoted string -
 // from the input.
-func (r *importReader) readImport() {
+func (r *importReader) readImport(imports *[]string) {
 	c := r.peekByte(true)
 	if c == '.' {
 		r.peek = 0
 	} else if isIdent(c) {
 		r.readIdent()
 	}
-	r.readString()
+	r.readString(imports)
 }
 
 // readComments is like ioutil.ReadAll, except that it only reads the leading
@@ -201,7 +209,7 @@
 
 // readImports is like ioutil.ReadAll, except that it expects a Go file as input
 // and stops reading the input once the imports have completed.
-func readImports(f io.Reader, reportSyntaxError bool) ([]byte, error) {
+func readImports(f io.Reader, reportSyntaxError bool, imports *[]string) ([]byte, error) {
 	r := &importReader{b: bufio.NewReader(f)}
 
 	r.readKeyword("package")
@@ -211,11 +219,11 @@
 		if r.peekByte(true) == '(' {
 			r.nextByte(false)
 			for r.peekByte(true) != ')' && r.err == nil {
-				r.readImport()
+				r.readImport(imports)
 			}
 			r.nextByte(false)
 		} else {
-			r.readImport()
+			r.readImport(imports)
 		}
 	}
 
diff --git a/third_party/gofrontend/libgo/go/go/build/read_test.go b/third_party/gofrontend/libgo/go/go/build/read_test.go
index 2dcc120..326960b 100644
--- a/third_party/gofrontend/libgo/go/go/build/read_test.go
+++ b/third_party/gofrontend/libgo/go/go/build/read_test.go
@@ -131,7 +131,7 @@
 }
 
 func TestReadImports(t *testing.T) {
-	testRead(t, readImportsTests, func(r io.Reader) ([]byte, error) { return readImports(r, true) })
+	testRead(t, readImportsTests, func(r io.Reader) ([]byte, error) { return readImports(r, true, nil) })
 }
 
 func TestReadComments(t *testing.T) {
@@ -207,7 +207,7 @@
 
 func TestReadFailures(t *testing.T) {
 	// Errors should be reported (true arg to readImports).
-	testRead(t, readFailuresTests, func(r io.Reader) ([]byte, error) { return readImports(r, true) })
+	testRead(t, readFailuresTests, func(r io.Reader) ([]byte, error) { return readImports(r, true, nil) })
 }
 
 func TestReadFailuresIgnored(t *testing.T) {
@@ -222,5 +222,5 @@
 			tt.err = ""
 		}
 	}
-	testRead(t, tests, func(r io.Reader) ([]byte, error) { return readImports(r, false) })
+	testRead(t, tests, func(r io.Reader) ([]byte, error) { return readImports(r, false, nil) })
 }
diff --git a/third_party/gofrontend/libgo/go/go/build/syslist.go b/third_party/gofrontend/libgo/go/go/build/syslist.go
index 0bf4b15..d800a78 100644
--- a/third_party/gofrontend/libgo/go/go/build/syslist.go
+++ b/third_party/gofrontend/libgo/go/go/build/syslist.go
@@ -5,4 +5,4 @@
 package build
 
 const goosList = "android darwin dragonfly freebsd linux nacl netbsd openbsd plan9 solaris windows "
-const goarchList = "386 amd64 amd64p32 arm arm64 alpha m68k mipso32 mipsn32 mipsn64 mipso64 ppc ppc64 ppc64le s390 s390x sparc sparc64 "
+const goarchList = "386 amd64 amd64p32 arm armbe arm64 arm64be alpha m68k ppc64 ppc64le mips mipsle mips64 mips64le mips64p32 mips64p32le mipso32 mipsn32 mipsn64 mipso64 ppc s390 s390x sparc sparc64 "
diff --git a/third_party/gofrontend/libgo/go/go/build/testdata/empty/dummy b/third_party/gofrontend/libgo/go/go/build/testdata/empty/dummy
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/go/build/testdata/empty/dummy
diff --git a/third_party/gofrontend/libgo/go/go/constant/go13.go b/third_party/gofrontend/libgo/go/go/constant/go13.go
new file mode 100644
index 0000000..a4a838a
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/go/constant/go13.go
@@ -0,0 +1,24 @@
+// 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.
+
+// +build !go1.4
+
+package constant
+
+import (
+	"math"
+	"math/big"
+)
+
+func ratToFloat32(x *big.Rat) (float32, bool) {
+	// Before 1.4, there's no Rat.Float32.
+	// Emulate it, albeit at the cost of
+	// imprecision in corner cases.
+	x64, exact := x.Float64()
+	x32 := float32(x64)
+	if math.IsInf(float64(x32), 0) {
+		exact = false
+	}
+	return x32, exact
+}
diff --git a/third_party/gofrontend/libgo/go/go/constant/go14.go b/third_party/gofrontend/libgo/go/go/constant/go14.go
new file mode 100644
index 0000000..2ab6da0
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/go/constant/go14.go
@@ -0,0 +1,13 @@
+// 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.
+
+// +build go1.4
+
+package constant
+
+import "math/big"
+
+func ratToFloat32(x *big.Rat) (float32, bool) {
+	return x.Float32()
+}
diff --git a/third_party/gofrontend/libgo/go/go/constant/value.go b/third_party/gofrontend/libgo/go/go/constant/value.go
new file mode 100644
index 0000000..79a80af
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/go/constant/value.go
@@ -0,0 +1,925 @@
+// Copyright 2013 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 constant implements Values representing untyped
+// Go constants and the corresponding operations. Values
+// and operations may have arbitrary or unlimited precision.
+//
+// A special Unknown value may be used when a value
+// is unknown due to an error. Operations on unknown
+// values produce unknown values unless specified
+// otherwise.
+//
+package constant // import "go/constant"
+
+import (
+	"fmt"
+	"go/token"
+	"math/big"
+	"strconv"
+)
+
+// Kind specifies the kind of value represented by a Value.
+type Kind int
+
+// Implementation note: Kinds must be enumerated in
+// order of increasing "complexity" (used by match).
+
+const (
+	// unknown values
+	Unknown Kind = iota
+
+	// non-numeric values
+	Bool
+	String
+
+	// numeric values
+	Int
+	Float
+	Complex
+)
+
+// A Value represents a mathematically exact value of a given Kind.
+type Value interface {
+	// Kind returns the value kind; it is always the smallest
+	// kind in which the value can be represented exactly.
+	Kind() Kind
+
+	// String returns a human-readable form of the value.
+	String() string
+
+	// Prevent external implementations.
+	implementsValue()
+}
+
+// ----------------------------------------------------------------------------
+// Implementations
+
+type (
+	unknownVal struct{}
+	boolVal    bool
+	stringVal  string
+	int64Val   int64
+	intVal     struct{ val *big.Int }
+	floatVal   struct{ val *big.Rat }
+	complexVal struct{ re, im *big.Rat }
+)
+
+func (unknownVal) Kind() Kind { return Unknown }
+func (boolVal) Kind() Kind    { return Bool }
+func (stringVal) Kind() Kind  { return String }
+func (int64Val) Kind() Kind   { return Int }
+func (intVal) Kind() Kind     { return Int }
+func (floatVal) Kind() Kind   { return Float }
+func (complexVal) Kind() Kind { return Complex }
+
+func (unknownVal) String() string   { return "unknown" }
+func (x boolVal) String() string    { return fmt.Sprintf("%v", bool(x)) }
+func (x stringVal) String() string  { return strconv.Quote(string(x)) }
+func (x int64Val) String() string   { return strconv.FormatInt(int64(x), 10) }
+func (x intVal) String() string     { return x.val.String() }
+func (x floatVal) String() string   { return x.val.String() }
+func (x complexVal) String() string { return fmt.Sprintf("(%s + %si)", x.re, x.im) }
+
+func (unknownVal) implementsValue() {}
+func (boolVal) implementsValue()    {}
+func (stringVal) implementsValue()  {}
+func (int64Val) implementsValue()   {}
+func (intVal) implementsValue()     {}
+func (floatVal) implementsValue()   {}
+func (complexVal) implementsValue() {}
+
+// int64 bounds
+var (
+	minInt64 = big.NewInt(-1 << 63)
+	maxInt64 = big.NewInt(1<<63 - 1)
+)
+
+func normInt(x *big.Int) Value {
+	if minInt64.Cmp(x) <= 0 && x.Cmp(maxInt64) <= 0 {
+		return int64Val(x.Int64())
+	}
+	return intVal{x}
+}
+
+func normFloat(x *big.Rat) Value {
+	if x.IsInt() {
+		return normInt(x.Num())
+	}
+	return floatVal{x}
+}
+
+func normComplex(re, im *big.Rat) Value {
+	if im.Sign() == 0 {
+		return normFloat(re)
+	}
+	return complexVal{re, im}
+}
+
+// ----------------------------------------------------------------------------
+// Factories
+
+// MakeUnknown returns the Unknown value.
+func MakeUnknown() Value { return unknownVal{} }
+
+// MakeBool returns the Bool value for x.
+func MakeBool(b bool) Value { return boolVal(b) }
+
+// MakeString returns the String value for x.
+func MakeString(s string) Value { return stringVal(s) }
+
+// MakeInt64 returns the Int value for x.
+func MakeInt64(x int64) Value { return int64Val(x) }
+
+// MakeUint64 returns the Int value for x.
+func MakeUint64(x uint64) Value { return normInt(new(big.Int).SetUint64(x)) }
+
+// MakeFloat64 returns the numeric value for x.
+// If x is not finite, the result is unknown.
+func MakeFloat64(x float64) Value {
+	if f := new(big.Rat).SetFloat64(x); f != nil {
+		return normFloat(f)
+	}
+	return unknownVal{}
+}
+
+// MakeFromLiteral returns the corresponding integer, floating-point,
+// imaginary, character, or string value for a Go literal string.
+// If prec > 0, prec specifies an upper limit for the precision of
+// a numeric value. If the literal string is invalid, the result is
+// nil.
+// BUG(gri) Only prec == 0 is supported at the moment.
+func MakeFromLiteral(lit string, tok token.Token, prec uint) Value {
+	if prec != 0 {
+		panic("limited precision not supported")
+	}
+	switch tok {
+	case token.INT:
+		if x, err := strconv.ParseInt(lit, 0, 64); err == nil {
+			return int64Val(x)
+		}
+		if x, ok := new(big.Int).SetString(lit, 0); ok {
+			return intVal{x}
+		}
+
+	case token.FLOAT:
+		if x, ok := new(big.Rat).SetString(lit); ok {
+			return normFloat(x)
+		}
+
+	case token.IMAG:
+		if n := len(lit); n > 0 && lit[n-1] == 'i' {
+			if im, ok := new(big.Rat).SetString(lit[0 : n-1]); ok {
+				return normComplex(big.NewRat(0, 1), im)
+			}
+		}
+
+	case token.CHAR:
+		if n := len(lit); n >= 2 {
+			if code, _, _, err := strconv.UnquoteChar(lit[1:n-1], '\''); err == nil {
+				return int64Val(code)
+			}
+		}
+
+	case token.STRING:
+		if s, err := strconv.Unquote(lit); err == nil {
+			return stringVal(s)
+		}
+	}
+
+	return nil
+}
+
+// ----------------------------------------------------------------------------
+// Accessors
+//
+// For unknown arguments the result is the zero value for the respective
+// accessor type, except for Sign, where the result is 1.
+
+// BoolVal returns the Go boolean value of x, which must be a Bool or an Unknown.
+// If x is Unknown, the result is false.
+func BoolVal(x Value) bool {
+	switch x := x.(type) {
+	case boolVal:
+		return bool(x)
+	case unknownVal:
+		return false
+	}
+	panic(fmt.Sprintf("%v not a Bool", x))
+}
+
+// StringVal returns the Go string value of x, which must be a String or an Unknown.
+// If x is Unknown, the result is "".
+func StringVal(x Value) string {
+	switch x := x.(type) {
+	case stringVal:
+		return string(x)
+	case unknownVal:
+		return ""
+	}
+	panic(fmt.Sprintf("%v not a String", x))
+}
+
+// Int64Val returns the Go int64 value of x and whether the result is exact;
+// x must be an Int or an Unknown. If the result is not exact, its value is undefined.
+// If x is Unknown, the result is (0, false).
+func Int64Val(x Value) (int64, bool) {
+	switch x := x.(type) {
+	case int64Val:
+		return int64(x), true
+	case intVal:
+		return x.val.Int64(), x.val.BitLen() <= 63
+	case unknownVal:
+		return 0, false
+	}
+	panic(fmt.Sprintf("%v not an Int", x))
+}
+
+// Uint64Val returns the Go uint64 value of x and whether the result is exact;
+// x must be an Int or an Unknown. If the result is not exact, its value is undefined.
+// If x is Unknown, the result is (0, false).
+func Uint64Val(x Value) (uint64, bool) {
+	switch x := x.(type) {
+	case int64Val:
+		return uint64(x), x >= 0
+	case intVal:
+		return x.val.Uint64(), x.val.Sign() >= 0 && x.val.BitLen() <= 64
+	case unknownVal:
+		return 0, false
+	}
+	panic(fmt.Sprintf("%v not an Int", x))
+}
+
+// Float32Val is like Float64Val but for float32 instead of float64.
+func Float32Val(x Value) (float32, bool) {
+	switch x := x.(type) {
+	case int64Val:
+		f := float32(x)
+		return f, int64Val(f) == x
+	case intVal:
+		return ratToFloat32(new(big.Rat).SetFrac(x.val, int1))
+	case floatVal:
+		return ratToFloat32(x.val)
+	case unknownVal:
+		return 0, false
+	}
+	panic(fmt.Sprintf("%v not a Float", x))
+}
+
+// Float64Val returns the nearest Go float64 value of x and whether the result is exact;
+// x must be numeric but not Complex, or Unknown. For values too small (too close to 0)
+// to represent as float64, Float64Val silently underflows to 0. The result sign always
+// matches the sign of x, even for 0.
+// If x is Unknown, the result is (0, false).
+func Float64Val(x Value) (float64, bool) {
+	switch x := x.(type) {
+	case int64Val:
+		f := float64(int64(x))
+		return f, int64Val(f) == x
+	case intVal:
+		return new(big.Rat).SetFrac(x.val, int1).Float64()
+	case floatVal:
+		return x.val.Float64()
+	case unknownVal:
+		return 0, false
+	}
+	panic(fmt.Sprintf("%v not a Float", x))
+}
+
+// BitLen returns the number of bits required to represent
+// the absolute value x in binary representation; x must be an Int or an Unknown.
+// If x is Unknown, the result is 0.
+func BitLen(x Value) int {
+	switch x := x.(type) {
+	case int64Val:
+		return new(big.Int).SetInt64(int64(x)).BitLen()
+	case intVal:
+		return x.val.BitLen()
+	case unknownVal:
+		return 0
+	}
+	panic(fmt.Sprintf("%v not an Int", x))
+}
+
+// Sign returns -1, 0, or 1 depending on whether x < 0, x == 0, or x > 0;
+// x must be numeric or Unknown. For complex values x, the sign is 0 if x == 0,
+// otherwise it is != 0. If x is Unknown, the result is 1.
+func Sign(x Value) int {
+	switch x := x.(type) {
+	case int64Val:
+		switch {
+		case x < 0:
+			return -1
+		case x > 0:
+			return 1
+		}
+		return 0
+	case intVal:
+		return x.val.Sign()
+	case floatVal:
+		return x.val.Sign()
+	case complexVal:
+		return x.re.Sign() | x.im.Sign()
+	case unknownVal:
+		return 1 // avoid spurious division by zero errors
+	}
+	panic(fmt.Sprintf("%v not numeric", x))
+}
+
+// ----------------------------------------------------------------------------
+// Support for serializing/deserializing integers
+
+const (
+	// Compute the size of a Word in bytes.
+	_m       = ^big.Word(0)
+	_log     = _m>>8&1 + _m>>16&1 + _m>>32&1
+	wordSize = 1 << _log
+)
+
+// Bytes returns the bytes for the absolute value of x in little-
+// endian binary representation; x must be an Int.
+func Bytes(x Value) []byte {
+	var val *big.Int
+	switch x := x.(type) {
+	case int64Val:
+		val = new(big.Int).SetInt64(int64(x))
+	case intVal:
+		val = x.val
+	default:
+		panic(fmt.Sprintf("%v not an Int", x))
+	}
+
+	words := val.Bits()
+	bytes := make([]byte, len(words)*wordSize)
+
+	i := 0
+	for _, w := range words {
+		for j := 0; j < wordSize; j++ {
+			bytes[i] = byte(w)
+			w >>= 8
+			i++
+		}
+	}
+	// remove leading 0's
+	for i > 0 && bytes[i-1] == 0 {
+		i--
+	}
+
+	return bytes[:i]
+}
+
+// MakeFromBytes returns the Int value given the bytes of its little-endian
+// binary representation. An empty byte slice argument represents 0.
+func MakeFromBytes(bytes []byte) Value {
+	words := make([]big.Word, (len(bytes)+(wordSize-1))/wordSize)
+
+	i := 0
+	var w big.Word
+	var s uint
+	for _, b := range bytes {
+		w |= big.Word(b) << s
+		if s += 8; s == wordSize*8 {
+			words[i] = w
+			i++
+			w = 0
+			s = 0
+		}
+	}
+	// store last word
+	if i < len(words) {
+		words[i] = w
+		i++
+	}
+	// remove leading 0's
+	for i > 0 && words[i-1] == 0 {
+		i--
+	}
+
+	return normInt(new(big.Int).SetBits(words[:i]))
+}
+
+// ----------------------------------------------------------------------------
+// Support for disassembling fractions
+
+// Num returns the numerator of x; x must be Int, Float, or Unknown.
+// If x is Unknown, the result is Unknown, otherwise it is an Int
+// with the same sign as x.
+func Num(x Value) Value {
+	switch x := x.(type) {
+	case unknownVal, int64Val, intVal:
+		return x
+	case floatVal:
+		return normInt(x.val.Num())
+	}
+	panic(fmt.Sprintf("%v not Int or Float", x))
+}
+
+// Denom returns the denominator of x; x must be Int, Float, or Unknown.
+// If x is Unknown, the result is Unknown, otherwise it is an Int >= 1.
+func Denom(x Value) Value {
+	switch x := x.(type) {
+	case unknownVal:
+		return x
+	case int64Val, intVal:
+		return int64Val(1)
+	case floatVal:
+		return normInt(x.val.Denom())
+	}
+	panic(fmt.Sprintf("%v not Int or Float", x))
+}
+
+// ----------------------------------------------------------------------------
+// Support for assembling/disassembling complex numbers
+
+// MakeImag returns the numeric value x*i (possibly 0);
+// x must be Int, Float, or Unknown.
+// If x is Unknown, the result is Unknown.
+func MakeImag(x Value) Value {
+	var im *big.Rat
+	switch x := x.(type) {
+	case unknownVal:
+		return x
+	case int64Val:
+		im = big.NewRat(int64(x), 1)
+	case intVal:
+		im = new(big.Rat).SetFrac(x.val, int1)
+	case floatVal:
+		im = x.val
+	default:
+		panic(fmt.Sprintf("%v not Int or Float", x))
+	}
+	return normComplex(rat0, im)
+}
+
+// Real returns the real part of x, which must be a numeric or unknown value.
+// If x is Unknown, the result is Unknown.
+func Real(x Value) Value {
+	switch x := x.(type) {
+	case unknownVal, int64Val, intVal, floatVal:
+		return x
+	case complexVal:
+		return normFloat(x.re)
+	}
+	panic(fmt.Sprintf("%v not numeric", x))
+}
+
+// Imag returns the imaginary part of x, which must be a numeric or unknown value.
+// If x is Unknown, the result is Unknown.
+func Imag(x Value) Value {
+	switch x := x.(type) {
+	case unknownVal:
+		return x
+	case int64Val, intVal, floatVal:
+		return int64Val(0)
+	case complexVal:
+		return normFloat(x.im)
+	}
+	panic(fmt.Sprintf("%v not numeric", x))
+}
+
+// ----------------------------------------------------------------------------
+// Operations
+
+// is32bit reports whether x can be represented using 32 bits.
+func is32bit(x int64) bool {
+	const s = 32
+	return -1<<(s-1) <= x && x <= 1<<(s-1)-1
+}
+
+// is63bit reports whether x can be represented using 63 bits.
+func is63bit(x int64) bool {
+	const s = 63
+	return -1<<(s-1) <= x && x <= 1<<(s-1)-1
+}
+
+// UnaryOp returns the result of the unary expression op y.
+// The operation must be defined for the operand.
+// If prec > 0 it specifies the ^ (xor) result size in bits.
+// If y is Unknown, the result is Unknown.
+//
+func UnaryOp(op token.Token, y Value, prec uint) Value {
+	switch op {
+	case token.ADD:
+		switch y.(type) {
+		case unknownVal, int64Val, intVal, floatVal, complexVal:
+			return y
+		}
+
+	case token.SUB:
+		switch y := y.(type) {
+		case unknownVal:
+			return y
+		case int64Val:
+			if z := -y; z != y {
+				return z // no overflow
+			}
+			return normInt(new(big.Int).Neg(big.NewInt(int64(y))))
+		case intVal:
+			return normInt(new(big.Int).Neg(y.val))
+		case floatVal:
+			return normFloat(new(big.Rat).Neg(y.val))
+		case complexVal:
+			return normComplex(new(big.Rat).Neg(y.re), new(big.Rat).Neg(y.im))
+		}
+
+	case token.XOR:
+		var z big.Int
+		switch y := y.(type) {
+		case unknownVal:
+			return y
+		case int64Val:
+			z.Not(big.NewInt(int64(y)))
+		case intVal:
+			z.Not(y.val)
+		default:
+			goto Error
+		}
+		// For unsigned types, the result will be negative and
+		// thus "too large": We must limit the result precision
+		// to the type's precision.
+		if prec > 0 {
+			z.AndNot(&z, new(big.Int).Lsh(big.NewInt(-1), prec)) // z &^= (-1)<<prec
+		}
+		return normInt(&z)
+
+	case token.NOT:
+		switch y := y.(type) {
+		case unknownVal:
+			return y
+		case boolVal:
+			return !y
+		}
+	}
+
+Error:
+	panic(fmt.Sprintf("invalid unary operation %s%v", op, y))
+}
+
+var (
+	int1 = big.NewInt(1)
+	rat0 = big.NewRat(0, 1)
+)
+
+func ord(x Value) int {
+	switch x.(type) {
+	default:
+		return 0
+	case boolVal, stringVal:
+		return 1
+	case int64Val:
+		return 2
+	case intVal:
+		return 3
+	case floatVal:
+		return 4
+	case complexVal:
+		return 5
+	}
+}
+
+// match returns the matching representation (same type) with the
+// smallest complexity for two values x and y. If one of them is
+// numeric, both of them must be numeric. If one of them is Unknown,
+// both results are Unknown.
+//
+func match(x, y Value) (_, _ Value) {
+	if ord(x) > ord(y) {
+		y, x = match(y, x)
+		return x, y
+	}
+	// ord(x) <= ord(y)
+
+	switch x := x.(type) {
+	case unknownVal:
+		return x, x
+
+	case boolVal, stringVal, complexVal:
+		return x, y
+
+	case int64Val:
+		switch y := y.(type) {
+		case int64Val:
+			return x, y
+		case intVal:
+			return intVal{big.NewInt(int64(x))}, y
+		case floatVal:
+			return floatVal{big.NewRat(int64(x), 1)}, y
+		case complexVal:
+			return complexVal{big.NewRat(int64(x), 1), rat0}, y
+		}
+
+	case intVal:
+		switch y := y.(type) {
+		case intVal:
+			return x, y
+		case floatVal:
+			return floatVal{new(big.Rat).SetFrac(x.val, int1)}, y
+		case complexVal:
+			return complexVal{new(big.Rat).SetFrac(x.val, int1), rat0}, y
+		}
+
+	case floatVal:
+		switch y := y.(type) {
+		case floatVal:
+			return x, y
+		case complexVal:
+			return complexVal{x.val, rat0}, y
+		}
+	}
+
+	panic("unreachable")
+}
+
+// BinaryOp returns the result of the binary expression x op y.
+// The operation must be defined for the operands. If one of the
+// operands is Unknown, the result is Unknown.
+// To force integer division of Int operands, use op == token.QUO_ASSIGN
+// instead of token.QUO; the result is guaranteed to be Int in this case.
+// Division by zero leads to a run-time panic.
+//
+func BinaryOp(x Value, op token.Token, y Value) Value {
+	x, y = match(x, y)
+
+	switch x := x.(type) {
+	case unknownVal:
+		return x
+
+	case boolVal:
+		y := y.(boolVal)
+		switch op {
+		case token.LAND:
+			return x && y
+		case token.LOR:
+			return x || y
+		}
+
+	case int64Val:
+		a := int64(x)
+		b := int64(y.(int64Val))
+		var c int64
+		switch op {
+		case token.ADD:
+			if !is63bit(a) || !is63bit(b) {
+				return normInt(new(big.Int).Add(big.NewInt(a), big.NewInt(b)))
+			}
+			c = a + b
+		case token.SUB:
+			if !is63bit(a) || !is63bit(b) {
+				return normInt(new(big.Int).Sub(big.NewInt(a), big.NewInt(b)))
+			}
+			c = a - b
+		case token.MUL:
+			if !is32bit(a) || !is32bit(b) {
+				return normInt(new(big.Int).Mul(big.NewInt(a), big.NewInt(b)))
+			}
+			c = a * b
+		case token.QUO:
+			return normFloat(new(big.Rat).SetFrac(big.NewInt(a), big.NewInt(b)))
+		case token.QUO_ASSIGN: // force integer division
+			c = a / b
+		case token.REM:
+			c = a % b
+		case token.AND:
+			c = a & b
+		case token.OR:
+			c = a | b
+		case token.XOR:
+			c = a ^ b
+		case token.AND_NOT:
+			c = a &^ b
+		default:
+			goto Error
+		}
+		return int64Val(c)
+
+	case intVal:
+		a := x.val
+		b := y.(intVal).val
+		var c big.Int
+		switch op {
+		case token.ADD:
+			c.Add(a, b)
+		case token.SUB:
+			c.Sub(a, b)
+		case token.MUL:
+			c.Mul(a, b)
+		case token.QUO:
+			return normFloat(new(big.Rat).SetFrac(a, b))
+		case token.QUO_ASSIGN: // force integer division
+			c.Quo(a, b)
+		case token.REM:
+			c.Rem(a, b)
+		case token.AND:
+			c.And(a, b)
+		case token.OR:
+			c.Or(a, b)
+		case token.XOR:
+			c.Xor(a, b)
+		case token.AND_NOT:
+			c.AndNot(a, b)
+		default:
+			goto Error
+		}
+		return normInt(&c)
+
+	case floatVal:
+		a := x.val
+		b := y.(floatVal).val
+		var c big.Rat
+		switch op {
+		case token.ADD:
+			c.Add(a, b)
+		case token.SUB:
+			c.Sub(a, b)
+		case token.MUL:
+			c.Mul(a, b)
+		case token.QUO:
+			c.Quo(a, b)
+		default:
+			goto Error
+		}
+		return normFloat(&c)
+
+	case complexVal:
+		y := y.(complexVal)
+		a, b := x.re, x.im
+		c, d := y.re, y.im
+		var re, im big.Rat
+		switch op {
+		case token.ADD:
+			// (a+c) + i(b+d)
+			re.Add(a, c)
+			im.Add(b, d)
+		case token.SUB:
+			// (a-c) + i(b-d)
+			re.Sub(a, c)
+			im.Sub(b, d)
+		case token.MUL:
+			// (ac-bd) + i(bc+ad)
+			var ac, bd, bc, ad big.Rat
+			ac.Mul(a, c)
+			bd.Mul(b, d)
+			bc.Mul(b, c)
+			ad.Mul(a, d)
+			re.Sub(&ac, &bd)
+			im.Add(&bc, &ad)
+		case token.QUO:
+			// (ac+bd)/s + i(bc-ad)/s, with s = cc + dd
+			var ac, bd, bc, ad, s, cc, dd big.Rat
+			ac.Mul(a, c)
+			bd.Mul(b, d)
+			bc.Mul(b, c)
+			ad.Mul(a, d)
+			cc.Mul(c, c)
+			dd.Mul(d, d)
+			s.Add(&cc, &dd)
+			re.Add(&ac, &bd)
+			re.Quo(&re, &s)
+			im.Sub(&bc, &ad)
+			im.Quo(&im, &s)
+		default:
+			goto Error
+		}
+		return normComplex(&re, &im)
+
+	case stringVal:
+		if op == token.ADD {
+			return x + y.(stringVal)
+		}
+	}
+
+Error:
+	panic(fmt.Sprintf("invalid binary operation %v %s %v", x, op, y))
+}
+
+// Shift returns the result of the shift expression x op s
+// with op == token.SHL or token.SHR (<< or >>). x must be
+// an Int or an Unknown. If x is Unknown, the result is x.
+//
+func Shift(x Value, op token.Token, s uint) Value {
+	switch x := x.(type) {
+	case unknownVal:
+		return x
+
+	case int64Val:
+		if s == 0 {
+			return x
+		}
+		switch op {
+		case token.SHL:
+			z := big.NewInt(int64(x))
+			return normInt(z.Lsh(z, s))
+		case token.SHR:
+			return x >> s
+		}
+
+	case intVal:
+		if s == 0 {
+			return x
+		}
+		var z big.Int
+		switch op {
+		case token.SHL:
+			return normInt(z.Lsh(x.val, s))
+		case token.SHR:
+			return normInt(z.Rsh(x.val, s))
+		}
+	}
+
+	panic(fmt.Sprintf("invalid shift %v %s %d", x, op, s))
+}
+
+func cmpZero(x int, op token.Token) bool {
+	switch op {
+	case token.EQL:
+		return x == 0
+	case token.NEQ:
+		return x != 0
+	case token.LSS:
+		return x < 0
+	case token.LEQ:
+		return x <= 0
+	case token.GTR:
+		return x > 0
+	case token.GEQ:
+		return x >= 0
+	}
+	panic("unreachable")
+}
+
+// Compare returns the result of the comparison x op y.
+// The comparison must be defined for the operands.
+// If one of the operands is Unknown, the result is
+// false.
+//
+func Compare(x Value, op token.Token, y Value) bool {
+	x, y = match(x, y)
+
+	switch x := x.(type) {
+	case unknownVal:
+		return false
+
+	case boolVal:
+		y := y.(boolVal)
+		switch op {
+		case token.EQL:
+			return x == y
+		case token.NEQ:
+			return x != y
+		}
+
+	case int64Val:
+		y := y.(int64Val)
+		switch op {
+		case token.EQL:
+			return x == y
+		case token.NEQ:
+			return x != y
+		case token.LSS:
+			return x < y
+		case token.LEQ:
+			return x <= y
+		case token.GTR:
+			return x > y
+		case token.GEQ:
+			return x >= y
+		}
+
+	case intVal:
+		return cmpZero(x.val.Cmp(y.(intVal).val), op)
+
+	case floatVal:
+		return cmpZero(x.val.Cmp(y.(floatVal).val), op)
+
+	case complexVal:
+		y := y.(complexVal)
+		re := x.re.Cmp(y.re)
+		im := x.im.Cmp(y.im)
+		switch op {
+		case token.EQL:
+			return re == 0 && im == 0
+		case token.NEQ:
+			return re != 0 || im != 0
+		}
+
+	case stringVal:
+		y := y.(stringVal)
+		switch op {
+		case token.EQL:
+			return x == y
+		case token.NEQ:
+			return x != y
+		case token.LSS:
+			return x < y
+		case token.LEQ:
+			return x <= y
+		case token.GTR:
+			return x > y
+		case token.GEQ:
+			return x >= y
+		}
+	}
+
+	panic(fmt.Sprintf("invalid comparison %v %s %v", x, op, y))
+}
diff --git a/third_party/gofrontend/libgo/go/go/constant/value_test.go b/third_party/gofrontend/libgo/go/go/constant/value_test.go
new file mode 100644
index 0000000..08cdd5e
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/go/constant/value_test.go
@@ -0,0 +1,375 @@
+// Copyright 2013 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 constant
+
+import (
+	"go/token"
+	"strings"
+	"testing"
+)
+
+// TODO(gri) expand this test framework
+
+var opTests = []string{
+	// unary operations
+	`+ 0 = 0`,
+	`+ ? = ?`,
+	`- 1 = -1`,
+	`- ? = ?`,
+	`^ 0 = -1`,
+	`^ ? = ?`,
+
+	`! true = false`,
+	`! false = true`,
+	`! ? = ?`,
+
+	// etc.
+
+	// binary operations
+	`"" + "" = ""`,
+	`"foo" + "" = "foo"`,
+	`"" + "bar" = "bar"`,
+	`"foo" + "bar" = "foobar"`,
+
+	`0 + 0 = 0`,
+	`0 + 0.1 = 0.1`,
+	`0 + 0.1i = 0.1i`,
+	`0.1 + 0.9 = 1`,
+	`1e100 + 1e100 = 2e100`,
+	`? + 0 = ?`,
+	`0 + ? = ?`,
+
+	`0 - 0 = 0`,
+	`0 - 0.1 = -0.1`,
+	`0 - 0.1i = -0.1i`,
+	`1e100 - 1e100 = 0`,
+	`? - 0 = ?`,
+	`0 - ? = ?`,
+
+	`0 * 0 = 0`,
+	`1 * 0.1 = 0.1`,
+	`1 * 0.1i = 0.1i`,
+	`1i * 1i = -1`,
+	`? * 0 = ?`,
+	`0 * ? = ?`,
+
+	`0 / 0 = "division_by_zero"`,
+	`10 / 2 = 5`,
+	`5 / 3 = 5/3`,
+	`5i / 3i = 5/3`,
+	`? / 0 = ?`,
+	`0 / ? = ?`,
+
+	`0 % 0 = "runtime_error:_integer_divide_by_zero"`, // TODO(gri) should be the same as for /
+	`10 % 3 = 1`,
+	`? % 0 = ?`,
+	`0 % ? = ?`,
+
+	`0 & 0 = 0`,
+	`12345 & 0 = 0`,
+	`0xff & 0xf = 0xf`,
+	`? & 0 = ?`,
+	`0 & ? = ?`,
+
+	`0 | 0 = 0`,
+	`12345 | 0 = 12345`,
+	`0xb | 0xa0 = 0xab`,
+	`? | 0 = ?`,
+	`0 | ? = ?`,
+
+	`0 ^ 0 = 0`,
+	`1 ^ -1 = -2`,
+	`? ^ 0 = ?`,
+	`0 ^ ? = ?`,
+
+	`0 &^ 0 = 0`,
+	`0xf &^ 1 = 0xe`,
+	`1 &^ 0xf = 0`,
+	// etc.
+
+	// shifts
+	`0 << 0 = 0`,
+	`1 << 10 = 1024`,
+	`0 >> 0 = 0`,
+	`1024 >> 10 == 1`,
+	`? << 0 == ?`,
+	`? >> 10 == ?`,
+	// etc.
+
+	// comparisons
+	`false == false = true`,
+	`false == true = false`,
+	`true == false = false`,
+	`true == true = true`,
+
+	`false != false = false`,
+	`false != true = true`,
+	`true != false = true`,
+	`true != true = false`,
+
+	`"foo" == "bar" = false`,
+	`"foo" != "bar" = true`,
+	`"foo" < "bar" = false`,
+	`"foo" <= "bar" = false`,
+	`"foo" > "bar" = true`,
+	`"foo" >= "bar" = true`,
+
+	`0 == 0 = true`,
+	`0 != 0 = false`,
+	`0 < 10 = true`,
+	`10 <= 10 = true`,
+	`0 > 10 = false`,
+	`10 >= 10 = true`,
+
+	`1/123456789 == 1/123456789 == true`,
+	`1/123456789 != 1/123456789 == false`,
+	`1/123456789 < 1/123456788 == true`,
+	`1/123456788 <= 1/123456789 == false`,
+	`0.11 > 0.11 = false`,
+	`0.11 >= 0.11 = true`,
+
+	`? == 0 = false`,
+	`? != 0 = false`,
+	`? < 10 = false`,
+	`? <= 10 = false`,
+	`? > 10 = false`,
+	`? >= 10 = false`,
+
+	`0 == ? = false`,
+	`0 != ? = false`,
+	`0 < ? = false`,
+	`10 <= ? = false`,
+	`0 > ? = false`,
+	`10 >= ? = false`,
+
+	// etc.
+}
+
+func TestOps(t *testing.T) {
+	for _, test := range opTests {
+		a := strings.Split(test, " ")
+		i := 0 // operator index
+
+		var x, x0 Value
+		switch len(a) {
+		case 4:
+			// unary operation
+		case 5:
+			// binary operation
+			x, x0 = val(a[0]), val(a[0])
+			i = 1
+		default:
+			t.Errorf("invalid test case: %s", test)
+			continue
+		}
+
+		op, ok := optab[a[i]]
+		if !ok {
+			panic("missing optab entry for " + a[i])
+		}
+
+		y, y0 := val(a[i+1]), val(a[i+1])
+
+		got := doOp(x, op, y)
+		want := val(a[i+3])
+		if !eql(got, want) {
+			t.Errorf("%s: got %s; want %s", test, got, want)
+		}
+		if x0 != nil && !eql(x, x0) {
+			t.Errorf("%s: x changed to %s", test, x)
+		}
+		if !eql(y, y0) {
+			t.Errorf("%s: y changed to %s", test, y)
+		}
+	}
+}
+
+func eql(x, y Value) bool {
+	_, ux := x.(unknownVal)
+	_, uy := y.(unknownVal)
+	if ux || uy {
+		return ux == uy
+	}
+	return Compare(x, token.EQL, y)
+}
+
+// ----------------------------------------------------------------------------
+// Support functions
+
+func val(lit string) Value {
+	if len(lit) == 0 {
+		return MakeUnknown()
+	}
+
+	switch lit {
+	case "?":
+		return MakeUnknown()
+	case "true":
+		return MakeBool(true)
+	case "false":
+		return MakeBool(false)
+	}
+
+	tok := token.INT
+	switch first, last := lit[0], lit[len(lit)-1]; {
+	case first == '"' || first == '`':
+		tok = token.STRING
+		lit = strings.Replace(lit, "_", " ", -1)
+	case first == '\'':
+		tok = token.CHAR
+	case last == 'i':
+		tok = token.IMAG
+	default:
+		if !strings.HasPrefix(lit, "0x") && strings.ContainsAny(lit, "./Ee") {
+			tok = token.FLOAT
+		}
+	}
+
+	return MakeFromLiteral(lit, tok, 0)
+}
+
+var optab = map[string]token.Token{
+	"!": token.NOT,
+
+	"+": token.ADD,
+	"-": token.SUB,
+	"*": token.MUL,
+	"/": token.QUO,
+	"%": token.REM,
+
+	"<<": token.SHL,
+	">>": token.SHR,
+
+	"&":  token.AND,
+	"|":  token.OR,
+	"^":  token.XOR,
+	"&^": token.AND_NOT,
+
+	"==": token.EQL,
+	"!=": token.NEQ,
+	"<":  token.LSS,
+	"<=": token.LEQ,
+	">":  token.GTR,
+	">=": token.GEQ,
+}
+
+func panicHandler(v *Value) {
+	switch p := recover().(type) {
+	case nil:
+		// nothing to do
+	case string:
+		*v = MakeString(p)
+	case error:
+		*v = MakeString(p.Error())
+	default:
+		panic(p)
+	}
+}
+
+func doOp(x Value, op token.Token, y Value) (z Value) {
+	defer panicHandler(&z)
+
+	if x == nil {
+		return UnaryOp(op, y, 0)
+	}
+
+	switch op {
+	case token.EQL, token.NEQ, token.LSS, token.LEQ, token.GTR, token.GEQ:
+		return MakeBool(Compare(x, op, y))
+	case token.SHL, token.SHR:
+		s, _ := Int64Val(y)
+		return Shift(x, op, uint(s))
+	default:
+		return BinaryOp(x, op, y)
+	}
+}
+
+// ----------------------------------------------------------------------------
+// Other tests
+
+var fracTests = []string{
+	"0 0 1",
+	"1 1 1",
+	"-1 -1 1",
+	"1.2 6 5",
+	"-0.991 -991 1000",
+	"1e100 1e100 1",
+}
+
+func TestFractions(t *testing.T) {
+	for _, test := range fracTests {
+		a := strings.Split(test, " ")
+		if len(a) != 3 {
+			t.Errorf("invalid test case: %s", test)
+			continue
+		}
+
+		x := val(a[0])
+		n := val(a[1])
+		d := val(a[2])
+
+		if got := Num(x); !eql(got, n) {
+			t.Errorf("%s: got num = %s; want %s", test, got, n)
+		}
+
+		if got := Denom(x); !eql(got, d) {
+			t.Errorf("%s: got denom = %s; want %s", test, got, d)
+		}
+	}
+}
+
+var bytesTests = []string{
+	"0",
+	"1",
+	"123456789",
+	"123456789012345678901234567890123456789012345678901234567890",
+}
+
+func TestBytes(t *testing.T) {
+	for _, test := range bytesTests {
+		x := val(test)
+		bytes := Bytes(x)
+
+		// special case 0
+		if Sign(x) == 0 && len(bytes) != 0 {
+			t.Errorf("%s: got %v; want empty byte slice", test, bytes)
+		}
+
+		if n := len(bytes); n > 0 && bytes[n-1] == 0 {
+			t.Errorf("%s: got %v; want no leading 0 byte", test, bytes)
+		}
+
+		if got := MakeFromBytes(bytes); !eql(got, x) {
+			t.Errorf("%s: got %s; want %s (bytes = %v)", test, got, x, bytes)
+		}
+	}
+}
+
+func TestUnknown(t *testing.T) {
+	u := MakeUnknown()
+	var values = []Value{
+		u,
+		MakeBool(false), // token.ADD ok below, operation is never considered
+		MakeString(""),
+		MakeInt64(1),
+		MakeFromLiteral("-1234567890123456789012345678901234567890", token.INT, 0),
+		MakeFloat64(1.2),
+		MakeImag(MakeFloat64(1.2)),
+	}
+	for _, val := range values {
+		x, y := val, u
+		for i := range [2]int{} {
+			if i == 1 {
+				x, y = y, x
+			}
+			if got := BinaryOp(x, token.ADD, y); got.Kind() != Unknown {
+				t.Errorf("%s + %s: got %s; want %s", x, y, got, u)
+			}
+			if got := Compare(x, token.EQL, y); got {
+				t.Errorf("%s == %s: got true; want false", x, y)
+			}
+		}
+	}
+}
diff --git a/third_party/gofrontend/libgo/go/go/doc/doc.go b/third_party/gofrontend/libgo/go/go/doc/doc.go
index 4264940..3c3e28d 100644
--- a/third_party/gofrontend/libgo/go/go/doc/doc.go
+++ b/third_party/gofrontend/libgo/go/go/doc/doc.go
@@ -18,7 +18,8 @@
 	Imports    []string
 	Filenames  []string
 	Notes      map[string][]*Note
-	// DEPRECATED. For backward compatibility Bugs is still populated,
+
+	// Deprecated: For backward compatibility Bugs is still populated,
 	// but all new code should use Notes instead.
 	Bugs []string
 
diff --git a/third_party/gofrontend/libgo/go/go/doc/exports.go b/third_party/gofrontend/libgo/go/go/doc/exports.go
index 1d3b466..4a12b1e 100644
--- a/third_party/gofrontend/libgo/go/go/doc/exports.go
+++ b/third_party/gofrontend/libgo/go/go/doc/exports.go
@@ -12,13 +12,12 @@
 )
 
 // filterIdentList removes unexported names from list in place
-// and returns the resulting list. If blankOk is set, blank
-// identifiers are considered exported names.
+// and returns the resulting list.
 //
-func filterIdentList(list []*ast.Ident, blankOk bool) []*ast.Ident {
+func filterIdentList(list []*ast.Ident) []*ast.Ident {
 	j := 0
 	for _, x := range list {
-		if ast.IsExported(x.Name) || (blankOk && x.Name == "_") {
+		if ast.IsExported(x.Name) {
 			list[j] = x
 			j++
 		}
@@ -26,6 +25,17 @@
 	return list[0:j]
 }
 
+// hasExportedName reports whether list contains any exported names.
+//
+func hasExportedName(list []*ast.Ident) bool {
+	for _, x := range list {
+		if x.IsExported() {
+			return true
+		}
+	}
+	return false
+}
+
 // removeErrorField removes anonymous fields named "error" from an interface.
 // This is called when "error" has been determined to be a local name,
 // not the predeclared type.
@@ -53,7 +63,7 @@
 }
 
 // filterFieldList removes unexported fields (field names) from the field list
-// in place and returns true if fields were removed. Anonymous fields are
+// in place and reports whether fields were removed. Anonymous fields are
 // recorded with the parent type. filterType is called with the types of
 // all remaining fields.
 //
@@ -78,7 +88,7 @@
 				r.remember(ityp)
 			}
 		} else {
-			field.Names = filterIdentList(field.Names, false)
+			field.Names = filterIdentList(field.Names)
 			if len(field.Names) < n {
 				removedFields = true
 			}
@@ -146,9 +156,7 @@
 		// always keep imports so we can collect them
 		return true
 	case *ast.ValueSpec:
-		// special case: consider blank constants as exported
-		// (work-around for issue 5397)
-		s.Names = filterIdentList(s.Names, tok == token.CONST)
+		s.Names = filterIdentList(s.Names)
 		if len(s.Names) > 0 {
 			r.filterType(nil, s.Type)
 			return true
@@ -165,7 +173,46 @@
 	return false
 }
 
+// copyConstType returns a copy of typ with position pos.
+// typ must be a valid constant type.
+// In practice, only (possibly qualified) identifiers are possible.
+//
+func copyConstType(typ ast.Expr, pos token.Pos) ast.Expr {
+	switch typ := typ.(type) {
+	case *ast.Ident:
+		return &ast.Ident{Name: typ.Name, NamePos: pos}
+	case *ast.SelectorExpr:
+		if id, ok := typ.X.(*ast.Ident); ok {
+			// presumably a qualified identifier
+			return &ast.SelectorExpr{
+				Sel: ast.NewIdent(typ.Sel.Name),
+				X:   &ast.Ident{Name: id.Name, NamePos: pos},
+			}
+		}
+	}
+	return nil // shouldn't happen, but be conservative and don't panic
+}
+
 func (r *reader) filterSpecList(list []ast.Spec, tok token.Token) []ast.Spec {
+	if tok == token.CONST {
+		// Propagate any type information that would get lost otherwise
+		// when unexported constants are filtered.
+		var prevType ast.Expr
+		for _, spec := range list {
+			spec := spec.(*ast.ValueSpec)
+			if spec.Type == nil && prevType != nil {
+				// provide current spec with an explicit type
+				spec.Type = copyConstType(prevType, spec.Pos())
+			}
+			if hasExportedName(spec.Names) {
+				// exported names are preserved so there's no need to propagate the type
+				prevType = nil
+			} else {
+				prevType = spec.Type
+			}
+		}
+	}
+
 	j := 0
 	for _, s := range list {
 		if r.filterSpec(s, tok) {
diff --git a/third_party/gofrontend/libgo/go/go/doc/testdata/blank.0.golden b/third_party/gofrontend/libgo/go/go/doc/testdata/blank.0.golden
index dae3ab2..c2987cf 100644
--- a/third_party/gofrontend/libgo/go/go/doc/testdata/blank.0.golden
+++ b/third_party/gofrontend/libgo/go/go/doc/testdata/blank.0.golden
@@ -4,14 +4,33 @@
 IMPORTPATH
 	testdata/blank
 
+IMPORTS
+	os
+
 FILENAMES
 	testdata/blank.go
 
 CONSTANTS
+	// T constants counting from unexported constants. 
+	const (
+		C1	T
+		C2
+	
+		C3
+	
+		C4	int
+	)
+
+	// Constants with an imported type that needs to be propagated. 
+	const (
+		Default		os.FileMode	= 0644
+		Useless				= 0312
+		WideOpen			= 0777
+	)
+
 	// Package constants. 
 	const (
-		_	int	= iota
-		I1
+		I1	int
 		I2
 	)
 
@@ -28,10 +47,9 @@
 	// 
 	type T int
 
-	// T constants. 
+	// T constants counting from a blank constant. 
 	const (
-		_	T	= iota
-		T1
+		T1	T
 		T2
 	)
 
diff --git a/third_party/gofrontend/libgo/go/go/doc/testdata/blank.1.golden b/third_party/gofrontend/libgo/go/go/doc/testdata/blank.1.golden
index 333d7e5..ee5054a 100644
--- a/third_party/gofrontend/libgo/go/go/doc/testdata/blank.1.golden
+++ b/third_party/gofrontend/libgo/go/go/doc/testdata/blank.1.golden
@@ -4,10 +4,25 @@
 IMPORTPATH
 	testdata/blank
 
+IMPORTS
+	os
+
 FILENAMES
 	testdata/blank.go
 
 CONSTANTS
+	// T constants counting from unexported constants. 
+	const (
+		tweedledee	T	= iota
+		tweedledum
+		C1
+		C2
+		alice
+		C3
+		redQueen	int	= iota
+		C4
+	)
+
 	// Package constants. 
 	const (
 		_	int	= iota
@@ -15,6 +30,20 @@
 		I2
 	)
 
+	// Constants with an imported type that needs to be propagated. 
+	const (
+		zero		os.FileMode	= 0
+		Default				= 0644
+		Useless				= 0312
+		WideOpen			= 0777
+	)
+
+	// Unexported constants counting from blank iota. See issue 9615. 
+	const (
+		_	= iota
+		one	= iota + 1
+	)
+
 
 VARIABLES
 	// 
@@ -37,7 +66,7 @@
 	// 
 	type T int
 
-	// T constants. 
+	// T constants counting from a blank constant. 
 	const (
 		_	T	= iota
 		T1
diff --git a/third_party/gofrontend/libgo/go/go/doc/testdata/blank.2.golden b/third_party/gofrontend/libgo/go/go/doc/testdata/blank.2.golden
index dae3ab2..c2987cf 100644
--- a/third_party/gofrontend/libgo/go/go/doc/testdata/blank.2.golden
+++ b/third_party/gofrontend/libgo/go/go/doc/testdata/blank.2.golden
@@ -4,14 +4,33 @@
 IMPORTPATH
 	testdata/blank
 
+IMPORTS
+	os
+
 FILENAMES
 	testdata/blank.go
 
 CONSTANTS
+	// T constants counting from unexported constants. 
+	const (
+		C1	T
+		C2
+	
+		C3
+	
+		C4	int
+	)
+
+	// Constants with an imported type that needs to be propagated. 
+	const (
+		Default		os.FileMode	= 0644
+		Useless				= 0312
+		WideOpen			= 0777
+	)
+
 	// Package constants. 
 	const (
-		_	int	= iota
-		I1
+		I1	int
 		I2
 	)
 
@@ -28,10 +47,9 @@
 	// 
 	type T int
 
-	// T constants. 
+	// T constants counting from a blank constant. 
 	const (
-		_	T	= iota
-		T1
+		T1	T
 		T2
 	)
 
diff --git a/third_party/gofrontend/libgo/go/go/doc/testdata/blank.go b/third_party/gofrontend/libgo/go/go/doc/testdata/blank.go
index f812c77..419a78f 100644
--- a/third_party/gofrontend/libgo/go/go/doc/testdata/blank.go
+++ b/third_party/gofrontend/libgo/go/go/doc/testdata/blank.go
@@ -6,15 +6,37 @@
 // See issue 5397.
 package blank
 
+import "os"
+
 type T int
 
-// T constants.
+// T constants counting from a blank constant.
 const (
 	_ T = iota
 	T1
 	T2
 )
 
+// T constants counting from unexported constants.
+const (
+	tweedledee T = iota
+	tweedledum
+	C1
+	C2
+	alice
+	C3
+	redQueen int = iota
+	C4
+)
+
+// Constants with an imported type that needs to be propagated.
+const (
+	zero     os.FileMode = 0
+	Default              = 0644
+	Useless              = 0312
+	WideOpen             = 0777
+)
+
 // Package constants.
 const (
 	_ int = iota
@@ -22,6 +44,13 @@
 	I2
 )
 
+// Unexported constants counting from blank iota.
+// See issue 9615.
+const (
+	_   = iota
+	one = iota + 1
+)
+
 // Blanks not in doc output:
 
 // S has a padding field.
diff --git a/third_party/gofrontend/libgo/go/go/format/format.go b/third_party/gofrontend/libgo/go/go/format/format.go
index 668a42d..1adfd7d 100644
--- a/third_party/gofrontend/libgo/go/go/format/format.go
+++ b/third_party/gofrontend/libgo/go/go/format/format.go
@@ -12,8 +12,8 @@
 	"go/parser"
 	"go/printer"
 	"go/token"
+	"internal/format"
 	"io"
-	"strings"
 )
 
 var config = printer.Config{Mode: printer.UseSpaces | printer.TabIndent, Tabwidth: 8}
@@ -82,7 +82,7 @@
 //
 func Source(src []byte) ([]byte, error) {
 	fset := token.NewFileSet()
-	file, sourceAdj, indentAdj, err := parse(fset, "", src, true)
+	file, sourceAdj, indentAdj, err := format.Parse(fset, "", src, true)
 	if err != nil {
 		return nil, err
 	}
@@ -93,7 +93,7 @@
 		ast.SortImports(fset, file)
 	}
 
-	return format(fset, file, sourceAdj, indentAdj, src, config)
+	return format.Format(fset, file, sourceAdj, indentAdj, src, config)
 }
 
 func hasUnsortedImports(file *ast.File) bool {
@@ -113,154 +113,3 @@
 	}
 	return false
 }
-
-// ----------------------------------------------------------------------------
-// Support functions
-//
-// The functions parse, format, and isSpace below are identical to the
-// respective functions in cmd/gofmt/gofmt.go - keep them in sync!
-//
-// TODO(gri) Factor out this functionality, eventually.
-
-// parse parses src, which was read from the named file,
-// as a Go source file, declaration, or statement list.
-func parse(fset *token.FileSet, filename string, src []byte, fragmentOk bool) (
-	file *ast.File,
-	sourceAdj func(src []byte, indent int) []byte,
-	indentAdj int,
-	err error,
-) {
-	// Try as whole source file.
-	file, err = parser.ParseFile(fset, filename, src, parserMode)
-	// If there's no error, return.  If the error is that the source file didn't begin with a
-	// package line and source fragments are ok, fall through to
-	// try as a source fragment.  Stop and return on any other error.
-	if err == nil || !fragmentOk || !strings.Contains(err.Error(), "expected 'package'") {
-		return
-	}
-
-	// If this is a declaration list, make it a source file
-	// by inserting a package clause.
-	// Insert using a ;, not a newline, so that the line numbers
-	// in psrc match the ones in src.
-	psrc := append([]byte("package p;"), src...)
-	file, err = parser.ParseFile(fset, filename, psrc, parserMode)
-	if err == nil {
-		sourceAdj = func(src []byte, indent int) []byte {
-			// Remove the package clause.
-			// Gofmt has turned the ; into a \n.
-			src = src[indent+len("package p\n"):]
-			return bytes.TrimSpace(src)
-		}
-		return
-	}
-	// If the error is that the source file didn't begin with a
-	// declaration, fall through to try as a statement list.
-	// Stop and return on any other error.
-	if !strings.Contains(err.Error(), "expected declaration") {
-		return
-	}
-
-	// If this is a statement list, make it a source file
-	// by inserting a package clause and turning the list
-	// into a function body.  This handles expressions too.
-	// Insert using a ;, not a newline, so that the line numbers
-	// in fsrc match the ones in src.
-	fsrc := append(append([]byte("package p; func _() {"), src...), '\n', '}')
-	file, err = parser.ParseFile(fset, filename, fsrc, parserMode)
-	if err == nil {
-		sourceAdj = func(src []byte, indent int) []byte {
-			// Cap adjusted indent to zero.
-			if indent < 0 {
-				indent = 0
-			}
-			// Remove the wrapping.
-			// Gofmt has turned the ; into a \n\n.
-			// There will be two non-blank lines with indent, hence 2*indent.
-			src = src[2*indent+len("package p\n\nfunc _() {"):]
-			src = src[:len(src)-(indent+len("\n}\n"))]
-			return bytes.TrimSpace(src)
-		}
-		// Gofmt has also indented the function body one level.
-		// Adjust that with indentAdj.
-		indentAdj = -1
-	}
-
-	// Succeeded, or out of options.
-	return
-}
-
-// format formats the given package file originally obtained from src
-// and adjusts the result based on the original source via sourceAdj
-// and indentAdj.
-func format(
-	fset *token.FileSet,
-	file *ast.File,
-	sourceAdj func(src []byte, indent int) []byte,
-	indentAdj int,
-	src []byte,
-	cfg printer.Config,
-) ([]byte, error) {
-	if sourceAdj == nil {
-		// Complete source file.
-		var buf bytes.Buffer
-		err := cfg.Fprint(&buf, fset, file)
-		if err != nil {
-			return nil, err
-		}
-		return buf.Bytes(), nil
-	}
-
-	// Partial source file.
-	// Determine and prepend leading space.
-	i, j := 0, 0
-	for j < len(src) && isSpace(src[j]) {
-		if src[j] == '\n' {
-			i = j + 1 // byte offset of last line in leading space
-		}
-		j++
-	}
-	var res []byte
-	res = append(res, src[:i]...)
-
-	// Determine and prepend indentation of first code line.
-	// Spaces are ignored unless there are no tabs,
-	// in which case spaces count as one tab.
-	indent := 0
-	hasSpace := false
-	for _, b := range src[i:j] {
-		switch b {
-		case ' ':
-			hasSpace = true
-		case '\t':
-			indent++
-		}
-	}
-	if indent == 0 && hasSpace {
-		indent = 1
-	}
-	for i := 0; i < indent; i++ {
-		res = append(res, '\t')
-	}
-
-	// Format the source.
-	// Write it without any leading and trailing space.
-	cfg.Indent = indent + indentAdj
-	var buf bytes.Buffer
-	err := cfg.Fprint(&buf, fset, file)
-	if err != nil {
-		return nil, err
-	}
-	res = append(res, sourceAdj(buf.Bytes(), cfg.Indent)...)
-
-	// Determine and append trailing space.
-	i = len(src)
-	for i > 0 && isSpace(src[i-1]) {
-		i--
-	}
-	return append(res, src[i:]...), nil
-}
-
-func isSpace(b byte) bool {
-	return b == ' ' || b == '\t' || b == '\n' || b == '\r'
-}
diff --git a/third_party/gofrontend/libgo/go/go/format/format_test.go b/third_party/gofrontend/libgo/go/go/format/format_test.go
index d7846be..000c611 100644
--- a/third_party/gofrontend/libgo/go/go/format/format_test.go
+++ b/third_party/gofrontend/libgo/go/go/format/format_test.go
@@ -91,7 +91,11 @@
 	"\n\t\t\n\n\t\t\tx := 0\n\t\t\tconst s = `\n\t\tfoo\n`\n\n\n", // no indentation removed inside raw strings
 
 	// comments
-	"i := 5 /* Comment */", // Issue 5551.
+	"i := 5 /* Comment */",         // Issue 5551.
+	"\ta()\n//line :1",             // Issue 11276.
+	"\t//xxx\n\ta()\n//line :2",    // Issue 11276.
+	"\ta() //line :1\n\tb()\n",     // Issue 11276.
+	"x := 0\n//line :1\n//line :2", // Issue 11276.
 
 	// erroneous programs
 	"ERROR1 + 2 +",
diff --git a/third_party/gofrontend/libgo/go/go/importer/importer.go b/third_party/gofrontend/libgo/go/go/importer/importer.go
new file mode 100644
index 0000000..4590ca3
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/go/importer/importer.go
@@ -0,0 +1,69 @@
+// 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 importer provides access to export data importers.
+package importer
+
+import (
+	"go/internal/gccgoimporter"
+	"go/internal/gcimporter"
+	"go/types"
+	"io"
+	"runtime"
+)
+
+// A Lookup function returns a reader to access package data for
+// a given import path, or an error if no matching package is found.
+type Lookup func(path string) (io.ReadCloser, error)
+
+// For returns an Importer for the given compiler and lookup interface,
+// or nil. Supported compilers are "gc", and "gccgo". If lookup is nil,
+// the default package lookup mechanism for the given compiler is used.
+func For(compiler string, lookup Lookup) types.Importer {
+	switch compiler {
+	case "gc":
+		if lookup == nil {
+			return make(gcimports)
+		}
+		panic("gc importer for custom import path lookup not yet implemented")
+	case "gccgo":
+		if lookup == nil {
+			var inst gccgoimporter.GccgoInstallation
+			if err := inst.InitFromDriver("gccgo"); err != nil {
+				return nil
+			}
+			return &gccgoimports{
+				packages: make(map[string]*types.Package),
+				importer: inst.GetImporter(nil, nil),
+			}
+		}
+		panic("gccgo importer for custom import path lookup not yet implemented")
+	}
+	// compiler not supported
+	return nil
+}
+
+// Default returns an Importer for the compiler that built the running binary.
+func Default() types.Importer {
+	return For(runtime.Compiler, nil)
+}
+
+// gc support
+
+type gcimports map[string]*types.Package
+
+func (m gcimports) Import(path string) (*types.Package, error) {
+	return gcimporter.Import(m, path)
+}
+
+// gccgo support
+
+type gccgoimports struct {
+	packages map[string]*types.Package
+	importer gccgoimporter.Importer
+}
+
+func (m *gccgoimports) Import(path string) (*types.Package, error) {
+	return m.importer(m.packages, path)
+}
diff --git a/third_party/gofrontend/libgo/go/go/internal/gccgoimporter/gccgoinstallation.go b/third_party/gofrontend/libgo/go/go/internal/gccgoimporter/gccgoinstallation.go
new file mode 100644
index 0000000..622dfc8
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/go/internal/gccgoimporter/gccgoinstallation.go
@@ -0,0 +1,94 @@
+// Copyright 2013 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 gccgoimporter
+
+import (
+	"bufio"
+	"go/types"
+	"os"
+	"os/exec"
+	"path/filepath"
+	"strings"
+)
+
+// Information about a specific installation of gccgo.
+type GccgoInstallation struct {
+	// Version of gcc (e.g. 4.8.0).
+	GccVersion string
+
+	// Target triple (e.g. x86_64-unknown-linux-gnu).
+	TargetTriple string
+
+	// Built-in library paths used by this installation.
+	LibPaths []string
+}
+
+// Ask the driver at the given path for information for this GccgoInstallation.
+func (inst *GccgoInstallation) InitFromDriver(gccgoPath string) (err error) {
+	cmd := exec.Command(gccgoPath, "-###", "-S", "-x", "go", "-")
+	stderr, err := cmd.StderrPipe()
+	if err != nil {
+		return
+	}
+
+	err = cmd.Start()
+	if err != nil {
+		return
+	}
+
+	scanner := bufio.NewScanner(stderr)
+	for scanner.Scan() {
+		line := scanner.Text()
+		switch {
+		case strings.HasPrefix(line, "Target: "):
+			inst.TargetTriple = line[8:]
+
+		case line[0] == ' ':
+			args := strings.Fields(line)
+			for _, arg := range args[1:] {
+				if strings.HasPrefix(arg, "-L") {
+					inst.LibPaths = append(inst.LibPaths, arg[2:])
+				}
+			}
+		}
+	}
+
+	stdout, err := exec.Command(gccgoPath, "-dumpversion").Output()
+	if err != nil {
+		return
+	}
+	inst.GccVersion = strings.TrimSpace(string(stdout))
+
+	return
+}
+
+// Return the list of export search paths for this GccgoInstallation.
+func (inst *GccgoInstallation) SearchPaths() (paths []string) {
+	for _, lpath := range inst.LibPaths {
+		spath := filepath.Join(lpath, "go", inst.GccVersion)
+		fi, err := os.Stat(spath)
+		if err != nil || !fi.IsDir() {
+			continue
+		}
+		paths = append(paths, spath)
+
+		spath = filepath.Join(spath, inst.TargetTriple)
+		fi, err = os.Stat(spath)
+		if err != nil || !fi.IsDir() {
+			continue
+		}
+		paths = append(paths, spath)
+	}
+
+	paths = append(paths, inst.LibPaths...)
+
+	return
+}
+
+// Return an importer that searches incpaths followed by the gcc installation's
+// built-in search paths and the current directory.
+func (inst *GccgoInstallation) GetImporter(incpaths []string, initmap map[*types.Package]InitData) Importer {
+	return GetImporter(append(append(incpaths, inst.SearchPaths()...), "."), initmap)
+}
diff --git a/third_party/gofrontend/libgo/go/go/internal/gccgoimporter/gccgoinstallation_test.go b/third_party/gofrontend/libgo/go/go/internal/gccgoimporter/gccgoinstallation_test.go
new file mode 100644
index 0000000..a2acaf7
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/go/internal/gccgoimporter/gccgoinstallation_test.go
@@ -0,0 +1,197 @@
+// Copyright 2013 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 gccgoimporter
+
+import (
+	"go/types"
+	"runtime"
+	"testing"
+)
+
+var importablePackages = [...]string{
+	"archive/tar",
+	"archive/zip",
+	"bufio",
+	"bytes",
+	"compress/bzip2",
+	"compress/flate",
+	"compress/gzip",
+	"compress/lzw",
+	"compress/zlib",
+	"container/heap",
+	"container/list",
+	"container/ring",
+	"crypto/aes",
+	"crypto/cipher",
+	"crypto/des",
+	"crypto/dsa",
+	"crypto/ecdsa",
+	"crypto/elliptic",
+	"crypto",
+	"crypto/hmac",
+	"crypto/md5",
+	"crypto/rand",
+	"crypto/rc4",
+	"crypto/rsa",
+	"crypto/sha1",
+	"crypto/sha256",
+	"crypto/sha512",
+	"crypto/subtle",
+	"crypto/tls",
+	"crypto/x509",
+	"crypto/x509/pkix",
+	"database/sql/driver",
+	"database/sql",
+	"debug/dwarf",
+	"debug/elf",
+	"debug/gosym",
+	"debug/macho",
+	"debug/pe",
+	"encoding/ascii85",
+	"encoding/asn1",
+	"encoding/base32",
+	"encoding/base64",
+	"encoding/binary",
+	"encoding/csv",
+	"encoding/gob",
+	"encoding",
+	"encoding/hex",
+	"encoding/json",
+	"encoding/pem",
+	"encoding/xml",
+	"errors",
+	"exp/proxy",
+	"exp/terminal",
+	"expvar",
+	"flag",
+	"fmt",
+	"go/ast",
+	"go/build",
+	"go/doc",
+	"go/format",
+	"go/parser",
+	"go/printer",
+	"go/scanner",
+	"go/token",
+	"hash/adler32",
+	"hash/crc32",
+	"hash/crc64",
+	"hash/fnv",
+	"hash",
+	"html",
+	"html/template",
+	"image/color",
+	"image/color/palette",
+	"image/draw",
+	"image/gif",
+	"image",
+	"image/jpeg",
+	"image/png",
+	"index/suffixarray",
+	"io",
+	"io/ioutil",
+	"log",
+	"log/syslog",
+	"math/big",
+	"math/cmplx",
+	"math",
+	"math/rand",
+	"mime",
+	"mime/multipart",
+	"net",
+	"net/http/cgi",
+	"net/http/cookiejar",
+	"net/http/fcgi",
+	"net/http",
+	"net/http/httptest",
+	"net/http/httputil",
+	"net/http/pprof",
+	"net/mail",
+	"net/rpc",
+	"net/rpc/jsonrpc",
+	"net/smtp",
+	"net/textproto",
+	"net/url",
+	"old/regexp",
+	"old/template",
+	"os/exec",
+	"os",
+	"os/signal",
+	"os/user",
+	"path/filepath",
+	"path",
+	"reflect",
+	"regexp",
+	"regexp/syntax",
+	"runtime/debug",
+	"runtime",
+	"runtime/pprof",
+	"sort",
+	"strconv",
+	"strings",
+	"sync/atomic",
+	"sync",
+	"syscall",
+	"testing",
+	"testing/iotest",
+	"testing/quick",
+	"text/scanner",
+	"text/tabwriter",
+	"text/template",
+	"text/template/parse",
+	"time",
+	"unicode",
+	"unicode/utf16",
+	"unicode/utf8",
+}
+
+func TestInstallationImporter(t *testing.T) {
+	// This test relies on gccgo being around, which it most likely will be if we
+	// were compiled with gccgo.
+	if runtime.Compiler != "gccgo" {
+		t.Skip("This test needs gccgo")
+		return
+	}
+
+	// Even when we have gccgo, this doesn't work while building
+	// gccgo itself.
+	t.Skip("gccgo is not necessarily available")
+
+	var inst GccgoInstallation
+	err := inst.InitFromDriver("gccgo")
+	if err != nil {
+		t.Fatal(err)
+	}
+	imp := inst.GetImporter(nil, nil)
+
+	// Ensure we don't regress the number of packages we can parse. First import
+	// all packages into the same map and then each individually.
+	pkgMap := make(map[string]*types.Package)
+	for _, pkg := range importablePackages {
+		_, err = imp(pkgMap, pkg)
+		if err != nil {
+			t.Error(err)
+		}
+	}
+
+	for _, pkg := range importablePackages {
+		_, err = imp(make(map[string]*types.Package), pkg)
+		if err != nil {
+			t.Error(err)
+		}
+	}
+
+	// Test for certain specific entities in the imported data.
+	for _, test := range [...]importerTest{
+		{pkgpath: "io", name: "Reader", want: "type Reader interface{Read(p []uint8) (n int, err error)}"},
+		{pkgpath: "io", name: "ReadWriter", want: "type ReadWriter interface{Reader; Writer}"},
+		{pkgpath: "math", name: "Pi", want: "const Pi untyped float"},
+		{pkgpath: "math", name: "Sin", want: "func Sin(x float64) float64"},
+		{pkgpath: "sort", name: "Ints", want: "func Ints(a []int)"},
+		{pkgpath: "unsafe", name: "Pointer", want: "type Pointer unsafe.Pointer"},
+	} {
+		runImporterTest(t, imp, nil, &test)
+	}
+}
diff --git a/third_party/gofrontend/libgo/go/go/internal/gccgoimporter/importer.go b/third_party/gofrontend/libgo/go/go/internal/gccgoimporter/importer.go
new file mode 100644
index 0000000..aa0d01a
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/go/internal/gccgoimporter/importer.go
@@ -0,0 +1,212 @@
+// Copyright 2013 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 gccgoimporter implements Import for gccgo-generated object files.
+package gccgoimporter // import "go/internal/gccgoimporter"
+
+import (
+	"bytes"
+	"debug/elf"
+	"fmt"
+	"go/types"
+	"io"
+	"os"
+	"os/exec"
+	"path/filepath"
+	"strings"
+)
+
+// A PackageInit describes an imported package that needs initialization.
+type PackageInit struct {
+	Name     string // short package name
+	InitFunc string // name of init function
+	Priority int    // priority of init function, see InitData.Priority
+}
+
+// The gccgo-specific init data for a package.
+type InitData struct {
+	// Initialization priority of this package relative to other packages.
+	// This is based on the maximum depth of the package's dependency graph;
+	// it is guaranteed to be greater than that of its dependencies.
+	Priority int
+
+	// The list of packages which this package depends on to be initialized,
+	// including itself if needed. This is the subset of the transitive closure of
+	// the package's dependencies that need initialization.
+	Inits []PackageInit
+}
+
+// Locate the file from which to read export data.
+// This is intended to replicate the logic in gofrontend.
+func findExportFile(searchpaths []string, pkgpath string) (string, error) {
+	for _, spath := range searchpaths {
+		pkgfullpath := filepath.Join(spath, pkgpath)
+		pkgdir, name := filepath.Split(pkgfullpath)
+
+		for _, filepath := range [...]string{
+			pkgfullpath,
+			pkgfullpath + ".gox",
+			pkgdir + "lib" + name + ".so",
+			pkgdir + "lib" + name + ".a",
+			pkgfullpath + ".o",
+		} {
+			fi, err := os.Stat(filepath)
+			if err == nil && !fi.IsDir() {
+				return filepath, nil
+			}
+		}
+	}
+
+	return "", fmt.Errorf("%s: could not find export data (tried %s)", pkgpath, strings.Join(searchpaths, ":"))
+}
+
+const (
+	gccgov1Magic    = "v1;\n"
+	goimporterMagic = "\n$$ "
+	archiveMagic    = "!<ar"
+)
+
+// Opens the export data file at the given path. If this is an ELF file,
+// searches for and opens the .go_export section. If this is an archive,
+// reads the export data from the first member, which is assumed to be an ELF file.
+// This is intended to replicate the logic in gofrontend.
+func openExportFile(fpath string) (reader io.ReadSeeker, closer io.Closer, err error) {
+	f, err := os.Open(fpath)
+	if err != nil {
+		return
+	}
+	closer = f
+	defer func() {
+		if err != nil && closer != nil {
+			f.Close()
+		}
+	}()
+
+	var magic [4]byte
+	_, err = f.ReadAt(magic[:], 0)
+	if err != nil {
+		return
+	}
+	// reset to offset 0 - needed on Plan 9 (see issue #11265)
+	// TODO: remove once issue #11265 has been resolved.
+	_, err = f.Seek(0, 0)
+	if err != nil {
+		return
+	}
+
+	var elfreader io.ReaderAt
+	switch string(magic[:]) {
+	case gccgov1Magic, goimporterMagic:
+		// Raw export data.
+		reader = f
+		return
+
+	case archiveMagic:
+		// TODO(pcc): Read the archive directly instead of using "ar".
+		f.Close()
+		closer = nil
+
+		cmd := exec.Command("ar", "p", fpath)
+		var out []byte
+		out, err = cmd.Output()
+		if err != nil {
+			return
+		}
+
+		elfreader = bytes.NewReader(out)
+
+	default:
+		elfreader = f
+	}
+
+	ef, err := elf.NewFile(elfreader)
+	if err != nil {
+		return
+	}
+
+	sec := ef.Section(".go_export")
+	if sec == nil {
+		err = fmt.Errorf("%s: .go_export section not found", fpath)
+		return
+	}
+
+	reader = sec.Open()
+	return
+}
+
+// An Importer resolves import paths to Packages. The imports map records
+// packages already known, indexed by package path.
+// An importer must determine the canonical package path and check imports
+// to see if it is already present in the map. If so, the Importer can return
+// the map entry. Otherwise, the importer must load the package data for the
+// given path into a new *Package, record it in imports map, and return the
+// package.
+type Importer func(imports map[string]*types.Package, path string) (*types.Package, error)
+
+func GetImporter(searchpaths []string, initmap map[*types.Package]InitData) Importer {
+	return func(imports map[string]*types.Package, pkgpath string) (pkg *types.Package, err error) {
+		if pkgpath == "unsafe" {
+			return types.Unsafe, nil
+		}
+
+		fpath, err := findExportFile(searchpaths, pkgpath)
+		if err != nil {
+			return
+		}
+
+		reader, closer, err := openExportFile(fpath)
+		if err != nil {
+			return
+		}
+		if closer != nil {
+			defer closer.Close()
+		}
+
+		var magic [4]byte
+		_, err = reader.Read(magic[:])
+		if err != nil {
+			return
+		}
+		_, err = reader.Seek(0, 0)
+		if err != nil {
+			return
+		}
+
+		switch string(magic[:]) {
+		case gccgov1Magic:
+			var p parser
+			p.init(fpath, reader, imports)
+			pkg = p.parsePackage()
+			if initmap != nil {
+				initmap[pkg] = p.initdata
+			}
+
+		// Excluded for now: Standard gccgo doesn't support this import format currently.
+		// case goimporterMagic:
+		// 	var data []byte
+		// 	data, err = ioutil.ReadAll(reader)
+		// 	if err != nil {
+		// 		return
+		// 	}
+		// 	var n int
+		// 	n, pkg, err = importer.ImportData(imports, data)
+		// 	if err != nil {
+		// 		return
+		// 	}
+
+		// 	if initmap != nil {
+		// 		suffixreader := bytes.NewReader(data[n:])
+		// 		var p parser
+		// 		p.init(fpath, suffixreader, nil)
+		// 		p.parseInitData()
+		// 		initmap[pkg] = p.initdata
+		// 	}
+
+		default:
+			err = fmt.Errorf("unrecognized magic string: %q", string(magic[:]))
+		}
+
+		return
+	}
+}
diff --git a/third_party/gofrontend/libgo/go/go/internal/gccgoimporter/importer_test.go b/third_party/gofrontend/libgo/go/go/internal/gccgoimporter/importer_test.go
new file mode 100644
index 0000000..f3bcadb
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/go/internal/gccgoimporter/importer_test.go
@@ -0,0 +1,171 @@
+// Copyright 2013 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 gccgoimporter
+
+import (
+	"go/types"
+	"internal/testenv"
+	"io/ioutil"
+	"os"
+	"os/exec"
+	"path/filepath"
+	"runtime"
+	"testing"
+)
+
+type importerTest struct {
+	pkgpath, name, want, wantval string
+	wantinits                    []string
+}
+
+func runImporterTest(t *testing.T, imp Importer, initmap map[*types.Package]InitData, test *importerTest) {
+	pkg, err := imp(make(map[string]*types.Package), test.pkgpath)
+	if err != nil {
+		t.Error(err)
+		return
+	}
+
+	if test.name != "" {
+		obj := pkg.Scope().Lookup(test.name)
+		if obj == nil {
+			t.Errorf("%s: object not found", test.name)
+			return
+		}
+
+		got := types.ObjectString(obj, types.RelativeTo(pkg))
+		if got != test.want {
+			t.Errorf("%s: got %q; want %q", test.name, got, test.want)
+		}
+
+		if test.wantval != "" {
+			gotval := obj.(*types.Const).Val().String()
+			if gotval != test.wantval {
+				t.Errorf("%s: got val %q; want val %q", test.name, gotval, test.wantval)
+			}
+		}
+	}
+
+	if len(test.wantinits) > 0 {
+		initdata := initmap[pkg]
+		found := false
+		// Check that the package's own init function has the package's priority
+		for _, pkginit := range initdata.Inits {
+			if pkginit.InitFunc == test.wantinits[0] {
+				if initdata.Priority != pkginit.Priority {
+					t.Errorf("%s: got self priority %d; want %d", test.pkgpath, pkginit.Priority, initdata.Priority)
+				}
+				found = true
+				break
+			}
+		}
+
+		if !found {
+			t.Errorf("%s: could not find expected function %q", test.pkgpath, test.wantinits[0])
+		}
+
+		// Each init function in the list other than the first one is a
+		// dependency of the function immediately before it. Check that
+		// the init functions appear in descending priority order.
+		priority := initdata.Priority
+		for _, wantdepinit := range test.wantinits[1:] {
+			found = false
+			for _, pkginit := range initdata.Inits {
+				if pkginit.InitFunc == wantdepinit {
+					if priority <= pkginit.Priority {
+						t.Errorf("%s: got dep priority %d; want less than %d", test.pkgpath, pkginit.Priority, priority)
+					}
+					found = true
+					priority = pkginit.Priority
+					break
+				}
+			}
+
+			if !found {
+				t.Errorf("%s: could not find expected function %q", test.pkgpath, wantdepinit)
+			}
+		}
+	}
+}
+
+var importerTests = [...]importerTest{
+	{pkgpath: "pointer", name: "Int8Ptr", want: "type Int8Ptr *int8"},
+	{pkgpath: "complexnums", name: "NN", want: "const NN untyped complex", wantval: "(-1/1 + -1/1i)"},
+	{pkgpath: "complexnums", name: "NP", want: "const NP untyped complex", wantval: "(-1/1 + 1/1i)"},
+	{pkgpath: "complexnums", name: "PN", want: "const PN untyped complex", wantval: "(1/1 + -1/1i)"},
+	{pkgpath: "complexnums", name: "PP", want: "const PP untyped complex", wantval: "(1/1 + 1/1i)"},
+	// TODO: enable this entry once bug has been tracked down
+	//{pkgpath: "imports", wantinits: []string{"imports..import", "fmt..import", "math..import"}},
+}
+
+func TestGoxImporter(t *testing.T) {
+	testenv.MustHaveGoBuild(t)
+
+	initmap := make(map[*types.Package]InitData)
+	imp := GetImporter([]string{"testdata"}, initmap)
+
+	for _, test := range importerTests {
+		runImporterTest(t, imp, initmap, &test)
+	}
+}
+
+func TestObjImporter(t *testing.T) {
+	testenv.MustHaveGoBuild(t)
+
+	// This test relies on gccgo being around, which it most likely will be if we
+	// were compiled with gccgo.
+	if runtime.Compiler != "gccgo" {
+		t.Skip("This test needs gccgo")
+		return
+	}
+
+	tmpdir, err := ioutil.TempDir("", "")
+	if err != nil {
+		t.Fatal(err)
+	}
+	initmap := make(map[*types.Package]InitData)
+	imp := GetImporter([]string{tmpdir}, initmap)
+
+	artmpdir, err := ioutil.TempDir("", "")
+	if err != nil {
+		t.Fatal(err)
+	}
+	arinitmap := make(map[*types.Package]InitData)
+	arimp := GetImporter([]string{artmpdir}, arinitmap)
+
+	for _, test := range importerTests {
+		gofile := filepath.Join("testdata", test.pkgpath+".go")
+		ofile := filepath.Join(tmpdir, test.pkgpath+".o")
+		afile := filepath.Join(artmpdir, "lib"+test.pkgpath+".a")
+
+		cmd := exec.Command("gccgo", "-fgo-pkgpath="+test.pkgpath, "-c", "-o", ofile, gofile)
+		out, err := cmd.CombinedOutput()
+		if err != nil {
+			t.Logf("%s", out)
+			t.Fatalf("gccgo %s failed: %s", gofile, err)
+		}
+
+		runImporterTest(t, imp, initmap, &test)
+
+		cmd = exec.Command("ar", "cr", afile, ofile)
+		out, err = cmd.CombinedOutput()
+		if err != nil {
+			t.Logf("%s", out)
+			t.Fatalf("ar cr %s %s failed: %s", afile, ofile, err)
+		}
+
+		runImporterTest(t, arimp, arinitmap, &test)
+
+		if err = os.Remove(ofile); err != nil {
+			t.Fatal(err)
+		}
+		if err = os.Remove(afile); err != nil {
+			t.Fatal(err)
+		}
+	}
+
+	if err = os.Remove(tmpdir); err != nil {
+		t.Fatal(err)
+	}
+}
diff --git a/third_party/gofrontend/libgo/go/go/internal/gccgoimporter/parser.go b/third_party/gofrontend/libgo/go/go/internal/gccgoimporter/parser.go
new file mode 100644
index 0000000..c06cce4
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/go/internal/gccgoimporter/parser.go
@@ -0,0 +1,855 @@
+// Copyright 2013 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 gccgoimporter
+
+import (
+	"bytes"
+	"errors"
+	"fmt"
+	"go/constant"
+	"go/token"
+	"go/types"
+	"io"
+	"strconv"
+	"strings"
+	"text/scanner"
+)
+
+type parser struct {
+	scanner  scanner.Scanner
+	tok      rune                      // current token
+	lit      string                    // literal string; only valid for Ident, Int, String tokens
+	pkgpath  string                    // package path of imported package
+	pkgname  string                    // name of imported package
+	pkg      *types.Package            // reference to imported package
+	imports  map[string]*types.Package // package path -> package object
+	typeMap  map[int]types.Type        // type number -> type
+	initdata InitData                  // package init priority data
+}
+
+func (p *parser) init(filename string, src io.Reader, imports map[string]*types.Package) {
+	p.scanner.Init(src)
+	p.scanner.Error = func(_ *scanner.Scanner, msg string) { p.error(msg) }
+	p.scanner.Mode = scanner.ScanIdents | scanner.ScanInts | scanner.ScanFloats | scanner.ScanStrings | scanner.ScanComments | scanner.SkipComments
+	p.scanner.Whitespace = 1<<'\t' | 1<<'\n' | 1<<' '
+	p.scanner.Filename = filename // for good error messages
+	p.next()
+	p.imports = imports
+	p.typeMap = make(map[int]types.Type)
+}
+
+type importError struct {
+	pos scanner.Position
+	err error
+}
+
+func (e importError) Error() string {
+	return fmt.Sprintf("import error %s (byte offset = %d): %s", e.pos, e.pos.Offset, e.err)
+}
+
+func (p *parser) error(err interface{}) {
+	if s, ok := err.(string); ok {
+		err = errors.New(s)
+	}
+	// panic with a runtime.Error if err is not an error
+	panic(importError{p.scanner.Pos(), err.(error)})
+}
+
+func (p *parser) errorf(format string, args ...interface{}) {
+	p.error(fmt.Errorf(format, args...))
+}
+
+func (p *parser) expect(tok rune) string {
+	lit := p.lit
+	if p.tok != tok {
+		p.errorf("expected %s, got %s (%s)", scanner.TokenString(tok), scanner.TokenString(p.tok), lit)
+	}
+	p.next()
+	return lit
+}
+
+func (p *parser) expectKeyword(keyword string) {
+	lit := p.expect(scanner.Ident)
+	if lit != keyword {
+		p.errorf("expected keyword %s, got %q", keyword, lit)
+	}
+}
+
+func (p *parser) parseString() string {
+	str, err := strconv.Unquote(p.expect(scanner.String))
+	if err != nil {
+		p.error(err)
+	}
+	return str
+}
+
+// unquotedString     = { unquotedStringChar } .
+// unquotedStringChar = <neither a whitespace nor a ';' char> .
+func (p *parser) parseUnquotedString() string {
+	if p.tok == scanner.EOF {
+		p.error("unexpected EOF")
+	}
+	var buf bytes.Buffer
+	buf.WriteString(p.scanner.TokenText())
+	// This loop needs to examine each character before deciding whether to consume it. If we see a semicolon,
+	// we need to let it be consumed by p.next().
+	for ch := p.scanner.Peek(); ch != ';' && ch != scanner.EOF && p.scanner.Whitespace&(1<<uint(ch)) == 0; ch = p.scanner.Peek() {
+		buf.WriteRune(ch)
+		p.scanner.Next()
+	}
+	p.next()
+	return buf.String()
+}
+
+func (p *parser) next() {
+	p.tok = p.scanner.Scan()
+	switch p.tok {
+	case scanner.Ident, scanner.Int, scanner.Float, scanner.String, '·':
+		p.lit = p.scanner.TokenText()
+	default:
+		p.lit = ""
+	}
+}
+
+func (p *parser) parseQualifiedName() (path, name string) {
+	return p.parseQualifiedNameStr(p.parseString())
+}
+
+func (p *parser) parseUnquotedQualifiedName() (path, name string) {
+	return p.parseQualifiedNameStr(p.parseUnquotedString())
+}
+
+// qualifiedName = [ ["."] unquotedString "." ] unquotedString .
+//
+// The above production uses greedy matching.
+func (p *parser) parseQualifiedNameStr(unquotedName string) (pkgpath, name string) {
+	parts := strings.Split(unquotedName, ".")
+	if parts[0] == "" {
+		parts = parts[1:]
+	}
+
+	switch len(parts) {
+	case 0:
+		p.errorf("malformed qualified name: %q", unquotedName)
+	case 1:
+		// unqualified name
+		pkgpath = p.pkgpath
+		name = parts[0]
+	default:
+		// qualified name, which may contain periods
+		pkgpath = strings.Join(parts[0:len(parts)-1], ".")
+		name = parts[len(parts)-1]
+	}
+
+	return
+}
+
+// getPkg returns the package for a given path. If the package is
+// not found but we have a package name, create the package and
+// add it to the p.imports map.
+//
+func (p *parser) getPkg(pkgpath, name string) *types.Package {
+	// package unsafe is not in the imports map - handle explicitly
+	if pkgpath == "unsafe" {
+		return types.Unsafe
+	}
+	pkg := p.imports[pkgpath]
+	if pkg == nil && name != "" {
+		pkg = types.NewPackage(pkgpath, name)
+		p.imports[pkgpath] = pkg
+	}
+	return pkg
+}
+
+// parseExportedName is like parseQualifiedName, but
+// the package path is resolved to an imported *types.Package.
+//
+// ExportedName = string [string] .
+func (p *parser) parseExportedName() (pkg *types.Package, name string) {
+	path, name := p.parseQualifiedName()
+	var pkgname string
+	if p.tok == scanner.String {
+		pkgname = p.parseString()
+	}
+	pkg = p.getPkg(path, pkgname)
+	if pkg == nil {
+		p.errorf("package %s (path = %q) not found", name, path)
+	}
+	return
+}
+
+// Name = QualifiedName | "?" .
+func (p *parser) parseName() string {
+	if p.tok == '?' {
+		// Anonymous.
+		p.next()
+		return ""
+	}
+	// The package path is redundant for us. Don't try to parse it.
+	_, name := p.parseUnquotedQualifiedName()
+	return name
+}
+
+func deref(typ types.Type) types.Type {
+	if p, _ := typ.(*types.Pointer); p != nil {
+		typ = p.Elem()
+	}
+	return typ
+}
+
+// Field = Name Type [string] .
+func (p *parser) parseField(pkg *types.Package) (field *types.Var, tag string) {
+	name := p.parseName()
+	typ := p.parseType(pkg)
+	anon := false
+	if name == "" {
+		anon = true
+		switch typ := deref(typ).(type) {
+		case *types.Basic:
+			name = typ.Name()
+		case *types.Named:
+			name = typ.Obj().Name()
+		default:
+			p.error("anonymous field expected")
+		}
+	}
+	field = types.NewField(token.NoPos, pkg, name, typ, anon)
+	if p.tok == scanner.String {
+		tag = p.parseString()
+	}
+	return
+}
+
+// Param = Name ["..."] Type .
+func (p *parser) parseParam(pkg *types.Package) (param *types.Var, isVariadic bool) {
+	name := p.parseName()
+	if p.tok == '.' {
+		p.next()
+		p.expect('.')
+		p.expect('.')
+		isVariadic = true
+	}
+	typ := p.parseType(pkg)
+	if isVariadic {
+		typ = types.NewSlice(typ)
+	}
+	param = types.NewParam(token.NoPos, pkg, name, typ)
+	return
+}
+
+// Var = Name Type .
+func (p *parser) parseVar(pkg *types.Package) *types.Var {
+	name := p.parseName()
+	return types.NewVar(token.NoPos, pkg, name, p.parseType(pkg))
+}
+
+// ConstValue     = string | "false" | "true" | ["-"] (int ["'"] | FloatOrComplex) .
+// FloatOrComplex = float ["i" | ("+"|"-") float "i"] .
+func (p *parser) parseConstValue() (val constant.Value, typ types.Type) {
+	switch p.tok {
+	case scanner.String:
+		str := p.parseString()
+		val = constant.MakeString(str)
+		typ = types.Typ[types.UntypedString]
+		return
+
+	case scanner.Ident:
+		b := false
+		switch p.lit {
+		case "false":
+		case "true":
+			b = true
+
+		default:
+			p.errorf("expected const value, got %s (%q)", scanner.TokenString(p.tok), p.lit)
+		}
+
+		p.next()
+		val = constant.MakeBool(b)
+		typ = types.Typ[types.UntypedBool]
+		return
+	}
+
+	sign := ""
+	if p.tok == '-' {
+		p.next()
+		sign = "-"
+	}
+
+	switch p.tok {
+	case scanner.Int:
+		val = constant.MakeFromLiteral(sign+p.lit, token.INT, 0)
+		if val == nil {
+			p.error("could not parse integer literal")
+		}
+
+		p.next()
+		if p.tok == '\'' {
+			p.next()
+			typ = types.Typ[types.UntypedRune]
+		} else {
+			typ = types.Typ[types.UntypedInt]
+		}
+
+	case scanner.Float:
+		re := sign + p.lit
+		p.next()
+
+		var im string
+		switch p.tok {
+		case '+':
+			p.next()
+			im = p.expect(scanner.Float)
+
+		case '-':
+			p.next()
+			im = "-" + p.expect(scanner.Float)
+
+		case scanner.Ident:
+			// re is in fact the imaginary component. Expect "i" below.
+			im = re
+			re = "0"
+
+		default:
+			val = constant.MakeFromLiteral(re, token.FLOAT, 0)
+			if val == nil {
+				p.error("could not parse float literal")
+			}
+			typ = types.Typ[types.UntypedFloat]
+			return
+		}
+
+		p.expectKeyword("i")
+		reval := constant.MakeFromLiteral(re, token.FLOAT, 0)
+		if reval == nil {
+			p.error("could not parse real component of complex literal")
+		}
+		imval := constant.MakeFromLiteral(im+"i", token.IMAG, 0)
+		if imval == nil {
+			p.error("could not parse imag component of complex literal")
+		}
+		val = constant.BinaryOp(reval, token.ADD, imval)
+		typ = types.Typ[types.UntypedComplex]
+
+	default:
+		p.errorf("expected const value, got %s (%q)", scanner.TokenString(p.tok), p.lit)
+	}
+
+	return
+}
+
+// Const = Name [Type] "=" ConstValue .
+func (p *parser) parseConst(pkg *types.Package) *types.Const {
+	name := p.parseName()
+	var typ types.Type
+	if p.tok == '<' {
+		typ = p.parseType(pkg)
+	}
+	p.expect('=')
+	val, vtyp := p.parseConstValue()
+	if typ == nil {
+		typ = vtyp
+	}
+	return types.NewConst(token.NoPos, pkg, name, typ, val)
+}
+
+// TypeName = ExportedName .
+func (p *parser) parseTypeName() *types.TypeName {
+	pkg, name := p.parseExportedName()
+	scope := pkg.Scope()
+	if obj := scope.Lookup(name); obj != nil {
+		return obj.(*types.TypeName)
+	}
+	obj := types.NewTypeName(token.NoPos, pkg, name, nil)
+	// a named type may be referred to before the underlying type
+	// is known - set it up
+	types.NewNamed(obj, nil, nil)
+	scope.Insert(obj)
+	return obj
+}
+
+// NamedType = TypeName Type { Method } .
+// Method    = "func" "(" Param ")" Name ParamList ResultList ";" .
+func (p *parser) parseNamedType(n int) types.Type {
+	obj := p.parseTypeName()
+
+	pkg := obj.Pkg()
+	typ := obj.Type()
+	p.typeMap[n] = typ
+
+	nt, ok := typ.(*types.Named)
+	if !ok {
+		// This can happen for unsafe.Pointer, which is a TypeName holding a Basic type.
+		pt := p.parseType(pkg)
+		if pt != typ {
+			p.error("unexpected underlying type for non-named TypeName")
+		}
+		return typ
+	}
+
+	underlying := p.parseType(pkg)
+	if nt.Underlying() == nil {
+		nt.SetUnderlying(underlying.Underlying())
+	}
+
+	for p.tok == scanner.Ident {
+		// collect associated methods
+		p.expectKeyword("func")
+		p.expect('(')
+		receiver, _ := p.parseParam(pkg)
+		p.expect(')')
+		name := p.parseName()
+		params, isVariadic := p.parseParamList(pkg)
+		results := p.parseResultList(pkg)
+		p.expect(';')
+
+		sig := types.NewSignature(receiver, params, results, isVariadic)
+		nt.AddMethod(types.NewFunc(token.NoPos, pkg, name, sig))
+	}
+
+	return nt
+}
+
+func (p *parser) parseInt() int64 {
+	lit := p.expect(scanner.Int)
+	n, err := strconv.ParseInt(lit, 10, 0)
+	if err != nil {
+		p.error(err)
+	}
+	return n
+}
+
+// ArrayOrSliceType = "[" [ int ] "]" Type .
+func (p *parser) parseArrayOrSliceType(pkg *types.Package) types.Type {
+	p.expect('[')
+	if p.tok == ']' {
+		p.next()
+		return types.NewSlice(p.parseType(pkg))
+	}
+
+	n := p.parseInt()
+	p.expect(']')
+	return types.NewArray(p.parseType(pkg), n)
+}
+
+// MapType = "map" "[" Type "]" Type .
+func (p *parser) parseMapType(pkg *types.Package) types.Type {
+	p.expectKeyword("map")
+	p.expect('[')
+	key := p.parseType(pkg)
+	p.expect(']')
+	elem := p.parseType(pkg)
+	return types.NewMap(key, elem)
+}
+
+// ChanType = "chan" ["<-" | "-<"] Type .
+func (p *parser) parseChanType(pkg *types.Package) types.Type {
+	p.expectKeyword("chan")
+	dir := types.SendRecv
+	switch p.tok {
+	case '-':
+		p.next()
+		p.expect('<')
+		dir = types.SendOnly
+
+	case '<':
+		// don't consume '<' if it belongs to Type
+		if p.scanner.Peek() == '-' {
+			p.next()
+			p.expect('-')
+			dir = types.RecvOnly
+		}
+	}
+
+	return types.NewChan(dir, p.parseType(pkg))
+}
+
+// StructType = "struct" "{" { Field } "}" .
+func (p *parser) parseStructType(pkg *types.Package) types.Type {
+	p.expectKeyword("struct")
+
+	var fields []*types.Var
+	var tags []string
+
+	p.expect('{')
+	for p.tok != '}' && p.tok != scanner.EOF {
+		field, tag := p.parseField(pkg)
+		p.expect(';')
+		fields = append(fields, field)
+		tags = append(tags, tag)
+	}
+	p.expect('}')
+
+	return types.NewStruct(fields, tags)
+}
+
+// ParamList = "(" [ { Parameter "," } Parameter ] ")" .
+func (p *parser) parseParamList(pkg *types.Package) (*types.Tuple, bool) {
+	var list []*types.Var
+	isVariadic := false
+
+	p.expect('(')
+	for p.tok != ')' && p.tok != scanner.EOF {
+		if len(list) > 0 {
+			p.expect(',')
+		}
+		par, variadic := p.parseParam(pkg)
+		list = append(list, par)
+		if variadic {
+			if isVariadic {
+				p.error("... not on final argument")
+			}
+			isVariadic = true
+		}
+	}
+	p.expect(')')
+
+	return types.NewTuple(list...), isVariadic
+}
+
+// ResultList = Type | ParamList .
+func (p *parser) parseResultList(pkg *types.Package) *types.Tuple {
+	switch p.tok {
+	case '<':
+		return types.NewTuple(types.NewParam(token.NoPos, pkg, "", p.parseType(pkg)))
+
+	case '(':
+		params, _ := p.parseParamList(pkg)
+		return params
+
+	default:
+		return nil
+	}
+}
+
+// FunctionType = ParamList ResultList .
+func (p *parser) parseFunctionType(pkg *types.Package) *types.Signature {
+	params, isVariadic := p.parseParamList(pkg)
+	results := p.parseResultList(pkg)
+	return types.NewSignature(nil, params, results, isVariadic)
+}
+
+// Func = Name FunctionType .
+func (p *parser) parseFunc(pkg *types.Package) *types.Func {
+	name := p.parseName()
+	if strings.ContainsRune(name, '$') {
+		// This is a Type$equal or Type$hash function, which we don't want to parse,
+		// except for the types.
+		p.discardDirectiveWhileParsingTypes(pkg)
+		return nil
+	}
+	return types.NewFunc(token.NoPos, pkg, name, p.parseFunctionType(pkg))
+}
+
+// InterfaceType = "interface" "{" { ("?" Type | Func) ";" } "}" .
+func (p *parser) parseInterfaceType(pkg *types.Package) types.Type {
+	p.expectKeyword("interface")
+
+	var methods []*types.Func
+	var typs []*types.Named
+
+	p.expect('{')
+	for p.tok != '}' && p.tok != scanner.EOF {
+		if p.tok == '?' {
+			p.next()
+			typs = append(typs, p.parseType(pkg).(*types.Named))
+		} else {
+			method := p.parseFunc(pkg)
+			methods = append(methods, method)
+		}
+		p.expect(';')
+	}
+	p.expect('}')
+
+	return types.NewInterface(methods, typs)
+}
+
+// PointerType = "*" ("any" | Type) .
+func (p *parser) parsePointerType(pkg *types.Package) types.Type {
+	p.expect('*')
+	if p.tok == scanner.Ident {
+		p.expectKeyword("any")
+		return types.Typ[types.UnsafePointer]
+	}
+	return types.NewPointer(p.parseType(pkg))
+}
+
+// TypeDefinition = NamedType | MapType | ChanType | StructType | InterfaceType | PointerType | ArrayOrSliceType | FunctionType .
+func (p *parser) parseTypeDefinition(pkg *types.Package, n int) types.Type {
+	var t types.Type
+	switch p.tok {
+	case scanner.String:
+		t = p.parseNamedType(n)
+
+	case scanner.Ident:
+		switch p.lit {
+		case "map":
+			t = p.parseMapType(pkg)
+
+		case "chan":
+			t = p.parseChanType(pkg)
+
+		case "struct":
+			t = p.parseStructType(pkg)
+
+		case "interface":
+			t = p.parseInterfaceType(pkg)
+		}
+
+	case '*':
+		t = p.parsePointerType(pkg)
+
+	case '[':
+		t = p.parseArrayOrSliceType(pkg)
+
+	case '(':
+		t = p.parseFunctionType(pkg)
+	}
+
+	p.typeMap[n] = t
+	return t
+}
+
+const (
+	// From gofrontend/go/export.h
+	// Note that these values are negative in the gofrontend and have been made positive
+	// in the gccgoimporter.
+	gccgoBuiltinINT8       = 1
+	gccgoBuiltinINT16      = 2
+	gccgoBuiltinINT32      = 3
+	gccgoBuiltinINT64      = 4
+	gccgoBuiltinUINT8      = 5
+	gccgoBuiltinUINT16     = 6
+	gccgoBuiltinUINT32     = 7
+	gccgoBuiltinUINT64     = 8
+	gccgoBuiltinFLOAT32    = 9
+	gccgoBuiltinFLOAT64    = 10
+	gccgoBuiltinINT        = 11
+	gccgoBuiltinUINT       = 12
+	gccgoBuiltinUINTPTR    = 13
+	gccgoBuiltinBOOL       = 15
+	gccgoBuiltinSTRING     = 16
+	gccgoBuiltinCOMPLEX64  = 17
+	gccgoBuiltinCOMPLEX128 = 18
+	gccgoBuiltinERROR      = 19
+	gccgoBuiltinBYTE       = 20
+	gccgoBuiltinRUNE       = 21
+)
+
+func lookupBuiltinType(typ int) types.Type {
+	return [...]types.Type{
+		gccgoBuiltinINT8:       types.Typ[types.Int8],
+		gccgoBuiltinINT16:      types.Typ[types.Int16],
+		gccgoBuiltinINT32:      types.Typ[types.Int32],
+		gccgoBuiltinINT64:      types.Typ[types.Int64],
+		gccgoBuiltinUINT8:      types.Typ[types.Uint8],
+		gccgoBuiltinUINT16:     types.Typ[types.Uint16],
+		gccgoBuiltinUINT32:     types.Typ[types.Uint32],
+		gccgoBuiltinUINT64:     types.Typ[types.Uint64],
+		gccgoBuiltinFLOAT32:    types.Typ[types.Float32],
+		gccgoBuiltinFLOAT64:    types.Typ[types.Float64],
+		gccgoBuiltinINT:        types.Typ[types.Int],
+		gccgoBuiltinUINT:       types.Typ[types.Uint],
+		gccgoBuiltinUINTPTR:    types.Typ[types.Uintptr],
+		gccgoBuiltinBOOL:       types.Typ[types.Bool],
+		gccgoBuiltinSTRING:     types.Typ[types.String],
+		gccgoBuiltinCOMPLEX64:  types.Typ[types.Complex64],
+		gccgoBuiltinCOMPLEX128: types.Typ[types.Complex128],
+		gccgoBuiltinERROR:      types.Universe.Lookup("error").Type(),
+		gccgoBuiltinBYTE:       types.Universe.Lookup("byte").Type(),
+		gccgoBuiltinRUNE:       types.Universe.Lookup("rune").Type(),
+	}[typ]
+}
+
+// Type = "<" "type" ( "-" int | int [ TypeDefinition ] ) ">" .
+func (p *parser) parseType(pkg *types.Package) (t types.Type) {
+	p.expect('<')
+	p.expectKeyword("type")
+
+	switch p.tok {
+	case scanner.Int:
+		n := p.parseInt()
+
+		if p.tok == '>' {
+			t = p.typeMap[int(n)]
+		} else {
+			t = p.parseTypeDefinition(pkg, int(n))
+		}
+
+	case '-':
+		p.next()
+		n := p.parseInt()
+		t = lookupBuiltinType(int(n))
+
+	default:
+		p.errorf("expected type number, got %s (%q)", scanner.TokenString(p.tok), p.lit)
+		return nil
+	}
+
+	p.expect('>')
+	return
+}
+
+// PackageInit = unquotedString unquotedString int .
+func (p *parser) parsePackageInit() PackageInit {
+	name := p.parseUnquotedString()
+	initfunc := p.parseUnquotedString()
+	priority := int(p.parseInt())
+	return PackageInit{Name: name, InitFunc: initfunc, Priority: priority}
+}
+
+// Throw away tokens until we see a ';'. If we see a '<', attempt to parse as a type.
+func (p *parser) discardDirectiveWhileParsingTypes(pkg *types.Package) {
+	for {
+		switch p.tok {
+		case ';':
+			return
+		case '<':
+			p.parseType(p.pkg)
+		case scanner.EOF:
+			p.error("unexpected EOF")
+		default:
+			p.next()
+		}
+	}
+}
+
+// Create the package if we have parsed both the package path and package name.
+func (p *parser) maybeCreatePackage() {
+	if p.pkgname != "" && p.pkgpath != "" {
+		p.pkg = p.getPkg(p.pkgpath, p.pkgname)
+	}
+}
+
+// InitDataDirective = "v1" ";" |
+//                     "priority" int ";" |
+//                     "init" { PackageInit } ";" |
+//                     "checksum" unquotedString ";" .
+func (p *parser) parseInitDataDirective() {
+	if p.tok != scanner.Ident {
+		// unexpected token kind; panic
+		p.expect(scanner.Ident)
+	}
+
+	switch p.lit {
+	case "v1":
+		p.next()
+		p.expect(';')
+
+	case "priority":
+		p.next()
+		p.initdata.Priority = int(p.parseInt())
+		p.expect(';')
+
+	case "init":
+		p.next()
+		for p.tok != ';' && p.tok != scanner.EOF {
+			p.initdata.Inits = append(p.initdata.Inits, p.parsePackageInit())
+		}
+		p.expect(';')
+
+	case "checksum":
+		// Don't let the scanner try to parse the checksum as a number.
+		defer func(mode uint) {
+			p.scanner.Mode = mode
+		}(p.scanner.Mode)
+		p.scanner.Mode &^= scanner.ScanInts | scanner.ScanFloats
+		p.next()
+		p.parseUnquotedString()
+		p.expect(';')
+
+	default:
+		p.errorf("unexpected identifier: %q", p.lit)
+	}
+}
+
+// Directive = InitDataDirective |
+//             "package" unquotedString ";" |
+//             "pkgpath" unquotedString ";" |
+//             "import" unquotedString unquotedString string ";" |
+//             "func" Func ";" |
+//             "type" Type ";" |
+//             "var" Var ";" |
+//             "const" Const ";" .
+func (p *parser) parseDirective() {
+	if p.tok != scanner.Ident {
+		// unexpected token kind; panic
+		p.expect(scanner.Ident)
+	}
+
+	switch p.lit {
+	case "v1", "priority", "init", "checksum":
+		p.parseInitDataDirective()
+
+	case "package":
+		p.next()
+		p.pkgname = p.parseUnquotedString()
+		p.maybeCreatePackage()
+		p.expect(';')
+
+	case "pkgpath":
+		p.next()
+		p.pkgpath = p.parseUnquotedString()
+		p.maybeCreatePackage()
+		p.expect(';')
+
+	case "import":
+		p.next()
+		pkgname := p.parseUnquotedString()
+		pkgpath := p.parseUnquotedString()
+		p.getPkg(pkgpath, pkgname)
+		p.parseString()
+		p.expect(';')
+
+	case "func":
+		p.next()
+		fun := p.parseFunc(p.pkg)
+		if fun != nil {
+			p.pkg.Scope().Insert(fun)
+		}
+		p.expect(';')
+
+	case "type":
+		p.next()
+		p.parseType(p.pkg)
+		p.expect(';')
+
+	case "var":
+		p.next()
+		v := p.parseVar(p.pkg)
+		p.pkg.Scope().Insert(v)
+		p.expect(';')
+
+	case "const":
+		p.next()
+		c := p.parseConst(p.pkg)
+		p.pkg.Scope().Insert(c)
+		p.expect(';')
+
+	default:
+		p.errorf("unexpected identifier: %q", p.lit)
+	}
+}
+
+// Package = { Directive } .
+func (p *parser) parsePackage() *types.Package {
+	for p.tok != scanner.EOF {
+		p.parseDirective()
+	}
+	for _, typ := range p.typeMap {
+		if it, ok := typ.(*types.Interface); ok {
+			it.Complete()
+		}
+	}
+	p.pkg.MarkComplete()
+	return p.pkg
+}
+
+// InitData = { InitDataDirective } .
+func (p *parser) parseInitData() {
+	for p.tok != scanner.EOF {
+		p.parseInitDataDirective()
+	}
+}
diff --git a/third_party/gofrontend/libgo/go/go/internal/gccgoimporter/parser_test.go b/third_party/gofrontend/libgo/go/go/internal/gccgoimporter/parser_test.go
new file mode 100644
index 0000000..b96486f
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/go/internal/gccgoimporter/parser_test.go
@@ -0,0 +1,72 @@
+// Copyright 2013 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 gccgoimporter
+
+import (
+	"bytes"
+	"go/types"
+	"strings"
+	"testing"
+	"text/scanner"
+)
+
+var typeParserTests = []struct {
+	id, typ, want, underlying, methods string
+}{
+	{id: "foo", typ: "<type -1>", want: "int8"},
+	{id: "foo", typ: "<type 1 *<type -19>>", want: "*error"},
+	{id: "foo", typ: "<type 1 *any>", want: "unsafe.Pointer"},
+	{id: "foo", typ: "<type 1 \"Bar\" <type 2 *<type 1>>>", want: "foo.Bar", underlying: "*foo.Bar"},
+	{id: "foo", typ: "<type 1 \"bar.Foo\" \"bar\" <type -1> func (? <type 1>) M (); >", want: "bar.Foo", underlying: "int8", methods: "func (bar.Foo).M()"},
+	{id: "foo", typ: "<type 1 \".bar.foo\" \"bar\" <type -1>>", want: "bar.foo", underlying: "int8"},
+	{id: "foo", typ: "<type 1 []<type -1>>", want: "[]int8"},
+	{id: "foo", typ: "<type 1 [42]<type -1>>", want: "[42]int8"},
+	{id: "foo", typ: "<type 1 map [<type -1>] <type -2>>", want: "map[int8]int16"},
+	{id: "foo", typ: "<type 1 chan <type -1>>", want: "chan int8"},
+	{id: "foo", typ: "<type 1 chan <- <type -1>>", want: "<-chan int8"},
+	{id: "foo", typ: "<type 1 chan -< <type -1>>", want: "chan<- int8"},
+	{id: "foo", typ: "<type 1 struct { I8 <type -1>; I16 <type -2> \"i16\"; }>", want: "struct{I8 int8; I16 int16 \"i16\"}"},
+	{id: "foo", typ: "<type 1 interface { Foo (a <type -1>, b <type -2>) <type -1>; Bar (? <type -2>, ? ...<type -1>) (? <type -2>, ? <type -1>); Baz (); }>", want: "interface{Bar(int16, ...int8) (int16, int8); Baz(); Foo(a int8, b int16) int8}"},
+	{id: "foo", typ: "<type 1 (? <type -1>) <type -2>>", want: "func(int8) int16"},
+}
+
+func TestTypeParser(t *testing.T) {
+	for _, test := range typeParserTests {
+		var p parser
+		p.init("test.gox", strings.NewReader(test.typ), make(map[string]*types.Package))
+		p.pkgname = test.id
+		p.pkgpath = test.id
+		p.maybeCreatePackage()
+		typ := p.parseType(p.pkg)
+
+		if p.tok != scanner.EOF {
+			t.Errorf("expected full parse, stopped at %q", p.lit)
+		}
+
+		got := typ.String()
+		if got != test.want {
+			t.Errorf("got type %q, expected %q", got, test.want)
+		}
+
+		if test.underlying != "" {
+			underlying := typ.Underlying().String()
+			if underlying != test.underlying {
+				t.Errorf("got underlying type %q, expected %q", underlying, test.underlying)
+			}
+		}
+
+		if test.methods != "" {
+			nt := typ.(*types.Named)
+			var buf bytes.Buffer
+			for i := 0; i != nt.NumMethods(); i++ {
+				buf.WriteString(nt.Method(i).String())
+			}
+			methods := buf.String()
+			if methods != test.methods {
+				t.Errorf("got methods %q, expected %q", methods, test.methods)
+			}
+		}
+	}
+}
diff --git a/third_party/gofrontend/libgo/go/go/internal/gccgoimporter/testdata/complexnums.go b/third_party/gofrontend/libgo/go/go/internal/gccgoimporter/testdata/complexnums.go
new file mode 100644
index 0000000..a51b6b0
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/go/internal/gccgoimporter/testdata/complexnums.go
@@ -0,0 +1,6 @@
+package complexnums
+
+const NN = -1 - 1i
+const NP = -1 + 1i
+const PN = 1 - 1i
+const PP = 1 + 1i
diff --git a/third_party/gofrontend/libgo/go/go/internal/gccgoimporter/testdata/imports.go b/third_party/gofrontend/libgo/go/go/internal/gccgoimporter/testdata/imports.go
new file mode 100644
index 0000000..7907316
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/go/internal/gccgoimporter/testdata/imports.go
@@ -0,0 +1,5 @@
+package imports
+
+import "fmt"
+
+var Hello = fmt.Sprintf("Hello, world")
diff --git a/third_party/gofrontend/libgo/go/go/internal/gccgoimporter/testdata/pointer.go b/third_party/gofrontend/libgo/go/go/internal/gccgoimporter/testdata/pointer.go
new file mode 100644
index 0000000..4ebc671
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/go/internal/gccgoimporter/testdata/pointer.go
@@ -0,0 +1,3 @@
+package pointer
+
+type Int8Ptr *int8
diff --git a/third_party/gofrontend/libgo/go/go/internal/gcimporter/exportdata.go b/third_party/gofrontend/libgo/go/go/internal/gcimporter/exportdata.go
new file mode 100644
index 0000000..657742b
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/go/internal/gcimporter/exportdata.go
@@ -0,0 +1,108 @@
+// Copyright 2011 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.
+
+// This file implements FindExportData.
+
+package gcimporter
+
+import (
+	"bufio"
+	"errors"
+	"fmt"
+	"io"
+	"strconv"
+	"strings"
+)
+
+func readGopackHeader(r *bufio.Reader) (name string, size int, err error) {
+	// See $GOROOT/include/ar.h.
+	hdr := make([]byte, 16+12+6+6+8+10+2)
+	_, err = io.ReadFull(r, hdr)
+	if err != nil {
+		return
+	}
+	// leave for debugging
+	if false {
+		fmt.Printf("header: %s", hdr)
+	}
+	s := strings.TrimSpace(string(hdr[16+12+6+6+8:][:10]))
+	size, err = strconv.Atoi(s)
+	if err != nil || hdr[len(hdr)-2] != '`' || hdr[len(hdr)-1] != '\n' {
+		err = errors.New("invalid archive header")
+		return
+	}
+	name = strings.TrimSpace(string(hdr[:16]))
+	return
+}
+
+// FindExportData positions the reader r at the beginning of the
+// export data section of an underlying GC-created object/archive
+// file by reading from it. The reader must be positioned at the
+// start of the file before calling this function.
+//
+func FindExportData(r *bufio.Reader) (err error) {
+	// Read first line to make sure this is an object file.
+	line, err := r.ReadSlice('\n')
+	if err != nil {
+		return
+	}
+	if string(line) == "!<arch>\n" {
+		// Archive file. Scan to __.PKGDEF.
+		var name string
+		var size int
+		if name, size, err = readGopackHeader(r); err != nil {
+			return
+		}
+
+		// Optional leading __.GOSYMDEF or __.SYMDEF.
+		// Read and discard.
+		if name == "__.SYMDEF" || name == "__.GOSYMDEF" {
+			const block = 4096
+			tmp := make([]byte, block)
+			for size > 0 {
+				n := size
+				if n > block {
+					n = block
+				}
+				if _, err = io.ReadFull(r, tmp[:n]); err != nil {
+					return
+				}
+				size -= n
+			}
+
+			if name, size, err = readGopackHeader(r); err != nil {
+				return
+			}
+		}
+
+		// First real entry should be __.PKGDEF.
+		if name != "__.PKGDEF" {
+			err = errors.New("go archive is missing __.PKGDEF")
+			return
+		}
+
+		// Read first line of __.PKGDEF data, so that line
+		// is once again the first line of the input.
+		if line, err = r.ReadSlice('\n'); err != nil {
+			return
+		}
+	}
+
+	// Now at __.PKGDEF in archive or still at beginning of file.
+	// Either way, line should begin with "go object ".
+	if !strings.HasPrefix(string(line), "go object ") {
+		err = errors.New("not a go object file")
+		return
+	}
+
+	// Skip over object header to export data.
+	// Begins after first line with $$.
+	for line[0] != '$' {
+		if line, err = r.ReadSlice('\n'); err != nil {
+			return
+		}
+	}
+
+	return
+}
diff --git a/third_party/gofrontend/libgo/go/go/internal/gcimporter/gcimporter.go b/third_party/gofrontend/libgo/go/go/internal/gcimporter/gcimporter.go
new file mode 100644
index 0000000..1d485cf
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/go/internal/gcimporter/gcimporter.go
@@ -0,0 +1,991 @@
+// Copyright 2011 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 gcimporter implements Import for gc-generated object files.
+package gcimporter // import "go/internal/gcimporter"
+
+import (
+	"bufio"
+	"errors"
+	"fmt"
+	"go/build"
+	"go/token"
+	"io"
+	"os"
+	"path/filepath"
+	"sort"
+	"strconv"
+	"strings"
+	"text/scanner"
+
+	exact "go/constant"
+	"go/types"
+)
+
+// debugging/development support
+const debug = false
+
+var pkgExts = [...]string{".a", ".o"}
+
+// FindPkg returns the filename and unique package id for an import
+// path based on package information provided by build.Import (using
+// the build.Default build.Context).
+// If no file was found, an empty filename is returned.
+//
+func FindPkg(path, srcDir string) (filename, id string) {
+	if len(path) == 0 {
+		return
+	}
+
+	id = path
+	var noext string
+	switch {
+	default:
+		// "x" -> "$GOPATH/pkg/$GOOS_$GOARCH/x.ext", "x"
+		// Don't require the source files to be present.
+		bp, _ := build.Import(path, srcDir, build.FindOnly|build.AllowBinary)
+		if bp.PkgObj == "" {
+			return
+		}
+		noext = strings.TrimSuffix(bp.PkgObj, ".a")
+
+	case build.IsLocalImport(path):
+		// "./x" -> "/this/directory/x.ext", "/this/directory/x"
+		noext = filepath.Join(srcDir, path)
+		id = noext
+
+	case filepath.IsAbs(path):
+		// for completeness only - go/build.Import
+		// does not support absolute imports
+		// "/x" -> "/x.ext", "/x"
+		noext = path
+	}
+
+	// try extensions
+	for _, ext := range pkgExts {
+		filename = noext + ext
+		if f, err := os.Stat(filename); err == nil && !f.IsDir() {
+			return
+		}
+	}
+
+	filename = "" // not found
+	return
+}
+
+// ImportData imports a package by reading the gc-generated export data,
+// adds the corresponding package object to the packages map indexed by id,
+// and returns the object.
+//
+// The packages map must contains all packages already imported. The data
+// reader position must be the beginning of the export data section. The
+// filename is only used in error messages.
+//
+// If packages[id] contains the completely imported package, that package
+// can be used directly, and there is no need to call this function (but
+// there is also no harm but for extra time used).
+//
+func ImportData(packages map[string]*types.Package, filename, id string, data io.Reader) (pkg *types.Package, err error) {
+	// support for parser error handling
+	defer func() {
+		switch r := recover().(type) {
+		case nil:
+			// nothing to do
+		case importError:
+			err = r
+		default:
+			panic(r) // internal error
+		}
+	}()
+
+	var p parser
+	p.init(filename, id, data, packages)
+	pkg = p.parseExport()
+
+	return
+}
+
+// Import imports a gc-generated package given its import path, adds the
+// corresponding package object to the packages map, and returns the object.
+// Local import paths are interpreted relative to the current working directory.
+// The packages map must contain all packages already imported.
+//
+func Import(packages map[string]*types.Package, path string) (pkg *types.Package, err error) {
+	// package "unsafe" is handled by the type checker
+	if path == "unsafe" {
+		panic(`gcimporter.Import called for package "unsafe"`)
+	}
+
+	srcDir := "."
+	if build.IsLocalImport(path) {
+		srcDir, err = os.Getwd()
+		if err != nil {
+			return
+		}
+	}
+
+	filename, id := FindPkg(path, srcDir)
+	if filename == "" {
+		err = fmt.Errorf("can't find import: %s", id)
+		return
+	}
+
+	// no need to re-import if the package was imported completely before
+	if pkg = packages[id]; pkg != nil && pkg.Complete() {
+		return
+	}
+
+	// open file
+	f, err := os.Open(filename)
+	if err != nil {
+		return
+	}
+	defer func() {
+		f.Close()
+		if err != nil {
+			// add file name to error
+			err = fmt.Errorf("reading export data: %s: %v", filename, err)
+		}
+	}()
+
+	buf := bufio.NewReader(f)
+	if err = FindExportData(buf); err != nil {
+		return
+	}
+
+	pkg, err = ImportData(packages, filename, id, buf)
+
+	return
+}
+
+// ----------------------------------------------------------------------------
+// Parser
+
+// TODO(gri) Imported objects don't have position information.
+//           Ideally use the debug table line info; alternatively
+//           create some fake position (or the position of the
+//           import). That way error messages referring to imported
+//           objects can print meaningful information.
+
+// parser parses the exports inside a gc compiler-produced
+// object/archive file and populates its scope with the results.
+type parser struct {
+	scanner    scanner.Scanner
+	tok        rune                      // current token
+	lit        string                    // literal string; only valid for Ident, Int, String tokens
+	id         string                    // package id of imported package
+	sharedPkgs map[string]*types.Package // package id -> package object (across importer)
+	localPkgs  map[string]*types.Package // package id -> package object (just this package)
+}
+
+func (p *parser) init(filename, id string, src io.Reader, packages map[string]*types.Package) {
+	p.scanner.Init(src)
+	p.scanner.Error = func(_ *scanner.Scanner, msg string) { p.error(msg) }
+	p.scanner.Mode = scanner.ScanIdents | scanner.ScanInts | scanner.ScanChars | scanner.ScanStrings | scanner.ScanComments | scanner.SkipComments
+	p.scanner.Whitespace = 1<<'\t' | 1<<' '
+	p.scanner.Filename = filename // for good error messages
+	p.next()
+	p.id = id
+	p.sharedPkgs = packages
+	if debug {
+		// check consistency of packages map
+		for _, pkg := range packages {
+			if pkg.Name() == "" {
+				fmt.Printf("no package name for %s\n", pkg.Path())
+			}
+		}
+	}
+}
+
+func (p *parser) next() {
+	p.tok = p.scanner.Scan()
+	switch p.tok {
+	case scanner.Ident, scanner.Int, scanner.Char, scanner.String, '·':
+		p.lit = p.scanner.TokenText()
+	default:
+		p.lit = ""
+	}
+	if debug {
+		fmt.Printf("%s: %q -> %q\n", scanner.TokenString(p.tok), p.scanner.TokenText(), p.lit)
+	}
+}
+
+func declTypeName(pkg *types.Package, name string) *types.TypeName {
+	scope := pkg.Scope()
+	if obj := scope.Lookup(name); obj != nil {
+		return obj.(*types.TypeName)
+	}
+	obj := types.NewTypeName(token.NoPos, pkg, name, nil)
+	// a named type may be referred to before the underlying type
+	// is known - set it up
+	types.NewNamed(obj, nil, nil)
+	scope.Insert(obj)
+	return obj
+}
+
+// ----------------------------------------------------------------------------
+// Error handling
+
+// Internal errors are boxed as importErrors.
+type importError struct {
+	pos scanner.Position
+	err error
+}
+
+func (e importError) Error() string {
+	return fmt.Sprintf("import error %s (byte offset = %d): %s", e.pos, e.pos.Offset, e.err)
+}
+
+func (p *parser) error(err interface{}) {
+	if s, ok := err.(string); ok {
+		err = errors.New(s)
+	}
+	// panic with a runtime.Error if err is not an error
+	panic(importError{p.scanner.Pos(), err.(error)})
+}
+
+func (p *parser) errorf(format string, args ...interface{}) {
+	p.error(fmt.Sprintf(format, args...))
+}
+
+func (p *parser) expect(tok rune) string {
+	lit := p.lit
+	if p.tok != tok {
+		p.errorf("expected %s, got %s (%s)", scanner.TokenString(tok), scanner.TokenString(p.tok), lit)
+	}
+	p.next()
+	return lit
+}
+
+func (p *parser) expectSpecial(tok string) {
+	sep := 'x' // not white space
+	i := 0
+	for i < len(tok) && p.tok == rune(tok[i]) && sep > ' ' {
+		sep = p.scanner.Peek() // if sep <= ' ', there is white space before the next token
+		p.next()
+		i++
+	}
+	if i < len(tok) {
+		p.errorf("expected %q, got %q", tok, tok[0:i])
+	}
+}
+
+func (p *parser) expectKeyword(keyword string) {
+	lit := p.expect(scanner.Ident)
+	if lit != keyword {
+		p.errorf("expected keyword %s, got %q", keyword, lit)
+	}
+}
+
+// ----------------------------------------------------------------------------
+// Qualified and unqualified names
+
+// PackageId = string_lit .
+//
+func (p *parser) parsePackageId() string {
+	id, err := strconv.Unquote(p.expect(scanner.String))
+	if err != nil {
+		p.error(err)
+	}
+	// id == "" stands for the imported package id
+	// (only known at time of package installation)
+	if id == "" {
+		id = p.id
+	}
+	return id
+}
+
+// PackageName = ident .
+//
+func (p *parser) parsePackageName() string {
+	return p.expect(scanner.Ident)
+}
+
+// dotIdentifier = ( ident | '·' ) { ident | int | '·' } .
+func (p *parser) parseDotIdent() string {
+	ident := ""
+	if p.tok != scanner.Int {
+		sep := 'x' // not white space
+		for (p.tok == scanner.Ident || p.tok == scanner.Int || p.tok == '·') && sep > ' ' {
+			ident += p.lit
+			sep = p.scanner.Peek() // if sep <= ' ', there is white space before the next token
+			p.next()
+		}
+	}
+	if ident == "" {
+		p.expect(scanner.Ident) // use expect() for error handling
+	}
+	return ident
+}
+
+// QualifiedName = "@" PackageId "." ( "?" | dotIdentifier ) .
+//
+func (p *parser) parseQualifiedName() (id, name string) {
+	p.expect('@')
+	id = p.parsePackageId()
+	p.expect('.')
+	// Per rev f280b8a485fd (10/2/2013), qualified names may be used for anonymous fields.
+	if p.tok == '?' {
+		p.next()
+	} else {
+		name = p.parseDotIdent()
+	}
+	return
+}
+
+// getPkg returns the package for a given id. If the package is
+// not found but we have a package name, create the package and
+// add it to the p.localPkgs and p.sharedPkgs maps.
+//
+// id identifies a package, usually by a canonical package path like
+// "encoding/json" but possibly by a non-canonical import path like
+// "./json".
+//
+func (p *parser) getPkg(id, name string) *types.Package {
+	// package unsafe is not in the packages maps - handle explicitly
+	if id == "unsafe" {
+		return types.Unsafe
+	}
+
+	pkg := p.localPkgs[id]
+	if pkg == nil && name != "" {
+		// first import of id from this package
+		pkg = p.sharedPkgs[id]
+		if pkg == nil {
+			// first import of id by this importer
+			pkg = types.NewPackage(id, name)
+			p.sharedPkgs[id] = pkg
+		}
+
+		if p.localPkgs == nil {
+			p.localPkgs = make(map[string]*types.Package)
+		}
+		p.localPkgs[id] = pkg
+	}
+	return pkg
+}
+
+// parseExportedName is like parseQualifiedName, but
+// the package id is resolved to an imported *types.Package.
+//
+func (p *parser) parseExportedName() (pkg *types.Package, name string) {
+	id, name := p.parseQualifiedName()
+	pkg = p.getPkg(id, "")
+	if pkg == nil {
+		p.errorf("%s package not found", id)
+	}
+	return
+}
+
+// ----------------------------------------------------------------------------
+// Types
+
+// BasicType = identifier .
+//
+func (p *parser) parseBasicType() types.Type {
+	id := p.expect(scanner.Ident)
+	obj := types.Universe.Lookup(id)
+	if obj, ok := obj.(*types.TypeName); ok {
+		return obj.Type()
+	}
+	p.errorf("not a basic type: %s", id)
+	return nil
+}
+
+// ArrayType = "[" int_lit "]" Type .
+//
+func (p *parser) parseArrayType() types.Type {
+	// "[" already consumed and lookahead known not to be "]"
+	lit := p.expect(scanner.Int)
+	p.expect(']')
+	elem := p.parseType()
+	n, err := strconv.ParseInt(lit, 10, 64)
+	if err != nil {
+		p.error(err)
+	}
+	return types.NewArray(elem, n)
+}
+
+// MapType = "map" "[" Type "]" Type .
+//
+func (p *parser) parseMapType() types.Type {
+	p.expectKeyword("map")
+	p.expect('[')
+	key := p.parseType()
+	p.expect(']')
+	elem := p.parseType()
+	return types.NewMap(key, elem)
+}
+
+// Name = identifier | "?" | QualifiedName .
+//
+// If materializePkg is set, the returned package is guaranteed to be set.
+// For fully qualified names, the returned package may be a fake package
+// (without name, scope, and not in the p.sharedPkgs map), created for the
+// sole purpose of providing a package path. Fake packages are created
+// when the package id is not found in the p.sharedPkgs map; in that case
+// we cannot create a real package because we don't have a package name.
+// For non-qualified names, the returned package is the imported package.
+//
+func (p *parser) parseName(materializePkg bool) (pkg *types.Package, name string) {
+	switch p.tok {
+	case scanner.Ident:
+		pkg = p.sharedPkgs[p.id]
+		name = p.lit
+		p.next()
+	case '?':
+		// anonymous
+		pkg = p.sharedPkgs[p.id]
+		p.next()
+	case '@':
+		// exported name prefixed with package path
+		var id string
+		id, name = p.parseQualifiedName()
+		if materializePkg {
+			// we don't have a package name - if the package
+			// doesn't exist yet, create a fake package instead
+			pkg = p.getPkg(id, "")
+			if pkg == nil {
+				pkg = types.NewPackage(id, "")
+			}
+		}
+	default:
+		p.error("name expected")
+	}
+	return
+}
+
+func deref(typ types.Type) types.Type {
+	if p, _ := typ.(*types.Pointer); p != nil {
+		return p.Elem()
+	}
+	return typ
+}
+
+// Field = Name Type [ string_lit ] .
+//
+func (p *parser) parseField() (*types.Var, string) {
+	pkg, name := p.parseName(true)
+	typ := p.parseType()
+	anonymous := false
+	if name == "" {
+		// anonymous field - typ must be T or *T and T must be a type name
+		switch typ := deref(typ).(type) {
+		case *types.Basic: // basic types are named types
+			pkg = nil
+			name = typ.Name()
+		case *types.Named:
+			name = typ.Obj().Name()
+		default:
+			p.errorf("anonymous field expected")
+		}
+		anonymous = true
+	}
+	tag := ""
+	if p.tok == scanner.String {
+		s := p.expect(scanner.String)
+		var err error
+		tag, err = strconv.Unquote(s)
+		if err != nil {
+			p.errorf("invalid struct tag %s: %s", s, err)
+		}
+	}
+	return types.NewField(token.NoPos, pkg, name, typ, anonymous), tag
+}
+
+// StructType = "struct" "{" [ FieldList ] "}" .
+// FieldList  = Field { ";" Field } .
+//
+func (p *parser) parseStructType() types.Type {
+	var fields []*types.Var
+	var tags []string
+
+	p.expectKeyword("struct")
+	p.expect('{')
+	for i := 0; p.tok != '}' && p.tok != scanner.EOF; i++ {
+		if i > 0 {
+			p.expect(';')
+		}
+		fld, tag := p.parseField()
+		if tag != "" && tags == nil {
+			tags = make([]string, i)
+		}
+		if tags != nil {
+			tags = append(tags, tag)
+		}
+		fields = append(fields, fld)
+	}
+	p.expect('}')
+
+	return types.NewStruct(fields, tags)
+}
+
+// Parameter = ( identifier | "?" ) [ "..." ] Type [ string_lit ] .
+//
+func (p *parser) parseParameter() (par *types.Var, isVariadic bool) {
+	_, name := p.parseName(false)
+	// remove gc-specific parameter numbering
+	if i := strings.Index(name, "·"); i >= 0 {
+		name = name[:i]
+	}
+	if p.tok == '.' {
+		p.expectSpecial("...")
+		isVariadic = true
+	}
+	typ := p.parseType()
+	if isVariadic {
+		typ = types.NewSlice(typ)
+	}
+	// ignore argument tag (e.g. "noescape")
+	if p.tok == scanner.String {
+		p.next()
+	}
+	// TODO(gri) should we provide a package?
+	par = types.NewVar(token.NoPos, nil, name, typ)
+	return
+}
+
+// Parameters    = "(" [ ParameterList ] ")" .
+// ParameterList = { Parameter "," } Parameter .
+//
+func (p *parser) parseParameters() (list []*types.Var, isVariadic bool) {
+	p.expect('(')
+	for p.tok != ')' && p.tok != scanner.EOF {
+		if len(list) > 0 {
+			p.expect(',')
+		}
+		par, variadic := p.parseParameter()
+		list = append(list, par)
+		if variadic {
+			if isVariadic {
+				p.error("... not on final argument")
+			}
+			isVariadic = true
+		}
+	}
+	p.expect(')')
+
+	return
+}
+
+// Signature = Parameters [ Result ] .
+// Result    = Type | Parameters .
+//
+func (p *parser) parseSignature(recv *types.Var) *types.Signature {
+	params, isVariadic := p.parseParameters()
+
+	// optional result type
+	var results []*types.Var
+	if p.tok == '(' {
+		var variadic bool
+		results, variadic = p.parseParameters()
+		if variadic {
+			p.error("... not permitted on result type")
+		}
+	}
+
+	return types.NewSignature(recv, types.NewTuple(params...), types.NewTuple(results...), isVariadic)
+}
+
+// InterfaceType = "interface" "{" [ MethodList ] "}" .
+// MethodList    = Method { ";" Method } .
+// Method        = Name Signature .
+//
+// The methods of embedded interfaces are always "inlined"
+// by the compiler and thus embedded interfaces are never
+// visible in the export data.
+//
+func (p *parser) parseInterfaceType() types.Type {
+	var methods []*types.Func
+
+	p.expectKeyword("interface")
+	p.expect('{')
+	for i := 0; p.tok != '}' && p.tok != scanner.EOF; i++ {
+		if i > 0 {
+			p.expect(';')
+		}
+		pkg, name := p.parseName(true)
+		sig := p.parseSignature(nil)
+		methods = append(methods, types.NewFunc(token.NoPos, pkg, name, sig))
+	}
+	p.expect('}')
+
+	// Complete requires the type's embedded interfaces to be fully defined,
+	// but we do not define any
+	return types.NewInterface(methods, nil).Complete()
+}
+
+// ChanType = ( "chan" [ "<-" ] | "<-" "chan" ) Type .
+//
+func (p *parser) parseChanType() types.Type {
+	dir := types.SendRecv
+	if p.tok == scanner.Ident {
+		p.expectKeyword("chan")
+		if p.tok == '<' {
+			p.expectSpecial("<-")
+			dir = types.SendOnly
+		}
+	} else {
+		p.expectSpecial("<-")
+		p.expectKeyword("chan")
+		dir = types.RecvOnly
+	}
+	elem := p.parseType()
+	return types.NewChan(dir, elem)
+}
+
+// Type =
+//	BasicType | TypeName | ArrayType | SliceType | StructType |
+//      PointerType | FuncType | InterfaceType | MapType | ChanType |
+//      "(" Type ")" .
+//
+// BasicType   = ident .
+// TypeName    = ExportedName .
+// SliceType   = "[" "]" Type .
+// PointerType = "*" Type .
+// FuncType    = "func" Signature .
+//
+func (p *parser) parseType() types.Type {
+	switch p.tok {
+	case scanner.Ident:
+		switch p.lit {
+		default:
+			return p.parseBasicType()
+		case "struct":
+			return p.parseStructType()
+		case "func":
+			// FuncType
+			p.next()
+			return p.parseSignature(nil)
+		case "interface":
+			return p.parseInterfaceType()
+		case "map":
+			return p.parseMapType()
+		case "chan":
+			return p.parseChanType()
+		}
+	case '@':
+		// TypeName
+		pkg, name := p.parseExportedName()
+		return declTypeName(pkg, name).Type()
+	case '[':
+		p.next() // look ahead
+		if p.tok == ']' {
+			// SliceType
+			p.next()
+			return types.NewSlice(p.parseType())
+		}
+		return p.parseArrayType()
+	case '*':
+		// PointerType
+		p.next()
+		return types.NewPointer(p.parseType())
+	case '<':
+		return p.parseChanType()
+	case '(':
+		// "(" Type ")"
+		p.next()
+		typ := p.parseType()
+		p.expect(')')
+		return typ
+	}
+	p.errorf("expected type, got %s (%q)", scanner.TokenString(p.tok), p.lit)
+	return nil
+}
+
+// ----------------------------------------------------------------------------
+// Declarations
+
+// ImportDecl = "import" PackageName PackageId .
+//
+func (p *parser) parseImportDecl() {
+	p.expectKeyword("import")
+	name := p.parsePackageName()
+	p.getPkg(p.parsePackageId(), name)
+}
+
+// int_lit = [ "+" | "-" ] { "0" ... "9" } .
+//
+func (p *parser) parseInt() string {
+	s := ""
+	switch p.tok {
+	case '-':
+		s = "-"
+		p.next()
+	case '+':
+		p.next()
+	}
+	return s + p.expect(scanner.Int)
+}
+
+// number = int_lit [ "p" int_lit ] .
+//
+func (p *parser) parseNumber() (typ *types.Basic, val exact.Value) {
+	// mantissa
+	mant := exact.MakeFromLiteral(p.parseInt(), token.INT, 0)
+	if mant == nil {
+		panic("invalid mantissa")
+	}
+
+	if p.lit == "p" {
+		// exponent (base 2)
+		p.next()
+		exp, err := strconv.ParseInt(p.parseInt(), 10, 0)
+		if err != nil {
+			p.error(err)
+		}
+		if exp < 0 {
+			denom := exact.MakeInt64(1)
+			denom = exact.Shift(denom, token.SHL, uint(-exp))
+			typ = types.Typ[types.UntypedFloat]
+			val = exact.BinaryOp(mant, token.QUO, denom)
+			return
+		}
+		if exp > 0 {
+			mant = exact.Shift(mant, token.SHL, uint(exp))
+		}
+		typ = types.Typ[types.UntypedFloat]
+		val = mant
+		return
+	}
+
+	typ = types.Typ[types.UntypedInt]
+	val = mant
+	return
+}
+
+// ConstDecl   = "const" ExportedName [ Type ] "=" Literal .
+// Literal     = bool_lit | int_lit | float_lit | complex_lit | rune_lit | string_lit .
+// bool_lit    = "true" | "false" .
+// complex_lit = "(" float_lit "+" float_lit "i" ")" .
+// rune_lit    = "(" int_lit "+" int_lit ")" .
+// string_lit  = `"` { unicode_char } `"` .
+//
+func (p *parser) parseConstDecl() {
+	p.expectKeyword("const")
+	pkg, name := p.parseExportedName()
+
+	var typ0 types.Type
+	if p.tok != '=' {
+		typ0 = p.parseType()
+	}
+
+	p.expect('=')
+	var typ types.Type
+	var val exact.Value
+	switch p.tok {
+	case scanner.Ident:
+		// bool_lit
+		if p.lit != "true" && p.lit != "false" {
+			p.error("expected true or false")
+		}
+		typ = types.Typ[types.UntypedBool]
+		val = exact.MakeBool(p.lit == "true")
+		p.next()
+
+	case '-', scanner.Int:
+		// int_lit
+		typ, val = p.parseNumber()
+
+	case '(':
+		// complex_lit or rune_lit
+		p.next()
+		if p.tok == scanner.Char {
+			p.next()
+			p.expect('+')
+			typ = types.Typ[types.UntypedRune]
+			_, val = p.parseNumber()
+			p.expect(')')
+			break
+		}
+		_, re := p.parseNumber()
+		p.expect('+')
+		_, im := p.parseNumber()
+		p.expectKeyword("i")
+		p.expect(')')
+		typ = types.Typ[types.UntypedComplex]
+		val = exact.BinaryOp(re, token.ADD, exact.MakeImag(im))
+
+	case scanner.Char:
+		// rune_lit
+		typ = types.Typ[types.UntypedRune]
+		val = exact.MakeFromLiteral(p.lit, token.CHAR, 0)
+		p.next()
+
+	case scanner.String:
+		// string_lit
+		typ = types.Typ[types.UntypedString]
+		val = exact.MakeFromLiteral(p.lit, token.STRING, 0)
+		p.next()
+
+	default:
+		p.errorf("expected literal got %s", scanner.TokenString(p.tok))
+	}
+
+	if typ0 == nil {
+		typ0 = typ
+	}
+
+	pkg.Scope().Insert(types.NewConst(token.NoPos, pkg, name, typ0, val))
+}
+
+// TypeDecl = "type" ExportedName Type .
+//
+func (p *parser) parseTypeDecl() {
+	p.expectKeyword("type")
+	pkg, name := p.parseExportedName()
+	obj := declTypeName(pkg, name)
+
+	// The type object may have been imported before and thus already
+	// have a type associated with it. We still need to parse the type
+	// structure, but throw it away if the object already has a type.
+	// This ensures that all imports refer to the same type object for
+	// a given type declaration.
+	typ := p.parseType()
+
+	if name := obj.Type().(*types.Named); name.Underlying() == nil {
+		name.SetUnderlying(typ)
+	}
+}
+
+// VarDecl = "var" ExportedName Type .
+//
+func (p *parser) parseVarDecl() {
+	p.expectKeyword("var")
+	pkg, name := p.parseExportedName()
+	typ := p.parseType()
+	pkg.Scope().Insert(types.NewVar(token.NoPos, pkg, name, typ))
+}
+
+// Func = Signature [ Body ] .
+// Body = "{" ... "}" .
+//
+func (p *parser) parseFunc(recv *types.Var) *types.Signature {
+	sig := p.parseSignature(recv)
+	if p.tok == '{' {
+		p.next()
+		for i := 1; i > 0; p.next() {
+			switch p.tok {
+			case '{':
+				i++
+			case '}':
+				i--
+			}
+		}
+	}
+	return sig
+}
+
+// MethodDecl = "func" Receiver Name Func .
+// Receiver   = "(" ( identifier | "?" ) [ "*" ] ExportedName ")" .
+//
+func (p *parser) parseMethodDecl() {
+	// "func" already consumed
+	p.expect('(')
+	recv, _ := p.parseParameter() // receiver
+	p.expect(')')
+
+	// determine receiver base type object
+	base := deref(recv.Type()).(*types.Named)
+
+	// parse method name, signature, and possibly inlined body
+	_, name := p.parseName(true)
+	sig := p.parseFunc(recv)
+
+	// methods always belong to the same package as the base type object
+	pkg := base.Obj().Pkg()
+
+	// add method to type unless type was imported before
+	// and method exists already
+	// TODO(gri) This leads to a quadratic algorithm - ok for now because method counts are small.
+	base.AddMethod(types.NewFunc(token.NoPos, pkg, name, sig))
+}
+
+// FuncDecl = "func" ExportedName Func .
+//
+func (p *parser) parseFuncDecl() {
+	// "func" already consumed
+	pkg, name := p.parseExportedName()
+	typ := p.parseFunc(nil)
+	pkg.Scope().Insert(types.NewFunc(token.NoPos, pkg, name, typ))
+}
+
+// Decl = [ ImportDecl | ConstDecl | TypeDecl | VarDecl | FuncDecl | MethodDecl ] "\n" .
+//
+func (p *parser) parseDecl() {
+	if p.tok == scanner.Ident {
+		switch p.lit {
+		case "import":
+			p.parseImportDecl()
+		case "const":
+			p.parseConstDecl()
+		case "type":
+			p.parseTypeDecl()
+		case "var":
+			p.parseVarDecl()
+		case "func":
+			p.next() // look ahead
+			if p.tok == '(' {
+				p.parseMethodDecl()
+			} else {
+				p.parseFuncDecl()
+			}
+		}
+	}
+	p.expect('\n')
+}
+
+// ----------------------------------------------------------------------------
+// Export
+
+// Export        = "PackageClause { Decl } "$$" .
+// PackageClause = "package" PackageName [ "safe" ] "\n" .
+//
+func (p *parser) parseExport() *types.Package {
+	p.expectKeyword("package")
+	name := p.parsePackageName()
+	if p.tok == scanner.Ident && p.lit == "safe" {
+		// package was compiled with -u option - ignore
+		p.next()
+	}
+	p.expect('\n')
+
+	pkg := p.getPkg(p.id, name)
+
+	for p.tok != '$' && p.tok != scanner.EOF {
+		p.parseDecl()
+	}
+
+	if ch := p.scanner.Peek(); p.tok != '$' || ch != '$' {
+		// don't call next()/expect() since reading past the
+		// export data may cause scanner errors (e.g. NUL chars)
+		p.errorf("expected '$$', got %s %c", scanner.TokenString(p.tok), ch)
+	}
+
+	if n := p.scanner.ErrorCount; n != 0 {
+		p.errorf("expected no scanner errors, got %d", n)
+	}
+
+	// Record all referenced packages as imports.
+	var imports []*types.Package
+	for id, pkg2 := range p.localPkgs {
+		if id == p.id {
+			continue // avoid self-edge
+		}
+		imports = append(imports, pkg2)
+	}
+	sort.Sort(byPath(imports))
+	pkg.SetImports(imports)
+
+	// package was imported completely and without errors
+	pkg.MarkComplete()
+
+	return pkg
+}
+
+type byPath []*types.Package
+
+func (a byPath) Len() int           { return len(a) }
+func (a byPath) Swap(i, j int)      { a[i], a[j] = a[j], a[i] }
+func (a byPath) Less(i, j int) bool { return a[i].Path() < a[j].Path() }
diff --git a/third_party/gofrontend/libgo/go/go/internal/gcimporter/gcimporter_test.go b/third_party/gofrontend/libgo/go/go/internal/gcimporter/gcimporter_test.go
new file mode 100644
index 0000000..07993a8
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/go/internal/gcimporter/gcimporter_test.go
@@ -0,0 +1,225 @@
+// Copyright 2011 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 gcimporter
+
+import (
+	"fmt"
+	"internal/testenv"
+	"io/ioutil"
+	"os"
+	"os/exec"
+	"path/filepath"
+	"runtime"
+	"strings"
+	"testing"
+	"time"
+
+	"go/types"
+)
+
+// skipSpecialPlatforms causes the test to be skipped for platforms where
+// builders (build.golang.org) don't have access to compiled packages for
+// import.
+func skipSpecialPlatforms(t *testing.T) {
+	switch platform := runtime.GOOS + "-" + runtime.GOARCH; platform {
+	case "nacl-amd64p32",
+		"nacl-386",
+		"nacl-arm",
+		"darwin-arm",
+		"darwin-arm64":
+		t.Skipf("no compiled packages available for import on %s", platform)
+	}
+}
+
+func compile(t *testing.T, dirname, filename string) string {
+	testenv.MustHaveGoBuild(t)
+	cmd := exec.Command("go", "tool", "compile", filename)
+	cmd.Dir = dirname
+	out, err := cmd.CombinedOutput()
+	if err != nil {
+		t.Logf("%s", out)
+		t.Fatalf("go tool compile %s failed: %s", filename, err)
+	}
+	// filename should end with ".go"
+	return filepath.Join(dirname, filename[:len(filename)-2]+"o")
+}
+
+// Use the same global imports map for all tests. The effect is
+// as if all tested packages were imported into a single package.
+var imports = make(map[string]*types.Package)
+
+func testPath(t *testing.T, path string) *types.Package {
+	t0 := time.Now()
+	pkg, err := Import(imports, path)
+	if err != nil {
+		t.Errorf("testPath(%s): %s", path, err)
+		return nil
+	}
+	t.Logf("testPath(%s): %v", path, time.Since(t0))
+	return pkg
+}
+
+const maxTime = 30 * time.Second
+
+func testDir(t *testing.T, dir string, endTime time.Time) (nimports int) {
+	dirname := filepath.Join(runtime.GOROOT(), "pkg", runtime.GOOS+"_"+runtime.GOARCH, dir)
+	list, err := ioutil.ReadDir(dirname)
+	if err != nil {
+		t.Fatalf("testDir(%s): %s", dirname, err)
+	}
+	for _, f := range list {
+		if time.Now().After(endTime) {
+			t.Log("testing time used up")
+			return
+		}
+		switch {
+		case !f.IsDir():
+			// try extensions
+			for _, ext := range pkgExts {
+				if strings.HasSuffix(f.Name(), ext) {
+					name := f.Name()[0 : len(f.Name())-len(ext)] // remove extension
+					if testPath(t, filepath.Join(dir, name)) != nil {
+						nimports++
+					}
+				}
+			}
+		case f.IsDir():
+			nimports += testDir(t, filepath.Join(dir, f.Name()), endTime)
+		}
+	}
+	return
+}
+
+func TestImport(t *testing.T) {
+	// This package only handles gc export data.
+	if runtime.Compiler != "gc" {
+		t.Skipf("gc-built packages not available (compiler = %s)", runtime.Compiler)
+		return
+	}
+
+	if outFn := compile(t, "testdata", "exports.go"); outFn != "" {
+		defer os.Remove(outFn)
+	}
+
+	nimports := 0
+	if pkg := testPath(t, "./testdata/exports"); pkg != nil {
+		nimports++
+		// The package's Imports should include all the types
+		// referenced by the exportdata, which may be more than
+		// the import statements in the package's source, but
+		// fewer than the transitive closure of dependencies.
+		want := `[package ast ("go/ast") package token ("go/token") package runtime ("runtime")]`
+		got := fmt.Sprint(pkg.Imports())
+		if got != want {
+			t.Errorf(`Package("exports").Imports() = %s, want %s`, got, want)
+		}
+	}
+	nimports += testDir(t, "", time.Now().Add(maxTime)) // installed packages
+	t.Logf("tested %d imports", nimports)
+}
+
+var importedObjectTests = []struct {
+	name string
+	want string
+}{
+	{"math.Pi", "const Pi untyped float"},
+	{"io.Reader", "type Reader interface{Read(p []byte) (n int, err error)}"},
+	{"io.ReadWriter", "type ReadWriter interface{Read(p []byte) (n int, err error); Write(p []byte) (n int, err error)}"},
+	{"math.Sin", "func Sin(x float64) float64"},
+	// TODO(gri) add more tests
+}
+
+func TestImportedTypes(t *testing.T) {
+	skipSpecialPlatforms(t)
+
+	// This package only handles gc export data.
+	if runtime.Compiler != "gc" {
+		t.Skipf("gc-built packages not available (compiler = %s)", runtime.Compiler)
+		return
+	}
+
+	for _, test := range importedObjectTests {
+		s := strings.Split(test.name, ".")
+		if len(s) != 2 {
+			t.Fatal("inconsistent test data")
+		}
+		importPath := s[0]
+		objName := s[1]
+
+		pkg, err := Import(imports, importPath)
+		if err != nil {
+			t.Error(err)
+			continue
+		}
+
+		obj := pkg.Scope().Lookup(objName)
+		if obj == nil {
+			t.Errorf("%s: object not found", test.name)
+			continue
+		}
+
+		got := types.ObjectString(obj, types.RelativeTo(pkg))
+		if got != test.want {
+			t.Errorf("%s: got %q; want %q", test.name, got, test.want)
+		}
+	}
+}
+
+func TestIssue5815(t *testing.T) {
+	skipSpecialPlatforms(t)
+
+	// This package only handles gc export data.
+	if runtime.Compiler != "gc" {
+		t.Skipf("gc-built packages not available (compiler = %s)", runtime.Compiler)
+		return
+	}
+
+	pkg, err := Import(make(map[string]*types.Package), "strings")
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	scope := pkg.Scope()
+	for _, name := range scope.Names() {
+		obj := scope.Lookup(name)
+		if obj.Pkg() == nil {
+			t.Errorf("no pkg for %s", obj)
+		}
+		if tname, _ := obj.(*types.TypeName); tname != nil {
+			named := tname.Type().(*types.Named)
+			for i := 0; i < named.NumMethods(); i++ {
+				m := named.Method(i)
+				if m.Pkg() == nil {
+					t.Errorf("no pkg for %s", m)
+				}
+			}
+		}
+	}
+}
+
+// Smoke test to ensure that imported methods get the correct package.
+func TestCorrectMethodPackage(t *testing.T) {
+	skipSpecialPlatforms(t)
+
+	// This package only handles gc export data.
+	if runtime.Compiler != "gc" {
+		t.Skipf("gc-built packages not available (compiler = %s)", runtime.Compiler)
+		return
+	}
+
+	imports := make(map[string]*types.Package)
+	_, err := Import(imports, "net/http")
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	mutex := imports["sync"].Scope().Lookup("Mutex").(*types.TypeName).Type()
+	mset := types.NewMethodSet(types.NewPointer(mutex)) // methods of *sync.Mutex
+	sel := mset.Lookup(nil, "Lock")
+	lock := sel.Obj().(*types.Func)
+	if got, want := lock.Pkg().Path(), "sync"; got != want {
+		t.Errorf("got package path %q; want %q", got, want)
+	}
+}
diff --git a/third_party/gofrontend/libgo/go/go/internal/gcimporter/testdata/exports.go b/third_party/gofrontend/libgo/go/go/internal/gcimporter/testdata/exports.go
new file mode 100644
index 0000000..8ee28b0
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/go/internal/gcimporter/testdata/exports.go
@@ -0,0 +1,89 @@
+// Copyright 2011 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.
+
+// This file is used to generate an object file which
+// serves as test file for gcimporter_test.go.
+
+package exports
+
+import (
+	"go/ast"
+)
+
+// Issue 3682: Correctly read dotted identifiers from export data.
+const init1 = 0
+
+func init() {}
+
+const (
+	C0 int = 0
+	C1     = 3.14159265
+	C2     = 2.718281828i
+	C3     = -123.456e-789
+	C4     = +123.456E+789
+	C5     = 1234i
+	C6     = "foo\n"
+	C7     = `bar\n`
+)
+
+type (
+	T1  int
+	T2  [10]int
+	T3  []int
+	T4  *int
+	T5  chan int
+	T6a chan<- int
+	T6b chan (<-chan int)
+	T6c chan<- (chan int)
+	T7  <-chan *ast.File
+	T8  struct{}
+	T9  struct {
+		a    int
+		b, c float32
+		d    []string `go:"tag"`
+	}
+	T10 struct {
+		T8
+		T9
+		_ *T10
+	}
+	T11 map[int]string
+	T12 interface{}
+	T13 interface {
+		m1()
+		m2(int) float32
+	}
+	T14 interface {
+		T12
+		T13
+		m3(x ...struct{}) []T9
+	}
+	T15 func()
+	T16 func(int)
+	T17 func(x int)
+	T18 func() float32
+	T19 func() (x float32)
+	T20 func(...interface{})
+	T21 struct{ next *T21 }
+	T22 struct{ link *T23 }
+	T23 struct{ link *T22 }
+	T24 *T24
+	T25 *T26
+	T26 *T27
+	T27 *T25
+	T28 func(T28) T28
+)
+
+var (
+	V0 int
+	V1 = -991.0
+)
+
+func F1()         {}
+func F2(x int)    {}
+func F3() int     { return 0 }
+func F4() float32 { return 0 }
+func F5(a, b, c int, u, v, w struct{ x, y T1 }, more ...interface{}) (p, q, r chan<- T10)
+
+func (p *T1) M1()
diff --git a/third_party/gofrontend/libgo/go/go/parser/error_test.go b/third_party/gofrontend/libgo/go/go/parser/error_test.go
index 48fb53e..1a08d5a 100644
--- a/third_party/gofrontend/libgo/go/go/parser/error_test.go
+++ b/third_party/gofrontend/libgo/go/go/parser/error_test.go
@@ -34,11 +34,9 @@
 
 const testdata = "testdata"
 
-var fsetErrs = token.NewFileSet()
-
 // getFile assumes that each filename occurs at most once
-func getFile(filename string) (file *token.File) {
-	fsetErrs.Iterate(func(f *token.File) bool {
+func getFile(fset *token.FileSet, filename string) (file *token.File) {
+	fset.Iterate(func(f *token.File) bool {
 		if f.Name() == filename {
 			if file != nil {
 				panic(filename + " used multiple times")
@@ -50,8 +48,8 @@
 	return file
 }
 
-func getPos(filename string, offset int) token.Pos {
-	if f := getFile(filename); f != nil {
+func getPos(fset *token.FileSet, filename string, offset int) token.Pos {
+	if f := getFile(fset, filename); f != nil {
 		return f.Pos(offset)
 	}
 	return token.NoPos
@@ -68,14 +66,14 @@
 // expectedErrors collects the regular expressions of ERROR comments found
 // in files and returns them as a map of error positions to error messages.
 //
-func expectedErrors(t *testing.T, filename string, src []byte) map[token.Pos]string {
+func expectedErrors(t *testing.T, fset *token.FileSet, filename string, src []byte) map[token.Pos]string {
 	errors := make(map[token.Pos]string)
 
 	var s scanner.Scanner
 	// file was parsed already - do not add it again to the file
 	// set otherwise the position information returned here will
 	// not match the position information collected by the parser
-	s.Init(getFile(filename), src, nil, scanner.ScanComments)
+	s.Init(getFile(fset, filename), src, nil, scanner.ScanComments)
 	var prev token.Pos // position of last non-comment, non-semicolon token
 	var here token.Pos // position immediately after the token at position prev
 
@@ -109,11 +107,11 @@
 // compareErrors compares the map of expected error messages with the list
 // of found errors and reports discrepancies.
 //
-func compareErrors(t *testing.T, expected map[token.Pos]string, found scanner.ErrorList) {
+func compareErrors(t *testing.T, fset *token.FileSet, expected map[token.Pos]string, found scanner.ErrorList) {
 	for _, error := range found {
 		// error.Pos is a token.Position, but we want
 		// a token.Pos so we can do a map lookup
-		pos := getPos(error.Pos.Filename, error.Pos.Offset)
+		pos := getPos(fset, error.Pos.Filename, error.Pos.Offset)
 		if msg, found := expected[pos]; found {
 			// we expect a message at pos; check if it matches
 			rx, err := regexp.Compile(msg)
@@ -140,7 +138,7 @@
 	if len(expected) > 0 {
 		t.Errorf("%d errors not reported:", len(expected))
 		for pos, msg := range expected {
-			t.Errorf("%s: %s\n", fsetErrs.Position(pos), msg)
+			t.Errorf("%s: %s\n", fset.Position(pos), msg)
 		}
 	}
 }
@@ -152,7 +150,8 @@
 		return
 	}
 
-	_, err = ParseFile(fsetErrs, filename, src, DeclarationErrors|AllErrors)
+	fset := token.NewFileSet()
+	_, err = ParseFile(fset, filename, src, DeclarationErrors|AllErrors)
 	found, ok := err.(scanner.ErrorList)
 	if err != nil && !ok {
 		t.Error(err)
@@ -162,10 +161,10 @@
 
 	// we are expecting the following errors
 	// (collect these after parsing a file so that it is found in the file set)
-	expected := expectedErrors(t, filename, src)
+	expected := expectedErrors(t, fset, filename, src)
 
 	// verify errors returned by the parser
-	compareErrors(t, expected, found)
+	compareErrors(t, fset, expected, found)
 }
 
 func TestErrors(t *testing.T) {
diff --git a/third_party/gofrontend/libgo/go/go/parser/interface.go b/third_party/gofrontend/libgo/go/go/parser/interface.go
index 4910305..c6fd932 100644
--- a/third_party/gofrontend/libgo/go/go/parser/interface.go
+++ b/third_party/gofrontend/libgo/go/go/parser/interface.go
@@ -91,7 +91,10 @@
 	var p parser
 	defer func() {
 		if e := recover(); e != nil {
-			_ = e.(bailout) // re-panics if it's not a bailout
+			// resume same panic if it's not a bailout
+			if _, ok := e.(bailout); !ok {
+				panic(e)
+			}
 		}
 
 		// set result values
@@ -164,14 +167,31 @@
 	return
 }
 
-// ParseExpr is a convenience function for obtaining the AST of an expression x.
-// The position information recorded in the AST is undefined. The filename used
-// in error messages is the empty string.
+// ParseExprFrom is a convenience function for parsing an expression.
+// The arguments have the same meaning as for Parse, but the source must
+// be a valid Go (type or value) expression.
 //
-func ParseExpr(x string) (ast.Expr, error) {
-	var p parser
-	p.init(token.NewFileSet(), "", []byte(x), 0)
+func ParseExprFrom(fset *token.FileSet, filename string, src interface{}, mode Mode) (ast.Expr, error) {
+	// get source
+	text, err := readSource(filename, src)
+	if err != nil {
+		return nil, err
+	}
 
+	var p parser
+	defer func() {
+		if e := recover(); e != nil {
+			// resume same panic if it's not a bailout
+			if _, ok := e.(bailout); !ok {
+				panic(e)
+			}
+		}
+		p.errors.Sort()
+		err = p.errors.Err()
+	}()
+
+	// parse expr
+	p.init(fset, filename, text, mode)
 	// Set up pkg-level scopes to avoid nil-pointer errors.
 	// This is not needed for a correct expression x as the
 	// parser will be ok with a nil topScope, but be cautious
@@ -196,3 +216,11 @@
 
 	return e, nil
 }
+
+// ParseExpr is a convenience function for obtaining the AST of an expression x.
+// The position information recorded in the AST is undefined. The filename used
+// in error messages is the empty string.
+//
+func ParseExpr(x string) (ast.Expr, error) {
+	return ParseExprFrom(token.NewFileSet(), "", []byte(x), 0)
+}
diff --git a/third_party/gofrontend/libgo/go/go/parser/parser.go b/third_party/gofrontend/libgo/go/go/parser/parser.go
index 4a005d8..e82c0bd 100644
--- a/third_party/gofrontend/libgo/go/go/parser/parser.go
+++ b/third_party/gofrontend/libgo/go/go/parser/parser.go
@@ -7,6 +7,13 @@
 // output is an abstract syntax tree (AST) representing the Go source. The
 // parser is invoked through one of the Parse* functions.
 //
+// The parser accepts a larger language than is syntactically permitted by
+// the Go spec, for simplicity, and for improved robustness in the presence
+// of syntax errors. For instance, in method declarations, the receiver is
+// treated like an ordinary parameter list and thus may contain multiple
+// entries where the spec permits exactly one. Consequently, the corresponding
+// field in the AST (ast.FuncDecl.Recv) field is not restricted to one entry.
+//
 package parser
 
 import (
@@ -412,14 +419,17 @@
 	}
 }
 
-func (p *parser) atComma(context string) bool {
+func (p *parser) atComma(context string, follow token.Token) bool {
 	if p.tok == token.COMMA {
 		return true
 	}
-	if p.tok == token.SEMICOLON && p.lit == "\n" {
-		p.error(p.pos, "missing ',' before newline in "+context)
-		return true // "insert" the comma and continue
-
+	if p.tok != follow {
+		msg := "missing ','"
+		if p.tok == token.SEMICOLON && p.lit == "\n" {
+			msg += " before newline"
+		}
+		p.error(p.pos, msg+" in "+context)
+		return true // "insert" comma and continue
 	}
 	return false
 }
@@ -825,7 +835,7 @@
 		// parameter or result variable is the function body.
 		p.declare(field, nil, scope, ast.Var, idents...)
 		p.resolve(typ)
-		if !p.atComma("parameter list") {
+		if !p.atComma("parameter list", token.RPAREN) {
 			return
 		}
 		p.next()
@@ -838,7 +848,7 @@
 			// parameter or result variable is the function body.
 			p.declare(field, nil, scope, ast.Var, idents...)
 			p.resolve(typ)
-			if !p.atComma("parameter list") {
+			if !p.atComma("parameter list", token.RPAREN) {
 				break
 			}
 			p.next()
@@ -1248,7 +1258,7 @@
 			ellipsis = p.pos
 			p.next()
 		}
-		if !p.atComma("argument list") {
+		if !p.atComma("argument list", token.RPAREN) {
 			break
 		}
 		p.next()
@@ -1259,7 +1269,7 @@
 	return &ast.CallExpr{Fun: fun, Lparen: lparen, Args: list, Ellipsis: ellipsis, Rparen: rparen}
 }
 
-func (p *parser) parseElement(keyOk bool) ast.Expr {
+func (p *parser) parseValue(keyOk bool) ast.Expr {
 	if p.trace {
 		defer un(trace(p, "Element"))
 	}
@@ -1287,16 +1297,30 @@
 	x := p.checkExpr(p.parseExpr(keyOk))
 	if keyOk {
 		if p.tok == token.COLON {
-			colon := p.pos
-			p.next()
 			// Try to resolve the key but don't collect it
 			// as unresolved identifier if it fails so that
 			// we don't get (possibly false) errors about
 			// undeclared names.
 			p.tryResolve(x, false)
-			return &ast.KeyValueExpr{Key: x, Colon: colon, Value: p.parseElement(false)}
+		} else {
+			// not a key
+			p.resolve(x)
 		}
-		p.resolve(x) // not a key
+	}
+
+	return x
+}
+
+func (p *parser) parseElement() ast.Expr {
+	if p.trace {
+		defer un(trace(p, "Element"))
+	}
+
+	x := p.parseValue(true)
+	if p.tok == token.COLON {
+		colon := p.pos
+		p.next()
+		x = &ast.KeyValueExpr{Key: x, Colon: colon, Value: p.parseValue(false)}
 	}
 
 	return x
@@ -1308,8 +1332,8 @@
 	}
 
 	for p.tok != token.RBRACE && p.tok != token.EOF {
-		list = append(list, p.parseElement(true))
-		if !p.atComma("composite literal") {
+		list = append(list, p.parseElement())
+		if !p.atComma("composite literal", token.RBRACE) {
 			break
 		}
 		p.next()
@@ -1365,7 +1389,7 @@
 	return x
 }
 
-// isTypeName returns true iff x is a (qualified) TypeName.
+// isTypeName reports whether x is a (qualified) TypeName.
 func isTypeName(x ast.Expr) bool {
 	switch t := x.(type) {
 	case *ast.BadExpr:
@@ -1379,7 +1403,7 @@
 	return true
 }
 
-// isLiteralType returns true iff x is a legal composite literal type.
+// isLiteralType reports whether x is a legal composite literal type.
 func isLiteralType(x ast.Expr) bool {
 	switch t := x.(type) {
 	case *ast.BadExpr:
@@ -1455,7 +1479,8 @@
 				pos := p.pos
 				p.errorExpected(pos, "selector or type assertion")
 				p.next() // make progress
-				x = &ast.BadExpr{From: pos, To: p.pos}
+				sel := &ast.Ident{NamePos: pos, Name: "_"}
+				x = &ast.SelectorExpr{X: x, Sel: sel}
 			}
 		case token.LBRACK:
 			if lhs {
@@ -2123,7 +2148,7 @@
 	case
 		// tokens that may start an expression
 		token.IDENT, token.INT, token.FLOAT, token.IMAG, token.CHAR, token.STRING, token.FUNC, token.LPAREN, // operands
-		token.LBRACK, token.STRUCT, // composite types
+		token.LBRACK, token.STRUCT, token.MAP, token.CHAN, token.INTERFACE, // composite types
 		token.ADD, token.SUB, token.MUL, token.AND, token.XOR, token.ARROW, token.NOT: // unary operators
 		s, _ = p.parseSimpleStmt(labelOk)
 		// because of the required look-ahead, labeled statements are
@@ -2152,11 +2177,14 @@
 	case token.FOR:
 		s = p.parseForStmt()
 	case token.SEMICOLON:
-		s = &ast.EmptyStmt{Semicolon: p.pos}
+		// Is it ever possible to have an implicit semicolon
+		// producing an empty statement in a valid program?
+		// (handle correctly anyway)
+		s = &ast.EmptyStmt{Semicolon: p.pos, Implicit: p.lit == "\n"}
 		p.next()
 	case token.RBRACE:
 		// a semicolon may be omitted before a closing "}"
-		s = &ast.EmptyStmt{Semicolon: p.pos}
+		s = &ast.EmptyStmt{Semicolon: p.pos, Implicit: true}
 	default:
 		// no statement found
 		pos := p.pos
@@ -2228,6 +2256,7 @@
 		defer un(trace(p, keyword.String()+"Spec"))
 	}
 
+	pos := p.pos
 	idents := p.parseIdentList()
 	typ := p.tryType()
 	var values []ast.Expr
@@ -2238,6 +2267,17 @@
 	}
 	p.expectSemi() // call before accessing p.linecomment
 
+	switch keyword {
+	case token.VAR:
+		if typ == nil && values == nil {
+			p.error(pos, "missing variable type or initialization")
+		}
+	case token.CONST:
+		if values == nil && (iota == 0 || typ != nil) {
+			p.error(pos, "missing constant value")
+		}
+	}
+
 	// Go spec: The scope of a constant or variable identifier declared inside
 	// a function begins at the end of the ConstSpec or VarSpec and ends at
 	// the end of the innermost containing block.
diff --git a/third_party/gofrontend/libgo/go/go/parser/parser_test.go b/third_party/gofrontend/libgo/go/go/parser/parser_test.go
index 85065fd..c7bb36d 100644
--- a/third_party/gofrontend/libgo/go/go/parser/parser_test.go
+++ b/third_party/gofrontend/libgo/go/go/parser/parser_test.go
@@ -14,8 +14,6 @@
 	"testing"
 )
 
-var fset = token.NewFileSet()
-
 var validFiles = []string{
 	"parser.go",
 	"parser_test.go",
@@ -25,7 +23,7 @@
 
 func TestParse(t *testing.T) {
 	for _, filename := range validFiles {
-		_, err := ParseFile(fset, filename, nil, DeclarationErrors)
+		_, err := ParseFile(token.NewFileSet(), filename, nil, DeclarationErrors)
 		if err != nil {
 			t.Fatalf("ParseFile(%s): %v", filename, err)
 		}
@@ -46,7 +44,7 @@
 
 func TestParseDir(t *testing.T) {
 	path := "."
-	pkgs, err := ParseDir(fset, path, dirFilter, 0)
+	pkgs, err := ParseDir(token.NewFileSet(), path, dirFilter, 0)
 	if err != nil {
 		t.Fatalf("ParseDir(%s): %v", path, err)
 	}
@@ -131,7 +129,7 @@
 }
 
 func TestColonEqualsScope(t *testing.T) {
-	f, err := ParseFile(fset, "", `package p; func f() { x, y, z := x, y, z }`, 0)
+	f, err := ParseFile(token.NewFileSet(), "", `package p; func f() { x, y, z := x, y, z }`, 0)
 	if err != nil {
 		t.Fatal(err)
 	}
@@ -153,7 +151,7 @@
 }
 
 func TestVarScope(t *testing.T) {
-	f, err := ParseFile(fset, "", `package p; func f() { var x, y, z = x, y, z }`, 0)
+	f, err := ParseFile(token.NewFileSet(), "", `package p; func f() { var x, y, z = x, y, z }`, 0)
 	if err != nil {
 		t.Fatal(err)
 	}
@@ -183,7 +181,7 @@
 func f() { L: }
 `
 
-	f, err := ParseFile(fset, "", src, 0)
+	f, err := ParseFile(token.NewFileSet(), "", src, 0)
 	if err != nil {
 		t.Fatal(err)
 	}
@@ -221,7 +219,7 @@
 }
 
 func TestUnresolved(t *testing.T) {
-	f, err := ParseFile(fset, "", `
+	f, err := ParseFile(token.NewFileSet(), "", `
 package p
 //
 func f1a(int)
@@ -316,7 +314,7 @@
 func TestImports(t *testing.T) {
 	for path, isValid := range imports {
 		src := fmt.Sprintf("package p; import %s", path)
-		_, err := ParseFile(fset, "", src, 0)
+		_, err := ParseFile(token.NewFileSet(), "", src, 0)
 		switch {
 		case err != nil && isValid:
 			t.Errorf("ParseFile(%s): got %v; expected no error", src, err)
@@ -327,7 +325,7 @@
 }
 
 func TestCommentGroups(t *testing.T) {
-	f, err := ParseFile(fset, "", `
+	f, err := ParseFile(token.NewFileSet(), "", `
 package p /* 1a */ /* 1b */      /* 1c */ // 1d
 /* 2a
 */
@@ -421,7 +419,7 @@
 }
 
 func TestLeadAndLineComments(t *testing.T) {
-	f, err := ParseFile(fset, "", `
+	f, err := ParseFile(token.NewFileSet(), "", `
 package p
 type T struct {
 	/* F1 lead comment */
@@ -447,3 +445,89 @@
 		t.Error("not expected to find T.f3")
 	}
 }
+
+// TestIssue9979 verifies that empty statements are contained within their enclosing blocks.
+func TestIssue9979(t *testing.T) {
+	for _, src := range []string{
+		"package p; func f() {;}",
+		"package p; func f() {L:}",
+		"package p; func f() {L:;}",
+		"package p; func f() {L:\n}",
+		"package p; func f() {L:\n;}",
+		"package p; func f() { ; }",
+		"package p; func f() { L: }",
+		"package p; func f() { L: ; }",
+		"package p; func f() { L: \n}",
+		"package p; func f() { L: \n; }",
+	} {
+		fset := token.NewFileSet()
+		f, err := ParseFile(fset, "", src, 0)
+		if err != nil {
+			t.Fatal(err)
+		}
+
+		var pos, end token.Pos
+		ast.Inspect(f, func(x ast.Node) bool {
+			switch s := x.(type) {
+			case *ast.BlockStmt:
+				pos, end = s.Pos()+1, s.End()-1 // exclude "{", "}"
+			case *ast.LabeledStmt:
+				pos, end = s.Pos()+2, s.End() // exclude "L:"
+			case *ast.EmptyStmt:
+				// check containment
+				if s.Pos() < pos || s.End() > end {
+					t.Errorf("%s: %T[%d, %d] not inside [%d, %d]", src, s, s.Pos(), s.End(), pos, end)
+				}
+				// check semicolon
+				offs := fset.Position(s.Pos()).Offset
+				if ch := src[offs]; ch != ';' != s.Implicit {
+					want := "want ';'"
+					if s.Implicit {
+						want = "but ';' is implicit"
+					}
+					t.Errorf("%s: found %q at offset %d; %s", src, ch, offs, want)
+				}
+			}
+			return true
+		})
+	}
+}
+
+// TestIncompleteSelection ensures that an incomplete selector
+// expression is parsed as a (blank) *ast.SelectorExpr, not a
+// *ast.BadExpr.
+func TestIncompleteSelection(t *testing.T) {
+	for _, src := range []string{
+		"package p; var _ = fmt.",             // at EOF
+		"package p; var _ = fmt.\ntype X int", // not at EOF
+	} {
+		fset := token.NewFileSet()
+		f, err := ParseFile(fset, "", src, 0)
+		if err == nil {
+			t.Errorf("ParseFile(%s) succeeded unexpectedly", src)
+			continue
+		}
+
+		const wantErr = "expected selector or type assertion"
+		if !strings.Contains(err.Error(), wantErr) {
+			t.Errorf("ParseFile returned wrong error %q, want %q", err, wantErr)
+		}
+
+		var sel *ast.SelectorExpr
+		ast.Inspect(f, func(n ast.Node) bool {
+			if n, ok := n.(*ast.SelectorExpr); ok {
+				sel = n
+			}
+			return true
+		})
+		if sel == nil {
+			t.Error("found no *ast.SelectorExpr")
+			continue
+		}
+		const wantSel = "&{fmt _}"
+		if fmt.Sprint(sel) != wantSel {
+			t.Errorf("found selector %s, want %s", sel, wantSel)
+			continue
+		}
+	}
+}
diff --git a/third_party/gofrontend/libgo/go/go/parser/short_test.go b/third_party/gofrontend/libgo/go/go/parser/short_test.go
index 05e44de..ef2ffad 100644
--- a/third_party/gofrontend/libgo/go/go/parser/short_test.go
+++ b/third_party/gofrontend/libgo/go/go/parser/short_test.go
@@ -40,6 +40,12 @@
 	`package p; func (*(T),) m() {}`,
 	`package p; func _(x []int) { for range x {} }`,
 	`package p; func _() { if [T{}.n]int{} {} }`,
+	`package p; func _() { map[int]int{}[0]++; map[int]int{}[0] += 1 }`,
+	`package p; func _(x interface{f()}) { interface{f()}(x).f() }`,
+	`package p; func _(x chan int) { chan int(x) <- 0 }`,
+	`package p; const (x = 0; y; z)`, // issue 9639
+	`package p; var _ = map[P]int{P{}:0, {}:1}`,
+	`package p; var _ = map[*P]int{&P{}:0, {}:1}`,
 }
 
 func TestValid(t *testing.T) {
@@ -93,8 +99,13 @@
 	`package p; func f() { for i /* ERROR "boolean or range expression" */ , x := []string {} }`,
 	`package p; func f() { go f /* ERROR HERE "function must be invoked" */ }`,
 	`package p; func f() { defer func() {} /* ERROR HERE "function must be invoked" */ }`,
-	`package p; func f() { go func() { func() { f(x func /* ERROR "expected '\)'" */ (){}) } } }`,
-	`package p; func f() (a b string /* ERROR "expected '\)'" */ , ok bool) // issue 8656`,
+	`package p; func f() { go func() { func() { f(x func /* ERROR "missing ','" */ (){}) } } }`,
+	`package p; func f(x func(), u v func /* ERROR "missing ','" */ ()){}`,
+	`package p; func f() (a b string /* ERROR "missing ','" */ , ok bool)`,           // issue 8656
+	`package p; var x /* ERROR "missing variable type or initialization" */ , y, z;`, // issue 9639
+	`package p; const x /* ERROR "missing constant value" */ ;`,                      // issue 9639
+	`package p; const x /* ERROR "missing constant value" */ int;`,                   // issue 9639
+	`package p; const (x = 0; y; z /* ERROR "missing constant value" */ int);`,       // issue 9639
 }
 
 func TestInvalid(t *testing.T) {
diff --git a/third_party/gofrontend/libgo/go/go/parser/testdata/issue3106.src b/third_party/gofrontend/libgo/go/go/parser/testdata/issue3106.src
index 82796c8..2db10be 100644
--- a/third_party/gofrontend/libgo/go/go/parser/testdata/issue3106.src
+++ b/third_party/gofrontend/libgo/go/go/parser/testdata/issue3106.src
@@ -19,7 +19,7 @@
 				time.Sleep(1e8)
 				m.Lock()
 				defer
-				if /* ERROR "expected operand, found 'if'" */ percent == 100 {
+				if /* ERROR "expected ';', found 'if'" */ percent == 100 {
 					m.Unlock()
 					break
 				}
diff --git a/third_party/gofrontend/libgo/go/go/printer/nodes.go b/third_party/gofrontend/libgo/go/go/printer/nodes.go
index d5a6934..fe04705 100644
--- a/third_party/gofrontend/libgo/go/go/printer/nodes.go
+++ b/third_party/gofrontend/libgo/go/go/printer/nodes.go
@@ -12,6 +12,9 @@
 	"bytes"
 	"go/ast"
 	"go/token"
+	"strconv"
+	"strings"
+	"unicode"
 	"unicode/utf8"
 )
 
@@ -1334,6 +1337,49 @@
 	}
 }
 
+func sanitizeImportPath(lit *ast.BasicLit) *ast.BasicLit {
+	// Note: An unmodified AST generated by go/parser will already
+	// contain a backward- or double-quoted path string that does
+	// not contain any invalid characters, and most of the work
+	// here is not needed. However, a modified or generated AST
+	// may possibly contain non-canonical paths. Do the work in
+	// all cases since it's not too hard and not speed-critical.
+
+	// if we don't have a proper string, be conservative and return whatever we have
+	if lit.Kind != token.STRING {
+		return lit
+	}
+	s, err := strconv.Unquote(lit.Value)
+	if err != nil {
+		return lit
+	}
+
+	// if the string is an invalid path, return whatever we have
+	//
+	// spec: "Implementation restriction: A compiler may restrict
+	// ImportPaths to non-empty strings using only characters belonging
+	// to Unicode's L, M, N, P, and S general categories (the Graphic
+	// characters without spaces) and may also exclude the characters
+	// !"#$%&'()*,:;<=>?[\]^`{|} and the Unicode replacement character
+	// U+FFFD."
+	if s == "" {
+		return lit
+	}
+	const illegalChars = `!"#$%&'()*,:;<=>?[\]^{|}` + "`\uFFFD"
+	for _, r := range s {
+		if !unicode.IsGraphic(r) || unicode.IsSpace(r) || strings.ContainsRune(illegalChars, r) {
+			return lit
+		}
+	}
+
+	// otherwise, return the double-quoted path
+	s = strconv.Quote(s)
+	if s == lit.Value {
+		return lit // nothing wrong with lit
+	}
+	return &ast.BasicLit{ValuePos: lit.ValuePos, Kind: token.STRING, Value: s}
+}
+
 // The parameter n is the number of specs in the group. If doIndent is set,
 // multi-line identifier lists in the spec are indented when the first
 // linebreak is encountered.
@@ -1346,7 +1392,7 @@
 			p.expr(s.Name)
 			p.print(blank)
 		}
-		p.expr(s.Path)
+		p.expr(sanitizeImportPath(s.Path))
 		p.setComment(s.Comment)
 		p.print(s.EndPos)
 
diff --git a/third_party/gofrontend/libgo/go/go/printer/printer.go b/third_party/gofrontend/libgo/go/go/printer/printer.go
index 280c697..f9343d3 100644
--- a/third_party/gofrontend/libgo/go/go/printer/printer.go
+++ b/third_party/gofrontend/libgo/go/go/printer/printer.go
@@ -144,7 +144,7 @@
 	p.commentOffset = infinity
 }
 
-// commentBefore returns true iff the current comment group occurs
+// commentBefore reports whether the current comment group occurs
 // before the next position in the source code and printing it does
 // not introduce implicit semicolons.
 //
@@ -496,29 +496,33 @@
 	// Compute maximum common white prefix of all but the first,
 	// last, and blank lines, and replace blank lines with empty
 	// lines (the first line starts with /* and has no prefix).
-	// In case of two-line comments, consider the last line for
-	// the prefix computation since otherwise the prefix would
-	// be empty.
+	// In cases where only the first and last lines are not blank,
+	// such as two-line comments, or comments where all inner lines
+	// are blank, consider the last line for the prefix computation
+	// since otherwise the prefix would be empty.
 	//
 	// Note that the first and last line are never empty (they
 	// contain the opening /* and closing */ respectively) and
 	// thus they can be ignored by the blank line check.
-	var prefix string
+	prefix := ""
+	prefixSet := false
 	if len(lines) > 2 {
-		first := true
 		for i, line := range lines[1 : len(lines)-1] {
-			switch {
-			case isBlank(line):
+			if isBlank(line) {
 				lines[1+i] = "" // range starts with lines[1]
-			case first:
-				prefix = commonPrefix(line, line)
-				first = false
-			default:
+			} else {
+				if !prefixSet {
+					prefix = line
+					prefixSet = true
+				}
 				prefix = commonPrefix(prefix, line)
 			}
+
 		}
-	} else { // len(lines) == 2, lines cannot be blank (contain /* and */)
-		line := lines[1]
+	}
+	// If we don't have a prefix yet, consider the last line.
+	if !prefixSet {
+		line := lines[len(lines)-1]
 		prefix = commonPrefix(line, line)
 	}
 
diff --git a/third_party/gofrontend/libgo/go/go/printer/testdata/comments.golden b/third_party/gofrontend/libgo/go/go/printer/testdata/comments.golden
index b1af795..849fa62 100644
--- a/third_party/gofrontend/libgo/go/go/printer/testdata/comments.golden
+++ b/third_party/gofrontend/libgo/go/go/printer/testdata/comments.golden
@@ -413,6 +413,68 @@
 		aligned line */
 }
 
+// Issue 9751.
+func _() {
+	/*a string
+
+	b string*/
+
+	/*A string
+
+
+
+	Z string*/
+
+	/*a string
+
+	b string
+
+	c string*/
+
+	{
+		/*a string
+		b string*/
+
+		/*a string
+
+		b string*/
+
+		/*a string
+
+		b string
+
+		c string*/
+	}
+
+	{
+		/*a string
+		b string*/
+
+		/*a string
+
+		b string*/
+
+		/*a string
+
+		b string
+
+		c string*/
+	}
+
+	/*
+	 */
+
+	/*
+
+	 */
+
+	/*
+
+	 * line
+
+	 */
+}
+
 /*
  * line
  * of
diff --git a/third_party/gofrontend/libgo/go/go/printer/testdata/comments.input b/third_party/gofrontend/libgo/go/go/printer/testdata/comments.input
index 983e2b2..30cd23c 100644
--- a/third_party/gofrontend/libgo/go/go/printer/testdata/comments.input
+++ b/third_party/gofrontend/libgo/go/go/printer/testdata/comments.input
@@ -418,6 +418,68 @@
 		aligned line */
 }
 
+// Issue 9751.
+func _() {
+	/*a string
+
+	b string*/
+
+	/*A string
+
+
+
+	Z string*/
+
+	/*a string
+
+	b string
+
+	c string*/
+
+	{
+		/*a string
+b string*/
+
+		/*a string
+
+b string*/
+
+		/*a string
+
+b string
+
+c string*/
+	}
+
+	{
+		/*a string
+				b string*/
+
+		/*a string
+
+				b string*/
+
+		/*a string
+
+				b string
+
+				c string*/
+	}
+
+	/*
+	*/
+
+	/*
+
+	*/
+
+	/*
+
+	 * line
+
+	*/
+}
+
 /*
  * line
  * of
diff --git a/third_party/gofrontend/libgo/go/go/printer/testdata/declarations.golden b/third_party/gofrontend/libgo/go/go/printer/testdata/declarations.golden
index 9acd41b..82f5e0f 100644
--- a/third_party/gofrontend/libgo/go/go/printer/testdata/declarations.golden
+++ b/third_party/gofrontend/libgo/go/go/printer/testdata/declarations.golden
@@ -110,6 +110,15 @@
 	"package_dddd"	// comment
 )
 
+// print import paths as double-quoted strings
+// (we would like more test cases but the go/parser
+// already excludes most incorrect paths, and we don't
+// bother setting up test-ASTs manually)
+import (
+	"fmt"
+	"math"
+)
+
 // at least one empty line between declarations of different kind
 import _ "io"
 
diff --git a/third_party/gofrontend/libgo/go/go/printer/testdata/declarations.input b/third_party/gofrontend/libgo/go/go/printer/testdata/declarations.input
index 45beec2..a0a3783 100644
--- a/third_party/gofrontend/libgo/go/go/printer/testdata/declarations.input
+++ b/third_party/gofrontend/libgo/go/go/printer/testdata/declarations.input
@@ -111,6 +111,15 @@
 	"package_dddd" // comment
 )
 
+// print import paths as double-quoted strings
+// (we would like more test cases but the go/parser
+// already excludes most incorrect paths, and we don't
+// bother setting up test-ASTs manually)
+import (
+	`fmt`
+	"math"
+)
+
 // at least one empty line between declarations of different kind
 import _ "io"
 var _ int
diff --git a/third_party/gofrontend/libgo/go/go/printer/testdata/parser.go b/third_party/gofrontend/libgo/go/go/printer/testdata/parser.go
index dba8bbd..44dfa19 100644
--- a/third_party/gofrontend/libgo/go/go/printer/testdata/parser.go
+++ b/third_party/gofrontend/libgo/go/go/printer/testdata/parser.go
@@ -1165,7 +1165,7 @@
 	return x
 }
 
-// isTypeName returns true iff x is a (qualified) TypeName.
+// isTypeName reports whether x is a (qualified) TypeName.
 func isTypeName(x ast.Expr) bool {
 	switch t := x.(type) {
 	case *ast.BadExpr:
@@ -1179,7 +1179,7 @@
 	return true
 }
 
-// isLiteralType returns true iff x is a legal composite literal type.
+// isLiteralType reports whether x is a legal composite literal type.
 func isLiteralType(x ast.Expr) bool {
 	switch t := x.(type) {
 	case *ast.BadExpr:
diff --git a/third_party/gofrontend/libgo/go/go/scanner/errors.go b/third_party/gofrontend/libgo/go/go/scanner/errors.go
index 22de69c..bf7bfa3 100644
--- a/third_party/gofrontend/libgo/go/go/scanner/errors.go
+++ b/third_party/gofrontend/libgo/go/go/scanner/errors.go
@@ -54,18 +54,16 @@
 	// Note that it is not sufficient to simply compare file offsets because
 	// the offsets do not reflect modified line information (through //line
 	// comments).
-	if e.Filename < f.Filename {
-		return true
+	if e.Filename != f.Filename {
+		return e.Filename < f.Filename
 	}
-	if e.Filename == f.Filename {
-		if e.Line < f.Line {
-			return true
-		}
-		if e.Line == f.Line {
-			return e.Column < f.Column
-		}
+	if e.Line != f.Line {
+		return e.Line < f.Line
 	}
-	return false
+	if e.Column != f.Column {
+		return e.Column < f.Column
+	}
+	return p[i].Msg < p[j].Msg
 }
 
 // Sort sorts an ErrorList. *Error entries are sorted by position,
diff --git a/third_party/gofrontend/libgo/go/go/scanner/scanner.go b/third_party/gofrontend/libgo/go/go/scanner/scanner.go
index cec82ea..e9476c4 100644
--- a/third_party/gofrontend/libgo/go/go/scanner/scanner.go
+++ b/third_party/gofrontend/libgo/go/go/scanner/scanner.go
@@ -706,13 +706,14 @@
 					s.insertSemi = false // newline consumed
 					return pos, token.SEMICOLON, "\n"
 				}
-				lit = s.scanComment()
+				comment := s.scanComment()
 				if s.mode&ScanComments == 0 {
 					// skip comment
 					s.insertSemi = false // newline consumed
 					goto scanAgain
 				}
 				tok = token.COMMENT
+				lit = comment
 			} else {
 				tok = s.switch2(token.QUO, token.QUO_ASSIGN)
 			}
diff --git a/third_party/gofrontend/libgo/go/go/scanner/scanner_test.go b/third_party/gofrontend/libgo/go/go/scanner/scanner_test.go
index fc450d8..0d21905 100644
--- a/third_party/gofrontend/libgo/go/go/scanner/scanner_test.go
+++ b/third_party/gofrontend/libgo/go/go/scanner/scanner_test.go
@@ -734,6 +734,41 @@
 	}
 }
 
+// Verify that no comments show up as literal values when skipping comments.
+func TestIssue10213(t *testing.T) {
+	var src = `
+		var (
+			A = 1 // foo
+		)
+
+		var (
+			B = 2
+			// foo
+		)
+
+		var C = 3 // foo
+
+		var D = 4
+		// foo
+
+		func anycode() {
+		// foo
+		}
+	`
+	var s Scanner
+	s.Init(fset.AddFile("", fset.Base(), len(src)), []byte(src), nil, 0)
+	for {
+		pos, tok, lit := s.Scan()
+		class := tokenclass(tok)
+		if lit != "" && class != keyword && class != literal && tok != token.SEMICOLON {
+			t.Errorf("%s: tok = %s, lit = %q", fset.Position(pos), tok, lit)
+		}
+		if tok <= token.EOF {
+			break
+		}
+	}
+}
+
 func BenchmarkScan(b *testing.B) {
 	b.StopTimer()
 	fset := token.NewFileSet()
diff --git a/third_party/gofrontend/libgo/go/go/token/position.go b/third_party/gofrontend/libgo/go/go/token/position.go
index 82d90ee..3375177 100644
--- a/third_party/gofrontend/libgo/go/go/token/position.go
+++ b/third_party/gofrontend/libgo/go/go/token/position.go
@@ -21,10 +21,10 @@
 	Filename string // filename, if any
 	Offset   int    // offset, starting at 0
 	Line     int    // line number, starting at 1
-	Column   int    // column number, starting at 1 (character count)
+	Column   int    // column number, starting at 1 (byte count)
 }
 
-// IsValid returns true if the position is valid.
+// IsValid reports whether the position is valid.
 func (pos *Position) IsValid() bool { return pos.Line > 0 }
 
 // String returns a string in one of several forms:
@@ -56,8 +56,8 @@
 // where base and size are specified when adding the file to the file set via
 // AddFile.
 //
-// To create the Pos value for a specific source offset, first add
-// the respective file to the current file set (via FileSet.AddFile)
+// To create the Pos value for a specific source offset (measured in bytes),
+// first add the respective file to the current file set using FileSet.AddFile
 // and then call File.Pos(offset) for that file. Given a Pos value p
 // for a specific file set fset, the corresponding Position value is
 // obtained by calling fset.Position(p).
@@ -77,7 +77,7 @@
 //
 const NoPos Pos = 0
 
-// IsValid returns true if the position is valid.
+// IsValid reports whether the position is valid.
 func (p Pos) IsValid() bool {
 	return p != NoPos
 }
@@ -157,7 +157,7 @@
 	f.lines = f.lines[:len(f.lines)-1]
 }
 
-// SetLines sets the line offsets for a file and returns true if successful.
+// SetLines sets the line offsets for a file and reports whether it succeeded.
 // The line offsets are the offsets of the first character of each line;
 // for instance for the content "ab\nc\n" the line offsets are {0, 3}.
 // An empty file has an empty line offset table.
diff --git a/third_party/gofrontend/libgo/go/go/types/api.go b/third_party/gofrontend/libgo/go/go/types/api.go
new file mode 100644
index 0000000..b3bf6f0
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/go/types/api.go
@@ -0,0 +1,336 @@
+// Copyright 2012 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 types declares the data types and implements
+// the algorithms for type-checking of Go packages. Use
+// Config.Check to invoke the type checker for a package.
+// Alternatively, create a new type checked with NewChecker
+// and invoke it incrementally by calling Checker.Files.
+//
+// Type-checking consists of several interdependent phases:
+//
+// Name resolution maps each identifier (ast.Ident) in the program to the
+// language object (Object) it denotes.
+// Use Info.{Defs,Uses,Implicits} for the results of name resolution.
+//
+// Constant folding computes the exact constant value (constant.Value)
+// for every expression (ast.Expr) that is a compile-time constant.
+// Use Info.Types[expr].Value for the results of constant folding.
+//
+// Type inference computes the type (Type) of every expression (ast.Expr)
+// and checks for compliance with the language specification.
+// Use Info.Types[expr].Type for the results of type inference.
+//
+package types // import "go/types"
+
+import (
+	"bytes"
+	"fmt"
+	"go/ast"
+	"go/constant"
+	"go/token"
+)
+
+// An Error describes a type-checking error; it implements the error interface.
+// A "soft" error is an error that still permits a valid interpretation of a
+// package (such as "unused variable"); "hard" errors may lead to unpredictable
+// behavior if ignored.
+type Error struct {
+	Fset *token.FileSet // file set for interpretation of Pos
+	Pos  token.Pos      // error position
+	Msg  string         // error message
+	Soft bool           // if set, error is "soft"
+}
+
+// Error returns an error string formatted as follows:
+// filename:line:column: message
+func (err Error) Error() string {
+	return fmt.Sprintf("%s: %s", err.Fset.Position(err.Pos), err.Msg)
+}
+
+// An importer resolves import paths to Packages.
+// See go/importer for existing implementations.
+type Importer interface {
+	// Import returns the imported package for the given import
+	// path, or an error if the package couldn't be imported.
+	// Import is responsible for returning the same package for
+	// matching import paths.
+	Import(path string) (*Package, error)
+}
+
+// A Config specifies the configuration for type checking.
+// The zero value for Config is a ready-to-use default configuration.
+type Config struct {
+	// If IgnoreFuncBodies is set, function bodies are not
+	// type-checked.
+	IgnoreFuncBodies bool
+
+	// If FakeImportC is set, `import "C"` (for packages requiring Cgo)
+	// declares an empty "C" package and errors are omitted for qualified
+	// identifiers referring to package C (which won't find an object).
+	// This feature is intended for the standard library cmd/api tool.
+	//
+	// Caution: Effects may be unpredictable due to follow-up errors.
+	//          Do not use casually!
+	FakeImportC bool
+
+	// If Error != nil, it is called with each error found
+	// during type checking; err has dynamic type Error.
+	// Secondary errors (for instance, to enumerate all types
+	// involved in an invalid recursive type declaration) have
+	// error strings that start with a '\t' character.
+	// If Error == nil, type-checking stops with the first
+	// error found.
+	Error func(err error)
+
+	// Importer is called for each import declaration except when
+	// importing package "unsafe". An error is reported if an
+	// importer is needed but none was installed.
+	Importer Importer
+
+	// If Sizes != nil, it provides the sizing functions for package unsafe.
+	// Otherwise &StdSizes{WordSize: 8, MaxAlign: 8} is used instead.
+	Sizes Sizes
+
+	// If DisableUnusedImportCheck is set, packages are not checked
+	// for unused imports.
+	DisableUnusedImportCheck bool
+}
+
+// Info holds result type information for a type-checked package.
+// Only the information for which a map is provided is collected.
+// If the package has type errors, the collected information may
+// be incomplete.
+type Info struct {
+	// Types maps expressions to their types, and for constant
+	// expressions, their values. Invalid expressions are omitted.
+	//
+	// For (possibly parenthesized) identifiers denoting built-in
+	// functions, the recorded signatures are call-site specific:
+	// if the call result is not a constant, the recorded type is
+	// an argument-specific signature. Otherwise, the recorded type
+	// is invalid.
+	//
+	// Identifiers on the lhs of declarations (i.e., the identifiers
+	// which are being declared) are collected in the Defs map.
+	// Identifiers denoting packages are collected in the Uses maps.
+	Types map[ast.Expr]TypeAndValue
+
+	// Defs maps identifiers to the objects they define (including
+	// package names, dots "." of dot-imports, and blank "_" identifiers).
+	// For identifiers that do not denote objects (e.g., the package name
+	// in package clauses, or symbolic variables t in t := x.(type) of
+	// type switch headers), the corresponding objects are nil.
+	//
+	// For an anonymous field, Defs returns the field *Var it defines.
+	//
+	// Invariant: Defs[id] == nil || Defs[id].Pos() == id.Pos()
+	Defs map[*ast.Ident]Object
+
+	// Uses maps identifiers to the objects they denote.
+	//
+	// For an anonymous field, Uses returns the *TypeName it denotes.
+	//
+	// Invariant: Uses[id].Pos() != id.Pos()
+	Uses map[*ast.Ident]Object
+
+	// Implicits maps nodes to their implicitly declared objects, if any.
+	// The following node and object types may appear:
+	//
+	//	node               declared object
+	//
+	//	*ast.ImportSpec    *PkgName for dot-imports and imports without renames
+	//	*ast.CaseClause    type-specific *Var for each type switch case clause (incl. default)
+	//      *ast.Field         anonymous struct field or parameter *Var
+	//
+	Implicits map[ast.Node]Object
+
+	// Selections maps selector expressions (excluding qualified identifiers)
+	// to their corresponding selections.
+	Selections map[*ast.SelectorExpr]*Selection
+
+	// Scopes maps ast.Nodes to the scopes they define. Package scopes are not
+	// associated with a specific node but with all files belonging to a package.
+	// Thus, the package scope can be found in the type-checked Package object.
+	// Scopes nest, with the Universe scope being the outermost scope, enclosing
+	// the package scope, which contains (one or more) files scopes, which enclose
+	// function scopes which in turn enclose statement and function literal scopes.
+	// Note that even though package-level functions are declared in the package
+	// scope, the function scopes are embedded in the file scope of the file
+	// containing the function declaration.
+	//
+	// The following node types may appear in Scopes:
+	//
+	//	*ast.File
+	//	*ast.FuncType
+	//	*ast.BlockStmt
+	//	*ast.IfStmt
+	//	*ast.SwitchStmt
+	//	*ast.TypeSwitchStmt
+	//	*ast.CaseClause
+	//	*ast.CommClause
+	//	*ast.ForStmt
+	//	*ast.RangeStmt
+	//
+	Scopes map[ast.Node]*Scope
+
+	// InitOrder is the list of package-level initializers in the order in which
+	// they must be executed. Initializers referring to variables related by an
+	// initialization dependency appear in topological order, the others appear
+	// in source order. Variables without an initialization expression do not
+	// appear in this list.
+	InitOrder []*Initializer
+}
+
+// TypeOf returns the type of expression e, or nil if not found.
+// Precondition: the Types, Uses and Defs maps are populated.
+//
+func (info *Info) TypeOf(e ast.Expr) Type {
+	if t, ok := info.Types[e]; ok {
+		return t.Type
+	}
+	if id, _ := e.(*ast.Ident); id != nil {
+		if obj := info.ObjectOf(id); obj != nil {
+			return obj.Type()
+		}
+	}
+	return nil
+}
+
+// ObjectOf returns the object denoted by the specified id,
+// or nil if not found.
+//
+// If id is an anonymous struct field, ObjectOf returns the field (*Var)
+// it uses, not the type (*TypeName) it defines.
+//
+// Precondition: the Uses and Defs maps are populated.
+//
+func (info *Info) ObjectOf(id *ast.Ident) Object {
+	if obj, _ := info.Defs[id]; obj != nil {
+		return obj
+	}
+	return info.Uses[id]
+}
+
+// TypeAndValue reports the type and value (for constants)
+// of the corresponding expression.
+type TypeAndValue struct {
+	mode  operandMode
+	Type  Type
+	Value constant.Value
+}
+
+// TODO(gri) Consider eliminating the IsVoid predicate. Instead, report
+// "void" values as regular values but with the empty tuple type.
+
+// IsVoid reports whether the corresponding expression
+// is a function call without results.
+func (tv TypeAndValue) IsVoid() bool {
+	return tv.mode == novalue
+}
+
+// IsType reports whether the corresponding expression specifies a type.
+func (tv TypeAndValue) IsType() bool {
+	return tv.mode == typexpr
+}
+
+// IsBuiltin reports whether the corresponding expression denotes
+// a (possibly parenthesized) built-in function.
+func (tv TypeAndValue) IsBuiltin() bool {
+	return tv.mode == builtin
+}
+
+// IsValue reports whether the corresponding expression is a value.
+// Builtins are not considered values. Constant values have a non-
+// nil Value.
+func (tv TypeAndValue) IsValue() bool {
+	switch tv.mode {
+	case constant_, variable, mapindex, value, commaok:
+		return true
+	}
+	return false
+}
+
+// IsNil reports whether the corresponding expression denotes the
+// predeclared value nil.
+func (tv TypeAndValue) IsNil() bool {
+	return tv.mode == value && tv.Type == Typ[UntypedNil]
+}
+
+// Addressable reports whether the corresponding expression
+// is addressable (https://golang.org/ref/spec#Address_operators).
+func (tv TypeAndValue) Addressable() bool {
+	return tv.mode == variable
+}
+
+// Assignable reports whether the corresponding expression
+// is assignable to (provided a value of the right type).
+func (tv TypeAndValue) Assignable() bool {
+	return tv.mode == variable || tv.mode == mapindex
+}
+
+// HasOk reports whether the corresponding expression may be
+// used on the lhs of a comma-ok assignment.
+func (tv TypeAndValue) HasOk() bool {
+	return tv.mode == commaok || tv.mode == mapindex
+}
+
+// An Initializer describes a package-level variable, or a list of variables in case
+// of a multi-valued initialization expression, and the corresponding initialization
+// expression.
+type Initializer struct {
+	Lhs []*Var // var Lhs = Rhs
+	Rhs ast.Expr
+}
+
+func (init *Initializer) String() string {
+	var buf bytes.Buffer
+	for i, lhs := range init.Lhs {
+		if i > 0 {
+			buf.WriteString(", ")
+		}
+		buf.WriteString(lhs.Name())
+	}
+	buf.WriteString(" = ")
+	WriteExpr(&buf, init.Rhs)
+	return buf.String()
+}
+
+// Check type-checks a package and returns the resulting package object,
+// the first error if any, and if info != nil, additional type information.
+// The package is marked as complete if no errors occurred, otherwise it is
+// incomplete. See Config.Error for controlling behavior in the presence of
+// errors.
+//
+// The package is specified by a list of *ast.Files and corresponding
+// file set, and the package path the package is identified with.
+// The clean path must not be empty or dot (".").
+func (conf *Config) Check(path string, fset *token.FileSet, files []*ast.File, info *Info) (*Package, error) {
+	pkg := NewPackage(path, "")
+	return pkg, NewChecker(conf, fset, pkg, info).Files(files)
+}
+
+// AssertableTo reports whether a value of type V can be asserted to have type T.
+func AssertableTo(V *Interface, T Type) bool {
+	m, _ := assertableTo(V, T)
+	return m == nil
+}
+
+// AssignableTo reports whether a value of type V is assignable to a variable of type T.
+func AssignableTo(V, T Type) bool {
+	x := operand{mode: value, typ: V}
+	return x.assignableTo(nil, T) // config not needed for non-constant x
+}
+
+// ConvertibleTo reports whether a value of type V is convertible to a value of type T.
+func ConvertibleTo(V, T Type) bool {
+	x := operand{mode: value, typ: V}
+	return x.convertibleTo(nil, T) // config not needed for non-constant x
+}
+
+// Implements reports whether type V implements interface T.
+func Implements(V Type, T *Interface) bool {
+	f, _ := MissingMethod(V, T, true)
+	return f == nil
+}
diff --git a/third_party/gofrontend/libgo/go/go/types/api_test.go b/third_party/gofrontend/libgo/go/go/types/api_test.go
new file mode 100644
index 0000000..eeda0d8
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/go/types/api_test.go
@@ -0,0 +1,1044 @@
+// Copyright 2013 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 types_test
+
+import (
+	"bytes"
+	"fmt"
+	"go/ast"
+	"go/importer"
+	"go/parser"
+	"go/token"
+	"internal/testenv"
+	"reflect"
+	"regexp"
+	"strings"
+	"testing"
+
+	. "go/types"
+)
+
+func pkgFor(path, source string, info *Info) (*Package, error) {
+	fset := token.NewFileSet()
+	f, err := parser.ParseFile(fset, path, source, 0)
+	if err != nil {
+		return nil, err
+	}
+
+	conf := Config{Importer: importer.Default()}
+	return conf.Check(f.Name.Name, fset, []*ast.File{f}, info)
+}
+
+func mustTypecheck(t *testing.T, path, source string, info *Info) string {
+	pkg, err := pkgFor(path, source, info)
+	if err != nil {
+		name := path
+		if pkg != nil {
+			name = "package " + pkg.Name()
+		}
+		t.Fatalf("%s: didn't type-check (%s)", name, err)
+	}
+	return pkg.Name()
+}
+
+func TestValuesInfo(t *testing.T) {
+	var tests = []struct {
+		src  string
+		expr string // constant expression
+		typ  string // constant type
+		val  string // constant value
+	}{
+		{`package a0; const _ = false`, `false`, `untyped bool`, `false`},
+		{`package a1; const _ = 0`, `0`, `untyped int`, `0`},
+		{`package a2; const _ = 'A'`, `'A'`, `untyped rune`, `65`},
+		{`package a3; const _ = 0.`, `0.`, `untyped float`, `0`},
+		{`package a4; const _ = 0i`, `0i`, `untyped complex`, `0`},
+		{`package a5; const _ = "foo"`, `"foo"`, `untyped string`, `"foo"`},
+
+		{`package b0; var _ = false`, `false`, `bool`, `false`},
+		{`package b1; var _ = 0`, `0`, `int`, `0`},
+		{`package b2; var _ = 'A'`, `'A'`, `rune`, `65`},
+		{`package b3; var _ = 0.`, `0.`, `float64`, `0`},
+		{`package b4; var _ = 0i`, `0i`, `complex128`, `0`},
+		{`package b5; var _ = "foo"`, `"foo"`, `string`, `"foo"`},
+
+		{`package c0a; var _ = bool(false)`, `false`, `bool`, `false`},
+		{`package c0b; var _ = bool(false)`, `bool(false)`, `bool`, `false`},
+		{`package c0c; type T bool; var _ = T(false)`, `T(false)`, `c0c.T`, `false`},
+
+		{`package c1a; var _ = int(0)`, `0`, `int`, `0`},
+		{`package c1b; var _ = int(0)`, `int(0)`, `int`, `0`},
+		{`package c1c; type T int; var _ = T(0)`, `T(0)`, `c1c.T`, `0`},
+
+		{`package c2a; var _ = rune('A')`, `'A'`, `rune`, `65`},
+		{`package c2b; var _ = rune('A')`, `rune('A')`, `rune`, `65`},
+		{`package c2c; type T rune; var _ = T('A')`, `T('A')`, `c2c.T`, `65`},
+
+		{`package c3a; var _ = float32(0.)`, `0.`, `float32`, `0`},
+		{`package c3b; var _ = float32(0.)`, `float32(0.)`, `float32`, `0`},
+		{`package c3c; type T float32; var _ = T(0.)`, `T(0.)`, `c3c.T`, `0`},
+
+		{`package c4a; var _ = complex64(0i)`, `0i`, `complex64`, `0`},
+		{`package c4b; var _ = complex64(0i)`, `complex64(0i)`, `complex64`, `0`},
+		{`package c4c; type T complex64; var _ = T(0i)`, `T(0i)`, `c4c.T`, `0`},
+
+		{`package c5a; var _ = string("foo")`, `"foo"`, `string`, `"foo"`},
+		{`package c5b; var _ = string("foo")`, `string("foo")`, `string`, `"foo"`},
+		{`package c5c; type T string; var _ = T("foo")`, `T("foo")`, `c5c.T`, `"foo"`},
+
+		{`package d0; var _ = []byte("foo")`, `"foo"`, `string`, `"foo"`},
+		{`package d1; var _ = []byte(string("foo"))`, `"foo"`, `string`, `"foo"`},
+		{`package d2; var _ = []byte(string("foo"))`, `string("foo")`, `string`, `"foo"`},
+		{`package d3; type T []byte; var _ = T("foo")`, `"foo"`, `string`, `"foo"`},
+
+		{`package e0; const _ = float32( 1e-200)`, `float32(1e-200)`, `float32`, `0`},
+		{`package e1; const _ = float32(-1e-200)`, `float32(-1e-200)`, `float32`, `0`},
+		{`package e2; const _ = float64( 1e-2000)`, `float64(1e-2000)`, `float64`, `0`},
+		{`package e3; const _ = float64(-1e-2000)`, `float64(-1e-2000)`, `float64`, `0`},
+		{`package e4; const _ = complex64( 1e-200)`, `complex64(1e-200)`, `complex64`, `0`},
+		{`package e5; const _ = complex64(-1e-200)`, `complex64(-1e-200)`, `complex64`, `0`},
+		{`package e6; const _ = complex128( 1e-2000)`, `complex128(1e-2000)`, `complex128`, `0`},
+		{`package e7; const _ = complex128(-1e-2000)`, `complex128(-1e-2000)`, `complex128`, `0`},
+
+		{`package f0 ; var _ float32 =  1e-200`, `1e-200`, `float32`, `0`},
+		{`package f1 ; var _ float32 = -1e-200`, `-1e-200`, `float32`, `0`},
+		{`package f2a; var _ float64 =  1e-2000`, `1e-2000`, `float64`, `0`},
+		{`package f3a; var _ float64 = -1e-2000`, `-1e-2000`, `float64`, `0`},
+		{`package f2b; var _         =  1e-2000`, `1e-2000`, `float64`, `0`},
+		{`package f3b; var _         = -1e-2000`, `-1e-2000`, `float64`, `0`},
+		{`package f4 ; var _ complex64  =  1e-200 `, `1e-200`, `complex64`, `0`},
+		{`package f5 ; var _ complex64  = -1e-200 `, `-1e-200`, `complex64`, `0`},
+		{`package f6a; var _ complex128 =  1e-2000i`, `1e-2000i`, `complex128`, `0`},
+		{`package f7a; var _ complex128 = -1e-2000i`, `-1e-2000i`, `complex128`, `0`},
+		{`package f6b; var _            =  1e-2000i`, `1e-2000i`, `complex128`, `0`},
+		{`package f7b; var _            = -1e-2000i`, `-1e-2000i`, `complex128`, `0`},
+	}
+
+	for _, test := range tests {
+		info := Info{
+			Types: make(map[ast.Expr]TypeAndValue),
+		}
+		name := mustTypecheck(t, "ValuesInfo", test.src, &info)
+
+		// look for constant expression
+		var expr ast.Expr
+		for e := range info.Types {
+			if ExprString(e) == test.expr {
+				expr = e
+				break
+			}
+		}
+		if expr == nil {
+			t.Errorf("package %s: no expression found for %s", name, test.expr)
+			continue
+		}
+		tv := info.Types[expr]
+
+		// check that type is correct
+		if got := tv.Type.String(); got != test.typ {
+			t.Errorf("package %s: got type %s; want %s", name, got, test.typ)
+			continue
+		}
+
+		// check that value is correct
+		if got := tv.Value.String(); got != test.val {
+			t.Errorf("package %s: got value %s; want %s", name, got, test.val)
+		}
+	}
+}
+
+func TestTypesInfo(t *testing.T) {
+	var tests = []struct {
+		src  string
+		expr string // expression
+		typ  string // value type
+	}{
+		// single-valued expressions of untyped constants
+		{`package b0; var x interface{} = false`, `false`, `bool`},
+		{`package b1; var x interface{} = 0`, `0`, `int`},
+		{`package b2; var x interface{} = 0.`, `0.`, `float64`},
+		{`package b3; var x interface{} = 0i`, `0i`, `complex128`},
+		{`package b4; var x interface{} = "foo"`, `"foo"`, `string`},
+
+		// comma-ok expressions
+		{`package p0; var x interface{}; var _, _ = x.(int)`,
+			`x.(int)`,
+			`(int, bool)`,
+		},
+		{`package p1; var x interface{}; func _() { _, _ = x.(int) }`,
+			`x.(int)`,
+			`(int, bool)`,
+		},
+		// TODO(gri): uncomment if we accept issue 8189.
+		// {`package p2; type mybool bool; var m map[string]complex128; var b mybool; func _() { _, b = m["foo"] }`,
+		// 	`m["foo"]`,
+		// 	`(complex128, p2.mybool)`,
+		// },
+		// TODO(gri): remove if we accept issue 8189.
+		{`package p2; var m map[string]complex128; var b bool; func _() { _, b = m["foo"] }`,
+			`m["foo"]`,
+			`(complex128, bool)`,
+		},
+		{`package p3; var c chan string; var _, _ = <-c`,
+			`<-c`,
+			`(string, bool)`,
+		},
+
+		// issue 6796
+		{`package issue6796_a; var x interface{}; var _, _ = (x.(int))`,
+			`x.(int)`,
+			`(int, bool)`,
+		},
+		{`package issue6796_b; var c chan string; var _, _ = (<-c)`,
+			`(<-c)`,
+			`(string, bool)`,
+		},
+		{`package issue6796_c; var c chan string; var _, _ = (<-c)`,
+			`<-c`,
+			`(string, bool)`,
+		},
+		{`package issue6796_d; var c chan string; var _, _ = ((<-c))`,
+			`(<-c)`,
+			`(string, bool)`,
+		},
+		{`package issue6796_e; func f(c chan string) { _, _ = ((<-c)) }`,
+			`(<-c)`,
+			`(string, bool)`,
+		},
+
+		// issue 7060
+		{`package issue7060_a; var ( m map[int]string; x, ok = m[0] )`,
+			`m[0]`,
+			`(string, bool)`,
+		},
+		{`package issue7060_b; var ( m map[int]string; x, ok interface{} = m[0] )`,
+			`m[0]`,
+			`(string, bool)`,
+		},
+		{`package issue7060_c; func f(x interface{}, ok bool, m map[int]string) { x, ok = m[0] }`,
+			`m[0]`,
+			`(string, bool)`,
+		},
+		{`package issue7060_d; var ( ch chan string; x, ok = <-ch )`,
+			`<-ch`,
+			`(string, bool)`,
+		},
+		{`package issue7060_e; var ( ch chan string; x, ok interface{} = <-ch )`,
+			`<-ch`,
+			`(string, bool)`,
+		},
+		{`package issue7060_f; func f(x interface{}, ok bool, ch chan string) { x, ok = <-ch }`,
+			`<-ch`,
+			`(string, bool)`,
+		},
+	}
+
+	for _, test := range tests {
+		info := Info{Types: make(map[ast.Expr]TypeAndValue)}
+		name := mustTypecheck(t, "TypesInfo", test.src, &info)
+
+		// look for expression type
+		var typ Type
+		for e, tv := range info.Types {
+			if ExprString(e) == test.expr {
+				typ = tv.Type
+				break
+			}
+		}
+		if typ == nil {
+			t.Errorf("package %s: no type found for %s", name, test.expr)
+			continue
+		}
+
+		// check that type is correct
+		if got := typ.String(); got != test.typ {
+			t.Errorf("package %s: got %s; want %s", name, got, test.typ)
+		}
+	}
+}
+
+func predString(tv TypeAndValue) string {
+	var buf bytes.Buffer
+	pred := func(b bool, s string) {
+		if b {
+			if buf.Len() > 0 {
+				buf.WriteString(", ")
+			}
+			buf.WriteString(s)
+		}
+	}
+
+	pred(tv.IsVoid(), "void")
+	pred(tv.IsType(), "type")
+	pred(tv.IsBuiltin(), "builtin")
+	pred(tv.IsValue() && tv.Value != nil, "const")
+	pred(tv.IsValue() && tv.Value == nil, "value")
+	pred(tv.IsNil(), "nil")
+	pred(tv.Addressable(), "addressable")
+	pred(tv.Assignable(), "assignable")
+	pred(tv.HasOk(), "hasOk")
+
+	if buf.Len() == 0 {
+		return "invalid"
+	}
+	return buf.String()
+}
+
+func TestPredicatesInfo(t *testing.T) {
+	testenv.MustHaveGoBuild(t)
+
+	var tests = []struct {
+		src  string
+		expr string
+		pred string
+	}{
+		// void
+		{`package n0; func f() { f() }`, `f()`, `void`},
+
+		// types
+		{`package t0; type _ int`, `int`, `type`},
+		{`package t1; type _ []int`, `[]int`, `type`},
+		{`package t2; type _ func()`, `func()`, `type`},
+
+		// built-ins
+		{`package b0; var _ = len("")`, `len`, `builtin`},
+		{`package b1; var _ = (len)("")`, `(len)`, `builtin`},
+
+		// constants
+		{`package c0; var _ = 42`, `42`, `const`},
+		{`package c1; var _ = "foo" + "bar"`, `"foo" + "bar"`, `const`},
+		{`package c2; const (i = 1i; _ = i)`, `i`, `const`},
+
+		// values
+		{`package v0; var (a, b int; _ = a + b)`, `a + b`, `value`},
+		{`package v1; var _ = &[]int{1}`, `([]int literal)`, `value`},
+		{`package v2; var _ = func(){}`, `(func() literal)`, `value`},
+		{`package v4; func f() { _ = f }`, `f`, `value`},
+		{`package v3; var _ *int = nil`, `nil`, `value, nil`},
+		{`package v3; var _ *int = (nil)`, `(nil)`, `value, nil`},
+
+		// addressable (and thus assignable) operands
+		{`package a0; var (x int; _ = x)`, `x`, `value, addressable, assignable`},
+		{`package a1; var (p *int; _ = *p)`, `*p`, `value, addressable, assignable`},
+		{`package a2; var (s []int; _ = s[0])`, `s[0]`, `value, addressable, assignable`},
+		{`package a3; var (s struct{f int}; _ = s.f)`, `s.f`, `value, addressable, assignable`},
+		{`package a4; var (a [10]int; _ = a[0])`, `a[0]`, `value, addressable, assignable`},
+		{`package a5; func _(x int) { _ = x }`, `x`, `value, addressable, assignable`},
+		{`package a6; func _()(x int) { _ = x; return }`, `x`, `value, addressable, assignable`},
+		{`package a7; type T int; func (x T) _() { _ = x }`, `x`, `value, addressable, assignable`},
+		// composite literals are not addressable
+
+		// assignable but not addressable values
+		{`package s0; var (m map[int]int; _ = m[0])`, `m[0]`, `value, assignable, hasOk`},
+		{`package s1; var (m map[int]int; _, _ = m[0])`, `m[0]`, `value, assignable, hasOk`},
+
+		// hasOk expressions
+		{`package k0; var (ch chan int; _ = <-ch)`, `<-ch`, `value, hasOk`},
+		{`package k1; var (ch chan int; _, _ = <-ch)`, `<-ch`, `value, hasOk`},
+
+		// missing entries
+		// - package names are collected in the Uses map
+		// - identifiers being declared are collected in the Defs map
+		{`package m0; import "os"; func _() { _ = os.Stdout }`, `os`, `<missing>`},
+		{`package m1; import p "os"; func _() { _ = p.Stdout }`, `p`, `<missing>`},
+		{`package m2; const c = 0`, `c`, `<missing>`},
+		{`package m3; type T int`, `T`, `<missing>`},
+		{`package m4; var v int`, `v`, `<missing>`},
+		{`package m5; func f() {}`, `f`, `<missing>`},
+		{`package m6; func _(x int) {}`, `x`, `<missing>`},
+		{`package m6; func _()(x int) { return }`, `x`, `<missing>`},
+		{`package m6; type T int; func (x T) _() {}`, `x`, `<missing>`},
+	}
+
+	for _, test := range tests {
+		info := Info{Types: make(map[ast.Expr]TypeAndValue)}
+		name := mustTypecheck(t, "PredicatesInfo", test.src, &info)
+
+		// look for expression predicates
+		got := "<missing>"
+		for e, tv := range info.Types {
+			//println(name, ExprString(e))
+			if ExprString(e) == test.expr {
+				got = predString(tv)
+				break
+			}
+		}
+
+		if got != test.pred {
+			t.Errorf("package %s: got %s; want %s", name, got, test.pred)
+		}
+	}
+}
+
+func TestScopesInfo(t *testing.T) {
+	testenv.MustHaveGoBuild(t)
+
+	var tests = []struct {
+		src    string
+		scopes []string // list of scope descriptors of the form kind:varlist
+	}{
+		{`package p0`, []string{
+			"file:",
+		}},
+		{`package p1; import ( "fmt"; m "math"; _ "os" ); var ( _ = fmt.Println; _ = m.Pi )`, []string{
+			"file:fmt m",
+		}},
+		{`package p2; func _() {}`, []string{
+			"file:", "func:",
+		}},
+		{`package p3; func _(x, y int) {}`, []string{
+			"file:", "func:x y",
+		}},
+		{`package p4; func _(x, y int) { x, z := 1, 2; _ = z }`, []string{
+			"file:", "func:x y z", // redeclaration of x
+		}},
+		{`package p5; func _(x, y int) (u, _ int) { return }`, []string{
+			"file:", "func:u x y",
+		}},
+		{`package p6; func _() { { var x int; _ = x } }`, []string{
+			"file:", "func:", "block:x",
+		}},
+		{`package p7; func _() { if true {} }`, []string{
+			"file:", "func:", "if:", "block:",
+		}},
+		{`package p8; func _() { if x := 0; x < 0 { y := x; _ = y } }`, []string{
+			"file:", "func:", "if:x", "block:y",
+		}},
+		{`package p9; func _() { switch x := 0; x {} }`, []string{
+			"file:", "func:", "switch:x",
+		}},
+		{`package p10; func _() { switch x := 0; x { case 1: y := x; _ = y; default: }}`, []string{
+			"file:", "func:", "switch:x", "case:y", "case:",
+		}},
+		{`package p11; func _(t interface{}) { switch t.(type) {} }`, []string{
+			"file:", "func:t", "type switch:",
+		}},
+		{`package p12; func _(t interface{}) { switch t := t; t.(type) {} }`, []string{
+			"file:", "func:t", "type switch:t",
+		}},
+		{`package p13; func _(t interface{}) { switch x := t.(type) { case int: _ = x } }`, []string{
+			"file:", "func:t", "type switch:", "case:x", // x implicitly declared
+		}},
+		{`package p14; func _() { select{} }`, []string{
+			"file:", "func:",
+		}},
+		{`package p15; func _(c chan int) { select{ case <-c: } }`, []string{
+			"file:", "func:c", "comm:",
+		}},
+		{`package p16; func _(c chan int) { select{ case i := <-c: x := i; _ = x} }`, []string{
+			"file:", "func:c", "comm:i x",
+		}},
+		{`package p17; func _() { for{} }`, []string{
+			"file:", "func:", "for:", "block:",
+		}},
+		{`package p18; func _(n int) { for i := 0; i < n; i++ { _ = i } }`, []string{
+			"file:", "func:n", "for:i", "block:",
+		}},
+		{`package p19; func _(a []int) { for i := range a { _ = i} }`, []string{
+			"file:", "func:a", "range:i", "block:",
+		}},
+		{`package p20; var s int; func _(a []int) { for i, x := range a { s += x; _ = i } }`, []string{
+			"file:", "func:a", "range:i x", "block:",
+		}},
+	}
+
+	for _, test := range tests {
+		info := Info{Scopes: make(map[ast.Node]*Scope)}
+		name := mustTypecheck(t, "ScopesInfo", test.src, &info)
+
+		// number of scopes must match
+		if len(info.Scopes) != len(test.scopes) {
+			t.Errorf("package %s: got %d scopes; want %d", name, len(info.Scopes), len(test.scopes))
+		}
+
+		// scope descriptions must match
+		for node, scope := range info.Scopes {
+			kind := "<unknown node kind>"
+			switch node.(type) {
+			case *ast.File:
+				kind = "file"
+			case *ast.FuncType:
+				kind = "func"
+			case *ast.BlockStmt:
+				kind = "block"
+			case *ast.IfStmt:
+				kind = "if"
+			case *ast.SwitchStmt:
+				kind = "switch"
+			case *ast.TypeSwitchStmt:
+				kind = "type switch"
+			case *ast.CaseClause:
+				kind = "case"
+			case *ast.CommClause:
+				kind = "comm"
+			case *ast.ForStmt:
+				kind = "for"
+			case *ast.RangeStmt:
+				kind = "range"
+			}
+
+			// look for matching scope description
+			desc := kind + ":" + strings.Join(scope.Names(), " ")
+			found := false
+			for _, d := range test.scopes {
+				if desc == d {
+					found = true
+					break
+				}
+			}
+			if !found {
+				t.Errorf("package %s: no matching scope found for %s", name, desc)
+			}
+		}
+	}
+}
+
+func TestInitOrderInfo(t *testing.T) {
+	var tests = []struct {
+		src   string
+		inits []string
+	}{
+		{`package p0; var (x = 1; y = x)`, []string{
+			"x = 1", "y = x",
+		}},
+		{`package p1; var (a = 1; b = 2; c = 3)`, []string{
+			"a = 1", "b = 2", "c = 3",
+		}},
+		{`package p2; var (a, b, c = 1, 2, 3)`, []string{
+			"a = 1", "b = 2", "c = 3",
+		}},
+		{`package p3; var _ = f(); func f() int { return 1 }`, []string{
+			"_ = f()", // blank var
+		}},
+		{`package p4; var (a = 0; x = y; y = z; z = 0)`, []string{
+			"a = 0", "z = 0", "y = z", "x = y",
+		}},
+		{`package p5; var (a, _ = m[0]; m map[int]string)`, []string{
+			"a, _ = m[0]", // blank var
+		}},
+		{`package p6; var a, b = f(); func f() (_, _ int) { return z, z }; var z = 0`, []string{
+			"z = 0", "a, b = f()",
+		}},
+		{`package p7; var (a = func() int { return b }(); b = 1)`, []string{
+			"b = 1", "a = (func() int literal)()",
+		}},
+		{`package p8; var (a, b = func() (_, _ int) { return c, c }(); c = 1)`, []string{
+			"c = 1", "a, b = (func() (_, _ int) literal)()",
+		}},
+		{`package p9; type T struct{}; func (T) m() int { _ = y; return 0 }; var x, y = T.m, 1`, []string{
+			"y = 1", "x = T.m",
+		}},
+		{`package p10; var (d = c + b; a = 0; b = 0; c = 0)`, []string{
+			"a = 0", "b = 0", "c = 0", "d = c + b",
+		}},
+		{`package p11; var (a = e + c; b = d + c; c = 0; d = 0; e = 0)`, []string{
+			"c = 0", "d = 0", "b = d + c", "e = 0", "a = e + c",
+		}},
+		// emit an initializer for n:1 initializations only once (not for each node
+		// on the lhs which may appear in different order in the dependency graph)
+		{`package p12; var (a = x; b = 0; x, y = m[0]; m map[int]int)`, []string{
+			"b = 0", "x, y = m[0]", "a = x",
+		}},
+		// test case from spec section on package initialization
+		{`package p12
+
+		var (
+			a = c + b
+			b = f()
+			c = f()
+			d = 3
+		)
+
+		func f() int {
+			d++
+			return d
+		}`, []string{
+			"d = 3", "b = f()", "c = f()", "a = c + b",
+		}},
+		// test case for issue 7131
+		{`package main
+
+		var counter int
+		func next() int { counter++; return counter }
+
+		var _ = makeOrder()
+		func makeOrder() []int { return []int{f, b, d, e, c, a} }
+
+		var a       = next()
+		var b, c    = next(), next()
+		var d, e, f = next(), next(), next()
+		`, []string{
+			"a = next()", "b = next()", "c = next()", "d = next()", "e = next()", "f = next()", "_ = makeOrder()",
+		}},
+	}
+
+	for _, test := range tests {
+		info := Info{}
+		name := mustTypecheck(t, "InitOrderInfo", test.src, &info)
+
+		// number of initializers must match
+		if len(info.InitOrder) != len(test.inits) {
+			t.Errorf("package %s: got %d initializers; want %d", name, len(info.InitOrder), len(test.inits))
+			continue
+		}
+
+		// initializers must match
+		for i, want := range test.inits {
+			got := info.InitOrder[i].String()
+			if got != want {
+				t.Errorf("package %s, init %d: got %s; want %s", name, i, got, want)
+				continue
+			}
+		}
+	}
+}
+
+func TestMultiFileInitOrder(t *testing.T) {
+	fset := token.NewFileSet()
+	mustParse := func(src string) *ast.File {
+		f, err := parser.ParseFile(fset, "main", src, 0)
+		if err != nil {
+			t.Fatal(err)
+		}
+		return f
+	}
+
+	fileA := mustParse(`package main; var a = 1`)
+	fileB := mustParse(`package main; var b = 2`)
+
+	// The initialization order must not depend on the parse
+	// order of the files, only on the presentation order to
+	// the type-checker.
+	for _, test := range []struct {
+		files []*ast.File
+		want  string
+	}{
+		{[]*ast.File{fileA, fileB}, "[a = 1 b = 2]"},
+		{[]*ast.File{fileB, fileA}, "[b = 2 a = 1]"},
+	} {
+		var info Info
+		if _, err := new(Config).Check("main", fset, test.files, &info); err != nil {
+			t.Fatal(err)
+		}
+		if got := fmt.Sprint(info.InitOrder); got != test.want {
+			t.Fatalf("got %s; want %s", got, test.want)
+		}
+	}
+}
+
+func TestFiles(t *testing.T) {
+	var sources = []string{
+		"package p; type T struct{}; func (T) m1() {}",
+		"package p; func (T) m2() {}; var x interface{ m1(); m2() } = T{}",
+		"package p; func (T) m3() {}; var y interface{ m1(); m2(); m3() } = T{}",
+		"package p",
+	}
+
+	var conf Config
+	fset := token.NewFileSet()
+	pkg := NewPackage("p", "p")
+	var info Info
+	check := NewChecker(&conf, fset, pkg, &info)
+
+	for i, src := range sources {
+		filename := fmt.Sprintf("sources%d", i)
+		f, err := parser.ParseFile(fset, filename, src, 0)
+		if err != nil {
+			t.Fatal(err)
+		}
+		if err := check.Files([]*ast.File{f}); err != nil {
+			t.Error(err)
+		}
+	}
+
+	// check InitOrder is [x y]
+	var vars []string
+	for _, init := range info.InitOrder {
+		for _, v := range init.Lhs {
+			vars = append(vars, v.Name())
+		}
+	}
+	if got, want := fmt.Sprint(vars), "[x y]"; got != want {
+		t.Errorf("InitOrder == %s, want %s", got, want)
+	}
+}
+
+type testImporter map[string]*Package
+
+func (m testImporter) Import(path string) (*Package, error) {
+	if pkg := m[path]; pkg != nil {
+		return pkg, nil
+	}
+	return nil, fmt.Errorf("package %q not found", path)
+}
+
+func TestSelection(t *testing.T) {
+	selections := make(map[*ast.SelectorExpr]*Selection)
+
+	fset := token.NewFileSet()
+	imports := make(testImporter)
+	conf := Config{Importer: imports}
+	makePkg := func(path, src string) {
+		f, err := parser.ParseFile(fset, path+".go", src, 0)
+		if err != nil {
+			t.Fatal(err)
+		}
+		pkg, err := conf.Check(path, fset, []*ast.File{f}, &Info{Selections: selections})
+		if err != nil {
+			t.Fatal(err)
+		}
+		imports[path] = pkg
+	}
+
+	const libSrc = `
+package lib
+type T float64
+const C T = 3
+var V T
+func F() {}
+func (T) M() {}
+`
+	const mainSrc = `
+package main
+import "lib"
+
+type A struct {
+	*B
+	C
+}
+
+type B struct {
+	b int
+}
+
+func (B) f(int)
+
+type C struct {
+	c int
+}
+
+func (C) g()
+func (*C) h()
+
+func main() {
+	// qualified identifiers
+	var _ lib.T
+        _ = lib.C
+        _ = lib.F
+        _ = lib.V
+	_ = lib.T.M
+
+	// fields
+	_ = A{}.B
+	_ = new(A).B
+
+	_ = A{}.C
+	_ = new(A).C
+
+	_ = A{}.b
+	_ = new(A).b
+
+	_ = A{}.c
+	_ = new(A).c
+
+	// methods
+        _ = A{}.f
+        _ = new(A).f
+        _ = A{}.g
+        _ = new(A).g
+        _ = new(A).h
+
+        _ = B{}.f
+        _ = new(B).f
+
+        _ = C{}.g
+        _ = new(C).g
+        _ = new(C).h
+
+	// method expressions
+        _ = A.f
+        _ = (*A).f
+        _ = B.f
+        _ = (*B).f
+}`
+
+	wantOut := map[string][2]string{
+		"lib.T.M": {"method expr (lib.T) M(lib.T)", ".[0]"},
+
+		"A{}.B":    {"field (main.A) B *main.B", ".[0]"},
+		"new(A).B": {"field (*main.A) B *main.B", "->[0]"},
+		"A{}.C":    {"field (main.A) C main.C", ".[1]"},
+		"new(A).C": {"field (*main.A) C main.C", "->[1]"},
+		"A{}.b":    {"field (main.A) b int", "->[0 0]"},
+		"new(A).b": {"field (*main.A) b int", "->[0 0]"},
+		"A{}.c":    {"field (main.A) c int", ".[1 0]"},
+		"new(A).c": {"field (*main.A) c int", "->[1 0]"},
+
+		"A{}.f":    {"method (main.A) f(int)", "->[0 0]"},
+		"new(A).f": {"method (*main.A) f(int)", "->[0 0]"},
+		"A{}.g":    {"method (main.A) g()", ".[1 0]"},
+		"new(A).g": {"method (*main.A) g()", "->[1 0]"},
+		"new(A).h": {"method (*main.A) h()", "->[1 1]"}, // TODO(gri) should this report .[1 1] ?
+		"B{}.f":    {"method (main.B) f(int)", ".[0]"},
+		"new(B).f": {"method (*main.B) f(int)", "->[0]"},
+		"C{}.g":    {"method (main.C) g()", ".[0]"},
+		"new(C).g": {"method (*main.C) g()", "->[0]"},
+		"new(C).h": {"method (*main.C) h()", "->[1]"}, // TODO(gri) should this report .[1] ?
+
+		"A.f":    {"method expr (main.A) f(main.A, int)", "->[0 0]"},
+		"(*A).f": {"method expr (*main.A) f(*main.A, int)", "->[0 0]"},
+		"B.f":    {"method expr (main.B) f(main.B, int)", ".[0]"},
+		"(*B).f": {"method expr (*main.B) f(*main.B, int)", "->[0]"},
+	}
+
+	makePkg("lib", libSrc)
+	makePkg("main", mainSrc)
+
+	for e, sel := range selections {
+		sel.String() // assertion: must not panic
+
+		start := fset.Position(e.Pos()).Offset
+		end := fset.Position(e.End()).Offset
+		syntax := mainSrc[start:end] // (all SelectorExprs are in main, not lib)
+
+		direct := "."
+		if sel.Indirect() {
+			direct = "->"
+		}
+		got := [2]string{
+			sel.String(),
+			fmt.Sprintf("%s%v", direct, sel.Index()),
+		}
+		want := wantOut[syntax]
+		if want != got {
+			t.Errorf("%s: got %q; want %q", syntax, got, want)
+		}
+		delete(wantOut, syntax)
+
+		// We must explicitly assert properties of the
+		// Signature's receiver since it doesn't participate
+		// in Identical() or String().
+		sig, _ := sel.Type().(*Signature)
+		if sel.Kind() == MethodVal {
+			got := sig.Recv().Type()
+			want := sel.Recv()
+			if !Identical(got, want) {
+				t.Errorf("%s: Recv() = %s, want %s", syntax, got, want)
+			}
+		} else if sig != nil && sig.Recv() != nil {
+			t.Errorf("%s: signature has receiver %s", sig, sig.Recv().Type())
+		}
+	}
+	// Assert that all wantOut entries were used exactly once.
+	for syntax := range wantOut {
+		t.Errorf("no ast.Selection found with syntax %q", syntax)
+	}
+}
+
+func TestIssue8518(t *testing.T) {
+	fset := token.NewFileSet()
+	imports := make(testImporter)
+	conf := Config{
+		Error:    func(err error) { t.Log(err) }, // don't exit after first error
+		Importer: imports,
+	}
+	makePkg := func(path, src string) {
+		f, err := parser.ParseFile(fset, path, src, 0)
+		if err != nil {
+			t.Fatal(err)
+		}
+		pkg, _ := conf.Check(path, fset, []*ast.File{f}, nil) // errors logged via conf.Error
+		imports[path] = pkg
+	}
+
+	const libSrc = `
+package a
+import "missing"
+const C1 = foo
+const C2 = missing.C
+`
+
+	const mainSrc = `
+package main
+import "a"
+var _ = a.C1
+var _ = a.C2
+`
+
+	makePkg("a", libSrc)
+	makePkg("main", mainSrc) // don't crash when type-checking this package
+}
+
+func TestLookupFieldOrMethod(t *testing.T) {
+	// Test cases assume a lookup of the form a.f or x.f, where a stands for an
+	// addressable value, and x for a non-addressable value (even though a variable
+	// for ease of test case writing).
+	var tests = []struct {
+		src      string
+		found    bool
+		index    []int
+		indirect bool
+	}{
+		// field lookups
+		{"var x T; type T struct{}", false, nil, false},
+		{"var x T; type T struct{ f int }", true, []int{0}, false},
+		{"var x T; type T struct{ a, b, f, c int }", true, []int{2}, false},
+
+		// method lookups
+		{"var a T; type T struct{}; func (T) f() {}", true, []int{0}, false},
+		{"var a *T; type T struct{}; func (T) f() {}", true, []int{0}, true},
+		{"var a T; type T struct{}; func (*T) f() {}", true, []int{0}, false},
+		{"var a *T; type T struct{}; func (*T) f() {}", true, []int{0}, true}, // TODO(gri) should this report indirect = false?
+
+		// collisions
+		{"type ( E1 struct{ f int }; E2 struct{ f int }; x struct{ E1; *E2 })", false, []int{1, 0}, false},
+		{"type ( E1 struct{ f int }; E2 struct{}; x struct{ E1; *E2 }); func (E2) f() {}", false, []int{1, 0}, false},
+
+		// outside methodset
+		// (*T).f method exists, but value of type T is not addressable
+		{"var x T; type T struct{}; func (*T) f() {}", false, nil, true},
+	}
+
+	for _, test := range tests {
+		pkg, err := pkgFor("test", "package p;"+test.src, nil)
+		if err != nil {
+			t.Errorf("%s: incorrect test case: %s", test.src, err)
+			continue
+		}
+
+		obj := pkg.Scope().Lookup("a")
+		if obj == nil {
+			if obj = pkg.Scope().Lookup("x"); obj == nil {
+				t.Errorf("%s: incorrect test case - no object a or x", test.src)
+				continue
+			}
+		}
+
+		f, index, indirect := LookupFieldOrMethod(obj.Type(), obj.Name() == "a", pkg, "f")
+		if (f != nil) != test.found {
+			if f == nil {
+				t.Errorf("%s: got no object; want one", test.src)
+			} else {
+				t.Errorf("%s: got object = %v; want none", test.src, f)
+			}
+		}
+		if !sameSlice(index, test.index) {
+			t.Errorf("%s: got index = %v; want %v", test.src, index, test.index)
+		}
+		if indirect != test.indirect {
+			t.Errorf("%s: got indirect = %v; want %v", test.src, indirect, test.indirect)
+		}
+	}
+}
+
+func sameSlice(a, b []int) bool {
+	if len(a) != len(b) {
+		return false
+	}
+	for i, x := range a {
+		if x != b[i] {
+			return false
+		}
+	}
+	return true
+}
+
+// TestScopeLookupParent ensures that (*Scope).LookupParent returns
+// the correct result at various positions with the source.
+func TestScopeLookupParent(t *testing.T) {
+	fset := token.NewFileSet()
+	imports := make(testImporter)
+	conf := Config{Importer: imports}
+	mustParse := func(src string) *ast.File {
+		f, err := parser.ParseFile(fset, "dummy.go", src, parser.ParseComments)
+		if err != nil {
+			t.Fatal(err)
+		}
+		return f
+	}
+	var info Info
+	makePkg := func(path string, files ...*ast.File) {
+		imports[path], _ = conf.Check(path, fset, files, &info)
+	}
+
+	makePkg("lib", mustParse("package lib; var X int"))
+	// Each /*name=kind:line*/ comment makes the test look up the
+	// name at that point and checks that it resolves to a decl of
+	// the specified kind and line number.  "undef" means undefined.
+	mainSrc := `
+package main
+import "lib"
+var Y = lib.X
+func f() {
+	print(Y) /*Y=var:4*/
+	z /*z=undef*/ := /*z=undef*/ 1 /*z=var:7*/
+	print(z)
+	/*f=func:5*/ /*lib=pkgname:3*/
+	type /*T=undef*/ T /*T=typename:10*/ *T
+}
+`
+	info.Uses = make(map[*ast.Ident]Object)
+	f := mustParse(mainSrc)
+	makePkg("main", f)
+	mainScope := imports["main"].Scope()
+	rx := regexp.MustCompile(`^/\*(\w*)=([\w:]*)\*/$`)
+	for _, group := range f.Comments {
+		for _, comment := range group.List {
+			// Parse the assertion in the comment.
+			m := rx.FindStringSubmatch(comment.Text)
+			if m == nil {
+				t.Errorf("%s: bad comment: %s",
+					fset.Position(comment.Pos()), comment.Text)
+				continue
+			}
+			name, want := m[1], m[2]
+
+			// Look up the name in the innermost enclosing scope.
+			inner := mainScope.Innermost(comment.Pos())
+			if inner == nil {
+				t.Errorf("%s: at %s: can't find innermost scope",
+					fset.Position(comment.Pos()), comment.Text)
+				continue
+			}
+			got := "undef"
+			if _, obj := inner.LookupParent(name, comment.Pos()); obj != nil {
+				kind := strings.ToLower(strings.TrimPrefix(reflect.TypeOf(obj).String(), "*types."))
+				got = fmt.Sprintf("%s:%d", kind, fset.Position(obj.Pos()).Line)
+			}
+			if got != want {
+				t.Errorf("%s: at %s: %s resolved to %s, want %s",
+					fset.Position(comment.Pos()), comment.Text, name, got, want)
+			}
+		}
+	}
+
+	// Check that for each referring identifier,
+	// a lookup of its name on the innermost
+	// enclosing scope returns the correct object.
+
+	for id, wantObj := range info.Uses {
+		inner := mainScope.Innermost(id.Pos())
+		if inner == nil {
+			t.Errorf("%s: can't find innermost scope enclosing %q",
+				fset.Position(id.Pos()), id.Name)
+			continue
+		}
+
+		// Exclude selectors and qualified identifiers---lexical
+		// refs only.  (Ideally, we'd see if the AST parent is a
+		// SelectorExpr, but that requires PathEnclosingInterval
+		// from golang.org/x/tools/go/ast/astutil.)
+		if id.Name == "X" {
+			continue
+		}
+
+		_, gotObj := inner.LookupParent(id.Name, id.Pos())
+		if gotObj != wantObj {
+			t.Errorf("%s: got %v, want %v",
+				fset.Position(id.Pos()), gotObj, wantObj)
+			continue
+		}
+	}
+}
diff --git a/third_party/gofrontend/libgo/go/go/types/assignments.go b/third_party/gofrontend/libgo/go/go/types/assignments.go
new file mode 100644
index 0000000..e88de56
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/go/types/assignments.go
@@ -0,0 +1,328 @@
+// Copyright 2013 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.
+
+// This file implements initialization and assignment checks.
+
+package types
+
+import (
+	"go/ast"
+	"go/token"
+)
+
+// assignment reports whether x can be assigned to a variable of type T,
+// if necessary by attempting to convert untyped values to the appropriate
+// type. If x.mode == invalid upon return, then assignment has already
+// issued an error message and the caller doesn't have to report another.
+// Use T == nil to indicate assignment to an untyped blank identifier.
+//
+// TODO(gri) Should find a better way to handle in-band errors.
+//
+func (check *Checker) assignment(x *operand, T Type) bool {
+	switch x.mode {
+	case invalid:
+		return true // error reported before
+	case constant_, variable, mapindex, value, commaok:
+		// ok
+	default:
+		unreachable()
+	}
+
+	// x must be a single value
+	// (tuple types are never named - no need for underlying type)
+	if t, _ := x.typ.(*Tuple); t != nil {
+		assert(t.Len() > 1)
+		check.errorf(x.pos(), "%d-valued expression %s used as single value", t.Len(), x)
+		x.mode = invalid
+		return false
+	}
+
+	if isUntyped(x.typ) {
+		target := T
+		// spec: "If an untyped constant is assigned to a variable of interface
+		// type or the blank identifier, the constant is first converted to type
+		// bool, rune, int, float64, complex128 or string respectively, depending
+		// on whether the value is a boolean, rune, integer, floating-point, complex,
+		// or string constant."
+		if T == nil || IsInterface(T) {
+			if T == nil && x.typ == Typ[UntypedNil] {
+				check.errorf(x.pos(), "use of untyped nil")
+				x.mode = invalid
+				return false
+			}
+			target = defaultType(x.typ)
+		}
+		check.convertUntyped(x, target)
+		if x.mode == invalid {
+			return false
+		}
+	}
+
+	// spec: "If a left-hand side is the blank identifier, any typed or
+	// non-constant value except for the predeclared identifier nil may
+	// be assigned to it."
+	return T == nil || x.assignableTo(check.conf, T)
+}
+
+func (check *Checker) initConst(lhs *Const, x *operand) {
+	if x.mode == invalid || x.typ == Typ[Invalid] || lhs.typ == Typ[Invalid] {
+		if lhs.typ == nil {
+			lhs.typ = Typ[Invalid]
+		}
+		return
+	}
+
+	// rhs must be a constant
+	if x.mode != constant_ {
+		check.errorf(x.pos(), "%s is not constant", x)
+		if lhs.typ == nil {
+			lhs.typ = Typ[Invalid]
+		}
+		return
+	}
+	assert(isConstType(x.typ))
+
+	// If the lhs doesn't have a type yet, use the type of x.
+	if lhs.typ == nil {
+		lhs.typ = x.typ
+	}
+
+	if !check.assignment(x, lhs.typ) {
+		if x.mode != invalid {
+			check.errorf(x.pos(), "cannot define constant %s (type %s) as %s", lhs.Name(), lhs.typ, x)
+		}
+		return
+	}
+
+	lhs.val = x.val
+}
+
+// If result is set, lhs is a function result parameter and x is a return result.
+func (check *Checker) initVar(lhs *Var, x *operand, result bool) Type {
+	if x.mode == invalid || x.typ == Typ[Invalid] || lhs.typ == Typ[Invalid] {
+		if lhs.typ == nil {
+			lhs.typ = Typ[Invalid]
+		}
+		return nil
+	}
+
+	// If the lhs doesn't have a type yet, use the type of x.
+	if lhs.typ == nil {
+		typ := x.typ
+		if isUntyped(typ) {
+			// convert untyped types to default types
+			if typ == Typ[UntypedNil] {
+				check.errorf(x.pos(), "use of untyped nil")
+				lhs.typ = Typ[Invalid]
+				return nil
+			}
+			typ = defaultType(typ)
+		}
+		lhs.typ = typ
+	}
+
+	if !check.assignment(x, lhs.typ) {
+		if x.mode != invalid {
+			if result {
+				// don't refer to lhs.name because it may be an anonymous result parameter
+				check.errorf(x.pos(), "cannot return %s as value of type %s", x, lhs.typ)
+			} else {
+				check.errorf(x.pos(), "cannot initialize %s with %s", lhs, x)
+			}
+		}
+		return nil
+	}
+
+	return x.typ
+}
+
+func (check *Checker) assignVar(lhs ast.Expr, x *operand) Type {
+	if x.mode == invalid || x.typ == Typ[Invalid] {
+		return nil
+	}
+
+	// Determine if the lhs is a (possibly parenthesized) identifier.
+	ident, _ := unparen(lhs).(*ast.Ident)
+
+	// Don't evaluate lhs if it is the blank identifier.
+	if ident != nil && ident.Name == "_" {
+		check.recordDef(ident, nil)
+		if !check.assignment(x, nil) {
+			assert(x.mode == invalid)
+			x.typ = nil
+		}
+		return x.typ
+	}
+
+	// If the lhs is an identifier denoting a variable v, this assignment
+	// is not a 'use' of v. Remember current value of v.used and restore
+	// after evaluating the lhs via check.expr.
+	var v *Var
+	var v_used bool
+	if ident != nil {
+		if _, obj := check.scope.LookupParent(ident.Name, token.NoPos); obj != nil {
+			v, _ = obj.(*Var)
+			if v != nil {
+				v_used = v.used
+			}
+		}
+	}
+
+	var z operand
+	check.expr(&z, lhs)
+	if v != nil {
+		v.used = v_used // restore v.used
+	}
+
+	if z.mode == invalid || z.typ == Typ[Invalid] {
+		return nil
+	}
+
+	// spec: "Each left-hand side operand must be addressable, a map index
+	// expression, or the blank identifier. Operands may be parenthesized."
+	switch z.mode {
+	case invalid:
+		return nil
+	case variable, mapindex:
+		// ok
+	default:
+		check.errorf(z.pos(), "cannot assign to %s", &z)
+		return nil
+	}
+
+	if !check.assignment(x, z.typ) {
+		if x.mode != invalid {
+			check.errorf(x.pos(), "cannot assign %s to %s", x, &z)
+		}
+		return nil
+	}
+
+	return x.typ
+}
+
+// If returnPos is valid, initVars is called to type-check the assignment of
+// return expressions, and returnPos is the position of the return statement.
+func (check *Checker) initVars(lhs []*Var, rhs []ast.Expr, returnPos token.Pos) {
+	l := len(lhs)
+	get, r, commaOk := unpack(func(x *operand, i int) { check.expr(x, rhs[i]) }, len(rhs), l == 2 && !returnPos.IsValid())
+	if get == nil || l != r {
+		// invalidate lhs and use rhs
+		for _, obj := range lhs {
+			if obj.typ == nil {
+				obj.typ = Typ[Invalid]
+			}
+		}
+		if get == nil {
+			return // error reported by unpack
+		}
+		check.useGetter(get, r)
+		if returnPos.IsValid() {
+			check.errorf(returnPos, "wrong number of return values (want %d, got %d)", l, r)
+			return
+		}
+		check.errorf(rhs[0].Pos(), "assignment count mismatch (%d vs %d)", l, r)
+		return
+	}
+
+	var x operand
+	if commaOk {
+		var a [2]Type
+		for i := range a {
+			get(&x, i)
+			a[i] = check.initVar(lhs[i], &x, returnPos.IsValid())
+		}
+		check.recordCommaOkTypes(rhs[0], a)
+		return
+	}
+
+	for i, lhs := range lhs {
+		get(&x, i)
+		check.initVar(lhs, &x, returnPos.IsValid())
+	}
+}
+
+func (check *Checker) assignVars(lhs, rhs []ast.Expr) {
+	l := len(lhs)
+	get, r, commaOk := unpack(func(x *operand, i int) { check.expr(x, rhs[i]) }, len(rhs), l == 2)
+	if get == nil {
+		return // error reported by unpack
+	}
+	if l != r {
+		check.useGetter(get, r)
+		check.errorf(rhs[0].Pos(), "assignment count mismatch (%d vs %d)", l, r)
+		return
+	}
+
+	var x operand
+	if commaOk {
+		var a [2]Type
+		for i := range a {
+			get(&x, i)
+			a[i] = check.assignVar(lhs[i], &x)
+		}
+		check.recordCommaOkTypes(rhs[0], a)
+		return
+	}
+
+	for i, lhs := range lhs {
+		get(&x, i)
+		check.assignVar(lhs, &x)
+	}
+}
+
+func (check *Checker) shortVarDecl(pos token.Pos, lhs, rhs []ast.Expr) {
+	scope := check.scope
+
+	// collect lhs variables
+	var newVars []*Var
+	var lhsVars = make([]*Var, len(lhs))
+	for i, lhs := range lhs {
+		var obj *Var
+		if ident, _ := lhs.(*ast.Ident); ident != nil {
+			// Use the correct obj if the ident is redeclared. The
+			// variable's scope starts after the declaration; so we
+			// must use Scope.Lookup here and call Scope.Insert
+			// (via check.declare) later.
+			name := ident.Name
+			if alt := scope.Lookup(name); alt != nil {
+				// redeclared object must be a variable
+				if alt, _ := alt.(*Var); alt != nil {
+					obj = alt
+				} else {
+					check.errorf(lhs.Pos(), "cannot assign to %s", lhs)
+				}
+				check.recordUse(ident, alt)
+			} else {
+				// declare new variable, possibly a blank (_) variable
+				obj = NewVar(ident.Pos(), check.pkg, name, nil)
+				if name != "_" {
+					newVars = append(newVars, obj)
+				}
+				check.recordDef(ident, obj)
+			}
+		} else {
+			check.errorf(lhs.Pos(), "cannot declare %s", lhs)
+		}
+		if obj == nil {
+			obj = NewVar(lhs.Pos(), check.pkg, "_", nil) // dummy variable
+		}
+		lhsVars[i] = obj
+	}
+
+	check.initVars(lhsVars, rhs, token.NoPos)
+
+	// declare new variables
+	if len(newVars) > 0 {
+		// spec: "The scope of a constant or variable identifier declared inside
+		// a function begins at the end of the ConstSpec or VarSpec (ShortVarDecl
+		// for short variable declarations) and ends at the end of the innermost
+		// containing block."
+		scopePos := rhs[len(rhs)-1].End()
+		for _, obj := range newVars {
+			check.declare(scope, nil, obj, scopePos) // recordObject already called
+		}
+	} else {
+		check.softErrorf(pos, "no new variables on left side of :=")
+	}
+}
diff --git a/third_party/gofrontend/libgo/go/go/types/builtins.go b/third_party/gofrontend/libgo/go/go/types/builtins.go
new file mode 100644
index 0000000..4729591
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/go/types/builtins.go
@@ -0,0 +1,627 @@
+// Copyright 2012 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.
+
+// This file implements typechecking of builtin function calls.
+
+package types
+
+import (
+	"go/ast"
+	"go/constant"
+	"go/token"
+)
+
+// builtin type-checks a call to the built-in specified by id and
+// returns true if the call is valid, with *x holding the result;
+// but x.expr is not set. If the call is invalid, the result is
+// false, and *x is undefined.
+//
+func (check *Checker) builtin(x *operand, call *ast.CallExpr, id builtinId) (_ bool) {
+	// append is the only built-in that permits the use of ... for the last argument
+	bin := predeclaredFuncs[id]
+	if call.Ellipsis.IsValid() && id != _Append {
+		check.invalidOp(call.Ellipsis, "invalid use of ... with built-in %s", bin.name)
+		check.use(call.Args...)
+		return
+	}
+
+	// For len(x) and cap(x) we need to know if x contains any function calls or
+	// receive operations. Save/restore current setting and set hasCallOrRecv to
+	// false for the evaluation of x so that we can check it afterwards.
+	// Note: We must do this _before_ calling unpack because unpack evaluates the
+	//       first argument before we even call arg(x, 0)!
+	if id == _Len || id == _Cap {
+		defer func(b bool) {
+			check.hasCallOrRecv = b
+		}(check.hasCallOrRecv)
+		check.hasCallOrRecv = false
+	}
+
+	// determine actual arguments
+	var arg getter
+	nargs := len(call.Args)
+	switch id {
+	default:
+		// make argument getter
+		arg, nargs, _ = unpack(func(x *operand, i int) { check.expr(x, call.Args[i]) }, nargs, false)
+		if arg == nil {
+			return
+		}
+		// evaluate first argument, if present
+		if nargs > 0 {
+			arg(x, 0)
+			if x.mode == invalid {
+				return
+			}
+		}
+	case _Make, _New, _Offsetof, _Trace:
+		// arguments require special handling
+	}
+
+	// check argument count
+	{
+		msg := ""
+		if nargs < bin.nargs {
+			msg = "not enough"
+		} else if !bin.variadic && nargs > bin.nargs {
+			msg = "too many"
+		}
+		if msg != "" {
+			check.invalidOp(call.Rparen, "%s arguments for %s (expected %d, found %d)", msg, call, bin.nargs, nargs)
+			return
+		}
+	}
+
+	switch id {
+	case _Append:
+		// append(s S, x ...T) S, where T is the element type of S
+		// spec: "The variadic function append appends zero or more values x to s of type
+		// S, which must be a slice type, and returns the resulting slice, also of type S.
+		// The values x are passed to a parameter of type ...T where T is the element type
+		// of S and the respective parameter passing rules apply."
+		S := x.typ
+		var T Type
+		if s, _ := S.Underlying().(*Slice); s != nil {
+			T = s.elem
+		} else {
+			check.invalidArg(x.pos(), "%s is not a slice", x)
+			return
+		}
+
+		// remember arguments that have been evaluated already
+		alist := []operand{*x}
+
+		// spec: "As a special case, append also accepts a first argument assignable
+		// to type []byte with a second argument of string type followed by ... .
+		// This form appends the bytes of the string.
+		if nargs == 2 && call.Ellipsis.IsValid() && x.assignableTo(check.conf, NewSlice(universeByte)) {
+			arg(x, 1)
+			if x.mode == invalid {
+				return
+			}
+			if isString(x.typ) {
+				if check.Types != nil {
+					sig := makeSig(S, S, x.typ)
+					sig.variadic = true
+					check.recordBuiltinType(call.Fun, sig)
+				}
+				x.mode = value
+				x.typ = S
+				break
+			}
+			alist = append(alist, *x)
+			// fallthrough
+		}
+
+		// check general case by creating custom signature
+		sig := makeSig(S, S, NewSlice(T)) // []T required for variadic signature
+		sig.variadic = true
+		check.arguments(x, call, sig, func(x *operand, i int) {
+			// only evaluate arguments that have not been evaluated before
+			if i < len(alist) {
+				*x = alist[i]
+				return
+			}
+			arg(x, i)
+		}, nargs)
+		// ok to continue even if check.arguments reported errors
+
+		x.mode = value
+		x.typ = S
+		if check.Types != nil {
+			check.recordBuiltinType(call.Fun, sig)
+		}
+
+	case _Cap, _Len:
+		// cap(x)
+		// len(x)
+		mode := invalid
+		var typ Type
+		var val constant.Value
+		switch typ = implicitArrayDeref(x.typ.Underlying()); t := typ.(type) {
+		case *Basic:
+			if isString(t) && id == _Len {
+				if x.mode == constant_ {
+					mode = constant_
+					val = constant.MakeInt64(int64(len(constant.StringVal(x.val))))
+				} else {
+					mode = value
+				}
+			}
+
+		case *Array:
+			mode = value
+			// spec: "The expressions len(s) and cap(s) are constants
+			// if the type of s is an array or pointer to an array and
+			// the expression s does not contain channel receives or
+			// function calls; in this case s is not evaluated."
+			if !check.hasCallOrRecv {
+				mode = constant_
+				val = constant.MakeInt64(t.len)
+			}
+
+		case *Slice, *Chan:
+			mode = value
+
+		case *Map:
+			if id == _Len {
+				mode = value
+			}
+		}
+
+		if mode == invalid {
+			check.invalidArg(x.pos(), "%s for %s", x, bin.name)
+			return
+		}
+
+		x.mode = mode
+		x.typ = Typ[Int]
+		x.val = val
+		if check.Types != nil && mode != constant_ {
+			check.recordBuiltinType(call.Fun, makeSig(x.typ, typ))
+		}
+
+	case _Close:
+		// close(c)
+		c, _ := x.typ.Underlying().(*Chan)
+		if c == nil {
+			check.invalidArg(x.pos(), "%s is not a channel", x)
+			return
+		}
+		if c.dir == RecvOnly {
+			check.invalidArg(x.pos(), "%s must not be a receive-only channel", x)
+			return
+		}
+
+		x.mode = novalue
+		if check.Types != nil {
+			check.recordBuiltinType(call.Fun, makeSig(nil, c))
+		}
+
+	case _Complex:
+		// complex(x, y realT) complexT
+		if !check.complexArg(x) {
+			return
+		}
+
+		var y operand
+		arg(&y, 1)
+		if y.mode == invalid {
+			return
+		}
+		if !check.complexArg(&y) {
+			return
+		}
+
+		check.convertUntyped(x, y.typ)
+		if x.mode == invalid {
+			return
+		}
+		check.convertUntyped(&y, x.typ)
+		if y.mode == invalid {
+			return
+		}
+
+		if !Identical(x.typ, y.typ) {
+			check.invalidArg(x.pos(), "mismatched types %s and %s", x.typ, y.typ)
+			return
+		}
+
+		if x.mode == constant_ && y.mode == constant_ {
+			x.val = constant.BinaryOp(x.val, token.ADD, constant.MakeImag(y.val))
+		} else {
+			x.mode = value
+		}
+
+		realT := x.typ
+		complexT := Typ[Invalid]
+		switch realT.Underlying().(*Basic).kind {
+		case Float32:
+			complexT = Typ[Complex64]
+		case Float64:
+			complexT = Typ[Complex128]
+		case UntypedInt, UntypedRune, UntypedFloat:
+			if x.mode == constant_ {
+				realT = defaultType(realT).(*Basic)
+				complexT = Typ[UntypedComplex]
+			} else {
+				// untyped but not constant; probably because one
+				// operand is a non-constant shift of untyped lhs
+				realT = Typ[Float64]
+				complexT = Typ[Complex128]
+			}
+		default:
+			check.invalidArg(x.pos(), "float32 or float64 arguments expected")
+			return
+		}
+
+		x.typ = complexT
+		if check.Types != nil && x.mode != constant_ {
+			check.recordBuiltinType(call.Fun, makeSig(complexT, realT, realT))
+		}
+
+		if x.mode != constant_ {
+			// The arguments have now their final types, which at run-
+			// time will be materialized. Update the expression trees.
+			// If the current types are untyped, the materialized type
+			// is the respective default type.
+			// (If the result is constant, the arguments are never
+			// materialized and there is nothing to do.)
+			check.updateExprType(x.expr, realT, true)
+			check.updateExprType(y.expr, realT, true)
+		}
+
+	case _Copy:
+		// copy(x, y []T) int
+		var dst Type
+		if t, _ := x.typ.Underlying().(*Slice); t != nil {
+			dst = t.elem
+		}
+
+		var y operand
+		arg(&y, 1)
+		if y.mode == invalid {
+			return
+		}
+		var src Type
+		switch t := y.typ.Underlying().(type) {
+		case *Basic:
+			if isString(y.typ) {
+				src = universeByte
+			}
+		case *Slice:
+			src = t.elem
+		}
+
+		if dst == nil || src == nil {
+			check.invalidArg(x.pos(), "copy expects slice arguments; found %s and %s", x, &y)
+			return
+		}
+
+		if !Identical(dst, src) {
+			check.invalidArg(x.pos(), "arguments to copy %s and %s have different element types %s and %s", x, &y, dst, src)
+			return
+		}
+
+		if check.Types != nil {
+			check.recordBuiltinType(call.Fun, makeSig(Typ[Int], x.typ, y.typ))
+		}
+		x.mode = value
+		x.typ = Typ[Int]
+
+	case _Delete:
+		// delete(m, k)
+		m, _ := x.typ.Underlying().(*Map)
+		if m == nil {
+			check.invalidArg(x.pos(), "%s is not a map", x)
+			return
+		}
+		arg(x, 1) // k
+		if x.mode == invalid {
+			return
+		}
+
+		if !x.assignableTo(check.conf, m.key) {
+			check.invalidArg(x.pos(), "%s is not assignable to %s", x, m.key)
+			return
+		}
+
+		x.mode = novalue
+		if check.Types != nil {
+			check.recordBuiltinType(call.Fun, makeSig(nil, m, m.key))
+		}
+
+	case _Imag, _Real:
+		// imag(complexT) realT
+		// real(complexT) realT
+		if !isComplex(x.typ) {
+			check.invalidArg(x.pos(), "%s must be a complex number", x)
+			return
+		}
+		if x.mode == constant_ {
+			if id == _Real {
+				x.val = constant.Real(x.val)
+			} else {
+				x.val = constant.Imag(x.val)
+			}
+		} else {
+			x.mode = value
+		}
+		var k BasicKind
+		switch x.typ.Underlying().(*Basic).kind {
+		case Complex64:
+			k = Float32
+		case Complex128:
+			k = Float64
+		case UntypedComplex:
+			k = UntypedFloat
+		default:
+			unreachable()
+		}
+
+		if check.Types != nil && x.mode != constant_ {
+			check.recordBuiltinType(call.Fun, makeSig(Typ[k], x.typ))
+		}
+		x.typ = Typ[k]
+
+	case _Make:
+		// make(T, n)
+		// make(T, n, m)
+		// (no argument evaluated yet)
+		arg0 := call.Args[0]
+		T := check.typ(arg0)
+		if T == Typ[Invalid] {
+			return
+		}
+
+		var min int // minimum number of arguments
+		switch T.Underlying().(type) {
+		case *Slice:
+			min = 2
+		case *Map, *Chan:
+			min = 1
+		default:
+			check.invalidArg(arg0.Pos(), "cannot make %s; type must be slice, map, or channel", arg0)
+			return
+		}
+		if nargs < min || min+1 < nargs {
+			check.errorf(call.Pos(), "%s expects %d or %d arguments; found %d", call, min, min+1, nargs)
+			return
+		}
+		var sizes []int64 // constant integer arguments, if any
+		for _, arg := range call.Args[1:] {
+			if s, ok := check.index(arg, -1); ok && s >= 0 {
+				sizes = append(sizes, s)
+			}
+		}
+		if len(sizes) == 2 && sizes[0] > sizes[1] {
+			check.invalidArg(call.Args[1].Pos(), "length and capacity swapped")
+			// safe to continue
+		}
+		x.mode = value
+		x.typ = T
+		if check.Types != nil {
+			params := [...]Type{T, Typ[Int], Typ[Int]}
+			check.recordBuiltinType(call.Fun, makeSig(x.typ, params[:1+len(sizes)]...))
+		}
+
+	case _New:
+		// new(T)
+		// (no argument evaluated yet)
+		T := check.typ(call.Args[0])
+		if T == Typ[Invalid] {
+			return
+		}
+
+		x.mode = value
+		x.typ = &Pointer{base: T}
+		if check.Types != nil {
+			check.recordBuiltinType(call.Fun, makeSig(x.typ, T))
+		}
+
+	case _Panic:
+		// panic(x)
+		T := new(Interface)
+		if !check.assignment(x, T) {
+			assert(x.mode == invalid)
+			return
+		}
+
+		x.mode = novalue
+		if check.Types != nil {
+			check.recordBuiltinType(call.Fun, makeSig(nil, T))
+		}
+
+	case _Print, _Println:
+		// print(x, y, ...)
+		// println(x, y, ...)
+		var params []Type
+		if nargs > 0 {
+			params = make([]Type, nargs)
+			for i := 0; i < nargs; i++ {
+				if i > 0 {
+					arg(x, i) // first argument already evaluated
+				}
+				if !check.assignment(x, nil) {
+					assert(x.mode == invalid)
+					return
+				}
+				params[i] = x.typ
+			}
+		}
+
+		x.mode = novalue
+		if check.Types != nil {
+			check.recordBuiltinType(call.Fun, makeSig(nil, params...))
+		}
+
+	case _Recover:
+		// recover() interface{}
+		x.mode = value
+		x.typ = new(Interface)
+		if check.Types != nil {
+			check.recordBuiltinType(call.Fun, makeSig(x.typ))
+		}
+
+	case _Alignof:
+		// unsafe.Alignof(x T) uintptr
+		if !check.assignment(x, nil) {
+			assert(x.mode == invalid)
+			return
+		}
+
+		x.mode = constant_
+		x.val = constant.MakeInt64(check.conf.alignof(x.typ))
+		x.typ = Typ[Uintptr]
+		// result is constant - no need to record signature
+
+	case _Offsetof:
+		// unsafe.Offsetof(x T) uintptr, where x must be a selector
+		// (no argument evaluated yet)
+		arg0 := call.Args[0]
+		selx, _ := unparen(arg0).(*ast.SelectorExpr)
+		if selx == nil {
+			check.invalidArg(arg0.Pos(), "%s is not a selector expression", arg0)
+			check.use(arg0)
+			return
+		}
+
+		check.expr(x, selx.X)
+		if x.mode == invalid {
+			return
+		}
+
+		base := derefStructPtr(x.typ)
+		sel := selx.Sel.Name
+		obj, index, indirect := LookupFieldOrMethod(base, false, check.pkg, sel)
+		switch obj.(type) {
+		case nil:
+			check.invalidArg(x.pos(), "%s has no single field %s", base, sel)
+			return
+		case *Func:
+			// TODO(gri) Using derefStructPtr may result in methods being found
+			// that don't actually exist. An error either way, but the error
+			// message is confusing. See: https://play.golang.org/p/al75v23kUy ,
+			// but go/types reports: "invalid argument: x.m is a method value".
+			check.invalidArg(arg0.Pos(), "%s is a method value", arg0)
+			return
+		}
+		if indirect {
+			check.invalidArg(x.pos(), "field %s is embedded via a pointer in %s", sel, base)
+			return
+		}
+
+		// TODO(gri) Should we pass x.typ instead of base (and indirect report if derefStructPtr indirected)?
+		check.recordSelection(selx, FieldVal, base, obj, index, false)
+
+		offs := check.conf.offsetof(base, index)
+		x.mode = constant_
+		x.val = constant.MakeInt64(offs)
+		x.typ = Typ[Uintptr]
+		// result is constant - no need to record signature
+
+	case _Sizeof:
+		// unsafe.Sizeof(x T) uintptr
+		if !check.assignment(x, nil) {
+			assert(x.mode == invalid)
+			return
+		}
+
+		x.mode = constant_
+		x.val = constant.MakeInt64(check.conf.sizeof(x.typ))
+		x.typ = Typ[Uintptr]
+		// result is constant - no need to record signature
+
+	case _Assert:
+		// assert(pred) causes a typechecker error if pred is false.
+		// The result of assert is the value of pred if there is no error.
+		// Note: assert is only available in self-test mode.
+		if x.mode != constant_ || !isBoolean(x.typ) {
+			check.invalidArg(x.pos(), "%s is not a boolean constant", x)
+			return
+		}
+		if x.val.Kind() != constant.Bool {
+			check.errorf(x.pos(), "internal error: value of %s should be a boolean constant", x)
+			return
+		}
+		if !constant.BoolVal(x.val) {
+			check.errorf(call.Pos(), "%s failed", call)
+			// compile-time assertion failure - safe to continue
+		}
+		// result is constant - no need to record signature
+
+	case _Trace:
+		// trace(x, y, z, ...) dumps the positions, expressions, and
+		// values of its arguments. The result of trace is the value
+		// of the first argument.
+		// Note: trace is only available in self-test mode.
+		// (no argument evaluated yet)
+		if nargs == 0 {
+			check.dump("%s: trace() without arguments", call.Pos())
+			x.mode = novalue
+			break
+		}
+		var t operand
+		x1 := x
+		for _, arg := range call.Args {
+			check.rawExpr(x1, arg, nil) // permit trace for types, e.g.: new(trace(T))
+			check.dump("%s: %s", x1.pos(), x1)
+			x1 = &t // use incoming x only for first argument
+		}
+		// trace is only available in test mode - no need to record signature
+
+	default:
+		unreachable()
+	}
+
+	return true
+}
+
+// makeSig makes a signature for the given argument and result types.
+// Default types are used for untyped arguments, and res may be nil.
+func makeSig(res Type, args ...Type) *Signature {
+	list := make([]*Var, len(args))
+	for i, param := range args {
+		list[i] = NewVar(token.NoPos, nil, "", defaultType(param))
+	}
+	params := NewTuple(list...)
+	var result *Tuple
+	if res != nil {
+		assert(!isUntyped(res))
+		result = NewTuple(NewVar(token.NoPos, nil, "", res))
+	}
+	return &Signature{params: params, results: result}
+}
+
+// implicitArrayDeref returns A if typ is of the form *A and A is an array;
+// otherwise it returns typ.
+//
+func implicitArrayDeref(typ Type) Type {
+	if p, ok := typ.(*Pointer); ok {
+		if a, ok := p.base.Underlying().(*Array); ok {
+			return a
+		}
+	}
+	return typ
+}
+
+// unparen returns e with any enclosing parentheses stripped.
+func unparen(e ast.Expr) ast.Expr {
+	for {
+		p, ok := e.(*ast.ParenExpr)
+		if !ok {
+			return e
+		}
+		e = p.X
+	}
+}
+
+func (check *Checker) complexArg(x *operand) bool {
+	t, _ := x.typ.Underlying().(*Basic)
+	if t != nil && (t.info&IsFloat != 0 || t.kind == UntypedInt || t.kind == UntypedRune) {
+		return true
+	}
+	check.invalidArg(x.pos(), "%s must be a float32, float64, or an untyped non-complex numeric constant", x)
+	return false
+}
diff --git a/third_party/gofrontend/libgo/go/go/types/builtins_test.go b/third_party/gofrontend/libgo/go/go/types/builtins_test.go
new file mode 100644
index 0000000..9835a48
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/go/types/builtins_test.go
@@ -0,0 +1,204 @@
+// Copyright 2013 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 types_test
+
+import (
+	"fmt"
+	"go/ast"
+	"go/importer"
+	"go/parser"
+	"testing"
+
+	. "go/types"
+)
+
+var builtinCalls = []struct {
+	name, src, sig string
+}{
+	{"append", `var s []int; _ = append(s)`, `func([]int, ...int) []int`},
+	{"append", `var s []int; _ = append(s, 0)`, `func([]int, ...int) []int`},
+	{"append", `var s []int; _ = (append)(s, 0)`, `func([]int, ...int) []int`},
+	{"append", `var s []byte; _ = ((append))(s, 0)`, `func([]byte, ...byte) []byte`},
+	{"append", `var s []byte; _ = append(s, "foo"...)`, `func([]byte, string...) []byte`},
+	{"append", `type T []byte; var s T; var str string; _ = append(s, str...)`, `func(p.T, string...) p.T`},
+	{"append", `type T []byte; type U string; var s T; var str U; _ = append(s, str...)`, `func(p.T, p.U...) p.T`},
+
+	{"cap", `var s [10]int; _ = cap(s)`, `invalid type`},  // constant
+	{"cap", `var s [10]int; _ = cap(&s)`, `invalid type`}, // constant
+	{"cap", `var s []int64; _ = cap(s)`, `func([]int64) int`},
+	{"cap", `var c chan<-bool; _ = cap(c)`, `func(chan<- bool) int`},
+
+	{"len", `_ = len("foo")`, `invalid type`}, // constant
+	{"len", `var s string; _ = len(s)`, `func(string) int`},
+	{"len", `var s [10]int; _ = len(s)`, `invalid type`},  // constant
+	{"len", `var s [10]int; _ = len(&s)`, `invalid type`}, // constant
+	{"len", `var s []int64; _ = len(s)`, `func([]int64) int`},
+	{"len", `var c chan<-bool; _ = len(c)`, `func(chan<- bool) int`},
+	{"len", `var m map[string]float32; _ = len(m)`, `func(map[string]float32) int`},
+
+	{"close", `var c chan int; close(c)`, `func(chan int)`},
+	{"close", `var c chan<- chan string; close(c)`, `func(chan<- chan string)`},
+
+	{"complex", `_ = complex(1, 0)`, `invalid type`}, // constant
+	{"complex", `var re float32; _ = complex(re, 1.0)`, `func(float32, float32) complex64`},
+	{"complex", `var im float64; _ = complex(1, im)`, `func(float64, float64) complex128`},
+	{"complex", `type F32 float32; var re, im F32; _ = complex(re, im)`, `func(p.F32, p.F32) complex64`},
+	{"complex", `type F64 float64; var re, im F64; _ = complex(re, im)`, `func(p.F64, p.F64) complex128`},
+
+	{"copy", `var src, dst []byte; copy(dst, src)`, `func([]byte, []byte) int`},
+	{"copy", `type T [][]int; var src, dst T; _ = copy(dst, src)`, `func(p.T, p.T) int`},
+	{"copy", `var src string; var dst []byte; copy(dst, src)`, `func([]byte, string) int`},
+	{"copy", `type T string; type U []byte; var src T; var dst U; copy(dst, src)`, `func(p.U, p.T) int`},
+	{"copy", `var dst []byte; copy(dst, "hello")`, `func([]byte, string) int`},
+
+	{"delete", `var m map[string]bool; delete(m, "foo")`, `func(map[string]bool, string)`},
+	{"delete", `type (K string; V int); var m map[K]V; delete(m, "foo")`, `func(map[p.K]p.V, p.K)`},
+
+	{"imag", `_ = imag(1i)`, `invalid type`}, // constant
+	{"imag", `var c complex64; _ = imag(c)`, `func(complex64) float32`},
+	{"imag", `var c complex128; _ = imag(c)`, `func(complex128) float64`},
+	{"imag", `type C64 complex64; var c C64; _ = imag(c)`, `func(p.C64) float32`},
+	{"imag", `type C128 complex128; var c C128; _ = imag(c)`, `func(p.C128) float64`},
+
+	{"real", `_ = real(1i)`, `invalid type`}, // constant
+	{"real", `var c complex64; _ = real(c)`, `func(complex64) float32`},
+	{"real", `var c complex128; _ = real(c)`, `func(complex128) float64`},
+	{"real", `type C64 complex64; var c C64; _ = real(c)`, `func(p.C64) float32`},
+	{"real", `type C128 complex128; var c C128; _ = real(c)`, `func(p.C128) float64`},
+
+	{"make", `_ = make([]int, 10)`, `func([]int, int) []int`},
+	{"make", `type T []byte; _ = make(T, 10, 20)`, `func(p.T, int, int) p.T`},
+
+	{"new", `_ = new(int)`, `func(int) *int`},
+	{"new", `type T struct{}; _ = new(T)`, `func(p.T) *p.T`},
+
+	{"panic", `panic(0)`, `func(interface{})`},
+	{"panic", `panic("foo")`, `func(interface{})`},
+
+	{"print", `print()`, `func()`},
+	{"print", `print(0)`, `func(int)`},
+	{"print", `print(1, 2.0, "foo", true)`, `func(int, float64, string, bool)`},
+
+	{"println", `println()`, `func()`},
+	{"println", `println(0)`, `func(int)`},
+	{"println", `println(1, 2.0, "foo", true)`, `func(int, float64, string, bool)`},
+
+	{"recover", `recover()`, `func() interface{}`},
+	{"recover", `_ = recover()`, `func() interface{}`},
+
+	{"Alignof", `_ = unsafe.Alignof(0)`, `invalid type`},                 // constant
+	{"Alignof", `var x struct{}; _ = unsafe.Alignof(x)`, `invalid type`}, // constant
+
+	{"Offsetof", `var x struct{f bool}; _ = unsafe.Offsetof(x.f)`, `invalid type`},           // constant
+	{"Offsetof", `var x struct{_ int; f bool}; _ = unsafe.Offsetof((&x).f)`, `invalid type`}, // constant
+
+	{"Sizeof", `_ = unsafe.Sizeof(0)`, `invalid type`},                 // constant
+	{"Sizeof", `var x struct{}; _ = unsafe.Sizeof(x)`, `invalid type`}, // constant
+
+	{"assert", `assert(true)`, `invalid type`},                                    // constant
+	{"assert", `type B bool; const pred B = 1 < 2; assert(pred)`, `invalid type`}, // constant
+
+	// no tests for trace since it produces output as a side-effect
+}
+
+func TestBuiltinSignatures(t *testing.T) {
+	DefPredeclaredTestFuncs()
+
+	seen := map[string]bool{"trace": true} // no test for trace built-in; add it manually
+	for _, call := range builtinCalls {
+		testBuiltinSignature(t, call.name, call.src, call.sig)
+		seen[call.name] = true
+	}
+
+	// make sure we didn't miss one
+	for _, name := range Universe.Names() {
+		if _, ok := Universe.Lookup(name).(*Builtin); ok && !seen[name] {
+			t.Errorf("missing test for %s", name)
+		}
+	}
+	for _, name := range Unsafe.Scope().Names() {
+		if _, ok := Unsafe.Scope().Lookup(name).(*Builtin); ok && !seen[name] {
+			t.Errorf("missing test for unsafe.%s", name)
+		}
+	}
+}
+
+func testBuiltinSignature(t *testing.T, name, src0, want string) {
+	src := fmt.Sprintf(`package p; import "unsafe"; type _ unsafe.Pointer /* use unsafe */; func _() { %s }`, src0)
+	f, err := parser.ParseFile(fset, "", src, 0)
+	if err != nil {
+		t.Errorf("%s: %s", src0, err)
+		return
+	}
+
+	conf := Config{Importer: importer.Default()}
+	uses := make(map[*ast.Ident]Object)
+	types := make(map[ast.Expr]TypeAndValue)
+	_, err = conf.Check(f.Name.Name, fset, []*ast.File{f}, &Info{Uses: uses, Types: types})
+	if err != nil {
+		t.Errorf("%s: %s", src0, err)
+		return
+	}
+
+	// find called function
+	n := 0
+	var fun ast.Expr
+	for x := range types {
+		if call, _ := x.(*ast.CallExpr); call != nil {
+			fun = call.Fun
+			n++
+		}
+	}
+	if n != 1 {
+		t.Errorf("%s: got %d CallExprs; want 1", src0, n)
+		return
+	}
+
+	// check recorded types for fun and descendents (may be parenthesized)
+	for {
+		// the recorded type for the built-in must match the wanted signature
+		typ := types[fun].Type
+		if typ == nil {
+			t.Errorf("%s: no type recorded for %s", src0, ExprString(fun))
+			return
+		}
+		if got := typ.String(); got != want {
+			t.Errorf("%s: got type %s; want %s", src0, got, want)
+			return
+		}
+
+		// called function must be a (possibly parenthesized, qualified)
+		// identifier denoting the expected built-in
+		switch p := fun.(type) {
+		case *ast.Ident:
+			obj := uses[p]
+			if obj == nil {
+				t.Errorf("%s: no object found for %s", src0, p)
+				return
+			}
+			bin, _ := obj.(*Builtin)
+			if bin == nil {
+				t.Errorf("%s: %s does not denote a built-in", src0, p)
+				return
+			}
+			if bin.Name() != name {
+				t.Errorf("%s: got built-in %s; want %s", src0, bin.Name(), name)
+				return
+			}
+			return // we're done
+
+		case *ast.ParenExpr:
+			fun = p.X // unpack
+
+		case *ast.SelectorExpr:
+			// built-in from package unsafe - ignore details
+			return // we're done
+
+		default:
+			t.Errorf("%s: invalid function call", src0)
+			return
+		}
+	}
+}
diff --git a/third_party/gofrontend/libgo/go/go/types/call.go b/third_party/gofrontend/libgo/go/go/types/call.go
new file mode 100644
index 0000000..62cefc0
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/go/types/call.go
@@ -0,0 +1,441 @@
+// Copyright 2013 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.
+
+// This file implements typechecking of call and selector expressions.
+
+package types
+
+import (
+	"go/ast"
+	"go/token"
+)
+
+func (check *Checker) call(x *operand, e *ast.CallExpr) exprKind {
+	check.exprOrType(x, e.Fun)
+
+	switch x.mode {
+	case invalid:
+		check.use(e.Args...)
+		x.mode = invalid
+		x.expr = e
+		return statement
+
+	case typexpr:
+		// conversion
+		T := x.typ
+		x.mode = invalid
+		switch n := len(e.Args); n {
+		case 0:
+			check.errorf(e.Rparen, "missing argument in conversion to %s", T)
+		case 1:
+			check.expr(x, e.Args[0])
+			if x.mode != invalid {
+				check.conversion(x, T)
+			}
+		default:
+			check.errorf(e.Args[n-1].Pos(), "too many arguments in conversion to %s", T)
+		}
+		x.expr = e
+		return conversion
+
+	case builtin:
+		id := x.id
+		if !check.builtin(x, e, id) {
+			x.mode = invalid
+		}
+		x.expr = e
+		// a non-constant result implies a function call
+		if x.mode != invalid && x.mode != constant_ {
+			check.hasCallOrRecv = true
+		}
+		return predeclaredFuncs[id].kind
+
+	default:
+		// function/method call
+		sig, _ := x.typ.Underlying().(*Signature)
+		if sig == nil {
+			check.invalidOp(x.pos(), "cannot call non-function %s", x)
+			x.mode = invalid
+			x.expr = e
+			return statement
+		}
+
+		arg, n, _ := unpack(func(x *operand, i int) { check.expr(x, e.Args[i]) }, len(e.Args), false)
+		if arg == nil {
+			x.mode = invalid
+			x.expr = e
+			return statement
+		}
+
+		check.arguments(x, e, sig, arg, n)
+
+		// determine result
+		switch sig.results.Len() {
+		case 0:
+			x.mode = novalue
+		case 1:
+			x.mode = value
+			x.typ = sig.results.vars[0].typ // unpack tuple
+		default:
+			x.mode = value
+			x.typ = sig.results
+		}
+		x.expr = e
+		check.hasCallOrRecv = true
+
+		return statement
+	}
+}
+
+// use type-checks each argument.
+// Useful to make sure expressions are evaluated
+// (and variables are "used") in the presence of other errors.
+func (check *Checker) use(arg ...ast.Expr) {
+	var x operand
+	for _, e := range arg {
+		check.rawExpr(&x, e, nil)
+	}
+}
+
+// useGetter is like use, but takes a getter instead of a list of expressions.
+// It should be called instead of use if a getter is present to avoid repeated
+// evaluation of the first argument (since the getter was likely obtained via
+// unpack, which may have evaluated the first argument already).
+func (check *Checker) useGetter(get getter, n int) {
+	var x operand
+	for i := 0; i < n; i++ {
+		get(&x, i)
+	}
+}
+
+// A getter sets x as the i'th operand, where 0 <= i < n and n is the total
+// number of operands (context-specific, and maintained elsewhere). A getter
+// type-checks the i'th operand; the details of the actual check are getter-
+// specific.
+type getter func(x *operand, i int)
+
+// unpack takes a getter get and a number of operands n. If n == 1, unpack
+// calls the incoming getter for the first operand. If that operand is
+// invalid, unpack returns (nil, 0, false). Otherwise, if that operand is a
+// function call, or a comma-ok expression and allowCommaOk is set, the result
+// is a new getter and operand count providing access to the function results,
+// or comma-ok values, respectively. The third result value reports if it
+// is indeed the comma-ok case. In all other cases, the incoming getter and
+// operand count are returned unchanged, and the third result value is false.
+//
+// In other words, if there's exactly one operand that - after type-checking
+// by calling get - stands for multiple operands, the resulting getter provides
+// access to those operands instead.
+//
+// If the returned getter is called at most once for a given operand index i
+// (including i == 0), that operand is guaranteed to cause only one call of
+// the incoming getter with that i.
+//
+func unpack(get getter, n int, allowCommaOk bool) (getter, int, bool) {
+	if n == 1 {
+		// possibly result of an n-valued function call or comma,ok value
+		var x0 operand
+		get(&x0, 0)
+		if x0.mode == invalid {
+			return nil, 0, false
+		}
+
+		if t, ok := x0.typ.(*Tuple); ok {
+			// result of an n-valued function call
+			return func(x *operand, i int) {
+				x.mode = value
+				x.expr = x0.expr
+				x.typ = t.At(i).typ
+			}, t.Len(), false
+		}
+
+		if x0.mode == mapindex || x0.mode == commaok {
+			// comma-ok value
+			if allowCommaOk {
+				a := [2]Type{x0.typ, Typ[UntypedBool]}
+				return func(x *operand, i int) {
+					x.mode = value
+					x.expr = x0.expr
+					x.typ = a[i]
+				}, 2, true
+			}
+			x0.mode = value
+		}
+
+		// single value
+		return func(x *operand, i int) {
+			if i != 0 {
+				unreachable()
+			}
+			*x = x0
+		}, 1, false
+	}
+
+	// zero or multiple values
+	return get, n, false
+}
+
+// arguments checks argument passing for the call with the given signature.
+// The arg function provides the operand for the i'th argument.
+func (check *Checker) arguments(x *operand, call *ast.CallExpr, sig *Signature, arg getter, n int) {
+	if call.Ellipsis.IsValid() {
+		// last argument is of the form x...
+		if len(call.Args) == 1 && n > 1 {
+			// f()... is not permitted if f() is multi-valued
+			check.errorf(call.Ellipsis, "cannot use ... with %d-valued expression %s", n, call.Args[0])
+			check.useGetter(arg, n)
+			return
+		}
+		if !sig.variadic {
+			check.errorf(call.Ellipsis, "cannot use ... in call to non-variadic %s", call.Fun)
+			check.useGetter(arg, n)
+			return
+		}
+	}
+
+	// evaluate arguments
+	for i := 0; i < n; i++ {
+		arg(x, i)
+		if x.mode != invalid {
+			var ellipsis token.Pos
+			if i == n-1 && call.Ellipsis.IsValid() {
+				ellipsis = call.Ellipsis
+			}
+			check.argument(sig, i, x, ellipsis)
+		}
+	}
+
+	// check argument count
+	if sig.variadic {
+		// a variadic function accepts an "empty"
+		// last argument: count one extra
+		n++
+	}
+	if n < sig.params.Len() {
+		check.errorf(call.Rparen, "too few arguments in call to %s", call.Fun)
+		// ok to continue
+	}
+}
+
+// argument checks passing of argument x to the i'th parameter of the given signature.
+// If ellipsis is valid, the argument is followed by ... at that position in the call.
+func (check *Checker) argument(sig *Signature, i int, x *operand, ellipsis token.Pos) {
+	n := sig.params.Len()
+
+	// determine parameter type
+	var typ Type
+	switch {
+	case i < n:
+		typ = sig.params.vars[i].typ
+	case sig.variadic:
+		typ = sig.params.vars[n-1].typ
+		if debug {
+			if _, ok := typ.(*Slice); !ok {
+				check.dump("%s: expected unnamed slice type, got %s", sig.params.vars[n-1].Pos(), typ)
+			}
+		}
+	default:
+		check.errorf(x.pos(), "too many arguments")
+		return
+	}
+
+	if ellipsis.IsValid() {
+		// argument is of the form x...
+		if i != n-1 {
+			check.errorf(ellipsis, "can only use ... with matching parameter")
+			return
+		}
+		switch t := x.typ.Underlying().(type) {
+		case *Slice:
+			// ok
+		case *Tuple:
+			check.errorf(ellipsis, "cannot use ... with %d-valued expression %s", t.Len(), x)
+			return
+		default:
+			check.errorf(x.pos(), "cannot use %s as parameter of type %s", x, typ)
+			return
+		}
+	} else if sig.variadic && i >= n-1 {
+		// use the variadic parameter slice's element type
+		typ = typ.(*Slice).elem
+	}
+
+	if !check.assignment(x, typ) && x.mode != invalid {
+		check.errorf(x.pos(), "cannot pass argument %s to parameter of type %s", x, typ)
+	}
+}
+
+func (check *Checker) selector(x *operand, e *ast.SelectorExpr) {
+	// these must be declared before the "goto Error" statements
+	var (
+		obj      Object
+		index    []int
+		indirect bool
+	)
+
+	sel := e.Sel.Name
+	// If the identifier refers to a package, handle everything here
+	// so we don't need a "package" mode for operands: package names
+	// can only appear in qualified identifiers which are mapped to
+	// selector expressions.
+	if ident, ok := e.X.(*ast.Ident); ok {
+		_, obj := check.scope.LookupParent(ident.Name, check.pos)
+		if pkg, _ := obj.(*PkgName); pkg != nil {
+			assert(pkg.pkg == check.pkg)
+			check.recordUse(ident, pkg)
+			pkg.used = true
+			exp := pkg.imported.scope.Lookup(sel)
+			if exp == nil {
+				if !pkg.imported.fake {
+					check.errorf(e.Pos(), "%s not declared by package %s", sel, ident)
+				}
+				goto Error
+			}
+			if !exp.Exported() {
+				check.errorf(e.Pos(), "%s not exported by package %s", sel, ident)
+				// ok to continue
+			}
+			check.recordUse(e.Sel, exp)
+			// Simplified version of the code for *ast.Idents:
+			// - imported objects are always fully initialized
+			switch exp := exp.(type) {
+			case *Const:
+				assert(exp.Val() != nil)
+				x.mode = constant_
+				x.typ = exp.typ
+				x.val = exp.val
+			case *TypeName:
+				x.mode = typexpr
+				x.typ = exp.typ
+			case *Var:
+				x.mode = variable
+				x.typ = exp.typ
+			case *Func:
+				x.mode = value
+				x.typ = exp.typ
+			case *Builtin:
+				x.mode = builtin
+				x.typ = exp.typ
+				x.id = exp.id
+			default:
+				unreachable()
+			}
+			x.expr = e
+			return
+		}
+	}
+
+	check.exprOrType(x, e.X)
+	if x.mode == invalid {
+		goto Error
+	}
+
+	obj, index, indirect = LookupFieldOrMethod(x.typ, x.mode == variable, check.pkg, sel)
+	if obj == nil {
+		switch {
+		case index != nil:
+			// TODO(gri) should provide actual type where the conflict happens
+			check.invalidOp(e.Pos(), "ambiguous selector %s", sel)
+		case indirect:
+			check.invalidOp(e.Pos(), "%s is not in method set of %s", sel, x.typ)
+		default:
+			check.invalidOp(e.Pos(), "%s has no field or method %s", x, sel)
+		}
+		goto Error
+	}
+
+	if x.mode == typexpr {
+		// method expression
+		m, _ := obj.(*Func)
+		if m == nil {
+			check.invalidOp(e.Pos(), "%s has no method %s", x, sel)
+			goto Error
+		}
+
+		check.recordSelection(e, MethodExpr, x.typ, m, index, indirect)
+
+		// the receiver type becomes the type of the first function
+		// argument of the method expression's function type
+		var params []*Var
+		sig := m.typ.(*Signature)
+		if sig.params != nil {
+			params = sig.params.vars
+		}
+		x.mode = value
+		x.typ = &Signature{
+			params:   NewTuple(append([]*Var{NewVar(token.NoPos, check.pkg, "", x.typ)}, params...)...),
+			results:  sig.results,
+			variadic: sig.variadic,
+		}
+
+		check.addDeclDep(m)
+
+	} else {
+		// regular selector
+		switch obj := obj.(type) {
+		case *Var:
+			check.recordSelection(e, FieldVal, x.typ, obj, index, indirect)
+			if x.mode == variable || indirect {
+				x.mode = variable
+			} else {
+				x.mode = value
+			}
+			x.typ = obj.typ
+
+		case *Func:
+			// TODO(gri) If we needed to take into account the receiver's
+			// addressability, should we report the type &(x.typ) instead?
+			check.recordSelection(e, MethodVal, x.typ, obj, index, indirect)
+
+			if debug {
+				// Verify that LookupFieldOrMethod and MethodSet.Lookup agree.
+				typ := x.typ
+				if x.mode == variable {
+					// If typ is not an (unnamed) pointer or an interface,
+					// use *typ instead, because the method set of *typ
+					// includes the methods of typ.
+					// Variables are addressable, so we can always take their
+					// address.
+					if _, ok := typ.(*Pointer); !ok && !IsInterface(typ) {
+						typ = &Pointer{base: typ}
+					}
+				}
+				// If we created a synthetic pointer type above, we will throw
+				// away the method set computed here after use.
+				// TODO(gri) Method set computation should probably always compute
+				// both, the value and the pointer receiver method set and represent
+				// them in a single structure.
+				// TODO(gri) Consider also using a method set cache for the lifetime
+				// of checker once we rely on MethodSet lookup instead of individual
+				// lookup.
+				mset := NewMethodSet(typ)
+				if m := mset.Lookup(check.pkg, sel); m == nil || m.obj != obj {
+					check.dump("%s: (%s).%v -> %s", e.Pos(), typ, obj.name, m)
+					check.dump("%s\n", mset)
+					panic("method sets and lookup don't agree")
+				}
+			}
+
+			x.mode = value
+
+			// remove receiver
+			sig := *obj.typ.(*Signature)
+			sig.recv = nil
+			x.typ = &sig
+
+			check.addDeclDep(obj)
+
+		default:
+			unreachable()
+		}
+	}
+
+	// everything went well
+	x.expr = e
+	return
+
+Error:
+	x.mode = invalid
+	x.expr = e
+}
diff --git a/third_party/gofrontend/libgo/go/go/types/check.go b/third_party/gofrontend/libgo/go/go/types/check.go
new file mode 100644
index 0000000..bb0b074
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/go/types/check.go
@@ -0,0 +1,358 @@
+// Copyright 2011 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.
+
+// This file implements the Check function, which drives type-checking.
+
+package types
+
+import (
+	"go/ast"
+	"go/constant"
+	"go/token"
+)
+
+// debugging/development support
+const (
+	debug = false // leave on during development
+	trace = false // turn on for detailed type resolution traces
+)
+
+// If Strict is set, the type-checker enforces additional
+// rules not specified by the Go 1 spec, but which will
+// catch guaranteed run-time errors if the respective
+// code is executed. In other words, programs passing in
+// Strict mode are Go 1 compliant, but not all Go 1 programs
+// will pass in Strict mode. The additional rules are:
+//
+// - A type assertion x.(T) where T is an interface type
+//   is invalid if any (statically known) method that exists
+//   for both x and T have different signatures.
+//
+const strict = false
+
+// exprInfo stores information about an untyped expression.
+type exprInfo struct {
+	isLhs bool // expression is lhs operand of a shift with delayed type-check
+	mode  operandMode
+	typ   *Basic
+	val   constant.Value // constant value; or nil (if not a constant)
+}
+
+// funcInfo stores the information required for type-checking a function.
+type funcInfo struct {
+	name string    // for debugging/tracing only
+	decl *declInfo // for cycle detection
+	sig  *Signature
+	body *ast.BlockStmt
+}
+
+// A context represents the context within which an object is type-checked.
+type context struct {
+	decl          *declInfo      // package-level declaration whose init expression/function body is checked
+	scope         *Scope         // top-most scope for lookups
+	iota          constant.Value // value of iota in a constant declaration; nil otherwise
+	sig           *Signature     // function signature if inside a function; nil otherwise
+	hasLabel      bool           // set if a function makes use of labels (only ~1% of functions); unused outside functions
+	hasCallOrRecv bool           // set if an expression contains a function call or channel receive operation
+}
+
+// A Checker maintains the state of the type checker.
+// It must be created with NewChecker.
+type Checker struct {
+	// package information
+	// (initialized by NewChecker, valid for the life-time of checker)
+	conf *Config
+	fset *token.FileSet
+	pkg  *Package
+	*Info
+	objMap map[Object]*declInfo // maps package-level object to declaration info
+
+	// information collected during type-checking of a set of package files
+	// (initialized by Files, valid only for the duration of check.Files;
+	// maps and lists are allocated on demand)
+	files            []*ast.File                       // package files
+	unusedDotImports map[*Scope]map[*Package]token.Pos // positions of unused dot-imported packages for each file scope
+
+	firstErr error                 // first error encountered
+	methods  map[string][]*Func    // maps type names to associated methods
+	untyped  map[ast.Expr]exprInfo // map of expressions without final type
+	funcs    []funcInfo            // list of functions to type-check
+	delayed  []func()              // delayed checks requiring fully setup types
+
+	// context within which the current object is type-checked
+	// (valid only for the duration of type-checking a specific object)
+	context
+	pos token.Pos // if valid, identifiers are looked up as if at position pos (used by Eval)
+
+	// debugging
+	indent int // indentation for tracing
+}
+
+// addUnusedImport adds the position of a dot-imported package
+// pkg to the map of dot imports for the given file scope.
+func (check *Checker) addUnusedDotImport(scope *Scope, pkg *Package, pos token.Pos) {
+	mm := check.unusedDotImports
+	if mm == nil {
+		mm = make(map[*Scope]map[*Package]token.Pos)
+		check.unusedDotImports = mm
+	}
+	m := mm[scope]
+	if m == nil {
+		m = make(map[*Package]token.Pos)
+		mm[scope] = m
+	}
+	m[pkg] = pos
+}
+
+// addDeclDep adds the dependency edge (check.decl -> to) if check.decl exists
+func (check *Checker) addDeclDep(to Object) {
+	from := check.decl
+	if from == nil {
+		return // not in a package-level init expression
+	}
+	if _, found := check.objMap[to]; !found {
+		return // to is not a package-level object
+	}
+	from.addDep(to)
+}
+
+func (check *Checker) assocMethod(tname string, meth *Func) {
+	m := check.methods
+	if m == nil {
+		m = make(map[string][]*Func)
+		check.methods = m
+	}
+	m[tname] = append(m[tname], meth)
+}
+
+func (check *Checker) rememberUntyped(e ast.Expr, lhs bool, mode operandMode, typ *Basic, val constant.Value) {
+	m := check.untyped
+	if m == nil {
+		m = make(map[ast.Expr]exprInfo)
+		check.untyped = m
+	}
+	m[e] = exprInfo{lhs, mode, typ, val}
+}
+
+func (check *Checker) later(name string, decl *declInfo, sig *Signature, body *ast.BlockStmt) {
+	check.funcs = append(check.funcs, funcInfo{name, decl, sig, body})
+}
+
+func (check *Checker) delay(f func()) {
+	check.delayed = append(check.delayed, f)
+}
+
+// NewChecker returns a new Checker instance for a given package.
+// Package files may be added incrementally via checker.Files.
+func NewChecker(conf *Config, fset *token.FileSet, pkg *Package, info *Info) *Checker {
+	// make sure we have a configuration
+	if conf == nil {
+		conf = new(Config)
+	}
+
+	// make sure we have an info struct
+	if info == nil {
+		info = new(Info)
+	}
+
+	return &Checker{
+		conf:   conf,
+		fset:   fset,
+		pkg:    pkg,
+		Info:   info,
+		objMap: make(map[Object]*declInfo),
+	}
+}
+
+// initFiles initializes the files-specific portion of checker.
+// The provided files must all belong to the same package.
+func (check *Checker) initFiles(files []*ast.File) {
+	// start with a clean slate (check.Files may be called multiple times)
+	check.files = nil
+	check.unusedDotImports = nil
+
+	check.firstErr = nil
+	check.methods = nil
+	check.untyped = nil
+	check.funcs = nil
+	check.delayed = nil
+
+	// determine package name and collect valid files
+	pkg := check.pkg
+	for _, file := range files {
+		switch name := file.Name.Name; pkg.name {
+		case "":
+			if name != "_" {
+				pkg.name = name
+			} else {
+				check.errorf(file.Name.Pos(), "invalid package name _")
+			}
+			fallthrough
+
+		case name:
+			check.files = append(check.files, file)
+
+		default:
+			check.errorf(file.Package, "package %s; expected %s", name, pkg.name)
+			// ignore this file
+		}
+	}
+}
+
+// A bailout panic is used for early termination.
+type bailout struct{}
+
+func (check *Checker) handleBailout(err *error) {
+	switch p := recover().(type) {
+	case nil, bailout:
+		// normal return or early exit
+		*err = check.firstErr
+	default:
+		// re-panic
+		panic(p)
+	}
+}
+
+// Files checks the provided files as part of the checker's package.
+func (check *Checker) Files(files []*ast.File) (err error) {
+	defer check.handleBailout(&err)
+
+	check.initFiles(files)
+
+	check.collectObjects()
+
+	check.packageObjects(check.resolveOrder())
+
+	check.functionBodies()
+
+	check.initOrder()
+
+	if !check.conf.DisableUnusedImportCheck {
+		check.unusedImports()
+	}
+
+	// perform delayed checks
+	for _, f := range check.delayed {
+		f()
+	}
+
+	check.recordUntyped()
+
+	check.pkg.complete = true
+	return
+}
+
+func (check *Checker) recordUntyped() {
+	if !debug && check.Types == nil {
+		return // nothing to do
+	}
+
+	for x, info := range check.untyped {
+		if debug && isTyped(info.typ) {
+			check.dump("%s: %s (type %s) is typed", x.Pos(), x, info.typ)
+			unreachable()
+		}
+		check.recordTypeAndValue(x, info.mode, info.typ, info.val)
+	}
+}
+
+func (check *Checker) recordTypeAndValue(x ast.Expr, mode operandMode, typ Type, val constant.Value) {
+	assert(x != nil)
+	assert(typ != nil)
+	if mode == invalid {
+		return // omit
+	}
+	assert(typ != nil)
+	if mode == constant_ {
+		assert(val != nil)
+		assert(typ == Typ[Invalid] || isConstType(typ))
+	}
+	if m := check.Types; m != nil {
+		m[x] = TypeAndValue{mode, typ, val}
+	}
+}
+
+func (check *Checker) recordBuiltinType(f ast.Expr, sig *Signature) {
+	// f must be a (possibly parenthesized) identifier denoting a built-in
+	// (built-ins in package unsafe always produce a constant result and
+	// we don't record their signatures, so we don't see qualified idents
+	// here): record the signature for f and possible children.
+	for {
+		check.recordTypeAndValue(f, builtin, sig, nil)
+		switch p := f.(type) {
+		case *ast.Ident:
+			return // we're done
+		case *ast.ParenExpr:
+			f = p.X
+		default:
+			unreachable()
+		}
+	}
+}
+
+func (check *Checker) recordCommaOkTypes(x ast.Expr, a [2]Type) {
+	assert(x != nil)
+	if a[0] == nil || a[1] == nil {
+		return
+	}
+	assert(isTyped(a[0]) && isTyped(a[1]) && isBoolean(a[1]))
+	if m := check.Types; m != nil {
+		for {
+			tv := m[x]
+			assert(tv.Type != nil) // should have been recorded already
+			pos := x.Pos()
+			tv.Type = NewTuple(
+				NewVar(pos, check.pkg, "", a[0]),
+				NewVar(pos, check.pkg, "", a[1]),
+			)
+			m[x] = tv
+			// if x is a parenthesized expression (p.X), update p.X
+			p, _ := x.(*ast.ParenExpr)
+			if p == nil {
+				break
+			}
+			x = p.X
+		}
+	}
+}
+
+func (check *Checker) recordDef(id *ast.Ident, obj Object) {
+	assert(id != nil)
+	if m := check.Defs; m != nil {
+		m[id] = obj
+	}
+}
+
+func (check *Checker) recordUse(id *ast.Ident, obj Object) {
+	assert(id != nil)
+	assert(obj != nil)
+	if m := check.Uses; m != nil {
+		m[id] = obj
+	}
+}
+
+func (check *Checker) recordImplicit(node ast.Node, obj Object) {
+	assert(node != nil)
+	assert(obj != nil)
+	if m := check.Implicits; m != nil {
+		m[node] = obj
+	}
+}
+
+func (check *Checker) recordSelection(x *ast.SelectorExpr, kind SelectionKind, recv Type, obj Object, index []int, indirect bool) {
+	assert(obj != nil && (recv == nil || len(index) > 0))
+	check.recordUse(x.Sel, obj)
+	// TODO(gri) Should we also call recordTypeAndValue?
+	if m := check.Selections; m != nil {
+		m[x] = &Selection{kind, recv, obj, index, indirect}
+	}
+}
+
+func (check *Checker) recordScope(node ast.Node, scope *Scope) {
+	assert(node != nil)
+	assert(scope != nil)
+	if m := check.Scopes; m != nil {
+		m[node] = scope
+	}
+}
diff --git a/third_party/gofrontend/libgo/go/go/types/check_test.go b/third_party/gofrontend/libgo/go/go/types/check_test.go
new file mode 100644
index 0000000..5e34c65
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/go/types/check_test.go
@@ -0,0 +1,298 @@
+// Copyright 2011 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.
+
+// This file implements a typechecker test harness. The packages specified
+// in tests are typechecked. Error messages reported by the typechecker are
+// compared against the error messages expected in the test files.
+//
+// Expected errors are indicated in the test files by putting a comment
+// of the form /* ERROR "rx" */ immediately following an offending token.
+// The harness will verify that an error matching the regular expression
+// rx is reported at that source position. Consecutive comments may be
+// used to indicate multiple errors for the same token position.
+//
+// For instance, the following test file indicates that a "not declared"
+// error should be reported for the undeclared variable x:
+//
+//	package p
+//	func f() {
+//		_ = x /* ERROR "not declared" */ + 1
+//	}
+
+// TODO(gri) Also collect strict mode errors of the form /* STRICT ... */
+//           and test against strict mode.
+
+package types_test
+
+import (
+	"flag"
+	"go/ast"
+	"go/importer"
+	"go/parser"
+	"go/scanner"
+	"go/token"
+	"internal/testenv"
+	"io/ioutil"
+	"regexp"
+	"strings"
+	"testing"
+
+	. "go/types"
+)
+
+var (
+	listErrors = flag.Bool("list", false, "list errors")
+	testFiles  = flag.String("files", "", "space-separated list of test files")
+)
+
+// The test filenames do not end in .go so that they are invisible
+// to gofmt since they contain comments that must not change their
+// positions relative to surrounding tokens.
+
+// Each tests entry is list of files belonging to the same package.
+var tests = [][]string{
+	{"testdata/errors.src"},
+	{"testdata/importdecl0a.src", "testdata/importdecl0b.src"},
+	{"testdata/importdecl1a.src", "testdata/importdecl1b.src"},
+	{"testdata/cycles.src"},
+	{"testdata/cycles1.src"},
+	{"testdata/cycles2.src"},
+	{"testdata/cycles3.src"},
+	{"testdata/cycles4.src"},
+	{"testdata/init0.src"},
+	{"testdata/init1.src"},
+	{"testdata/init2.src"},
+	{"testdata/decls0.src"},
+	{"testdata/decls1.src"},
+	{"testdata/decls2a.src", "testdata/decls2b.src"},
+	{"testdata/decls3.src"},
+	{"testdata/const0.src"},
+	{"testdata/const1.src"},
+	{"testdata/constdecl.src"},
+	{"testdata/vardecl.src"},
+	{"testdata/expr0.src"},
+	{"testdata/expr1.src"},
+	{"testdata/expr2.src"},
+	{"testdata/expr3.src"},
+	{"testdata/methodsets.src"},
+	{"testdata/shifts.src"},
+	{"testdata/builtins.src"},
+	{"testdata/conversions.src"},
+	{"testdata/stmt0.src"},
+	{"testdata/stmt1.src"},
+	{"testdata/gotos.src"},
+	{"testdata/labels.src"},
+	{"testdata/issues.src"},
+	{"testdata/blank.src"},
+}
+
+var fset = token.NewFileSet()
+
+// Positioned errors are of the form filename:line:column: message .
+var posMsgRx = regexp.MustCompile(`^(.*:[0-9]+:[0-9]+): *(.*)`)
+
+// splitError splits an error's error message into a position string
+// and the actual error message. If there's no position information,
+// pos is the empty string, and msg is the entire error message.
+//
+func splitError(err error) (pos, msg string) {
+	msg = err.Error()
+	if m := posMsgRx.FindStringSubmatch(msg); len(m) == 3 {
+		pos = m[1]
+		msg = m[2]
+	}
+	return
+}
+
+func parseFiles(t *testing.T, filenames []string) ([]*ast.File, []error) {
+	var files []*ast.File
+	var errlist []error
+	for _, filename := range filenames {
+		file, err := parser.ParseFile(fset, filename, nil, parser.AllErrors)
+		if file == nil {
+			t.Fatalf("%s: %s", filename, err)
+		}
+		files = append(files, file)
+		if err != nil {
+			if list, _ := err.(scanner.ErrorList); len(list) > 0 {
+				for _, err := range list {
+					errlist = append(errlist, err)
+				}
+			} else {
+				errlist = append(errlist, err)
+			}
+		}
+	}
+	return files, errlist
+}
+
+// ERROR comments must start with text `ERROR "rx"` or `ERROR rx` where
+// rx is a regular expression that matches the expected error message.
+// Space around "rx" or rx is ignored. Use the form `ERROR HERE "rx"`
+// for error messages that are located immediately after rather than
+// at a token's position.
+//
+var errRx = regexp.MustCompile(`^ *ERROR *(HERE)? *"?([^"]*)"?`)
+
+// errMap collects the regular expressions of ERROR comments found
+// in files and returns them as a map of error positions to error messages.
+//
+func errMap(t *testing.T, testname string, files []*ast.File) map[string][]string {
+	// map of position strings to lists of error message patterns
+	errmap := make(map[string][]string)
+
+	for _, file := range files {
+		filename := fset.Position(file.Package).Filename
+		src, err := ioutil.ReadFile(filename)
+		if err != nil {
+			t.Fatalf("%s: could not read %s", testname, filename)
+		}
+
+		var s scanner.Scanner
+		s.Init(fset.AddFile(filename, -1, len(src)), src, nil, scanner.ScanComments)
+		var prev token.Pos // position of last non-comment, non-semicolon token
+		var here token.Pos // position immediately after the token at position prev
+
+	scanFile:
+		for {
+			pos, tok, lit := s.Scan()
+			switch tok {
+			case token.EOF:
+				break scanFile
+			case token.COMMENT:
+				if lit[1] == '*' {
+					lit = lit[:len(lit)-2] // strip trailing */
+				}
+				if s := errRx.FindStringSubmatch(lit[2:]); len(s) == 3 {
+					pos := prev
+					if s[1] == "HERE" {
+						pos = here
+					}
+					p := fset.Position(pos).String()
+					errmap[p] = append(errmap[p], strings.TrimSpace(s[2]))
+				}
+			case token.SEMICOLON:
+				// ignore automatically inserted semicolon
+				if lit == "\n" {
+					continue scanFile
+				}
+				fallthrough
+			default:
+				prev = pos
+				var l int // token length
+				if tok.IsLiteral() {
+					l = len(lit)
+				} else {
+					l = len(tok.String())
+				}
+				here = prev + token.Pos(l)
+			}
+		}
+	}
+
+	return errmap
+}
+
+func eliminate(t *testing.T, errmap map[string][]string, errlist []error) {
+	for _, err := range errlist {
+		pos, gotMsg := splitError(err)
+		list := errmap[pos]
+		index := -1 // list index of matching message, if any
+		// we expect one of the messages in list to match the error at pos
+		for i, wantRx := range list {
+			rx, err := regexp.Compile(wantRx)
+			if err != nil {
+				t.Errorf("%s: %v", pos, err)
+				continue
+			}
+			if rx.MatchString(gotMsg) {
+				index = i
+				break
+			}
+		}
+		if index >= 0 {
+			// eliminate from list
+			if n := len(list) - 1; n > 0 {
+				// not the last entry - swap in last element and shorten list by 1
+				list[index] = list[n]
+				errmap[pos] = list[:n]
+			} else {
+				// last entry - remove list from map
+				delete(errmap, pos)
+			}
+		} else {
+			t.Errorf("%s: no error expected: %q", pos, gotMsg)
+		}
+	}
+}
+
+func checkFiles(t *testing.T, testfiles []string) {
+	// parse files and collect parser errors
+	files, errlist := parseFiles(t, testfiles)
+
+	pkgName := "<no package>"
+	if len(files) > 0 {
+		pkgName = files[0].Name.Name
+	}
+
+	if *listErrors && len(errlist) > 0 {
+		t.Errorf("--- %s:", pkgName)
+		for _, err := range errlist {
+			t.Error(err)
+		}
+	}
+
+	// typecheck and collect typechecker errors
+	var conf Config
+	conf.Importer = importer.Default()
+	conf.Error = func(err error) {
+		if *listErrors {
+			t.Error(err)
+			return
+		}
+		// Ignore secondary error messages starting with "\t";
+		// they are clarifying messages for a primary error.
+		if !strings.Contains(err.Error(), ": \t") {
+			errlist = append(errlist, err)
+		}
+	}
+	conf.Check(pkgName, fset, files, nil)
+
+	if *listErrors {
+		return
+	}
+
+	// match and eliminate errors;
+	// we are expecting the following errors
+	errmap := errMap(t, pkgName, files)
+	eliminate(t, errmap, errlist)
+
+	// there should be no expected errors left
+	if len(errmap) > 0 {
+		t.Errorf("--- %s: %d source positions with expected (but not reported) errors:", pkgName, len(errmap))
+		for pos, list := range errmap {
+			for _, rx := range list {
+				t.Errorf("%s: %q", pos, rx)
+			}
+		}
+	}
+}
+
+func TestCheck(t *testing.T) {
+	testenv.MustHaveGoBuild(t)
+
+	// Declare builtins for testing.
+	DefPredeclaredTestFuncs()
+
+	// If explicit test files are specified, only check those.
+	if files := *testFiles; files != "" {
+		checkFiles(t, strings.Split(files, " "))
+		return
+	}
+
+	// Otherwise, run all the tests.
+	for _, files := range tests {
+		checkFiles(t, files)
+	}
+}
diff --git a/third_party/gofrontend/libgo/go/go/types/conversions.go b/third_party/gofrontend/libgo/go/go/types/conversions.go
new file mode 100644
index 0000000..74826ce
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/go/types/conversions.go
@@ -0,0 +1,146 @@
+// Copyright 2012 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.
+
+// This file implements typechecking of conversions.
+
+package types
+
+import "go/constant"
+
+// Conversion type-checks the conversion T(x).
+// The result is in x.
+func (check *Checker) conversion(x *operand, T Type) {
+	constArg := x.mode == constant_
+
+	var ok bool
+	switch {
+	case constArg && isConstType(T):
+		// constant conversion
+		switch t := T.Underlying().(*Basic); {
+		case representableConst(x.val, check.conf, t.kind, &x.val):
+			ok = true
+		case isInteger(x.typ) && isString(t):
+			codepoint := int64(-1)
+			if i, ok := constant.Int64Val(x.val); ok {
+				codepoint = i
+			}
+			// If codepoint < 0 the absolute value is too large (or unknown) for
+			// conversion. This is the same as converting any other out-of-range
+			// value - let string(codepoint) do the work.
+			x.val = constant.MakeString(string(codepoint))
+			ok = true
+		}
+	case x.convertibleTo(check.conf, T):
+		// non-constant conversion
+		x.mode = value
+		ok = true
+	}
+
+	if !ok {
+		check.errorf(x.pos(), "cannot convert %s to %s", x, T)
+		x.mode = invalid
+		return
+	}
+
+	// The conversion argument types are final. For untyped values the
+	// conversion provides the type, per the spec: "A constant may be
+	// given a type explicitly by a constant declaration or conversion,...".
+	final := x.typ
+	if isUntyped(x.typ) {
+		final = T
+		// - For conversions to interfaces, use the argument's default type.
+		// - For conversions of untyped constants to non-constant types, also
+		//   use the default type (e.g., []byte("foo") should report string
+		//   not []byte as type for the constant "foo").
+		// - Keep untyped nil for untyped nil arguments.
+		if IsInterface(T) || constArg && !isConstType(T) {
+			final = defaultType(x.typ)
+		}
+		check.updateExprType(x.expr, final, true)
+	}
+
+	x.typ = T
+}
+
+func (x *operand) convertibleTo(conf *Config, T Type) bool {
+	// "x is assignable to T"
+	if x.assignableTo(conf, T) {
+		return true
+	}
+
+	// "x's type and T have identical underlying types"
+	V := x.typ
+	Vu := V.Underlying()
+	Tu := T.Underlying()
+	if Identical(Vu, Tu) {
+		return true
+	}
+
+	// "x's type and T are unnamed pointer types and their pointer base types have identical underlying types"
+	if V, ok := V.(*Pointer); ok {
+		if T, ok := T.(*Pointer); ok {
+			if Identical(V.base.Underlying(), T.base.Underlying()) {
+				return true
+			}
+		}
+	}
+
+	// "x's type and T are both integer or floating point types"
+	if (isInteger(V) || isFloat(V)) && (isInteger(T) || isFloat(T)) {
+		return true
+	}
+
+	// "x's type and T are both complex types"
+	if isComplex(V) && isComplex(T) {
+		return true
+	}
+
+	// "x is an integer or a slice of bytes or runes and T is a string type"
+	if (isInteger(V) || isBytesOrRunes(Vu)) && isString(T) {
+		return true
+	}
+
+	// "x is a string and T is a slice of bytes or runes"
+	if isString(V) && isBytesOrRunes(Tu) {
+		return true
+	}
+
+	// package unsafe:
+	// "any pointer or value of underlying type uintptr can be converted into a unsafe.Pointer"
+	if (isPointer(Vu) || isUintptr(Vu)) && isUnsafePointer(T) {
+		return true
+	}
+	// "and vice versa"
+	if isUnsafePointer(V) && (isPointer(Tu) || isUintptr(Tu)) {
+		return true
+	}
+
+	return false
+}
+
+func isUintptr(typ Type) bool {
+	t, ok := typ.Underlying().(*Basic)
+	return ok && t.kind == Uintptr
+}
+
+func isUnsafePointer(typ Type) bool {
+	// TODO(gri): Is this (typ.Underlying() instead of just typ) correct?
+	//            The spec does not say so, but gc claims it is. See also
+	//            issue 6326.
+	t, ok := typ.Underlying().(*Basic)
+	return ok && t.kind == UnsafePointer
+}
+
+func isPointer(typ Type) bool {
+	_, ok := typ.Underlying().(*Pointer)
+	return ok
+}
+
+func isBytesOrRunes(typ Type) bool {
+	if s, ok := typ.(*Slice); ok {
+		t, ok := s.elem.Underlying().(*Basic)
+		return ok && (t.kind == Byte || t.kind == Rune)
+	}
+	return false
+}
diff --git a/third_party/gofrontend/libgo/go/go/types/decl.go b/third_party/gofrontend/libgo/go/go/types/decl.go
new file mode 100644
index 0000000..8e9e5f3
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/go/types/decl.go
@@ -0,0 +1,430 @@
+// 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.
+
+package types
+
+import (
+	"go/ast"
+	"go/constant"
+	"go/token"
+)
+
+func (check *Checker) reportAltDecl(obj Object) {
+	if pos := obj.Pos(); pos.IsValid() {
+		// We use "other" rather than "previous" here because
+		// the first declaration seen may not be textually
+		// earlier in the source.
+		check.errorf(pos, "\tother declaration of %s", obj.Name()) // secondary error, \t indented
+	}
+}
+
+func (check *Checker) declare(scope *Scope, id *ast.Ident, obj Object, pos token.Pos) {
+	// spec: "The blank identifier, represented by the underscore
+	// character _, may be used in a declaration like any other
+	// identifier but the declaration does not introduce a new
+	// binding."
+	if obj.Name() != "_" {
+		if alt := scope.Insert(obj); alt != nil {
+			check.errorf(obj.Pos(), "%s redeclared in this block", obj.Name())
+			check.reportAltDecl(alt)
+			return
+		}
+		obj.setScopePos(pos)
+	}
+	if id != nil {
+		check.recordDef(id, obj)
+	}
+}
+
+// objDecl type-checks the declaration of obj in its respective (file) context.
+// See check.typ for the details on def and path.
+func (check *Checker) objDecl(obj Object, def *Named, path []*TypeName) {
+	if obj.Type() != nil {
+		return // already checked - nothing to do
+	}
+
+	if trace {
+		check.trace(obj.Pos(), "-- declaring %s", obj.Name())
+		check.indent++
+		defer func() {
+			check.indent--
+			check.trace(obj.Pos(), "=> %s", obj)
+		}()
+	}
+
+	d := check.objMap[obj]
+	if d == nil {
+		check.dump("%s: %s should have been declared", obj.Pos(), obj.Name())
+		unreachable()
+	}
+
+	// save/restore current context and setup object context
+	defer func(ctxt context) {
+		check.context = ctxt
+	}(check.context)
+	check.context = context{
+		scope: d.file,
+	}
+
+	// Const and var declarations must not have initialization
+	// cycles. We track them by remembering the current declaration
+	// in check.decl. Initialization expressions depending on other
+	// consts, vars, or functions, add dependencies to the current
+	// check.decl.
+	switch obj := obj.(type) {
+	case *Const:
+		check.decl = d // new package-level const decl
+		check.constDecl(obj, d.typ, d.init)
+	case *Var:
+		check.decl = d // new package-level var decl
+		check.varDecl(obj, d.lhs, d.typ, d.init)
+	case *TypeName:
+		// invalid recursive types are detected via path
+		check.typeDecl(obj, d.typ, def, path)
+	case *Func:
+		// functions may be recursive - no need to track dependencies
+		check.funcDecl(obj, d)
+	default:
+		unreachable()
+	}
+}
+
+func (check *Checker) constDecl(obj *Const, typ, init ast.Expr) {
+	assert(obj.typ == nil)
+
+	if obj.visited {
+		obj.typ = Typ[Invalid]
+		return
+	}
+	obj.visited = true
+
+	// use the correct value of iota
+	assert(check.iota == nil)
+	check.iota = obj.val
+	defer func() { check.iota = nil }()
+
+	// provide valid constant value under all circumstances
+	obj.val = constant.MakeUnknown()
+
+	// determine type, if any
+	if typ != nil {
+		t := check.typ(typ)
+		if !isConstType(t) {
+			check.errorf(typ.Pos(), "invalid constant type %s", t)
+			obj.typ = Typ[Invalid]
+			return
+		}
+		obj.typ = t
+	}
+
+	// check initialization
+	var x operand
+	if init != nil {
+		check.expr(&x, init)
+	}
+	check.initConst(obj, &x)
+}
+
+func (check *Checker) varDecl(obj *Var, lhs []*Var, typ, init ast.Expr) {
+	assert(obj.typ == nil)
+
+	if obj.visited {
+		obj.typ = Typ[Invalid]
+		return
+	}
+	obj.visited = true
+
+	// var declarations cannot use iota
+	assert(check.iota == nil)
+
+	// determine type, if any
+	if typ != nil {
+		obj.typ = check.typ(typ)
+	}
+
+	// check initialization
+	if init == nil {
+		if typ == nil {
+			// error reported before by arityMatch
+			obj.typ = Typ[Invalid]
+		}
+		return
+	}
+
+	if lhs == nil || len(lhs) == 1 {
+		assert(lhs == nil || lhs[0] == obj)
+		var x operand
+		check.expr(&x, init)
+		check.initVar(obj, &x, false)
+		return
+	}
+
+	if debug {
+		// obj must be one of lhs
+		found := false
+		for _, lhs := range lhs {
+			if obj == lhs {
+				found = true
+				break
+			}
+		}
+		if !found {
+			panic("inconsistent lhs")
+		}
+	}
+	check.initVars(lhs, []ast.Expr{init}, token.NoPos)
+}
+
+// underlying returns the underlying type of typ; possibly by following
+// forward chains of named types. Such chains only exist while named types
+// are incomplete.
+func underlying(typ Type) Type {
+	for {
+		n, _ := typ.(*Named)
+		if n == nil {
+			break
+		}
+		typ = n.underlying
+	}
+	return typ
+}
+
+func (n *Named) setUnderlying(typ Type) {
+	if n != nil {
+		n.underlying = typ
+	}
+}
+
+func (check *Checker) typeDecl(obj *TypeName, typ ast.Expr, def *Named, path []*TypeName) {
+	assert(obj.typ == nil)
+
+	// type declarations cannot use iota
+	assert(check.iota == nil)
+
+	named := &Named{obj: obj}
+	def.setUnderlying(named)
+	obj.typ = named // make sure recursive type declarations terminate
+
+	// determine underlying type of named
+	check.typExpr(typ, named, append(path, obj))
+
+	// The underlying type of named may be itself a named type that is
+	// incomplete:
+	//
+	//	type (
+	//		A B
+	//		B *C
+	//		C A
+	//	)
+	//
+	// The type of C is the (named) type of A which is incomplete,
+	// and which has as its underlying type the named type B.
+	// Determine the (final, unnamed) underlying type by resolving
+	// any forward chain (they always end in an unnamed type).
+	named.underlying = underlying(named.underlying)
+
+	// check and add associated methods
+	// TODO(gri) It's easy to create pathological cases where the
+	// current approach is incorrect: In general we need to know
+	// and add all methods _before_ type-checking the type.
+	// See https://play.golang.org/p/WMpE0q2wK8
+	check.addMethodDecls(obj)
+}
+
+func (check *Checker) addMethodDecls(obj *TypeName) {
+	// get associated methods
+	methods := check.methods[obj.name]
+	if len(methods) == 0 {
+		return // no methods
+	}
+	delete(check.methods, obj.name)
+
+	// use an objset to check for name conflicts
+	var mset objset
+
+	// spec: "If the base type is a struct type, the non-blank method
+	// and field names must be distinct."
+	base := obj.typ.(*Named)
+	if t, _ := base.underlying.(*Struct); t != nil {
+		for _, fld := range t.fields {
+			if fld.name != "_" {
+				assert(mset.insert(fld) == nil)
+			}
+		}
+	}
+
+	// Checker.Files may be called multiple times; additional package files
+	// may add methods to already type-checked types. Add pre-existing methods
+	// so that we can detect redeclarations.
+	for _, m := range base.methods {
+		assert(m.name != "_")
+		assert(mset.insert(m) == nil)
+	}
+
+	// type-check methods
+	for _, m := range methods {
+		// spec: "For a base type, the non-blank names of methods bound
+		// to it must be unique."
+		if m.name != "_" {
+			if alt := mset.insert(m); alt != nil {
+				switch alt.(type) {
+				case *Var:
+					check.errorf(m.pos, "field and method with the same name %s", m.name)
+				case *Func:
+					check.errorf(m.pos, "method %s already declared for %s", m.name, base)
+				default:
+					unreachable()
+				}
+				check.reportAltDecl(alt)
+				continue
+			}
+		}
+		check.objDecl(m, nil, nil)
+		// methods with blank _ names cannot be found - don't keep them
+		if m.name != "_" {
+			base.methods = append(base.methods, m)
+		}
+	}
+}
+
+func (check *Checker) funcDecl(obj *Func, decl *declInfo) {
+	assert(obj.typ == nil)
+
+	// func declarations cannot use iota
+	assert(check.iota == nil)
+
+	sig := new(Signature)
+	obj.typ = sig // guard against cycles
+	fdecl := decl.fdecl
+	check.funcType(sig, fdecl.Recv, fdecl.Type)
+	if sig.recv == nil && obj.name == "init" && (sig.params.Len() > 0 || sig.results.Len() > 0) {
+		check.errorf(fdecl.Pos(), "func init must have no arguments and no return values")
+		// ok to continue
+	}
+
+	// function body must be type-checked after global declarations
+	// (functions implemented elsewhere have no body)
+	if !check.conf.IgnoreFuncBodies && fdecl.Body != nil {
+		check.later(obj.name, decl, sig, fdecl.Body)
+	}
+}
+
+func (check *Checker) declStmt(decl ast.Decl) {
+	pkg := check.pkg
+
+	switch d := decl.(type) {
+	case *ast.BadDecl:
+		// ignore
+
+	case *ast.GenDecl:
+		var last *ast.ValueSpec // last ValueSpec with type or init exprs seen
+		for iota, spec := range d.Specs {
+			switch s := spec.(type) {
+			case *ast.ValueSpec:
+				switch d.Tok {
+				case token.CONST:
+					// determine which init exprs to use
+					switch {
+					case s.Type != nil || len(s.Values) > 0:
+						last = s
+					case last == nil:
+						last = new(ast.ValueSpec) // make sure last exists
+					}
+
+					// declare all constants
+					lhs := make([]*Const, len(s.Names))
+					for i, name := range s.Names {
+						obj := NewConst(name.Pos(), pkg, name.Name, nil, constant.MakeInt64(int64(iota)))
+						lhs[i] = obj
+
+						var init ast.Expr
+						if i < len(last.Values) {
+							init = last.Values[i]
+						}
+
+						check.constDecl(obj, last.Type, init)
+					}
+
+					check.arityMatch(s, last)
+
+					// spec: "The scope of a constant or variable identifier declared
+					// inside a function begins at the end of the ConstSpec or VarSpec
+					// (ShortVarDecl for short variable declarations) and ends at the
+					// end of the innermost containing block."
+					scopePos := s.End()
+					for i, name := range s.Names {
+						check.declare(check.scope, name, lhs[i], scopePos)
+					}
+
+				case token.VAR:
+					lhs0 := make([]*Var, len(s.Names))
+					for i, name := range s.Names {
+						lhs0[i] = NewVar(name.Pos(), pkg, name.Name, nil)
+					}
+
+					// initialize all variables
+					for i, obj := range lhs0 {
+						var lhs []*Var
+						var init ast.Expr
+						switch len(s.Values) {
+						case len(s.Names):
+							// lhs and rhs match
+							init = s.Values[i]
+						case 1:
+							// rhs is expected to be a multi-valued expression
+							lhs = lhs0
+							init = s.Values[0]
+						default:
+							if i < len(s.Values) {
+								init = s.Values[i]
+							}
+						}
+						check.varDecl(obj, lhs, s.Type, init)
+						if len(s.Values) == 1 {
+							// If we have a single lhs variable we are done either way.
+							// If we have a single rhs expression, it must be a multi-
+							// valued expression, in which case handling the first lhs
+							// variable will cause all lhs variables to have a type
+							// assigned, and we are done as well.
+							if debug {
+								for _, obj := range lhs0 {
+									assert(obj.typ != nil)
+								}
+							}
+							break
+						}
+					}
+
+					check.arityMatch(s, nil)
+
+					// declare all variables
+					// (only at this point are the variable scopes (parents) set)
+					scopePos := s.End() // see constant declarations
+					for i, name := range s.Names {
+						// see constant declarations
+						check.declare(check.scope, name, lhs0[i], scopePos)
+					}
+
+				default:
+					check.invalidAST(s.Pos(), "invalid token %s", d.Tok)
+				}
+
+			case *ast.TypeSpec:
+				obj := NewTypeName(s.Name.Pos(), pkg, s.Name.Name, nil)
+				// spec: "The scope of a type identifier declared inside a function
+				// begins at the identifier in the TypeSpec and ends at the end of
+				// the innermost containing block."
+				scopePos := s.Name.Pos()
+				check.declare(check.scope, s.Name, obj, scopePos)
+				check.typeDecl(obj, s.Type, nil, nil)
+
+			default:
+				check.invalidAST(s.Pos(), "const, type, or var declaration expected")
+			}
+		}
+
+	default:
+		check.invalidAST(d.Pos(), "unknown ast.Decl node %T", d)
+	}
+}
diff --git a/third_party/gofrontend/libgo/go/go/types/errors.go b/third_party/gofrontend/libgo/go/go/types/errors.go
new file mode 100644
index 0000000..0c0049b
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/go/types/errors.go
@@ -0,0 +1,103 @@
+// Copyright 2012 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.
+
+// This file implements various error reporters.
+
+package types
+
+import (
+	"fmt"
+	"go/ast"
+	"go/token"
+	"strings"
+)
+
+func assert(p bool) {
+	if !p {
+		panic("assertion failed")
+	}
+}
+
+func unreachable() {
+	panic("unreachable")
+}
+
+func (check *Checker) qualifier(pkg *Package) string {
+	if pkg != check.pkg {
+		return pkg.path
+	}
+	return ""
+}
+
+func (check *Checker) sprintf(format string, args ...interface{}) string {
+	for i, arg := range args {
+		switch a := arg.(type) {
+		case nil:
+			arg = "<nil>"
+		case operand:
+			panic("internal error: should always pass *operand")
+		case *operand:
+			arg = operandString(a, check.qualifier)
+		case token.Pos:
+			arg = check.fset.Position(a).String()
+		case ast.Expr:
+			arg = ExprString(a)
+		case Object:
+			arg = ObjectString(a, check.qualifier)
+		case Type:
+			arg = TypeString(a, check.qualifier)
+		}
+		args[i] = arg
+	}
+	return fmt.Sprintf(format, args...)
+}
+
+func (check *Checker) trace(pos token.Pos, format string, args ...interface{}) {
+	fmt.Printf("%s:\t%s%s\n",
+		check.fset.Position(pos),
+		strings.Repeat(".  ", check.indent),
+		check.sprintf(format, args...),
+	)
+}
+
+// dump is only needed for debugging
+func (check *Checker) dump(format string, args ...interface{}) {
+	fmt.Println(check.sprintf(format, args...))
+}
+
+func (check *Checker) err(pos token.Pos, msg string, soft bool) {
+	err := Error{check.fset, pos, msg, soft}
+	if check.firstErr == nil {
+		check.firstErr = err
+	}
+	f := check.conf.Error
+	if f == nil {
+		panic(bailout{}) // report only first error
+	}
+	f(err)
+}
+
+func (check *Checker) error(pos token.Pos, msg string) {
+	check.err(pos, msg, false)
+}
+
+func (check *Checker) errorf(pos token.Pos, format string, args ...interface{}) {
+	check.err(pos, check.sprintf(format, args...), false)
+}
+
+func (check *Checker) softErrorf(pos token.Pos, format string, args ...interface{}) {
+	check.err(pos, check.sprintf(format, args...), true)
+}
+
+func (check *Checker) invalidAST(pos token.Pos, format string, args ...interface{}) {
+	check.errorf(pos, "invalid AST: "+format, args...)
+}
+
+func (check *Checker) invalidArg(pos token.Pos, format string, args ...interface{}) {
+	check.errorf(pos, "invalid argument: "+format, args...)
+}
+
+func (check *Checker) invalidOp(pos token.Pos, format string, args ...interface{}) {
+	check.errorf(pos, "invalid operation: "+format, args...)
+}
diff --git a/third_party/gofrontend/libgo/go/go/types/eval.go b/third_party/gofrontend/libgo/go/go/types/eval.go
new file mode 100644
index 0000000..7b42ff1
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/go/types/eval.go
@@ -0,0 +1,83 @@
+// Copyright 2013 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 types
+
+import (
+	"fmt"
+	"go/parser"
+	"go/token"
+)
+
+// Eval returns the type and, if constant, the value for the
+// expression expr, evaluated at position pos of package pkg,
+// which must have been derived from type-checking an AST with
+// complete position information relative to the provided file
+// set.
+//
+// If the expression contains function literals, their bodies
+// are ignored (i.e., the bodies are not type-checked).
+//
+// If pkg == nil, the Universe scope is used and the provided
+// position pos is ignored. If pkg != nil, and pos is invalid,
+// the package scope is used. Otherwise, pos must belong to the
+// package.
+//
+// An error is returned if pos is not within the package or
+// if the node cannot be evaluated.
+//
+// Note: Eval should not be used instead of running Check to compute
+// types and values, but in addition to Check. Eval will re-evaluate
+// its argument each time, and it also does not know about the context
+// in which an expression is used (e.g., an assignment). Thus, top-
+// level untyped constants will return an untyped type rather then the
+// respective context-specific type.
+//
+func Eval(fset *token.FileSet, pkg *Package, pos token.Pos, expr string) (tv TypeAndValue, err error) {
+	// determine scope
+	var scope *Scope
+	if pkg == nil {
+		scope = Universe
+		pos = token.NoPos
+	} else if !pos.IsValid() {
+		scope = pkg.scope
+	} else {
+		// The package scope extent (position information) may be
+		// incorrect (files spread accross a wide range of fset
+		// positions) - ignore it and just consider its children
+		// (file scopes).
+		for _, fscope := range pkg.scope.children {
+			if scope = fscope.Innermost(pos); scope != nil {
+				break
+			}
+		}
+		if scope == nil || debug {
+			s := scope
+			for s != nil && s != pkg.scope {
+				s = s.parent
+			}
+			// s == nil || s == pkg.scope
+			if s == nil {
+				return TypeAndValue{}, fmt.Errorf("no position %s found in package %s", fset.Position(pos), pkg.name)
+			}
+		}
+	}
+
+	// parse expressions
+	node, err := parser.ParseExprFrom(fset, "eval", expr, 0)
+	if err != nil {
+		return TypeAndValue{}, err
+	}
+
+	// initialize checker
+	check := NewChecker(nil, fset, pkg, nil)
+	check.scope = scope
+	check.pos = pos
+	defer check.handleBailout(&err)
+
+	// evaluate node
+	var x operand
+	check.rawExpr(&x, node, nil)
+	return TypeAndValue{x.mode, x.typ, x.val}, err
+}
diff --git a/third_party/gofrontend/libgo/go/go/types/eval_test.go b/third_party/gofrontend/libgo/go/go/types/eval_test.go
new file mode 100644
index 0000000..7e0be43
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/go/types/eval_test.go
@@ -0,0 +1,188 @@
+// Copyright 2013 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.
+
+// This file contains tests for Eval.
+
+package types_test
+
+import (
+	"go/ast"
+	"go/importer"
+	"go/parser"
+	"go/token"
+	"internal/testenv"
+	"strings"
+	"testing"
+
+	. "go/types"
+)
+
+func testEval(t *testing.T, fset *token.FileSet, pkg *Package, pos token.Pos, expr string, typ Type, typStr, valStr string) {
+	gotTv, err := Eval(fset, pkg, pos, expr)
+	if err != nil {
+		t.Errorf("Eval(%q) failed: %s", expr, err)
+		return
+	}
+	if gotTv.Type == nil {
+		t.Errorf("Eval(%q) got nil type but no error", expr)
+		return
+	}
+
+	// compare types
+	if typ != nil {
+		// we have a type, check identity
+		if !Identical(gotTv.Type, typ) {
+			t.Errorf("Eval(%q) got type %s, want %s", expr, gotTv.Type, typ)
+			return
+		}
+	} else {
+		// we have a string, compare type string
+		gotStr := gotTv.Type.String()
+		if gotStr != typStr {
+			t.Errorf("Eval(%q) got type %s, want %s", expr, gotStr, typStr)
+			return
+		}
+	}
+
+	// compare values
+	gotStr := ""
+	if gotTv.Value != nil {
+		gotStr = gotTv.Value.String()
+	}
+	if gotStr != valStr {
+		t.Errorf("Eval(%q) got value %s, want %s", expr, gotStr, valStr)
+	}
+}
+
+func TestEvalBasic(t *testing.T) {
+	fset := token.NewFileSet()
+	for _, typ := range Typ[Bool : String+1] {
+		testEval(t, fset, nil, token.NoPos, typ.Name(), typ, "", "")
+	}
+}
+
+func TestEvalComposite(t *testing.T) {
+	fset := token.NewFileSet()
+	for _, test := range independentTestTypes {
+		testEval(t, fset, nil, token.NoPos, test.src, nil, test.str, "")
+	}
+}
+
+func TestEvalArith(t *testing.T) {
+	var tests = []string{
+		`true`,
+		`false == false`,
+		`12345678 + 87654321 == 99999999`,
+		`10 * 20 == 200`,
+		`(1<<1000)*2 >> 100 == 2<<900`,
+		`"foo" + "bar" == "foobar"`,
+		`"abc" <= "bcd"`,
+		`len([10]struct{}{}) == 2*5`,
+	}
+	fset := token.NewFileSet()
+	for _, test := range tests {
+		testEval(t, fset, nil, token.NoPos, test, Typ[UntypedBool], "", "true")
+	}
+}
+
+func TestEvalPos(t *testing.T) {
+	testenv.MustHaveGoBuild(t)
+
+	// The contents of /*-style comments are of the form
+	//	expr => value, type
+	// where value may be the empty string.
+	// Each expr is evaluated at the position of the comment
+	// and the result is compared with the expected value
+	// and type.
+	var sources = []string{
+		`
+		package p
+		import "fmt"
+		import m "math"
+		const c = 3.0
+		type T []int
+		func f(a int, s string) float64 {
+			fmt.Println("calling f")
+			_ = m.Pi // use package math
+			const d int = c + 1
+			var x int
+			x = a + len(s)
+			return float64(x)
+			/* true => true, untyped bool */
+			/* fmt.Println => , func(a ...interface{}) (n int, err error) */
+			/* c => 3, untyped float */
+			/* T => , p.T */
+			/* a => , int */
+			/* s => , string */
+			/* d => 4, int */
+			/* x => , int */
+			/* d/c => 1, int */
+			/* c/2 => 3/2, untyped float */
+			/* m.Pi < m.E => false, untyped bool */
+		}
+		`,
+		`
+		package p
+		/* c => 3, untyped float */
+		type T1 /* T1 => , p.T1 */ struct {}
+		var v1 /* v1 => , int */ = 42
+		func /* f1 => , func(v1 float64) */ f1(v1 float64) {
+			/* f1 => , func(v1 float64) */
+			/* v1 => , float64 */
+			var c /* c => 3, untyped float */ = "foo" /* c => , string */
+			{
+				var c struct {
+					c /* c => , string */ int
+				}
+				/* c => , struct{c int} */
+				_ = c
+			}
+			_ = func(a, b, c int) /* c => , string */ {
+				/* c => , int */
+			}
+			_ = c
+			type FT /* FT => , p.FT */ interface{}
+		}
+		`,
+		`
+		package p
+		/* T => , p.T */
+		`,
+	}
+
+	fset := token.NewFileSet()
+	var files []*ast.File
+	for i, src := range sources {
+		file, err := parser.ParseFile(fset, "p", src, parser.ParseComments)
+		if err != nil {
+			t.Fatalf("could not parse file %d: %s", i, err)
+		}
+		files = append(files, file)
+	}
+
+	conf := Config{Importer: importer.Default()}
+	pkg, err := conf.Check("p", fset, files, nil)
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	for _, file := range files {
+		for _, group := range file.Comments {
+			for _, comment := range group.List {
+				s := comment.Text
+				if len(s) >= 4 && s[:2] == "/*" && s[len(s)-2:] == "*/" {
+					str, typ := split(s[2:len(s)-2], ", ")
+					str, val := split(str, "=>")
+					testEval(t, fset, pkg, comment.Pos(), str, nil, typ, val)
+				}
+			}
+		}
+	}
+}
+
+// split splits string s at the first occurrence of s.
+func split(s, sep string) (string, string) {
+	i := strings.Index(s, sep)
+	return strings.TrimSpace(s[:i]), strings.TrimSpace(s[i+len(sep):])
+}
diff --git a/third_party/gofrontend/libgo/go/go/types/example_test.go b/third_party/gofrontend/libgo/go/go/types/example_test.go
new file mode 100644
index 0000000..9daad87
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/go/types/example_test.go
@@ -0,0 +1,312 @@
+// 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.
+
+// Only run where builders (build.golang.org) have
+// access to compiled packages for import.
+//
+// +build ignore,!arm,!arm64,!nacl
+
+package types_test
+
+// This file shows examples of basic usage of the go/types API.
+//
+// To locate a Go package, use (*go/build.Context).Import.
+// To load, parse, and type-check a complete Go program
+// from source, use golang.org/x/tools/go/loader.
+
+import (
+	"bytes"
+	"fmt"
+	"go/ast"
+	"go/format"
+	"go/importer"
+	"go/parser"
+	"go/token"
+	"go/types"
+	"log"
+	"regexp"
+	"sort"
+	"strings"
+)
+
+// ExampleScope prints the tree of Scopes of a package created from a
+// set of parsed files.
+func ExampleScope() {
+	// Parse the source files for a package.
+	fset := token.NewFileSet()
+	var files []*ast.File
+	for _, file := range []struct{ name, input string }{
+		{"main.go", `
+package main
+import "fmt"
+func main() {
+	freezing := FToC(-18)
+	fmt.Println(freezing, Boiling) }
+`},
+		{"celsius.go", `
+package main
+import "fmt"
+type Celsius float64
+func (c Celsius) String() string { return fmt.Sprintf("%g°C", c) }
+func FToC(f float64) Celsius { return Celsius(f - 32 / 9 * 5) }
+const Boiling Celsius = 100
+`},
+	} {
+		f, err := parser.ParseFile(fset, file.name, file.input, 0)
+		if err != nil {
+			log.Fatal(err)
+		}
+		files = append(files, f)
+	}
+
+	// Type-check a package consisting of these files.
+	// Type information for the imported "fmt" package
+	// comes from $GOROOT/pkg/$GOOS_$GOOARCH/fmt.a.
+	conf := types.Config{Importer: importer.Default()}
+	pkg, err := conf.Check("temperature", fset, files, nil)
+	if err != nil {
+		log.Fatal(err)
+	}
+
+	// Print the tree of scopes.
+	// For determinism, we redact addresses.
+	var buf bytes.Buffer
+	pkg.Scope().WriteTo(&buf, 0, true)
+	rx := regexp.MustCompile(` 0x[a-fA-F0-9]*`)
+	fmt.Println(rx.ReplaceAllString(buf.String(), ""))
+
+	// Output:
+	// package "temperature" scope {
+	// .  const temperature.Boiling temperature.Celsius
+	// .  type temperature.Celsius float64
+	// .  func temperature.FToC(f float64) temperature.Celsius
+	// .  func temperature.main()
+	//
+	// .  main.go scope {
+	// .  .  package fmt
+	//
+	// .  .  function scope {
+	// .  .  .  var freezing temperature.Celsius
+	// .  .  }.  }
+	// .  celsius.go scope {
+	// .  .  package fmt
+	//
+	// .  .  function scope {
+	// .  .  .  var c temperature.Celsius
+	// .  .  }
+	// .  .  function scope {
+	// .  .  .  var f float64
+	// .  .  }.  }}
+}
+
+// ExampleMethodSet prints the method sets of various types.
+func ExampleMethodSet() {
+	// Parse a single source file.
+	const input = `
+package temperature
+import "fmt"
+type Celsius float64
+func (c Celsius) String() string  { return fmt.Sprintf("%g°C", c) }
+func (c *Celsius) SetF(f float64) { *c = Celsius(f - 32 / 9 * 5) }
+`
+	fset := token.NewFileSet()
+	f, err := parser.ParseFile(fset, "celsius.go", input, 0)
+	if err != nil {
+		log.Fatal(err)
+	}
+
+	// Type-check a package consisting of this file.
+	// Type information for the imported packages
+	// comes from $GOROOT/pkg/$GOOS_$GOOARCH/fmt.a.
+	conf := types.Config{Importer: importer.Default()}
+	pkg, err := conf.Check("temperature", fset, []*ast.File{f}, nil)
+	if err != nil {
+		log.Fatal(err)
+	}
+
+	// Print the method sets of Celsius and *Celsius.
+	celsius := pkg.Scope().Lookup("Celsius").Type()
+	for _, t := range []types.Type{celsius, types.NewPointer(celsius)} {
+		fmt.Printf("Method set of %s:\n", t)
+		mset := types.NewMethodSet(t)
+		for i := 0; i < mset.Len(); i++ {
+			fmt.Println(mset.At(i))
+		}
+		fmt.Println()
+	}
+
+	// Output:
+	// Method set of temperature.Celsius:
+	// method (temperature.Celsius) String() string
+	//
+	// Method set of *temperature.Celsius:
+	// method (*temperature.Celsius) SetF(f float64)
+	// method (*temperature.Celsius) String() string
+}
+
+// ExampleInfo prints various facts recorded by the type checker in a
+// types.Info struct: definitions of and references to each named object,
+// and the type, value, and mode of every expression in the package.
+func ExampleInfo() {
+	// Parse a single source file.
+	const input = `
+package fib
+
+type S string
+
+var a, b, c = len(b), S(c), "hello"
+
+func fib(x int) int {
+	if x < 2 {
+		return x
+	}
+	return fib(x-1) - fib(x-2)
+}`
+	fset := token.NewFileSet()
+	f, err := parser.ParseFile(fset, "fib.go", input, 0)
+	if err != nil {
+		log.Fatal(err)
+	}
+
+	// Type-check the package.
+	// We create an empty map for each kind of input
+	// we're interested in, and Check populates them.
+	info := types.Info{
+		Types: make(map[ast.Expr]types.TypeAndValue),
+		Defs:  make(map[*ast.Ident]types.Object),
+		Uses:  make(map[*ast.Ident]types.Object),
+	}
+	var conf types.Config
+	pkg, err := conf.Check("fib", fset, []*ast.File{f}, &info)
+	if err != nil {
+		log.Fatal(err)
+	}
+
+	// Print package-level variables in initialization order.
+	fmt.Printf("InitOrder: %v\n\n", info.InitOrder)
+
+	// For each named object, print the line and
+	// column of its definition and each of its uses.
+	fmt.Println("Defs and Uses of each named object:")
+	usesByObj := make(map[types.Object][]string)
+	for id, obj := range info.Uses {
+		posn := fset.Position(id.Pos())
+		lineCol := fmt.Sprintf("%d:%d", posn.Line, posn.Column)
+		usesByObj[obj] = append(usesByObj[obj], lineCol)
+	}
+	var items []string
+	for obj, uses := range usesByObj {
+		sort.Strings(uses)
+		item := fmt.Sprintf("%s:\n  defined at %s\n  used at %s",
+			types.ObjectString(obj, types.RelativeTo(pkg)),
+			fset.Position(obj.Pos()),
+			strings.Join(uses, ", "))
+		items = append(items, item)
+	}
+	sort.Strings(items) // sort by line:col, in effect
+	fmt.Println(strings.Join(items, "\n"))
+	fmt.Println()
+
+	fmt.Println("Types and Values of each expression:")
+	items = nil
+	for expr, tv := range info.Types {
+		var buf bytes.Buffer
+		posn := fset.Position(expr.Pos())
+		tvstr := tv.Type.String()
+		if tv.Value != nil {
+			tvstr += " = " + tv.Value.String()
+		}
+		// line:col | expr | mode : type = value
+		fmt.Fprintf(&buf, "%2d:%2d | %-19s | %-7s : %s",
+			posn.Line, posn.Column, exprString(fset, expr),
+			mode(tv), tvstr)
+		items = append(items, buf.String())
+	}
+	sort.Strings(items)
+	fmt.Println(strings.Join(items, "\n"))
+
+	// Output:
+	// InitOrder: [c = "hello" b = S(c) a = len(b)]
+	//
+	// Defs and Uses of each named object:
+	// builtin len:
+	//   defined at -
+	//   used at 6:15
+	// func fib(x int) int:
+	//   defined at fib.go:8:6
+	//   used at 12:20, 12:9
+	// type S string:
+	//   defined at fib.go:4:6
+	//   used at 6:23
+	// type int int:
+	//   defined at -
+	//   used at 8:12, 8:17
+	// type string string:
+	//   defined at -
+	//   used at 4:8
+	// var b S:
+	//   defined at fib.go:6:8
+	//   used at 6:19
+	// var c string:
+	//   defined at fib.go:6:11
+	//   used at 6:25
+	// var x int:
+	//   defined at fib.go:8:10
+	//   used at 10:10, 12:13, 12:24, 9:5
+	//
+	// Types and Values of each expression:
+	//  4: 8 | string              | type    : string
+	//  6:15 | len                 | builtin : func(string) int
+	//  6:15 | len(b)              | value   : int
+	//  6:19 | b                   | var     : fib.S
+	//  6:23 | S                   | type    : fib.S
+	//  6:23 | S(c)                | value   : fib.S
+	//  6:25 | c                   | var     : string
+	//  6:29 | "hello"             | value   : string = "hello"
+	//  8:12 | int                 | type    : int
+	//  8:17 | int                 | type    : int
+	//  9: 5 | x                   | var     : int
+	//  9: 5 | x < 2               | value   : untyped bool
+	//  9: 9 | 2                   | value   : int = 2
+	// 10:10 | x                   | var     : int
+	// 12: 9 | fib                 | value   : func(x int) int
+	// 12: 9 | fib(x - 1)          | value   : int
+	// 12: 9 | fib(x-1) - fib(x-2) | value   : int
+	// 12:13 | x                   | var     : int
+	// 12:13 | x - 1               | value   : int
+	// 12:15 | 1                   | value   : int = 1
+	// 12:20 | fib                 | value   : func(x int) int
+	// 12:20 | fib(x - 2)          | value   : int
+	// 12:24 | x                   | var     : int
+	// 12:24 | x - 2               | value   : int
+	// 12:26 | 2                   | value   : int = 2
+}
+
+func mode(tv types.TypeAndValue) string {
+	switch {
+	case tv.IsVoid():
+		return "void"
+	case tv.IsType():
+		return "type"
+	case tv.IsBuiltin():
+		return "builtin"
+	case tv.IsNil():
+		return "nil"
+	case tv.Assignable():
+		if tv.Addressable() {
+			return "var"
+		}
+		return "mapindex"
+	case tv.IsValue():
+		return "value"
+	default:
+		return "unknown"
+	}
+}
+
+func exprString(fset *token.FileSet, expr ast.Expr) string {
+	var buf bytes.Buffer
+	format.Node(&buf, fset, expr)
+	return buf.String()
+}
diff --git a/third_party/gofrontend/libgo/go/go/types/expr.go b/third_party/gofrontend/libgo/go/go/types/expr.go
new file mode 100644
index 0000000..7d00dd5
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/go/types/expr.go
@@ -0,0 +1,1496 @@
+// Copyright 2012 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.
+
+// This file implements typechecking of expressions.
+
+package types
+
+import (
+	"fmt"
+	"go/ast"
+	"go/constant"
+	"go/token"
+	"math"
+)
+
+/*
+Basic algorithm:
+
+Expressions are checked recursively, top down. Expression checker functions
+are generally of the form:
+
+  func f(x *operand, e *ast.Expr, ...)
+
+where e is the expression to be checked, and x is the result of the check.
+The check performed by f may fail in which case x.mode == invalid, and
+related error messages will have been issued by f.
+
+If a hint argument is present, it is the composite literal element type
+of an outer composite literal; it is used to type-check composite literal
+elements that have no explicit type specification in the source
+(e.g.: []T{{...}, {...}}, the hint is the type T in this case).
+
+All expressions are checked via rawExpr, which dispatches according
+to expression kind. Upon returning, rawExpr is recording the types and
+constant values for all expressions that have an untyped type (those types
+may change on the way up in the expression tree). Usually these are constants,
+but the results of comparisons or non-constant shifts of untyped constants
+may also be untyped, but not constant.
+
+Untyped expressions may eventually become fully typed (i.e., not untyped),
+typically when the value is assigned to a variable, or is used otherwise.
+The updateExprType method is used to record this final type and update
+the recorded types: the type-checked expression tree is again traversed down,
+and the new type is propagated as needed. Untyped constant expression values
+that become fully typed must now be representable by the full type (constant
+sub-expression trees are left alone except for their roots). This mechanism
+ensures that a client sees the actual (run-time) type an untyped value would
+have. It also permits type-checking of lhs shift operands "as if the shift
+were not present": when updateExprType visits an untyped lhs shift operand
+and assigns it it's final type, that type must be an integer type, and a
+constant lhs must be representable as an integer.
+
+When an expression gets its final type, either on the way out from rawExpr,
+on the way down in updateExprType, or at the end of the type checker run,
+the type (and constant value, if any) is recorded via Info.Types, if present.
+*/
+
+type opPredicates map[token.Token]func(Type) bool
+
+var unaryOpPredicates = opPredicates{
+	token.ADD: isNumeric,
+	token.SUB: isNumeric,
+	token.XOR: isInteger,
+	token.NOT: isBoolean,
+}
+
+func (check *Checker) op(m opPredicates, x *operand, op token.Token) bool {
+	if pred := m[op]; pred != nil {
+		if !pred(x.typ) {
+			check.invalidOp(x.pos(), "operator %s not defined for %s", op, x)
+			return false
+		}
+	} else {
+		check.invalidAST(x.pos(), "unknown operator %s", op)
+		return false
+	}
+	return true
+}
+
+// The unary expression e may be nil. It's passed in for better error messages only.
+func (check *Checker) unary(x *operand, e *ast.UnaryExpr, op token.Token) {
+	switch op {
+	case token.AND:
+		// spec: "As an exception to the addressability
+		// requirement x may also be a composite literal."
+		if _, ok := unparen(x.expr).(*ast.CompositeLit); !ok && x.mode != variable {
+			check.invalidOp(x.pos(), "cannot take address of %s", x)
+			x.mode = invalid
+			return
+		}
+		x.mode = value
+		x.typ = &Pointer{base: x.typ}
+		return
+
+	case token.ARROW:
+		typ, ok := x.typ.Underlying().(*Chan)
+		if !ok {
+			check.invalidOp(x.pos(), "cannot receive from non-channel %s", x)
+			x.mode = invalid
+			return
+		}
+		if typ.dir == SendOnly {
+			check.invalidOp(x.pos(), "cannot receive from send-only channel %s", x)
+			x.mode = invalid
+			return
+		}
+		x.mode = commaok
+		x.typ = typ.elem
+		check.hasCallOrRecv = true
+		return
+	}
+
+	if !check.op(unaryOpPredicates, x, op) {
+		x.mode = invalid
+		return
+	}
+
+	if x.mode == constant_ {
+		typ := x.typ.Underlying().(*Basic)
+		var prec uint
+		if isUnsigned(typ) {
+			prec = uint(check.conf.sizeof(typ) * 8)
+		}
+		x.val = constant.UnaryOp(op, x.val, prec)
+		// Typed constants must be representable in
+		// their type after each constant operation.
+		if isTyped(typ) {
+			if e != nil {
+				x.expr = e // for better error message
+			}
+			check.representable(x, typ)
+		}
+		return
+	}
+
+	x.mode = value
+	// x.typ remains unchanged
+}
+
+func isShift(op token.Token) bool {
+	return op == token.SHL || op == token.SHR
+}
+
+func isComparison(op token.Token) bool {
+	// Note: tokens are not ordered well to make this much easier
+	switch op {
+	case token.EQL, token.NEQ, token.LSS, token.LEQ, token.GTR, token.GEQ:
+		return true
+	}
+	return false
+}
+
+func fitsFloat32(x constant.Value) bool {
+	f32, _ := constant.Float32Val(x)
+	f := float64(f32)
+	return !math.IsInf(f, 0)
+}
+
+func roundFloat32(x constant.Value) constant.Value {
+	f32, _ := constant.Float32Val(x)
+	f := float64(f32)
+	if !math.IsInf(f, 0) {
+		return constant.MakeFloat64(f)
+	}
+	return nil
+}
+
+func fitsFloat64(x constant.Value) bool {
+	f, _ := constant.Float64Val(x)
+	return !math.IsInf(f, 0)
+}
+
+func roundFloat64(x constant.Value) constant.Value {
+	f, _ := constant.Float64Val(x)
+	if !math.IsInf(f, 0) {
+		return constant.MakeFloat64(f)
+	}
+	return nil
+}
+
+// representableConst reports whether x can be represented as
+// value of the given basic type kind and for the configuration
+// provided (only needed for int/uint sizes).
+//
+// If rounded != nil, *rounded is set to the rounded value of x for
+// representable floating-point values; it is left alone otherwise.
+// It is ok to provide the addressof the first argument for rounded.
+func representableConst(x constant.Value, conf *Config, as BasicKind, rounded *constant.Value) bool {
+	switch x.Kind() {
+	case constant.Unknown:
+		return true
+
+	case constant.Bool:
+		return as == Bool || as == UntypedBool
+
+	case constant.Int:
+		if x, ok := constant.Int64Val(x); ok {
+			switch as {
+			case Int:
+				var s = uint(conf.sizeof(Typ[as])) * 8
+				return int64(-1)<<(s-1) <= x && x <= int64(1)<<(s-1)-1
+			case Int8:
+				const s = 8
+				return -1<<(s-1) <= x && x <= 1<<(s-1)-1
+			case Int16:
+				const s = 16
+				return -1<<(s-1) <= x && x <= 1<<(s-1)-1
+			case Int32:
+				const s = 32
+				return -1<<(s-1) <= x && x <= 1<<(s-1)-1
+			case Int64:
+				return true
+			case Uint, Uintptr:
+				if s := uint(conf.sizeof(Typ[as])) * 8; s < 64 {
+					return 0 <= x && x <= int64(1)<<s-1
+				}
+				return 0 <= x
+			case Uint8:
+				const s = 8
+				return 0 <= x && x <= 1<<s-1
+			case Uint16:
+				const s = 16
+				return 0 <= x && x <= 1<<s-1
+			case Uint32:
+				const s = 32
+				return 0 <= x && x <= 1<<s-1
+			case Uint64:
+				return 0 <= x
+			case Float32, Float64, Complex64, Complex128,
+				UntypedInt, UntypedFloat, UntypedComplex:
+				return true
+			}
+		}
+
+		n := constant.BitLen(x)
+		switch as {
+		case Uint, Uintptr:
+			var s = uint(conf.sizeof(Typ[as])) * 8
+			return constant.Sign(x) >= 0 && n <= int(s)
+		case Uint64:
+			return constant.Sign(x) >= 0 && n <= 64
+		case Float32, Complex64:
+			if rounded == nil {
+				return fitsFloat32(x)
+			}
+			r := roundFloat32(x)
+			if r != nil {
+				*rounded = r
+				return true
+			}
+		case Float64, Complex128:
+			if rounded == nil {
+				return fitsFloat64(x)
+			}
+			r := roundFloat64(x)
+			if r != nil {
+				*rounded = r
+				return true
+			}
+		case UntypedInt, UntypedFloat, UntypedComplex:
+			return true
+		}
+
+	case constant.Float:
+		switch as {
+		case Float32, Complex64:
+			if rounded == nil {
+				return fitsFloat32(x)
+			}
+			r := roundFloat32(x)
+			if r != nil {
+				*rounded = r
+				return true
+			}
+		case Float64, Complex128:
+			if rounded == nil {
+				return fitsFloat64(x)
+			}
+			r := roundFloat64(x)
+			if r != nil {
+				*rounded = r
+				return true
+			}
+		case UntypedFloat, UntypedComplex:
+			return true
+		}
+
+	case constant.Complex:
+		switch as {
+		case Complex64:
+			if rounded == nil {
+				return fitsFloat32(constant.Real(x)) && fitsFloat32(constant.Imag(x))
+			}
+			re := roundFloat32(constant.Real(x))
+			im := roundFloat32(constant.Imag(x))
+			if re != nil && im != nil {
+				*rounded = constant.BinaryOp(re, token.ADD, constant.MakeImag(im))
+				return true
+			}
+		case Complex128:
+			if rounded == nil {
+				return fitsFloat64(constant.Real(x)) && fitsFloat64(constant.Imag(x))
+			}
+			re := roundFloat64(constant.Real(x))
+			im := roundFloat64(constant.Imag(x))
+			if re != nil && im != nil {
+				*rounded = constant.BinaryOp(re, token.ADD, constant.MakeImag(im))
+				return true
+			}
+		case UntypedComplex:
+			return true
+		}
+
+	case constant.String:
+		return as == String || as == UntypedString
+
+	default:
+		unreachable()
+	}
+
+	return false
+}
+
+// representable checks that a constant operand is representable in the given basic type.
+func (check *Checker) representable(x *operand, typ *Basic) {
+	assert(x.mode == constant_)
+	if !representableConst(x.val, check.conf, typ.kind, &x.val) {
+		var msg string
+		if isNumeric(x.typ) && isNumeric(typ) {
+			// numeric conversion : error msg
+			//
+			// integer -> integer : overflows
+			// integer -> float   : overflows (actually not possible)
+			// float   -> integer : truncated
+			// float   -> float   : overflows
+			//
+			if !isInteger(x.typ) && isInteger(typ) {
+				msg = "%s truncated to %s"
+			} else {
+				msg = "%s overflows %s"
+			}
+		} else {
+			msg = "cannot convert %s to %s"
+		}
+		check.errorf(x.pos(), msg, x, typ)
+		x.mode = invalid
+	}
+}
+
+// updateExprType updates the type of x to typ and invokes itself
+// recursively for the operands of x, depending on expression kind.
+// If typ is still an untyped and not the final type, updateExprType
+// only updates the recorded untyped type for x and possibly its
+// operands. Otherwise (i.e., typ is not an untyped type anymore,
+// or it is the final type for x), the type and value are recorded.
+// Also, if x is a constant, it must be representable as a value of typ,
+// and if x is the (formerly untyped) lhs operand of a non-constant
+// shift, it must be an integer value.
+//
+func (check *Checker) updateExprType(x ast.Expr, typ Type, final bool) {
+	old, found := check.untyped[x]
+	if !found {
+		return // nothing to do
+	}
+
+	// update operands of x if necessary
+	switch x := x.(type) {
+	case *ast.BadExpr,
+		*ast.FuncLit,
+		*ast.CompositeLit,
+		*ast.IndexExpr,
+		*ast.SliceExpr,
+		*ast.TypeAssertExpr,
+		*ast.StarExpr,
+		*ast.KeyValueExpr,
+		*ast.ArrayType,
+		*ast.StructType,
+		*ast.FuncType,
+		*ast.InterfaceType,
+		*ast.MapType,
+		*ast.ChanType:
+		// These expression are never untyped - nothing to do.
+		// The respective sub-expressions got their final types
+		// upon assignment or use.
+		if debug {
+			check.dump("%s: found old type(%s): %s (new: %s)", x.Pos(), x, old.typ, typ)
+			unreachable()
+		}
+		return
+
+	case *ast.CallExpr:
+		// Resulting in an untyped constant (e.g., built-in complex).
+		// The respective calls take care of calling updateExprType
+		// for the arguments if necessary.
+
+	case *ast.Ident, *ast.BasicLit, *ast.SelectorExpr:
+		// An identifier denoting a constant, a constant literal,
+		// or a qualified identifier (imported untyped constant).
+		// No operands to take care of.
+
+	case *ast.ParenExpr:
+		check.updateExprType(x.X, typ, final)
+
+	case *ast.UnaryExpr:
+		// If x is a constant, the operands were constants.
+		// They don't need to be updated since they never
+		// get "materialized" into a typed value; and they
+		// will be processed at the end of the type check.
+		if old.val != nil {
+			break
+		}
+		check.updateExprType(x.X, typ, final)
+
+	case *ast.BinaryExpr:
+		if old.val != nil {
+			break // see comment for unary expressions
+		}
+		if isComparison(x.Op) {
+			// The result type is independent of operand types
+			// and the operand types must have final types.
+		} else if isShift(x.Op) {
+			// The result type depends only on lhs operand.
+			// The rhs type was updated when checking the shift.
+			check.updateExprType(x.X, typ, final)
+		} else {
+			// The operand types match the result type.
+			check.updateExprType(x.X, typ, final)
+			check.updateExprType(x.Y, typ, final)
+		}
+
+	default:
+		unreachable()
+	}
+
+	// If the new type is not final and still untyped, just
+	// update the recorded type.
+	if !final && isUntyped(typ) {
+		old.typ = typ.Underlying().(*Basic)
+		check.untyped[x] = old
+		return
+	}
+
+	// Otherwise we have the final (typed or untyped type).
+	// Remove it from the map of yet untyped expressions.
+	delete(check.untyped, x)
+
+	// If x is the lhs of a shift, its final type must be integer.
+	// We already know from the shift check that it is representable
+	// as an integer if it is a constant.
+	if old.isLhs && !isInteger(typ) {
+		check.invalidOp(x.Pos(), "shifted operand %s (type %s) must be integer", x, typ)
+		return
+	}
+
+	// Everything's fine, record final type and value for x.
+	check.recordTypeAndValue(x, old.mode, typ, old.val)
+}
+
+// updateExprVal updates the value of x to val.
+func (check *Checker) updateExprVal(x ast.Expr, val constant.Value) {
+	if info, ok := check.untyped[x]; ok {
+		info.val = val
+		check.untyped[x] = info
+	}
+}
+
+// convertUntyped attempts to set the type of an untyped value to the target type.
+func (check *Checker) convertUntyped(x *operand, target Type) {
+	if x.mode == invalid || isTyped(x.typ) || target == Typ[Invalid] {
+		return
+	}
+
+	// TODO(gri) Sloppy code - clean up. This function is central
+	//           to assignment and expression checking.
+
+	if isUntyped(target) {
+		// both x and target are untyped
+		xkind := x.typ.(*Basic).kind
+		tkind := target.(*Basic).kind
+		if isNumeric(x.typ) && isNumeric(target) {
+			if xkind < tkind {
+				x.typ = target
+				check.updateExprType(x.expr, target, false)
+			}
+		} else if xkind != tkind {
+			goto Error
+		}
+		return
+	}
+
+	// typed target
+	switch t := target.Underlying().(type) {
+	case *Basic:
+		if x.mode == constant_ {
+			check.representable(x, t)
+			if x.mode == invalid {
+				return
+			}
+			// expression value may have been rounded - update if needed
+			// TODO(gri) A floating-point value may silently underflow to
+			// zero. If it was negative, the sign is lost. See issue 6898.
+			check.updateExprVal(x.expr, x.val)
+		} else {
+			// Non-constant untyped values may appear as the
+			// result of comparisons (untyped bool), intermediate
+			// (delayed-checked) rhs operands of shifts, and as
+			// the value nil.
+			switch x.typ.(*Basic).kind {
+			case UntypedBool:
+				if !isBoolean(target) {
+					goto Error
+				}
+			case UntypedInt, UntypedRune, UntypedFloat, UntypedComplex:
+				if !isNumeric(target) {
+					goto Error
+				}
+			case UntypedString:
+				// Non-constant untyped string values are not
+				// permitted by the spec and should not occur.
+				unreachable()
+			case UntypedNil:
+				// Unsafe.Pointer is a basic type that includes nil.
+				if !hasNil(target) {
+					goto Error
+				}
+			default:
+				goto Error
+			}
+		}
+	case *Interface:
+		if !x.isNil() && !t.Empty() /* empty interfaces are ok */ {
+			goto Error
+		}
+		// Update operand types to the default type rather then
+		// the target (interface) type: values must have concrete
+		// dynamic types. If the value is nil, keep it untyped
+		// (this is important for tools such as go vet which need
+		// the dynamic type for argument checking of say, print
+		// functions)
+		if x.isNil() {
+			target = Typ[UntypedNil]
+		} else {
+			// cannot assign untyped values to non-empty interfaces
+			if !t.Empty() {
+				goto Error
+			}
+			target = defaultType(x.typ)
+		}
+	case *Pointer, *Signature, *Slice, *Map, *Chan:
+		if !x.isNil() {
+			goto Error
+		}
+		// keep nil untyped - see comment for interfaces, above
+		target = Typ[UntypedNil]
+	default:
+		goto Error
+	}
+
+	x.typ = target
+	check.updateExprType(x.expr, target, true) // UntypedNils are final
+	return
+
+Error:
+	check.errorf(x.pos(), "cannot convert %s to %s", x, target)
+	x.mode = invalid
+}
+
+func (check *Checker) comparison(x, y *operand, op token.Token) {
+	// spec: "In any comparison, the first operand must be assignable
+	// to the type of the second operand, or vice versa."
+	err := ""
+	if x.assignableTo(check.conf, y.typ) || y.assignableTo(check.conf, x.typ) {
+		defined := false
+		switch op {
+		case token.EQL, token.NEQ:
+			// spec: "The equality operators == and != apply to operands that are comparable."
+			defined = Comparable(x.typ) || x.isNil() && hasNil(y.typ) || y.isNil() && hasNil(x.typ)
+		case token.LSS, token.LEQ, token.GTR, token.GEQ:
+			// spec: The ordering operators <, <=, >, and >= apply to operands that are ordered."
+			defined = isOrdered(x.typ)
+		default:
+			unreachable()
+		}
+		if !defined {
+			typ := x.typ
+			if x.isNil() {
+				typ = y.typ
+			}
+			err = check.sprintf("operator %s not defined for %s", op, typ)
+		}
+	} else {
+		err = check.sprintf("mismatched types %s and %s", x.typ, y.typ)
+	}
+
+	if err != "" {
+		check.errorf(x.pos(), "cannot compare %s %s %s (%s)", x.expr, op, y.expr, err)
+		x.mode = invalid
+		return
+	}
+
+	if x.mode == constant_ && y.mode == constant_ {
+		x.val = constant.MakeBool(constant.Compare(x.val, op, y.val))
+		// The operands are never materialized; no need to update
+		// their types.
+	} else {
+		x.mode = value
+		// The operands have now their final types, which at run-
+		// time will be materialized. Update the expression trees.
+		// If the current types are untyped, the materialized type
+		// is the respective default type.
+		check.updateExprType(x.expr, defaultType(x.typ), true)
+		check.updateExprType(y.expr, defaultType(y.typ), true)
+	}
+
+	// spec: "Comparison operators compare two operands and yield
+	//        an untyped boolean value."
+	x.typ = Typ[UntypedBool]
+}
+
+func (check *Checker) shift(x, y *operand, op token.Token) {
+	untypedx := isUntyped(x.typ)
+
+	// The lhs must be of integer type or be representable
+	// as an integer; otherwise the shift has no chance.
+	if !x.isInteger() {
+		check.invalidOp(x.pos(), "shifted operand %s must be integer", x)
+		x.mode = invalid
+		return
+	}
+
+	// spec: "The right operand in a shift expression must have unsigned
+	// integer type or be an untyped constant that can be converted to
+	// unsigned integer type."
+	switch {
+	case isInteger(y.typ) && isUnsigned(y.typ):
+		// nothing to do
+	case isUntyped(y.typ):
+		check.convertUntyped(y, Typ[UntypedInt])
+		if y.mode == invalid {
+			x.mode = invalid
+			return
+		}
+	default:
+		check.invalidOp(y.pos(), "shift count %s must be unsigned integer", y)
+		x.mode = invalid
+		return
+	}
+
+	if x.mode == constant_ {
+		if y.mode == constant_ {
+			// rhs must be an integer value
+			if !y.isInteger() {
+				check.invalidOp(y.pos(), "shift count %s must be unsigned integer", y)
+				x.mode = invalid
+				return
+			}
+			// rhs must be within reasonable bounds
+			const stupidShift = 1023 - 1 + 52 // so we can express smallestFloat64
+			s, ok := constant.Uint64Val(y.val)
+			if !ok || s > stupidShift {
+				check.invalidOp(y.pos(), "stupid shift count %s", y)
+				x.mode = invalid
+				return
+			}
+			// The lhs is representable as an integer but may not be an integer
+			// (e.g., 2.0, an untyped float) - this can only happen for untyped
+			// non-integer numeric constants. Correct the type so that the shift
+			// result is of integer type.
+			if !isInteger(x.typ) {
+				x.typ = Typ[UntypedInt]
+			}
+			x.val = constant.Shift(x.val, op, uint(s))
+			return
+		}
+
+		// non-constant shift with constant lhs
+		if untypedx {
+			// spec: "If the left operand of a non-constant shift
+			// expression is an untyped constant, the type of the
+			// constant is what it would be if the shift expression
+			// were replaced by its left operand alone.".
+			//
+			// Delay operand checking until we know the final type:
+			// The lhs expression must be in the untyped map, mark
+			// the entry as lhs shift operand.
+			info, found := check.untyped[x.expr]
+			assert(found)
+			info.isLhs = true
+			check.untyped[x.expr] = info
+			// keep x's type
+			x.mode = value
+			return
+		}
+	}
+
+	// constant rhs must be >= 0
+	if y.mode == constant_ && constant.Sign(y.val) < 0 {
+		check.invalidOp(y.pos(), "shift count %s must not be negative", y)
+	}
+
+	// non-constant shift - lhs must be an integer
+	if !isInteger(x.typ) {
+		check.invalidOp(x.pos(), "shifted operand %s must be integer", x)
+		x.mode = invalid
+		return
+	}
+
+	x.mode = value
+}
+
+var binaryOpPredicates = opPredicates{
+	token.ADD: func(typ Type) bool { return isNumeric(typ) || isString(typ) },
+	token.SUB: isNumeric,
+	token.MUL: isNumeric,
+	token.QUO: isNumeric,
+	token.REM: isInteger,
+
+	token.AND:     isInteger,
+	token.OR:      isInteger,
+	token.XOR:     isInteger,
+	token.AND_NOT: isInteger,
+
+	token.LAND: isBoolean,
+	token.LOR:  isBoolean,
+}
+
+// The binary expression e may be nil. It's passed in for better error messages only.
+func (check *Checker) binary(x *operand, e *ast.BinaryExpr, lhs, rhs ast.Expr, op token.Token) {
+	var y operand
+
+	check.expr(x, lhs)
+	check.expr(&y, rhs)
+
+	if x.mode == invalid {
+		return
+	}
+	if y.mode == invalid {
+		x.mode = invalid
+		x.expr = y.expr
+		return
+	}
+
+	if isShift(op) {
+		check.shift(x, &y, op)
+		return
+	}
+
+	check.convertUntyped(x, y.typ)
+	if x.mode == invalid {
+		return
+	}
+	check.convertUntyped(&y, x.typ)
+	if y.mode == invalid {
+		x.mode = invalid
+		return
+	}
+
+	if isComparison(op) {
+		check.comparison(x, &y, op)
+		return
+	}
+
+	if !Identical(x.typ, y.typ) {
+		// only report an error if we have valid types
+		// (otherwise we had an error reported elsewhere already)
+		if x.typ != Typ[Invalid] && y.typ != Typ[Invalid] {
+			check.invalidOp(x.pos(), "mismatched types %s and %s", x.typ, y.typ)
+		}
+		x.mode = invalid
+		return
+	}
+
+	if !check.op(binaryOpPredicates, x, op) {
+		x.mode = invalid
+		return
+	}
+
+	if (op == token.QUO || op == token.REM) && (x.mode == constant_ || isInteger(x.typ)) && y.mode == constant_ && constant.Sign(y.val) == 0 {
+		check.invalidOp(y.pos(), "division by zero")
+		x.mode = invalid
+		return
+	}
+
+	if x.mode == constant_ && y.mode == constant_ {
+		typ := x.typ.Underlying().(*Basic)
+		// force integer division of integer operands
+		if op == token.QUO && isInteger(typ) {
+			op = token.QUO_ASSIGN
+		}
+		x.val = constant.BinaryOp(x.val, op, y.val)
+		// Typed constants must be representable in
+		// their type after each constant operation.
+		if isTyped(typ) {
+			if e != nil {
+				x.expr = e // for better error message
+			}
+			check.representable(x, typ)
+		}
+		return
+	}
+
+	x.mode = value
+	// x.typ is unchanged
+}
+
+// index checks an index expression for validity.
+// If max >= 0, it is the upper bound for index.
+// If index is valid and the result i >= 0, then i is the constant value of index.
+func (check *Checker) index(index ast.Expr, max int64) (i int64, valid bool) {
+	var x operand
+	check.expr(&x, index)
+	if x.mode == invalid {
+		return
+	}
+
+	// an untyped constant must be representable as Int
+	check.convertUntyped(&x, Typ[Int])
+	if x.mode == invalid {
+		return
+	}
+
+	// the index must be of integer type
+	if !isInteger(x.typ) {
+		check.invalidArg(x.pos(), "index %s must be integer", &x)
+		return
+	}
+
+	// a constant index i must be in bounds
+	if x.mode == constant_ {
+		if constant.Sign(x.val) < 0 {
+			check.invalidArg(x.pos(), "index %s must not be negative", &x)
+			return
+		}
+		i, valid = constant.Int64Val(x.val)
+		if !valid || max >= 0 && i >= max {
+			check.errorf(x.pos(), "index %s is out of bounds", &x)
+			return i, false
+		}
+		// 0 <= i [ && i < max ]
+		return i, true
+	}
+
+	return -1, true
+}
+
+// indexElts checks the elements (elts) of an array or slice composite literal
+// against the literal's element type (typ), and the element indices against
+// the literal length if known (length >= 0). It returns the length of the
+// literal (maximum index value + 1).
+//
+func (check *Checker) indexedElts(elts []ast.Expr, typ Type, length int64) int64 {
+	visited := make(map[int64]bool, len(elts))
+	var index, max int64
+	for _, e := range elts {
+		// determine and check index
+		validIndex := false
+		eval := e
+		if kv, _ := e.(*ast.KeyValueExpr); kv != nil {
+			if i, ok := check.index(kv.Key, length); ok {
+				if i >= 0 {
+					index = i
+					validIndex = true
+				} else {
+					check.errorf(e.Pos(), "index %s must be integer constant", kv.Key)
+				}
+			}
+			eval = kv.Value
+		} else if length >= 0 && index >= length {
+			check.errorf(e.Pos(), "index %d is out of bounds (>= %d)", index, length)
+		} else {
+			validIndex = true
+		}
+
+		// if we have a valid index, check for duplicate entries
+		if validIndex {
+			if visited[index] {
+				check.errorf(e.Pos(), "duplicate index %d in array or slice literal", index)
+			}
+			visited[index] = true
+		}
+		index++
+		if index > max {
+			max = index
+		}
+
+		// check element against composite literal element type
+		var x operand
+		check.exprWithHint(&x, eval, typ)
+		if !check.assignment(&x, typ) && x.mode != invalid {
+			check.errorf(x.pos(), "cannot use %s as %s value in array or slice literal", &x, typ)
+		}
+	}
+	return max
+}
+
+// exprKind describes the kind of an expression; the kind
+// determines if an expression is valid in 'statement context'.
+type exprKind int
+
+const (
+	conversion exprKind = iota
+	expression
+	statement
+)
+
+// rawExpr typechecks expression e and initializes x with the expression
+// value or type. If an error occurred, x.mode is set to invalid.
+// If hint != nil, it is the type of a composite literal element.
+//
+func (check *Checker) rawExpr(x *operand, e ast.Expr, hint Type) exprKind {
+	if trace {
+		check.trace(e.Pos(), "%s", e)
+		check.indent++
+		defer func() {
+			check.indent--
+			check.trace(e.Pos(), "=> %s", x)
+		}()
+	}
+
+	kind := check.exprInternal(x, e, hint)
+
+	// convert x into a user-friendly set of values
+	// TODO(gri) this code can be simplified
+	var typ Type
+	var val constant.Value
+	switch x.mode {
+	case invalid:
+		typ = Typ[Invalid]
+	case novalue:
+		typ = (*Tuple)(nil)
+	case constant_:
+		typ = x.typ
+		val = x.val
+	default:
+		typ = x.typ
+	}
+	assert(x.expr != nil && typ != nil)
+
+	if isUntyped(typ) {
+		// delay type and value recording until we know the type
+		// or until the end of type checking
+		check.rememberUntyped(x.expr, false, x.mode, typ.(*Basic), val)
+	} else {
+		check.recordTypeAndValue(e, x.mode, typ, val)
+	}
+
+	return kind
+}
+
+// exprInternal contains the core of type checking of expressions.
+// Must only be called by rawExpr.
+//
+func (check *Checker) exprInternal(x *operand, e ast.Expr, hint Type) exprKind {
+	// make sure x has a valid state in case of bailout
+	// (was issue 5770)
+	x.mode = invalid
+	x.typ = Typ[Invalid]
+
+	switch e := e.(type) {
+	case *ast.BadExpr:
+		goto Error // error was reported before
+
+	case *ast.Ident:
+		check.ident(x, e, nil, nil)
+
+	case *ast.Ellipsis:
+		// ellipses are handled explicitly where they are legal
+		// (array composite literals and parameter lists)
+		check.error(e.Pos(), "invalid use of '...'")
+		goto Error
+
+	case *ast.BasicLit:
+		x.setConst(e.Kind, e.Value)
+		if x.mode == invalid {
+			check.invalidAST(e.Pos(), "invalid literal %v", e.Value)
+			goto Error
+		}
+
+	case *ast.FuncLit:
+		if sig, ok := check.typ(e.Type).(*Signature); ok {
+			// Anonymous functions are considered part of the
+			// init expression/func declaration which contains
+			// them: use existing package-level declaration info.
+			check.funcBody(check.decl, "", sig, e.Body)
+			x.mode = value
+			x.typ = sig
+		} else {
+			check.invalidAST(e.Pos(), "invalid function literal %s", e)
+			goto Error
+		}
+
+	case *ast.CompositeLit:
+		typ := hint
+		openArray := false
+		if e.Type != nil {
+			// [...]T array types may only appear with composite literals.
+			// Check for them here so we don't have to handle ... in general.
+			typ = nil
+			if atyp, _ := e.Type.(*ast.ArrayType); atyp != nil && atyp.Len != nil {
+				if ellip, _ := atyp.Len.(*ast.Ellipsis); ellip != nil && ellip.Elt == nil {
+					// We have an "open" [...]T array type.
+					// Create a new ArrayType with unknown length (-1)
+					// and finish setting it up after analyzing the literal.
+					typ = &Array{len: -1, elem: check.typ(atyp.Elt)}
+					openArray = true
+				}
+			}
+			if typ == nil {
+				typ = check.typ(e.Type)
+			}
+		}
+		if typ == nil {
+			// TODO(gri) provide better error messages depending on context
+			check.error(e.Pos(), "missing type in composite literal")
+			goto Error
+		}
+
+		switch typ, _ := deref(typ); utyp := typ.Underlying().(type) {
+		case *Struct:
+			if len(e.Elts) == 0 {
+				break
+			}
+			fields := utyp.fields
+			if _, ok := e.Elts[0].(*ast.KeyValueExpr); ok {
+				// all elements must have keys
+				visited := make([]bool, len(fields))
+				for _, e := range e.Elts {
+					kv, _ := e.(*ast.KeyValueExpr)
+					if kv == nil {
+						check.error(e.Pos(), "mixture of field:value and value elements in struct literal")
+						continue
+					}
+					key, _ := kv.Key.(*ast.Ident)
+					if key == nil {
+						check.errorf(kv.Pos(), "invalid field name %s in struct literal", kv.Key)
+						continue
+					}
+					i := fieldIndex(utyp.fields, check.pkg, key.Name)
+					if i < 0 {
+						check.errorf(kv.Pos(), "unknown field %s in struct literal", key.Name)
+						continue
+					}
+					fld := fields[i]
+					check.recordUse(key, fld)
+					// 0 <= i < len(fields)
+					if visited[i] {
+						check.errorf(kv.Pos(), "duplicate field name %s in struct literal", key.Name)
+						continue
+					}
+					visited[i] = true
+					check.expr(x, kv.Value)
+					etyp := fld.typ
+					if !check.assignment(x, etyp) {
+						if x.mode != invalid {
+							check.errorf(x.pos(), "cannot use %s as %s value in struct literal", x, etyp)
+						}
+						continue
+					}
+				}
+			} else {
+				// no element must have a key
+				for i, e := range e.Elts {
+					if kv, _ := e.(*ast.KeyValueExpr); kv != nil {
+						check.error(kv.Pos(), "mixture of field:value and value elements in struct literal")
+						continue
+					}
+					check.expr(x, e)
+					if i >= len(fields) {
+						check.error(x.pos(), "too many values in struct literal")
+						break // cannot continue
+					}
+					// i < len(fields)
+					fld := fields[i]
+					if !fld.Exported() && fld.pkg != check.pkg {
+						check.errorf(x.pos(), "implicit assignment to unexported field %s in %s literal", fld.name, typ)
+						continue
+					}
+					etyp := fld.typ
+					if !check.assignment(x, etyp) {
+						if x.mode != invalid {
+							check.errorf(x.pos(), "cannot use %s as %s value in struct literal", x, etyp)
+						}
+						continue
+					}
+				}
+				if len(e.Elts) < len(fields) {
+					check.error(e.Rbrace, "too few values in struct literal")
+					// ok to continue
+				}
+			}
+
+		case *Array:
+			n := check.indexedElts(e.Elts, utyp.elem, utyp.len)
+			// if we have an "open" [...]T array, set the length now that we know it
+			if openArray {
+				utyp.len = n
+			}
+
+		case *Slice:
+			check.indexedElts(e.Elts, utyp.elem, -1)
+
+		case *Map:
+			visited := make(map[interface{}][]Type, len(e.Elts))
+			for _, e := range e.Elts {
+				kv, _ := e.(*ast.KeyValueExpr)
+				if kv == nil {
+					check.error(e.Pos(), "missing key in map literal")
+					continue
+				}
+				check.exprWithHint(x, kv.Key, utyp.key)
+				if !check.assignment(x, utyp.key) {
+					if x.mode != invalid {
+						check.errorf(x.pos(), "cannot use %s as %s key in map literal", x, utyp.key)
+					}
+					continue
+				}
+				if x.mode == constant_ {
+					duplicate := false
+					// if the key is of interface type, the type is also significant when checking for duplicates
+					if _, ok := utyp.key.Underlying().(*Interface); ok {
+						for _, vtyp := range visited[x.val] {
+							if Identical(vtyp, x.typ) {
+								duplicate = true
+								break
+							}
+						}
+						visited[x.val] = append(visited[x.val], x.typ)
+					} else {
+						_, duplicate = visited[x.val]
+						visited[x.val] = nil
+					}
+					if duplicate {
+						check.errorf(x.pos(), "duplicate key %s in map literal", x.val)
+						continue
+					}
+				}
+				check.exprWithHint(x, kv.Value, utyp.elem)
+				if !check.assignment(x, utyp.elem) {
+					if x.mode != invalid {
+						check.errorf(x.pos(), "cannot use %s as %s value in map literal", x, utyp.elem)
+					}
+					continue
+				}
+			}
+
+		default:
+			// if utyp is invalid, an error was reported before
+			if utyp != Typ[Invalid] {
+				check.errorf(e.Pos(), "invalid composite literal type %s", typ)
+				goto Error
+			}
+		}
+
+		x.mode = value
+		x.typ = typ
+
+	case *ast.ParenExpr:
+		kind := check.rawExpr(x, e.X, nil)
+		x.expr = e
+		return kind
+
+	case *ast.SelectorExpr:
+		check.selector(x, e)
+
+	case *ast.IndexExpr:
+		check.expr(x, e.X)
+		if x.mode == invalid {
+			goto Error
+		}
+
+		valid := false
+		length := int64(-1) // valid if >= 0
+		switch typ := x.typ.Underlying().(type) {
+		case *Basic:
+			if isString(typ) {
+				valid = true
+				if x.mode == constant_ {
+					length = int64(len(constant.StringVal(x.val)))
+				}
+				// an indexed string always yields a byte value
+				// (not a constant) even if the string and the
+				// index are constant
+				x.mode = value
+				x.typ = universeByte // use 'byte' name
+			}
+
+		case *Array:
+			valid = true
+			length = typ.len
+			if x.mode != variable {
+				x.mode = value
+			}
+			x.typ = typ.elem
+
+		case *Pointer:
+			if typ, _ := typ.base.Underlying().(*Array); typ != nil {
+				valid = true
+				length = typ.len
+				x.mode = variable
+				x.typ = typ.elem
+			}
+
+		case *Slice:
+			valid = true
+			x.mode = variable
+			x.typ = typ.elem
+
+		case *Map:
+			var key operand
+			check.expr(&key, e.Index)
+			if !check.assignment(&key, typ.key) {
+				if key.mode != invalid {
+					check.invalidOp(key.pos(), "cannot use %s as map index of type %s", &key, typ.key)
+				}
+				goto Error
+			}
+			x.mode = mapindex
+			x.typ = typ.elem
+			x.expr = e
+			return expression
+		}
+
+		if !valid {
+			check.invalidOp(x.pos(), "cannot index %s", x)
+			goto Error
+		}
+
+		if e.Index == nil {
+			check.invalidAST(e.Pos(), "missing index for %s", x)
+			goto Error
+		}
+
+		check.index(e.Index, length)
+		// ok to continue
+
+	case *ast.SliceExpr:
+		check.expr(x, e.X)
+		if x.mode == invalid {
+			goto Error
+		}
+
+		valid := false
+		length := int64(-1) // valid if >= 0
+		switch typ := x.typ.Underlying().(type) {
+		case *Basic:
+			if isString(typ) {
+				if slice3(e) {
+					check.invalidOp(x.pos(), "3-index slice of string")
+					goto Error
+				}
+				valid = true
+				if x.mode == constant_ {
+					length = int64(len(constant.StringVal(x.val)))
+				}
+				// spec: "For untyped string operands the result
+				// is a non-constant value of type string."
+				if typ.kind == UntypedString {
+					x.typ = Typ[String]
+				}
+			}
+
+		case *Array:
+			valid = true
+			length = typ.len
+			if x.mode != variable {
+				check.invalidOp(x.pos(), "cannot slice %s (value not addressable)", x)
+				goto Error
+			}
+			x.typ = &Slice{elem: typ.elem}
+
+		case *Pointer:
+			if typ, _ := typ.base.Underlying().(*Array); typ != nil {
+				valid = true
+				length = typ.len
+				x.typ = &Slice{elem: typ.elem}
+			}
+
+		case *Slice:
+			valid = true
+			// x.typ doesn't change
+		}
+
+		if !valid {
+			check.invalidOp(x.pos(), "cannot slice %s", x)
+			goto Error
+		}
+
+		x.mode = value
+
+		// spec: "Only the first index may be omitted; it defaults to 0."
+		if slice3(e) && (e.High == nil || sliceMax(e) == nil) {
+			check.error(e.Rbrack, "2nd and 3rd index required in 3-index slice")
+			goto Error
+		}
+
+		// check indices
+		var ind [3]int64
+		for i, expr := range []ast.Expr{e.Low, e.High, sliceMax(e)} {
+			x := int64(-1)
+			switch {
+			case expr != nil:
+				// The "capacity" is only known statically for strings, arrays,
+				// and pointers to arrays, and it is the same as the length for
+				// those types.
+				max := int64(-1)
+				if length >= 0 {
+					max = length + 1
+				}
+				if t, ok := check.index(expr, max); ok && t >= 0 {
+					x = t
+				}
+			case i == 0:
+				// default is 0 for the first index
+				x = 0
+			case length >= 0:
+				// default is length (== capacity) otherwise
+				x = length
+			}
+			ind[i] = x
+		}
+
+		// constant indices must be in range
+		// (check.index already checks that existing indices >= 0)
+	L:
+		for i, x := range ind[:len(ind)-1] {
+			if x > 0 {
+				for _, y := range ind[i+1:] {
+					if y >= 0 && x > y {
+						check.errorf(e.Rbrack, "invalid slice indices: %d > %d", x, y)
+						break L // only report one error, ok to continue
+					}
+				}
+			}
+		}
+
+	case *ast.TypeAssertExpr:
+		check.expr(x, e.X)
+		if x.mode == invalid {
+			goto Error
+		}
+		xtyp, _ := x.typ.Underlying().(*Interface)
+		if xtyp == nil {
+			check.invalidOp(x.pos(), "%s is not an interface", x)
+			goto Error
+		}
+		// x.(type) expressions are handled explicitly in type switches
+		if e.Type == nil {
+			check.invalidAST(e.Pos(), "use of .(type) outside type switch")
+			goto Error
+		}
+		T := check.typ(e.Type)
+		if T == Typ[Invalid] {
+			goto Error
+		}
+		check.typeAssertion(x.pos(), x, xtyp, T)
+		x.mode = commaok
+		x.typ = T
+
+	case *ast.CallExpr:
+		return check.call(x, e)
+
+	case *ast.StarExpr:
+		check.exprOrType(x, e.X)
+		switch x.mode {
+		case invalid:
+			goto Error
+		case typexpr:
+			x.typ = &Pointer{base: x.typ}
+		default:
+			if typ, ok := x.typ.Underlying().(*Pointer); ok {
+				x.mode = variable
+				x.typ = typ.base
+			} else {
+				check.invalidOp(x.pos(), "cannot indirect %s", x)
+				goto Error
+			}
+		}
+
+	case *ast.UnaryExpr:
+		check.expr(x, e.X)
+		if x.mode == invalid {
+			goto Error
+		}
+		check.unary(x, e, e.Op)
+		if x.mode == invalid {
+			goto Error
+		}
+		if e.Op == token.ARROW {
+			x.expr = e
+			return statement // receive operations may appear in statement context
+		}
+
+	case *ast.BinaryExpr:
+		check.binary(x, e, e.X, e.Y, e.Op)
+		if x.mode == invalid {
+			goto Error
+		}
+
+	case *ast.KeyValueExpr:
+		// key:value expressions are handled in composite literals
+		check.invalidAST(e.Pos(), "no key:value expected")
+		goto Error
+
+	case *ast.ArrayType, *ast.StructType, *ast.FuncType,
+		*ast.InterfaceType, *ast.MapType, *ast.ChanType:
+		x.mode = typexpr
+		x.typ = check.typ(e)
+		// Note: rawExpr (caller of exprInternal) will call check.recordTypeAndValue
+		// even though check.typ has already called it. This is fine as both
+		// times the same expression and type are recorded. It is also not a
+		// performance issue because we only reach here for composite literal
+		// types, which are comparatively rare.
+
+	default:
+		panic(fmt.Sprintf("%s: unknown expression type %T", check.fset.Position(e.Pos()), e))
+	}
+
+	// everything went well
+	x.expr = e
+	return expression
+
+Error:
+	x.mode = invalid
+	x.expr = e
+	return statement // avoid follow-up errors
+}
+
+// typeAssertion checks that x.(T) is legal; xtyp must be the type of x.
+func (check *Checker) typeAssertion(pos token.Pos, x *operand, xtyp *Interface, T Type) {
+	method, wrongType := assertableTo(xtyp, T)
+	if method == nil {
+		return
+	}
+
+	var msg string
+	if wrongType {
+		msg = "wrong type for method"
+	} else {
+		msg = "missing method"
+	}
+	check.errorf(pos, "%s cannot have dynamic type %s (%s %s)", x, T, msg, method.name)
+}
+
+// expr typechecks expression e and initializes x with the expression value.
+// If an error occurred, x.mode is set to invalid.
+//
+func (check *Checker) expr(x *operand, e ast.Expr) {
+	check.rawExpr(x, e, nil)
+	var msg string
+	switch x.mode {
+	default:
+		return
+	case novalue:
+		msg = "used as value"
+	case builtin:
+		msg = "must be called"
+	case typexpr:
+		msg = "is not an expression"
+	}
+	check.errorf(x.pos(), "%s %s", x, msg)
+	x.mode = invalid
+}
+
+// exprWithHint typechecks expression e and initializes x with the expression value.
+// If an error occurred, x.mode is set to invalid.
+// If hint != nil, it is the type of a composite literal element.
+//
+func (check *Checker) exprWithHint(x *operand, e ast.Expr, hint Type) {
+	assert(hint != nil)
+	check.rawExpr(x, e, hint)
+	var msg string
+	switch x.mode {
+	default:
+		return
+	case novalue:
+		msg = "used as value"
+	case builtin:
+		msg = "must be called"
+	case typexpr:
+		msg = "is not an expression"
+	}
+	check.errorf(x.pos(), "%s %s", x, msg)
+	x.mode = invalid
+}
+
+// exprOrType typechecks expression or type e and initializes x with the expression value or type.
+// If an error occurred, x.mode is set to invalid.
+//
+func (check *Checker) exprOrType(x *operand, e ast.Expr) {
+	check.rawExpr(x, e, nil)
+	if x.mode == novalue {
+		check.errorf(x.pos(), "%s used as value or type", x)
+		x.mode = invalid
+	}
+}
diff --git a/third_party/gofrontend/libgo/go/go/types/exprstring.go b/third_party/gofrontend/libgo/go/go/types/exprstring.go
new file mode 100644
index 0000000..370bdf3
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/go/types/exprstring.go
@@ -0,0 +1,220 @@
+// Copyright 2013 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.
+
+// This file implements printing of expressions.
+
+package types
+
+import (
+	"bytes"
+	"go/ast"
+)
+
+// ExprString returns the (possibly simplified) string representation for x.
+func ExprString(x ast.Expr) string {
+	var buf bytes.Buffer
+	WriteExpr(&buf, x)
+	return buf.String()
+}
+
+// WriteExpr writes the (possibly simplified) string representation for x to buf.
+func WriteExpr(buf *bytes.Buffer, x ast.Expr) {
+	// The AST preserves source-level parentheses so there is
+	// no need to introduce them here to correct for different
+	// operator precedences. (This assumes that the AST was
+	// generated by a Go parser.)
+
+	switch x := x.(type) {
+	default:
+		buf.WriteString("(bad expr)") // nil, ast.BadExpr, ast.KeyValueExpr
+
+	case *ast.Ident:
+		buf.WriteString(x.Name)
+
+	case *ast.Ellipsis:
+		buf.WriteString("...")
+		if x.Elt != nil {
+			WriteExpr(buf, x.Elt)
+		}
+
+	case *ast.BasicLit:
+		buf.WriteString(x.Value)
+
+	case *ast.FuncLit:
+		buf.WriteByte('(')
+		WriteExpr(buf, x.Type)
+		buf.WriteString(" literal)") // simplified
+
+	case *ast.CompositeLit:
+		buf.WriteByte('(')
+		WriteExpr(buf, x.Type)
+		buf.WriteString(" literal)") // simplified
+
+	case *ast.ParenExpr:
+		buf.WriteByte('(')
+		WriteExpr(buf, x.X)
+		buf.WriteByte(')')
+
+	case *ast.SelectorExpr:
+		WriteExpr(buf, x.X)
+		buf.WriteByte('.')
+		buf.WriteString(x.Sel.Name)
+
+	case *ast.IndexExpr:
+		WriteExpr(buf, x.X)
+		buf.WriteByte('[')
+		WriteExpr(buf, x.Index)
+		buf.WriteByte(']')
+
+	case *ast.SliceExpr:
+		WriteExpr(buf, x.X)
+		buf.WriteByte('[')
+		if x.Low != nil {
+			WriteExpr(buf, x.Low)
+		}
+		buf.WriteByte(':')
+		if x.High != nil {
+			WriteExpr(buf, x.High)
+		}
+		if x.Slice3 {
+			buf.WriteByte(':')
+			if x.Max != nil {
+				WriteExpr(buf, x.Max)
+			}
+		}
+		buf.WriteByte(']')
+
+	case *ast.TypeAssertExpr:
+		WriteExpr(buf, x.X)
+		buf.WriteString(".(")
+		WriteExpr(buf, x.Type)
+		buf.WriteByte(')')
+
+	case *ast.CallExpr:
+		WriteExpr(buf, x.Fun)
+		buf.WriteByte('(')
+		for i, arg := range x.Args {
+			if i > 0 {
+				buf.WriteString(", ")
+			}
+			WriteExpr(buf, arg)
+		}
+		if x.Ellipsis.IsValid() {
+			buf.WriteString("...")
+		}
+		buf.WriteByte(')')
+
+	case *ast.StarExpr:
+		buf.WriteByte('*')
+		WriteExpr(buf, x.X)
+
+	case *ast.UnaryExpr:
+		buf.WriteString(x.Op.String())
+		WriteExpr(buf, x.X)
+
+	case *ast.BinaryExpr:
+		WriteExpr(buf, x.X)
+		buf.WriteByte(' ')
+		buf.WriteString(x.Op.String())
+		buf.WriteByte(' ')
+		WriteExpr(buf, x.Y)
+
+	case *ast.ArrayType:
+		buf.WriteByte('[')
+		if x.Len != nil {
+			WriteExpr(buf, x.Len)
+		}
+		buf.WriteByte(']')
+		WriteExpr(buf, x.Elt)
+
+	case *ast.StructType:
+		buf.WriteString("struct{")
+		writeFieldList(buf, x.Fields, "; ", false)
+		buf.WriteByte('}')
+
+	case *ast.FuncType:
+		buf.WriteString("func")
+		writeSigExpr(buf, x)
+
+	case *ast.InterfaceType:
+		buf.WriteString("interface{")
+		writeFieldList(buf, x.Methods, "; ", true)
+		buf.WriteByte('}')
+
+	case *ast.MapType:
+		buf.WriteString("map[")
+		WriteExpr(buf, x.Key)
+		buf.WriteByte(']')
+		WriteExpr(buf, x.Value)
+
+	case *ast.ChanType:
+		var s string
+		switch x.Dir {
+		case ast.SEND:
+			s = "chan<- "
+		case ast.RECV:
+			s = "<-chan "
+		default:
+			s = "chan "
+		}
+		buf.WriteString(s)
+		WriteExpr(buf, x.Value)
+	}
+}
+
+func writeSigExpr(buf *bytes.Buffer, sig *ast.FuncType) {
+	buf.WriteByte('(')
+	writeFieldList(buf, sig.Params, ", ", false)
+	buf.WriteByte(')')
+
+	res := sig.Results
+	n := res.NumFields()
+	if n == 0 {
+		// no result
+		return
+	}
+
+	buf.WriteByte(' ')
+	if n == 1 && len(res.List[0].Names) == 0 {
+		// single unnamed result
+		WriteExpr(buf, res.List[0].Type)
+		return
+	}
+
+	// multiple or named result(s)
+	buf.WriteByte('(')
+	writeFieldList(buf, res, ", ", false)
+	buf.WriteByte(')')
+}
+
+func writeFieldList(buf *bytes.Buffer, fields *ast.FieldList, sep string, iface bool) {
+	for i, f := range fields.List {
+		if i > 0 {
+			buf.WriteString(sep)
+		}
+
+		// field list names
+		for i, name := range f.Names {
+			if i > 0 {
+				buf.WriteString(", ")
+			}
+			buf.WriteString(name.Name)
+		}
+
+		// types of interface methods consist of signatures only
+		if sig, _ := f.Type.(*ast.FuncType); sig != nil && iface {
+			writeSigExpr(buf, sig)
+			continue
+		}
+
+		// named fields are separated with a blank from the field type
+		if len(f.Names) > 0 {
+			buf.WriteByte(' ')
+		}
+
+		WriteExpr(buf, f.Type)
+
+		// ignore tag
+	}
+}
diff --git a/third_party/gofrontend/libgo/go/go/types/exprstring_test.go b/third_party/gofrontend/libgo/go/go/types/exprstring_test.go
new file mode 100644
index 0000000..5110288
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/go/types/exprstring_test.go
@@ -0,0 +1,94 @@
+// Copyright 2013 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 types_test
+
+import (
+	"go/parser"
+	"testing"
+
+	. "go/types"
+)
+
+var testExprs = []testEntry{
+	// basic type literals
+	dup("x"),
+	dup("true"),
+	dup("42"),
+	dup("3.1415"),
+	dup("2.71828i"),
+	dup(`'a'`),
+	dup(`"foo"`),
+	dup("`bar`"),
+
+	// func and composite literals
+	{"func(){}", "(func() literal)"},
+	{"func(x int) complex128 {}", "(func(x int) complex128 literal)"},
+	{"[]int{1, 2, 3}", "([]int literal)"},
+
+	// non-type expressions
+	dup("(x)"),
+	dup("x.f"),
+	dup("a[i]"),
+
+	dup("s[:]"),
+	dup("s[i:]"),
+	dup("s[:j]"),
+	dup("s[i:j]"),
+	dup("s[:j:k]"),
+	dup("s[i:j:k]"),
+
+	dup("x.(T)"),
+
+	dup("x.([10]int)"),
+	dup("x.([...]int)"),
+
+	dup("x.(struct{})"),
+	dup("x.(struct{x int; y, z float32; E})"),
+
+	dup("x.(func())"),
+	dup("x.(func(x int))"),
+	dup("x.(func() int)"),
+	dup("x.(func(x, y int, z float32) (r int))"),
+	dup("x.(func(a, b, c int))"),
+	dup("x.(func(x ...T))"),
+
+	dup("x.(interface{})"),
+	dup("x.(interface{m(); n(x int); E})"),
+	dup("x.(interface{m(); n(x int) T; E; F})"),
+
+	dup("x.(map[K]V)"),
+
+	dup("x.(chan E)"),
+	dup("x.(<-chan E)"),
+	dup("x.(chan<- chan int)"),
+	dup("x.(chan<- <-chan int)"),
+	dup("x.(<-chan chan int)"),
+	dup("x.(chan (<-chan int))"),
+
+	dup("f()"),
+	dup("f(x)"),
+	dup("int(x)"),
+	dup("f(x, x + y)"),
+	dup("f(s...)"),
+	dup("f(a, s...)"),
+
+	dup("*x"),
+	dup("&x"),
+	dup("x + y"),
+	dup("x + y << (2 * s)"),
+}
+
+func TestExprString(t *testing.T) {
+	for _, test := range testExprs {
+		x, err := parser.ParseExpr(test.src)
+		if err != nil {
+			t.Errorf("%s: %s", test.src, err)
+			continue
+		}
+		if got := ExprString(x); got != test.str {
+			t.Errorf("%s: got %s, want %s", test.src, got, test.str)
+		}
+	}
+}
diff --git a/third_party/gofrontend/libgo/go/go/types/go11.go b/third_party/gofrontend/libgo/go/go/types/go11.go
new file mode 100644
index 0000000..cf41cab
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/go/types/go11.go
@@ -0,0 +1,17 @@
+// Copyright 2013 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 !go1.2
+
+package types
+
+import "go/ast"
+
+func slice3(x *ast.SliceExpr) bool {
+	return false
+}
+
+func sliceMax(x *ast.SliceExpr) ast.Expr {
+	return nil
+}
diff --git a/third_party/gofrontend/libgo/go/go/types/go12.go b/third_party/gofrontend/libgo/go/go/types/go12.go
new file mode 100644
index 0000000..2017442
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/go/types/go12.go
@@ -0,0 +1,17 @@
+// Copyright 2013 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 go1.2
+
+package types
+
+import "go/ast"
+
+func slice3(x *ast.SliceExpr) bool {
+	return x.Slice3
+}
+
+func sliceMax(x *ast.SliceExpr) ast.Expr {
+	return x.Max
+}
diff --git a/third_party/gofrontend/libgo/go/go/types/hilbert_test.go b/third_party/gofrontend/libgo/go/go/types/hilbert_test.go
new file mode 100644
index 0000000..cfd51b1
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/go/types/hilbert_test.go
@@ -0,0 +1,234 @@
+// Copyright 2013 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 types_test
+
+import (
+	"bytes"
+	"flag"
+	"fmt"
+	"go/ast"
+	"go/importer"
+	"go/parser"
+	"go/token"
+	"io/ioutil"
+	"testing"
+
+	. "go/types"
+)
+
+var (
+	H   = flag.Int("H", 5, "Hilbert matrix size")
+	out = flag.String("out", "", "write generated program to out")
+)
+
+func TestHilbert(t *testing.T) {
+	// generate source
+	src := program(*H, *out)
+	if *out != "" {
+		ioutil.WriteFile(*out, src, 0666)
+		return
+	}
+
+	// parse source
+	fset := token.NewFileSet()
+	f, err := parser.ParseFile(fset, "hilbert.go", src, 0)
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	// type-check file
+	DefPredeclaredTestFuncs() // define assert built-in
+	conf := Config{Importer: importer.Default()}
+	_, err = conf.Check(f.Name.Name, fset, []*ast.File{f}, nil)
+	if err != nil {
+		t.Fatal(err)
+	}
+}
+
+func program(n int, out string) []byte {
+	var g gen
+
+	g.p(`// WARNING: GENERATED FILE - DO NOT MODIFY MANUALLY!
+// (To generate, in go/types directory: go test -run=Hilbert -H=%d -out=%q)
+
+// This program tests arbitrary precision constant arithmetic
+// by generating the constant elements of a Hilbert matrix H,
+// its inverse I, and the product P = H*I. The product should
+// be the identity matrix.
+package main
+
+func main() {
+	if !ok {
+		printProduct()
+		return
+	}
+	println("PASS")
+}
+
+`, n, out)
+	g.hilbert(n)
+	g.inverse(n)
+	g.product(n)
+	g.verify(n)
+	g.printProduct(n)
+	g.binomials(2*n - 1)
+	g.factorials(2*n - 1)
+
+	return g.Bytes()
+}
+
+type gen struct {
+	bytes.Buffer
+}
+
+func (g *gen) p(format string, args ...interface{}) {
+	fmt.Fprintf(&g.Buffer, format, args...)
+}
+
+func (g *gen) hilbert(n int) {
+	g.p(`// Hilbert matrix, n = %d
+const (
+`, n)
+	for i := 0; i < n; i++ {
+		g.p("\t")
+		for j := 0; j < n; j++ {
+			if j > 0 {
+				g.p(", ")
+			}
+			g.p("h%d_%d", i, j)
+		}
+		if i == 0 {
+			g.p(" = ")
+			for j := 0; j < n; j++ {
+				if j > 0 {
+					g.p(", ")
+				}
+				g.p("1.0/(iota + %d)", j+1)
+			}
+		}
+		g.p("\n")
+	}
+	g.p(")\n\n")
+}
+
+func (g *gen) inverse(n int) {
+	g.p(`// Inverse Hilbert matrix
+const (
+`)
+	for i := 0; i < n; i++ {
+		for j := 0; j < n; j++ {
+			s := "+"
+			if (i+j)&1 != 0 {
+				s = "-"
+			}
+			g.p("\ti%d_%d = %s%d * b%d_%d * b%d_%d * b%d_%d * b%d_%d\n",
+				i, j, s, i+j+1, n+i, n-j-1, n+j, n-i-1, i+j, i, i+j, i)
+		}
+		g.p("\n")
+	}
+	g.p(")\n\n")
+}
+
+func (g *gen) product(n int) {
+	g.p(`// Product matrix
+const (
+`)
+	for i := 0; i < n; i++ {
+		for j := 0; j < n; j++ {
+			g.p("\tp%d_%d = ", i, j)
+			for k := 0; k < n; k++ {
+				if k > 0 {
+					g.p(" + ")
+				}
+				g.p("h%d_%d*i%d_%d", i, k, k, j)
+			}
+			g.p("\n")
+		}
+		g.p("\n")
+	}
+	g.p(")\n\n")
+}
+
+func (g *gen) verify(n int) {
+	g.p(`// Verify that product is the identity matrix
+const ok =
+`)
+	for i := 0; i < n; i++ {
+		for j := 0; j < n; j++ {
+			if j == 0 {
+				g.p("\t")
+			} else {
+				g.p(" && ")
+			}
+			v := 0
+			if i == j {
+				v = 1
+			}
+			g.p("p%d_%d == %d", i, j, v)
+		}
+		g.p(" &&\n")
+	}
+	g.p("\ttrue\n\n")
+
+	// verify ok at type-check time
+	if *out == "" {
+		g.p("const _ = assert(ok)\n\n")
+	}
+}
+
+func (g *gen) printProduct(n int) {
+	g.p("func printProduct() {\n")
+	for i := 0; i < n; i++ {
+		g.p("\tprintln(")
+		for j := 0; j < n; j++ {
+			if j > 0 {
+				g.p(", ")
+			}
+			g.p("p%d_%d", i, j)
+		}
+		g.p(")\n")
+	}
+	g.p("}\n\n")
+}
+
+func (g *gen) mulRange(a, b int) {
+	if a > b {
+		g.p("1")
+		return
+	}
+	for i := a; i <= b; i++ {
+		if i > a {
+			g.p("*")
+		}
+		g.p("%d", i)
+	}
+}
+
+func (g *gen) binomials(n int) {
+	g.p(`// Binomials
+const (
+`)
+	for j := 0; j <= n; j++ {
+		if j > 0 {
+			g.p("\n")
+		}
+		for k := 0; k <= j; k++ {
+			g.p("\tb%d_%d = f%d / (f%d*f%d)\n", j, k, j, k, j-k)
+		}
+	}
+	g.p(")\n\n")
+}
+
+func (g *gen) factorials(n int) {
+	g.p(`// Factorials
+const (
+	f0 = 1
+	f1 = 1
+`)
+	for i := 2; i <= n; i++ {
+		g.p("\tf%d = f%d * %d\n", i, i-1, i)
+	}
+	g.p(")\n\n")
+}
diff --git a/third_party/gofrontend/libgo/go/go/types/initorder.go b/third_party/gofrontend/libgo/go/go/types/initorder.go
new file mode 100644
index 0000000..0fd567b
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/go/types/initorder.go
@@ -0,0 +1,222 @@
+// 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.
+
+package types
+
+import (
+	"container/heap"
+	"fmt"
+)
+
+// initOrder computes the Info.InitOrder for package variables.
+func (check *Checker) initOrder() {
+	// An InitOrder may already have been computed if a package is
+	// built from several calls to (*Checker).Files.  Clear it.
+	check.Info.InitOrder = check.Info.InitOrder[:0]
+
+	// compute the object dependency graph and
+	// initialize a priority queue with the list
+	// of graph nodes
+	pq := nodeQueue(dependencyGraph(check.objMap))
+	heap.Init(&pq)
+
+	const debug = false
+	if debug {
+		fmt.Printf("package %s: object dependency graph\n", check.pkg.Name())
+		for _, n := range pq {
+			for _, o := range n.out {
+				fmt.Printf("\t%s -> %s\n", n.obj.Name(), o.obj.Name())
+			}
+		}
+		fmt.Println()
+		fmt.Printf("package %s: initialization order\n", check.pkg.Name())
+	}
+
+	// determine initialization order by removing the highest priority node
+	// (the one with the fewest dependencies) and its edges from the graph,
+	// repeatedly, until there are no nodes left.
+	// In a valid Go program, those nodes always have zero dependencies (after
+	// removing all incoming dependencies), otherwise there are initialization
+	// cycles.
+	mark := 0
+	emitted := make(map[*declInfo]bool)
+	for len(pq) > 0 {
+		// get the next node
+		n := heap.Pop(&pq).(*objNode)
+
+		// if n still depends on other nodes, we have a cycle
+		if n.in > 0 {
+			mark++ // mark nodes using a different value each time
+			cycle := findPath(n, n, mark)
+			if i := valIndex(cycle); i >= 0 {
+				check.reportCycle(cycle, i)
+			}
+			// ok to continue, but the variable initialization order
+			// will be incorrect at this point since it assumes no
+			// cycle errors
+		}
+
+		// reduce dependency count of all dependent nodes
+		// and update priority queue
+		for _, out := range n.out {
+			out.in--
+			heap.Fix(&pq, out.index)
+		}
+
+		// record the init order for variables with initializers only
+		v, _ := n.obj.(*Var)
+		info := check.objMap[v]
+		if v == nil || !info.hasInitializer() {
+			continue
+		}
+
+		// n:1 variable declarations such as: a, b = f()
+		// introduce a node for each lhs variable (here: a, b);
+		// but they all have the same initializer - emit only
+		// one, for the first variable seen
+		if emitted[info] {
+			continue // initializer already emitted, if any
+		}
+		emitted[info] = true
+
+		infoLhs := info.lhs // possibly nil (see declInfo.lhs field comment)
+		if infoLhs == nil {
+			infoLhs = []*Var{v}
+		}
+		init := &Initializer{infoLhs, info.init}
+		check.Info.InitOrder = append(check.Info.InitOrder, init)
+
+		if debug {
+			fmt.Printf("\t%s\n", init)
+		}
+	}
+
+	if debug {
+		fmt.Println()
+	}
+}
+
+// findPath returns the (reversed) list of nodes z, ... c, b, a,
+// such that there is a path (list of edges) from a to z.
+// If there is no such path, the result is nil.
+// Nodes marked with the value mark are considered "visited";
+// unvisited nodes are marked during the graph search.
+func findPath(a, z *objNode, mark int) []*objNode {
+	if a.mark == mark {
+		return nil // node already seen
+	}
+	a.mark = mark
+
+	for _, n := range a.out {
+		if n == z {
+			return []*objNode{z}
+		}
+		if P := findPath(n, z, mark); P != nil {
+			return append(P, n)
+		}
+	}
+
+	return nil
+}
+
+// valIndex returns the index of the first constant or variable in a,
+// if any; or a value < 0.
+func valIndex(a []*objNode) int {
+	for i, n := range a {
+		switch n.obj.(type) {
+		case *Const, *Var:
+			return i
+		}
+	}
+	return -1
+}
+
+// reportCycle reports an error for the cycle starting at i.
+func (check *Checker) reportCycle(cycle []*objNode, i int) {
+	obj := cycle[i].obj
+	check.errorf(obj.Pos(), "initialization cycle for %s", obj.Name())
+	// print cycle
+	for _ = range cycle {
+		check.errorf(obj.Pos(), "\t%s refers to", obj.Name()) // secondary error, \t indented
+		i++
+		if i >= len(cycle) {
+			i = 0
+		}
+		obj = cycle[i].obj
+	}
+	check.errorf(obj.Pos(), "\t%s", obj.Name())
+}
+
+// An objNode represents a node in the object dependency graph.
+// Each node b in a.out represents an edge a->b indicating that
+// b depends on a.
+// Nodes may be marked for cycle detection. A node n is marked
+// if n.mark corresponds to the current mark value.
+type objNode struct {
+	obj   Object     // object represented by this node
+	in    int        // number of nodes this node depends on
+	out   []*objNode // list of nodes that depend on this node
+	index int        // node index in list of nodes
+	mark  int        // for cycle detection
+}
+
+// dependencyGraph computes the transposed object dependency graph
+// from the given objMap. The transposed graph is returned as a list
+// of nodes; an edge d->n indicates that node n depends on node d.
+func dependencyGraph(objMap map[Object]*declInfo) []*objNode {
+	// M maps each object to its corresponding node
+	M := make(map[Object]*objNode, len(objMap))
+	for obj := range objMap {
+		M[obj] = &objNode{obj: obj}
+	}
+
+	// G is the graph of nodes n
+	G := make([]*objNode, len(M))
+	i := 0
+	for obj, n := range M {
+		deps := objMap[obj].deps
+		n.in = len(deps)
+		for d := range deps {
+			d := M[d]                // node n depends on node d
+			d.out = append(d.out, n) // add edge d->n
+		}
+
+		G[i] = n
+		n.index = i
+		i++
+	}
+
+	return G
+}
+
+// nodeQueue implements the container/heap interface;
+// a nodeQueue may be used as a priority queue.
+type nodeQueue []*objNode
+
+func (a nodeQueue) Len() int { return len(a) }
+
+func (a nodeQueue) Swap(i, j int) {
+	x, y := a[i], a[j]
+	a[i], a[j] = y, x
+	x.index, y.index = j, i
+}
+
+func (a nodeQueue) Less(i, j int) bool {
+	x, y := a[i], a[j]
+	// nodes are prioritized by number of incoming dependencies (1st key)
+	// and source order (2nd key)
+	return x.in < y.in || x.in == y.in && x.obj.order() < y.obj.order()
+}
+
+func (a *nodeQueue) Push(x interface{}) {
+	panic("unreachable")
+}
+
+func (a *nodeQueue) Pop() interface{} {
+	n := len(*a)
+	x := (*a)[n-1]
+	x.index = -1 // for safety
+	*a = (*a)[:n-1]
+	return x
+}
diff --git a/third_party/gofrontend/libgo/go/go/types/issues_test.go b/third_party/gofrontend/libgo/go/go/types/issues_test.go
new file mode 100644
index 0000000..672c78d
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/go/types/issues_test.go
@@ -0,0 +1,206 @@
+// Copyright 2013 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.
+
+// This file implements tests for various issues.
+
+package types_test
+
+import (
+	"fmt"
+	"go/ast"
+	"go/importer"
+	"go/parser"
+	"sort"
+	"strings"
+	"testing"
+
+	. "go/types"
+)
+
+func TestIssue5770(t *testing.T) {
+	src := `package p; type S struct{T}`
+	f, err := parser.ParseFile(fset, "", src, 0)
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	conf := Config{Importer: importer.Default()}
+	_, err = conf.Check(f.Name.Name, fset, []*ast.File{f}, nil) // do not crash
+	want := "undeclared name: T"
+	if err == nil || !strings.Contains(err.Error(), want) {
+		t.Errorf("got: %v; want: %s", err, want)
+	}
+}
+
+func TestIssue5849(t *testing.T) {
+	src := `
+package p
+var (
+	s uint
+	_ = uint8(8)
+	_ = uint16(16) << s
+	_ = uint32(32 << s)
+	_ = uint64(64 << s + s)
+	_ = (interface{})("foo")
+	_ = (interface{})(nil)
+)`
+	f, err := parser.ParseFile(fset, "", src, 0)
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	var conf Config
+	types := make(map[ast.Expr]TypeAndValue)
+	_, err = conf.Check(f.Name.Name, fset, []*ast.File{f}, &Info{Types: types})
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	for x, tv := range types {
+		var want Type
+		switch x := x.(type) {
+		case *ast.BasicLit:
+			switch x.Value {
+			case `8`:
+				want = Typ[Uint8]
+			case `16`:
+				want = Typ[Uint16]
+			case `32`:
+				want = Typ[Uint32]
+			case `64`:
+				want = Typ[Uint] // because of "+ s", s is of type uint
+			case `"foo"`:
+				want = Typ[String]
+			}
+		case *ast.Ident:
+			if x.Name == "nil" {
+				want = Typ[UntypedNil]
+			}
+		}
+		if want != nil && !Identical(tv.Type, want) {
+			t.Errorf("got %s; want %s", tv.Type, want)
+		}
+	}
+}
+
+func TestIssue6413(t *testing.T) {
+	src := `
+package p
+func f() int {
+	defer f()
+	go f()
+	return 0
+}
+`
+	f, err := parser.ParseFile(fset, "", src, 0)
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	var conf Config
+	types := make(map[ast.Expr]TypeAndValue)
+	_, err = conf.Check(f.Name.Name, fset, []*ast.File{f}, &Info{Types: types})
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	want := Typ[Int]
+	n := 0
+	for x, tv := range types {
+		if _, ok := x.(*ast.CallExpr); ok {
+			if tv.Type != want {
+				t.Errorf("%s: got %s; want %s", fset.Position(x.Pos()), tv.Type, want)
+			}
+			n++
+		}
+	}
+
+	if n != 2 {
+		t.Errorf("got %d CallExprs; want 2", n)
+	}
+}
+
+func TestIssue7245(t *testing.T) {
+	src := `
+package p
+func (T) m() (res bool) { return }
+type T struct{} // receiver type after method declaration
+`
+	f, err := parser.ParseFile(fset, "", src, 0)
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	var conf Config
+	defs := make(map[*ast.Ident]Object)
+	_, err = conf.Check(f.Name.Name, fset, []*ast.File{f}, &Info{Defs: defs})
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	m := f.Decls[0].(*ast.FuncDecl)
+	res1 := defs[m.Name].(*Func).Type().(*Signature).Results().At(0)
+	res2 := defs[m.Type.Results.List[0].Names[0]].(*Var)
+
+	if res1 != res2 {
+		t.Errorf("got %s (%p) != %s (%p)", res1, res2, res1, res2)
+	}
+}
+
+// This tests that uses of existing vars on the LHS of an assignment
+// are Uses, not Defs; and also that the (illegal) use of a non-var on
+// the LHS of an assignment is a Use nonetheless.
+func TestIssue7827(t *testing.T) {
+	const src = `
+package p
+func _() {
+	const w = 1        // defs w
+        x, y := 2, 3       // defs x, y
+        w, x, z := 4, 5, 6 // uses w, x, defs z; error: cannot assign to w
+        _, _, _ = x, y, z  // uses x, y, z
+}
+`
+	const want = `L3 defs func p._()
+L4 defs const w untyped int
+L5 defs var x int
+L5 defs var y int
+L6 defs var z int
+L6 uses const w untyped int
+L6 uses var x int
+L7 uses var x int
+L7 uses var y int
+L7 uses var z int`
+
+	f, err := parser.ParseFile(fset, "", src, 0)
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	// don't abort at the first error
+	conf := Config{Error: func(err error) { t.Log(err) }}
+	defs := make(map[*ast.Ident]Object)
+	uses := make(map[*ast.Ident]Object)
+	_, err = conf.Check(f.Name.Name, fset, []*ast.File{f}, &Info{Defs: defs, Uses: uses})
+	if s := fmt.Sprint(err); !strings.HasSuffix(s, "cannot assign to w") {
+		t.Errorf("Check: unexpected error: %s", s)
+	}
+
+	var facts []string
+	for id, obj := range defs {
+		if obj != nil {
+			fact := fmt.Sprintf("L%d defs %s", fset.Position(id.Pos()).Line, obj)
+			facts = append(facts, fact)
+		}
+	}
+	for id, obj := range uses {
+		fact := fmt.Sprintf("L%d uses %s", fset.Position(id.Pos()).Line, obj)
+		facts = append(facts, fact)
+	}
+	sort.Strings(facts)
+
+	got := strings.Join(facts, "\n")
+	if got != want {
+		t.Errorf("Unexpected defs/uses\ngot:\n%s\nwant:\n%s", got, want)
+	}
+}
diff --git a/third_party/gofrontend/libgo/go/go/types/labels.go b/third_party/gofrontend/libgo/go/go/types/labels.go
new file mode 100644
index 0000000..7364d4d
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/go/types/labels.go
@@ -0,0 +1,268 @@
+// Copyright 2013 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 types
+
+import (
+	"go/ast"
+	"go/token"
+)
+
+// labels checks correct label use in body.
+func (check *Checker) labels(body *ast.BlockStmt) {
+	// set of all labels in this body
+	all := NewScope(nil, body.Pos(), body.End(), "label")
+
+	fwdJumps := check.blockBranches(all, nil, nil, body.List)
+
+	// If there are any forward jumps left, no label was found for
+	// the corresponding goto statements. Either those labels were
+	// never defined, or they are inside blocks and not reachable
+	// for the respective gotos.
+	for _, jmp := range fwdJumps {
+		var msg string
+		name := jmp.Label.Name
+		if alt := all.Lookup(name); alt != nil {
+			msg = "goto %s jumps into block"
+			alt.(*Label).used = true // avoid another error
+		} else {
+			msg = "label %s not declared"
+		}
+		check.errorf(jmp.Label.Pos(), msg, name)
+	}
+
+	// spec: "It is illegal to define a label that is never used."
+	for _, obj := range all.elems {
+		if lbl := obj.(*Label); !lbl.used {
+			check.softErrorf(lbl.pos, "label %s declared but not used", lbl.name)
+		}
+	}
+}
+
+// A block tracks label declarations in a block and its enclosing blocks.
+type block struct {
+	parent *block                      // enclosing block
+	lstmt  *ast.LabeledStmt            // labeled statement to which this block belongs, or nil
+	labels map[string]*ast.LabeledStmt // allocated lazily
+}
+
+// insert records a new label declaration for the current block.
+// The label must not have been declared before in any block.
+func (b *block) insert(s *ast.LabeledStmt) {
+	name := s.Label.Name
+	if debug {
+		assert(b.gotoTarget(name) == nil)
+	}
+	labels := b.labels
+	if labels == nil {
+		labels = make(map[string]*ast.LabeledStmt)
+		b.labels = labels
+	}
+	labels[name] = s
+}
+
+// gotoTarget returns the labeled statement in the current
+// or an enclosing block with the given label name, or nil.
+func (b *block) gotoTarget(name string) *ast.LabeledStmt {
+	for s := b; s != nil; s = s.parent {
+		if t := s.labels[name]; t != nil {
+			return t
+		}
+	}
+	return nil
+}
+
+// enclosingTarget returns the innermost enclosing labeled
+// statement with the given label name, or nil.
+func (b *block) enclosingTarget(name string) *ast.LabeledStmt {
+	for s := b; s != nil; s = s.parent {
+		if t := s.lstmt; t != nil && t.Label.Name == name {
+			return t
+		}
+	}
+	return nil
+}
+
+// blockBranches processes a block's statement list and returns the set of outgoing forward jumps.
+// all is the scope of all declared labels, parent the set of labels declared in the immediately
+// enclosing block, and lstmt is the labeled statement this block is associated with (or nil).
+func (check *Checker) blockBranches(all *Scope, parent *block, lstmt *ast.LabeledStmt, list []ast.Stmt) []*ast.BranchStmt {
+	b := &block{parent: parent, lstmt: lstmt}
+
+	var (
+		varDeclPos         token.Pos
+		fwdJumps, badJumps []*ast.BranchStmt
+	)
+
+	// All forward jumps jumping over a variable declaration are possibly
+	// invalid (they may still jump out of the block and be ok).
+	// recordVarDecl records them for the given position.
+	recordVarDecl := func(pos token.Pos) {
+		varDeclPos = pos
+		badJumps = append(badJumps[:0], fwdJumps...) // copy fwdJumps to badJumps
+	}
+
+	jumpsOverVarDecl := func(jmp *ast.BranchStmt) bool {
+		if varDeclPos.IsValid() {
+			for _, bad := range badJumps {
+				if jmp == bad {
+					return true
+				}
+			}
+		}
+		return false
+	}
+
+	blockBranches := func(lstmt *ast.LabeledStmt, list []ast.Stmt) {
+		// Unresolved forward jumps inside the nested block
+		// become forward jumps in the current block.
+		fwdJumps = append(fwdJumps, check.blockBranches(all, b, lstmt, list)...)
+	}
+
+	var stmtBranches func(ast.Stmt)
+	stmtBranches = func(s ast.Stmt) {
+		switch s := s.(type) {
+		case *ast.DeclStmt:
+			if d, _ := s.Decl.(*ast.GenDecl); d != nil && d.Tok == token.VAR {
+				recordVarDecl(d.Pos())
+			}
+
+		case *ast.LabeledStmt:
+			// declare non-blank label
+			if name := s.Label.Name; name != "_" {
+				lbl := NewLabel(s.Label.Pos(), check.pkg, name)
+				if alt := all.Insert(lbl); alt != nil {
+					check.softErrorf(lbl.pos, "label %s already declared", name)
+					check.reportAltDecl(alt)
+					// ok to continue
+				} else {
+					b.insert(s)
+					check.recordDef(s.Label, lbl)
+				}
+				// resolve matching forward jumps and remove them from fwdJumps
+				i := 0
+				for _, jmp := range fwdJumps {
+					if jmp.Label.Name == name {
+						// match
+						lbl.used = true
+						check.recordUse(jmp.Label, lbl)
+						if jumpsOverVarDecl(jmp) {
+							check.softErrorf(
+								jmp.Label.Pos(),
+								"goto %s jumps over variable declaration at line %d",
+								name,
+								check.fset.Position(varDeclPos).Line,
+							)
+							// ok to continue
+						}
+					} else {
+						// no match - record new forward jump
+						fwdJumps[i] = jmp
+						i++
+					}
+				}
+				fwdJumps = fwdJumps[:i]
+				lstmt = s
+			}
+			stmtBranches(s.Stmt)
+
+		case *ast.BranchStmt:
+			if s.Label == nil {
+				return // checked in 1st pass (check.stmt)
+			}
+
+			// determine and validate target
+			name := s.Label.Name
+			switch s.Tok {
+			case token.BREAK:
+				// spec: "If there is a label, it must be that of an enclosing
+				// "for", "switch", or "select" statement, and that is the one
+				// whose execution terminates."
+				valid := false
+				if t := b.enclosingTarget(name); t != nil {
+					switch t.Stmt.(type) {
+					case *ast.SwitchStmt, *ast.TypeSwitchStmt, *ast.SelectStmt, *ast.ForStmt, *ast.RangeStmt:
+						valid = true
+					}
+				}
+				if !valid {
+					check.errorf(s.Label.Pos(), "invalid break label %s", name)
+					return
+				}
+
+			case token.CONTINUE:
+				// spec: "If there is a label, it must be that of an enclosing
+				// "for" statement, and that is the one whose execution advances."
+				valid := false
+				if t := b.enclosingTarget(name); t != nil {
+					switch t.Stmt.(type) {
+					case *ast.ForStmt, *ast.RangeStmt:
+						valid = true
+					}
+				}
+				if !valid {
+					check.errorf(s.Label.Pos(), "invalid continue label %s", name)
+					return
+				}
+
+			case token.GOTO:
+				if b.gotoTarget(name) == nil {
+					// label may be declared later - add branch to forward jumps
+					fwdJumps = append(fwdJumps, s)
+					return
+				}
+
+			default:
+				check.invalidAST(s.Pos(), "branch statement: %s %s", s.Tok, name)
+				return
+			}
+
+			// record label use
+			obj := all.Lookup(name)
+			obj.(*Label).used = true
+			check.recordUse(s.Label, obj)
+
+		case *ast.AssignStmt:
+			if s.Tok == token.DEFINE {
+				recordVarDecl(s.Pos())
+			}
+
+		case *ast.BlockStmt:
+			blockBranches(lstmt, s.List)
+
+		case *ast.IfStmt:
+			stmtBranches(s.Body)
+			if s.Else != nil {
+				stmtBranches(s.Else)
+			}
+
+		case *ast.CaseClause:
+			blockBranches(nil, s.Body)
+
+		case *ast.SwitchStmt:
+			stmtBranches(s.Body)
+
+		case *ast.TypeSwitchStmt:
+			stmtBranches(s.Body)
+
+		case *ast.CommClause:
+			blockBranches(nil, s.Body)
+
+		case *ast.SelectStmt:
+			stmtBranches(s.Body)
+
+		case *ast.ForStmt:
+			stmtBranches(s.Body)
+
+		case *ast.RangeStmt:
+			stmtBranches(s.Body)
+		}
+	}
+
+	for _, s := range list {
+		stmtBranches(s)
+	}
+
+	return fwdJumps
+}
diff --git a/third_party/gofrontend/libgo/go/go/types/lookup.go b/third_party/gofrontend/libgo/go/go/types/lookup.go
new file mode 100644
index 0000000..3caca55
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/go/types/lookup.go
@@ -0,0 +1,341 @@
+// Copyright 2013 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.
+
+// This file implements various field and method lookup functions.
+
+package types
+
+// LookupFieldOrMethod looks up a field or method with given package and name
+// in T and returns the corresponding *Var or *Func, an index sequence, and a
+// bool indicating if there were any pointer indirections on the path to the
+// field or method. If addressable is set, T is the type of an addressable
+// variable (only matters for method lookups).
+//
+// The last index entry is the field or method index in the (possibly embedded)
+// type where the entry was found, either:
+//
+//	1) the list of declared methods of a named type; or
+//	2) the list of all methods (method set) of an interface type; or
+//	3) the list of fields of a struct type.
+//
+// The earlier index entries are the indices of the anonymous struct fields
+// traversed to get to the found entry, starting at depth 0.
+//
+// If no entry is found, a nil object is returned. In this case, the returned
+// index and indirect values have the following meaning:
+//
+//	- If index != nil, the index sequence points to an ambiguous entry
+//	(the same name appeared more than once at the same embedding level).
+//
+//	- If indirect is set, a method with a pointer receiver type was found
+//      but there was no pointer on the path from the actual receiver type to
+//	the method's formal receiver base type, nor was the receiver addressable.
+//
+func LookupFieldOrMethod(T Type, addressable bool, pkg *Package, name string) (obj Object, index []int, indirect bool) {
+	// Methods cannot be associated to a named pointer type
+	// (spec: "The type denoted by T is called the receiver base type;
+	// it must not be a pointer or interface type and it must be declared
+	// in the same package as the method.").
+	// Thus, if we have a named pointer type, proceed with the underlying
+	// pointer type but discard the result if it is a method since we would
+	// not have found it for T (see also issue 8590).
+	if t, _ := T.(*Named); t != nil {
+		if p, _ := t.underlying.(*Pointer); p != nil {
+			obj, index, indirect = lookupFieldOrMethod(p, false, pkg, name)
+			if _, ok := obj.(*Func); ok {
+				return nil, nil, false
+			}
+			return
+		}
+	}
+
+	return lookupFieldOrMethod(T, addressable, pkg, name)
+}
+
+// TODO(gri) The named type consolidation and seen maps below must be
+//           indexed by unique keys for a given type. Verify that named
+//           types always have only one representation (even when imported
+//           indirectly via different packages.)
+
+func lookupFieldOrMethod(T Type, addressable bool, pkg *Package, name string) (obj Object, index []int, indirect bool) {
+	// WARNING: The code in this function is extremely subtle - do not modify casually!
+	//          This function and NewMethodSet should be kept in sync.
+
+	if name == "_" {
+		return // blank fields/methods are never found
+	}
+
+	typ, isPtr := deref(T)
+	named, _ := typ.(*Named)
+
+	// *typ where typ is an interface has no methods.
+	if isPtr {
+		utyp := typ
+		if named != nil {
+			utyp = named.underlying
+		}
+		if _, ok := utyp.(*Interface); ok {
+			return
+		}
+	}
+
+	// Start with typ as single entry at shallowest depth.
+	// If typ is not a named type, insert a nil type instead.
+	current := []embeddedType{{named, nil, isPtr, false}}
+
+	// named types that we have seen already, allocated lazily
+	var seen map[*Named]bool
+
+	// search current depth
+	for len(current) > 0 {
+		var next []embeddedType // embedded types found at current depth
+
+		// look for (pkg, name) in all types at current depth
+		for _, e := range current {
+			// The very first time only, e.typ may be nil.
+			// In this case, we don't have a named type and
+			// we simply continue with the underlying type.
+			if e.typ != nil {
+				if seen[e.typ] {
+					// We have seen this type before, at a more shallow depth
+					// (note that multiples of this type at the current depth
+					// were consolidated before). The type at that depth shadows
+					// this same type at the current depth, so we can ignore
+					// this one.
+					continue
+				}
+				if seen == nil {
+					seen = make(map[*Named]bool)
+				}
+				seen[e.typ] = true
+
+				// look for a matching attached method
+				if i, m := lookupMethod(e.typ.methods, pkg, name); m != nil {
+					// potential match
+					assert(m.typ != nil)
+					index = concat(e.index, i)
+					if obj != nil || e.multiples {
+						return nil, index, false // collision
+					}
+					obj = m
+					indirect = e.indirect
+					continue // we can't have a matching field or interface method
+				}
+
+				// continue with underlying type
+				typ = e.typ.underlying
+			}
+
+			switch t := typ.(type) {
+			case *Struct:
+				// look for a matching field and collect embedded types
+				for i, f := range t.fields {
+					if f.sameId(pkg, name) {
+						assert(f.typ != nil)
+						index = concat(e.index, i)
+						if obj != nil || e.multiples {
+							return nil, index, false // collision
+						}
+						obj = f
+						indirect = e.indirect
+						continue // we can't have a matching interface method
+					}
+					// Collect embedded struct fields for searching the next
+					// lower depth, but only if we have not seen a match yet
+					// (if we have a match it is either the desired field or
+					// we have a name collision on the same depth; in either
+					// case we don't need to look further).
+					// Embedded fields are always of the form T or *T where
+					// T is a named type. If e.typ appeared multiple times at
+					// this depth, f.typ appears multiple times at the next
+					// depth.
+					if obj == nil && f.anonymous {
+						// Ignore embedded basic types - only user-defined
+						// named types can have methods or struct fields.
+						typ, isPtr := deref(f.typ)
+						if t, _ := typ.(*Named); t != nil {
+							next = append(next, embeddedType{t, concat(e.index, i), e.indirect || isPtr, e.multiples})
+						}
+					}
+				}
+
+			case *Interface:
+				// look for a matching method
+				// TODO(gri) t.allMethods is sorted - use binary search
+				if i, m := lookupMethod(t.allMethods, pkg, name); m != nil {
+					assert(m.typ != nil)
+					index = concat(e.index, i)
+					if obj != nil || e.multiples {
+						return nil, index, false // collision
+					}
+					obj = m
+					indirect = e.indirect
+				}
+			}
+		}
+
+		if obj != nil {
+			// found a potential match
+			// spec: "A method call x.m() is valid if the method set of (the type of) x
+			//        contains m and the argument list can be assigned to the parameter
+			//        list of m. If x is addressable and &x's method set contains m, x.m()
+			//        is shorthand for (&x).m()".
+			if f, _ := obj.(*Func); f != nil && ptrRecv(f) && !indirect && !addressable {
+				return nil, nil, true // pointer/addressable receiver required
+			}
+			return
+		}
+
+		current = consolidateMultiples(next)
+	}
+
+	return nil, nil, false // not found
+}
+
+// embeddedType represents an embedded named type
+type embeddedType struct {
+	typ       *Named // nil means use the outer typ variable instead
+	index     []int  // embedded field indices, starting with index at depth 0
+	indirect  bool   // if set, there was a pointer indirection on the path to this field
+	multiples bool   // if set, typ appears multiple times at this depth
+}
+
+// consolidateMultiples collects multiple list entries with the same type
+// into a single entry marked as containing multiples. The result is the
+// consolidated list.
+func consolidateMultiples(list []embeddedType) []embeddedType {
+	if len(list) <= 1 {
+		return list // at most one entry - nothing to do
+	}
+
+	n := 0                       // number of entries w/ unique type
+	prev := make(map[*Named]int) // index at which type was previously seen
+	for _, e := range list {
+		if i, found := prev[e.typ]; found {
+			list[i].multiples = true
+			// ignore this entry
+		} else {
+			prev[e.typ] = n
+			list[n] = e
+			n++
+		}
+	}
+	return list[:n]
+}
+
+// MissingMethod returns (nil, false) if V implements T, otherwise it
+// returns a missing method required by T and whether it is missing or
+// just has the wrong type.
+//
+// For non-interface types V, or if static is set, V implements T if all
+// methods of T are present in V. Otherwise (V is an interface and static
+// is not set), MissingMethod only checks that methods of T which are also
+// present in V have matching types (e.g., for a type assertion x.(T) where
+// x is of interface type V).
+//
+func MissingMethod(V Type, T *Interface, static bool) (method *Func, wrongType bool) {
+	// fast path for common case
+	if T.Empty() {
+		return
+	}
+
+	// TODO(gri) Consider using method sets here. Might be more efficient.
+
+	if ityp, _ := V.Underlying().(*Interface); ityp != nil {
+		// TODO(gri) allMethods is sorted - can do this more efficiently
+		for _, m := range T.allMethods {
+			_, obj := lookupMethod(ityp.allMethods, m.pkg, m.name)
+			switch {
+			case obj == nil:
+				if static {
+					return m, false
+				}
+			case !Identical(obj.Type(), m.typ):
+				return m, true
+			}
+		}
+		return
+	}
+
+	// A concrete type implements T if it implements all methods of T.
+	for _, m := range T.allMethods {
+		obj, _, _ := lookupFieldOrMethod(V, false, m.pkg, m.name)
+
+		f, _ := obj.(*Func)
+		if f == nil {
+			return m, false
+		}
+
+		if !Identical(f.typ, m.typ) {
+			return m, true
+		}
+	}
+
+	return
+}
+
+// assertableTo reports whether a value of type V can be asserted to have type T.
+// It returns (nil, false) as affirmative answer. Otherwise it returns a missing
+// method required by V and whether it is missing or just has the wrong type.
+func assertableTo(V *Interface, T Type) (method *Func, wrongType bool) {
+	// no static check is required if T is an interface
+	// spec: "If T is an interface type, x.(T) asserts that the
+	//        dynamic type of x implements the interface T."
+	if _, ok := T.Underlying().(*Interface); ok && !strict {
+		return
+	}
+	return MissingMethod(T, V, false)
+}
+
+// deref dereferences typ if it is a *Pointer and returns its base and true.
+// Otherwise it returns (typ, false).
+func deref(typ Type) (Type, bool) {
+	if p, _ := typ.(*Pointer); p != nil {
+		return p.base, true
+	}
+	return typ, false
+}
+
+// derefStructPtr dereferences typ if it is a (named or unnamed) pointer to a
+// (named or unnamed) struct and returns its base. Otherwise it returns typ.
+func derefStructPtr(typ Type) Type {
+	if p, _ := typ.Underlying().(*Pointer); p != nil {
+		if _, ok := p.base.Underlying().(*Struct); ok {
+			return p.base
+		}
+	}
+	return typ
+}
+
+// concat returns the result of concatenating list and i.
+// The result does not share its underlying array with list.
+func concat(list []int, i int) []int {
+	var t []int
+	t = append(t, list...)
+	return append(t, i)
+}
+
+// fieldIndex returns the index for the field with matching package and name, or a value < 0.
+func fieldIndex(fields []*Var, pkg *Package, name string) int {
+	if name != "_" {
+		for i, f := range fields {
+			if f.sameId(pkg, name) {
+				return i
+			}
+		}
+	}
+	return -1
+}
+
+// lookupMethod returns the index of and method with matching package and name, or (-1, nil).
+func lookupMethod(methods []*Func, pkg *Package, name string) (int, *Func) {
+	if name != "_" {
+		for i, m := range methods {
+			if m.sameId(pkg, name) {
+				return i, m
+			}
+		}
+	}
+	return -1, nil
+}
diff --git a/third_party/gofrontend/libgo/go/go/types/methodset.go b/third_party/gofrontend/libgo/go/go/types/methodset.go
new file mode 100644
index 0000000..b27f2da
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/go/types/methodset.go
@@ -0,0 +1,268 @@
+// Copyright 2013 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.
+
+// This file implements method sets.
+
+package types
+
+import (
+	"bytes"
+	"fmt"
+	"sort"
+)
+
+// A MethodSet is an ordered set of concrete or abstract (interface) methods;
+// a method is a MethodVal selection, and they are ordered by ascending m.Obj().Id().
+// The zero value for a MethodSet is a ready-to-use empty method set.
+type MethodSet struct {
+	list []*Selection
+}
+
+func (s *MethodSet) String() string {
+	if s.Len() == 0 {
+		return "MethodSet {}"
+	}
+
+	var buf bytes.Buffer
+	fmt.Fprintln(&buf, "MethodSet {")
+	for _, f := range s.list {
+		fmt.Fprintf(&buf, "\t%s\n", f)
+	}
+	fmt.Fprintln(&buf, "}")
+	return buf.String()
+}
+
+// Len returns the number of methods in s.
+func (s *MethodSet) Len() int { return len(s.list) }
+
+// At returns the i'th method in s for 0 <= i < s.Len().
+func (s *MethodSet) At(i int) *Selection { return s.list[i] }
+
+// Lookup returns the method with matching package and name, or nil if not found.
+func (s *MethodSet) Lookup(pkg *Package, name string) *Selection {
+	if s.Len() == 0 {
+		return nil
+	}
+
+	key := Id(pkg, name)
+	i := sort.Search(len(s.list), func(i int) bool {
+		m := s.list[i]
+		return m.obj.Id() >= key
+	})
+	if i < len(s.list) {
+		m := s.list[i]
+		if m.obj.Id() == key {
+			return m
+		}
+	}
+	return nil
+}
+
+// Shared empty method set.
+var emptyMethodSet MethodSet
+
+// NewMethodSet returns the method set for the given type T.
+// It always returns a non-nil method set, even if it is empty.
+func NewMethodSet(T Type) *MethodSet {
+	// WARNING: The code in this function is extremely subtle - do not modify casually!
+	//          This function and lookupFieldOrMethod should be kept in sync.
+
+	// method set up to the current depth, allocated lazily
+	var base methodSet
+
+	typ, isPtr := deref(T)
+	named, _ := typ.(*Named)
+
+	// *typ where typ is an interface has no methods.
+	if isPtr {
+		utyp := typ
+		if named != nil {
+			utyp = named.underlying
+		}
+		if _, ok := utyp.(*Interface); ok {
+			return &emptyMethodSet
+		}
+	}
+
+	// Start with typ as single entry at shallowest depth.
+	// If typ is not a named type, insert a nil type instead.
+	current := []embeddedType{{named, nil, isPtr, false}}
+
+	// named types that we have seen already, allocated lazily
+	var seen map[*Named]bool
+
+	// collect methods at current depth
+	for len(current) > 0 {
+		var next []embeddedType // embedded types found at current depth
+
+		// field and method sets at current depth, allocated lazily
+		var fset fieldSet
+		var mset methodSet
+
+		for _, e := range current {
+			// The very first time only, e.typ may be nil.
+			// In this case, we don't have a named type and
+			// we simply continue with the underlying type.
+			if e.typ != nil {
+				if seen[e.typ] {
+					// We have seen this type before, at a more shallow depth
+					// (note that multiples of this type at the current depth
+					// were consolidated before). The type at that depth shadows
+					// this same type at the current depth, so we can ignore
+					// this one.
+					continue
+				}
+				if seen == nil {
+					seen = make(map[*Named]bool)
+				}
+				seen[e.typ] = true
+
+				mset = mset.add(e.typ.methods, e.index, e.indirect, e.multiples)
+
+				// continue with underlying type
+				typ = e.typ.underlying
+			}
+
+			switch t := typ.(type) {
+			case *Struct:
+				for i, f := range t.fields {
+					fset = fset.add(f, e.multiples)
+
+					// Embedded fields are always of the form T or *T where
+					// T is a named type. If typ appeared multiple times at
+					// this depth, f.Type appears multiple times at the next
+					// depth.
+					if f.anonymous {
+						// Ignore embedded basic types - only user-defined
+						// named types can have methods or struct fields.
+						typ, isPtr := deref(f.typ)
+						if t, _ := typ.(*Named); t != nil {
+							next = append(next, embeddedType{t, concat(e.index, i), e.indirect || isPtr, e.multiples})
+						}
+					}
+				}
+
+			case *Interface:
+				mset = mset.add(t.allMethods, e.index, true, e.multiples)
+			}
+		}
+
+		// Add methods and collisions at this depth to base if no entries with matching
+		// names exist already.
+		for k, m := range mset {
+			if _, found := base[k]; !found {
+				// Fields collide with methods of the same name at this depth.
+				if _, found := fset[k]; found {
+					m = nil // collision
+				}
+				if base == nil {
+					base = make(methodSet)
+				}
+				base[k] = m
+			}
+		}
+
+		// Multiple fields with matching names collide at this depth and shadow all
+		// entries further down; add them as collisions to base if no entries with
+		// matching names exist already.
+		for k, f := range fset {
+			if f == nil {
+				if _, found := base[k]; !found {
+					if base == nil {
+						base = make(methodSet)
+					}
+					base[k] = nil // collision
+				}
+			}
+		}
+
+		current = consolidateMultiples(next)
+	}
+
+	if len(base) == 0 {
+		return &emptyMethodSet
+	}
+
+	// collect methods
+	var list []*Selection
+	for _, m := range base {
+		if m != nil {
+			m.recv = T
+			list = append(list, m)
+		}
+	}
+	sort.Sort(byUniqueName(list))
+	return &MethodSet{list}
+}
+
+// A fieldSet is a set of fields and name collisions.
+// A collision indicates that multiple fields with the
+// same unique id appeared.
+type fieldSet map[string]*Var // a nil entry indicates a name collision
+
+// Add adds field f to the field set s.
+// If multiples is set, f appears multiple times
+// and is treated as a collision.
+func (s fieldSet) add(f *Var, multiples bool) fieldSet {
+	if s == nil {
+		s = make(fieldSet)
+	}
+	key := f.Id()
+	// if f is not in the set, add it
+	if !multiples {
+		if _, found := s[key]; !found {
+			s[key] = f
+			return s
+		}
+	}
+	s[key] = nil // collision
+	return s
+}
+
+// A methodSet is a set of methods and name collisions.
+// A collision indicates that multiple methods with the
+// same unique id appeared.
+type methodSet map[string]*Selection // a nil entry indicates a name collision
+
+// Add adds all functions in list to the method set s.
+// If multiples is set, every function in list appears multiple times
+// and is treated as a collision.
+func (s methodSet) add(list []*Func, index []int, indirect bool, multiples bool) methodSet {
+	if len(list) == 0 {
+		return s
+	}
+	if s == nil {
+		s = make(methodSet)
+	}
+	for i, f := range list {
+		key := f.Id()
+		// if f is not in the set, add it
+		if !multiples {
+			// TODO(gri) A found method may not be added because it's not in the method set
+			// (!indirect && ptrRecv(f)). A 2nd method on the same level may be in the method
+			// set and may not collide with the first one, thus leading to a false positive.
+			// Is that possible? Investigate.
+			if _, found := s[key]; !found && (indirect || !ptrRecv(f)) {
+				s[key] = &Selection{MethodVal, nil, f, concat(index, i), indirect}
+				continue
+			}
+		}
+		s[key] = nil // collision
+	}
+	return s
+}
+
+// ptrRecv reports whether the receiver is of the form *T.
+// The receiver must exist.
+func ptrRecv(f *Func) bool {
+	_, isPtr := deref(f.typ.(*Signature).recv.typ)
+	return isPtr
+}
+
+// byUniqueName function lists can be sorted by their unique names.
+type byUniqueName []*Selection
+
+func (a byUniqueName) Len() int           { return len(a) }
+func (a byUniqueName) Less(i, j int) bool { return a[i].obj.Id() < a[j].obj.Id() }
+func (a byUniqueName) Swap(i, j int)      { a[i], a[j] = a[j], a[i] }
diff --git a/third_party/gofrontend/libgo/go/go/types/object.go b/third_party/gofrontend/libgo/go/go/types/object.go
new file mode 100644
index 0000000..b835c6e
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/go/types/object.go
@@ -0,0 +1,360 @@
+// Copyright 2013 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 types
+
+import (
+	"bytes"
+	"fmt"
+	"go/ast"
+	"go/constant"
+	"go/token"
+)
+
+// TODO(gri) Document factory, accessor methods, and fields. General clean-up.
+
+// An Object describes a named language entity such as a package,
+// constant, type, variable, function (incl. methods), or label.
+// All objects implement the Object interface.
+//
+type Object interface {
+	Parent() *Scope // scope in which this object is declared
+	Pos() token.Pos // position of object identifier in declaration
+	Pkg() *Package  // nil for objects in the Universe scope and labels
+	Name() string   // package local object name
+	Type() Type     // object type
+	Exported() bool // reports whether the name starts with a capital letter
+	Id() string     // object id (see Id below)
+
+	// String returns a human-readable string of the object.
+	String() string
+
+	// order reflects a package-level object's source order: if object
+	// a is before object b in the source, then a.order() < b.order().
+	// order returns a value > 0 for package-level objects; it returns
+	// 0 for all other objects (including objects in file scopes).
+	order() uint32
+
+	// setOrder sets the order number of the object. It must be > 0.
+	setOrder(uint32)
+
+	// setParent sets the parent scope of the object.
+	setParent(*Scope)
+
+	// sameId reports whether obj.Id() and Id(pkg, name) are the same.
+	sameId(pkg *Package, name string) bool
+
+	// scopePos returns the start position of the scope of this Object
+	scopePos() token.Pos
+
+	// setScopePos sets the start position of the scope for this Object.
+	setScopePos(pos token.Pos)
+}
+
+// Id returns name if it is exported, otherwise it
+// returns the name qualified with the package path.
+func Id(pkg *Package, name string) string {
+	if ast.IsExported(name) {
+		return name
+	}
+	// unexported names need the package path for differentiation
+	// (if there's no package, make sure we don't start with '.'
+	// as that may change the order of methods between a setup
+	// inside a package and outside a package - which breaks some
+	// tests)
+	path := "_"
+	// TODO(gri): shouldn't !ast.IsExported(name) => pkg != nil be an precondition?
+	// if pkg == nil {
+	// 	panic("nil package in lookup of unexported name")
+	// }
+	if pkg != nil {
+		path = pkg.path
+		if path == "" {
+			path = "_"
+		}
+	}
+	return path + "." + name
+}
+
+// An object implements the common parts of an Object.
+type object struct {
+	parent    *Scope
+	pos       token.Pos
+	pkg       *Package
+	name      string
+	typ       Type
+	order_    uint32
+	scopePos_ token.Pos
+}
+
+func (obj *object) Parent() *Scope      { return obj.parent }
+func (obj *object) Pos() token.Pos      { return obj.pos }
+func (obj *object) Pkg() *Package       { return obj.pkg }
+func (obj *object) Name() string        { return obj.name }
+func (obj *object) Type() Type          { return obj.typ }
+func (obj *object) Exported() bool      { return ast.IsExported(obj.name) }
+func (obj *object) Id() string          { return Id(obj.pkg, obj.name) }
+func (obj *object) String() string      { panic("abstract") }
+func (obj *object) order() uint32       { return obj.order_ }
+func (obj *object) scopePos() token.Pos { return obj.scopePos_ }
+
+func (obj *object) setParent(parent *Scope)   { obj.parent = parent }
+func (obj *object) setOrder(order uint32)     { assert(order > 0); obj.order_ = order }
+func (obj *object) setScopePos(pos token.Pos) { obj.scopePos_ = pos }
+
+func (obj *object) sameId(pkg *Package, name string) bool {
+	// spec:
+	// "Two identifiers are different if they are spelled differently,
+	// or if they appear in different packages and are not exported.
+	// Otherwise, they are the same."
+	if name != obj.name {
+		return false
+	}
+	// obj.Name == name
+	if obj.Exported() {
+		return true
+	}
+	// not exported, so packages must be the same (pkg == nil for
+	// fields in Universe scope; this can only happen for types
+	// introduced via Eval)
+	if pkg == nil || obj.pkg == nil {
+		return pkg == obj.pkg
+	}
+	// pkg != nil && obj.pkg != nil
+	return pkg.path == obj.pkg.path
+}
+
+// A PkgName represents an imported Go package.
+type PkgName struct {
+	object
+	imported *Package
+	used     bool // set if the package was used
+}
+
+func NewPkgName(pos token.Pos, pkg *Package, name string, imported *Package) *PkgName {
+	return &PkgName{object{nil, pos, pkg, name, Typ[Invalid], 0, token.NoPos}, imported, false}
+}
+
+// Imported returns the package that was imported.
+// It is distinct from Pkg(), which is the package containing the import statement.
+func (obj *PkgName) Imported() *Package { return obj.imported }
+
+// A Const represents a declared constant.
+type Const struct {
+	object
+	val     constant.Value
+	visited bool // for initialization cycle detection
+}
+
+func NewConst(pos token.Pos, pkg *Package, name string, typ Type, val constant.Value) *Const {
+	return &Const{object{nil, pos, pkg, name, typ, 0, token.NoPos}, val, false}
+}
+
+func (obj *Const) Val() constant.Value { return obj.val }
+
+// A TypeName represents a declared type.
+type TypeName struct {
+	object
+}
+
+func NewTypeName(pos token.Pos, pkg *Package, name string, typ Type) *TypeName {
+	return &TypeName{object{nil, pos, pkg, name, typ, 0, token.NoPos}}
+}
+
+// A Variable represents a declared variable (including function parameters and results, and struct fields).
+type Var struct {
+	object
+	anonymous bool // if set, the variable is an anonymous struct field, and name is the type name
+	visited   bool // for initialization cycle detection
+	isField   bool // var is struct field
+	used      bool // set if the variable was used
+}
+
+func NewVar(pos token.Pos, pkg *Package, name string, typ Type) *Var {
+	return &Var{object: object{nil, pos, pkg, name, typ, 0, token.NoPos}}
+}
+
+func NewParam(pos token.Pos, pkg *Package, name string, typ Type) *Var {
+	return &Var{object: object{nil, pos, pkg, name, typ, 0, token.NoPos}, used: true} // parameters are always 'used'
+}
+
+func NewField(pos token.Pos, pkg *Package, name string, typ Type, anonymous bool) *Var {
+	return &Var{object: object{nil, pos, pkg, name, typ, 0, token.NoPos}, anonymous: anonymous, isField: true}
+}
+
+func (obj *Var) Anonymous() bool { return obj.anonymous }
+
+func (obj *Var) IsField() bool { return obj.isField }
+
+// A Func represents a declared function, concrete method, or abstract
+// (interface) method.  Its Type() is always a *Signature.
+// An abstract method may belong to many interfaces due to embedding.
+type Func struct {
+	object
+}
+
+func NewFunc(pos token.Pos, pkg *Package, name string, sig *Signature) *Func {
+	// don't store a nil signature
+	var typ Type
+	if sig != nil {
+		typ = sig
+	}
+	return &Func{object{nil, pos, pkg, name, typ, 0, token.NoPos}}
+}
+
+// FullName returns the package- or receiver-type-qualified name of
+// function or method obj.
+func (obj *Func) FullName() string {
+	var buf bytes.Buffer
+	writeFuncName(&buf, obj, nil)
+	return buf.String()
+}
+
+func (obj *Func) Scope() *Scope {
+	return obj.typ.(*Signature).scope
+}
+
+// A Label represents a declared label.
+type Label struct {
+	object
+	used bool // set if the label was used
+}
+
+func NewLabel(pos token.Pos, pkg *Package, name string) *Label {
+	return &Label{object{pos: pos, pkg: pkg, name: name, typ: Typ[Invalid]}, false}
+}
+
+// A Builtin represents a built-in function.
+// Builtins don't have a valid type.
+type Builtin struct {
+	object
+	id builtinId
+}
+
+func newBuiltin(id builtinId) *Builtin {
+	return &Builtin{object{name: predeclaredFuncs[id].name, typ: Typ[Invalid]}, id}
+}
+
+// Nil represents the predeclared value nil.
+type Nil struct {
+	object
+}
+
+func writeObject(buf *bytes.Buffer, obj Object, qf Qualifier) {
+	typ := obj.Type()
+	switch obj := obj.(type) {
+	case *PkgName:
+		fmt.Fprintf(buf, "package %s", obj.Name())
+		if path := obj.imported.path; path != "" && path != obj.name {
+			fmt.Fprintf(buf, " (%q)", path)
+		}
+		return
+
+	case *Const:
+		buf.WriteString("const")
+
+	case *TypeName:
+		buf.WriteString("type")
+		typ = typ.Underlying()
+
+	case *Var:
+		if obj.isField {
+			buf.WriteString("field")
+		} else {
+			buf.WriteString("var")
+		}
+
+	case *Func:
+		buf.WriteString("func ")
+		writeFuncName(buf, obj, qf)
+		if typ != nil {
+			WriteSignature(buf, typ.(*Signature), qf)
+		}
+		return
+
+	case *Label:
+		buf.WriteString("label")
+		typ = nil
+
+	case *Builtin:
+		buf.WriteString("builtin")
+		typ = nil
+
+	case *Nil:
+		buf.WriteString("nil")
+		return
+
+	default:
+		panic(fmt.Sprintf("writeObject(%T)", obj))
+	}
+
+	buf.WriteByte(' ')
+
+	// For package-level objects, qualify the name.
+	if obj.Pkg() != nil && obj.Pkg().scope.Lookup(obj.Name()) == obj {
+		writePackage(buf, obj.Pkg(), qf)
+	}
+	buf.WriteString(obj.Name())
+	if typ != nil {
+		buf.WriteByte(' ')
+		WriteType(buf, typ, qf)
+	}
+}
+
+func writePackage(buf *bytes.Buffer, pkg *Package, qf Qualifier) {
+	if pkg == nil {
+		return
+	}
+	var s string
+	if qf != nil {
+		s = qf(pkg)
+	} else {
+		s = pkg.Path()
+	}
+	if s != "" {
+		buf.WriteString(s)
+		buf.WriteByte('.')
+	}
+}
+
+// ObjectString returns the string form of obj.
+// The Qualifier controls the printing of
+// package-level objects, and may be nil.
+func ObjectString(obj Object, qf Qualifier) string {
+	var buf bytes.Buffer
+	writeObject(&buf, obj, qf)
+	return buf.String()
+}
+
+func (obj *PkgName) String() string  { return ObjectString(obj, nil) }
+func (obj *Const) String() string    { return ObjectString(obj, nil) }
+func (obj *TypeName) String() string { return ObjectString(obj, nil) }
+func (obj *Var) String() string      { return ObjectString(obj, nil) }
+func (obj *Func) String() string     { return ObjectString(obj, nil) }
+func (obj *Label) String() string    { return ObjectString(obj, nil) }
+func (obj *Builtin) String() string  { return ObjectString(obj, nil) }
+func (obj *Nil) String() string      { return ObjectString(obj, nil) }
+
+func writeFuncName(buf *bytes.Buffer, f *Func, qf Qualifier) {
+	if f.typ != nil {
+		sig := f.typ.(*Signature)
+		if recv := sig.Recv(); recv != nil {
+			buf.WriteByte('(')
+			if _, ok := recv.Type().(*Interface); ok {
+				// gcimporter creates abstract methods of
+				// named interfaces using the interface type
+				// (not the named type) as the receiver.
+				// Don't print it in full.
+				buf.WriteString("interface")
+			} else {
+				WriteType(buf, recv.Type(), qf)
+			}
+			buf.WriteByte(')')
+			buf.WriteByte('.')
+		} else if f.pkg != nil {
+			writePackage(buf, f.pkg, qf)
+		}
+	}
+	buf.WriteString(f.name)
+}
diff --git a/third_party/gofrontend/libgo/go/go/types/objset.go b/third_party/gofrontend/libgo/go/go/types/objset.go
new file mode 100644
index 0000000..55eb74a
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/go/types/objset.go
@@ -0,0 +1,31 @@
+// Copyright 2013 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.
+
+// This file implements objsets.
+//
+// An objset is similar to a Scope but objset elements
+// are identified by their unique id, instead of their
+// object name.
+
+package types
+
+// An objset is a set of objects identified by their unique id.
+// The zero value for objset is a ready-to-use empty objset.
+type objset map[string]Object // initialized lazily
+
+// insert attempts to insert an object obj into objset s.
+// If s already contains an alternative object alt with
+// the same name, insert leaves s unchanged and returns alt.
+// Otherwise it inserts obj and returns nil.
+func (s *objset) insert(obj Object) Object {
+	id := obj.Id()
+	if alt := (*s)[id]; alt != nil {
+		return alt
+	}
+	if *s == nil {
+		*s = make(map[string]Object)
+	}
+	(*s)[id] = obj
+	return nil
+}
diff --git a/third_party/gofrontend/libgo/go/go/types/operand.go b/third_party/gofrontend/libgo/go/go/types/operand.go
new file mode 100644
index 0000000..d3bab51
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/go/types/operand.go
@@ -0,0 +1,287 @@
+// Copyright 2012 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.
+
+// This file defines operands and associated operations.
+
+package types
+
+import (
+	"bytes"
+	"go/ast"
+	"go/constant"
+	"go/token"
+)
+
+// An operandMode specifies the (addressing) mode of an operand.
+type operandMode byte
+
+const (
+	invalid   operandMode = iota // operand is invalid
+	novalue                      // operand represents no value (result of a function call w/o result)
+	builtin                      // operand is a built-in function
+	typexpr                      // operand is a type
+	constant_                    // operand is a constant; the operand's typ is a Basic type
+	variable                     // operand is an addressable variable
+	mapindex                     // operand is a map index expression (acts like a variable on lhs, commaok on rhs of an assignment)
+	value                        // operand is a computed value
+	commaok                      // like value, but operand may be used in a comma,ok expression
+)
+
+var operandModeString = [...]string{
+	invalid:   "invalid operand",
+	novalue:   "no value",
+	builtin:   "built-in",
+	typexpr:   "type",
+	constant_: "constant",
+	variable:  "variable",
+	mapindex:  "map index expression",
+	value:     "value",
+	commaok:   "comma, ok expression",
+}
+
+// An operand represents an intermediate value during type checking.
+// Operands have an (addressing) mode, the expression evaluating to
+// the operand, the operand's type, a value for constants, and an id
+// for built-in functions.
+// The zero value of operand is a ready to use invalid operand.
+//
+type operand struct {
+	mode operandMode
+	expr ast.Expr
+	typ  Type
+	val  constant.Value
+	id   builtinId
+}
+
+// pos returns the position of the expression corresponding to x.
+// If x is invalid the position is token.NoPos.
+//
+func (x *operand) pos() token.Pos {
+	// x.expr may not be set if x is invalid
+	if x.expr == nil {
+		return token.NoPos
+	}
+	return x.expr.Pos()
+}
+
+// Operand string formats
+// (not all "untyped" cases can appear due to the type system,
+// but they fall out naturally here)
+//
+// mode       format
+//
+// invalid    <expr> (               <mode>                    )
+// novalue    <expr> (               <mode>                    )
+// builtin    <expr> (               <mode>                    )
+// typexpr    <expr> (               <mode>                    )
+//
+// constant   <expr> (<untyped kind> <mode>                    )
+// constant   <expr> (               <mode>       of type <typ>)
+// constant   <expr> (<untyped kind> <mode> <val>              )
+// constant   <expr> (               <mode> <val> of type <typ>)
+//
+// variable   <expr> (<untyped kind> <mode>                    )
+// variable   <expr> (               <mode>       of type <typ>)
+//
+// mapindex   <expr> (<untyped kind> <mode>                    )
+// mapindex   <expr> (               <mode>       of type <typ>)
+//
+// value      <expr> (<untyped kind> <mode>                    )
+// value      <expr> (               <mode>       of type <typ>)
+//
+// commaok    <expr> (<untyped kind> <mode>                    )
+// commaok    <expr> (               <mode>       of type <typ>)
+//
+func operandString(x *operand, qf Qualifier) string {
+	var buf bytes.Buffer
+
+	var expr string
+	if x.expr != nil {
+		expr = ExprString(x.expr)
+	} else {
+		switch x.mode {
+		case builtin:
+			expr = predeclaredFuncs[x.id].name
+		case typexpr:
+			expr = TypeString(x.typ, qf)
+		case constant_:
+			expr = x.val.String()
+		}
+	}
+
+	// <expr> (
+	if expr != "" {
+		buf.WriteString(expr)
+		buf.WriteString(" (")
+	}
+
+	// <untyped kind>
+	hasType := false
+	switch x.mode {
+	case invalid, novalue, builtin, typexpr:
+		// no type
+	default:
+		// has type
+		if isUntyped(x.typ) {
+			buf.WriteString(x.typ.(*Basic).name)
+			buf.WriteByte(' ')
+			break
+		}
+		hasType = true
+	}
+
+	// <mode>
+	buf.WriteString(operandModeString[x.mode])
+
+	// <val>
+	if x.mode == constant_ {
+		if s := x.val.String(); s != expr {
+			buf.WriteByte(' ')
+			buf.WriteString(s)
+		}
+	}
+
+	// <typ>
+	if hasType {
+		if x.typ != Typ[Invalid] {
+			buf.WriteString(" of type ")
+			WriteType(&buf, x.typ, qf)
+		} else {
+			buf.WriteString(" with invalid type")
+		}
+	}
+
+	// )
+	if expr != "" {
+		buf.WriteByte(')')
+	}
+
+	return buf.String()
+}
+
+func (x *operand) String() string {
+	return operandString(x, nil)
+}
+
+// setConst sets x to the untyped constant for literal lit.
+func (x *operand) setConst(tok token.Token, lit string) {
+	val := constant.MakeFromLiteral(lit, tok, 0)
+	if val == nil {
+		// TODO(gri) Should we make it an unknown constant instead?
+		x.mode = invalid
+		return
+	}
+
+	var kind BasicKind
+	switch tok {
+	case token.INT:
+		kind = UntypedInt
+	case token.FLOAT:
+		kind = UntypedFloat
+	case token.IMAG:
+		kind = UntypedComplex
+	case token.CHAR:
+		kind = UntypedRune
+	case token.STRING:
+		kind = UntypedString
+	}
+
+	x.mode = constant_
+	x.typ = Typ[kind]
+	x.val = val
+}
+
+// isNil reports whether x is the nil value.
+func (x *operand) isNil() bool {
+	return x.mode == value && x.typ == Typ[UntypedNil]
+}
+
+// TODO(gri) The functions operand.assignableTo, checker.convertUntyped,
+//           checker.representable, and checker.assignment are
+//           overlapping in functionality. Need to simplify and clean up.
+
+// assignableTo reports whether x is assignable to a variable of type T.
+func (x *operand) assignableTo(conf *Config, T Type) bool {
+	if x.mode == invalid || T == Typ[Invalid] {
+		return true // avoid spurious errors
+	}
+
+	V := x.typ
+
+	// x's type is identical to T
+	if Identical(V, T) {
+		return true
+	}
+
+	Vu := V.Underlying()
+	Tu := T.Underlying()
+
+	// T is an interface type and x implements T
+	// (Do this check first as it might succeed early.)
+	if Ti, ok := Tu.(*Interface); ok {
+		if Implements(x.typ, Ti) {
+			return true
+		}
+	}
+
+	// x's type V and T have identical underlying types
+	// and at least one of V or T is not a named type
+	if Identical(Vu, Tu) && (!isNamed(V) || !isNamed(T)) {
+		return true
+	}
+
+	// x is a bidirectional channel value, T is a channel
+	// type, x's type V and T have identical element types,
+	// and at least one of V or T is not a named type
+	if Vc, ok := Vu.(*Chan); ok && Vc.dir == SendRecv {
+		if Tc, ok := Tu.(*Chan); ok && Identical(Vc.elem, Tc.elem) {
+			return !isNamed(V) || !isNamed(T)
+		}
+	}
+
+	// x is the predeclared identifier nil and T is a pointer,
+	// function, slice, map, channel, or interface type
+	if x.isNil() {
+		switch t := Tu.(type) {
+		case *Basic:
+			if t.kind == UnsafePointer {
+				return true
+			}
+		case *Pointer, *Signature, *Slice, *Map, *Chan, *Interface:
+			return true
+		}
+		return false
+	}
+
+	// x is an untyped constant representable by a value of type T
+	// TODO(gri) This is borrowing from checker.convertUntyped and
+	//           checker.representable. Need to clean up.
+	if isUntyped(Vu) {
+		switch t := Tu.(type) {
+		case *Basic:
+			if x.mode == constant_ {
+				return representableConst(x.val, conf, t.kind, nil)
+			}
+			// The result of a comparison is an untyped boolean,
+			// but may not be a constant.
+			if Vb, _ := Vu.(*Basic); Vb != nil {
+				return Vb.kind == UntypedBool && isBoolean(Tu)
+			}
+		case *Interface:
+			return x.isNil() || t.Empty()
+		case *Pointer, *Signature, *Slice, *Map, *Chan:
+			return x.isNil()
+		}
+	}
+
+	return false
+}
+
+// isInteger reports whether x is value of integer type
+// or an untyped constant representable as an integer.
+func (x *operand) isInteger() bool {
+	return x.mode == invalid ||
+		isInteger(x.typ) ||
+		isUntyped(x.typ) && x.mode == constant_ && representableConst(x.val, nil, UntypedInt, nil) // no *Config required for UntypedInt
+}
diff --git a/third_party/gofrontend/libgo/go/go/types/ordering.go b/third_party/gofrontend/libgo/go/go/types/ordering.go
new file mode 100644
index 0000000..6bb98f2
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/go/types/ordering.go
@@ -0,0 +1,127 @@
+// 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.
+
+// This file implements resolveOrder.
+
+package types
+
+import (
+	"go/ast"
+	"sort"
+)
+
+// resolveOrder computes the order in which package-level objects
+// must be type-checked.
+//
+// Interface types appear first in the list, sorted topologically
+// by dependencies on embedded interfaces that are also declared
+// in this package, followed by all other objects sorted in source
+// order.
+//
+// TODO(gri) Consider sorting all types by dependencies here, and
+// in the process check _and_ report type cycles. This may simplify
+// the full type-checking phase.
+//
+func (check *Checker) resolveOrder() []Object {
+	var ifaces, others []Object
+
+	// collect interface types with their dependencies, and all other objects
+	for obj := range check.objMap {
+		if ityp := check.interfaceFor(obj); ityp != nil {
+			ifaces = append(ifaces, obj)
+			// determine dependencies on embedded interfaces
+			for _, f := range ityp.Methods.List {
+				if len(f.Names) == 0 {
+					// Embedded interface: The type must be a (possibly
+					// qualified) identifier denoting another interface.
+					// Imported interfaces are already fully resolved,
+					// so we can ignore qualified identifiers.
+					if ident, _ := f.Type.(*ast.Ident); ident != nil {
+						embedded := check.pkg.scope.Lookup(ident.Name)
+						if check.interfaceFor(embedded) != nil {
+							check.objMap[obj].addDep(embedded)
+						}
+					}
+				}
+			}
+		} else {
+			others = append(others, obj)
+		}
+	}
+
+	// final object order
+	var order []Object
+
+	// sort interface types topologically by dependencies,
+	// and in source order if there are no dependencies
+	sort.Sort(inSourceOrder(ifaces))
+	if debug {
+		for _, obj := range ifaces {
+			assert(check.objMap[obj].mark == 0)
+		}
+	}
+	for _, obj := range ifaces {
+		check.appendInPostOrder(&order, obj)
+	}
+
+	// sort everything else in source order
+	sort.Sort(inSourceOrder(others))
+
+	return append(order, others...)
+}
+
+// interfaceFor returns the AST interface denoted by obj, or nil.
+func (check *Checker) interfaceFor(obj Object) *ast.InterfaceType {
+	tname, _ := obj.(*TypeName)
+	if tname == nil {
+		return nil // not a type
+	}
+	d := check.objMap[obj]
+	if d == nil {
+		check.dump("%s: %s should have been declared", obj.Pos(), obj.Name())
+		unreachable()
+	}
+	if d.typ == nil {
+		return nil // invalid AST - ignore (will be handled later)
+	}
+	ityp, _ := d.typ.(*ast.InterfaceType)
+	return ityp
+}
+
+func (check *Checker) appendInPostOrder(order *[]Object, obj Object) {
+	d := check.objMap[obj]
+	if d.mark != 0 {
+		// We've already seen this object; either because it's
+		// already added to order, or because we have a cycle.
+		// In both cases we stop. Cycle errors are reported
+		// when type-checking types.
+		return
+	}
+	d.mark = 1
+
+	for _, obj := range orderedSetObjects(d.deps) {
+		check.appendInPostOrder(order, obj)
+	}
+
+	*order = append(*order, obj)
+}
+
+func orderedSetObjects(set map[Object]bool) []Object {
+	list := make([]Object, len(set))
+	i := 0
+	for obj := range set {
+		// we don't care about the map element value
+		list[i] = obj
+		i++
+	}
+	sort.Sort(inSourceOrder(list))
+	return list
+}
+
+// inSourceOrder implements the sort.Sort interface.
+type inSourceOrder []Object
+
+func (a inSourceOrder) Len() int           { return len(a) }
+func (a inSourceOrder) Less(i, j int) bool { return a[i].order() < a[j].order() }
+func (a inSourceOrder) Swap(i, j int)      { a[i], a[j] = a[j], a[i] }
diff --git a/third_party/gofrontend/libgo/go/go/types/package.go b/third_party/gofrontend/libgo/go/go/types/package.go
new file mode 100644
index 0000000..48fe839
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/go/types/package.go
@@ -0,0 +1,65 @@
+// Copyright 2013 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 types
+
+import (
+	"fmt"
+	"go/token"
+)
+
+// A Package describes a Go package.
+type Package struct {
+	path     string
+	name     string
+	scope    *Scope
+	complete bool
+	imports  []*Package
+	fake     bool // scope lookup errors are silently dropped if package is fake (internal use only)
+}
+
+// NewPackage returns a new Package for the given package path and name;
+// the name must not be the blank identifier.
+// The package is not complete and contains no explicit imports.
+func NewPackage(path, name string) *Package {
+	if name == "_" {
+		panic("invalid package name _")
+	}
+	scope := NewScope(Universe, token.NoPos, token.NoPos, fmt.Sprintf("package %q", path))
+	return &Package{path: path, name: name, scope: scope}
+}
+
+// Path returns the package path.
+func (pkg *Package) Path() string { return pkg.path }
+
+// Name returns the package name.
+func (pkg *Package) Name() string { return pkg.name }
+
+// Scope returns the (complete or incomplete) package scope
+// holding the objects declared at package level (TypeNames,
+// Consts, Vars, and Funcs).
+func (pkg *Package) Scope() *Scope { return pkg.scope }
+
+// A package is complete if its scope contains (at least) all
+// exported objects; otherwise it is incomplete.
+func (pkg *Package) Complete() bool { return pkg.complete }
+
+// MarkComplete marks a package as complete.
+func (pkg *Package) MarkComplete() { pkg.complete = true }
+
+// Imports returns the list of packages directly imported by
+// pkg; the list is in source order. Package unsafe is excluded.
+//
+// If pkg was loaded from export data, Imports includes packages that
+// provide package-level objects referenced by pkg.  This may be more or
+// less than the set of packages directly imported by pkg's source code.
+func (pkg *Package) Imports() []*Package { return pkg.imports }
+
+// SetImports sets the list of explicitly imported packages to list.
+// It is the caller's responsibility to make sure list elements are unique.
+func (pkg *Package) SetImports(list []*Package) { pkg.imports = list }
+
+func (pkg *Package) String() string {
+	return fmt.Sprintf("package %s (%q)", pkg.name, pkg.path)
+}
diff --git a/third_party/gofrontend/libgo/go/go/types/predicates.go b/third_party/gofrontend/libgo/go/go/types/predicates.go
new file mode 100644
index 0000000..993c6d2
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/go/types/predicates.go
@@ -0,0 +1,309 @@
+// Copyright 2012 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.
+
+// This file implements commonly used type predicates.
+
+package types
+
+import "sort"
+
+func isNamed(typ Type) bool {
+	if _, ok := typ.(*Basic); ok {
+		return ok
+	}
+	_, ok := typ.(*Named)
+	return ok
+}
+
+func isBoolean(typ Type) bool {
+	t, ok := typ.Underlying().(*Basic)
+	return ok && t.info&IsBoolean != 0
+}
+
+func isInteger(typ Type) bool {
+	t, ok := typ.Underlying().(*Basic)
+	return ok && t.info&IsInteger != 0
+}
+
+func isUnsigned(typ Type) bool {
+	t, ok := typ.Underlying().(*Basic)
+	return ok && t.info&IsUnsigned != 0
+}
+
+func isFloat(typ Type) bool {
+	t, ok := typ.Underlying().(*Basic)
+	return ok && t.info&IsFloat != 0
+}
+
+func isComplex(typ Type) bool {
+	t, ok := typ.Underlying().(*Basic)
+	return ok && t.info&IsComplex != 0
+}
+
+func isNumeric(typ Type) bool {
+	t, ok := typ.Underlying().(*Basic)
+	return ok && t.info&IsNumeric != 0
+}
+
+func isString(typ Type) bool {
+	t, ok := typ.Underlying().(*Basic)
+	return ok && t.info&IsString != 0
+}
+
+func isTyped(typ Type) bool {
+	t, ok := typ.Underlying().(*Basic)
+	return !ok || t.info&IsUntyped == 0
+}
+
+func isUntyped(typ Type) bool {
+	t, ok := typ.Underlying().(*Basic)
+	return ok && t.info&IsUntyped != 0
+}
+
+func isOrdered(typ Type) bool {
+	t, ok := typ.Underlying().(*Basic)
+	return ok && t.info&IsOrdered != 0
+}
+
+func isConstType(typ Type) bool {
+	t, ok := typ.Underlying().(*Basic)
+	return ok && t.info&IsConstType != 0
+}
+
+// IsInterface reports whether typ is an interface type.
+func IsInterface(typ Type) bool {
+	_, ok := typ.Underlying().(*Interface)
+	return ok
+}
+
+// Comparable reports whether values of type T are comparable.
+func Comparable(T Type) bool {
+	switch t := T.Underlying().(type) {
+	case *Basic:
+		// assume invalid types to be comparable
+		// to avoid follow-up errors
+		return t.kind != UntypedNil
+	case *Pointer, *Interface, *Chan:
+		return true
+	case *Struct:
+		for _, f := range t.fields {
+			if !Comparable(f.typ) {
+				return false
+			}
+		}
+		return true
+	case *Array:
+		return Comparable(t.elem)
+	}
+	return false
+}
+
+// hasNil reports whether a type includes the nil value.
+func hasNil(typ Type) bool {
+	switch t := typ.Underlying().(type) {
+	case *Basic:
+		return t.kind == UnsafePointer
+	case *Slice, *Pointer, *Signature, *Interface, *Map, *Chan:
+		return true
+	}
+	return false
+}
+
+// Identical reports whether x and y are identical.
+func Identical(x, y Type) bool {
+	return identical(x, y, nil)
+}
+
+// An ifacePair is a node in a stack of interface type pairs compared for identity.
+type ifacePair struct {
+	x, y *Interface
+	prev *ifacePair
+}
+
+func (p *ifacePair) identical(q *ifacePair) bool {
+	return p.x == q.x && p.y == q.y || p.x == q.y && p.y == q.x
+}
+
+func identical(x, y Type, p *ifacePair) bool {
+	if x == y {
+		return true
+	}
+
+	switch x := x.(type) {
+	case *Basic:
+		// Basic types are singletons except for the rune and byte
+		// aliases, thus we cannot solely rely on the x == y check
+		// above.
+		if y, ok := y.(*Basic); ok {
+			return x.kind == y.kind
+		}
+
+	case *Array:
+		// Two array types are identical if they have identical element types
+		// and the same array length.
+		if y, ok := y.(*Array); ok {
+			return x.len == y.len && identical(x.elem, y.elem, p)
+		}
+
+	case *Slice:
+		// Two slice types are identical if they have identical element types.
+		if y, ok := y.(*Slice); ok {
+			return identical(x.elem, y.elem, p)
+		}
+
+	case *Struct:
+		// Two struct types are identical if they have the same sequence of fields,
+		// and if corresponding fields have the same names, and identical types,
+		// and identical tags. Two anonymous fields are considered to have the same
+		// name. Lower-case field names from different packages are always different.
+		if y, ok := y.(*Struct); ok {
+			if x.NumFields() == y.NumFields() {
+				for i, f := range x.fields {
+					g := y.fields[i]
+					if f.anonymous != g.anonymous ||
+						x.Tag(i) != y.Tag(i) ||
+						!f.sameId(g.pkg, g.name) ||
+						!identical(f.typ, g.typ, p) {
+						return false
+					}
+				}
+				return true
+			}
+		}
+
+	case *Pointer:
+		// Two pointer types are identical if they have identical base types.
+		if y, ok := y.(*Pointer); ok {
+			return identical(x.base, y.base, p)
+		}
+
+	case *Tuple:
+		// Two tuples types are identical if they have the same number of elements
+		// and corresponding elements have identical types.
+		if y, ok := y.(*Tuple); ok {
+			if x.Len() == y.Len() {
+				if x != nil {
+					for i, v := range x.vars {
+						w := y.vars[i]
+						if !identical(v.typ, w.typ, p) {
+							return false
+						}
+					}
+				}
+				return true
+			}
+		}
+
+	case *Signature:
+		// Two function types are identical if they have the same number of parameters
+		// and result values, corresponding parameter and result types are identical,
+		// and either both functions are variadic or neither is. Parameter and result
+		// names are not required to match.
+		if y, ok := y.(*Signature); ok {
+			return x.variadic == y.variadic &&
+				identical(x.params, y.params, p) &&
+				identical(x.results, y.results, p)
+		}
+
+	case *Interface:
+		// Two interface types are identical if they have the same set of methods with
+		// the same names and identical function types. Lower-case method names from
+		// different packages are always different. The order of the methods is irrelevant.
+		if y, ok := y.(*Interface); ok {
+			a := x.allMethods
+			b := y.allMethods
+			if len(a) == len(b) {
+				// Interface types are the only types where cycles can occur
+				// that are not "terminated" via named types; and such cycles
+				// can only be created via method parameter types that are
+				// anonymous interfaces (directly or indirectly) embedding
+				// the current interface. Example:
+				//
+				//    type T interface {
+				//        m() interface{T}
+				//    }
+				//
+				// If two such (differently named) interfaces are compared,
+				// endless recursion occurs if the cycle is not detected.
+				//
+				// If x and y were compared before, they must be equal
+				// (if they were not, the recursion would have stopped);
+				// search the ifacePair stack for the same pair.
+				//
+				// This is a quadratic algorithm, but in practice these stacks
+				// are extremely short (bounded by the nesting depth of interface
+				// type declarations that recur via parameter types, an extremely
+				// rare occurrence). An alternative implementation might use a
+				// "visited" map, but that is probably less efficient overall.
+				q := &ifacePair{x, y, p}
+				for p != nil {
+					if p.identical(q) {
+						return true // same pair was compared before
+					}
+					p = p.prev
+				}
+				if debug {
+					assert(sort.IsSorted(byUniqueMethodName(a)))
+					assert(sort.IsSorted(byUniqueMethodName(b)))
+				}
+				for i, f := range a {
+					g := b[i]
+					if f.Id() != g.Id() || !identical(f.typ, g.typ, q) {
+						return false
+					}
+				}
+				return true
+			}
+		}
+
+	case *Map:
+		// Two map types are identical if they have identical key and value types.
+		if y, ok := y.(*Map); ok {
+			return identical(x.key, y.key, p) && identical(x.elem, y.elem, p)
+		}
+
+	case *Chan:
+		// Two channel types are identical if they have identical value types
+		// and the same direction.
+		if y, ok := y.(*Chan); ok {
+			return x.dir == y.dir && identical(x.elem, y.elem, p)
+		}
+
+	case *Named:
+		// Two named types are identical if their type names originate
+		// in the same type declaration.
+		if y, ok := y.(*Named); ok {
+			return x.obj == y.obj
+		}
+
+	default:
+		unreachable()
+	}
+
+	return false
+}
+
+// defaultType returns the default "typed" type for an "untyped" type;
+// it returns the incoming type for all other types. The default type
+// for untyped nil is untyped nil.
+//
+func defaultType(typ Type) Type {
+	if t, ok := typ.(*Basic); ok {
+		switch t.kind {
+		case UntypedBool:
+			return Typ[Bool]
+		case UntypedInt:
+			return Typ[Int]
+		case UntypedRune:
+			return universeRune // use 'rune' name
+		case UntypedFloat:
+			return Typ[Float64]
+		case UntypedComplex:
+			return Typ[Complex128]
+		case UntypedString:
+			return Typ[String]
+		}
+	}
+	return typ
+}
diff --git a/third_party/gofrontend/libgo/go/go/types/resolver.go b/third_party/gofrontend/libgo/go/go/types/resolver.go
new file mode 100644
index 0000000..c31ef42
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/go/types/resolver.go
@@ -0,0 +1,445 @@
+// Copyright 2013 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 types
+
+import (
+	"fmt"
+	"go/ast"
+	"go/constant"
+	"go/token"
+	pathLib "path"
+	"strconv"
+	"strings"
+	"unicode"
+)
+
+// A declInfo describes a package-level const, type, var, or func declaration.
+type declInfo struct {
+	file  *Scope        // scope of file containing this declaration
+	lhs   []*Var        // lhs of n:1 variable declarations, or nil
+	typ   ast.Expr      // type, or nil
+	init  ast.Expr      // init expression, or nil
+	fdecl *ast.FuncDecl // func declaration, or nil
+
+	deps map[Object]bool // type and init dependencies; lazily allocated
+	mark int             // for dependency analysis
+}
+
+// hasInitializer reports whether the declared object has an initialization
+// expression or function body.
+func (d *declInfo) hasInitializer() bool {
+	return d.init != nil || d.fdecl != nil && d.fdecl.Body != nil
+}
+
+// addDep adds obj as a dependency to d.
+func (d *declInfo) addDep(obj Object) {
+	m := d.deps
+	if m == nil {
+		m = make(map[Object]bool)
+		d.deps = m
+	}
+	m[obj] = true
+}
+
+// arityMatch checks that the lhs and rhs of a const or var decl
+// have the appropriate number of names and init exprs. For const
+// decls, init is the value spec providing the init exprs; for
+// var decls, init is nil (the init exprs are in s in this case).
+func (check *Checker) arityMatch(s, init *ast.ValueSpec) {
+	l := len(s.Names)
+	r := len(s.Values)
+	if init != nil {
+		r = len(init.Values)
+	}
+
+	switch {
+	case init == nil && r == 0:
+		// var decl w/o init expr
+		if s.Type == nil {
+			check.errorf(s.Pos(), "missing type or init expr")
+		}
+	case l < r:
+		if l < len(s.Values) {
+			// init exprs from s
+			n := s.Values[l]
+			check.errorf(n.Pos(), "extra init expr %s", n)
+			// TODO(gri) avoid declared but not used error here
+		} else {
+			// init exprs "inherited"
+			check.errorf(s.Pos(), "extra init expr at %s", init.Pos())
+			// TODO(gri) avoid declared but not used error here
+		}
+	case l > r && (init != nil || r != 1):
+		n := s.Names[r]
+		check.errorf(n.Pos(), "missing init expr for %s", n)
+	}
+}
+
+func validatedImportPath(path string) (string, error) {
+	s, err := strconv.Unquote(path)
+	if err != nil {
+		return "", err
+	}
+	if s == "" {
+		return "", fmt.Errorf("empty string")
+	}
+	const illegalChars = `!"#$%&'()*,:;<=>?[\]^{|}` + "`\uFFFD"
+	for _, r := range s {
+		if !unicode.IsGraphic(r) || unicode.IsSpace(r) || strings.ContainsRune(illegalChars, r) {
+			return s, fmt.Errorf("invalid character %#U", r)
+		}
+	}
+	return s, nil
+}
+
+// declarePkgObj declares obj in the package scope, records its ident -> obj mapping,
+// and updates check.objMap. The object must not be a function or method.
+func (check *Checker) declarePkgObj(ident *ast.Ident, obj Object, d *declInfo) {
+	assert(ident.Name == obj.Name())
+
+	// spec: "A package-scope or file-scope identifier with name init
+	// may only be declared to be a function with this (func()) signature."
+	if ident.Name == "init" {
+		check.errorf(ident.Pos(), "cannot declare init - must be func")
+		return
+	}
+
+	check.declare(check.pkg.scope, ident, obj, token.NoPos)
+	check.objMap[obj] = d
+	obj.setOrder(uint32(len(check.objMap)))
+}
+
+// filename returns a filename suitable for debugging output.
+func (check *Checker) filename(fileNo int) string {
+	file := check.files[fileNo]
+	if pos := file.Pos(); pos.IsValid() {
+		return check.fset.File(pos).Name()
+	}
+	return fmt.Sprintf("file[%d]", fileNo)
+}
+
+// collectObjects collects all file and package objects and inserts them
+// into their respective scopes. It also performs imports and associates
+// methods with receiver base type names.
+func (check *Checker) collectObjects() {
+	pkg := check.pkg
+
+	// pkgImports is the set of packages already imported by any package file seen
+	// so far. Used to avoid duplicate entries in pkg.imports. Allocate and populate
+	// it (pkg.imports may not be empty if we are checking test files incrementally).
+	var pkgImports = make(map[*Package]bool)
+	for _, imp := range pkg.imports {
+		pkgImports[imp] = true
+	}
+
+	for fileNo, file := range check.files {
+		// The package identifier denotes the current package,
+		// but there is no corresponding package object.
+		check.recordDef(file.Name, nil)
+
+		// Use the actual source file extent rather than *ast.File extent since the
+		// latter doesn't include comments which appear at the start or end of the file.
+		// Be conservative and use the *ast.File extent if we don't have a *token.File.
+		pos, end := file.Pos(), file.End()
+		if f := check.fset.File(file.Pos()); f != nil {
+			pos, end = token.Pos(f.Base()), token.Pos(f.Base()+f.Size())
+		}
+		fileScope := NewScope(check.pkg.scope, pos, end, check.filename(fileNo))
+		check.recordScope(file, fileScope)
+
+		for _, decl := range file.Decls {
+			switch d := decl.(type) {
+			case *ast.BadDecl:
+				// ignore
+
+			case *ast.GenDecl:
+				var last *ast.ValueSpec // last ValueSpec with type or init exprs seen
+				for iota, spec := range d.Specs {
+					switch s := spec.(type) {
+					case *ast.ImportSpec:
+						// import package
+						var imp *Package
+						path, err := validatedImportPath(s.Path.Value)
+						if err != nil {
+							check.errorf(s.Path.Pos(), "invalid import path (%s)", err)
+							continue
+						}
+						if path == "C" && check.conf.FakeImportC {
+							// TODO(gri) shouldn't create a new one each time
+							imp = NewPackage("C", "C")
+							imp.fake = true
+						} else if path == "unsafe" {
+							// package "unsafe" is known to the language
+							imp = Unsafe
+						} else {
+							if importer := check.conf.Importer; importer != nil {
+								imp, err = importer.Import(path)
+								if imp == nil && err == nil {
+									err = fmt.Errorf("Config.Importer.Import(%s) returned nil but no error", path)
+								}
+							} else {
+								err = fmt.Errorf("Config.Importer not installed")
+							}
+							if err != nil {
+								check.errorf(s.Path.Pos(), "could not import %s (%s)", path, err)
+								continue
+							}
+						}
+
+						// add package to list of explicit imports
+						// (this functionality is provided as a convenience
+						// for clients; it is not needed for type-checking)
+						if !pkgImports[imp] {
+							pkgImports[imp] = true
+							if imp != Unsafe {
+								pkg.imports = append(pkg.imports, imp)
+							}
+						}
+
+						// local name overrides imported package name
+						name := imp.name
+						if s.Name != nil {
+							name = s.Name.Name
+							if name == "init" {
+								check.errorf(s.Name.Pos(), "cannot declare init - must be func")
+								continue
+							}
+						}
+
+						obj := NewPkgName(s.Pos(), pkg, name, imp)
+						if s.Name != nil {
+							// in a dot-import, the dot represents the package
+							check.recordDef(s.Name, obj)
+						} else {
+							check.recordImplicit(s, obj)
+						}
+
+						// add import to file scope
+						if name == "." {
+							// merge imported scope with file scope
+							for _, obj := range imp.scope.elems {
+								// A package scope may contain non-exported objects,
+								// do not import them!
+								if obj.Exported() {
+									// TODO(gri) When we import a package, we create
+									// a new local package object. We should do the
+									// same for each dot-imported object. That way
+									// they can have correct position information.
+									// (We must not modify their existing position
+									// information because the same package - found
+									// via Config.Packages - may be dot-imported in
+									// another package!)
+									check.declare(fileScope, nil, obj, token.NoPos)
+									check.recordImplicit(s, obj)
+								}
+							}
+							// add position to set of dot-import positions for this file
+							// (this is only needed for "imported but not used" errors)
+							check.addUnusedDotImport(fileScope, imp, s.Pos())
+						} else {
+							// declare imported package object in file scope
+							check.declare(fileScope, nil, obj, token.NoPos)
+						}
+
+					case *ast.ValueSpec:
+						switch d.Tok {
+						case token.CONST:
+							// determine which initialization expressions to use
+							switch {
+							case s.Type != nil || len(s.Values) > 0:
+								last = s
+							case last == nil:
+								last = new(ast.ValueSpec) // make sure last exists
+							}
+
+							// declare all constants
+							for i, name := range s.Names {
+								obj := NewConst(name.Pos(), pkg, name.Name, nil, constant.MakeInt64(int64(iota)))
+
+								var init ast.Expr
+								if i < len(last.Values) {
+									init = last.Values[i]
+								}
+
+								d := &declInfo{file: fileScope, typ: last.Type, init: init}
+								check.declarePkgObj(name, obj, d)
+							}
+
+							check.arityMatch(s, last)
+
+						case token.VAR:
+							lhs := make([]*Var, len(s.Names))
+							// If there's exactly one rhs initializer, use
+							// the same declInfo d1 for all lhs variables
+							// so that each lhs variable depends on the same
+							// rhs initializer (n:1 var declaration).
+							var d1 *declInfo
+							if len(s.Values) == 1 {
+								// The lhs elements are only set up after the for loop below,
+								// but that's ok because declareVar only collects the declInfo
+								// for a later phase.
+								d1 = &declInfo{file: fileScope, lhs: lhs, typ: s.Type, init: s.Values[0]}
+							}
+
+							// declare all variables
+							for i, name := range s.Names {
+								obj := NewVar(name.Pos(), pkg, name.Name, nil)
+								lhs[i] = obj
+
+								d := d1
+								if d == nil {
+									// individual assignments
+									var init ast.Expr
+									if i < len(s.Values) {
+										init = s.Values[i]
+									}
+									d = &declInfo{file: fileScope, typ: s.Type, init: init}
+								}
+
+								check.declarePkgObj(name, obj, d)
+							}
+
+							check.arityMatch(s, nil)
+
+						default:
+							check.invalidAST(s.Pos(), "invalid token %s", d.Tok)
+						}
+
+					case *ast.TypeSpec:
+						obj := NewTypeName(s.Name.Pos(), pkg, s.Name.Name, nil)
+						check.declarePkgObj(s.Name, obj, &declInfo{file: fileScope, typ: s.Type})
+
+					default:
+						check.invalidAST(s.Pos(), "unknown ast.Spec node %T", s)
+					}
+				}
+
+			case *ast.FuncDecl:
+				name := d.Name.Name
+				obj := NewFunc(d.Name.Pos(), pkg, name, nil)
+				if d.Recv == nil {
+					// regular function
+					if name == "init" {
+						// don't declare init functions in the package scope - they are invisible
+						obj.parent = pkg.scope
+						check.recordDef(d.Name, obj)
+						// init functions must have a body
+						if d.Body == nil {
+							check.softErrorf(obj.pos, "missing function body")
+						}
+					} else {
+						check.declare(pkg.scope, d.Name, obj, token.NoPos)
+					}
+				} else {
+					// method
+					check.recordDef(d.Name, obj)
+					// Associate method with receiver base type name, if possible.
+					// Ignore methods that have an invalid receiver, or a blank _
+					// receiver name. They will be type-checked later, with regular
+					// functions.
+					if list := d.Recv.List; len(list) > 0 {
+						typ := list[0].Type
+						if ptr, _ := typ.(*ast.StarExpr); ptr != nil {
+							typ = ptr.X
+						}
+						if base, _ := typ.(*ast.Ident); base != nil && base.Name != "_" {
+							check.assocMethod(base.Name, obj)
+						}
+					}
+				}
+				info := &declInfo{file: fileScope, fdecl: d}
+				check.objMap[obj] = info
+				obj.setOrder(uint32(len(check.objMap)))
+
+			default:
+				check.invalidAST(d.Pos(), "unknown ast.Decl node %T", d)
+			}
+		}
+	}
+
+	// verify that objects in package and file scopes have different names
+	for _, scope := range check.pkg.scope.children /* file scopes */ {
+		for _, obj := range scope.elems {
+			if alt := pkg.scope.Lookup(obj.Name()); alt != nil {
+				if pkg, ok := obj.(*PkgName); ok {
+					check.errorf(alt.Pos(), "%s already declared through import of %s", alt.Name(), pkg.Imported())
+					check.reportAltDecl(pkg)
+				} else {
+					check.errorf(alt.Pos(), "%s already declared through dot-import of %s", alt.Name(), obj.Pkg())
+					// TODO(gri) dot-imported objects don't have a position; reportAltDecl won't print anything
+					check.reportAltDecl(obj)
+				}
+			}
+		}
+	}
+}
+
+// packageObjects typechecks all package objects in objList, but not function bodies.
+func (check *Checker) packageObjects(objList []Object) {
+	// add new methods to already type-checked types (from a prior Checker.Files call)
+	for _, obj := range objList {
+		if obj, _ := obj.(*TypeName); obj != nil && obj.typ != nil {
+			check.addMethodDecls(obj)
+		}
+	}
+
+	// pre-allocate space for type declaration paths so that the underlying array is reused
+	typePath := make([]*TypeName, 0, 8)
+
+	for _, obj := range objList {
+		check.objDecl(obj, nil, typePath)
+	}
+
+	// At this point we may have a non-empty check.methods map; this means that not all
+	// entries were deleted at the end of typeDecl because the respective receiver base
+	// types were not found. In that case, an error was reported when declaring those
+	// methods. We can now safely discard this map.
+	check.methods = nil
+}
+
+// functionBodies typechecks all function bodies.
+func (check *Checker) functionBodies() {
+	for _, f := range check.funcs {
+		check.funcBody(f.decl, f.name, f.sig, f.body)
+	}
+}
+
+// unusedImports checks for unused imports.
+func (check *Checker) unusedImports() {
+	// if function bodies are not checked, packages' uses are likely missing - don't check
+	if check.conf.IgnoreFuncBodies {
+		return
+	}
+
+	// spec: "It is illegal (...) to directly import a package without referring to
+	// any of its exported identifiers. To import a package solely for its side-effects
+	// (initialization), use the blank identifier as explicit package name."
+
+	// check use of regular imported packages
+	for _, scope := range check.pkg.scope.children /* file scopes */ {
+		for _, obj := range scope.elems {
+			if obj, ok := obj.(*PkgName); ok {
+				// Unused "blank imports" are automatically ignored
+				// since _ identifiers are not entered into scopes.
+				if !obj.used {
+					path := obj.imported.path
+					base := pathLib.Base(path)
+					if obj.name == base {
+						check.softErrorf(obj.pos, "%q imported but not used", path)
+					} else {
+						check.softErrorf(obj.pos, "%q imported but not used as %s", path, obj.name)
+					}
+				}
+			}
+		}
+	}
+
+	// check use of dot-imported packages
+	for _, unusedDotImports := range check.unusedDotImports {
+		for pkg, pos := range unusedDotImports {
+			check.softErrorf(pos, "%q imported but not used", pkg.path)
+		}
+	}
+}
diff --git a/third_party/gofrontend/libgo/go/go/types/resolver_test.go b/third_party/gofrontend/libgo/go/go/types/resolver_test.go
new file mode 100644
index 0000000..34deae2
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/go/types/resolver_test.go
@@ -0,0 +1,209 @@
+// Copyright 2011 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 types_test
+
+import (
+	"fmt"
+	"go/ast"
+	"go/importer"
+	"go/parser"
+	"go/token"
+	"internal/testenv"
+	"sort"
+	"testing"
+
+	. "go/types"
+)
+
+type resolveTestImporter struct {
+	importer Importer
+	imported map[string]bool
+}
+
+func (imp *resolveTestImporter) Import(path string) (*Package, error) {
+	if imp.importer == nil {
+		imp.importer = importer.Default()
+		imp.imported = make(map[string]bool)
+	}
+	pkg, err := imp.importer.Import(path)
+	if err != nil {
+		return nil, err
+	}
+	imp.imported[path] = true
+	return pkg, nil
+}
+
+func TestResolveIdents(t *testing.T) {
+	testenv.MustHaveGoBuild(t)
+
+	sources := []string{
+		`
+		package p
+		import "fmt"
+		import "math"
+		const pi = math.Pi
+		func sin(x float64) float64 {
+			return math.Sin(x)
+		}
+		var Println = fmt.Println
+		`,
+		`
+		package p
+		import "fmt"
+		type errorStringer struct { fmt.Stringer; error }
+		func f() string {
+			_ = "foo"
+			return fmt.Sprintf("%d", g())
+		}
+		func g() (x int) { return }
+		`,
+		`
+		package p
+		import . "go/parser"
+		import "sync"
+		func h() Mode { return ImportsOnly }
+		var _, x int = 1, 2
+		func init() {}
+		type T struct{ *sync.Mutex; a, b, c int}
+		type I interface{ m() }
+		var _ = T{a: 1, b: 2, c: 3}
+		func (_ T) m() {}
+		func (T) _() {}
+		var i I
+		var _ = i.m
+		func _(s []int) { for i, x := range s { _, _ = i, x } }
+		func _(x interface{}) {
+			switch x := x.(type) {
+			case int:
+				_ = x
+			}
+			switch {} // implicit 'true' tag
+		}
+		`,
+		`
+		package p
+		type S struct{}
+		func (T) _() {}
+		func (T) _() {}
+		`,
+		`
+		package p
+		func _() {
+		L0:
+		L1:
+			goto L0
+			for {
+				goto L1
+			}
+			if true {
+				goto L2
+			}
+		L2:
+		}
+		`,
+	}
+
+	pkgnames := []string{
+		"fmt",
+		"math",
+	}
+
+	// parse package files
+	fset := token.NewFileSet()
+	var files []*ast.File
+	for i, src := range sources {
+		f, err := parser.ParseFile(fset, fmt.Sprintf("sources[%d]", i), src, parser.DeclarationErrors)
+		if err != nil {
+			t.Fatal(err)
+		}
+		files = append(files, f)
+	}
+
+	// resolve and type-check package AST
+	importer := new(resolveTestImporter)
+	conf := Config{Importer: importer}
+	uses := make(map[*ast.Ident]Object)
+	defs := make(map[*ast.Ident]Object)
+	_, err := conf.Check("testResolveIdents", fset, files, &Info{Defs: defs, Uses: uses})
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	// check that all packages were imported
+	for _, name := range pkgnames {
+		if !importer.imported[name] {
+			t.Errorf("package %s not imported", name)
+		}
+	}
+
+	// check that qualified identifiers are resolved
+	for _, f := range files {
+		ast.Inspect(f, func(n ast.Node) bool {
+			if s, ok := n.(*ast.SelectorExpr); ok {
+				if x, ok := s.X.(*ast.Ident); ok {
+					obj := uses[x]
+					if obj == nil {
+						t.Errorf("%s: unresolved qualified identifier %s", fset.Position(x.Pos()), x.Name)
+						return false
+					}
+					if _, ok := obj.(*PkgName); ok && uses[s.Sel] == nil {
+						t.Errorf("%s: unresolved selector %s", fset.Position(s.Sel.Pos()), s.Sel.Name)
+						return false
+					}
+					return false
+				}
+				return false
+			}
+			return true
+		})
+	}
+
+	for id, obj := range uses {
+		if obj == nil {
+			t.Errorf("%s: Uses[%s] == nil", fset.Position(id.Pos()), id.Name)
+		}
+	}
+
+	// check that each identifier in the source is found in uses or defs or both
+	var both []string
+	for _, f := range files {
+		ast.Inspect(f, func(n ast.Node) bool {
+			if x, ok := n.(*ast.Ident); ok {
+				var objects int
+				if _, found := uses[x]; found {
+					objects |= 1
+					delete(uses, x)
+				}
+				if _, found := defs[x]; found {
+					objects |= 2
+					delete(defs, x)
+				}
+				if objects == 0 {
+					t.Errorf("%s: unresolved identifier %s", fset.Position(x.Pos()), x.Name)
+				} else if objects == 3 {
+					both = append(both, x.Name)
+				}
+				return false
+			}
+			return true
+		})
+	}
+
+	// check the expected set of idents that are simultaneously uses and defs
+	sort.Strings(both)
+	if got, want := fmt.Sprint(both), "[Mutex Stringer error]"; got != want {
+		t.Errorf("simultaneous uses/defs = %s, want %s", got, want)
+	}
+
+	// any left-over identifiers didn't exist in the source
+	for x := range uses {
+		t.Errorf("%s: identifier %s not present in source", fset.Position(x.Pos()), x.Name)
+	}
+	for x := range defs {
+		t.Errorf("%s: identifier %s not present in source", fset.Position(x.Pos()), x.Name)
+	}
+
+	// TODO(gri) add tests to check ImplicitObj callbacks
+}
diff --git a/third_party/gofrontend/libgo/go/go/types/return.go b/third_party/gofrontend/libgo/go/go/types/return.go
new file mode 100644
index 0000000..6628985
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/go/types/return.go
@@ -0,0 +1,185 @@
+// Copyright 2013 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.
+
+// This file implements isTerminating.
+
+package types
+
+import (
+	"go/ast"
+	"go/token"
+)
+
+// isTerminating reports if s is a terminating statement.
+// If s is labeled, label is the label name; otherwise s
+// is "".
+func (check *Checker) isTerminating(s ast.Stmt, label string) bool {
+	switch s := s.(type) {
+	default:
+		unreachable()
+
+	case *ast.BadStmt, *ast.DeclStmt, *ast.EmptyStmt, *ast.SendStmt,
+		*ast.IncDecStmt, *ast.AssignStmt, *ast.GoStmt, *ast.DeferStmt,
+		*ast.RangeStmt:
+		// no chance
+
+	case *ast.LabeledStmt:
+		return check.isTerminating(s.Stmt, s.Label.Name)
+
+	case *ast.ExprStmt:
+		// the predeclared (possibly parenthesized) panic() function is terminating
+		if call, _ := unparen(s.X).(*ast.CallExpr); call != nil {
+			if id, _ := call.Fun.(*ast.Ident); id != nil {
+				if _, obj := check.scope.LookupParent(id.Name, token.NoPos); obj != nil {
+					if b, _ := obj.(*Builtin); b != nil && b.id == _Panic {
+						return true
+					}
+				}
+			}
+		}
+
+	case *ast.ReturnStmt:
+		return true
+
+	case *ast.BranchStmt:
+		if s.Tok == token.GOTO || s.Tok == token.FALLTHROUGH {
+			return true
+		}
+
+	case *ast.BlockStmt:
+		return check.isTerminatingList(s.List, "")
+
+	case *ast.IfStmt:
+		if s.Else != nil &&
+			check.isTerminating(s.Body, "") &&
+			check.isTerminating(s.Else, "") {
+			return true
+		}
+
+	case *ast.SwitchStmt:
+		return check.isTerminatingSwitch(s.Body, label)
+
+	case *ast.TypeSwitchStmt:
+		return check.isTerminatingSwitch(s.Body, label)
+
+	case *ast.SelectStmt:
+		for _, s := range s.Body.List {
+			cc := s.(*ast.CommClause)
+			if !check.isTerminatingList(cc.Body, "") || hasBreakList(cc.Body, label, true) {
+				return false
+			}
+
+		}
+		return true
+
+	case *ast.ForStmt:
+		if s.Cond == nil && !hasBreak(s.Body, label, true) {
+			return true
+		}
+	}
+
+	return false
+}
+
+func (check *Checker) isTerminatingList(list []ast.Stmt, label string) bool {
+	n := len(list)
+	return n > 0 && check.isTerminating(list[n-1], label)
+}
+
+func (check *Checker) isTerminatingSwitch(body *ast.BlockStmt, label string) bool {
+	hasDefault := false
+	for _, s := range body.List {
+		cc := s.(*ast.CaseClause)
+		if cc.List == nil {
+			hasDefault = true
+		}
+		if !check.isTerminatingList(cc.Body, "") || hasBreakList(cc.Body, label, true) {
+			return false
+		}
+	}
+	return hasDefault
+}
+
+// TODO(gri) For nested breakable statements, the current implementation of hasBreak
+//	     will traverse the same subtree repeatedly, once for each label. Replace
+//           with a single-pass label/break matching phase.
+
+// hasBreak reports if s is or contains a break statement
+// referring to the label-ed statement or implicit-ly the
+// closest outer breakable statement.
+func hasBreak(s ast.Stmt, label string, implicit bool) bool {
+	switch s := s.(type) {
+	default:
+		unreachable()
+
+	case *ast.BadStmt, *ast.DeclStmt, *ast.EmptyStmt, *ast.ExprStmt,
+		*ast.SendStmt, *ast.IncDecStmt, *ast.AssignStmt, *ast.GoStmt,
+		*ast.DeferStmt, *ast.ReturnStmt:
+		// no chance
+
+	case *ast.LabeledStmt:
+		return hasBreak(s.Stmt, label, implicit)
+
+	case *ast.BranchStmt:
+		if s.Tok == token.BREAK {
+			if s.Label == nil {
+				return implicit
+			}
+			if s.Label.Name == label {
+				return true
+			}
+		}
+
+	case *ast.BlockStmt:
+		return hasBreakList(s.List, label, implicit)
+
+	case *ast.IfStmt:
+		if hasBreak(s.Body, label, implicit) ||
+			s.Else != nil && hasBreak(s.Else, label, implicit) {
+			return true
+		}
+
+	case *ast.CaseClause:
+		return hasBreakList(s.Body, label, implicit)
+
+	case *ast.SwitchStmt:
+		if label != "" && hasBreak(s.Body, label, false) {
+			return true
+		}
+
+	case *ast.TypeSwitchStmt:
+		if label != "" && hasBreak(s.Body, label, false) {
+			return true
+		}
+
+	case *ast.CommClause:
+		return hasBreakList(s.Body, label, implicit)
+
+	case *ast.SelectStmt:
+		if label != "" && hasBreak(s.Body, label, false) {
+			return true
+		}
+
+	case *ast.ForStmt:
+		if label != "" && hasBreak(s.Body, label, false) {
+			return true
+		}
+
+	case *ast.RangeStmt:
+		if label != "" && hasBreak(s.Body, label, false) {
+			return true
+		}
+	}
+
+	return false
+}
+
+func hasBreakList(list []ast.Stmt, label string, implicit bool) bool {
+	for _, s := range list {
+		if hasBreak(s, label, implicit) {
+			return true
+		}
+	}
+	return false
+}
diff --git a/third_party/gofrontend/libgo/go/go/types/scope.go b/third_party/gofrontend/libgo/go/go/types/scope.go
new file mode 100644
index 0000000..3502840
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/go/types/scope.go
@@ -0,0 +1,190 @@
+// Copyright 2013 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.
+
+// This file implements Scopes.
+
+package types
+
+import (
+	"bytes"
+	"fmt"
+	"go/token"
+	"io"
+	"sort"
+	"strings"
+)
+
+// TODO(gri) Provide scopes with a name or other mechanism so that
+//           objects can use that information for better printing.
+
+// A Scope maintains a set of objects and links to its containing
+// (parent) and contained (children) scopes. Objects may be inserted
+// and looked up by name. The zero value for Scope is a ready-to-use
+// empty scope.
+type Scope struct {
+	parent   *Scope
+	children []*Scope
+	elems    map[string]Object // lazily allocated
+	pos, end token.Pos         // scope extent; may be invalid
+	comment  string            // for debugging only
+}
+
+// NewScope returns a new, empty scope contained in the given parent
+// scope, if any.  The comment is for debugging only.
+func NewScope(parent *Scope, pos, end token.Pos, comment string) *Scope {
+	s := &Scope{parent, nil, nil, pos, end, comment}
+	// don't add children to Universe scope!
+	if parent != nil && parent != Universe {
+		parent.children = append(parent.children, s)
+	}
+	return s
+}
+
+// Parent returns the scope's containing (parent) scope.
+func (s *Scope) Parent() *Scope { return s.parent }
+
+// Len() returns the number of scope elements.
+func (s *Scope) Len() int { return len(s.elems) }
+
+// Names returns the scope's element names in sorted order.
+func (s *Scope) Names() []string {
+	names := make([]string, len(s.elems))
+	i := 0
+	for name := range s.elems {
+		names[i] = name
+		i++
+	}
+	sort.Strings(names)
+	return names
+}
+
+// NumChildren() returns the number of scopes nested in s.
+func (s *Scope) NumChildren() int { return len(s.children) }
+
+// Child returns the i'th child scope for 0 <= i < NumChildren().
+func (s *Scope) Child(i int) *Scope { return s.children[i] }
+
+// Lookup returns the object in scope s with the given name if such an
+// object exists; otherwise the result is nil.
+func (s *Scope) Lookup(name string) Object {
+	return s.elems[name]
+}
+
+// LookupParent follows the parent chain of scopes starting with s until
+// it finds a scope where Lookup(name) returns a non-nil object, and then
+// returns that scope and object. If a valid position pos is provided,
+// only objects that were declared at or before pos are considered.
+// If no such scope and object exists, the result is (nil, nil).
+//
+// Note that obj.Parent() may be different from the returned scope if the
+// object was inserted into the scope and already had a parent at that
+// time (see Insert, below). This can only happen for dot-imported objects
+// whose scope is the scope of the package that exported them.
+func (s *Scope) LookupParent(name string, pos token.Pos) (*Scope, Object) {
+	for ; s != nil; s = s.parent {
+		if obj := s.elems[name]; obj != nil && (!pos.IsValid() || obj.scopePos() <= pos) {
+			return s, obj
+		}
+	}
+	return nil, nil
+}
+
+// Insert attempts to insert an object obj into scope s.
+// If s already contains an alternative object alt with
+// the same name, Insert leaves s unchanged and returns alt.
+// Otherwise it inserts obj, sets the object's parent scope
+// if not already set, and returns nil.
+func (s *Scope) Insert(obj Object) Object {
+	name := obj.Name()
+	if alt := s.elems[name]; alt != nil {
+		return alt
+	}
+	if s.elems == nil {
+		s.elems = make(map[string]Object)
+	}
+	s.elems[name] = obj
+	if obj.Parent() == nil {
+		obj.setParent(s)
+	}
+	return nil
+}
+
+// Pos and End describe the scope's source code extent [pos, end).
+// The results are guaranteed to be valid only if the type-checked
+// AST has complete position information. The extent is undefined
+// for Universe and package scopes.
+func (s *Scope) Pos() token.Pos { return s.pos }
+func (s *Scope) End() token.Pos { return s.end }
+
+// Contains returns true if pos is within the scope's extent.
+// The result is guaranteed to be valid only if the type-checked
+// AST has complete position information.
+func (s *Scope) Contains(pos token.Pos) bool {
+	return s.pos <= pos && pos < s.end
+}
+
+// Innermost returns the innermost (child) scope containing
+// pos. If pos is not within any scope, the result is nil.
+// The result is also nil for the Universe scope.
+// The result is guaranteed to be valid only if the type-checked
+// AST has complete position information.
+func (s *Scope) Innermost(pos token.Pos) *Scope {
+	// Package scopes do not have extents since they may be
+	// discontiguous, so iterate over the package's files.
+	if s.parent == Universe {
+		for _, s := range s.children {
+			if inner := s.Innermost(pos); inner != nil {
+				return inner
+			}
+		}
+	}
+
+	if s.Contains(pos) {
+		for _, s := range s.children {
+			if s.Contains(pos) {
+				return s.Innermost(pos)
+			}
+		}
+		return s
+	}
+	return nil
+}
+
+// WriteTo writes a string representation of the scope to w,
+// with the scope elements sorted by name.
+// The level of indentation is controlled by n >= 0, with
+// n == 0 for no indentation.
+// If recurse is set, it also writes nested (children) scopes.
+func (s *Scope) WriteTo(w io.Writer, n int, recurse bool) {
+	const ind = ".  "
+	indn := strings.Repeat(ind, n)
+
+	fmt.Fprintf(w, "%s%s scope %p {", indn, s.comment, s)
+	if len(s.elems) == 0 {
+		fmt.Fprintf(w, "}\n")
+		return
+	}
+
+	fmt.Fprintln(w)
+	indn1 := indn + ind
+	for _, name := range s.Names() {
+		fmt.Fprintf(w, "%s%s\n", indn1, s.elems[name])
+	}
+
+	if recurse {
+		for _, s := range s.children {
+			fmt.Fprintln(w)
+			s.WriteTo(w, n+1, recurse)
+		}
+	}
+
+	fmt.Fprintf(w, "%s}", indn)
+}
+
+// String returns a string representation of the scope, for debugging.
+func (s *Scope) String() string {
+	var buf bytes.Buffer
+	s.WriteTo(&buf, 0, false)
+	return buf.String()
+}
diff --git a/third_party/gofrontend/libgo/go/go/types/selection.go b/third_party/gofrontend/libgo/go/go/types/selection.go
new file mode 100644
index 0000000..124e0d3
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/go/types/selection.go
@@ -0,0 +1,143 @@
+// Copyright 2013 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.
+
+// This file implements Selections.
+
+package types
+
+import (
+	"bytes"
+	"fmt"
+)
+
+// SelectionKind describes the kind of a selector expression x.f
+// (excluding qualified identifiers).
+type SelectionKind int
+
+const (
+	FieldVal   SelectionKind = iota // x.f is a struct field selector
+	MethodVal                       // x.f is a method selector
+	MethodExpr                      // x.f is a method expression
+)
+
+// A Selection describes a selector expression x.f.
+// For the declarations:
+//
+//	type T struct{ x int; E }
+//	type E struct{}
+//	func (e E) m() {}
+//	var p *T
+//
+// the following relations exist:
+//
+//	Selector    Kind          Recv    Obj    Type               Index     Indirect
+//
+//	p.x         FieldVal      T       x      int                {0}       true
+//	p.m         MethodVal     *T      m      func (e *T) m()    {1, 0}    true
+//	T.m         MethodExpr    T       m      func m(_ T)        {1, 0}    false
+//
+type Selection struct {
+	kind     SelectionKind
+	recv     Type   // type of x
+	obj      Object // object denoted by x.f
+	index    []int  // path from x to x.f
+	indirect bool   // set if there was any pointer indirection on the path
+}
+
+// Kind returns the selection kind.
+func (s *Selection) Kind() SelectionKind { return s.kind }
+
+// Recv returns the type of x in x.f.
+func (s *Selection) Recv() Type { return s.recv }
+
+// Obj returns the object denoted by x.f; a *Var for
+// a field selection, and a *Func in all other cases.
+func (s *Selection) Obj() Object { return s.obj }
+
+// Type returns the type of x.f, which may be different from the type of f.
+// See Selection for more information.
+func (s *Selection) Type() Type {
+	switch s.kind {
+	case MethodVal:
+		// The type of x.f is a method with its receiver type set
+		// to the type of x.
+		sig := *s.obj.(*Func).typ.(*Signature)
+		recv := *sig.recv
+		recv.typ = s.recv
+		sig.recv = &recv
+		return &sig
+
+	case MethodExpr:
+		// The type of x.f is a function (without receiver)
+		// and an additional first argument with the same type as x.
+		// TODO(gri) Similar code is already in call.go - factor!
+		// TODO(gri) Compute this eagerly to avoid allocations.
+		sig := *s.obj.(*Func).typ.(*Signature)
+		arg0 := *sig.recv
+		sig.recv = nil
+		arg0.typ = s.recv
+		var params []*Var
+		if sig.params != nil {
+			params = sig.params.vars
+		}
+		sig.params = NewTuple(append([]*Var{&arg0}, params...)...)
+		return &sig
+	}
+
+	// In all other cases, the type of x.f is the type of x.
+	return s.obj.Type()
+}
+
+// Index describes the path from x to f in x.f.
+// The last index entry is the field or method index of the type declaring f;
+// either:
+//
+//	1) the list of declared methods of a named type; or
+//	2) the list of methods of an interface type; or
+//	3) the list of fields of a struct type.
+//
+// The earlier index entries are the indices of the embedded fields implicitly
+// traversed to get from (the type of) x to f, starting at embedding depth 0.
+func (s *Selection) Index() []int { return s.index }
+
+// Indirect reports whether any pointer indirection was required to get from
+// x to f in x.f.
+func (s *Selection) Indirect() bool { return s.indirect }
+
+func (s *Selection) String() string { return SelectionString(s, nil) }
+
+// SelectionString returns the string form of s.
+// The Qualifier controls the printing of
+// package-level objects, and may be nil.
+//
+// Examples:
+//	"field (T) f int"
+//	"method (T) f(X) Y"
+//	"method expr (T) f(X) Y"
+//
+func SelectionString(s *Selection, qf Qualifier) string {
+	var k string
+	switch s.kind {
+	case FieldVal:
+		k = "field "
+	case MethodVal:
+		k = "method "
+	case MethodExpr:
+		k = "method expr "
+	default:
+		unreachable()
+	}
+	var buf bytes.Buffer
+	buf.WriteString(k)
+	buf.WriteByte('(')
+	WriteType(&buf, s.Recv(), qf)
+	fmt.Fprintf(&buf, ") %s", s.obj.Name())
+	if T := s.Type(); s.kind == FieldVal {
+		buf.WriteByte(' ')
+		WriteType(&buf, T, qf)
+	} else {
+		WriteSignature(&buf, T.(*Signature), qf)
+	}
+	return buf.String()
+}
diff --git a/third_party/gofrontend/libgo/go/go/types/self_test.go b/third_party/gofrontend/libgo/go/go/types/self_test.go
new file mode 100644
index 0000000..10ad06f
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/go/types/self_test.go
@@ -0,0 +1,102 @@
+// Copyright 2013 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 types_test
+
+import (
+	"flag"
+	"fmt"
+	"go/ast"
+	"go/importer"
+	"go/parser"
+	"go/token"
+	"path/filepath"
+	"testing"
+	"time"
+
+	. "go/types"
+)
+
+var benchmark = flag.Bool("b", false, "run benchmarks")
+
+func TestSelf(t *testing.T) {
+	fset := token.NewFileSet()
+	files, err := pkgFiles(fset, ".")
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	conf := Config{Importer: importer.Default()}
+	_, err = conf.Check("go/types", fset, files, nil)
+	if err != nil {
+		// Importing go/constant doesn't work in the
+		// build dashboard environment. Don't report an error
+		// for now so that the build remains green.
+		// TODO(gri) fix this
+		t.Log(err) // replace w/ t.Fatal eventually
+		return
+	}
+}
+
+func TestBenchmark(t *testing.T) {
+	if !*benchmark {
+		return
+	}
+
+	// We're not using testing's benchmarking mechanism directly
+	// because we want custom output.
+
+	for _, p := range []string{"types", "constant", filepath.Join("internal", "gcimporter")} {
+		path := filepath.Join("..", p)
+		runbench(t, path, false)
+		runbench(t, path, true)
+		fmt.Println()
+	}
+}
+
+func runbench(t *testing.T, path string, ignoreFuncBodies bool) {
+	fset := token.NewFileSet()
+	files, err := pkgFiles(fset, path)
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	b := testing.Benchmark(func(b *testing.B) {
+		for i := 0; i < b.N; i++ {
+			conf := Config{IgnoreFuncBodies: ignoreFuncBodies}
+			conf.Check(path, fset, files, nil)
+		}
+	})
+
+	// determine line count
+	lines := 0
+	fset.Iterate(func(f *token.File) bool {
+		lines += f.LineCount()
+		return true
+	})
+
+	d := time.Duration(b.NsPerOp())
+	fmt.Printf(
+		"%s: %s for %d lines (%d lines/s), ignoreFuncBodies = %v\n",
+		filepath.Base(path), d, lines, int64(float64(lines)/d.Seconds()), ignoreFuncBodies,
+	)
+}
+
+func pkgFiles(fset *token.FileSet, path string) ([]*ast.File, error) {
+	filenames, err := pkgFilenames(path) // from stdlib_test.go
+	if err != nil {
+		return nil, err
+	}
+
+	var files []*ast.File
+	for _, filename := range filenames {
+		file, err := parser.ParseFile(fset, filename, nil, 0)
+		if err != nil {
+			return nil, err
+		}
+		files = append(files, file)
+	}
+
+	return files, nil
+}
diff --git a/third_party/gofrontend/libgo/go/go/types/sizes.go b/third_party/gofrontend/libgo/go/go/types/sizes.go
new file mode 100644
index 0000000..56fb310
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/go/types/sizes.go
@@ -0,0 +1,211 @@
+// Copyright 2013 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.
+
+// This file implements Sizes.
+
+package types
+
+// Sizes defines the sizing functions for package unsafe.
+type Sizes interface {
+	// Alignof returns the alignment of a variable of type T.
+	// Alignof must implement the alignment guarantees required by the spec.
+	Alignof(T Type) int64
+
+	// Offsetsof returns the offsets of the given struct fields, in bytes.
+	// Offsetsof must implement the offset guarantees required by the spec.
+	Offsetsof(fields []*Var) []int64
+
+	// Sizeof returns the size of a variable of type T.
+	// Sizeof must implement the size guarantees required by the spec.
+	Sizeof(T Type) int64
+}
+
+// StdSizes is a convenience type for creating commonly used Sizes.
+// It makes the following simplifying assumptions:
+//
+//	- The size of explicitly sized basic types (int16, etc.) is the
+//	  specified size.
+//	- The size of strings and interfaces is 2*WordSize.
+//	- The size of slices is 3*WordSize.
+//	- The size of an array of n elements corresponds to the size of
+//	  a struct of n consecutive fields of the array's element type.
+//      - The size of a struct is the offset of the last field plus that
+//	  field's size. As with all element types, if the struct is used
+//	  in an array its size must first be aligned to a multiple of the
+//	  struct's alignment.
+//	- All other types have size WordSize.
+//	- Arrays and structs are aligned per spec definition; all other
+//	  types are naturally aligned with a maximum alignment MaxAlign.
+//
+// *StdSizes implements Sizes.
+//
+type StdSizes struct {
+	WordSize int64 // word size in bytes - must be >= 4 (32bits)
+	MaxAlign int64 // maximum alignment in bytes - must be >= 1
+}
+
+func (s *StdSizes) Alignof(T Type) int64 {
+	// For arrays and structs, alignment is defined in terms
+	// of alignment of the elements and fields, respectively.
+	switch t := T.Underlying().(type) {
+	case *Array:
+		// spec: "For a variable x of array type: unsafe.Alignof(x)
+		// is the same as unsafe.Alignof(x[0]), but at least 1."
+		return s.Alignof(t.elem)
+	case *Struct:
+		// spec: "For a variable x of struct type: unsafe.Alignof(x)
+		// is the largest of the values unsafe.Alignof(x.f) for each
+		// field f of x, but at least 1."
+		max := int64(1)
+		for _, f := range t.fields {
+			if a := s.Alignof(f.typ); a > max {
+				max = a
+			}
+		}
+		return max
+	}
+	a := s.Sizeof(T) // may be 0
+	// spec: "For a variable x of any type: unsafe.Alignof(x) is at least 1."
+	if a < 1 {
+		return 1
+	}
+	if a > s.MaxAlign {
+		return s.MaxAlign
+	}
+	return a
+}
+
+func (s *StdSizes) Offsetsof(fields []*Var) []int64 {
+	offsets := make([]int64, len(fields))
+	var o int64
+	for i, f := range fields {
+		a := s.Alignof(f.typ)
+		o = align(o, a)
+		offsets[i] = o
+		o += s.Sizeof(f.typ)
+	}
+	return offsets
+}
+
+var basicSizes = [...]byte{
+	Bool:       1,
+	Int8:       1,
+	Int16:      2,
+	Int32:      4,
+	Int64:      8,
+	Uint8:      1,
+	Uint16:     2,
+	Uint32:     4,
+	Uint64:     8,
+	Float32:    4,
+	Float64:    8,
+	Complex64:  8,
+	Complex128: 16,
+}
+
+func (s *StdSizes) Sizeof(T Type) int64 {
+	switch t := T.Underlying().(type) {
+	case *Basic:
+		assert(isTyped(T))
+		k := t.kind
+		if int(k) < len(basicSizes) {
+			if s := basicSizes[k]; s > 0 {
+				return int64(s)
+			}
+		}
+		if k == String {
+			return s.WordSize * 2
+		}
+	case *Array:
+		n := t.len
+		if n == 0 {
+			return 0
+		}
+		a := s.Alignof(t.elem)
+		z := s.Sizeof(t.elem)
+		return align(z, a)*(n-1) + z
+	case *Slice:
+		return s.WordSize * 3
+	case *Struct:
+		n := t.NumFields()
+		if n == 0 {
+			return 0
+		}
+		offsets := t.offsets
+		if t.offsets == nil {
+			// compute offsets on demand
+			offsets = s.Offsetsof(t.fields)
+			t.offsets = offsets
+		}
+		return offsets[n-1] + s.Sizeof(t.fields[n-1].typ)
+	case *Interface:
+		return s.WordSize * 2
+	}
+	return s.WordSize // catch-all
+}
+
+// stdSizes is used if Config.Sizes == nil.
+var stdSizes = StdSizes{8, 8}
+
+func (conf *Config) alignof(T Type) int64 {
+	if s := conf.Sizes; s != nil {
+		if a := s.Alignof(T); a >= 1 {
+			return a
+		}
+		panic("Config.Sizes.Alignof returned an alignment < 1")
+	}
+	return stdSizes.Alignof(T)
+}
+
+func (conf *Config) offsetsof(T *Struct) []int64 {
+	offsets := T.offsets
+	if offsets == nil && T.NumFields() > 0 {
+		// compute offsets on demand
+		if s := conf.Sizes; s != nil {
+			offsets = s.Offsetsof(T.fields)
+			// sanity checks
+			if len(offsets) != T.NumFields() {
+				panic("Config.Sizes.Offsetsof returned the wrong number of offsets")
+			}
+			for _, o := range offsets {
+				if o < 0 {
+					panic("Config.Sizes.Offsetsof returned an offset < 0")
+				}
+			}
+		} else {
+			offsets = stdSizes.Offsetsof(T.fields)
+		}
+		T.offsets = offsets
+	}
+	return offsets
+}
+
+// offsetof returns the offset of the field specified via
+// the index sequence relative to typ. All embedded fields
+// must be structs (rather than pointer to structs).
+func (conf *Config) offsetof(typ Type, index []int) int64 {
+	var o int64
+	for _, i := range index {
+		s := typ.Underlying().(*Struct)
+		o += conf.offsetsof(s)[i]
+		typ = s.fields[i].typ
+	}
+	return o
+}
+
+func (conf *Config) sizeof(T Type) int64 {
+	if s := conf.Sizes; s != nil {
+		if z := s.Sizeof(T); z >= 0 {
+			return z
+		}
+		panic("Config.Sizes.Sizeof returned a size < 0")
+	}
+	return stdSizes.Sizeof(T)
+}
+
+// align returns the smallest y >= x such that y % a == 0.
+func align(x, a int64) int64 {
+	y := x + a - 1
+	return y - y%a
+}
diff --git a/third_party/gofrontend/libgo/go/go/types/stdlib_test.go b/third_party/gofrontend/libgo/go/go/types/stdlib_test.go
new file mode 100644
index 0000000..c6c946e
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/go/types/stdlib_test.go
@@ -0,0 +1,279 @@
+// Copyright 2013 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.
+
+// This file tests types.Check by using it to
+// typecheck the standard library and tests.
+
+package types_test
+
+import (
+	"fmt"
+	"go/ast"
+	"go/build"
+	"go/importer"
+	"go/parser"
+	"go/scanner"
+	"go/token"
+	"internal/testenv"
+	"io/ioutil"
+	"os"
+	"path/filepath"
+	"runtime"
+	"strings"
+	"testing"
+	"time"
+
+	. "go/types"
+)
+
+var (
+	pkgCount int // number of packages processed
+	start    time.Time
+
+	// Use the same importer for all std lib tests to
+	// avoid repeated importing of the same packages.
+	stdLibImporter = importer.Default()
+)
+
+func TestStdlib(t *testing.T) {
+	testenv.MustHaveGoBuild(t)
+
+	start = time.Now()
+	walkDirs(t, filepath.Join(runtime.GOROOT(), "src"))
+	if testing.Verbose() {
+		fmt.Println(pkgCount, "packages typechecked in", time.Since(start))
+	}
+}
+
+// firstComment returns the contents of the first comment in
+// the given file, assuming there's one within the first KB.
+func firstComment(filename string) string {
+	f, err := os.Open(filename)
+	if err != nil {
+		return ""
+	}
+	defer f.Close()
+
+	var src [1 << 10]byte // read at most 1KB
+	n, _ := f.Read(src[:])
+
+	var s scanner.Scanner
+	s.Init(fset.AddFile("", fset.Base(), n), src[:n], nil, scanner.ScanComments)
+	for {
+		_, tok, lit := s.Scan()
+		switch tok {
+		case token.COMMENT:
+			// remove trailing */ of multi-line comment
+			if lit[1] == '*' {
+				lit = lit[:len(lit)-2]
+			}
+			return strings.TrimSpace(lit[2:])
+		case token.EOF:
+			return ""
+		}
+	}
+}
+
+func testTestDir(t *testing.T, path string, ignore ...string) {
+	files, err := ioutil.ReadDir(path)
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	excluded := make(map[string]bool)
+	for _, filename := range ignore {
+		excluded[filename] = true
+	}
+
+	fset := token.NewFileSet()
+	for _, f := range files {
+		// filter directory contents
+		if f.IsDir() || !strings.HasSuffix(f.Name(), ".go") || excluded[f.Name()] {
+			continue
+		}
+
+		// get per-file instructions
+		expectErrors := false
+		filename := filepath.Join(path, f.Name())
+		if cmd := firstComment(filename); cmd != "" {
+			switch cmd {
+			case "skip", "compiledir":
+				continue // ignore this file
+			case "errorcheck":
+				expectErrors = true
+			}
+		}
+
+		// parse and type-check file
+		file, err := parser.ParseFile(fset, filename, nil, 0)
+		if err == nil {
+			conf := Config{Importer: stdLibImporter}
+			_, err = conf.Check(filename, fset, []*ast.File{file}, nil)
+		}
+
+		if expectErrors {
+			if err == nil {
+				t.Errorf("expected errors but found none in %s", filename)
+			}
+		} else {
+			if err != nil {
+				t.Error(err)
+			}
+		}
+	}
+}
+
+func TestStdTest(t *testing.T) {
+	testenv.MustHaveGoBuild(t)
+
+	// test/recover4.go is only built for Linux and Darwin.
+	// TODO(gri) Remove once tests consider +build tags (issue 10370).
+	if runtime.GOOS != "linux" && runtime.GOOS != "darwin" {
+		return
+	}
+
+	testTestDir(t, filepath.Join(runtime.GOROOT(), "test"),
+		"cmplxdivide.go", // also needs file cmplxdivide1.go - ignore
+		"sigchld.go",     // don't work on Windows; testTestDir should consult build tags
+	)
+}
+
+func TestStdFixed(t *testing.T) {
+	testenv.MustHaveGoBuild(t)
+
+	testTestDir(t, filepath.Join(runtime.GOROOT(), "test", "fixedbugs"),
+		"bug248.go", "bug302.go", "bug369.go", // complex test instructions - ignore
+		"bug459.go",      // possibly incorrect test - see issue 6703 (pending spec clarification)
+		"issue3924.go",   // possibly incorrect test - see issue 6671 (pending spec clarification)
+		"issue6889.go",   // gc-specific test
+		"issue7746.go",   // large constants - consumes too much memory
+		"issue11326.go",  // large constants
+		"issue11326b.go", // large constants
+	)
+}
+
+func TestStdKen(t *testing.T) {
+	testenv.MustHaveGoBuild(t)
+
+	testTestDir(t, filepath.Join(runtime.GOROOT(), "test", "ken"))
+}
+
+// Package paths of excluded packages.
+var excluded = map[string]bool{
+	"builtin": true,
+}
+
+// typecheck typechecks the given package files.
+func typecheck(t *testing.T, path string, filenames []string) {
+	fset := token.NewFileSet()
+
+	// parse package files
+	var files []*ast.File
+	for _, filename := range filenames {
+		file, err := parser.ParseFile(fset, filename, nil, parser.AllErrors)
+		if err != nil {
+			// the parser error may be a list of individual errors; report them all
+			if list, ok := err.(scanner.ErrorList); ok {
+				for _, err := range list {
+					t.Error(err)
+				}
+				return
+			}
+			t.Error(err)
+			return
+		}
+
+		if testing.Verbose() {
+			if len(files) == 0 {
+				fmt.Println("package", file.Name.Name)
+			}
+			fmt.Println("\t", filename)
+		}
+
+		files = append(files, file)
+	}
+
+	// typecheck package files
+	conf := Config{
+		Error:    func(err error) { t.Error(err) },
+		Importer: stdLibImporter,
+	}
+	info := Info{Uses: make(map[*ast.Ident]Object)}
+	conf.Check(path, fset, files, &info)
+	pkgCount++
+
+	// Perform checks of API invariants.
+
+	// All Objects have a package, except predeclared ones.
+	errorError := Universe.Lookup("error").Type().Underlying().(*Interface).ExplicitMethod(0) // (error).Error
+	for id, obj := range info.Uses {
+		predeclared := obj == Universe.Lookup(obj.Name()) || obj == errorError
+		if predeclared == (obj.Pkg() != nil) {
+			posn := fset.Position(id.Pos())
+			if predeclared {
+				t.Errorf("%s: predeclared object with package: %s", posn, obj)
+			} else {
+				t.Errorf("%s: user-defined object without package: %s", posn, obj)
+			}
+		}
+	}
+}
+
+// pkgFilenames returns the list of package filenames for the given directory.
+func pkgFilenames(dir string) ([]string, error) {
+	ctxt := build.Default
+	ctxt.CgoEnabled = false
+	pkg, err := ctxt.ImportDir(dir, 0)
+	if err != nil {
+		if _, nogo := err.(*build.NoGoError); nogo {
+			return nil, nil // no *.go files, not an error
+		}
+		return nil, err
+	}
+	if excluded[pkg.ImportPath] {
+		return nil, nil
+	}
+	var filenames []string
+	for _, name := range pkg.GoFiles {
+		filenames = append(filenames, filepath.Join(pkg.Dir, name))
+	}
+	for _, name := range pkg.TestGoFiles {
+		filenames = append(filenames, filepath.Join(pkg.Dir, name))
+	}
+	return filenames, nil
+}
+
+// Note: Could use filepath.Walk instead of walkDirs but that wouldn't
+//       necessarily be shorter or clearer after adding the code to
+//       terminate early for -short tests.
+
+func walkDirs(t *testing.T, dir string) {
+	// limit run time for short tests
+	if testing.Short() && time.Since(start) >= 750*time.Millisecond {
+		return
+	}
+
+	fis, err := ioutil.ReadDir(dir)
+	if err != nil {
+		t.Error(err)
+		return
+	}
+
+	// typecheck package in directory
+	files, err := pkgFilenames(dir)
+	if err != nil {
+		t.Error(err)
+		return
+	}
+	if files != nil {
+		typecheck(t, dir, files)
+	}
+
+	// traverse subdirectories, but don't walk into testdata
+	for _, fi := range fis {
+		if fi.IsDir() && fi.Name() != "testdata" {
+			walkDirs(t, filepath.Join(dir, fi.Name()))
+		}
+	}
+}
diff --git a/third_party/gofrontend/libgo/go/go/types/stmt.go b/third_party/gofrontend/libgo/go/go/types/stmt.go
new file mode 100644
index 0000000..88a1d9b
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/go/types/stmt.go
@@ -0,0 +1,744 @@
+// Copyright 2012 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.
+
+// This file implements typechecking of statements.
+
+package types
+
+import (
+	"fmt"
+	"go/ast"
+	"go/constant"
+	"go/token"
+)
+
+func (check *Checker) funcBody(decl *declInfo, name string, sig *Signature, body *ast.BlockStmt) {
+	if trace {
+		if name == "" {
+			name = "<function literal>"
+		}
+		fmt.Printf("--- %s: %s {\n", name, sig)
+		defer fmt.Println("--- <end>")
+	}
+
+	// set function scope extent
+	sig.scope.pos = body.Pos()
+	sig.scope.end = body.End()
+
+	// save/restore current context and setup function context
+	// (and use 0 indentation at function start)
+	defer func(ctxt context, indent int) {
+		check.context = ctxt
+		check.indent = indent
+	}(check.context, check.indent)
+	check.context = context{
+		decl:  decl,
+		scope: sig.scope,
+		sig:   sig,
+	}
+	check.indent = 0
+
+	check.stmtList(0, body.List)
+
+	if check.hasLabel {
+		check.labels(body)
+	}
+
+	if sig.results.Len() > 0 && !check.isTerminating(body, "") {
+		check.error(body.Rbrace, "missing return")
+	}
+
+	// spec: "Implementation restriction: A compiler may make it illegal to
+	// declare a variable inside a function body if the variable is never used."
+	// (One could check each scope after use, but that distributes this check
+	// over several places because CloseScope is not always called explicitly.)
+	check.usage(sig.scope)
+}
+
+func (check *Checker) usage(scope *Scope) {
+	for _, obj := range scope.elems {
+		if v, _ := obj.(*Var); v != nil && !v.used {
+			check.softErrorf(v.pos, "%s declared but not used", v.name)
+		}
+	}
+	for _, scope := range scope.children {
+		check.usage(scope)
+	}
+}
+
+// stmtContext is a bitset describing which
+// control-flow statements are permissible.
+type stmtContext uint
+
+const (
+	breakOk stmtContext = 1 << iota
+	continueOk
+	fallthroughOk
+)
+
+func (check *Checker) simpleStmt(s ast.Stmt) {
+	if s != nil {
+		check.stmt(0, s)
+	}
+}
+
+func (check *Checker) stmtList(ctxt stmtContext, list []ast.Stmt) {
+	ok := ctxt&fallthroughOk != 0
+	inner := ctxt &^ fallthroughOk
+	for i, s := range list {
+		inner := inner
+		if ok && i+1 == len(list) {
+			inner |= fallthroughOk
+		}
+		check.stmt(inner, s)
+	}
+}
+
+func (check *Checker) multipleDefaults(list []ast.Stmt) {
+	var first ast.Stmt
+	for _, s := range list {
+		var d ast.Stmt
+		switch c := s.(type) {
+		case *ast.CaseClause:
+			if len(c.List) == 0 {
+				d = s
+			}
+		case *ast.CommClause:
+			if c.Comm == nil {
+				d = s
+			}
+		default:
+			check.invalidAST(s.Pos(), "case/communication clause expected")
+		}
+		if d != nil {
+			if first != nil {
+				check.errorf(d.Pos(), "multiple defaults (first at %s)", first.Pos())
+			} else {
+				first = d
+			}
+		}
+	}
+}
+
+func (check *Checker) openScope(s ast.Stmt, comment string) {
+	scope := NewScope(check.scope, s.Pos(), s.End(), comment)
+	check.recordScope(s, scope)
+	check.scope = scope
+}
+
+func (check *Checker) closeScope() {
+	check.scope = check.scope.Parent()
+}
+
+func assignOp(op token.Token) token.Token {
+	// token_test.go verifies the token ordering this function relies on
+	if token.ADD_ASSIGN <= op && op <= token.AND_NOT_ASSIGN {
+		return op + (token.ADD - token.ADD_ASSIGN)
+	}
+	return token.ILLEGAL
+}
+
+func (check *Checker) suspendedCall(keyword string, call *ast.CallExpr) {
+	var x operand
+	var msg string
+	switch check.rawExpr(&x, call, nil) {
+	case conversion:
+		msg = "requires function call, not conversion"
+	case expression:
+		msg = "discards result of"
+	case statement:
+		return
+	default:
+		unreachable()
+	}
+	check.errorf(x.pos(), "%s %s %s", keyword, msg, &x)
+}
+
+func (check *Checker) caseValues(x operand /* copy argument (not *operand!) */, values []ast.Expr) {
+	// No duplicate checking for now. See issue 4524.
+	for _, e := range values {
+		var y operand
+		check.expr(&y, e)
+		if y.mode == invalid {
+			return
+		}
+		// TODO(gri) The convertUntyped call pair below appears in other places. Factor!
+		// Order matters: By comparing y against x, error positions are at the case values.
+		check.convertUntyped(&y, x.typ)
+		if y.mode == invalid {
+			return
+		}
+		check.convertUntyped(&x, y.typ)
+		if x.mode == invalid {
+			return
+		}
+		check.comparison(&y, &x, token.EQL)
+	}
+}
+
+func (check *Checker) caseTypes(x *operand, xtyp *Interface, types []ast.Expr, seen map[Type]token.Pos) (T Type) {
+L:
+	for _, e := range types {
+		T = check.typOrNil(e)
+		if T == Typ[Invalid] {
+			continue
+		}
+		// complain about duplicate types
+		// TODO(gri) use a type hash to avoid quadratic algorithm
+		for t, pos := range seen {
+			if T == nil && t == nil || T != nil && t != nil && Identical(T, t) {
+				// talk about "case" rather than "type" because of nil case
+				check.error(e.Pos(), "duplicate case in type switch")
+				check.errorf(pos, "\tprevious case %s", T) // secondary error, \t indented
+				continue L
+			}
+		}
+		seen[T] = e.Pos()
+		if T != nil {
+			check.typeAssertion(e.Pos(), x, xtyp, T)
+		}
+	}
+	return
+}
+
+// stmt typechecks statement s.
+func (check *Checker) stmt(ctxt stmtContext, s ast.Stmt) {
+	// statements cannot use iota in general
+	// (constant declarations set it explicitly)
+	assert(check.iota == nil)
+
+	// statements must end with the same top scope as they started with
+	if debug {
+		defer func(scope *Scope) {
+			// don't check if code is panicking
+			if p := recover(); p != nil {
+				panic(p)
+			}
+			assert(scope == check.scope)
+		}(check.scope)
+	}
+
+	inner := ctxt &^ fallthroughOk
+	switch s := s.(type) {
+	case *ast.BadStmt, *ast.EmptyStmt:
+		// ignore
+
+	case *ast.DeclStmt:
+		check.declStmt(s.Decl)
+
+	case *ast.LabeledStmt:
+		check.hasLabel = true
+		check.stmt(ctxt, s.Stmt)
+
+	case *ast.ExprStmt:
+		// spec: "With the exception of specific built-in functions,
+		// function and method calls and receive operations can appear
+		// in statement context. Such statements may be parenthesized."
+		var x operand
+		kind := check.rawExpr(&x, s.X, nil)
+		var msg string
+		switch x.mode {
+		default:
+			if kind == statement {
+				return
+			}
+			msg = "is not used"
+		case builtin:
+			msg = "must be called"
+		case typexpr:
+			msg = "is not an expression"
+		}
+		check.errorf(x.pos(), "%s %s", &x, msg)
+
+	case *ast.SendStmt:
+		var ch, x operand
+		check.expr(&ch, s.Chan)
+		check.expr(&x, s.Value)
+		if ch.mode == invalid || x.mode == invalid {
+			return
+		}
+		if tch, ok := ch.typ.Underlying().(*Chan); !ok || tch.dir == RecvOnly || !check.assignment(&x, tch.elem) {
+			if x.mode != invalid {
+				check.invalidOp(ch.pos(), "cannot send %s to channel %s", &x, &ch)
+			}
+		}
+
+	case *ast.IncDecStmt:
+		var op token.Token
+		switch s.Tok {
+		case token.INC:
+			op = token.ADD
+		case token.DEC:
+			op = token.SUB
+		default:
+			check.invalidAST(s.TokPos, "unknown inc/dec operation %s", s.Tok)
+			return
+		}
+		var x operand
+		Y := &ast.BasicLit{ValuePos: s.X.Pos(), Kind: token.INT, Value: "1"} // use x's position
+		check.binary(&x, nil, s.X, Y, op)
+		if x.mode == invalid {
+			return
+		}
+		check.assignVar(s.X, &x)
+
+	case *ast.AssignStmt:
+		switch s.Tok {
+		case token.ASSIGN, token.DEFINE:
+			if len(s.Lhs) == 0 {
+				check.invalidAST(s.Pos(), "missing lhs in assignment")
+				return
+			}
+			if s.Tok == token.DEFINE {
+				check.shortVarDecl(s.TokPos, s.Lhs, s.Rhs)
+			} else {
+				// regular assignment
+				check.assignVars(s.Lhs, s.Rhs)
+			}
+
+		default:
+			// assignment operations
+			if len(s.Lhs) != 1 || len(s.Rhs) != 1 {
+				check.errorf(s.TokPos, "assignment operation %s requires single-valued expressions", s.Tok)
+				return
+			}
+			op := assignOp(s.Tok)
+			if op == token.ILLEGAL {
+				check.invalidAST(s.TokPos, "unknown assignment operation %s", s.Tok)
+				return
+			}
+			var x operand
+			check.binary(&x, nil, s.Lhs[0], s.Rhs[0], op)
+			if x.mode == invalid {
+				return
+			}
+			check.assignVar(s.Lhs[0], &x)
+		}
+
+	case *ast.GoStmt:
+		check.suspendedCall("go", s.Call)
+
+	case *ast.DeferStmt:
+		check.suspendedCall("defer", s.Call)
+
+	case *ast.ReturnStmt:
+		res := check.sig.results
+		if res.Len() > 0 {
+			// function returns results
+			// (if one, say the first, result parameter is named, all of them are named)
+			if len(s.Results) == 0 && res.vars[0].name != "" {
+				// spec: "Implementation restriction: A compiler may disallow an empty expression
+				// list in a "return" statement if a different entity (constant, type, or variable)
+				// with the same name as a result parameter is in scope at the place of the return."
+				for _, obj := range res.vars {
+					if _, alt := check.scope.LookupParent(obj.name, check.pos); alt != nil && alt != obj {
+						check.errorf(s.Pos(), "result parameter %s not in scope at return", obj.name)
+						check.errorf(alt.Pos(), "\tinner declaration of %s", obj)
+						// ok to continue
+					}
+				}
+			} else {
+				// return has results or result parameters are unnamed
+				check.initVars(res.vars, s.Results, s.Return)
+			}
+		} else if len(s.Results) > 0 {
+			check.error(s.Results[0].Pos(), "no result values expected")
+			check.use(s.Results...)
+		}
+
+	case *ast.BranchStmt:
+		if s.Label != nil {
+			check.hasLabel = true
+			return // checked in 2nd pass (check.labels)
+		}
+		switch s.Tok {
+		case token.BREAK:
+			if ctxt&breakOk == 0 {
+				check.error(s.Pos(), "break not in for, switch, or select statement")
+			}
+		case token.CONTINUE:
+			if ctxt&continueOk == 0 {
+				check.error(s.Pos(), "continue not in for statement")
+			}
+		case token.FALLTHROUGH:
+			if ctxt&fallthroughOk == 0 {
+				check.error(s.Pos(), "fallthrough statement out of place")
+			}
+		default:
+			check.invalidAST(s.Pos(), "branch statement: %s", s.Tok)
+		}
+
+	case *ast.BlockStmt:
+		check.openScope(s, "block")
+		defer check.closeScope()
+
+		check.stmtList(inner, s.List)
+
+	case *ast.IfStmt:
+		check.openScope(s, "if")
+		defer check.closeScope()
+
+		check.simpleStmt(s.Init)
+		var x operand
+		check.expr(&x, s.Cond)
+		if x.mode != invalid && !isBoolean(x.typ) {
+			check.error(s.Cond.Pos(), "non-boolean condition in if statement")
+		}
+		check.stmt(inner, s.Body)
+		if s.Else != nil {
+			check.stmt(inner, s.Else)
+		}
+
+	case *ast.SwitchStmt:
+		inner |= breakOk
+		check.openScope(s, "switch")
+		defer check.closeScope()
+
+		check.simpleStmt(s.Init)
+		var x operand
+		if s.Tag != nil {
+			check.expr(&x, s.Tag)
+		} else {
+			// spec: "A missing switch expression is
+			// equivalent to the boolean value true."
+			x.mode = constant_
+			x.typ = Typ[Bool]
+			x.val = constant.MakeBool(true)
+			x.expr = &ast.Ident{NamePos: s.Body.Lbrace, Name: "true"}
+		}
+
+		check.multipleDefaults(s.Body.List)
+
+		for i, c := range s.Body.List {
+			clause, _ := c.(*ast.CaseClause)
+			if clause == nil {
+				check.invalidAST(c.Pos(), "incorrect expression switch case")
+				continue
+			}
+			if x.mode != invalid {
+				check.caseValues(x, clause.List)
+			}
+			check.openScope(clause, "case")
+			inner := inner
+			if i+1 < len(s.Body.List) {
+				inner |= fallthroughOk
+			}
+			check.stmtList(inner, clause.Body)
+			check.closeScope()
+		}
+
+	case *ast.TypeSwitchStmt:
+		inner |= breakOk
+		check.openScope(s, "type switch")
+		defer check.closeScope()
+
+		check.simpleStmt(s.Init)
+
+		// A type switch guard must be of the form:
+		//
+		//     TypeSwitchGuard = [ identifier ":=" ] PrimaryExpr "." "(" "type" ")" .
+		//
+		// The parser is checking syntactic correctness;
+		// remaining syntactic errors are considered AST errors here.
+		// TODO(gri) better factoring of error handling (invalid ASTs)
+		//
+		var lhs *ast.Ident // lhs identifier or nil
+		var rhs ast.Expr
+		switch guard := s.Assign.(type) {
+		case *ast.ExprStmt:
+			rhs = guard.X
+		case *ast.AssignStmt:
+			if len(guard.Lhs) != 1 || guard.Tok != token.DEFINE || len(guard.Rhs) != 1 {
+				check.invalidAST(s.Pos(), "incorrect form of type switch guard")
+				return
+			}
+
+			lhs, _ = guard.Lhs[0].(*ast.Ident)
+			if lhs == nil {
+				check.invalidAST(s.Pos(), "incorrect form of type switch guard")
+				return
+			}
+
+			if lhs.Name == "_" {
+				// _ := x.(type) is an invalid short variable declaration
+				check.softErrorf(lhs.Pos(), "no new variable on left side of :=")
+				lhs = nil // avoid declared but not used error below
+			} else {
+				check.recordDef(lhs, nil) // lhs variable is implicitly declared in each cause clause
+			}
+
+			rhs = guard.Rhs[0]
+
+		default:
+			check.invalidAST(s.Pos(), "incorrect form of type switch guard")
+			return
+		}
+
+		// rhs must be of the form: expr.(type) and expr must be an interface
+		expr, _ := rhs.(*ast.TypeAssertExpr)
+		if expr == nil || expr.Type != nil {
+			check.invalidAST(s.Pos(), "incorrect form of type switch guard")
+			return
+		}
+		var x operand
+		check.expr(&x, expr.X)
+		if x.mode == invalid {
+			return
+		}
+		xtyp, _ := x.typ.Underlying().(*Interface)
+		if xtyp == nil {
+			check.errorf(x.pos(), "%s is not an interface", &x)
+			return
+		}
+
+		check.multipleDefaults(s.Body.List)
+
+		var lhsVars []*Var               // list of implicitly declared lhs variables
+		seen := make(map[Type]token.Pos) // map of seen types to positions
+		for _, s := range s.Body.List {
+			clause, _ := s.(*ast.CaseClause)
+			if clause == nil {
+				check.invalidAST(s.Pos(), "incorrect type switch case")
+				continue
+			}
+			// Check each type in this type switch case.
+			T := check.caseTypes(&x, xtyp, clause.List, seen)
+			check.openScope(clause, "case")
+			// If lhs exists, declare a corresponding variable in the case-local scope.
+			if lhs != nil {
+				// spec: "The TypeSwitchGuard may include a short variable declaration.
+				// When that form is used, the variable is declared at the beginning of
+				// the implicit block in each clause. In clauses with a case listing
+				// exactly one type, the variable has that type; otherwise, the variable
+				// has the type of the expression in the TypeSwitchGuard."
+				if len(clause.List) != 1 || T == nil {
+					T = x.typ
+				}
+				obj := NewVar(lhs.Pos(), check.pkg, lhs.Name, T)
+				scopePos := clause.End()
+				if len(clause.Body) > 0 {
+					scopePos = clause.Body[0].Pos()
+				}
+				check.declare(check.scope, nil, obj, scopePos)
+				check.recordImplicit(clause, obj)
+				// For the "declared but not used" error, all lhs variables act as
+				// one; i.e., if any one of them is 'used', all of them are 'used'.
+				// Collect them for later analysis.
+				lhsVars = append(lhsVars, obj)
+			}
+			check.stmtList(inner, clause.Body)
+			check.closeScope()
+		}
+
+		// If lhs exists, we must have at least one lhs variable that was used.
+		if lhs != nil {
+			var used bool
+			for _, v := range lhsVars {
+				if v.used {
+					used = true
+				}
+				v.used = true // avoid usage error when checking entire function
+			}
+			if !used {
+				check.softErrorf(lhs.Pos(), "%s declared but not used", lhs.Name)
+			}
+		}
+
+	case *ast.SelectStmt:
+		inner |= breakOk
+
+		check.multipleDefaults(s.Body.List)
+
+		for _, s := range s.Body.List {
+			clause, _ := s.(*ast.CommClause)
+			if clause == nil {
+				continue // error reported before
+			}
+
+			// clause.Comm must be a SendStmt, RecvStmt, or default case
+			valid := false
+			var rhs ast.Expr // rhs of RecvStmt, or nil
+			switch s := clause.Comm.(type) {
+			case nil, *ast.SendStmt:
+				valid = true
+			case *ast.AssignStmt:
+				if len(s.Rhs) == 1 {
+					rhs = s.Rhs[0]
+				}
+			case *ast.ExprStmt:
+				rhs = s.X
+			}
+
+			// if present, rhs must be a receive operation
+			if rhs != nil {
+				if x, _ := unparen(rhs).(*ast.UnaryExpr); x != nil && x.Op == token.ARROW {
+					valid = true
+				}
+			}
+
+			if !valid {
+				check.error(clause.Comm.Pos(), "select case must be send or receive (possibly with assignment)")
+				continue
+			}
+
+			check.openScope(s, "case")
+			if clause.Comm != nil {
+				check.stmt(inner, clause.Comm)
+			}
+			check.stmtList(inner, clause.Body)
+			check.closeScope()
+		}
+
+	case *ast.ForStmt:
+		inner |= breakOk | continueOk
+		check.openScope(s, "for")
+		defer check.closeScope()
+
+		check.simpleStmt(s.Init)
+		if s.Cond != nil {
+			var x operand
+			check.expr(&x, s.Cond)
+			if x.mode != invalid && !isBoolean(x.typ) {
+				check.error(s.Cond.Pos(), "non-boolean condition in for statement")
+			}
+		}
+		check.simpleStmt(s.Post)
+		// spec: "The init statement may be a short variable
+		// declaration, but the post statement must not."
+		if s, _ := s.Post.(*ast.AssignStmt); s != nil && s.Tok == token.DEFINE {
+			check.softErrorf(s.Pos(), "cannot declare in post statement")
+			check.use(s.Lhs...) // avoid follow-up errors
+		}
+		check.stmt(inner, s.Body)
+
+	case *ast.RangeStmt:
+		inner |= breakOk | continueOk
+		check.openScope(s, "for")
+		defer check.closeScope()
+
+		// check expression to iterate over
+		var x operand
+		check.expr(&x, s.X)
+
+		// determine key/value types
+		var key, val Type
+		if x.mode != invalid {
+			switch typ := x.typ.Underlying().(type) {
+			case *Basic:
+				if isString(typ) {
+					key = Typ[Int]
+					val = universeRune // use 'rune' name
+				}
+			case *Array:
+				key = Typ[Int]
+				val = typ.elem
+			case *Slice:
+				key = Typ[Int]
+				val = typ.elem
+			case *Pointer:
+				if typ, _ := typ.base.Underlying().(*Array); typ != nil {
+					key = Typ[Int]
+					val = typ.elem
+				}
+			case *Map:
+				key = typ.key
+				val = typ.elem
+			case *Chan:
+				key = typ.elem
+				val = Typ[Invalid]
+				if typ.dir == SendOnly {
+					check.errorf(x.pos(), "cannot range over send-only channel %s", &x)
+					// ok to continue
+				}
+				if s.Value != nil {
+					check.errorf(s.Value.Pos(), "iteration over %s permits only one iteration variable", &x)
+					// ok to continue
+				}
+			}
+		}
+
+		if key == nil {
+			check.errorf(x.pos(), "cannot range over %s", &x)
+			// ok to continue
+		}
+
+		// check assignment to/declaration of iteration variables
+		// (irregular assignment, cannot easily map to existing assignment checks)
+
+		// lhs expressions and initialization value (rhs) types
+		lhs := [2]ast.Expr{s.Key, s.Value}
+		rhs := [2]Type{key, val} // key, val may be nil
+
+		if s.Tok == token.DEFINE {
+			// short variable declaration; variable scope starts after the range clause
+			// (the for loop opens a new scope, so variables on the lhs never redeclare
+			// previously declared variables)
+			var vars []*Var
+			for i, lhs := range lhs {
+				if lhs == nil {
+					continue
+				}
+
+				// determine lhs variable
+				var obj *Var
+				if ident, _ := lhs.(*ast.Ident); ident != nil {
+					// declare new variable
+					name := ident.Name
+					obj = NewVar(ident.Pos(), check.pkg, name, nil)
+					check.recordDef(ident, obj)
+					// _ variables don't count as new variables
+					if name != "_" {
+						vars = append(vars, obj)
+					}
+				} else {
+					check.errorf(lhs.Pos(), "cannot declare %s", lhs)
+					obj = NewVar(lhs.Pos(), check.pkg, "_", nil) // dummy variable
+				}
+
+				// initialize lhs variable
+				if typ := rhs[i]; typ != nil {
+					x.mode = value
+					x.expr = lhs // we don't have a better rhs expression to use here
+					x.typ = typ
+					check.initVar(obj, &x, false)
+				} else {
+					obj.typ = Typ[Invalid]
+					obj.used = true // don't complain about unused variable
+				}
+			}
+
+			// declare variables
+			if len(vars) > 0 {
+				for _, obj := range vars {
+					// spec: "The scope of a constant or variable identifier declared inside
+					// a function begins at the end of the ConstSpec or VarSpec (ShortVarDecl
+					// for short variable declarations) and ends at the end of the innermost
+					// containing block."
+					scopePos := s.End()
+					check.declare(check.scope, nil /* recordDef already called */, obj, scopePos)
+				}
+			} else {
+				check.error(s.TokPos, "no new variables on left side of :=")
+			}
+		} else {
+			// ordinary assignment
+			for i, lhs := range lhs {
+				if lhs == nil {
+					continue
+				}
+				if typ := rhs[i]; typ != nil {
+					x.mode = value
+					x.expr = lhs // we don't have a better rhs expression to use here
+					x.typ = typ
+					check.assignVar(lhs, &x)
+				}
+			}
+		}
+
+		check.stmt(inner, s.Body)
+
+	default:
+		check.error(s.Pos(), "invalid statement")
+	}
+}
diff --git a/third_party/gofrontend/libgo/go/go/types/token_test.go b/third_party/gofrontend/libgo/go/go/types/token_test.go
new file mode 100644
index 0000000..705bb29
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/go/types/token_test.go
@@ -0,0 +1,47 @@
+// Copyright 2013 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.
+
+// This file checks invariants of token.Token ordering that we rely on
+// since package go/token doesn't provide any guarantees at the moment.
+
+package types
+
+import (
+	"go/token"
+	"testing"
+)
+
+var assignOps = map[token.Token]token.Token{
+	token.ADD_ASSIGN:     token.ADD,
+	token.SUB_ASSIGN:     token.SUB,
+	token.MUL_ASSIGN:     token.MUL,
+	token.QUO_ASSIGN:     token.QUO,
+	token.REM_ASSIGN:     token.REM,
+	token.AND_ASSIGN:     token.AND,
+	token.OR_ASSIGN:      token.OR,
+	token.XOR_ASSIGN:     token.XOR,
+	token.SHL_ASSIGN:     token.SHL,
+	token.SHR_ASSIGN:     token.SHR,
+	token.AND_NOT_ASSIGN: token.AND_NOT,
+}
+
+func TestZeroTok(t *testing.T) {
+	// zero value for token.Token must be token.ILLEGAL
+	var zero token.Token
+	if token.ILLEGAL != zero {
+		t.Errorf("%s == %d; want 0", token.ILLEGAL, zero)
+	}
+}
+
+func TestAssignOp(t *testing.T) {
+	// there are fewer than 256 tokens
+	for i := 0; i < 256; i++ {
+		tok := token.Token(i)
+		got := assignOp(tok)
+		want := assignOps[tok]
+		if got != want {
+			t.Errorf("for assignOp(%s): got %s; want %s", tok, got, want)
+		}
+	}
+}
diff --git a/third_party/gofrontend/libgo/go/go/types/type.go b/third_party/gofrontend/libgo/go/go/types/type.go
new file mode 100644
index 0000000..1df8b45
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/go/types/type.go
@@ -0,0 +1,454 @@
+// Copyright 2011 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 types
+
+import "sort"
+
+// TODO(gri) Revisit factory functions - make sure they have all relevant parameters.
+
+// A Type represents a type of Go.
+// All types implement the Type interface.
+type Type interface {
+	// Underlying returns the underlying type of a type.
+	Underlying() Type
+
+	// String returns a string representation of a type.
+	String() string
+}
+
+// BasicKind describes the kind of basic type.
+type BasicKind int
+
+const (
+	Invalid BasicKind = iota // type is invalid
+
+	// predeclared types
+	Bool
+	Int
+	Int8
+	Int16
+	Int32
+	Int64
+	Uint
+	Uint8
+	Uint16
+	Uint32
+	Uint64
+	Uintptr
+	Float32
+	Float64
+	Complex64
+	Complex128
+	String
+	UnsafePointer
+
+	// types for untyped values
+	UntypedBool
+	UntypedInt
+	UntypedRune
+	UntypedFloat
+	UntypedComplex
+	UntypedString
+	UntypedNil
+
+	// aliases
+	Byte = Uint8
+	Rune = Int32
+)
+
+// BasicInfo is a set of flags describing properties of a basic type.
+type BasicInfo int
+
+// Properties of basic types.
+const (
+	IsBoolean BasicInfo = 1 << iota
+	IsInteger
+	IsUnsigned
+	IsFloat
+	IsComplex
+	IsString
+	IsUntyped
+
+	IsOrdered   = IsInteger | IsFloat | IsString
+	IsNumeric   = IsInteger | IsFloat | IsComplex
+	IsConstType = IsBoolean | IsNumeric | IsString
+)
+
+// A Basic represents a basic type.
+type Basic struct {
+	kind BasicKind
+	info BasicInfo
+	name string
+}
+
+// Kind returns the kind of basic type b.
+func (b *Basic) Kind() BasicKind { return b.kind }
+
+// Info returns information about properties of basic type b.
+func (b *Basic) Info() BasicInfo { return b.info }
+
+// Name returns the name of basic type b.
+func (b *Basic) Name() string { return b.name }
+
+// An Array represents an array type.
+type Array struct {
+	len  int64
+	elem Type
+}
+
+// NewArray returns a new array type for the given element type and length.
+func NewArray(elem Type, len int64) *Array { return &Array{len, elem} }
+
+// Len returns the length of array a.
+func (a *Array) Len() int64 { return a.len }
+
+// Elem returns element type of array a.
+func (a *Array) Elem() Type { return a.elem }
+
+// A Slice represents a slice type.
+type Slice struct {
+	elem Type
+}
+
+// NewSlice returns a new slice type for the given element type.
+func NewSlice(elem Type) *Slice { return &Slice{elem} }
+
+// Elem returns the element type of slice s.
+func (s *Slice) Elem() Type { return s.elem }
+
+// A Struct represents a struct type.
+type Struct struct {
+	fields []*Var
+	tags   []string // field tags; nil if there are no tags
+	// TODO(gri) access to offsets is not threadsafe - fix this
+	offsets []int64 // field offsets in bytes, lazily initialized
+}
+
+// NewStruct returns a new struct with the given fields and corresponding field tags.
+// If a field with index i has a tag, tags[i] must be that tag, but len(tags) may be
+// only as long as required to hold the tag with the largest index i. Consequently,
+// if no field has a tag, tags may be nil.
+func NewStruct(fields []*Var, tags []string) *Struct {
+	var fset objset
+	for _, f := range fields {
+		if f.name != "_" && fset.insert(f) != nil {
+			panic("multiple fields with the same name")
+		}
+	}
+	if len(tags) > len(fields) {
+		panic("more tags than fields")
+	}
+	return &Struct{fields: fields, tags: tags}
+}
+
+// NumFields returns the number of fields in the struct (including blank and anonymous fields).
+func (s *Struct) NumFields() int { return len(s.fields) }
+
+// Field returns the i'th field for 0 <= i < NumFields().
+func (s *Struct) Field(i int) *Var { return s.fields[i] }
+
+// Tag returns the i'th field tag for 0 <= i < NumFields().
+func (s *Struct) Tag(i int) string {
+	if i < len(s.tags) {
+		return s.tags[i]
+	}
+	return ""
+}
+
+// A Pointer represents a pointer type.
+type Pointer struct {
+	base Type // element type
+}
+
+// NewPointer returns a new pointer type for the given element (base) type.
+func NewPointer(elem Type) *Pointer { return &Pointer{base: elem} }
+
+// Elem returns the element type for the given pointer p.
+func (p *Pointer) Elem() Type { return p.base }
+
+// A Tuple represents an ordered list of variables; a nil *Tuple is a valid (empty) tuple.
+// Tuples are used as components of signatures and to represent the type of multiple
+// assignments; they are not first class types of Go.
+type Tuple struct {
+	vars []*Var
+}
+
+// NewTuple returns a new tuple for the given variables.
+func NewTuple(x ...*Var) *Tuple {
+	if len(x) > 0 {
+		return &Tuple{x}
+	}
+	return nil
+}
+
+// Len returns the number variables of tuple t.
+func (t *Tuple) Len() int {
+	if t != nil {
+		return len(t.vars)
+	}
+	return 0
+}
+
+// At returns the i'th variable of tuple t.
+func (t *Tuple) At(i int) *Var { return t.vars[i] }
+
+// A Signature represents a (non-builtin) function or method type.
+type Signature struct {
+	// We need to keep the scope in Signature (rather than passing it around
+	// and store it in the Func Object) because when type-checking a function
+	// literal we call the general type checker which returns a general Type.
+	// We then unpack the *Signature and use the scope for the literal body.
+	scope    *Scope // function scope, present for package-local signatures
+	recv     *Var   // nil if not a method
+	params   *Tuple // (incoming) parameters from left to right; or nil
+	results  *Tuple // (outgoing) results from left to right; or nil
+	variadic bool   // true if the last parameter's type is of the form ...T (or string, for append built-in only)
+}
+
+// NewSignature returns a new function type for the given receiver, parameters,
+// and results, either of which may be nil. If variadic is set, the function
+// is variadic, it must have at least one parameter, and the last parameter
+// must be of unnamed slice type.
+func NewSignature(recv *Var, params, results *Tuple, variadic bool) *Signature {
+	if variadic {
+		n := params.Len()
+		if n == 0 {
+			panic("types.NewSignature: variadic function must have at least one parameter")
+		}
+		if _, ok := params.At(n - 1).typ.(*Slice); !ok {
+			panic("types.NewSignature: variadic parameter must be of unnamed slice type")
+		}
+	}
+	return &Signature{nil, recv, params, results, variadic}
+}
+
+// Recv returns the receiver of signature s (if a method), or nil if a
+// function.
+//
+// For an abstract method, Recv returns the enclosing interface either
+// as a *Named or an *Interface.  Due to embedding, an interface may
+// contain methods whose receiver type is a different interface.
+func (s *Signature) Recv() *Var { return s.recv }
+
+// Params returns the parameters of signature s, or nil.
+func (s *Signature) Params() *Tuple { return s.params }
+
+// Results returns the results of signature s, or nil.
+func (s *Signature) Results() *Tuple { return s.results }
+
+// Variadic reports whether the signature s is variadic.
+func (s *Signature) Variadic() bool { return s.variadic }
+
+// An Interface represents an interface type.
+type Interface struct {
+	methods   []*Func  // ordered list of explicitly declared methods
+	embeddeds []*Named // ordered list of explicitly embedded types
+
+	allMethods []*Func // ordered list of methods declared with or embedded in this interface (TODO(gri): replace with mset)
+}
+
+// NewInterface returns a new interface for the given methods and embedded types.
+func NewInterface(methods []*Func, embeddeds []*Named) *Interface {
+	typ := new(Interface)
+
+	var mset objset
+	for _, m := range methods {
+		if mset.insert(m) != nil {
+			panic("multiple methods with the same name")
+		}
+		// set receiver
+		// TODO(gri) Ideally, we should use a named type here instead of
+		// typ, for less verbose printing of interface method signatures.
+		m.typ.(*Signature).recv = NewVar(m.pos, m.pkg, "", typ)
+	}
+	sort.Sort(byUniqueMethodName(methods))
+
+	if embeddeds == nil {
+		sort.Sort(byUniqueTypeName(embeddeds))
+	}
+
+	typ.methods = methods
+	typ.embeddeds = embeddeds
+	return typ
+}
+
+// NumExplicitMethods returns the number of explicitly declared methods of interface t.
+func (t *Interface) NumExplicitMethods() int { return len(t.methods) }
+
+// ExplicitMethod returns the i'th explicitly declared method of interface t for 0 <= i < t.NumExplicitMethods().
+// The methods are ordered by their unique Id.
+func (t *Interface) ExplicitMethod(i int) *Func { return t.methods[i] }
+
+// NumEmbeddeds returns the number of embedded types in interface t.
+func (t *Interface) NumEmbeddeds() int { return len(t.embeddeds) }
+
+// Embedded returns the i'th embedded type of interface t for 0 <= i < t.NumEmbeddeds().
+// The types are ordered by the corresponding TypeName's unique Id.
+func (t *Interface) Embedded(i int) *Named { return t.embeddeds[i] }
+
+// NumMethods returns the total number of methods of interface t.
+func (t *Interface) NumMethods() int { return len(t.allMethods) }
+
+// Method returns the i'th method of interface t for 0 <= i < t.NumMethods().
+// The methods are ordered by their unique Id.
+func (t *Interface) Method(i int) *Func { return t.allMethods[i] }
+
+// Empty returns true if t is the empty interface.
+func (t *Interface) Empty() bool { return len(t.allMethods) == 0 }
+
+// Complete computes the interface's method set. It must be called by users of
+// NewInterface after the interface's embedded types are fully defined and
+// before using the interface type in any way other than to form other types.
+// Complete returns the receiver.
+func (t *Interface) Complete() *Interface {
+	if t.allMethods != nil {
+		return t
+	}
+
+	var allMethods []*Func
+	if t.embeddeds == nil {
+		if t.methods == nil {
+			allMethods = make([]*Func, 0, 1)
+		} else {
+			allMethods = t.methods
+		}
+	} else {
+		allMethods = append(allMethods, t.methods...)
+		for _, et := range t.embeddeds {
+			it := et.Underlying().(*Interface)
+			it.Complete()
+			for _, tm := range it.allMethods {
+				// Make a copy of the method and adjust its receiver type.
+				newm := *tm
+				newmtyp := *tm.typ.(*Signature)
+				newm.typ = &newmtyp
+				newmtyp.recv = NewVar(newm.pos, newm.pkg, "", t)
+				allMethods = append(allMethods, &newm)
+			}
+		}
+		sort.Sort(byUniqueMethodName(allMethods))
+	}
+	t.allMethods = allMethods
+
+	return t
+}
+
+// A Map represents a map type.
+type Map struct {
+	key, elem Type
+}
+
+// NewMap returns a new map for the given key and element types.
+func NewMap(key, elem Type) *Map {
+	return &Map{key, elem}
+}
+
+// Key returns the key type of map m.
+func (m *Map) Key() Type { return m.key }
+
+// Elem returns the element type of map m.
+func (m *Map) Elem() Type { return m.elem }
+
+// A Chan represents a channel type.
+type Chan struct {
+	dir  ChanDir
+	elem Type
+}
+
+// A ChanDir value indicates a channel direction.
+type ChanDir int
+
+// The direction of a channel is indicated by one of the following constants.
+const (
+	SendRecv ChanDir = iota
+	SendOnly
+	RecvOnly
+)
+
+// NewChan returns a new channel type for the given direction and element type.
+func NewChan(dir ChanDir, elem Type) *Chan {
+	return &Chan{dir, elem}
+}
+
+// Dir returns the direction of channel c.
+func (c *Chan) Dir() ChanDir { return c.dir }
+
+// Elem returns the element type of channel c.
+func (c *Chan) Elem() Type { return c.elem }
+
+// A Named represents a named type.
+type Named struct {
+	obj        *TypeName // corresponding declared object
+	underlying Type      // possibly a *Named during setup; never a *Named once set up completely
+	methods    []*Func   // methods declared for this type (not the method set of this type)
+}
+
+// NewNamed returns a new named type for the given type name, underlying type, and associated methods.
+// The underlying type must not be a *Named.
+func NewNamed(obj *TypeName, underlying Type, methods []*Func) *Named {
+	if _, ok := underlying.(*Named); ok {
+		panic("types.NewNamed: underlying type must not be *Named")
+	}
+	typ := &Named{obj: obj, underlying: underlying, methods: methods}
+	if obj.typ == nil {
+		obj.typ = typ
+	}
+	return typ
+}
+
+// TypeName returns the type name for the named type t.
+func (t *Named) Obj() *TypeName { return t.obj }
+
+// NumMethods returns the number of explicit methods whose receiver is named type t.
+func (t *Named) NumMethods() int { return len(t.methods) }
+
+// Method returns the i'th method of named type t for 0 <= i < t.NumMethods().
+func (t *Named) Method(i int) *Func { return t.methods[i] }
+
+// SetUnderlying sets the underlying type and marks t as complete.
+// TODO(gri) determine if there's a better solution rather than providing this function
+func (t *Named) SetUnderlying(underlying Type) {
+	if underlying == nil {
+		panic("types.Named.SetUnderlying: underlying type must not be nil")
+	}
+	if _, ok := underlying.(*Named); ok {
+		panic("types.Named.SetUnderlying: underlying type must not be *Named")
+	}
+	t.underlying = underlying
+}
+
+// AddMethod adds method m unless it is already in the method list.
+// TODO(gri) find a better solution instead of providing this function
+func (t *Named) AddMethod(m *Func) {
+	if i, _ := lookupMethod(t.methods, m.pkg, m.name); i < 0 {
+		t.methods = append(t.methods, m)
+	}
+}
+
+// Implementations for Type methods.
+
+func (t *Basic) Underlying() Type     { return t }
+func (t *Array) Underlying() Type     { return t }
+func (t *Slice) Underlying() Type     { return t }
+func (t *Struct) Underlying() Type    { return t }
+func (t *Pointer) Underlying() Type   { return t }
+func (t *Tuple) Underlying() Type     { return t }
+func (t *Signature) Underlying() Type { return t }
+func (t *Interface) Underlying() Type { return t }
+func (t *Map) Underlying() Type       { return t }
+func (t *Chan) Underlying() Type      { return t }
+func (t *Named) Underlying() Type     { return t.underlying }
+
+func (t *Basic) String() string     { return TypeString(t, nil) }
+func (t *Array) String() string     { return TypeString(t, nil) }
+func (t *Slice) String() string     { return TypeString(t, nil) }
+func (t *Struct) String() string    { return TypeString(t, nil) }
+func (t *Pointer) String() string   { return TypeString(t, nil) }
+func (t *Tuple) String() string     { return TypeString(t, nil) }
+func (t *Signature) String() string { return TypeString(t, nil) }
+func (t *Interface) String() string { return TypeString(t, nil) }
+func (t *Map) String() string       { return TypeString(t, nil) }
+func (t *Chan) String() string      { return TypeString(t, nil) }
+func (t *Named) String() string     { return TypeString(t, nil) }
diff --git a/third_party/gofrontend/libgo/go/go/types/typestring.go b/third_party/gofrontend/libgo/go/go/types/typestring.go
new file mode 100644
index 0000000..bd62f4d
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/go/types/typestring.go
@@ -0,0 +1,296 @@
+// Copyright 2013 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.
+
+// This file implements printing of types.
+
+package types
+
+import (
+	"bytes"
+	"fmt"
+)
+
+// A Qualifier controls how named package-level objects are printed in
+// calls to TypeString, ObjectString, and SelectionString.
+//
+// These three formatting routines call the Qualifier for each
+// package-level object O, and if the Qualifier returns a non-empty
+// string p, the object is printed in the form p.O.
+// If it returns an empty string, only the object name O is printed.
+//
+// Using a nil Qualifier is equivalent to using (*Package).Path: the
+// object is qualified by the import path, e.g., "encoding/json.Marshal".
+//
+type Qualifier func(*Package) string
+
+// RelativeTo(pkg) returns a Qualifier that fully qualifies members of
+// all packages other than pkg.
+func RelativeTo(pkg *Package) Qualifier {
+	if pkg == nil {
+		return nil
+	}
+	return func(other *Package) string {
+		if pkg == other {
+			return "" // same package; unqualified
+		}
+		return other.Path()
+	}
+}
+
+// If gcCompatibilityMode is set, printing of types is modified
+// to match the representation of some types in the gc compiler:
+//
+//	- byte and rune lose their alias name and simply stand for
+//	  uint8 and int32 respectively
+//	- embedded interfaces get flattened (the embedding info is lost,
+//	  and certain recursive interface types cannot be printed anymore)
+//
+// This makes it easier to compare packages computed with the type-
+// checker vs packages imported from gc export data.
+//
+// Caution: This flag affects all uses of WriteType, globally.
+// It is only provided for testing in conjunction with
+// gc-generated data.
+//
+// This flag is exported in the x/tools/go/types package. We don't
+// need it at the moment in the std repo and so we don't export it
+// anymore. We should eventually try to remove it altogether.
+var gcCompatibilityMode bool
+
+// TypeString returns the string representation of typ.
+// The Qualifier controls the printing of
+// package-level objects, and may be nil.
+func TypeString(typ Type, qf Qualifier) string {
+	var buf bytes.Buffer
+	WriteType(&buf, typ, qf)
+	return buf.String()
+}
+
+// WriteType writes the string representation of typ to buf.
+// The Qualifier controls the printing of
+// package-level objects, and may be nil.
+func WriteType(buf *bytes.Buffer, typ Type, qf Qualifier) {
+	writeType(buf, typ, qf, make([]Type, 8))
+}
+
+func writeType(buf *bytes.Buffer, typ Type, qf Qualifier, visited []Type) {
+	// Theoretically, this is a quadratic lookup algorithm, but in
+	// practice deeply nested composite types with unnamed component
+	// types are uncommon. This code is likely more efficient than
+	// using a map.
+	for _, t := range visited {
+		if t == typ {
+			fmt.Fprintf(buf, "○%T", typ) // cycle to typ
+			return
+		}
+	}
+	visited = append(visited, typ)
+
+	switch t := typ.(type) {
+	case nil:
+		buf.WriteString("<nil>")
+
+	case *Basic:
+		if t.kind == UnsafePointer {
+			buf.WriteString("unsafe.")
+		}
+		if gcCompatibilityMode {
+			// forget the alias names
+			switch t.kind {
+			case Byte:
+				t = Typ[Uint8]
+			case Rune:
+				t = Typ[Int32]
+			}
+		}
+		buf.WriteString(t.name)
+
+	case *Array:
+		fmt.Fprintf(buf, "[%d]", t.len)
+		writeType(buf, t.elem, qf, visited)
+
+	case *Slice:
+		buf.WriteString("[]")
+		writeType(buf, t.elem, qf, visited)
+
+	case *Struct:
+		buf.WriteString("struct{")
+		for i, f := range t.fields {
+			if i > 0 {
+				buf.WriteString("; ")
+			}
+			if !f.anonymous {
+				buf.WriteString(f.name)
+				buf.WriteByte(' ')
+			}
+			writeType(buf, f.typ, qf, visited)
+			if tag := t.Tag(i); tag != "" {
+				fmt.Fprintf(buf, " %q", tag)
+			}
+		}
+		buf.WriteByte('}')
+
+	case *Pointer:
+		buf.WriteByte('*')
+		writeType(buf, t.base, qf, visited)
+
+	case *Tuple:
+		writeTuple(buf, t, false, qf, visited)
+
+	case *Signature:
+		buf.WriteString("func")
+		writeSignature(buf, t, qf, visited)
+
+	case *Interface:
+		// We write the source-level methods and embedded types rather
+		// than the actual method set since resolved method signatures
+		// may have non-printable cycles if parameters have anonymous
+		// interface types that (directly or indirectly) embed the
+		// current interface. For instance, consider the result type
+		// of m:
+		//
+		//     type T interface{
+		//         m() interface{ T }
+		//     }
+		//
+		buf.WriteString("interface{")
+		if gcCompatibilityMode {
+			// print flattened interface
+			// (useful to compare against gc-generated interfaces)
+			for i, m := range t.allMethods {
+				if i > 0 {
+					buf.WriteString("; ")
+				}
+				buf.WriteString(m.name)
+				writeSignature(buf, m.typ.(*Signature), qf, visited)
+			}
+		} else {
+			// print explicit interface methods and embedded types
+			for i, m := range t.methods {
+				if i > 0 {
+					buf.WriteString("; ")
+				}
+				buf.WriteString(m.name)
+				writeSignature(buf, m.typ.(*Signature), qf, visited)
+			}
+			for i, typ := range t.embeddeds {
+				if i > 0 || len(t.methods) > 0 {
+					buf.WriteString("; ")
+				}
+				writeType(buf, typ, qf, visited)
+			}
+		}
+		buf.WriteByte('}')
+
+	case *Map:
+		buf.WriteString("map[")
+		writeType(buf, t.key, qf, visited)
+		buf.WriteByte(']')
+		writeType(buf, t.elem, qf, visited)
+
+	case *Chan:
+		var s string
+		var parens bool
+		switch t.dir {
+		case SendRecv:
+			s = "chan "
+			// chan (<-chan T) requires parentheses
+			if c, _ := t.elem.(*Chan); c != nil && c.dir == RecvOnly {
+				parens = true
+			}
+		case SendOnly:
+			s = "chan<- "
+		case RecvOnly:
+			s = "<-chan "
+		default:
+			panic("unreachable")
+		}
+		buf.WriteString(s)
+		if parens {
+			buf.WriteByte('(')
+		}
+		writeType(buf, t.elem, qf, visited)
+		if parens {
+			buf.WriteByte(')')
+		}
+
+	case *Named:
+		s := "<Named w/o object>"
+		if obj := t.obj; obj != nil {
+			if obj.pkg != nil {
+				writePackage(buf, obj.pkg, qf)
+			}
+			// TODO(gri): function-local named types should be displayed
+			// differently from named types at package level to avoid
+			// ambiguity.
+			s = obj.name
+		}
+		buf.WriteString(s)
+
+	default:
+		// For externally defined implementations of Type.
+		buf.WriteString(t.String())
+	}
+}
+
+func writeTuple(buf *bytes.Buffer, tup *Tuple, variadic bool, qf Qualifier, visited []Type) {
+	buf.WriteByte('(')
+	if tup != nil {
+		for i, v := range tup.vars {
+			if i > 0 {
+				buf.WriteString(", ")
+			}
+			if v.name != "" {
+				buf.WriteString(v.name)
+				buf.WriteByte(' ')
+			}
+			typ := v.typ
+			if variadic && i == len(tup.vars)-1 {
+				if s, ok := typ.(*Slice); ok {
+					buf.WriteString("...")
+					typ = s.elem
+				} else {
+					// special case:
+					// append(s, "foo"...) leads to signature func([]byte, string...)
+					if t, ok := typ.Underlying().(*Basic); !ok || t.kind != String {
+						panic("internal error: string type expected")
+					}
+					writeType(buf, typ, qf, visited)
+					buf.WriteString("...")
+					continue
+				}
+			}
+			writeType(buf, typ, qf, visited)
+		}
+	}
+	buf.WriteByte(')')
+}
+
+// WriteSignature writes the representation of the signature sig to buf,
+// without a leading "func" keyword.
+// The Qualifier controls the printing of
+// package-level objects, and may be nil.
+func WriteSignature(buf *bytes.Buffer, sig *Signature, qf Qualifier) {
+	writeSignature(buf, sig, qf, make([]Type, 8))
+}
+
+func writeSignature(buf *bytes.Buffer, sig *Signature, qf Qualifier, visited []Type) {
+	writeTuple(buf, sig.params, sig.variadic, qf, visited)
+
+	n := sig.results.Len()
+	if n == 0 {
+		// no result
+		return
+	}
+
+	buf.WriteByte(' ')
+	if n == 1 && sig.results.vars[0].name == "" {
+		// single unnamed result
+		writeType(buf, sig.results.vars[0].typ, qf, visited)
+		return
+	}
+
+	// multiple or named result(s)
+	writeTuple(buf, sig.results, false, qf, visited)
+}
diff --git a/third_party/gofrontend/libgo/go/go/types/typestring_test.go b/third_party/gofrontend/libgo/go/go/types/typestring_test.go
new file mode 100644
index 0000000..913e6c7
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/go/types/typestring_test.go
@@ -0,0 +1,168 @@
+// Copyright 2012 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 types_test
+
+import (
+	"go/ast"
+	"go/importer"
+	"go/parser"
+	"go/token"
+	"internal/testenv"
+	"testing"
+
+	. "go/types"
+)
+
+const filename = "<src>"
+
+func makePkg(t *testing.T, src string) (*Package, error) {
+	fset := token.NewFileSet()
+	file, err := parser.ParseFile(fset, filename, src, parser.DeclarationErrors)
+	if err != nil {
+		return nil, err
+	}
+	// use the package name as package path
+	conf := Config{Importer: importer.Default()}
+	return conf.Check(file.Name.Name, fset, []*ast.File{file}, nil)
+}
+
+type testEntry struct {
+	src, str string
+}
+
+// dup returns a testEntry where both src and str are the same.
+func dup(s string) testEntry {
+	return testEntry{s, s}
+}
+
+// types that don't depend on any other type declarations
+var independentTestTypes = []testEntry{
+	// basic types
+	dup("int"),
+	dup("float32"),
+	dup("string"),
+
+	// arrays
+	dup("[10]int"),
+
+	// slices
+	dup("[]int"),
+	dup("[][]int"),
+
+	// structs
+	dup("struct{}"),
+	dup("struct{x int}"),
+	{`struct {
+		x, y int
+		z float32 "foo"
+	}`, `struct{x int; y int; z float32 "foo"}`},
+	{`struct {
+		string
+		elems []complex128
+	}`, `struct{string; elems []complex128}`},
+
+	// pointers
+	dup("*int"),
+	dup("***struct{}"),
+	dup("*struct{a int; b float32}"),
+
+	// functions
+	dup("func()"),
+	dup("func(x int)"),
+	{"func(x, y int)", "func(x int, y int)"},
+	{"func(x, y int, z string)", "func(x int, y int, z string)"},
+	dup("func(int)"),
+	{"func(int, string, byte)", "func(int, string, byte)"},
+
+	dup("func() int"),
+	{"func() (string)", "func() string"},
+	dup("func() (u int)"),
+	{"func() (u, v int, w string)", "func() (u int, v int, w string)"},
+
+	dup("func(int) string"),
+	dup("func(x int) string"),
+	dup("func(x int) (u string)"),
+	{"func(x, y int) (u string)", "func(x int, y int) (u string)"},
+
+	dup("func(...int) string"),
+	dup("func(x ...int) string"),
+	dup("func(x ...int) (u string)"),
+	{"func(x, y ...int) (u string)", "func(x int, y ...int) (u string)"},
+
+	// interfaces
+	dup("interface{}"),
+	dup("interface{m()}"),
+	dup(`interface{String() string; m(int) float32}`),
+
+	// maps
+	dup("map[string]int"),
+	{"map[struct{x, y int}][]byte", "map[struct{x int; y int}][]byte"},
+
+	// channels
+	dup("chan<- chan int"),
+	dup("chan<- <-chan int"),
+	dup("<-chan <-chan int"),
+	dup("chan (<-chan int)"),
+	dup("chan<- func()"),
+	dup("<-chan []func() int"),
+}
+
+// types that depend on other type declarations (src in TestTypes)
+var dependentTestTypes = []testEntry{
+	// interfaces
+	dup(`interface{io.Reader; io.Writer}`),
+	dup(`interface{m() int; io.Writer}`),
+	{`interface{m() interface{T}}`, `interface{m() interface{p.T}}`},
+}
+
+func TestTypeString(t *testing.T) {
+	testenv.MustHaveGoBuild(t)
+
+	var tests []testEntry
+	tests = append(tests, independentTestTypes...)
+	tests = append(tests, dependentTestTypes...)
+
+	for _, test := range tests {
+		src := `package p; import "io"; type _ io.Writer; type T ` + test.src
+		pkg, err := makePkg(t, src)
+		if err != nil {
+			t.Errorf("%s: %s", src, err)
+			continue
+		}
+		typ := pkg.Scope().Lookup("T").Type().Underlying()
+		if got := typ.String(); got != test.str {
+			t.Errorf("%s: got %s, want %s", test.src, got, test.str)
+		}
+	}
+}
+
+func TestQualifiedTypeString(t *testing.T) {
+	p, _ := pkgFor("p.go", "package p; type T int", nil)
+	q, _ := pkgFor("q.go", "package q", nil)
+
+	pT := p.Scope().Lookup("T").Type()
+	for _, test := range []struct {
+		typ  Type
+		this *Package
+		want string
+	}{
+		{pT, nil, "p.T"},
+		{pT, p, "T"},
+		{pT, q, "p.T"},
+		{NewPointer(pT), p, "*T"},
+		{NewPointer(pT), q, "*p.T"},
+	} {
+		qualifier := func(pkg *Package) string {
+			if pkg != test.this {
+				return pkg.Name()
+			}
+			return ""
+		}
+		if got := TypeString(test.typ, qualifier); got != test.want {
+			t.Errorf("TypeString(%s, %s) = %s, want %s",
+				test.this, test.typ, got, test.want)
+		}
+	}
+}
diff --git a/third_party/gofrontend/libgo/go/go/types/typexpr.go b/third_party/gofrontend/libgo/go/go/types/typexpr.go
new file mode 100644
index 0000000..c744eea
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/go/types/typexpr.go
@@ -0,0 +1,712 @@
+// Copyright 2013 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.
+
+// This file implements type-checking of identifiers and type expressions.
+
+package types
+
+import (
+	"go/ast"
+	"go/constant"
+	"go/token"
+	"sort"
+	"strconv"
+)
+
+// ident type-checks identifier e and initializes x with the value or type of e.
+// If an error occurred, x.mode is set to invalid.
+// For the meaning of def and path, see check.typ, below.
+//
+func (check *Checker) ident(x *operand, e *ast.Ident, def *Named, path []*TypeName) {
+	x.mode = invalid
+	x.expr = e
+
+	scope, obj := check.scope.LookupParent(e.Name, check.pos)
+	if obj == nil {
+		if e.Name == "_" {
+			check.errorf(e.Pos(), "cannot use _ as value or type")
+		} else {
+			check.errorf(e.Pos(), "undeclared name: %s", e.Name)
+		}
+		return
+	}
+	check.recordUse(e, obj)
+
+	check.objDecl(obj, def, path)
+	typ := obj.Type()
+	assert(typ != nil)
+
+	// The object may be dot-imported: If so, remove its package from
+	// the map of unused dot imports for the respective file scope.
+	// (This code is only needed for dot-imports. Without them,
+	// we only have to mark variables, see *Var case below).
+	if pkg := obj.Pkg(); pkg != check.pkg && pkg != nil {
+		delete(check.unusedDotImports[scope], pkg)
+	}
+
+	switch obj := obj.(type) {
+	case *PkgName:
+		check.errorf(e.Pos(), "use of package %s not in selector", obj.name)
+		return
+
+	case *Const:
+		check.addDeclDep(obj)
+		if typ == Typ[Invalid] {
+			return
+		}
+		if obj == universeIota {
+			if check.iota == nil {
+				check.errorf(e.Pos(), "cannot use iota outside constant declaration")
+				return
+			}
+			x.val = check.iota
+		} else {
+			x.val = obj.val
+		}
+		assert(x.val != nil)
+		x.mode = constant_
+
+	case *TypeName:
+		x.mode = typexpr
+		// check for cycle
+		// (it's ok to iterate forward because each named type appears at most once in path)
+		for i, prev := range path {
+			if prev == obj {
+				check.errorf(obj.pos, "illegal cycle in declaration of %s", obj.name)
+				// print cycle
+				for _, obj := range path[i:] {
+					check.errorf(obj.Pos(), "\t%s refers to", obj.Name()) // secondary error, \t indented
+				}
+				check.errorf(obj.Pos(), "\t%s", obj.Name())
+				// maintain x.mode == typexpr despite error
+				typ = Typ[Invalid]
+				break
+			}
+		}
+
+	case *Var:
+		if obj.pkg == check.pkg {
+			obj.used = true
+		}
+		check.addDeclDep(obj)
+		if typ == Typ[Invalid] {
+			return
+		}
+		x.mode = variable
+
+	case *Func:
+		check.addDeclDep(obj)
+		x.mode = value
+
+	case *Builtin:
+		x.id = obj.id
+		x.mode = builtin
+
+	case *Nil:
+		x.mode = value
+
+	default:
+		unreachable()
+	}
+
+	x.typ = typ
+}
+
+// typExpr type-checks the type expression e and returns its type, or Typ[Invalid].
+// If def != nil, e is the type specification for the named type def, declared
+// in a type declaration, and def.underlying will be set to the type of e before
+// any components of e are type-checked. Path contains the path of named types
+// referring to this type.
+//
+func (check *Checker) typExpr(e ast.Expr, def *Named, path []*TypeName) (T Type) {
+	if trace {
+		check.trace(e.Pos(), "%s", e)
+		check.indent++
+		defer func() {
+			check.indent--
+			check.trace(e.Pos(), "=> %s", T)
+		}()
+	}
+
+	T = check.typExprInternal(e, def, path)
+	assert(isTyped(T))
+	check.recordTypeAndValue(e, typexpr, T, nil)
+
+	return
+}
+
+func (check *Checker) typ(e ast.Expr) Type {
+	return check.typExpr(e, nil, nil)
+}
+
+// funcType type-checks a function or method type.
+func (check *Checker) funcType(sig *Signature, recvPar *ast.FieldList, ftyp *ast.FuncType) {
+	scope := NewScope(check.scope, token.NoPos, token.NoPos, "function")
+	check.recordScope(ftyp, scope)
+
+	recvList, _ := check.collectParams(scope, recvPar, false)
+	params, variadic := check.collectParams(scope, ftyp.Params, true)
+	results, _ := check.collectParams(scope, ftyp.Results, false)
+
+	if recvPar != nil {
+		// recv parameter list present (may be empty)
+		// spec: "The receiver is specified via an extra parameter section preceding the
+		// method name. That parameter section must declare a single parameter, the receiver."
+		var recv *Var
+		switch len(recvList) {
+		case 0:
+			check.error(recvPar.Pos(), "method is missing receiver")
+			recv = NewParam(0, nil, "", Typ[Invalid]) // ignore recv below
+		default:
+			// more than one receiver
+			check.error(recvList[len(recvList)-1].Pos(), "method must have exactly one receiver")
+			fallthrough // continue with first receiver
+		case 1:
+			recv = recvList[0]
+		}
+		// spec: "The receiver type must be of the form T or *T where T is a type name."
+		// (ignore invalid types - error was reported before)
+		if t, _ := deref(recv.typ); t != Typ[Invalid] {
+			var err string
+			if T, _ := t.(*Named); T != nil {
+				// spec: "The type denoted by T is called the receiver base type; it must not
+				// be a pointer or interface type and it must be declared in the same package
+				// as the method."
+				if T.obj.pkg != check.pkg {
+					err = "type not defined in this package"
+				} else {
+					// TODO(gri) This is not correct if the underlying type is unknown yet.
+					switch u := T.underlying.(type) {
+					case *Basic:
+						// unsafe.Pointer is treated like a regular pointer
+						if u.kind == UnsafePointer {
+							err = "unsafe.Pointer"
+						}
+					case *Pointer, *Interface:
+						err = "pointer or interface type"
+					}
+				}
+			} else {
+				err = "basic or unnamed type"
+			}
+			if err != "" {
+				check.errorf(recv.pos, "invalid receiver %s (%s)", recv.typ, err)
+				// ok to continue
+			}
+		}
+		sig.recv = recv
+	}
+
+	sig.scope = scope
+	sig.params = NewTuple(params...)
+	sig.results = NewTuple(results...)
+	sig.variadic = variadic
+}
+
+// typExprInternal drives type checking of types.
+// Must only be called by typExpr.
+//
+func (check *Checker) typExprInternal(e ast.Expr, def *Named, path []*TypeName) Type {
+	switch e := e.(type) {
+	case *ast.BadExpr:
+		// ignore - error reported before
+
+	case *ast.Ident:
+		var x operand
+		check.ident(&x, e, def, path)
+
+		switch x.mode {
+		case typexpr:
+			typ := x.typ
+			def.setUnderlying(typ)
+			return typ
+		case invalid:
+			// ignore - error reported before
+		case novalue:
+			check.errorf(x.pos(), "%s used as type", &x)
+		default:
+			check.errorf(x.pos(), "%s is not a type", &x)
+		}
+
+	case *ast.SelectorExpr:
+		var x operand
+		check.selector(&x, e)
+
+		switch x.mode {
+		case typexpr:
+			typ := x.typ
+			def.setUnderlying(typ)
+			return typ
+		case invalid:
+			// ignore - error reported before
+		case novalue:
+			check.errorf(x.pos(), "%s used as type", &x)
+		default:
+			check.errorf(x.pos(), "%s is not a type", &x)
+		}
+
+	case *ast.ParenExpr:
+		return check.typExpr(e.X, def, path)
+
+	case *ast.ArrayType:
+		if e.Len != nil {
+			typ := new(Array)
+			def.setUnderlying(typ)
+			typ.len = check.arrayLength(e.Len)
+			typ.elem = check.typExpr(e.Elt, nil, path)
+			return typ
+
+		} else {
+			typ := new(Slice)
+			def.setUnderlying(typ)
+			typ.elem = check.typ(e.Elt)
+			return typ
+		}
+
+	case *ast.StructType:
+		typ := new(Struct)
+		def.setUnderlying(typ)
+		check.structType(typ, e, path)
+		return typ
+
+	case *ast.StarExpr:
+		typ := new(Pointer)
+		def.setUnderlying(typ)
+		typ.base = check.typ(e.X)
+		return typ
+
+	case *ast.FuncType:
+		typ := new(Signature)
+		def.setUnderlying(typ)
+		check.funcType(typ, nil, e)
+		return typ
+
+	case *ast.InterfaceType:
+		typ := new(Interface)
+		def.setUnderlying(typ)
+		check.interfaceType(typ, e, def, path)
+		return typ
+
+	case *ast.MapType:
+		typ := new(Map)
+		def.setUnderlying(typ)
+
+		typ.key = check.typ(e.Key)
+		typ.elem = check.typ(e.Value)
+
+		// spec: "The comparison operators == and != must be fully defined
+		// for operands of the key type; thus the key type must not be a
+		// function, map, or slice."
+		//
+		// Delay this check because it requires fully setup types;
+		// it is safe to continue in any case (was issue 6667).
+		check.delay(func() {
+			if !Comparable(typ.key) {
+				check.errorf(e.Key.Pos(), "invalid map key type %s", typ.key)
+			}
+		})
+
+		return typ
+
+	case *ast.ChanType:
+		typ := new(Chan)
+		def.setUnderlying(typ)
+
+		dir := SendRecv
+		switch e.Dir {
+		case ast.SEND | ast.RECV:
+			// nothing to do
+		case ast.SEND:
+			dir = SendOnly
+		case ast.RECV:
+			dir = RecvOnly
+		default:
+			check.invalidAST(e.Pos(), "unknown channel direction %d", e.Dir)
+			// ok to continue
+		}
+
+		typ.dir = dir
+		typ.elem = check.typ(e.Value)
+		return typ
+
+	default:
+		check.errorf(e.Pos(), "%s is not a type", e)
+	}
+
+	typ := Typ[Invalid]
+	def.setUnderlying(typ)
+	return typ
+}
+
+// typeOrNil type-checks the type expression (or nil value) e
+// and returns the typ of e, or nil.
+// If e is neither a type nor nil, typOrNil returns Typ[Invalid].
+//
+func (check *Checker) typOrNil(e ast.Expr) Type {
+	var x operand
+	check.rawExpr(&x, e, nil)
+	switch x.mode {
+	case invalid:
+		// ignore - error reported before
+	case novalue:
+		check.errorf(x.pos(), "%s used as type", &x)
+	case typexpr:
+		return x.typ
+	case value:
+		if x.isNil() {
+			return nil
+		}
+		fallthrough
+	default:
+		check.errorf(x.pos(), "%s is not a type", &x)
+	}
+	return Typ[Invalid]
+}
+
+func (check *Checker) arrayLength(e ast.Expr) int64 {
+	var x operand
+	check.expr(&x, e)
+	if x.mode != constant_ {
+		if x.mode != invalid {
+			check.errorf(x.pos(), "array length %s must be constant", &x)
+		}
+		return 0
+	}
+	if !x.isInteger() {
+		check.errorf(x.pos(), "array length %s must be integer", &x)
+		return 0
+	}
+	n, ok := constant.Int64Val(x.val)
+	if !ok || n < 0 {
+		check.errorf(x.pos(), "invalid array length %s", &x)
+		return 0
+	}
+	return n
+}
+
+func (check *Checker) collectParams(scope *Scope, list *ast.FieldList, variadicOk bool) (params []*Var, variadic bool) {
+	if list == nil {
+		return
+	}
+
+	var named, anonymous bool
+	for i, field := range list.List {
+		ftype := field.Type
+		if t, _ := ftype.(*ast.Ellipsis); t != nil {
+			ftype = t.Elt
+			if variadicOk && i == len(list.List)-1 {
+				variadic = true
+			} else {
+				check.invalidAST(field.Pos(), "... not permitted")
+				// ignore ... and continue
+			}
+		}
+		typ := check.typ(ftype)
+		// The parser ensures that f.Tag is nil and we don't
+		// care if a constructed AST contains a non-nil tag.
+		if len(field.Names) > 0 {
+			// named parameter
+			for _, name := range field.Names {
+				if name.Name == "" {
+					check.invalidAST(name.Pos(), "anonymous parameter")
+					// ok to continue
+				}
+				par := NewParam(name.Pos(), check.pkg, name.Name, typ)
+				check.declare(scope, name, par, scope.pos)
+				params = append(params, par)
+			}
+			named = true
+		} else {
+			// anonymous parameter
+			par := NewParam(ftype.Pos(), check.pkg, "", typ)
+			check.recordImplicit(field, par)
+			params = append(params, par)
+			anonymous = true
+		}
+	}
+
+	if named && anonymous {
+		check.invalidAST(list.Pos(), "list contains both named and anonymous parameters")
+		// ok to continue
+	}
+
+	// For a variadic function, change the last parameter's type from T to []T.
+	if variadic && len(params) > 0 {
+		last := params[len(params)-1]
+		last.typ = &Slice{elem: last.typ}
+	}
+
+	return
+}
+
+func (check *Checker) declareInSet(oset *objset, pos token.Pos, obj Object) bool {
+	if alt := oset.insert(obj); alt != nil {
+		check.errorf(pos, "%s redeclared", obj.Name())
+		check.reportAltDecl(alt)
+		return false
+	}
+	return true
+}
+
+func (check *Checker) interfaceType(iface *Interface, ityp *ast.InterfaceType, def *Named, path []*TypeName) {
+	// empty interface: common case
+	if ityp.Methods == nil {
+		return
+	}
+
+	// The parser ensures that field tags are nil and we don't
+	// care if a constructed AST contains non-nil tags.
+
+	// use named receiver type if available (for better error messages)
+	var recvTyp Type = iface
+	if def != nil {
+		recvTyp = def
+	}
+
+	// Phase 1: Collect explicitly declared methods, the corresponding
+	//          signature (AST) expressions, and the list of embedded
+	//          type (AST) expressions. Do not resolve signatures or
+	//          embedded types yet to avoid cycles referring to this
+	//          interface.
+
+	var (
+		mset       objset
+		signatures []ast.Expr // list of corresponding method signatures
+		embedded   []ast.Expr // list of embedded types
+	)
+	for _, f := range ityp.Methods.List {
+		if len(f.Names) > 0 {
+			// The parser ensures that there's only one method
+			// and we don't care if a constructed AST has more.
+			name := f.Names[0]
+			pos := name.Pos()
+			// spec: "As with all method sets, in an interface type,
+			// each method must have a unique non-blank name."
+			if name.Name == "_" {
+				check.errorf(pos, "invalid method name _")
+				continue
+			}
+			// Don't type-check signature yet - use an
+			// empty signature now and update it later.
+			// Since we know the receiver, set it up now
+			// (required to avoid crash in ptrRecv; see
+			// e.g. test case for issue 6638).
+			// TODO(gri) Consider marking methods signatures
+			// as incomplete, for better error messages. See
+			// also the T4 and T5 tests in testdata/cycles2.src.
+			sig := new(Signature)
+			sig.recv = NewVar(pos, check.pkg, "", recvTyp)
+			m := NewFunc(pos, check.pkg, name.Name, sig)
+			if check.declareInSet(&mset, pos, m) {
+				iface.methods = append(iface.methods, m)
+				iface.allMethods = append(iface.allMethods, m)
+				signatures = append(signatures, f.Type)
+				check.recordDef(name, m)
+			}
+		} else {
+			// embedded type
+			embedded = append(embedded, f.Type)
+		}
+	}
+
+	// Phase 2: Resolve embedded interfaces. Because an interface must not
+	//          embed itself (directly or indirectly), each embedded interface
+	//          can be fully resolved without depending on any method of this
+	//          interface (if there is a cycle or another error, the embedded
+	//          type resolves to an invalid type and is ignored).
+	//          In particular, the list of methods for each embedded interface
+	//          must be complete (it cannot depend on this interface), and so
+	//          those methods can be added to the list of all methods of this
+	//          interface.
+
+	for _, e := range embedded {
+		pos := e.Pos()
+		typ := check.typExpr(e, nil, path)
+		// Determine underlying embedded (possibly incomplete) type
+		// by following its forward chain.
+		named, _ := typ.(*Named)
+		under := underlying(named)
+		embed, _ := under.(*Interface)
+		if embed == nil {
+			if typ != Typ[Invalid] {
+				check.errorf(pos, "%s is not an interface", typ)
+			}
+			continue
+		}
+		iface.embeddeds = append(iface.embeddeds, named)
+		// collect embedded methods
+		for _, m := range embed.allMethods {
+			if check.declareInSet(&mset, pos, m) {
+				iface.allMethods = append(iface.allMethods, m)
+			}
+		}
+	}
+
+	// Phase 3: At this point all methods have been collected for this interface.
+	//          It is now safe to type-check the signatures of all explicitly
+	//          declared methods, even if they refer to this interface via a cycle
+	//          and embed the methods of this interface in a parameter of interface
+	//          type.
+
+	for i, m := range iface.methods {
+		expr := signatures[i]
+		typ := check.typ(expr)
+		sig, _ := typ.(*Signature)
+		if sig == nil {
+			if typ != Typ[Invalid] {
+				check.invalidAST(expr.Pos(), "%s is not a method signature", typ)
+			}
+			continue // keep method with empty method signature
+		}
+		// update signature, but keep recv that was set up before
+		old := m.typ.(*Signature)
+		sig.recv = old.recv
+		*old = *sig // update signature (don't replace it!)
+	}
+
+	// TODO(gri) The list of explicit methods is only sorted for now to
+	// produce the same Interface as NewInterface. We may be able to
+	// claim source order in the future. Revisit.
+	sort.Sort(byUniqueMethodName(iface.methods))
+
+	// TODO(gri) The list of embedded types is only sorted for now to
+	// produce the same Interface as NewInterface. We may be able to
+	// claim source order in the future. Revisit.
+	sort.Sort(byUniqueTypeName(iface.embeddeds))
+
+	sort.Sort(byUniqueMethodName(iface.allMethods))
+}
+
+// byUniqueTypeName named type lists can be sorted by their unique type names.
+type byUniqueTypeName []*Named
+
+func (a byUniqueTypeName) Len() int           { return len(a) }
+func (a byUniqueTypeName) Less(i, j int) bool { return a[i].obj.Id() < a[j].obj.Id() }
+func (a byUniqueTypeName) Swap(i, j int)      { a[i], a[j] = a[j], a[i] }
+
+// byUniqueMethodName method lists can be sorted by their unique method names.
+type byUniqueMethodName []*Func
+
+func (a byUniqueMethodName) Len() int           { return len(a) }
+func (a byUniqueMethodName) Less(i, j int) bool { return a[i].Id() < a[j].Id() }
+func (a byUniqueMethodName) Swap(i, j int)      { a[i], a[j] = a[j], a[i] }
+
+func (check *Checker) tag(t *ast.BasicLit) string {
+	if t != nil {
+		if t.Kind == token.STRING {
+			if val, err := strconv.Unquote(t.Value); err == nil {
+				return val
+			}
+		}
+		check.invalidAST(t.Pos(), "incorrect tag syntax: %q", t.Value)
+	}
+	return ""
+}
+
+func (check *Checker) structType(styp *Struct, e *ast.StructType, path []*TypeName) {
+	list := e.Fields
+	if list == nil {
+		return
+	}
+
+	// struct fields and tags
+	var fields []*Var
+	var tags []string
+
+	// for double-declaration checks
+	var fset objset
+
+	// current field typ and tag
+	var typ Type
+	var tag string
+	// anonymous != nil indicates an anonymous field.
+	add := func(field *ast.Field, ident *ast.Ident, anonymous *TypeName, pos token.Pos) {
+		if tag != "" && tags == nil {
+			tags = make([]string, len(fields))
+		}
+		if tags != nil {
+			tags = append(tags, tag)
+		}
+
+		name := ident.Name
+		fld := NewField(pos, check.pkg, name, typ, anonymous != nil)
+		// spec: "Within a struct, non-blank field names must be unique."
+		if name == "_" || check.declareInSet(&fset, pos, fld) {
+			fields = append(fields, fld)
+			check.recordDef(ident, fld)
+		}
+		if anonymous != nil {
+			check.recordUse(ident, anonymous)
+		}
+	}
+
+	for _, f := range list.List {
+		typ = check.typExpr(f.Type, nil, path)
+		tag = check.tag(f.Tag)
+		if len(f.Names) > 0 {
+			// named fields
+			for _, name := range f.Names {
+				add(f, name, nil, name.Pos())
+			}
+		} else {
+			// anonymous field
+			name := anonymousFieldIdent(f.Type)
+			pos := f.Type.Pos()
+			t, isPtr := deref(typ)
+			switch t := t.(type) {
+			case *Basic:
+				if t == Typ[Invalid] {
+					// error was reported before
+					continue
+				}
+				// unsafe.Pointer is treated like a regular pointer
+				if t.kind == UnsafePointer {
+					check.errorf(pos, "anonymous field type cannot be unsafe.Pointer")
+					continue
+				}
+				add(f, name, Universe.Lookup(t.name).(*TypeName), pos)
+
+			case *Named:
+				// spec: "An embedded type must be specified as a type name
+				// T or as a pointer to a non-interface type name *T, and T
+				// itself may not be a pointer type."
+				switch u := t.underlying.(type) {
+				case *Basic:
+					// unsafe.Pointer is treated like a regular pointer
+					if u.kind == UnsafePointer {
+						check.errorf(pos, "anonymous field type cannot be unsafe.Pointer")
+						continue
+					}
+				case *Pointer:
+					check.errorf(pos, "anonymous field type cannot be a pointer")
+					continue
+				case *Interface:
+					if isPtr {
+						check.errorf(pos, "anonymous field type cannot be a pointer to an interface")
+						continue
+					}
+				}
+				add(f, name, t.obj, pos)
+
+			default:
+				check.invalidAST(pos, "anonymous field type %s must be named", typ)
+			}
+		}
+	}
+
+	styp.fields = fields
+	styp.tags = tags
+}
+
+func anonymousFieldIdent(e ast.Expr) *ast.Ident {
+	switch e := e.(type) {
+	case *ast.Ident:
+		return e
+	case *ast.StarExpr:
+		return anonymousFieldIdent(e.X)
+	case *ast.SelectorExpr:
+		return e.Sel
+	}
+	return nil // invalid anonymous field
+}
diff --git a/third_party/gofrontend/libgo/go/go/types/universe.go b/third_party/gofrontend/libgo/go/go/types/universe.go
new file mode 100644
index 0000000..40185c1
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/go/types/universe.go
@@ -0,0 +1,223 @@
+// Copyright 2011 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.
+
+// This file sets up the universe scope and the unsafe package.
+
+package types
+
+import (
+	"go/constant"
+	"go/token"
+	"strings"
+)
+
+var (
+	Universe     *Scope
+	Unsafe       *Package
+	universeIota *Const
+	universeByte *Basic // uint8 alias, but has name "byte"
+	universeRune *Basic // int32 alias, but has name "rune"
+)
+
+var Typ = []*Basic{
+	Invalid: {Invalid, 0, "invalid type"},
+
+	Bool:          {Bool, IsBoolean, "bool"},
+	Int:           {Int, IsInteger, "int"},
+	Int8:          {Int8, IsInteger, "int8"},
+	Int16:         {Int16, IsInteger, "int16"},
+	Int32:         {Int32, IsInteger, "int32"},
+	Int64:         {Int64, IsInteger, "int64"},
+	Uint:          {Uint, IsInteger | IsUnsigned, "uint"},
+	Uint8:         {Uint8, IsInteger | IsUnsigned, "uint8"},
+	Uint16:        {Uint16, IsInteger | IsUnsigned, "uint16"},
+	Uint32:        {Uint32, IsInteger | IsUnsigned, "uint32"},
+	Uint64:        {Uint64, IsInteger | IsUnsigned, "uint64"},
+	Uintptr:       {Uintptr, IsInteger | IsUnsigned, "uintptr"},
+	Float32:       {Float32, IsFloat, "float32"},
+	Float64:       {Float64, IsFloat, "float64"},
+	Complex64:     {Complex64, IsComplex, "complex64"},
+	Complex128:    {Complex128, IsComplex, "complex128"},
+	String:        {String, IsString, "string"},
+	UnsafePointer: {UnsafePointer, 0, "Pointer"},
+
+	UntypedBool:    {UntypedBool, IsBoolean | IsUntyped, "untyped bool"},
+	UntypedInt:     {UntypedInt, IsInteger | IsUntyped, "untyped int"},
+	UntypedRune:    {UntypedRune, IsInteger | IsUntyped, "untyped rune"},
+	UntypedFloat:   {UntypedFloat, IsFloat | IsUntyped, "untyped float"},
+	UntypedComplex: {UntypedComplex, IsComplex | IsUntyped, "untyped complex"},
+	UntypedString:  {UntypedString, IsString | IsUntyped, "untyped string"},
+	UntypedNil:     {UntypedNil, IsUntyped, "untyped nil"},
+}
+
+var aliases = [...]*Basic{
+	{Byte, IsInteger | IsUnsigned, "byte"},
+	{Rune, IsInteger, "rune"},
+}
+
+func defPredeclaredTypes() {
+	for _, t := range Typ {
+		def(NewTypeName(token.NoPos, nil, t.name, t))
+	}
+	for _, t := range aliases {
+		def(NewTypeName(token.NoPos, nil, t.name, t))
+	}
+
+	// Error has a nil package in its qualified name since it is in no package
+	res := NewVar(token.NoPos, nil, "", Typ[String])
+	sig := &Signature{results: NewTuple(res)}
+	err := NewFunc(token.NoPos, nil, "Error", sig)
+	typ := &Named{underlying: NewInterface([]*Func{err}, nil).Complete()}
+	sig.recv = NewVar(token.NoPos, nil, "", typ)
+	def(NewTypeName(token.NoPos, nil, "error", typ))
+}
+
+var predeclaredConsts = [...]struct {
+	name string
+	kind BasicKind
+	val  constant.Value
+}{
+	{"true", UntypedBool, constant.MakeBool(true)},
+	{"false", UntypedBool, constant.MakeBool(false)},
+	{"iota", UntypedInt, constant.MakeInt64(0)},
+}
+
+func defPredeclaredConsts() {
+	for _, c := range predeclaredConsts {
+		def(NewConst(token.NoPos, nil, c.name, Typ[c.kind], c.val))
+	}
+}
+
+func defPredeclaredNil() {
+	def(&Nil{object{name: "nil", typ: Typ[UntypedNil]}})
+}
+
+// A builtinId is the id of a builtin function.
+type builtinId int
+
+const (
+	// universe scope
+	_Append builtinId = iota
+	_Cap
+	_Close
+	_Complex
+	_Copy
+	_Delete
+	_Imag
+	_Len
+	_Make
+	_New
+	_Panic
+	_Print
+	_Println
+	_Real
+	_Recover
+
+	// package unsafe
+	_Alignof
+	_Offsetof
+	_Sizeof
+
+	// testing support
+	_Assert
+	_Trace
+)
+
+var predeclaredFuncs = [...]struct {
+	name     string
+	nargs    int
+	variadic bool
+	kind     exprKind
+}{
+	_Append:  {"append", 1, true, expression},
+	_Cap:     {"cap", 1, false, expression},
+	_Close:   {"close", 1, false, statement},
+	_Complex: {"complex", 2, false, expression},
+	_Copy:    {"copy", 2, false, statement},
+	_Delete:  {"delete", 2, false, statement},
+	_Imag:    {"imag", 1, false, expression},
+	_Len:     {"len", 1, false, expression},
+	_Make:    {"make", 1, true, expression},
+	_New:     {"new", 1, false, expression},
+	_Panic:   {"panic", 1, false, statement},
+	_Print:   {"print", 0, true, statement},
+	_Println: {"println", 0, true, statement},
+	_Real:    {"real", 1, false, expression},
+	_Recover: {"recover", 0, false, statement},
+
+	_Alignof:  {"Alignof", 1, false, expression},
+	_Offsetof: {"Offsetof", 1, false, expression},
+	_Sizeof:   {"Sizeof", 1, false, expression},
+
+	_Assert: {"assert", 1, false, statement},
+	_Trace:  {"trace", 0, true, statement},
+}
+
+func defPredeclaredFuncs() {
+	for i := range predeclaredFuncs {
+		id := builtinId(i)
+		if id == _Assert || id == _Trace {
+			continue // only define these in testing environment
+		}
+		def(newBuiltin(id))
+	}
+}
+
+// DefPredeclaredTestFuncs defines the assert and trace built-ins.
+// These built-ins are intended for debugging and testing of this
+// package only.
+func DefPredeclaredTestFuncs() {
+	if Universe.Lookup("assert") != nil {
+		return // already defined
+	}
+	def(newBuiltin(_Assert))
+	def(newBuiltin(_Trace))
+}
+
+func init() {
+	Universe = NewScope(nil, token.NoPos, token.NoPos, "universe")
+	Unsafe = NewPackage("unsafe", "unsafe")
+	Unsafe.complete = true
+
+	defPredeclaredTypes()
+	defPredeclaredConsts()
+	defPredeclaredNil()
+	defPredeclaredFuncs()
+
+	universeIota = Universe.Lookup("iota").(*Const)
+	universeByte = Universe.Lookup("byte").(*TypeName).typ.(*Basic)
+	universeRune = Universe.Lookup("rune").(*TypeName).typ.(*Basic)
+}
+
+// Objects with names containing blanks are internal and not entered into
+// a scope. Objects with exported names are inserted in the unsafe package
+// scope; other objects are inserted in the universe scope.
+//
+func def(obj Object) {
+	name := obj.Name()
+	if strings.Index(name, " ") >= 0 {
+		return // nothing to do
+	}
+	// fix Obj link for named types
+	if typ, ok := obj.Type().(*Named); ok {
+		typ.obj = obj.(*TypeName)
+	}
+	// exported identifiers go into package unsafe
+	scope := Universe
+	if obj.Exported() {
+		scope = Unsafe.scope
+		// set Pkg field
+		switch obj := obj.(type) {
+		case *TypeName:
+			obj.pkg = Unsafe
+		case *Builtin:
+			obj.pkg = Unsafe
+		default:
+			unreachable()
+		}
+	}
+	if scope.Insert(obj) != nil {
+		panic("internal error: double declaration")
+	}
+}
diff --git a/third_party/gofrontend/libgo/go/hash/crc32/crc32.go b/third_party/gofrontend/libgo/go/hash/crc32/crc32.go
index 6a6b947..234d929 100644
--- a/third_party/gofrontend/libgo/go/hash/crc32/crc32.go
+++ b/third_party/gofrontend/libgo/go/hash/crc32/crc32.go
@@ -5,6 +5,11 @@
 // Package crc32 implements the 32-bit cyclic redundancy check, or CRC-32,
 // checksum. See http://en.wikipedia.org/wiki/Cyclic_redundancy_check for
 // information.
+//
+// Polynomials are represented in LSB-first form also known as reversed representation.
+//
+// See http://en.wikipedia.org/wiki/Mathematics_of_cyclic_redundancy_checks#Reversed_representations_and_reciprocal_polynomials
+// for information.
 package crc32
 
 import (
@@ -49,6 +54,13 @@
 // IEEETable is the table for the IEEE polynomial.
 var IEEETable = makeTable(IEEE)
 
+// slicing8Table is array of 8 Tables
+type slicing8Table [8]Table
+
+// iEEETable8 is the slicing8Table for IEEE
+var iEEETable8 *slicing8Table
+var iEEETable8Once sync.Once
+
 // MakeTable returns the Table constructed from the specified polynomial.
 func MakeTable(poly uint32) *Table {
 	switch poly {
@@ -78,6 +90,20 @@
 	return t
 }
 
+// makeTable8 returns slicing8Table constructed from the specified polynomial.
+func makeTable8(poly uint32) *slicing8Table {
+	t := new(slicing8Table)
+	t[0] = *makeTable(poly)
+	for i := 0; i < 256; i++ {
+		crc := t[0][i]
+		for j := 1; j < 8; j++ {
+			crc = t[0][crc&0xFF] ^ (crc >> 8)
+			t[j][i] = crc
+		}
+	}
+	return t
+}
+
 // digest represents the partial evaluation of a checksum.
 type digest struct {
 	crc uint32
@@ -106,11 +132,32 @@
 	return ^crc
 }
 
+// updateSlicingBy8 updates CRC using Slicing-by-8
+func updateSlicingBy8(crc uint32, tab *slicing8Table, p []byte) uint32 {
+	crc = ^crc
+	for len(p) > 8 {
+		crc ^= uint32(p[0]) | uint32(p[1])<<8 | uint32(p[2])<<16 | uint32(p[3])<<24
+		crc = tab[0][p[7]] ^ tab[1][p[6]] ^ tab[2][p[5]] ^ tab[3][p[4]] ^
+			tab[4][crc>>24] ^ tab[5][(crc>>16)&0xFF] ^
+			tab[6][(crc>>8)&0xFF] ^ tab[7][crc&0xFF]
+		p = p[8:]
+	}
+	crc = ^crc
+	return update(crc, &tab[0], p)
+}
+
 // Update returns the result of adding the bytes in p to the crc.
 func Update(crc uint32, tab *Table, p []byte) uint32 {
 	if tab == castagnoliTable {
 		return updateCastagnoli(crc, p)
 	}
+	// only use slicing-by-8 when input is larger than 4KB
+	if tab == IEEETable && len(p) >= 4096 {
+		iEEETable8Once.Do(func() {
+			iEEETable8 = makeTable8(IEEE)
+		})
+		return updateSlicingBy8(crc, iEEETable8, p)
+	}
 	return update(crc, tab, p)
 }
 
@@ -132,4 +179,4 @@
 
 // ChecksumIEEE returns the CRC-32 checksum of data
 // using the IEEE polynomial.
-func ChecksumIEEE(data []byte) uint32 { return update(0, IEEETable, data) }
+func ChecksumIEEE(data []byte) uint32 { return Update(0, IEEETable, data) }
diff --git a/third_party/gofrontend/libgo/go/hash/crc32/crc32_generic.go b/third_party/gofrontend/libgo/go/hash/crc32/crc32_generic.go
index c3fdcd6..416c1b7 100644
--- a/third_party/gofrontend/libgo/go/hash/crc32/crc32_generic.go
+++ b/third_party/gofrontend/libgo/go/hash/crc32/crc32_generic.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 386 arm
+// +build 386 arm arm64 ppc64 ppc64le
 
 package crc32
 
diff --git a/third_party/gofrontend/libgo/go/hash/crc32/crc32_test.go b/third_party/gofrontend/libgo/go/hash/crc32/crc32_test.go
index 75dc26e..1ca3ac2 100644
--- a/third_party/gofrontend/libgo/go/hash/crc32/crc32_test.go
+++ b/third_party/gofrontend/libgo/go/hash/crc32/crc32_test.go
@@ -81,7 +81,7 @@
 	}
 }
 
-func BenchmarkCrc32KB(b *testing.B) {
+func BenchmarkIEEECrc1KB(b *testing.B) {
 	b.SetBytes(1024)
 	data := make([]byte, 1024)
 	for i := range data {
@@ -97,3 +97,37 @@
 		h.Sum(in)
 	}
 }
+
+func BenchmarkIEEECrc4KB(b *testing.B) {
+	b.SetBytes(4096)
+	data := make([]byte, 4096)
+	for i := range data {
+		data[i] = byte(i)
+	}
+	h := NewIEEE()
+	in := make([]byte, 0, h.Size())
+
+	b.ResetTimer()
+	for i := 0; i < b.N; i++ {
+		h.Reset()
+		h.Write(data)
+		h.Sum(in)
+	}
+}
+
+func BenchmarkCastagnoliCrc1KB(b *testing.B) {
+	b.SetBytes(1024)
+	data := make([]byte, 1024)
+	for i := range data {
+		data[i] = byte(i)
+	}
+	h := New(MakeTable(Castagnoli))
+	in := make([]byte, 0, h.Size())
+
+	b.ResetTimer()
+	for i := 0; i < b.N; i++ {
+		h.Reset()
+		h.Write(data)
+		h.Sum(in)
+	}
+}
diff --git a/third_party/gofrontend/libgo/go/hash/crc32/example_test.go b/third_party/gofrontend/libgo/go/hash/crc32/example_test.go
new file mode 100644
index 0000000..a1d9e16
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/hash/crc32/example_test.go
@@ -0,0 +1,30 @@
+// 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 ignore
+
+package crc32_test
+
+import (
+	"fmt"
+	"hash/crc32"
+)
+
+func ExampleMakeTable() {
+	// In this package, the CRC polynomial is represented in reversed notation,
+	// or LSB-first representation.
+	//
+	// LSB-first representation is a hexadecimal number with n bits, in which the
+	// most significant bit represents the coefficient of x⁰ and the least significant
+	// bit represents the coefficient of xⁿ⁻¹ (the coefficient for xⁿ is implicit).
+	//
+	// For example, CRC32-Q, as defined by the following polynomial,
+	//	x³²+ x³¹+ x²⁴+ x²²+ x¹⁶+ x¹⁴+ x⁸+ x⁷+ x⁵+ x³+ x¹+ x⁰
+	// has the reversed notation 0b11010101100000101000001010000001, so the value
+	// that should be passed to MakeTable is 0xD5828281.
+	crc32q := crc32.MakeTable(0xD5828281)
+	fmt.Printf("%08x\n", crc32.Checksum([]byte("Hello world"), crc32q))
+	// Output:
+	// 2964d064
+}
diff --git a/third_party/gofrontend/libgo/go/html/escape.go b/third_party/gofrontend/libgo/go/html/escape.go
index dd5dfa7..f50a4b9 100644
--- a/third_party/gofrontend/libgo/go/html/escape.go
+++ b/third_party/gofrontend/libgo/go/html/escape.go
@@ -6,7 +6,6 @@
 package html
 
 import (
-	"bytes"
 	"strings"
 	"unicode/utf8"
 )
@@ -187,52 +186,20 @@
 	return b
 }
 
-const escapedChars = `&'<>"`
-
-func escape(w writer, s string) error {
-	i := strings.IndexAny(s, escapedChars)
-	for i != -1 {
-		if _, err := w.WriteString(s[:i]); err != nil {
-			return err
-		}
-		var esc string
-		switch s[i] {
-		case '&':
-			esc = "&amp;"
-		case '\'':
-			// "&#39;" is shorter than "&apos;" and apos was not in HTML until HTML5.
-			esc = "&#39;"
-		case '<':
-			esc = "&lt;"
-		case '>':
-			esc = "&gt;"
-		case '"':
-			// "&#34;" is shorter than "&quot;".
-			esc = "&#34;"
-		default:
-			panic("unrecognized escape character")
-		}
-		s = s[i+1:]
-		if _, err := w.WriteString(esc); err != nil {
-			return err
-		}
-		i = strings.IndexAny(s, escapedChars)
-	}
-	_, err := w.WriteString(s)
-	return err
-}
+var htmlEscaper = strings.NewReplacer(
+	`&`, "&amp;",
+	`'`, "&#39;", // "&#39;" is shorter than "&apos;" and apos was not in HTML until HTML5.
+	`<`, "&lt;",
+	`>`, "&gt;",
+	`"`, "&#34;", // "&#34;" is shorter than "&quot;".
+)
 
 // EscapeString escapes special characters like "<" to become "&lt;". It
 // escapes only five such characters: <, >, &, ' and ".
 // UnescapeString(EscapeString(s)) == s always holds, but the converse isn't
 // always true.
 func EscapeString(s string) string {
-	if strings.IndexAny(s, escapedChars) == -1 {
-		return s
-	}
-	var buf bytes.Buffer
-	escape(&buf, s)
-	return buf.String()
+	return htmlEscaper.Replace(s)
 }
 
 // UnescapeString unescapes entities like "&lt;" to become "<". It unescapes a
@@ -241,10 +208,8 @@
 // UnescapeString(EscapeString(s)) == s always holds, but the converse isn't
 // always true.
 func UnescapeString(s string) string {
-	for _, c := range s {
-		if c == '&' {
-			return string(unescape([]byte(s)))
-		}
+	if !strings.Contains(s, "&") {
+		return s
 	}
-	return s
+	return string(unescape([]byte(s)))
 }
diff --git a/third_party/gofrontend/libgo/go/html/escape_test.go b/third_party/gofrontend/libgo/go/html/escape_test.go
index 2d7ad8a..3702626 100644
--- a/third_party/gofrontend/libgo/go/html/escape_test.go
+++ b/third_party/gofrontend/libgo/go/html/escape_test.go
@@ -4,7 +4,10 @@
 
 package html
 
-import "testing"
+import (
+	"strings"
+	"testing"
+)
 
 type unescapeTest struct {
 	// A short description of the test case.
@@ -113,3 +116,38 @@
 		}
 	}
 }
+
+var (
+	benchEscapeData = strings.Repeat("AAAAA < BBBBB > CCCCC & DDDDD ' EEEEE \" ", 100)
+	benchEscapeNone = strings.Repeat("AAAAA x BBBBB x CCCCC x DDDDD x EEEEE x ", 100)
+)
+
+func BenchmarkEscape(b *testing.B) {
+	n := 0
+	for i := 0; i < b.N; i++ {
+		n += len(EscapeString(benchEscapeData))
+	}
+}
+
+func BenchmarkEscapeNone(b *testing.B) {
+	n := 0
+	for i := 0; i < b.N; i++ {
+		n += len(EscapeString(benchEscapeNone))
+	}
+}
+
+func BenchmarkUnescape(b *testing.B) {
+	s := EscapeString(benchEscapeData)
+	n := 0
+	for i := 0; i < b.N; i++ {
+		n += len(UnescapeString(s))
+	}
+}
+
+func BenchmarkUnescapeNone(b *testing.B) {
+	s := EscapeString(benchEscapeNone)
+	n := 0
+	for i := 0; i < b.N; i++ {
+		n += len(UnescapeString(s))
+	}
+}
diff --git a/third_party/gofrontend/libgo/go/html/example_test.go b/third_party/gofrontend/libgo/go/html/example_test.go
new file mode 100644
index 0000000..d0f0a9b
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/html/example_test.go
@@ -0,0 +1,24 @@
+// 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 ignore
+
+package html_test
+
+import (
+	"fmt"
+	"html"
+)
+
+func ExampleEscapeString() {
+	const s = `"Fran & Freddie's Diner" <tasty@example.com>`
+	fmt.Println(html.EscapeString(s))
+	// Output: &#34;Fran &amp; Freddie&#39;s Diner&#34; &lt;tasty@example.com&gt;
+}
+
+func ExampleUnescapeString() {
+	const s = `&quot;Fran &amp; Freddie&#39;s Diner&quot; &lt;tasty@example.com&gt;`
+	fmt.Println(html.UnescapeString(s))
+	// Output: "Fran & Freddie's Diner" <tasty@example.com>
+}
diff --git a/third_party/gofrontend/libgo/go/html/template/clone_test.go b/third_party/gofrontend/libgo/go/html/template/clone_test.go
index e11bff2..c89d22a 100644
--- a/third_party/gofrontend/libgo/go/html/template/clone_test.go
+++ b/third_party/gofrontend/libgo/go/html/template/clone_test.go
@@ -142,7 +142,7 @@
 	}
 }
 
-// This used to crash; http://golang.org/issue/3281
+// This used to crash; https://golang.org/issue/3281
 func TestCloneCrash(t *testing.T) {
 	t1 := New("all")
 	Must(t1.New("t1").Parse(`{{define "foo"}}foo{{end}}`))
@@ -166,7 +166,7 @@
 	}
 }
 
-// https://code.google.com/p/go/issues/detail?id=5980
+// https://golang.org/issue/5980
 func TestFuncMapWorksAfterClone(t *testing.T) {
 	funcs := FuncMap{"customFunc": func() (string, error) {
 		return "", errors.New("issue5980")
diff --git a/third_party/gofrontend/libgo/go/html/template/content_test.go b/third_party/gofrontend/libgo/go/html/template/content_test.go
index 5f3ffe2..e698328 100644
--- a/third_party/gofrontend/libgo/go/html/template/content_test.go
+++ b/third_party/gofrontend/libgo/go/html/template/content_test.go
@@ -260,7 +260,7 @@
 	}
 }
 
-// https://code.google.com/p/go/issues/detail?id=5982
+// https://golang.org/issue/5982
 func TestEscapingNilNonemptyInterfaces(t *testing.T) {
 	tmpl := Must(New("x").Parse("{{.E}}"))
 
diff --git a/third_party/gofrontend/libgo/go/html/template/css.go b/third_party/gofrontend/libgo/go/html/template/css.go
index 634f183..3184648 100644
--- a/third_party/gofrontend/libgo/go/html/template/css.go
+++ b/third_party/gofrontend/libgo/go/html/template/css.go
@@ -157,56 +157,20 @@
 func cssEscaper(args ...interface{}) string {
 	s, _ := stringify(args...)
 	var b bytes.Buffer
-	written := 0
-	for i, r := range s {
+	r, w, written := rune(0), 0, 0
+	for i := 0; i < len(s); i += w {
+		// See comment in htmlEscaper.
+		r, w = utf8.DecodeRuneInString(s[i:])
 		var repl string
-		switch r {
-		case 0:
-			repl = `\0`
-		case '\t':
-			repl = `\9`
-		case '\n':
-			repl = `\a`
-		case '\f':
-			repl = `\c`
-		case '\r':
-			repl = `\d`
-		// Encode HTML specials as hex so the output can be embedded
-		// in HTML attributes without further encoding.
-		case '"':
-			repl = `\22`
-		case '&':
-			repl = `\26`
-		case '\'':
-			repl = `\27`
-		case '(':
-			repl = `\28`
-		case ')':
-			repl = `\29`
-		case '+':
-			repl = `\2b`
-		case '/':
-			repl = `\2f`
-		case ':':
-			repl = `\3a`
-		case ';':
-			repl = `\3b`
-		case '<':
-			repl = `\3c`
-		case '>':
-			repl = `\3e`
-		case '\\':
-			repl = `\\`
-		case '{':
-			repl = `\7b`
-		case '}':
-			repl = `\7d`
+		switch {
+		case int(r) < len(cssReplacementTable) && cssReplacementTable[r] != "":
+			repl = cssReplacementTable[r]
 		default:
 			continue
 		}
 		b.WriteString(s[written:i])
 		b.WriteString(repl)
-		written = i + utf8.RuneLen(r)
+		written = i + w
 		if repl != `\\` && (written == len(s) || isHex(s[written]) || isCSSSpace(s[written])) {
 			b.WriteByte(' ')
 		}
@@ -218,6 +182,30 @@
 	return b.String()
 }
 
+var cssReplacementTable = []string{
+	0:    `\0`,
+	'\t': `\9`,
+	'\n': `\a`,
+	'\f': `\c`,
+	'\r': `\d`,
+	// Encode HTML specials as hex so the output can be embedded
+	// in HTML attributes without further encoding.
+	'"':  `\22`,
+	'&':  `\26`,
+	'\'': `\27`,
+	'(':  `\28`,
+	')':  `\29`,
+	'+':  `\2b`,
+	'/':  `\2f`,
+	':':  `\3a`,
+	';':  `\3b`,
+	'<':  `\3c`,
+	'>':  `\3e`,
+	'\\': `\\`,
+	'{':  `\7b`,
+	'}':  `\7d`,
+}
+
 var expressionBytes = []byte("expression")
 var mozBindingBytes = []byte("mozbinding")
 
diff --git a/third_party/gofrontend/libgo/go/html/template/doc.go b/third_party/gofrontend/libgo/go/html/template/doc.go
index d422ada..1827403 100644
--- a/third_party/gofrontend/libgo/go/html/template/doc.go
+++ b/third_party/gofrontend/libgo/go/html/template/doc.go
@@ -151,7 +151,7 @@
 
 can be invoked with
 
-  tmpl.Execute(out, HTML(`<b>World</b>`))
+  tmpl.Execute(out, template.HTML(`<b>World</b>`))
 
 to produce
 
diff --git a/third_party/gofrontend/libgo/go/html/template/escape.go b/third_party/gofrontend/libgo/go/html/template/escape.go
index ee01fb1..3c18340 100644
--- a/third_party/gofrontend/libgo/go/html/template/escape.go
+++ b/third_party/gofrontend/libgo/go/html/template/escape.go
@@ -205,15 +205,17 @@
 }
 
 // allIdents returns the names of the identifiers under the Ident field of the node,
-// which might be a singleton (Identifier) or a slice (Field).
+// which might be a singleton (Identifier) or a slice (Field or Chain).
 func allIdents(node parse.Node) []string {
 	switch node := node.(type) {
 	case *parse.IdentifierNode:
 		return []string{node.Ident}
 	case *parse.FieldNode:
 		return node.Ident
+	case *parse.ChainNode:
+		return node.Field
 	}
-	panic("unidentified node type in allIdents")
+	return nil
 }
 
 // ensurePipelineContains ensures that the pipeline has commands with
@@ -297,9 +299,9 @@
 // unless it is redundant with the last command.
 func appendCmd(cmds []*parse.CommandNode, cmd *parse.CommandNode) []*parse.CommandNode {
 	if n := len(cmds); n != 0 {
-		last, ok := cmds[n-1].Args[0].(*parse.IdentifierNode)
-		next, _ := cmd.Args[0].(*parse.IdentifierNode)
-		if ok && redundantFuncs[last.Ident][next.Ident] {
+		last, okLast := cmds[n-1].Args[0].(*parse.IdentifierNode)
+		next, okNext := cmd.Args[0].(*parse.IdentifierNode)
+		if okLast && okNext && redundantFuncs[last.Ident][next.Ident] {
 			return cmds
 		}
 	}
diff --git a/third_party/gofrontend/libgo/go/html/template/escape_test.go b/third_party/gofrontend/libgo/go/html/template/escape_test.go
index ef7b877..bea2d13 100644
--- a/third_party/gofrontend/libgo/go/html/template/escape_test.go
+++ b/third_party/gofrontend/libgo/go/html/template/escape_test.go
@@ -1547,6 +1547,28 @@
 			"($).X | urlquery | html | print",
 			[]string{"urlquery", "html"},
 		},
+		{
+			"{{.X | print 2 | .f 3}}",
+			".X | print 2 | .f 3 | urlquery | html",
+			[]string{"urlquery", "html"},
+		},
+		{
+			"{{.X | html | print 2 | .f 3}}",
+			".X | urlquery | html | print 2 | .f 3",
+			[]string{"urlquery", "html"},
+		},
+		{
+			// covering issue 10801
+			"{{.X | js.x }}",
+			".X | js.x | urlquery | html",
+			[]string{"urlquery", "html"},
+		},
+		{
+			// covering issue 10801
+			"{{.X | (print 12 | js).x }}",
+			".X | (print 12 | js).x | urlquery | html",
+			[]string{"urlquery", "html"},
+		},
 	}
 	for i, test := range tests {
 		tmpl := template.Must(template.New("test").Parse(test.input))
@@ -1564,6 +1586,28 @@
 	}
 }
 
+func TestEscapeMalformedPipelines(t *testing.T) {
+	tests := []string{
+		"{{ 0 | $ }}",
+		"{{ 0 | $ | urlquery }}",
+		"{{ 0 | $ | urlquery | html }}",
+		"{{ 0 | (nil) }}",
+		"{{ 0 | (nil) | html }}",
+		"{{ 0 | (nil) | html | urlquery }}",
+	}
+	for _, test := range tests {
+		var b bytes.Buffer
+		tmpl, err := New("test").Parse(test)
+		if err != nil {
+			t.Errorf("failed to parse set: %q", err)
+		}
+		err = tmpl.Execute(&b, nil)
+		if err == nil {
+			t.Errorf("Expected error for %q", test)
+		}
+	}
+}
+
 func TestEscapeErrorsNotIgnorable(t *testing.T) {
 	var b bytes.Buffer
 	tmpl, _ := New("dangerous").Parse("<a")
@@ -1686,6 +1730,21 @@
 	}
 }
 
+// Unlike text/template, html/template crashed if given an incomplete
+// template, that is, a template that had been named but not given any content.
+// This is issue #10204.
+func TestErrorOnUndefined(t *testing.T) {
+	tmpl := New("undefined")
+
+	err := tmpl.Execute(nil, nil)
+	if err == nil {
+		t.Error("expected error")
+	}
+	if !strings.Contains(err.Error(), "incomplete") {
+		t.Errorf("expected error about incomplete template; got %s", err)
+	}
+}
+
 func BenchmarkEscapedExecute(b *testing.B) {
 	tmpl := Must(New("t").Parse(`<a onclick="alert('{{.}}')">{{.}}</a>`))
 	var buf bytes.Buffer
diff --git a/third_party/gofrontend/libgo/go/html/template/example_test.go b/third_party/gofrontend/libgo/go/html/template/example_test.go
new file mode 100644
index 0000000..3ea3dca
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/html/template/example_test.go
@@ -0,0 +1,124 @@
+// 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 ignore
+
+package template_test
+
+import (
+	"fmt"
+	"html/template"
+	"log"
+	"os"
+)
+
+func Example() {
+	const tpl = `
+<!DOCTYPE html>
+<html>
+	<head>
+		<meta charset="UTF-8">
+		<title>{{.Title}}</title>
+	</head>
+	<body>
+		{{range .Items}}<div>{{ . }}</div>{{else}}<div><strong>no rows</strong></div>{{end}}
+	</body>
+</html>`
+
+	check := func(err error) {
+		if err != nil {
+			log.Fatal(err)
+		}
+	}
+	t, err := template.New("webpage").Parse(tpl)
+
+	data := struct {
+		Title string
+		Items []string
+	}{
+		Title: "My page",
+		Items: []string{
+			"My photos",
+			"My blog",
+		},
+	}
+
+	err = t.Execute(os.Stdout, data)
+	check(err)
+
+	noItems := struct {
+		Title string
+		Items []string
+	}{
+		Title: "My another page",
+		Items: []string{},
+	}
+
+	err = t.Execute(os.Stdout, noItems)
+	check(err)
+
+	// Output:
+	// <!DOCTYPE html>
+	// <html>
+	// 	<head>
+	// 		<meta charset="UTF-8">
+	// 		<title>My page</title>
+	// 	</head>
+	// 	<body>
+	// 		<div>My photos</div><div>My blog</div>
+	// 	</body>
+	// </html>
+	// <!DOCTYPE html>
+	// <html>
+	// 	<head>
+	// 		<meta charset="UTF-8">
+	// 		<title>My another page</title>
+	// 	</head>
+	// 	<body>
+	// 		<div><strong>no rows</strong></div>
+	// 	</body>
+	// </html>
+
+}
+
+func Example_autoescaping() {
+	check := func(err error) {
+		if err != nil {
+			log.Fatal(err)
+		}
+	}
+	t, err := template.New("foo").Parse(`{{define "T"}}Hello, {{.}}!{{end}}`)
+	check(err)
+	err = t.ExecuteTemplate(os.Stdout, "T", "<script>alert('you have been pwned')</script>")
+	check(err)
+	// Output:
+	// Hello, &lt;script&gt;alert(&#39;you have been pwned&#39;)&lt;/script&gt;!
+}
+
+func Example_escape() {
+	const s = `"Fran & Freddie's Diner" <tasty@example.com>`
+	v := []interface{}{`"Fran & Freddie's Diner"`, ' ', `<tasty@example.com>`}
+
+	fmt.Println(template.HTMLEscapeString(s))
+	template.HTMLEscape(os.Stdout, []byte(s))
+	fmt.Fprintln(os.Stdout, "")
+	fmt.Println(template.HTMLEscaper(v...))
+
+	fmt.Println(template.JSEscapeString(s))
+	template.JSEscape(os.Stdout, []byte(s))
+	fmt.Fprintln(os.Stdout, "")
+	fmt.Println(template.JSEscaper(v...))
+
+	fmt.Println(template.URLQueryEscaper(v...))
+
+	// Output:
+	// &#34;Fran &amp; Freddie&#39;s Diner&#34; &lt;tasty@example.com&gt;
+	// &#34;Fran &amp; Freddie&#39;s Diner&#34; &lt;tasty@example.com&gt;
+	// &#34;Fran &amp; Freddie&#39;s Diner&#34;32&lt;tasty@example.com&gt;
+	// \"Fran & Freddie\'s Diner\" \x3Ctasty@example.com\x3E
+	// \"Fran & Freddie\'s Diner\" \x3Ctasty@example.com\x3E
+	// \"Fran & Freddie\'s Diner\"32\x3Ctasty@example.com\x3E
+	// %22Fran+%26+Freddie%27s+Diner%2232%3Ctasty%40example.com%3E
+
+}
diff --git a/third_party/gofrontend/libgo/go/html/template/html.go b/third_party/gofrontend/libgo/go/html/template/html.go
index 9c069ef..de4aa4a 100644
--- a/third_party/gofrontend/libgo/go/html/template/html.go
+++ b/third_party/gofrontend/libgo/go/html/template/html.go
@@ -138,21 +138,24 @@
 // and when badRunes is true, certain bad runes are allowed through unescaped.
 func htmlReplacer(s string, replacementTable []string, badRunes bool) string {
 	written, b := 0, new(bytes.Buffer)
-	for i, r := range s {
+	r, w := rune(0), 0
+	for i := 0; i < len(s); i += w {
+		// Cannot use 'for range s' because we need to preserve the width
+		// of the runes in the input. If we see a decoding error, the input
+		// width will not be utf8.Runelen(r) and we will overrun the buffer.
+		r, w = utf8.DecodeRuneInString(s[i:])
 		if int(r) < len(replacementTable) {
 			if repl := replacementTable[r]; len(repl) != 0 {
 				b.WriteString(s[written:i])
 				b.WriteString(repl)
-				// Valid as long as replacementTable doesn't
-				// include anything above 0x7f.
-				written = i + utf8.RuneLen(r)
+				written = i + w
 			}
 		} else if badRunes {
 			// No-op.
 			// IE does not allow these ranges in unquoted attrs.
 		} else if 0xfdd0 <= r && r <= 0xfdef || 0xfff0 <= r && r <= 0xffff {
 			fmt.Fprintf(b, "%s&#x%x;", s[written:i], r)
-			written = i + utf8.RuneLen(r)
+			written = i + w
 		}
 	}
 	if written == 0 {
diff --git a/third_party/gofrontend/libgo/go/html/template/html_test.go b/third_party/gofrontend/libgo/go/html/template/html_test.go
index b9b9703..f04ee04 100644
--- a/third_party/gofrontend/libgo/go/html/template/html_test.go
+++ b/third_party/gofrontend/libgo/go/html/template/html_test.go
@@ -19,7 +19,8 @@
 		`PQRSTUVWXYZ[\]^_` +
 		"`abcdefghijklmno" +
 		"pqrstuvwxyz{|}~\x7f" +
-		"\u00A0\u0100\u2028\u2029\ufeff\ufdec\U0001D11E")
+		"\u00A0\u0100\u2028\u2029\ufeff\ufdec\U0001D11E" +
+		"erroneous\x960") // keep at the end
 
 	want := ("&#xfffd;\x01\x02\x03\x04\x05\x06\x07" +
 		"\x08&#9;&#10;&#11;&#12;&#13;\x0E\x0F" +
@@ -31,14 +32,16 @@
 		`PQRSTUVWXYZ[\]^_` +
 		`&#96;abcdefghijklmno` +
 		`pqrstuvwxyz{|}~` + "\u007f" +
-		"\u00A0\u0100\u2028\u2029\ufeff&#xfdec;\U0001D11E")
+		"\u00A0\u0100\u2028\u2029\ufeff&#xfdec;\U0001D11E" +
+		"erroneous&#xfffd;0") // keep at the end
 
 	got := htmlNospaceEscaper(input)
 	if got != want {
 		t.Errorf("encode: want\n\t%q\nbut got\n\t%q", want, got)
 	}
 
-	got, want = html.UnescapeString(got), strings.Replace(input, "\x00", "\ufffd", 1)
+	r := strings.NewReplacer("\x00", "\ufffd", "\x96", "\ufffd")
+	got, want = html.UnescapeString(got), r.Replace(input)
 	if want != got {
 		t.Errorf("decode: want\n\t%q\nbut got\n\t%q", want, got)
 	}
diff --git a/third_party/gofrontend/libgo/go/html/template/js.go b/third_party/gofrontend/libgo/go/html/template/js.go
index 999a61e..f6d166b 100644
--- a/third_party/gofrontend/libgo/go/html/template/js.go
+++ b/third_party/gofrontend/libgo/go/html/template/js.go
@@ -246,8 +246,10 @@
 // `\u2029`.
 func replace(s string, replacementTable []string) string {
 	var b bytes.Buffer
-	written := 0
-	for i, r := range s {
+	r, w, written := rune(0), 0, 0
+	for i := 0; i < len(s); i += w {
+		// See comment in htmlEscaper.
+		r, w = utf8.DecodeRuneInString(s[i:])
 		var repl string
 		switch {
 		case int(r) < len(replacementTable) && replacementTable[r] != "":
@@ -261,7 +263,7 @@
 		}
 		b.WriteString(s[written:i])
 		b.WriteString(repl)
-		written = i + utf8.RuneLen(r)
+		written = i + w
 	}
 	if written == 0 {
 		return s
diff --git a/third_party/gofrontend/libgo/go/html/template/template.go b/third_party/gofrontend/libgo/go/html/template/template.go
index ce61701..bb9140a 100644
--- a/third_party/gofrontend/libgo/go/html/template/template.go
+++ b/third_party/gofrontend/libgo/go/html/template/template.go
@@ -51,11 +51,37 @@
 	return m
 }
 
+// Option sets options for the template. Options are described by
+// strings, either a simple string or "key=value". There can be at
+// most one equals sign in an option string. If the option string
+// is unrecognized or otherwise invalid, Option panics.
+//
+// Known options:
+//
+// missingkey: Control the behavior during execution if a map is
+// indexed with a key that is not present in the map.
+//	"missingkey=default" or "missingkey=invalid"
+//		The default behavior: Do nothing and continue execution.
+//		If printed, the result of the index operation is the string
+//		"<no value>".
+//	"missingkey=zero"
+//		The operation returns the zero value for the map type's element.
+//	"missingkey=error"
+//		Execution stops immediately with an error.
+//
+func (t *Template) Option(opt ...string) *Template {
+	t.text.Option(opt...)
+	return t
+}
+
 // escape escapes all associated templates.
 func (t *Template) escape() error {
 	t.nameSpace.mu.Lock()
 	defer t.nameSpace.mu.Unlock()
 	if t.escapeErr == nil {
+		if t.Tree == nil {
+			return fmt.Errorf("template: %q is an incomplete or empty template%s", t.Name(), t.text.DefinedTemplates())
+		}
 		if err := escapeTemplate(t, t.text.Root, t.Name()); err != nil {
 			return err
 		}
diff --git a/third_party/gofrontend/libgo/go/html/template/transition.go b/third_party/gofrontend/libgo/go/html/template/transition.go
index b486fcd..d2e0287 100644
--- a/third_party/gofrontend/libgo/go/html/template/transition.go
+++ b/third_party/gofrontend/libgo/go/html/template/transition.go
@@ -183,24 +183,54 @@
 
 // specialTagEndMarkers maps element types to the character sequence that
 // case-insensitively signals the end of the special tag body.
-var specialTagEndMarkers = [...]string{
-	elementScript:   "</script",
-	elementStyle:    "</style",
-	elementTextarea: "</textarea",
-	elementTitle:    "</title",
+var specialTagEndMarkers = [...][]byte{
+	elementScript:   []byte("script"),
+	elementStyle:    []byte("style"),
+	elementTextarea: []byte("textarea"),
+	elementTitle:    []byte("title"),
 }
 
+var (
+	specialTagEndPrefix = []byte("</")
+	tagEndSeparators    = []byte("> \t\n\f/")
+)
+
 // tSpecialTagEnd is the context transition function for raw text and RCDATA
 // element states.
 func tSpecialTagEnd(c context, s []byte) (context, int) {
 	if c.element != elementNone {
-		if i := strings.Index(strings.ToLower(string(s)), specialTagEndMarkers[c.element]); i != -1 {
+		if i := indexTagEnd(s, specialTagEndMarkers[c.element]); i != -1 {
 			return context{}, i
 		}
 	}
 	return c, len(s)
 }
 
+// indexTagEnd finds the index of a special tag end in a case insensitive way, or returns -1
+func indexTagEnd(s []byte, tag []byte) int {
+	res := 0
+	plen := len(specialTagEndPrefix)
+	for len(s) > 0 {
+		// Try to find the tag end prefix first
+		i := bytes.Index(s, specialTagEndPrefix)
+		if i == -1 {
+			return i
+		}
+		s = s[i+plen:]
+		// Try to match the actual tag if there is still space for it
+		if len(tag) <= len(s) && bytes.EqualFold(tag, s[:len(tag)]) {
+			s = s[len(tag):]
+			// Check the tag is followed by a proper separator
+			if len(s) > 0 && bytes.IndexByte(tagEndSeparators, s[0]) != -1 {
+				return res + i
+			}
+			res += len(tag)
+		}
+		res += i + plen
+	}
+	return -1
+}
+
 // tAttr is the context transition function for the attribute state.
 func tAttr(c context, s []byte) (context, int) {
 	return c, len(s)
diff --git a/third_party/gofrontend/libgo/go/html/template/transition_test.go b/third_party/gofrontend/libgo/go/html/template/transition_test.go
new file mode 100644
index 0000000..412a4c7
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/html/template/transition_test.go
@@ -0,0 +1,60 @@
+// Copyright 2011 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 template
+
+import (
+	"bytes"
+	"strings"
+	"testing"
+)
+
+func TestFindEndTag(t *testing.T) {
+	tests := []struct {
+		s, tag string
+		want   int
+	}{
+		{"", "tag", -1},
+		{"hello </textarea> hello", "textarea", 6},
+		{"hello </TEXTarea> hello", "textarea", 6},
+		{"hello </textAREA>", "textarea", 6},
+		{"hello </textarea", "textareax", -1},
+		{"hello </textarea>", "tag", -1},
+		{"hello tag </textarea", "tag", -1},
+		{"hello </tag> </other> </textarea> <other>", "textarea", 22},
+		{"</textarea> <other>", "textarea", 0},
+		{"<div> </div> </TEXTAREA>", "textarea", 13},
+		{"<div> </div> </TEXTAREA\t>", "textarea", 13},
+		{"<div> </div> </TEXTAREA >", "textarea", 13},
+		{"<div> </div> </TEXTAREAfoo", "textarea", -1},
+		{"</TEXTAREAfoo </textarea>", "textarea", 14},
+		{"<</script >", "script", 1},
+		{"</script>", "textarea", -1},
+	}
+	for _, test := range tests {
+		if got := indexTagEnd([]byte(test.s), []byte(test.tag)); test.want != got {
+			t.Errorf("%q/%q: want\n\t%d\nbut got\n\t%d", test.s, test.tag, test.want, got)
+		}
+	}
+}
+
+func BenchmarkTemplateSpecialTags(b *testing.B) {
+
+	r := struct {
+		Name, Gift string
+	}{"Aunt Mildred", "bone china tea set"}
+
+	h1 := "<textarea> Hello Hello Hello </textarea> "
+	h2 := "<textarea> <p> Dear {{.Name}},\n{{with .Gift}}Thank you for the lovely {{.}}. {{end}}\nBest wishes. </p>\n</textarea>"
+	html := strings.Repeat(h1, 100) + h2 + strings.Repeat(h1, 100) + h2
+
+	var buf bytes.Buffer
+	for i := 0; i < b.N; i++ {
+		tmpl := Must(New("foo").Parse(html))
+		if err := tmpl.Execute(&buf, r); err != nil {
+			b.Fatal(err)
+		}
+		buf.Reset()
+	}
+}
diff --git a/third_party/gofrontend/libgo/go/image/color/color.go b/third_party/gofrontend/libgo/go/image/color/color.go
index ff596a7..cae059b 100644
--- a/third_party/gofrontend/libgo/go/image/color/color.go
+++ b/third_party/gofrontend/libgo/go/image/color/color.go
@@ -9,14 +9,20 @@
 // The conversion may be lossy.
 type Color interface {
 	// RGBA returns the alpha-premultiplied red, green, blue and alpha values
-	// for the color. Each value ranges within [0, 0xFFFF], but is represented
-	// by a uint32 so that multiplying by a blend factor up to 0xFFFF will not
+	// for the color. Each value ranges within [0, 0xffff], but is represented
+	// by a uint32 so that multiplying by a blend factor up to 0xffff will not
 	// overflow.
+	//
+	// An alpha-premultiplied color component c has been scaled by alpha (a),
+	// so has valid values 0 <= c <= a.
 	RGBA() (r, g, b, a uint32)
 }
 
-// RGBA represents a traditional 32-bit alpha-premultiplied color,
-// having 8 bits for each of red, green, blue and alpha.
+// RGBA represents a traditional 32-bit alpha-premultiplied color, having 8
+// bits for each of red, green, blue and alpha.
+//
+// An alpha-premultiplied color component C has been scaled by alpha (A), so
+// has valid values 0 <= C <= A.
 type RGBA struct {
 	R, G, B, A uint8
 }
@@ -33,8 +39,11 @@
 	return
 }
 
-// RGBA64 represents a 64-bit alpha-premultiplied color,
-// having 16 bits for each of red, green, blue and alpha.
+// RGBA64 represents a 64-bit alpha-premultiplied color, having 16 bits for
+// each of red, green, blue and alpha.
+//
+// An alpha-premultiplied color component C has been scaled by alpha (A), so
+// has valid values 0 <= C <= A.
 type RGBA64 struct {
 	R, G, B, A uint16
 }
@@ -262,32 +271,39 @@
 }
 
 // Index returns the index of the palette color closest to c in Euclidean
-// R,G,B space.
+// R,G,B,A space.
 func (p Palette) Index(c Color) int {
 	// A batch version of this computation is in image/draw/draw.go.
 
-	cr, cg, cb, _ := c.RGBA()
-	ret, bestSSD := 0, uint32(1<<32-1)
+	cr, cg, cb, ca := c.RGBA()
+	ret, bestSum := 0, uint32(1<<32-1)
 	for i, v := range p {
-		vr, vg, vb, _ := v.RGBA()
-		// We shift by 1 bit to avoid potential uint32 overflow in
-		// sum-squared-difference.
-		delta := (int32(cr) - int32(vr)) >> 1
-		ssd := uint32(delta * delta)
-		delta = (int32(cg) - int32(vg)) >> 1
-		ssd += uint32(delta * delta)
-		delta = (int32(cb) - int32(vb)) >> 1
-		ssd += uint32(delta * delta)
-		if ssd < bestSSD {
-			if ssd == 0 {
+		vr, vg, vb, va := v.RGBA()
+		sum := sqDiff(cr, vr) + sqDiff(cg, vg) + sqDiff(cb, vb) + sqDiff(ca, va)
+		if sum < bestSum {
+			if sum == 0 {
 				return i
 			}
-			ret, bestSSD = i, ssd
+			ret, bestSum = i, sum
 		}
 	}
 	return ret
 }
 
+// sqDiff returns the squared-difference of x and y, shifted by 2 so that
+// adding four of those won't overflow a uint32.
+//
+// x and y are both assumed to be in the range [0, 0xffff].
+func sqDiff(x, y uint32) uint32 {
+	var d uint32
+	if x > y {
+		d = x - y
+	} else {
+		d = y - x
+	}
+	return (d * d) >> 2
+}
+
 // Standard colors.
 var (
 	Black       = Gray16{0}
diff --git a/third_party/gofrontend/libgo/go/image/color/ycbcr.go b/third_party/gofrontend/libgo/go/image/color/ycbcr.go
index 4c2f29e..4bcb07d 100644
--- a/third_party/gofrontend/libgo/go/image/color/ycbcr.go
+++ b/third_party/gofrontend/libgo/go/image/color/ycbcr.go
@@ -11,26 +11,27 @@
 	//	Cb = -0.1687*R - 0.3313*G + 0.5000*B + 128
 	//	Cr =  0.5000*R - 0.4187*G - 0.0813*B + 128
 	// http://www.w3.org/Graphics/JPEG/jfif3.pdf says Y but means Y'.
-	r1 := int(r)
-	g1 := int(g)
-	b1 := int(b)
+
+	r1 := int32(r)
+	g1 := int32(g)
+	b1 := int32(b)
 	yy := (19595*r1 + 38470*g1 + 7471*b1 + 1<<15) >> 16
 	cb := (-11056*r1 - 21712*g1 + 32768*b1 + 257<<15) >> 16
 	cr := (32768*r1 - 27440*g1 - 5328*b1 + 257<<15) >> 16
 	if yy < 0 {
 		yy = 0
-	} else if yy > 255 {
-		yy = 255
+	} else if yy > 0xff {
+		yy = 0xff
 	}
 	if cb < 0 {
 		cb = 0
-	} else if cb > 255 {
-		cb = 255
+	} else if cb > 0xff {
+		cb = 0xff
 	}
 	if cr < 0 {
 		cr = 0
-	} else if cr > 255 {
-		cr = 255
+	} else if cr > 0xff {
+		cr = 0xff
 	}
 	return uint8(yy), uint8(cb), uint8(cr)
 }
@@ -42,26 +43,27 @@
 	//	G = Y' - 0.34414*(Cb-128) - 0.71414*(Cr-128)
 	//	B = Y' + 1.77200*(Cb-128)
 	// http://www.w3.org/Graphics/JPEG/jfif3.pdf says Y but means Y'.
-	yy1 := int(y)<<16 + 1<<15
-	cb1 := int(cb) - 128
-	cr1 := int(cr) - 128
+
+	yy1 := int32(y) * 0x10100 // Convert 0x12 to 0x121200.
+	cb1 := int32(cb) - 128
+	cr1 := int32(cr) - 128
 	r := (yy1 + 91881*cr1) >> 16
 	g := (yy1 - 22554*cb1 - 46802*cr1) >> 16
 	b := (yy1 + 116130*cb1) >> 16
 	if r < 0 {
 		r = 0
-	} else if r > 255 {
-		r = 255
+	} else if r > 0xff {
+		r = 0xff
 	}
 	if g < 0 {
 		g = 0
-	} else if g > 255 {
-		g = 255
+	} else if g > 0xff {
+		g = 0xff
 	}
 	if b < 0 {
 		b = 0
-	} else if b > 255 {
-		b = 255
+	} else if b > 0xff {
+		b = 0xff
 	}
 	return uint8(r), uint8(g), uint8(b)
 }
@@ -82,8 +84,45 @@
 }
 
 func (c YCbCr) RGBA() (uint32, uint32, uint32, uint32) {
-	r, g, b := YCbCrToRGB(c.Y, c.Cb, c.Cr)
-	return uint32(r) * 0x101, uint32(g) * 0x101, uint32(b) * 0x101, 0xffff
+	// This code is a copy of the YCbCrToRGB function above, except that it
+	// returns values in the range [0, 0xffff] instead of [0, 0xff]. There is a
+	// subtle difference between doing this and having YCbCr satisfy the Color
+	// interface by first converting to an RGBA. The latter loses some
+	// information by going to and from 8 bits per channel.
+	//
+	// For example, this code:
+	//	const y, cb, cr = 0x7f, 0x7f, 0x7f
+	//	r, g, b := color.YCbCrToRGB(y, cb, cr)
+	//	r0, g0, b0, _ := color.YCbCr{y, cb, cr}.RGBA()
+	//	r1, g1, b1, _ := color.RGBA{r, g, b, 0xff}.RGBA()
+	//	fmt.Printf("0x%04x 0x%04x 0x%04x\n", r0, g0, b0)
+	//	fmt.Printf("0x%04x 0x%04x 0x%04x\n", r1, g1, b1)
+	// prints:
+	//	0x7e18 0x808e 0x7db9
+	//	0x7e7e 0x8080 0x7d7d
+
+	yy1 := int32(c.Y) * 0x10100 // Convert 0x12 to 0x121200.
+	cb1 := int32(c.Cb) - 128
+	cr1 := int32(c.Cr) - 128
+	r := (yy1 + 91881*cr1) >> 8
+	g := (yy1 - 22554*cb1 - 46802*cr1) >> 8
+	b := (yy1 + 116130*cb1) >> 8
+	if r < 0 {
+		r = 0
+	} else if r > 0xffff {
+		r = 0xffff
+	}
+	if g < 0 {
+		g = 0
+	} else if g > 0xffff {
+		g = 0xffff
+	}
+	if b < 0 {
+		b = 0
+	} else if b > 0xffff {
+		b = 0xffff
+	}
+	return uint32(r), uint32(g), uint32(b), 0xffff
 }
 
 // YCbCrModel is the Model for Y'CbCr colors.
@@ -97,3 +136,64 @@
 	y, u, v := RGBToYCbCr(uint8(r>>8), uint8(g>>8), uint8(b>>8))
 	return YCbCr{y, u, v}
 }
+
+// RGBToCMYK converts an RGB triple to a CMYK quadruple.
+func RGBToCMYK(r, g, b uint8) (uint8, uint8, uint8, uint8) {
+	rr := uint32(r)
+	gg := uint32(g)
+	bb := uint32(b)
+	w := rr
+	if w < gg {
+		w = gg
+	}
+	if w < bb {
+		w = bb
+	}
+	if w == 0 {
+		return 0, 0, 0, 0xff
+	}
+	c := (w - rr) * 0xff / w
+	m := (w - gg) * 0xff / w
+	y := (w - bb) * 0xff / w
+	return uint8(c), uint8(m), uint8(y), uint8(0xff - w)
+}
+
+// CMYKToRGB converts a CMYK quadruple to an RGB triple.
+func CMYKToRGB(c, m, y, k uint8) (uint8, uint8, uint8) {
+	w := uint32(0xffff - uint32(k)*0x101)
+	r := uint32(0xffff-uint32(c)*0x101) * w / 0xffff
+	g := uint32(0xffff-uint32(m)*0x101) * w / 0xffff
+	b := uint32(0xffff-uint32(y)*0x101) * w / 0xffff
+	return uint8(r >> 8), uint8(g >> 8), uint8(b >> 8)
+}
+
+// CMYK represents a fully opaque CMYK color, having 8 bits for each of cyan,
+// magenta, yellow and black.
+//
+// It is not associated with any particular color profile.
+type CMYK struct {
+	C, M, Y, K uint8
+}
+
+func (c CMYK) RGBA() (uint32, uint32, uint32, uint32) {
+	// This code is a copy of the CMYKToRGB function above, except that it
+	// returns values in the range [0, 0xffff] instead of [0, 0xff].
+
+	w := uint32(0xffff - uint32(c.K)*0x101)
+	r := uint32(0xffff-uint32(c.C)*0x101) * w / 0xffff
+	g := uint32(0xffff-uint32(c.M)*0x101) * w / 0xffff
+	b := uint32(0xffff-uint32(c.Y)*0x101) * w / 0xffff
+	return uint32(r), uint32(g), uint32(b), 0xffff
+}
+
+// CMYKModel is the Model for CMYK colors.
+var CMYKModel Model = ModelFunc(cmykModel)
+
+func cmykModel(c Color) Color {
+	if _, ok := c.(CMYK); ok {
+		return c
+	}
+	r, g, b, _ := c.RGBA()
+	cc, mm, yy, kk := RGBToCMYK(uint8(r>>8), uint8(g>>8), uint8(b>>8))
+	return CMYK{cc, mm, yy, kk}
+}
diff --git a/third_party/gofrontend/libgo/go/image/color/ycbcr_test.go b/third_party/gofrontend/libgo/go/image/color/ycbcr_test.go
index 92a0e6f..5da49d3 100644
--- a/third_party/gofrontend/libgo/go/image/color/ycbcr_test.go
+++ b/third_party/gofrontend/libgo/go/image/color/ycbcr_test.go
@@ -5,6 +5,7 @@
 package color
 
 import (
+	"fmt"
 	"testing"
 )
 
@@ -15,19 +16,134 @@
 	return y - x
 }
 
-// Test that a subset of RGB space can be converted to YCbCr and back to within
-// 1/256 tolerance.
-func TestRoundtrip(t *testing.T) {
-	for r := 0; r < 255; r += 7 {
-		for g := 0; g < 255; g += 5 {
-			for b := 0; b < 255; b += 3 {
+func eq(c0, c1 Color) error {
+	r0, g0, b0, a0 := c0.RGBA()
+	r1, g1, b1, a1 := c1.RGBA()
+	if r0 != r1 || g0 != g1 || b0 != b1 || a0 != a1 {
+		return fmt.Errorf("got  0x%04x 0x%04x 0x%04x 0x%04x\nwant 0x%04x 0x%04x 0x%04x 0x%04x",
+			r0, g0, b0, a0, r1, g1, b1, a1)
+	}
+	return nil
+}
+
+// TestYCbCrRoundtrip tests that a subset of RGB space can be converted to YCbCr
+// and back to within 2/256 tolerance.
+func TestYCbCrRoundtrip(t *testing.T) {
+	for r := 0; r < 256; r += 7 {
+		for g := 0; g < 256; g += 5 {
+			for b := 0; b < 256; b += 3 {
 				r0, g0, b0 := uint8(r), uint8(g), uint8(b)
 				y, cb, cr := RGBToYCbCr(r0, g0, b0)
 				r1, g1, b1 := YCbCrToRGB(y, cb, cr)
-				if delta(r0, r1) > 1 || delta(g0, g1) > 1 || delta(b0, b1) > 1 {
-					t.Fatalf("r0, g0, b0 = %d, %d, %d   r1, g1, b1 = %d, %d, %d", r0, g0, b0, r1, g1, b1)
+				if delta(r0, r1) > 2 || delta(g0, g1) > 2 || delta(b0, b1) > 2 {
+					t.Fatalf("\nr0, g0, b0 = %d, %d, %d\ny,  cb, cr = %d, %d, %d\nr1, g1, b1 = %d, %d, %d",
+						r0, g0, b0, y, cb, cr, r1, g1, b1)
 				}
 			}
 		}
 	}
 }
+
+// TestYCbCrToRGBConsistency tests that calling the RGBA method (16 bit color)
+// then truncating to 8 bits is equivalent to calling the YCbCrToRGB function (8
+// bit color).
+func TestYCbCrToRGBConsistency(t *testing.T) {
+	for y := 0; y < 256; y += 7 {
+		for cb := 0; cb < 256; cb += 5 {
+			for cr := 0; cr < 256; cr += 3 {
+				x := YCbCr{uint8(y), uint8(cb), uint8(cr)}
+				r0, g0, b0, _ := x.RGBA()
+				r1, g1, b1 := uint8(r0>>8), uint8(g0>>8), uint8(b0>>8)
+				r2, g2, b2 := YCbCrToRGB(x.Y, x.Cb, x.Cr)
+				if r1 != r2 || g1 != g2 || b1 != b2 {
+					t.Fatalf("y, cb, cr = %d, %d, %d\nr1, g1, b1 = %d, %d, %d\nr2, g2, b2 = %d, %d, %d",
+						y, cb, cr, r1, g1, b1, r2, g2, b2)
+				}
+			}
+		}
+	}
+}
+
+// TestYCbCrGray tests that YCbCr colors are a superset of Gray colors.
+func TestYCbCrGray(t *testing.T) {
+	for i := 0; i < 256; i++ {
+		if err := eq(YCbCr{uint8(i), 0x80, 0x80}, Gray{uint8(i)}); err != nil {
+			t.Errorf("i=0x%02x:\n%v", i, err)
+		}
+	}
+}
+
+// TestCMYKRoundtrip tests that a subset of RGB space can be converted to CMYK
+// and back to within 1/256 tolerance.
+func TestCMYKRoundtrip(t *testing.T) {
+	for r := 0; r < 256; r += 7 {
+		for g := 0; g < 256; g += 5 {
+			for b := 0; b < 256; b += 3 {
+				r0, g0, b0 := uint8(r), uint8(g), uint8(b)
+				c, m, y, k := RGBToCMYK(r0, g0, b0)
+				r1, g1, b1 := CMYKToRGB(c, m, y, k)
+				if delta(r0, r1) > 1 || delta(g0, g1) > 1 || delta(b0, b1) > 1 {
+					t.Fatalf("\nr0, g0, b0 = %d, %d, %d\nc, m, y, k = %d, %d, %d, %d\nr1, g1, b1 = %d, %d, %d",
+						r0, g0, b0, c, m, y, k, r1, g1, b1)
+				}
+			}
+		}
+	}
+}
+
+// TestCMYKToRGBConsistency tests that calling the RGBA method (16 bit color)
+// then truncating to 8 bits is equivalent to calling the CMYKToRGB function (8
+// bit color).
+func TestCMYKToRGBConsistency(t *testing.T) {
+	for c := 0; c < 256; c += 7 {
+		for m := 0; m < 256; m += 5 {
+			for y := 0; y < 256; y += 3 {
+				for k := 0; k < 256; k += 11 {
+					x := CMYK{uint8(c), uint8(m), uint8(y), uint8(k)}
+					r0, g0, b0, _ := x.RGBA()
+					r1, g1, b1 := uint8(r0>>8), uint8(g0>>8), uint8(b0>>8)
+					r2, g2, b2 := CMYKToRGB(x.C, x.M, x.Y, x.K)
+					if r1 != r2 || g1 != g2 || b1 != b2 {
+						t.Fatalf("c, m, y, k = %d, %d, %d, %d\nr1, g1, b1 = %d, %d, %d\nr2, g2, b2 = %d, %d, %d",
+							c, m, y, k, r1, g1, b1, r2, g2, b2)
+					}
+				}
+			}
+		}
+	}
+}
+
+// TestCMYKGray tests that CMYK colors are a superset of Gray colors.
+func TestCMYKGray(t *testing.T) {
+	for i := 0; i < 256; i++ {
+		if err := eq(CMYK{0x00, 0x00, 0x00, uint8(255 - i)}, Gray{uint8(i)}); err != nil {
+			t.Errorf("i=0x%02x:\n%v", i, err)
+		}
+	}
+}
+
+func TestPalette(t *testing.T) {
+	p := Palette{
+		RGBA{0xff, 0xff, 0xff, 0xff},
+		RGBA{0x80, 0x00, 0x00, 0xff},
+		RGBA{0x7f, 0x00, 0x00, 0x7f},
+		RGBA{0x00, 0x00, 0x00, 0x7f},
+		RGBA{0x00, 0x00, 0x00, 0x00},
+		RGBA{0x40, 0x40, 0x40, 0x40},
+	}
+	// Check that, for a Palette with no repeated colors, the closest color to
+	// each element is itself.
+	for i, c := range p {
+		j := p.Index(c)
+		if i != j {
+			t.Errorf("Index(%v): got %d (color = %v), want %d", c, j, p[j], i)
+		}
+	}
+	// Check that finding the closest color considers alpha, not just red,
+	// green and blue.
+	got := p.Convert(RGBA{0x80, 0x00, 0x00, 0x80})
+	want := RGBA{0x7f, 0x00, 0x00, 0x7f}
+	if got != want {
+		t.Errorf("got %v, want %v", got, want)
+	}
+}
diff --git a/third_party/gofrontend/libgo/go/image/decode_example_test.go b/third_party/gofrontend/libgo/go/image/decode_example_test.go
index 21e90fe..81fa037 100644
--- a/third_party/gofrontend/libgo/go/image/decode_example_test.go
+++ b/third_party/gofrontend/libgo/go/image/decode_example_test.go
@@ -61,22 +61,22 @@
 	}
 	// Output:
 	// bin               red  green   blue  alpha
-	// 0x0000-0x0fff:    353    759   7228      0
-	// 0x1000-0x1fff:    629   2944   1036      0
-	// 0x2000-0x2fff:   1075   2319    984      0
-	// 0x3000-0x3fff:    838   2291    988      0
-	// 0x4000-0x4fff:    540   1302    542      0
-	// 0x5000-0x5fff:    319    971    263      0
-	// 0x6000-0x6fff:    316    377    178      0
-	// 0x7000-0x7fff:    581    280    216      0
-	// 0x8000-0x8fff:   3457    228    274      0
-	// 0x9000-0x9fff:   2294    237    334      0
-	// 0xa000-0xafff:    938    283    370      0
-	// 0xb000-0xbfff:    322    338    401      0
-	// 0xc000-0xcfff:    229    386    295      0
-	// 0xd000-0xdfff:    263    416    281      0
-	// 0xe000-0xefff:    538    433    312      0
-	// 0xf000-0xffff:   2758   1886   1748  15450
+	// 0x0000-0x0fff:    364    790   7242      0
+	// 0x1000-0x1fff:    645   2967   1039      0
+	// 0x2000-0x2fff:   1072   2299    979      0
+	// 0x3000-0x3fff:    820   2266    980      0
+	// 0x4000-0x4fff:    537   1305    541      0
+	// 0x5000-0x5fff:    319    962    261      0
+	// 0x6000-0x6fff:    322    375    177      0
+	// 0x7000-0x7fff:    601    279    214      0
+	// 0x8000-0x8fff:   3478    227    273      0
+	// 0x9000-0x9fff:   2260    234    329      0
+	// 0xa000-0xafff:    921    282    373      0
+	// 0xb000-0xbfff:    321    335    397      0
+	// 0xc000-0xcfff:    229    388    298      0
+	// 0xd000-0xdfff:    260    414    277      0
+	// 0xe000-0xefff:    516    428    298      0
+	// 0xf000-0xffff:   2785   1899   1772  15450
 }
 
 const data = `
diff --git a/third_party/gofrontend/libgo/go/image/decode_test.go b/third_party/gofrontend/libgo/go/image/decode_test.go
index 8dee57e..d16ef8a 100644
--- a/third_party/gofrontend/libgo/go/image/decode_test.go
+++ b/third_party/gofrontend/libgo/go/image/decode_test.go
@@ -6,6 +6,7 @@
 
 import (
 	"bufio"
+	"fmt"
 	"image"
 	"image/color"
 	"os"
@@ -32,6 +33,9 @@
 	// JPEG is a lossy format and hence needs a non-zero tolerance.
 	{"testdata/video-001.png", "testdata/video-001.jpeg", 8 << 8},
 	{"testdata/video-001.png", "testdata/video-001.progressive.jpeg", 8 << 8},
+	{"testdata/video-001.221212.png", "testdata/video-001.221212.jpeg", 8 << 8},
+	{"testdata/video-001.cmyk.png", "testdata/video-001.cmyk.jpeg", 8 << 8},
+	{"testdata/video-001.rgb.png", "testdata/video-001.rgb.jpeg", 8 << 8},
 	// Grayscale images.
 	{"testdata/video-005.gray.png", "testdata/video-005.gray.jpeg", 8 << 8},
 	{"testdata/video-005.gray.png", "testdata/video-005.gray.png", 0},
@@ -74,6 +78,11 @@
 }
 
 func TestDecode(t *testing.T) {
+	rgba := func(c color.Color) string {
+		r, g, b, a := c.RGBA()
+		return fmt.Sprintf("rgba = 0x%04x, 0x%04x, 0x%04x, 0x%04x for %T%v", r, g, b, a, c, c)
+	}
+
 	golden := make(map[string]image.Image)
 loop:
 	for _, it := range imageTests {
@@ -94,13 +103,14 @@
 		}
 		b := g.Bounds()
 		if !b.Eq(m.Bounds()) {
-			t.Errorf("%s: want bounds %v got %v", it.filename, b, m.Bounds())
+			t.Errorf("%s: got bounds %v want %v", it.filename, m.Bounds(), b)
 			continue loop
 		}
 		for y := b.Min.Y; y < b.Max.Y; y++ {
 			for x := b.Min.X; x < b.Max.X; x++ {
 				if !withinTolerance(g.At(x, y), m.At(x, y), it.tolerance) {
-					t.Errorf("%s: at (%d, %d), want %v got %v", it.filename, x, y, g.At(x, y), m.At(x, y))
+					t.Errorf("%s: at (%d, %d):\ngot  %v\nwant %v",
+						it.filename, x, y, rgba(m.At(x, y)), rgba(g.At(x, y)))
 					continue loop
 				}
 			}
diff --git a/third_party/gofrontend/libgo/go/image/draw/bench_test.go b/third_party/gofrontend/libgo/go/image/draw/bench_test.go
index cc62e25..7b89f95 100644
--- a/third_party/gofrontend/libgo/go/image/draw/bench_test.go
+++ b/third_party/gofrontend/libgo/go/image/draw/bench_test.go
@@ -7,6 +7,7 @@
 import (
 	"image"
 	"image/color"
+	"reflect"
 	"testing"
 )
 
@@ -15,6 +16,11 @@
 	srcw, srch = 400, 300
 )
 
+var palette = color.Palette{
+	color.Black,
+	color.White,
+}
+
 // bench benchmarks drawing src and mask images onto a dst image with the
 // given op and the color models to create those images from.
 // The created images' pixels are initialized to non-zero values.
@@ -50,13 +56,48 @@
 		}
 		dst = dst1
 	default:
-		b.Fatal("unknown destination color model", dcm)
+		// The == operator isn't defined on a color.Palette (a slice), so we
+		// use reflection.
+		if reflect.DeepEqual(dcm, palette) {
+			dst1 := image.NewPaletted(image.Rect(0, 0, dstw, dsth), palette)
+			for y := 0; y < dsth; y++ {
+				for x := 0; x < dstw; x++ {
+					dst1.SetColorIndex(x, y, uint8(x^y)&1)
+				}
+			}
+			dst = dst1
+		} else {
+			b.Fatal("unknown destination color model", dcm)
+		}
 	}
 
 	var src image.Image
 	switch scm {
 	case nil:
 		src = &image.Uniform{C: color.RGBA{0x11, 0x22, 0x33, 0xff}}
+	case color.CMYKModel:
+		src1 := image.NewCMYK(image.Rect(0, 0, srcw, srch))
+		for y := 0; y < srch; y++ {
+			for x := 0; x < srcw; x++ {
+				src1.SetCMYK(x, y, color.CMYK{
+					uint8(13 * x % 0x100),
+					uint8(11 * y % 0x100),
+					uint8((11*x + 13*y) % 0x100),
+					uint8((31*x + 37*y) % 0x100),
+				})
+			}
+		}
+		src = src1
+	case color.GrayModel:
+		src1 := image.NewGray(image.Rect(0, 0, srcw, srch))
+		for y := 0; y < srch; y++ {
+			for x := 0; x < srcw; x++ {
+				src1.SetGray(x, y, color.Gray{
+					uint8((11*x + 13*y) % 0x100),
+				})
+			}
+		}
+		src = src1
 	case color.RGBAModel:
 		src1 := image.NewRGBA(image.Rect(0, 0, srcw, srch))
 		for y := 0; y < srch; y++ {
@@ -179,6 +220,14 @@
 	bench(b, color.RGBAModel, color.YCbCrModel, nil, Over)
 }
 
+func BenchmarkGray(b *testing.B) {
+	bench(b, color.RGBAModel, color.GrayModel, nil, Over)
+}
+
+func BenchmarkCMYK(b *testing.B) {
+	bench(b, color.RGBAModel, color.CMYKModel, nil, Over)
+}
+
 func BenchmarkGlyphOver(b *testing.B) {
 	bench(b, color.RGBAModel, nil, color.AlphaModel, Over)
 }
@@ -187,6 +236,10 @@
 	bench(b, color.RGBAModel, color.RGBA64Model, nil, Src)
 }
 
+func BenchmarkPaletted(b *testing.B) {
+	bench(b, palette, color.RGBAModel, nil, Src)
+}
+
 // The BenchmarkGenericFoo functions exercise the generic, slow-path code.
 
 func BenchmarkGenericOver(b *testing.B) {
diff --git a/third_party/gofrontend/libgo/go/image/draw/clip_test.go b/third_party/gofrontend/libgo/go/image/draw/clip_test.go
index 65381f7..0abf53e 100644
--- a/third_party/gofrontend/libgo/go/image/draw/clip_test.go
+++ b/third_party/gofrontend/libgo/go/image/draw/clip_test.go
@@ -139,7 +139,19 @@
 		image.Pt(20, 0),
 		image.Pt(20, 0),
 	},
-	// TODO(nigeltao): write more tests.
+	{
+		"clip sr and mr",
+		image.Rect(0, 0, 100, 100),
+		image.Rect(0, 0, 100, 100),
+		image.Rect(23, 23, 55, 86),
+		image.Rect(44, 44, 87, 58),
+		image.Pt(10, 10),
+		image.Pt(11, 11),
+		false,
+		image.Rect(33, 33, 45, 47),
+		image.Pt(43, 43),
+		image.Pt(44, 44),
+	},
 }
 
 func TestClip(t *testing.T) {
@@ -149,12 +161,12 @@
 	for _, c := range clipTests {
 		dst := dst0.SubImage(c.dr).(*image.RGBA)
 		src := src0.SubImage(c.sr).(*image.RGBA)
-		var mask image.Image
-		if !c.nilMask {
-			mask = mask0.SubImage(c.mr)
-		}
 		r, sp, mp := c.r, c.sp, c.mp
-		clip(dst, &r, src, &sp, mask, &mp)
+		if c.nilMask {
+			clip(dst, &r, src, &sp, nil, nil)
+		} else {
+			clip(dst, &r, src, &sp, mask0.SubImage(c.mr), &mp)
+		}
 
 		// Check that the actual results equal the expected results.
 		if !c.r0.Eq(r) {
@@ -173,17 +185,17 @@
 		}
 
 		// Check that the clipped rectangle is contained by the dst / src / mask
-		// rectangles, in their respective co-ordinate spaces.
+		// rectangles, in their respective coordinate spaces.
 		if !r.In(c.dr) {
 			t.Errorf("%s: c.dr %v does not contain r %v", c.desc, c.dr, r)
 		}
-		// sr is r translated into src's co-ordinate space.
+		// sr is r translated into src's coordinate space.
 		sr := r.Add(c.sp.Sub(c.dr.Min))
 		if !sr.In(c.sr) {
 			t.Errorf("%s: c.sr %v does not contain sr %v", c.desc, c.sr, sr)
 		}
 		if !c.nilMask {
-			// mr is r translated into mask's co-ordinate space.
+			// mr is r translated into mask's coordinate space.
 			mr := r.Add(c.mp.Sub(c.dr.Min))
 			if !mr.In(c.mr) {
 				t.Errorf("%s: c.mr %v does not contain mr %v", c.desc, c.mr, mr)
diff --git a/third_party/gofrontend/libgo/go/image/draw/draw.go b/third_party/gofrontend/libgo/go/image/draw/draw.go
index 661230e..9419d5e 100644
--- a/third_party/gofrontend/libgo/go/image/draw/draw.go
+++ b/third_party/gofrontend/libgo/go/image/draw/draw.go
@@ -5,12 +5,13 @@
 // Package draw provides image composition functions.
 //
 // See "The Go image/draw package" for an introduction to this package:
-// http://golang.org/doc/articles/image_draw.html
+// https://golang.org/doc/articles/image_draw.html
 package draw
 
 import (
 	"image"
 	"image/color"
+	"image/internal/imageutil"
 )
 
 // m is the maximum color value returned by image.Color.RGBA.
@@ -67,7 +68,7 @@
 }
 
 // clip clips r against each image's bounds (after translating into the
-// destination image's co-ordinate space) and shifts the points sp and mp by
+// destination image's coordinate space) and shifts the points sp and mp by
 // the same amount as the change in r.Min.
 func clip(dst Image, r *image.Rectangle, src image.Image, sp *image.Point, mask image.Image, mp *image.Point) {
 	orig := r.Min
@@ -81,10 +82,12 @@
 	if dx == 0 && dy == 0 {
 		return
 	}
-	(*sp).X += dx
-	(*sp).Y += dy
-	(*mp).X += dx
-	(*mp).Y += dy
+	sp.X += dx
+	sp.Y += dy
+	if mp != nil {
+		mp.X += dx
+		mp.Y += dy
+	}
 }
 
 func processBackward(dst Image, r image.Rectangle, src image.Image, sp image.Point) bool {
@@ -122,9 +125,19 @@
 					drawNRGBAOver(dst0, r, src0, sp)
 					return
 				case *image.YCbCr:
-					if drawYCbCr(dst0, r, src0, sp) {
+					// An image.YCbCr is always fully opaque, and so if the
+					// mask is nil (i.e. fully opaque) then the op is
+					// effectively always Src. Similarly for image.Gray and
+					// image.CMYK.
+					if imageutil.DrawYCbCr(dst0, r, src0, sp) {
 						return
 					}
+				case *image.Gray:
+					drawGray(dst0, r, src0, sp)
+					return
+				case *image.CMYK:
+					drawCMYK(dst0, r, src0, sp)
+					return
 				}
 			} else if mask0, ok := mask.(*image.Alpha); ok {
 				switch src0 := src.(type) {
@@ -146,9 +159,15 @@
 					drawNRGBASrc(dst0, r, src0, sp)
 					return
 				case *image.YCbCr:
-					if drawYCbCr(dst0, r, src0, sp) {
+					if imageutil.DrawYCbCr(dst0, r, src0, sp) {
 						return
 					}
+				case *image.Gray:
+					drawGray(dst0, r, src0, sp)
+					return
+				case *image.CMYK:
+					drawCMYK(dst0, r, src0, sp)
+					return
 				}
 			}
 		}
@@ -157,6 +176,7 @@
 	case *image.Paletted:
 		if op == Src && mask == nil && !processBackward(dst, r, src, sp) {
 			drawPaletted(dst0, r, src, sp, false)
+			return
 		}
 	}
 
@@ -237,16 +257,20 @@
 
 func drawFillSrc(dst *image.RGBA, r image.Rectangle, src *image.Uniform) {
 	sr, sg, sb, sa := src.RGBA()
+	sr8 := uint8(sr >> 8)
+	sg8 := uint8(sg >> 8)
+	sb8 := uint8(sb >> 8)
+	sa8 := uint8(sa >> 8)
 	// The built-in copy function is faster than a straightforward for loop to fill the destination with
 	// the color, but copy requires a slice source. We therefore use a for loop to fill the first row, and
 	// then use the first row as the slice source for the remaining rows.
 	i0 := dst.PixOffset(r.Min.X, r.Min.Y)
 	i1 := i0 + r.Dx()*4
 	for i := i0; i < i1; i += 4 {
-		dst.Pix[i+0] = uint8(sr >> 8)
-		dst.Pix[i+1] = uint8(sg >> 8)
-		dst.Pix[i+2] = uint8(sb >> 8)
-		dst.Pix[i+3] = uint8(sa >> 8)
+		dst.Pix[i+0] = sr8
+		dst.Pix[i+1] = sg8
+		dst.Pix[i+2] = sb8
+		dst.Pix[i+3] = sa8
 	}
 	firstRow := dst.Pix[i0:i1]
 	for y := r.Min.Y + 1; y < r.Max.Y; y++ {
@@ -313,9 +337,11 @@
 		ddelta = dst.Stride
 		sdelta = src.Stride
 	} else {
-		// If the source start point is higher than the destination start point, then we compose the rows
-		// in bottom-up order instead of top-down. Unlike the drawCopyOver function, we don't have to
-		// check the x co-ordinates because the built-in copy function can handle overlapping slices.
+		// If the source start point is higher than the destination start
+		// point, then we compose the rows in bottom-up order instead of
+		// top-down. Unlike the drawCopyOver function, we don't have to check
+		// the x coordinates because the built-in copy function can handle
+		// overlapping slices.
 		d0 += (dy - 1) * dst.Stride
 		s0 += (dy - 1) * src.Stride
 		ddelta = -dst.Stride
@@ -390,72 +416,46 @@
 	}
 }
 
-func drawYCbCr(dst *image.RGBA, r image.Rectangle, src *image.YCbCr, sp image.Point) (ok bool) {
-	// An image.YCbCr is always fully opaque, and so if the mask is implicitly nil
-	// (i.e. fully opaque) then the op is effectively always Src.
-	x0 := (r.Min.X - dst.Rect.Min.X) * 4
-	x1 := (r.Max.X - dst.Rect.Min.X) * 4
-	y0 := r.Min.Y - dst.Rect.Min.Y
-	y1 := r.Max.Y - dst.Rect.Min.Y
-	switch src.SubsampleRatio {
-	case image.YCbCrSubsampleRatio444:
-		for y, sy := y0, sp.Y; y != y1; y, sy = y+1, sy+1 {
-			dpix := dst.Pix[y*dst.Stride:]
-			yi := (sy-src.Rect.Min.Y)*src.YStride + (sp.X - src.Rect.Min.X)
-			ci := (sy-src.Rect.Min.Y)*src.CStride + (sp.X - src.Rect.Min.X)
-			for x := x0; x != x1; x, yi, ci = x+4, yi+1, ci+1 {
-				rr, gg, bb := color.YCbCrToRGB(src.Y[yi], src.Cb[ci], src.Cr[ci])
-				dpix[x+0] = rr
-				dpix[x+1] = gg
-				dpix[x+2] = bb
-				dpix[x+3] = 255
-			}
+func drawGray(dst *image.RGBA, r image.Rectangle, src *image.Gray, sp image.Point) {
+	i0 := (r.Min.X - dst.Rect.Min.X) * 4
+	i1 := (r.Max.X - dst.Rect.Min.X) * 4
+	si0 := (sp.X - src.Rect.Min.X) * 1
+	yMax := r.Max.Y - dst.Rect.Min.Y
+
+	y := r.Min.Y - dst.Rect.Min.Y
+	sy := sp.Y - src.Rect.Min.Y
+	for ; y != yMax; y, sy = y+1, sy+1 {
+		dpix := dst.Pix[y*dst.Stride:]
+		spix := src.Pix[sy*src.Stride:]
+
+		for i, si := i0, si0; i < i1; i, si = i+4, si+1 {
+			p := spix[si]
+			dpix[i+0] = p
+			dpix[i+1] = p
+			dpix[i+2] = p
+			dpix[i+3] = 255
 		}
-	case image.YCbCrSubsampleRatio422:
-		for y, sy := y0, sp.Y; y != y1; y, sy = y+1, sy+1 {
-			dpix := dst.Pix[y*dst.Stride:]
-			yi := (sy-src.Rect.Min.Y)*src.YStride + (sp.X - src.Rect.Min.X)
-			ciBase := (sy-src.Rect.Min.Y)*src.CStride - src.Rect.Min.X/2
-			for x, sx := x0, sp.X; x != x1; x, sx, yi = x+4, sx+1, yi+1 {
-				ci := ciBase + sx/2
-				rr, gg, bb := color.YCbCrToRGB(src.Y[yi], src.Cb[ci], src.Cr[ci])
-				dpix[x+0] = rr
-				dpix[x+1] = gg
-				dpix[x+2] = bb
-				dpix[x+3] = 255
-			}
-		}
-	case image.YCbCrSubsampleRatio420:
-		for y, sy := y0, sp.Y; y != y1; y, sy = y+1, sy+1 {
-			dpix := dst.Pix[y*dst.Stride:]
-			yi := (sy-src.Rect.Min.Y)*src.YStride + (sp.X - src.Rect.Min.X)
-			ciBase := (sy/2-src.Rect.Min.Y/2)*src.CStride - src.Rect.Min.X/2
-			for x, sx := x0, sp.X; x != x1; x, sx, yi = x+4, sx+1, yi+1 {
-				ci := ciBase + sx/2
-				rr, gg, bb := color.YCbCrToRGB(src.Y[yi], src.Cb[ci], src.Cr[ci])
-				dpix[x+0] = rr
-				dpix[x+1] = gg
-				dpix[x+2] = bb
-				dpix[x+3] = 255
-			}
-		}
-	case image.YCbCrSubsampleRatio440:
-		for y, sy := y0, sp.Y; y != y1; y, sy = y+1, sy+1 {
-			dpix := dst.Pix[y*dst.Stride:]
-			yi := (sy-src.Rect.Min.Y)*src.YStride + (sp.X - src.Rect.Min.X)
-			ci := (sy/2-src.Rect.Min.Y/2)*src.CStride + (sp.X - src.Rect.Min.X)
-			for x := x0; x != x1; x, yi, ci = x+4, yi+1, ci+1 {
-				rr, gg, bb := color.YCbCrToRGB(src.Y[yi], src.Cb[ci], src.Cr[ci])
-				dpix[x+0] = rr
-				dpix[x+1] = gg
-				dpix[x+2] = bb
-				dpix[x+3] = 255
-			}
-		}
-	default:
-		return false
 	}
-	return true
+}
+
+func drawCMYK(dst *image.RGBA, r image.Rectangle, src *image.CMYK, sp image.Point) {
+	i0 := (r.Min.X - dst.Rect.Min.X) * 4
+	i1 := (r.Max.X - dst.Rect.Min.X) * 4
+	si0 := (sp.X - src.Rect.Min.X) * 4
+	yMax := r.Max.Y - dst.Rect.Min.Y
+
+	y := r.Min.Y - dst.Rect.Min.Y
+	sy := sp.Y - src.Rect.Min.Y
+	for ; y != yMax; y, sy = y+1, sy+1 {
+		dpix := dst.Pix[y*dst.Stride:]
+		spix := src.Pix[sy*src.Stride:]
+
+		for i, si := i0, si0; i < i1; i, si = i+4, si+4 {
+			dpix[i+0], dpix[i+1], dpix[i+2] =
+				color.CMYKToRGB(spix[si+0], spix[si+1], spix[si+2], spix[si+3])
+			dpix[i+3] = 255
+		}
+	}
 }
 
 func drawGlyphOver(dst *image.RGBA, r image.Rectangle, src *image.Uniform, mask *image.Alpha, mp image.Point) {
@@ -555,6 +555,20 @@
 	return i
 }
 
+// sqDiff returns the squared-difference of x and y, shifted by 2 so that
+// adding four of those won't overflow a uint32.
+//
+// x and y are both assumed to be in the range [0, 0xffff].
+func sqDiff(x, y int32) uint32 {
+	var d uint32
+	if x > y {
+		d = uint32(x - y)
+	} else {
+		d = uint32(y - x)
+	}
+	return (d * d) >> 2
+}
+
 func drawPaletted(dst Image, r image.Rectangle, src image.Image, sp image.Point, floydSteinberg bool) {
 	// TODO(nigeltao): handle the case where the dst and src overlap.
 	// Does it even make sense to try and do Floyd-Steinberg whilst
@@ -564,14 +578,15 @@
 	// dst.At. The dst.Set equivalent is a batch version of the algorithm
 	// used by color.Palette's Index method in image/color/color.go, plus
 	// optional Floyd-Steinberg error diffusion.
-	palette, pix, stride := [][3]int32(nil), []byte(nil), 0
+	palette, pix, stride := [][4]int32(nil), []byte(nil), 0
 	if p, ok := dst.(*image.Paletted); ok {
-		palette = make([][3]int32, len(p.Palette))
+		palette = make([][4]int32, len(p.Palette))
 		for i, col := range p.Palette {
-			r, g, b, _ := col.RGBA()
+			r, g, b, a := col.RGBA()
 			palette[i][0] = int32(r)
 			palette[i][1] = int32(g)
 			palette[i][2] = int32(b)
+			palette[i][3] = int32(a)
 		}
 		pix, stride = p.Pix[p.PixOffset(r.Min.X, r.Min.Y):], p.Stride
 	}
@@ -579,10 +594,10 @@
 	// quantErrorCurr and quantErrorNext are the Floyd-Steinberg quantization
 	// errors that have been propagated to the pixels in the current and next
 	// rows. The +2 simplifies calculation near the edges.
-	var quantErrorCurr, quantErrorNext [][3]int32
+	var quantErrorCurr, quantErrorNext [][4]int32
 	if floydSteinberg {
-		quantErrorCurr = make([][3]int32, r.Dx()+2)
-		quantErrorNext = make([][3]int32, r.Dx()+2)
+		quantErrorCurr = make([][4]int32, r.Dx()+2)
+		quantErrorNext = make([][4]int32, r.Dx()+2)
 	}
 
 	// Loop over each source pixel.
@@ -591,30 +606,25 @@
 		for x := 0; x != r.Dx(); x++ {
 			// er, eg and eb are the pixel's R,G,B values plus the
 			// optional Floyd-Steinberg error.
-			sr, sg, sb, _ := src.At(sp.X+x, sp.Y+y).RGBA()
-			er, eg, eb := int32(sr), int32(sg), int32(sb)
+			sr, sg, sb, sa := src.At(sp.X+x, sp.Y+y).RGBA()
+			er, eg, eb, ea := int32(sr), int32(sg), int32(sb), int32(sa)
 			if floydSteinberg {
 				er = clamp(er + quantErrorCurr[x+1][0]/16)
 				eg = clamp(eg + quantErrorCurr[x+1][1]/16)
 				eb = clamp(eb + quantErrorCurr[x+1][2]/16)
+				ea = clamp(ea + quantErrorCurr[x+1][3]/16)
 			}
 
 			if palette != nil {
-				// Find the closest palette color in Euclidean R,G,B space: the
-				// one that minimizes sum-squared-difference. We shift by 1 bit
-				// to avoid potential uint32 overflow in sum-squared-difference.
+				// Find the closest palette color in Euclidean R,G,B,A space:
+				// the one that minimizes sum-squared-difference.
 				// TODO(nigeltao): consider smarter algorithms.
-				bestIndex, bestSSD := 0, uint32(1<<32-1)
+				bestIndex, bestSum := 0, uint32(1<<32-1)
 				for index, p := range palette {
-					delta := (er - p[0]) >> 1
-					ssd := uint32(delta * delta)
-					delta = (eg - p[1]) >> 1
-					ssd += uint32(delta * delta)
-					delta = (eb - p[2]) >> 1
-					ssd += uint32(delta * delta)
-					if ssd < bestSSD {
-						bestIndex, bestSSD = index, ssd
-						if ssd == 0 {
+					sum := sqDiff(er, p[0]) + sqDiff(eg, p[1]) + sqDiff(eb, p[2]) + sqDiff(ea, p[3])
+					if sum < bestSum {
+						bestIndex, bestSum = index, sum
+						if sum == 0 {
 							break
 						}
 					}
@@ -627,11 +637,13 @@
 				er -= int32(palette[bestIndex][0])
 				eg -= int32(palette[bestIndex][1])
 				eb -= int32(palette[bestIndex][2])
+				ea -= int32(palette[bestIndex][3])
 
 			} else {
 				out.R = uint16(er)
 				out.G = uint16(eg)
 				out.B = uint16(eb)
+				out.A = uint16(ea)
 				// The third argument is &out instead of out (and out is
 				// declared outside of the inner loop) to avoid the implicit
 				// conversion to color.Color here allocating memory in the
@@ -641,32 +653,37 @@
 				if !floydSteinberg {
 					continue
 				}
-				sr, sg, sb, _ = dst.At(r.Min.X+x, r.Min.Y+y).RGBA()
+				sr, sg, sb, sa = dst.At(r.Min.X+x, r.Min.Y+y).RGBA()
 				er -= int32(sr)
 				eg -= int32(sg)
 				eb -= int32(sb)
+				ea -= int32(sa)
 			}
 
 			// Propagate the Floyd-Steinberg quantization error.
 			quantErrorNext[x+0][0] += er * 3
 			quantErrorNext[x+0][1] += eg * 3
 			quantErrorNext[x+0][2] += eb * 3
+			quantErrorNext[x+0][3] += ea * 3
 			quantErrorNext[x+1][0] += er * 5
 			quantErrorNext[x+1][1] += eg * 5
 			quantErrorNext[x+1][2] += eb * 5
+			quantErrorNext[x+1][3] += ea * 5
 			quantErrorNext[x+2][0] += er * 1
 			quantErrorNext[x+2][1] += eg * 1
 			quantErrorNext[x+2][2] += eb * 1
+			quantErrorNext[x+2][3] += ea * 1
 			quantErrorCurr[x+2][0] += er * 7
 			quantErrorCurr[x+2][1] += eg * 7
 			quantErrorCurr[x+2][2] += eb * 7
+			quantErrorCurr[x+2][3] += ea * 7
 		}
 
 		// Recycle the quantization error buffers.
 		if floydSteinberg {
 			quantErrorCurr, quantErrorNext = quantErrorNext, quantErrorCurr
 			for i := range quantErrorNext {
-				quantErrorNext[i] = [3]int32{}
+				quantErrorNext[i] = [4]int32{}
 			}
 		}
 	}
diff --git a/third_party/gofrontend/libgo/go/image/draw/draw_test.go b/third_party/gofrontend/libgo/go/image/draw/draw_test.go
index 0dd7fbd..a58f0f4 100644
--- a/third_party/gofrontend/libgo/go/image/draw/draw_test.go
+++ b/third_party/gofrontend/libgo/go/image/draw/draw_test.go
@@ -74,6 +74,26 @@
 	return m
 }
 
+func vgradGray() image.Image {
+	m := image.NewGray(image.Rect(0, 0, 16, 16))
+	for y := 0; y < 16; y++ {
+		for x := 0; x < 16; x++ {
+			m.Set(x, y, color.Gray{uint8(y * 0x11)})
+		}
+	}
+	return m
+}
+
+func vgradMagenta() image.Image {
+	m := image.NewCMYK(image.Rect(0, 0, 16, 16))
+	for y := 0; y < 16; y++ {
+		for x := 0; x < 16; x++ {
+			m.Set(x, y, color.CMYK{0, uint8(y * 0x11), 0, 0x3f})
+		}
+	}
+	return m
+}
+
 func hgradRed(alpha int) Image {
 	m := image.NewRGBA(image.Rect(0, 0, 16, 16))
 	for y := 0; y < 16; y++ {
@@ -147,6 +167,26 @@
 	{"ycbcrAlphaSrc", vgradCr(), fillAlpha(192), Src, color.RGBA{8, 28, 0, 192}},
 	{"ycbcrNil", vgradCr(), nil, Over, color.RGBA{11, 38, 0, 255}},
 	{"ycbcrNilSrc", vgradCr(), nil, Src, color.RGBA{11, 38, 0, 255}},
+	// Uniform mask (100%, 75%, nil) and variable Gray source.
+	// At (x, y) == (8, 8):
+	// The destination pixel is {136, 0, 0, 255}.
+	// The source pixel is {136} in Gray-space, which is {136, 136, 136, 255} in RGBA-space.
+	{"gray", vgradGray(), fillAlpha(255), Over, color.RGBA{136, 136, 136, 255}},
+	{"graySrc", vgradGray(), fillAlpha(255), Src, color.RGBA{136, 136, 136, 255}},
+	{"grayAlpha", vgradGray(), fillAlpha(192), Over, color.RGBA{136, 102, 102, 255}},
+	{"grayAlphaSrc", vgradGray(), fillAlpha(192), Src, color.RGBA{102, 102, 102, 192}},
+	{"grayNil", vgradGray(), nil, Over, color.RGBA{136, 136, 136, 255}},
+	{"grayNilSrc", vgradGray(), nil, Src, color.RGBA{136, 136, 136, 255}},
+	// Uniform mask (100%, 75%, nil) and variable CMYK source.
+	// At (x, y) == (8, 8):
+	// The destination pixel is {136, 0, 0, 255}.
+	// The source pixel is {0, 136, 0, 63} in CMYK-space, which is {192, 89, 192} in RGB-space.
+	{"cmyk", vgradMagenta(), fillAlpha(255), Over, color.RGBA{192, 89, 192, 255}},
+	{"cmykSrc", vgradMagenta(), fillAlpha(255), Src, color.RGBA{192, 89, 192, 255}},
+	{"cmykAlpha", vgradMagenta(), fillAlpha(192), Over, color.RGBA{178, 67, 145, 255}},
+	{"cmykAlphaSrc", vgradMagenta(), fillAlpha(192), Src, color.RGBA{145, 67, 145, 192}},
+	{"cmykNil", vgradMagenta(), nil, Over, color.RGBA{192, 89, 192, 255}},
+	{"cmykNilSrc", vgradMagenta(), nil, Src, color.RGBA{192, 89, 192, 255}},
 	// Variable mask and variable source.
 	// At (x, y) == (8, 8):
 	// The destination pixel is {136, 0, 0, 255}.
diff --git a/third_party/gofrontend/libgo/go/image/geom.go b/third_party/gofrontend/libgo/go/image/geom.go
index 6ebaf67..e1cd4dc 100644
--- a/third_party/gofrontend/libgo/go/image/geom.go
+++ b/third_party/gofrontend/libgo/go/image/geom.go
@@ -5,6 +5,7 @@
 package image
 
 import (
+	"image/color"
 	"strconv"
 )
 
@@ -62,7 +63,7 @@
 
 // Eq reports whether p and q are equal.
 func (p Point) Eq(q Point) bool {
-	return p.X == q.X && p.Y == q.Y
+	return p == q
 }
 
 // ZP is the zero Point.
@@ -77,6 +78,10 @@
 // It is well-formed if Min.X <= Max.X and likewise for Y. Points are always
 // well-formed. A rectangle's methods always return well-formed outputs for
 // well-formed inputs.
+//
+// A Rectangle is also an Image whose bounds are the rectangle itself. At
+// returns color.Opaque for points in the rectangle and color.Transparent
+// otherwise.
 type Rectangle struct {
 	Min, Max Point
 }
@@ -164,6 +169,12 @@
 
 // Union returns the smallest rectangle that contains both r and s.
 func (r Rectangle) Union(s Rectangle) Rectangle {
+	if r.Empty() {
+		return s
+	}
+	if s.Empty() {
+		return r
+	}
 	if r.Min.X > s.Min.X {
 		r.Min.X = s.Min.X
 	}
@@ -184,15 +195,16 @@
 	return r.Min.X >= r.Max.X || r.Min.Y >= r.Max.Y
 }
 
-// Eq reports whether r and s are equal.
+// Eq reports whether r and s contain the same set of points. All empty
+// rectangles are considered equal.
 func (r Rectangle) Eq(s Rectangle) bool {
-	return r.Min.X == s.Min.X && r.Min.Y == s.Min.Y &&
-		r.Max.X == s.Max.X && r.Max.Y == s.Max.Y
+	return r == s || r.Empty() && s.Empty()
 }
 
 // Overlaps reports whether r and s have a non-empty intersection.
 func (r Rectangle) Overlaps(s Rectangle) bool {
-	return r.Min.X < s.Max.X && s.Min.X < r.Max.X &&
+	return !r.Empty() && !s.Empty() &&
+		r.Min.X < s.Max.X && s.Min.X < r.Max.X &&
 		r.Min.Y < s.Max.Y && s.Min.Y < r.Max.Y
 }
 
@@ -219,10 +231,30 @@
 	return r
 }
 
+// At implements the Image interface.
+func (r Rectangle) At(x, y int) color.Color {
+	if (Point{x, y}).In(r) {
+		return color.Opaque
+	}
+	return color.Transparent
+}
+
+// Bounds implements the Image interface.
+func (r Rectangle) Bounds() Rectangle {
+	return r
+}
+
+// ColorModel implements the Image interface.
+func (r Rectangle) ColorModel() color.Model {
+	return color.Alpha16Model
+}
+
 // ZR is the zero Rectangle.
 var ZR Rectangle
 
-// Rect is shorthand for Rectangle{Pt(x0, y0), Pt(x1, y1)}.
+// Rect is shorthand for Rectangle{Pt(x0, y0), Pt(x1, y1)}. The returned
+// rectangle has minimum and maximum coordinates swapped if necessary so that
+// it is well-formed.
 func Rect(x0, y0, x1, y1 int) Rectangle {
 	if x0 > x1 {
 		x0, x1 = x1, x0
diff --git a/third_party/gofrontend/libgo/go/image/geom_test.go b/third_party/gofrontend/libgo/go/image/geom_test.go
new file mode 100644
index 0000000..6e9c6a1
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/image/geom_test.go
@@ -0,0 +1,115 @@
+// 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 image
+
+import (
+	"fmt"
+	"testing"
+)
+
+func TestRectangle(t *testing.T) {
+	// in checks that every point in f is in g.
+	in := func(f, g Rectangle) error {
+		if !f.In(g) {
+			return fmt.Errorf("f=%s, f.In(%s): got false, want true", f, g)
+		}
+		for y := f.Min.Y; y < f.Max.Y; y++ {
+			for x := f.Min.X; x < f.Max.X; x++ {
+				p := Point{x, y}
+				if !p.In(g) {
+					return fmt.Errorf("p=%s, p.In(%s): got false, want true", p, g)
+				}
+			}
+		}
+		return nil
+	}
+
+	rects := []Rectangle{
+		Rect(0, 0, 10, 10),
+		Rect(1, 2, 3, 4),
+		Rect(4, 6, 10, 10),
+		Rect(2, 3, 12, 5),
+		Rect(-1, -2, 0, 0),
+		Rect(-1, -2, 4, 6),
+		Rect(-10, -20, 30, 40),
+		Rect(8, 8, 8, 8),
+		Rect(88, 88, 88, 88),
+		Rect(6, 5, 4, 3),
+	}
+
+	// r.Eq(s) should be equivalent to every point in r being in s, and every
+	// point in s being in r.
+	for _, r := range rects {
+		for _, s := range rects {
+			got := r.Eq(s)
+			want := in(r, s) == nil && in(s, r) == nil
+			if got != want {
+				t.Errorf("Eq: r=%s, s=%s: got %t, want %t", r, s, got, want)
+			}
+		}
+	}
+
+	// The intersection should be the largest rectangle a such that every point
+	// in a is both in r and in s.
+	for _, r := range rects {
+		for _, s := range rects {
+			a := r.Intersect(s)
+			if err := in(a, r); err != nil {
+				t.Errorf("Intersect: r=%s, s=%s, a=%s, a not in r: %v", r, s, a, err)
+			}
+			if err := in(a, s); err != nil {
+				t.Errorf("Intersect: r=%s, s=%s, a=%s, a not in s: %v", r, s, a, err)
+			}
+			if a.Empty() == r.Overlaps(s) {
+				t.Errorf("Intersect: r=%s, s=%s, a=%s: empty=%t same as overlaps=%t",
+					r, s, a, a.Empty(), r.Overlaps(s))
+			}
+			largerThanA := [4]Rectangle{a, a, a, a}
+			largerThanA[0].Min.X--
+			largerThanA[1].Min.Y--
+			largerThanA[2].Max.X++
+			largerThanA[3].Max.Y++
+			for i, b := range largerThanA {
+				if b.Empty() {
+					// b isn't actually larger than a.
+					continue
+				}
+				if in(b, r) == nil && in(b, s) == nil {
+					t.Errorf("Intersect: r=%s, s=%s, a=%s, b=%s, i=%d: intersection could be larger",
+						r, s, a, b, i)
+				}
+			}
+		}
+	}
+
+	// The union should be the smallest rectangle a such that every point in r
+	// is in a and every point in s is in a.
+	for _, r := range rects {
+		for _, s := range rects {
+			a := r.Union(s)
+			if err := in(r, a); err != nil {
+				t.Errorf("Union: r=%s, s=%s, a=%s, r not in a: %v", r, s, a, err)
+			}
+			if err := in(s, a); err != nil {
+				t.Errorf("Union: r=%s, s=%s, a=%s, s not in a: %v", r, s, a, err)
+			}
+			if a.Empty() {
+				// You can't get any smaller than a.
+				continue
+			}
+			smallerThanA := [4]Rectangle{a, a, a, a}
+			smallerThanA[0].Min.X++
+			smallerThanA[1].Min.Y++
+			smallerThanA[2].Max.X--
+			smallerThanA[3].Max.Y--
+			for i, b := range smallerThanA {
+				if in(r, b) == nil && in(s, b) == nil {
+					t.Errorf("Union: r=%s, s=%s, a=%s, b=%s, i=%d: union could be smaller",
+						r, s, a, b, i)
+				}
+			}
+		}
+	}
+}
diff --git a/third_party/gofrontend/libgo/go/image/gif/reader.go b/third_party/gofrontend/libgo/go/image/gif/reader.go
index 5a863e2..6a13312 100644
--- a/third_party/gofrontend/libgo/go/image/gif/reader.go
+++ b/third_party/gofrontend/libgo/go/image/gif/reader.go
@@ -32,15 +32,20 @@
 // Masks etc.
 const (
 	// Fields.
-	fColorMapFollows = 1 << 7
-
-	// Image fields.
-	ifLocalColorTable = 1 << 7
-	ifInterlace       = 1 << 6
-	ifPixelSizeMask   = 7
+	fColorTable         = 1 << 7
+	fInterlace          = 1 << 6
+	fColorTableBitsMask = 7
 
 	// Graphic control flags.
 	gcTransparentColorSet = 1 << 0
+	gcDisposalMethodMask  = 7 << 2
+)
+
+// Disposal Methods.
+const (
+	DisposalNone       = 0x01
+	DisposalBackground = 0x02
+	DisposalPrevious   = 0x03
 )
 
 // Section indicators.
@@ -66,14 +71,10 @@
 	vers            string
 	width           int
 	height          int
-	flags           byte
-	headerFields    byte
-	backgroundIndex byte
 	loopCount       int
 	delayTime       int
-
-	// Unused from header.
-	aspect byte
+	backgroundIndex byte
+	disposalMethod  byte
 
 	// From image descriptor.
 	imageFields byte
@@ -83,13 +84,13 @@
 	hasTransparentIndex bool
 
 	// Computed.
-	pixelSize      uint
-	globalColorMap color.Palette
+	globalColorTable color.Palette
 
 	// Used when decoding.
-	delay []int
-	image []*image.Paletted
-	tmp   [1024]byte // must be at least 768 so we can read color map
+	delay    []int
+	disposal []byte
+	image    []*image.Paletted
+	tmp      [1024]byte // must be at least 768 so we can read color table
 }
 
 // blockReader parses the block structure of GIF image data, which
@@ -122,7 +123,7 @@
 			b.err = io.EOF
 			return 0, b.err
 		}
-		b.slice = b.tmp[0:blockLen]
+		b.slice = b.tmp[:blockLen]
 		if _, b.err = io.ReadFull(b.r, b.slice); b.err != nil {
 			return 0, b.err
 		}
@@ -149,12 +150,6 @@
 		return nil
 	}
 
-	if d.headerFields&fColorMapFollows != 0 {
-		if d.globalColorMap, err = d.readColorMap(); err != nil {
-			return err
-		}
-	}
-
 	for {
 		c, err := d.r.ReadByte()
 		if err != nil {
@@ -171,19 +166,22 @@
 			if err != nil {
 				return err
 			}
-			useLocalColorMap := d.imageFields&fColorMapFollows != 0
-			if useLocalColorMap {
-				m.Palette, err = d.readColorMap()
+			useLocalColorTable := d.imageFields&fColorTable != 0
+			if useLocalColorTable {
+				m.Palette, err = d.readColorTable(d.imageFields)
 				if err != nil {
 					return err
 				}
 			} else {
-				m.Palette = d.globalColorMap
+				if d.globalColorTable == nil {
+					return errors.New("gif: no color table")
+				}
+				m.Palette = d.globalColorTable
 			}
 			if d.hasTransparentIndex && int(d.transparentIndex) < len(m.Palette) {
-				if !useLocalColorMap {
-					// Clone the global color map.
-					m.Palette = append(color.Palette(nil), d.globalColorMap...)
+				if !useLocalColorTable {
+					// Clone the global color table.
+					m.Palette = append(color.Palette(nil), d.globalColorTable...)
 				}
 				m.Palette[d.transparentIndex] = color.RGBA{}
 			}
@@ -204,9 +202,18 @@
 				}
 				return errNotEnough
 			}
-			// Both lzwr and br should be exhausted. Reading from them
-			// should yield (0, io.EOF).
-			if n, err := lzwr.Read(d.tmp[:1]); n != 0 || err != io.EOF {
+			// Both lzwr and br should be exhausted. Reading from them should
+			// yield (0, io.EOF).
+			//
+			// The spec (Appendix F - Compression), says that "An End of
+			// Information code... must be the last code output by the encoder
+			// for an image". In practice, though, giflib (a widely used C
+			// library) does not enforce this, so we also accept lzwr returning
+			// io.ErrUnexpectedEOF (meaning that the encoded stream hit io.EOF
+			// before the LZW decoder saw an explict end code), provided that
+			// the io.ReadFull call above successfully read len(m.Pix) bytes.
+			// See https://golang.org/issue/9856 for an example GIF.
+			if n, err := lzwr.Read(d.tmp[:1]); n != 0 || (err != io.EOF && err != io.ErrUnexpectedEOF) {
 				if err != nil {
 					return err
 				}
@@ -229,12 +236,13 @@
 			}
 
 			// Undo the interlacing if necessary.
-			if d.imageFields&ifInterlace != 0 {
+			if d.imageFields&fInterlace != 0 {
 				uninterlace(m)
 			}
 
 			d.image = append(d.image, m)
 			d.delay = append(d.delay, d.delayTime)
+			d.disposal = append(d.disposal, d.disposalMethod)
 			// The GIF89a spec, Section 23 (Graphic Control Extension) says:
 			// "The scope of this extension is the first graphic rendering block
 			// to follow." We therefore reset the GCE fields to zero.
@@ -254,44 +262,39 @@
 }
 
 func (d *decoder) readHeaderAndScreenDescriptor() error {
-	_, err := io.ReadFull(d.r, d.tmp[0:13])
+	_, err := io.ReadFull(d.r, d.tmp[:13])
 	if err != nil {
 		return err
 	}
-	d.vers = string(d.tmp[0:6])
+	d.vers = string(d.tmp[:6])
 	if d.vers != "GIF87a" && d.vers != "GIF89a" {
 		return fmt.Errorf("gif: can't recognize format %s", d.vers)
 	}
 	d.width = int(d.tmp[6]) + int(d.tmp[7])<<8
 	d.height = int(d.tmp[8]) + int(d.tmp[9])<<8
-	d.headerFields = d.tmp[10]
-	d.backgroundIndex = d.tmp[11]
-	d.aspect = d.tmp[12]
-	d.loopCount = -1
-	d.pixelSize = uint(d.headerFields&7) + 1
+	if fields := d.tmp[10]; fields&fColorTable != 0 {
+		d.backgroundIndex = d.tmp[11]
+		// readColorTable overwrites the contents of d.tmp, but that's OK.
+		if d.globalColorTable, err = d.readColorTable(fields); err != nil {
+			return err
+		}
+	}
+	// d.tmp[12] is the Pixel Aspect Ratio, which is ignored.
 	return nil
 }
 
-func (d *decoder) readColorMap() (color.Palette, error) {
-	if d.pixelSize > 8 {
-		return nil, fmt.Errorf("gif: can't handle %d bits per pixel", d.pixelSize)
-	}
-	numColors := 1 << d.pixelSize
-	if d.imageFields&ifLocalColorTable != 0 {
-		numColors = 1 << ((d.imageFields & ifPixelSizeMask) + 1)
-	}
-	numValues := 3 * numColors
-	_, err := io.ReadFull(d.r, d.tmp[0:numValues])
+func (d *decoder) readColorTable(fields byte) (color.Palette, error) {
+	n := 1 << (1 + uint(fields&fColorTableBitsMask))
+	_, err := io.ReadFull(d.r, d.tmp[:3*n])
 	if err != nil {
-		return nil, fmt.Errorf("gif: short read on color map: %s", err)
+		return nil, fmt.Errorf("gif: short read on color table: %s", err)
 	}
-	colorMap := make(color.Palette, numColors)
-	j := 0
-	for i := range colorMap {
-		colorMap[i] = color.RGBA{d.tmp[j+0], d.tmp[j+1], d.tmp[j+2], 0xFF}
+	j, p := 0, make(color.Palette, n)
+	for i := range p {
+		p[i] = color.RGBA{d.tmp[j+0], d.tmp[j+1], d.tmp[j+2], 0xFF}
 		j += 3
 	}
-	return colorMap, nil
+	return p, nil
 }
 
 func (d *decoder) readExtension() error {
@@ -318,7 +321,7 @@
 		return fmt.Errorf("gif: unknown extension 0x%.2x", extension)
 	}
 	if size > 0 {
-		if _, err := io.ReadFull(d.r, d.tmp[0:size]); err != nil {
+		if _, err := io.ReadFull(d.r, d.tmp[:size]); err != nil {
 			return err
 		}
 	}
@@ -343,12 +346,13 @@
 }
 
 func (d *decoder) readGraphicControl() error {
-	if _, err := io.ReadFull(d.r, d.tmp[0:6]); err != nil {
+	if _, err := io.ReadFull(d.r, d.tmp[:6]); err != nil {
 		return fmt.Errorf("gif: can't read graphic control: %s", err)
 	}
-	d.flags = d.tmp[1]
+	flags := d.tmp[1]
+	d.disposalMethod = (flags & gcDisposalMethodMask) >> 2
 	d.delayTime = int(d.tmp[2]) | int(d.tmp[3])<<8
-	if d.flags&gcTransparentColorSet != 0 {
+	if flags&gcTransparentColorSet != 0 {
 		d.transparentIndex = d.tmp[4]
 		d.hasTransparentIndex = true
 	}
@@ -356,7 +360,7 @@
 }
 
 func (d *decoder) newImageFromDescriptor() (*image.Paletted, error) {
-	if _, err := io.ReadFull(d.r, d.tmp[0:9]); err != nil {
+	if _, err := io.ReadFull(d.r, d.tmp[:9]); err != nil {
 		return nil, fmt.Errorf("gif: can't read image descriptor: %s", err)
 	}
 	left := int(d.tmp[0]) + int(d.tmp[1])<<8
@@ -380,7 +384,7 @@
 	if n == 0 || err != nil {
 		return 0, err
 	}
-	return io.ReadFull(d.r, d.tmp[0:n])
+	return io.ReadFull(d.r, d.tmp[:n])
 }
 
 // interlaceScan defines the ordering for a pass of the interlace algorithm.
@@ -429,6 +433,24 @@
 	Image     []*image.Paletted // The successive images.
 	Delay     []int             // The successive delay times, one per frame, in 100ths of a second.
 	LoopCount int               // The loop count.
+	// Disposal is the successive disposal methods, one per frame. For
+	// backwards compatibility, a nil Disposal is valid to pass to EncodeAll,
+	// and implies that each frame's disposal method is 0 (no disposal
+	// specified).
+	Disposal []byte
+	// Config is the global color table (palette), width and height. A nil or
+	// empty-color.Palette Config.ColorModel means that each frame has its own
+	// color table and there is no global color table. Each frame's bounds must
+	// be within the rectangle defined by the two points (0, 0) and
+	// (Config.Width, Config.Height).
+	//
+	// For backwards compatibility, a zero-valued Config is valid to pass to
+	// EncodeAll, and implies that the overall GIF's width and height equals
+	// the first frame's bounds' Rectangle.Max point.
+	Config image.Config
+	// BackgroundIndex is the background index in the global color table, for
+	// use with the DisposalBackground disposal method.
+	BackgroundIndex byte
 }
 
 // DecodeAll reads a GIF image from r and returns the sequential frames
@@ -442,6 +464,13 @@
 		Image:     d.image,
 		LoopCount: d.loopCount,
 		Delay:     d.delay,
+		Disposal:  d.disposal,
+		Config: image.Config{
+			ColorModel: d.globalColorTable,
+			Width:      d.width,
+			Height:     d.height,
+		},
+		BackgroundIndex: d.backgroundIndex,
 	}
 	return gif, nil
 }
@@ -454,7 +483,7 @@
 		return image.Config{}, err
 	}
 	return image.Config{
-		ColorModel: d.globalColorMap,
+		ColorModel: d.globalColorTable,
 		Width:      d.width,
 		Height:     d.height,
 	}, nil
diff --git a/third_party/gofrontend/libgo/go/image/gif/reader_test.go b/third_party/gofrontend/libgo/go/image/gif/reader_test.go
index 7b6f504..c294195 100644
--- a/third_party/gofrontend/libgo/go/image/gif/reader_test.go
+++ b/third_party/gofrontend/libgo/go/image/gif/reader_test.go
@@ -17,8 +17,8 @@
 const (
 	headerStr = "GIF89a" +
 		"\x02\x00\x01\x00" + // width=2, height=1
-		"\x80\x00\x00" // headerFields=(a color map of 2 pixels), backgroundIndex, aspect
-	paletteStr = "\x10\x20\x30\x40\x50\x60" // the color map, also known as a palette
+		"\x80\x00\x00" // headerFields=(a color table of 2 pixels), backgroundIndex, aspect
+	paletteStr = "\x10\x20\x30\x40\x50\x60" // the color table, also known as a palette
 	trailerStr = "\x3b"
 )
 
@@ -141,7 +141,7 @@
 	'G', 'I', 'F', '8', '9', 'a',
 	1, 0, 1, 0, // w=1, h=1 (6)
 	128, 0, 0, // headerFields, bg, aspect (10)
-	0, 0, 0, 1, 1, 1, // color map and graphics control (13)
+	0, 0, 0, 1, 1, 1, // color table and graphics control (13)
 	0x21, 0xf9, 0x04, 0x00, 0x00, 0x00, 0xff, 0x00, // (19)
 	// frame 1 (0,0 - 1,1)
 	0x2c,
@@ -200,22 +200,26 @@
 	b.WriteString("\x2c\x00\x00\x00\x00\x02\x00\x01\x00\x00\x02")
 
 	// Encode the pixels: neither is in range, because there is no palette.
-	pix := []byte{0, 128}
+	pix := []byte{0, 3}
 	enc := &bytes.Buffer{}
 	w := lzw.NewWriter(enc, lzw.LSB, 2)
-	w.Write(pix)
-	w.Close()
+	if _, err := w.Write(pix); err != nil {
+		t.Fatalf("Write: %v", err)
+	}
+	if err := w.Close(); err != nil {
+		t.Fatalf("Close: %v", err)
+	}
 	b.WriteByte(byte(len(enc.Bytes())))
 	b.Write(enc.Bytes())
 	b.WriteByte(0x00) // An empty block signifies the end of the image data.
 
 	b.WriteString(trailerStr)
 
-	try(t, b.Bytes(), "gif: invalid pixel value")
+	try(t, b.Bytes(), "gif: no color table")
 }
 
 func TestPixelOutsidePaletteRange(t *testing.T) {
-	for _, pval := range []byte{0, 1, 2, 3, 255} {
+	for _, pval := range []byte{0, 1, 2, 3} {
 		b := &bytes.Buffer{}
 
 		// Manufacture a GIF with a 2 color palette.
@@ -229,8 +233,12 @@
 		pix := []byte{pval, pval}
 		enc := &bytes.Buffer{}
 		w := lzw.NewWriter(enc, lzw.LSB, 2)
-		w.Write(pix)
-		w.Close()
+		if _, err := w.Write(pix); err != nil {
+			t.Fatalf("Write: %v", err)
+		}
+		if err := w.Close(); err != nil {
+			t.Fatalf("Close: %v", err)
+		}
 		b.WriteByte(byte(len(enc.Bytes())))
 		b.Write(enc.Bytes())
 		b.WriteByte(0x00) // An empty block signifies the end of the image data.
@@ -245,3 +253,24 @@
 		try(t, b.Bytes(), want)
 	}
 }
+
+func TestLoopCount(t *testing.T) {
+	data := []byte("GIF89a000\x00000,0\x00\x00\x00\n\x00" +
+		"\n\x00\x80000000\x02\b\xf01u\xb9\xfdal\x05\x00;")
+	img, err := DecodeAll(bytes.NewReader(data))
+	if err != nil {
+		t.Fatal("DecodeAll:", err)
+	}
+	w := new(bytes.Buffer)
+	err = EncodeAll(w, img)
+	if err != nil {
+		t.Fatal("EncodeAll:", err)
+	}
+	img1, err := DecodeAll(w)
+	if err != nil {
+		t.Fatal("DecodeAll:", err)
+	}
+	if img.LoopCount != img1.LoopCount {
+		t.Errorf("loop count mismatch: %d vs %d", img.LoopCount, img1.LoopCount)
+	}
+}
diff --git a/third_party/gofrontend/libgo/go/image/gif/writer.go b/third_party/gofrontend/libgo/go/image/gif/writer.go
index 49abde7..dd31790 100644
--- a/third_party/gofrontend/libgo/go/image/gif/writer.go
+++ b/third_party/gofrontend/libgo/go/image/gif/writer.go
@@ -6,6 +6,7 @@
 
 import (
 	"bufio"
+	"bytes"
 	"compress/lzw"
 	"errors"
 	"image"
@@ -52,9 +53,13 @@
 	w   writer
 	err error
 	// g is a reference to the data that is being encoded.
-	g *GIF
-	// buf is a scratch buffer. It must be at least 768 so we can write the color map.
-	buf [1024]byte
+	g GIF
+	// globalCT is the size in bytes of the global color table.
+	globalCT int
+	// buf is a scratch buffer. It must be at least 256 for the blockWriter.
+	buf              [256]byte
+	globalColorTable [3 * 256]byte
+	localColorTable  [3 * 256]byte
 }
 
 // blockWriter writes the block structure of GIF image data, which
@@ -116,18 +121,27 @@
 		return
 	}
 
-	pm := e.g.Image[0]
 	// Logical screen width and height.
-	writeUint16(e.buf[0:2], uint16(pm.Bounds().Dx()))
-	writeUint16(e.buf[2:4], uint16(pm.Bounds().Dy()))
+	writeUint16(e.buf[0:2], uint16(e.g.Config.Width))
+	writeUint16(e.buf[2:4], uint16(e.g.Config.Height))
 	e.write(e.buf[:4])
 
-	// All frames have a local color table, so a global color table
-	// is not needed.
-	e.buf[0] = 0x00
-	e.buf[1] = 0x00 // Background Color Index.
-	e.buf[2] = 0x00 // Pixel Aspect Ratio.
-	e.write(e.buf[:3])
+	if p, ok := e.g.Config.ColorModel.(color.Palette); ok && len(p) > 0 {
+		paddedSize := log2(len(p)) // Size of Global Color Table: 2^(1+n).
+		e.buf[0] = fColorTable | uint8(paddedSize)
+		e.buf[1] = e.g.BackgroundIndex
+		e.buf[2] = 0x00 // Pixel Aspect Ratio.
+		e.write(e.buf[:3])
+		e.globalCT = encodeColorTable(e.globalColorTable[:], p, paddedSize)
+		e.write(e.globalColorTable[:e.globalCT])
+	} else {
+		// All frames have a local color table, so a global color table
+		// is not needed.
+		e.buf[0] = 0x00
+		e.buf[1] = 0x00 // Background Color Index.
+		e.buf[2] = 0x00 // Pixel Aspect Ratio.
+		e.write(e.buf[:3])
+	}
 
 	// Add animation info if necessary.
 	if len(e.g.Image) > 1 {
@@ -147,28 +161,25 @@
 	}
 }
 
-func (e *encoder) writeColorTable(p color.Palette, size int) {
-	if e.err != nil {
-		return
-	}
-
-	for i := 0; i < log2Lookup[size]; i++ {
+func encodeColorTable(dst []byte, p color.Palette, size int) int {
+	n := log2Lookup[size]
+	for i := 0; i < n; i++ {
 		if i < len(p) {
 			r, g, b, _ := p[i].RGBA()
-			e.buf[3*i+0] = uint8(r >> 8)
-			e.buf[3*i+1] = uint8(g >> 8)
-			e.buf[3*i+2] = uint8(b >> 8)
+			dst[3*i+0] = uint8(r >> 8)
+			dst[3*i+1] = uint8(g >> 8)
+			dst[3*i+2] = uint8(b >> 8)
 		} else {
 			// Pad with black.
-			e.buf[3*i+0] = 0x00
-			e.buf[3*i+1] = 0x00
-			e.buf[3*i+2] = 0x00
+			dst[3*i+0] = 0x00
+			dst[3*i+1] = 0x00
+			dst[3*i+2] = 0x00
 		}
 	}
-	e.write(e.buf[:3*log2Lookup[size]])
+	return 3 * n
 }
 
-func (e *encoder) writeImageBlock(pm *image.Paletted, delay int) {
+func (e *encoder) writeImageBlock(pm *image.Paletted, delay int, disposal byte) {
 	if e.err != nil {
 		return
 	}
@@ -179,10 +190,14 @@
 	}
 
 	b := pm.Bounds()
-	if b.Dx() >= 1<<16 || b.Dy() >= 1<<16 || b.Min.X < 0 || b.Min.X >= 1<<16 || b.Min.Y < 0 || b.Min.Y >= 1<<16 {
+	if b.Min.X < 0 || b.Max.X >= 1<<16 || b.Min.Y < 0 || b.Max.Y >= 1<<16 {
 		e.err = errors.New("gif: image block is too large to encode")
 		return
 	}
+	if !b.In(image.Rectangle{Max: image.Point{e.g.Config.Width, e.g.Config.Height}}) {
+		e.err = errors.New("gif: image block is out of bounds")
+		return
+	}
 
 	transparentIndex := -1
 	for i, c := range pm.Palette {
@@ -192,14 +207,14 @@
 		}
 	}
 
-	if delay > 0 || transparentIndex != -1 {
+	if delay > 0 || disposal != 0 || transparentIndex != -1 {
 		e.buf[0] = sExtension  // Extension Introducer.
 		e.buf[1] = gcLabel     // Graphic Control Label.
 		e.buf[2] = gcBlockSize // Block Size.
 		if transparentIndex != -1 {
-			e.buf[3] = 0x01
+			e.buf[3] = 0x01 | disposal<<2
 		} else {
-			e.buf[3] = 0x00
+			e.buf[3] = 0x00 | disposal<<2
 		}
 		writeUint16(e.buf[4:6], uint16(delay)) // Delay Time (1/100ths of a second)
 
@@ -220,11 +235,15 @@
 	e.write(e.buf[:9])
 
 	paddedSize := log2(len(pm.Palette)) // Size of Local Color Table: 2^(1+n).
-	// Interlacing is not supported.
-	e.writeByte(0x80 | uint8(paddedSize))
-
-	// Local Color Table.
-	e.writeColorTable(pm.Palette, paddedSize)
+	ct := encodeColorTable(e.localColorTable[:], pm.Palette, paddedSize)
+	if ct != e.globalCT || !bytes.Equal(e.globalColorTable[:ct], e.localColorTable[:ct]) {
+		// Use a local color table.
+		e.writeByte(fColorTable | uint8(paddedSize))
+		e.write(e.localColorTable[:ct])
+	} else {
+		// Use the global color table.
+		e.writeByte(0)
+	}
 
 	litWidth := paddedSize + 1
 	if litWidth < 2 {
@@ -281,7 +300,23 @@
 		g.LoopCount = 0
 	}
 
-	e := encoder{g: g}
+	e := encoder{g: *g}
+	// The GIF.Disposal, GIF.Config and GIF.BackgroundIndex fields were added
+	// in Go 1.5. Valid Go 1.4 code, such as when the Disposal field is omitted
+	// in a GIF struct literal, should still produce valid GIFs.
+	if e.g.Disposal != nil && len(e.g.Image) != len(e.g.Disposal) {
+		return errors.New("gif: mismatched image and disposal lengths")
+	}
+	if e.g.Config == (image.Config{}) {
+		p := g.Image[0].Bounds().Max
+		e.g.Config.Width = p.X
+		e.g.Config.Height = p.Y
+	} else if e.g.Config.ColorModel != nil {
+		if _, ok := e.g.Config.ColorModel.(color.Palette); !ok {
+			return errors.New("gif: GIF color model must be a color.Palette")
+		}
+	}
+
 	if ww, ok := w.(writer); ok {
 		e.w = ww
 	} else {
@@ -290,7 +325,11 @@
 
 	e.writeHeader()
 	for i, pm := range g.Image {
-		e.writeImageBlock(pm, g.Delay[i])
+		disposal := uint8(0)
+		if g.Disposal != nil {
+			disposal = g.Disposal[i]
+		}
+		e.writeImageBlock(pm, g.Delay[i], disposal)
 	}
 	e.writeByte(sTrailer)
 	e.flush()
@@ -326,8 +365,22 @@
 		opts.Drawer.Draw(pm, b, m, image.ZP)
 	}
 
+	// When calling Encode instead of EncodeAll, the single-frame image is
+	// translated such that its top-left corner is (0, 0), so that the single
+	// frame completely fills the overall GIF's bounds.
+	if pm.Rect.Min != (image.Point{}) {
+		dup := *pm
+		dup.Rect = dup.Rect.Sub(dup.Rect.Min)
+		pm = &dup
+	}
+
 	return EncodeAll(w, &GIF{
 		Image: []*image.Paletted{pm},
 		Delay: []int{0},
+		Config: image.Config{
+			ColorModel: pm.Palette,
+			Width:      b.Dx(),
+			Height:     b.Dy(),
+		},
 	})
 }
diff --git a/third_party/gofrontend/libgo/go/image/gif/writer_test.go b/third_party/gofrontend/libgo/go/image/gif/writer_test.go
index 93306ff..db61a5c 100644
--- a/third_party/gofrontend/libgo/go/image/gif/writer_test.go
+++ b/third_party/gofrontend/libgo/go/image/gif/writer_test.go
@@ -8,10 +8,12 @@
 	"bytes"
 	"image"
 	"image/color"
+	"image/color/palette"
 	_ "image/png"
 	"io/ioutil"
 	"math/rand"
 	"os"
+	"reflect"
 	"testing"
 )
 
@@ -125,55 +127,317 @@
 	}
 }
 
+// palettesEqual reports whether two color.Palette values are equal, ignoring
+// any trailing opaque-black palette entries.
+func palettesEqual(p, q color.Palette) bool {
+	n := len(p)
+	if n > len(q) {
+		n = len(q)
+	}
+	for i := 0; i < n; i++ {
+		if p[i] != q[i] {
+			return false
+		}
+	}
+	for i := n; i < len(p); i++ {
+		r, g, b, a := p[i].RGBA()
+		if r != 0 || g != 0 || b != 0 || a != 0xffff {
+			return false
+		}
+	}
+	for i := n; i < len(q); i++ {
+		r, g, b, a := q[i].RGBA()
+		if r != 0 || g != 0 || b != 0 || a != 0xffff {
+			return false
+		}
+	}
+	return true
+}
+
 var frames = []string{
 	"../testdata/video-001.gif",
 	"../testdata/video-005.gray.gif",
 }
 
-func TestEncodeAll(t *testing.T) {
+func testEncodeAll(t *testing.T, go1Dot5Fields bool, useGlobalColorModel bool) {
+	const width, height = 150, 103
+
 	g0 := &GIF{
 		Image:     make([]*image.Paletted, len(frames)),
 		Delay:     make([]int, len(frames)),
 		LoopCount: 5,
 	}
 	for i, f := range frames {
-		m, err := readGIF(f)
+		g, err := readGIF(f)
 		if err != nil {
 			t.Fatal(f, err)
 		}
-		g0.Image[i] = m.Image[0]
+		m := g.Image[0]
+		if m.Bounds().Dx() != width || m.Bounds().Dy() != height {
+			t.Fatalf("frame %d had unexpected bounds: got %v, want width/height = %d/%d",
+				i, m.Bounds(), width, height)
+		}
+		g0.Image[i] = m
 	}
+	// The GIF.Disposal, GIF.Config and GIF.BackgroundIndex fields were added
+	// in Go 1.5. Valid Go 1.4 or earlier code should still produce valid GIFs.
+	//
+	// On the following line, color.Model is an interface type, and
+	// color.Palette is a concrete (slice) type.
+	globalColorModel, backgroundIndex := color.Model(color.Palette(nil)), uint8(0)
+	if useGlobalColorModel {
+		globalColorModel, backgroundIndex = color.Palette(palette.WebSafe), uint8(1)
+	}
+	if go1Dot5Fields {
+		g0.Disposal = make([]byte, len(g0.Image))
+		for i := range g0.Disposal {
+			g0.Disposal[i] = DisposalNone
+		}
+		g0.Config = image.Config{
+			ColorModel: globalColorModel,
+			Width:      width,
+			Height:     height,
+		}
+		g0.BackgroundIndex = backgroundIndex
+	}
+
 	var buf bytes.Buffer
 	if err := EncodeAll(&buf, g0); err != nil {
 		t.Fatal("EncodeAll:", err)
 	}
-	g1, err := DecodeAll(&buf)
+	encoded := buf.Bytes()
+	config, err := DecodeConfig(bytes.NewReader(encoded))
+	if err != nil {
+		t.Fatal("DecodeConfig:", err)
+	}
+	g1, err := DecodeAll(bytes.NewReader(encoded))
 	if err != nil {
 		t.Fatal("DecodeAll:", err)
 	}
+
+	if !reflect.DeepEqual(config, g1.Config) {
+		t.Errorf("DecodeConfig inconsistent with DecodeAll")
+	}
+	if !palettesEqual(g1.Config.ColorModel.(color.Palette), globalColorModel.(color.Palette)) {
+		t.Errorf("unexpected global color model")
+	}
+	if w, h := g1.Config.Width, g1.Config.Height; w != width || h != height {
+		t.Errorf("got config width * height = %d * %d, want %d * %d", w, h, width, height)
+	}
+
 	if g0.LoopCount != g1.LoopCount {
 		t.Errorf("loop counts differ: %d and %d", g0.LoopCount, g1.LoopCount)
 	}
+	if backgroundIndex != g1.BackgroundIndex {
+		t.Errorf("background indexes differ: %d and %d", backgroundIndex, g1.BackgroundIndex)
+	}
+	if len(g0.Image) != len(g1.Image) {
+		t.Fatalf("image lengths differ: %d and %d", len(g0.Image), len(g1.Image))
+	}
+	if len(g1.Image) != len(g1.Delay) {
+		t.Fatalf("image and delay lengths differ: %d and %d", len(g1.Image), len(g1.Delay))
+	}
+	if len(g1.Image) != len(g1.Disposal) {
+		t.Fatalf("image and disposal lengths differ: %d and %d", len(g1.Image), len(g1.Disposal))
+	}
+
 	for i := range g0.Image {
 		m0, m1 := g0.Image[i], g1.Image[i]
 		if m0.Bounds() != m1.Bounds() {
-			t.Errorf("%s, bounds differ: %v and %v", frames[i], m0.Bounds(), m1.Bounds())
+			t.Errorf("frame %d: bounds differ: %v and %v", i, m0.Bounds(), m1.Bounds())
 		}
 		d0, d1 := g0.Delay[i], g1.Delay[i]
 		if d0 != d1 {
-			t.Errorf("%s: delay values differ: %d and %d", frames[i], d0, d1)
+			t.Errorf("frame %d: delay values differ: %d and %d", i, d0, d1)
+		}
+		p0, p1 := uint8(0), g1.Disposal[i]
+		if go1Dot5Fields {
+			p0 = DisposalNone
+		}
+		if p0 != p1 {
+			t.Errorf("frame %d: disposal values differ: %d and %d", i, p0, p1)
 		}
 	}
+}
 
-	g1.Delay = make([]int, 1)
-	if err := EncodeAll(ioutil.Discard, g1); err == nil {
+func TestEncodeAllGo1Dot4(t *testing.T)                 { testEncodeAll(t, false, false) }
+func TestEncodeAllGo1Dot5(t *testing.T)                 { testEncodeAll(t, true, false) }
+func TestEncodeAllGo1Dot5GlobalColorModel(t *testing.T) { testEncodeAll(t, true, true) }
+
+func TestEncodeMismatchDelay(t *testing.T) {
+	images := make([]*image.Paletted, 2)
+	for i := range images {
+		images[i] = image.NewPaletted(image.Rect(0, 0, 5, 5), palette.Plan9)
+	}
+
+	g0 := &GIF{
+		Image: images,
+		Delay: make([]int, 1),
+	}
+	if err := EncodeAll(ioutil.Discard, g0); err == nil {
 		t.Error("expected error from mismatched delay and image slice lengths")
 	}
+
+	g1 := &GIF{
+		Image:    images,
+		Delay:    make([]int, len(images)),
+		Disposal: make([]byte, 1),
+	}
+	for i := range g1.Disposal {
+		g1.Disposal[i] = DisposalNone
+	}
+	if err := EncodeAll(ioutil.Discard, g1); err == nil {
+		t.Error("expected error from mismatched disposal and image slice lengths")
+	}
+}
+
+func TestEncodeZeroGIF(t *testing.T) {
 	if err := EncodeAll(ioutil.Discard, &GIF{}); err == nil {
 		t.Error("expected error from providing empty gif")
 	}
 }
 
+func TestEncodeAllFramesOutOfBounds(t *testing.T) {
+	images := []*image.Paletted{
+		image.NewPaletted(image.Rect(0, 0, 5, 5), palette.Plan9),
+		image.NewPaletted(image.Rect(2, 2, 8, 8), palette.Plan9),
+		image.NewPaletted(image.Rect(3, 3, 4, 4), palette.Plan9),
+	}
+	for _, upperBound := range []int{6, 10} {
+		g := &GIF{
+			Image:    images,
+			Delay:    make([]int, len(images)),
+			Disposal: make([]byte, len(images)),
+			Config: image.Config{
+				Width:  upperBound,
+				Height: upperBound,
+			},
+		}
+		err := EncodeAll(ioutil.Discard, g)
+		if upperBound >= 8 {
+			if err != nil {
+				t.Errorf("upperBound=%d: %v", upperBound, err)
+			}
+		} else {
+			if err == nil {
+				t.Errorf("upperBound=%d: got nil error, want non-nil", upperBound)
+			}
+		}
+	}
+}
+
+func TestEncodeNonZeroMinPoint(t *testing.T) {
+	points := []image.Point{
+		image.Point{-8, -9},
+		image.Point{-4, -4},
+		image.Point{-3, +3},
+		image.Point{+0, +0},
+		image.Point{+2, +2},
+	}
+	for _, p := range points {
+		src := image.NewPaletted(image.Rectangle{Min: p, Max: p.Add(image.Point{6, 6})}, palette.Plan9)
+		var buf bytes.Buffer
+		if err := Encode(&buf, src, nil); err != nil {
+			t.Errorf("p=%v: Encode: %v", p, err)
+			continue
+		}
+		m, err := Decode(&buf)
+		if err != nil {
+			t.Errorf("p=%v: Decode: %v", p, err)
+			continue
+		}
+		if got, want := m.Bounds(), image.Rect(0, 0, 6, 6); got != want {
+			t.Errorf("p=%v: got %v, want %v", p, got, want)
+		}
+	}
+}
+
+func TestEncodeImplicitConfigSize(t *testing.T) {
+	// For backwards compatibility for Go 1.4 and earlier code, the Config
+	// field is optional, and if zero, the width and height is implied by the
+	// first (and in this case only) frame's width and height.
+	//
+	// A Config only specifies a width and height (two integers) while an
+	// image.Image's Bounds method returns an image.Rectangle (four integers).
+	// For a gif.GIF, the overall bounds' top-left point is always implicitly
+	// (0, 0), and any frame whose bounds have a negative X or Y will be
+	// outside those overall bounds, so encoding should fail.
+	for _, lowerBound := range []int{-1, 0, 1} {
+		images := []*image.Paletted{
+			image.NewPaletted(image.Rect(lowerBound, lowerBound, 4, 4), palette.Plan9),
+		}
+		g := &GIF{
+			Image: images,
+			Delay: make([]int, len(images)),
+		}
+		err := EncodeAll(ioutil.Discard, g)
+		if lowerBound >= 0 {
+			if err != nil {
+				t.Errorf("lowerBound=%d: %v", lowerBound, err)
+			}
+		} else {
+			if err == nil {
+				t.Errorf("lowerBound=%d: got nil error, want non-nil", lowerBound)
+			}
+		}
+	}
+}
+
+func TestEncodePalettes(t *testing.T) {
+	const w, h = 5, 5
+	pals := []color.Palette{{
+		color.RGBA{0x00, 0x00, 0x00, 0xff},
+		color.RGBA{0x01, 0x00, 0x00, 0xff},
+		color.RGBA{0x02, 0x00, 0x00, 0xff},
+	}, {
+		color.RGBA{0x00, 0x00, 0x00, 0xff},
+		color.RGBA{0x00, 0x01, 0x00, 0xff},
+	}, {
+		color.RGBA{0x00, 0x00, 0x03, 0xff},
+		color.RGBA{0x00, 0x00, 0x02, 0xff},
+		color.RGBA{0x00, 0x00, 0x01, 0xff},
+		color.RGBA{0x00, 0x00, 0x00, 0xff},
+	}, {
+		color.RGBA{0x10, 0x07, 0xf0, 0xff},
+		color.RGBA{0x20, 0x07, 0xf0, 0xff},
+		color.RGBA{0x30, 0x07, 0xf0, 0xff},
+		color.RGBA{0x40, 0x07, 0xf0, 0xff},
+		color.RGBA{0x50, 0x07, 0xf0, 0xff},
+	}}
+	g0 := &GIF{
+		Image: []*image.Paletted{
+			image.NewPaletted(image.Rect(0, 0, w, h), pals[0]),
+			image.NewPaletted(image.Rect(0, 0, w, h), pals[1]),
+			image.NewPaletted(image.Rect(0, 0, w, h), pals[2]),
+			image.NewPaletted(image.Rect(0, 0, w, h), pals[3]),
+		},
+		Delay:    make([]int, len(pals)),
+		Disposal: make([]byte, len(pals)),
+		Config: image.Config{
+			ColorModel: pals[2],
+			Width:      w,
+			Height:     h,
+		},
+	}
+
+	var buf bytes.Buffer
+	if err := EncodeAll(&buf, g0); err != nil {
+		t.Fatalf("EncodeAll: %v", err)
+	}
+	g1, err := DecodeAll(&buf)
+	if err != nil {
+		t.Fatalf("DecodeAll: %v", err)
+	}
+	if len(g0.Image) != len(g1.Image) {
+		t.Fatalf("image lengths differ: %d and %d", len(g0.Image), len(g1.Image))
+	}
+	for i, m := range g1.Image {
+		if got, want := m.Palette, pals[i]; !palettesEqual(got, want) {
+			t.Errorf("frame %d:\ngot  %v\nwant %v", i, got, want)
+		}
+	}
+}
+
 func BenchmarkEncode(b *testing.B) {
 	b.StopTimer()
 
diff --git a/third_party/gofrontend/libgo/go/image/image.go b/third_party/gofrontend/libgo/go/image/image.go
index 6b8e5c4..20b64d7 100644
--- a/third_party/gofrontend/libgo/go/image/image.go
+++ b/third_party/gofrontend/libgo/go/image/image.go
@@ -18,7 +18,7 @@
 // initialization side effects.
 //
 // See "The Go image package" for more details:
-// http://golang.org/doc/articles/image_package.html
+// https://golang.org/doc/articles/image_package.html
 package image
 
 import (
@@ -46,9 +46,9 @@
 }
 
 // PalettedImage is an image whose colors may come from a limited palette.
-// If m is a PalettedImage and m.ColorModel() returns a PalettedColorModel p,
+// If m is a PalettedImage and m.ColorModel() returns a color.Palette p,
 // then m.At(x, y) should be equivalent to p[m.ColorIndexAt(x, y)]. If m's
-// color model is not a PalettedColorModel, then ColorIndexAt's behavior is
+// color model is not a color.Palette, then ColorIndexAt's behavior is
 // undefined.
 type PalettedImage interface {
 	// ColorIndexAt returns the palette index of the pixel at (x, y).
@@ -570,7 +570,7 @@
 	return &Alpha{pix, 1 * w, r}
 }
 
-// Alpha16 is an in-memory image whose At method returns color.Alpha64 values.
+// Alpha16 is an in-memory image whose At method returns color.Alpha16 values.
 type Alpha16 struct {
 	// Pix holds the image's pixels, as alpha values in big-endian format. The pixel at
 	// (x, y) starts at Pix[(y-Rect.Min.Y)*Stride + (x-Rect.Min.X)*2].
@@ -826,6 +826,92 @@
 	return &Gray16{pix, 2 * w, r}
 }
 
+// CMYK is an in-memory image whose At method returns color.CMYK values.
+type CMYK struct {
+	// Pix holds the image's pixels, in C, M, Y, K order. The pixel at
+	// (x, y) starts at Pix[(y-Rect.Min.Y)*Stride + (x-Rect.Min.X)*4].
+	Pix []uint8
+	// Stride is the Pix stride (in bytes) between vertically adjacent pixels.
+	Stride int
+	// Rect is the image's bounds.
+	Rect Rectangle
+}
+
+func (p *CMYK) ColorModel() color.Model { return color.CMYKModel }
+
+func (p *CMYK) Bounds() Rectangle { return p.Rect }
+
+func (p *CMYK) At(x, y int) color.Color {
+	return p.CMYKAt(x, y)
+}
+
+func (p *CMYK) CMYKAt(x, y int) color.CMYK {
+	if !(Point{x, y}.In(p.Rect)) {
+		return color.CMYK{}
+	}
+	i := p.PixOffset(x, y)
+	return color.CMYK{p.Pix[i+0], p.Pix[i+1], p.Pix[i+2], p.Pix[i+3]}
+}
+
+// PixOffset returns the index of the first element of Pix that corresponds to
+// the pixel at (x, y).
+func (p *CMYK) PixOffset(x, y int) int {
+	return (y-p.Rect.Min.Y)*p.Stride + (x-p.Rect.Min.X)*4
+}
+
+func (p *CMYK) Set(x, y int, c color.Color) {
+	if !(Point{x, y}.In(p.Rect)) {
+		return
+	}
+	i := p.PixOffset(x, y)
+	c1 := color.CMYKModel.Convert(c).(color.CMYK)
+	p.Pix[i+0] = c1.C
+	p.Pix[i+1] = c1.M
+	p.Pix[i+2] = c1.Y
+	p.Pix[i+3] = c1.K
+}
+
+func (p *CMYK) SetCMYK(x, y int, c color.CMYK) {
+	if !(Point{x, y}.In(p.Rect)) {
+		return
+	}
+	i := p.PixOffset(x, y)
+	p.Pix[i+0] = c.C
+	p.Pix[i+1] = c.M
+	p.Pix[i+2] = c.Y
+	p.Pix[i+3] = c.K
+}
+
+// SubImage returns an image representing the portion of the image p visible
+// through r. The returned value shares pixels with the original image.
+func (p *CMYK) SubImage(r Rectangle) Image {
+	r = r.Intersect(p.Rect)
+	// If r1 and r2 are Rectangles, r1.Intersect(r2) is not guaranteed to be inside
+	// either r1 or r2 if the intersection is empty. Without explicitly checking for
+	// this, the Pix[i:] expression below can panic.
+	if r.Empty() {
+		return &CMYK{}
+	}
+	i := p.PixOffset(r.Min.X, r.Min.Y)
+	return &CMYK{
+		Pix:    p.Pix[i:],
+		Stride: p.Stride,
+		Rect:   r,
+	}
+}
+
+// Opaque scans the entire image and reports whether it is fully opaque.
+func (p *CMYK) Opaque() bool {
+	return true
+}
+
+// NewCMYK returns a new CMYK with the given bounds.
+func NewCMYK(r Rectangle) *CMYK {
+	w, h := r.Dx(), r.Dy()
+	buf := make([]uint8, 4*w*h)
+	return &CMYK{buf, 4 * w, r}
+}
+
 // Paletted is an in-memory image of uint8 indices into a given palette.
 type Paletted struct {
 	// Pix holds the image's pixels, as palette indices. The pixel at
diff --git a/third_party/gofrontend/libgo/go/image/internal/imageutil/gen.go b/third_party/gofrontend/libgo/go/image/internal/imageutil/gen.go
new file mode 100644
index 0000000..fc1e707
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/image/internal/imageutil/gen.go
@@ -0,0 +1,154 @@
+// 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 ignore
+
+package main
+
+import (
+	"bytes"
+	"flag"
+	"fmt"
+	"go/format"
+	"io/ioutil"
+	"log"
+	"os"
+)
+
+var debug = flag.Bool("debug", false, "")
+
+func main() {
+	flag.Parse()
+
+	w := new(bytes.Buffer)
+	w.WriteString(pre)
+	for _, sratio := range subsampleRatios {
+		fmt.Fprintf(w, sratioCase, sratio, sratioLines[sratio])
+	}
+	w.WriteString(post)
+
+	if *debug {
+		os.Stdout.Write(w.Bytes())
+		return
+	}
+	out, err := format.Source(w.Bytes())
+	if err != nil {
+		log.Fatal(err)
+	}
+	if err := ioutil.WriteFile("impl.go", out, 0660); err != nil {
+		log.Fatal(err)
+	}
+}
+
+const pre = `// generated by "go run gen.go". DO NOT EDIT.
+
+package imageutil
+
+import (
+	"image"
+)
+
+// DrawYCbCr draws the YCbCr source image on the RGBA destination image with
+// r.Min in dst aligned with sp in src. It reports whether the draw was
+// successful. If it returns false, no dst pixels were changed.
+//
+// This function assumes that r is entirely within dst's bounds and the
+// translation of r from dst coordinate space to src coordinate space is
+// entirely within src's bounds.
+func DrawYCbCr(dst *image.RGBA, r image.Rectangle, src *image.YCbCr, sp image.Point) (ok bool) {
+	// This function exists in the image/internal/imageutil package because it
+	// is needed by both the image/draw and image/jpeg packages, but it doesn't
+	// seem right for one of those two to depend on the other.
+	//
+	// Another option is to have this code be exported in the image package,
+	// but we'd need to make sure we're totally happy with the API (for the
+	// rest of Go 1 compatibility), and decide if we want to have a more
+	// general purpose DrawToRGBA method for other image types. One possibility
+	// is:
+	//
+	// func (src *YCbCr) CopyToRGBA(dst *RGBA, dr, sr Rectangle) (effectiveDr, effectiveSr Rectangle)
+	//
+	// in the spirit of the built-in copy function for 1-dimensional slices,
+	// that also allowed a CopyFromRGBA method if needed.
+
+	x0 := (r.Min.X - dst.Rect.Min.X) * 4
+	x1 := (r.Max.X - dst.Rect.Min.X) * 4
+	y0 := r.Min.Y - dst.Rect.Min.Y
+	y1 := r.Max.Y - dst.Rect.Min.Y
+	switch src.SubsampleRatio {
+`
+
+const post = `
+	default:
+		return false
+	}
+	return true
+}
+`
+
+const sratioCase = `
+	case image.YCbCrSubsampleRatio%s:
+		for y, sy := y0, sp.Y; y != y1; y, sy = y+1, sy+1 {
+			dpix := dst.Pix[y*dst.Stride:]
+			yi := (sy-src.Rect.Min.Y)*src.YStride + (sp.X - src.Rect.Min.X)
+			%s
+
+				// This is an inline version of image/color/ycbcr.go's func YCbCrToRGB.
+				yy1 := int32(src.Y[yi]) * 0x10100 // Convert 0x12 to 0x121200.
+				cb1 := int32(src.Cb[ci]) - 128
+				cr1 := int32(src.Cr[ci]) - 128
+				r := (yy1 + 91881*cr1) >> 16
+				g := (yy1 - 22554*cb1 - 46802*cr1) >> 16
+				b := (yy1 + 116130*cb1) >> 16
+				if r < 0 {
+					r = 0
+				} else if r > 255 {
+					r = 255
+				}
+				if g < 0 {
+					g = 0
+				} else if g > 255 {
+					g = 255
+				}
+				if b < 0 {
+					b = 0
+				} else if b > 255 {
+					b = 255
+				}
+
+				dpix[x+0] = uint8(r)
+				dpix[x+1] = uint8(g)
+				dpix[x+2] = uint8(b)
+				dpix[x+3] = 255
+			}
+		}
+`
+
+var subsampleRatios = []string{
+	"444",
+	"422",
+	"420",
+	"440",
+}
+
+var sratioLines = map[string]string{
+	"444": `
+		ci := (sy-src.Rect.Min.Y)*src.CStride + (sp.X - src.Rect.Min.X)
+		for x := x0; x != x1; x, yi, ci = x+4, yi+1, ci+1 {
+	`,
+	"422": `
+		ciBase := (sy-src.Rect.Min.Y)*src.CStride - src.Rect.Min.X/2
+		for x, sx := x0, sp.X; x != x1; x, sx, yi = x+4, sx+1, yi+1 {
+			ci := ciBase + sx/2
+	`,
+	"420": `
+		ciBase := (sy/2-src.Rect.Min.Y/2)*src.CStride - src.Rect.Min.X/2
+		for x, sx := x0, sp.X; x != x1; x, sx, yi = x+4, sx+1, yi+1 {
+			ci := ciBase + sx/2
+	`,
+	"440": `
+		ci := (sy/2-src.Rect.Min.Y/2)*src.CStride + (sp.X - src.Rect.Min.X)
+		for x := x0; x != x1; x, yi, ci = x+4, yi+1, ci+1 {
+	`,
+}
diff --git a/third_party/gofrontend/libgo/go/image/internal/imageutil/imageutil.go b/third_party/gofrontend/libgo/go/image/internal/imageutil/imageutil.go
new file mode 100644
index 0000000..10cef0c
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/image/internal/imageutil/imageutil.go
@@ -0,0 +1,8 @@
+// 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.
+
+//go:generate go run gen.go
+
+// Package imageutil contains code shared by image-related packages.
+package imageutil
diff --git a/third_party/gofrontend/libgo/go/image/internal/imageutil/impl.go b/third_party/gofrontend/libgo/go/image/internal/imageutil/impl.go
new file mode 100644
index 0000000..fd7826d
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/image/internal/imageutil/impl.go
@@ -0,0 +1,196 @@
+// generated by "go run gen.go". DO NOT EDIT.
+
+package imageutil
+
+import (
+	"image"
+)
+
+// DrawYCbCr draws the YCbCr source image on the RGBA destination image with
+// r.Min in dst aligned with sp in src. It reports whether the draw was
+// successful. If it returns false, no dst pixels were changed.
+//
+// This function assumes that r is entirely within dst's bounds and the
+// translation of r from dst coordinate space to src coordinate space is
+// entirely within src's bounds.
+func DrawYCbCr(dst *image.RGBA, r image.Rectangle, src *image.YCbCr, sp image.Point) (ok bool) {
+	// This function exists in the image/internal/imageutil package because it
+	// is needed by both the image/draw and image/jpeg packages, but it doesn't
+	// seem right for one of those two to depend on the other.
+	//
+	// Another option is to have this code be exported in the image package,
+	// but we'd need to make sure we're totally happy with the API (for the
+	// rest of Go 1 compatibility), and decide if we want to have a more
+	// general purpose DrawToRGBA method for other image types. One possibility
+	// is:
+	//
+	// func (src *YCbCr) CopyToRGBA(dst *RGBA, dr, sr Rectangle) (effectiveDr, effectiveSr Rectangle)
+	//
+	// in the spirit of the built-in copy function for 1-dimensional slices,
+	// that also allowed a CopyFromRGBA method if needed.
+
+	x0 := (r.Min.X - dst.Rect.Min.X) * 4
+	x1 := (r.Max.X - dst.Rect.Min.X) * 4
+	y0 := r.Min.Y - dst.Rect.Min.Y
+	y1 := r.Max.Y - dst.Rect.Min.Y
+	switch src.SubsampleRatio {
+
+	case image.YCbCrSubsampleRatio444:
+		for y, sy := y0, sp.Y; y != y1; y, sy = y+1, sy+1 {
+			dpix := dst.Pix[y*dst.Stride:]
+			yi := (sy-src.Rect.Min.Y)*src.YStride + (sp.X - src.Rect.Min.X)
+
+			ci := (sy-src.Rect.Min.Y)*src.CStride + (sp.X - src.Rect.Min.X)
+			for x := x0; x != x1; x, yi, ci = x+4, yi+1, ci+1 {
+
+				// This is an inline version of image/color/ycbcr.go's func YCbCrToRGB.
+				yy1 := int32(src.Y[yi]) * 0x10100 // Convert 0x12 to 0x121200.
+				cb1 := int32(src.Cb[ci]) - 128
+				cr1 := int32(src.Cr[ci]) - 128
+				r := (yy1 + 91881*cr1) >> 16
+				g := (yy1 - 22554*cb1 - 46802*cr1) >> 16
+				b := (yy1 + 116130*cb1) >> 16
+				if r < 0 {
+					r = 0
+				} else if r > 255 {
+					r = 255
+				}
+				if g < 0 {
+					g = 0
+				} else if g > 255 {
+					g = 255
+				}
+				if b < 0 {
+					b = 0
+				} else if b > 255 {
+					b = 255
+				}
+
+				dpix[x+0] = uint8(r)
+				dpix[x+1] = uint8(g)
+				dpix[x+2] = uint8(b)
+				dpix[x+3] = 255
+			}
+		}
+
+	case image.YCbCrSubsampleRatio422:
+		for y, sy := y0, sp.Y; y != y1; y, sy = y+1, sy+1 {
+			dpix := dst.Pix[y*dst.Stride:]
+			yi := (sy-src.Rect.Min.Y)*src.YStride + (sp.X - src.Rect.Min.X)
+
+			ciBase := (sy-src.Rect.Min.Y)*src.CStride - src.Rect.Min.X/2
+			for x, sx := x0, sp.X; x != x1; x, sx, yi = x+4, sx+1, yi+1 {
+				ci := ciBase + sx/2
+
+				// This is an inline version of image/color/ycbcr.go's func YCbCrToRGB.
+				yy1 := int32(src.Y[yi]) * 0x10100 // Convert 0x12 to 0x121200.
+				cb1 := int32(src.Cb[ci]) - 128
+				cr1 := int32(src.Cr[ci]) - 128
+				r := (yy1 + 91881*cr1) >> 16
+				g := (yy1 - 22554*cb1 - 46802*cr1) >> 16
+				b := (yy1 + 116130*cb1) >> 16
+				if r < 0 {
+					r = 0
+				} else if r > 255 {
+					r = 255
+				}
+				if g < 0 {
+					g = 0
+				} else if g > 255 {
+					g = 255
+				}
+				if b < 0 {
+					b = 0
+				} else if b > 255 {
+					b = 255
+				}
+
+				dpix[x+0] = uint8(r)
+				dpix[x+1] = uint8(g)
+				dpix[x+2] = uint8(b)
+				dpix[x+3] = 255
+			}
+		}
+
+	case image.YCbCrSubsampleRatio420:
+		for y, sy := y0, sp.Y; y != y1; y, sy = y+1, sy+1 {
+			dpix := dst.Pix[y*dst.Stride:]
+			yi := (sy-src.Rect.Min.Y)*src.YStride + (sp.X - src.Rect.Min.X)
+
+			ciBase := (sy/2-src.Rect.Min.Y/2)*src.CStride - src.Rect.Min.X/2
+			for x, sx := x0, sp.X; x != x1; x, sx, yi = x+4, sx+1, yi+1 {
+				ci := ciBase + sx/2
+
+				// This is an inline version of image/color/ycbcr.go's func YCbCrToRGB.
+				yy1 := int32(src.Y[yi]) * 0x10100 // Convert 0x12 to 0x121200.
+				cb1 := int32(src.Cb[ci]) - 128
+				cr1 := int32(src.Cr[ci]) - 128
+				r := (yy1 + 91881*cr1) >> 16
+				g := (yy1 - 22554*cb1 - 46802*cr1) >> 16
+				b := (yy1 + 116130*cb1) >> 16
+				if r < 0 {
+					r = 0
+				} else if r > 255 {
+					r = 255
+				}
+				if g < 0 {
+					g = 0
+				} else if g > 255 {
+					g = 255
+				}
+				if b < 0 {
+					b = 0
+				} else if b > 255 {
+					b = 255
+				}
+
+				dpix[x+0] = uint8(r)
+				dpix[x+1] = uint8(g)
+				dpix[x+2] = uint8(b)
+				dpix[x+3] = 255
+			}
+		}
+
+	case image.YCbCrSubsampleRatio440:
+		for y, sy := y0, sp.Y; y != y1; y, sy = y+1, sy+1 {
+			dpix := dst.Pix[y*dst.Stride:]
+			yi := (sy-src.Rect.Min.Y)*src.YStride + (sp.X - src.Rect.Min.X)
+
+			ci := (sy/2-src.Rect.Min.Y/2)*src.CStride + (sp.X - src.Rect.Min.X)
+			for x := x0; x != x1; x, yi, ci = x+4, yi+1, ci+1 {
+
+				// This is an inline version of image/color/ycbcr.go's func YCbCrToRGB.
+				yy1 := int32(src.Y[yi]) * 0x10100 // Convert 0x12 to 0x121200.
+				cb1 := int32(src.Cb[ci]) - 128
+				cr1 := int32(src.Cr[ci]) - 128
+				r := (yy1 + 91881*cr1) >> 16
+				g := (yy1 - 22554*cb1 - 46802*cr1) >> 16
+				b := (yy1 + 116130*cb1) >> 16
+				if r < 0 {
+					r = 0
+				} else if r > 255 {
+					r = 255
+				}
+				if g < 0 {
+					g = 0
+				} else if g > 255 {
+					g = 255
+				}
+				if b < 0 {
+					b = 0
+				} else if b > 255 {
+					b = 255
+				}
+
+				dpix[x+0] = uint8(r)
+				dpix[x+1] = uint8(g)
+				dpix[x+2] = uint8(b)
+				dpix[x+3] = 255
+			}
+		}
+
+	default:
+		return false
+	}
+	return true
+}
diff --git a/third_party/gofrontend/libgo/go/image/jpeg/huffman.go b/third_party/gofrontend/libgo/go/image/jpeg/huffman.go
index d4ff4cf..4f8fe8e 100644
--- a/third_party/gofrontend/libgo/go/image/jpeg/huffman.go
+++ b/third_party/gofrontend/libgo/go/image/jpeg/huffman.go
@@ -187,7 +187,9 @@
 			// There are no more bytes of data in this segment, but we may still
 			// be able to read the next symbol out of the previously read bits.
 			// First, undo the readByte that the ensureNBits call made.
-			d.unreadByteStuffedByte()
+			if d.bytes.nUnreadable != 0 {
+				d.unreadByteStuffedByte()
+			}
 			goto slowPath
 		}
 	}
diff --git a/third_party/gofrontend/libgo/go/image/jpeg/reader.go b/third_party/gofrontend/libgo/go/image/jpeg/reader.go
index 6d8b1d1..adf97ab 100644
--- a/third_party/gofrontend/libgo/go/image/jpeg/reader.go
+++ b/third_party/gofrontend/libgo/go/image/jpeg/reader.go
@@ -10,6 +10,7 @@
 import (
 	"image"
 	"image/color"
+	"image/internal/imageutil"
 	"io"
 )
 
@@ -26,6 +27,8 @@
 
 func (e UnsupportedError) Error() string { return "unsupported JPEG feature: " + string(e) }
 
+var errUnsupportedSubsamplingRatio = UnsupportedError("luma/chroma subsampling ratio")
+
 // Component specification, specified in section B.2.2.
 type component struct {
 	h  int   // Horizontal sampling factor.
@@ -41,32 +44,35 @@
 	maxTh   = 3
 	maxTq   = 3
 
-	// A grayscale JPEG image has only a Y component.
-	nGrayComponent = 1
-	// A color JPEG image has Y, Cb and Cr components.
-	nColorComponent = 3
-
-	// We only support 4:4:4, 4:4:0, 4:2:2 and 4:2:0 downsampling, and therefore the
-	// number of luma samples per chroma sample is at most 2 in the horizontal
-	// and 2 in the vertical direction.
-	maxH = 2
-	maxV = 2
+	maxComponents = 4
 )
 
 const (
-	soiMarker   = 0xd8 // Start Of Image.
-	eoiMarker   = 0xd9 // End Of Image.
-	sof0Marker  = 0xc0 // Start Of Frame (Baseline).
-	sof2Marker  = 0xc2 // Start Of Frame (Progressive).
-	dhtMarker   = 0xc4 // Define Huffman Table.
-	dqtMarker   = 0xdb // Define Quantization Table.
-	sosMarker   = 0xda // Start Of Scan.
-	driMarker   = 0xdd // Define Restart Interval.
-	rst0Marker  = 0xd0 // ReSTart (0).
-	rst7Marker  = 0xd7 // ReSTart (7).
-	app0Marker  = 0xe0 // APPlication specific (0).
-	app15Marker = 0xef // APPlication specific (15).
-	comMarker   = 0xfe // COMment.
+	sof0Marker = 0xc0 // Start Of Frame (Baseline).
+	sof1Marker = 0xc1 // Start Of Frame (Extended Sequential).
+	sof2Marker = 0xc2 // Start Of Frame (Progressive).
+	dhtMarker  = 0xc4 // Define Huffman Table.
+	rst0Marker = 0xd0 // ReSTart (0).
+	rst7Marker = 0xd7 // ReSTart (7).
+	soiMarker  = 0xd8 // Start Of Image.
+	eoiMarker  = 0xd9 // End Of Image.
+	sosMarker  = 0xda // Start Of Scan.
+	dqtMarker  = 0xdb // Define Quantization Table.
+	driMarker  = 0xdd // Define Restart Interval.
+	comMarker  = 0xfe // COMment.
+	// "APPlication specific" markers aren't part of the JPEG spec per se,
+	// but in practice, their use is described at
+	// http://www.sno.phy.queensu.ca/~phil/exiftool/TagNames/JPEG.html
+	app0Marker  = 0xe0
+	app14Marker = 0xee
+	app15Marker = 0xef
+)
+
+// See http://www.sno.phy.queensu.ca/~phil/exiftool/TagNames/JPEG.html#Adobe
+const (
+	adobeTransformUnknown = 0
+	adobeTransformYCbCr   = 1
+	adobeTransformYCbCrK  = 2
 )
 
 // unzig maps from the zig-zag ordering to the natural ordering. For example,
@@ -83,7 +89,7 @@
 	53, 60, 61, 54, 47, 55, 62, 63,
 }
 
-// Reader is deprecated.
+// Deprecated: Reader is deprecated.
 type Reader interface {
 	io.ByteReader
 	io.Reader
@@ -114,17 +120,25 @@
 		nUnreadable int
 	}
 	width, height int
-	img1          *image.Gray
-	img3          *image.YCbCr
-	ri            int // Restart Interval.
-	nComp         int
-	progressive   bool
-	eobRun        uint16 // End-of-Band run, specified in section G.1.2.2.
-	comp          [nColorComponent]component
-	progCoeffs    [nColorComponent][]block // Saved state between progressive-mode scans.
-	huff          [maxTc + 1][maxTh + 1]huffman
-	quant         [maxTq + 1]block // Quantization tables, in zig-zag order.
-	tmp           [blockSize + 1]byte
+
+	img1        *image.Gray
+	img3        *image.YCbCr
+	blackPix    []byte
+	blackStride int
+
+	ri                  int // Restart Interval.
+	nComp               int
+	progressive         bool
+	jfif                bool
+	adobeTransformValid bool
+	adobeTransform      uint8
+	eobRun              uint16 // End-of-Band run, specified in section G.1.2.2.
+
+	comp       [maxComponents]component
+	progCoeffs [maxComponents][]block // Saved state between progressive-mode scans.
+	huff       [maxTc + 1][maxTh + 1]huffman
+	quant      [maxTq + 1]block // Quantization tables, in zig-zag order.
+	tmp        [2 * blockSize]byte
 }
 
 // fill fills up the d.bytes.buf buffer from the underlying io.Reader. It
@@ -155,9 +169,6 @@
 // sometimes overshoot and read one or two too many bytes. Two-byte overshoot
 // can happen when expecting to read a 0xff 0x00 byte-stuffed byte.
 func (d *decoder) unreadByteStuffedByte() {
-	if d.bytes.nUnreadable == 0 {
-		panic("jpeg: unreadByteStuffedByte call cannot be fulfilled")
-	}
 	d.bytes.i -= d.bytes.nUnreadable
 	d.bytes.nUnreadable = 0
 	if d.bits.n >= 8 {
@@ -203,18 +214,19 @@
 		return 0xff, nil
 	}
 
+	d.bytes.nUnreadable = 0
+
 	x, err = d.readByte()
 	if err != nil {
 		return 0, err
 	}
+	d.bytes.nUnreadable = 1
 	if x != 0xff {
-		d.bytes.nUnreadable = 1
 		return x, nil
 	}
 
 	x, err = d.readByte()
 	if err != nil {
-		d.bytes.nUnreadable = 1
 		return 0, err
 	}
 	d.bytes.nUnreadable = 2
@@ -284,13 +296,18 @@
 
 // Specified in section B.2.2.
 func (d *decoder) processSOF(n int) error {
+	if d.nComp != 0 {
+		return FormatError("multiple SOF markers")
+	}
 	switch n {
-	case 6 + 3*nGrayComponent:
-		d.nComp = nGrayComponent
-	case 6 + 3*nColorComponent:
-		d.nComp = nColorComponent
+	case 6 + 3*1: // Grayscale image.
+		d.nComp = 1
+	case 6 + 3*3: // YCbCr or RGB image.
+		d.nComp = 3
+	case 6 + 3*4: // YCbCrK or CMYK image.
+		d.nComp = 4
 	default:
-		return UnsupportedError("SOF has wrong length")
+		return UnsupportedError("number of components")
 	}
 	if err := d.readFull(d.tmp[:n]); err != nil {
 		return err
@@ -302,12 +319,34 @@
 	d.height = int(d.tmp[1])<<8 + int(d.tmp[2])
 	d.width = int(d.tmp[3])<<8 + int(d.tmp[4])
 	if int(d.tmp[5]) != d.nComp {
-		return UnsupportedError("SOF has wrong number of image components")
+		return FormatError("SOF has wrong length")
 	}
+
 	for i := 0; i < d.nComp; i++ {
 		d.comp[i].c = d.tmp[6+3*i]
+		// Section B.2.2 states that "the value of C_i shall be different from
+		// the values of C_1 through C_(i-1)".
+		for j := 0; j < i; j++ {
+			if d.comp[i].c == d.comp[j].c {
+				return FormatError("repeated component identifier")
+			}
+		}
+
 		d.comp[i].tq = d.tmp[8+3*i]
-		if d.nComp == nGrayComponent {
+		if d.comp[i].tq > maxTq {
+			return FormatError("bad Tq value")
+		}
+
+		hv := d.tmp[7+3*i]
+		h, v := int(hv>>4), int(hv&0x0f)
+		if h < 1 || 4 < h || v < 1 || 4 < v {
+			return FormatError("luma/chroma subsampling ratio")
+		}
+		if h == 3 || v == 3 {
+			return errUnsupportedSubsamplingRatio
+		}
+		switch d.nComp {
+		case 1:
 			// If a JPEG image has only one component, section A.2 says "this data
 			// is non-interleaved by definition" and section A.2.2 says "[in this
 			// case...] the order of data units within a scan shall be left-to-right
@@ -319,45 +358,104 @@
 			// always 1. The component's (h, v) is effectively always (1, 1): even if
 			// the nominal (h, v) is (2, 1), a 20x5 image is encoded in three 8x8
 			// MCUs, not two 16x8 MCUs.
-			d.comp[i].h = 1
-			d.comp[i].v = 1
-			continue
-		}
-		hv := d.tmp[7+3*i]
-		d.comp[i].h = int(hv >> 4)
-		d.comp[i].v = int(hv & 0x0f)
-		// For color images, we only support 4:4:4, 4:4:0, 4:2:2 or 4:2:0 chroma
-		// downsampling ratios. This implies that the (h, v) values for the Y
-		// component are either (1, 1), (1, 2), (2, 1) or (2, 2), and the (h, v)
-		// values for the Cr and Cb components must be (1, 1).
-		if i == 0 {
-			if hv != 0x11 && hv != 0x21 && hv != 0x22 && hv != 0x12 {
-				return UnsupportedError("luma/chroma downsample ratio")
+			h, v = 1, 1
+
+		case 3:
+			// For YCbCr images, we only support 4:4:4, 4:4:0, 4:2:2, 4:2:0,
+			// 4:1:1 or 4:1:0 chroma subsampling ratios. This implies that the
+			// (h, v) values for the Y component are either (1, 1), (1, 2),
+			// (2, 1), (2, 2), (4, 1) or (4, 2), and the Y component's values
+			// must be a multiple of the Cb and Cr component's values. We also
+			// assume that the two chroma components have the same subsampling
+			// ratio.
+			switch i {
+			case 0: // Y.
+				// We have already verified, above, that h and v are both
+				// either 1, 2 or 4, so invalid (h, v) combinations are those
+				// with v == 4.
+				if v == 4 {
+					return errUnsupportedSubsamplingRatio
+				}
+			case 1: // Cb.
+				if d.comp[0].h%h != 0 || d.comp[0].v%v != 0 {
+					return errUnsupportedSubsamplingRatio
+				}
+			case 2: // Cr.
+				if d.comp[1].h != h || d.comp[1].v != v {
+					return errUnsupportedSubsamplingRatio
+				}
 			}
-		} else if hv != 0x11 {
-			return UnsupportedError("luma/chroma downsample ratio")
+
+		case 4:
+			// For 4-component images (either CMYK or YCbCrK), we only support two
+			// hv vectors: [0x11 0x11 0x11 0x11] and [0x22 0x11 0x11 0x22].
+			// Theoretically, 4-component JPEG images could mix and match hv values
+			// but in practice, those two combinations are the only ones in use,
+			// and it simplifies the applyBlack code below if we can assume that:
+			//	- for CMYK, the C and K channels have full samples, and if the M
+			//	  and Y channels subsample, they subsample both horizontally and
+			//	  vertically.
+			//	- for YCbCrK, the Y and K channels have full samples.
+			switch i {
+			case 0:
+				if hv != 0x11 && hv != 0x22 {
+					return errUnsupportedSubsamplingRatio
+				}
+			case 1, 2:
+				if hv != 0x11 {
+					return errUnsupportedSubsamplingRatio
+				}
+			case 3:
+				if d.comp[0].h != h || d.comp[0].v != v {
+					return errUnsupportedSubsamplingRatio
+				}
+			}
 		}
+
+		d.comp[i].h = h
+		d.comp[i].v = v
 	}
 	return nil
 }
 
 // Specified in section B.2.4.1.
 func (d *decoder) processDQT(n int) error {
-	const qtLength = 1 + blockSize
-	for ; n >= qtLength; n -= qtLength {
-		if err := d.readFull(d.tmp[:qtLength]); err != nil {
+loop:
+	for n > 0 {
+		n--
+		x, err := d.readByte()
+		if err != nil {
 			return err
 		}
-		pq := d.tmp[0] >> 4
-		if pq != 0 {
-			return UnsupportedError("bad Pq value")
-		}
-		tq := d.tmp[0] & 0x0f
+		tq := x & 0x0f
 		if tq > maxTq {
 			return FormatError("bad Tq value")
 		}
-		for i := range d.quant[tq] {
-			d.quant[tq][i] = int32(d.tmp[i+1])
+		switch x >> 4 {
+		default:
+			return FormatError("bad Pq value")
+		case 0:
+			if n < blockSize {
+				break loop
+			}
+			n -= blockSize
+			if err := d.readFull(d.tmp[:blockSize]); err != nil {
+				return err
+			}
+			for i := range d.quant[tq] {
+				d.quant[tq][i] = int32(d.tmp[i])
+			}
+		case 1:
+			if n < 2*blockSize {
+				break loop
+			}
+			n -= 2 * blockSize
+			if err := d.readFull(d.tmp[:2*blockSize]); err != nil {
+				return err
+			}
+			for i := range d.quant[tq] {
+				d.quant[tq][i] = int32(d.tmp[2*i])<<8 | int32(d.tmp[2*i+1])
+			}
 		}
 	}
 	if n != 0 {
@@ -378,6 +476,43 @@
 	return nil
 }
 
+func (d *decoder) processApp0Marker(n int) error {
+	if n < 5 {
+		return d.ignore(n)
+	}
+	if err := d.readFull(d.tmp[:5]); err != nil {
+		return err
+	}
+	n -= 5
+
+	d.jfif = d.tmp[0] == 'J' && d.tmp[1] == 'F' && d.tmp[2] == 'I' && d.tmp[3] == 'F' && d.tmp[4] == '\x00'
+
+	if n > 0 {
+		return d.ignore(n)
+	}
+	return nil
+}
+
+func (d *decoder) processApp14Marker(n int) error {
+	if n < 12 {
+		return d.ignore(n)
+	}
+	if err := d.readFull(d.tmp[:12]); err != nil {
+		return err
+	}
+	n -= 12
+
+	if d.tmp[0] == 'A' && d.tmp[1] == 'd' && d.tmp[2] == 'o' && d.tmp[3] == 'b' && d.tmp[4] == 'e' {
+		d.adobeTransformValid = true
+		d.adobeTransform = d.tmp[11]
+	}
+
+	if n > 0 {
+		return d.ignore(n)
+	}
+	return nil
+}
+
 // decode reads a JPEG image from r and returns it as an image.Image.
 func (d *decoder) decode(r io.Reader, configOnly bool) (image.Image, error) {
 	d.r = r
@@ -459,25 +594,48 @@
 			return nil, FormatError("short segment length")
 		}
 
-		switch {
-		case marker == sof0Marker || marker == sof2Marker: // Start Of Frame.
+		switch marker {
+		case sof0Marker, sof1Marker, sof2Marker:
 			d.progressive = marker == sof2Marker
 			err = d.processSOF(n)
-			if configOnly {
+			if configOnly && d.jfif {
 				return nil, err
 			}
-		case marker == dhtMarker: // Define Huffman Table.
-			err = d.processDHT(n)
-		case marker == dqtMarker: // Define Quantization Table.
-			err = d.processDQT(n)
-		case marker == sosMarker: // Start Of Scan.
+		case dhtMarker:
+			if configOnly {
+				err = d.ignore(n)
+			} else {
+				err = d.processDHT(n)
+			}
+		case dqtMarker:
+			if configOnly {
+				err = d.ignore(n)
+			} else {
+				err = d.processDQT(n)
+			}
+		case sosMarker:
+			if configOnly {
+				return nil, nil
+			}
 			err = d.processSOS(n)
-		case marker == driMarker: // Define Restart Interval.
-			err = d.processDRI(n)
-		case app0Marker <= marker && marker <= app15Marker || marker == comMarker: // APPlication specific, or COMment.
-			err = d.ignore(n)
+		case driMarker:
+			if configOnly {
+				err = d.ignore(n)
+			} else {
+				err = d.processDRI(n)
+			}
+		case app0Marker:
+			err = d.processApp0Marker(n)
+		case app14Marker:
+			err = d.processApp14Marker(n)
 		default:
-			err = UnsupportedError("unknown marker")
+			if app0Marker <= marker && marker <= app15Marker || marker == comMarker {
+				err = d.ignore(n)
+			} else if marker < 0xc0 { // See Table B.1 "Marker code assignments".
+				err = FormatError("unknown marker")
+			} else {
+				err = UnsupportedError("unknown marker")
+			}
 		}
 		if err != nil {
 			return nil, err
@@ -487,11 +645,118 @@
 		return d.img1, nil
 	}
 	if d.img3 != nil {
+		if d.blackPix != nil {
+			return d.applyBlack()
+		} else if d.isRGB() {
+			return d.convertToRGB()
+		}
 		return d.img3, nil
 	}
 	return nil, FormatError("missing SOS marker")
 }
 
+// applyBlack combines d.img3 and d.blackPix into a CMYK image. The formula
+// used depends on whether the JPEG image is stored as CMYK or YCbCrK,
+// indicated by the APP14 (Adobe) metadata.
+//
+// Adobe CMYK JPEG images are inverted, where 255 means no ink instead of full
+// ink, so we apply "v = 255 - v" at various points. Note that a double
+// inversion is a no-op, so inversions might be implicit in the code below.
+func (d *decoder) applyBlack() (image.Image, error) {
+	if !d.adobeTransformValid {
+		return nil, UnsupportedError("unknown color model: 4-component JPEG doesn't have Adobe APP14 metadata")
+	}
+
+	// If the 4-component JPEG image isn't explicitly marked as "Unknown (RGB
+	// or CMYK)" as per
+	// http://www.sno.phy.queensu.ca/~phil/exiftool/TagNames/JPEG.html#Adobe
+	// we assume that it is YCbCrK. This matches libjpeg's jdapimin.c.
+	if d.adobeTransform != adobeTransformUnknown {
+		// Convert the YCbCr part of the YCbCrK to RGB, invert the RGB to get
+		// CMY, and patch in the original K. The RGB to CMY inversion cancels
+		// out the 'Adobe inversion' described in the applyBlack doc comment
+		// above, so in practice, only the fourth channel (black) is inverted.
+		bounds := d.img3.Bounds()
+		img := image.NewRGBA(bounds)
+		imageutil.DrawYCbCr(img, bounds, d.img3, bounds.Min)
+		for iBase, y := 0, bounds.Min.Y; y < bounds.Max.Y; iBase, y = iBase+img.Stride, y+1 {
+			for i, x := iBase+3, bounds.Min.X; x < bounds.Max.X; i, x = i+4, x+1 {
+				img.Pix[i] = 255 - d.blackPix[(y-bounds.Min.Y)*d.blackStride+(x-bounds.Min.X)]
+			}
+		}
+		return &image.CMYK{
+			Pix:    img.Pix,
+			Stride: img.Stride,
+			Rect:   img.Rect,
+		}, nil
+	}
+
+	// The first three channels (cyan, magenta, yellow) of the CMYK
+	// were decoded into d.img3, but each channel was decoded into a separate
+	// []byte slice, and some channels may be subsampled. We interleave the
+	// separate channels into an image.CMYK's single []byte slice containing 4
+	// contiguous bytes per pixel.
+	bounds := d.img3.Bounds()
+	img := image.NewCMYK(bounds)
+
+	translations := [4]struct {
+		src    []byte
+		stride int
+	}{
+		{d.img3.Y, d.img3.YStride},
+		{d.img3.Cb, d.img3.CStride},
+		{d.img3.Cr, d.img3.CStride},
+		{d.blackPix, d.blackStride},
+	}
+	for t, translation := range translations {
+		subsample := d.comp[t].h != d.comp[0].h || d.comp[t].v != d.comp[0].v
+		for iBase, y := 0, bounds.Min.Y; y < bounds.Max.Y; iBase, y = iBase+img.Stride, y+1 {
+			sy := y - bounds.Min.Y
+			if subsample {
+				sy /= 2
+			}
+			for i, x := iBase+t, bounds.Min.X; x < bounds.Max.X; i, x = i+4, x+1 {
+				sx := x - bounds.Min.X
+				if subsample {
+					sx /= 2
+				}
+				img.Pix[i] = 255 - translation.src[sy*translation.stride+sx]
+			}
+		}
+	}
+	return img, nil
+}
+
+func (d *decoder) isRGB() bool {
+	if d.jfif {
+		return false
+	}
+	if d.adobeTransformValid && d.adobeTransform == adobeTransformUnknown {
+		// http://www.sno.phy.queensu.ca/~phil/exiftool/TagNames/JPEG.html#Adobe
+		// says that 0 means Unknown (and in practice RGB) and 1 means YCbCr.
+		return true
+	}
+	return d.comp[0].c == 'R' && d.comp[1].c == 'G' && d.comp[2].c == 'B'
+}
+
+func (d *decoder) convertToRGB() (image.Image, error) {
+	cScale := d.comp[0].h / d.comp[1].h
+	bounds := d.img3.Bounds()
+	img := image.NewRGBA(bounds)
+	for y := bounds.Min.Y; y < bounds.Max.Y; y++ {
+		po := img.PixOffset(bounds.Min.X, y)
+		yo := d.img3.YOffset(bounds.Min.X, y)
+		co := d.img3.COffset(bounds.Min.X, y)
+		for i, iMax := 0, bounds.Max.X-bounds.Min.X; i < iMax; i++ {
+			img.Pix[po+4*i+0] = d.img3.Y[yo+i]
+			img.Pix[po+4*i+1] = d.img3.Cb[co+i/cScale]
+			img.Pix[po+4*i+2] = d.img3.Cr[co+i/cScale]
+			img.Pix[po+4*i+3] = 255
+		}
+	}
+	return img, nil
+}
+
 // Decode reads a JPEG image from r and returns it as an image.Image.
 func Decode(r io.Reader) (image.Image, error) {
 	var d decoder
@@ -506,15 +771,25 @@
 		return image.Config{}, err
 	}
 	switch d.nComp {
-	case nGrayComponent:
+	case 1:
 		return image.Config{
 			ColorModel: color.GrayModel,
 			Width:      d.width,
 			Height:     d.height,
 		}, nil
-	case nColorComponent:
+	case 3:
+		cm := color.YCbCrModel
+		if d.isRGB() {
+			cm = color.RGBAModel
+		}
 		return image.Config{
-			ColorModel: color.YCbCrModel,
+			ColorModel: cm,
+			Width:      d.width,
+			Height:     d.height,
+		}, nil
+	case 4:
+		return image.Config{
+			ColorModel: color.CMYKModel,
 			Width:      d.width,
 			Height:     d.height,
 		}, nil
diff --git a/third_party/gofrontend/libgo/go/image/jpeg/reader_test.go b/third_party/gofrontend/libgo/go/image/jpeg/reader_test.go
index 4de2e8e..7737615 100644
--- a/third_party/gofrontend/libgo/go/image/jpeg/reader_test.go
+++ b/third_party/gofrontend/libgo/go/image/jpeg/reader_test.go
@@ -15,6 +15,7 @@
 	"os"
 	"strings"
 	"testing"
+	"time"
 )
 
 // TestDecodeProgressive tests that decoding the baseline and progressive
@@ -23,6 +24,8 @@
 func TestDecodeProgressive(t *testing.T) {
 	testCases := []string{
 		"../testdata/video-001",
+		"../testdata/video-001.q50.410",
+		"../testdata/video-001.q50.411",
 		"../testdata/video-001.q50.420",
 		"../testdata/video-001.q50.422",
 		"../testdata/video-001.q50.440",
@@ -184,6 +187,81 @@
 	return s.String()
 }
 
+func TestTruncatedSOSDataDoesntPanic(t *testing.T) {
+	b, err := ioutil.ReadFile("../testdata/video-005.gray.q50.jpeg")
+	if err != nil {
+		t.Fatal(err)
+	}
+	sosMarker := []byte{0xff, 0xda}
+	i := bytes.Index(b, sosMarker)
+	if i < 0 {
+		t.Fatal("SOS marker not found")
+	}
+	i += len(sosMarker)
+	j := i + 10
+	if j > len(b) {
+		j = len(b)
+	}
+	for ; i < j; i++ {
+		Decode(bytes.NewReader(b[:i]))
+	}
+}
+
+func TestLargeImageWithShortData(t *testing.T) {
+	// This input is an invalid JPEG image, based on the fuzzer-generated image
+	// in issue 10413. It is only 504 bytes, and shouldn't take long for Decode
+	// to return an error. The Start Of Frame marker gives the image dimensions
+	// as 8192 wide and 8192 high, so even if an unreadByteStuffedByte bug
+	// doesn't technically lead to an infinite loop, such a bug can still cause
+	// an unreasonably long loop for such a short input.
+	const input = "" +
+		"\xff\xd8\xff\xe0\x00\x10\x4a\x46\x49\x46\x00\x01\x01\x00\x00\x01" +
+		"\x00\x01\x00\x00\xff\xdb\x00\x43\x00\x10\x0b\x0c\x0e\x0c\x0a\x10" +
+		"\x0e\x89\x0e\x12\x11\x10\x13\x18\xff\xd8\xff\xe0\x00\x10\x4a\x46" +
+		"\x49\x46\x00\x01\x01\x00\x00\x01\x00\x01\x00\x00\xff\xdb\x00\x43" +
+		"\x00\x10\x0b\x0c\x0e\x0c\x0a\x10\x0e\x0d\x0e\x12\x11\x10\x13\x18" +
+		"\x28\x1a\x18\x16\x16\x18\x31\x23\x25\x1d\x28\x3a\x33\x3d\x3c\x39" +
+		"\x33\x38\x37\x40\x48\x5c\x4e\x40\x44\x57\x45\x37\x38\x50\x6d\x51" +
+		"\x57\x5f\x62\x67\x68\x67\x3e\x4d\x71\x79\x70\x64\x78\x5c\x65\x67" +
+		"\x63\xff\xc0\x00\x0b\x08\x20\x00\x20\x00\x01\x01\x11\x00\xff\xc4" +
+		"\x00\x1f\x00\x00\x01\x05\x01\x01\x01\x01\x01\x01\x00\x00\x00\x00" +
+		"\x00\x00\x00\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\xff" +
+		"\xc4\x00\xb5\x10\x00\x02\x01\x03\x03\x02\x04\x03\x05\x05\x04\x04" +
+		"\x00\x00\x01\x7d\x01\x02\x03\x00\x04\x11\x05\x12\x21\x31\x01\x06" +
+		"\x13\x51\x61\x07\x22\x71\x14\x32\x81\x91\xa1\x08\x23\xd8\xff\xdd" +
+		"\x42\xb1\xc1\x15\x52\xd1\xf0\x24\x33\x62\x72\x82\x09\x0a\x16\x17" +
+		"\x18\x19\x1a\x25\x26\x27\x28\x29\x2a\x34\x35\x36\x37\x38\x39\x3a" +
+		"\x43\x44\x45\x46\x47\x48\x49\x4a\x53\x54\x55\x56\x57\x58\x59\x5a" +
+		"\x00\x63\x64\x65\x66\x67\x68\x69\x6a\x73\x74\x75\x76\x77\x78\x79" +
+		"\x7a\x83\x84\x85\x86\x87\x88\x89\x8a\x92\x93\x94\x95\x96\x97\x98" +
+		"\x99\x9a\xa2\xa3\xa4\xa5\xa6\xa7\xa8\xa9\xaa\xb2\xb3\xb4\xb5\xb6" +
+		"\xb7\xb8\xb9\xba\xc2\xc3\xc4\xc5\xc6\xc7\xff\xd8\xff\xe0\x00\x10" +
+		"\x4a\x46\x49\x46\x00\x01\x01\x00\x00\x01\x00\x01\x00\x00\xff\xdb" +
+		"\x00\x43\x00\x10\x0b\x0c\x0e\x0c\x0a\x10\x0e\x0d\x0e\x12\x11\x10" +
+		"\x13\x18\x28\x1a\x18\x16\x16\x18\x31\x23\x25\x1d\xc8\xc9\xca\xd2" +
+		"\xd3\xd4\xd5\xd6\xd7\xd8\xd9\xda\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8" +
+		"\xe9\xea\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xff\xda\x00\x08" +
+		"\x01\x01\x00\x00\x3f\x00\xb9\xeb\x50\xb0\xdb\xc8\xa8\xe4\x63\x80" +
+		"\xdd\x31\xd6\x9d\xbb\xf2\xc5\x42\x1f\x6c\x6f\xf4\x34\xdd\x3c\xfc" +
+		"\xac\xe7\x3d\x80\xa9\xcc\x87\x34\xb3\x37\xfa\x2b\x9f\x6a\xad\x63" +
+		"\x20\x36\x9f\x78\x64\x75\xe6\xab\x7d\xb2\xde\x29\x70\xd3\x20\x27" +
+		"\xde\xaf\xa4\xf0\xca\x9f\x24\xa8\xdf\x46\xa8\x24\x84\x96\xe3\x77" +
+		"\xf9\x2e\xe0\x0a\x62\x7f\xdf\xd9"
+	c := make(chan error, 1)
+	go func() {
+		_, err := Decode(strings.NewReader(input))
+		c <- err
+	}()
+	select {
+	case err := <-c:
+		if err == nil {
+			t.Fatalf("got nil error, want non-nil")
+		}
+	case <-time.After(3 * time.Second):
+		t.Fatalf("timed out")
+	}
+}
+
 func TestExtraneousData(t *testing.T) {
 	// Encode a 1x1 red image.
 	src := image.NewRGBA(image.Rect(0, 0, 1, 1))
diff --git a/third_party/gofrontend/libgo/go/image/jpeg/scan.go b/third_party/gofrontend/libgo/go/image/jpeg/scan.go
index 2bd1d9d..99734c0 100644
--- a/third_party/gofrontend/libgo/go/image/jpeg/scan.go
+++ b/third_party/gofrontend/libgo/go/image/jpeg/scan.go
@@ -9,27 +9,42 @@
 )
 
 // makeImg allocates and initializes the destination image.
-func (d *decoder) makeImg(h0, v0, mxx, myy int) {
-	if d.nComp == nGrayComponent {
+func (d *decoder) makeImg(mxx, myy int) {
+	if d.nComp == 1 {
 		m := image.NewGray(image.Rect(0, 0, 8*mxx, 8*myy))
 		d.img1 = m.SubImage(image.Rect(0, 0, d.width, d.height)).(*image.Gray)
 		return
 	}
+
+	h0 := d.comp[0].h
+	v0 := d.comp[0].v
+	hRatio := h0 / d.comp[1].h
+	vRatio := v0 / d.comp[1].v
 	var subsampleRatio image.YCbCrSubsampleRatio
-	switch {
-	case h0 == 1 && v0 == 1:
+	switch hRatio<<4 | vRatio {
+	case 0x11:
 		subsampleRatio = image.YCbCrSubsampleRatio444
-	case h0 == 1 && v0 == 2:
+	case 0x12:
 		subsampleRatio = image.YCbCrSubsampleRatio440
-	case h0 == 2 && v0 == 1:
+	case 0x21:
 		subsampleRatio = image.YCbCrSubsampleRatio422
-	case h0 == 2 && v0 == 2:
+	case 0x22:
 		subsampleRatio = image.YCbCrSubsampleRatio420
+	case 0x41:
+		subsampleRatio = image.YCbCrSubsampleRatio411
+	case 0x42:
+		subsampleRatio = image.YCbCrSubsampleRatio410
 	default:
 		panic("unreachable")
 	}
 	m := image.NewYCbCr(image.Rect(0, 0, 8*h0*mxx, 8*v0*myy), subsampleRatio)
 	d.img3 = m.SubImage(image.Rect(0, 0, d.width, d.height)).(*image.YCbCr)
+
+	if d.nComp == 4 {
+		h3, v3 := d.comp[3].h, d.comp[3].v
+		d.blackPix = make([]byte, 8*h3*mxx*8*v3*myy)
+		d.blackStride = 8 * h3 * mxx
+	}
 }
 
 // Specified in section B.2.3.
@@ -47,15 +62,16 @@
 	if n != 4+2*nComp {
 		return FormatError("SOS length inconsistent with number of components")
 	}
-	var scan [nColorComponent]struct {
+	var scan [maxComponents]struct {
 		compIndex uint8
 		td        uint8 // DC table selector.
 		ta        uint8 // AC table selector.
 	}
+	totalHV := 0
 	for i := 0; i < nComp; i++ {
 		cs := d.tmp[1+2*i] // Component selector.
 		compIndex := -1
-		for j, comp := range d.comp {
+		for j, comp := range d.comp[:d.nComp] {
 			if cs == comp.c {
 				compIndex = j
 			}
@@ -64,6 +80,18 @@
 			return FormatError("unknown component selector")
 		}
 		scan[i].compIndex = uint8(compIndex)
+		// Section B.2.3 states that "the value of Cs_j shall be different from
+		// the values of Cs_1 through Cs_(j-1)". Since we have previously
+		// verified that a frame's component identifiers (C_i values in section
+		// B.2.2) are unique, it suffices to check that the implicit indexes
+		// into d.comp are unique.
+		for j := 0; j < i; j++ {
+			if scan[i].compIndex == scan[j].compIndex {
+				return FormatError("repeated component selector")
+			}
+		}
+		totalHV += d.comp[compIndex].h * d.comp[compIndex].v
+
 		scan[i].td = d.tmp[2+2*i] >> 4
 		if scan[i].td > maxTh {
 			return FormatError("bad Td value")
@@ -73,6 +101,11 @@
 			return FormatError("bad Ta value")
 		}
 	}
+	// Section B.2.3 states that if there is more than one component then the
+	// total H*V values in a scan must be <= 10.
+	if d.nComp > 1 && totalHV > 10 {
+		return FormatError("total sampling factors too large")
+	}
 
 	// zigStart and zigEnd are the spectral selection bounds.
 	// ah and al are the successive approximation high and low values.
@@ -112,7 +145,7 @@
 	mxx := (d.width + 8*h0 - 1) / (8 * h0)
 	myy := (d.height + 8*v0 - 1) / (8 * v0)
 	if d.img1 == nil && d.img3 == nil {
-		d.makeImg(h0, v0, mxx, myy)
+		d.makeImg(mxx, myy)
 	}
 	if d.progressive {
 		for i := 0; i < nComp; i++ {
@@ -128,11 +161,9 @@
 	var (
 		// b is the decoded coefficients, in natural (not zig-zag) order.
 		b  block
-		dc [nColorComponent]int32
-		// bx and by are the location of the current (in terms of 8x8 blocks).
-		// For example, with 4:2:0 chroma subsampling, the block whose top left
-		// pixel co-ordinates are (16, 8) is the third block in the first row:
-		// bx is 2 and by is 0, even though the pixel is in the second MCU.
+		dc [maxComponents]int32
+		// bx and by are the location of the current block, in units of 8x8
+		// blocks: the third block in the first row has (bx, by) = (2, 0).
 		bx, by     int
 		blockCount int
 	)
@@ -140,8 +171,10 @@
 		for mx := 0; mx < mxx; mx++ {
 			for i := 0; i < nComp; i++ {
 				compIndex := scan[i].compIndex
+				hi := d.comp[compIndex].h
+				vi := d.comp[compIndex].v
 				qt := &d.quant[d.comp[compIndex].tq]
-				for j := 0; j < d.comp[compIndex].h*d.comp[compIndex].v; j++ {
+				for j := 0; j < hi*vi; j++ {
 					// The blocks are traversed one MCU at a time. For 4:2:0 chroma
 					// subsampling, there are four Y 8x8 blocks in every 16x16 MCU.
 					//
@@ -168,15 +201,10 @@
 					//	0 1 2
 					//	3 4 5
 					if nComp != 1 {
-						bx, by = d.comp[compIndex].h*mx, d.comp[compIndex].v*my
-						if h0 == 1 {
-							by += j
-						} else {
-							bx += j % 2
-							by += j / 2
-						}
+						bx = hi*mx + j%hi
+						by = vi*my + j/hi
 					} else {
-						q := mxx * d.comp[compIndex].h
+						q := mxx * hi
 						bx = blockCount % q
 						by = blockCount / q
 						blockCount++
@@ -187,7 +215,7 @@
 
 					// Load the previous partially decoded coefficients, if applicable.
 					if d.progressive {
-						b = d.progCoeffs[compIndex][by*mxx*d.comp[compIndex].h+bx]
+						b = d.progCoeffs[compIndex][by*mxx*hi+bx]
 					} else {
 						b = block{}
 					}
@@ -260,7 +288,7 @@
 					if d.progressive {
 						if zigEnd != blockSize-1 || al != 0 {
 							// We haven't completely decoded this 8x8 block. Save the coefficients.
-							d.progCoeffs[compIndex][by*mxx*d.comp[compIndex].h+bx] = b
+							d.progCoeffs[compIndex][by*mxx*hi+bx] = b
 							// At this point, we could execute the rest of the loop body to dequantize and
 							// perform the inverse DCT, to save early stages of a progressive image to the
 							// *image.YCbCr buffers (the whole point of progressive encoding), but in Go,
@@ -276,7 +304,7 @@
 					}
 					idct(&b)
 					dst, stride := []byte(nil), 0
-					if d.nComp == nGrayComponent {
+					if d.nComp == 1 {
 						dst, stride = d.img1.Pix[8*(by*d.img1.Stride+bx):], d.img1.Stride
 					} else {
 						switch compIndex {
@@ -286,6 +314,8 @@
 							dst, stride = d.img3.Cb[8*(by*d.img3.CStride+bx):], d.img3.CStride
 						case 2:
 							dst, stride = d.img3.Cr[8*(by*d.img3.CStride+bx):], d.img3.CStride
+						case 3:
+							dst, stride = d.blackPix[8*(by*d.blackStride+bx):], d.blackStride
 						default:
 							return UnsupportedError("too many components")
 						}
@@ -325,7 +355,7 @@
 				// Reset the Huffman decoder.
 				d.bits = bits{}
 				// Reset the DC components, as per section F.2.1.3.1.
-				dc = [nColorComponent]int32{}
+				dc = [maxComponents]int32{}
 				// Reset the progressive decoder state, as per section G.1.2.2.
 				d.eobRun = 0
 			}
diff --git a/third_party/gofrontend/libgo/go/image/png/reader.go b/third_party/gofrontend/libgo/go/image/png/reader.go
index 0a40ca1..bbd6f75 100644
--- a/third_party/gofrontend/libgo/go/image/png/reader.go
+++ b/third_party/gofrontend/libgo/go/image/png/reader.go
@@ -47,6 +47,10 @@
 	cbTCA16
 )
 
+func cbPaletted(cb int) bool {
+	return cbP1 <= cb && cb <= cbP8
+}
+
 // Filter type, as per the PNG spec.
 const (
 	ftNone    = 0
@@ -81,15 +85,16 @@
 }
 
 // Decoding stage.
-// The PNG specification says that the IHDR, PLTE (if present), IDAT and IEND
-// chunks must appear in that order. There may be multiple IDAT chunks, and
-// IDAT chunks must be sequential (i.e. they may not have any other chunks
-// between them).
+// The PNG specification says that the IHDR, PLTE (if present), tRNS (if
+// present), IDAT and IEND chunks must appear in that order. There may be
+// multiple IDAT chunks, and IDAT chunks must be sequential (i.e. they may not
+// have any other chunks between them).
 // http://www.w3.org/TR/PNG/#5ChunkOrdering
 const (
 	dsStart = iota
 	dsSeenIHDR
 	dsSeenPLTE
+	dsSeentRNS
 	dsSeenIDAT
 	dsSeenIEND
 )
@@ -321,15 +326,23 @@
 	var img image.Image
 	if d.interlace == itNone {
 		img, err = d.readImagePass(r, 0, false)
+		if err != nil {
+			return nil, err
+		}
 	} else if d.interlace == itAdam7 {
 		// Allocate a blank image of the full size.
 		img, err = d.readImagePass(nil, 0, true)
+		if err != nil {
+			return nil, err
+		}
 		for pass := 0; pass < 7; pass++ {
 			imagePass, err := d.readImagePass(r, pass, false)
 			if err != nil {
 				return nil, err
 			}
-			d.mergePassInto(img, imagePass, pass)
+			if imagePass != nil {
+				d.mergePassInto(img, imagePass, pass)
+			}
 		}
 	}
 
@@ -371,6 +384,12 @@
 		// Add the multiplication factor and subtract one, effectively rounding up.
 		width = (width - p.xOffset + p.xFactor - 1) / p.xFactor
 		height = (height - p.yOffset + p.yFactor - 1) / p.yFactor
+		// A PNG image can't have zero width or height, but for an interlaced
+		// image, an individual pass might have zero width or height. If so, we
+		// shouldn't even read a per-row filter type byte, so return early.
+		if width == 0 || height == 0 {
+			return nil, nil
+		}
 	}
 	switch d.cb {
 	case cbG1, cbG2, cbG4, cbG8:
@@ -425,6 +444,9 @@
 		// Read the decompressed bytes.
 		_, err := io.ReadFull(r, cr)
 		if err != nil {
+			if err == io.EOF || err == io.ErrUnexpectedEOF {
+				return nil, FormatError("not enough pixel data")
+			}
 			return nil, err
 		}
 
@@ -443,6 +465,9 @@
 				cdat[i] += p
 			}
 		case ftAverage:
+			// The first column has no column to the left of it, so it is a
+			// special case. We know that the first column exists because we
+			// check above that width != 0, and so len(cdat) != 0.
 			for i := 0; i < bytesPerPixel; i++ {
 				cdat[i] += pdat[i] / 2
 			}
@@ -687,9 +712,10 @@
 		if d.stage != dsSeenPLTE {
 			return chunkOrderError
 		}
+		d.stage = dsSeentRNS
 		return d.parsetRNS(length)
 	case "IDAT":
-		if d.stage < dsSeenIHDR || d.stage > dsSeenIDAT || (d.cb == cbP8 && d.stage == dsSeenIHDR) {
+		if d.stage < dsSeenIHDR || d.stage > dsSeenIDAT || (d.stage == dsSeenIHDR && cbPaletted(d.cb)) {
 			return chunkOrderError
 		}
 		d.stage = dsSeenIDAT
@@ -779,7 +805,7 @@
 			}
 			return image.Config{}, err
 		}
-		paletted := d.cb == cbP8 || d.cb == cbP4 || d.cb == cbP2 || d.cb == cbP1
+		paletted := cbPaletted(d.cb)
 		if d.stage == dsSeenIHDR && !paletted {
 			break
 		}
diff --git a/third_party/gofrontend/libgo/go/image/png/reader_test.go b/third_party/gofrontend/libgo/go/image/png/reader_test.go
index ce772eb..f89e7ef 100644
--- a/third_party/gofrontend/libgo/go/image/png/reader_test.go
+++ b/third_party/gofrontend/libgo/go/image/png/reader_test.go
@@ -6,12 +6,14 @@
 
 import (
 	"bufio"
+	"bytes"
 	"fmt"
 	"image"
 	"image/color"
 	"io"
 	"io/ioutil"
 	"os"
+	"reflect"
 	"strings"
 	"testing"
 )
@@ -319,6 +321,93 @@
 	}
 }
 
+func TestInterlaced(t *testing.T) {
+	a, err := readPNG("testdata/gray-gradient.png")
+	if err != nil {
+		t.Fatal(err)
+	}
+	b, err := readPNG("testdata/gray-gradient.interlaced.png")
+	if err != nil {
+		t.Fatal(err)
+	}
+	if !reflect.DeepEqual(a, b) {
+		t.Fatalf("decodings differ:\nnon-interlaced:\n%#v\ninterlaced:\n%#v", a, b)
+	}
+}
+
+func TestIncompleteIDATOnRowBoundary(t *testing.T) {
+	// The following is an invalid 1x2 grayscale PNG image. The header is OK,
+	// but the zlib-compressed IDAT payload contains two bytes "\x02\x00",
+	// which is only one row of data (the leading "\x02" is a row filter).
+	const (
+		ihdr = "\x00\x00\x00\x0dIHDR\x00\x00\x00\x01\x00\x00\x00\x02\x08\x00\x00\x00\x00\xbc\xea\xe9\xfb"
+		idat = "\x00\x00\x00\x0eIDAT\x78\x9c\x62\x62\x00\x04\x00\x00\xff\xff\x00\x06\x00\x03\xfa\xd0\x59\xae"
+		iend = "\x00\x00\x00\x00IEND\xae\x42\x60\x82"
+	)
+	_, err := Decode(strings.NewReader(pngHeader + ihdr + idat + iend))
+	if err == nil {
+		t.Fatal("got nil error, want non-nil")
+	}
+}
+
+func TestMultipletRNSChunks(t *testing.T) {
+	/*
+		The following is a valid 1x1 paletted PNG image with a 1-element palette
+		containing color.NRGBA{0xff, 0x00, 0x00, 0x7f}:
+			0000000: 8950 4e47 0d0a 1a0a 0000 000d 4948 4452  .PNG........IHDR
+			0000010: 0000 0001 0000 0001 0803 0000 0028 cb34  .............(.4
+			0000020: bb00 0000 0350 4c54 45ff 0000 19e2 0937  .....PLTE......7
+			0000030: 0000 0001 7452 4e53 7f80 5cb4 cb00 0000  ....tRNS..\.....
+			0000040: 0e49 4441 5478 9c62 6200 0400 00ff ff00  .IDATx.bb.......
+			0000050: 0600 03fa d059 ae00 0000 0049 454e 44ae  .....Y.....IEND.
+			0000060: 4260 82                                  B`.
+		Dropping the tRNS chunk makes that color's alpha 0xff instead of 0x7f.
+	*/
+	const (
+		ihdr = "\x00\x00\x00\x0dIHDR\x00\x00\x00\x01\x00\x00\x00\x01\x08\x03\x00\x00\x00\x28\xcb\x34\xbb"
+		plte = "\x00\x00\x00\x03PLTE\xff\x00\x00\x19\xe2\x09\x37"
+		trns = "\x00\x00\x00\x01tRNS\x7f\x80\x5c\xb4\xcb"
+		idat = "\x00\x00\x00\x0eIDAT\x78\x9c\x62\x62\x00\x04\x00\x00\xff\xff\x00\x06\x00\x03\xfa\xd0\x59\xae"
+		iend = "\x00\x00\x00\x00IEND\xae\x42\x60\x82"
+	)
+	for i := 0; i < 4; i++ {
+		var b []byte
+		b = append(b, pngHeader...)
+		b = append(b, ihdr...)
+		b = append(b, plte...)
+		for j := 0; j < i; j++ {
+			b = append(b, trns...)
+		}
+		b = append(b, idat...)
+		b = append(b, iend...)
+
+		var want color.Color
+		m, err := Decode(bytes.NewReader(b))
+		switch i {
+		case 0:
+			if err != nil {
+				t.Errorf("%d tRNS chunks: %v", i, err)
+				continue
+			}
+			want = color.RGBA{0xff, 0x00, 0x00, 0xff}
+		case 1:
+			if err != nil {
+				t.Errorf("%d tRNS chunks: %v", i, err)
+				continue
+			}
+			want = color.NRGBA{0xff, 0x00, 0x00, 0x7f}
+		default:
+			if err == nil {
+				t.Errorf("%d tRNS chunks: got nil error, want non-nil", i)
+			}
+			continue
+		}
+		if got := m.At(0, 0); got != want {
+			t.Errorf("%d tRNS chunks: got %T %v, want %T %v", i, got, got, want, want)
+		}
+	}
+}
+
 func benchmarkDecode(b *testing.B, filename string, bytesPerPixel int) {
 	b.StopTimer()
 	data, err := ioutil.ReadFile(filename)
diff --git a/third_party/gofrontend/libgo/go/image/png/testdata/benchRGB-interlace.png b/third_party/gofrontend/libgo/go/image/png/testdata/benchRGB-interlace.png
new file mode 100644
index 0000000..b4b5dab
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/image/png/testdata/benchRGB-interlace.png
Binary files differ
diff --git a/third_party/gofrontend/libgo/go/image/png/testdata/gray-gradient.interlaced.png b/third_party/gofrontend/libgo/go/image/png/testdata/gray-gradient.interlaced.png
new file mode 100644
index 0000000..01f657a
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/image/png/testdata/gray-gradient.interlaced.png
Binary files differ
diff --git a/third_party/gofrontend/libgo/go/image/png/testdata/gray-gradient.png b/third_party/gofrontend/libgo/go/image/png/testdata/gray-gradient.png
new file mode 100644
index 0000000..6de1cd3
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/image/png/testdata/gray-gradient.png
Binary files differ
diff --git a/third_party/gofrontend/libgo/go/image/png/testdata/pngsuite/basn3p04-31i.png b/third_party/gofrontend/libgo/go/image/png/testdata/pngsuite/basn3p04-31i.png
new file mode 100644
index 0000000..540137c
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/image/png/testdata/pngsuite/basn3p04-31i.png
Binary files differ
diff --git a/third_party/gofrontend/libgo/go/image/png/testdata/pngsuite/basn3p04-31i.sng b/third_party/gofrontend/libgo/go/image/png/testdata/pngsuite/basn3p04-31i.sng
new file mode 100644
index 0000000..31b87c7
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/image/png/testdata/pngsuite/basn3p04-31i.sng
@@ -0,0 +1,57 @@
+#SNG: from basn3p04-31i.png
+IHDR {
+    width: 31; height: 31; bitdepth: 4;
+    using color palette;
+}
+gAMA {1.0000}
+PLTE {
+    ( 34,  0,255)     # rgb = (0x22,0x00,0xff)
+    (  0,255,255)     # rgb = (0x00,0xff,0xff)
+    (136,  0,255)     # rgb = (0x88,0x00,0xff)
+    ( 34,255,  0)     # rgb = (0x22,0xff,0x00)
+    (  0,153,255)     # rgb = (0x00,0x99,0xff)
+    (255,102,  0)     # rgb = (0xff,0x66,0x00)
+    (221,  0,255)     # rgb = (0xdd,0x00,0xff)
+    (119,255,  0)     # rgb = (0x77,0xff,0x00)
+    (255,  0,  0)     # rgb = (0xff,0x00,0x00)
+    (  0,255,153)     # rgb = (0x00,0xff,0x99)
+    (221,255,  0)     # rgb = (0xdd,0xff,0x00)
+    (255,  0,187)     # rgb = (0xff,0x00,0xbb)
+    (255,187,  0)     # rgb = (0xff,0xbb,0x00)
+    (  0, 68,255)     # rgb = (0x00,0x44,0xff)
+    (  0,255, 68)     # rgb = (0x00,0xff,0x44)
+}
+IMAGE {
+    pixels hex
+88885555ccccaaaa77773333eeee9990
+88885555ccccaaaa77773333eeee9990
+88885555ccccaaaa77773333eeee9990
+88885555ccccaaaa77773333eeee9990
+5555ccccaaaa77773333eeee99991110
+5555ccccaaaa77773333eeee99991110
+5555ccccaaaa77773333eeee99991110
+5555ccccaaaa77773333eeee99991110
+ccccaaaa77773333eeee999911114440
+ccccaaaa77773333eeee999911114440
+ccccaaaa77773333eeee999911114440
+ccccaaaa77773333eeee999911114440
+aaaa77773333eeee999911114444ddd0
+aaaa77773333eeee999911114444ddd0
+aaaa77773333eeee999911114444ddd0
+aaaa77773333eeee999911114444ddd0
+77773333eeee999911114444dddd0000
+77773333eeee999911114444dddd0000
+77773333eeee999911114444dddd0000
+77773333eeee999911114444dddd0000
+3333eeee999911114444dddd00002220
+3333eeee999911114444dddd00002220
+3333eeee999911114444dddd00002220
+3333eeee999911114444dddd00002220
+eeee999911114444dddd000022226660
+eeee999911114444dddd000022226660
+eeee999911114444dddd000022226660
+eeee999911114444dddd000022226660
+999911114444dddd000022226666bbb0
+999911114444dddd000022226666bbb0
+999911114444dddd000022226666bbb0
+}
diff --git a/third_party/gofrontend/libgo/go/image/testdata/video-001.221212.jpeg b/third_party/gofrontend/libgo/go/image/testdata/video-001.221212.jpeg
new file mode 100644
index 0000000..f069c76
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/image/testdata/video-001.221212.jpeg
Binary files differ
diff --git a/third_party/gofrontend/libgo/go/image/testdata/video-001.221212.png b/third_party/gofrontend/libgo/go/image/testdata/video-001.221212.png
new file mode 100644
index 0000000..d619a62
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/image/testdata/video-001.221212.png
Binary files differ
diff --git a/third_party/gofrontend/libgo/go/image/testdata/video-001.cmyk.jpeg b/third_party/gofrontend/libgo/go/image/testdata/video-001.cmyk.jpeg
new file mode 100644
index 0000000..507df84
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/image/testdata/video-001.cmyk.jpeg
Binary files differ
diff --git a/third_party/gofrontend/libgo/go/image/testdata/video-001.cmyk.png b/third_party/gofrontend/libgo/go/image/testdata/video-001.cmyk.png
new file mode 100644
index 0000000..ef7b2b8
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/image/testdata/video-001.cmyk.png
Binary files differ
diff --git a/third_party/gofrontend/libgo/go/image/testdata/video-001.q50.410.jpeg b/third_party/gofrontend/libgo/go/image/testdata/video-001.q50.410.jpeg
new file mode 100644
index 0000000..4cebd1e
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/image/testdata/video-001.q50.410.jpeg
Binary files differ
diff --git a/third_party/gofrontend/libgo/go/image/testdata/video-001.q50.410.progressive.jpeg b/third_party/gofrontend/libgo/go/image/testdata/video-001.q50.410.progressive.jpeg
new file mode 100644
index 0000000..fb71402
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/image/testdata/video-001.q50.410.progressive.jpeg
Binary files differ
diff --git a/third_party/gofrontend/libgo/go/image/testdata/video-001.q50.411.jpeg b/third_party/gofrontend/libgo/go/image/testdata/video-001.q50.411.jpeg
new file mode 100644
index 0000000..b90de18
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/image/testdata/video-001.q50.411.jpeg
Binary files differ
diff --git a/third_party/gofrontend/libgo/go/image/testdata/video-001.q50.411.progressive.jpeg b/third_party/gofrontend/libgo/go/image/testdata/video-001.q50.411.progressive.jpeg
new file mode 100644
index 0000000..1ddb22b
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/image/testdata/video-001.q50.411.progressive.jpeg
Binary files differ
diff --git a/third_party/gofrontend/libgo/go/image/testdata/video-001.rgb.jpeg b/third_party/gofrontend/libgo/go/image/testdata/video-001.rgb.jpeg
new file mode 100644
index 0000000..fc2ce3c
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/image/testdata/video-001.rgb.jpeg
Binary files differ
diff --git a/third_party/gofrontend/libgo/go/image/testdata/video-001.rgb.png b/third_party/gofrontend/libgo/go/image/testdata/video-001.rgb.png
new file mode 100644
index 0000000..edb716d
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/image/testdata/video-001.rgb.png
Binary files differ
diff --git a/third_party/gofrontend/libgo/go/image/ycbcr.go b/third_party/gofrontend/libgo/go/image/ycbcr.go
index 7c773f2..93c354b 100644
--- a/third_party/gofrontend/libgo/go/image/ycbcr.go
+++ b/third_party/gofrontend/libgo/go/image/ycbcr.go
@@ -16,6 +16,8 @@
 	YCbCrSubsampleRatio422
 	YCbCrSubsampleRatio420
 	YCbCrSubsampleRatio440
+	YCbCrSubsampleRatio411
+	YCbCrSubsampleRatio410
 )
 
 func (s YCbCrSubsampleRatio) String() string {
@@ -28,6 +30,10 @@
 		return "YCbCrSubsampleRatio420"
 	case YCbCrSubsampleRatio440:
 		return "YCbCrSubsampleRatio440"
+	case YCbCrSubsampleRatio411:
+		return "YCbCrSubsampleRatio411"
+	case YCbCrSubsampleRatio410:
+		return "YCbCrSubsampleRatio410"
 	}
 	return "YCbCrSubsampleRatioUnknown"
 }
@@ -43,6 +49,8 @@
 //	For 4:2:2, CStride == YStride/2 && len(Cb) == len(Cr) == len(Y)/2.
 //	For 4:2:0, CStride == YStride/2 && len(Cb) == len(Cr) == len(Y)/4.
 //	For 4:4:0, CStride == YStride/1 && len(Cb) == len(Cr) == len(Y)/2.
+//	For 4:1:1, CStride == YStride/4 && len(Cb) == len(Cr) == len(Y)/4.
+//	For 4:1:0, CStride == YStride/4 && len(Cb) == len(Cr) == len(Y)/8.
 type YCbCr struct {
 	Y, Cb, Cr      []uint8
 	YStride        int
@@ -92,6 +100,10 @@
 		return (y/2-p.Rect.Min.Y/2)*p.CStride + (x/2 - p.Rect.Min.X/2)
 	case YCbCrSubsampleRatio440:
 		return (y/2-p.Rect.Min.Y/2)*p.CStride + (x - p.Rect.Min.X)
+	case YCbCrSubsampleRatio411:
+		return (y-p.Rect.Min.Y)*p.CStride + (x/4 - p.Rect.Min.X/4)
+	case YCbCrSubsampleRatio410:
+		return (y/2-p.Rect.Min.Y/2)*p.CStride + (x/4 - p.Rect.Min.X/4)
 	}
 	// Default to 4:4:4 subsampling.
 	return (y-p.Rect.Min.Y)*p.CStride + (x - p.Rect.Min.X)
@@ -139,16 +151,25 @@
 	case YCbCrSubsampleRatio440:
 		cw = w
 		ch = (r.Max.Y+1)/2 - r.Min.Y/2
+	case YCbCrSubsampleRatio411:
+		cw = (r.Max.X+3)/4 - r.Min.X/4
+		ch = h
+	case YCbCrSubsampleRatio410:
+		cw = (r.Max.X+3)/4 - r.Min.X/4
+		ch = (r.Max.Y+1)/2 - r.Min.Y/2
 	default:
 		// Default to 4:4:4 subsampling.
 		cw = w
 		ch = h
 	}
-	b := make([]byte, w*h+2*cw*ch)
+	i0 := w*h + 0*cw*ch
+	i1 := w*h + 1*cw*ch
+	i2 := w*h + 2*cw*ch
+	b := make([]byte, i2)
 	return &YCbCr{
-		Y:              b[:w*h],
-		Cb:             b[w*h+0*cw*ch : w*h+1*cw*ch],
-		Cr:             b[w*h+1*cw*ch : w*h+2*cw*ch],
+		Y:              b[:i0:i0],
+		Cb:             b[i0:i1:i1],
+		Cr:             b[i1:i2:i2],
 		SubsampleRatio: subsampleRatio,
 		YStride:        w,
 		CStride:        cw,
diff --git a/third_party/gofrontend/libgo/go/image/ycbcr_test.go b/third_party/gofrontend/libgo/go/image/ycbcr_test.go
index a5f4482..4996bc8 100644
--- a/third_party/gofrontend/libgo/go/image/ycbcr_test.go
+++ b/third_party/gofrontend/libgo/go/image/ycbcr_test.go
@@ -37,6 +37,8 @@
 		YCbCrSubsampleRatio422,
 		YCbCrSubsampleRatio420,
 		YCbCrSubsampleRatio440,
+		YCbCrSubsampleRatio411,
+		YCbCrSubsampleRatio410,
 	}
 	deltas := []Point{
 		Pt(0, 0),
@@ -105,3 +107,27 @@
 		}
 	}
 }
+
+func TestYCbCrSlicesDontOverlap(t *testing.T) {
+	m := NewYCbCr(Rect(0, 0, 8, 8), YCbCrSubsampleRatio420)
+	names := []string{"Y", "Cb", "Cr"}
+	slices := [][]byte{
+		m.Y[:cap(m.Y)],
+		m.Cb[:cap(m.Cb)],
+		m.Cr[:cap(m.Cr)],
+	}
+	for i, slice := range slices {
+		want := uint8(10 + i)
+		for j := range slice {
+			slice[j] = want
+		}
+	}
+	for i, slice := range slices {
+		want := uint8(10 + i)
+		for j, got := range slice {
+			if got != want {
+				t.Fatalf("m.%s[%d]: got %d, want %d", names[i], j, got, want)
+			}
+		}
+	}
+}
diff --git a/third_party/gofrontend/libgo/go/internal/format/format.go b/third_party/gofrontend/libgo/go/internal/format/format.go
new file mode 100644
index 0000000..a8270ba
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/internal/format/format.go
@@ -0,0 +1,163 @@
+// 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 format
+
+import (
+	"bytes"
+	"go/ast"
+	"go/parser"
+	"go/printer"
+	"go/token"
+	"strings"
+)
+
+const parserMode = parser.ParseComments
+
+// Parse parses src, which was read from the named file,
+// as a Go source file, declaration, or statement list.
+func Parse(fset *token.FileSet, filename string, src []byte, fragmentOk bool) (
+	file *ast.File,
+	sourceAdj func(src []byte, indent int) []byte,
+	indentAdj int,
+	err error,
+) {
+	// Try as whole source file.
+	file, err = parser.ParseFile(fset, filename, src, parserMode)
+	// If there's no error, return.  If the error is that the source file didn't begin with a
+	// package line and source fragments are ok, fall through to
+	// try as a source fragment.  Stop and return on any other error.
+	if err == nil || !fragmentOk || !strings.Contains(err.Error(), "expected 'package'") {
+		return
+	}
+
+	// If this is a declaration list, make it a source file
+	// by inserting a package clause.
+	// Insert using a ;, not a newline, so that the line numbers
+	// in psrc match the ones in src.
+	psrc := append([]byte("package p;"), src...)
+	file, err = parser.ParseFile(fset, filename, psrc, parserMode)
+	if err == nil {
+		sourceAdj = func(src []byte, indent int) []byte {
+			// Remove the package clause.
+			// Gofmt has turned the ; into a \n.
+			src = src[indent+len("package p\n"):]
+			return bytes.TrimSpace(src)
+		}
+		return
+	}
+	// If the error is that the source file didn't begin with a
+	// declaration, fall through to try as a statement list.
+	// Stop and return on any other error.
+	if !strings.Contains(err.Error(), "expected declaration") {
+		return
+	}
+
+	// If this is a statement list, make it a source file
+	// by inserting a package clause and turning the list
+	// into a function body.  This handles expressions too.
+	// Insert using a ;, not a newline, so that the line numbers
+	// in fsrc match the ones in src. Add an extra '\n' before the '}'
+	// to make sure comments are flushed before the '}'.
+	fsrc := append(append([]byte("package p; func _() {"), src...), '\n', '\n', '}')
+	file, err = parser.ParseFile(fset, filename, fsrc, parserMode)
+	if err == nil {
+		sourceAdj = func(src []byte, indent int) []byte {
+			// Cap adjusted indent to zero.
+			if indent < 0 {
+				indent = 0
+			}
+			// Remove the wrapping.
+			// Gofmt has turned the ; into a \n\n.
+			// There will be two non-blank lines with indent, hence 2*indent.
+			src = src[2*indent+len("package p\n\nfunc _() {"):]
+			// Remove only the "}\n" suffix: remaining whitespaces will be trimmed anyway
+			src = src[:len(src)-len("}\n")]
+			return bytes.TrimSpace(src)
+		}
+		// Gofmt has also indented the function body one level.
+		// Adjust that with indentAdj.
+		indentAdj = -1
+	}
+
+	// Succeeded, or out of options.
+	return
+}
+
+// Format formats the given package file originally obtained from src
+// and adjusts the result based on the original source via sourceAdj
+// and indentAdj.
+func Format(
+	fset *token.FileSet,
+	file *ast.File,
+	sourceAdj func(src []byte, indent int) []byte,
+	indentAdj int,
+	src []byte,
+	cfg printer.Config,
+) ([]byte, error) {
+	if sourceAdj == nil {
+		// Complete source file.
+		var buf bytes.Buffer
+		err := cfg.Fprint(&buf, fset, file)
+		if err != nil {
+			return nil, err
+		}
+		return buf.Bytes(), nil
+	}
+
+	// Partial source file.
+	// Determine and prepend leading space.
+	i, j := 0, 0
+	for j < len(src) && IsSpace(src[j]) {
+		if src[j] == '\n' {
+			i = j + 1 // byte offset of last line in leading space
+		}
+		j++
+	}
+	var res []byte
+	res = append(res, src[:i]...)
+
+	// Determine and prepend indentation of first code line.
+	// Spaces are ignored unless there are no tabs,
+	// in which case spaces count as one tab.
+	indent := 0
+	hasSpace := false
+	for _, b := range src[i:j] {
+		switch b {
+		case ' ':
+			hasSpace = true
+		case '\t':
+			indent++
+		}
+	}
+	if indent == 0 && hasSpace {
+		indent = 1
+	}
+	for i := 0; i < indent; i++ {
+		res = append(res, '\t')
+	}
+
+	// Format the source.
+	// Write it without any leading and trailing space.
+	cfg.Indent = indent + indentAdj
+	var buf bytes.Buffer
+	err := cfg.Fprint(&buf, fset, file)
+	if err != nil {
+		return nil, err
+	}
+	res = append(res, sourceAdj(buf.Bytes(), cfg.Indent)...)
+
+	// Determine and append trailing space.
+	i = len(src)
+	for i > 0 && IsSpace(src[i-1]) {
+		i--
+	}
+	return append(res, src[i:]...), nil
+}
+
+// IsSpace reports whether the byte is a space character.
+// IsSpace defines a space as being among the following bytes: ' ', '\t', '\n' and '\r'.
+func IsSpace(b byte) bool {
+	return b == ' ' || b == '\t' || b == '\n' || b == '\r'
+}
diff --git a/third_party/gofrontend/libgo/go/net/singleflight.go b/third_party/gofrontend/libgo/go/internal/singleflight/singleflight.go
similarity index 72%
rename from third_party/gofrontend/libgo/go/net/singleflight.go
rename to third_party/gofrontend/libgo/go/internal/singleflight/singleflight.go
index bf599f0..f4cb2d6 100644
--- a/third_party/gofrontend/libgo/go/net/singleflight.go
+++ b/third_party/gofrontend/libgo/go/internal/singleflight/singleflight.go
@@ -2,7 +2,9 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-package net
+// Package singleflight provides a duplicate function call suppression
+// mechanism.
+package singleflight
 
 import "sync"
 
@@ -19,22 +21,22 @@
 	// mutex held before the WaitGroup is done, and are read but
 	// not written after the WaitGroup is done.
 	dups  int
-	chans []chan<- singleflightResult
+	chans []chan<- Result
 }
 
-// singleflight represents a class of work and forms a namespace in
+// Group represents a class of work and forms a namespace in
 // which units of work can be executed with duplicate suppression.
-type singleflight struct {
+type Group struct {
 	mu sync.Mutex       // protects m
 	m  map[string]*call // lazily initialized
 }
 
-// singleflightResult holds the results of Do, so they can be passed
+// Result holds the results of Do, so they can be passed
 // on a channel.
-type singleflightResult struct {
-	v      interface{}
-	err    error
-	shared bool
+type Result struct {
+	Val    interface{}
+	Err    error
+	Shared bool
 }
 
 // Do executes and returns the results of the given function, making
@@ -42,7 +44,7 @@
 // time. If a duplicate comes in, the duplicate caller waits for the
 // original to complete and receives the same results.
 // The return value shared indicates whether v was given to multiple callers.
-func (g *singleflight) Do(key string, fn func() (interface{}, error)) (v interface{}, err error, shared bool) {
+func (g *Group) Do(key string, fn func() (interface{}, error)) (v interface{}, err error, shared bool) {
 	g.mu.Lock()
 	if g.m == nil {
 		g.m = make(map[string]*call)
@@ -64,8 +66,8 @@
 
 // DoChan is like Do but returns a channel that will receive the
 // results when they are ready.
-func (g *singleflight) DoChan(key string, fn func() (interface{}, error)) <-chan singleflightResult {
-	ch := make(chan singleflightResult, 1)
+func (g *Group) DoChan(key string, fn func() (interface{}, error)) <-chan Result {
+	ch := make(chan Result, 1)
 	g.mu.Lock()
 	if g.m == nil {
 		g.m = make(map[string]*call)
@@ -76,7 +78,7 @@
 		g.mu.Unlock()
 		return ch
 	}
-	c := &call{chans: []chan<- singleflightResult{ch}}
+	c := &call{chans: []chan<- Result{ch}}
 	c.wg.Add(1)
 	g.m[key] = c
 	g.mu.Unlock()
@@ -87,14 +89,14 @@
 }
 
 // doCall handles the single call for a key.
-func (g *singleflight) doCall(c *call, key string, fn func() (interface{}, error)) {
+func (g *Group) doCall(c *call, key string, fn func() (interface{}, error)) {
 	c.val, c.err = fn()
 	c.wg.Done()
 
 	g.mu.Lock()
 	delete(g.m, key)
 	for _, ch := range c.chans {
-		ch <- singleflightResult{c.val, c.err, c.dups > 0}
+		ch <- Result{c.val, c.err, c.dups > 0}
 	}
 	g.mu.Unlock()
 }
@@ -102,7 +104,7 @@
 // Forget tells the singleflight to forget about a key.  Future calls
 // to Do for this key will call the function rather than waiting for
 // an earlier call to complete.
-func (g *singleflight) Forget(key string) {
+func (g *Group) Forget(key string) {
 	g.mu.Lock()
 	delete(g.m, key)
 	g.mu.Unlock()
diff --git a/third_party/gofrontend/libgo/go/internal/singleflight/singleflight_test.go b/third_party/gofrontend/libgo/go/internal/singleflight/singleflight_test.go
new file mode 100644
index 0000000..c0ec024
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/internal/singleflight/singleflight_test.go
@@ -0,0 +1,87 @@
+// Copyright 2013 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 singleflight
+
+import (
+	"errors"
+	"fmt"
+	"sync"
+	"sync/atomic"
+	"testing"
+	"time"
+)
+
+func TestDo(t *testing.T) {
+	var g Group
+	v, err, _ := g.Do("key", func() (interface{}, error) {
+		return "bar", nil
+	})
+	if got, want := fmt.Sprintf("%v (%T)", v, v), "bar (string)"; got != want {
+		t.Errorf("Do = %v; want %v", got, want)
+	}
+	if err != nil {
+		t.Errorf("Do error = %v", err)
+	}
+}
+
+func TestDoErr(t *testing.T) {
+	var g Group
+	someErr := errors.New("Some error")
+	v, err, _ := g.Do("key", func() (interface{}, error) {
+		return nil, someErr
+	})
+	if err != someErr {
+		t.Errorf("Do error = %v; want someErr %v", err, someErr)
+	}
+	if v != nil {
+		t.Errorf("unexpected non-nil value %#v", v)
+	}
+}
+
+func TestDoDupSuppress(t *testing.T) {
+	var g Group
+	var wg1, wg2 sync.WaitGroup
+	c := make(chan string, 1)
+	var calls int32
+	fn := func() (interface{}, error) {
+		if atomic.AddInt32(&calls, 1) == 1 {
+			// First invocation.
+			wg1.Done()
+		}
+		v := <-c
+		c <- v // pump; make available for any future calls
+
+		time.Sleep(10 * time.Millisecond) // let more goroutines enter Do
+
+		return v, nil
+	}
+
+	const n = 10
+	wg1.Add(1)
+	for i := 0; i < n; i++ {
+		wg1.Add(1)
+		wg2.Add(1)
+		go func() {
+			defer wg2.Done()
+			wg1.Done()
+			v, err, _ := g.Do("key", fn)
+			if err != nil {
+				t.Errorf("Do error: %v", err)
+				return
+			}
+			if s, _ := v.(string); s != "bar" {
+				t.Errorf("Do = %T %v; want %q", v, v, "bar")
+			}
+		}()
+	}
+	wg1.Wait()
+	// At least one goroutine is in fn now and all of them have at
+	// least reached the line before the Do.
+	c <- "bar"
+	wg2.Wait()
+	if got := atomic.LoadInt32(&calls); got <= 0 || got >= n {
+		t.Errorf("number of calls = %d; want over 0 and less than %d", got, n)
+	}
+}
diff --git a/third_party/gofrontend/libgo/go/internal/syscall/dummy.go b/third_party/gofrontend/libgo/go/internal/syscall/unix/dummy.go
similarity index 90%
rename from third_party/gofrontend/libgo/go/internal/syscall/dummy.go
rename to third_party/gofrontend/libgo/go/internal/syscall/unix/dummy.go
index b00eb27..a40e6a3 100644
--- a/third_party/gofrontend/libgo/go/internal/syscall/dummy.go
+++ b/third_party/gofrontend/libgo/go/internal/syscall/unix/dummy.go
@@ -2,4 +2,4 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-package syscall
+package unix
diff --git a/third_party/gofrontend/libgo/go/internal/syscall/getrandom_linux.go b/third_party/gofrontend/libgo/go/internal/syscall/unix/getrandom_linux.go
similarity index 82%
rename from third_party/gofrontend/libgo/go/internal/syscall/getrandom_linux.go
rename to third_party/gofrontend/libgo/go/internal/syscall/unix/getrandom_linux.go
index 944bab3..7388271 100644
--- a/third_party/gofrontend/libgo/go/internal/syscall/getrandom_linux.go
+++ b/third_party/gofrontend/libgo/go/internal/syscall/unix/getrandom_linux.go
@@ -2,19 +2,21 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-package syscall
+package unix
 
 import (
 	"runtime"
 	"sync/atomic"
-	stdsyscall "syscall"
+	"syscall"
 	"unsafe"
 )
 
 var randomTrap = map[string]uintptr{
-	"386":   355,
-	"amd64": 318,
-	"arm":   384,
+	"386":     355,
+	"amd64":   318,
+	"arm":     384,
+	"ppc64":   359,
+	"ppc64le": 359,
 }[runtime.GOARCH]
 
 var randomUnsupported int32 // atomic
@@ -34,20 +36,20 @@
 // See https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=c6e9d6f38894798696f23c8084ca7edbf16ee895
 func GetRandom(p []byte, flags GetRandomFlag) (n int, err error) {
 	if randomTrap == 0 {
-		return 0, stdsyscall.ENOSYS
+		return 0, syscall.ENOSYS
 	}
 	if len(p) == 0 {
 		return 0, nil
 	}
 	if atomic.LoadInt32(&randomUnsupported) != 0 {
-		return 0, stdsyscall.ENOSYS
+		return 0, syscall.ENOSYS
 	}
-	r1, _, errno := stdsyscall.Syscall(randomTrap,
+	r1, _, errno := syscall.Syscall(randomTrap,
 		uintptr(unsafe.Pointer(&p[0])),
 		uintptr(len(p)),
 		uintptr(flags))
 	if errno != 0 {
-		if errno == stdsyscall.ENOSYS {
+		if errno == syscall.ENOSYS {
 			atomic.StoreInt32(&randomUnsupported, 1)
 		}
 		return 0, errno
diff --git a/third_party/gofrontend/libgo/go/internal/syscall/windows/registry/export_test.go b/third_party/gofrontend/libgo/go/internal/syscall/windows/registry/export_test.go
new file mode 100644
index 0000000..8badf6f
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/internal/syscall/windows/registry/export_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 windows
+
+package registry
+
+func (k Key) SetValue(name string, valtype uint32, data []byte) error {
+	return k.setValue(name, valtype, data)
+}
diff --git a/third_party/gofrontend/libgo/go/internal/syscall/windows/registry/key.go b/third_party/gofrontend/libgo/go/internal/syscall/windows/registry/key.go
new file mode 100644
index 0000000..62144d3
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/internal/syscall/windows/registry/key.go
@@ -0,0 +1,175 @@
+// 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 windows
+
+// Package registry provides access to the Windows registry.
+//
+// Here is a simple example, opening a registry key and reading a string value from it.
+//
+//	k, err := registry.OpenKey(registry.LOCAL_MACHINE, `SOFTWARE\Microsoft\Windows NT\CurrentVersion`, registry.QUERY_VALUE)
+//	if err != nil {
+//		log.Fatal(err)
+//	}
+//	defer k.Close()
+//
+//	s, _, err := k.GetStringValue("SystemRoot")
+//	if err != nil {
+//		log.Fatal(err)
+//	}
+//	fmt.Printf("Windows system root is %q\n", s)
+//
+// NOTE: This package is a copy of golang.org/x/sys/windows/registry
+// with KeyInfo.ModTime removed to prevent dependency cycles.
+//
+package registry
+
+import (
+	"io"
+	"syscall"
+)
+
+const (
+	// Registry key security and access rights.
+	// See https://msdn.microsoft.com/en-us/library/windows/desktop/ms724878.aspx
+	// for details.
+	ALL_ACCESS         = 0xf003f
+	CREATE_LINK        = 0x00020
+	CREATE_SUB_KEY     = 0x00004
+	ENUMERATE_SUB_KEYS = 0x00008
+	EXECUTE            = 0x20019
+	NOTIFY             = 0x00010
+	QUERY_VALUE        = 0x00001
+	READ               = 0x20019
+	SET_VALUE          = 0x00002
+	WOW64_32KEY        = 0x00200
+	WOW64_64KEY        = 0x00100
+	WRITE              = 0x20006
+)
+
+// Key is a handle to an open Windows registry key.
+// Keys can be obtained by calling OpenKey; there are
+// also some predefined root keys such as CURRENT_USER.
+// Keys can be used directly in the Windows API.
+type Key syscall.Handle
+
+const (
+	// Windows defines some predefined root keys that are always open.
+	// An application can use these keys as entry points to the registry.
+	// Normally these keys are used in OpenKey to open new keys,
+	// but they can also be used anywhere a Key is required.
+	CLASSES_ROOT   = Key(syscall.HKEY_CLASSES_ROOT)
+	CURRENT_USER   = Key(syscall.HKEY_CURRENT_USER)
+	LOCAL_MACHINE  = Key(syscall.HKEY_LOCAL_MACHINE)
+	USERS          = Key(syscall.HKEY_USERS)
+	CURRENT_CONFIG = Key(syscall.HKEY_CURRENT_CONFIG)
+)
+
+// Close closes open key k.
+func (k Key) Close() error {
+	return syscall.RegCloseKey(syscall.Handle(k))
+}
+
+// OpenKey opens a new key with path name relative to key k.
+// It accepts any open key, including CURRENT_USER and others,
+// and returns the new key and an error.
+// The access parameter specifies desired access rights to the
+// key to be opened.
+func OpenKey(k Key, path string, access uint32) (Key, error) {
+	p, err := syscall.UTF16PtrFromString(path)
+	if err != nil {
+		return 0, err
+	}
+	var subkey syscall.Handle
+	err = syscall.RegOpenKeyEx(syscall.Handle(k), p, 0, access, &subkey)
+	if err != nil {
+		return 0, err
+	}
+	return Key(subkey), nil
+}
+
+// ReadSubKeyNames returns the names of subkeys of key k.
+// The parameter n controls the number of returned names,
+// analogous to the way os.File.Readdirnames works.
+func (k Key) ReadSubKeyNames(n int) ([]string, error) {
+	ki, err := k.Stat()
+	if err != nil {
+		return nil, err
+	}
+	names := make([]string, 0, ki.SubKeyCount)
+	buf := make([]uint16, ki.MaxSubKeyLen+1) // extra room for terminating zero byte
+loopItems:
+	for i := uint32(0); ; i++ {
+		if n > 0 {
+			if len(names) == n {
+				return names, nil
+			}
+		}
+		l := uint32(len(buf))
+		for {
+			err := syscall.RegEnumKeyEx(syscall.Handle(k), i, &buf[0], &l, nil, nil, nil, nil)
+			if err == nil {
+				break
+			}
+			if err == syscall.ERROR_MORE_DATA {
+				// Double buffer size and try again.
+				l = uint32(2 * len(buf))
+				buf = make([]uint16, l)
+				continue
+			}
+			if err == _ERROR_NO_MORE_ITEMS {
+				break loopItems
+			}
+			return names, err
+		}
+		names = append(names, syscall.UTF16ToString(buf[:l]))
+	}
+	if n > len(names) {
+		return names, io.EOF
+	}
+	return names, nil
+}
+
+// CreateKey creates a key named path under open key k.
+// CreateKey returns the new key and a boolean flag that reports
+// whether the key already existed.
+// The access parameter specifies the access rights for the key
+// to be created.
+func CreateKey(k Key, path string, access uint32) (newk Key, openedExisting bool, err error) {
+	var h syscall.Handle
+	var d uint32
+	err = regCreateKeyEx(syscall.Handle(k), syscall.StringToUTF16Ptr(path),
+		0, nil, _REG_OPTION_NON_VOLATILE, access, nil, &h, &d)
+	if err != nil {
+		return 0, false, err
+	}
+	return Key(h), d == _REG_OPENED_EXISTING_KEY, nil
+}
+
+// DeleteKey deletes the subkey path of key k and its values.
+func DeleteKey(k Key, path string) error {
+	return regDeleteKey(syscall.Handle(k), syscall.StringToUTF16Ptr(path))
+}
+
+// A KeyInfo describes the statistics of a key. It is returned by Stat.
+type KeyInfo struct {
+	SubKeyCount     uint32
+	MaxSubKeyLen    uint32 // size of the key's subkey with the longest name, in Unicode characters, not including the terminating zero byte
+	ValueCount      uint32
+	MaxValueNameLen uint32 // size of the key's longest value name, in Unicode characters, not including the terminating zero byte
+	MaxValueLen     uint32 // longest data component among the key's values, in bytes
+	lastWriteTime   syscall.Filetime
+}
+
+// Stat retrieves information about the open key k.
+func (k Key) Stat() (*KeyInfo, error) {
+	var ki KeyInfo
+	err := syscall.RegQueryInfoKey(syscall.Handle(k), nil, nil, nil,
+		&ki.SubKeyCount, &ki.MaxSubKeyLen, nil, &ki.ValueCount,
+		&ki.MaxValueNameLen, &ki.MaxValueLen, nil, &ki.lastWriteTime)
+	if err != nil {
+		return nil, err
+	}
+	return &ki, nil
+}
diff --git a/third_party/gofrontend/libgo/go/internal/syscall/windows/registry/registry_test.go b/third_party/gofrontend/libgo/go/internal/syscall/windows/registry/registry_test.go
new file mode 100644
index 0000000..07eccb2
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/internal/syscall/windows/registry/registry_test.go
@@ -0,0 +1,678 @@
+// 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 windows
+
+package registry_test
+
+import (
+	"bytes"
+	"crypto/rand"
+	"os"
+	"syscall"
+	"testing"
+
+	"internal/syscall/windows/registry"
+)
+
+func randKeyName(prefix string) string {
+	const numbers = "0123456789"
+	buf := make([]byte, 10)
+	rand.Read(buf)
+	for i, b := range buf {
+		buf[i] = numbers[b%byte(len(numbers))]
+	}
+	return prefix + string(buf)
+}
+
+func TestReadSubKeyNames(t *testing.T) {
+	k, err := registry.OpenKey(registry.CLASSES_ROOT, "TypeLib", registry.ENUMERATE_SUB_KEYS|registry.QUERY_VALUE)
+	if err != nil {
+		t.Fatal(err)
+	}
+	defer k.Close()
+
+	names, err := k.ReadSubKeyNames(-1)
+	if err != nil {
+		t.Fatal(err)
+	}
+	var foundStdOle bool
+	for _, name := range names {
+		// Every PC has "stdole 2.0 OLE Automation" library installed.
+		if name == "{00020430-0000-0000-C000-000000000046}" {
+			foundStdOle = true
+		}
+	}
+	if !foundStdOle {
+		t.Fatal("could not find stdole 2.0 OLE Automation")
+	}
+}
+
+func TestCreateOpenDeleteKey(t *testing.T) {
+	k, err := registry.OpenKey(registry.CURRENT_USER, "Software", registry.QUERY_VALUE)
+	if err != nil {
+		t.Fatal(err)
+	}
+	defer k.Close()
+
+	testKName := randKeyName("TestCreateOpenDeleteKey_")
+
+	testK, exist, err := registry.CreateKey(k, testKName, registry.CREATE_SUB_KEY)
+	if err != nil {
+		t.Fatal(err)
+	}
+	defer testK.Close()
+
+	if exist {
+		t.Fatalf("key %q already exists", testKName)
+	}
+
+	testKAgain, exist, err := registry.CreateKey(k, testKName, registry.CREATE_SUB_KEY)
+	if err != nil {
+		t.Fatal(err)
+	}
+	defer testKAgain.Close()
+
+	if !exist {
+		t.Fatalf("key %q should already exist", testKName)
+	}
+
+	testKOpened, err := registry.OpenKey(k, testKName, registry.ENUMERATE_SUB_KEYS)
+	if err != nil {
+		t.Fatal(err)
+	}
+	defer testKOpened.Close()
+
+	err = registry.DeleteKey(k, testKName)
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	testKOpenedAgain, err := registry.OpenKey(k, testKName, registry.ENUMERATE_SUB_KEYS)
+	if err == nil {
+		defer testKOpenedAgain.Close()
+		t.Fatalf("key %q should already been deleted", testKName)
+	}
+	if err != registry.ErrNotExist {
+		t.Fatalf(`unexpected error ("not exist" expected): %v`, err)
+	}
+}
+
+func equalStringSlice(a, b []string) bool {
+	if len(a) != len(b) {
+		return false
+	}
+	if a == nil {
+		return true
+	}
+	for i := range a {
+		if a[i] != b[i] {
+			return false
+		}
+	}
+	return true
+}
+
+type ValueTest struct {
+	Type     uint32
+	Name     string
+	Value    interface{}
+	WillFail bool
+}
+
+var ValueTests = []ValueTest{
+	{Type: registry.SZ, Name: "String1", Value: ""},
+	{Type: registry.SZ, Name: "String2", Value: "\000", WillFail: true},
+	{Type: registry.SZ, Name: "String3", Value: "Hello World"},
+	{Type: registry.SZ, Name: "String4", Value: "Hello World\000", WillFail: true},
+	{Type: registry.EXPAND_SZ, Name: "ExpString1", Value: ""},
+	{Type: registry.EXPAND_SZ, Name: "ExpString2", Value: "\000", WillFail: true},
+	{Type: registry.EXPAND_SZ, Name: "ExpString3", Value: "Hello World"},
+	{Type: registry.EXPAND_SZ, Name: "ExpString4", Value: "Hello\000World", WillFail: true},
+	{Type: registry.EXPAND_SZ, Name: "ExpString5", Value: "%PATH%"},
+	{Type: registry.EXPAND_SZ, Name: "ExpString6", Value: "%NO_SUCH_VARIABLE%"},
+	{Type: registry.EXPAND_SZ, Name: "ExpString7", Value: "%PATH%;."},
+	{Type: registry.BINARY, Name: "Binary1", Value: []byte{}},
+	{Type: registry.BINARY, Name: "Binary2", Value: []byte{1, 2, 3}},
+	{Type: registry.BINARY, Name: "Binary3", Value: []byte{3, 2, 1, 0, 1, 2, 3}},
+	{Type: registry.DWORD, Name: "Dword1", Value: uint64(0)},
+	{Type: registry.DWORD, Name: "Dword2", Value: uint64(1)},
+	{Type: registry.DWORD, Name: "Dword3", Value: uint64(0xff)},
+	{Type: registry.DWORD, Name: "Dword4", Value: uint64(0xffff)},
+	{Type: registry.QWORD, Name: "Qword1", Value: uint64(0)},
+	{Type: registry.QWORD, Name: "Qword2", Value: uint64(1)},
+	{Type: registry.QWORD, Name: "Qword3", Value: uint64(0xff)},
+	{Type: registry.QWORD, Name: "Qword4", Value: uint64(0xffff)},
+	{Type: registry.QWORD, Name: "Qword5", Value: uint64(0xffffff)},
+	{Type: registry.QWORD, Name: "Qword6", Value: uint64(0xffffffff)},
+	{Type: registry.MULTI_SZ, Name: "MultiString1", Value: []string{"a", "b", "c"}},
+	{Type: registry.MULTI_SZ, Name: "MultiString2", Value: []string{"abc", "", "cba"}},
+	{Type: registry.MULTI_SZ, Name: "MultiString3", Value: []string{""}},
+	{Type: registry.MULTI_SZ, Name: "MultiString4", Value: []string{"abcdef"}},
+	{Type: registry.MULTI_SZ, Name: "MultiString5", Value: []string{"\000"}, WillFail: true},
+	{Type: registry.MULTI_SZ, Name: "MultiString6", Value: []string{"a\000b"}, WillFail: true},
+	{Type: registry.MULTI_SZ, Name: "MultiString7", Value: []string{"ab", "\000", "cd"}, WillFail: true},
+	{Type: registry.MULTI_SZ, Name: "MultiString8", Value: []string{"\000", "cd"}, WillFail: true},
+	{Type: registry.MULTI_SZ, Name: "MultiString9", Value: []string{"ab", "\000"}, WillFail: true},
+}
+
+func setValues(t *testing.T, k registry.Key) {
+	for _, test := range ValueTests {
+		var err error
+		switch test.Type {
+		case registry.SZ:
+			err = k.SetStringValue(test.Name, test.Value.(string))
+		case registry.EXPAND_SZ:
+			err = k.SetExpandStringValue(test.Name, test.Value.(string))
+		case registry.MULTI_SZ:
+			err = k.SetStringsValue(test.Name, test.Value.([]string))
+		case registry.BINARY:
+			err = k.SetBinaryValue(test.Name, test.Value.([]byte))
+		case registry.DWORD:
+			err = k.SetDWordValue(test.Name, uint32(test.Value.(uint64)))
+		case registry.QWORD:
+			err = k.SetQWordValue(test.Name, test.Value.(uint64))
+		default:
+			t.Fatalf("unsupported type %d for %s value", test.Type, test.Name)
+		}
+		if test.WillFail {
+			if err == nil {
+				t.Fatalf("setting %s value %q should fail, but succeeded", test.Name, test.Value)
+			}
+		} else {
+			if err != nil {
+				t.Fatal(err)
+			}
+		}
+	}
+}
+
+func enumerateValues(t *testing.T, k registry.Key) {
+	names, err := k.ReadValueNames(-1)
+	if err != nil {
+		t.Error(err)
+		return
+	}
+	haveNames := make(map[string]bool)
+	for _, n := range names {
+		haveNames[n] = false
+	}
+	for _, test := range ValueTests {
+		wantFound := !test.WillFail
+		_, haveFound := haveNames[test.Name]
+		if wantFound && !haveFound {
+			t.Errorf("value %s is not found while enumerating", test.Name)
+		}
+		if haveFound && !wantFound {
+			t.Errorf("value %s is found while enumerating, but expected to fail", test.Name)
+		}
+		if haveFound {
+			delete(haveNames, test.Name)
+		}
+	}
+	for n, v := range haveNames {
+		t.Errorf("value %s (%v) is found while enumerating, but has not been cretaed", n, v)
+	}
+}
+
+func testErrNotExist(t *testing.T, name string, err error) {
+	if err == nil {
+		t.Errorf("%s value should not exist", name)
+		return
+	}
+	if err != registry.ErrNotExist {
+		t.Errorf("reading %s value should return 'not exist' error, but got: %s", name, err)
+		return
+	}
+}
+
+func testErrUnexpectedType(t *testing.T, test ValueTest, gottype uint32, err error) {
+	if err == nil {
+		t.Errorf("GetXValue(%q) should not succeed", test.Name)
+		return
+	}
+	if err != registry.ErrUnexpectedType {
+		t.Errorf("reading %s value should return 'unexpected key value type' error, but got: %s", test.Name, err)
+		return
+	}
+	if gottype != test.Type {
+		t.Errorf("want %s value type %v, got %v", test.Name, test.Type, gottype)
+		return
+	}
+}
+
+func testGetStringValue(t *testing.T, k registry.Key, test ValueTest) {
+	got, gottype, err := k.GetStringValue(test.Name)
+	if err != nil {
+		t.Errorf("GetStringValue(%s) failed: %v", test.Name, err)
+		return
+	}
+	if got != test.Value {
+		t.Errorf("want %s value %q, got %q", test.Name, test.Value, got)
+		return
+	}
+	if gottype != test.Type {
+		t.Errorf("want %s value type %v, got %v", test.Name, test.Type, gottype)
+		return
+	}
+	if gottype == registry.EXPAND_SZ {
+		_, err = registry.ExpandString(got)
+		if err != nil {
+			t.Errorf("ExpandString(%s) failed: %v", got, err)
+			return
+		}
+	}
+}
+
+func testGetIntegerValue(t *testing.T, k registry.Key, test ValueTest) {
+	got, gottype, err := k.GetIntegerValue(test.Name)
+	if err != nil {
+		t.Errorf("GetIntegerValue(%s) failed: %v", test.Name, err)
+		return
+	}
+	if got != test.Value.(uint64) {
+		t.Errorf("want %s value %v, got %v", test.Name, test.Value, got)
+		return
+	}
+	if gottype != test.Type {
+		t.Errorf("want %s value type %v, got %v", test.Name, test.Type, gottype)
+		return
+	}
+}
+
+func testGetBinaryValue(t *testing.T, k registry.Key, test ValueTest) {
+	got, gottype, err := k.GetBinaryValue(test.Name)
+	if err != nil {
+		t.Errorf("GetBinaryValue(%s) failed: %v", test.Name, err)
+		return
+	}
+	if !bytes.Equal(got, test.Value.([]byte)) {
+		t.Errorf("want %s value %v, got %v", test.Name, test.Value, got)
+		return
+	}
+	if gottype != test.Type {
+		t.Errorf("want %s value type %v, got %v", test.Name, test.Type, gottype)
+		return
+	}
+}
+
+func testGetStringsValue(t *testing.T, k registry.Key, test ValueTest) {
+	got, gottype, err := k.GetStringsValue(test.Name)
+	if err != nil {
+		t.Errorf("GetStringsValue(%s) failed: %v", test.Name, err)
+		return
+	}
+	if !equalStringSlice(got, test.Value.([]string)) {
+		t.Errorf("want %s value %#v, got %#v", test.Name, test.Value, got)
+		return
+	}
+	if gottype != test.Type {
+		t.Errorf("want %s value type %v, got %v", test.Name, test.Type, gottype)
+		return
+	}
+}
+
+func testGetValue(t *testing.T, k registry.Key, test ValueTest, size int) {
+	if size <= 0 {
+		return
+	}
+	// read data with no buffer
+	gotsize, gottype, err := k.GetValue(test.Name, nil)
+	if err != nil {
+		t.Errorf("GetValue(%s, [%d]byte) failed: %v", test.Name, size, err)
+		return
+	}
+	if gotsize != size {
+		t.Errorf("want %s value size of %d, got %v", test.Name, size, gotsize)
+		return
+	}
+	if gottype != test.Type {
+		t.Errorf("want %s value type %v, got %v", test.Name, test.Type, gottype)
+		return
+	}
+	// read data with short buffer
+	gotsize, gottype, err = k.GetValue(test.Name, make([]byte, size-1))
+	if err == nil {
+		t.Errorf("GetValue(%s, [%d]byte) should fail, but suceeded", test.Name, size-1)
+		return
+	}
+	if err != registry.ErrShortBuffer {
+		t.Errorf("reading %s value should return 'short buffer' error, but got: %s", test.Name, err)
+		return
+	}
+	if gotsize != size {
+		t.Errorf("want %s value size of %d, got %v", test.Name, size, gotsize)
+		return
+	}
+	if gottype != test.Type {
+		t.Errorf("want %s value type %v, got %v", test.Name, test.Type, gottype)
+		return
+	}
+	// read full data
+	gotsize, gottype, err = k.GetValue(test.Name, make([]byte, size))
+	if err != nil {
+		t.Errorf("GetValue(%s, [%d]byte) failed: %v", test.Name, size, err)
+		return
+	}
+	if gotsize != size {
+		t.Errorf("want %s value size of %d, got %v", test.Name, size, gotsize)
+		return
+	}
+	if gottype != test.Type {
+		t.Errorf("want %s value type %v, got %v", test.Name, test.Type, gottype)
+		return
+	}
+	// check GetValue returns ErrNotExist as required
+	_, _, err = k.GetValue(test.Name+"_not_there", make([]byte, size))
+	if err == nil {
+		t.Errorf("GetValue(%q) should not succeed", test.Name)
+		return
+	}
+	if err != registry.ErrNotExist {
+		t.Errorf("GetValue(%q) should return 'not exist' error, but got: %s", test.Name, err)
+		return
+	}
+}
+
+func testValues(t *testing.T, k registry.Key) {
+	for _, test := range ValueTests {
+		switch test.Type {
+		case registry.SZ, registry.EXPAND_SZ:
+			if test.WillFail {
+				_, _, err := k.GetStringValue(test.Name)
+				testErrNotExist(t, test.Name, err)
+			} else {
+				testGetStringValue(t, k, test)
+				_, gottype, err := k.GetIntegerValue(test.Name)
+				testErrUnexpectedType(t, test, gottype, err)
+				// Size of utf16 string in bytes is not perfect,
+				// but correct for current test values.
+				// Size also includes terminating 0.
+				testGetValue(t, k, test, (len(test.Value.(string))+1)*2)
+			}
+			_, _, err := k.GetStringValue(test.Name + "_string_not_created")
+			testErrNotExist(t, test.Name+"_string_not_created", err)
+		case registry.DWORD, registry.QWORD:
+			testGetIntegerValue(t, k, test)
+			_, gottype, err := k.GetBinaryValue(test.Name)
+			testErrUnexpectedType(t, test, gottype, err)
+			_, _, err = k.GetIntegerValue(test.Name + "_int_not_created")
+			testErrNotExist(t, test.Name+"_int_not_created", err)
+			size := 8
+			if test.Type == registry.DWORD {
+				size = 4
+			}
+			testGetValue(t, k, test, size)
+		case registry.BINARY:
+			testGetBinaryValue(t, k, test)
+			_, gottype, err := k.GetStringsValue(test.Name)
+			testErrUnexpectedType(t, test, gottype, err)
+			_, _, err = k.GetBinaryValue(test.Name + "_byte_not_created")
+			testErrNotExist(t, test.Name+"_byte_not_created", err)
+			testGetValue(t, k, test, len(test.Value.([]byte)))
+		case registry.MULTI_SZ:
+			if test.WillFail {
+				_, _, err := k.GetStringsValue(test.Name)
+				testErrNotExist(t, test.Name, err)
+			} else {
+				testGetStringsValue(t, k, test)
+				_, gottype, err := k.GetStringValue(test.Name)
+				testErrUnexpectedType(t, test, gottype, err)
+				size := 0
+				for _, s := range test.Value.([]string) {
+					size += len(s) + 1 // nil terminated
+				}
+				size += 1 // extra nil at the end
+				size *= 2 // count bytes, not uint16
+				testGetValue(t, k, test, size)
+			}
+			_, _, err := k.GetStringsValue(test.Name + "_strings_not_created")
+			testErrNotExist(t, test.Name+"_strings_not_created", err)
+		default:
+			t.Errorf("unsupported type %d for %s value", test.Type, test.Name)
+			continue
+		}
+	}
+}
+
+func testStat(t *testing.T, k registry.Key) {
+	subk, _, err := registry.CreateKey(k, "subkey", registry.CREATE_SUB_KEY)
+	if err != nil {
+		t.Error(err)
+		return
+	}
+	defer subk.Close()
+
+	defer registry.DeleteKey(k, "subkey")
+
+	ki, err := k.Stat()
+	if err != nil {
+		t.Error(err)
+		return
+	}
+	if ki.SubKeyCount != 1 {
+		t.Error("key must have 1 subkey")
+	}
+	if ki.MaxSubKeyLen != 6 {
+		t.Error("key max subkey name length must be 6")
+	}
+	if ki.ValueCount != 24 {
+		t.Errorf("key must have 24 values, but is %d", ki.ValueCount)
+	}
+	if ki.MaxValueNameLen != 12 {
+		t.Errorf("key max value name length must be 10, but is %d", ki.MaxValueNameLen)
+	}
+	if ki.MaxValueLen != 38 {
+		t.Errorf("key max value length must be 38, but is %d", ki.MaxValueLen)
+	}
+}
+
+func deleteValues(t *testing.T, k registry.Key) {
+	for _, test := range ValueTests {
+		if test.WillFail {
+			continue
+		}
+		err := k.DeleteValue(test.Name)
+		if err != nil {
+			t.Error(err)
+			continue
+		}
+	}
+	names, err := k.ReadValueNames(-1)
+	if err != nil {
+		t.Error(err)
+		return
+	}
+	if len(names) != 0 {
+		t.Errorf("some values remain after deletion: %v", names)
+	}
+}
+
+func TestValues(t *testing.T) {
+	softwareK, err := registry.OpenKey(registry.CURRENT_USER, "Software", registry.QUERY_VALUE)
+	if err != nil {
+		t.Fatal(err)
+	}
+	defer softwareK.Close()
+
+	testKName := randKeyName("TestValues_")
+
+	k, exist, err := registry.CreateKey(softwareK, testKName, registry.CREATE_SUB_KEY|registry.QUERY_VALUE|registry.SET_VALUE)
+	if err != nil {
+		t.Fatal(err)
+	}
+	defer k.Close()
+
+	if exist {
+		t.Fatalf("key %q already exists", testKName)
+	}
+
+	defer registry.DeleteKey(softwareK, testKName)
+
+	setValues(t, k)
+
+	enumerateValues(t, k)
+
+	testValues(t, k)
+
+	testStat(t, k)
+
+	deleteValues(t, k)
+}
+
+func walkKey(t *testing.T, k registry.Key, kname string) {
+	names, err := k.ReadValueNames(-1)
+	if err != nil {
+		t.Fatalf("reading value names of %s failed: %v", kname, err)
+	}
+	for _, name := range names {
+		_, valtype, err := k.GetValue(name, nil)
+		if err != nil {
+			t.Fatalf("reading value type of %s of %s failed: %v", name, kname, err)
+		}
+		switch valtype {
+		case registry.NONE:
+		case registry.SZ:
+			_, _, err := k.GetStringValue(name)
+			if err != nil {
+				t.Error(err)
+			}
+		case registry.EXPAND_SZ:
+			s, _, err := k.GetStringValue(name)
+			if err != nil {
+				t.Error(err)
+			}
+			_, err = registry.ExpandString(s)
+			if err != nil {
+				t.Error(err)
+			}
+		case registry.DWORD, registry.QWORD:
+			_, _, err := k.GetIntegerValue(name)
+			if err != nil {
+				t.Error(err)
+			}
+		case registry.BINARY:
+			_, _, err := k.GetBinaryValue(name)
+			if err != nil {
+				t.Error(err)
+			}
+		case registry.MULTI_SZ:
+			_, _, err := k.GetStringsValue(name)
+			if err != nil {
+				t.Error(err)
+			}
+		case registry.FULL_RESOURCE_DESCRIPTOR, registry.RESOURCE_LIST, registry.RESOURCE_REQUIREMENTS_LIST:
+			// TODO: not implemented
+		default:
+			t.Fatalf("value type %d of %s of %s failed: %v", valtype, name, kname, err)
+		}
+	}
+
+	names, err = k.ReadSubKeyNames(-1)
+	if err != nil {
+		t.Fatalf("reading sub-keys of %s failed: %v", kname, err)
+	}
+	for _, name := range names {
+		func() {
+			subk, err := registry.OpenKey(k, name, registry.ENUMERATE_SUB_KEYS|registry.QUERY_VALUE)
+			if err != nil {
+				if err == syscall.ERROR_ACCESS_DENIED {
+					// ignore error, if we are not allowed to access this key
+					return
+				}
+				t.Fatalf("opening sub-keys %s of %s failed: %v", name, kname, err)
+			}
+			defer subk.Close()
+
+			walkKey(t, subk, kname+`\`+name)
+		}()
+	}
+}
+
+func TestWalkFullRegistry(t *testing.T) {
+	if testing.Short() {
+		t.Skip("skipping long running test in short mode")
+	}
+	walkKey(t, registry.CLASSES_ROOT, "CLASSES_ROOT")
+	walkKey(t, registry.CURRENT_USER, "CURRENT_USER")
+	walkKey(t, registry.LOCAL_MACHINE, "LOCAL_MACHINE")
+	walkKey(t, registry.USERS, "USERS")
+	walkKey(t, registry.CURRENT_CONFIG, "CURRENT_CONFIG")
+}
+
+func TestExpandString(t *testing.T) {
+	got, err := registry.ExpandString("%PATH%")
+	if err != nil {
+		t.Fatal(err)
+	}
+	want := os.Getenv("PATH")
+	if got != want {
+		t.Errorf("want %q string expanded, got %q", want, got)
+	}
+}
+
+func TestInvalidValues(t *testing.T) {
+	softwareK, err := registry.OpenKey(registry.CURRENT_USER, "Software", registry.QUERY_VALUE)
+	if err != nil {
+		t.Fatal(err)
+	}
+	defer softwareK.Close()
+
+	testKName := randKeyName("TestInvalidValues_")
+
+	k, exist, err := registry.CreateKey(softwareK, testKName, registry.CREATE_SUB_KEY|registry.QUERY_VALUE|registry.SET_VALUE)
+	if err != nil {
+		t.Fatal(err)
+	}
+	defer k.Close()
+
+	if exist {
+		t.Fatalf("key %q already exists", testKName)
+	}
+
+	defer registry.DeleteKey(softwareK, testKName)
+
+	var tests = []struct {
+		Type uint32
+		Name string
+		Data []byte
+	}{
+		{registry.DWORD, "Dword1", nil},
+		{registry.DWORD, "Dword2", []byte{1, 2, 3}},
+		{registry.QWORD, "Qword1", nil},
+		{registry.QWORD, "Qword2", []byte{1, 2, 3}},
+		{registry.QWORD, "Qword3", []byte{1, 2, 3, 4, 5, 6, 7}},
+		{registry.MULTI_SZ, "MultiString1", nil},
+		{registry.MULTI_SZ, "MultiString2", []byte{0}},
+		{registry.MULTI_SZ, "MultiString3", []byte{'a', 'b', 0}},
+		{registry.MULTI_SZ, "MultiString4", []byte{'a', 0, 0, 'b', 0}},
+		{registry.MULTI_SZ, "MultiString5", []byte{'a', 0, 0}},
+	}
+
+	for _, test := range tests {
+		err := k.SetValue(test.Name, test.Type, test.Data)
+		if err != nil {
+			t.Fatalf("SetValue for %q failed: %v", test.Name, err)
+		}
+	}
+
+	for _, test := range tests {
+		switch test.Type {
+		case registry.DWORD, registry.QWORD:
+			value, valType, err := k.GetIntegerValue(test.Name)
+			if err == nil {
+				t.Errorf("GetIntegerValue(%q) succeeded. Returns type=%d value=%v", test.Name, valType, value)
+			}
+		case registry.MULTI_SZ:
+			value, valType, err := k.GetStringsValue(test.Name)
+			if err == nil {
+				if len(value) != 0 {
+					t.Errorf("GetStringsValue(%q) succeeded. Returns type=%d value=%v", test.Name, valType, value)
+				}
+			}
+		default:
+			t.Errorf("unsupported type %d for %s value", test.Type, test.Name)
+		}
+	}
+}
diff --git a/third_party/gofrontend/libgo/go/internal/syscall/windows/registry/syscall.go b/third_party/gofrontend/libgo/go/internal/syscall/windows/registry/syscall.go
new file mode 100644
index 0000000..38e573f
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/internal/syscall/windows/registry/syscall.go
@@ -0,0 +1,28 @@
+// 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 windows
+
+package registry
+
+import "syscall"
+
+//go:generate go run $GOROOT/src/syscall/mksyscall_windows.go -output zsyscall_windows.go syscall.go
+
+const (
+	_REG_OPTION_NON_VOLATILE = 0
+
+	_REG_CREATED_NEW_KEY     = 1
+	_REG_OPENED_EXISTING_KEY = 2
+
+	_ERROR_NO_MORE_ITEMS syscall.Errno = 259
+)
+
+//sys	regCreateKeyEx(key syscall.Handle, subkey *uint16, reserved uint32, class *uint16, options uint32, desired uint32, sa *syscall.SecurityAttributes, result *syscall.Handle, disposition *uint32) (regerrno error) = advapi32.RegCreateKeyExW
+//sys	regDeleteKey(key syscall.Handle, subkey *uint16) (regerrno error) = advapi32.RegDeleteKeyW
+//sys	regSetValueEx(key syscall.Handle, valueName *uint16, reserved uint32, vtype uint32, buf *byte, bufsize uint32) (regerrno error) = advapi32.RegSetValueExW
+//sys	regEnumValue(key syscall.Handle, index uint32, name *uint16, nameLen *uint32, reserved *uint32, valtype *uint32, buf *byte, buflen *uint32) (regerrno error) = advapi32.RegEnumValueW
+//sys	regDeleteValue(key syscall.Handle, name *uint16) (regerrno error) = advapi32.RegDeleteValueW
+
+//sys	expandEnvironmentStrings(src *uint16, dst *uint16, size uint32) (n uint32, err error) = kernel32.ExpandEnvironmentStringsW
diff --git a/third_party/gofrontend/libgo/go/internal/syscall/windows/registry/value.go b/third_party/gofrontend/libgo/go/internal/syscall/windows/registry/value.go
new file mode 100644
index 0000000..f4bb1b3
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/internal/syscall/windows/registry/value.go
@@ -0,0 +1,329 @@
+// 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 windows
+
+package registry
+
+import (
+	"errors"
+	"io"
+	"syscall"
+	"unicode/utf16"
+	"unsafe"
+)
+
+const (
+	// Registry value types.
+	NONE                       = 0
+	SZ                         = 1
+	EXPAND_SZ                  = 2
+	BINARY                     = 3
+	DWORD                      = 4
+	DWORD_BIG_ENDIAN           = 5
+	LINK                       = 6
+	MULTI_SZ                   = 7
+	RESOURCE_LIST              = 8
+	FULL_RESOURCE_DESCRIPTOR   = 9
+	RESOURCE_REQUIREMENTS_LIST = 10
+	QWORD                      = 11
+)
+
+var (
+	// ErrShortBuffer is returned when the buffer was too short for the operation.
+	ErrShortBuffer = syscall.ERROR_MORE_DATA
+
+	// ErrNotExist is returned when a registry key or value does not exist.
+	ErrNotExist = syscall.ERROR_FILE_NOT_FOUND
+
+	// ErrUnexpectedType is returned by Get*Value when the value's type was unexpected.
+	ErrUnexpectedType = errors.New("unexpected key value type")
+)
+
+// GetValue retrieves the type and data for the specified value associated
+// with an open key k. It fills up buffer buf and returns the retrieved
+// byte count n. If buf is too small to fit the stored value it returns
+// ErrShortBuffer error along with the required buffer size n.
+// If no buffer is provided, it returns true and actual buffer size n.
+// If no buffer is provided, GetValue returns the value's type only.
+// If the value does not exist, the error returned is ErrNotExist.
+//
+// GetValue is a low level function. If value's type is known, use the appropriate
+// Get*Value function instead.
+func (k Key) GetValue(name string, buf []byte) (n int, valtype uint32, err error) {
+	pname, err := syscall.UTF16PtrFromString(name)
+	if err != nil {
+		return 0, 0, err
+	}
+	var pbuf *byte
+	if len(buf) > 0 {
+		pbuf = (*byte)(unsafe.Pointer(&buf[0]))
+	}
+	l := uint32(len(buf))
+	err = syscall.RegQueryValueEx(syscall.Handle(k), pname, nil, &valtype, pbuf, &l)
+	if err != nil {
+		return int(l), valtype, err
+	}
+	return int(l), valtype, nil
+}
+
+func (k Key) getValue(name string, buf []byte) (date []byte, valtype uint32, err error) {
+	p, err := syscall.UTF16PtrFromString(name)
+	if err != nil {
+		return nil, 0, err
+	}
+	var t uint32
+	n := uint32(len(buf))
+	for {
+		err = syscall.RegQueryValueEx(syscall.Handle(k), p, nil, &t, (*byte)(unsafe.Pointer(&buf[0])), &n)
+		if err == nil {
+			return buf[:n], t, nil
+		}
+		if err != syscall.ERROR_MORE_DATA {
+			return nil, 0, err
+		}
+		if n <= uint32(len(buf)) {
+			return nil, 0, err
+		}
+		buf = make([]byte, n)
+	}
+}
+
+// GetStringValue retrieves the string value for the specified
+// value name associated with an open key k. It also returns the value's type.
+// If value does not exist, GetStringValue returns ErrNotExist.
+// If value is not SZ or EXPAND_SZ, it will return the correct value
+// type and ErrUnexpectedType.
+func (k Key) GetStringValue(name string) (val string, valtype uint32, err error) {
+	data, typ, err2 := k.getValue(name, make([]byte, 64))
+	if err2 != nil {
+		return "", typ, err2
+	}
+	switch typ {
+	case SZ, EXPAND_SZ:
+	default:
+		return "", typ, ErrUnexpectedType
+	}
+	if len(data) == 0 {
+		return "", typ, nil
+	}
+	u := (*[1 << 10]uint16)(unsafe.Pointer(&data[0]))[:]
+	return syscall.UTF16ToString(u), typ, nil
+}
+
+// ExpandString expands environment-variable strings and replaces
+// them with the values defined for the current user.
+// Use ExpandString to expand EXPAND_SZ strings.
+func ExpandString(value string) (string, error) {
+	if value == "" {
+		return "", nil
+	}
+	p, err := syscall.UTF16PtrFromString(value)
+	if err != nil {
+		return "", err
+	}
+	r := make([]uint16, 100)
+	for {
+		n, err := expandEnvironmentStrings(p, &r[0], uint32(len(r)))
+		if err != nil {
+			return "", err
+		}
+		if n <= uint32(len(r)) {
+			u := (*[1 << 15]uint16)(unsafe.Pointer(&r[0]))[:]
+			return syscall.UTF16ToString(u), nil
+		}
+		r = make([]uint16, n)
+	}
+}
+
+// GetStringsValue retrieves the []string value for the specified
+// value name associated with an open key k. It also returns the value's type.
+// If value does not exist, GetStringsValue returns ErrNotExist.
+// If value is not MULTI_SZ, it will return the correct value
+// type and ErrUnexpectedType.
+func (k Key) GetStringsValue(name string) (val []string, valtype uint32, err error) {
+	data, typ, err2 := k.getValue(name, make([]byte, 64))
+	if err2 != nil {
+		return nil, typ, err2
+	}
+	if typ != MULTI_SZ {
+		return nil, typ, ErrUnexpectedType
+	}
+	if len(data) == 0 {
+		return nil, typ, nil
+	}
+	p := (*[1 << 24]uint16)(unsafe.Pointer(&data[0]))[:len(data)/2]
+	if len(p) == 0 {
+		return nil, typ, nil
+	}
+	if p[len(p)-1] == 0 {
+		p = p[:len(p)-1] // remove terminating null
+	}
+	val = make([]string, 0, 5)
+	from := 0
+	for i, c := range p {
+		if c == 0 {
+			val = append(val, string(utf16.Decode(p[from:i])))
+			from = i + 1
+		}
+	}
+	return val, typ, nil
+}
+
+// GetIntegerValue retrieves the integer value for the specified
+// value name associated with an open key k. It also returns the value's type.
+// If value does not exist, GetIntegerValue returns ErrNotExist.
+// If value is not DWORD or QWORD, it will return the correct value
+// type and ErrUnexpectedType.
+func (k Key) GetIntegerValue(name string) (val uint64, valtype uint32, err error) {
+	data, typ, err2 := k.getValue(name, make([]byte, 8))
+	if err2 != nil {
+		return 0, typ, err2
+	}
+	switch typ {
+	case DWORD:
+		if len(data) != 4 {
+			return 0, typ, errors.New("DWORD value is not 4 bytes long")
+		}
+		return uint64(*(*uint32)(unsafe.Pointer(&data[0]))), DWORD, nil
+	case QWORD:
+		if len(data) != 8 {
+			return 0, typ, errors.New("QWORD value is not 8 bytes long")
+		}
+		return uint64(*(*uint64)(unsafe.Pointer(&data[0]))), QWORD, nil
+	default:
+		return 0, typ, ErrUnexpectedType
+	}
+}
+
+// GetBinaryValue retrieves the binary value for the specified
+// value name associated with an open key k. It also returns the value's type.
+// If value does not exist, GetBinaryValue returns ErrNotExist.
+// If value is not BINARY, it will return the correct value
+// type and ErrUnexpectedType.
+func (k Key) GetBinaryValue(name string) (val []byte, valtype uint32, err error) {
+	data, typ, err2 := k.getValue(name, make([]byte, 64))
+	if err2 != nil {
+		return nil, typ, err2
+	}
+	if typ != BINARY {
+		return nil, typ, ErrUnexpectedType
+	}
+	return data, typ, nil
+}
+
+func (k Key) setValue(name string, valtype uint32, data []byte) error {
+	p, err := syscall.UTF16PtrFromString(name)
+	if err != nil {
+		return err
+	}
+	if len(data) == 0 {
+		return regSetValueEx(syscall.Handle(k), p, 0, valtype, nil, 0)
+	}
+	return regSetValueEx(syscall.Handle(k), p, 0, valtype, &data[0], uint32(len(data)))
+}
+
+// SetDWordValue sets the data and type of a name value
+// under key k to value and DWORD.
+func (k Key) SetDWordValue(name string, value uint32) error {
+	return k.setValue(name, DWORD, (*[4]byte)(unsafe.Pointer(&value))[:])
+}
+
+// SetQWordValue sets the data and type of a name value
+// under key k to value and QWORD.
+func (k Key) SetQWordValue(name string, value uint64) error {
+	return k.setValue(name, QWORD, (*[8]byte)(unsafe.Pointer(&value))[:])
+}
+
+func (k Key) setStringValue(name string, valtype uint32, value string) error {
+	v, err := syscall.UTF16FromString(value)
+	if err != nil {
+		return err
+	}
+	buf := (*[1 << 10]byte)(unsafe.Pointer(&v[0]))[:len(v)*2]
+	return k.setValue(name, valtype, buf)
+}
+
+// SetStringValue sets the data and type of a name value
+// under key k to value and SZ. The value must not contain a zero byte.
+func (k Key) SetStringValue(name, value string) error {
+	return k.setStringValue(name, SZ, value)
+}
+
+// SetExpandStringValue sets the data and type of a name value
+// under key k to value and EXPAND_SZ. The value must not contain a zero byte.
+func (k Key) SetExpandStringValue(name, value string) error {
+	return k.setStringValue(name, EXPAND_SZ, value)
+}
+
+// SetStringsValue sets the data and type of a name value
+// under key k to value and MULTI_SZ. The value strings
+// must not contain a zero byte.
+func (k Key) SetStringsValue(name string, value []string) error {
+	ss := ""
+	for _, s := range value {
+		for i := 0; i < len(s); i++ {
+			if s[i] == 0 {
+				return errors.New("string cannot have 0 inside")
+			}
+		}
+		ss += s + "\x00"
+	}
+	v := utf16.Encode([]rune(ss + "\x00"))
+	buf := (*[1 << 10]byte)(unsafe.Pointer(&v[0]))[:len(v)*2]
+	return k.setValue(name, MULTI_SZ, buf)
+}
+
+// SetBinaryValue sets the data and type of a name value
+// under key k to value and BINARY.
+func (k Key) SetBinaryValue(name string, value []byte) error {
+	return k.setValue(name, BINARY, value)
+}
+
+// DeleteValue removes a named value from the key k.
+func (k Key) DeleteValue(name string) error {
+	return regDeleteValue(syscall.Handle(k), syscall.StringToUTF16Ptr(name))
+}
+
+// ReadValueNames returns the value names of key k.
+// The parameter n controls the number of returned names,
+// analogous to the way os.File.Readdirnames works.
+func (k Key) ReadValueNames(n int) ([]string, error) {
+	ki, err := k.Stat()
+	if err != nil {
+		return nil, err
+	}
+	names := make([]string, 0, ki.ValueCount)
+	buf := make([]uint16, ki.MaxValueNameLen+1) // extra room for terminating null character
+loopItems:
+	for i := uint32(0); ; i++ {
+		if n > 0 {
+			if len(names) == n {
+				return names, nil
+			}
+		}
+		l := uint32(len(buf))
+		for {
+			err := regEnumValue(syscall.Handle(k), i, &buf[0], &l, nil, nil, nil, nil)
+			if err == nil {
+				break
+			}
+			if err == syscall.ERROR_MORE_DATA {
+				// Double buffer size and try again.
+				l = uint32(2 * len(buf))
+				buf = make([]uint16, l)
+				continue
+			}
+			if err == _ERROR_NO_MORE_ITEMS {
+				break loopItems
+			}
+			return names, err
+		}
+		names = append(names, syscall.UTF16ToString(buf[:l]))
+	}
+	if n > len(names) {
+		return names, io.EOF
+	}
+	return names, nil
+}
diff --git a/third_party/gofrontend/libgo/go/internal/syscall/windows/registry/zsyscall_windows.go b/third_party/gofrontend/libgo/go/internal/syscall/windows/registry/zsyscall_windows.go
new file mode 100644
index 0000000..2b3de63
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/internal/syscall/windows/registry/zsyscall_windows.go
@@ -0,0 +1,73 @@
+// MACHINE GENERATED BY 'go generate' COMMAND; DO NOT EDIT
+
+package registry
+
+import "unsafe"
+import "syscall"
+
+var _ unsafe.Pointer
+
+var (
+	modadvapi32 = syscall.NewLazyDLL("advapi32.dll")
+	modkernel32 = syscall.NewLazyDLL("kernel32.dll")
+
+	procRegCreateKeyExW           = modadvapi32.NewProc("RegCreateKeyExW")
+	procRegDeleteKeyW             = modadvapi32.NewProc("RegDeleteKeyW")
+	procRegSetValueExW            = modadvapi32.NewProc("RegSetValueExW")
+	procRegEnumValueW             = modadvapi32.NewProc("RegEnumValueW")
+	procRegDeleteValueW           = modadvapi32.NewProc("RegDeleteValueW")
+	procExpandEnvironmentStringsW = modkernel32.NewProc("ExpandEnvironmentStringsW")
+)
+
+func regCreateKeyEx(key syscall.Handle, subkey *uint16, reserved uint32, class *uint16, options uint32, desired uint32, sa *syscall.SecurityAttributes, result *syscall.Handle, disposition *uint32) (regerrno error) {
+	r0, _, _ := syscall.Syscall9(procRegCreateKeyExW.Addr(), 9, uintptr(key), uintptr(unsafe.Pointer(subkey)), uintptr(reserved), uintptr(unsafe.Pointer(class)), uintptr(options), uintptr(desired), uintptr(unsafe.Pointer(sa)), uintptr(unsafe.Pointer(result)), uintptr(unsafe.Pointer(disposition)))
+	if r0 != 0 {
+		regerrno = syscall.Errno(r0)
+	}
+	return
+}
+
+func regDeleteKey(key syscall.Handle, subkey *uint16) (regerrno error) {
+	r0, _, _ := syscall.Syscall(procRegDeleteKeyW.Addr(), 2, uintptr(key), uintptr(unsafe.Pointer(subkey)), 0)
+	if r0 != 0 {
+		regerrno = syscall.Errno(r0)
+	}
+	return
+}
+
+func regSetValueEx(key syscall.Handle, valueName *uint16, reserved uint32, vtype uint32, buf *byte, bufsize uint32) (regerrno error) {
+	r0, _, _ := syscall.Syscall6(procRegSetValueExW.Addr(), 6, uintptr(key), uintptr(unsafe.Pointer(valueName)), uintptr(reserved), uintptr(vtype), uintptr(unsafe.Pointer(buf)), uintptr(bufsize))
+	if r0 != 0 {
+		regerrno = syscall.Errno(r0)
+	}
+	return
+}
+
+func regEnumValue(key syscall.Handle, index uint32, name *uint16, nameLen *uint32, reserved *uint32, valtype *uint32, buf *byte, buflen *uint32) (regerrno error) {
+	r0, _, _ := syscall.Syscall9(procRegEnumValueW.Addr(), 8, uintptr(key), uintptr(index), uintptr(unsafe.Pointer(name)), uintptr(unsafe.Pointer(nameLen)), uintptr(unsafe.Pointer(reserved)), uintptr(unsafe.Pointer(valtype)), uintptr(unsafe.Pointer(buf)), uintptr(unsafe.Pointer(buflen)), 0)
+	if r0 != 0 {
+		regerrno = syscall.Errno(r0)
+	}
+	return
+}
+
+func regDeleteValue(key syscall.Handle, name *uint16) (regerrno error) {
+	r0, _, _ := syscall.Syscall(procRegDeleteValueW.Addr(), 2, uintptr(key), uintptr(unsafe.Pointer(name)), 0)
+	if r0 != 0 {
+		regerrno = syscall.Errno(r0)
+	}
+	return
+}
+
+func expandEnvironmentStrings(src *uint16, dst *uint16, size uint32) (n uint32, err error) {
+	r0, _, e1 := syscall.Syscall(procExpandEnvironmentStringsW.Addr(), 3, uintptr(unsafe.Pointer(src)), uintptr(unsafe.Pointer(dst)), uintptr(size))
+	n = uint32(r0)
+	if n == 0 {
+		if e1 != 0 {
+			err = error(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
diff --git a/third_party/gofrontend/libgo/go/internal/syscall/windows/syscall_windows.go b/third_party/gofrontend/libgo/go/internal/syscall/windows/syscall_windows.go
new file mode 100644
index 0000000..dc8a916
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/internal/syscall/windows/syscall_windows.go
@@ -0,0 +1,130 @@
+// 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.
+
+package windows
+
+import "syscall"
+
+//go:generate go run ../../../syscall/mksyscall_windows.go -output zsyscall_windows.go syscall_windows.go
+
+const GAA_FLAG_INCLUDE_PREFIX = 0x00000010
+
+const IF_TYPE_SOFTWARE_LOOPBACK = 24
+
+type SocketAddress struct {
+	Sockaddr       *syscall.RawSockaddrAny
+	SockaddrLength int32
+}
+
+type IpAdapterUnicastAddress struct {
+	Length             uint32
+	Flags              uint32
+	Next               *IpAdapterUnicastAddress
+	Address            SocketAddress
+	PrefixOrigin       int32
+	SuffixOrigin       int32
+	DadState           int32
+	ValidLifetime      uint32
+	PreferredLifetime  uint32
+	LeaseLifetime      uint32
+	OnLinkPrefixLength uint8
+}
+
+type IpAdapterAnycastAddress struct {
+	Length  uint32
+	Flags   uint32
+	Next    *IpAdapterAnycastAddress
+	Address SocketAddress
+}
+
+type IpAdapterMulticastAddress struct {
+	Length  uint32
+	Flags   uint32
+	Next    *IpAdapterMulticastAddress
+	Address SocketAddress
+}
+
+type IpAdapterDnsServerAdapter struct {
+	Length   uint32
+	Reserved uint32
+	Next     *IpAdapterDnsServerAdapter
+	Address  SocketAddress
+}
+
+type IpAdapterPrefix struct {
+	Length       uint32
+	Flags        uint32
+	Next         *IpAdapterPrefix
+	Address      SocketAddress
+	PrefixLength uint32
+}
+
+type IpAdapterAddresses struct {
+	Length                uint32
+	IfIndex               uint32
+	Next                  *IpAdapterAddresses
+	AdapterName           *byte
+	FirstUnicastAddress   *IpAdapterUnicastAddress
+	FirstAnycastAddress   *IpAdapterAnycastAddress
+	FirstMulticastAddress *IpAdapterMulticastAddress
+	FirstDnsServerAddress *IpAdapterDnsServerAdapter
+	DnsSuffix             *uint16
+	Description           *uint16
+	FriendlyName          *uint16
+	PhysicalAddress       [syscall.MAX_ADAPTER_ADDRESS_LENGTH]byte
+	PhysicalAddressLength uint32
+	Flags                 uint32
+	Mtu                   uint32
+	IfType                uint32
+	OperStatus            uint32
+	Ipv6IfIndex           uint32
+	ZoneIndices           [16]uint32
+	FirstPrefix           *IpAdapterPrefix
+	/* more fields might be present here. */
+}
+
+const (
+	IfOperStatusUp             = 1
+	IfOperStatusDown           = 2
+	IfOperStatusTesting        = 3
+	IfOperStatusUnknown        = 4
+	IfOperStatusDormant        = 5
+	IfOperStatusNotPresent     = 6
+	IfOperStatusLowerLayerDown = 7
+)
+
+//sys GetAdaptersAddresses(family uint32, flags uint32, reserved uintptr, adapterAddresses *IpAdapterAddresses, sizeOfPointer *uint32) (errcode error) = iphlpapi.GetAdaptersAddresses
+//sys	GetComputerNameEx(nameformat uint32, buf *uint16, n *uint32) (err error) = GetComputerNameExW
+//sys	MoveFileEx(from *uint16, to *uint16, flags uint32) (err error) = MoveFileExW
+
+const (
+	ComputerNameNetBIOS                   = 0
+	ComputerNameDnsHostname               = 1
+	ComputerNameDnsDomain                 = 2
+	ComputerNameDnsFullyQualified         = 3
+	ComputerNamePhysicalNetBIOS           = 4
+	ComputerNamePhysicalDnsHostname       = 5
+	ComputerNamePhysicalDnsDomain         = 6
+	ComputerNamePhysicalDnsFullyQualified = 7
+	ComputerNameMax                       = 8
+
+	MOVEFILE_REPLACE_EXISTING      = 0x1
+	MOVEFILE_COPY_ALLOWED          = 0x2
+	MOVEFILE_DELAY_UNTIL_REBOOT    = 0x4
+	MOVEFILE_WRITE_THROUGH         = 0x8
+	MOVEFILE_CREATE_HARDLINK       = 0x10
+	MOVEFILE_FAIL_IF_NOT_TRACKABLE = 0x20
+)
+
+func Rename(oldpath, newpath string) error {
+	from, err := syscall.UTF16PtrFromString(oldpath)
+	if err != nil {
+		return err
+	}
+	to, err := syscall.UTF16PtrFromString(newpath)
+	if err != nil {
+		return err
+	}
+	return MoveFileEx(from, to, MOVEFILE_REPLACE_EXISTING)
+}
diff --git a/third_party/gofrontend/libgo/go/internal/syscall/windows/zsyscall_windows.go b/third_party/gofrontend/libgo/go/internal/syscall/windows/zsyscall_windows.go
new file mode 100644
index 0000000..c6f607a
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/internal/syscall/windows/zsyscall_windows.go
@@ -0,0 +1,49 @@
+// MACHINE GENERATED BY 'go generate' COMMAND; DO NOT EDIT
+
+package windows
+
+import "unsafe"
+import "syscall"
+
+var _ unsafe.Pointer
+
+var (
+	modiphlpapi = syscall.NewLazyDLL("iphlpapi.dll")
+	modkernel32 = syscall.NewLazyDLL("kernel32.dll")
+
+	procGetAdaptersAddresses = modiphlpapi.NewProc("GetAdaptersAddresses")
+	procGetComputerNameExW   = modkernel32.NewProc("GetComputerNameExW")
+	procMoveFileExW          = modkernel32.NewProc("MoveFileExW")
+)
+
+func GetAdaptersAddresses(family uint32, flags uint32, reserved uintptr, adapterAddresses *IpAdapterAddresses, sizeOfPointer *uint32) (errcode error) {
+	r0, _, _ := syscall.Syscall6(procGetAdaptersAddresses.Addr(), 5, uintptr(family), uintptr(flags), uintptr(reserved), uintptr(unsafe.Pointer(adapterAddresses)), uintptr(unsafe.Pointer(sizeOfPointer)), 0)
+	if r0 != 0 {
+		errcode = syscall.Errno(r0)
+	}
+	return
+}
+
+func GetComputerNameEx(nameformat uint32, buf *uint16, n *uint32) (err error) {
+	r1, _, e1 := syscall.Syscall(procGetComputerNameExW.Addr(), 3, uintptr(nameformat), uintptr(unsafe.Pointer(buf)), uintptr(unsafe.Pointer(n)))
+	if r1 == 0 {
+		if e1 != 0 {
+			err = error(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func MoveFileEx(from *uint16, to *uint16, flags uint32) (err error) {
+	r1, _, e1 := syscall.Syscall(procMoveFileExW.Addr(), 3, uintptr(unsafe.Pointer(from)), uintptr(unsafe.Pointer(to)), uintptr(flags))
+	if r1 == 0 {
+		if e1 != 0 {
+			err = error(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
diff --git a/third_party/gofrontend/libgo/go/internal/testenv/testenv.go b/third_party/gofrontend/libgo/go/internal/testenv/testenv.go
new file mode 100644
index 0000000..1071908
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/internal/testenv/testenv.go
@@ -0,0 +1,104 @@
+// 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 testenv provides information about what functionality
+// is available in different testing environments run by the Go team.
+//
+// It is an internal package because these details are specific
+// to the Go team's test setup (on build.golang.org) and not
+// fundamental to tests in general.
+package testenv
+
+import (
+	"os"
+	"runtime"
+	"strings"
+	"testing"
+)
+
+// Builder reports the name of the builder running this test
+// (for example, "linux-amd64" or "windows-386-gce").
+// If the test is not running on the build infrastructure,
+// Builder returns the empty string.
+func Builder() string {
+	return os.Getenv("GO_BUILDER_NAME")
+}
+
+// HasGoBuild reports whether the current system can build programs with ``go build''
+// and then run them with os.StartProcess or exec.Command.
+func HasGoBuild() bool {
+	switch runtime.GOOS {
+	case "android", "nacl":
+		return false
+	case "darwin":
+		if strings.HasPrefix(runtime.GOARCH, "arm") {
+			return false
+		}
+	}
+	// gccgo tests can not run "go build".
+	return false
+}
+
+// MustHaveGoBuild checks that the current system can build programs with ``go build''
+// and then run them with os.StartProcess or exec.Command.
+// If not, MustHaveGoBuild calls t.Skip with an explanation.
+func MustHaveGoBuild(t *testing.T) {
+	t.Skip("skipping test: 'go build' not available for gccgo tests")
+	if !HasGoBuild() {
+		t.Skipf("skipping test: 'go build' not available on %s/%s", runtime.GOOS, runtime.GOARCH)
+	}
+}
+
+// HasGoRun reports whether the current system can run programs with ``go run.''
+func HasGoRun() bool {
+	// For now, having go run and having go build are the same.
+	return HasGoBuild()
+}
+
+// MustHaveGoRun checks that the current system can run programs with ``go run.''
+// If not, MustHaveGoRun calls t.Skip with an explanation.
+func MustHaveGoRun(t *testing.T) {
+	t.Skip("skipping test: 'go run' not available for gccgo tests")
+	if !HasGoRun() {
+		t.Skipf("skipping test: 'go run' not available on %s/%s", runtime.GOOS, runtime.GOARCH)
+	}
+}
+
+// HasExec reports whether the current system can start new processes
+// using os.StartProcess or (more commonly) exec.Command.
+func HasExec() bool {
+	switch runtime.GOOS {
+	case "nacl":
+		return false
+	case "darwin":
+		if strings.HasPrefix(runtime.GOARCH, "arm") {
+			return false
+		}
+	}
+	return true
+}
+
+// MustHaveExec checks that the current system can start new processes
+// using os.StartProcess or (more commonly) exec.Command.
+// If not, MustHaveExec calls t.Skip with an explanation.
+func MustHaveExec(t *testing.T) {
+	if !HasExec() {
+		t.Skipf("skipping test: cannot exec subprocess on %s/%s", runtime.GOOS, runtime.GOARCH)
+	}
+}
+
+// HasExternalNetwork reports whether the current system can use
+// external (non-localhost) networks.
+func HasExternalNetwork() bool {
+	return !testing.Short()
+}
+
+// MustHaveExternalNetwork checks that the current system can use
+// external (non-localhost) networks.
+// If not, MustHaveExternalNetwork calls t.Skip with an explanation.
+func MustHaveExternalNetwork(t *testing.T) {
+	if testing.Short() {
+		t.Skipf("skipping test: no external network in -short mode")
+	}
+}
diff --git a/third_party/gofrontend/libgo/go/internal/trace/goroutines.go b/third_party/gofrontend/libgo/go/internal/trace/goroutines.go
new file mode 100644
index 0000000..f8673e2
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/internal/trace/goroutines.go
@@ -0,0 +1,180 @@
+// 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.
+
+package trace
+
+// GDesc contains statistics about execution of a single goroutine.
+type GDesc struct {
+	ID           uint64
+	Name         string
+	PC           uint64
+	CreationTime int64
+	StartTime    int64
+	EndTime      int64
+
+	ExecTime      int64
+	SchedWaitTime int64
+	IOTime        int64
+	BlockTime     int64
+	SyscallTime   int64
+	GCTime        int64
+	SweepTime     int64
+	TotalTime     int64
+
+	*gdesc // private part
+}
+
+// gdesc is a private part of GDesc that is required only during analysis.
+type gdesc struct {
+	lastStartTime    int64
+	blockNetTime     int64
+	blockSyncTime    int64
+	blockSyscallTime int64
+	blockSweepTime   int64
+	blockGCTime      int64
+	blockSchedTime   int64
+}
+
+// GoroutineStats generates statistics for all goroutines in the trace.
+func GoroutineStats(events []*Event) map[uint64]*GDesc {
+	gs := make(map[uint64]*GDesc)
+	var lastTs int64
+	var gcStartTime int64
+	for _, ev := range events {
+		lastTs = ev.Ts
+		switch ev.Type {
+		case EvGoCreate:
+			g := &GDesc{ID: ev.Args[0], CreationTime: ev.Ts, gdesc: new(gdesc)}
+			g.blockSchedTime = ev.Ts
+			gs[g.ID] = g
+		case EvGoStart:
+			g := gs[ev.G]
+			if g.PC == 0 {
+				g.PC = ev.Stk[0].PC
+				g.Name = ev.Stk[0].Fn
+			}
+			g.lastStartTime = ev.Ts
+			if g.StartTime == 0 {
+				g.StartTime = ev.Ts
+			}
+			if g.blockSchedTime != 0 {
+				g.SchedWaitTime += ev.Ts - g.blockSchedTime
+				g.blockSchedTime = 0
+			}
+		case EvGoEnd, EvGoStop:
+			g := gs[ev.G]
+			g.ExecTime += ev.Ts - g.lastStartTime
+			g.TotalTime = ev.Ts - g.CreationTime
+			g.EndTime = ev.Ts
+		case EvGoBlockSend, EvGoBlockRecv, EvGoBlockSelect,
+			EvGoBlockSync, EvGoBlockCond:
+			g := gs[ev.G]
+			g.ExecTime += ev.Ts - g.lastStartTime
+			g.blockSyncTime = ev.Ts
+		case EvGoSched, EvGoPreempt:
+			g := gs[ev.G]
+			g.ExecTime += ev.Ts - g.lastStartTime
+			g.blockSchedTime = ev.Ts
+		case EvGoSleep, EvGoBlock:
+			g := gs[ev.G]
+			g.ExecTime += ev.Ts - g.lastStartTime
+		case EvGoBlockNet:
+			g := gs[ev.G]
+			g.ExecTime += ev.Ts - g.lastStartTime
+			g.blockNetTime = ev.Ts
+		case EvGoUnblock:
+			g := gs[ev.Args[0]]
+			if g.blockNetTime != 0 {
+				g.IOTime += ev.Ts - g.blockNetTime
+				g.blockNetTime = 0
+			}
+			if g.blockSyncTime != 0 {
+				g.BlockTime += ev.Ts - g.blockSyncTime
+				g.blockSyncTime = 0
+			}
+			g.blockSchedTime = ev.Ts
+		case EvGoSysBlock:
+			g := gs[ev.G]
+			g.ExecTime += ev.Ts - g.lastStartTime
+			g.blockSyscallTime = ev.Ts
+		case EvGoSysExit:
+			g := gs[ev.G]
+			if g.blockSyscallTime != 0 {
+				g.SyscallTime += ev.Ts - g.blockSyscallTime
+				g.blockSyscallTime = 0
+			}
+			g.blockSchedTime = ev.Ts
+		case EvGCSweepStart:
+			g := gs[ev.G]
+			if g != nil {
+				// Sweep can happen during GC on system goroutine.
+				g.blockSweepTime = ev.Ts
+			}
+		case EvGCSweepDone:
+			g := gs[ev.G]
+			if g != nil && g.blockSweepTime != 0 {
+				g.SweepTime += ev.Ts - g.blockSweepTime
+				g.blockSweepTime = 0
+			}
+		case EvGCStart:
+			gcStartTime = ev.Ts
+		case EvGCDone:
+			for _, g := range gs {
+				if g.EndTime == 0 {
+					g.GCTime += ev.Ts - gcStartTime
+				}
+			}
+		}
+	}
+
+	for _, g := range gs {
+		if g.TotalTime == 0 {
+			g.TotalTime = lastTs - g.CreationTime
+		}
+		if g.EndTime == 0 {
+			g.EndTime = lastTs
+		}
+		if g.blockNetTime != 0 {
+			g.IOTime += lastTs - g.blockNetTime
+			g.blockNetTime = 0
+		}
+		if g.blockSyncTime != 0 {
+			g.BlockTime += lastTs - g.blockSyncTime
+			g.blockSyncTime = 0
+		}
+		if g.blockSyscallTime != 0 {
+			g.SyscallTime += lastTs - g.blockSyscallTime
+			g.blockSyscallTime = 0
+		}
+		if g.blockSchedTime != 0 {
+			g.SchedWaitTime += lastTs - g.blockSchedTime
+			g.blockSchedTime = 0
+		}
+		g.gdesc = nil
+	}
+
+	return gs
+}
+
+// RelatedGoroutines finds a set of goroutines related to goroutine goid.
+func RelatedGoroutines(events []*Event, goid uint64) map[uint64]bool {
+	// BFS of depth 2 over "unblock" edges
+	// (what goroutines unblock goroutine goid?).
+	gmap := make(map[uint64]bool)
+	gmap[goid] = true
+	for i := 0; i < 2; i++ {
+		gmap1 := make(map[uint64]bool)
+		for g := range gmap {
+			gmap1[g] = true
+		}
+		for _, ev := range events {
+			if ev.Type == EvGoUnblock && gmap[ev.Args[0]] {
+				gmap1[ev.G] = true
+			}
+		}
+		gmap = gmap1
+	}
+	gmap[0] = true // for GC events
+	return gmap
+}
diff --git a/third_party/gofrontend/libgo/go/internal/trace/parser.go b/third_party/gofrontend/libgo/go/internal/trace/parser.go
new file mode 100644
index 0000000..1eb39dd
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/internal/trace/parser.go
@@ -0,0 +1,786 @@
+// 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.
+
+package trace
+
+import (
+	"bufio"
+	"bytes"
+	"fmt"
+	"io"
+	"os"
+	"os/exec"
+	"sort"
+	"strconv"
+	"strings"
+)
+
+// Event describes one event in the trace.
+type Event struct {
+	Off   int       // offset in input file (for debugging and error reporting)
+	Type  byte      // one of Ev*
+	Seq   int64     // sequence number
+	Ts    int64     // timestamp in nanoseconds
+	P     int       // P on which the event happened (can be one of TimerP, NetpollP, SyscallP)
+	G     uint64    // G on which the event happened
+	StkID uint64    // unique stack ID
+	Stk   []*Frame  // stack trace (can be empty)
+	Args  [3]uint64 // event-type-specific arguments
+	// linked event (can be nil), depends on event type:
+	// for GCStart: the GCStop
+	// for GCScanStart: the GCScanDone
+	// for GCSweepStart: the GCSweepDone
+	// for GoCreate: first GoStart of the created goroutine
+	// for GoStart: the associated GoEnd, GoBlock or other blocking event
+	// for GoSched/GoPreempt: the next GoStart
+	// for GoBlock and other blocking events: the unblock event
+	// for GoUnblock: the associated GoStart
+	// for blocking GoSysCall: the associated GoSysExit
+	// for GoSysExit: the next GoStart
+	Link *Event
+}
+
+// Frame is a frame in stack traces.
+type Frame struct {
+	PC   uint64
+	Fn   string
+	File string
+	Line int
+}
+
+const (
+	// Special P identifiers:
+	FakeP    = 1000000 + iota
+	TimerP   // depicts timer unblocks
+	NetpollP // depicts network unblocks
+	SyscallP // depicts returns from syscalls
+)
+
+// Parse parses, post-processes and verifies the trace.
+func Parse(r io.Reader) ([]*Event, error) {
+	rawEvents, err := readTrace(r)
+	if err != nil {
+		return nil, err
+	}
+	events, err := parseEvents(rawEvents)
+	if err != nil {
+		return nil, err
+	}
+	events, err = removeFutile(events)
+	if err != nil {
+		return nil, err
+	}
+	err = postProcessTrace(events)
+	if err != nil {
+		return nil, err
+	}
+	return events, nil
+}
+
+// rawEvent is a helper type used during parsing.
+type rawEvent struct {
+	off  int
+	typ  byte
+	args []uint64
+}
+
+// readTrace does wire-format parsing and verification.
+// It does not care about specific event types and argument meaning.
+func readTrace(r io.Reader) ([]rawEvent, error) {
+	// Read and validate trace header.
+	var buf [16]byte
+	off, err := r.Read(buf[:])
+	if off != 16 || err != nil {
+		return nil, fmt.Errorf("failed to read header: read %v, err %v", off, err)
+	}
+	if bytes.Compare(buf[:], []byte("go 1.5 trace\x00\x00\x00\x00")) != 0 {
+		return nil, fmt.Errorf("not a trace file")
+	}
+
+	// Read events.
+	var events []rawEvent
+	for {
+		// Read event type and number of arguments (1 byte).
+		off0 := off
+		n, err := r.Read(buf[:1])
+		if err == io.EOF {
+			break
+		}
+		if err != nil || n != 1 {
+			return nil, fmt.Errorf("failed to read trace at offset 0x%x: n=%v err=%v", off0, n, err)
+		}
+		off += n
+		typ := buf[0] << 2 >> 2
+		narg := buf[0] >> 6
+		ev := rawEvent{typ: typ, off: off0}
+		if narg < 3 {
+			for i := 0; i < int(narg)+2; i++ { // sequence number and time stamp are present but not counted in narg
+				var v uint64
+				v, off, err = readVal(r, off)
+				if err != nil {
+					return nil, err
+				}
+				ev.args = append(ev.args, v)
+			}
+		} else {
+			// If narg == 3, the first value is length of the event in bytes.
+			var v uint64
+			v, off, err = readVal(r, off)
+			if err != nil {
+				return nil, err
+			}
+			evLen := v
+			off1 := off
+			for evLen > uint64(off-off1) {
+				v, off, err = readVal(r, off)
+				if err != nil {
+					return nil, err
+				}
+				ev.args = append(ev.args, v)
+			}
+			if evLen != uint64(off-off1) {
+				return nil, fmt.Errorf("event has wrong length at offset 0x%x: want %v, got %v", off0, evLen, off-off1)
+			}
+		}
+		events = append(events, ev)
+	}
+	return events, nil
+}
+
+// Parse events transforms raw events into events.
+// It does analyze and verify per-event-type arguments.
+func parseEvents(rawEvents []rawEvent) (events []*Event, err error) {
+	var ticksPerSec, lastSeq, lastTs int64
+	var lastG, timerGoid uint64
+	var lastP int
+	lastGs := make(map[int]uint64) // last goroutine running on P
+	stacks := make(map[uint64][]*Frame)
+	for _, raw := range rawEvents {
+		if raw.typ == EvNone || raw.typ >= EvCount {
+			err = fmt.Errorf("unknown event type %v at offset 0x%x", raw.typ, raw.off)
+			return
+		}
+		desc := EventDescriptions[raw.typ]
+		if desc.Name == "" {
+			err = fmt.Errorf("missing description for event type %v", raw.typ)
+			return
+		}
+		if raw.typ != EvStack {
+			narg := len(desc.Args)
+			if desc.Stack {
+				narg++
+			}
+			if raw.typ != EvBatch && raw.typ != EvFrequency && raw.typ != EvTimerGoroutine {
+				narg++ // sequence number
+				narg++ // timestamp
+			}
+			if len(raw.args) != narg {
+				err = fmt.Errorf("%v has wrong number of arguments at offset 0x%x: want %v, got %v",
+					desc.Name, raw.off, narg, len(raw.args))
+				return
+			}
+		}
+		switch raw.typ {
+		case EvBatch:
+			lastGs[lastP] = lastG
+			lastP = int(raw.args[0])
+			lastG = lastGs[lastP]
+			lastSeq = int64(raw.args[1])
+			lastTs = int64(raw.args[2])
+		case EvFrequency:
+			ticksPerSec = int64(raw.args[0])
+			if ticksPerSec <= 0 {
+				// The most likely cause for this is tick skew on different CPUs.
+				// For example, solaris/amd64 seems to have wildly different
+				// ticks on different CPUs.
+				err = ErrTimeOrder
+				return
+			}
+		case EvTimerGoroutine:
+			timerGoid = raw.args[0]
+		case EvStack:
+			if len(raw.args) < 2 {
+				err = fmt.Errorf("EvStack has wrong number of arguments at offset 0x%x: want at least 2, got %v",
+					raw.off, len(raw.args))
+				return
+			}
+			size := raw.args[1]
+			if size > 1000 {
+				err = fmt.Errorf("EvStack has bad number of frames at offset 0x%x: %v",
+					raw.off, size)
+				return
+			}
+			if uint64(len(raw.args)) != size+2 {
+				err = fmt.Errorf("EvStack has wrong number of arguments at offset 0x%x: want %v, got %v",
+					raw.off, size+2, len(raw.args))
+				return
+			}
+			id := raw.args[0]
+			if id != 0 && size > 0 {
+				stk := make([]*Frame, size)
+				for i := 0; i < int(size); i++ {
+					stk[i] = &Frame{PC: raw.args[i+2]}
+				}
+				stacks[id] = stk
+			}
+		default:
+			e := &Event{Off: raw.off, Type: raw.typ, P: lastP, G: lastG}
+			e.Seq = lastSeq + int64(raw.args[0])
+			e.Ts = lastTs + int64(raw.args[1])
+			lastSeq = e.Seq
+			lastTs = e.Ts
+			for i := range desc.Args {
+				e.Args[i] = raw.args[i+2]
+			}
+			if desc.Stack {
+				e.StkID = raw.args[len(desc.Args)+2]
+			}
+			switch raw.typ {
+			case EvGoStart:
+				lastG = e.Args[0]
+				e.G = lastG
+			case EvGCStart, EvGCDone, EvGCScanStart, EvGCScanDone:
+				e.G = 0
+			case EvGoEnd, EvGoStop, EvGoSched, EvGoPreempt,
+				EvGoSleep, EvGoBlock, EvGoBlockSend, EvGoBlockRecv,
+				EvGoBlockSelect, EvGoBlockSync, EvGoBlockCond, EvGoBlockNet,
+				EvGoSysBlock:
+				lastG = 0
+			case EvGoSysExit:
+				// EvGoSysExit emission is delayed until the thread has a P.
+				// Give it the real sequence number and time stamp.
+				e.Seq = int64(e.Args[1])
+				if e.Args[2] != 0 {
+					e.Ts = int64(e.Args[2])
+				}
+			}
+			events = append(events, e)
+		}
+	}
+	if len(events) == 0 {
+		err = fmt.Errorf("trace is empty")
+		return
+	}
+
+	// Attach stack traces.
+	for _, ev := range events {
+		if ev.StkID != 0 {
+			ev.Stk = stacks[ev.StkID]
+		}
+	}
+
+	// Sort by sequence number and translate cpu ticks to real time.
+	sort.Sort(eventList(events))
+	if ticksPerSec == 0 {
+		err = fmt.Errorf("no EvFrequency event")
+		return
+	}
+	minTs := events[0].Ts
+	for _, ev := range events {
+		ev.Ts = (ev.Ts - minTs) * 1e9 / ticksPerSec
+		// Move timers and syscalls to separate fake Ps.
+		if timerGoid != 0 && ev.G == timerGoid && ev.Type == EvGoUnblock {
+			ev.P = TimerP
+		}
+		if ev.Type == EvGoSysExit {
+			ev.P = SyscallP
+			ev.G = ev.Args[0]
+		}
+	}
+
+	return
+}
+
+// removeFutile removes all constituents of futile wakeups (block, unblock, start).
+// For example, a goroutine was unblocked on a mutex, but another goroutine got
+// ahead and acquired the mutex before the first goroutine is scheduled,
+// so the first goroutine has to block again. Such wakeups happen on buffered
+// channels and sync.Mutex, but are generally not interesting for end user.
+func removeFutile(events []*Event) ([]*Event, error) {
+	// Two non-trivial aspects:
+	// 1. A goroutine can be preempted during a futile wakeup and migrate to another P.
+	//	We want to remove all of that.
+	// 2. Tracing can start in the middle of a futile wakeup.
+	//	That is, we can see a futile wakeup event w/o the actual wakeup before it.
+	// postProcessTrace runs after us and ensures that we leave the trace in a consistent state.
+
+	// Phase 1: determine futile wakeup sequences.
+	type G struct {
+		futile bool
+		wakeup []*Event // wakeup sequence (subject for removal)
+	}
+	gs := make(map[uint64]G)
+	futile := make(map[*Event]bool)
+	for _, ev := range events {
+		switch ev.Type {
+		case EvGoUnblock:
+			g := gs[ev.Args[0]]
+			g.wakeup = []*Event{ev}
+			gs[ev.Args[0]] = g
+		case EvGoStart, EvGoPreempt, EvFutileWakeup:
+			g := gs[ev.G]
+			g.wakeup = append(g.wakeup, ev)
+			if ev.Type == EvFutileWakeup {
+				g.futile = true
+			}
+			gs[ev.G] = g
+		case EvGoBlock, EvGoBlockSend, EvGoBlockRecv, EvGoBlockSelect, EvGoBlockSync, EvGoBlockCond:
+			g := gs[ev.G]
+			if g.futile {
+				futile[ev] = true
+				for _, ev1 := range g.wakeup {
+					futile[ev1] = true
+				}
+			}
+			delete(gs, ev.G)
+		}
+	}
+
+	// Phase 2: remove futile wakeup sequences.
+	newEvents := events[:0] // overwrite the original slice
+	for _, ev := range events {
+		if !futile[ev] {
+			newEvents = append(newEvents, ev)
+		}
+	}
+	return newEvents, nil
+}
+
+// ErrTimeOrder is returned by Parse when the trace contains
+// time stamps that do not respect actual event ordering.
+var ErrTimeOrder = fmt.Errorf("time stamps out of order")
+
+// postProcessTrace does inter-event verification and information restoration.
+// The resulting trace is guaranteed to be consistent
+// (for example, a P does not run two Gs at the same time, or a G is indeed
+// blocked before an unblock event).
+func postProcessTrace(events []*Event) error {
+	const (
+		gDead = iota
+		gRunnable
+		gRunning
+		gWaiting
+	)
+	type gdesc struct {
+		state    int
+		ev       *Event
+		evStart  *Event
+		evCreate *Event
+	}
+	type pdesc struct {
+		running bool
+		g       uint64
+		evScan  *Event
+		evSweep *Event
+	}
+
+	gs := make(map[uint64]gdesc)
+	ps := make(map[int]pdesc)
+	gs[0] = gdesc{state: gRunning}
+	var evGC *Event
+
+	checkRunning := func(p pdesc, g gdesc, ev *Event, allowG0 bool) error {
+		name := EventDescriptions[ev.Type].Name
+		if g.state != gRunning {
+			return fmt.Errorf("g %v is not running while %v (offset %v, time %v)", ev.G, name, ev.Off, ev.Ts)
+		}
+		if p.g != ev.G {
+			return fmt.Errorf("p %v is not running g %v while %v (offset %v, time %v)", ev.P, ev.G, name, ev.Off, ev.Ts)
+		}
+		if !allowG0 && ev.G == 0 {
+			return fmt.Errorf("g 0 did %v (offset %v, time %v)", EventDescriptions[ev.Type].Name, ev.Off, ev.Ts)
+		}
+		return nil
+	}
+
+	for _, ev := range events {
+		g := gs[ev.G]
+		p := ps[ev.P]
+
+		switch ev.Type {
+		case EvProcStart:
+			if p.running {
+				return fmt.Errorf("p %v is running before start (offset %v, time %v)", ev.P, ev.Off, ev.Ts)
+			}
+			p.running = true
+		case EvProcStop:
+			if !p.running {
+				return fmt.Errorf("p %v is not running before stop (offset %v, time %v)", ev.P, ev.Off, ev.Ts)
+			}
+			if p.g != 0 {
+				return fmt.Errorf("p %v is running a goroutine %v during stop (offset %v, time %v)", ev.P, p.g, ev.Off, ev.Ts)
+			}
+			p.running = false
+		case EvGCStart:
+			if evGC != nil {
+				return fmt.Errorf("previous GC is not ended before a new one (offset %v, time %v)", ev.Off, ev.Ts)
+			}
+			evGC = ev
+		case EvGCDone:
+			if evGC == nil {
+				return fmt.Errorf("bogus GC end (offset %v, time %v)", ev.Off, ev.Ts)
+			}
+			evGC.Link = ev
+			evGC = nil
+		case EvGCScanStart:
+			if p.evScan != nil {
+				return fmt.Errorf("previous scanning is not ended before a new one (offset %v, time %v)", ev.Off, ev.Ts)
+			}
+			p.evScan = ev
+		case EvGCScanDone:
+			if p.evScan == nil {
+				return fmt.Errorf("bogus scanning end (offset %v, time %v)", ev.Off, ev.Ts)
+			}
+			p.evScan.Link = ev
+			p.evScan = nil
+		case EvGCSweepStart:
+			if p.evSweep != nil {
+				return fmt.Errorf("previous sweeping is not ended before a new one (offset %v, time %v)", ev.Off, ev.Ts)
+			}
+			p.evSweep = ev
+		case EvGCSweepDone:
+			if p.evSweep == nil {
+				return fmt.Errorf("bogus sweeping end (offset %v, time %v)", ev.Off, ev.Ts)
+			}
+			p.evSweep.Link = ev
+			p.evSweep = nil
+		case EvGoWaiting:
+			g1 := gs[ev.Args[0]]
+			if g1.state != gRunnable {
+				return fmt.Errorf("g %v is not runnable before EvGoWaiting (offset %v, time %v)", ev.Args[0], ev.Off, ev.Ts)
+			}
+			g1.state = gWaiting
+			gs[ev.Args[0]] = g1
+		case EvGoInSyscall:
+			g1 := gs[ev.Args[0]]
+			if g1.state != gRunnable {
+				return fmt.Errorf("g %v is not runnable before EvGoInSyscall (offset %v, time %v)", ev.Args[0], ev.Off, ev.Ts)
+			}
+			g1.state = gWaiting
+			gs[ev.Args[0]] = g1
+		case EvGoCreate:
+			if err := checkRunning(p, g, ev, true); err != nil {
+				return err
+			}
+			if _, ok := gs[ev.Args[0]]; ok {
+				return fmt.Errorf("g %v already exists (offset %v, time %v)", ev.Args[0], ev.Off, ev.Ts)
+			}
+			gs[ev.Args[0]] = gdesc{state: gRunnable, ev: ev, evCreate: ev}
+		case EvGoStart:
+			if g.state != gRunnable {
+				return fmt.Errorf("g %v is not runnable before start (offset %v, time %v)", ev.G, ev.Off, ev.Ts)
+			}
+			if p.g != 0 {
+				return fmt.Errorf("p %v is already running g %v while start g %v (offset %v, time %v)", ev.P, p.g, ev.G, ev.Off, ev.Ts)
+			}
+			g.state = gRunning
+			g.evStart = ev
+			p.g = ev.G
+			if g.evCreate != nil {
+				// +1 because symbolizer expects return pc.
+				ev.Stk = []*Frame{&Frame{PC: g.evCreate.Args[1] + 1}}
+				g.evCreate = nil
+			}
+
+			if g.ev != nil {
+				g.ev.Link = ev
+				g.ev = nil
+			}
+		case EvGoEnd, EvGoStop:
+			if err := checkRunning(p, g, ev, false); err != nil {
+				return err
+			}
+			g.evStart.Link = ev
+			g.evStart = nil
+			g.state = gDead
+			p.g = 0
+		case EvGoSched, EvGoPreempt:
+			if err := checkRunning(p, g, ev, false); err != nil {
+				return err
+			}
+			g.state = gRunnable
+			g.evStart.Link = ev
+			g.evStart = nil
+			p.g = 0
+			g.ev = ev
+		case EvGoUnblock:
+			if g.state != gRunning {
+				return fmt.Errorf("g %v is not running while unpark (offset %v, time %v)", ev.G, ev.Off, ev.Ts)
+			}
+			if ev.P != TimerP && p.g != ev.G {
+				return fmt.Errorf("p %v is not running g %v while unpark (offset %v, time %v)", ev.P, ev.G, ev.Off, ev.Ts)
+			}
+			g1 := gs[ev.Args[0]]
+			if g1.state != gWaiting {
+				return fmt.Errorf("g %v is not waiting before unpark (offset %v, time %v)", ev.Args[0], ev.Off, ev.Ts)
+			}
+			if g1.ev != nil && g1.ev.Type == EvGoBlockNet && ev.P != TimerP {
+				ev.P = NetpollP
+			}
+			if g1.ev != nil {
+				g1.ev.Link = ev
+			}
+			g1.state = gRunnable
+			g1.ev = ev
+			gs[ev.Args[0]] = g1
+		case EvGoSysCall:
+			if err := checkRunning(p, g, ev, false); err != nil {
+				return err
+			}
+			g.ev = ev
+		case EvGoSysBlock:
+			if err := checkRunning(p, g, ev, false); err != nil {
+				return err
+			}
+			g.state = gWaiting
+			g.evStart.Link = ev
+			g.evStart = nil
+			p.g = 0
+		case EvGoSysExit:
+			if g.state != gWaiting {
+				return fmt.Errorf("g %v is not waiting during syscall exit (offset %v, time %v)", ev.G, ev.Off, ev.Ts)
+			}
+			if g.ev != nil && g.ev.Type == EvGoSysCall {
+				g.ev.Link = ev
+			}
+			g.state = gRunnable
+			g.ev = ev
+		case EvGoSleep, EvGoBlock, EvGoBlockSend, EvGoBlockRecv,
+			EvGoBlockSelect, EvGoBlockSync, EvGoBlockCond, EvGoBlockNet:
+			if err := checkRunning(p, g, ev, false); err != nil {
+				return err
+			}
+			g.state = gWaiting
+			g.ev = ev
+			g.evStart.Link = ev
+			g.evStart = nil
+			p.g = 0
+		}
+
+		gs[ev.G] = g
+		ps[ev.P] = p
+	}
+
+	// TODO(dvyukov): restore stacks for EvGoStart events.
+	// TODO(dvyukov): test that all EvGoStart events has non-nil Link.
+
+	// Last, after all the other consistency checks,
+	// make sure time stamps respect sequence numbers.
+	// The tests will skip (not fail) the test case if they see this error,
+	// so check everything else that could possibly be wrong first.
+	lastTs := int64(0)
+	for _, ev := range events {
+		if ev.Ts < lastTs {
+			return ErrTimeOrder
+		}
+		lastTs = ev.Ts
+	}
+
+	return nil
+}
+
+// symbolizeTrace attaches func/file/line info to stack traces.
+func Symbolize(events []*Event, bin string) error {
+	// First, collect and dedup all pcs.
+	pcs := make(map[uint64]*Frame)
+	for _, ev := range events {
+		for _, f := range ev.Stk {
+			pcs[f.PC] = nil
+		}
+	}
+
+	// Start addr2line.
+	cmd := exec.Command("go", "tool", "addr2line", bin)
+	in, err := cmd.StdinPipe()
+	if err != nil {
+		return fmt.Errorf("failed to pipe addr2line stdin: %v", err)
+	}
+	cmd.Stderr = os.Stderr
+	out, err := cmd.StdoutPipe()
+	if err != nil {
+		return fmt.Errorf("failed to pipe addr2line stdout: %v", err)
+	}
+	err = cmd.Start()
+	if err != nil {
+		return fmt.Errorf("failed to start addr2line: %v", err)
+	}
+	outb := bufio.NewReader(out)
+
+	// Write all pcs to addr2line.
+	// Need to copy pcs to an array, because map iteration order is non-deterministic.
+	var pcArray []uint64
+	for pc := range pcs {
+		pcArray = append(pcArray, pc)
+		_, err := fmt.Fprintf(in, "0x%x\n", pc-1)
+		if err != nil {
+			return fmt.Errorf("failed to write to addr2line: %v", err)
+		}
+	}
+	in.Close()
+
+	// Read in answers.
+	for _, pc := range pcArray {
+		fn, err := outb.ReadString('\n')
+		if err != nil {
+			return fmt.Errorf("failed to read from addr2line: %v", err)
+		}
+		file, err := outb.ReadString('\n')
+		if err != nil {
+			return fmt.Errorf("failed to read from addr2line: %v", err)
+		}
+		f := &Frame{PC: pc}
+		f.Fn = fn[:len(fn)-1]
+		f.File = file[:len(file)-1]
+		if colon := strings.LastIndex(f.File, ":"); colon != -1 {
+			ln, err := strconv.Atoi(f.File[colon+1:])
+			if err == nil {
+				f.File = f.File[:colon]
+				f.Line = ln
+			}
+		}
+		pcs[pc] = f
+	}
+	cmd.Wait()
+
+	// Replace frames in events array.
+	for _, ev := range events {
+		for i, f := range ev.Stk {
+			ev.Stk[i] = pcs[f.PC]
+		}
+	}
+
+	return nil
+}
+
+// readVal reads unsigned base-128 value from r.
+func readVal(r io.Reader, off0 int) (v uint64, off int, err error) {
+	off = off0
+	for i := 0; i < 10; i++ {
+		var buf [1]byte
+		var n int
+		n, err = r.Read(buf[:])
+		if err != nil || n != 1 {
+			return 0, 0, fmt.Errorf("failed to read trace at offset %d: read %v, error %v", off0, n, err)
+		}
+		off++
+		v |= uint64(buf[0]&0x7f) << (uint(i) * 7)
+		if buf[0]&0x80 == 0 {
+			return
+		}
+	}
+	return 0, 0, fmt.Errorf("bad value at offset 0x%x", off0)
+}
+
+type eventList []*Event
+
+func (l eventList) Len() int {
+	return len(l)
+}
+
+func (l eventList) Less(i, j int) bool {
+	return l[i].Seq < l[j].Seq
+}
+
+func (l eventList) Swap(i, j int) {
+	l[i], l[j] = l[j], l[i]
+}
+
+// Print dumps events to stdout. For debugging.
+func Print(events []*Event) {
+	for _, ev := range events {
+		desc := EventDescriptions[ev.Type]
+		fmt.Printf("%v %v p=%v g=%v off=%v", ev.Ts, desc.Name, ev.P, ev.G, ev.Off)
+		for i, a := range desc.Args {
+			fmt.Printf(" %v=%v", a, ev.Args[i])
+		}
+		fmt.Printf("\n")
+	}
+}
+
+// Event types in the trace.
+// Verbatim copy from src/runtime/trace.go.
+const (
+	EvNone           = 0  // unused
+	EvBatch          = 1  // start of per-P batch of events [pid, timestamp]
+	EvFrequency      = 2  // contains tracer timer frequency [frequency (ticks per second)]
+	EvStack          = 3  // stack [stack id, number of PCs, array of PCs]
+	EvGomaxprocs     = 4  // current value of GOMAXPROCS [timestamp, GOMAXPROCS, stack id]
+	EvProcStart      = 5  // start of P [timestamp, thread id]
+	EvProcStop       = 6  // stop of P [timestamp]
+	EvGCStart        = 7  // GC start [timestamp, stack id]
+	EvGCDone         = 8  // GC done [timestamp]
+	EvGCScanStart    = 9  // GC scan start [timestamp]
+	EvGCScanDone     = 10 // GC scan done [timestamp]
+	EvGCSweepStart   = 11 // GC sweep start [timestamp, stack id]
+	EvGCSweepDone    = 12 // GC sweep done [timestamp]
+	EvGoCreate       = 13 // goroutine creation [timestamp, new goroutine id, start PC, stack id]
+	EvGoStart        = 14 // goroutine starts running [timestamp, goroutine id]
+	EvGoEnd          = 15 // goroutine ends [timestamp]
+	EvGoStop         = 16 // goroutine stops (like in select{}) [timestamp, stack]
+	EvGoSched        = 17 // goroutine calls Gosched [timestamp, stack]
+	EvGoPreempt      = 18 // goroutine is preempted [timestamp, stack]
+	EvGoSleep        = 19 // goroutine calls Sleep [timestamp, stack]
+	EvGoBlock        = 20 // goroutine blocks [timestamp, stack]
+	EvGoUnblock      = 21 // goroutine is unblocked [timestamp, goroutine id, stack]
+	EvGoBlockSend    = 22 // goroutine blocks on chan send [timestamp, stack]
+	EvGoBlockRecv    = 23 // goroutine blocks on chan recv [timestamp, stack]
+	EvGoBlockSelect  = 24 // goroutine blocks on select [timestamp, stack]
+	EvGoBlockSync    = 25 // goroutine blocks on Mutex/RWMutex [timestamp, stack]
+	EvGoBlockCond    = 26 // goroutine blocks on Cond [timestamp, stack]
+	EvGoBlockNet     = 27 // goroutine blocks on network [timestamp, stack]
+	EvGoSysCall      = 28 // syscall enter [timestamp, stack]
+	EvGoSysExit      = 29 // syscall exit [timestamp, goroutine id, real timestamp]
+	EvGoSysBlock     = 30 // syscall blocks [timestamp]
+	EvGoWaiting      = 31 // denotes that goroutine is blocked when tracing starts [goroutine id]
+	EvGoInSyscall    = 32 // denotes that goroutine is in syscall when tracing starts [goroutine id]
+	EvHeapAlloc      = 33 // memstats.heap_alloc change [timestamp, heap_alloc]
+	EvNextGC         = 34 // memstats.next_gc change [timestamp, next_gc]
+	EvTimerGoroutine = 35 // denotes timer goroutine [timer goroutine id]
+	EvFutileWakeup   = 36 // denotes that the previous wakeup of this goroutine was futile [timestamp]
+	EvCount          = 37
+)
+
+var EventDescriptions = [EvCount]struct {
+	Name  string
+	Stack bool
+	Args  []string
+}{
+	EvNone:           {"None", false, []string{}},
+	EvBatch:          {"Batch", false, []string{"p", "seq", "ticks"}},
+	EvFrequency:      {"Frequency", false, []string{"freq", "unused"}},
+	EvStack:          {"Stack", false, []string{"id", "siz"}},
+	EvGomaxprocs:     {"Gomaxprocs", true, []string{"procs"}},
+	EvProcStart:      {"ProcStart", false, []string{"thread"}},
+	EvProcStop:       {"ProcStop", false, []string{}},
+	EvGCStart:        {"GCStart", true, []string{}},
+	EvGCDone:         {"GCDone", false, []string{}},
+	EvGCScanStart:    {"GCScanStart", false, []string{}},
+	EvGCScanDone:     {"GCScanDone", false, []string{}},
+	EvGCSweepStart:   {"GCSweepStart", true, []string{}},
+	EvGCSweepDone:    {"GCSweepDone", false, []string{}},
+	EvGoCreate:       {"GoCreate", true, []string{"g", "pc"}},
+	EvGoStart:        {"GoStart", false, []string{"g"}},
+	EvGoEnd:          {"GoEnd", false, []string{}},
+	EvGoStop:         {"GoStop", true, []string{}},
+	EvGoSched:        {"GoSched", true, []string{}},
+	EvGoPreempt:      {"GoPreempt", true, []string{}},
+	EvGoSleep:        {"GoSleep", true, []string{}},
+	EvGoBlock:        {"GoBlock", true, []string{}},
+	EvGoUnblock:      {"GoUnblock", true, []string{"g"}},
+	EvGoBlockSend:    {"GoBlockSend", true, []string{}},
+	EvGoBlockRecv:    {"GoBlockRecv", true, []string{}},
+	EvGoBlockSelect:  {"GoBlockSelect", true, []string{}},
+	EvGoBlockSync:    {"GoBlockSync", true, []string{}},
+	EvGoBlockCond:    {"GoBlockCond", true, []string{}},
+	EvGoBlockNet:     {"GoBlockNet", true, []string{}},
+	EvGoSysCall:      {"GoSysCall", true, []string{}},
+	EvGoSysExit:      {"GoSysExit", false, []string{"g", "seq", "ts"}},
+	EvGoSysBlock:     {"GoSysBlock", false, []string{}},
+	EvGoWaiting:      {"GoWaiting", false, []string{"g"}},
+	EvGoInSyscall:    {"GoInSyscall", false, []string{"g"}},
+	EvHeapAlloc:      {"HeapAlloc", false, []string{"mem"}},
+	EvNextGC:         {"NextGC", false, []string{"mem"}},
+	EvTimerGoroutine: {"TimerGoroutine", false, []string{"g", "unused"}},
+	EvFutileWakeup:   {"FutileWakeup", false, []string{}},
+}
diff --git a/third_party/gofrontend/libgo/go/internal/trace/parser_test.go b/third_party/gofrontend/libgo/go/internal/trace/parser_test.go
new file mode 100644
index 0000000..0eeb3e6
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/internal/trace/parser_test.go
@@ -0,0 +1,30 @@
+// 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 trace
+
+import (
+	"strings"
+	"testing"
+)
+
+func TestCorruptedInputs(t *testing.T) {
+	// These inputs crashed parser previously.
+	tests := []string{
+		"gotrace\x00\x020",
+		"gotrace\x00Q00\x020",
+		"gotrace\x00T00\x020",
+		"gotrace\x00\xc3\x0200",
+		"go 1.5 trace\x00\x00\x00\x00\x020",
+		"go 1.5 trace\x00\x00\x00\x00Q00\x020",
+		"go 1.5 trace\x00\x00\x00\x00T00\x020",
+		"go 1.5 trace\x00\x00\x00\x00\xc3\x0200",
+	}
+	for _, data := range tests {
+		events, err := Parse(strings.NewReader(data))
+		if err == nil || events != nil {
+			t.Fatalf("no error on input: %q\n", t)
+		}
+	}
+}
diff --git a/third_party/gofrontend/libgo/go/io/io.go b/third_party/gofrontend/libgo/go/io/io.go
index 7507a84..8851eaf 100644
--- a/third_party/gofrontend/libgo/go/io/io.go
+++ b/third_party/gofrontend/libgo/go/io/io.go
@@ -54,7 +54,7 @@
 // An instance of this general case is that a Reader returning
 // a non-zero number of bytes at the end of the input stream may
 // return either err == EOF or err == nil.  The next Read should
-// return 0, EOF regardless.
+// return 0, EOF.
 //
 // Callers should always process the n > 0 bytes returned before
 // considering the error err.  Doing so correctly handles I/O errors
@@ -273,8 +273,8 @@
 	WriteString(s string) (n int, err error)
 }
 
-// WriteString writes the contents of the string s to w, which accepts an array of bytes.
-// If w already implements a WriteString method, it is invoked directly.
+// WriteString writes the contents of the string s to w, which accepts a slice of bytes.
+// If w implements a WriteString method, it is invoked directly.
 func WriteString(w Writer, s string) (n int, err error) {
 	if sw, ok := w.(stringWriter); ok {
 		return sw.WriteString(s)
@@ -348,6 +348,23 @@
 // Otherwise, if dst implements the ReaderFrom interface,
 // the copy is implemented by calling dst.ReadFrom(src).
 func Copy(dst Writer, src Reader) (written int64, err error) {
+	return copyBuffer(dst, src, nil)
+}
+
+// CopyBuffer is identical to Copy except that it stages through the
+// provided buffer (if one is required) rather than allocating a
+// temporary one. If buf is nil, one is allocated; otherwise if it has
+// zero length, CopyBuffer panics.
+func CopyBuffer(dst Writer, src Reader, buf []byte) (written int64, err error) {
+	if buf != nil && len(buf) == 0 {
+		panic("empty buffer in io.CopyBuffer")
+	}
+	return copyBuffer(dst, src, buf)
+}
+
+// copyBuffer is the actual implementation of Copy and CopyBuffer.
+// if buf is nil, one is allocated.
+func copyBuffer(dst Writer, src Reader, buf []byte) (written int64, err error) {
 	// If the reader has a WriteTo method, use it to do the copy.
 	// Avoids an allocation and a copy.
 	if wt, ok := src.(WriterTo); ok {
@@ -357,7 +374,9 @@
 	if rt, ok := dst.(ReaderFrom); ok {
 		return rt.ReadFrom(src)
 	}
-	buf := make([]byte, 32*1024)
+	if buf == nil {
+		buf = make([]byte, 32*1024)
+	}
 	for {
 		nr, er := src.Read(buf)
 		if nr > 0 {
diff --git a/third_party/gofrontend/libgo/go/io/io_test.go b/third_party/gofrontend/libgo/go/io/io_test.go
index 57db1fb..e892574 100644
--- a/third_party/gofrontend/libgo/go/io/io_test.go
+++ b/third_party/gofrontend/libgo/go/io/io_test.go
@@ -20,7 +20,7 @@
 	WriterTo   // conflicts with and hides bytes.Buffer's WriterTo.
 }
 
-// Simple tests, primarily to verify the ReadFrom and WriteTo callouts inside Copy and CopyN.
+// Simple tests, primarily to verify the ReadFrom and WriteTo callouts inside Copy, CopyBuffer and CopyN.
 
 func TestCopy(t *testing.T) {
 	rb := new(Buffer)
@@ -32,6 +32,26 @@
 	}
 }
 
+func TestCopyBuffer(t *testing.T) {
+	rb := new(Buffer)
+	wb := new(Buffer)
+	rb.WriteString("hello, world.")
+	CopyBuffer(wb, rb, make([]byte, 1)) // Tiny buffer to keep it honest.
+	if wb.String() != "hello, world." {
+		t.Errorf("CopyBuffer did not work properly")
+	}
+}
+
+func TestCopyBufferNil(t *testing.T) {
+	rb := new(Buffer)
+	wb := new(Buffer)
+	rb.WriteString("hello, world.")
+	CopyBuffer(wb, rb, nil) // Should allocate a buffer.
+	if wb.String() != "hello, world." {
+		t.Errorf("CopyBuffer did not work properly")
+	}
+}
+
 func TestCopyReadFrom(t *testing.T) {
 	rb := new(Buffer)
 	wb := new(bytes.Buffer) // implements ReadFrom.
@@ -78,6 +98,34 @@
 	}
 }
 
+type zeroErrReader struct {
+	err error
+}
+
+func (r zeroErrReader) Read(p []byte) (int, error) {
+	return copy(p, []byte{0}), r.err
+}
+
+type errWriter struct {
+	err error
+}
+
+func (w errWriter) Write([]byte) (int, error) {
+	return 0, w.err
+}
+
+// In case a Read results in an error with non-zero bytes read, and
+// the subsequent Write also results in an error, the error from Write
+// is returned, as it is the one that prevented progressing further.
+func TestCopyReadErrWriteErr(t *testing.T) {
+	er, ew := errors.New("readError"), errors.New("writeError")
+	r, w := zeroErrReader{err: er}, errWriter{err: ew}
+	n, err := Copy(w, r)
+	if n != 0 || err != ew {
+		t.Errorf("Copy(zeroErrReader, errWriter) = %d, %v; want 0, writeError", n, err)
+	}
+}
+
 func TestCopyN(t *testing.T) {
 	rb := new(Buffer)
 	wb := new(Buffer)
diff --git a/third_party/gofrontend/libgo/go/io/ioutil/tempfile.go b/third_party/gofrontend/libgo/go/io/ioutil/tempfile.go
index 4a06e97..61d4a7a 100644
--- a/third_party/gofrontend/libgo/go/io/ioutil/tempfile.go
+++ b/third_party/gofrontend/libgo/go/io/ioutil/tempfile.go
@@ -55,7 +55,9 @@
 		f, err = os.OpenFile(name, os.O_RDWR|os.O_CREATE|os.O_EXCL, 0600)
 		if os.IsExist(err) {
 			if nconflict++; nconflict > 10 {
+				randmu.Lock()
 				rand = reseed()
+				randmu.Unlock()
 			}
 			continue
 		}
@@ -82,7 +84,9 @@
 		err = os.Mkdir(try, 0700)
 		if os.IsExist(err) {
 			if nconflict++; nconflict > 10 {
+				randmu.Lock()
 				rand = reseed()
+				randmu.Unlock()
 			}
 			continue
 		}
diff --git a/third_party/gofrontend/libgo/go/io/pipe.go b/third_party/gofrontend/libgo/go/io/pipe.go
index f65354a..179515e 100644
--- a/third_party/gofrontend/libgo/go/io/pipe.go
+++ b/third_party/gofrontend/libgo/go/io/pipe.go
@@ -168,7 +168,10 @@
 }
 
 // CloseWithError closes the writer; subsequent reads from the
-// read half of the pipe will return no bytes and the error err.
+// read half of the pipe will return no bytes and the error err,
+// or EOF if err is nil.
+//
+// CloseWithError always returns nil.
 func (w *PipeWriter) CloseWithError(err error) error {
 	w.p.wclose(err)
 	return nil
diff --git a/third_party/gofrontend/libgo/go/log/log.go b/third_party/gofrontend/libgo/go/log/log.go
index d37e437..4cfe550 100644
--- a/third_party/gofrontend/libgo/go/log/log.go
+++ b/third_party/gofrontend/libgo/go/log/log.go
@@ -23,15 +23,21 @@
 
 // These flags define which text to prefix to each log entry generated by the Logger.
 const (
-	// Bits or'ed together to control what's printed. There is no control over the
-	// order they appear (the order listed here) or the format they present (as
-	// described in the comments).  A colon appears after these items:
+	// Bits or'ed together to control what's printed.
+	// There is no control over the order they appear (the order listed
+	// here) or the format they present (as described in the comments).
+	// The prefix is followed by a colon only when Llongfile or Lshortfile
+	// is specified.
+	// For example, flags Ldate | Ltime (or LstdFlags) produce,
+	//	2009/01/23 01:23:23 message
+	// while flags Ldate | Ltime | Lmicroseconds | Llongfile produce,
 	//	2009/01/23 01:23:23.123123 /a/b/c/d.go:23: message
-	Ldate         = 1 << iota     // the date: 2009/01/23
-	Ltime                         // the time: 01:23:23
+	Ldate         = 1 << iota     // the date in the local time zone: 2009/01/23
+	Ltime                         // the time in the local time zone: 01:23:23
 	Lmicroseconds                 // microsecond resolution: 01:23:23.123123.  assumes Ltime.
 	Llongfile                     // full file name and line number: /a/b/c/d.go:23
 	Lshortfile                    // final file name element and line number: d.go:23. overrides Llongfile
+	LUTC                          // if Ldate or Ltime is set, use UTC rather than the local time zone
 	LstdFlags     = Ldate | Ltime // initial values for the standard logger
 )
 
@@ -55,30 +61,37 @@
 	return &Logger{out: out, prefix: prefix, flag: flag}
 }
 
+// SetOutput sets the output destination for the logger.
+func (l *Logger) SetOutput(w io.Writer) {
+	l.mu.Lock()
+	defer l.mu.Unlock()
+	l.out = w
+}
+
 var std = New(os.Stderr, "", LstdFlags)
 
 // Cheap integer to fixed-width decimal ASCII.  Give a negative width to avoid zero-padding.
-// Knows the buffer has capacity.
 func itoa(buf *[]byte, i int, wid int) {
-	var u uint = uint(i)
-	if u == 0 && wid <= 1 {
-		*buf = append(*buf, '0')
-		return
-	}
-
 	// Assemble decimal in reverse order.
-	var b [32]byte
-	bp := len(b)
-	for ; u > 0 || wid > 0; u /= 10 {
-		bp--
+	var b [20]byte
+	bp := len(b) - 1
+	for i >= 10 || wid > 1 {
 		wid--
-		b[bp] = byte(u%10) + '0'
+		q := i / 10
+		b[bp] = byte('0' + i - q*10)
+		bp--
+		i = q
 	}
+	// i < 10
+	b[bp] = byte('0' + i)
 	*buf = append(*buf, b[bp:]...)
 }
 
 func (l *Logger) formatHeader(buf *[]byte, t time.Time, file string, line int) {
 	*buf = append(*buf, l.prefix...)
+	if l.flag&LUTC != 0 {
+		t = t.UTC()
+	}
 	if l.flag&(Ldate|Ltime|Lmicroseconds) != 0 {
 		if l.flag&Ldate != 0 {
 			year, month, day := t.Date()
@@ -147,7 +160,7 @@
 	l.buf = l.buf[:0]
 	l.formatHeader(&l.buf, now, file, line)
 	l.buf = append(l.buf, s...)
-	if len(s) > 0 && s[len(s)-1] != '\n' {
+	if len(s) == 0 || s[len(s)-1] != '\n' {
 		l.buf = append(l.buf, '\n')
 	}
 	_, err := l.out.Write(l.buf)
@@ -320,3 +333,14 @@
 	std.Output(2, s)
 	panic(s)
 }
+
+// Output writes the output for a logging event.  The string s contains
+// the text to print after the prefix specified by the flags of the
+// Logger.  A newline is appended if the last character of s is not
+// already a newline.  Calldepth is the count of the number of
+// frames to skip when computing the file name and line number
+// if Llongfile or Lshortfile is set; a value of 1 will print the details
+// for the caller of Output.
+func Output(calldepth int, s string) error {
+	return std.Output(calldepth+1, s) // +1 for this frame.
+}
diff --git a/third_party/gofrontend/libgo/go/log/log_test.go b/third_party/gofrontend/libgo/go/log/log_test.go
index 158c3d9..dd16c9d 100644
--- a/third_party/gofrontend/libgo/go/log/log_test.go
+++ b/third_party/gofrontend/libgo/go/log/log_test.go
@@ -8,16 +8,19 @@
 
 import (
 	"bytes"
+	"fmt"
 	"os"
 	"regexp"
+	"strings"
 	"testing"
+	"time"
 )
 
 const (
 	Rdate         = `[0-9][0-9][0-9][0-9]/[0-9][0-9]/[0-9][0-9]`
 	Rtime         = `[0-9][0-9]:[0-9][0-9]:[0-9][0-9]`
 	Rmicroseconds = `\.[0-9][0-9][0-9][0-9][0-9][0-9]`
-	Rline         = `(54|56):` // must update if the calls to l.Printf / l.Print below move
+	Rline         = `(57|59):` // must update if the calls to l.Printf / l.Print below move
 	Rlongfile     = `.*/[A-Za-z0-9_\-]+\.go:` + Rline
 	Rshortfile    = `[A-Za-z0-9_\-]+\.go:` + Rline
 )
@@ -117,3 +120,65 @@
 		t.Error("message did not match pattern")
 	}
 }
+
+func TestUTCFlag(t *testing.T) {
+	var b bytes.Buffer
+	l := New(&b, "Test:", LstdFlags)
+	l.SetFlags(Ldate | Ltime | LUTC)
+	// Verify a log message looks right in the right time zone. Quantize to the second only.
+	now := time.Now().UTC()
+	l.Print("hello")
+	want := fmt.Sprintf("Test:%d/%.2d/%.2d %.2d:%.2d:%.2d hello\n",
+		now.Year(), now.Month(), now.Day(), now.Hour(), now.Minute(), now.Second())
+	got := b.String()
+	if got == want {
+		return
+	}
+	// It's possible we crossed a second boundary between getting now and logging,
+	// so add a second and try again. This should very nearly always work.
+	now = now.Add(time.Second)
+	want = fmt.Sprintf("Test:%d/%.2d/%.2d %.2d:%.2d:%.2d hello\n",
+		now.Year(), now.Month(), now.Day(), now.Hour(), now.Minute(), now.Second())
+	if got == want {
+		return
+	}
+	t.Errorf("got %q; want %q", got, want)
+}
+
+func TestEmptyPrintCreatesLine(t *testing.T) {
+	var b bytes.Buffer
+	l := New(&b, "Header:", LstdFlags)
+	l.Print()
+	l.Println("non-empty")
+	output := b.String()
+	if n := strings.Count(output, "Header"); n != 2 {
+		t.Errorf("expected 2 headers, got %d", n)
+	}
+	if n := strings.Count(output, "\n"); n != 2 {
+		t.Errorf("expected 2 lines, got %d", n)
+	}
+}
+
+func BenchmarkItoa(b *testing.B) {
+	dst := make([]byte, 0, 64)
+	for i := 0; i < b.N; i++ {
+		dst = dst[0:0]
+		itoa(&dst, 2015, 4)   // year
+		itoa(&dst, 1, 2)      // month
+		itoa(&dst, 30, 2)     // day
+		itoa(&dst, 12, 2)     // hour
+		itoa(&dst, 56, 2)     // minute
+		itoa(&dst, 0, 2)      // second
+		itoa(&dst, 987654, 6) // microsecond
+	}
+}
+
+func BenchmarkPrintln(b *testing.B) {
+	const testString = "test"
+	var buf bytes.Buffer
+	l := New(&buf, "", LstdFlags)
+	for i := 0; i < b.N; i++ {
+		buf.Reset()
+		l.Println(testString)
+	}
+}
diff --git a/third_party/gofrontend/libgo/go/log/syslog/doc.go b/third_party/gofrontend/libgo/go/log/syslog/doc.go
new file mode 100644
index 0000000..54e76ed
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/log/syslog/doc.go
@@ -0,0 +1,18 @@
+// Copyright 2012 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 syslog provides a simple interface to the system log
+// service. It can send messages to the syslog daemon using UNIX
+// domain sockets, UDP or TCP.
+//
+// Only one call to Dial is necessary. On write failures,
+// the syslog client will attempt to reconnect to the server
+// and write again.
+package syslog
+
+// BUG(brainman): This package is not implemented on Windows yet.
+
+// BUG(akumar): This package is not implemented on Plan 9 yet.
+
+// BUG(minux): This package is not implemented on NaCl (Native Client) yet.
diff --git a/third_party/gofrontend/libgo/go/log/syslog/syslog.go b/third_party/gofrontend/libgo/go/log/syslog/syslog.go
index 5e09599..4bf4476 100644
--- a/third_party/gofrontend/libgo/go/log/syslog/syslog.go
+++ b/third_party/gofrontend/libgo/go/log/syslog/syslog.go
@@ -4,13 +4,6 @@
 
 // +build !windows,!nacl,!plan9
 
-// Package syslog provides a simple interface to the system log
-// service. It can send messages to the syslog daemon using UNIX
-// domain sockets, UDP or TCP.
-//
-// Only one call to Dial is necessary. On write failures,
-// the syslog client will attempt to reconnect to the server
-// and write again.
 package syslog
 
 import (
diff --git a/third_party/gofrontend/libgo/go/log/syslog/syslog_plan9.go b/third_party/gofrontend/libgo/go/log/syslog/syslog_plan9.go
deleted file mode 100644
index 0c05f6f..0000000
--- a/third_party/gofrontend/libgo/go/log/syslog/syslog_plan9.go
+++ /dev/null
@@ -1,8 +0,0 @@
-// Copyright 2012 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 syslog provides a simple interface to the system log service.
-package syslog
-
-// BUG(akumar): This package is not implemented on Plan 9 yet.
diff --git a/third_party/gofrontend/libgo/go/log/syslog/syslog_test.go b/third_party/gofrontend/libgo/go/log/syslog/syslog_test.go
index 6a863fe..85aec53 100644
--- a/third_party/gofrontend/libgo/go/log/syslog/syslog_test.go
+++ b/third_party/gofrontend/libgo/go/log/syslog/syslog_test.go
@@ -14,6 +14,7 @@
 	"log"
 	"net"
 	"os"
+	"runtime"
 	"sync"
 	"testing"
 	"time"
@@ -120,6 +121,13 @@
 	msg := "Test 123"
 	transport := []string{"unix", "unixgram", "udp", "tcp"}
 
+	if runtime.GOOS == "darwin" {
+		switch runtime.GOARCH {
+		case "arm", "arm64":
+			transport = []string{"udp", "tcp"}
+		}
+	}
+
 	for _, tr := range transport {
 		done := make(chan string)
 		addr, sock, srvWG := startServer(tr, "", done)
@@ -142,6 +150,13 @@
 }
 
 func TestFlap(t *testing.T) {
+	if runtime.GOOS == "darwin" {
+		switch runtime.GOARCH {
+		case "arm", "arm64":
+			t.Skipf("skipping on %s/%s", runtime.GOOS, runtime.GOARCH)
+		}
+	}
+
 	net := "unix"
 	done := make(chan string)
 	addr, sock, srvWG := startServer(net, "", done)
@@ -306,9 +321,17 @@
 	const N = 10
 	const M = 100
 	net := "unix"
+	if runtime.GOOS == "darwin" {
+		switch runtime.GOARCH {
+		case "arm", "arm64":
+			net = "tcp"
+		}
+	}
 	done := make(chan string, N*M)
 	addr, sock, srvWG := startServer(net, "", done)
-	defer os.Remove(addr)
+	if net == "unix" {
+		defer os.Remove(addr)
+	}
 
 	// count all the messages arriving
 	count := make(chan int)
diff --git a/third_party/gofrontend/libgo/go/log/syslog/syslog_windows.go b/third_party/gofrontend/libgo/go/log/syslog/syslog_windows.go
deleted file mode 100644
index 8d99e2e..0000000
--- a/third_party/gofrontend/libgo/go/log/syslog/syslog_windows.go
+++ /dev/null
@@ -1,8 +0,0 @@
-// Copyright 2012 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 syslog provides a simple interface to the system log service.
-package syslog
-
-// BUG(brainman): This package is not implemented on Windows yet.
diff --git a/third_party/gofrontend/libgo/go/math/all_test.go b/third_party/gofrontend/libgo/go/math/all_test.go
index 763efb2..e18e45e 100644
--- a/third_party/gofrontend/libgo/go/math/all_test.go
+++ b/third_party/gofrontend/libgo/go/math/all_test.go
@@ -946,16 +946,20 @@
 
 var vfexpm1SC = []float64{
 	Inf(-1),
+	-710,
 	Copysign(0, -1),
 	0,
+	710,
 	Inf(1),
 	NaN(),
 }
 var expm1SC = []float64{
 	-1,
+	-1,
 	Copysign(0, -1),
 	0,
 	Inf(1),
+	Inf(1),
 	NaN(),
 }
 
@@ -991,6 +995,24 @@
 	{NaN(), Inf(1)},
 	{NaN(), NaN()},
 }
+var nan = Float64frombits(0xFFF8000000000000) // SSE2 DIVSD 0/0
+var vffdim2SC = [][2]float64{
+	{Inf(-1), Inf(-1)},
+	{Inf(-1), Inf(1)},
+	{Inf(-1), nan},
+	{Copysign(0, -1), Copysign(0, -1)},
+	{Copysign(0, -1), 0},
+	{0, Copysign(0, -1)},
+	{0, 0},
+	{Inf(1), Inf(-1)},
+	{Inf(1), Inf(1)},
+	{Inf(1), nan},
+	{nan, Inf(-1)},
+	{nan, Copysign(0, -1)},
+	{nan, 0},
+	{nan, Inf(1)},
+	{nan, nan},
+}
 var fdimSC = []float64{
 	NaN(),
 	0,
@@ -1708,8 +1730,10 @@
 		d = -d
 	}
 
-	if a != 0 {
-		e = e * a
+	// note: b is correct (expected) value, a is actual value.
+	// make error tolerance a fraction of b, not a.
+	if b != 0 {
+		e = e * b
 		if e < 0 {
 			e = -e
 		}
@@ -2015,6 +2039,11 @@
 			t.Errorf("Dim(%g, %g) = %g, want %g", vffdimSC[i][0], vffdimSC[i][1], f, fdimSC[i])
 		}
 	}
+	for i := 0; i < len(vffdim2SC); i++ {
+		if f := Dim(vffdim2SC[i][0], vffdim2SC[i][1]); !alike(fdimSC[i], f) {
+			t.Errorf("Dim(%g, %g) = %g, want %g", vffdim2SC[i][0], vffdim2SC[i][1], f, fdimSC[i])
+		}
+	}
 }
 
 func TestFloor(t *testing.T) {
@@ -2041,6 +2070,11 @@
 			t.Errorf("Max(%g, %g) = %g, want %g", vffdimSC[i][0], vffdimSC[i][1], f, fmaxSC[i])
 		}
 	}
+	for i := 0; i < len(vffdim2SC); i++ {
+		if f := Max(vffdim2SC[i][0], vffdim2SC[i][1]); !alike(fmaxSC[i], f) {
+			t.Errorf("Max(%g, %g) = %g, want %g", vffdim2SC[i][0], vffdim2SC[i][1], f, fmaxSC[i])
+		}
+	}
 }
 
 func TestMin(t *testing.T) {
@@ -2054,6 +2088,11 @@
 			t.Errorf("Min(%g, %g) = %g, want %g", vffdimSC[i][0], vffdimSC[i][1], f, fminSC[i])
 		}
 	}
+	for i := 0; i < len(vffdim2SC); i++ {
+		if f := Min(vffdim2SC[i][0], vffdim2SC[i][1]); !alike(fminSC[i], f) {
+			t.Errorf("Min(%g, %g) = %g, want %g", vffdim2SC[i][0], vffdim2SC[i][1], f, fminSC[i])
+		}
+	}
 }
 
 func TestMod(t *testing.T) {
@@ -2606,7 +2645,7 @@
 
 // Check that math constants are accepted by compiler
 // and have right value (assumes strconv.ParseFloat works).
-// http://code.google.com/p/go/issues/detail?id=201
+// https://golang.org/issue/201
 
 type floatTest struct {
 	val  interface{}
@@ -2944,15 +2983,56 @@
 	}
 }
 
+var Global float64
+
 func BenchmarkSqrt(b *testing.B) {
+	x, y := 0.0, 10.0
 	for i := 0; i < b.N; i++ {
-		Sqrt(10)
+		x += Sqrt(y)
 	}
+	Global = x
+}
+
+func BenchmarkSqrtIndirect(b *testing.B) {
+	x, y := 0.0, 10.0
+	f := Sqrt
+	for i := 0; i < b.N; i++ {
+		x += f(y)
+	}
+	Global = x
 }
 
 func BenchmarkSqrtGo(b *testing.B) {
+	x, y := 0.0, 10.0
 	for i := 0; i < b.N; i++ {
-		SqrtGo(10)
+		x += SqrtGo(y)
+	}
+	Global = x
+}
+
+func isPrime(i int) bool {
+	// Yes, this is a dumb way to write this code,
+	// but calling Sqrt repeatedly in this way demonstrates
+	// the benefit of using a direct SQRT instruction on systems
+	// that have one, whereas the obvious loop seems not to
+	// demonstrate such a benefit.
+	for j := 2; float64(j) <= Sqrt(float64(i)); j++ {
+		if i%j == 0 {
+			return false
+		}
+	}
+	return true
+}
+
+func BenchmarkSqrtPrime(b *testing.B) {
+	any := false
+	for i := 0; i < b.N; i++ {
+		if isPrime(100003) {
+			any = true
+		}
+	}
+	if any {
+		Global = 1
 	}
 }
 
diff --git a/third_party/gofrontend/libgo/go/math/big/accuracy_string.go b/third_party/gofrontend/libgo/go/math/big/accuracy_string.go
new file mode 100644
index 0000000..24ef7f1
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/math/big/accuracy_string.go
@@ -0,0 +1,17 @@
+// generated by stringer -type=Accuracy; DO NOT EDIT
+
+package big
+
+import "fmt"
+
+const _Accuracy_name = "BelowExactAbove"
+
+var _Accuracy_index = [...]uint8{0, 5, 10, 15}
+
+func (i Accuracy) String() string {
+	i -= -1
+	if i < 0 || i+1 >= Accuracy(len(_Accuracy_index)) {
+		return fmt.Sprintf("Accuracy(%d)", i+-1)
+	}
+	return _Accuracy_name[_Accuracy_index[i]:_Accuracy_index[i+1]]
+}
diff --git a/third_party/gofrontend/libgo/go/math/big/arith.go b/third_party/gofrontend/libgo/go/math/big/arith.go
index c5ff425..d7ea838 100644
--- a/third_party/gofrontend/libgo/go/math/big/arith.go
+++ b/third_party/gofrontend/libgo/go/math/big/arith.go
@@ -52,8 +52,6 @@
 }
 
 // z1<<_W + z0 = x*y
-func mulWW(x, y Word) (z1, z0 Word) { return mulWW_g(x, y) }
-
 // Adapted from Warren, Hacker's Delight, p. 132.
 func mulWW_g(x, y Word) (z1, z0 Word) {
 	x0 := x & _M2
@@ -72,7 +70,7 @@
 
 // z1<<_W + z0 = x*y + c
 func mulAddWWW_g(x, y, c Word) (z1, z0 Word) {
-	z1, zz0 := mulWW(x, y)
+	z1, zz0 := mulWW_g(x, y)
 	if z0 = zz0 + c; z0 < zz0 {
 		z1++
 	}
@@ -80,7 +78,6 @@
 }
 
 // Length of x in bits.
-func bitLen(x Word) (n int) { return bitLen_g(x) }
 func bitLen_g(x Word) (n int) {
 	for ; x >= 0x8000; x >>= 16 {
 		n += 16
@@ -110,21 +107,34 @@
 	return bitLen(x) - 1
 }
 
-// Number of leading zeros in x.
-func leadingZeros(x Word) uint {
+// nlz returns the number of leading zeros in x.
+func nlz(x Word) uint {
 	return uint(_W - bitLen(x))
 }
 
-// q = (u1<<_W + u0 - r)/y
-func divWW(x1, x0, y Word) (q, r Word) { return divWW_g(x1, x0, y) }
+// nlz64 returns the number of leading zeros in x.
+func nlz64(x uint64) uint {
+	switch _W {
+	case 32:
+		w := x >> 32
+		if w == 0 {
+			return 32 + nlz(Word(x))
+		}
+		return nlz(Word(w))
+	case 64:
+		return nlz(Word(x))
+	}
+	panic("unreachable")
+}
 
+// q = (u1<<_W + u0 - r)/y
 // Adapted from Warren, Hacker's Delight, p. 152.
 func divWW_g(u1, u0, v Word) (q, r Word) {
 	if u1 >= v {
 		return 1<<_W - 1, 1<<_W - 1
 	}
 
-	s := leadingZeros(v)
+	s := nlz(v)
 	v <<= s
 
 	vn1 := v >> _W2
@@ -159,41 +169,85 @@
 	return q1*_B2 + q0, (un21*_B2 + un0 - q0*v) >> s
 }
 
-func addVV(z, x, y []Word) (c Word) { return addVV_g(z, x, y) }
+// Keep for performance debugging.
+// Using addWW_g is likely slower.
+const use_addWW_g = false
+
+// The resulting carry c is either 0 or 1.
 func addVV_g(z, x, y []Word) (c Word) {
-	for i := range z {
-		c, z[i] = addWW_g(x[i], y[i], c)
+	if use_addWW_g {
+		for i := range z {
+			c, z[i] = addWW_g(x[i], y[i], c)
+		}
+		return
+	}
+
+	for i, xi := range x[:len(z)] {
+		yi := y[i]
+		zi := xi + yi + c
+		z[i] = zi
+		// see "Hacker's Delight", section 2-12 (overflow detection)
+		c = (xi&yi | (xi|yi)&^zi) >> (_W - 1)
 	}
 	return
 }
 
-func subVV(z, x, y []Word) (c Word) { return subVV_g(z, x, y) }
+// The resulting carry c is either 0 or 1.
 func subVV_g(z, x, y []Word) (c Word) {
-	for i := range z {
-		c, z[i] = subWW_g(x[i], y[i], c)
+	if use_addWW_g {
+		for i := range z {
+			c, z[i] = subWW_g(x[i], y[i], c)
+		}
+		return
+	}
+
+	for i, xi := range x[:len(z)] {
+		yi := y[i]
+		zi := xi - yi - c
+		z[i] = zi
+		// see "Hacker's Delight", section 2-12 (overflow detection)
+		c = (yi&^xi | (yi|^xi)&zi) >> (_W - 1)
 	}
 	return
 }
 
-func addVW(z, x []Word, y Word) (c Word) { return addVW_g(z, x, y) }
+// The resulting carry c is either 0 or 1.
 func addVW_g(z, x []Word, y Word) (c Word) {
+	if use_addWW_g {
+		c = y
+		for i := range z {
+			c, z[i] = addWW_g(x[i], c, 0)
+		}
+		return
+	}
+
 	c = y
-	for i := range z {
-		c, z[i] = addWW_g(x[i], c, 0)
+	for i, xi := range x[:len(z)] {
+		zi := xi + c
+		z[i] = zi
+		c = xi &^ zi >> (_W - 1)
 	}
 	return
 }
 
-func subVW(z, x []Word, y Word) (c Word) { return subVW_g(z, x, y) }
 func subVW_g(z, x []Word, y Word) (c Word) {
+	if use_addWW_g {
+		c = y
+		for i := range z {
+			c, z[i] = subWW_g(x[i], c, 0)
+		}
+		return
+	}
+
 	c = y
-	for i := range z {
-		c, z[i] = subWW_g(x[i], c, 0)
+	for i, xi := range x[:len(z)] {
+		zi := xi - c
+		z[i] = zi
+		c = (zi &^ xi) >> (_W - 1)
 	}
 	return
 }
 
-func shlVU(z, x []Word, s uint) (c Word) { return shlVU_g(z, x, s) }
 func shlVU_g(z, x []Word, s uint) (c Word) {
 	if n := len(z); n > 0 {
 		ŝ := _W - s
@@ -209,7 +263,6 @@
 	return
 }
 
-func shrVU(z, x []Word, s uint) (c Word) { return shrVU_g(z, x, s) }
 func shrVU_g(z, x []Word, s uint) (c Word) {
 	if n := len(z); n > 0 {
 		ŝ := _W - s
@@ -225,7 +278,6 @@
 	return
 }
 
-func mulAddVWW(z, x []Word, y, r Word) (c Word) { return mulAddVWW_g(z, x, y, r) }
 func mulAddVWW_g(z, x []Word, y, r Word) (c Word) {
 	c = r
 	for i := range z {
@@ -234,7 +286,7 @@
 	return
 }
 
-func addMulVVW(z, x []Word, y Word) (c Word) { return addMulVVW_g(z, x, y) }
+// TODO(gri) Remove use of addWW_g here and then we can remove addWW_g and subWW_g.
 func addMulVVW_g(z, x []Word, y Word) (c Word) {
 	for i := range z {
 		z1, z0 := mulAddWWW_g(x[i], y, z[i])
@@ -244,7 +296,6 @@
 	return
 }
 
-func divWVW(z []Word, xn Word, x []Word, y Word) (r Word) { return divWVW_g(z, xn, x, y) }
 func divWVW_g(z []Word, xn Word, x []Word, y Word) (r Word) {
 	r = xn
 	for i := len(z) - 1; i >= 0; i-- {
diff --git a/third_party/gofrontend/libgo/go/math/big/arith_decl.go b/third_party/gofrontend/libgo/go/math/big/arith_decl.go
index 068cc8d..1707aa4 100644
--- a/third_party/gofrontend/libgo/go/math/big/arith_decl.go
+++ b/third_party/gofrontend/libgo/go/math/big/arith_decl.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 !math_big_pure_go
+
 package big
 
 // implemented in arith_$GOARCH.s
diff --git a/third_party/gofrontend/libgo/go/math/big/arith_decl_pure.go b/third_party/gofrontend/libgo/go/math/big/arith_decl_pure.go
new file mode 100644
index 0000000..e760a38
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/math/big/arith_decl_pure.go
@@ -0,0 +1,55 @@
+// 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 math_big_pure_go
+
+package big
+
+func mulWW(x, y Word) (z1, z0 Word) {
+	return mulWW_g(x, y)
+}
+
+func divWW(x1, x0, y Word) (q, r Word) {
+	return divWW_g(x1, x0, y)
+}
+
+func addVV(z, x, y []Word) (c Word) {
+	return addVV_g(z, x, y)
+}
+
+func subVV(z, x, y []Word) (c Word) {
+	return subVV_g(z, x, y)
+}
+
+func addVW(z, x []Word, y Word) (c Word) {
+	return addVW_g(z, x, y)
+}
+
+func subVW(z, x []Word, y Word) (c Word) {
+	return subVW_g(z, x, y)
+}
+
+func shlVU(z, x []Word, s uint) (c Word) {
+	return shlVU_g(z, x, s)
+}
+
+func shrVU(z, x []Word, s uint) (c Word) {
+	return shrVU_g(z, x, s)
+}
+
+func mulAddVWW(z, x []Word, y, r Word) (c Word) {
+	return mulAddVWW_g(z, x, y, r)
+}
+
+func addMulVVW(z, x []Word, y Word) (c Word) {
+	return addMulVVW_g(z, x, y)
+}
+
+func divWVW(z []Word, xn Word, x []Word, y Word) (r Word) {
+	return divWVW_g(z, xn, x, y)
+}
+
+func bitLen(x Word) (n int) {
+	return bitLen_g(x)
+}
diff --git a/third_party/gofrontend/libgo/go/math/big/arith_test.go b/third_party/gofrontend/libgo/go/math/big/arith_test.go
index 3615a65..f46a494 100644
--- a/third_party/gofrontend/libgo/go/math/big/arith_test.go
+++ b/third_party/gofrontend/libgo/go/math/big/arith_test.go
@@ -155,6 +155,7 @@
 	{nat{1}, nat{1}, 0, 0},
 	{nat{0}, nat{_M}, 1, 1},
 	{nat{0, 0, 0, 0}, nat{_M, _M, _M, _M}, 1, 1},
+	{nat{585}, nat{314}, 271, 0},
 }
 
 var prodVW = []argVW{
@@ -254,7 +255,7 @@
 	x := rndV(n)
 	y := rndW()
 	z := make([]Word, n)
-	b.SetBytes(int64(n * _W))
+	b.SetBytes(int64(n * _S))
 	b.ResetTimer()
 	for i := 0; i < b.N; i++ {
 		f(z, x, y)
diff --git a/third_party/gofrontend/libgo/go/math/big/bits_test.go b/third_party/gofrontend/libgo/go/math/big/bits_test.go
new file mode 100644
index 0000000..985b60b
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/math/big/bits_test.go
@@ -0,0 +1,224 @@
+// 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.
+
+// This file implements the Bits type used for testing Float operations
+// via an independent (albeit slower) representations for floating-point
+// numbers.
+
+package big
+
+import (
+	"fmt"
+	"sort"
+	"testing"
+)
+
+// A Bits value b represents a finite floating-point number x of the form
+//
+//	x = 2**b[0] + 2**b[1] + ... 2**b[len(b)-1]
+//
+// The order of slice elements is not significant. Negative elements may be
+// used to form fractions. A Bits value is normalized if each b[i] occurs at
+// most once. For instance Bits{0, 0, 1} is not normalized but represents the
+// same floating-point number as Bits{2}, which is normalized. The zero (nil)
+// value of Bits is a ready to use Bits value and represents the value 0.
+type Bits []int
+
+func (x Bits) add(y Bits) Bits {
+	return append(x, y...)
+}
+
+func (x Bits) mul(y Bits) Bits {
+	var p Bits
+	for _, x := range x {
+		for _, y := range y {
+			p = append(p, x+y)
+		}
+	}
+	return p
+}
+
+func TestMulBits(t *testing.T) {
+	for _, test := range []struct {
+		x, y, want Bits
+	}{
+		{nil, nil, nil},
+		{Bits{}, Bits{}, nil},
+		{Bits{0}, Bits{0}, Bits{0}},
+		{Bits{0}, Bits{1}, Bits{1}},
+		{Bits{1}, Bits{1, 2, 3}, Bits{2, 3, 4}},
+		{Bits{-1}, Bits{1}, Bits{0}},
+		{Bits{-10, -1, 0, 1, 10}, Bits{1, 2, 3}, Bits{-9, -8, -7, 0, 1, 2, 1, 2, 3, 2, 3, 4, 11, 12, 13}},
+	} {
+		got := fmt.Sprintf("%v", test.x.mul(test.y))
+		want := fmt.Sprintf("%v", test.want)
+		if got != want {
+			t.Errorf("%v * %v = %s; want %s", test.x, test.y, got, want)
+		}
+
+	}
+}
+
+// norm returns the normalized bits for x: It removes multiple equal entries
+// by treating them as an addition (e.g., Bits{5, 5} => Bits{6}), and it sorts
+// the result list for reproducible results.
+func (x Bits) norm() Bits {
+	m := make(map[int]bool)
+	for _, b := range x {
+		for m[b] {
+			m[b] = false
+			b++
+		}
+		m[b] = true
+	}
+	var z Bits
+	for b, set := range m {
+		if set {
+			z = append(z, b)
+		}
+	}
+	sort.Ints([]int(z))
+	return z
+}
+
+func TestNormBits(t *testing.T) {
+	for _, test := range []struct {
+		x, want Bits
+	}{
+		{nil, nil},
+		{Bits{}, Bits{}},
+		{Bits{0}, Bits{0}},
+		{Bits{0, 0}, Bits{1}},
+		{Bits{3, 1, 1}, Bits{2, 3}},
+		{Bits{10, 9, 8, 7, 6, 6}, Bits{11}},
+	} {
+		got := fmt.Sprintf("%v", test.x.norm())
+		want := fmt.Sprintf("%v", test.want)
+		if got != want {
+			t.Errorf("normBits(%v) = %s; want %s", test.x, got, want)
+		}
+
+	}
+}
+
+// round returns the Float value corresponding to x after rounding x
+// to prec bits according to mode.
+func (x Bits) round(prec uint, mode RoundingMode) *Float {
+	x = x.norm()
+
+	// determine range
+	var min, max int
+	for i, b := range x {
+		if i == 0 || b < min {
+			min = b
+		}
+		if i == 0 || b > max {
+			max = b
+		}
+	}
+	prec0 := uint(max + 1 - min)
+	if prec >= prec0 {
+		return x.Float()
+	}
+	// prec < prec0
+
+	// determine bit 0, rounding, and sticky bit, and result bits z
+	var bit0, rbit, sbit uint
+	var z Bits
+	r := max - int(prec)
+	for _, b := range x {
+		switch {
+		case b == r:
+			rbit = 1
+		case b < r:
+			sbit = 1
+		default:
+			// b > r
+			if b == r+1 {
+				bit0 = 1
+			}
+			z = append(z, b)
+		}
+	}
+
+	// round
+	f := z.Float() // rounded to zero
+	if mode == ToNearestAway {
+		panic("not yet implemented")
+	}
+	if mode == ToNearestEven && rbit == 1 && (sbit == 1 || sbit == 0 && bit0 != 0) || mode == AwayFromZero {
+		// round away from zero
+		f.SetMode(ToZero).SetPrec(prec)
+		f.Add(f, Bits{int(r) + 1}.Float())
+	}
+	return f
+}
+
+// Float returns the *Float z of the smallest possible precision such that
+// z = sum(2**bits[i]), with i = range bits. If multiple bits[i] are equal,
+// they are added: Bits{0, 1, 0}.Float() == 2**0 + 2**1 + 2**0 = 4.
+func (bits Bits) Float() *Float {
+	// handle 0
+	if len(bits) == 0 {
+		return new(Float)
+	}
+	// len(bits) > 0
+
+	// determine lsb exponent
+	var min int
+	for i, b := range bits {
+		if i == 0 || b < min {
+			min = b
+		}
+	}
+
+	// create bit pattern
+	x := NewInt(0)
+	for _, b := range bits {
+		badj := b - min
+		// propagate carry if necessary
+		for x.Bit(badj) != 0 {
+			x.SetBit(x, badj, 0)
+			badj++
+		}
+		x.SetBit(x, badj, 1)
+	}
+
+	// create corresponding float
+	z := new(Float).SetInt(x) // normalized
+	if e := int64(z.exp) + int64(min); MinExp <= e && e <= MaxExp {
+		z.exp = int32(e)
+	} else {
+		// this should never happen for our test cases
+		panic("exponent out of range")
+	}
+	return z
+}
+
+func TestFromBits(t *testing.T) {
+	for _, test := range []struct {
+		bits Bits
+		want string
+	}{
+		// all different bit numbers
+		{nil, "0"},
+		{Bits{0}, "0x.8p+1"},
+		{Bits{1}, "0x.8p+2"},
+		{Bits{-1}, "0x.8p+0"},
+		{Bits{63}, "0x.8p+64"},
+		{Bits{33, -30}, "0x.8000000000000001p+34"},
+		{Bits{255, 0}, "0x.8000000000000000000000000000000000000000000000000000000000000001p+256"},
+
+		// multiple equal bit numbers
+		{Bits{0, 0}, "0x.8p+2"},
+		{Bits{0, 0, 0, 0}, "0x.8p+3"},
+		{Bits{0, 1, 0}, "0x.8p+3"},
+		{append(Bits{2, 1, 0} /* 7 */, Bits{3, 1} /* 10 */ ...), "0x.88p+5" /* 17 */},
+	} {
+		f := test.bits.Float()
+		if got := f.Text('p', 0); got != test.want {
+			t.Errorf("setBits(%v) = %s; want %s", test.bits, got, test.want)
+		}
+	}
+}
diff --git a/third_party/gofrontend/libgo/go/math/big/decimal.go b/third_party/gofrontend/libgo/go/math/big/decimal.go
new file mode 100644
index 0000000..2595e5f
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/math/big/decimal.go
@@ -0,0 +1,264 @@
+// 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.
+
+// This file implements multi-precision decimal numbers.
+// The implementation is for float to decimal conversion only;
+// not general purpose use.
+// The only operations are precise conversion from binary to
+// decimal and rounding.
+//
+// The key observation and some code (shr) is borrowed from
+// strconv/decimal.go: conversion of binary fractional values can be done
+// precisely in multi-precision decimal because 2 divides 10 (required for
+// >> of mantissa); but conversion of decimal floating-point values cannot
+// be done precisely in binary representation.
+//
+// In contrast to strconv/decimal.go, only right shift is implemented in
+// decimal format - left shift can be done precisely in binary format.
+
+package big
+
+// A decimal represents an unsigned floating-point number in decimal representation.
+// The value of a non-zero decimal x is x.mant * 10 ** x.exp with 0.5 <= x.mant < 1,
+// with the most-significant mantissa digit at index 0. For the zero decimal, the
+// mantissa length and exponent are 0.
+// The zero value for decimal represents a ready-to-use 0.0.
+type decimal struct {
+	mant []byte // mantissa ASCII digits, big-endian
+	exp  int    // exponent
+}
+
+// Maximum shift amount that can be done in one pass without overflow.
+// A Word has _W bits and (1<<maxShift - 1)*10 + 9 must fit into Word.
+const maxShift = _W - 4
+
+// TODO(gri) Since we know the desired decimal precision when converting
+// a floating-point number, we may be able to limit the number of decimal
+// digits that need to be computed by init by providing an additional
+// precision argument and keeping track of when a number was truncated early
+// (equivalent of "sticky bit" in binary rounding).
+
+// TODO(gri) Along the same lines, enforce some limit to shift magnitudes
+// to avoid "infinitely" long running conversions (until we run out of space).
+
+// Init initializes x to the decimal representation of m << shift (for
+// shift >= 0), or m >> -shift (for shift < 0).
+func (x *decimal) init(m nat, shift int) {
+	// special case 0
+	if len(m) == 0 {
+		x.mant = x.mant[:0]
+		x.exp = 0
+		return
+	}
+
+	// Optimization: If we need to shift right, first remove any trailing
+	// zero bits from m to reduce shift amount that needs to be done in
+	// decimal format (since that is likely slower).
+	if shift < 0 {
+		ntz := m.trailingZeroBits()
+		s := uint(-shift)
+		if s >= ntz {
+			s = ntz // shift at most ntz bits
+		}
+		m = nat(nil).shr(m, s)
+		shift += int(s)
+	}
+
+	// Do any shift left in binary representation.
+	if shift > 0 {
+		m = nat(nil).shl(m, uint(shift))
+		shift = 0
+	}
+
+	// Convert mantissa into decimal representation.
+	s := m.decimalString() // TODO(gri) avoid string conversion here
+	n := len(s)
+	x.exp = n
+	// Trim trailing zeros; instead the exponent is tracking
+	// the decimal point independent of the number of digits.
+	for n > 0 && s[n-1] == '0' {
+		n--
+	}
+	x.mant = append(x.mant[:0], s[:n]...)
+
+	// Do any (remaining) shift right in decimal representation.
+	if shift < 0 {
+		for shift < -maxShift {
+			shr(x, maxShift)
+			shift += maxShift
+		}
+		shr(x, uint(-shift))
+	}
+}
+
+// Possibly optimization: The current implementation of nat.string takes
+// a charset argument. When a right shift is needed, we could provide
+// "\x00\x01...\x09" instead of "012..9" (as in nat.decimalString) and
+// avoid the repeated +'0' and -'0' operations in decimal.shr (and do a
+// single +'0' pass at the end).
+
+// shr implements x >> s, for s <= maxShift.
+func shr(x *decimal, s uint) {
+	// Division by 1<<s using shift-and-subtract algorithm.
+
+	// pick up enough leading digits to cover first shift
+	r := 0 // read index
+	var n Word
+	for n>>s == 0 && r < len(x.mant) {
+		ch := Word(x.mant[r])
+		r++
+		n = n*10 + ch - '0'
+	}
+	if n == 0 {
+		// x == 0; shouldn't get here, but handle anyway
+		x.mant = x.mant[:0]
+		return
+	}
+	for n>>s == 0 {
+		r++
+		n *= 10
+	}
+	x.exp += 1 - r
+
+	// read a digit, write a digit
+	w := 0 // write index
+	for r < len(x.mant) {
+		ch := Word(x.mant[r])
+		r++
+		d := n >> s
+		n -= d << s
+		x.mant[w] = byte(d + '0')
+		w++
+		n = n*10 + ch - '0'
+	}
+
+	// write extra digits that still fit
+	for n > 0 && w < len(x.mant) {
+		d := n >> s
+		n -= d << s
+		x.mant[w] = byte(d + '0')
+		w++
+		n = n * 10
+	}
+	x.mant = x.mant[:w] // the number may be shorter (e.g. 1024 >> 10)
+
+	// append additional digits that didn't fit
+	for n > 0 {
+		d := n >> s
+		n -= d << s
+		x.mant = append(x.mant, byte(d+'0'))
+		n = n * 10
+	}
+
+	trim(x)
+}
+
+func (x *decimal) String() string {
+	if len(x.mant) == 0 {
+		return "0"
+	}
+
+	var buf []byte
+	switch {
+	case x.exp <= 0:
+		// 0.00ddd
+		buf = append(buf, "0."...)
+		buf = appendZeros(buf, -x.exp)
+		buf = append(buf, x.mant...)
+
+	case /* 0 < */ x.exp < len(x.mant):
+		// dd.ddd
+		buf = append(buf, x.mant[:x.exp]...)
+		buf = append(buf, '.')
+		buf = append(buf, x.mant[x.exp:]...)
+
+	default: // len(x.mant) <= x.exp
+		// ddd00
+		buf = append(buf, x.mant...)
+		buf = appendZeros(buf, x.exp-len(x.mant))
+	}
+
+	return string(buf)
+}
+
+// appendZeros appends n 0 digits to buf and returns buf.
+func appendZeros(buf []byte, n int) []byte {
+	for ; n > 0; n-- {
+		buf = append(buf, '0')
+	}
+	return buf
+}
+
+// shouldRoundUp reports if x should be rounded up
+// if shortened to n digits. n must be a valid index
+// for x.mant.
+func shouldRoundUp(x *decimal, n int) bool {
+	if x.mant[n] == '5' && n+1 == len(x.mant) {
+		// exactly halfway - round to even
+		return n > 0 && (x.mant[n-1]-'0')&1 != 0
+	}
+	// not halfway - digit tells all (x.mant has no trailing zeros)
+	return x.mant[n] >= '5'
+}
+
+// round sets x to (at most) n mantissa digits by rounding it
+// to the nearest even value with n (or fever) mantissa digits.
+// If n < 0, x remains unchanged.
+func (x *decimal) round(n int) {
+	if n < 0 || n >= len(x.mant) {
+		return // nothing to do
+	}
+
+	if shouldRoundUp(x, n) {
+		x.roundUp(n)
+	} else {
+		x.roundDown(n)
+	}
+}
+
+func (x *decimal) roundUp(n int) {
+	if n < 0 || n >= len(x.mant) {
+		return // nothing to do
+	}
+	// 0 <= n < len(x.mant)
+
+	// find first digit < '9'
+	for n > 0 && x.mant[n-1] >= '9' {
+		n--
+	}
+
+	if n == 0 {
+		// all digits are '9's => round up to '1' and update exponent
+		x.mant[0] = '1' // ok since len(x.mant) > n
+		x.mant = x.mant[:1]
+		x.exp++
+		return
+	}
+
+	// n > 0 && x.mant[n-1] < '9'
+	x.mant[n-1]++
+	x.mant = x.mant[:n]
+	// x already trimmed
+}
+
+func (x *decimal) roundDown(n int) {
+	if n < 0 || n >= len(x.mant) {
+		return // nothing to do
+	}
+	x.mant = x.mant[:n]
+	trim(x)
+}
+
+// trim cuts off any trailing zeros from x's mantissa;
+// they are meaningless for the value of x.
+func trim(x *decimal) {
+	i := len(x.mant)
+	for i > 0 && x.mant[i-1] == '0' {
+		i--
+	}
+	x.mant = x.mant[:i]
+	if i == 0 {
+		x.exp = 0
+	}
+}
diff --git a/third_party/gofrontend/libgo/go/math/big/decimal_test.go b/third_party/gofrontend/libgo/go/math/big/decimal_test.go
new file mode 100644
index 0000000..81e022a
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/math/big/decimal_test.go
@@ -0,0 +1,106 @@
+// 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 big
+
+import "testing"
+
+func TestDecimalString(t *testing.T) {
+	for _, test := range []struct {
+		x    decimal
+		want string
+	}{
+		{want: "0"},
+		{decimal{nil, 1000}, "0"}, // exponent of 0 is ignored
+		{decimal{[]byte("12345"), 0}, "0.12345"},
+		{decimal{[]byte("12345"), -3}, "0.00012345"},
+		{decimal{[]byte("12345"), +3}, "123.45"},
+		{decimal{[]byte("12345"), +10}, "1234500000"},
+	} {
+		if got := test.x.String(); got != test.want {
+			t.Errorf("%v == %s; want %s", test.x, got, test.want)
+		}
+	}
+}
+
+func TestDecimalInit(t *testing.T) {
+	for _, test := range []struct {
+		x     Word
+		shift int
+		want  string
+	}{
+		{0, 0, "0"},
+		{0, -100, "0"},
+		{0, 100, "0"},
+		{1, 0, "1"},
+		{1, 10, "1024"},
+		{1, 100, "1267650600228229401496703205376"},
+		{1, -100, "0.0000000000000000000000000000007888609052210118054117285652827862296732064351090230047702789306640625"},
+		{12345678, 8, "3160493568"},
+		{12345678, -8, "48225.3046875"},
+		{195312, 9, "99999744"},
+		{1953125, 9, "1000000000"},
+	} {
+		var d decimal
+		d.init(nat{test.x}.norm(), test.shift)
+		if got := d.String(); got != test.want {
+			t.Errorf("%d << %d == %s; want %s", test.x, test.shift, got, test.want)
+		}
+	}
+}
+
+func TestDecimalRounding(t *testing.T) {
+	for _, test := range []struct {
+		x              uint64
+		n              int
+		down, even, up string
+	}{
+		{0, 0, "0", "0", "0"},
+		{0, 1, "0", "0", "0"},
+
+		{1, 0, "0", "0", "10"},
+		{5, 0, "0", "0", "10"},
+		{9, 0, "0", "10", "10"},
+
+		{15, 1, "10", "20", "20"},
+		{45, 1, "40", "40", "50"},
+		{95, 1, "90", "100", "100"},
+
+		{12344999, 4, "12340000", "12340000", "12350000"},
+		{12345000, 4, "12340000", "12340000", "12350000"},
+		{12345001, 4, "12340000", "12350000", "12350000"},
+		{23454999, 4, "23450000", "23450000", "23460000"},
+		{23455000, 4, "23450000", "23460000", "23460000"},
+		{23455001, 4, "23450000", "23460000", "23460000"},
+
+		{99994999, 4, "99990000", "99990000", "100000000"},
+		{99995000, 4, "99990000", "100000000", "100000000"},
+		{99999999, 4, "99990000", "100000000", "100000000"},
+
+		{12994999, 4, "12990000", "12990000", "13000000"},
+		{12995000, 4, "12990000", "13000000", "13000000"},
+		{12999999, 4, "12990000", "13000000", "13000000"},
+	} {
+		x := nat(nil).setUint64(test.x)
+
+		var d decimal
+		d.init(x, 0)
+		d.roundDown(test.n)
+		if got := d.String(); got != test.down {
+			t.Errorf("roundDown(%d, %d) = %s; want %s", test.x, test.n, got, test.down)
+		}
+
+		d.init(x, 0)
+		d.round(test.n)
+		if got := d.String(); got != test.even {
+			t.Errorf("round(%d, %d) = %s; want %s", test.x, test.n, got, test.even)
+		}
+
+		d.init(x, 0)
+		d.roundUp(test.n)
+		if got := d.String(); got != test.up {
+			t.Errorf("roundUp(%d, %d) = %s; want %s", test.x, test.n, got, test.up)
+		}
+	}
+}
diff --git a/third_party/gofrontend/libgo/go/math/big/float.go b/third_party/gofrontend/libgo/go/math/big/float.go
new file mode 100644
index 0000000..d7aa895
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/math/big/float.go
@@ -0,0 +1,1693 @@
+// 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.
+
+// This file implements multi-precision floating-point numbers.
+// Like in the GNU MPFR library (http://www.mpfr.org/), operands
+// can be of mixed precision. Unlike MPFR, the rounding mode is
+// not specified with each operation, but with each operand. The
+// rounding mode of the result operand determines the rounding
+// mode of an operation. This is a from-scratch implementation.
+
+package big
+
+import (
+	"fmt"
+	"math"
+)
+
+const debugFloat = false // enable for debugging
+
+// A nonzero finite Float represents a multi-precision floating point number
+//
+//   sign × mantissa × 2**exponent
+//
+// with 0.5 <= mantissa < 1.0, and MinExp <= exponent <= MaxExp.
+// A Float may also be zero (+0, -0) or infinite (+Inf, -Inf).
+// All Floats are ordered, and the ordering of two Floats x and y
+// is defined by x.Cmp(y).
+//
+// Each Float value also has a precision, rounding mode, and accuracy.
+// The precision is the maximum number of mantissa bits available to
+// represent the value. The rounding mode specifies how a result should
+// be rounded to fit into the mantissa bits, and accuracy describes the
+// rounding error with respect to the exact result.
+//
+// Unless specified otherwise, all operations (including setters) that
+// specify a *Float variable for the result (usually via the receiver
+// with the exception of MantExp), round the numeric result according
+// to the precision and rounding mode of the result variable.
+//
+// If the provided result precision is 0 (see below), it is set to the
+// precision of the argument with the largest precision value before any
+// rounding takes place, and the rounding mode remains unchanged. Thus,
+// uninitialized Floats provided as result arguments will have their
+// precision set to a reasonable value determined by the operands and
+// their mode is the zero value for RoundingMode (ToNearestEven).
+//
+// By setting the desired precision to 24 or 53 and using matching rounding
+// mode (typically ToNearestEven), Float operations produce the same results
+// as the corresponding float32 or float64 IEEE-754 arithmetic for operands
+// that correspond to normal (i.e., not denormal) float32 or float64 numbers.
+// Exponent underflow and overflow lead to a 0 or an Infinity for different
+// values than IEEE-754 because Float exponents have a much larger range.
+//
+// The zero (uninitialized) value for a Float is ready to use and represents
+// the number +0.0 exactly, with precision 0 and rounding mode ToNearestEven.
+//
+type Float struct {
+	prec uint32
+	mode RoundingMode
+	acc  Accuracy
+	form form
+	neg  bool
+	mant nat
+	exp  int32
+}
+
+// An ErrNaN panic is raised by a Float operation that would lead to
+// a NaN under IEEE-754 rules. An ErrNaN implements the error interface.
+type ErrNaN struct {
+	msg string
+}
+
+func (err ErrNaN) Error() string {
+	return err.msg
+}
+
+// NewFloat allocates and returns a new Float set to x,
+// with precision 53 and rounding mode ToNearestEven.
+// NewFloat panics with ErrNaN if x is a NaN.
+func NewFloat(x float64) *Float {
+	if math.IsNaN(x) {
+		panic(ErrNaN{"NewFloat(NaN)"})
+	}
+	return new(Float).SetFloat64(x)
+}
+
+// Exponent and precision limits.
+const (
+	MaxExp  = math.MaxInt32  // largest supported exponent
+	MinExp  = math.MinInt32  // smallest supported exponent
+	MaxPrec = math.MaxUint32 // largest (theoretically) supported precision; likely memory-limited
+)
+
+// Internal representation: The mantissa bits x.mant of a nonzero finite
+// Float x are stored in a nat slice long enough to hold up to x.prec bits;
+// the slice may (but doesn't have to) be shorter if the mantissa contains
+// trailing 0 bits. x.mant is normalized if the msb of x.mant == 1 (i.e.,
+// the msb is shifted all the way "to the left"). Thus, if the mantissa has
+// trailing 0 bits or x.prec is not a multiple of the the Word size _W,
+// x.mant[0] has trailing zero bits. The msb of the mantissa corresponds
+// to the value 0.5; the exponent x.exp shifts the binary point as needed.
+//
+// A zero or non-finite Float x ignores x.mant and x.exp.
+//
+// x                 form      neg      mant         exp
+// ----------------------------------------------------------
+// ±0                zero      sign     -            -
+// 0 < |x| < +Inf    finite    sign     mantissa     exponent
+// ±Inf              inf       sign     -            -
+
+// A form value describes the internal representation.
+type form byte
+
+// The form value order is relevant - do not change!
+const (
+	zero form = iota
+	finite
+	inf
+)
+
+// RoundingMode determines how a Float value is rounded to the
+// desired precision. Rounding may change the Float value; the
+// rounding error is described by the Float's Accuracy.
+type RoundingMode byte
+
+// The following rounding modes are supported.
+const (
+	ToNearestEven RoundingMode = iota // == IEEE 754-2008 roundTiesToEven
+	ToNearestAway                     // == IEEE 754-2008 roundTiesToAway
+	ToZero                            // == IEEE 754-2008 roundTowardZero
+	AwayFromZero                      // no IEEE 754-2008 equivalent
+	ToNegativeInf                     // == IEEE 754-2008 roundTowardNegative
+	ToPositiveInf                     // == IEEE 754-2008 roundTowardPositive
+)
+
+//go:generate stringer -type=RoundingMode
+
+// Accuracy describes the rounding error produced by the most recent
+// operation that generated a Float value, relative to the exact value.
+type Accuracy int8
+
+// Constants describing the Accuracy of a Float.
+const (
+	Below Accuracy = -1
+	Exact Accuracy = 0
+	Above Accuracy = +1
+)
+
+//go:generate stringer -type=Accuracy
+
+// SetPrec sets z's precision to prec and returns the (possibly) rounded
+// value of z. Rounding occurs according to z's rounding mode if the mantissa
+// cannot be represented in prec bits without loss of precision.
+// SetPrec(0) maps all finite values to ±0; infinite values remain unchanged.
+// If prec > MaxPrec, it is set to MaxPrec.
+func (z *Float) SetPrec(prec uint) *Float {
+	z.acc = Exact // optimistically assume no rounding is needed
+
+	// special case
+	if prec == 0 {
+		z.prec = 0
+		if z.form == finite {
+			// truncate z to 0
+			z.acc = makeAcc(z.neg)
+			z.form = zero
+		}
+		return z
+	}
+
+	// general case
+	if prec > MaxPrec {
+		prec = MaxPrec
+	}
+	old := z.prec
+	z.prec = uint32(prec)
+	if z.prec < old {
+		z.round(0)
+	}
+	return z
+}
+
+func makeAcc(above bool) Accuracy {
+	if above {
+		return Above
+	}
+	return Below
+}
+
+// SetMode sets z's rounding mode to mode and returns an exact z.
+// z remains unchanged otherwise.
+// z.SetMode(z.Mode()) is a cheap way to set z's accuracy to Exact.
+func (z *Float) SetMode(mode RoundingMode) *Float {
+	z.mode = mode
+	z.acc = Exact
+	return z
+}
+
+// Prec returns the mantissa precision of x in bits.
+// The result may be 0 for |x| == 0 and |x| == Inf.
+func (x *Float) Prec() uint {
+	return uint(x.prec)
+}
+
+// MinPrec returns the minimum precision required to represent x exactly
+// (i.e., the smallest prec before x.SetPrec(prec) would start rounding x).
+// The result is 0 for |x| == 0 and |x| == Inf.
+func (x *Float) MinPrec() uint {
+	if x.form != finite {
+		return 0
+	}
+	return uint(len(x.mant))*_W - x.mant.trailingZeroBits()
+}
+
+// Mode returns the rounding mode of x.
+func (x *Float) Mode() RoundingMode {
+	return x.mode
+}
+
+// Acc returns the accuracy of x produced by the most recent operation.
+func (x *Float) Acc() Accuracy {
+	return x.acc
+}
+
+// Sign returns:
+//
+//	-1 if x <   0
+//	 0 if x is ±0
+//	+1 if x >   0
+//
+func (x *Float) Sign() int {
+	if debugFloat {
+		x.validate()
+	}
+	if x.form == zero {
+		return 0
+	}
+	if x.neg {
+		return -1
+	}
+	return 1
+}
+
+// MantExp breaks x into its mantissa and exponent components
+// and returns the exponent. If a non-nil mant argument is
+// provided its value is set to the mantissa of x, with the
+// same precision and rounding mode as x. The components
+// satisfy x == mant × 2**exp, with 0.5 <= |mant| < 1.0.
+// Calling MantExp with a nil argument is an efficient way to
+// get the exponent of the receiver.
+//
+// Special cases are:
+//
+//	(  ±0).MantExp(mant) = 0, with mant set to   ±0
+//	(±Inf).MantExp(mant) = 0, with mant set to ±Inf
+//
+// x and mant may be the same in which case x is set to its
+// mantissa value.
+func (x *Float) MantExp(mant *Float) (exp int) {
+	if debugFloat {
+		x.validate()
+	}
+	if x.form == finite {
+		exp = int(x.exp)
+	}
+	if mant != nil {
+		mant.Copy(x)
+		if mant.form == finite {
+			mant.exp = 0
+		}
+	}
+	return
+}
+
+func (z *Float) setExpAndRound(exp int64, sbit uint) {
+	if exp < MinExp {
+		// underflow
+		z.acc = makeAcc(z.neg)
+		z.form = zero
+		return
+	}
+
+	if exp > MaxExp {
+		// overflow
+		z.acc = makeAcc(!z.neg)
+		z.form = inf
+		return
+	}
+
+	z.form = finite
+	z.exp = int32(exp)
+	z.round(sbit)
+}
+
+// SetMantExp sets z to mant × 2**exp and and returns z.
+// The result z has the same precision and rounding mode
+// as mant. SetMantExp is an inverse of MantExp but does
+// not require 0.5 <= |mant| < 1.0. Specifically:
+//
+//	mant := new(Float)
+//	new(Float).SetMantExp(mant, x.SetMantExp(mant)).Cmp(x).Eql() is true
+//
+// Special cases are:
+//
+//	z.SetMantExp(  ±0, exp) =   ±0
+//	z.SetMantExp(±Inf, exp) = ±Inf
+//
+// z and mant may be the same in which case z's exponent
+// is set to exp.
+func (z *Float) SetMantExp(mant *Float, exp int) *Float {
+	if debugFloat {
+		z.validate()
+		mant.validate()
+	}
+	z.Copy(mant)
+	if z.form != finite {
+		return z
+	}
+	z.setExpAndRound(int64(z.exp)+int64(exp), 0)
+	return z
+}
+
+// Signbit returns true if x is negative or negative zero.
+func (x *Float) Signbit() bool {
+	return x.neg
+}
+
+// IsInf reports whether x is +Inf or -Inf.
+func (x *Float) IsInf() bool {
+	return x.form == inf
+}
+
+// IsInt reports whether x is an integer.
+// ±Inf values are not integers.
+func (x *Float) IsInt() bool {
+	if debugFloat {
+		x.validate()
+	}
+	// special cases
+	if x.form != finite {
+		return x.form == zero
+	}
+	// x.form == finite
+	if x.exp <= 0 {
+		return false
+	}
+	// x.exp > 0
+	return x.prec <= uint32(x.exp) || x.MinPrec() <= uint(x.exp) // not enough bits for fractional mantissa
+}
+
+// debugging support
+func (x *Float) validate() {
+	if !debugFloat {
+		// avoid performance bugs
+		panic("validate called but debugFloat is not set")
+	}
+	if x.form != finite {
+		return
+	}
+	m := len(x.mant)
+	if m == 0 {
+		panic("nonzero finite number with empty mantissa")
+	}
+	const msb = 1 << (_W - 1)
+	if x.mant[m-1]&msb == 0 {
+		panic(fmt.Sprintf("msb not set in last word %#x of %s", x.mant[m-1], x.Text('p', 0)))
+	}
+	if x.prec == 0 {
+		panic("zero precision finite number")
+	}
+}
+
+// round rounds z according to z.mode to z.prec bits and sets z.acc accordingly.
+// sbit must be 0 or 1 and summarizes any "sticky bit" information one might
+// have before calling round. z's mantissa must be normalized (with the msb set)
+// or empty.
+//
+// CAUTION: The rounding modes ToNegativeInf, ToPositiveInf are affected by the
+// sign of z. For correct rounding, the sign of z must be set correctly before
+// calling round.
+func (z *Float) round(sbit uint) {
+	if debugFloat {
+		z.validate()
+	}
+
+	z.acc = Exact
+	if z.form != finite {
+		// ±0 or ±Inf => nothing left to do
+		return
+	}
+	// z.form == finite && len(z.mant) > 0
+	// m > 0 implies z.prec > 0 (checked by validate)
+
+	m := uint32(len(z.mant)) // present mantissa length in words
+	bits := m * _W           // present mantissa bits
+	if bits <= z.prec {
+		// mantissa fits => nothing to do
+		return
+	}
+	// bits > z.prec
+
+	n := (z.prec + (_W - 1)) / _W // mantissa length in words for desired precision
+
+	// Rounding is based on two bits: the rounding bit (rbit) and the
+	// sticky bit (sbit). The rbit is the bit immediately before the
+	// z.prec leading mantissa bits (the "0.5"). The sbit is set if any
+	// of the bits before the rbit are set (the "0.25", "0.125", etc.):
+	//
+	//   rbit  sbit  => "fractional part"
+	//
+	//   0     0        == 0
+	//   0     1        >  0  , < 0.5
+	//   1     0        == 0.5
+	//   1     1        >  0.5, < 1.0
+
+	// bits > z.prec: mantissa too large => round
+	r := uint(bits - z.prec - 1) // rounding bit position; r >= 0
+	rbit := z.mant.bit(r)        // rounding bit
+	if sbit == 0 {
+		sbit = z.mant.sticky(r)
+	}
+	if debugFloat && sbit&^1 != 0 {
+		panic(fmt.Sprintf("invalid sbit %#x", sbit))
+	}
+
+	// convert ToXInf rounding modes
+	mode := z.mode
+	switch mode {
+	case ToNegativeInf:
+		mode = ToZero
+		if z.neg {
+			mode = AwayFromZero
+		}
+	case ToPositiveInf:
+		mode = AwayFromZero
+		if z.neg {
+			mode = ToZero
+		}
+	}
+
+	// cut off extra words
+	if m > n {
+		copy(z.mant, z.mant[m-n:]) // move n last words to front
+		z.mant = z.mant[:n]
+	}
+
+	// determine number of trailing zero bits t
+	t := n*_W - z.prec // 0 <= t < _W
+	lsb := Word(1) << t
+
+	// make rounding decision
+	// TODO(gri) This can be simplified (see Bits.round in bits_test.go).
+	switch mode {
+	case ToZero:
+		// nothing to do
+	case ToNearestEven, ToNearestAway:
+		if rbit == 0 {
+			// rounding bits == 0b0x
+			mode = ToZero
+		} else if sbit == 1 {
+			// rounding bits == 0b11
+			mode = AwayFromZero
+		}
+	case AwayFromZero:
+		if rbit|sbit == 0 {
+			mode = ToZero
+		}
+	default:
+		// ToXInf modes have been converted to ToZero or AwayFromZero
+		panic("unreachable")
+	}
+
+	// round and determine accuracy
+	switch mode {
+	case ToZero:
+		if rbit|sbit != 0 {
+			z.acc = Below
+		}
+
+	case ToNearestEven, ToNearestAway:
+		if debugFloat && rbit != 1 {
+			panic("internal error in rounding")
+		}
+		if mode == ToNearestEven && sbit == 0 && z.mant[0]&lsb == 0 {
+			z.acc = Below
+			break
+		}
+		// mode == ToNearestAway || sbit == 1 || z.mant[0]&lsb != 0
+		fallthrough
+
+	case AwayFromZero:
+		// add 1 to mantissa
+		if addVW(z.mant, z.mant, lsb) != 0 {
+			// overflow => shift mantissa right by 1 and add msb
+			shrVU(z.mant, z.mant, 1)
+			z.mant[n-1] |= 1 << (_W - 1)
+			// adjust exponent
+			if z.exp < MaxExp {
+				z.exp++
+			} else {
+				// exponent overflow
+				z.acc = makeAcc(!z.neg)
+				z.form = inf
+				return
+			}
+		}
+		z.acc = Above
+	}
+
+	// zero out trailing bits in least-significant word
+	z.mant[0] &^= lsb - 1
+
+	// update accuracy
+	if z.acc != Exact && z.neg {
+		z.acc = -z.acc
+	}
+
+	if debugFloat {
+		z.validate()
+	}
+
+	return
+}
+
+func (z *Float) setBits64(neg bool, x uint64) *Float {
+	if z.prec == 0 {
+		z.prec = 64
+	}
+	z.acc = Exact
+	z.neg = neg
+	if x == 0 {
+		z.form = zero
+		return z
+	}
+	// x != 0
+	z.form = finite
+	s := nlz64(x)
+	z.mant = z.mant.setUint64(x << s)
+	z.exp = int32(64 - s) // always fits
+	if z.prec < 64 {
+		z.round(0)
+	}
+	return z
+}
+
+// SetUint64 sets z to the (possibly rounded) value of x and returns z.
+// If z's precision is 0, it is changed to 64 (and rounding will have
+// no effect).
+func (z *Float) SetUint64(x uint64) *Float {
+	return z.setBits64(false, x)
+}
+
+// SetInt64 sets z to the (possibly rounded) value of x and returns z.
+// If z's precision is 0, it is changed to 64 (and rounding will have
+// no effect).
+func (z *Float) SetInt64(x int64) *Float {
+	u := x
+	if u < 0 {
+		u = -u
+	}
+	// We cannot simply call z.SetUint64(uint64(u)) and change
+	// the sign afterwards because the sign affects rounding.
+	return z.setBits64(x < 0, uint64(u))
+}
+
+// SetFloat64 sets z to the (possibly rounded) value of x and returns z.
+// If z's precision is 0, it is changed to 53 (and rounding will have
+// no effect). SetFloat64 panics with ErrNaN if x is a NaN.
+func (z *Float) SetFloat64(x float64) *Float {
+	if z.prec == 0 {
+		z.prec = 53
+	}
+	if math.IsNaN(x) {
+		panic(ErrNaN{"Float.SetFloat64(NaN)"})
+	}
+	z.acc = Exact
+	z.neg = math.Signbit(x) // handle -0, -Inf correctly
+	if x == 0 {
+		z.form = zero
+		return z
+	}
+	if math.IsInf(x, 0) {
+		z.form = inf
+		return z
+	}
+	// normalized x != 0
+	z.form = finite
+	fmant, exp := math.Frexp(x) // get normalized mantissa
+	z.mant = z.mant.setUint64(1<<63 | math.Float64bits(fmant)<<11)
+	z.exp = int32(exp) // always fits
+	if z.prec < 53 {
+		z.round(0)
+	}
+	return z
+}
+
+// fnorm normalizes mantissa m by shifting it to the left
+// such that the msb of the most-significant word (msw) is 1.
+// It returns the shift amount. It assumes that len(m) != 0.
+func fnorm(m nat) int64 {
+	if debugFloat && (len(m) == 0 || m[len(m)-1] == 0) {
+		panic("msw of mantissa is 0")
+	}
+	s := nlz(m[len(m)-1])
+	if s > 0 {
+		c := shlVU(m, m, s)
+		if debugFloat && c != 0 {
+			panic("nlz or shlVU incorrect")
+		}
+	}
+	return int64(s)
+}
+
+// SetInt sets z to the (possibly rounded) value of x and returns z.
+// If z's precision is 0, it is changed to the larger of x.BitLen()
+// or 64 (and rounding will have no effect).
+func (z *Float) SetInt(x *Int) *Float {
+	// TODO(gri) can be more efficient if z.prec > 0
+	// but small compared to the size of x, or if there
+	// are many trailing 0's.
+	bits := uint32(x.BitLen())
+	if z.prec == 0 {
+		z.prec = umax32(bits, 64)
+	}
+	z.acc = Exact
+	z.neg = x.neg
+	if len(x.abs) == 0 {
+		z.form = zero
+		return z
+	}
+	// x != 0
+	z.mant = z.mant.set(x.abs)
+	fnorm(z.mant)
+	z.setExpAndRound(int64(bits), 0)
+	return z
+}
+
+// SetRat sets z to the (possibly rounded) value of x and returns z.
+// If z's precision is 0, it is changed to the largest of a.BitLen(),
+// b.BitLen(), or 64; with x = a/b.
+func (z *Float) SetRat(x *Rat) *Float {
+	if x.IsInt() {
+		return z.SetInt(x.Num())
+	}
+	var a, b Float
+	a.SetInt(x.Num())
+	b.SetInt(x.Denom())
+	if z.prec == 0 {
+		z.prec = umax32(a.prec, b.prec)
+	}
+	return z.Quo(&a, &b)
+}
+
+// SetInf sets z to the infinite Float -Inf if signbit is
+// set, or +Inf if signbit is not set, and returns z. The
+// precision of z is unchanged and the result is always
+// Exact.
+func (z *Float) SetInf(signbit bool) *Float {
+	z.acc = Exact
+	z.form = inf
+	z.neg = signbit
+	return z
+}
+
+// Set sets z to the (possibly rounded) value of x and returns z.
+// If z's precision is 0, it is changed to the precision of x
+// before setting z (and rounding will have no effect).
+// Rounding is performed according to z's precision and rounding
+// mode; and z's accuracy reports the result error relative to the
+// exact (not rounded) result.
+func (z *Float) Set(x *Float) *Float {
+	if debugFloat {
+		x.validate()
+	}
+	z.acc = Exact
+	if z != x {
+		z.form = x.form
+		z.neg = x.neg
+		if x.form == finite {
+			z.exp = x.exp
+			z.mant = z.mant.set(x.mant)
+		}
+		if z.prec == 0 {
+			z.prec = x.prec
+		} else if z.prec < x.prec {
+			z.round(0)
+		}
+	}
+	return z
+}
+
+// Copy sets z to x, with the same precision, rounding mode, and
+// accuracy as x, and returns z. x is not changed even if z and
+// x are the same.
+func (z *Float) Copy(x *Float) *Float {
+	if debugFloat {
+		x.validate()
+	}
+	if z != x {
+		z.prec = x.prec
+		z.mode = x.mode
+		z.acc = x.acc
+		z.form = x.form
+		z.neg = x.neg
+		if z.form == finite {
+			z.mant = z.mant.set(x.mant)
+			z.exp = x.exp
+		}
+	}
+	return z
+}
+
+// msb32 returns the 32 most significant bits of x.
+func msb32(x nat) uint32 {
+	i := len(x) - 1
+	if i < 0 {
+		return 0
+	}
+	if debugFloat && x[i]&(1<<(_W-1)) == 0 {
+		panic("x not normalized")
+	}
+	switch _W {
+	case 32:
+		return uint32(x[i])
+	case 64:
+		return uint32(x[i] >> 32)
+	}
+	panic("unreachable")
+}
+
+// msb64 returns the 64 most significant bits of x.
+func msb64(x nat) uint64 {
+	i := len(x) - 1
+	if i < 0 {
+		return 0
+	}
+	if debugFloat && x[i]&(1<<(_W-1)) == 0 {
+		panic("x not normalized")
+	}
+	switch _W {
+	case 32:
+		v := uint64(x[i]) << 32
+		if i > 0 {
+			v |= uint64(x[i-1])
+		}
+		return v
+	case 64:
+		return uint64(x[i])
+	}
+	panic("unreachable")
+}
+
+// Uint64 returns the unsigned integer resulting from truncating x
+// towards zero. If 0 <= x <= math.MaxUint64, the result is Exact
+// if x is an integer and Below otherwise.
+// The result is (0, Above) for x < 0, and (math.MaxUint64, Below)
+// for x > math.MaxUint64.
+func (x *Float) Uint64() (uint64, Accuracy) {
+	if debugFloat {
+		x.validate()
+	}
+
+	switch x.form {
+	case finite:
+		if x.neg {
+			return 0, Above
+		}
+		// 0 < x < +Inf
+		if x.exp <= 0 {
+			// 0 < x < 1
+			return 0, Below
+		}
+		// 1 <= x < Inf
+		if x.exp <= 64 {
+			// u = trunc(x) fits into a uint64
+			u := msb64(x.mant) >> (64 - uint32(x.exp))
+			if x.MinPrec() <= 64 {
+				return u, Exact
+			}
+			return u, Below // x truncated
+		}
+		// x too large
+		return math.MaxUint64, Below
+
+	case zero:
+		return 0, Exact
+
+	case inf:
+		if x.neg {
+			return 0, Above
+		}
+		return math.MaxUint64, Below
+	}
+
+	panic("unreachable")
+}
+
+// Int64 returns the integer resulting from truncating x towards zero.
+// If math.MinInt64 <= x <= math.MaxInt64, the result is Exact if x is
+// an integer, and Above (x < 0) or Below (x > 0) otherwise.
+// The result is (math.MinInt64, Above) for x < math.MinInt64,
+// and (math.MaxInt64, Below) for x > math.MaxInt64.
+func (x *Float) Int64() (int64, Accuracy) {
+	if debugFloat {
+		x.validate()
+	}
+
+	switch x.form {
+	case finite:
+		// 0 < |x| < +Inf
+		acc := makeAcc(x.neg)
+		if x.exp <= 0 {
+			// 0 < |x| < 1
+			return 0, acc
+		}
+		// x.exp > 0
+
+		// 1 <= |x| < +Inf
+		if x.exp <= 63 {
+			// i = trunc(x) fits into an int64 (excluding math.MinInt64)
+			i := int64(msb64(x.mant) >> (64 - uint32(x.exp)))
+			if x.neg {
+				i = -i
+			}
+			if x.MinPrec() <= uint(x.exp) {
+				return i, Exact
+			}
+			return i, acc // x truncated
+		}
+		if x.neg {
+			// check for special case x == math.MinInt64 (i.e., x == -(0.5 << 64))
+			if x.exp == 64 && x.MinPrec() == 1 {
+				acc = Exact
+			}
+			return math.MinInt64, acc
+		}
+		// x too large
+		return math.MaxInt64, Below
+
+	case zero:
+		return 0, Exact
+
+	case inf:
+		if x.neg {
+			return math.MinInt64, Above
+		}
+		return math.MaxInt64, Below
+	}
+
+	panic("unreachable")
+}
+
+// Float32 returns the float32 value nearest to x. If x is too small to be
+// represented by a float32 (|x| < math.SmallestNonzeroFloat32), the result
+// is (0, Below) or (-0, Above), respectively, depending on the sign of x.
+// If x is too large to be represented by a float32 (|x| > math.MaxFloat32),
+// the result is (+Inf, Above) or (-Inf, Below), depending on the sign of x.
+func (x *Float) Float32() (float32, Accuracy) {
+	if debugFloat {
+		x.validate()
+	}
+
+	switch x.form {
+	case finite:
+		// 0 < |x| < +Inf
+
+		const (
+			fbits = 32                //        float size
+			mbits = 23                //        mantissa size (excluding implicit msb)
+			ebits = fbits - mbits - 1 //     8  exponent size
+			bias  = 1<<(ebits-1) - 1  //   127  exponent bias
+			dmin  = 1 - bias - mbits  //  -149  smallest unbiased exponent (denormal)
+			emin  = 1 - bias          //  -126  smallest unbiased exponent (normal)
+			emax  = bias              //   127  largest unbiased exponent (normal)
+		)
+
+		// Float mantissa m is 0.5 <= m < 1.0; compute exponent for floatxx mantissa.
+		e := x.exp - 1 // exponent for mantissa m with 1.0 <= m < 2.0
+		p := mbits + 1 // precision of normal float
+
+		// If the exponent is too small, we may have a denormal number
+		// in which case we have fewer mantissa bits available: reduce
+		// precision accordingly.
+		if e < emin {
+			p -= emin - int(e)
+			// Make sure we have at least 1 bit so that we don't
+			// lose numbers rounded up to the smallest denormal.
+			if p < 1 {
+				p = 1
+			}
+		}
+
+		// round
+		var r Float
+		r.prec = uint32(p)
+		r.Set(x)
+		e = r.exp - 1
+
+		// Rounding may have caused r to overflow to ±Inf
+		// (rounding never causes underflows to 0).
+		if r.form == inf {
+			e = emax + 1 // cause overflow below
+		}
+
+		// If the exponent is too large, overflow to ±Inf.
+		if e > emax {
+			// overflow
+			if x.neg {
+				return float32(math.Inf(-1)), Below
+			}
+			return float32(math.Inf(+1)), Above
+		}
+		// e <= emax
+
+		// Determine sign, biased exponent, and mantissa.
+		var sign, bexp, mant uint32
+		if x.neg {
+			sign = 1 << (fbits - 1)
+		}
+
+		// Rounding may have caused a denormal number to
+		// become normal. Check again.
+		if e < emin {
+			// denormal number
+			if e < dmin {
+				// underflow to ±0
+				if x.neg {
+					var z float32
+					return -z, Above
+				}
+				return 0.0, Below
+			}
+			// bexp = 0
+			mant = msb32(r.mant) >> (fbits - r.prec)
+		} else {
+			// normal number: emin <= e <= emax
+			bexp = uint32(e+bias) << mbits
+			mant = msb32(r.mant) >> ebits & (1<<mbits - 1) // cut off msb (implicit 1 bit)
+		}
+
+		return math.Float32frombits(sign | bexp | mant), r.acc
+
+	case zero:
+		if x.neg {
+			var z float32
+			return -z, Exact
+		}
+		return 0.0, Exact
+
+	case inf:
+		if x.neg {
+			return float32(math.Inf(-1)), Exact
+		}
+		return float32(math.Inf(+1)), Exact
+	}
+
+	panic("unreachable")
+}
+
+// Float64 returns the float64 value nearest to x. If x is too small to be
+// represented by a float64 (|x| < math.SmallestNonzeroFloat64), the result
+// is (0, Below) or (-0, Above), respectively, depending on the sign of x.
+// If x is too large to be represented by a float64 (|x| > math.MaxFloat64),
+// the result is (+Inf, Above) or (-Inf, Below), depending on the sign of x.
+func (x *Float) Float64() (float64, Accuracy) {
+	if debugFloat {
+		x.validate()
+	}
+
+	switch x.form {
+	case finite:
+		// 0 < |x| < +Inf
+
+		const (
+			fbits = 64                //        float size
+			mbits = 52                //        mantissa size (excluding implicit msb)
+			ebits = fbits - mbits - 1 //    11  exponent size
+			bias  = 1<<(ebits-1) - 1  //  1023  exponent bias
+			dmin  = 1 - bias - mbits  // -1074  smallest unbiased exponent (denormal)
+			emin  = 1 - bias          // -1022  smallest unbiased exponent (normal)
+			emax  = bias              //  1023  largest unbiased exponent (normal)
+		)
+
+		// Float mantissa m is 0.5 <= m < 1.0; compute exponent for floatxx mantissa.
+		e := x.exp - 1 // exponent for mantissa m with 1.0 <= m < 2.0
+		p := mbits + 1 // precision of normal float
+
+		// If the exponent is too small, we may have a denormal number
+		// in which case we have fewer mantissa bits available: reduce
+		// precision accordingly.
+		if e < emin {
+			p -= emin - int(e)
+			// Make sure we have at least 1 bit so that we don't
+			// lose numbers rounded up to the smallest denormal.
+			if p < 1 {
+				p = 1
+			}
+		}
+
+		// round
+		var r Float
+		r.prec = uint32(p)
+		r.Set(x)
+		e = r.exp - 1
+
+		// Rounding may have caused r to overflow to ±Inf
+		// (rounding never causes underflows to 0).
+		if r.form == inf {
+			e = emax + 1 // cause overflow below
+		}
+
+		// If the exponent is too large, overflow to ±Inf.
+		if e > emax {
+			// overflow
+			if x.neg {
+				return math.Inf(-1), Below
+			}
+			return math.Inf(+1), Above
+		}
+		// e <= emax
+
+		// Determine sign, biased exponent, and mantissa.
+		var sign, bexp, mant uint64
+		if x.neg {
+			sign = 1 << (fbits - 1)
+		}
+
+		// Rounding may have caused a denormal number to
+		// become normal. Check again.
+		if e < emin {
+			// denormal number
+			if e < dmin {
+				// underflow to ±0
+				if x.neg {
+					var z float64
+					return -z, Above
+				}
+				return 0.0, Below
+			}
+			// bexp = 0
+			mant = msb64(r.mant) >> (fbits - r.prec)
+		} else {
+			// normal number: emin <= e <= emax
+			bexp = uint64(e+bias) << mbits
+			mant = msb64(r.mant) >> ebits & (1<<mbits - 1) // cut off msb (implicit 1 bit)
+		}
+
+		return math.Float64frombits(sign | bexp | mant), r.acc
+
+	case zero:
+		if x.neg {
+			var z float64
+			return -z, Exact
+		}
+		return 0.0, Exact
+
+	case inf:
+		if x.neg {
+			return math.Inf(-1), Exact
+		}
+		return math.Inf(+1), Exact
+	}
+
+	panic("unreachable")
+}
+
+// Int returns the result of truncating x towards zero;
+// or nil if x is an infinity.
+// The result is Exact if x.IsInt(); otherwise it is Below
+// for x > 0, and Above for x < 0.
+// If a non-nil *Int argument z is provided, Int stores
+// the result in z instead of allocating a new Int.
+func (x *Float) Int(z *Int) (*Int, Accuracy) {
+	if debugFloat {
+		x.validate()
+	}
+
+	if z == nil && x.form <= finite {
+		z = new(Int)
+	}
+
+	switch x.form {
+	case finite:
+		// 0 < |x| < +Inf
+		acc := makeAcc(x.neg)
+		if x.exp <= 0 {
+			// 0 < |x| < 1
+			return z.SetInt64(0), acc
+		}
+		// x.exp > 0
+
+		// 1 <= |x| < +Inf
+		// determine minimum required precision for x
+		allBits := uint(len(x.mant)) * _W
+		exp := uint(x.exp)
+		if x.MinPrec() <= exp {
+			acc = Exact
+		}
+		// shift mantissa as needed
+		if z == nil {
+			z = new(Int)
+		}
+		z.neg = x.neg
+		switch {
+		case exp > allBits:
+			z.abs = z.abs.shl(x.mant, exp-allBits)
+		default:
+			z.abs = z.abs.set(x.mant)
+		case exp < allBits:
+			z.abs = z.abs.shr(x.mant, allBits-exp)
+		}
+		return z, acc
+
+	case zero:
+		return z.SetInt64(0), Exact
+
+	case inf:
+		return nil, makeAcc(x.neg)
+	}
+
+	panic("unreachable")
+}
+
+// Rat returns the rational number corresponding to x;
+// or nil if x is an infinity.
+// The result is Exact is x is not an Inf.
+// If a non-nil *Rat argument z is provided, Rat stores
+// the result in z instead of allocating a new Rat.
+func (x *Float) Rat(z *Rat) (*Rat, Accuracy) {
+	if debugFloat {
+		x.validate()
+	}
+
+	if z == nil && x.form <= finite {
+		z = new(Rat)
+	}
+
+	switch x.form {
+	case finite:
+		// 0 < |x| < +Inf
+		allBits := int32(len(x.mant)) * _W
+		// build up numerator and denominator
+		z.a.neg = x.neg
+		switch {
+		case x.exp > allBits:
+			z.a.abs = z.a.abs.shl(x.mant, uint(x.exp-allBits))
+			z.b.abs = z.b.abs[:0] // == 1 (see Rat)
+			// z already in normal form
+		default:
+			z.a.abs = z.a.abs.set(x.mant)
+			z.b.abs = z.b.abs[:0] // == 1 (see Rat)
+			// z already in normal form
+		case x.exp < allBits:
+			z.a.abs = z.a.abs.set(x.mant)
+			t := z.b.abs.setUint64(1)
+			z.b.abs = t.shl(t, uint(allBits-x.exp))
+			z.norm()
+		}
+		return z, Exact
+
+	case zero:
+		return z.SetInt64(0), Exact
+
+	case inf:
+		return nil, makeAcc(x.neg)
+	}
+
+	panic("unreachable")
+}
+
+// Abs sets z to the (possibly rounded) value |x| (the absolute value of x)
+// and returns z.
+func (z *Float) Abs(x *Float) *Float {
+	z.Set(x)
+	z.neg = false
+	return z
+}
+
+// Neg sets z to the (possibly rounded) value of x with its sign negated,
+// and returns z.
+func (z *Float) Neg(x *Float) *Float {
+	z.Set(x)
+	z.neg = !z.neg
+	return z
+}
+
+func validateBinaryOperands(x, y *Float) {
+	if !debugFloat {
+		// avoid performance bugs
+		panic("validateBinaryOperands called but debugFloat is not set")
+	}
+	if len(x.mant) == 0 {
+		panic("empty mantissa for x")
+	}
+	if len(y.mant) == 0 {
+		panic("empty mantissa for y")
+	}
+}
+
+// z = x + y, ignoring signs of x and y for the addition
+// but using the sign of z for rounding the result.
+// x and y must have a non-empty mantissa and valid exponent.
+func (z *Float) uadd(x, y *Float) {
+	// Note: This implementation requires 2 shifts most of the
+	// time. It is also inefficient if exponents or precisions
+	// differ by wide margins. The following article describes
+	// an efficient (but much more complicated) implementation
+	// compatible with the internal representation used here:
+	//
+	// Vincent Lefèvre: "The Generic Multiple-Precision Floating-
+	// Point Addition With Exact Rounding (as in the MPFR Library)"
+	// http://www.vinc17.net/research/papers/rnc6.pdf
+
+	if debugFloat {
+		validateBinaryOperands(x, y)
+	}
+
+	// compute exponents ex, ey for mantissa with "binary point"
+	// on the right (mantissa.0) - use int64 to avoid overflow
+	ex := int64(x.exp) - int64(len(x.mant))*_W
+	ey := int64(y.exp) - int64(len(y.mant))*_W
+
+	// TODO(gri) having a combined add-and-shift primitive
+	//           could make this code significantly faster
+	switch {
+	case ex < ey:
+		// cannot re-use z.mant w/o testing for aliasing
+		t := nat(nil).shl(y.mant, uint(ey-ex))
+		z.mant = z.mant.add(x.mant, t)
+	default:
+		// ex == ey, no shift needed
+		z.mant = z.mant.add(x.mant, y.mant)
+	case ex > ey:
+		// cannot re-use z.mant w/o testing for aliasing
+		t := nat(nil).shl(x.mant, uint(ex-ey))
+		z.mant = z.mant.add(t, y.mant)
+		ex = ey
+	}
+	// len(z.mant) > 0
+
+	z.setExpAndRound(ex+int64(len(z.mant))*_W-fnorm(z.mant), 0)
+}
+
+// z = x - y for |x| > |y|, ignoring signs of x and y for the subtraction
+// but using the sign of z for rounding the result.
+// x and y must have a non-empty mantissa and valid exponent.
+func (z *Float) usub(x, y *Float) {
+	// This code is symmetric to uadd.
+	// We have not factored the common code out because
+	// eventually uadd (and usub) should be optimized
+	// by special-casing, and the code will diverge.
+
+	if debugFloat {
+		validateBinaryOperands(x, y)
+	}
+
+	ex := int64(x.exp) - int64(len(x.mant))*_W
+	ey := int64(y.exp) - int64(len(y.mant))*_W
+
+	switch {
+	case ex < ey:
+		// cannot re-use z.mant w/o testing for aliasing
+		t := nat(nil).shl(y.mant, uint(ey-ex))
+		z.mant = t.sub(x.mant, t)
+	default:
+		// ex == ey, no shift needed
+		z.mant = z.mant.sub(x.mant, y.mant)
+	case ex > ey:
+		// cannot re-use z.mant w/o testing for aliasing
+		t := nat(nil).shl(x.mant, uint(ex-ey))
+		z.mant = t.sub(t, y.mant)
+		ex = ey
+	}
+
+	// operands may have cancelled each other out
+	if len(z.mant) == 0 {
+		z.acc = Exact
+		z.form = zero
+		z.neg = false
+		return
+	}
+	// len(z.mant) > 0
+
+	z.setExpAndRound(ex+int64(len(z.mant))*_W-fnorm(z.mant), 0)
+}
+
+// z = x * y, ignoring signs of x and y for the multiplication
+// but using the sign of z for rounding the result.
+// x and y must have a non-empty mantissa and valid exponent.
+func (z *Float) umul(x, y *Float) {
+	if debugFloat {
+		validateBinaryOperands(x, y)
+	}
+
+	// Note: This is doing too much work if the precision
+	// of z is less than the sum of the precisions of x
+	// and y which is often the case (e.g., if all floats
+	// have the same precision).
+	// TODO(gri) Optimize this for the common case.
+
+	e := int64(x.exp) + int64(y.exp)
+	z.mant = z.mant.mul(x.mant, y.mant)
+
+	z.setExpAndRound(e-fnorm(z.mant), 0)
+}
+
+// z = x / y, ignoring signs of x and y for the division
+// but using the sign of z for rounding the result.
+// x and y must have a non-empty mantissa and valid exponent.
+func (z *Float) uquo(x, y *Float) {
+	if debugFloat {
+		validateBinaryOperands(x, y)
+	}
+
+	// mantissa length in words for desired result precision + 1
+	// (at least one extra bit so we get the rounding bit after
+	// the division)
+	n := int(z.prec/_W) + 1
+
+	// compute adjusted x.mant such that we get enough result precision
+	xadj := x.mant
+	if d := n - len(x.mant) + len(y.mant); d > 0 {
+		// d extra words needed => add d "0 digits" to x
+		xadj = make(nat, len(x.mant)+d)
+		copy(xadj[d:], x.mant)
+	}
+	// TODO(gri): If we have too many digits (d < 0), we should be able
+	// to shorten x for faster division. But we must be extra careful
+	// with rounding in that case.
+
+	// Compute d before division since there may be aliasing of x.mant
+	// (via xadj) or y.mant with z.mant.
+	d := len(xadj) - len(y.mant)
+
+	// divide
+	var r nat
+	z.mant, r = z.mant.div(nil, xadj, y.mant)
+	e := int64(x.exp) - int64(y.exp) - int64(d-len(z.mant))*_W
+
+	// The result is long enough to include (at least) the rounding bit.
+	// If there's a non-zero remainder, the corresponding fractional part
+	// (if it were computed), would have a non-zero sticky bit (if it were
+	// zero, it couldn't have a non-zero remainder).
+	var sbit uint
+	if len(r) > 0 {
+		sbit = 1
+	}
+
+	z.setExpAndRound(e-fnorm(z.mant), sbit)
+}
+
+// ucmp returns -1, 0, or +1, depending on whether
+// |x| < |y|, |x| == |y|, or |x| > |y|.
+// x and y must have a non-empty mantissa and valid exponent.
+func (x *Float) ucmp(y *Float) int {
+	if debugFloat {
+		validateBinaryOperands(x, y)
+	}
+
+	switch {
+	case x.exp < y.exp:
+		return -1
+	case x.exp > y.exp:
+		return +1
+	}
+	// x.exp == y.exp
+
+	// compare mantissas
+	i := len(x.mant)
+	j := len(y.mant)
+	for i > 0 || j > 0 {
+		var xm, ym Word
+		if i > 0 {
+			i--
+			xm = x.mant[i]
+		}
+		if j > 0 {
+			j--
+			ym = y.mant[j]
+		}
+		switch {
+		case xm < ym:
+			return -1
+		case xm > ym:
+			return +1
+		}
+	}
+
+	return 0
+}
+
+// Handling of sign bit as defined by IEEE 754-2008, section 6.3:
+//
+// When neither the inputs nor result are NaN, the sign of a product or
+// quotient is the exclusive OR of the operands’ signs; the sign of a sum,
+// or of a difference x−y regarded as a sum x+(−y), differs from at most
+// one of the addends’ signs; and the sign of the result of conversions,
+// the quantize operation, the roundToIntegral operations, and the
+// roundToIntegralExact (see 5.3.1) is the sign of the first or only operand.
+// These rules shall apply even when operands or results are zero or infinite.
+//
+// When the sum of two operands with opposite signs (or the difference of
+// two operands with like signs) is exactly zero, the sign of that sum (or
+// difference) shall be +0 in all rounding-direction attributes except
+// roundTowardNegative; under that attribute, the sign of an exact zero
+// sum (or difference) shall be −0. However, x+x = x−(−x) retains the same
+// sign as x even when x is zero.
+//
+// See also: https://play.golang.org/p/RtH3UCt5IH
+
+// Add sets z to the rounded sum x+y and returns z. If z's precision is 0,
+// it is changed to the larger of x's or y's precision before the operation.
+// Rounding is performed according to z's precision and rounding mode; and
+// z's accuracy reports the result error relative to the exact (not rounded)
+// result. Add panics with ErrNaN if x and y are infinities with opposite
+// signs. The value of z is undefined in that case.
+//
+// BUG(gri) When rounding ToNegativeInf, the sign of Float values rounded to 0 is incorrect.
+func (z *Float) Add(x, y *Float) *Float {
+	if debugFloat {
+		x.validate()
+		y.validate()
+	}
+
+	if z.prec == 0 {
+		z.prec = umax32(x.prec, y.prec)
+	}
+
+	if x.form == finite && y.form == finite {
+		// x + y (commom case)
+		z.neg = x.neg
+		if x.neg == y.neg {
+			// x + y == x + y
+			// (-x) + (-y) == -(x + y)
+			z.uadd(x, y)
+		} else {
+			// x + (-y) == x - y == -(y - x)
+			// (-x) + y == y - x == -(x - y)
+			if x.ucmp(y) > 0 {
+				z.usub(x, y)
+			} else {
+				z.neg = !z.neg
+				z.usub(y, x)
+			}
+		}
+		return z
+	}
+
+	if x.form == inf && y.form == inf && x.neg != y.neg {
+		// +Inf + -Inf
+		// -Inf + +Inf
+		// value of z is undefined but make sure it's valid
+		z.acc = Exact
+		z.form = zero
+		z.neg = false
+		panic(ErrNaN{"addition of infinities with opposite signs"})
+	}
+
+	if x.form == zero && y.form == zero {
+		// ±0 + ±0
+		z.acc = Exact
+		z.form = zero
+		z.neg = x.neg && y.neg // -0 + -0 == -0
+		return z
+	}
+
+	if x.form == inf || y.form == zero {
+		// ±Inf + y
+		// x + ±0
+		return z.Set(x)
+	}
+
+	// ±0 + y
+	// x + ±Inf
+	return z.Set(y)
+}
+
+// Sub sets z to the rounded difference x-y and returns z.
+// Precision, rounding, and accuracy reporting are as for Add.
+// Sub panics with ErrNaN if x and y are infinities with equal
+// signs. The value of z is undefined in that case.
+func (z *Float) Sub(x, y *Float) *Float {
+	if debugFloat {
+		x.validate()
+		y.validate()
+	}
+
+	if z.prec == 0 {
+		z.prec = umax32(x.prec, y.prec)
+	}
+
+	if x.form == finite && y.form == finite {
+		// x - y (common case)
+		z.neg = x.neg
+		if x.neg != y.neg {
+			// x - (-y) == x + y
+			// (-x) - y == -(x + y)
+			z.uadd(x, y)
+		} else {
+			// x - y == x - y == -(y - x)
+			// (-x) - (-y) == y - x == -(x - y)
+			if x.ucmp(y) > 0 {
+				z.usub(x, y)
+			} else {
+				z.neg = !z.neg
+				z.usub(y, x)
+			}
+		}
+		return z
+	}
+
+	if x.form == inf && y.form == inf && x.neg == y.neg {
+		// +Inf - +Inf
+		// -Inf - -Inf
+		// value of z is undefined but make sure it's valid
+		z.acc = Exact
+		z.form = zero
+		z.neg = false
+		panic(ErrNaN{"subtraction of infinities with equal signs"})
+	}
+
+	if x.form == zero && y.form == zero {
+		// ±0 - ±0
+		z.acc = Exact
+		z.form = zero
+		z.neg = x.neg && !y.neg // -0 - +0 == -0
+		return z
+	}
+
+	if x.form == inf || y.form == zero {
+		// ±Inf - y
+		// x - ±0
+		return z.Set(x)
+	}
+
+	// ±0 - y
+	// x - ±Inf
+	return z.Neg(y)
+}
+
+// Mul sets z to the rounded product x*y and returns z.
+// Precision, rounding, and accuracy reporting are as for Add.
+// Mul panics with ErrNaN if one operand is zero and the other
+// operand an infinity. The value of z is undefined in that case.
+func (z *Float) Mul(x, y *Float) *Float {
+	if debugFloat {
+		x.validate()
+		y.validate()
+	}
+
+	if z.prec == 0 {
+		z.prec = umax32(x.prec, y.prec)
+	}
+
+	z.neg = x.neg != y.neg
+
+	if x.form == finite && y.form == finite {
+		// x * y (common case)
+		z.umul(x, y)
+		return z
+	}
+
+	z.acc = Exact
+	if x.form == zero && y.form == inf || x.form == inf && y.form == zero {
+		// ±0 * ±Inf
+		// ±Inf * ±0
+		// value of z is undefined but make sure it's valid
+		z.form = zero
+		z.neg = false
+		panic(ErrNaN{"multiplication of zero with infinity"})
+	}
+
+	if x.form == inf || y.form == inf {
+		// ±Inf * y
+		// x * ±Inf
+		z.form = inf
+		return z
+	}
+
+	// ±0 * y
+	// x * ±0
+	z.form = zero
+	return z
+}
+
+// Quo sets z to the rounded quotient x/y and returns z.
+// Precision, rounding, and accuracy reporting are as for Add.
+// Quo panics with ErrNaN if both operands are zero or infinities.
+// The value of z is undefined in that case.
+func (z *Float) Quo(x, y *Float) *Float {
+	if debugFloat {
+		x.validate()
+		y.validate()
+	}
+
+	if z.prec == 0 {
+		z.prec = umax32(x.prec, y.prec)
+	}
+
+	z.neg = x.neg != y.neg
+
+	if x.form == finite && y.form == finite {
+		// x / y (common case)
+		z.uquo(x, y)
+		return z
+	}
+
+	z.acc = Exact
+	if x.form == zero && y.form == zero || x.form == inf && y.form == inf {
+		// ±0 / ±0
+		// ±Inf / ±Inf
+		// value of z is undefined but make sure it's valid
+		z.form = zero
+		z.neg = false
+		panic(ErrNaN{"division of zero by zero or infinity by infinity"})
+	}
+
+	if x.form == zero || y.form == inf {
+		// ±0 / y
+		// x / ±Inf
+		z.form = zero
+		return z
+	}
+
+	// x / ±0
+	// ±Inf / y
+	z.form = inf
+	return z
+}
+
+// Cmp compares x and y and returns:
+//
+//   -1 if x <  y
+//    0 if x == y (incl. -0 == 0, -Inf == -Inf, and +Inf == +Inf)
+//   +1 if x >  y
+//
+func (x *Float) Cmp(y *Float) int {
+	if debugFloat {
+		x.validate()
+		y.validate()
+	}
+
+	mx := x.ord()
+	my := y.ord()
+	switch {
+	case mx < my:
+		return -1
+	case mx > my:
+		return +1
+	}
+	// mx == my
+
+	// only if |mx| == 1 we have to compare the mantissae
+	switch mx {
+	case -1:
+		return y.ucmp(x)
+	case +1:
+		return x.ucmp(y)
+	}
+
+	return 0
+}
+
+// ord classifies x and returns:
+//
+//	-2 if -Inf == x
+//	-1 if -Inf < x < 0
+//	 0 if x == 0 (signed or unsigned)
+//	+1 if 0 < x < +Inf
+//	+2 if x == +Inf
+//
+func (x *Float) ord() int {
+	var m int
+	switch x.form {
+	case finite:
+		m = 1
+	case zero:
+		return 0
+	case inf:
+		m = 2
+	}
+	if x.neg {
+		m = -m
+	}
+	return m
+}
+
+func umax32(x, y uint32) uint32 {
+	if x > y {
+		return x
+	}
+	return y
+}
diff --git a/third_party/gofrontend/libgo/go/math/big/float_test.go b/third_party/gofrontend/libgo/go/math/big/float_test.go
new file mode 100644
index 0000000..d3b214b
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/math/big/float_test.go
@@ -0,0 +1,1694 @@
+// 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.
+
+package big
+
+import (
+	"fmt"
+	"math"
+	"strconv"
+	"strings"
+	"testing"
+)
+
+// Verify that ErrNaN implements the error interface.
+var _ error = ErrNaN{}
+
+func (x *Float) uint64() uint64 {
+	u, acc := x.Uint64()
+	if acc != Exact {
+		panic(fmt.Sprintf("%s is not a uint64", x.Text('g', 10)))
+	}
+	return u
+}
+
+func (x *Float) int64() int64 {
+	i, acc := x.Int64()
+	if acc != Exact {
+		panic(fmt.Sprintf("%s is not an int64", x.Text('g', 10)))
+	}
+	return i
+}
+
+func TestFloatZeroValue(t *testing.T) {
+	// zero (uninitialized) value is a ready-to-use 0.0
+	var x Float
+	if s := x.Text('f', 1); s != "0.0" {
+		t.Errorf("zero value = %s; want 0.0", s)
+	}
+
+	// zero value has precision 0
+	if prec := x.Prec(); prec != 0 {
+		t.Errorf("prec = %d; want 0", prec)
+	}
+
+	// zero value can be used in any and all positions of binary operations
+	make := func(x int) *Float {
+		var f Float
+		if x != 0 {
+			f.SetInt64(int64(x))
+		}
+		// x == 0 translates into the zero value
+		return &f
+	}
+	for _, test := range []struct {
+		z, x, y, want int
+		opname        rune
+		op            func(z, x, y *Float) *Float
+	}{
+		{0, 0, 0, 0, '+', (*Float).Add},
+		{0, 1, 2, 3, '+', (*Float).Add},
+		{1, 2, 0, 2, '+', (*Float).Add},
+		{2, 0, 1, 1, '+', (*Float).Add},
+
+		{0, 0, 0, 0, '-', (*Float).Sub},
+		{0, 1, 2, -1, '-', (*Float).Sub},
+		{1, 2, 0, 2, '-', (*Float).Sub},
+		{2, 0, 1, -1, '-', (*Float).Sub},
+
+		{0, 0, 0, 0, '*', (*Float).Mul},
+		{0, 1, 2, 2, '*', (*Float).Mul},
+		{1, 2, 0, 0, '*', (*Float).Mul},
+		{2, 0, 1, 0, '*', (*Float).Mul},
+
+		// {0, 0, 0, 0, '/', (*Float).Quo}, // panics
+		{0, 2, 1, 2, '/', (*Float).Quo},
+		{1, 2, 0, 0, '/', (*Float).Quo}, // = +Inf
+		{2, 0, 1, 0, '/', (*Float).Quo},
+	} {
+		z := make(test.z)
+		test.op(z, make(test.x), make(test.y))
+		got := 0
+		if !z.IsInf() {
+			got = int(z.int64())
+		}
+		if got != test.want {
+			t.Errorf("%d %c %d = %d; want %d", test.x, test.opname, test.y, got, test.want)
+		}
+	}
+
+	// TODO(gri) test how precision is set for zero value results
+}
+
+func makeFloat(s string) *Float {
+	x, _, err := ParseFloat(s, 0, 1000, ToNearestEven)
+	if err != nil {
+		panic(err)
+	}
+	return x
+}
+
+func TestFloatSetPrec(t *testing.T) {
+	for _, test := range []struct {
+		x    string
+		prec uint
+		want string
+		acc  Accuracy
+	}{
+		// prec 0
+		{"0", 0, "0", Exact},
+		{"-0", 0, "-0", Exact},
+		{"-Inf", 0, "-Inf", Exact},
+		{"+Inf", 0, "+Inf", Exact},
+		{"123", 0, "0", Below},
+		{"-123", 0, "-0", Above},
+
+		// prec at upper limit
+		{"0", MaxPrec, "0", Exact},
+		{"-0", MaxPrec, "-0", Exact},
+		{"-Inf", MaxPrec, "-Inf", Exact},
+		{"+Inf", MaxPrec, "+Inf", Exact},
+
+		// just a few regular cases - general rounding is tested elsewhere
+		{"1.5", 1, "2", Above},
+		{"-1.5", 1, "-2", Below},
+		{"123", 1e6, "123", Exact},
+		{"-123", 1e6, "-123", Exact},
+	} {
+		x := makeFloat(test.x).SetPrec(test.prec)
+		prec := test.prec
+		if prec > MaxPrec {
+			prec = MaxPrec
+		}
+		if got := x.Prec(); got != prec {
+			t.Errorf("%s.SetPrec(%d).Prec() == %d; want %d", test.x, test.prec, got, prec)
+		}
+		if got, acc := x.String(), x.Acc(); got != test.want || acc != test.acc {
+			t.Errorf("%s.SetPrec(%d) = %s (%s); want %s (%s)", test.x, test.prec, got, acc, test.want, test.acc)
+		}
+	}
+}
+
+func TestFloatMinPrec(t *testing.T) {
+	const max = 100
+	for _, test := range []struct {
+		x    string
+		want uint
+	}{
+		{"0", 0},
+		{"-0", 0},
+		{"+Inf", 0},
+		{"-Inf", 0},
+		{"1", 1},
+		{"2", 1},
+		{"3", 2},
+		{"0x8001", 16},
+		{"0x8001p-1000", 16},
+		{"0x8001p+1000", 16},
+		{"0.1", max},
+	} {
+		x := makeFloat(test.x).SetPrec(max)
+		if got := x.MinPrec(); got != test.want {
+			t.Errorf("%s.MinPrec() = %d; want %d", test.x, got, test.want)
+		}
+	}
+}
+
+func TestFloatSign(t *testing.T) {
+	for _, test := range []struct {
+		x string
+		s int
+	}{
+		{"-Inf", -1},
+		{"-1", -1},
+		{"-0", 0},
+		{"+0", 0},
+		{"+1", +1},
+		{"+Inf", +1},
+	} {
+		x := makeFloat(test.x)
+		s := x.Sign()
+		if s != test.s {
+			t.Errorf("%s.Sign() = %d; want %d", test.x, s, test.s)
+		}
+	}
+}
+
+// alike(x, y) is like x.Cmp(y) == 0 but also considers the sign of 0 (0 != -0).
+func alike(x, y *Float) bool {
+	return x.Cmp(y) == 0 && x.Signbit() == y.Signbit()
+}
+
+func alike32(x, y float32) bool {
+	// we can ignore NaNs
+	return x == y && math.Signbit(float64(x)) == math.Signbit(float64(y))
+
+}
+
+func alike64(x, y float64) bool {
+	// we can ignore NaNs
+	return x == y && math.Signbit(x) == math.Signbit(y)
+
+}
+
+func TestFloatMantExp(t *testing.T) {
+	for _, test := range []struct {
+		x    string
+		mant string
+		exp  int
+	}{
+		{"0", "0", 0},
+		{"+0", "0", 0},
+		{"-0", "-0", 0},
+		{"Inf", "+Inf", 0},
+		{"+Inf", "+Inf", 0},
+		{"-Inf", "-Inf", 0},
+		{"1.5", "0.75", 1},
+		{"1.024e3", "0.5", 11},
+		{"-0.125", "-0.5", -2},
+	} {
+		x := makeFloat(test.x)
+		mant := makeFloat(test.mant)
+		m := new(Float)
+		e := x.MantExp(m)
+		if !alike(m, mant) || e != test.exp {
+			t.Errorf("%s.MantExp() = %s, %d; want %s, %d", test.x, m.Text('g', 10), e, test.mant, test.exp)
+		}
+	}
+}
+
+func TestFloatMantExpAliasing(t *testing.T) {
+	x := makeFloat("0.5p10")
+	if e := x.MantExp(x); e != 10 {
+		t.Fatalf("Float.MantExp aliasing error: got %d; want 10", e)
+	}
+	if want := makeFloat("0.5"); !alike(x, want) {
+		t.Fatalf("Float.MantExp aliasing error: got %s; want %s", x.Text('g', 10), want.Text('g', 10))
+	}
+}
+
+func TestFloatSetMantExp(t *testing.T) {
+	for _, test := range []struct {
+		frac string
+		exp  int
+		z    string
+	}{
+		{"0", 0, "0"},
+		{"+0", 0, "0"},
+		{"-0", 0, "-0"},
+		{"Inf", 1234, "+Inf"},
+		{"+Inf", -1234, "+Inf"},
+		{"-Inf", -1234, "-Inf"},
+		{"0", MinExp, "0"},
+		{"0.25", MinExp, "+0"},    // exponent underflow
+		{"-0.25", MinExp, "-0"},   // exponent underflow
+		{"1", MaxExp, "+Inf"},     // exponent overflow
+		{"2", MaxExp - 1, "+Inf"}, // exponent overflow
+		{"0.75", 1, "1.5"},
+		{"0.5", 11, "1024"},
+		{"-0.5", -2, "-0.125"},
+		{"32", 5, "1024"},
+		{"1024", -10, "1"},
+	} {
+		frac := makeFloat(test.frac)
+		want := makeFloat(test.z)
+		var z Float
+		z.SetMantExp(frac, test.exp)
+		if !alike(&z, want) {
+			t.Errorf("SetMantExp(%s, %d) = %s; want %s", test.frac, test.exp, z.Text('g', 10), test.z)
+		}
+		// test inverse property
+		mant := new(Float)
+		if z.SetMantExp(mant, want.MantExp(mant)).Cmp(want) != 0 {
+			t.Errorf("Inverse property not satisfied: got %s; want %s", z.Text('g', 10), test.z)
+		}
+	}
+}
+
+func TestFloatPredicates(t *testing.T) {
+	for _, test := range []struct {
+		x            string
+		sign         int
+		signbit, inf bool
+	}{
+		{x: "-Inf", sign: -1, signbit: true, inf: true},
+		{x: "-1", sign: -1, signbit: true},
+		{x: "-0", signbit: true},
+		{x: "0"},
+		{x: "1", sign: 1},
+		{x: "+Inf", sign: 1, inf: true},
+	} {
+		x := makeFloat(test.x)
+		if got := x.Signbit(); got != test.signbit {
+			t.Errorf("(%s).Signbit() = %v; want %v", test.x, got, test.signbit)
+		}
+		if got := x.Sign(); got != test.sign {
+			t.Errorf("(%s).Sign() = %d; want %d", test.x, got, test.sign)
+		}
+		if got := x.IsInf(); got != test.inf {
+			t.Errorf("(%s).IsInf() = %v; want %v", test.x, got, test.inf)
+		}
+	}
+}
+
+func TestFloatIsInt(t *testing.T) {
+	for _, test := range []string{
+		"0 int",
+		"-0 int",
+		"1 int",
+		"-1 int",
+		"0.5",
+		"1.23",
+		"1.23e1",
+		"1.23e2 int",
+		"0.000000001e+8",
+		"0.000000001e+9 int",
+		"1.2345e200 int",
+		"Inf",
+		"+Inf",
+		"-Inf",
+	} {
+		s := strings.TrimSuffix(test, " int")
+		want := s != test
+		if got := makeFloat(s).IsInt(); got != want {
+			t.Errorf("%s.IsInt() == %t", s, got)
+		}
+	}
+}
+
+func fromBinary(s string) int64 {
+	x, err := strconv.ParseInt(s, 2, 64)
+	if err != nil {
+		panic(err)
+	}
+	return x
+}
+
+func toBinary(x int64) string {
+	return strconv.FormatInt(x, 2)
+}
+
+func testFloatRound(t *testing.T, x, r int64, prec uint, mode RoundingMode) {
+	// verify test data
+	var ok bool
+	switch mode {
+	case ToNearestEven, ToNearestAway:
+		ok = true // nothing to do for now
+	case ToZero:
+		if x < 0 {
+			ok = r >= x
+		} else {
+			ok = r <= x
+		}
+	case AwayFromZero:
+		if x < 0 {
+			ok = r <= x
+		} else {
+			ok = r >= x
+		}
+	case ToNegativeInf:
+		ok = r <= x
+	case ToPositiveInf:
+		ok = r >= x
+	default:
+		panic("unreachable")
+	}
+	if !ok {
+		t.Fatalf("incorrect test data for prec = %d, %s: x = %s, r = %s", prec, mode, toBinary(x), toBinary(r))
+	}
+
+	// compute expected accuracy
+	a := Exact
+	switch {
+	case r < x:
+		a = Below
+	case r > x:
+		a = Above
+	}
+
+	// round
+	f := new(Float).SetMode(mode).SetInt64(x).SetPrec(prec)
+
+	// check result
+	r1 := f.int64()
+	p1 := f.Prec()
+	a1 := f.Acc()
+	if r1 != r || p1 != prec || a1 != a {
+		t.Errorf("round %s (%d bits, %s) incorrect: got %s (%d bits, %s); want %s (%d bits, %s)",
+			toBinary(x), prec, mode,
+			toBinary(r1), p1, a1,
+			toBinary(r), prec, a)
+		return
+	}
+
+	// g and f should be the same
+	// (rounding by SetPrec after SetInt64 using default precision
+	// should be the same as rounding by SetInt64 after setting the
+	// precision)
+	g := new(Float).SetMode(mode).SetPrec(prec).SetInt64(x)
+	if !alike(g, f) {
+		t.Errorf("round %s (%d bits, %s) not symmetric: got %s and %s; want %s",
+			toBinary(x), prec, mode,
+			toBinary(g.int64()),
+			toBinary(r1),
+			toBinary(r),
+		)
+		return
+	}
+
+	// h and f should be the same
+	// (repeated rounding should be idempotent)
+	h := new(Float).SetMode(mode).SetPrec(prec).Set(f)
+	if !alike(h, f) {
+		t.Errorf("round %s (%d bits, %s) not idempotent: got %s and %s; want %s",
+			toBinary(x), prec, mode,
+			toBinary(h.int64()),
+			toBinary(r1),
+			toBinary(r),
+		)
+		return
+	}
+}
+
+// TestFloatRound tests basic rounding.
+func TestFloatRound(t *testing.T) {
+	for _, test := range []struct {
+		prec                        uint
+		x, zero, neven, naway, away string // input, results rounded to prec bits
+	}{
+		{5, "1000", "1000", "1000", "1000", "1000"},
+		{5, "1001", "1001", "1001", "1001", "1001"},
+		{5, "1010", "1010", "1010", "1010", "1010"},
+		{5, "1011", "1011", "1011", "1011", "1011"},
+		{5, "1100", "1100", "1100", "1100", "1100"},
+		{5, "1101", "1101", "1101", "1101", "1101"},
+		{5, "1110", "1110", "1110", "1110", "1110"},
+		{5, "1111", "1111", "1111", "1111", "1111"},
+
+		{4, "1000", "1000", "1000", "1000", "1000"},
+		{4, "1001", "1001", "1001", "1001", "1001"},
+		{4, "1010", "1010", "1010", "1010", "1010"},
+		{4, "1011", "1011", "1011", "1011", "1011"},
+		{4, "1100", "1100", "1100", "1100", "1100"},
+		{4, "1101", "1101", "1101", "1101", "1101"},
+		{4, "1110", "1110", "1110", "1110", "1110"},
+		{4, "1111", "1111", "1111", "1111", "1111"},
+
+		{3, "1000", "1000", "1000", "1000", "1000"},
+		{3, "1001", "1000", "1000", "1010", "1010"},
+		{3, "1010", "1010", "1010", "1010", "1010"},
+		{3, "1011", "1010", "1100", "1100", "1100"},
+		{3, "1100", "1100", "1100", "1100", "1100"},
+		{3, "1101", "1100", "1100", "1110", "1110"},
+		{3, "1110", "1110", "1110", "1110", "1110"},
+		{3, "1111", "1110", "10000", "10000", "10000"},
+
+		{3, "1000001", "1000000", "1000000", "1000000", "1010000"},
+		{3, "1001001", "1000000", "1010000", "1010000", "1010000"},
+		{3, "1010001", "1010000", "1010000", "1010000", "1100000"},
+		{3, "1011001", "1010000", "1100000", "1100000", "1100000"},
+		{3, "1100001", "1100000", "1100000", "1100000", "1110000"},
+		{3, "1101001", "1100000", "1110000", "1110000", "1110000"},
+		{3, "1110001", "1110000", "1110000", "1110000", "10000000"},
+		{3, "1111001", "1110000", "10000000", "10000000", "10000000"},
+
+		{2, "1000", "1000", "1000", "1000", "1000"},
+		{2, "1001", "1000", "1000", "1000", "1100"},
+		{2, "1010", "1000", "1000", "1100", "1100"},
+		{2, "1011", "1000", "1100", "1100", "1100"},
+		{2, "1100", "1100", "1100", "1100", "1100"},
+		{2, "1101", "1100", "1100", "1100", "10000"},
+		{2, "1110", "1100", "10000", "10000", "10000"},
+		{2, "1111", "1100", "10000", "10000", "10000"},
+
+		{2, "1000001", "1000000", "1000000", "1000000", "1100000"},
+		{2, "1001001", "1000000", "1000000", "1000000", "1100000"},
+		{2, "1010001", "1000000", "1100000", "1100000", "1100000"},
+		{2, "1011001", "1000000", "1100000", "1100000", "1100000"},
+		{2, "1100001", "1100000", "1100000", "1100000", "10000000"},
+		{2, "1101001", "1100000", "1100000", "1100000", "10000000"},
+		{2, "1110001", "1100000", "10000000", "10000000", "10000000"},
+		{2, "1111001", "1100000", "10000000", "10000000", "10000000"},
+
+		{1, "1000", "1000", "1000", "1000", "1000"},
+		{1, "1001", "1000", "1000", "1000", "10000"},
+		{1, "1010", "1000", "1000", "1000", "10000"},
+		{1, "1011", "1000", "1000", "1000", "10000"},
+		{1, "1100", "1000", "10000", "10000", "10000"},
+		{1, "1101", "1000", "10000", "10000", "10000"},
+		{1, "1110", "1000", "10000", "10000", "10000"},
+		{1, "1111", "1000", "10000", "10000", "10000"},
+
+		{1, "1000001", "1000000", "1000000", "1000000", "10000000"},
+		{1, "1001001", "1000000", "1000000", "1000000", "10000000"},
+		{1, "1010001", "1000000", "1000000", "1000000", "10000000"},
+		{1, "1011001", "1000000", "1000000", "1000000", "10000000"},
+		{1, "1100001", "1000000", "10000000", "10000000", "10000000"},
+		{1, "1101001", "1000000", "10000000", "10000000", "10000000"},
+		{1, "1110001", "1000000", "10000000", "10000000", "10000000"},
+		{1, "1111001", "1000000", "10000000", "10000000", "10000000"},
+	} {
+		x := fromBinary(test.x)
+		z := fromBinary(test.zero)
+		e := fromBinary(test.neven)
+		n := fromBinary(test.naway)
+		a := fromBinary(test.away)
+		prec := test.prec
+
+		testFloatRound(t, x, z, prec, ToZero)
+		testFloatRound(t, x, e, prec, ToNearestEven)
+		testFloatRound(t, x, n, prec, ToNearestAway)
+		testFloatRound(t, x, a, prec, AwayFromZero)
+
+		testFloatRound(t, x, z, prec, ToNegativeInf)
+		testFloatRound(t, x, a, prec, ToPositiveInf)
+
+		testFloatRound(t, -x, -a, prec, ToNegativeInf)
+		testFloatRound(t, -x, -z, prec, ToPositiveInf)
+	}
+}
+
+// TestFloatRound24 tests that rounding a float64 to 24 bits
+// matches IEEE-754 rounding to nearest when converting a
+// float64 to a float32 (excluding denormal numbers).
+func TestFloatRound24(t *testing.T) {
+	const x0 = 1<<26 - 0x10 // 11...110000 (26 bits)
+	for d := 0; d <= 0x10; d++ {
+		x := float64(x0 + d)
+		f := new(Float).SetPrec(24).SetFloat64(x)
+		got, _ := f.Float32()
+		want := float32(x)
+		if got != want {
+			t.Errorf("Round(%g, 24) = %g; want %g", x, got, want)
+		}
+	}
+}
+
+func TestFloatSetUint64(t *testing.T) {
+	for _, want := range []uint64{
+		0,
+		1,
+		2,
+		10,
+		100,
+		1<<32 - 1,
+		1 << 32,
+		1<<64 - 1,
+	} {
+		var f Float
+		f.SetUint64(want)
+		if got := f.uint64(); got != want {
+			t.Errorf("got %#x (%s); want %#x", got, f.Text('p', 0), want)
+		}
+	}
+
+	// test basic rounding behavior (exhaustive rounding testing is done elsewhere)
+	const x uint64 = 0x8765432187654321 // 64 bits needed
+	for prec := uint(1); prec <= 64; prec++ {
+		f := new(Float).SetPrec(prec).SetMode(ToZero).SetUint64(x)
+		got := f.uint64()
+		want := x &^ (1<<(64-prec) - 1) // cut off (round to zero) low 64-prec bits
+		if got != want {
+			t.Errorf("got %#x (%s); want %#x", got, f.Text('p', 0), want)
+		}
+	}
+}
+
+func TestFloatSetInt64(t *testing.T) {
+	for _, want := range []int64{
+		0,
+		1,
+		2,
+		10,
+		100,
+		1<<32 - 1,
+		1 << 32,
+		1<<63 - 1,
+	} {
+		for i := range [2]int{} {
+			if i&1 != 0 {
+				want = -want
+			}
+			var f Float
+			f.SetInt64(want)
+			if got := f.int64(); got != want {
+				t.Errorf("got %#x (%s); want %#x", got, f.Text('p', 0), want)
+			}
+		}
+	}
+
+	// test basic rounding behavior (exhaustive rounding testing is done elsewhere)
+	const x int64 = 0x7654321076543210 // 63 bits needed
+	for prec := uint(1); prec <= 63; prec++ {
+		f := new(Float).SetPrec(prec).SetMode(ToZero).SetInt64(x)
+		got := f.int64()
+		want := x &^ (1<<(63-prec) - 1) // cut off (round to zero) low 63-prec bits
+		if got != want {
+			t.Errorf("got %#x (%s); want %#x", got, f.Text('p', 0), want)
+		}
+	}
+}
+
+func TestFloatSetFloat64(t *testing.T) {
+	for _, want := range []float64{
+		0,
+		1,
+		2,
+		12345,
+		1e10,
+		1e100,
+		3.14159265e10,
+		2.718281828e-123,
+		1.0 / 3,
+		math.MaxFloat32,
+		math.MaxFloat64,
+		math.SmallestNonzeroFloat32,
+		math.SmallestNonzeroFloat64,
+		math.Inf(-1),
+		math.Inf(0),
+		-math.Inf(1),
+	} {
+		for i := range [2]int{} {
+			if i&1 != 0 {
+				want = -want
+			}
+			var f Float
+			f.SetFloat64(want)
+			if got, acc := f.Float64(); got != want || acc != Exact {
+				t.Errorf("got %g (%s, %s); want %g (Exact)", got, f.Text('p', 0), acc, want)
+			}
+		}
+	}
+
+	// test basic rounding behavior (exhaustive rounding testing is done elsewhere)
+	const x uint64 = 0x8765432143218 // 53 bits needed
+	for prec := uint(1); prec <= 52; prec++ {
+		f := new(Float).SetPrec(prec).SetMode(ToZero).SetFloat64(float64(x))
+		got, _ := f.Float64()
+		want := float64(x &^ (1<<(52-prec) - 1)) // cut off (round to zero) low 53-prec bits
+		if got != want {
+			t.Errorf("got %g (%s); want %g", got, f.Text('p', 0), want)
+		}
+	}
+
+	// test NaN
+	defer func() {
+		if p, ok := recover().(ErrNaN); !ok {
+			t.Errorf("got %v; want ErrNaN panic", p)
+		}
+	}()
+	var f Float
+	f.SetFloat64(math.NaN())
+	// should not reach here
+	t.Errorf("got %s; want ErrNaN panic", f.Text('p', 0))
+}
+
+func TestFloatSetInt(t *testing.T) {
+	for _, want := range []string{
+		"0",
+		"1",
+		"-1",
+		"1234567890",
+		"123456789012345678901234567890",
+		"123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890",
+	} {
+		var x Int
+		_, ok := x.SetString(want, 0)
+		if !ok {
+			t.Errorf("invalid integer %s", want)
+			continue
+		}
+		n := x.BitLen()
+
+		var f Float
+		f.SetInt(&x)
+
+		// check precision
+		if n < 64 {
+			n = 64
+		}
+		if prec := f.Prec(); prec != uint(n) {
+			t.Errorf("got prec = %d; want %d", prec, n)
+		}
+
+		// check value
+		got := f.Text('g', 100)
+		if got != want {
+			t.Errorf("got %s (%s); want %s", got, f.Text('p', 0), want)
+		}
+	}
+
+	// TODO(gri) test basic rounding behavior
+}
+
+func TestFloatSetRat(t *testing.T) {
+	for _, want := range []string{
+		"0",
+		"1",
+		"-1",
+		"1234567890",
+		"123456789012345678901234567890",
+		"123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890",
+		"1.2",
+		"3.14159265",
+		// TODO(gri) expand
+	} {
+		var x Rat
+		_, ok := x.SetString(want)
+		if !ok {
+			t.Errorf("invalid fraction %s", want)
+			continue
+		}
+		n := max(x.Num().BitLen(), x.Denom().BitLen())
+
+		var f1, f2 Float
+		f2.SetPrec(1000)
+		f1.SetRat(&x)
+		f2.SetRat(&x)
+
+		// check precision when set automatically
+		if n < 64 {
+			n = 64
+		}
+		if prec := f1.Prec(); prec != uint(n) {
+			t.Errorf("got prec = %d; want %d", prec, n)
+		}
+
+		got := f2.Text('g', 100)
+		if got != want {
+			t.Errorf("got %s (%s); want %s", got, f2.Text('p', 0), want)
+		}
+	}
+}
+
+func TestFloatSetInf(t *testing.T) {
+	var f Float
+	for _, test := range []struct {
+		signbit bool
+		prec    uint
+		want    string
+	}{
+		{false, 0, "+Inf"},
+		{true, 0, "-Inf"},
+		{false, 10, "+Inf"},
+		{true, 30, "-Inf"},
+	} {
+		x := f.SetPrec(test.prec).SetInf(test.signbit)
+		if got := x.String(); got != test.want || x.Prec() != test.prec {
+			t.Errorf("SetInf(%v) = %s (prec = %d); want %s (prec = %d)", test.signbit, got, x.Prec(), test.want, test.prec)
+		}
+	}
+}
+
+func TestFloatUint64(t *testing.T) {
+	for _, test := range []struct {
+		x   string
+		out uint64
+		acc Accuracy
+	}{
+		{"-Inf", 0, Above},
+		{"-1", 0, Above},
+		{"-1e-1000", 0, Above},
+		{"-0", 0, Exact},
+		{"0", 0, Exact},
+		{"1e-1000", 0, Below},
+		{"1", 1, Exact},
+		{"1.000000000000000000001", 1, Below},
+		{"12345.0", 12345, Exact},
+		{"12345.000000000000000000001", 12345, Below},
+		{"18446744073709551615", 18446744073709551615, Exact},
+		{"18446744073709551615.000000000000000000001", math.MaxUint64, Below},
+		{"18446744073709551616", math.MaxUint64, Below},
+		{"1e10000", math.MaxUint64, Below},
+		{"+Inf", math.MaxUint64, Below},
+	} {
+		x := makeFloat(test.x)
+		out, acc := x.Uint64()
+		if out != test.out || acc != test.acc {
+			t.Errorf("%s: got %d (%s); want %d (%s)", test.x, out, acc, test.out, test.acc)
+		}
+	}
+}
+
+func TestFloatInt64(t *testing.T) {
+	for _, test := range []struct {
+		x   string
+		out int64
+		acc Accuracy
+	}{
+		{"-Inf", math.MinInt64, Above},
+		{"-1e10000", math.MinInt64, Above},
+		{"-9223372036854775809", math.MinInt64, Above},
+		{"-9223372036854775808.000000000000000000001", math.MinInt64, Above},
+		{"-9223372036854775808", -9223372036854775808, Exact},
+		{"-9223372036854775807.000000000000000000001", -9223372036854775807, Above},
+		{"-9223372036854775807", -9223372036854775807, Exact},
+		{"-12345.000000000000000000001", -12345, Above},
+		{"-12345.0", -12345, Exact},
+		{"-1.000000000000000000001", -1, Above},
+		{"-1.5", -1, Above},
+		{"-1", -1, Exact},
+		{"-1e-1000", 0, Above},
+		{"0", 0, Exact},
+		{"1e-1000", 0, Below},
+		{"1", 1, Exact},
+		{"1.000000000000000000001", 1, Below},
+		{"1.5", 1, Below},
+		{"12345.0", 12345, Exact},
+		{"12345.000000000000000000001", 12345, Below},
+		{"9223372036854775807", 9223372036854775807, Exact},
+		{"9223372036854775807.000000000000000000001", math.MaxInt64, Below},
+		{"9223372036854775808", math.MaxInt64, Below},
+		{"1e10000", math.MaxInt64, Below},
+		{"+Inf", math.MaxInt64, Below},
+	} {
+		x := makeFloat(test.x)
+		out, acc := x.Int64()
+		if out != test.out || acc != test.acc {
+			t.Errorf("%s: got %d (%s); want %d (%s)", test.x, out, acc, test.out, test.acc)
+		}
+	}
+}
+
+func TestFloatFloat32(t *testing.T) {
+	for _, test := range []struct {
+		x   string
+		out float32
+		acc Accuracy
+	}{
+		{"0", 0, Exact},
+
+		// underflow
+		{"1e-1000", 0, Below},
+		{"0x0.000002p-127", 0, Below},
+		{"0x.0000010p-126", 0, Below},
+
+		// denormals
+		{"1.401298464e-45", math.SmallestNonzeroFloat32, Above}, // rounded up to smallest denormal
+		{"0x.ffffff8p-149", math.SmallestNonzeroFloat32, Above}, // rounded up to smallest denormal
+		{"0x.0000018p-126", math.SmallestNonzeroFloat32, Above}, // rounded up to smallest denormal
+		{"0x.0000020p-126", math.SmallestNonzeroFloat32, Exact},
+		{"0x.8p-148", math.SmallestNonzeroFloat32, Exact},
+		{"1p-149", math.SmallestNonzeroFloat32, Exact},
+		{"0x.fffffep-126", math.Float32frombits(0x7fffff), Exact}, // largest denormal
+
+		// normals
+		{"0x.ffffffp-126", math.Float32frombits(0x00800000), Above}, // rounded up to smallest normal
+		{"1p-126", math.Float32frombits(0x00800000), Exact},         // smallest normal
+		{"0x1.fffffep-126", math.Float32frombits(0x00ffffff), Exact},
+		{"0x1.ffffffp-126", math.Float32frombits(0x01000000), Above}, // rounded up
+		{"1", 1, Exact},
+		{"1.000000000000000000001", 1, Below},
+		{"12345.0", 12345, Exact},
+		{"12345.000000000000000000001", 12345, Below},
+		{"0x1.fffffe0p127", math.MaxFloat32, Exact},
+		{"0x1.fffffe8p127", math.MaxFloat32, Below},
+
+		// overflow
+		{"0x1.ffffff0p127", float32(math.Inf(+1)), Above},
+		{"0x1p128", float32(math.Inf(+1)), Above},
+		{"1e10000", float32(math.Inf(+1)), Above},
+		{"0x1.ffffff0p2147483646", float32(math.Inf(+1)), Above}, // overflow in rounding
+
+		// inf
+		{"Inf", float32(math.Inf(+1)), Exact},
+	} {
+		for i := 0; i < 2; i++ {
+			// test both signs
+			tx, tout, tacc := test.x, test.out, test.acc
+			if i != 0 {
+				tx = "-" + tx
+				tout = -tout
+				tacc = -tacc
+			}
+
+			// conversion should match strconv where syntax is agreeable
+			if f, err := strconv.ParseFloat(tx, 32); err == nil && !alike32(float32(f), tout) {
+				t.Errorf("%s: got %g; want %g (incorrect test data)", tx, f, tout)
+			}
+
+			x := makeFloat(tx)
+			out, acc := x.Float32()
+			if !alike32(out, tout) || acc != tacc {
+				t.Errorf("%s: got %g (%#x, %s); want %g (%#x, %s)", tx, out, math.Float32bits(out), acc, test.out, math.Float32bits(test.out), tacc)
+			}
+
+			// test that x.SetFloat64(float64(f)).Float32() == f
+			var x2 Float
+			out2, acc2 := x2.SetFloat64(float64(out)).Float32()
+			if !alike32(out2, out) || acc2 != Exact {
+				t.Errorf("idempotency test: got %g (%s); want %g (Exact)", out2, acc2, out)
+			}
+		}
+	}
+}
+
+func TestFloatFloat64(t *testing.T) {
+	const smallestNormalFloat64 = 2.2250738585072014e-308 // 1p-1022
+	for _, test := range []struct {
+		x   string
+		out float64
+		acc Accuracy
+	}{
+		{"0", 0, Exact},
+
+		// underflow
+		{"1e-1000", 0, Below},
+		{"0x0.0000000000001p-1023", 0, Below},
+		{"0x0.00000000000008p-1022", 0, Below},
+
+		// denormals
+		{"0x0.0000000000000cp-1022", math.SmallestNonzeroFloat64, Above}, // rounded up to smallest denormal
+		{"0x0.0000000000001p-1022", math.SmallestNonzeroFloat64, Exact},  // smallest denormal
+		{"0x.8p-1073", math.SmallestNonzeroFloat64, Exact},
+		{"1p-1074", math.SmallestNonzeroFloat64, Exact},
+		{"0x.fffffffffffffp-1022", math.Float64frombits(0x000fffffffffffff), Exact}, // largest denormal
+
+		// normals
+		{"0x.fffffffffffff8p-1022", math.Float64frombits(0x0010000000000000), Above}, // rounded up to smallest normal
+		{"1p-1022", math.Float64frombits(0x0010000000000000), Exact},                 // smallest normal
+		{"1", 1, Exact},
+		{"1.000000000000000000001", 1, Below},
+		{"12345.0", 12345, Exact},
+		{"12345.000000000000000000001", 12345, Below},
+		{"0x1.fffffffffffff0p1023", math.MaxFloat64, Exact},
+		{"0x1.fffffffffffff4p1023", math.MaxFloat64, Below},
+
+		// overflow
+		{"0x1.fffffffffffff8p1023", math.Inf(+1), Above},
+		{"0x1p1024", math.Inf(+1), Above},
+		{"1e10000", math.Inf(+1), Above},
+		{"0x1.fffffffffffff8p2147483646", math.Inf(+1), Above}, // overflow in rounding
+		{"Inf", math.Inf(+1), Exact},
+
+		// selected denormalized values that were handled incorrectly in the past
+		{"0x.fffffffffffffp-1022", smallestNormalFloat64 - math.SmallestNonzeroFloat64, Exact},
+		{"4503599627370495p-1074", smallestNormalFloat64 - math.SmallestNonzeroFloat64, Exact},
+
+		// http://www.exploringbinary.com/php-hangs-on-numeric-value-2-2250738585072011e-308/
+		{"2.2250738585072011e-308", 2.225073858507201e-308, Below},
+		// http://www.exploringbinary.com/java-hangs-when-converting-2-2250738585072012e-308/
+		{"2.2250738585072012e-308", 2.2250738585072014e-308, Above},
+	} {
+		for i := 0; i < 2; i++ {
+			// test both signs
+			tx, tout, tacc := test.x, test.out, test.acc
+			if i != 0 {
+				tx = "-" + tx
+				tout = -tout
+				tacc = -tacc
+			}
+
+			// conversion should match strconv where syntax is agreeable
+			if f, err := strconv.ParseFloat(tx, 64); err == nil && !alike64(f, tout) {
+				t.Errorf("%s: got %g; want %g (incorrect test data)", tx, f, tout)
+			}
+
+			x := makeFloat(tx)
+			out, acc := x.Float64()
+			if !alike64(out, tout) || acc != tacc {
+				t.Errorf("%s: got %g (%#x, %s); want %g (%#x, %s)", tx, out, math.Float64bits(out), acc, test.out, math.Float64bits(test.out), tacc)
+			}
+
+			// test that x.SetFloat64(f).Float64() == f
+			var x2 Float
+			out2, acc2 := x2.SetFloat64(out).Float64()
+			if !alike64(out2, out) || acc2 != Exact {
+				t.Errorf("idempotency test: got %g (%s); want %g (Exact)", out2, acc2, out)
+			}
+		}
+	}
+}
+
+func TestFloatInt(t *testing.T) {
+	for _, test := range []struct {
+		x    string
+		want string
+		acc  Accuracy
+	}{
+		{"0", "0", Exact},
+		{"+0", "0", Exact},
+		{"-0", "0", Exact},
+		{"Inf", "nil", Below},
+		{"+Inf", "nil", Below},
+		{"-Inf", "nil", Above},
+		{"1", "1", Exact},
+		{"-1", "-1", Exact},
+		{"1.23", "1", Below},
+		{"-1.23", "-1", Above},
+		{"123e-2", "1", Below},
+		{"123e-3", "0", Below},
+		{"123e-4", "0", Below},
+		{"1e-1000", "0", Below},
+		{"-1e-1000", "0", Above},
+		{"1e+10", "10000000000", Exact},
+		{"1e+100", "10000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", Exact},
+	} {
+		x := makeFloat(test.x)
+		res, acc := x.Int(nil)
+		got := "nil"
+		if res != nil {
+			got = res.String()
+		}
+		if got != test.want || acc != test.acc {
+			t.Errorf("%s: got %s (%s); want %s (%s)", test.x, got, acc, test.want, test.acc)
+		}
+	}
+
+	// check that supplied *Int is used
+	for _, f := range []string{"0", "1", "-1", "1234"} {
+		x := makeFloat(f)
+		i := new(Int)
+		if res, _ := x.Int(i); res != i {
+			t.Errorf("(%s).Int is not using supplied *Int", f)
+		}
+	}
+}
+
+func TestFloatRat(t *testing.T) {
+	for _, test := range []struct {
+		x, want string
+		acc     Accuracy
+	}{
+		{"0", "0/1", Exact},
+		{"+0", "0/1", Exact},
+		{"-0", "0/1", Exact},
+		{"Inf", "nil", Below},
+		{"+Inf", "nil", Below},
+		{"-Inf", "nil", Above},
+		{"1", "1/1", Exact},
+		{"-1", "-1/1", Exact},
+		{"1.25", "5/4", Exact},
+		{"-1.25", "-5/4", Exact},
+		{"1e10", "10000000000/1", Exact},
+		{"1p10", "1024/1", Exact},
+		{"-1p-10", "-1/1024", Exact},
+		{"3.14159265", "7244019449799623199/2305843009213693952", Exact},
+	} {
+		x := makeFloat(test.x).SetPrec(64)
+		res, acc := x.Rat(nil)
+		got := "nil"
+		if res != nil {
+			got = res.String()
+		}
+		if got != test.want {
+			t.Errorf("%s: got %s; want %s", test.x, got, test.want)
+			continue
+		}
+		if acc != test.acc {
+			t.Errorf("%s: got %s; want %s", test.x, acc, test.acc)
+			continue
+		}
+
+		// inverse conversion
+		if res != nil {
+			got := new(Float).SetPrec(64).SetRat(res)
+			if got.Cmp(x) != 0 {
+				t.Errorf("%s: got %s; want %s", test.x, got, x)
+			}
+		}
+	}
+
+	// check that supplied *Rat is used
+	for _, f := range []string{"0", "1", "-1", "1234"} {
+		x := makeFloat(f)
+		r := new(Rat)
+		if res, _ := x.Rat(r); res != r {
+			t.Errorf("(%s).Rat is not using supplied *Rat", f)
+		}
+	}
+}
+
+func TestFloatAbs(t *testing.T) {
+	for _, test := range []string{
+		"0",
+		"1",
+		"1234",
+		"1.23e-2",
+		"1e-1000",
+		"1e1000",
+		"Inf",
+	} {
+		p := makeFloat(test)
+		a := new(Float).Abs(p)
+		if !alike(a, p) {
+			t.Errorf("%s: got %s; want %s", test, a.Text('g', 10), test)
+		}
+
+		n := makeFloat("-" + test)
+		a.Abs(n)
+		if !alike(a, p) {
+			t.Errorf("-%s: got %s; want %s", test, a.Text('g', 10), test)
+		}
+	}
+}
+
+func TestFloatNeg(t *testing.T) {
+	for _, test := range []string{
+		"0",
+		"1",
+		"1234",
+		"1.23e-2",
+		"1e-1000",
+		"1e1000",
+		"Inf",
+	} {
+		p1 := makeFloat(test)
+		n1 := makeFloat("-" + test)
+		n2 := new(Float).Neg(p1)
+		p2 := new(Float).Neg(n2)
+		if !alike(n2, n1) {
+			t.Errorf("%s: got %s; want %s", test, n2.Text('g', 10), n1.Text('g', 10))
+		}
+		if !alike(p2, p1) {
+			t.Errorf("%s: got %s; want %s", test, p2.Text('g', 10), p1.Text('g', 10))
+		}
+	}
+}
+
+func TestFloatInc(t *testing.T) {
+	const n = 10
+	for _, prec := range precList {
+		if 1<<prec < n {
+			continue // prec must be large enough to hold all numbers from 0 to n
+		}
+		var x, one Float
+		x.SetPrec(prec)
+		one.SetInt64(1)
+		for i := 0; i < n; i++ {
+			x.Add(&x, &one)
+		}
+		if x.Cmp(new(Float).SetInt64(n)) != 0 {
+			t.Errorf("prec = %d: got %s; want %d", prec, &x, n)
+		}
+	}
+}
+
+// Selected precisions with which to run various tests.
+var precList = [...]uint{1, 2, 5, 8, 10, 16, 23, 24, 32, 50, 53, 64, 100, 128, 500, 511, 512, 513, 1000, 10000}
+
+// Selected bits with which to run various tests.
+// Each entry is a list of bits representing a floating-point number (see fromBits).
+var bitsList = [...]Bits{
+	{},           // = 0
+	{0},          // = 1
+	{1},          // = 2
+	{-1},         // = 1/2
+	{10},         // = 2**10 == 1024
+	{-10},        // = 2**-10 == 1/1024
+	{100, 10, 1}, // = 2**100 + 2**10 + 2**1
+	{0, -1, -2, -10},
+	// TODO(gri) add more test cases
+}
+
+// TestFloatAdd tests Float.Add/Sub by comparing the result of a "manual"
+// addition/subtraction of arguments represented by Bits values with the
+// respective Float addition/subtraction for a variety of precisions
+// and rounding modes.
+func TestFloatAdd(t *testing.T) {
+	for _, xbits := range bitsList {
+		for _, ybits := range bitsList {
+			// exact values
+			x := xbits.Float()
+			y := ybits.Float()
+			zbits := xbits.add(ybits)
+			z := zbits.Float()
+
+			for i, mode := range [...]RoundingMode{ToZero, ToNearestEven, AwayFromZero} {
+				for _, prec := range precList {
+					got := new(Float).SetPrec(prec).SetMode(mode)
+					got.Add(x, y)
+					want := zbits.round(prec, mode)
+					if got.Cmp(want) != 0 {
+						t.Errorf("i = %d, prec = %d, %s:\n\t     %s %v\n\t+    %s %v\n\t=    %s\n\twant %s",
+							i, prec, mode, x, xbits, y, ybits, got, want)
+					}
+
+					got.Sub(z, x)
+					want = ybits.round(prec, mode)
+					if got.Cmp(want) != 0 {
+						t.Errorf("i = %d, prec = %d, %s:\n\t     %s %v\n\t-    %s %v\n\t=    %s\n\twant %s",
+							i, prec, mode, z, zbits, x, xbits, got, want)
+					}
+				}
+			}
+		}
+	}
+}
+
+// TestFloatAdd32 tests that Float.Add/Sub of numbers with
+// 24bit mantissa behaves like float32 addition/subtraction
+// (excluding denormal numbers).
+func TestFloatAdd32(t *testing.T) {
+	// chose base such that we cross the mantissa precision limit
+	const base = 1<<26 - 0x10 // 11...110000 (26 bits)
+	for d := 0; d <= 0x10; d++ {
+		for i := range [2]int{} {
+			x0, y0 := float64(base), float64(d)
+			if i&1 != 0 {
+				x0, y0 = y0, x0
+			}
+
+			x := NewFloat(x0)
+			y := NewFloat(y0)
+			z := new(Float).SetPrec(24)
+
+			z.Add(x, y)
+			got, acc := z.Float32()
+			want := float32(y0) + float32(x0)
+			if got != want || acc != Exact {
+				t.Errorf("d = %d: %g + %g = %g (%s); want %g (Exact)", d, x0, y0, got, acc, want)
+			}
+
+			z.Sub(z, y)
+			got, acc = z.Float32()
+			want = float32(want) - float32(y0)
+			if got != want || acc != Exact {
+				t.Errorf("d = %d: %g - %g = %g (%s); want %g (Exact)", d, x0+y0, y0, got, acc, want)
+			}
+		}
+	}
+}
+
+// TestFloatAdd64 tests that Float.Add/Sub of numbers with
+// 53bit mantissa behaves like float64 addition/subtraction.
+func TestFloatAdd64(t *testing.T) {
+	// chose base such that we cross the mantissa precision limit
+	const base = 1<<55 - 0x10 // 11...110000 (55 bits)
+	for d := 0; d <= 0x10; d++ {
+		for i := range [2]int{} {
+			x0, y0 := float64(base), float64(d)
+			if i&1 != 0 {
+				x0, y0 = y0, x0
+			}
+
+			x := NewFloat(x0)
+			y := NewFloat(y0)
+			z := new(Float).SetPrec(53)
+
+			z.Add(x, y)
+			got, acc := z.Float64()
+			want := x0 + y0
+			if got != want || acc != Exact {
+				t.Errorf("d = %d: %g + %g = %g (%s); want %g (Exact)", d, x0, y0, got, acc, want)
+			}
+
+			z.Sub(z, y)
+			got, acc = z.Float64()
+			want -= y0
+			if got != want || acc != Exact {
+				t.Errorf("d = %d: %g - %g = %g (%s); want %g (Exact)", d, x0+y0, y0, got, acc, want)
+			}
+		}
+	}
+}
+
+// TestFloatMul tests Float.Mul/Quo by comparing the result of a "manual"
+// multiplication/division of arguments represented by Bits values with the
+// respective Float multiplication/division for a variety of precisions
+// and rounding modes.
+func TestFloatMul(t *testing.T) {
+	for _, xbits := range bitsList {
+		for _, ybits := range bitsList {
+			// exact values
+			x := xbits.Float()
+			y := ybits.Float()
+			zbits := xbits.mul(ybits)
+			z := zbits.Float()
+
+			for i, mode := range [...]RoundingMode{ToZero, ToNearestEven, AwayFromZero} {
+				for _, prec := range precList {
+					got := new(Float).SetPrec(prec).SetMode(mode)
+					got.Mul(x, y)
+					want := zbits.round(prec, mode)
+					if got.Cmp(want) != 0 {
+						t.Errorf("i = %d, prec = %d, %s:\n\t     %s %v\n\t*    %s %v\n\t=    %s\n\twant %s",
+							i, prec, mode, x, xbits, y, ybits, got, want)
+					}
+
+					if x.Sign() == 0 {
+						continue // ignore div-0 case (not invertable)
+					}
+					got.Quo(z, x)
+					want = ybits.round(prec, mode)
+					if got.Cmp(want) != 0 {
+						t.Errorf("i = %d, prec = %d, %s:\n\t     %s %v\n\t/    %s %v\n\t=    %s\n\twant %s",
+							i, prec, mode, z, zbits, x, xbits, got, want)
+					}
+				}
+			}
+		}
+	}
+}
+
+// TestFloatMul64 tests that Float.Mul/Quo of numbers with
+// 53bit mantissa behaves like float64 multiplication/division.
+func TestFloatMul64(t *testing.T) {
+	for _, test := range []struct {
+		x, y float64
+	}{
+		{0, 0},
+		{0, 1},
+		{1, 1},
+		{1, 1.5},
+		{1.234, 0.5678},
+		{2.718281828, 3.14159265358979},
+		{2.718281828e10, 3.14159265358979e-32},
+		{1.0 / 3, 1e200},
+	} {
+		for i := range [8]int{} {
+			x0, y0 := test.x, test.y
+			if i&1 != 0 {
+				x0 = -x0
+			}
+			if i&2 != 0 {
+				y0 = -y0
+			}
+			if i&4 != 0 {
+				x0, y0 = y0, x0
+			}
+
+			x := NewFloat(x0)
+			y := NewFloat(y0)
+			z := new(Float).SetPrec(53)
+
+			z.Mul(x, y)
+			got, _ := z.Float64()
+			want := x0 * y0
+			if got != want {
+				t.Errorf("%g * %g = %g; want %g", x0, y0, got, want)
+			}
+
+			if y0 == 0 {
+				continue // avoid division-by-zero
+			}
+			z.Quo(z, y)
+			got, _ = z.Float64()
+			want /= y0
+			if got != want {
+				t.Errorf("%g / %g = %g; want %g", x0*y0, y0, got, want)
+			}
+		}
+	}
+}
+
+func TestIssue6866(t *testing.T) {
+	for _, prec := range precList {
+		two := new(Float).SetPrec(prec).SetInt64(2)
+		one := new(Float).SetPrec(prec).SetInt64(1)
+		three := new(Float).SetPrec(prec).SetInt64(3)
+		msix := new(Float).SetPrec(prec).SetInt64(-6)
+		psix := new(Float).SetPrec(prec).SetInt64(+6)
+
+		p := new(Float).SetPrec(prec)
+		z1 := new(Float).SetPrec(prec)
+		z2 := new(Float).SetPrec(prec)
+
+		// z1 = 2 + 1.0/3*-6
+		p.Quo(one, three)
+		p.Mul(p, msix)
+		z1.Add(two, p)
+
+		// z2 = 2 - 1.0/3*+6
+		p.Quo(one, three)
+		p.Mul(p, psix)
+		z2.Sub(two, p)
+
+		if z1.Cmp(z2) != 0 {
+			t.Fatalf("prec %d: got z1 = %s != z2 = %s; want z1 == z2\n", prec, z1, z2)
+		}
+		if z1.Sign() != 0 {
+			t.Errorf("prec %d: got z1 = %s; want 0", prec, z1)
+		}
+		if z2.Sign() != 0 {
+			t.Errorf("prec %d: got z2 = %s; want 0", prec, z2)
+		}
+	}
+}
+
+func TestFloatQuo(t *testing.T) {
+	// TODO(gri) make the test vary these precisions
+	preci := 200 // precision of integer part
+	precf := 20  // precision of fractional part
+
+	for i := 0; i < 8; i++ {
+		// compute accurate (not rounded) result z
+		bits := Bits{preci - 1}
+		if i&3 != 0 {
+			bits = append(bits, 0)
+		}
+		if i&2 != 0 {
+			bits = append(bits, -1)
+		}
+		if i&1 != 0 {
+			bits = append(bits, -precf)
+		}
+		z := bits.Float()
+
+		// compute accurate x as z*y
+		y := NewFloat(3.14159265358979323e123)
+
+		x := new(Float).SetPrec(z.Prec() + y.Prec()).SetMode(ToZero)
+		x.Mul(z, y)
+
+		// leave for debugging
+		// fmt.Printf("x = %s\ny = %s\nz = %s\n", x, y, z)
+
+		if got := x.Acc(); got != Exact {
+			t.Errorf("got acc = %s; want exact", got)
+		}
+
+		// round accurate z for a variety of precisions and
+		// modes and compare against result of x / y.
+		for _, mode := range [...]RoundingMode{ToZero, ToNearestEven, AwayFromZero} {
+			for d := -5; d < 5; d++ {
+				prec := uint(preci + d)
+				got := new(Float).SetPrec(prec).SetMode(mode).Quo(x, y)
+				want := bits.round(prec, mode)
+				if got.Cmp(want) != 0 {
+					t.Errorf("i = %d, prec = %d, %s:\n\t     %s\n\t/    %s\n\t=    %s\n\twant %s",
+						i, prec, mode, x, y, got, want)
+				}
+			}
+		}
+	}
+}
+
+// TestFloatQuoSmoke tests all divisions x/y for values x, y in the range [-n, +n];
+// it serves as a smoke test for basic correctness of division.
+func TestFloatQuoSmoke(t *testing.T) {
+	n := 1000
+	if testing.Short() {
+		n = 10
+	}
+
+	const dprec = 3         // max. precision variation
+	const prec = 10 + dprec // enough bits to hold n precisely
+	for x := -n; x <= n; x++ {
+		for y := -n; y < n; y++ {
+			if y == 0 {
+				continue
+			}
+
+			a := float64(x)
+			b := float64(y)
+			c := a / b
+
+			// vary operand precision (only ok as long as a, b can be represented correctly)
+			for ad := -dprec; ad <= dprec; ad++ {
+				for bd := -dprec; bd <= dprec; bd++ {
+					A := new(Float).SetPrec(uint(prec + ad)).SetFloat64(a)
+					B := new(Float).SetPrec(uint(prec + bd)).SetFloat64(b)
+					C := new(Float).SetPrec(53).Quo(A, B) // C has float64 mantissa width
+
+					cc, acc := C.Float64()
+					if cc != c {
+						t.Errorf("%g/%g = %s; want %.5g\n", a, b, C.Text('g', 5), c)
+						continue
+					}
+					if acc != Exact {
+						t.Errorf("%g/%g got %s result; want exact result", a, b, acc)
+					}
+				}
+			}
+		}
+	}
+}
+
+// TestFloatArithmeticSpecialValues tests that Float operations produce the
+// correct results for combinations of zero (±0), finite (±1 and ±2.71828),
+// and infinite (±Inf) operands.
+func TestFloatArithmeticSpecialValues(t *testing.T) {
+	zero := 0.0
+	args := []float64{math.Inf(-1), -2.71828, -1, -zero, zero, 1, 2.71828, math.Inf(1)}
+	xx := new(Float)
+	yy := new(Float)
+	got := new(Float)
+	want := new(Float)
+	for i := 0; i < 4; i++ {
+		for _, x := range args {
+			xx.SetFloat64(x)
+			// check conversion is correct
+			// (no need to do this for y, since we see exactly the
+			// same values there)
+			if got, acc := xx.Float64(); got != x || acc != Exact {
+				t.Errorf("Float(%g) == %g (%s)", x, got, acc)
+			}
+			for _, y := range args {
+				yy.SetFloat64(y)
+				var (
+					op string
+					z  float64
+					f  func(z, x, y *Float) *Float
+				)
+				switch i {
+				case 0:
+					op = "+"
+					z = x + y
+					f = (*Float).Add
+				case 1:
+					op = "-"
+					z = x - y
+					f = (*Float).Sub
+				case 2:
+					op = "*"
+					z = x * y
+					f = (*Float).Mul
+				case 3:
+					op = "/"
+					z = x / y
+					f = (*Float).Quo
+				default:
+					panic("unreachable")
+				}
+				var errnan bool // set if execution of f panicked with ErrNaN
+				// protect execution of f
+				func() {
+					defer func() {
+						if p := recover(); p != nil {
+							_ = p.(ErrNaN) // re-panic if not ErrNaN
+							errnan = true
+						}
+					}()
+					f(got, xx, yy)
+				}()
+				if math.IsNaN(z) {
+					if !errnan {
+						t.Errorf("%5g %s %5g = %5s; want ErrNaN panic", x, op, y, got)
+					}
+					continue
+				}
+				if errnan {
+					t.Errorf("%5g %s %5g panicked with ErrNan; want %5s", x, op, y, want)
+					continue
+				}
+				want.SetFloat64(z)
+				if !alike(got, want) {
+					t.Errorf("%5g %s %5g = %5s; want %5s", x, op, y, got, want)
+				}
+			}
+		}
+	}
+}
+
+func TestFloatArithmeticOverflow(t *testing.T) {
+	for _, test := range []struct {
+		prec       uint
+		mode       RoundingMode
+		op         byte
+		x, y, want string
+		acc        Accuracy
+	}{
+		{4, ToNearestEven, '+', "0", "0", "0", Exact},                   // smoke test
+		{4, ToNearestEven, '+', "0x.8p+0", "0x.8p+0", "0x.8p+1", Exact}, // smoke test
+
+		{4, ToNearestEven, '+', "0", "0x.8p2147483647", "0x.8p+2147483647", Exact},
+		{4, ToNearestEven, '+', "0x.8p2147483500", "0x.8p2147483647", "0x.8p+2147483647", Below}, // rounded to zero
+		{4, ToNearestEven, '+', "0x.8p2147483647", "0x.8p2147483647", "+Inf", Above},             // exponent overflow in +
+		{4, ToNearestEven, '+', "-0x.8p2147483647", "-0x.8p2147483647", "-Inf", Below},           // exponent overflow in +
+		{4, ToNearestEven, '-', "-0x.8p2147483647", "0x.8p2147483647", "-Inf", Below},            // exponent overflow in -
+
+		{4, ToZero, '+', "0x.fp2147483647", "0x.8p2147483643", "0x.fp+2147483647", Below}, // rounded to zero
+		{4, ToNearestEven, '+', "0x.fp2147483647", "0x.8p2147483643", "+Inf", Above},      // exponent overflow in rounding
+		{4, AwayFromZero, '+', "0x.fp2147483647", "0x.8p2147483643", "+Inf", Above},       // exponent overflow in rounding
+
+		{4, AwayFromZero, '-', "-0x.fp2147483647", "0x.8p2147483644", "-Inf", Below},        // exponent overflow in rounding
+		{4, ToNearestEven, '-', "-0x.fp2147483647", "0x.8p2147483643", "-Inf", Below},       // exponent overflow in rounding
+		{4, ToZero, '-', "-0x.fp2147483647", "0x.8p2147483643", "-0x.fp+2147483647", Above}, // rounded to zero
+
+		{4, ToNearestEven, '+', "0", "0x.8p-2147483648", "0x.8p-2147483648", Exact},
+		{4, ToNearestEven, '+', "0x.8p-2147483648", "0x.8p-2147483648", "0x.8p-2147483647", Exact},
+
+		{4, ToNearestEven, '*', "1", "0x.8p2147483647", "0x.8p+2147483647", Exact},
+		{4, ToNearestEven, '*', "2", "0x.8p2147483647", "+Inf", Above},  // exponent overflow in *
+		{4, ToNearestEven, '*', "-2", "0x.8p2147483647", "-Inf", Below}, // exponent overflow in *
+
+		{4, ToNearestEven, '/', "0.5", "0x.8p2147483647", "0x.8p-2147483646", Exact},
+		{4, ToNearestEven, '/', "0x.8p+0", "0x.8p2147483647", "0x.8p-2147483646", Exact},
+		{4, ToNearestEven, '/', "0x.8p-1", "0x.8p2147483647", "0x.8p-2147483647", Exact},
+		{4, ToNearestEven, '/', "0x.8p-2", "0x.8p2147483647", "0x.8p-2147483648", Exact},
+		{4, ToNearestEven, '/', "0x.8p-3", "0x.8p2147483647", "0", Below}, // exponent underflow in /
+	} {
+		x := makeFloat(test.x)
+		y := makeFloat(test.y)
+		z := new(Float).SetPrec(test.prec).SetMode(test.mode)
+		switch test.op {
+		case '+':
+			z.Add(x, y)
+		case '-':
+			z.Sub(x, y)
+		case '*':
+			z.Mul(x, y)
+		case '/':
+			z.Quo(x, y)
+		default:
+			panic("unreachable")
+		}
+		if got := z.Text('p', 0); got != test.want || z.Acc() != test.acc {
+			t.Errorf(
+				"prec = %d (%s): %s %c %s = %s (%s); want %s (%s)",
+				test.prec, test.mode, x.Text('p', 0), test.op, y.Text('p', 0), got, z.Acc(), test.want, test.acc,
+			)
+		}
+	}
+}
+
+// TODO(gri) Add tests that check correctness in the presence of aliasing.
+
+// For rounding modes ToNegativeInf and ToPositiveInf, rounding is affected
+// by the sign of the value to be rounded. Test that rounding happens after
+// the sign of a result has been set.
+// This test uses specific values that are known to fail if rounding is
+// "factored" out before setting the result sign.
+func TestFloatArithmeticRounding(t *testing.T) {
+	for _, test := range []struct {
+		mode       RoundingMode
+		prec       uint
+		x, y, want int64
+		op         byte
+	}{
+		{ToZero, 3, -0x8, -0x1, -0x8, '+'},
+		{AwayFromZero, 3, -0x8, -0x1, -0xa, '+'},
+		{ToNegativeInf, 3, -0x8, -0x1, -0xa, '+'},
+
+		{ToZero, 3, -0x8, 0x1, -0x8, '-'},
+		{AwayFromZero, 3, -0x8, 0x1, -0xa, '-'},
+		{ToNegativeInf, 3, -0x8, 0x1, -0xa, '-'},
+
+		{ToZero, 3, -0x9, 0x1, -0x8, '*'},
+		{AwayFromZero, 3, -0x9, 0x1, -0xa, '*'},
+		{ToNegativeInf, 3, -0x9, 0x1, -0xa, '*'},
+
+		{ToZero, 3, -0x9, 0x1, -0x8, '/'},
+		{AwayFromZero, 3, -0x9, 0x1, -0xa, '/'},
+		{ToNegativeInf, 3, -0x9, 0x1, -0xa, '/'},
+	} {
+		var x, y, z Float
+		x.SetInt64(test.x)
+		y.SetInt64(test.y)
+		z.SetPrec(test.prec).SetMode(test.mode)
+		switch test.op {
+		case '+':
+			z.Add(&x, &y)
+		case '-':
+			z.Sub(&x, &y)
+		case '*':
+			z.Mul(&x, &y)
+		case '/':
+			z.Quo(&x, &y)
+		default:
+			panic("unreachable")
+		}
+		if got, acc := z.Int64(); got != test.want || acc != Exact {
+			t.Errorf("%s, %d bits: %d %c %d = %d (%s); want %d (Exact)",
+				test.mode, test.prec, test.x, test.op, test.y, got, acc, test.want,
+			)
+		}
+	}
+}
+
+// TestFloatCmpSpecialValues tests that Cmp produces the correct results for
+// combinations of zero (±0), finite (±1 and ±2.71828), and infinite (±Inf)
+// operands.
+func TestFloatCmpSpecialValues(t *testing.T) {
+	zero := 0.0
+	args := []float64{math.Inf(-1), -2.71828, -1, -zero, zero, 1, 2.71828, math.Inf(1)}
+	xx := new(Float)
+	yy := new(Float)
+	for i := 0; i < 4; i++ {
+		for _, x := range args {
+			xx.SetFloat64(x)
+			// check conversion is correct
+			// (no need to do this for y, since we see exactly the
+			// same values there)
+			if got, acc := xx.Float64(); got != x || acc != Exact {
+				t.Errorf("Float(%g) == %g (%s)", x, got, acc)
+			}
+			for _, y := range args {
+				yy.SetFloat64(y)
+				got := xx.Cmp(yy)
+				want := 0
+				switch {
+				case x < y:
+					want = -1
+				case x > y:
+					want = +1
+				}
+				if got != want {
+					t.Errorf("(%g).Cmp(%g) = %v; want %v", x, y, got, want)
+				}
+			}
+		}
+	}
+}
diff --git a/third_party/gofrontend/libgo/go/math/big/floatconv.go b/third_party/gofrontend/libgo/go/math/big/floatconv.go
new file mode 100644
index 0000000..4a070ca
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/math/big/floatconv.go
@@ -0,0 +1,239 @@
+// 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.
+
+// This file implements string-to-Float conversion functions.
+
+package big
+
+import (
+	"fmt"
+	"io"
+	"strings"
+)
+
+// SetString sets z to the value of s and returns z and a boolean indicating
+// success. s must be a floating-point number of the same format as accepted
+// by Parse, with base argument 0.
+func (z *Float) SetString(s string) (*Float, bool) {
+	if f, _, err := z.Parse(s, 0); err == nil {
+		return f, true
+	}
+	return nil, false
+}
+
+// scan is like Parse but reads the longest possible prefix representing a valid
+// floating point number from an io.ByteScanner rather than a string. It serves
+// as the implementation of Parse. It does not recognize ±Inf and does not expect
+// EOF at the end.
+func (z *Float) scan(r io.ByteScanner, base int) (f *Float, b int, err error) {
+	prec := z.prec
+	if prec == 0 {
+		prec = 64
+	}
+
+	// A reasonable value in case of an error.
+	z.form = zero
+
+	// sign
+	z.neg, err = scanSign(r)
+	if err != nil {
+		return
+	}
+
+	// mantissa
+	var fcount int // fractional digit count; valid if <= 0
+	z.mant, b, fcount, err = z.mant.scan(r, base, true)
+	if err != nil {
+		return
+	}
+
+	// exponent
+	var exp int64
+	var ebase int
+	exp, ebase, err = scanExponent(r, true)
+	if err != nil {
+		return
+	}
+
+	// special-case 0
+	if len(z.mant) == 0 {
+		z.prec = prec
+		z.acc = Exact
+		z.form = zero
+		f = z
+		return
+	}
+	// len(z.mant) > 0
+
+	// The mantissa may have a decimal point (fcount <= 0) and there
+	// may be a nonzero exponent exp. The decimal point amounts to a
+	// division by b**(-fcount). An exponent means multiplication by
+	// ebase**exp. Finally, mantissa normalization (shift left) requires
+	// a correcting multiplication by 2**(-shiftcount). Multiplications
+	// are commutative, so we can apply them in any order as long as there
+	// is no loss of precision. We only have powers of 2 and 10; keep
+	// track via separate exponents exp2 and exp10.
+
+	// normalize mantissa and get initial binary exponent
+	var exp2 = int64(len(z.mant))*_W - fnorm(z.mant)
+
+	// determine binary or decimal exponent contribution of decimal point
+	var exp10 int64
+	if fcount < 0 {
+		// The mantissa has a "decimal" point ddd.dddd; and
+		// -fcount is the number of digits to the right of '.'.
+		// Adjust relevant exponent accodingly.
+		switch b {
+		case 16:
+			fcount *= 4 // hexadecimal digits are 4 bits each
+			fallthrough
+		case 2:
+			exp2 += int64(fcount)
+		default: // b == 10
+			exp10 = int64(fcount)
+		}
+		// we don't need fcount anymore
+	}
+
+	// take actual exponent into account
+	if ebase == 2 {
+		exp2 += exp
+	} else { // ebase == 10
+		exp10 += exp
+	}
+	// we don't need exp anymore
+
+	// apply 2**exp2
+	if MinExp <= exp2 && exp2 <= MaxExp {
+		z.prec = prec
+		z.form = finite
+		z.exp = int32(exp2)
+		f = z
+	} else {
+		err = fmt.Errorf("exponent overflow")
+		return
+	}
+
+	if exp10 == 0 {
+		// no decimal exponent to consider
+		z.round(0)
+		return
+	}
+	// exp10 != 0
+
+	// apply 10**exp10
+	p := new(Float).SetPrec(z.Prec() + 64) // use more bits for p -- TODO(gri) what is the right number?
+	if exp10 < 0 {
+		z.uquo(z, p.pow10(-exp10))
+	} else {
+		z.umul(z, p.pow10(exp10))
+	}
+
+	return
+}
+
+// These powers of 10 can be represented exactly as a float64.
+var pow10tab = [...]float64{
+	1e0, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9,
+	1e10, 1e11, 1e12, 1e13, 1e14, 1e15, 1e16, 1e17, 1e18, 1e19,
+}
+
+// pow10 sets z to 10**n and returns z.
+// n must not be negative.
+func (z *Float) pow10(n int64) *Float {
+	if n < 0 {
+		panic("pow10 called with negative argument")
+	}
+
+	const m = int64(len(pow10tab) - 1)
+	if n <= m {
+		return z.SetFloat64(pow10tab[n])
+	}
+	// n > m
+
+	z.SetFloat64(pow10tab[m])
+	n -= m
+
+	// use more bits for f than for z
+	// TODO(gri) what is the right number?
+	f := new(Float).SetPrec(z.Prec() + 64).SetInt64(10)
+
+	for n > 0 {
+		if n&1 != 0 {
+			z.Mul(z, f)
+		}
+		f.Mul(f, f)
+		n >>= 1
+	}
+
+	return z
+}
+
+// Parse parses s which must contain a text representation of a floating-
+// point number with a mantissa in the given conversion base (the exponent
+// is always a decimal number), or a string representing an infinite value.
+//
+// It sets z to the (possibly rounded) value of the corresponding floating-
+// point value, and returns z, the actual base b, and an error err, if any.
+// If z's precision is 0, it is changed to 64 before rounding takes effect.
+// The number must be of the form:
+//
+//	number   = [ sign ] [ prefix ] mantissa [ exponent ] | infinity .
+//	sign     = "+" | "-" .
+//      prefix   = "0" ( "x" | "X" | "b" | "B" ) .
+//	mantissa = digits | digits "." [ digits ] | "." digits .
+//	exponent = ( "E" | "e" | "p" ) [ sign ] digits .
+//	digits   = digit { digit } .
+//	digit    = "0" ... "9" | "a" ... "z" | "A" ... "Z" .
+//      infinity = [ sign ] ( "inf" | "Inf" ) .
+//
+// The base argument must be 0, 2, 10, or 16. Providing an invalid base
+// argument will lead to a run-time panic.
+//
+// For base 0, the number prefix determines the actual base: A prefix of
+// "0x" or "0X" selects base 16, and a "0b" or "0B" prefix selects
+// base 2; otherwise, the actual base is 10 and no prefix is accepted.
+// The octal prefix "0" is not supported (a leading "0" is simply
+// considered a "0").
+//
+// A "p" exponent indicates a binary (rather then decimal) exponent;
+// for instance "0x1.fffffffffffffp1023" (using base 0) represents the
+// maximum float64 value. For hexadecimal mantissae, the exponent must
+// be binary, if present (an "e" or "E" exponent indicator cannot be
+// distinguished from a mantissa digit).
+//
+// The returned *Float f is nil and the value of z is valid but not
+// defined if an error is reported.
+//
+func (z *Float) Parse(s string, base int) (f *Float, b int, err error) {
+	// scan doesn't handle ±Inf
+	if len(s) == 3 && (s == "Inf" || s == "inf") {
+		f = z.SetInf(false)
+		return
+	}
+	if len(s) == 4 && (s[0] == '+' || s[0] == '-') && (s[1:] == "Inf" || s[1:] == "inf") {
+		f = z.SetInf(s[0] == '-')
+		return
+	}
+
+	r := strings.NewReader(s)
+	if f, b, err = z.scan(r, base); err != nil {
+		return
+	}
+
+	// entire string must have been consumed
+	if ch, err2 := r.ReadByte(); err2 == nil {
+		err = fmt.Errorf("expected end of string, found %q", ch)
+	} else if err2 != io.EOF {
+		err = err2
+	}
+
+	return
+}
+
+// ParseFloat is like f.Parse(s, base) with f set to the given precision
+// and rounding mode.
+func ParseFloat(s string, base int, prec uint, mode RoundingMode) (f *Float, b int, err error) {
+	return new(Float).SetPrec(prec).SetMode(mode).Parse(s, base)
+}
diff --git a/third_party/gofrontend/libgo/go/math/big/floatconv_test.go b/third_party/gofrontend/libgo/go/math/big/floatconv_test.go
new file mode 100644
index 0000000..4f23953
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/math/big/floatconv_test.go
@@ -0,0 +1,573 @@
+// 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 big
+
+import (
+	"fmt"
+	"math"
+	"strconv"
+	"testing"
+)
+
+func TestFloatSetFloat64String(t *testing.T) {
+	inf := math.Inf(0)
+	nan := math.NaN()
+
+	for _, test := range []struct {
+		s string
+		x float64 // NaNs represent invalid inputs
+	}{
+		// basics
+		{"0", 0},
+		{"-0", -0},
+		{"+0", 0},
+		{"1", 1},
+		{"-1", -1},
+		{"+1", 1},
+		{"1.234", 1.234},
+		{"-1.234", -1.234},
+		{"+1.234", 1.234},
+		{".1", 0.1},
+		{"1.", 1},
+		{"+1.", 1},
+
+		// various zeros
+		{"0e100", 0},
+		{"-0e+100", 0},
+		{"+0e-100", 0},
+		{"0E100", 0},
+		{"-0E+100", 0},
+		{"+0E-100", 0},
+
+		// various decimal exponent formats
+		{"1.e10", 1e10},
+		{"1e+10", 1e10},
+		{"+1e-10", 1e-10},
+		{"1E10", 1e10},
+		{"1.E+10", 1e10},
+		{"+1E-10", 1e-10},
+
+		// infinities
+		{"Inf", inf},
+		{"+Inf", inf},
+		{"-Inf", -inf},
+		{"inf", inf},
+		{"+inf", inf},
+		{"-inf", -inf},
+
+		// invalid numbers
+		{"", nan},
+		{"-", nan},
+		{"0x", nan},
+		{"0e", nan},
+		{"1.2ef", nan},
+		{"2..3", nan},
+		{"123..", nan},
+		{"infinity", nan},
+		{"foobar", nan},
+
+		// misc decimal values
+		{"3.14159265", 3.14159265},
+		{"-687436.79457e-245", -687436.79457e-245},
+		{"-687436.79457E245", -687436.79457e245},
+		{".0000000000000000000000000000000000000001", 1e-40},
+		{"+10000000000000000000000000000000000000000e-0", 1e40},
+
+		// decimal mantissa, binary exponent
+		{"0p0", 0},
+		{"-0p0", -0},
+		{"1p10", 1 << 10},
+		{"1p+10", 1 << 10},
+		{"+1p-10", 1.0 / (1 << 10)},
+		{"1024p-12", 0.25},
+		{"-1p10", -1024},
+		{"1.5p1", 3},
+
+		// binary mantissa, decimal exponent
+		{"0b0", 0},
+		{"-0b0", -0},
+		{"0b0e+10", 0},
+		{"-0b0e-10", -0},
+		{"0b1010", 10},
+		{"0B1010E2", 1000},
+		{"0b.1", 0.5},
+		{"0b.001", 0.125},
+		{"0b.001e3", 125},
+
+		// binary mantissa, binary exponent
+		{"0b0p+10", 0},
+		{"-0b0p-10", -0},
+		{"0b.1010p4", 10},
+		{"0b1p-1", 0.5},
+		{"0b001p-3", 0.125},
+		{"0b.001p3", 1},
+		{"0b0.01p2", 1},
+
+		// hexadecimal mantissa and exponent
+		{"0x0", 0},
+		{"-0x0", -0},
+		{"0x0p+10", 0},
+		{"-0x0p-10", -0},
+		{"0xff", 255},
+		{"0X.8p1", 1},
+		{"-0X0.00008p16", -0.5},
+		{"0x0.0000000000001p-1022", math.SmallestNonzeroFloat64},
+		{"0x1.fffffffffffffp1023", math.MaxFloat64},
+	} {
+		var x Float
+		x.SetPrec(53)
+		_, ok := x.SetString(test.s)
+		if math.IsNaN(test.x) {
+			// test.s is invalid
+			if ok {
+				t.Errorf("%s: want parse error", test.s)
+			}
+			continue
+		}
+		// test.s is valid
+		if !ok {
+			t.Errorf("%s: got parse error", test.s)
+			continue
+		}
+		f, _ := x.Float64()
+		want := new(Float).SetFloat64(test.x)
+		if x.Cmp(want) != 0 {
+			t.Errorf("%s: got %s (%v); want %v", test.s, &x, f, test.x)
+		}
+	}
+}
+
+const (
+	below1e23 = 99999999999999974834176
+	above1e23 = 100000000000000008388608
+)
+
+func TestFloat64Text(t *testing.T) {
+	for _, test := range []struct {
+		x      float64
+		format byte
+		prec   int
+		want   string
+	}{
+		{0, 'f', 0, "0"},
+		{math.Copysign(0, -1), 'f', 0, "-0"},
+		{1, 'f', 0, "1"},
+		{-1, 'f', 0, "-1"},
+
+		{0.001, 'e', 0, "1e-03"},
+		{0.459, 'e', 0, "5e-01"},
+		{1.459, 'e', 0, "1e+00"},
+		{2.459, 'e', 1, "2.5e+00"},
+		{3.459, 'e', 2, "3.46e+00"},
+		{4.459, 'e', 3, "4.459e+00"},
+		{5.459, 'e', 4, "5.4590e+00"},
+
+		{0.001, 'f', 0, "0"},
+		{0.459, 'f', 0, "0"},
+		{1.459, 'f', 0, "1"},
+		{2.459, 'f', 1, "2.5"},
+		{3.459, 'f', 2, "3.46"},
+		{4.459, 'f', 3, "4.459"},
+		{5.459, 'f', 4, "5.4590"},
+
+		{0, 'b', 0, "0"},
+		{math.Copysign(0, -1), 'b', 0, "-0"},
+		{1.0, 'b', 0, "4503599627370496p-52"},
+		{-1.0, 'b', 0, "-4503599627370496p-52"},
+		{4503599627370496, 'b', 0, "4503599627370496p+0"},
+
+		{0, 'p', 0, "0"},
+		{math.Copysign(0, -1), 'p', 0, "-0"},
+		{1024.0, 'p', 0, "0x.8p+11"},
+		{-1024.0, 'p', 0, "-0x.8p+11"},
+
+		// all test cases below from strconv/ftoa_test.go
+		{1, 'e', 5, "1.00000e+00"},
+		{1, 'f', 5, "1.00000"},
+		{1, 'g', 5, "1"},
+		// {1, 'g', -1, "1"},
+		// {20, 'g', -1, "20"},
+		// {1234567.8, 'g', -1, "1.2345678e+06"},
+		// {200000, 'g', -1, "200000"},
+		// {2000000, 'g', -1, "2e+06"},
+
+		// g conversion and zero suppression
+		{400, 'g', 2, "4e+02"},
+		{40, 'g', 2, "40"},
+		{4, 'g', 2, "4"},
+		{.4, 'g', 2, "0.4"},
+		{.04, 'g', 2, "0.04"},
+		{.004, 'g', 2, "0.004"},
+		{.0004, 'g', 2, "0.0004"},
+		{.00004, 'g', 2, "4e-05"},
+		{.000004, 'g', 2, "4e-06"},
+
+		{0, 'e', 5, "0.00000e+00"},
+		{0, 'f', 5, "0.00000"},
+		{0, 'g', 5, "0"},
+		// {0, 'g', -1, "0"},
+
+		{-1, 'e', 5, "-1.00000e+00"},
+		{-1, 'f', 5, "-1.00000"},
+		{-1, 'g', 5, "-1"},
+		// {-1, 'g', -1, "-1"},
+
+		{12, 'e', 5, "1.20000e+01"},
+		{12, 'f', 5, "12.00000"},
+		{12, 'g', 5, "12"},
+		// {12, 'g', -1, "12"},
+
+		{123456700, 'e', 5, "1.23457e+08"},
+		{123456700, 'f', 5, "123456700.00000"},
+		{123456700, 'g', 5, "1.2346e+08"},
+		// {123456700, 'g', -1, "1.234567e+08"},
+
+		{1.2345e6, 'e', 5, "1.23450e+06"},
+		{1.2345e6, 'f', 5, "1234500.00000"},
+		{1.2345e6, 'g', 5, "1.2345e+06"},
+
+		{1e23, 'e', 17, "9.99999999999999916e+22"},
+		{1e23, 'f', 17, "99999999999999991611392.00000000000000000"},
+		{1e23, 'g', 17, "9.9999999999999992e+22"},
+
+		// {1e23, 'e', -1, "1e+23"},
+		// {1e23, 'f', -1, "100000000000000000000000"},
+		// {1e23, 'g', -1, "1e+23"},
+
+		{below1e23, 'e', 17, "9.99999999999999748e+22"},
+		{below1e23, 'f', 17, "99999999999999974834176.00000000000000000"},
+		{below1e23, 'g', 17, "9.9999999999999975e+22"},
+
+		// {below1e23, 'e', -1, "9.999999999999997e+22"},
+		// {below1e23, 'f', -1, "99999999999999970000000"},
+		// {below1e23, 'g', -1, "9.999999999999997e+22"},
+
+		{above1e23, 'e', 17, "1.00000000000000008e+23"},
+		{above1e23, 'f', 17, "100000000000000008388608.00000000000000000"},
+		// {above1e23, 'g', 17, "1.0000000000000001e+23"},
+
+		// {above1e23, 'e', -1, "1.0000000000000001e+23"},
+		// {above1e23, 'f', -1, "100000000000000010000000"},
+		// {above1e23, 'g', -1, "1.0000000000000001e+23"},
+
+		// {fdiv(5e-304, 1e20), 'g', -1, "5e-324"},
+		// {fdiv(-5e-304, 1e20), 'g', -1, "-5e-324"},
+
+		// {32, 'g', -1, "32"},
+		// {32, 'g', 0, "3e+01"},
+
+		// {100, 'x', -1, "%x"},
+
+		// {math.NaN(), 'g', -1, "NaN"},
+		// {-math.NaN(), 'g', -1, "NaN"},
+		{math.Inf(0), 'g', -1, "+Inf"},
+		{math.Inf(-1), 'g', -1, "-Inf"},
+		{-math.Inf(0), 'g', -1, "-Inf"},
+
+		{-1, 'b', -1, "-4503599627370496p-52"},
+
+		// fixed bugs
+		{0.9, 'f', 1, "0.9"},
+		{0.09, 'f', 1, "0.1"},
+		{0.0999, 'f', 1, "0.1"},
+		{0.05, 'f', 1, "0.1"},
+		{0.05, 'f', 0, "0"},
+		{0.5, 'f', 1, "0.5"},
+		{0.5, 'f', 0, "0"},
+		{1.5, 'f', 0, "2"},
+
+		// http://www.exploringbinary.com/java-hangs-when-converting-2-2250738585072012e-308/
+		// {2.2250738585072012e-308, 'g', -1, "2.2250738585072014e-308"},
+		// http://www.exploringbinary.com/php-hangs-on-numeric-value-2-2250738585072011e-308/
+		// {2.2250738585072011e-308, 'g', -1, "2.225073858507201e-308"},
+
+		// Issue 2625.
+		{383260575764816448, 'f', 0, "383260575764816448"},
+		// {383260575764816448, 'g', -1, "3.8326057576481645e+17"},
+	} {
+		f := new(Float).SetFloat64(test.x)
+		got := f.Text(test.format, test.prec)
+		if got != test.want {
+			t.Errorf("%v: got %s; want %s", test, got, test.want)
+		}
+
+		if test.format == 'b' && test.x == 0 {
+			continue // 'b' format in strconv.Float requires knowledge of bias for 0.0
+		}
+		if test.format == 'p' {
+			continue // 'p' format not supported in strconv.Format
+		}
+
+		// verify that Float format matches strconv format
+		want := strconv.FormatFloat(test.x, test.format, test.prec, 64)
+		if got != want {
+			t.Errorf("%v: got %s; want %s (strconv)", test, got, want)
+		}
+	}
+}
+
+func TestFloatText(t *testing.T) {
+	for _, test := range []struct {
+		x      string
+		prec   uint
+		format byte
+		digits int
+		want   string
+	}{
+		{"0", 10, 'f', 0, "0"},
+		{"-0", 10, 'f', 0, "-0"},
+		{"1", 10, 'f', 0, "1"},
+		{"-1", 10, 'f', 0, "-1"},
+
+		{"1.459", 100, 'e', 0, "1e+00"},
+		{"2.459", 100, 'e', 1, "2.5e+00"},
+		{"3.459", 100, 'e', 2, "3.46e+00"},
+		{"4.459", 100, 'e', 3, "4.459e+00"},
+		{"5.459", 100, 'e', 4, "5.4590e+00"},
+
+		{"1.459", 100, 'E', 0, "1E+00"},
+		{"2.459", 100, 'E', 1, "2.5E+00"},
+		{"3.459", 100, 'E', 2, "3.46E+00"},
+		{"4.459", 100, 'E', 3, "4.459E+00"},
+		{"5.459", 100, 'E', 4, "5.4590E+00"},
+
+		{"1.459", 100, 'f', 0, "1"},
+		{"2.459", 100, 'f', 1, "2.5"},
+		{"3.459", 100, 'f', 2, "3.46"},
+		{"4.459", 100, 'f', 3, "4.459"},
+		{"5.459", 100, 'f', 4, "5.4590"},
+
+		{"1.459", 100, 'g', 0, "1"},
+		{"2.459", 100, 'g', 1, "2"},
+		{"3.459", 100, 'g', 2, "3.5"},
+		{"4.459", 100, 'g', 3, "4.46"},
+		{"5.459", 100, 'g', 4, "5.459"},
+
+		{"1459", 53, 'g', 0, "1e+03"},
+		{"2459", 53, 'g', 1, "2e+03"},
+		{"3459", 53, 'g', 2, "3.5e+03"},
+		{"4459", 53, 'g', 3, "4.46e+03"},
+		{"5459", 53, 'g', 4, "5459"},
+
+		{"1459", 53, 'G', 0, "1E+03"},
+		{"2459", 53, 'G', 1, "2E+03"},
+		{"3459", 53, 'G', 2, "3.5E+03"},
+		{"4459", 53, 'G', 3, "4.46E+03"},
+		{"5459", 53, 'G', 4, "5459"},
+
+		{"3", 10, 'e', 40, "3.0000000000000000000000000000000000000000e+00"},
+		{"3", 10, 'f', 40, "3.0000000000000000000000000000000000000000"},
+		{"3", 10, 'g', 40, "3"},
+
+		{"3e40", 100, 'e', 40, "3.0000000000000000000000000000000000000000e+40"},
+		{"3e40", 100, 'f', 4, "30000000000000000000000000000000000000000.0000"},
+		{"3e40", 100, 'g', 40, "3e+40"},
+
+		// make sure "stupid" exponents don't stall the machine
+		{"1e1000000", 64, 'p', 0, "0x.88b3a28a05eade3ap+3321929"},
+		{"1e1000000000", 64, 'p', 0, "0x.ecc5f45aa573d3p+1538481529"},
+		{"1e-1000000", 64, 'p', 0, "0x.efb4542cc8ca418ap-3321928"},
+		{"1e-1000000000", 64, 'p', 0, "0x.8a64dd983a4c7dabp-1538481528"},
+
+		// TODO(gri) need tests for actual large Floats
+
+		{"0", 53, 'b', 0, "0"},
+		{"-0", 53, 'b', 0, "-0"},
+		{"1.0", 53, 'b', 0, "4503599627370496p-52"},
+		{"-1.0", 53, 'b', 0, "-4503599627370496p-52"},
+		{"4503599627370496", 53, 'b', 0, "4503599627370496p+0"},
+
+		// issue 9939
+		{"3", 350, 'b', 0, "1720123961992553633708115671476565205597423741876210842803191629540192157066363606052513914832594264915968p-348"},
+		{"03", 350, 'b', 0, "1720123961992553633708115671476565205597423741876210842803191629540192157066363606052513914832594264915968p-348"},
+		{"3.", 350, 'b', 0, "1720123961992553633708115671476565205597423741876210842803191629540192157066363606052513914832594264915968p-348"},
+		{"3.0", 350, 'b', 0, "1720123961992553633708115671476565205597423741876210842803191629540192157066363606052513914832594264915968p-348"},
+		{"3.00", 350, 'b', 0, "1720123961992553633708115671476565205597423741876210842803191629540192157066363606052513914832594264915968p-348"},
+		{"3.000", 350, 'b', 0, "1720123961992553633708115671476565205597423741876210842803191629540192157066363606052513914832594264915968p-348"},
+
+		{"3", 350, 'p', 0, "0x.cp+2"},
+		{"03", 350, 'p', 0, "0x.cp+2"},
+		{"3.", 350, 'p', 0, "0x.cp+2"},
+		{"3.0", 350, 'p', 0, "0x.cp+2"},
+		{"3.00", 350, 'p', 0, "0x.cp+2"},
+		{"3.000", 350, 'p', 0, "0x.cp+2"},
+
+		{"0", 64, 'p', 0, "0"},
+		{"-0", 64, 'p', 0, "-0"},
+		{"1024.0", 64, 'p', 0, "0x.8p+11"},
+		{"-1024.0", 64, 'p', 0, "-0x.8p+11"},
+
+		// unsupported format
+		{"3.14", 64, 'x', 0, "%x"},
+		{"-3.14", 64, 'x', 0, "%x"},
+	} {
+		f, _, err := ParseFloat(test.x, 0, test.prec, ToNearestEven)
+		if err != nil {
+			t.Errorf("%v: %s", test, err)
+			continue
+		}
+
+		got := f.Text(test.format, test.digits)
+		if got != test.want {
+			t.Errorf("%v: got %s; want %s", test, got, test.want)
+		}
+
+		// compare with strconv.FormatFloat output if possible
+		// ('p' format is not supported by strconv.FormatFloat,
+		// and its output for 0.0 prints a biased exponent value
+		// as in 0p-1074 which makes no sense to emulate here)
+		if test.prec == 53 && test.format != 'p' && f.Sign() != 0 {
+			f64, acc := f.Float64()
+			if acc != Exact {
+				t.Errorf("%v: expected exact conversion to float64", test)
+				continue
+			}
+			got := strconv.FormatFloat(f64, test.format, test.digits, 64)
+			if got != test.want {
+				t.Errorf("%v: got %s; want %s", test, got, test.want)
+			}
+		}
+	}
+}
+
+func TestFloatFormat(t *testing.T) {
+	for _, test := range []struct {
+		format string
+		value  interface{} // float32, float64, or string (== 512bit *Float)
+		want   string
+	}{
+		// TODO(gri) uncomment the disabled 'g'/'G' formats
+		// 	     below once (*Float).Text supports prec < 0
+
+		// from fmt/fmt_test.go
+		{"%+.3e", 0.0, "+0.000e+00"},
+		{"%+.3e", 1.0, "+1.000e+00"},
+		{"%+.3f", -1.0, "-1.000"},
+		{"%+.3F", -1.0, "-1.000"},
+		{"%+.3F", float32(-1.0), "-1.000"},
+		{"%+07.2f", 1.0, "+001.00"},
+		{"%+07.2f", -1.0, "-001.00"},
+		{"%+10.2f", +1.0, "     +1.00"},
+		{"%+10.2f", -1.0, "     -1.00"},
+		{"% .3E", -1.0, "-1.000E+00"},
+		{"% .3e", 1.0, " 1.000e+00"},
+		{"%+.3g", 0.0, "+0"},
+		{"%+.3g", 1.0, "+1"},
+		{"%+.3g", -1.0, "-1"},
+		{"% .3g", -1.0, "-1"},
+		{"% .3g", 1.0, " 1"},
+		{"%b", float32(1.0), "8388608p-23"},
+		{"%b", 1.0, "4503599627370496p-52"},
+
+		// from fmt/fmt_test.go: old test/fmt_test.go
+		{"%e", 1.0, "1.000000e+00"},
+		{"%e", 1234.5678e3, "1.234568e+06"},
+		{"%e", 1234.5678e-8, "1.234568e-05"},
+		{"%e", -7.0, "-7.000000e+00"},
+		{"%e", -1e-9, "-1.000000e-09"},
+		{"%f", 1234.5678e3, "1234567.800000"},
+		{"%f", 1234.5678e-8, "0.000012"},
+		{"%f", -7.0, "-7.000000"},
+		{"%f", -1e-9, "-0.000000"},
+		// {"%g", 1234.5678e3, "1.2345678e+06"},
+		// {"%g", float32(1234.5678e3), "1.2345678e+06"},
+		// {"%g", 1234.5678e-8, "1.2345678e-05"},
+		{"%g", -7.0, "-7"},
+		{"%g", -1e-9, "-1e-09"},
+		{"%g", float32(-1e-9), "-1e-09"},
+		{"%E", 1.0, "1.000000E+00"},
+		{"%E", 1234.5678e3, "1.234568E+06"},
+		{"%E", 1234.5678e-8, "1.234568E-05"},
+		{"%E", -7.0, "-7.000000E+00"},
+		{"%E", -1e-9, "-1.000000E-09"},
+		// {"%G", 1234.5678e3, "1.2345678E+06"},
+		// {"%G", float32(1234.5678e3), "1.2345678E+06"},
+		// {"%G", 1234.5678e-8, "1.2345678E-05"},
+		{"%G", -7.0, "-7"},
+		{"%G", -1e-9, "-1E-09"},
+		{"%G", float32(-1e-9), "-1E-09"},
+
+		{"%20.6e", 1.2345e3, "        1.234500e+03"},
+		{"%20.6e", 1.2345e-3, "        1.234500e-03"},
+		{"%20e", 1.2345e3, "        1.234500e+03"},
+		{"%20e", 1.2345e-3, "        1.234500e-03"},
+		{"%20.8e", 1.2345e3, "      1.23450000e+03"},
+		{"%20f", 1.23456789e3, "         1234.567890"},
+		{"%20f", 1.23456789e-3, "            0.001235"},
+		{"%20f", 12345678901.23456789, "  12345678901.234568"},
+		{"%-20f", 1.23456789e3, "1234.567890         "},
+		{"%20.8f", 1.23456789e3, "       1234.56789000"},
+		{"%20.8f", 1.23456789e-3, "          0.00123457"},
+		// {"%g", 1.23456789e3, "1234.56789"},
+		// {"%g", 1.23456789e-3, "0.00123456789"},
+		// {"%g", 1.23456789e20, "1.23456789e+20"},
+		{"%20e", math.Inf(1), "                +Inf"},
+		{"%-20f", math.Inf(-1), "-Inf                "},
+
+		// from fmt/fmt_test.go: comparison of padding rules with C printf
+		{"%.2f", 1.0, "1.00"},
+		{"%.2f", -1.0, "-1.00"},
+		{"% .2f", 1.0, " 1.00"},
+		{"% .2f", -1.0, "-1.00"},
+		{"%+.2f", 1.0, "+1.00"},
+		{"%+.2f", -1.0, "-1.00"},
+		{"%7.2f", 1.0, "   1.00"},
+		{"%7.2f", -1.0, "  -1.00"},
+		{"% 7.2f", 1.0, "   1.00"},
+		{"% 7.2f", -1.0, "  -1.00"},
+		{"%+7.2f", 1.0, "  +1.00"},
+		{"%+7.2f", -1.0, "  -1.00"},
+		{"%07.2f", 1.0, "0001.00"},
+		{"%07.2f", -1.0, "-001.00"},
+		{"% 07.2f", 1.0, " 001.00"},
+		{"% 07.2f", -1.0, "-001.00"},
+		{"%+07.2f", 1.0, "+001.00"},
+		{"%+07.2f", -1.0, "-001.00"},
+
+		// from fmt/fmt_test.go: zero padding does not apply to infinities
+		{"%020f", math.Inf(-1), "                -Inf"},
+		{"%020f", math.Inf(+1), "                +Inf"},
+		{"% 020f", math.Inf(-1), "                -Inf"},
+		{"% 020f", math.Inf(+1), "                 Inf"},
+		{"%+020f", math.Inf(-1), "                -Inf"},
+		{"%+020f", math.Inf(+1), "                +Inf"},
+		{"%20f", -1.0, "           -1.000000"},
+
+		// handle %v like %g
+		{"%v", 0.0, "0"},
+		{"%v", -7.0, "-7"},
+		{"%v", -1e-9, "-1e-09"},
+		{"%v", float32(-1e-9), "-1e-09"},
+		{"%010v", 0.0, "0000000000"},
+		{"%010v", 0.0, "0000000000"},
+
+		// *Float cases
+		{"%.20f", "1e-20", "0.00000000000000000001"},
+		{"%.20f", "-1e-20", "-0.00000000000000000001"},
+		{"%30.20f", "-1e-20", "       -0.00000000000000000001"},
+		{"%030.20f", "-1e-20", "-00000000.00000000000000000001"},
+		{"%030.20f", "+1e-20", "000000000.00000000000000000001"},
+		{"% 030.20f", "+1e-20", " 00000000.00000000000000000001"},
+
+		// erroneous formats
+		{"%s", 1.0, "%!s(*big.Float=1)"},
+	} {
+		value := new(Float)
+		switch v := test.value.(type) {
+		case float32:
+			value.SetPrec(24).SetFloat64(float64(v))
+		case float64:
+			value.SetPrec(53).SetFloat64(v)
+		case string:
+			value.SetPrec(512).Parse(v, 0)
+		default:
+			t.Fatalf("unsupported test value: %v (%T)", v, v)
+		}
+
+		if got := fmt.Sprintf(test.format, value); got != test.want {
+			t.Errorf("%v: got %q; want %q", test, got, test.want)
+		}
+	}
+}
diff --git a/third_party/gofrontend/libgo/go/math/big/floatexample_test.go b/third_party/gofrontend/libgo/go/math/big/floatexample_test.go
new file mode 100644
index 0000000..69686b7
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/math/big/floatexample_test.go
@@ -0,0 +1,113 @@
+// 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 ignore
+
+package big_test
+
+import (
+	"fmt"
+	"math"
+	"math/big"
+)
+
+func ExampleFloat_Add() {
+	// Operating on numbers of different precision.
+	var x, y, z big.Float
+	x.SetInt64(1000)          // x is automatically set to 64bit precision
+	y.SetFloat64(2.718281828) // y is automatically set to 53bit precision
+	z.SetPrec(32)
+	z.Add(&x, &y)
+	fmt.Printf("x = %.10g (%s, prec = %d, acc = %s)\n", &x, x.Text('p', 0), x.Prec(), x.Acc())
+	fmt.Printf("y = %.10g (%s, prec = %d, acc = %s)\n", &y, y.Text('p', 0), y.Prec(), y.Acc())
+	fmt.Printf("z = %.10g (%s, prec = %d, acc = %s)\n", &z, z.Text('p', 0), z.Prec(), z.Acc())
+	// Output:
+	// x = 1000 (0x.fap+10, prec = 64, acc = Exact)
+	// y = 2.718281828 (0x.adf85458248cd8p+2, prec = 53, acc = Exact)
+	// z = 1002.718282 (0x.faadf854p+10, prec = 32, acc = Below)
+}
+
+func Example_Shift() {
+	// Implementing Float "shift" by modifying the (binary) exponents directly.
+	for s := -5; s <= 5; s++ {
+		x := big.NewFloat(0.5)
+		x.SetMantExp(x, x.MantExp(nil)+s) // shift x by s
+		fmt.Println(x)
+	}
+	// Output:
+	// 0.015625
+	// 0.03125
+	// 0.0625
+	// 0.125
+	// 0.25
+	// 0.5
+	// 1
+	// 2
+	// 4
+	// 8
+	// 16
+}
+
+func ExampleFloat_Cmp() {
+	inf := math.Inf(1)
+	zero := 0.0
+
+	operands := []float64{-inf, -1.2, -zero, 0, +1.2, +inf}
+
+	fmt.Println("   x     y  cmp")
+	fmt.Println("---------------")
+	for _, x64 := range operands {
+		x := big.NewFloat(x64)
+		for _, y64 := range operands {
+			y := big.NewFloat(y64)
+			fmt.Printf("%4g  %4g  %3d\n", x, y, x.Cmp(y))
+		}
+		fmt.Println()
+	}
+
+	// Output:
+	//    x     y  cmp
+	// ---------------
+	// -Inf  -Inf    0
+	// -Inf  -1.2   -1
+	// -Inf    -0   -1
+	// -Inf     0   -1
+	// -Inf   1.2   -1
+	// -Inf  +Inf   -1
+	//
+	// -1.2  -Inf    1
+	// -1.2  -1.2    0
+	// -1.2    -0   -1
+	// -1.2     0   -1
+	// -1.2   1.2   -1
+	// -1.2  +Inf   -1
+	//
+	//   -0  -Inf    1
+	//   -0  -1.2    1
+	//   -0    -0    0
+	//   -0     0    0
+	//   -0   1.2   -1
+	//   -0  +Inf   -1
+	//
+	//    0  -Inf    1
+	//    0  -1.2    1
+	//    0    -0    0
+	//    0     0    0
+	//    0   1.2   -1
+	//    0  +Inf   -1
+	//
+	//  1.2  -Inf    1
+	//  1.2  -1.2    1
+	//  1.2    -0    1
+	//  1.2     0    1
+	//  1.2   1.2    0
+	//  1.2  +Inf   -1
+	//
+	// +Inf  -Inf    1
+	// +Inf  -1.2    1
+	// +Inf    -0    1
+	// +Inf     0    1
+	// +Inf   1.2    1
+	// +Inf  +Inf    0
+}
diff --git a/third_party/gofrontend/libgo/go/math/big/ftoa.go b/third_party/gofrontend/libgo/go/math/big/ftoa.go
new file mode 100644
index 0000000..5c5f2ce
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/math/big/ftoa.go
@@ -0,0 +1,393 @@
+// 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.
+
+// This file implements Float-to-string conversion functions.
+// It is closely following the corresponding implementation
+// in strconv/ftoa.go, but modified and simplified for Float.
+
+package big
+
+import (
+	"fmt"
+	"strconv"
+	"strings"
+)
+
+// Text converts the floating-point number x to a string according
+// to the given format and precision prec. The format is one of:
+//
+//	'e'	-d.dddde±dd, decimal exponent, at least two (possibly 0) exponent digits
+//	'E'	-d.ddddE±dd, decimal exponent, at least two (possibly 0) exponent digits
+//	'f'	-ddddd.dddd, no exponent
+//	'g'	like 'e' for large exponents, like 'f' otherwise
+//	'G'	like 'E' for large exponents, like 'f' otherwise
+//	'b'	-ddddddp±dd, binary exponent
+//	'p'	-0x.dddp±dd, binary exponent, hexadecimal mantissa
+//
+// For the binary exponent formats, the mantissa is printed in normalized form:
+//
+//	'b'	decimal integer mantissa using x.Prec() bits, or -0
+//	'p'	hexadecimal fraction with 0.5 <= 0.mantissa < 1.0, or -0
+//
+// If format is a different character, Text returns a "%" followed by the
+// unrecognized format character.
+//
+// The precision prec controls the number of digits (excluding the exponent)
+// printed by the 'e', 'E', 'f', 'g', and 'G' formats. For 'e', 'E', and 'f'
+// it is the number of digits after the decimal point. For 'g' and 'G' it is
+// the total number of digits. A negative precision selects the smallest
+// number of digits necessary to identify the value x uniquely.
+// The prec value is ignored for the 'b' or 'p' format.
+//
+// BUG(gri) Float.Text does not accept negative precisions (issue #10991).
+func (x *Float) Text(format byte, prec int) string {
+	const extra = 10 // TODO(gri) determine a good/better value here
+	return string(x.Append(make([]byte, 0, prec+extra), format, prec))
+}
+
+// String formats x like x.Text('g', 10).
+func (x *Float) String() string {
+	return x.Text('g', 10)
+}
+
+// Append appends to buf the string form of the floating-point number x,
+// as generated by x.Text, and returns the extended buffer.
+func (x *Float) Append(buf []byte, fmt byte, prec int) []byte {
+	// sign
+	if x.neg {
+		buf = append(buf, '-')
+	}
+
+	// Inf
+	if x.form == inf {
+		if !x.neg {
+			buf = append(buf, '+')
+		}
+		return append(buf, "Inf"...)
+	}
+
+	// pick off easy formats
+	switch fmt {
+	case 'b':
+		return x.fmtB(buf)
+	case 'p':
+		return x.fmtP(buf)
+	}
+
+	// Algorithm:
+	//   1) convert Float to multiprecision decimal
+	//   2) round to desired precision
+	//   3) read digits out and format
+
+	// 1) convert Float to multiprecision decimal
+	var d decimal // == 0.0
+	if x.form == finite {
+		d.init(x.mant, int(x.exp)-x.mant.bitLen())
+	}
+
+	// 2) round to desired precision
+	shortest := false
+	if prec < 0 {
+		shortest = true
+		panic("unimplemented")
+		// TODO(gri) complete this
+		// roundShortest(&d, f.mant, int(f.exp))
+		// Precision for shortest representation mode.
+		switch fmt {
+		case 'e', 'E':
+			prec = len(d.mant) - 1
+		case 'f':
+			prec = max(len(d.mant)-d.exp, 0)
+		case 'g', 'G':
+			prec = len(d.mant)
+		}
+	} else {
+		// round appropriately
+		switch fmt {
+		case 'e', 'E':
+			// one digit before and number of digits after decimal point
+			d.round(1 + prec)
+		case 'f':
+			// number of digits before and after decimal point
+			d.round(d.exp + prec)
+		case 'g', 'G':
+			if prec == 0 {
+				prec = 1
+			}
+			d.round(prec)
+		}
+	}
+
+	// 3) read digits out and format
+	switch fmt {
+	case 'e', 'E':
+		return fmtE(buf, fmt, prec, d)
+	case 'f':
+		return fmtF(buf, prec, d)
+	case 'g', 'G':
+		// trim trailing fractional zeros in %e format
+		eprec := prec
+		if eprec > len(d.mant) && len(d.mant) >= d.exp {
+			eprec = len(d.mant)
+		}
+		// %e is used if the exponent from the conversion
+		// is less than -4 or greater than or equal to the precision.
+		// If precision was the shortest possible, use eprec = 6 for
+		// this decision.
+		if shortest {
+			eprec = 6
+		}
+		exp := d.exp - 1
+		if exp < -4 || exp >= eprec {
+			if prec > len(d.mant) {
+				prec = len(d.mant)
+			}
+			return fmtE(buf, fmt+'e'-'g', prec-1, d)
+		}
+		if prec > d.exp {
+			prec = len(d.mant)
+		}
+		return fmtF(buf, max(prec-d.exp, 0), d)
+	}
+
+	// unknown format
+	if x.neg {
+		buf = buf[:len(buf)-1] // sign was added prematurely - remove it again
+	}
+	return append(buf, '%', fmt)
+}
+
+// %e: d.ddddde±dd
+func fmtE(buf []byte, fmt byte, prec int, d decimal) []byte {
+	// first digit
+	ch := byte('0')
+	if len(d.mant) > 0 {
+		ch = d.mant[0]
+	}
+	buf = append(buf, ch)
+
+	// .moredigits
+	if prec > 0 {
+		buf = append(buf, '.')
+		i := 1
+		m := min(len(d.mant), prec+1)
+		if i < m {
+			buf = append(buf, d.mant[i:m]...)
+			i = m
+		}
+		for ; i <= prec; i++ {
+			buf = append(buf, '0')
+		}
+	}
+
+	// e±
+	buf = append(buf, fmt)
+	var exp int64
+	if len(d.mant) > 0 {
+		exp = int64(d.exp) - 1 // -1 because first digit was printed before '.'
+	}
+	if exp < 0 {
+		ch = '-'
+		exp = -exp
+	} else {
+		ch = '+'
+	}
+	buf = append(buf, ch)
+
+	// dd...d
+	if exp < 10 {
+		buf = append(buf, '0') // at least 2 exponent digits
+	}
+	return strconv.AppendInt(buf, exp, 10)
+}
+
+// %f: ddddddd.ddddd
+func fmtF(buf []byte, prec int, d decimal) []byte {
+	// integer, padded with zeros as needed
+	if d.exp > 0 {
+		m := min(len(d.mant), d.exp)
+		buf = append(buf, d.mant[:m]...)
+		for ; m < d.exp; m++ {
+			buf = append(buf, '0')
+		}
+	} else {
+		buf = append(buf, '0')
+	}
+
+	// fraction
+	if prec > 0 {
+		buf = append(buf, '.')
+		for i := 0; i < prec; i++ {
+			ch := byte('0')
+			if j := d.exp + i; 0 <= j && j < len(d.mant) {
+				ch = d.mant[j]
+			}
+			buf = append(buf, ch)
+		}
+	}
+
+	return buf
+}
+
+// fmtB appends the string of x in the format mantissa "p" exponent
+// with a decimal mantissa and a binary exponent, or 0" if x is zero,
+// and returns the extended buffer.
+// The mantissa is normalized such that is uses x.Prec() bits in binary
+// representation.
+// The sign of x is ignored, and x must not be an Inf.
+func (x *Float) fmtB(buf []byte) []byte {
+	if x.form == zero {
+		return append(buf, '0')
+	}
+
+	if debugFloat && x.form != finite {
+		panic("non-finite float")
+	}
+	// x != 0
+
+	// adjust mantissa to use exactly x.prec bits
+	m := x.mant
+	switch w := uint32(len(x.mant)) * _W; {
+	case w < x.prec:
+		m = nat(nil).shl(m, uint(x.prec-w))
+	case w > x.prec:
+		m = nat(nil).shr(m, uint(w-x.prec))
+	}
+
+	buf = append(buf, m.decimalString()...)
+	buf = append(buf, 'p')
+	e := int64(x.exp) - int64(x.prec)
+	if e >= 0 {
+		buf = append(buf, '+')
+	}
+	return strconv.AppendInt(buf, e, 10)
+}
+
+// fmtP appends the string of x in the format 0x." mantissa "p" exponent
+// with a hexadecimal mantissa and a binary exponent, or 0" if x is zero,
+// ad returns the extended buffer.
+// The mantissa is normalized such that 0.5 <= 0.mantissa < 1.0.
+// The sign of x is ignored, and x must not be an Inf.
+func (x *Float) fmtP(buf []byte) []byte {
+	if x.form == zero {
+		return append(buf, '0')
+	}
+
+	if debugFloat && x.form != finite {
+		panic("non-finite float")
+	}
+	// x != 0
+
+	// remove trailing 0 words early
+	// (no need to convert to hex 0's and trim later)
+	m := x.mant
+	i := 0
+	for i < len(m) && m[i] == 0 {
+		i++
+	}
+	m = m[i:]
+
+	buf = append(buf, "0x."...)
+	buf = append(buf, strings.TrimRight(m.hexString(), "0")...)
+	buf = append(buf, 'p')
+	if x.exp >= 0 {
+		buf = append(buf, '+')
+	}
+	return strconv.AppendInt(buf, int64(x.exp), 10)
+}
+
+func min(x, y int) int {
+	if x < y {
+		return x
+	}
+	return y
+}
+
+// Format implements fmt.Formatter. It accepts all the regular
+// formats for floating-point numbers ('e', 'E', 'f', 'F', 'g',
+// 'G') as well as 'b', 'p', and 'v'. See (*Float).Text for the
+// interpretation of 'b' and 'p'. The 'v' format is handled like
+// 'g'.
+// Format also supports specification of the minimum precision
+// in digits, the output field width, as well as the format verbs
+// '+' and ' ' for sign control, '0' for space or zero padding,
+// and '-' for left or right justification. See the fmt package
+// for details.
+//
+// BUG(gri) A missing precision for the 'g' format, or a negative
+//          (via '*') precision is not yet supported. Instead the
+//          default precision (6) is used in that case (issue #10991).
+func (x *Float) Format(s fmt.State, format rune) {
+	prec, hasPrec := s.Precision()
+	if !hasPrec {
+		prec = 6 // default precision for 'e', 'f'
+	}
+
+	switch format {
+	case 'e', 'E', 'f', 'b', 'p':
+		// nothing to do
+	case 'F':
+		// (*Float).Text doesn't support 'F'; handle like 'f'
+		format = 'f'
+	case 'v':
+		// handle like 'g'
+		format = 'g'
+		fallthrough
+	case 'g', 'G':
+		if !hasPrec {
+			// TODO(gri) uncomment once (*Float).Text handles prec < 0
+			// prec = -1 // default precision for 'g', 'G'
+		}
+	default:
+		fmt.Fprintf(s, "%%!%c(*big.Float=%s)", format, x.String())
+		return
+	}
+	var buf []byte
+	buf = x.Append(buf, byte(format), prec)
+	if len(buf) == 0 {
+		buf = []byte("?") // should never happen, but don't crash
+	}
+	// len(buf) > 0
+
+	var sign string
+	switch {
+	case buf[0] == '-':
+		sign = "-"
+		buf = buf[1:]
+	case buf[0] == '+':
+		// +Inf
+		sign = "+"
+		if s.Flag(' ') {
+			sign = " "
+		}
+		buf = buf[1:]
+	case s.Flag('+'):
+		sign = "+"
+	case s.Flag(' '):
+		sign = " "
+	}
+
+	var padding int
+	if width, hasWidth := s.Width(); hasWidth && width > len(sign)+len(buf) {
+		padding = width - len(sign) - len(buf)
+	}
+
+	switch {
+	case s.Flag('0') && !x.IsInf():
+		// 0-padding on left
+		writeMultiple(s, sign, 1)
+		writeMultiple(s, "0", padding)
+		s.Write(buf)
+	case s.Flag('-'):
+		// padding on right
+		writeMultiple(s, sign, 1)
+		s.Write(buf)
+		writeMultiple(s, " ", padding)
+	default:
+		// padding on left
+		writeMultiple(s, " ", padding)
+		writeMultiple(s, sign, 1)
+		s.Write(buf)
+	}
+}
diff --git a/third_party/gofrontend/libgo/go/math/big/int.go b/third_party/gofrontend/libgo/go/math/big/int.go
index ade5c2f..65334e0 100644
--- a/third_party/gofrontend/libgo/go/math/big/int.go
+++ b/third_party/gofrontend/libgo/go/math/big/int.go
@@ -7,7 +7,6 @@
 package big
 
 import (
-	"errors"
 	"fmt"
 	"io"
 	"math/rand"
@@ -184,6 +183,10 @@
 
 // Binomial sets z to the binomial coefficient of (n, k) and returns z.
 func (z *Int) Binomial(n, k int64) *Int {
+	// reduce the number of multiplications by reducing k
+	if n/2 < k && k <= n {
+		k = n - k // Binomial(n, k) == Binomial(n, n-k)
+	}
 	var a, b Int
 	a.MulRange(n-k+1, n)
 	b.MulRange(1, k)
@@ -321,195 +324,6 @@
 	return
 }
 
-func (x *Int) String() string {
-	switch {
-	case x == nil:
-		return "<nil>"
-	case x.neg:
-		return "-" + x.abs.decimalString()
-	}
-	return x.abs.decimalString()
-}
-
-func charset(ch rune) string {
-	switch ch {
-	case 'b':
-		return lowercaseDigits[0:2]
-	case 'o':
-		return lowercaseDigits[0:8]
-	case 'd', 's', 'v':
-		return lowercaseDigits[0:10]
-	case 'x':
-		return lowercaseDigits[0:16]
-	case 'X':
-		return uppercaseDigits[0:16]
-	}
-	return "" // unknown format
-}
-
-// write count copies of text to s
-func writeMultiple(s fmt.State, text string, count int) {
-	if len(text) > 0 {
-		b := []byte(text)
-		for ; count > 0; count-- {
-			s.Write(b)
-		}
-	}
-}
-
-// Format is a support routine for fmt.Formatter. It accepts
-// the formats 'b' (binary), 'o' (octal), 'd' (decimal), 'x'
-// (lowercase hexadecimal), and 'X' (uppercase hexadecimal).
-// Also supported are the full suite of package fmt's format
-// verbs for integral types, including '+', '-', and ' '
-// for sign control, '#' for leading zero in octal and for
-// hexadecimal, a leading "0x" or "0X" for "%#x" and "%#X"
-// respectively, specification of minimum digits precision,
-// output field width, space or zero padding, and left or
-// right justification.
-//
-func (x *Int) Format(s fmt.State, ch rune) {
-	cs := charset(ch)
-
-	// special cases
-	switch {
-	case cs == "":
-		// unknown format
-		fmt.Fprintf(s, "%%!%c(big.Int=%s)", ch, x.String())
-		return
-	case x == nil:
-		fmt.Fprint(s, "<nil>")
-		return
-	}
-
-	// determine sign character
-	sign := ""
-	switch {
-	case x.neg:
-		sign = "-"
-	case s.Flag('+'): // supersedes ' ' when both specified
-		sign = "+"
-	case s.Flag(' '):
-		sign = " "
-	}
-
-	// determine prefix characters for indicating output base
-	prefix := ""
-	if s.Flag('#') {
-		switch ch {
-		case 'o': // octal
-			prefix = "0"
-		case 'x': // hexadecimal
-			prefix = "0x"
-		case 'X':
-			prefix = "0X"
-		}
-	}
-
-	// determine digits with base set by len(cs) and digit characters from cs
-	digits := x.abs.string(cs)
-
-	// number of characters for the three classes of number padding
-	var left int   // space characters to left of digits for right justification ("%8d")
-	var zeroes int // zero characters (actually cs[0]) as left-most digits ("%.8d")
-	var right int  // space characters to right of digits for left justification ("%-8d")
-
-	// determine number padding from precision: the least number of digits to output
-	precision, precisionSet := s.Precision()
-	if precisionSet {
-		switch {
-		case len(digits) < precision:
-			zeroes = precision - len(digits) // count of zero padding
-		case digits == "0" && precision == 0:
-			return // print nothing if zero value (x == 0) and zero precision ("." or ".0")
-		}
-	}
-
-	// determine field pad from width: the least number of characters to output
-	length := len(sign) + len(prefix) + zeroes + len(digits)
-	if width, widthSet := s.Width(); widthSet && length < width { // pad as specified
-		switch d := width - length; {
-		case s.Flag('-'):
-			// pad on the right with spaces; supersedes '0' when both specified
-			right = d
-		case s.Flag('0') && !precisionSet:
-			// pad with zeroes unless precision also specified
-			zeroes = d
-		default:
-			// pad on the left with spaces
-			left = d
-		}
-	}
-
-	// print number as [left pad][sign][prefix][zero pad][digits][right pad]
-	writeMultiple(s, " ", left)
-	writeMultiple(s, sign, 1)
-	writeMultiple(s, prefix, 1)
-	writeMultiple(s, "0", zeroes)
-	writeMultiple(s, digits, 1)
-	writeMultiple(s, " ", right)
-}
-
-// scan sets z to the integer value corresponding to the longest possible prefix
-// read from r representing a signed integer number in a given conversion base.
-// It returns z, the actual conversion base used, and an error, if any. In the
-// error case, the value of z is undefined but the returned value is nil. The
-// syntax follows the syntax of integer literals in Go.
-//
-// The base argument must be 0 or a value from 2 through MaxBase. If the base
-// is 0, the string prefix determines the actual conversion base. A prefix of
-// ``0x'' or ``0X'' selects base 16; the ``0'' prefix selects base 8, and a
-// ``0b'' or ``0B'' prefix selects base 2. Otherwise the selected base is 10.
-//
-func (z *Int) scan(r io.RuneScanner, base int) (*Int, int, error) {
-	// determine sign
-	ch, _, err := r.ReadRune()
-	if err != nil {
-		return nil, 0, err
-	}
-	neg := false
-	switch ch {
-	case '-':
-		neg = true
-	case '+': // nothing to do
-	default:
-		r.UnreadRune()
-	}
-
-	// determine mantissa
-	z.abs, base, err = z.abs.scan(r, base)
-	if err != nil {
-		return nil, base, err
-	}
-	z.neg = len(z.abs) > 0 && neg // 0 has no sign
-
-	return z, base, nil
-}
-
-// Scan is a support routine for fmt.Scanner; it sets z to the value of
-// the scanned number. It accepts the formats 'b' (binary), 'o' (octal),
-// 'd' (decimal), 'x' (lowercase hexadecimal), and 'X' (uppercase hexadecimal).
-func (z *Int) Scan(s fmt.ScanState, ch rune) error {
-	s.SkipSpace() // skip leading space characters
-	base := 0
-	switch ch {
-	case 'b':
-		base = 2
-	case 'o':
-		base = 8
-	case 'd':
-		base = 10
-	case 'x', 'X':
-		base = 16
-	case 's', 'v':
-		// let scan determine the base
-	default:
-		return errors.New("Int.Scan: invalid verb")
-	}
-	_, _, err := z.scan(s, base)
-	return err
-}
-
 // low32 returns the least significant 32 bits of z.
 func low32(z nat) uint32 {
 	if len(z) == 0 {
@@ -550,7 +364,7 @@
 // and returns z and a boolean indicating success. If SetString fails,
 // the value of z is undefined but the returned value is nil.
 //
-// The base argument must be 0 or a value from 2 through MaxBase. If the base
+// The base argument must be 0 or a value between 2 and MaxBase. If the base
 // is 0, the string prefix determines the actual conversion base. A prefix of
 // ``0x'' or ``0X'' selects base 16; the ``0'' prefix selects base 8, and a
 // ``0b'' or ``0B'' prefix selects base 2. Otherwise the selected base is 10.
@@ -561,7 +375,7 @@
 	if err != nil {
 		return nil, false
 	}
-	_, _, err = r.ReadRune()
+	_, err = r.ReadByte()
 	if err != io.EOF {
 		return nil, false
 	}
@@ -686,15 +500,17 @@
 	// use one Euclidean iteration to ensure that u and v are approx. the same size
 	switch {
 	case len(a.abs) > len(b.abs):
-		u.Set(b)
+		// must set v before u since u may be alias for a or b (was issue #11284)
 		v.Rem(a, b)
+		u.Set(b)
 	case len(a.abs) < len(b.abs):
-		u.Set(a)
 		v.Rem(b, a)
-	default:
 		u.Set(a)
+	default:
 		v.Set(b)
+		u.Set(a)
 	}
+	// a, b must not be used anymore (may be aliases with u)
 
 	// v might be 0 now
 	if len(v.abs) == 0 {
@@ -736,8 +552,11 @@
 
 // ProbablyPrime performs n Miller-Rabin tests to check whether x is prime.
 // If it returns true, x is prime with probability 1 - 1/4^n.
-// If it returns false, x is not prime.
+// If it returns false, x is not prime. n must be > 0.
 func (x *Int) ProbablyPrime(n int) bool {
+	if n <= 0 {
+		panic("non-positive n for ProbablyPrime")
+	}
 	return !x.neg && x.abs.probablyPrime(n)
 }
 
@@ -766,6 +585,124 @@
 	return z
 }
 
+// Jacobi returns the Jacobi symbol (x/y), either +1, -1, or 0.
+// The y argument must be an odd integer.
+func Jacobi(x, y *Int) int {
+	if len(y.abs) == 0 || y.abs[0]&1 == 0 {
+		panic(fmt.Sprintf("big: invalid 2nd argument to Int.Jacobi: need odd integer but got %s", y))
+	}
+
+	// We use the formulation described in chapter 2, section 2.4,
+	// "The Yacas Book of Algorithms":
+	// http://yacas.sourceforge.net/Algo.book.pdf
+
+	var a, b, c Int
+	a.Set(x)
+	b.Set(y)
+	j := 1
+
+	if b.neg {
+		if a.neg {
+			j = -1
+		}
+		b.neg = false
+	}
+
+	for {
+		if b.Cmp(intOne) == 0 {
+			return j
+		}
+		if len(a.abs) == 0 {
+			return 0
+		}
+		a.Mod(&a, &b)
+		if len(a.abs) == 0 {
+			return 0
+		}
+		// a > 0
+
+		// handle factors of 2 in 'a'
+		s := a.abs.trailingZeroBits()
+		if s&1 != 0 {
+			bmod8 := b.abs[0] & 7
+			if bmod8 == 3 || bmod8 == 5 {
+				j = -j
+			}
+		}
+		c.Rsh(&a, s) // a = 2^s*c
+
+		// swap numerator and denominator
+		if b.abs[0]&3 == 3 && c.abs[0]&3 == 3 {
+			j = -j
+		}
+		a.Set(&b)
+		b.Set(&c)
+	}
+}
+
+// ModSqrt sets z to a square root of x mod p if such a square root exists, and
+// returns z. The modulus p must be an odd prime. If x is not a square mod p,
+// ModSqrt leaves z unchanged and returns nil. This function panics if p is
+// not an odd integer.
+func (z *Int) ModSqrt(x, p *Int) *Int {
+	switch Jacobi(x, p) {
+	case -1:
+		return nil // x is not a square mod p
+	case 0:
+		return z.SetInt64(0) // sqrt(0) mod p = 0
+	case 1:
+		break
+	}
+	if x.neg || x.Cmp(p) >= 0 { // ensure 0 <= x < p
+		x = new(Int).Mod(x, p)
+	}
+
+	// Break p-1 into s*2^e such that s is odd.
+	var s Int
+	s.Sub(p, intOne)
+	e := s.abs.trailingZeroBits()
+	s.Rsh(&s, e)
+
+	// find some non-square n
+	var n Int
+	n.SetInt64(2)
+	for Jacobi(&n, p) != -1 {
+		n.Add(&n, intOne)
+	}
+
+	// Core of the Tonelli-Shanks algorithm. Follows the description in
+	// section 6 of "Square roots from 1; 24, 51, 10 to Dan Shanks" by Ezra
+	// Brown:
+	// https://www.maa.org/sites/default/files/pdf/upload_library/22/Polya/07468342.di020786.02p0470a.pdf
+	var y, b, g, t Int
+	y.Add(&s, intOne)
+	y.Rsh(&y, 1)
+	y.Exp(x, &y, p)  // y = x^((s+1)/2)
+	b.Exp(x, &s, p)  // b = x^s
+	g.Exp(&n, &s, p) // g = n^s
+	r := e
+	for {
+		// find the least m such that ord_p(b) = 2^m
+		var m uint
+		t.Set(&b)
+		for t.Cmp(intOne) != 0 {
+			t.Mul(&t, &t).Mod(&t, p)
+			m++
+		}
+
+		if m == 0 {
+			return z.Set(&y)
+		}
+
+		t.SetInt64(0).SetBit(&t, int(r-m-1), 1).Exp(&g, &t, p)
+		// t = g^(2^(r-m-1)) mod p
+		g.Mul(&t, &t).Mod(&g, p) // g = g^(2^(r-m)) mod p
+		y.Mul(&y, &t).Mod(&y, p)
+		b.Mul(&b, &g).Mod(&b, p)
+		r = m
+	}
+}
+
 // Lsh sets z = x << n and returns z.
 func (z *Int) Lsh(x *Int, n uint) *Int {
 	z.abs = z.abs.shl(x.abs, n)
@@ -995,7 +932,7 @@
 	}
 	b := buf[0]
 	if b>>1 != intGobVersion {
-		return errors.New(fmt.Sprintf("Int.GobDecode: encoding version %d not supported", b>>1))
+		return fmt.Errorf("Int.GobDecode: encoding version %d not supported", b>>1)
 	}
 	z.neg = b&1 != 0
 	z.abs = z.abs.setBytes(buf[1:])
diff --git a/third_party/gofrontend/libgo/go/math/big/int_test.go b/third_party/gofrontend/libgo/go/math/big/int_test.go
index 2d762db..88c8c2b 100644
--- a/third_party/gofrontend/libgo/go/math/big/int_test.go
+++ b/third_party/gofrontend/libgo/go/math/big/int_test.go
@@ -219,334 +219,42 @@
 	}
 }
 
-var stringTests = []struct {
-	in   string
-	out  string
-	base int
-	val  int64
-	ok   bool
-}{
-	{in: "", ok: false},
-	{in: "a", ok: false},
-	{in: "z", ok: false},
-	{in: "+", ok: false},
-	{in: "-", ok: false},
-	{in: "0b", ok: false},
-	{in: "0x", ok: false},
-	{in: "2", base: 2, ok: false},
-	{in: "0b2", base: 0, ok: false},
-	{in: "08", ok: false},
-	{in: "8", base: 8, ok: false},
-	{in: "0xg", base: 0, ok: false},
-	{in: "g", base: 16, ok: false},
-	{"0", "0", 0, 0, true},
-	{"0", "0", 10, 0, true},
-	{"0", "0", 16, 0, true},
-	{"+0", "0", 0, 0, true},
-	{"-0", "0", 0, 0, true},
-	{"10", "10", 0, 10, true},
-	{"10", "10", 10, 10, true},
-	{"10", "10", 16, 16, true},
-	{"-10", "-10", 16, -16, true},
-	{"+10", "10", 16, 16, true},
-	{"0x10", "16", 0, 16, true},
-	{in: "0x10", base: 16, ok: false},
-	{"-0x10", "-16", 0, -16, true},
-	{"+0x10", "16", 0, 16, true},
-	{"00", "0", 0, 0, true},
-	{"0", "0", 8, 0, true},
-	{"07", "7", 0, 7, true},
-	{"7", "7", 8, 7, true},
-	{"023", "19", 0, 19, true},
-	{"23", "23", 8, 19, true},
-	{"cafebabe", "cafebabe", 16, 0xcafebabe, true},
-	{"0b0", "0", 0, 0, true},
-	{"-111", "-111", 2, -7, true},
-	{"-0b111", "-7", 0, -7, true},
-	{"0b1001010111", "599", 0, 0x257, true},
-	{"1001010111", "1001010111", 2, 0x257, true},
-}
-
-func format(base int) string {
-	switch base {
-	case 2:
-		return "%b"
-	case 8:
-		return "%o"
-	case 16:
-		return "%x"
-	}
-	return "%d"
-}
-
-func TestGetString(t *testing.T) {
-	z := new(Int)
-	for i, test := range stringTests {
-		if !test.ok {
-			continue
-		}
-		z.SetInt64(test.val)
-
-		if test.base == 10 {
-			s := z.String()
-			if s != test.out {
-				t.Errorf("#%da got %s; want %s", i, s, test.out)
-			}
-		}
-
-		s := fmt.Sprintf(format(test.base), z)
-		if s != test.out {
-			t.Errorf("#%db got %s; want %s", i, s, test.out)
+func TestBinomial(t *testing.T) {
+	var z Int
+	for _, test := range []struct {
+		n, k int64
+		want string
+	}{
+		{0, 0, "1"},
+		{0, 1, "0"},
+		{1, 0, "1"},
+		{1, 1, "1"},
+		{1, 10, "0"},
+		{4, 0, "1"},
+		{4, 1, "4"},
+		{4, 2, "6"},
+		{4, 3, "4"},
+		{4, 4, "1"},
+		{10, 1, "10"},
+		{10, 9, "10"},
+		{10, 5, "252"},
+		{11, 5, "462"},
+		{11, 6, "462"},
+		{100, 10, "17310309456440"},
+		{100, 90, "17310309456440"},
+		{1000, 10, "263409560461970212832400"},
+		{1000, 990, "263409560461970212832400"},
+	} {
+		if got := z.Binomial(test.n, test.k).String(); got != test.want {
+			t.Errorf("Binomial(%d, %d) = %s; want %s", test.n, test.k, got, test.want)
 		}
 	}
 }
 
-func TestSetString(t *testing.T) {
-	tmp := new(Int)
-	for i, test := range stringTests {
-		// initialize to a non-zero value so that issues with parsing
-		// 0 are detected
-		tmp.SetInt64(1234567890)
-		n1, ok1 := new(Int).SetString(test.in, test.base)
-		n2, ok2 := tmp.SetString(test.in, test.base)
-		expected := NewInt(test.val)
-		if ok1 != test.ok || ok2 != test.ok {
-			t.Errorf("#%d (input '%s') ok incorrect (should be %t)", i, test.in, test.ok)
-			continue
-		}
-		if !ok1 {
-			if n1 != nil {
-				t.Errorf("#%d (input '%s') n1 != nil", i, test.in)
-			}
-			continue
-		}
-		if !ok2 {
-			if n2 != nil {
-				t.Errorf("#%d (input '%s') n2 != nil", i, test.in)
-			}
-			continue
-		}
-
-		if ok1 && !isNormalized(n1) {
-			t.Errorf("#%d (input '%s'): %v is not normalized", i, test.in, *n1)
-		}
-		if ok2 && !isNormalized(n2) {
-			t.Errorf("#%d (input '%s'): %v is not normalized", i, test.in, *n2)
-		}
-
-		if n1.Cmp(expected) != 0 {
-			t.Errorf("#%d (input '%s') got: %s want: %d", i, test.in, n1, test.val)
-		}
-		if n2.Cmp(expected) != 0 {
-			t.Errorf("#%d (input '%s') got: %s want: %d", i, test.in, n2, test.val)
-		}
-	}
-}
-
-var formatTests = []struct {
-	input  string
-	format string
-	output string
-}{
-	{"<nil>", "%x", "<nil>"},
-	{"<nil>", "%#x", "<nil>"},
-	{"<nil>", "%#y", "%!y(big.Int=<nil>)"},
-
-	{"10", "%b", "1010"},
-	{"10", "%o", "12"},
-	{"10", "%d", "10"},
-	{"10", "%v", "10"},
-	{"10", "%x", "a"},
-	{"10", "%X", "A"},
-	{"-10", "%X", "-A"},
-	{"10", "%y", "%!y(big.Int=10)"},
-	{"-10", "%y", "%!y(big.Int=-10)"},
-
-	{"10", "%#b", "1010"},
-	{"10", "%#o", "012"},
-	{"10", "%#d", "10"},
-	{"10", "%#v", "10"},
-	{"10", "%#x", "0xa"},
-	{"10", "%#X", "0XA"},
-	{"-10", "%#X", "-0XA"},
-	{"10", "%#y", "%!y(big.Int=10)"},
-	{"-10", "%#y", "%!y(big.Int=-10)"},
-
-	{"1234", "%d", "1234"},
-	{"1234", "%3d", "1234"},
-	{"1234", "%4d", "1234"},
-	{"-1234", "%d", "-1234"},
-	{"1234", "% 5d", " 1234"},
-	{"1234", "%+5d", "+1234"},
-	{"1234", "%-5d", "1234 "},
-	{"1234", "%x", "4d2"},
-	{"1234", "%X", "4D2"},
-	{"-1234", "%3x", "-4d2"},
-	{"-1234", "%4x", "-4d2"},
-	{"-1234", "%5x", " -4d2"},
-	{"-1234", "%-5x", "-4d2 "},
-	{"1234", "%03d", "1234"},
-	{"1234", "%04d", "1234"},
-	{"1234", "%05d", "01234"},
-	{"1234", "%06d", "001234"},
-	{"-1234", "%06d", "-01234"},
-	{"1234", "%+06d", "+01234"},
-	{"1234", "% 06d", " 01234"},
-	{"1234", "%-6d", "1234  "},
-	{"1234", "%-06d", "1234  "},
-	{"-1234", "%-06d", "-1234 "},
-
-	{"1234", "%.3d", "1234"},
-	{"1234", "%.4d", "1234"},
-	{"1234", "%.5d", "01234"},
-	{"1234", "%.6d", "001234"},
-	{"-1234", "%.3d", "-1234"},
-	{"-1234", "%.4d", "-1234"},
-	{"-1234", "%.5d", "-01234"},
-	{"-1234", "%.6d", "-001234"},
-
-	{"1234", "%8.3d", "    1234"},
-	{"1234", "%8.4d", "    1234"},
-	{"1234", "%8.5d", "   01234"},
-	{"1234", "%8.6d", "  001234"},
-	{"-1234", "%8.3d", "   -1234"},
-	{"-1234", "%8.4d", "   -1234"},
-	{"-1234", "%8.5d", "  -01234"},
-	{"-1234", "%8.6d", " -001234"},
-
-	{"1234", "%+8.3d", "   +1234"},
-	{"1234", "%+8.4d", "   +1234"},
-	{"1234", "%+8.5d", "  +01234"},
-	{"1234", "%+8.6d", " +001234"},
-	{"-1234", "%+8.3d", "   -1234"},
-	{"-1234", "%+8.4d", "   -1234"},
-	{"-1234", "%+8.5d", "  -01234"},
-	{"-1234", "%+8.6d", " -001234"},
-
-	{"1234", "% 8.3d", "    1234"},
-	{"1234", "% 8.4d", "    1234"},
-	{"1234", "% 8.5d", "   01234"},
-	{"1234", "% 8.6d", "  001234"},
-	{"-1234", "% 8.3d", "   -1234"},
-	{"-1234", "% 8.4d", "   -1234"},
-	{"-1234", "% 8.5d", "  -01234"},
-	{"-1234", "% 8.6d", " -001234"},
-
-	{"1234", "%.3x", "4d2"},
-	{"1234", "%.4x", "04d2"},
-	{"1234", "%.5x", "004d2"},
-	{"1234", "%.6x", "0004d2"},
-	{"-1234", "%.3x", "-4d2"},
-	{"-1234", "%.4x", "-04d2"},
-	{"-1234", "%.5x", "-004d2"},
-	{"-1234", "%.6x", "-0004d2"},
-
-	{"1234", "%8.3x", "     4d2"},
-	{"1234", "%8.4x", "    04d2"},
-	{"1234", "%8.5x", "   004d2"},
-	{"1234", "%8.6x", "  0004d2"},
-	{"-1234", "%8.3x", "    -4d2"},
-	{"-1234", "%8.4x", "   -04d2"},
-	{"-1234", "%8.5x", "  -004d2"},
-	{"-1234", "%8.6x", " -0004d2"},
-
-	{"1234", "%+8.3x", "    +4d2"},
-	{"1234", "%+8.4x", "   +04d2"},
-	{"1234", "%+8.5x", "  +004d2"},
-	{"1234", "%+8.6x", " +0004d2"},
-	{"-1234", "%+8.3x", "    -4d2"},
-	{"-1234", "%+8.4x", "   -04d2"},
-	{"-1234", "%+8.5x", "  -004d2"},
-	{"-1234", "%+8.6x", " -0004d2"},
-
-	{"1234", "% 8.3x", "     4d2"},
-	{"1234", "% 8.4x", "    04d2"},
-	{"1234", "% 8.5x", "   004d2"},
-	{"1234", "% 8.6x", "  0004d2"},
-	{"1234", "% 8.7x", " 00004d2"},
-	{"1234", "% 8.8x", " 000004d2"},
-	{"-1234", "% 8.3x", "    -4d2"},
-	{"-1234", "% 8.4x", "   -04d2"},
-	{"-1234", "% 8.5x", "  -004d2"},
-	{"-1234", "% 8.6x", " -0004d2"},
-	{"-1234", "% 8.7x", "-00004d2"},
-	{"-1234", "% 8.8x", "-000004d2"},
-
-	{"1234", "%-8.3d", "1234    "},
-	{"1234", "%-8.4d", "1234    "},
-	{"1234", "%-8.5d", "01234   "},
-	{"1234", "%-8.6d", "001234  "},
-	{"1234", "%-8.7d", "0001234 "},
-	{"1234", "%-8.8d", "00001234"},
-	{"-1234", "%-8.3d", "-1234   "},
-	{"-1234", "%-8.4d", "-1234   "},
-	{"-1234", "%-8.5d", "-01234  "},
-	{"-1234", "%-8.6d", "-001234 "},
-	{"-1234", "%-8.7d", "-0001234"},
-	{"-1234", "%-8.8d", "-00001234"},
-
-	{"16777215", "%b", "111111111111111111111111"}, // 2**24 - 1
-
-	{"0", "%.d", ""},
-	{"0", "%.0d", ""},
-	{"0", "%3.d", ""},
-}
-
-func TestFormat(t *testing.T) {
-	for i, test := range formatTests {
-		var x *Int
-		if test.input != "<nil>" {
-			var ok bool
-			x, ok = new(Int).SetString(test.input, 0)
-			if !ok {
-				t.Errorf("#%d failed reading input %s", i, test.input)
-			}
-		}
-		output := fmt.Sprintf(test.format, x)
-		if output != test.output {
-			t.Errorf("#%d got %q; want %q, {%q, %q, %q}", i, output, test.output, test.input, test.format, test.output)
-		}
-	}
-}
-
-var scanTests = []struct {
-	input     string
-	format    string
-	output    string
-	remaining int
-}{
-	{"1010", "%b", "10", 0},
-	{"0b1010", "%v", "10", 0},
-	{"12", "%o", "10", 0},
-	{"012", "%v", "10", 0},
-	{"10", "%d", "10", 0},
-	{"10", "%v", "10", 0},
-	{"a", "%x", "10", 0},
-	{"0xa", "%v", "10", 0},
-	{"A", "%X", "10", 0},
-	{"-A", "%X", "-10", 0},
-	{"+0b1011001", "%v", "89", 0},
-	{"0xA", "%v", "10", 0},
-	{"0 ", "%v", "0", 1},
-	{"2+3", "%v", "2", 2},
-	{"0XABC 12", "%v", "2748", 3},
-}
-
-func TestScan(t *testing.T) {
-	var buf bytes.Buffer
-	for i, test := range scanTests {
-		x := new(Int)
-		buf.Reset()
-		buf.WriteString(test.input)
-		if _, err := fmt.Fscanf(&buf, test.format, x); err != nil {
-			t.Errorf("#%d error: %s", i, err)
-		}
-		if x.String() != test.output {
-			t.Errorf("#%d got %s; want %s", i, x.String(), test.output)
-		}
-		if buf.Len() != test.remaining {
-			t.Errorf("#%d got %d bytes remaining; want %d", i, buf.Len(), test.remaining)
-		}
+func BenchmarkBinomial(b *testing.B) {
+	var z Int
+	for i := b.N - 1; i >= 0; i-- {
+		z.Binomial(1000, 990)
 	}
 }
 
@@ -621,6 +329,42 @@
 	}
 }
 
+func norm(x nat) nat {
+	i := len(x)
+	for i > 0 && x[i-1] == 0 {
+		i--
+	}
+	return x[:i]
+}
+
+func TestBits(t *testing.T) {
+	for _, test := range []nat{
+		nil,
+		{0},
+		{1},
+		{0, 1, 2, 3, 4},
+		{4, 3, 2, 1, 0},
+		{4, 3, 2, 1, 0, 0, 0, 0},
+	} {
+		var z Int
+		z.neg = true
+		got := z.SetBits(test)
+		want := norm(test)
+		if got.abs.cmp(want) != 0 {
+			t.Errorf("SetBits(%v) = %v; want %v", test, got.abs, want)
+		}
+
+		if got.neg {
+			t.Errorf("SetBits(%v): got negative result", test)
+		}
+
+		bits := nat(z.Bits())
+		if bits.cmp(want) != 0 {
+			t.Errorf("%v.Bits() = %v; want %v", z.abs, bits, want)
+		}
+	}
+}
+
 func checkSetBytes(b []byte) bool {
 	hex1 := hex.EncodeToString(new(Int).SetBytes(b).Bytes())
 	hex2 := hex.EncodeToString(b)
@@ -648,7 +392,7 @@
 }
 
 func TestBytes(t *testing.T) {
-	if err := quick.Check(checkSetBytes, nil); err != nil {
+	if err := quick.Check(checkBytes, nil); err != nil {
 		t.Error(err)
 	}
 }
@@ -781,6 +525,7 @@
 	{"1234", "-1", "1", "0"},
 
 	// misc
+	{"5", "1", "3", "2"},
 	{"5", "-7", "", "1"},
 	{"-5", "-7", "", "1"},
 	{"5", "0", "", "1"},
@@ -917,6 +662,21 @@
 	if D.Cmp(d) != 0 {
 		t.Errorf("binaryGcd(%s, %s): got d = %s, want %s", a, b, D, d)
 	}
+
+	// check results in presence of aliasing (issue #11284)
+	a2 := new(Int).Set(a)
+	b2 := new(Int).Set(b)
+	a2.binaryGCD(a2, b2) // result is same as 1st argument
+	if a2.Cmp(d) != 0 {
+		t.Errorf("binaryGcd(%s, %s): got d = %s, want %s", a, b, a2, d)
+	}
+
+	a2 = new(Int).Set(a)
+	b2 = new(Int).Set(b)
+	b2.binaryGCD(a2, b2) // result is same as 2nd argument
+	if b2.Cmp(d) != 0 {
+		t.Errorf("binaryGcd(%s, %s): got d = %s, want %s", a, b, b2, d)
+	}
 }
 
 func TestGcd(t *testing.T) {
@@ -948,7 +708,7 @@
 	"10953742525620032441",
 	"17908251027575790097",
 
-	// http://code.google.com/p/go/issues/detail?id=638
+	// https://golang.org/issue/638
 	"18699199384836356663",
 
 	"98920366548084643601728869055592650835572950932266967461790948584315647051443",
@@ -959,9 +719,18 @@
 	"230975859993204150666423538988557839555560243929065415434980904258310530753006723857139742334640122533598517597674807096648905501653461687601339782814316124971547968912893214002992086353183070342498989426570593",
 	"5521712099665906221540423207019333379125265462121169655563495403888449493493629943498064604536961775110765377745550377067893607246020694972959780839151452457728855382113555867743022746090187341871655890805971735385789993",
 	"203956878356401977405765866929034577280193993314348263094772646453283062722701277632936616063144088173312372882677123879538709400158306567338328279154499698366071906766440037074217117805690872792848149112022286332144876183376326512083574821647933992961249917319836219304274280243803104015000563790123",
+
+	// ECC primes: http://tools.ietf.org/html/draft-ladd-safecurves-02
+	"3618502788666131106986593281521497120414687020801267626233049500247285301239",                                                                                  // Curve1174: 2^251-9
+	"57896044618658097711785492504343953926634992332820282019728792003956564819949",                                                                                 // Curve25519: 2^255-19
+	"9850501549098619803069760025035903451269934817616361666987073351061430442874302652853566563721228910201656997576599",                                           // E-382: 2^382-105
+	"42307582002575910332922579714097346549017899709713998034217522897561970639123926132812109468141778230245837569601494931472367",                                 // Curve41417: 2^414-17
+	"6864797660130609714981900799081393217269435300143305409394463459185543183397656052122559640661454554977296311391480858037121987999716643812574028291115057151", // E-521: 2^521-1
 }
 
 var composites = []string{
+	"0",
+	"1",
 	"21284175091214687912771199898307297748211672914763848041968395774954376176754",
 	"6084766654921918907427900243509372380954290099172559290432744450051395395951",
 	"84594350493221918389213352992032324280367711247940675652888030554255915464401",
@@ -989,6 +758,21 @@
 			break
 		}
 	}
+
+	// check that ProbablyPrime panics if n <= 0
+	c := NewInt(11) // a prime
+	for _, n := range []int{-1, 0, 1} {
+		func() {
+			defer func() {
+				if n <= 0 && recover() == nil {
+					t.Fatalf("expected panic from ProbablyPrime(%d)", n)
+				}
+			}()
+			if !c.ProbablyPrime(n) {
+				t.Fatalf("%v should be a prime", c)
+			}
+		}()
+	}
 }
 
 type intShiftTest struct {
@@ -1487,6 +1271,136 @@
 	}
 }
 
+// testModSqrt is a helper for TestModSqrt,
+// which checks that ModSqrt can compute a square-root of elt^2.
+func testModSqrt(t *testing.T, elt, mod, sq, sqrt *Int) bool {
+	var sqChk, sqrtChk, sqrtsq Int
+	sq.Mul(elt, elt)
+	sq.Mod(sq, mod)
+	z := sqrt.ModSqrt(sq, mod)
+	if z != sqrt {
+		t.Errorf("ModSqrt returned wrong value %s", z)
+	}
+
+	// test ModSqrt arguments outside the range [0,mod)
+	sqChk.Add(sq, mod)
+	z = sqrtChk.ModSqrt(&sqChk, mod)
+	if z != &sqrtChk || z.Cmp(sqrt) != 0 {
+		t.Errorf("ModSqrt returned inconsistent value %s", z)
+	}
+	sqChk.Sub(sq, mod)
+	z = sqrtChk.ModSqrt(&sqChk, mod)
+	if z != &sqrtChk || z.Cmp(sqrt) != 0 {
+		t.Errorf("ModSqrt returned inconsistent value %s", z)
+	}
+
+	// make sure we actually got a square root
+	if sqrt.Cmp(elt) == 0 {
+		return true // we found the "desired" square root
+	}
+	sqrtsq.Mul(sqrt, sqrt) // make sure we found the "other" one
+	sqrtsq.Mod(&sqrtsq, mod)
+	return sq.Cmp(&sqrtsq) == 0
+}
+
+func TestModSqrt(t *testing.T) {
+	var elt, mod, modx4, sq, sqrt Int
+	r := rand.New(rand.NewSource(9))
+	for i, s := range primes[1:] { // skip 2, use only odd primes
+		mod.SetString(s, 10)
+		modx4.Lsh(&mod, 2)
+
+		// test a few random elements per prime
+		for x := 1; x < 5; x++ {
+			elt.Rand(r, &modx4)
+			elt.Sub(&elt, &mod) // test range [-mod, 3*mod)
+			if !testModSqrt(t, &elt, &mod, &sq, &sqrt) {
+				t.Errorf("#%d: failed (sqrt(e) = %s)", i, &sqrt)
+			}
+		}
+	}
+
+	// exhaustive test for small values
+	for n := 3; n < 100; n++ {
+		mod.SetInt64(int64(n))
+		if !mod.ProbablyPrime(10) {
+			continue
+		}
+		isSquare := make([]bool, n)
+
+		// test all the squares
+		for x := 1; x < n; x++ {
+			elt.SetInt64(int64(x))
+			if !testModSqrt(t, &elt, &mod, &sq, &sqrt) {
+				t.Errorf("#%d: failed (sqrt(%d,%d) = %s)", x, &elt, &mod, &sqrt)
+			}
+			isSquare[sq.Uint64()] = true
+		}
+
+		// test all non-squares
+		for x := 1; x < n; x++ {
+			sq.SetInt64(int64(x))
+			z := sqrt.ModSqrt(&sq, &mod)
+			if !isSquare[x] && z != nil {
+				t.Errorf("#%d: failed (sqrt(%d,%d) = nil)", x, &sqrt, &mod)
+			}
+		}
+	}
+}
+
+func TestJacobi(t *testing.T) {
+	testCases := []struct {
+		x, y   int64
+		result int
+	}{
+		{0, 1, 1},
+		{0, -1, 1},
+		{1, 1, 1},
+		{1, -1, 1},
+		{0, 5, 0},
+		{1, 5, 1},
+		{2, 5, -1},
+		{-2, 5, -1},
+		{2, -5, -1},
+		{-2, -5, 1},
+		{3, 5, -1},
+		{5, 5, 0},
+		{-5, 5, 0},
+		{6, 5, 1},
+		{6, -5, 1},
+		{-6, 5, 1},
+		{-6, -5, -1},
+	}
+
+	var x, y Int
+
+	for i, test := range testCases {
+		x.SetInt64(test.x)
+		y.SetInt64(test.y)
+		expected := test.result
+		actual := Jacobi(&x, &y)
+		if actual != expected {
+			t.Errorf("#%d: Jacobi(%d, %d) = %d, but expected %d", i, test.x, test.y, actual, expected)
+		}
+	}
+}
+
+func TestJacobiPanic(t *testing.T) {
+	const failureMsg = "test failure"
+	defer func() {
+		msg := recover()
+		if msg == nil || msg == failureMsg {
+			panic(msg)
+		}
+		t.Log(msg)
+	}()
+	x := NewInt(1)
+	y := NewInt(2)
+	// Jacobi should panic when the second argument is even.
+	Jacobi(x, y)
+	panic(failureMsg)
+}
+
 var encodingTests = []string{
 	"-539345864568634858364538753846587364875430589374589",
 	"-678645873",
diff --git a/third_party/gofrontend/libgo/go/math/big/intconv.go b/third_party/gofrontend/libgo/go/math/big/intconv.go
new file mode 100644
index 0000000..9c68a22
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/math/big/intconv.go
@@ -0,0 +1,228 @@
+// 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.
+
+// This file implements int-to-string conversion functions.
+
+package big
+
+import (
+	"errors"
+	"fmt"
+	"io"
+)
+
+func (x *Int) String() string {
+	switch {
+	case x == nil:
+		return "<nil>"
+	case x.neg:
+		return "-" + x.abs.decimalString()
+	}
+	return x.abs.decimalString()
+}
+
+func charset(ch rune) string {
+	switch ch {
+	case 'b':
+		return lowercaseDigits[0:2]
+	case 'o':
+		return lowercaseDigits[0:8]
+	case 'd', 's', 'v':
+		return lowercaseDigits[0:10]
+	case 'x':
+		return lowercaseDigits[0:16]
+	case 'X':
+		return uppercaseDigits[0:16]
+	}
+	return "" // unknown format
+}
+
+// write count copies of text to s
+func writeMultiple(s fmt.State, text string, count int) {
+	if len(text) > 0 {
+		b := []byte(text)
+		for ; count > 0; count-- {
+			s.Write(b)
+		}
+	}
+}
+
+// Format is a support routine for fmt.Formatter. It accepts
+// the formats 'b' (binary), 'o' (octal), 'd' (decimal), 'x'
+// (lowercase hexadecimal), and 'X' (uppercase hexadecimal).
+// Also supported are the full suite of package fmt's format
+// verbs for integral types, including '+', '-', and ' '
+// for sign control, '#' for leading zero in octal and for
+// hexadecimal, a leading "0x" or "0X" for "%#x" and "%#X"
+// respectively, specification of minimum digits precision,
+// output field width, space or zero padding, and left or
+// right justification.
+//
+func (x *Int) Format(s fmt.State, ch rune) {
+	cs := charset(ch)
+
+	// special cases
+	switch {
+	case cs == "":
+		// unknown format
+		fmt.Fprintf(s, "%%!%c(big.Int=%s)", ch, x.String())
+		return
+	case x == nil:
+		fmt.Fprint(s, "<nil>")
+		return
+	}
+
+	// determine sign character
+	sign := ""
+	switch {
+	case x.neg:
+		sign = "-"
+	case s.Flag('+'): // supersedes ' ' when both specified
+		sign = "+"
+	case s.Flag(' '):
+		sign = " "
+	}
+
+	// determine prefix characters for indicating output base
+	prefix := ""
+	if s.Flag('#') {
+		switch ch {
+		case 'o': // octal
+			prefix = "0"
+		case 'x': // hexadecimal
+			prefix = "0x"
+		case 'X':
+			prefix = "0X"
+		}
+	}
+
+	// determine digits with base set by len(cs) and digit characters from cs
+	digits := x.abs.string(cs)
+
+	// number of characters for the three classes of number padding
+	var left int   // space characters to left of digits for right justification ("%8d")
+	var zeroes int // zero characters (actually cs[0]) as left-most digits ("%.8d")
+	var right int  // space characters to right of digits for left justification ("%-8d")
+
+	// determine number padding from precision: the least number of digits to output
+	precision, precisionSet := s.Precision()
+	if precisionSet {
+		switch {
+		case len(digits) < precision:
+			zeroes = precision - len(digits) // count of zero padding
+		case digits == "0" && precision == 0:
+			return // print nothing if zero value (x == 0) and zero precision ("." or ".0")
+		}
+	}
+
+	// determine field pad from width: the least number of characters to output
+	length := len(sign) + len(prefix) + zeroes + len(digits)
+	if width, widthSet := s.Width(); widthSet && length < width { // pad as specified
+		switch d := width - length; {
+		case s.Flag('-'):
+			// pad on the right with spaces; supersedes '0' when both specified
+			right = d
+		case s.Flag('0') && !precisionSet:
+			// pad with zeroes unless precision also specified
+			zeroes = d
+		default:
+			// pad on the left with spaces
+			left = d
+		}
+	}
+
+	// print number as [left pad][sign][prefix][zero pad][digits][right pad]
+	writeMultiple(s, " ", left)
+	writeMultiple(s, sign, 1)
+	writeMultiple(s, prefix, 1)
+	writeMultiple(s, "0", zeroes)
+	writeMultiple(s, digits, 1)
+	writeMultiple(s, " ", right)
+}
+
+// scan sets z to the integer value corresponding to the longest possible prefix
+// read from r representing a signed integer number in a given conversion base.
+// It returns z, the actual conversion base used, and an error, if any. In the
+// error case, the value of z is undefined but the returned value is nil. The
+// syntax follows the syntax of integer literals in Go.
+//
+// The base argument must be 0 or a value from 2 through MaxBase. If the base
+// is 0, the string prefix determines the actual conversion base. A prefix of
+// ``0x'' or ``0X'' selects base 16; the ``0'' prefix selects base 8, and a
+// ``0b'' or ``0B'' prefix selects base 2. Otherwise the selected base is 10.
+//
+func (z *Int) scan(r io.ByteScanner, base int) (*Int, int, error) {
+	// determine sign
+	neg, err := scanSign(r)
+	if err != nil {
+		return nil, 0, err
+	}
+
+	// determine mantissa
+	z.abs, base, _, err = z.abs.scan(r, base, false)
+	if err != nil {
+		return nil, base, err
+	}
+	z.neg = len(z.abs) > 0 && neg // 0 has no sign
+
+	return z, base, nil
+}
+
+func scanSign(r io.ByteScanner) (neg bool, err error) {
+	var ch byte
+	if ch, err = r.ReadByte(); err != nil {
+		return false, err
+	}
+	switch ch {
+	case '-':
+		neg = true
+	case '+':
+		// nothing to do
+	default:
+		r.UnreadByte()
+	}
+	return
+}
+
+// byteReader is a local wrapper around fmt.ScanState;
+// it implements the ByteReader interface.
+type byteReader struct {
+	fmt.ScanState
+}
+
+func (r byteReader) ReadByte() (byte, error) {
+	ch, size, err := r.ReadRune()
+	if size != 1 && err == nil {
+		err = fmt.Errorf("invalid rune %#U", ch)
+	}
+	return byte(ch), err
+}
+
+func (r byteReader) UnreadByte() error {
+	return r.UnreadRune()
+}
+
+// Scan is a support routine for fmt.Scanner; it sets z to the value of
+// the scanned number. It accepts the formats 'b' (binary), 'o' (octal),
+// 'd' (decimal), 'x' (lowercase hexadecimal), and 'X' (uppercase hexadecimal).
+func (z *Int) Scan(s fmt.ScanState, ch rune) error {
+	s.SkipSpace() // skip leading space characters
+	base := 0
+	switch ch {
+	case 'b':
+		base = 2
+	case 'o':
+		base = 8
+	case 'd':
+		base = 10
+	case 'x', 'X':
+		base = 16
+	case 's', 'v':
+		// let scan determine the base
+	default:
+		return errors.New("Int.Scan: invalid verb")
+	}
+	_, _, err := z.scan(byteReader{s}, base)
+	return err
+}
diff --git a/third_party/gofrontend/libgo/go/math/big/intconv_test.go b/third_party/gofrontend/libgo/go/math/big/intconv_test.go
new file mode 100644
index 0000000..2deb84b
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/math/big/intconv_test.go
@@ -0,0 +1,342 @@
+// 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 big
+
+import (
+	"bytes"
+	"fmt"
+	"testing"
+)
+
+var stringTests = []struct {
+	in   string
+	out  string
+	base int
+	val  int64
+	ok   bool
+}{
+	{in: "", ok: false},
+	{in: "a", ok: false},
+	{in: "z", ok: false},
+	{in: "+", ok: false},
+	{in: "-", ok: false},
+	{in: "0b", ok: false},
+	{in: "0x", ok: false},
+	{in: "2", base: 2, ok: false},
+	{in: "0b2", base: 0, ok: false},
+	{in: "08", ok: false},
+	{in: "8", base: 8, ok: false},
+	{in: "0xg", base: 0, ok: false},
+	{in: "g", base: 16, ok: false},
+	{"0", "0", 0, 0, true},
+	{"0", "0", 10, 0, true},
+	{"0", "0", 16, 0, true},
+	{"+0", "0", 0, 0, true},
+	{"-0", "0", 0, 0, true},
+	{"10", "10", 0, 10, true},
+	{"10", "10", 10, 10, true},
+	{"10", "10", 16, 16, true},
+	{"-10", "-10", 16, -16, true},
+	{"+10", "10", 16, 16, true},
+	{"0x10", "16", 0, 16, true},
+	{in: "0x10", base: 16, ok: false},
+	{"-0x10", "-16", 0, -16, true},
+	{"+0x10", "16", 0, 16, true},
+	{"00", "0", 0, 0, true},
+	{"0", "0", 8, 0, true},
+	{"07", "7", 0, 7, true},
+	{"7", "7", 8, 7, true},
+	{"023", "19", 0, 19, true},
+	{"23", "23", 8, 19, true},
+	{"cafebabe", "cafebabe", 16, 0xcafebabe, true},
+	{"0b0", "0", 0, 0, true},
+	{"-111", "-111", 2, -7, true},
+	{"-0b111", "-7", 0, -7, true},
+	{"0b1001010111", "599", 0, 0x257, true},
+	{"1001010111", "1001010111", 2, 0x257, true},
+}
+
+func format(base int) string {
+	switch base {
+	case 2:
+		return "%b"
+	case 8:
+		return "%o"
+	case 16:
+		return "%x"
+	}
+	return "%d"
+}
+
+func TestGetString(t *testing.T) {
+	z := new(Int)
+	for i, test := range stringTests {
+		if !test.ok {
+			continue
+		}
+		z.SetInt64(test.val)
+
+		if test.base == 10 {
+			s := z.String()
+			if s != test.out {
+				t.Errorf("#%da got %s; want %s", i, s, test.out)
+			}
+		}
+
+		s := fmt.Sprintf(format(test.base), z)
+		if s != test.out {
+			t.Errorf("#%db got %s; want %s", i, s, test.out)
+		}
+	}
+}
+
+func TestSetString(t *testing.T) {
+	tmp := new(Int)
+	for i, test := range stringTests {
+		// initialize to a non-zero value so that issues with parsing
+		// 0 are detected
+		tmp.SetInt64(1234567890)
+		n1, ok1 := new(Int).SetString(test.in, test.base)
+		n2, ok2 := tmp.SetString(test.in, test.base)
+		expected := NewInt(test.val)
+		if ok1 != test.ok || ok2 != test.ok {
+			t.Errorf("#%d (input '%s') ok incorrect (should be %t)", i, test.in, test.ok)
+			continue
+		}
+		if !ok1 {
+			if n1 != nil {
+				t.Errorf("#%d (input '%s') n1 != nil", i, test.in)
+			}
+			continue
+		}
+		if !ok2 {
+			if n2 != nil {
+				t.Errorf("#%d (input '%s') n2 != nil", i, test.in)
+			}
+			continue
+		}
+
+		if ok1 && !isNormalized(n1) {
+			t.Errorf("#%d (input '%s'): %v is not normalized", i, test.in, *n1)
+		}
+		if ok2 && !isNormalized(n2) {
+			t.Errorf("#%d (input '%s'): %v is not normalized", i, test.in, *n2)
+		}
+
+		if n1.Cmp(expected) != 0 {
+			t.Errorf("#%d (input '%s') got: %s want: %d", i, test.in, n1, test.val)
+		}
+		if n2.Cmp(expected) != 0 {
+			t.Errorf("#%d (input '%s') got: %s want: %d", i, test.in, n2, test.val)
+		}
+	}
+}
+
+var formatTests = []struct {
+	input  string
+	format string
+	output string
+}{
+	{"<nil>", "%x", "<nil>"},
+	{"<nil>", "%#x", "<nil>"},
+	{"<nil>", "%#y", "%!y(big.Int=<nil>)"},
+
+	{"10", "%b", "1010"},
+	{"10", "%o", "12"},
+	{"10", "%d", "10"},
+	{"10", "%v", "10"},
+	{"10", "%x", "a"},
+	{"10", "%X", "A"},
+	{"-10", "%X", "-A"},
+	{"10", "%y", "%!y(big.Int=10)"},
+	{"-10", "%y", "%!y(big.Int=-10)"},
+
+	{"10", "%#b", "1010"},
+	{"10", "%#o", "012"},
+	{"10", "%#d", "10"},
+	{"10", "%#v", "10"},
+	{"10", "%#x", "0xa"},
+	{"10", "%#X", "0XA"},
+	{"-10", "%#X", "-0XA"},
+	{"10", "%#y", "%!y(big.Int=10)"},
+	{"-10", "%#y", "%!y(big.Int=-10)"},
+
+	{"1234", "%d", "1234"},
+	{"1234", "%3d", "1234"},
+	{"1234", "%4d", "1234"},
+	{"-1234", "%d", "-1234"},
+	{"1234", "% 5d", " 1234"},
+	{"1234", "%+5d", "+1234"},
+	{"1234", "%-5d", "1234 "},
+	{"1234", "%x", "4d2"},
+	{"1234", "%X", "4D2"},
+	{"-1234", "%3x", "-4d2"},
+	{"-1234", "%4x", "-4d2"},
+	{"-1234", "%5x", " -4d2"},
+	{"-1234", "%-5x", "-4d2 "},
+	{"1234", "%03d", "1234"},
+	{"1234", "%04d", "1234"},
+	{"1234", "%05d", "01234"},
+	{"1234", "%06d", "001234"},
+	{"-1234", "%06d", "-01234"},
+	{"1234", "%+06d", "+01234"},
+	{"1234", "% 06d", " 01234"},
+	{"1234", "%-6d", "1234  "},
+	{"1234", "%-06d", "1234  "},
+	{"-1234", "%-06d", "-1234 "},
+
+	{"1234", "%.3d", "1234"},
+	{"1234", "%.4d", "1234"},
+	{"1234", "%.5d", "01234"},
+	{"1234", "%.6d", "001234"},
+	{"-1234", "%.3d", "-1234"},
+	{"-1234", "%.4d", "-1234"},
+	{"-1234", "%.5d", "-01234"},
+	{"-1234", "%.6d", "-001234"},
+
+	{"1234", "%8.3d", "    1234"},
+	{"1234", "%8.4d", "    1234"},
+	{"1234", "%8.5d", "   01234"},
+	{"1234", "%8.6d", "  001234"},
+	{"-1234", "%8.3d", "   -1234"},
+	{"-1234", "%8.4d", "   -1234"},
+	{"-1234", "%8.5d", "  -01234"},
+	{"-1234", "%8.6d", " -001234"},
+
+	{"1234", "%+8.3d", "   +1234"},
+	{"1234", "%+8.4d", "   +1234"},
+	{"1234", "%+8.5d", "  +01234"},
+	{"1234", "%+8.6d", " +001234"},
+	{"-1234", "%+8.3d", "   -1234"},
+	{"-1234", "%+8.4d", "   -1234"},
+	{"-1234", "%+8.5d", "  -01234"},
+	{"-1234", "%+8.6d", " -001234"},
+
+	{"1234", "% 8.3d", "    1234"},
+	{"1234", "% 8.4d", "    1234"},
+	{"1234", "% 8.5d", "   01234"},
+	{"1234", "% 8.6d", "  001234"},
+	{"-1234", "% 8.3d", "   -1234"},
+	{"-1234", "% 8.4d", "   -1234"},
+	{"-1234", "% 8.5d", "  -01234"},
+	{"-1234", "% 8.6d", " -001234"},
+
+	{"1234", "%.3x", "4d2"},
+	{"1234", "%.4x", "04d2"},
+	{"1234", "%.5x", "004d2"},
+	{"1234", "%.6x", "0004d2"},
+	{"-1234", "%.3x", "-4d2"},
+	{"-1234", "%.4x", "-04d2"},
+	{"-1234", "%.5x", "-004d2"},
+	{"-1234", "%.6x", "-0004d2"},
+
+	{"1234", "%8.3x", "     4d2"},
+	{"1234", "%8.4x", "    04d2"},
+	{"1234", "%8.5x", "   004d2"},
+	{"1234", "%8.6x", "  0004d2"},
+	{"-1234", "%8.3x", "    -4d2"},
+	{"-1234", "%8.4x", "   -04d2"},
+	{"-1234", "%8.5x", "  -004d2"},
+	{"-1234", "%8.6x", " -0004d2"},
+
+	{"1234", "%+8.3x", "    +4d2"},
+	{"1234", "%+8.4x", "   +04d2"},
+	{"1234", "%+8.5x", "  +004d2"},
+	{"1234", "%+8.6x", " +0004d2"},
+	{"-1234", "%+8.3x", "    -4d2"},
+	{"-1234", "%+8.4x", "   -04d2"},
+	{"-1234", "%+8.5x", "  -004d2"},
+	{"-1234", "%+8.6x", " -0004d2"},
+
+	{"1234", "% 8.3x", "     4d2"},
+	{"1234", "% 8.4x", "    04d2"},
+	{"1234", "% 8.5x", "   004d2"},
+	{"1234", "% 8.6x", "  0004d2"},
+	{"1234", "% 8.7x", " 00004d2"},
+	{"1234", "% 8.8x", " 000004d2"},
+	{"-1234", "% 8.3x", "    -4d2"},
+	{"-1234", "% 8.4x", "   -04d2"},
+	{"-1234", "% 8.5x", "  -004d2"},
+	{"-1234", "% 8.6x", " -0004d2"},
+	{"-1234", "% 8.7x", "-00004d2"},
+	{"-1234", "% 8.8x", "-000004d2"},
+
+	{"1234", "%-8.3d", "1234    "},
+	{"1234", "%-8.4d", "1234    "},
+	{"1234", "%-8.5d", "01234   "},
+	{"1234", "%-8.6d", "001234  "},
+	{"1234", "%-8.7d", "0001234 "},
+	{"1234", "%-8.8d", "00001234"},
+	{"-1234", "%-8.3d", "-1234   "},
+	{"-1234", "%-8.4d", "-1234   "},
+	{"-1234", "%-8.5d", "-01234  "},
+	{"-1234", "%-8.6d", "-001234 "},
+	{"-1234", "%-8.7d", "-0001234"},
+	{"-1234", "%-8.8d", "-00001234"},
+
+	{"16777215", "%b", "111111111111111111111111"}, // 2**24 - 1
+
+	{"0", "%.d", ""},
+	{"0", "%.0d", ""},
+	{"0", "%3.d", ""},
+}
+
+func TestFormat(t *testing.T) {
+	for i, test := range formatTests {
+		var x *Int
+		if test.input != "<nil>" {
+			var ok bool
+			x, ok = new(Int).SetString(test.input, 0)
+			if !ok {
+				t.Errorf("#%d failed reading input %s", i, test.input)
+			}
+		}
+		output := fmt.Sprintf(test.format, x)
+		if output != test.output {
+			t.Errorf("#%d got %q; want %q, {%q, %q, %q}", i, output, test.output, test.input, test.format, test.output)
+		}
+	}
+}
+
+var scanTests = []struct {
+	input     string
+	format    string
+	output    string
+	remaining int
+}{
+	{"1010", "%b", "10", 0},
+	{"0b1010", "%v", "10", 0},
+	{"12", "%o", "10", 0},
+	{"012", "%v", "10", 0},
+	{"10", "%d", "10", 0},
+	{"10", "%v", "10", 0},
+	{"a", "%x", "10", 0},
+	{"0xa", "%v", "10", 0},
+	{"A", "%X", "10", 0},
+	{"-A", "%X", "-10", 0},
+	{"+0b1011001", "%v", "89", 0},
+	{"0xA", "%v", "10", 0},
+	{"0 ", "%v", "0", 1},
+	{"2+3", "%v", "2", 2},
+	{"0XABC 12", "%v", "2748", 3},
+}
+
+func TestScan(t *testing.T) {
+	var buf bytes.Buffer
+	for i, test := range scanTests {
+		x := new(Int)
+		buf.Reset()
+		buf.WriteString(test.input)
+		if _, err := fmt.Fscanf(&buf, test.format, x); err != nil {
+			t.Errorf("#%d error: %s", i, err)
+		}
+		if x.String() != test.output {
+			t.Errorf("#%d got %s; want %s", i, x.String(), test.output)
+		}
+		if buf.Len() != test.remaining {
+			t.Errorf("#%d got %d bytes remaining; want %d", i, buf.Len(), test.remaining)
+		}
+	}
+}
diff --git a/third_party/gofrontend/libgo/go/math/big/nat.go b/third_party/gofrontend/libgo/go/math/big/nat.go
index 16a87f5..6545bc1 100644
--- a/third_party/gofrontend/libgo/go/math/big/nat.go
+++ b/third_party/gofrontend/libgo/go/math/big/nat.go
@@ -5,18 +5,22 @@
 // Package big implements multi-precision arithmetic (big numbers).
 // The following numeric types are supported:
 //
-//	- Int	signed integers
-//	- Rat	rational numbers
+//   Int    signed integers
+//   Rat    rational numbers
+//   Float  floating-point numbers
 //
 // Methods are typically of the form:
 //
-//	func (z *Int) Op(x, y *Int) *Int	(similar for *Rat)
+//   func (z *T) Unary(x *T) *T        // z = op x
+//   func (z *T) Binary(x, y *T) *T    // z = x op y
+//   func (x *T) M() T1                // v = x.M()
 //
-// and implement operations z = x Op y with the result as receiver; if it
-// is one of the operands it may be overwritten (and its memory reused).
+// with T one of Int, Rat, or Float. For unary and binary operations, the
+// result is the receiver (usually named z in that case); if it is one of
+// the operands x or y it may be overwritten (and its memory reused).
 // To enable chaining of operations, the result is also returned. Methods
-// returning a result other than *Int or *Rat take one of the operands as
-// the receiver.
+// returning a result other than *Int, *Rat, or *Float take an operand as
+// the receiver (usually named x in that case).
 //
 package big
 
@@ -24,13 +28,7 @@
 // These are the building blocks for the operations on signed integers
 // and rationals.
 
-import (
-	"errors"
-	"io"
-	"math"
-	"math/rand"
-	"sync"
-)
+import "math/rand"
 
 // An unsigned integer x of the form
 //
@@ -68,7 +66,7 @@
 
 func (z nat) make(n int) nat {
 	if n <= cap(z) {
-		return z[0:n] // reuse z
+		return z[:n] // reuse z
 	}
 	// Choosing a good value for e has significant performance impact
 	// because it increases the chance that a value can be reused.
@@ -78,7 +76,7 @@
 
 func (z nat) setWord(x Word) nat {
 	if x == 0 {
-		return z.make(0)
+		return z[:0]
 	}
 	z = z.make(1)
 	z[0] = x
@@ -122,7 +120,7 @@
 		return z.add(y, x)
 	case m == 0:
 		// n == 0 because m >= n; result is 0
-		return z.make(0)
+		return z[:0]
 	case n == 0:
 		// result is x
 		return z.set(x)
@@ -148,7 +146,7 @@
 		panic("underflow")
 	case m == 0:
 		// n == 0 because m >= n; result is 0
-		return z.make(0)
+		return z[:0]
 	case n == 0:
 		// result is x
 		return z.set(x)
@@ -218,6 +216,34 @@
 	}
 }
 
+// montgomery computes x*y*2^(-n*_W) mod m,
+// assuming k = -1/m mod 2^_W.
+// z is used for storing the result which is returned;
+// z must not alias x, y or m.
+func (z nat) montgomery(x, y, m nat, k Word, n int) nat {
+	var c1, c2 Word
+	z = z.make(n)
+	z.clear()
+	for i := 0; i < n; i++ {
+		d := y[i]
+		c1 += addMulVVW(z, x, d)
+		t := z[0] * k
+		c2 = addMulVVW(z, m, t)
+
+		copy(z, z[1:])
+		z[n-1] = c1 + c2
+		if z[n-1] < c1 {
+			c1 = 1
+		} else {
+			c1 = 0
+		}
+	}
+	if c1 != 0 {
+		subVV(z, z, m)
+	}
+	return z
+}
+
 // Fast version of z[0:n+n>>1].add(z[0:n+n>>1], x[0:n]) w/o bounds checks.
 // Factored out for readability - do not use outside karatsuba.
 func karatsubaAdd(z, x nat, n int) {
@@ -337,7 +363,7 @@
 	}
 }
 
-// alias returns true if x and y share the same base array.
+// alias reports whether x and y share the same base array.
 func alias(x, y nat) bool {
 	return cap(x) > 0 && cap(y) > 0 && &x[0:cap(x)][cap(x)-1] == &y[0:cap(y)][cap(y)-1]
 }
@@ -384,7 +410,7 @@
 	case m < n:
 		return z.mul(y, x)
 	case m == 0 || n == 0:
-		return z.make(0)
+		return z[:0]
 	case n == 1:
 		return z.mulAddWW(x, y[0], 0)
 	}
@@ -488,7 +514,7 @@
 		q = z.set(x) // result is x
 		return
 	case m == 0:
-		q = z.make(0) // result is 0
+		q = z[:0] // result is 0
 		return
 	}
 	// m > 0
@@ -504,7 +530,7 @@
 	}
 
 	if u.cmp(v) < 0 {
-		q = z.make(0)
+		q = z[:0]
 		r = z2.set(u)
 		return
 	}
@@ -543,10 +569,10 @@
 		u = nil // u is an alias for uIn or v - cannot reuse
 	}
 	u = u.make(len(uIn) + 1)
-	u.clear()
+	u.clear() // TODO(gri) no need to clear if we allocated a new u
 
 	// D1.
-	shift := leadingZeros(v[n-1])
+	shift := nlz(v[n-1])
 	if shift > 0 {
 		// do not modify v, it may be used by another goroutine simultaneously
 		v1 := make(nat, n)
@@ -606,385 +632,6 @@
 	return 0
 }
 
-// MaxBase is the largest number base accepted for string conversions.
-const MaxBase = 'z' - 'a' + 10 + 1 // = hexValue('z') + 1
-
-func hexValue(ch rune) Word {
-	d := int(MaxBase + 1) // illegal base
-	switch {
-	case '0' <= ch && ch <= '9':
-		d = int(ch - '0')
-	case 'a' <= ch && ch <= 'z':
-		d = int(ch - 'a' + 10)
-	case 'A' <= ch && ch <= 'Z':
-		d = int(ch - 'A' + 10)
-	}
-	return Word(d)
-}
-
-// scan sets z to the natural number corresponding to the longest possible prefix
-// read from r representing an unsigned integer in a given conversion base.
-// It returns z, the actual conversion base used, and an error, if any. In the
-// error case, the value of z is undefined. The syntax follows the syntax of
-// unsigned integer literals in Go.
-//
-// The base argument must be 0 or a value from 2 through MaxBase. If the base
-// is 0, the string prefix determines the actual conversion base. A prefix of
-// ``0x'' or ``0X'' selects base 16; the ``0'' prefix selects base 8, and a
-// ``0b'' or ``0B'' prefix selects base 2. Otherwise the selected base is 10.
-//
-func (z nat) scan(r io.RuneScanner, base int) (nat, int, error) {
-	// reject illegal bases
-	if base < 0 || base == 1 || MaxBase < base {
-		return z, 0, errors.New("illegal number base")
-	}
-
-	// one char look-ahead
-	ch, _, err := r.ReadRune()
-	if err != nil {
-		return z, 0, err
-	}
-
-	// determine base if necessary
-	b := Word(base)
-	if base == 0 {
-		b = 10
-		if ch == '0' {
-			switch ch, _, err = r.ReadRune(); err {
-			case nil:
-				b = 8
-				switch ch {
-				case 'x', 'X':
-					b = 16
-				case 'b', 'B':
-					b = 2
-				}
-				if b == 2 || b == 16 {
-					if ch, _, err = r.ReadRune(); err != nil {
-						return z, 0, err
-					}
-				}
-			case io.EOF:
-				return z.make(0), 10, nil
-			default:
-				return z, 10, err
-			}
-		}
-	}
-
-	// convert string
-	// - group as many digits d as possible together into a "super-digit" dd with "super-base" bb
-	// - only when bb does not fit into a word anymore, do a full number mulAddWW using bb and dd
-	z = z.make(0)
-	bb := Word(1)
-	dd := Word(0)
-	for max := _M / b; ; {
-		d := hexValue(ch)
-		if d >= b {
-			r.UnreadRune() // ch does not belong to number anymore
-			break
-		}
-
-		if bb <= max {
-			bb *= b
-			dd = dd*b + d
-		} else {
-			// bb * b would overflow
-			z = z.mulAddWW(z, bb, dd)
-			bb = b
-			dd = d
-		}
-
-		if ch, _, err = r.ReadRune(); err != nil {
-			if err != io.EOF {
-				return z, int(b), err
-			}
-			break
-		}
-	}
-
-	switch {
-	case bb > 1:
-		// there was at least one mantissa digit
-		z = z.mulAddWW(z, bb, dd)
-	case base == 0 && b == 8:
-		// there was only the octal prefix 0 (possibly followed by digits > 7);
-		// return base 10, not 8
-		return z, 10, nil
-	case base != 0 || b != 8:
-		// there was neither a mantissa digit nor the octal prefix 0
-		return z, int(b), errors.New("syntax error scanning number")
-	}
-
-	return z.norm(), int(b), nil
-}
-
-// Character sets for string conversion.
-const (
-	lowercaseDigits = "0123456789abcdefghijklmnopqrstuvwxyz"
-	uppercaseDigits = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"
-)
-
-// decimalString returns a decimal representation of x.
-// It calls x.string with the charset "0123456789".
-func (x nat) decimalString() string {
-	return x.string(lowercaseDigits[0:10])
-}
-
-// string converts x to a string using digits from a charset; a digit with
-// value d is represented by charset[d]. The conversion base is determined
-// by len(charset), which must be >= 2 and <= 256.
-func (x nat) string(charset string) string {
-	b := Word(len(charset))
-
-	// special cases
-	switch {
-	case b < 2 || MaxBase > 256:
-		panic("illegal base")
-	case len(x) == 0:
-		return string(charset[0])
-	}
-
-	// allocate buffer for conversion
-	i := int(float64(x.bitLen())/math.Log2(float64(b))) + 1 // off by one at most
-	s := make([]byte, i)
-
-	// convert power of two and non power of two bases separately
-	if b == b&-b {
-		// shift is base-b digit size in bits
-		shift := trailingZeroBits(b) // shift > 0 because b >= 2
-		mask := Word(1)<<shift - 1
-		w := x[0]
-		nbits := uint(_W) // number of unprocessed bits in w
-
-		// convert less-significant words
-		for k := 1; k < len(x); k++ {
-			// convert full digits
-			for nbits >= shift {
-				i--
-				s[i] = charset[w&mask]
-				w >>= shift
-				nbits -= shift
-			}
-
-			// convert any partial leading digit and advance to next word
-			if nbits == 0 {
-				// no partial digit remaining, just advance
-				w = x[k]
-				nbits = _W
-			} else {
-				// partial digit in current (k-1) and next (k) word
-				w |= x[k] << nbits
-				i--
-				s[i] = charset[w&mask]
-
-				// advance
-				w = x[k] >> (shift - nbits)
-				nbits = _W - (shift - nbits)
-			}
-		}
-
-		// convert digits of most-significant word (omit leading zeros)
-		for nbits >= 0 && w != 0 {
-			i--
-			s[i] = charset[w&mask]
-			w >>= shift
-			nbits -= shift
-		}
-
-	} else {
-		// determine "big base"; i.e., the largest possible value bb
-		// that is a power of base b and still fits into a Word
-		// (as in 10^19 for 19 decimal digits in a 64bit Word)
-		bb := b      // big base is b**ndigits
-		ndigits := 1 // number of base b digits
-		for max := Word(_M / b); bb <= max; bb *= b {
-			ndigits++ // maximize ndigits where bb = b**ndigits, bb <= _M
-		}
-
-		// construct table of successive squares of bb*leafSize to use in subdivisions
-		// result (table != nil) <=> (len(x) > leafSize > 0)
-		table := divisors(len(x), b, ndigits, bb)
-
-		// preserve x, create local copy for use by convertWords
-		q := nat(nil).set(x)
-
-		// convert q to string s in base b
-		q.convertWords(s, charset, b, ndigits, bb, table)
-
-		// strip leading zeros
-		// (x != 0; thus s must contain at least one non-zero digit
-		// and the loop will terminate)
-		i = 0
-		for zero := charset[0]; s[i] == zero; {
-			i++
-		}
-	}
-
-	return string(s[i:])
-}
-
-// Convert words of q to base b digits in s. If q is large, it is recursively "split in half"
-// by nat/nat division using tabulated divisors. Otherwise, it is converted iteratively using
-// repeated nat/Word division.
-//
-// The iterative method processes n Words by n divW() calls, each of which visits every Word in the
-// incrementally shortened q for a total of n + (n-1) + (n-2) ... + 2 + 1, or n(n+1)/2 divW()'s.
-// Recursive conversion divides q by its approximate square root, yielding two parts, each half
-// the size of q. Using the iterative method on both halves means 2 * (n/2)(n/2 + 1)/2 divW()'s
-// plus the expensive long div(). Asymptotically, the ratio is favorable at 1/2 the divW()'s, and
-// is made better by splitting the subblocks recursively. Best is to split blocks until one more
-// split would take longer (because of the nat/nat div()) than the twice as many divW()'s of the
-// iterative approach. This threshold is represented by leafSize. Benchmarking of leafSize in the
-// range 2..64 shows that values of 8 and 16 work well, with a 4x speedup at medium lengths and
-// ~30x for 20000 digits. Use nat_test.go's BenchmarkLeafSize tests to optimize leafSize for
-// specific hardware.
-//
-func (q nat) convertWords(s []byte, charset string, b Word, ndigits int, bb Word, table []divisor) {
-	// split larger blocks recursively
-	if table != nil {
-		// len(q) > leafSize > 0
-		var r nat
-		index := len(table) - 1
-		for len(q) > leafSize {
-			// find divisor close to sqrt(q) if possible, but in any case < q
-			maxLength := q.bitLen()     // ~= log2 q, or at of least largest possible q of this bit length
-			minLength := maxLength >> 1 // ~= log2 sqrt(q)
-			for index > 0 && table[index-1].nbits > minLength {
-				index-- // desired
-			}
-			if table[index].nbits >= maxLength && table[index].bbb.cmp(q) >= 0 {
-				index--
-				if index < 0 {
-					panic("internal inconsistency")
-				}
-			}
-
-			// split q into the two digit number (q'*bbb + r) to form independent subblocks
-			q, r = q.div(r, q, table[index].bbb)
-
-			// convert subblocks and collect results in s[:h] and s[h:]
-			h := len(s) - table[index].ndigits
-			r.convertWords(s[h:], charset, b, ndigits, bb, table[0:index])
-			s = s[:h] // == q.convertWords(s, charset, b, ndigits, bb, table[0:index+1])
-		}
-	}
-
-	// having split any large blocks now process the remaining (small) block iteratively
-	i := len(s)
-	var r Word
-	if b == 10 {
-		// hard-coding for 10 here speeds this up by 1.25x (allows for / and % by constants)
-		for len(q) > 0 {
-			// extract least significant, base bb "digit"
-			q, r = q.divW(q, bb)
-			for j := 0; j < ndigits && i > 0; j++ {
-				i--
-				// avoid % computation since r%10 == r - int(r/10)*10;
-				// this appears to be faster for BenchmarkString10000Base10
-				// and smaller strings (but a bit slower for larger ones)
-				t := r / 10
-				s[i] = charset[r-t<<3-t-t] // TODO(gri) replace w/ t*10 once compiler produces better code
-				r = t
-			}
-		}
-	} else {
-		for len(q) > 0 {
-			// extract least significant, base bb "digit"
-			q, r = q.divW(q, bb)
-			for j := 0; j < ndigits && i > 0; j++ {
-				i--
-				s[i] = charset[r%b]
-				r /= b
-			}
-		}
-	}
-
-	// prepend high-order zeroes
-	zero := charset[0]
-	for i > 0 { // while need more leading zeroes
-		i--
-		s[i] = zero
-	}
-}
-
-// Split blocks greater than leafSize Words (or set to 0 to disable recursive conversion)
-// Benchmark and configure leafSize using: go test -bench="Leaf"
-//   8 and 16 effective on 3.0 GHz Xeon "Clovertown" CPU (128 byte cache lines)
-//   8 and 16 effective on 2.66 GHz Core 2 Duo "Penryn" CPU
-var leafSize int = 8 // number of Word-size binary values treat as a monolithic block
-
-type divisor struct {
-	bbb     nat // divisor
-	nbits   int // bit length of divisor (discounting leading zeroes) ~= log2(bbb)
-	ndigits int // digit length of divisor in terms of output base digits
-}
-
-var cacheBase10 struct {
-	sync.Mutex
-	table [64]divisor // cached divisors for base 10
-}
-
-// expWW computes x**y
-func (z nat) expWW(x, y Word) nat {
-	return z.expNN(nat(nil).setWord(x), nat(nil).setWord(y), nil)
-}
-
-// construct table of powers of bb*leafSize to use in subdivisions
-func divisors(m int, b Word, ndigits int, bb Word) []divisor {
-	// only compute table when recursive conversion is enabled and x is large
-	if leafSize == 0 || m <= leafSize {
-		return nil
-	}
-
-	// determine k where (bb**leafSize)**(2**k) >= sqrt(x)
-	k := 1
-	for words := leafSize; words < m>>1 && k < len(cacheBase10.table); words <<= 1 {
-		k++
-	}
-
-	// reuse and extend existing table of divisors or create new table as appropriate
-	var table []divisor // for b == 10, table overlaps with cacheBase10.table
-	if b == 10 {
-		cacheBase10.Lock()
-		table = cacheBase10.table[0:k] // reuse old table for this conversion
-	} else {
-		table = make([]divisor, k) // create new table for this conversion
-	}
-
-	// extend table
-	if table[k-1].ndigits == 0 {
-		// add new entries as needed
-		var larger nat
-		for i := 0; i < k; i++ {
-			if table[i].ndigits == 0 {
-				if i == 0 {
-					table[0].bbb = nat(nil).expWW(bb, Word(leafSize))
-					table[0].ndigits = ndigits * leafSize
-				} else {
-					table[i].bbb = nat(nil).mul(table[i-1].bbb, table[i-1].bbb)
-					table[i].ndigits = 2 * table[i-1].ndigits
-				}
-
-				// optimization: exploit aggregated extra bits in macro blocks
-				larger = nat(nil).set(table[i].bbb)
-				for mulAddVWW(larger, larger, b, 0) == 0 {
-					table[i].bbb = table[i].bbb.set(larger)
-					table[i].ndigits++
-				}
-
-				table[i].nbits = table[i].bbb.bitLen()
-			}
-		}
-	}
-
-	if b == 10 {
-		cacheBase10.Unlock()
-	}
-
-	return table
-}
-
 const deBruijn32 = 0x077CB531
 
 var deBruijn32Lookup = []byte{
@@ -1041,7 +688,7 @@
 func (z nat) shl(x nat, s uint) nat {
 	m := len(x)
 	if m == 0 {
-		return z.make(0)
+		return z[:0]
 	}
 	// m > 0
 
@@ -1058,7 +705,7 @@
 	m := len(x)
 	n := m - int(s/_W)
 	if n <= 0 {
-		return z.make(0)
+		return z[:0]
 	}
 	// n > 0
 
@@ -1097,12 +744,36 @@
 	panic("set bit is not 0 or 1")
 }
 
-func (z nat) bit(i uint) uint {
-	j := int(i / _W)
-	if j >= len(z) {
+// bit returns the value of the i'th bit, with lsb == bit 0.
+func (x nat) bit(i uint) uint {
+	j := i / _W
+	if j >= uint(len(x)) {
 		return 0
 	}
-	return uint(z[j] >> (i % _W) & 1)
+	// 0 <= j < len(x)
+	return uint(x[j] >> (i % _W) & 1)
+}
+
+// sticky returns 1 if there's a 1 bit within the
+// i least significant bits, otherwise it returns 0.
+func (x nat) sticky(i uint) uint {
+	j := i / _W
+	if j >= uint(len(x)) {
+		if len(x) == 0 {
+			return 0
+		}
+		return 1
+	}
+	// 0 <= j < len(x)
+	for _, x := range x[:j] {
+		if x != 0 {
+			return 1
+		}
+	}
+	if x[j]<<(_W-i%_W) != 0 {
+		return 1
+	}
+	return 0
 }
 
 func (z nat) and(x, y nat) nat {
@@ -1176,7 +847,7 @@
 	return z.norm()
 }
 
-// greaterThan returns true iff (x1<<_W + x2) > (y1<<_W + y2)
+// greaterThan reports whether (x1<<_W + x2) > (y1<<_W + y2)
 func greaterThan(x1, x2, y1, y2 Word) bool {
 	return x1 > y1 || x1 == y1 && x2 > y2
 }
@@ -1245,6 +916,13 @@
 	}
 	// y > 0
 
+	// x**1 mod m == x mod m
+	if len(y) == 1 && y[0] == 1 && len(m) != 0 {
+		_, z = z.div(z, x, m)
+		return z
+	}
+	// y > 1
+
 	if len(m) != 0 {
 		// We likely end up being as long as the modulus.
 		z = z.make(len(m))
@@ -1255,13 +933,16 @@
 	// 4-bit, windowed exponentiation. This involves precomputing 14 values
 	// (x^2...x^15) but then reduces the number of multiply-reduces by a
 	// third. Even for a 32-bit exponent, this reduces the number of
-	// operations.
+	// operations. Uses Montgomery method for odd moduli.
 	if len(x) > 1 && len(y) > 1 && len(m) > 0 {
+		if m[0]&1 == 1 {
+			return z.expNNMontgomery(x, y, m)
+		}
 		return z.expNNWindowed(x, y, m)
 	}
 
 	v := y[len(y)-1] // v > 0 because y is normalized and y > 0
-	shift := leadingZeros(v) + 1
+	shift := nlz(v) + 1
 	v <<= shift
 	var q nat
 
@@ -1379,6 +1060,87 @@
 	return z.norm()
 }
 
+// expNNMontgomery calculates x**y mod m using a fixed, 4-bit window.
+// Uses Montgomery representation.
+func (z nat) expNNMontgomery(x, y, m nat) nat {
+	var zz, one, rr, RR nat
+
+	numWords := len(m)
+
+	// We want the lengths of x and m to be equal.
+	if len(x) > numWords {
+		_, rr = rr.div(rr, x, m)
+	} else if len(x) < numWords {
+		rr = rr.make(numWords)
+		rr.clear()
+		for i := range x {
+			rr[i] = x[i]
+		}
+	} else {
+		rr = x
+	}
+	x = rr
+
+	// Ideally the precomputations would be performed outside, and reused
+	// k0 = -mˆ-1 mod 2ˆ_W. Algorithm from: Dumas, J.G. "On Newton–Raphson
+	// Iteration for Multiplicative Inverses Modulo Prime Powers".
+	k0 := 2 - m[0]
+	t := m[0] - 1
+	for i := 1; i < _W; i <<= 1 {
+		t *= t
+		k0 *= (t + 1)
+	}
+	k0 = -k0
+
+	// RR = 2ˆ(2*_W*len(m)) mod m
+	RR = RR.setWord(1)
+	zz = zz.shl(RR, uint(2*numWords*_W))
+	_, RR = RR.div(RR, zz, m)
+	if len(RR) < numWords {
+		zz = zz.make(numWords)
+		copy(zz, RR)
+		RR = zz
+	}
+	// one = 1, with equal length to that of m
+	one = one.make(numWords)
+	one.clear()
+	one[0] = 1
+
+	const n = 4
+	// powers[i] contains x^i
+	var powers [1 << n]nat
+	powers[0] = powers[0].montgomery(one, RR, m, k0, numWords)
+	powers[1] = powers[1].montgomery(x, RR, m, k0, numWords)
+	for i := 2; i < 1<<n; i++ {
+		powers[i] = powers[i].montgomery(powers[i-1], powers[1], m, k0, numWords)
+	}
+
+	// initialize z = 1 (Montgomery 1)
+	z = z.make(numWords)
+	copy(z, powers[0])
+
+	zz = zz.make(numWords)
+
+	// same windowed exponent, but with Montgomery multiplications
+	for i := len(y) - 1; i >= 0; i-- {
+		yi := y[i]
+		for j := 0; j < _W; j += n {
+			if i != len(y)-1 || j != 0 {
+				zz = zz.montgomery(z, z, m, k0, numWords)
+				z = z.montgomery(zz, zz, m, k0, numWords)
+				zz = zz.montgomery(z, z, m, k0, numWords)
+				z = z.montgomery(zz, zz, m, k0, numWords)
+			}
+			zz = zz.montgomery(z, powers[yi>>(_W-n)], m, k0, numWords)
+			z, zz = zz, z
+			yi <<= n
+		}
+	}
+	// convert to regular number
+	zz = zz.montgomery(z, one, m, k0, numWords)
+	return zz.norm()
+}
+
 // probablyPrime performs reps Miller-Rabin tests to check whether n is prime.
 // If it returns true, n is prime with probability 1 - 1/4^reps.
 // If it returns false, n is not prime.
@@ -1404,6 +1166,10 @@
 		}
 	}
 
+	if n[0]&1 == 0 {
+		return false // n is even
+	}
+
 	const primesProduct32 = 0xC0CFD797         // Π {p ∈ primes, 2 < p <= 29}
 	const primesProduct64 = 0xE221F97C30E94E1D // Π {p ∈ primes, 2 < p <= 53}
 
diff --git a/third_party/gofrontend/libgo/go/math/big/nat_test.go b/third_party/gofrontend/libgo/go/math/big/nat_test.go
index a2ae533..7ac3cb8 100644
--- a/third_party/gofrontend/libgo/go/math/big/nat_test.go
+++ b/third_party/gofrontend/libgo/go/math/big/nat_test.go
@@ -5,7 +5,6 @@
 package big
 
 import (
-	"io"
 	"runtime"
 	"strings"
 	"testing"
@@ -88,7 +87,7 @@
 }
 
 func natFromString(s string) nat {
-	x, _, err := nat(nil).scan(strings.NewReader(s), 0)
+	x, _, _, err := nat(nil).scan(strings.NewReader(s), 0, false)
 	if err != nil {
 		panic(err)
 	}
@@ -206,398 +205,11 @@
 	}
 }
 
-func toString(x nat, charset string) string {
-	base := len(charset)
-
-	// special cases
-	switch {
-	case base < 2:
-		panic("illegal base")
-	case len(x) == 0:
-		return string(charset[0])
-	}
-
-	// allocate buffer for conversion
-	i := x.bitLen()/log2(Word(base)) + 1 // +1: round up
-	s := make([]byte, i)
-
-	// don't destroy x
-	q := nat(nil).set(x)
-
-	// convert
-	for len(q) > 0 {
-		i--
-		var r Word
-		q, r = q.divW(q, Word(base))
-		s[i] = charset[r]
-	}
-
-	return string(s[i:])
-}
-
-var strTests = []struct {
-	x nat    // nat value to be converted
-	c string // conversion charset
-	s string // expected result
-}{
-	{nil, "01", "0"},
-	{nat{1}, "01", "1"},
-	{nat{0xc5}, "01", "11000101"},
-	{nat{03271}, lowercaseDigits[0:8], "3271"},
-	{nat{10}, lowercaseDigits[0:10], "10"},
-	{nat{1234567890}, uppercaseDigits[0:10], "1234567890"},
-	{nat{0xdeadbeef}, lowercaseDigits[0:16], "deadbeef"},
-	{nat{0xdeadbeef}, uppercaseDigits[0:16], "DEADBEEF"},
-	{nat{0x229be7}, lowercaseDigits[0:17], "1a2b3c"},
-	{nat{0x309663e6}, uppercaseDigits[0:32], "O9COV6"},
-}
-
-func TestString(t *testing.T) {
-	for _, a := range strTests {
-		s := a.x.string(a.c)
-		if s != a.s {
-			t.Errorf("string%+v\n\tgot s = %s; want %s", a, s, a.s)
-		}
-
-		x, b, err := nat(nil).scan(strings.NewReader(a.s), len(a.c))
-		if x.cmp(a.x) != 0 {
-			t.Errorf("scan%+v\n\tgot z = %v; want %v", a, x, a.x)
-		}
-		if b != len(a.c) {
-			t.Errorf("scan%+v\n\tgot b = %d; want %d", a, b, len(a.c))
-		}
-		if err != nil {
-			t.Errorf("scan%+v\n\tgot error = %s", a, err)
-		}
-	}
-}
-
-var natScanTests = []struct {
-	s    string // string to be scanned
-	base int    // input base
-	x    nat    // expected nat
-	b    int    // expected base
-	ok   bool   // expected success
-	next rune   // next character (or 0, if at EOF)
-}{
-	// error: illegal base
-	{base: -1},
-	{base: 1},
-	{base: 37},
-
-	// error: no mantissa
-	{},
-	{s: "?"},
-	{base: 10},
-	{base: 36},
-	{s: "?", base: 10},
-	{s: "0x"},
-	{s: "345", base: 2},
-
-	// no errors
-	{"0", 0, nil, 10, true, 0},
-	{"0", 10, nil, 10, true, 0},
-	{"0", 36, nil, 36, true, 0},
-	{"1", 0, nat{1}, 10, true, 0},
-	{"1", 10, nat{1}, 10, true, 0},
-	{"0 ", 0, nil, 10, true, ' '},
-	{"08", 0, nil, 10, true, '8'},
-	{"018", 0, nat{1}, 8, true, '8'},
-	{"0b1", 0, nat{1}, 2, true, 0},
-	{"0b11000101", 0, nat{0xc5}, 2, true, 0},
-	{"03271", 0, nat{03271}, 8, true, 0},
-	{"10ab", 0, nat{10}, 10, true, 'a'},
-	{"1234567890", 0, nat{1234567890}, 10, true, 0},
-	{"xyz", 36, nat{(33*36+34)*36 + 35}, 36, true, 0},
-	{"xyz?", 36, nat{(33*36+34)*36 + 35}, 36, true, '?'},
-	{"0x", 16, nil, 16, true, 'x'},
-	{"0xdeadbeef", 0, nat{0xdeadbeef}, 16, true, 0},
-	{"0XDEADBEEF", 0, nat{0xdeadbeef}, 16, true, 0},
-}
-
-func TestScanBase(t *testing.T) {
-	for _, a := range natScanTests {
-		r := strings.NewReader(a.s)
-		x, b, err := nat(nil).scan(r, a.base)
-		if err == nil && !a.ok {
-			t.Errorf("scan%+v\n\texpected error", a)
-		}
-		if err != nil {
-			if a.ok {
-				t.Errorf("scan%+v\n\tgot error = %s", a, err)
-			}
-			continue
-		}
-		if x.cmp(a.x) != 0 {
-			t.Errorf("scan%+v\n\tgot z = %v; want %v", a, x, a.x)
-		}
-		if b != a.b {
-			t.Errorf("scan%+v\n\tgot b = %d; want %d", a, b, a.base)
-		}
-		next, _, err := r.ReadRune()
-		if err == io.EOF {
-			next = 0
-			err = nil
-		}
-		if err == nil && next != a.next {
-			t.Errorf("scan%+v\n\tgot next = %q; want %q", a, next, a.next)
-		}
-	}
-}
-
-var pi = "3" +
-	"14159265358979323846264338327950288419716939937510582097494459230781640628620899862803482534211706798214808651" +
-	"32823066470938446095505822317253594081284811174502841027019385211055596446229489549303819644288109756659334461" +
-	"28475648233786783165271201909145648566923460348610454326648213393607260249141273724587006606315588174881520920" +
-	"96282925409171536436789259036001133053054882046652138414695194151160943305727036575959195309218611738193261179" +
-	"31051185480744623799627495673518857527248912279381830119491298336733624406566430860213949463952247371907021798" +
-	"60943702770539217176293176752384674818467669405132000568127145263560827785771342757789609173637178721468440901" +
-	"22495343014654958537105079227968925892354201995611212902196086403441815981362977477130996051870721134999999837" +
-	"29780499510597317328160963185950244594553469083026425223082533446850352619311881710100031378387528865875332083" +
-	"81420617177669147303598253490428755468731159562863882353787593751957781857780532171226806613001927876611195909" +
-	"21642019893809525720106548586327886593615338182796823030195203530185296899577362259941389124972177528347913151" +
-	"55748572424541506959508295331168617278558890750983817546374649393192550604009277016711390098488240128583616035" +
-	"63707660104710181942955596198946767837449448255379774726847104047534646208046684259069491293313677028989152104" +
-	"75216205696602405803815019351125338243003558764024749647326391419927260426992279678235478163600934172164121992" +
-	"45863150302861829745557067498385054945885869269956909272107975093029553211653449872027559602364806654991198818" +
-	"34797753566369807426542527862551818417574672890977772793800081647060016145249192173217214772350141441973568548" +
-	"16136115735255213347574184946843852332390739414333454776241686251898356948556209921922218427255025425688767179" +
-	"04946016534668049886272327917860857843838279679766814541009538837863609506800642251252051173929848960841284886" +
-	"26945604241965285022210661186306744278622039194945047123713786960956364371917287467764657573962413890865832645" +
-	"99581339047802759009946576407895126946839835259570982582262052248940772671947826848260147699090264013639443745" +
-	"53050682034962524517493996514314298091906592509372216964615157098583874105978859597729754989301617539284681382" +
-	"68683868942774155991855925245953959431049972524680845987273644695848653836736222626099124608051243884390451244" +
-	"13654976278079771569143599770012961608944169486855584840635342207222582848864815845602850601684273945226746767" +
-	"88952521385225499546667278239864565961163548862305774564980355936345681743241125150760694794510965960940252288" +
-	"79710893145669136867228748940560101503308617928680920874760917824938589009714909675985261365549781893129784821" +
-	"68299894872265880485756401427047755513237964145152374623436454285844479526586782105114135473573952311342716610" +
-	"21359695362314429524849371871101457654035902799344037420073105785390621983874478084784896833214457138687519435" +
-	"06430218453191048481005370614680674919278191197939952061419663428754440643745123718192179998391015919561814675" +
-	"14269123974894090718649423196156794520809514655022523160388193014209376213785595663893778708303906979207734672" +
-	"21825625996615014215030680384477345492026054146659252014974428507325186660021324340881907104863317346496514539" +
-	"05796268561005508106658796998163574736384052571459102897064140110971206280439039759515677157700420337869936007" +
-	"23055876317635942187312514712053292819182618612586732157919841484882916447060957527069572209175671167229109816" +
-	"90915280173506712748583222871835209353965725121083579151369882091444210067510334671103141267111369908658516398" +
-	"31501970165151168517143765761835155650884909989859982387345528331635507647918535893226185489632132933089857064" +
-	"20467525907091548141654985946163718027098199430992448895757128289059232332609729971208443357326548938239119325" +
-	"97463667305836041428138830320382490375898524374417029132765618093773444030707469211201913020330380197621101100" +
-	"44929321516084244485963766983895228684783123552658213144957685726243344189303968642624341077322697802807318915" +
-	"44110104468232527162010526522721116603966655730925471105578537634668206531098965269186205647693125705863566201" +
-	"85581007293606598764861179104533488503461136576867532494416680396265797877185560845529654126654085306143444318" +
-	"58676975145661406800700237877659134401712749470420562230538994561314071127000407854733269939081454664645880797" +
-	"27082668306343285878569830523580893306575740679545716377525420211495576158140025012622859413021647155097925923" +
-	"09907965473761255176567513575178296664547791745011299614890304639947132962107340437518957359614589019389713111" +
-	"79042978285647503203198691514028708085990480109412147221317947647772622414254854540332157185306142288137585043" +
-	"06332175182979866223717215916077166925474873898665494945011465406284336639379003976926567214638530673609657120" +
-	"91807638327166416274888800786925602902284721040317211860820419000422966171196377921337575114959501566049631862" +
-	"94726547364252308177036751590673502350728354056704038674351362222477158915049530984448933309634087807693259939" +
-	"78054193414473774418426312986080998886874132604721569516239658645730216315981931951673538129741677294786724229" +
-	"24654366800980676928238280689964004824354037014163149658979409243237896907069779422362508221688957383798623001" +
-	"59377647165122893578601588161755782973523344604281512627203734314653197777416031990665541876397929334419521541" +
-	"34189948544473456738316249934191318148092777710386387734317720754565453220777092120190516609628049092636019759" +
-	"88281613323166636528619326686336062735676303544776280350450777235547105859548702790814356240145171806246436267" +
-	"94561275318134078330336254232783944975382437205835311477119926063813346776879695970309833913077109870408591337"
-
-// Test case for BenchmarkScanPi.
-func TestScanPi(t *testing.T) {
-	var x nat
-	z, _, err := x.scan(strings.NewReader(pi), 10)
-	if err != nil {
-		t.Errorf("scanning pi: %s", err)
-	}
-	if s := z.decimalString(); s != pi {
-		t.Errorf("scanning pi: got %s", s)
-	}
-}
-
-func TestScanPiParallel(t *testing.T) {
-	const n = 2
-	c := make(chan int)
-	for i := 0; i < n; i++ {
-		go func() {
-			TestScanPi(t)
-			c <- 0
-		}()
-	}
-	for i := 0; i < n; i++ {
-		<-c
-	}
-}
-
-func BenchmarkScanPi(b *testing.B) {
-	for i := 0; i < b.N; i++ {
-		var x nat
-		x.scan(strings.NewReader(pi), 10)
-	}
-}
-
-func BenchmarkStringPiParallel(b *testing.B) {
-	var x nat
-	x, _, _ = x.scan(strings.NewReader(pi), 0)
-	if x.decimalString() != pi {
-		panic("benchmark incorrect: conversion failed")
-	}
-	b.RunParallel(func(pb *testing.PB) {
-		for pb.Next() {
-			x.decimalString()
-		}
-	})
-}
-
-func BenchmarkScan10Base2(b *testing.B)     { ScanHelper(b, 2, 10, 10) }
-func BenchmarkScan100Base2(b *testing.B)    { ScanHelper(b, 2, 10, 100) }
-func BenchmarkScan1000Base2(b *testing.B)   { ScanHelper(b, 2, 10, 1000) }
-func BenchmarkScan10000Base2(b *testing.B)  { ScanHelper(b, 2, 10, 10000) }
-func BenchmarkScan100000Base2(b *testing.B) { ScanHelper(b, 2, 10, 100000) }
-
-func BenchmarkScan10Base8(b *testing.B)     { ScanHelper(b, 8, 10, 10) }
-func BenchmarkScan100Base8(b *testing.B)    { ScanHelper(b, 8, 10, 100) }
-func BenchmarkScan1000Base8(b *testing.B)   { ScanHelper(b, 8, 10, 1000) }
-func BenchmarkScan10000Base8(b *testing.B)  { ScanHelper(b, 8, 10, 10000) }
-func BenchmarkScan100000Base8(b *testing.B) { ScanHelper(b, 8, 10, 100000) }
-
-func BenchmarkScan10Base10(b *testing.B)     { ScanHelper(b, 10, 10, 10) }
-func BenchmarkScan100Base10(b *testing.B)    { ScanHelper(b, 10, 10, 100) }
-func BenchmarkScan1000Base10(b *testing.B)   { ScanHelper(b, 10, 10, 1000) }
-func BenchmarkScan10000Base10(b *testing.B)  { ScanHelper(b, 10, 10, 10000) }
-func BenchmarkScan100000Base10(b *testing.B) { ScanHelper(b, 10, 10, 100000) }
-
-func BenchmarkScan10Base16(b *testing.B)     { ScanHelper(b, 16, 10, 10) }
-func BenchmarkScan100Base16(b *testing.B)    { ScanHelper(b, 16, 10, 100) }
-func BenchmarkScan1000Base16(b *testing.B)   { ScanHelper(b, 16, 10, 1000) }
-func BenchmarkScan10000Base16(b *testing.B)  { ScanHelper(b, 16, 10, 10000) }
-func BenchmarkScan100000Base16(b *testing.B) { ScanHelper(b, 16, 10, 100000) }
-
-func ScanHelper(b *testing.B, base int, x, y Word) {
-	b.StopTimer()
-	var z nat
-	z = z.expWW(x, y)
-
-	var s string
-	s = z.string(lowercaseDigits[0:base])
-	if t := toString(z, lowercaseDigits[0:base]); t != s {
-		b.Fatalf("scanning: got %s; want %s", s, t)
-	}
-	b.StartTimer()
-
-	for i := 0; i < b.N; i++ {
-		z.scan(strings.NewReader(s), base)
-	}
-}
-
-func BenchmarkString10Base2(b *testing.B)     { StringHelper(b, 2, 10, 10) }
-func BenchmarkString100Base2(b *testing.B)    { StringHelper(b, 2, 10, 100) }
-func BenchmarkString1000Base2(b *testing.B)   { StringHelper(b, 2, 10, 1000) }
-func BenchmarkString10000Base2(b *testing.B)  { StringHelper(b, 2, 10, 10000) }
-func BenchmarkString100000Base2(b *testing.B) { StringHelper(b, 2, 10, 100000) }
-
-func BenchmarkString10Base8(b *testing.B)     { StringHelper(b, 8, 10, 10) }
-func BenchmarkString100Base8(b *testing.B)    { StringHelper(b, 8, 10, 100) }
-func BenchmarkString1000Base8(b *testing.B)   { StringHelper(b, 8, 10, 1000) }
-func BenchmarkString10000Base8(b *testing.B)  { StringHelper(b, 8, 10, 10000) }
-func BenchmarkString100000Base8(b *testing.B) { StringHelper(b, 8, 10, 100000) }
-
-func BenchmarkString10Base10(b *testing.B)     { StringHelper(b, 10, 10, 10) }
-func BenchmarkString100Base10(b *testing.B)    { StringHelper(b, 10, 10, 100) }
-func BenchmarkString1000Base10(b *testing.B)   { StringHelper(b, 10, 10, 1000) }
-func BenchmarkString10000Base10(b *testing.B)  { StringHelper(b, 10, 10, 10000) }
-func BenchmarkString100000Base10(b *testing.B) { StringHelper(b, 10, 10, 100000) }
-
-func BenchmarkString10Base16(b *testing.B)     { StringHelper(b, 16, 10, 10) }
-func BenchmarkString100Base16(b *testing.B)    { StringHelper(b, 16, 10, 100) }
-func BenchmarkString1000Base16(b *testing.B)   { StringHelper(b, 16, 10, 1000) }
-func BenchmarkString10000Base16(b *testing.B)  { StringHelper(b, 16, 10, 10000) }
-func BenchmarkString100000Base16(b *testing.B) { StringHelper(b, 16, 10, 100000) }
-
-func StringHelper(b *testing.B, base int, x, y Word) {
-	b.StopTimer()
-	var z nat
-	z = z.expWW(x, y)
-	z.string(lowercaseDigits[0:base]) // warm divisor cache
-	b.StartTimer()
-
-	for i := 0; i < b.N; i++ {
-		_ = z.string(lowercaseDigits[0:base])
-	}
-}
-
-func BenchmarkLeafSize0(b *testing.B)  { LeafSizeHelper(b, 10, 0) } // test without splitting
-func BenchmarkLeafSize1(b *testing.B)  { LeafSizeHelper(b, 10, 1) }
-func BenchmarkLeafSize2(b *testing.B)  { LeafSizeHelper(b, 10, 2) }
-func BenchmarkLeafSize3(b *testing.B)  { LeafSizeHelper(b, 10, 3) }
-func BenchmarkLeafSize4(b *testing.B)  { LeafSizeHelper(b, 10, 4) }
-func BenchmarkLeafSize5(b *testing.B)  { LeafSizeHelper(b, 10, 5) }
-func BenchmarkLeafSize6(b *testing.B)  { LeafSizeHelper(b, 10, 6) }
-func BenchmarkLeafSize7(b *testing.B)  { LeafSizeHelper(b, 10, 7) }
-func BenchmarkLeafSize8(b *testing.B)  { LeafSizeHelper(b, 10, 8) }
-func BenchmarkLeafSize9(b *testing.B)  { LeafSizeHelper(b, 10, 9) }
-func BenchmarkLeafSize10(b *testing.B) { LeafSizeHelper(b, 10, 10) }
-func BenchmarkLeafSize11(b *testing.B) { LeafSizeHelper(b, 10, 11) }
-func BenchmarkLeafSize12(b *testing.B) { LeafSizeHelper(b, 10, 12) }
-func BenchmarkLeafSize13(b *testing.B) { LeafSizeHelper(b, 10, 13) }
-func BenchmarkLeafSize14(b *testing.B) { LeafSizeHelper(b, 10, 14) }
-func BenchmarkLeafSize15(b *testing.B) { LeafSizeHelper(b, 10, 15) }
-func BenchmarkLeafSize16(b *testing.B) { LeafSizeHelper(b, 10, 16) }
-func BenchmarkLeafSize32(b *testing.B) { LeafSizeHelper(b, 10, 32) } // try some large lengths
-func BenchmarkLeafSize64(b *testing.B) { LeafSizeHelper(b, 10, 64) }
-
-func LeafSizeHelper(b *testing.B, base Word, size int) {
-	b.StopTimer()
-	originalLeafSize := leafSize
-	resetTable(cacheBase10.table[:])
-	leafSize = size
-	b.StartTimer()
-
-	for d := 1; d <= 10000; d *= 10 {
-		b.StopTimer()
-		var z nat
-		z = z.expWW(base, Word(d))            // build target number
-		_ = z.string(lowercaseDigits[0:base]) // warm divisor cache
-		b.StartTimer()
-
-		for i := 0; i < b.N; i++ {
-			_ = z.string(lowercaseDigits[0:base])
-		}
-	}
-
-	b.StopTimer()
-	resetTable(cacheBase10.table[:])
-	leafSize = originalLeafSize
-	b.StartTimer()
-}
-
-func resetTable(table []divisor) {
-	if table != nil && table[0].bbb != nil {
-		for i := 0; i < len(table); i++ {
-			table[i].bbb = nil
-			table[i].nbits = 0
-			table[i].ndigits = 0
-		}
-	}
-}
-
-func TestStringPowers(t *testing.T) {
-	var b, p Word
-	for b = 2; b <= 16; b++ {
-		for p = 0; p <= 512; p++ {
-			x := nat(nil).expWW(b, p)
-			xs := x.string(lowercaseDigits[0:b])
-			xs2 := toString(x, lowercaseDigits[0:b])
-			if xs != xs2 {
-				t.Errorf("failed at %d ** %d in base %d: %s != %s", b, p, b, xs, xs2)
-			}
-		}
-		if b >= 3 && testing.Short() {
-			break
-		}
-	}
-}
-
-func TestLeadingZeros(t *testing.T) {
+func TestNLZ(t *testing.T) {
 	var x Word = _B >> 1
 	for i := 0; i <= _W; i++ {
-		if int(leadingZeros(x)) != i {
-			t.Errorf("failed at %x: got %d want %d", x, leadingZeros(x), i)
+		if int(nlz(x)) != i {
+			t.Errorf("failed at %x: got %d want %d", x, nlz(x), i)
 		}
 		x >>= 1
 	}
@@ -691,25 +303,96 @@
 }
 
 func TestTrailingZeroBits(t *testing.T) {
+	// test 0 case explicitly
+	if n := trailingZeroBits(0); n != 0 {
+		t.Errorf("got trailingZeroBits(0) = %d; want 0", n)
+	}
+
 	x := Word(1)
-	for i := uint(0); i <= _W; i++ {
+	for i := uint(0); i < _W; i++ {
 		n := trailingZeroBits(x)
-		if n != i%_W {
+		if n != i {
 			t.Errorf("got trailingZeroBits(%#x) = %d; want %d", x, n, i%_W)
 		}
 		x <<= 1
 	}
 
+	// test 0 case explicitly
+	if n := nat(nil).trailingZeroBits(); n != 0 {
+		t.Errorf("got nat(nil).trailingZeroBits() = %d; want 0", n)
+	}
+
 	y := nat(nil).set(natOne)
 	for i := uint(0); i <= 3*_W; i++ {
 		n := y.trailingZeroBits()
 		if n != i {
-			t.Errorf("got 0x%s.trailingZeroBits() = %d; want %d", y.string(lowercaseDigits[0:16]), n, i)
+			t.Errorf("got 0x%s.trailingZeroBits() = %d; want %d", y.hexString(), n, i)
 		}
 		y = y.shl(y, 1)
 	}
 }
 
+var montgomeryTests = []struct {
+	x, y, m      string
+	k0           uint64
+	out32, out64 string
+}{
+	{
+		"0xffffffffffffffffffffffffffffffffffffffffffffffffe",
+		"0xffffffffffffffffffffffffffffffffffffffffffffffffe",
+		"0xfffffffffffffffffffffffffffffffffffffffffffffffff",
+		0x0000000000000000,
+		"0xffffffffffffffffffffffffffffffffffffffffff",
+		"0xffffffffffffffffffffffffffffffffff",
+	},
+	{
+		"0x0000000080000000",
+		"0x00000000ffffffff",
+		"0x0000000010000001",
+		0xff0000000fffffff,
+		"0x0000000088000000",
+		"0x0000000007800001",
+	},
+	{
+		"0xffffffffffffffffffffffffffffffff00000000000022222223333333333444444444",
+		"0xffffffffffffffffffffffffffffffff999999999999999aaabbbbbbbbcccccccccccc",
+		"0x33377fffffffffffffffffffffffffffffffffffffffffffff0000000000022222eee1",
+		0xdecc8f1249812adf,
+		"0x22bb05b6d95eaaeca2bb7c05e51f807bce9064b5fbad177161695e4558f9474e91cd79",
+		"0x14beb58d230f85b6d95eaaeca2bb7c05e51f807bce9064b5fb45669afa695f228e48cd",
+	},
+	{
+		"0x10000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffffffffffff00000000000022222223333333333444444444",
+		"0x10000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffffffffffff999999999999999aaabbbbbbbbcccccccccccc",
+		"0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff33377fffffffffffffffffffffffffffffffffffffffffffff0000000000022222eee1",
+		0xdecc8f1249812adf,
+		"0x5c0d52f451aec609b15da8e5e5626c4eaa88723bdeac9d25ca9b961269400410ca208a16af9c2fb07d7a11c7772cba02c22f9711078d51a3797eb18e691295293284d988e349fa6deba46b25a4ecd9f715",
+		"0x92fcad4b5c0d52f451aec609b15da8e5e5626c4eaa88723bdeac9d25ca9b961269400410ca208a16af9c2fb07d799c32fe2f3cc5422f9711078d51a3797eb18e691295293284d8f5e69caf6decddfe1df6",
+	},
+}
+
+func TestMontgomery(t *testing.T) {
+	for i, test := range montgomeryTests {
+		x := natFromString(test.x)
+		y := natFromString(test.y)
+		m := natFromString(test.m)
+
+		var out nat
+		if _W == 32 {
+			out = natFromString(test.out32)
+		} else {
+			out = natFromString(test.out64)
+		}
+
+		k0 := Word(test.k0 & _M) // mask k0 to ensure that it fits for 32-bit systems.
+		z := nat(nil).montgomery(x, y, m, k0, len(m))
+		z = z.norm()
+		if z.cmp(out) != 0 {
+			t.Errorf("#%d got %s want %s", i, z.decimalString(), out.decimalString())
+		}
+	}
+}
+
 var expNNTests = []struct {
 	x, y, m string
 	out     string
@@ -735,14 +418,13 @@
 
 func TestExpNN(t *testing.T) {
 	for i, test := range expNNTests {
-		x, _, _ := nat(nil).scan(strings.NewReader(test.x), 0)
-		y, _, _ := nat(nil).scan(strings.NewReader(test.y), 0)
-		out, _, _ := nat(nil).scan(strings.NewReader(test.out), 0)
+		x := natFromString(test.x)
+		y := natFromString(test.y)
+		out := natFromString(test.out)
 
 		var m nat
-
 		if len(test.m) > 0 {
-			m, _, _ = nat(nil).scan(strings.NewReader(test.m), 0)
+			m = natFromString(test.m)
 		}
 
 		z := nat(nil).expNN(x, y, m)
@@ -769,3 +451,129 @@
 func BenchmarkExp3Power0x40000(b *testing.B)  { ExpHelper(b, 3, 0x40000) }
 func BenchmarkExp3Power0x100000(b *testing.B) { ExpHelper(b, 3, 0x100000) }
 func BenchmarkExp3Power0x400000(b *testing.B) { ExpHelper(b, 3, 0x400000) }
+
+func fibo(n int) nat {
+	switch n {
+	case 0:
+		return nil
+	case 1:
+		return nat{1}
+	}
+	f0 := fibo(0)
+	f1 := fibo(1)
+	var f2 nat
+	for i := 1; i < n; i++ {
+		f2 = f2.add(f0, f1)
+		f0, f1, f2 = f1, f2, f0
+	}
+	return f1
+}
+
+var fiboNums = []string{
+	"0",
+	"55",
+	"6765",
+	"832040",
+	"102334155",
+	"12586269025",
+	"1548008755920",
+	"190392490709135",
+	"23416728348467685",
+	"2880067194370816120",
+	"354224848179261915075",
+}
+
+func TestFibo(t *testing.T) {
+	for i, want := range fiboNums {
+		n := i * 10
+		got := fibo(n).decimalString()
+		if got != want {
+			t.Errorf("fibo(%d) failed: got %s want %s", n, got, want)
+		}
+	}
+}
+
+func BenchmarkFibo(b *testing.B) {
+	for i := 0; i < b.N; i++ {
+		fibo(1e0)
+		fibo(1e1)
+		fibo(1e2)
+		fibo(1e3)
+		fibo(1e4)
+		fibo(1e5)
+	}
+}
+
+var bitTests = []struct {
+	x    string
+	i    uint
+	want uint
+}{
+	{"0", 0, 0},
+	{"0", 1, 0},
+	{"0", 1000, 0},
+
+	{"0x1", 0, 1},
+	{"0x10", 0, 0},
+	{"0x10", 3, 0},
+	{"0x10", 4, 1},
+	{"0x10", 5, 0},
+
+	{"0x8000000000000000", 62, 0},
+	{"0x8000000000000000", 63, 1},
+	{"0x8000000000000000", 64, 0},
+
+	{"0x3" + strings.Repeat("0", 32), 127, 0},
+	{"0x3" + strings.Repeat("0", 32), 128, 1},
+	{"0x3" + strings.Repeat("0", 32), 129, 1},
+	{"0x3" + strings.Repeat("0", 32), 130, 0},
+}
+
+func TestBit(t *testing.T) {
+	for i, test := range bitTests {
+		x := natFromString(test.x)
+		if got := x.bit(test.i); got != test.want {
+			t.Errorf("#%d: %s.bit(%d) = %v; want %v", i, test.x, test.i, got, test.want)
+		}
+	}
+}
+
+var stickyTests = []struct {
+	x    string
+	i    uint
+	want uint
+}{
+	{"0", 0, 0},
+	{"0", 1, 0},
+	{"0", 1000, 0},
+
+	{"0x1", 0, 0},
+	{"0x1", 1, 1},
+
+	{"0x1350", 0, 0},
+	{"0x1350", 4, 0},
+	{"0x1350", 5, 1},
+
+	{"0x8000000000000000", 63, 0},
+	{"0x8000000000000000", 64, 1},
+
+	{"0x1" + strings.Repeat("0", 100), 400, 0},
+	{"0x1" + strings.Repeat("0", 100), 401, 1},
+}
+
+func TestSticky(t *testing.T) {
+	for i, test := range stickyTests {
+		x := natFromString(test.x)
+		if got := x.sticky(test.i); got != test.want {
+			t.Errorf("#%d: %s.sticky(%d) = %v; want %v", i, test.x, test.i, got, test.want)
+		}
+		if test.want == 1 {
+			// all subsequent i's should also return 1
+			for d := uint(1); d <= 3; d++ {
+				if got := x.sticky(test.i + d); got != 1 {
+					t.Errorf("#%d: %s.sticky(%d) = %v; want %v", i, test.x, test.i+d, got, 1)
+				}
+			}
+		}
+	}
+}
diff --git a/third_party/gofrontend/libgo/go/math/big/natconv.go b/third_party/gofrontend/libgo/go/math/big/natconv.go
new file mode 100644
index 0000000..022dcfe
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/math/big/natconv.go
@@ -0,0 +1,495 @@
+// 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.
+
+// This file implements nat-to-string conversion functions.
+
+package big
+
+import (
+	"errors"
+	"fmt"
+	"io"
+	"math"
+	"sync"
+)
+
+// MaxBase is the largest number base accepted for string conversions.
+const MaxBase = 'z' - 'a' + 10 + 1
+
+// maxPow returns (b**n, n) such that b**n is the largest power b**n <= _M.
+// For instance maxPow(10) == (1e19, 19) for 19 decimal digits in a 64bit Word.
+// In other words, at most n digits in base b fit into a Word.
+// TODO(gri) replace this with a table, generated at build time.
+func maxPow(b Word) (p Word, n int) {
+	p, n = b, 1 // assuming b <= _M
+	for max := _M / b; p <= max; {
+		// p == b**n && p <= max
+		p *= b
+		n++
+	}
+	// p == b**n && p <= _M
+	return
+}
+
+// pow returns x**n for n > 0, and 1 otherwise.
+func pow(x Word, n int) (p Word) {
+	// n == sum of bi * 2**i, for 0 <= i < imax, and bi is 0 or 1
+	// thus x**n == product of x**(2**i) for all i where bi == 1
+	// (Russian Peasant Method for exponentiation)
+	p = 1
+	for n > 0 {
+		if n&1 != 0 {
+			p *= x
+		}
+		x *= x
+		n >>= 1
+	}
+	return
+}
+
+// scan scans the number corresponding to the longest possible prefix
+// from r representing an unsigned number in a given conversion base.
+// It returns the corresponding natural number res, the actual base b,
+// a digit count, and a read or syntax error err, if any.
+//
+//	number   = [ prefix ] mantissa .
+//	prefix   = "0" [ "x" | "X" | "b" | "B" ] .
+//      mantissa = digits | digits "." [ digits ] | "." digits .
+//	digits   = digit { digit } .
+//	digit    = "0" ... "9" | "a" ... "z" | "A" ... "Z" .
+//
+// Unless fracOk is set, the base argument must be 0 or a value between
+// 2 and MaxBase. If fracOk is set, the base argument must be one of
+// 0, 2, 10, or 16. Providing an invalid base argument leads to a run-
+// time panic.
+//
+// For base 0, the number prefix determines the actual base: A prefix of
+// ``0x'' or ``0X'' selects base 16; if fracOk is not set, the ``0'' prefix
+// selects base 8, and a ``0b'' or ``0B'' prefix selects base 2. Otherwise
+// the selected base is 10 and no prefix is accepted.
+//
+// If fracOk is set, an octal prefix is ignored (a leading ``0'' simply
+// stands for a zero digit), and a period followed by a fractional part
+// is permitted. The result value is computed as if there were no period
+// present; and the count value is used to determine the fractional part.
+//
+// A result digit count > 0 corresponds to the number of (non-prefix) digits
+// parsed. A digit count <= 0 indicates the presence of a period (if fracOk
+// is set, only), and -count is the number of fractional digits found.
+// In this case, the actual value of the scanned number is res * b**count.
+//
+func (z nat) scan(r io.ByteScanner, base int, fracOk bool) (res nat, b, count int, err error) {
+	// reject illegal bases
+	baseOk := base == 0 ||
+		!fracOk && 2 <= base && base <= MaxBase ||
+		fracOk && (base == 2 || base == 10 || base == 16)
+	if !baseOk {
+		panic(fmt.Sprintf("illegal number base %d", base))
+	}
+
+	// one char look-ahead
+	ch, err := r.ReadByte()
+	if err != nil {
+		return
+	}
+
+	// determine actual base
+	b = base
+	if base == 0 {
+		// actual base is 10 unless there's a base prefix
+		b = 10
+		if ch == '0' {
+			count = 1
+			switch ch, err = r.ReadByte(); err {
+			case nil:
+				// possibly one of 0x, 0X, 0b, 0B
+				if !fracOk {
+					b = 8
+				}
+				switch ch {
+				case 'x', 'X':
+					b = 16
+				case 'b', 'B':
+					b = 2
+				}
+				switch b {
+				case 16, 2:
+					count = 0 // prefix is not counted
+					if ch, err = r.ReadByte(); err != nil {
+						// io.EOF is also an error in this case
+						return
+					}
+				case 8:
+					count = 0 // prefix is not counted
+				}
+			case io.EOF:
+				// input is "0"
+				res = z[:0]
+				err = nil
+				return
+			default:
+				// read error
+				return
+			}
+		}
+	}
+
+	// convert string
+	// Algorithm: Collect digits in groups of at most n digits in di
+	// and then use mulAddWW for every such group to add them to the
+	// result.
+	z = z[:0]
+	b1 := Word(b)
+	bn, n := maxPow(b1) // at most n digits in base b1 fit into Word
+	di := Word(0)       // 0 <= di < b1**i < bn
+	i := 0              // 0 <= i < n
+	dp := -1            // position of decimal point
+	for {
+		if fracOk && ch == '.' {
+			fracOk = false
+			dp = count
+			// advance
+			if ch, err = r.ReadByte(); err != nil {
+				if err == io.EOF {
+					err = nil
+					break
+				}
+				return
+			}
+		}
+
+		// convert rune into digit value d1
+		var d1 Word
+		switch {
+		case '0' <= ch && ch <= '9':
+			d1 = Word(ch - '0')
+		case 'a' <= ch && ch <= 'z':
+			d1 = Word(ch - 'a' + 10)
+		case 'A' <= ch && ch <= 'Z':
+			d1 = Word(ch - 'A' + 10)
+		default:
+			d1 = MaxBase + 1
+		}
+		if d1 >= b1 {
+			r.UnreadByte() // ch does not belong to number anymore
+			break
+		}
+		count++
+
+		// collect d1 in di
+		di = di*b1 + d1
+		i++
+
+		// if di is "full", add it to the result
+		if i == n {
+			z = z.mulAddWW(z, bn, di)
+			di = 0
+			i = 0
+		}
+
+		// advance
+		if ch, err = r.ReadByte(); err != nil {
+			if err == io.EOF {
+				err = nil
+				break
+			}
+			return
+		}
+	}
+
+	if count == 0 {
+		// no digits found
+		switch {
+		case base == 0 && b == 8:
+			// there was only the octal prefix 0 (possibly followed by digits > 7);
+			// count as one digit and return base 10, not 8
+			count = 1
+			b = 10
+		case base != 0 || b != 8:
+			// there was neither a mantissa digit nor the octal prefix 0
+			err = errors.New("syntax error scanning number")
+		}
+		return
+	}
+	// count > 0
+
+	// add remaining digits to result
+	if i > 0 {
+		z = z.mulAddWW(z, pow(b1, i), di)
+	}
+	res = z.norm()
+
+	// adjust for fraction, if any
+	if dp >= 0 {
+		// 0 <= dp <= count > 0
+		count = dp - count
+	}
+
+	return
+}
+
+// Character sets for string conversion.
+const (
+	lowercaseDigits = "0123456789abcdefghijklmnopqrstuvwxyz"
+	uppercaseDigits = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"
+)
+
+// decimalString returns a decimal representation of x.
+// It calls x.string with the charset "0123456789".
+func (x nat) decimalString() string {
+	return x.string(lowercaseDigits[:10])
+}
+
+// hexString returns a hexadecimal representation of x.
+// It calls x.string with the charset "0123456789abcdef".
+func (x nat) hexString() string {
+	return x.string(lowercaseDigits[:16])
+}
+
+// string converts x to a string using digits from a charset; a digit with
+// value d is represented by charset[d]. The conversion base is determined
+// by len(charset), which must be >= 2 and <= 256.
+func (x nat) string(charset string) string {
+	b := Word(len(charset))
+
+	// special cases
+	switch {
+	case b < 2 || b > 256:
+		panic("invalid character set length")
+	case len(x) == 0:
+		return string(charset[0])
+	}
+
+	// allocate buffer for conversion
+	i := int(float64(x.bitLen())/math.Log2(float64(b))) + 1 // off by one at most
+	s := make([]byte, i)
+
+	// convert power of two and non power of two bases separately
+	if b == b&-b {
+		// shift is base-b digit size in bits
+		shift := trailingZeroBits(b) // shift > 0 because b >= 2
+		mask := Word(1)<<shift - 1
+		w := x[0]
+		nbits := uint(_W) // number of unprocessed bits in w
+
+		// convert less-significant words
+		for k := 1; k < len(x); k++ {
+			// convert full digits
+			for nbits >= shift {
+				i--
+				s[i] = charset[w&mask]
+				w >>= shift
+				nbits -= shift
+			}
+
+			// convert any partial leading digit and advance to next word
+			if nbits == 0 {
+				// no partial digit remaining, just advance
+				w = x[k]
+				nbits = _W
+			} else {
+				// partial digit in current (k-1) and next (k) word
+				w |= x[k] << nbits
+				i--
+				s[i] = charset[w&mask]
+
+				// advance
+				w = x[k] >> (shift - nbits)
+				nbits = _W - (shift - nbits)
+			}
+		}
+
+		// convert digits of most-significant word (omit leading zeros)
+		for nbits >= 0 && w != 0 {
+			i--
+			s[i] = charset[w&mask]
+			w >>= shift
+			nbits -= shift
+		}
+
+	} else {
+		bb, ndigits := maxPow(Word(b))
+
+		// construct table of successive squares of bb*leafSize to use in subdivisions
+		// result (table != nil) <=> (len(x) > leafSize > 0)
+		table := divisors(len(x), b, ndigits, bb)
+
+		// preserve x, create local copy for use by convertWords
+		q := nat(nil).set(x)
+
+		// convert q to string s in base b
+		q.convertWords(s, charset, b, ndigits, bb, table)
+
+		// strip leading zeros
+		// (x != 0; thus s must contain at least one non-zero digit
+		// and the loop will terminate)
+		i = 0
+		for zero := charset[0]; s[i] == zero; {
+			i++
+		}
+	}
+
+	return string(s[i:])
+}
+
+// Convert words of q to base b digits in s. If q is large, it is recursively "split in half"
+// by nat/nat division using tabulated divisors. Otherwise, it is converted iteratively using
+// repeated nat/Word division.
+//
+// The iterative method processes n Words by n divW() calls, each of which visits every Word in the
+// incrementally shortened q for a total of n + (n-1) + (n-2) ... + 2 + 1, or n(n+1)/2 divW()'s.
+// Recursive conversion divides q by its approximate square root, yielding two parts, each half
+// the size of q. Using the iterative method on both halves means 2 * (n/2)(n/2 + 1)/2 divW()'s
+// plus the expensive long div(). Asymptotically, the ratio is favorable at 1/2 the divW()'s, and
+// is made better by splitting the subblocks recursively. Best is to split blocks until one more
+// split would take longer (because of the nat/nat div()) than the twice as many divW()'s of the
+// iterative approach. This threshold is represented by leafSize. Benchmarking of leafSize in the
+// range 2..64 shows that values of 8 and 16 work well, with a 4x speedup at medium lengths and
+// ~30x for 20000 digits. Use nat_test.go's BenchmarkLeafSize tests to optimize leafSize for
+// specific hardware.
+//
+func (q nat) convertWords(s []byte, charset string, b Word, ndigits int, bb Word, table []divisor) {
+	// split larger blocks recursively
+	if table != nil {
+		// len(q) > leafSize > 0
+		var r nat
+		index := len(table) - 1
+		for len(q) > leafSize {
+			// find divisor close to sqrt(q) if possible, but in any case < q
+			maxLength := q.bitLen()     // ~= log2 q, or at of least largest possible q of this bit length
+			minLength := maxLength >> 1 // ~= log2 sqrt(q)
+			for index > 0 && table[index-1].nbits > minLength {
+				index-- // desired
+			}
+			if table[index].nbits >= maxLength && table[index].bbb.cmp(q) >= 0 {
+				index--
+				if index < 0 {
+					panic("internal inconsistency")
+				}
+			}
+
+			// split q into the two digit number (q'*bbb + r) to form independent subblocks
+			q, r = q.div(r, q, table[index].bbb)
+
+			// convert subblocks and collect results in s[:h] and s[h:]
+			h := len(s) - table[index].ndigits
+			r.convertWords(s[h:], charset, b, ndigits, bb, table[0:index])
+			s = s[:h] // == q.convertWords(s, charset, b, ndigits, bb, table[0:index+1])
+		}
+	}
+
+	// having split any large blocks now process the remaining (small) block iteratively
+	i := len(s)
+	var r Word
+	if b == 10 {
+		// hard-coding for 10 here speeds this up by 1.25x (allows for / and % by constants)
+		for len(q) > 0 {
+			// extract least significant, base bb "digit"
+			q, r = q.divW(q, bb)
+			for j := 0; j < ndigits && i > 0; j++ {
+				i--
+				// avoid % computation since r%10 == r - int(r/10)*10;
+				// this appears to be faster for BenchmarkString10000Base10
+				// and smaller strings (but a bit slower for larger ones)
+				t := r / 10
+				s[i] = charset[r-t<<3-t-t] // TODO(gri) replace w/ t*10 once compiler produces better code
+				r = t
+			}
+		}
+	} else {
+		for len(q) > 0 {
+			// extract least significant, base bb "digit"
+			q, r = q.divW(q, bb)
+			for j := 0; j < ndigits && i > 0; j++ {
+				i--
+				s[i] = charset[r%b]
+				r /= b
+			}
+		}
+	}
+
+	// prepend high-order zeroes
+	zero := charset[0]
+	for i > 0 { // while need more leading zeroes
+		i--
+		s[i] = zero
+	}
+}
+
+// Split blocks greater than leafSize Words (or set to 0 to disable recursive conversion)
+// Benchmark and configure leafSize using: go test -bench="Leaf"
+//   8 and 16 effective on 3.0 GHz Xeon "Clovertown" CPU (128 byte cache lines)
+//   8 and 16 effective on 2.66 GHz Core 2 Duo "Penryn" CPU
+var leafSize int = 8 // number of Word-size binary values treat as a monolithic block
+
+type divisor struct {
+	bbb     nat // divisor
+	nbits   int // bit length of divisor (discounting leading zeroes) ~= log2(bbb)
+	ndigits int // digit length of divisor in terms of output base digits
+}
+
+var cacheBase10 struct {
+	sync.Mutex
+	table [64]divisor // cached divisors for base 10
+}
+
+// expWW computes x**y
+func (z nat) expWW(x, y Word) nat {
+	return z.expNN(nat(nil).setWord(x), nat(nil).setWord(y), nil)
+}
+
+// construct table of powers of bb*leafSize to use in subdivisions
+func divisors(m int, b Word, ndigits int, bb Word) []divisor {
+	// only compute table when recursive conversion is enabled and x is large
+	if leafSize == 0 || m <= leafSize {
+		return nil
+	}
+
+	// determine k where (bb**leafSize)**(2**k) >= sqrt(x)
+	k := 1
+	for words := leafSize; words < m>>1 && k < len(cacheBase10.table); words <<= 1 {
+		k++
+	}
+
+	// reuse and extend existing table of divisors or create new table as appropriate
+	var table []divisor // for b == 10, table overlaps with cacheBase10.table
+	if b == 10 {
+		cacheBase10.Lock()
+		table = cacheBase10.table[0:k] // reuse old table for this conversion
+	} else {
+		table = make([]divisor, k) // create new table for this conversion
+	}
+
+	// extend table
+	if table[k-1].ndigits == 0 {
+		// add new entries as needed
+		var larger nat
+		for i := 0; i < k; i++ {
+			if table[i].ndigits == 0 {
+				if i == 0 {
+					table[0].bbb = nat(nil).expWW(bb, Word(leafSize))
+					table[0].ndigits = ndigits * leafSize
+				} else {
+					table[i].bbb = nat(nil).mul(table[i-1].bbb, table[i-1].bbb)
+					table[i].ndigits = 2 * table[i-1].ndigits
+				}
+
+				// optimization: exploit aggregated extra bits in macro blocks
+				larger = nat(nil).set(table[i].bbb)
+				for mulAddVWW(larger, larger, b, 0) == 0 {
+					table[i].bbb = table[i].bbb.set(larger)
+					table[i].ndigits++
+				}
+
+				table[i].nbits = table[i].bbb.bitLen()
+			}
+		}
+	}
+
+	if b == 10 {
+		cacheBase10.Unlock()
+	}
+
+	return table
+}
diff --git a/third_party/gofrontend/libgo/go/math/big/natconv_test.go b/third_party/gofrontend/libgo/go/math/big/natconv_test.go
new file mode 100644
index 0000000..f321fbc
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/math/big/natconv_test.go
@@ -0,0 +1,425 @@
+// 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 big
+
+import (
+	"io"
+	"strings"
+	"testing"
+)
+
+func toString(x nat, charset string) string {
+	base := len(charset)
+
+	// special cases
+	switch {
+	case base < 2:
+		panic("illegal base")
+	case len(x) == 0:
+		return string(charset[0])
+	}
+
+	// allocate buffer for conversion
+	i := x.bitLen()/log2(Word(base)) + 1 // +1: round up
+	s := make([]byte, i)
+
+	// don't destroy x
+	q := nat(nil).set(x)
+
+	// convert
+	for len(q) > 0 {
+		i--
+		var r Word
+		q, r = q.divW(q, Word(base))
+		s[i] = charset[r]
+	}
+
+	return string(s[i:])
+}
+
+var strTests = []struct {
+	x nat    // nat value to be converted
+	c string // conversion charset
+	s string // expected result
+}{
+	{nil, "01", "0"},
+	{nat{1}, "01", "1"},
+	{nat{0xc5}, "01", "11000101"},
+	{nat{03271}, lowercaseDigits[:8], "3271"},
+	{nat{10}, lowercaseDigits[:10], "10"},
+	{nat{1234567890}, uppercaseDigits[:10], "1234567890"},
+	{nat{0xdeadbeef}, lowercaseDigits[:16], "deadbeef"},
+	{nat{0xdeadbeef}, uppercaseDigits[:16], "DEADBEEF"},
+	{nat{0x229be7}, lowercaseDigits[:17], "1a2b3c"},
+	{nat{0x309663e6}, uppercaseDigits[:32], "O9COV6"},
+}
+
+func TestString(t *testing.T) {
+	// test invalid character set explicitly
+	var panicStr string
+	func() {
+		defer func() {
+			panicStr = recover().(string)
+		}()
+		natOne.string("0")
+	}()
+	if panicStr != "invalid character set length" {
+		t.Errorf("expected panic for invalid character set")
+	}
+
+	for _, a := range strTests {
+		s := a.x.string(a.c)
+		if s != a.s {
+			t.Errorf("string%+v\n\tgot s = %s; want %s", a, s, a.s)
+		}
+
+		x, b, _, err := nat(nil).scan(strings.NewReader(a.s), len(a.c), false)
+		if x.cmp(a.x) != 0 {
+			t.Errorf("scan%+v\n\tgot z = %v; want %v", a, x, a.x)
+		}
+		if b != len(a.c) {
+			t.Errorf("scan%+v\n\tgot b = %d; want %d", a, b, len(a.c))
+		}
+		if err != nil {
+			t.Errorf("scan%+v\n\tgot error = %s", a, err)
+		}
+	}
+}
+
+var natScanTests = []struct {
+	s     string // string to be scanned
+	base  int    // input base
+	frac  bool   // fraction ok
+	x     nat    // expected nat
+	b     int    // expected base
+	count int    // expected digit count
+	ok    bool   // expected success
+	next  rune   // next character (or 0, if at EOF)
+}{
+	// error: no mantissa
+	{},
+	{s: "?"},
+	{base: 10},
+	{base: 36},
+	{s: "?", base: 10},
+	{s: "0x"},
+	{s: "345", base: 2},
+
+	// error: incorrect use of decimal point
+	{s: ".0"},
+	{s: ".0", base: 10},
+	{s: ".", base: 0},
+	{s: "0x.0"},
+
+	// no errors
+	{"0", 0, false, nil, 10, 1, true, 0},
+	{"0", 10, false, nil, 10, 1, true, 0},
+	{"0", 36, false, nil, 36, 1, true, 0},
+	{"1", 0, false, nat{1}, 10, 1, true, 0},
+	{"1", 10, false, nat{1}, 10, 1, true, 0},
+	{"0 ", 0, false, nil, 10, 1, true, ' '},
+	{"08", 0, false, nil, 10, 1, true, '8'},
+	{"08", 10, false, nat{8}, 10, 2, true, 0},
+	{"018", 0, false, nat{1}, 8, 1, true, '8'},
+	{"0b1", 0, false, nat{1}, 2, 1, true, 0},
+	{"0b11000101", 0, false, nat{0xc5}, 2, 8, true, 0},
+	{"03271", 0, false, nat{03271}, 8, 4, true, 0},
+	{"10ab", 0, false, nat{10}, 10, 2, true, 'a'},
+	{"1234567890", 0, false, nat{1234567890}, 10, 10, true, 0},
+	{"xyz", 36, false, nat{(33*36+34)*36 + 35}, 36, 3, true, 0},
+	{"xyz?", 36, false, nat{(33*36+34)*36 + 35}, 36, 3, true, '?'},
+	{"0x", 16, false, nil, 16, 1, true, 'x'},
+	{"0xdeadbeef", 0, false, nat{0xdeadbeef}, 16, 8, true, 0},
+	{"0XDEADBEEF", 0, false, nat{0xdeadbeef}, 16, 8, true, 0},
+
+	// no errors, decimal point
+	{"0.", 0, false, nil, 10, 1, true, '.'},
+	{"0.", 10, true, nil, 10, 0, true, 0},
+	{"0.1.2", 10, true, nat{1}, 10, -1, true, '.'},
+	{".000", 10, true, nil, 10, -3, true, 0},
+	{"12.3", 10, true, nat{123}, 10, -1, true, 0},
+	{"012.345", 10, true, nat{12345}, 10, -3, true, 0},
+}
+
+func TestScanBase(t *testing.T) {
+	for _, a := range natScanTests {
+		r := strings.NewReader(a.s)
+		x, b, count, err := nat(nil).scan(r, a.base, a.frac)
+		if err == nil && !a.ok {
+			t.Errorf("scan%+v\n\texpected error", a)
+		}
+		if err != nil {
+			if a.ok {
+				t.Errorf("scan%+v\n\tgot error = %s", a, err)
+			}
+			continue
+		}
+		if x.cmp(a.x) != 0 {
+			t.Errorf("scan%+v\n\tgot z = %v; want %v", a, x, a.x)
+		}
+		if b != a.b {
+			t.Errorf("scan%+v\n\tgot b = %d; want %d", a, b, a.base)
+		}
+		if count != a.count {
+			t.Errorf("scan%+v\n\tgot count = %d; want %d", a, count, a.count)
+		}
+		next, _, err := r.ReadRune()
+		if err == io.EOF {
+			next = 0
+			err = nil
+		}
+		if err == nil && next != a.next {
+			t.Errorf("scan%+v\n\tgot next = %q; want %q", a, next, a.next)
+		}
+	}
+}
+
+var pi = "3" +
+	"14159265358979323846264338327950288419716939937510582097494459230781640628620899862803482534211706798214808651" +
+	"32823066470938446095505822317253594081284811174502841027019385211055596446229489549303819644288109756659334461" +
+	"28475648233786783165271201909145648566923460348610454326648213393607260249141273724587006606315588174881520920" +
+	"96282925409171536436789259036001133053054882046652138414695194151160943305727036575959195309218611738193261179" +
+	"31051185480744623799627495673518857527248912279381830119491298336733624406566430860213949463952247371907021798" +
+	"60943702770539217176293176752384674818467669405132000568127145263560827785771342757789609173637178721468440901" +
+	"22495343014654958537105079227968925892354201995611212902196086403441815981362977477130996051870721134999999837" +
+	"29780499510597317328160963185950244594553469083026425223082533446850352619311881710100031378387528865875332083" +
+	"81420617177669147303598253490428755468731159562863882353787593751957781857780532171226806613001927876611195909" +
+	"21642019893809525720106548586327886593615338182796823030195203530185296899577362259941389124972177528347913151" +
+	"55748572424541506959508295331168617278558890750983817546374649393192550604009277016711390098488240128583616035" +
+	"63707660104710181942955596198946767837449448255379774726847104047534646208046684259069491293313677028989152104" +
+	"75216205696602405803815019351125338243003558764024749647326391419927260426992279678235478163600934172164121992" +
+	"45863150302861829745557067498385054945885869269956909272107975093029553211653449872027559602364806654991198818" +
+	"34797753566369807426542527862551818417574672890977772793800081647060016145249192173217214772350141441973568548" +
+	"16136115735255213347574184946843852332390739414333454776241686251898356948556209921922218427255025425688767179" +
+	"04946016534668049886272327917860857843838279679766814541009538837863609506800642251252051173929848960841284886" +
+	"26945604241965285022210661186306744278622039194945047123713786960956364371917287467764657573962413890865832645" +
+	"99581339047802759009946576407895126946839835259570982582262052248940772671947826848260147699090264013639443745" +
+	"53050682034962524517493996514314298091906592509372216964615157098583874105978859597729754989301617539284681382" +
+	"68683868942774155991855925245953959431049972524680845987273644695848653836736222626099124608051243884390451244" +
+	"13654976278079771569143599770012961608944169486855584840635342207222582848864815845602850601684273945226746767" +
+	"88952521385225499546667278239864565961163548862305774564980355936345681743241125150760694794510965960940252288" +
+	"79710893145669136867228748940560101503308617928680920874760917824938589009714909675985261365549781893129784821" +
+	"68299894872265880485756401427047755513237964145152374623436454285844479526586782105114135473573952311342716610" +
+	"21359695362314429524849371871101457654035902799344037420073105785390621983874478084784896833214457138687519435" +
+	"06430218453191048481005370614680674919278191197939952061419663428754440643745123718192179998391015919561814675" +
+	"14269123974894090718649423196156794520809514655022523160388193014209376213785595663893778708303906979207734672" +
+	"21825625996615014215030680384477345492026054146659252014974428507325186660021324340881907104863317346496514539" +
+	"05796268561005508106658796998163574736384052571459102897064140110971206280439039759515677157700420337869936007" +
+	"23055876317635942187312514712053292819182618612586732157919841484882916447060957527069572209175671167229109816" +
+	"90915280173506712748583222871835209353965725121083579151369882091444210067510334671103141267111369908658516398" +
+	"31501970165151168517143765761835155650884909989859982387345528331635507647918535893226185489632132933089857064" +
+	"20467525907091548141654985946163718027098199430992448895757128289059232332609729971208443357326548938239119325" +
+	"97463667305836041428138830320382490375898524374417029132765618093773444030707469211201913020330380197621101100" +
+	"44929321516084244485963766983895228684783123552658213144957685726243344189303968642624341077322697802807318915" +
+	"44110104468232527162010526522721116603966655730925471105578537634668206531098965269186205647693125705863566201" +
+	"85581007293606598764861179104533488503461136576867532494416680396265797877185560845529654126654085306143444318" +
+	"58676975145661406800700237877659134401712749470420562230538994561314071127000407854733269939081454664645880797" +
+	"27082668306343285878569830523580893306575740679545716377525420211495576158140025012622859413021647155097925923" +
+	"09907965473761255176567513575178296664547791745011299614890304639947132962107340437518957359614589019389713111" +
+	"79042978285647503203198691514028708085990480109412147221317947647772622414254854540332157185306142288137585043" +
+	"06332175182979866223717215916077166925474873898665494945011465406284336639379003976926567214638530673609657120" +
+	"91807638327166416274888800786925602902284721040317211860820419000422966171196377921337575114959501566049631862" +
+	"94726547364252308177036751590673502350728354056704038674351362222477158915049530984448933309634087807693259939" +
+	"78054193414473774418426312986080998886874132604721569516239658645730216315981931951673538129741677294786724229" +
+	"24654366800980676928238280689964004824354037014163149658979409243237896907069779422362508221688957383798623001" +
+	"59377647165122893578601588161755782973523344604281512627203734314653197777416031990665541876397929334419521541" +
+	"34189948544473456738316249934191318148092777710386387734317720754565453220777092120190516609628049092636019759" +
+	"88281613323166636528619326686336062735676303544776280350450777235547105859548702790814356240145171806246436267" +
+	"94561275318134078330336254232783944975382437205835311477119926063813346776879695970309833913077109870408591337"
+
+// Test case for BenchmarkScanPi.
+func TestScanPi(t *testing.T) {
+	var x nat
+	z, _, _, err := x.scan(strings.NewReader(pi), 10, false)
+	if err != nil {
+		t.Errorf("scanning pi: %s", err)
+	}
+	if s := z.decimalString(); s != pi {
+		t.Errorf("scanning pi: got %s", s)
+	}
+}
+
+func TestScanPiParallel(t *testing.T) {
+	const n = 2
+	c := make(chan int)
+	for i := 0; i < n; i++ {
+		go func() {
+			TestScanPi(t)
+			c <- 0
+		}()
+	}
+	for i := 0; i < n; i++ {
+		<-c
+	}
+}
+
+func BenchmarkScanPi(b *testing.B) {
+	for i := 0; i < b.N; i++ {
+		var x nat
+		x.scan(strings.NewReader(pi), 10, false)
+	}
+}
+
+func BenchmarkStringPiParallel(b *testing.B) {
+	var x nat
+	x, _, _, _ = x.scan(strings.NewReader(pi), 0, false)
+	if x.decimalString() != pi {
+		panic("benchmark incorrect: conversion failed")
+	}
+	b.RunParallel(func(pb *testing.PB) {
+		for pb.Next() {
+			x.decimalString()
+		}
+	})
+}
+
+func BenchmarkScan10Base2(b *testing.B)     { ScanHelper(b, 2, 10, 10) }
+func BenchmarkScan100Base2(b *testing.B)    { ScanHelper(b, 2, 10, 100) }
+func BenchmarkScan1000Base2(b *testing.B)   { ScanHelper(b, 2, 10, 1000) }
+func BenchmarkScan10000Base2(b *testing.B)  { ScanHelper(b, 2, 10, 10000) }
+func BenchmarkScan100000Base2(b *testing.B) { ScanHelper(b, 2, 10, 100000) }
+
+func BenchmarkScan10Base8(b *testing.B)     { ScanHelper(b, 8, 10, 10) }
+func BenchmarkScan100Base8(b *testing.B)    { ScanHelper(b, 8, 10, 100) }
+func BenchmarkScan1000Base8(b *testing.B)   { ScanHelper(b, 8, 10, 1000) }
+func BenchmarkScan10000Base8(b *testing.B)  { ScanHelper(b, 8, 10, 10000) }
+func BenchmarkScan100000Base8(b *testing.B) { ScanHelper(b, 8, 10, 100000) }
+
+func BenchmarkScan10Base10(b *testing.B)     { ScanHelper(b, 10, 10, 10) }
+func BenchmarkScan100Base10(b *testing.B)    { ScanHelper(b, 10, 10, 100) }
+func BenchmarkScan1000Base10(b *testing.B)   { ScanHelper(b, 10, 10, 1000) }
+func BenchmarkScan10000Base10(b *testing.B)  { ScanHelper(b, 10, 10, 10000) }
+func BenchmarkScan100000Base10(b *testing.B) { ScanHelper(b, 10, 10, 100000) }
+
+func BenchmarkScan10Base16(b *testing.B)     { ScanHelper(b, 16, 10, 10) }
+func BenchmarkScan100Base16(b *testing.B)    { ScanHelper(b, 16, 10, 100) }
+func BenchmarkScan1000Base16(b *testing.B)   { ScanHelper(b, 16, 10, 1000) }
+func BenchmarkScan10000Base16(b *testing.B)  { ScanHelper(b, 16, 10, 10000) }
+func BenchmarkScan100000Base16(b *testing.B) { ScanHelper(b, 16, 10, 100000) }
+
+func ScanHelper(b *testing.B, base int, x, y Word) {
+	b.StopTimer()
+	var z nat
+	z = z.expWW(x, y)
+
+	var s string
+	s = z.string(lowercaseDigits[:base])
+	if t := toString(z, lowercaseDigits[:base]); t != s {
+		b.Fatalf("scanning: got %s; want %s", s, t)
+	}
+	b.StartTimer()
+
+	for i := 0; i < b.N; i++ {
+		z.scan(strings.NewReader(s), base, false)
+	}
+}
+
+func BenchmarkString10Base2(b *testing.B)     { StringHelper(b, 2, 10, 10) }
+func BenchmarkString100Base2(b *testing.B)    { StringHelper(b, 2, 10, 100) }
+func BenchmarkString1000Base2(b *testing.B)   { StringHelper(b, 2, 10, 1000) }
+func BenchmarkString10000Base2(b *testing.B)  { StringHelper(b, 2, 10, 10000) }
+func BenchmarkString100000Base2(b *testing.B) { StringHelper(b, 2, 10, 100000) }
+
+func BenchmarkString10Base8(b *testing.B)     { StringHelper(b, 8, 10, 10) }
+func BenchmarkString100Base8(b *testing.B)    { StringHelper(b, 8, 10, 100) }
+func BenchmarkString1000Base8(b *testing.B)   { StringHelper(b, 8, 10, 1000) }
+func BenchmarkString10000Base8(b *testing.B)  { StringHelper(b, 8, 10, 10000) }
+func BenchmarkString100000Base8(b *testing.B) { StringHelper(b, 8, 10, 100000) }
+
+func BenchmarkString10Base10(b *testing.B)     { StringHelper(b, 10, 10, 10) }
+func BenchmarkString100Base10(b *testing.B)    { StringHelper(b, 10, 10, 100) }
+func BenchmarkString1000Base10(b *testing.B)   { StringHelper(b, 10, 10, 1000) }
+func BenchmarkString10000Base10(b *testing.B)  { StringHelper(b, 10, 10, 10000) }
+func BenchmarkString100000Base10(b *testing.B) { StringHelper(b, 10, 10, 100000) }
+
+func BenchmarkString10Base16(b *testing.B)     { StringHelper(b, 16, 10, 10) }
+func BenchmarkString100Base16(b *testing.B)    { StringHelper(b, 16, 10, 100) }
+func BenchmarkString1000Base16(b *testing.B)   { StringHelper(b, 16, 10, 1000) }
+func BenchmarkString10000Base16(b *testing.B)  { StringHelper(b, 16, 10, 10000) }
+func BenchmarkString100000Base16(b *testing.B) { StringHelper(b, 16, 10, 100000) }
+
+func StringHelper(b *testing.B, base int, x, y Word) {
+	b.StopTimer()
+	var z nat
+	z = z.expWW(x, y)
+	z.string(lowercaseDigits[:base]) // warm divisor cache
+	b.StartTimer()
+
+	for i := 0; i < b.N; i++ {
+		_ = z.string(lowercaseDigits[:base])
+	}
+}
+
+func BenchmarkLeafSize0(b *testing.B)  { LeafSizeHelper(b, 10, 0) } // test without splitting
+func BenchmarkLeafSize1(b *testing.B)  { LeafSizeHelper(b, 10, 1) }
+func BenchmarkLeafSize2(b *testing.B)  { LeafSizeHelper(b, 10, 2) }
+func BenchmarkLeafSize3(b *testing.B)  { LeafSizeHelper(b, 10, 3) }
+func BenchmarkLeafSize4(b *testing.B)  { LeafSizeHelper(b, 10, 4) }
+func BenchmarkLeafSize5(b *testing.B)  { LeafSizeHelper(b, 10, 5) }
+func BenchmarkLeafSize6(b *testing.B)  { LeafSizeHelper(b, 10, 6) }
+func BenchmarkLeafSize7(b *testing.B)  { LeafSizeHelper(b, 10, 7) }
+func BenchmarkLeafSize8(b *testing.B)  { LeafSizeHelper(b, 10, 8) }
+func BenchmarkLeafSize9(b *testing.B)  { LeafSizeHelper(b, 10, 9) }
+func BenchmarkLeafSize10(b *testing.B) { LeafSizeHelper(b, 10, 10) }
+func BenchmarkLeafSize11(b *testing.B) { LeafSizeHelper(b, 10, 11) }
+func BenchmarkLeafSize12(b *testing.B) { LeafSizeHelper(b, 10, 12) }
+func BenchmarkLeafSize13(b *testing.B) { LeafSizeHelper(b, 10, 13) }
+func BenchmarkLeafSize14(b *testing.B) { LeafSizeHelper(b, 10, 14) }
+func BenchmarkLeafSize15(b *testing.B) { LeafSizeHelper(b, 10, 15) }
+func BenchmarkLeafSize16(b *testing.B) { LeafSizeHelper(b, 10, 16) }
+func BenchmarkLeafSize32(b *testing.B) { LeafSizeHelper(b, 10, 32) } // try some large lengths
+func BenchmarkLeafSize64(b *testing.B) { LeafSizeHelper(b, 10, 64) }
+
+func LeafSizeHelper(b *testing.B, base Word, size int) {
+	b.StopTimer()
+	originalLeafSize := leafSize
+	resetTable(cacheBase10.table[:])
+	leafSize = size
+	b.StartTimer()
+
+	for d := 1; d <= 10000; d *= 10 {
+		b.StopTimer()
+		var z nat
+		z = z.expWW(base, Word(d))           // build target number
+		_ = z.string(lowercaseDigits[:base]) // warm divisor cache
+		b.StartTimer()
+
+		for i := 0; i < b.N; i++ {
+			_ = z.string(lowercaseDigits[:base])
+		}
+	}
+
+	b.StopTimer()
+	resetTable(cacheBase10.table[:])
+	leafSize = originalLeafSize
+	b.StartTimer()
+}
+
+func resetTable(table []divisor) {
+	if table != nil && table[0].bbb != nil {
+		for i := 0; i < len(table); i++ {
+			table[i].bbb = nil
+			table[i].nbits = 0
+			table[i].ndigits = 0
+		}
+	}
+}
+
+func TestStringPowers(t *testing.T) {
+	var b, p Word
+	for b = 2; b <= 16; b++ {
+		for p = 0; p <= 512; p++ {
+			x := nat(nil).expWW(b, p)
+			xs := x.string(lowercaseDigits[:b])
+			xs2 := toString(x, lowercaseDigits[:b])
+			if xs != xs2 {
+				t.Errorf("failed at %d ** %d in base %d: %s != %s", b, p, b, xs, xs2)
+			}
+		}
+		if b >= 3 && testing.Short() {
+			break
+		}
+	}
+}
diff --git a/third_party/gofrontend/libgo/go/math/big/rat.go b/third_party/gofrontend/libgo/go/math/big/rat.go
index c5339fe..fb16f18 100644
--- a/third_party/gofrontend/libgo/go/math/big/rat.go
+++ b/third_party/gofrontend/libgo/go/math/big/rat.go
@@ -11,7 +11,6 @@
 	"errors"
 	"fmt"
 	"math"
-	"strings"
 )
 
 // A Rat represents a quotient a/b of arbitrary precision.
@@ -324,14 +323,14 @@
 // SetInt sets z to x (by making a copy of x) and returns z.
 func (z *Rat) SetInt(x *Int) *Rat {
 	z.a.Set(x)
-	z.b.abs = z.b.abs.make(0)
+	z.b.abs = z.b.abs[:0]
 	return z
 }
 
 // SetInt64 sets z to x and returns z.
 func (z *Rat) SetInt64(x int64) *Rat {
 	z.a.SetInt64(x)
-	z.b.abs = z.b.abs.make(0)
+	z.b.abs = z.b.abs[:0]
 	return z
 }
 
@@ -370,7 +369,7 @@
 	}
 	b := z.a.abs
 	if b.cmp(natOne) == 0 {
-		b = b.make(0) // normalize denominator
+		b = b[:0] // normalize denominator
 	}
 	z.a.abs, z.b.abs = a, b // sign doesn't change
 	return z
@@ -386,7 +385,7 @@
 	return x.a.Sign()
 }
 
-// IsInt returns true if the denominator of x is 1.
+// IsInt reports whether the denominator of x is 1.
 func (x *Rat) IsInt() bool {
 	return len(x.b.abs) == 0 || x.b.abs.cmp(natOne) == 0
 }
@@ -415,12 +414,12 @@
 	case len(z.a.abs) == 0:
 		// z == 0 - normalize sign and denominator
 		z.a.neg = false
-		z.b.abs = z.b.abs.make(0)
+		z.b.abs = z.b.abs[:0]
 	case len(z.b.abs) == 0:
 		// z is normalized int - nothing to do
 	case z.b.abs.cmp(natOne) == 0:
 		// z is int - normalize denominator
-		z.b.abs = z.b.abs.make(0)
+		z.b.abs = z.b.abs[:0]
 	default:
 		neg := z.a.neg
 		z.a.neg = false
@@ -430,7 +429,7 @@
 			z.b.abs, _ = z.b.abs.div(nil, z.b.abs, f.abs)
 			if z.b.abs.cmp(natOne) == 0 {
 				// z is int - normalize denominator
-				z.b.abs = z.b.abs.make(0)
+				z.b.abs = z.b.abs[:0]
 			}
 		}
 		z.a.neg = neg
@@ -512,151 +511,6 @@
 	return z.norm()
 }
 
-func ratTok(ch rune) bool {
-	return strings.IndexRune("+-/0123456789.eE", ch) >= 0
-}
-
-// Scan is a support routine for fmt.Scanner. It accepts the formats
-// 'e', 'E', 'f', 'F', 'g', 'G', and 'v'. All formats are equivalent.
-func (z *Rat) Scan(s fmt.ScanState, ch rune) error {
-	tok, err := s.Token(true, ratTok)
-	if err != nil {
-		return err
-	}
-	if strings.IndexRune("efgEFGv", ch) < 0 {
-		return errors.New("Rat.Scan: invalid verb")
-	}
-	if _, ok := z.SetString(string(tok)); !ok {
-		return errors.New("Rat.Scan: invalid syntax")
-	}
-	return nil
-}
-
-// SetString sets z to the value of s and returns z and a boolean indicating
-// success. s can be given as a fraction "a/b" or as a floating-point number
-// optionally followed by an exponent. If the operation failed, the value of
-// z is undefined but the returned value is nil.
-func (z *Rat) SetString(s string) (*Rat, bool) {
-	if len(s) == 0 {
-		return nil, false
-	}
-
-	// check for a quotient
-	sep := strings.Index(s, "/")
-	if sep >= 0 {
-		if _, ok := z.a.SetString(s[0:sep], 10); !ok {
-			return nil, false
-		}
-		s = s[sep+1:]
-		var err error
-		if z.b.abs, _, err = z.b.abs.scan(strings.NewReader(s), 10); err != nil {
-			return nil, false
-		}
-		if len(z.b.abs) == 0 {
-			return nil, false
-		}
-		return z.norm(), true
-	}
-
-	// check for a decimal point
-	sep = strings.Index(s, ".")
-	// check for an exponent
-	e := strings.IndexAny(s, "eE")
-	var exp Int
-	if e >= 0 {
-		if e < sep {
-			// The E must come after the decimal point.
-			return nil, false
-		}
-		if _, ok := exp.SetString(s[e+1:], 10); !ok {
-			return nil, false
-		}
-		s = s[0:e]
-	}
-	if sep >= 0 {
-		s = s[0:sep] + s[sep+1:]
-		exp.Sub(&exp, NewInt(int64(len(s)-sep)))
-	}
-
-	if _, ok := z.a.SetString(s, 10); !ok {
-		return nil, false
-	}
-	powTen := nat(nil).expNN(natTen, exp.abs, nil)
-	if exp.neg {
-		z.b.abs = powTen
-		z.norm()
-	} else {
-		z.a.abs = z.a.abs.mul(z.a.abs, powTen)
-		z.b.abs = z.b.abs.make(0)
-	}
-
-	return z, true
-}
-
-// String returns a string representation of x in the form "a/b" (even if b == 1).
-func (x *Rat) String() string {
-	s := "/1"
-	if len(x.b.abs) != 0 {
-		s = "/" + x.b.abs.decimalString()
-	}
-	return x.a.String() + s
-}
-
-// RatString returns a string representation of x in the form "a/b" if b != 1,
-// and in the form "a" if b == 1.
-func (x *Rat) RatString() string {
-	if x.IsInt() {
-		return x.a.String()
-	}
-	return x.String()
-}
-
-// FloatString returns a string representation of x in decimal form with prec
-// digits of precision after the decimal point and the last digit rounded.
-func (x *Rat) FloatString(prec int) string {
-	if x.IsInt() {
-		s := x.a.String()
-		if prec > 0 {
-			s += "." + strings.Repeat("0", prec)
-		}
-		return s
-	}
-	// x.b.abs != 0
-
-	q, r := nat(nil).div(nat(nil), x.a.abs, x.b.abs)
-
-	p := natOne
-	if prec > 0 {
-		p = nat(nil).expNN(natTen, nat(nil).setUint64(uint64(prec)), nil)
-	}
-
-	r = r.mul(r, p)
-	r, r2 := r.div(nat(nil), r, x.b.abs)
-
-	// see if we need to round up
-	r2 = r2.add(r2, r2)
-	if x.b.abs.cmp(r2) <= 0 {
-		r = r.add(r, natOne)
-		if r.cmp(p) >= 0 {
-			q = nat(nil).add(q, natOne)
-			r = nat(nil).sub(r, p)
-		}
-	}
-
-	s := q.decimalString()
-	if x.a.neg {
-		s = "-" + s
-	}
-
-	if prec > 0 {
-		rs := r.decimalString()
-		leadingZeros := prec - len(rs)
-		s += "." + strings.Repeat("0", leadingZeros) + rs
-	}
-
-	return s
-}
-
 // Gob codec version. Permits backward-compatible changes to the encoding.
 const ratGobVersion byte = 1
 
@@ -667,7 +521,7 @@
 	}
 	buf := make([]byte, 1+4+(len(x.a.abs)+len(x.b.abs))*_S) // extra bytes for version and sign bit (1), and numerator length (4)
 	i := x.b.abs.bytes(buf)
-	j := x.a.abs.bytes(buf[0:i])
+	j := x.a.abs.bytes(buf[:i])
 	n := i - j
 	if int(uint32(n)) != n {
 		// this should never happen
@@ -692,7 +546,7 @@
 	}
 	b := buf[0]
 	if b>>1 != ratGobVersion {
-		return errors.New(fmt.Sprintf("Rat.GobDecode: encoding version %d not supported", b>>1))
+		return fmt.Errorf("Rat.GobDecode: encoding version %d not supported", b>>1)
 	}
 	const j = 1 + 4
 	i := j + binary.BigEndian.Uint32(buf[j-4:j])
diff --git a/third_party/gofrontend/libgo/go/math/big/rat_test.go b/third_party/gofrontend/libgo/go/math/big/rat_test.go
index 5dbbb35..012d0c4 100644
--- a/third_party/gofrontend/libgo/go/math/big/rat_test.go
+++ b/third_party/gofrontend/libgo/go/math/big/rat_test.go
@@ -9,10 +9,7 @@
 	"encoding/gob"
 	"encoding/json"
 	"encoding/xml"
-	"fmt"
 	"math"
-	"strconv"
-	"strings"
 	"testing"
 )
 
@@ -56,112 +53,6 @@
 	z.Quo(&x, &y)
 }
 
-var setStringTests = []struct {
-	in, out string
-	ok      bool
-}{
-	{"0", "0", true},
-	{"-0", "0", true},
-	{"1", "1", true},
-	{"-1", "-1", true},
-	{"1.", "1", true},
-	{"1e0", "1", true},
-	{"1.e1", "10", true},
-	{in: "1e", ok: false},
-	{in: "1.e", ok: false},
-	{in: "1e+14e-5", ok: false},
-	{in: "1e4.5", ok: false},
-	{in: "r", ok: false},
-	{in: "a/b", ok: false},
-	{in: "a.b", ok: false},
-	{"-0.1", "-1/10", true},
-	{"-.1", "-1/10", true},
-	{"2/4", "1/2", true},
-	{".25", "1/4", true},
-	{"-1/5", "-1/5", true},
-	{"8129567.7690E14", "812956776900000000000", true},
-	{"78189e+4", "781890000", true},
-	{"553019.8935e+8", "55301989350000", true},
-	{"98765432109876543210987654321e-10", "98765432109876543210987654321/10000000000", true},
-	{"9877861857500000E-7", "3951144743/4", true},
-	{"2169378.417e-3", "2169378417/1000000", true},
-	{"884243222337379604041632732738665534", "884243222337379604041632732738665534", true},
-	{"53/70893980658822810696", "53/70893980658822810696", true},
-	{"106/141787961317645621392", "53/70893980658822810696", true},
-	{"204211327800791583.81095", "4084226556015831676219/20000", true},
-	{in: "1/0", ok: false},
-}
-
-func TestRatSetString(t *testing.T) {
-	for i, test := range setStringTests {
-		x, ok := new(Rat).SetString(test.in)
-
-		if ok {
-			if !test.ok {
-				t.Errorf("#%d SetString(%q) expected failure", i, test.in)
-			} else if x.RatString() != test.out {
-				t.Errorf("#%d SetString(%q) got %s want %s", i, test.in, x.RatString(), test.out)
-			}
-		} else if x != nil {
-			t.Errorf("#%d SetString(%q) got %p want nil", i, test.in, x)
-		}
-	}
-}
-
-func TestRatScan(t *testing.T) {
-	var buf bytes.Buffer
-	for i, test := range setStringTests {
-		x := new(Rat)
-		buf.Reset()
-		buf.WriteString(test.in)
-
-		_, err := fmt.Fscanf(&buf, "%v", x)
-		if err == nil != test.ok {
-			if test.ok {
-				t.Errorf("#%d error: %s", i, err)
-			} else {
-				t.Errorf("#%d expected error", i)
-			}
-			continue
-		}
-		if err == nil && x.RatString() != test.out {
-			t.Errorf("#%d got %s want %s", i, x.RatString(), test.out)
-		}
-	}
-}
-
-var floatStringTests = []struct {
-	in   string
-	prec int
-	out  string
-}{
-	{"0", 0, "0"},
-	{"0", 4, "0.0000"},
-	{"1", 0, "1"},
-	{"1", 2, "1.00"},
-	{"-1", 0, "-1"},
-	{".25", 2, "0.25"},
-	{".25", 1, "0.3"},
-	{".25", 3, "0.250"},
-	{"-1/3", 3, "-0.333"},
-	{"-2/3", 4, "-0.6667"},
-	{"0.96", 1, "1.0"},
-	{"0.999", 2, "1.00"},
-	{"0.9", 0, "1"},
-	{".25", -1, "0"},
-	{".55", -1, "1"},
-}
-
-func TestFloatString(t *testing.T) {
-	for i, test := range floatStringTests {
-		x, _ := new(Rat).SetString(test.in)
-
-		if x.FloatString(test.prec) != test.out {
-			t.Errorf("#%d got %s want %s", i, x.FloatString(test.prec), test.out)
-		}
-	}
-}
-
 func TestRatSign(t *testing.T) {
 	zero := NewRat(0, 1)
 	for _, a := range setStringTests {
@@ -592,321 +483,6 @@
 	}
 }
 
-// Test inputs to Rat.SetString.  The prefix "long:" causes the test
-// to be skipped in --test.short mode.  (The threshold is about 500us.)
-var float64inputs = []string{
-	// Constants plundered from strconv/testfp.txt.
-
-	// Table 1: Stress Inputs for Conversion to 53-bit Binary, < 1/2 ULP
-	"5e+125",
-	"69e+267",
-	"999e-026",
-	"7861e-034",
-	"75569e-254",
-	"928609e-261",
-	"9210917e+080",
-	"84863171e+114",
-	"653777767e+273",
-	"5232604057e-298",
-	"27235667517e-109",
-	"653532977297e-123",
-	"3142213164987e-294",
-	"46202199371337e-072",
-	"231010996856685e-073",
-	"9324754620109615e+212",
-	"78459735791271921e+049",
-	"272104041512242479e+200",
-	"6802601037806061975e+198",
-	"20505426358836677347e-221",
-	"836168422905420598437e-234",
-	"4891559871276714924261e+222",
-
-	// Table 2: Stress Inputs for Conversion to 53-bit Binary, > 1/2 ULP
-	"9e-265",
-	"85e-037",
-	"623e+100",
-	"3571e+263",
-	"81661e+153",
-	"920657e-023",
-	"4603285e-024",
-	"87575437e-309",
-	"245540327e+122",
-	"6138508175e+120",
-	"83356057653e+193",
-	"619534293513e+124",
-	"2335141086879e+218",
-	"36167929443327e-159",
-	"609610927149051e-255",
-	"3743626360493413e-165",
-	"94080055902682397e-242",
-	"899810892172646163e+283",
-	"7120190517612959703e+120",
-	"25188282901709339043e-252",
-	"308984926168550152811e-052",
-	"6372891218502368041059e+064",
-
-	// Table 14: Stress Inputs for Conversion to 24-bit Binary, <1/2 ULP
-	"5e-20",
-	"67e+14",
-	"985e+15",
-	"7693e-42",
-	"55895e-16",
-	"996622e-44",
-	"7038531e-32",
-	"60419369e-46",
-	"702990899e-20",
-	"6930161142e-48",
-	"25933168707e+13",
-	"596428896559e+20",
-
-	// Table 15: Stress Inputs for Conversion to 24-bit Binary, >1/2 ULP
-	"3e-23",
-	"57e+18",
-	"789e-35",
-	"2539e-18",
-	"76173e+28",
-	"887745e-11",
-	"5382571e-37",
-	"82381273e-35",
-	"750486563e-38",
-	"3752432815e-39",
-	"75224575729e-45",
-	"459926601011e+15",
-
-	// Constants plundered from strconv/atof_test.go.
-
-	"0",
-	"1",
-	"+1",
-	"1e23",
-	"1E23",
-	"100000000000000000000000",
-	"1e-100",
-	"123456700",
-	"99999999999999974834176",
-	"100000000000000000000001",
-	"100000000000000008388608",
-	"100000000000000016777215",
-	"100000000000000016777216",
-	"-1",
-	"-0.1",
-	"-0", // NB: exception made for this input
-	"1e-20",
-	"625e-3",
-
-	// largest float64
-	"1.7976931348623157e308",
-	"-1.7976931348623157e308",
-	// next float64 - too large
-	"1.7976931348623159e308",
-	"-1.7976931348623159e308",
-	// the border is ...158079
-	// borderline - okay
-	"1.7976931348623158e308",
-	"-1.7976931348623158e308",
-	// borderline - too large
-	"1.797693134862315808e308",
-	"-1.797693134862315808e308",
-
-	// a little too large
-	"1e308",
-	"2e308",
-	"1e309",
-
-	// way too large
-	"1e310",
-	"-1e310",
-	"1e400",
-	"-1e400",
-	"long:1e400000",
-	"long:-1e400000",
-
-	// denormalized
-	"1e-305",
-	"1e-306",
-	"1e-307",
-	"1e-308",
-	"1e-309",
-	"1e-310",
-	"1e-322",
-	// smallest denormal
-	"5e-324",
-	"4e-324",
-	"3e-324",
-	// too small
-	"2e-324",
-	// way too small
-	"1e-350",
-	"long:1e-400000",
-	// way too small, negative
-	"-1e-350",
-	"long:-1e-400000",
-
-	// try to overflow exponent
-	// [Disabled: too slow and memory-hungry with rationals.]
-	// "1e-4294967296",
-	// "1e+4294967296",
-	// "1e-18446744073709551616",
-	// "1e+18446744073709551616",
-
-	// http://www.exploringbinary.com/java-hangs-when-converting-2-2250738585072012e-308/
-	"2.2250738585072012e-308",
-	// http://www.exploringbinary.com/php-hangs-on-numeric-value-2-2250738585072011e-308/
-	"2.2250738585072011e-308",
-
-	// A very large number (initially wrongly parsed by the fast algorithm).
-	"4.630813248087435e+307",
-
-	// A different kind of very large number.
-	"22.222222222222222",
-	"long:2." + strings.Repeat("2", 4000) + "e+1",
-
-	// Exactly halfway between 1 and math.Nextafter(1, 2).
-	// Round to even (down).
-	"1.00000000000000011102230246251565404236316680908203125",
-	// Slightly lower; still round down.
-	"1.00000000000000011102230246251565404236316680908203124",
-	// Slightly higher; round up.
-	"1.00000000000000011102230246251565404236316680908203126",
-	// Slightly higher, but you have to read all the way to the end.
-	"long:1.00000000000000011102230246251565404236316680908203125" + strings.Repeat("0", 10000) + "1",
-
-	// Smallest denormal, 2^(-1022-52)
-	"4.940656458412465441765687928682213723651e-324",
-	// Half of smallest denormal, 2^(-1022-53)
-	"2.470328229206232720882843964341106861825e-324",
-	// A little more than the exact half of smallest denormal
-	// 2^-1075 + 2^-1100.  (Rounds to 1p-1074.)
-	"2.470328302827751011111470718709768633275e-324",
-	// The exact halfway between smallest normal and largest denormal:
-	// 2^-1022 - 2^-1075.  (Rounds to 2^-1022.)
-	"2.225073858507201136057409796709131975935e-308",
-
-	"1152921504606846975",  //   1<<60 - 1
-	"-1152921504606846975", // -(1<<60 - 1)
-	"1152921504606846977",  //   1<<60 + 1
-	"-1152921504606846977", // -(1<<60 + 1)
-
-	"1/3",
-}
-
-// isFinite reports whether f represents a finite rational value.
-// It is equivalent to !math.IsNan(f) && !math.IsInf(f, 0).
-func isFinite(f float64) bool {
-	return math.Abs(f) <= math.MaxFloat64
-}
-
-func TestFloat32SpecialCases(t *testing.T) {
-	for _, input := range float64inputs {
-		if strings.HasPrefix(input, "long:") {
-			if testing.Short() {
-				continue
-			}
-			input = input[len("long:"):]
-		}
-
-		r, ok := new(Rat).SetString(input)
-		if !ok {
-			t.Errorf("Rat.SetString(%q) failed", input)
-			continue
-		}
-		f, exact := r.Float32()
-
-		// 1. Check string -> Rat -> float32 conversions are
-		// consistent with strconv.ParseFloat.
-		// Skip this check if the input uses "a/b" rational syntax.
-		if !strings.Contains(input, "/") {
-			e64, _ := strconv.ParseFloat(input, 32)
-			e := float32(e64)
-
-			// Careful: negative Rats too small for
-			// float64 become -0, but Rat obviously cannot
-			// preserve the sign from SetString("-0").
-			switch {
-			case math.Float32bits(e) == math.Float32bits(f):
-				// Ok: bitwise equal.
-			case f == 0 && r.Num().BitLen() == 0:
-				// Ok: Rat(0) is equivalent to both +/- float64(0).
-			default:
-				t.Errorf("strconv.ParseFloat(%q) = %g (%b), want %g (%b); delta = %g", input, e, e, f, f, f-e)
-			}
-		}
-
-		if !isFinite(float64(f)) {
-			continue
-		}
-
-		// 2. Check f is best approximation to r.
-		if !checkIsBestApprox32(t, f, r) {
-			// Append context information.
-			t.Errorf("(input was %q)", input)
-		}
-
-		// 3. Check f->R->f roundtrip is non-lossy.
-		checkNonLossyRoundtrip32(t, f)
-
-		// 4. Check exactness using slow algorithm.
-		if wasExact := new(Rat).SetFloat64(float64(f)).Cmp(r) == 0; wasExact != exact {
-			t.Errorf("Rat.SetString(%q).Float32().exact = %t, want %t", input, exact, wasExact)
-		}
-	}
-}
-
-func TestFloat64SpecialCases(t *testing.T) {
-	for _, input := range float64inputs {
-		if strings.HasPrefix(input, "long:") {
-			if testing.Short() {
-				continue
-			}
-			input = input[len("long:"):]
-		}
-
-		r, ok := new(Rat).SetString(input)
-		if !ok {
-			t.Errorf("Rat.SetString(%q) failed", input)
-			continue
-		}
-		f, exact := r.Float64()
-
-		// 1. Check string -> Rat -> float64 conversions are
-		// consistent with strconv.ParseFloat.
-		// Skip this check if the input uses "a/b" rational syntax.
-		if !strings.Contains(input, "/") {
-			e, _ := strconv.ParseFloat(input, 64)
-
-			// Careful: negative Rats too small for
-			// float64 become -0, but Rat obviously cannot
-			// preserve the sign from SetString("-0").
-			switch {
-			case math.Float64bits(e) == math.Float64bits(f):
-				// Ok: bitwise equal.
-			case f == 0 && r.Num().BitLen() == 0:
-				// Ok: Rat(0) is equivalent to both +/- float64(0).
-			default:
-				t.Errorf("strconv.ParseFloat(%q) = %g (%b), want %g (%b); delta = %g", input, e, e, f, f, f-e)
-			}
-		}
-
-		if !isFinite(f) {
-			continue
-		}
-
-		// 2. Check f is best approximation to r.
-		if !checkIsBestApprox64(t, f, r) {
-			// Append context information.
-			t.Errorf("(input was %q)", input)
-		}
-
-		// 3. Check f->R->f roundtrip is non-lossy.
-		checkNonLossyRoundtrip64(t, f)
-
-		// 4. Check exactness using slow algorithm.
-		if wasExact := new(Rat).SetFloat64(f).Cmp(r) == 0; wasExact != exact {
-			t.Errorf("Rat.SetString(%q).Float64().exact = %t, want %t", input, exact, wasExact)
-		}
-	}
-}
-
 func TestFloat32Distribution(t *testing.T) {
 	// Generate a distribution of (sign, mantissa, exp) values
 	// broader than the float32 range, and check Rat.Float32()
diff --git a/third_party/gofrontend/libgo/go/math/big/ratconv.go b/third_party/gofrontend/libgo/go/math/big/ratconv.go
new file mode 100644
index 0000000..961ff64
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/math/big/ratconv.go
@@ -0,0 +1,252 @@
+// 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.
+
+// This file implements rat-to-string conversion functions.
+
+package big
+
+import (
+	"errors"
+	"fmt"
+	"io"
+	"strconv"
+	"strings"
+)
+
+func ratTok(ch rune) bool {
+	return strings.IndexRune("+-/0123456789.eE", ch) >= 0
+}
+
+// Scan is a support routine for fmt.Scanner. It accepts the formats
+// 'e', 'E', 'f', 'F', 'g', 'G', and 'v'. All formats are equivalent.
+func (z *Rat) Scan(s fmt.ScanState, ch rune) error {
+	tok, err := s.Token(true, ratTok)
+	if err != nil {
+		return err
+	}
+	if strings.IndexRune("efgEFGv", ch) < 0 {
+		return errors.New("Rat.Scan: invalid verb")
+	}
+	if _, ok := z.SetString(string(tok)); !ok {
+		return errors.New("Rat.Scan: invalid syntax")
+	}
+	return nil
+}
+
+// SetString sets z to the value of s and returns z and a boolean indicating
+// success. s can be given as a fraction "a/b" or as a floating-point number
+// optionally followed by an exponent. If the operation failed, the value of
+// z is undefined but the returned value is nil.
+func (z *Rat) SetString(s string) (*Rat, bool) {
+	if len(s) == 0 {
+		return nil, false
+	}
+	// len(s) > 0
+
+	// parse fraction a/b, if any
+	if sep := strings.Index(s, "/"); sep >= 0 {
+		if _, ok := z.a.SetString(s[:sep], 0); !ok {
+			return nil, false
+		}
+		s = s[sep+1:]
+		var err error
+		if z.b.abs, _, _, err = z.b.abs.scan(strings.NewReader(s), 0, false); err != nil {
+			return nil, false
+		}
+		if len(z.b.abs) == 0 {
+			return nil, false
+		}
+		return z.norm(), true
+	}
+
+	// parse floating-point number
+	r := strings.NewReader(s)
+
+	// sign
+	neg, err := scanSign(r)
+	if err != nil {
+		return nil, false
+	}
+
+	// mantissa
+	var ecorr int
+	z.a.abs, _, ecorr, err = z.a.abs.scan(r, 10, true)
+	if err != nil {
+		return nil, false
+	}
+
+	// exponent
+	var exp int64
+	exp, _, err = scanExponent(r, false)
+	if err != nil {
+		return nil, false
+	}
+
+	// there should be no unread characters left
+	if _, err = r.ReadByte(); err != io.EOF {
+		return nil, false
+	}
+
+	// correct exponent
+	if ecorr < 0 {
+		exp += int64(ecorr)
+	}
+
+	// compute exponent power
+	expabs := exp
+	if expabs < 0 {
+		expabs = -expabs
+	}
+	powTen := nat(nil).expNN(natTen, nat(nil).setWord(Word(expabs)), nil)
+
+	// complete fraction
+	if exp < 0 {
+		z.b.abs = powTen
+		z.norm()
+	} else {
+		z.a.abs = z.a.abs.mul(z.a.abs, powTen)
+		z.b.abs = z.b.abs[:0]
+	}
+
+	z.a.neg = neg && len(z.a.abs) > 0 // 0 has no sign
+
+	return z, true
+}
+
+// scanExponent scans the longest possible prefix of r representing a decimal
+// ('e', 'E') or binary ('p') exponent, if any. It returns the exponent, the
+// exponent base (10 or 2), or a read or syntax error, if any.
+//
+//	exponent = ( "E" | "e" | "p" ) [ sign ] digits .
+//	sign     = "+" | "-" .
+//	digits   = digit { digit } .
+//	digit    = "0" ... "9" .
+//
+// A binary exponent is only permitted if binExpOk is set.
+func scanExponent(r io.ByteScanner, binExpOk bool) (exp int64, base int, err error) {
+	base = 10
+
+	var ch byte
+	if ch, err = r.ReadByte(); err != nil {
+		if err == io.EOF {
+			err = nil // no exponent; same as e0
+		}
+		return
+	}
+
+	switch ch {
+	case 'e', 'E':
+		// ok
+	case 'p':
+		if binExpOk {
+			base = 2
+			break // ok
+		}
+		fallthrough // binary exponent not permitted
+	default:
+		r.UnreadByte()
+		return // no exponent; same as e0
+	}
+
+	var neg bool
+	if neg, err = scanSign(r); err != nil {
+		return
+	}
+
+	var digits []byte
+	if neg {
+		digits = append(digits, '-')
+	}
+
+	// no need to use nat.scan for exponent digits
+	// since we only care about int64 values - the
+	// from-scratch scan is easy enough and faster
+	for i := 0; ; i++ {
+		if ch, err = r.ReadByte(); err != nil {
+			if err != io.EOF || i == 0 {
+				return
+			}
+			err = nil
+			break // i > 0
+		}
+		if ch < '0' || '9' < ch {
+			if i == 0 {
+				r.UnreadByte()
+				err = fmt.Errorf("invalid exponent (missing digits)")
+				return
+			}
+			break // i > 0
+		}
+		digits = append(digits, byte(ch))
+	}
+	// i > 0 => we have at least one digit
+
+	exp, err = strconv.ParseInt(string(digits), 10, 64)
+	return
+}
+
+// String returns a string representation of x in the form "a/b" (even if b == 1).
+func (x *Rat) String() string {
+	s := "/1"
+	if len(x.b.abs) != 0 {
+		s = "/" + x.b.abs.decimalString()
+	}
+	return x.a.String() + s
+}
+
+// RatString returns a string representation of x in the form "a/b" if b != 1,
+// and in the form "a" if b == 1.
+func (x *Rat) RatString() string {
+	if x.IsInt() {
+		return x.a.String()
+	}
+	return x.String()
+}
+
+// FloatString returns a string representation of x in decimal form with prec
+// digits of precision after the decimal point. The last digit is rounded to
+// nearest, with halves rounded away from zero.
+func (x *Rat) FloatString(prec int) string {
+	if x.IsInt() {
+		s := x.a.String()
+		if prec > 0 {
+			s += "." + strings.Repeat("0", prec)
+		}
+		return s
+	}
+	// x.b.abs != 0
+
+	q, r := nat(nil).div(nat(nil), x.a.abs, x.b.abs)
+
+	p := natOne
+	if prec > 0 {
+		p = nat(nil).expNN(natTen, nat(nil).setUint64(uint64(prec)), nil)
+	}
+
+	r = r.mul(r, p)
+	r, r2 := r.div(nat(nil), r, x.b.abs)
+
+	// see if we need to round up
+	r2 = r2.add(r2, r2)
+	if x.b.abs.cmp(r2) <= 0 {
+		r = r.add(r, natOne)
+		if r.cmp(p) >= 0 {
+			q = nat(nil).add(q, natOne)
+			r = nat(nil).sub(r, p)
+		}
+	}
+
+	s := q.decimalString()
+	if x.a.neg {
+		s = "-" + s
+	}
+
+	if prec > 0 {
+		rs := r.decimalString()
+		leadingZeros := prec - len(rs)
+		s += "." + strings.Repeat("0", leadingZeros) + rs
+	}
+
+	return s
+}
diff --git a/third_party/gofrontend/libgo/go/math/big/ratconv_test.go b/third_party/gofrontend/libgo/go/math/big/ratconv_test.go
new file mode 100644
index 0000000..da2fdab
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/math/big/ratconv_test.go
@@ -0,0 +1,453 @@
+// 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 big
+
+import (
+	"bytes"
+	"fmt"
+	"math"
+	"strconv"
+	"strings"
+	"testing"
+)
+
+type StringTest struct {
+	in, out string
+	ok      bool
+}
+
+var setStringTests = []StringTest{
+	{"0", "0", true},
+	{"-0", "0", true},
+	{"1", "1", true},
+	{"-1", "-1", true},
+	{"1.", "1", true},
+	{"1e0", "1", true},
+	{"1.e1", "10", true},
+	{in: "1e"},
+	{in: "1.e"},
+	{in: "1e+14e-5"},
+	{in: "1e4.5"},
+	{in: "r"},
+	{in: "a/b"},
+	{in: "a.b"},
+	{"-0.1", "-1/10", true},
+	{"-.1", "-1/10", true},
+	{"2/4", "1/2", true},
+	{".25", "1/4", true},
+	{"-1/5", "-1/5", true},
+	{"8129567.7690E14", "812956776900000000000", true},
+	{"78189e+4", "781890000", true},
+	{"553019.8935e+8", "55301989350000", true},
+	{"98765432109876543210987654321e-10", "98765432109876543210987654321/10000000000", true},
+	{"9877861857500000E-7", "3951144743/4", true},
+	{"2169378.417e-3", "2169378417/1000000", true},
+	{"884243222337379604041632732738665534", "884243222337379604041632732738665534", true},
+	{"53/70893980658822810696", "53/70893980658822810696", true},
+	{"106/141787961317645621392", "53/70893980658822810696", true},
+	{"204211327800791583.81095", "4084226556015831676219/20000", true},
+	{in: "1/0"},
+}
+
+// These are not supported by fmt.Fscanf.
+var setStringTests2 = []StringTest{
+	{"0x10", "16", true},
+	{"-010/1", "-8", true}, // TODO(gri) should we even permit octal here?
+	{"-010.", "-10", true},
+	{"0x10/0x20", "1/2", true},
+	{"0b1000/3", "8/3", true},
+	// TODO(gri) add more tests
+}
+
+func TestRatSetString(t *testing.T) {
+	var tests []StringTest
+	tests = append(tests, setStringTests...)
+	tests = append(tests, setStringTests2...)
+
+	for i, test := range tests {
+		x, ok := new(Rat).SetString(test.in)
+
+		if ok {
+			if !test.ok {
+				t.Errorf("#%d SetString(%q) expected failure", i, test.in)
+			} else if x.RatString() != test.out {
+				t.Errorf("#%d SetString(%q) got %s want %s", i, test.in, x.RatString(), test.out)
+			}
+		} else if x != nil {
+			t.Errorf("#%d SetString(%q) got %p want nil", i, test.in, x)
+		}
+	}
+}
+
+func TestRatScan(t *testing.T) {
+	var buf bytes.Buffer
+	for i, test := range setStringTests {
+		x := new(Rat)
+		buf.Reset()
+		buf.WriteString(test.in)
+
+		_, err := fmt.Fscanf(&buf, "%v", x)
+		if err == nil != test.ok {
+			if test.ok {
+				t.Errorf("#%d (%s) error: %s", i, test.in, err)
+			} else {
+				t.Errorf("#%d (%s) expected error", i, test.in)
+			}
+			continue
+		}
+		if err == nil && x.RatString() != test.out {
+			t.Errorf("#%d got %s want %s", i, x.RatString(), test.out)
+		}
+	}
+}
+
+var floatStringTests = []struct {
+	in   string
+	prec int
+	out  string
+}{
+	{"0", 0, "0"},
+	{"0", 4, "0.0000"},
+	{"1", 0, "1"},
+	{"1", 2, "1.00"},
+	{"-1", 0, "-1"},
+	{"0.05", 1, "0.1"},
+	{"-0.05", 1, "-0.1"},
+	{".25", 2, "0.25"},
+	{".25", 1, "0.3"},
+	{".25", 3, "0.250"},
+	{"-1/3", 3, "-0.333"},
+	{"-2/3", 4, "-0.6667"},
+	{"0.96", 1, "1.0"},
+	{"0.999", 2, "1.00"},
+	{"0.9", 0, "1"},
+	{".25", -1, "0"},
+	{".55", -1, "1"},
+}
+
+func TestFloatString(t *testing.T) {
+	for i, test := range floatStringTests {
+		x, _ := new(Rat).SetString(test.in)
+
+		if x.FloatString(test.prec) != test.out {
+			t.Errorf("#%d got %s want %s", i, x.FloatString(test.prec), test.out)
+		}
+	}
+}
+
+// Test inputs to Rat.SetString.  The prefix "long:" causes the test
+// to be skipped in --test.short mode.  (The threshold is about 500us.)
+var float64inputs = []string{
+	// Constants plundered from strconv/testfp.txt.
+
+	// Table 1: Stress Inputs for Conversion to 53-bit Binary, < 1/2 ULP
+	"5e+125",
+	"69e+267",
+	"999e-026",
+	"7861e-034",
+	"75569e-254",
+	"928609e-261",
+	"9210917e+080",
+	"84863171e+114",
+	"653777767e+273",
+	"5232604057e-298",
+	"27235667517e-109",
+	"653532977297e-123",
+	"3142213164987e-294",
+	"46202199371337e-072",
+	"231010996856685e-073",
+	"9324754620109615e+212",
+	"78459735791271921e+049",
+	"272104041512242479e+200",
+	"6802601037806061975e+198",
+	"20505426358836677347e-221",
+	"836168422905420598437e-234",
+	"4891559871276714924261e+222",
+
+	// Table 2: Stress Inputs for Conversion to 53-bit Binary, > 1/2 ULP
+	"9e-265",
+	"85e-037",
+	"623e+100",
+	"3571e+263",
+	"81661e+153",
+	"920657e-023",
+	"4603285e-024",
+	"87575437e-309",
+	"245540327e+122",
+	"6138508175e+120",
+	"83356057653e+193",
+	"619534293513e+124",
+	"2335141086879e+218",
+	"36167929443327e-159",
+	"609610927149051e-255",
+	"3743626360493413e-165",
+	"94080055902682397e-242",
+	"899810892172646163e+283",
+	"7120190517612959703e+120",
+	"25188282901709339043e-252",
+	"308984926168550152811e-052",
+	"6372891218502368041059e+064",
+
+	// Table 14: Stress Inputs for Conversion to 24-bit Binary, <1/2 ULP
+	"5e-20",
+	"67e+14",
+	"985e+15",
+	"7693e-42",
+	"55895e-16",
+	"996622e-44",
+	"7038531e-32",
+	"60419369e-46",
+	"702990899e-20",
+	"6930161142e-48",
+	"25933168707e+13",
+	"596428896559e+20",
+
+	// Table 15: Stress Inputs for Conversion to 24-bit Binary, >1/2 ULP
+	"3e-23",
+	"57e+18",
+	"789e-35",
+	"2539e-18",
+	"76173e+28",
+	"887745e-11",
+	"5382571e-37",
+	"82381273e-35",
+	"750486563e-38",
+	"3752432815e-39",
+	"75224575729e-45",
+	"459926601011e+15",
+
+	// Constants plundered from strconv/atof_test.go.
+
+	"0",
+	"1",
+	"+1",
+	"1e23",
+	"1E23",
+	"100000000000000000000000",
+	"1e-100",
+	"123456700",
+	"99999999999999974834176",
+	"100000000000000000000001",
+	"100000000000000008388608",
+	"100000000000000016777215",
+	"100000000000000016777216",
+	"-1",
+	"-0.1",
+	"-0", // NB: exception made for this input
+	"1e-20",
+	"625e-3",
+
+	// largest float64
+	"1.7976931348623157e308",
+	"-1.7976931348623157e308",
+	// next float64 - too large
+	"1.7976931348623159e308",
+	"-1.7976931348623159e308",
+	// the border is ...158079
+	// borderline - okay
+	"1.7976931348623158e308",
+	"-1.7976931348623158e308",
+	// borderline - too large
+	"1.797693134862315808e308",
+	"-1.797693134862315808e308",
+
+	// a little too large
+	"1e308",
+	"2e308",
+	"1e309",
+
+	// way too large
+	"1e310",
+	"-1e310",
+	"1e400",
+	"-1e400",
+	"long:1e400000",
+	"long:-1e400000",
+
+	// denormalized
+	"1e-305",
+	"1e-306",
+	"1e-307",
+	"1e-308",
+	"1e-309",
+	"1e-310",
+	"1e-322",
+	// smallest denormal
+	"5e-324",
+	"4e-324",
+	"3e-324",
+	// too small
+	"2e-324",
+	// way too small
+	"1e-350",
+	"long:1e-400000",
+	// way too small, negative
+	"-1e-350",
+	"long:-1e-400000",
+
+	// try to overflow exponent
+	// [Disabled: too slow and memory-hungry with rationals.]
+	// "1e-4294967296",
+	// "1e+4294967296",
+	// "1e-18446744073709551616",
+	// "1e+18446744073709551616",
+
+	// http://www.exploringbinary.com/java-hangs-when-converting-2-2250738585072012e-308/
+	"2.2250738585072012e-308",
+	// http://www.exploringbinary.com/php-hangs-on-numeric-value-2-2250738585072011e-308/
+	"2.2250738585072011e-308",
+
+	// A very large number (initially wrongly parsed by the fast algorithm).
+	"4.630813248087435e+307",
+
+	// A different kind of very large number.
+	"22.222222222222222",
+	"long:2." + strings.Repeat("2", 4000) + "e+1",
+
+	// Exactly halfway between 1 and math.Nextafter(1, 2).
+	// Round to even (down).
+	"1.00000000000000011102230246251565404236316680908203125",
+	// Slightly lower; still round down.
+	"1.00000000000000011102230246251565404236316680908203124",
+	// Slightly higher; round up.
+	"1.00000000000000011102230246251565404236316680908203126",
+	// Slightly higher, but you have to read all the way to the end.
+	"long:1.00000000000000011102230246251565404236316680908203125" + strings.Repeat("0", 10000) + "1",
+
+	// Smallest denormal, 2^(-1022-52)
+	"4.940656458412465441765687928682213723651e-324",
+	// Half of smallest denormal, 2^(-1022-53)
+	"2.470328229206232720882843964341106861825e-324",
+	// A little more than the exact half of smallest denormal
+	// 2^-1075 + 2^-1100.  (Rounds to 1p-1074.)
+	"2.470328302827751011111470718709768633275e-324",
+	// The exact halfway between smallest normal and largest denormal:
+	// 2^-1022 - 2^-1075.  (Rounds to 2^-1022.)
+	"2.225073858507201136057409796709131975935e-308",
+
+	"1152921504606846975",  //   1<<60 - 1
+	"-1152921504606846975", // -(1<<60 - 1)
+	"1152921504606846977",  //   1<<60 + 1
+	"-1152921504606846977", // -(1<<60 + 1)
+
+	"1/3",
+}
+
+// isFinite reports whether f represents a finite rational value.
+// It is equivalent to !math.IsNan(f) && !math.IsInf(f, 0).
+func isFinite(f float64) bool {
+	return math.Abs(f) <= math.MaxFloat64
+}
+
+func TestFloat32SpecialCases(t *testing.T) {
+	for _, input := range float64inputs {
+		if strings.HasPrefix(input, "long:") {
+			if testing.Short() {
+				continue
+			}
+			input = input[len("long:"):]
+		}
+
+		r, ok := new(Rat).SetString(input)
+		if !ok {
+			t.Errorf("Rat.SetString(%q) failed", input)
+			continue
+		}
+		f, exact := r.Float32()
+
+		// 1. Check string -> Rat -> float32 conversions are
+		// consistent with strconv.ParseFloat.
+		// Skip this check if the input uses "a/b" rational syntax.
+		if !strings.Contains(input, "/") {
+			e64, _ := strconv.ParseFloat(input, 32)
+			e := float32(e64)
+
+			// Careful: negative Rats too small for
+			// float64 become -0, but Rat obviously cannot
+			// preserve the sign from SetString("-0").
+			switch {
+			case math.Float32bits(e) == math.Float32bits(f):
+				// Ok: bitwise equal.
+			case f == 0 && r.Num().BitLen() == 0:
+				// Ok: Rat(0) is equivalent to both +/- float64(0).
+			default:
+				t.Errorf("strconv.ParseFloat(%q) = %g (%b), want %g (%b); delta = %g", input, e, e, f, f, f-e)
+			}
+		}
+
+		if !isFinite(float64(f)) {
+			continue
+		}
+
+		// 2. Check f is best approximation to r.
+		if !checkIsBestApprox32(t, f, r) {
+			// Append context information.
+			t.Errorf("(input was %q)", input)
+		}
+
+		// 3. Check f->R->f roundtrip is non-lossy.
+		checkNonLossyRoundtrip32(t, f)
+
+		// 4. Check exactness using slow algorithm.
+		if wasExact := new(Rat).SetFloat64(float64(f)).Cmp(r) == 0; wasExact != exact {
+			t.Errorf("Rat.SetString(%q).Float32().exact = %t, want %t", input, exact, wasExact)
+		}
+	}
+}
+
+func TestFloat64SpecialCases(t *testing.T) {
+	for _, input := range float64inputs {
+		if strings.HasPrefix(input, "long:") {
+			if testing.Short() {
+				continue
+			}
+			input = input[len("long:"):]
+		}
+
+		r, ok := new(Rat).SetString(input)
+		if !ok {
+			t.Errorf("Rat.SetString(%q) failed", input)
+			continue
+		}
+		f, exact := r.Float64()
+
+		// 1. Check string -> Rat -> float64 conversions are
+		// consistent with strconv.ParseFloat.
+		// Skip this check if the input uses "a/b" rational syntax.
+		if !strings.Contains(input, "/") {
+			e, _ := strconv.ParseFloat(input, 64)
+
+			// Careful: negative Rats too small for
+			// float64 become -0, but Rat obviously cannot
+			// preserve the sign from SetString("-0").
+			switch {
+			case math.Float64bits(e) == math.Float64bits(f):
+				// Ok: bitwise equal.
+			case f == 0 && r.Num().BitLen() == 0:
+				// Ok: Rat(0) is equivalent to both +/- float64(0).
+			default:
+				t.Errorf("strconv.ParseFloat(%q) = %g (%b), want %g (%b); delta = %g", input, e, e, f, f, f-e)
+			}
+		}
+
+		if !isFinite(f) {
+			continue
+		}
+
+		// 2. Check f is best approximation to r.
+		if !checkIsBestApprox64(t, f, r) {
+			// Append context information.
+			t.Errorf("(input was %q)", input)
+		}
+
+		// 3. Check f->R->f roundtrip is non-lossy.
+		checkNonLossyRoundtrip64(t, f)
+
+		// 4. Check exactness using slow algorithm.
+		if wasExact := new(Rat).SetFloat64(f).Cmp(r) == 0; wasExact != exact {
+			t.Errorf("Rat.SetString(%q).Float64().exact = %t, want %t", input, exact, wasExact)
+		}
+	}
+}
diff --git a/third_party/gofrontend/libgo/go/math/big/roundingmode_string.go b/third_party/gofrontend/libgo/go/math/big/roundingmode_string.go
new file mode 100644
index 0000000..05024b8
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/math/big/roundingmode_string.go
@@ -0,0 +1,16 @@
+// generated by stringer -type=RoundingMode; DO NOT EDIT
+
+package big
+
+import "fmt"
+
+const _RoundingMode_name = "ToNearestEvenToNearestAwayToZeroAwayFromZeroToNegativeInfToPositiveInf"
+
+var _RoundingMode_index = [...]uint8{0, 13, 26, 32, 44, 57, 70}
+
+func (i RoundingMode) String() string {
+	if i+1 >= RoundingMode(len(_RoundingMode_index)) {
+		return fmt.Sprintf("RoundingMode(%d)", i)
+	}
+	return _RoundingMode_name[_RoundingMode_index[i]:_RoundingMode_index[i+1]]
+}
diff --git a/third_party/gofrontend/libgo/go/math/cbrt.go b/third_party/gofrontend/libgo/go/math/cbrt.go
index 272e309..f009faf 100644
--- a/third_party/gofrontend/libgo/go/math/cbrt.go
+++ b/third_party/gofrontend/libgo/go/math/cbrt.go
@@ -4,13 +4,17 @@
 
 package math
 
-/*
-	The algorithm is based in part on "Optimal Partitioning of
-	Newton's Method for Calculating Roots", by Gunter Meinardus
-	and G. D. Taylor, Mathematics of Computation © 1980 American
-	Mathematical Society.
-	(http://www.jstor.org/stable/2006387?seq=9, accessed 11-Feb-2010)
-*/
+// The go code is a modified version of the original C code from
+// http://www.netlib.org/fdlibm/s_cbrt.c and came with this notice.
+//
+// ====================================================
+// Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+//
+// Developed at SunSoft, a Sun Microsystems, Inc. business.
+// Permission to use, copy, modify, and distribute this
+// software is freely granted, provided that this notice
+// is preserved.
+// ====================================================
 
 // Cbrt returns the cube root of x.
 //
@@ -20,57 +24,54 @@
 //	Cbrt(NaN) = NaN
 func Cbrt(x float64) float64 {
 	const (
-		A1 = 1.662848358e-01
-		A2 = 1.096040958e+00
-		A3 = 4.105032829e-01
-		A4 = 5.649335816e-01
-		B1 = 2.639607233e-01
-		B2 = 8.699282849e-01
-		B3 = 1.629083358e-01
-		B4 = 2.824667908e-01
-		C1 = 4.190115298e-01
-		C2 = 6.904625373e-01
-		C3 = 6.46502159e-02
-		C4 = 1.412333954e-01
+		B1             = 715094163                   // (682-0.03306235651)*2**20
+		B2             = 696219795                   // (664-0.03306235651)*2**20
+		C              = 5.42857142857142815906e-01  // 19/35     = 0x3FE15F15F15F15F1
+		D              = -7.05306122448979611050e-01 // -864/1225 = 0xBFE691DE2532C834
+		E              = 1.41428571428571436819e+00  // 99/70     = 0x3FF6A0EA0EA0EA0F
+		F              = 1.60714285714285720630e+00  // 45/28     = 0x3FF9B6DB6DB6DB6E
+		G              = 3.57142857142857150787e-01  // 5/14      = 0x3FD6DB6DB6DB6DB7
+		SmallestNormal = 2.22507385850720138309e-308 // 2**-1022  = 0x0010000000000000
 	)
 	// special cases
 	switch {
 	case x == 0 || IsNaN(x) || IsInf(x, 0):
 		return x
 	}
+
 	sign := false
 	if x < 0 {
 		x = -x
 		sign = true
 	}
-	// Reduce argument and estimate cube root
-	f, e := Frexp(x) // 0.5 <= f < 1.0
-	m := e % 3
-	if m > 0 {
-		m -= 3
-		e -= m // e is multiple of 3
-	}
-	switch m {
-	case 0: // 0.5 <= f < 1.0
-		f = A1*f + A2 - A3/(A4+f)
-	case -1:
-		f *= 0.5 // 0.25 <= f < 0.5
-		f = B1*f + B2 - B3/(B4+f)
-	default: // m == -2
-		f *= 0.25 // 0.125 <= f < 0.25
-		f = C1*f + C2 - C3/(C4+f)
-	}
-	y := Ldexp(f, e/3) // e/3 = exponent of cube root
 
-	// Iterate
-	s := y * y * y
-	t := s + x
-	y *= (t + x) / (s + t)
-	// Reiterate
-	s = (y*y*y - x) / x
-	y -= y * (((14.0/81.0)*s-(2.0/9.0))*s + (1.0 / 3.0)) * s
-	if sign {
-		y = -y
+	// rough cbrt to 5 bits
+	t := Float64frombits(Float64bits(x)/3 + B1<<32)
+	if x < SmallestNormal {
+		// subnormal number
+		t = float64(1 << 54) // set t= 2**54
+		t *= x
+		t = Float64frombits(Float64bits(t)/3 + B2<<32)
 	}
-	return y
+
+	// new cbrt to 23 bits
+	r := t * t / x
+	s := C + r*t
+	t *= G + F/(s+E+D/s)
+
+	// chop to 22 bits, make larger than cbrt(x)
+	t = Float64frombits(Float64bits(t)&(0xFFFFFFFFC<<28) + 1<<30)
+
+	// one step newton iteration to 53 bits with error less than 0.667ulps
+	s = t * t // t*t is exact
+	r = x / s
+	w := t + t
+	r = (r - t) / (w + r) // r-s is exact
+	t = t + t*r
+
+	// restore the sign bit
+	if sign {
+		t = -t
+	}
+	return t
 }
diff --git a/third_party/gofrontend/libgo/go/math/const.go b/third_party/gofrontend/libgo/go/math/const.go
index f1247c3..b440538 100644
--- a/third_party/gofrontend/libgo/go/math/const.go
+++ b/third_party/gofrontend/libgo/go/math/const.go
@@ -6,20 +6,19 @@
 package math
 
 // Mathematical constants.
-// Reference: http://oeis.org/Axxxxxx
 const (
-	E   = 2.71828182845904523536028747135266249775724709369995957496696763 // A001113
-	Pi  = 3.14159265358979323846264338327950288419716939937510582097494459 // A000796
-	Phi = 1.61803398874989484820458683436563811772030917980576286213544862 // A001622
+	E   = 2.71828182845904523536028747135266249775724709369995957496696763 // http://oeis.org/A001113
+	Pi  = 3.14159265358979323846264338327950288419716939937510582097494459 // http://oeis.org/A000796
+	Phi = 1.61803398874989484820458683436563811772030917980576286213544862 // http://oeis.org/A001622
 
-	Sqrt2   = 1.41421356237309504880168872420969807856967187537694807317667974 // A002193
-	SqrtE   = 1.64872127070012814684865078781416357165377610071014801157507931 // A019774
-	SqrtPi  = 1.77245385090551602729816748334114518279754945612238712821380779 // A002161
-	SqrtPhi = 1.27201964951406896425242246173749149171560804184009624861664038 // A139339
+	Sqrt2   = 1.41421356237309504880168872420969807856967187537694807317667974 // http://oeis.org/A002193
+	SqrtE   = 1.64872127070012814684865078781416357165377610071014801157507931 // http://oeis.org/A019774
+	SqrtPi  = 1.77245385090551602729816748334114518279754945612238712821380779 // http://oeis.org/A002161
+	SqrtPhi = 1.27201964951406896425242246173749149171560804184009624861664038 // http://oeis.org/A139339
 
-	Ln2    = 0.693147180559945309417232121458176568075500134360255254120680009 // A002162
+	Ln2    = 0.693147180559945309417232121458176568075500134360255254120680009 // http://oeis.org/A002162
 	Log2E  = 1 / Ln2
-	Ln10   = 2.30258509299404568401799145468436420760110148862877297603332790 // A002392
+	Ln10   = 2.30258509299404568401799145468436420760110148862877297603332790 // http://oeis.org/A002392
 	Log10E = 1 / Ln10
 )
 
diff --git a/third_party/gofrontend/libgo/go/math/expm1.go b/third_party/gofrontend/libgo/go/math/expm1.go
index f7e15db..8d7b3d3 100644
--- a/third_party/gofrontend/libgo/go/math/expm1.go
+++ b/third_party/gofrontend/libgo/go/math/expm1.go
@@ -164,11 +164,11 @@
 
 	// filter out huge argument
 	if absx >= Ln2X56 { // if |x| >= 56 * ln2
-		if absx >= Othreshold { // if |x| >= 709.78...
-			return Inf(1) // overflow
-		}
 		if sign {
-			return -1 // x < -56*ln2, return -1.0
+			return -1 // x < -56*ln2, return -1
+		}
+		if absx >= Othreshold { // if |x| >= 709.78...
+			return Inf(1)
 		}
 	}
 
diff --git a/third_party/gofrontend/libgo/go/math/log10.go b/third_party/gofrontend/libgo/go/math/log10.go
index d880ec2..2c09d88 100644
--- a/third_party/gofrontend/libgo/go/math/log10.go
+++ b/third_party/gofrontend/libgo/go/math/log10.go
@@ -27,5 +27,10 @@
 
 func log2(x float64) float64 {
 	frac, exp := Frexp(x)
+	// Make sure exact powers of two give an exact answer.
+	// Don't depend on Log(0.5)*(1/Ln2)+exp being exactly exp-1.
+	if frac == 0.5 {
+		return float64(exp - 1)
+	}
 	return Log(frac)*(1/Ln2) + float64(exp)
 }
diff --git a/third_party/gofrontend/libgo/go/math/nextafter.go b/third_party/gofrontend/libgo/go/math/nextafter.go
index bbb1399..9088e4d 100644
--- a/third_party/gofrontend/libgo/go/math/nextafter.go
+++ b/third_party/gofrontend/libgo/go/math/nextafter.go
@@ -5,10 +5,11 @@
 package math
 
 // Nextafter32 returns the next representable float32 value after x towards y.
-// Special cases:
+//
+// Special cases are:
 //	Nextafter32(x, x)   = x
-//      Nextafter32(NaN, y) = NaN
-//      Nextafter32(x, NaN) = NaN
+//	Nextafter32(NaN, y) = NaN
+//	Nextafter32(x, NaN) = NaN
 func Nextafter32(x, y float32) (r float32) {
 	switch {
 	case IsNaN(float64(x)) || IsNaN(float64(y)): // special case
@@ -26,10 +27,11 @@
 }
 
 // Nextafter returns the next representable float64 value after x towards y.
-// Special cases:
-//	Nextafter64(x, x)   = x
-//      Nextafter64(NaN, y) = NaN
-//      Nextafter64(x, NaN) = NaN
+//
+// Special cases are:
+//	Nextafter(x, x)   = x
+//	Nextafter(NaN, y) = NaN
+//	Nextafter(x, NaN) = NaN
 func Nextafter(x, y float64) (r float64) {
 	switch {
 	case IsNaN(x) || IsNaN(y): // special case
diff --git a/third_party/gofrontend/libgo/go/math/rand/rand.go b/third_party/gofrontend/libgo/go/math/rand/rand.go
index 3ffb5c4..6360128 100644
--- a/third_party/gofrontend/libgo/go/math/rand/rand.go
+++ b/third_party/gofrontend/libgo/go/math/rand/rand.go
@@ -9,6 +9,9 @@
 // sequence of values each time a program is run. Use the Seed function to
 // initialize the default Source if different behavior is required for each run.
 // The default Source is safe for concurrent use by multiple goroutines.
+//
+// For random numbers suitable for security-sensitive work, see the crypto/rand
+// package.
 package rand
 
 import "sync"
diff --git a/third_party/gofrontend/libgo/go/math/rand/rand_test.go b/third_party/gofrontend/libgo/go/math/rand/rand_test.go
index ab0dc49..c61494f 100644
--- a/third_party/gofrontend/libgo/go/math/rand/rand_test.go
+++ b/third_party/gofrontend/libgo/go/math/rand/rand_test.go
@@ -8,6 +8,8 @@
 	"errors"
 	"fmt"
 	"math"
+	"os"
+	"runtime"
 	"testing"
 )
 
@@ -322,10 +324,17 @@
 	}
 }
 
-// For issue 6721, the problem came after 7533753 calls, so check 10e6.
 func TestFloat32(t *testing.T) {
+	// For issue 6721, the problem came after 7533753 calls, so check 10e6.
+	num := int(10e6)
+	// But ARM5 floating point emulation is slow (Issue 10749), so
+	// do less for that builder:
+	if testing.Short() && runtime.GOARCH == "arm" && os.Getenv("GOARM") == "5" {
+		num /= 100 // 1.72 seconds instead of 172 seconds
+	}
+
 	r := New(NewSource(1))
-	for ct := 0; ct < 10e6; ct++ {
+	for ct := 0; ct < num; ct++ {
 		f := r.Float32()
 		if f >= 1 {
 			t.Fatal("Float32() should be in range [0,1). ct:", ct, "f:", f)
diff --git a/third_party/gofrontend/libgo/go/math/rand/zipf.go b/third_party/gofrontend/libgo/go/math/rand/zipf.go
index 8db2c6f..f04c814 100644
--- a/third_party/gofrontend/libgo/go/math/rand/zipf.go
+++ b/third_party/gofrontend/libgo/go/math/rand/zipf.go
@@ -32,8 +32,10 @@
 	return math.Exp(z.oneminusQinv*math.Log(z.oneminusQ*x)) - z.v
 }
 
-// NewZipf returns a Zipf generating variates p(k) on [0, imax]
-// proportional to (v+k)**(-s) where s>1 and k>=0, and v>=1.
+// NewZipf returns a Zipf variate generator.
+// The generator generates values k ∈ [0, imax]
+// such that P(k) is proportional to (v + k) ** (-s).
+// Requirements: s > 1 and v >= 1.
 func NewZipf(r *Rand, s float64, v float64, imax uint64) *Zipf {
 	z := new(Zipf)
 	if s <= 1.0 || v < 1 {
diff --git a/third_party/gofrontend/libgo/go/math/sqrt.go b/third_party/gofrontend/libgo/go/math/sqrt.go
index 56122b5..215d648 100644
--- a/third_party/gofrontend/libgo/go/math/sqrt.go
+++ b/third_party/gofrontend/libgo/go/math/sqrt.go
@@ -96,6 +96,12 @@
 //	Sqrt(±0) = ±0
 //	Sqrt(x < 0) = NaN
 //	Sqrt(NaN) = NaN
+
+// Note: Sqrt is implemented in assembly on some systems.
+// Others have assembly stubs that jump to func sqrt below.
+// On systems where Sqrt is a single instruction, the compiler
+// may turn a direct call into a direct use of that instruction instead.
+
 func sqrt(x float64) float64 {
 	// special cases
 	switch {
diff --git a/third_party/gofrontend/libgo/go/mime/encodedword.go b/third_party/gofrontend/libgo/go/mime/encodedword.go
new file mode 100644
index 0000000..9796f50
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/mime/encodedword.go
@@ -0,0 +1,329 @@
+// 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 mime
+
+import (
+	"bytes"
+	"encoding/base64"
+	"errors"
+	"fmt"
+	"io"
+	"strings"
+	"sync"
+	"unicode"
+	"unicode/utf8"
+)
+
+// A WordEncoder is a RFC 2047 encoded-word encoder.
+type WordEncoder byte
+
+const (
+	// BEncoding represents Base64 encoding scheme as defined by RFC 2045.
+	BEncoding = WordEncoder('b')
+	// QEncoding represents the Q-encoding scheme as defined by RFC 2047.
+	QEncoding = WordEncoder('q')
+)
+
+var (
+	errInvalidWord = errors.New("mime: invalid RFC 2047 encoded-word")
+)
+
+// Encode returns the encoded-word form of s. If s is ASCII without special
+// characters, it is returned unchanged. The provided charset is the IANA
+// charset name of s. It is case insensitive.
+func (e WordEncoder) Encode(charset, s string) string {
+	if !needsEncoding(s) {
+		return s
+	}
+	return e.encodeWord(charset, s)
+}
+
+func needsEncoding(s string) bool {
+	for _, b := range s {
+		if (b < ' ' || b > '~') && b != '\t' {
+			return true
+		}
+	}
+	return false
+}
+
+// encodeWord encodes a string into an encoded-word.
+func (e WordEncoder) encodeWord(charset, s string) string {
+	buf := getBuffer()
+	defer putBuffer(buf)
+
+	buf.WriteString("=?")
+	buf.WriteString(charset)
+	buf.WriteByte('?')
+	buf.WriteByte(byte(e))
+	buf.WriteByte('?')
+
+	if e == BEncoding {
+		w := base64.NewEncoder(base64.StdEncoding, buf)
+		io.WriteString(w, s)
+		w.Close()
+	} else {
+		enc := make([]byte, 3)
+		for i := 0; i < len(s); i++ {
+			b := s[i]
+			switch {
+			case b == ' ':
+				buf.WriteByte('_')
+			case b <= '~' && b >= '!' && b != '=' && b != '?' && b != '_':
+				buf.WriteByte(b)
+			default:
+				enc[0] = '='
+				enc[1] = upperhex[b>>4]
+				enc[2] = upperhex[b&0x0f]
+				buf.Write(enc)
+			}
+		}
+	}
+	buf.WriteString("?=")
+	return buf.String()
+}
+
+const upperhex = "0123456789ABCDEF"
+
+// A WordDecoder decodes MIME headers containing RFC 2047 encoded-words.
+type WordDecoder struct {
+	// CharsetReader, if non-nil, defines a function to generate
+	// charset-conversion readers, converting from the provided
+	// charset into UTF-8.
+	// Charsets are always lower-case. utf-8, iso-8859-1 and us-ascii charsets
+	// are handled by default.
+	// One of the the CharsetReader's result values must be non-nil.
+	CharsetReader func(charset string, input io.Reader) (io.Reader, error)
+}
+
+// Decode decodes an encoded-word. If word is not a valid RFC 2047 encoded-word,
+// word is returned unchanged.
+func (d *WordDecoder) Decode(word string) (string, error) {
+	fields := strings.Split(word, "?") // TODO: remove allocation?
+	if len(fields) != 5 || fields[0] != "=" || fields[4] != "=" || len(fields[2]) != 1 {
+		return "", errInvalidWord
+	}
+
+	content, err := decode(fields[2][0], fields[3])
+	if err != nil {
+		return "", err
+	}
+
+	buf := getBuffer()
+	defer putBuffer(buf)
+
+	if err := d.convert(buf, fields[1], content); err != nil {
+		return "", err
+	}
+
+	return buf.String(), nil
+}
+
+// DecodeHeader decodes all encoded-words of the given string. It returns an
+// error if and only if CharsetReader of d returns an error.
+func (d *WordDecoder) DecodeHeader(header string) (string, error) {
+	// If there is no encoded-word, returns before creating a buffer.
+	i := strings.Index(header, "=?")
+	if i == -1 {
+		return header, nil
+	}
+
+	buf := getBuffer()
+	defer putBuffer(buf)
+
+	buf.WriteString(header[:i])
+	header = header[i:]
+
+	betweenWords := false
+	for {
+		start := strings.Index(header, "=?")
+		if start == -1 {
+			break
+		}
+		cur := start + len("=?")
+
+		i := strings.Index(header[cur:], "?")
+		if i == -1 {
+			break
+		}
+		charset := header[cur : cur+i]
+		cur += i + len("?")
+
+		if len(header) < cur+len("Q??=") {
+			break
+		}
+		encoding := header[cur]
+		cur++
+
+		if header[cur] != '?' {
+			break
+		}
+		cur++
+
+		j := strings.Index(header[cur:], "?=")
+		if j == -1 {
+			break
+		}
+		text := header[cur : cur+j]
+		end := cur + j + len("?=")
+
+		content, err := decode(encoding, text)
+		if err != nil {
+			betweenWords = false
+			buf.WriteString(header[:start+2])
+			header = header[start+2:]
+			continue
+		}
+
+		// Write characters before the encoded-word. White-space and newline
+		// characters separating two encoded-words must be deleted.
+		if start > 0 && (!betweenWords || hasNonWhitespace(header[:start])) {
+			buf.WriteString(header[:start])
+		}
+
+		if err := d.convert(buf, charset, content); err != nil {
+			return "", err
+		}
+
+		header = header[end:]
+		betweenWords = true
+	}
+
+	if len(header) > 0 {
+		buf.WriteString(header)
+	}
+
+	return buf.String(), nil
+}
+
+func decode(encoding byte, text string) ([]byte, error) {
+	switch encoding {
+	case 'B', 'b':
+		return base64.StdEncoding.DecodeString(text)
+	case 'Q', 'q':
+		return qDecode(text)
+	default:
+		return nil, errInvalidWord
+	}
+}
+
+func (d *WordDecoder) convert(buf *bytes.Buffer, charset string, content []byte) error {
+	switch {
+	case strings.EqualFold("utf-8", charset):
+		buf.Write(content)
+	case strings.EqualFold("iso-8859-1", charset):
+		for _, c := range content {
+			buf.WriteRune(rune(c))
+		}
+	case strings.EqualFold("us-ascii", charset):
+		for _, c := range content {
+			if c >= utf8.RuneSelf {
+				buf.WriteRune(unicode.ReplacementChar)
+			} else {
+				buf.WriteByte(c)
+			}
+		}
+	default:
+		if d.CharsetReader == nil {
+			return fmt.Errorf("mime: unhandled charset %q", charset)
+		}
+		r, err := d.CharsetReader(strings.ToLower(charset), bytes.NewReader(content))
+		if err != nil {
+			return err
+		}
+		if _, err = buf.ReadFrom(r); err != nil {
+			return err
+		}
+	}
+	return nil
+}
+
+// hasNonWhitespace reports whether s (assumed to be ASCII) contains at least
+// one byte of non-whitespace.
+func hasNonWhitespace(s string) bool {
+	for _, b := range s {
+		switch b {
+		// Encoded-words can only be separated by linear white spaces which does
+		// not include vertical tabs (\v).
+		case ' ', '\t', '\n', '\r':
+		default:
+			return true
+		}
+	}
+	return false
+}
+
+// qDecode decodes a Q encoded string.
+func qDecode(s string) ([]byte, error) {
+	dec := make([]byte, len(s))
+	n := 0
+	for i := 0; i < len(s); i++ {
+		switch c := s[i]; {
+		case c == '_':
+			dec[n] = ' '
+		case c == '=':
+			if i+2 >= len(s) {
+				return nil, errInvalidWord
+			}
+			b, err := readHexByte(s[i+1], s[i+2])
+			if err != nil {
+				return nil, err
+			}
+			dec[n] = b
+			i += 2
+		case (c <= '~' && c >= ' ') || c == '\n' || c == '\r' || c == '\t':
+			dec[n] = c
+		default:
+			return nil, errInvalidWord
+		}
+		n++
+	}
+
+	return dec[:n], nil
+}
+
+// readHexByte returns the byte from its quoted-printable representation.
+func readHexByte(a, b byte) (byte, error) {
+	var hb, lb byte
+	var err error
+	if hb, err = fromHex(a); err != nil {
+		return 0, err
+	}
+	if lb, err = fromHex(b); err != nil {
+		return 0, err
+	}
+	return hb<<4 | lb, nil
+}
+
+func fromHex(b byte) (byte, error) {
+	switch {
+	case b >= '0' && b <= '9':
+		return b - '0', nil
+	case b >= 'A' && b <= 'F':
+		return b - 'A' + 10, nil
+	// Accept badly encoded bytes.
+	case b >= 'a' && b <= 'f':
+		return b - 'a' + 10, nil
+	}
+	return 0, fmt.Errorf("mime: invalid hex byte %#02x", b)
+}
+
+var bufPool = sync.Pool{
+	New: func() interface{} {
+		return new(bytes.Buffer)
+	},
+}
+
+func getBuffer() *bytes.Buffer {
+	return bufPool.Get().(*bytes.Buffer)
+}
+
+func putBuffer(buf *bytes.Buffer) {
+	if buf.Len() > 1024 {
+		return
+	}
+	buf.Reset()
+	bufPool.Put(buf)
+}
diff --git a/third_party/gofrontend/libgo/go/mime/encodedword_test.go b/third_party/gofrontend/libgo/go/mime/encodedword_test.go
new file mode 100644
index 0000000..2beff5d
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/mime/encodedword_test.go
@@ -0,0 +1,287 @@
+// 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 mime
+
+import (
+	"bytes"
+	"errors"
+	"fmt"
+	"io"
+	"io/ioutil"
+	"strings"
+	"testing"
+)
+
+func ExampleWordEncoder_Encode() {
+	fmt.Println(QEncoding.Encode("utf-8", "¡Hola, señor!"))
+	fmt.Println(QEncoding.Encode("utf-8", "Hello!"))
+	fmt.Println(BEncoding.Encode("UTF-8", "¡Hola, señor!"))
+	fmt.Println(QEncoding.Encode("ISO-8859-1", "Caf\xE9"))
+	// Output:
+	// =?utf-8?q?=C2=A1Hola,_se=C3=B1or!?=
+	// Hello!
+	// =?UTF-8?b?wqFIb2xhLCBzZcOxb3Ih?=
+	// =?ISO-8859-1?q?Caf=E9?=
+}
+
+func ExampleWordDecoder_Decode() {
+	dec := new(WordDecoder)
+	header, err := dec.Decode("=?utf-8?q?=C2=A1Hola,_se=C3=B1or!?=")
+	if err != nil {
+		panic(err)
+	}
+	fmt.Println(header)
+
+	dec.CharsetReader = func(charset string, input io.Reader) (io.Reader, error) {
+		switch charset {
+		case "x-case":
+			// Fake character set for example.
+			// Real use would integrate with packages such
+			// as code.google.com/p/go-charset
+			content, err := ioutil.ReadAll(input)
+			if err != nil {
+				return nil, err
+			}
+			return bytes.NewReader(bytes.ToUpper(content)), nil
+		default:
+			return nil, fmt.Errorf("unhandled charset %q", charset)
+		}
+	}
+	header, err = dec.Decode("=?x-case?q?hello!?=")
+	if err != nil {
+		panic(err)
+	}
+	fmt.Println(header)
+	// Output:
+	// ¡Hola, señor!
+	// HELLO!
+}
+
+func ExampleWordDecoder_DecodeHeader() {
+	dec := new(WordDecoder)
+	header, err := dec.DecodeHeader("=?utf-8?q?=C3=89ric?= <eric@example.org>, =?utf-8?q?Ana=C3=AFs?= <anais@example.org>")
+	if err != nil {
+		panic(err)
+	}
+	fmt.Println(header)
+
+	header, err = dec.DecodeHeader("=?utf-8?q?=C2=A1Hola,?= =?utf-8?q?_se=C3=B1or!?=")
+	if err != nil {
+		panic(err)
+	}
+	fmt.Println(header)
+
+	dec.CharsetReader = func(charset string, input io.Reader) (io.Reader, error) {
+		switch charset {
+		case "x-case":
+			// Fake character set for example.
+			// Real use would integrate with packages such
+			// as code.google.com/p/go-charset
+			content, err := ioutil.ReadAll(input)
+			if err != nil {
+				return nil, err
+			}
+			return bytes.NewReader(bytes.ToUpper(content)), nil
+		default:
+			return nil, fmt.Errorf("unhandled charset %q", charset)
+		}
+	}
+	header, err = dec.DecodeHeader("=?x-case?q?hello_?= =?x-case?q?world!?=")
+	if err != nil {
+		panic(err)
+	}
+	fmt.Println(header)
+	// Output:
+	// Éric <eric@example.org>, Anaïs <anais@example.org>
+	// ¡Hola, señor!
+	// HELLO WORLD!
+}
+
+func TestEncodeWord(t *testing.T) {
+	utf8, iso88591 := "utf-8", "iso-8859-1"
+	tests := []struct {
+		enc      WordEncoder
+		charset  string
+		src, exp string
+	}{
+		{QEncoding, utf8, "François-Jérôme", "=?utf-8?q?Fran=C3=A7ois-J=C3=A9r=C3=B4me?="},
+		{BEncoding, utf8, "Café", "=?utf-8?b?Q2Fmw6k=?="},
+		{QEncoding, iso88591, "La Seleção", "=?iso-8859-1?q?La_Sele=C3=A7=C3=A3o?="},
+		{QEncoding, utf8, "", ""},
+		{QEncoding, utf8, "A", "A"},
+		{QEncoding, iso88591, "a", "a"},
+		{QEncoding, utf8, "123 456", "123 456"},
+		{QEncoding, utf8, "\t !\"#$%&'()*+,-./ :;<>?@[\\]^_`{|}~", "\t !\"#$%&'()*+,-./ :;<>?@[\\]^_`{|}~"},
+	}
+
+	for _, test := range tests {
+		if s := test.enc.Encode(test.charset, test.src); s != test.exp {
+			t.Errorf("Encode(%q) = %q, want %q", test.src, s, test.exp)
+		}
+	}
+}
+
+func TestDecodeWord(t *testing.T) {
+	tests := []struct {
+		src, exp string
+		hasErr   bool
+	}{
+		{"=?UTF-8?Q?=C2=A1Hola,_se=C3=B1or!?=", "¡Hola, señor!", false},
+		{"=?UTF-8?Q?Fran=C3=A7ois-J=C3=A9r=C3=B4me?=", "François-Jérôme", false},
+		{"=?UTF-8?q?ascii?=", "ascii", false},
+		{"=?utf-8?B?QW5kcsOp?=", "André", false},
+		{"=?ISO-8859-1?Q?Rapha=EBl_Dupont?=", "Raphaël Dupont", false},
+		{"=?utf-8?b?IkFudG9uaW8gSm9zw6kiIDxqb3NlQGV4YW1wbGUub3JnPg==?=", `"Antonio José" <jose@example.org>`, false},
+		{"=?UTF-8?A?Test?=", "", true},
+		{"=?UTF-8?Q?A=B?=", "", true},
+		{"=?UTF-8?Q?=A?=", "", true},
+		{"=?UTF-8?A?A?=", "", true},
+	}
+
+	for _, test := range tests {
+		dec := new(WordDecoder)
+		s, err := dec.Decode(test.src)
+		if test.hasErr && err == nil {
+			t.Errorf("Decode(%q) should return an error", test.src)
+			continue
+		}
+		if !test.hasErr && err != nil {
+			t.Errorf("Decode(%q): %v", test.src, err)
+			continue
+		}
+		if s != test.exp {
+			t.Errorf("Decode(%q) = %q, want %q", test.src, s, test.exp)
+		}
+	}
+}
+
+func TestDecodeHeader(t *testing.T) {
+	tests := []struct {
+		src, exp string
+	}{
+		{"=?UTF-8?Q?=C2=A1Hola,_se=C3=B1or!?=", "¡Hola, señor!"},
+		{"=?UTF-8?Q?Fran=C3=A7ois-J=C3=A9r=C3=B4me?=", "François-Jérôme"},
+		{"=?UTF-8?q?ascii?=", "ascii"},
+		{"=?utf-8?B?QW5kcsOp?=", "André"},
+		{"=?ISO-8859-1?Q?Rapha=EBl_Dupont?=", "Raphaël Dupont"},
+		{"Jean", "Jean"},
+		{"=?utf-8?b?IkFudG9uaW8gSm9zw6kiIDxqb3NlQGV4YW1wbGUub3JnPg==?=", `"Antonio José" <jose@example.org>`},
+		{"=?UTF-8?A?Test?=", "=?UTF-8?A?Test?="},
+		{"=?UTF-8?Q?A=B?=", "=?UTF-8?Q?A=B?="},
+		{"=?UTF-8?Q?=A?=", "=?UTF-8?Q?=A?="},
+		{"=?UTF-8?A?A?=", "=?UTF-8?A?A?="},
+		// Incomplete words
+		{"=?", "=?"},
+		{"=?UTF-8?", "=?UTF-8?"},
+		{"=?UTF-8?=", "=?UTF-8?="},
+		{"=?UTF-8?Q", "=?UTF-8?Q"},
+		{"=?UTF-8?Q?", "=?UTF-8?Q?"},
+		{"=?UTF-8?Q?=", "=?UTF-8?Q?="},
+		{"=?UTF-8?Q?A", "=?UTF-8?Q?A"},
+		{"=?UTF-8?Q?A?", "=?UTF-8?Q?A?"},
+		// Tests from RFC 2047
+		{"=?ISO-8859-1?Q?a?=", "a"},
+		{"=?ISO-8859-1?Q?a?= b", "a b"},
+		{"=?ISO-8859-1?Q?a?= =?ISO-8859-1?Q?b?=", "ab"},
+		{"=?ISO-8859-1?Q?a?=  =?ISO-8859-1?Q?b?=", "ab"},
+		{"=?ISO-8859-1?Q?a?= \r\n\t =?ISO-8859-1?Q?b?=", "ab"},
+		{"=?ISO-8859-1?Q?a_b?=", "a b"},
+	}
+
+	for _, test := range tests {
+		dec := new(WordDecoder)
+		s, err := dec.DecodeHeader(test.src)
+		if err != nil {
+			t.Errorf("DecodeHeader(%q): %v", test.src, err)
+		}
+		if s != test.exp {
+			t.Errorf("DecodeHeader(%q) = %q, want %q", test.src, s, test.exp)
+		}
+	}
+}
+
+func TestCharsetDecoder(t *testing.T) {
+	tests := []struct {
+		src      string
+		want     string
+		charsets []string
+		content  []string
+	}{
+		{"=?utf-8?b?Q2Fmw6k=?=", "Café", nil, nil},
+		{"=?ISO-8859-1?Q?caf=E9?=", "café", nil, nil},
+		{"=?US-ASCII?Q?foo_bar?=", "foo bar", nil, nil},
+		{"=?utf-8?Q?=?=", "=?utf-8?Q?=?=", nil, nil},
+		{"=?utf-8?Q?=A?=", "=?utf-8?Q?=A?=", nil, nil},
+		{
+			"=?ISO-8859-15?Q?f=F5=F6?=  =?windows-1252?Q?b=E0r?=",
+			"f\xf5\xf6b\xe0r",
+			[]string{"iso-8859-15", "windows-1252"},
+			[]string{"f\xf5\xf6", "b\xe0r"},
+		},
+	}
+
+	for _, test := range tests {
+		i := 0
+		dec := &WordDecoder{
+			CharsetReader: func(charset string, input io.Reader) (io.Reader, error) {
+				if charset != test.charsets[i] {
+					t.Errorf("DecodeHeader(%q), got charset %q, want %q", test.src, charset, test.charsets[i])
+				}
+				content, err := ioutil.ReadAll(input)
+				if err != nil {
+					t.Errorf("DecodeHeader(%q), error in reader: %v", test.src, err)
+				}
+				got := string(content)
+				if got != test.content[i] {
+					t.Errorf("DecodeHeader(%q), got content %q, want %q", test.src, got, test.content[i])
+				}
+				i++
+
+				return strings.NewReader(got), nil
+			},
+		}
+		got, err := dec.DecodeHeader(test.src)
+		if err != nil {
+			t.Errorf("DecodeHeader(%q): %v", test.src, err)
+		}
+		if got != test.want {
+			t.Errorf("DecodeHeader(%q) = %q, want %q", test.src, got, test.want)
+		}
+	}
+}
+
+func TestCharsetDecoderError(t *testing.T) {
+	dec := &WordDecoder{
+		CharsetReader: func(charset string, input io.Reader) (io.Reader, error) {
+			return nil, errors.New("Test error")
+		},
+	}
+
+	if _, err := dec.DecodeHeader("=?charset?Q?foo?="); err == nil {
+		t.Error("DecodeHeader should return an error")
+	}
+}
+
+func BenchmarkQEncodeWord(b *testing.B) {
+	for i := 0; i < b.N; i++ {
+		QEncoding.Encode("UTF-8", "¡Hola, señor!")
+	}
+}
+
+func BenchmarkQDecodeWord(b *testing.B) {
+	dec := new(WordDecoder)
+
+	for i := 0; i < b.N; i++ {
+		dec.Decode("=?utf-8?q?=C2=A1Hola,_se=C3=B1or!?=")
+	}
+}
+
+func BenchmarkQDecodeHeader(b *testing.B) {
+	dec := new(WordDecoder)
+
+	for i := 0; i < b.N; i++ {
+		dec.Decode("=?utf-8?q?=C2=A1Hola,_se=C3=B1or!?=")
+	}
+}
diff --git a/third_party/gofrontend/libgo/go/mime/grammar.go b/third_party/gofrontend/libgo/go/mime/grammar.go
index 2347324..31b66e8 100644
--- a/third_party/gofrontend/libgo/go/mime/grammar.go
+++ b/third_party/gofrontend/libgo/go/mime/grammar.go
@@ -8,13 +8,13 @@
 	"strings"
 )
 
-// isTSpecial returns true if rune is in 'tspecials' as defined by RFC
+// isTSpecial reports whether rune is in 'tspecials' as defined by RFC
 // 1521 and RFC 2045.
 func isTSpecial(r rune) bool {
 	return strings.IndexRune(`()<>@,;:\"/[]?=`, r) != -1
 }
 
-// isTokenChar returns true if rune is in 'token' as defined by RFC
+// isTokenChar reports whether rune is in 'token' as defined by RFC
 // 1521 and RFC 2045.
 func isTokenChar(r rune) bool {
 	// token := 1*<any (US-ASCII) CHAR except SPACE, CTLs,
@@ -22,7 +22,7 @@
 	return r > 0x20 && r < 0x7f && !isTSpecial(r)
 }
 
-// isToken returns true if s is a 'token' as defined by RFC 1521
+// isToken reports whether s is a 'token' as defined by RFC 1521
 // and RFC 2045.
 func isToken(s string) bool {
 	if s == "" {
diff --git a/third_party/gofrontend/libgo/go/mime/multipart/multipart.go b/third_party/gofrontend/libgo/go/mime/multipart/multipart.go
index 01a667d..6f65a55 100644
--- a/third_party/gofrontend/libgo/go/mime/multipart/multipart.go
+++ b/third_party/gofrontend/libgo/go/mime/multipart/multipart.go
@@ -19,6 +19,7 @@
 	"io"
 	"io/ioutil"
 	"mime"
+	"mime/quotedprintable"
 	"net/textproto"
 )
 
@@ -111,7 +112,7 @@
 	const cte = "Content-Transfer-Encoding"
 	if bp.Header.Get(cte) == "quoted-printable" {
 		bp.Header.Del(cte)
-		bp.r = newQuotedPrintableReader(bp.r)
+		bp.r = quotedprintable.NewReader(bp.r)
 	}
 	return bp, nil
 }
@@ -164,16 +165,18 @@
 	if peek == nil {
 		panic("nil peek buf")
 	}
-
 	// Search the peek buffer for "\r\n--boundary". If found,
 	// consume everything up to the boundary. If not, consume only
 	// as much of the peek buffer as cannot hold the boundary
 	// string.
 	nCopy := 0
 	foundBoundary := false
-	if idx := bytes.Index(peek, p.mr.nlDashBoundary); idx != -1 {
+	if idx, isEnd := p.mr.peekBufferSeparatorIndex(peek); idx != -1 {
 		nCopy = idx
-		foundBoundary = true
+		foundBoundary = isEnd
+		if !isEnd && nCopy == 0 {
+			nCopy = 1 // make some progress.
+		}
 	} else if safeCount := len(peek) - len(p.mr.nlDashBoundary); safeCount > 0 {
 		nCopy = safeCount
 	} else if unexpectedEOF {
@@ -337,6 +340,33 @@
 	return bytes.HasPrefix(rest, mr.nl)
 }
 
+// peekBufferSeparatorIndex returns the index of mr.nlDashBoundary in
+// peek and whether it is a real boundary (and not a prefix of an
+// unrelated separator). To be the end, the peek buffer must contain a
+// newline after the boundary.
+func (mr *Reader) peekBufferSeparatorIndex(peek []byte) (idx int, isEnd bool) {
+	idx = bytes.Index(peek, mr.nlDashBoundary)
+	if idx == -1 {
+		return
+	}
+	peek = peek[idx+len(mr.nlDashBoundary):]
+	if len(peek) > 1 && peek[0] == '-' && peek[1] == '-' {
+		return idx, true
+	}
+	peek = skipLWSPChar(peek)
+	// Don't have a complete line after the peek.
+	if bytes.IndexByte(peek, '\n') == -1 {
+		return -1, false
+	}
+	if len(peek) > 0 && peek[0] == '\n' {
+		return idx, true
+	}
+	if len(peek) > 1 && peek[0] == '\r' && peek[1] == '\n' {
+		return idx, true
+	}
+	return idx, false
+}
+
 // skipLWSPChar returns b with leading spaces and tabs removed.
 // RFC 822 defines:
 //    LWSP-char = SPACE / HTAB
diff --git a/third_party/gofrontend/libgo/go/mime/multipart/multipart_test.go b/third_party/gofrontend/libgo/go/mime/multipart/multipart_test.go
index d662e83..30452d1 100644
--- a/third_party/gofrontend/libgo/go/mime/multipart/multipart_test.go
+++ b/third_party/gofrontend/libgo/go/mime/multipart/multipart_test.go
@@ -351,7 +351,7 @@
 }
 
 func TestQuotedPrintableEncoding(t *testing.T) {
-	// From http://golang.org/issue/4411
+	// From https://golang.org/issue/4411
 	body := "--0016e68ee29c5d515f04cedf6733\r\nContent-Type: text/plain; charset=ISO-8859-1\r\nContent-Disposition: form-data; name=text\r\nContent-Transfer-Encoding: quoted-printable\r\n\r\nwords words words words words words words words words words words words wor=\r\nds words words words words words words words words words words words words =\r\nwords words words words words words words words words words words words wor=\r\nds words words words words words words words words words words words words =\r\nwords words words words words words words words words\r\n--0016e68ee29c5d515f04cedf6733\r\nContent-Type: text/plain; charset=ISO-8859-1\r\nContent-Disposition: form-data; name=submit\r\n\r\nSubmit\r\n--0016e68ee29c5d515f04cedf6733--"
 	r := NewReader(strings.NewReader(body), "0016e68ee29c5d515f04cedf6733")
 	part, err := r.NextPart()
@@ -565,6 +565,58 @@
 		},
 	},
 
+	// Issue 10616; minimal
+	{
+		name: "issue 10616 minimal",
+		sep:  "sep",
+		in: "--sep \r\nFoo: bar\r\n\r\n" +
+			"a\r\n" +
+			"--sep_alt\r\n" +
+			"b\r\n" +
+			"\r\n--sep--",
+		want: []headerBody{
+			{textproto.MIMEHeader{"Foo": {"bar"}}, "a\r\n--sep_alt\r\nb\r\n"},
+		},
+	},
+
+	// Issue 10616; full example from bug.
+	{
+		name: "nested separator prefix is outer separator",
+		sep:  "----=_NextPart_4c2fbafd7ec4c8bf08034fe724b608d9",
+		in: strings.Replace(`------=_NextPart_4c2fbafd7ec4c8bf08034fe724b608d9
+Content-Type: multipart/alternative; boundary="----=_NextPart_4c2fbafd7ec4c8bf08034fe724b608d9_alt"
+
+------=_NextPart_4c2fbafd7ec4c8bf08034fe724b608d9_alt
+Content-Type: text/plain; charset="utf-8"
+Content-Transfer-Encoding: 8bit
+
+This is a multi-part message in MIME format.
+
+------=_NextPart_4c2fbafd7ec4c8bf08034fe724b608d9_alt
+Content-Type: text/html; charset="utf-8"
+Content-Transfer-Encoding: 8bit
+
+html things
+------=_NextPart_4c2fbafd7ec4c8bf08034fe724b608d9_alt--
+------=_NextPart_4c2fbafd7ec4c8bf08034fe724b608d9--`, "\n", "\r\n", -1),
+		want: []headerBody{
+			{textproto.MIMEHeader{"Content-Type": {`multipart/alternative; boundary="----=_NextPart_4c2fbafd7ec4c8bf08034fe724b608d9_alt"`}},
+				strings.Replace(`------=_NextPart_4c2fbafd7ec4c8bf08034fe724b608d9_alt
+Content-Type: text/plain; charset="utf-8"
+Content-Transfer-Encoding: 8bit
+
+This is a multi-part message in MIME format.
+
+------=_NextPart_4c2fbafd7ec4c8bf08034fe724b608d9_alt
+Content-Type: text/html; charset="utf-8"
+Content-Transfer-Encoding: 8bit
+
+html things
+------=_NextPart_4c2fbafd7ec4c8bf08034fe724b608d9_alt--`, "\n", "\r\n", -1),
+			},
+		},
+	},
+
 	roundTripParseTest(),
 }
 
diff --git a/third_party/gofrontend/libgo/go/mime/multipart/quotedprintable.go b/third_party/gofrontend/libgo/go/mime/multipart/quotedprintable.go
deleted file mode 100644
index 9ff4ee7..0000000
--- a/third_party/gofrontend/libgo/go/mime/multipart/quotedprintable.go
+++ /dev/null
@@ -1,118 +0,0 @@
-// Copyright 2012 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.
-
-// The file define a quoted-printable decoder, as specified in RFC 2045.
-// Deviations:
-// 1. in addition to "=\r\n", "=\n" is also treated as soft line break.
-// 2. it will pass through a '\r' or '\n' not preceded by '=', consistent
-//    with other broken QP encoders & decoders.
-
-package multipart
-
-import (
-	"bufio"
-	"bytes"
-	"fmt"
-	"io"
-)
-
-type qpReader struct {
-	br   *bufio.Reader
-	rerr error  // last read error
-	line []byte // to be consumed before more of br
-}
-
-func newQuotedPrintableReader(r io.Reader) io.Reader {
-	return &qpReader{
-		br: bufio.NewReader(r),
-	}
-}
-
-func fromHex(b byte) (byte, error) {
-	switch {
-	case b >= '0' && b <= '9':
-		return b - '0', nil
-	case b >= 'A' && b <= 'F':
-		return b - 'A' + 10, nil
-	}
-	return 0, fmt.Errorf("multipart: invalid quoted-printable hex byte 0x%02x", b)
-}
-
-func (q *qpReader) readHexByte(v []byte) (b byte, err error) {
-	if len(v) < 2 {
-		return 0, io.ErrUnexpectedEOF
-	}
-	var hb, lb byte
-	if hb, err = fromHex(v[0]); err != nil {
-		return 0, err
-	}
-	if lb, err = fromHex(v[1]); err != nil {
-		return 0, err
-	}
-	return hb<<4 | lb, nil
-}
-
-func isQPDiscardWhitespace(r rune) bool {
-	switch r {
-	case '\n', '\r', ' ', '\t':
-		return true
-	}
-	return false
-}
-
-var (
-	crlf       = []byte("\r\n")
-	lf         = []byte("\n")
-	softSuffix = []byte("=")
-)
-
-func (q *qpReader) Read(p []byte) (n int, err error) {
-	for len(p) > 0 {
-		if len(q.line) == 0 {
-			if q.rerr != nil {
-				return n, q.rerr
-			}
-			q.line, q.rerr = q.br.ReadSlice('\n')
-
-			// Does the line end in CRLF instead of just LF?
-			hasLF := bytes.HasSuffix(q.line, lf)
-			hasCR := bytes.HasSuffix(q.line, crlf)
-			wholeLine := q.line
-			q.line = bytes.TrimRightFunc(wholeLine, isQPDiscardWhitespace)
-			if bytes.HasSuffix(q.line, softSuffix) {
-				rightStripped := wholeLine[len(q.line):]
-				q.line = q.line[:len(q.line)-1]
-				if !bytes.HasPrefix(rightStripped, lf) && !bytes.HasPrefix(rightStripped, crlf) {
-					q.rerr = fmt.Errorf("multipart: invalid bytes after =: %q", rightStripped)
-				}
-			} else if hasLF {
-				if hasCR {
-					q.line = append(q.line, '\r', '\n')
-				} else {
-					q.line = append(q.line, '\n')
-				}
-			}
-			continue
-		}
-		b := q.line[0]
-
-		switch {
-		case b == '=':
-			b, err = q.readHexByte(q.line[1:])
-			if err != nil {
-				return n, err
-			}
-			q.line = q.line[2:] // 2 of the 3; other 1 is done below
-		case b == '\t' || b == '\r' || b == '\n':
-			break
-		case b < ' ' || b > '~':
-			return n, fmt.Errorf("multipart: invalid unescaped byte 0x%02x in quoted-printable body", b)
-		}
-		p[0] = b
-		p = p[1:]
-		q.line = q.line[1:]
-		n++
-	}
-	return n, nil
-}
diff --git a/third_party/gofrontend/libgo/go/mime/multipart/writer.go b/third_party/gofrontend/libgo/go/mime/multipart/writer.go
index e13a956..8096093 100644
--- a/third_party/gofrontend/libgo/go/mime/multipart/writer.go
+++ b/third_party/gofrontend/libgo/go/mime/multipart/writer.go
@@ -39,7 +39,8 @@
 // boundary separator with an explicit value.
 //
 // SetBoundary must be called before any parts are created, may only
-// contain certain ASCII characters, and must be 1-69 bytes long.
+// contain certain ASCII characters, and must be non-empty and
+// at most 69 bytes long.
 func (w *Writer) SetBoundary(boundary string) error {
 	if w.lastpart != nil {
 		return errors.New("mime: SetBoundary called after write")
diff --git a/third_party/gofrontend/libgo/go/mime/quotedprintable/reader.go b/third_party/gofrontend/libgo/go/mime/quotedprintable/reader.go
new file mode 100644
index 0000000..3bd6833
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/mime/quotedprintable/reader.go
@@ -0,0 +1,124 @@
+// Copyright 2012 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 quotedprintable implements quoted-printable encoding as specified by
+// RFC 2045.
+package quotedprintable
+
+import (
+	"bufio"
+	"bytes"
+	"fmt"
+	"io"
+)
+
+// Reader is a quoted-printable decoder.
+type Reader struct {
+	br   *bufio.Reader
+	rerr error  // last read error
+	line []byte // to be consumed before more of br
+}
+
+// NewReader returns a quoted-printable reader, decoding from r.
+func NewReader(r io.Reader) *Reader {
+	return &Reader{
+		br: bufio.NewReader(r),
+	}
+}
+
+func fromHex(b byte) (byte, error) {
+	switch {
+	case b >= '0' && b <= '9':
+		return b - '0', nil
+	case b >= 'A' && b <= 'F':
+		return b - 'A' + 10, nil
+	// Accept badly encoded bytes.
+	case b >= 'a' && b <= 'f':
+		return b - 'a' + 10, nil
+	}
+	return 0, fmt.Errorf("quotedprintable: invalid hex byte 0x%02x", b)
+}
+
+func readHexByte(v []byte) (b byte, err error) {
+	if len(v) < 2 {
+		return 0, io.ErrUnexpectedEOF
+	}
+	var hb, lb byte
+	if hb, err = fromHex(v[0]); err != nil {
+		return 0, err
+	}
+	if lb, err = fromHex(v[1]); err != nil {
+		return 0, err
+	}
+	return hb<<4 | lb, nil
+}
+
+func isQPDiscardWhitespace(r rune) bool {
+	switch r {
+	case '\n', '\r', ' ', '\t':
+		return true
+	}
+	return false
+}
+
+var (
+	crlf       = []byte("\r\n")
+	lf         = []byte("\n")
+	softSuffix = []byte("=")
+)
+
+// Read reads and decodes quoted-printable data from the underlying reader.
+func (r *Reader) Read(p []byte) (n int, err error) {
+	// Deviations from RFC 2045:
+	// 1. in addition to "=\r\n", "=\n" is also treated as soft line break.
+	// 2. it will pass through a '\r' or '\n' not preceded by '=', consistent
+	//    with other broken QP encoders & decoders.
+	for len(p) > 0 {
+		if len(r.line) == 0 {
+			if r.rerr != nil {
+				return n, r.rerr
+			}
+			r.line, r.rerr = r.br.ReadSlice('\n')
+
+			// Does the line end in CRLF instead of just LF?
+			hasLF := bytes.HasSuffix(r.line, lf)
+			hasCR := bytes.HasSuffix(r.line, crlf)
+			wholeLine := r.line
+			r.line = bytes.TrimRightFunc(wholeLine, isQPDiscardWhitespace)
+			if bytes.HasSuffix(r.line, softSuffix) {
+				rightStripped := wholeLine[len(r.line):]
+				r.line = r.line[:len(r.line)-1]
+				if !bytes.HasPrefix(rightStripped, lf) && !bytes.HasPrefix(rightStripped, crlf) {
+					r.rerr = fmt.Errorf("quotedprintable: invalid bytes after =: %q", rightStripped)
+				}
+			} else if hasLF {
+				if hasCR {
+					r.line = append(r.line, '\r', '\n')
+				} else {
+					r.line = append(r.line, '\n')
+				}
+			}
+			continue
+		}
+		b := r.line[0]
+
+		switch {
+		case b == '=':
+			b, err = readHexByte(r.line[1:])
+			if err != nil {
+				return n, err
+			}
+			r.line = r.line[2:] // 2 of the 3; other 1 is done below
+		case b == '\t' || b == '\r' || b == '\n':
+			break
+		case b < ' ' || b > '~':
+			return n, fmt.Errorf("quotedprintable: invalid unescaped byte 0x%02x in body", b)
+		}
+		p[0] = b
+		p = p[1:]
+		r.line = r.line[1:]
+		n++
+	}
+	return n, nil
+}
diff --git a/third_party/gofrontend/libgo/go/mime/multipart/quotedprintable_test.go b/third_party/gofrontend/libgo/go/mime/quotedprintable/reader_test.go
similarity index 82%
rename from third_party/gofrontend/libgo/go/mime/multipart/quotedprintable_test.go
rename to third_party/gofrontend/libgo/go/mime/quotedprintable/reader_test.go
index c4de3eb..e77b261 100644
--- a/third_party/gofrontend/libgo/go/mime/multipart/quotedprintable_test.go
+++ b/third_party/gofrontend/libgo/go/mime/quotedprintable/reader_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.
 
-package multipart
+package quotedprintable
 
 import (
 	"bufio"
@@ -19,7 +19,7 @@
 	"time"
 )
 
-func TestQuotedPrintable(t *testing.T) {
+func TestReader(t *testing.T) {
 	tests := []struct {
 		in, want string
 		err      interface{}
@@ -27,17 +27,17 @@
 		{in: "", want: ""},
 		{in: "foo bar", want: "foo bar"},
 		{in: "foo bar=3D", want: "foo bar="},
+		{in: "foo bar=3d", want: "foo bar="}, // lax.
 		{in: "foo bar=\n", want: "foo bar"},
 		{in: "foo bar\n", want: "foo bar\n"}, // somewhat lax.
 		{in: "foo bar=0", want: "foo bar", err: io.ErrUnexpectedEOF},
-		{in: "foo bar=ab", want: "foo bar", err: "multipart: invalid quoted-printable hex byte 0x61"},
 		{in: "foo bar=0D=0A", want: "foo bar\r\n"},
 		{in: " A B        \r\n C ", want: " A B\r\n C"},
 		{in: " A B =\r\n C ", want: " A B  C"},
 		{in: " A B =\n C ", want: " A B  C"}, // lax. treating LF as CRLF
 		{in: "foo=\nbar", want: "foobar"},
-		{in: "foo\x00bar", want: "foo", err: "multipart: invalid unescaped byte 0x00 in quoted-printable body"},
-		{in: "foo bar\xff", want: "foo bar", err: "multipart: invalid unescaped byte 0xff in quoted-printable body"},
+		{in: "foo\x00bar", want: "foo", err: "quotedprintable: invalid unescaped byte 0x00 in body"},
+		{in: "foo bar\xff", want: "foo bar", err: "quotedprintable: invalid unescaped byte 0xff in body"},
 
 		// Equal sign.
 		{in: "=3D30\n", want: "=30\n"},
@@ -56,8 +56,8 @@
 		// Different types of soft line-breaks.
 		{in: "foo=\r\nbar", want: "foobar"},
 		{in: "foo=\nbar", want: "foobar"},
-		{in: "foo=\rbar", want: "foo", err: "multipart: invalid quoted-printable hex byte 0x0d"},
-		{in: "foo=\r\r\r \nbar", want: "foo", err: `multipart: invalid bytes after =: "\r\r\r \n"`},
+		{in: "foo=\rbar", want: "foo", err: "quotedprintable: invalid hex byte 0x0d"},
+		{in: "foo=\r\r\r \nbar", want: "foo", err: `quotedprintable: invalid bytes after =: "\r\r\r \n"`},
 
 		// Example from RFC 2045:
 		{in: "Now's the time =\n" + "for all folk to come=\n" + " to the aid of their country.",
@@ -65,7 +65,7 @@
 	}
 	for _, tt := range tests {
 		var buf bytes.Buffer
-		_, err := io.Copy(&buf, newQuotedPrintableReader(strings.NewReader(tt.in)))
+		_, err := io.Copy(&buf, NewReader(strings.NewReader(tt.in)))
 		if got := buf.String(); got != tt.want {
 			t.Errorf("for %q, got %q; want %q", tt.in, got, tt.want)
 		}
@@ -101,7 +101,7 @@
 
 var badSoftRx = regexp.MustCompile(`=([^\r\n]+?\n)|([^\r\n]+$)|(\r$)|(\r[^\n]+\n)|( \r\n)`)
 
-func TestQPExhaustive(t *testing.T) {
+func TestExhaustive(t *testing.T) {
 	if *useQprint {
 		_, err := exec.LookPath("qprint")
 		if err != nil {
@@ -116,14 +116,14 @@
 			return
 		}
 		buf.Reset()
-		_, err := io.Copy(&buf, newQuotedPrintableReader(strings.NewReader(s)))
+		_, err := io.Copy(&buf, NewReader(strings.NewReader(s)))
 		if err != nil {
 			errStr := err.Error()
 			if strings.Contains(errStr, "invalid bytes after =:") {
 				errStr = "invalid bytes after ="
 			}
 			res[errStr]++
-			if strings.Contains(errStr, "invalid quoted-printable hex byte ") {
+			if strings.Contains(errStr, "invalid hex byte ") {
 				if strings.HasSuffix(errStr, "0x20") && (strings.Contains(s, "=0 ") || strings.Contains(s, "=A ") || strings.Contains(s, "= ")) {
 					return
 				}
@@ -193,10 +193,10 @@
 	got := strings.Join(outcomes, "\n")
 	want := `OK: 21576
 invalid bytes after =: 3397
-multipart: invalid quoted-printable hex byte 0x0a: 1400
-multipart: invalid quoted-printable hex byte 0x0d: 2700
-multipart: invalid quoted-printable hex byte 0x20: 2490
-multipart: invalid quoted-printable hex byte 0x3d: 440
+quotedprintable: invalid hex byte 0x0a: 1400
+quotedprintable: invalid hex byte 0x0d: 2700
+quotedprintable: invalid hex byte 0x20: 2490
+quotedprintable: invalid hex byte 0x3d: 440
 unexpected EOF: 3122`
 	if got != want {
 		t.Errorf("Got:\n%s\nWant:\n%s", got, want)
diff --git a/third_party/gofrontend/libgo/go/mime/quotedprintable/writer.go b/third_party/gofrontend/libgo/go/mime/quotedprintable/writer.go
new file mode 100644
index 0000000..16ea0bf
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/mime/quotedprintable/writer.go
@@ -0,0 +1,172 @@
+// 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 quotedprintable
+
+import "io"
+
+const lineMaxLen = 76
+
+// A Writer is a quoted-printable writer that implements io.WriteCloser.
+type Writer struct {
+	// Binary mode treats the writer's input as pure binary and processes end of
+	// line bytes as binary data.
+	Binary bool
+
+	w    io.Writer
+	i    int
+	line [78]byte
+	cr   bool
+}
+
+// NewWriter returns a new Writer that writes to w.
+func NewWriter(w io.Writer) *Writer {
+	return &Writer{w: w}
+}
+
+// Write encodes p using quoted-printable encoding and writes it to the
+// underlying io.Writer. It limits line length to 76 characters. The encoded
+// bytes are not necessarily flushed until the Writer is closed.
+func (w *Writer) Write(p []byte) (n int, err error) {
+	for i, b := range p {
+		switch {
+		// Simple writes are done in batch.
+		case b >= '!' && b <= '~' && b != '=':
+			continue
+		case isWhitespace(b) || !w.Binary && (b == '\n' || b == '\r'):
+			continue
+		}
+
+		if i > n {
+			if err := w.write(p[n:i]); err != nil {
+				return n, err
+			}
+			n = i
+		}
+
+		if err := w.encode(b); err != nil {
+			return n, err
+		}
+		n++
+	}
+
+	if n == len(p) {
+		return n, nil
+	}
+
+	if err := w.write(p[n:]); err != nil {
+		return n, err
+	}
+
+	return len(p), nil
+}
+
+// Close closes the Writer, flushing any unwritten data to the underlying
+// io.Writer, but does not close the underlying io.Writer.
+func (w *Writer) Close() error {
+	if err := w.checkLastByte(); err != nil {
+		return err
+	}
+
+	return w.flush()
+}
+
+// write limits text encoded in quoted-printable to 76 characters per line.
+func (w *Writer) write(p []byte) error {
+	for _, b := range p {
+		if b == '\n' || b == '\r' {
+			// If the previous byte was \r, the CRLF has already been inserted.
+			if w.cr && b == '\n' {
+				w.cr = false
+				continue
+			}
+
+			if b == '\r' {
+				w.cr = true
+			}
+
+			if err := w.checkLastByte(); err != nil {
+				return err
+			}
+			if err := w.insertCRLF(); err != nil {
+				return err
+			}
+			continue
+		}
+
+		if w.i == lineMaxLen-1 {
+			if err := w.insertSoftLineBreak(); err != nil {
+				return err
+			}
+		}
+
+		w.line[w.i] = b
+		w.i++
+		w.cr = false
+	}
+
+	return nil
+}
+
+func (w *Writer) encode(b byte) error {
+	if lineMaxLen-1-w.i < 3 {
+		if err := w.insertSoftLineBreak(); err != nil {
+			return err
+		}
+	}
+
+	w.line[w.i] = '='
+	w.line[w.i+1] = upperhex[b>>4]
+	w.line[w.i+2] = upperhex[b&0x0f]
+	w.i += 3
+
+	return nil
+}
+
+const upperhex = "0123456789ABCDEF"
+
+// checkLastByte encodes the last buffered byte if it is a space or a tab.
+func (w *Writer) checkLastByte() error {
+	if w.i == 0 {
+		return nil
+	}
+
+	b := w.line[w.i-1]
+	if isWhitespace(b) {
+		w.i--
+		if err := w.encode(b); err != nil {
+			return err
+		}
+	}
+
+	return nil
+}
+
+func (w *Writer) insertSoftLineBreak() error {
+	w.line[w.i] = '='
+	w.i++
+
+	return w.insertCRLF()
+}
+
+func (w *Writer) insertCRLF() error {
+	w.line[w.i] = '\r'
+	w.line[w.i+1] = '\n'
+	w.i += 2
+
+	return w.flush()
+}
+
+func (w *Writer) flush() error {
+	if _, err := w.w.Write(w.line[:w.i]); err != nil {
+		return err
+	}
+
+	w.i = 0
+	return nil
+}
+
+func isWhitespace(b byte) bool {
+	return b == ' ' || b == '\t'
+}
diff --git a/third_party/gofrontend/libgo/go/mime/quotedprintable/writer_test.go b/third_party/gofrontend/libgo/go/mime/quotedprintable/writer_test.go
new file mode 100644
index 0000000..a9b77b3
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/mime/quotedprintable/writer_test.go
@@ -0,0 +1,158 @@
+// 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 quotedprintable
+
+import (
+	"bytes"
+	"io/ioutil"
+	"strings"
+	"testing"
+)
+
+func TestWriter(t *testing.T) {
+	testWriter(t, false)
+}
+
+func TestWriterBinary(t *testing.T) {
+	testWriter(t, true)
+}
+
+func testWriter(t *testing.T, binary bool) {
+	tests := []struct {
+		in, want, wantB string
+	}{
+		{in: "", want: ""},
+		{in: "foo bar", want: "foo bar"},
+		{in: "foo bar=", want: "foo bar=3D"},
+		{in: "foo bar\r", want: "foo bar\r\n", wantB: "foo bar=0D"},
+		{in: "foo bar\r\r", want: "foo bar\r\n\r\n", wantB: "foo bar=0D=0D"},
+		{in: "foo bar\n", want: "foo bar\r\n", wantB: "foo bar=0A"},
+		{in: "foo bar\r\n", want: "foo bar\r\n", wantB: "foo bar=0D=0A"},
+		{in: "foo bar\r\r\n", want: "foo bar\r\n\r\n", wantB: "foo bar=0D=0D=0A"},
+		{in: "foo bar ", want: "foo bar=20"},
+		{in: "foo bar\t", want: "foo bar=09"},
+		{in: "foo bar  ", want: "foo bar =20"},
+		{in: "foo bar \n", want: "foo bar=20\r\n", wantB: "foo bar =0A"},
+		{in: "foo bar \r", want: "foo bar=20\r\n", wantB: "foo bar =0D"},
+		{in: "foo bar \r\n", want: "foo bar=20\r\n", wantB: "foo bar =0D=0A"},
+		{in: "foo bar  \n", want: "foo bar =20\r\n", wantB: "foo bar  =0A"},
+		{in: "foo bar  \n ", want: "foo bar =20\r\n=20", wantB: "foo bar  =0A=20"},
+		{in: "¡Hola Señor!", want: "=C2=A1Hola Se=C3=B1or!"},
+		{
+			in:   "\t !\"#$%&'()*+,-./ :;<>?@[\\]^_`{|}~",
+			want: "\t !\"#$%&'()*+,-./ :;<>?@[\\]^_`{|}~",
+		},
+		{
+			in:   strings.Repeat("a", 75),
+			want: strings.Repeat("a", 75),
+		},
+		{
+			in:   strings.Repeat("a", 76),
+			want: strings.Repeat("a", 75) + "=\r\na",
+		},
+		{
+			in:   strings.Repeat("a", 72) + "=",
+			want: strings.Repeat("a", 72) + "=3D",
+		},
+		{
+			in:   strings.Repeat("a", 73) + "=",
+			want: strings.Repeat("a", 73) + "=\r\n=3D",
+		},
+		{
+			in:   strings.Repeat("a", 74) + "=",
+			want: strings.Repeat("a", 74) + "=\r\n=3D",
+		},
+		{
+			in:   strings.Repeat("a", 75) + "=",
+			want: strings.Repeat("a", 75) + "=\r\n=3D",
+		},
+		{
+			in:   strings.Repeat(" ", 73),
+			want: strings.Repeat(" ", 72) + "=20",
+		},
+		{
+			in:   strings.Repeat(" ", 74),
+			want: strings.Repeat(" ", 73) + "=\r\n=20",
+		},
+		{
+			in:   strings.Repeat(" ", 75),
+			want: strings.Repeat(" ", 74) + "=\r\n=20",
+		},
+		{
+			in:   strings.Repeat(" ", 76),
+			want: strings.Repeat(" ", 75) + "=\r\n=20",
+		},
+		{
+			in:   strings.Repeat(" ", 77),
+			want: strings.Repeat(" ", 75) + "=\r\n =20",
+		},
+	}
+
+	for _, tt := range tests {
+		buf := new(bytes.Buffer)
+		w := NewWriter(buf)
+
+		want := tt.want
+		if binary {
+			w.Binary = true
+			if tt.wantB != "" {
+				want = tt.wantB
+			}
+		}
+
+		if _, err := w.Write([]byte(tt.in)); err != nil {
+			t.Errorf("Write(%q): %v", tt.in, err)
+			continue
+		}
+		if err := w.Close(); err != nil {
+			t.Errorf("Close(): %v", err)
+			continue
+		}
+		got := buf.String()
+		if got != want {
+			t.Errorf("Write(%q), got:\n%q\nwant:\n%q", tt.in, got, want)
+		}
+	}
+}
+
+func TestRoundTrip(t *testing.T) {
+	buf := new(bytes.Buffer)
+	w := NewWriter(buf)
+	if _, err := w.Write(testMsg); err != nil {
+		t.Fatalf("Write: %v", err)
+	}
+	if err := w.Close(); err != nil {
+		t.Fatalf("Close: %v", err)
+	}
+
+	r := NewReader(buf)
+	gotBytes, err := ioutil.ReadAll(r)
+	if err != nil {
+		t.Fatalf("Error while reading from Reader: %v", err)
+	}
+	got := string(gotBytes)
+	if got != string(testMsg) {
+		t.Errorf("Encoding and decoding changed the message, got:\n%s", got)
+	}
+}
+
+// From http://fr.wikipedia.org/wiki/Quoted-Printable
+var testMsg = []byte("Quoted-Printable (QP) est un format d'encodage de données codées sur 8 bits, qui utilise exclusivement les caractères alphanumériques imprimables du code ASCII (7 bits).\r\n" +
+	"\r\n" +
+	"En effet, les différents codages comprennent de nombreux caractères qui ne sont pas représentables en ASCII (par exemple les caractères accentués), ainsi que des caractères dits « non-imprimables ».\r\n" +
+	"\r\n" +
+	"L'encodage Quoted-Printable permet de remédier à ce problème, en procédant de la manière suivante :\r\n" +
+	"\r\n" +
+	"Un octet correspondant à un caractère imprimable de l'ASCII sauf le signe égal (donc un caractère de code ASCII entre 33 et 60 ou entre 62 et 126) ou aux caractères de saut de ligne (codes ASCII 13 et 10) ou une suite de tabulations et espaces non situées en fin de ligne (de codes ASCII respectifs 9 et 32) est représenté tel quel.\r\n" +
+	"Un octet qui ne correspond pas à la définition ci-dessus (caractère non imprimable de l'ASCII, tabulation ou espaces non suivies d'un caractère imprimable avant la fin de la ligne ou signe égal) est représenté par un signe égal, suivi de son numéro, exprimé en hexadécimal.\r\n" +
+	"Enfin, un signe égal suivi par un saut de ligne (donc la suite des trois caractères de codes ASCII 61, 13 et 10) peut être inséré n'importe où, afin de limiter la taille des lignes produites si nécessaire. Une limite de 76 caractères par ligne est généralement respectée.\r\n")
+
+func BenchmarkWriter(b *testing.B) {
+	for i := 0; i < b.N; i++ {
+		w := NewWriter(ioutil.Discard)
+		w.Write(testMsg)
+		w.Close()
+	}
+}
diff --git a/third_party/gofrontend/libgo/go/mime/type.go b/third_party/gofrontend/libgo/go/mime/type.go
index ffda1f0..d369259 100644
--- a/third_party/gofrontend/libgo/go/mime/type.go
+++ b/third_party/gofrontend/libgo/go/mime/type.go
@@ -12,34 +12,75 @@
 )
 
 var (
-	mimeLock       sync.RWMutex
-	mimeTypesLower = map[string]string{
-		".css":  "text/css; charset=utf-8",
-		".gif":  "image/gif",
-		".htm":  "text/html; charset=utf-8",
-		".html": "text/html; charset=utf-8",
-		".jpg":  "image/jpeg",
-		".js":   "application/x-javascript",
-		".pdf":  "application/pdf",
-		".png":  "image/png",
-		".xml":  "text/xml; charset=utf-8",
-	}
-	mimeTypes = clone(mimeTypesLower)
+	mimeLock       sync.RWMutex      // guards following 3 maps
+	mimeTypes      map[string]string // ".Z" => "application/x-compress"
+	mimeTypesLower map[string]string // ".z" => "application/x-compress"
+
+	// extensions maps from MIME type to list of lowercase file
+	// extensions: "image/jpeg" => [".jpg", ".jpeg"]
+	extensions map[string][]string
 )
 
+// setMimeTypes is used by initMime's non-test path, and by tests.
+// The two maps must not be the same, or nil.
+func setMimeTypes(lowerExt, mixExt map[string]string) {
+	if lowerExt == nil || mixExt == nil {
+		panic("nil map")
+	}
+	mimeTypesLower = lowerExt
+	mimeTypes = mixExt
+	extensions = invert(lowerExt)
+}
+
+var builtinTypesLower = map[string]string{
+	".css":  "text/css; charset=utf-8",
+	".gif":  "image/gif",
+	".htm":  "text/html; charset=utf-8",
+	".html": "text/html; charset=utf-8",
+	".jpg":  "image/jpeg",
+	".js":   "application/x-javascript",
+	".pdf":  "application/pdf",
+	".png":  "image/png",
+	".svg":  "image/svg+xml",
+	".xml":  "text/xml; charset=utf-8",
+}
+
 func clone(m map[string]string) map[string]string {
 	m2 := make(map[string]string, len(m))
 	for k, v := range m {
 		m2[k] = v
 		if strings.ToLower(k) != k {
-			panic("keys in mimeTypesLower must be lowercase")
+			panic("keys in builtinTypesLower must be lowercase")
 		}
 	}
 	return m2
 }
 
+func invert(m map[string]string) map[string][]string {
+	m2 := make(map[string][]string, len(m))
+	for k, v := range m {
+		justType, _, err := ParseMediaType(v)
+		if err != nil {
+			panic(err)
+		}
+		m2[justType] = append(m2[justType], k)
+	}
+	return m2
+}
+
 var once sync.Once // guards initMime
 
+var testInitMime, osInitMime func()
+
+func initMime() {
+	if fn := testInitMime; fn != nil {
+		fn()
+	} else {
+		setMimeTypes(builtinTypesLower, clone(builtinTypesLower))
+		osInitMime()
+	}
+}
+
 // TypeByExtension returns the MIME type associated with the file extension ext.
 // The extension ext should begin with a leading dot, as in ".html".
 // When ext has no associated type, TypeByExtension returns "".
@@ -63,8 +104,7 @@
 	defer mimeLock.RUnlock()
 
 	// Case-sensitive lookup.
-	v := mimeTypes[ext]
-	if v != "" {
+	if v := mimeTypes[ext]; v != "" {
 		return v
 	}
 
@@ -91,19 +131,39 @@
 	return mimeTypesLower[string(lower)]
 }
 
+// ExtensionsByType returns the extensions known to be associated with the MIME
+// type typ. The returned extensions will each begin with a leading dot, as in
+// ".html". When typ has no associated extensions, ExtensionsByType returns an
+// nil slice.
+func ExtensionsByType(typ string) ([]string, error) {
+	justType, _, err := ParseMediaType(typ)
+	if err != nil {
+		return nil, err
+	}
+
+	once.Do(initMime)
+	mimeLock.RLock()
+	defer mimeLock.RUnlock()
+	s, ok := extensions[justType]
+	if !ok {
+		return nil, nil
+	}
+	return append([]string{}, s...), nil
+}
+
 // AddExtensionType sets the MIME type associated with
 // the extension ext to typ. The extension should begin with
 // a leading dot, as in ".html".
 func AddExtensionType(ext, typ string) error {
 	if !strings.HasPrefix(ext, ".") {
-		return fmt.Errorf(`mime: extension %q misses dot`, ext)
+		return fmt.Errorf("mime: extension %q missing leading dot", ext)
 	}
 	once.Do(initMime)
 	return setExtensionType(ext, typ)
 }
 
 func setExtensionType(extension, mimeType string) error {
-	_, param, err := ParseMediaType(mimeType)
+	justType, param, err := ParseMediaType(mimeType)
 	if err != nil {
 		return err
 	}
@@ -114,8 +174,14 @@
 	extLower := strings.ToLower(extension)
 
 	mimeLock.Lock()
+	defer mimeLock.Unlock()
 	mimeTypes[extension] = mimeType
 	mimeTypesLower[extLower] = mimeType
-	mimeLock.Unlock()
+	for _, v := range extensions[justType] {
+		if v == extLower {
+			return nil
+		}
+	}
+	extensions[justType] = append(extensions[justType], extLower)
 	return nil
 }
diff --git a/third_party/gofrontend/libgo/go/mime/type_dragonfly.go b/third_party/gofrontend/libgo/go/mime/type_dragonfly.go
new file mode 100644
index 0000000..d09d74a
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/mime/type_dragonfly.go
@@ -0,0 +1,9 @@
+// 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 mime
+
+func init() {
+	typeFiles = append(typeFiles, "/usr/local/etc/mime.types")
+}
diff --git a/third_party/gofrontend/libgo/go/mime/type_freebsd.go b/third_party/gofrontend/libgo/go/mime/type_freebsd.go
new file mode 100644
index 0000000..d09d74a
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/mime/type_freebsd.go
@@ -0,0 +1,9 @@
+// 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 mime
+
+func init() {
+	typeFiles = append(typeFiles, "/usr/local/etc/mime.types")
+}
diff --git a/third_party/gofrontend/libgo/go/mime/type_openbsd.go b/third_party/gofrontend/libgo/go/mime/type_openbsd.go
new file mode 100644
index 0000000..c3b1abb
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/mime/type_openbsd.go
@@ -0,0 +1,9 @@
+// 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 mime
+
+func init() {
+	typeFiles = append(typeFiles, "/usr/share/misc/mime.types")
+}
diff --git a/third_party/gofrontend/libgo/go/mime/type_plan9.go b/third_party/gofrontend/libgo/go/mime/type_plan9.go
index 8cbf677..c3ba186 100644
--- a/third_party/gofrontend/libgo/go/mime/type_plan9.go
+++ b/third_party/gofrontend/libgo/go/mime/type_plan9.go
@@ -10,10 +10,29 @@
 	"strings"
 )
 
+func init() {
+	osInitMime = initMimePlan9
+}
+
+func initMimePlan9() {
+	for _, filename := range typeFiles {
+		loadMimeFile(filename)
+	}
+}
+
 var typeFiles = []string{
 	"/sys/lib/mimetypes",
 }
 
+func initMimeForTests() map[string]string {
+	typeFiles = []string{"testdata/test.types.plan9"}
+	return map[string]string{
+		".t1":  "application/test",
+		".t2":  "text/test; charset=utf-8",
+		".pNg": "image/png",
+	}
+}
+
 func loadMimeFile(filename string) {
 	f, err := os.Open(filename)
 	if err != nil {
@@ -36,18 +55,3 @@
 		panic(err)
 	}
 }
-
-func initMime() {
-	for _, filename := range typeFiles {
-		loadMimeFile(filename)
-	}
-}
-
-func initMimeForTests() map[string]string {
-	typeFiles = []string{"testdata/test.types.plan9"}
-	return map[string]string{
-		".t1":  "application/test",
-		".t2":  "text/test; charset=utf-8",
-		".pNg": "image/png",
-	}
-}
diff --git a/third_party/gofrontend/libgo/go/mime/type_test.go b/third_party/gofrontend/libgo/go/mime/type_test.go
index e4ec254..48735ef 100644
--- a/third_party/gofrontend/libgo/go/mime/type_test.go
+++ b/third_party/gofrontend/libgo/go/mime/type_test.go
@@ -5,12 +5,41 @@
 package mime
 
 import (
+	"reflect"
+	"strings"
+	"sync"
 	"testing"
 )
 
-var typeTests = initMimeForTests()
+func setMimeInit(fn func()) (cleanup func()) {
+	once = sync.Once{}
+	testInitMime = fn
+	return func() { testInitMime = nil }
+}
+
+func clearMimeTypes() {
+	setMimeTypes(map[string]string{}, map[string]string{})
+}
+
+func setType(ext, typ string) {
+	if !strings.HasPrefix(ext, ".") {
+		panic("missing leading dot")
+	}
+	if err := setExtensionType(ext, typ); err != nil {
+		panic("bad test data: " + err.Error())
+	}
+}
 
 func TestTypeByExtension(t *testing.T) {
+	once = sync.Once{}
+	// initMimeForTests returns the platform-specific extension =>
+	// type tests. On Unix and Plan 9, this also tests the parsing
+	// of MIME text files (in testdata/*). On Windows, we test the
+	// real registry on the machine and assume that ".png" exists
+	// there, which empirically it always has, for all versions of
+	// Windows.
+	typeTests := initMimeForTests()
+
 	for ext, want := range typeTests {
 		val := TypeByExtension(ext)
 		if val != want {
@@ -19,15 +48,41 @@
 	}
 }
 
+func TestTypeByExtension_LocalData(t *testing.T) {
+	cleanup := setMimeInit(func() {
+		clearMimeTypes()
+		setType(".foo", "x/foo")
+		setType(".bar", "x/bar")
+		setType(".Bar", "x/bar; capital=1")
+	})
+	defer cleanup()
+
+	tests := map[string]string{
+		".foo":          "x/foo",
+		".bar":          "x/bar",
+		".Bar":          "x/bar; capital=1",
+		".sdlkfjskdlfj": "",
+		".t1":           "", // testdata shouldn't be used
+	}
+
+	for ext, want := range tests {
+		val := TypeByExtension(ext)
+		if val != want {
+			t.Errorf("TypeByExtension(%q) = %q, want %q", ext, val, want)
+		}
+	}
+}
+
 func TestTypeByExtensionCase(t *testing.T) {
 	const custom = "test/test; charset=iso-8859-1"
 	const caps = "test/test; WAS=ALLCAPS"
-	if err := AddExtensionType(".TEST", caps); err != nil {
-		t.Fatalf("error %s for AddExtension(%s)", err, custom)
-	}
-	if err := AddExtensionType(".tesT", custom); err != nil {
-		t.Fatalf("error %s for AddExtension(%s)", err, custom)
-	}
+
+	cleanup := setMimeInit(func() {
+		clearMimeTypes()
+		setType(".TEST", caps)
+		setType(".tesT", custom)
+	})
+	defer cleanup()
 
 	// case-sensitive lookup
 	if got := TypeByExtension(".tesT"); got != custom {
@@ -43,13 +98,54 @@
 	}
 }
 
+func TestExtensionsByType(t *testing.T) {
+	cleanup := setMimeInit(func() {
+		clearMimeTypes()
+		setType(".gif", "image/gif")
+		setType(".a", "foo/letter")
+		setType(".b", "foo/letter")
+		setType(".B", "foo/letter")
+		setType(".PNG", "image/png")
+	})
+	defer cleanup()
+
+	tests := []struct {
+		typ     string
+		want    []string
+		wantErr string
+	}{
+		{typ: "image/gif", want: []string{".gif"}},
+		{typ: "image/png", want: []string{".png"}}, // lowercase
+		{typ: "foo/letter", want: []string{".a", ".b"}},
+		{typ: "x/unknown", want: nil},
+	}
+
+	for _, tt := range tests {
+		got, err := ExtensionsByType(tt.typ)
+		if err != nil && tt.wantErr != "" && strings.Contains(err.Error(), tt.wantErr) {
+			continue
+		}
+		if err != nil {
+			t.Errorf("ExtensionsByType(%q) error: %v", tt.typ, err)
+			continue
+		}
+		if tt.wantErr != "" {
+			t.Errorf("ExtensionsByType(%q) = %q, %v; want error substring %q", tt.typ, got, err, tt.wantErr)
+			continue
+		}
+		if !reflect.DeepEqual(got, tt.want) {
+			t.Errorf("ExtensionsByType(%q) = %q; want %q", tt.typ, got, tt.want)
+		}
+	}
+}
+
 func TestLookupMallocs(t *testing.T) {
+	t.Skip("skipping test on gccgo until it has better escape analysis")
 	n := testing.AllocsPerRun(10000, func() {
 		TypeByExtension(".html")
 		TypeByExtension(".HtML")
 	})
-	// Changed from 0 to 1 for gccgo, pending escape analysis.
-	if n > 1 {
+	if n > 0 {
 		t.Errorf("allocs = %v; want 0", n)
 	}
 }
diff --git a/third_party/gofrontend/libgo/go/mime/type_unix.go b/third_party/gofrontend/libgo/go/mime/type_unix.go
index 3e404cf..bb06a77 100644
--- a/third_party/gofrontend/libgo/go/mime/type_unix.go
+++ b/third_party/gofrontend/libgo/go/mime/type_unix.go
@@ -12,6 +12,10 @@
 	"strings"
 )
 
+func init() {
+	osInitMime = initMimeUnix
+}
+
 var typeFiles = []string{
 	"/etc/mime.types",
 	"/etc/apache2/mime.types",
@@ -44,7 +48,7 @@
 	}
 }
 
-func initMime() {
+func initMimeUnix() {
 	for _, filename := range typeFiles {
 		loadMimeFile(filename)
 	}
diff --git a/third_party/gofrontend/libgo/go/mime/type_windows.go b/third_party/gofrontend/libgo/go/mime/type_windows.go
index ae758d7..97b9aeb 100644
--- a/third_party/gofrontend/libgo/go/mime/type_windows.go
+++ b/third_party/gofrontend/libgo/go/mime/type_windows.go
@@ -5,54 +5,32 @@
 package mime
 
 import (
-	"syscall"
-	"unsafe"
+	"internal/syscall/windows/registry"
 )
 
-func initMime() {
-	var root syscall.Handle
-	rootpathp, _ := syscall.UTF16PtrFromString(`\`)
-	if syscall.RegOpenKeyEx(syscall.HKEY_CLASSES_ROOT, rootpathp,
-		0, syscall.KEY_READ, &root) != nil {
+func init() {
+	osInitMime = initMimeWindows
+}
+
+func initMimeWindows() {
+	names, err := registry.CLASSES_ROOT.ReadSubKeyNames(-1)
+	if err != nil {
 		return
 	}
-	defer syscall.RegCloseKey(root)
-	var count uint32
-	if syscall.RegQueryInfoKey(root, nil, nil, nil, &count, nil, nil, nil, nil, nil, nil, nil) != nil {
-		return
-	}
-	var buf [1 << 10]uint16
-	for i := uint32(0); i < count; i++ {
-		n := uint32(len(buf))
-		if syscall.RegEnumKeyEx(root, i, &buf[0], &n, nil, nil, nil, nil) != nil {
+	for _, name := range names {
+		if len(name) < 2 || name[0] != '.' { // looking for extensions only
 			continue
 		}
-		ext := syscall.UTF16ToString(buf[:])
-		if len(ext) < 2 || ext[0] != '.' { // looking for extensions only
+		k, err := registry.OpenKey(registry.CLASSES_ROOT, name, registry.READ)
+		if err != nil {
 			continue
 		}
-		var h syscall.Handle
-		extpathp, _ := syscall.UTF16PtrFromString(`\` + ext)
-		if syscall.RegOpenKeyEx(
-			syscall.HKEY_CLASSES_ROOT, extpathp,
-			0, syscall.KEY_READ, &h) != nil {
+		v, _, err := k.GetStringValue("Content Type")
+		k.Close()
+		if err != nil {
 			continue
 		}
-		var typ uint32
-		n = uint32(len(buf) * 2) // api expects array of bytes, not uint16
-		contenttypep, _ := syscall.UTF16PtrFromString("Content Type")
-		if syscall.RegQueryValueEx(
-			h, contenttypep,
-			nil, &typ, (*byte)(unsafe.Pointer(&buf[0])), &n) != nil {
-			syscall.RegCloseKey(h)
-			continue
-		}
-		syscall.RegCloseKey(h)
-		if typ != syscall.REG_SZ { // null terminated strings only
-			continue
-		}
-		mimeType := syscall.UTF16ToString(buf[:])
-		setExtensionType(ext, mimeType)
+		setExtensionType(name, v)
 	}
 }
 
diff --git a/third_party/gofrontend/libgo/go/net/addrselect.go b/third_party/gofrontend/libgo/go/net/addrselect.go
new file mode 100644
index 0000000..e22fbac
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/net/addrselect.go
@@ -0,0 +1,388 @@
+// 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 darwin dragonfly freebsd linux netbsd openbsd solaris
+
+// Minimal RFC 6724 address selection.
+
+package net
+
+import "sort"
+
+func sortByRFC6724(addrs []IPAddr) {
+	if len(addrs) < 2 {
+		return
+	}
+	sortByRFC6724withSrcs(addrs, srcAddrs(addrs))
+}
+
+func sortByRFC6724withSrcs(addrs []IPAddr, srcs []IP) {
+	if len(addrs) != len(srcs) {
+		panic("internal error")
+	}
+	addrAttr := make([]ipAttr, len(addrs))
+	srcAttr := make([]ipAttr, len(srcs))
+	for i, v := range addrs {
+		addrAttr[i] = ipAttrOf(v.IP)
+		srcAttr[i] = ipAttrOf(srcs[i])
+	}
+	sort.Stable(&byRFC6724{
+		addrs:    addrs,
+		addrAttr: addrAttr,
+		srcs:     srcs,
+		srcAttr:  srcAttr,
+	})
+}
+
+// srcsAddrs tries to UDP-connect to each address to see if it has a
+// route. (This doesn't send any packets). The destination port
+// number is irrelevant.
+func srcAddrs(addrs []IPAddr) []IP {
+	srcs := make([]IP, len(addrs))
+	dst := UDPAddr{Port: 9}
+	for i := range addrs {
+		dst.IP = addrs[i].IP
+		dst.Zone = addrs[i].Zone
+		c, err := DialUDP("udp", nil, &dst)
+		if err == nil {
+			if src, ok := c.LocalAddr().(*UDPAddr); ok {
+				srcs[i] = src.IP
+			}
+			c.Close()
+		}
+	}
+	return srcs
+}
+
+type ipAttr struct {
+	Scope      scope
+	Precedence uint8
+	Label      uint8
+}
+
+func ipAttrOf(ip IP) ipAttr {
+	if ip == nil {
+		return ipAttr{}
+	}
+	match := rfc6724policyTable.Classify(ip)
+	return ipAttr{
+		Scope:      classifyScope(ip),
+		Precedence: match.Precedence,
+		Label:      match.Label,
+	}
+}
+
+type byRFC6724 struct {
+	addrs    []IPAddr // addrs to sort
+	addrAttr []ipAttr
+	srcs     []IP // or nil if unreachable
+	srcAttr  []ipAttr
+}
+
+func (s *byRFC6724) Len() int { return len(s.addrs) }
+
+func (s *byRFC6724) Swap(i, j int) {
+	s.addrs[i], s.addrs[j] = s.addrs[j], s.addrs[i]
+	s.srcs[i], s.srcs[j] = s.srcs[j], s.srcs[i]
+	s.addrAttr[i], s.addrAttr[j] = s.addrAttr[j], s.addrAttr[i]
+	s.srcAttr[i], s.srcAttr[j] = s.srcAttr[j], s.srcAttr[i]
+}
+
+// Less reports whether i is a better destination address for this
+// host than j.
+//
+// The algorithm and variable names comes from RFC 6724 section 6.
+func (s *byRFC6724) Less(i, j int) bool {
+	DA := s.addrs[i].IP
+	DB := s.addrs[j].IP
+	SourceDA := s.srcs[i]
+	SourceDB := s.srcs[j]
+	attrDA := &s.addrAttr[i]
+	attrDB := &s.addrAttr[j]
+	attrSourceDA := &s.srcAttr[i]
+	attrSourceDB := &s.srcAttr[j]
+
+	const preferDA = true
+	const preferDB = false
+
+	// Rule 1: Avoid unusable destinations.
+	// If DB is known to be unreachable or if Source(DB) is undefined, then
+	// prefer DA.  Similarly, if DA is known to be unreachable or if
+	// Source(DA) is undefined, then prefer DB.
+	if SourceDA == nil && SourceDB == nil {
+		return false // "equal"
+	}
+	if SourceDB == nil {
+		return preferDA
+	}
+	if SourceDA == nil {
+		return preferDB
+	}
+
+	// Rule 2: Prefer matching scope.
+	// If Scope(DA) = Scope(Source(DA)) and Scope(DB) <> Scope(Source(DB)),
+	// then prefer DA.  Similarly, if Scope(DA) <> Scope(Source(DA)) and
+	// Scope(DB) = Scope(Source(DB)), then prefer DB.
+	if attrDA.Scope == attrSourceDA.Scope && attrDB.Scope != attrSourceDB.Scope {
+		return preferDA
+	}
+	if attrDA.Scope != attrSourceDA.Scope && attrDB.Scope == attrSourceDB.Scope {
+		return preferDB
+	}
+
+	// Rule 3: Avoid deprecated addresses.
+	// If Source(DA) is deprecated and Source(DB) is not, then prefer DB.
+	// Similarly, if Source(DA) is not deprecated and Source(DB) is
+	// deprecated, then prefer DA.
+
+	// TODO(bradfitz): implement? low priority for now.
+
+	// Rule 4: Prefer home addresses.
+	// If Source(DA) is simultaneously a home address and care-of address
+	// and Source(DB) is not, then prefer DA.  Similarly, if Source(DB) is
+	// simultaneously a home address and care-of address and Source(DA) is
+	// not, then prefer DB.
+
+	// TODO(bradfitz): implement? low priority for now.
+
+	// Rule 5: Prefer matching label.
+	// If Label(Source(DA)) = Label(DA) and Label(Source(DB)) <> Label(DB),
+	// then prefer DA.  Similarly, if Label(Source(DA)) <> Label(DA) and
+	// Label(Source(DB)) = Label(DB), then prefer DB.
+	if attrSourceDA.Label == attrDA.Label &&
+		attrSourceDB.Label != attrDB.Label {
+		return preferDA
+	}
+	if attrSourceDA.Label != attrDA.Label &&
+		attrSourceDB.Label == attrDB.Label {
+		return preferDB
+	}
+
+	// Rule 6: Prefer higher precedence.
+	// If Precedence(DA) > Precedence(DB), then prefer DA.  Similarly, if
+	// Precedence(DA) < Precedence(DB), then prefer DB.
+	if attrDA.Precedence > attrDB.Precedence {
+		return preferDA
+	}
+	if attrDA.Precedence < attrDB.Precedence {
+		return preferDB
+	}
+
+	// Rule 7: Prefer native transport.
+	// If DA is reached via an encapsulating transition mechanism (e.g.,
+	// IPv6 in IPv4) and DB is not, then prefer DB.  Similarly, if DB is
+	// reached via encapsulation and DA is not, then prefer DA.
+
+	// TODO(bradfitz): implement? low priority for now.
+
+	// Rule 8: Prefer smaller scope.
+	// If Scope(DA) < Scope(DB), then prefer DA.  Similarly, if Scope(DA) >
+	// Scope(DB), then prefer DB.
+	if attrDA.Scope < attrDB.Scope {
+		return preferDA
+	}
+	if attrDA.Scope > attrDB.Scope {
+		return preferDB
+	}
+
+	// Rule 9: Use longest matching prefix.
+	// When DA and DB belong to the same address family (both are IPv6 or
+	// both are IPv4): If CommonPrefixLen(Source(DA), DA) >
+	// CommonPrefixLen(Source(DB), DB), then prefer DA.  Similarly, if
+	// CommonPrefixLen(Source(DA), DA) < CommonPrefixLen(Source(DB), DB),
+	// then prefer DB.
+	da4 := DA.To4() != nil
+	db4 := DB.To4() != nil
+	if da4 == db4 {
+		commonA := commonPrefixLen(SourceDA, DA)
+		commonB := commonPrefixLen(SourceDB, DB)
+		if commonA > commonB {
+			return preferDA
+		}
+		if commonA < commonB {
+			return preferDB
+		}
+	}
+
+	// Rule 10: Otherwise, leave the order unchanged.
+	// If DA preceded DB in the original list, prefer DA.
+	// Otherwise, prefer DB.
+	return false // "equal"
+}
+
+type policyTableEntry struct {
+	Prefix     *IPNet
+	Precedence uint8
+	Label      uint8
+}
+
+type policyTable []policyTableEntry
+
+// RFC 6724 section 2.1.
+var rfc6724policyTable = policyTable{
+	{
+		Prefix:     mustCIDR("::1/128"),
+		Precedence: 50,
+		Label:      0,
+	},
+	{
+		Prefix:     mustCIDR("::/0"),
+		Precedence: 40,
+		Label:      1,
+	},
+	{
+		// IPv4-compatible, etc.
+		Prefix:     mustCIDR("::ffff:0:0/96"),
+		Precedence: 35,
+		Label:      4,
+	},
+	{
+		// 6to4
+		Prefix:     mustCIDR("2002::/16"),
+		Precedence: 30,
+		Label:      2,
+	},
+	{
+		// Teredo
+		Prefix:     mustCIDR("2001::/32"),
+		Precedence: 5,
+		Label:      5,
+	},
+	{
+		Prefix:     mustCIDR("fc00::/7"),
+		Precedence: 3,
+		Label:      13,
+	},
+	{
+		Prefix:     mustCIDR("::/96"),
+		Precedence: 1,
+		Label:      3,
+	},
+	{
+		Prefix:     mustCIDR("fec0::/10"),
+		Precedence: 1,
+		Label:      11,
+	},
+	{
+		Prefix:     mustCIDR("3ffe::/16"),
+		Precedence: 1,
+		Label:      12,
+	},
+}
+
+func init() {
+	sort.Sort(sort.Reverse(byMaskLength(rfc6724policyTable)))
+}
+
+// byMaskLength sorts policyTableEntry by the size of their Prefix.Mask.Size,
+// from smallest mask, to largest.
+type byMaskLength []policyTableEntry
+
+func (s byMaskLength) Len() int      { return len(s) }
+func (s byMaskLength) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
+func (s byMaskLength) Less(i, j int) bool {
+	isize, _ := s[i].Prefix.Mask.Size()
+	jsize, _ := s[j].Prefix.Mask.Size()
+	return isize < jsize
+}
+
+// mustCIDR calls ParseCIDR and panics on any error, or if the network
+// is not IPv6.
+func mustCIDR(s string) *IPNet {
+	ip, ipNet, err := ParseCIDR(s)
+	if err != nil {
+		panic(err.Error())
+	}
+	if len(ip) != IPv6len {
+		panic("unexpected IP length")
+	}
+	return ipNet
+}
+
+// Classify returns the policyTableEntry of the entry with the longest
+// matching prefix that contains ip.
+// The table t must be sorted from largest mask size to smallest.
+func (t policyTable) Classify(ip IP) policyTableEntry {
+	for _, ent := range t {
+		if ent.Prefix.Contains(ip) {
+			return ent
+		}
+	}
+	return policyTableEntry{}
+}
+
+// RFC 6724 section 3.1.
+type scope uint8
+
+const (
+	scopeInterfaceLocal scope = 0x1
+	scopeLinkLocal      scope = 0x2
+	scopeAdminLocal     scope = 0x4
+	scopeSiteLocal      scope = 0x5
+	scopeOrgLocal       scope = 0x8
+	scopeGlobal         scope = 0xe
+)
+
+func classifyScope(ip IP) scope {
+	if ip.IsLoopback() || ip.IsLinkLocalUnicast() {
+		return scopeLinkLocal
+	}
+	ipv6 := len(ip) == IPv6len && ip.To4() == nil
+	if ipv6 && ip.IsMulticast() {
+		return scope(ip[1] & 0xf)
+	}
+	// Site-local addresses are defined in RFC 3513 section 2.5.6
+	// (and deprecated in RFC 3879).
+	if ipv6 && ip[0] == 0xfe && ip[1]&0xc0 == 0xc0 {
+		return scopeSiteLocal
+	}
+	return scopeGlobal
+}
+
+// commonPrefixLen reports the length of the longest prefix (looking
+// at the most significant, or leftmost, bits) that the
+// two addresses have in common, up to the length of a's prefix (i.e.,
+// the portion of the address not including the interface ID).
+//
+// If a or b is an IPv4 address as an IPv6 address, the IPv4 addresses
+// are compared (with max common prefix length of 32).
+// If a and b are different IP versions, 0 is returned.
+//
+// See https://tools.ietf.org/html/rfc6724#section-2.2
+func commonPrefixLen(a, b IP) (cpl int) {
+	if a4 := a.To4(); a4 != nil {
+		a = a4
+	}
+	if b4 := b.To4(); b4 != nil {
+		b = b4
+	}
+	if len(a) != len(b) {
+		return 0
+	}
+	// If IPv6, only up to the prefix (first 64 bits)
+	if len(a) > 8 {
+		a = a[:8]
+		b = b[:8]
+	}
+	for len(a) > 0 {
+		if a[0] == b[0] {
+			cpl += 8
+			a = a[1:]
+			b = b[1:]
+			continue
+		}
+		bits := 8
+		ab, bb := a[0], b[0]
+		for {
+			ab >>= 1
+			bb >>= 1
+			bits--
+			if ab == bb {
+				cpl += bits
+				return
+			}
+		}
+	}
+	return
+}
diff --git a/third_party/gofrontend/libgo/go/net/addrselect_test.go b/third_party/gofrontend/libgo/go/net/addrselect_test.go
new file mode 100644
index 0000000..5620227
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/net/addrselect_test.go
@@ -0,0 +1,219 @@
+// 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 darwin dragonfly freebsd linux netbsd openbsd solaris
+
+package net
+
+import (
+	"reflect"
+	"testing"
+)
+
+func TestSortByRFC6724(t *testing.T) {
+	tests := []struct {
+		in      []IPAddr
+		srcs    []IP
+		want    []IPAddr
+		reverse bool // also test it starting backwards
+	}{
+		// Examples from RFC 6724 section 10.2:
+
+		// Prefer matching scope.
+		{
+			in: []IPAddr{
+				{IP: ParseIP("2001:db8:1::1")},
+				{IP: ParseIP("198.51.100.121")},
+			},
+			srcs: []IP{
+				ParseIP("2001:db8:1::2"),
+				ParseIP("169.254.13.78"),
+			},
+			want: []IPAddr{
+				{IP: ParseIP("2001:db8:1::1")},
+				{IP: ParseIP("198.51.100.121")},
+			},
+			reverse: true,
+		},
+
+		// Prefer matching scope.
+		{
+			in: []IPAddr{
+				{IP: ParseIP("2001:db8:1::1")},
+				{IP: ParseIP("198.51.100.121")},
+			},
+			srcs: []IP{
+				ParseIP("fe80::1"),
+				ParseIP("198.51.100.117"),
+			},
+			want: []IPAddr{
+				{IP: ParseIP("198.51.100.121")},
+				{IP: ParseIP("2001:db8:1::1")},
+			},
+			reverse: true,
+		},
+
+		// Prefer higher precedence.
+		{
+			in: []IPAddr{
+				{IP: ParseIP("2001:db8:1::1")},
+				{IP: ParseIP("10.1.2.3")},
+			},
+			srcs: []IP{
+				ParseIP("2001:db8:1::2"),
+				ParseIP("10.1.2.4"),
+			},
+			want: []IPAddr{
+				{IP: ParseIP("2001:db8:1::1")},
+				{IP: ParseIP("10.1.2.3")},
+			},
+			reverse: true,
+		},
+
+		// Prefer smaller scope.
+		{
+			in: []IPAddr{
+				{IP: ParseIP("2001:db8:1::1")},
+				{IP: ParseIP("fe80::1")},
+			},
+			srcs: []IP{
+				ParseIP("2001:db8:1::2"),
+				ParseIP("fe80::2"),
+			},
+			want: []IPAddr{
+				{IP: ParseIP("fe80::1")},
+				{IP: ParseIP("2001:db8:1::1")},
+			},
+			reverse: true,
+		},
+	}
+	for i, tt := range tests {
+		inCopy := make([]IPAddr, len(tt.in))
+		copy(inCopy, tt.in)
+		srcCopy := make([]IP, len(tt.in))
+		copy(srcCopy, tt.srcs)
+		sortByRFC6724withSrcs(inCopy, srcCopy)
+		if !reflect.DeepEqual(inCopy, tt.want) {
+			t.Errorf("test %d:\nin = %s\ngot: %s\nwant: %s\n", i, tt.in, inCopy, tt.want)
+		}
+		if tt.reverse {
+			copy(inCopy, tt.in)
+			copy(srcCopy, tt.srcs)
+			for j := 0; j < len(inCopy)/2; j++ {
+				k := len(inCopy) - j - 1
+				inCopy[j], inCopy[k] = inCopy[k], inCopy[j]
+				srcCopy[j], srcCopy[k] = srcCopy[k], srcCopy[j]
+			}
+			sortByRFC6724withSrcs(inCopy, srcCopy)
+			if !reflect.DeepEqual(inCopy, tt.want) {
+				t.Errorf("test %d, starting backwards:\nin = %s\ngot: %s\nwant: %s\n", i, tt.in, inCopy, tt.want)
+			}
+		}
+
+	}
+
+}
+
+func TestRFC6724PolicyTableClassify(t *testing.T) {
+	tests := []struct {
+		ip   IP
+		want policyTableEntry
+	}{
+		{
+			ip: ParseIP("127.0.0.1"),
+			want: policyTableEntry{
+				Prefix:     &IPNet{IP: ParseIP("::ffff:0:0"), Mask: CIDRMask(96, 128)},
+				Precedence: 35,
+				Label:      4,
+			},
+		},
+		{
+			ip: ParseIP("2601:645:8002:a500:986f:1db8:c836:bd65"),
+			want: policyTableEntry{
+				Prefix:     &IPNet{IP: ParseIP("::"), Mask: CIDRMask(0, 128)},
+				Precedence: 40,
+				Label:      1,
+			},
+		},
+		{
+			ip: ParseIP("::1"),
+			want: policyTableEntry{
+				Prefix:     &IPNet{IP: ParseIP("::1"), Mask: CIDRMask(128, 128)},
+				Precedence: 50,
+				Label:      0,
+			},
+		},
+		{
+			ip: ParseIP("2002::ab12"),
+			want: policyTableEntry{
+				Prefix:     &IPNet{IP: ParseIP("2002::"), Mask: CIDRMask(16, 128)},
+				Precedence: 30,
+				Label:      2,
+			},
+		},
+	}
+	for i, tt := range tests {
+		got := rfc6724policyTable.Classify(tt.ip)
+		if !reflect.DeepEqual(got, tt.want) {
+			t.Errorf("%d. Classify(%s) = %v; want %v", i, tt.ip, got, tt.want)
+		}
+	}
+}
+
+func TestRFC6724ClassifyScope(t *testing.T) {
+	tests := []struct {
+		ip   IP
+		want scope
+	}{
+		{ParseIP("127.0.0.1"), scopeLinkLocal},   // rfc6724#section-3.2
+		{ParseIP("::1"), scopeLinkLocal},         // rfc4007#section-4
+		{ParseIP("169.254.1.2"), scopeLinkLocal}, // rfc6724#section-3.2
+		{ParseIP("fec0::1"), scopeSiteLocal},
+		{ParseIP("8.8.8.8"), scopeGlobal},
+
+		{ParseIP("ff02::"), scopeLinkLocal},  // IPv6 multicast
+		{ParseIP("ff05::"), scopeSiteLocal},  // IPv6 multicast
+		{ParseIP("ff04::"), scopeAdminLocal}, // IPv6 multicast
+		{ParseIP("ff0e::"), scopeGlobal},     // IPv6 multicast
+
+		{IPv4(0xe0, 0, 0, 0), scopeGlobal},       // IPv4 link-local multicast as 16 bytes
+		{IPv4(0xe0, 2, 2, 2), scopeGlobal},       // IPv4 global multicast as 16 bytes
+		{IPv4(0xe0, 0, 0, 0).To4(), scopeGlobal}, // IPv4 link-local multicast as 4 bytes
+		{IPv4(0xe0, 2, 2, 2).To4(), scopeGlobal}, // IPv4 global multicast as 4 bytes
+	}
+	for i, tt := range tests {
+		got := classifyScope(tt.ip)
+		if got != tt.want {
+			t.Errorf("%d. classifyScope(%s) = %x; want %x", i, tt.ip, got, tt.want)
+		}
+	}
+}
+
+func TestRFC6724CommonPrefixLength(t *testing.T) {
+	tests := []struct {
+		a, b IP
+		want int
+	}{
+		{ParseIP("fe80::1"), ParseIP("fe80::2"), 64},
+		{ParseIP("fe81::1"), ParseIP("fe80::2"), 15},
+		{ParseIP("127.0.0.1"), ParseIP("fe80::1"), 0}, // diff size
+		{IPv4(1, 2, 3, 4), IP{1, 2, 3, 4}, 32},
+		{IP{1, 2, 255, 255}, IP{1, 2, 0, 0}, 16},
+		{IP{1, 2, 127, 255}, IP{1, 2, 0, 0}, 17},
+		{IP{1, 2, 63, 255}, IP{1, 2, 0, 0}, 18},
+		{IP{1, 2, 31, 255}, IP{1, 2, 0, 0}, 19},
+		{IP{1, 2, 15, 255}, IP{1, 2, 0, 0}, 20},
+		{IP{1, 2, 7, 255}, IP{1, 2, 0, 0}, 21},
+		{IP{1, 2, 3, 255}, IP{1, 2, 0, 0}, 22},
+		{IP{1, 2, 1, 255}, IP{1, 2, 0, 0}, 23},
+		{IP{1, 2, 0, 255}, IP{1, 2, 0, 0}, 24},
+	}
+	for i, tt := range tests {
+		got := commonPrefixLen(tt.a, tt.b)
+		if got != tt.want {
+			t.Errorf("%d. commonPrefixLen(%s, %s) = %d; want %d", i, tt.a, tt.b, got, tt.want)
+		}
+	}
+
+}
diff --git a/third_party/gofrontend/libgo/go/net/cgo_android.go b/third_party/gofrontend/libgo/go/net/cgo_android.go
index 3819ce5..fe9925b 100644
--- a/third_party/gofrontend/libgo/go/net/cgo_android.go
+++ b/third_party/gofrontend/libgo/go/net/cgo_android.go
@@ -9,6 +9,4 @@
 //#include <netdb.h>
 import "C"
 
-func cgoAddrInfoFlags() C.int {
-	return C.AI_CANONNAME
-}
+const cgoAddrInfoFlags = C.AI_CANONNAME
diff --git a/third_party/gofrontend/libgo/go/net/cgo_bsd.go b/third_party/gofrontend/libgo/go/net/cgo_bsd.go
index ce46f2e..ae1054b 100644
--- a/third_party/gofrontend/libgo/go/net/cgo_bsd.go
+++ b/third_party/gofrontend/libgo/go/net/cgo_bsd.go
@@ -2,8 +2,8 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-// +build !netgo
-// +build darwin dragonfly freebsd solaris
+// +build cgo,!netgo
+// +build darwin dragonfly freebsd
 
 package net
 
@@ -13,6 +13,4 @@
 
 import "syscall"
 
-func cgoAddrInfoFlags() int {
-	return (syscall.AI_CANONNAME | syscall.AI_V4MAPPED | syscall.AI_ALL) & syscall.AI_MASK
-}
+const cgoAddrInfoFlags = (syscall.AI_CANONNAME | syscall.AI_V4MAPPED | syscall.AI_ALL) & syscall.AI_MASK
diff --git a/third_party/gofrontend/libgo/go/net/cgo_linux.go b/third_party/gofrontend/libgo/go/net/cgo_linux.go
index 0e33226..baf2072 100644
--- a/third_party/gofrontend/libgo/go/net/cgo_linux.go
+++ b/third_party/gofrontend/libgo/go/net/cgo_linux.go
@@ -12,12 +12,10 @@
 
 import "syscall"
 
-func cgoAddrInfoFlags() int {
-	// NOTE(rsc): In theory there are approximately balanced
-	// arguments for and against including AI_ADDRCONFIG
-	// in the flags (it includes IPv4 results only on IPv4 systems,
-	// and similarly for IPv6), but in practice setting it causes
-	// getaddrinfo to return the wrong canonical name on Linux.
-	// So definitely leave it out.
-	return syscall.AI_CANONNAME | syscall.AI_V4MAPPED | syscall.AI_ALL
-}
+// NOTE(rsc): In theory there are approximately balanced
+// arguments for and against including AI_ADDRCONFIG
+// in the flags (it includes IPv4 results only on IPv4 systems,
+// and similarly for IPv6), but in practice setting it causes
+// getaddrinfo to return the wrong canonical name on Linux.
+// So definitely leave it out.
+const cgoAddrInfoFlags = syscall.AI_CANONNAME | syscall.AI_V4MAPPED | syscall.AI_ALL
diff --git a/third_party/gofrontend/libgo/go/net/cgo_netbsd.go b/third_party/gofrontend/libgo/go/net/cgo_netbsd.go
index 3c13103..8a16871 100644
--- a/third_party/gofrontend/libgo/go/net/cgo_netbsd.go
+++ b/third_party/gofrontend/libgo/go/net/cgo_netbsd.go
@@ -9,8 +9,6 @@
 /*
 #include <netdb.h>
 */
-import "C"
+import "syscall"
 
-func cgoAddrInfoFlags() int {
-	return C.AI_CANONNAME
-}
+const cgoAddrInfoFlags = syscall.AI_CANONNAME
diff --git a/third_party/gofrontend/libgo/go/net/cgo_openbsd.go b/third_party/gofrontend/libgo/go/net/cgo_openbsd.go
index 09c5ad2..1830913 100644
--- a/third_party/gofrontend/libgo/go/net/cgo_openbsd.go
+++ b/third_party/gofrontend/libgo/go/net/cgo_openbsd.go
@@ -11,6 +11,4 @@
 */
 import "C"
 
-func cgoAddrInfoFlags() C.int {
-	return C.AI_CANONNAME
-}
+const cgoAddrInfoFlags = C.AI_CANONNAME
diff --git a/third_party/gofrontend/libgo/go/net/cgo_resnew.go b/third_party/gofrontend/libgo/go/net/cgo_resnew.go
new file mode 100644
index 0000000..ebca1bd
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/net/cgo_resnew.go
@@ -0,0 +1,36 @@
+// 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 cgo,!netgo
+// +build darwin linux,!android netbsd solaris
+
+package net
+
+/*
+#include <sys/types.h>
+#include <sys/socket.h>
+
+#include <netdb.h>
+*/
+
+import (
+	"syscall"
+)
+
+//extern getnameinfo
+func libc_getnameinfo(*syscall.RawSockaddr, syscall.Socklen_t, *byte, syscall.Size_t, *byte, syscall.Size_t, int) int
+
+func cgoNameinfoPTR(b []byte, sa *syscall.RawSockaddr, salen syscall.Socklen_t) (int, error) {
+	syscall.Entersyscall()
+	gerrno := libc_getnameinfo(sa, salen, &b[0], syscall.Size_t(len(b)), nil, 0, syscall.NI_NAMEREQD)
+	syscall.Exitsyscall()
+	var err error
+	if gerrno == syscall.EAI_SYSTEM {
+		errno := syscall.GetErrno()
+		if errno != 0 {
+			err = errno
+		}
+	}
+	return gerrno, err
+}
diff --git a/third_party/gofrontend/libgo/go/net/cgo_resold.go b/third_party/gofrontend/libgo/go/net/cgo_resold.go
new file mode 100644
index 0000000..8e13e41
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/net/cgo_resold.go
@@ -0,0 +1,36 @@
+// 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 cgo,!netgo
+// +build android freebsd dragonfly openbsd
+
+package net
+
+/*
+#include <sys/types.h>
+#include <sys/socket.h>
+
+#include <netdb.h>
+*/
+
+import (
+	"syscall"
+)
+
+//extern getnameinfo
+func libc_getnameinfo(*syscall.RawSockaddr, syscall.Socklen_t, *byte, syscall.Size_t, *byte, syscall.Size_t, int) int
+
+func cgoNameinfoPTR(b []byte, sa *syscall.RawSockaddr, salen syscall.Socklen_t) (int, error) {
+	syscall.Entersyscall()
+	gerrno := libc_getnameinfo(sa, salen, &b[0], syscall.Size(len(b)), nil, 0, syscall.NI_NAMEREQD)
+	syscall.Exitsyscall()
+	var err error
+	if gerrno == syscall.EAI_SYSTEM {
+		errno := syscall.GetErrno()
+		if errno != 0 {
+			err = errno
+		}
+	}
+	return gerrno, err
+}
diff --git a/third_party/gofrontend/libgo/go/net/cgo_socknew.go b/third_party/gofrontend/libgo/go/net/cgo_socknew.go
new file mode 100644
index 0000000..81816c6
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/net/cgo_socknew.go
@@ -0,0 +1,32 @@
+// 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 cgo,!netgo
+// +build android linux solaris
+
+package net
+
+/*
+#include <sys/types.h>
+#include <sys/socket.h>
+
+#include <netinet/in.h>
+*/
+
+import (
+	"syscall"
+	"unsafe"
+)
+
+func cgoSockaddrInet4(ip IP) *syscall.RawSockaddr {
+	sa := syscall.RawSockaddrInet4{Family: syscall.AF_INET}
+	copy(sa.Addr[:], ip)
+	return (*syscall.RawSockaddr)(unsafe.Pointer(&sa))
+}
+
+func cgoSockaddrInet6(ip IP) *syscall.RawSockaddr {
+	sa := syscall.RawSockaddrInet6{Family: syscall.AF_INET6}
+	copy(sa.Addr[:], ip)
+	return (*syscall.RawSockaddr)(unsafe.Pointer(&sa))
+}
diff --git a/third_party/gofrontend/libgo/go/net/cgo_sockold.go b/third_party/gofrontend/libgo/go/net/cgo_sockold.go
new file mode 100644
index 0000000..e80e03b
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/net/cgo_sockold.go
@@ -0,0 +1,32 @@
+// 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 cgo,!netgo
+// +build darwin dragonfly freebsd netbsd openbsd
+
+package net
+
+/*
+#include <sys/types.h>
+#include <sys/socket.h>
+
+#include <netinet/in.h>
+*/
+
+import (
+	"syscall"
+	"unsafe"
+)
+
+func cgoSockaddrInet4(ip IP) *syscall.RawSockaddr {
+	sa := syscall.RawSockaddrInet4{Len: syscall.SizeofSockaddrInet4, Family: syscall.AF_INET}
+	copy(sa.Addr[:], ip)
+	return (*syscall.RawSockaddr)(unsafe.Pointer(&sa))
+}
+
+func cgoSockaddrInet6(ip IP) *syscall.RawSockaddr {
+	sa := syscall.RawSockaddrInet6{Len: syscall.SizeofSockaddrInet6, Family: syscall.AF_INET6}
+	copy(sa.Addr[:], ip)
+	return (*syscall.RawSockaddr)(unsafe.Pointer(&sa))
+}
diff --git a/third_party/gofrontend/libgo/go/net/cgo_solaris.go b/third_party/gofrontend/libgo/go/net/cgo_solaris.go
new file mode 100644
index 0000000..05811c6
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/net/cgo_solaris.go
@@ -0,0 +1,16 @@
+// 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 cgo,!netgo
+
+package net
+
+/*
+#cgo LDFLAGS: -lsocket -lnsl -lsendfile
+#include <netdb.h>
+*/
+
+import "syscall"
+
+const cgoAddrInfoFlags = syscall.AI_CANONNAME | syscall.AI_V4MAPPED | syscall.AI_ALL
diff --git a/third_party/gofrontend/libgo/go/net/cgo_stub.go b/third_party/gofrontend/libgo/go/net/cgo_stub.go
index f533c14..b86ff7d 100644
--- a/third_party/gofrontend/libgo/go/net/cgo_stub.go
+++ b/third_party/gofrontend/libgo/go/net/cgo_stub.go
@@ -4,10 +4,16 @@
 
 // +build !cgo netgo
 
-// Stub cgo routines for systems that do not use cgo to do network lookups.
-
 package net
 
+func init() { netGo = true }
+
+type addrinfoErrno int
+
+func (eai addrinfoErrno) Error() string   { return "<nil>" }
+func (eai addrinfoErrno) Temporary() bool { return false }
+func (eai addrinfoErrno) Timeout() bool   { return false }
+
 func cgoLookupHost(name string) (addrs []string, err error, completed bool) {
 	return nil, nil, false
 }
@@ -16,10 +22,14 @@
 	return 0, nil, false
 }
 
-func cgoLookupIP(name string) (addrs []IP, err error, completed bool) {
+func cgoLookupIP(name string) (addrs []IPAddr, err error, completed bool) {
 	return nil, nil, false
 }
 
 func cgoLookupCNAME(name string) (cname string, err error, completed bool) {
 	return "", nil, false
 }
+
+func cgoLookupPTR(addr string) (ptrs []string, err error, completed bool) {
+	return nil, nil, false
+}
diff --git a/third_party/gofrontend/libgo/go/net/cgo_unix.go b/third_party/gofrontend/libgo/go/net/cgo_unix.go
index 0abf434..8eafa8c 100644
--- a/third_party/gofrontend/libgo/go/net/cgo_unix.go
+++ b/third_party/gofrontend/libgo/go/net/cgo_unix.go
@@ -2,8 +2,8 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-// +build !netgo
-// +build darwin dragonfly freebsd linux netbsd openbsd
+// +build cgo,!netgo
+// +build darwin dragonfly freebsd linux netbsd openbsd solaris
 
 package net
 
@@ -42,24 +42,30 @@
 	return string(a[:i])
 }
 
-func cgoLookupHost(name string) (addrs []string, err error, completed bool) {
-	ip, err, completed := cgoLookupIP(name)
-	for _, p := range ip {
-		addrs = append(addrs, p.String())
+// An addrinfoErrno represents a getaddrinfo, getnameinfo-specific
+// error number. It's a signed number and a zero value is a non-error
+// by convention.
+type addrinfoErrno int
+
+func (eai addrinfoErrno) Error() string   { return bytePtrToString(libc_gai_strerror(int(eai))) }
+func (eai addrinfoErrno) Temporary() bool { return eai == syscall.EAI_AGAIN }
+func (eai addrinfoErrno) Timeout() bool   { return false }
+
+func cgoLookupHost(name string) (hosts []string, err error, completed bool) {
+	addrs, err, completed := cgoLookupIP(name)
+	for _, addr := range addrs {
+		hosts = append(hosts, addr.String())
 	}
 	return
 }
 
-func cgoLookupPort(net, service string) (port int, err error, completed bool) {
+func cgoLookupPort(network, service string) (port int, err error, completed bool) {
 	acquireThread()
 	defer releaseThread()
 
-	var res *syscall.Addrinfo
 	var hints syscall.Addrinfo
-
-	switch net {
-	case "":
-		// no hints
+	switch network {
+	case "": // no hints
 	case "tcp", "tcp4", "tcp6":
 		hints.Ai_socktype = syscall.SOCK_STREAM
 		hints.Ai_protocol = syscall.IPPROTO_TCP
@@ -67,10 +73,10 @@
 		hints.Ai_socktype = syscall.SOCK_DGRAM
 		hints.Ai_protocol = syscall.IPPROTO_UDP
 	default:
-		return 0, UnknownNetworkError(net), true
+		return 0, &DNSError{Err: "unknown network", Name: network + "/" + service}, true
 	}
-	if len(net) >= 4 {
-		switch net[3] {
+	if len(network) >= 4 {
+		switch network[3] {
 		case '4':
 			hints.Ai_family = syscall.AF_INET
 		case '6':
@@ -79,48 +85,56 @@
 	}
 
 	s := syscall.StringBytePtr(service)
+	var res *syscall.Addrinfo
 	syscall.Entersyscall()
 	gerrno := libc_getaddrinfo(nil, s, &hints, &res)
 	syscall.Exitsyscall()
-	if gerrno == 0 {
-		defer libc_freeaddrinfo(res)
-		for r := res; r != nil; r = r.Ai_next {
-			switch r.Ai_family {
-			default:
-				continue
-			case syscall.AF_INET:
-				sa := (*syscall.RawSockaddrInet4)(unsafe.Pointer(r.Ai_addr))
-				p := (*[2]byte)(unsafe.Pointer(&sa.Port))
-				return int(p[0])<<8 | int(p[1]), nil, true
-			case syscall.AF_INET6:
-				sa := (*syscall.RawSockaddrInet6)(unsafe.Pointer(r.Ai_addr))
-				p := (*[2]byte)(unsafe.Pointer(&sa.Port))
-				return int(p[0])<<8 | int(p[1]), nil, true
+	if gerrno != 0 {
+		switch gerrno {
+		case syscall.EAI_SYSTEM:
+			errno := syscall.GetErrno()
+			if errno == 0 { // see golang.org/issue/6232
+				errno = syscall.EMFILE
 			}
+			err = errno
+		default:
+			err = addrinfoErrno(gerrno)
+		}
+		return 0, &DNSError{Err: err.Error(), Name: network + "/" + service}, true
+	}
+	defer libc_freeaddrinfo(res)
+
+	for r := res; r != nil; r = r.Ai_next {
+		switch r.Ai_family {
+		case syscall.AF_INET:
+			sa := (*syscall.RawSockaddrInet4)(unsafe.Pointer(r.Ai_addr))
+			p := (*[2]byte)(unsafe.Pointer(&sa.Port))
+			return int(p[0])<<8 | int(p[1]), nil, true
+		case syscall.AF_INET6:
+			sa := (*syscall.RawSockaddrInet6)(unsafe.Pointer(r.Ai_addr))
+			p := (*[2]byte)(unsafe.Pointer(&sa.Port))
+			return int(p[0])<<8 | int(p[1]), nil, true
 		}
 	}
-	return 0, &AddrError{"unknown port", net + "/" + service}, true
+	return 0, &DNSError{Err: "unknown port", Name: network + "/" + service}, true
 }
 
-func cgoLookupIPCNAME(name string) (addrs []IP, cname string, err error, completed bool) {
+func cgoLookupIPCNAME(name string) (addrs []IPAddr, cname string, err error, completed bool) {
 	acquireThread()
 	defer releaseThread()
 
-	var res *syscall.Addrinfo
 	var hints syscall.Addrinfo
-
-	hints.Ai_flags = int32(cgoAddrInfoFlags())
+	hints.Ai_flags = int32(cgoAddrInfoFlags)
 	hints.Ai_socktype = syscall.SOCK_STREAM
 
 	h := syscall.StringBytePtr(name)
+	var res *syscall.Addrinfo
 	syscall.Entersyscall()
 	gerrno := libc_getaddrinfo(h, nil, &hints, &res)
 	syscall.Exitsyscall()
 	if gerrno != 0 {
-		var str string
-		if gerrno == syscall.EAI_NONAME {
-			str = noSuchHost
-		} else if gerrno == syscall.EAI_SYSTEM {
+		switch gerrno {
+		case syscall.EAI_SYSTEM:
 			errno := syscall.GetErrno()
 			if errno == 0 {
 				// err should not be nil, but sometimes getaddrinfo returns
@@ -132,13 +146,16 @@
 				// comes up again. golang.org/issue/6232.
 				errno = syscall.EMFILE
 			}
-			str = errno.Error()
-		} else {
-			str = bytePtrToString(libc_gai_strerror(gerrno))
+			err = errno
+		case syscall.EAI_NONAME:
+			err = errNoSuchHost
+		default:
+			err = addrinfoErrno(gerrno)
 		}
-		return nil, "", &DNSError{Err: str, Name: name}, true
+		return nil, "", &DNSError{Err: err.Error(), Name: name}, true
 	}
 	defer libc_freeaddrinfo(res)
+
 	if res != nil {
 		cname = bytePtrToString((*byte)(unsafe.Pointer(res.Ai_canonname)))
 		if cname == "" {
@@ -154,20 +171,20 @@
 			continue
 		}
 		switch r.Ai_family {
-		default:
-			continue
 		case syscall.AF_INET:
 			sa := (*syscall.RawSockaddrInet4)(unsafe.Pointer(r.Ai_addr))
-			addrs = append(addrs, copyIP(sa.Addr[:]))
+			addr := IPAddr{IP: copyIP(sa.Addr[:])}
+			addrs = append(addrs, addr)
 		case syscall.AF_INET6:
 			sa := (*syscall.RawSockaddrInet6)(unsafe.Pointer(r.Ai_addr))
-			addrs = append(addrs, copyIP(sa.Addr[:]))
+			addr := IPAddr{IP: copyIP(sa.Addr[:]), Zone: zoneToString(int(sa.Scope_id))}
+			addrs = append(addrs, addr)
 		}
 	}
 	return addrs, cname, nil, true
 }
 
-func cgoLookupIP(name string) (addrs []IP, err error, completed bool) {
+func cgoLookupIP(name string) (addrs []IPAddr, err error, completed bool) {
 	addrs, _, err, completed = cgoLookupIPCNAME(name)
 	return
 }
@@ -177,6 +194,77 @@
 	return
 }
 
+// These are roughly enough for the following:
+//
+// Source		Encoding			Maximum length of single name entry
+// Unicast DNS		ASCII or			<=253 + a NUL terminator
+//			Unicode in RFC 5892		252 * total number of labels + delimiters + a NUL terminator
+// Multicast DNS	UTF-8 in RFC 5198 or		<=253 + a NUL terminator
+//			the same as unicast DNS ASCII	<=253 + a NUL terminator
+// Local database	various				depends on implementation
+const (
+	nameinfoLen    = 64
+	maxNameinfoLen = 4096
+)
+
+func cgoLookupPTR(addr string) ([]string, error, bool) {
+	acquireThread()
+	defer releaseThread()
+
+	ip := ParseIP(addr)
+	if ip == nil {
+		return nil, &DNSError{Err: "invalid address", Name: addr}, true
+	}
+	sa, salen := cgoSockaddr(ip)
+	if sa == nil {
+		return nil, &DNSError{Err: "invalid address " + ip.String(), Name: addr}, true
+	}
+	var err error
+	var b []byte
+	var gerrno int
+	for l := nameinfoLen; l <= maxNameinfoLen; l *= 2 {
+		b = make([]byte, l)
+		gerrno, err = cgoNameinfoPTR(b, sa, salen)
+		if gerrno == 0 || gerrno != syscall.EAI_OVERFLOW {
+			break
+		}
+	}
+	if gerrno != 0 {
+		switch gerrno {
+		case syscall.EAI_SYSTEM:
+			if err == nil { // see golang.org/issue/6232
+				err = syscall.EMFILE
+			}
+		default:
+			err = addrinfoErrno(gerrno)
+		}
+		return nil, &DNSError{Err: err.Error(), Name: addr}, true
+	}
+
+	for i := 0; i < len(b); i++ {
+		if b[i] == 0 {
+			b = b[:i]
+			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
+}
+
+func cgoSockaddr(ip IP) (*syscall.RawSockaddr, syscall.Socklen_t) {
+	if ip4 := ip.To4(); ip4 != nil {
+		return cgoSockaddrInet4(ip4), syscall.Socklen_t(syscall.SizeofSockaddrInet4)
+	}
+	if ip6 := ip.To16(); ip6 != nil {
+		return cgoSockaddrInet6(ip6), syscall.Socklen_t(syscall.SizeofSockaddrInet6)
+	}
+	return nil, 0
+}
+
 func copyIP(x IP) IP {
 	if len(x) < 16 {
 		return x.To16()
diff --git a/third_party/gofrontend/libgo/go/net/cgo_unix_test.go b/third_party/gofrontend/libgo/go/net/cgo_unix_test.go
index 33566ce..4d5ab23 100644
--- a/third_party/gofrontend/libgo/go/net/cgo_unix_test.go
+++ b/third_party/gofrontend/libgo/go/net/cgo_unix_test.go
@@ -3,7 +3,7 @@
 // license that can be found in the LICENSE file.
 
 // +build cgo,!netgo
-// +build darwin dragonfly freebsd linux netbsd openbsd
+// +build darwin dragonfly freebsd linux netbsd openbsd solaris
 
 package net
 
@@ -16,9 +16,9 @@
 		t.Errorf("cgoLookupIP must not be a placeholder")
 	}
 	if err != nil {
-		t.Errorf("cgoLookupIP failed: %v", err)
+		t.Error(err)
 	}
 	if _, err := goLookupIP(host); err != nil {
-		t.Errorf("goLookupIP failed: %v", err)
+		t.Error(err)
 	}
 }
diff --git a/third_party/gofrontend/libgo/go/net/cgo_windows.go b/third_party/gofrontend/libgo/go/net/cgo_windows.go
new file mode 100644
index 0000000..8968b75
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/net/cgo_windows.go
@@ -0,0 +1,13 @@
+// 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 cgo,!netgo
+
+package net
+
+type addrinfoErrno int
+
+func (eai addrinfoErrno) Error() string   { return "<nil>" }
+func (eai addrinfoErrno) Temporary() bool { return false }
+func (eai addrinfoErrno) Timeout() bool   { return false }
diff --git a/third_party/gofrontend/libgo/go/net/conf.go b/third_party/gofrontend/libgo/go/net/conf.go
new file mode 100644
index 0000000..c92e579
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/net/conf.go
@@ -0,0 +1,308 @@
+// 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 darwin dragonfly freebsd linux netbsd openbsd solaris
+
+package net
+
+import (
+	"os"
+	"runtime"
+	"strconv"
+	"sync"
+	"syscall"
+)
+
+// conf represents a system's network configuration.
+type conf struct {
+	// forceCgoLookupHost forces CGO to always be used, if available.
+	forceCgoLookupHost bool
+
+	netGo  bool // go DNS resolution forced
+	netCgo bool // cgo DNS resolution forced
+
+	// machine has an /etc/mdns.allow file
+	hasMDNSAllow bool
+
+	goos          string // the runtime.GOOS, to ease testing
+	dnsDebugLevel int
+
+	nss    *nssConf
+	resolv *dnsConfig
+}
+
+var (
+	confOnce sync.Once // guards init of confVal via initConfVal
+	confVal  = &conf{goos: runtime.GOOS}
+)
+
+// systemConf returns the machine's network configuration.
+func systemConf() *conf {
+	confOnce.Do(initConfVal)
+	return confVal
+}
+
+func initConfVal() {
+	dnsMode, debugLevel := goDebugNetDNS()
+	confVal.dnsDebugLevel = debugLevel
+	confVal.netGo = netGo || dnsMode == "go"
+	confVal.netCgo = netCgo || dnsMode == "cgo"
+
+	if confVal.dnsDebugLevel > 0 {
+		defer func() {
+			switch {
+			case confVal.netGo:
+				if netGo {
+					println("go package net: built with netgo build tag; using Go's DNS resolver")
+				} else {
+					println("go package net: GODEBUG setting forcing use of Go's resolver")
+				}
+			case confVal.forceCgoLookupHost:
+				println("go package net: using cgo DNS resolver")
+			default:
+				println("go package net: dynamic selection of DNS resolver")
+			}
+		}()
+	}
+
+	// Darwin pops up annoying dialog boxes if programs try to do
+	// their own DNS requests. So always use cgo instead, which
+	// avoids that.
+	if runtime.GOOS == "darwin" {
+		confVal.forceCgoLookupHost = true
+		return
+	}
+
+	// If any environment-specified resolver options are specified,
+	// force cgo. Note that LOCALDOMAIN can change behavior merely
+	// by being specified with the empty string.
+	_, localDomainDefined := syscall.Getenv("LOCALDOMAIN")
+	if os.Getenv("RES_OPTIONS") != "" ||
+		os.Getenv("HOSTALIASES") != "" ||
+		confVal.netCgo ||
+		localDomainDefined {
+		confVal.forceCgoLookupHost = true
+		return
+	}
+
+	// OpenBSD apparently lets you override the location of resolv.conf
+	// with ASR_CONFIG. If we notice that, defer to libc.
+	if runtime.GOOS == "openbsd" && os.Getenv("ASR_CONFIG") != "" {
+		confVal.forceCgoLookupHost = true
+		return
+	}
+
+	if runtime.GOOS != "openbsd" {
+		confVal.nss = parseNSSConfFile("/etc/nsswitch.conf")
+	}
+
+	confVal.resolv = dnsReadConfig("/etc/resolv.conf")
+	if confVal.resolv.err != nil && !os.IsNotExist(confVal.resolv.err) &&
+		!os.IsPermission(confVal.resolv.err) {
+		// If we can't read the resolv.conf file, assume it
+		// had something important in it and defer to cgo.
+		// libc's resolver might then fail too, but at least
+		// it wasn't our fault.
+		confVal.forceCgoLookupHost = true
+	}
+
+	if _, err := os.Stat("/etc/mdns.allow"); err == nil {
+		confVal.hasMDNSAllow = true
+	}
+}
+
+// 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 {
+		defer func() {
+			print("go package net: hostLookupOrder(", hostname, ") = ", ret.String(), "\n")
+		}()
+	}
+	if c.netGo {
+		return hostLookupFilesDNS
+	}
+	if c.forceCgoLookupHost || c.resolv.unknownOpt || c.goos == "android" {
+		return hostLookupCgo
+	}
+	if byteIndex(hostname, '\\') != -1 || byteIndex(hostname, '%') != -1 {
+		// Don't deal with special form hostnames with backslashes
+		// or '%'.
+		return hostLookupCgo
+	}
+
+	// OpenBSD is unique and doesn't use nsswitch.conf.
+	// It also doesn't support mDNS.
+	if c.goos == "openbsd" {
+		// OpenBSD's resolv.conf manpage says that a non-existent
+		// resolv.conf means "lookup" defaults to only "files",
+		// without DNS lookups.
+		if os.IsNotExist(c.resolv.err) {
+			return hostLookupFiles
+		}
+		lookup := c.resolv.lookup
+		if len(lookup) == 0 {
+			// http://www.openbsd.org/cgi-bin/man.cgi/OpenBSD-current/man5/resolv.conf.5
+			// "If the lookup keyword is not used in the
+			// system's resolv.conf file then the assumed
+			// order is 'bind file'"
+			return hostLookupDNSFiles
+		}
+		if len(lookup) < 1 || len(lookup) > 2 {
+			return hostLookupCgo
+		}
+		switch lookup[0] {
+		case "bind":
+			if len(lookup) == 2 {
+				if lookup[1] == "file" {
+					return hostLookupDNSFiles
+				}
+				return hostLookupCgo
+			}
+			return hostLookupDNS
+		case "file":
+			if len(lookup) == 2 {
+				if lookup[1] == "bind" {
+					return hostLookupFilesDNS
+				}
+				return hostLookupCgo
+			}
+			return hostLookupFiles
+		default:
+			return hostLookupCgo
+		}
+	}
+
+	hasDot := byteIndex(hostname, '.') != -1
+
+	// Canonicalize the hostname by removing any trailing dot.
+	if stringsHasSuffix(hostname, ".") {
+		hostname = hostname[:len(hostname)-1]
+	}
+	if stringsHasSuffixFold(hostname, ".local") {
+		// Per RFC 6762, the ".local" TLD is special.  And
+		// because Go's native resolver doesn't do mDNS or
+		// similar local resolution mechanisms, assume that
+		// libc might (via Avahi, etc) and use cgo.
+		return hostLookupCgo
+	}
+
+	nss := c.nss
+	srcs := nss.sources["hosts"]
+	// If /etc/nsswitch.conf doesn't exist or doesn't specify any
+	// sources for "hosts", assume Go's DNS will work fine.
+	if os.IsNotExist(nss.err) || (nss.err == nil && len(srcs) == 0) {
+		if c.goos == "solaris" {
+			// illumos defaults to "nis [NOTFOUND=return] files"
+			return hostLookupCgo
+		}
+		if c.goos == "linux" {
+			// glibc says the default is "dns [!UNAVAIL=return] files"
+			// http://www.gnu.org/software/libc/manual/html_node/Notes-on-NSS-Configuration-File.html.
+			return hostLookupDNSFiles
+		}
+		return hostLookupFilesDNS
+	}
+	if nss.err != nil {
+		// We failed to parse or open nsswitch.conf, so
+		// conservatively assume we should use cgo if it's
+		// available.
+		return hostLookupCgo
+	}
+
+	var mdnsSource, filesSource, dnsSource bool
+	var first string
+	for _, src := range srcs {
+		if src.source == "myhostname" {
+			if hasDot {
+				continue
+			}
+			return hostLookupCgo
+		}
+		if src.source == "files" || src.source == "dns" {
+			if !src.standardCriteria() {
+				return hostLookupCgo // non-standard; let libc deal with it.
+			}
+			if src.source == "files" {
+				filesSource = true
+			} else if src.source == "dns" {
+				dnsSource = true
+			}
+			if first == "" {
+				first = src.source
+			}
+			continue
+		}
+		if stringsHasPrefix(src.source, "mdns") {
+			// e.g. "mdns4", "mdns4_minimal"
+			// We already returned true before if it was *.local.
+			// libc wouldn't have found a hit on this anyway.
+			mdnsSource = true
+			continue
+		}
+		// Some source we don't know how to deal with.
+		return hostLookupCgo
+	}
+
+	// We don't parse mdns.allow files. They're rare. If one
+	// exists, it might list other TLDs (besides .local) or even
+	// '*', so just let libc deal with it.
+	if mdnsSource && c.hasMDNSAllow {
+		return hostLookupCgo
+	}
+
+	// Cases where Go can handle it without cgo and C thread
+	// overhead.
+	switch {
+	case filesSource && dnsSource:
+		if first == "files" {
+			return hostLookupFilesDNS
+		} else {
+			return hostLookupDNSFiles
+		}
+	case filesSource:
+		return hostLookupFiles
+	case dnsSource:
+		return hostLookupDNS
+	}
+
+	// Something weird. Let libc deal with it.
+	return hostLookupCgo
+}
+
+// goDebugNetDNS parses the value of the GODEBUG "netdns" value.
+// The netdns value can be of the form:
+//    1       // debug level 1
+//    2       // debug level 2
+//    cgo     // use cgo for DNS lookups
+//    go      // use go for DNS lookups
+//    cgo+1   // use cgo for DNS lookups + debug level 1
+//    1+cgo   // same
+//    cgo+2   // same, but debug level 2
+// etc.
+func goDebugNetDNS() (dnsMode string, debugLevel int) {
+	goDebug := goDebugString("netdns")
+	parsePart := func(s string) {
+		if s == "" {
+			return
+		}
+		if '0' <= s[0] && s[0] <= '9' {
+			debugLevel, _ = strconv.Atoi(s)
+		} else {
+			dnsMode = s
+		}
+	}
+	if i := byteIndex(goDebug, '+'); i != -1 {
+		parsePart(goDebug[:i])
+		parsePart(goDebug[i+1:])
+		return
+	}
+	parsePart(goDebug)
+	return
+}
diff --git a/third_party/gofrontend/libgo/go/net/conf_netcgo.go b/third_party/gofrontend/libgo/go/net/conf_netcgo.go
new file mode 100644
index 0000000..b66bae3
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/net/conf_netcgo.go
@@ -0,0 +1,17 @@
+// 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 netcgo
+
+package net
+
+/*
+
+// Fail if cgo isn't available.
+
+*/
+
+// The build tag "netcgo" forces use of the cgo DNS resolver.
+// It is the opposite of "netgo".
+func init() { netCgo = true }
diff --git a/third_party/gofrontend/libgo/go/net/conf_test.go b/third_party/gofrontend/libgo/go/net/conf_test.go
new file mode 100644
index 0000000..86904bf
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/net/conf_test.go
@@ -0,0 +1,301 @@
+// 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 darwin dragonfly freebsd linux netbsd openbsd solaris
+
+package net
+
+import (
+	"os"
+	"strings"
+	"testing"
+)
+
+type nssHostTest struct {
+	host string
+	want hostLookupOrder
+}
+
+func nssStr(s string) *nssConf { return parseNSSConf(strings.NewReader(s)) }
+
+// represents a dnsConfig returned by parsing a nonexistent resolv.conf
+var defaultResolvConf = &dnsConfig{
+	servers:  defaultNS,
+	ndots:    1,
+	timeout:  5,
+	attempts: 2,
+	err:      os.ErrNotExist,
+}
+
+func TestConfHostLookupOrder(t *testing.T) {
+	tests := []struct {
+		name      string
+		c         *conf
+		goos      string
+		hostTests []nssHostTest
+	}{
+		{
+			name: "force",
+			c: &conf{
+				forceCgoLookupHost: true,
+				nss:                nssStr("foo: bar"),
+				resolv:             defaultResolvConf,
+			},
+			hostTests: []nssHostTest{
+				{"foo.local", hostLookupCgo},
+				{"google.com", hostLookupCgo},
+			},
+		},
+		{
+			name: "ubuntu_trusty_avahi",
+			c: &conf{
+				nss:    nssStr("hosts: files mdns4_minimal [NOTFOUND=return] dns mdns4"),
+				resolv: defaultResolvConf,
+			},
+			hostTests: []nssHostTest{
+				{"foo.local", hostLookupCgo},
+				{"foo.local.", hostLookupCgo},
+				{"foo.LOCAL", hostLookupCgo},
+				{"foo.LOCAL.", hostLookupCgo},
+				{"google.com", hostLookupFilesDNS},
+			},
+		},
+		{
+			name: "freebsdlinux_no_resolv_conf",
+			c: &conf{
+				goos:   "freebsd",
+				nss:    nssStr("foo: bar"),
+				resolv: defaultResolvConf,
+			},
+			hostTests: []nssHostTest{{"google.com", hostLookupFilesDNS}},
+		},
+		// On OpenBSD, no resolv.conf means no DNS.
+		{
+			name: "openbsd_no_resolv_conf",
+			c: &conf{
+				goos:   "openbsd",
+				resolv: defaultResolvConf,
+			},
+			hostTests: []nssHostTest{{"google.com", hostLookupFiles}},
+		},
+		{
+			name: "solaris_no_nsswitch",
+			c: &conf{
+				goos:   "solaris",
+				nss:    &nssConf{err: os.ErrNotExist},
+				resolv: defaultResolvConf,
+			},
+			hostTests: []nssHostTest{{"google.com", hostLookupCgo}},
+		},
+		{
+			name: "openbsd_lookup_bind_file",
+			c: &conf{
+				goos:   "openbsd",
+				resolv: &dnsConfig{lookup: []string{"bind", "file"}},
+			},
+			hostTests: []nssHostTest{
+				{"google.com", hostLookupDNSFiles},
+				{"foo.local", hostLookupDNSFiles},
+			},
+		},
+		{
+			name: "openbsd_lookup_file_bind",
+			c: &conf{
+				goos:   "openbsd",
+				resolv: &dnsConfig{lookup: []string{"file", "bind"}},
+			},
+			hostTests: []nssHostTest{{"google.com", hostLookupFilesDNS}},
+		},
+		{
+			name: "openbsd_lookup_bind",
+			c: &conf{
+				goos:   "openbsd",
+				resolv: &dnsConfig{lookup: []string{"bind"}},
+			},
+			hostTests: []nssHostTest{{"google.com", hostLookupDNS}},
+		},
+		{
+			name: "openbsd_lookup_file",
+			c: &conf{
+				goos:   "openbsd",
+				resolv: &dnsConfig{lookup: []string{"file"}},
+			},
+			hostTests: []nssHostTest{{"google.com", hostLookupFiles}},
+		},
+		{
+			name: "openbsd_lookup_yp",
+			c: &conf{
+				goos:   "openbsd",
+				resolv: &dnsConfig{lookup: []string{"file", "bind", "yp"}},
+			},
+			hostTests: []nssHostTest{{"google.com", hostLookupCgo}},
+		},
+		{
+			name: "openbsd_lookup_two",
+			c: &conf{
+				goos:   "openbsd",
+				resolv: &dnsConfig{lookup: []string{"file", "foo"}},
+			},
+			hostTests: []nssHostTest{{"google.com", hostLookupCgo}},
+		},
+		{
+			name: "openbsd_lookup_empty",
+			c: &conf{
+				goos:   "openbsd",
+				resolv: &dnsConfig{lookup: nil},
+			},
+			hostTests: []nssHostTest{{"google.com", hostLookupDNSFiles}},
+		},
+		// glibc lacking an nsswitch.conf, per
+		// http://www.gnu.org/software/libc/manual/html_node/Notes-on-NSS-Configuration-File.html
+		{
+			name: "linux_no_nsswitch.conf",
+			c: &conf{
+				goos:   "linux",
+				nss:    &nssConf{err: os.ErrNotExist},
+				resolv: defaultResolvConf,
+			},
+			hostTests: []nssHostTest{{"google.com", hostLookupDNSFiles}},
+		},
+		{
+			name: "files_mdns_dns",
+			c: &conf{
+				nss:    nssStr("hosts: files mdns dns"),
+				resolv: defaultResolvConf,
+			},
+			hostTests: []nssHostTest{
+				{"x.com", hostLookupFilesDNS},
+				{"x.local", hostLookupCgo},
+			},
+		},
+		{
+			name: "dns_special_hostnames",
+			c: &conf{
+				nss:    nssStr("hosts: dns"),
+				resolv: defaultResolvConf,
+			},
+			hostTests: []nssHostTest{
+				{"x.com", hostLookupDNS},
+				{"x\\.com", hostLookupCgo},     // punt on weird glibc escape
+				{"foo.com%en0", hostLookupCgo}, // and IPv6 zones
+			},
+		},
+		{
+			name: "mdns_allow",
+			c: &conf{
+				nss:          nssStr("hosts: files mdns dns"),
+				resolv:       defaultResolvConf,
+				hasMDNSAllow: true,
+			},
+			hostTests: []nssHostTest{
+				{"x.com", hostLookupCgo},
+				{"x.local", hostLookupCgo},
+			},
+		},
+		{
+			name: "files_dns",
+			c: &conf{
+				nss:    nssStr("hosts: files dns"),
+				resolv: defaultResolvConf,
+			},
+			hostTests: []nssHostTest{
+				{"x.com", hostLookupFilesDNS},
+				{"x", hostLookupFilesDNS},
+				{"x.local", hostLookupCgo},
+			},
+		},
+		{
+			name: "dns_files",
+			c: &conf{
+				nss:    nssStr("hosts: dns files"),
+				resolv: defaultResolvConf,
+			},
+			hostTests: []nssHostTest{
+				{"x.com", hostLookupDNSFiles},
+				{"x", hostLookupDNSFiles},
+				{"x.local", hostLookupCgo},
+			},
+		},
+		{
+			name: "something_custom",
+			c: &conf{
+				nss:    nssStr("hosts: dns files something_custom"),
+				resolv: defaultResolvConf,
+			},
+			hostTests: []nssHostTest{
+				{"x.com", hostLookupCgo},
+			},
+		},
+		{
+			name: "myhostname",
+			c: &conf{
+				nss:    nssStr("hosts: files dns myhostname"),
+				resolv: defaultResolvConf,
+			},
+			hostTests: []nssHostTest{
+				{"x.com", hostLookupFilesDNS},
+				{"somehostname", hostLookupCgo},
+			},
+		},
+		{
+			name: "ubuntu14.04.02",
+			c: &conf{
+				nss:    nssStr("hosts: files myhostname mdns4_minimal [NOTFOUND=return] dns mdns4"),
+				resolv: defaultResolvConf,
+			},
+			hostTests: []nssHostTest{
+				{"x.com", hostLookupFilesDNS},
+				{"somehostname", hostLookupCgo},
+			},
+		},
+		// Debian Squeeze is just "dns,files", but lists all
+		// the default criteria for dns, but then has a
+		// non-standard but redundant notfound=return for the
+		// files.
+		{
+			name: "debian_squeeze",
+			c: &conf{
+				nss:    nssStr("hosts: dns [success=return notfound=continue unavail=continue tryagain=continue] files [notfound=return]"),
+				resolv: defaultResolvConf,
+			},
+			hostTests: []nssHostTest{
+				{"x.com", hostLookupDNSFiles},
+				{"somehostname", hostLookupDNSFiles},
+			},
+		},
+		{
+			name: "resolv.conf-unknown",
+			c: &conf{
+				nss:    nssStr("foo: bar"),
+				resolv: &dnsConfig{servers: defaultNS, ndots: 1, timeout: 5, attempts: 2, unknownOpt: true},
+			},
+			hostTests: []nssHostTest{{"google.com", hostLookupCgo}},
+		},
+		// Android should always use cgo.
+		{
+			name: "android",
+			c: &conf{
+				goos:   "android",
+				nss:    nssStr(""),
+				resolv: defaultResolvConf,
+			},
+			hostTests: []nssHostTest{
+				{"x.com", hostLookupCgo},
+			},
+		},
+	}
+	for _, tt := range tests {
+		for _, ht := range tt.hostTests {
+			gotOrder := tt.c.hostLookupOrder(ht.host)
+			if gotOrder != ht.want {
+				t.Errorf("%s: hostLookupOrder(%q) = %v; want %v", tt.name, ht.host, gotOrder, ht.want)
+			}
+		}
+	}
+
+}
+
+func TestSystemConf(t *testing.T) {
+	systemConf()
+}
diff --git a/third_party/gofrontend/libgo/go/net/conn_test.go b/third_party/gofrontend/libgo/go/net/conn_test.go
index 9c9d1a8..6995c11 100644
--- a/third_party/gofrontend/libgo/go/net/conn_test.go
+++ b/third_party/gofrontend/libgo/go/net/conn_test.go
@@ -8,117 +8,58 @@
 package net
 
 import (
-	"os"
-	"runtime"
 	"testing"
 	"time"
 )
 
-var connTests = []struct {
-	net  string
-	addr string
-}{
-	{"tcp", "127.0.0.1:0"},
-	{"unix", testUnixAddr()},
-	{"unixpacket", testUnixAddr()},
-}
-
 // someTimeout is used just to test that net.Conn implementations
 // don't explode when their SetFooDeadline methods are called.
 // It isn't actually used for testing timeouts.
 const someTimeout = 10 * time.Second
 
 func TestConnAndListener(t *testing.T) {
-	for _, tt := range connTests {
-		switch tt.net {
-		case "unix":
-			switch runtime.GOOS {
-			case "nacl", "plan9", "windows":
-				continue
-			}
-		case "unixpacket":
-			switch runtime.GOOS {
-			case "android", "darwin", "nacl", "openbsd", "plan9", "windows":
-				continue
-			case "freebsd": // FreeBSD 8 doesn't support unixpacket
-				continue
-			}
+	for i, network := range []string{"tcp", "unix", "unixpacket"} {
+		if !testableNetwork(network) {
+			t.Logf("skipping %s test", network)
+			continue
 		}
 
-		ln, err := Listen(tt.net, tt.addr)
+		ls, err := newLocalServer(network)
 		if err != nil {
-			t.Fatalf("Listen failed: %v", err)
+			t.Fatal(err)
 		}
-		defer func(ln Listener, net, addr string) {
-			ln.Close()
-			switch net {
-			case "unix", "unixpacket":
-				os.Remove(addr)
-			}
-		}(ln, tt.net, tt.addr)
-		if ln.Addr().Network() != tt.net {
-			t.Fatalf("got %v; expected %v", ln.Addr().Network(), tt.net)
+		defer ls.teardown()
+		ch := make(chan error, 1)
+		handler := func(ls *localServer, ln Listener) { transponder(ln, ch) }
+		if err := ls.buildup(handler); err != nil {
+			t.Fatal(err)
+		}
+		if ls.Listener.Addr().Network() != network {
+			t.Fatalf("got %s; want %s", ls.Listener.Addr().Network(), network)
 		}
 
-		done := make(chan int)
-		go transponder(t, ln, done)
-
-		c, err := Dial(tt.net, ln.Addr().String())
+		c, err := Dial(ls.Listener.Addr().Network(), ls.Listener.Addr().String())
 		if err != nil {
-			t.Fatalf("Dial failed: %v", err)
+			t.Fatal(err)
 		}
 		defer c.Close()
-		if c.LocalAddr().Network() != tt.net || c.LocalAddr().Network() != tt.net {
-			t.Fatalf("got %v->%v; expected %v->%v", c.LocalAddr().Network(), c.RemoteAddr().Network(), tt.net, tt.net)
+		if c.LocalAddr().Network() != network || c.LocalAddr().Network() != network {
+			t.Fatalf("got %s->%s; want %s->%s", c.LocalAddr().Network(), c.RemoteAddr().Network(), network, network)
 		}
 		c.SetDeadline(time.Now().Add(someTimeout))
 		c.SetReadDeadline(time.Now().Add(someTimeout))
 		c.SetWriteDeadline(time.Now().Add(someTimeout))
 
-		if _, err := c.Write([]byte("CONN TEST")); err != nil {
-			t.Fatalf("Conn.Write failed: %v", err)
+		if _, err := c.Write([]byte("CONN AND LISTENER TEST")); err != nil {
+			t.Fatal(err)
 		}
 		rb := make([]byte, 128)
 		if _, err := c.Read(rb); err != nil {
-			t.Fatalf("Conn.Read failed: %v", err)
+			t.Fatal(err)
 		}
 
-		<-done
-	}
-}
-
-func transponder(t *testing.T, ln Listener, done chan<- int) {
-	defer func() { done <- 1 }()
-
-	switch ln := ln.(type) {
-	case *TCPListener:
-		ln.SetDeadline(time.Now().Add(someTimeout))
-	case *UnixListener:
-		ln.SetDeadline(time.Now().Add(someTimeout))
-	}
-	c, err := ln.Accept()
-	if err != nil {
-		t.Errorf("Listener.Accept failed: %v", err)
-		return
-	}
-	defer c.Close()
-	network := ln.Addr().Network()
-	if c.LocalAddr().Network() != network || c.LocalAddr().Network() != network {
-		t.Errorf("got %v->%v; expected %v->%v", c.LocalAddr().Network(), c.RemoteAddr().Network(), network, network)
-		return
-	}
-	c.SetDeadline(time.Now().Add(someTimeout))
-	c.SetReadDeadline(time.Now().Add(someTimeout))
-	c.SetWriteDeadline(time.Now().Add(someTimeout))
-
-	b := make([]byte, 128)
-	n, err := c.Read(b)
-	if err != nil {
-		t.Errorf("Conn.Read failed: %v", err)
-		return
-	}
-	if _, err := c.Write(b[:n]); err != nil {
-		t.Errorf("Conn.Write failed: %v", err)
-		return
+		for err := range ch {
+			t.Errorf("#%d: %v", i, err)
+		}
 	}
 }
diff --git a/third_party/gofrontend/libgo/go/net/dial.go b/third_party/gofrontend/libgo/go/net/dial.go
index e6f0436..cb4ec21 100644
--- a/third_party/gofrontend/libgo/go/net/dial.go
+++ b/third_party/gofrontend/libgo/go/net/dial.go
@@ -21,6 +21,9 @@
 	//
 	// The default is no timeout.
 	//
+	// When dialing a name with multiple IP addresses, the timeout
+	// may be divided between them.
+	//
 	// With or without a timeout, the operating system may impose
 	// its own earlier timeout. For instance, TCP timeouts are
 	// often around 3 minutes.
@@ -38,13 +41,17 @@
 	// If nil, a local address is automatically chosen.
 	LocalAddr Addr
 
-	// DualStack allows a single dial to attempt to establish
-	// multiple IPv4 and IPv6 connections and to return the first
-	// established connection when the network is "tcp" and the
-	// destination is a host name that has multiple address family
-	// DNS records.
+	// DualStack enables RFC 6555-compliant "Happy Eyeballs" dialing
+	// when the network is "tcp" and the destination is a host name
+	// with both IPv4 and IPv6 addresses. This allows a client to
+	// tolerate networks where one address family is silently broken.
 	DualStack bool
 
+	// FallbackDelay specifies the length of time to wait before
+	// spawning a fallback connection, when DualStack is enabled.
+	// If zero, a default delay of 300ms is used.
+	FallbackDelay time.Duration
+
 	// KeepAlive specifies the keep-alive period for an active
 	// network connection.
 	// If zero, keep-alives are not enabled. Network protocols
@@ -54,11 +61,11 @@
 
 // Return either now+Timeout or Deadline, whichever comes first.
 // Or zero, if neither is set.
-func (d *Dialer) deadline() time.Time {
+func (d *Dialer) deadline(now time.Time) time.Time {
 	if d.Timeout == 0 {
 		return d.Deadline
 	}
-	timeoutDeadline := time.Now().Add(d.Timeout)
+	timeoutDeadline := now.Add(d.Timeout)
 	if d.Deadline.IsZero() || timeoutDeadline.Before(d.Deadline) {
 		return timeoutDeadline
 	} else {
@@ -66,6 +73,38 @@
 	}
 }
 
+// partialDeadline returns the deadline to use for a single address,
+// when multiple addresses are pending.
+func partialDeadline(now, deadline time.Time, addrsRemaining int) (time.Time, error) {
+	if deadline.IsZero() {
+		return deadline, nil
+	}
+	timeRemaining := deadline.Sub(now)
+	if timeRemaining <= 0 {
+		return time.Time{}, errTimeout
+	}
+	// Tentatively allocate equal time to each remaining address.
+	timeout := timeRemaining / time.Duration(addrsRemaining)
+	// If the time per address is too short, steal from the end of the list.
+	const saneMinimum = 2 * time.Second
+	if timeout < saneMinimum {
+		if timeRemaining < saneMinimum {
+			timeout = timeRemaining
+		} else {
+			timeout = saneMinimum
+		}
+	}
+	return now.Add(timeout), nil
+}
+
+func (d *Dialer) fallbackDelay() time.Duration {
+	if d.FallbackDelay > 0 {
+		return d.FallbackDelay
+	} else {
+		return 300 * time.Millisecond
+	}
+}
+
 func parseNetwork(net string) (afnet string, proto int, err error) {
 	i := last(net, ':')
 	if i < 0 { // no colon
@@ -95,7 +134,7 @@
 	return "", 0, UnknownNetworkError(net)
 }
 
-func resolveAddr(op, net, addr string, deadline time.Time) (netaddr, error) {
+func resolveAddrList(op, net, addr string, deadline time.Time) (addrList, error) {
 	afnet, _, err := parseNetwork(net)
 	if err != nil {
 		return nil, err
@@ -105,9 +144,13 @@
 	}
 	switch afnet {
 	case "unix", "unixgram", "unixpacket":
-		return ResolveUnixAddr(afnet, addr)
+		addr, err := ResolveUnixAddr(afnet, addr)
+		if err != nil {
+			return nil, err
+		}
+		return addrList{addr}, nil
 	}
-	return resolveInternetAddr(afnet, addr, deadline)
+	return internetAddrList(afnet, addr, deadline)
 }
 
 // Dial connects to the address on the named network.
@@ -150,100 +193,186 @@
 	return d.Dial(network, address)
 }
 
+// dialContext holds common state for all dial operations.
+type dialContext struct {
+	Dialer
+	network, address string
+	finalDeadline    time.Time
+}
+
 // Dial connects to the address on the named network.
 //
 // See func Dial for a description of the network and address
 // parameters.
 func (d *Dialer) Dial(network, address string) (Conn, error) {
-	ra, err := resolveAddr("dial", network, address, d.deadline())
+	finalDeadline := d.deadline(time.Now())
+	addrs, err := resolveAddrList("dial", network, address, finalDeadline)
 	if err != nil {
-		return nil, &OpError{Op: "dial", Net: network, Addr: nil, Err: err}
+		return nil, &OpError{Op: "dial", Net: network, Source: nil, Addr: nil, Err: err}
 	}
-	dialer := func(deadline time.Time) (Conn, error) {
-		return dialSingle(network, address, d.LocalAddr, ra.toAddr(), deadline)
+
+	ctx := &dialContext{
+		Dialer:        *d,
+		network:       network,
+		address:       address,
+		finalDeadline: finalDeadline,
 	}
-	if ras, ok := ra.(addrList); ok && d.DualStack && network == "tcp" {
-		dialer = func(deadline time.Time) (Conn, error) {
-			return dialMulti(network, address, d.LocalAddr, ras, deadline)
-		}
+
+	var primaries, fallbacks addrList
+	if d.DualStack && network == "tcp" {
+		primaries, fallbacks = addrs.partition(isIPv4)
+	} else {
+		primaries = addrs
 	}
-	c, err := dial(network, ra.toAddr(), dialer, d.deadline())
+
+	var c Conn
+	if len(fallbacks) == 0 {
+		// dialParallel can accept an empty fallbacks list,
+		// but this shortcut avoids the goroutine/channel overhead.
+		c, err = dialSerial(ctx, primaries, nil)
+	} else {
+		c, err = dialParallel(ctx, primaries, fallbacks)
+	}
+
 	if d.KeepAlive > 0 && err == nil {
 		if tc, ok := c.(*TCPConn); ok {
-			tc.SetKeepAlive(true)
-			tc.SetKeepAlivePeriod(d.KeepAlive)
+			setKeepAlive(tc.fd, true)
+			setKeepAlivePeriod(tc.fd, d.KeepAlive)
 			testHookSetKeepAlive()
 		}
 	}
 	return c, err
 }
 
-var testHookSetKeepAlive = func() {} // changed by dial_test.go
+// dialParallel races two copies of dialSerial, giving the first a
+// head start. It returns the first established connection and
+// closes the others. Otherwise it returns an error from the first
+// primary address.
+func dialParallel(ctx *dialContext, primaries, fallbacks addrList) (Conn, error) {
+	results := make(chan dialResult) // unbuffered, so dialSerialAsync can detect race loss & cleanup
+	cancel := make(chan struct{})
+	defer close(cancel)
 
-// dialMulti attempts to establish connections to each destination of
-// the list of addresses. It will return the first established
-// connection and close the other connections. Otherwise it returns
-// error on the last attempt.
-func dialMulti(net, addr string, la Addr, ras addrList, deadline time.Time) (Conn, error) {
-	type racer struct {
-		Conn
-		error
-	}
-	// Sig controls the flow of dial results on lane. It passes a
-	// token to the next racer and also indicates the end of flow
-	// by using closed channel.
-	sig := make(chan bool, 1)
-	lane := make(chan racer, 1)
-	for _, ra := range ras {
-		go func(ra Addr) {
-			c, err := dialSingle(net, addr, la, ra, deadline)
-			if _, ok := <-sig; ok {
-				lane <- racer{c, err}
-			} else if err == nil {
-				// We have to return the resources
-				// that belong to the other
-				// connections here for avoiding
-				// unnecessary resource starvation.
-				c.Close()
-			}
-		}(ra.toAddr())
-	}
-	defer close(sig)
-	lastErr := errTimeout
-	nracers := len(ras)
-	for nracers > 0 {
-		sig <- true
-		racer := <-lane
-		if racer.error == nil {
-			return racer.Conn, nil
+	// Spawn the primary racer.
+	go dialSerialAsync(ctx, primaries, nil, cancel, results)
+
+	// Spawn the fallback racer.
+	fallbackTimer := time.NewTimer(ctx.fallbackDelay())
+	go dialSerialAsync(ctx, fallbacks, fallbackTimer, cancel, results)
+
+	var primaryErr error
+	for nracers := 2; nracers > 0; nracers-- {
+		res := <-results
+		// If we're still waiting for a connection, then hasten the delay.
+		// Otherwise, disable the Timer and let cancel take over.
+		if fallbackTimer.Stop() && res.error != nil {
+			fallbackTimer.Reset(0)
 		}
-		lastErr = racer.error
-		nracers--
+		if res.error == nil {
+			return res.Conn, nil
+		}
+		if res.primary {
+			primaryErr = res.error
+		}
 	}
-	return nil, lastErr
+	return nil, primaryErr
+}
+
+type dialResult struct {
+	Conn
+	error
+	primary bool
+}
+
+// dialSerialAsync runs dialSerial after some delay, and returns the
+// resulting connection through a channel. When racing two connections,
+// the primary goroutine uses a nil timer to omit the delay.
+func dialSerialAsync(ctx *dialContext, ras addrList, timer *time.Timer, cancel <-chan struct{}, results chan<- dialResult) {
+	if timer != nil {
+		// We're in the fallback goroutine; sleep before connecting.
+		select {
+		case <-timer.C:
+		case <-cancel:
+			return
+		}
+	}
+	c, err := dialSerial(ctx, ras, cancel)
+	select {
+	case results <- dialResult{c, err, timer == nil}:
+		// We won the race.
+	case <-cancel:
+		// The other goroutine won the race.
+		if c != nil {
+			c.Close()
+		}
+	}
+}
+
+// dialSerial connects to a list of addresses in sequence, returning
+// either the first successful connection, or the first error.
+func dialSerial(ctx *dialContext, ras addrList, cancel <-chan struct{}) (Conn, error) {
+	var firstErr error // The error from the first address is most relevant.
+
+	for i, ra := range ras {
+		select {
+		case <-cancel:
+			return nil, &OpError{Op: "dial", Net: ctx.network, Source: ctx.LocalAddr, Addr: ra, Err: errCanceled}
+		default:
+		}
+
+		partialDeadline, err := partialDeadline(time.Now(), ctx.finalDeadline, len(ras)-i)
+		if err != nil {
+			// Ran out of time.
+			if firstErr == nil {
+				firstErr = &OpError{Op: "dial", Net: ctx.network, Source: ctx.LocalAddr, Addr: ra, Err: err}
+			}
+			break
+		}
+
+		// dialTCP does not support cancelation (see golang.org/issue/11225),
+		// so if cancel fires, we'll continue trying to connect until the next
+		// timeout, or return a spurious connection for the caller to close.
+		dialer := func(d time.Time) (Conn, error) {
+			return dialSingle(ctx, ra, d)
+		}
+		c, err := dial(ctx.network, ra, dialer, partialDeadline)
+		if err == nil {
+			return c, nil
+		}
+		if firstErr == nil {
+			firstErr = err
+		}
+	}
+
+	if firstErr == nil {
+		firstErr = &OpError{Op: "dial", Net: ctx.network, Source: nil, Addr: nil, Err: errMissingAddress}
+	}
+	return nil, firstErr
 }
 
 // dialSingle attempts to establish and returns a single connection to
-// the destination address.
-func dialSingle(net, addr string, la, ra Addr, deadline time.Time) (c Conn, err error) {
+// the destination address. This must be called through the OS-specific
+// dial function, because some OSes don't implement the deadline feature.
+func dialSingle(ctx *dialContext, ra Addr, deadline time.Time) (c Conn, err error) {
+	la := ctx.LocalAddr
 	if la != nil && la.Network() != ra.Network() {
-		return nil, &OpError{Op: "dial", Net: net, Addr: ra, Err: errors.New("mismatched local address type " + la.Network())}
+		return nil, &OpError{Op: "dial", Net: ctx.network, Source: la, Addr: ra, Err: errors.New("mismatched local address type " + la.Network())}
 	}
 	switch ra := ra.(type) {
 	case *TCPAddr:
 		la, _ := la.(*TCPAddr)
-		c, err = dialTCP(net, la, ra, deadline)
+		c, err = testHookDialTCP(ctx.network, la, ra, deadline)
 	case *UDPAddr:
 		la, _ := la.(*UDPAddr)
-		c, err = dialUDP(net, la, ra, deadline)
+		c, err = dialUDP(ctx.network, la, ra, deadline)
 	case *IPAddr:
 		la, _ := la.(*IPAddr)
-		c, err = dialIP(net, la, ra, deadline)
+		c, err = dialIP(ctx.network, la, ra, deadline)
 	case *UnixAddr:
 		la, _ := la.(*UnixAddr)
-		c, err = dialUnix(net, la, ra, deadline)
+		c, err = dialUnix(ctx.network, la, ra, deadline)
 	default:
-		return nil, &OpError{Op: "dial", Net: net, Addr: ra, Err: &AddrError{Err: "unexpected address type", Addr: addr}}
+		return nil, &OpError{Op: "dial", Net: ctx.network, Source: la, Addr: ra, Err: &AddrError{Err: "unexpected address type", Addr: ctx.address}}
 	}
 	if err != nil {
 		return nil, err // c is non-nil interface containing nil pointer
@@ -256,18 +385,18 @@
 // "tcp6", "unix" or "unixpacket".
 // See Dial for the syntax of laddr.
 func Listen(net, laddr string) (Listener, error) {
-	la, err := resolveAddr("listen", net, laddr, noDeadline)
+	addrs, err := resolveAddrList("listen", net, laddr, noDeadline)
 	if err != nil {
-		return nil, &OpError{Op: "listen", Net: net, Addr: nil, Err: err}
+		return nil, &OpError{Op: "listen", Net: net, Source: nil, Addr: nil, Err: err}
 	}
 	var l Listener
-	switch la := la.toAddr().(type) {
+	switch la := addrs.first(isIPv4).(type) {
 	case *TCPAddr:
 		l, err = ListenTCP(net, la)
 	case *UnixAddr:
 		l, err = ListenUnix(net, la)
 	default:
-		return nil, &OpError{Op: "listen", Net: net, Addr: la, Err: &AddrError{Err: "unexpected address type", Addr: laddr}}
+		return nil, &OpError{Op: "listen", Net: net, Source: nil, Addr: la, Err: &AddrError{Err: "unexpected address type", Addr: laddr}}
 	}
 	if err != nil {
 		return nil, err // l is non-nil interface containing nil pointer
@@ -280,12 +409,12 @@
 // "udp6", "ip", "ip4", "ip6" or "unixgram".
 // See Dial for the syntax of laddr.
 func ListenPacket(net, laddr string) (PacketConn, error) {
-	la, err := resolveAddr("listen", net, laddr, noDeadline)
+	addrs, err := resolveAddrList("listen", net, laddr, noDeadline)
 	if err != nil {
-		return nil, &OpError{Op: "listen", Net: net, Addr: nil, Err: err}
+		return nil, &OpError{Op: "listen", Net: net, Source: nil, Addr: nil, Err: err}
 	}
 	var l PacketConn
-	switch la := la.toAddr().(type) {
+	switch la := addrs.first(isIPv4).(type) {
 	case *UDPAddr:
 		l, err = ListenUDP(net, la)
 	case *IPAddr:
@@ -293,7 +422,7 @@
 	case *UnixAddr:
 		l, err = ListenUnixgram(net, la)
 	default:
-		return nil, &OpError{Op: "listen", Net: net, Addr: la, Err: &AddrError{Err: "unexpected address type", Addr: laddr}}
+		return nil, &OpError{Op: "listen", Net: net, Source: nil, Addr: la, Err: &AddrError{Err: "unexpected address type", Addr: laddr}}
 	}
 	if err != nil {
 		return nil, err // l is non-nil interface containing nil pointer
diff --git a/third_party/gofrontend/libgo/go/net/dial_gen.go b/third_party/gofrontend/libgo/go/net/dial_gen.go
index ada6233..a628f71 100644
--- a/third_party/gofrontend/libgo/go/net/dial_gen.go
+++ b/third_party/gofrontend/libgo/go/net/dial_gen.go
@@ -6,23 +6,19 @@
 
 package net
 
-import (
-	"time"
-)
-
-var testingIssue5349 bool // used during tests
+import "time"
 
 // dialChannel is the simple pure-Go implementation of dial, still
 // used on operating systems where the deadline hasn't been pushed
 // down into the pollserver. (Plan 9 and some old versions of Windows)
 func dialChannel(net string, ra Addr, dialer func(time.Time) (Conn, error), deadline time.Time) (Conn, error) {
-	var timeout time.Duration
-	if !deadline.IsZero() {
-		timeout = deadline.Sub(time.Now())
-	}
-	if timeout <= 0 {
+	if deadline.IsZero() {
 		return dialer(noDeadline)
 	}
+	timeout := deadline.Sub(time.Now())
+	if timeout <= 0 {
+		return nil, &OpError{Op: "dial", Net: net, Source: nil, Addr: ra, Err: errTimeout}
+	}
 	t := time.NewTimer(timeout)
 	defer t.Stop()
 	type racer struct {
@@ -31,15 +27,13 @@
 	}
 	ch := make(chan racer, 1)
 	go func() {
-		if testingIssue5349 {
-			time.Sleep(time.Millisecond)
-		}
+		testHookDialChannel()
 		c, err := dialer(noDeadline)
 		ch <- racer{c, err}
 	}()
 	select {
 	case <-t.C:
-		return nil, &OpError{Op: "dial", Net: net, Addr: ra, Err: errTimeout}
+		return nil, &OpError{Op: "dial", Net: net, Source: nil, Addr: ra, Err: errTimeout}
 	case racer := <-ch:
 		return racer.Conn, racer.error
 	}
diff --git a/third_party/gofrontend/libgo/go/net/dial_test.go b/third_party/gofrontend/libgo/go/net/dial_test.go
index 42898d6..ed6d7cc 100644
--- a/third_party/gofrontend/libgo/go/net/dial_test.go
+++ b/third_party/gofrontend/libgo/go/net/dial_test.go
@@ -5,111 +5,50 @@
 package net
 
 import (
-	"bytes"
-	"flag"
-	"fmt"
 	"io"
-	"os"
-	"os/exec"
-	"reflect"
-	"regexp"
+	"net/internal/socktest"
 	"runtime"
-	"strconv"
 	"sync"
 	"testing"
 	"time"
 )
 
-func newLocalListener(t *testing.T) Listener {
-	ln, err := Listen("tcp", "127.0.0.1:0")
-	if err != nil {
-		ln, err = Listen("tcp6", "[::1]:0")
+var prohibitionaryDialArgTests = []struct {
+	network string
+	address string
+}{
+	{"tcp6", "127.0.0.1"},
+	{"tcp6", "::ffff:127.0.0.1"},
+}
+
+func TestProhibitionaryDialArg(t *testing.T) {
+	switch runtime.GOOS {
+	case "plan9":
+		t.Skipf("not supported on %s", runtime.GOOS)
 	}
+	if testing.Short() || !*testExternal {
+		t.Skip("avoid external network")
+	}
+	if !supportsIPv4map {
+		t.Skip("mapping ipv4 address inside ipv6 address not supported")
+	}
+
+	ln, err := Listen("tcp", "[::]:0")
 	if err != nil {
 		t.Fatal(err)
 	}
-	return ln
-}
-
-func TestDialTimeout(t *testing.T) {
-	origBacklog := listenerBacklog
-	defer func() {
-		listenerBacklog = origBacklog
-	}()
-	listenerBacklog = 1
-
-	ln := newLocalListener(t)
 	defer ln.Close()
 
-	errc := make(chan error)
-
-	numConns := listenerBacklog + 100
-
-	// TODO(bradfitz): It's hard to test this in a portable
-	// way. This is unfortunate, but works for now.
-	switch runtime.GOOS {
-	case "linux":
-		// The kernel will start accepting TCP connections before userspace
-		// gets a chance to not accept them, so fire off a bunch to fill up
-		// the kernel's backlog.  Then we test we get a failure after that.
-		for i := 0; i < numConns; i++ {
-			go func() {
-				_, err := DialTimeout("tcp", ln.Addr().String(), 200*time.Millisecond)
-				errc <- err
-			}()
-		}
-	case "darwin", "plan9", "windows":
-		// At least OS X 10.7 seems to accept any number of
-		// connections, ignoring listen's backlog, so resort
-		// to connecting to a hopefully-dead 127/8 address.
-		// Same for windows.
-		//
-		// Use an IANA reserved port (49151) instead of 80, because
-		// on our 386 builder, this Dial succeeds, connecting
-		// to an IIS web server somewhere.  The data center
-		// or VM or firewall must be stealing the TCP connection.
-		//
-		// IANA Service Name and Transport Protocol Port Number Registry
-		// <http://www.iana.org/assignments/service-names-port-numbers/service-names-port-numbers.xml>
-		go func() {
-			c, err := DialTimeout("tcp", "127.0.71.111:49151", 200*time.Millisecond)
-			if err == nil {
-				err = fmt.Errorf("unexpected: connected to %s!", c.RemoteAddr())
-				c.Close()
-			}
-			errc <- err
-		}()
-	default:
-		// TODO(bradfitz):
-		// OpenBSD may have a reject route to 127/8 except 127.0.0.1/32
-		// by default. FreeBSD likely works, but is untested.
-		// TODO(rsc):
-		// The timeout never happens on Windows.  Why?  Issue 3016.
-		t.Skipf("skipping test on %q; untested.", runtime.GOOS)
+	_, port, err := SplitHostPort(ln.Addr().String())
+	if err != nil {
+		t.Fatal(err)
 	}
 
-	connected := 0
-	for {
-		select {
-		case <-time.After(15 * time.Second):
-			t.Fatal("too slow")
-		case err := <-errc:
-			if err == nil {
-				connected++
-				if connected == numConns {
-					t.Fatal("all connections connected; expected some to time out")
-				}
-			} else {
-				terr, ok := err.(timeout)
-				if !ok {
-					t.Fatalf("got error %q; want error with timeout interface", err)
-				}
-				if !terr.Timeout() {
-					t.Fatalf("got error %q; not a timeout", err)
-				}
-				// Pass. We saw a timeout error.
-				return
-			}
+	for i, tt := range prohibitionaryDialArgTests {
+		c, err := Dial(tt.network, JoinHostPort(tt.address, port))
+		if err == nil {
+			c.Close()
+			t.Errorf("#%d: %v", i, err)
 		}
 	}
 }
@@ -117,7 +56,7 @@
 func TestSelfConnect(t *testing.T) {
 	if runtime.GOOS == "windows" {
 		// TODO(brainman): do not know why it hangs.
-		t.Skip("skipping known-broken test on windows")
+		t.Skip("known-broken test on windows")
 	}
 
 	// Test that Dial does not honor self-connects.
@@ -160,303 +99,518 @@
 	}
 }
 
-var runErrorTest = flag.Bool("run_error_test", false, "let TestDialError check for dns errors")
-
-type DialErrorTest struct {
-	Net     string
-	Raddr   string
-	Pattern string
-}
-
-var dialErrorTests = []DialErrorTest{
-	{
-		"datakit", "mh/astro/r70",
-		"dial datakit mh/astro/r70: unknown network datakit",
-	},
-	{
-		"tcp", "127.0.0.1:☺",
-		"dial tcp 127.0.0.1:☺: unknown port tcp/☺",
-	},
-	{
-		"tcp", "no-such-name.google.com.:80",
-		"dial tcp no-such-name.google.com.:80: lookup no-such-name.google.com.( on .*)?: no (.*)",
-	},
-	{
-		"tcp", "no-such-name.no-such-top-level-domain.:80",
-		"dial tcp no-such-name.no-such-top-level-domain.:80: lookup no-such-name.no-such-top-level-domain.( on .*)?: no (.*)",
-	},
-	{
-		"tcp", "no-such-name:80",
-		`dial tcp no-such-name:80: lookup no-such-name\.(.*\.)?( on .*)?: no (.*)`,
-	},
-	{
-		"tcp", "mh/astro/r70:http",
-		"dial tcp mh/astro/r70:http: lookup mh/astro/r70: invalid domain name",
-	},
-	{
-		"unix", "/etc/file-not-found",
-		"dial unix /etc/file-not-found: no such file or directory",
-	},
-	{
-		"unix", "/etc/",
-		"dial unix /etc/: (permission denied|socket operation on non-socket|connection refused)",
-	},
-	{
-		"unixpacket", "/etc/file-not-found",
-		"dial unixpacket /etc/file-not-found: no such file or directory",
-	},
-	{
-		"unixpacket", "/etc/",
-		"dial unixpacket /etc/: (permission denied|socket operation on non-socket|connection refused)",
-	},
-}
-
-var duplicateErrorPattern = `dial (.*) dial (.*)`
-
-func TestDialError(t *testing.T) {
-	if !*runErrorTest {
-		t.Logf("test disabled; use -run_error_test to enable")
-		return
-	}
-	for i, tt := range dialErrorTests {
-		c, err := Dial(tt.Net, tt.Raddr)
-		if c != nil {
-			c.Close()
-		}
-		if err == nil {
-			t.Errorf("#%d: nil error, want match for %#q", i, tt.Pattern)
-			continue
-		}
-		s := err.Error()
-		match, _ := regexp.MatchString(tt.Pattern, s)
-		if !match {
-			t.Errorf("#%d: %q, want match for %#q", i, s, tt.Pattern)
-		}
-		match, _ = regexp.MatchString(duplicateErrorPattern, s)
-		if match {
-			t.Errorf("#%d: %q, duplicate error return from Dial", i, s)
-		}
-	}
-}
-
-var invalidDialAndListenArgTests = []struct {
-	net  string
-	addr string
-	err  error
-}{
-	{"foo", "bar", &OpError{Op: "dial", Net: "foo", Addr: nil, Err: UnknownNetworkError("foo")}},
-	{"baz", "", &OpError{Op: "listen", Net: "baz", Addr: nil, Err: UnknownNetworkError("baz")}},
-	{"tcp", "", &OpError{Op: "dial", Net: "tcp", Addr: nil, Err: errMissingAddress}},
-}
-
-func TestInvalidDialAndListenArgs(t *testing.T) {
-	for _, tt := range invalidDialAndListenArgTests {
-		var err error
-		switch tt.err.(*OpError).Op {
-		case "dial":
-			_, err = Dial(tt.net, tt.addr)
-		case "listen":
-			_, err = Listen(tt.net, tt.addr)
-		}
-		if !reflect.DeepEqual(tt.err, err) {
-			t.Fatalf("got %#v; expected %#v", err, tt.err)
-		}
-	}
-}
-
 func TestDialTimeoutFDLeak(t *testing.T) {
-	if runtime.GOOS != "linux" {
-		// TODO(bradfitz): test on other platforms
-		t.Skipf("skipping test on %q", runtime.GOOS)
+	switch runtime.GOOS {
+	case "plan9":
+		t.Skipf("%s does not have full support of socktest", runtime.GOOS)
 	}
 
-	ln := newLocalListener(t)
-	defer ln.Close()
+	const T = 100 * time.Millisecond
 
-	type connErr struct {
-		conn Conn
-		err  error
-	}
-	dials := listenerBacklog + 100
-	// used to be listenerBacklog + 5, but was found to be unreliable, issue 4384.
-	maxGoodConnect := listenerBacklog + runtime.NumCPU()*10
-	resc := make(chan connErr)
-	for i := 0; i < dials; i++ {
-		go func() {
-			conn, err := DialTimeout("tcp", ln.Addr().String(), 500*time.Millisecond)
-			resc <- connErr{conn, err}
-		}()
-	}
-
-	var firstErr string
-	var ngood int
-	var toClose []io.Closer
-	for i := 0; i < dials; i++ {
-		ce := <-resc
-		if ce.err == nil {
-			ngood++
-			if ngood > maxGoodConnect {
-				t.Errorf("%d good connects; expected at most %d", ngood, maxGoodConnect)
-			}
-			toClose = append(toClose, ce.conn)
-			continue
+	switch runtime.GOOS {
+	case "plan9", "windows":
+		origTestHookDialChannel := testHookDialChannel
+		testHookDialChannel = func() { time.Sleep(2 * T) }
+		defer func() { testHookDialChannel = origTestHookDialChannel }()
+		if runtime.GOOS == "plan9" {
+			break
 		}
-		err := ce.err
-		if firstErr == "" {
-			firstErr = err.Error()
-		} else if err.Error() != firstErr {
-			t.Fatalf("inconsistent error messages: first was %q, then later %q", firstErr, err)
-		}
-	}
-	for _, c := range toClose {
-		c.Close()
-	}
-	for i := 0; i < 100; i++ {
-		if got := numFD(); got < dials {
-			// Test passes.
-			return
-		}
-		time.Sleep(10 * time.Millisecond)
-	}
-	if got := numFD(); got >= dials {
-		t.Errorf("num fds after %d timeouts = %d; want <%d", dials, got, dials)
-	}
-}
-
-func numTCP() (ntcp, nopen, nclose int, err error) {
-	lsof, err := exec.Command("lsof", "-n", "-p", strconv.Itoa(os.Getpid())).Output()
-	if err != nil {
-		return 0, 0, 0, err
-	}
-	ntcp += bytes.Count(lsof, []byte("TCP"))
-	for _, state := range []string{"LISTEN", "SYN_SENT", "SYN_RECEIVED", "ESTABLISHED"} {
-		nopen += bytes.Count(lsof, []byte(state))
-	}
-	for _, state := range []string{"CLOSED", "CLOSE_WAIT", "LAST_ACK", "FIN_WAIT_1", "FIN_WAIT_2", "CLOSING", "TIME_WAIT"} {
-		nclose += bytes.Count(lsof, []byte(state))
-	}
-	return ntcp, nopen, nclose, nil
-}
-
-func TestDialMultiFDLeak(t *testing.T) {
-	t.Skip("flaky test - golang.org/issue/8764")
-
-	if !supportsIPv4 || !supportsIPv6 {
-		t.Skip("neither ipv4 nor ipv6 is supported")
+		fallthrough
+	default:
+		sw.Set(socktest.FilterConnect, func(so *socktest.Status) (socktest.AfterFilter, error) {
+			time.Sleep(2 * T)
+			return nil, errTimeout
+		})
+		defer sw.Set(socktest.FilterConnect, nil)
 	}
 
-	halfDeadServer := func(dss *dualStackServer, ln Listener) {
-		for {
-			if c, err := ln.Accept(); err != nil {
-				return
-			} else {
-				// It just keeps established
-				// connections like a half-dead server
-				// does.
-				dss.putConn(c)
-			}
-		}
-	}
-	dss, err := newDualStackServer([]streamListener{
-		{net: "tcp4", addr: "127.0.0.1"},
-		{net: "tcp6", addr: "[::1]"},
+	// Avoid tracking open-close jitterbugs between netFD and
+	// socket that leads to confusion of information inside
+	// socktest.Switch.
+	// It may happen when the Dial call bumps against TCP
+	// simultaneous open. See selfConnect in tcpsock_posix.go.
+	defer func() {
+		sw.Set(socktest.FilterClose, nil)
+		forceCloseSockets()
+	}()
+	var mu sync.Mutex
+	var attempts int
+	sw.Set(socktest.FilterClose, func(so *socktest.Status) (socktest.AfterFilter, error) {
+		mu.Lock()
+		attempts++
+		mu.Unlock()
+		return nil, errTimedout
 	})
-	if err != nil {
-		t.Fatalf("newDualStackServer failed: %v", err)
-	}
-	defer dss.teardown()
-	if err := dss.buildup(halfDeadServer); err != nil {
-		t.Fatalf("dualStackServer.buildup failed: %v", err)
-	}
 
-	_, before, _, err := numTCP()
-	if err != nil {
-		t.Skipf("skipping test; error finding or running lsof: %v", err)
-	}
-
+	const N = 100
 	var wg sync.WaitGroup
-	portnum, _, _ := dtoi(dss.port, 0)
-	ras := addrList{
-		// Losers that will fail to connect, see RFC 6890.
-		&TCPAddr{IP: IPv4(198, 18, 0, 254), Port: portnum},
-		&TCPAddr{IP: ParseIP("2001:2::254"), Port: portnum},
-
-		// Winner candidates of this race.
-		&TCPAddr{IP: IPv4(127, 0, 0, 1), Port: portnum},
-		&TCPAddr{IP: IPv6loopback, Port: portnum},
-
-		// Losers that will have established connections.
-		&TCPAddr{IP: IPv4(127, 0, 0, 1), Port: portnum},
-		&TCPAddr{IP: IPv6loopback, Port: portnum},
-	}
-	const T1 = 10 * time.Millisecond
-	const T2 = 2 * T1
-	const N = 10
+	wg.Add(N)
 	for i := 0; i < N; i++ {
-		wg.Add(1)
 		go func() {
 			defer wg.Done()
-			if c, err := dialMulti("tcp", "fast failover test", nil, ras, time.Now().Add(T1)); err == nil {
+			// This dial never starts to send any SYN
+			// segment because of above socket filter and
+			// test hook.
+			c, err := DialTimeout("tcp", "127.0.0.1:0", T)
+			if err == nil {
+				t.Errorf("unexpectedly established: tcp:%s->%s", c.LocalAddr(), c.RemoteAddr())
 				c.Close()
 			}
 		}()
 	}
 	wg.Wait()
-	time.Sleep(T2)
-
-	ntcp, after, nclose, err := numTCP()
-	if err != nil {
-		t.Skipf("skipping test; error finding or running lsof: %v", err)
-	}
-	t.Logf("tcp sessions: %v, open sessions: %v, closing sessions: %v", ntcp, after, nclose)
-
-	if after != before {
-		t.Fatalf("got %v open sessions; expected %v", after, before)
+	if attempts < N {
+		t.Errorf("got %d; want >= %d", attempts, N)
 	}
 }
 
-func numFD() int {
-	if runtime.GOOS == "linux" {
-		f, err := os.Open("/proc/self/fd")
-		if err != nil {
-			panic(err)
-		}
-		defer f.Close()
-		names, err := f.Readdirnames(0)
-		if err != nil {
-			panic(err)
-		}
-		return len(names)
+func TestDialerDualStackFDLeak(t *testing.T) {
+	switch runtime.GOOS {
+	case "plan9":
+		t.Skipf("%s does not have full support of socktest", runtime.GOOS)
+	case "windows":
+		t.Skipf("not implemented a way to cancel dial racers in TCP SYN-SENT state on %s", runtime.GOOS)
 	}
-	// All tests using this should be skipped anyway, but:
-	panic("numFDs not implemented on " + runtime.GOOS)
+	if !supportsIPv4 || !supportsIPv6 {
+		t.Skip("both IPv4 and IPv6 are required")
+	}
+
+	origTestHookLookupIP := testHookLookupIP
+	defer func() { testHookLookupIP = origTestHookLookupIP }()
+	testHookLookupIP = lookupLocalhost
+	handler := func(dss *dualStackServer, ln Listener) {
+		for {
+			c, err := ln.Accept()
+			if err != nil {
+				return
+			}
+			c.Close()
+		}
+	}
+	dss, err := newDualStackServer([]streamListener{
+		{network: "tcp4", address: "127.0.0.1"},
+		{network: "tcp6", address: "::1"},
+	})
+	if err != nil {
+		t.Fatal(err)
+	}
+	defer dss.teardown()
+	if err := dss.buildup(handler); err != nil {
+		t.Fatal(err)
+	}
+
+	before := sw.Sockets()
+	const T = 100 * time.Millisecond
+	const N = 10
+	var wg sync.WaitGroup
+	wg.Add(N)
+	d := &Dialer{DualStack: true, Timeout: T}
+	for i := 0; i < N; i++ {
+		go func() {
+			defer wg.Done()
+			c, err := d.Dial("tcp", JoinHostPort("localhost", dss.port))
+			if err != nil {
+				t.Error(err)
+				return
+			}
+			c.Close()
+		}()
+	}
+	wg.Wait()
+	time.Sleep(2 * T) // wait for the dial racers to stop
+	after := sw.Sockets()
+	if len(after) != len(before) {
+		t.Errorf("got %d; want %d", len(after), len(before))
+	}
 }
 
-func TestDialer(t *testing.T) {
-	ln, err := Listen("tcp4", "127.0.0.1:0")
+// Define a pair of blackholed (IPv4, IPv6) addresses, for which dialTCP is
+// expected to hang until the timeout elapses. These addresses are reserved
+// for benchmarking by RFC 6890.
+const (
+	slowDst4    = "192.18.0.254"
+	slowDst6    = "2001:2::254"
+	slowTimeout = 1 * time.Second
+)
+
+// In some environments, the slow IPs may be explicitly unreachable, and fail
+// more quickly than expected. This test hook prevents dialTCP from returning
+// before the deadline.
+func slowDialTCP(net string, laddr, raddr *TCPAddr, deadline time.Time) (*TCPConn, error) {
+	c, err := dialTCP(net, laddr, raddr, deadline)
+	if ParseIP(slowDst4).Equal(raddr.IP) || ParseIP(slowDst6).Equal(raddr.IP) {
+		time.Sleep(deadline.Sub(time.Now()))
+	}
+	return c, err
+}
+
+func dialClosedPort() (actual, expected time.Duration) {
+	// Estimate the expected time for this platform.
+	// On Windows, dialing a closed port takes roughly 1 second,
+	// but other platforms should be instantaneous.
+	if runtime.GOOS == "windows" {
+		expected = 1500 * time.Millisecond
+	} else {
+		expected = 95 * time.Millisecond
+	}
+
+	l, err := Listen("tcp", "127.0.0.1:0")
 	if err != nil {
-		t.Fatalf("Listen failed: %v", err)
+		return 999 * time.Hour, expected
+	}
+	addr := l.Addr().String()
+	l.Close()
+	// On OpenBSD, interference from TestSelfConnect is mysteriously
+	// causing the first attempt to hang for a few seconds, so we throw
+	// away the first result and keep the second.
+	for i := 1; ; i++ {
+		startTime := time.Now()
+		c, err := Dial("tcp", addr)
+		if err == nil {
+			c.Close()
+		}
+		elapsed := time.Now().Sub(startTime)
+		if i == 2 {
+			return elapsed, expected
+		}
+	}
+}
+
+func TestDialParallel(t *testing.T) {
+	if testing.Short() || !*testExternal {
+		t.Skip("avoid external network")
+	}
+	if !supportsIPv4 || !supportsIPv6 {
+		t.Skip("both IPv4 and IPv6 are required")
+	}
+
+	closedPortDelay, expectClosedPortDelay := dialClosedPort()
+	if closedPortDelay > expectClosedPortDelay {
+		t.Errorf("got %v; want <= %v", closedPortDelay, expectClosedPortDelay)
+	}
+
+	const instant time.Duration = 0
+	const fallbackDelay = 200 * time.Millisecond
+
+	// Some cases will run quickly when "connection refused" is fast,
+	// or trigger the fallbackDelay on Windows.  This value holds the
+	// lesser of the two delays.
+	var closedPortOrFallbackDelay time.Duration
+	if closedPortDelay < fallbackDelay {
+		closedPortOrFallbackDelay = closedPortDelay
+	} else {
+		closedPortOrFallbackDelay = fallbackDelay
+	}
+
+	origTestHookDialTCP := testHookDialTCP
+	defer func() { testHookDialTCP = origTestHookDialTCP }()
+	testHookDialTCP = slowDialTCP
+
+	nCopies := func(s string, n int) []string {
+		out := make([]string, n)
+		for i := 0; i < n; i++ {
+			out[i] = s
+		}
+		return out
+	}
+
+	var testCases = []struct {
+		primaries       []string
+		fallbacks       []string
+		teardownNetwork string
+		expectOk        bool
+		expectElapsed   time.Duration
+	}{
+		// These should just work on the first try.
+		{[]string{"127.0.0.1"}, []string{}, "", true, instant},
+		{[]string{"::1"}, []string{}, "", true, instant},
+		{[]string{"127.0.0.1", "::1"}, []string{slowDst6}, "tcp6", true, instant},
+		{[]string{"::1", "127.0.0.1"}, []string{slowDst4}, "tcp4", true, instant},
+		// Primary is slow; fallback should kick in.
+		{[]string{slowDst4}, []string{"::1"}, "", true, fallbackDelay},
+		// Skip a "connection refused" in the primary thread.
+		{[]string{"127.0.0.1", "::1"}, []string{}, "tcp4", true, closedPortDelay},
+		{[]string{"::1", "127.0.0.1"}, []string{}, "tcp6", true, closedPortDelay},
+		// Skip a "connection refused" in the fallback thread.
+		{[]string{slowDst4, slowDst6}, []string{"::1", "127.0.0.1"}, "tcp6", true, fallbackDelay + closedPortDelay},
+		// Primary refused, fallback without delay.
+		{[]string{"127.0.0.1"}, []string{"::1"}, "tcp4", true, closedPortOrFallbackDelay},
+		{[]string{"::1"}, []string{"127.0.0.1"}, "tcp6", true, closedPortOrFallbackDelay},
+		// Everything is refused.
+		{[]string{"127.0.0.1"}, []string{}, "tcp4", false, closedPortDelay},
+		// Nothing to do; fail instantly.
+		{[]string{}, []string{}, "", false, instant},
+		// Connecting to tons of addresses should not trip the deadline.
+		{nCopies("::1", 1000), []string{}, "", true, instant},
+	}
+
+	handler := func(dss *dualStackServer, ln Listener) {
+		for {
+			c, err := ln.Accept()
+			if err != nil {
+				return
+			}
+			c.Close()
+		}
+	}
+
+	// Convert a list of IP strings into TCPAddrs.
+	makeAddrs := func(ips []string, port string) addrList {
+		var out addrList
+		for _, ip := range ips {
+			addr, err := ResolveTCPAddr("tcp", JoinHostPort(ip, port))
+			if err != nil {
+				t.Fatal(err)
+			}
+			out = append(out, addr)
+		}
+		return out
+	}
+
+	for i, tt := range testCases {
+		dss, err := newDualStackServer([]streamListener{
+			{network: "tcp4", address: "127.0.0.1"},
+			{network: "tcp6", address: "::1"},
+		})
+		if err != nil {
+			t.Fatal(err)
+		}
+		defer dss.teardown()
+		if err := dss.buildup(handler); err != nil {
+			t.Fatal(err)
+		}
+		if tt.teardownNetwork != "" {
+			// Destroy one of the listening sockets, creating an unreachable port.
+			dss.teardownNetwork(tt.teardownNetwork)
+		}
+
+		primaries := makeAddrs(tt.primaries, dss.port)
+		fallbacks := makeAddrs(tt.fallbacks, dss.port)
+		d := Dialer{
+			FallbackDelay: fallbackDelay,
+			Timeout:       slowTimeout,
+		}
+		ctx := &dialContext{
+			Dialer:        d,
+			network:       "tcp",
+			address:       "?",
+			finalDeadline: d.deadline(time.Now()),
+		}
+		startTime := time.Now()
+		c, err := dialParallel(ctx, primaries, fallbacks)
+		elapsed := time.Now().Sub(startTime)
+
+		if c != nil {
+			c.Close()
+		}
+
+		if tt.expectOk && err != nil {
+			t.Errorf("#%d: got %v; want nil", i, err)
+		} else if !tt.expectOk && err == nil {
+			t.Errorf("#%d: got nil; want non-nil", i)
+		}
+
+		expectElapsedMin := tt.expectElapsed - 95*time.Millisecond
+		expectElapsedMax := tt.expectElapsed + 95*time.Millisecond
+		if !(elapsed >= expectElapsedMin) {
+			t.Errorf("#%d: got %v; want >= %v", i, elapsed, expectElapsedMin)
+		} else if !(elapsed <= expectElapsedMax) {
+			t.Errorf("#%d: got %v; want <= %v", i, elapsed, expectElapsedMax)
+		}
+	}
+	// Wait for any slowDst4/slowDst6 connections to timeout.
+	time.Sleep(slowTimeout * 3 / 2)
+}
+
+func lookupSlowFast(fn func(string) ([]IPAddr, error), host string) ([]IPAddr, error) {
+	switch host {
+	case "slow6loopback4":
+		// Returns a slow IPv6 address, and a local IPv4 address.
+		return []IPAddr{
+			{IP: ParseIP(slowDst6)},
+			{IP: ParseIP("127.0.0.1")},
+		}, nil
+	default:
+		return fn(host)
+	}
+}
+
+func TestDialerFallbackDelay(t *testing.T) {
+	if testing.Short() || !*testExternal {
+		t.Skip("avoid external network")
+	}
+	if !supportsIPv4 || !supportsIPv6 {
+		t.Skip("both IPv4 and IPv6 are required")
+	}
+
+	origTestHookLookupIP := testHookLookupIP
+	defer func() { testHookLookupIP = origTestHookLookupIP }()
+	testHookLookupIP = lookupSlowFast
+
+	origTestHookDialTCP := testHookDialTCP
+	defer func() { testHookDialTCP = origTestHookDialTCP }()
+	testHookDialTCP = slowDialTCP
+
+	var testCases = []struct {
+		dualstack     bool
+		delay         time.Duration
+		expectElapsed time.Duration
+	}{
+		// Use a very brief delay, which should fallback immediately.
+		{true, 1 * time.Nanosecond, 0},
+		// Use a 200ms explicit timeout.
+		{true, 200 * time.Millisecond, 200 * time.Millisecond},
+		// The default is 300ms.
+		{true, 0, 300 * time.Millisecond},
+		// This case is last, in order to wait for hanging slowDst6 connections.
+		{false, 0, slowTimeout},
+	}
+
+	handler := func(dss *dualStackServer, ln Listener) {
+		for {
+			c, err := ln.Accept()
+			if err != nil {
+				return
+			}
+			c.Close()
+		}
+	}
+	dss, err := newDualStackServer([]streamListener{
+		{network: "tcp", address: "127.0.0.1"},
+	})
+	if err != nil {
+		t.Fatal(err)
+	}
+	defer dss.teardown()
+	if err := dss.buildup(handler); err != nil {
+		t.Fatal(err)
+	}
+
+	for i, tt := range testCases {
+		d := &Dialer{DualStack: tt.dualstack, FallbackDelay: tt.delay, Timeout: slowTimeout}
+
+		startTime := time.Now()
+		c, err := d.Dial("tcp", JoinHostPort("slow6loopback4", dss.port))
+		elapsed := time.Now().Sub(startTime)
+		if err == nil {
+			c.Close()
+		} else if tt.dualstack {
+			t.Error(err)
+		}
+		expectMin := tt.expectElapsed - 1*time.Millisecond
+		expectMax := tt.expectElapsed + 95*time.Millisecond
+		if !(elapsed >= expectMin) {
+			t.Errorf("#%d: got %v; want >= %v", i, elapsed, expectMin)
+		}
+		if !(elapsed <= expectMax) {
+			t.Errorf("#%d: got %v; want <= %v", i, elapsed, expectMax)
+		}
+	}
+}
+
+func TestDialSerialAsyncSpuriousConnection(t *testing.T) {
+	ln, err := newLocalListener("tcp")
+	if err != nil {
+		t.Fatal(err)
 	}
 	defer ln.Close()
+
+	d := Dialer{}
+	ctx := &dialContext{
+		Dialer:        d,
+		network:       "tcp",
+		address:       "?",
+		finalDeadline: d.deadline(time.Now()),
+	}
+
+	results := make(chan dialResult)
+	cancel := make(chan struct{})
+
+	// Spawn a connection in the background.
+	go dialSerialAsync(ctx, addrList{ln.Addr()}, nil, cancel, results)
+
+	// Receive it at the server.
+	c, err := ln.Accept()
+	if err != nil {
+		t.Fatal(err)
+	}
+	defer c.Close()
+
+	// Tell dialSerialAsync that someone else won the race.
+	close(cancel)
+
+	// The connection should close itself, without sending data.
+	c.SetReadDeadline(time.Now().Add(1 * time.Second))
+	var b [1]byte
+	if _, err := c.Read(b[:]); err != io.EOF {
+		t.Errorf("got %v; want %v", err, io.EOF)
+	}
+}
+
+func TestDialerPartialDeadline(t *testing.T) {
+	now := time.Date(2000, time.January, 1, 0, 0, 0, 0, time.UTC)
+	var testCases = []struct {
+		now            time.Time
+		deadline       time.Time
+		addrs          int
+		expectDeadline time.Time
+		expectErr      error
+	}{
+		// Regular division.
+		{now, now.Add(12 * time.Second), 1, now.Add(12 * time.Second), nil},
+		{now, now.Add(12 * time.Second), 2, now.Add(6 * time.Second), nil},
+		{now, now.Add(12 * time.Second), 3, now.Add(4 * time.Second), nil},
+		// Bump against the 2-second sane minimum.
+		{now, now.Add(12 * time.Second), 999, now.Add(2 * time.Second), nil},
+		// Total available is now below the sane minimum.
+		{now, now.Add(1900 * time.Millisecond), 999, now.Add(1900 * time.Millisecond), nil},
+		// Null deadline.
+		{now, noDeadline, 1, noDeadline, nil},
+		// Step the clock forward and cross the deadline.
+		{now.Add(-1 * time.Millisecond), now, 1, now, nil},
+		{now.Add(0 * time.Millisecond), now, 1, noDeadline, errTimeout},
+		{now.Add(1 * time.Millisecond), now, 1, noDeadline, errTimeout},
+	}
+	for i, tt := range testCases {
+		deadline, err := partialDeadline(tt.now, tt.deadline, tt.addrs)
+		if err != tt.expectErr {
+			t.Errorf("#%d: got %v; want %v", i, err, tt.expectErr)
+		}
+		if deadline != tt.expectDeadline {
+			t.Errorf("#%d: got %v; want %v", i, deadline, tt.expectDeadline)
+		}
+	}
+}
+
+func TestDialerLocalAddr(t *testing.T) {
 	ch := make(chan error, 1)
-	go func() {
+	handler := func(ls *localServer, ln Listener) {
 		c, err := ln.Accept()
 		if err != nil {
-			ch <- fmt.Errorf("Accept failed: %v", err)
+			ch <- err
 			return
 		}
 		defer c.Close()
 		ch <- nil
-	}()
-
-	laddr, err := ResolveTCPAddr("tcp4", "127.0.0.1:0")
-	if err != nil {
-		t.Fatalf("ResolveTCPAddr failed: %v", err)
 	}
-	d := &Dialer{LocalAddr: laddr}
-	c, err := d.Dial("tcp4", ln.Addr().String())
+	ls, err := newLocalServer("tcp")
 	if err != nil {
-		t.Fatalf("Dial failed: %v", err)
+		t.Fatal(err)
+	}
+	defer ls.teardown()
+	if err := ls.buildup(handler); err != nil {
+		t.Fatal(err)
+	}
+
+	laddr, err := ResolveTCPAddr(ls.Listener.Addr().Network(), ls.Listener.Addr().String())
+	if err != nil {
+		t.Fatal(err)
+	}
+	laddr.Port = 0
+	d := &Dialer{LocalAddr: laddr}
+	c, err := d.Dial(ls.Listener.Addr().Network(), ls.Addr().String())
+	if err != nil {
+		t.Fatal(err)
 	}
 	defer c.Close()
 	c.Read(make([]byte, 1))
@@ -466,61 +620,20 @@
 	}
 }
 
-func TestDialDualStackLocalhost(t *testing.T) {
-	switch runtime.GOOS {
-	case "nacl":
-		t.Skipf("skipping test on %q", runtime.GOOS)
+func TestDialerDualStack(t *testing.T) {
+	if !supportsIPv4 || !supportsIPv6 {
+		t.Skip("both IPv4 and IPv6 are required")
 	}
 
-	if ips, err := LookupIP("localhost"); err != nil {
-		t.Fatalf("LookupIP failed: %v", err)
-	} else if len(ips) < 2 || !supportsIPv4 || !supportsIPv6 {
-		t.Skip("localhost doesn't have a pair of different address family IP addresses")
+	closedPortDelay, expectClosedPortDelay := dialClosedPort()
+	if closedPortDelay > expectClosedPortDelay {
+		t.Errorf("got %v; want <= %v", closedPortDelay, expectClosedPortDelay)
 	}
 
-	touchAndByeServer := func(dss *dualStackServer, ln Listener) {
-		for {
-			if c, err := ln.Accept(); err != nil {
-				return
-			} else {
-				c.Close()
-			}
-		}
-	}
-	dss, err := newDualStackServer([]streamListener{
-		{net: "tcp4", addr: "127.0.0.1"},
-		{net: "tcp6", addr: "[::1]"},
-	})
-	if err != nil {
-		t.Fatalf("newDualStackServer failed: %v", err)
-	}
-	defer dss.teardown()
-	if err := dss.buildup(touchAndByeServer); err != nil {
-		t.Fatalf("dualStackServer.buildup failed: %v", err)
-	}
-
-	d := &Dialer{DualStack: true}
-	for range dss.lns {
-		if c, err := d.Dial("tcp", "localhost:"+dss.port); err != nil {
-			t.Errorf("Dial failed: %v", err)
-		} else {
-			if addr := c.LocalAddr().(*TCPAddr); addr.IP.To4() != nil {
-				dss.teardownNetwork("tcp4")
-			} else if addr.IP.To16() != nil && addr.IP.To4() == nil {
-				dss.teardownNetwork("tcp6")
-			}
-			c.Close()
-		}
-	}
-}
-
-func TestDialerKeepAlive(t *testing.T) {
-	ln := newLocalListener(t)
-	defer ln.Close()
-	defer func() {
-		testHookSetKeepAlive = func() {}
-	}()
-	go func() {
+	origTestHookLookupIP := testHookLookupIP
+	defer func() { testHookLookupIP = origTestHookLookupIP }()
+	testHookLookupIP = lookupLocalhost
+	handler := func(dss *dualStackServer, ln Listener) {
 		for {
 			c, err := ln.Accept()
 			if err != nil {
@@ -528,7 +641,61 @@
 			}
 			c.Close()
 		}
-	}()
+	}
+
+	var timeout = 100*time.Millisecond + closedPortDelay
+	for _, dualstack := range []bool{false, true} {
+		dss, err := newDualStackServer([]streamListener{
+			{network: "tcp4", address: "127.0.0.1"},
+			{network: "tcp6", address: "::1"},
+		})
+		if err != nil {
+			t.Fatal(err)
+		}
+		defer dss.teardown()
+		if err := dss.buildup(handler); err != nil {
+			t.Fatal(err)
+		}
+
+		d := &Dialer{DualStack: dualstack, Timeout: timeout}
+		for range dss.lns {
+			c, err := d.Dial("tcp", JoinHostPort("localhost", dss.port))
+			if err != nil {
+				t.Error(err)
+				continue
+			}
+			switch addr := c.LocalAddr().(*TCPAddr); {
+			case addr.IP.To4() != nil:
+				dss.teardownNetwork("tcp4")
+			case addr.IP.To16() != nil && addr.IP.To4() == nil:
+				dss.teardownNetwork("tcp6")
+			}
+			c.Close()
+		}
+	}
+	time.Sleep(timeout * 3 / 2) // wait for the dial racers to stop
+}
+
+func TestDialerKeepAlive(t *testing.T) {
+	handler := func(ls *localServer, ln Listener) {
+		for {
+			c, err := ln.Accept()
+			if err != nil {
+				return
+			}
+			c.Close()
+		}
+	}
+	ls, err := newLocalServer("tcp")
+	if err != nil {
+		t.Fatal(err)
+	}
+	defer ls.teardown()
+	if err := ls.buildup(handler); err != nil {
+		t.Fatal(err)
+	}
+	defer func() { testHookSetKeepAlive = func() {} }()
+
 	for _, keepAlive := range []bool{false, true} {
 		got := false
 		testHookSetKeepAlive = func() { got = true }
@@ -536,7 +703,7 @@
 		if keepAlive {
 			d.KeepAlive = 30 * time.Second
 		}
-		c, err := d.Dial("tcp", ln.Addr().String())
+		c, err := d.Dial("tcp", ls.Listener.Addr().String())
 		if err != nil {
 			t.Fatal(err)
 		}
diff --git a/third_party/gofrontend/libgo/go/net/dialgoogle_test.go b/third_party/gofrontend/libgo/go/net/dialgoogle_test.go
deleted file mode 100644
index df5895a..0000000
--- a/third_party/gofrontend/libgo/go/net/dialgoogle_test.go
+++ /dev/null
@@ -1,209 +0,0 @@
-// Copyright 2009 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 net
-
-import (
-	"flag"
-	"fmt"
-	"io"
-	"strings"
-	"syscall"
-	"testing"
-)
-
-// If an IPv6 tunnel is running, we can try dialing a real IPv6 address.
-var testIPv6 = flag.Bool("ipv6", false, "assume ipv6 tunnel is present")
-
-func TestResolveGoogle(t *testing.T) {
-	if testing.Short() || !*testExternal {
-		t.Skip("skipping test to avoid external network")
-	}
-
-	for _, network := range []string{"tcp", "tcp4", "tcp6"} {
-		addr, err := ResolveTCPAddr(network, "www.google.com:http")
-		if err != nil {
-			if (network == "tcp" || network == "tcp4") && !supportsIPv4 {
-				t.Logf("ipv4 is not supported: %v", err)
-			} else if network == "tcp6" && !supportsIPv6 {
-				t.Logf("ipv6 is not supported: %v", err)
-			} else {
-				t.Errorf("ResolveTCPAddr failed: %v", err)
-			}
-			continue
-		}
-		if (network == "tcp" || network == "tcp4") && addr.IP.To4() == nil {
-			t.Errorf("got %v; expected an IPv4 address on %v", addr, network)
-		} else if network == "tcp6" && (addr.IP.To16() == nil || addr.IP.To4() != nil) {
-			t.Errorf("got %v; expected an IPv6 address on %v", addr, network)
-		}
-	}
-}
-
-func TestDialGoogle(t *testing.T) {
-	if testing.Short() || !*testExternal {
-		t.Skip("skipping test to avoid external network")
-	}
-
-	d := &Dialer{DualStack: true}
-	for _, network := range []string{"tcp", "tcp4", "tcp6"} {
-		if network == "tcp" && !supportsIPv4 && !supportsIPv6 {
-			t.Logf("skipping test; both ipv4 and ipv6 are not supported")
-			continue
-		} else if network == "tcp4" && !supportsIPv4 {
-			t.Logf("skipping test; ipv4 is not supported")
-			continue
-		} else if network == "tcp6" && !supportsIPv6 {
-			t.Logf("skipping test; ipv6 is not supported")
-			continue
-		} else if network == "tcp6" && !*testIPv6 {
-			t.Logf("test disabled; use -ipv6 to enable")
-			continue
-		}
-		if c, err := d.Dial(network, "www.google.com:http"); err != nil {
-			t.Errorf("Dial failed: %v", err)
-		} else {
-			c.Close()
-		}
-	}
-}
-
-// fd is already connected to the destination, port 80.
-// Run an HTTP request to fetch the appropriate page.
-func fetchGoogle(t *testing.T, fd Conn, network, addr string) {
-	req := []byte("GET /robots.txt HTTP/1.0\r\nHost: www.google.com\r\n\r\n")
-	n, err := fd.Write(req)
-
-	buf := make([]byte, 1000)
-	n, err = io.ReadFull(fd, buf)
-
-	if n < 1000 {
-		t.Errorf("fetchGoogle: short HTTP read from %s %s - %v", network, addr, err)
-		return
-	}
-}
-
-func doDial(t *testing.T, network, addr string) {
-	fd, err := Dial(network, addr)
-	if err != nil {
-		t.Errorf("Dial(%q, %q, %q) = _, %v", network, "", addr, err)
-		return
-	}
-	fetchGoogle(t, fd, network, addr)
-	fd.Close()
-}
-
-var googleaddrsipv4 = []string{
-	"%d.%d.%d.%d:80",
-	"www.google.com:80",
-	"%d.%d.%d.%d:http",
-	"www.google.com:http",
-	"%03d.%03d.%03d.%03d:0080",
-	"[::ffff:%d.%d.%d.%d]:80",
-	"[::ffff:%02x%02x:%02x%02x]:80",
-	"[0:0:0:0:0000:ffff:%d.%d.%d.%d]:80",
-	"[0:0:0:0:000000:ffff:%d.%d.%d.%d]:80",
-	"[0:0:0:0::ffff:%d.%d.%d.%d]:80",
-}
-
-func TestDialGoogleIPv4(t *testing.T) {
-	if testing.Short() || !*testExternal {
-		t.Skip("skipping test to avoid external network")
-	}
-
-	// Insert an actual IPv4 address for google.com
-	// into the table.
-	addrs, err := LookupIP("www.google.com")
-	if err != nil {
-		t.Fatalf("lookup www.google.com: %v", err)
-	}
-	var ip IP
-	for _, addr := range addrs {
-		if x := addr.To4(); x != nil {
-			ip = x
-			break
-		}
-	}
-	if ip == nil {
-		t.Fatalf("no IPv4 addresses for www.google.com")
-	}
-
-	for i, s := range googleaddrsipv4 {
-		if strings.Contains(s, "%") {
-			googleaddrsipv4[i] = fmt.Sprintf(s, ip[0], ip[1], ip[2], ip[3])
-		}
-	}
-
-	for i := 0; i < len(googleaddrsipv4); i++ {
-		addr := googleaddrsipv4[i]
-		if addr == "" {
-			continue
-		}
-		t.Logf("-- %s --", addr)
-		doDial(t, "tcp", addr)
-		if addr[0] != '[' {
-			doDial(t, "tcp4", addr)
-			if supportsIPv6 {
-				// make sure syscall.SocketDisableIPv6 flag works.
-				syscall.SocketDisableIPv6 = true
-				doDial(t, "tcp", addr)
-				doDial(t, "tcp4", addr)
-				syscall.SocketDisableIPv6 = false
-			}
-		}
-	}
-}
-
-var googleaddrsipv6 = []string{
-	"[%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x]:80",
-	"ipv6.google.com:80",
-	"[%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x]:http",
-	"ipv6.google.com:http",
-}
-
-func TestDialGoogleIPv6(t *testing.T) {
-	if testing.Short() || !*testExternal {
-		t.Skip("skipping test to avoid external network")
-	}
-	// Only run tcp6 if the kernel will take it.
-	if !supportsIPv6 {
-		t.Skip("skipping test; ipv6 is not supported")
-	}
-	if !*testIPv6 {
-		t.Skip("test disabled; use -ipv6 to enable")
-	}
-
-	// Insert an actual IPv6 address for ipv6.google.com
-	// into the table.
-	addrs, err := LookupIP("ipv6.google.com")
-	if err != nil {
-		t.Fatalf("lookup ipv6.google.com: %v", err)
-	}
-	var ip IP
-	for _, addr := range addrs {
-		if x := addr.To16(); x != nil {
-			ip = x
-			break
-		}
-	}
-	if ip == nil {
-		t.Fatalf("no IPv6 addresses for ipv6.google.com")
-	}
-
-	for i, s := range googleaddrsipv6 {
-		if strings.Contains(s, "%") {
-			googleaddrsipv6[i] = fmt.Sprintf(s, ip[0], ip[1], ip[2], ip[3], ip[4], ip[5], ip[6], ip[7], ip[8], ip[9], ip[10], ip[11], ip[12], ip[13], ip[14], ip[15])
-		}
-	}
-
-	for i := 0; i < len(googleaddrsipv6); i++ {
-		addr := googleaddrsipv6[i]
-		if addr == "" {
-			continue
-		}
-		t.Logf("-- %s --", addr)
-		doDial(t, "tcp", addr)
-		doDial(t, "tcp6", addr)
-	}
-}
diff --git a/third_party/gofrontend/libgo/go/net/dnsclient.go b/third_party/gofrontend/libgo/go/net/dnsclient.go
index e8014e4..ce48521 100644
--- a/third_party/gofrontend/libgo/go/net/dnsclient.go
+++ b/third_party/gofrontend/libgo/go/net/dnsclient.go
@@ -9,31 +9,6 @@
 	"sort"
 )
 
-// DNSError represents a DNS lookup error.
-type DNSError struct {
-	Err       string // description of the error
-	Name      string // name looked for
-	Server    string // server used
-	IsTimeout bool
-}
-
-func (e *DNSError) Error() string {
-	if e == nil {
-		return "<nil>"
-	}
-	s := "lookup " + e.Name
-	if e.Server != "" {
-		s += " on " + e.Server
-	}
-	s += ": " + e.Err
-	return s
-}
-
-func (e *DNSError) Timeout() bool   { return e.IsTimeout }
-func (e *DNSError) Temporary() bool { return e.IsTimeout }
-
-const noSuchHost = "no such host"
-
 // reverseaddr returns the in-addr.arpa. or ip6.arpa. hostname of the IP
 // address addr suitable for rDNS (PTR) record lookup or an error if it fails
 // to parse the IP address.
@@ -43,8 +18,7 @@
 		return "", &DNSError{Err: "unrecognized address", Name: addr}
 	}
 	if ip.To4() != nil {
-		return itoa(int(ip[15])) + "." + itoa(int(ip[14])) + "." + itoa(int(ip[13])) + "." +
-			itoa(int(ip[12])) + ".in-addr.arpa.", nil
+		return uitoa(uint(ip[15])) + "." + uitoa(uint(ip[14])) + "." + uitoa(uint(ip[13])) + "." + uitoa(uint(ip[12])) + ".in-addr.arpa.", nil
 	}
 	// Must be IPv6
 	buf := make([]byte, 0, len(ip)*4+len("ip6.arpa."))
@@ -67,7 +41,7 @@
 	addrs = make([]dnsRR, 0, len(dns.answer))
 
 	if dns.rcode == dnsRcodeNameError && dns.recursion_available {
-		return "", nil, &DNSError{Err: noSuchHost, Name: name}
+		return "", nil, &DNSError{Err: errNoSuchHost.Error(), Name: name, Server: server}
 	}
 	if dns.rcode != dnsRcodeSuccess {
 		// None of the error codes make sense
@@ -94,7 +68,7 @@
 				continue
 			}
 			h := rr.Header()
-			if h.Class == dnsClassINET && h.Name == name {
+			if h.Class == dnsClassINET && equalASCIILabel(h.Name, name) {
 				switch h.Rrtype {
 				case qtype:
 					addrs = append(addrs, rr)
@@ -106,7 +80,7 @@
 			}
 		}
 		if len(addrs) == 0 {
-			return "", nil, &DNSError{Err: noSuchHost, Name: name, Server: server}
+			return "", nil, &DNSError{Err: errNoSuchHost.Error(), Name: name, Server: server}
 		}
 		return name, addrs, nil
 	}
@@ -114,6 +88,26 @@
 	return "", nil, &DNSError{Err: "too many redirects", Name: name, Server: server}
 }
 
+func equalASCIILabel(x, y string) bool {
+	if len(x) != len(y) {
+		return false
+	}
+	for i := 0; i < len(x); i++ {
+		a := x[i]
+		b := y[i]
+		if 'A' <= a && a <= 'Z' {
+			a += 0x20
+		}
+		if 'A' <= b && b <= 'Z' {
+			b += 0x20
+		}
+		if a != b {
+			return false
+		}
+	}
+	return true
+}
+
 func isDomainName(s string) bool {
 	// See RFC 1035, RFC 3696.
 	if len(s) == 0 {
@@ -174,13 +168,10 @@
 type byPriorityWeight []*SRV
 
 func (s byPriorityWeight) Len() int { return len(s) }
-
-func (s byPriorityWeight) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
-
 func (s byPriorityWeight) Less(i, j int) bool {
-	return s[i].Priority < s[j].Priority ||
-		(s[i].Priority == s[j].Priority && s[i].Weight < s[j].Weight)
+	return s[i].Priority < s[j].Priority || (s[i].Priority == s[j].Priority && s[i].Weight < s[j].Weight)
 }
+func (s byPriorityWeight) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
 
 // shuffleByWeight shuffles SRV records by weight using the algorithm
 // described in RFC 2782.
@@ -228,11 +219,9 @@
 // byPref implements sort.Interface to sort MX records by preference
 type byPref []*MX
 
-func (s byPref) Len() int { return len(s) }
-
+func (s byPref) Len() int           { return len(s) }
 func (s byPref) Less(i, j int) bool { return s[i].Pref < s[j].Pref }
-
-func (s byPref) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
+func (s byPref) Swap(i, j int)      { s[i], s[j] = s[j], s[i] }
 
 // sort reorders MX records as specified in RFC 5321.
 func (s byPref) sort() {
diff --git a/third_party/gofrontend/libgo/go/net/dnsclient_test.go b/third_party/gofrontend/libgo/go/net/dnsclient_test.go
index 435eb35..3ab2b83 100644
--- a/third_party/gofrontend/libgo/go/net/dnsclient_test.go
+++ b/third_party/gofrontend/libgo/go/net/dnsclient_test.go
@@ -47,7 +47,7 @@
 	checkDistribution(t, data, margin)
 }
 
-func TestUniformity(t *testing.T) {
+func TestDNSSRVUniformity(t *testing.T) {
 	testUniformity(t, 2, 0.05)
 	testUniformity(t, 3, 0.10)
 	testUniformity(t, 10, 0.20)
diff --git a/third_party/gofrontend/libgo/go/net/dnsclient_unix.go b/third_party/gofrontend/libgo/go/net/dnsclient_unix.go
index 7511083..c03c1b1 100644
--- a/third_party/gofrontend/libgo/go/net/dnsclient_unix.go
+++ b/third_party/gofrontend/libgo/go/net/dnsclient_unix.go
@@ -20,6 +20,7 @@
 	"io"
 	"math/rand"
 	"os"
+	"strconv"
 	"sync"
 	"time"
 )
@@ -184,9 +185,9 @@
 				}
 				continue
 			}
-			cname, addrs, err := answer(name, server, msg, qtype)
-			if err == nil || err.(*DNSError).Err == noSuchHost {
-				return cname, addrs, err
+			cname, rrs, err := answer(name, server, msg, qtype)
+			if err == nil || msg.rcode == dnsRcodeSuccess || msg.rcode == dnsRcodeNameError && msg.recursion_available {
+				return cname, rrs, err
 			}
 			lastErr = err
 		}
@@ -194,144 +195,188 @@
 	return "", nil, lastErr
 }
 
-func convertRR_A(records []dnsRR) []IP {
-	addrs := make([]IP, len(records))
-	for i, rr := range records {
-		a := rr.(*dnsRR_A).A
-		addrs[i] = IPv4(byte(a>>24), byte(a>>16), byte(a>>8), byte(a))
-	}
-	return addrs
-}
-
-func convertRR_AAAA(records []dnsRR) []IP {
-	addrs := make([]IP, len(records))
-	for i, rr := range records {
-		a := make(IP, IPv6len)
-		copy(a, rr.(*dnsRR_AAAA).AAAA[:])
-		addrs[i] = a
-	}
-	return addrs
-}
-
-var cfg struct {
-	ch        chan struct{}
-	mu        sync.RWMutex // protects dnsConfig and dnserr
-	dnsConfig *dnsConfig
-	dnserr    error
-}
-var onceLoadConfig sync.Once
-
-// Assume dns config file is /etc/resolv.conf here
-func loadDefaultConfig() {
-	loadConfig("/etc/resolv.conf", 5*time.Second, nil)
-}
-
-func loadConfig(resolvConfPath string, reloadTime time.Duration, quit <-chan chan struct{}) {
-	var mtime time.Time
-	cfg.ch = make(chan struct{}, 1)
-	if fi, err := os.Stat(resolvConfPath); err != nil {
-		cfg.dnserr = err
-	} else {
-		mtime = fi.ModTime()
-		cfg.dnsConfig, cfg.dnserr = dnsReadConfig(resolvConfPath)
-	}
-	go func() {
-		for {
-			time.Sleep(reloadTime)
-			select {
-			case qresp := <-quit:
-				qresp <- struct{}{}
-				return
-			case <-cfg.ch:
-			}
-
-			// In case of error, we keep the previous config
-			fi, err := os.Stat(resolvConfPath)
-			if err != nil {
-				continue
-			}
-			// If the resolv.conf mtime didn't change, do not reload
-			m := fi.ModTime()
-			if m.Equal(mtime) {
-				continue
-			}
-			mtime = m
-			// In case of error, we keep the previous config
-			ncfg, err := dnsReadConfig(resolvConfPath)
-			if err != nil || len(ncfg.servers) == 0 {
-				continue
-			}
-			cfg.mu.Lock()
-			cfg.dnsConfig = ncfg
-			cfg.dnserr = nil
-			cfg.mu.Unlock()
+// addrRecordList converts and returns a list of IP addresses from DNS
+// address records (both A and AAAA). Other record types are ignored.
+func addrRecordList(rrs []dnsRR) []IPAddr {
+	addrs := make([]IPAddr, 0, 4)
+	for _, rr := range rrs {
+		switch rr := rr.(type) {
+		case *dnsRR_A:
+			addrs = append(addrs, IPAddr{IP: IPv4(byte(rr.A>>24), byte(rr.A>>16), byte(rr.A>>8), byte(rr.A))})
+		case *dnsRR_AAAA:
+			ip := make(IP, IPv6len)
+			copy(ip, rr.AAAA[:])
+			addrs = append(addrs, IPAddr{IP: ip})
 		}
-	}()
+	}
+	return addrs
 }
 
-func lookup(name string, qtype uint16) (cname string, addrs []dnsRR, err error) {
-	if !isDomainName(name) {
-		return name, nil, &DNSError{Err: "invalid domain name", Name: name}
-	}
-	onceLoadConfig.Do(loadDefaultConfig)
+// A resolverConfig represents a DNS stub resolver configuration.
+type resolverConfig struct {
+	initOnce sync.Once // guards init of resolverConfig
 
-	select {
-	case cfg.ch <- struct{}{}:
-	default:
+	// ch is used as a semaphore that only allows one lookup at a
+	// time to recheck resolv.conf.
+	ch          chan struct{} // guards lastChecked and modTime
+	lastChecked time.Time     // last time resolv.conf was checked
+	modTime     time.Time     // time of resolv.conf modification
+
+	mu        sync.RWMutex // protects dnsConfig
+	dnsConfig *dnsConfig   // parsed resolv.conf structure used in lookups
+}
+
+var resolvConf resolverConfig
+
+// init initializes conf and is only called via conf.initOnce.
+func (conf *resolverConfig) init() {
+	// Set dnsConfig, modTime, and lastChecked so we don't parse
+	// resolv.conf twice the first time.
+	conf.dnsConfig = systemConf().resolv
+	if conf.dnsConfig == nil {
+		conf.dnsConfig = dnsReadConfig("/etc/resolv.conf")
 	}
 
-	cfg.mu.RLock()
-	defer cfg.mu.RUnlock()
+	if fi, err := os.Stat("/etc/resolv.conf"); err == nil {
+		conf.modTime = fi.ModTime()
+	}
+	conf.lastChecked = time.Now()
 
-	if cfg.dnserr != nil || cfg.dnsConfig == nil {
-		err = cfg.dnserr
+	// Prepare ch so that only one update of resolverConfig may
+	// run at once.
+	conf.ch = make(chan struct{}, 1)
+}
+
+// tryUpdate tries to update conf with the named resolv.conf file.
+// The name variable only exists for testing. It is otherwise always
+// "/etc/resolv.conf".
+func (conf *resolverConfig) tryUpdate(name string) {
+	conf.initOnce.Do(conf.init)
+
+	// Ensure only one update at a time checks resolv.conf.
+	if !conf.tryAcquireSema() {
 		return
 	}
-	// If name is rooted (trailing dot) or has enough dots,
-	// try it by itself first.
-	rooted := len(name) > 0 && name[len(name)-1] == '.'
-	if rooted || count(name, '.') >= cfg.dnsConfig.ndots {
-		rname := name
-		if !rooted {
-			rname += "."
-		}
-		// Can try as ordinary name.
-		cname, addrs, err = tryOneName(cfg.dnsConfig, rname, qtype)
-		if rooted || err == nil {
+	defer conf.releaseSema()
+
+	now := time.Now()
+	if conf.lastChecked.After(now.Add(-5 * time.Second)) {
+		return
+	}
+	conf.lastChecked = now
+
+	if fi, err := os.Stat(name); err == nil {
+		if fi.ModTime().Equal(conf.modTime) {
 			return
 		}
+		conf.modTime = fi.ModTime()
+	} else {
+		// If modTime wasn't set prior, assume nothing has changed.
+		if conf.modTime.IsZero() {
+			return
+		}
+		conf.modTime = time.Time{}
 	}
 
-	// Otherwise, try suffixes.
-	for i := 0; i < len(cfg.dnsConfig.search); i++ {
-		rname := name + "." + cfg.dnsConfig.search[i]
-		if rname[len(rname)-1] != '.' {
-			rname += "."
-		}
-		cname, addrs, err = tryOneName(cfg.dnsConfig, rname, qtype)
+	dnsConf := dnsReadConfig(name)
+	conf.mu.Lock()
+	conf.dnsConfig = dnsConf
+	conf.mu.Unlock()
+}
+
+func (conf *resolverConfig) tryAcquireSema() bool {
+	select {
+	case conf.ch <- struct{}{}:
+		return true
+	default:
+		return false
+	}
+}
+
+func (conf *resolverConfig) releaseSema() {
+	<-conf.ch
+}
+
+func lookup(name string, qtype uint16) (cname string, rrs []dnsRR, err error) {
+	if !isDomainName(name) {
+		return "", nil, &DNSError{Err: "invalid domain name", Name: name}
+	}
+	resolvConf.tryUpdate("/etc/resolv.conf")
+	resolvConf.mu.RLock()
+	conf := resolvConf.dnsConfig
+	resolvConf.mu.RUnlock()
+	for _, fqdn := range conf.nameList(name) {
+		cname, rrs, err = tryOneName(conf, fqdn, qtype)
 		if err == nil {
-			return
+			break
 		}
 	}
-
-	// Last ditch effort: try unsuffixed only if we haven't already,
-	// that is, name is not rooted and has less than ndots dots.
-	if count(name, '.') < cfg.dnsConfig.ndots {
-		cname, addrs, err = tryOneName(cfg.dnsConfig, name+".", qtype)
-		if err == nil {
-			return
-		}
-	}
-
-	if e, ok := err.(*DNSError); ok {
+	if err, ok := err.(*DNSError); ok {
 		// Show original name passed to lookup, not suffixed one.
 		// In general we might have tried many suffixes; showing
 		// just one is misleading. See also golang.org/issue/6324.
-		e.Name = name
+		err.Name = name
 	}
 	return
 }
 
+// nameList returns a list of names for sequential DNS queries.
+func (conf *dnsConfig) nameList(name string) []string {
+	// If name is rooted (trailing dot), try only that name.
+	rooted := len(name) > 0 && name[len(name)-1] == '.'
+	if rooted {
+		return []string{name}
+	}
+	// Build list of search choices.
+	names := make([]string, 0, 1+len(conf.search))
+	// If name has enough dots, try unsuffixed first.
+	if count(name, '.') >= conf.ndots {
+		names = append(names, name+".")
+	}
+	// Try suffixes.
+	for _, suffix := range conf.search {
+		suffixed := name + "." + suffix
+		if suffixed[len(suffixed)-1] != '.' {
+			suffixed += "."
+		}
+		names = append(names, suffixed)
+	}
+	// Try unsuffixed, if not tried first above.
+	if count(name, '.') < conf.ndots {
+		names = append(names, name+".")
+	}
+	return names
+}
+
+// hostLookupOrder specifies the order of LookupHost lookup strategies.
+// It is basically a simplified representation of nsswitch.conf.
+// "files" means /etc/hosts.
+type hostLookupOrder int
+
+const (
+	// hostLookupCgo means defer to cgo.
+	hostLookupCgo      hostLookupOrder = iota
+	hostLookupFilesDNS                 // files first
+	hostLookupDNSFiles                 // dns first
+	hostLookupFiles                    // only files
+	hostLookupDNS                      // only DNS
+)
+
+var lookupOrderName = map[hostLookupOrder]string{
+	hostLookupCgo:      "cgo",
+	hostLookupFilesDNS: "files,dns",
+	hostLookupDNSFiles: "dns,files",
+	hostLookupFiles:    "files",
+	hostLookupDNS:      "dns",
+}
+
+func (o hostLookupOrder) String() string {
+	if s, ok := lookupOrderName[o]; ok {
+		return s
+	}
+	return "hostLookupOrder=" + strconv.Itoa(int(o)) + "??"
+}
+
 // goLookupHost is the native Go implementation of LookupHost.
 // Used only if cgoLookupHost refuses to handle the request
 // (that is, only if cgoLookupHost is the stub in cgo_stub.go).
@@ -339,12 +384,18 @@
 // depending on our lookup code, so that Go and C get the same
 // answers.
 func goLookupHost(name string) (addrs []string, err error) {
-	// Use entries from /etc/hosts if they match.
-	addrs = lookupStaticHost(name)
-	if len(addrs) > 0 {
-		return
+	return goLookupHostOrder(name, hostLookupFilesDNS)
+}
+
+func goLookupHostOrder(name string, order hostLookupOrder) (addrs []string, err error) {
+	if order == hostLookupFilesDNS || order == hostLookupFiles {
+		// Use entries from /etc/hosts if they match.
+		addrs = lookupStaticHost(name)
+		if len(addrs) > 0 || order == hostLookupFiles {
+			return
+		}
 	}
-	ips, err := goLookupIP(name)
+	ips, err := goLookupIPOrder(name, order)
 	if err != nil {
 		return
 	}
@@ -355,54 +406,79 @@
 	return
 }
 
-// goLookupIP is the native Go implementation of LookupIP.
-// Used only if cgoLookupIP refuses to handle the request
-// (that is, only if cgoLookupIP is the stub in cgo_stub.go).
-// Normally we let cgo use the C library resolver instead of
-// depending on our lookup code, so that Go and C get the same
-// answers.
-func goLookupIP(name string) (addrs []IP, err error) {
-	// Use entries from /etc/hosts if possible.
-	haddrs := lookupStaticHost(name)
-	if len(haddrs) > 0 {
-		for _, haddr := range haddrs {
-			if ip := ParseIP(haddr); ip != nil {
-				addrs = append(addrs, ip)
-			}
-		}
-		if len(addrs) > 0 {
-			return
+// lookup entries from /etc/hosts
+func goLookupIPFiles(name string) (addrs []IPAddr) {
+	for _, haddr := range lookupStaticHost(name) {
+		haddr, zone := splitHostZone(haddr)
+		if ip := ParseIP(haddr); ip != nil {
+			addr := IPAddr{IP: ip, Zone: zone}
+			addrs = append(addrs, addr)
 		}
 	}
+	sortByRFC6724(addrs)
+	return
+}
+
+// goLookupIP is the native Go implementation of LookupIP.
+// The libc versions are in cgo_*.go.
+func goLookupIP(name string) (addrs []IPAddr, err error) {
+	return goLookupIPOrder(name, hostLookupFilesDNS)
+}
+
+func goLookupIPOrder(name string, order hostLookupOrder) (addrs []IPAddr, err error) {
+	if order == hostLookupFilesDNS || order == hostLookupFiles {
+		addrs = goLookupIPFiles(name)
+		if len(addrs) > 0 || order == hostLookupFiles {
+			return addrs, nil
+		}
+	}
+	if !isDomainName(name) {
+		return nil, &DNSError{Err: "invalid domain name", Name: name}
+	}
+	resolvConf.tryUpdate("/etc/resolv.conf")
+	resolvConf.mu.RLock()
+	conf := resolvConf.dnsConfig
+	resolvConf.mu.RUnlock()
 	type racer struct {
-		qtype uint16
-		rrs   []dnsRR
+		rrs []dnsRR
 		error
 	}
 	lane := make(chan racer, 1)
 	qtypes := [...]uint16{dnsTypeA, dnsTypeAAAA}
-	for _, qtype := range qtypes {
-		go func(qtype uint16) {
-			_, rrs, err := lookup(name, qtype)
-			lane <- racer{qtype, rrs, err}
-		}(qtype)
-	}
 	var lastErr error
-	for range qtypes {
-		racer := <-lane
-		if racer.error != nil {
-			lastErr = racer.error
-			continue
+	for _, fqdn := range conf.nameList(name) {
+		for _, qtype := range qtypes {
+			go func(qtype uint16) {
+				_, rrs, err := tryOneName(conf, fqdn, qtype)
+				lane <- racer{rrs, err}
+			}(qtype)
 		}
-		switch racer.qtype {
-		case dnsTypeA:
-			addrs = append(addrs, convertRR_A(racer.rrs)...)
-		case dnsTypeAAAA:
-			addrs = append(addrs, convertRR_AAAA(racer.rrs)...)
+		for range qtypes {
+			racer := <-lane
+			if racer.error != nil {
+				lastErr = racer.error
+				continue
+			}
+			addrs = append(addrs, addrRecordList(racer.rrs)...)
+		}
+		if len(addrs) > 0 {
+			break
 		}
 	}
-	if len(addrs) == 0 && lastErr != nil {
-		return nil, lastErr
+	if lastErr, ok := lastErr.(*DNSError); ok {
+		// Show original name passed to lookup, not suffixed one.
+		// In general we might have tried many suffixes; showing
+		// just one is misleading. See also golang.org/issue/6324.
+		lastErr.Name = name
+	}
+	sortByRFC6724(addrs)
+	if len(addrs) == 0 {
+		if lastErr != nil {
+			return nil, lastErr
+		}
+		if order == hostLookupDNSFiles {
+			addrs = goLookupIPFiles(name)
+		}
 	}
 	return addrs, nil
 }
@@ -414,10 +490,35 @@
 // depending on our lookup code, so that Go and C get the same
 // answers.
 func goLookupCNAME(name string) (cname string, err error) {
-	_, rr, err := lookup(name, dnsTypeCNAME)
+	_, rrs, err := lookup(name, dnsTypeCNAME)
 	if err != nil {
 		return
 	}
-	cname = rr[0].(*dnsRR_CNAME).Cname
+	cname = rrs[0].(*dnsRR_CNAME).Cname
 	return
 }
+
+// goLookupPTR is the native Go implementation of LookupAddr.
+// Used only if cgoLookupPTR refuses to handle the request (that is,
+// only if cgoLookupPTR is the stub in cgo_stub.go).
+// Normally we let cgo use the C library resolver instead of depending
+// on our lookup code, so that Go and C get the same answers.
+func goLookupPTR(addr string) ([]string, error) {
+	names := lookupStaticAddr(addr)
+	if len(names) > 0 {
+		return names, nil
+	}
+	arpa, err := reverseaddr(addr)
+	if err != nil {
+		return nil, err
+	}
+	_, rrs, err := lookup(arpa, dnsTypePTR)
+	if err != nil {
+		return nil, err
+	}
+	ptrs := make([]string, len(rrs))
+	for i, rr := range rrs {
+		ptrs[i] = rr.(*dnsRR_PTR).Ptr
+	}
+	return ptrs, nil
+}
diff --git a/third_party/gofrontend/libgo/go/net/dnsclient_unix_test.go b/third_party/gofrontend/libgo/go/net/dnsclient_unix_test.go
index 1167c26..a999f8f 100644
--- a/third_party/gofrontend/libgo/go/net/dnsclient_unix_test.go
+++ b/third_party/gofrontend/libgo/go/net/dnsclient_unix_test.go
@@ -7,11 +7,13 @@
 package net
 
 import (
-	"io"
+	"fmt"
 	"io/ioutil"
 	"os"
 	"path"
 	"reflect"
+	"strings"
+	"sync"
 	"testing"
 	"time"
 )
@@ -31,7 +33,7 @@
 
 func TestDNSTransportFallback(t *testing.T) {
 	if testing.Short() || !*testExternal {
-		t.Skip("skipping test to avoid external network")
+		t.Skip("avoid external network")
 	}
 
 	for _, tt := range dnsTransportFallbackTests {
@@ -57,13 +59,13 @@
 	qtype uint16
 	rcode int
 }{
-	// Name resoltion APIs and libraries should not recongnize the
+	// Name resolution APIs and libraries should not recognize the
 	// followings as special.
 	{"1.0.168.192.in-addr.arpa.", dnsTypePTR, dnsRcodeNameError},
 	{"test.", dnsTypeALL, dnsRcodeNameError},
 	{"example.com.", dnsTypeALL, dnsRcodeSuccess},
 
-	// Name resoltion APIs and libraries should recongnize the
+	// Name resolution APIs and libraries should recognize the
 	// followings as special and should not send any queries.
 	// Though, we test those names here for verifying nagative
 	// answers at DNS query-response interaction level.
@@ -73,7 +75,7 @@
 
 func TestSpecialDomainName(t *testing.T) {
 	if testing.Short() || !*testExternal {
-		t.Skip("skipping test to avoid external network")
+		t.Skip("avoid external network")
 	}
 
 	server := "8.8.8.8:53"
@@ -93,154 +95,323 @@
 }
 
 type resolvConfTest struct {
-	*testing.T
-	dir     string
-	path    string
-	started bool
-	quitc   chan chan struct{}
+	dir  string
+	path string
+	*resolverConfig
 }
 
-func newResolvConfTest(t *testing.T) *resolvConfTest {
-	dir, err := ioutil.TempDir("", "resolvConfTest")
+func newResolvConfTest() (*resolvConfTest, error) {
+	dir, err := ioutil.TempDir("", "go-resolvconftest")
 	if err != nil {
-		t.Fatalf("could not create temp dir: %v", err)
+		return nil, err
 	}
-
-	// Disable the default loadConfig
-	onceLoadConfig.Do(func() {})
-
-	r := &resolvConfTest{
-		T:     t,
-		dir:   dir,
-		path:  path.Join(dir, "resolv.conf"),
-		quitc: make(chan chan struct{}),
+	conf := &resolvConfTest{
+		dir:            dir,
+		path:           path.Join(dir, "resolv.conf"),
+		resolverConfig: &resolvConf,
 	}
-
-	return r
+	conf.initOnce.Do(conf.init)
+	return conf, nil
 }
 
-func (r *resolvConfTest) Start() {
-	loadConfig(r.path, 100*time.Millisecond, r.quitc)
-	r.started = true
-}
-
-func (r *resolvConfTest) SetConf(s string) {
-	// Make sure the file mtime will be different once we're done here,
-	// even on systems with coarse (1s) mtime resolution.
-	time.Sleep(time.Second)
-
-	f, err := os.OpenFile(r.path, os.O_CREATE|os.O_TRUNC|os.O_WRONLY, 0600)
+func (conf *resolvConfTest) writeAndUpdate(lines []string) error {
+	f, err := os.OpenFile(conf.path, os.O_CREATE|os.O_TRUNC|os.O_WRONLY, 0600)
 	if err != nil {
-		r.Fatalf("failed to create temp file %s: %v", r.path, err)
+		return err
 	}
-	if _, err := io.WriteString(f, s); err != nil {
+	if _, err := f.WriteString(strings.Join(lines, "\n")); err != nil {
 		f.Close()
-		r.Fatalf("failed to write temp file: %v", err)
+		return err
 	}
 	f.Close()
-
-	if r.started {
-		cfg.ch <- struct{}{} // fill buffer
-		cfg.ch <- struct{}{} // wait for reload to begin
-		cfg.ch <- struct{}{} // wait for reload to complete
+	if err := conf.forceUpdate(conf.path); err != nil {
+		return err
 	}
+	return nil
 }
 
-func (r *resolvConfTest) WantServers(want []string) {
-	cfg.mu.RLock()
-	defer cfg.mu.RUnlock()
-	if got := cfg.dnsConfig.servers; !reflect.DeepEqual(got, want) {
-		r.Fatalf("Unexpected dns server loaded, got %v want %v", got, want)
+func (conf *resolvConfTest) forceUpdate(name string) error {
+	dnsConf := dnsReadConfig(name)
+	conf.mu.Lock()
+	conf.dnsConfig = dnsConf
+	conf.mu.Unlock()
+	for i := 0; i < 5; i++ {
+		if conf.tryAcquireSema() {
+			conf.lastChecked = time.Time{}
+			conf.releaseSema()
+			return nil
+		}
 	}
+	return fmt.Errorf("tryAcquireSema for %s failed", name)
 }
 
-func (r *resolvConfTest) Close() {
-	resp := make(chan struct{})
-	r.quitc <- resp
-	<-resp
-	if err := os.RemoveAll(r.dir); err != nil {
-		r.Logf("failed to remove temp dir %s: %v", r.dir, err)
-	}
+func (conf *resolvConfTest) servers() []string {
+	conf.mu.RLock()
+	servers := conf.dnsConfig.servers
+	conf.mu.RUnlock()
+	return servers
 }
 
-func TestReloadResolvConfFail(t *testing.T) {
+func (conf *resolvConfTest) teardown() error {
+	err := conf.forceUpdate("/etc/resolv.conf")
+	os.RemoveAll(conf.dir)
+	return err
+}
+
+var updateResolvConfTests = []struct {
+	name    string   // query name
+	lines   []string // resolver configuration lines
+	servers []string // expected name servers
+}{
+	{
+		name:    "golang.org",
+		lines:   []string{"nameserver 8.8.8.8"},
+		servers: []string{"8.8.8.8"},
+	},
+	{
+		name:    "",
+		lines:   nil, // an empty resolv.conf should use defaultNS as name servers
+		servers: defaultNS,
+	},
+	{
+		name:    "www.example.com",
+		lines:   []string{"nameserver 8.8.4.4"},
+		servers: []string{"8.8.4.4"},
+	},
+}
+
+func TestUpdateResolvConf(t *testing.T) {
 	if testing.Short() || !*testExternal {
-		t.Skip("skipping test to avoid external network")
+		t.Skip("avoid external network")
 	}
 
-	r := newResolvConfTest(t)
-	defer r.Close()
-
-	// resolv.conf.tmp does not exist yet
-	r.Start()
-	if _, err := goLookupIP("golang.org"); err == nil {
-		t.Fatal("goLookupIP(missing) succeeded")
+	conf, err := newResolvConfTest()
+	if err != nil {
+		t.Fatal(err)
 	}
+	defer conf.teardown()
 
-	r.SetConf("nameserver 8.8.8.8")
-	if _, err := goLookupIP("golang.org"); err != nil {
-		t.Fatalf("goLookupIP(missing; good) failed: %v", err)
-	}
-
-	// Using a bad resolv.conf while we had a good
-	// one before should not update the config
-	r.SetConf("")
-	if _, err := goLookupIP("golang.org"); err != nil {
-		t.Fatalf("goLookupIP(missing; good; bad) failed: %v", err)
+	for i, tt := range updateResolvConfTests {
+		if err := conf.writeAndUpdate(tt.lines); err != nil {
+			t.Error(err)
+			continue
+		}
+		if tt.name != "" {
+			var wg sync.WaitGroup
+			const N = 10
+			wg.Add(N)
+			for j := 0; j < N; j++ {
+				go func(name string) {
+					defer wg.Done()
+					ips, err := goLookupIP(name)
+					if err != nil {
+						t.Error(err)
+						return
+					}
+					if len(ips) == 0 {
+						t.Errorf("no records for %s", name)
+						return
+					}
+				}(tt.name)
+			}
+			wg.Wait()
+		}
+		servers := conf.servers()
+		if !reflect.DeepEqual(servers, tt.servers) {
+			t.Errorf("#%d: got %v; want %v", i, servers, tt.servers)
+			continue
+		}
 	}
 }
 
-func TestReloadResolvConfChange(t *testing.T) {
+var goLookupIPWithResolverConfigTests = []struct {
+	name  string
+	lines []string // resolver configuration lines
+	error
+	a, aaaa bool // whether response contains A, AAAA-record
+}{
+	// no records, transport timeout
+	{
+		"jgahvsekduiv9bw4b3qhn4ykdfgj0493iohkrjfhdvhjiu4j",
+		[]string{
+			"options timeout:1 attempts:1",
+			"nameserver 255.255.255.255", // please forgive us for abuse of limited broadcast address
+		},
+		&DNSError{Name: "jgahvsekduiv9bw4b3qhn4ykdfgj0493iohkrjfhdvhjiu4j", Server: "255.255.255.255:53", IsTimeout: true},
+		false, false,
+	},
+
+	// no records, non-existent domain
+	{
+		"jgahvsekduiv9bw4b3qhn4ykdfgj0493iohkrjfhdvhjiu4j",
+		[]string{
+			"options timeout:3 attempts:1",
+			"nameserver 8.8.8.8",
+		},
+		&DNSError{Name: "jgahvsekduiv9bw4b3qhn4ykdfgj0493iohkrjfhdvhjiu4j", Server: "8.8.8.8:53", IsTimeout: false},
+		false, false,
+	},
+
+	// a few A records, no AAAA records
+	{
+		"ipv4.google.com.",
+		[]string{
+			"nameserver 8.8.8.8",
+			"nameserver 2001:4860:4860::8888",
+		},
+		nil,
+		true, false,
+	},
+	{
+		"ipv4.google.com",
+		[]string{
+			"domain golang.org",
+			"nameserver 2001:4860:4860::8888",
+			"nameserver 8.8.8.8",
+		},
+		nil,
+		true, false,
+	},
+	{
+		"ipv4.google.com",
+		[]string{
+			"search x.golang.org y.golang.org",
+			"nameserver 2001:4860:4860::8888",
+			"nameserver 8.8.8.8",
+		},
+		nil,
+		true, false,
+	},
+
+	// no A records, a few AAAA records
+	{
+		"ipv6.google.com.",
+		[]string{
+			"nameserver 2001:4860:4860::8888",
+			"nameserver 8.8.8.8",
+		},
+		nil,
+		false, true,
+	},
+	{
+		"ipv6.google.com",
+		[]string{
+			"domain golang.org",
+			"nameserver 8.8.8.8",
+			"nameserver 2001:4860:4860::8888",
+		},
+		nil,
+		false, true,
+	},
+	{
+		"ipv6.google.com",
+		[]string{
+			"search x.golang.org y.golang.org",
+			"nameserver 8.8.8.8",
+			"nameserver 2001:4860:4860::8888",
+		},
+		nil,
+		false, true,
+	},
+
+	// both A and AAAA records
+	{
+		"hostname.as112.net", // see RFC 7534
+		[]string{
+			"domain golang.org",
+			"nameserver 2001:4860:4860::8888",
+			"nameserver 8.8.8.8",
+		},
+		nil,
+		true, true,
+	},
+	{
+		"hostname.as112.net", // see RFC 7534
+		[]string{
+			"search x.golang.org y.golang.org",
+			"nameserver 2001:4860:4860::8888",
+			"nameserver 8.8.8.8",
+		},
+		nil,
+		true, true,
+	},
+}
+
+func TestGoLookupIPWithResolverConfig(t *testing.T) {
 	if testing.Short() || !*testExternal {
-		t.Skip("skipping test to avoid external network")
+		t.Skip("avoid external network")
 	}
 
-	r := newResolvConfTest(t)
-	defer r.Close()
-
-	r.SetConf("nameserver 8.8.8.8")
-	r.Start()
-
-	if _, err := goLookupIP("golang.org"); err != nil {
-		t.Fatalf("goLookupIP(good) failed: %v", err)
+	conf, err := newResolvConfTest()
+	if err != nil {
+		t.Fatal(err)
 	}
-	r.WantServers([]string{"8.8.8.8"})
+	defer conf.teardown()
 
-	// Using a bad resolv.conf when we had a good one
-	// before should not update the config
-	r.SetConf("")
-	if _, err := goLookupIP("golang.org"); err != nil {
-		t.Fatalf("goLookupIP(good; bad) failed: %v", err)
+	for _, tt := range goLookupIPWithResolverConfigTests {
+		if err := conf.writeAndUpdate(tt.lines); err != nil {
+			t.Error(err)
+			continue
+		}
+		conf.tryUpdate(conf.path)
+		addrs, err := goLookupIP(tt.name)
+		if err != nil {
+			if err, ok := err.(*DNSError); !ok || (err.Name != tt.error.(*DNSError).Name || err.Server != tt.error.(*DNSError).Server || err.IsTimeout != tt.error.(*DNSError).IsTimeout) {
+				t.Errorf("got %v; want %v", err, tt.error)
+			}
+			continue
+		}
+		if len(addrs) == 0 {
+			t.Errorf("no records for %s", tt.name)
+		}
+		if !tt.a && !tt.aaaa && len(addrs) > 0 {
+			t.Errorf("unexpected %v for %s", addrs, tt.name)
+		}
+		for _, addr := range addrs {
+			if !tt.a && addr.IP.To4() != nil {
+				t.Errorf("got %v; must not be IPv4 address", addr)
+			}
+			if !tt.aaaa && addr.IP.To16() != nil && addr.IP.To4() == nil {
+				t.Errorf("got %v; must not be IPv6 address", addr)
+			}
+		}
 	}
-
-	// A new good config should get picked up
-	r.SetConf("nameserver 8.8.4.4")
-	r.WantServers([]string{"8.8.4.4"})
 }
 
 func BenchmarkGoLookupIP(b *testing.B) {
+	testHookUninstaller.Do(uninstallTestHooks)
+
 	for i := 0; i < b.N; i++ {
 		goLookupIP("www.example.com")
 	}
 }
 
 func BenchmarkGoLookupIPNoSuchHost(b *testing.B) {
+	testHookUninstaller.Do(uninstallTestHooks)
+
 	for i := 0; i < b.N; i++ {
 		goLookupIP("some.nonexistent")
 	}
 }
 
 func BenchmarkGoLookupIPWithBrokenNameServer(b *testing.B) {
-	onceLoadConfig.Do(loadDefaultConfig)
-	if cfg.dnserr != nil || cfg.dnsConfig == nil {
-		b.Fatalf("loadConfig failed: %v", cfg.dnserr)
+	testHookUninstaller.Do(uninstallTestHooks)
+
+	conf, err := newResolvConfTest()
+	if err != nil {
+		b.Fatal(err)
 	}
-	// This looks ugly but it's safe as long as benchmarks are run
-	// sequentially in package testing.
-	orig := cfg.dnsConfig
-	cfg.dnsConfig.servers = append([]string{"203.0.113.254"}, cfg.dnsConfig.servers...) // use TEST-NET-3 block, see RFC 5737
+	defer conf.teardown()
+
+	lines := []string{
+		"nameserver 203.0.113.254", // use TEST-NET-3 block, see RFC 5737
+		"nameserver 8.8.8.8",
+	}
+	if err := conf.writeAndUpdate(lines); err != nil {
+		b.Fatal(err)
+	}
+
 	for i := 0; i < b.N; i++ {
 		goLookupIP("www.example.com")
 	}
-	cfg.dnsConfig = orig
 }
diff --git a/third_party/gofrontend/libgo/go/net/dnsconfig_unix.go b/third_party/gofrontend/libgo/go/net/dnsconfig_unix.go
index 66ab7c4..6073fdb 100644
--- a/third_party/gofrontend/libgo/go/net/dnsconfig_unix.go
+++ b/third_party/gofrontend/libgo/go/net/dnsconfig_unix.go
@@ -8,30 +8,41 @@
 
 package net
 
+var defaultNS = []string{"127.0.0.1", "::1"}
+
 type dnsConfig struct {
-	servers  []string // servers to use
-	search   []string // suffixes to append to local name
-	ndots    int      // number of dots in name to trigger absolute lookup
-	timeout  int      // seconds before giving up on packet
-	attempts int      // lost packets before giving up on server
-	rotate   bool     // round robin among servers
+	servers    []string // servers to use
+	search     []string // suffixes to append to local name
+	ndots      int      // number of dots in name to trigger absolute lookup
+	timeout    int      // seconds before giving up on packet
+	attempts   int      // lost packets before giving up on server
+	rotate     bool     // round robin among servers
+	unknownOpt bool     // anything unknown was encountered
+	lookup     []string // OpenBSD top-level database "lookup" order
+	err        error    // any error that occurs during open of resolv.conf
 }
 
 // See resolv.conf(5) on a Linux machine.
 // TODO(rsc): Supposed to call uname() and chop the beginning
 // of the host name to get the default search domain.
-func dnsReadConfig(filename string) (*dnsConfig, error) {
-	file, err := open(filename)
-	if err != nil {
-		return nil, &DNSConfigError{err}
-	}
-	defer file.close()
+func dnsReadConfig(filename string) *dnsConfig {
 	conf := &dnsConfig{
 		ndots:    1,
 		timeout:  5,
 		attempts: 2,
 	}
+	file, err := open(filename)
+	if err != nil {
+		conf.servers = defaultNS
+		conf.err = err
+		return conf
+	}
+	defer file.close()
 	for line, ok := file.readLine(); ok; line, ok = file.readLine() {
+		if len(line) > 0 && (line[0] == ';' || line[0] == '#') {
+			// comment.
+			continue
+		}
 		f := getFields(line)
 		if len(f) < 1 {
 			continue
@@ -61,8 +72,7 @@
 			}
 
 		case "options": // magic options
-			for i := 1; i < len(f); i++ {
-				s := f[i]
+			for _, s := range f[1:] {
 				switch {
 				case hasPrefix(s, "ndots:"):
 					n, _, _ := dtoi(s, 6)
@@ -84,11 +94,25 @@
 					conf.attempts = n
 				case s == "rotate":
 					conf.rotate = true
+				default:
+					conf.unknownOpt = true
 				}
 			}
+
+		case "lookup":
+			// OpenBSD option:
+			// http://www.openbsd.org/cgi-bin/man.cgi/OpenBSD-current/man5/resolv.conf.5
+			// "the legal space-separated values are: bind, file, yp"
+			conf.lookup = f[1:]
+
+		default:
+			conf.unknownOpt = true
 		}
 	}
-	return conf, nil
+	if len(conf.servers) == 0 {
+		conf.servers = defaultNS
+	}
+	return conf
 }
 
 func hasPrefix(s, prefix string) bool {
diff --git a/third_party/gofrontend/libgo/go/net/dnsconfig_unix_test.go b/third_party/gofrontend/libgo/go/net/dnsconfig_unix_test.go
index 94fb0c3..c8eed61 100644
--- a/third_party/gofrontend/libgo/go/net/dnsconfig_unix_test.go
+++ b/third_party/gofrontend/libgo/go/net/dnsconfig_unix_test.go
@@ -7,28 +7,30 @@
 package net
 
 import (
+	"os"
 	"reflect"
 	"testing"
 )
 
 var dnsReadConfigTests = []struct {
 	name string
-	conf dnsConfig
+	want *dnsConfig
 }{
 	{
 		name: "testdata/resolv.conf",
-		conf: dnsConfig{
-			servers:  []string{"8.8.8.8", "2001:4860:4860::8888", "fe80::1%lo0"},
-			search:   []string{"localdomain"},
-			ndots:    5,
-			timeout:  10,
-			attempts: 3,
-			rotate:   true,
+		want: &dnsConfig{
+			servers:    []string{"8.8.8.8", "2001:4860:4860::8888", "fe80::1%lo0"},
+			search:     []string{"localdomain"},
+			ndots:      5,
+			timeout:    10,
+			attempts:   3,
+			rotate:     true,
+			unknownOpt: true, // the "options attempts 3" line
 		},
 	},
 	{
 		name: "testdata/domain-resolv.conf",
-		conf: dnsConfig{
+		want: &dnsConfig{
 			servers:  []string{"8.8.8.8"},
 			search:   []string{"localdomain"},
 			ndots:    1,
@@ -38,7 +40,7 @@
 	},
 	{
 		name: "testdata/search-resolv.conf",
-		conf: dnsConfig{
+		want: &dnsConfig{
 			servers:  []string{"8.8.8.8"},
 			search:   []string{"test", "invalid"},
 			ndots:    1,
@@ -48,22 +50,51 @@
 	},
 	{
 		name: "testdata/empty-resolv.conf",
-		conf: dnsConfig{
+		want: &dnsConfig{
+			servers:  defaultNS,
 			ndots:    1,
 			timeout:  5,
 			attempts: 2,
 		},
 	},
+	{
+		name: "testdata/openbsd-resolv.conf",
+		want: &dnsConfig{
+			ndots:    1,
+			timeout:  5,
+			attempts: 2,
+			lookup:   []string{"file", "bind"},
+			servers:  []string{"169.254.169.254", "10.240.0.1"},
+			search:   []string{"c.symbolic-datum-552.internal."},
+		},
+	},
 }
 
 func TestDNSReadConfig(t *testing.T) {
 	for _, tt := range dnsReadConfigTests {
-		conf, err := dnsReadConfig(tt.name)
-		if err != nil {
-			t.Fatal(err)
+		conf := dnsReadConfig(tt.name)
+		if conf.err != nil {
+			t.Fatal(conf.err)
 		}
-		if !reflect.DeepEqual(conf, &tt.conf) {
-			t.Errorf("got %v; want %v", conf, &tt.conf)
+		if !reflect.DeepEqual(conf, tt.want) {
+			t.Errorf("%s:\ngot: %+v\nwant: %+v", tt.name, conf, tt.want)
 		}
 	}
 }
+
+func TestDNSReadMissingFile(t *testing.T) {
+	conf := dnsReadConfig("a-nonexistent-file")
+	if !os.IsNotExist(conf.err) {
+		t.Errorf("missing resolv.conf:\ngot: %v\nwant: %v", conf.err, os.ErrNotExist)
+	}
+	conf.err = nil
+	want := &dnsConfig{
+		servers:  defaultNS,
+		ndots:    1,
+		timeout:  5,
+		attempts: 2,
+	}
+	if !reflect.DeepEqual(conf, want) {
+		t.Errorf("missing resolv.conf:\ngot: %+v\nwant: %+v", conf, want)
+	}
+}
diff --git a/third_party/gofrontend/libgo/go/net/dnsmsg.go b/third_party/gofrontend/libgo/go/net/dnsmsg.go
index 161afb2..6ecaa94 100644
--- a/third_party/gofrontend/libgo/go/net/dnsmsg.go
+++ b/third_party/gofrontend/libgo/go/net/dnsmsg.go
@@ -306,7 +306,23 @@
 }
 
 func (rr *dnsRR_TXT) Walk(f func(v interface{}, name, tag string) bool) bool {
-	return rr.Hdr.Walk(f) && f(&rr.Txt, "Txt", "")
+	if !rr.Hdr.Walk(f) {
+		return false
+	}
+	var n uint16 = 0
+	for n < rr.Hdr.Rdlength {
+		var txt string
+		if !f(&txt, "Txt", "") {
+			return false
+		}
+		// more bytes than rr.Hdr.Rdlength said there woudld be
+		if rr.Hdr.Rdlength-n < uint16(len(txt))+1 {
+			return false
+		}
+		n += uint16(len(txt)) + 1
+		rr.Txt += txt
+	}
+	return true
 }
 
 type dnsRR_SRV struct {
diff --git a/third_party/gofrontend/libgo/go/net/dnsmsg_test.go b/third_party/gofrontend/libgo/go/net/dnsmsg_test.go
index c39dbdb..1078d77 100644
--- a/third_party/gofrontend/libgo/go/net/dnsmsg_test.go
+++ b/third_party/gofrontend/libgo/go/net/dnsmsg_test.go
@@ -18,7 +18,7 @@
 	msg := new(dnsMsg)
 	ok := msg.Unpack(data)
 	if !ok {
-		t.Fatalf("unpacking packet failed")
+		t.Fatal("unpacking packet failed")
 	}
 	msg.String() // exercise this code path
 	if g, e := len(msg.answer), 5; g != e {
@@ -32,13 +32,19 @@
 			t.Errorf("answer[%d] = %T; want *dnsRR_SRV", idx, rr)
 		}
 	}
-	_, addrs, err := answer("_xmpp-server._tcp.google.com.", "foo:53", msg, uint16(dnsTypeSRV))
-	if err != nil {
-		t.Fatalf("answer: %v", err)
-	}
-	if g, e := len(addrs), 5; g != e {
-		t.Errorf("len(addrs) = %d; want %d", g, e)
-		t.Logf("addrs = %#v", addrs)
+	for _, name := range [...]string{
+		"_xmpp-server._tcp.google.com.",
+		"_XMPP-Server._TCP.Google.COM.",
+		"_XMPP-SERVER._TCP.GOOGLE.COM.",
+	} {
+		_, addrs, err := answer(name, "foo:53", msg, uint16(dnsTypeSRV))
+		if err != nil {
+			t.Error(err)
+		}
+		if g, e := len(addrs), 5; g != e {
+			t.Errorf("len(addrs) = %d; want %d", g, e)
+			t.Logf("addrs = %#v", addrs)
+		}
 	}
 	// repack and unpack.
 	data2, ok := msg.Pack()
@@ -46,9 +52,9 @@
 	msg2.Unpack(data2)
 	switch {
 	case !ok:
-		t.Errorf("failed to repack message")
+		t.Error("failed to repack message")
 	case !reflect.DeepEqual(msg, msg2):
-		t.Errorf("repacked message differs from original")
+		t.Error("repacked message differs from original")
 	}
 }
 
@@ -60,7 +66,7 @@
 	msg := new(dnsMsg)
 	ok := msg.Unpack(data)
 	if !ok {
-		t.Fatalf("unpacking packet failed")
+		t.Fatal("unpacking packet failed")
 	}
 	msg.String() // exercise this code path
 	if g, e := len(msg.answer), 5; g != e {
@@ -90,6 +96,93 @@
 	}
 }
 
+func TestDNSParseTXTReply(t *testing.T) {
+	expectedTxt1 := "v=spf1 redirect=_spf.google.com"
+	expectedTxt2 := "v=spf1 ip4:69.63.179.25 ip4:69.63.178.128/25 ip4:69.63.184.0/25 " +
+		"ip4:66.220.144.128/25 ip4:66.220.155.0/24 " +
+		"ip4:69.171.232.0/25 ip4:66.220.157.0/25 " +
+		"ip4:69.171.244.0/24 mx -all"
+
+	replies := []string{dnsTXTReply1, dnsTXTReply2}
+	expectedTxts := []string{expectedTxt1, expectedTxt2}
+
+	for i := range replies {
+		data, err := hex.DecodeString(replies[i])
+		if err != nil {
+			t.Fatal(err)
+		}
+
+		msg := new(dnsMsg)
+		ok := msg.Unpack(data)
+		if !ok {
+			t.Errorf("test %d: unpacking packet failed", i)
+			continue
+		}
+
+		if len(msg.answer) != 1 {
+			t.Errorf("test %d: len(rr.answer) = %d; want 1", i, len(msg.answer))
+			continue
+		}
+
+		rr := msg.answer[0]
+		rrTXT, ok := rr.(*dnsRR_TXT)
+		if !ok {
+			t.Errorf("test %d: answer[0] = %T; want *dnsRR_TXT", i, rr)
+			continue
+		}
+
+		if rrTXT.Txt != expectedTxts[i] {
+			t.Errorf("test %d: Txt = %s; want %s", i, rrTXT.Txt, expectedTxts[i])
+		}
+	}
+}
+
+func TestDNSParseTXTCorruptDataLengthReply(t *testing.T) {
+	replies := []string{dnsTXTCorruptDataLengthReply1, dnsTXTCorruptDataLengthReply2}
+
+	for i := range replies {
+		data, err := hex.DecodeString(replies[i])
+		if err != nil {
+			t.Fatal(err)
+		}
+
+		msg := new(dnsMsg)
+		ok := msg.Unpack(data)
+		if ok {
+			t.Errorf("test %d: expected to fail on unpacking corrupt packet", i)
+		}
+	}
+}
+
+func TestDNSParseTXTCorruptTXTLengthReply(t *testing.T) {
+	replies := []string{dnsTXTCorruptTXTLengthReply1, dnsTXTCorruptTXTLengthReply2}
+
+	for i := range replies {
+		data, err := hex.DecodeString(replies[i])
+		if err != nil {
+			t.Fatal(err)
+		}
+
+		msg := new(dnsMsg)
+		ok := msg.Unpack(data)
+		// Unpacking should succeed, but we should just get the header.
+		if !ok {
+			t.Errorf("test %d: unpacking packet failed", i)
+			continue
+		}
+
+		if len(msg.answer) != 1 {
+			t.Errorf("test %d: len(rr.answer) = %d; want 1", i, len(msg.answer))
+			continue
+		}
+
+		rr := msg.answer[0]
+		if _, justHeader := rr.(*dnsRR_Header); !justHeader {
+			t.Errorf("test %d: rr = %T; expected *dnsRR_Header", i, rr)
+		}
+	}
+}
+
 // Valid DNS SRV reply
 const dnsSRVReply = "0901818000010005000000000c5f786d70702d736572766572045f74637006676f6f67" +
 	"6c6503636f6d0000210001c00c002100010000012c00210014000014950c786d70702d" +
@@ -111,3 +204,63 @@
 	"6503636f6d00c00c002100010000012c00200005000014950b786d70702d7365727665" +
 	"72016c06676f6f676c6503636f6d00c00c002100010000012c00FF0014000014950c78" +
 	"6d70702d73657276657231016c06676f6f676c6503636f6d00"
+
+// TXT reply with one <character-string>
+const dnsTXTReply1 = "b3458180000100010004000505676d61696c03636f6d0000100001c00c001000010000012c00" +
+	"201f763d737066312072656469726563743d5f7370662e676f6f676c652e636f6dc00" +
+	"c0002000100025d4c000d036e733406676f6f676c65c012c00c0002000100025d4c00" +
+	"06036e7331c057c00c0002000100025d4c0006036e7333c057c00c0002000100025d4" +
+	"c0006036e7332c057c06c00010001000248b50004d8ef200ac09000010001000248b5" +
+	"0004d8ef220ac07e00010001000248b50004d8ef240ac05300010001000248b50004d" +
+	"8ef260a0000291000000000000000"
+
+// TXT reply with more than one <character-string>.
+// See https://tools.ietf.org/html/rfc1035#section-3.3.14
+const dnsTXTReply2 = "a0a381800001000100020002045f7370660866616365626f6f6b03636f6d0000100001c00c0010000" +
+	"100000e1000af7f763d73706631206970343a36392e36332e3137392e3235206970343a36392e" +
+	"36332e3137382e3132382f3235206970343a36392e36332e3138342e302f3235206970343a363" +
+	"62e3232302e3134342e3132382f3235206970343a36362e3232302e3135352e302f3234206970" +
+	"343a36392e3137312e3233322e302f323520692e70343a36362e3232302e3135372e302f32352" +
+	"06970343a36392e3137312e3234342e302f3234206d78202d616c6cc0110002000100025d1500" +
+	"070161026e73c011c0110002000100025d1500040162c0ecc0ea0001000100025d15000445abe" +
+	"f0cc0fd0001000100025d15000445abff0c"
+
+// DataLength field should be sum of all TXT fields. In this case it's less.
+const dnsTXTCorruptDataLengthReply1 = "a0a381800001000100020002045f7370660866616365626f6f6b03636f6d0000100001c00c0010000" +
+	"100000e1000967f763d73706631206970343a36392e36332e3137392e3235206970343a36392e" +
+	"36332e3137382e3132382f3235206970343a36392e36332e3138342e302f3235206970343a363" +
+	"62e3232302e3134342e3132382f3235206970343a36362e3232302e3135352e302f3234206970" +
+	"343a36392e3137312e3233322e302f323520692e70343a36362e3232302e3135372e302f32352" +
+	"06970343a36392e3137312e3234342e302f3234206d78202d616c6cc0110002000100025d1500" +
+	"070161026e73c011c0110002000100025d1500040162c0ecc0ea0001000100025d15000445abe" +
+	"f0cc0fd0001000100025d15000445abff0c"
+
+// Same as above but DataLength is more than sum of TXT fields.
+const dnsTXTCorruptDataLengthReply2 = "a0a381800001000100020002045f7370660866616365626f6f6b03636f6d0000100001c00c0010000" +
+	"100000e1001227f763d73706631206970343a36392e36332e3137392e3235206970343a36392e" +
+	"36332e3137382e3132382f3235206970343a36392e36332e3138342e302f3235206970343a363" +
+	"62e3232302e3134342e3132382f3235206970343a36362e3232302e3135352e302f3234206970" +
+	"343a36392e3137312e3233322e302f323520692e70343a36362e3232302e3135372e302f32352" +
+	"06970343a36392e3137312e3234342e302f3234206d78202d616c6cc0110002000100025d1500" +
+	"070161026e73c011c0110002000100025d1500040162c0ecc0ea0001000100025d15000445abe" +
+	"f0cc0fd0001000100025d15000445abff0c"
+
+// TXT Length field is less than actual length.
+const dnsTXTCorruptTXTLengthReply1 = "a0a381800001000100020002045f7370660866616365626f6f6b03636f6d0000100001c00c0010000" +
+	"100000e1000af7f763d73706631206970343a36392e36332e3137392e3235206970343a36392e" +
+	"36332e3137382e3132382f3235206970343a36392e36332e3138342e302f3235206970343a363" +
+	"62e3232302e3134342e3132382f3235206970343a36362e3232302e3135352e302f3234206970" +
+	"343a36392e3137312e3233322e302f323520691470343a36362e3232302e3135372e302f32352" +
+	"06970343a36392e3137312e3234342e302f3234206d78202d616c6cc0110002000100025d1500" +
+	"070161026e73c011c0110002000100025d1500040162c0ecc0ea0001000100025d15000445abe" +
+	"f0cc0fd0001000100025d15000445abff0c"
+
+// TXT Length field is more than actual length.
+const dnsTXTCorruptTXTLengthReply2 = "a0a381800001000100020002045f7370660866616365626f6f6b03636f6d0000100001c00c0010000" +
+	"100000e1000af7f763d73706631206970343a36392e36332e3137392e3235206970343a36392e" +
+	"36332e3137382e3132382f3235206970343a36392e36332e3138342e302f3235206970343a363" +
+	"62e3232302e3134342e3132382f3235206970343a36362e3232302e3135352e302f3234206970" +
+	"343a36392e3137312e3233322e302f323520693370343a36362e3232302e3135372e302f32352" +
+	"06970343a36392e3137312e3234342e302f3234206d78202d616c6cc0110002000100025d1500" +
+	"070161026e73c011c0110002000100025d1500040162c0ecc0ea0001000100025d15000445abe" +
+	"f0cc0fd0001000100025d15000445abff0c"
diff --git a/third_party/gofrontend/libgo/go/net/dnsname_test.go b/third_party/gofrontend/libgo/go/net/dnsname_test.go
index 57dd25f..be07dc6 100644
--- a/third_party/gofrontend/libgo/go/net/dnsname_test.go
+++ b/third_party/gofrontend/libgo/go/net/dnsname_test.go
@@ -9,12 +9,12 @@
 	"testing"
 )
 
-type testCase struct {
+type dnsNameTest struct {
 	name   string
 	result bool
 }
 
-var tests = []testCase{
+var dnsNameTests = []dnsNameTest{
 	// RFC2181, section 11.
 	{"_xmpp-server._tcp.google.com", true},
 	{"foo.com", true},
@@ -30,7 +30,7 @@
 	{"b.com.", true},
 }
 
-func getTestCases(ch chan<- testCase) {
+func emitDNSNameTest(ch chan<- dnsNameTest) {
 	defer close(ch)
 	var char59 = ""
 	var char63 = ""
@@ -41,35 +41,36 @@
 	char63 = char59 + "aaaa"
 	char64 = char63 + "a"
 
-	for _, tc := range tests {
+	for _, tc := range dnsNameTests {
 		ch <- tc
 	}
 
-	ch <- testCase{char63 + ".com", true}
-	ch <- testCase{char64 + ".com", false}
+	ch <- dnsNameTest{char63 + ".com", true}
+	ch <- dnsNameTest{char64 + ".com", false}
 	// 255 char name is fine:
-	ch <- testCase{char59 + "." + char63 + "." + char63 + "." +
+	ch <- dnsNameTest{char59 + "." + char63 + "." + char63 + "." +
 		char63 + ".com",
 		true}
 	// 256 char name is bad:
-	ch <- testCase{char59 + "a." + char63 + "." + char63 + "." +
+	ch <- dnsNameTest{char59 + "a." + char63 + "." + char63 + "." +
 		char63 + ".com",
 		false}
 }
 
-func TestDNSNames(t *testing.T) {
-	ch := make(chan testCase)
-	go getTestCases(ch)
+func TestDNSName(t *testing.T) {
+	ch := make(chan dnsNameTest)
+	go emitDNSNameTest(ch)
 	for tc := range ch {
 		if isDomainName(tc.name) != tc.result {
-			t.Errorf("isDomainName(%v) failed: Should be %v",
-				tc.name, tc.result)
+			t.Errorf("isDomainName(%q) = %v; want %v", tc.name, !tc.result, tc.result)
 		}
 	}
 }
 
-func BenchmarkDNSNames(b *testing.B) {
-	benchmarks := append(tests, []testCase{
+func BenchmarkDNSName(b *testing.B) {
+	testHookUninstaller.Do(uninstallTestHooks)
+
+	benchmarks := append(dnsNameTests, []dnsNameTest{
 		{strings.Repeat("a", 63), true},
 		{strings.Repeat("a", 64), false},
 	}...)
diff --git a/third_party/gofrontend/libgo/go/net/error_plan9_test.go b/third_party/gofrontend/libgo/go/net/error_plan9_test.go
new file mode 100644
index 0000000..495ea96
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/net/error_plan9_test.go
@@ -0,0 +1,17 @@
+// 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 net
+
+import "syscall"
+
+var (
+	errTimedout       = syscall.ETIMEDOUT
+	errOpNotSupported = syscall.EPLAN9
+)
+
+func isPlatformError(err error) bool {
+	_, ok := err.(syscall.ErrorString)
+	return ok
+}
diff --git a/third_party/gofrontend/libgo/go/net/error_posix_test.go b/third_party/gofrontend/libgo/go/net/error_posix_test.go
new file mode 100644
index 0000000..981cc83
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/net/error_posix_test.go
@@ -0,0 +1,44 @@
+// 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 !plan9
+
+package net
+
+import (
+	"os"
+	"syscall"
+	"testing"
+)
+
+var (
+	errTimedout       = syscall.ETIMEDOUT
+	errOpNotSupported = syscall.EOPNOTSUPP
+)
+
+func isPlatformError(err error) bool {
+	_, ok := err.(syscall.Errno)
+	return ok
+}
+
+func TestSpuriousENOTAVAIL(t *testing.T) {
+	for _, tt := range []struct {
+		error
+		ok bool
+	}{
+		{syscall.EADDRNOTAVAIL, true},
+		{&os.SyscallError{Syscall: "syscall", Err: syscall.EADDRNOTAVAIL}, true},
+		{&OpError{Op: "op", Err: syscall.EADDRNOTAVAIL}, true},
+		{&OpError{Op: "op", Err: &os.SyscallError{Syscall: "syscall", Err: syscall.EADDRNOTAVAIL}}, true},
+
+		{syscall.EINVAL, false},
+		{&os.SyscallError{Syscall: "syscall", Err: syscall.EINVAL}, false},
+		{&OpError{Op: "op", Err: syscall.EINVAL}, false},
+		{&OpError{Op: "op", Err: &os.SyscallError{Syscall: "syscall", Err: syscall.EINVAL}}, false},
+	} {
+		if ok := spuriousENOTAVAIL(tt.error); ok != tt.ok {
+			t.Errorf("spuriousENOTAVAIL(%v) = %v; want %v", tt.error, ok, tt.ok)
+		}
+	}
+}
diff --git a/third_party/gofrontend/libgo/go/net/error_test.go b/third_party/gofrontend/libgo/go/net/error_test.go
new file mode 100644
index 0000000..bf95ff6
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/net/error_test.go
@@ -0,0 +1,673 @@
+// 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 net
+
+import (
+	"fmt"
+	"io"
+	"io/ioutil"
+	"net/internal/socktest"
+	"os"
+	"runtime"
+	"testing"
+	"time"
+)
+
+func (e *OpError) isValid() error {
+	if e.Op == "" {
+		return fmt.Errorf("OpError.Op is empty: %v", e)
+	}
+	if e.Net == "" {
+		return fmt.Errorf("OpError.Net is empty: %v", e)
+	}
+	for _, addr := range []Addr{e.Source, e.Addr} {
+		switch addr := addr.(type) {
+		case nil:
+		case *TCPAddr:
+			if addr == nil {
+				return fmt.Errorf("OpError.Source or Addr is non-nil interface: %#v, %v", addr, e)
+			}
+		case *UDPAddr:
+			if addr == nil {
+				return fmt.Errorf("OpError.Source or Addr is non-nil interface: %#v, %v", addr, e)
+			}
+		case *IPAddr:
+			if addr == nil {
+				return fmt.Errorf("OpError.Source or Addr is non-nil interface: %#v, %v", addr, e)
+			}
+		case *IPNet:
+			if addr == nil {
+				return fmt.Errorf("OpError.Source or Addr is non-nil interface: %#v, %v", addr, e)
+			}
+		case *UnixAddr:
+			if addr == nil {
+				return fmt.Errorf("OpError.Source or Addr is non-nil interface: %#v, %v", addr, e)
+			}
+		case *pipeAddr:
+			if addr == nil {
+				return fmt.Errorf("OpError.Source or Addr is non-nil interface: %#v, %v", addr, e)
+			}
+		case fileAddr:
+			if addr == "" {
+				return fmt.Errorf("OpError.Source or Addr is empty: %#v, %v", addr, e)
+			}
+		default:
+			return fmt.Errorf("OpError.Source or Addr is unknown type: %T, %v", addr, e)
+		}
+	}
+	if e.Err == nil {
+		return fmt.Errorf("OpError.Err is empty: %v", e)
+	}
+	return nil
+}
+
+// parseDialError parses nestedErr and reports whether it is a valid
+// error value from Dial, Listen functions.
+// It returns nil when nestedErr is valid.
+func parseDialError(nestedErr error) error {
+	if nestedErr == nil {
+		return nil
+	}
+
+	switch err := nestedErr.(type) {
+	case *OpError:
+		if err := err.isValid(); err != nil {
+			return err
+		}
+		nestedErr = err.Err
+		goto second
+	}
+	return fmt.Errorf("unexpected type on 1st nested level: %T", nestedErr)
+
+second:
+	if isPlatformError(nestedErr) {
+		return nil
+	}
+	switch err := nestedErr.(type) {
+	case *AddrError, addrinfoErrno, *DNSError, InvalidAddrError, *ParseError, *timeoutError, UnknownNetworkError:
+		return nil
+	case *os.SyscallError:
+		nestedErr = err.Err
+		goto third
+	}
+	switch nestedErr {
+	case errClosing, errMissingAddress:
+		return nil
+	}
+	return fmt.Errorf("unexpected type on 2nd nested level: %T", nestedErr)
+
+third:
+	if isPlatformError(nestedErr) {
+		return nil
+	}
+	return fmt.Errorf("unexpected type on 3rd nested level: %T", nestedErr)
+}
+
+var dialErrorTests = []struct {
+	network, address string
+}{
+	{"foo", ""},
+	{"bar", "baz"},
+	{"datakit", "mh/astro/r70"},
+	{"tcp", ""},
+	{"tcp", "127.0.0.1:☺"},
+	{"tcp", "no-such-name:80"},
+	{"tcp", "mh/astro/r70:http"},
+
+	{"tcp", "127.0.0.1:0"},
+	{"udp", "127.0.0.1:0"},
+	{"ip:icmp", "127.0.0.1"},
+
+	{"unix", "/path/to/somewhere"},
+	{"unixgram", "/path/to/somewhere"},
+	{"unixpacket", "/path/to/somewhere"},
+}
+
+func TestDialError(t *testing.T) {
+	switch runtime.GOOS {
+	case "plan9":
+		t.Skipf("%s does not have full support of socktest", runtime.GOOS)
+	}
+
+	origTestHookLookupIP := testHookLookupIP
+	defer func() { testHookLookupIP = origTestHookLookupIP }()
+	testHookLookupIP = func(fn func(string) ([]IPAddr, error), host string) ([]IPAddr, error) {
+		return nil, &DNSError{Err: "dial error test", Name: "name", Server: "server", IsTimeout: true}
+	}
+	sw.Set(socktest.FilterConnect, func(so *socktest.Status) (socktest.AfterFilter, error) {
+		return nil, errOpNotSupported
+	})
+	defer sw.Set(socktest.FilterConnect, nil)
+
+	d := Dialer{Timeout: someTimeout}
+	for i, tt := range dialErrorTests {
+		c, err := d.Dial(tt.network, tt.address)
+		if err == nil {
+			t.Errorf("#%d: should fail; %s:%s->%s", i, tt.network, c.LocalAddr(), c.RemoteAddr())
+			c.Close()
+			continue
+		}
+		if c != nil {
+			t.Errorf("Dial returned non-nil interface %T(%v) with err != nil", c, c)
+		}
+		if err = parseDialError(err); err != nil {
+			t.Errorf("#%d: %v", i, err)
+			continue
+		}
+	}
+}
+
+func TestProtocolDialError(t *testing.T) {
+	switch runtime.GOOS {
+	case "nacl", "solaris":
+		t.Skipf("not supported on %s", runtime.GOOS)
+	}
+
+	for _, network := range []string{"tcp", "udp", "ip:4294967296", "unix", "unixpacket", "unixgram"} {
+		var err error
+		switch network {
+		case "tcp":
+			_, err = DialTCP(network, nil, &TCPAddr{Port: 1 << 16})
+		case "udp":
+			_, err = DialUDP(network, nil, &UDPAddr{Port: 1 << 16})
+		case "ip:4294967296":
+			_, err = DialIP(network, nil, nil)
+		case "unix", "unixpacket", "unixgram":
+			_, err = DialUnix(network, nil, &UnixAddr{Name: "//"})
+		}
+		if err == nil {
+			t.Errorf("%s: should fail", network)
+			continue
+		}
+		if err = parseDialError(err); err != nil {
+			t.Errorf("%s: %v", network, err)
+			continue
+		}
+	}
+}
+
+var listenErrorTests = []struct {
+	network, address string
+}{
+	{"foo", ""},
+	{"bar", "baz"},
+	{"datakit", "mh/astro/r70"},
+	{"tcp", "127.0.0.1:☺"},
+	{"tcp", "no-such-name:80"},
+	{"tcp", "mh/astro/r70:http"},
+
+	{"tcp", "127.0.0.1:0"},
+
+	{"unix", "/path/to/somewhere"},
+	{"unixpacket", "/path/to/somewhere"},
+}
+
+func TestListenError(t *testing.T) {
+	switch runtime.GOOS {
+	case "plan9":
+		t.Skipf("%s does not have full support of socktest", runtime.GOOS)
+	}
+
+	origTestHookLookupIP := testHookLookupIP
+	defer func() { testHookLookupIP = origTestHookLookupIP }()
+	testHookLookupIP = func(fn func(string) ([]IPAddr, error), host string) ([]IPAddr, error) {
+		return nil, &DNSError{Err: "listen error test", Name: "name", Server: "server", IsTimeout: true}
+	}
+	sw.Set(socktest.FilterListen, func(so *socktest.Status) (socktest.AfterFilter, error) {
+		return nil, errOpNotSupported
+	})
+	defer sw.Set(socktest.FilterListen, nil)
+
+	for i, tt := range listenErrorTests {
+		ln, err := Listen(tt.network, tt.address)
+		if err == nil {
+			t.Errorf("#%d: should fail; %s:%s->", i, tt.network, ln.Addr())
+			ln.Close()
+			continue
+		}
+		if ln != nil {
+			t.Errorf("Listen returned non-nil interface %T(%v) with err != nil", ln, ln)
+		}
+		if err = parseDialError(err); err != nil {
+			t.Errorf("#%d: %v", i, err)
+			continue
+		}
+	}
+}
+
+var listenPacketErrorTests = []struct {
+	network, address string
+}{
+	{"foo", ""},
+	{"bar", "baz"},
+	{"datakit", "mh/astro/r70"},
+	{"udp", "127.0.0.1:☺"},
+	{"udp", "no-such-name:80"},
+	{"udp", "mh/astro/r70:http"},
+}
+
+func TestListenPacketError(t *testing.T) {
+	switch runtime.GOOS {
+	case "plan9":
+		t.Skipf("%s does not have full support of socktest", runtime.GOOS)
+	}
+
+	origTestHookLookupIP := testHookLookupIP
+	defer func() { testHookLookupIP = origTestHookLookupIP }()
+	testHookLookupIP = func(fn func(string) ([]IPAddr, error), host string) ([]IPAddr, error) {
+		return nil, &DNSError{Err: "listen error test", Name: "name", Server: "server", IsTimeout: true}
+	}
+
+	for i, tt := range listenPacketErrorTests {
+		c, err := ListenPacket(tt.network, tt.address)
+		if err == nil {
+			t.Errorf("#%d: should fail; %s:%s->", i, tt.network, c.LocalAddr())
+			c.Close()
+			continue
+		}
+		if c != nil {
+			t.Errorf("ListenPacket returned non-nil interface %T(%v) with err != nil", c, c)
+		}
+		if err = parseDialError(err); err != nil {
+			t.Errorf("#%d: %v", i, err)
+			continue
+		}
+	}
+}
+
+func TestProtocolListenError(t *testing.T) {
+	switch runtime.GOOS {
+	case "nacl", "plan9":
+		t.Skipf("not supported on %s", runtime.GOOS)
+	}
+
+	for _, network := range []string{"tcp", "udp", "ip:4294967296", "unix", "unixpacket", "unixgram"} {
+		var err error
+		switch network {
+		case "tcp":
+			_, err = ListenTCP(network, &TCPAddr{Port: 1 << 16})
+		case "udp":
+			_, err = ListenUDP(network, &UDPAddr{Port: 1 << 16})
+		case "ip:4294967296":
+			_, err = ListenIP(network, nil)
+		case "unix", "unixpacket":
+			_, err = ListenUnix(network, &UnixAddr{Name: "//"})
+		case "unixgram":
+			_, err = ListenUnixgram(network, &UnixAddr{Name: "//"})
+		}
+		if err == nil {
+			t.Errorf("%s: should fail", network)
+			continue
+		}
+		if err = parseDialError(err); err != nil {
+			t.Errorf("%s: %v", network, err)
+			continue
+		}
+	}
+}
+
+// parseReadError parses nestedErr and reports whether it is a valid
+// error value from Read functions.
+// It returns nil when nestedErr is valid.
+func parseReadError(nestedErr error) error {
+	if nestedErr == nil {
+		return nil
+	}
+
+	switch err := nestedErr.(type) {
+	case *OpError:
+		if err := err.isValid(); err != nil {
+			return err
+		}
+		nestedErr = err.Err
+		goto second
+	}
+	if nestedErr == io.EOF {
+		return nil
+	}
+	return fmt.Errorf("unexpected type on 1st nested level: %T", nestedErr)
+
+second:
+	if isPlatformError(nestedErr) {
+		return nil
+	}
+	switch err := nestedErr.(type) {
+	case *os.SyscallError:
+		nestedErr = err.Err
+		goto third
+	}
+	switch nestedErr {
+	case errClosing, errTimeout:
+		return nil
+	}
+	return fmt.Errorf("unexpected type on 2nd nested level: %T", nestedErr)
+
+third:
+	if isPlatformError(nestedErr) {
+		return nil
+	}
+	return fmt.Errorf("unexpected type on 3rd nested level: %T", nestedErr)
+}
+
+// parseWriteError parses nestedErr and reports whether it is a valid
+// error value from Write functions.
+// It returns nil when nestedErr is valid.
+func parseWriteError(nestedErr error) error {
+	if nestedErr == nil {
+		return nil
+	}
+
+	switch err := nestedErr.(type) {
+	case *OpError:
+		if err := err.isValid(); err != nil {
+			return err
+		}
+		nestedErr = err.Err
+		goto second
+	}
+	return fmt.Errorf("unexpected type on 1st nested level: %T", nestedErr)
+
+second:
+	if isPlatformError(nestedErr) {
+		return nil
+	}
+	switch err := nestedErr.(type) {
+	case *AddrError, addrinfoErrno, *DNSError, InvalidAddrError, *ParseError, *timeoutError, UnknownNetworkError:
+		return nil
+	case *os.SyscallError:
+		nestedErr = err.Err
+		goto third
+	}
+	switch nestedErr {
+	case errClosing, errTimeout, ErrWriteToConnected, io.ErrUnexpectedEOF:
+		return nil
+	}
+	return fmt.Errorf("unexpected type on 2nd nested level: %T", nestedErr)
+
+third:
+	if isPlatformError(nestedErr) {
+		return nil
+	}
+	return fmt.Errorf("unexpected type on 3rd nested level: %T", nestedErr)
+}
+
+// parseCloseError parses nestedErr and reports whether it is a valid
+// error value from Close functions.
+// It returns nil when nestedErr is valid.
+func parseCloseError(nestedErr error) error {
+	if nestedErr == nil {
+		return nil
+	}
+
+	switch err := nestedErr.(type) {
+	case *OpError:
+		if err := err.isValid(); err != nil {
+			return err
+		}
+		nestedErr = err.Err
+		goto second
+	}
+	return fmt.Errorf("unexpected type on 1st nested level: %T", nestedErr)
+
+second:
+	if isPlatformError(nestedErr) {
+		return nil
+	}
+	switch err := nestedErr.(type) {
+	case *os.SyscallError:
+		nestedErr = err.Err
+		goto third
+	case *os.PathError: // for Plan 9
+		nestedErr = err.Err
+		goto third
+	}
+	switch nestedErr {
+	case errClosing:
+		return nil
+	}
+	return fmt.Errorf("unexpected type on 2nd nested level: %T", nestedErr)
+
+third:
+	if isPlatformError(nestedErr) {
+		return nil
+	}
+	return fmt.Errorf("unexpected type on 3rd nested level: %T", nestedErr)
+}
+
+func TestCloseError(t *testing.T) {
+	ln, err := newLocalListener("tcp")
+	if err != nil {
+		t.Fatal(err)
+	}
+	defer ln.Close()
+	c, err := Dial(ln.Addr().Network(), ln.Addr().String())
+	if err != nil {
+		t.Fatal(err)
+	}
+	defer c.Close()
+
+	for i := 0; i < 3; i++ {
+		err = c.(*TCPConn).CloseRead()
+		if perr := parseCloseError(err); perr != nil {
+			t.Errorf("#%d: %v", i, perr)
+		}
+	}
+	for i := 0; i < 3; i++ {
+		err = c.(*TCPConn).CloseWrite()
+		if perr := parseCloseError(err); perr != nil {
+			t.Errorf("#%d: %v", i, perr)
+		}
+	}
+	for i := 0; i < 3; i++ {
+		err = c.Close()
+		if perr := parseCloseError(err); perr != nil {
+			t.Errorf("#%d: %v", i, perr)
+		}
+		err = ln.Close()
+		if perr := parseCloseError(err); perr != nil {
+			t.Errorf("#%d: %v", i, perr)
+		}
+	}
+
+	pc, err := ListenPacket("udp", "127.0.0.1:0")
+	if err != nil {
+		t.Fatal(err)
+	}
+	defer pc.Close()
+
+	for i := 0; i < 3; i++ {
+		err = pc.Close()
+		if perr := parseCloseError(err); perr != nil {
+			t.Errorf("#%d: %v", i, perr)
+		}
+	}
+}
+
+// parseAcceptError parses nestedErr and reports whether it is a valid
+// error value from Accept functions.
+// It returns nil when nestedErr is valid.
+func parseAcceptError(nestedErr error) error {
+	if nestedErr == nil {
+		return nil
+	}
+
+	switch err := nestedErr.(type) {
+	case *OpError:
+		if err := err.isValid(); err != nil {
+			return err
+		}
+		nestedErr = err.Err
+		goto second
+	}
+	return fmt.Errorf("unexpected type on 1st nested level: %T", nestedErr)
+
+second:
+	if isPlatformError(nestedErr) {
+		return nil
+	}
+	switch err := nestedErr.(type) {
+	case *os.SyscallError:
+		nestedErr = err.Err
+		goto third
+	}
+	switch nestedErr {
+	case errClosing, errTimeout:
+		return nil
+	}
+	return fmt.Errorf("unexpected type on 2nd nested level: %T", nestedErr)
+
+third:
+	if isPlatformError(nestedErr) {
+		return nil
+	}
+	return fmt.Errorf("unexpected type on 3rd nested level: %T", nestedErr)
+}
+
+func TestAcceptError(t *testing.T) {
+	handler := func(ls *localServer, ln Listener) {
+		for {
+			ln.(*TCPListener).SetDeadline(time.Now().Add(5 * time.Millisecond))
+			c, err := ln.Accept()
+			if perr := parseAcceptError(err); perr != nil {
+				t.Error(perr)
+			}
+			if err != nil {
+				if c != nil {
+					t.Errorf("Accept returned non-nil interface %T(%v) with err != nil", c, c)
+				}
+				if nerr, ok := err.(Error); !ok || (!nerr.Timeout() && !nerr.Temporary()) {
+					return
+				}
+				continue
+			}
+			c.Close()
+		}
+	}
+	ls, err := newLocalServer("tcp")
+	if err != nil {
+		t.Fatal(err)
+	}
+	if err := ls.buildup(handler); err != nil {
+		ls.teardown()
+		t.Fatal(err)
+	}
+
+	time.Sleep(100 * time.Millisecond)
+	ls.teardown()
+}
+
+// parseCommonError parses nestedErr and reports whether it is a valid
+// error value from miscellaneous functions.
+// It returns nil when nestedErr is valid.
+func parseCommonError(nestedErr error) error {
+	if nestedErr == nil {
+		return nil
+	}
+
+	switch err := nestedErr.(type) {
+	case *OpError:
+		if err := err.isValid(); err != nil {
+			return err
+		}
+		nestedErr = err.Err
+		goto second
+	}
+	return fmt.Errorf("unexpected type on 1st nested level: %T", nestedErr)
+
+second:
+	if isPlatformError(nestedErr) {
+		return nil
+	}
+	switch err := nestedErr.(type) {
+	case *os.SyscallError:
+		nestedErr = err.Err
+		goto third
+	case *os.LinkError:
+		nestedErr = err.Err
+		goto third
+	case *os.PathError:
+		nestedErr = err.Err
+		goto third
+	}
+	switch nestedErr {
+	case errClosing:
+		return nil
+	}
+	return fmt.Errorf("unexpected type on 2nd nested level: %T", nestedErr)
+
+third:
+	if isPlatformError(nestedErr) {
+		return nil
+	}
+	return fmt.Errorf("unexpected type on 3rd nested level: %T", nestedErr)
+}
+
+func TestFileError(t *testing.T) {
+	switch runtime.GOOS {
+	case "windows":
+		t.Skipf("not supported on %s", runtime.GOOS)
+	}
+
+	f, err := ioutil.TempFile("", "go-nettest")
+	if err != nil {
+		t.Fatal(err)
+	}
+	defer os.Remove(f.Name())
+	defer f.Close()
+
+	c, err := FileConn(f)
+	if err != nil {
+		if c != nil {
+			t.Errorf("FileConn returned non-nil interface %T(%v) with err != nil", c, c)
+		}
+		if perr := parseCommonError(err); perr != nil {
+			t.Error(perr)
+		}
+	} else {
+		c.Close()
+		t.Error("should fail")
+	}
+	ln, err := FileListener(f)
+	if err != nil {
+		if ln != nil {
+			t.Errorf("FileListener returned non-nil interface %T(%v) with err != nil", ln, ln)
+		}
+		if perr := parseCommonError(err); perr != nil {
+			t.Error(perr)
+		}
+	} else {
+		ln.Close()
+		t.Error("should fail")
+	}
+	pc, err := FilePacketConn(f)
+	if err != nil {
+		if pc != nil {
+			t.Errorf("FilePacketConn returned non-nil interface %T(%v) with err != nil", pc, pc)
+		}
+		if perr := parseCommonError(err); perr != nil {
+			t.Error(perr)
+		}
+	} else {
+		pc.Close()
+		t.Error("should fail")
+	}
+
+	ln, err = newLocalListener("tcp")
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	for i := 0; i < 3; i++ {
+		f, err := ln.(*TCPListener).File()
+		if err != nil {
+			if perr := parseCommonError(err); perr != nil {
+				t.Error(perr)
+			}
+		} else {
+			f.Close()
+		}
+		ln.Close()
+	}
+}
diff --git a/third_party/gofrontend/libgo/go/net/external_test.go b/third_party/gofrontend/libgo/go/net/external_test.go
new file mode 100644
index 0000000..d5ff2be
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/net/external_test.go
@@ -0,0 +1,167 @@
+// Copyright 2009 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 net
+
+import (
+	"fmt"
+	"io"
+	"strings"
+	"testing"
+)
+
+func TestResolveGoogle(t *testing.T) {
+	if testing.Short() || !*testExternal {
+		t.Skip("avoid external network")
+	}
+	if !supportsIPv4 || !supportsIPv6 || !*testIPv4 || !*testIPv6 {
+		t.Skip("both IPv4 and IPv6 are required")
+	}
+
+	for _, network := range []string{"tcp", "tcp4", "tcp6"} {
+		addr, err := ResolveTCPAddr(network, "www.google.com:http")
+		if err != nil {
+			t.Error(err)
+			continue
+		}
+		switch {
+		case network == "tcp" && addr.IP.To4() == nil:
+			fallthrough
+		case network == "tcp4" && addr.IP.To4() == nil:
+			t.Errorf("got %v; want an IPv4 address on %s", addr, network)
+		case network == "tcp6" && (addr.IP.To16() == nil || addr.IP.To4() != nil):
+			t.Errorf("got %v; want an IPv6 address on %s", addr, network)
+		}
+	}
+}
+
+var dialGoogleTests = []struct {
+	dial               func(string, string) (Conn, error)
+	unreachableNetwork string
+	networks           []string
+	addrs              []string
+}{
+	{
+		dial:     (&Dialer{DualStack: true}).Dial,
+		networks: []string{"tcp", "tcp4", "tcp6"},
+		addrs:    []string{"www.google.com:http"},
+	},
+	{
+		dial:               Dial,
+		unreachableNetwork: "tcp6",
+		networks:           []string{"tcp", "tcp4"},
+	},
+	{
+		dial:               Dial,
+		unreachableNetwork: "tcp4",
+		networks:           []string{"tcp", "tcp6"},
+	},
+}
+
+func TestDialGoogle(t *testing.T) {
+	if testing.Short() || !*testExternal {
+		t.Skip("avoid external network")
+	}
+	if !supportsIPv4 || !supportsIPv6 || !*testIPv4 || !*testIPv6 {
+		t.Skip("both IPv4 and IPv6 are required")
+	}
+
+	var err error
+	dialGoogleTests[1].addrs, dialGoogleTests[2].addrs, err = googleLiteralAddrs()
+	if err != nil {
+		t.Error(err)
+	}
+	for _, tt := range dialGoogleTests {
+		for _, network := range tt.networks {
+			disableSocketConnect(tt.unreachableNetwork)
+			for _, addr := range tt.addrs {
+				if err := fetchGoogle(tt.dial, network, addr); err != nil {
+					t.Error(err)
+				}
+			}
+			enableSocketConnect()
+		}
+	}
+}
+
+var (
+	literalAddrs4 = [...]string{
+		"%d.%d.%d.%d:80",
+		"www.google.com:80",
+		"%d.%d.%d.%d:http",
+		"www.google.com:http",
+		"%03d.%03d.%03d.%03d:0080",
+		"[::ffff:%d.%d.%d.%d]:80",
+		"[::ffff:%02x%02x:%02x%02x]:80",
+		"[0:0:0:0:0000:ffff:%d.%d.%d.%d]:80",
+		"[0:0:0:0:000000:ffff:%d.%d.%d.%d]:80",
+		"[0:0:0:0::ffff:%d.%d.%d.%d]:80",
+	}
+	literalAddrs6 = [...]string{
+		"[%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x]:80",
+		"ipv6.google.com:80",
+		"[%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x]:http",
+		"ipv6.google.com:http",
+	}
+)
+
+func googleLiteralAddrs() (lits4, lits6 []string, err error) {
+	ips, err := LookupIP("www.google.com")
+	if err != nil {
+		return nil, nil, err
+	}
+	if len(ips) == 0 {
+		return nil, nil, nil
+	}
+	var ip4, ip6 IP
+	for _, ip := range ips {
+		if ip4 == nil && ip.To4() != nil {
+			ip4 = ip.To4()
+		}
+		if ip6 == nil && ip.To16() != nil && ip.To4() == nil {
+			ip6 = ip.To16()
+		}
+		if ip4 != nil && ip6 != nil {
+			break
+		}
+	}
+	if ip4 != nil {
+		for i, lit4 := range literalAddrs4 {
+			if strings.Contains(lit4, "%") {
+				literalAddrs4[i] = fmt.Sprintf(lit4, ip4[0], ip4[1], ip4[2], ip4[3])
+			}
+		}
+		lits4 = literalAddrs4[:]
+	}
+	if ip6 != nil {
+		for i, lit6 := range literalAddrs6 {
+			if strings.Contains(lit6, "%") {
+				literalAddrs6[i] = fmt.Sprintf(lit6, ip6[0], ip6[1], ip6[2], ip6[3], ip6[4], ip6[5], ip6[6], ip6[7], ip6[8], ip6[9], ip6[10], ip6[11], ip6[12], ip6[13], ip6[14], ip6[15])
+			}
+		}
+		lits6 = literalAddrs6[:]
+	}
+	return
+}
+
+func fetchGoogle(dial func(string, string) (Conn, error), network, address string) error {
+	c, err := dial(network, address)
+	if err != nil {
+		return err
+	}
+	defer c.Close()
+	req := []byte("GET /robots.txt HTTP/1.0\r\nHost: www.google.com\r\n\r\n")
+	if _, err := c.Write(req); err != nil {
+		return err
+	}
+	b := make([]byte, 1000)
+	n, err := io.ReadFull(c, b)
+	if err != nil {
+		return err
+	}
+	if n < 1000 {
+		return fmt.Errorf("short read from %s:%s->%s", network, c.RemoteAddr(), c.LocalAddr())
+	}
+	return nil
+}
diff --git a/third_party/gofrontend/libgo/go/net/fd_plan9.go b/third_party/gofrontend/libgo/go/net/fd_plan9.go
index 5fe8eff..32766f5 100644
--- a/third_party/gofrontend/libgo/go/net/fd_plan9.go
+++ b/third_party/gofrontend/libgo/go/net/fd_plan9.go
@@ -11,13 +11,13 @@
 	"time"
 )
 
-// Network file descritor.
+// Network file descriptor.
 type netFD struct {
 	// locking/lifetime of sysfd + serialize access to Read and Write methods
 	fdmu fdMutex
 
 	// immutable until Close
-	proto        string
+	net          string
 	n            string
 	dir          string
 	ctl, data    *os.File
@@ -38,8 +38,8 @@
 	return dialChannel(net, ra, dialer, deadline)
 }
 
-func newFD(proto, name string, ctl, data *os.File, laddr, raddr Addr) (*netFD, error) {
-	return &netFD{proto: proto, n: name, dir: netdir + "/" + proto + "/" + name, ctl: ctl, data: data, laddr: laddr, raddr: raddr}, nil
+func newFD(net, name string, ctl, data *os.File, laddr, raddr Addr) (*netFD, error) {
+	return &netFD{net: net, n: name, dir: netdir + "/" + net + "/" + name, ctl: ctl, data: data, laddr: laddr, raddr: raddr}, nil
 }
 
 func (fd *netFD) init() error {
@@ -55,7 +55,7 @@
 	if fd.raddr != nil {
 		rs = fd.raddr.String()
 	}
-	return fd.proto + ":" + ls + "->" + rs
+	return fd.net + ":" + ls + "->" + rs
 }
 
 func (fd *netFD) ok() bool { return fd != nil && fd.ctl != nil }
@@ -132,7 +132,7 @@
 	}
 	defer fd.readUnlock()
 	n, err = fd.data.Read(b)
-	if fd.proto == "udp" && err == io.EOF {
+	if fd.net == "udp" && err == io.EOF {
 		n = 0
 		err = nil
 	}
@@ -202,7 +202,7 @@
 	dfd, err := syscall.Dup(int(f.Fd()), -1)
 	syscall.ForkLock.RUnlock()
 	if err != nil {
-		return nil, &OpError{"dup", s, fd.laddr, err}
+		return nil, os.NewSyscallError("dup", err)
 	}
 	return os.NewFile(uintptr(dfd), s), nil
 }
@@ -226,7 +226,3 @@
 func setWriteBuffer(fd *netFD, bytes int) error {
 	return syscall.EPLAN9
 }
-
-func skipRawSocketTests() (skip bool, skipmsg string, err error) {
-	return true, "skipping test on plan9", nil
-}
diff --git a/third_party/gofrontend/libgo/go/net/fd_poll_nacl.go b/third_party/gofrontend/libgo/go/net/fd_poll_nacl.go
index a3701f8..cdf14e3 100644
--- a/third_party/gofrontend/libgo/go/net/fd_poll_nacl.go
+++ b/third_party/gofrontend/libgo/go/net/fd_poll_nacl.go
@@ -18,18 +18,11 @@
 
 func (pd *pollDesc) Close() {}
 
-func (pd *pollDesc) Lock() {}
-
-func (pd *pollDesc) Unlock() {}
-
-func (pd *pollDesc) Wakeup() {}
-
-func (pd *pollDesc) Evict() bool {
+func (pd *pollDesc) Evict() {
 	pd.closing = true
 	if pd.fd != nil {
 		syscall.StopIO(pd.fd.sysfd)
 	}
-	return false
 }
 
 func (pd *pollDesc) Prepare(mode int) error {
diff --git a/third_party/gofrontend/libgo/go/net/fd_poll_runtime.go b/third_party/gofrontend/libgo/go/net/fd_poll_runtime.go
index 2bddc83..8522cce 100644
--- a/third_party/gofrontend/libgo/go/net/fd_poll_runtime.go
+++ b/third_party/gofrontend/libgo/go/net/fd_poll_runtime.go
@@ -48,23 +48,12 @@
 	pd.runtimeCtx = 0
 }
 
-func (pd *pollDesc) Lock() {
-}
-
-func (pd *pollDesc) Unlock() {
-}
-
-func (pd *pollDesc) Wakeup() {
-}
-
 // Evict evicts fd from the pending list, unblocking any I/O running on fd.
-// Return value is whether the pollServer should be woken up.
-func (pd *pollDesc) Evict() bool {
+func (pd *pollDesc) Evict() {
 	if pd.runtimeCtx == 0 {
-		return false
+		return
 	}
 	runtime_pollUnblock(pd.runtimeCtx)
-	return false
 }
 
 func (pd *pollDesc) Prepare(mode int) error {
diff --git a/third_party/gofrontend/libgo/go/net/fd_posix.go b/third_party/gofrontend/libgo/go/net/fd_posix.go
new file mode 100644
index 0000000..b4b908a
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/net/fd_posix.go
@@ -0,0 +1,21 @@
+// Copyright 2009 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 darwin dragonfly freebsd linux nacl netbsd openbsd solaris windows
+
+package net
+
+import (
+	"io"
+	"syscall"
+)
+
+// eofError returns io.EOF when fd is available for reading end of
+// file.
+func (fd *netFD) eofError(n int, err error) error {
+	if n == 0 && err == nil && fd.sotype != syscall.SOCK_DGRAM && fd.sotype != syscall.SOCK_RAW {
+		return io.EOF
+	}
+	return err
+}
diff --git a/third_party/gofrontend/libgo/go/net/fd_unix_test.go b/third_party/gofrontend/libgo/go/net/fd_posix_test.go
similarity index 84%
rename from third_party/gofrontend/libgo/go/net/fd_unix_test.go
rename to third_party/gofrontend/libgo/go/net/fd_posix_test.go
index fe8e8ff..85711ef 100644
--- a/third_party/gofrontend/libgo/go/net/fd_unix_test.go
+++ b/third_party/gofrontend/libgo/go/net/fd_posix_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 darwin dragonfly freebsd linux netbsd openbsd solaris
+// +build darwin dragonfly freebsd linux nacl netbsd openbsd solaris windows
 
 package net
 
@@ -12,13 +12,12 @@
 	"testing"
 )
 
-var chkReadErrTests = []struct {
+var eofErrorTests = []struct {
 	n        int
 	err      error
 	fd       *netFD
 	expected error
 }{
-
 	{100, nil, &netFD{sotype: syscall.SOCK_STREAM}, nil},
 	{100, io.EOF, &netFD{sotype: syscall.SOCK_STREAM}, io.EOF},
 	{100, errClosing, &netFD{sotype: syscall.SOCK_STREAM}, errClosing},
@@ -48,11 +47,11 @@
 	{0, errClosing, &netFD{sotype: syscall.SOCK_RAW}, errClosing},
 }
 
-func TestChkReadErr(t *testing.T) {
-	for _, tt := range chkReadErrTests {
-		actual := chkReadErr(tt.n, tt.err, tt.fd)
+func TestEOFError(t *testing.T) {
+	for _, tt := range eofErrorTests {
+		actual := tt.fd.eofError(tt.n, tt.err)
 		if actual != tt.expected {
-			t.Errorf("chkReadError(%v, %v, %v): expected %v, actual %v", tt.n, tt.err, tt.fd.sotype, tt.expected, actual)
+			t.Errorf("eofError(%v, %v, %v): expected %v, actual %v", tt.n, tt.err, tt.fd.sotype, tt.expected, actual)
 		}
 	}
 }
diff --git a/third_party/gofrontend/libgo/go/net/fd_unix.go b/third_party/gofrontend/libgo/go/net/fd_unix.go
index 7a97fae..465023f 100644
--- a/third_party/gofrontend/libgo/go/net/fd_unix.go
+++ b/third_party/gofrontend/libgo/go/net/fd_unix.go
@@ -72,7 +72,7 @@
 	// Do not need to call fd.writeLock here,
 	// because fd is not yet accessible to user,
 	// so no concurrent operations are possible.
-	switch err := syscall.Connect(fd.sysfd, ra); err {
+	switch err := connectFunc(fd.sysfd, ra); err {
 	case syscall.EINPROGRESS, syscall.EALREADY, syscall.EINTR:
 	case nil, syscall.EISCONN:
 		if !deadline.IsZero() && deadline.Before(time.Now()) {
@@ -87,13 +87,13 @@
 		// already been accepted and closed by the server.
 		// Treat this as a successful connection--writes to
 		// the socket will see EOF.  For details and a test
-		// case in C see http://golang.org/issue/6828.
+		// case in C see https://golang.org/issue/6828.
 		if runtime.GOOS == "solaris" {
 			return nil
 		}
 		fallthrough
 	default:
-		return err
+		return os.NewSyscallError("connect", err)
 	}
 	if err := fd.init(); err != nil {
 		return err
@@ -114,25 +114,25 @@
 		if err := fd.pd.WaitWrite(); err != nil {
 			return err
 		}
-		nerr, err := syscall.GetsockoptInt(fd.sysfd, syscall.SOL_SOCKET, syscall.SO_ERROR)
+		nerr, err := getsockoptIntFunc(fd.sysfd, syscall.SOL_SOCKET, syscall.SO_ERROR)
 		if err != nil {
-			return err
+			return os.NewSyscallError("getsockopt", err)
 		}
 		switch err := syscall.Errno(nerr); err {
 		case syscall.EINPROGRESS, syscall.EALREADY, syscall.EINTR:
 		case syscall.Errno(0), syscall.EISCONN:
 			return nil
 		default:
-			return err
+			return os.NewSyscallError("getsockopt", err)
 		}
 	}
 }
 
 func (fd *netFD) destroy() {
 	// Poller may want to unregister fd in readiness notification mechanism,
-	// so this must be executed before closesocket.
+	// so this must be executed before closeFunc.
 	fd.pd.Close()
-	closesocket(fd.sysfd)
+	closeFunc(fd.sysfd)
 	fd.sysfd = -1
 	runtime.SetFinalizer(fd, nil)
 }
@@ -187,9 +187,7 @@
 }
 
 func (fd *netFD) Close() error {
-	fd.pd.Lock() // needed for both fd.incref(true) and pollDesc.Evict
 	if !fd.fdmu.IncrefAndClose() {
-		fd.pd.Unlock()
 		return errClosing
 	}
 	// Unblock any I/O.  Once it all unblocks and returns,
@@ -197,12 +195,8 @@
 	// the final decref will close fd.sysfd.  This should happen
 	// fairly quickly, since all the I/O is non-blocking, and any
 	// attempts to block in the pollDesc will return errClosing.
-	doWakeup := fd.pd.Evict()
-	fd.pd.Unlock()
+	fd.pd.Evict()
 	fd.decref()
-	if doWakeup {
-		fd.pd.Wakeup()
-	}
 	return nil
 }
 
@@ -211,11 +205,7 @@
 		return err
 	}
 	defer fd.decref()
-	err := syscall.Shutdown(fd.sysfd, how)
-	if err != nil {
-		return &OpError{"shutdown", fd.net, fd.laddr, err}
-	}
-	return nil
+	return os.NewSyscallError("shutdown", syscall.Shutdown(fd.sysfd, how))
 }
 
 func (fd *netFD) closeRead() error {
@@ -232,10 +222,10 @@
 	}
 	defer fd.readUnlock()
 	if err := fd.pd.PrepareRead(); err != nil {
-		return 0, &OpError{"read", fd.net, fd.raddr, err}
+		return 0, err
 	}
 	for {
-		n, err = syscall.Read(int(fd.sysfd), p)
+		n, err = syscall.Read(fd.sysfd, p)
 		if err != nil {
 			n = 0
 			if err == syscall.EAGAIN {
@@ -244,11 +234,11 @@
 				}
 			}
 		}
-		err = chkReadErr(n, err, fd)
+		err = fd.eofError(n, err)
 		break
 	}
-	if err != nil && err != io.EOF {
-		err = &OpError{"read", fd.net, fd.raddr, err}
+	if _, ok := err.(syscall.Errno); ok {
+		err = os.NewSyscallError("read", err)
 	}
 	return
 }
@@ -259,7 +249,7 @@
 	}
 	defer fd.readUnlock()
 	if err := fd.pd.PrepareRead(); err != nil {
-		return 0, nil, &OpError{"read", fd.net, fd.laddr, err}
+		return 0, nil, err
 	}
 	for {
 		n, sa, err = syscall.Recvfrom(fd.sysfd, p, 0)
@@ -271,11 +261,11 @@
 				}
 			}
 		}
-		err = chkReadErr(n, err, fd)
+		err = fd.eofError(n, err)
 		break
 	}
-	if err != nil && err != io.EOF {
-		err = &OpError{"read", fd.net, fd.laddr, err}
+	if _, ok := err.(syscall.Errno); ok {
+		err = os.NewSyscallError("recvfrom", err)
 	}
 	return
 }
@@ -286,7 +276,7 @@
 	}
 	defer fd.readUnlock()
 	if err := fd.pd.PrepareRead(); err != nil {
-		return 0, 0, 0, nil, &OpError{"read", fd.net, fd.laddr, err}
+		return 0, 0, 0, nil, err
 	}
 	for {
 		n, oobn, flags, sa, err = syscall.Recvmsg(fd.sysfd, p, oob, 0)
@@ -298,33 +288,26 @@
 				}
 			}
 		}
-		err = chkReadErr(n, err, fd)
+		err = fd.eofError(n, err)
 		break
 	}
-	if err != nil && err != io.EOF {
-		err = &OpError{"read", fd.net, fd.laddr, err}
+	if _, ok := err.(syscall.Errno); ok {
+		err = os.NewSyscallError("recvmsg", err)
 	}
 	return
 }
 
-func chkReadErr(n int, err error, fd *netFD) error {
-	if n == 0 && err == nil && fd.sotype != syscall.SOCK_DGRAM && fd.sotype != syscall.SOCK_RAW {
-		return io.EOF
-	}
-	return err
-}
-
 func (fd *netFD) Write(p []byte) (nn int, err error) {
 	if err := fd.writeLock(); err != nil {
 		return 0, err
 	}
 	defer fd.writeUnlock()
 	if err := fd.pd.PrepareWrite(); err != nil {
-		return 0, &OpError{"write", fd.net, fd.raddr, err}
+		return 0, err
 	}
 	for {
 		var n int
-		n, err = syscall.Write(int(fd.sysfd), p[nn:])
+		n, err = syscall.Write(fd.sysfd, p[nn:])
 		if n > 0 {
 			nn += n
 		}
@@ -337,7 +320,6 @@
 			}
 		}
 		if err != nil {
-			n = 0
 			break
 		}
 		if n == 0 {
@@ -345,8 +327,8 @@
 			break
 		}
 	}
-	if err != nil {
-		err = &OpError{"write", fd.net, fd.raddr, err}
+	if _, ok := err.(syscall.Errno); ok {
+		err = os.NewSyscallError("write", err)
 	}
 	return nn, err
 }
@@ -357,7 +339,7 @@
 	}
 	defer fd.writeUnlock()
 	if err := fd.pd.PrepareWrite(); err != nil {
-		return 0, &OpError{"write", fd.net, fd.raddr, err}
+		return 0, err
 	}
 	for {
 		err = syscall.Sendto(fd.sysfd, p, 0, sa)
@@ -370,8 +352,9 @@
 	}
 	if err == nil {
 		n = len(p)
-	} else {
-		err = &OpError{"write", fd.net, fd.raddr, err}
+	}
+	if _, ok := err.(syscall.Errno); ok {
+		err = os.NewSyscallError("sendto", err)
 	}
 	return
 }
@@ -382,7 +365,7 @@
 	}
 	defer fd.writeUnlock()
 	if err := fd.pd.PrepareWrite(); err != nil {
-		return 0, 0, &OpError{"write", fd.net, fd.raddr, err}
+		return 0, 0, err
 	}
 	for {
 		n, err = syscall.SendmsgN(fd.sysfd, p, oob, sa, 0)
@@ -395,8 +378,9 @@
 	}
 	if err == nil {
 		oobn = len(oob)
-	} else {
-		err = &OpError{"write", fd.net, fd.raddr, err}
+	}
+	if _, ok := err.(syscall.Errno); ok {
+		err = os.NewSyscallError("sendmsg", err)
 	}
 	return
 }
@@ -410,27 +394,34 @@
 	var s int
 	var rsa syscall.Sockaddr
 	if err = fd.pd.PrepareRead(); err != nil {
-		return nil, &OpError{"accept", fd.net, fd.laddr, err}
+		return nil, err
 	}
 	for {
 		s, rsa, err = accept(fd.sysfd)
 		if err != nil {
-			if err == syscall.EAGAIN {
+			nerr, ok := err.(*os.SyscallError)
+			if !ok {
+				return nil, err
+			}
+			switch nerr.Err {
+			case syscall.EAGAIN:
 				if err = fd.pd.WaitRead(); err == nil {
 					continue
 				}
-			} else if err == syscall.ECONNABORTED {
-				// This means that a socket on the listen queue was closed
-				// before we Accept()ed it; it's a silly error, so try again.
+			case syscall.ECONNABORTED:
+				// This means that a socket on the
+				// listen queue was closed before we
+				// Accept()ed it; it's a silly error,
+				// so try again.
 				continue
 			}
-			return nil, &OpError{"accept", fd.net, fd.laddr, err}
+			return nil, err
 		}
 		break
 	}
 
 	if netfd, err = newFD(s, fd.family, fd.sotype, fd.net); err != nil {
-		closesocket(s)
+		closeFunc(s)
 		return nil, err
 	}
 	if err = netfd.init(); err != nil {
@@ -442,13 +433,21 @@
 	return netfd, nil
 }
 
+// Use a helper function to call fcntl.  This is defined in C in
+// libgo/runtime.
+//extern __go_fcntl_uintptr
+func fcntl(uintptr, uintptr, uintptr) (uintptr, uintptr)
+
 // tryDupCloexec indicates whether F_DUPFD_CLOEXEC should be used.
 // If the kernel doesn't support it, this is set to 0.
 var tryDupCloexec = int32(1)
 
 func dupCloseOnExec(fd int) (newfd int, err error) {
 	if atomic.LoadInt32(&tryDupCloexec) == 1 && syscall.F_DUPFD_CLOEXEC != 0 {
-		r0, _, e1 := syscall.Syscall(syscall.SYS_FCNTL, uintptr(fd), syscall.F_DUPFD_CLOEXEC, 0)
+		syscall.Entersyscall()
+		r0, errno := fcntl(uintptr(fd), syscall.F_DUPFD_CLOEXEC, 0)
+		syscall.Exitsyscall()
+		e1 := syscall.Errno(errno)
 		if runtime.GOOS == "darwin" && e1 == syscall.EBADF {
 			// On OS X 10.6 and below (but we only support
 			// >= 10.6), F_DUPFD_CLOEXEC is unsupported
@@ -470,7 +469,7 @@
 			// from now on.
 			atomic.StoreInt32(&tryDupCloexec, 0)
 		default:
-			return -1, e1
+			return -1, os.NewSyscallError("fcntl", e1)
 		}
 	}
 	return dupCloseOnExecOld(fd)
@@ -483,7 +482,7 @@
 	defer syscall.ForkLock.RUnlock()
 	newfd, err = syscall.Dup(fd)
 	if err != nil {
-		return -1, err
+		return -1, os.NewSyscallError("dup", err)
 	}
 	syscall.CloseOnExec(newfd)
 	return
@@ -492,7 +491,7 @@
 func (fd *netFD) dup() (f *os.File, err error) {
 	ns, err := dupCloseOnExec(fd.sysfd)
 	if err != nil {
-		return nil, &OpError{"dup", fd.net, fd.laddr, err}
+		return nil, err
 	}
 
 	// We want blocking mode for the new fd, hence the double negative.
@@ -500,19 +499,8 @@
 	// I/O will block the thread instead of letting us use the epoll server.
 	// Everything will still work, just with more threads.
 	if err = syscall.SetNonblock(ns, false); err != nil {
-		return nil, &OpError{"setnonblock", fd.net, fd.laddr, err}
+		return nil, os.NewSyscallError("setnonblock", err)
 	}
 
 	return os.NewFile(uintptr(ns), fd.name()), nil
 }
-
-func closesocket(s int) error {
-	return syscall.Close(s)
-}
-
-func skipRawSocketTests() (skip bool, skipmsg string, err error) {
-	if os.Getuid() != 0 {
-		return true, "skipping test; must be root", nil
-	}
-	return false, "", nil
-}
diff --git a/third_party/gofrontend/libgo/go/net/fd_windows.go b/third_party/gofrontend/libgo/go/net/fd_windows.go
index f3a534a..205daff 100644
--- a/third_party/gofrontend/libgo/go/net/fd_windows.go
+++ b/third_party/gofrontend/libgo/go/net/fd_windows.go
@@ -5,8 +5,6 @@
 package net
 
 import (
-	"errors"
-	"io"
 	"os"
 	"runtime"
 	"sync"
@@ -40,7 +38,7 @@
 	var d syscall.WSAData
 	e := syscall.WSAStartup(uint32(0x202), &d)
 	if e != nil {
-		initErr = os.NewSyscallError("WSAStartup", e)
+		initErr = os.NewSyscallError("wsastartup", e)
 	}
 	canCancelIO = syscall.LoadCancelIoEx() == nil
 	if syscall.LoadGetAddrInfo() == nil {
@@ -70,10 +68,6 @@
 	}
 }
 
-func closesocket(s syscall.Handle) error {
-	return syscall.Closesocket(s)
-}
-
 func canUseConnectEx(net string) bool {
 	switch net {
 	case "udp", "udp4", "udp6", "ip", "ip4", "ip6":
@@ -159,7 +153,7 @@
 	// Notify runtime netpoll about starting IO.
 	err := fd.pd.Prepare(int(o.mode))
 	if err != nil {
-		return 0, &OpError{name, fd.net, fd.laddr, err}
+		return 0, err
 	}
 	// Start IO.
 	if canCancelIO {
@@ -182,7 +176,7 @@
 		// IO started, and we have to wait for its completion.
 		err = nil
 	default:
-		return 0, &OpError{name, fd.net, fd.laddr, err}
+		return 0, err
 	}
 	// Wait for our request to complete.
 	err = fd.pd.Wait(int(o.mode))
@@ -190,7 +184,7 @@
 		// All is good. Extract our IO results and return.
 		if o.errno != 0 {
 			err = syscall.Errno(o.errno)
-			return 0, &OpError{name, fd.net, fd.laddr, err}
+			return 0, err
 		}
 		return int(o.qty), nil
 	}
@@ -221,7 +215,7 @@
 		if err == syscall.ERROR_OPERATION_ABORTED { // IO Canceled
 			err = netpollErr
 		}
-		return 0, &OpError{name, fd.net, fd.laddr, err}
+		return 0, err
 	}
 	// We issued cancellation request. But, it seems, IO operation succeeded
 	// before cancellation request run. We need to treat IO operation as
@@ -303,7 +297,7 @@
 		size := uint32(unsafe.Sizeof(flag))
 		err := syscall.WSAIoctl(fd.sysfd, syscall.SIO_UDP_CONNRESET, (*byte)(unsafe.Pointer(&flag)), size, nil, 0, &ret, nil, 0)
 		if err != nil {
-			return os.NewSyscallError("WSAIoctl", err)
+			return os.NewSyscallError("wsaioctl", err)
 		}
 	}
 	fd.rop.mode = 'r'
@@ -337,7 +331,7 @@
 		defer fd.setWriteDeadline(noDeadline)
 	}
 	if !canUseConnectEx(fd.net) {
-		return syscall.Connect(fd.sysfd, ra)
+		return os.NewSyscallError("connect", connectFunc(fd.sysfd, ra))
 	}
 	// ConnectEx windows API requires an unconnected, previously bound socket.
 	if la == nil {
@@ -350,20 +344,23 @@
 			panic("unexpected type in connect")
 		}
 		if err := syscall.Bind(fd.sysfd, la); err != nil {
-			return err
+			return os.NewSyscallError("bind", err)
 		}
 	}
 	// Call ConnectEx API.
 	o := &fd.wop
 	o.sa = ra
 	_, err := wsrv.ExecIO(o, "ConnectEx", func(o *operation) error {
-		return syscall.ConnectEx(o.fd.sysfd, o.sa, nil, 0, nil, &o.o)
+		return connectExFunc(o.fd.sysfd, o.sa, nil, 0, nil, &o.o)
 	})
 	if err != nil {
+		if _, ok := err.(syscall.Errno); ok {
+			err = os.NewSyscallError("connectex", err)
+		}
 		return err
 	}
 	// Refresh socket properties.
-	return syscall.Setsockopt(fd.sysfd, syscall.SOL_SOCKET, syscall.SO_UPDATE_CONNECT_CONTEXT, (*byte)(unsafe.Pointer(&fd.sysfd)), int32(unsafe.Sizeof(fd.sysfd)))
+	return os.NewSyscallError("setsockopt", syscall.Setsockopt(fd.sysfd, syscall.SOL_SOCKET, syscall.SO_UPDATE_CONNECT_CONTEXT, (*byte)(unsafe.Pointer(&fd.sysfd)), int32(unsafe.Sizeof(fd.sysfd))))
 }
 
 func (fd *netFD) destroy() {
@@ -371,9 +368,9 @@
 		return
 	}
 	// Poller may want to unregister fd in readiness notification mechanism,
-	// so this must be executed before closesocket.
+	// so this must be executed before closeFunc.
 	fd.pd.Close()
-	closesocket(fd.sysfd)
+	closeFunc(fd.sysfd)
 	fd.sysfd = syscall.InvalidHandle
 	// no need for a finalizer anymore
 	runtime.SetFinalizer(fd, nil)
@@ -443,11 +440,7 @@
 		return err
 	}
 	defer fd.decref()
-	err := syscall.Shutdown(fd.sysfd, how)
-	if err != nil {
-		return &OpError{"shutdown", fd.net, fd.laddr, err}
-	}
-	return nil
+	return syscall.Shutdown(fd.sysfd, how)
 }
 
 func (fd *netFD) closeRead() error {
@@ -468,16 +461,17 @@
 	n, err := rsrv.ExecIO(o, "WSARecv", func(o *operation) error {
 		return syscall.WSARecv(o.fd.sysfd, &o.buf, 1, &o.qty, &o.flags, &o.o, nil)
 	})
-	if err == nil && n == 0 {
-		err = io.EOF
-	}
 	if raceenabled {
 		raceAcquire(unsafe.Pointer(&ioSync))
 	}
+	err = fd.eofError(n, err)
+	if _, ok := err.(syscall.Errno); ok {
+		err = os.NewSyscallError("wsarecv", err)
+	}
 	return n, err
 }
 
-func (fd *netFD) readFrom(buf []byte) (n int, sa syscall.Sockaddr, err error) {
+func (fd *netFD) readFrom(buf []byte) (int, syscall.Sockaddr, error) {
 	if len(buf) == 0 {
 		return 0, nil, nil
 	}
@@ -487,18 +481,22 @@
 	defer fd.readUnlock()
 	o := &fd.rop
 	o.InitBuf(buf)
-	n, err = rsrv.ExecIO(o, "WSARecvFrom", func(o *operation) error {
+	n, err := rsrv.ExecIO(o, "WSARecvFrom", func(o *operation) error {
 		if o.rsa == nil {
 			o.rsa = new(syscall.RawSockaddrAny)
 		}
 		o.rsan = int32(unsafe.Sizeof(*o.rsa))
 		return syscall.WSARecvFrom(o.fd.sysfd, &o.buf, 1, &o.qty, &o.flags, o.rsa, &o.rsan, &o.o, nil)
 	})
-	if err != nil {
-		return 0, nil, err
+	err = fd.eofError(n, err)
+	if _, ok := err.(syscall.Errno); ok {
+		err = os.NewSyscallError("wsarecvfrom", err)
 	}
-	sa, _ = o.rsa.Sockaddr()
-	return
+	if err != nil {
+		return n, nil, err
+	}
+	sa, _ := o.rsa.Sockaddr()
+	return n, sa, nil
 }
 
 func (fd *netFD) Write(buf []byte) (int, error) {
@@ -511,9 +509,13 @@
 	}
 	o := &fd.wop
 	o.InitBuf(buf)
-	return wsrv.ExecIO(o, "WSASend", func(o *operation) error {
+	n, err := wsrv.ExecIO(o, "WSASend", func(o *operation) error {
 		return syscall.WSASend(o.fd.sysfd, &o.buf, 1, &o.qty, 0, &o.o, nil)
 	})
+	if _, ok := err.(syscall.Errno); ok {
+		err = os.NewSyscallError("wsasend", err)
+	}
+	return n, err
 }
 
 func (fd *netFD) writeTo(buf []byte, sa syscall.Sockaddr) (int, error) {
@@ -527,23 +529,27 @@
 	o := &fd.wop
 	o.InitBuf(buf)
 	o.sa = sa
-	return wsrv.ExecIO(o, "WSASendto", func(o *operation) error {
+	n, err := wsrv.ExecIO(o, "WSASendto", func(o *operation) error {
 		return syscall.WSASendto(o.fd.sysfd, &o.buf, 1, &o.qty, 0, o.sa, &o.o, nil)
 	})
+	if _, ok := err.(syscall.Errno); ok {
+		err = os.NewSyscallError("wsasendto", err)
+	}
+	return n, err
 }
 
 func (fd *netFD) acceptOne(rawsa []syscall.RawSockaddrAny, o *operation) (*netFD, error) {
 	// Get new socket.
 	s, err := sysSocket(fd.family, fd.sotype, 0)
 	if err != nil {
-		return nil, &OpError{"socket", fd.net, fd.laddr, err}
+		return nil, err
 	}
 
 	// Associate our new socket with IOCP.
 	netfd, err := newFD(s, fd.family, fd.sotype, fd.net)
 	if err != nil {
-		closesocket(s)
-		return nil, &OpError{"accept", fd.net, fd.laddr, err}
+		closeFunc(s)
+		return nil, err
 	}
 	if err := netfd.init(); err != nil {
 		fd.Close()
@@ -558,6 +564,9 @@
 	})
 	if err != nil {
 		netfd.Close()
+		if _, ok := err.(syscall.Errno); ok {
+			err = os.NewSyscallError("acceptex", err)
+		}
 		return nil, err
 	}
 
@@ -565,7 +574,7 @@
 	err = syscall.Setsockopt(s, syscall.SOL_SOCKET, syscall.SO_UPDATE_ACCEPT_CONTEXT, (*byte)(unsafe.Pointer(&fd.sysfd)), int32(unsafe.Sizeof(fd.sysfd)))
 	if err != nil {
 		netfd.Close()
-		return nil, &OpError{"Setsockopt", fd.net, fd.laddr, err}
+		return nil, os.NewSyscallError("setsockopt", err)
 	}
 
 	return netfd, nil
@@ -591,11 +600,11 @@
 		// before AcceptEx could complete. These errors relate to new
 		// connection, not to AcceptEx, so ignore broken connection and
 		// try AcceptEx again for more connections.
-		operr, ok := err.(*OpError)
+		nerr, ok := err.(*os.SyscallError)
 		if !ok {
 			return nil, err
 		}
-		errno, ok := operr.Err.(syscall.Errno)
+		errno, ok := nerr.Err.(syscall.Errno)
 		if !ok {
 			return nil, err
 		}
@@ -619,38 +628,17 @@
 	return netfd, nil
 }
 
-func skipRawSocketTests() (skip bool, skipmsg string, err error) {
-	// From http://msdn.microsoft.com/en-us/library/windows/desktop/ms740548.aspx:
-	// Note: To use a socket of type SOCK_RAW requires administrative privileges.
-	// Users running Winsock applications that use raw sockets must be a member of
-	// the Administrators group on the local computer, otherwise raw socket calls
-	// will fail with an error code of WSAEACCES. On Windows Vista and later, access
-	// for raw sockets is enforced at socket creation. In earlier versions of Windows,
-	// access for raw sockets is enforced during other socket operations.
-	s, err := syscall.Socket(syscall.AF_INET, syscall.SOCK_RAW, 0)
-	if err == syscall.WSAEACCES {
-		return true, "skipping test; no access to raw socket allowed", nil
-	}
-	if err != nil {
-		return true, "", err
-	}
-	defer syscall.Closesocket(s)
-	return false, "", nil
-}
-
 // Unimplemented functions.
 
 func (fd *netFD) dup() (*os.File, error) {
 	// TODO: Implement this
-	return nil, os.NewSyscallError("dup", syscall.EWINDOWS)
+	return nil, syscall.EWINDOWS
 }
 
-var errNoSupport = errors.New("address family not supported")
-
 func (fd *netFD) readMsg(p []byte, oob []byte) (n, oobn, flags int, sa syscall.Sockaddr, err error) {
-	return 0, 0, 0, nil, errNoSupport
+	return 0, 0, 0, nil, syscall.EWINDOWS
 }
 
 func (fd *netFD) writeMsg(p []byte, oob []byte, sa syscall.Sockaddr) (n int, oobn int, err error) {
-	return 0, 0, errNoSupport
+	return 0, 0, syscall.EWINDOWS
 }
diff --git a/third_party/gofrontend/libgo/go/net/file.go b/third_party/gofrontend/libgo/go/net/file.go
new file mode 100644
index 0000000..1aad477
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/net/file.go
@@ -0,0 +1,48 @@
+// 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 net
+
+import "os"
+
+type fileAddr string
+
+func (fileAddr) Network() string  { return "file+net" }
+func (f fileAddr) String() string { return string(f) }
+
+// FileConn returns a copy of the network connection corresponding to
+// the open file f.
+// It is the caller's responsibility to close f when finished.
+// Closing c does not affect f, and closing f does not affect c.
+func FileConn(f *os.File) (c Conn, err error) {
+	c, err = fileConn(f)
+	if err != nil {
+		err = &OpError{Op: "file", Net: "file+net", Source: nil, Addr: fileAddr(f.Name()), Err: err}
+	}
+	return
+}
+
+// FileListener returns a copy of the network listener corresponding
+// to the open file f.
+// It is the caller's responsibility to close ln when finished.
+// Closing ln does not affect f, and closing f does not affect ln.
+func FileListener(f *os.File) (ln Listener, err error) {
+	ln, err = fileListener(f)
+	if err != nil {
+		err = &OpError{Op: "file", Net: "file+net", Source: nil, Addr: fileAddr(f.Name()), Err: err}
+	}
+	return
+}
+
+// FilePacketConn returns a copy of the packet network connection
+// corresponding to the open file f.
+// It is the caller's responsibility to close f when finished.
+// Closing c does not affect f, and closing f does not affect c.
+func FilePacketConn(f *os.File) (c PacketConn, err error) {
+	c, err = filePacketConn(f)
+	if err != nil {
+		err = &OpError{Op: "file", Net: "file+net", Source: nil, Addr: fileAddr(f.Name()), Err: err}
+	}
+	return
+}
diff --git a/third_party/gofrontend/libgo/go/net/file_plan9.go b/third_party/gofrontend/libgo/go/net/file_plan9.go
index 068f088..892775a 100644
--- a/third_party/gofrontend/libgo/go/net/file_plan9.go
+++ b/third_party/gofrontend/libgo/go/net/file_plan9.go
@@ -86,7 +86,7 @@
 	return newFD(comp[1], name, ctl, nil, laddr, nil)
 }
 
-func newFileConn(f *os.File) (c Conn, err error) {
+func fileConn(f *os.File) (Conn, error) {
 	fd, err := newFileFD(f)
 	if err != nil {
 		return nil, err
@@ -109,7 +109,7 @@
 	return nil, syscall.EPLAN9
 }
 
-func newFileListener(f *os.File) (l Listener, err error) {
+func fileListener(f *os.File) (Listener, error) {
 	fd, err := newFileFD(f)
 	if err != nil {
 		return nil, err
@@ -132,26 +132,6 @@
 	return &TCPListener{fd}, nil
 }
 
-// FileConn returns a copy of the network connection corresponding to
-// the open file f.  It is the caller's responsibility to close f when
-// finished.  Closing c does not affect f, and closing f does not
-// affect c.
-func FileConn(f *os.File) (c Conn, err error) {
-	return newFileConn(f)
-}
-
-// FileListener returns a copy of the network listener corresponding
-// to the open file f.  It is the caller's responsibility to close l
-// when finished.  Closing l does not affect f, and closing f does not
-// affect l.
-func FileListener(f *os.File) (l Listener, err error) {
-	return newFileListener(f)
-}
-
-// FilePacketConn returns a copy of the packet network connection
-// corresponding to the open file f.  It is the caller's
-// responsibility to close f when finished.  Closing c does not affect
-// f, and closing f does not affect c.
-func FilePacketConn(f *os.File) (c PacketConn, err error) {
+func filePacketConn(f *os.File) (PacketConn, error) {
 	return nil, syscall.EPLAN9
 }
diff --git a/third_party/gofrontend/libgo/go/net/file_stub.go b/third_party/gofrontend/libgo/go/net/file_stub.go
index 4281072..0f7460c 100644
--- a/third_party/gofrontend/libgo/go/net/file_stub.go
+++ b/third_party/gofrontend/libgo/go/net/file_stub.go
@@ -11,28 +11,6 @@
 	"syscall"
 )
 
-// FileConn returns a copy of the network connection corresponding to
-// the open file f.  It is the caller's responsibility to close f when
-// finished.  Closing c does not affect f, and closing f does not
-// affect c.
-func FileConn(f *os.File) (c Conn, err error) {
-	return nil, syscall.ENOPROTOOPT
-
-}
-
-// FileListener returns a copy of the network listener corresponding
-// to the open file f.  It is the caller's responsibility to close l
-// when finished.  Closing l does not affect f, and closing f does not
-// affect l.
-func FileListener(f *os.File) (l Listener, err error) {
-	return nil, syscall.ENOPROTOOPT
-
-}
-
-// FilePacketConn returns a copy of the packet network connection
-// corresponding to the open file f.  It is the caller's
-// responsibility to close f when finished.  Closing c does not affect
-// f, and closing f does not affect c.
-func FilePacketConn(f *os.File) (c PacketConn, err error) {
-	return nil, syscall.ENOPROTOOPT
-}
+func fileConn(f *os.File) (Conn, error)             { return nil, syscall.ENOPROTOOPT }
+func fileListener(f *os.File) (Listener, error)     { return nil, syscall.ENOPROTOOPT }
+func filePacketConn(f *os.File) (PacketConn, error) { return nil, syscall.ENOPROTOOPT }
diff --git a/third_party/gofrontend/libgo/go/net/file_test.go b/third_party/gofrontend/libgo/go/net/file_test.go
index 6fab06a..003dbb2 100644
--- a/third_party/gofrontend/libgo/go/net/file_test.go
+++ b/third_party/gofrontend/libgo/go/net/file_test.go
@@ -27,77 +27,69 @@
 }
 
 func testFileListener(t *testing.T, net, laddr string) {
-	switch net {
-	case "tcp", "tcp4", "tcp6":
-		laddr += ":0" // any available port
-	}
 	l, err := Listen(net, laddr)
 	if err != nil {
-		t.Fatalf("Listen failed: %v", err)
+		t.Fatal(err)
 	}
 	defer l.Close()
 	lf := l.(listenerFile)
 	f, err := lf.File()
 	if err != nil {
-		t.Fatalf("File failed: %v", err)
+		t.Fatal(err)
 	}
 	c, err := FileListener(f)
 	if err != nil {
-		t.Fatalf("FileListener failed: %v", err)
+		t.Fatal(err)
 	}
 	if !reflect.DeepEqual(l.Addr(), c.Addr()) {
-		t.Fatalf("Addrs not equal: %#v != %#v", l.Addr(), c.Addr())
+		t.Fatalf("got %#v; want%#v", l.Addr(), c.Addr())
 	}
 	if err := c.Close(); err != nil {
-		t.Fatalf("Close failed: %v", err)
+		t.Fatal(err)
 	}
 	if err := f.Close(); err != nil {
-		t.Fatalf("Close failed: %v", err)
+		t.Fatal(err)
 	}
 }
 
 var fileListenerTests = []struct {
 	net   string
 	laddr string
-	ipv6  bool // test with underlying AF_INET6 socket
-	linux bool // test with abstract unix domain socket, a Linux-ism
 }{
-	{net: "tcp", laddr: ""},
-	{net: "tcp", laddr: "0.0.0.0"},
-	{net: "tcp", laddr: "[::ffff:0.0.0.0]"},
-	{net: "tcp", laddr: "[::]", ipv6: true},
+	{net: "tcp", laddr: ":0"},
+	{net: "tcp", laddr: "0.0.0.0:0"},
+	{net: "tcp", laddr: "[::ffff:0.0.0.0]:0"},
+	{net: "tcp", laddr: "[::]:0"},
 
-	{net: "tcp", laddr: "127.0.0.1"},
-	{net: "tcp", laddr: "[::ffff:127.0.0.1]"},
-	{net: "tcp", laddr: "[::1]", ipv6: true},
+	{net: "tcp", laddr: "127.0.0.1:0"},
+	{net: "tcp", laddr: "[::ffff:127.0.0.1]:0"},
+	{net: "tcp", laddr: "[::1]:0"},
 
-	{net: "tcp4", laddr: ""},
-	{net: "tcp4", laddr: "0.0.0.0"},
-	{net: "tcp4", laddr: "[::ffff:0.0.0.0]"},
+	{net: "tcp4", laddr: ":0"},
+	{net: "tcp4", laddr: "0.0.0.0:0"},
+	{net: "tcp4", laddr: "[::ffff:0.0.0.0]:0"},
 
-	{net: "tcp4", laddr: "127.0.0.1"},
-	{net: "tcp4", laddr: "[::ffff:127.0.0.1]"},
+	{net: "tcp4", laddr: "127.0.0.1:0"},
+	{net: "tcp4", laddr: "[::ffff:127.0.0.1]:0"},
 
-	{net: "tcp6", laddr: "", ipv6: true},
-	{net: "tcp6", laddr: "[::]", ipv6: true},
+	{net: "tcp6", laddr: ":0"},
+	{net: "tcp6", laddr: "[::]:0"},
 
-	{net: "tcp6", laddr: "[::1]", ipv6: true},
+	{net: "tcp6", laddr: "[::1]:0"},
 
-	{net: "unix", laddr: "@gotest/net", linux: true},
-	{net: "unixpacket", laddr: "@gotest/net", linux: true},
+	{net: "unix", laddr: "@gotest/net"},
+	{net: "unixpacket", laddr: "@gotest/net"},
 }
 
 func TestFileListener(t *testing.T) {
 	switch runtime.GOOS {
 	case "nacl", "windows":
-		t.Skipf("skipping test on %q", runtime.GOOS)
+		t.Skipf("not supported on %s", runtime.GOOS)
 	}
 
 	for _, tt := range fileListenerTests {
-		if skipServerTest(tt.net, "unix", tt.laddr, tt.ipv6, false, tt.linux) {
-			continue
-		}
-		if skipServerTest(tt.net, "unixpacket", tt.laddr, tt.ipv6, false, tt.linux) {
+		if !testableListenArgs(tt.net, tt.laddr, "") {
+			t.Logf("skipping %s test", tt.net+" "+tt.laddr)
 			continue
 		}
 		testFileListener(t, tt.net, tt.laddr)
@@ -107,86 +99,78 @@
 func testFilePacketConn(t *testing.T, pcf packetConnFile, listen bool) {
 	f, err := pcf.File()
 	if err != nil {
-		t.Fatalf("File failed: %v", err)
+		t.Fatal(err)
 	}
 	c, err := FilePacketConn(f)
 	if err != nil {
-		t.Fatalf("FilePacketConn failed: %v", err)
+		t.Fatal(err)
 	}
 	if !reflect.DeepEqual(pcf.LocalAddr(), c.LocalAddr()) {
-		t.Fatalf("LocalAddrs not equal: %#v != %#v", pcf.LocalAddr(), c.LocalAddr())
+		t.Fatalf("got %#v; want %#v", pcf.LocalAddr(), c.LocalAddr())
 	}
 	if listen {
 		if _, err := c.WriteTo([]byte{}, c.LocalAddr()); err != nil {
-			t.Fatalf("WriteTo failed: %v", err)
+			t.Fatal(err)
 		}
 	}
 	if err := c.Close(); err != nil {
-		t.Fatalf("Close failed: %v", err)
+		t.Fatal(err)
 	}
 	if err := f.Close(); err != nil {
-		t.Fatalf("Close failed: %v", err)
+		t.Fatal(err)
 	}
 }
 
 func testFilePacketConnListen(t *testing.T, net, laddr string) {
-	switch net {
-	case "udp", "udp4", "udp6":
-		laddr += ":0" // any available port
-	}
 	l, err := ListenPacket(net, laddr)
 	if err != nil {
-		t.Fatalf("ListenPacket failed: %v", err)
+		t.Fatal(err)
 	}
 	testFilePacketConn(t, l.(packetConnFile), true)
 	if err := l.Close(); err != nil {
-		t.Fatalf("Close failed: %v", err)
+		t.Fatal(err)
 	}
 }
 
 func testFilePacketConnDial(t *testing.T, net, raddr string) {
-	switch net {
-	case "udp", "udp4", "udp6":
-		raddr += ":12345"
-	}
 	c, err := Dial(net, raddr)
 	if err != nil {
-		t.Fatalf("Dial failed: %v", err)
+		t.Fatal(err)
 	}
 	testFilePacketConn(t, c.(packetConnFile), false)
 	if err := c.Close(); err != nil {
-		t.Fatalf("Close failed: %v", err)
+		t.Fatal(err)
 	}
 }
 
 var filePacketConnTests = []struct {
-	net   string
-	addr  string
-	ipv6  bool // test with underlying AF_INET6 socket
-	linux bool // test with abstract unix domain socket, a Linux-ism
+	net  string
+	addr string
 }{
-	{net: "udp", addr: "127.0.0.1"},
-	{net: "udp", addr: "[::ffff:127.0.0.1]"},
-	{net: "udp", addr: "[::1]", ipv6: true},
+	{net: "udp", addr: "127.0.0.1:0"},
+	{net: "udp", addr: "[::ffff:127.0.0.1]:0"},
+	{net: "udp", addr: "[::1]:0"},
 
-	{net: "udp4", addr: "127.0.0.1"},
-	{net: "udp4", addr: "[::ffff:127.0.0.1]"},
+	{net: "udp4", addr: "127.0.0.1:0"},
+	{net: "udp4", addr: "[::ffff:127.0.0.1]:0"},
 
-	{net: "udp6", addr: "[::1]", ipv6: true},
+	{net: "udp6", addr: "[::1]:0"},
 
-	{net: "ip4:icmp", addr: "127.0.0.1"},
+	// TODO(mikioh,bradfitz): reenable once 10730 is fixed
+	// {net: "ip4:icmp", addr: "127.0.0.1"},
 
-	{net: "unixgram", addr: "@gotest3/net", linux: true},
+	{net: "unixgram", addr: "@gotest3/net"},
 }
 
 func TestFilePacketConn(t *testing.T) {
 	switch runtime.GOOS {
 	case "nacl", "plan9", "windows":
-		t.Skipf("skipping test on %q", runtime.GOOS)
+		t.Skipf("not supported on %s", runtime.GOOS)
 	}
 
 	for _, tt := range filePacketConnTests {
-		if skipServerTest(tt.net, "unixgram", tt.addr, tt.ipv6, false, tt.linux) {
+		if !testableListenArgs(tt.net, tt.addr, "") {
+			t.Logf("skipping %s test", tt.net+" "+tt.addr)
 			continue
 		}
 		if os.Getuid() != 0 && tt.net == "ip4:icmp" {
@@ -194,12 +178,16 @@
 			continue
 		}
 		testFilePacketConnListen(t, tt.net, tt.addr)
-		switch tt.addr {
-		case "", "0.0.0.0", "[::ffff:0.0.0.0]", "[::]":
-		default:
-			if tt.net != "unixgram" {
-				testFilePacketConnDial(t, tt.net, tt.addr)
+		switch tt.net {
+		case "udp", "udp4", "udp6":
+			host, _, err := SplitHostPort(tt.addr)
+			if err != nil {
+				t.Error(err)
+				continue
 			}
+			testFilePacketConnDial(t, tt.net, JoinHostPort(host, "12345"))
+		case "ip4:icmp":
+			testFilePacketConnDial(t, tt.net, tt.addr)
 		}
 	}
 }
diff --git a/third_party/gofrontend/libgo/go/net/file_unix.go b/third_party/gofrontend/libgo/go/net/file_unix.go
index 214a419..5b24c7d 100644
--- a/third_party/gofrontend/libgo/go/net/file_unix.go
+++ b/third_party/gofrontend/libgo/go/net/file_unix.go
@@ -11,75 +11,59 @@
 	"syscall"
 )
 
-func newFileFD(f *os.File) (*netFD, error) {
-	fd, err := dupCloseOnExec(int(f.Fd()))
+func dupSocket(f *os.File) (int, error) {
+	s, err := dupCloseOnExec(int(f.Fd()))
 	if err != nil {
-		return nil, os.NewSyscallError("dup", err)
+		return -1, err
 	}
-
-	if err = syscall.SetNonblock(fd, true); err != nil {
-		closesocket(fd)
-		return nil, err
+	if err := syscall.SetNonblock(s, true); err != nil {
+		closeFunc(s)
+		return -1, os.NewSyscallError("setnonblock", err)
 	}
-
-	sotype, err := syscall.GetsockoptInt(fd, syscall.SOL_SOCKET, syscall.SO_TYPE)
-	if err != nil {
-		closesocket(fd)
-		return nil, os.NewSyscallError("getsockopt", err)
-	}
-
-	family := syscall.AF_UNSPEC
-	toAddr := sockaddrToTCP
-	lsa, _ := syscall.Getsockname(fd)
-	switch lsa.(type) {
-	default:
-		closesocket(fd)
-		return nil, syscall.EINVAL
-	case *syscall.SockaddrInet4:
-		family = syscall.AF_INET
-		if sotype == syscall.SOCK_DGRAM {
-			toAddr = sockaddrToUDP
-		} else if sotype == syscall.SOCK_RAW {
-			toAddr = sockaddrToIP
-		}
-	case *syscall.SockaddrInet6:
-		family = syscall.AF_INET6
-		if sotype == syscall.SOCK_DGRAM {
-			toAddr = sockaddrToUDP
-		} else if sotype == syscall.SOCK_RAW {
-			toAddr = sockaddrToIP
-		}
-	case *syscall.SockaddrUnix:
-		family = syscall.AF_UNIX
-		toAddr = sockaddrToUnix
-		if sotype == syscall.SOCK_DGRAM {
-			toAddr = sockaddrToUnixgram
-		} else if sotype == syscall.SOCK_SEQPACKET {
-			toAddr = sockaddrToUnixpacket
-		}
-	}
-	laddr := toAddr(lsa)
-	rsa, _ := syscall.Getpeername(fd)
-	raddr := toAddr(rsa)
-
-	netfd, err := newFD(fd, family, sotype, laddr.Network())
-	if err != nil {
-		closesocket(fd)
-		return nil, err
-	}
-	if err := netfd.init(); err != nil {
-		netfd.Close()
-		return nil, err
-	}
-	netfd.setAddr(laddr, raddr)
-	return netfd, nil
+	return s, nil
 }
 
-// FileConn returns a copy of the network connection corresponding to
-// the open file f.  It is the caller's responsibility to close f when
-// finished.  Closing c does not affect f, and closing f does not
-// affect c.
-func FileConn(f *os.File) (c Conn, err error) {
+func newFileFD(f *os.File) (*netFD, error) {
+	s, err := dupSocket(f)
+	if err != nil {
+		return nil, err
+	}
+	family := syscall.AF_UNSPEC
+	sotype, err := syscall.GetsockoptInt(s, syscall.SOL_SOCKET, syscall.SO_TYPE)
+	if err != nil {
+		closeFunc(s)
+		return nil, os.NewSyscallError("getsockopt", err)
+	}
+	lsa, _ := syscall.Getsockname(s)
+	rsa, _ := syscall.Getpeername(s)
+	switch lsa.(type) {
+	case *syscall.SockaddrInet4:
+		family = syscall.AF_INET
+	case *syscall.SockaddrInet6:
+		family = syscall.AF_INET6
+	case *syscall.SockaddrUnix:
+		family = syscall.AF_UNIX
+	default:
+		closeFunc(s)
+		return nil, syscall.EPROTONOSUPPORT
+	}
+	fd, err := newFD(s, family, sotype, "")
+	if err != nil {
+		closeFunc(s)
+		return nil, err
+	}
+	laddr := fd.addrFunc()(lsa)
+	raddr := fd.addrFunc()(rsa)
+	fd.net = laddr.Network()
+	if err := fd.init(); err != nil {
+		fd.Close()
+		return nil, err
+	}
+	fd.setAddr(laddr, raddr)
+	return fd, nil
+}
+
+func fileConn(f *os.File) (Conn, error) {
 	fd, err := newFileFD(f)
 	if err != nil {
 		return nil, err
@@ -98,11 +82,7 @@
 	return nil, syscall.EINVAL
 }
 
-// FileListener returns a copy of the network listener corresponding
-// to the open file f.  It is the caller's responsibility to close l
-// when finished.  Closing l does not affect f, and closing f does not
-// affect l.
-func FileListener(f *os.File) (l Listener, err error) {
+func fileListener(f *os.File) (Listener, error) {
 	fd, err := newFileFD(f)
 	if err != nil {
 		return nil, err
@@ -117,11 +97,7 @@
 	return nil, syscall.EINVAL
 }
 
-// FilePacketConn returns a copy of the packet network connection
-// corresponding to the open file f.  It is the caller's
-// responsibility to close f when finished.  Closing c does not affect
-// f, and closing f does not affect c.
-func FilePacketConn(f *os.File) (c PacketConn, err error) {
+func filePacketConn(f *os.File) (PacketConn, error) {
 	fd, err := newFileFD(f)
 	if err != nil {
 		return nil, err
diff --git a/third_party/gofrontend/libgo/go/net/file_windows.go b/third_party/gofrontend/libgo/go/net/file_windows.go
index ca2b9b2..241fa17 100644
--- a/third_party/gofrontend/libgo/go/net/file_windows.go
+++ b/third_party/gofrontend/libgo/go/net/file_windows.go
@@ -9,29 +9,17 @@
 	"syscall"
 )
 
-// FileConn returns a copy of the network connection corresponding to
-// the open file f.  It is the caller's responsibility to close f when
-// finished.  Closing c does not affect f, and closing f does not
-// affect c.
-func FileConn(f *os.File) (c Conn, err error) {
+func fileConn(f *os.File) (Conn, error) {
 	// TODO: Implement this
-	return nil, os.NewSyscallError("FileConn", syscall.EWINDOWS)
+	return nil, syscall.EWINDOWS
 }
 
-// FileListener returns a copy of the network listener corresponding
-// to the open file f.  It is the caller's responsibility to close l
-// when finished.  Closing l does not affect f, and closing f does not
-// affect l.
-func FileListener(f *os.File) (l Listener, err error) {
+func fileListener(f *os.File) (Listener, error) {
 	// TODO: Implement this
-	return nil, os.NewSyscallError("FileListener", syscall.EWINDOWS)
+	return nil, syscall.EWINDOWS
 }
 
-// FilePacketConn returns a copy of the packet network connection
-// corresponding to the open file f.  It is the caller's
-// responsibility to close f when finished.  Closing c does not affect
-// f, and closing f does not affect c.
-func FilePacketConn(f *os.File) (c PacketConn, err error) {
+func filePacketConn(f *os.File) (PacketConn, error) {
 	// TODO: Implement this
-	return nil, os.NewSyscallError("FilePacketConn", syscall.EWINDOWS)
+	return nil, syscall.EWINDOWS
 }
diff --git a/third_party/gofrontend/libgo/go/net/hook.go b/third_party/gofrontend/libgo/go/net/hook.go
new file mode 100644
index 0000000..9ab34c0
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/net/hook.go
@@ -0,0 +1,12 @@
+// 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 net
+
+var (
+	testHookDialTCP      = dialTCP
+	testHookHostsPath    = "/etc/hosts"
+	testHookLookupIP     = func(fn func(string) ([]IPAddr, error), host string) ([]IPAddr, error) { return fn(host) }
+	testHookSetKeepAlive = func() {}
+)
diff --git a/third_party/gofrontend/libgo/go/net/hook_cloexec.go b/third_party/gofrontend/libgo/go/net/hook_cloexec.go
new file mode 100644
index 0000000..870f0d7
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/net/hook_cloexec.go
@@ -0,0 +1,14 @@
+// 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 freebsd linux
+
+package net
+
+import "syscall"
+
+var (
+	// Placeholders for socket system calls.
+	accept4Func func(int, int) (int, syscall.Sockaddr, error) = syscall.Accept4
+)
diff --git a/third_party/gofrontend/libgo/go/net/hook_plan9.go b/third_party/gofrontend/libgo/go/net/hook_plan9.go
new file mode 100644
index 0000000..e053348
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/net/hook_plan9.go
@@ -0,0 +1,9 @@
+// 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 net
+
+import "time"
+
+var testHookDialChannel = func() { time.Sleep(time.Millisecond) } // see golang.org/issue/5349
diff --git a/third_party/gofrontend/libgo/go/net/hook_unix.go b/third_party/gofrontend/libgo/go/net/hook_unix.go
new file mode 100644
index 0000000..361ca59
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/net/hook_unix.go
@@ -0,0 +1,21 @@
+// 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 darwin dragonfly freebsd linux nacl netbsd openbsd solaris
+
+package net
+
+import "syscall"
+
+var (
+	testHookDialChannel = func() {} // see golang.org/issue/5349
+
+	// Placeholders for socket system calls.
+	socketFunc        func(int, int, int) (int, error)         = syscall.Socket
+	closeFunc         func(int) error                          = syscall.Close
+	connectFunc       func(int, syscall.Sockaddr) error        = syscall.Connect
+	listenFunc        func(int, int) error                     = syscall.Listen
+	acceptFunc        func(int) (int, syscall.Sockaddr, error) = syscall.Accept
+	getsockoptIntFunc func(int, int, int) (int, error)         = syscall.GetsockoptInt
+)
diff --git a/third_party/gofrontend/libgo/go/net/hook_windows.go b/third_party/gofrontend/libgo/go/net/hook_windows.go
new file mode 100644
index 0000000..126b0eb
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/net/hook_windows.go
@@ -0,0 +1,21 @@
+// 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 net
+
+import (
+	"syscall"
+	"time"
+)
+
+var (
+	testHookDialChannel = func() { time.Sleep(time.Millisecond) } // see golang.org/issue/5349
+
+	// Placeholders for socket system calls.
+	socketFunc    func(int, int, int) (syscall.Handle, error)                                               = syscall.Socket
+	closeFunc     func(syscall.Handle) error                                                                = syscall.Closesocket
+	connectFunc   func(syscall.Handle, syscall.Sockaddr) error                                              = syscall.Connect
+	connectExFunc func(syscall.Handle, syscall.Sockaddr, *byte, uint32, *uint32, *syscall.Overlapped) error = syscall.ConnectEx
+	listenFunc    func(syscall.Handle, int) error                                                           = syscall.Listen
+)
diff --git a/third_party/gofrontend/libgo/go/net/hosts.go b/third_party/gofrontend/libgo/go/net/hosts.go
index 9400503..27958c7 100644
--- a/third_party/gofrontend/libgo/go/net/hosts.go
+++ b/third_party/gofrontend/libgo/go/net/hosts.go
@@ -2,8 +2,6 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-// Read static host/IP entries from /etc/hosts.
-
 package net
 
 import (
@@ -13,8 +11,21 @@
 
 const cacheMaxAge = 5 * time.Minute
 
-// hostsPath points to the file with static IP/address entries.
-var hostsPath = "/etc/hosts"
+func parseLiteralIP(addr string) string {
+	var ip IP
+	var zone string
+	ip = parseIPv4(addr)
+	if ip == nil {
+		ip, zone = parseIPv6(addr, true)
+	}
+	if ip == nil {
+		return ""
+	}
+	if zone == "" {
+		return ip.String()
+	}
+	return ip.String() + "%" + zone
+}
 
 // Simple cache.
 var hosts struct {
@@ -27,7 +38,7 @@
 
 func readHosts() {
 	now := time.Now()
-	hp := hostsPath
+	hp := testHookHostsPath
 	if len(hosts.byName) == 0 || now.After(hosts.expire) || hosts.path != hp {
 		hs := make(map[string][]string)
 		is := make(map[string][]string)
@@ -41,13 +52,17 @@
 				line = line[0:i]
 			}
 			f := getFields(line)
-			if len(f) < 2 || ParseIP(f[0]) == nil {
+			if len(f) < 2 {
+				continue
+			}
+			addr := parseLiteralIP(f[0])
+			if addr == "" {
 				continue
 			}
 			for i := 1; i < len(f); i++ {
 				h := f[i]
-				hs[h] = append(hs[h], f[0])
-				is[f[0]] = append(is[f[0]], h)
+				hs[h] = append(hs[h], addr)
+				is[addr] = append(is[addr], h)
 			}
 		}
 		// Update the data cache.
@@ -77,6 +92,10 @@
 	hosts.Lock()
 	defer hosts.Unlock()
 	readHosts()
+	addr = parseLiteralIP(addr)
+	if addr == "" {
+		return nil
+	}
 	if len(hosts.byAddr) != 0 {
 		if hosts, ok := hosts.byAddr[addr]; ok {
 			return hosts
diff --git a/third_party/gofrontend/libgo/go/net/hosts_test.go b/third_party/gofrontend/libgo/go/net/hosts_test.go
index 2fe358e..aca64c3 100644
--- a/third_party/gofrontend/libgo/go/net/hosts_test.go
+++ b/third_party/gofrontend/libgo/go/net/hosts_test.go
@@ -5,77 +5,116 @@
 package net
 
 import (
-	"sort"
+	"reflect"
 	"testing"
 )
 
-type hostTest struct {
-	host string
-	ips  []IP
+type staticHostEntry struct {
+	in  string
+	out []string
 }
 
-var hosttests = []hostTest{
-	{"odin", []IP{
-		IPv4(127, 0, 0, 2),
-		IPv4(127, 0, 0, 3),
-		ParseIP("::2"),
-	}},
-	{"thor", []IP{
-		IPv4(127, 1, 1, 1),
-	}},
-	{"loki", []IP{}},
-	{"ullr", []IP{
-		IPv4(127, 1, 1, 2),
-	}},
-	{"ullrhost", []IP{
-		IPv4(127, 1, 1, 2),
-	}},
+var lookupStaticHostTests = []struct {
+	name string
+	ents []staticHostEntry
+}{
+	{
+		"testdata/hosts",
+		[]staticHostEntry{
+			{"odin", []string{"127.0.0.2", "127.0.0.3", "::2"}},
+			{"thor", []string{"127.1.1.1"}},
+			{"ullr", []string{"127.1.1.2"}},
+			{"ullrhost", []string{"127.1.1.2"}},
+			{"localhost", []string{"fe80::1%lo0"}},
+		},
+	},
+	{
+		"testdata/singleline-hosts", // see golang.org/issue/6646
+		[]staticHostEntry{
+			{"odin", []string{"127.0.0.2"}},
+		},
+	},
+	{
+		"testdata/ipv4-hosts", // see golang.org/issue/8996
+		[]staticHostEntry{
+			{"localhost", []string{"127.0.0.1", "127.0.0.2", "127.0.0.3"}},
+			{"localhost.localdomain", []string{"127.0.0.3"}},
+		},
+	},
+	{
+		"testdata/ipv6-hosts", // see golang.org/issue/8996
+		[]staticHostEntry{
+			{"localhost", []string{"::1", "fe80::1", "fe80::2%lo0", "fe80::3%lo0"}},
+			{"localhost.localdomain", []string{"fe80::3%lo0"}},
+		},
+	},
 }
 
 func TestLookupStaticHost(t *testing.T) {
-	p := hostsPath
-	hostsPath = "testdata/hosts"
-	for i := 0; i < len(hosttests); i++ {
-		tt := hosttests[i]
-		ips := lookupStaticHost(tt.host)
-		if len(ips) != len(tt.ips) {
-			t.Errorf("# of hosts = %v; want %v",
-				len(ips), len(tt.ips))
-			continue
-		}
-		for k, v := range ips {
-			if tt.ips[k].String() != v {
-				t.Errorf("lookupStaticHost(%q) = %v; want %v",
-					tt.host, v, tt.ips[k])
+	defer func(orig string) { testHookHostsPath = orig }(testHookHostsPath)
+
+	for _, tt := range lookupStaticHostTests {
+		testHookHostsPath = tt.name
+		for _, ent := range tt.ents {
+			addrs := lookupStaticHost(ent.in)
+			if !reflect.DeepEqual(addrs, ent.out) {
+				t.Errorf("%s, lookupStaticHost(%s) = %v; want %v", tt.name, ent.in, addrs, ent.out)
 			}
 		}
 	}
-	hostsPath = p
 }
 
-// https://code.google.com/p/go/issues/detail?id=6646
-func TestSingleLineHostsFile(t *testing.T) {
-	p := hostsPath
-	hostsPath = "testdata/hosts_singleline"
-
-	ips := lookupStaticHost("odin")
-	if len(ips) != 1 || ips[0] != "127.0.0.2" {
-		t.Errorf("lookupStaticHost = %v, want %v", ips, []string{"127.0.0.2"})
-	}
-
-	hostsPath = p
+var lookupStaticAddrTests = []struct {
+	name string
+	ents []staticHostEntry
+}{
+	{
+		"testdata/hosts",
+		[]staticHostEntry{
+			{"255.255.255.255", []string{"broadcasthost"}},
+			{"127.0.0.2", []string{"odin"}},
+			{"127.0.0.3", []string{"odin"}},
+			{"::2", []string{"odin"}},
+			{"127.1.1.1", []string{"thor"}},
+			{"127.1.1.2", []string{"ullr", "ullrhost"}},
+			{"fe80::1%lo0", []string{"localhost"}},
+		},
+	},
+	{
+		"testdata/singleline-hosts", // see golang.org/issue/6646
+		[]staticHostEntry{
+			{"127.0.0.2", []string{"odin"}},
+		},
+	},
+	{
+		"testdata/ipv4-hosts", // see golang.org/issue/8996
+		[]staticHostEntry{
+			{"127.0.0.1", []string{"localhost"}},
+			{"127.0.0.2", []string{"localhost"}},
+			{"127.0.0.3", []string{"localhost", "localhost.localdomain"}},
+		},
+	},
+	{
+		"testdata/ipv6-hosts", // see golang.org/issue/8996
+		[]staticHostEntry{
+			{"::1", []string{"localhost"}},
+			{"fe80::1", []string{"localhost"}},
+			{"fe80::2%lo0", []string{"localhost"}},
+			{"fe80::3%lo0", []string{"localhost", "localhost.localdomain"}},
+		},
+	},
 }
 
-func TestLookupHost(t *testing.T) {
-	// Can't depend on this to return anything in particular,
-	// but if it does return something, make sure it doesn't
-	// duplicate addresses (a common bug due to the way
-	// getaddrinfo works).
-	addrs, _ := LookupHost("localhost")
-	sort.Strings(addrs)
-	for i := 0; i+1 < len(addrs); i++ {
-		if addrs[i] == addrs[i+1] {
-			t.Fatalf("LookupHost(\"localhost\") = %v, has duplicate addresses", addrs)
+func TestLookupStaticAddr(t *testing.T) {
+	defer func(orig string) { testHookHostsPath = orig }(testHookHostsPath)
+
+	for _, tt := range lookupStaticAddrTests {
+		testHookHostsPath = tt.name
+		for _, ent := range tt.ents {
+			hosts := lookupStaticAddr(ent.in)
+			if !reflect.DeepEqual(hosts, ent.out) {
+				t.Errorf("%s, lookupStaticAddr(%s) = %v; want %v", tt.name, ent.in, hosts, ent.out)
+			}
 		}
 	}
 }
diff --git a/third_party/gofrontend/libgo/go/net/http/cgi/child.go b/third_party/gofrontend/libgo/go/net/http/cgi/child.go
index 45fc2e5..ec10108 100644
--- a/third_party/gofrontend/libgo/go/net/http/cgi/child.go
+++ b/third_party/gofrontend/libgo/go/net/http/cgi/child.go
@@ -132,9 +132,9 @@
 	}
 
 	// Request.RemoteAddr has its port set by Go's standard http
-	// server, so we do here too. We don't have one, though, so we
-	// use a dummy one.
-	r.RemoteAddr = net.JoinHostPort(params["REMOTE_ADDR"], "0")
+	// server, so we do here too.
+	remotePort, _ := strconv.Atoi(params["REMOTE_PORT"]) // zero if unset or invalid
+	r.RemoteAddr = net.JoinHostPort(params["REMOTE_ADDR"], strconv.Itoa(remotePort))
 
 	return r, nil
 }
diff --git a/third_party/gofrontend/libgo/go/net/http/cgi/child_test.go b/third_party/gofrontend/libgo/go/net/http/cgi/child_test.go
index 075d841..14e0af4 100644
--- a/third_party/gofrontend/libgo/go/net/http/cgi/child_test.go
+++ b/third_party/gofrontend/libgo/go/net/http/cgi/child_test.go
@@ -22,6 +22,7 @@
 		"CONTENT_LENGTH":  "123",
 		"CONTENT_TYPE":    "text/xml",
 		"REMOTE_ADDR":     "5.6.7.8",
+		"REMOTE_PORT":     "54321",
 	}
 	req, err := RequestFromMap(env)
 	if err != nil {
@@ -60,7 +61,7 @@
 	if req.TLS != nil {
 		t.Errorf("expected nil TLS")
 	}
-	if e, g := "5.6.7.8:0", req.RemoteAddr; e != g {
+	if e, g := "5.6.7.8:54321", req.RemoteAddr; e != g {
 		t.Errorf("RemoteAddr: got %q; want %q", g, e)
 	}
 }
@@ -129,3 +130,21 @@
 		t.Errorf("URL = %q; want %q", g, e)
 	}
 }
+
+func TestRequestWithoutRemotePort(t *testing.T) {
+	env := map[string]string{
+		"SERVER_PROTOCOL": "HTTP/1.1",
+		"HTTP_HOST":       "example.com",
+		"REQUEST_METHOD":  "GET",
+		"REQUEST_URI":     "/path?a=b",
+		"CONTENT_LENGTH":  "123",
+		"REMOTE_ADDR":     "5.6.7.8",
+	}
+	req, err := RequestFromMap(env)
+	if err != nil {
+		t.Fatalf("RequestFromMap: %v", err)
+	}
+	if e, g := "5.6.7.8:0", req.RemoteAddr; e != g {
+		t.Errorf("RemoteAddr: got %q; want %q", g, e)
+	}
+}
diff --git a/third_party/gofrontend/libgo/go/net/http/cgi/host.go b/third_party/gofrontend/libgo/go/net/http/cgi/host.go
index ec95a97..4efbe7a 100644
--- a/third_party/gofrontend/libgo/go/net/http/cgi/host.go
+++ b/third_party/gofrontend/libgo/go/net/http/cgi/host.go
@@ -19,6 +19,7 @@
 	"fmt"
 	"io"
 	"log"
+	"net"
 	"net/http"
 	"os"
 	"os/exec"
@@ -128,11 +129,16 @@
 		"PATH_INFO=" + pathInfo,
 		"SCRIPT_NAME=" + root,
 		"SCRIPT_FILENAME=" + h.Path,
-		"REMOTE_ADDR=" + req.RemoteAddr,
-		"REMOTE_HOST=" + req.RemoteAddr,
 		"SERVER_PORT=" + port,
 	}
 
+	if remoteIP, remotePort, err := net.SplitHostPort(req.RemoteAddr); err == nil {
+		env = append(env, "REMOTE_ADDR="+remoteIP, "REMOTE_HOST="+remoteIP, "REMOTE_PORT="+remotePort)
+	} else {
+		// could not parse ip:port, let's use whole RemoteAddr and leave REMOTE_PORT undefined
+		env = append(env, "REMOTE_ADDR="+req.RemoteAddr, "REMOTE_HOST="+req.RemoteAddr)
+	}
+
 	if req.TLS != nil {
 		env = append(env, "HTTPS=on")
 	}
diff --git a/third_party/gofrontend/libgo/go/net/http/cgi/host_test.go b/third_party/gofrontend/libgo/go/net/http/cgi/host_test.go
index b514e10..f341110 100644
--- a/third_party/gofrontend/libgo/go/net/http/cgi/host_test.go
+++ b/third_party/gofrontend/libgo/go/net/http/cgi/host_test.go
@@ -29,7 +29,7 @@
 	if err != nil {
 		panic("cgi: bogus http request in test: " + httpreq)
 	}
-	req.RemoteAddr = "1.2.3.4"
+	req.RemoteAddr = "1.2.3.4:1234"
 	return req
 }
 
@@ -37,7 +37,11 @@
 	rw := httptest.NewRecorder()
 	req := newRequest(httpreq)
 	h.ServeHTTP(rw, req)
+	runResponseChecks(t, rw, expectedMap)
+	return rw
+}
 
+func runResponseChecks(t *testing.T, rw *httptest.ResponseRecorder, expectedMap map[string]string) {
 	// Make a map to hold the test map that the CGI returns.
 	m := make(map[string]string)
 	m["_body"] = rw.Body.String()
@@ -75,7 +79,6 @@
 			t.Errorf("for key %q got %q; expected %q", key, got, expected)
 		}
 	}
-	return rw
 }
 
 var cgiTested, cgiWorks bool
@@ -108,6 +111,7 @@
 		"env-QUERY_STRING":      "foo=bar&a=b",
 		"env-REMOTE_ADDR":       "1.2.3.4",
 		"env-REMOTE_HOST":       "1.2.3.4",
+		"env-REMOTE_PORT":       "1234",
 		"env-REQUEST_METHOD":    "GET",
 		"env-REQUEST_URI":       "/test.cgi?foo=bar&a=b",
 		"env-SCRIPT_FILENAME":   "testdata/test.cgi",
@@ -126,6 +130,39 @@
 	}
 }
 
+func TestCGIEnvIPv6(t *testing.T) {
+	check(t)
+	h := &Handler{
+		Path: "testdata/test.cgi",
+		Root: "/test.cgi",
+	}
+	expectedMap := map[string]string{
+		"test":                  "Hello CGI",
+		"param-a":               "b",
+		"param-foo":             "bar",
+		"env-GATEWAY_INTERFACE": "CGI/1.1",
+		"env-HTTP_HOST":         "example.com",
+		"env-PATH_INFO":         "",
+		"env-QUERY_STRING":      "foo=bar&a=b",
+		"env-REMOTE_ADDR":       "2000::3000",
+		"env-REMOTE_HOST":       "2000::3000",
+		"env-REMOTE_PORT":       "12345",
+		"env-REQUEST_METHOD":    "GET",
+		"env-REQUEST_URI":       "/test.cgi?foo=bar&a=b",
+		"env-SCRIPT_FILENAME":   "testdata/test.cgi",
+		"env-SCRIPT_NAME":       "/test.cgi",
+		"env-SERVER_NAME":       "example.com",
+		"env-SERVER_PORT":       "80",
+		"env-SERVER_SOFTWARE":   "go",
+	}
+
+	rw := httptest.NewRecorder()
+	req := newRequest("GET /test.cgi?foo=bar&a=b HTTP/1.0\nHost: example.com\n\n")
+	req.RemoteAddr = "[2000::3000]:12345"
+	h.ServeHTTP(rw, req)
+	runResponseChecks(t, rw, expectedMap)
+}
+
 func TestCGIBasicGetAbsPath(t *testing.T) {
 	check(t)
 	pwd, err := os.Getwd()
@@ -289,7 +326,7 @@
 	}
 	expectedMap := map[string]string{
 		"basepath":   "/foo",
-		"remoteaddr": "1.2.3.4",
+		"remoteaddr": "1.2.3.4:1234",
 	}
 	runCgiTest(t, h, "GET /test.cgi?loc=/foo HTTP/1.0\nHost: example.com\n\n", expectedMap)
 }
diff --git a/third_party/gofrontend/libgo/go/net/http/cgi/matryoshka_test.go b/third_party/gofrontend/libgo/go/net/http/cgi/matryoshka_test.go
index 18c4803..32d59c0 100644
--- a/third_party/gofrontend/libgo/go/net/http/cgi/matryoshka_test.go
+++ b/third_party/gofrontend/libgo/go/net/http/cgi/matryoshka_test.go
@@ -12,11 +12,11 @@
 	"bytes"
 	"errors"
 	"fmt"
+	"internal/testenv"
 	"io"
 	"net/http"
 	"net/http/httptest"
 	"os"
-	"runtime"
 	"testing"
 	"time"
 )
@@ -24,9 +24,7 @@
 // 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")
-	}
+	testenv.MustHaveExec(t)
 
 	h := &Handler{
 		Path: os.Args[0],
@@ -43,6 +41,7 @@
 		"env-QUERY_STRING":      "foo=bar&a=b",
 		"env-REMOTE_ADDR":       "1.2.3.4",
 		"env-REMOTE_HOST":       "1.2.3.4",
+		"env-REMOTE_PORT":       "1234",
 		"env-REQUEST_METHOD":    "GET",
 		"env-REQUEST_URI":       "/test.go?foo=bar&a=b",
 		"env-SCRIPT_FILENAME":   os.Args[0],
@@ -92,9 +91,7 @@
 // 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")
-	}
+	testenv.MustHaveExec(t)
 
 	defer func() { testHookStartProcess = nil }()
 	proc := make(chan *os.Process, 1)
@@ -139,9 +136,7 @@
 // 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")
-	}
+	testenv.MustHaveExec(t)
 
 	h := &Handler{
 		Path: os.Args[0],
diff --git a/third_party/gofrontend/libgo/go/net/http/cgi/testdata/test.cgi b/third_party/gofrontend/libgo/go/net/http/cgi/testdata/test.cgi
index 3214df6..ec7ee6f 100755
--- a/third_party/gofrontend/libgo/go/net/http/cgi/testdata/test.cgi
+++ b/third_party/gofrontend/libgo/go/net/http/cgi/testdata/test.cgi
@@ -45,7 +45,7 @@
 
 # NOTE: msys perl returns /c/go/src/... not C:\go\....
 my $dir = getcwd();
-if ($^O eq 'MSWin32' || $^O eq 'msys') {
+if ($^O eq 'MSWin32' || $^O eq 'msys' || $^O eq 'cygwin') {
     if ($dir =~ /^.:/) {
         $dir =~ s!/!\\!g;
     } else {
diff --git a/third_party/gofrontend/libgo/go/net/http/client.go b/third_party/gofrontend/libgo/go/net/http/client.go
index ce884d1..7f2fbb4 100644
--- a/third_party/gofrontend/libgo/go/net/http/client.go
+++ b/third_party/gofrontend/libgo/go/net/http/client.go
@@ -19,6 +19,7 @@
 	"net/url"
 	"strings"
 	"sync"
+	"sync/atomic"
 	"time"
 )
 
@@ -211,7 +212,7 @@
 		req.Header = make(Header)
 	}
 
-	if u := req.URL.User; u != nil {
+	if u := req.URL.User; u != nil && req.Header.Get("Authorization") == "" {
 		username := u.Username()
 		password, _ := u.Password()
 		req.Header.Set("Authorization", "Basic "+basicAuth(username, password))
@@ -256,8 +257,9 @@
 	return false
 }
 
-// Get issues a GET to the specified URL.  If the response is one of the following
-// redirect codes, Get follows the redirect, up to a maximum of 10 redirects:
+// Get issues a GET to the specified URL. If the response is one of
+// the following redirect codes, Get follows the redirect, up to a
+// maximum of 10 redirects:
 //
 //    301 (Moved Permanently)
 //    302 (Found)
@@ -272,13 +274,16 @@
 // Caller should close resp.Body when done reading from it.
 //
 // Get is a wrapper around DefaultClient.Get.
+//
+// To make a request with custom headers, use NewRequest and
+// DefaultClient.Do.
 func Get(url string) (resp *Response, err error) {
 	return DefaultClient.Get(url)
 }
 
-// Get issues a GET to the specified URL.  If the response is one of the
+// Get issues a GET to the specified URL. If the response is one of the
 // following redirect codes, Get follows the redirect after calling the
-// Client's CheckRedirect function.
+// Client's CheckRedirect function:
 //
 //    301 (Moved Permanently)
 //    302 (Found)
@@ -291,6 +296,8 @@
 //
 // When err is nil, resp always contains a non-nil resp.Body.
 // Caller should close resp.Body when done reading from it.
+//
+// To make a request with custom headers, use NewRequest and Client.Do.
 func (c *Client) Get(url string) (resp *Response, err error) {
 	req, err := NewRequest("GET", url, nil)
 	if err != nil {
@@ -299,6 +306,8 @@
 	return c.doFollowingRedirects(req, shouldRedirectGet)
 }
 
+func alwaysFalse() bool { return false }
+
 func (c *Client) doFollowingRedirects(ireq *Request, shouldRedirect func(int) bool) (resp *Response, err error) {
 	var base *url.URL
 	redirectChecker := c.CheckRedirect
@@ -316,7 +325,10 @@
 	req := ireq
 
 	var timer *time.Timer
+	var atomicWasCanceled int32 // atomic bool (1 or 0)
+	var wasCanceled = alwaysFalse
 	if c.Timeout > 0 {
+		wasCanceled = func() bool { return atomic.LoadInt32(&atomicWasCanceled) != 0 }
 		type canceler interface {
 			CancelRequest(*Request)
 		}
@@ -325,6 +337,7 @@
 			return nil, fmt.Errorf("net/http: Client Transport of type %T doesn't support CancelRequest; Timeout not supported", c.transport())
 		}
 		timer = time.AfterFunc(c.Timeout, func() {
+			atomic.StoreInt32(&atomicWasCanceled, 1)
 			reqmu.Lock()
 			defer reqmu.Unlock()
 			tr.CancelRequest(req)
@@ -365,6 +378,12 @@
 
 		urlStr = req.URL.String()
 		if resp, err = c.send(req); err != nil {
+			if wasCanceled() {
+				err = &httpError{
+					err:     err.Error() + " (Client.Timeout exceeded while awaiting headers)",
+					timeout: true,
+				}
+			}
 			break
 		}
 
@@ -377,7 +396,7 @@
 			}
 			resp.Body.Close()
 			if urlStr = resp.Header.Get("Location"); urlStr == "" {
-				err = errors.New(fmt.Sprintf("%d response missing Location header", resp.StatusCode))
+				err = fmt.Errorf("%d response missing Location header", resp.StatusCode)
 				break
 			}
 			base = req.URL
@@ -385,7 +404,11 @@
 			continue
 		}
 		if timer != nil {
-			resp.Body = &cancelTimerBody{timer, resp.Body}
+			resp.Body = &cancelTimerBody{
+				t:              timer,
+				rc:             resp.Body,
+				reqWasCanceled: wasCanceled,
+			}
 		}
 		return resp, nil
 	}
@@ -400,7 +423,7 @@
 	if redirectFailed {
 		// Special case for Go 1 compatibility: return both the response
 		// and an error if the CheckRedirect function failed.
-		// See http://golang.org/issue/3795
+		// See https://golang.org/issue/3795
 		return resp, urlErr
 	}
 
@@ -421,7 +444,12 @@
 //
 // Caller should close resp.Body when done reading from it.
 //
-// Post is a wrapper around DefaultClient.Post
+// If the provided body is an io.Closer, it is closed after the
+// request.
+//
+// Post is a wrapper around DefaultClient.Post.
+//
+// To set custom headers, use NewRequest and DefaultClient.Do.
 func Post(url string, bodyType string, body io.Reader) (resp *Response, err error) {
 	return DefaultClient.Post(url, bodyType, body)
 }
@@ -430,8 +458,10 @@
 //
 // Caller should close resp.Body when done reading from it.
 //
-// If the provided body is also an io.Closer, it is closed after the
+// If the provided body is an io.Closer, it is closed after the
 // request.
+//
+// To set custom headers, use NewRequest and Client.Do.
 func (c *Client) Post(url string, bodyType string, body io.Reader) (resp *Response, err error) {
 	req, err := NewRequest("POST", url, body)
 	if err != nil {
@@ -444,16 +474,22 @@
 // PostForm issues a POST to the specified URL, with data's keys and
 // values URL-encoded as the request body.
 //
+// The Content-Type header is set to application/x-www-form-urlencoded.
+// To set other headers, use NewRequest and DefaultClient.Do.
+//
 // When err is nil, resp always contains a non-nil resp.Body.
 // Caller should close resp.Body when done reading from it.
 //
-// PostForm is a wrapper around DefaultClient.PostForm
+// PostForm is a wrapper around DefaultClient.PostForm.
 func PostForm(url string, data url.Values) (resp *Response, err error) {
 	return DefaultClient.PostForm(url, data)
 }
 
 // PostForm issues a POST to the specified URL,
-// with data's keys and values urlencoded as the request body.
+// with data's keys and values URL-encoded as the request body.
+//
+// The Content-Type header is set to application/x-www-form-urlencoded.
+// To set other headers, use NewRequest and DefaultClient.Do.
 //
 // When err is nil, resp always contains a non-nil resp.Body.
 // Caller should close resp.Body when done reading from it.
@@ -461,9 +497,9 @@
 	return c.Post(url, "application/x-www-form-urlencoded", strings.NewReader(data.Encode()))
 }
 
-// Head issues a HEAD to the specified URL.  If the response is one of the
-// following redirect codes, Head follows the redirect after calling the
-// Client's CheckRedirect function.
+// Head issues a HEAD to the specified URL.  If the response is one of
+// the following redirect codes, Head follows the redirect, up to a
+// maximum of 10 redirects:
 //
 //    301 (Moved Permanently)
 //    302 (Found)
@@ -477,7 +513,7 @@
 
 // Head issues a HEAD to the specified URL.  If the response is one of the
 // following redirect codes, Head follows the redirect after calling the
-// Client's CheckRedirect function.
+// Client's CheckRedirect function:
 //
 //    301 (Moved Permanently)
 //    302 (Found)
@@ -491,15 +527,25 @@
 	return c.doFollowingRedirects(req, shouldRedirectGet)
 }
 
+// cancelTimerBody is an io.ReadCloser that wraps rc with two features:
+// 1) on Read EOF or Close, the timer t is Stopped,
+// 2) On Read failure, if reqWasCanceled is true, the error is wrapped and
+//    marked as net.Error that hit its timeout.
 type cancelTimerBody struct {
-	t  *time.Timer
-	rc io.ReadCloser
+	t              *time.Timer
+	rc             io.ReadCloser
+	reqWasCanceled func() bool
 }
 
 func (b *cancelTimerBody) Read(p []byte) (n int, err error) {
 	n, err = b.rc.Read(p)
 	if err == io.EOF {
 		b.t.Stop()
+	} else if err != nil && b.reqWasCanceled() {
+		return n, &httpError{
+			err:     err.Error() + " (Client.Timeout exceeded while reading body)",
+			timeout: true,
+		}
 	}
 	return
 }
diff --git a/third_party/gofrontend/libgo/go/net/http/client_test.go b/third_party/gofrontend/libgo/go/net/http/client_test.go
index 56b6563..7b524d3 100644
--- a/third_party/gofrontend/libgo/go/net/http/client_test.go
+++ b/third_party/gofrontend/libgo/go/net/http/client_test.go
@@ -258,7 +258,7 @@
 		t.Errorf("with redirects forbidden, expected a *url.Error with our 'no redirects allowed' error inside; got %#v (%q)", err, err)
 	}
 	if res == nil {
-		t.Fatalf("Expected a non-nil Response on CheckRedirect failure (http://golang.org/issue/3795)")
+		t.Fatalf("Expected a non-nil Response on CheckRedirect failure (https://golang.org/issue/3795)")
 	}
 	res.Body.Close()
 	if res.Header.Get("Location") == "" {
@@ -334,6 +334,7 @@
 })
 
 func TestClientSendsCookieFromJar(t *testing.T) {
+	defer afterTest(t)
 	tr := &recordingTransport{}
 	client := &Client{Transport: tr}
 	client.Jar = &TestJar{perURL: make(map[string][]*Cookie)}
@@ -426,7 +427,7 @@
 	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
 		pathSuffix := r.RequestURI[1:]
 		if r.RequestURI == "/nosetcookie" {
-			return // dont set cookies for this path
+			return // don't set cookies for this path
 		}
 		SetCookie(w, &Cookie{Name: "name" + pathSuffix, Value: "val" + pathSuffix})
 		if r.RequestURI == "/" {
@@ -738,7 +739,7 @@
 	}
 }
 
-// Verify Response.ContentLength is populated. http://golang.org/issue/4126
+// Verify Response.ContentLength is populated. https://golang.org/issue/4126
 func TestClientHeadContentLength(t *testing.T) {
 	defer afterTest(t)
 	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
@@ -842,6 +843,47 @@
 	}
 }
 
+func TestBasicAuthHeadersPreserved(t *testing.T) {
+	defer afterTest(t)
+	tr := &recordingTransport{}
+	client := &Client{Transport: tr}
+
+	// If Authorization header is provided, username in URL should not override it
+	url := "http://My%20User@dummy.faketld/"
+	req, err := NewRequest("GET", url, nil)
+	if err != nil {
+		t.Fatal(err)
+	}
+	req.SetBasicAuth("My User", "My Pass")
+	expected := "My User:My Pass"
+	client.Do(req)
+
+	if tr.req.Method != "GET" {
+		t.Errorf("got method %q, want %q", tr.req.Method, "GET")
+	}
+	if tr.req.URL.String() != url {
+		t.Errorf("got URL %q, want %q", tr.req.URL.String(), url)
+	}
+	if tr.req.Header == nil {
+		t.Fatalf("expected non-nil request Header")
+	}
+	auth := tr.req.Header.Get("Authorization")
+	if strings.HasPrefix(auth, "Basic ") {
+		encoded := auth[6:]
+		decoded, err := base64.StdEncoding.DecodeString(encoded)
+		if err != nil {
+			t.Fatal(err)
+		}
+		s := string(decoded)
+		if expected != s {
+			t.Errorf("Invalid Authorization header. Got %q, wanted %q", s, expected)
+		}
+	} else {
+		t.Errorf("Invalid auth %q", auth)
+	}
+
+}
+
 func TestClientTimeout(t *testing.T) {
 	if testing.Short() {
 		t.Skip("skipping in short mode")
@@ -899,14 +941,64 @@
 	select {
 	case err := <-errc:
 		if err == nil {
-			t.Error("expected error from ReadAll")
+			t.Fatal("expected error from ReadAll")
 		}
-		// Expected error.
+		ne, ok := err.(net.Error)
+		if !ok {
+			t.Errorf("error value from ReadAll was %T; expected some net.Error", err)
+		} else if !ne.Timeout() {
+			t.Errorf("net.Error.Timeout = false; want true")
+		}
+		if got := ne.Error(); !strings.Contains(got, "Client.Timeout exceeded") {
+			t.Errorf("error string = %q; missing timeout substring", got)
+		}
 	case <-time.After(failTime):
 		t.Errorf("timeout after %v waiting for timeout of %v", failTime, timeout)
 	}
 }
 
+// Client.Timeout firing before getting to the body
+func TestClientTimeout_Headers(t *testing.T) {
+	if testing.Short() {
+		t.Skip("skipping in short mode")
+	}
+	defer afterTest(t)
+	donec := make(chan bool)
+	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
+		<-donec
+	}))
+	defer ts.Close()
+	// Note that we use a channel send here and not a close.
+	// The race detector doesn't know that we're waiting for a timeout
+	// and thinks that the waitgroup inside httptest.Server is added to concurrently
+	// with us closing it. If we timed out immediately, we could close the testserver
+	// before we entered the handler. We're not timing out immediately and there's
+	// no way we would be done before we entered the handler, but the race detector
+	// doesn't know this, so synchronize explicitly.
+	defer func() { donec <- true }()
+
+	c := &Client{Timeout: 500 * time.Millisecond}
+
+	_, err := c.Get(ts.URL)
+	if err == nil {
+		t.Fatal("got response from Get; expected error")
+	}
+	ue, ok := err.(*url.Error)
+	if !ok {
+		t.Fatalf("Got error of type %T; want *url.Error", err)
+	}
+	ne, ok := ue.Err.(net.Error)
+	if !ok {
+		t.Fatalf("Got url.Error.Err of type %T; want some net.Error", err)
+	}
+	if !ne.Timeout() {
+		t.Error("net.Error.Timeout = false; want true")
+	}
+	if got := ne.Error(); !strings.Contains(got, "Client.Timeout exceeded") {
+		t.Errorf("error string = %q; missing timeout substring", got)
+	}
+}
+
 func TestClientRedirectEatsBody(t *testing.T) {
 	defer afterTest(t)
 	saw := make(chan string, 2)
@@ -984,24 +1076,12 @@
 				r.Trailer.Get("Client-Trailer-B"))
 		}
 
-		// TODO: golang.org/issue/7759: there's no way yet for
-		// the server to set trailers without hijacking, so do
-		// that for now, just to test the client.  Later, in
-		// Go 1.4, it should be implicit that any mutations
-		// to w.Header() after the initial write are the
-		// trailers to be sent, if and only if they were
-		// previously declared with w.Header().Set("Trailer",
-		// ..keys..)
-		w.(Flusher).Flush()
-		conn, buf, _ := w.(Hijacker).Hijack()
-		t := Header{}
-		t.Set("Server-Trailer-A", "valuea")
-		t.Set("Server-Trailer-C", "valuec") // skipping B
-		buf.WriteString("0\r\n")            // eof
-		t.Write(buf)
-		buf.WriteString("\r\n") // end of trailers
-		buf.Flush()
-		conn.Close()
+		// How handlers set Trailers: declare it ahead of time
+		// with the Trailer header, and then mutate the
+		// Header() of those values later, after the response
+		// has been written (we wrote to w above).
+		w.Header().Set("Server-Trailer-A", "valuea")
+		w.Header().Set("Server-Trailer-C", "valuec") // skipping B
 	}))
 	defer ts.Close()
 
diff --git a/third_party/gofrontend/libgo/go/net/http/cookie.go b/third_party/gofrontend/libgo/go/net/http/cookie.go
index a0d0fdb..648709d 100644
--- a/third_party/gofrontend/libgo/go/net/http/cookie.go
+++ b/third_party/gofrontend/libgo/go/net/http/cookie.go
@@ -14,19 +14,18 @@
 	"time"
 )
 
-// This implementation is done according to RFC 6265:
-//
-//    http://tools.ietf.org/html/rfc6265
-
 // A Cookie represents an HTTP cookie as sent in the Set-Cookie header of an
 // HTTP response or the Cookie header of an HTTP request.
+//
+// See http://tools.ietf.org/html/rfc6265 for details.
 type Cookie struct {
-	Name       string
-	Value      string
-	Path       string
-	Domain     string
-	Expires    time.Time
-	RawExpires string
+	Name  string
+	Value string
+
+	Path       string    // optional
+	Domain     string    // optional
+	Expires    time.Time // optional
+	RawExpires string    // for reading cookies only
 
 	// MaxAge=0 means no 'Max-Age' attribute specified.
 	// MaxAge<0 means delete cookie now, equivalently 'Max-Age: 0'
@@ -126,14 +125,22 @@
 }
 
 // SetCookie adds a Set-Cookie header to the provided ResponseWriter's headers.
+// The provided cookie must have a valid Name. Invalid cookies may be
+// silently dropped.
 func SetCookie(w ResponseWriter, cookie *Cookie) {
-	w.Header().Add("Set-Cookie", cookie.String())
+	if v := cookie.String(); v != "" {
+		w.Header().Add("Set-Cookie", v)
+	}
 }
 
 // String returns the serialization of the cookie for use in a Cookie
 // header (if only Name and Value are set) or a Set-Cookie response
 // header (if other fields are set).
+// If c is nil or c.Name is invalid, the empty string is returned.
 func (c *Cookie) String() string {
+	if c == nil || !isCookieNameValid(c.Name) {
+		return ""
+	}
 	var b bytes.Buffer
 	fmt.Fprintf(&b, "%s=%s", sanitizeCookieName(c.Name), sanitizeCookieValue(c.Value))
 	if len(c.Path) > 0 {
@@ -156,7 +163,7 @@
 		}
 	}
 	if c.Expires.Unix() > 0 {
-		fmt.Fprintf(&b, "; Expires=%s", c.Expires.UTC().Format(time.RFC1123))
+		fmt.Fprintf(&b, "; Expires=%s", c.Expires.UTC().Format(TimeFormat))
 	}
 	if c.MaxAge > 0 {
 		fmt.Fprintf(&b, "; Max-Age=%d", c.MaxAge)
@@ -297,7 +304,7 @@
 // We loosen this as spaces and commas are common in cookie values
 // but we produce a quoted cookie-value in when value starts or ends
 // with a comma or space.
-// See http://golang.org/issue/7243 for the discussion.
+// See https://golang.org/issue/7243 for the discussion.
 func sanitizeCookieValue(v string) string {
 	v = sanitizeOrWarn("Cookie.Value", validCookieValueByte, v)
 	if len(v) == 0 {
@@ -359,5 +366,8 @@
 }
 
 func isCookieNameValid(raw string) bool {
+	if raw == "" {
+		return false
+	}
 	return strings.IndexFunc(raw, isNotToken) < 0
 }
diff --git a/third_party/gofrontend/libgo/go/net/http/cookie_test.go b/third_party/gofrontend/libgo/go/net/http/cookie_test.go
index 98dc2fa..d474f31 100644
--- a/third_party/gofrontend/libgo/go/net/http/cookie_test.go
+++ b/third_party/gofrontend/libgo/go/net/http/cookie_test.go
@@ -52,6 +52,10 @@
 		&Cookie{Name: "cookie-8", Value: "eight", Domain: "::1"},
 		"cookie-8=eight",
 	},
+	{
+		&Cookie{Name: "cookie-9", Value: "expiring", Expires: time.Unix(1257894000, 0)},
+		"cookie-9=expiring; Expires=Tue, 10 Nov 2009 23:00:00 GMT",
+	},
 	// The "special" cookies have values containing commas or spaces which
 	// are disallowed by RFC 6265 but are common in the wild.
 	{
@@ -90,6 +94,18 @@
 		&Cookie{Name: "empty-value", Value: ""},
 		`empty-value=`,
 	},
+	{
+		nil,
+		``,
+	},
+	{
+		&Cookie{Name: ""},
+		``,
+	},
+	{
+		&Cookie{Name: "\t"},
+		``,
+	},
 }
 
 func TestWriteSetCookies(t *testing.T) {
@@ -349,7 +365,7 @@
 		{Name: "quoted3", Value: "both"},
 	}
 	if len(got) != len(want) {
-		t.Fatal("got %d cookies, want %d", len(got), len(want))
+		t.Fatalf("got %d cookies, want %d", len(got), len(want))
 	}
 	for i, w := range want {
 		g := got[i]
diff --git a/third_party/gofrontend/libgo/go/net/http/example_test.go b/third_party/gofrontend/libgo/go/net/http/example_test.go
index 88b97d9..1774795 100644
--- a/third_party/gofrontend/libgo/go/net/http/example_test.go
+++ b/third_party/gofrontend/libgo/go/net/http/example_test.go
@@ -6,6 +6,7 @@
 
 import (
 	"fmt"
+	"io"
 	"io/ioutil"
 	"log"
 	"net/http"
@@ -86,3 +87,25 @@
 		fmt.Fprintf(w, "Welcome to the home page!")
 	})
 }
+
+// HTTP Trailers are a set of key/value pairs like headers that come
+// after the HTTP response, instead of before.
+func ExampleResponseWriter_trailers() {
+	mux := http.NewServeMux()
+	mux.HandleFunc("/sendstrailers", func(w http.ResponseWriter, req *http.Request) {
+		// Before any call to WriteHeader or Write, declare
+		// the trailers you will set during the HTTP
+		// response. These three headers are actually sent in
+		// the trailer.
+		w.Header().Set("Trailer", "AtEnd1, AtEnd2")
+		w.Header().Add("Trailer", "AtEnd3")
+
+		w.Header().Set("Content-Type", "text/plain; charset=utf-8") // normal header
+		w.WriteHeader(http.StatusOK)
+
+		w.Header().Set("AtEnd1", "value 1")
+		io.WriteString(w, "This HTTP response has both headers before this text and trailers at the end.\n")
+		w.Header().Set("AtEnd2", "value 2")
+		w.Header().Set("AtEnd3", "value 3") // These will appear as trailers.
+	})
+}
diff --git a/third_party/gofrontend/libgo/go/net/http/export_test.go b/third_party/gofrontend/libgo/go/net/http/export_test.go
index 87b6c07..0457be5 100644
--- a/third_party/gofrontend/libgo/go/net/http/export_test.go
+++ b/third_party/gofrontend/libgo/go/net/http/export_test.go
@@ -10,9 +10,17 @@
 import (
 	"net"
 	"net/url"
+	"sync"
 	"time"
 )
 
+func init() {
+	// We only want to pay for this cost during testing.
+	// When not under test, these values are always nil
+	// and never assigned to.
+	testHookMu = new(sync.Mutex)
+}
+
 func NewLoggingConn(baseName string, c net.Conn) net.Conn {
 	return newLoggingConn(baseName, c)
 }
@@ -78,6 +86,20 @@
 	})
 }
 
+func SetInstallConnClosedHook(f func()) {
+	testHookPersistConnClosedGotRes = f
+}
+
+func SetEnterRoundTripHook(f func()) {
+	testHookEnterRoundTrip = f
+}
+
+func SetReadLoopBeforeNextReadHook(f func()) {
+	testHookMu.Lock()
+	defer testHookMu.Unlock()
+	testHookReadLoopBeforeNextRead = f
+}
+
 func NewTestTimeoutHandler(handler Handler, ch <-chan time.Time) Handler {
 	f := func() <-chan time.Time {
 		return ch
@@ -106,3 +128,5 @@
 var ExportServerNewConn = (*Server).newConn
 
 var ExportCloseWriteAndWait = (*conn).closeWriteAndWait
+
+var ExportErrRequestCanceled = errRequestCanceled
diff --git a/third_party/gofrontend/libgo/go/net/http/fcgi/child.go b/third_party/gofrontend/libgo/go/net/http/fcgi/child.go
index a3beaa3..da824ed 100644
--- a/third_party/gofrontend/libgo/go/net/http/fcgi/child.go
+++ b/third_party/gofrontend/libgo/go/net/http/fcgi/child.go
@@ -144,6 +144,7 @@
 
 func (c *child) serve() {
 	defer c.conn.Close()
+	defer c.cleanUp()
 	var rec record
 	for {
 		if err := rec.read(c.conn.rwc); err != nil {
@@ -159,6 +160,14 @@
 
 var emptyBody = ioutil.NopCloser(strings.NewReader(""))
 
+// ErrRequestAborted is returned by Read when a handler attempts to read the
+// body of a request that has been aborted by the web server.
+var ErrRequestAborted = errors.New("fcgi: request aborted by web server")
+
+// ErrConnClosed is returned by Read when a handler attempts to read the body of
+// a request after the connection to the web server has been closed.
+var ErrConnClosed = errors.New("fcgi: connection to web server closed")
+
 func (c *child) handleRecord(rec *record) error {
 	c.mu.Lock()
 	req, ok := c.requests[rec.h.Id]
@@ -227,11 +236,13 @@
 		// If the filter role is implemented, read the data stream here.
 		return nil
 	case typeAbortRequest:
-		println("abort")
 		c.mu.Lock()
 		delete(c.requests, rec.h.Id)
 		c.mu.Unlock()
 		c.conn.writeEndRequest(rec.h.Id, 0, statusRequestComplete)
+		if req.pw != nil {
+			req.pw.CloseWithError(ErrRequestAborted)
+		}
 		if !req.keepConn {
 			// connection will close upon return
 			return errCloseConn
@@ -277,6 +288,18 @@
 	}
 }
 
+func (c *child) cleanUp() {
+	c.mu.Lock()
+	defer c.mu.Unlock()
+	for _, req := range c.requests {
+		if req.pw != nil {
+			// race with call to Close in c.serveRequest doesn't matter because
+			// Pipe(Reader|Writer).Close are idempotent
+			req.pw.CloseWithError(ErrConnClosed)
+		}
+	}
+}
+
 // Serve accepts incoming FastCGI connections on the listener l, creating a new
 // goroutine for each. The goroutine reads requests and then calls handler
 // to reply to them.
diff --git a/third_party/gofrontend/libgo/go/net/http/fcgi/fcgi_test.go b/third_party/gofrontend/libgo/go/net/http/fcgi/fcgi_test.go
index 6c7e1a9..de0f7f8 100644
--- a/third_party/gofrontend/libgo/go/net/http/fcgi/fcgi_test.go
+++ b/third_party/gofrontend/libgo/go/net/http/fcgi/fcgi_test.go
@@ -8,6 +8,8 @@
 	"bytes"
 	"errors"
 	"io"
+	"io/ioutil"
+	"net/http"
 	"testing"
 )
 
@@ -148,3 +150,107 @@
 		t.Errorf(" got: %q\nwant: %q\n", got, want)
 	}
 }
+
+func nameValuePair11(nameData, valueData string) []byte {
+	return bytes.Join(
+		[][]byte{
+			{byte(len(nameData)), byte(len(valueData))},
+			[]byte(nameData),
+			[]byte(valueData),
+		},
+		nil,
+	)
+}
+
+func makeRecord(
+	recordType recType,
+	requestId uint16,
+	contentData []byte,
+) []byte {
+	requestIdB1 := byte(requestId >> 8)
+	requestIdB0 := byte(requestId)
+
+	contentLength := len(contentData)
+	contentLengthB1 := byte(contentLength >> 8)
+	contentLengthB0 := byte(contentLength)
+	return bytes.Join([][]byte{
+		{1, byte(recordType), requestIdB1, requestIdB0, contentLengthB1,
+			contentLengthB0, 0, 0},
+		contentData,
+	},
+		nil)
+}
+
+// a series of FastCGI records that start a request and begin sending the
+// request body
+var streamBeginTypeStdin = bytes.Join([][]byte{
+	// set up request 1
+	makeRecord(typeBeginRequest, 1,
+		[]byte{0, byte(roleResponder), 0, 0, 0, 0, 0, 0}),
+	// add required parameters to request 1
+	makeRecord(typeParams, 1, nameValuePair11("REQUEST_METHOD", "GET")),
+	makeRecord(typeParams, 1, nameValuePair11("SERVER_PROTOCOL", "HTTP/1.1")),
+	makeRecord(typeParams, 1, nil),
+	// begin sending body of request 1
+	makeRecord(typeStdin, 1, []byte("0123456789abcdef")),
+},
+	nil)
+
+var cleanUpTests = []struct {
+	input []byte
+	err   error
+}{
+	// confirm that child.handleRecord closes req.pw after aborting req
+	{
+		bytes.Join([][]byte{
+			streamBeginTypeStdin,
+			makeRecord(typeAbortRequest, 1, nil),
+		},
+			nil),
+		ErrRequestAborted,
+	},
+	// confirm that child.serve closes all pipes after error reading record
+	{
+		bytes.Join([][]byte{
+			streamBeginTypeStdin,
+			nil,
+		},
+			nil),
+		ErrConnClosed,
+	},
+}
+
+type nopWriteCloser struct {
+	io.ReadWriter
+}
+
+func (nopWriteCloser) Close() error {
+	return nil
+}
+
+// Test that child.serve closes the bodies of aborted requests and closes the
+// bodies of all requests before returning. Causes deadlock if either condition
+// isn't met. See issue 6934.
+func TestChildServeCleansUp(t *testing.T) {
+	for _, tt := range cleanUpTests {
+		input := make([]byte, len(tt.input))
+		copy(input, tt.input)
+		rc := nopWriteCloser{bytes.NewBuffer(input)}
+		done := make(chan bool)
+		c := newChild(rc, http.HandlerFunc(func(
+			w http.ResponseWriter,
+			r *http.Request,
+		) {
+			// block on reading body of request
+			_, err := io.Copy(ioutil.Discard, r.Body)
+			if err != tt.err {
+				t.Errorf("Expected %#v, got %#v", tt.err, err)
+			}
+			// not reached if body of request isn't closed
+			done <- true
+		}))
+		go c.serve()
+		// wait for body of request to be closed or all goroutines to block
+		<-done
+	}
+}
diff --git a/third_party/gofrontend/libgo/go/net/http/fs.go b/third_party/gofrontend/libgo/go/net/http/fs.go
index e322f71..7572023 100644
--- a/third_party/gofrontend/libgo/go/net/http/fs.go
+++ b/third_party/gofrontend/libgo/go/net/http/fs.go
@@ -102,10 +102,10 @@
 // The name is otherwise unused; in particular it can be empty and is
 // never sent in the response.
 //
-// If modtime is not the zero time, ServeContent includes it in a
-// Last-Modified header in the response.  If the request includes an
-// If-Modified-Since header, ServeContent uses modtime to decide
-// whether the content needs to be sent at all.
+// If modtime is not the zero time or Unix epoch, ServeContent
+// includes it in a Last-Modified header in the response.  If the
+// request includes an If-Modified-Since header, ServeContent uses
+// modtime to decide whether the content needs to be sent at all.
 //
 // The content's Seek method must work: ServeContent uses
 // a seek to the end of the content to determine its size.
@@ -258,10 +258,15 @@
 	}
 }
 
+var unixEpochTime = time.Unix(0, 0)
+
 // modtime is the modification time of the resource to be served, or IsZero().
 // return value is whether this request is now complete.
 func checkLastModified(w ResponseWriter, r *Request, modtime time.Time) bool {
-	if modtime.IsZero() {
+	if modtime.IsZero() || modtime.Equal(unixEpochTime) {
+		// If the file doesn't have a modtime (IsZero), or the modtime
+		// is obviously garbage (Unix time == 0), then ignore modtimes
+		// and don't process the If-Modified-Since header.
 		return false
 	}
 
@@ -353,16 +358,16 @@
 
 	f, err := fs.Open(name)
 	if err != nil {
-		// TODO expose actual error?
-		NotFound(w, r)
+		msg, code := toHTTPError(err)
+		Error(w, msg, code)
 		return
 	}
 	defer f.Close()
 
 	d, err1 := f.Stat()
 	if err1 != nil {
-		// TODO expose actual error?
-		NotFound(w, r)
+		msg, code := toHTTPError(err)
+		Error(w, msg, code)
 		return
 	}
 
@@ -412,6 +417,22 @@
 	serveContent(w, r, d.Name(), d.ModTime(), sizeFunc, f)
 }
 
+// toHTTPError returns a non-specific HTTP error message and status code
+// for a given non-nil error value. It's important that toHTTPError does not
+// actually return err.Error(), since msg and httpStatus are returned to users,
+// and historically Go's ServeContent always returned just "404 Not Found" for
+// all errors. We don't want to start leaking information in error messages.
+func toHTTPError(err error) (msg string, httpStatus int) {
+	if os.IsNotExist(err) {
+		return "404 page not found", StatusNotFound
+	}
+	if os.IsPermission(err) {
+		return "403 Forbidden", StatusForbidden
+	}
+	// Default:
+	return "500 Internal Server Error", StatusInternalServerError
+}
+
 // localRedirect gives a Moved Permanently response.
 // It does not convert relative paths to absolute paths like Redirect does.
 func localRedirect(w ResponseWriter, r *Request, newPath string) {
@@ -422,7 +443,13 @@
 	w.WriteHeader(StatusMovedPermanently)
 }
 
-// ServeFile replies to the request with the contents of the named file or directory.
+// ServeFile replies to the request with the contents of the named
+// file or directory.
+//
+// As a special case, ServeFile redirects any request where r.URL.Path
+// ends in "/index.html" to the same path, without the final
+// "index.html". To avoid such redirects either modify the path or
+// use ServeContent.
 func ServeFile(w ResponseWriter, r *Request, name string) {
 	dir, file := filepath.Split(name)
 	serveFile(w, r, Dir(dir), file, false)
@@ -439,6 +466,10 @@
 // use http.Dir:
 //
 //     http.Handle("/", http.FileServer(http.Dir("/tmp")))
+//
+// As a special case, the returned file server redirects any request
+// ending in "/index.html" to the same path, without the final
+// "index.html".
 func FileServer(root FileSystem) Handler {
 	return &fileHandler{root}
 }
@@ -503,7 +534,7 @@
 			r.length = size - r.start
 		} else {
 			i, err := strconv.ParseInt(start, 10, 64)
-			if err != nil || i > size || i < 0 {
+			if err != nil || i >= size || i < 0 {
 				return nil, errors.New("invalid range")
 			}
 			r.start = i
diff --git a/third_party/gofrontend/libgo/go/net/http/fs_test.go b/third_party/gofrontend/libgo/go/net/http/fs_test.go
index 2ddd4ca..538f34d 100644
--- a/third_party/gofrontend/libgo/go/net/http/fs_test.go
+++ b/third_party/gofrontend/libgo/go/net/http/fs_test.go
@@ -50,15 +50,23 @@
 	{r: "bytes=2-", code: StatusPartialContent, ranges: []wantRange{{2, testFileLen}}},
 	{r: "bytes=-5", code: StatusPartialContent, ranges: []wantRange{{testFileLen - 5, testFileLen}}},
 	{r: "bytes=3-7", code: StatusPartialContent, ranges: []wantRange{{3, 8}}},
-	{r: "bytes=20-", code: StatusRequestedRangeNotSatisfiable},
 	{r: "bytes=0-0,-2", code: StatusPartialContent, ranges: []wantRange{{0, 1}, {testFileLen - 2, testFileLen}}},
 	{r: "bytes=0-1,5-8", code: StatusPartialContent, ranges: []wantRange{{0, 2}, {5, 9}}},
 	{r: "bytes=0-1,5-", code: StatusPartialContent, ranges: []wantRange{{0, 2}, {5, testFileLen}}},
 	{r: "bytes=5-1000", code: StatusPartialContent, ranges: []wantRange{{5, testFileLen}}},
 	{r: "bytes=0-,1-,2-,3-,4-", code: StatusOK}, // ignore wasteful range request
-	{r: "bytes=0-" + itoa(testFileLen-2), code: StatusPartialContent, ranges: []wantRange{{0, testFileLen - 1}}},
-	{r: "bytes=0-" + itoa(testFileLen-1), code: StatusPartialContent, ranges: []wantRange{{0, testFileLen}}},
-	{r: "bytes=0-" + itoa(testFileLen), code: StatusPartialContent, ranges: []wantRange{{0, testFileLen}}},
+	{r: "bytes=0-9", code: StatusPartialContent, ranges: []wantRange{{0, testFileLen - 1}}},
+	{r: "bytes=0-10", code: StatusPartialContent, ranges: []wantRange{{0, testFileLen}}},
+	{r: "bytes=0-11", code: StatusPartialContent, ranges: []wantRange{{0, testFileLen}}},
+	{r: "bytes=10-11", code: StatusPartialContent, ranges: []wantRange{{testFileLen - 1, testFileLen}}},
+	{r: "bytes=10-", code: StatusPartialContent, ranges: []wantRange{{testFileLen - 1, testFileLen}}},
+	{r: "bytes=11-", code: StatusRequestedRangeNotSatisfiable},
+	{r: "bytes=11-12", code: StatusRequestedRangeNotSatisfiable},
+	{r: "bytes=12-12", code: StatusRequestedRangeNotSatisfiable},
+	{r: "bytes=11-100", code: StatusRequestedRangeNotSatisfiable},
+	{r: "bytes=12-100", code: StatusRequestedRangeNotSatisfiable},
+	{r: "bytes=100-", code: StatusRequestedRangeNotSatisfiable},
+	{r: "bytes=100-1000", code: StatusRequestedRangeNotSatisfiable},
 }
 
 func TestServeFile(t *testing.T) {
@@ -489,6 +497,7 @@
 	modtime  time.Time
 	ents     []*fakeFileInfo
 	contents string
+	err      error
 }
 
 func (f *fakeFileInfo) Name() string       { return f.basename }
@@ -541,6 +550,9 @@
 	if !ok {
 		return nil, os.ErrNotExist
 	}
+	if f.err != nil {
+		return nil, f.err
+	}
 	return &fakeFile{ReadSeeker: strings.NewReader(f.contents), fi: f, path: name}, nil
 }
 
@@ -743,6 +755,12 @@
 			wantContentType: "text/css; charset=utf-8",
 			wantLastMod:     "Wed, 25 Jun 2014 17:12:18 GMT",
 		},
+		"unix_zero_modtime": {
+			content:         strings.NewReader("<html>foo"),
+			modtime:         time.Unix(0, 0),
+			wantStatus:      StatusOK,
+			wantContentType: "text/html; charset=utf-8",
+		},
 	}
 	for testName, tt := range tests {
 		var content io.ReadSeeker
@@ -789,6 +807,31 @@
 	}
 }
 
+func TestServeContentErrorMessages(t *testing.T) {
+	defer afterTest(t)
+	fs := fakeFS{
+		"/500": &fakeFileInfo{
+			err: errors.New("random error"),
+		},
+		"/403": &fakeFileInfo{
+			err: &os.PathError{Err: os.ErrPermission},
+		},
+	}
+	ts := httptest.NewServer(FileServer(fs))
+	defer ts.Close()
+	for _, code := range []int{403, 404, 500} {
+		res, err := DefaultClient.Get(fmt.Sprintf("%s/%d", ts.URL, code))
+		if err != nil {
+			t.Errorf("Error fetching /%d: %v", code, err)
+			continue
+		}
+		if res.StatusCode != code {
+			t.Errorf("For /%d, status code = %d; want %d", code, res.StatusCode, code)
+		}
+		res.Body.Close()
+	}
+}
+
 // verifies that sendfile is being used on Linux
 func TestLinuxSendfile(t *testing.T) {
 	defer afterTest(t)
diff --git a/third_party/gofrontend/libgo/go/net/http/header.go b/third_party/gofrontend/libgo/go/net/http/header.go
index 153b943..d847b13 100644
--- a/third_party/gofrontend/libgo/go/net/http/header.go
+++ b/third_party/gofrontend/libgo/go/net/http/header.go
@@ -168,6 +168,8 @@
 // letter and any letter following a hyphen to upper case;
 // the rest are converted to lowercase.  For example, the
 // canonical key for "accept-encoding" is "Accept-Encoding".
+// If s contains a space or invalid header field bytes, it is
+// returned without modifications.
 func CanonicalHeaderKey(s string) string { return textproto.CanonicalMIMEHeaderKey(s) }
 
 // hasToken reports whether token appears with v, ASCII
diff --git a/third_party/gofrontend/libgo/go/net/http/http_test.go b/third_party/gofrontend/libgo/go/net/http/http_test.go
new file mode 100644
index 0000000..dead3b0
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/net/http/http_test.go
@@ -0,0 +1,58 @@
+// 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.
+
+// Tests of internal functions with no better homes.
+
+package http
+
+import (
+	"reflect"
+	"testing"
+)
+
+func TestForeachHeaderElement(t *testing.T) {
+	tests := []struct {
+		in   string
+		want []string
+	}{
+		{"Foo", []string{"Foo"}},
+		{" Foo", []string{"Foo"}},
+		{"Foo ", []string{"Foo"}},
+		{" Foo ", []string{"Foo"}},
+
+		{"foo", []string{"foo"}},
+		{"anY-cAsE", []string{"anY-cAsE"}},
+
+		{"", nil},
+		{",,,,  ,  ,,   ,,, ,", nil},
+
+		{" Foo,Bar, Baz,lower,,Quux ", []string{"Foo", "Bar", "Baz", "lower", "Quux"}},
+	}
+	for _, tt := range tests {
+		var got []string
+		foreachHeaderElement(tt.in, func(v string) {
+			got = append(got, v)
+		})
+		if !reflect.DeepEqual(got, tt.want) {
+			t.Errorf("foreachHeaderElement(%q) = %q; want %q", tt.in, got, tt.want)
+		}
+	}
+}
+
+func TestCleanHost(t *testing.T) {
+	tests := []struct {
+		in, want string
+	}{
+		{"www.google.com", "www.google.com"},
+		{"www.google.com foo", "www.google.com"},
+		{"www.google.com/foo", "www.google.com"},
+		{" first character is a space", ""},
+	}
+	for _, tt := range tests {
+		got := cleanHost(tt.in)
+		if tt.want != got {
+			t.Errorf("cleanHost(%q) = %q, want %q", tt.in, got, tt.want)
+		}
+	}
+}
diff --git a/third_party/gofrontend/libgo/go/net/http/httptest/server.go b/third_party/gofrontend/libgo/go/net/http/httptest/server.go
index 789e7bf..96eb0ef 100644
--- a/third_party/gofrontend/libgo/go/net/http/httptest/server.go
+++ b/third_party/gofrontend/libgo/go/net/http/httptest/server.go
@@ -204,25 +204,35 @@
 // "127.0.0.1" and "[::1]", expiring at the last second of 2049 (the end
 // of ASN.1 time).
 // generated from src/crypto/tls:
-// go run generate_cert.go  --rsa-bits 512 --host 127.0.0.1,::1,example.com --ca --start-date "Jan 1 00:00:00 1970" --duration=1000000h
+// go run generate_cert.go  --rsa-bits 1024 --host 127.0.0.1,::1,example.com --ca --start-date "Jan 1 00:00:00 1970" --duration=1000000h
 var localhostCert = []byte(`-----BEGIN CERTIFICATE-----
-MIIBdzCCASOgAwIBAgIBADALBgkqhkiG9w0BAQUwEjEQMA4GA1UEChMHQWNtZSBD
-bzAeFw03MDAxMDEwMDAwMDBaFw00OTEyMzEyMzU5NTlaMBIxEDAOBgNVBAoTB0Fj
-bWUgQ28wWjALBgkqhkiG9w0BAQEDSwAwSAJBAN55NcYKZeInyTuhcCwFMhDHCmwa
-IUSdtXdcbItRB/yfXGBhiex00IaLXQnSU+QZPRZWYqeTEbFSgihqi1PUDy8CAwEA
-AaNoMGYwDgYDVR0PAQH/BAQDAgCkMBMGA1UdJQQMMAoGCCsGAQUFBwMBMA8GA1Ud
-EwEB/wQFMAMBAf8wLgYDVR0RBCcwJYILZXhhbXBsZS5jb22HBH8AAAGHEAAAAAAA
-AAAAAAAAAAAAAAEwCwYJKoZIhvcNAQEFA0EAAoQn/ytgqpiLcZu9XKbCJsJcvkgk
-Se6AbGXgSlq+ZCEVo0qIwSgeBqmsJxUu7NCSOwVJLYNEBO2DtIxoYVk+MA==
+MIICEzCCAXygAwIBAgIQMIMChMLGrR+QvmQvpwAU6zANBgkqhkiG9w0BAQsFADAS
+MRAwDgYDVQQKEwdBY21lIENvMCAXDTcwMDEwMTAwMDAwMFoYDzIwODQwMTI5MTYw
+MDAwWjASMRAwDgYDVQQKEwdBY21lIENvMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCB
+iQKBgQDuLnQAI3mDgey3VBzWnB2L39JUU4txjeVE6myuDqkM/uGlfjb9SjY1bIw4
+iA5sBBZzHi3z0h1YV8QPuxEbi4nW91IJm2gsvvZhIrCHS3l6afab4pZBl2+XsDul
+rKBxKKtD1rGxlG4LjncdabFn9gvLZad2bSysqz/qTAUStTvqJQIDAQABo2gwZjAO
+BgNVHQ8BAf8EBAMCAqQwEwYDVR0lBAwwCgYIKwYBBQUHAwEwDwYDVR0TAQH/BAUw
+AwEB/zAuBgNVHREEJzAlggtleGFtcGxlLmNvbYcEfwAAAYcQAAAAAAAAAAAAAAAA
+AAAAATANBgkqhkiG9w0BAQsFAAOBgQCEcetwO59EWk7WiJsG4x8SY+UIAA+flUI9
+tyC4lNhbcF2Idq9greZwbYCqTTTr2XiRNSMLCOjKyI7ukPoPjo16ocHj+P3vZGfs
+h1fIw3cSS2OolhloGw/XM6RWPWtPAlGykKLciQrBru5NAPvCMsb/I1DAceTiotQM
+fblo6RBxUQ==
 -----END CERTIFICATE-----`)
 
 // localhostKey is the private key for localhostCert.
 var localhostKey = []byte(`-----BEGIN RSA PRIVATE KEY-----
-MIIBPAIBAAJBAN55NcYKZeInyTuhcCwFMhDHCmwaIUSdtXdcbItRB/yfXGBhiex0
-0IaLXQnSU+QZPRZWYqeTEbFSgihqi1PUDy8CAwEAAQJBAQdUx66rfh8sYsgfdcvV
-NoafYpnEcB5s4m/vSVe6SU7dCK6eYec9f9wpT353ljhDUHq3EbmE4foNzJngh35d
-AekCIQDhRQG5Li0Wj8TM4obOnnXUXf1jRv0UkzE9AHWLG5q3AwIhAPzSjpYUDjVW
-MCUXgckTpKCuGwbJk7424Nb8bLzf3kllAiA5mUBgjfr/WtFSJdWcPQ4Zt9KTMNKD
-EUO0ukpTwEIl6wIhAMbGqZK3zAAFdq8DD2jPx+UJXnh0rnOkZBzDtJ6/iN69AiEA
-1Aq8MJgTaYsDQWyU/hDq5YkDJc9e9DSCvUIzqxQWMQE=
+MIICXgIBAAKBgQDuLnQAI3mDgey3VBzWnB2L39JUU4txjeVE6myuDqkM/uGlfjb9
+SjY1bIw4iA5sBBZzHi3z0h1YV8QPuxEbi4nW91IJm2gsvvZhIrCHS3l6afab4pZB
+l2+XsDulrKBxKKtD1rGxlG4LjncdabFn9gvLZad2bSysqz/qTAUStTvqJQIDAQAB
+AoGAGRzwwir7XvBOAy5tM/uV6e+Zf6anZzus1s1Y1ClbjbE6HXbnWWF/wbZGOpet
+3Zm4vD6MXc7jpTLryzTQIvVdfQbRc6+MUVeLKwZatTXtdZrhu+Jk7hx0nTPy8Jcb
+uJqFk541aEw+mMogY/xEcfbWd6IOkp+4xqjlFLBEDytgbIECQQDvH/E6nk+hgN4H
+qzzVtxxr397vWrjrIgPbJpQvBsafG7b0dA4AFjwVbFLmQcj2PprIMmPcQrooz8vp
+jy4SHEg1AkEA/v13/5M47K9vCxmb8QeD/asydfsgS5TeuNi8DoUBEmiSJwma7FXY
+fFUtxuvL7XvjwjN5B30pNEbc6Iuyt7y4MQJBAIt21su4b3sjXNueLKH85Q+phy2U
+fQtuUE9txblTu14q3N7gHRZB4ZMhFYyDy8CKrN2cPg/Fvyt0Xlp/DoCzjA0CQQDU
+y2ptGsuSmgUtWj3NM9xuwYPm+Z/F84K6+ARYiZ6PYj013sovGKUFfYAqVXVlxtIX
+qyUBnu3X9ps8ZfjLZO7BAkEAlT4R5Yl6cGhaJQYZHOde3JEMhNRcVFMO8dJDaFeo
+f9Oeos0UUothgiDktdQHxdNEwLjQf7lJJBzV+5OtwswCWA==
 -----END RSA PRIVATE KEY-----`)
diff --git a/third_party/gofrontend/libgo/go/net/http/httputil/dump.go b/third_party/gofrontend/libgo/go/net/http/httputil/dump.go
index ac8f103..ca2d1cd 100644
--- a/third_party/gofrontend/libgo/go/net/http/httputil/dump.go
+++ b/third_party/gofrontend/libgo/go/net/http/httputil/dump.go
@@ -98,6 +98,14 @@
 	defer pr.Close()
 	defer pw.Close()
 	dr := &delegateReader{c: make(chan io.Reader)}
+
+	t := &http.Transport{
+		Dial: func(net, addr string) (net.Conn, error) {
+			return &dumpConn{io.MultiWriter(&buf, pw), dr}, nil
+		},
+	}
+	defer t.CloseIdleConnections()
+
 	// Wait for the request before replying with a dummy response:
 	go func() {
 		req, err := http.ReadRequest(bufio.NewReader(pr))
@@ -107,16 +115,9 @@
 			io.Copy(ioutil.Discard, req.Body)
 			req.Body.Close()
 		}
-		dr.c <- strings.NewReader("HTTP/1.1 204 No Content\r\n\r\n")
+		dr.c <- strings.NewReader("HTTP/1.1 204 No Content\r\nConnection: close\r\n\r\n")
 	}()
 
-	t := &http.Transport{
-		DisableKeepAlives: true,
-		Dial: func(net, addr string) (net.Conn, error) {
-			return &dumpConn{io.MultiWriter(&buf, pw), dr}, nil
-		},
-	}
-
 	_, err := t.RoundTrip(reqSend)
 
 	req.Body = save
diff --git a/third_party/gofrontend/libgo/go/net/http/httputil/dump_test.go b/third_party/gofrontend/libgo/go/net/http/httputil/dump_test.go
index 024ee5a..ae67e98 100644
--- a/third_party/gofrontend/libgo/go/net/http/httputil/dump_test.go
+++ b/third_party/gofrontend/libgo/go/net/http/httputil/dump_test.go
@@ -71,7 +71,7 @@
 
 		WantDumpOut: "GET /foo HTTP/1.1\r\n" +
 			"Host: example.com\r\n" +
-			"User-Agent: Go 1.1 package http\r\n" +
+			"User-Agent: Go-http-client/1.1\r\n" +
 			"Accept-Encoding: gzip\r\n\r\n",
 	},
 
@@ -83,7 +83,7 @@
 
 		WantDumpOut: "GET /foo HTTP/1.1\r\n" +
 			"Host: example.com\r\n" +
-			"User-Agent: Go 1.1 package http\r\n" +
+			"User-Agent: Go-http-client/1.1\r\n" +
 			"Accept-Encoding: gzip\r\n\r\n",
 	},
 
@@ -105,7 +105,7 @@
 
 		WantDumpOut: "POST / HTTP/1.1\r\n" +
 			"Host: post.tld\r\n" +
-			"User-Agent: Go 1.1 package http\r\n" +
+			"User-Agent: Go-http-client/1.1\r\n" +
 			"Content-Length: 6\r\n" +
 			"Accept-Encoding: gzip\r\n\r\n",
 
@@ -130,7 +130,7 @@
 
 		WantDumpOut: "POST / HTTP/1.1\r\n" +
 			"Host: post.tld\r\n" +
-			"User-Agent: Go 1.1 package http\r\n" +
+			"User-Agent: Go-http-client/1.1\r\n" +
 			"Content-Length: 8193\r\n" +
 			"Accept-Encoding: gzip\r\n\r\n" +
 			strings.Repeat("a", 8193),
diff --git a/third_party/gofrontend/libgo/go/net/http/httputil/reverseproxy.go b/third_party/gofrontend/libgo/go/net/http/httputil/reverseproxy.go
index ab46370..c8e1132 100644
--- a/third_party/gofrontend/libgo/go/net/http/httputil/reverseproxy.go
+++ b/third_party/gofrontend/libgo/go/net/http/httputil/reverseproxy.go
@@ -100,6 +100,27 @@
 	"Upgrade",
 }
 
+type requestCanceler interface {
+	CancelRequest(*http.Request)
+}
+
+type runOnFirstRead struct {
+	io.Reader // optional; nil means empty body
+
+	fn func() // Run before first Read, then set to nil
+}
+
+func (c *runOnFirstRead) Read(bs []byte) (int, error) {
+	if c.fn != nil {
+		c.fn()
+		c.fn = nil
+	}
+	if c.Reader == nil {
+		return 0, io.EOF
+	}
+	return c.Reader.Read(bs)
+}
+
 func (p *ReverseProxy) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
 	transport := p.Transport
 	if transport == nil {
@@ -109,6 +130,34 @@
 	outreq := new(http.Request)
 	*outreq = *req // includes shallow copies of maps, but okay
 
+	if closeNotifier, ok := rw.(http.CloseNotifier); ok {
+		if requestCanceler, ok := transport.(requestCanceler); ok {
+			reqDone := make(chan struct{})
+			defer close(reqDone)
+
+			clientGone := closeNotifier.CloseNotify()
+
+			outreq.Body = struct {
+				io.Reader
+				io.Closer
+			}{
+				Reader: &runOnFirstRead{
+					Reader: outreq.Body,
+					fn: func() {
+						go func() {
+							select {
+							case <-clientGone:
+								requestCanceler.CancelRequest(outreq)
+							case <-reqDone:
+							}
+						}()
+					},
+				},
+				Closer: outreq.Body,
+			}
+		}
+	}
+
 	p.Director(outreq)
 	outreq.Proto = "HTTP/1.1"
 	outreq.ProtoMajor = 1
@@ -148,7 +197,6 @@
 		rw.WriteHeader(http.StatusInternalServerError)
 		return
 	}
-	defer res.Body.Close()
 
 	for _, h := range hopHeaders {
 		res.Header.Del(h)
@@ -156,8 +204,28 @@
 
 	copyHeader(rw.Header(), res.Header)
 
+	// The "Trailer" header isn't included in the Transport's response,
+	// at least for *http.Transport. Build it up from Trailer.
+	if len(res.Trailer) > 0 {
+		var trailerKeys []string
+		for k := range res.Trailer {
+			trailerKeys = append(trailerKeys, k)
+		}
+		rw.Header().Add("Trailer", strings.Join(trailerKeys, ", "))
+	}
+
 	rw.WriteHeader(res.StatusCode)
+	if len(res.Trailer) > 0 {
+		// Force chunking if we saw a response trailer.
+		// This prevents net/http from calculating the length for short
+		// bodies and adding a Content-Length.
+		if fl, ok := rw.(http.Flusher); ok {
+			fl.Flush()
+		}
+	}
 	p.copyResponse(rw, res.Body)
+	res.Body.Close() // close now, instead of defer, to populate res.Trailer
+	copyHeader(rw.Header(), res.Trailer)
 }
 
 func (p *ReverseProxy) copyResponse(dst io.Writer, src io.Reader) {
diff --git a/third_party/gofrontend/libgo/go/net/http/httputil/reverseproxy_test.go b/third_party/gofrontend/libgo/go/net/http/httputil/reverseproxy_test.go
index e9539b4..80a26ab 100644
--- a/third_party/gofrontend/libgo/go/net/http/httputil/reverseproxy_test.go
+++ b/third_party/gofrontend/libgo/go/net/http/httputil/reverseproxy_test.go
@@ -7,10 +7,14 @@
 package httputil
 
 import (
+	"bufio"
 	"io/ioutil"
+	"log"
 	"net/http"
 	"net/http/httptest"
 	"net/url"
+	"reflect"
+	"runtime"
 	"strings"
 	"testing"
 	"time"
@@ -41,6 +45,7 @@
 		if g, e := r.Host, "some-name"; g != e {
 			t.Errorf("backend got Host header %q, want %q", g, e)
 		}
+		w.Header().Set("Trailer", "X-Trailer")
 		w.Header().Set("X-Foo", "bar")
 		w.Header().Set("Upgrade", "foo")
 		w.Header().Set(fakeHopHeader, "foo")
@@ -49,6 +54,7 @@
 		http.SetCookie(w, &http.Cookie{Name: "flavor", Value: "chocolateChip"})
 		w.WriteHeader(backendStatus)
 		w.Write([]byte(backendResponse))
+		w.Header().Set("X-Trailer", "trailer_value")
 	}))
 	defer backend.Close()
 	backendURL, err := url.Parse(backend.URL)
@@ -83,6 +89,9 @@
 	if g, e := len(res.Header["Set-Cookie"]), 1; g != e {
 		t.Fatalf("got %d SetCookies, want %d", g, e)
 	}
+	if g, e := res.Trailer, (http.Header{"X-Trailer": nil}); !reflect.DeepEqual(g, e) {
+		t.Errorf("before reading body, Trailer = %#v; want %#v", g, e)
+	}
 	if cookie := res.Cookies()[0]; cookie.Name != "flavor" {
 		t.Errorf("unexpected cookie %q", cookie.Name)
 	}
@@ -90,6 +99,10 @@
 	if g, e := string(bodyBytes), backendResponse; g != e {
 		t.Errorf("got body %q; expected %q", g, e)
 	}
+	if g, e := res.Trailer.Get("X-Trailer"), "trailer_value"; g != e {
+		t.Errorf("Trailer(X-Trailer) = %q ; want %q", g, e)
+	}
+
 }
 
 func TestXForwardedFor(t *testing.T) {
@@ -211,3 +224,99 @@
 		t.Error("maxLatencyWriter flushLoop() never exited")
 	}
 }
+
+func TestReverseProxyCancellation(t *testing.T) {
+	if runtime.GOOS == "plan9" {
+		t.Skip("skipping test; see https://golang.org/issue/9554")
+	}
+	const backendResponse = "I am the backend"
+
+	reqInFlight := make(chan struct{})
+	backend := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
+		close(reqInFlight)
+
+		select {
+		case <-time.After(10 * time.Second):
+			// Note: this should only happen in broken implementations, and the
+			// closenotify case should be instantaneous.
+			t.Log("Failed to close backend connection")
+			t.Fail()
+		case <-w.(http.CloseNotifier).CloseNotify():
+		}
+
+		w.WriteHeader(http.StatusOK)
+		w.Write([]byte(backendResponse))
+	}))
+
+	defer backend.Close()
+
+	backend.Config.ErrorLog = log.New(ioutil.Discard, "", 0)
+
+	backendURL, err := url.Parse(backend.URL)
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	proxyHandler := NewSingleHostReverseProxy(backendURL)
+
+	// Discards errors of the form:
+	// http: proxy error: read tcp 127.0.0.1:44643: use of closed network connection
+	proxyHandler.ErrorLog = log.New(ioutil.Discard, "", 0)
+
+	frontend := httptest.NewServer(proxyHandler)
+	defer frontend.Close()
+
+	getReq, _ := http.NewRequest("GET", frontend.URL, nil)
+	go func() {
+		<-reqInFlight
+		http.DefaultTransport.(*http.Transport).CancelRequest(getReq)
+	}()
+	res, err := http.DefaultClient.Do(getReq)
+	if res != nil {
+		t.Fatal("Non-nil response")
+	}
+	if err == nil {
+		// This should be an error like:
+		// Get http://127.0.0.1:58079: read tcp 127.0.0.1:58079:
+		//    use of closed network connection
+		t.Fatal("DefaultClient.Do() returned nil error")
+	}
+}
+
+func req(t *testing.T, v string) *http.Request {
+	req, err := http.ReadRequest(bufio.NewReader(strings.NewReader(v)))
+	if err != nil {
+		t.Fatal(err)
+	}
+	return req
+}
+
+// Issue 12344
+func TestNilBody(t *testing.T) {
+	backend := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
+		w.Write([]byte("hi"))
+	}))
+	defer backend.Close()
+
+	frontend := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) {
+		backURL, _ := url.Parse(backend.URL)
+		rp := NewSingleHostReverseProxy(backURL)
+		r := req(t, "GET / HTTP/1.0\r\n\r\n")
+		r.Body = nil // this accidentally worked in Go 1.4 and below, so keep it working
+		rp.ServeHTTP(w, r)
+	}))
+	defer frontend.Close()
+
+	res, err := http.Get(frontend.URL)
+	if err != nil {
+		t.Fatal(err)
+	}
+	defer res.Body.Close()
+	slurp, err := ioutil.ReadAll(res.Body)
+	if err != nil {
+		t.Fatal(err)
+	}
+	if string(slurp) != "hi" {
+		t.Errorf("Got %q; want %q", slurp, "hi")
+	}
+}
diff --git a/third_party/gofrontend/libgo/go/net/http/internal/chunked.go b/third_party/gofrontend/libgo/go/net/http/internal/chunked.go
index 9294deb..6d7c698 100644
--- a/third_party/gofrontend/libgo/go/net/http/internal/chunked.go
+++ b/third_party/gofrontend/libgo/go/net/http/internal/chunked.go
@@ -173,8 +173,12 @@
 		err = io.ErrShortWrite
 		return
 	}
-	_, err = io.WriteString(cw.Wire, "\r\n")
-
+	if _, err = io.WriteString(cw.Wire, "\r\n"); err != nil {
+		return
+	}
+	if bw, ok := cw.Wire.(*FlushAfterChunkWriter); ok {
+		err = bw.Flush()
+	}
 	return
 }
 
@@ -183,6 +187,15 @@
 	return err
 }
 
+// FlushAfterChunkWriter signals from the caller of NewChunkedWriter
+// that each chunk should be followed by a flush. It is used by the
+// http.Transport code to keep the buffering behavior for headers and
+// trailers, but flush out chunks aggressively in the middle for
+// request bodies which may be generated slowly. See Issue 6574.
+type FlushAfterChunkWriter struct {
+	*bufio.Writer
+}
+
 func parseHexUint(v []byte) (n uint64, err error) {
 	for _, b := range v {
 		n <<= 4
diff --git a/third_party/gofrontend/libgo/go/net/http/lex.go b/third_party/gofrontend/libgo/go/net/http/lex.go
index cb33318..50b14f8 100644
--- a/third_party/gofrontend/libgo/go/net/http/lex.go
+++ b/third_party/gofrontend/libgo/go/net/http/lex.go
@@ -4,6 +4,11 @@
 
 package http
 
+import (
+	"strings"
+	"unicode/utf8"
+)
+
 // This file deals with lexical matters of HTTP
 
 var isTokenTable = [127]bool{
@@ -94,3 +99,71 @@
 func isNotToken(r rune) bool {
 	return !isToken(r)
 }
+
+// headerValuesContainsToken reports whether any string in values
+// contains the provided token, ASCII case-insensitively.
+func headerValuesContainsToken(values []string, token string) bool {
+	for _, v := range values {
+		if headerValueContainsToken(v, token) {
+			return true
+		}
+	}
+	return false
+}
+
+// isOWS reports whether b is an optional whitespace byte, as defined
+// by RFC 7230 section 3.2.3.
+func isOWS(b byte) bool { return b == ' ' || b == '\t' }
+
+// trimOWS returns x with all optional whitespace removes from the
+// beginning and end.
+func trimOWS(x string) string {
+	// TODO: consider using strings.Trim(x, " \t") instead,
+	// if and when it's fast enough. See issue 10292.
+	// But this ASCII-only code will probably always beat UTF-8
+	// aware code.
+	for len(x) > 0 && isOWS(x[0]) {
+		x = x[1:]
+	}
+	for len(x) > 0 && isOWS(x[len(x)-1]) {
+		x = x[:len(x)-1]
+	}
+	return x
+}
+
+// headerValueContainsToken reports whether v (assumed to be a
+// 0#element, in the ABNF extension described in RFC 7230 section 7)
+// contains token amongst its comma-separated tokens, ASCII
+// case-insensitively.
+func headerValueContainsToken(v string, token string) bool {
+	v = trimOWS(v)
+	if comma := strings.IndexByte(v, ','); comma != -1 {
+		return tokenEqual(trimOWS(v[:comma]), token) || headerValueContainsToken(v[comma+1:], token)
+	}
+	return tokenEqual(v, token)
+}
+
+// lowerASCII returns the ASCII lowercase version of b.
+func lowerASCII(b byte) byte {
+	if 'A' <= b && b <= 'Z' {
+		return b + ('a' - 'A')
+	}
+	return b
+}
+
+// tokenEqual reports whether t1 and t2 are equal, ASCII case-insensitively.
+func tokenEqual(t1, t2 string) bool {
+	if len(t1) != len(t2) {
+		return false
+	}
+	for i, b := range t1 {
+		if b >= utf8.RuneSelf {
+			// No UTF-8 or non-ASCII allowed in tokens.
+			return false
+		}
+		if lowerASCII(byte(b)) != lowerASCII(t2[i]) {
+			return false
+		}
+	}
+	return true
+}
diff --git a/third_party/gofrontend/libgo/go/net/http/lex_test.go b/third_party/gofrontend/libgo/go/net/http/lex_test.go
index 6d9d294..986fda1 100644
--- a/third_party/gofrontend/libgo/go/net/http/lex_test.go
+++ b/third_party/gofrontend/libgo/go/net/http/lex_test.go
@@ -29,3 +29,73 @@
 		}
 	}
 }
+
+func TestHeaderValuesContainsToken(t *testing.T) {
+	tests := []struct {
+		vals  []string
+		token string
+		want  bool
+	}{
+		{
+			vals:  []string{"foo"},
+			token: "foo",
+			want:  true,
+		},
+		{
+			vals:  []string{"bar", "foo"},
+			token: "foo",
+			want:  true,
+		},
+		{
+			vals:  []string{"foo"},
+			token: "FOO",
+			want:  true,
+		},
+		{
+			vals:  []string{"foo"},
+			token: "bar",
+			want:  false,
+		},
+		{
+			vals:  []string{" foo "},
+			token: "FOO",
+			want:  true,
+		},
+		{
+			vals:  []string{"foo,bar"},
+			token: "FOO",
+			want:  true,
+		},
+		{
+			vals:  []string{"bar,foo,bar"},
+			token: "FOO",
+			want:  true,
+		},
+		{
+			vals:  []string{"bar , foo"},
+			token: "FOO",
+			want:  true,
+		},
+		{
+			vals:  []string{"foo ,bar "},
+			token: "FOO",
+			want:  true,
+		},
+		{
+			vals:  []string{"bar, foo ,bar"},
+			token: "FOO",
+			want:  true,
+		},
+		{
+			vals:  []string{"bar , foo"},
+			token: "FOO",
+			want:  true,
+		},
+	}
+	for _, tt := range tests {
+		got := headerValuesContainsToken(tt.vals, tt.token)
+		if got != tt.want {
+			t.Errorf("headerValuesContainsToken(%q, %q) = %v; want %v", tt.vals, tt.token, got, tt.want)
+		}
+	}
+}
diff --git a/third_party/gofrontend/libgo/go/net/http/main_test.go b/third_party/gofrontend/libgo/go/net/http/main_test.go
index b8c71fd..12eea6f 100644
--- a/third_party/gofrontend/libgo/go/net/http/main_test.go
+++ b/third_party/gofrontend/libgo/go/net/http/main_test.go
@@ -56,17 +56,21 @@
 		// not counting goroutines for leakage in -short mode
 		return false
 	}
-	gs := interestingGoroutines()
 
-	n := 0
-	stackCount := make(map[string]int)
-	for _, g := range gs {
-		stackCount[g]++
-		n++
-	}
-
-	if n == 0 {
-		return false
+	var stackCount map[string]int
+	for i := 0; i < 5; i++ {
+		n := 0
+		stackCount = make(map[string]int)
+		gs := interestingGoroutines()
+		for _, g := range gs {
+			stackCount[g]++
+			n++
+		}
+		if n == 0 {
+			return false
+		}
+		// Wait for goroutines to schedule and die off:
+		time.Sleep(100 * time.Millisecond)
 	}
 	fmt.Fprintf(os.Stderr, "Too many goroutines running after net/http test(s).\n")
 	for stack, count := range stackCount {
@@ -75,7 +79,7 @@
 	return true
 }
 
-func afterTest(t *testing.T) {
+func afterTest(t testing.TB) {
 	http.DefaultTransport.(*http.Transport).CloseIdleConnections()
 	if testing.Short() {
 		return
diff --git a/third_party/gofrontend/libgo/go/net/http/npn_test.go b/third_party/gofrontend/libgo/go/net/http/npn_test.go
index 98b8930..e2e911d 100644
--- a/third_party/gofrontend/libgo/go/net/http/npn_test.go
+++ b/third_party/gofrontend/libgo/go/net/http/npn_test.go
@@ -6,6 +6,7 @@
 
 import (
 	"bufio"
+	"bytes"
 	"crypto/tls"
 	"fmt"
 	"io"
@@ -17,6 +18,7 @@
 )
 
 func TestNextProtoUpgrade(t *testing.T) {
+	defer afterTest(t)
 	ts := httptest.NewUnstartedServer(HandlerFunc(func(w ResponseWriter, r *Request) {
 		fmt.Fprintf(w, "path=%s,proto=", r.URL.Path)
 		if r.TLS != nil {
@@ -38,12 +40,12 @@
 	ts.StartTLS()
 	defer ts.Close()
 
-	tr := newTLSTransport(t, ts)
-	defer tr.CloseIdleConnections()
-	c := &Client{Transport: tr}
-
 	// Normal request, without NPN.
 	{
+		tr := newTLSTransport(t, ts)
+		defer tr.CloseIdleConnections()
+		c := &Client{Transport: tr}
+
 		res, err := c.Get(ts.URL)
 		if err != nil {
 			t.Fatal(err)
@@ -60,11 +62,17 @@
 	// Request to an advertised but unhandled NPN protocol.
 	// Server will hang up.
 	{
-		tr.CloseIdleConnections()
+		tr := newTLSTransport(t, ts)
 		tr.TLSClientConfig.NextProtos = []string{"unhandled-proto"}
-		_, err := c.Get(ts.URL)
+		defer tr.CloseIdleConnections()
+		c := &Client{Transport: tr}
+
+		res, err := c.Get(ts.URL)
 		if err == nil {
-			t.Errorf("expected error on unhandled-proto request")
+			defer res.Body.Close()
+			var buf bytes.Buffer
+			res.Write(&buf)
+			t.Errorf("expected error on unhandled-proto request; got: %s", buf.Bytes())
 		}
 	}
 
diff --git a/third_party/gofrontend/libgo/go/net/http/pprof/pprof.go b/third_party/gofrontend/libgo/go/net/http/pprof/pprof.go
index a23f1bc..8994392 100644
--- a/third_party/gofrontend/libgo/go/net/http/pprof/pprof.go
+++ b/third_party/gofrontend/libgo/go/net/http/pprof/pprof.go
@@ -34,12 +34,16 @@
 //
 //	go tool pprof http://localhost:6060/debug/pprof/block
 //
+// Or to collect a 5-second execution trace:
+//
+//	wget http://localhost:6060/debug/pprof/trace?seconds=5
+//
 // To view all available profiles, open http://localhost:6060/debug/pprof/
 // in your browser.
 //
 // For a study of the facility in action, visit
 //
-//	http://blog.golang.org/2011/06/profiling-go-programs.html
+//	https://blog.golang.org/2011/06/profiling-go-programs.html
 //
 package pprof
 
@@ -64,6 +68,7 @@
 	http.Handle("/debug/pprof/cmdline", http.HandlerFunc(Cmdline))
 	http.Handle("/debug/pprof/profile", http.HandlerFunc(Profile))
 	http.Handle("/debug/pprof/symbol", http.HandlerFunc(Symbol))
+	http.Handle("/debug/pprof/trace", http.HandlerFunc(Trace))
 }
 
 // Cmdline responds with the running program's
@@ -98,6 +103,33 @@
 	pprof.StopCPUProfile()
 }
 
+// Trace responds with the execution trace in binary form.
+// Tracing lasts for duration specified in seconds GET parameter, or for 1 second if not specified.
+// The package initialization registers it as /debug/pprof/trace.
+func Trace(w http.ResponseWriter, r *http.Request) {
+	sec, _ := strconv.ParseInt(r.FormValue("seconds"), 10, 64)
+	if sec == 0 {
+		sec = 1
+	}
+
+	// Set Content Type assuming trace.Start will work,
+	// because if it does it starts writing.
+	w.Header().Set("Content-Type", "application/octet-stream")
+	w.Write([]byte("tracing not yet supported with gccgo"))
+	/*
+		if err := trace.Start(w); err != nil {
+			// trace.Start failed, so no writes yet.
+			// Can change header back to text content and send error code.
+			w.Header().Set("Content-Type", "text/plain; charset=utf-8")
+			w.WriteHeader(http.StatusInternalServerError)
+			fmt.Fprintf(w, "Could not enable tracing: %s\n", err)
+			return
+		}
+		time.Sleep(time.Duration(sec) * time.Second)
+		trace.Stop()
+	*/
+}
+
 // Symbol looks up the program counters listed in the request,
 // responding with a table mapping program counters to function names.
 // The package initialization registers it as /debug/pprof/symbol.
@@ -193,17 +225,17 @@
 <head>
 <title>/debug/pprof/</title>
 </head>
+<body>
 /debug/pprof/<br>
 <br>
-<body>
 profiles:<br>
 <table>
 {{range .}}
-<tr><td align=right>{{.Count}}<td><a href="/debug/pprof/{{.Name}}?debug=1">{{.Name}}</a>
+<tr><td align=right>{{.Count}}<td><a href="{{.Name}}?debug=1">{{.Name}}</a>
 {{end}}
 </table>
 <br>
-<a href="/debug/pprof/goroutine?debug=2">full goroutine stack dump</a><br>
+<a href="goroutine?debug=2">full goroutine stack dump</a><br>
 </body>
 </html>
 `))
diff --git a/third_party/gofrontend/libgo/go/net/http/proxy_test.go b/third_party/gofrontend/libgo/go/net/http/proxy_test.go
index b6aed37..823d144 100644
--- a/third_party/gofrontend/libgo/go/net/http/proxy_test.go
+++ b/third_party/gofrontend/libgo/go/net/http/proxy_test.go
@@ -18,7 +18,7 @@
 	match bool
 }{
 	// Never proxy localhost:
-	{"localhost:80", false},
+	{"localhost", false},
 	{"127.0.0.1", false},
 	{"127.0.0.2", false},
 	{"[::1]", false},
diff --git a/third_party/gofrontend/libgo/go/net/http/readrequest_test.go b/third_party/gofrontend/libgo/go/net/http/readrequest_test.go
index e930d99..60e2be4 100644
--- a/third_party/gofrontend/libgo/go/net/http/readrequest_test.go
+++ b/third_party/gofrontend/libgo/go/net/http/readrequest_test.go
@@ -9,6 +9,7 @@
 	"bytes"
 	"fmt"
 	"io"
+	"io/ioutil"
 	"net/url"
 	"reflect"
 	"strings"
@@ -177,6 +178,36 @@
 		noError,
 	},
 
+	// Tests chunked body and a bogus Content-Length which should be deleted.
+	{
+		"POST / HTTP/1.1\r\n" +
+			"Host: foo.com\r\n" +
+			"Transfer-Encoding: chunked\r\n" +
+			"Content-Length: 9999\r\n\r\n" + // to be removed.
+			"3\r\nfoo\r\n" +
+			"3\r\nbar\r\n" +
+			"0\r\n" +
+			"\r\n",
+		&Request{
+			Method: "POST",
+			URL: &url.URL{
+				Path: "/",
+			},
+			TransferEncoding: []string{"chunked"},
+			Proto:            "HTTP/1.1",
+			ProtoMajor:       1,
+			ProtoMinor:       1,
+			Header:           Header{},
+			ContentLength:    -1,
+			Host:             "foo.com",
+			RequestURI:       "/",
+		},
+
+		"foobar",
+		noTrailer,
+		noError,
+	},
+
 	// CONNECT request with domain name:
 	{
 		"CONNECT www.google.com:443 HTTP/1.1\r\n\r\n",
@@ -323,6 +354,32 @@
 		noTrailer,
 		noError,
 	},
+
+	// HEAD with Content-Length 0. Make sure this is permitted,
+	// since I think we used to send it.
+	{
+		"HEAD / HTTP/1.1\r\nHost: issue8261.com\r\nConnection: close\r\nContent-Length: 0\r\n\r\n",
+		&Request{
+			Method: "HEAD",
+			URL: &url.URL{
+				Path: "/",
+			},
+			Header: Header{
+				"Connection":     []string{"close"},
+				"Content-Length": []string{"0"},
+			},
+			Host:       "issue8261.com",
+			Proto:      "HTTP/1.1",
+			ProtoMajor: 1,
+			ProtoMinor: 1,
+			Close:      true,
+			RequestURI: "/",
+		},
+
+		noBody,
+		noTrailer,
+		noError,
+	},
 }
 
 func TestReadRequest(t *testing.T) {
@@ -356,3 +413,34 @@
 		}
 	}
 }
+
+// reqBytes treats req as a request (with \n delimiters) and returns it with \r\n delimiters,
+// ending in \r\n\r\n
+func reqBytes(req string) []byte {
+	return []byte(strings.Replace(strings.TrimSpace(req), "\n", "\r\n", -1) + "\r\n\r\n")
+}
+
+var badRequestTests = []struct {
+	name string
+	req  []byte
+}{
+	{"bad_connect_host", reqBytes("CONNECT []%20%48%54%54%50%2f%31%2e%31%0a%4d%79%48%65%61%64%65%72%3a%20%31%32%33%0a%0a HTTP/1.0")},
+	{"smuggle_two_contentlen", reqBytes(`POST / HTTP/1.1
+Content-Length: 3
+Content-Length: 4
+
+abc`)},
+	{"smuggle_content_len_head", reqBytes(`HEAD / HTTP/1.1
+Host: foo
+Content-Length: 5`)},
+}
+
+func TestReadRequest_Bad(t *testing.T) {
+	for _, tt := range badRequestTests {
+		got, err := ReadRequest(bufio.NewReader(bytes.NewReader(tt.req)))
+		if err == nil {
+			all, err := ioutil.ReadAll(got.Body)
+			t.Errorf("%s: got unexpected request = %#v\n  Body = %q, %v", tt.name, got, all, err)
+		}
+	}
+}
diff --git a/third_party/gofrontend/libgo/go/net/http/request.go b/third_party/gofrontend/libgo/go/net/http/request.go
index 487eebc..31fe45a 100644
--- a/third_party/gofrontend/libgo/go/net/http/request.go
+++ b/third_party/gofrontend/libgo/go/net/http/request.go
@@ -25,9 +25,6 @@
 )
 
 const (
-	maxValueLength   = 4096
-	maxHeaderLines   = 1024
-	chunkSize        = 4 << 10  // 4 KB chunks
 	defaultMaxMemory = 32 << 20 // 32 MB
 )
 
@@ -172,8 +169,9 @@
 	// The HTTP client ignores Form and uses Body instead.
 	Form url.Values
 
-	// PostForm contains the parsed form data from POST or PUT
-	// body parameters.
+	// PostForm contains the parsed form data from POST, PATCH,
+	// or PUT body parameters.
+	//
 	// This field is only available after ParseForm is called.
 	// The HTTP client ignores PostForm and uses Body instead.
 	PostForm url.Values
@@ -226,6 +224,13 @@
 	// otherwise it leaves the field nil.
 	// This field is ignored by the HTTP client.
 	TLS *tls.ConnectionState
+
+	// Cancel is an optional channel whose closure indicates that the client
+	// request should be regarded as canceled. Not all implementations of
+	// RoundTripper may support Cancel.
+	//
+	// For server requests, this field is not applicable.
+	Cancel <-chan struct{}
 }
 
 // ProtoAtLeast reports whether the HTTP protocol used
@@ -245,6 +250,7 @@
 	return readCookies(r.Header, "")
 }
 
+// ErrNoCookie is returned by Request's Cookie method when a cookie is not found.
 var ErrNoCookie = errors.New("http: named cookie not present")
 
 // Cookie returns the named cookie provided in the request or
@@ -329,13 +335,12 @@
 }
 
 // NOTE: This is not intended to reflect the actual Go version being used.
-// It was changed from "Go http package" to "Go 1.1 package http" at the
-// time of the Go 1.1 release because the former User-Agent had ended up
-// on a blacklist for some intrusion detection systems.
+// It was changed at the time of Go 1.1 release because the former User-Agent
+// had ended up on a blacklist for some intrusion detection systems.
 // See https://codereview.appspot.com/7532043.
-const defaultUserAgent = "Go 1.1 package http"
+const defaultUserAgent = "Go-http-client/1.1"
 
-// Write writes an HTTP/1.1 request -- header and body -- in wire format.
+// Write writes an HTTP/1.1 request, which is the header and body, in wire format.
 // This method consults the following fields of the request:
 //	Host
 //	URL
@@ -364,14 +369,23 @@
 
 // extraHeaders may be nil
 func (req *Request) write(w io.Writer, usingProxy bool, extraHeaders Header) error {
-	host := req.Host
+	// Find the target host. Prefer the Host: header, but if that
+	// is not given, use the host from the request URL.
+	//
+	// Clean the host, in case it arrives with unexpected stuff in it.
+	host := cleanHost(req.Host)
 	if host == "" {
 		if req.URL == nil {
 			return errors.New("http: Request.Write on Request with no Host or URL set")
 		}
-		host = req.URL.Host
+		host = cleanHost(req.URL.Host)
 	}
 
+	// According to RFC 6874, an HTTP client, proxy, or other
+	// intermediary must remove any IPv6 zone identifier attached
+	// to an outgoing URI.
+	host = removeZone(host)
+
 	ruri := req.URL.RequestURI()
 	if usingProxy && req.URL.Scheme != "" && req.URL.Opaque == "" {
 		ruri = req.URL.Scheme + "://" + host + ruri
@@ -456,6 +470,39 @@
 	return nil
 }
 
+// cleanHost strips anything after '/' or ' '.
+// Ideally we'd clean the Host header according to the spec:
+//   https://tools.ietf.org/html/rfc7230#section-5.4 (Host = uri-host [ ":" port ]")
+//   https://tools.ietf.org/html/rfc7230#section-2.7 (uri-host -> rfc3986's host)
+//   https://tools.ietf.org/html/rfc3986#section-3.2.2 (definition of host)
+// But practically, what we are trying to avoid is the situation in
+// issue 11206, where a malformed Host header used in the proxy context
+// would create a bad request. So it is enough to just truncate at the
+// first offending character.
+func cleanHost(in string) string {
+	if i := strings.IndexAny(in, " /"); i != -1 {
+		return in[:i]
+	}
+	return in
+}
+
+// removeZone removes IPv6 zone identifer from host.
+// E.g., "[fe80::1%en0]:8080" to "[fe80::1]:8080"
+func removeZone(host string) string {
+	if !strings.HasPrefix(host, "[") {
+		return host
+	}
+	i := strings.LastIndex(host, "]")
+	if i < 0 {
+		return host
+	}
+	j := strings.LastIndex(host[:i], "%")
+	if j < 0 {
+		return host
+	}
+	return host[:j] + host[i:]
+}
+
 // ParseHTTPVersion parses a HTTP version string.
 // "HTTP/1.0" returns (1, 0, true).
 func ParseHTTPVersion(vers string) (major, minor int, ok bool) {
@@ -489,6 +536,13 @@
 // If the provided body is also an io.Closer, the returned
 // Request.Body is set to body and will be closed by the Client
 // methods Do, Post, and PostForm, and Transport.RoundTrip.
+//
+// NewRequest returns a Request suitable for use with Client.Do or
+// Transport.RoundTrip.
+// To create a request for use with testing a Server Handler use either
+// ReadRequest or manually update the Request fields. See the Request
+// type's documentation for the difference between inbound and outbound
+// request fields.
 func NewRequest(method, urlStr string, body io.Reader) (*Request, error) {
 	u, err := url.Parse(urlStr)
 	if err != nil {
@@ -536,10 +590,11 @@
 // parseBasicAuth parses an HTTP Basic Authentication string.
 // "Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==" returns ("Aladdin", "open sesame", true).
 func parseBasicAuth(auth string) (username, password string, ok bool) {
-	if !strings.HasPrefix(auth, "Basic ") {
+	const prefix = "Basic "
+	if !strings.HasPrefix(auth, prefix) {
 		return
 	}
-	c, err := base64.StdEncoding.DecodeString(strings.TrimPrefix(auth, "Basic "))
+	c, err := base64.StdEncoding.DecodeString(auth[len(prefix):])
 	if err != nil {
 		return
 	}
@@ -587,7 +642,7 @@
 	textprotoReaderPool.Put(r)
 }
 
-// ReadRequest reads and parses a request from b.
+// ReadRequest reads and parses an incoming request from b.
 func ReadRequest(b *bufio.Reader) (req *Request, err error) {
 
 	tp := newTextprotoReader(b)
@@ -660,19 +715,20 @@
 
 	fixPragmaCacheControl(req.Header)
 
+	req.Close = shouldClose(req.ProtoMajor, req.ProtoMinor, req.Header, false)
+
 	err = readTransfer(req, b)
 	if err != nil {
 		return nil, err
 	}
 
-	req.Close = shouldClose(req.ProtoMajor, req.ProtoMinor, req.Header, false)
 	return req, nil
 }
 
 // MaxBytesReader is similar to io.LimitReader but is intended for
 // limiting the size of incoming request bodies. In contrast to
 // io.LimitReader, MaxBytesReader's result is a ReadCloser, returns a
-// non-EOF error for a Read beyond the limit, and Closes the
+// non-EOF error for a Read beyond the limit, and closes the
 // underlying reader when its Close method is called.
 //
 // MaxBytesReader prevents clients from accidentally or maliciously
@@ -686,23 +742,52 @@
 	r       io.ReadCloser // underlying reader
 	n       int64         // max bytes remaining
 	stopped bool
+	sawEOF  bool
+}
+
+func (l *maxBytesReader) tooLarge() (n int, err error) {
+	if !l.stopped {
+		l.stopped = true
+		if res, ok := l.w.(*response); ok {
+			res.requestTooLarge()
+		}
+	}
+	return 0, errors.New("http: request body too large")
 }
 
 func (l *maxBytesReader) Read(p []byte) (n int, err error) {
-	if l.n <= 0 {
-		if !l.stopped {
-			l.stopped = true
-			if res, ok := l.w.(*response); ok {
-				res.requestTooLarge()
-			}
+	toRead := l.n
+	if l.n == 0 {
+		if l.sawEOF {
+			return l.tooLarge()
 		}
-		return 0, errors.New("http: request body too large")
+		// The underlying io.Reader may not return (0, io.EOF)
+		// at EOF if the requested size is 0, so read 1 byte
+		// instead. The io.Reader docs are a bit ambiguous
+		// about the return value of Read when 0 bytes are
+		// requested, and {bytes,strings}.Reader gets it wrong
+		// too (it returns (0, nil) even at EOF).
+		toRead = 1
 	}
-	if int64(len(p)) > l.n {
-		p = p[:l.n]
+	if int64(len(p)) > toRead {
+		p = p[:toRead]
 	}
 	n, err = l.r.Read(p)
+	if err == io.EOF {
+		l.sawEOF = true
+	}
+	if l.n == 0 {
+		// If we had zero bytes to read remaining (but hadn't seen EOF)
+		// and we get a byte here, that means we went over our limit.
+		if n > 0 {
+			return l.tooLarge()
+		}
+		return 0, err
+	}
 	l.n -= int64(n)
+	if l.n < 0 {
+		l.n = 0
+	}
 	return
 }
 
@@ -852,6 +937,7 @@
 // POST and PUT body parameters take precedence over URL query string values.
 // FormValue calls ParseMultipartForm and ParseForm if necessary and ignores
 // any errors returned by these functions.
+// If key is not present, FormValue returns the empty string.
 // To access multiple values of the same key, call ParseForm and
 // then inspect Request.Form directly.
 func (r *Request) FormValue(key string) string {
@@ -868,6 +954,7 @@
 // or PUT request body. URL query parameters are ignored.
 // PostFormValue calls ParseMultipartForm and ParseForm if necessary and ignores
 // any errors returned by these functions.
+// If key is not present, PostFormValue returns the empty string.
 func (r *Request) PostFormValue(key string) string {
 	if r.PostForm == nil {
 		r.ParseMultipartForm(defaultMaxMemory)
diff --git a/third_party/gofrontend/libgo/go/net/http/request_test.go b/third_party/gofrontend/libgo/go/net/http/request_test.go
index 759ea4e..627620c 100644
--- a/third_party/gofrontend/libgo/go/net/http/request_test.go
+++ b/third_party/gofrontend/libgo/go/net/http/request_test.go
@@ -178,6 +178,7 @@
 }
 
 func TestRedirect(t *testing.T) {
+	defer afterTest(t)
 	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
 		switch r.URL.Path {
 		case "/":
@@ -326,13 +327,31 @@
 	}
 }
 
+var newRequestHostTests = []struct {
+	in, out string
+}{
+	{"http://www.example.com/", "www.example.com"},
+	{"http://www.example.com:8080/", "www.example.com:8080"},
+
+	{"http://192.168.0.1/", "192.168.0.1"},
+	{"http://192.168.0.1:8080/", "192.168.0.1:8080"},
+
+	{"http://[fe80::1]/", "[fe80::1]"},
+	{"http://[fe80::1]:8080/", "[fe80::1]:8080"},
+	{"http://[fe80::1%25en0]/", "[fe80::1%en0]"},
+	{"http://[fe80::1%25en0]:8080/", "[fe80::1%en0]:8080"},
+}
+
 func TestNewRequestHost(t *testing.T) {
-	req, err := NewRequest("GET", "http://localhost:1234/", nil)
-	if err != nil {
-		t.Fatal(err)
-	}
-	if req.Host != "localhost:1234" {
-		t.Errorf("Host = %q; want localhost:1234", req.Host)
+	for i, tt := range newRequestHostTests {
+		req, err := NewRequest("GET", tt.in, nil)
+		if err != nil {
+			t.Errorf("#%v: %v", i, err)
+			continue
+		}
+		if req.Host != tt.out {
+			t.Errorf("got %q; want %q", req.Host, tt.out)
+		}
 	}
 }
 
@@ -402,8 +421,6 @@
 	ok                 bool
 }
 
-type parseBasicAuthTest getBasicAuthTest
-
 type basicAuthCredentialsTest struct {
 	username, password string
 }
@@ -496,6 +513,82 @@
 	}
 }
 
+func TestRequestBadHost(t *testing.T) {
+	got := []string{}
+	req, err := NewRequest("GET", "http://foo.com with spaces/after", nil)
+	if err != nil {
+		t.Fatal(err)
+	}
+	req.Write(logWrites{t, &got})
+	want := []string{
+		"GET /after HTTP/1.1\r\n",
+		"Host: foo.com\r\n",
+		"User-Agent: " + DefaultUserAgent + "\r\n",
+		"\r\n",
+	}
+	if !reflect.DeepEqual(got, want) {
+		t.Errorf("Writes = %q\n  Want = %q", got, want)
+	}
+}
+
+func TestStarRequest(t *testing.T) {
+	req, err := ReadRequest(bufio.NewReader(strings.NewReader("M-SEARCH * HTTP/1.1\r\n\r\n")))
+	if err != nil {
+		return
+	}
+	var out bytes.Buffer
+	if err := req.Write(&out); err != nil {
+		t.Fatal(err)
+	}
+	back, err := ReadRequest(bufio.NewReader(&out))
+	if err != nil {
+		t.Fatal(err)
+	}
+	// Ignore the Headers (the User-Agent breaks the deep equal,
+	// but we don't care about it)
+	req.Header = nil
+	back.Header = nil
+	if !reflect.DeepEqual(req, back) {
+		t.Errorf("Original request doesn't match Request read back.")
+		t.Logf("Original: %#v", req)
+		t.Logf("Original.URL: %#v", req.URL)
+		t.Logf("Wrote: %s", out.Bytes())
+		t.Logf("Read back (doesn't match Original): %#v", back)
+	}
+}
+
+type responseWriterJustWriter struct {
+	io.Writer
+}
+
+func (responseWriterJustWriter) Header() Header  { panic("should not be called") }
+func (responseWriterJustWriter) WriteHeader(int) { panic("should not be called") }
+
+// delayedEOFReader never returns (n > 0, io.EOF), instead putting
+// off the io.EOF until a subsequent Read call.
+type delayedEOFReader struct {
+	r io.Reader
+}
+
+func (dr delayedEOFReader) Read(p []byte) (n int, err error) {
+	n, err = dr.r.Read(p)
+	if n > 0 && err == io.EOF {
+		err = nil
+	}
+	return
+}
+
+func TestIssue10884_MaxBytesEOF(t *testing.T) {
+	dst := ioutil.Discard
+	_, err := io.Copy(dst, MaxBytesReader(
+		responseWriterJustWriter{dst},
+		ioutil.NopCloser(delayedEOFReader{strings.NewReader("12345")}),
+		5))
+	if err != nil {
+		t.Fatal(err)
+	}
+}
+
 func testMissingFile(t *testing.T, req *Request) {
 	f, fh, err := req.FormFile("missing")
 	if f != nil {
diff --git a/third_party/gofrontend/libgo/go/net/http/requestwrite_test.go b/third_party/gofrontend/libgo/go/net/http/requestwrite_test.go
index 7a6bd58..cfb95b0 100644
--- a/third_party/gofrontend/libgo/go/net/http/requestwrite_test.go
+++ b/third_party/gofrontend/libgo/go/net/http/requestwrite_test.go
@@ -93,13 +93,13 @@
 
 		WantWrite: "GET /search HTTP/1.1\r\n" +
 			"Host: www.google.com\r\n" +
-			"User-Agent: Go 1.1 package http\r\n" +
+			"User-Agent: Go-http-client/1.1\r\n" +
 			"Transfer-Encoding: chunked\r\n\r\n" +
 			chunk("abcdef") + chunk(""),
 
 		WantProxy: "GET http://www.google.com/search HTTP/1.1\r\n" +
 			"Host: www.google.com\r\n" +
-			"User-Agent: Go 1.1 package http\r\n" +
+			"User-Agent: Go-http-client/1.1\r\n" +
 			"Transfer-Encoding: chunked\r\n\r\n" +
 			chunk("abcdef") + chunk(""),
 	},
@@ -123,14 +123,14 @@
 
 		WantWrite: "POST /search HTTP/1.1\r\n" +
 			"Host: www.google.com\r\n" +
-			"User-Agent: Go 1.1 package http\r\n" +
+			"User-Agent: Go-http-client/1.1\r\n" +
 			"Connection: close\r\n" +
 			"Transfer-Encoding: chunked\r\n\r\n" +
 			chunk("abcdef") + chunk(""),
 
 		WantProxy: "POST http://www.google.com/search HTTP/1.1\r\n" +
 			"Host: www.google.com\r\n" +
-			"User-Agent: Go 1.1 package http\r\n" +
+			"User-Agent: Go-http-client/1.1\r\n" +
 			"Connection: close\r\n" +
 			"Transfer-Encoding: chunked\r\n\r\n" +
 			chunk("abcdef") + chunk(""),
@@ -156,7 +156,7 @@
 
 		WantWrite: "POST /search HTTP/1.1\r\n" +
 			"Host: www.google.com\r\n" +
-			"User-Agent: Go 1.1 package http\r\n" +
+			"User-Agent: Go-http-client/1.1\r\n" +
 			"Connection: close\r\n" +
 			"Content-Length: 6\r\n" +
 			"\r\n" +
@@ -164,7 +164,7 @@
 
 		WantProxy: "POST http://www.google.com/search HTTP/1.1\r\n" +
 			"Host: www.google.com\r\n" +
-			"User-Agent: Go 1.1 package http\r\n" +
+			"User-Agent: Go-http-client/1.1\r\n" +
 			"Connection: close\r\n" +
 			"Content-Length: 6\r\n" +
 			"\r\n" +
@@ -187,14 +187,14 @@
 
 		WantWrite: "POST / HTTP/1.1\r\n" +
 			"Host: example.com\r\n" +
-			"User-Agent: Go 1.1 package http\r\n" +
+			"User-Agent: Go-http-client/1.1\r\n" +
 			"Content-Length: 6\r\n" +
 			"\r\n" +
 			"abcdef",
 
 		WantProxy: "POST http://example.com/ HTTP/1.1\r\n" +
 			"Host: example.com\r\n" +
-			"User-Agent: Go 1.1 package http\r\n" +
+			"User-Agent: Go-http-client/1.1\r\n" +
 			"Content-Length: 6\r\n" +
 			"\r\n" +
 			"abcdef",
@@ -210,7 +210,7 @@
 
 		WantWrite: "GET /search HTTP/1.1\r\n" +
 			"Host: www.google.com\r\n" +
-			"User-Agent: Go 1.1 package http\r\n" +
+			"User-Agent: Go-http-client/1.1\r\n" +
 			"\r\n",
 	},
 
@@ -232,13 +232,13 @@
 		// Also, nginx expects it for POST and PUT.
 		WantWrite: "POST / HTTP/1.1\r\n" +
 			"Host: example.com\r\n" +
-			"User-Agent: Go 1.1 package http\r\n" +
+			"User-Agent: Go-http-client/1.1\r\n" +
 			"Content-Length: 0\r\n" +
 			"\r\n",
 
 		WantProxy: "POST / HTTP/1.1\r\n" +
 			"Host: example.com\r\n" +
-			"User-Agent: Go 1.1 package http\r\n" +
+			"User-Agent: Go-http-client/1.1\r\n" +
 			"Content-Length: 0\r\n" +
 			"\r\n",
 	},
@@ -258,13 +258,13 @@
 
 		WantWrite: "POST / HTTP/1.1\r\n" +
 			"Host: example.com\r\n" +
-			"User-Agent: Go 1.1 package http\r\n" +
+			"User-Agent: Go-http-client/1.1\r\n" +
 			"Transfer-Encoding: chunked\r\n\r\n" +
 			chunk("x") + chunk(""),
 
 		WantProxy: "POST / HTTP/1.1\r\n" +
 			"Host: example.com\r\n" +
-			"User-Agent: Go 1.1 package http\r\n" +
+			"User-Agent: Go-http-client/1.1\r\n" +
 			"Transfer-Encoding: chunked\r\n\r\n" +
 			chunk("x") + chunk(""),
 	},
@@ -365,7 +365,7 @@
 
 		WantWrite: "GET /foo HTTP/1.1\r\n" +
 			"Host: \r\n" +
-			"User-Agent: Go 1.1 package http\r\n" +
+			"User-Agent: Go-http-client/1.1\r\n" +
 			"X-Foo: X-Bar\r\n\r\n",
 	},
 
@@ -391,7 +391,7 @@
 
 		WantWrite: "GET /search HTTP/1.1\r\n" +
 			"Host: \r\n" +
-			"User-Agent: Go 1.1 package http\r\n\r\n",
+			"User-Agent: Go-http-client/1.1\r\n\r\n",
 	},
 
 	// Opaque test #1 from golang.org/issue/4860
@@ -410,7 +410,7 @@
 
 		WantWrite: "GET /%2F/%2F/ HTTP/1.1\r\n" +
 			"Host: www.google.com\r\n" +
-			"User-Agent: Go 1.1 package http\r\n\r\n",
+			"User-Agent: Go-http-client/1.1\r\n\r\n",
 	},
 
 	// Opaque test #2 from golang.org/issue/4860
@@ -429,7 +429,7 @@
 
 		WantWrite: "GET http://y.google.com/%2F/%2F/ HTTP/1.1\r\n" +
 			"Host: x.google.com\r\n" +
-			"User-Agent: Go 1.1 package http\r\n\r\n",
+			"User-Agent: Go-http-client/1.1\r\n\r\n",
 	},
 
 	// Testing custom case in header keys. Issue 5022.
@@ -451,10 +451,41 @@
 
 		WantWrite: "GET / HTTP/1.1\r\n" +
 			"Host: www.google.com\r\n" +
-			"User-Agent: Go 1.1 package http\r\n" +
+			"User-Agent: Go-http-client/1.1\r\n" +
 			"ALL-CAPS: x\r\n" +
 			"\r\n",
 	},
+
+	// Request with host header field; IPv6 address with zone identifier
+	{
+		Req: Request{
+			Method: "GET",
+			URL: &url.URL{
+				Host: "[fe80::1%en0]",
+			},
+		},
+
+		WantWrite: "GET / HTTP/1.1\r\n" +
+			"Host: [fe80::1]\r\n" +
+			"User-Agent: Go-http-client/1.1\r\n" +
+			"\r\n",
+	},
+
+	// Request with optional host header field; IPv6 address with zone identifier
+	{
+		Req: Request{
+			Method: "GET",
+			URL: &url.URL{
+				Host: "www.example.com",
+			},
+			Host: "[fe80::1%en0]:8080",
+		},
+
+		WantWrite: "GET / HTTP/1.1\r\n" +
+			"Host: [fe80::1]:8080\r\n" +
+			"User-Agent: Go-http-client/1.1\r\n" +
+			"\r\n",
+	},
 }
 
 func TestRequestWrite(t *testing.T) {
@@ -538,7 +569,7 @@
 	}
 	expected := "POST / HTTP/1.1\r\n" +
 		"Host: foo.com\r\n" +
-		"User-Agent: Go 1.1 package http\r\n" +
+		"User-Agent: Go-http-client/1.1\r\n" +
 		"Transfer-Encoding: chunked\r\n\r\n" +
 		// TODO: currently we don't buffer before chunking, so we get a
 		// single "m" chunk before the other chunks, as this was the 1-byte
diff --git a/third_party/gofrontend/libgo/go/net/http/response.go b/third_party/gofrontend/libgo/go/net/http/response.go
index 5d2c390..76b8538 100644
--- a/third_party/gofrontend/libgo/go/net/http/response.go
+++ b/third_party/gofrontend/libgo/go/net/http/response.go
@@ -48,7 +48,10 @@
 	// The http Client and Transport guarantee that Body is always
 	// non-nil, even on responses without a body or responses with
 	// a zero-length body. It is the caller's responsibility to
-	// close Body.
+	// close Body. The default HTTP client's Transport does not
+	// attempt to reuse HTTP/1.0 or HTTP/1.1 TCP connections
+	// ("keep-alive") unless the Body is read to completion and is
+	// closed.
 	//
 	// The Body is automatically dechunked if the server replied
 	// with a "chunked" Transfer-Encoding.
@@ -90,6 +93,8 @@
 	return readSetCookies(r.Header)
 }
 
+// ErrNoLocation is returned by Response's Location method
+// when no Location header is present.
 var ErrNoLocation = errors.New("http: no Location header in response")
 
 // Location returns the URL of the response's "Location" header,
@@ -186,8 +191,10 @@
 		r.ProtoMajor == major && r.ProtoMinor >= minor
 }
 
-// Writes the response (header, body and trailer) in wire format. This method
-// consults the following fields of the response:
+// Write writes r to w in the HTTP/1.n server response format,
+// including the status line, headers, body, and optional trailer.
+//
+// This method consults the following fields of the response r:
 //
 //  StatusCode
 //  ProtoMajor
@@ -199,7 +206,7 @@
 //  ContentLength
 //  Header, values for non-canonical keys will have unpredictable behavior
 //
-// Body is closed after it is sent.
+// The Response Body is closed after it is sent.
 func (r *Response) Write(w io.Writer) error {
 	// Status line
 	text := r.Status
diff --git a/third_party/gofrontend/libgo/go/net/http/response_test.go b/third_party/gofrontend/libgo/go/net/http/response_test.go
index 06e940d..421cf55 100644
--- a/third_party/gofrontend/libgo/go/net/http/response_test.go
+++ b/third_party/gofrontend/libgo/go/net/http/response_test.go
@@ -405,6 +405,57 @@
 
 		"foobar",
 	},
+
+	// Both keep-alive and close, on the same Connection line. (Issue 8840)
+	{
+		"HTTP/1.1 200 OK\r\n" +
+			"Content-Length: 256\r\n" +
+			"Connection: keep-alive, close\r\n" +
+			"\r\n",
+
+		Response{
+			Status:     "200 OK",
+			StatusCode: 200,
+			Proto:      "HTTP/1.1",
+			ProtoMajor: 1,
+			ProtoMinor: 1,
+			Request:    dummyReq("HEAD"),
+			Header: Header{
+				"Content-Length": {"256"},
+			},
+			TransferEncoding: nil,
+			Close:            true,
+			ContentLength:    256,
+		},
+
+		"",
+	},
+
+	// Both keep-alive and close, on different Connection lines. (Issue 8840)
+	{
+		"HTTP/1.1 200 OK\r\n" +
+			"Content-Length: 256\r\n" +
+			"Connection: keep-alive\r\n" +
+			"Connection: close\r\n" +
+			"\r\n",
+
+		Response{
+			Status:     "200 OK",
+			StatusCode: 200,
+			Proto:      "HTTP/1.1",
+			ProtoMajor: 1,
+			ProtoMinor: 1,
+			Request:    dummyReq("HEAD"),
+			Header: Header{
+				"Content-Length": {"256"},
+			},
+			TransferEncoding: nil,
+			Close:            true,
+			ContentLength:    256,
+		},
+
+		"",
+	},
 }
 
 func TestReadResponse(t *testing.T) {
diff --git a/third_party/gofrontend/libgo/go/net/http/responsewrite_test.go b/third_party/gofrontend/libgo/go/net/http/responsewrite_test.go
index 585b13b..5b8d47a 100644
--- a/third_party/gofrontend/libgo/go/net/http/responsewrite_test.go
+++ b/third_party/gofrontend/libgo/go/net/http/responsewrite_test.go
@@ -207,6 +207,21 @@
 			},
 			"HTTP/1.1 200 OK\r\nContent-Length: 0\r\n\r\n",
 		},
+
+		// When a response to a POST has Content-Length: -1, make sure we don't
+		// write the Content-Length as -1.
+		{
+			Response{
+				StatusCode:    StatusOK,
+				ProtoMajor:    1,
+				ProtoMinor:    1,
+				Request:       &Request{Method: "POST"},
+				Header:        Header{},
+				ContentLength: -1,
+				Body:          ioutil.NopCloser(strings.NewReader("abcdef")),
+			},
+			"HTTP/1.1 200 OK\r\nConnection: close\r\n\r\nabcdef",
+		},
 	}
 
 	for i := range respWriteTests {
diff --git a/third_party/gofrontend/libgo/go/net/http/serve_test.go b/third_party/gofrontend/libgo/go/net/http/serve_test.go
index 6bd168d..d51417e 100644
--- a/third_party/gofrontend/libgo/go/net/http/serve_test.go
+++ b/third_party/gofrontend/libgo/go/net/http/serve_test.go
@@ -20,6 +20,7 @@
 	. "net/http"
 	"net/http/httptest"
 	"net/http/httputil"
+	"net/http/internal"
 	"net/url"
 	"os"
 	"os/exec"
@@ -146,6 +147,7 @@
 }
 
 func TestConsumingBodyOnNextConn(t *testing.T) {
+	defer afterTest(t)
 	conn := new(testConn)
 	for i := 0; i < 2; i++ {
 		conn.readBuf.Write([]byte(
@@ -205,6 +207,7 @@
 }{
 	{"/", "Default"},
 	{"/someDir/", "someDir"},
+	{"/#/", "hash"},
 	{"someHost.com/someDir/", "someHost.com/someDir"},
 }
 
@@ -213,12 +216,14 @@
 	expected string
 }{
 	{"http://localhost/someDir/apage", "someDir"},
+	{"http://localhost/%23/apage", "hash"},
 	{"http://localhost/otherDir/apage", "Default"},
 	{"http://someHost.com/someDir/apage", "someHost.com/someDir"},
 	{"http://otherHost.com/someDir/apage", "someDir"},
 	{"http://otherHost.com/aDir/apage", "Default"},
 	// redirections for trees
 	{"http://localhost/someDir", "/someDir/"},
+	{"http://localhost/%23", "/%23/"},
 	{"http://someHost.com/someDir", "/someDir/"},
 }
 
@@ -416,7 +421,7 @@
 	}
 }
 
-// Tests for http://code.google.com/p/go/issues/detail?id=900
+// Tests for https://golang.org/issue/900
 func TestMuxRedirectLeadingSlashes(t *testing.T) {
 	paths := []string{"//foo.txt", "///foo.txt", "/../../foo.txt"}
 	for _, path := range paths {
@@ -443,7 +448,7 @@
 
 func TestServerTimeouts(t *testing.T) {
 	if runtime.GOOS == "plan9" {
-		t.Skip("skipping test; see http://golang.org/issue/7237")
+		t.Skip("skipping test; see https://golang.org/issue/7237")
 	}
 	defer afterTest(t)
 	reqNum := 0
@@ -522,7 +527,7 @@
 // request) that will never happen.
 func TestOnlyWriteTimeout(t *testing.T) {
 	if runtime.GOOS == "plan9" {
-		t.Skip("skipping test; see http://golang.org/issue/7237")
+		t.Skip("skipping test; see https://golang.org/issue/7237")
 	}
 	defer afterTest(t)
 	var conn net.Conn
@@ -877,7 +882,7 @@
 
 func TestTLSHandshakeTimeout(t *testing.T) {
 	if runtime.GOOS == "plan9" {
-		t.Skip("skipping test; see http://golang.org/issue/7237")
+		t.Skip("skipping test; see https://golang.org/issue/7237")
 	}
 	defer afterTest(t)
 	ts := httptest.NewUnstartedServer(HandlerFunc(func(w ResponseWriter, r *Request) {}))
@@ -1105,6 +1110,7 @@
 // Under a ~256KB (maxPostHandlerReadBytes) threshold, the server
 // should consume client request bodies that a handler didn't read.
 func TestServerUnreadRequestBodyLittle(t *testing.T) {
+	defer afterTest(t)
 	conn := new(testConn)
 	body := strings.Repeat("x", 100<<10)
 	conn.readBuf.Write([]byte(fmt.Sprintf(
@@ -1166,6 +1172,365 @@
 	}
 }
 
+type handlerBodyCloseTest struct {
+	bodySize     int
+	bodyChunked  bool
+	reqConnClose bool
+
+	wantEOFSearch bool // should Handler's Body.Close do Reads, looking for EOF?
+	wantNextReq   bool // should it find the next request on the same conn?
+}
+
+func (t handlerBodyCloseTest) connectionHeader() string {
+	if t.reqConnClose {
+		return "Connection: close\r\n"
+	}
+	return ""
+}
+
+var handlerBodyCloseTests = [...]handlerBodyCloseTest{
+	// Small enough to slurp past to the next request +
+	// has Content-Length.
+	0: {
+		bodySize:      20 << 10,
+		bodyChunked:   false,
+		reqConnClose:  false,
+		wantEOFSearch: true,
+		wantNextReq:   true,
+	},
+
+	// Small enough to slurp past to the next request +
+	// is chunked.
+	1: {
+		bodySize:      20 << 10,
+		bodyChunked:   true,
+		reqConnClose:  false,
+		wantEOFSearch: true,
+		wantNextReq:   true,
+	},
+
+	// Small enough to slurp past to the next request +
+	// has Content-Length +
+	// declares Connection: close (so pointless to read more).
+	2: {
+		bodySize:      20 << 10,
+		bodyChunked:   false,
+		reqConnClose:  true,
+		wantEOFSearch: false,
+		wantNextReq:   false,
+	},
+
+	// Small enough to slurp past to the next request +
+	// declares Connection: close,
+	// but chunked, so it might have trailers.
+	// TODO: maybe skip this search if no trailers were declared
+	// in the headers.
+	3: {
+		bodySize:      20 << 10,
+		bodyChunked:   true,
+		reqConnClose:  true,
+		wantEOFSearch: true,
+		wantNextReq:   false,
+	},
+
+	// Big with Content-Length, so give up immediately if we know it's too big.
+	4: {
+		bodySize:      1 << 20,
+		bodyChunked:   false, // has a Content-Length
+		reqConnClose:  false,
+		wantEOFSearch: false,
+		wantNextReq:   false,
+	},
+
+	// Big chunked, so read a bit before giving up.
+	5: {
+		bodySize:      1 << 20,
+		bodyChunked:   true,
+		reqConnClose:  false,
+		wantEOFSearch: true,
+		wantNextReq:   false,
+	},
+
+	// Big with Connection: close, but chunked, so search for trailers.
+	// TODO: maybe skip this search if no trailers were declared
+	// in the headers.
+	6: {
+		bodySize:      1 << 20,
+		bodyChunked:   true,
+		reqConnClose:  true,
+		wantEOFSearch: true,
+		wantNextReq:   false,
+	},
+
+	// Big with Connection: close, so don't do any reads on Close.
+	// With Content-Length.
+	7: {
+		bodySize:      1 << 20,
+		bodyChunked:   false,
+		reqConnClose:  true,
+		wantEOFSearch: false,
+		wantNextReq:   false,
+	},
+}
+
+func TestHandlerBodyClose(t *testing.T) {
+	for i, tt := range handlerBodyCloseTests {
+		testHandlerBodyClose(t, i, tt)
+	}
+}
+
+func testHandlerBodyClose(t *testing.T, i int, tt handlerBodyCloseTest) {
+	conn := new(testConn)
+	body := strings.Repeat("x", tt.bodySize)
+	if tt.bodyChunked {
+		conn.readBuf.WriteString("POST / HTTP/1.1\r\n" +
+			"Host: test\r\n" +
+			tt.connectionHeader() +
+			"Transfer-Encoding: chunked\r\n" +
+			"\r\n")
+		cw := internal.NewChunkedWriter(&conn.readBuf)
+		io.WriteString(cw, body)
+		cw.Close()
+		conn.readBuf.WriteString("\r\n")
+	} else {
+		conn.readBuf.Write([]byte(fmt.Sprintf(
+			"POST / HTTP/1.1\r\n"+
+				"Host: test\r\n"+
+				tt.connectionHeader()+
+				"Content-Length: %d\r\n"+
+				"\r\n", len(body))))
+		conn.readBuf.Write([]byte(body))
+	}
+	if !tt.reqConnClose {
+		conn.readBuf.WriteString("GET / HTTP/1.1\r\nHost: test\r\n\r\n")
+	}
+	conn.closec = make(chan bool, 1)
+
+	ls := &oneConnListener{conn}
+	var numReqs int
+	var size0, size1 int
+	go Serve(ls, HandlerFunc(func(rw ResponseWriter, req *Request) {
+		numReqs++
+		if numReqs == 1 {
+			size0 = conn.readBuf.Len()
+			req.Body.Close()
+			size1 = conn.readBuf.Len()
+		}
+	}))
+	<-conn.closec
+	if numReqs < 1 || numReqs > 2 {
+		t.Fatalf("%d. bug in test. unexpected number of requests = %d", i, numReqs)
+	}
+	didSearch := size0 != size1
+	if didSearch != tt.wantEOFSearch {
+		t.Errorf("%d. did EOF search = %v; want %v (size went from %d to %d)", i, didSearch, !didSearch, size0, size1)
+	}
+	if tt.wantNextReq && numReqs != 2 {
+		t.Errorf("%d. numReq = %d; want 2", i, numReqs)
+	}
+}
+
+// testHandlerBodyConsumer represents a function injected into a test handler to
+// vary work done on a request Body.
+type testHandlerBodyConsumer struct {
+	name string
+	f    func(io.ReadCloser)
+}
+
+var testHandlerBodyConsumers = []testHandlerBodyConsumer{
+	{"nil", func(io.ReadCloser) {}},
+	{"close", func(r io.ReadCloser) { r.Close() }},
+	{"discard", func(r io.ReadCloser) { io.Copy(ioutil.Discard, r) }},
+}
+
+func TestRequestBodyReadErrorClosesConnection(t *testing.T) {
+	defer afterTest(t)
+	for _, handler := range testHandlerBodyConsumers {
+		conn := new(testConn)
+		conn.readBuf.WriteString("POST /public HTTP/1.1\r\n" +
+			"Host: test\r\n" +
+			"Transfer-Encoding: chunked\r\n" +
+			"\r\n" +
+			"hax\r\n" + // Invalid chunked encoding
+			"GET /secret HTTP/1.1\r\n" +
+			"Host: test\r\n" +
+			"\r\n")
+
+		conn.closec = make(chan bool, 1)
+		ls := &oneConnListener{conn}
+		var numReqs int
+		go Serve(ls, HandlerFunc(func(_ ResponseWriter, req *Request) {
+			numReqs++
+			if strings.Contains(req.URL.Path, "secret") {
+				t.Error("Request for /secret encountered, should not have happened.")
+			}
+			handler.f(req.Body)
+		}))
+		<-conn.closec
+		if numReqs != 1 {
+			t.Errorf("Handler %v: got %d reqs; want 1", handler.name, numReqs)
+		}
+	}
+}
+
+func TestInvalidTrailerClosesConnection(t *testing.T) {
+	defer afterTest(t)
+	for _, handler := range testHandlerBodyConsumers {
+		conn := new(testConn)
+		conn.readBuf.WriteString("POST /public HTTP/1.1\r\n" +
+			"Host: test\r\n" +
+			"Trailer: hack\r\n" +
+			"Transfer-Encoding: chunked\r\n" +
+			"\r\n" +
+			"3\r\n" +
+			"hax\r\n" +
+			"0\r\n" +
+			"I'm not a valid trailer\r\n" +
+			"GET /secret HTTP/1.1\r\n" +
+			"Host: test\r\n" +
+			"\r\n")
+
+		conn.closec = make(chan bool, 1)
+		ln := &oneConnListener{conn}
+		var numReqs int
+		go Serve(ln, HandlerFunc(func(_ ResponseWriter, req *Request) {
+			numReqs++
+			if strings.Contains(req.URL.Path, "secret") {
+				t.Errorf("Handler %s, Request for /secret encountered, should not have happened.", handler.name)
+			}
+			handler.f(req.Body)
+		}))
+		<-conn.closec
+		if numReqs != 1 {
+			t.Errorf("Handler %s: got %d reqs; want 1", handler.name, numReqs)
+		}
+	}
+}
+
+// slowTestConn is a net.Conn that provides a means to simulate parts of a
+// request being received piecemeal. Deadlines can be set and enforced in both
+// Read and Write.
+type slowTestConn struct {
+	// over multiple calls to Read, time.Durations are slept, strings are read.
+	script []interface{}
+	closec chan bool
+	rd, wd time.Time // read, write deadline
+	noopConn
+}
+
+func (c *slowTestConn) SetDeadline(t time.Time) error {
+	c.SetReadDeadline(t)
+	c.SetWriteDeadline(t)
+	return nil
+}
+
+func (c *slowTestConn) SetReadDeadline(t time.Time) error {
+	c.rd = t
+	return nil
+}
+
+func (c *slowTestConn) SetWriteDeadline(t time.Time) error {
+	c.wd = t
+	return nil
+}
+
+func (c *slowTestConn) Read(b []byte) (n int, err error) {
+restart:
+	if !c.rd.IsZero() && time.Now().After(c.rd) {
+		return 0, syscall.ETIMEDOUT
+	}
+	if len(c.script) == 0 {
+		return 0, io.EOF
+	}
+
+	switch cue := c.script[0].(type) {
+	case time.Duration:
+		if !c.rd.IsZero() {
+			// If the deadline falls in the middle of our sleep window, deduct
+			// part of the sleep, then return a timeout.
+			if remaining := c.rd.Sub(time.Now()); remaining < cue {
+				c.script[0] = cue - remaining
+				time.Sleep(remaining)
+				return 0, syscall.ETIMEDOUT
+			}
+		}
+		c.script = c.script[1:]
+		time.Sleep(cue)
+		goto restart
+
+	case string:
+		n = copy(b, cue)
+		// If cue is too big for the buffer, leave the end for the next Read.
+		if len(cue) > n {
+			c.script[0] = cue[n:]
+		} else {
+			c.script = c.script[1:]
+		}
+
+	default:
+		panic("unknown cue in slowTestConn script")
+	}
+
+	return
+}
+
+func (c *slowTestConn) Close() error {
+	select {
+	case c.closec <- true:
+	default:
+	}
+	return nil
+}
+
+func (c *slowTestConn) Write(b []byte) (int, error) {
+	if !c.wd.IsZero() && time.Now().After(c.wd) {
+		return 0, syscall.ETIMEDOUT
+	}
+	return len(b), nil
+}
+
+func TestRequestBodyTimeoutClosesConnection(t *testing.T) {
+	if testing.Short() {
+		t.Skip("skipping in -short mode")
+	}
+	defer afterTest(t)
+	for _, handler := range testHandlerBodyConsumers {
+		conn := &slowTestConn{
+			script: []interface{}{
+				"POST /public HTTP/1.1\r\n" +
+					"Host: test\r\n" +
+					"Content-Length: 10000\r\n" +
+					"\r\n",
+				"foo bar baz",
+				600 * time.Millisecond, // Request deadline should hit here
+				"GET /secret HTTP/1.1\r\n" +
+					"Host: test\r\n" +
+					"\r\n",
+			},
+			closec: make(chan bool, 1),
+		}
+		ls := &oneConnListener{conn}
+
+		var numReqs int
+		s := Server{
+			Handler: HandlerFunc(func(_ ResponseWriter, req *Request) {
+				numReqs++
+				if strings.Contains(req.URL.Path, "secret") {
+					t.Error("Request for /secret encountered, should not have happened.")
+				}
+				handler.f(req.Body)
+			}),
+			ReadTimeout: 400 * time.Millisecond,
+		}
+		go s.Serve(ls)
+		<-conn.closec
+
+		if numReqs != 1 {
+			t.Errorf("Handler %v: got %d reqs; want 1", handler.name, numReqs)
+		}
+	}
+}
+
 func TestTimeoutHandler(t *testing.T) {
 	defer afterTest(t)
 	sendHi := make(chan bool, 1)
@@ -1451,19 +1816,23 @@
 	}
 }
 
-func TestNoDate(t *testing.T) {
+func TestServerNoDate(t *testing.T)        { testServerNoHeader(t, "Date") }
+func TestServerNoContentType(t *testing.T) { testServerNoHeader(t, "Content-Type") }
+
+func testServerNoHeader(t *testing.T, header string) {
 	defer afterTest(t)
 	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
-		w.Header()["Date"] = nil
+		w.Header()[header] = nil
+		io.WriteString(w, "<html>foo</html>") // non-empty
 	}))
 	defer ts.Close()
 	res, err := Get(ts.URL)
 	if err != nil {
 		t.Fatal(err)
 	}
-	_, present := res.Header["Date"]
-	if present {
-		t.Fatalf("Expected no Date header; got %v", res.Header["Date"])
+	res.Body.Close()
+	if got, ok := res.Header[header]; ok {
+		t.Fatalf("Expected no %s header; got %q", header, got)
 	}
 }
 
@@ -1577,7 +1946,7 @@
 // side of their TCP connection, the server doesn't send a 400 Bad Request.
 func TestClientWriteShutdown(t *testing.T) {
 	if runtime.GOOS == "plan9" {
-		t.Skip("skipping test; see http://golang.org/issue/7237")
+		t.Skip("skipping test; see https://golang.org/issue/7237")
 	}
 	defer afterTest(t)
 	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {}))
@@ -1632,7 +2001,7 @@
 // Tests that the server flushes its response headers out when it's
 // ignoring the response body and waits a bit before forcefully
 // closing the TCP connection, causing the client to get a RST.
-// See http://golang.org/issue/3595
+// See https://golang.org/issue/3595
 func TestServerGracefulClose(t *testing.T) {
 	defer afterTest(t)
 	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
@@ -2124,7 +2493,7 @@
 	<-conn.closec
 }
 
-// http://code.google.com/p/go/issues/detail?id=5955
+// https://golang.org/issue/5955
 // Note that this does not test the "request too large"
 // exit path from the http server. This is intentional;
 // not sending Connection: close is just a minor wire
@@ -2288,17 +2657,13 @@
 
 	unblockBackend := make(chan bool)
 	backend := httptest.NewServer(HandlerFunc(func(rw ResponseWriter, req *Request) {
-		io.CopyN(rw, req.Body, bodySize/2)
+		io.CopyN(rw, req.Body, bodySize)
 		<-unblockBackend
 	}))
 	defer backend.Close()
 
 	backendRespc := make(chan *Response, 1)
 	proxy := httptest.NewServer(HandlerFunc(func(rw ResponseWriter, req *Request) {
-		if req.RequestURI == "/foo" {
-			rw.Write([]byte("bar"))
-			return
-		}
 		req2, _ := NewRequest("POST", backend.URL, req.Body)
 		req2.ContentLength = bodySize
 
@@ -2307,7 +2672,7 @@
 			t.Errorf("Proxy outbound request: %v", err)
 			return
 		}
-		_, err = io.CopyN(ioutil.Discard, bresp.Body, bodySize/4)
+		_, err = io.CopyN(ioutil.Discard, bresp.Body, bodySize/2)
 		if err != nil {
 			t.Errorf("Proxy copy error: %v", err)
 			return
@@ -2321,6 +2686,7 @@
 	}))
 	defer proxy.Close()
 
+	defer close(unblockBackend)
 	req, _ := NewRequest("POST", proxy.URL, io.LimitReader(neverEnding('a'), bodySize))
 	res, err := DefaultClient.Do(req)
 	if err != nil {
@@ -2329,8 +2695,12 @@
 
 	// Cleanup, so we don't leak goroutines.
 	res.Body.Close()
-	close(unblockBackend)
-	(<-backendRespc).Body.Close()
+	select {
+	case res := <-backendRespc:
+		res.Body.Close()
+	default:
+		// We failed earlier. (e.g. on DefaultClient.Do(req2))
+	}
 }
 
 // Test that a hanging Request.Body.Read from another goroutine can't
@@ -2384,19 +2754,24 @@
 	}
 }
 
-func TestResponseWriterWriteStringAllocs(t *testing.T) {
-	t.Skip("allocs test unreliable with gccgo")
+// test that ResponseWriter implements io.stringWriter.
+func TestResponseWriterWriteString(t *testing.T) {
+	okc := make(chan bool, 1)
 	ht := newHandlerTest(HandlerFunc(func(w ResponseWriter, r *Request) {
-		if r.URL.Path == "/s" {
-			io.WriteString(w, "Hello world")
-		} else {
-			w.Write([]byte("Hello world"))
+		type stringWriter interface {
+			WriteString(s string) (n int, err error)
 		}
+		_, ok := w.(stringWriter)
+		okc <- ok
 	}))
-	before := testing.AllocsPerRun(50, func() { ht.rawResponse("GET / HTTP/1.0") })
-	after := testing.AllocsPerRun(50, func() { ht.rawResponse("GET /s HTTP/1.0") })
-	if int(after) >= int(before) {
-		t.Errorf("WriteString allocs of %v >= Write allocs of %v", after, before)
+	ht.rawResponse("GET / HTTP/1.0")
+	select {
+	case ok := <-okc:
+		if !ok {
+			t.Error("ResponseWriter did not implement io.stringWriter")
+		}
+	default:
+		t.Error("handler was never called")
 	}
 }
 
@@ -2757,6 +3132,134 @@
 	}
 }
 
+// Issue 9987: shouldn't add automatic Content-Length (or
+// Content-Type) if a Transfer-Encoding was set by the handler.
+func TestNoContentLengthIfTransferEncoding(t *testing.T) {
+	defer afterTest(t)
+	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
+		w.Header().Set("Transfer-Encoding", "foo")
+		io.WriteString(w, "<html>")
+	}))
+	defer ts.Close()
+	c, err := net.Dial("tcp", ts.Listener.Addr().String())
+	if err != nil {
+		t.Fatalf("Dial: %v", err)
+	}
+	defer c.Close()
+	if _, err := io.WriteString(c, "GET / HTTP/1.1\r\nHost: foo\r\n\r\n"); err != nil {
+		t.Fatal(err)
+	}
+	bs := bufio.NewScanner(c)
+	var got bytes.Buffer
+	for bs.Scan() {
+		if strings.TrimSpace(bs.Text()) == "" {
+			break
+		}
+		got.WriteString(bs.Text())
+		got.WriteByte('\n')
+	}
+	if err := bs.Err(); err != nil {
+		t.Fatal(err)
+	}
+	if strings.Contains(got.String(), "Content-Length") {
+		t.Errorf("Unexpected Content-Length in response headers: %s", got.String())
+	}
+	if strings.Contains(got.String(), "Content-Type") {
+		t.Errorf("Unexpected Content-Type in response headers: %s", got.String())
+	}
+}
+
+// tolerate extra CRLF(s) before Request-Line on subsequent requests on a conn
+// Issue 10876.
+func TestTolerateCRLFBeforeRequestLine(t *testing.T) {
+	req := []byte("POST / HTTP/1.1\r\nHost: golang.org\r\nContent-Length: 3\r\n\r\nABC" +
+		"\r\n\r\n" + // <-- this stuff is bogus, but we'll ignore it
+		"GET / HTTP/1.1\r\nHost: golang.org\r\n\r\n")
+	var buf bytes.Buffer
+	conn := &rwTestConn{
+		Reader: bytes.NewReader(req),
+		Writer: &buf,
+		closec: make(chan bool, 1),
+	}
+	ln := &oneConnListener{conn: conn}
+	numReq := 0
+	go Serve(ln, HandlerFunc(func(rw ResponseWriter, r *Request) {
+		numReq++
+	}))
+	<-conn.closec
+	if numReq != 2 {
+		t.Errorf("num requests = %d; want 2", numReq)
+		t.Logf("Res: %s", buf.Bytes())
+	}
+}
+
+func TestIssue11549_Expect100(t *testing.T) {
+	req := reqBytes(`PUT /readbody HTTP/1.1
+User-Agent: PycURL/7.22.0
+Host: 127.0.0.1:9000
+Accept: */*
+Expect: 100-continue
+Content-Length: 10
+
+HelloWorldPUT /noreadbody HTTP/1.1
+User-Agent: PycURL/7.22.0
+Host: 127.0.0.1:9000
+Accept: */*
+Expect: 100-continue
+Content-Length: 10
+
+GET /should-be-ignored HTTP/1.1
+Host: foo
+
+`)
+	var buf bytes.Buffer
+	conn := &rwTestConn{
+		Reader: bytes.NewReader(req),
+		Writer: &buf,
+		closec: make(chan bool, 1),
+	}
+	ln := &oneConnListener{conn: conn}
+	numReq := 0
+	go Serve(ln, HandlerFunc(func(w ResponseWriter, r *Request) {
+		numReq++
+		if r.URL.Path == "/readbody" {
+			ioutil.ReadAll(r.Body)
+		}
+		io.WriteString(w, "Hello world!")
+	}))
+	<-conn.closec
+	if numReq != 2 {
+		t.Errorf("num requests = %d; want 2", numReq)
+	}
+	if !strings.Contains(buf.String(), "Connection: close\r\n") {
+		t.Errorf("expected 'Connection: close' in response; got: %s", buf.String())
+	}
+}
+
+// If a Handler finishes and there's an unread request body,
+// verify the server try to do implicit read on it before replying.
+func TestHandlerFinishSkipBigContentLengthRead(t *testing.T) {
+	conn := &testConn{closec: make(chan bool)}
+	conn.readBuf.Write([]byte(fmt.Sprintf(
+		"POST / HTTP/1.1\r\n" +
+			"Host: test\r\n" +
+			"Content-Length: 9999999999\r\n" +
+			"\r\n" + strings.Repeat("a", 1<<20))))
+
+	ls := &oneConnListener{conn}
+	var inHandlerLen int
+	go Serve(ls, HandlerFunc(func(rw ResponseWriter, req *Request) {
+		inHandlerLen = conn.readBuf.Len()
+		rw.WriteHeader(404)
+	}))
+	<-conn.closec
+	afterHandlerLen := conn.readBuf.Len()
+
+	if afterHandlerLen != inHandlerLen {
+		t.Errorf("unexpected implicit read. Read buffer went from %d -> %d", inHandlerLen, afterHandlerLen)
+	}
+}
+
 func BenchmarkClientServer(b *testing.B) {
 	b.ReportAllocs()
 	b.StopTimer()
@@ -2886,7 +3389,7 @@
 	defer ts.Close()
 	b.StartTimer()
 
-	cmd := exec.Command(os.Args[0], "-test.run=XXXX", "-test.bench=BenchmarkServer")
+	cmd := exec.Command(os.Args[0], "-test.run=XXXX", "-test.bench=BenchmarkServer$")
 	cmd.Env = append([]string{
 		fmt.Sprintf("TEST_BENCH_CLIENT_N=%d", b.N),
 		fmt.Sprintf("TEST_BENCH_SERVER_URL=%s", ts.URL),
@@ -2897,6 +3400,95 @@
 	}
 }
 
+// getNoBody wraps Get but closes any Response.Body before returning the response.
+func getNoBody(urlStr string) (*Response, error) {
+	res, err := Get(urlStr)
+	if err != nil {
+		return nil, err
+	}
+	res.Body.Close()
+	return res, nil
+}
+
+// A benchmark for profiling the client without the HTTP server code.
+// The server code runs in a subprocess.
+func BenchmarkClient(b *testing.B) {
+	b.ReportAllocs()
+	b.StopTimer()
+	defer afterTest(b)
+
+	port := os.Getenv("TEST_BENCH_SERVER_PORT") // can be set by user
+	if port == "" {
+		port = "39207"
+	}
+	var data = []byte("Hello world.\n")
+	if server := os.Getenv("TEST_BENCH_SERVER"); server != "" {
+		// Server process mode.
+		HandleFunc("/", func(w ResponseWriter, r *Request) {
+			r.ParseForm()
+			if r.Form.Get("stop") != "" {
+				os.Exit(0)
+			}
+			w.Header().Set("Content-Type", "text/html; charset=utf-8")
+			w.Write(data)
+		})
+		log.Fatal(ListenAndServe("localhost:"+port, nil))
+	}
+
+	// Start server process.
+	cmd := exec.Command(os.Args[0], "-test.run=XXXX", "-test.bench=BenchmarkClient$")
+	cmd.Env = append(os.Environ(), "TEST_BENCH_SERVER=yes")
+	if err := cmd.Start(); err != nil {
+		b.Fatalf("subprocess failed to start: %v", err)
+	}
+	defer cmd.Process.Kill()
+	done := make(chan error)
+	go func() {
+		done <- cmd.Wait()
+	}()
+
+	// Wait for the server process to respond.
+	url := "http://localhost:" + port + "/"
+	for i := 0; i < 100; i++ {
+		time.Sleep(50 * time.Millisecond)
+		if _, err := getNoBody(url); err == nil {
+			break
+		}
+		if i == 99 {
+			b.Fatalf("subprocess does not respond")
+		}
+	}
+
+	// Do b.N requests to the server.
+	b.StartTimer()
+	for i := 0; i < b.N; i++ {
+		res, err := Get(url)
+		if err != nil {
+			b.Fatalf("Get: %v", err)
+		}
+		body, err := ioutil.ReadAll(res.Body)
+		res.Body.Close()
+		if err != nil {
+			b.Fatalf("ReadAll: %v", err)
+		}
+		if bytes.Compare(body, data) != 0 {
+			b.Fatalf("Got body: %q", body)
+		}
+	}
+	b.StopTimer()
+
+	// Instruct server process to stop.
+	getNoBody(url + "?stop=yes")
+	select {
+	case err := <-done:
+		if err != nil {
+			b.Fatalf("subprocess failed: %v", err)
+		}
+	case <-time.After(5 * time.Second):
+		b.Fatalf("subprocess did not stop")
+	}
+}
+
 func BenchmarkServerFakeConnNoKeepAlive(b *testing.B) {
 	b.ReportAllocs()
 	req := reqBytes(`GET / HTTP/1.0
diff --git a/third_party/gofrontend/libgo/go/net/http/server.go b/third_party/gofrontend/libgo/go/net/http/server.go
index 008d5aa..a3e4355 100644
--- a/third_party/gofrontend/libgo/go/net/http/server.go
+++ b/third_party/gofrontend/libgo/go/net/http/server.go
@@ -15,6 +15,7 @@
 	"io/ioutil"
 	"log"
 	"net"
+	"net/textproto"
 	"net/url"
 	"os"
 	"path"
@@ -55,9 +56,12 @@
 // A ResponseWriter interface is used by an HTTP handler to
 // construct an HTTP response.
 type ResponseWriter interface {
-	// Header returns the header map that will be sent by WriteHeader.
-	// Changing the header after a call to WriteHeader (or Write) has
-	// no effect.
+	// Header returns the header map that will be sent by
+	// WriteHeader. Changing the header after a call to
+	// WriteHeader (or Write) has no effect unless the modified
+	// headers were declared as trailers by setting the
+	// "Trailer" header before the call to WriteHeader (see example).
+	// To suppress implicit response headers, set their value to nil.
 	Header() Header
 
 	// Write writes the data to the connection as part of an HTTP reply.
@@ -93,8 +97,14 @@
 	// Hijack lets the caller take over the connection.
 	// After a call to Hijack(), the HTTP server library
 	// will not do anything else with the connection.
+	//
 	// It becomes the caller's responsibility to manage
 	// and close the connection.
+	//
+	// The returned net.Conn may have read or write deadlines
+	// already set, depending on the configuration of the
+	// Server. It is the caller's responsibility to set
+	// or clear those deadlines as needed.
 	Hijack() (net.Conn, *bufio.ReadWriter, error)
 }
 
@@ -120,6 +130,7 @@
 	lr         *io.LimitedReader    // io.LimitReader(sr)
 	buf        *bufio.ReadWriter    // buffered(lr,rwc), reading from bufio->limitReader->sr->rwc
 	tlsState   *tls.ConnectionState // or nil when not using TLS
+	lastMethod string               // method of previous request, or ""
 
 	mu           sync.Mutex // guards the following
 	clientGone   bool       // if client has disconnected mid-request
@@ -188,20 +199,14 @@
 	c.clientGone = true
 }
 
-// A switchReader can have its Reader changed at runtime.
-// It's not safe for concurrent Reads and switches.
-type switchReader struct {
-	io.Reader
-}
-
 // A switchWriter can have its Writer changed at runtime.
 // It's not safe for concurrent Writes and switches.
 type switchWriter struct {
 	io.Writer
 }
 
-// A liveSwitchReader is a switchReader that's safe for concurrent
-// reads and switches, if its mutex is held.
+// A liveSwitchReader can have its Reader changed at runtime. It's
+// safe for concurrent reads and switches, if its mutex is held.
 type liveSwitchReader struct {
 	sync.Mutex
 	r io.Reader
@@ -288,10 +293,21 @@
 		cw.writeHeader(nil)
 	}
 	if cw.chunking {
-		// zero EOF chunk, trailer key/value pairs (currently
-		// unsupported in Go's server), followed by a blank
-		// line.
-		cw.res.conn.buf.WriteString("0\r\n\r\n")
+		bw := cw.res.conn.buf // conn's bufio writer
+		// zero chunk to mark EOF
+		bw.WriteString("0\r\n")
+		if len(cw.res.trailers) > 0 {
+			trailers := make(Header)
+			for _, h := range cw.res.trailers {
+				if vv := cw.res.handlerHeader[h]; len(vv) > 0 {
+					trailers[h] = vv
+				}
+			}
+			trailers.Write(bw) // the writer handles noting errors
+		}
+		// final blank line after the trailers (whether
+		// present or not)
+		bw.WriteString("\r\n")
 	}
 }
 
@@ -332,6 +348,12 @@
 	// input from it.
 	requestBodyLimitHit bool
 
+	// trailers are the headers to be sent after the handler
+	// finishes writing the body.  This field is initialized from
+	// the Trailer response header when the response header is
+	// written.
+	trailers []string
+
 	handlerDone bool // set true when the handler exits
 
 	// Buffers for Date and Content-Length
@@ -339,6 +361,19 @@
 	clenBuf [10]byte
 }
 
+// declareTrailer is called for each Trailer header when the
+// response header is written. It notes that a header will need to be
+// written in the trailers at the end of the response.
+func (w *response) declareTrailer(k string) {
+	k = CanonicalHeaderKey(k)
+	switch k {
+	case "Transfer-Encoding", "Content-Length", "Trailer":
+		// Forbidden by RFC 2616 14.40.
+		return
+	}
+	w.trailers = append(w.trailers, k)
+}
+
 // requestTooLarge is called by maxBytesReader when too much input has
 // been read from the client.
 func (w *response) requestTooLarge() {
@@ -438,7 +473,7 @@
 	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)
@@ -468,6 +503,8 @@
 		br.Reset(r)
 		return br
 	}
+	// Note: if this reader size is every changed, update
+	// TestHandlerBodyClose's assumptions.
 	return bufio.NewReader(r)
 }
 
@@ -517,6 +554,7 @@
 	resp       *response
 	readCloser io.ReadCloser
 	closed     bool
+	sawEOF     bool
 }
 
 func (ecr *expectContinueReader) Read(p []byte) (n int, err error) {
@@ -528,7 +566,11 @@
 		ecr.resp.conn.buf.WriteString("HTTP/1.1 100 Continue\r\n\r\n")
 		ecr.resp.conn.buf.Flush()
 	}
-	return ecr.readCloser.Read(p)
+	n, err = ecr.readCloser.Read(p)
+	if err == io.EOF {
+		ecr.sawEOF = true
+	}
+	return
 }
 
 func (ecr *expectContinueReader) Close() error {
@@ -582,6 +624,11 @@
 	}
 
 	c.lr.N = c.server.initialLimitedReaderSize()
+	if c.lastMethod == "POST" {
+		// RFC 2616 section 4.1 tolerance for old buggy clients.
+		peek, _ := c.buf.Reader.Peek(4) // ReadRequest will get err below
+		c.buf.Reader.Discard(numLeadingCRorLF(peek))
+	}
 	var req *Request
 	if req, err = ReadRequest(c.buf.Reader); err != nil {
 		if c.lr.N == 0 {
@@ -590,9 +637,13 @@
 		return nil, err
 	}
 	c.lr.N = noLimit
+	c.lastMethod = req.Method
 
 	req.RemoteAddr = c.remoteAddr
 	req.TLS = c.tlsState
+	if body, ok := req.Body.(*body); ok {
+		body.doEarlyClose = true
+	}
 
 	w = &response{
 		conn:          c,
@@ -747,6 +798,15 @@
 	}
 	var setHeader extraHeader
 
+	trailers := false
+	for _, v := range cw.header["Trailer"] {
+		trailers = true
+		foreachHeaderElement(v, cw.res.declareTrailer)
+	}
+
+	te := header.get("Transfer-Encoding")
+	hasTE := te != ""
+
 	// If the handler is done but never sent a Content-Length
 	// response header and this is our first (and last) write, set
 	// it, even to zero. This helps HTTP/1.0 clients keep their
@@ -759,7 +819,9 @@
 	// write non-zero bytes.  If it's actually 0 bytes and the
 	// handler never looked at the Request.Method, we just don't
 	// send a Content-Length header.
-	if w.handlerDone && bodyAllowedForStatus(w.status) && header.get("Content-Length") == "" && (!isHEAD || len(p) > 0) {
+	// Further, we don't send an automatic Content-Length if they
+	// set a Transfer-Encoding, because they're generally incompatible.
+	if w.handlerDone && !trailers && !hasTE && bodyAllowedForStatus(w.status) && header.get("Content-Length") == "" && (!isHEAD || len(p) > 0) {
 		w.contentLength = int64(len(p))
 		setHeader.contentLength = strconv.AppendInt(cw.res.clenBuf[:0], int64(len(p)), 10)
 	}
@@ -789,21 +851,78 @@
 		w.closeAfterReply = true
 	}
 
+	// If the client wanted a 100-continue but we never sent it to
+	// them (or, more strictly: we never finished reading their
+	// request body), don't reuse this connection because it's now
+	// in an unknown state: we might be sending this response at
+	// the same time the client is now sending its request body
+	// after a timeout.  (Some HTTP clients send Expect:
+	// 100-continue but knowing that some servers don't support
+	// it, the clients set a timer and send the body later anyway)
+	// If we haven't seen EOF, we can't skip over the unread body
+	// because we don't know if the next bytes on the wire will be
+	// the body-following-the-timer or the subsequent request.
+	// See Issue 11549.
+	if ecr, ok := w.req.Body.(*expectContinueReader); ok && !ecr.sawEOF {
+		w.closeAfterReply = true
+	}
+
 	// Per RFC 2616, we should consume the request body before
 	// replying, if the handler hasn't already done so.  But we
 	// don't want to do an unbounded amount of reading here for
 	// DoS reasons, so we only try up to a threshold.
 	if w.req.ContentLength != 0 && !w.closeAfterReply {
-		ecr, isExpecter := w.req.Body.(*expectContinueReader)
-		if !isExpecter || ecr.resp.wroteContinue {
-			n, _ := io.CopyN(ioutil.Discard, w.req.Body, maxPostHandlerReadBytes+1)
-			if n >= maxPostHandlerReadBytes {
-				w.requestTooLarge()
-				delHeader("Connection")
-				setHeader.connection = "close"
-			} else {
-				w.req.Body.Close()
+		var discard, tooBig bool
+
+		switch bdy := w.req.Body.(type) {
+		case *expectContinueReader:
+			if bdy.resp.wroteContinue {
+				discard = true
 			}
+		case *body:
+			bdy.mu.Lock()
+			switch {
+			case bdy.closed:
+				if !bdy.sawEOF {
+					// Body was closed in handler with non-EOF error.
+					w.closeAfterReply = true
+				}
+			case bdy.unreadDataSizeLocked() >= maxPostHandlerReadBytes:
+				tooBig = true
+			default:
+				discard = true
+			}
+			bdy.mu.Unlock()
+		default:
+			discard = true
+		}
+
+		if discard {
+			_, err := io.CopyN(ioutil.Discard, w.req.Body, maxPostHandlerReadBytes+1)
+			switch err {
+			case nil:
+				// There must be even more data left over.
+				tooBig = true
+			case ErrBodyReadAfterClose:
+				// Body was already consumed and closed.
+			case io.EOF:
+				// The remaining body was just consumed, close it.
+				err = w.req.Body.Close()
+				if err != nil {
+					w.closeAfterReply = true
+				}
+			default:
+				// Some other kind of error occured, like a read timeout, or
+				// corrupt chunked encoding. In any case, whatever remains
+				// on the wire must not be parsed as another HTTP request.
+				w.closeAfterReply = true
+			}
+		}
+
+		if tooBig {
+			w.requestTooLarge()
+			delHeader("Connection")
+			setHeader.connection = "close"
 		}
 	}
 
@@ -811,7 +930,7 @@
 	if bodyAllowedForStatus(code) {
 		// If no content type, apply sniffing algorithm to body.
 		_, haveType := header["Content-Type"]
-		if !haveType {
+		if !haveType && !hasTE {
 			setHeader.contentType = DetectContentType(p)
 		}
 	} else {
@@ -824,8 +943,6 @@
 		setHeader.date = appendTime(cw.res.dateBuf[:0], time.Now())
 	}
 
-	te := header.get("Transfer-Encoding")
-	hasTE := te != ""
 	if hasCL && hasTE && te != "identity" {
 		// TODO: return an error if WriteHeader gets a return parameter
 		// For now just ignore the Content-Length.
@@ -885,6 +1002,24 @@
 	w.conn.buf.Write(crlf)
 }
 
+// foreachHeaderElement splits v according to the "#rule" construction
+// in RFC 2616 section 2.1 and calls fn for each non-empty element.
+func foreachHeaderElement(v string, fn func(string)) {
+	v = textproto.TrimString(v)
+	if v == "" {
+		return
+	}
+	if !strings.Contains(v, ",") {
+		fn(v)
+		return
+	}
+	for _, f := range strings.Split(v, ",") {
+		if f = textproto.TrimString(f); f != "" {
+			fn(f)
+		}
+	}
+}
+
 // statusLines is a cache of Status-Line strings, keyed by code (for
 // HTTP/1.1) or negative code (for HTTP/1.0). This is faster than a
 // map keyed by struct of two fields. This map's max size is bounded
@@ -930,7 +1065,7 @@
 	return line
 }
 
-// bodyAllowed returns true if a Write is allowed for this response type.
+// bodyAllowed reports whether a Write is allowed for this response type.
 // It's illegal to call this before the header has been flushed.
 func (w *response) bodyAllowed() bool {
 	if !w.wroteHeader {
@@ -1027,17 +1162,39 @@
 	if w.req.MultipartForm != nil {
 		w.req.MultipartForm.RemoveAll()
 	}
+}
+
+// shouldReuseConnection reports whether the underlying TCP connection can be reused.
+// It must only be called after the handler is done executing.
+func (w *response) shouldReuseConnection() bool {
+	if w.closeAfterReply {
+		// The request or something set while executing the
+		// handler indicated we shouldn't reuse this
+		// connection.
+		return false
+	}
 
 	if w.req.Method != "HEAD" && w.contentLength != -1 && w.bodyAllowed() && w.contentLength != w.written {
 		// Did not write enough. Avoid getting out of sync.
-		w.closeAfterReply = true
+		return false
 	}
 
 	// There was some error writing to the underlying connection
 	// during the request, so don't re-use this conn.
 	if w.conn.werr != nil {
-		w.closeAfterReply = true
+		return false
 	}
+
+	if w.closedRequestBodyEarly() {
+		return false
+	}
+
+	return true
+}
+
+func (w *response) closedRequestBodyEarly() bool {
+	body, ok := w.req.Body.(*body)
+	return ok && body.didEarlyClose()
 }
 
 func (w *response) Flush() {
@@ -1093,7 +1250,7 @@
 // pause for a bit, hoping the client processes it before any
 // subsequent RST.
 //
-// See http://golang.org/issue/3595
+// See https://golang.org/issue/3595
 func (c *conn) closeWriteAndWait() {
 	c.finalFlush()
 	if tcp, ok := c.rwc.(closeWriter); ok {
@@ -1206,8 +1363,8 @@
 			return
 		}
 		w.finishRequest()
-		if w.closeAfterReply {
-			if w.requestBodyLimitHit {
+		if !w.shouldReuseConnection() {
+			if w.requestBodyLimitHit || w.closedRequestBodyEarly() {
 				c.closeWriteAndWait()
 			}
 			break
@@ -1271,6 +1428,7 @@
 // The error message should be plain text.
 func Error(w ResponseWriter, error string, code int) {
 	w.Header().Set("Content-Type", "text/plain; charset=utf-8")
+	w.Header().Set("X-Content-Type-Options", "nosniff")
 	w.WriteHeader(code)
 	fmt.Fprintln(w, error)
 }
@@ -1576,7 +1734,8 @@
 			// strings.Index can't be -1.
 			path = pattern[strings.Index(pattern, "/"):]
 		}
-		mux.m[pattern[0:n-1]] = muxEntry{h: RedirectHandler(path, StatusMovedPermanently), pattern: pattern}
+		url := &url.URL{Path: path}
+		mux.m[pattern[0:n-1]] = muxEntry{h: RedirectHandler(url.String(), StatusMovedPermanently), pattern: pattern}
 	}
 }
 
@@ -1760,11 +1919,11 @@
 // By default, keep-alives are always enabled. Only very
 // resource-constrained environments or servers in the process of
 // shutting down should disable them.
-func (s *Server) SetKeepAlivesEnabled(v bool) {
+func (srv *Server) SetKeepAlivesEnabled(v bool) {
 	if v {
-		atomic.StoreInt32(&s.disableKeepAlives, 0)
+		atomic.StoreInt32(&srv.disableKeepAlives, 0)
 	} else {
-		atomic.StoreInt32(&s.disableKeepAlives, 1)
+		atomic.StoreInt32(&srv.disableKeepAlives, 1)
 	}
 }
 
@@ -1812,7 +1971,7 @@
 // expects HTTPS connections. Additionally, files containing a certificate and
 // matching private key for the server must be provided. If the certificate
 // is signed by a certificate authority, the certFile should be the concatenation
-// of the server's certificate followed by the CA's certificate.
+// of the server's certificate, any intermediates, and the CA's certificate.
 //
 // A trivial example server is:
 //
@@ -1844,10 +2003,11 @@
 // ListenAndServeTLS listens on the TCP network address srv.Addr and
 // then calls Serve to handle requests on incoming TLS connections.
 //
-// Filenames containing a certificate and matching private key for
-// the server must be provided. If the certificate is signed by a
-// certificate authority, the certFile should be the concatenation
-// of the server's certificate followed by the CA's certificate.
+// Filenames containing a certificate and matching private key for the
+// server must be provided if the Server's TLSConfig.Certificates is
+// not populated. If the certificate is signed by a certificate
+// authority, the certFile should be the concatenation of the server's
+// certificate, any intermediates, and the CA's certificate.
 //
 // If srv.Addr is blank, ":https" is used.
 func (srv *Server) ListenAndServeTLS(certFile, keyFile string) error {
@@ -1855,19 +2015,18 @@
 	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"}
 	}
 
-	var err error
-	config.Certificates = make([]tls.Certificate, 1)
-	config.Certificates[0], err = tls.LoadX509KeyPair(certFile, keyFile)
-	if err != nil {
-		return err
+	if len(config.Certificates) == 0 || certFile != "" || keyFile != "" {
+		var err error
+		config.Certificates = make([]tls.Certificate, 1)
+		config.Certificates[0], err = tls.LoadX509KeyPair(certFile, keyFile)
+		if err != nil {
+			return err
+		}
 	}
 
 	ln, err := net.Listen("tcp", addr)
@@ -2094,3 +2253,15 @@
 	}
 	return
 }
+
+func numLeadingCRorLF(v []byte) (n int) {
+	for _, b := range v {
+		if b == '\r' || b == '\n' {
+			n++
+			continue
+		}
+		break
+	}
+	return
+
+}
diff --git a/third_party/gofrontend/libgo/go/net/http/sniff.go b/third_party/gofrontend/libgo/go/net/http/sniff.go
index 68f519b..3be8c86 100644
--- a/third_party/gofrontend/libgo/go/net/http/sniff.go
+++ b/third_party/gofrontend/libgo/go/net/http/sniff.go
@@ -38,7 +38,11 @@
 }
 
 func isWS(b byte) bool {
-	return bytes.IndexByte([]byte("\t\n\x0C\r "), b) != -1
+	switch b {
+	case '\t', '\n', '\x0c', '\r', ' ':
+		return true
+	}
+	return false
 }
 
 type sniffSig interface {
@@ -161,6 +165,8 @@
 	return "text/html; charset=utf-8"
 }
 
+var mp4ftype = []byte("ftyp")
+
 type mp4Sig int
 
 func (mp4Sig) match(data []byte, firstNonWS int) string {
@@ -172,7 +178,7 @@
 	if boxSize%4 != 0 || len(data) < boxSize {
 		return ""
 	}
-	if !bytes.Equal(data[4:8], []byte("ftyp")) {
+	if !bytes.Equal(data[4:8], mp4ftype) {
 		return ""
 	}
 	for st := 8; st < boxSize; st += 4 {
diff --git a/third_party/gofrontend/libgo/go/net/http/transfer.go b/third_party/gofrontend/libgo/go/net/http/transfer.go
index 5205003..a8736b2 100644
--- a/third_party/gofrontend/libgo/go/net/http/transfer.go
+++ b/third_party/gofrontend/libgo/go/net/http/transfer.go
@@ -27,7 +27,7 @@
 	err error
 }
 
-func (r *errorReader) Read(p []byte) (n int, err error) {
+func (r errorReader) Read(p []byte) (n int, err error) {
 	return 0, r.err
 }
 
@@ -43,6 +43,7 @@
 	Close            bool
 	TransferEncoding []string
 	Trailer          Header
+	IsResponse       bool
 }
 
 func newTransferWriter(r interface{}) (t *transferWriter, err error) {
@@ -70,7 +71,7 @@
 				n, rerr := io.ReadFull(t.Body, buf[:])
 				if rerr != nil && rerr != io.EOF {
 					t.ContentLength = -1
-					t.Body = &errorReader{rerr}
+					t.Body = errorReader{rerr}
 				} else if n == 1 {
 					// Oh, guess there is data in this Body Reader after all.
 					// The ContentLength field just wasn't set.
@@ -89,6 +90,7 @@
 			}
 		}
 	case *Response:
+		t.IsResponse = true
 		if rr.Request != nil {
 			t.Method = rr.Request.Method
 		}
@@ -138,11 +140,17 @@
 	if t.ContentLength > 0 {
 		return true
 	}
+	if t.ContentLength < 0 {
+		return false
+	}
 	// Many servers expect a Content-Length for these methods
 	if t.Method == "POST" || t.Method == "PUT" {
 		return true
 	}
 	if t.ContentLength == 0 && isIdentity(t.TransferEncoding) {
+		if t.Method == "GET" || t.Method == "HEAD" {
+			return false
+		}
 		return true
 	}
 
@@ -203,6 +211,9 @@
 	// Write body
 	if t.Body != nil {
 		if chunked(t.TransferEncoding) {
+			if bw, ok := w.(*bufio.Writer); ok && !t.IsResponse {
+				w = &internal.FlushAfterChunkWriter{bw}
+			}
 			cw := internal.NewChunkedWriter(w)
 			_, err = io.Copy(cw, t.Body)
 			if err == nil {
@@ -232,7 +243,6 @@
 			t.ContentLength, ncopy)
 	}
 
-	// TODO(petar): Place trailer writer code here.
 	if chunked(t.TransferEncoding) {
 		// Write Trailer header
 		if t.Trailer != nil {
@@ -310,11 +320,13 @@
 		}
 	case *Request:
 		t.Header = rr.Header
+		t.RequestMethod = rr.Method
 		t.ProtoMajor = rr.ProtoMajor
 		t.ProtoMinor = rr.ProtoMinor
 		// Transfer semantics for Requests are exactly like those for
 		// Responses with status code 200, responding to a GET method
 		t.StatusCode = 200
+		t.Close = rr.Close
 	default:
 		panic("unexpected type")
 	}
@@ -325,7 +337,7 @@
 	}
 
 	// Transfer encoding, content length
-	t.TransferEncoding, err = fixTransferEncoding(t.RequestMethod, t.Header)
+	t.TransferEncoding, err = fixTransferEncoding(isResponse, t.RequestMethod, t.Header)
 	if err != nil {
 		return err
 	}
@@ -413,12 +425,11 @@
 func isIdentity(te []string) bool { return len(te) == 1 && te[0] == "identity" }
 
 // Sanitize transfer encoding
-func fixTransferEncoding(requestMethod string, header Header) ([]string, error) {
+func fixTransferEncoding(isResponse bool, requestMethod string, header Header) ([]string, error) {
 	raw, present := header["Transfer-Encoding"]
 	if !present {
 		return nil, nil
 	}
-
 	delete(header, "Transfer-Encoding")
 
 	encodings := strings.Split(raw[0], ",")
@@ -443,9 +454,22 @@
 		return nil, &badStringError{"too many transfer encodings", strings.Join(te, ",")}
 	}
 	if len(te) > 0 {
-		// Chunked encoding trumps Content-Length. See RFC 2616
-		// Section 4.4. Currently len(te) > 0 implies chunked
-		// encoding.
+		// RFC 7230 3.3.2 says "A sender MUST NOT send a
+		// Content-Length header field in any message that
+		// contains a Transfer-Encoding header field."
+		//
+		// but also:
+		// "If a message is received with both a
+		// Transfer-Encoding and a Content-Length header
+		// field, the Transfer-Encoding overrides the
+		// Content-Length. Such a message might indicate an
+		// attempt to perform request smuggling (Section 9.5)
+		// or response splitting (Section 9.4) and ought to be
+		// handled as an error. A sender MUST remove the
+		// received Content-Length field prior to forwarding
+		// such a message downstream."
+		//
+		// Reportedly, these appear in the wild.
 		delete(header, "Content-Length")
 		return te, nil
 	}
@@ -457,9 +481,17 @@
 // function is not a method, because ultimately it should be shared by
 // ReadResponse and ReadRequest.
 func fixLength(isResponse bool, status int, requestMethod string, header Header, te []string) (int64, error) {
-
+	contentLens := header["Content-Length"]
+	isRequest := !isResponse
 	// Logic based on response type or status
 	if noBodyExpected(requestMethod) {
+		// For HTTP requests, as part of hardening against request
+		// smuggling (RFC 7230), don't allow a Content-Length header for
+		// methods which don't permit bodies. As an exception, allow
+		// exactly one Content-Length header if its value is "0".
+		if isRequest && len(contentLens) > 0 && !(len(contentLens) == 1 && contentLens[0] == "0") {
+			return 0, fmt.Errorf("http: method cannot contain a Content-Length; got %q", contentLens)
+		}
 		return 0, nil
 	}
 	if status/100 == 1 {
@@ -470,13 +502,21 @@
 		return 0, nil
 	}
 
+	if len(contentLens) > 1 {
+		// harden against HTTP request smuggling. See RFC 7230.
+		return 0, errors.New("http: message cannot contain multiple Content-Length headers")
+	}
+
 	// Logic based on Transfer-Encoding
 	if chunked(te) {
 		return -1, nil
 	}
 
 	// Logic based on Content-Length
-	cl := strings.TrimSpace(header.get("Content-Length"))
+	var cl string
+	if len(contentLens) == 1 {
+		cl = strings.TrimSpace(contentLens[0])
+	}
 	if cl != "" {
 		n, err := parseContentLength(cl)
 		if err != nil {
@@ -487,11 +527,14 @@
 		header.Del("Content-Length")
 	}
 
-	if !isResponse && requestMethod == "GET" {
-		// RFC 2616 doesn't explicitly permit nor forbid an
+	if !isResponse {
+		// RFC 2616 neither explicitly permits nor forbids an
 		// entity-body on a GET request so we permit one if
 		// declared, but we default to 0 here (not -1 below)
 		// if there's no mention of a body.
+		// Likewise, all other request methods are assumed to have
+		// no body if neither Transfer-Encoding chunked nor a
+		// Content-Length are set.
 		return 0, nil
 	}
 
@@ -506,14 +549,13 @@
 	if major < 1 {
 		return true
 	} else if major == 1 && minor == 0 {
-		if !strings.Contains(strings.ToLower(header.get("Connection")), "keep-alive") {
+		vv := header["Connection"]
+		if headerValuesContainsToken(vv, "close") || !headerValuesContainsToken(vv, "keep-alive") {
 			return true
 		}
 		return false
 	} else {
-		// TODO: Should split on commas, toss surrounding white space,
-		// and check each field.
-		if strings.ToLower(header.get("Connection")) == "close" {
+		if headerValuesContainsToken(header["Connection"], "close") {
 			if removeCloseHeader {
 				header.Del("Connection")
 			}
@@ -555,13 +597,16 @@
 // Close ensures that the body has been fully read
 // and then reads the trailer if necessary.
 type body struct {
-	src     io.Reader
-	hdr     interface{}   // non-nil (Response or Request) value means read trailer
-	r       *bufio.Reader // underlying wire-format reader for the trailer
-	closing bool          // is the connection to be closed after reading body?
+	src          io.Reader
+	hdr          interface{}   // non-nil (Response or Request) value means read trailer
+	r            *bufio.Reader // underlying wire-format reader for the trailer
+	closing      bool          // is the connection to be closed after reading body?
+	doEarlyClose bool          // whether Close should stop early
 
-	mu     sync.Mutex // guards closed, and calls to Read and Close
-	closed bool
+	mu         sync.Mutex // guards closed, and calls to Read and Close
+	sawEOF     bool
+	closed     bool
+	earlyClose bool // Close called and we didn't read to the end of src
 }
 
 // ErrBodyReadAfterClose is returned when reading a Request or Response
@@ -581,13 +626,23 @@
 
 // Must hold b.mu.
 func (b *body) readLocked(p []byte) (n int, err error) {
+	if b.sawEOF {
+		return 0, io.EOF
+	}
 	n, err = b.src.Read(p)
 
 	if err == io.EOF {
+		b.sawEOF = true
 		// Chunked case. Read the trailer.
 		if b.hdr != nil {
 			if e := b.readTrailer(); e != nil {
 				err = e
+				// Something went wrong in the trailer, we must not allow any
+				// further reads of any kind to succeed from body, nor any
+				// subsequent requests on the server connection. See
+				// golang.org/issue/12027
+				b.sawEOF = false
+				b.closed = true
 			}
 			b.hdr = nil
 		} else {
@@ -607,6 +662,7 @@
 	if err == nil && n > 0 {
 		if lr, ok := b.src.(*io.LimitedReader); ok && lr.N == 0 {
 			err = io.EOF
+			b.sawEOF = true
 		}
 	}
 
@@ -639,8 +695,7 @@
 	// The common case, since nobody uses trailers.
 	buf, err := b.r.Peek(2)
 	if bytes.Equal(buf, singleCRLF) {
-		b.r.ReadByte()
-		b.r.ReadByte()
+		b.r.Discard(2)
 		return nil
 	}
 	if len(buf) < 2 {
@@ -688,6 +743,16 @@
 	}
 }
 
+// unreadDataSizeLocked returns the number of bytes of unread input.
+// It returns -1 if unknown.
+// b.mu must be held.
+func (b *body) unreadDataSizeLocked() int64 {
+	if lr, ok := b.src.(*io.LimitedReader); ok {
+		return lr.N
+	}
+	return -1
+}
+
 func (b *body) Close() error {
 	b.mu.Lock()
 	defer b.mu.Unlock()
@@ -696,9 +761,30 @@
 	}
 	var err error
 	switch {
+	case b.sawEOF:
+		// Already saw EOF, so no need going to look for it.
 	case b.hdr == nil && b.closing:
 		// no trailer and closing the connection next.
 		// no point in reading to EOF.
+	case b.doEarlyClose:
+		// Read up to maxPostHandlerReadBytes bytes of the body, looking for
+		// for EOF (and trailers), so we can re-use this connection.
+		if lr, ok := b.src.(*io.LimitedReader); ok && lr.N > maxPostHandlerReadBytes {
+			// There was a declared Content-Length, and we have more bytes remaining
+			// than our maxPostHandlerReadBytes tolerance. So, give up.
+			b.earlyClose = true
+		} else {
+			var n int64
+			// Consume the body, or, which will also lead to us reading
+			// the trailer headers after the body, if present.
+			n, err = io.CopyN(ioutil.Discard, bodyLocked{b}, maxPostHandlerReadBytes)
+			if err == io.EOF {
+				err = nil
+			}
+			if n == maxPostHandlerReadBytes {
+				b.earlyClose = true
+			}
+		}
 	default:
 		// Fully consume the body, which will also lead to us reading
 		// the trailer headers after the body, if present.
@@ -708,6 +794,12 @@
 	return err
 }
 
+func (b *body) didEarlyClose() bool {
+	b.mu.Lock()
+	defer b.mu.Unlock()
+	return b.earlyClose
+}
+
 // bodyLocked is a io.Reader reading from a *body when its mutex is
 // already held.
 type bodyLocked struct {
diff --git a/third_party/gofrontend/libgo/go/net/http/transport.go b/third_party/gofrontend/libgo/go/net/http/transport.go
index 782f7cd..70d1864 100644
--- a/third_party/gofrontend/libgo/go/net/http/transport.go
+++ b/third_party/gofrontend/libgo/go/net/http/transport.go
@@ -274,11 +274,12 @@
 	}
 }
 
-// CancelRequest cancels an in-flight request by closing its
-// connection.
+// CancelRequest cancels an in-flight request by closing its connection.
+// CancelRequest should only be called after RoundTrip has returned.
 func (t *Transport) CancelRequest(req *Request) {
 	t.reqMu.Lock()
 	cancel := t.reqCanceler[req]
+	delete(t.reqCanceler, req)
 	t.reqMu.Unlock()
 	if cancel != nil {
 		cancel()
@@ -474,6 +475,25 @@
 	}
 }
 
+// replaceReqCanceler replaces an existing cancel function. If there is no cancel function
+// for the request, we don't set the function and return false.
+// Since CancelRequest will clear the canceler, we can use the return value to detect if
+// the request was canceled since the last setReqCancel call.
+func (t *Transport) replaceReqCanceler(r *Request, fn func()) bool {
+	t.reqMu.Lock()
+	defer t.reqMu.Unlock()
+	_, ok := t.reqCanceler[r]
+	if !ok {
+		return false
+	}
+	if fn != nil {
+		t.reqCanceler[r] = fn
+	} else {
+		delete(t.reqCanceler, r)
+	}
+	return true
+}
+
 func (t *Transport) dial(network, addr string) (c net.Conn, err error) {
 	if t.Dial != nil {
 		return t.Dial(network, addr)
@@ -490,6 +510,10 @@
 // is ready to write requests to.
 func (t *Transport) getConn(req *Request, cm connectMethod) (*persistConn, error) {
 	if pc := t.getIdleConn(cm); pc != nil {
+		// set request canceler to some non-nil function so we
+		// can detect whether it was cleared between now and when
+		// we enter roundTrip
+		t.setReqCanceler(req, func() {})
 		return pc, nil
 	}
 
@@ -499,6 +523,11 @@
 	}
 	dialc := make(chan dialRes)
 
+	// Copy these hooks so we don't race on the postPendingDial in
+	// the goroutine we launch. Issue 11136.
+	prePendingDial := prePendingDial
+	postPendingDial := postPendingDial
+
 	handlePendingDial := func() {
 		if prePendingDial != nil {
 			prePendingDial()
@@ -534,6 +563,9 @@
 		// when it finishes:
 		handlePendingDial()
 		return pc, nil
+	case <-req.Cancel:
+		handlePendingDial()
+		return nil, errors.New("net/http: request canceled while waiting for connection")
 	case <-cancelc:
 		handlePendingDial()
 		return nil, errors.New("net/http: request canceled while waiting for connection")
@@ -613,16 +645,9 @@
 
 	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)
@@ -662,7 +687,7 @@
 	return pconn, nil
 }
 
-// useProxy returns true if requests to addr should use a proxy,
+// useProxy reports whether requests to addr should use a proxy,
 // according to the NO_PROXY or no_proxy environment variable.
 // addr is always a canonicalAddr with a host and port.
 func useProxy(addr string) bool {
@@ -805,6 +830,7 @@
 	numExpectedResponses int
 	closed               bool // whether conn has been closed
 	broken               bool // an error has happened on this connection; marked broken so it's not reused.
+	canceled             bool // whether this conn was broken due a CancelRequest
 	// mutateHeaderFunc is an optional func to modify extra
 	// headers on each outbound request before it's written. (the
 	// original Request given to RoundTrip is not modified)
@@ -819,25 +845,33 @@
 	return b
 }
 
-func (pc *persistConn) cancelRequest() {
-	pc.conn.Close()
+// isCanceled reports whether this connection was closed due to CancelRequest.
+func (pc *persistConn) isCanceled() bool {
+	pc.lk.Lock()
+	defer pc.lk.Unlock()
+	return pc.canceled
 }
 
-var remoteSideClosedFunc func(error) bool // or nil to use default
-
-func remoteSideClosed(err error) bool {
-	if err == io.EOF {
-		return true
-	}
-	if remoteSideClosedFunc != nil {
-		return remoteSideClosedFunc(err)
-	}
-	return false
+func (pc *persistConn) cancelRequest() {
+	pc.lk.Lock()
+	defer pc.lk.Unlock()
+	pc.canceled = true
+	pc.closeLocked()
 }
 
 func (pc *persistConn) readLoop() {
-	alive := true
+	// eofc is used to block http.Handler goroutines reading from Response.Body
+	// at EOF until this goroutines has (potentially) added the connection
+	// back to the idle pool.
+	eofc := make(chan struct{})
+	defer close(eofc) // unblock reader on errors
 
+	// Read this once, before loop starts. (to avoid races in tests)
+	testHookMu.Lock()
+	testHookReadLoopBeforeNextRead := testHookReadLoopBeforeNextRead
+	testHookMu.Unlock()
+
+	alive := true
 	for alive {
 		pb, err := pc.br.Peek(1)
 
@@ -895,49 +929,79 @@
 			alive = false
 		}
 
-		var waitForBodyRead chan bool
+		var waitForBodyRead chan bool // channel is nil when there's no body
 		if hasBody {
 			waitForBodyRead = make(chan bool, 2)
 			resp.Body.(*bodyEOFSignal).earlyCloseFn = func() error {
-				// Sending false here sets alive to
-				// false and closes the connection
-				// below.
 				waitForBodyRead <- false
 				return nil
 			}
-			resp.Body.(*bodyEOFSignal).fn = func(err error) {
-				waitForBodyRead <- alive &&
-					err == nil &&
+			resp.Body.(*bodyEOFSignal).fn = func(err error) error {
+				isEOF := err == io.EOF
+				waitForBodyRead <- isEOF
+				if isEOF {
+					<-eofc // see comment at top
+				} else if err != nil && pc.isCanceled() {
+					return errRequestCanceled
+				}
+				return err
+			}
+		} else {
+			// Before send on rc.ch, as client might re-use the
+			// same *Request pointer, and we don't want to set this
+			// on t from this persistConn while the Transport
+			// potentially spins up a different persistConn for the
+			// caller's subsequent request.
+			pc.t.setReqCanceler(rc.req, nil)
+		}
+
+		pc.lk.Lock()
+		pc.numExpectedResponses--
+		pc.lk.Unlock()
+
+		// The connection might be going away when we put the
+		// idleConn below. When that happens, we close the response channel to signal
+		// to roundTrip that the connection is gone. roundTrip waits for
+		// both closing and a response in a select, so it might choose
+		// the close channel, rather than the response.
+		// We send the response first so that roundTrip can check
+		// if there is a pending one with a non-blocking select
+		// on the response channel before erroring out.
+		rc.ch <- responseAndError{resp, err}
+
+		if hasBody {
+			// To avoid a race, wait for the just-returned
+			// response body to be fully consumed before peek on
+			// the underlying bufio reader.
+			select {
+			case <-rc.req.Cancel:
+				alive = false
+				pc.t.CancelRequest(rc.req)
+			case bodyEOF := <-waitForBodyRead:
+				pc.t.setReqCanceler(rc.req, nil) // before pc might return to idle pool
+				alive = alive &&
+					bodyEOF &&
 					!pc.sawEOF &&
 					pc.wroteRequest() &&
 					pc.t.putIdleConn(pc)
+				if bodyEOF {
+					eofc <- struct{}{}
+				}
+			case <-pc.closech:
+				alive = false
 			}
-		}
-
-		if alive && !hasBody {
-			alive = !pc.sawEOF &&
+		} else {
+			alive = alive &&
+				!pc.sawEOF &&
 				pc.wroteRequest() &&
 				pc.t.putIdleConn(pc)
 		}
 
-		rc.ch <- responseAndError{resp, err}
-
-		// Wait for the just-returned response body to be fully consumed
-		// before we race and peek on the underlying bufio reader.
-		if waitForBodyRead != nil {
-			select {
-			case alive = <-waitForBodyRead:
-			case <-pc.closech:
-				alive = false
-			}
-		}
-
-		pc.t.setReqCanceler(rc.req, nil)
-
-		if !alive {
-			pc.close()
+		if hook := testHookReadLoopBeforeNextRead; hook != nil {
+			hook()
 		}
 	}
+	pc.close()
 }
 
 func (pc *persistConn) writeLoop() {
@@ -1027,9 +1091,24 @@
 
 var errTimeout error = &httpError{err: "net/http: timeout awaiting response headers", timeout: true}
 var errClosed error = &httpError{err: "net/http: transport closed before response was received"}
+var errRequestCanceled = errors.New("net/http: request canceled")
+
+// nil except for tests
+var (
+	testHookPersistConnClosedGotRes func()
+	testHookEnterRoundTrip          func()
+	testHookMu                      sync.Locker = fakeLocker{} // guards following
+	testHookReadLoopBeforeNextRead  func()
+)
 
 func (pc *persistConn) roundTrip(req *transportRequest) (resp *Response, err error) {
-	pc.t.setReqCanceler(req.Request, pc.cancelRequest)
+	if hook := testHookEnterRoundTrip; hook != nil {
+		hook()
+	}
+	if !pc.t.replaceReqCanceler(req.Request, pc.cancelRequest) {
+		pc.t.putIdleConn(pc)
+		return nil, errRequestCanceled
+	}
 	pc.lk.Lock()
 	pc.numExpectedResponses++
 	headerFn := pc.mutateHeaderFunc
@@ -1055,15 +1134,19 @@
 		// Note that we don't request this for HEAD requests,
 		// due to a bug in nginx:
 		//   http://trac.nginx.org/nginx/ticket/358
-		//   http://golang.org/issue/5522
+		//   https://golang.org/issue/5522
 		//
 		// We don't request gzip if the request is for a range, since
 		// auto-decoding a portion of a gzipped document will just fail
-		// anyway. See http://golang.org/issue/8923
+		// anyway. See https://golang.org/issue/8923
 		requestedGzip = true
 		req.extraHeaders().Set("Accept-Encoding", "gzip")
 	}
 
+	if pc.t.DisableKeepAlives {
+		req.extraHeaders().Set("Connection", "close")
+	}
+
 	// Write the request concurrently with waiting for a response,
 	// in case the server decides to reply before reading our full
 	// request body.
@@ -1074,38 +1157,57 @@
 	pc.reqch <- requestAndChan{req.Request, resc, requestedGzip}
 
 	var re responseAndError
-	var pconnDeadCh = pc.closech
-	var failTicker <-chan time.Time
 	var respHeaderTimer <-chan time.Time
+	cancelChan := req.Request.Cancel
 WaitResponse:
 	for {
 		select {
 		case err := <-writeErrCh:
+			if isNetWriteError(err) {
+				// Issue 11745. If we failed to write the request
+				// body, it's possible the server just heard enough
+				// and already wrote to us. Prioritize the server's
+				// response over returning a body write error.
+				select {
+				case re = <-resc:
+					pc.close()
+					break WaitResponse
+				case <-time.After(50 * time.Millisecond):
+					// Fall through.
+				}
+			}
 			if err != nil {
 				re = responseAndError{nil, err}
 				pc.close()
 				break WaitResponse
 			}
 			if d := pc.t.ResponseHeaderTimeout; d > 0 {
-				respHeaderTimer = time.After(d)
+				timer := time.NewTimer(d)
+				defer timer.Stop() // prevent leaks
+				respHeaderTimer = timer.C
 			}
-		case <-pconnDeadCh:
+		case <-pc.closech:
 			// The persist connection is dead. This shouldn't
 			// usually happen (only with Connection: close responses
 			// with no response bodies), but if it does happen it
 			// means either a) the remote server hung up on us
 			// prematurely, or b) the readLoop sent us a response &
 			// closed its closech at roughly the same time, and we
-			// selected this case first, in which case a response
-			// might still be coming soon.
-			//
-			// We can't avoid the select race in b) by using a unbuffered
-			// resc channel instead, because then goroutines can
-			// leak if we exit due to other errors.
-			pconnDeadCh = nil                               // avoid spinning
-			failTicker = time.After(100 * time.Millisecond) // arbitrary time to wait for resc
-		case <-failTicker:
-			re = responseAndError{err: errClosed}
+			// selected this case first. If we got a response, readLoop makes sure
+			// to send it before it puts the conn and closes the channel.
+			// That way, we can fetch the response, if there is one,
+			// with a non-blocking receive.
+			select {
+			case re = <-resc:
+				if fn := testHookPersistConnClosedGotRes; fn != nil {
+					fn()
+				}
+			default:
+				re = responseAndError{err: errClosed}
+				if pc.isCanceled() {
+					re = responseAndError{err: errRequestCanceled}
+				}
+			}
 			break WaitResponse
 		case <-respHeaderTimer:
 			pc.close()
@@ -1113,13 +1215,12 @@
 			break WaitResponse
 		case re = <-resc:
 			break WaitResponse
+		case <-cancelChan:
+			pc.t.CancelRequest(req.Request)
+			cancelChan = nil
 		}
 	}
 
-	pc.lk.Lock()
-	pc.numExpectedResponses--
-	pc.lk.Unlock()
-
 	if re.err != nil {
 		pc.t.setReqCanceler(req.Request, nil)
 	}
@@ -1167,16 +1268,18 @@
 
 // bodyEOFSignal wraps a ReadCloser but runs fn (if non-nil) at most
 // once, right before its final (error-producing) Read or Close call
-// returns. If earlyCloseFn is non-nil and Close is called before
-// io.EOF is seen, earlyCloseFn is called instead of fn, and its
-// return value is the return value from Close.
+// returns. fn should return the new error to return from Read or Close.
+//
+// If earlyCloseFn is non-nil and Close is called before io.EOF is
+// seen, earlyCloseFn is called instead of fn, and its return value is
+// the return value from Close.
 type bodyEOFSignal struct {
 	body         io.ReadCloser
-	mu           sync.Mutex   // guards following 4 fields
-	closed       bool         // whether Close has been called
-	rerr         error        // sticky Read error
-	fn           func(error)  // error will be nil on Read io.EOF
-	earlyCloseFn func() error // optional alt Close func used if io.EOF not seen
+	mu           sync.Mutex        // guards following 4 fields
+	closed       bool              // whether Close has been called
+	rerr         error             // sticky Read error
+	fn           func(error) error // err will be nil on Read io.EOF
+	earlyCloseFn func() error      // optional alt Close func used if io.EOF not seen
 }
 
 func (es *bodyEOFSignal) Read(p []byte) (n int, err error) {
@@ -1197,7 +1300,7 @@
 		if es.rerr == nil {
 			es.rerr = err
 		}
-		es.condfn(err)
+		err = es.condfn(err)
 	}
 	return
 }
@@ -1213,20 +1316,17 @@
 		return es.earlyCloseFn()
 	}
 	err := es.body.Close()
-	es.condfn(err)
-	return err
+	return es.condfn(err)
 }
 
 // caller must hold es.mu.
-func (es *bodyEOFSignal) condfn(err error) {
+func (es *bodyEOFSignal) condfn(err error) error {
 	if es.fn == nil {
-		return
+		return err
 	}
-	if err == io.EOF {
-		err = nil
-	}
-	es.fn(err)
+	err = es.fn(err)
 	es.fn = nil
+	return err
 }
 
 // gzipReader wraps a response body so it can lazily
@@ -1273,3 +1373,89 @@
 	}
 	return
 }
+
+// fakeLocker is a sync.Locker which does nothing. It's used to guard
+// test-only fields when not under test, to avoid runtime atomic
+// overhead.
+type fakeLocker struct{}
+
+func (fakeLocker) Lock()   {}
+func (fakeLocker) Unlock() {}
+
+func isNetWriteError(err error) bool {
+	switch e := err.(type) {
+	case *url.Error:
+		return isNetWriteError(e.Err)
+	case *net.OpError:
+		return e.Op == "write"
+	default:
+		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/third_party/gofrontend/libgo/go/net/http/transport_test.go b/third_party/gofrontend/libgo/go/net/http/transport_test.go
index defa633..c21d4af 100644
--- a/third_party/gofrontend/libgo/go/net/http/transport_test.go
+++ b/third_party/gofrontend/libgo/go/net/http/transport_test.go
@@ -18,11 +18,11 @@
 	"io/ioutil"
 	"log"
 	"net"
-	"net/http"
 	. "net/http"
 	"net/http/httptest"
 	"net/url"
 	"os"
+	"reflect"
 	"runtime"
 	"strconv"
 	"strings"
@@ -39,6 +39,7 @@
 	if r.FormValue("close") == "true" {
 		w.Header().Set("Connection", "close")
 	}
+	w.Header().Set("X-Saw-Close", fmt.Sprint(r.Close))
 	w.Write([]byte(r.RemoteAddr))
 })
 
@@ -228,6 +229,10 @@
 			if err != nil {
 				t.Fatalf("error in connectionClose=%v, req #%d, Do: %v", connectionClose, n, err)
 			}
+			if got, want := res.Header.Get("X-Saw-Close"), fmt.Sprint(connectionClose); got != want {
+				t.Errorf("For connectionClose = %v; handler's X-Saw-Close was %v; want %v",
+					connectionClose, got, !connectionClose)
+			}
 			body, err := ioutil.ReadAll(res.Body)
 			if err != nil {
 				t.Fatalf("error in connectionClose=%v, req #%d, ReadAll: %v", connectionClose, n, err)
@@ -249,6 +254,27 @@
 	connSet.check(t)
 }
 
+// if the Transport's DisableKeepAlives is set, all requests should
+// send Connection: close.
+func TestTransportConnectionCloseOnRequestDisableKeepAlive(t *testing.T) {
+	defer afterTest(t)
+	ts := httptest.NewServer(hostPortHandler)
+	defer ts.Close()
+
+	tr := &Transport{
+		DisableKeepAlives: true,
+	}
+	c := &Client{Transport: tr}
+	res, err := c.Get(ts.URL)
+	if err != nil {
+		t.Fatal(err)
+	}
+	res.Body.Close()
+	if res.Header.Get("X-Saw-Close") != "true" {
+		t.Errorf("handler didn't see Connection: close ")
+	}
+}
+
 func TestTransportIdleCacheKeys(t *testing.T) {
 	defer afterTest(t)
 	ts := httptest.NewServer(hostPortHandler)
@@ -293,7 +319,7 @@
 		addrSeen[r.RemoteAddr]++
 		if r.URL.Path == "/chunked/" {
 			w.WriteHeader(200)
-			w.(http.Flusher).Flush()
+			w.(Flusher).Flush()
 		} else {
 			w.Header().Set("Content-Type", strconv.Itoa(len(msg)))
 			w.WriteHeader(200)
@@ -308,7 +334,7 @@
 		wantLen := []int{len(msg), -1}[pi]
 		addrSeen = make(map[string]int)
 		for i := 0; i < 3; i++ {
-			res, err := http.Get(ts.URL + path)
+			res, err := Get(ts.URL + path)
 			if err != nil {
 				t.Errorf("Get %s: %v", path, err)
 				continue
@@ -459,7 +485,7 @@
 	}
 }
 
-// Test for http://golang.org/issue/2616 (appropriate issue number)
+// Test for https://golang.org/issue/2616 (appropriate issue number)
 // This fails pretty reliably with GOMAXPROCS=100 or something high.
 func TestStressSurpriseServerCloses(t *testing.T) {
 	defer afterTest(t)
@@ -479,12 +505,17 @@
 
 	tr := &Transport{DisableKeepAlives: false}
 	c := &Client{Transport: tr}
+	defer tr.CloseIdleConnections()
 
 	// Do a bunch of traffic from different goroutines. Send to activityc
 	// after each request completes, regardless of whether it failed.
+	// If these are too high, OS X exhausts its ephemeral ports
+	// and hangs waiting for them to transition TCP states. That's
+	// not what we want to test.  TODO(bradfitz): use an io.Pipe
+	// dialer for this test instead?
 	const (
-		numClients    = 50
-		reqsPerClient = 250
+		numClients    = 20
+		reqsPerClient = 25
 	)
 	activityc := make(chan bool)
 	for i := 0; i < numClients; i++ {
@@ -567,11 +598,22 @@
 	tr := &Transport{DisableKeepAlives: false}
 	c := &Client{Transport: tr}
 
+	// Ensure that we wait for the readLoop to complete before
+	// calling Head again
+	didRead := make(chan bool)
+	SetReadLoopBeforeNextReadHook(func() { didRead <- true })
+	defer SetReadLoopBeforeNextReadHook(nil)
+
 	res1, err := c.Head(ts.URL)
+	<-didRead
+
 	if err != nil {
 		t.Fatalf("request 1 error: %v", err)
 	}
+
 	res2, err := c.Head(ts.URL)
+	<-didRead
+
 	if err != nil {
 		t.Fatalf("request 2 error: %v", err)
 	}
@@ -833,7 +875,7 @@
 // tests that persistent goroutine connections shut down when no longer desired.
 func TestTransportPersistConnLeak(t *testing.T) {
 	if runtime.GOOS == "plan9" {
-		t.Skip("skipping test; see http://golang.org/issue/7237")
+		t.Skip("skipping test; see https://golang.org/issue/7237")
 	}
 	defer afterTest(t)
 	gotReqCh := make(chan bool)
@@ -902,7 +944,7 @@
 // request.ContentLength is explicitly short
 func TestTransportPersistConnLeakShortBody(t *testing.T) {
 	if runtime.GOOS == "plan9" {
-		t.Skip("skipping test; see http://golang.org/issue/7237")
+		t.Skip("skipping test; see https://golang.org/issue/7237")
 	}
 	defer afterTest(t)
 	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
@@ -941,7 +983,7 @@
 	}
 }
 
-// This used to crash; http://golang.org/issue/3266
+// This used to crash; https://golang.org/issue/3266
 func TestTransportIdleConnCrash(t *testing.T) {
 	defer afterTest(t)
 	tr := &Transport{}
@@ -1023,7 +1065,7 @@
 	}
 }
 
-// From http://golang.org/issue/4454 ,
+// From https://golang.org/issue/4454 ,
 // "client fails to handle requests with no body and chunked encoding"
 func TestChunkedNoContent(t *testing.T) {
 	defer afterTest(t)
@@ -1110,7 +1152,7 @@
 
 func TestIssue4191_InfiniteGetTimeout(t *testing.T) {
 	if runtime.GOOS == "plan9" {
-		t.Skip("skipping test; see http://golang.org/issue/7237")
+		t.Skip("skipping test; see https://golang.org/issue/7237")
 	}
 	defer afterTest(t)
 	const debug = false
@@ -1174,7 +1216,7 @@
 
 func TestIssue4191_InfiniteGetToPutTimeout(t *testing.T) {
 	if runtime.GOOS == "plan9" {
-		t.Skip("skipping test; see http://golang.org/issue/7237")
+		t.Skip("skipping test; see https://golang.org/issue/7237")
 	}
 	defer afterTest(t)
 	const debug = false
@@ -1345,8 +1387,8 @@
 	body, err := ioutil.ReadAll(res.Body)
 	d := time.Since(t0)
 
-	if err == nil {
-		t.Error("expected an error reading the body")
+	if err != ExportErrRequestCanceled {
+		t.Errorf("Body.Read error = %v; want errRequestCanceled", err)
 	}
 	if string(body) != "Hello" {
 		t.Errorf("Body = %q; want Hello", body)
@@ -1356,7 +1398,7 @@
 	}
 	// Verify no outstanding requests after readLoop/writeLoop
 	// goroutines shut down.
-	for tries := 3; tries > 0; tries-- {
+	for tries := 5; tries > 0; tries-- {
 		n := tr.NumPendingRequestsForTesting()
 		if n == 0 {
 			break
@@ -1405,6 +1447,7 @@
 
 	eventLog.Printf("canceling")
 	tr.CancelRequest(req)
+	tr.CancelRequest(req) // used to panic on second call
 
 	select {
 	case <-gotres:
@@ -1422,6 +1465,135 @@
 	}
 }
 
+func TestCancelRequestWithChannel(t *testing.T) {
+	defer afterTest(t)
+	if testing.Short() {
+		t.Skip("skipping test in -short mode")
+	}
+	unblockc := make(chan bool)
+	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
+		fmt.Fprintf(w, "Hello")
+		w.(Flusher).Flush() // send headers and some body
+		<-unblockc
+	}))
+	defer ts.Close()
+	defer close(unblockc)
+
+	tr := &Transport{}
+	defer tr.CloseIdleConnections()
+	c := &Client{Transport: tr}
+
+	req, _ := NewRequest("GET", ts.URL, nil)
+	ch := make(chan struct{})
+	req.Cancel = ch
+
+	res, err := c.Do(req)
+	if err != nil {
+		t.Fatal(err)
+	}
+	go func() {
+		time.Sleep(1 * time.Second)
+		close(ch)
+	}()
+	t0 := time.Now()
+	body, err := ioutil.ReadAll(res.Body)
+	d := time.Since(t0)
+
+	if err != ExportErrRequestCanceled {
+		t.Errorf("Body.Read error = %v; want errRequestCanceled", err)
+	}
+	if string(body) != "Hello" {
+		t.Errorf("Body = %q; want Hello", body)
+	}
+	if d < 500*time.Millisecond {
+		t.Errorf("expected ~1 second delay; got %v", d)
+	}
+	// Verify no outstanding requests after readLoop/writeLoop
+	// goroutines shut down.
+	for tries := 5; tries > 0; tries-- {
+		n := tr.NumPendingRequestsForTesting()
+		if n == 0 {
+			break
+		}
+		time.Sleep(100 * time.Millisecond)
+		if tries == 1 {
+			t.Errorf("pending requests = %d; want 0", n)
+		}
+	}
+}
+
+func TestCancelRequestWithChannelBeforeDo(t *testing.T) {
+	defer afterTest(t)
+	unblockc := make(chan bool)
+	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
+		<-unblockc
+	}))
+	defer ts.Close()
+	defer close(unblockc)
+
+	// Don't interfere with the next test on plan9.
+	// Cf. https://golang.org/issues/11476
+	if runtime.GOOS == "plan9" {
+		defer time.Sleep(500 * time.Millisecond)
+	}
+
+	tr := &Transport{}
+	defer tr.CloseIdleConnections()
+	c := &Client{Transport: tr}
+
+	req, _ := NewRequest("GET", ts.URL, nil)
+	ch := make(chan struct{})
+	req.Cancel = ch
+	close(ch)
+
+	_, err := c.Do(req)
+	if err == nil || !strings.Contains(err.Error(), "canceled") {
+		t.Errorf("Do error = %v; want cancelation", err)
+	}
+}
+
+// Issue 11020. The returned error message should be errRequestCanceled
+func TestTransportCancelBeforeResponseHeaders(t *testing.T) {
+	t.Skip("Skipping flaky test; see Issue 11894")
+	defer afterTest(t)
+
+	serverConnCh := make(chan net.Conn, 1)
+	tr := &Transport{
+		Dial: func(network, addr string) (net.Conn, error) {
+			cc, sc := net.Pipe()
+			serverConnCh <- sc
+			return cc, nil
+		},
+	}
+	defer tr.CloseIdleConnections()
+	errc := make(chan error, 1)
+	req, _ := NewRequest("GET", "http://example.com/", nil)
+	go func() {
+		_, err := tr.RoundTrip(req)
+		errc <- err
+	}()
+
+	sc := <-serverConnCh
+	verb := make([]byte, 3)
+	if _, err := io.ReadFull(sc, verb); err != nil {
+		t.Errorf("Error reading HTTP verb from server: %v", err)
+	}
+	if string(verb) != "GET" {
+		t.Errorf("server received %q; want GET", verb)
+	}
+	defer sc.Close()
+
+	tr.CancelRequest(req)
+
+	err := <-errc
+	if err == nil {
+		t.Fatalf("unexpected success from RoundTrip")
+	}
+	if err != ExportErrRequestCanceled {
+		t.Errorf("RoundTrip error = %v; want ExportErrRequestCanceled", err)
+	}
+}
+
 // golang.org/issue/3672 -- Client can't close HTTP stream
 // Calling Close on a Response.Body used to just read until EOF.
 // Now it actually closes the TCP connection.
@@ -1795,6 +1967,11 @@
 	}))
 	defer ts.Close()
 
+	const nReqs = 5
+	didRead := make(chan bool, nReqs)
+	SetReadLoopBeforeNextReadHook(func() { didRead <- true })
+	defer SetReadLoopBeforeNextReadHook(nil)
+
 	tr := &Transport{
 		Dial: func(netw, addr string) (net.Conn, error) {
 			return net.Dial(netw, ts.Listener.Addr().String())
@@ -1807,12 +1984,28 @@
 	// First, without keep-alives.
 	for _, disableKeep := range []bool{true, false} {
 		tr.DisableKeepAlives = disableKeep
-		for i := 0; i < 5; i++ {
+		for i := 0; i < nReqs; i++ {
 			_, err := c.Get(fmt.Sprintf("http://foo-host-%d.tld/", i))
 			if err != nil {
 				t.Fatal(err)
 			}
+			// Note: no res.Body.Close is needed here, since the
+			// response Content-Length is zero. Perhaps the test
+			// should be more explicit and use a HEAD, but tests
+			// elsewhere guarantee that zero byte responses generate
+			// a "Content-Length: 0" instead of chunking.
 		}
+
+		// At this point, each of the 5 Transport.readLoop goroutines
+		// are scheduling noting that there are no response bodies (see
+		// earlier comment), and are then calling putIdleConn, which
+		// decrements this count. Usually that happens quickly, which is
+		// why this test has seemed to work for ages. But it's still
+		// racey: we have wait for them to finish first. See Issue 10427
+		for i := 0; i < nReqs; i++ {
+			<-didRead
+		}
+
 		if got := tr.IdleConnChMapSizeForTesting(); got != 0 {
 			t.Fatalf("ForDisableKeepAlives = %v, map size = %d; want 0", disableKeep, got)
 		}
@@ -1824,7 +2017,7 @@
 // then closes it.
 func TestTransportClosesRequestBody(t *testing.T) {
 	defer afterTest(t)
-	ts := httptest.NewServer(http.HandlerFunc(func(w ResponseWriter, r *Request) {
+	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
 		io.Copy(ioutil.Discard, r.Body)
 	}))
 	defer ts.Close()
@@ -2060,6 +2253,38 @@
 	}
 }
 
+// Tests that we don't leak Transport persistConn.readLoop goroutines
+// when a server hangs up immediately after saying it would keep-alive.
+func TestTransportIssue10457(t *testing.T) {
+	defer afterTest(t) // used to fail in goroutine leak check
+	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
+		// Send a response with no body, keep-alive
+		// (implicit), and then lie and immediately close the
+		// connection. This forces the Transport's readLoop to
+		// immediately Peek an io.EOF and get to the point
+		// that used to hang.
+		conn, _, _ := w.(Hijacker).Hijack()
+		conn.Write([]byte("HTTP/1.1 200 OK\r\nFoo: Bar\r\nContent-Length: 0\r\n\r\n")) // keep-alive
+		conn.Close()
+	}))
+	defer ts.Close()
+	tr := &Transport{}
+	defer tr.CloseIdleConnections()
+	cl := &Client{Transport: tr}
+	res, err := cl.Get(ts.URL)
+	if err != nil {
+		t.Fatalf("Get: %v", err)
+	}
+	defer res.Body.Close()
+
+	// Just a sanity check that we at least get the response. The real
+	// test here is that the "defer afterTest" above doesn't find any
+	// leaked goroutines.
+	if got, want := res.Header.Get("Foo"), "Bar"; got != want {
+		t.Errorf("Foo header = %q; want %q", got, want)
+	}
+}
+
 type errorReader struct {
 	err error
 }
@@ -2073,7 +2298,7 @@
 // Issue 6981
 func TestTransportClosesBodyOnError(t *testing.T) {
 	if runtime.GOOS == "plan9" {
-		t.Skip("skipping test; see http://golang.org/issue/7782")
+		t.Skip("skipping test; see https://golang.org/issue/7782")
 	}
 	defer afterTest(t)
 	readBody := make(chan error, 1)
@@ -2162,13 +2387,13 @@
 // Test for issue 8755
 // Ensure that if a proxy returns an error, it is exposed by RoundTrip
 func TestRoundTripReturnsProxyError(t *testing.T) {
-	badProxy := func(*http.Request) (*url.URL, error) {
+	badProxy := func(*Request) (*url.URL, error) {
 		return nil, errors.New("errorMessage")
 	}
 
 	tr := &Transport{Proxy: badProxy}
 
-	req, _ := http.NewRequest("GET", "http://example.com", nil)
+	req, _ := NewRequest("GET", "http://example.com", nil)
 
 	_, err := tr.RoundTrip(req)
 
@@ -2249,7 +2474,268 @@
 	res.Body.Close()
 }
 
-func wantBody(res *http.Response, err error, want string) error {
+// Previously, we used to handle a logical race within RoundTrip by waiting for 100ms
+// in the case of an error. Changing the order of the channel operations got rid of this
+// race.
+//
+// In order to test that the channel op reordering works, we install a hook into the
+// roundTrip function which gets called if we saw the connection go away and
+// we subsequently received a response.
+func TestTransportResponseCloseRace(t *testing.T) {
+	if testing.Short() {
+		t.Skip("skipping in short mode")
+	}
+	defer afterTest(t)
+
+	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
+	}))
+	defer ts.Close()
+	sawRace := false
+	SetInstallConnClosedHook(func() {
+		sawRace = true
+	})
+	defer SetInstallConnClosedHook(nil)
+	tr := &Transport{
+		DisableKeepAlives: true,
+	}
+	req, err := NewRequest("GET", ts.URL, nil)
+	if err != nil {
+		t.Fatal(err)
+	}
+	// selects are not deterministic, so do this a bunch
+	// and see if we handle the logical race at least once.
+	for i := 0; i < 10000; i++ {
+		resp, err := tr.RoundTrip(req)
+		if err != nil {
+			t.Fatalf("unexpected error: %s", err)
+			continue
+		}
+		resp.Body.Close()
+		if sawRace {
+			break
+		}
+	}
+	if !sawRace {
+		t.Errorf("didn't see response/connection going away race")
+	}
+}
+
+// Test for issue 10474
+func TestTransportResponseCancelRace(t *testing.T) {
+	defer afterTest(t)
+
+	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
+		// important that this response has a body.
+		var b [1024]byte
+		w.Write(b[:])
+	}))
+	defer ts.Close()
+
+	tr := &Transport{}
+	defer tr.CloseIdleConnections()
+
+	req, err := NewRequest("GET", ts.URL, nil)
+	if err != nil {
+		t.Fatal(err)
+	}
+	res, err := tr.RoundTrip(req)
+	if err != nil {
+		t.Fatal(err)
+	}
+	// If we do an early close, Transport just throws the connection away and
+	// doesn't reuse it. In order to trigger the bug, it has to reuse the connection
+	// so read the body
+	if _, err := io.Copy(ioutil.Discard, res.Body); err != nil {
+		t.Fatal(err)
+	}
+
+	req2, err := NewRequest("GET", ts.URL, nil)
+	if err != nil {
+		t.Fatal(err)
+	}
+	tr.CancelRequest(req)
+	res, err = tr.RoundTrip(req2)
+	if err != nil {
+		t.Fatal(err)
+	}
+	res.Body.Close()
+}
+
+func TestTransportDialCancelRace(t *testing.T) {
+	defer afterTest(t)
+
+	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {}))
+	defer ts.Close()
+
+	tr := &Transport{}
+	defer tr.CloseIdleConnections()
+
+	req, err := NewRequest("GET", ts.URL, nil)
+	if err != nil {
+		t.Fatal(err)
+	}
+	SetEnterRoundTripHook(func() {
+		tr.CancelRequest(req)
+	})
+	defer SetEnterRoundTripHook(nil)
+	res, err := tr.RoundTrip(req)
+	if err != ExportErrRequestCanceled {
+		t.Errorf("expected canceled request error; got %v", err)
+		if err == nil {
+			res.Body.Close()
+		}
+	}
+}
+
+// logWritesConn is a net.Conn that logs each Write call to writes
+// and then proxies to w.
+// It proxies Read calls to a reader it receives from rch.
+type logWritesConn struct {
+	net.Conn // nil. crash on use.
+
+	w io.Writer
+
+	rch <-chan io.Reader
+	r   io.Reader // nil until received by rch
+
+	mu     sync.Mutex
+	writes []string
+}
+
+func (c *logWritesConn) Write(p []byte) (n int, err error) {
+	c.mu.Lock()
+	defer c.mu.Unlock()
+	c.writes = append(c.writes, string(p))
+	return c.w.Write(p)
+}
+
+func (c *logWritesConn) Read(p []byte) (n int, err error) {
+	if c.r == nil {
+		c.r = <-c.rch
+	}
+	return c.r.Read(p)
+}
+
+func (c *logWritesConn) Close() error { return nil }
+
+// Issue 6574
+func TestTransportFlushesBodyChunks(t *testing.T) {
+	defer afterTest(t)
+	resBody := make(chan io.Reader, 1)
+	connr, connw := io.Pipe() // connection pipe pair
+	lw := &logWritesConn{
+		rch: resBody,
+		w:   connw,
+	}
+	tr := &Transport{
+		Dial: func(network, addr string) (net.Conn, error) {
+			return lw, nil
+		},
+	}
+	bodyr, bodyw := io.Pipe() // body pipe pair
+	go func() {
+		defer bodyw.Close()
+		for i := 0; i < 3; i++ {
+			fmt.Fprintf(bodyw, "num%d\n", i)
+		}
+	}()
+	resc := make(chan *Response)
+	go func() {
+		req, _ := NewRequest("POST", "http://localhost:8080", bodyr)
+		req.Header.Set("User-Agent", "x") // known value for test
+		res, err := tr.RoundTrip(req)
+		if err != nil {
+			t.Error("RoundTrip: %v", err)
+			close(resc)
+			return
+		}
+		resc <- res
+
+	}()
+	// Fully consume the request before checking the Write log vs. want.
+	req, err := ReadRequest(bufio.NewReader(connr))
+	if err != nil {
+		t.Fatal(err)
+	}
+	io.Copy(ioutil.Discard, req.Body)
+
+	// Unblock the transport's roundTrip goroutine.
+	resBody <- strings.NewReader("HTTP/1.1 204 No Content\r\nConnection: close\r\n\r\n")
+	res, ok := <-resc
+	if !ok {
+		return
+	}
+	defer res.Body.Close()
+
+	want := []string{
+		// Because Request.ContentLength = 0, the body is sniffed for 1 byte to determine whether there's content.
+		// That explains the initial "num0" being split into "n" and "um0".
+		// The first byte is included with the request headers Write. Perhaps in the future
+		// we will want to flush the headers out early if the first byte of the request body is
+		// taking a long time to arrive. But not yet.
+		"POST / HTTP/1.1\r\nHost: localhost:8080\r\nUser-Agent: x\r\nTransfer-Encoding: chunked\r\nAccept-Encoding: gzip\r\n\r\n" +
+			"1\r\nn\r\n",
+		"4\r\num0\n\r\n",
+		"5\r\nnum1\n\r\n",
+		"5\r\nnum2\n\r\n",
+		"0\r\n\r\n",
+	}
+	if !reflect.DeepEqual(lw.writes, want) {
+		t.Errorf("Writes differed.\n Got: %q\nWant: %q\n", lw.writes, want)
+	}
+}
+
+// Issue 11745.
+func TestTransportPrefersResponseOverWriteError(t *testing.T) {
+	if testing.Short() {
+		t.Skip("skipping in short mode")
+	}
+	defer afterTest(t)
+	const contentLengthLimit = 1024 * 1024 // 1MB
+	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
+		if r.ContentLength >= contentLengthLimit {
+			w.WriteHeader(StatusBadRequest)
+			r.Body.Close()
+			return
+		}
+		w.WriteHeader(StatusOK)
+	}))
+	defer ts.Close()
+
+	fail := 0
+	count := 100
+	bigBody := strings.Repeat("a", contentLengthLimit*2)
+	for i := 0; i < count; i++ {
+		req, err := NewRequest("PUT", ts.URL, strings.NewReader(bigBody))
+		if err != nil {
+			t.Fatal(err)
+		}
+		tr := new(Transport)
+		defer tr.CloseIdleConnections()
+		client := &Client{Transport: tr}
+		resp, err := client.Do(req)
+		if err != nil {
+			fail++
+			t.Logf("%d = %#v", i, err)
+			if ue, ok := err.(*url.Error); ok {
+				t.Logf("urlErr = %#v", ue.Err)
+				if ne, ok := ue.Err.(*net.OpError); ok {
+					t.Logf("netOpError = %#v", ne.Err)
+				}
+			}
+		} else {
+			resp.Body.Close()
+			if resp.StatusCode != 400 {
+				t.Errorf("Expected status code 400, got %v", resp.Status)
+			}
+		}
+	}
+	if fail > 0 {
+		t.Errorf("Failed %v out of %v\n", fail, count)
+	}
+}
+
+func wantBody(res *Response, err error, want string) error {
 	if err != nil {
 		return err
 	}
diff --git a/third_party/gofrontend/libgo/go/net/interface.go b/third_party/gofrontend/libgo/go/net/interface.go
index 2e9f1eb..9c7b5da 100644
--- a/third_party/gofrontend/libgo/go/net/interface.go
+++ b/third_party/gofrontend/libgo/go/net/interface.go
@@ -62,41 +62,61 @@
 // Addrs returns interface addresses for a specific interface.
 func (ifi *Interface) Addrs() ([]Addr, error) {
 	if ifi == nil {
-		return nil, errInvalidInterface
+		return nil, &OpError{Op: "route", Net: "ip+net", Source: nil, Addr: nil, Err: errInvalidInterface}
 	}
-	return interfaceAddrTable(ifi)
+	ifat, err := interfaceAddrTable(ifi)
+	if err != nil {
+		err = &OpError{Op: "route", Net: "ip+net", Source: nil, Addr: nil, Err: err}
+	}
+	return ifat, err
 }
 
 // MulticastAddrs returns multicast, joined group addresses for
 // a specific interface.
 func (ifi *Interface) MulticastAddrs() ([]Addr, error) {
 	if ifi == nil {
-		return nil, errInvalidInterface
+		return nil, &OpError{Op: "route", Net: "ip+net", Source: nil, Addr: nil, Err: errInvalidInterface}
 	}
-	return interfaceMulticastAddrTable(ifi)
+	ifat, err := interfaceMulticastAddrTable(ifi)
+	if err != nil {
+		err = &OpError{Op: "route", Net: "ip+net", Source: nil, Addr: nil, Err: err}
+	}
+	return ifat, err
 }
 
 // Interfaces returns a list of the system's network interfaces.
 func Interfaces() ([]Interface, error) {
-	return interfaceTable(0)
+	ift, err := interfaceTable(0)
+	if err != nil {
+		err = &OpError{Op: "route", Net: "ip+net", Source: nil, Addr: nil, Err: err}
+	}
+	return ift, err
 }
 
 // InterfaceAddrs returns a list of the system's network interface
 // addresses.
 func InterfaceAddrs() ([]Addr, error) {
-	return interfaceAddrTable(nil)
+	ifat, err := interfaceAddrTable(nil)
+	if err != nil {
+		err = &OpError{Op: "route", Net: "ip+net", Source: nil, Addr: nil, Err: err}
+	}
+	return ifat, err
 }
 
 // InterfaceByIndex returns the interface specified by index.
 func InterfaceByIndex(index int) (*Interface, error) {
 	if index <= 0 {
-		return nil, errInvalidInterfaceIndex
+		return nil, &OpError{Op: "route", Net: "ip+net", Source: nil, Addr: nil, Err: errInvalidInterfaceIndex}
 	}
 	ift, err := interfaceTable(index)
 	if err != nil {
-		return nil, err
+		return nil, &OpError{Op: "route", Net: "ip+net", Source: nil, Addr: nil, Err: err}
 	}
-	return interfaceByIndex(ift, index)
+	ifi, err := interfaceByIndex(ift, index)
+	if err != nil {
+		err = &OpError{Op: "route", Net: "ip+net", Source: nil, Addr: nil, Err: err}
+	}
+	return ifi, err
 }
 
 func interfaceByIndex(ift []Interface, index int) (*Interface, error) {
@@ -111,16 +131,16 @@
 // InterfaceByName returns the interface specified by name.
 func InterfaceByName(name string) (*Interface, error) {
 	if name == "" {
-		return nil, errInvalidInterfaceName
+		return nil, &OpError{Op: "route", Net: "ip+net", Source: nil, Addr: nil, Err: errInvalidInterfaceName}
 	}
 	ift, err := interfaceTable(0)
 	if err != nil {
-		return nil, err
+		return nil, &OpError{Op: "route", Net: "ip+net", Source: nil, Addr: nil, Err: err}
 	}
 	for _, ifi := range ift {
 		if name == ifi.Name {
 			return &ifi, nil
 		}
 	}
-	return nil, errNoSuchInterface
+	return nil, &OpError{Op: "route", Net: "ip+net", Source: nil, Addr: nil, Err: errNoSuchInterface}
 }
diff --git a/third_party/gofrontend/libgo/go/net/interface_bsd.go b/third_party/gofrontend/libgo/go/net/interface_bsd.go
index 1677557..208f37f 100644
--- a/third_party/gofrontend/libgo/go/net/interface_bsd.go
+++ b/third_party/gofrontend/libgo/go/net/interface_bsd.go
@@ -18,11 +18,11 @@
 func interfaceTable(ifindex int) ([]Interface, error) {
 	tab, err := syscall.RouteRIB(syscall.NET_RT_IFLIST, ifindex)
 	if err != nil {
-		return nil, os.NewSyscallError("route rib", err)
+		return nil, os.NewSyscallError("routerib", err)
 	}
 	msgs, err := syscall.ParseRoutingMessage(tab)
 	if err != nil {
-		return nil, os.NewSyscallError("route message", err)
+		return nil, os.NewSyscallError("parseroutingmessage", err)
 	}
 	return parseInterfaceTable(ifindex, msgs)
 }
@@ -51,27 +51,25 @@
 func newLink(m *syscall.InterfaceMessage) (*Interface, error) {
 	sas, err := syscall.ParseRoutingSockaddr(m)
 	if err != nil {
-		return nil, os.NewSyscallError("route sockaddr", err)
+		return nil, os.NewSyscallError("parseroutingsockaddr", err)
 	}
 	ifi := &Interface{Index: int(m.Header.Index), Flags: linkFlags(m.Header.Flags)}
-	for _, sa := range sas {
-		switch sa := sa.(type) {
-		case *syscall.SockaddrDatalink:
-			// NOTE: SockaddrDatalink.Data is minimum work area,
-			// can be larger.
-			m.Data = m.Data[unsafe.Offsetof(sa.Data):]
-			var name [syscall.IFNAMSIZ]byte
-			for i := 0; i < int(sa.Nlen); i++ {
-				name[i] = byte(m.Data[i])
-			}
-			ifi.Name = string(name[:sa.Nlen])
-			ifi.MTU = int(m.Header.Data.Mtu)
-			addr := make([]byte, sa.Alen)
-			for i := 0; i < int(sa.Alen); i++ {
-				addr[i] = byte(m.Data[int(sa.Nlen)+i])
-			}
-			ifi.HardwareAddr = addr[:sa.Alen]
+	sa, _ := sas[syscall.RTAX_IFP].(*syscall.SockaddrDatalink)
+	if sa != nil {
+		// NOTE: SockaddrDatalink.Data is minimum work area,
+		// can be larger.
+		m.Data = m.Data[unsafe.Offsetof(sa.Data):]
+		var name [syscall.IFNAMSIZ]byte
+		for i := 0; i < int(sa.Nlen); i++ {
+			name[i] = byte(m.Data[i])
 		}
+		ifi.Name = string(name[:sa.Nlen])
+		ifi.MTU = int(m.Header.Data.Mtu)
+		addr := make([]byte, sa.Alen)
+		for i := 0; i < int(sa.Alen); i++ {
+			addr[i] = byte(m.Data[int(sa.Nlen)+i])
+		}
+		ifi.HardwareAddr = addr[:sa.Alen]
 	}
 	return ifi, nil
 }
@@ -106,11 +104,11 @@
 	}
 	tab, err := syscall.RouteRIB(syscall.NET_RT_IFLIST, index)
 	if err != nil {
-		return nil, os.NewSyscallError("route rib", err)
+		return nil, os.NewSyscallError("routerib", err)
 	}
 	msgs, err := syscall.ParseRoutingMessage(tab)
 	if err != nil {
-		return nil, os.NewSyscallError("route message", err)
+		return nil, os.NewSyscallError("parseroutingmessage", err)
 	}
 	var ift []Interface
 	if index == 0 {
@@ -144,39 +142,34 @@
 	return ifat, nil
 }
 
-func newAddr(ifi *Interface, m *syscall.InterfaceAddrMessage) (Addr, error) {
+func newAddr(ifi *Interface, m *syscall.InterfaceAddrMessage) (*IPNet, error) {
 	sas, err := syscall.ParseRoutingSockaddr(m)
 	if err != nil {
-		return nil, os.NewSyscallError("route sockaddr", err)
+		return nil, os.NewSyscallError("parseroutingsockaddr", err)
 	}
 	ifa := &IPNet{}
-	for i, sa := range sas {
-		switch sa := sa.(type) {
-		case *syscall.SockaddrInet4:
-			switch i {
-			case 0:
-				ifa.Mask = IPv4Mask(sa.Addr[0], sa.Addr[1], sa.Addr[2], sa.Addr[3])
-			case 1:
-				ifa.IP = IPv4(sa.Addr[0], sa.Addr[1], sa.Addr[2], sa.Addr[3])
-			}
-		case *syscall.SockaddrInet6:
-			switch i {
-			case 0:
-				ifa.Mask = make(IPMask, IPv6len)
-				copy(ifa.Mask, sa.Addr[:])
-			case 1:
-				ifa.IP = make(IP, IPv6len)
-				copy(ifa.IP, sa.Addr[:])
-				// NOTE: KAME based IPv6 protcol stack usually embeds
-				// the interface index in the interface-local or link-
-				// local address as the kernel-internal form.
-				if ifa.IP.IsLinkLocalUnicast() {
-					ifa.IP[2], ifa.IP[3] = 0, 0
-				}
-			}
-		default: // Sockaddrs contain syscall.SockaddrDatalink on NetBSD
-			return nil, nil
+	switch sa := sas[syscall.RTAX_NETMASK].(type) {
+	case *syscall.SockaddrInet4:
+		ifa.Mask = IPv4Mask(sa.Addr[0], sa.Addr[1], sa.Addr[2], sa.Addr[3])
+	case *syscall.SockaddrInet6:
+		ifa.Mask = make(IPMask, IPv6len)
+		copy(ifa.Mask, sa.Addr[:])
+	}
+	switch sa := sas[syscall.RTAX_IFA].(type) {
+	case *syscall.SockaddrInet4:
+		ifa.IP = IPv4(sa.Addr[0], sa.Addr[1], sa.Addr[2], sa.Addr[3])
+	case *syscall.SockaddrInet6:
+		ifa.IP = make(IP, IPv6len)
+		copy(ifa.IP, sa.Addr[:])
+		// NOTE: KAME based IPv6 protcol stack usually embeds
+		// the interface index in the interface-local or
+		// link-local address as the kernel-internal form.
+		if ifa.IP.IsLinkLocalUnicast() {
+			ifa.IP[2], ifa.IP[3] = 0, 0
 		}
 	}
+	if ifa.IP == nil || ifa.Mask == nil {
+		return nil, nil // Sockaddrs contain syscall.SockaddrDatalink on NetBSD
+	}
 	return ifa, nil
 }
diff --git a/third_party/gofrontend/libgo/go/net/interface_darwin.go b/third_party/gofrontend/libgo/go/net/interface_darwin.go
index ad0937d..b7a3338 100644
--- a/third_party/gofrontend/libgo/go/net/interface_darwin.go
+++ b/third_party/gofrontend/libgo/go/net/interface_darwin.go
@@ -14,11 +14,11 @@
 func interfaceMulticastAddrTable(ifi *Interface) ([]Addr, error) {
 	tab, err := syscall.RouteRIB(syscall.NET_RT_IFLIST2, ifi.Index)
 	if err != nil {
-		return nil, os.NewSyscallError("route rib", err)
+		return nil, os.NewSyscallError("routerib", err)
 	}
 	msgs, err := syscall.ParseRoutingMessage(tab)
 	if err != nil {
-		return nil, os.NewSyscallError("route message", err)
+		return nil, os.NewSyscallError("parseroutingmessage", err)
 	}
 	var ifmat []Addr
 	for _, m := range msgs {
@@ -29,35 +29,34 @@
 				if err != nil {
 					return nil, err
 				}
-				ifmat = append(ifmat, ifma...)
+				if ifma != nil {
+					ifmat = append(ifmat, ifma)
+				}
 			}
 		}
 	}
 	return ifmat, nil
 }
 
-func newMulticastAddr(ifi *Interface, m *syscall.InterfaceMulticastAddrMessage) ([]Addr, error) {
+func newMulticastAddr(ifi *Interface, m *syscall.InterfaceMulticastAddrMessage) (*IPAddr, error) {
 	sas, err := syscall.ParseRoutingSockaddr(m)
 	if err != nil {
-		return nil, os.NewSyscallError("route sockaddr", err)
+		return nil, os.NewSyscallError("parseroutingsockaddr", err)
 	}
-	var ifmat []Addr
-	for _, sa := range sas {
-		switch sa := sa.(type) {
-		case *syscall.SockaddrInet4:
-			ifma := &IPAddr{IP: IPv4(sa.Addr[0], sa.Addr[1], sa.Addr[2], sa.Addr[3])}
-			ifmat = append(ifmat, ifma.toAddr())
-		case *syscall.SockaddrInet6:
-			ifma := &IPAddr{IP: make(IP, IPv6len)}
-			copy(ifma.IP, sa.Addr[:])
-			// NOTE: KAME based IPv6 protocol stack usually embeds
-			// the interface index in the interface-local or link-
-			// local address as the kernel-internal form.
-			if ifma.IP.IsInterfaceLocalMulticast() || ifma.IP.IsLinkLocalMulticast() {
-				ifma.IP[2], ifma.IP[3] = 0, 0
-			}
-			ifmat = append(ifmat, ifma.toAddr())
+	switch sa := sas[syscall.RTAX_IFA].(type) {
+	case *syscall.SockaddrInet4:
+		return &IPAddr{IP: IPv4(sa.Addr[0], sa.Addr[1], sa.Addr[2], sa.Addr[3])}, nil
+	case *syscall.SockaddrInet6:
+		ifma := IPAddr{IP: make(IP, IPv6len)}
+		copy(ifma.IP, sa.Addr[:])
+		// NOTE: KAME based IPv6 protcol stack usually embeds
+		// the interface index in the interface-local or
+		// link-local address as the kernel-internal form.
+		if ifma.IP.IsInterfaceLocalMulticast() || ifma.IP.IsLinkLocalMulticast() {
+			ifma.IP[2], ifma.IP[3] = 0, 0
 		}
+		return &ifma, nil
+	default:
+		return nil, nil
 	}
-	return ifmat, nil
 }
diff --git a/third_party/gofrontend/libgo/go/net/interface_freebsd.go b/third_party/gofrontend/libgo/go/net/interface_freebsd.go
index 5df7679..c42d90b 100644
--- a/third_party/gofrontend/libgo/go/net/interface_freebsd.go
+++ b/third_party/gofrontend/libgo/go/net/interface_freebsd.go
@@ -14,11 +14,11 @@
 func interfaceMulticastAddrTable(ifi *Interface) ([]Addr, error) {
 	tab, err := syscall.RouteRIB(syscall.NET_RT_IFMALIST, ifi.Index)
 	if err != nil {
-		return nil, os.NewSyscallError("route rib", err)
+		return nil, os.NewSyscallError("routerib", err)
 	}
 	msgs, err := syscall.ParseRoutingMessage(tab)
 	if err != nil {
-		return nil, os.NewSyscallError("route message", err)
+		return nil, os.NewSyscallError("parseroutingmessage", err)
 	}
 	var ifmat []Addr
 	for _, m := range msgs {
@@ -29,35 +29,34 @@
 				if err != nil {
 					return nil, err
 				}
-				ifmat = append(ifmat, ifma...)
+				if ifma != nil {
+					ifmat = append(ifmat, ifma)
+				}
 			}
 		}
 	}
 	return ifmat, nil
 }
 
-func newMulticastAddr(ifi *Interface, m *syscall.InterfaceMulticastAddrMessage) ([]Addr, error) {
+func newMulticastAddr(ifi *Interface, m *syscall.InterfaceMulticastAddrMessage) (*IPAddr, error) {
 	sas, err := syscall.ParseRoutingSockaddr(m)
 	if err != nil {
-		return nil, os.NewSyscallError("route sockaddr", err)
+		return nil, os.NewSyscallError("parseroutingsockaddr", err)
 	}
-	var ifmat []Addr
-	for _, sa := range sas {
-		switch sa := sa.(type) {
-		case *syscall.SockaddrInet4:
-			ifma := &IPAddr{IP: IPv4(sa.Addr[0], sa.Addr[1], sa.Addr[2], sa.Addr[3])}
-			ifmat = append(ifmat, ifma.toAddr())
-		case *syscall.SockaddrInet6:
-			ifma := &IPAddr{IP: make(IP, IPv6len)}
-			copy(ifma.IP, sa.Addr[:])
-			// NOTE: KAME based IPv6 protocol stack usually embeds
-			// the interface index in the interface-local or link-
-			// local address as the kernel-internal form.
-			if ifma.IP.IsInterfaceLocalMulticast() || ifma.IP.IsLinkLocalMulticast() {
-				ifma.IP[2], ifma.IP[3] = 0, 0
-			}
-			ifmat = append(ifmat, ifma.toAddr())
+	switch sa := sas[syscall.RTAX_IFA].(type) {
+	case *syscall.SockaddrInet4:
+		return &IPAddr{IP: IPv4(sa.Addr[0], sa.Addr[1], sa.Addr[2], sa.Addr[3])}, nil
+	case *syscall.SockaddrInet6:
+		ifma := IPAddr{IP: make(IP, IPv6len)}
+		copy(ifma.IP, sa.Addr[:])
+		// NOTE: KAME based IPv6 protcol stack usually embeds
+		// the interface index in the interface-local or
+		// link-local address as the kernel-internal form.
+		if ifma.IP.IsInterfaceLocalMulticast() || ifma.IP.IsLinkLocalMulticast() {
+			ifma.IP[2], ifma.IP[3] = 0, 0
 		}
+		return &ifma, nil
+	default:
+		return nil, nil
 	}
-	return ifmat, nil
 }
diff --git a/third_party/gofrontend/libgo/go/net/interface_linux.go b/third_party/gofrontend/libgo/go/net/interface_linux.go
index 1115d0f..ef20429 100644
--- a/third_party/gofrontend/libgo/go/net/interface_linux.go
+++ b/third_party/gofrontend/libgo/go/net/interface_linux.go
@@ -16,11 +16,11 @@
 func interfaceTable(ifindex int) ([]Interface, error) {
 	tab, err := syscall.NetlinkRIB(syscall.RTM_GETLINK, syscall.AF_UNSPEC)
 	if err != nil {
-		return nil, os.NewSyscallError("netlink rib", err)
+		return nil, os.NewSyscallError("netlinkrib", err)
 	}
 	msgs, err := syscall.ParseNetlinkMessage(tab)
 	if err != nil {
-		return nil, os.NewSyscallError("netlink message", err)
+		return nil, os.NewSyscallError("parsenetlinkmessage", err)
 	}
 	var ift []Interface
 loop:
@@ -33,7 +33,7 @@
 			if ifindex == 0 || ifindex == int(ifim.Index) {
 				attrs, err := syscall.ParseNetlinkRouteAttr(&m)
 				if err != nil {
-					return nil, os.NewSyscallError("netlink routeattr", err)
+					return nil, os.NewSyscallError("parsenetlinkrouteattr", err)
 				}
 				ift = append(ift, *newLink(ifim, attrs))
 				if ifindex == int(ifim.Index) {
@@ -120,11 +120,11 @@
 func interfaceAddrTable(ifi *Interface) ([]Addr, error) {
 	tab, err := syscall.NetlinkRIB(syscall.RTM_GETADDR, syscall.AF_UNSPEC)
 	if err != nil {
-		return nil, os.NewSyscallError("netlink rib", err)
+		return nil, os.NewSyscallError("netlinkrib", err)
 	}
 	msgs, err := syscall.ParseNetlinkMessage(tab)
 	if err != nil {
-		return nil, os.NewSyscallError("netlink message", err)
+		return nil, os.NewSyscallError("parsenetlinkmessage", err)
 	}
 	var ift []Interface
 	if ifi == nil {
@@ -160,7 +160,7 @@
 				}
 				attrs, err := syscall.ParseNetlinkRouteAttr(&m)
 				if err != nil {
-					return nil, os.NewSyscallError("netlink routeattr", err)
+					return nil, os.NewSyscallError("parsenetlinkrouteattr", err)
 				}
 				ifa := newAddr(ifi, ifam, attrs)
 				if ifa != nil {
@@ -176,17 +176,15 @@
 	var ipPointToPoint bool
 	// Seems like we need to make sure whether the IP interface
 	// stack consists of IP point-to-point numbered or unnumbered
-	// addressing over point-to-point link encapsulation.
-	if ifi.Flags&FlagPointToPoint != 0 {
-		for _, a := range attrs {
-			if a.Attr.Type == syscall.IFA_LOCAL {
-				ipPointToPoint = true
-				break
-			}
+	// addressing.
+	for _, a := range attrs {
+		if a.Attr.Type == syscall.IFA_LOCAL {
+			ipPointToPoint = true
+			break
 		}
 	}
 	for _, a := range attrs {
-		if ipPointToPoint && a.Attr.Type == syscall.IFA_ADDRESS || !ipPointToPoint && a.Attr.Type == syscall.IFA_LOCAL {
+		if ipPointToPoint && a.Attr.Type == syscall.IFA_ADDRESS {
 			continue
 		}
 		switch ifam.Family {
@@ -238,8 +236,8 @@
 					b[i/2], _ = xtoi2(f[0][i:i+2], 0)
 				}
 				i := *(*uint32)(unsafe.Pointer(&b[:4][0]))
-				ifma := IPAddr{IP: IPv4(byte(i>>24), byte(i>>16), byte(i>>8), byte(i))}
-				ifmat = append(ifmat, ifma.toAddr())
+				ifma := &IPAddr{IP: IPv4(byte(i>>24), byte(i>>16), byte(i>>8), byte(i))}
+				ifmat = append(ifmat, ifma)
 			}
 		}
 	}
@@ -263,8 +261,8 @@
 			for i := 0; i+1 < len(f[2]); i += 2 {
 				b[i/2], _ = xtoi2(f[2][i:i+2], 0)
 			}
-			ifma := IPAddr{IP: IP{b[0], b[1], b[2], b[3], b[4], b[5], b[6], b[7], b[8], b[9], b[10], b[11], b[12], b[13], b[14], b[15]}}
-			ifmat = append(ifmat, ifma.toAddr())
+			ifma := &IPAddr{IP: IP{b[0], b[1], b[2], b[3], b[4], b[5], b[6], b[7], b[8], b[9], b[10], b[11], b[12], b[13], b[14], b[15]}}
+			ifmat = append(ifmat, ifma)
 		}
 	}
 	return ifmat
diff --git a/third_party/gofrontend/libgo/go/net/interface_test.go b/third_party/gofrontend/libgo/go/net/interface_test.go
index efabb5f..567d18d 100644
--- a/third_party/gofrontend/libgo/go/net/interface_test.go
+++ b/third_party/gofrontend/libgo/go/net/interface_test.go
@@ -6,6 +6,7 @@
 
 import (
 	"reflect"
+	"runtime"
 	"testing"
 )
 
@@ -37,12 +38,7 @@
 		return ""
 	}
 	for _, ifa := range ifat {
-		switch ifa := ifa.(type) {
-		case *IPAddr:
-			if ifa.IP.To4() == nil && ifa.IP.IsLinkLocalUnicast() {
-				return ifa.IP.String()
-			}
-		case *IPNet:
+		if ifa, ok := ifa.(*IPNet); ok {
 			if ifa.IP.To4() == nil && ifa.IP.IsLinkLocalUnicast() {
 				return ifa.IP.String()
 			}
@@ -51,161 +47,259 @@
 	return ""
 }
 
+type routeStats struct {
+	loop  int // # of active loopback interfaces
+	other int // # of active other interfaces
+
+	uni4, uni6     int // # of active connected unicast, anycast routes
+	multi4, multi6 int // # of active connected multicast route clones
+}
+
 func TestInterfaces(t *testing.T) {
 	ift, err := Interfaces()
 	if err != nil {
-		t.Fatalf("Interfaces failed: %v", err)
+		t.Fatal(err)
 	}
-	t.Logf("table: len/cap = %v/%v", len(ift), cap(ift))
-
+	var stats routeStats
 	for _, ifi := range ift {
 		ifxi, err := InterfaceByIndex(ifi.Index)
 		if err != nil {
-			t.Fatalf("InterfaceByIndex(%v) failed: %v", ifi.Index, err)
+			t.Fatal(err)
 		}
 		if !reflect.DeepEqual(ifxi, &ifi) {
-			t.Fatalf("InterfaceByIndex(%v) = %v, want %v", ifi.Index, ifxi, ifi)
+			t.Errorf("got %v; want %v", ifxi, ifi)
 		}
 		ifxn, err := InterfaceByName(ifi.Name)
 		if err != nil {
-			t.Fatalf("InterfaceByName(%q) failed: %v", ifi.Name, err)
+			t.Fatal(err)
 		}
 		if !reflect.DeepEqual(ifxn, &ifi) {
-			t.Fatalf("InterfaceByName(%q) = %v, want %v", ifi.Name, ifxn, ifi)
+			t.Errorf("got %v; want %v", ifxn, ifi)
 		}
 		t.Logf("%q: flags %q, ifindex %v, mtu %v", ifi.Name, ifi.Flags.String(), ifi.Index, ifi.MTU)
-		t.Logf("\thardware address %q", ifi.HardwareAddr.String())
-		testInterfaceAddrs(t, &ifi)
-		testInterfaceMulticastAddrs(t, &ifi)
+		t.Logf("hardware address %q", ifi.HardwareAddr.String())
+		if ifi.Flags&FlagUp != 0 {
+			if ifi.Flags&FlagLoopback != 0 {
+				stats.loop++
+			} else {
+				stats.other++
+			}
+		}
+		n4, n6 := testInterfaceAddrs(t, &ifi)
+		stats.uni4 += n4
+		stats.uni6 += n6
+		n4, n6 = testInterfaceMulticastAddrs(t, &ifi)
+		stats.multi4 += n4
+		stats.multi6 += n6
+	}
+	switch runtime.GOOS {
+	case "nacl", "plan9", "solaris":
+	default:
+		// Test the existence of connected unicast routes for
+		// IPv4.
+		if supportsIPv4 && stats.loop+stats.other > 0 && stats.uni4 == 0 {
+			t.Errorf("num IPv4 unicast routes = 0; want >0; summary: %+v", stats)
+		}
+		// Test the existence of connected unicast routes for
+		// IPv6. We can assume the existence of ::1/128 when
+		// at least one looopback interface is installed.
+		if supportsIPv6 && stats.loop > 0 && stats.uni6 == 0 {
+			t.Errorf("num IPv6 unicast routes = 0; want >0; summary: %+v", stats)
+		}
+	}
+	switch runtime.GOOS {
+	case "dragonfly", "nacl", "netbsd", "openbsd", "plan9", "solaris":
+	default:
+		// Test the existence of connected multicast route
+		// clones for IPv4. Unlike IPv6, IPv4 multicast
+		// capability is not a mandatory feature, and so this
+		// test is disabled.
+		//if supportsIPv4 && stats.loop > 0 && stats.uni4 > 1 && stats.multi4 == 0 {
+		//	t.Errorf("num IPv4 multicast route clones = 0; want >0; summary: %+v", stats)
+		//}
+		// Test the existence of connected multicast route
+		// clones for IPv6. Some platform never uses loopback
+		// interface as the nexthop for multicast routing.
+		// We can assume the existence of connected multicast
+		// route clones when at least two connected unicast
+		// routes, ::1/128 and other, are installed.
+		if supportsIPv6 && stats.loop > 0 && stats.uni6 > 1 && stats.multi6 == 0 {
+			t.Errorf("num IPv6 multicast route clones = 0; want >0; summary: %+v", stats)
+		}
 	}
 }
 
 func TestInterfaceAddrs(t *testing.T) {
-	ifat, err := InterfaceAddrs()
+	ift, err := Interfaces()
 	if err != nil {
-		t.Fatalf("InterfaceAddrs failed: %v", err)
+		t.Fatal(err)
 	}
-	t.Logf("table: len/cap = %v/%v", len(ifat), cap(ifat))
-	testAddrs(t, ifat)
-}
-
-func testInterfaceAddrs(t *testing.T, ifi *Interface) {
-	ifat, err := ifi.Addrs()
-	if err != nil {
-		t.Fatalf("Interface.Addrs failed: %v", err)
-	}
-	testAddrs(t, ifat)
-}
-
-func testInterfaceMulticastAddrs(t *testing.T, ifi *Interface) {
-	ifmat, err := ifi.MulticastAddrs()
-	if err != nil {
-		t.Fatalf("Interface.MulticastAddrs failed: %v", err)
-	}
-	testMulticastAddrs(t, ifmat)
-}
-
-func testAddrs(t *testing.T, ifat []Addr) {
-	for _, ifa := range ifat {
-		switch ifa := ifa.(type) {
-		case *IPAddr:
-			if ifa == nil || ifa.IP == nil {
-				t.Errorf("\tunexpected value: %v, %v", ifa, ifa.IP)
+	var stats routeStats
+	for _, ifi := range ift {
+		if ifi.Flags&FlagUp != 0 {
+			if ifi.Flags&FlagLoopback != 0 {
+				stats.loop++
 			} else {
-				t.Logf("\tinterface address %q", ifa.String())
+				stats.other++
 			}
-		case *IPNet:
-			if ifa == nil || ifa.IP == nil || ifa.Mask == nil {
-				t.Errorf("\tunexpected value: %v, %v, %v", ifa, ifa.IP, ifa.Mask)
-			} else {
-				_, prefixLen := ifa.Mask.Size()
-				if ifa.IP.To4() != nil && prefixLen != 8*IPv4len || ifa.IP.To16() != nil && ifa.IP.To4() == nil && prefixLen != 8*IPv6len {
-					t.Errorf("\tunexpected value: %v, %v, %v, %v", ifa, ifa.IP, ifa.Mask, prefixLen)
-				} else {
-					t.Logf("\tinterface address %q", ifa.String())
-				}
-			}
-		default:
-			t.Errorf("\tunexpected type: %T", ifa)
 		}
 	}
+	ifat, err := InterfaceAddrs()
+	if err != nil {
+		t.Fatal(err)
+	}
+	stats.uni4, stats.uni6 = testAddrs(t, ifat)
+	// Test the existence of connected unicast routes for IPv4.
+	if supportsIPv4 && stats.loop+stats.other > 0 && stats.uni4 == 0 {
+		t.Errorf("num IPv4 unicast routes = 0; want >0; summary: %+v", stats)
+	}
+	// Test the existence of connected unicast routes for IPv6.
+	// We can assume the existence of ::1/128 when at least one
+	// looopback interface is installed.
+	if supportsIPv6 && stats.loop > 0 && stats.uni6 == 0 {
+		t.Errorf("num IPv6 unicast routes = 0; want >0; summary: %+v", stats)
+	}
 }
 
-func testMulticastAddrs(t *testing.T, ifmat []Addr) {
+func testInterfaceAddrs(t *testing.T, ifi *Interface) (naf4, naf6 int) {
+	ifat, err := ifi.Addrs()
+	if err != nil {
+		t.Fatal(err)
+	}
+	return testAddrs(t, ifat)
+}
+
+func testInterfaceMulticastAddrs(t *testing.T, ifi *Interface) (nmaf4, nmaf6 int) {
+	ifmat, err := ifi.MulticastAddrs()
+	if err != nil {
+		t.Fatal(err)
+	}
+	return testMulticastAddrs(t, ifmat)
+}
+
+func testAddrs(t *testing.T, ifat []Addr) (naf4, naf6 int) {
+	for _, ifa := range ifat {
+		switch ifa := ifa.(type) {
+		case *IPNet:
+			if ifa == nil || ifa.IP == nil || ifa.IP.IsUnspecified() || ifa.IP.IsMulticast() || ifa.Mask == nil {
+				t.Errorf("unexpected value: %#v", ifa)
+				continue
+			}
+			prefixLen, maxPrefixLen := ifa.Mask.Size()
+			if ifa.IP.To4() != nil {
+				if 0 >= prefixLen || prefixLen > 8*IPv4len || maxPrefixLen != 8*IPv4len {
+					t.Errorf("unexpected prefix length: %v/%v", prefixLen, maxPrefixLen)
+					continue
+				}
+				naf4++
+			} else if ifa.IP.To16() != nil {
+				if 0 >= prefixLen || prefixLen > 8*IPv6len || maxPrefixLen != 8*IPv6len {
+					t.Errorf("unexpected prefix length: %v/%v", prefixLen, maxPrefixLen)
+					continue
+				}
+				naf6++
+			}
+			t.Logf("interface address %q", ifa.String())
+		default:
+			t.Errorf("unexpected type: %T", ifa)
+		}
+	}
+	return
+}
+
+func testMulticastAddrs(t *testing.T, ifmat []Addr) (nmaf4, nmaf6 int) {
 	for _, ifma := range ifmat {
 		switch ifma := ifma.(type) {
 		case *IPAddr:
-			if ifma == nil {
-				t.Errorf("\tunexpected value: %v", ifma)
-			} else {
-				t.Logf("\tjoined group address %q", ifma.String())
+			if ifma == nil || ifma.IP == nil || ifma.IP.IsUnspecified() || !ifma.IP.IsMulticast() {
+				t.Errorf("unexpected value: %#v", ifma)
+				continue
 			}
+			if ifma.IP.To4() != nil {
+				nmaf4++
+			} else if ifma.IP.To16() != nil {
+				nmaf6++
+			}
+			t.Logf("joined group address %q", ifma.String())
 		default:
-			t.Errorf("\tunexpected type: %T", ifma)
+			t.Errorf("unexpected type: %T", ifma)
 		}
 	}
+	return
 }
 
 func BenchmarkInterfaces(b *testing.B) {
+	testHookUninstaller.Do(uninstallTestHooks)
+
 	for i := 0; i < b.N; i++ {
 		if _, err := Interfaces(); err != nil {
-			b.Fatalf("Interfaces failed: %v", err)
+			b.Fatal(err)
 		}
 	}
 }
 
 func BenchmarkInterfaceByIndex(b *testing.B) {
+	testHookUninstaller.Do(uninstallTestHooks)
+
 	ifi := loopbackInterface()
 	if ifi == nil {
 		b.Skip("loopback interface not found")
 	}
 	for i := 0; i < b.N; i++ {
 		if _, err := InterfaceByIndex(ifi.Index); err != nil {
-			b.Fatalf("InterfaceByIndex failed: %v", err)
+			b.Fatal(err)
 		}
 	}
 }
 
 func BenchmarkInterfaceByName(b *testing.B) {
+	testHookUninstaller.Do(uninstallTestHooks)
+
 	ifi := loopbackInterface()
 	if ifi == nil {
 		b.Skip("loopback interface not found")
 	}
 	for i := 0; i < b.N; i++ {
 		if _, err := InterfaceByName(ifi.Name); err != nil {
-			b.Fatalf("InterfaceByName failed: %v", err)
+			b.Fatal(err)
 		}
 	}
 }
 
 func BenchmarkInterfaceAddrs(b *testing.B) {
+	testHookUninstaller.Do(uninstallTestHooks)
+
 	for i := 0; i < b.N; i++ {
 		if _, err := InterfaceAddrs(); err != nil {
-			b.Fatalf("InterfaceAddrs failed: %v", err)
+			b.Fatal(err)
 		}
 	}
 }
 
 func BenchmarkInterfacesAndAddrs(b *testing.B) {
+	testHookUninstaller.Do(uninstallTestHooks)
+
 	ifi := loopbackInterface()
 	if ifi == nil {
 		b.Skip("loopback interface not found")
 	}
 	for i := 0; i < b.N; i++ {
 		if _, err := ifi.Addrs(); err != nil {
-			b.Fatalf("Interface.Addrs failed: %v", err)
+			b.Fatal(err)
 		}
 	}
 }
 
 func BenchmarkInterfacesAndMulticastAddrs(b *testing.B) {
+	testHookUninstaller.Do(uninstallTestHooks)
+
 	ifi := loopbackInterface()
 	if ifi == nil {
 		b.Skip("loopback interface not found")
 	}
 	for i := 0; i < b.N; i++ {
 		if _, err := ifi.MulticastAddrs(); err != nil {
-			b.Fatalf("Interface.MulticastAddrs failed: %v", err)
+			b.Fatal(err)
 		}
 	}
 }
diff --git a/third_party/gofrontend/libgo/go/net/interface_windows.go b/third_party/gofrontend/libgo/go/net/interface_windows.go
index 0759dc2..e25c1ed 100644
--- a/third_party/gofrontend/libgo/go/net/interface_windows.go
+++ b/third_party/gofrontend/libgo/go/net/interface_windows.go
@@ -5,123 +5,139 @@
 package net
 
 import (
+	"internal/syscall/windows"
 	"os"
 	"syscall"
 	"unsafe"
 )
 
-func bytePtrToString(p *uint8) string {
-	a := (*[10000]uint8)(unsafe.Pointer(p))
-	i := 0
-	for a[i] != 0 {
-		i++
+func getAdapters() (*windows.IpAdapterAddresses, error) {
+	block := uint32(unsafe.Sizeof(windows.IpAdapterAddresses{}))
+
+	// pre-allocate a 15KB working buffer pointed to by the AdapterAddresses
+	// parameter.
+	// https://msdn.microsoft.com/en-us/library/windows/desktop/aa365915(v=vs.85).aspx
+	size := uint32(15000)
+
+	var addrs []windows.IpAdapterAddresses
+	for {
+		addrs = make([]windows.IpAdapterAddresses, size/block+1)
+		err := windows.GetAdaptersAddresses(syscall.AF_UNSPEC, windows.GAA_FLAG_INCLUDE_PREFIX, 0, &addrs[0], &size)
+		if err == nil {
+			break
+		}
+		if err.(syscall.Errno) != syscall.ERROR_BUFFER_OVERFLOW {
+			return nil, os.NewSyscallError("getadaptersaddresses", err)
+		}
 	}
-	return string(a[:i])
+	return &addrs[0], nil
 }
 
-func getAdapterList() (*syscall.IpAdapterInfo, error) {
-	b := make([]byte, 1000)
-	l := uint32(len(b))
-	a := (*syscall.IpAdapterInfo)(unsafe.Pointer(&b[0]))
-	// TODO(mikio): GetAdaptersInfo returns IP_ADAPTER_INFO that
-	// contains IPv4 address list only. We should use another API
-	// for fetching IPv6 stuff from the kernel.
-	err := syscall.GetAdaptersInfo(a, &l)
-	if err == syscall.ERROR_BUFFER_OVERFLOW {
-		b = make([]byte, l)
-		a = (*syscall.IpAdapterInfo)(unsafe.Pointer(&b[0]))
-		err = syscall.GetAdaptersInfo(a, &l)
-	}
-	if err != nil {
-		return nil, os.NewSyscallError("GetAdaptersInfo", err)
-	}
-	return a, nil
-}
-
-func getInterfaceList() ([]syscall.InterfaceInfo, error) {
+func getInterfaceInfos() ([]syscall.InterfaceInfo, error) {
 	s, err := sysSocket(syscall.AF_INET, syscall.SOCK_DGRAM, syscall.IPPROTO_UDP)
 	if err != nil {
-		return nil, os.NewSyscallError("Socket", err)
+		return nil, err
 	}
-	defer syscall.Closesocket(s)
+	defer closeFunc(s)
 
-	ii := [20]syscall.InterfaceInfo{}
+	iia := [20]syscall.InterfaceInfo{}
 	ret := uint32(0)
-	size := uint32(unsafe.Sizeof(ii))
-	err = syscall.WSAIoctl(s, syscall.SIO_GET_INTERFACE_LIST, nil, 0, (*byte)(unsafe.Pointer(&ii[0])), size, &ret, nil, 0)
+	size := uint32(unsafe.Sizeof(iia))
+	err = syscall.WSAIoctl(s, syscall.SIO_GET_INTERFACE_LIST, nil, 0, (*byte)(unsafe.Pointer(&iia[0])), size, &ret, nil, 0)
 	if err != nil {
-		return nil, os.NewSyscallError("WSAIoctl", err)
+		return nil, os.NewSyscallError("wsaioctl", err)
 	}
-	c := ret / uint32(unsafe.Sizeof(ii[0]))
-	return ii[:c-1], nil
+	iilen := ret / uint32(unsafe.Sizeof(iia[0]))
+	return iia[:iilen-1], nil
+}
+
+func bytesEqualIP(a []byte, b []int8) bool {
+	for i := 0; i < len(a); i++ {
+		if a[i] != byte(b[i]) {
+			return false
+		}
+	}
+	return true
+}
+
+func findInterfaceInfo(iis []syscall.InterfaceInfo, paddr *windows.IpAdapterAddresses) *syscall.InterfaceInfo {
+	for _, ii := range iis {
+		iaddr := (*syscall.RawSockaddr)(unsafe.Pointer(&ii.Address))
+		puni := paddr.FirstUnicastAddress
+		for ; puni != nil; puni = puni.Next {
+			if iaddr.Family == puni.Address.Sockaddr.Addr.Family {
+				switch iaddr.Family {
+				case syscall.AF_INET:
+					a := (*syscall.RawSockaddrInet4)(unsafe.Pointer(&ii.Address)).Addr
+					if bytesEqualIP(a[:], puni.Address.Sockaddr.Addr.Data[2:]) {
+						return &ii
+					}
+				case syscall.AF_INET6:
+					a := (*syscall.RawSockaddrInet6)(unsafe.Pointer(&ii.Address)).Addr
+					if bytesEqualIP(a[:], puni.Address.Sockaddr.Addr.Data[2:]) {
+						return &ii
+					}
+				default:
+					continue
+				}
+			}
+		}
+	}
+	return nil
 }
 
 // If the ifindex is zero, interfaceTable returns mappings of all
 // network interfaces.  Otherwise it returns a mapping of a specific
 // interface.
 func interfaceTable(ifindex int) ([]Interface, error) {
-	ai, err := getAdapterList()
+	paddr, err := getAdapters()
 	if err != nil {
 		return nil, err
 	}
 
-	ii, err := getInterfaceList()
+	iis, err := getInterfaceInfos()
 	if err != nil {
 		return nil, err
 	}
 
 	var ift []Interface
-	for ; ai != nil; ai = ai.Next {
-		index := ai.Index
+	for ; paddr != nil; paddr = paddr.Next {
+		index := paddr.IfIndex
+		if paddr.Ipv6IfIndex != 0 {
+			index = paddr.Ipv6IfIndex
+		}
 		if ifindex == 0 || ifindex == int(index) {
+			ii := findInterfaceInfo(iis, paddr)
+			if ii == nil {
+				continue
+			}
 			var flags Flags
-
-			row := syscall.MibIfRow{Index: index}
-			e := syscall.GetIfEntry(&row)
-			if e != nil {
-				return nil, os.NewSyscallError("GetIfEntry", e)
+			if paddr.Flags&windows.IfOperStatusUp != 0 {
+				flags |= FlagUp
 			}
-
-			for _, ii := range ii {
-				ip := (*syscall.RawSockaddrInet4)(unsafe.Pointer(&ii.Address)).Addr
-				ipv4 := IPv4(ip[0], ip[1], ip[2], ip[3])
-				ipl := &ai.IpAddressList
-				for ipl != nil {
-					ips := bytePtrToString(&ipl.IpAddress.String[0])
-					if ipv4.Equal(parseIPv4(ips)) {
-						break
-					}
-					ipl = ipl.Next
-				}
-				if ipl == nil {
-					continue
-				}
-				if ii.Flags&syscall.IFF_UP != 0 {
-					flags |= FlagUp
-				}
-				if ii.Flags&syscall.IFF_LOOPBACK != 0 {
-					flags |= FlagLoopback
-				}
-				if ii.Flags&syscall.IFF_BROADCAST != 0 {
-					flags |= FlagBroadcast
-				}
-				if ii.Flags&syscall.IFF_POINTTOPOINT != 0 {
-					flags |= FlagPointToPoint
-				}
-				if ii.Flags&syscall.IFF_MULTICAST != 0 {
-					flags |= FlagMulticast
-				}
+			if paddr.IfType&windows.IF_TYPE_SOFTWARE_LOOPBACK != 0 {
+				flags |= FlagLoopback
 			}
-
-			name := bytePtrToString(&ai.AdapterName[0])
-
+			if ii.Flags&syscall.IFF_BROADCAST != 0 {
+				flags |= FlagBroadcast
+			}
+			if ii.Flags&syscall.IFF_POINTTOPOINT != 0 {
+				flags |= FlagPointToPoint
+			}
+			if ii.Flags&syscall.IFF_MULTICAST != 0 {
+				flags |= FlagMulticast
+			}
 			ifi := Interface{
 				Index:        int(index),
-				MTU:          int(row.Mtu),
-				Name:         name,
-				HardwareAddr: HardwareAddr(row.PhysAddr[:row.PhysAddrLen]),
-				Flags:        flags}
+				MTU:          int(paddr.Mtu),
+				Name:         syscall.UTF16ToString((*(*[10000]uint16)(unsafe.Pointer(paddr.FriendlyName)))[:]),
+				HardwareAddr: HardwareAddr(paddr.PhysicalAddress[:]),
+				Flags:        flags,
+			}
 			ift = append(ift, ifi)
+			if ifindex == int(ifi.Index) {
+				break
+			}
 		}
 	}
 	return ift, nil
@@ -131,28 +147,86 @@
 // network interfaces.  Otherwise it returns addresses for a specific
 // interface.
 func interfaceAddrTable(ifi *Interface) ([]Addr, error) {
-	ai, err := getAdapterList()
+	paddr, err := getAdapters()
 	if err != nil {
 		return nil, err
 	}
 
 	var ifat []Addr
-	for ; ai != nil; ai = ai.Next {
-		index := ai.Index
+	for ; paddr != nil; paddr = paddr.Next {
+		index := paddr.IfIndex
+		if paddr.Ipv6IfIndex != 0 {
+			index = paddr.Ipv6IfIndex
+		}
 		if ifi == nil || ifi.Index == int(index) {
-			ipl := &ai.IpAddressList
-			for ; ipl != nil; ipl = ipl.Next {
-				ifa := IPAddr{IP: parseIPv4(bytePtrToString(&ipl.IpAddress.String[0]))}
-				ifat = append(ifat, ifa.toAddr())
+			puni := paddr.FirstUnicastAddress
+			for ; puni != nil; puni = puni.Next {
+				if sa, err := puni.Address.Sockaddr.Sockaddr(); err == nil {
+					switch sav := sa.(type) {
+					case *syscall.SockaddrInet4:
+						ifa := &IPNet{IP: make(IP, IPv4len), Mask: CIDRMask(int(puni.Address.SockaddrLength), 8*IPv4len)}
+						copy(ifa.IP, sav.Addr[:])
+						ifat = append(ifat, ifa)
+					case *syscall.SockaddrInet6:
+						ifa := &IPNet{IP: make(IP, IPv6len), Mask: CIDRMask(int(puni.Address.SockaddrLength), 8*IPv6len)}
+						copy(ifa.IP, sav.Addr[:])
+						ifat = append(ifat, ifa)
+					}
+				}
+			}
+			pany := paddr.FirstAnycastAddress
+			for ; pany != nil; pany = pany.Next {
+				if sa, err := pany.Address.Sockaddr.Sockaddr(); err == nil {
+					switch sav := sa.(type) {
+					case *syscall.SockaddrInet4:
+						ifa := &IPNet{IP: make(IP, IPv4len), Mask: CIDRMask(int(pany.Address.SockaddrLength), 8*IPv4len)}
+						copy(ifa.IP, sav.Addr[:])
+						ifat = append(ifat, ifa)
+					case *syscall.SockaddrInet6:
+						ifa := &IPNet{IP: make(IP, IPv6len), Mask: CIDRMask(int(pany.Address.SockaddrLength), 8*IPv6len)}
+						copy(ifa.IP, sav.Addr[:])
+						ifat = append(ifat, ifa)
+					}
+				}
 			}
 		}
 	}
+
 	return ifat, nil
 }
 
 // interfaceMulticastAddrTable returns addresses for a specific
 // interface.
 func interfaceMulticastAddrTable(ifi *Interface) ([]Addr, error) {
-	// TODO(mikio): Implement this like other platforms.
-	return nil, nil
+	paddr, err := getAdapters()
+	if err != nil {
+		return nil, err
+	}
+
+	var ifat []Addr
+	for ; paddr != nil; paddr = paddr.Next {
+		index := paddr.IfIndex
+		if paddr.Ipv6IfIndex != 0 {
+			index = paddr.Ipv6IfIndex
+		}
+		if ifi == nil || ifi.Index == int(index) {
+			pmul := paddr.FirstMulticastAddress
+			for ; pmul != nil; pmul = pmul.Next {
+				if sa, err := pmul.Address.Sockaddr.Sockaddr(); err == nil {
+					switch sav := sa.(type) {
+					case *syscall.SockaddrInet4:
+						ifa := &IPAddr{IP: make(IP, IPv4len)}
+						copy(ifa.IP, sav.Addr[:])
+						ifat = append(ifat, ifa)
+					case *syscall.SockaddrInet6:
+						ifa := &IPAddr{IP: make(IP, IPv6len)}
+						copy(ifa.IP, sav.Addr[:])
+						ifat = append(ifat, ifa)
+					}
+				}
+			}
+		}
+	}
+
+	return ifat, nil
 }
diff --git a/third_party/gofrontend/libgo/go/net/internal/socktest/main_test.go b/third_party/gofrontend/libgo/go/net/internal/socktest/main_test.go
new file mode 100644
index 0000000..60e581f
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/net/internal/socktest/main_test.go
@@ -0,0 +1,56 @@
+// 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 !plan9
+
+package socktest_test
+
+import (
+	"net/internal/socktest"
+	"os"
+	"sync"
+	"syscall"
+	"testing"
+)
+
+var sw socktest.Switch
+
+func TestMain(m *testing.M) {
+	installTestHooks()
+
+	st := m.Run()
+
+	for s := range sw.Sockets() {
+		closeFunc(s)
+	}
+	uninstallTestHooks()
+	os.Exit(st)
+}
+
+func TestSwitch(t *testing.T) {
+	const N = 10
+	var wg sync.WaitGroup
+	wg.Add(N)
+	for i := 0; i < N; i++ {
+		go func() {
+			defer wg.Done()
+			for _, family := range []int{syscall.AF_INET, syscall.AF_INET6} {
+				socketFunc(family, syscall.SOCK_STREAM, syscall.IPPROTO_TCP)
+			}
+		}()
+	}
+	wg.Wait()
+}
+
+func TestSocket(t *testing.T) {
+	for _, f := range []socktest.Filter{
+		func(st *socktest.Status) (socktest.AfterFilter, error) { return nil, nil },
+		nil,
+	} {
+		sw.Set(socktest.FilterSocket, f)
+		for _, family := range []int{syscall.AF_INET, syscall.AF_INET6} {
+			socketFunc(family, syscall.SOCK_STREAM, syscall.IPPROTO_TCP)
+		}
+	}
+}
diff --git a/third_party/gofrontend/libgo/go/net/internal/socktest/main_unix_test.go b/third_party/gofrontend/libgo/go/net/internal/socktest/main_unix_test.go
new file mode 100644
index 0000000..b8eebc2
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/net/internal/socktest/main_unix_test.go
@@ -0,0 +1,24 @@
+// 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 !plan9,!windows
+
+package socktest_test
+
+import "syscall"
+
+var (
+	socketFunc func(int, int, int) (int, error)
+	closeFunc  func(int) error
+)
+
+func installTestHooks() {
+	socketFunc = sw.Socket
+	closeFunc = sw.Close
+}
+
+func uninstallTestHooks() {
+	socketFunc = syscall.Socket
+	closeFunc = syscall.Close
+}
diff --git a/third_party/gofrontend/libgo/go/net/internal/socktest/main_windows_test.go b/third_party/gofrontend/libgo/go/net/internal/socktest/main_windows_test.go
new file mode 100644
index 0000000..df1cb97
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/net/internal/socktest/main_windows_test.go
@@ -0,0 +1,22 @@
+// 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 socktest_test
+
+import "syscall"
+
+var (
+	socketFunc func(int, int, int) (syscall.Handle, error)
+	closeFunc  func(syscall.Handle) error
+)
+
+func installTestHooks() {
+	socketFunc = sw.Socket
+	closeFunc = sw.Closesocket
+}
+
+func uninstallTestHooks() {
+	socketFunc = syscall.Socket
+	closeFunc = syscall.Closesocket
+}
diff --git a/third_party/gofrontend/libgo/go/net/internal/socktest/switch.go b/third_party/gofrontend/libgo/go/net/internal/socktest/switch.go
new file mode 100644
index 0000000..4e38c7a
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/net/internal/socktest/switch.go
@@ -0,0 +1,169 @@
+// 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 socktest provides utilities for socket testing.
+package socktest
+
+import (
+	"fmt"
+	"sync"
+)
+
+// A Switch represents a callpath point switch for socket system
+// calls.
+type Switch struct {
+	once sync.Once
+
+	fmu   sync.RWMutex
+	fltab map[FilterType]Filter
+
+	smu   sync.RWMutex
+	sotab Sockets
+	stats stats
+}
+
+func (sw *Switch) init() {
+	sw.fltab = make(map[FilterType]Filter)
+	sw.sotab = make(Sockets)
+	sw.stats = make(stats)
+}
+
+// Stats returns a list of per-cookie socket statistics.
+func (sw *Switch) Stats() []Stat {
+	var st []Stat
+	sw.smu.RLock()
+	for _, s := range sw.stats {
+		ns := *s
+		st = append(st, ns)
+	}
+	sw.smu.RUnlock()
+	return st
+}
+
+// Sockets returns mappings of socket descriptor to socket status.
+func (sw *Switch) Sockets() Sockets {
+	sw.smu.RLock()
+	tab := make(Sockets, len(sw.sotab))
+	for i, s := range sw.sotab {
+		tab[i] = s
+	}
+	sw.smu.RUnlock()
+	return tab
+}
+
+// A Cookie represents a 3-tuple of a socket; address family, socket
+// type and protocol number.
+type Cookie uint64
+
+// Family returns an address family.
+func (c Cookie) Family() int { return int(c >> 48) }
+
+// Type returns a socket type.
+func (c Cookie) Type() int { return int(c << 16 >> 32) }
+
+// Protocol returns a protocol number.
+func (c Cookie) Protocol() int { return int(c & 0xff) }
+
+func cookie(family, sotype, proto int) Cookie {
+	return Cookie(family)<<48 | Cookie(sotype)&0xffffffff<<16 | Cookie(proto)&0xff
+}
+
+// A Status represents the status of a socket.
+type Status struct {
+	Cookie    Cookie
+	Err       error // error status of socket system call
+	SocketErr error // error status of socket by SO_ERROR
+}
+
+func (so Status) String() string {
+	return fmt.Sprintf("(%s, %s, %s): syscallerr=%v, socketerr=%v", familyString(so.Cookie.Family()), typeString(so.Cookie.Type()), protocolString(so.Cookie.Protocol()), so.Err, so.SocketErr)
+}
+
+// A Stat represents a per-cookie socket statistics.
+type Stat struct {
+	Family   int // address family
+	Type     int // socket type
+	Protocol int // protocol number
+
+	Opened    uint64 // number of sockets opened
+	Connected uint64 // number of sockets connected
+	Listened  uint64 // number of sockets listened
+	Accepted  uint64 // number of sockets accepted
+	Closed    uint64 // number of sockets closed
+
+	OpenFailed    uint64 // number of sockets open failed
+	ConnectFailed uint64 // number of sockets connect failed
+	ListenFailed  uint64 // number of sockets listen failed
+	AcceptFailed  uint64 // number of sockets accept failed
+	CloseFailed   uint64 // number of sockets close failed
+}
+
+func (st Stat) String() string {
+	return fmt.Sprintf("(%s, %s, %s): opened=%d, connected=%d, listened=%d, accepted=%d, closed=%d, openfailed=%d, connectfailed=%d, listenfailed=%d, acceptfailed=%d, closefailed=%d", familyString(st.Family), typeString(st.Type), protocolString(st.Protocol), st.Opened, st.Connected, st.Listened, st.Accepted, st.Closed, st.OpenFailed, st.ConnectFailed, st.ListenFailed, st.AcceptFailed, st.CloseFailed)
+}
+
+type stats map[Cookie]*Stat
+
+func (st stats) getLocked(c Cookie) *Stat {
+	s, ok := st[c]
+	if !ok {
+		s = &Stat{Family: c.Family(), Type: c.Type(), Protocol: c.Protocol()}
+		st[c] = s
+	}
+	return s
+}
+
+// A FilterType represents a filter type.
+type FilterType int
+
+const (
+	FilterSocket        FilterType = iota // for Socket
+	FilterConnect                         // for Connect or ConnectEx
+	FilterListen                          // for Listen
+	FilterAccept                          // for Accept or Accept4
+	FilterGetsockoptInt                   // for GetsockoptInt
+	FilterClose                           // for Close or Closesocket
+)
+
+// A Filter represents a socket system call filter.
+//
+// It will only be executed before a system call for a socket that has
+// an entry in internal table.
+// If the filter returns a non-nil error, the execution of system call
+// will be canceled and the system call function returns the non-nil
+// error.
+// It can return a non-nil AfterFilter for filtering after the
+// execution of the system call.
+type Filter func(*Status) (AfterFilter, error)
+
+func (f Filter) apply(st *Status) (AfterFilter, error) {
+	if f == nil {
+		return nil, nil
+	}
+	return f(st)
+}
+
+// An AfterFilter represents a socket system call filter after an
+// execution of a system call.
+//
+// It will only be executed after a system call for a socket that has
+// an entry in internal table.
+// If the filter returns a non-nil error, the system call function
+// returns the non-nil error.
+type AfterFilter func(*Status) error
+
+func (f AfterFilter) apply(st *Status) error {
+	if f == nil {
+		return nil
+	}
+	return f(st)
+}
+
+// Set deploys the socket system call filter f for the filter type t.
+func (sw *Switch) Set(t FilterType, f Filter) {
+	sw.once.Do(sw.init)
+	sw.fmu.Lock()
+	sw.fltab[t] = f
+	sw.fmu.Unlock()
+}
diff --git a/third_party/gofrontend/libgo/go/net/internal/socktest/switch_posix.go b/third_party/gofrontend/libgo/go/net/internal/socktest/switch_posix.go
new file mode 100644
index 0000000..863edef
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/net/internal/socktest/switch_posix.go
@@ -0,0 +1,58 @@
+// 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 !plan9
+
+package socktest
+
+import (
+	"fmt"
+	"syscall"
+)
+
+func familyString(family int) string {
+	switch family {
+	case syscall.AF_INET:
+		return "inet4"
+	case syscall.AF_INET6:
+		return "inet6"
+	case syscall.AF_UNIX:
+		return "local"
+	default:
+		return fmt.Sprintf("%d", family)
+	}
+}
+
+func typeString(sotype int) string {
+	var s string
+	switch sotype & 0xff {
+	case syscall.SOCK_STREAM:
+		s = "stream"
+	case syscall.SOCK_DGRAM:
+		s = "datagram"
+	case syscall.SOCK_RAW:
+		s = "raw"
+	case syscall.SOCK_SEQPACKET:
+		s = "seqpacket"
+	default:
+		s = fmt.Sprintf("%d", sotype&0xff)
+	}
+	if flags := uint(sotype) & ^uint(0xff); flags != 0 {
+		s += fmt.Sprintf("|%#x", flags)
+	}
+	return s
+}
+
+func protocolString(proto int) string {
+	switch proto {
+	case 0:
+		return "default"
+	case syscall.IPPROTO_TCP:
+		return "tcp"
+	case syscall.IPPROTO_UDP:
+		return "udp"
+	default:
+		return fmt.Sprintf("%d", proto)
+	}
+}
diff --git a/third_party/gofrontend/libgo/go/net/internal/socktest/switch_stub.go b/third_party/gofrontend/libgo/go/net/internal/socktest/switch_stub.go
new file mode 100644
index 0000000..28ce72c
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/net/internal/socktest/switch_stub.go
@@ -0,0 +1,16 @@
+// 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 plan9
+
+package socktest
+
+// Sockets maps a socket descriptor to the status of socket.
+type Sockets map[int]Status
+
+func familyString(family int) string { return "<nil>" }
+
+func typeString(sotype int) string { return "<nil>" }
+
+func protocolString(proto int) string { return "<nil>" }
diff --git a/third_party/gofrontend/libgo/go/net/internal/socktest/switch_unix.go b/third_party/gofrontend/libgo/go/net/internal/socktest/switch_unix.go
new file mode 100644
index 0000000..14c0c22
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/net/internal/socktest/switch_unix.go
@@ -0,0 +1,29 @@
+// 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 darwin dragonfly freebsd linux nacl netbsd openbsd solaris
+
+package socktest
+
+// Sockets maps a socket descriptor to the status of socket.
+type Sockets map[int]Status
+
+func (sw *Switch) sockso(s int) *Status {
+	sw.smu.RLock()
+	defer sw.smu.RUnlock()
+	so, ok := sw.sotab[s]
+	if !ok {
+		return nil
+	}
+	return &so
+}
+
+// addLocked returns a new Status without locking.
+// sw.smu must be held before call.
+func (sw *Switch) addLocked(s, family, sotype, proto int) *Status {
+	sw.once.Do(sw.init)
+	so := Status{Cookie: cookie(family, sotype, proto)}
+	sw.sotab[s] = so
+	return &so
+}
diff --git a/third_party/gofrontend/libgo/go/net/internal/socktest/switch_windows.go b/third_party/gofrontend/libgo/go/net/internal/socktest/switch_windows.go
new file mode 100644
index 0000000..4f1d597
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/net/internal/socktest/switch_windows.go
@@ -0,0 +1,29 @@
+// 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 socktest
+
+import "syscall"
+
+// Sockets maps a socket descriptor to the status of socket.
+type Sockets map[syscall.Handle]Status
+
+func (sw *Switch) sockso(s syscall.Handle) *Status {
+	sw.smu.RLock()
+	defer sw.smu.RUnlock()
+	so, ok := sw.sotab[s]
+	if !ok {
+		return nil
+	}
+	return &so
+}
+
+// addLocked returns a new Status without locking.
+// sw.smu must be held before call.
+func (sw *Switch) addLocked(s syscall.Handle, family, sotype, proto int) *Status {
+	sw.once.Do(sw.init)
+	so := Status{Cookie: cookie(family, sotype, proto)}
+	sw.sotab[s] = so
+	return &so
+}
diff --git a/third_party/gofrontend/libgo/go/net/internal/socktest/sys_cloexec.go b/third_party/gofrontend/libgo/go/net/internal/socktest/sys_cloexec.go
new file mode 100644
index 0000000..340ff07
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/net/internal/socktest/sys_cloexec.go
@@ -0,0 +1,42 @@
+// 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 freebsd linux
+
+package socktest
+
+import "syscall"
+
+// Accept4 wraps syscall.Accept4.
+func (sw *Switch) Accept4(s, flags int) (ns int, sa syscall.Sockaddr, err error) {
+	so := sw.sockso(s)
+	if so == nil {
+		return syscall.Accept4(s, flags)
+	}
+	sw.fmu.RLock()
+	f, _ := sw.fltab[FilterAccept]
+	sw.fmu.RUnlock()
+
+	af, err := f.apply(so)
+	if err != nil {
+		return -1, nil, err
+	}
+	ns, sa, so.Err = syscall.Accept4(s, flags)
+	if err = af.apply(so); err != nil {
+		if so.Err == nil {
+			syscall.Close(ns)
+		}
+		return -1, nil, err
+	}
+
+	sw.smu.Lock()
+	defer sw.smu.Unlock()
+	if so.Err != nil {
+		sw.stats.getLocked(so.Cookie).AcceptFailed++
+		return -1, nil, so.Err
+	}
+	nso := sw.addLocked(ns, so.Cookie.Family(), so.Cookie.Type(), so.Cookie.Protocol())
+	sw.stats.getLocked(nso.Cookie).Accepted++
+	return ns, sa, nil
+}
diff --git a/third_party/gofrontend/libgo/go/net/internal/socktest/sys_unix.go b/third_party/gofrontend/libgo/go/net/internal/socktest/sys_unix.go
new file mode 100644
index 0000000..f983e26
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/net/internal/socktest/sys_unix.go
@@ -0,0 +1,193 @@
+// 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 darwin dragonfly freebsd linux nacl netbsd openbsd solaris
+
+package socktest
+
+import "syscall"
+
+// Socket wraps syscall.Socket.
+func (sw *Switch) Socket(family, sotype, proto int) (s int, err error) {
+	sw.once.Do(sw.init)
+
+	so := &Status{Cookie: cookie(family, sotype, proto)}
+	sw.fmu.RLock()
+	f, _ := sw.fltab[FilterSocket]
+	sw.fmu.RUnlock()
+
+	af, err := f.apply(so)
+	if err != nil {
+		return -1, err
+	}
+	s, so.Err = syscall.Socket(family, sotype, proto)
+	if err = af.apply(so); err != nil {
+		if so.Err == nil {
+			syscall.Close(s)
+		}
+		return -1, err
+	}
+
+	sw.smu.Lock()
+	defer sw.smu.Unlock()
+	if so.Err != nil {
+		sw.stats.getLocked(so.Cookie).OpenFailed++
+		return -1, so.Err
+	}
+	nso := sw.addLocked(s, family, sotype, proto)
+	sw.stats.getLocked(nso.Cookie).Opened++
+	return s, nil
+}
+
+// Close wraps syscall.Close.
+func (sw *Switch) Close(s int) (err error) {
+	so := sw.sockso(s)
+	if so == nil {
+		return syscall.Close(s)
+	}
+	sw.fmu.RLock()
+	f, _ := sw.fltab[FilterClose]
+	sw.fmu.RUnlock()
+
+	af, err := f.apply(so)
+	if err != nil {
+		return err
+	}
+	so.Err = syscall.Close(s)
+	if err = af.apply(so); err != nil {
+		return err
+	}
+
+	sw.smu.Lock()
+	defer sw.smu.Unlock()
+	if so.Err != nil {
+		sw.stats.getLocked(so.Cookie).CloseFailed++
+		return so.Err
+	}
+	delete(sw.sotab, s)
+	sw.stats.getLocked(so.Cookie).Closed++
+	return nil
+}
+
+// Connect wraps syscall.Connect.
+func (sw *Switch) Connect(s int, sa syscall.Sockaddr) (err error) {
+	so := sw.sockso(s)
+	if so == nil {
+		return syscall.Connect(s, sa)
+	}
+	sw.fmu.RLock()
+	f, _ := sw.fltab[FilterConnect]
+	sw.fmu.RUnlock()
+
+	af, err := f.apply(so)
+	if err != nil {
+		return err
+	}
+	so.Err = syscall.Connect(s, sa)
+	if err = af.apply(so); err != nil {
+		return err
+	}
+
+	sw.smu.Lock()
+	defer sw.smu.Unlock()
+	if so.Err != nil {
+		sw.stats.getLocked(so.Cookie).ConnectFailed++
+		return so.Err
+	}
+	sw.stats.getLocked(so.Cookie).Connected++
+	return nil
+}
+
+// Listen wraps syscall.Listen.
+func (sw *Switch) Listen(s, backlog int) (err error) {
+	so := sw.sockso(s)
+	if so == nil {
+		return syscall.Listen(s, backlog)
+	}
+	sw.fmu.RLock()
+	f, _ := sw.fltab[FilterListen]
+	sw.fmu.RUnlock()
+
+	af, err := f.apply(so)
+	if err != nil {
+		return err
+	}
+	so.Err = syscall.Listen(s, backlog)
+	if err = af.apply(so); err != nil {
+		return err
+	}
+
+	sw.smu.Lock()
+	defer sw.smu.Unlock()
+	if so.Err != nil {
+		sw.stats.getLocked(so.Cookie).ListenFailed++
+		return so.Err
+	}
+	sw.stats.getLocked(so.Cookie).Listened++
+	return nil
+}
+
+// Accept wraps syscall.Accept.
+func (sw *Switch) Accept(s int) (ns int, sa syscall.Sockaddr, err error) {
+	so := sw.sockso(s)
+	if so == nil {
+		return syscall.Accept(s)
+	}
+	sw.fmu.RLock()
+	f, _ := sw.fltab[FilterAccept]
+	sw.fmu.RUnlock()
+
+	af, err := f.apply(so)
+	if err != nil {
+		return -1, nil, err
+	}
+	ns, sa, so.Err = syscall.Accept(s)
+	if err = af.apply(so); err != nil {
+		if so.Err == nil {
+			syscall.Close(ns)
+		}
+		return -1, nil, err
+	}
+
+	sw.smu.Lock()
+	defer sw.smu.Unlock()
+	if so.Err != nil {
+		sw.stats.getLocked(so.Cookie).AcceptFailed++
+		return -1, nil, so.Err
+	}
+	nso := sw.addLocked(ns, so.Cookie.Family(), so.Cookie.Type(), so.Cookie.Protocol())
+	sw.stats.getLocked(nso.Cookie).Accepted++
+	return ns, sa, nil
+}
+
+// GetsockoptInt wraps syscall.GetsockoptInt.
+func (sw *Switch) GetsockoptInt(s, level, opt int) (soerr int, err error) {
+	so := sw.sockso(s)
+	if so == nil {
+		return syscall.GetsockoptInt(s, level, opt)
+	}
+	sw.fmu.RLock()
+	f, _ := sw.fltab[FilterGetsockoptInt]
+	sw.fmu.RUnlock()
+
+	af, err := f.apply(so)
+	if err != nil {
+		return -1, err
+	}
+	soerr, so.Err = syscall.GetsockoptInt(s, level, opt)
+	so.SocketErr = syscall.Errno(soerr)
+	if err = af.apply(so); err != nil {
+		return -1, err
+	}
+
+	if so.Err != nil {
+		return -1, so.Err
+	}
+	if opt == syscall.SO_ERROR && (so.SocketErr == syscall.Errno(0) || so.SocketErr == syscall.EISCONN) {
+		sw.smu.Lock()
+		sw.stats.getLocked(so.Cookie).Connected++
+		sw.smu.Unlock()
+	}
+	return soerr, nil
+}
diff --git a/third_party/gofrontend/libgo/go/net/internal/socktest/sys_windows.go b/third_party/gofrontend/libgo/go/net/internal/socktest/sys_windows.go
new file mode 100644
index 0000000..e61bf2b
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/net/internal/socktest/sys_windows.go
@@ -0,0 +1,156 @@
+// 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 socktest
+
+import "syscall"
+
+// Socket wraps syscall.Socket.
+func (sw *Switch) Socket(family, sotype, proto int) (s syscall.Handle, err error) {
+	sw.once.Do(sw.init)
+
+	so := &Status{Cookie: cookie(family, sotype, proto)}
+	sw.fmu.RLock()
+	f, _ := sw.fltab[FilterSocket]
+	sw.fmu.RUnlock()
+
+	af, err := f.apply(so)
+	if err != nil {
+		return syscall.InvalidHandle, err
+	}
+	s, so.Err = syscall.Socket(family, sotype, proto)
+	if err = af.apply(so); err != nil {
+		if so.Err == nil {
+			syscall.Closesocket(s)
+		}
+		return syscall.InvalidHandle, err
+	}
+
+	sw.smu.Lock()
+	defer sw.smu.Unlock()
+	if so.Err != nil {
+		sw.stats.getLocked(so.Cookie).OpenFailed++
+		return syscall.InvalidHandle, so.Err
+	}
+	nso := sw.addLocked(s, family, sotype, proto)
+	sw.stats.getLocked(nso.Cookie).Opened++
+	return s, nil
+}
+
+// Closesocket wraps syscall.Closesocket.
+func (sw *Switch) Closesocket(s syscall.Handle) (err error) {
+	so := sw.sockso(s)
+	if so == nil {
+		return syscall.Closesocket(s)
+	}
+	sw.fmu.RLock()
+	f, _ := sw.fltab[FilterClose]
+	sw.fmu.RUnlock()
+
+	af, err := f.apply(so)
+	if err != nil {
+		return err
+	}
+	so.Err = syscall.Closesocket(s)
+	if err = af.apply(so); err != nil {
+		return err
+	}
+
+	sw.smu.Lock()
+	defer sw.smu.Unlock()
+	if so.Err != nil {
+		sw.stats.getLocked(so.Cookie).CloseFailed++
+		return so.Err
+	}
+	delete(sw.sotab, s)
+	sw.stats.getLocked(so.Cookie).Closed++
+	return nil
+}
+
+// Connect wraps syscall.Connect.
+func (sw *Switch) Connect(s syscall.Handle, sa syscall.Sockaddr) (err error) {
+	so := sw.sockso(s)
+	if so == nil {
+		return syscall.Connect(s, sa)
+	}
+	sw.fmu.RLock()
+	f, _ := sw.fltab[FilterConnect]
+	sw.fmu.RUnlock()
+
+	af, err := f.apply(so)
+	if err != nil {
+		return err
+	}
+	so.Err = syscall.Connect(s, sa)
+	if err = af.apply(so); err != nil {
+		return err
+	}
+
+	sw.smu.Lock()
+	defer sw.smu.Unlock()
+	if so.Err != nil {
+		sw.stats.getLocked(so.Cookie).ConnectFailed++
+		return so.Err
+	}
+	sw.stats.getLocked(so.Cookie).Connected++
+	return nil
+}
+
+// ConnectEx wraps syscall.ConnectEx.
+func (sw *Switch) ConnectEx(s syscall.Handle, sa syscall.Sockaddr, b *byte, n uint32, nwr *uint32, o *syscall.Overlapped) (err error) {
+	so := sw.sockso(s)
+	if so == nil {
+		return syscall.ConnectEx(s, sa, b, n, nwr, o)
+	}
+	sw.fmu.RLock()
+	f, _ := sw.fltab[FilterConnect]
+	sw.fmu.RUnlock()
+
+	af, err := f.apply(so)
+	if err != nil {
+		return err
+	}
+	so.Err = syscall.ConnectEx(s, sa, b, n, nwr, o)
+	if err = af.apply(so); err != nil {
+		return err
+	}
+
+	sw.smu.Lock()
+	defer sw.smu.Unlock()
+	if so.Err != nil {
+		sw.stats.getLocked(so.Cookie).ConnectFailed++
+		return so.Err
+	}
+	sw.stats.getLocked(so.Cookie).Connected++
+	return nil
+}
+
+// Listen wraps syscall.Listen.
+func (sw *Switch) Listen(s syscall.Handle, backlog int) (err error) {
+	so := sw.sockso(s)
+	if so == nil {
+		return syscall.Listen(s, backlog)
+	}
+	sw.fmu.RLock()
+	f, _ := sw.fltab[FilterListen]
+	sw.fmu.RUnlock()
+
+	af, err := f.apply(so)
+	if err != nil {
+		return err
+	}
+	so.Err = syscall.Listen(s, backlog)
+	if err = af.apply(so); err != nil {
+		return err
+	}
+
+	sw.smu.Lock()
+	defer sw.smu.Unlock()
+	if so.Err != nil {
+		sw.stats.getLocked(so.Cookie).ListenFailed++
+		return so.Err
+	}
+	sw.stats.getLocked(so.Cookie).Listened++
+	return nil
+}
diff --git a/third_party/gofrontend/libgo/go/net/ip.go b/third_party/gofrontend/libgo/go/net/ip.go
index 4a93e97..cc004d6 100644
--- a/third_party/gofrontend/libgo/go/net/ip.go
+++ b/third_party/gofrontend/libgo/go/net/ip.go
@@ -12,8 +12,6 @@
 
 package net
 
-import "errors"
-
 // IP address lengths (bytes).
 const (
 	IPv4len = 4
@@ -108,58 +106,57 @@
 	IPv6linklocalallrouters    = IP{0xff, 0x02, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x02}
 )
 
-// IsUnspecified returns true if ip is an unspecified address.
+// IsUnspecified reports whether ip is an unspecified address.
 func (ip IP) IsUnspecified() bool {
-	if ip.Equal(IPv4zero) || ip.Equal(IPv6unspecified) {
-		return true
-	}
-	return false
+	return ip.Equal(IPv4zero) || ip.Equal(IPv6unspecified)
 }
 
-// IsLoopback returns true if ip is a loopback address.
+// IsLoopback reports whether ip is a loopback address.
 func (ip IP) IsLoopback() bool {
-	if ip4 := ip.To4(); ip4 != nil && ip4[0] == 127 {
-		return true
+	if ip4 := ip.To4(); ip4 != nil {
+		return ip4[0] == 127
 	}
 	return ip.Equal(IPv6loopback)
 }
 
-// IsMulticast returns true if ip is a multicast address.
+// IsMulticast reports whether ip is a multicast address.
 func (ip IP) IsMulticast() bool {
-	if ip4 := ip.To4(); ip4 != nil && ip4[0]&0xf0 == 0xe0 {
-		return true
+	if ip4 := ip.To4(); ip4 != nil {
+		return ip4[0]&0xf0 == 0xe0
 	}
-	return ip[0] == 0xff
+	return len(ip) == IPv6len && ip[0] == 0xff
 }
 
-// IsInterfaceLinkLocalMulticast returns true if ip is
+// IsInterfaceLocalMulticast reports whether ip is
 // an interface-local multicast address.
 func (ip IP) IsInterfaceLocalMulticast() bool {
 	return len(ip) == IPv6len && ip[0] == 0xff && ip[1]&0x0f == 0x01
 }
 
-// IsLinkLocalMulticast returns true if ip is a link-local
+// IsLinkLocalMulticast reports whether ip is a link-local
 // multicast address.
 func (ip IP) IsLinkLocalMulticast() bool {
-	if ip4 := ip.To4(); ip4 != nil && ip4[0] == 224 && ip4[1] == 0 && ip4[2] == 0 {
-		return true
+	if ip4 := ip.To4(); ip4 != nil {
+		return ip4[0] == 224 && ip4[1] == 0 && ip4[2] == 0
 	}
-	return ip[0] == 0xff && ip[1]&0x0f == 0x02
+	return len(ip) == IPv6len && ip[0] == 0xff && ip[1]&0x0f == 0x02
 }
 
-// IsLinkLocalUnicast returns true if ip is a link-local
+// IsLinkLocalUnicast reports whether ip is a link-local
 // unicast address.
 func (ip IP) IsLinkLocalUnicast() bool {
-	if ip4 := ip.To4(); ip4 != nil && ip4[0] == 169 && ip4[1] == 254 {
-		return true
+	if ip4 := ip.To4(); ip4 != nil {
+		return ip4[0] == 169 && ip4[1] == 254
 	}
-	return ip[0] == 0xfe && ip[1]&0xc0 == 0x80
+	return len(ip) == IPv6len && ip[0] == 0xfe && ip[1]&0xc0 == 0x80
 }
 
-// IsGlobalUnicast returns true if ip is a global unicast
+// IsGlobalUnicast reports whether ip is a global unicast
 // address.
 func (ip IP) IsGlobalUnicast() bool {
-	return !ip.IsUnspecified() &&
+	return (len(ip) == IPv4len || len(ip) == IPv6len) &&
+		!ip.Equal(IPv4bcast) &&
+		!ip.IsUnspecified() &&
 		!ip.IsLoopback() &&
 		!ip.IsMulticast() &&
 		!ip.IsLinkLocalUnicast()
@@ -267,10 +264,10 @@
 
 	// If IPv4, use dotted notation.
 	if p4 := p.To4(); len(p4) == IPv4len {
-		return itod(uint(p4[0])) + "." +
-			itod(uint(p4[1])) + "." +
-			itod(uint(p4[2])) + "." +
-			itod(uint(p4[3]))
+		return uitoa(uint(p4[0])) + "." +
+			uitoa(uint(p4[1])) + "." +
+			uitoa(uint(p4[2])) + "." +
+			uitoa(uint(p4[3]))
 	}
 	if len(p) != IPv6len {
 		return "?"
@@ -331,7 +328,7 @@
 		return []byte(""), nil
 	}
 	if len(ip) != IPv4len && len(ip) != IPv6len {
-		return nil, errors.New("invalid IP address")
+		return nil, &AddrError{Err: "invalid IP address", Addr: ip.String()}
 	}
 	return []byte(ip.String()), nil
 }
@@ -346,13 +343,13 @@
 	s := string(text)
 	x := ParseIP(s)
 	if x == nil {
-		return &ParseError{"IP address", s}
+		return &ParseError{Type: "IP address", Text: s}
 	}
 	*ip = x
 	return nil
 }
 
-// Equal returns true if ip and x are the same IP address.
+// Equal reports whether ip and x are the same IP address.
 // An IPv4 address and that same address in IPv6 form are
 // considered to be equal.
 func (ip IP) Equal(x IP) bool {
@@ -491,7 +488,7 @@
 	if l == -1 {
 		return nn.String() + "/" + m.String()
 	}
-	return nn.String() + "/" + itod(uint(l))
+	return nn.String() + "/" + uitoa(uint(l))
 }
 
 // Parse IPv4 address (d.d.d.d).
@@ -633,16 +630,6 @@
 	return ip, zone
 }
 
-// A ParseError represents a malformed text string and the type of string that was expected.
-type ParseError struct {
-	Type string
-	Text string
-}
-
-func (e *ParseError) Error() string {
-	return "invalid " + e.Type + ": " + e.Text
-}
-
 // ParseIP parses s as an IP address, returning the result.
 // The string s can be in dotted decimal ("74.125.19.99")
 // or IPv6 ("2001:4860:0:2001::68") form.
@@ -671,7 +658,7 @@
 func ParseCIDR(s string) (IP, *IPNet, error) {
 	i := byteIndex(s, '/')
 	if i < 0 {
-		return nil, nil, &ParseError{"CIDR address", s}
+		return nil, nil, &ParseError{Type: "CIDR address", Text: s}
 	}
 	addr, mask := s[:i], s[i+1:]
 	iplen := IPv4len
@@ -682,7 +669,7 @@
 	}
 	n, i, ok := dtoi(mask, 0)
 	if ip == nil || !ok || i != len(mask) || n < 0 || n > 8*iplen {
-		return nil, nil, &ParseError{"CIDR address", s}
+		return nil, nil, &ParseError{Type: "CIDR address", Text: s}
 	}
 	m := CIDRMask(n, 8*iplen)
 	return ip, &IPNet{IP: ip.Mask(m), Mask: m}, nil
diff --git a/third_party/gofrontend/libgo/go/net/ip_test.go b/third_party/gofrontend/libgo/go/net/ip_test.go
index 485ff51..3d95a73 100644
--- a/third_party/gofrontend/libgo/go/net/ip_test.go
+++ b/third_party/gofrontend/libgo/go/net/ip_test.go
@@ -16,12 +16,20 @@
 }{
 	{"127.0.1.2", IPv4(127, 0, 1, 2)},
 	{"127.0.0.1", IPv4(127, 0, 0, 1)},
+	{"127.001.002.003", IPv4(127, 1, 2, 3)},
+	{"::ffff:127.1.2.3", IPv4(127, 1, 2, 3)},
+	{"::ffff:127.001.002.003", IPv4(127, 1, 2, 3)},
+	{"::ffff:7f01:0203", IPv4(127, 1, 2, 3)},
+	{"0:0:0:0:0000:ffff:127.1.2.3", IPv4(127, 1, 2, 3)},
+	{"0:0:0:0:000000:ffff:127.1.2.3", IPv4(127, 1, 2, 3)},
+	{"0:0:0:0::ffff:127.1.2.3", IPv4(127, 1, 2, 3)},
+
+	{"2001:4860:0:2001::68", IP{0x20, 0x01, 0x48, 0x60, 0, 0, 0x20, 0x01, 0, 0, 0, 0, 0, 0, 0x00, 0x68}},
+	{"2001:4860:0000:2001:0000:0000:0000:0068", IP{0x20, 0x01, 0x48, 0x60, 0, 0, 0x20, 0x01, 0, 0, 0, 0, 0, 0, 0x00, 0x68}},
+
 	{"127.0.0.256", nil},
 	{"abc", nil},
 	{"123:", nil},
-	{"::ffff:127.0.0.1", IPv4(127, 0, 0, 1)},
-	{"2001:4860:0:2001::68", IP{0x20, 0x01, 0x48, 0x60, 0, 0, 0x20, 0x01, 0, 0, 0, 0, 0, 0, 0x00, 0x68}},
-	{"::ffff:4a7d:1363", IPv4(74, 125, 19, 99)},
 	{"fe80::1%lo0", nil},
 	{"fe80::1%911", nil},
 	{"", nil},
@@ -44,7 +52,52 @@
 	}
 }
 
+func TestLookupWithIP(t *testing.T) {
+	_, err := LookupIP("")
+	if err == nil {
+		t.Errorf(`LookupIP("") succeeded, should fail`)
+	}
+	_, err = LookupHost("")
+	if err == nil {
+		t.Errorf(`LookupIP("") succeeded, should fail`)
+	}
+
+	// Test that LookupHost and LookupIP, which normally
+	// expect host names, work with IP addresses.
+	for _, tt := range parseIPTests {
+		if tt.out != nil {
+			addrs, err := LookupHost(tt.in)
+			if len(addrs) != 1 || addrs[0] != tt.in || err != nil {
+				t.Errorf("LookupHost(%q) = %v, %v, want %v, nil", tt.in, addrs, err, []string{tt.in})
+			}
+		} else if !testing.Short() {
+			// We can't control what the host resolver does; if it can resolve, say,
+			// 127.0.0.256 or fe80::1%911 or a host named 'abc', who are we to judge?
+			// Warn about these discrepancies but don't fail the test.
+			addrs, err := LookupHost(tt.in)
+			if err == nil {
+				t.Logf("warning: LookupHost(%q) = %v, want error", tt.in, addrs)
+			}
+		}
+
+		if tt.out != nil {
+			ips, err := LookupIP(tt.in)
+			if len(ips) != 1 || !reflect.DeepEqual(ips[0], tt.out) || err != nil {
+				t.Errorf("LookupIP(%q) = %v, %v, want %v, nil", tt.in, ips, err, []IP{tt.out})
+			}
+		} else if !testing.Short() {
+			ips, err := LookupIP(tt.in)
+			// We can't control what the host resolver does. See above.
+			if err == nil {
+				t.Logf("warning: LookupIP(%q) = %v, want error", tt.in, ips)
+			}
+		}
+	}
+}
+
 func BenchmarkParseIP(b *testing.B) {
+	testHookUninstaller.Do(uninstallTestHooks)
+
 	for i := 0; i < b.N; i++ {
 		for _, tt := range parseIPTests {
 			ParseIP(tt.in)
@@ -100,6 +153,8 @@
 }
 
 func BenchmarkIPString(b *testing.B) {
+	testHookUninstaller.Do(uninstallTestHooks)
+
 	for i := 0; i < b.N; i++ {
 		for _, tt := range ipStringTests {
 			if tt.in != nil {
@@ -150,6 +205,8 @@
 }
 
 func BenchmarkIPMaskString(b *testing.B) {
+	testHookUninstaller.Do(uninstallTestHooks)
+
 	for i := 0; i < b.N; i++ {
 		for _, tt := range ipMaskStringTests {
 			tt.in.String()
@@ -180,10 +237,10 @@
 	{"abcd:2345::/24", ParseIP("abcd:2345::"), &IPNet{IP: ParseIP("abcd:2300::"), Mask: IPMask(ParseIP("ffff:ff00::"))}, nil},
 	{"2001:DB8::/48", ParseIP("2001:DB8::"), &IPNet{IP: ParseIP("2001:DB8::"), Mask: IPMask(ParseIP("ffff:ffff:ffff::"))}, nil},
 	{"2001:DB8::1/48", ParseIP("2001:DB8::1"), &IPNet{IP: ParseIP("2001:DB8::"), Mask: IPMask(ParseIP("ffff:ffff:ffff::"))}, nil},
-	{"192.168.1.1/255.255.255.0", nil, nil, &ParseError{"CIDR address", "192.168.1.1/255.255.255.0"}},
-	{"192.168.1.1/35", nil, nil, &ParseError{"CIDR address", "192.168.1.1/35"}},
-	{"2001:db8::1/-1", nil, nil, &ParseError{"CIDR address", "2001:db8::1/-1"}},
-	{"", nil, nil, &ParseError{"CIDR address", ""}},
+	{"192.168.1.1/255.255.255.0", nil, nil, &ParseError{Type: "CIDR address", Text: "192.168.1.1/255.255.255.0"}},
+	{"192.168.1.1/35", nil, nil, &ParseError{Type: "CIDR address", Text: "192.168.1.1/35"}},
+	{"2001:db8::1/-1", nil, nil, &ParseError{Type: "CIDR address", Text: "2001:db8::1/-1"}},
+	{"", nil, nil, &ParseError{Type: "CIDR address", Text: ""}},
 }
 
 func TestParseCIDR(t *testing.T) {
@@ -425,31 +482,44 @@
 	{IP.IsUnspecified, IPv4(127, 0, 0, 1), false},
 	{IP.IsUnspecified, IPv6unspecified, true},
 	{IP.IsUnspecified, IPv6interfacelocalallnodes, false},
+	{IP.IsUnspecified, nil, false},
 	{IP.IsLoopback, IPv4(127, 0, 0, 1), true},
 	{IP.IsLoopback, IPv4(127, 255, 255, 254), true},
 	{IP.IsLoopback, IPv4(128, 1, 2, 3), false},
 	{IP.IsLoopback, IPv6loopback, true},
 	{IP.IsLoopback, IPv6linklocalallrouters, false},
+	{IP.IsLoopback, nil, false},
 	{IP.IsMulticast, IPv4(224, 0, 0, 0), true},
 	{IP.IsMulticast, IPv4(239, 0, 0, 0), true},
 	{IP.IsMulticast, IPv4(240, 0, 0, 0), false},
 	{IP.IsMulticast, IPv6linklocalallnodes, true},
 	{IP.IsMulticast, IP{0xff, 0x05, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, true},
 	{IP.IsMulticast, IP{0xfe, 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, false},
+	{IP.IsMulticast, nil, false},
+	{IP.IsInterfaceLocalMulticast, IPv4(224, 0, 0, 0), false},
+	{IP.IsInterfaceLocalMulticast, IPv4(0xff, 0x01, 0, 0), false},
+	{IP.IsInterfaceLocalMulticast, IPv6interfacelocalallnodes, true},
+	{IP.IsInterfaceLocalMulticast, nil, false},
 	{IP.IsLinkLocalMulticast, IPv4(224, 0, 0, 0), true},
 	{IP.IsLinkLocalMulticast, IPv4(239, 0, 0, 0), false},
+	{IP.IsLinkLocalMulticast, IPv4(0xff, 0x02, 0, 0), false},
 	{IP.IsLinkLocalMulticast, IPv6linklocalallrouters, true},
 	{IP.IsLinkLocalMulticast, IP{0xff, 0x05, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, false},
+	{IP.IsLinkLocalMulticast, nil, false},
 	{IP.IsLinkLocalUnicast, IPv4(169, 254, 0, 0), true},
 	{IP.IsLinkLocalUnicast, IPv4(169, 255, 0, 0), false},
+	{IP.IsLinkLocalUnicast, IPv4(0xfe, 0x80, 0, 0), false},
 	{IP.IsLinkLocalUnicast, IP{0xfe, 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, true},
 	{IP.IsLinkLocalUnicast, IP{0xfe, 0xc0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, false},
+	{IP.IsLinkLocalUnicast, nil, false},
 	{IP.IsGlobalUnicast, IPv4(240, 0, 0, 0), true},
 	{IP.IsGlobalUnicast, IPv4(232, 0, 0, 0), false},
 	{IP.IsGlobalUnicast, IPv4(169, 254, 0, 0), false},
+	{IP.IsGlobalUnicast, IPv4bcast, false},
 	{IP.IsGlobalUnicast, IP{0x20, 0x1, 0xd, 0xb8, 0, 0, 0, 0, 0, 0, 0x1, 0x23, 0, 0x12, 0, 0x1}, true},
 	{IP.IsGlobalUnicast, IP{0xfe, 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, false},
 	{IP.IsGlobalUnicast, IP{0xff, 0x05, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, false},
+	{IP.IsGlobalUnicast, nil, false},
 }
 
 func name(f interface{}) string {
@@ -461,5 +531,12 @@
 		if ok := tt.scope(tt.in); ok != tt.ok {
 			t.Errorf("%s(%q) = %v, want %v", name(tt.scope), tt.in, ok, tt.ok)
 		}
+		ip := tt.in.To4()
+		if ip == nil {
+			continue
+		}
+		if ok := tt.scope(ip); ok != tt.ok {
+			t.Errorf("%s(%q) = %v, want %v", name(tt.scope), ip, ok, tt.ok)
+		}
 	}
 }
diff --git a/third_party/gofrontend/libgo/go/net/ipraw_test.go b/third_party/gofrontend/libgo/go/net/ipraw_test.go
index 92dc8dc..5d86a9d 100644
--- a/third_party/gofrontend/libgo/go/net/ipraw_test.go
+++ b/third_party/gofrontend/libgo/go/net/ipraw_test.go
@@ -5,17 +5,18 @@
 package net
 
 import (
-	"bytes"
-	"fmt"
-	"os"
 	"reflect"
-	"runtime"
 	"testing"
-	"time"
 )
 
+// The full stack test cases for IPConn have been moved to the
+// following:
+//	golang.org/x/net/ipv4
+//	golang.org/x/net/ipv6
+//	golang.org/x/net/icmp
+
 type resolveIPAddrTest struct {
-	net           string
+	network       string
 	litAddrOrName string
 	addr          *IPAddr
 	err           error
@@ -37,210 +38,41 @@
 	{"", "127.0.0.1", &IPAddr{IP: IPv4(127, 0, 0, 1)}, nil}, // Go 1.0 behavior
 	{"", "::1", &IPAddr{IP: ParseIP("::1")}, nil},           // Go 1.0 behavior
 
+	{"ip4:icmp", "", &IPAddr{}, nil},
+
 	{"l2tp", "127.0.0.1", nil, UnknownNetworkError("l2tp")},
 	{"l2tp:gre", "127.0.0.1", nil, UnknownNetworkError("l2tp:gre")},
 	{"tcp", "1.2.3.4:123", nil, UnknownNetworkError("tcp")},
 }
 
-func init() {
-	if ifi := loopbackInterface(); ifi != nil {
-		index := fmt.Sprintf("%v", ifi.Index)
-		resolveIPAddrTests = append(resolveIPAddrTests, []resolveIPAddrTest{
-			{"ip6", "fe80::1%" + ifi.Name, &IPAddr{IP: ParseIP("fe80::1"), Zone: zoneToString(ifi.Index)}, nil},
-			{"ip6", "fe80::1%" + index, &IPAddr{IP: ParseIP("fe80::1"), Zone: index}, nil},
-		}...)
-	}
-	if ips, err := LookupIP("localhost"); err == nil && len(ips) > 1 && supportsIPv4 && supportsIPv6 {
-		resolveIPAddrTests = append(resolveIPAddrTests, []resolveIPAddrTest{
-			{"ip", "localhost", &IPAddr{IP: IPv4(127, 0, 0, 1)}, nil},
-			{"ip4", "localhost", &IPAddr{IP: IPv4(127, 0, 0, 1)}, nil},
-			{"ip6", "localhost", &IPAddr{IP: IPv6loopback}, nil},
-		}...)
-	}
-}
-
-func skipRawSocketTest(t *testing.T) (skip bool, skipmsg string) {
-	skip, skipmsg, err := skipRawSocketTests()
-	if err != nil {
-		t.Fatal(err)
-	}
-	return skip, skipmsg
-}
-
 func TestResolveIPAddr(t *testing.T) {
-	switch runtime.GOOS {
-	case "nacl":
-		t.Skipf("skipping test on %q", runtime.GOOS)
+	if !testableNetwork("ip+nopriv") {
+		t.Skip("ip+nopriv test")
 	}
 
-	for _, tt := range resolveIPAddrTests {
-		addr, err := ResolveIPAddr(tt.net, tt.litAddrOrName)
+	origTestHookLookupIP := testHookLookupIP
+	defer func() { testHookLookupIP = origTestHookLookupIP }()
+	testHookLookupIP = lookupLocalhost
+
+	for i, tt := range resolveIPAddrTests {
+		addr, err := ResolveIPAddr(tt.network, tt.litAddrOrName)
 		if err != tt.err {
-			t.Fatalf("ResolveIPAddr(%v, %v) failed: %v", tt.net, tt.litAddrOrName, err)
+			t.Errorf("#%d: %v", i, err)
 		} else if !reflect.DeepEqual(addr, tt.addr) {
-			t.Fatalf("got %#v; expected %#v", addr, tt.addr)
+			t.Errorf("#%d: got %#v; want %#v", i, addr, tt.addr)
 		}
-	}
-}
-
-var icmpEchoTests = []struct {
-	net   string
-	laddr string
-	raddr string
-}{
-	{"ip4:icmp", "0.0.0.0", "127.0.0.1"},
-	{"ip6:ipv6-icmp", "::", "::1"},
-}
-
-func TestConnICMPEcho(t *testing.T) {
-	if skip, skipmsg := skipRawSocketTest(t); skip {
-		t.Skip(skipmsg)
-	}
-
-	for i, tt := range icmpEchoTests {
-		net, _, err := parseNetwork(tt.net)
 		if err != nil {
-			t.Fatalf("parseNetwork failed: %v", err)
-		}
-		if net == "ip6" && !supportsIPv6 {
 			continue
 		}
-
-		c, err := Dial(tt.net, tt.raddr)
+		rtaddr, err := ResolveIPAddr(addr.Network(), addr.String())
 		if err != nil {
-			t.Fatalf("Dial failed: %v", err)
-		}
-		c.SetDeadline(time.Now().Add(100 * time.Millisecond))
-		defer c.Close()
-
-		typ := icmpv4EchoRequest
-		if net == "ip6" {
-			typ = icmpv6EchoRequest
-		}
-		xid, xseq := os.Getpid()&0xffff, i+1
-		wb, err := (&icmpMessage{
-			Type: typ, Code: 0,
-			Body: &icmpEcho{
-				ID: xid, Seq: xseq,
-				Data: bytes.Repeat([]byte("Go Go Gadget Ping!!!"), 3),
-			},
-		}).Marshal()
-		if err != nil {
-			t.Fatalf("icmpMessage.Marshal failed: %v", err)
-		}
-		if _, err := c.Write(wb); err != nil {
-			t.Fatalf("Conn.Write failed: %v", err)
-		}
-		var m *icmpMessage
-		rb := make([]byte, 20+len(wb))
-		for {
-			if _, err := c.Read(rb); err != nil {
-				t.Fatalf("Conn.Read failed: %v", err)
-			}
-			if net == "ip4" {
-				rb = ipv4Payload(rb)
-			}
-			if m, err = parseICMPMessage(rb); err != nil {
-				t.Fatalf("parseICMPMessage failed: %v", err)
-			}
-			switch m.Type {
-			case icmpv4EchoRequest, icmpv6EchoRequest:
-				continue
-			}
-			break
-		}
-		switch p := m.Body.(type) {
-		case *icmpEcho:
-			if p.ID != xid || p.Seq != xseq {
-				t.Fatalf("got id=%v, seqnum=%v; expected id=%v, seqnum=%v", p.ID, p.Seq, xid, xseq)
-			}
-		default:
-			t.Fatalf("got type=%v, code=%v; expected type=%v, code=%v", m.Type, m.Code, typ, 0)
+			t.Errorf("#%d: %v", i, err)
+		} else if !reflect.DeepEqual(rtaddr, addr) {
+			t.Errorf("#%d: got %#v; want %#v", i, rtaddr, addr)
 		}
 	}
 }
 
-func TestPacketConnICMPEcho(t *testing.T) {
-	if skip, skipmsg := skipRawSocketTest(t); skip {
-		t.Skip(skipmsg)
-	}
-
-	for i, tt := range icmpEchoTests {
-		net, _, err := parseNetwork(tt.net)
-		if err != nil {
-			t.Fatalf("parseNetwork failed: %v", err)
-		}
-		if net == "ip6" && !supportsIPv6 {
-			continue
-		}
-
-		c, err := ListenPacket(tt.net, tt.laddr)
-		if err != nil {
-			t.Fatalf("ListenPacket failed: %v", err)
-		}
-		c.SetDeadline(time.Now().Add(100 * time.Millisecond))
-		defer c.Close()
-
-		ra, err := ResolveIPAddr(tt.net, tt.raddr)
-		if err != nil {
-			t.Fatalf("ResolveIPAddr failed: %v", err)
-		}
-		typ := icmpv4EchoRequest
-		if net == "ip6" {
-			typ = icmpv6EchoRequest
-		}
-		xid, xseq := os.Getpid()&0xffff, i+1
-		wb, err := (&icmpMessage{
-			Type: typ, Code: 0,
-			Body: &icmpEcho{
-				ID: xid, Seq: xseq,
-				Data: bytes.Repeat([]byte("Go Go Gadget Ping!!!"), 3),
-			},
-		}).Marshal()
-		if err != nil {
-			t.Fatalf("icmpMessage.Marshal failed: %v", err)
-		}
-		if _, err := c.WriteTo(wb, ra); err != nil {
-			t.Fatalf("PacketConn.WriteTo failed: %v", err)
-		}
-		var m *icmpMessage
-		rb := make([]byte, 20+len(wb))
-		for {
-			if _, _, err := c.ReadFrom(rb); err != nil {
-				t.Fatalf("PacketConn.ReadFrom failed: %v", err)
-			}
-			// See BUG section.
-			//if net == "ip4" {
-			//	rb = ipv4Payload(rb)
-			//}
-			if m, err = parseICMPMessage(rb); err != nil {
-				t.Fatalf("parseICMPMessage failed: %v", err)
-			}
-			switch m.Type {
-			case icmpv4EchoRequest, icmpv6EchoRequest:
-				continue
-			}
-			break
-		}
-		switch p := m.Body.(type) {
-		case *icmpEcho:
-			if p.ID != xid || p.Seq != xseq {
-				t.Fatalf("got id=%v, seqnum=%v; expected id=%v, seqnum=%v", p.ID, p.Seq, xid, xseq)
-			}
-		default:
-			t.Fatalf("got type=%v, code=%v; expected type=%v, code=%v", m.Type, m.Code, typ, 0)
-		}
-	}
-}
-
-func ipv4Payload(b []byte) []byte {
-	if len(b) < 20 {
-		return b
-	}
-	hdrlen := int(b[0]&0x0f) << 2
-	return b[hdrlen:]
-}
-
 var ipConnLocalNameTests = []struct {
 	net   string
 	laddr *IPAddr
@@ -251,44 +83,34 @@
 }
 
 func TestIPConnLocalName(t *testing.T) {
-	switch runtime.GOOS {
-	case "nacl", "plan9", "windows":
-		t.Skipf("skipping test on %q", runtime.GOOS)
-	default:
-		if os.Getuid() != 0 {
-			t.Skip("skipping test; must be root")
-		}
-	}
-
 	for _, tt := range ipConnLocalNameTests {
+		if !testableNetwork(tt.net) {
+			t.Logf("skipping %s test", tt.net)
+			continue
+		}
 		c, err := ListenIP(tt.net, tt.laddr)
 		if err != nil {
-			t.Fatalf("ListenIP failed: %v", err)
+			t.Fatal(err)
 		}
 		defer c.Close()
 		if la := c.LocalAddr(); la == nil {
-			t.Fatal("IPConn.LocalAddr failed")
+			t.Fatal("should not fail")
 		}
 	}
 }
 
 func TestIPConnRemoteName(t *testing.T) {
-	switch runtime.GOOS {
-	case "plan9", "windows":
-		t.Skipf("skipping test on %q", runtime.GOOS)
-	default:
-		if os.Getuid() != 0 {
-			t.Skip("skipping test; must be root")
-		}
+	if !testableNetwork("ip:tcp") {
+		t.Skip("ip:tcp test")
 	}
 
 	raddr := &IPAddr{IP: IPv4(127, 0, 0, 1).To4()}
 	c, err := DialIP("ip:tcp", &IPAddr{IP: IPv4(127, 0, 0, 1)}, raddr)
 	if err != nil {
-		t.Fatalf("DialIP failed: %v", err)
+		t.Fatal(err)
 	}
 	defer c.Close()
 	if !reflect.DeepEqual(raddr, c.RemoteAddr()) {
-		t.Fatalf("got %#v, expected %#v", c.RemoteAddr(), raddr)
+		t.Fatalf("got %#v; want %#v", c.RemoteAddr(), raddr)
 	}
 }
diff --git a/third_party/gofrontend/libgo/go/net/iprawsock.go b/third_party/gofrontend/libgo/go/net/iprawsock.go
index 5cc3613..f02df7f 100644
--- a/third_party/gofrontend/libgo/go/net/iprawsock.go
+++ b/third_party/gofrontend/libgo/go/net/iprawsock.go
@@ -17,13 +17,21 @@
 	if a == nil {
 		return "<nil>"
 	}
+	ip := ipEmptyString(a.IP)
 	if a.Zone != "" {
-		return a.IP.String() + "%" + a.Zone
+		return ip + "%" + a.Zone
 	}
-	return a.IP.String()
+	return ip
 }
 
-func (a *IPAddr) toAddr() Addr {
+func (a *IPAddr) isWildcard() bool {
+	if a == nil || a.IP == nil {
+		return true
+	}
+	return a.IP.IsUnspecified()
+}
+
+func (a *IPAddr) opAddr() Addr {
 	if a == nil {
 		return nil
 	}
@@ -46,9 +54,9 @@
 	default:
 		return nil, UnknownNetworkError(net)
 	}
-	a, err := resolveInternetAddr(afnet, addr, noDeadline)
+	addrs, err := internetAddrList(afnet, addr, noDeadline)
 	if err != nil {
 		return nil, err
 	}
-	return a.toAddr().(*IPAddr), nil
+	return addrs.first(isIPv4).(*IPAddr), nil
 }
diff --git a/third_party/gofrontend/libgo/go/net/iprawsock_plan9.go b/third_party/gofrontend/libgo/go/net/iprawsock_plan9.go
index e62d116..b027adc 100644
--- a/third_party/gofrontend/libgo/go/net/iprawsock_plan9.go
+++ b/third_party/gofrontend/libgo/go/net/iprawsock_plan9.go
@@ -23,12 +23,12 @@
 // Timeout() == true after a fixed time limit; see SetDeadline and
 // SetReadDeadline.
 func (c *IPConn) ReadFromIP(b []byte) (int, *IPAddr, error) {
-	return 0, nil, syscall.EPLAN9
+	return 0, nil, &OpError{Op: "read", Net: c.fd.dir, Source: c.fd.laddr, Addr: c.fd.raddr, Err: syscall.EPLAN9}
 }
 
 // ReadFrom implements the PacketConn ReadFrom method.
 func (c *IPConn) ReadFrom(b []byte) (int, Addr, error) {
-	return 0, nil, syscall.EPLAN9
+	return 0, nil, &OpError{Op: "read", Net: c.fd.dir, Source: c.fd.laddr, Addr: c.fd.raddr, Err: syscall.EPLAN9}
 }
 
 // ReadMsgIP reads a packet from c, copying the payload into b and the
@@ -36,7 +36,7 @@
 // bytes copied into b, the number of bytes copied into oob, the flags
 // that were set on the packet and the source address of the packet.
 func (c *IPConn) ReadMsgIP(b, oob []byte) (n, oobn, flags int, addr *IPAddr, err error) {
-	return 0, 0, 0, nil, syscall.EPLAN9
+	return 0, 0, 0, nil, &OpError{Op: "read", Net: c.fd.dir, Source: c.fd.laddr, Addr: c.fd.raddr, Err: syscall.EPLAN9}
 }
 
 // WriteToIP writes an IP packet to addr via c, copying the payload
@@ -47,19 +47,19 @@
 // SetWriteDeadline.  On packet-oriented connections, write timeouts
 // are rare.
 func (c *IPConn) WriteToIP(b []byte, addr *IPAddr) (int, error) {
-	return 0, syscall.EPLAN9
+	return 0, &OpError{Op: "write", Net: c.fd.dir, Source: c.fd.laddr, Addr: addr.opAddr(), Err: syscall.EPLAN9}
 }
 
 // WriteTo implements the PacketConn WriteTo method.
 func (c *IPConn) WriteTo(b []byte, addr Addr) (int, error) {
-	return 0, syscall.EPLAN9
+	return 0, &OpError{Op: "write", Net: c.fd.dir, Source: c.fd.laddr, Addr: addr, Err: syscall.EPLAN9}
 }
 
 // WriteMsgIP writes a packet to addr via c, copying the payload from
 // b and the associated out-of-band data from oob.  It returns the
 // number of payload and out-of-band bytes written.
 func (c *IPConn) WriteMsgIP(b, oob []byte, addr *IPAddr) (n, oobn int, err error) {
-	return 0, 0, syscall.EPLAN9
+	return 0, 0, &OpError{Op: "write", Net: c.fd.dir, Source: c.fd.laddr, Addr: addr.opAddr(), Err: syscall.EPLAN9}
 }
 
 // DialIP connects to the remote address raddr on the network protocol
@@ -70,7 +70,7 @@
 }
 
 func dialIP(netProto string, laddr, raddr *IPAddr, deadline time.Time) (*IPConn, error) {
-	return nil, syscall.EPLAN9
+	return nil, &OpError{Op: "dial", Net: netProto, Source: laddr.opAddr(), Addr: raddr.opAddr(), Err: syscall.EPLAN9}
 }
 
 // ListenIP listens for incoming IP packets addressed to the local
@@ -78,5 +78,5 @@
 // methods can be used to receive and send IP packets with per-packet
 // addressing.
 func ListenIP(netProto string, laddr *IPAddr) (*IPConn, error) {
-	return nil, syscall.EPLAN9
+	return nil, &OpError{Op: "listen", Net: netProto, Source: nil, Addr: laddr.opAddr(), Err: syscall.EPLAN9}
 }
diff --git a/third_party/gofrontend/libgo/go/net/iprawsock_posix.go b/third_party/gofrontend/libgo/go/net/iprawsock_posix.go
index 99b081b..9417606 100644
--- a/third_party/gofrontend/libgo/go/net/iprawsock_posix.go
+++ b/third_party/gofrontend/libgo/go/net/iprawsock_posix.go
@@ -43,13 +43,6 @@
 	return syscall.AF_INET6
 }
 
-func (a *IPAddr) isWildcard() bool {
-	if a == nil || a.IP == nil {
-		return true
-	}
-	return a.IP.IsUnspecified()
-}
-
 func (a *IPAddr) sockaddr(family int) (syscall.Sockaddr, error) {
 	if a == nil {
 		return nil, nil
@@ -83,24 +76,41 @@
 	switch sa := sa.(type) {
 	case *syscall.SockaddrInet4:
 		addr = &IPAddr{IP: sa.Addr[0:]}
-		if len(b) >= IPv4len { // discard ipv4 header
-			hsize := (int(b[0]) & 0xf) * 4
-			copy(b, b[hsize:])
-			n -= hsize
-		}
+		n = stripIPv4Header(n, b)
 	case *syscall.SockaddrInet6:
 		addr = &IPAddr{IP: sa.Addr[0:], Zone: zoneToString(int(sa.ZoneId))}
 	}
+	if err != nil {
+		err = &OpError{Op: "read", Net: c.fd.net, Source: c.fd.laddr, Addr: c.fd.raddr, Err: err}
+	}
 	return n, addr, err
 }
 
+func stripIPv4Header(n int, b []byte) int {
+	if len(b) < 20 {
+		return n
+	}
+	l := int(b[0]&0x0f) << 2
+	if 20 > l || l > len(b) {
+		return n
+	}
+	if b[0]>>4 != 4 {
+		return n
+	}
+	copy(b, b[l:])
+	return n - l
+}
+
 // ReadFrom implements the PacketConn ReadFrom method.
 func (c *IPConn) ReadFrom(b []byte) (int, Addr, error) {
 	if !c.ok() {
 		return 0, nil, syscall.EINVAL
 	}
 	n, addr, err := c.ReadFromIP(b)
-	return n, addr.toAddr(), err
+	if addr == nil {
+		return n, nil, err
+	}
+	return n, addr, err
 }
 
 // ReadMsgIP reads a packet from c, copying the payload into b and the
@@ -119,6 +129,9 @@
 	case *syscall.SockaddrInet6:
 		addr = &IPAddr{IP: sa.Addr[0:], Zone: zoneToString(int(sa.ZoneId))}
 	}
+	if err != nil {
+		err = &OpError{Op: "read", Net: c.fd.net, Source: c.fd.laddr, Addr: c.fd.raddr, Err: err}
+	}
 	return
 }
 
@@ -134,16 +147,20 @@
 		return 0, syscall.EINVAL
 	}
 	if c.fd.isConnected {
-		return 0, &OpError{Op: "write", Net: c.fd.net, Addr: addr, Err: ErrWriteToConnected}
+		return 0, &OpError{Op: "write", Net: c.fd.net, Source: c.fd.laddr, Addr: addr.opAddr(), Err: ErrWriteToConnected}
 	}
 	if addr == nil {
-		return 0, &OpError{Op: "write", Net: c.fd.net, Addr: nil, Err: errMissingAddress}
+		return 0, &OpError{Op: "write", Net: c.fd.net, Source: c.fd.laddr, Addr: nil, Err: errMissingAddress}
 	}
 	sa, err := addr.sockaddr(c.fd.family)
 	if err != nil {
-		return 0, &OpError{"write", c.fd.net, addr, err}
+		return 0, &OpError{Op: "write", Net: c.fd.net, Source: c.fd.laddr, Addr: addr.opAddr(), Err: err}
 	}
-	return c.fd.writeTo(b, sa)
+	n, err := c.fd.writeTo(b, sa)
+	if err != nil {
+		err = &OpError{Op: "write", Net: c.fd.net, Source: c.fd.laddr, Addr: addr.opAddr(), Err: err}
+	}
+	return n, err
 }
 
 // WriteTo implements the PacketConn WriteTo method.
@@ -153,7 +170,7 @@
 	}
 	a, ok := addr.(*IPAddr)
 	if !ok {
-		return 0, &OpError{"write", c.fd.net, addr, syscall.EINVAL}
+		return 0, &OpError{Op: "write", Net: c.fd.net, Source: c.fd.laddr, Addr: addr, Err: syscall.EINVAL}
 	}
 	return c.WriteToIP(b, a)
 }
@@ -166,16 +183,21 @@
 		return 0, 0, syscall.EINVAL
 	}
 	if c.fd.isConnected {
-		return 0, 0, &OpError{Op: "write", Net: c.fd.net, Addr: addr, Err: ErrWriteToConnected}
+		return 0, 0, &OpError{Op: "write", Net: c.fd.net, Source: c.fd.laddr, Addr: addr.opAddr(), Err: ErrWriteToConnected}
 	}
 	if addr == nil {
-		return 0, 0, &OpError{Op: "write", Net: c.fd.net, Addr: nil, Err: errMissingAddress}
+		return 0, 0, &OpError{Op: "write", Net: c.fd.net, Source: c.fd.laddr, Addr: nil, Err: errMissingAddress}
 	}
-	sa, err := addr.sockaddr(c.fd.family)
+	var sa syscall.Sockaddr
+	sa, err = addr.sockaddr(c.fd.family)
 	if err != nil {
-		return 0, 0, &OpError{"write", c.fd.net, addr, err}
+		return 0, 0, &OpError{Op: "write", Net: c.fd.net, Source: c.fd.laddr, Addr: addr.opAddr(), Err: err}
 	}
-	return c.fd.writeMsg(b, oob, sa)
+	n, oobn, err = c.fd.writeMsg(b, oob, sa)
+	if err != nil {
+		err = &OpError{Op: "write", Net: c.fd.net, Source: c.fd.laddr, Addr: addr.opAddr(), Err: err}
+	}
+	return
 }
 
 // DialIP connects to the remote address raddr on the network protocol
@@ -188,19 +210,19 @@
 func dialIP(netProto string, laddr, raddr *IPAddr, deadline time.Time) (*IPConn, error) {
 	net, proto, err := parseNetwork(netProto)
 	if err != nil {
-		return nil, &OpError{Op: "dial", Net: netProto, Addr: raddr, Err: err}
+		return nil, &OpError{Op: "dial", Net: netProto, Source: laddr.opAddr(), Addr: raddr.opAddr(), Err: err}
 	}
 	switch net {
 	case "ip", "ip4", "ip6":
 	default:
-		return nil, &OpError{Op: "dial", Net: netProto, Addr: raddr, Err: UnknownNetworkError(netProto)}
+		return nil, &OpError{Op: "dial", Net: netProto, Source: laddr.opAddr(), Addr: raddr.opAddr(), Err: UnknownNetworkError(netProto)}
 	}
 	if raddr == nil {
-		return nil, &OpError{Op: "dial", Net: netProto, Addr: nil, Err: errMissingAddress}
+		return nil, &OpError{Op: "dial", Net: netProto, Source: laddr.opAddr(), Addr: nil, Err: errMissingAddress}
 	}
 	fd, err := internetSocket(net, laddr, raddr, deadline, syscall.SOCK_RAW, proto, "dial")
 	if err != nil {
-		return nil, &OpError{Op: "dial", Net: netProto, Addr: raddr, Err: err}
+		return nil, &OpError{Op: "dial", Net: netProto, Source: laddr.opAddr(), Addr: raddr.opAddr(), Err: err}
 	}
 	return newIPConn(fd), nil
 }
@@ -212,16 +234,16 @@
 func ListenIP(netProto string, laddr *IPAddr) (*IPConn, error) {
 	net, proto, err := parseNetwork(netProto)
 	if err != nil {
-		return nil, &OpError{Op: "dial", Net: netProto, Addr: laddr, Err: err}
+		return nil, &OpError{Op: "listen", Net: netProto, Source: nil, Addr: laddr.opAddr(), Err: err}
 	}
 	switch net {
 	case "ip", "ip4", "ip6":
 	default:
-		return nil, &OpError{Op: "listen", Net: netProto, Addr: laddr, Err: UnknownNetworkError(netProto)}
+		return nil, &OpError{Op: "listen", Net: netProto, Source: nil, Addr: laddr.opAddr(), Err: UnknownNetworkError(netProto)}
 	}
 	fd, err := internetSocket(net, laddr, nil, noDeadline, syscall.SOCK_RAW, proto, "listen")
 	if err != nil {
-		return nil, &OpError{Op: "listen", Net: netProto, Addr: laddr, Err: err}
+		return nil, &OpError{Op: "listen", Net: netProto, Source: nil, Addr: laddr.opAddr(), Err: err}
 	}
 	return newIPConn(fd), nil
 }
diff --git a/third_party/gofrontend/libgo/go/net/ipsock.go b/third_party/gofrontend/libgo/go/net/ipsock.go
index dda8578..6e75c33 100644
--- a/third_party/gofrontend/libgo/go/net/ipsock.go
+++ b/third_party/gofrontend/libgo/go/net/ipsock.go
@@ -26,113 +26,82 @@
 	supportsIPv4map bool
 )
 
-func init() {
-	sysInit()
-	supportsIPv4 = probeIPv4Stack()
-	supportsIPv6, supportsIPv4map = probeIPv6Stack()
-}
-
-// A netaddr represents a network endpoint address or a list of
-// network endpoint addresses.
-type netaddr interface {
-	// toAddr returns the address represented in Addr interface.
-	// It returns a nil interface when the address is nil.
-	toAddr() Addr
-}
-
 // An addrList represents a list of network endpoint addresses.
-type addrList []netaddr
+type addrList []Addr
 
-func (al addrList) toAddr() Addr {
-	switch len(al) {
-	case 0:
-		return nil
-	case 1:
-		return al[0].toAddr()
-	default:
-		// For now, we'll roughly pick first one without
-		// considering dealing with any preferences such as
-		// DNS TTL, transport path quality, network routing
-		// information.
-		return al[0].toAddr()
+// isIPv4 returns true if the Addr contains an IPv4 address.
+func isIPv4(addr Addr) bool {
+	switch addr := addr.(type) {
+	case *TCPAddr:
+		return addr.IP.To4() != nil
+	case *UDPAddr:
+		return addr.IP.To4() != nil
+	case *IPAddr:
+		return addr.IP.To4() != nil
 	}
+	return false
+}
+
+// first returns the first address which satisfies strategy, or if
+// none do, then the first address of any kind.
+func (addrs addrList) first(strategy func(Addr) bool) Addr {
+	for _, addr := range addrs {
+		if strategy(addr) {
+			return addr
+		}
+	}
+	return addrs[0]
+}
+
+// partition divides an address list into two categories, using a
+// strategy function to assign a boolean label to each address.
+// The first address, and any with a matching label, are returned as
+// primaries, while addresses with the opposite label are returned
+// as fallbacks. For non-empty inputs, primaries is guaranteed to be
+// non-empty.
+func (addrs addrList) partition(strategy func(Addr) bool) (primaries, fallbacks addrList) {
+	var primaryLabel bool
+	for i, addr := range addrs {
+		label := strategy(addr)
+		if i == 0 || label == primaryLabel {
+			primaryLabel = label
+			primaries = append(primaries, addr)
+		} else {
+			fallbacks = append(fallbacks, addr)
+		}
+	}
+	return
 }
 
 var errNoSuitableAddress = errors.New("no suitable address found")
 
-// firstFavoriteAddr returns an address or a list of addresses that
-// implement the netaddr interface. Known filters are nil, ipv4only
-// and ipv6only. It returns any address when filter is nil. The result
-// contains at least one address when error is nil.
-func firstFavoriteAddr(filter func(IP) IP, ips []IP, inetaddr func(IP) netaddr) (netaddr, error) {
-	if filter != nil {
-		return firstSupportedAddr(filter, ips, inetaddr)
-	}
-	var (
-		ipv4, ipv6, swap bool
-		list             addrList
-	)
+// filterAddrList applies a filter to a list of IP addresses,
+// yielding a list of Addr objects. Known filters are nil, ipv4only,
+// and ipv6only. It returns every address when the filter is nil.
+// The result contains at least one address when error is nil.
+func filterAddrList(filter func(IPAddr) bool, ips []IPAddr, inetaddr func(IPAddr) Addr) (addrList, error) {
+	var addrs addrList
 	for _, ip := range ips {
-		// We'll take any IP address, but since the dialing
-		// code does not yet try multiple addresses
-		// effectively, prefer to use an IPv4 address if
-		// possible. This is especially relevant if localhost
-		// resolves to [ipv6-localhost, ipv4-localhost]. Too
-		// much code assumes localhost == ipv4-localhost.
-		if ip4 := ipv4only(ip); ip4 != nil && !ipv4 {
-			list = append(list, inetaddr(ip4))
-			ipv4 = true
-			if ipv6 {
-				swap = true
-			}
-		} else if ip6 := ipv6only(ip); ip6 != nil && !ipv6 {
-			list = append(list, inetaddr(ip6))
-			ipv6 = true
-		}
-		if ipv4 && ipv6 {
-			if swap {
-				list[0], list[1] = list[1], list[0]
-			}
-			break
+		if filter == nil || filter(ip) {
+			addrs = append(addrs, inetaddr(ip))
 		}
 	}
-	switch len(list) {
-	case 0:
+	if len(addrs) == 0 {
 		return nil, errNoSuitableAddress
-	case 1:
-		return list[0], nil
-	default:
-		return list, nil
 	}
+	return addrs, nil
 }
 
-func firstSupportedAddr(filter func(IP) IP, ips []IP, inetaddr func(IP) netaddr) (netaddr, error) {
-	for _, ip := range ips {
-		if ip := filter(ip); ip != nil {
-			return inetaddr(ip), nil
-		}
-	}
-	return nil, errNoSuitableAddress
+// ipv4only reports whether the kernel supports IPv4 addressing mode
+// and addr is an IPv4 address.
+func ipv4only(addr IPAddr) bool {
+	return supportsIPv4 && addr.IP.To4() != nil
 }
 
-// ipv4only returns IPv4 addresses that we can use with the kernel's
-// IPv4 addressing modes. If ip is an IPv4 address, ipv4only returns ip.
-// Otherwise it returns nil.
-func ipv4only(ip IP) IP {
-	if supportsIPv4 && ip.To4() != nil {
-		return ip
-	}
-	return nil
-}
-
-// ipv6only returns IPv6 addresses that we can use with the kernel's
-// IPv6 addressing modes.  It returns IPv4-mapped IPv6 addresses as
-// nils and returns other IPv6 address types as IPv6 addresses.
-func ipv6only(ip IP) IP {
-	if supportsIPv6 && len(ip) == IPv6len && ip.To4() == nil {
-		return ip
-	}
-	return nil
+// ipv6only reports whether the kernel supports IPv6 addressing mode
+// and addr is an IPv6 address except IPv4-mapped IPv6 address.
+func ipv6only(addr IPAddr) bool {
+	return supportsIPv6 && len(addr.IP) == IPv6len && addr.IP.To4() == nil
 }
 
 // SplitHostPort splits a network address of the form "host:port",
@@ -153,7 +122,7 @@
 		// Expect the first ']' just before the last ':'.
 		end := byteIndex(hostport, ']')
 		if end < 0 {
-			err = &AddrError{"missing ']' in address", hostport}
+			err = &AddrError{Err: "missing ']' in address", Addr: hostport}
 			return
 		}
 		switch end + 1 {
@@ -182,11 +151,11 @@
 		}
 	}
 	if byteIndex(hostport[j:], '[') >= 0 {
-		err = &AddrError{"unexpected '[' in address", hostport}
+		err = &AddrError{Err: "unexpected '[' in address", Addr: hostport}
 		return
 	}
 	if byteIndex(hostport[k:], ']') >= 0 {
-		err = &AddrError{"unexpected ']' in address", hostport}
+		err = &AddrError{Err: "unexpected ']' in address", Addr: hostport}
 		return
 	}
 
@@ -194,15 +163,15 @@
 	return
 
 missingPort:
-	err = &AddrError{"missing port in address", hostport}
+	err = &AddrError{Err: "missing port in address", Addr: hostport}
 	return
 
 tooManyColons:
-	err = &AddrError{"too many colons in address", hostport}
+	err = &AddrError{Err: "too many colons in address", Addr: hostport}
 	return
 
 missingBrackets:
-	err = &AddrError{"missing brackets in address", hostport}
+	err = &AddrError{Err: "missing brackets in address", Addr: hostport}
 	return
 }
 
@@ -228,17 +197,15 @@
 	return host + ":" + port
 }
 
-// resolveInternetAddr resolves addr that is either a literal IP
-// address or a DNS name and returns an internet protocol family
-// address. It returns a list that contains a pair of different
-// address family addresses when addr is a DNS name and the name has
-// multiple address family records. The result contains at least one
-// address when error is nil.
-func resolveInternetAddr(net, addr string, deadline time.Time) (netaddr, error) {
+// internetAddrList resolves addr, which may be a literal IP
+// address or a DNS name, and returns a list of internet protocol
+// family addresses. The result contains at least one address when
+// error is nil.
+func internetAddrList(net, addr string, deadline time.Time) (addrList, error) {
 	var (
-		err              error
-		host, port, zone string
-		portnum          int
+		err        error
+		host, port string
+		portnum    int
 	)
 	switch net {
 	case "tcp", "tcp4", "tcp6", "udp", "udp4", "udp6":
@@ -257,43 +224,43 @@
 	default:
 		return nil, UnknownNetworkError(net)
 	}
-	inetaddr := func(ip IP) netaddr {
+	inetaddr := func(ip IPAddr) Addr {
 		switch net {
 		case "tcp", "tcp4", "tcp6":
-			return &TCPAddr{IP: ip, Port: portnum, Zone: zone}
+			return &TCPAddr{IP: ip.IP, Port: portnum, Zone: ip.Zone}
 		case "udp", "udp4", "udp6":
-			return &UDPAddr{IP: ip, Port: portnum, Zone: zone}
+			return &UDPAddr{IP: ip.IP, Port: portnum, Zone: ip.Zone}
 		case "ip", "ip4", "ip6":
-			return &IPAddr{IP: ip, Zone: zone}
+			return &IPAddr{IP: ip.IP, Zone: ip.Zone}
 		default:
 			panic("unexpected network: " + net)
 		}
 	}
 	if host == "" {
-		return inetaddr(nil), nil
+		return addrList{inetaddr(IPAddr{})}, nil
 	}
 	// Try as a literal IP address.
 	var ip IP
 	if ip = parseIPv4(host); ip != nil {
-		return inetaddr(ip), nil
+		return addrList{inetaddr(IPAddr{IP: ip})}, nil
 	}
+	var zone string
 	if ip, zone = parseIPv6(host, true); ip != nil {
-		return inetaddr(ip), nil
+		return addrList{inetaddr(IPAddr{IP: ip, Zone: zone})}, nil
 	}
 	// Try as a DNS name.
-	host, zone = splitHostZone(host)
 	ips, err := lookupIPDeadline(host, deadline)
 	if err != nil {
 		return nil, err
 	}
-	var filter func(IP) IP
+	var filter func(IPAddr) bool
 	if net != "" && net[len(net)-1] == '4' {
 		filter = ipv4only
 	}
-	if net != "" && net[len(net)-1] == '6' || zone != "" {
+	if net != "" && net[len(net)-1] == '6' {
 		filter = ipv6only
 	}
-	return firstFavoriteAddr(filter, ips, inetaddr)
+	return filterAddrList(filter, ips, inetaddr)
 }
 
 func zoneToString(zone int) string {
@@ -303,7 +270,7 @@
 	if ifi, err := InterfaceByIndex(zone); err == nil {
 		return ifi.Name
 	}
-	return itod(uint(zone))
+	return uitoa(uint(zone))
 }
 
 func zoneToInt(zone string) int {
diff --git a/third_party/gofrontend/libgo/go/net/ipsock_plan9.go b/third_party/gofrontend/libgo/go/net/ipsock_plan9.go
index 94ceea3..9da6ec3 100644
--- a/third_party/gofrontend/libgo/go/net/ipsock_plan9.go
+++ b/third_party/gofrontend/libgo/go/net/ipsock_plan9.go
@@ -7,7 +7,6 @@
 package net
 
 import (
-	"errors"
 	"os"
 	"syscall"
 )
@@ -60,15 +59,15 @@
 	if i >= 0 {
 		addr = ParseIP(s[:i])
 		if addr == nil {
-			return nil, 0, errors.New("parsing IP failed")
+			return nil, 0, &ParseError{Type: "IP address", Text: s}
 		}
 	}
 	p, _, ok := dtoi(s[i+1:], 0)
 	if !ok {
-		return nil, 0, errors.New("parsing port failed")
+		return nil, 0, &ParseError{Type: "port", Text: s}
 	}
 	if p < 0 || p > 0xFFFF {
-		return nil, 0, &AddrError{"invalid port", string(p)}
+		return nil, 0, &AddrError{Err: "invalid port", Addr: string(p)}
 	}
 	return addr, p, nil
 }
@@ -95,7 +94,7 @@
 	case "udp":
 		addr = &UDPAddr{IP: ip, Port: port}
 	default:
-		return nil, errors.New("unknown protocol " + proto)
+		return nil, UnknownNetworkError(proto)
 	}
 	return addr, nil
 }
@@ -141,6 +140,24 @@
 	if !ok {
 		return
 	}
+	nonNilInterface := func(a Addr) bool {
+		switch a := a.(type) {
+		case *TCPAddr:
+			return a == nil
+		case *UDPAddr:
+			return a == nil
+		case *IPAddr:
+			return a == nil
+		default:
+			return false
+		}
+	}
+	if nonNilInterface(oe.Source) {
+		oe.Source = nil
+	}
+	if nonNilInterface(oe.Addr) {
+		oe.Addr = nil
+	}
 	if pe, ok := oe.Err.(*os.PathError); ok {
 		if _, ok = pe.Err.(syscall.ErrorString); ok {
 			oe.Err = pe.Err
@@ -152,23 +169,23 @@
 	defer func() { netErr(err) }()
 	f, dest, proto, name, err := startPlan9(net, raddr)
 	if err != nil {
-		return nil, &OpError{"dial", net, raddr, err}
+		return nil, &OpError{Op: "dial", Net: net, Source: laddr, Addr: raddr, Err: err}
 	}
 	_, err = f.WriteString("connect " + dest)
 	if err != nil {
 		f.Close()
-		return nil, &OpError{"dial", f.Name(), raddr, err}
+		return nil, &OpError{Op: "dial", Net: f.Name(), Source: laddr, Addr: raddr, Err: err}
 	}
 	data, err := os.OpenFile(netdir+"/"+proto+"/"+name+"/data", os.O_RDWR, 0)
 	if err != nil {
 		f.Close()
-		return nil, &OpError{"dial", net, raddr, err}
+		return nil, &OpError{Op: "dial", Net: net, Source: laddr, Addr: raddr, Err: err}
 	}
 	laddr, err = readPlan9Addr(proto, netdir+"/"+proto+"/"+name+"/local")
 	if err != nil {
 		data.Close()
 		f.Close()
-		return nil, &OpError{"dial", proto, raddr, err}
+		return nil, &OpError{Op: "dial", Net: proto, Source: laddr, Addr: raddr, Err: err}
 	}
 	return newFD(proto, name, f, data, laddr, raddr)
 }
@@ -177,52 +194,52 @@
 	defer func() { netErr(err) }()
 	f, dest, proto, name, err := startPlan9(net, laddr)
 	if err != nil {
-		return nil, &OpError{"listen", net, laddr, err}
+		return nil, &OpError{Op: "listen", Net: net, Source: nil, Addr: laddr, Err: err}
 	}
 	_, err = f.WriteString("announce " + dest)
 	if err != nil {
 		f.Close()
-		return nil, &OpError{"announce", proto, laddr, err}
+		return nil, &OpError{Op: "announce", Net: proto, Source: nil, Addr: laddr, Err: err}
 	}
 	laddr, err = readPlan9Addr(proto, netdir+"/"+proto+"/"+name+"/local")
 	if err != nil {
 		f.Close()
-		return nil, &OpError{Op: "listen", Net: net, Err: err}
+		return nil, &OpError{Op: "listen", Net: net, Source: nil, Addr: laddr, Err: err}
 	}
 	return newFD(proto, name, f, nil, laddr, nil)
 }
 
-func (l *netFD) netFD() (*netFD, error) {
-	return newFD(l.proto, l.n, l.ctl, l.data, l.laddr, l.raddr)
+func (fd *netFD) netFD() (*netFD, error) {
+	return newFD(fd.net, fd.n, fd.ctl, fd.data, fd.laddr, fd.raddr)
 }
 
-func (l *netFD) acceptPlan9() (fd *netFD, err error) {
+func (fd *netFD) acceptPlan9() (nfd *netFD, err error) {
 	defer func() { netErr(err) }()
-	if err := l.readLock(); err != nil {
+	if err := fd.readLock(); err != nil {
 		return nil, err
 	}
-	defer l.readUnlock()
-	f, err := os.Open(l.dir + "/listen")
+	defer fd.readUnlock()
+	f, err := os.Open(fd.dir + "/listen")
 	if err != nil {
-		return nil, &OpError{"accept", l.dir + "/listen", l.laddr, err}
+		return nil, &OpError{Op: "accept", Net: fd.dir + "/listen", Source: nil, Addr: fd.laddr, Err: err}
 	}
 	var buf [16]byte
 	n, err := f.Read(buf[:])
 	if err != nil {
 		f.Close()
-		return nil, &OpError{"accept", l.dir + "/listen", l.laddr, err}
+		return nil, &OpError{Op: "accept", Net: fd.dir + "/listen", Source: nil, Addr: fd.laddr, Err: err}
 	}
 	name := string(buf[:n])
-	data, err := os.OpenFile(netdir+"/"+l.proto+"/"+name+"/data", os.O_RDWR, 0)
+	data, err := os.OpenFile(netdir+"/"+fd.net+"/"+name+"/data", os.O_RDWR, 0)
 	if err != nil {
 		f.Close()
-		return nil, &OpError{"accept", l.proto, l.laddr, err}
+		return nil, &OpError{Op: "accept", Net: fd.net, Source: nil, Addr: fd.laddr, Err: err}
 	}
-	raddr, err := readPlan9Addr(l.proto, netdir+"/"+l.proto+"/"+name+"/remote")
+	raddr, err := readPlan9Addr(fd.net, netdir+"/"+fd.net+"/"+name+"/remote")
 	if err != nil {
 		data.Close()
 		f.Close()
-		return nil, &OpError{"accept", l.proto, l.laddr, err}
+		return nil, &OpError{Op: "accept", Net: fd.net, Source: nil, Addr: fd.laddr, Err: err}
 	}
-	return newFD(l.proto, name, f, data, l.laddr, raddr)
+	return newFD(fd.net, name, f, data, fd.laddr, raddr)
 }
diff --git a/third_party/gofrontend/libgo/go/net/ipsock_posix.go b/third_party/gofrontend/libgo/go/net/ipsock_posix.go
index f9ebe40..83eaf85 100644
--- a/third_party/gofrontend/libgo/go/net/ipsock_posix.go
+++ b/third_party/gofrontend/libgo/go/net/ipsock_posix.go
@@ -9,17 +9,25 @@
 package net
 
 import (
+	"runtime"
 	"syscall"
 	"time"
 )
 
+// BUG(rsc,mikio): On DragonFly BSD and OpenBSD, listening on the
+// "tcp" and "udp" networks does not listen for both IPv4 and IPv6
+// connections. This is due to the fact that IPv4 traffic will not be
+// routed to an IPv6 socket - two separate sockets are required if
+// both address families are to be supported.
+// See inet6(4) for details.
+
 func probeIPv4Stack() bool {
-	s, err := syscall.Socket(syscall.AF_INET, syscall.SOCK_STREAM, syscall.IPPROTO_TCP)
+	s, err := socketFunc(syscall.AF_INET, syscall.SOCK_STREAM, syscall.IPPROTO_TCP)
 	switch err {
 	case syscall.EAFNOSUPPORT, syscall.EPROTONOSUPPORT:
 		return false
 	case nil:
-		closesocket(s)
+		closeFunc(s)
 	}
 	return true
 }
@@ -41,20 +49,35 @@
 	var probes = []struct {
 		laddr TCPAddr
 		value int
-		ok    bool
 	}{
 		// IPv6 communication capability
 		{laddr: TCPAddr{IP: ParseIP("::1")}, value: 1},
 		// IPv6 IPv4-mapped address communication capability
 		{laddr: TCPAddr{IP: IPv4(127, 0, 0, 1)}, value: 0},
 	}
+	var supps [2]bool
+	switch runtime.GOOS {
+	case "dragonfly", "openbsd":
+		// Some released versions of DragonFly BSD pretend to
+		// accept IPV6_V6ONLY=0 successfully, but the state
+		// still stays IPV6_V6ONLY=1. Eventually DragonFly BSD
+		// stops preteding, but the transition period would
+		// cause unpredictable behavior and we need to avoid
+		// it.
+		//
+		// OpenBSD also doesn't support IPV6_V6ONLY=0 but it
+		// never pretends to accept IPV6_V6OLY=0. It always
+		// returns an error and we don't need to probe the
+		// capability.
+		probes = probes[:1]
+	}
 
 	for i := range probes {
-		s, err := syscall.Socket(syscall.AF_INET6, syscall.SOCK_STREAM, syscall.IPPROTO_TCP)
+		s, err := socketFunc(syscall.AF_INET6, syscall.SOCK_STREAM, syscall.IPPROTO_TCP)
 		if err != nil {
 			continue
 		}
-		defer closesocket(s)
+		defer closeFunc(s)
 		syscall.SetsockoptInt(s, syscall.IPPROTO_IPV6, syscall.IPV6_V6ONLY, probes[i].value)
 		sa, err := probes[i].laddr.sockaddr(syscall.AF_INET6)
 		if err != nil {
@@ -63,10 +86,10 @@
 		if err := syscall.Bind(s, sa); err != nil {
 			continue
 		}
-		probes[i].ok = true
+		supps[i] = true
 	}
 
-	return probes[0].ok, probes[1].ok
+	return supps[0], supps[1]
 }
 
 // favoriteAddrFamily returns the appropriate address family to
@@ -144,7 +167,7 @@
 			ip = IPv4zero
 		}
 		if ip = ip.To4(); ip == nil {
-			return nil, InvalidAddrError("non-IPv4 address")
+			return nil, &AddrError{Err: "non-IPv4 address", Addr: ip.String()}
 		}
 		sa := new(syscall.SockaddrInet4)
 		for i := 0; i < IPv4len; i++ {
@@ -163,7 +186,7 @@
 			ip = IPv6zero
 		}
 		if ip = ip.To16(); ip == nil {
-			return nil, InvalidAddrError("non-IPv6 address")
+			return nil, &AddrError{Err: "non-IPv6 address", Addr: ip.String()}
 		}
 		sa := new(syscall.SockaddrInet6)
 		for i := 0; i < IPv6len; i++ {
@@ -173,5 +196,5 @@
 		sa.ZoneId = uint32(zoneToInt(zone))
 		return sa, nil
 	}
-	return nil, InvalidAddrError("unexpected socket family")
+	return nil, &AddrError{Err: "invalid address family", Addr: ip.String()}
 }
diff --git a/third_party/gofrontend/libgo/go/net/ipsock_test.go b/third_party/gofrontend/libgo/go/net/ipsock_test.go
index 9ecaaec..b36557a 100644
--- a/third_party/gofrontend/libgo/go/net/ipsock_test.go
+++ b/third_party/gofrontend/libgo/go/net/ipsock_test.go
@@ -9,185 +9,274 @@
 	"testing"
 )
 
-var testInetaddr = func(ip IP) netaddr { return &TCPAddr{IP: ip, Port: 5682} }
+var testInetaddr = func(ip IPAddr) Addr { return &TCPAddr{IP: ip.IP, Port: 5682, Zone: ip.Zone} }
 
-var firstFavoriteAddrTests = []struct {
-	filter   func(IP) IP
-	ips      []IP
-	inetaddr func(IP) netaddr
-	addr     netaddr
-	err      error
+var addrListTests = []struct {
+	filter    func(IPAddr) bool
+	ips       []IPAddr
+	inetaddr  func(IPAddr) Addr
+	first     Addr
+	primaries addrList
+	fallbacks addrList
+	err       error
 }{
 	{
 		nil,
-		[]IP{
-			IPv4(127, 0, 0, 1),
-			IPv6loopback,
-		},
-		testInetaddr,
-		addrList{
-			&TCPAddr{IP: IPv4(127, 0, 0, 1), Port: 5682},
-			&TCPAddr{IP: IPv6loopback, Port: 5682},
-		},
-		nil,
-	},
-	{
-		nil,
-		[]IP{
-			IPv6loopback,
-			IPv4(127, 0, 0, 1),
-		},
-		testInetaddr,
-		addrList{
-			&TCPAddr{IP: IPv4(127, 0, 0, 1), Port: 5682},
-			&TCPAddr{IP: IPv6loopback, Port: 5682},
-		},
-		nil,
-	},
-	{
-		nil,
-		[]IP{
-			IPv4(127, 0, 0, 1),
-			IPv4(192, 168, 0, 1),
+		[]IPAddr{
+			{IP: IPv4(127, 0, 0, 1)},
+			{IP: IPv6loopback},
 		},
 		testInetaddr,
 		&TCPAddr{IP: IPv4(127, 0, 0, 1), Port: 5682},
+		addrList{&TCPAddr{IP: IPv4(127, 0, 0, 1), Port: 5682}},
+		addrList{&TCPAddr{IP: IPv6loopback, Port: 5682}},
 		nil,
 	},
 	{
 		nil,
-		[]IP{
-			IPv6loopback,
-			ParseIP("fe80::1"),
+		[]IPAddr{
+			{IP: IPv6loopback},
+			{IP: IPv4(127, 0, 0, 1)},
+		},
+		testInetaddr,
+		&TCPAddr{IP: IPv4(127, 0, 0, 1), Port: 5682},
+		addrList{&TCPAddr{IP: IPv6loopback, Port: 5682}},
+		addrList{&TCPAddr{IP: IPv4(127, 0, 0, 1), Port: 5682}},
+		nil,
+	},
+	{
+		nil,
+		[]IPAddr{
+			{IP: IPv4(127, 0, 0, 1)},
+			{IP: IPv4(192, 168, 0, 1)},
+		},
+		testInetaddr,
+		&TCPAddr{IP: IPv4(127, 0, 0, 1), Port: 5682},
+		addrList{
+			&TCPAddr{IP: IPv4(127, 0, 0, 1), Port: 5682},
+			&TCPAddr{IP: IPv4(192, 168, 0, 1), Port: 5682},
+		},
+		nil,
+		nil,
+	},
+	{
+		nil,
+		[]IPAddr{
+			{IP: IPv6loopback},
+			{IP: ParseIP("fe80::1"), Zone: "eth0"},
 		},
 		testInetaddr,
 		&TCPAddr{IP: IPv6loopback, Port: 5682},
+		addrList{
+			&TCPAddr{IP: IPv6loopback, Port: 5682},
+			&TCPAddr{IP: ParseIP("fe80::1"), Port: 5682, Zone: "eth0"},
+		},
+		nil,
 		nil,
 	},
 	{
 		nil,
-		[]IP{
-			IPv4(127, 0, 0, 1),
-			IPv4(192, 168, 0, 1),
-			IPv6loopback,
-			ParseIP("fe80::1"),
+		[]IPAddr{
+			{IP: IPv4(127, 0, 0, 1)},
+			{IP: IPv4(192, 168, 0, 1)},
+			{IP: IPv6loopback},
+			{IP: ParseIP("fe80::1"), Zone: "eth0"},
 		},
 		testInetaddr,
+		&TCPAddr{IP: IPv4(127, 0, 0, 1), Port: 5682},
 		addrList{
 			&TCPAddr{IP: IPv4(127, 0, 0, 1), Port: 5682},
+			&TCPAddr{IP: IPv4(192, 168, 0, 1), Port: 5682},
+		},
+		addrList{
 			&TCPAddr{IP: IPv6loopback, Port: 5682},
+			&TCPAddr{IP: ParseIP("fe80::1"), Port: 5682, Zone: "eth0"},
 		},
 		nil,
 	},
 	{
 		nil,
-		[]IP{
-			IPv6loopback,
-			ParseIP("fe80::1"),
-			IPv4(127, 0, 0, 1),
-			IPv4(192, 168, 0, 1),
+		[]IPAddr{
+			{IP: IPv6loopback},
+			{IP: ParseIP("fe80::1"), Zone: "eth0"},
+			{IP: IPv4(127, 0, 0, 1)},
+			{IP: IPv4(192, 168, 0, 1)},
 		},
 		testInetaddr,
+		&TCPAddr{IP: IPv4(127, 0, 0, 1), Port: 5682},
+		addrList{
+			&TCPAddr{IP: IPv6loopback, Port: 5682},
+			&TCPAddr{IP: ParseIP("fe80::1"), Port: 5682, Zone: "eth0"},
+		},
 		addrList{
 			&TCPAddr{IP: IPv4(127, 0, 0, 1), Port: 5682},
-			&TCPAddr{IP: IPv6loopback, Port: 5682},
+			&TCPAddr{IP: IPv4(192, 168, 0, 1), Port: 5682},
 		},
 		nil,
 	},
 	{
 		nil,
-		[]IP{
-			IPv4(127, 0, 0, 1),
-			IPv6loopback,
-			IPv4(192, 168, 0, 1),
-			ParseIP("fe80::1"),
+		[]IPAddr{
+			{IP: IPv4(127, 0, 0, 1)},
+			{IP: IPv6loopback},
+			{IP: IPv4(192, 168, 0, 1)},
+			{IP: ParseIP("fe80::1"), Zone: "eth0"},
 		},
 		testInetaddr,
+		&TCPAddr{IP: IPv4(127, 0, 0, 1), Port: 5682},
 		addrList{
 			&TCPAddr{IP: IPv4(127, 0, 0, 1), Port: 5682},
+			&TCPAddr{IP: IPv4(192, 168, 0, 1), Port: 5682},
+		},
+		addrList{
 			&TCPAddr{IP: IPv6loopback, Port: 5682},
+			&TCPAddr{IP: ParseIP("fe80::1"), Port: 5682, Zone: "eth0"},
 		},
 		nil,
 	},
 	{
 		nil,
-		[]IP{
-			IPv6loopback,
-			IPv4(127, 0, 0, 1),
-			ParseIP("fe80::1"),
-			IPv4(192, 168, 0, 1),
+		[]IPAddr{
+			{IP: IPv6loopback},
+			{IP: IPv4(127, 0, 0, 1)},
+			{IP: ParseIP("fe80::1"), Zone: "eth0"},
+			{IP: IPv4(192, 168, 0, 1)},
 		},
 		testInetaddr,
+		&TCPAddr{IP: IPv4(127, 0, 0, 1), Port: 5682},
+		addrList{
+			&TCPAddr{IP: IPv6loopback, Port: 5682},
+			&TCPAddr{IP: ParseIP("fe80::1"), Port: 5682, Zone: "eth0"},
+		},
 		addrList{
 			&TCPAddr{IP: IPv4(127, 0, 0, 1), Port: 5682},
-			&TCPAddr{IP: IPv6loopback, Port: 5682},
+			&TCPAddr{IP: IPv4(192, 168, 0, 1), Port: 5682},
 		},
 		nil,
 	},
 
 	{
 		ipv4only,
-		[]IP{
-			IPv4(127, 0, 0, 1),
-			IPv6loopback,
+		[]IPAddr{
+			{IP: IPv4(127, 0, 0, 1)},
+			{IP: IPv6loopback},
 		},
 		testInetaddr,
 		&TCPAddr{IP: IPv4(127, 0, 0, 1), Port: 5682},
+		addrList{&TCPAddr{IP: IPv4(127, 0, 0, 1), Port: 5682}},
+		nil,
 		nil,
 	},
 	{
 		ipv4only,
-		[]IP{
-			IPv6loopback,
-			IPv4(127, 0, 0, 1),
+		[]IPAddr{
+			{IP: IPv6loopback},
+			{IP: IPv4(127, 0, 0, 1)},
 		},
 		testInetaddr,
 		&TCPAddr{IP: IPv4(127, 0, 0, 1), Port: 5682},
+		addrList{&TCPAddr{IP: IPv4(127, 0, 0, 1), Port: 5682}},
+		nil,
 		nil,
 	},
 
 	{
 		ipv6only,
-		[]IP{
-			IPv4(127, 0, 0, 1),
-			IPv6loopback,
+		[]IPAddr{
+			{IP: IPv4(127, 0, 0, 1)},
+			{IP: IPv6loopback},
 		},
 		testInetaddr,
 		&TCPAddr{IP: IPv6loopback, Port: 5682},
+		addrList{&TCPAddr{IP: IPv6loopback, Port: 5682}},
+		nil,
 		nil,
 	},
 	{
 		ipv6only,
-		[]IP{
-			IPv6loopback,
-			IPv4(127, 0, 0, 1),
+		[]IPAddr{
+			{IP: IPv6loopback},
+			{IP: IPv4(127, 0, 0, 1)},
 		},
 		testInetaddr,
 		&TCPAddr{IP: IPv6loopback, Port: 5682},
+		addrList{&TCPAddr{IP: IPv6loopback, Port: 5682}},
+		nil,
 		nil,
 	},
 
-	{nil, nil, testInetaddr, nil, errNoSuitableAddress},
+	{nil, nil, testInetaddr, nil, nil, nil, errNoSuitableAddress},
 
-	{ipv4only, nil, testInetaddr, nil, errNoSuitableAddress},
-	{ipv4only, []IP{IPv6loopback}, testInetaddr, nil, errNoSuitableAddress},
+	{ipv4only, nil, testInetaddr, nil, nil, nil, errNoSuitableAddress},
+	{ipv4only, []IPAddr{{IP: IPv6loopback}}, testInetaddr, nil, nil, nil, errNoSuitableAddress},
 
-	{ipv6only, nil, testInetaddr, nil, errNoSuitableAddress},
-	{ipv6only, []IP{IPv4(127, 0, 0, 1)}, testInetaddr, nil, errNoSuitableAddress},
+	{ipv6only, nil, testInetaddr, nil, nil, nil, errNoSuitableAddress},
+	{ipv6only, []IPAddr{{IP: IPv4(127, 0, 0, 1)}}, testInetaddr, nil, nil, nil, errNoSuitableAddress},
 }
 
-func TestFirstFavoriteAddr(t *testing.T) {
+func TestAddrList(t *testing.T) {
 	if !supportsIPv4 || !supportsIPv6 {
-		t.Skip("ipv4 or ipv6 is not supported")
+		t.Skip("both IPv4 and IPv6 are required")
 	}
 
-	for i, tt := range firstFavoriteAddrTests {
-		addr, err := firstFavoriteAddr(tt.filter, tt.ips, tt.inetaddr)
+	for i, tt := range addrListTests {
+		addrs, err := filterAddrList(tt.filter, tt.ips, tt.inetaddr)
 		if err != tt.err {
-			t.Errorf("#%v: got %v; expected %v", i, err, tt.err)
+			t.Errorf("#%v: got %v; want %v", i, err, tt.err)
 		}
-		if !reflect.DeepEqual(addr, tt.addr) {
-			t.Errorf("#%v: got %v; expected %v", i, addr, tt.addr)
+		if tt.err != nil {
+			if len(addrs) != 0 {
+				t.Errorf("#%v: got %v; want 0", i, len(addrs))
+			}
+			continue
+		}
+		first := addrs.first(isIPv4)
+		if !reflect.DeepEqual(first, tt.first) {
+			t.Errorf("#%v: got %v; want %v", i, first, tt.first)
+		}
+		primaries, fallbacks := addrs.partition(isIPv4)
+		if !reflect.DeepEqual(primaries, tt.primaries) {
+			t.Errorf("#%v: got %v; want %v", i, primaries, tt.primaries)
+		}
+		if !reflect.DeepEqual(fallbacks, tt.fallbacks) {
+			t.Errorf("#%v: got %v; want %v", i, fallbacks, tt.fallbacks)
+		}
+		expectedLen := len(primaries) + len(fallbacks)
+		if len(addrs) != expectedLen {
+			t.Errorf("#%v: got %v; want %v", i, len(addrs), expectedLen)
+		}
+	}
+}
+
+func TestAddrListPartition(t *testing.T) {
+	addrs := addrList{
+		&IPAddr{IP: ParseIP("fe80::"), Zone: "eth0"},
+		&IPAddr{IP: ParseIP("fe80::1"), Zone: "eth0"},
+		&IPAddr{IP: ParseIP("fe80::2"), Zone: "eth0"},
+	}
+	cases := []struct {
+		lastByte  byte
+		primaries addrList
+		fallbacks addrList
+	}{
+		{0, addrList{addrs[0]}, addrList{addrs[1], addrs[2]}},
+		{1, addrList{addrs[0], addrs[2]}, addrList{addrs[1]}},
+		{2, addrList{addrs[0], addrs[1]}, addrList{addrs[2]}},
+		{3, addrList{addrs[0], addrs[1], addrs[2]}, nil},
+	}
+	for i, tt := range cases {
+		// Inverting the function's output should not affect the outcome.
+		for _, invert := range []bool{false, true} {
+			primaries, fallbacks := addrs.partition(func(a Addr) bool {
+				ip := a.(*IPAddr).IP
+				return (ip[len(ip)-1] == tt.lastByte) != invert
+			})
+			if !reflect.DeepEqual(primaries, tt.primaries) {
+				t.Errorf("#%v: got %v; want %v", i, primaries, tt.primaries)
+			}
+			if !reflect.DeepEqual(fallbacks, tt.fallbacks) {
+				t.Errorf("#%v: got %v; want %v", i, fallbacks, tt.fallbacks)
+			}
 		}
 	}
 }
diff --git a/third_party/gofrontend/libgo/go/net/listen_test.go b/third_party/gofrontend/libgo/go/net/listen_test.go
new file mode 100644
index 0000000..51ffe67
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/net/listen_test.go
@@ -0,0 +1,685 @@
+// Copyright 2011 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 !plan9
+
+package net
+
+import (
+	"fmt"
+	"os"
+	"runtime"
+	"syscall"
+	"testing"
+)
+
+func (ln *TCPListener) port() string {
+	_, port, err := SplitHostPort(ln.Addr().String())
+	if err != nil {
+		return ""
+	}
+	return port
+}
+
+func (c *UDPConn) port() string {
+	_, port, err := SplitHostPort(c.LocalAddr().String())
+	if err != nil {
+		return ""
+	}
+	return port
+}
+
+var tcpListenerTests = []struct {
+	network string
+	address string
+}{
+	{"tcp", ""},
+	{"tcp", "0.0.0.0"},
+	{"tcp", "::ffff:0.0.0.0"},
+	{"tcp", "::"},
+
+	{"tcp", "127.0.0.1"},
+	{"tcp", "::ffff:127.0.0.1"},
+	{"tcp", "::1"},
+
+	{"tcp4", ""},
+	{"tcp4", "0.0.0.0"},
+	{"tcp4", "::ffff:0.0.0.0"},
+
+	{"tcp4", "127.0.0.1"},
+	{"tcp4", "::ffff:127.0.0.1"},
+
+	{"tcp6", ""},
+	{"tcp6", "::"},
+
+	{"tcp6", "::1"},
+}
+
+// TestTCPListener tests both single and double listen to a test
+// listener with same address family, same listening address and
+// same port.
+func TestTCPListener(t *testing.T) {
+	switch runtime.GOOS {
+	case "plan9":
+		t.Skipf("not supported on %s", runtime.GOOS)
+	}
+
+	for _, tt := range tcpListenerTests {
+		if !testableListenArgs(tt.network, JoinHostPort(tt.address, "0"), "") {
+			t.Logf("skipping %s test", tt.network+" "+tt.address)
+			continue
+		}
+
+		ln1, err := Listen(tt.network, JoinHostPort(tt.address, "0"))
+		if err != nil {
+			t.Fatal(err)
+		}
+		if err := checkFirstListener(tt.network, ln1); err != nil {
+			ln1.Close()
+			t.Fatal(err)
+		}
+		ln2, err := Listen(tt.network, JoinHostPort(tt.address, ln1.(*TCPListener).port()))
+		if err == nil {
+			ln2.Close()
+		}
+		if err := checkSecondListener(tt.network, tt.address, err); err != nil {
+			ln1.Close()
+			t.Fatal(err)
+		}
+		ln1.Close()
+	}
+}
+
+var udpListenerTests = []struct {
+	network string
+	address string
+}{
+	{"udp", ""},
+	{"udp", "0.0.0.0"},
+	{"udp", "::ffff:0.0.0.0"},
+	{"udp", "::"},
+
+	{"udp", "127.0.0.1"},
+	{"udp", "::ffff:127.0.0.1"},
+	{"udp", "::1"},
+
+	{"udp4", ""},
+	{"udp4", "0.0.0.0"},
+	{"udp4", "::ffff:0.0.0.0"},
+
+	{"udp4", "127.0.0.1"},
+	{"udp4", "::ffff:127.0.0.1"},
+
+	{"udp6", ""},
+	{"udp6", "::"},
+
+	{"udp6", "::1"},
+}
+
+// TestUDPListener tests both single and double listen to a test
+// listener with same address family, same listening address and
+// same port.
+func TestUDPListener(t *testing.T) {
+	switch runtime.GOOS {
+	case "plan9":
+		t.Skipf("not supported on %s", runtime.GOOS)
+	}
+
+	for _, tt := range udpListenerTests {
+		if !testableListenArgs(tt.network, JoinHostPort(tt.address, "0"), "") {
+			t.Logf("skipping %s test", tt.network+" "+tt.address)
+			continue
+		}
+
+		c1, err := ListenPacket(tt.network, JoinHostPort(tt.address, "0"))
+		if err != nil {
+			t.Fatal(err)
+		}
+		if err := checkFirstListener(tt.network, c1); err != nil {
+			c1.Close()
+			t.Fatal(err)
+		}
+		c2, err := ListenPacket(tt.network, JoinHostPort(tt.address, c1.(*UDPConn).port()))
+		if err == nil {
+			c2.Close()
+		}
+		if err := checkSecondListener(tt.network, tt.address, err); err != nil {
+			c1.Close()
+			t.Fatal(err)
+		}
+		c1.Close()
+	}
+}
+
+var dualStackTCPListenerTests = []struct {
+	network1, address1 string // first listener
+	network2, address2 string // second listener
+	xerr               error  // expected error value, nil or other
+}{
+	// Test cases and expected results for the attemping 2nd listen on the same port
+	// 1st listen                2nd listen                 darwin  freebsd  linux  openbsd
+	// ------------------------------------------------------------------------------------
+	// "tcp"  ""                 "tcp"  ""                    -        -       -       -
+	// "tcp"  ""                 "tcp"  "0.0.0.0"             -        -       -       -
+	// "tcp"  "0.0.0.0"          "tcp"  ""                    -        -       -       -
+	// ------------------------------------------------------------------------------------
+	// "tcp"  ""                 "tcp"  "[::]"                -        -       -       ok
+	// "tcp"  "[::]"             "tcp"  ""                    -        -       -       ok
+	// "tcp"  "0.0.0.0"          "tcp"  "[::]"                -        -       -       ok
+	// "tcp"  "[::]"             "tcp"  "0.0.0.0"             -        -       -       ok
+	// "tcp"  "[::ffff:0.0.0.0]" "tcp"  "[::]"                -        -       -       ok
+	// "tcp"  "[::]"             "tcp"  "[::ffff:0.0.0.0]"    -        -       -       ok
+	// ------------------------------------------------------------------------------------
+	// "tcp4" ""                 "tcp6" ""                    ok       ok      ok      ok
+	// "tcp6" ""                 "tcp4" ""                    ok       ok      ok      ok
+	// "tcp4" "0.0.0.0"          "tcp6" "[::]"                ok       ok      ok      ok
+	// "tcp6" "[::]"             "tcp4" "0.0.0.0"             ok       ok      ok      ok
+	// ------------------------------------------------------------------------------------
+	// "tcp"  "127.0.0.1"        "tcp"  "[::1]"               ok       ok      ok      ok
+	// "tcp"  "[::1]"            "tcp"  "127.0.0.1"           ok       ok      ok      ok
+	// "tcp4" "127.0.0.1"        "tcp6" "[::1]"               ok       ok      ok      ok
+	// "tcp6" "[::1]"            "tcp4" "127.0.0.1"           ok       ok      ok      ok
+	//
+	// Platform default configurations:
+	// darwin, kernel version 11.3.0
+	//	net.inet6.ip6.v6only=0 (overridable by sysctl or IPV6_V6ONLY option)
+	// freebsd, kernel version 8.2
+	//	net.inet6.ip6.v6only=1 (overridable by sysctl or IPV6_V6ONLY option)
+	// linux, kernel version 3.0.0
+	//	net.ipv6.bindv6only=0 (overridable by sysctl or IPV6_V6ONLY option)
+	// openbsd, kernel version 5.0
+	//	net.inet6.ip6.v6only=1 (overriding is prohibited)
+
+	{"tcp", "", "tcp", "", syscall.EADDRINUSE},
+	{"tcp", "", "tcp", "0.0.0.0", syscall.EADDRINUSE},
+	{"tcp", "0.0.0.0", "tcp", "", syscall.EADDRINUSE},
+
+	{"tcp", "", "tcp", "::", syscall.EADDRINUSE},
+	{"tcp", "::", "tcp", "", syscall.EADDRINUSE},
+	{"tcp", "0.0.0.0", "tcp", "::", syscall.EADDRINUSE},
+	{"tcp", "::", "tcp", "0.0.0.0", syscall.EADDRINUSE},
+	{"tcp", "::ffff:0.0.0.0", "tcp", "::", syscall.EADDRINUSE},
+	{"tcp", "::", "tcp", "::ffff:0.0.0.0", syscall.EADDRINUSE},
+
+	{"tcp4", "", "tcp6", "", nil},
+	{"tcp6", "", "tcp4", "", nil},
+	{"tcp4", "0.0.0.0", "tcp6", "::", nil},
+	{"tcp6", "::", "tcp4", "0.0.0.0", nil},
+
+	{"tcp", "127.0.0.1", "tcp", "::1", nil},
+	{"tcp", "::1", "tcp", "127.0.0.1", nil},
+	{"tcp4", "127.0.0.1", "tcp6", "::1", nil},
+	{"tcp6", "::1", "tcp4", "127.0.0.1", nil},
+}
+
+// TestDualStackTCPListener tests both single and double listen
+// to a test listener with various address families, different
+// listening address and same port.
+func TestDualStackTCPListener(t *testing.T) {
+	switch runtime.GOOS {
+	case "dragonfly", "nacl", "plan9": // re-enable on dragonfly once the new IP control block management has landed
+		t.Skipf("not supported on %s", runtime.GOOS)
+	}
+	if !supportsIPv4 || !supportsIPv6 {
+		t.Skip("both IPv4 and IPv6 are required")
+	}
+
+	for _, tt := range dualStackTCPListenerTests {
+		if !testableListenArgs(tt.network1, JoinHostPort(tt.address1, "0"), "") {
+			t.Logf("skipping %s test", tt.network1+" "+tt.address1)
+			continue
+		}
+
+		if !supportsIPv4map && differentWildcardAddr(tt.address1, tt.address2) {
+			tt.xerr = nil
+		}
+		var firstErr, secondErr error
+		for i := 0; i < 5; i++ {
+			lns, err := newDualStackListener()
+			if err != nil {
+				t.Fatal(err)
+			}
+			port := lns[0].port()
+			for _, ln := range lns {
+				ln.Close()
+			}
+			var ln1 Listener
+			ln1, firstErr = Listen(tt.network1, JoinHostPort(tt.address1, port))
+			if firstErr != nil {
+				continue
+			}
+			if err := checkFirstListener(tt.network1, ln1); err != nil {
+				ln1.Close()
+				t.Fatal(err)
+			}
+			ln2, err := Listen(tt.network2, JoinHostPort(tt.address2, ln1.(*TCPListener).port()))
+			if err == nil {
+				ln2.Close()
+			}
+			if secondErr = checkDualStackSecondListener(tt.network2, tt.address2, err, tt.xerr); secondErr != nil {
+				ln1.Close()
+				continue
+			}
+			ln1.Close()
+			break
+		}
+		if firstErr != nil {
+			t.Error(firstErr)
+		}
+		if secondErr != nil {
+			t.Error(secondErr)
+		}
+	}
+}
+
+var dualStackUDPListenerTests = []struct {
+	network1, address1 string // first listener
+	network2, address2 string // second listener
+	xerr               error  // expected error value, nil or other
+}{
+	{"udp", "", "udp", "", syscall.EADDRINUSE},
+	{"udp", "", "udp", "0.0.0.0", syscall.EADDRINUSE},
+	{"udp", "0.0.0.0", "udp", "", syscall.EADDRINUSE},
+
+	{"udp", "", "udp", "::", syscall.EADDRINUSE},
+	{"udp", "::", "udp", "", syscall.EADDRINUSE},
+	{"udp", "0.0.0.0", "udp", "::", syscall.EADDRINUSE},
+	{"udp", "::", "udp", "0.0.0.0", syscall.EADDRINUSE},
+	{"udp", "::ffff:0.0.0.0", "udp", "::", syscall.EADDRINUSE},
+	{"udp", "::", "udp", "::ffff:0.0.0.0", syscall.EADDRINUSE},
+
+	{"udp4", "", "udp6", "", nil},
+	{"udp6", "", "udp4", "", nil},
+	{"udp4", "0.0.0.0", "udp6", "::", nil},
+	{"udp6", "::", "udp4", "0.0.0.0", nil},
+
+	{"udp", "127.0.0.1", "udp", "::1", nil},
+	{"udp", "::1", "udp", "127.0.0.1", nil},
+	{"udp4", "127.0.0.1", "udp6", "::1", nil},
+	{"udp6", "::1", "udp4", "127.0.0.1", nil},
+}
+
+// TestDualStackUDPListener tests both single and double listen
+// to a test listener with various address families, differnet
+// listening address and same port.
+func TestDualStackUDPListener(t *testing.T) {
+	switch runtime.GOOS {
+	case "dragonfly", "nacl", "plan9": // re-enable on dragonfly once the new IP control block management has landed
+		t.Skipf("not supported on %s", runtime.GOOS)
+	}
+	if !supportsIPv4 || !supportsIPv6 {
+		t.Skip("both IPv4 and IPv6 are required")
+	}
+
+	for _, tt := range dualStackUDPListenerTests {
+		if !testableListenArgs(tt.network1, JoinHostPort(tt.address1, "0"), "") {
+			t.Logf("skipping %s test", tt.network1+" "+tt.address1)
+			continue
+		}
+
+		if !supportsIPv4map && differentWildcardAddr(tt.address1, tt.address2) {
+			tt.xerr = nil
+		}
+		var firstErr, secondErr error
+		for i := 0; i < 5; i++ {
+			cs, err := newDualStackPacketListener()
+			if err != nil {
+				t.Fatal(err)
+			}
+			port := cs[0].port()
+			for _, c := range cs {
+				c.Close()
+			}
+			var c1 PacketConn
+			c1, firstErr = ListenPacket(tt.network1, JoinHostPort(tt.address1, port))
+			if firstErr != nil {
+				continue
+			}
+			if err := checkFirstListener(tt.network1, c1); err != nil {
+				c1.Close()
+				t.Fatal(err)
+			}
+			c2, err := ListenPacket(tt.network2, JoinHostPort(tt.address2, c1.(*UDPConn).port()))
+			if err == nil {
+				c2.Close()
+			}
+			if secondErr = checkDualStackSecondListener(tt.network2, tt.address2, err, tt.xerr); secondErr != nil {
+				c1.Close()
+				continue
+			}
+			c1.Close()
+			break
+		}
+		if firstErr != nil {
+			t.Error(firstErr)
+		}
+		if secondErr != nil {
+			t.Error(secondErr)
+		}
+	}
+}
+
+func differentWildcardAddr(i, j string) bool {
+	if (i == "" || i == "0.0.0.0" || i == "::ffff:0.0.0.0") && (j == "" || j == "0.0.0.0" || j == "::ffff:0.0.0.0") {
+		return false
+	}
+	if i == "[::]" && j == "[::]" {
+		return false
+	}
+	return true
+}
+
+func checkFirstListener(network string, ln interface{}) error {
+	switch network {
+	case "tcp":
+		fd := ln.(*TCPListener).fd
+		if err := checkDualStackAddrFamily(fd); err != nil {
+			return err
+		}
+	case "tcp4":
+		fd := ln.(*TCPListener).fd
+		if fd.family != syscall.AF_INET {
+			return fmt.Errorf("%v got %v; want %v", fd.laddr, fd.family, syscall.AF_INET)
+		}
+	case "tcp6":
+		fd := ln.(*TCPListener).fd
+		if fd.family != syscall.AF_INET6 {
+			return fmt.Errorf("%v got %v; want %v", fd.laddr, fd.family, syscall.AF_INET6)
+		}
+	case "udp":
+		fd := ln.(*UDPConn).fd
+		if err := checkDualStackAddrFamily(fd); err != nil {
+			return err
+		}
+	case "udp4":
+		fd := ln.(*UDPConn).fd
+		if fd.family != syscall.AF_INET {
+			return fmt.Errorf("%v got %v; want %v", fd.laddr, fd.family, syscall.AF_INET)
+		}
+	case "udp6":
+		fd := ln.(*UDPConn).fd
+		if fd.family != syscall.AF_INET6 {
+			return fmt.Errorf("%v got %v; want %v", fd.laddr, fd.family, syscall.AF_INET6)
+		}
+	default:
+		return UnknownNetworkError(network)
+	}
+	return nil
+}
+
+func checkSecondListener(network, address string, err error) error {
+	switch network {
+	case "tcp", "tcp4", "tcp6":
+		if err == nil {
+			return fmt.Errorf("%s should fail", network+" "+address)
+		}
+	case "udp", "udp4", "udp6":
+		if err == nil {
+			return fmt.Errorf("%s should fail", network+" "+address)
+		}
+	default:
+		return UnknownNetworkError(network)
+	}
+	return nil
+}
+
+func checkDualStackSecondListener(network, address string, err, xerr error) error {
+	switch network {
+	case "tcp", "tcp4", "tcp6":
+		if xerr == nil && err != nil || xerr != nil && err == nil {
+			return fmt.Errorf("%s got %v; want %v", network+" "+address, err, xerr)
+		}
+	case "udp", "udp4", "udp6":
+		if xerr == nil && err != nil || xerr != nil && err == nil {
+			return fmt.Errorf("%s got %v; want %v", network+" "+address, err, xerr)
+		}
+	default:
+		return UnknownNetworkError(network)
+	}
+	return nil
+}
+
+func checkDualStackAddrFamily(fd *netFD) error {
+	switch a := fd.laddr.(type) {
+	case *TCPAddr:
+		// If a node under test supports both IPv6 capability
+		// and IPv6 IPv4-mapping capability, we can assume
+		// that the node listens on a wildcard address with an
+		// AF_INET6 socket.
+		if supportsIPv4map && fd.laddr.(*TCPAddr).isWildcard() {
+			if fd.family != syscall.AF_INET6 {
+				return fmt.Errorf("Listen(%s, %v) returns %v; want %v", fd.net, fd.laddr, fd.family, syscall.AF_INET6)
+			}
+		} else {
+			if fd.family != a.family() {
+				return fmt.Errorf("Listen(%s, %v) returns %v; want %v", fd.net, fd.laddr, fd.family, a.family())
+			}
+		}
+	case *UDPAddr:
+		// If a node under test supports both IPv6 capability
+		// and IPv6 IPv4-mapping capability, we can assume
+		// that the node listens on a wildcard address with an
+		// AF_INET6 socket.
+		if supportsIPv4map && fd.laddr.(*UDPAddr).isWildcard() {
+			if fd.family != syscall.AF_INET6 {
+				return fmt.Errorf("ListenPacket(%s, %v) returns %v; want %v", fd.net, fd.laddr, fd.family, syscall.AF_INET6)
+			}
+		} else {
+			if fd.family != a.family() {
+				return fmt.Errorf("ListenPacket(%s, %v) returns %v; want %v", fd.net, fd.laddr, fd.family, a.family())
+			}
+		}
+	default:
+		return fmt.Errorf("unexpected protocol address type: %T", a)
+	}
+	return nil
+}
+
+func TestWildWildcardListener(t *testing.T) {
+	switch runtime.GOOS {
+	case "plan9":
+		t.Skipf("not supported on %s", runtime.GOOS)
+	}
+	if testing.Short() || !*testExternal {
+		t.Skip("avoid external network")
+	}
+
+	defer func() {
+		if p := recover(); p != nil {
+			t.Fatalf("panicked: %v", p)
+		}
+	}()
+
+	if ln, err := Listen("tcp", ""); err == nil {
+		ln.Close()
+	}
+	if ln, err := ListenPacket("udp", ""); err == nil {
+		ln.Close()
+	}
+	if ln, err := ListenTCP("tcp", nil); err == nil {
+		ln.Close()
+	}
+	if ln, err := ListenUDP("udp", nil); err == nil {
+		ln.Close()
+	}
+	if ln, err := ListenIP("ip:icmp", nil); err == nil {
+		ln.Close()
+	}
+}
+
+var ipv4MulticastListenerTests = []struct {
+	net   string
+	gaddr *UDPAddr // see RFC 4727
+}{
+	{"udp", &UDPAddr{IP: IPv4(224, 0, 0, 254), Port: 12345}},
+
+	{"udp4", &UDPAddr{IP: IPv4(224, 0, 0, 254), Port: 12345}},
+}
+
+// TestIPv4MulticastListener tests both single and double listen to a
+// test listener with same address family, same group address and same
+// port.
+func TestIPv4MulticastListener(t *testing.T) {
+	switch runtime.GOOS {
+	case "android", "nacl", "plan9":
+		t.Skipf("not supported on %s", runtime.GOOS)
+	case "solaris":
+		t.Skipf("not supported on solaris, see golang.org/issue/7399")
+	}
+
+	closer := func(cs []*UDPConn) {
+		for _, c := range cs {
+			if c != nil {
+				c.Close()
+			}
+		}
+	}
+
+	for _, ifi := range []*Interface{loopbackInterface(), nil} {
+		// Note that multicast interface assignment by system
+		// is not recommended because it usually relies on
+		// routing stuff for finding out an appropriate
+		// nexthop containing both network and link layer
+		// adjacencies.
+		if ifi == nil && (testing.Short() || !*testExternal) {
+			continue
+		}
+		for _, tt := range ipv4MulticastListenerTests {
+			var err error
+			cs := make([]*UDPConn, 2)
+			if cs[0], err = ListenMulticastUDP(tt.net, ifi, tt.gaddr); err != nil {
+				t.Fatal(err)
+			}
+			if err := checkMulticastListener(cs[0], tt.gaddr.IP); err != nil {
+				closer(cs)
+				t.Fatal(err)
+			}
+			if cs[1], err = ListenMulticastUDP(tt.net, ifi, tt.gaddr); err != nil {
+				closer(cs)
+				t.Fatal(err)
+			}
+			if err := checkMulticastListener(cs[1], tt.gaddr.IP); err != nil {
+				closer(cs)
+				t.Fatal(err)
+			}
+			closer(cs)
+		}
+	}
+}
+
+var ipv6MulticastListenerTests = []struct {
+	net   string
+	gaddr *UDPAddr // see RFC 4727
+}{
+	{"udp", &UDPAddr{IP: ParseIP("ff01::114"), Port: 12345}},
+	{"udp", &UDPAddr{IP: ParseIP("ff02::114"), Port: 12345}},
+	{"udp", &UDPAddr{IP: ParseIP("ff04::114"), Port: 12345}},
+	{"udp", &UDPAddr{IP: ParseIP("ff05::114"), Port: 12345}},
+	{"udp", &UDPAddr{IP: ParseIP("ff08::114"), Port: 12345}},
+	{"udp", &UDPAddr{IP: ParseIP("ff0e::114"), Port: 12345}},
+
+	{"udp6", &UDPAddr{IP: ParseIP("ff01::114"), Port: 12345}},
+	{"udp6", &UDPAddr{IP: ParseIP("ff02::114"), Port: 12345}},
+	{"udp6", &UDPAddr{IP: ParseIP("ff04::114"), Port: 12345}},
+	{"udp6", &UDPAddr{IP: ParseIP("ff05::114"), Port: 12345}},
+	{"udp6", &UDPAddr{IP: ParseIP("ff08::114"), Port: 12345}},
+	{"udp6", &UDPAddr{IP: ParseIP("ff0e::114"), Port: 12345}},
+}
+
+// TestIPv6MulticastListener tests both single and double listen to a
+// test listener with same address family, same group address and same
+// port.
+func TestIPv6MulticastListener(t *testing.T) {
+	switch runtime.GOOS {
+	case "plan9":
+		t.Skipf("not supported on %s", runtime.GOOS)
+	case "solaris":
+		t.Skipf("not supported on solaris, see issue 7399")
+	}
+	if !supportsIPv6 {
+		t.Skip("ipv6 is not supported")
+	}
+	if os.Getuid() != 0 {
+		t.Skip("must be root")
+	}
+
+	closer := func(cs []*UDPConn) {
+		for _, c := range cs {
+			if c != nil {
+				c.Close()
+			}
+		}
+	}
+
+	for _, ifi := range []*Interface{loopbackInterface(), nil} {
+		// Note that multicast interface assignment by system
+		// is not recommended because it usually relies on
+		// routing stuff for finding out an appropriate
+		// nexthop containing both network and link layer
+		// adjacencies.
+		if ifi == nil && (testing.Short() || !*testExternal || !*testIPv6) {
+			continue
+		}
+		for _, tt := range ipv6MulticastListenerTests {
+			var err error
+			cs := make([]*UDPConn, 2)
+			if cs[0], err = ListenMulticastUDP(tt.net, ifi, tt.gaddr); err != nil {
+				t.Fatal(err)
+			}
+			if err := checkMulticastListener(cs[0], tt.gaddr.IP); err != nil {
+				closer(cs)
+				t.Fatal(err)
+			}
+			if cs[1], err = ListenMulticastUDP(tt.net, ifi, tt.gaddr); err != nil {
+				closer(cs)
+				t.Fatal(err)
+			}
+			if err := checkMulticastListener(cs[1], tt.gaddr.IP); err != nil {
+				closer(cs)
+				t.Fatal(err)
+			}
+			closer(cs)
+		}
+	}
+}
+
+func checkMulticastListener(c *UDPConn, ip IP) error {
+	if ok, err := multicastRIBContains(ip); err != nil {
+		return err
+	} else if !ok {
+		return fmt.Errorf("%s not found in multicast rib", ip.String())
+	}
+	la := c.LocalAddr()
+	if la, ok := la.(*UDPAddr); !ok || la.Port == 0 {
+		return fmt.Errorf("got %v; want a proper address with non-zero port number", la)
+	}
+	return nil
+}
+
+func multicastRIBContains(ip IP) (bool, error) {
+	switch runtime.GOOS {
+	case "dragonfly", "netbsd", "openbsd", "plan9", "solaris", "windows":
+		return true, nil // not implemented yet
+	case "linux":
+		if runtime.GOARCH == "arm" || runtime.GOARCH == "alpha" {
+			return true, nil // not implemented yet
+		}
+	}
+	ift, err := Interfaces()
+	if err != nil {
+		return false, err
+	}
+	for _, ifi := range ift {
+		ifmat, err := ifi.MulticastAddrs()
+		if err != nil {
+			return false, err
+		}
+		for _, ifma := range ifmat {
+			if ifma.(*IPAddr).IP.Equal(ip) {
+				return true, nil
+			}
+		}
+	}
+	return false, nil
+}
diff --git a/third_party/gofrontend/libgo/go/net/lookup.go b/third_party/gofrontend/libgo/go/net/lookup.go
index aeffe6c..9008322 100644
--- a/third_party/gofrontend/libgo/go/net/lookup.go
+++ b/third_party/gofrontend/libgo/go/net/lookup.go
@@ -4,7 +4,10 @@
 
 package net
 
-import "time"
+import (
+	"internal/singleflight"
+	"time"
+)
 
 // protocols contains minimal mappings between internet protocol
 // names and numbers for platforms that don't have a complete list of
@@ -22,36 +25,60 @@
 // LookupHost looks up the given host using the local resolver.
 // It returns an array of that host's addresses.
 func LookupHost(host string) (addrs []string, err error) {
+	// Make sure that no matter what we do later, host=="" is rejected.
+	// ParseIP, for example, does accept empty strings.
+	if host == "" {
+		return nil, &DNSError{Err: errNoSuchHost.Error(), Name: host}
+	}
+	if ip := ParseIP(host); ip != nil {
+		return []string{host}, nil
+	}
 	return lookupHost(host)
 }
 
 // LookupIP looks up host using the local resolver.
 // It returns an array of that host's IPv4 and IPv6 addresses.
-func LookupIP(host string) (addrs []IP, err error) {
-	return lookupIPMerge(host)
+func LookupIP(host string) (ips []IP, err error) {
+	// Make sure that no matter what we do later, host=="" is rejected.
+	// ParseIP, for example, does accept empty strings.
+	if host == "" {
+		return nil, &DNSError{Err: errNoSuchHost.Error(), Name: host}
+	}
+	if ip := ParseIP(host); ip != nil {
+		return []IP{ip}, nil
+	}
+	addrs, err := lookupIPMerge(host)
+	if err != nil {
+		return
+	}
+	ips = make([]IP, len(addrs))
+	for i, addr := range addrs {
+		ips[i] = addr.IP
+	}
+	return
 }
 
-var lookupGroup singleflight
+var lookupGroup singleflight.Group
 
 // lookupIPMerge wraps lookupIP, but makes sure that for any given
 // host, only one lookup is in-flight at a time. The returned memory
 // is always owned by the caller.
-func lookupIPMerge(host string) (addrs []IP, err error) {
+func lookupIPMerge(host string) (addrs []IPAddr, err error) {
 	addrsi, err, shared := lookupGroup.Do(host, func() (interface{}, error) {
-		return lookupIP(host)
+		return testHookLookupIP(lookupIP, host)
 	})
 	return lookupIPReturn(addrsi, err, shared)
 }
 
 // lookupIPReturn turns the return values from singleflight.Do into
 // the return values from LookupIP.
-func lookupIPReturn(addrsi interface{}, err error, shared bool) ([]IP, error) {
+func lookupIPReturn(addrsi interface{}, err error, shared bool) ([]IPAddr, error) {
 	if err != nil {
 		return nil, err
 	}
-	addrs := addrsi.([]IP)
+	addrs := addrsi.([]IPAddr)
 	if shared {
-		clone := make([]IP, len(addrs))
+		clone := make([]IPAddr, len(addrs))
 		copy(clone, addrs)
 		addrs = clone
 	}
@@ -59,7 +86,7 @@
 }
 
 // lookupIPDeadline looks up a hostname with a deadline.
-func lookupIPDeadline(host string, deadline time.Time) (addrs []IP, err error) {
+func lookupIPDeadline(host string, deadline time.Time) (addrs []IPAddr, err error) {
 	if deadline.IsZero() {
 		return lookupIPMerge(host)
 	}
@@ -76,7 +103,7 @@
 	defer t.Stop()
 
 	ch := lookupGroup.DoChan(host, func() (interface{}, error) {
-		return lookupIP(host)
+		return testHookLookupIP(lookupIP, host)
 	})
 
 	select {
@@ -90,12 +117,15 @@
 		return nil, errTimeout
 
 	case r := <-ch:
-		return lookupIPReturn(r.v, r.err, r.shared)
+		return lookupIPReturn(r.Val, r.Err, r.Shared)
 	}
 }
 
 // LookupPort looks up the port for the given network and service.
 func LookupPort(network, service string) (port int, err error) {
+	if n, i, ok := dtoi(service, 0); ok && i == len(service) {
+		return n, nil
+	}
 	return lookupPort(network, service)
 }
 
@@ -121,22 +151,22 @@
 }
 
 // LookupMX returns the DNS MX records for the given domain name sorted by preference.
-func LookupMX(name string) (mx []*MX, err error) {
+func LookupMX(name string) (mxs []*MX, err error) {
 	return lookupMX(name)
 }
 
 // LookupNS returns the DNS NS records for the given domain name.
-func LookupNS(name string) (ns []*NS, err error) {
+func LookupNS(name string) (nss []*NS, err error) {
 	return lookupNS(name)
 }
 
 // LookupTXT returns the DNS TXT records for the given domain name.
-func LookupTXT(name string) (txt []string, err error) {
+func LookupTXT(name string) (txts []string, err error) {
 	return lookupTXT(name)
 }
 
 // LookupAddr performs a reverse lookup for the given address, returning a list
 // of names mapping to that address.
-func LookupAddr(addr string) (name []string, err error) {
+func LookupAddr(addr string) (names []string, err error) {
 	return lookupAddr(addr)
 }
diff --git a/third_party/gofrontend/libgo/go/net/lookup_plan9.go b/third_party/gofrontend/libgo/go/net/lookup_plan9.go
index b80ac10..c627464 100644
--- a/third_party/gofrontend/libgo/go/net/lookup_plan9.go
+++ b/third_party/gofrontend/libgo/go/net/lookup_plan9.go
@@ -101,19 +101,18 @@
 	if err != nil {
 		return 0, err
 	}
-	unknownProtoError := errors.New("unknown IP protocol specified: " + name)
 	if len(lines) == 0 {
-		return 0, unknownProtoError
+		return 0, UnknownNetworkError(name)
 	}
 	f := getFields(lines[0])
 	if len(f) < 2 {
-		return 0, unknownProtoError
+		return 0, UnknownNetworkError(name)
 	}
 	s := f[1]
 	if n, _, ok := dtoi(s, byteIndex(s, '=')+1); ok {
 		return n, nil
 	}
-	return 0, unknownProtoError
+	return 0, UnknownNetworkError(name)
 }
 
 func lookupHost(host string) (addrs []string, err error) {
@@ -147,14 +146,16 @@
 	return
 }
 
-func lookupIP(host string) (ips []IP, err error) {
-	addrs, err := LookupHost(host)
+func lookupIP(host string) (addrs []IPAddr, err error) {
+	lits, err := LookupHost(host)
 	if err != nil {
 		return
 	}
-	for _, addr := range addrs {
-		if ip := ParseIP(addr); ip != nil {
-			ips = append(ips, ip)
+	for _, lit := range lits {
+		host, zone := splitHostZone(lit)
+		if ip := ParseIP(host); ip != nil {
+			addr := IPAddr{IP: ip, Zone: zone}
+			addrs = append(addrs, addr)
 		}
 	}
 	return
@@ -171,7 +172,7 @@
 	if err != nil {
 		return
 	}
-	unknownPortError := &AddrError{"unknown port", network + "/" + service}
+	unknownPortError := &AddrError{Err: "unknown port", Addr: network + "/" + service}
 	if len(lines) == 0 {
 		return 0, unknownPortError
 	}
diff --git a/third_party/gofrontend/libgo/go/net/lookup_stub.go b/third_party/gofrontend/libgo/go/net/lookup_stub.go
index 502aafb..5636198 100644
--- a/third_party/gofrontend/libgo/go/net/lookup_stub.go
+++ b/third_party/gofrontend/libgo/go/net/lookup_stub.go
@@ -16,7 +16,7 @@
 	return nil, syscall.ENOPROTOOPT
 }
 
-func lookupIP(host string) (ips []IP, err error) {
+func lookupIP(host string) (addrs []IPAddr, err error) {
 	return nil, syscall.ENOPROTOOPT
 }
 
diff --git a/third_party/gofrontend/libgo/go/net/lookup_test.go b/third_party/gofrontend/libgo/go/net/lookup_test.go
index 057e132..86957b5 100644
--- a/third_party/gofrontend/libgo/go/net/lookup_test.go
+++ b/third_party/gofrontend/libgo/go/net/lookup_test.go
@@ -2,18 +2,34 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-// TODO It would be nice to use a mock DNS server, to eliminate
-// external dependencies.
-
 package net
 
 import (
-	"flag"
+	"bytes"
+	"fmt"
 	"strings"
 	"testing"
+	"time"
 )
 
-var testExternal = flag.Bool("external", true, "allow use of external networks during long test")
+func lookupLocalhost(fn func(string) ([]IPAddr, error), host string) ([]IPAddr, error) {
+	switch host {
+	case "localhost":
+		return []IPAddr{
+			{IP: IPv4(127, 0, 0, 1)},
+			{IP: IPv6loopback},
+		}, nil
+	default:
+		return fn(host)
+	}
+}
+
+// The Lookup APIs use various sources such as local database, DNS or
+// mDNS, and may use platform-dependent DNS stub resolver if possible.
+// The APIs accept any of forms for a query; host name in various
+// encodings, UTF-8 encoded net name, domain name, FQDN or absolute
+// FQDN, but the result would be one of the forms and it depends on
+// the circumstances.
 
 var lookupGoogleSRVTests = []struct {
 	service, proto, name string
@@ -21,17 +37,30 @@
 }{
 	{
 		"xmpp-server", "tcp", "google.com",
-		".google.com", ".google.com",
+		"google.com", "google.com",
 	},
 	{
-		"", "", "_xmpp-server._tcp.google.com", // non-standard back door
-		".google.com", ".google.com",
+		"xmpp-server", "tcp", "google.com.",
+		"google.com", "google.com",
+	},
+
+	// non-standard back door
+	{
+		"", "", "_xmpp-server._tcp.google.com",
+		"google.com", "google.com",
+	},
+	{
+		"", "", "_xmpp-server._tcp.google.com.",
+		"google.com", "google.com",
 	},
 }
 
 func TestLookupGoogleSRV(t *testing.T) {
 	if testing.Short() || !*testExternal {
-		t.Skip("skipping test to avoid external network")
+		t.Skip("avoid external network")
+	}
+	if !supportsIPv4 || !*testIPv4 {
+		t.Skip("IPv4 is required")
 	}
 
 	for _, tt := range lookupGoogleSRVTests {
@@ -42,90 +71,128 @@
 		if len(srvs) == 0 {
 			t.Error("got no record")
 		}
-		if !strings.Contains(cname, tt.cname) {
-			t.Errorf("got %q; want %q", cname, tt.cname)
+		if !strings.HasSuffix(cname, tt.cname) && !strings.HasSuffix(cname, tt.cname+".") {
+			t.Errorf("got %s; want %s", cname, tt.cname)
 		}
 		for _, srv := range srvs {
-			if !strings.Contains(srv.Target, tt.target) {
-				t.Errorf("got %v; want a record containing %q", srv, tt.target)
+			if !strings.HasSuffix(srv.Target, tt.target) && !strings.HasSuffix(srv.Target, tt.target+".") {
+				t.Errorf("got %v; want a record containing %s", srv, tt.target)
 			}
 		}
 	}
 }
 
+var lookupGmailMXTests = []struct {
+	name, host string
+}{
+	{"gmail.com", "google.com"},
+	{"gmail.com.", "google.com"},
+}
+
 func TestLookupGmailMX(t *testing.T) {
 	if testing.Short() || !*testExternal {
-		t.Skip("skipping test to avoid external network")
+		t.Skip("avoid external network")
+	}
+	if !supportsIPv4 || !*testIPv4 {
+		t.Skip("IPv4 is required")
 	}
 
-	mxs, err := LookupMX("gmail.com")
-	if err != nil {
-		t.Fatal(err)
-	}
-	if len(mxs) == 0 {
-		t.Error("got no record")
-	}
-	for _, mx := range mxs {
-		if !strings.Contains(mx.Host, ".google.com") {
-			t.Errorf("got %v; want a record containing .google.com.", mx)
+	for _, tt := range lookupGmailMXTests {
+		mxs, err := LookupMX(tt.name)
+		if err != nil {
+			t.Fatal(err)
+		}
+		if len(mxs) == 0 {
+			t.Error("got no record")
+		}
+		for _, mx := range mxs {
+			if !strings.HasSuffix(mx.Host, tt.host) && !strings.HasSuffix(mx.Host, tt.host+".") {
+				t.Errorf("got %v; want a record containing %s", mx, tt.host)
+			}
 		}
 	}
 }
 
+var lookupGmailNSTests = []struct {
+	name, host string
+}{
+	{"gmail.com", "google.com"},
+	{"gmail.com.", "google.com"},
+}
+
 func TestLookupGmailNS(t *testing.T) {
 	if testing.Short() || !*testExternal {
-		t.Skip("skipping test to avoid external network")
+		t.Skip("avoid external network")
+	}
+	if !supportsIPv4 || !*testIPv4 {
+		t.Skip("IPv4 is required")
 	}
 
-	nss, err := LookupNS("gmail.com")
-	if err != nil {
-		t.Fatal(err)
-	}
-	if len(nss) == 0 {
-		t.Error("got no record")
-	}
-	for _, ns := range nss {
-		if !strings.Contains(ns.Host, ".google.com") {
-			t.Errorf("got %v; want a record containing .google.com.", ns)
+	for _, tt := range lookupGmailNSTests {
+		nss, err := LookupNS(tt.name)
+		if err != nil {
+			t.Fatal(err)
+		}
+		if len(nss) == 0 {
+			t.Error("got no record")
+		}
+		for _, ns := range nss {
+			if !strings.HasSuffix(ns.Host, tt.host) && !strings.HasSuffix(ns.Host, tt.host+".") {
+				t.Errorf("got %v; want a record containing %s", ns, tt.host)
+			}
 		}
 	}
 }
 
+var lookupGmailTXTTests = []struct {
+	name, txt, host string
+}{
+	{"gmail.com", "spf", "google.com"},
+	{"gmail.com.", "spf", "google.com"},
+}
+
 func TestLookupGmailTXT(t *testing.T) {
 	if testing.Short() || !*testExternal {
-		t.Skip("skipping test to avoid external network")
+		t.Skip("avoid external network")
+	}
+	if !supportsIPv4 || !*testIPv4 {
+		t.Skip("IPv4 is required")
 	}
 
-	txts, err := LookupTXT("gmail.com")
-	if err != nil {
-		t.Fatal(err)
-	}
-	if len(txts) == 0 {
-		t.Error("got no record")
-	}
-	for _, txt := range txts {
-		if !strings.Contains(txt, "spf") {
-			t.Errorf("got %q; want a spf record", txt)
+	for _, tt := range lookupGmailTXTTests {
+		txts, err := LookupTXT(tt.name)
+		if err != nil {
+			t.Fatal(err)
+		}
+		if len(txts) == 0 {
+			t.Error("got no record")
+		}
+		for _, txt := range txts {
+			if !strings.Contains(txt, tt.txt) || (!strings.HasSuffix(txt, tt.host) && !strings.HasSuffix(txt, tt.host+".")) {
+				t.Errorf("got %s; want a record containing %s, %s", txt, tt.txt, tt.host)
+			}
 		}
 	}
 }
 
-var lookupGooglePublicDNSAddrs = []struct {
-	addr string
-	name string
+var lookupGooglePublicDNSAddrTests = []struct {
+	addr, name string
 }{
-	{"8.8.8.8", ".google.com."},
-	{"8.8.4.4", ".google.com."},
-	{"2001:4860:4860::8888", ".google.com."},
-	{"2001:4860:4860::8844", ".google.com."},
+	{"8.8.8.8", ".google.com"},
+	{"8.8.4.4", ".google.com"},
+	{"2001:4860:4860::8888", ".google.com"},
+	{"2001:4860:4860::8844", ".google.com"},
 }
 
 func TestLookupGooglePublicDNSAddr(t *testing.T) {
 	if testing.Short() || !*testExternal {
-		t.Skip("skipping test to avoid external network")
+		t.Skip("avoid external network")
+	}
+	if !supportsIPv4 || !supportsIPv6 || !*testIPv4 || !*testIPv6 {
+		t.Skip("both IPv4 and IPv6 are required")
 	}
 
-	for _, tt := range lookupGooglePublicDNSAddrs {
+	for _, tt := range lookupGooglePublicDNSAddrTests {
 		names, err := LookupAddr(tt.addr)
 		if err != nil {
 			t.Fatal(err)
@@ -134,61 +201,97 @@
 			t.Error("got no record")
 		}
 		for _, name := range names {
-			if !strings.HasSuffix(name, tt.name) {
-				t.Errorf("got %q; want a record containing %q", name, tt.name)
+			if !strings.HasSuffix(name, tt.name) && !strings.HasSuffix(name, tt.name+".") {
+				t.Errorf("got %s; want a record containing %s", name, tt.name)
 			}
 		}
 	}
 }
 
-func TestLookupIANACNAME(t *testing.T) {
-	if testing.Short() || !*testExternal {
-		t.Skip("skipping test to avoid external network")
-	}
-
-	cname, err := LookupCNAME("www.iana.org")
-	if err != nil {
-		t.Fatal(err)
-	}
-	if !strings.HasSuffix(cname, ".icann.org.") {
-		t.Errorf("got %q; want a record containing .icann.org.", cname)
-	}
+var lookupIANACNAMETests = []struct {
+	name, cname string
+}{
+	{"www.iana.org", "icann.org"},
+	{"www.iana.org.", "icann.org"},
 }
 
-func TestLookupGoogleHost(t *testing.T) {
+func TestLookupIANACNAME(t *testing.T) {
 	if testing.Short() || !*testExternal {
-		t.Skip("skipping test to avoid external network")
+		t.Skip("avoid external network")
+	}
+	if !supportsIPv4 || !*testIPv4 {
+		t.Skip("IPv4 is required")
 	}
 
-	addrs, err := LookupHost("google.com")
-	if err != nil {
-		t.Fatal(err)
-	}
-	if len(addrs) == 0 {
-		t.Error("got no record")
-	}
-	for _, addr := range addrs {
-		if ParseIP(addr) == nil {
-			t.Errorf("got %q; want a literal ip address", addr)
+	for _, tt := range lookupIANACNAMETests {
+		cname, err := LookupCNAME(tt.name)
+		if err != nil {
+			t.Fatal(err)
+		}
+		if !strings.HasSuffix(cname, tt.cname) && !strings.HasSuffix(cname, tt.cname+".") {
+			t.Errorf("got %s; want a record containing %s", cname, tt.cname)
 		}
 	}
 }
 
-func TestLookupGoogleIP(t *testing.T) {
+var lookupGoogleHostTests = []struct {
+	name string
+}{
+	{"google.com"},
+	{"google.com."},
+}
+
+func TestLookupGoogleHost(t *testing.T) {
 	if testing.Short() || !*testExternal {
-		t.Skip("skipping test to avoid external network")
+		t.Skip("avoid external network")
+	}
+	if !supportsIPv4 || !*testIPv4 {
+		t.Skip("IPv4 is required")
 	}
 
-	ips, err := LookupIP("google.com")
-	if err != nil {
-		t.Fatal(err)
+	for _, tt := range lookupGoogleHostTests {
+		addrs, err := LookupHost(tt.name)
+		if err != nil {
+			t.Fatal(err)
+		}
+		if len(addrs) == 0 {
+			t.Error("got no record")
+		}
+		for _, addr := range addrs {
+			if ParseIP(addr) == nil {
+				t.Errorf("got %q; want a literal IP address", addr)
+			}
+		}
 	}
-	if len(ips) == 0 {
-		t.Error("got no record")
+}
+
+var lookupGoogleIPTests = []struct {
+	name string
+}{
+	{"google.com"},
+	{"google.com."},
+}
+
+func TestLookupGoogleIP(t *testing.T) {
+	if testing.Short() || !*testExternal {
+		t.Skip("avoid external network")
 	}
-	for _, ip := range ips {
-		if ip.To4() == nil && ip.To16() == nil {
-			t.Errorf("got %v; want an ip address", ip)
+	if !supportsIPv4 || !*testIPv4 {
+		t.Skip("IPv4 is required")
+	}
+
+	for _, tt := range lookupGoogleIPTests {
+		ips, err := LookupIP(tt.name)
+		if err != nil {
+			t.Fatal(err)
+		}
+		if len(ips) == 0 {
+			t.Error("got no record")
+		}
+		for _, ip := range ips {
+			if ip.To4() == nil && ip.To16() == nil {
+				t.Errorf("got %v; want an IP address", ip)
+			}
 		}
 	}
 }
@@ -229,3 +332,172 @@
 		}
 	}
 }
+
+func TestLookupIPDeadline(t *testing.T) {
+	if !*testDNSFlood {
+		t.Skip("test disabled; use -dnsflood to enable")
+	}
+
+	const N = 5000
+	const timeout = 3 * time.Second
+	c := make(chan error, 2*N)
+	for i := 0; i < N; i++ {
+		name := fmt.Sprintf("%d.net-test.golang.org", i)
+		go func() {
+			_, err := lookupIPDeadline(name, time.Now().Add(timeout/2))
+			c <- err
+		}()
+		go func() {
+			_, err := lookupIPDeadline(name, time.Now().Add(timeout))
+			c <- err
+		}()
+	}
+	qstats := struct {
+		succeeded, failed         int
+		timeout, temporary, other int
+		unknown                   int
+	}{}
+	deadline := time.After(timeout + time.Second)
+	for i := 0; i < 2*N; i++ {
+		select {
+		case <-deadline:
+			t.Fatal("deadline exceeded")
+		case err := <-c:
+			switch err := err.(type) {
+			case nil:
+				qstats.succeeded++
+			case Error:
+				qstats.failed++
+				if err.Timeout() {
+					qstats.timeout++
+				}
+				if err.Temporary() {
+					qstats.temporary++
+				}
+				if !err.Timeout() && !err.Temporary() {
+					qstats.other++
+				}
+			default:
+				qstats.failed++
+				qstats.unknown++
+			}
+		}
+	}
+
+	// A high volume of DNS queries for sub-domain of golang.org
+	// would be coordinated by authoritative or recursive server,
+	// or stub resolver which implements query-response rate
+	// limitation, so we can expect some query successes and more
+	// failures including timeout, temporary and other here.
+	// As a rule, unknown must not be shown but it might possibly
+	// 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/third_party/gofrontend/libgo/go/net/lookup_unix.go b/third_party/gofrontend/libgo/go/net/lookup_unix.go
index a545784..a64da8b 100644
--- a/third_party/gofrontend/libgo/go/net/lookup_unix.go
+++ b/third_party/gofrontend/libgo/go/net/lookup_unix.go
@@ -6,10 +6,7 @@
 
 package net
 
-import (
-	"errors"
-	"sync"
-)
+import "sync"
 
 var onceReadProtocols sync.Once
 
@@ -43,126 +40,120 @@
 
 // lookupProtocol looks up IP protocol name in /etc/protocols and
 // returns correspondent protocol number.
-func lookupProtocol(name string) (proto int, err error) {
+func lookupProtocol(name string) (int, error) {
 	onceReadProtocols.Do(readProtocols)
 	proto, found := protocols[name]
 	if !found {
-		return 0, errors.New("unknown IP protocol specified: " + name)
+		return 0, &AddrError{Err: "unknown IP protocol specified", Addr: name}
 	}
-	return
+	return proto, nil
 }
 
 func lookupHost(host string) (addrs []string, err error) {
-	addrs, err, ok := cgoLookupHost(host)
-	if !ok {
-		addrs, err = goLookupHost(host)
+	order := systemConf().hostLookupOrder(host)
+	if order == hostLookupCgo {
+		if addrs, err, ok := cgoLookupHost(host); ok {
+			return addrs, err
+		}
+		// cgo not available (or netgo); fall back to Go's DNS resolver
+		order = hostLookupFilesDNS
 	}
-	return
+	return goLookupHostOrder(host, order)
 }
 
-func lookupIP(host string) (addrs []IP, err error) {
-	addrs, err, ok := cgoLookupIP(host)
-	if !ok {
-		addrs, err = goLookupIP(host)
+func lookupIP(host string) (addrs []IPAddr, err error) {
+	order := systemConf().hostLookupOrder(host)
+	if order == hostLookupCgo {
+		if addrs, err, ok := cgoLookupIP(host); ok {
+			return addrs, err
+		}
+		// cgo not available (or netgo); fall back to Go's DNS resolver
+		order = hostLookupFilesDNS
 	}
-	return
+	return goLookupIPOrder(host, order)
 }
 
-func lookupPort(network, service string) (port int, err error) {
-	port, err, ok := cgoLookupPort(network, service)
-	if !ok {
-		port, err = goLookupPort(network, service)
+func lookupPort(network, service string) (int, error) {
+	if systemConf().canUseCgo() {
+		if port, err, ok := cgoLookupPort(network, service); ok {
+			return port, err
+		}
 	}
-	return
+	return goLookupPort(network, service)
 }
 
-func lookupCNAME(name string) (cname string, err error) {
-	cname, err, ok := cgoLookupCNAME(name)
-	if !ok {
-		cname, err = goLookupCNAME(name)
+func lookupCNAME(name string) (string, error) {
+	if systemConf().canUseCgo() {
+		if cname, err, ok := cgoLookupCNAME(name); ok {
+			return cname, err
+		}
 	}
-	return
+	return goLookupCNAME(name)
 }
 
-func lookupSRV(service, proto, name string) (cname string, addrs []*SRV, err error) {
+func lookupSRV(service, proto, name string) (string, []*SRV, error) {
 	var target string
 	if service == "" && proto == "" {
 		target = name
 	} else {
 		target = "_" + service + "._" + proto + "." + name
 	}
-	var records []dnsRR
-	cname, records, err = lookup(target, dnsTypeSRV)
+	cname, rrs, err := lookup(target, dnsTypeSRV)
 	if err != nil {
-		return
+		return "", nil, err
 	}
-	addrs = make([]*SRV, len(records))
-	for i, rr := range records {
-		r := rr.(*dnsRR_SRV)
-		addrs[i] = &SRV{r.Target, r.Port, r.Priority, r.Weight}
+	srvs := make([]*SRV, len(rrs))
+	for i, rr := range rrs {
+		rr := rr.(*dnsRR_SRV)
+		srvs[i] = &SRV{Target: rr.Target, Port: rr.Port, Priority: rr.Priority, Weight: rr.Weight}
 	}
-	byPriorityWeight(addrs).sort()
-	return
+	byPriorityWeight(srvs).sort()
+	return cname, srvs, nil
 }
 
-func lookupMX(name string) (mx []*MX, err error) {
-	_, records, err := lookup(name, dnsTypeMX)
+func lookupMX(name string) ([]*MX, error) {
+	_, rrs, err := lookup(name, dnsTypeMX)
 	if err != nil {
-		return
+		return nil, err
 	}
-	mx = make([]*MX, len(records))
-	for i, rr := range records {
-		r := rr.(*dnsRR_MX)
-		mx[i] = &MX{r.Mx, r.Pref}
+	mxs := make([]*MX, len(rrs))
+	for i, rr := range rrs {
+		rr := rr.(*dnsRR_MX)
+		mxs[i] = &MX{Host: rr.Mx, Pref: rr.Pref}
 	}
-	byPref(mx).sort()
-	return
+	byPref(mxs).sort()
+	return mxs, nil
 }
 
-func lookupNS(name string) (ns []*NS, err error) {
-	_, records, err := lookup(name, dnsTypeNS)
+func lookupNS(name string) ([]*NS, error) {
+	_, rrs, err := lookup(name, dnsTypeNS)
 	if err != nil {
-		return
+		return nil, err
 	}
-	ns = make([]*NS, len(records))
-	for i, r := range records {
-		r := r.(*dnsRR_NS)
-		ns[i] = &NS{r.Ns}
+	nss := make([]*NS, len(rrs))
+	for i, rr := range rrs {
+		nss[i] = &NS{Host: rr.(*dnsRR_NS).Ns}
 	}
-	return
+	return nss, nil
 }
 
-func lookupTXT(name string) (txt []string, err error) {
-	_, records, err := lookup(name, dnsTypeTXT)
+func lookupTXT(name string) ([]string, error) {
+	_, rrs, err := lookup(name, dnsTypeTXT)
 	if err != nil {
-		return
+		return nil, err
 	}
-	txt = make([]string, len(records))
-	for i, r := range records {
-		txt[i] = r.(*dnsRR_TXT).Txt
+	txts := make([]string, len(rrs))
+	for i, rr := range rrs {
+		txts[i] = rr.(*dnsRR_TXT).Txt
 	}
-	return
+	return txts, nil
 }
 
-func lookupAddr(addr string) (name []string, err error) {
-	name = lookupStaticAddr(addr)
-	if len(name) > 0 {
-		return
+func lookupAddr(addr string) ([]string, error) {
+	if systemConf().canUseCgo() {
+		if ptrs, err, ok := cgoLookupPTR(addr); ok {
+			return ptrs, err
+		}
 	}
-	var arpa string
-	arpa, err = reverseaddr(addr)
-	if err != nil {
-		return
-	}
-	var records []dnsRR
-	_, records, err = lookup(arpa, dnsTypePTR)
-	if err != nil {
-		return
-	}
-	name = make([]string, len(records))
-	for i := range records {
-		r := records[i].(*dnsRR_PTR)
-		name[i] = r.Ptr
-	}
-	return
+	return goLookupPTR(addr)
 }
diff --git a/third_party/gofrontend/libgo/go/net/lookup_windows.go b/third_party/gofrontend/libgo/go/net/lookup_windows.go
index 6a925b0..1b6d392 100644
--- a/third_party/gofrontend/libgo/go/net/lookup_windows.go
+++ b/third_party/gofrontend/libgo/go/net/lookup_windows.go
@@ -19,13 +19,13 @@
 func getprotobyname(name string) (proto int, err error) {
 	p, err := syscall.GetProtoByName(name)
 	if err != nil {
-		return 0, os.NewSyscallError("GetProtoByName", err)
+		return 0, os.NewSyscallError("getorotobyname", err)
 	}
 	return int(p.Proto), nil
 }
 
 // lookupProtocol looks up IP protocol name and returns correspondent protocol number.
-func lookupProtocol(name string) (proto int, err error) {
+func lookupProtocol(name string) (int, error) {
 	// GetProtoByName return value is stored in thread local storage.
 	// Start new os thread before the call to prevent races.
 	type result struct {
@@ -46,47 +46,48 @@
 		if proto, ok := protocols[name]; ok {
 			return proto, nil
 		}
+		r.err = &DNSError{Err: r.err.Error(), Name: name}
 	}
 	return r.proto, r.err
 }
 
-func lookupHost(name string) (addrs []string, err error) {
+func lookupHost(name string) ([]string, error) {
 	ips, err := LookupIP(name)
 	if err != nil {
-		return
+		return nil, err
 	}
-	addrs = make([]string, 0, len(ips))
+	addrs := make([]string, 0, len(ips))
 	for _, ip := range ips {
 		addrs = append(addrs, ip.String())
 	}
-	return
-}
-
-func gethostbyname(name string) (addrs []IP, err error) {
-	// caller already acquired thread
-	h, err := syscall.GetHostByName(name)
-	if err != nil {
-		return nil, os.NewSyscallError("GetHostByName", err)
-	}
-	switch h.AddrType {
-	case syscall.AF_INET:
-		i := 0
-		addrs = make([]IP, 100) // plenty of room to grow
-		for p := (*[100](*[4]byte))(unsafe.Pointer(h.AddrList)); i < cap(addrs) && p[i] != nil; i++ {
-			addrs[i] = IPv4(p[i][0], p[i][1], p[i][2], p[i][3])
-		}
-		addrs = addrs[0:i]
-	default: // TODO(vcc): Implement non IPv4 address lookups.
-		return nil, os.NewSyscallError("LookupIP", syscall.EWINDOWS)
-	}
 	return addrs, nil
 }
 
-func oldLookupIP(name string) (addrs []IP, err error) {
+func gethostbyname(name string) (addrs []IPAddr, err error) {
+	// caller already acquired thread
+	h, err := syscall.GetHostByName(name)
+	if err != nil {
+		return nil, os.NewSyscallError("gethostbyname", err)
+	}
+	switch h.AddrType {
+	case syscall.AF_INET:
+		i := 0
+		addrs = make([]IPAddr, 100) // plenty of room to grow
+		for p := (*[100](*[4]byte))(unsafe.Pointer(h.AddrList)); i < cap(addrs) && p[i] != nil; i++ {
+			addrs[i] = IPAddr{IP: IPv4(p[i][0], p[i][1], p[i][2], p[i][3])}
+		}
+		addrs = addrs[0:i]
+	default: // TODO(vcc): Implement non IPv4 address lookups.
+		return nil, syscall.EWINDOWS
+	}
+	return addrs, nil
+}
+
+func oldLookupIP(name string) ([]IPAddr, error) {
 	// GetHostByName return value is stored in thread local storage.
 	// Start new os thread before the call to prevent races.
 	type result struct {
-		addrs []IP
+		addrs []IPAddr
 		err   error
 	}
 	ch := make(chan result)
@@ -99,10 +100,13 @@
 		ch <- result{addrs: addrs, err: err}
 	}()
 	r := <-ch
+	if r.err != nil {
+		r.err = &DNSError{Err: r.err.Error(), Name: name}
+	}
 	return r.addrs, r.err
 }
 
-func newLookupIP(name string) (addrs []IP, err error) {
+func newLookupIP(name string) ([]IPAddr, error) {
 	acquireThread()
 	defer releaseThread()
 	hints := syscall.AddrinfoW{
@@ -113,27 +117,28 @@
 	var result *syscall.AddrinfoW
 	e := syscall.GetAddrInfoW(syscall.StringToUTF16Ptr(name), nil, &hints, &result)
 	if e != nil {
-		return nil, os.NewSyscallError("GetAddrInfoW", e)
+		return nil, &DNSError{Err: os.NewSyscallError("getaddrinfow", e).Error(), Name: name}
 	}
 	defer syscall.FreeAddrInfoW(result)
-	addrs = make([]IP, 0, 5)
+	addrs := make([]IPAddr, 0, 5)
 	for ; result != nil; result = result.Next {
 		addr := unsafe.Pointer(result.Addr)
 		switch result.Family {
 		case syscall.AF_INET:
 			a := (*syscall.RawSockaddrInet4)(addr).Addr
-			addrs = append(addrs, IPv4(a[0], a[1], a[2], a[3]))
+			addrs = append(addrs, IPAddr{IP: IPv4(a[0], a[1], a[2], a[3])})
 		case syscall.AF_INET6:
 			a := (*syscall.RawSockaddrInet6)(addr).Addr
-			addrs = append(addrs, IP{a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9], a[10], a[11], a[12], a[13], a[14], a[15]})
+			zone := zoneToString(int((*syscall.RawSockaddrInet6)(addr).Scope_id))
+			addrs = append(addrs, IPAddr{IP: IP{a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9], a[10], a[11], a[12], a[13], a[14], a[15]}, Zone: zone})
 		default:
-			return nil, os.NewSyscallError("LookupIP", syscall.EWINDOWS)
+			return nil, &DNSError{Err: syscall.EWINDOWS.Error(), Name: name}
 		}
 	}
 	return addrs, nil
 }
 
-func getservbyname(network, service string) (port int, err error) {
+func getservbyname(network, service string) (int, error) {
 	acquireThread()
 	defer releaseThread()
 	switch network {
@@ -144,12 +149,12 @@
 	}
 	s, err := syscall.GetServByName(service, network)
 	if err != nil {
-		return 0, os.NewSyscallError("GetServByName", err)
+		return 0, os.NewSyscallError("getservbyname", err)
 	}
 	return int(syscall.Ntohs(s.Port)), nil
 }
 
-func oldLookupPort(network, service string) (port int, err error) {
+func oldLookupPort(network, service string) (int, error) {
 	// GetServByName return value is stored in thread local storage.
 	// Start new os thread before the call to prevent races.
 	type result struct {
@@ -166,10 +171,13 @@
 		ch <- result{port: port, err: err}
 	}()
 	r := <-ch
+	if r.err != nil {
+		r.err = &DNSError{Err: r.err.Error(), Name: network + "/" + service}
+	}
 	return r.port, r.err
 }
 
-func newLookupPort(network, service string) (port int, err error) {
+func newLookupPort(network, service string) (int, error) {
 	acquireThread()
 	defer releaseThread()
 	var stype int32
@@ -187,11 +195,11 @@
 	var result *syscall.AddrinfoW
 	e := syscall.GetAddrInfoW(nil, syscall.StringToUTF16Ptr(service), &hints, &result)
 	if e != nil {
-		return 0, os.NewSyscallError("GetAddrInfoW", e)
+		return 0, &DNSError{Err: os.NewSyscallError("getaddrinfow", e).Error(), Name: network + "/" + service}
 	}
 	defer syscall.FreeAddrInfoW(result)
 	if result == nil {
-		return 0, os.NewSyscallError("LookupPort", syscall.EINVAL)
+		return 0, &DNSError{Err: syscall.EINVAL.Error(), Name: network + "/" + service}
 	}
 	addr := unsafe.Pointer(result.Addr)
 	switch result.Family {
@@ -202,10 +210,10 @@
 		a := (*syscall.RawSockaddrInet6)(addr)
 		return int(syscall.Ntohs(a.Port)), nil
 	}
-	return 0, os.NewSyscallError("LookupPort", syscall.EINVAL)
+	return 0, &DNSError{Err: syscall.EINVAL.Error(), Name: network + "/" + service}
 }
 
-func lookupCNAME(name string) (cname string, err error) {
+func lookupCNAME(name string) (string, error) {
 	acquireThread()
 	defer releaseThread()
 	var r *syscall.DNSRecord
@@ -219,16 +227,16 @@
 		return name, nil
 	}
 	if e != nil {
-		return "", os.NewSyscallError("LookupCNAME", e)
+		return "", &DNSError{Err: os.NewSyscallError("dnsquery", e).Error(), Name: name}
 	}
 	defer syscall.DnsRecordListFree(r, 1)
 
 	resolved := resolveCNAME(syscall.StringToUTF16Ptr(name), r)
-	cname = syscall.UTF16ToString((*[256]uint16)(unsafe.Pointer(resolved))[:]) + "."
-	return
+	cname := syscall.UTF16ToString((*[256]uint16)(unsafe.Pointer(resolved))[:]) + "."
+	return cname, nil
 }
 
-func lookupSRV(service, proto, name string) (cname string, addrs []*SRV, err error) {
+func lookupSRV(service, proto, name string) (string, []*SRV, error) {
 	acquireThread()
 	defer releaseThread()
 	var target string
@@ -240,78 +248,78 @@
 	var r *syscall.DNSRecord
 	e := syscall.DnsQuery(target, syscall.DNS_TYPE_SRV, 0, nil, &r, nil)
 	if e != nil {
-		return "", nil, os.NewSyscallError("LookupSRV", e)
+		return "", nil, &DNSError{Err: os.NewSyscallError("dnsquery", e).Error(), Name: target}
 	}
 	defer syscall.DnsRecordListFree(r, 1)
 
-	addrs = make([]*SRV, 0, 10)
+	srvs := make([]*SRV, 0, 10)
 	for _, p := range validRecs(r, syscall.DNS_TYPE_SRV, target) {
 		v := (*syscall.DNSSRVData)(unsafe.Pointer(&p.Data[0]))
-		addrs = append(addrs, &SRV{syscall.UTF16ToString((*[256]uint16)(unsafe.Pointer(v.Target))[:]), v.Port, v.Priority, v.Weight})
+		srvs = append(srvs, &SRV{syscall.UTF16ToString((*[256]uint16)(unsafe.Pointer(v.Target))[:]), v.Port, v.Priority, v.Weight})
 	}
-	byPriorityWeight(addrs).sort()
-	return name, addrs, nil
+	byPriorityWeight(srvs).sort()
+	return name, srvs, nil
 }
 
-func lookupMX(name string) (mx []*MX, err error) {
+func lookupMX(name string) ([]*MX, error) {
 	acquireThread()
 	defer releaseThread()
 	var r *syscall.DNSRecord
 	e := syscall.DnsQuery(name, syscall.DNS_TYPE_MX, 0, nil, &r, nil)
 	if e != nil {
-		return nil, os.NewSyscallError("LookupMX", e)
+		return nil, &DNSError{Err: os.NewSyscallError("dnsquery", e).Error(), Name: name}
 	}
 	defer syscall.DnsRecordListFree(r, 1)
 
-	mx = make([]*MX, 0, 10)
+	mxs := make([]*MX, 0, 10)
 	for _, p := range validRecs(r, syscall.DNS_TYPE_MX, name) {
 		v := (*syscall.DNSMXData)(unsafe.Pointer(&p.Data[0]))
-		mx = append(mx, &MX{syscall.UTF16ToString((*[256]uint16)(unsafe.Pointer(v.NameExchange))[:]) + ".", v.Preference})
+		mxs = append(mxs, &MX{syscall.UTF16ToString((*[256]uint16)(unsafe.Pointer(v.NameExchange))[:]) + ".", v.Preference})
 	}
-	byPref(mx).sort()
-	return mx, nil
+	byPref(mxs).sort()
+	return mxs, nil
 }
 
-func lookupNS(name string) (ns []*NS, err error) {
+func lookupNS(name string) ([]*NS, error) {
 	acquireThread()
 	defer releaseThread()
 	var r *syscall.DNSRecord
 	e := syscall.DnsQuery(name, syscall.DNS_TYPE_NS, 0, nil, &r, nil)
 	if e != nil {
-		return nil, os.NewSyscallError("LookupNS", e)
+		return nil, &DNSError{Err: os.NewSyscallError("dnsquery", e).Error(), Name: name}
 	}
 	defer syscall.DnsRecordListFree(r, 1)
 
-	ns = make([]*NS, 0, 10)
+	nss := make([]*NS, 0, 10)
 	for _, p := range validRecs(r, syscall.DNS_TYPE_NS, name) {
 		v := (*syscall.DNSPTRData)(unsafe.Pointer(&p.Data[0]))
-		ns = append(ns, &NS{syscall.UTF16ToString((*[256]uint16)(unsafe.Pointer(v.Host))[:]) + "."})
+		nss = append(nss, &NS{syscall.UTF16ToString((*[256]uint16)(unsafe.Pointer(v.Host))[:]) + "."})
 	}
-	return ns, nil
+	return nss, nil
 }
 
-func lookupTXT(name string) (txt []string, err error) {
+func lookupTXT(name string) ([]string, error) {
 	acquireThread()
 	defer releaseThread()
 	var r *syscall.DNSRecord
 	e := syscall.DnsQuery(name, syscall.DNS_TYPE_TEXT, 0, nil, &r, nil)
 	if e != nil {
-		return nil, os.NewSyscallError("LookupTXT", e)
+		return nil, &DNSError{Err: os.NewSyscallError("dnsquery", e).Error(), Name: name}
 	}
 	defer syscall.DnsRecordListFree(r, 1)
 
-	txt = make([]string, 0, 10)
+	txts := make([]string, 0, 10)
 	for _, p := range validRecs(r, syscall.DNS_TYPE_TEXT, name) {
 		d := (*syscall.DNSTXTData)(unsafe.Pointer(&p.Data[0]))
 		for _, v := range (*[1 << 10]*uint16)(unsafe.Pointer(&(d.StringArray[0])))[:d.StringCount] {
 			s := syscall.UTF16ToString((*[1 << 20]uint16)(unsafe.Pointer(v))[:])
-			txt = append(txt, s)
+			txts = append(txts, s)
 		}
 	}
-	return
+	return txts, nil
 }
 
-func lookupAddr(addr string) (name []string, err error) {
+func lookupAddr(addr string) ([]string, error) {
 	acquireThread()
 	defer releaseThread()
 	arpa, err := reverseaddr(addr)
@@ -321,16 +329,16 @@
 	var r *syscall.DNSRecord
 	e := syscall.DnsQuery(arpa, syscall.DNS_TYPE_PTR, 0, nil, &r, nil)
 	if e != nil {
-		return nil, os.NewSyscallError("LookupAddr", e)
+		return nil, &DNSError{Err: os.NewSyscallError("dnsquery", e).Error(), Name: addr}
 	}
 	defer syscall.DnsRecordListFree(r, 1)
 
-	name = make([]string, 0, 10)
+	ptrs := make([]string, 0, 10)
 	for _, p := range validRecs(r, syscall.DNS_TYPE_PTR, arpa) {
 		v := (*syscall.DNSPTRData)(unsafe.Pointer(&p.Data[0]))
-		name = append(name, syscall.UTF16ToString((*[256]uint16)(unsafe.Pointer(v.Host))[:]))
+		ptrs = append(ptrs, syscall.UTF16ToString((*[256]uint16)(unsafe.Pointer(v.Host))[:]))
 	}
-	return name, nil
+	return ptrs, nil
 }
 
 const dnsSectionMask = 0x0003
diff --git a/third_party/gofrontend/libgo/go/net/mac.go b/third_party/gofrontend/libgo/go/net/mac.go
index d616b1f..8594a91 100644
--- a/third_party/gofrontend/libgo/go/net/mac.go
+++ b/third_party/gofrontend/libgo/go/net/mac.go
@@ -2,12 +2,8 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-// MAC address manipulations
-
 package net
 
-import "errors"
-
 const hexDigit = "0123456789abcdef"
 
 // A HardwareAddr represents a physical hardware address.
@@ -82,5 +78,5 @@
 	return hw, nil
 
 error:
-	return nil, errors.New("invalid MAC address: " + s)
+	return nil, &AddrError{Err: "invalid MAC address", Addr: s}
 }
diff --git a/third_party/gofrontend/libgo/go/net/mac_test.go b/third_party/gofrontend/libgo/go/net/mac_test.go
index 8f9dc66..0af0c01 100644
--- a/third_party/gofrontend/libgo/go/net/mac_test.go
+++ b/third_party/gofrontend/libgo/go/net/mac_test.go
@@ -10,7 +10,7 @@
 	"testing"
 )
 
-var mactests = []struct {
+var parseMACTests = []struct {
 	in  string
 	out HardwareAddr
 	err string
@@ -36,19 +36,18 @@
 	{"0123.4567.89AB.CDEF", HardwareAddr{1, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef}, ""},
 }
 
-func match(err error, s string) bool {
-	if s == "" {
-		return err == nil
+func TestParseMAC(t *testing.T) {
+	match := func(err error, s string) bool {
+		if s == "" {
+			return err == nil
+		}
+		return err != nil && strings.Contains(err.Error(), s)
 	}
-	return err != nil && strings.Contains(err.Error(), s)
-}
 
-func TestMACParseString(t *testing.T) {
-	for i, tt := range mactests {
+	for i, tt := range parseMACTests {
 		out, err := ParseMAC(tt.in)
 		if !reflect.DeepEqual(out, tt.out) || !match(err, tt.err) {
-			t.Errorf("ParseMAC(%q) = %v, %v, want %v, %v", tt.in, out, err, tt.out,
-				tt.err)
+			t.Errorf("ParseMAC(%q) = %v, %v, want %v, %v", tt.in, out, err, tt.out, tt.err)
 		}
 		if tt.err == "" {
 			// Verify that serialization works too, and that it round-trips.
diff --git a/third_party/gofrontend/libgo/go/net/mail/example_test.go b/third_party/gofrontend/libgo/go/net/mail/example_test.go
new file mode 100644
index 0000000..972cfd6
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/net/mail/example_test.go
@@ -0,0 +1,79 @@
+// 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 ignore
+
+package mail_test
+
+import (
+	"fmt"
+	"io/ioutil"
+	"log"
+	"net/mail"
+	"strings"
+)
+
+func ExampleParseAddressList() {
+	const list = "Alice <alice@example.com>, Bob <bob@example.com>, Eve <eve@example.com>"
+	emails, err := mail.ParseAddressList(list)
+	if err != nil {
+		log.Fatal(err)
+	}
+
+	for _, v := range emails {
+		fmt.Println(v.Name, v.Address)
+	}
+
+	// Output:
+	// Alice alice@example.com
+	// Bob bob@example.com
+	// Eve eve@example.com
+}
+
+func ExampleParseAddress() {
+	e, err := mail.ParseAddress("Alice <alice@example.com>")
+	if err != nil {
+		log.Fatal(err)
+	}
+
+	fmt.Println(e.Name, e.Address)
+
+	// Output:
+	// Alice alice@example.com
+}
+
+func ExampleReadMessage() {
+	msg := `Date: Mon, 23 Jun 2015 11:40:36 -0400
+From: Gopher <from@example.com>
+To: Another Gopher <to@example.com>
+Subject: Gophers at Gophercon
+
+Message body
+`
+
+	r := strings.NewReader(msg)
+	m, err := mail.ReadMessage(r)
+	if err != nil {
+		log.Fatal(err)
+	}
+
+	header := m.Header
+	fmt.Println("Date:", header.Get("Date"))
+	fmt.Println("From:", header.Get("From"))
+	fmt.Println("To:", header.Get("To"))
+	fmt.Println("Subject:", header.Get("Subject"))
+
+	body, err := ioutil.ReadAll(m.Body)
+	if err != nil {
+		log.Fatal(err)
+	}
+	fmt.Printf("%s", body)
+
+	// Output:
+	// Date: Mon, 23 Jun 2015 11:40:36 -0400
+	// From: Gopher <from@example.com>
+	// To: Another Gopher <to@example.com>
+	// Subject: Gophers at Gophercon
+	// Message body
+}
diff --git a/third_party/gofrontend/libgo/go/net/mail/message.go b/third_party/gofrontend/libgo/go/net/mail/message.go
index 19aa888..266ac50 100644
--- a/third_party/gofrontend/libgo/go/net/mail/message.go
+++ b/third_party/gofrontend/libgo/go/net/mail/message.go
@@ -18,17 +18,14 @@
 import (
 	"bufio"
 	"bytes"
-	"encoding/base64"
 	"errors"
 	"fmt"
 	"io"
-	"io/ioutil"
 	"log"
+	"mime"
 	"net/textproto"
-	"strconv"
 	"strings"
 	"time"
-	"unicode"
 )
 
 var debug = debugT(false)
@@ -141,22 +138,79 @@
 
 // Parses a single RFC 5322 address, e.g. "Barry Gibbs <bg@example.com>"
 func ParseAddress(address string) (*Address, error) {
-	return newAddrParser(address).parseAddress()
+	return (&addrParser{s: address}).parseAddress()
 }
 
 // ParseAddressList parses the given string as a list of addresses.
 func ParseAddressList(list string) ([]*Address, error) {
-	return newAddrParser(list).parseAddressList()
+	return (&addrParser{s: list}).parseAddressList()
+}
+
+// An AddressParser is an RFC 5322 address parser.
+type AddressParser struct {
+	// WordDecoder optionally specifies a decoder for RFC 2047 encoded-words.
+	WordDecoder *mime.WordDecoder
+}
+
+// Parse parses a single RFC 5322 address of the
+// form "Gogh Fir <gf@example.com>" or "foo@example.com".
+func (p *AddressParser) Parse(address string) (*Address, error) {
+	return (&addrParser{s: address, dec: p.WordDecoder}).parseAddress()
+}
+
+// ParseList parses the given string as a list of comma-separated addresses
+// of the form "Gogh Fir <gf@example.com>" or "foo@example.com".
+func (p *AddressParser) ParseList(list string) ([]*Address, error) {
+	return (&addrParser{s: list, dec: p.WordDecoder}).parseAddressList()
 }
 
 // String formats the address as a valid RFC 5322 address.
 // If the address's name contains non-ASCII characters
 // the name will be rendered according to RFC 2047.
 func (a *Address) String() string {
-	s := "<" + a.Address + ">"
+
+	// Format address local@domain
+	at := strings.LastIndex(a.Address, "@")
+	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
+	//       should be merged in helper function.
+	quoteLocal := false
+	for i := 0; i < len(local); i++ {
+		ch := local[i]
+		if isAtext(ch, false) {
+			continue
+		}
+		if ch == '.' {
+			// Dots are okay if they are surrounded by atext.
+			// We only need to check that the previous byte is
+			// not a dot, and this isn't the end of the string.
+			if i > 0 && local[i-1] != '.' && i < len(local)-1 {
+				continue
+			}
+		}
+		quoteLocal = true
+		break
+	}
+	if quoteLocal {
+		local = quoteString(local)
+
+	}
+
+	s := "<" + local + "@" + domain + ">"
+
 	if a.Name == "" {
 		return s
 	}
+
 	// If every character is printable ASCII, quoting is simple.
 	allPrintable := true
 	for i := 0; i < len(a.Name); i++ {
@@ -180,28 +234,12 @@
 		return b.String()
 	}
 
-	// UTF-8 "Q" encoding
-	b := bytes.NewBufferString("=?utf-8?q?")
-	for i := 0; i < len(a.Name); i++ {
-		switch c := a.Name[i]; {
-		case c == ' ':
-			b.WriteByte('_')
-		case isVchar(c) && c != '=' && c != '?' && c != '_':
-			b.WriteByte(c)
-		default:
-			fmt.Fprintf(b, "=%02X", c)
-		}
-	}
-	b.WriteString("?= ")
-	b.WriteString(s)
-	return b.String()
+	return mime.QEncoding.Encode("utf-8", a.Name) + " " + s
 }
 
-type addrParser []byte
-
-func newAddrParser(s string) *addrParser {
-	p := addrParser(s)
-	return &p
+type addrParser struct {
+	s   string
+	dec *mime.WordDecoder // may be nil
 }
 
 func (p *addrParser) parseAddressList() ([]*Address, error) {
@@ -227,7 +265,7 @@
 
 // parseAddress parses a single RFC 5322 address at the start of p.
 func (p *addrParser) parseAddress() (addr *Address, err error) {
-	debug.Printf("parseAddress: %q", *p)
+	debug.Printf("parseAddress: %q", p.s)
 	p.skipSpace()
 	if p.empty() {
 		return nil, errors.New("mail: no address")
@@ -246,7 +284,7 @@
 		}, err
 	}
 	debug.Printf("parseAddress: not an addr-spec: %v", err)
-	debug.Printf("parseAddress: state is now %q", *p)
+	debug.Printf("parseAddress: state is now %q", p.s)
 
 	// display-name
 	var displayName string
@@ -280,7 +318,7 @@
 
 // consumeAddrSpec parses a single RFC 5322 addr-spec at the start of p.
 func (p *addrParser) consumeAddrSpec() (spec string, err error) {
-	debug.Printf("consumeAddrSpec: %q", *p)
+	debug.Printf("consumeAddrSpec: %q", p.s)
 
 	orig := *p
 	defer func() {
@@ -302,7 +340,7 @@
 	} else {
 		// dot-atom
 		debug.Printf("consumeAddrSpec: parsing dot-atom")
-		localPart, err = p.consumeAtom(true)
+		localPart, err = p.consumeAtom(true, false)
 	}
 	if err != nil {
 		debug.Printf("consumeAddrSpec: failed: %v", err)
@@ -320,7 +358,7 @@
 		return "", errors.New("mail: no domain in addr-spec")
 	}
 	// TODO(dsymonds): Handle domain-literal
-	domain, err = p.consumeAtom(true)
+	domain, err = p.consumeAtom(true, false)
 	if err != nil {
 		return "", err
 	}
@@ -330,7 +368,7 @@
 
 // consumePhrase parses the RFC 5322 phrase at the start of p.
 func (p *addrParser) consumePhrase() (phrase string, err error) {
-	debug.Printf("consumePhrase: [%s]", *p)
+	debug.Printf("consumePhrase: [%s]", p.s)
 	// phrase = 1*word
 	var words []string
 	for {
@@ -347,12 +385,11 @@
 			// atom
 			// We actually parse dot-atom here to be more permissive
 			// than what RFC 5322 specifies.
-			word, err = p.consumeAtom(true)
+			word, err = p.consumeAtom(true, true)
 		}
 
-		// RFC 2047 encoded-word starts with =?, ends with ?=, and has two other ?s.
-		if err == nil && strings.HasPrefix(word, "=?") && strings.HasSuffix(word, "?=") && strings.Count(word, "?") == 4 {
-			word, err = decodeRFC2047Word(word)
+		if err == nil {
+			word, err = p.decodeRFC2047Word(word)
 		}
 
 		if err != nil {
@@ -380,16 +417,16 @@
 		if i >= p.len() {
 			return "", errors.New("mail: unclosed quoted-string")
 		}
-		switch c := (*p)[i]; {
+		switch c := p.s[i]; {
 		case c == '"':
 			break Loop
 		case c == '\\':
 			if i+1 == p.len() {
 				return "", errors.New("mail: unclosed quoted-string")
 			}
-			qsb = append(qsb, (*p)[i+1])
+			qsb = append(qsb, p.s[i+1])
 			i += 2
-		case isQtext(c), c == ' ' || c == '\t':
+		case isQtext(c), c == ' ':
 			// qtext (printable US-ASCII excluding " and \), or
 			// FWS (almost; we're ignoring CRLF)
 			qsb = append(qsb, c)
@@ -398,20 +435,36 @@
 			return "", fmt.Errorf("mail: bad character in quoted-string: %q", c)
 		}
 	}
-	*p = (*p)[i+1:]
+	p.s = p.s[i+1:]
+	if len(qsb) == 0 {
+		return "", errors.New("mail: empty quoted-string")
+	}
 	return string(qsb), nil
 }
 
 // consumeAtom parses an RFC 5322 atom at the start of p.
 // If dot is true, consumeAtom parses an RFC 5322 dot-atom instead.
-func (p *addrParser) consumeAtom(dot bool) (atom string, err error) {
+// If permissive is true, consumeAtom will not fail on
+// leading/trailing/double dots in the atom (see golang.org/issue/4938).
+func (p *addrParser) consumeAtom(dot bool, permissive bool) (atom string, err error) {
 	if !isAtext(p.peek(), false) {
 		return "", errors.New("mail: invalid string")
 	}
 	i := 1
-	for ; i < p.len() && isAtext((*p)[i], dot); i++ {
+	for ; i < p.len() && isAtext(p.s[i], dot); i++ {
 	}
-	atom, *p = string((*p)[:i]), (*p)[i:]
+	atom, p.s = string(p.s[:i]), p.s[i:]
+	if !permissive {
+		if strings.HasPrefix(atom, ".") {
+			return "", errors.New("mail: leading dot in atom")
+		}
+		if strings.Contains(atom, "..") {
+			return "", errors.New("mail: double dot in atom")
+		}
+		if strings.HasSuffix(atom, ".") {
+			return "", errors.New("mail: trailing dot in atom")
+		}
+	}
 	return atom, nil
 }
 
@@ -419,17 +472,17 @@
 	if p.empty() || p.peek() != c {
 		return false
 	}
-	*p = (*p)[1:]
+	p.s = p.s[1:]
 	return true
 }
 
 // skipSpace skips the leading space and tab characters.
 func (p *addrParser) skipSpace() {
-	*p = bytes.TrimLeft(*p, " \t")
+	p.s = strings.TrimLeft(p.s, " \t")
 }
 
 func (p *addrParser) peek() byte {
-	return (*p)[0]
+	return p.s[0]
 }
 
 func (p *addrParser) empty() bool {
@@ -437,87 +490,37 @@
 }
 
 func (p *addrParser) len() int {
-	return len(*p)
+	return len(p.s)
 }
 
-func decodeRFC2047Word(s string) (string, error) {
-	fields := strings.Split(s, "?")
-	if len(fields) != 5 || fields[0] != "=" || fields[4] != "=" {
-		return "", errors.New("address not RFC 2047 encoded")
-	}
-	charset, enc := strings.ToLower(fields[1]), strings.ToLower(fields[2])
-	if charset != "us-ascii" && charset != "iso-8859-1" && charset != "utf-8" {
-		return "", fmt.Errorf("charset not supported: %q", charset)
+func (p *addrParser) decodeRFC2047Word(s string) (string, error) {
+	if p.dec != nil {
+		return p.dec.DecodeHeader(s)
 	}
 
-	in := bytes.NewBufferString(fields[3])
-	var r io.Reader
-	switch enc {
-	case "b":
-		r = base64.NewDecoder(base64.StdEncoding, in)
-	case "q":
-		r = qDecoder{r: in}
-	default:
-		return "", fmt.Errorf("RFC 2047 encoding not supported: %q", enc)
+	dec, err := rfc2047Decoder.Decode(s)
+	if err == nil {
+		return dec, nil
 	}
 
-	dec, err := ioutil.ReadAll(r)
-	if err != nil {
-		return "", err
+	if _, ok := err.(charsetError); ok {
+		return s, err
 	}
 
-	switch charset {
-	case "us-ascii":
-		b := new(bytes.Buffer)
-		for _, c := range dec {
-			if c >= 0x80 {
-				b.WriteRune(unicode.ReplacementChar)
-			} else {
-				b.WriteRune(rune(c))
-			}
-		}
-		return b.String(), nil
-	case "iso-8859-1":
-		b := new(bytes.Buffer)
-		for _, c := range dec {
-			b.WriteRune(rune(c))
-		}
-		return b.String(), nil
-	case "utf-8":
-		return string(dec), nil
-	}
-	panic("unreachable")
+	// Ignore invalid RFC 2047 encoded-word errors.
+	return s, nil
 }
 
-type qDecoder struct {
-	r       io.Reader
-	scratch [2]byte
+var rfc2047Decoder = mime.WordDecoder{
+	CharsetReader: func(charset string, input io.Reader) (io.Reader, error) {
+		return nil, charsetError(charset)
+	},
 }
 
-func (qd qDecoder) Read(p []byte) (n int, err error) {
-	// This method writes at most one byte into p.
-	if len(p) == 0 {
-		return 0, nil
-	}
-	if _, err := qd.r.Read(qd.scratch[:1]); err != nil {
-		return 0, err
-	}
-	switch c := qd.scratch[0]; {
-	case c == '=':
-		if _, err := io.ReadFull(qd.r, qd.scratch[:2]); err != nil {
-			return 0, err
-		}
-		x, err := strconv.ParseInt(string(qd.scratch[:2]), 16, 64)
-		if err != nil {
-			return 0, fmt.Errorf("mail: invalid RFC 2047 encoding: %q", qd.scratch[:2])
-		}
-		p[0] = byte(x)
-	case c == '_':
-		p[0] = ' '
-	default:
-		p[0] = c
-	}
-	return 1, nil
+type charsetError string
+
+func (e charsetError) Error() string {
+	return fmt.Sprintf("charset not supported: %q", string(e))
 }
 
 var atextChars = []byte("ABCDEFGHIJKLMNOPQRSTUVWXYZ" +
@@ -525,7 +528,7 @@
 	"0123456789" +
 	"!#$%&'*+-/=?^_`{|}~")
 
-// isAtext returns true if c is an RFC 5322 atext character.
+// isAtext reports whether c is an RFC 5322 atext character.
 // If dot is true, period is included.
 func isAtext(c byte, dot bool) bool {
 	if dot && c == '.' {
@@ -534,7 +537,7 @@
 	return bytes.IndexByte(atextChars, c) >= 0
 }
 
-// isQtext returns true if c is an RFC 5322 qtext character.
+// isQtext reports whether c is an RFC 5322 qtext character.
 func isQtext(c byte) bool {
 	// Printable US-ASCII, excluding backslash or quote.
 	if c == '\\' || c == '"' {
@@ -543,13 +546,30 @@
 	return '!' <= c && c <= '~'
 }
 
-// isVchar returns true if c is an RFC 5322 VCHAR character.
+// quoteString renders a string as a RFC5322 quoted-string.
+func quoteString(s string) string {
+	var buf bytes.Buffer
+	buf.WriteByte('"')
+	for _, c := range s {
+		ch := byte(c)
+		if isQtext(ch) || isWSP(ch) {
+			buf.WriteByte(ch)
+		} else if isVchar(ch) {
+			buf.WriteByte('\\')
+			buf.WriteByte(ch)
+		}
+	}
+	buf.WriteByte('"')
+	return buf.String()
+}
+
+// isVchar reports whether c is an RFC 5322 VCHAR character.
 func isVchar(c byte) bool {
 	// Visible (printing) characters.
 	return '!' <= c && c <= '~'
 }
 
-// isWSP returns true if c is a WSP (white space).
+// isWSP reports whether c is a WSP (white space).
 // WSP is a space or horizontal tab (RFC5234 Appendix B).
 func isWSP(c byte) bool {
 	return c == ' ' || c == '\t'
diff --git a/third_party/gofrontend/libgo/go/net/mail/message_test.go b/third_party/gofrontend/libgo/go/net/mail/message_test.go
index 6ba48be..1b42274 100644
--- a/third_party/gofrontend/libgo/go/net/mail/message_test.go
+++ b/third_party/gofrontend/libgo/go/net/mail/message_test.go
@@ -6,7 +6,9 @@
 
 import (
 	"bytes"
+	"io"
 	"io/ioutil"
+	"mime"
 	"reflect"
 	"strings"
 	"testing"
@@ -278,6 +280,175 @@
 	}
 }
 
+func TestAddressParser(t *testing.T) {
+	tests := []struct {
+		addrsStr string
+		exp      []*Address
+	}{
+		// Bare address
+		{
+			`jdoe@machine.example`,
+			[]*Address{{
+				Address: "jdoe@machine.example",
+			}},
+		},
+		// RFC 5322, Appendix A.1.1
+		{
+			`John Doe <jdoe@machine.example>`,
+			[]*Address{{
+				Name:    "John Doe",
+				Address: "jdoe@machine.example",
+			}},
+		},
+		// RFC 5322, Appendix A.1.2
+		{
+			`"Joe Q. Public" <john.q.public@example.com>`,
+			[]*Address{{
+				Name:    "Joe Q. Public",
+				Address: "john.q.public@example.com",
+			}},
+		},
+		{
+			`Mary Smith <mary@x.test>, jdoe@example.org, Who? <one@y.test>`,
+			[]*Address{
+				{
+					Name:    "Mary Smith",
+					Address: "mary@x.test",
+				},
+				{
+					Address: "jdoe@example.org",
+				},
+				{
+					Name:    "Who?",
+					Address: "one@y.test",
+				},
+			},
+		},
+		{
+			`<boss@nil.test>, "Giant; \"Big\" Box" <sysservices@example.net>`,
+			[]*Address{
+				{
+					Address: "boss@nil.test",
+				},
+				{
+					Name:    `Giant; "Big" Box`,
+					Address: "sysservices@example.net",
+				},
+			},
+		},
+		// RFC 2047 "Q"-encoded ISO-8859-1 address.
+		{
+			`=?iso-8859-1?q?J=F6rg_Doe?= <joerg@example.com>`,
+			[]*Address{
+				{
+					Name:    `Jörg Doe`,
+					Address: "joerg@example.com",
+				},
+			},
+		},
+		// RFC 2047 "Q"-encoded US-ASCII address. Dumb but legal.
+		{
+			`=?us-ascii?q?J=6Frg_Doe?= <joerg@example.com>`,
+			[]*Address{
+				{
+					Name:    `Jorg Doe`,
+					Address: "joerg@example.com",
+				},
+			},
+		},
+		// RFC 2047 "Q"-encoded ISO-8859-15 address.
+		{
+			`=?ISO-8859-15?Q?J=F6rg_Doe?= <joerg@example.com>`,
+			[]*Address{
+				{
+					Name:    `Jörg Doe`,
+					Address: "joerg@example.com",
+				},
+			},
+		},
+		// RFC 2047 "B"-encoded windows-1252 address.
+		{
+			`=?windows-1252?q?Andr=E9?= Pirard <PIRARD@vm1.ulg.ac.be>`,
+			[]*Address{
+				{
+					Name:    `André Pirard`,
+					Address: "PIRARD@vm1.ulg.ac.be",
+				},
+			},
+		},
+		// Custom example of RFC 2047 "B"-encoded ISO-8859-15 address.
+		{
+			`=?ISO-8859-15?B?SvZyZw==?= <joerg@example.com>`,
+			[]*Address{
+				{
+					Name:    `Jörg`,
+					Address: "joerg@example.com",
+				},
+			},
+		},
+		// Custom example of RFC 2047 "B"-encoded UTF-8 address.
+		{
+			`=?UTF-8?B?SsO2cmc=?= <joerg@example.com>`,
+			[]*Address{
+				{
+					Name:    `Jörg`,
+					Address: "joerg@example.com",
+				},
+			},
+		},
+		// Custom example with "." in name. For issue 4938
+		{
+			`Asem H. <noreply@example.com>`,
+			[]*Address{
+				{
+					Name:    `Asem H.`,
+					Address: "noreply@example.com",
+				},
+			},
+		},
+	}
+
+	ap := AddressParser{WordDecoder: &mime.WordDecoder{
+		CharsetReader: func(charset string, input io.Reader) (io.Reader, error) {
+			in, err := ioutil.ReadAll(input)
+			if err != nil {
+				return nil, err
+			}
+
+			switch charset {
+			case "iso-8859-15":
+				in = bytes.Replace(in, []byte("\xf6"), []byte("ö"), -1)
+			case "windows-1252":
+				in = bytes.Replace(in, []byte("\xe9"), []byte("é"), -1)
+			}
+
+			return bytes.NewReader(in), nil
+		},
+	}}
+
+	for _, test := range tests {
+		if len(test.exp) == 1 {
+			addr, err := ap.Parse(test.addrsStr)
+			if err != nil {
+				t.Errorf("Failed parsing (single) %q: %v", test.addrsStr, err)
+				continue
+			}
+			if !reflect.DeepEqual([]*Address{addr}, test.exp) {
+				t.Errorf("Parse (single) of %q: got %+v, want %+v", test.addrsStr, addr, test.exp)
+			}
+		}
+
+		addrs, err := ap.ParseList(test.addrsStr)
+		if err != nil {
+			t.Errorf("Failed parsing (list) %q: %v", test.addrsStr, err)
+			continue
+		}
+		if !reflect.DeepEqual(addrs, test.exp) {
+			t.Errorf("Parse (list) of %q: got %+v, want %+v", test.addrsStr, addrs, test.exp)
+		}
+	}
+}
+
 func TestAddressFormatting(t *testing.T) {
 	tests := []struct {
 		addr *Address
@@ -287,6 +458,14 @@
 			&Address{Address: "bob@example.com"},
 			"<bob@example.com>",
 		},
+		{ // quoted local parts: RFC 5322, 3.4.1. and 3.2.4.
+			&Address{Address: `my@idiot@address@example.com`},
+			`<"my@idiot@address"@example.com>`,
+		},
+		{ // quoted local parts
+			&Address{Address: ` @example.com`},
+			`<" "@example.com>`,
+		},
 		{
 			&Address{Name: "Bob", Address: "bob@example.com"},
 			`"Bob" <bob@example.com>`,
@@ -304,6 +483,14 @@
 			&Address{Name: "Böb Jacöb", Address: "bob@example.com"},
 			`=?utf-8?q?B=C3=B6b_Jac=C3=B6b?= <bob@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()
@@ -312,3 +499,90 @@
 		}
 	}
 }
+
+// Check if all valid addresses can be parsed, formatted and parsed again
+func TestAddressParsingAndFormatting(t *testing.T) {
+
+	// Should pass
+	tests := []string{
+		`<Bob@example.com>`,
+		`<bob.bob@example.com>`,
+		`<".bob"@example.com>`,
+		`<" "@example.com>`,
+		`<some.mail-with-dash@example.com>`,
+		`<"dot.and space"@example.com>`,
+		`<"very.unusual.@.unusual.com"@example.com>`,
+		`<admin@mailserver1>`,
+		`<postmaster@localhost>`,
+		"<#!$%&'*+-/=?^_`{}|~@example.org>",
+		`<"very.(),:;<>[]\".VERY.\"very@\\ \"very\".unusual"@strange.example.com>`, // escaped quotes
+		`<"()<>[]:,;@\\\"!#$%&'*+-/=?^_{}| ~.a"@example.org>`,                      // escaped backslashes
+		`<"Abc\\@def"@example.com>`,
+		`<"Joe\\Blow"@example.com>`,
+		`<test1/test2=test3@example.com>`,
+		`<def!xyz%abc@example.com>`,
+		`<_somename@example.com>`,
+		`<joe@uk>`,
+		`<~@example.com>`,
+		`<"..."@test.com>`,
+		`<"john..doe"@example.com>`,
+		`<"john.doe."@example.com>`,
+		`<".john.doe"@example.com>`,
+		`<"."@example.com>`,
+		`<".."@example.com>`,
+		`<"0:"@0>`,
+	}
+
+	for _, test := range tests {
+		addr, err := ParseAddress(test)
+		if err != nil {
+			t.Errorf("Couldn't parse address %s: %s", test, err.Error())
+			continue
+		}
+		str := addr.String()
+		addr, err = ParseAddress(str)
+		if err != nil {
+			t.Errorf("ParseAddr(%q) error: %v", test, err)
+			continue
+		}
+
+		if addr.String() != test {
+			t.Errorf("String() round-trip = %q; want %q", addr, test)
+			continue
+		}
+
+	}
+
+	// Should fail
+	badTests := []string{
+		`<Abc.example.com>`,
+		`<A@b@c@example.com>`,
+		`<a"b(c)d,e:f;g<h>i[j\k]l@example.com>`,
+		`<just"not"right@example.com>`,
+		`<this is"not\allowed@example.com>`,
+		`<this\ still\"not\\allowed@example.com>`,
+		`<john..doe@example.com>`,
+		`<john.doe@example..com>`,
+		`<john.doe@example..com>`,
+		`<john.doe.@example.com>`,
+		`<john.doe.@.example.com>`,
+		`<.john.doe@example.com>`,
+		`<@example.com>`,
+		`<.@example.com>`,
+		`<test@.>`,
+		`< @example.com>`,
+		`<""test""blah""@example.com>`,
+		`<""@0>`,
+		"<\"\t0\"@0>",
+	}
+
+	for _, test := range badTests {
+		_, err := ParseAddress(test)
+		if err == nil {
+			t.Errorf("Should have failed to parse address: %s", test)
+			continue
+		}
+
+	}
+
+}
diff --git a/third_party/gofrontend/libgo/go/net/main_cloexec_test.go b/third_party/gofrontend/libgo/go/net/main_cloexec_test.go
new file mode 100644
index 0000000..7903819
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/net/main_cloexec_test.go
@@ -0,0 +1,25 @@
+// 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 freebsd linux
+
+package net
+
+func init() {
+	extraTestHookInstallers = append(extraTestHookInstallers, installAccept4TestHook)
+	extraTestHookUninstallers = append(extraTestHookUninstallers, uninstallAccept4TestHook)
+}
+
+var (
+	// Placeholders for saving original socket system calls.
+	origAccept4 = accept4Func
+)
+
+func installAccept4TestHook() {
+	accept4Func = sw.Accept4
+}
+
+func uninstallAccept4TestHook() {
+	accept4Func = origAccept4
+}
diff --git a/third_party/gofrontend/libgo/go/net/main_plan9_test.go b/third_party/gofrontend/libgo/go/net/main_plan9_test.go
new file mode 100644
index 0000000..94501ca
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/net/main_plan9_test.go
@@ -0,0 +1,15 @@
+// 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 net
+
+func installTestHooks() {}
+
+func uninstallTestHooks() {}
+
+func forceCloseSockets() {}
+
+func enableSocketConnect() {}
+
+func disableSocketConnect(network string) {}
diff --git a/third_party/gofrontend/libgo/go/net/main_posix_test.go b/third_party/gofrontend/libgo/go/net/main_posix_test.go
new file mode 100644
index 0000000..ead311c
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/net/main_posix_test.go
@@ -0,0 +1,50 @@
+// 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 !plan9
+
+package net
+
+import (
+	"net/internal/socktest"
+	"strings"
+	"syscall"
+)
+
+func enableSocketConnect() {
+	sw.Set(socktest.FilterConnect, nil)
+}
+
+func disableSocketConnect(network string) {
+	ss := strings.Split(network, ":")
+	sw.Set(socktest.FilterConnect, func(so *socktest.Status) (socktest.AfterFilter, error) {
+		switch ss[0] {
+		case "tcp4":
+			if so.Cookie.Family() == syscall.AF_INET && so.Cookie.Type() == syscall.SOCK_STREAM {
+				return nil, syscall.EHOSTUNREACH
+			}
+		case "udp4":
+			if so.Cookie.Family() == syscall.AF_INET && so.Cookie.Type() == syscall.SOCK_DGRAM {
+				return nil, syscall.EHOSTUNREACH
+			}
+		case "ip4":
+			if so.Cookie.Family() == syscall.AF_INET && so.Cookie.Type() == syscall.SOCK_RAW {
+				return nil, syscall.EHOSTUNREACH
+			}
+		case "tcp6":
+			if so.Cookie.Family() == syscall.AF_INET6 && so.Cookie.Type() == syscall.SOCK_STREAM {
+				return nil, syscall.EHOSTUNREACH
+			}
+		case "udp6":
+			if so.Cookie.Family() == syscall.AF_INET6 && so.Cookie.Type() == syscall.SOCK_DGRAM {
+				return nil, syscall.EHOSTUNREACH
+			}
+		case "ip6":
+			if so.Cookie.Family() == syscall.AF_INET6 && so.Cookie.Type() == syscall.SOCK_RAW {
+				return nil, syscall.EHOSTUNREACH
+			}
+		}
+		return nil, nil
+	})
+}
diff --git a/third_party/gofrontend/libgo/go/net/main_test.go b/third_party/gofrontend/libgo/go/net/main_test.go
new file mode 100644
index 0000000..f3f8b1a
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/net/main_test.go
@@ -0,0 +1,204 @@
+// 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 net
+
+import (
+	"flag"
+	"fmt"
+	"net/internal/socktest"
+	"os"
+	"runtime"
+	"sort"
+	"strings"
+	"sync"
+	"testing"
+)
+
+var (
+	sw socktest.Switch
+
+	// uninstallTestHooks runs just before a run of benchmarks.
+	testHookUninstaller sync.Once
+)
+
+var (
+	testDNSFlood = flag.Bool("dnsflood", false, "whether to test DNS query flooding")
+
+	testExternal = flag.Bool("external", true, "allow use of external networks during long test")
+
+	// If external IPv4 connectivity exists, we can try dialing
+	// non-node/interface local scope IPv4 addresses.
+	// On Windows, Lookup APIs may not return IPv4-related
+	// resource records when a node has no external IPv4
+	// connectivity.
+	testIPv4 = flag.Bool("ipv4", true, "assume external IPv4 connectivity exists")
+
+	// If external IPv6 connectivity exists, we can try dialing
+	// non-node/interface local scope IPv6 addresses.
+	// On Windows, Lookup APIs may not return IPv6-related
+	// resource records when a node has no external IPv6
+	// connectivity.
+	testIPv6 = flag.Bool("ipv6", false, "assume external IPv6 connectivity exists")
+)
+
+func TestMain(m *testing.M) {
+	setupTestData()
+	installTestHooks()
+
+	st := m.Run()
+
+	testHookUninstaller.Do(uninstallTestHooks)
+	if testing.Verbose() {
+		printRunningGoroutines()
+		printInflightSockets()
+		printSocketStats()
+	}
+	forceCloseSockets()
+	os.Exit(st)
+}
+
+type ipv6LinkLocalUnicastTest struct {
+	network, address string
+	nameLookup       bool
+}
+
+var (
+	ipv6LinkLocalUnicastTCPTests []ipv6LinkLocalUnicastTest
+	ipv6LinkLocalUnicastUDPTests []ipv6LinkLocalUnicastTest
+)
+
+func setupTestData() {
+	if supportsIPv4 {
+		resolveTCPAddrTests = append(resolveTCPAddrTests, []resolveTCPAddrTest{
+			{"tcp", "localhost:1", &TCPAddr{IP: IPv4(127, 0, 0, 1), Port: 1}, nil},
+			{"tcp4", "localhost:2", &TCPAddr{IP: IPv4(127, 0, 0, 1), Port: 2}, nil},
+		}...)
+		resolveUDPAddrTests = append(resolveUDPAddrTests, []resolveUDPAddrTest{
+			{"udp", "localhost:1", &UDPAddr{IP: IPv4(127, 0, 0, 1), Port: 1}, nil},
+			{"udp4", "localhost:2", &UDPAddr{IP: IPv4(127, 0, 0, 1), Port: 2}, nil},
+		}...)
+		resolveIPAddrTests = append(resolveIPAddrTests, []resolveIPAddrTest{
+			{"ip", "localhost", &IPAddr{IP: IPv4(127, 0, 0, 1)}, nil},
+			{"ip4", "localhost", &IPAddr{IP: IPv4(127, 0, 0, 1)}, nil},
+		}...)
+	}
+
+	if supportsIPv6 {
+		resolveTCPAddrTests = append(resolveTCPAddrTests, resolveTCPAddrTest{"tcp6", "localhost:3", &TCPAddr{IP: IPv6loopback, Port: 3}, nil})
+		resolveUDPAddrTests = append(resolveUDPAddrTests, resolveUDPAddrTest{"udp6", "localhost:3", &UDPAddr{IP: IPv6loopback, Port: 3}, nil})
+		resolveIPAddrTests = append(resolveIPAddrTests, resolveIPAddrTest{"ip6", "localhost", &IPAddr{IP: IPv6loopback}, nil})
+	}
+
+	ifi := loopbackInterface()
+	if ifi != nil {
+		index := fmt.Sprintf("%v", ifi.Index)
+		resolveTCPAddrTests = append(resolveTCPAddrTests, []resolveTCPAddrTest{
+			{"tcp6", "[fe80::1%" + ifi.Name + "]:1", &TCPAddr{IP: ParseIP("fe80::1"), Port: 1, Zone: zoneToString(ifi.Index)}, nil},
+			{"tcp6", "[fe80::1%" + index + "]:2", &TCPAddr{IP: ParseIP("fe80::1"), Port: 2, Zone: index}, nil},
+		}...)
+		resolveUDPAddrTests = append(resolveUDPAddrTests, []resolveUDPAddrTest{
+			{"udp6", "[fe80::1%" + ifi.Name + "]:1", &UDPAddr{IP: ParseIP("fe80::1"), Port: 1, Zone: zoneToString(ifi.Index)}, nil},
+			{"udp6", "[fe80::1%" + index + "]:2", &UDPAddr{IP: ParseIP("fe80::1"), Port: 2, Zone: index}, nil},
+		}...)
+		resolveIPAddrTests = append(resolveIPAddrTests, []resolveIPAddrTest{
+			{"ip6", "fe80::1%" + ifi.Name, &IPAddr{IP: ParseIP("fe80::1"), Zone: zoneToString(ifi.Index)}, nil},
+			{"ip6", "fe80::1%" + index, &IPAddr{IP: ParseIP("fe80::1"), Zone: index}, nil},
+		}...)
+	}
+
+	addr := ipv6LinkLocalUnicastAddr(ifi)
+	if addr != "" {
+		if runtime.GOOS != "dragonfly" {
+			ipv6LinkLocalUnicastTCPTests = append(ipv6LinkLocalUnicastTCPTests, []ipv6LinkLocalUnicastTest{
+				{"tcp", "[" + addr + "%" + ifi.Name + "]:0", false},
+			}...)
+			ipv6LinkLocalUnicastUDPTests = append(ipv6LinkLocalUnicastUDPTests, []ipv6LinkLocalUnicastTest{
+				{"udp", "[" + addr + "%" + ifi.Name + "]:0", false},
+			}...)
+		}
+		ipv6LinkLocalUnicastTCPTests = append(ipv6LinkLocalUnicastTCPTests, []ipv6LinkLocalUnicastTest{
+			{"tcp6", "[" + addr + "%" + ifi.Name + "]:0", false},
+		}...)
+		ipv6LinkLocalUnicastUDPTests = append(ipv6LinkLocalUnicastUDPTests, []ipv6LinkLocalUnicastTest{
+			{"udp6", "[" + addr + "%" + ifi.Name + "]:0", false},
+		}...)
+		switch runtime.GOOS {
+		case "darwin", "dragonfly", "freebsd", "openbsd", "netbsd":
+			ipv6LinkLocalUnicastTCPTests = append(ipv6LinkLocalUnicastTCPTests, []ipv6LinkLocalUnicastTest{
+				{"tcp", "[localhost%" + ifi.Name + "]:0", true},
+				{"tcp6", "[localhost%" + ifi.Name + "]:0", true},
+			}...)
+			ipv6LinkLocalUnicastUDPTests = append(ipv6LinkLocalUnicastUDPTests, []ipv6LinkLocalUnicastTest{
+				{"udp", "[localhost%" + ifi.Name + "]:0", true},
+				{"udp6", "[localhost%" + ifi.Name + "]:0", true},
+			}...)
+		case "linux":
+			ipv6LinkLocalUnicastTCPTests = append(ipv6LinkLocalUnicastTCPTests, []ipv6LinkLocalUnicastTest{
+				{"tcp", "[ip6-localhost%" + ifi.Name + "]:0", true},
+				{"tcp6", "[ip6-localhost%" + ifi.Name + "]:0", true},
+			}...)
+			ipv6LinkLocalUnicastUDPTests = append(ipv6LinkLocalUnicastUDPTests, []ipv6LinkLocalUnicastTest{
+				{"udp", "[ip6-localhost%" + ifi.Name + "]:0", true},
+				{"udp6", "[ip6-localhost%" + ifi.Name + "]:0", true},
+			}...)
+		}
+	}
+}
+
+func printRunningGoroutines() {
+	gss := runningGoroutines()
+	if len(gss) == 0 {
+		return
+	}
+	fmt.Fprintf(os.Stderr, "Running goroutines:\n")
+	for _, gs := range gss {
+		fmt.Fprintf(os.Stderr, "%v\n", gs)
+	}
+	fmt.Fprintf(os.Stderr, "\n")
+}
+
+// runningGoroutines returns a list of remaining goroutines.
+func runningGoroutines() []string {
+	var gss []string
+	b := make([]byte, 2<<20)
+	b = b[:runtime.Stack(b, true)]
+	for _, s := range strings.Split(string(b), "\n\n") {
+		ss := strings.SplitN(s, "\n", 2)
+		if len(ss) != 2 {
+			continue
+		}
+		stack := strings.TrimSpace(ss[1])
+		if !strings.Contains(stack, "created by net") {
+			continue
+		}
+		gss = append(gss, stack)
+	}
+	sort.Strings(gss)
+	return gss
+}
+
+func printInflightSockets() {
+	sos := sw.Sockets()
+	if len(sos) == 0 {
+		return
+	}
+	fmt.Fprintf(os.Stderr, "Inflight sockets:\n")
+	for s, so := range sos {
+		fmt.Fprintf(os.Stderr, "%v: %v\n", s, so)
+	}
+	fmt.Fprintf(os.Stderr, "\n")
+}
+
+func printSocketStats() {
+	sts := sw.Stats()
+	if len(sts) == 0 {
+		return
+	}
+	fmt.Fprintf(os.Stderr, "Socket statistical information:\n")
+	for _, st := range sts {
+		fmt.Fprintf(os.Stderr, "%v\n", st)
+	}
+	fmt.Fprintf(os.Stderr, "\n")
+}
diff --git a/third_party/gofrontend/libgo/go/net/main_unix_test.go b/third_party/gofrontend/libgo/go/net/main_unix_test.go
new file mode 100644
index 0000000..bfb4cd0
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/net/main_unix_test.go
@@ -0,0 +1,52 @@
+// 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 darwin dragonfly freebsd linux nacl netbsd openbsd solaris
+
+package net
+
+var (
+	// Placeholders for saving original socket system calls.
+	origSocket        = socketFunc
+	origClose         = closeFunc
+	origConnect       = connectFunc
+	origListen        = listenFunc
+	origAccept        = acceptFunc
+	origGetsockoptInt = getsockoptIntFunc
+
+	extraTestHookInstallers   []func()
+	extraTestHookUninstallers []func()
+)
+
+func installTestHooks() {
+	socketFunc = sw.Socket
+	closeFunc = sw.Close
+	connectFunc = sw.Connect
+	listenFunc = sw.Listen
+	acceptFunc = sw.Accept
+	getsockoptIntFunc = sw.GetsockoptInt
+
+	for _, fn := range extraTestHookInstallers {
+		fn()
+	}
+}
+
+func uninstallTestHooks() {
+	socketFunc = origSocket
+	closeFunc = origClose
+	connectFunc = origConnect
+	listenFunc = origListen
+	acceptFunc = origAccept
+	getsockoptIntFunc = origGetsockoptInt
+
+	for _, fn := range extraTestHookUninstallers {
+		fn()
+	}
+}
+
+func forceCloseSockets() {
+	for s := range sw.Sockets() {
+		closeFunc(s)
+	}
+}
diff --git a/third_party/gofrontend/libgo/go/net/main_windows_test.go b/third_party/gofrontend/libgo/go/net/main_windows_test.go
new file mode 100644
index 0000000..2d82974
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/net/main_windows_test.go
@@ -0,0 +1,36 @@
+// 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 net
+
+var (
+	// Placeholders for saving original socket system calls.
+	origSocket      = socketFunc
+	origClosesocket = closeFunc
+	origConnect     = connectFunc
+	origConnectEx   = connectExFunc
+	origListen      = listenFunc
+)
+
+func installTestHooks() {
+	socketFunc = sw.Socket
+	closeFunc = sw.Closesocket
+	connectFunc = sw.Connect
+	connectExFunc = sw.ConnectEx
+	listenFunc = sw.Listen
+}
+
+func uninstallTestHooks() {
+	socketFunc = origSocket
+	closeFunc = origClosesocket
+	connectFunc = origConnect
+	connectExFunc = origConnectEx
+	listenFunc = origListen
+}
+
+func forceCloseSockets() {
+	for s := range sw.Sockets() {
+		closeFunc(s)
+	}
+}
diff --git a/third_party/gofrontend/libgo/go/net/mockicmp_test.go b/third_party/gofrontend/libgo/go/net/mockicmp_test.go
deleted file mode 100644
index e742365..0000000
--- a/third_party/gofrontend/libgo/go/net/mockicmp_test.go
+++ /dev/null
@@ -1,116 +0,0 @@
-// Copyright 2009 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 net
-
-import "errors"
-
-const (
-	icmpv4EchoRequest = 8
-	icmpv4EchoReply   = 0
-	icmpv6EchoRequest = 128
-	icmpv6EchoReply   = 129
-)
-
-// icmpMessage represents an ICMP message.
-type icmpMessage struct {
-	Type     int             // type
-	Code     int             // code
-	Checksum int             // checksum
-	Body     icmpMessageBody // body
-}
-
-// icmpMessageBody represents an ICMP message body.
-type icmpMessageBody interface {
-	Len() int
-	Marshal() ([]byte, error)
-}
-
-// Marshal returns the binary enconding of the ICMP echo request or
-// reply message m.
-func (m *icmpMessage) Marshal() ([]byte, error) {
-	b := []byte{byte(m.Type), byte(m.Code), 0, 0}
-	if m.Body != nil && m.Body.Len() != 0 {
-		mb, err := m.Body.Marshal()
-		if err != nil {
-			return nil, err
-		}
-		b = append(b, mb...)
-	}
-	switch m.Type {
-	case icmpv6EchoRequest, icmpv6EchoReply:
-		return b, nil
-	}
-	csumcv := len(b) - 1 // checksum coverage
-	s := uint32(0)
-	for i := 0; i < csumcv; i += 2 {
-		s += uint32(b[i+1])<<8 | uint32(b[i])
-	}
-	if csumcv&1 == 0 {
-		s += uint32(b[csumcv])
-	}
-	s = s>>16 + s&0xffff
-	s = s + s>>16
-	// Place checksum back in header; using ^= avoids the
-	// assumption the checksum bytes are zero.
-	b[2] ^= byte(^s)
-	b[3] ^= byte(^s >> 8)
-	return b, nil
-}
-
-// parseICMPMessage parses b as an ICMP message.
-func parseICMPMessage(b []byte) (*icmpMessage, error) {
-	msglen := len(b)
-	if msglen < 4 {
-		return nil, errors.New("message too short")
-	}
-	m := &icmpMessage{Type: int(b[0]), Code: int(b[1]), Checksum: int(b[2])<<8 | int(b[3])}
-	if msglen > 4 {
-		var err error
-		switch m.Type {
-		case icmpv4EchoRequest, icmpv4EchoReply, icmpv6EchoRequest, icmpv6EchoReply:
-			m.Body, err = parseICMPEcho(b[4:])
-			if err != nil {
-				return nil, err
-			}
-		}
-	}
-	return m, nil
-}
-
-// imcpEcho represenets an ICMP echo request or reply message body.
-type icmpEcho struct {
-	ID   int    // identifier
-	Seq  int    // sequence number
-	Data []byte // data
-}
-
-func (p *icmpEcho) Len() int {
-	if p == nil {
-		return 0
-	}
-	return 4 + len(p.Data)
-}
-
-// Marshal returns the binary enconding of the ICMP echo request or
-// reply message body p.
-func (p *icmpEcho) Marshal() ([]byte, error) {
-	b := make([]byte, 4+len(p.Data))
-	b[0], b[1] = byte(p.ID>>8), byte(p.ID)
-	b[2], b[3] = byte(p.Seq>>8), byte(p.Seq)
-	copy(b[4:], p.Data)
-	return b, nil
-}
-
-// parseICMPEcho parses b as an ICMP echo request or reply message
-// body.
-func parseICMPEcho(b []byte) (*icmpEcho, error) {
-	bodylen := len(b)
-	p := &icmpEcho{ID: int(b[0])<<8 | int(b[1]), Seq: int(b[2])<<8 | int(b[3])}
-	if bodylen > 4 {
-		p.Data = make([]byte, bodylen-4)
-		copy(p.Data, b[4:])
-	}
-	return p, nil
-}
diff --git a/third_party/gofrontend/libgo/go/net/mockserver_test.go b/third_party/gofrontend/libgo/go/net/mockserver_test.go
index 68ded5d..dd6f4df 100644
--- a/third_party/gofrontend/libgo/go/net/mockserver_test.go
+++ b/third_party/gofrontend/libgo/go/net/mockserver_test.go
@@ -4,11 +4,123 @@
 
 package net
 
-import "sync"
+import (
+	"errors"
+	"fmt"
+	"io/ioutil"
+	"os"
+	"sync"
+	"testing"
+	"time"
+)
+
+// testUnixAddr uses ioutil.TempFile to get a name that is unique.
+// It also uses /tmp directory in case it is prohibited to create UNIX
+// sockets in TMPDIR.
+func testUnixAddr() string {
+	f, err := ioutil.TempFile("", "go-nettest")
+	if err != nil {
+		panic(err)
+	}
+	addr := f.Name()
+	f.Close()
+	os.Remove(addr)
+	return addr
+}
+
+func newLocalListener(network string) (Listener, error) {
+	switch network {
+	case "tcp", "tcp4", "tcp6":
+		if supportsIPv4 {
+			return Listen("tcp4", "127.0.0.1:0")
+		}
+		if supportsIPv6 {
+			return Listen("tcp6", "[::1]:0")
+		}
+	case "unix", "unixpacket":
+		return Listen(network, testUnixAddr())
+	}
+	return nil, fmt.Errorf("%s is not supported", network)
+}
+
+func newDualStackListener() (lns []*TCPListener, err error) {
+	var args = []struct {
+		network string
+		TCPAddr
+	}{
+		{"tcp4", TCPAddr{IP: IPv4(127, 0, 0, 1)}},
+		{"tcp6", TCPAddr{IP: IPv6loopback}},
+	}
+	for i := 0; i < 64; i++ {
+		var port int
+		var lns []*TCPListener
+		for _, arg := range args {
+			arg.TCPAddr.Port = port
+			ln, err := ListenTCP(arg.network, &arg.TCPAddr)
+			if err != nil {
+				continue
+			}
+			port = ln.Addr().(*TCPAddr).Port
+			lns = append(lns, ln)
+		}
+		if len(lns) != len(args) {
+			for _, ln := range lns {
+				ln.Close()
+			}
+			continue
+		}
+		return lns, nil
+	}
+	return nil, errors.New("no dualstack port available")
+}
+
+type localServer struct {
+	lnmu sync.RWMutex
+	Listener
+	done chan bool // signal that indicates server stopped
+}
+
+func (ls *localServer) buildup(handler func(*localServer, Listener)) error {
+	go func() {
+		handler(ls, ls.Listener)
+		close(ls.done)
+	}()
+	return nil
+}
+
+func (ls *localServer) teardown() error {
+	ls.lnmu.Lock()
+	if ls.Listener != nil {
+		network := ls.Listener.Addr().Network()
+		address := ls.Listener.Addr().String()
+		ls.Listener.Close()
+		<-ls.done
+		ls.Listener = nil
+		switch network {
+		case "unix", "unixpacket":
+			os.Remove(address)
+		}
+	}
+	ls.lnmu.Unlock()
+	return nil
+}
+
+func newLocalServer(network string) (*localServer, error) {
+	ln, err := newLocalListener(network)
+	if err != nil {
+		return nil, err
+	}
+	return &localServer{Listener: ln, done: make(chan bool)}, nil
+}
 
 type streamListener struct {
-	net, addr string
-	ln        Listener
+	network, address string
+	Listener
+	done chan bool // signal that indicates server stopped
+}
+
+func (sl *streamListener) newLocalServer() (*localServer, error) {
+	return &localServer{Listener: sl.Listener, done: make(chan bool)}, nil
 }
 
 type dualStackServer struct {
@@ -20,9 +132,12 @@
 	cs  []Conn // established connections at the passive open side
 }
 
-func (dss *dualStackServer) buildup(server func(*dualStackServer, Listener)) error {
+func (dss *dualStackServer) buildup(handler func(*dualStackServer, Listener)) error {
 	for i := range dss.lns {
-		go server(dss, dss.lns[i].ln)
+		go func(i int) {
+			handler(dss, dss.lns[i].Listener)
+			close(dss.lns[i].done)
+		}(i)
 	}
 	return nil
 }
@@ -34,12 +149,13 @@
 	return nil
 }
 
-func (dss *dualStackServer) teardownNetwork(net string) error {
+func (dss *dualStackServer) teardownNetwork(network string) error {
 	dss.lnmu.Lock()
 	for i := range dss.lns {
-		if net == dss.lns[i].net && dss.lns[i].ln != nil {
-			dss.lns[i].ln.Close()
-			dss.lns[i].ln = nil
+		if network == dss.lns[i].network && dss.lns[i].Listener != nil {
+			dss.lns[i].Listener.Close()
+			<-dss.lns[i].done
+			dss.lns[i].Listener = nil
 		}
 	}
 	dss.lnmu.Unlock()
@@ -49,15 +165,18 @@
 func (dss *dualStackServer) teardown() error {
 	dss.lnmu.Lock()
 	for i := range dss.lns {
-		if dss.lns[i].ln != nil {
-			dss.lns[i].ln.Close()
+		if dss.lns[i].Listener != nil {
+			dss.lns[i].Listener.Close()
+			<-dss.lns[i].done
 		}
 	}
+	dss.lns = dss.lns[:0]
 	dss.lnmu.Unlock()
 	dss.cmu.Lock()
 	for _, c := range dss.cs {
 		c.Close()
 	}
+	dss.cs = dss.cs[:0]
 	dss.cmu.Unlock()
 	return nil
 }
@@ -65,18 +184,333 @@
 func newDualStackServer(lns []streamListener) (*dualStackServer, error) {
 	dss := &dualStackServer{lns: lns, port: "0"}
 	for i := range dss.lns {
-		ln, err := Listen(dss.lns[i].net, dss.lns[i].addr+":"+dss.port)
+		ln, err := Listen(dss.lns[i].network, JoinHostPort(dss.lns[i].address, dss.port))
 		if err != nil {
-			dss.teardown()
+			for _, ln := range dss.lns[:i] {
+				ln.Listener.Close()
+			}
 			return nil, err
 		}
-		dss.lns[i].ln = ln
+		dss.lns[i].Listener = ln
+		dss.lns[i].done = make(chan bool)
 		if dss.port == "0" {
 			if _, dss.port, err = SplitHostPort(ln.Addr().String()); err != nil {
-				dss.teardown()
+				for _, ln := range dss.lns {
+					ln.Listener.Close()
+				}
 				return nil, err
 			}
 		}
 	}
 	return dss, nil
 }
+
+func transponder(ln Listener, ch chan<- error) {
+	defer close(ch)
+
+	switch ln := ln.(type) {
+	case *TCPListener:
+		ln.SetDeadline(time.Now().Add(someTimeout))
+	case *UnixListener:
+		ln.SetDeadline(time.Now().Add(someTimeout))
+	}
+	c, err := ln.Accept()
+	if err != nil {
+		if perr := parseAcceptError(err); perr != nil {
+			ch <- perr
+		}
+		ch <- err
+		return
+	}
+	defer c.Close()
+
+	network := ln.Addr().Network()
+	if c.LocalAddr().Network() != network || c.LocalAddr().Network() != network {
+		ch <- fmt.Errorf("got %v->%v; expected %v->%v", c.LocalAddr().Network(), c.RemoteAddr().Network(), network, network)
+		return
+	}
+	c.SetDeadline(time.Now().Add(someTimeout))
+	c.SetReadDeadline(time.Now().Add(someTimeout))
+	c.SetWriteDeadline(time.Now().Add(someTimeout))
+
+	b := make([]byte, 256)
+	n, err := c.Read(b)
+	if err != nil {
+		if perr := parseReadError(err); perr != nil {
+			ch <- perr
+		}
+		ch <- err
+		return
+	}
+	if _, err := c.Write(b[:n]); err != nil {
+		if perr := parseWriteError(err); perr != nil {
+			ch <- perr
+		}
+		ch <- err
+		return
+	}
+}
+
+func transceiver(c Conn, wb []byte, ch chan<- error) {
+	defer close(ch)
+
+	c.SetDeadline(time.Now().Add(someTimeout))
+	c.SetReadDeadline(time.Now().Add(someTimeout))
+	c.SetWriteDeadline(time.Now().Add(someTimeout))
+
+	n, err := c.Write(wb)
+	if err != nil {
+		if perr := parseWriteError(err); perr != nil {
+			ch <- perr
+		}
+		ch <- err
+		return
+	}
+	if n != len(wb) {
+		ch <- fmt.Errorf("wrote %d; want %d", n, len(wb))
+	}
+	rb := make([]byte, len(wb))
+	n, err = c.Read(rb)
+	if err != nil {
+		if perr := parseReadError(err); perr != nil {
+			ch <- perr
+		}
+		ch <- err
+		return
+	}
+	if n != len(wb) {
+		ch <- fmt.Errorf("read %d; want %d", n, len(wb))
+	}
+}
+
+func timeoutReceiver(c Conn, d, min, max time.Duration, ch chan<- error) {
+	var err error
+	defer func() { ch <- err }()
+
+	t0 := time.Now()
+	if err = c.SetReadDeadline(time.Now().Add(d)); err != nil {
+		return
+	}
+	b := make([]byte, 256)
+	var n int
+	n, err = c.Read(b)
+	t1 := time.Now()
+	if n != 0 || err == nil || !err.(Error).Timeout() {
+		err = fmt.Errorf("Read did not return (0, timeout): (%d, %v)", n, err)
+		return
+	}
+	if dt := t1.Sub(t0); min > dt || dt > max && !testing.Short() {
+		err = fmt.Errorf("Read took %s; expected %s", dt, d)
+		return
+	}
+}
+
+func timeoutTransmitter(c Conn, d, min, max time.Duration, ch chan<- error) {
+	var err error
+	defer func() { ch <- err }()
+
+	t0 := time.Now()
+	if err = c.SetWriteDeadline(time.Now().Add(d)); err != nil {
+		return
+	}
+	var n int
+	for {
+		n, err = c.Write([]byte("TIMEOUT TRANSMITTER"))
+		if err != nil {
+			break
+		}
+	}
+	t1 := time.Now()
+	if err == nil || !err.(Error).Timeout() {
+		err = fmt.Errorf("Write did not return (any, timeout): (%d, %v)", n, err)
+		return
+	}
+	if dt := t1.Sub(t0); min > dt || dt > max && !testing.Short() {
+		err = fmt.Errorf("Write took %s; expected %s", dt, d)
+		return
+	}
+}
+
+func newLocalPacketListener(network string) (PacketConn, error) {
+	switch network {
+	case "udp", "udp4", "udp6":
+		if supportsIPv4 {
+			return ListenPacket("udp4", "127.0.0.1:0")
+		}
+		if supportsIPv6 {
+			return ListenPacket("udp6", "[::1]:0")
+		}
+	case "unixgram":
+		return ListenPacket(network, testUnixAddr())
+	}
+	return nil, fmt.Errorf("%s is not supported", network)
+}
+
+func newDualStackPacketListener() (cs []*UDPConn, err error) {
+	var args = []struct {
+		network string
+		UDPAddr
+	}{
+		{"udp4", UDPAddr{IP: IPv4(127, 0, 0, 1)}},
+		{"udp6", UDPAddr{IP: IPv6loopback}},
+	}
+	for i := 0; i < 64; i++ {
+		var port int
+		var cs []*UDPConn
+		for _, arg := range args {
+			arg.UDPAddr.Port = port
+			c, err := ListenUDP(arg.network, &arg.UDPAddr)
+			if err != nil {
+				continue
+			}
+			port = c.LocalAddr().(*UDPAddr).Port
+			cs = append(cs, c)
+		}
+		if len(cs) != len(args) {
+			for _, c := range cs {
+				c.Close()
+			}
+			continue
+		}
+		return cs, nil
+	}
+	return nil, errors.New("no dualstack port available")
+}
+
+type localPacketServer struct {
+	pcmu sync.RWMutex
+	PacketConn
+	done chan bool // signal that indicates server stopped
+}
+
+func (ls *localPacketServer) buildup(handler func(*localPacketServer, PacketConn)) error {
+	go func() {
+		handler(ls, ls.PacketConn)
+		close(ls.done)
+	}()
+	return nil
+}
+
+func (ls *localPacketServer) teardown() error {
+	ls.pcmu.Lock()
+	if ls.PacketConn != nil {
+		network := ls.PacketConn.LocalAddr().Network()
+		address := ls.PacketConn.LocalAddr().String()
+		ls.PacketConn.Close()
+		<-ls.done
+		ls.PacketConn = nil
+		switch network {
+		case "unixgram":
+			os.Remove(address)
+		}
+	}
+	ls.pcmu.Unlock()
+	return nil
+}
+
+func newLocalPacketServer(network string) (*localPacketServer, error) {
+	c, err := newLocalPacketListener(network)
+	if err != nil {
+		return nil, err
+	}
+	return &localPacketServer{PacketConn: c, done: make(chan bool)}, nil
+}
+
+type packetListener struct {
+	PacketConn
+}
+
+func (pl *packetListener) newLocalServer() (*localPacketServer, error) {
+	return &localPacketServer{PacketConn: pl.PacketConn, done: make(chan bool)}, nil
+}
+
+func packetTransponder(c PacketConn, ch chan<- error) {
+	defer close(ch)
+
+	c.SetDeadline(time.Now().Add(someTimeout))
+	c.SetReadDeadline(time.Now().Add(someTimeout))
+	c.SetWriteDeadline(time.Now().Add(someTimeout))
+
+	b := make([]byte, 256)
+	n, peer, err := c.ReadFrom(b)
+	if err != nil {
+		if perr := parseReadError(err); perr != nil {
+			ch <- perr
+		}
+		ch <- err
+		return
+	}
+	if peer == nil { // for connected-mode sockets
+		switch c.LocalAddr().Network() {
+		case "udp":
+			peer, err = ResolveUDPAddr("udp", string(b[:n]))
+		case "unixgram":
+			peer, err = ResolveUnixAddr("unixgram", string(b[:n]))
+		}
+		if err != nil {
+			ch <- err
+			return
+		}
+	}
+	if _, err := c.WriteTo(b[:n], peer); err != nil {
+		if perr := parseWriteError(err); perr != nil {
+			ch <- perr
+		}
+		ch <- err
+		return
+	}
+}
+
+func packetTransceiver(c PacketConn, wb []byte, dst Addr, ch chan<- error) {
+	defer close(ch)
+
+	c.SetDeadline(time.Now().Add(someTimeout))
+	c.SetReadDeadline(time.Now().Add(someTimeout))
+	c.SetWriteDeadline(time.Now().Add(someTimeout))
+
+	n, err := c.WriteTo(wb, dst)
+	if err != nil {
+		if perr := parseWriteError(err); perr != nil {
+			ch <- perr
+		}
+		ch <- err
+		return
+	}
+	if n != len(wb) {
+		ch <- fmt.Errorf("wrote %d; want %d", n, len(wb))
+	}
+	rb := make([]byte, len(wb))
+	n, _, err = c.ReadFrom(rb)
+	if err != nil {
+		if perr := parseReadError(err); perr != nil {
+			ch <- perr
+		}
+		ch <- err
+		return
+	}
+	if n != len(wb) {
+		ch <- fmt.Errorf("read %d; want %d", n, len(wb))
+	}
+}
+
+func timeoutPacketReceiver(c PacketConn, d, min, max time.Duration, ch chan<- error) {
+	var err error
+	defer func() { ch <- err }()
+
+	t0 := time.Now()
+	if err = c.SetReadDeadline(time.Now().Add(d)); err != nil {
+		return
+	}
+	b := make([]byte, 256)
+	var n int
+	n, _, err = c.ReadFrom(b)
+	t1 := time.Now()
+	if n != 0 || err == nil || !err.(Error).Timeout() {
+		err = fmt.Errorf("ReadFrom did not return (0, timeout): (%d, %v)", n, err)
+		return
+	}
+	if dt := t1.Sub(t0); min > dt || dt > max && !testing.Short() {
+		err = fmt.Errorf("ReadFrom took %s; expected %s", dt, d)
+		return
+	}
+}
diff --git a/third_party/gofrontend/libgo/go/net/multicast_test.go b/third_party/gofrontend/libgo/go/net/multicast_test.go
deleted file mode 100644
index 5f253f4..0000000
--- a/third_party/gofrontend/libgo/go/net/multicast_test.go
+++ /dev/null
@@ -1,188 +0,0 @@
-// Copyright 2011 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 net
-
-import (
-	"fmt"
-	"os"
-	"runtime"
-	"testing"
-)
-
-var ipv4MulticastListenerTests = []struct {
-	net   string
-	gaddr *UDPAddr // see RFC 4727
-}{
-	{"udp", &UDPAddr{IP: IPv4(224, 0, 0, 254), Port: 12345}},
-
-	{"udp4", &UDPAddr{IP: IPv4(224, 0, 0, 254), Port: 12345}},
-}
-
-// TestIPv4MulticastListener tests both single and double listen to a
-// test listener with same address family, same group address and same
-// port.
-func TestIPv4MulticastListener(t *testing.T) {
-	switch runtime.GOOS {
-	case "android", "nacl", "plan9":
-		t.Skipf("skipping test on %q", runtime.GOOS)
-	case "solaris":
-		t.Skipf("skipping test on solaris, see issue 7399")
-	}
-
-	closer := func(cs []*UDPConn) {
-		for _, c := range cs {
-			if c != nil {
-				c.Close()
-			}
-		}
-	}
-
-	for _, ifi := range []*Interface{loopbackInterface(), nil} {
-		// Note that multicast interface assignment by system
-		// is not recommended because it usually relies on
-		// routing stuff for finding out an appropriate
-		// nexthop containing both network and link layer
-		// adjacencies.
-		if ifi == nil && !*testExternal {
-			continue
-		}
-		for _, tt := range ipv4MulticastListenerTests {
-			var err error
-			cs := make([]*UDPConn, 2)
-			if cs[0], err = ListenMulticastUDP(tt.net, ifi, tt.gaddr); err != nil {
-				t.Fatalf("First ListenMulticastUDP on %v failed: %v", ifi, err)
-			}
-			if err := checkMulticastListener(cs[0], tt.gaddr.IP); err != nil {
-				closer(cs)
-				t.Fatal(err)
-			}
-			if cs[1], err = ListenMulticastUDP(tt.net, ifi, tt.gaddr); err != nil {
-				closer(cs)
-				t.Fatalf("Second ListenMulticastUDP on %v failed: %v", ifi, err)
-			}
-			if err := checkMulticastListener(cs[1], tt.gaddr.IP); err != nil {
-				closer(cs)
-				t.Fatal(err)
-			}
-			closer(cs)
-		}
-	}
-}
-
-var ipv6MulticastListenerTests = []struct {
-	net   string
-	gaddr *UDPAddr // see RFC 4727
-}{
-	{"udp", &UDPAddr{IP: ParseIP("ff01::114"), Port: 12345}},
-	{"udp", &UDPAddr{IP: ParseIP("ff02::114"), Port: 12345}},
-	{"udp", &UDPAddr{IP: ParseIP("ff04::114"), Port: 12345}},
-	{"udp", &UDPAddr{IP: ParseIP("ff05::114"), Port: 12345}},
-	{"udp", &UDPAddr{IP: ParseIP("ff08::114"), Port: 12345}},
-	{"udp", &UDPAddr{IP: ParseIP("ff0e::114"), Port: 12345}},
-
-	{"udp6", &UDPAddr{IP: ParseIP("ff01::114"), Port: 12345}},
-	{"udp6", &UDPAddr{IP: ParseIP("ff02::114"), Port: 12345}},
-	{"udp6", &UDPAddr{IP: ParseIP("ff04::114"), Port: 12345}},
-	{"udp6", &UDPAddr{IP: ParseIP("ff05::114"), Port: 12345}},
-	{"udp6", &UDPAddr{IP: ParseIP("ff08::114"), Port: 12345}},
-	{"udp6", &UDPAddr{IP: ParseIP("ff0e::114"), Port: 12345}},
-}
-
-// TestIPv6MulticastListener tests both single and double listen to a
-// test listener with same address family, same group address and same
-// port.
-func TestIPv6MulticastListener(t *testing.T) {
-	switch runtime.GOOS {
-	case "plan9":
-		t.Skipf("skipping test on %q", runtime.GOOS)
-	case "solaris":
-		t.Skipf("skipping test on solaris, see issue 7399")
-	}
-	if !supportsIPv6 {
-		t.Skip("ipv6 is not supported")
-	}
-	if os.Getuid() != 0 {
-		t.Skip("skipping test; must be root")
-	}
-
-	closer := func(cs []*UDPConn) {
-		for _, c := range cs {
-			if c != nil {
-				c.Close()
-			}
-		}
-	}
-
-	for _, ifi := range []*Interface{loopbackInterface(), nil} {
-		// Note that multicast interface assignment by system
-		// is not recommended because it usually relies on
-		// routing stuff for finding out an appropriate
-		// nexthop containing both network and link layer
-		// adjacencies.
-		if ifi == nil && (!*testExternal || !*testIPv6) {
-			continue
-		}
-		for _, tt := range ipv6MulticastListenerTests {
-			var err error
-			cs := make([]*UDPConn, 2)
-			if cs[0], err = ListenMulticastUDP(tt.net, ifi, tt.gaddr); err != nil {
-				t.Fatalf("First ListenMulticastUDP on %v failed: %v", ifi, err)
-			}
-			if err := checkMulticastListener(cs[0], tt.gaddr.IP); err != nil {
-				closer(cs)
-				t.Fatal(err)
-			}
-			if cs[1], err = ListenMulticastUDP(tt.net, ifi, tt.gaddr); err != nil {
-				closer(cs)
-				t.Fatalf("Second ListenMulticastUDP on %v failed: %v", ifi, err)
-			}
-			if err := checkMulticastListener(cs[1], tt.gaddr.IP); err != nil {
-				closer(cs)
-				t.Fatal(err)
-			}
-			closer(cs)
-		}
-	}
-}
-
-func checkMulticastListener(c *UDPConn, ip IP) error {
-	if ok, err := multicastRIBContains(ip); err != nil {
-		return err
-	} else if !ok {
-		return fmt.Errorf("%q not found in multicast RIB", ip.String())
-	}
-	la := c.LocalAddr()
-	if la, ok := la.(*UDPAddr); !ok || la.Port == 0 {
-		return fmt.Errorf("got %v; expected a proper address with non-zero port number", la)
-	}
-	return nil
-}
-
-func multicastRIBContains(ip IP) (bool, error) {
-	switch runtime.GOOS {
-	case "dragonfly", "netbsd", "openbsd", "plan9", "solaris", "windows":
-		return true, nil // not implemented yet
-	case "linux":
-		if runtime.GOARCH == "arm" || runtime.GOARCH == "alpha" {
-			return true, nil // not implemented yet
-		}
-	}
-	ift, err := Interfaces()
-	if err != nil {
-		return false, err
-	}
-	for _, ifi := range ift {
-		ifmat, err := ifi.MulticastAddrs()
-		if err != nil {
-			return false, err
-		}
-		for _, ifma := range ifmat {
-			if ifma.(*IPAddr).IP.Equal(ip) {
-				return true, nil
-			}
-		}
-	}
-	return false, nil
-}
diff --git a/third_party/gofrontend/libgo/go/net/net.go b/third_party/gofrontend/libgo/go/net/net.go
index cb31af5..6e84c3a 100644
--- a/third_party/gofrontend/libgo/go/net/net.go
+++ b/third_party/gofrontend/libgo/go/net/net.go
@@ -35,12 +35,49 @@
 		}
 		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
 
-// TODO(rsc):
-//	support for raw ethernet sockets
-
 import (
 	"errors"
 	"io"
@@ -49,6 +86,20 @@
 	"time"
 )
 
+// netGo and netCgo contain the state of the build tags used
+// to build this binary, and whether cgo is available.
+// conf.go mirrors these into conf for easier testing.
+var (
+	netGo  bool // set true in cgo_stub.go for build tag "netgo" (or no cgo)
+	netCgo bool // set true in conf_netcgo.go for build tag "netcgo"
+)
+
+func init() {
+	sysInit()
+	supportsIPv4 = probeIPv4Stack()
+	supportsIPv6, supportsIPv4map = probeIPv6Stack()
+}
+
 // Addr represents a network end point address.
 type Addr interface {
 	Network() string // name of the network
@@ -118,7 +169,11 @@
 	if !c.ok() {
 		return 0, syscall.EINVAL
 	}
-	return c.fd.Read(b)
+	n, err := c.fd.Read(b)
+	if err != nil && err != io.EOF {
+		err = &OpError{Op: "read", Net: c.fd.net, Source: c.fd.laddr, Addr: c.fd.raddr, Err: err}
+	}
+	return n, err
 }
 
 // Write implements the Conn Write method.
@@ -126,7 +181,11 @@
 	if !c.ok() {
 		return 0, syscall.EINVAL
 	}
-	return c.fd.Write(b)
+	n, err := c.fd.Write(b)
+	if err != nil {
+		err = &OpError{Op: "write", Net: c.fd.net, Source: c.fd.laddr, Addr: c.fd.raddr, Err: err}
+	}
+	return n, err
 }
 
 // Close closes the connection.
@@ -134,10 +193,16 @@
 	if !c.ok() {
 		return syscall.EINVAL
 	}
-	return c.fd.Close()
+	err := c.fd.Close()
+	if err != nil {
+		err = &OpError{Op: "close", Net: c.fd.net, Source: c.fd.laddr, Addr: c.fd.raddr, Err: err}
+	}
+	return err
 }
 
 // LocalAddr returns the local network address.
+// The Addr returned is shared by all invocations of LocalAddr, so
+// do not modify it.
 func (c *conn) LocalAddr() Addr {
 	if !c.ok() {
 		return nil
@@ -146,6 +211,8 @@
 }
 
 // RemoteAddr returns the remote network address.
+// The Addr returned is shared by all invocations of RemoteAddr, so
+// do not modify it.
 func (c *conn) RemoteAddr() Addr {
 	if !c.ok() {
 		return nil
@@ -158,7 +225,10 @@
 	if !c.ok() {
 		return syscall.EINVAL
 	}
-	return c.fd.setDeadline(t)
+	if err := c.fd.setDeadline(t); err != nil {
+		return &OpError{Op: "set", Net: c.fd.net, Source: nil, Addr: c.fd.laddr, Err: err}
+	}
+	return nil
 }
 
 // SetReadDeadline implements the Conn SetReadDeadline method.
@@ -166,7 +236,10 @@
 	if !c.ok() {
 		return syscall.EINVAL
 	}
-	return c.fd.setReadDeadline(t)
+	if err := c.fd.setReadDeadline(t); err != nil {
+		return &OpError{Op: "set", Net: c.fd.net, Source: nil, Addr: c.fd.laddr, Err: err}
+	}
+	return nil
 }
 
 // SetWriteDeadline implements the Conn SetWriteDeadline method.
@@ -174,7 +247,10 @@
 	if !c.ok() {
 		return syscall.EINVAL
 	}
-	return c.fd.setWriteDeadline(t)
+	if err := c.fd.setWriteDeadline(t); err != nil {
+		return &OpError{Op: "set", Net: c.fd.net, Source: nil, Addr: c.fd.laddr, Err: err}
+	}
+	return nil
 }
 
 // SetReadBuffer sets the size of the operating system's
@@ -183,7 +259,10 @@
 	if !c.ok() {
 		return syscall.EINVAL
 	}
-	return setReadBuffer(c.fd, bytes)
+	if err := setReadBuffer(c.fd, bytes); err != nil {
+		return &OpError{Op: "set", Net: c.fd.net, Source: nil, Addr: c.fd.laddr, Err: err}
+	}
+	return nil
 }
 
 // SetWriteBuffer sets the size of the operating system's
@@ -192,7 +271,10 @@
 	if !c.ok() {
 		return syscall.EINVAL
 	}
-	return setWriteBuffer(c.fd, bytes)
+	if err := setWriteBuffer(c.fd, bytes); err != nil {
+		return &OpError{Op: "set", Net: c.fd.net, Source: nil, Addr: c.fd.laddr, Err: err}
+	}
+	return nil
 }
 
 // File sets the underlying os.File to blocking mode and returns a copy.
@@ -202,13 +284,12 @@
 // The returned os.File's file descriptor is different from the connection's.
 // Attempting to change properties of the original using this duplicate
 // may or may not have the desired effect.
-func (c *conn) File() (f *os.File, err error) { return c.fd.dup() }
-
-// An Error represents a network error.
-type Error interface {
-	error
-	Timeout() bool   // Is the error a timeout?
-	Temporary() bool // Is the error temporary?
+func (c *conn) File() (f *os.File, err error) {
+	f, err = c.fd.dup()
+	if err != nil {
+		err = &OpError{Op: "file", Net: c.fd.net, Source: c.fd.laddr, Addr: c.fd.raddr, Err: err}
+	}
+	return
 }
 
 // PacketConn is a generic packet-oriented network connection.
@@ -274,6 +355,13 @@
 	Addr() Addr
 }
 
+// An Error represents a network error.
+type Error interface {
+	error
+	Timeout() bool   // Is the error a timeout?
+	Temporary() bool // Is the error temporary?
+}
+
 // Various errors contained in OpError.
 var (
 	// For connection setup and write operations.
@@ -281,6 +369,7 @@
 
 	// For both read and write operations.
 	errTimeout          error = &timeoutError{}
+	errCanceled               = errors.New("operation was canceled")
 	errClosing                = errors.New("use of closed network connection")
 	ErrWriteToConnected       = errors.New("use of WriteTo with pre-connected connection")
 )
@@ -297,7 +386,17 @@
 	// such as "tcp" or "udp6".
 	Net string
 
-	// Addr is the network address on which this error occurred.
+	// For operations involving a remote network connection, like
+	// Dial, Read, or Write, Source is the corresponding local
+	// network address.
+	Source Addr
+
+	// Addr is the network address for which this error occurred.
+	// For local operations, like Listen or SetDeadline, Addr is
+	// the address of the local endpoint being manipulated.
+	// For operations involving a remote network connection, like
+	// Dial, Read, or Write, Addr is the remote address of that
+	// connection.
 	Addr Addr
 
 	// Err is the error that occurred during the operation.
@@ -312,22 +411,21 @@
 	if e.Net != "" {
 		s += " " + e.Net
 	}
+	if e.Source != nil {
+		s += " " + e.Source.String()
+	}
 	if e.Addr != nil {
-		s += " " + e.Addr.String()
+		if e.Source != nil {
+			s += "->"
+		} else {
+			s += " "
+		}
+		s += e.Addr.String()
 	}
 	s += ": " + e.Err.Error()
 	return s
 }
 
-type temporary interface {
-	Temporary() bool
-}
-
-func (e *OpError) Temporary() bool {
-	t, ok := e.Err.(temporary)
-	return ok && t.Temporary()
-}
-
 var noDeadline = time.Time{}
 
 type timeout interface {
@@ -335,16 +433,45 @@
 }
 
 func (e *OpError) Timeout() bool {
+	if ne, ok := e.Err.(*os.SyscallError); ok {
+		t, ok := ne.Err.(timeout)
+		return ok && t.Timeout()
+	}
 	t, ok := e.Err.(timeout)
 	return ok && t.Timeout()
 }
 
+type temporary interface {
+	Temporary() bool
+}
+
+func (e *OpError) Temporary() bool {
+	if ne, ok := e.Err.(*os.SyscallError); ok {
+		t, ok := ne.Err.(temporary)
+		return ok && t.Temporary()
+	}
+	t, ok := e.Err.(temporary)
+	return ok && t.Temporary()
+}
+
 type timeoutError struct{}
 
 func (e *timeoutError) Error() string   { return "i/o timeout" }
 func (e *timeoutError) Timeout() bool   { return true }
 func (e *timeoutError) Temporary() bool { return true }
 
+// A ParseError is the error type of literal network address parsers.
+type ParseError struct {
+	// Type is the type of string that was expected, such as
+	// "IP address", "CIDR address".
+	Type string
+
+	// Text is the malformed text string.
+	Text string
+}
+
+func (e *ParseError) Error() string { return "invalid " + e.Type + ": " + e.Text }
+
 type AddrError struct {
 	Err  string
 	Addr string
@@ -361,19 +488,14 @@
 	return s
 }
 
-func (e *AddrError) Temporary() bool {
-	return false
-}
-
-func (e *AddrError) Timeout() bool {
-	return false
-}
+func (e *AddrError) Timeout() bool   { return false }
+func (e *AddrError) Temporary() bool { return false }
 
 type UnknownNetworkError string
 
 func (e UnknownNetworkError) Error() string   { return "unknown network " + string(e) }
-func (e UnknownNetworkError) Temporary() bool { return false }
 func (e UnknownNetworkError) Timeout() bool   { return false }
+func (e UnknownNetworkError) Temporary() bool { return false }
 
 type InvalidAddrError string
 
@@ -382,17 +504,50 @@
 func (e InvalidAddrError) Temporary() bool { return false }
 
 // DNSConfigError represents an error reading the machine's DNS configuration.
+// (No longer used; kept for compatibility.)
 type DNSConfigError struct {
 	Err error
 }
 
-func (e *DNSConfigError) Error() string {
-	return "error reading DNS config: " + e.Err.Error()
-}
-
+func (e *DNSConfigError) Error() string   { return "error reading DNS config: " + e.Err.Error() }
 func (e *DNSConfigError) Timeout() bool   { return false }
 func (e *DNSConfigError) Temporary() bool { return false }
 
+// Various errors contained in DNSError.
+var (
+	errNoSuchHost = errors.New("no such host")
+)
+
+// DNSError represents a DNS lookup error.
+type DNSError struct {
+	Err       string // description of the error
+	Name      string // name looked for
+	Server    string // server used
+	IsTimeout bool   // if true, timed out; not all timeouts set this
+}
+
+func (e *DNSError) Error() string {
+	if e == nil {
+		return "<nil>"
+	}
+	s := "lookup " + e.Name
+	if e.Server != "" {
+		s += " on " + e.Server
+	}
+	s += ": " + e.Err
+	return s
+}
+
+// Timeout reports whether the DNS lookup is known to have timed out.
+// This is not always known; a DNS lookup may fail due to a timeout
+// and return a DNSError for which Timeout returns false.
+func (e *DNSError) Timeout() bool { return e.IsTimeout }
+
+// Temporary reports whether the DNS error is known to be temporary.
+// This is not always known; a DNS lookup may fail due to a temporary
+// error and return a DNSError for which Temporary returns false.
+func (e *DNSError) Temporary() bool { return e.IsTimeout }
+
 type writerOnly struct {
 	io.Writer
 }
@@ -412,10 +567,6 @@
 
 var threadLimit = make(chan struct{}, 500)
 
-// Using send for acquire is fine here because we are not using this
-// to protect any memory. All we care about is the number of goroutines
-// making calls at a time.
-
 func acquireThread() {
 	threadLimit <- struct{}{}
 }
diff --git a/third_party/gofrontend/libgo/go/net/net_test.go b/third_party/gofrontend/libgo/go/net/net_test.go
index bfed4d6..3907ce4 100644
--- a/third_party/gofrontend/libgo/go/net/net_test.go
+++ b/third_party/gofrontend/libgo/go/net/net_test.go
@@ -6,258 +6,251 @@
 
 import (
 	"io"
-	"io/ioutil"
 	"os"
 	"runtime"
 	"testing"
-	"time"
 )
 
-func TestShutdown(t *testing.T) {
-	if runtime.GOOS == "plan9" {
-		t.Skipf("skipping test on %q", runtime.GOOS)
-	}
-	ln, err := Listen("tcp", "127.0.0.1:0")
-	if err != nil {
-		if ln, err = Listen("tcp6", "[::1]:0"); err != nil {
-			t.Fatalf("ListenTCP on :0: %v", err)
-		}
-	}
-
-	go func() {
-		defer ln.Close()
-		c, err := ln.Accept()
-		if err != nil {
-			t.Errorf("Accept: %v", err)
-			return
-		}
-		var buf [10]byte
-		n, err := c.Read(buf[:])
-		if n != 0 || err != io.EOF {
-			t.Errorf("server Read = %d, %v; want 0, io.EOF", n, err)
-			return
-		}
-		c.Write([]byte("response"))
-		c.Close()
-	}()
-
-	c, err := Dial("tcp", ln.Addr().String())
-	if err != nil {
-		t.Fatalf("Dial: %v", err)
-	}
-	defer c.Close()
-
-	err = c.(*TCPConn).CloseWrite()
-	if err != nil {
-		t.Fatalf("CloseWrite: %v", err)
-	}
-	var buf [10]byte
-	n, err := c.Read(buf[:])
-	if err != nil {
-		t.Fatalf("client Read: %d, %v", n, err)
-	}
-	got := string(buf[:n])
-	if got != "response" {
-		t.Errorf("read = %q, want \"response\"", got)
-	}
-}
-
-func TestShutdownUnix(t *testing.T) {
+func TestCloseRead(t *testing.T) {
 	switch runtime.GOOS {
-	case "nacl", "plan9", "windows":
-		t.Skipf("skipping test on %q", runtime.GOOS)
+	case "nacl", "plan9":
+		t.Skipf("not supported on %s", runtime.GOOS)
 	}
-	f, err := ioutil.TempFile("", "go_net_unixtest")
-	if err != nil {
-		t.Fatalf("TempFile: %s", err)
-	}
-	f.Close()
-	tmpname := f.Name()
-	os.Remove(tmpname)
-	ln, err := Listen("unix", tmpname)
-	if err != nil {
-		t.Fatalf("ListenUnix on %s: %s", tmpname, err)
-	}
-	defer func() {
-		ln.Close()
-		os.Remove(tmpname)
-	}()
 
-	go func() {
-		c, err := ln.Accept()
+	for _, network := range []string{"tcp", "unix", "unixpacket"} {
+		if !testableNetwork(network) {
+			t.Logf("skipping %s test", network)
+			continue
+		}
+
+		ln, err := newLocalListener(network)
 		if err != nil {
-			t.Errorf("Accept: %v", err)
-			return
+			t.Fatal(err)
 		}
-		var buf [10]byte
-		n, err := c.Read(buf[:])
-		if n != 0 || err != io.EOF {
-			t.Errorf("server Read = %d, %v; want 0, io.EOF", n, err)
-			return
+		switch network {
+		case "unix", "unixpacket":
+			defer os.Remove(ln.Addr().String())
 		}
-		c.Write([]byte("response"))
-		c.Close()
-	}()
+		defer ln.Close()
 
-	c, err := Dial("unix", tmpname)
-	if err != nil {
-		t.Fatalf("Dial: %v", err)
-	}
-	defer c.Close()
+		c, err := Dial(ln.Addr().Network(), ln.Addr().String())
+		if err != nil {
+			t.Fatal(err)
+		}
+		switch network {
+		case "unix", "unixpacket":
+			defer os.Remove(c.LocalAddr().String())
+		}
+		defer c.Close()
 
-	err = c.(*UnixConn).CloseWrite()
-	if err != nil {
-		t.Fatalf("CloseWrite: %v", err)
-	}
-	var buf [10]byte
-	n, err := c.Read(buf[:])
-	if err != nil {
-		t.Fatalf("client Read: %d, %v", n, err)
-	}
-	got := string(buf[:n])
-	if got != "response" {
-		t.Errorf("read = %q, want \"response\"", got)
+		switch c := c.(type) {
+		case *TCPConn:
+			err = c.CloseRead()
+		case *UnixConn:
+			err = c.CloseRead()
+		}
+		if err != nil {
+			if perr := parseCloseError(err); perr != nil {
+				t.Error(perr)
+			}
+			t.Fatal(err)
+		}
+		var b [1]byte
+		n, err := c.Read(b[:])
+		if n != 0 || err == nil {
+			t.Fatalf("got (%d, %v); want (0, error)", n, err)
+		}
 	}
 }
 
-func TestTCPListenClose(t *testing.T) {
-	ln, err := Listen("tcp", "127.0.0.1:0")
-	if err != nil {
-		t.Fatalf("Listen failed: %v", err)
+func TestCloseWrite(t *testing.T) {
+	switch runtime.GOOS {
+	case "nacl", "plan9":
+		t.Skipf("not supported on %s", runtime.GOOS)
 	}
 
-	done := make(chan bool, 1)
-	go func() {
-		time.Sleep(100 * time.Millisecond)
-		ln.Close()
-	}()
-	go func() {
+	handler := func(ls *localServer, ln Listener) {
+		c, err := ln.Accept()
+		if err != nil {
+			t.Error(err)
+			return
+		}
+		defer c.Close()
+
+		var b [1]byte
+		n, err := c.Read(b[:])
+		if n != 0 || err != io.EOF {
+			t.Errorf("got (%d, %v); want (0, io.EOF)", n, err)
+			return
+		}
+		switch c := c.(type) {
+		case *TCPConn:
+			err = c.CloseWrite()
+		case *UnixConn:
+			err = c.CloseWrite()
+		}
+		if err != nil {
+			if perr := parseCloseError(err); perr != nil {
+				t.Error(perr)
+			}
+			t.Error(err)
+			return
+		}
+		n, err = c.Write(b[:])
+		if err == nil {
+			t.Errorf("got (%d, %v); want (any, error)", n, err)
+			return
+		}
+	}
+
+	for _, network := range []string{"tcp", "unix", "unixpacket"} {
+		if !testableNetwork(network) {
+			t.Logf("skipping %s test", network)
+			continue
+		}
+
+		ls, err := newLocalServer(network)
+		if err != nil {
+			t.Fatal(err)
+		}
+		defer ls.teardown()
+		if err := ls.buildup(handler); err != nil {
+			t.Fatal(err)
+		}
+
+		c, err := Dial(ls.Listener.Addr().Network(), ls.Listener.Addr().String())
+		if err != nil {
+			t.Fatal(err)
+		}
+		switch network {
+		case "unix", "unixpacket":
+			defer os.Remove(c.LocalAddr().String())
+		}
+		defer c.Close()
+
+		switch c := c.(type) {
+		case *TCPConn:
+			err = c.CloseWrite()
+		case *UnixConn:
+			err = c.CloseWrite()
+		}
+		if err != nil {
+			if perr := parseCloseError(err); perr != nil {
+				t.Error(perr)
+			}
+			t.Fatal(err)
+		}
+		var b [1]byte
+		n, err := c.Read(b[:])
+		if n != 0 || err != io.EOF {
+			t.Fatalf("got (%d, %v); want (0, io.EOF)", n, err)
+		}
+		n, err = c.Write(b[:])
+		if err == nil {
+			t.Fatalf("got (%d, %v); want (any, error)", n, err)
+		}
+	}
+}
+
+func TestConnClose(t *testing.T) {
+	for _, network := range []string{"tcp", "unix", "unixpacket"} {
+		if !testableNetwork(network) {
+			t.Logf("skipping %s test", network)
+			continue
+		}
+
+		ln, err := newLocalListener(network)
+		if err != nil {
+			t.Fatal(err)
+		}
+		switch network {
+		case "unix", "unixpacket":
+			defer os.Remove(ln.Addr().String())
+		}
+		defer ln.Close()
+
+		c, err := Dial(ln.Addr().Network(), ln.Addr().String())
+		if err != nil {
+			t.Fatal(err)
+		}
+		switch network {
+		case "unix", "unixpacket":
+			defer os.Remove(c.LocalAddr().String())
+		}
+		defer c.Close()
+
+		if err := c.Close(); err != nil {
+			if perr := parseCloseError(err); perr != nil {
+				t.Error(perr)
+			}
+			t.Fatal(err)
+		}
+		var b [1]byte
+		n, err := c.Read(b[:])
+		if n != 0 || err == nil {
+			t.Fatalf("got (%d, %v); want (0, error)", n, err)
+		}
+	}
+}
+
+func TestListenerClose(t *testing.T) {
+	for _, network := range []string{"tcp", "unix", "unixpacket"} {
+		if !testableNetwork(network) {
+			t.Logf("skipping %s test", network)
+			continue
+		}
+
+		ln, err := newLocalListener(network)
+		if err != nil {
+			t.Fatal(err)
+		}
+		switch network {
+		case "unix", "unixpacket":
+			defer os.Remove(ln.Addr().String())
+		}
+		defer ln.Close()
+
+		if err := ln.Close(); err != nil {
+			if perr := parseCloseError(err); perr != nil {
+				t.Error(perr)
+			}
+			t.Fatal(err)
+		}
 		c, err := ln.Accept()
 		if err == nil {
 			c.Close()
-			t.Error("Accept succeeded")
-		} else {
-			t.Logf("Accept timeout error: %s (any error is fine)", err)
+			t.Fatal("should fail")
 		}
-		done <- true
-	}()
-	select {
-	case <-done:
-	case <-time.After(2 * time.Second):
-		t.Fatal("timeout waiting for TCP close")
 	}
 }
 
-func TestUDPListenClose(t *testing.T) {
-	switch runtime.GOOS {
-	case "plan9":
-		t.Skipf("skipping test on %q", runtime.GOOS)
-	}
-	ln, err := ListenPacket("udp", "127.0.0.1:0")
-	if err != nil {
-		t.Fatalf("Listen failed: %v", err)
-	}
-
-	buf := make([]byte, 1000)
-	done := make(chan bool, 1)
-	go func() {
-		time.Sleep(100 * time.Millisecond)
-		ln.Close()
-	}()
-	go func() {
-		_, _, err = ln.ReadFrom(buf)
-		if err == nil {
-			t.Error("ReadFrom succeeded")
-		} else {
-			t.Logf("ReadFrom timeout error: %s (any error is fine)", err)
+func TestPacketConnClose(t *testing.T) {
+	for _, network := range []string{"udp", "unixgram"} {
+		if !testableNetwork(network) {
+			t.Logf("skipping %s test", network)
+			continue
 		}
-		done <- true
-	}()
-	select {
-	case <-done:
-	case <-time.After(2 * time.Second):
-		t.Fatal("timeout waiting for UDP close")
-	}
-}
 
-func TestTCPClose(t *testing.T) {
-	switch runtime.GOOS {
-	case "plan9":
-		t.Skipf("skipping test on %q", runtime.GOOS)
-	}
-	l, err := Listen("tcp", "127.0.0.1:0")
-	if err != nil {
-		t.Fatal(err)
-	}
-	defer l.Close()
-
-	read := func(r io.Reader) error {
-		var m [1]byte
-		_, err := r.Read(m[:])
-		return err
-	}
-
-	go func() {
-		c, err := Dial("tcp", l.Addr().String())
+		c, err := newLocalPacketListener(network)
 		if err != nil {
-			t.Errorf("Dial: %v", err)
-			return
+			t.Fatal(err)
 		}
+		switch network {
+		case "unixgram":
+			defer os.Remove(c.LocalAddr().String())
+		}
+		defer c.Close()
 
-		go read(c)
-
-		time.Sleep(10 * time.Millisecond)
-		c.Close()
-	}()
-
-	c, err := l.Accept()
-	if err != nil {
-		t.Fatal(err)
-	}
-	defer c.Close()
-
-	for err == nil {
-		err = read(c)
-	}
-	if err != nil && err != io.EOF {
-		t.Fatal(err)
-	}
-}
-
-func TestErrorNil(t *testing.T) {
-	c, err := Dial("tcp", "127.0.0.1:65535")
-	if err == nil {
-		t.Fatal("Dial 127.0.0.1:65535 succeeded")
-	}
-	if c != nil {
-		t.Fatalf("Dial returned non-nil interface %T(%v) with err != nil", c, c)
-	}
-
-	// Make Listen fail by relistening on the same address.
-	l, err := Listen("tcp", "127.0.0.1:0")
-	if err != nil {
-		t.Fatalf("Listen 127.0.0.1:0: %v", err)
-	}
-	defer l.Close()
-	l1, err := Listen("tcp", l.Addr().String())
-	if err == nil {
-		t.Fatalf("second Listen %v: %v", l.Addr(), err)
-	}
-	if l1 != nil {
-		t.Fatalf("Listen returned non-nil interface %T(%v) with err != nil", l1, l1)
-	}
-
-	// Make ListenPacket fail by relistening on the same address.
-	lp, err := ListenPacket("udp", "127.0.0.1:0")
-	if err != nil {
-		t.Fatalf("Listen 127.0.0.1:0: %v", err)
-	}
-	defer lp.Close()
-	lp1, err := ListenPacket("udp", lp.LocalAddr().String())
-	if err == nil {
-		t.Fatalf("second Listen %v: %v", lp.LocalAddr(), err)
-	}
-	if lp1 != nil {
-		t.Fatalf("ListenPacket returned non-nil interface %T(%v) with err != nil", lp1, lp1)
+		if err := c.Close(); err != nil {
+			if perr := parseCloseError(err); perr != nil {
+				t.Error(perr)
+			}
+			t.Fatal(err)
+		}
+		var b [1]byte
+		n, _, err := c.ReadFrom(b[:])
+		if n != 0 || err == nil {
+			t.Fatalf("got (%d, %v); want (0, error)", n, err)
+		}
 	}
 }
diff --git a/third_party/gofrontend/libgo/go/net/non_unix_test.go b/third_party/gofrontend/libgo/go/net/non_unix_test.go
new file mode 100644
index 0000000..eddca56
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/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/third_party/gofrontend/libgo/go/net/nss.go b/third_party/gofrontend/libgo/go/net/nss.go
new file mode 100644
index 0000000..08c3e6a
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/net/nss.go
@@ -0,0 +1,159 @@
+// 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 darwin dragonfly freebsd linux netbsd openbsd solaris
+
+package net
+
+import (
+	"errors"
+	"io"
+	"os"
+)
+
+// nssConf represents the state of the machine's /etc/nsswitch.conf file.
+type nssConf struct {
+	err     error                  // any error encountered opening or parsing the file
+	sources map[string][]nssSource // keyed by database (e.g. "hosts")
+}
+
+type nssSource struct {
+	source   string // e.g. "compat", "files", "mdns4_minimal"
+	criteria []nssCriterion
+}
+
+// standardCriteria reports all specified criteria have the default
+// status actions.
+func (s nssSource) standardCriteria() bool {
+	for i, crit := range s.criteria {
+		if !crit.standardStatusAction(i == len(s.criteria)-1) {
+			return false
+		}
+	}
+	return true
+}
+
+// nssCriterion is the parsed structure of one of the criteria in brackets
+// after an NSS source name.
+type nssCriterion struct {
+	negate bool   // if "!" was present
+	status string // e.g. "success", "unavail" (lowercase)
+	action string // e.g. "return", "continue" (lowercase)
+}
+
+// standardStatusAction reports whether c is equivalent to not
+// specifying the criterion at all. last is whether this criteria is the
+// last in the list.
+func (c nssCriterion) standardStatusAction(last bool) bool {
+	if c.negate {
+		return false
+	}
+	var def string
+	switch c.status {
+	case "success":
+		def = "return"
+	case "notfound", "unavail", "tryagain":
+		def = "continue"
+	default:
+		// Unknown status
+		return false
+	}
+	if last && c.action == "return" {
+		return true
+	}
+	return c.action == def
+}
+
+func parseNSSConfFile(file string) *nssConf {
+	f, err := os.Open(file)
+	if err != nil {
+		return &nssConf{err: err}
+	}
+	defer f.Close()
+	return parseNSSConf(f)
+}
+
+func parseNSSConf(r io.Reader) *nssConf {
+	slurp, err := readFull(r)
+	if err != nil {
+		return &nssConf{err: err}
+	}
+	conf := new(nssConf)
+	conf.err = foreachLine(slurp, func(line []byte) error {
+		line = trimSpace(removeComment(line))
+		if len(line) == 0 {
+			return nil
+		}
+		colon := bytesIndexByte(line, ':')
+		if colon == -1 {
+			return errors.New("no colon on line")
+		}
+		db := string(trimSpace(line[:colon]))
+		srcs := line[colon+1:]
+		for {
+			srcs = trimSpace(srcs)
+			if len(srcs) == 0 {
+				break
+			}
+			sp := bytesIndexByte(srcs, ' ')
+			var src string
+			if sp == -1 {
+				src = string(srcs)
+				srcs = nil // done
+			} else {
+				src = string(srcs[:sp])
+				srcs = trimSpace(srcs[sp+1:])
+			}
+			var criteria []nssCriterion
+			// See if there's a criteria block in brackets.
+			if len(srcs) > 0 && srcs[0] == '[' {
+				bclose := bytesIndexByte(srcs, ']')
+				if bclose == -1 {
+					return errors.New("unclosed criterion bracket")
+				}
+				var err error
+				criteria, err = parseCriteria(srcs[1:bclose])
+				if err != nil {
+					return errors.New("invalid criteria: " + string(srcs[1:bclose]))
+				}
+				srcs = srcs[bclose+1:]
+			}
+			if conf.sources == nil {
+				conf.sources = make(map[string][]nssSource)
+			}
+			conf.sources[db] = append(conf.sources[db], nssSource{
+				source:   src,
+				criteria: criteria,
+			})
+		}
+		return nil
+	})
+	return conf
+}
+
+// parses "foo=bar !foo=bar"
+func parseCriteria(x []byte) (c []nssCriterion, err error) {
+	err = foreachField(x, func(f []byte) error {
+		not := false
+		if len(f) > 0 && f[0] == '!' {
+			not = true
+			f = f[1:]
+		}
+		if len(f) < 3 {
+			return errors.New("criterion too short")
+		}
+		eq := bytesIndexByte(f, '=')
+		if eq == -1 {
+			return errors.New("criterion lacks equal sign")
+		}
+		lowerASCIIBytes(f)
+		c = append(c, nssCriterion{
+			negate: not,
+			status: string(f[:eq]),
+			action: string(f[eq+1:]),
+		})
+		return nil
+	})
+	return
+}
diff --git a/third_party/gofrontend/libgo/go/net/nss_test.go b/third_party/gofrontend/libgo/go/net/nss_test.go
new file mode 100644
index 0000000..371deb5
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/net/nss_test.go
@@ -0,0 +1,169 @@
+// 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 darwin dragonfly freebsd linux netbsd openbsd solaris
+
+package net
+
+import (
+	"reflect"
+	"strings"
+	"testing"
+)
+
+const ubuntuTrustyAvahi = `# /etc/nsswitch.conf
+#
+# Example configuration of GNU Name Service Switch functionality.
+# If you have the libc-doc-reference' and nfo' packages installed, try:
+# nfo libc "Name Service Switch"' for information about this file.
+
+passwd:         compat
+group:          compat
+shadow:         compat
+
+hosts:          files mdns4_minimal [NOTFOUND=return] dns mdns4
+networks:       files
+
+protocols:      db files
+services:       db files
+ethers:         db files
+rpc:            db files
+
+netgroup:       nis
+`
+
+func TestParseNSSConf(t *testing.T) {
+	tests := []struct {
+		name string
+		in   string
+		want *nssConf
+	}{
+		{
+			name: "no_newline",
+			in:   "foo: a b",
+			want: &nssConf{
+				sources: map[string][]nssSource{
+					"foo": {{source: "a"}, {source: "b"}},
+				},
+			},
+		},
+		{
+			name: "newline",
+			in:   "foo: a b\n",
+			want: &nssConf{
+				sources: map[string][]nssSource{
+					"foo": {{source: "a"}, {source: "b"}},
+				},
+			},
+		},
+		{
+			name: "whitespace",
+			in:   "   foo:a    b    \n",
+			want: &nssConf{
+				sources: map[string][]nssSource{
+					"foo": {{source: "a"}, {source: "b"}},
+				},
+			},
+		},
+		{
+			name: "comment1",
+			in:   "   foo:a    b#c\n",
+			want: &nssConf{
+				sources: map[string][]nssSource{
+					"foo": {{source: "a"}, {source: "b"}},
+				},
+			},
+		},
+		{
+			name: "comment2",
+			in:   "   foo:a    b #c \n",
+			want: &nssConf{
+				sources: map[string][]nssSource{
+					"foo": {{source: "a"}, {source: "b"}},
+				},
+			},
+		},
+		{
+			name: "crit",
+			in:   "   foo:a    b [!a=b    X=Y ] c#d \n",
+			want: &nssConf{
+				sources: map[string][]nssSource{
+					"foo": {
+						{source: "a"},
+						{
+							source: "b",
+							criteria: []nssCriterion{
+								{
+									negate: true,
+									status: "a",
+									action: "b",
+								},
+								{
+									status: "x",
+									action: "y",
+								},
+							},
+						},
+						{source: "c"},
+					},
+				},
+			},
+		},
+
+		// Ubuntu Trusty w/ avahi-daemon, libavahi-* etc installed.
+		{
+			name: "ubuntu_trusty_avahi",
+			in:   ubuntuTrustyAvahi,
+			want: &nssConf{
+				sources: map[string][]nssSource{
+					"passwd": {{source: "compat"}},
+					"group":  {{source: "compat"}},
+					"shadow": {{source: "compat"}},
+					"hosts": {
+						{source: "files"},
+						{
+							source: "mdns4_minimal",
+							criteria: []nssCriterion{
+								{
+									negate: false,
+									status: "notfound",
+									action: "return",
+								},
+							},
+						},
+						{source: "dns"},
+						{source: "mdns4"},
+					},
+					"networks": {{source: "files"}},
+					"protocols": {
+						{source: "db"},
+						{source: "files"},
+					},
+					"services": {
+						{source: "db"},
+						{source: "files"},
+					},
+					"ethers": {
+						{source: "db"},
+						{source: "files"},
+					},
+					"rpc": {
+						{source: "db"},
+						{source: "files"},
+					},
+					"netgroup": {
+						{source: "nis"},
+					},
+				},
+			},
+		},
+	}
+
+	for _, tt := range tests {
+		gotConf := parseNSSConf(strings.NewReader(tt.in))
+		if !reflect.DeepEqual(gotConf, tt.want) {
+			t.Errorf("%s: mismatch\n got %#v\nwant %#v", tt.name, gotConf, tt.want)
+		}
+	}
+}
diff --git a/third_party/gofrontend/libgo/go/net/packetconn_test.go b/third_party/gofrontend/libgo/go/net/packetconn_test.go
index b6e4e76..7f3ea8a 100644
--- a/third_party/gofrontend/libgo/go/net/packetconn_test.go
+++ b/third_party/gofrontend/libgo/go/net/packetconn_test.go
@@ -9,49 +9,21 @@
 
 import (
 	"os"
-	"runtime"
-	"strings"
 	"testing"
 	"time"
 )
 
-func packetConnTestData(t *testing.T, net string, i int) ([]byte, func()) {
-	switch net {
-	case "udp":
-		return []byte("UDP PACKETCONN TEST"), nil
-	case "ip":
-		if skip, skipmsg := skipRawSocketTest(t); skip {
-			return nil, func() {
-				t.Logf(skipmsg)
-			}
-		}
-		b, err := (&icmpMessage{
-			Type: icmpv4EchoRequest, Code: 0,
-			Body: &icmpEcho{
-				ID: os.Getpid() & 0xffff, Seq: i + 1,
-				Data: []byte("IP PACKETCONN TEST"),
-			},
-		}).Marshal()
-		if err != nil {
-			return nil, func() {
-				t.Fatalf("icmpMessage.Marshal failed: %v", err)
-			}
-		}
-		return b, nil
-	case "unixgram":
-		switch runtime.GOOS {
-		case "nacl", "plan9", "windows":
-			return nil, func() {
-				t.Logf("skipping %q test on %q", net, runtime.GOOS)
-			}
-		default:
-			return []byte("UNIXGRAM PACKETCONN TEST"), nil
-		}
-	default:
-		return nil, func() {
-			t.Logf("skipping %q test", net)
-		}
+// The full stack test cases for IPConn have been moved to the
+// following:
+//	golang.org/x/net/ipv4
+//	golang.org/x/net/ipv6
+//	golang.org/x/net/icmp
+
+func packetConnTestData(t *testing.T, network string) ([]byte, func()) {
+	if !testableNetwork(network) {
+		return nil, func() { t.Logf("skipping %s test", network) }
 	}
+	return []byte("PACKETCONN TEST"), nil
 }
 
 var packetConnTests = []struct {
@@ -60,7 +32,6 @@
 	addr2 string
 }{
 	{"udp", "127.0.0.1:0", "127.0.0.1:0"},
-	{"ip:icmp", "127.0.0.1", "127.0.0.1"},
 	{"unixgram", testUnixAddr(), testUnixAddr()},
 }
 
@@ -74,9 +45,8 @@
 		}
 	}
 
-	for i, tt := range packetConnTests {
-		netstr := strings.Split(tt.net, ":")
-		wb, skipOrFatalFn := packetConnTestData(t, netstr[0], i)
+	for _, tt := range packetConnTests {
+		wb, skipOrFatalFn := packetConnTestData(t, tt.net)
 		if skipOrFatalFn != nil {
 			skipOrFatalFn()
 			continue
@@ -84,37 +54,37 @@
 
 		c1, err := ListenPacket(tt.net, tt.addr1)
 		if err != nil {
-			t.Fatalf("ListenPacket failed: %v", err)
+			t.Fatal(err)
 		}
-		defer closer(c1, netstr[0], tt.addr1, tt.addr2)
+		defer closer(c1, tt.net, tt.addr1, tt.addr2)
 		c1.LocalAddr()
-		c1.SetDeadline(time.Now().Add(100 * time.Millisecond))
-		c1.SetReadDeadline(time.Now().Add(100 * time.Millisecond))
-		c1.SetWriteDeadline(time.Now().Add(100 * time.Millisecond))
+		c1.SetDeadline(time.Now().Add(500 * time.Millisecond))
+		c1.SetReadDeadline(time.Now().Add(500 * time.Millisecond))
+		c1.SetWriteDeadline(time.Now().Add(500 * time.Millisecond))
 
 		c2, err := ListenPacket(tt.net, tt.addr2)
 		if err != nil {
-			t.Fatalf("ListenPacket failed: %v", err)
+			t.Fatal(err)
 		}
-		defer closer(c2, netstr[0], tt.addr1, tt.addr2)
+		defer closer(c2, tt.net, tt.addr1, tt.addr2)
 		c2.LocalAddr()
-		c2.SetDeadline(time.Now().Add(100 * time.Millisecond))
-		c2.SetReadDeadline(time.Now().Add(100 * time.Millisecond))
-		c2.SetWriteDeadline(time.Now().Add(100 * time.Millisecond))
+		c2.SetDeadline(time.Now().Add(500 * time.Millisecond))
+		c2.SetReadDeadline(time.Now().Add(500 * time.Millisecond))
+		c2.SetWriteDeadline(time.Now().Add(500 * time.Millisecond))
+		rb2 := make([]byte, 128)
 
 		if _, err := c1.WriteTo(wb, c2.LocalAddr()); err != nil {
-			t.Fatalf("PacketConn.WriteTo failed: %v", err)
+			t.Fatal(err)
 		}
-		rb2 := make([]byte, 128)
 		if _, _, err := c2.ReadFrom(rb2); err != nil {
-			t.Fatalf("PacketConn.ReadFrom failed: %v", err)
+			t.Fatal(err)
 		}
 		if _, err := c2.WriteTo(wb, c1.LocalAddr()); err != nil {
-			t.Fatalf("PacketConn.WriteTo failed: %v", err)
+			t.Fatal(err)
 		}
 		rb1 := make([]byte, 128)
 		if _, _, err := c1.ReadFrom(rb1); err != nil {
-			t.Fatalf("PacketConn.ReadFrom failed: %v", err)
+			t.Fatal(err)
 		}
 	}
 }
@@ -129,10 +99,9 @@
 		}
 	}
 
-	for i, tt := range packetConnTests {
+	for _, tt := range packetConnTests {
 		var wb []byte
-		netstr := strings.Split(tt.net, ":")
-		wb, skipOrFatalFn := packetConnTestData(t, netstr[0], i)
+		wb, skipOrFatalFn := packetConnTestData(t, tt.net)
 		if skipOrFatalFn != nil {
 			skipOrFatalFn()
 			continue
@@ -140,47 +109,45 @@
 
 		c1, err := ListenPacket(tt.net, tt.addr1)
 		if err != nil {
-			t.Fatalf("ListenPacket failed: %v", err)
+			t.Fatal(err)
 		}
-		defer closer(c1, netstr[0], tt.addr1, tt.addr2)
+		defer closer(c1, tt.net, tt.addr1, tt.addr2)
 		c1.LocalAddr()
-		c1.SetDeadline(time.Now().Add(100 * time.Millisecond))
-		c1.SetReadDeadline(time.Now().Add(100 * time.Millisecond))
-		c1.SetWriteDeadline(time.Now().Add(100 * time.Millisecond))
+		c1.SetDeadline(time.Now().Add(500 * time.Millisecond))
+		c1.SetReadDeadline(time.Now().Add(500 * time.Millisecond))
+		c1.SetWriteDeadline(time.Now().Add(500 * time.Millisecond))
 
 		c2, err := Dial(tt.net, c1.LocalAddr().String())
 		if err != nil {
-			t.Fatalf("Dial failed: %v", err)
+			t.Fatal(err)
 		}
 		defer c2.Close()
 		c2.LocalAddr()
 		c2.RemoteAddr()
-		c2.SetDeadline(time.Now().Add(100 * time.Millisecond))
-		c2.SetReadDeadline(time.Now().Add(100 * time.Millisecond))
-		c2.SetWriteDeadline(time.Now().Add(100 * time.Millisecond))
+		c2.SetDeadline(time.Now().Add(500 * time.Millisecond))
+		c2.SetReadDeadline(time.Now().Add(500 * time.Millisecond))
+		c2.SetWriteDeadline(time.Now().Add(500 * time.Millisecond))
 
 		if _, err := c2.Write(wb); err != nil {
-			t.Fatalf("Conn.Write failed: %v", err)
+			t.Fatal(err)
 		}
 		rb1 := make([]byte, 128)
 		if _, _, err := c1.ReadFrom(rb1); err != nil {
-			t.Fatalf("PacketConn.ReadFrom failed: %v", err)
+			t.Fatal(err)
 		}
 		var dst Addr
-		switch netstr[0] {
-		case "ip":
-			dst = &IPAddr{IP: IPv4(127, 0, 0, 1)}
+		switch tt.net {
 		case "unixgram":
 			continue
 		default:
 			dst = c2.LocalAddr()
 		}
 		if _, err := c1.WriteTo(wb, dst); err != nil {
-			t.Fatalf("PacketConn.WriteTo failed: %v", err)
+			t.Fatal(err)
 		}
 		rb2 := make([]byte, 128)
 		if _, err := c2.Read(rb2); err != nil {
-			t.Fatalf("Conn.Read failed: %v", err)
+			t.Fatal(err)
 		}
 	}
 }
diff --git a/third_party/gofrontend/libgo/go/net/parse.go b/third_party/gofrontend/libgo/go/net/parse.go
index e1d0130..c72e1c2 100644
--- a/third_party/gofrontend/libgo/go/net/parse.go
+++ b/third_party/gofrontend/libgo/go/net/parse.go
@@ -171,43 +171,30 @@
 	return byte(n), ok && ei == 2
 }
 
-// Integer to decimal.
-func itoa(i int) string {
-	var buf [30]byte
-	n := len(buf)
-	neg := false
-	if i < 0 {
-		i = -i
-		neg = true
+// Convert integer to decimal string.
+func itoa(val int) string {
+	if val < 0 {
+		return "-" + uitoa(uint(-val))
 	}
-	ui := uint(i)
-	for ui > 0 || n == len(buf) {
-		n--
-		buf[n] = byte('0' + ui%10)
-		ui /= 10
-	}
-	if neg {
-		n--
-		buf[n] = '-'
-	}
-	return string(buf[n:])
+	return uitoa(uint(val))
 }
 
-// Convert i to decimal string.
-func itod(i uint) string {
-	if i == 0 {
+// Convert unsigned integer to decimal string.
+func uitoa(val uint) string {
+	if val == 0 { // avoid string allocation
 		return "0"
 	}
-
-	// Assemble decimal in reverse order.
-	var b [32]byte
-	bp := len(b)
-	for ; i > 0; i /= 10 {
-		bp--
-		b[bp] = byte(i%10) + '0'
+	var buf [20]byte // big enough for 64bit value base 10
+	i := len(buf) - 1
+	for val >= 10 {
+		q := val / 10
+		buf[i] = byte('0' + val - q*10)
+		i--
+		val = q
 	}
-
-	return string(b[bp:])
+	// val < 10
+	buf[i] = byte('0' + val)
+	return string(buf[i:])
 }
 
 // Convert i to a hexadecimal string. Leading zeros are not printed.
@@ -245,3 +232,155 @@
 	}
 	return i
 }
+
+// lowerASCIIBytes makes x ASCII lowercase in-place.
+func lowerASCIIBytes(x []byte) {
+	for i, b := range x {
+		if 'A' <= b && b <= 'Z' {
+			x[i] += 'a' - 'A'
+		}
+	}
+}
+
+// lowerASCII returns the ASCII lowercase version of b.
+func lowerASCII(b byte) byte {
+	if 'A' <= b && b <= 'Z' {
+		return b + ('a' - 'A')
+	}
+	return b
+}
+
+// trimSpace returns x without any leading or trailing ASCII whitespace.
+func trimSpace(x []byte) []byte {
+	for len(x) > 0 && isSpace(x[0]) {
+		x = x[1:]
+	}
+	for len(x) > 0 && isSpace(x[len(x)-1]) {
+		x = x[:len(x)-1]
+	}
+	return x
+}
+
+// isSpace reports whether b is an ASCII space character.
+func isSpace(b byte) bool {
+	return b == ' ' || b == '\t' || b == '\n' || b == '\r'
+}
+
+// removeComment returns line, removing any '#' byte and any following
+// bytes.
+func removeComment(line []byte) []byte {
+	if i := bytesIndexByte(line, '#'); i != -1 {
+		return line[:i]
+	}
+	return line
+}
+
+// foreachLine runs fn on each line of x.
+// Each line (except for possibly the last) ends in '\n'.
+// It returns the first non-nil error returned by fn.
+func foreachLine(x []byte, fn func(line []byte) error) error {
+	for len(x) > 0 {
+		nl := bytesIndexByte(x, '\n')
+		if nl == -1 {
+			return fn(x)
+		}
+		line := x[:nl+1]
+		x = x[nl+1:]
+		if err := fn(line); err != nil {
+			return err
+		}
+	}
+	return nil
+}
+
+// foreachField runs fn on each non-empty run of non-space bytes in x.
+// It returns the first non-nil error returned by fn.
+func foreachField(x []byte, fn func(field []byte) error) error {
+	x = trimSpace(x)
+	for len(x) > 0 {
+		sp := bytesIndexByte(x, ' ')
+		if sp == -1 {
+			return fn(x)
+		}
+		if field := trimSpace(x[:sp]); len(field) > 0 {
+			if err := fn(field); err != nil {
+				return err
+			}
+		}
+		x = trimSpace(x[sp+1:])
+	}
+	return nil
+}
+
+// bytesIndexByte is bytes.IndexByte. It returns the index of the
+// first instance of c in s, or -1 if c is not present in s.
+func bytesIndexByte(s []byte, c byte) int {
+	for i, b := range s {
+		if b == c {
+			return i
+		}
+	}
+	return -1
+}
+
+// stringsHasSuffix is strings.HasSuffix. It reports whether s ends in
+// suffix.
+func stringsHasSuffix(s, suffix string) bool {
+	return len(s) >= len(suffix) && s[len(s)-len(suffix):] == suffix
+}
+
+// stringsHasSuffixFold reports whether s ends in suffix,
+// ASCII-case-insensitively.
+func stringsHasSuffixFold(s, suffix string) bool {
+	if len(suffix) > len(s) {
+		return false
+	}
+	for i := 0; i < len(suffix); i++ {
+		if lowerASCII(suffix[i]) != lowerASCII(s[len(s)-len(suffix)+i]) {
+			return false
+		}
+	}
+	return true
+}
+
+// stringsHasPrefix is strings.HasPrefix. It reports whether s begins with prefix.
+func stringsHasPrefix(s, prefix string) bool {
+	return len(s) >= len(prefix) && s[:len(prefix)] == prefix
+}
+
+func readFull(r io.Reader) (all []byte, err error) {
+	buf := make([]byte, 1024)
+	for {
+		n, err := r.Read(buf)
+		all = append(all, buf[:n]...)
+		if err == io.EOF {
+			return all, nil
+		}
+		if err != nil {
+			return nil, err
+		}
+	}
+}
+
+// goDebugString returns the value of the named GODEBUG key.
+// GODEBUG is of the form "key=val,key2=val2"
+func goDebugString(key string) string {
+	s := os.Getenv("GODEBUG")
+	for i := 0; i < len(s)-len(key)-1; i++ {
+		if i > 0 && s[i-1] != ',' {
+			continue
+		}
+		afterKey := s[i+len(key):]
+		if afterKey[0] != '=' || s[i:i+len(key)] != key {
+			continue
+		}
+		val := afterKey[1:]
+		for i, b := range val {
+			if b == ',' {
+				return val[:i]
+			}
+		}
+		return val
+	}
+	return ""
+}
diff --git a/third_party/gofrontend/libgo/go/net/parse_test.go b/third_party/gofrontend/libgo/go/net/parse_test.go
index 7b213b7..0f048fc 100644
--- a/third_party/gofrontend/libgo/go/net/parse_test.go
+++ b/third_party/gofrontend/libgo/go/net/parse_test.go
@@ -15,20 +15,20 @@
 	// /etc/services file does not exist on android, plan9, windows.
 	switch runtime.GOOS {
 	case "android", "plan9", "windows":
-		t.Skipf("skipping test on %q", runtime.GOOS)
+		t.Skipf("not supported on %s", runtime.GOOS)
 	}
 	filename := "/etc/services" // a nice big file
 
 	fd, err := os.Open(filename)
 	if err != nil {
-		t.Fatalf("open %s: %v", filename, err)
+		t.Fatal(err)
 	}
 	defer fd.Close()
 	br := bufio.NewReader(fd)
 
 	file, err := open(filename)
 	if file == nil {
-		t.Fatalf("net.open(%s) = nil", filename)
+		t.Fatal(err)
 	}
 	defer file.close()
 
@@ -41,8 +41,7 @@
 		}
 		line, ok := file.readLine()
 		if (berr != nil) != !ok || bline != line {
-			t.Fatalf("%s:%d (#%d)\nbufio => %q, %v\nnet => %q, %v",
-				filename, lineno, byteno, bline, berr, line, ok)
+			t.Fatalf("%s:%d (#%d)\nbufio => %q, %v\nnet => %q, %v", filename, lineno, byteno, bline, berr, line, ok)
 		}
 		if !ok {
 			break
@@ -51,3 +50,30 @@
 		byteno += len(line) + 1
 	}
 }
+
+func TestGoDebugString(t *testing.T) {
+	defer os.Setenv("GODEBUG", os.Getenv("GODEBUG"))
+	tests := []struct {
+		godebug string
+		key     string
+		want    string
+	}{
+		{"", "foo", ""},
+		{"foo=", "foo", ""},
+		{"foo=bar", "foo", "bar"},
+		{"foo=bar,", "foo", "bar"},
+		{"foo,foo=bar,", "foo", "bar"},
+		{"foo1=bar,foo=bar,", "foo", "bar"},
+		{"foo=bar,foo=bar,", "foo", "bar"},
+		{"foo=", "foo", ""},
+		{"foo", "foo", ""},
+		{",foo", "foo", ""},
+		{"foo=bar,baz", "loooooooong", ""},
+	}
+	for _, tt := range tests {
+		os.Setenv("GODEBUG", tt.godebug)
+		if got := goDebugString(tt.key); got != tt.want {
+			t.Errorf("for %q, goDebugString(%q) = %q; want %q", tt.godebug, tt.key, got, tt.want)
+		}
+	}
+}
diff --git a/third_party/gofrontend/libgo/go/net/pipe.go b/third_party/gofrontend/libgo/go/net/pipe.go
index f1a2eca..5fc830b 100644
--- a/third_party/gofrontend/libgo/go/net/pipe.go
+++ b/third_party/gofrontend/libgo/go/net/pipe.go
@@ -55,13 +55,13 @@
 }
 
 func (p *pipe) SetDeadline(t time.Time) error {
-	return errors.New("net.Pipe does not support deadlines")
+	return &OpError{Op: "set", Net: "pipe", Source: nil, Addr: nil, Err: errors.New("deadline not supported")}
 }
 
 func (p *pipe) SetReadDeadline(t time.Time) error {
-	return errors.New("net.Pipe does not support deadlines")
+	return &OpError{Op: "set", Net: "pipe", Source: nil, Addr: nil, Err: errors.New("deadline not supported")}
 }
 
 func (p *pipe) SetWriteDeadline(t time.Time) error {
-	return errors.New("net.Pipe does not support deadlines")
+	return &OpError{Op: "set", Net: "pipe", Source: nil, Addr: nil, Err: errors.New("deadline not supported")}
 }
diff --git a/third_party/gofrontend/libgo/go/net/pipe_test.go b/third_party/gofrontend/libgo/go/net/pipe_test.go
index afe4f24..60c3920 100644
--- a/third_party/gofrontend/libgo/go/net/pipe_test.go
+++ b/third_party/gofrontend/libgo/go/net/pipe_test.go
@@ -10,10 +10,10 @@
 	"testing"
 )
 
-func checkWrite(t *testing.T, w io.Writer, data []byte, c chan int) {
+func checkPipeWrite(t *testing.T, w io.Writer, data []byte, c chan int) {
 	n, err := w.Write(data)
 	if err != nil {
-		t.Errorf("write: %v", err)
+		t.Error(err)
 	}
 	if n != len(data) {
 		t.Errorf("short write: %d != %d", n, len(data))
@@ -21,11 +21,11 @@
 	c <- 0
 }
 
-func checkRead(t *testing.T, r io.Reader, data []byte, wantErr error) {
+func checkPipeRead(t *testing.T, r io.Reader, data []byte, wantErr error) {
 	buf := make([]byte, len(data)+10)
 	n, err := r.Read(buf)
 	if err != wantErr {
-		t.Errorf("read: %v", err)
+		t.Error(err)
 		return
 	}
 	if n != len(data) || !bytes.Equal(buf[0:n], data) {
@@ -34,23 +34,22 @@
 	}
 }
 
-// Test a simple read/write/close sequence.
+// TestPipe tests a simple read/write/close sequence.
 // Assumes that the underlying io.Pipe implementation
 // is solid and we're just testing the net wrapping.
-
 func TestPipe(t *testing.T) {
 	c := make(chan int)
 	cli, srv := Pipe()
-	go checkWrite(t, cli, []byte("hello, world"), c)
-	checkRead(t, srv, []byte("hello, world"), nil)
+	go checkPipeWrite(t, cli, []byte("hello, world"), c)
+	checkPipeRead(t, srv, []byte("hello, world"), nil)
 	<-c
-	go checkWrite(t, srv, []byte("line 2"), c)
-	checkRead(t, cli, []byte("line 2"), nil)
+	go checkPipeWrite(t, srv, []byte("line 2"), c)
+	checkPipeRead(t, cli, []byte("line 2"), nil)
 	<-c
-	go checkWrite(t, cli, []byte("a third line"), c)
-	checkRead(t, srv, []byte("a third line"), nil)
+	go checkPipeWrite(t, cli, []byte("a third line"), c)
+	checkPipeRead(t, srv, []byte("a third line"), nil)
 	<-c
 	go srv.Close()
-	checkRead(t, cli, nil, io.EOF)
+	checkPipeRead(t, cli, nil, io.EOF)
 	cli.Close()
 }
diff --git a/third_party/gofrontend/libgo/go/net/platform_test.go b/third_party/gofrontend/libgo/go/net/platform_test.go
new file mode 100644
index 0000000..d624852
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/net/platform_test.go
@@ -0,0 +1,159 @@
+// 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 net
+
+import (
+	"os"
+	"runtime"
+	"strings"
+	"testing"
+)
+
+// testableNetwork reports whether network is testable on the current
+// platform configuration.
+func testableNetwork(network string) bool {
+	ss := strings.Split(network, ":")
+	switch ss[0] {
+	case "ip+nopriv":
+		switch runtime.GOOS {
+		case "nacl":
+			return false
+		}
+	case "ip", "ip4", "ip6":
+		switch runtime.GOOS {
+		case "nacl", "plan9":
+			return false
+		default:
+			if os.Getuid() != 0 {
+				return false
+			}
+		}
+	case "unix", "unixgram":
+		switch runtime.GOOS {
+		case "nacl", "plan9", "windows":
+			return false
+		}
+		// iOS does not support unix, unixgram.
+		if runtime.GOOS == "darwin" && (runtime.GOARCH == "arm" || runtime.GOARCH == "arm64") {
+			return false
+		}
+	case "unixpacket":
+		switch runtime.GOOS {
+		case "android", "darwin", "nacl", "plan9", "windows":
+			fallthrough
+		case "freebsd": // FreeBSD 8 and below don't support unixpacket
+			return false
+		}
+	}
+	switch ss[0] {
+	case "tcp4", "udp4", "ip4":
+		if !supportsIPv4 {
+			return false
+		}
+	case "tcp6", "udp6", "ip6":
+		if !supportsIPv6 {
+			return false
+		}
+	}
+	return true
+}
+
+// testableAddress reports whether address of network is testable on
+// the current platform configuration.
+func testableAddress(network, address string) bool {
+	switch ss := strings.Split(network, ":"); ss[0] {
+	case "unix", "unixgram", "unixpacket":
+		// Abstract unix domain sockets, a Linux-ism.
+		if address[0] == '@' && runtime.GOOS != "linux" {
+			return false
+		}
+	}
+	return true
+}
+
+// testableListenArgs reports whether arguments are testable on the
+// current platform configuration.
+func testableListenArgs(network, address, client string) bool {
+	if !testableNetwork(network) || !testableAddress(network, address) {
+		return false
+	}
+
+	var err error
+	var addr Addr
+	switch ss := strings.Split(network, ":"); ss[0] {
+	case "tcp", "tcp4", "tcp6":
+		addr, err = ResolveTCPAddr("tcp", address)
+	case "udp", "udp4", "udp6":
+		addr, err = ResolveUDPAddr("udp", address)
+	case "ip", "ip4", "ip6":
+		addr, err = ResolveIPAddr("ip", address)
+	default:
+		return true
+	}
+	if err != nil {
+		return false
+	}
+	var ip IP
+	var wildcard bool
+	switch addr := addr.(type) {
+	case *TCPAddr:
+		ip = addr.IP
+		wildcard = addr.isWildcard()
+	case *UDPAddr:
+		ip = addr.IP
+		wildcard = addr.isWildcard()
+	case *IPAddr:
+		ip = addr.IP
+		wildcard = addr.isWildcard()
+	}
+
+	// Test wildcard IP addresses.
+	if wildcard && (testing.Short() || !*testExternal) {
+		return false
+	}
+
+	// Test functionality of IPv4 communication using AF_INET and
+	// IPv6 communication using AF_INET6 sockets.
+	if !supportsIPv4 && ip.To4() != nil {
+		return false
+	}
+	if !supportsIPv6 && ip.To16() != nil && ip.To4() == nil {
+		return false
+	}
+	cip := ParseIP(client)
+	if cip != nil {
+		if !supportsIPv4 && cip.To4() != nil {
+			return false
+		}
+		if !supportsIPv6 && cip.To16() != nil && cip.To4() == nil {
+			return false
+		}
+	}
+
+	// Test functionality of IPv4 communication using AF_INET6
+	// sockets.
+	if !supportsIPv4map && (network == "tcp" || network == "udp" || network == "ip") && wildcard {
+		// At this point, we prefer IPv4 when ip is nil.
+		// See favoriteAddrFamily for further information.
+		if ip.To16() != nil && ip.To4() == nil && cip.To4() != nil { // a pair of IPv6 server and IPv4 client
+			return false
+		}
+		if (ip.To4() != nil || ip == nil) && cip.To16() != nil && cip.To4() == nil { // a pair of IPv4 server and IPv6 client
+			return false
+		}
+	}
+
+	return true
+}
+
+var condFatalf = func() func(*testing.T, string, ...interface{}) {
+	// A few APIs, File, Read/WriteMsg{UDP,IP}, are not
+	// implemented yet on both Plan 9 and Windows.
+	switch runtime.GOOS {
+	case "plan9", "windows":
+		return (*testing.T).Logf
+	}
+	return (*testing.T).Fatalf
+}()
diff --git a/third_party/gofrontend/libgo/go/net/port.go b/third_party/gofrontend/libgo/go/net/port.go
index c24f4ed..a2a5387 100644
--- a/third_party/gofrontend/libgo/go/net/port.go
+++ b/third_party/gofrontend/libgo/go/net/port.go
@@ -18,7 +18,7 @@
 		}
 	}
 	if p < 0 || p > 0xFFFF {
-		return 0, &AddrError{"invalid port", port}
+		return 0, &AddrError{Err: "invalid port", Addr: port}
 	}
 	return p, nil
 }
diff --git a/third_party/gofrontend/libgo/go/net/port_test.go b/third_party/gofrontend/libgo/go/net/port_test.go
index 4811ade..258a5bd 100644
--- a/third_party/gofrontend/libgo/go/net/port_test.go
+++ b/third_party/gofrontend/libgo/go/net/port_test.go
@@ -9,14 +9,12 @@
 	"testing"
 )
 
-type portTest struct {
-	netw string
-	name string
-	port int
-	ok   bool
-}
-
-var porttests = []portTest{
+var portTests = []struct {
+	network string
+	name    string
+	port    int
+	ok      bool
+}{
 	{"tcp", "echo", 7, true},
 	{"tcp", "discard", 9, true},
 	{"tcp", "systat", 11, true},
@@ -29,6 +27,7 @@
 	{"tcp", "time", 37, true},
 	{"tcp", "domain", 53, true},
 	{"tcp", "finger", 79, true},
+	{"tcp", "42", 42, true},
 
 	{"udp", "echo", 7, true},
 	{"udp", "tftp", 69, true},
@@ -38,6 +37,7 @@
 	{"udp", "ntp", 123, true},
 	{"udp", "snmp", 161, true},
 	{"udp", "syslog", 514, true},
+	{"udp", "42", 42, true},
 
 	{"--badnet--", "zzz", 0, false},
 	{"tcp", "--badport--", 0, false},
@@ -46,14 +46,12 @@
 func TestLookupPort(t *testing.T) {
 	switch runtime.GOOS {
 	case "nacl":
-		t.Skipf("skipping test on %q", runtime.GOOS)
+		t.Skipf("not supported on %s", runtime.GOOS)
 	}
 
-	for i := 0; i < len(porttests); i++ {
-		tt := porttests[i]
-		if port, err := LookupPort(tt.netw, tt.name); port != tt.port || (err == nil) != tt.ok {
-			t.Errorf("LookupPort(%q, %q) = %v, %v; want %v",
-				tt.netw, tt.name, port, err, tt.port)
+	for _, tt := range portTests {
+		if port, err := LookupPort(tt.network, tt.name); port != tt.port || (err == nil) != tt.ok {
+			t.Errorf("LookupPort(%q, %q) = %v, %v; want %v", tt.network, tt.name, port, err, tt.port)
 		}
 	}
 }
diff --git a/third_party/gofrontend/libgo/go/net/port_unix.go b/third_party/gofrontend/libgo/go/net/port_unix.go
index 348c771..badf8ab 100644
--- a/third_party/gofrontend/libgo/go/net/port_unix.go
+++ b/third_party/gofrontend/libgo/go/net/port_unix.go
@@ -69,5 +69,5 @@
 			return
 		}
 	}
-	return 0, &AddrError{"unknown port", network + "/" + service}
+	return 0, &AddrError{Err: "unknown port", Addr: network + "/" + service}
 }
diff --git a/third_party/gofrontend/libgo/go/net/protoconn_test.go b/third_party/gofrontend/libgo/go/net/protoconn_test.go
index 12856b6..c6ef23b 100644
--- a/third_party/gofrontend/libgo/go/net/protoconn_test.go
+++ b/third_party/gofrontend/libgo/go/net/protoconn_test.go
@@ -8,49 +8,31 @@
 package net
 
 import (
-	"io/ioutil"
 	"os"
 	"runtime"
 	"testing"
 	"time"
 )
 
-// testUnixAddr uses ioutil.TempFile to get a name that is unique. It
-// also uses /tmp directory in case it is prohibited to create UNIX
-// sockets in TMPDIR.
-func testUnixAddr() string {
-	f, err := ioutil.TempFile("", "nettest")
-	if err != nil {
-		panic(err)
-	}
-	addr := f.Name()
-	f.Close()
-	os.Remove(addr)
-	return addr
-}
-
-var condFatalf = func() func(*testing.T, string, ...interface{}) {
-	// A few APIs are not implemented yet on both Plan 9 and Windows.
-	switch runtime.GOOS {
-	case "plan9", "windows":
-		return (*testing.T).Logf
-	}
-	return (*testing.T).Fatalf
-}()
+// The full stack test cases for IPConn have been moved to the
+// following:
+//	golang.org/x/net/ipv4
+//	golang.org/x/net/ipv6
+//	golang.org/x/net/icmp
 
 func TestTCPListenerSpecificMethods(t *testing.T) {
 	switch runtime.GOOS {
 	case "plan9":
-		t.Skipf("skipping test on %q", runtime.GOOS)
+		t.Skipf("not supported on %s", runtime.GOOS)
 	}
 
 	la, err := ResolveTCPAddr("tcp4", "127.0.0.1:0")
 	if err != nil {
-		t.Fatalf("ResolveTCPAddr failed: %v", err)
+		t.Fatal(err)
 	}
 	ln, err := ListenTCP("tcp4", la)
 	if err != nil {
-		t.Fatalf("ListenTCP failed: %v", err)
+		t.Fatal(err)
 	}
 	defer ln.Close()
 	ln.Addr()
@@ -58,21 +40,21 @@
 
 	if c, err := ln.Accept(); err != nil {
 		if !err.(Error).Timeout() {
-			t.Fatalf("TCPListener.Accept failed: %v", err)
+			t.Fatal(err)
 		}
 	} else {
 		c.Close()
 	}
 	if c, err := ln.AcceptTCP(); err != nil {
 		if !err.(Error).Timeout() {
-			t.Fatalf("TCPListener.AcceptTCP failed: %v", err)
+			t.Fatal(err)
 		}
 	} else {
 		c.Close()
 	}
 
 	if f, err := ln.File(); err != nil {
-		condFatalf(t, "TCPListener.File failed: %v", err)
+		condFatalf(t, "%v", err)
 	} else {
 		f.Close()
 	}
@@ -81,25 +63,30 @@
 func TestTCPConnSpecificMethods(t *testing.T) {
 	la, err := ResolveTCPAddr("tcp4", "127.0.0.1:0")
 	if err != nil {
-		t.Fatalf("ResolveTCPAddr failed: %v", err)
+		t.Fatal(err)
 	}
 	ln, err := ListenTCP("tcp4", la)
 	if err != nil {
-		t.Fatalf("ListenTCP failed: %v", err)
+		t.Fatal(err)
 	}
-	defer ln.Close()
-	ln.Addr()
-
-	done := make(chan int)
-	go transponder(t, ln, done)
-
-	ra, err := ResolveTCPAddr("tcp4", ln.Addr().String())
+	ch := make(chan error, 1)
+	handler := func(ls *localServer, ln Listener) { transponder(ls.Listener, ch) }
+	ls, err := (&streamListener{Listener: ln}).newLocalServer()
 	if err != nil {
-		t.Fatalf("ResolveTCPAddr failed: %v", err)
+		t.Fatal(err)
+	}
+	defer ls.teardown()
+	if err := ls.buildup(handler); err != nil {
+		t.Fatal(err)
+	}
+
+	ra, err := ResolveTCPAddr("tcp4", ls.Listener.Addr().String())
+	if err != nil {
+		t.Fatal(err)
 	}
 	c, err := DialTCP("tcp4", nil, ra)
 	if err != nil {
-		t.Fatalf("DialTCP failed: %v", err)
+		t.Fatal(err)
 	}
 	defer c.Close()
 	c.SetKeepAlive(false)
@@ -113,24 +100,26 @@
 	c.SetWriteDeadline(time.Now().Add(someTimeout))
 
 	if _, err := c.Write([]byte("TCPCONN TEST")); err != nil {
-		t.Fatalf("TCPConn.Write failed: %v", err)
+		t.Fatal(err)
 	}
 	rb := make([]byte, 128)
 	if _, err := c.Read(rb); err != nil {
-		t.Fatalf("TCPConn.Read failed: %v", err)
+		t.Fatal(err)
 	}
 
-	<-done
+	for err := range ch {
+		t.Error(err)
+	}
 }
 
 func TestUDPConnSpecificMethods(t *testing.T) {
 	la, err := ResolveUDPAddr("udp4", "127.0.0.1:0")
 	if err != nil {
-		t.Fatalf("ResolveUDPAddr failed: %v", err)
+		t.Fatal(err)
 	}
 	c, err := ListenUDP("udp4", la)
 	if err != nil {
-		t.Fatalf("ListenUDP failed: %v", err)
+		t.Fatal(err)
 	}
 	defer c.Close()
 	c.LocalAddr()
@@ -144,27 +133,27 @@
 	wb := []byte("UDPCONN TEST")
 	rb := make([]byte, 128)
 	if _, err := c.WriteToUDP(wb, c.LocalAddr().(*UDPAddr)); err != nil {
-		t.Fatalf("UDPConn.WriteToUDP failed: %v", err)
+		t.Fatal(err)
 	}
 	if _, _, err := c.ReadFromUDP(rb); err != nil {
-		t.Fatalf("UDPConn.ReadFromUDP failed: %v", err)
+		t.Fatal(err)
 	}
 	if _, _, err := c.WriteMsgUDP(wb, nil, c.LocalAddr().(*UDPAddr)); err != nil {
-		condFatalf(t, "UDPConn.WriteMsgUDP failed: %v", err)
+		condFatalf(t, "%v", err)
 	}
 	if _, _, _, _, err := c.ReadMsgUDP(rb, nil); err != nil {
-		condFatalf(t, "UDPConn.ReadMsgUDP failed: %v", err)
+		condFatalf(t, "%v", err)
 	}
 
 	if f, err := c.File(); err != nil {
-		condFatalf(t, "UDPConn.File failed: %v", err)
+		condFatalf(t, "%v", err)
 	} else {
 		f.Close()
 	}
 
 	defer func() {
 		if p := recover(); p != nil {
-			t.Fatalf("UDPConn.WriteToUDP or WriteMsgUDP panicked: %v", p)
+			t.Fatalf("panicked: %v", p)
 		}
 	}()
 
@@ -173,17 +162,17 @@
 }
 
 func TestIPConnSpecificMethods(t *testing.T) {
-	if skip, skipmsg := skipRawSocketTest(t); skip {
-		t.Skip(skipmsg)
+	if os.Getuid() != 0 {
+		t.Skip("must be root")
 	}
 
 	la, err := ResolveIPAddr("ip4", "127.0.0.1")
 	if err != nil {
-		t.Fatalf("ResolveIPAddr failed: %v", err)
+		t.Fatal(err)
 	}
 	c, err := ListenIP("ip4:icmp", la)
 	if err != nil {
-		t.Fatalf("ListenIP failed: %v", err)
+		t.Fatal(err)
 	}
 	defer c.Close()
 	c.LocalAddr()
@@ -194,60 +183,36 @@
 	c.SetReadBuffer(2048)
 	c.SetWriteBuffer(2048)
 
-	wb, err := (&icmpMessage{
-		Type: icmpv4EchoRequest, Code: 0,
-		Body: &icmpEcho{
-			ID: os.Getpid() & 0xffff, Seq: 1,
-			Data: []byte("IPCONN TEST "),
-		},
-	}).Marshal()
-	if err != nil {
-		t.Fatalf("icmpMessage.Marshal failed: %v", err)
-	}
-	rb := make([]byte, 20+len(wb))
-	if _, err := c.WriteToIP(wb, c.LocalAddr().(*IPAddr)); err != nil {
-		t.Fatalf("IPConn.WriteToIP failed: %v", err)
-	}
-	if _, _, err := c.ReadFromIP(rb); err != nil {
-		t.Fatalf("IPConn.ReadFromIP failed: %v", err)
-	}
-	if _, _, err := c.WriteMsgIP(wb, nil, c.LocalAddr().(*IPAddr)); err != nil {
-		condFatalf(t, "IPConn.WriteMsgIP failed: %v", err)
-	}
-	if _, _, _, _, err := c.ReadMsgIP(rb, nil); err != nil {
-		condFatalf(t, "IPConn.ReadMsgIP failed: %v", err)
-	}
-
 	if f, err := c.File(); err != nil {
-		condFatalf(t, "IPConn.File failed: %v", err)
+		condFatalf(t, "%v", err)
 	} else {
 		f.Close()
 	}
 
 	defer func() {
 		if p := recover(); p != nil {
-			t.Fatalf("IPConn.WriteToIP or WriteMsgIP panicked: %v", p)
+			t.Fatalf("panicked: %v", p)
 		}
 	}()
 
+	wb := []byte("IPCONN TEST")
 	c.WriteToIP(wb, nil)
 	c.WriteMsgIP(wb, nil, nil)
 }
 
 func TestUnixListenerSpecificMethods(t *testing.T) {
-	switch runtime.GOOS {
-	case "nacl", "plan9", "windows":
-		t.Skipf("skipping test on %q", runtime.GOOS)
+	if !testableNetwork("unix") {
+		t.Skip("unix test")
 	}
 
 	addr := testUnixAddr()
 	la, err := ResolveUnixAddr("unix", addr)
 	if err != nil {
-		t.Fatalf("ResolveUnixAddr failed: %v", err)
+		t.Fatal(err)
 	}
 	ln, err := ListenUnix("unix", la)
 	if err != nil {
-		t.Fatalf("ListenUnix failed: %v", err)
+		t.Fatal(err)
 	}
 	defer ln.Close()
 	defer os.Remove(addr)
@@ -256,41 +221,40 @@
 
 	if c, err := ln.Accept(); err != nil {
 		if !err.(Error).Timeout() {
-			t.Fatalf("UnixListener.Accept failed: %v", err)
+			t.Fatal(err)
 		}
 	} else {
 		c.Close()
 	}
 	if c, err := ln.AcceptUnix(); err != nil {
 		if !err.(Error).Timeout() {
-			t.Fatalf("UnixListener.AcceptUnix failed: %v", err)
+			t.Fatal(err)
 		}
 	} else {
 		c.Close()
 	}
 
 	if f, err := ln.File(); err != nil {
-		t.Fatalf("UnixListener.File failed: %v", err)
+		t.Fatal(err)
 	} else {
 		f.Close()
 	}
 }
 
 func TestUnixConnSpecificMethods(t *testing.T) {
-	switch runtime.GOOS {
-	case "nacl", "plan9", "windows":
-		t.Skipf("skipping test on %q", runtime.GOOS)
+	if !testableNetwork("unixgram") {
+		t.Skip("unixgram test")
 	}
 
 	addr1, addr2, addr3 := testUnixAddr(), testUnixAddr(), testUnixAddr()
 
 	a1, err := ResolveUnixAddr("unixgram", addr1)
 	if err != nil {
-		t.Fatalf("ResolveUnixAddr failed: %v", err)
+		t.Fatal(err)
 	}
 	c1, err := DialUnix("unixgram", a1, nil)
 	if err != nil {
-		t.Fatalf("DialUnix failed: %v", err)
+		t.Fatal(err)
 	}
 	defer c1.Close()
 	defer os.Remove(addr1)
@@ -304,11 +268,11 @@
 
 	a2, err := ResolveUnixAddr("unixgram", addr2)
 	if err != nil {
-		t.Fatalf("ResolveUnixAddr failed: %v", err)
+		t.Fatal(err)
 	}
 	c2, err := DialUnix("unixgram", a2, nil)
 	if err != nil {
-		t.Fatalf("DialUnix failed: %v", err)
+		t.Fatal(err)
 	}
 	defer c2.Close()
 	defer os.Remove(addr2)
@@ -322,11 +286,11 @@
 
 	a3, err := ResolveUnixAddr("unixgram", addr3)
 	if err != nil {
-		t.Fatalf("ResolveUnixAddr failed: %v", err)
+		t.Fatal(err)
 	}
 	c3, err := ListenUnixgram("unixgram", a3)
 	if err != nil {
-		t.Fatalf("ListenUnixgram failed: %v", err)
+		t.Fatal(err)
 	}
 	defer c3.Close()
 	defer os.Remove(addr3)
@@ -343,39 +307,39 @@
 	rb2 := make([]byte, 128)
 	rb3 := make([]byte, 128)
 	if _, _, err := c1.WriteMsgUnix(wb, nil, a2); err != nil {
-		t.Fatalf("UnixConn.WriteMsgUnix failed: %v", err)
+		t.Fatal(err)
 	}
 	if _, _, _, _, err := c2.ReadMsgUnix(rb2, nil); err != nil {
-		t.Fatalf("UnixConn.ReadMsgUnix failed: %v", err)
+		t.Fatal(err)
 	}
 	if _, err := c2.WriteToUnix(wb, a1); err != nil {
-		t.Fatalf("UnixConn.WriteToUnix failed: %v", err)
+		t.Fatal(err)
 	}
 	if _, _, err := c1.ReadFromUnix(rb1); err != nil {
-		t.Fatalf("UnixConn.ReadFromUnix failed: %v", err)
+		t.Fatal(err)
 	}
 	if _, err := c3.WriteToUnix(wb, a1); err != nil {
-		t.Fatalf("UnixConn.WriteToUnix failed: %v", err)
+		t.Fatal(err)
 	}
 	if _, _, err := c1.ReadFromUnix(rb1); err != nil {
-		t.Fatalf("UnixConn.ReadFromUnix failed: %v", err)
+		t.Fatal(err)
 	}
 	if _, err := c2.WriteToUnix(wb, a3); err != nil {
-		t.Fatalf("UnixConn.WriteToUnix failed: %v", err)
+		t.Fatal(err)
 	}
 	if _, _, err := c3.ReadFromUnix(rb3); err != nil {
-		t.Fatalf("UnixConn.ReadFromUnix failed: %v", err)
+		t.Fatal(err)
 	}
 
 	if f, err := c1.File(); err != nil {
-		t.Fatalf("UnixConn.File failed: %v", err)
+		t.Fatal(err)
 	} else {
 		f.Close()
 	}
 
 	defer func() {
 		if p := recover(); p != nil {
-			t.Fatalf("UnixConn.WriteToUnix or WriteMsgUnix panicked: %v", p)
+			t.Fatalf("panicked: %v", p)
 		}
 	}()
 
diff --git a/third_party/gofrontend/libgo/go/net/rpc/client_test.go b/third_party/gofrontend/libgo/go/net/rpc/client_test.go
index 5dd111b..ba11ff8 100644
--- a/third_party/gofrontend/libgo/go/net/rpc/client_test.go
+++ b/third_party/gofrontend/libgo/go/net/rpc/client_test.go
@@ -54,7 +54,7 @@
 
 func TestGobError(t *testing.T) {
 	if runtime.GOOS == "plan9" {
-		t.Skip("skipping test; see http://golang.org/issue/8908")
+		t.Skip("skipping test; see https://golang.org/issue/8908")
 	}
 	defer func() {
 		err := recover()
diff --git a/third_party/gofrontend/libgo/go/net/rpc/server.go b/third_party/gofrontend/libgo/go/net/rpc/server.go
index 83728d5..6e6e881 100644
--- a/third_party/gofrontend/libgo/go/net/rpc/server.go
+++ b/third_party/gofrontend/libgo/go/net/rpc/server.go
@@ -13,6 +13,7 @@
 	Only methods that satisfy these criteria will be made available for remote access;
 	other methods will be ignored:
 
+		- the method's type is exported.
 		- the method is exported.
 		- the method has two arguments, both exported (or builtin) types.
 		- the method's second argument is a pointer.
@@ -216,7 +217,7 @@
 
 // Register publishes in the server the set of methods of the
 // receiver value that satisfy the following conditions:
-//	- exported method
+//	- exported method of exported type
 //	- two arguments, both of exported type
 //	- the second argument is a pointer
 //	- one return value, of type error
diff --git a/third_party/gofrontend/libgo/go/net/sendfile_dragonfly.go b/third_party/gofrontend/libgo/go/net/sendfile_dragonfly.go
index bc88fd3..a9cf3fe 100644
--- a/third_party/gofrontend/libgo/go/net/sendfile_dragonfly.go
+++ b/third_party/gofrontend/libgo/go/net/sendfile_dragonfly.go
@@ -91,13 +91,16 @@
 		if err1 != nil {
 			// This includes syscall.ENOSYS (no kernel
 			// support) and syscall.EINVAL (fd types which
-			// don't implement sendfile together)
-			err = &OpError{"sendfile", c.net, c.raddr, err1}
+			// don't implement sendfile)
+			err = err1
 			break
 		}
 	}
 	if lr != nil {
 		lr.N = remain
 	}
+	if err != nil {
+		err = os.NewSyscallError("sendfile", err)
+	}
 	return written, err, written > 0
 }
diff --git a/third_party/gofrontend/libgo/go/net/sendfile_freebsd.go b/third_party/gofrontend/libgo/go/net/sendfile_freebsd.go
index ffc1472..d0bf603 100644
--- a/third_party/gofrontend/libgo/go/net/sendfile_freebsd.go
+++ b/third_party/gofrontend/libgo/go/net/sendfile_freebsd.go
@@ -91,13 +91,16 @@
 		if err1 != nil {
 			// This includes syscall.ENOSYS (no kernel
 			// support) and syscall.EINVAL (fd types which
-			// don't implement sendfile together)
-			err = &OpError{"sendfile", c.net, c.raddr, err1}
+			// don't implement sendfile)
+			err = err1
 			break
 		}
 	}
 	if lr != nil {
 		lr.N = remain
 	}
+	if err != nil {
+		err = os.NewSyscallError("sendfile", err)
+	}
 	return written, err, written > 0
 }
diff --git a/third_party/gofrontend/libgo/go/net/sendfile_linux.go b/third_party/gofrontend/libgo/go/net/sendfile_linux.go
index 5e11763..5ca41c3 100644
--- a/third_party/gofrontend/libgo/go/net/sendfile_linux.go
+++ b/third_party/gofrontend/libgo/go/net/sendfile_linux.go
@@ -64,13 +64,16 @@
 		if err1 != nil {
 			// This includes syscall.ENOSYS (no kernel
 			// support) and syscall.EINVAL (fd types which
-			// don't implement sendfile together)
-			err = &OpError{"sendfile", c.net, c.raddr, err1}
+			// don't implement sendfile)
+			err = err1
 			break
 		}
 	}
 	if lr != nil {
 		lr.N = remain
 	}
+	if err != nil {
+		err = os.NewSyscallError("sendfile", err)
+	}
 	return written, err, written > 0
 }
diff --git a/third_party/gofrontend/libgo/go/net/sendfile_solaris.go b/third_party/gofrontend/libgo/go/net/sendfile_solaris.go
new file mode 100644
index 0000000..0966575
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/net/sendfile_solaris.go
@@ -0,0 +1,110 @@
+// 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 net
+
+import (
+	"io"
+	"os"
+	"syscall"
+)
+
+// Not strictly needed, but very helpful for debugging, see issue #10221.
+//go:cgo_import_dynamic _ _ "libsendfile.so"
+//go:cgo_import_dynamic _ _ "libsocket.so"
+
+// maxSendfileSize is the largest chunk size we ask the kernel to copy
+// at a time.
+const maxSendfileSize int = 4 << 20
+
+// sendFile copies the contents of r to c using the sendfile
+// system call to minimize copies.
+//
+// if handled == true, sendFile returns the number of bytes copied and any
+// non-EOF error.
+//
+// if handled == false, sendFile performed no work.
+func sendFile(c *netFD, r io.Reader) (written int64, err error, handled bool) {
+	// Solaris uses 0 as the "until EOF" value. If you pass in more bytes than the
+	// file contains, it will loop back to the beginning ad nauseam until it's sent
+	// exactly the number of bytes told to. As such, we need to know exactly how many
+	// bytes to send.
+	var remain int64 = 0
+
+	lr, ok := r.(*io.LimitedReader)
+	if ok {
+		remain, r = lr.N, lr.R
+		if remain <= 0 {
+			return 0, nil, true
+		}
+	}
+	f, ok := r.(*os.File)
+	if !ok {
+		return 0, nil, false
+	}
+
+	if remain == 0 {
+		fi, err := f.Stat()
+		if err != nil {
+			return 0, err, false
+		}
+
+		remain = fi.Size()
+	}
+
+	// The other quirk with Solaris's sendfile implementation is that it doesn't
+	// use the current position of the file -- if you pass it offset 0, it starts
+	// from offset 0. There's no way to tell it "start from current position", so
+	// we have to manage that explicitly.
+	pos, err := f.Seek(0, os.SEEK_CUR)
+	if err != nil {
+		return 0, err, false
+	}
+
+	if err := c.writeLock(); err != nil {
+		return 0, err, true
+	}
+	defer c.writeUnlock()
+
+	dst := c.sysfd
+	src := int(f.Fd())
+	for remain > 0 {
+		n := maxSendfileSize
+		if int64(n) > remain {
+			n = int(remain)
+		}
+		pos1 := pos
+		n, err1 := syscall.Sendfile(dst, src, &pos1, n)
+		if n > 0 {
+			pos += int64(n)
+			written += int64(n)
+			remain -= int64(n)
+		}
+		if n == 0 && err1 == nil {
+			break
+		}
+		if err1 == syscall.EAGAIN {
+			if err1 = c.pd.WaitWrite(); err1 == nil {
+				continue
+			}
+		}
+		if err1 == syscall.EINTR {
+			continue
+		}
+		if err1 != nil {
+			// This includes syscall.ENOSYS (no kernel
+			// support) and syscall.EINVAL (fd types which
+			// don't implement sendfile)
+			err = err1
+			break
+		}
+	}
+	if lr != nil {
+		lr.N = remain
+	}
+	if err != nil {
+		err = os.NewSyscallError("sendfile", err)
+	}
+	return written, err, written > 0
+}
diff --git a/third_party/gofrontend/libgo/go/net/sendfile_stub.go b/third_party/gofrontend/libgo/go/net/sendfile_stub.go
index 03426ef..a0760b4 100644
--- a/third_party/gofrontend/libgo/go/net/sendfile_stub.go
+++ b/third_party/gofrontend/libgo/go/net/sendfile_stub.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 darwin nacl netbsd openbsd solaris
+// +build darwin nacl netbsd openbsd
 
 package net
 
diff --git a/third_party/gofrontend/libgo/go/net/sendfile_windows.go b/third_party/gofrontend/libgo/go/net/sendfile_windows.go
index b128ba2..f3f3b54 100644
--- a/third_party/gofrontend/libgo/go/net/sendfile_windows.go
+++ b/third_party/gofrontend/libgo/go/net/sendfile_windows.go
@@ -46,7 +46,7 @@
 		return syscall.TransmitFile(o.fd.sysfd, o.handle, o.qty, 0, &o.o, nil, syscall.TF_WRITE_BEHIND)
 	})
 	if err != nil {
-		return 0, err, false
+		return 0, os.NewSyscallError("transmitfile", err), false
 	}
 	if lr != nil {
 		lr.N -= int64(done)
diff --git a/third_party/gofrontend/libgo/go/net/server_test.go b/third_party/gofrontend/libgo/go/net/server_test.go
index 6a2bb92..fe0006b 100644
--- a/third_party/gofrontend/libgo/go/net/server_test.go
+++ b/third_party/gofrontend/libgo/go/net/server_test.go
@@ -5,457 +5,384 @@
 package net
 
 import (
-	"flag"
-	"io"
 	"os"
-	"runtime"
 	"testing"
-	"time"
 )
 
-func skipServerTest(net, unixsotype, addr string, ipv6, ipv4map, linuxOnly bool) bool {
-	switch runtime.GOOS {
-	case "linux":
-	case "nacl", "plan9", "windows":
-		// "unix" sockets are not supported on Windows and Plan 9.
-		if net == unixsotype {
-			return true
-		}
-	default:
-		if net == unixsotype && linuxOnly {
-			return true
-		}
-	}
-	switch addr {
-	case "", "0.0.0.0", "[::ffff:0.0.0.0]", "[::]":
-		if testing.Short() || !*testExternal {
-			return true
-		}
-	}
-	if ipv6 && !supportsIPv6 {
-		return true
-	}
-	if ipv4map && !supportsIPv4map {
-		return true
-	}
-	return false
-}
-
-var streamConnServerTests = []struct {
-	snet      string // server side
-	saddr     string
-	cnet      string // client side
-	caddr     string
-	ipv6      bool // test with underlying AF_INET6 socket
-	ipv4map   bool // test with IPv6 IPv4-mapping functionality
-	empty     bool // test with empty data
-	linuxOnly bool // test with abstract unix domain socket, a Linux-ism
+var tcpServerTests = []struct {
+	snet, saddr string // server endpoint
+	tnet, taddr string // target endpoint for client
 }{
-	{snet: "tcp", saddr: "", cnet: "tcp", caddr: "127.0.0.1"},
-	{snet: "tcp", saddr: "0.0.0.0", cnet: "tcp", caddr: "127.0.0.1"},
-	{snet: "tcp", saddr: "[::ffff:0.0.0.0]", cnet: "tcp", caddr: "127.0.0.1"},
-	{snet: "tcp", saddr: "[::]", cnet: "tcp", caddr: "[::1]", ipv6: true},
+	{snet: "tcp", saddr: ":0", tnet: "tcp", taddr: "127.0.0.1"},
+	{snet: "tcp", saddr: "0.0.0.0:0", tnet: "tcp", taddr: "127.0.0.1"},
+	{snet: "tcp", saddr: "[::ffff:0.0.0.0]:0", tnet: "tcp", taddr: "127.0.0.1"},
+	{snet: "tcp", saddr: "[::]:0", tnet: "tcp", taddr: "::1"},
 
-	{snet: "tcp", saddr: "", cnet: "tcp", caddr: "[::1]", ipv4map: true},
-	{snet: "tcp", saddr: "0.0.0.0", cnet: "tcp", caddr: "[::1]", ipv4map: true},
-	{snet: "tcp", saddr: "[::ffff:0.0.0.0]", cnet: "tcp", caddr: "[::1]", ipv4map: true},
-	{snet: "tcp", saddr: "[::]", cnet: "tcp", caddr: "127.0.0.1", ipv4map: true},
+	{snet: "tcp", saddr: ":0", tnet: "tcp", taddr: "::1"},
+	{snet: "tcp", saddr: "0.0.0.0:0", tnet: "tcp", taddr: "::1"},
+	{snet: "tcp", saddr: "[::ffff:0.0.0.0]:0", tnet: "tcp", taddr: "::1"},
+	{snet: "tcp", saddr: "[::]:0", tnet: "tcp", taddr: "127.0.0.1"},
 
-	{snet: "tcp", saddr: "", cnet: "tcp4", caddr: "127.0.0.1"},
-	{snet: "tcp", saddr: "0.0.0.0", cnet: "tcp4", caddr: "127.0.0.1"},
-	{snet: "tcp", saddr: "[::ffff:0.0.0.0]", cnet: "tcp4", caddr: "127.0.0.1"},
-	{snet: "tcp", saddr: "[::]", cnet: "tcp6", caddr: "[::1]", ipv6: true},
+	{snet: "tcp", saddr: ":0", tnet: "tcp4", taddr: "127.0.0.1"},
+	{snet: "tcp", saddr: "0.0.0.0:0", tnet: "tcp4", taddr: "127.0.0.1"},
+	{snet: "tcp", saddr: "[::ffff:0.0.0.0]:0", tnet: "tcp4", taddr: "127.0.0.1"},
+	{snet: "tcp", saddr: "[::]:0", tnet: "tcp6", taddr: "::1"},
 
-	{snet: "tcp", saddr: "", cnet: "tcp6", caddr: "[::1]", ipv4map: true},
-	{snet: "tcp", saddr: "0.0.0.0", cnet: "tcp6", caddr: "[::1]", ipv4map: true},
-	{snet: "tcp", saddr: "[::ffff:0.0.0.0]", cnet: "tcp6", caddr: "[::1]", ipv4map: true},
-	{snet: "tcp", saddr: "[::]", cnet: "tcp4", caddr: "127.0.0.1", ipv4map: true},
+	{snet: "tcp", saddr: ":0", tnet: "tcp6", taddr: "::1"},
+	{snet: "tcp", saddr: "0.0.0.0:0", tnet: "tcp6", taddr: "::1"},
+	{snet: "tcp", saddr: "[::ffff:0.0.0.0]:0", tnet: "tcp6", taddr: "::1"},
+	{snet: "tcp", saddr: "[::]:0", tnet: "tcp4", taddr: "127.0.0.1"},
 
-	{snet: "tcp", saddr: "127.0.0.1", cnet: "tcp", caddr: "127.0.0.1"},
-	{snet: "tcp", saddr: "[::ffff:127.0.0.1]", cnet: "tcp", caddr: "127.0.0.1"},
-	{snet: "tcp", saddr: "[::1]", cnet: "tcp", caddr: "[::1]", ipv6: true},
+	{snet: "tcp", saddr: "127.0.0.1:0", tnet: "tcp", taddr: "127.0.0.1"},
+	{snet: "tcp", saddr: "[::ffff:127.0.0.1]:0", tnet: "tcp", taddr: "127.0.0.1"},
+	{snet: "tcp", saddr: "[::1]:0", tnet: "tcp", taddr: "::1"},
 
-	{snet: "tcp4", saddr: "", cnet: "tcp4", caddr: "127.0.0.1"},
-	{snet: "tcp4", saddr: "0.0.0.0", cnet: "tcp4", caddr: "127.0.0.1"},
-	{snet: "tcp4", saddr: "[::ffff:0.0.0.0]", cnet: "tcp4", caddr: "127.0.0.1"},
+	{snet: "tcp4", saddr: ":0", tnet: "tcp4", taddr: "127.0.0.1"},
+	{snet: "tcp4", saddr: "0.0.0.0:0", tnet: "tcp4", taddr: "127.0.0.1"},
+	{snet: "tcp4", saddr: "[::ffff:0.0.0.0]:0", tnet: "tcp4", taddr: "127.0.0.1"},
 
-	{snet: "tcp4", saddr: "127.0.0.1", cnet: "tcp4", caddr: "127.0.0.1"},
+	{snet: "tcp4", saddr: "127.0.0.1:0", tnet: "tcp4", taddr: "127.0.0.1"},
 
-	{snet: "tcp6", saddr: "", cnet: "tcp6", caddr: "[::1]", ipv6: true},
-	{snet: "tcp6", saddr: "[::]", cnet: "tcp6", caddr: "[::1]", ipv6: true},
+	{snet: "tcp6", saddr: ":0", tnet: "tcp6", taddr: "::1"},
+	{snet: "tcp6", saddr: "[::]:0", tnet: "tcp6", taddr: "::1"},
 
-	{snet: "tcp6", saddr: "[::1]", cnet: "tcp6", caddr: "[::1]", ipv6: true},
-
-	{snet: "unix", saddr: testUnixAddr(), cnet: "unix", caddr: testUnixAddr()},
-	{snet: "unix", saddr: "@gotest2/net", cnet: "unix", caddr: "@gotest2/net.local", linuxOnly: true},
+	{snet: "tcp6", saddr: "[::1]:0", tnet: "tcp6", taddr: "::1"},
 }
 
-func TestStreamConnServer(t *testing.T) {
-	for _, tt := range streamConnServerTests {
-		if skipServerTest(tt.snet, "unix", tt.saddr, tt.ipv6, tt.ipv4map, tt.linuxOnly) {
+// TestTCPServer tests concurrent accept-read-write servers.
+func TestTCPServer(t *testing.T) {
+	const N = 3
+
+	for i, tt := range tcpServerTests {
+		if !testableListenArgs(tt.snet, tt.saddr, tt.taddr) {
+			t.Logf("skipping %s test", tt.snet+" "+tt.saddr+"->"+tt.taddr)
 			continue
 		}
 
-		listening := make(chan string)
-		done := make(chan int)
-		switch tt.snet {
-		case "tcp", "tcp4", "tcp6":
-			tt.saddr += ":0"
-		case "unix":
-			os.Remove(tt.saddr)
-			os.Remove(tt.caddr)
-		}
-
-		go runStreamConnServer(t, tt.snet, tt.saddr, listening, done)
-		taddr := <-listening // wait for server to start
-
-		switch tt.cnet {
-		case "tcp", "tcp4", "tcp6":
-			_, port, err := SplitHostPort(taddr)
-			if err != nil {
-				t.Fatalf("SplitHostPort(%q) failed: %v", taddr, err)
-			}
-			taddr = tt.caddr + ":" + port
-		}
-
-		runStreamConnClient(t, tt.cnet, taddr, tt.empty)
-		<-done // make sure server stopped
-
-		switch tt.snet {
-		case "unix":
-			os.Remove(tt.saddr)
-			os.Remove(tt.caddr)
-		}
-	}
-}
-
-var seqpacketConnServerTests = []struct {
-	net       string
-	saddr     string // server address
-	caddr     string // client address
-	empty     bool   // test with empty data
-	linuxOnly bool   // test with abstract unix domain socket, a Linux-ism
-}{
-	{net: "unixpacket", saddr: testUnixAddr(), caddr: testUnixAddr()},
-	{net: "unixpacket", saddr: "@gotest4/net", caddr: "@gotest4/net.local", linuxOnly: true},
-}
-
-func TestSeqpacketConnServer(t *testing.T) {
-	switch runtime.GOOS {
-	case "darwin", "nacl", "openbsd", "plan9", "windows":
-		fallthrough
-	case "freebsd": // FreeBSD 8 doesn't support unixpacket
-		t.Skipf("skipping test on %q", runtime.GOOS)
-	}
-
-	for _, tt := range seqpacketConnServerTests {
-		if runtime.GOOS != "linux" && tt.linuxOnly {
-			continue
-		}
-		listening := make(chan string)
-		done := make(chan int)
-		switch tt.net {
-		case "unixpacket":
-			os.Remove(tt.saddr)
-			os.Remove(tt.caddr)
-		}
-
-		go runStreamConnServer(t, tt.net, tt.saddr, listening, done)
-		taddr := <-listening // wait for server to start
-
-		runStreamConnClient(t, tt.net, taddr, tt.empty)
-		<-done // make sure server stopped
-
-		switch tt.net {
-		case "unixpacket":
-			os.Remove(tt.saddr)
-			os.Remove(tt.caddr)
-		}
-	}
-}
-
-func runStreamConnServer(t *testing.T, net, laddr string, listening chan<- string, done chan<- int) {
-	defer close(done)
-	l, err := Listen(net, laddr)
-	if err != nil {
-		t.Errorf("Listen(%q, %q) failed: %v", net, laddr, err)
-		listening <- "<nil>"
-		return
-	}
-	defer l.Close()
-	listening <- l.Addr().String()
-
-	echo := func(rw io.ReadWriter, done chan<- int) {
-		buf := make([]byte, 1024)
-		for {
-			n, err := rw.Read(buf[0:])
-			if err != nil || n == 0 || string(buf[:n]) == "END" {
-				break
-			}
-			rw.Write(buf[0:n])
-		}
-		close(done)
-	}
-
-run:
-	for {
-		c, err := l.Accept()
+		ln, err := Listen(tt.snet, tt.saddr)
 		if err != nil {
-			t.Logf("Accept failed: %v", err)
-			continue run
+			if perr := parseDialError(err); perr != nil {
+				t.Error(perr)
+			}
+			t.Fatal(err)
 		}
-		echodone := make(chan int)
-		go echo(c, echodone)
-		<-echodone // make sure echo stopped
-		c.Close()
-		break run
+
+		var lss []*localServer
+		var tpchs []chan error
+		defer func() {
+			for _, ls := range lss {
+				ls.teardown()
+			}
+		}()
+		for i := 0; i < N; i++ {
+			ls, err := (&streamListener{Listener: ln}).newLocalServer()
+			if err != nil {
+				t.Fatal(err)
+			}
+			lss = append(lss, ls)
+			tpchs = append(tpchs, make(chan error, 1))
+		}
+		for i := 0; i < N; i++ {
+			ch := tpchs[i]
+			handler := func(ls *localServer, ln Listener) { transponder(ln, ch) }
+			if err := lss[i].buildup(handler); err != nil {
+				t.Fatal(err)
+			}
+		}
+
+		var trchs []chan error
+		for i := 0; i < N; i++ {
+			_, port, err := SplitHostPort(lss[i].Listener.Addr().String())
+			if err != nil {
+				t.Fatal(err)
+			}
+			d := Dialer{Timeout: someTimeout}
+			c, err := d.Dial(tt.tnet, JoinHostPort(tt.taddr, port))
+			if err != nil {
+				if perr := parseDialError(err); perr != nil {
+					t.Error(perr)
+				}
+				t.Fatal(err)
+			}
+			defer c.Close()
+			trchs = append(trchs, make(chan error, 1))
+			go transceiver(c, []byte("TCP SERVER TEST"), trchs[i])
+		}
+
+		for _, ch := range trchs {
+			for err := range ch {
+				t.Errorf("#%d: %v", i, err)
+			}
+		}
+		for _, ch := range tpchs {
+			for err := range ch {
+				t.Errorf("#%d: %v", i, err)
+			}
+		}
 	}
 }
 
-func runStreamConnClient(t *testing.T, net, taddr string, isEmpty bool) {
-	c, err := Dial(net, taddr)
-	if err != nil {
-		t.Fatalf("Dial(%q, %q) failed: %v", net, taddr, err)
-	}
-	defer c.Close()
-	c.SetReadDeadline(time.Now().Add(1 * time.Second))
-
-	var wb []byte
-	if !isEmpty {
-		wb = []byte("StreamConnClient by Dial\n")
-	}
-	if n, err := c.Write(wb); err != nil || n != len(wb) {
-		t.Fatalf("Write failed: %v, %v; want %v, <nil>", n, err, len(wb))
-	}
-
-	rb := make([]byte, 1024)
-	if n, err := c.Read(rb[0:]); err != nil || n != len(wb) {
-		t.Fatalf("Read failed: %v, %v; want %v, <nil>", n, err, len(wb))
-	}
-
-	// Send explicit ending for unixpacket.
-	// Older Linux kernels do not stop reads on close.
-	switch net {
-	case "unixpacket":
-		c.Write([]byte("END"))
-	}
-}
-
-// Do not test empty datagrams by default.
-// It causes unexplained timeouts on some systems,
-// including Snow Leopard.  I think that the kernel
-// doesn't quite expect them.
-var testDatagram = flag.Bool("datagram", false, "whether to test udp and unixgram")
-
-var datagramPacketConnServerTests = []struct {
-	snet      string // server side
-	saddr     string
-	cnet      string // client side
-	caddr     string
-	ipv6      bool // test with underlying AF_INET6 socket
-	ipv4map   bool // test with IPv6 IPv4-mapping functionality
-	dial      bool // test with Dial or DialUnix
-	empty     bool // test with empty data
-	linuxOnly bool // test with abstract unix domain socket, a Linux-ism
+var unixAndUnixpacketServerTests = []struct {
+	network, address string
 }{
-	{snet: "udp", saddr: "", cnet: "udp", caddr: "127.0.0.1"},
-	{snet: "udp", saddr: "0.0.0.0", cnet: "udp", caddr: "127.0.0.1"},
-	{snet: "udp", saddr: "[::ffff:0.0.0.0]", cnet: "udp", caddr: "127.0.0.1"},
-	{snet: "udp", saddr: "[::]", cnet: "udp", caddr: "[::1]", ipv6: true},
+	{"unix", testUnixAddr()},
+	{"unix", "@nettest/go/unix"},
 
-	{snet: "udp", saddr: "", cnet: "udp", caddr: "[::1]", ipv4map: true},
-	{snet: "udp", saddr: "0.0.0.0", cnet: "udp", caddr: "[::1]", ipv4map: true},
-	{snet: "udp", saddr: "[::ffff:0.0.0.0]", cnet: "udp", caddr: "[::1]", ipv4map: true},
-	{snet: "udp", saddr: "[::]", cnet: "udp", caddr: "127.0.0.1", ipv4map: true},
-
-	{snet: "udp", saddr: "", cnet: "udp4", caddr: "127.0.0.1"},
-	{snet: "udp", saddr: "0.0.0.0", cnet: "udp4", caddr: "127.0.0.1"},
-	{snet: "udp", saddr: "[::ffff:0.0.0.0]", cnet: "udp4", caddr: "127.0.0.1"},
-	{snet: "udp", saddr: "[::]", cnet: "udp6", caddr: "[::1]", ipv6: true},
-
-	{snet: "udp", saddr: "", cnet: "udp6", caddr: "[::1]", ipv4map: true},
-	{snet: "udp", saddr: "0.0.0.0", cnet: "udp6", caddr: "[::1]", ipv4map: true},
-	{snet: "udp", saddr: "[::ffff:0.0.0.0]", cnet: "udp6", caddr: "[::1]", ipv4map: true},
-	{snet: "udp", saddr: "[::]", cnet: "udp4", caddr: "127.0.0.1", ipv4map: true},
-
-	{snet: "udp", saddr: "127.0.0.1", cnet: "udp", caddr: "127.0.0.1"},
-	{snet: "udp", saddr: "[::ffff:127.0.0.1]", cnet: "udp", caddr: "127.0.0.1"},
-	{snet: "udp", saddr: "[::1]", cnet: "udp", caddr: "[::1]", ipv6: true},
-
-	{snet: "udp4", saddr: "", cnet: "udp4", caddr: "127.0.0.1"},
-	{snet: "udp4", saddr: "0.0.0.0", cnet: "udp4", caddr: "127.0.0.1"},
-	{snet: "udp4", saddr: "[::ffff:0.0.0.0]", cnet: "udp4", caddr: "127.0.0.1"},
-
-	{snet: "udp4", saddr: "127.0.0.1", cnet: "udp4", caddr: "127.0.0.1"},
-
-	{snet: "udp6", saddr: "", cnet: "udp6", caddr: "[::1]", ipv6: true},
-	{snet: "udp6", saddr: "[::]", cnet: "udp6", caddr: "[::1]", ipv6: true},
-
-	{snet: "udp6", saddr: "[::1]", cnet: "udp6", caddr: "[::1]", ipv6: true},
-
-	{snet: "udp", saddr: "127.0.0.1", cnet: "udp", caddr: "127.0.0.1", dial: true},
-	{snet: "udp", saddr: "127.0.0.1", cnet: "udp", caddr: "127.0.0.1", empty: true},
-	{snet: "udp", saddr: "127.0.0.1", cnet: "udp", caddr: "127.0.0.1", dial: true, empty: true},
-
-	{snet: "udp", saddr: "[::1]", cnet: "udp", caddr: "[::1]", ipv6: true, dial: true},
-	{snet: "udp", saddr: "[::1]", cnet: "udp", caddr: "[::1]", ipv6: true, empty: true},
-	{snet: "udp", saddr: "[::1]", cnet: "udp", caddr: "[::1]", ipv6: true, dial: true, empty: true},
-
-	{snet: "unixgram", saddr: testUnixAddr(), cnet: "unixgram", caddr: testUnixAddr()},
-	{snet: "unixgram", saddr: testUnixAddr(), cnet: "unixgram", caddr: testUnixAddr(), dial: true},
-	{snet: "unixgram", saddr: testUnixAddr(), cnet: "unixgram", caddr: testUnixAddr(), empty: true},
-	{snet: "unixgram", saddr: testUnixAddr(), cnet: "unixgram", caddr: testUnixAddr(), dial: true, empty: true},
-
-	{snet: "unixgram", saddr: "@gotest6/net", cnet: "unixgram", caddr: "@gotest6/net.local", linuxOnly: true},
+	{"unixpacket", testUnixAddr()},
+	{"unixpacket", "@nettest/go/unixpacket"},
 }
 
-func TestDatagramPacketConnServer(t *testing.T) {
-	if !*testDatagram {
-		return
-	}
+// TestUnixAndUnixpacketServer tests concurrent accept-read-write
+// servers
+func TestUnixAndUnixpacketServer(t *testing.T) {
+	const N = 3
 
-	for _, tt := range datagramPacketConnServerTests {
-		if skipServerTest(tt.snet, "unixgram", tt.saddr, tt.ipv6, tt.ipv4map, tt.linuxOnly) {
+	for i, tt := range unixAndUnixpacketServerTests {
+		if !testableListenArgs(tt.network, tt.address, "") {
+			t.Logf("skipping %s test", tt.network+" "+tt.address)
 			continue
 		}
 
-		listening := make(chan string)
-		done := make(chan int)
-		switch tt.snet {
-		case "udp", "udp4", "udp6":
-			tt.saddr += ":0"
-		case "unixgram":
-			os.Remove(tt.saddr)
-			os.Remove(tt.caddr)
+		ln, err := Listen(tt.network, tt.address)
+		if err != nil {
+			if perr := parseDialError(err); perr != nil {
+				t.Error(perr)
+			}
+			t.Fatal(err)
 		}
 
-		go runDatagramPacketConnServer(t, tt.snet, tt.saddr, listening, done)
-		taddr := <-listening // wait for server to start
-
-		switch tt.cnet {
-		case "udp", "udp4", "udp6":
-			_, port, err := SplitHostPort(taddr)
-			if err != nil {
-				t.Fatalf("SplitHostPort(%q) failed: %v", taddr, err)
+		var lss []*localServer
+		var tpchs []chan error
+		defer func() {
+			for _, ls := range lss {
+				ls.teardown()
 			}
-			taddr = tt.caddr + ":" + port
-			tt.caddr += ":0"
+		}()
+		for i := 0; i < N; i++ {
+			ls, err := (&streamListener{Listener: ln}).newLocalServer()
+			if err != nil {
+				t.Fatal(err)
+			}
+			lss = append(lss, ls)
+			tpchs = append(tpchs, make(chan error, 1))
+		}
+		for i := 0; i < N; i++ {
+			ch := tpchs[i]
+			handler := func(ls *localServer, ln Listener) { transponder(ln, ch) }
+			if err := lss[i].buildup(handler); err != nil {
+				t.Fatal(err)
+			}
+		}
+
+		var trchs []chan error
+		for i := 0; i < N; i++ {
+			d := Dialer{Timeout: someTimeout}
+			c, err := d.Dial(lss[i].Listener.Addr().Network(), lss[i].Listener.Addr().String())
+			if err != nil {
+				if perr := parseDialError(err); perr != nil {
+					t.Error(perr)
+				}
+				t.Fatal(err)
+			}
+			defer os.Remove(c.LocalAddr().String())
+			defer c.Close()
+			trchs = append(trchs, make(chan error, 1))
+			go transceiver(c, []byte("UNIX AND UNIXPACKET SERVER TEST"), trchs[i])
+		}
+
+		for _, ch := range trchs {
+			for err := range ch {
+				t.Errorf("#%d: %v", i, err)
+			}
+		}
+		for _, ch := range tpchs {
+			for err := range ch {
+				t.Errorf("#%d: %v", i, err)
+			}
+		}
+	}
+}
+
+var udpServerTests = []struct {
+	snet, saddr string // server endpoint
+	tnet, taddr string // target endpoint for client
+	dial        bool   // test with Dial
+}{
+	{snet: "udp", saddr: ":0", tnet: "udp", taddr: "127.0.0.1"},
+	{snet: "udp", saddr: "0.0.0.0:0", tnet: "udp", taddr: "127.0.0.1"},
+	{snet: "udp", saddr: "[::ffff:0.0.0.0]:0", tnet: "udp", taddr: "127.0.0.1"},
+	{snet: "udp", saddr: "[::]:0", tnet: "udp", taddr: "::1"},
+
+	{snet: "udp", saddr: ":0", tnet: "udp", taddr: "::1"},
+	{snet: "udp", saddr: "0.0.0.0:0", tnet: "udp", taddr: "::1"},
+	{snet: "udp", saddr: "[::ffff:0.0.0.0]:0", tnet: "udp", taddr: "::1"},
+	{snet: "udp", saddr: "[::]:0", tnet: "udp", taddr: "127.0.0.1"},
+
+	{snet: "udp", saddr: ":0", tnet: "udp4", taddr: "127.0.0.1"},
+	{snet: "udp", saddr: "0.0.0.0:0", tnet: "udp4", taddr: "127.0.0.1"},
+	{snet: "udp", saddr: "[::ffff:0.0.0.0]:0", tnet: "udp4", taddr: "127.0.0.1"},
+	{snet: "udp", saddr: "[::]:0", tnet: "udp6", taddr: "::1"},
+
+	{snet: "udp", saddr: ":0", tnet: "udp6", taddr: "::1"},
+	{snet: "udp", saddr: "0.0.0.0:0", tnet: "udp6", taddr: "::1"},
+	{snet: "udp", saddr: "[::ffff:0.0.0.0]:0", tnet: "udp6", taddr: "::1"},
+	{snet: "udp", saddr: "[::]:0", tnet: "udp4", taddr: "127.0.0.1"},
+
+	{snet: "udp", saddr: "127.0.0.1:0", tnet: "udp", taddr: "127.0.0.1"},
+	{snet: "udp", saddr: "[::ffff:127.0.0.1]:0", tnet: "udp", taddr: "127.0.0.1"},
+	{snet: "udp", saddr: "[::1]:0", tnet: "udp", taddr: "::1"},
+
+	{snet: "udp4", saddr: ":0", tnet: "udp4", taddr: "127.0.0.1"},
+	{snet: "udp4", saddr: "0.0.0.0:0", tnet: "udp4", taddr: "127.0.0.1"},
+	{snet: "udp4", saddr: "[::ffff:0.0.0.0]:0", tnet: "udp4", taddr: "127.0.0.1"},
+
+	{snet: "udp4", saddr: "127.0.0.1:0", tnet: "udp4", taddr: "127.0.0.1"},
+
+	{snet: "udp6", saddr: ":0", tnet: "udp6", taddr: "::1"},
+	{snet: "udp6", saddr: "[::]:0", tnet: "udp6", taddr: "::1"},
+
+	{snet: "udp6", saddr: "[::1]:0", tnet: "udp6", taddr: "::1"},
+
+	{snet: "udp", saddr: "127.0.0.1:0", tnet: "udp", taddr: "127.0.0.1", dial: true},
+
+	{snet: "udp", saddr: "[::1]:0", tnet: "udp", taddr: "::1", dial: true},
+}
+
+func TestUDPServer(t *testing.T) {
+	for i, tt := range udpServerTests {
+		if !testableListenArgs(tt.snet, tt.saddr, tt.taddr) {
+			t.Logf("skipping %s test", tt.snet+" "+tt.saddr+"->"+tt.taddr)
+			continue
+		}
+
+		c1, err := ListenPacket(tt.snet, tt.saddr)
+		if err != nil {
+			if perr := parseDialError(err); perr != nil {
+				t.Error(perr)
+			}
+			t.Fatal(err)
+		}
+
+		ls, err := (&packetListener{PacketConn: c1}).newLocalServer()
+		if err != nil {
+			t.Fatal(err)
+		}
+		defer ls.teardown()
+		tpch := make(chan error, 1)
+		handler := func(ls *localPacketServer, c PacketConn) { packetTransponder(c, tpch) }
+		if err := ls.buildup(handler); err != nil {
+			t.Fatal(err)
+		}
+
+		trch := make(chan error, 1)
+		_, port, err := SplitHostPort(ls.PacketConn.LocalAddr().String())
+		if err != nil {
+			t.Fatal(err)
 		}
 		if tt.dial {
-			runDatagramConnClient(t, tt.cnet, tt.caddr, taddr, tt.empty)
-		} else {
-			runDatagramPacketConnClient(t, tt.cnet, tt.caddr, taddr, tt.empty)
-		}
-		<-done // tell server to stop
-		<-done // make sure server stopped
-
-		switch tt.snet {
-		case "unixgram":
-			os.Remove(tt.saddr)
-			os.Remove(tt.caddr)
-		}
-	}
-}
-
-func runDatagramPacketConnServer(t *testing.T, net, laddr string, listening chan<- string, done chan<- int) {
-	c, err := ListenPacket(net, laddr)
-	if err != nil {
-		t.Errorf("ListenPacket(%q, %q) failed: %v", net, laddr, err)
-		listening <- "<nil>"
-		done <- 1
-		return
-	}
-	defer c.Close()
-	listening <- c.LocalAddr().String()
-
-	buf := make([]byte, 1024)
-run:
-	for {
-		c.SetReadDeadline(time.Now().Add(10 * time.Millisecond))
-		n, ra, err := c.ReadFrom(buf[0:])
-		if nerr, ok := err.(Error); ok && nerr.Timeout() {
-			select {
-			case done <- 1:
-				break run
-			default:
-				continue run
+			d := Dialer{Timeout: someTimeout}
+			c2, err := d.Dial(tt.tnet, JoinHostPort(tt.taddr, port))
+			if err != nil {
+				if perr := parseDialError(err); perr != nil {
+					t.Error(perr)
+				}
+				t.Fatal(err)
 			}
+			defer c2.Close()
+			go transceiver(c2, []byte("UDP SERVER TEST"), trch)
+		} else {
+			c2, err := ListenPacket(tt.tnet, JoinHostPort(tt.taddr, "0"))
+			if err != nil {
+				if perr := parseDialError(err); perr != nil {
+					t.Error(perr)
+				}
+				t.Fatal(err)
+			}
+			defer c2.Close()
+			dst, err := ResolveUDPAddr(tt.tnet, JoinHostPort(tt.taddr, port))
+			if err != nil {
+				t.Fatal(err)
+			}
+			go packetTransceiver(c2, []byte("UDP SERVER TEST"), dst, trch)
 		}
-		if err != nil {
-			break run
-		}
-		if _, err = c.WriteTo(buf[0:n], ra); err != nil {
-			t.Errorf("WriteTo(%v) failed: %v", ra, err)
-			break run
-		}
-	}
-	done <- 1
-}
 
-func runDatagramConnClient(t *testing.T, net, laddr, taddr string, isEmpty bool) {
-	var c Conn
-	var err error
-	switch net {
-	case "udp", "udp4", "udp6":
-		c, err = Dial(net, taddr)
-		if err != nil {
-			t.Fatalf("Dial(%q, %q) failed: %v", net, taddr, err)
+		for err := range trch {
+			t.Errorf("#%d: %v", i, err)
 		}
-	case "unixgram":
-		c, err = DialUnix(net, &UnixAddr{Name: laddr, Net: net}, &UnixAddr{Name: taddr, Net: net})
-		if err != nil {
-			t.Fatalf("DialUnix(%q, {%q, %q}) failed: %v", net, laddr, taddr, err)
+		for err := range tpch {
+			t.Errorf("#%d: %v", i, err)
 		}
 	}
-	defer c.Close()
-	c.SetReadDeadline(time.Now().Add(1 * time.Second))
-
-	var wb []byte
-	if !isEmpty {
-		wb = []byte("DatagramConnClient by Dial\n")
-	}
-	if n, err := c.Write(wb[0:]); err != nil || n != len(wb) {
-		t.Fatalf("Write failed: %v, %v; want %v, <nil>", n, err, len(wb))
-	}
-
-	rb := make([]byte, 1024)
-	if n, err := c.Read(rb[0:]); err != nil || n != len(wb) {
-		t.Fatalf("Read failed: %v, %v; want %v, <nil>", n, err, len(wb))
-	}
 }
 
-func runDatagramPacketConnClient(t *testing.T, net, laddr, taddr string, isEmpty bool) {
-	var ra Addr
-	var err error
-	switch net {
-	case "udp", "udp4", "udp6":
-		ra, err = ResolveUDPAddr(net, taddr)
-		if err != nil {
-			t.Fatalf("ResolveUDPAddr(%q, %q) failed: %v", net, taddr, err)
-		}
-	case "unixgram":
-		ra, err = ResolveUnixAddr(net, taddr)
-		if err != nil {
-			t.Fatalf("ResolveUxixAddr(%q, %q) failed: %v", net, taddr, err)
-		}
-	}
-	c, err := ListenPacket(net, laddr)
-	if err != nil {
-		t.Fatalf("ListenPacket(%q, %q) faild: %v", net, laddr, err)
-	}
-	defer c.Close()
-	c.SetReadDeadline(time.Now().Add(1 * time.Second))
+var unixgramServerTests = []struct {
+	saddr string // server endpoint
+	caddr string // client endpoint
+	dial  bool   // test with Dial
+}{
+	{saddr: testUnixAddr(), caddr: testUnixAddr()},
+	{saddr: testUnixAddr(), caddr: testUnixAddr(), dial: true},
 
-	var wb []byte
-	if !isEmpty {
-		wb = []byte("DatagramPacketConnClient by ListenPacket\n")
-	}
-	if n, err := c.WriteTo(wb[0:], ra); err != nil || n != len(wb) {
-		t.Fatalf("WriteTo(%v) failed: %v, %v; want %v, <nil>", ra, n, err, len(wb))
-	}
+	{saddr: "@nettest/go/unixgram/server", caddr: "@nettest/go/unixgram/client"},
+}
 
-	rb := make([]byte, 1024)
-	if n, _, err := c.ReadFrom(rb[0:]); err != nil || n != len(wb) {
-		t.Fatalf("ReadFrom failed: %v, %v; want %v, <nil>", n, err, len(wb))
+func TestUnixgramServer(t *testing.T) {
+	for i, tt := range unixgramServerTests {
+		if !testableListenArgs("unixgram", tt.saddr, "") {
+			t.Logf("skipping %s test", "unixgram "+tt.saddr+"->"+tt.caddr)
+			continue
+		}
+
+		c1, err := ListenPacket("unixgram", tt.saddr)
+		if err != nil {
+			if perr := parseDialError(err); perr != nil {
+				t.Error(perr)
+			}
+			t.Fatal(err)
+		}
+
+		ls, err := (&packetListener{PacketConn: c1}).newLocalServer()
+		if err != nil {
+			t.Fatal(err)
+		}
+		defer ls.teardown()
+		tpch := make(chan error, 1)
+		handler := func(ls *localPacketServer, c PacketConn) { packetTransponder(c, tpch) }
+		if err := ls.buildup(handler); err != nil {
+			t.Fatal(err)
+		}
+
+		trch := make(chan error, 1)
+		if tt.dial {
+			d := Dialer{Timeout: someTimeout, LocalAddr: &UnixAddr{Net: "unixgram", Name: tt.caddr}}
+			c2, err := d.Dial("unixgram", ls.PacketConn.LocalAddr().String())
+			if err != nil {
+				if perr := parseDialError(err); perr != nil {
+					t.Error(perr)
+				}
+				t.Fatal(err)
+			}
+			defer os.Remove(c2.LocalAddr().String())
+			defer c2.Close()
+			go transceiver(c2, []byte(c2.LocalAddr().String()), trch)
+		} else {
+			c2, err := ListenPacket("unixgram", tt.caddr)
+			if err != nil {
+				if perr := parseDialError(err); perr != nil {
+					t.Error(perr)
+				}
+				t.Fatal(err)
+			}
+			defer os.Remove(c2.LocalAddr().String())
+			defer c2.Close()
+			go packetTransceiver(c2, []byte("UNIXGRAM SERVER TEST"), ls.PacketConn.LocalAddr(), trch)
+		}
+
+		for err := range trch {
+			t.Errorf("#%d: %v", i, err)
+		}
+		for err := range tpch {
+			t.Errorf("#%d: %v", i, err)
+		}
 	}
 }
diff --git a/third_party/gofrontend/libgo/go/net/smtp/smtp.go b/third_party/gofrontend/libgo/go/net/smtp/smtp.go
index 87dea44..0988350 100644
--- a/third_party/gofrontend/libgo/go/net/smtp/smtp.go
+++ b/third_party/gofrontend/libgo/go/net/smtp/smtp.go
@@ -41,7 +41,7 @@
 }
 
 // Dial returns a new Client connected to an SMTP server at addr.
-// The addr must include a port number.
+// The addr must include a port, as in "mail.example.com:smtp".
 func Dial(addr string) (*Client, error) {
 	conn, err := net.Dial("tcp", addr)
 	if err != nil {
@@ -157,6 +157,17 @@
 	return c.ehlo()
 }
 
+// TLSConnectionState returns the client's TLS connection state.
+// The return values are their zero values if StartTLS did
+// not succeed.
+func (c *Client) TLSConnectionState() (state tls.ConnectionState, ok bool) {
+	tc, ok := c.conn.(*tls.Conn)
+	if !ok {
+		return
+	}
+	return tc.ConnectionState(), true
+}
+
 // Verify checks the validity of an email address on the server.
 // If Verify returns nil, the address is valid. A non-nil return
 // does not necessarily indicate an invalid address. Many servers
@@ -253,9 +264,9 @@
 }
 
 // Data issues a DATA command to the server and returns a writer that
-// can be used to write the data. The caller should close the writer
-// before calling any more methods on c.
-// A call to Data must be preceded by one or more calls to Rcpt.
+// can be used to write the mail headers and body. The caller should
+// close the writer before calling any more methods on c.  A call to
+// Data must be preceded by one or more calls to Rcpt.
 func (c *Client) Data() (io.WriteCloser, error) {
 	_, _, err := c.cmd(354, "DATA")
 	if err != nil {
@@ -270,6 +281,22 @@
 // possible, authenticates with the optional mechanism a if possible,
 // and then sends an email from address from, to addresses to, with
 // message msg.
+// The addr must include a port, as in "mail.example.com:smtp".
+//
+// The addresses in the to parameter are the SMTP RCPT addresses.
+//
+// The msg parameter should be an RFC 822-style email with headers
+// first, a blank line, and then the message body. The lines of msg
+// should be CRLF terminated.  The msg headers should usually include
+// fields such as "From", "To", "Subject", and "Cc".  Sending "Bcc"
+// messages is accomplished by including an email address in the to
+// parameter but not including it in the msg headers.
+//
+// The SendMail function and the the net/smtp package are low-level
+// mechanisms and provide no support for DKIM signing, MIME
+// attachments (see the mime/multipart package), or other mail
+// functionality. Higher-level packages exist outside of the standard
+// library.
 func SendMail(addr string, a Auth, from string, to []string, msg []byte) error {
 	c, err := Dial(addr)
 	if err != nil {
diff --git a/third_party/gofrontend/libgo/go/net/smtp/smtp_test.go b/third_party/gofrontend/libgo/go/net/smtp/smtp_test.go
index 5c659e8..3ae0d5b 100644
--- a/third_party/gofrontend/libgo/go/net/smtp/smtp_test.go
+++ b/third_party/gofrontend/libgo/go/net/smtp/smtp_test.go
@@ -571,6 +571,50 @@
 	}
 }
 
+func TestTLSConnState(t *testing.T) {
+	ln := newLocalListener(t)
+	defer ln.Close()
+	clientDone := make(chan bool)
+	serverDone := make(chan bool)
+	go func() {
+		defer close(serverDone)
+		c, err := ln.Accept()
+		if err != nil {
+			t.Errorf("Server accept: %v", err)
+			return
+		}
+		defer c.Close()
+		if err := serverHandle(c, t); err != nil {
+			t.Errorf("server error: %v", err)
+		}
+	}()
+	go func() {
+		defer close(clientDone)
+		c, err := Dial(ln.Addr().String())
+		if err != nil {
+			t.Errorf("Client dial: %v", err)
+			return
+		}
+		defer c.Quit()
+		cfg := &tls.Config{ServerName: "example.com"}
+		testHookStartTLS(cfg) // set the RootCAs
+		if err := c.StartTLS(cfg); err != nil {
+			t.Errorf("StartTLS: %v", err)
+			return
+		}
+		cs, ok := c.TLSConnectionState()
+		if !ok {
+			t.Errorf("TLSConnectionState returned ok == false; want true")
+			return
+		}
+		if cs.Version == 0 || !cs.HandshakeComplete {
+			t.Errorf("ConnectionState = %#v; expect non-zero Version and HandshakeComplete", cs)
+		}
+	}()
+	<-clientDone
+	<-serverDone
+}
+
 func newLocalListener(t *testing.T) net.Listener {
 	ln, err := net.Listen("tcp", "127.0.0.1:0")
 	if err != nil {
diff --git a/third_party/gofrontend/libgo/go/net/sock_cloexec.go b/third_party/gofrontend/libgo/go/net/sock_cloexec.go
index dec8185..616a101 100644
--- a/third_party/gofrontend/libgo/go/net/sock_cloexec.go
+++ b/third_party/gofrontend/libgo/go/net/sock_cloexec.go
@@ -9,34 +9,41 @@
 
 package net
 
-import "syscall"
+import (
+	"os"
+	"syscall"
+)
 
 // Wrapper around the socket system call that marks the returned file
 // descriptor as nonblocking and close-on-exec.
 func sysSocket(family, sotype, proto int) (int, error) {
-	s, err := syscall.Socket(family, sotype|syscall.SOCK_NONBLOCK|syscall.SOCK_CLOEXEC, proto)
+	s, err := socketFunc(family, sotype|syscall.SOCK_NONBLOCK|syscall.SOCK_CLOEXEC, proto)
 	// On Linux the SOCK_NONBLOCK and SOCK_CLOEXEC flags were
 	// introduced in 2.6.27 kernel and on FreeBSD both flags were
 	// introduced in 10 kernel. If we get an EINVAL error on Linux
 	// or EPROTONOSUPPORT error on FreeBSD, fall back to using
 	// socket without them.
-	if err == nil || (err != syscall.EPROTONOSUPPORT && err != syscall.EINVAL) {
-		return s, err
+	switch err {
+	case nil:
+		return s, nil
+	default:
+		return -1, os.NewSyscallError("socket", err)
+	case syscall.EPROTONOSUPPORT, syscall.EINVAL:
 	}
 
 	// See ../syscall/exec_unix.go for description of ForkLock.
 	syscall.ForkLock.RLock()
-	s, err = syscall.Socket(family, sotype, proto)
+	s, err = socketFunc(family, sotype, proto)
 	if err == nil {
 		syscall.CloseOnExec(s)
 	}
 	syscall.ForkLock.RUnlock()
 	if err != nil {
-		return -1, err
+		return -1, os.NewSyscallError("socket", err)
 	}
 	if err = syscall.SetNonblock(s, true); err != nil {
-		syscall.Close(s)
-		return -1, err
+		closeFunc(s)
+		return -1, os.NewSyscallError("setnonblock", err)
 	}
 	return s, nil
 }
@@ -44,14 +51,16 @@
 // Wrapper around the accept system call that marks the returned file
 // descriptor as nonblocking and close-on-exec.
 func accept(s int) (int, syscall.Sockaddr, error) {
-	ns, sa, err := syscall.Accept4(s, syscall.SOCK_NONBLOCK|syscall.SOCK_CLOEXEC)
+	ns, sa, err := accept4Func(s, syscall.SOCK_NONBLOCK|syscall.SOCK_CLOEXEC)
 	// On Linux the accept4 system call was introduced in 2.6.28
 	// kernel and on FreeBSD it was introduced in 10 kernel. If we
 	// get an ENOSYS error on both Linux and FreeBSD, or EINVAL
 	// error on Linux, fall back to using accept.
 	switch err {
-	default: // nil and errors other than the ones listed
-		return ns, sa, err
+	case nil:
+		return ns, sa, nil
+	default: // errors other than the ones listed
+		return -1, sa, os.NewSyscallError("accept4", err)
 	case syscall.ENOSYS: // syscall missing
 	case syscall.EINVAL: // some Linux use this instead of ENOSYS
 	case syscall.EACCES: // some Linux use this instead of ENOSYS
@@ -63,16 +72,16 @@
 	// because we have put fd.sysfd into non-blocking mode.
 	// However, a call to the File method will put it back into
 	// blocking mode. We can't take that risk, so no use of ForkLock here.
-	ns, sa, err = syscall.Accept(s)
+	ns, sa, err = acceptFunc(s)
 	if err == nil {
 		syscall.CloseOnExec(ns)
 	}
 	if err != nil {
-		return -1, nil, err
+		return -1, nil, os.NewSyscallError("accept", err)
 	}
 	if err = syscall.SetNonblock(ns, true); err != nil {
-		syscall.Close(ns)
-		return -1, nil, err
+		closeFunc(ns)
+		return -1, nil, os.NewSyscallError("setnonblock", err)
 	}
 	return ns, sa, nil
 }
diff --git a/third_party/gofrontend/libgo/go/net/sock_posix.go b/third_party/gofrontend/libgo/go/net/sock_posix.go
index 3f956df..4d2cfde 100644
--- a/third_party/gofrontend/libgo/go/net/sock_posix.go
+++ b/third_party/gofrontend/libgo/go/net/sock_posix.go
@@ -17,8 +17,6 @@
 type sockaddr interface {
 	Addr
 
-	netaddr
-
 	// family returns the platform-dependent address family
 	// identifier.
 	family() int
@@ -42,11 +40,11 @@
 		return nil, err
 	}
 	if err = setDefaultSockopts(s, family, sotype, ipv6only); err != nil {
-		closesocket(s)
+		closeFunc(s)
 		return nil, err
 	}
 	if fd, err = newFD(s, family, sotype, net); err != nil {
-		closesocket(s)
+		closeFunc(s)
 		return nil, err
 	}
 
@@ -54,7 +52,7 @@
 	// following applications:
 	//
 	// - An endpoint holder that opens a passive stream
-	//   connenction, known as a stream listener
+	//   connection, known as a stream listener
 	//
 	// - An endpoint holder that opens a destination-unspecific
 	//   datagram connection, known as a datagram listener
@@ -165,7 +163,7 @@
 			return os.NewSyscallError("bind", err)
 		}
 	}
-	if err := syscall.Listen(fd.sysfd, backlog); err != nil {
+	if err := listenFunc(fd.sysfd, backlog); err != nil {
 		return os.NewSyscallError("listen", err)
 	}
 	if err := fd.init(); err != nil {
diff --git a/third_party/gofrontend/libgo/go/net/sock_windows.go b/third_party/gofrontend/libgo/go/net/sock_windows.go
index 6ccde3a..888e70b 100644
--- a/third_party/gofrontend/libgo/go/net/sock_windows.go
+++ b/third_party/gofrontend/libgo/go/net/sock_windows.go
@@ -4,7 +4,10 @@
 
 package net
 
-import "syscall"
+import (
+	"os"
+	"syscall"
+)
 
 func maxListenerBacklog() int {
 	// TODO: Implement this
@@ -12,13 +15,16 @@
 	return syscall.SOMAXCONN
 }
 
-func sysSocket(f, t, p int) (syscall.Handle, error) {
+func sysSocket(family, sotype, proto int) (syscall.Handle, error) {
 	// See ../syscall/exec_unix.go for description of ForkLock.
 	syscall.ForkLock.RLock()
-	s, err := syscall.Socket(f, t, p)
+	s, err := socketFunc(family, sotype, proto)
 	if err == nil {
 		syscall.CloseOnExec(s)
 	}
 	syscall.ForkLock.RUnlock()
-	return s, err
+	if err != nil {
+		return syscall.InvalidHandle, os.NewSyscallError("socket", err)
+	}
+	return s, nil
 }
diff --git a/third_party/gofrontend/libgo/go/net/sockopt_bsd.go b/third_party/gofrontend/libgo/go/net/sockopt_bsd.go
index d5b3621..52b2a5d 100644
--- a/third_party/gofrontend/libgo/go/net/sockopt_bsd.go
+++ b/third_party/gofrontend/libgo/go/net/sockopt_bsd.go
@@ -25,7 +25,7 @@
 			syscall.SetsockoptInt(s, syscall.IPPROTO_IPV6, syscall.IPV6_PORTRANGE, syscall.IPV6_PORTRANGE_HIGH)
 		}
 	}
-	if family == syscall.AF_INET6 && sotype != syscall.SOCK_RAW {
+	if supportsIPv4map && family == syscall.AF_INET6 && sotype != syscall.SOCK_RAW {
 		// Allow both IP versions even if the OS default
 		// is otherwise.  Note that some operating systems
 		// never admit this option.
diff --git a/third_party/gofrontend/libgo/go/net/sys_cloexec.go b/third_party/gofrontend/libgo/go/net/sys_cloexec.go
index 898fb7c..ba266e6 100644
--- a/third_party/gofrontend/libgo/go/net/sys_cloexec.go
+++ b/third_party/gofrontend/libgo/go/net/sys_cloexec.go
@@ -9,24 +9,27 @@
 
 package net
 
-import "syscall"
+import (
+	"os"
+	"syscall"
+)
 
 // Wrapper around the socket system call that marks the returned file
 // descriptor as nonblocking and close-on-exec.
 func sysSocket(family, sotype, proto int) (int, error) {
 	// See ../syscall/exec_unix.go for description of ForkLock.
 	syscall.ForkLock.RLock()
-	s, err := syscall.Socket(family, sotype, proto)
+	s, err := socketFunc(family, sotype, proto)
 	if err == nil {
 		syscall.CloseOnExec(s)
 	}
 	syscall.ForkLock.RUnlock()
 	if err != nil {
-		return -1, err
+		return -1, os.NewSyscallError("socket", err)
 	}
 	if err = syscall.SetNonblock(s, true); err != nil {
-		syscall.Close(s)
-		return -1, err
+		closeFunc(s)
+		return -1, os.NewSyscallError("setnonblock", err)
 	}
 	return s, nil
 }
@@ -39,16 +42,16 @@
 	// because we have put fd.sysfd into non-blocking mode.
 	// However, a call to the File method will put it back into
 	// blocking mode. We can't take that risk, so no use of ForkLock here.
-	ns, sa, err := syscall.Accept(s)
+	ns, sa, err := acceptFunc(s)
 	if err == nil {
 		syscall.CloseOnExec(ns)
 	}
 	if err != nil {
-		return -1, nil, err
+		return -1, nil, os.NewSyscallError("accept", err)
 	}
 	if err = syscall.SetNonblock(ns, true); err != nil {
-		syscall.Close(ns)
-		return -1, nil, err
+		closeFunc(ns)
+		return -1, nil, os.NewSyscallError("setnonblock", err)
 	}
 	return ns, sa, nil
 }
diff --git a/third_party/gofrontend/libgo/go/net/tcp_test.go b/third_party/gofrontend/libgo/go/net/tcp_test.go
index c04198e..25ae9b9 100644
--- a/third_party/gofrontend/libgo/go/net/tcp_test.go
+++ b/third_party/gofrontend/libgo/go/net/tcp_test.go
@@ -5,7 +5,6 @@
 package net
 
 import (
-	"fmt"
 	"io"
 	"reflect"
 	"runtime"
@@ -59,6 +58,8 @@
 }
 
 func benchmarkTCP(b *testing.B, persistent, timeout bool, laddr string) {
+	testHookUninstaller.Do(uninstallTestHooks)
+
 	const msgLen = 512
 	conns := b.N
 	numConcurrent := runtime.GOMAXPROCS(-1) * 2
@@ -76,7 +77,7 @@
 	sendMsg := func(c Conn, buf []byte) bool {
 		n, err := c.Write(buf)
 		if n != len(buf) || err != nil {
-			b.Logf("Write failed: %v", err)
+			b.Log(err)
 			return false
 		}
 		return true
@@ -86,7 +87,7 @@
 			n, err := c.Read(buf)
 			read += n
 			if err != nil {
-				b.Logf("Read failed: %v", err)
+				b.Log(err)
 				return false
 			}
 		}
@@ -94,7 +95,7 @@
 	}
 	ln, err := Listen("tcp", laddr)
 	if err != nil {
-		b.Fatalf("Listen failed: %v", err)
+		b.Fatal(err)
 	}
 	defer ln.Close()
 	serverSem := make(chan bool, numConcurrent)
@@ -134,7 +135,7 @@
 			}()
 			c, err := Dial("tcp", ln.Addr().String())
 			if err != nil {
-				b.Logf("Dial failed: %v", err)
+				b.Log(err)
 				return
 			}
 			defer c.Close()
@@ -167,6 +168,8 @@
 }
 
 func benchmarkTCPConcurrentReadWrite(b *testing.B, laddr string) {
+	testHookUninstaller.Do(uninstallTestHooks)
+
 	// The benchmark creates GOMAXPROCS client/server pairs.
 	// Each pair creates 4 goroutines: client reader/writer and server reader/writer.
 	// The benchmark stresses concurrent reading and writing to the same connection.
@@ -183,7 +186,7 @@
 	servers := make([]Conn, P)
 	ln, err := Listen("tcp", laddr)
 	if err != nil {
-		b.Fatalf("Listen failed: %v", err)
+		b.Fatal(err)
 	}
 	defer ln.Close()
 	done := make(chan bool)
@@ -191,7 +194,7 @@
 		for p := 0; p < P; p++ {
 			s, err := ln.Accept()
 			if err != nil {
-				b.Errorf("Accept failed: %v", err)
+				b.Error(err)
 				return
 			}
 			servers[p] = s
@@ -201,7 +204,7 @@
 	for p := 0; p < P; p++ {
 		c, err := Dial("tcp", ln.Addr().String())
 		if err != nil {
-			b.Fatalf("Dial failed: %v", err)
+			b.Fatal(err)
 		}
 		clients[p] = c
 	}
@@ -224,7 +227,7 @@
 				buf[0] = v
 				_, err := c.Write(buf[:])
 				if err != nil {
-					b.Errorf("Write failed: %v", err)
+					b.Error(err)
 					return
 				}
 			}
@@ -240,7 +243,7 @@
 			for i := 0; i < N; i++ {
 				_, err := s.Read(buf[:])
 				if err != nil {
-					b.Errorf("Read failed: %v", err)
+					b.Error(err)
 					return
 				}
 				pipe <- buf[0]
@@ -259,7 +262,7 @@
 				buf[0] = v
 				_, err := s.Write(buf[:])
 				if err != nil {
-					b.Errorf("Write failed: %v", err)
+					b.Error(err)
 					return
 				}
 			}
@@ -273,7 +276,7 @@
 			for i := 0; i < N; i++ {
 				_, err := c.Read(buf[:])
 				if err != nil {
-					b.Errorf("Read failed: %v", err)
+					b.Error(err)
 					return
 				}
 			}
@@ -284,7 +287,7 @@
 }
 
 type resolveTCPAddrTest struct {
-	net           string
+	network       string
 	litAddrOrName string
 	addr          *TCPAddr
 	err           error
@@ -294,8 +297,8 @@
 	{"tcp", "127.0.0.1:0", &TCPAddr{IP: IPv4(127, 0, 0, 1), Port: 0}, nil},
 	{"tcp4", "127.0.0.1:65535", &TCPAddr{IP: IPv4(127, 0, 0, 1), Port: 65535}, nil},
 
-	{"tcp", "[::1]:1", &TCPAddr{IP: ParseIP("::1"), Port: 1}, nil},
-	{"tcp6", "[::1]:65534", &TCPAddr{IP: ParseIP("::1"), Port: 65534}, nil},
+	{"tcp", "[::1]:0", &TCPAddr{IP: ParseIP("::1"), Port: 0}, nil},
+	{"tcp6", "[::1]:65535", &TCPAddr{IP: ParseIP("::1"), Port: 65535}, nil},
 
 	{"tcp", "[::1%en0]:1", &TCPAddr{IP: ParseIP("::1"), Port: 1, Zone: "en0"}, nil},
 	{"tcp6", "[::1%911]:2", &TCPAddr{IP: ParseIP("::1"), Port: 2, Zone: "911"}, nil},
@@ -308,41 +311,26 @@
 	{"http", "127.0.0.1:0", nil, UnknownNetworkError("http")},
 }
 
-func init() {
-	if ifi := loopbackInterface(); ifi != nil {
-		index := fmt.Sprintf("%v", ifi.Index)
-		resolveTCPAddrTests = append(resolveTCPAddrTests, []resolveTCPAddrTest{
-			{"tcp6", "[fe80::1%" + ifi.Name + "]:3", &TCPAddr{IP: ParseIP("fe80::1"), Port: 3, Zone: zoneToString(ifi.Index)}, nil},
-			{"tcp6", "[fe80::1%" + index + "]:4", &TCPAddr{IP: ParseIP("fe80::1"), Port: 4, Zone: index}, nil},
-		}...)
-	}
-	if ips, err := LookupIP("localhost"); err == nil && len(ips) > 1 && supportsIPv4 && supportsIPv6 {
-		resolveTCPAddrTests = append(resolveTCPAddrTests, []resolveTCPAddrTest{
-			{"tcp", "localhost:5", &TCPAddr{IP: IPv4(127, 0, 0, 1), Port: 5}, nil},
-			{"tcp4", "localhost:6", &TCPAddr{IP: IPv4(127, 0, 0, 1), Port: 6}, nil},
-			{"tcp6", "localhost:7", &TCPAddr{IP: IPv6loopback, Port: 7}, nil},
-		}...)
-	}
-}
-
 func TestResolveTCPAddr(t *testing.T) {
-	for _, tt := range resolveTCPAddrTests {
-		addr, err := ResolveTCPAddr(tt.net, tt.litAddrOrName)
+	origTestHookLookupIP := testHookLookupIP
+	defer func() { testHookLookupIP = origTestHookLookupIP }()
+	testHookLookupIP = lookupLocalhost
+
+	for i, tt := range resolveTCPAddrTests {
+		addr, err := ResolveTCPAddr(tt.network, tt.litAddrOrName)
 		if err != tt.err {
-			t.Fatalf("ResolveTCPAddr(%q, %q) failed: %v", tt.net, tt.litAddrOrName, err)
+			t.Errorf("#%d: %v", i, err)
+		} else if !reflect.DeepEqual(addr, tt.addr) {
+			t.Errorf("#%d: got %#v; want %#v", i, addr, tt.addr)
 		}
-		if !reflect.DeepEqual(addr, tt.addr) {
-			t.Fatalf("ResolveTCPAddr(%q, %q) = %#v, want %#v", tt.net, tt.litAddrOrName, addr, tt.addr)
+		if err != nil {
+			continue
 		}
-		if err == nil {
-			str := addr.String()
-			addr1, err := ResolveTCPAddr(tt.net, str)
-			if err != nil {
-				t.Fatalf("ResolveTCPAddr(%q, %q) [from %q]: %v", tt.net, str, tt.litAddrOrName, err)
-			}
-			if !reflect.DeepEqual(addr1, addr) {
-				t.Fatalf("ResolveTCPAddr(%q, %q) [from %q] = %#v, want %#v", tt.net, str, tt.litAddrOrName, addr1, addr)
-			}
+		rtaddr, err := ResolveTCPAddr(addr.Network(), addr.String())
+		if err != nil {
+			t.Errorf("#%d: %v", i, err)
+		} else if !reflect.DeepEqual(rtaddr, addr) {
+			t.Errorf("#%d: got %#v; want %#v", i, rtaddr, addr)
 		}
 	}
 }
@@ -358,13 +346,13 @@
 
 func TestTCPListenerName(t *testing.T) {
 	if testing.Short() || !*testExternal {
-		t.Skip("skipping test to avoid external network")
+		t.Skip("avoid external network")
 	}
 
 	for _, tt := range tcpListenerNameTests {
 		ln, err := ListenTCP(tt.net, tt.laddr)
 		if err != nil {
-			t.Fatalf("ListenTCP failed: %v", err)
+			t.Fatal(err)
 		}
 		defer ln.Close()
 		la := ln.Addr()
@@ -376,59 +364,37 @@
 
 func TestIPv6LinkLocalUnicastTCP(t *testing.T) {
 	if testing.Short() || !*testExternal {
-		t.Skip("skipping test to avoid external network")
+		t.Skip("avoid external network")
 	}
 	if !supportsIPv6 {
-		t.Skip("ipv6 is not supported")
-	}
-	ifi := loopbackInterface()
-	if ifi == nil {
-		t.Skip("loopback interface not found")
-	}
-	laddr := ipv6LinkLocalUnicastAddr(ifi)
-	if laddr == "" {
-		t.Skip("ipv6 unicast address on loopback not found")
+		t.Skip("IPv6 is not supported")
 	}
 
-	type test struct {
-		net, addr  string
-		nameLookup bool
-	}
-	var tests = []test{
-		{"tcp", "[" + laddr + "%" + ifi.Name + "]:0", false},
-		{"tcp6", "[" + laddr + "%" + ifi.Name + "]:0", false},
-	}
-	switch runtime.GOOS {
-	case "darwin", "freebsd", "openbsd", "netbsd":
-		tests = append(tests, []test{
-			{"tcp", "[localhost%" + ifi.Name + "]:0", true},
-			{"tcp6", "[localhost%" + ifi.Name + "]:0", true},
-		}...)
-	case "linux":
-		tests = append(tests, []test{
-			{"tcp", "[ip6-localhost%" + ifi.Name + "]:0", true},
-			{"tcp6", "[ip6-localhost%" + ifi.Name + "]:0", true},
-		}...)
-	}
-	for _, tt := range tests {
-		ln, err := Listen(tt.net, tt.addr)
+	for i, tt := range ipv6LinkLocalUnicastTCPTests {
+		ln, err := Listen(tt.network, tt.address)
 		if err != nil {
 			// It might return "LookupHost returned no
 			// suitable address" error on some platforms.
-			t.Logf("Listen failed: %v", err)
+			t.Log(err)
 			continue
 		}
-		defer ln.Close()
+		ls, err := (&streamListener{Listener: ln}).newLocalServer()
+		if err != nil {
+			t.Fatal(err)
+		}
+		defer ls.teardown()
+		ch := make(chan error, 1)
+		handler := func(ls *localServer, ln Listener) { transponder(ln, ch) }
+		if err := ls.buildup(handler); err != nil {
+			t.Fatal(err)
+		}
 		if la, ok := ln.Addr().(*TCPAddr); !ok || !tt.nameLookup && la.Zone == "" {
 			t.Fatalf("got %v; expected a proper address with zone identifier", la)
 		}
 
-		done := make(chan int)
-		go transponder(t, ln, done)
-
-		c, err := Dial(tt.net, ln.Addr().String())
+		c, err := Dial(tt.network, ls.Listener.Addr().String())
 		if err != nil {
-			t.Fatalf("Dial failed: %v", err)
+			t.Fatal(err)
 		}
 		defer c.Close()
 		if la, ok := c.LocalAddr().(*TCPAddr); !ok || !tt.nameLookup && la.Zone == "" {
@@ -439,14 +405,16 @@
 		}
 
 		if _, err := c.Write([]byte("TCP OVER IPV6 LINKLOCAL TEST")); err != nil {
-			t.Fatalf("Conn.Write failed: %v", err)
+			t.Fatal(err)
 		}
 		b := make([]byte, 32)
 		if _, err := c.Read(b); err != nil {
-			t.Fatalf("Conn.Read failed: %v", err)
+			t.Fatal(err)
 		}
 
-		<-done
+		for err := range ch {
+			t.Errorf("#%d: %v", i, err)
+		}
 	}
 }
 
@@ -454,7 +422,7 @@
 	defer runtime.GOMAXPROCS(runtime.GOMAXPROCS(4))
 	ln, err := Listen("tcp", "127.0.0.1:0")
 	if err != nil {
-		t.Fatalf("Listen failed: %v", err)
+		t.Fatal(err)
 	}
 	const N = 10
 	var wg sync.WaitGroup
@@ -492,13 +460,20 @@
 	}
 }
 
-func TestTCPReadWriteMallocs(t *testing.T) {
-	if testing.Short() {
-		t.Skip("skipping malloc count in short mode")
+func TestTCPReadWriteAllocs(t *testing.T) {
+	t.Skip("skipping test on gccgo until escape analysis is turned on")
+	switch runtime.GOOS {
+	case "nacl", "windows":
+		// NaCl needs to allocate pseudo file descriptor
+		// stuff. See syscall/fd_nacl.go.
+		// Windows uses closures and channels for IO
+		// completion port-based netpoll. See fd_windows.go.
+		t.Skipf("not supported on %s", runtime.GOOS)
 	}
+
 	ln, err := Listen("tcp", "127.0.0.1:0")
 	if err != nil {
-		t.Fatalf("Listen failed: %v", err)
+		t.Fatal(err)
 	}
 	defer ln.Close()
 	var server Conn
@@ -510,25 +485,26 @@
 	}()
 	client, err := Dial("tcp", ln.Addr().String())
 	if err != nil {
-		t.Fatalf("Dial failed: %v", err)
+		t.Fatal(err)
 	}
+	defer client.Close()
 	if err := <-errc; err != nil {
-		t.Fatalf("Accept failed: %v", err)
+		t.Fatal(err)
 	}
 	defer server.Close()
 	var buf [128]byte
-	mallocs := testing.AllocsPerRun(1000, func() {
+	allocs := testing.AllocsPerRun(1000, func() {
 		_, err := server.Write(buf[:])
 		if err != nil {
-			t.Fatalf("Write failed: %v", err)
+			t.Fatal(err)
 		}
 		_, err = io.ReadFull(client, buf[:])
 		if err != nil {
-			t.Fatalf("Read failed: %v", err)
+			t.Fatal(err)
 		}
 	})
-	if mallocs > 0 {
-		t.Fatalf("Got %v allocs, want 0", mallocs)
+	if allocs > 0 {
+		t.Fatalf("got %v; want 0", allocs)
 	}
 }
 
@@ -543,7 +519,7 @@
 	sendMsg := func(c Conn, buf []byte) bool {
 		n, err := c.Write(buf)
 		if n != len(buf) || err != nil {
-			t.Logf("Write failed: %v", err)
+			t.Log(err)
 			return false
 		}
 		return true
@@ -553,7 +529,7 @@
 			n, err := c.Read(buf)
 			read += n
 			if err != nil {
-				t.Logf("Read failed: %v", err)
+				t.Log(err)
 				return false
 			}
 		}
@@ -562,7 +538,7 @@
 
 	ln, err := Listen("tcp", "127.0.0.1:0")
 	if err != nil {
-		t.Fatalf("Listen failed: %v", err)
+		t.Fatal(err)
 	}
 	defer ln.Close()
 	// Acceptor.
@@ -593,7 +569,7 @@
 			}()
 			c, err := Dial("tcp", ln.Addr().String())
 			if err != nil {
-				t.Logf("Dial failed: %v", err)
+				t.Log(err)
 				return
 			}
 			defer c.Close()
diff --git a/third_party/gofrontend/libgo/go/net/tcpsock.go b/third_party/gofrontend/libgo/go/net/tcpsock.go
index f3dfbd2..8765aff 100644
--- a/third_party/gofrontend/libgo/go/net/tcpsock.go
+++ b/third_party/gofrontend/libgo/go/net/tcpsock.go
@@ -25,7 +25,14 @@
 	return JoinHostPort(ip, itoa(a.Port))
 }
 
-func (a *TCPAddr) toAddr() Addr {
+func (a *TCPAddr) isWildcard() bool {
+	if a == nil || a.IP == nil {
+		return true
+	}
+	return a.IP.IsUnspecified()
+}
+
+func (a *TCPAddr) opAddr() Addr {
 	if a == nil {
 		return nil
 	}
@@ -46,9 +53,9 @@
 	default:
 		return nil, UnknownNetworkError(net)
 	}
-	a, err := resolveInternetAddr(net, addr, noDeadline)
+	addrs, err := internetAddrList(net, addr, noDeadline)
 	if err != nil {
 		return nil, err
 	}
-	return a.toAddr().(*TCPAddr), nil
+	return addrs.first(isIPv4).(*TCPAddr), nil
 }
diff --git a/third_party/gofrontend/libgo/go/net/tcpsock_plan9.go b/third_party/gofrontend/libgo/go/net/tcpsock_plan9.go
index 52019d7..9f23703 100644
--- a/third_party/gofrontend/libgo/go/net/tcpsock_plan9.go
+++ b/third_party/gofrontend/libgo/go/net/tcpsock_plan9.go
@@ -23,7 +23,11 @@
 
 // ReadFrom implements the io.ReaderFrom ReadFrom method.
 func (c *TCPConn) ReadFrom(r io.Reader) (int64, error) {
-	return genericReadFrom(c, r)
+	n, err := genericReadFrom(c, r)
+	if err != nil && err != io.EOF {
+		err = &OpError{Op: "read", Net: c.fd.dir, Source: c.fd.laddr, Addr: c.fd.raddr, Err: err}
+	}
+	return n, err
 }
 
 // CloseRead shuts down the reading side of the TCP connection.
@@ -32,7 +36,11 @@
 	if !c.ok() {
 		return syscall.EINVAL
 	}
-	return c.fd.closeRead()
+	err := c.fd.closeRead()
+	if err != nil {
+		err = &OpError{Op: "close", Net: c.fd.dir, Source: c.fd.laddr, Addr: c.fd.raddr, Err: err}
+	}
+	return err
 }
 
 // CloseWrite shuts down the writing side of the TCP connection.
@@ -41,7 +49,11 @@
 	if !c.ok() {
 		return syscall.EINVAL
 	}
-	return c.fd.closeWrite()
+	err := c.fd.closeWrite()
+	if err != nil {
+		err = &OpError{Op: "close", Net: c.fd.dir, Source: c.fd.laddr, Addr: c.fd.raddr, Err: err}
+	}
+	return err
 }
 
 // SetLinger sets the behavior of Close on a connection which still
@@ -57,7 +69,7 @@
 // some operating systems after sec seconds have elapsed any remaining
 // unsent data may be discarded.
 func (c *TCPConn) SetLinger(sec int) error {
-	return syscall.EPLAN9
+	return &OpError{Op: "set", Net: c.fd.dir, Source: c.fd.laddr, Addr: c.fd.raddr, Err: syscall.EPLAN9}
 }
 
 // SetKeepAlive sets whether the operating system should send
@@ -66,7 +78,10 @@
 	if !c.ok() {
 		return syscall.EPLAN9
 	}
-	return setKeepAlive(c.fd, keepalive)
+	if err := setKeepAlive(c.fd, keepalive); err != nil {
+		return &OpError{Op: "set", Net: c.fd.dir, Source: c.fd.laddr, Addr: c.fd.raddr, Err: err}
+	}
+	return nil
 }
 
 // SetKeepAlivePeriod sets period between keep alives.
@@ -74,7 +89,10 @@
 	if !c.ok() {
 		return syscall.EPLAN9
 	}
-	return setKeepAlivePeriod(c.fd, d)
+	if err := setKeepAlivePeriod(c.fd, d); err != nil {
+		return &OpError{Op: "set", Net: c.fd.dir, Source: c.fd.laddr, Addr: c.fd.raddr, Err: err}
+	}
+	return nil
 }
 
 // SetNoDelay controls whether the operating system should delay
@@ -82,7 +100,7 @@
 // algorithm).  The default is true (no delay), meaning that data is
 // sent as soon as possible after a Write.
 func (c *TCPConn) SetNoDelay(noDelay bool) error {
-	return syscall.EPLAN9
+	return &OpError{Op: "set", Net: c.fd.dir, Source: c.fd.laddr, Addr: c.fd.raddr, Err: syscall.EPLAN9}
 }
 
 // DialTCP connects to the remote address raddr on the network net,
@@ -99,10 +117,10 @@
 	switch net {
 	case "tcp", "tcp4", "tcp6":
 	default:
-		return nil, &OpError{"dial", net, raddr, UnknownNetworkError(net)}
+		return nil, &OpError{Op: "dial", Net: net, Source: laddr.opAddr(), Addr: raddr.opAddr(), Err: UnknownNetworkError(net)}
 	}
 	if raddr == nil {
-		return nil, &OpError{"dial", net, nil, errMissingAddress}
+		return nil, &OpError{Op: "dial", Net: net, Source: laddr.opAddr(), Addr: nil, Err: errMissingAddress}
 	}
 	fd, err := dialPlan9(net, laddr, raddr)
 	if err != nil {
@@ -151,12 +169,18 @@
 	}
 	if _, err := l.fd.ctl.WriteString("hangup"); err != nil {
 		l.fd.ctl.Close()
-		return &OpError{"close", l.fd.ctl.Name(), l.fd.laddr, err}
+		return &OpError{Op: "close", Net: l.fd.dir, Source: nil, Addr: l.fd.laddr, Err: err}
 	}
-	return l.fd.ctl.Close()
+	err := l.fd.ctl.Close()
+	if err != nil {
+		err = &OpError{Op: "close", Net: l.fd.dir, Source: nil, Addr: l.fd.laddr, Err: err}
+	}
+	return err
 }
 
 // Addr returns the listener's network address, a *TCPAddr.
+// The Addr returned is shared by all invocations of Addr, so
+// do not modify it.
 func (l *TCPListener) Addr() Addr { return l.fd.laddr }
 
 // SetDeadline sets the deadline associated with the listener.
@@ -165,7 +189,10 @@
 	if l == nil || l.fd == nil || l.fd.ctl == nil {
 		return syscall.EINVAL
 	}
-	return l.fd.setDeadline(t)
+	if err := l.fd.setDeadline(t); err != nil {
+		return &OpError{Op: "set", Net: l.fd.dir, Source: nil, Addr: l.fd.laddr, Err: err}
+	}
+	return nil
 }
 
 // File returns a copy of the underlying os.File, set to blocking
@@ -175,7 +202,13 @@
 // The returned os.File's file descriptor is different from the
 // connection's.  Attempting to change properties of the original
 // using this duplicate may or may not have the desired effect.
-func (l *TCPListener) File() (f *os.File, err error) { return l.dup() }
+func (l *TCPListener) File() (f *os.File, err error) {
+	f, err = l.dup()
+	if err != nil {
+		err = &OpError{Op: "file", Net: l.fd.dir, Source: nil, Addr: l.fd.laddr, Err: err}
+	}
+	return
+}
 
 // ListenTCP announces on the TCP address laddr and returns a TCP
 // listener.  Net must be "tcp", "tcp4", or "tcp6".  If laddr has a
@@ -185,7 +218,7 @@
 	switch net {
 	case "tcp", "tcp4", "tcp6":
 	default:
-		return nil, &OpError{"listen", net, laddr, UnknownNetworkError(net)}
+		return nil, &OpError{Op: "listen", Net: net, Source: nil, Addr: laddr.opAddr(), Err: UnknownNetworkError(net)}
 	}
 	if laddr == nil {
 		laddr = &TCPAddr{}
diff --git a/third_party/gofrontend/libgo/go/net/tcpsock_posix.go b/third_party/gofrontend/libgo/go/net/tcpsock_posix.go
index dd78aef..7e49b76 100644
--- a/third_party/gofrontend/libgo/go/net/tcpsock_posix.go
+++ b/third_party/gofrontend/libgo/go/net/tcpsock_posix.go
@@ -13,11 +13,6 @@
 	"time"
 )
 
-// BUG(rsc): On OpenBSD, listening on the "tcp" network does not listen for
-// both IPv4 and IPv6 connections. This is due to the fact that IPv4 traffic
-// will not be routed to an IPv6 socket - two separate sockets are required
-// if both AFs are to be supported. See inet6(4) on OpenBSD for details.
-
 func sockaddrToTCP(sa syscall.Sockaddr) Addr {
 	switch sa := sa.(type) {
 	case *syscall.SockaddrInet4:
@@ -38,13 +33,6 @@
 	return syscall.AF_INET6
 }
 
-func (a *TCPAddr) isWildcard() bool {
-	if a == nil || a.IP == nil {
-		return true
-	}
-	return a.IP.IsUnspecified()
-}
-
 func (a *TCPAddr) sockaddr(family int) (syscall.Sockaddr, error) {
 	if a == nil {
 		return nil, nil
@@ -60,16 +48,23 @@
 
 func newTCPConn(fd *netFD) *TCPConn {
 	c := &TCPConn{conn{fd}}
-	c.SetNoDelay(true)
+	setNoDelay(c.fd, true)
 	return c
 }
 
 // ReadFrom implements the io.ReaderFrom ReadFrom method.
 func (c *TCPConn) ReadFrom(r io.Reader) (int64, error) {
 	if n, err, handled := sendFile(c.fd, r); handled {
+		if err != nil && err != io.EOF {
+			err = &OpError{Op: "read", Net: c.fd.net, Source: c.fd.laddr, Addr: c.fd.raddr, Err: err}
+		}
 		return n, err
 	}
-	return genericReadFrom(c, r)
+	n, err := genericReadFrom(c, r)
+	if err != nil && err != io.EOF {
+		err = &OpError{Op: "read", Net: c.fd.net, Source: c.fd.laddr, Addr: c.fd.raddr, Err: err}
+	}
+	return n, err
 }
 
 // CloseRead shuts down the reading side of the TCP connection.
@@ -78,7 +73,11 @@
 	if !c.ok() {
 		return syscall.EINVAL
 	}
-	return c.fd.closeRead()
+	err := c.fd.closeRead()
+	if err != nil {
+		err = &OpError{Op: "close", Net: c.fd.net, Source: c.fd.laddr, Addr: c.fd.raddr, Err: err}
+	}
+	return err
 }
 
 // CloseWrite shuts down the writing side of the TCP connection.
@@ -87,7 +86,11 @@
 	if !c.ok() {
 		return syscall.EINVAL
 	}
-	return c.fd.closeWrite()
+	err := c.fd.closeWrite()
+	if err != nil {
+		err = &OpError{Op: "close", Net: c.fd.net, Source: c.fd.laddr, Addr: c.fd.raddr, Err: err}
+	}
+	return err
 }
 
 // SetLinger sets the behavior of Close on a connection which still
@@ -106,7 +109,10 @@
 	if !c.ok() {
 		return syscall.EINVAL
 	}
-	return setLinger(c.fd, sec)
+	if err := setLinger(c.fd, sec); err != nil {
+		return &OpError{Op: "set", Net: c.fd.net, Source: c.fd.laddr, Addr: c.fd.raddr, Err: err}
+	}
+	return nil
 }
 
 // SetKeepAlive sets whether the operating system should send
@@ -115,7 +121,10 @@
 	if !c.ok() {
 		return syscall.EINVAL
 	}
-	return setKeepAlive(c.fd, keepalive)
+	if err := setKeepAlive(c.fd, keepalive); err != nil {
+		return &OpError{Op: "set", Net: c.fd.net, Source: c.fd.laddr, Addr: c.fd.raddr, Err: err}
+	}
+	return nil
 }
 
 // SetKeepAlivePeriod sets period between keep alives.
@@ -123,7 +132,10 @@
 	if !c.ok() {
 		return syscall.EINVAL
 	}
-	return setKeepAlivePeriod(c.fd, d)
+	if err := setKeepAlivePeriod(c.fd, d); err != nil {
+		return &OpError{Op: "set", Net: c.fd.net, Source: c.fd.laddr, Addr: c.fd.raddr, Err: err}
+	}
+	return nil
 }
 
 // SetNoDelay controls whether the operating system should delay
@@ -134,7 +146,10 @@
 	if !c.ok() {
 		return syscall.EINVAL
 	}
-	return setNoDelay(c.fd, noDelay)
+	if err := setNoDelay(c.fd, noDelay); err != nil {
+		return &OpError{Op: "set", Net: c.fd.net, Source: c.fd.laddr, Addr: c.fd.raddr, Err: err}
+	}
+	return nil
 }
 
 // DialTCP connects to the remote address raddr on the network net,
@@ -144,10 +159,10 @@
 	switch net {
 	case "tcp", "tcp4", "tcp6":
 	default:
-		return nil, &OpError{Op: "dial", Net: net, Addr: raddr, Err: UnknownNetworkError(net)}
+		return nil, &OpError{Op: "dial", Net: net, Source: laddr.opAddr(), Addr: raddr.opAddr(), Err: UnknownNetworkError(net)}
 	}
 	if raddr == nil {
-		return nil, &OpError{Op: "dial", Net: net, Addr: nil, Err: errMissingAddress}
+		return nil, &OpError{Op: "dial", Net: net, Source: laddr.opAddr(), Addr: nil, Err: errMissingAddress}
 	}
 	return dialTCP(net, laddr, raddr, noDeadline)
 }
@@ -170,7 +185,7 @@
 	// see this happen, rather than expose the buggy effect to users, we
 	// close the fd and try again.  If it happens twice more, we relent and
 	// use the result.  See also:
-	//	http://golang.org/issue/2690
+	//	https://golang.org/issue/2690
 	//	http://stackoverflow.com/questions/4949858/
 	//
 	// The opposite can also happen: if we ask the kernel to pick an appropriate
@@ -187,7 +202,7 @@
 	}
 
 	if err != nil {
-		return nil, &OpError{Op: "dial", Net: net, Addr: raddr, Err: err}
+		return nil, &OpError{Op: "dial", Net: net, Source: laddr.opAddr(), Addr: raddr.opAddr(), Err: err}
 	}
 	return newTCPConn(fd), nil
 }
@@ -215,8 +230,13 @@
 }
 
 func spuriousENOTAVAIL(err error) bool {
-	e, ok := err.(*OpError)
-	return ok && e.Err == syscall.EADDRNOTAVAIL
+	if op, ok := err.(*OpError); ok {
+		err = op.Err
+	}
+	if sys, ok := err.(*os.SyscallError); ok {
+		err = sys.Err
+	}
+	return err == syscall.EADDRNOTAVAIL
 }
 
 // TCPListener is a TCP network listener.  Clients should typically
@@ -233,7 +253,7 @@
 	}
 	fd, err := l.fd.accept()
 	if err != nil {
-		return nil, err
+		return nil, &OpError{Op: "accept", Net: l.fd.net, Source: nil, Addr: l.fd.laddr, Err: err}
 	}
 	return newTCPConn(fd), nil
 }
@@ -254,10 +274,16 @@
 	if l == nil || l.fd == nil {
 		return syscall.EINVAL
 	}
-	return l.fd.Close()
+	err := l.fd.Close()
+	if err != nil {
+		err = &OpError{Op: "close", Net: l.fd.net, Source: nil, Addr: l.fd.laddr, Err: err}
+	}
+	return err
 }
 
 // Addr returns the listener's network address, a *TCPAddr.
+// The Addr returned is shared by all invocations of Addr, so
+// do not modify it.
 func (l *TCPListener) Addr() Addr { return l.fd.laddr }
 
 // SetDeadline sets the deadline associated with the listener.
@@ -266,7 +292,10 @@
 	if l == nil || l.fd == nil {
 		return syscall.EINVAL
 	}
-	return l.fd.setDeadline(t)
+	if err := l.fd.setDeadline(t); err != nil {
+		return &OpError{Op: "set", Net: l.fd.net, Source: nil, Addr: l.fd.laddr, Err: err}
+	}
+	return nil
 }
 
 // File returns a copy of the underlying os.File, set to blocking
@@ -276,7 +305,13 @@
 // The returned os.File's file descriptor is different from the
 // connection's.  Attempting to change properties of the original
 // using this duplicate may or may not have the desired effect.
-func (l *TCPListener) File() (f *os.File, err error) { return l.fd.dup() }
+func (l *TCPListener) File() (f *os.File, err error) {
+	f, err = l.fd.dup()
+	if err != nil {
+		err = &OpError{Op: "file", Net: l.fd.net, Source: nil, Addr: l.fd.laddr, Err: err}
+	}
+	return
+}
 
 // ListenTCP announces on the TCP address laddr and returns a TCP
 // listener.  Net must be "tcp", "tcp4", or "tcp6".  If laddr has a
@@ -286,14 +321,14 @@
 	switch net {
 	case "tcp", "tcp4", "tcp6":
 	default:
-		return nil, &OpError{Op: "listen", Net: net, Addr: laddr, Err: UnknownNetworkError(net)}
+		return nil, &OpError{Op: "listen", Net: net, Source: nil, Addr: laddr.opAddr(), Err: UnknownNetworkError(net)}
 	}
 	if laddr == nil {
 		laddr = &TCPAddr{}
 	}
 	fd, err := internetSocket(net, laddr, nil, noDeadline, syscall.SOCK_STREAM, 0, "listen")
 	if err != nil {
-		return nil, &OpError{Op: "listen", Net: net, Addr: laddr, Err: err}
+		return nil, &OpError{Op: "listen", Net: net, Source: nil, Addr: laddr, Err: err}
 	}
 	return &TCPListener{fd}, nil
 }
diff --git a/third_party/gofrontend/libgo/go/net/tcpsockopt_plan9.go b/third_party/gofrontend/libgo/go/net/tcpsockopt_plan9.go
index 0e7a664..9abe186 100644
--- a/third_party/gofrontend/libgo/go/net/tcpsockopt_plan9.go
+++ b/third_party/gofrontend/libgo/go/net/tcpsockopt_plan9.go
@@ -7,12 +7,13 @@
 package net
 
 import (
+	"strconv"
 	"time"
 )
 
 // Set keep alive period.
 func setKeepAlivePeriod(fd *netFD, d time.Duration) error {
-	cmd := "keepalive " + string(int64(d/time.Millisecond))
+	cmd := "keepalive " + strconv.Itoa(int(d/time.Millisecond))
 	_, e := fd.ctl.WriteAt([]byte(cmd), 0)
 	return e
 }
diff --git a/third_party/gofrontend/libgo/go/net/tcpsockopt_unix.go b/third_party/gofrontend/libgo/go/net/tcpsockopt_unix.go
index c9f604c..c8970d1 100644
--- a/third_party/gofrontend/libgo/go/net/tcpsockopt_unix.go
+++ b/third_party/gofrontend/libgo/go/net/tcpsockopt_unix.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 freebsd linux netbsd solaris
+// +build freebsd linux netbsd
 
 package net
 
diff --git a/third_party/gofrontend/libgo/go/net/tcpsockopt_windows.go b/third_party/gofrontend/libgo/go/net/tcpsockopt_windows.go
index 091f523..ae2d7c8 100644
--- a/third_party/gofrontend/libgo/go/net/tcpsockopt_windows.go
+++ b/third_party/gofrontend/libgo/go/net/tcpsockopt_windows.go
@@ -28,5 +28,5 @@
 	ret := uint32(0)
 	size := uint32(unsafe.Sizeof(ka))
 	err := syscall.WSAIoctl(fd.sysfd, syscall.SIO_KEEPALIVE_VALS, (*byte)(unsafe.Pointer(&ka)), size, nil, 0, &ret, nil, 0)
-	return os.NewSyscallError("WSAIoctl", err)
+	return os.NewSyscallError("wsaioctl", err)
 }
diff --git a/third_party/gofrontend/libgo/go/net/testdata/ipv4-hosts b/third_party/gofrontend/libgo/go/net/testdata/ipv4-hosts
new file mode 100644
index 0000000..5208bb4
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/net/testdata/ipv4-hosts
@@ -0,0 +1,12 @@
+# See https://tools.ietf.org/html/rfc1123.
+#
+# The literal IPv4 address parser in the net package is a relaxed
+# one. It may accept a literal IPv4 address in dotted-decimal notation
+# with leading zeros such as "001.2.003.4".
+
+# internet address and host name
+127.0.0.1	localhost	# inline comment separated by tab
+127.000.000.002	localhost       # inline comment separated by space
+
+# internet address, host name and aliases
+127.000.000.003	localhost	localhost.localdomain
diff --git a/third_party/gofrontend/libgo/go/net/testdata/ipv6-hosts b/third_party/gofrontend/libgo/go/net/testdata/ipv6-hosts
new file mode 100644
index 0000000..f78b7fc
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/net/testdata/ipv6-hosts
@@ -0,0 +1,11 @@
+# See https://tools.ietf.org/html/rfc5952, https://tools.ietf.org/html/rfc4007.
+
+# internet address and host name
+::1						localhost	# inline comment separated by tab
+fe80:0000:0000:0000:0000:0000:0000:0001		localhost       # inline comment separated by space
+
+# internet address with zone identifier and host name
+fe80:0000:0000:0000:0000:0000:0000:0002%lo0	localhost
+
+# internet address, host name and aliases
+fe80::3%lo0					localhost	localhost.localdomain
diff --git a/third_party/gofrontend/libgo/go/net/testdata/openbsd-resolv.conf b/third_party/gofrontend/libgo/go/net/testdata/openbsd-resolv.conf
new file mode 100644
index 0000000..8281a91
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/net/testdata/openbsd-resolv.conf
@@ -0,0 +1,5 @@
+# Generated by vio0 dhclient
+search c.symbolic-datum-552.internal.
+nameserver 169.254.169.254
+nameserver 10.240.0.1
+lookup file bind
diff --git a/third_party/gofrontend/libgo/go/net/testdata/hosts_singleline b/third_party/gofrontend/libgo/go/net/testdata/singleline-hosts
similarity index 100%
rename from third_party/gofrontend/libgo/go/net/testdata/hosts_singleline
rename to third_party/gofrontend/libgo/go/net/testdata/singleline-hosts
diff --git a/third_party/gofrontend/libgo/go/net/textproto/reader.go b/third_party/gofrontend/libgo/go/net/textproto/reader.go
index eea9207..91303fe 100644
--- a/third_party/gofrontend/libgo/go/net/textproto/reader.go
+++ b/third_party/gofrontend/libgo/go/net/textproto/reader.go
@@ -13,10 +13,6 @@
 	"strings"
 )
 
-// BUG(rsc): To let callers manage exposure to denial of service
-// attacks, Reader should allow them to set and reset a limit on
-// the number of bytes read from the connection.
-
 // A Reader implements convenience methods for reading requests
 // or responses from a text protocol network connection.
 type Reader struct {
@@ -26,6 +22,10 @@
 }
 
 // NewReader returns a new Reader reading from r.
+//
+// To avoid denial of service attacks, the provided bufio.Reader
+// should be reading from an io.LimitReader or similar Reader to bound
+// the size of responses.
 func NewReader(r *bufio.Reader) *Reader {
 	return &Reader{R: r}
 }
@@ -485,6 +485,13 @@
 		}
 		key := canonicalMIMEHeaderKey(kv[:endKey])
 
+		// As per RFC 7230 field-name is a token, tokens consist of one or more chars.
+		// We could return a ProtocolError here, but better to be liberal in what we
+		// accept, so if we get an empty key, skip it.
+		if key == "" {
+			continue
+		}
+
 		// Skip initial spaces in value.
 		i++ // skip colon
 		for i < len(kv) && (kv[i] == ' ' || kv[i] == '\t') {
@@ -540,11 +547,16 @@
 // the rest are converted to lowercase.  For example, the
 // canonical key for "accept-encoding" is "Accept-Encoding".
 // MIME header keys are assumed to be ASCII only.
+// If s contains a space or invalid header field bytes, it is
+// returned without modifications.
 func CanonicalMIMEHeaderKey(s string) string {
 	// Quick check for canonical encoding.
 	upper := true
 	for i := 0; i < len(s); i++ {
 		c := s[i]
+		if !validHeaderFieldByte(c) {
+			return s
+		}
 		if upper && 'a' <= c && c <= 'z' {
 			return canonicalMIMEHeaderKey([]byte(s))
 		}
@@ -558,19 +570,44 @@
 
 const toLower = 'a' - 'A'
 
+// validHeaderFieldByte reports whether b is a valid byte in a header
+// field key. This is actually stricter than RFC 7230, which says:
+//   tchar = "!" / "#" / "$" / "%" / "&" / "'" / "*" / "+" / "-" / "." /
+//           "^" / "_" / "`" / "|" / "~" / DIGIT / ALPHA
+//   token = 1*tchar
+// TODO: revisit in Go 1.6+ and possibly expand this. But note that many
+// servers have historically dropped '_' to prevent ambiguities when mapping
+// to CGI environment variables.
+func validHeaderFieldByte(b byte) bool {
+	return ('A' <= b && b <= 'Z') ||
+		('a' <= b && b <= 'z') ||
+		('0' <= b && b <= '9') ||
+		b == '-'
+}
+
 // canonicalMIMEHeaderKey is like CanonicalMIMEHeaderKey but is
 // allowed to mutate the provided byte slice before returning the
 // string.
+//
+// For invalid inputs (if a contains spaces or non-token bytes), a
+// is unchanged and a string copy is returned.
 func canonicalMIMEHeaderKey(a []byte) string {
+	// See if a looks like a header key. If not, return it unchanged.
+	for _, c := range a {
+		if validHeaderFieldByte(c) {
+			continue
+		}
+		// Don't canonicalize.
+		return string(a)
+	}
+
 	upper := true
 	for i, c := range a {
 		// Canonicalize: first letter upper case
 		// and upper case after each dash.
 		// (Host, User-Agent, If-Modified-Since).
 		// MIME headers are ASCII only, so no Unicode issues.
-		if c == ' ' {
-			c = '-'
-		} else if upper && 'a' <= c && c <= 'z' {
+		if upper && 'a' <= c && c <= 'z' {
 			c -= toLower
 		} else if !upper && 'A' <= c && c <= 'Z' {
 			c += toLower
diff --git a/third_party/gofrontend/libgo/go/net/textproto/reader_test.go b/third_party/gofrontend/libgo/go/net/textproto/reader_test.go
index c895666..91550f7 100644
--- a/third_party/gofrontend/libgo/go/net/textproto/reader_test.go
+++ b/third_party/gofrontend/libgo/go/net/textproto/reader_test.go
@@ -24,11 +24,14 @@
 	{"uSER-aGENT", "User-Agent"},
 	{"user-agent", "User-Agent"},
 	{"USER-AGENT", "User-Agent"},
-	{"üser-agenT", "üser-Agent"}, // non-ASCII unchanged
+
+	// Non-ASCII or anything with spaces or non-token chars is unchanged:
+	{"üser-agenT", "üser-agenT"},
+	{"a B", "a B"},
 
 	// This caused a panic due to mishandling of a space:
-	{"C Ontent-Transfer-Encoding", "C-Ontent-Transfer-Encoding"},
-	{"foo bar", "Foo-Bar"},
+	{"C Ontent-Transfer-Encoding", "C Ontent-Transfer-Encoding"},
+	{"foo bar", "foo bar"},
 }
 
 func TestCanonicalMIMEHeaderKey(t *testing.T) {
@@ -153,6 +156,15 @@
 	}
 }
 
+func TestReadMIMEHeaderNoKey(t *testing.T) {
+	r := reader(": bar\ntest-1: 1\n\n")
+	m, err := r.ReadMIMEHeader()
+	want := MIMEHeader{"Test-1": {"1"}}
+	if !reflect.DeepEqual(m, want) || err != nil {
+		t.Fatalf("ReadMIMEHeader: %v, %v; want %v", m, err, want)
+	}
+}
+
 func TestLargeReadMIMEHeader(t *testing.T) {
 	data := make([]byte, 16*1024)
 	for i := 0; i < len(data); i++ {
@@ -185,7 +197,7 @@
 		"Foo":              {"bar"},
 		"Content-Language": {"en"},
 		"Sid":              {"0"},
-		"Audio-Mode":       {"None"},
+		"Audio Mode":       {"None"},
 		"Privilege":        {"127"},
 	}
 	if !reflect.DeepEqual(m, want) || err != nil {
diff --git a/third_party/gofrontend/libgo/go/net/timeout_test.go b/third_party/gofrontend/libgo/go/net/timeout_test.go
index 9ef0c4d..ca94e24 100644
--- a/third_party/gofrontend/libgo/go/net/timeout_test.go
+++ b/third_party/gofrontend/libgo/go/net/timeout_test.go
@@ -8,408 +8,727 @@
 	"fmt"
 	"io"
 	"io/ioutil"
+	"net/internal/socktest"
 	"runtime"
+	"sync"
 	"testing"
 	"time"
 )
 
-func isTimeout(err error) bool {
-	e, ok := err.(Error)
-	return ok && e.Timeout()
+var dialTimeoutTests = []struct {
+	timeout time.Duration
+	delta   time.Duration // for deadline
+
+	guard time.Duration
+	max   time.Duration
+}{
+	// Tests that dial timeouts, deadlines in the past work.
+	{-5 * time.Second, 0, -5 * time.Second, 100 * time.Millisecond},
+	{0, -5 * time.Second, -5 * time.Second, 100 * time.Millisecond},
+	{-5 * time.Second, 5 * time.Second, -5 * time.Second, 100 * time.Millisecond}, // timeout over deadline
+
+	{50 * time.Millisecond, 0, 100 * time.Millisecond, time.Second},
+	{0, 50 * time.Millisecond, 100 * time.Millisecond, time.Second},
+	{50 * time.Millisecond, 5 * time.Second, 100 * time.Millisecond, time.Second}, // timeout over deadline
 }
 
-type copyRes struct {
-	n   int64
-	err error
-	d   time.Duration
+func TestDialTimeout(t *testing.T) {
+	origTestHookDialChannel := testHookDialChannel
+	defer func() { testHookDialChannel = origTestHookDialChannel }()
+	defer sw.Set(socktest.FilterConnect, nil)
+
+	// Avoid tracking open-close jitterbugs between netFD and
+	// socket that leads to confusion of information inside
+	// socktest.Switch.
+	// It may happen when the Dial call bumps against TCP
+	// simultaneous open. See selfConnect in tcpsock_posix.go.
+	defer func() {
+		sw.Set(socktest.FilterClose, nil)
+		forceCloseSockets()
+	}()
+	sw.Set(socktest.FilterClose, func(so *socktest.Status) (socktest.AfterFilter, error) {
+		return nil, errTimedout
+	})
+
+	for i, tt := range dialTimeoutTests {
+		switch runtime.GOOS {
+		case "plan9", "windows":
+			testHookDialChannel = func() { time.Sleep(tt.guard) }
+			if runtime.GOOS == "plan9" {
+				break
+			}
+			fallthrough
+		default:
+			sw.Set(socktest.FilterConnect, func(so *socktest.Status) (socktest.AfterFilter, error) {
+				time.Sleep(tt.guard)
+				return nil, errTimedout
+			})
+		}
+
+		ch := make(chan error)
+		d := Dialer{Timeout: tt.timeout}
+		if tt.delta != 0 {
+			d.Deadline = time.Now().Add(tt.delta)
+		}
+		max := time.NewTimer(tt.max)
+		defer max.Stop()
+		go func() {
+			// This dial never starts to send any TCP SYN
+			// segment because of above socket filter and
+			// test hook.
+			c, err := d.Dial("tcp", "127.0.0.1:0")
+			if err == nil {
+				err = fmt.Errorf("unexpectedly established: tcp:%s->%s", c.LocalAddr(), c.RemoteAddr())
+				c.Close()
+			}
+			ch <- err
+		}()
+
+		select {
+		case <-max.C:
+			t.Fatalf("#%d: Dial didn't return in an expected time", i)
+		case err := <-ch:
+			if perr := parseDialError(err); perr != nil {
+				t.Errorf("#%d: %v", i, perr)
+			}
+			if nerr, ok := err.(Error); !ok || !nerr.Timeout() {
+				t.Fatalf("#%d: %v", i, err)
+			}
+		}
+	}
+}
+
+var acceptTimeoutTests = []struct {
+	timeout time.Duration
+	xerrs   [2]error // expected errors in transition
+}{
+	// Tests that accept deadlines in the past work, even if
+	// there's incoming connections available.
+	{-5 * time.Second, [2]error{errTimeout, errTimeout}},
+
+	{50 * time.Millisecond, [2]error{nil, errTimeout}},
 }
 
 func TestAcceptTimeout(t *testing.T) {
 	switch runtime.GOOS {
 	case "plan9":
-		t.Skipf("skipping test on %q", runtime.GOOS)
+		t.Skipf("not supported on %s", runtime.GOOS)
 	}
 
-	ln := newLocalListener(t).(*TCPListener)
+	ln, err := newLocalListener("tcp")
+	if err != nil {
+		t.Fatal(err)
+	}
 	defer ln.Close()
-	ln.SetDeadline(time.Now().Add(-1 * time.Second))
-	if _, err := ln.Accept(); !isTimeout(err) {
-		t.Fatalf("Accept: expected err %v, got %v", errTimeout, err)
+
+	for i, tt := range acceptTimeoutTests {
+		if tt.timeout < 0 {
+			go func() {
+				c, err := Dial(ln.Addr().Network(), ln.Addr().String())
+				if err != nil {
+					t.Error(err)
+					return
+				}
+				var b [1]byte
+				c.Read(b[:])
+				c.Close()
+			}()
+		}
+
+		if err := ln.(*TCPListener).SetDeadline(time.Now().Add(tt.timeout)); err != nil {
+			t.Fatalf("$%d: %v", i, err)
+		}
+		for j, xerr := range tt.xerrs {
+			for {
+				c, err := ln.Accept()
+				if xerr != nil {
+					if perr := parseAcceptError(err); perr != nil {
+						t.Errorf("#%d/%d: %v", i, j, perr)
+					}
+					if nerr, ok := err.(Error); !ok || !nerr.Timeout() {
+						t.Fatalf("#%d/%d: %v", i, j, err)
+					}
+				}
+				if err == nil {
+					c.Close()
+					time.Sleep(tt.timeout / 3)
+					continue
+				}
+				break
+			}
+		}
 	}
-	if _, err := ln.Accept(); !isTimeout(err) {
-		t.Fatalf("Accept: expected err %v, got %v", errTimeout, err)
+}
+
+func TestAcceptTimeoutMustReturn(t *testing.T) {
+	switch runtime.GOOS {
+	case "plan9":
+		t.Skipf("not supported on %s", runtime.GOOS)
 	}
-	ln.SetDeadline(time.Now().Add(100 * time.Millisecond))
-	if _, err := ln.Accept(); !isTimeout(err) {
-		t.Fatalf("Accept: expected err %v, got %v", errTimeout, err)
+
+	ln, err := newLocalListener("tcp")
+	if err != nil {
+		t.Fatal(err)
 	}
-	if _, err := ln.Accept(); !isTimeout(err) {
-		t.Fatalf("Accept: expected err %v, got %v", errTimeout, err)
-	}
-	ln.SetDeadline(noDeadline)
-	errc := make(chan error)
+	defer ln.Close()
+
+	max := time.NewTimer(time.Second)
+	defer max.Stop()
+	ch := make(chan error)
 	go func() {
-		_, err := ln.Accept()
-		errc <- err
+		if err := ln.(*TCPListener).SetDeadline(noDeadline); err != nil {
+			t.Error(err)
+		}
+		if err := ln.(*TCPListener).SetDeadline(time.Now().Add(10 * time.Millisecond)); err != nil {
+			t.Error(err)
+		}
+		c, err := ln.Accept()
+		if err == nil {
+			c.Close()
+		}
+		ch <- err
 	}()
-	time.Sleep(100 * time.Millisecond)
+
 	select {
-	case err := <-errc:
-		t.Fatalf("Expected Accept() to not return, but it returned with %v\n", err)
-	default:
-	}
-	ln.Close()
-	switch nerr := <-errc; err := nerr.(type) {
-	case *OpError:
-		if err.Err != errClosing {
-			t.Fatalf("Accept: expected err %v, got %v", errClosing, err)
+	case <-max.C:
+		ln.Close()
+		<-ch // wait for tester goroutine to stop
+		t.Fatal("Accept didn't return in an expected time")
+	case err := <-ch:
+		if perr := parseAcceptError(err); perr != nil {
+			t.Error(perr)
 		}
-	default:
-		if err != errClosing {
-			t.Fatalf("Accept: expected err %v, got %v", errClosing, err)
+		if nerr, ok := err.(Error); !ok || !nerr.Timeout() {
+			t.Fatal(err)
 		}
 	}
 }
 
+func TestAcceptTimeoutMustNotReturn(t *testing.T) {
+	switch runtime.GOOS {
+	case "plan9":
+		t.Skipf("not supported on %s", runtime.GOOS)
+	}
+
+	ln, err := newLocalListener("tcp")
+	if err != nil {
+		t.Fatal(err)
+	}
+	defer ln.Close()
+
+	max := time.NewTimer(100 * time.Millisecond)
+	defer max.Stop()
+	ch := make(chan error)
+	go func() {
+		if err := ln.(*TCPListener).SetDeadline(time.Now().Add(-5 * time.Second)); err != nil {
+			t.Error(err)
+		}
+		if err := ln.(*TCPListener).SetDeadline(noDeadline); err != nil {
+			t.Error(err)
+		}
+		_, err := ln.Accept()
+		ch <- err
+	}()
+
+	select {
+	case err := <-ch:
+		if perr := parseAcceptError(err); perr != nil {
+			t.Error(perr)
+		}
+		t.Fatalf("expected Accept to not return, but it returned with %v", err)
+	case <-max.C:
+		ln.Close()
+		<-ch // wait for tester goroutine to stop
+	}
+}
+
+var readTimeoutTests = []struct {
+	timeout time.Duration
+	xerrs   [2]error // expected errors in transition
+}{
+	// Tests that read deadlines work, even if there's data ready
+	// to be read.
+	{-5 * time.Second, [2]error{errTimeout, errTimeout}},
+
+	{50 * time.Millisecond, [2]error{nil, errTimeout}},
+}
+
 func TestReadTimeout(t *testing.T) {
 	switch runtime.GOOS {
 	case "plan9":
-		t.Skipf("skipping test on %q", runtime.GOOS)
+		t.Skipf("not supported on %s", runtime.GOOS)
 	}
 
-	ln := newLocalListener(t)
-	defer ln.Close()
-	c, err := DialTCP("tcp", nil, ln.Addr().(*TCPAddr))
+	handler := func(ls *localServer, ln Listener) {
+		c, err := ln.Accept()
+		if err != nil {
+			t.Error(err)
+			return
+		}
+		c.Write([]byte("READ TIMEOUT TEST"))
+		defer c.Close()
+	}
+	ls, err := newLocalServer("tcp")
 	if err != nil {
-		t.Fatalf("Connect: %v", err)
+		t.Fatal(err)
+	}
+	defer ls.teardown()
+	if err := ls.buildup(handler); err != nil {
+		t.Fatal(err)
+	}
+
+	c, err := Dial(ls.Listener.Addr().Network(), ls.Listener.Addr().String())
+	if err != nil {
+		t.Fatal(err)
 	}
 	defer c.Close()
-	c.SetDeadline(time.Now().Add(time.Hour))
-	c.SetReadDeadline(time.Now().Add(-1 * time.Second))
-	buf := make([]byte, 1)
-	if _, err = c.Read(buf); !isTimeout(err) {
-		t.Fatalf("Read: expected err %v, got %v", errTimeout, err)
+
+	for i, tt := range readTimeoutTests {
+		if err := c.SetReadDeadline(time.Now().Add(tt.timeout)); err != nil {
+			t.Fatalf("#%d: %v", i, err)
+		}
+		var b [1]byte
+		for j, xerr := range tt.xerrs {
+			for {
+				n, err := c.Read(b[:])
+				if xerr != nil {
+					if perr := parseReadError(err); perr != nil {
+						t.Errorf("#%d/%d: %v", i, j, perr)
+					}
+					if nerr, ok := err.(Error); !ok || !nerr.Timeout() {
+						t.Fatalf("#%d/%d: %v", i, j, err)
+					}
+				}
+				if err == nil {
+					time.Sleep(tt.timeout / 3)
+					continue
+				}
+				if n != 0 {
+					t.Fatalf("#%d/%d: read %d; want 0", i, j, n)
+				}
+				break
+			}
+		}
 	}
-	if _, err = c.Read(buf); !isTimeout(err) {
-		t.Fatalf("Read: expected err %v, got %v", errTimeout, err)
+}
+
+func TestReadTimeoutMustNotReturn(t *testing.T) {
+	switch runtime.GOOS {
+	case "plan9":
+		t.Skipf("not supported on %s", runtime.GOOS)
 	}
-	c.SetDeadline(time.Now().Add(100 * time.Millisecond))
-	if _, err = c.Read(buf); !isTimeout(err) {
-		t.Fatalf("Read: expected err %v, got %v", errTimeout, err)
+
+	ln, err := newLocalListener("tcp")
+	if err != nil {
+		t.Fatal(err)
 	}
-	if _, err = c.Read(buf); !isTimeout(err) {
-		t.Fatalf("Read: expected err %v, got %v", errTimeout, err)
+	defer ln.Close()
+
+	c, err := Dial(ln.Addr().Network(), ln.Addr().String())
+	if err != nil {
+		t.Fatal(err)
 	}
-	c.SetReadDeadline(noDeadline)
-	c.SetWriteDeadline(time.Now().Add(-1 * time.Second))
-	errc := make(chan error)
+	defer c.Close()
+
+	max := time.NewTimer(100 * time.Millisecond)
+	defer max.Stop()
+	ch := make(chan error)
 	go func() {
-		_, err := c.Read(buf)
-		errc <- err
+		if err := c.SetDeadline(time.Now().Add(-5 * time.Second)); err != nil {
+			t.Error(err)
+		}
+		if err := c.SetWriteDeadline(time.Now().Add(-5 * time.Second)); err != nil {
+			t.Error(err)
+		}
+		if err := c.SetReadDeadline(noDeadline); err != nil {
+			t.Error(err)
+		}
+		var b [1]byte
+		_, err := c.Read(b[:])
+		ch <- err
 	}()
-	time.Sleep(100 * time.Millisecond)
+
 	select {
-	case err := <-errc:
-		t.Fatalf("Expected Read() to not return, but it returned with %v\n", err)
-	default:
-	}
-	c.Close()
-	switch nerr := <-errc; err := nerr.(type) {
-	case *OpError:
-		if err.Err != errClosing {
-			t.Fatalf("Read: expected err %v, got %v", errClosing, err)
+	case err := <-ch:
+		if perr := parseReadError(err); perr != nil {
+			t.Error(perr)
 		}
-	default:
-		if err == io.EOF && runtime.GOOS == "nacl" { // close enough; golang.org/issue/8044
-			break
+		t.Fatalf("expected Read to not return, but it returned with %v", err)
+	case <-max.C:
+		c.Close()
+		err := <-ch // wait for tester goroutine to stop
+		if perr := parseReadError(err); perr != nil {
+			t.Error(perr)
 		}
-		if err != errClosing {
-			t.Fatalf("Read: expected err %v, got %v", errClosing, err)
+		if err == io.EOF && runtime.GOOS == "nacl" { // see golang.org/issue/8044
+			return
+		}
+		if nerr, ok := err.(Error); !ok || nerr.Timeout() || nerr.Temporary() {
+			t.Fatal(err)
 		}
 	}
 }
 
+var readFromTimeoutTests = []struct {
+	timeout time.Duration
+	xerrs   [2]error // expected errors in transition
+}{
+	// Tests that read deadlines work, even if there's data ready
+	// to be read.
+	{-5 * time.Second, [2]error{errTimeout, errTimeout}},
+
+	{50 * time.Millisecond, [2]error{nil, errTimeout}},
+}
+
+func TestReadFromTimeout(t *testing.T) {
+	switch runtime.GOOS {
+	case "nacl", "plan9":
+		t.Skipf("not supported on %s", runtime.GOOS) // see golang.org/issue/8916
+	}
+
+	ch := make(chan Addr)
+	defer close(ch)
+	handler := func(ls *localPacketServer, c PacketConn) {
+		if dst, ok := <-ch; ok {
+			c.WriteTo([]byte("READFROM TIMEOUT TEST"), dst)
+		}
+	}
+	ls, err := newLocalPacketServer("udp")
+	if err != nil {
+		t.Fatal(err)
+	}
+	defer ls.teardown()
+	if err := ls.buildup(handler); err != nil {
+		t.Fatal(err)
+	}
+
+	host, _, err := SplitHostPort(ls.PacketConn.LocalAddr().String())
+	if err != nil {
+		t.Fatal(err)
+	}
+	c, err := ListenPacket(ls.PacketConn.LocalAddr().Network(), JoinHostPort(host, "0"))
+	if err != nil {
+		t.Fatal(err)
+	}
+	defer c.Close()
+	ch <- c.LocalAddr()
+
+	for i, tt := range readFromTimeoutTests {
+		if err := c.SetReadDeadline(time.Now().Add(tt.timeout)); err != nil {
+			t.Fatalf("#%d: %v", i, err)
+		}
+		var b [1]byte
+		for j, xerr := range tt.xerrs {
+			for {
+				n, _, err := c.ReadFrom(b[:])
+				if xerr != nil {
+					if perr := parseReadError(err); perr != nil {
+						t.Errorf("#%d/%d: %v", i, j, perr)
+					}
+					if nerr, ok := err.(Error); !ok || !nerr.Timeout() {
+						t.Fatalf("#%d/%d: %v", i, j, err)
+					}
+				}
+				if err == nil {
+					time.Sleep(tt.timeout / 3)
+					continue
+				}
+				if n != 0 {
+					t.Fatalf("#%d/%d: read %d; want 0", i, j, n)
+				}
+				break
+			}
+		}
+	}
+}
+
+var writeTimeoutTests = []struct {
+	timeout time.Duration
+	xerrs   [2]error // expected errors in transition
+}{
+	// Tests that write deadlines work, even if there's buffer
+	// space available to write.
+	{-5 * time.Second, [2]error{errTimeout, errTimeout}},
+
+	{10 * time.Millisecond, [2]error{nil, errTimeout}},
+}
+
 func TestWriteTimeout(t *testing.T) {
 	switch runtime.GOOS {
 	case "plan9":
-		t.Skipf("skipping test on %q", runtime.GOOS)
+		t.Skipf("not supported on %s", runtime.GOOS)
 	}
 
-	ln := newLocalListener(t)
-	defer ln.Close()
-	c, err := DialTCP("tcp", nil, ln.Addr().(*TCPAddr))
-	if err != nil {
-		t.Fatalf("Connect: %v", err)
-	}
-	defer c.Close()
-	c.SetDeadline(time.Now().Add(time.Hour))
-	c.SetWriteDeadline(time.Now().Add(-1 * time.Second))
-	buf := make([]byte, 4096)
-	writeUntilTimeout := func() {
-		for {
-			_, err := c.Write(buf)
-			if err != nil {
-				if isTimeout(err) {
-					return
-				}
-				t.Fatalf("Write: expected err %v, got %v", errTimeout, err)
-			}
-		}
-	}
-	writeUntilTimeout()
-	c.SetDeadline(time.Now().Add(10 * time.Millisecond))
-	writeUntilTimeout()
-	writeUntilTimeout()
-	c.SetWriteDeadline(noDeadline)
-	c.SetReadDeadline(time.Now().Add(-1 * time.Second))
-	errc := make(chan error)
-	go func() {
-		for {
-			_, err := c.Write(buf)
-			if err != nil {
-				errc <- err
-			}
-		}
-	}()
-	time.Sleep(100 * time.Millisecond)
-	select {
-	case err := <-errc:
-		t.Fatalf("Expected Write() to not return, but it returned with %v\n", err)
-	default:
-	}
-	c.Close()
-	switch nerr := <-errc; err := nerr.(type) {
-	case *OpError:
-		if err.Err != errClosing {
-			t.Fatalf("Write: expected err %v, got %v", errClosing, err)
-		}
-	default:
-		if err != errClosing {
-			t.Fatalf("Write: expected err %v, got %v", errClosing, err)
-		}
-	}
-}
-
-func testTimeout(t *testing.T, net, addr string, readFrom bool) {
-	c, err := Dial(net, addr)
-	if err != nil {
-		t.Errorf("Dial(%q, %q) failed: %v", net, addr, err)
-		return
-	}
-	defer c.Close()
-	what := "Read"
-	if readFrom {
-		what = "ReadFrom"
-	}
-
-	errc := make(chan error, 1)
-	go func() {
-		t0 := time.Now()
-		c.SetReadDeadline(time.Now().Add(100 * time.Millisecond))
-		var b [100]byte
-		var n int
-		var err error
-		if readFrom {
-			n, _, err = c.(PacketConn).ReadFrom(b[0:])
-		} else {
-			n, err = c.Read(b[0:])
-		}
-		t1 := time.Now()
-		if n != 0 || err == nil || !err.(Error).Timeout() {
-			errc <- fmt.Errorf("%s(%q, %q) did not return 0, timeout: %v, %v", what, net, addr, n, err)
-			return
-		}
-		if dt := t1.Sub(t0); dt < 50*time.Millisecond || !testing.Short() && dt > 250*time.Millisecond {
-			errc <- fmt.Errorf("%s(%q, %q) took %s, expected 0.1s", what, net, addr, dt)
-			return
-		}
-		errc <- nil
-	}()
-	select {
-	case err := <-errc:
-		if err != nil {
-			t.Error(err)
-		}
-	case <-time.After(1 * time.Second):
-		t.Errorf("%s(%q, %q) took over 1 second, expected 0.1s", what, net, addr)
-	}
-}
-
-func TestTimeoutUDP(t *testing.T) {
-	switch runtime.GOOS {
-	case "plan9":
-		t.Skipf("skipping test on %q", runtime.GOOS)
-	}
-
-	// set up a listener that won't talk back
-	listening := make(chan string)
-	done := make(chan int)
-	go runDatagramPacketConnServer(t, "udp", "127.0.0.1:0", listening, done)
-	addr := <-listening
-
-	testTimeout(t, "udp", addr, false)
-	testTimeout(t, "udp", addr, true)
-	<-done
-}
-
-func TestTimeoutTCP(t *testing.T) {
-	switch runtime.GOOS {
-	case "plan9":
-		t.Skipf("skipping test on %q", runtime.GOOS)
-	}
-
-	// set up a listener that won't talk back
-	listening := make(chan string)
-	done := make(chan int)
-	go runStreamConnServer(t, "tcp", "127.0.0.1:0", listening, done)
-	addr := <-listening
-
-	testTimeout(t, "tcp", addr, false)
-	<-done
-}
-
-func TestDeadlineReset(t *testing.T) {
-	switch runtime.GOOS {
-	case "plan9":
-		t.Skipf("skipping test on %q", runtime.GOOS)
-	}
-	ln, err := Listen("tcp", "127.0.0.1:0")
+	ln, err := newLocalListener("tcp")
 	if err != nil {
 		t.Fatal(err)
 	}
 	defer ln.Close()
-	tl := ln.(*TCPListener)
-	tl.SetDeadline(time.Now().Add(1 * time.Minute))
-	tl.SetDeadline(noDeadline) // reset it
-	errc := make(chan error, 1)
-	go func() {
-		_, err := ln.Accept()
-		errc <- err
-	}()
-	select {
-	case <-time.After(50 * time.Millisecond):
-		// Pass.
-	case err := <-errc:
-		// Accept should never return; we never
-		// connected to it.
-		t.Errorf("unexpected return from Accept; err=%v", err)
-	}
-}
 
-func TestTimeoutAccept(t *testing.T) {
-	switch runtime.GOOS {
-	case "plan9":
-		t.Skipf("skipping test on %q", runtime.GOOS)
-	}
-	ln, err := Listen("tcp", "127.0.0.1:0")
-	if err != nil {
-		t.Fatal(err)
-	}
-	defer ln.Close()
-	tl := ln.(*TCPListener)
-	tl.SetDeadline(time.Now().Add(100 * time.Millisecond))
-	errc := make(chan error, 1)
-	go func() {
-		_, err := ln.Accept()
-		errc <- err
-	}()
-	select {
-	case <-time.After(1 * time.Second):
-		// Accept shouldn't block indefinitely
-		t.Errorf("Accept didn't return in an expected time")
-	case <-errc:
-		// Pass.
-	}
-}
-
-func TestReadWriteDeadline(t *testing.T) {
-	switch runtime.GOOS {
-	case "plan9":
-		t.Skipf("skipping test on %q", runtime.GOOS)
-	}
-
-	const (
-		readTimeout  = 50 * time.Millisecond
-		writeTimeout = 250 * time.Millisecond
-	)
-	checkTimeout := func(command string, start time.Time, should time.Duration) {
-		is := time.Now().Sub(start)
-		d := is - should
-		if d < -30*time.Millisecond || !testing.Short() && 150*time.Millisecond < d {
-			t.Errorf("%s timeout test failed: is=%v should=%v\n", command, is, should)
-		}
-	}
-
-	ln, err := Listen("tcp", "127.0.0.1:0")
-	if err != nil {
-		t.Fatalf("ListenTCP on :0: %v", err)
-	}
-	defer ln.Close()
-
-	lnquit := make(chan bool)
-
-	go func() {
-		c, err := ln.Accept()
+	for i, tt := range writeTimeoutTests {
+		c, err := Dial(ln.Addr().Network(), ln.Addr().String())
 		if err != nil {
-			t.Errorf("Accept: %v", err)
-			return
+			t.Fatal(err)
 		}
 		defer c.Close()
-		lnquit <- true
-	}()
 
-	c, err := Dial("tcp", ln.Addr().String())
-	if err != nil {
-		t.Fatalf("Dial: %v", err)
-	}
-	defer c.Close()
-
-	start := time.Now()
-	err = c.SetReadDeadline(start.Add(readTimeout))
-	if err != nil {
-		t.Fatalf("SetReadDeadline: %v", err)
-	}
-	err = c.SetWriteDeadline(start.Add(writeTimeout))
-	if err != nil {
-		t.Fatalf("SetWriteDeadline: %v", err)
-	}
-
-	quit := make(chan bool)
-
-	go func() {
-		var buf [10]byte
-		_, err := c.Read(buf[:])
-		if err == nil {
-			t.Errorf("Read should not succeed")
+		if err := c.SetWriteDeadline(time.Now().Add(tt.timeout)); err != nil {
+			t.Fatalf("#%d: %v", i, err)
 		}
-		checkTimeout("Read", start, readTimeout)
-		quit <- true
-	}()
-
-	go func() {
-		var buf [10000]byte
-		for {
-			_, err := c.Write(buf[:])
-			if err != nil {
+		for j, xerr := range tt.xerrs {
+			for {
+				n, err := c.Write([]byte("WRITE TIMEOUT TEST"))
+				if xerr != nil {
+					if perr := parseWriteError(err); perr != nil {
+						t.Errorf("#%d/%d: %v", i, j, perr)
+					}
+					if nerr, ok := err.(Error); !ok || !nerr.Timeout() {
+						t.Fatalf("#%d/%d: %v", i, j, err)
+					}
+				}
+				if err == nil {
+					time.Sleep(tt.timeout / 3)
+					continue
+				}
+				if n != 0 {
+					t.Fatalf("#%d/%d: wrote %d; want 0", i, j, n)
+				}
 				break
 			}
 		}
-		checkTimeout("Write", start, writeTimeout)
-		quit <- true
-	}()
-
-	<-quit
-	<-quit
-	<-lnquit
+	}
 }
 
-type neverEnding byte
-
-func (b neverEnding) Read(p []byte) (n int, err error) {
-	for i := range p {
-		p[i] = byte(b)
+func TestWriteTimeoutMustNotReturn(t *testing.T) {
+	switch runtime.GOOS {
+	case "plan9":
+		t.Skipf("not supported on %s", runtime.GOOS)
 	}
-	return len(p), nil
+
+	ln, err := newLocalListener("tcp")
+	if err != nil {
+		t.Fatal(err)
+	}
+	defer ln.Close()
+
+	c, err := Dial(ln.Addr().Network(), ln.Addr().String())
+	if err != nil {
+		t.Fatal(err)
+	}
+	defer c.Close()
+
+	max := time.NewTimer(100 * time.Millisecond)
+	defer max.Stop()
+	ch := make(chan error)
+	go func() {
+		if err := c.SetDeadline(time.Now().Add(-5 * time.Second)); err != nil {
+			t.Error(err)
+		}
+		if err := c.SetReadDeadline(time.Now().Add(-5 * time.Second)); err != nil {
+			t.Error(err)
+		}
+		if err := c.SetWriteDeadline(noDeadline); err != nil {
+			t.Error(err)
+		}
+		var b [1]byte
+		for {
+			if _, err := c.Write(b[:]); err != nil {
+				ch <- err
+				break
+			}
+		}
+	}()
+
+	select {
+	case err := <-ch:
+		if perr := parseWriteError(err); perr != nil {
+			t.Error(perr)
+		}
+		t.Fatalf("expected Write to not return, but it returned with %v", err)
+	case <-max.C:
+		c.Close()
+		err := <-ch // wait for tester goroutine to stop
+		if perr := parseWriteError(err); perr != nil {
+			t.Error(perr)
+		}
+		if nerr, ok := err.(Error); !ok || nerr.Timeout() || nerr.Temporary() {
+			t.Fatal(err)
+		}
+	}
+}
+
+var writeToTimeoutTests = []struct {
+	timeout time.Duration
+	xerrs   [2]error // expected errors in transition
+}{
+	// Tests that write deadlines work, even if there's buffer
+	// space available to write.
+	{-5 * time.Second, [2]error{errTimeout, errTimeout}},
+
+	{10 * time.Millisecond, [2]error{nil, errTimeout}},
+}
+
+func TestWriteToTimeout(t *testing.T) {
+	switch runtime.GOOS {
+	case "nacl", "plan9":
+		t.Skipf("not supported on %s", runtime.GOOS)
+	}
+
+	c1, err := newLocalPacketListener("udp")
+	if err != nil {
+		t.Fatal(err)
+	}
+	defer c1.Close()
+
+	host, _, err := SplitHostPort(c1.LocalAddr().String())
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	for i, tt := range writeToTimeoutTests {
+		c2, err := ListenPacket(c1.LocalAddr().Network(), JoinHostPort(host, "0"))
+		if err != nil {
+			t.Fatal(err)
+		}
+		defer c2.Close()
+
+		if err := c2.SetWriteDeadline(time.Now().Add(tt.timeout)); err != nil {
+			t.Fatalf("#%d: %v", i, err)
+		}
+		for j, xerr := range tt.xerrs {
+			for {
+				n, err := c2.WriteTo([]byte("WRITETO TIMEOUT TEST"), c1.LocalAddr())
+				if xerr != nil {
+					if perr := parseWriteError(err); perr != nil {
+						t.Errorf("#%d/%d: %v", i, j, perr)
+					}
+					if nerr, ok := err.(Error); !ok || !nerr.Timeout() {
+						t.Fatalf("#%d/%d: %v", i, j, err)
+					}
+				}
+				if err == nil {
+					time.Sleep(tt.timeout / 3)
+					continue
+				}
+				if n != 0 {
+					t.Fatalf("#%d/%d: wrote %d; want 0", i, j, n)
+				}
+				break
+			}
+		}
+	}
+}
+
+func TestReadTimeoutFluctuation(t *testing.T) {
+	switch runtime.GOOS {
+	case "plan9":
+		t.Skipf("not supported on %s", runtime.GOOS)
+	}
+
+	ln, err := newLocalListener("tcp")
+	if err != nil {
+		t.Fatal(err)
+	}
+	defer ln.Close()
+
+	c, err := Dial(ln.Addr().Network(), ln.Addr().String())
+	if err != nil {
+		t.Fatal(err)
+	}
+	defer c.Close()
+
+	max := time.NewTimer(time.Second)
+	defer max.Stop()
+	ch := make(chan error)
+	go timeoutReceiver(c, 100*time.Millisecond, 50*time.Millisecond, 250*time.Millisecond, ch)
+
+	select {
+	case <-max.C:
+		t.Fatal("Read took over 1s; expected 0.1s")
+	case err := <-ch:
+		if perr := parseReadError(err); perr != nil {
+			t.Error(perr)
+		}
+		if nerr, ok := err.(Error); !ok || !nerr.Timeout() {
+			t.Fatal(err)
+		}
+	}
+}
+
+func TestReadFromTimeoutFluctuation(t *testing.T) {
+	switch runtime.GOOS {
+	case "plan9":
+		t.Skipf("not supported on %s", runtime.GOOS)
+	}
+
+	c1, err := newLocalPacketListener("udp")
+	if err != nil {
+		t.Fatal(err)
+	}
+	defer c1.Close()
+
+	c2, err := Dial(c1.LocalAddr().Network(), c1.LocalAddr().String())
+	if err != nil {
+		t.Fatal(err)
+	}
+	defer c2.Close()
+
+	max := time.NewTimer(time.Second)
+	defer max.Stop()
+	ch := make(chan error)
+	go timeoutPacketReceiver(c2.(PacketConn), 100*time.Millisecond, 50*time.Millisecond, 250*time.Millisecond, ch)
+
+	select {
+	case <-max.C:
+		t.Fatal("ReadFrom took over 1s; expected 0.1s")
+	case err := <-ch:
+		if perr := parseReadError(err); perr != nil {
+			t.Error(perr)
+		}
+		if nerr, ok := err.(Error); !ok || !nerr.Timeout() {
+			t.Fatal(err)
+		}
+	}
+}
+
+func TestWriteTimeoutFluctuation(t *testing.T) {
+	switch runtime.GOOS {
+	case "plan9":
+		t.Skipf("not supported on %s", runtime.GOOS)
+	}
+
+	ln, err := newLocalListener("tcp")
+	if err != nil {
+		t.Fatal(err)
+	}
+	defer ln.Close()
+
+	c, err := Dial(ln.Addr().Network(), ln.Addr().String())
+	if err != nil {
+		t.Fatal(err)
+	}
+	defer c.Close()
+
+	d := time.Second
+	if runtime.GOOS == "darwin" && (runtime.GOARCH == "arm" || runtime.GOARCH == "arm64") {
+		d = 3 * time.Second // see golang.org/issue/10775
+	}
+	max := time.NewTimer(d)
+	defer max.Stop()
+	ch := make(chan error)
+	go timeoutTransmitter(c, 100*time.Millisecond, 50*time.Millisecond, 250*time.Millisecond, ch)
+
+	select {
+	case <-max.C:
+		t.Fatalf("Write took over %v; expected 0.1s", d)
+	case err := <-ch:
+		if perr := parseWriteError(err); perr != nil {
+			t.Error(perr)
+		}
+		if nerr, ok := err.(Error); !ok || !nerr.Timeout() {
+			t.Fatal(err)
+		}
+	}
 }
 
 func TestVariousDeadlines1Proc(t *testing.T) {
@@ -420,36 +739,57 @@
 	testVariousDeadlines(t, 4)
 }
 
+type neverEnding byte
+
+func (b neverEnding) Read(p []byte) (int, error) {
+	for i := range p {
+		p[i] = byte(b)
+	}
+	return len(p), nil
+}
+
 func testVariousDeadlines(t *testing.T, maxProcs int) {
 	switch runtime.GOOS {
 	case "plan9":
-		t.Skipf("skipping test on %q", runtime.GOOS)
+		t.Skipf("not supported on %s", runtime.GOOS)
 	}
 
 	defer runtime.GOMAXPROCS(runtime.GOMAXPROCS(maxProcs))
-	ln := newLocalListener(t)
-	defer ln.Close()
-	acceptc := make(chan error, 1)
 
-	// The server, with no timeouts of its own, sending bytes to clients
-	// as fast as it can.
-	servec := make(chan copyRes)
-	go func() {
+	type result struct {
+		n   int64
+		err error
+		d   time.Duration
+	}
+
+	ch := make(chan error, 1)
+	pasvch := make(chan result)
+	handler := func(ls *localServer, ln Listener) {
 		for {
 			c, err := ln.Accept()
 			if err != nil {
-				acceptc <- err
+				ch <- err
 				return
 			}
+			// The server, with no timeouts of its own,
+			// sending bytes to clients as fast as it can.
 			go func() {
 				t0 := time.Now()
 				n, err := io.Copy(c, neverEnding('a'))
-				d := time.Since(t0)
+				dt := time.Since(t0)
 				c.Close()
-				servec <- copyRes{n, err, d}
+				pasvch <- result{n, err, dt}
 			}()
 		}
-	}()
+	}
+	ls, err := newLocalServer("tcp")
+	if err != nil {
+		t.Fatal(err)
+	}
+	defer ls.teardown()
+	if err := ls.buildup(handler); err != nil {
+		t.Fatal(err)
+	}
 
 	for _, timeout := range []time.Duration{
 		1 * time.Nanosecond,
@@ -483,236 +823,133 @@
 			name := fmt.Sprintf("%v run %d/%d", timeout, run+1, numRuns)
 			t.Log(name)
 
-			c, err := Dial("tcp", ln.Addr().String())
+			c, err := Dial(ls.Listener.Addr().Network(), ls.Listener.Addr().String())
 			if err != nil {
-				t.Fatalf("Dial: %v", err)
+				t.Fatal(err)
 			}
-			clientc := make(chan copyRes)
-			go func() {
-				t0 := time.Now()
-				c.SetDeadline(t0.Add(timeout))
-				n, err := io.Copy(ioutil.Discard, c)
-				d := time.Since(t0)
-				c.Close()
-				clientc <- copyRes{n, err, d}
-			}()
 
 			tooLong := 5 * time.Second
+			max := time.NewTimer(tooLong)
+			defer max.Stop()
+			actvch := make(chan result)
+			go func() {
+				t0 := time.Now()
+				if err := c.SetDeadline(t0.Add(timeout)); err != nil {
+					t.Error(err)
+				}
+				n, err := io.Copy(ioutil.Discard, c)
+				dt := time.Since(t0)
+				c.Close()
+				actvch <- result{n, err, dt}
+			}()
+
 			select {
-			case res := <-clientc:
-				if isTimeout(res.err) {
+			case res := <-actvch:
+				if nerr, ok := res.err.(Error); ok && nerr.Timeout() {
 					t.Logf("for %v, good client timeout after %v, reading %d bytes", name, res.d, res.n)
 				} else {
-					t.Fatalf("for %v: client Copy = %d, %v (want timeout)", name, res.n, res.err)
+					t.Fatalf("for %v, client Copy = %d, %v; want timeout", name, res.n, res.err)
 				}
-			case <-time.After(tooLong):
-				t.Fatalf("for %v: timeout (%v) waiting for client to timeout (%v) reading", name, tooLong, timeout)
+			case <-max.C:
+				t.Fatalf("for %v, timeout (%v) waiting for client to timeout (%v) reading", name, tooLong, timeout)
 			}
 
 			select {
-			case res := <-servec:
-				t.Logf("for %v: server in %v wrote %d, %v", name, res.d, res.n, res.err)
-			case err := <-acceptc:
-				t.Fatalf("for %v: server Accept = %v", name, err)
-			case <-time.After(tooLong):
+			case res := <-pasvch:
+				t.Logf("for %v, server in %v wrote %d: %v", name, res.d, res.n, res.err)
+			case err := <-ch:
+				t.Fatalf("for %v, Accept = %v", name, err)
+			case <-max.C:
 				t.Fatalf("for %v, timeout waiting for server to finish writing", name)
 			}
 		}
 	}
 }
 
-// TestReadDeadlineDataAvailable tests that read deadlines work, even
-// if there's data ready to be read.
-func TestReadDeadlineDataAvailable(t *testing.T) {
+// TestReadWriteProlongedTimeout tests concurrent deadline
+// modification. Known to cause data races in the past.
+func TestReadWriteProlongedTimeout(t *testing.T) {
 	switch runtime.GOOS {
 	case "plan9":
-		t.Skipf("skipping test on %q", runtime.GOOS)
+		t.Skipf("not supported on %s", runtime.GOOS)
 	}
 
-	ln := newLocalListener(t)
-	defer ln.Close()
-
-	servec := make(chan copyRes)
-	const msg = "data client shouldn't read, even though it'll be waiting"
-	go func() {
+	handler := func(ls *localServer, ln Listener) {
 		c, err := ln.Accept()
 		if err != nil {
-			t.Errorf("Accept: %v", err)
+			t.Error(err)
 			return
 		}
 		defer c.Close()
-		n, err := c.Write([]byte(msg))
-		servec <- copyRes{n: int64(n), err: err}
-	}()
 
-	c, err := Dial("tcp", ln.Addr().String())
-	if err != nil {
-		t.Fatalf("Dial: %v", err)
-	}
-	defer c.Close()
-	if res := <-servec; res.err != nil || res.n != int64(len(msg)) {
-		t.Fatalf("unexpected server Write: n=%d, err=%v; want n=%d, err=nil", res.n, res.err, len(msg))
-	}
-	c.SetReadDeadline(time.Now().Add(-5 * time.Second)) // in the psat.
-	buf := make([]byte, len(msg)/2)
-	n, err := c.Read(buf)
-	if n > 0 || !isTimeout(err) {
-		t.Fatalf("client read = %d (%q) err=%v; want 0, timeout", n, buf[:n], err)
-	}
-}
-
-// TestWriteDeadlineBufferAvailable tests that write deadlines work, even
-// if there's buffer space available to write.
-func TestWriteDeadlineBufferAvailable(t *testing.T) {
-	switch runtime.GOOS {
-	case "plan9":
-		t.Skipf("skipping test on %q", runtime.GOOS)
-	}
-
-	ln := newLocalListener(t)
-	defer ln.Close()
-
-	servec := make(chan copyRes)
-	go func() {
-		c, err := ln.Accept()
-		if err != nil {
-			t.Errorf("Accept: %v", err)
-			return
-		}
-		defer c.Close()
-		c.SetWriteDeadline(time.Now().Add(-5 * time.Second)) // in the past
-		n, err := c.Write([]byte{'x'})
-		servec <- copyRes{n: int64(n), err: err}
-	}()
-
-	c, err := Dial("tcp", ln.Addr().String())
-	if err != nil {
-		t.Fatalf("Dial: %v", err)
-	}
-	defer c.Close()
-	res := <-servec
-	if res.n != 0 {
-		t.Errorf("Write = %d; want 0", res.n)
-	}
-	if !isTimeout(res.err) {
-		t.Errorf("Write error = %v; want timeout", res.err)
-	}
-}
-
-// TestAcceptDeadlineConnectionAvailable tests that accept deadlines work, even
-// if there's incoming connections available.
-func TestAcceptDeadlineConnectionAvailable(t *testing.T) {
-	switch runtime.GOOS {
-	case "plan9":
-		t.Skipf("skipping test on %q", runtime.GOOS)
-	}
-
-	ln := newLocalListener(t).(*TCPListener)
-	defer ln.Close()
-
-	go func() {
-		c, err := Dial("tcp", ln.Addr().String())
-		if err != nil {
-			t.Errorf("Dial: %v", err)
-			return
-		}
-		defer c.Close()
-		var buf [1]byte
-		c.Read(buf[:]) // block until the connection or listener is closed
-	}()
-	time.Sleep(10 * time.Millisecond)
-	ln.SetDeadline(time.Now().Add(-5 * time.Second)) // in the past
-	c, err := ln.Accept()
-	if err == nil {
-		defer c.Close()
-	}
-	if !isTimeout(err) {
-		t.Fatalf("Accept: got %v; want timeout", err)
-	}
-}
-
-// TestConnectDeadlineInThePast tests that connect deadlines work, even
-// if the connection can be established w/o blocking.
-func TestConnectDeadlineInThePast(t *testing.T) {
-	switch runtime.GOOS {
-	case "plan9":
-		t.Skipf("skipping test on %q", runtime.GOOS)
-	}
-
-	ln := newLocalListener(t).(*TCPListener)
-	defer ln.Close()
-
-	go func() {
-		c, err := ln.Accept()
-		if err == nil {
-			defer c.Close()
-		}
-	}()
-	time.Sleep(10 * time.Millisecond)
-	c, err := DialTimeout("tcp", ln.Addr().String(), -5*time.Second) // in the past
-	if err == nil {
-		defer c.Close()
-	}
-	if !isTimeout(err) {
-		t.Fatalf("DialTimeout: got %v; want timeout", err)
-	}
-}
-
-// TestProlongTimeout tests concurrent deadline modification.
-// Known to cause data races in the past.
-func TestProlongTimeout(t *testing.T) {
-	switch runtime.GOOS {
-	case "plan9":
-		t.Skipf("skipping test on %q", runtime.GOOS)
-	}
-
-	ln := newLocalListener(t)
-	defer ln.Close()
-	connected := make(chan bool)
-	go func() {
-		s, err := ln.Accept()
-		connected <- true
-		if err != nil {
-			t.Errorf("ln.Accept: %v", err)
-			return
-		}
-		defer s.Close()
-		s.SetDeadline(time.Now().Add(time.Hour))
+		var wg sync.WaitGroup
+		wg.Add(2)
 		go func() {
-			var buf [4096]byte
+			defer wg.Done()
+			var b [1]byte
 			for {
-				_, err := s.Write(buf[:])
-				if err != nil {
-					break
+				if err := c.SetReadDeadline(time.Now().Add(time.Hour)); err != nil {
+					if perr := parseCommonError(err); perr != nil {
+						t.Error(perr)
+					}
+					t.Error(err)
+					return
 				}
-				s.SetDeadline(time.Now().Add(time.Hour))
+				if _, err := c.Read(b[:]); err != nil {
+					if perr := parseReadError(err); perr != nil {
+						t.Error(perr)
+					}
+					return
+				}
 			}
 		}()
-		buf := make([]byte, 1)
-		for {
-			_, err := s.Read(buf)
-			if err != nil {
-				break
+		go func() {
+			defer wg.Done()
+			var b [1]byte
+			for {
+				if err := c.SetWriteDeadline(time.Now().Add(time.Hour)); err != nil {
+					if perr := parseCommonError(err); perr != nil {
+						t.Error(perr)
+					}
+					t.Error(err)
+					return
+				}
+				if _, err := c.Write(b[:]); err != nil {
+					if perr := parseWriteError(err); perr != nil {
+						t.Error(perr)
+					}
+					return
+				}
 			}
-			s.SetDeadline(time.Now().Add(time.Hour))
-		}
-	}()
-	c, err := Dial("tcp", ln.Addr().String())
+		}()
+		wg.Wait()
+	}
+	ls, err := newLocalServer("tcp")
 	if err != nil {
-		t.Fatalf("DialTCP: %v", err)
+		t.Fatal(err)
+	}
+	defer ls.teardown()
+	if err := ls.buildup(handler); err != nil {
+		t.Fatal(err)
+	}
+
+	c, err := Dial(ls.Listener.Addr().Network(), ls.Listener.Addr().String())
+	if err != nil {
+		t.Fatal(err)
 	}
 	defer c.Close()
-	<-connected
-	for i := 0; i < 1024; i++ {
-		var buf [1]byte
-		c.Write(buf[:])
+
+	var b [1]byte
+	for i := 0; i < 1000; i++ {
+		c.Write(b[:])
+		c.Read(b[:])
 	}
 }
 
-func TestDeadlineRace(t *testing.T) {
+func TestReadWriteDeadlineRace(t *testing.T) {
 	switch runtime.GOOS {
 	case "nacl", "plan9":
-		t.Skipf("skipping test on %q", runtime.GOOS)
+		t.Skipf("not supported on %s", runtime.GOOS)
 	}
 
 	N := 1000
@@ -720,28 +957,54 @@
 		N = 50
 	}
 	defer runtime.GOMAXPROCS(runtime.GOMAXPROCS(4))
-	ln := newLocalListener(t)
-	defer ln.Close()
-	c, err := Dial("tcp", ln.Addr().String())
+
+	ln, err := newLocalListener("tcp")
 	if err != nil {
-		t.Fatalf("Dial: %v", err)
+		t.Fatal(err)
+	}
+	defer ln.Close()
+
+	c, err := Dial(ln.Addr().Network(), ln.Addr().String())
+	if err != nil {
+		t.Fatal(err)
 	}
 	defer c.Close()
-	done := make(chan bool)
+
+	var wg sync.WaitGroup
+	wg.Add(3)
 	go func() {
-		t := time.NewTicker(2 * time.Microsecond).C
+		defer wg.Done()
+		tic := time.NewTicker(2 * time.Microsecond)
+		defer tic.Stop()
 		for i := 0; i < N; i++ {
-			if err := c.SetDeadline(time.Now().Add(2 * time.Microsecond)); err != nil {
+			if err := c.SetReadDeadline(time.Now().Add(2 * time.Microsecond)); err != nil {
+				if perr := parseCommonError(err); perr != nil {
+					t.Error(perr)
+				}
 				break
 			}
-			<-t
+			if err := c.SetWriteDeadline(time.Now().Add(2 * time.Microsecond)); err != nil {
+				if perr := parseCommonError(err); perr != nil {
+					t.Error(perr)
+				}
+				break
+			}
+			<-tic.C
 		}
-		done <- true
 	}()
-	var buf [1]byte
-	for i := 0; i < N; i++ {
-		c.Read(buf[:]) // ignore possible timeout errors
-	}
-	c.Close()
-	<-done
+	go func() {
+		defer wg.Done()
+		var b [1]byte
+		for i := 0; i < N; i++ {
+			c.Read(b[:]) // ignore possible timeout errors
+		}
+	}()
+	go func() {
+		defer wg.Done()
+		var b [1]byte
+		for i := 0; i < N; i++ {
+			c.Write(b[:]) // ignore possible timeout errors
+		}
+	}()
+	wg.Wait() // wait for tester goroutine to stop
 }
diff --git a/third_party/gofrontend/libgo/go/net/udp_test.go b/third_party/gofrontend/libgo/go/net/udp_test.go
index 125bbca..b25f96a 100644
--- a/third_party/gofrontend/libgo/go/net/udp_test.go
+++ b/third_party/gofrontend/libgo/go/net/udp_test.go
@@ -7,149 +7,164 @@
 import (
 	"reflect"
 	"runtime"
-	"strings"
 	"testing"
 	"time"
 )
 
-func TestResolveUDPAddr(t *testing.T) {
-	for _, tt := range resolveTCPAddrTests {
-		net := strings.Replace(tt.net, "tcp", "udp", -1)
-		addr, err := ResolveUDPAddr(net, tt.litAddrOrName)
-		if err != tt.err {
-			t.Fatalf("ResolveUDPAddr(%q, %q) failed: %v", net, tt.litAddrOrName, err)
-		}
-		if !reflect.DeepEqual(addr, (*UDPAddr)(tt.addr)) {
-			t.Fatalf("ResolveUDPAddr(%q, %q) = %#v, want %#v", net, tt.litAddrOrName, addr, tt.addr)
-		}
-		if err == nil {
-			str := addr.String()
-			addr1, err := ResolveUDPAddr(net, str)
-			if err != nil {
-				t.Fatalf("ResolveUDPAddr(%q, %q) [from %q]: %v", net, str, tt.litAddrOrName, err)
-			}
-			if !reflect.DeepEqual(addr1, addr) {
-				t.Fatalf("ResolveUDPAddr(%q, %q) [from %q] = %#v, want %#v", net, str, tt.litAddrOrName, addr1, addr)
-			}
-		}
-	}
+type resolveUDPAddrTest struct {
+	network       string
+	litAddrOrName string
+	addr          *UDPAddr
+	err           error
 }
 
-func TestReadFromUDP(t *testing.T) {
-	switch runtime.GOOS {
-	case "nacl", "plan9":
-		t.Skipf("skipping test on %q, see issue 8916", runtime.GOOS)
-	}
+var resolveUDPAddrTests = []resolveUDPAddrTest{
+	{"udp", "127.0.0.1:0", &UDPAddr{IP: IPv4(127, 0, 0, 1), Port: 0}, nil},
+	{"udp4", "127.0.0.1:65535", &UDPAddr{IP: IPv4(127, 0, 0, 1), Port: 65535}, nil},
 
-	ra, err := ResolveUDPAddr("udp", "127.0.0.1:7")
-	if err != nil {
-		t.Fatal(err)
-	}
+	{"udp", "[::1]:0", &UDPAddr{IP: ParseIP("::1"), Port: 0}, nil},
+	{"udp6", "[::1]:65535", &UDPAddr{IP: ParseIP("::1"), Port: 65535}, nil},
 
-	la, err := ResolveUDPAddr("udp", "127.0.0.1:0")
-	if err != nil {
-		t.Fatal(err)
-	}
+	{"udp", "[::1%en0]:1", &UDPAddr{IP: ParseIP("::1"), Port: 1, Zone: "en0"}, nil},
+	{"udp6", "[::1%911]:2", &UDPAddr{IP: ParseIP("::1"), Port: 2, Zone: "911"}, nil},
 
-	c, err := ListenUDP("udp", la)
-	if err != nil {
-		t.Fatal(err)
-	}
-	defer c.Close()
+	{"", "127.0.0.1:0", &UDPAddr{IP: IPv4(127, 0, 0, 1), Port: 0}, nil}, // Go 1.0 behavior
+	{"", "[::1]:0", &UDPAddr{IP: ParseIP("::1"), Port: 0}, nil},         // Go 1.0 behavior
 
-	_, err = c.WriteToUDP([]byte("a"), ra)
-	if err != nil {
-		t.Fatal(err)
-	}
+	{"udp", ":12345", &UDPAddr{Port: 12345}, nil},
 
-	err = c.SetDeadline(time.Now().Add(100 * time.Millisecond))
-	if err != nil {
-		t.Fatal(err)
-	}
-	b := make([]byte, 1)
-	_, _, err = c.ReadFromUDP(b)
-	if err == nil {
-		t.Fatal("ReadFromUDP should fail")
-	} else if !isTimeout(err) {
-		t.Fatal(err)
+	{"http", "127.0.0.1:0", nil, UnknownNetworkError("http")},
+}
+
+func TestResolveUDPAddr(t *testing.T) {
+	origTestHookLookupIP := testHookLookupIP
+	defer func() { testHookLookupIP = origTestHookLookupIP }()
+	testHookLookupIP = lookupLocalhost
+
+	for i, tt := range resolveUDPAddrTests {
+		addr, err := ResolveUDPAddr(tt.network, tt.litAddrOrName)
+		if err != tt.err {
+			t.Errorf("#%d: %v", i, err)
+		} else if !reflect.DeepEqual(addr, tt.addr) {
+			t.Errorf("#%d: got %#v; want %#v", i, addr, tt.addr)
+		}
+		if err != nil {
+			continue
+		}
+		rtaddr, err := ResolveUDPAddr(addr.Network(), addr.String())
+		if err != nil {
+			t.Errorf("#%d: %v", i, err)
+		} else if !reflect.DeepEqual(rtaddr, addr) {
+			t.Errorf("#%d: got %#v; want %#v", i, rtaddr, addr)
+		}
 	}
 }
 
 func TestWriteToUDP(t *testing.T) {
 	switch runtime.GOOS {
 	case "plan9":
-		t.Skipf("skipping test on %q", runtime.GOOS)
+		t.Skipf("not supported on %s", runtime.GOOS)
 	}
 
-	l, err := ListenPacket("udp", "127.0.0.1:0")
+	c, err := ListenPacket("udp", "127.0.0.1:0")
 	if err != nil {
-		t.Fatalf("Listen failed: %v", err)
+		t.Fatal(err)
 	}
-	defer l.Close()
+	defer c.Close()
 
-	testWriteToConn(t, l.LocalAddr().String())
-	testWriteToPacketConn(t, l.LocalAddr().String())
+	testWriteToConn(t, c.LocalAddr().String())
+	testWriteToPacketConn(t, c.LocalAddr().String())
 }
 
 func testWriteToConn(t *testing.T, raddr string) {
 	c, err := Dial("udp", raddr)
 	if err != nil {
-		t.Fatalf("Dial failed: %v", err)
+		t.Fatal(err)
 	}
 	defer c.Close()
 
 	ra, err := ResolveUDPAddr("udp", raddr)
 	if err != nil {
-		t.Fatalf("ResolveUDPAddr failed: %v", err)
+		t.Fatal(err)
 	}
 
-	_, err = c.(*UDPConn).WriteToUDP([]byte("Connection-oriented mode socket"), ra)
+	b := []byte("CONNECTED-MODE SOCKET")
+	_, err = c.(*UDPConn).WriteToUDP(b, ra)
 	if err == nil {
-		t.Fatal("WriteToUDP should fail")
+		t.Fatal("should fail")
 	}
 	if err != nil && err.(*OpError).Err != ErrWriteToConnected {
-		t.Fatalf("WriteToUDP should fail as ErrWriteToConnected: %v", err)
+		t.Fatalf("should fail as ErrWriteToConnected: %v", err)
 	}
-
-	_, err = c.(*UDPConn).WriteTo([]byte("Connection-oriented mode socket"), ra)
+	_, err = c.(*UDPConn).WriteTo(b, ra)
 	if err == nil {
-		t.Fatal("WriteTo should fail")
+		t.Fatal("should fail")
 	}
 	if err != nil && err.(*OpError).Err != ErrWriteToConnected {
-		t.Fatalf("WriteTo should fail as ErrWriteToConnected: %v", err)
+		t.Fatalf("should fail as ErrWriteToConnected: %v", err)
 	}
-
-	_, err = c.Write([]byte("Connection-oriented mode socket"))
+	_, err = c.Write(b)
 	if err != nil {
-		t.Fatalf("Write failed: %v", err)
+		t.Fatal(err)
+	}
+	_, _, err = c.(*UDPConn).WriteMsgUDP(b, nil, ra)
+	if err == nil {
+		t.Fatal("should fail")
+	}
+	if err != nil && err.(*OpError).Err != ErrWriteToConnected {
+		t.Fatalf("should fail as ErrWriteToConnected: %v", err)
+	}
+	_, _, err = c.(*UDPConn).WriteMsgUDP(b, nil, nil)
+	switch runtime.GOOS {
+	case "nacl", "windows": // see golang.org/issue/9252
+		t.Skipf("not implemented yet on %s", runtime.GOOS)
+	default:
+		if err != nil {
+			t.Fatal(err)
+		}
 	}
 }
 
 func testWriteToPacketConn(t *testing.T, raddr string) {
 	c, err := ListenPacket("udp", "127.0.0.1:0")
 	if err != nil {
-		t.Fatalf("ListenPacket failed: %v", err)
+		t.Fatal(err)
 	}
 	defer c.Close()
 
 	ra, err := ResolveUDPAddr("udp", raddr)
 	if err != nil {
-		t.Fatalf("ResolveUDPAddr failed: %v", err)
+		t.Fatal(err)
 	}
 
-	_, err = c.(*UDPConn).WriteToUDP([]byte("Connection-less mode socket"), ra)
+	b := []byte("UNCONNECTED-MODE SOCKET")
+	_, err = c.(*UDPConn).WriteToUDP(b, ra)
 	if err != nil {
-		t.Fatalf("WriteToUDP failed: %v", err)
+		t.Fatal(err)
 	}
-
-	_, err = c.WriteTo([]byte("Connection-less mode socket"), ra)
+	_, err = c.WriteTo(b, ra)
 	if err != nil {
-		t.Fatalf("WriteTo failed: %v", err)
+		t.Fatal(err)
 	}
-
-	_, err = c.(*UDPConn).Write([]byte("Connection-less mode socket"))
+	_, err = c.(*UDPConn).Write(b)
 	if err == nil {
-		t.Fatal("Write should fail")
+		t.Fatal("should fail")
+	}
+	_, _, err = c.(*UDPConn).WriteMsgUDP(b, nil, nil)
+	if err == nil {
+		t.Fatal("should fail")
+	}
+	if err != nil && err.(*OpError).Err != errMissingAddress {
+		t.Fatalf("should fail as errMissingAddress: %v", err)
+	}
+	_, _, err = c.(*UDPConn).WriteMsgUDP(b, nil, ra)
+	switch runtime.GOOS {
+	case "nacl", "windows": // see golang.org/issue/9252
+		t.Skipf("not implemented yet on %s", runtime.GOOS)
+	default:
+		if err != nil {
+			t.Fatal(err)
+		}
 	}
 }
 
@@ -164,13 +179,13 @@
 
 func TestUDPConnLocalName(t *testing.T) {
 	if testing.Short() || !*testExternal {
-		t.Skip("skipping test to avoid external network")
+		t.Skip("avoid external network")
 	}
 
 	for _, tt := range udpConnLocalNameTests {
 		c, err := ListenUDP(tt.net, tt.laddr)
 		if err != nil {
-			t.Fatalf("ListenUDP failed: %v", err)
+			t.Fatal(err)
 		}
 		defer c.Close()
 		la := c.LocalAddr()
@@ -184,7 +199,7 @@
 	for _, laddr := range []string{"", "127.0.0.1:0"} {
 		c1, err := ListenPacket("udp", "127.0.0.1:0")
 		if err != nil {
-			t.Fatalf("ListenUDP failed: %v", err)
+			t.Fatal(err)
 		}
 		defer c1.Close()
 
@@ -192,12 +207,12 @@
 		if laddr != "" {
 			var err error
 			if la, err = ResolveUDPAddr("udp", laddr); err != nil {
-				t.Fatalf("ResolveUDPAddr failed: %v", err)
+				t.Fatal(err)
 			}
 		}
 		c2, err := DialUDP("udp", la, c1.LocalAddr().(*UDPAddr))
 		if err != nil {
-			t.Fatalf("DialUDP failed: %v", err)
+			t.Fatal(err)
 		}
 		defer c2.Close()
 
@@ -220,60 +235,37 @@
 
 func TestIPv6LinkLocalUnicastUDP(t *testing.T) {
 	if testing.Short() || !*testExternal {
-		t.Skip("skipping test to avoid external network")
+		t.Skip("avoid external network")
 	}
 	if !supportsIPv6 {
-		t.Skip("ipv6 is not supported")
-	}
-	ifi := loopbackInterface()
-	if ifi == nil {
-		t.Skip("loopback interface not found")
-	}
-	laddr := ipv6LinkLocalUnicastAddr(ifi)
-	if laddr == "" {
-		t.Skip("ipv6 unicast address on loopback not found")
+		t.Skip("IPv6 is not supported")
 	}
 
-	type test struct {
-		net, addr  string
-		nameLookup bool
-	}
-	var tests = []test{
-		{"udp", "[" + laddr + "%" + ifi.Name + "]:0", false},
-		{"udp6", "[" + laddr + "%" + ifi.Name + "]:0", false},
-	}
-	// The first udp test fails on DragonFly - see issue 7473.
-	if runtime.GOOS == "dragonfly" {
-		tests = tests[1:]
-	}
-	switch runtime.GOOS {
-	case "darwin", "dragonfly", "freebsd", "openbsd", "netbsd":
-		tests = append(tests, []test{
-			{"udp", "[localhost%" + ifi.Name + "]:0", true},
-			{"udp6", "[localhost%" + ifi.Name + "]:0", true},
-		}...)
-	case "linux":
-		tests = append(tests, []test{
-			{"udp", "[ip6-localhost%" + ifi.Name + "]:0", true},
-			{"udp6", "[ip6-localhost%" + ifi.Name + "]:0", true},
-		}...)
-	}
-	for _, tt := range tests {
-		c1, err := ListenPacket(tt.net, tt.addr)
+	for i, tt := range ipv6LinkLocalUnicastUDPTests {
+		c1, err := ListenPacket(tt.network, tt.address)
 		if err != nil {
 			// It might return "LookupHost returned no
 			// suitable address" error on some platforms.
-			t.Logf("ListenPacket failed: %v", err)
+			t.Log(err)
 			continue
 		}
-		defer c1.Close()
+		ls, err := (&packetListener{PacketConn: c1}).newLocalServer()
+		if err != nil {
+			t.Fatal(err)
+		}
+		defer ls.teardown()
+		ch := make(chan error, 1)
+		handler := func(ls *localPacketServer, c PacketConn) { packetTransponder(c, ch) }
+		if err := ls.buildup(handler); err != nil {
+			t.Fatal(err)
+		}
 		if la, ok := c1.LocalAddr().(*UDPAddr); !ok || !tt.nameLookup && la.Zone == "" {
 			t.Fatalf("got %v; expected a proper address with zone identifier", la)
 		}
 
-		c2, err := Dial(tt.net, c1.LocalAddr().String())
+		c2, err := Dial(tt.network, ls.PacketConn.LocalAddr().String())
 		if err != nil {
-			t.Fatalf("Dial failed: %v", err)
+			t.Fatal(err)
 		}
 		defer c2.Close()
 		if la, ok := c2.LocalAddr().(*UDPAddr); !ok || !tt.nameLookup && la.Zone == "" {
@@ -284,14 +276,88 @@
 		}
 
 		if _, err := c2.Write([]byte("UDP OVER IPV6 LINKLOCAL TEST")); err != nil {
-			t.Fatalf("Conn.Write failed: %v", err)
+			t.Fatal(err)
 		}
 		b := make([]byte, 32)
-		if _, from, err := c1.ReadFrom(b); err != nil {
-			t.Fatalf("PacketConn.ReadFrom failed: %v", err)
+		if _, err := c2.Read(b); err != nil {
+			t.Fatal(err)
+		}
+
+		for err := range ch {
+			t.Errorf("#%d: %v", i, err)
+		}
+	}
+}
+
+func TestUDPZeroBytePayload(t *testing.T) {
+	switch runtime.GOOS {
+	case "nacl", "plan9":
+		t.Skipf("not supported on %s", runtime.GOOS)
+	}
+
+	c, err := newLocalPacketListener("udp")
+	if err != nil {
+		t.Fatal(err)
+	}
+	defer c.Close()
+
+	for _, genericRead := range []bool{false, true} {
+		n, err := c.WriteTo(nil, c.LocalAddr())
+		if err != nil {
+			t.Fatal(err)
+		}
+		if n != 0 {
+			t.Errorf("got %d; want 0", n)
+		}
+		c.SetReadDeadline(time.Now().Add(100 * time.Millisecond))
+		var b [1]byte
+		if genericRead {
+			_, err = c.(Conn).Read(b[:])
 		} else {
-			if ra, ok := from.(*UDPAddr); !ok || !tt.nameLookup && ra.Zone == "" {
-				t.Fatalf("got %v; expected a proper address with zone identifier", ra)
+			_, _, err = c.ReadFrom(b[:])
+		}
+		switch err {
+		case nil: // ReadFrom succeeds
+		default: // Read may timeout, it depends on the platform
+			if nerr, ok := err.(Error); !ok || !nerr.Timeout() {
+				t.Fatal(err)
+			}
+		}
+	}
+}
+
+func TestUDPZeroByteBuffer(t *testing.T) {
+	switch runtime.GOOS {
+	case "nacl", "plan9":
+		t.Skipf("not supported on %s", runtime.GOOS)
+	}
+
+	c, err := newLocalPacketListener("udp")
+	if err != nil {
+		t.Fatal(err)
+	}
+	defer c.Close()
+
+	b := []byte("UDP ZERO BYTE BUFFER TEST")
+	for _, genericRead := range []bool{false, true} {
+		n, err := c.WriteTo(b, c.LocalAddr())
+		if err != nil {
+			t.Fatal(err)
+		}
+		if n != len(b) {
+			t.Errorf("got %d; want %d", n, len(b))
+		}
+		c.SetReadDeadline(time.Now().Add(100 * time.Millisecond))
+		if genericRead {
+			_, err = c.(Conn).Read(nil)
+		} else {
+			_, _, err = c.ReadFrom(nil)
+		}
+		switch err {
+		case nil: // ReadFrom succeeds
+		default: // Read may timeout, it depends on the platform
+			if nerr, ok := err.(Error); (!ok || !nerr.Timeout()) && runtime.GOOS != "windows" { // Windows retruns WSAEMSGSIZ
+				t.Fatal(err)
 			}
 		}
 	}
diff --git a/third_party/gofrontend/libgo/go/net/udpsock.go b/third_party/gofrontend/libgo/go/net/udpsock.go
index 4c99ae4..9292133 100644
--- a/third_party/gofrontend/libgo/go/net/udpsock.go
+++ b/third_party/gofrontend/libgo/go/net/udpsock.go
@@ -25,7 +25,14 @@
 	return JoinHostPort(ip, itoa(a.Port))
 }
 
-func (a *UDPAddr) toAddr() Addr {
+func (a *UDPAddr) isWildcard() bool {
+	if a == nil || a.IP == nil {
+		return true
+	}
+	return a.IP.IsUnspecified()
+}
+
+func (a *UDPAddr) opAddr() Addr {
 	if a == nil {
 		return nil
 	}
@@ -46,9 +53,9 @@
 	default:
 		return nil, UnknownNetworkError(net)
 	}
-	a, err := resolveInternetAddr(net, addr, noDeadline)
+	addrs, err := internetAddrList(net, addr, noDeadline)
 	if err != nil {
 		return nil, err
 	}
-	return a.toAddr().(*UDPAddr), nil
+	return addrs.first(isIPv4).(*UDPAddr), nil
 }
diff --git a/third_party/gofrontend/libgo/go/net/udpsock_plan9.go b/third_party/gofrontend/libgo/go/net/udpsock_plan9.go
index 510ac5e..1ba57a2 100644
--- a/third_party/gofrontend/libgo/go/net/udpsock_plan9.go
+++ b/third_party/gofrontend/libgo/go/net/udpsock_plan9.go
@@ -33,10 +33,10 @@
 	buf := make([]byte, udpHeaderSize+len(b))
 	m, err := c.fd.data.Read(buf)
 	if err != nil {
-		return
+		return 0, nil, &OpError{Op: "read", Net: c.fd.dir, Source: c.fd.laddr, Addr: c.fd.raddr, Err: err}
 	}
 	if m < udpHeaderSize {
-		return 0, nil, errors.New("short read reading UDP header")
+		return 0, nil, &OpError{Op: "read", Net: c.fd.dir, Source: c.fd.laddr, Addr: c.fd.raddr, Err: errors.New("short read reading UDP header")}
 	}
 	buf = buf[:m]
 
@@ -59,7 +59,7 @@
 // flags that were set on the packet and the source address of the
 // packet.
 func (c *UDPConn) ReadMsgUDP(b, oob []byte) (n, oobn, flags int, addr *UDPAddr, err error) {
-	return 0, 0, 0, nil, syscall.EPLAN9
+	return 0, 0, 0, nil, &OpError{Op: "read", Net: c.fd.dir, Source: c.fd.laddr, Addr: c.fd.raddr, Err: syscall.EPLAN9}
 }
 
 // WriteToUDP writes a UDP packet to addr via c, copying the payload
@@ -74,7 +74,7 @@
 		return 0, syscall.EINVAL
 	}
 	if addr == nil {
-		return 0, &OpError{Op: "write", Net: c.fd.dir, Addr: nil, Err: errMissingAddress}
+		return 0, &OpError{Op: "write", Net: c.fd.dir, Source: c.fd.laddr, Addr: nil, Err: errMissingAddress}
 	}
 	h := new(udpHeader)
 	h.raddr = addr.IP.To16()
@@ -86,7 +86,10 @@
 	buf := make([]byte, udpHeaderSize+len(b))
 	i := copy(buf, h.Bytes())
 	copy(buf[i:], b)
-	return c.fd.data.Write(buf)
+	if _, err := c.fd.data.Write(buf); err != nil {
+		return 0, &OpError{Op: "write", Net: c.fd.dir, Source: c.fd.laddr, Addr: addr.opAddr(), Err: err}
+	}
+	return len(b), nil
 }
 
 // WriteTo implements the PacketConn WriteTo method.
@@ -96,16 +99,18 @@
 	}
 	a, ok := addr.(*UDPAddr)
 	if !ok {
-		return 0, &OpError{"write", c.fd.dir, addr, syscall.EINVAL}
+		return 0, &OpError{Op: "write", Net: c.fd.dir, Source: c.fd.laddr, Addr: addr, Err: syscall.EINVAL}
 	}
 	return c.WriteToUDP(b, a)
 }
 
-// WriteMsgUDP writes a packet to addr via c, copying the payload from
-// b and the associated out-of-band data from oob.  It returns the
-// number of payload and out-of-band bytes written.
+// WriteMsgUDP writes a packet to addr via c if c isn't connected, or
+// to c's remote destination address if c is connected (in which case
+// addr must be nil).  The payload is copied from b and the associated
+// out-of-band data is copied from oob.  It returns the number of
+// payload and out-of-band bytes written.
 func (c *UDPConn) WriteMsgUDP(b, oob []byte, addr *UDPAddr) (n, oobn int, err error) {
-	return 0, 0, syscall.EPLAN9
+	return 0, 0, &OpError{Op: "write", Net: c.fd.dir, Source: c.fd.laddr, Addr: addr.opAddr(), Err: syscall.EPLAN9}
 }
 
 // DialUDP connects to the remote address raddr on the network net,
@@ -122,10 +127,10 @@
 	switch net {
 	case "udp", "udp4", "udp6":
 	default:
-		return nil, UnknownNetworkError(net)
+		return nil, &OpError{Op: "dial", Net: net, Source: laddr.opAddr(), Addr: raddr.opAddr(), Err: UnknownNetworkError(net)}
 	}
 	if raddr == nil {
-		return nil, &OpError{"dial", net, nil, errMissingAddress}
+		return nil, &OpError{Op: "dial", Net: net, Source: laddr.opAddr(), Addr: nil, Err: errMissingAddress}
 	}
 	fd, err := dialPlan9(net, laddr, raddr)
 	if err != nil {
@@ -173,7 +178,7 @@
 	switch net {
 	case "udp", "udp4", "udp6":
 	default:
-		return nil, UnknownNetworkError(net)
+		return nil, &OpError{Op: "listen", Net: net, Source: nil, Addr: laddr.opAddr(), Err: UnknownNetworkError(net)}
 	}
 	if laddr == nil {
 		laddr = &UDPAddr{}
@@ -184,20 +189,27 @@
 	}
 	_, err = l.ctl.WriteString("headers")
 	if err != nil {
-		return nil, err
+		return nil, &OpError{Op: "listen", Net: net, Source: nil, Addr: laddr, Err: err}
 	}
 	l.data, err = os.OpenFile(l.dir+"/data", os.O_RDWR, 0)
 	if err != nil {
-		return nil, err
+		return nil, &OpError{Op: "listen", Net: net, Source: nil, Addr: laddr, Err: err}
 	}
 	fd, err := l.netFD()
 	return newUDPConn(fd), err
 }
 
 // ListenMulticastUDP listens for incoming multicast UDP packets
-// addressed to the group address gaddr on ifi, which specifies the
-// interface to join.  ListenMulticastUDP uses default multicast
-// interface if ifi is nil.
-func ListenMulticastUDP(net string, ifi *Interface, gaddr *UDPAddr) (*UDPConn, error) {
-	return nil, syscall.EPLAN9
+// addressed to the group address gaddr on the interface ifi.
+// Network must be "udp", "udp4" or "udp6".
+// ListenMulticastUDP uses the system-assigned multicast interface
+// when ifi is nil, although this is not recommended because the
+// assignment depends on platforms and sometimes it might require
+// routing configuration.
+//
+// ListenMulticastUDP is just for convenience of simple, small
+// applications. There are golang.org/x/net/ipv4 and
+// golang.org/x/net/ipv6 packages for general purpose uses.
+func ListenMulticastUDP(network string, ifi *Interface, gaddr *UDPAddr) (*UDPConn, error) {
+	return nil, &OpError{Op: "listen", Net: network, Source: nil, Addr: gaddr.opAddr(), Err: syscall.EPLAN9}
 }
diff --git a/third_party/gofrontend/libgo/go/net/udpsock_posix.go b/third_party/gofrontend/libgo/go/net/udpsock_posix.go
index a053336..61868c4 100644
--- a/third_party/gofrontend/libgo/go/net/udpsock_posix.go
+++ b/third_party/gofrontend/libgo/go/net/udpsock_posix.go
@@ -31,13 +31,6 @@
 	return syscall.AF_INET6
 }
 
-func (a *UDPAddr) isWildcard() bool {
-	if a == nil || a.IP == nil {
-		return true
-	}
-	return a.IP.IsUnspecified()
-}
-
 func (a *UDPAddr) sockaddr(family int) (syscall.Sockaddr, error) {
 	if a == nil {
 		return nil, nil
@@ -60,10 +53,11 @@
 // ReadFromUDP can be made to time out and return an error with
 // Timeout() == true after a fixed time limit; see SetDeadline and
 // SetReadDeadline.
-func (c *UDPConn) ReadFromUDP(b []byte) (n int, addr *UDPAddr, err error) {
+func (c *UDPConn) ReadFromUDP(b []byte) (int, *UDPAddr, error) {
 	if !c.ok() {
 		return 0, nil, syscall.EINVAL
 	}
+	var addr *UDPAddr
 	n, sa, err := c.fd.readFrom(b)
 	switch sa := sa.(type) {
 	case *syscall.SockaddrInet4:
@@ -71,7 +65,10 @@
 	case *syscall.SockaddrInet6:
 		addr = &UDPAddr{IP: sa.Addr[0:], Port: sa.Port, Zone: zoneToString(int(sa.ZoneId))}
 	}
-	return
+	if err != nil {
+		err = &OpError{Op: "read", Net: c.fd.net, Source: c.fd.laddr, Addr: c.fd.raddr, Err: err}
+	}
+	return n, addr, err
 }
 
 // ReadFrom implements the PacketConn ReadFrom method.
@@ -80,7 +77,10 @@
 		return 0, nil, syscall.EINVAL
 	}
 	n, addr, err := c.ReadFromUDP(b)
-	return n, addr.toAddr(), err
+	if addr == nil {
+		return n, nil, err
+	}
+	return n, addr, err
 }
 
 // ReadMsgUDP reads a packet from c, copying the payload into b and
@@ -100,6 +100,9 @@
 	case *syscall.SockaddrInet6:
 		addr = &UDPAddr{IP: sa.Addr[0:], Port: sa.Port, Zone: zoneToString(int(sa.ZoneId))}
 	}
+	if err != nil {
+		err = &OpError{Op: "read", Net: c.fd.net, Source: c.fd.laddr, Addr: c.fd.raddr, Err: err}
+	}
 	return
 }
 
@@ -115,16 +118,20 @@
 		return 0, syscall.EINVAL
 	}
 	if c.fd.isConnected {
-		return 0, &OpError{"write", c.fd.net, addr, ErrWriteToConnected}
+		return 0, &OpError{Op: "write", Net: c.fd.net, Source: c.fd.laddr, Addr: addr.opAddr(), Err: ErrWriteToConnected}
 	}
 	if addr == nil {
-		return 0, &OpError{Op: "write", Net: c.fd.net, Addr: nil, Err: errMissingAddress}
+		return 0, &OpError{Op: "write", Net: c.fd.net, Source: c.fd.laddr, Addr: nil, Err: errMissingAddress}
 	}
 	sa, err := addr.sockaddr(c.fd.family)
 	if err != nil {
-		return 0, &OpError{"write", c.fd.net, addr, err}
+		return 0, &OpError{Op: "write", Net: c.fd.net, Source: c.fd.laddr, Addr: addr.opAddr(), Err: err}
 	}
-	return c.fd.writeTo(b, sa)
+	n, err := c.fd.writeTo(b, sa)
+	if err != nil {
+		err = &OpError{Op: "write", Net: c.fd.net, Source: c.fd.laddr, Addr: addr.opAddr(), Err: err}
+	}
+	return n, err
 }
 
 // WriteTo implements the PacketConn WriteTo method.
@@ -134,29 +141,36 @@
 	}
 	a, ok := addr.(*UDPAddr)
 	if !ok {
-		return 0, &OpError{"write", c.fd.net, addr, syscall.EINVAL}
+		return 0, &OpError{Op: "write", Net: c.fd.net, Source: c.fd.laddr, Addr: addr, Err: syscall.EINVAL}
 	}
 	return c.WriteToUDP(b, a)
 }
 
-// WriteMsgUDP writes a packet to addr via c, copying the payload from
-// b and the associated out-of-band data from oob.  It returns the
-// number of payload and out-of-band bytes written.
+// WriteMsgUDP writes a packet to addr via c if c isn't connected, or
+// to c's remote destination address if c is connected (in which case
+// addr must be nil).  The payload is copied from b and the associated
+// out-of-band data is copied from oob.  It returns the number of
+// payload and out-of-band bytes written.
 func (c *UDPConn) WriteMsgUDP(b, oob []byte, addr *UDPAddr) (n, oobn int, err error) {
 	if !c.ok() {
 		return 0, 0, syscall.EINVAL
 	}
-	if c.fd.isConnected {
-		return 0, 0, &OpError{"write", c.fd.net, addr, ErrWriteToConnected}
+	if c.fd.isConnected && addr != nil {
+		return 0, 0, &OpError{Op: "write", Net: c.fd.net, Source: c.fd.laddr, Addr: addr.opAddr(), Err: ErrWriteToConnected}
 	}
-	if addr == nil {
-		return 0, 0, &OpError{Op: "write", Net: c.fd.net, Addr: nil, Err: errMissingAddress}
+	if !c.fd.isConnected && addr == nil {
+		return 0, 0, &OpError{Op: "write", Net: c.fd.net, Source: c.fd.laddr, Addr: addr.opAddr(), Err: errMissingAddress}
 	}
-	sa, err := addr.sockaddr(c.fd.family)
+	var sa syscall.Sockaddr
+	sa, err = addr.sockaddr(c.fd.family)
 	if err != nil {
-		return 0, 0, &OpError{"write", c.fd.net, addr, err}
+		return 0, 0, &OpError{Op: "write", Net: c.fd.net, Source: c.fd.laddr, Addr: addr.opAddr(), Err: err}
 	}
-	return c.fd.writeMsg(b, oob, sa)
+	n, oobn, err = c.fd.writeMsg(b, oob, sa)
+	if err != nil {
+		err = &OpError{Op: "write", Net: c.fd.net, Source: c.fd.laddr, Addr: addr.opAddr(), Err: err}
+	}
+	return
 }
 
 // DialUDP connects to the remote address raddr on the network net,
@@ -166,10 +180,10 @@
 	switch net {
 	case "udp", "udp4", "udp6":
 	default:
-		return nil, &OpError{Op: "dial", Net: net, Addr: raddr, Err: UnknownNetworkError(net)}
+		return nil, &OpError{Op: "dial", Net: net, Source: laddr.opAddr(), Addr: raddr.opAddr(), Err: UnknownNetworkError(net)}
 	}
 	if raddr == nil {
-		return nil, &OpError{Op: "dial", Net: net, Addr: nil, Err: errMissingAddress}
+		return nil, &OpError{Op: "dial", Net: net, Source: laddr.opAddr(), Addr: nil, Err: errMissingAddress}
 	}
 	return dialUDP(net, laddr, raddr, noDeadline)
 }
@@ -177,7 +191,7 @@
 func dialUDP(net string, laddr, raddr *UDPAddr, deadline time.Time) (*UDPConn, error) {
 	fd, err := internetSocket(net, laddr, raddr, deadline, syscall.SOCK_DGRAM, 0, "dial")
 	if err != nil {
-		return nil, &OpError{Op: "dial", Net: net, Addr: raddr, Err: err}
+		return nil, &OpError{Op: "dial", Net: net, Source: laddr.opAddr(), Addr: raddr.opAddr(), Err: err}
 	}
 	return newUDPConn(fd), nil
 }
@@ -193,45 +207,52 @@
 	switch net {
 	case "udp", "udp4", "udp6":
 	default:
-		return nil, &OpError{Op: "listen", Net: net, Addr: laddr, Err: UnknownNetworkError(net)}
+		return nil, &OpError{Op: "listen", Net: net, Source: nil, Addr: laddr.opAddr(), Err: UnknownNetworkError(net)}
 	}
 	if laddr == nil {
 		laddr = &UDPAddr{}
 	}
 	fd, err := internetSocket(net, laddr, nil, noDeadline, syscall.SOCK_DGRAM, 0, "listen")
 	if err != nil {
-		return nil, &OpError{Op: "listen", Net: net, Addr: laddr, Err: err}
+		return nil, &OpError{Op: "listen", Net: net, Source: nil, Addr: laddr, Err: err}
 	}
 	return newUDPConn(fd), nil
 }
 
 // ListenMulticastUDP listens for incoming multicast UDP packets
-// addressed to the group address gaddr on ifi, which specifies the
-// interface to join.  ListenMulticastUDP uses default multicast
-// interface if ifi is nil.
-func ListenMulticastUDP(net string, ifi *Interface, gaddr *UDPAddr) (*UDPConn, error) {
-	switch net {
+// addressed to the group address gaddr on the interface ifi.
+// Network must be "udp", "udp4" or "udp6".
+// ListenMulticastUDP uses the system-assigned multicast interface
+// when ifi is nil, although this is not recommended because the
+// assignment depends on platforms and sometimes it might require
+// routing configuration.
+//
+// ListenMulticastUDP is just for convenience of simple, small
+// applications. There are golang.org/x/net/ipv4 and
+// golang.org/x/net/ipv6 packages for general purpose uses.
+func ListenMulticastUDP(network string, ifi *Interface, gaddr *UDPAddr) (*UDPConn, error) {
+	switch network {
 	case "udp", "udp4", "udp6":
 	default:
-		return nil, &OpError{Op: "listen", Net: net, Addr: gaddr, Err: UnknownNetworkError(net)}
+		return nil, &OpError{Op: "listen", Net: network, Source: nil, Addr: gaddr.opAddr(), Err: UnknownNetworkError(network)}
 	}
 	if gaddr == nil || gaddr.IP == nil {
-		return nil, &OpError{Op: "listen", Net: net, Addr: nil, Err: errMissingAddress}
+		return nil, &OpError{Op: "listen", Net: network, Source: nil, Addr: gaddr.opAddr(), Err: errMissingAddress}
 	}
-	fd, err := internetSocket(net, gaddr, nil, noDeadline, syscall.SOCK_DGRAM, 0, "listen")
+	fd, err := internetSocket(network, gaddr, nil, noDeadline, syscall.SOCK_DGRAM, 0, "listen")
 	if err != nil {
-		return nil, &OpError{Op: "listen", Net: net, Addr: gaddr, Err: err}
+		return nil, &OpError{Op: "listen", Net: network, Source: nil, Addr: gaddr, Err: err}
 	}
 	c := newUDPConn(fd)
 	if ip4 := gaddr.IP.To4(); ip4 != nil {
 		if err := listenIPv4MulticastUDP(c, ifi, ip4); err != nil {
 			c.Close()
-			return nil, &OpError{Op: "listen", Net: net, Addr: &IPAddr{IP: ip4}, Err: err}
+			return nil, &OpError{Op: "listen", Net: network, Source: c.fd.laddr, Addr: &IPAddr{IP: ip4}, Err: err}
 		}
 	} else {
 		if err := listenIPv6MulticastUDP(c, ifi, gaddr.IP); err != nil {
 			c.Close()
-			return nil, &OpError{Op: "listen", Net: net, Addr: &IPAddr{IP: gaddr.IP}, Err: err}
+			return nil, &OpError{Op: "listen", Net: network, Source: c.fd.laddr, Addr: &IPAddr{IP: gaddr.IP}, Err: err}
 		}
 	}
 	return c, nil
diff --git a/third_party/gofrontend/libgo/go/net/unicast_posix_test.go b/third_party/gofrontend/libgo/go/net/unicast_posix_test.go
deleted file mode 100644
index ab7ef40..0000000
--- a/third_party/gofrontend/libgo/go/net/unicast_posix_test.go
+++ /dev/null
@@ -1,469 +0,0 @@
-// Copyright 2011 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 !plan9
-
-package net
-
-import (
-	"runtime"
-	"syscall"
-	"testing"
-)
-
-var listenerTests = []struct {
-	net      string
-	laddr    string
-	ipv6     bool // test with underlying AF_INET6 socket
-	wildcard bool // test with wildcard address
-}{
-	{net: "tcp", laddr: "", wildcard: true},
-	{net: "tcp", laddr: "0.0.0.0", wildcard: true},
-	{net: "tcp", laddr: "[::ffff:0.0.0.0]", wildcard: true},
-	{net: "tcp", laddr: "[::]", ipv6: true, wildcard: true},
-
-	{net: "tcp", laddr: "127.0.0.1"},
-	{net: "tcp", laddr: "[::ffff:127.0.0.1]"},
-	{net: "tcp", laddr: "[::1]", ipv6: true},
-
-	{net: "tcp4", laddr: "", wildcard: true},
-	{net: "tcp4", laddr: "0.0.0.0", wildcard: true},
-	{net: "tcp4", laddr: "[::ffff:0.0.0.0]", wildcard: true},
-
-	{net: "tcp4", laddr: "127.0.0.1"},
-	{net: "tcp4", laddr: "[::ffff:127.0.0.1]"},
-
-	{net: "tcp6", laddr: "", ipv6: true, wildcard: true},
-	{net: "tcp6", laddr: "[::]", ipv6: true, wildcard: true},
-
-	{net: "tcp6", laddr: "[::1]", ipv6: true},
-}
-
-// TestTCPListener tests both single and double listen to a test
-// listener with same address family, same listening address and
-// same port.
-func TestTCPListener(t *testing.T) {
-	switch runtime.GOOS {
-	case "plan9":
-		t.Skipf("skipping test on %q", runtime.GOOS)
-	}
-
-	for _, tt := range listenerTests {
-		if tt.wildcard && (testing.Short() || !*testExternal) {
-			continue
-		}
-		if tt.ipv6 && !supportsIPv6 {
-			continue
-		}
-		l1, port := usableListenPort(t, tt.net, tt.laddr)
-		checkFirstListener(t, tt.net, tt.laddr+":"+port, l1)
-		l2, err := Listen(tt.net, tt.laddr+":"+port)
-		checkSecondListener(t, tt.net, tt.laddr+":"+port, err, l2)
-		l1.Close()
-	}
-}
-
-// TestUDPListener tests both single and double listen to a test
-// listener with same address family, same listening address and
-// same port.
-func TestUDPListener(t *testing.T) {
-	switch runtime.GOOS {
-	case "plan9":
-		t.Skipf("skipping test on %q", runtime.GOOS)
-	}
-
-	toudpnet := func(net string) string {
-		switch net {
-		case "tcp":
-			return "udp"
-		case "tcp4":
-			return "udp4"
-		case "tcp6":
-			return "udp6"
-		}
-		return "<nil>"
-	}
-
-	for _, tt := range listenerTests {
-		if tt.wildcard && (testing.Short() || !*testExternal) {
-			continue
-		}
-		if tt.ipv6 && !supportsIPv6 {
-			continue
-		}
-		tt.net = toudpnet(tt.net)
-		l1, port := usableListenPacketPort(t, tt.net, tt.laddr)
-		checkFirstListener(t, tt.net, tt.laddr+":"+port, l1)
-		l2, err := ListenPacket(tt.net, tt.laddr+":"+port)
-		checkSecondListener(t, tt.net, tt.laddr+":"+port, err, l2)
-		l1.Close()
-	}
-}
-
-var dualStackListenerTests = []struct {
-	net1     string // first listener
-	laddr1   string
-	net2     string // second listener
-	laddr2   string
-	wildcard bool  // test with wildcard address
-	xerr     error // expected error value, nil or other
-}{
-	// Test cases and expected results for the attemping 2nd listen on the same port
-	// 1st listen                2nd listen                 darwin  freebsd  linux  openbsd
-	// ------------------------------------------------------------------------------------
-	// "tcp"  ""                 "tcp"  ""                    -        -       -       -
-	// "tcp"  ""                 "tcp"  "0.0.0.0"             -        -       -       -
-	// "tcp"  "0.0.0.0"          "tcp"  ""                    -        -       -       -
-	// ------------------------------------------------------------------------------------
-	// "tcp"  ""                 "tcp"  "[::]"                -        -       -       ok
-	// "tcp"  "[::]"             "tcp"  ""                    -        -       -       ok
-	// "tcp"  "0.0.0.0"          "tcp"  "[::]"                -        -       -       ok
-	// "tcp"  "[::]"             "tcp"  "0.0.0.0"             -        -       -       ok
-	// "tcp"  "[::ffff:0.0.0.0]" "tcp"  "[::]"                -        -       -       ok
-	// "tcp"  "[::]"             "tcp"  "[::ffff:0.0.0.0]"    -        -       -       ok
-	// ------------------------------------------------------------------------------------
-	// "tcp4" ""                 "tcp6" ""                    ok       ok      ok      ok
-	// "tcp6" ""                 "tcp4" ""                    ok       ok      ok      ok
-	// "tcp4" "0.0.0.0"          "tcp6" "[::]"                ok       ok      ok      ok
-	// "tcp6" "[::]"             "tcp4" "0.0.0.0"             ok       ok      ok      ok
-	// ------------------------------------------------------------------------------------
-	// "tcp"  "127.0.0.1"        "tcp"  "[::1]"               ok       ok      ok      ok
-	// "tcp"  "[::1]"            "tcp"  "127.0.0.1"           ok       ok      ok      ok
-	// "tcp4" "127.0.0.1"        "tcp6" "[::1]"               ok       ok      ok      ok
-	// "tcp6" "[::1]"            "tcp4" "127.0.0.1"           ok       ok      ok      ok
-	//
-	// Platform default configurations:
-	// darwin, kernel version 11.3.0
-	//	net.inet6.ip6.v6only=0 (overridable by sysctl or IPV6_V6ONLY option)
-	// freebsd, kernel version 8.2
-	//	net.inet6.ip6.v6only=1 (overridable by sysctl or IPV6_V6ONLY option)
-	// linux, kernel version 3.0.0
-	//	net.ipv6.bindv6only=0 (overridable by sysctl or IPV6_V6ONLY option)
-	// openbsd, kernel version 5.0
-	//	net.inet6.ip6.v6only=1 (overriding is prohibited)
-
-	{net1: "tcp", laddr1: "", net2: "tcp", laddr2: "", wildcard: true, xerr: syscall.EADDRINUSE},
-	{net1: "tcp", laddr1: "", net2: "tcp", laddr2: "0.0.0.0", wildcard: true, xerr: syscall.EADDRINUSE},
-	{net1: "tcp", laddr1: "0.0.0.0", net2: "tcp", laddr2: "", wildcard: true, xerr: syscall.EADDRINUSE},
-
-	{net1: "tcp", laddr1: "", net2: "tcp", laddr2: "[::]", wildcard: true, xerr: syscall.EADDRINUSE},
-	{net1: "tcp", laddr1: "[::]", net2: "tcp", laddr2: "", wildcard: true, xerr: syscall.EADDRINUSE},
-	{net1: "tcp", laddr1: "0.0.0.0", net2: "tcp", laddr2: "[::]", wildcard: true, xerr: syscall.EADDRINUSE},
-	{net1: "tcp", laddr1: "[::]", net2: "tcp", laddr2: "0.0.0.0", wildcard: true, xerr: syscall.EADDRINUSE},
-	{net1: "tcp", laddr1: "[::ffff:0.0.0.0]", net2: "tcp", laddr2: "[::]", wildcard: true, xerr: syscall.EADDRINUSE},
-	{net1: "tcp", laddr1: "[::]", net2: "tcp", laddr2: "[::ffff:0.0.0.0]", wildcard: true, xerr: syscall.EADDRINUSE},
-
-	{net1: "tcp4", laddr1: "", net2: "tcp6", laddr2: "", wildcard: true},
-	{net1: "tcp6", laddr1: "", net2: "tcp4", laddr2: "", wildcard: true},
-	{net1: "tcp4", laddr1: "0.0.0.0", net2: "tcp6", laddr2: "[::]", wildcard: true},
-	{net1: "tcp6", laddr1: "[::]", net2: "tcp4", laddr2: "0.0.0.0", wildcard: true},
-
-	{net1: "tcp", laddr1: "127.0.0.1", net2: "tcp", laddr2: "[::1]"},
-	{net1: "tcp", laddr1: "[::1]", net2: "tcp", laddr2: "127.0.0.1"},
-	{net1: "tcp4", laddr1: "127.0.0.1", net2: "tcp6", laddr2: "[::1]"},
-	{net1: "tcp6", laddr1: "[::1]", net2: "tcp4", laddr2: "127.0.0.1"},
-}
-
-// TestDualStackTCPListener tests both single and double listen
-// to a test listener with various address families, different
-// listening address and same port.
-func TestDualStackTCPListener(t *testing.T) {
-	if testing.Short() {
-		t.Skip("skipping in -short mode, see issue 5001")
-	}
-	switch runtime.GOOS {
-	case "plan9":
-		t.Skipf("skipping test on %q", runtime.GOOS)
-	}
-	if !supportsIPv6 {
-		t.Skip("ipv6 is not supported")
-	}
-
-	for _, tt := range dualStackListenerTests {
-		if tt.wildcard && !*testExternal {
-			continue
-		}
-		switch runtime.GOOS {
-		case "openbsd":
-			if tt.wildcard && differentWildcardAddr(tt.laddr1, tt.laddr2) {
-				tt.xerr = nil
-			}
-		}
-		l1, port := usableListenPort(t, tt.net1, tt.laddr1)
-		laddr := tt.laddr1 + ":" + port
-		checkFirstListener(t, tt.net1, laddr, l1)
-		laddr = tt.laddr2 + ":" + port
-		l2, err := Listen(tt.net2, laddr)
-		checkDualStackSecondListener(t, tt.net2, laddr, tt.xerr, err, l2)
-		l1.Close()
-	}
-}
-
-// TestDualStackUDPListener tests both single and double listen
-// to a test listener with various address families, differnet
-// listening address and same port.
-func TestDualStackUDPListener(t *testing.T) {
-	if testing.Short() {
-		t.Skip("skipping in -short mode, see issue 5001")
-	}
-	switch runtime.GOOS {
-	case "plan9":
-		t.Skipf("skipping test on %q", runtime.GOOS)
-	}
-	if !supportsIPv6 {
-		t.Skip("ipv6 is not supported")
-	}
-
-	toudpnet := func(net string) string {
-		switch net {
-		case "tcp":
-			return "udp"
-		case "tcp4":
-			return "udp4"
-		case "tcp6":
-			return "udp6"
-		}
-		return "<nil>"
-	}
-
-	for _, tt := range dualStackListenerTests {
-		if tt.wildcard && (testing.Short() || !*testExternal) {
-			continue
-		}
-		tt.net1 = toudpnet(tt.net1)
-		tt.net2 = toudpnet(tt.net2)
-		switch runtime.GOOS {
-		case "openbsd":
-			if tt.wildcard && differentWildcardAddr(tt.laddr1, tt.laddr2) {
-				tt.xerr = nil
-			}
-		}
-		l1, port := usableListenPacketPort(t, tt.net1, tt.laddr1)
-		laddr := tt.laddr1 + ":" + port
-		checkFirstListener(t, tt.net1, laddr, l1)
-		laddr = tt.laddr2 + ":" + port
-		l2, err := ListenPacket(tt.net2, laddr)
-		checkDualStackSecondListener(t, tt.net2, laddr, tt.xerr, err, l2)
-		l1.Close()
-	}
-}
-
-func usableListenPort(t *testing.T, net, laddr string) (l Listener, port string) {
-	var nladdr string
-	var err error
-	switch net {
-	default:
-		panic("usableListenPort net=" + net)
-	case "tcp", "tcp4", "tcp6":
-		l, err = Listen(net, laddr+":0")
-		if err != nil {
-			t.Fatalf("Probe Listen(%q, %q) failed: %v", net, laddr, err)
-		}
-		nladdr = l.(*TCPListener).Addr().String()
-	}
-	_, port, err = SplitHostPort(nladdr)
-	if err != nil {
-		t.Fatalf("SplitHostPort failed: %v", err)
-	}
-	return l, port
-}
-
-func usableListenPacketPort(t *testing.T, net, laddr string) (l PacketConn, port string) {
-	var nladdr string
-	var err error
-	switch net {
-	default:
-		panic("usableListenPacketPort net=" + net)
-	case "udp", "udp4", "udp6":
-		l, err = ListenPacket(net, laddr+":0")
-		if err != nil {
-			t.Fatalf("Probe ListenPacket(%q, %q) failed: %v", net, laddr, err)
-		}
-		nladdr = l.(*UDPConn).LocalAddr().String()
-	}
-	_, port, err = SplitHostPort(nladdr)
-	if err != nil {
-		t.Fatalf("SplitHostPort failed: %v", err)
-	}
-	return l, port
-}
-
-func differentWildcardAddr(i, j string) bool {
-	if (i == "" || i == "0.0.0.0" || i == "::ffff:0.0.0.0") && (j == "" || j == "0.0.0.0" || j == "::ffff:0.0.0.0") {
-		return false
-	}
-	if i == "[::]" && j == "[::]" {
-		return false
-	}
-	return true
-}
-
-func checkFirstListener(t *testing.T, net, laddr string, l interface{}) {
-	switch net {
-	case "tcp":
-		fd := l.(*TCPListener).fd
-		checkDualStackAddrFamily(t, net, laddr, fd)
-	case "tcp4":
-		fd := l.(*TCPListener).fd
-		if fd.family != syscall.AF_INET {
-			t.Fatalf("First Listen(%q, %q) returns address family %v, expected %v", net, laddr, fd.family, syscall.AF_INET)
-		}
-	case "tcp6":
-		fd := l.(*TCPListener).fd
-		if fd.family != syscall.AF_INET6 {
-			t.Fatalf("First Listen(%q, %q) returns address family %v, expected %v", net, laddr, fd.family, syscall.AF_INET6)
-		}
-	case "udp":
-		fd := l.(*UDPConn).fd
-		checkDualStackAddrFamily(t, net, laddr, fd)
-	case "udp4":
-		fd := l.(*UDPConn).fd
-		if fd.family != syscall.AF_INET {
-			t.Fatalf("First ListenPacket(%q, %q) returns address family %v, expected %v", net, laddr, fd.family, syscall.AF_INET)
-		}
-	case "udp6":
-		fd := l.(*UDPConn).fd
-		if fd.family != syscall.AF_INET6 {
-			t.Fatalf("First ListenPacket(%q, %q) returns address family %v, expected %v", net, laddr, fd.family, syscall.AF_INET6)
-		}
-	default:
-		t.Fatalf("Unexpected network: %q", net)
-	}
-}
-
-func checkSecondListener(t *testing.T, net, laddr string, err error, l interface{}) {
-	switch net {
-	case "tcp", "tcp4", "tcp6":
-		if err == nil {
-			l.(*TCPListener).Close()
-			t.Fatalf("Second Listen(%q, %q) should fail", net, laddr)
-		}
-	case "udp", "udp4", "udp6":
-		if err == nil {
-			l.(*UDPConn).Close()
-			t.Fatalf("Second ListenPacket(%q, %q) should fail", net, laddr)
-		}
-	default:
-		t.Fatalf("Unexpected network: %q", net)
-	}
-}
-
-func checkDualStackSecondListener(t *testing.T, net, laddr string, xerr, err error, l interface{}) {
-	switch net {
-	case "tcp", "tcp4", "tcp6":
-		if xerr == nil && err != nil || xerr != nil && err == nil {
-			t.Fatalf("Second Listen(%q, %q) returns %v, expected %v", net, laddr, err, xerr)
-		}
-		if err == nil {
-			l.(*TCPListener).Close()
-		}
-	case "udp", "udp4", "udp6":
-		if xerr == nil && err != nil || xerr != nil && err == nil {
-			t.Fatalf("Second ListenPacket(%q, %q) returns %v, expected %v", net, laddr, err, xerr)
-		}
-		if err == nil {
-			l.(*UDPConn).Close()
-		}
-	default:
-		t.Fatalf("Unexpected network: %q", net)
-	}
-}
-
-func checkDualStackAddrFamily(t *testing.T, net, laddr string, fd *netFD) {
-	switch a := fd.laddr.(type) {
-	case *TCPAddr:
-		// If a node under test supports both IPv6 capability
-		// and IPv6 IPv4-mapping capability, we can assume
-		// that the node listens on a wildcard address with an
-		// AF_INET6 socket.
-		if supportsIPv4map && fd.laddr.(*TCPAddr).isWildcard() {
-			if fd.family != syscall.AF_INET6 {
-				t.Fatalf("Listen(%q, %q) returns address family %v, expected %v", net, laddr, fd.family, syscall.AF_INET6)
-			}
-		} else {
-			if fd.family != a.family() {
-				t.Fatalf("Listen(%q, %q) returns address family %v, expected %v", net, laddr, fd.family, a.family())
-			}
-		}
-	case *UDPAddr:
-		// If a node under test supports both IPv6 capability
-		// and IPv6 IPv4-mapping capability, we can assume
-		// that the node listens on a wildcard address with an
-		// AF_INET6 socket.
-		if supportsIPv4map && fd.laddr.(*UDPAddr).isWildcard() {
-			if fd.family != syscall.AF_INET6 {
-				t.Fatalf("ListenPacket(%q, %q) returns address family %v, expected %v", net, laddr, fd.family, syscall.AF_INET6)
-			}
-		} else {
-			if fd.family != a.family() {
-				t.Fatalf("ListenPacket(%q, %q) returns address family %v, expected %v", net, laddr, fd.family, a.family())
-			}
-		}
-	default:
-		t.Fatalf("Unexpected protocol address type: %T", a)
-	}
-}
-
-var prohibitionaryDialArgTests = []struct {
-	net  string
-	addr string
-}{
-	{"tcp6", "127.0.0.1"},
-	{"tcp6", "[::ffff:127.0.0.1]"},
-}
-
-func TestProhibitionaryDialArgs(t *testing.T) {
-	switch runtime.GOOS {
-	case "plan9":
-		t.Skipf("skipping test on %q", runtime.GOOS)
-	}
-	// This test requires both IPv6 and IPv6 IPv4-mapping functionality.
-	if !supportsIPv4map || testing.Short() || !*testExternal {
-		return
-	}
-
-	l, port := usableListenPort(t, "tcp", "[::]")
-	defer l.Close()
-
-	for _, tt := range prohibitionaryDialArgTests {
-		c, err := Dial(tt.net, tt.addr+":"+port)
-		if err == nil {
-			c.Close()
-			t.Fatalf("Dial(%q, %q) should fail", tt.net, tt.addr)
-		}
-	}
-}
-
-func TestWildWildcardListener(t *testing.T) {
-	switch runtime.GOOS {
-	case "plan9":
-		t.Skipf("skipping test on %q", runtime.GOOS)
-	}
-
-	if testing.Short() || !*testExternal {
-		t.Skip("skipping test to avoid external network")
-	}
-
-	defer func() {
-		if p := recover(); p != nil {
-			t.Fatalf("Listen, ListenPacket or protocol-specific Listen panicked: %v", p)
-		}
-	}()
-
-	if ln, err := Listen("tcp", ""); err == nil {
-		ln.Close()
-	}
-	if ln, err := ListenPacket("udp", ""); err == nil {
-		ln.Close()
-	}
-	if ln, err := ListenTCP("tcp", nil); err == nil {
-		ln.Close()
-	}
-	if ln, err := ListenUDP("udp", nil); err == nil {
-		ln.Close()
-	}
-	if ln, err := ListenIP("ip:icmp", nil); err == nil {
-		ln.Close()
-	}
-}
diff --git a/third_party/gofrontend/libgo/go/net/unix_test.go b/third_party/gofrontend/libgo/go/net/unix_test.go
index 1cdff39..358ff31 100644
--- a/third_party/gofrontend/libgo/go/net/unix_test.go
+++ b/third_party/gofrontend/libgo/go/net/unix_test.go
@@ -17,14 +17,18 @@
 )
 
 func TestReadUnixgramWithUnnamedSocket(t *testing.T) {
+	if !testableNetwork("unixgram") {
+		t.Skip("unixgram test")
+	}
+
 	addr := testUnixAddr()
 	la, err := ResolveUnixAddr("unixgram", addr)
 	if err != nil {
-		t.Fatalf("ResolveUnixAddr failed: %v", err)
+		t.Fatal(err)
 	}
 	c, err := ListenUnixgram("unixgram", la)
 	if err != nil {
-		t.Fatalf("ListenUnixgram failed: %v", err)
+		t.Fatal(err)
 	}
 	defer func() {
 		c.Close()
@@ -37,13 +41,13 @@
 		defer func() { off <- true }()
 		s, err := syscall.Socket(syscall.AF_UNIX, syscall.SOCK_DGRAM, 0)
 		if err != nil {
-			t.Errorf("syscall.Socket failed: %v", err)
+			t.Error(err)
 			return
 		}
 		defer syscall.Close(s)
 		rsa := &syscall.SockaddrUnix{Name: addr}
 		if err := syscall.Sendto(s, data[:], 0, rsa); err != nil {
-			t.Errorf("syscall.Sendto failed: %v", err)
+			t.Error(err)
 			return
 		}
 	}()
@@ -53,69 +57,123 @@
 	c.SetReadDeadline(time.Now().Add(100 * time.Millisecond))
 	n, from, err := c.ReadFrom(b)
 	if err != nil {
-		t.Fatalf("UnixConn.ReadFrom failed: %v", err)
+		t.Fatal(err)
 	}
 	if from != nil {
-		t.Fatalf("neighbor address is %v", from)
+		t.Fatalf("unexpected peer address: %v", from)
 	}
 	if !bytes.Equal(b[:n], data[:]) {
-		t.Fatalf("got %v, want %v", b[:n], data[:])
+		t.Fatalf("got %v; want %v", b[:n], data[:])
 	}
 }
 
-func TestReadUnixgramWithZeroBytesBuffer(t *testing.T) {
+func TestUnixgramZeroBytePayload(t *testing.T) {
+	if !testableNetwork("unixgram") {
+		t.Skip("unixgram test")
+	}
+
+	c1, err := newLocalPacketListener("unixgram")
+	if err != nil {
+		t.Fatal(err)
+	}
+	defer os.Remove(c1.LocalAddr().String())
+	defer c1.Close()
+
+	c2, err := Dial("unixgram", c1.LocalAddr().String())
+	if err != nil {
+		t.Fatal(err)
+	}
+	defer os.Remove(c2.LocalAddr().String())
+	defer c2.Close()
+
+	for _, genericRead := range []bool{false, true} {
+		n, err := c2.Write(nil)
+		if err != nil {
+			t.Fatal(err)
+		}
+		if n != 0 {
+			t.Errorf("got %d; want 0", n)
+		}
+		c1.SetReadDeadline(time.Now().Add(100 * time.Millisecond))
+		var b [1]byte
+		var peer Addr
+		if genericRead {
+			_, err = c1.(Conn).Read(b[:])
+		} else {
+			_, peer, err = c1.ReadFrom(b[:])
+		}
+		switch err {
+		case nil: // ReadFrom succeeds
+			if peer != nil { // peer is connected-mode
+				t.Fatalf("unexpected peer address: %v", peer)
+			}
+		default: // Read may timeout, it depends on the platform
+			if nerr, ok := err.(Error); !ok || !nerr.Timeout() {
+				t.Fatal(err)
+			}
+		}
+	}
+}
+
+func TestUnixgramZeroByteBuffer(t *testing.T) {
+	if !testableNetwork("unixgram") {
+		t.Skip("unixgram test")
+	}
 	// issue 4352: Recvfrom failed with "address family not
 	// supported by protocol family" if zero-length buffer provided
 
-	addr := testUnixAddr()
-	la, err := ResolveUnixAddr("unixgram", addr)
+	c1, err := newLocalPacketListener("unixgram")
 	if err != nil {
-		t.Fatalf("ResolveUnixAddr failed: %v", err)
+		t.Fatal(err)
 	}
-	c, err := ListenUnixgram("unixgram", la)
-	if err != nil {
-		t.Fatalf("ListenUnixgram failed: %v", err)
-	}
-	defer func() {
-		c.Close()
-		os.Remove(addr)
-	}()
+	defer os.Remove(c1.LocalAddr().String())
+	defer c1.Close()
 
-	off := make(chan bool)
-	go func() {
-		defer func() { off <- true }()
-		c, err := DialUnix("unixgram", nil, la)
+	c2, err := Dial("unixgram", c1.LocalAddr().String())
+	if err != nil {
+		t.Fatal(err)
+	}
+	defer os.Remove(c2.LocalAddr().String())
+	defer c2.Close()
+
+	b := []byte("UNIXGRAM ZERO BYTE BUFFER TEST")
+	for _, genericRead := range []bool{false, true} {
+		n, err := c2.Write(b)
 		if err != nil {
-			t.Errorf("DialUnix failed: %v", err)
-			return
+			t.Fatal(err)
 		}
-		defer c.Close()
-		if _, err := c.Write([]byte{1, 2, 3, 4, 5}); err != nil {
-			t.Errorf("UnixConn.Write failed: %v", err)
-			return
+		if n != len(b) {
+			t.Errorf("got %d; want %d", n, len(b))
 		}
-	}()
-
-	<-off
-	c.SetReadDeadline(time.Now().Add(100 * time.Millisecond))
-	_, from, err := c.ReadFrom(nil)
-	if err != nil {
-		t.Fatalf("UnixConn.ReadFrom failed: %v", err)
-	}
-	if from != nil {
-		t.Fatalf("neighbor address is %v", from)
+		c1.SetReadDeadline(time.Now().Add(100 * time.Millisecond))
+		var peer Addr
+		if genericRead {
+			_, err = c1.(Conn).Read(nil)
+		} else {
+			_, peer, err = c1.ReadFrom(nil)
+		}
+		switch err {
+		case nil: // ReadFrom succeeds
+			if peer != nil { // peer is connected-mode
+				t.Fatalf("unexpected peer address: %v", peer)
+			}
+		default: // Read may timeout, it depends on the platform
+			if nerr, ok := err.(Error); !ok || !nerr.Timeout() {
+				t.Fatal(err)
+			}
+		}
 	}
 }
 
 func TestUnixgramAutobind(t *testing.T) {
 	if runtime.GOOS != "linux" {
-		t.Skip("skipping: autobind is linux only")
+		t.Skip("autobind is linux only")
 	}
 
 	laddr := &UnixAddr{Name: "", Net: "unixgram"}
 	c1, err := ListenUnixgram("unixgram", laddr)
 	if err != nil {
-		t.Fatalf("ListenUnixgram failed: %v", err)
+		t.Fatal(err)
 	}
 	defer c1.Close()
 
@@ -130,7 +188,7 @@
 
 	c2, err := DialUnix("unixgram", nil, autoAddr)
 	if err != nil {
-		t.Fatalf("DialUnix failed: %v", err)
+		t.Fatal(err)
 	}
 	defer c2.Close()
 
@@ -141,25 +199,30 @@
 
 func TestUnixAutobindClose(t *testing.T) {
 	if runtime.GOOS != "linux" {
-		t.Skip("skipping: autobind is linux only")
+		t.Skip("autobind is linux only")
 	}
+
 	laddr := &UnixAddr{Name: "", Net: "unix"}
 	ln, err := ListenUnix("unix", laddr)
 	if err != nil {
-		t.Fatalf("ListenUnix failed: %v", err)
+		t.Fatal(err)
 	}
 	ln.Close()
 }
 
 func TestUnixgramWrite(t *testing.T) {
+	if !testableNetwork("unixgram") {
+		t.Skip("unixgram test")
+	}
+
 	addr := testUnixAddr()
 	laddr, err := ResolveUnixAddr("unixgram", addr)
 	if err != nil {
-		t.Fatalf("ResolveUnixAddr failed: %v", err)
+		t.Fatal(err)
 	}
 	c, err := ListenPacket("unixgram", addr)
 	if err != nil {
-		t.Fatalf("ListenPacket failed: %v", err)
+		t.Fatal(err)
 	}
 	defer os.Remove(addr)
 	defer c.Close()
@@ -171,27 +234,28 @@
 func testUnixgramWriteConn(t *testing.T, raddr *UnixAddr) {
 	c, err := Dial("unixgram", raddr.String())
 	if err != nil {
-		t.Fatalf("Dial failed: %v", err)
+		t.Fatal(err)
 	}
 	defer c.Close()
 
-	if _, err := c.(*UnixConn).WriteToUnix([]byte("Connection-oriented mode socket"), raddr); err == nil {
-		t.Fatal("WriteToUnix should fail")
+	b := []byte("CONNECTED-MODE SOCKET")
+	if _, err := c.(*UnixConn).WriteToUnix(b, raddr); err == nil {
+		t.Fatal("should fail")
 	} else if err.(*OpError).Err != ErrWriteToConnected {
-		t.Fatalf("WriteToUnix should fail as ErrWriteToConnected: %v", err)
+		t.Fatalf("should fail as ErrWriteToConnected: %v", err)
 	}
-	if _, err = c.(*UnixConn).WriteTo([]byte("Connection-oriented mode socket"), raddr); err == nil {
-		t.Fatal("WriteTo should fail")
+	if _, err = c.(*UnixConn).WriteTo(b, raddr); err == nil {
+		t.Fatal("should fail")
 	} else if err.(*OpError).Err != ErrWriteToConnected {
-		t.Fatalf("WriteTo should fail as ErrWriteToConnected: %v", err)
+		t.Fatalf("should fail as ErrWriteToConnected: %v", err)
 	}
-	if _, _, err = c.(*UnixConn).WriteMsgUnix([]byte("Connection-oriented mode socket"), nil, raddr); err == nil {
-		t.Fatal("WriteTo should fail")
+	if _, _, err = c.(*UnixConn).WriteMsgUnix(b, nil, raddr); err == nil {
+		t.Fatal("should fail")
 	} else if err.(*OpError).Err != ErrWriteToConnected {
-		t.Fatalf("WriteMsgUnix should fail as ErrWriteToConnected: %v", err)
+		t.Fatalf("should fail as ErrWriteToConnected: %v", err)
 	}
-	if _, err := c.Write([]byte("Connection-oriented mode socket")); err != nil {
-		t.Fatalf("Write failed: %v", err)
+	if _, err := c.Write(b); err != nil {
+		t.Fatal(err)
 	}
 }
 
@@ -199,52 +263,59 @@
 	addr := testUnixAddr()
 	c, err := ListenPacket("unixgram", addr)
 	if err != nil {
-		t.Fatalf("ListenPacket failed: %v", err)
+		t.Fatal(err)
 	}
 	defer os.Remove(addr)
 	defer c.Close()
 
-	if _, err := c.(*UnixConn).WriteToUnix([]byte("Connectionless mode socket"), raddr); err != nil {
-		t.Fatalf("WriteToUnix failed: %v", err)
+	b := []byte("UNCONNECTED-MODE SOCKET")
+	if _, err := c.(*UnixConn).WriteToUnix(b, raddr); err != nil {
+		t.Fatal(err)
 	}
-	if _, err := c.WriteTo([]byte("Connectionless mode socket"), raddr); err != nil {
-		t.Fatalf("WriteTo failed: %v", err)
+	if _, err := c.WriteTo(b, raddr); err != nil {
+		t.Fatal(err)
 	}
-	if _, _, err := c.(*UnixConn).WriteMsgUnix([]byte("Connectionless mode socket"), nil, raddr); err != nil {
-		t.Fatalf("WriteMsgUnix failed: %v", err)
+	if _, _, err := c.(*UnixConn).WriteMsgUnix(b, nil, raddr); err != nil {
+		t.Fatal(err)
 	}
-	if _, err := c.(*UnixConn).Write([]byte("Connectionless mode socket")); err == nil {
-		t.Fatal("Write should fail")
+	if _, err := c.(*UnixConn).Write(b); err == nil {
+		t.Fatal("should fail")
 	}
 }
 
 func TestUnixConnLocalAndRemoteNames(t *testing.T) {
+	if !testableNetwork("unix") {
+		t.Skip("unix test")
+	}
+
+	handler := func(ls *localServer, ln Listener) {}
 	for _, laddr := range []string{"", testUnixAddr()} {
 		laddr := laddr
 		taddr := testUnixAddr()
 		ta, err := ResolveUnixAddr("unix", taddr)
 		if err != nil {
-			t.Fatalf("ResolveUnixAddr failed: %v", err)
+			t.Fatal(err)
 		}
 		ln, err := ListenUnix("unix", ta)
 		if err != nil {
-			t.Fatalf("ListenUnix failed: %v", err)
+			t.Fatal(err)
 		}
-		defer func() {
-			ln.Close()
-			os.Remove(taddr)
-		}()
-
-		done := make(chan int)
-		go transponder(t, ln, done)
+		ls, err := (&streamListener{Listener: ln}).newLocalServer()
+		if err != nil {
+			t.Fatal(err)
+		}
+		defer ls.teardown()
+		if err := ls.buildup(handler); err != nil {
+			t.Fatal(err)
+		}
 
 		la, err := ResolveUnixAddr("unix", laddr)
 		if err != nil {
-			t.Fatalf("ResolveUnixAddr failed: %v", err)
+			t.Fatal(err)
 		}
 		c, err := DialUnix("unix", la, ta)
 		if err != nil {
-			t.Fatalf("DialUnix failed: %v", err)
+			t.Fatal(err)
 		}
 		defer func() {
 			c.Close()
@@ -253,7 +324,7 @@
 			}
 		}()
 		if _, err := c.Write([]byte("UNIXCONN LOCAL AND REMOTE NAME TEST")); err != nil {
-			t.Fatalf("UnixConn.Write failed: %v", err)
+			t.Fatal(err)
 		}
 
 		switch runtime.GOOS {
@@ -272,22 +343,24 @@
 				t.Fatalf("got %#v, expected %#v", ca.got, ca.want)
 			}
 		}
-
-		<-done
 	}
 }
 
 func TestUnixgramConnLocalAndRemoteNames(t *testing.T) {
+	if !testableNetwork("unixgram") {
+		t.Skip("unixgram test")
+	}
+
 	for _, laddr := range []string{"", testUnixAddr()} {
 		laddr := laddr
 		taddr := testUnixAddr()
 		ta, err := ResolveUnixAddr("unixgram", taddr)
 		if err != nil {
-			t.Fatalf("ResolveUnixAddr failed: %v", err)
+			t.Fatal(err)
 		}
 		c1, err := ListenUnixgram("unixgram", ta)
 		if err != nil {
-			t.Fatalf("ListenUnixgram failed: %v", err)
+			t.Fatal(err)
 		}
 		defer func() {
 			c1.Close()
@@ -297,12 +370,12 @@
 		var la *UnixAddr
 		if laddr != "" {
 			if la, err = ResolveUnixAddr("unixgram", laddr); err != nil {
-				t.Fatalf("ResolveUnixAddr failed: %v", err)
+				t.Fatal(err)
 			}
 		}
 		c2, err := DialUnix("unixgram", la, ta)
 		if err != nil {
-			t.Fatalf("DialUnix failed: %v", err)
+			t.Fatal(err)
 		}
 		defer func() {
 			c2.Close()
@@ -326,8 +399,33 @@
 		}
 		for _, ca := range connAddrs {
 			if !reflect.DeepEqual(ca.got, ca.want) {
-				t.Fatalf("got %#v, expected %#v", ca.got, ca.want)
+				t.Fatalf("got %#v; want %#v", ca.got, ca.want)
 			}
 		}
 	}
 }
+
+// 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/third_party/gofrontend/libgo/go/net/unixsock.go b/third_party/gofrontend/libgo/go/net/unixsock.go
index 8595584..eb91d0d 100644
--- a/third_party/gofrontend/libgo/go/net/unixsock.go
+++ b/third_party/gofrontend/libgo/go/net/unixsock.go
@@ -23,7 +23,11 @@
 	return a.Name
 }
 
-func (a *UnixAddr) toAddr() Addr {
+func (a *UnixAddr) isWildcard() bool {
+	return a == nil || a.Name == ""
+}
+
+func (a *UnixAddr) opAddr() Addr {
 	if a == nil {
 		return nil
 	}
diff --git a/third_party/gofrontend/libgo/go/net/unixsock_plan9.go b/third_party/gofrontend/libgo/go/net/unixsock_plan9.go
index c60c1d8..84b6b60 100644
--- a/third_party/gofrontend/libgo/go/net/unixsock_plan9.go
+++ b/third_party/gofrontend/libgo/go/net/unixsock_plan9.go
@@ -24,12 +24,12 @@
 // Timeout() == true after a fixed time limit; see SetDeadline and
 // SetReadDeadline.
 func (c *UnixConn) ReadFromUnix(b []byte) (int, *UnixAddr, error) {
-	return 0, nil, syscall.EPLAN9
+	return 0, nil, &OpError{Op: "read", Net: c.fd.dir, Source: c.fd.laddr, Addr: c.fd.raddr, Err: syscall.EPLAN9}
 }
 
 // ReadFrom implements the PacketConn ReadFrom method.
 func (c *UnixConn) ReadFrom(b []byte) (int, Addr, error) {
-	return 0, nil, syscall.EPLAN9
+	return 0, nil, &OpError{Op: "read", Net: c.fd.dir, Source: c.fd.laddr, Addr: c.fd.raddr, Err: syscall.EPLAN9}
 }
 
 // ReadMsgUnix reads a packet from c, copying the payload into b and
@@ -37,7 +37,7 @@
 // bytes copied into b, the number of bytes copied into oob, the flags
 // that were set on the packet, and the source address of the packet.
 func (c *UnixConn) ReadMsgUnix(b, oob []byte) (n, oobn, flags int, addr *UnixAddr, err error) {
-	return 0, 0, 0, nil, syscall.EPLAN9
+	return 0, 0, 0, nil, &OpError{Op: "read", Net: c.fd.dir, Source: c.fd.laddr, Addr: c.fd.raddr, Err: syscall.EPLAN9}
 }
 
 // WriteToUnix writes a packet to addr via c, copying the payload from b.
@@ -47,31 +47,31 @@
 // SetWriteDeadline.  On packet-oriented connections, write timeouts
 // are rare.
 func (c *UnixConn) WriteToUnix(b []byte, addr *UnixAddr) (int, error) {
-	return 0, syscall.EPLAN9
+	return 0, &OpError{Op: "write", Net: c.fd.dir, Source: c.fd.laddr, Addr: addr.opAddr(), Err: syscall.EPLAN9}
 }
 
 // WriteTo implements the PacketConn WriteTo method.
 func (c *UnixConn) WriteTo(b []byte, addr Addr) (int, error) {
-	return 0, syscall.EPLAN9
+	return 0, &OpError{Op: "write", Net: c.fd.dir, Source: c.fd.laddr, Addr: addr, Err: syscall.EPLAN9}
 }
 
 // WriteMsgUnix writes a packet to addr via c, copying the payload
 // from b and the associated out-of-band data from oob.  It returns
 // the number of payload and out-of-band bytes written.
 func (c *UnixConn) WriteMsgUnix(b, oob []byte, addr *UnixAddr) (n, oobn int, err error) {
-	return 0, 0, syscall.EPLAN9
+	return 0, 0, &OpError{Op: "write", Net: c.fd.dir, Source: c.fd.laddr, Addr: addr.opAddr(), Err: syscall.EPLAN9}
 }
 
 // CloseRead shuts down the reading side of the Unix domain connection.
 // Most callers should just use Close.
 func (c *UnixConn) CloseRead() error {
-	return syscall.EPLAN9
+	return &OpError{Op: "close", Net: c.fd.dir, Source: c.fd.laddr, Addr: c.fd.raddr, Err: syscall.EPLAN9}
 }
 
 // CloseWrite shuts down the writing side of the Unix domain connection.
 // Most callers should just use Close.
 func (c *UnixConn) CloseWrite() error {
-	return syscall.EPLAN9
+	return &OpError{Op: "close", Net: c.fd.dir, Source: c.fd.laddr, Addr: c.fd.raddr, Err: syscall.EPLAN9}
 }
 
 // DialUnix connects to the remote address raddr on the network net,
@@ -82,45 +82,49 @@
 }
 
 func dialUnix(net string, laddr, raddr *UnixAddr, deadline time.Time) (*UnixConn, error) {
-	return nil, syscall.EPLAN9
+	return nil, &OpError{Op: "dial", Net: net, Source: laddr.opAddr(), Addr: raddr.opAddr(), Err: syscall.EPLAN9}
 }
 
 // UnixListener is a Unix domain socket listener.  Clients should
 // typically use variables of type Listener instead of assuming Unix
 // domain sockets.
-type UnixListener struct{}
+type UnixListener struct {
+	fd *netFD
+}
 
 // ListenUnix announces on the Unix domain socket laddr and returns a
 // Unix listener.  The network net must be "unix" or "unixpacket".
 func ListenUnix(net string, laddr *UnixAddr) (*UnixListener, error) {
-	return nil, syscall.EPLAN9
+	return nil, &OpError{Op: "listen", Net: net, Source: nil, Addr: laddr.opAddr(), Err: syscall.EPLAN9}
 }
 
 // AcceptUnix accepts the next incoming call and returns the new
 // connection.
 func (l *UnixListener) AcceptUnix() (*UnixConn, error) {
-	return nil, syscall.EPLAN9
+	return nil, &OpError{Op: "accept", Net: l.fd.dir, Source: nil, Addr: l.fd.laddr, Err: syscall.EPLAN9}
 }
 
 // Accept implements the Accept method in the Listener interface; it
 // waits for the next call and returns a generic Conn.
 func (l *UnixListener) Accept() (Conn, error) {
-	return nil, syscall.EPLAN9
+	return nil, &OpError{Op: "accept", Net: l.fd.dir, Source: nil, Addr: l.fd.laddr, Err: syscall.EPLAN9}
 }
 
 // Close stops listening on the Unix address.  Already accepted
 // connections are not closed.
 func (l *UnixListener) Close() error {
-	return syscall.EPLAN9
+	return &OpError{Op: "close", Net: l.fd.dir, Source: nil, Addr: l.fd.laddr, Err: syscall.EPLAN9}
 }
 
 // Addr returns the listener's network address.
+// The Addr returned is shared by all invocations of Addr, so
+// do not modify it.
 func (l *UnixListener) Addr() Addr { return nil }
 
 // SetDeadline sets the deadline associated with the listener.
 // A zero time value disables the deadline.
 func (l *UnixListener) SetDeadline(t time.Time) error {
-	return syscall.EPLAN9
+	return &OpError{Op: "set", Net: l.fd.dir, Source: nil, Addr: l.fd.laddr, Err: syscall.EPLAN9}
 }
 
 // File returns a copy of the underlying os.File, set to blocking
@@ -131,7 +135,7 @@
 // connection's.  Attempting to change properties of the original
 // using this duplicate may or may not have the desired effect.
 func (l *UnixListener) File() (*os.File, error) {
-	return nil, syscall.EPLAN9
+	return nil, &OpError{Op: "file", Net: l.fd.dir, Source: nil, Addr: l.fd.laddr, Err: syscall.EPLAN9}
 }
 
 // ListenUnixgram listens for incoming Unix datagram packets addressed
@@ -139,5 +143,5 @@
 // The returned connection's ReadFrom and WriteTo methods can be used
 // to receive and send packets with per-packet addressing.
 func ListenUnixgram(net string, laddr *UnixAddr) (*UnixConn, error) {
-	return nil, syscall.EPLAN9
+	return nil, &OpError{Op: "listen", Net: net, Source: nil, Addr: laddr.opAddr(), Err: syscall.EPLAN9}
 }
diff --git a/third_party/gofrontend/libgo/go/net/unixsock_posix.go b/third_party/gofrontend/libgo/go/net/unixsock_posix.go
index 3c2e78b..351d9b3 100644
--- a/third_party/gofrontend/libgo/go/net/unixsock_posix.go
+++ b/third_party/gofrontend/libgo/go/net/unixsock_posix.go
@@ -87,10 +87,6 @@
 	return syscall.AF_UNIX
 }
 
-func (a *UnixAddr) isWildcard() bool {
-	return a == nil || a.Name == ""
-}
-
 func (a *UnixAddr) sockaddr(family int) (syscall.Sockaddr, error) {
 	if a == nil {
 		return nil, nil
@@ -113,10 +109,11 @@
 // ReadFromUnix can be made to time out and return an error with
 // Timeout() == true after a fixed time limit; see SetDeadline and
 // SetReadDeadline.
-func (c *UnixConn) ReadFromUnix(b []byte) (n int, addr *UnixAddr, err error) {
+func (c *UnixConn) ReadFromUnix(b []byte) (int, *UnixAddr, error) {
 	if !c.ok() {
 		return 0, nil, syscall.EINVAL
 	}
+	var addr *UnixAddr
 	n, sa, err := c.fd.readFrom(b)
 	switch sa := sa.(type) {
 	case *syscall.SockaddrUnix:
@@ -124,7 +121,10 @@
 			addr = &UnixAddr{Name: sa.Name, Net: sotypeToNet(c.fd.sotype)}
 		}
 	}
-	return
+	if err != nil {
+		err = &OpError{Op: "read", Net: c.fd.net, Source: c.fd.laddr, Addr: c.fd.raddr, Err: err}
+	}
+	return n, addr, err
 }
 
 // ReadFrom implements the PacketConn ReadFrom method.
@@ -133,7 +133,10 @@
 		return 0, nil, syscall.EINVAL
 	}
 	n, addr, err := c.ReadFromUnix(b)
-	return n, addr.toAddr(), err
+	if addr == nil {
+		return n, nil, err
+	}
+	return n, addr, err
 }
 
 // ReadMsgUnix reads a packet from c, copying the payload into b and
@@ -151,6 +154,9 @@
 			addr = &UnixAddr{Name: sa.Name, Net: sotypeToNet(c.fd.sotype)}
 		}
 	}
+	if err != nil {
+		err = &OpError{Op: "read", Net: c.fd.net, Source: c.fd.laddr, Addr: c.fd.raddr, Err: err}
+	}
 	return
 }
 
@@ -160,21 +166,25 @@
 // Timeout() == true after a fixed time limit; see SetDeadline and
 // SetWriteDeadline.  On packet-oriented connections, write timeouts
 // are rare.
-func (c *UnixConn) WriteToUnix(b []byte, addr *UnixAddr) (n int, err error) {
+func (c *UnixConn) WriteToUnix(b []byte, addr *UnixAddr) (int, error) {
 	if !c.ok() {
 		return 0, syscall.EINVAL
 	}
 	if c.fd.isConnected {
-		return 0, &OpError{Op: "write", Net: c.fd.net, Addr: addr, Err: ErrWriteToConnected}
+		return 0, &OpError{Op: "write", Net: c.fd.net, Source: c.fd.laddr, Addr: addr.opAddr(), Err: ErrWriteToConnected}
 	}
 	if addr == nil {
-		return 0, &OpError{Op: "write", Net: c.fd.net, Addr: nil, Err: errMissingAddress}
+		return 0, &OpError{Op: "write", Net: c.fd.net, Source: c.fd.laddr, Addr: nil, Err: errMissingAddress}
 	}
 	if addr.Net != sotypeToNet(c.fd.sotype) {
-		return 0, syscall.EAFNOSUPPORT
+		return 0, &OpError{Op: "write", Net: c.fd.net, Source: c.fd.laddr, Addr: addr.opAddr(), Err: syscall.EAFNOSUPPORT}
 	}
 	sa := &syscall.SockaddrUnix{Name: addr.Name}
-	return c.fd.writeTo(b, sa)
+	n, err := c.fd.writeTo(b, sa)
+	if err != nil {
+		err = &OpError{Op: "write", Net: c.fd.net, Source: c.fd.laddr, Addr: addr.opAddr(), Err: err}
+	}
+	return n, err
 }
 
 // WriteTo implements the PacketConn WriteTo method.
@@ -184,7 +194,7 @@
 	}
 	a, ok := addr.(*UnixAddr)
 	if !ok {
-		return 0, &OpError{"write", c.fd.net, addr, syscall.EINVAL}
+		return 0, &OpError{Op: "write", Net: c.fd.net, Source: c.fd.laddr, Addr: addr, Err: syscall.EINVAL}
 	}
 	return c.WriteToUnix(b, a)
 }
@@ -197,16 +207,20 @@
 		return 0, 0, syscall.EINVAL
 	}
 	if c.fd.sotype == syscall.SOCK_DGRAM && c.fd.isConnected {
-		return 0, 0, &OpError{Op: "write", Net: c.fd.net, Addr: addr, Err: ErrWriteToConnected}
+		return 0, 0, &OpError{Op: "write", Net: c.fd.net, Source: c.fd.laddr, Addr: addr.opAddr(), Err: ErrWriteToConnected}
 	}
+	var sa syscall.Sockaddr
 	if addr != nil {
 		if addr.Net != sotypeToNet(c.fd.sotype) {
-			return 0, 0, syscall.EAFNOSUPPORT
+			return 0, 0, &OpError{Op: "write", Net: c.fd.net, Source: c.fd.laddr, Addr: addr.opAddr(), Err: syscall.EAFNOSUPPORT}
 		}
-		sa := &syscall.SockaddrUnix{Name: addr.Name}
-		return c.fd.writeMsg(b, oob, sa)
+		sa = &syscall.SockaddrUnix{Name: addr.Name}
 	}
-	return c.fd.writeMsg(b, oob, nil)
+	n, oobn, err = c.fd.writeMsg(b, oob, sa)
+	if err != nil {
+		err = &OpError{Op: "write", Net: c.fd.net, Source: c.fd.laddr, Addr: addr.opAddr(), Err: err}
+	}
+	return
 }
 
 // CloseRead shuts down the reading side of the Unix domain connection.
@@ -215,7 +229,11 @@
 	if !c.ok() {
 		return syscall.EINVAL
 	}
-	return c.fd.closeRead()
+	err := c.fd.closeRead()
+	if err != nil {
+		err = &OpError{Op: "close", Net: c.fd.net, Source: c.fd.laddr, Addr: c.fd.raddr, Err: err}
+	}
+	return err
 }
 
 // CloseWrite shuts down the writing side of the Unix domain connection.
@@ -224,7 +242,11 @@
 	if !c.ok() {
 		return syscall.EINVAL
 	}
-	return c.fd.closeWrite()
+	err := c.fd.closeWrite()
+	if err != nil {
+		err = &OpError{Op: "close", Net: c.fd.net, Source: c.fd.laddr, Addr: c.fd.raddr, Err: err}
+	}
+	return err
 }
 
 // DialUnix connects to the remote address raddr on the network net,
@@ -234,7 +256,7 @@
 	switch net {
 	case "unix", "unixgram", "unixpacket":
 	default:
-		return nil, &OpError{Op: "dial", Net: net, Addr: raddr, Err: UnknownNetworkError(net)}
+		return nil, &OpError{Op: "dial", Net: net, Source: laddr.opAddr(), Addr: raddr.opAddr(), Err: UnknownNetworkError(net)}
 	}
 	return dialUnix(net, laddr, raddr, noDeadline)
 }
@@ -242,7 +264,7 @@
 func dialUnix(net string, laddr, raddr *UnixAddr, deadline time.Time) (*UnixConn, error) {
 	fd, err := unixSocket(net, laddr, raddr, "dial", deadline)
 	if err != nil {
-		return nil, &OpError{Op: "dial", Net: net, Addr: raddr, Err: err}
+		return nil, &OpError{Op: "dial", Net: net, Source: laddr.opAddr(), Addr: raddr.opAddr(), Err: err}
 	}
 	return newUnixConn(fd), nil
 }
@@ -261,16 +283,16 @@
 	switch net {
 	case "unix", "unixpacket":
 	default:
-		return nil, &OpError{Op: "listen", Net: net, Addr: laddr, Err: UnknownNetworkError(net)}
+		return nil, &OpError{Op: "listen", Net: net, Source: nil, Addr: laddr.opAddr(), Err: UnknownNetworkError(net)}
 	}
 	if laddr == nil {
-		return nil, &OpError{Op: "listen", Net: net, Addr: nil, Err: errMissingAddress}
+		return nil, &OpError{Op: "listen", Net: net, Source: nil, Addr: laddr.opAddr(), Err: errMissingAddress}
 	}
 	fd, err := unixSocket(net, laddr, nil, "listen", noDeadline)
 	if err != nil {
-		return nil, &OpError{Op: "listen", Net: net, Addr: laddr, Err: err}
+		return nil, &OpError{Op: "listen", Net: net, Source: nil, Addr: laddr.opAddr(), Err: err}
 	}
-	return &UnixListener{fd, fd.laddr.String()}, nil
+	return &UnixListener{fd: fd, path: fd.laddr.String()}, nil
 }
 
 // AcceptUnix accepts the next incoming call and returns the new
@@ -281,10 +303,9 @@
 	}
 	fd, err := l.fd.accept()
 	if err != nil {
-		return nil, err
+		return nil, &OpError{Op: "accept", Net: l.fd.net, Source: nil, Addr: l.fd.laddr, Err: err}
 	}
-	c := newUnixConn(fd)
-	return c, nil
+	return newUnixConn(fd), nil
 }
 
 // Accept implements the Accept method in the Listener interface; it
@@ -317,19 +338,28 @@
 	if l.path[0] != '@' {
 		syscall.Unlink(l.path)
 	}
-	return l.fd.Close()
+	err := l.fd.Close()
+	if err != nil {
+		err = &OpError{Op: "close", Net: l.fd.net, Source: l.fd.laddr, Addr: l.fd.raddr, Err: err}
+	}
+	return err
 }
 
 // Addr returns the listener's network address.
+// The Addr returned is shared by all invocations of Addr, so
+// do not modify it.
 func (l *UnixListener) Addr() Addr { return l.fd.laddr }
 
 // SetDeadline sets the deadline associated with the listener.
 // A zero time value disables the deadline.
-func (l *UnixListener) SetDeadline(t time.Time) (err error) {
+func (l *UnixListener) SetDeadline(t time.Time) error {
 	if l == nil || l.fd == nil {
 		return syscall.EINVAL
 	}
-	return l.fd.setDeadline(t)
+	if err := l.fd.setDeadline(t); err != nil {
+		return &OpError{Op: "set", Net: l.fd.net, Source: nil, Addr: l.fd.laddr, Err: err}
+	}
+	return nil
 }
 
 // File returns a copy of the underlying os.File, set to blocking
@@ -339,7 +369,13 @@
 // The returned os.File's file descriptor is different from the
 // connection's.  Attempting to change properties of the original
 // using this duplicate may or may not have the desired effect.
-func (l *UnixListener) File() (f *os.File, err error) { return l.fd.dup() }
+func (l *UnixListener) File() (f *os.File, err error) {
+	f, err = l.fd.dup()
+	if err != nil {
+		err = &OpError{Op: "file", Net: l.fd.net, Source: nil, Addr: l.fd.laddr, Err: err}
+	}
+	return
+}
 
 // ListenUnixgram listens for incoming Unix datagram packets addressed
 // to the local address laddr.  The network net must be "unixgram".
@@ -349,14 +385,14 @@
 	switch net {
 	case "unixgram":
 	default:
-		return nil, &OpError{Op: "listen", Net: net, Addr: laddr, Err: UnknownNetworkError(net)}
+		return nil, &OpError{Op: "listen", Net: net, Source: nil, Addr: laddr.opAddr(), Err: UnknownNetworkError(net)}
 	}
 	if laddr == nil {
-		return nil, &OpError{Op: "listen", Net: net, Addr: nil, Err: errMissingAddress}
+		return nil, &OpError{Op: "listen", Net: net, Source: nil, Addr: nil, Err: errMissingAddress}
 	}
 	fd, err := unixSocket(net, laddr, nil, "listen", noDeadline)
 	if err != nil {
-		return nil, &OpError{Op: "listen", Net: net, Addr: laddr, Err: err}
+		return nil, &OpError{Op: "listen", Net: net, Source: nil, Addr: laddr.opAddr(), Err: err}
 	}
 	return newUnixConn(fd), nil
 }
diff --git a/third_party/gofrontend/libgo/go/net/url/url.go b/third_party/gofrontend/libgo/go/net/url/url.go
index f167408..8ffad66 100644
--- a/third_party/gofrontend/libgo/go/net/url/url.go
+++ b/third_party/gofrontend/libgo/go/net/url/url.go
@@ -9,6 +9,7 @@
 import (
 	"bytes"
 	"errors"
+	"fmt"
 	"sort"
 	"strconv"
 	"strings"
@@ -51,6 +52,7 @@
 
 const (
 	encodePath encoding = 1 + iota
+	encodeHost
 	encodeUserPassword
 	encodeQueryComponent
 	encodeFragment
@@ -64,12 +66,27 @@
 
 // Return true if the specified character should be escaped when
 // appearing in a URL string, according to RFC 3986.
+//
+// Please be informed that for now shouldEscape does not check all
+// reserved characters correctly. See golang.org/issue/5684.
 func shouldEscape(c byte, mode encoding) bool {
 	// §2.3 Unreserved characters (alphanum)
 	if 'A' <= c && c <= 'Z' || 'a' <= c && c <= 'z' || '0' <= c && c <= '9' {
 		return false
 	}
 
+	if mode == encodeHost {
+		// §3.2.2 Host allows
+		//	sub-delims = "!" / "$" / "&" / "'" / "(" / ")" / "*" / "+" / "," / ";" / "="
+		// as part of reg-name.
+		// We add : because we include :port as part of host.
+		// We add [ ] because we include [ipv6]:port as part of host
+		switch c {
+		case '!', '$', '&', '\'', '(', ')', '*', '+', ',', ';', '=', ':', '[', ']':
+			return false
+		}
+	}
+
 	switch c {
 	case '-', '_', '.', '~': // §2.3 Unreserved characters (mark)
 		return false
@@ -127,7 +144,7 @@
 			if i+2 >= len(s) || !ishex(s[i+1]) || !ishex(s[i+2]) {
 				s = s[i:]
 				if len(s) > 3 {
-					s = s[0:3]
+					s = s[:3]
 				}
 				return "", EscapeError(s)
 			}
@@ -224,16 +241,24 @@
 // Note that the Path field is stored in decoded form: /%47%6f%2f becomes /Go/.
 // A consequence is that it is impossible to tell which slashes in the Path were
 // slashes in the raw URL and which were %2f. This distinction is rarely important,
-// but when it is a client must use other routines to parse the raw URL or construct
-// the parsed URL. For example, an HTTP server can consult req.RequestURI, and
-// an HTTP client can use URL{Host: "example.com", Opaque: "//example.com/Go%2f"}
-// instead of URL{Host: "example.com", Path: "/Go/"}.
+// but when it is, code must not use Path directly.
+//
+// Go 1.5 introduced the RawPath field to hold the encoded form of Path.
+// The Parse function sets both Path and RawPath in the URL it returns,
+// and URL's String method uses RawPath if it is a valid encoding of Path,
+// by calling the EncodedPath method.
+//
+// In earlier versions of Go, the more indirect workarounds were that an
+// HTTP server could consult req.RequestURI and an HTTP client could
+// construct a URL struct directly and set the Opaque field instead of Path.
+// These still work as well.
 type URL struct {
 	Scheme   string
 	Opaque   string    // encoded opaque data
 	User     *Userinfo // username and password information
 	Host     string    // host or host:port
 	Path     string
+	RawPath  string // encoded path hint (Go 1.5 and later only; see EscapedPath method)
 	RawQuery string // encoded query values, without '?'
 	Fragment string // fragment for references, without '#'
 }
@@ -305,7 +330,7 @@
 			if i == 0 {
 				return "", "", errors.New("missing protocol scheme")
 			}
-			return rawurl[0:i], rawurl[i+1:], nil
+			return rawurl[:i], rawurl[i+1:], nil
 		default:
 			// we have encountered an invalid character,
 			// so there is no valid scheme
@@ -324,9 +349,9 @@
 		return s, ""
 	}
 	if cutc {
-		return s[0:i], s[i+len(c):]
+		return s[:i], s[i+len(c):]
 	}
-	return s[0:i], s[i:]
+	return s[:i], s[i:]
 }
 
 // Parse parses rawurl into a URL structure.
@@ -401,14 +426,17 @@
 		if err != nil {
 			goto Error
 		}
-		if strings.Contains(url.Host, "%") {
-			err = errors.New("hexadecimal escape in host")
-			goto Error
-		}
 	}
 	if url.Path, err = unescape(rest, encodePath); err != nil {
 		goto Error
 	}
+	// RawPath is a hint as to the encoding of Path to use
+	// in url.EncodedPath. If that method already gets the
+	// right answer without RawPath, leave it empty.
+	// This will help make sure that people don't rely on it in general.
+	if url.EscapedPath() != rest && validEncodedPath(rest) {
+		url.RawPath = rest
+	}
 	return url, nil
 
 Error:
@@ -418,36 +446,157 @@
 func parseAuthority(authority string) (user *Userinfo, host string, err error) {
 	i := strings.LastIndex(authority, "@")
 	if i < 0 {
-		host = authority
-		return
+		host, err = parseHost(authority)
+	} else {
+		host, err = parseHost(authority[i+1:])
 	}
-	userinfo, host := authority[:i], authority[i+1:]
+	if err != nil {
+		return nil, "", err
+	}
+	if i < 0 {
+		return nil, host, nil
+	}
+	userinfo := authority[:i]
 	if strings.Index(userinfo, ":") < 0 {
 		if userinfo, err = unescape(userinfo, encodeUserPassword); err != nil {
-			return
+			return nil, "", err
 		}
 		user = User(userinfo)
 	} else {
 		username, password := split(userinfo, ":", true)
 		if username, err = unescape(username, encodeUserPassword); err != nil {
-			return
+			return nil, "", err
 		}
 		if password, err = unescape(password, encodeUserPassword); err != nil {
-			return
+			return nil, "", err
 		}
 		user = UserPassword(username, password)
 	}
-	return
+	return user, host, nil
+}
+
+// parseHost parses host as an authority without user
+// information. That is, as host[:port].
+func parseHost(host string) (string, error) {
+	litOrName := host
+	if strings.HasPrefix(host, "[") {
+		// Parse an IP-Literal in RFC 3986 and RFC 6874.
+		// E.g., "[fe80::1], "[fe80::1%25en0]"
+		//
+		// RFC 4007 defines "%" as a delimiter character in
+		// the textual representation of IPv6 addresses.
+		// Per RFC 6874, in URIs that "%" is encoded as "%25".
+		i := strings.LastIndex(host, "]")
+		if i < 0 {
+			return "", errors.New("missing ']' in host")
+		}
+		colonPort := host[i+1:]
+		if !validOptionalPort(colonPort) {
+			return "", fmt.Errorf("invalid port %q after host", colonPort)
+		}
+		// Parse a host subcomponent without a ZoneID in RFC
+		// 6874 because the ZoneID is allowed to use the
+		// percent encoded form.
+		j := strings.Index(host[:i], "%25")
+		if j < 0 {
+			litOrName = host[1:i]
+		} else {
+			litOrName = host[1:j]
+		}
+	}
+
+	// A URI containing an IP-Literal without a ZoneID or
+	// IPv4address in RFC 3986 and RFC 6847 must not be
+	// percent-encoded.
+	//
+	// A URI containing a DNS registered name in RFC 3986 is
+	// allowed to be percent-encoded, though we don't use it for
+	// now to avoid messing up with the gap between allowed
+	// characters in URI and allowed characters in DNS.
+	// See golang.org/issue/7991.
+	if strings.Contains(litOrName, "%") {
+		return "", errors.New("percent-encoded characters in host")
+	}
+	var err error
+	if host, err = unescape(host, encodeHost); err != nil {
+		return "", err
+	}
+	return host, nil
+}
+
+// EscapedPath returns the escaped form of u.Path.
+// In general there are multiple possible escaped forms of any path.
+// EscapedPath returns u.RawPath when it is a valid escaping of u.Path.
+// Otherwise EscapedPath ignores u.RawPath and computes an escaped
+// form on its own.
+// The String and RequestURI methods use EscapedPath to construct
+// their results.
+// In general, code should call EscapedPath instead of
+// reading u.RawPath directly.
+func (u *URL) EscapedPath() string {
+	if u.RawPath != "" && validEncodedPath(u.RawPath) {
+		p, err := unescape(u.RawPath, encodePath)
+		if err == nil && p == u.Path {
+			return u.RawPath
+		}
+	}
+	if u.Path == "*" {
+		return "*" // don't escape (Issue 11202)
+	}
+	return escape(u.Path, encodePath)
+}
+
+// validEncodedPath reports whether s is a valid encoded path.
+// It must not contain any bytes that require escaping during path encoding.
+func validEncodedPath(s string) bool {
+	for i := 0; i < len(s); i++ {
+		// RFC 3986, Appendix A.
+		// pchar = unreserved / pct-encoded / sub-delims / ":" / "@".
+		// shouldEscape is not quite compliant with the RFC,
+		// so we check the sub-delims ourselves and let
+		// shouldEscape handle the others.
+		switch s[i] {
+		case '!', '$', '&', '\'', '(', ')', '*', '+', ',', ';', '=', ':', '@':
+			// ok
+		case '[', ']':
+			// ok - not specified in RFC 3986 but left alone by modern browsers
+		case '%':
+			// ok - percent encoded, will decode
+		default:
+			if shouldEscape(s[i], encodePath) {
+				return false
+			}
+		}
+	}
+	return true
+}
+
+// validOptionalPort reports whether port is either an empty string
+// or matches /^:\d+$/
+func validOptionalPort(port string) bool {
+	if port == "" {
+		return true
+	}
+	if port[0] != ':' || len(port) == 1 {
+		return false
+	}
+	for _, b := range port[1:] {
+		if b < '0' || b > '9' {
+			return false
+		}
+	}
+	return true
 }
 
 // String reassembles the URL into a valid URL string.
 // The general form of the result is one of:
 //
-//	scheme:opaque
+//	scheme:opaque?query#fragment
 //	scheme://userinfo@host/path?query#fragment
 //
 // If u.Opaque is non-empty, String uses the first form;
 // otherwise it uses the second form.
+// To obtain the path, String uses u.EncodedPath().
 //
 // In the second form, the following rules apply:
 //	- if u.Scheme is empty, scheme: is omitted.
@@ -475,13 +624,14 @@
 				buf.WriteByte('@')
 			}
 			if h := u.Host; h != "" {
-				buf.WriteString(h)
+				buf.WriteString(escape(h, encodeHost))
 			}
 		}
-		if u.Path != "" && u.Path[0] != '/' && u.Host != "" {
+		path := u.EscapedPath()
+		if path != "" && path[0] != '/' && u.Host != "" {
 			buf.WriteByte('/')
 		}
-		buf.WriteString(escape(u.Path, encodePath))
+		buf.WriteString(path)
 	}
 	if u.RawQuery != "" {
 		buf.WriteByte('?')
@@ -639,7 +789,7 @@
 	return "/" + strings.TrimLeft(strings.Join(dst, "/"), "/")
 }
 
-// IsAbs returns true if the URL is absolute.
+// IsAbs reports whether the URL is absolute.
 func (u *URL) IsAbs() bool {
 	return u.Scheme != ""
 }
@@ -703,7 +853,7 @@
 func (u *URL) RequestURI() string {
 	result := u.Opaque
 	if result == "" {
-		result = escape(u.Path, encodePath)
+		result = u.EscapedPath()
 		if result == "" {
 			result = "/"
 		}
diff --git a/third_party/gofrontend/libgo/go/net/url/url_test.go b/third_party/gofrontend/libgo/go/net/url/url_test.go
index d8b19d8..ff6e9e4 100644
--- a/third_party/gofrontend/libgo/go/net/url/url_test.go
+++ b/third_party/gofrontend/libgo/go/net/url/url_test.go
@@ -13,7 +13,7 @@
 
 type URLTest struct {
 	in        string
-	out       *URL
+	out       *URL   // expected parse; RawPath="" means same as Path
 	roundtrip string // expected result of reserializing the URL; empty means same as "in".
 }
 
@@ -41,11 +41,12 @@
 	{
 		"http://www.google.com/file%20one%26two",
 		&URL{
-			Scheme: "http",
-			Host:   "www.google.com",
-			Path:   "/file one&two",
+			Scheme:  "http",
+			Host:    "www.google.com",
+			Path:    "/file one&two",
+			RawPath: "/file%20one%26two",
 		},
-		"http://www.google.com/file%20one&two",
+		"",
 	},
 	// user
 	{
@@ -289,6 +290,140 @@
 		},
 		"",
 	},
+	// host subcomponent; IPv4 address in RFC 3986
+	{
+		"http://192.168.0.1/",
+		&URL{
+			Scheme: "http",
+			Host:   "192.168.0.1",
+			Path:   "/",
+		},
+		"",
+	},
+	// host and port subcomponents; IPv4 address in RFC 3986
+	{
+		"http://192.168.0.1:8080/",
+		&URL{
+			Scheme: "http",
+			Host:   "192.168.0.1:8080",
+			Path:   "/",
+		},
+		"",
+	},
+	// host subcomponent; IPv6 address in RFC 3986
+	{
+		"http://[fe80::1]/",
+		&URL{
+			Scheme: "http",
+			Host:   "[fe80::1]",
+			Path:   "/",
+		},
+		"",
+	},
+	// host and port subcomponents; IPv6 address in RFC 3986
+	{
+		"http://[fe80::1]:8080/",
+		&URL{
+			Scheme: "http",
+			Host:   "[fe80::1]:8080",
+			Path:   "/",
+		},
+		"",
+	},
+	// host subcomponent; IPv6 address with zone identifier in RFC 6847
+	{
+		"http://[fe80::1%25en0]/", // alphanum zone identifier
+		&URL{
+			Scheme: "http",
+			Host:   "[fe80::1%en0]",
+			Path:   "/",
+		},
+		"",
+	},
+	// host and port subcomponents; IPv6 address with zone identifier in RFC 6847
+	{
+		"http://[fe80::1%25en0]:8080/", // alphanum zone identifier
+		&URL{
+			Scheme: "http",
+			Host:   "[fe80::1%en0]:8080",
+			Path:   "/",
+		},
+		"",
+	},
+	// host subcomponent; IPv6 address with zone identifier in RFC 6847
+	{
+		"http://[fe80::1%25%65%6e%301-._~]/", // percent-encoded+unreserved zone identifier
+		&URL{
+			Scheme: "http",
+			Host:   "[fe80::1%en01-._~]",
+			Path:   "/",
+		},
+		"http://[fe80::1%25en01-._~]/",
+	},
+	// host and port subcomponents; IPv6 address with zone identifier in RFC 6847
+	{
+		"http://[fe80::1%25%65%6e%301-._~]:8080/", // percent-encoded+unreserved zone identifier
+		&URL{
+			Scheme: "http",
+			Host:   "[fe80::1%en01-._~]:8080",
+			Path:   "/",
+		},
+		"http://[fe80::1%25en01-._~]:8080/",
+	},
+	// alternate escapings of path survive round trip
+	{
+		"http://rest.rsc.io/foo%2fbar/baz%2Fquux?alt=media",
+		&URL{
+			Scheme:   "http",
+			Host:     "rest.rsc.io",
+			Path:     "/foo/bar/baz/quux",
+			RawPath:  "/foo%2fbar/baz%2Fquux",
+			RawQuery: "alt=media",
+		},
+		"",
+	},
+	// issue 12036
+	{
+		"mysql://a,b,c/bar",
+		&URL{
+			Scheme: "mysql",
+			Host:   "a,b,c",
+			Path:   "/bar",
+		},
+		"",
+	},
+	// worst case host, still round trips
+	{
+		"scheme://!$&'()*+,;=hello!:port/path",
+		&URL{
+			Scheme: "scheme",
+			Host:   "!$&'()*+,;=hello!:port",
+			Path:   "/path",
+		},
+		"",
+	},
+	// worst case path, still round trips
+	{
+		"http://host/!$&'()*+,;=:@[hello]",
+		&URL{
+			Scheme:  "http",
+			Host:    "host",
+			Path:    "/!$&'()*+,;=:@[hello]",
+			RawPath: "/!$&'()*+,;=:@[hello]",
+		},
+		"",
+	},
+	// golang.org/issue/5684
+	{
+		"http://example.com/oid/[order_id]",
+		&URL{
+			Scheme:  "http",
+			Host:    "example.com",
+			Path:    "/oid/[order_id]",
+			RawPath: "/oid/[order_id]",
+		},
+		"",
+	},
 }
 
 // more useful string for debugging than fmt's struct printer
@@ -300,8 +435,8 @@
 			pass = p
 		}
 	}
-	return fmt.Sprintf("opaque=%q, scheme=%q, user=%#v, pass=%#v, host=%q, path=%q, rawq=%q, frag=%q",
-		u.Opaque, u.Scheme, user, pass, u.Host, u.Path, u.RawQuery, u.Fragment)
+	return fmt.Sprintf("opaque=%q, scheme=%q, user=%#v, pass=%#v, host=%q, path=%q, rawpath=%q, rawq=%q, frag=%q",
+		u.Opaque, u.Scheme, user, pass, u.Host, u.Path, u.RawPath, u.RawQuery, u.Fragment)
 }
 
 func DoTest(t *testing.T, parse func(string) (*URL, error), name string, tests []URLTest) {
@@ -358,9 +493,33 @@
 	{"/", true},
 	{pathThatLooksSchemeRelative, true},
 	{"//not.a.user@%66%6f%6f.com/just/a/path/also", true},
+	{"*", true},
+	{"http://192.168.0.1/", true},
+	{"http://192.168.0.1:8080/", true},
+	{"http://[fe80::1]/", true},
+	{"http://[fe80::1]:8080/", true},
+
+	// Tests exercising RFC 6874 compliance:
+	{"http://[fe80::1%25en0]/", true},                 // with alphanum zone identifier
+	{"http://[fe80::1%25en0]:8080/", true},            // with alphanum zone identifier
+	{"http://[fe80::1%25%65%6e%301-._~]/", true},      // with percent-encoded+unreserved zone identifier
+	{"http://[fe80::1%25%65%6e%301-._~]:8080/", true}, // with percent-encoded+unreserved zone identifier
+
 	{"foo.html", false},
 	{"../dir/", false},
-	{"*", true},
+	{"http://192.168.0.%31/", false},
+	{"http://192.168.0.%31:8080/", false},
+	{"http://[fe80::%31]/", false},
+	{"http://[fe80::%31]:8080/", false},
+	{"http://[fe80::%31%25en0]/", false},
+	{"http://[fe80::%31%25en0]:8080/", false},
+
+	// These two cases are valid as textual representations as
+	// described in RFC 4007, but are not valid as address
+	// literals with IPv6 zone identifiers in URIs as described in
+	// RFC 6874.
+	{"http://[fe80::1%en0]/", false},
+	{"http://[fe80::1%en0]:8080/", false},
 }
 
 func TestParseRequestURI(t *testing.T) {
@@ -869,6 +1028,25 @@
 		},
 		"http://other.example.com/%2F/%2F/",
 	},
+	// better fix for issue 4860
+	{
+		&URL{
+			Scheme:  "http",
+			Host:    "example.com",
+			Path:    "/////",
+			RawPath: "/%2F/%2F/",
+		},
+		"/%2F/%2F/",
+	},
+	{
+		&URL{
+			Scheme:  "http",
+			Host:    "example.com",
+			Path:    "/////",
+			RawPath: "/WRONG/", // ignored because doesn't match Path
+		},
+		"/////",
+	},
 	{
 		&URL{
 			Scheme:   "http",
@@ -880,6 +1058,26 @@
 	},
 	{
 		&URL{
+			Scheme:   "http",
+			Host:     "example.com",
+			Path:     "/a b",
+			RawPath:  "/a b", // ignored because invalid
+			RawQuery: "q=go+language",
+		},
+		"/a%20b?q=go+language",
+	},
+	{
+		&URL{
+			Scheme:   "http",
+			Host:     "example.com",
+			Path:     "/a?b",
+			RawPath:  "/a?b", // ignored because invalid
+			RawQuery: "q=go+language",
+		},
+		"/a%3Fb?q=go+language",
+	},
+	{
+		&URL{
 			Scheme: "myschema",
 			Opaque: "opaque",
 		},
@@ -914,6 +1112,54 @@
 	}
 }
 
+func TestParseAuthority(t *testing.T) {
+	tests := []struct {
+		in      string
+		wantErr bool
+	}{
+		{"http://[::1]", false},
+		{"http://[::1]:80", false},
+		{"http://[::1]:namedport", true}, // rfc3986 3.2.3
+		{"http://[::1]/", false},
+		{"http://[::1]a", true},
+		{"http://[::1]%23", true},
+		{"http://[::1%25en0]", false},     // valid zone id
+		{"http://[::1]:", true},           // colon, but no port
+		{"http://[::1]:%38%30", true},     // no hex in port
+		{"http://[::1%25%10]", false},     // TODO: reject the %10 after the valid zone %25 separator?
+		{"http://[%10::1]", true},         // no %xx escapes in IP address
+		{"http://[::1]/%48", false},       // %xx in path is fine
+		{"http://%41:8080/", true},        // TODO: arguably we should accept reg-name with %xx
+		{"mysql://x@y(z:123)/foo", false}, // golang.org/issue/12023
+		{"mysql://x@y(1.2.3.4:123)/foo", false},
+		{"mysql://x@y([2001:db8::1]:123)/foo", false},
+		{"http://[]%20%48%54%54%50%2f%31%2e%31%0a%4d%79%48%65%61%64%65%72%3a%20%31%32%33%0a%0a/", true}, // golang.org/issue/11208
+	}
+	for _, tt := range tests {
+		u, err := Parse(tt.in)
+		if tt.wantErr {
+			if err == nil {
+				t.Errorf("Parse(%q) = %#v; want an error", tt.in, u)
+			}
+			continue
+		}
+		if err != nil {
+			t.Logf("Parse(%q) = %v; want no error", tt.in, err)
+		}
+	}
+}
+
+// Issue 11202
+func TestStarRequest(t *testing.T) {
+	u, err := Parse("*")
+	if err != nil {
+		t.Fatal(err)
+	}
+	if got, want := u.RequestURI(), "*"; got != want {
+		t.Errorf("RequestURI = %q; want %q", got, want)
+	}
+}
+
 type shouldEscapeTest struct {
 	in     byte
 	mode   encoding
@@ -926,6 +1172,7 @@
 	{'a', encodeUserPassword, false},
 	{'a', encodeQueryComponent, false},
 	{'a', encodeFragment, false},
+	{'a', encodeHost, false},
 	{'z', encodePath, false},
 	{'A', encodePath, false},
 	{'Z', encodePath, false},
@@ -950,6 +1197,29 @@
 	{',', encodeUserPassword, false},
 	{';', encodeUserPassword, false},
 	{'=', encodeUserPassword, false},
+
+	// Host (IP address, IPv6 address, registered name, port suffix; §3.2.2)
+	{'!', encodeHost, false},
+	{'$', encodeHost, false},
+	{'&', encodeHost, false},
+	{'\'', encodeHost, false},
+	{'(', encodeHost, false},
+	{')', encodeHost, false},
+	{'*', encodeHost, false},
+	{'+', encodeHost, false},
+	{',', encodeHost, false},
+	{';', encodeHost, false},
+	{'=', encodeHost, false},
+	{':', encodeHost, false},
+	{'[', encodeHost, false},
+	{']', encodeHost, false},
+	{'0', encodeHost, false},
+	{'9', encodeHost, false},
+	{'A', encodeHost, false},
+	{'z', encodeHost, false},
+	{'_', encodeHost, false},
+	{'-', encodeHost, false},
+	{'.', encodeHost, false},
 }
 
 func TestShouldEscape(t *testing.T) {
diff --git a/third_party/gofrontend/libgo/go/net/z_last_test.go b/third_party/gofrontend/libgo/go/net/z_last_test.go
deleted file mode 100644
index 716c103..0000000
--- a/third_party/gofrontend/libgo/go/net/z_last_test.go
+++ /dev/null
@@ -1,99 +0,0 @@
-// Copyright 2009 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 net
-
-import (
-	"flag"
-	"fmt"
-	"testing"
-	"time"
-)
-
-var testDNSFlood = flag.Bool("dnsflood", false, "whether to test dns query flooding")
-
-func TestDNSThreadLimit(t *testing.T) {
-	if !*testDNSFlood {
-		t.Skip("test disabled; use -dnsflood to enable")
-	}
-
-	const N = 10000
-	c := make(chan int, N)
-	for i := 0; i < N; i++ {
-		go func(i int) {
-			LookupIP(fmt.Sprintf("%d.net-test.golang.org", i))
-			c <- 1
-		}(i)
-	}
-	// Don't bother waiting for the stragglers; stop at 0.9 N.
-	for i := 0; i < N*9/10; i++ {
-		if i%100 == 0 {
-			//println("TestDNSThreadLimit:", i)
-		}
-		<-c
-	}
-
-	// If we're still here, it worked.
-}
-
-func TestLookupIPDeadline(t *testing.T) {
-	if !*testDNSFlood {
-		t.Skip("test disabled; use -dnsflood to enable")
-	}
-
-	const N = 5000
-	const timeout = 3 * time.Second
-	c := make(chan error, 2*N)
-	for i := 0; i < N; i++ {
-		name := fmt.Sprintf("%d.net-test.golang.org", i)
-		go func() {
-			_, err := lookupIPDeadline(name, time.Now().Add(timeout/2))
-			c <- err
-		}()
-		go func() {
-			_, err := lookupIPDeadline(name, time.Now().Add(timeout))
-			c <- err
-		}()
-	}
-	qstats := struct {
-		succeeded, failed         int
-		timeout, temporary, other int
-		unknown                   int
-	}{}
-	deadline := time.After(timeout + time.Second)
-	for i := 0; i < 2*N; i++ {
-		select {
-		case <-deadline:
-			t.Fatal("deadline exceeded")
-		case err := <-c:
-			switch err := err.(type) {
-			case nil:
-				qstats.succeeded++
-			case Error:
-				qstats.failed++
-				if err.Timeout() {
-					qstats.timeout++
-				}
-				if err.Temporary() {
-					qstats.temporary++
-				}
-				if !err.Timeout() && !err.Temporary() {
-					qstats.other++
-				}
-			default:
-				qstats.failed++
-				qstats.unknown++
-			}
-		}
-	}
-
-	// A high volume of DNS queries for sub-domain of golang.org
-	// would be coordinated by authoritative or recursive server,
-	// or stub resolver which implements query-response rate
-	// limitation, so we can expect some query successes and more
-	// failures including timeout, temporary and other here.
-	// As a rule, unknown must not be shown but it might possibly
-	// 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)
-}
diff --git a/third_party/gofrontend/libgo/go/os/env.go b/third_party/gofrontend/libgo/go/os/env.go
index d0494a4..a4ede15 100644
--- a/third_party/gofrontend/libgo/go/os/env.go
+++ b/third_party/gofrontend/libgo/go/os/env.go
@@ -33,7 +33,7 @@
 	return Expand(s, Getenv)
 }
 
-// isSpellSpecialVar reports whether the character identifies a special
+// isShellSpecialVar reports whether the character identifies a special
 // shell variable such as $*.
 func isShellSpecialVar(c uint8) bool {
 	switch c {
@@ -48,7 +48,7 @@
 	return c == '_' || '0' <= c && c <= '9' || 'a' <= c && c <= 'z' || 'A' <= c && c <= 'Z'
 }
 
-// getName returns the name that begins the string and the number of bytes
+// getShellName returns the name that begins the string and the number of bytes
 // consumed to extract it.  If the name is enclosed in {}, it's part of a ${}
 // expansion and two more bytes are needed than the length of the name.
 func getShellName(s string) (string, int) {
@@ -81,6 +81,15 @@
 	return v
 }
 
+// LookupEnv retrieves the value of the environment variable named
+// by the key. If the variable is present in the environment the
+// value (which may be empty) is returned and the boolean is true.
+// Otherwise the returned value will be empty and the boolean will
+// be false.
+func LookupEnv(key string) (string, bool) {
+	return syscall.Getenv(key)
+}
+
 // Setenv sets the value of the environment variable named by the key.
 // It returns an error, if any.
 func Setenv(key, value string) error {
diff --git a/third_party/gofrontend/libgo/go/os/env_test.go b/third_party/gofrontend/libgo/go/os/env_test.go
index e618067..d1074cd 100644
--- a/third_party/gofrontend/libgo/go/os/env_test.go
+++ b/third_party/gofrontend/libgo/go/os/env_test.go
@@ -94,3 +94,20 @@
 		t.Fatal("Unsetenv didn't clear TestUnsetenv")
 	}
 }
+
+func TestLookupEnv(t *testing.T) {
+	const smallpox = "SMALLPOX"      // No one has smallpox.
+	value, ok := LookupEnv(smallpox) // Should not exist.
+	if ok || value != "" {
+		t.Fatalf("%s=%q", smallpox, value)
+	}
+	defer Unsetenv(smallpox)
+	err := Setenv(smallpox, "virus")
+	if err != nil {
+		t.Fatalf("failed to release smallpox virus")
+	}
+	value, ok = LookupEnv(smallpox)
+	if !ok {
+		t.Errorf("smallpox release failed; world remains safe but LookupEnv is broken")
+	}
+}
diff --git a/third_party/gofrontend/libgo/go/os/exec.go b/third_party/gofrontend/libgo/go/os/exec.go
index 5aea309..15e95b9 100644
--- a/third_party/gofrontend/libgo/go/os/exec.go
+++ b/third_party/gofrontend/libgo/go/os/exec.go
@@ -13,8 +13,8 @@
 // Process stores the information about a process created by StartProcess.
 type Process struct {
 	Pid    int
-	handle uintptr
-	isdone uint32 // process has been successfully waited on, non zero if true
+	handle uintptr // handle is accessed atomically on Windows
+	isdone uint32  // process has been successfully waited on, non zero if true
 }
 
 func newProcess(pid int, handle uintptr) *Process {
diff --git a/third_party/gofrontend/libgo/go/os/exec/exec.go b/third_party/gofrontend/libgo/go/os/exec/exec.go
index 72b4905..8a84e26 100644
--- a/third_party/gofrontend/libgo/go/os/exec/exec.go
+++ b/third_party/gofrontend/libgo/go/os/exec/exec.go
@@ -32,6 +32,9 @@
 }
 
 // Cmd represents an external command being prepared or run.
+//
+// A Cmd cannot be reused after calling its Run, Output or CombinedOutput
+// methods.
 type Cmd struct {
 	// Path is the path of the command to run.
 	//
@@ -80,8 +83,8 @@
 	// new process. It does not include standard input, standard output, or
 	// standard error. If non-nil, entry i becomes file descriptor 3+i.
 	//
-	// BUG: on OS X 10.6, child processes may sometimes inherit unwanted fds.
-	// http://golang.org/issue/2603
+	// BUG(rsc): On OS X 10.6, child processes may sometimes inherit unwanted fds.
+	// https://golang.org/issue/2603
 	ExtraFiles []*os.File
 
 	// SysProcAttr holds optional, operating system-specific attributes.
@@ -154,6 +157,11 @@
 	return []string{c.Path}
 }
 
+// skipStdinCopyError optionally specifies a function which reports
+// whether the provided the stdin copy error should be ignored.
+// It is non-nil everywhere but Plan 9, which lacks EPIPE. See exec_posix.go.
+var skipStdinCopyError func(error) bool
+
 func (c *Cmd) stdin() (f *os.File, err error) {
 	if c.Stdin == nil {
 		f, err = os.Open(os.DevNull)
@@ -177,6 +185,9 @@
 	c.closeAfterWait = append(c.closeAfterWait, pw)
 	c.goroutine = append(c.goroutine, func() error {
 		_, err := io.Copy(pw, c.Stdin)
+		if skip := skipStdinCopyError; skip != nil && skip(err) {
+			err = nil
+		}
 		if err1 := pw.Close(); err == nil {
 			err = err1
 		}
@@ -219,6 +230,7 @@
 	c.closeAfterWait = append(c.closeAfterWait, pr)
 	c.goroutine = append(c.goroutine, func() error {
 		_, err := io.Copy(w, pr)
+		pr.Close() // in case io.Copy stopped due to write error
 		return err
 	})
 	return pw, nil
@@ -352,6 +364,10 @@
 // error is of type *ExitError. Other error types may be
 // returned for I/O problems.
 //
+// If c.Stdin is not an *os.File, Wait also waits for the I/O loop
+// copying from c.Stdin into the process's standard input
+// to complete.
+//
 // Wait releases any resources associated with the Cmd.
 func (c *Cmd) Wait() error {
 	if c.Process == nil {
diff --git a/third_party/gofrontend/libgo/go/os/exec/exec_posix.go b/third_party/gofrontend/libgo/go/os/exec/exec_posix.go
new file mode 100644
index 0000000..5e11137
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/os/exec/exec_posix.go
@@ -0,0 +1,24 @@
+// 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 !plan9
+
+package exec
+
+import (
+	"os"
+	"syscall"
+)
+
+func init() {
+	skipStdinCopyError = func(err error) bool {
+		// Ignore EPIPE errors copying to stdin if the program
+		// completed successfully otherwise.
+		// See Issue 9173.
+		pe, ok := err.(*os.PathError)
+		return ok &&
+			pe.Op == "write" && pe.Path == "|1" &&
+			pe.Err == syscall.EPIPE
+	}
+}
diff --git a/third_party/gofrontend/libgo/go/os/exec/exec_test.go b/third_party/gofrontend/libgo/go/os/exec/exec_test.go
index f9ffde6..f4c025e 100644
--- a/third_party/gofrontend/libgo/go/os/exec/exec_test.go
+++ b/third_party/gofrontend/libgo/go/os/exec/exec_test.go
@@ -11,6 +11,7 @@
 	"bufio"
 	"bytes"
 	"fmt"
+	"internal/testenv"
 	"io"
 	"io/ioutil"
 	"log"
@@ -28,9 +29,8 @@
 )
 
 func helperCommand(t *testing.T, s ...string) *exec.Cmd {
-	if runtime.GOOS == "nacl" {
-		t.Skip("skipping on nacl")
-	}
+	testenv.MustHaveExec(t)
+
 	cs := []string{"-test.run=TestHelperProcess", "--"}
 	cs = append(cs, s...)
 	cmd := exec.Command(os.Args[0], cs...)
@@ -53,6 +53,8 @@
 }
 
 func TestCommandRelativeName(t *testing.T) {
+	testenv.MustHaveExec(t)
+
 	// Run our own binary as a relative path
 	// (e.g. "_test/exec.test") our parent directory.
 	base := filepath.Base(os.Args[0]) // "exec.test"
@@ -250,6 +252,12 @@
 }
 
 func numOpenFDS(t *testing.T) (n int, lsof []byte) {
+	if runtime.GOOS == "android" {
+		// Android's stock lsof does not obey the -p option,
+		// so extra filtering is needed. (golang.org/issue/10206)
+		return numOpenFDsAndroid(t)
+	}
+
 	lsof, err := exec.Command("lsof", "-b", "-n", "-p", strconv.Itoa(os.Getpid())).Output()
 	if err != nil {
 		t.Skip("skipping test; error finding or running lsof")
@@ -257,6 +265,45 @@
 	return bytes.Count(lsof, []byte("\n")), lsof
 }
 
+func numOpenFDsAndroid(t *testing.T) (n int, lsof []byte) {
+	raw, err := exec.Command("lsof").Output()
+	if err != nil {
+		t.Skip("skipping test; error finding or running lsof")
+	}
+
+	// First find the PID column index by parsing the first line, and
+	// select lines containing pid in the column.
+	pid := []byte(strconv.Itoa(os.Getpid()))
+	pidCol := -1
+
+	s := bufio.NewScanner(bytes.NewReader(raw))
+	for s.Scan() {
+		line := s.Bytes()
+		fields := bytes.Fields(line)
+		if pidCol < 0 {
+			for i, v := range fields {
+				if bytes.Equal(v, []byte("PID")) {
+					pidCol = i
+					break
+				}
+			}
+			lsof = append(lsof, line...)
+			continue
+		}
+		if bytes.Equal(fields[pidCol], pid) {
+			lsof = append(lsof, '\n')
+			lsof = append(lsof, line...)
+		}
+	}
+	if pidCol < 0 {
+		t.Fatal("error processing lsof output: unexpected header format")
+	}
+	if err := s.Err(); err != nil {
+		t.Fatalf("error processing lsof output: %v", err)
+	}
+	return bytes.Count(lsof, []byte("\n")), lsof
+}
+
 var testedAlreadyLeaked = false
 
 // basefds returns the number of expected file descriptors
@@ -275,15 +322,15 @@
 }
 
 func TestExtraFilesFDShuffle(t *testing.T) {
-	t.Skip("flaky test; see http://golang.org/issue/5780")
+	t.Skip("flaky test; see https://golang.org/issue/5780")
 	switch runtime.GOOS {
 	case "darwin":
-		// TODO(cnicolaou): http://golang.org/issue/2603
+		// TODO(cnicolaou): https://golang.org/issue/2603
 		// leads to leaked file descriptors in this test when it's
 		// run from a builder.
 		closeUnexpectedFds(t, "TestExtraFilesFDShuffle")
 	case "netbsd":
-		// http://golang.org/issue/3955
+		// https://golang.org/issue/3955
 		closeUnexpectedFds(t, "TestExtraFilesFDShuffle")
 	case "windows":
 		t.Skip("no operating system support; skipping")
@@ -379,8 +426,9 @@
 }
 
 func TestExtraFiles(t *testing.T) {
-	switch runtime.GOOS {
-	case "nacl", "windows":
+	testenv.MustHaveExec(t)
+
+	if runtime.GOOS == "windows" {
 		t.Skipf("skipping test on %q", runtime.GOOS)
 	}
 
@@ -608,21 +656,21 @@
 			// file descriptors...
 		case "darwin":
 			// TODO(bradfitz): broken? Sometimes.
-			// http://golang.org/issue/2603
+			// https://golang.org/issue/2603
 			// Skip this additional part of the test for now.
 		case "netbsd":
 			// TODO(jsing): This currently fails on NetBSD due to
 			// the cloned file descriptors that result from opening
 			// /dev/urandom.
-			// http://golang.org/issue/3955
+			// https://golang.org/issue/3955
 		case "plan9":
 			// TODO(0intro): Determine why Plan 9 is leaking
 			// file descriptors.
-			// http://golang.org/issue/7118
+			// https://golang.org/issue/7118
 		case "solaris":
 			// TODO(aram): This fails on Solaris because libc opens
 			// its own files, as it sees fit. Darwin does the same,
-			// see: http://golang.org/issue/2603
+			// see: https://golang.org/issue/2603
 		default:
 			// Now verify that there are no other open fds.
 			var files []*os.File
@@ -721,3 +769,54 @@
 		os.Exit(2)
 	}
 }
+
+// Issue 9173: ignore stdin pipe writes if the program completes successfully.
+func TestIgnorePipeErrorOnSuccess(t *testing.T) {
+	testenv.MustHaveExec(t)
+
+	// We really only care about testing this on Unixy things.
+	if runtime.GOOS == "windows" || runtime.GOOS == "plan9" {
+		t.Skipf("skipping test on %q", runtime.GOOS)
+	}
+
+	cmd := helperCommand(t, "echo", "foo")
+	var out bytes.Buffer
+	cmd.Stdin = strings.NewReader(strings.Repeat("x", 10<<20))
+	cmd.Stdout = &out
+	if err := cmd.Run(); err != nil {
+		t.Fatal(err)
+	}
+	if got, want := out.String(), "foo\n"; got != want {
+		t.Errorf("output = %q; want %q", got, want)
+	}
+}
+
+type badWriter struct{}
+
+func (w *badWriter) Write(data []byte) (int, error) {
+	return 0, io.ErrUnexpectedEOF
+}
+
+func TestClosePipeOnCopyError(t *testing.T) {
+	testenv.MustHaveExec(t)
+
+	if runtime.GOOS == "windows" || runtime.GOOS == "plan9" {
+		t.Skipf("skipping test on %s - no yes command", runtime.GOOS)
+	}
+	cmd := exec.Command("yes")
+	cmd.Stdout = new(badWriter)
+	c := make(chan int, 1)
+	go func() {
+		err := cmd.Run()
+		if err == nil {
+			t.Errorf("yes completed successfully")
+		}
+		c <- 1
+	}()
+	select {
+	case <-c:
+		// ok
+	case <-time.After(5 * time.Second):
+		t.Fatalf("yes got stuck writing to bad writer")
+	}
+}
diff --git a/third_party/gofrontend/libgo/go/os/exec_posix.go b/third_party/gofrontend/libgo/go/os/exec_posix.go
index fb9d291..94dd04b 100644
--- a/third_party/gofrontend/libgo/go/os/exec_posix.go
+++ b/third_party/gofrontend/libgo/go/os/exec_posix.go
@@ -81,33 +81,6 @@
 	return p.rusage
 }
 
-// Convert i to decimal string.
-func itod(i int) string {
-	if i == 0 {
-		return "0"
-	}
-
-	u := uint64(i)
-	if i < 0 {
-		u = -u
-	}
-
-	// Assemble decimal in reverse order.
-	var b [32]byte
-	bp := len(b)
-	for ; u > 0; u /= 10 {
-		bp--
-		b[bp] = byte(u%10) + '0'
-	}
-
-	if i < 0 {
-		bp--
-		b[bp] = '-'
-	}
-
-	return string(b[bp:])
-}
-
 func (p *ProcessState) String() string {
 	if p == nil {
 		return "<nil>"
@@ -116,13 +89,13 @@
 	res := ""
 	switch {
 	case status.Exited():
-		res = "exit status " + itod(status.ExitStatus())
+		res = "exit status " + itoa(status.ExitStatus())
 	case status.Signaled():
 		res = "signal: " + status.Signal().String()
 	case status.Stopped():
 		res = "stop signal: " + status.StopSignal().String()
 		if status.StopSignal() == syscall.SIGTRAP && status.TrapCause() != 0 {
-			res += " (trap " + itod(status.TrapCause()) + ")"
+			res += " (trap " + itoa(status.TrapCause()) + ")"
 		}
 	case status.Continued():
 		res = "continued"
diff --git a/third_party/gofrontend/libgo/go/os/exec_windows.go b/third_party/gofrontend/libgo/go/os/exec_windows.go
index 393393b..3264271 100644
--- a/third_party/gofrontend/libgo/go/os/exec_windows.go
+++ b/third_party/gofrontend/libgo/go/os/exec_windows.go
@@ -7,13 +7,15 @@
 import (
 	"errors"
 	"runtime"
+	"sync/atomic"
 	"syscall"
 	"time"
 	"unsafe"
 )
 
 func (p *Process) wait() (ps *ProcessState, err error) {
-	s, e := syscall.WaitForSingleObject(syscall.Handle(p.handle), syscall.INFINITE)
+	handle := atomic.LoadUintptr(&p.handle)
+	s, e := syscall.WaitForSingleObject(syscall.Handle(handle), syscall.INFINITE)
 	switch s {
 	case syscall.WAIT_OBJECT_0:
 		break
@@ -23,12 +25,12 @@
 		return nil, errors.New("os: unexpected result from WaitForSingleObject")
 	}
 	var ec uint32
-	e = syscall.GetExitCodeProcess(syscall.Handle(p.handle), &ec)
+	e = syscall.GetExitCodeProcess(syscall.Handle(handle), &ec)
 	if e != nil {
 		return nil, NewSyscallError("GetExitCodeProcess", e)
 	}
 	var u syscall.Rusage
-	e = syscall.GetProcessTimes(syscall.Handle(p.handle), &u.CreationTime, &u.ExitTime, &u.KernelTime, &u.UserTime)
+	e = syscall.GetProcessTimes(syscall.Handle(handle), &u.CreationTime, &u.ExitTime, &u.KernelTime, &u.UserTime)
 	if e != nil {
 		return nil, NewSyscallError("GetProcessTimes", e)
 	}
@@ -53,7 +55,8 @@
 }
 
 func (p *Process) signal(sig Signal) error {
-	if p.handle == uintptr(syscall.InvalidHandle) {
+	handle := atomic.LoadUintptr(&p.handle)
+	if handle == uintptr(syscall.InvalidHandle) {
 		return syscall.EINVAL
 	}
 	if p.done() {
@@ -67,14 +70,15 @@
 }
 
 func (p *Process) release() error {
-	if p.handle == uintptr(syscall.InvalidHandle) {
+	handle := atomic.LoadUintptr(&p.handle)
+	if handle == uintptr(syscall.InvalidHandle) {
 		return syscall.EINVAL
 	}
-	e := syscall.CloseHandle(syscall.Handle(p.handle))
+	e := syscall.CloseHandle(syscall.Handle(handle))
 	if e != nil {
 		return NewSyscallError("CloseHandle", e)
 	}
-	p.handle = uintptr(syscall.InvalidHandle)
+	atomic.StoreUintptr(&p.handle, uintptr(syscall.InvalidHandle))
 	// no need for a finalizer anymore
 	runtime.SetFinalizer(p, nil)
 	return nil
diff --git a/third_party/gofrontend/libgo/go/os/file.go b/third_party/gofrontend/libgo/go/os/file.go
index e12428c..8c0e3ff 100644
--- a/third_party/gofrontend/libgo/go/os/file.go
+++ b/third_party/gofrontend/libgo/go/os/file.go
@@ -192,7 +192,7 @@
 
 // WriteString is like Write, but writes the contents of string s rather than
 // a slice of bytes.
-func (f *File) WriteString(s string) (ret int, err error) {
+func (f *File) WriteString(s string) (n int, err error) {
 	if f == nil {
 		return 0, ErrInvalid
 	}
@@ -203,9 +203,16 @@
 // If there is an error, it will be of type *PathError.
 func Mkdir(name string, perm FileMode) error {
 	e := syscall.Mkdir(name, syscallMode(perm))
+
 	if e != nil {
 		return &PathError{"mkdir", name, e}
 	}
+
+	// mkdir(2) itself won't handle the sticky bit on *BSD and Solaris
+	if !supportsCreateWithStickyBit && perm&ModeSticky != 0 {
+		Chmod(name, perm)
+	}
+
 	return nil
 }
 
@@ -235,16 +242,16 @@
 // the returned file can be used for reading; the associated file
 // descriptor has mode O_RDONLY.
 // If there is an error, it will be of type *PathError.
-func Open(name string) (file *File, err error) {
+func Open(name string) (*File, error) {
 	return OpenFile(name, O_RDONLY, 0)
 }
 
-// Create creates the named file mode 0666 (before umask), truncating
-// it if it already exists.  If successful, methods on the returned
+// Create creates the named file with mode 0666 (before umask), truncating
+// it if it already exists. If successful, methods on the returned
 // File can be used for I/O; the associated file descriptor has mode
 // O_RDWR.
 // If there is an error, it will be of type *PathError.
-func Create(name string) (file *File, err error) {
+func Create(name string) (*File, error) {
 	return OpenFile(name, O_RDWR|O_CREATE|O_TRUNC, 0666)
 }
 
@@ -252,6 +259,7 @@
 var lstat = Lstat
 
 // Rename renames (moves) a file. OS-specific restrictions might apply.
+// If there is an error, it will be of type *LinkError.
 func Rename(oldpath, newpath string) error {
 	return rename(oldpath, newpath)
 }
diff --git a/third_party/gofrontend/libgo/go/os/file_plan9.go b/third_party/gofrontend/libgo/go/os/file_plan9.go
index 132594e..085ebc4 100644
--- a/third_party/gofrontend/libgo/go/os/file_plan9.go
+++ b/third_party/gofrontend/libgo/go/os/file_plan9.go
@@ -79,7 +79,7 @@
 // (O_RDONLY etc.) and perm, (0666 etc.) if applicable.  If successful,
 // methods on the returned File can be used for I/O.
 // If there is an error, it will be of type *PathError.
-func OpenFile(name string, flag int, perm FileMode) (file *File, err error) {
+func OpenFile(name string, flag int, perm FileMode) (*File, error) {
 	var (
 		fd     int
 		e      error
@@ -159,7 +159,7 @@
 
 // Stat returns the FileInfo structure describing file.
 // If there is an error, it will be of type *PathError.
-func (f *File) Stat() (fi FileInfo, err error) {
+func (f *File) Stat() (FileInfo, error) {
 	if f == nil {
 		return nil, ErrInvalid
 	}
@@ -224,7 +224,7 @@
 // Sync commits the current contents of the file to stable storage.
 // Typically, this means flushing the file system's in-memory copy
 // of recently written data to disk.
-func (f *File) Sync() (err error) {
+func (f *File) Sync() error {
 	if f == nil {
 		return ErrInvalid
 	}
@@ -319,7 +319,7 @@
 	return len(s) >= len(prefix) && s[0:len(prefix)] == prefix
 }
 
-// Variant of LastIndex from the strings package.
+// LastIndexByte from the strings package.
 func lastIndex(s string, sep byte) int {
 	for i := len(s) - 1; i >= 0; i-- {
 		if s[i] == sep {
diff --git a/third_party/gofrontend/libgo/go/os/file_posix.go b/third_party/gofrontend/libgo/go/os/file_posix.go
index fbb3b5e..6d8076f 100644
--- a/third_party/gofrontend/libgo/go/os/file_posix.go
+++ b/third_party/gofrontend/libgo/go/os/file_posix.go
@@ -28,14 +28,6 @@
 	}
 }
 
-func rename(oldname, newname string) error {
-	e := syscall.Rename(oldname, newname)
-	if e != nil {
-		return &LinkError{"rename", oldname, newname, e}
-	}
-	return nil
-}
-
 // syscallMode returns the syscall-specific mode bits from Go's portable mode bits.
 func syscallMode(i FileMode) (o uint32) {
 	o |= uint32(i.Perm())
@@ -122,7 +114,7 @@
 // Sync commits the current contents of the file to stable storage.
 // Typically, this means flushing the file system's in-memory copy
 // of recently written data to disk.
-func (f *File) Sync() (err error) {
+func (f *File) Sync() error {
 	if f == nil {
 		return ErrInvalid
 	}
diff --git a/third_party/gofrontend/libgo/go/os/file_unix.go b/third_party/gofrontend/libgo/go/os/file_unix.go
index b25e62f..7a18987 100644
--- a/third_party/gofrontend/libgo/go/os/file_unix.go
+++ b/third_party/gofrontend/libgo/go/os/file_unix.go
@@ -12,6 +12,14 @@
 	"syscall"
 )
 
+func rename(oldname, newname string) error {
+	e := syscall.Rename(oldname, newname)
+	if e != nil {
+		return &LinkError{"rename", oldname, newname, e}
+	}
+	return nil
+}
+
 // File represents an open file descriptor.
 type File struct {
 	*file
@@ -73,12 +81,24 @@
 // (O_RDONLY etc.) and perm, (0666 etc.) if applicable.  If successful,
 // methods on the returned File can be used for I/O.
 // If there is an error, it will be of type *PathError.
-func OpenFile(name string, flag int, perm FileMode) (file *File, err error) {
+func OpenFile(name string, flag int, perm FileMode) (*File, error) {
+	chmod := false
+	if !supportsCreateWithStickyBit && flag&O_CREATE != 0 && perm&ModeSticky != 0 {
+		if _, err := Stat(name); IsNotExist(err) {
+			chmod = true
+		}
+	}
+
 	r, e := syscall.Open(name, flag|syscall.O_CLOEXEC, syscallMode(perm))
 	if e != nil {
 		return nil, &PathError{"open", name, e}
 	}
 
+	// open(2) itself won't handle the sticky bit on *BSD and Solaris
+	if chmod {
+		Chmod(name, perm)
+	}
+
 	// There's a race here with fork/exec, which we are
 	// content to live with.  See ../syscall/exec_unix.go.
 	if !supportsCloseOnExec {
@@ -126,12 +146,12 @@
 
 // Stat returns the FileInfo structure describing file.
 // If there is an error, it will be of type *PathError.
-func (f *File) Stat() (fi FileInfo, err error) {
+func (f *File) Stat() (FileInfo, error) {
 	if f == nil {
 		return nil, ErrInvalid
 	}
 	var stat syscall.Stat_t
-	err = syscall.Fstat(f.fd, &stat)
+	err := syscall.Fstat(f.fd, &stat)
 	if err != nil {
 		return nil, &PathError{"stat", f.name, err}
 	}
@@ -140,9 +160,9 @@
 
 // Stat returns a FileInfo describing the named file.
 // If there is an error, it will be of type *PathError.
-func Stat(name string) (fi FileInfo, err error) {
+func Stat(name string) (FileInfo, error) {
 	var stat syscall.Stat_t
-	err = syscall.Stat(name, &stat)
+	err := syscall.Stat(name, &stat)
 	if err != nil {
 		return nil, &PathError{"stat", name, err}
 	}
@@ -153,9 +173,9 @@
 // If the file is a symbolic link, the returned FileInfo
 // describes the symbolic link.  Lstat makes no attempt to follow the link.
 // If there is an error, it will be of type *PathError.
-func Lstat(name string) (fi FileInfo, err error) {
+func Lstat(name string) (FileInfo, error) {
 	var stat syscall.Stat_t
-	err = syscall.Lstat(name, &stat)
+	err := syscall.Lstat(name, &stat)
 	if err != nil {
 		return nil, &PathError{"lstat", name, err}
 	}
diff --git a/third_party/gofrontend/libgo/go/os/os_test.go b/third_party/gofrontend/libgo/go/os/os_test.go
index 7a86efa..78201f2 100644
--- a/third_party/gofrontend/libgo/go/os/os_test.go
+++ b/third_party/gofrontend/libgo/go/os/os_test.go
@@ -9,6 +9,7 @@
 	"errors"
 	"flag"
 	"fmt"
+	"internal/testenv"
 	"io"
 	"io/ioutil"
 	. "os"
@@ -21,7 +22,6 @@
 	"sync"
 	"syscall"
 	"testing"
-	"text/template"
 	"time"
 )
 
@@ -41,18 +41,33 @@
 	files []string
 }
 
-var sysdir = func() (sd *sysDir) {
+var sysdir = func() *sysDir {
 	switch runtime.GOOS {
 	case "android":
-		sd = &sysDir{
+		return &sysDir{
 			"/system/etc",
 			[]string{
 				"audio_policy.conf",
 				"system_fonts.xml",
 			},
 		}
+	case "darwin":
+		switch runtime.GOARCH {
+		case "arm", "arm64":
+			wd, err := syscall.Getwd()
+			if err != nil {
+				wd = err.Error()
+			}
+			return &sysDir{
+				filepath.Join(wd, "..", ".."),
+				[]string{
+					"ResourceRules.plist",
+					"Info.plist",
+				},
+			}
+		}
 	case "windows":
-		sd = &sysDir{
+		return &sysDir{
 			Getenv("SystemRoot") + "\\system32\\drivers\\etc",
 			[]string{
 				"networks",
@@ -61,24 +76,22 @@
 			},
 		}
 	case "plan9":
-		sd = &sysDir{
+		return &sysDir{
 			"/lib/ndb",
 			[]string{
 				"common",
 				"local",
 			},
 		}
-	default:
-		sd = &sysDir{
-			"/etc",
-			[]string{
-				"group",
-				"hosts",
-				"passwd",
-			},
-		}
 	}
-	return
+	return &sysDir{
+		"/etc",
+		[]string{
+			"group",
+			"hosts",
+			"passwd",
+		},
+	}
 }()
 
 func size(name string, t *testing.T) int64 {
@@ -112,15 +125,22 @@
 	return
 }
 
-func newFile(testName string, t *testing.T) (f *File) {
-	// Use a local file system, not NFS.
-	// On Unix, override $TMPDIR in case the user
-	// has it set to an NFS-mounted directory.
-	dir := ""
-	if runtime.GOOS != "android" && runtime.GOOS != "windows" {
-		dir = "/tmp"
+// localTmp returns a local temporary directory not on NFS.
+func localTmp() string {
+	switch runtime.GOOS {
+	case "android", "windows":
+		return TempDir()
+	case "darwin":
+		switch runtime.GOARCH {
+		case "arm", "arm64":
+			return TempDir()
+		}
 	}
-	f, err := ioutil.TempFile(dir, "_Go_"+testName)
+	return "/tmp"
+}
+
+func newFile(testName string, t *testing.T) (f *File) {
+	f, err := ioutil.TempFile(localTmp(), "_Go_"+testName)
 	if err != nil {
 		t.Fatalf("TempFile %s: %s", testName, err)
 	}
@@ -128,14 +148,7 @@
 }
 
 func newDir(testName string, t *testing.T) (name string) {
-	// Use a local file system, not NFS.
-	// On Unix, override $TMPDIR in case the user
-	// has it set to an NFS-mounted directory.
-	dir := ""
-	if runtime.GOOS != "android" && runtime.GOOS != "windows" {
-		dir = "/tmp"
-	}
-	name, err := ioutil.TempDir(dir, "_Go_"+testName)
+	name, err := ioutil.TempDir(localTmp(), "_Go_"+testName)
 	if err != nil {
 		t.Fatalf("TempDir %s: %s", testName, err)
 	}
@@ -310,6 +323,15 @@
 	switch runtime.GOOS {
 	case "android":
 		dir = "/system/bin"
+	case "darwin":
+		switch runtime.GOARCH {
+		case "arm", "arm64":
+			wd, err := Getwd()
+			if err != nil {
+				t.Fatal(err)
+			}
+			dir = wd
+		}
 	case "plan9":
 		dir = "/bin"
 	case "windows":
@@ -489,11 +511,35 @@
 	}
 }
 
-func TestHardLink(t *testing.T) {
-	// Hardlinks are not supported under windows or Plan 9.
-	if runtime.GOOS == "plan9" {
-		return
+// Readdir on a regular file should fail.
+func TestReaddirOfFile(t *testing.T) {
+	f, err := ioutil.TempFile("", "_Go_ReaddirOfFile")
+	if err != nil {
+		t.Fatal(err)
 	}
+	defer Remove(f.Name())
+	f.Write([]byte("foo"))
+	f.Close()
+	reg, err := Open(f.Name())
+	if err != nil {
+		t.Fatal(err)
+	}
+	defer reg.Close()
+
+	names, err := reg.Readdirnames(-1)
+	if err == nil {
+		t.Error("Readdirnames succeeded; want non-nil error")
+	}
+	if len(names) > 0 {
+		t.Errorf("unexpected dir names in regular file: %q", names)
+	}
+}
+
+func TestHardLink(t *testing.T) {
+	if runtime.GOOS == "plan9" {
+		t.Skip("skipping on plan9, hardlinks not supported")
+	}
+	defer chtmpdir(t)()
 	from, to := "hardlinktestfrom", "hardlinktestto"
 	Remove(from) // Just in case.
 	file, err := Create(to)
@@ -508,6 +554,14 @@
 	if err != nil {
 		t.Fatalf("link %q, %q failed: %v", to, from, err)
 	}
+
+	none := "hardlinktestnone"
+	err = Link(none, none)
+	// Check the returned error is well-formed.
+	if lerr, ok := err.(*LinkError); !ok || lerr.Error() == "" {
+		t.Errorf("link %q, %q failed to return a valid error", none, none)
+	}
+
 	defer Remove(from)
 	tostat, err := Stat(to)
 	if err != nil {
@@ -522,6 +576,31 @@
 	}
 }
 
+// chtmpdir changes the working directory to a new temporary directory and
+// provides a cleanup function. Used when PWD is read-only.
+func chtmpdir(t *testing.T) func() {
+	if runtime.GOOS != "darwin" || (runtime.GOARCH != "arm" && runtime.GOARCH != "arm64") {
+		return func() {} // only needed on darwin/arm{,64}
+	}
+	oldwd, err := Getwd()
+	if err != nil {
+		t.Fatalf("chtmpdir: %v", err)
+	}
+	d, err := ioutil.TempDir("", "test")
+	if err != nil {
+		t.Fatalf("chtmpdir: %v", err)
+	}
+	if err := Chdir(d); err != nil {
+		t.Fatalf("chtmpdir: %v", err)
+	}
+	return func() {
+		if err := Chdir(oldwd); err != nil {
+			t.Fatalf("chtmpdir: %v", err)
+		}
+		RemoveAll(d)
+	}
+}
+
 func TestSymlink(t *testing.T) {
 	switch runtime.GOOS {
 	case "android", "nacl", "plan9":
@@ -531,6 +610,7 @@
 			t.Skipf("skipping on %s", runtime.GOOS)
 		}
 	}
+	defer chtmpdir(t)()
 	from, to := "symlinktestfrom", "symlinktestto"
 	Remove(from) // Just in case.
 	file, err := Create(to)
@@ -597,6 +677,7 @@
 			t.Skipf("skipping on %s", runtime.GOOS)
 		}
 	}
+	defer chtmpdir(t)()
 	s := "0123456789abcdef"
 	// Long, but not too long: a common limit is 255.
 	s = s + s + s + s + s + s + s + s + s + s + s + s + s + s + s
@@ -617,14 +698,18 @@
 }
 
 func TestRename(t *testing.T) {
+	defer chtmpdir(t)()
 	from, to := "renamefrom", "renameto"
-	Remove(to) // Just in case.
+	// Ensure we are not testing the overwrite case here.
+	Remove(from)
+	Remove(to)
+
 	file, err := Create(from)
 	if err != nil {
-		t.Fatalf("open %q failed: %v", to, err)
+		t.Fatalf("open %q failed: %v", from, err)
 	}
 	if err = file.Close(); err != nil {
-		t.Errorf("close %q failed: %v", to, err)
+		t.Errorf("close %q failed: %v", from, err)
 	}
 	err = Rename(from, to)
 	if err != nil {
@@ -637,6 +722,79 @@
 	}
 }
 
+func TestRenameOverwriteDest(t *testing.T) {
+	if runtime.GOOS == "plan9" {
+		t.Skip("skipping on plan9")
+	}
+	defer chtmpdir(t)()
+	from, to := "renamefrom", "renameto"
+	// Just in case.
+	Remove(from)
+	Remove(to)
+
+	toData := []byte("to")
+	fromData := []byte("from")
+
+	err := ioutil.WriteFile(to, toData, 0777)
+	if err != nil {
+		t.Fatalf("write file %q failed: %v", to, err)
+	}
+
+	err = ioutil.WriteFile(from, fromData, 0777)
+	if err != nil {
+		t.Fatalf("write file %q failed: %v", from, err)
+	}
+	err = Rename(from, to)
+	if err != nil {
+		t.Fatalf("rename %q, %q failed: %v", to, from, err)
+	}
+	defer Remove(to)
+
+	_, err = Stat(from)
+	if err == nil {
+		t.Errorf("from file %q still exists", from)
+	}
+	if err != nil && !IsNotExist(err) {
+		t.Fatalf("stat from: %v", err)
+	}
+	toFi, err := Stat(to)
+	if err != nil {
+		t.Fatalf("stat %q failed: %v", to, err)
+	}
+	if toFi.Size() != int64(len(fromData)) {
+		t.Errorf(`"to" size = %d; want %d (old "from" size)`, toFi.Size(), len(fromData))
+	}
+}
+
+func TestRenameFailed(t *testing.T) {
+	defer chtmpdir(t)()
+	from, to := "renamefrom", "renameto"
+	// Ensure we are not testing the overwrite case here.
+	Remove(from)
+	Remove(to)
+
+	err := Rename(from, to)
+	switch err := err.(type) {
+	case *LinkError:
+		if err.Op != "rename" {
+			t.Errorf("rename %q, %q: err.Op: want %q, got %q", from, to, "rename", err.Op)
+		}
+		if err.Old != from {
+			t.Errorf("rename %q, %q: err.Old: want %q, got %q", from, to, from, err.Old)
+		}
+		if err.New != to {
+			t.Errorf("rename %q, %q: err.New: want %q, got %q", from, to, to, err.New)
+		}
+	case nil:
+		t.Errorf("rename %q, %q: expected error, got nil", from, to)
+
+		// cleanup whatever was placed in "renameto"
+		Remove(to)
+	default:
+		t.Errorf("rename %q, %q: expected %T, got %T %v", from, to, new(LinkError), err, err)
+	}
+}
+
 func exec(t *testing.T, dir, cmd string, args []string, expect string) {
 	r, w, err := Pipe()
 	if err != nil {
@@ -664,18 +822,18 @@
 }
 
 func TestStartProcess(t *testing.T) {
-	switch runtime.GOOS {
-	case "android", "nacl":
-		t.Skipf("skipping on %s", runtime.GOOS)
-	}
+	testenv.MustHaveExec(t)
 
 	var dir, cmd string
 	var args []string
-	if runtime.GOOS == "windows" {
+	switch runtime.GOOS {
+	case "android":
+		t.Skip("android doesn't have /bin/pwd")
+	case "windows":
 		cmd = Getenv("COMSPEC")
 		dir = Getenv("SystemRoot")
 		args = []string{"/c", "cd"}
-	} else {
+	default:
 		cmd = "/bin/pwd"
 		dir = "/"
 		args = []string{}
@@ -847,6 +1005,19 @@
 		dirs = []string{"/", "/system/bin"}
 	case "plan9":
 		dirs = []string{"/", "/usr"}
+	case "darwin":
+		switch runtime.GOARCH {
+		case "arm", "arm64":
+			d1, err := ioutil.TempDir("", "d1")
+			if err != nil {
+				t.Fatalf("TempDir: %v", err)
+			}
+			d2, err := ioutil.TempDir("", "d2")
+			if err != nil {
+				t.Fatalf("TempDir: %v", err)
+			}
+			dirs = []string{d1, d2}
+		}
 	}
 	oldwd := Getenv("PWD")
 	for mode := 0; mode < 2; mode++ {
@@ -892,6 +1063,64 @@
 	fd.Close()
 }
 
+// Test that Chdir+Getwd is program-wide.
+func TestProgWideChdir(t *testing.T) {
+	const N = 10
+	c := make(chan bool)
+	cpwd := make(chan string)
+	for i := 0; i < N; i++ {
+		go func(i int) {
+			// Lock half the goroutines in their own operating system
+			// thread to exercise more scheduler possibilities.
+			if i%2 == 1 {
+				// On Plan 9, after calling LockOSThread, the goroutines
+				// run on different processes which don't share the working
+				// directory. This used to be an issue because Go expects
+				// the working directory to be program-wide.
+				// See issue 9428.
+				runtime.LockOSThread()
+			}
+			<-c
+			pwd, err := Getwd()
+			if err != nil {
+				t.Errorf("Getwd on goroutine %d: %v", i, err)
+				return
+			}
+			cpwd <- pwd
+		}(i)
+	}
+	oldwd, err := Getwd()
+	if err != nil {
+		t.Fatalf("Getwd: %v", err)
+	}
+	d, err := ioutil.TempDir("", "test")
+	if err != nil {
+		t.Fatalf("TempDir: %v", err)
+	}
+	defer func() {
+		if err := Chdir(oldwd); err != nil {
+			t.Fatalf("Chdir: %v", err)
+		}
+		RemoveAll(d)
+	}()
+	if err := Chdir(d); err != nil {
+		t.Fatalf("Chdir: %v", err)
+	}
+	// OS X sets TMPDIR to a symbolic link.
+	// So we resolve our working directory again before the test.
+	d, err = Getwd()
+	if err != nil {
+		t.Fatalf("Getwd: %v", err)
+	}
+	close(c)
+	for i := 0; i < N; i++ {
+		pwd := <-cpwd
+		if pwd != d {
+			t.Errorf("Getwd returned %q; want %q", pwd, d)
+		}
+	}
+}
+
 func TestSeek(t *testing.T) {
 	f := newFile("TestSeek", t)
 	defer Remove(f.Name())
@@ -920,7 +1149,7 @@
 		if off != tt.out || err != nil {
 			if e, ok := err.(*PathError); ok && e.Err == syscall.EINVAL && tt.out > 1<<32 {
 				// Reiserfs rejects the big seeks.
-				// http://code.google.com/p/go/issues/detail?id=91
+				// https://golang.org/issue/91
 				break
 			}
 			t.Errorf("#%d: Seek(%v, %v) = %v, %v want %v, nil", i, tt.in, tt.whence, off, err, tt.out)
@@ -1033,14 +1262,35 @@
 	return output
 }
 
+func testWindowsHostname(t *testing.T) {
+	hostname, err := Hostname()
+	if err != nil {
+		t.Fatal(err)
+	}
+	cmd := osexec.Command("hostname")
+	out, err := cmd.CombinedOutput()
+	if err != nil {
+		t.Fatalf("Failed to execute hostname command: %v %s", err, out)
+	}
+	want := strings.Trim(string(out), "\r\n")
+	if hostname != want {
+		t.Fatalf("Hostname() = %q, want %q", hostname, want)
+	}
+}
+
 func TestHostname(t *testing.T) {
 	// There is no other way to fetch hostname on windows, but via winapi.
 	// On Plan 9 it can be taken from #c/sysname as Hostname() does.
 	switch runtime.GOOS {
-	case "android", "nacl", "plan9", "windows":
-		t.Skipf("skipping on %s", runtime.GOOS)
+	case "android", "plan9":
+		t.Skipf("%s doesn't have /bin/hostname", runtime.GOOS)
+	case "windows":
+		testWindowsHostname(t)
+		return
 	}
 
+	testenv.MustHaveExec(t)
+
 	// Check internal Hostname() against the output of /bin/hostname.
 	// Allow that the internal Hostname returns a Fully Qualified Domain Name
 	// and the /bin/hostname only returns the first component
@@ -1115,6 +1365,7 @@
 }
 
 func TestAppend(t *testing.T) {
+	defer chtmpdir(t)()
 	const f = "append.txt"
 	defer Remove(f)
 	s := writeFile(t, f, O_CREATE|O_TRUNC|O_RDWR, "new")
@@ -1178,6 +1429,7 @@
 }
 
 func TestSameFile(t *testing.T) {
+	defer chtmpdir(t)()
 	fa, err := Create("a")
 	if err != nil {
 		t.Fatalf("Create(a): %v", err)
@@ -1297,45 +1549,11 @@
 }
 
 func testKillProcess(t *testing.T, processKiller func(p *Process)) {
-	t.Skip("gccgo does not have a go command")
-	switch runtime.GOOS {
-	case "android", "nacl":
-		t.Skipf("skipping on %s", runtime.GOOS)
-	}
+	testenv.MustHaveExec(t)
 
-	dir, err := ioutil.TempDir("", "go-build")
-	if err != nil {
-		t.Fatalf("Failed to create temp directory: %v", err)
-	}
-	defer RemoveAll(dir)
-
-	src := filepath.Join(dir, "main.go")
-	f, err := Create(src)
-	if err != nil {
-		t.Fatalf("Failed to create %v: %v", src, err)
-	}
-	st := template.Must(template.New("source").Parse(`
-package main
-import "time"
-func main() {
-	time.Sleep(time.Second)
-}
-`))
-	err = st.Execute(f, nil)
-	if err != nil {
-		f.Close()
-		t.Fatalf("Failed to execute template: %v", err)
-	}
-	f.Close()
-
-	exe := filepath.Join(dir, "main.exe")
-	output, err := osexec.Command("go", "build", "-o", exe, src).CombinedOutput()
-	if err != nil {
-		t.Fatalf("Failed to build exe %v: %v %v", exe, err, string(output))
-	}
-
-	cmd := osexec.Command(exe)
-	err = cmd.Start()
+	// Re-exec the test binary itself to emulate "sleep 1".
+	cmd := osexec.Command(Args[0], "-test.run", "TestSleep")
+	err := cmd.Start()
 	if err != nil {
 		t.Fatalf("Failed to start test process: %v", err)
 	}
@@ -1349,6 +1567,15 @@
 	}
 }
 
+// TestSleep emulates "sleep 1". It is a helper for testKillProcess, so we
+// don't have to rely on an external "sleep" command being available.
+func TestSleep(t *testing.T) {
+	if testing.Short() {
+		t.Skip("Skipping in short mode")
+	}
+	time.Sleep(time.Second)
+}
+
 func TestKillStartProcess(t *testing.T) {
 	testKillProcess(t, func(p *Process) {
 		err := p.Kill()
@@ -1359,14 +1586,13 @@
 }
 
 func TestGetppid(t *testing.T) {
-	switch runtime.GOOS {
-	case "nacl":
-		t.Skip("skipping on nacl")
-	case "plan9":
+	if runtime.GOOS == "plan9" {
 		// TODO: golang.org/issue/8206
 		t.Skipf("skipping test on plan9; see issue 8206")
 	}
 
+	testenv.MustHaveExec(t)
+
 	if Getenv("GO_WANT_HELPER_PROCESS") == "1" {
 		fmt.Print(Getppid())
 		Exit(0)
diff --git a/third_party/gofrontend/libgo/go/os/os_unix_test.go b/third_party/gofrontend/libgo/go/os/os_unix_test.go
index 21d40cc..2adc3b5 100644
--- a/third_party/gofrontend/libgo/go/os/os_unix_test.go
+++ b/third_party/gofrontend/libgo/go/os/os_unix_test.go
@@ -13,6 +13,10 @@
 	"testing"
 )
 
+func init() {
+	isReadonlyError = func(err error) bool { return err == syscall.EROFS }
+}
+
 func checkUidGid(t *testing.T, path string, uid, gid int) {
 	dir, err := Stat(path)
 	if err != nil {
@@ -28,10 +32,10 @@
 }
 
 func TestChown(t *testing.T) {
-	// Chown is not supported under windows os Plan 9.
+	// Chown is not supported under windows or Plan 9.
 	// Plan9 provides a native ChownPlan9 version instead.
 	if runtime.GOOS == "windows" || runtime.GOOS == "plan9" {
-		return
+		t.Skipf("%s does not support syscall.Chown", runtime.GOOS)
 	}
 	// Use TempDir() to make sure we're on a local file system,
 	// so that the group ids returned by Getgroups will be allowed
@@ -74,3 +78,109 @@
 		checkUidGid(t, f.Name(), int(sys.Uid), gid)
 	}
 }
+
+func TestFileChown(t *testing.T) {
+	// Fchown is not supported under windows or Plan 9.
+	if runtime.GOOS == "windows" || runtime.GOOS == "plan9" {
+		t.Skipf("%s does not support syscall.Fchown", runtime.GOOS)
+	}
+	// Use TempDir() to make sure we're on a local file system,
+	// so that the group ids returned by Getgroups will be allowed
+	// on the file.  On NFS, the Getgroups groups are
+	// basically useless.
+	f := newFile("TestFileChown", t)
+	defer Remove(f.Name())
+	defer f.Close()
+	dir, err := f.Stat()
+	if err != nil {
+		t.Fatalf("stat %s: %s", f.Name(), err)
+	}
+
+	// Can't change uid unless root, but can try
+	// changing the group id.  First try our current group.
+	gid := Getgid()
+	t.Log("gid:", gid)
+	if err = f.Chown(-1, gid); err != nil {
+		t.Fatalf("fchown %s -1 %d: %s", f.Name(), gid, err)
+	}
+	sys := dir.Sys().(*syscall.Stat_t)
+	checkUidGid(t, f.Name(), int(sys.Uid), gid)
+
+	// Then try all the auxiliary groups.
+	groups, err := Getgroups()
+	if err != nil {
+		t.Fatalf("getgroups: %s", err)
+	}
+	t.Log("groups: ", groups)
+	for _, g := range groups {
+		if err = f.Chown(-1, g); err != nil {
+			t.Fatalf("fchown %s -1 %d: %s", f.Name(), g, err)
+		}
+		checkUidGid(t, f.Name(), int(sys.Uid), g)
+
+		// change back to gid to test fd.Chown
+		if err = f.Chown(-1, gid); err != nil {
+			t.Fatalf("fchown %s -1 %d: %s", f.Name(), gid, err)
+		}
+		checkUidGid(t, f.Name(), int(sys.Uid), gid)
+	}
+}
+
+func TestLchown(t *testing.T) {
+	// Lchown is not supported under windows or Plan 9.
+	if runtime.GOOS == "windows" || runtime.GOOS == "plan9" {
+		t.Skipf("%s does not support syscall.Lchown", runtime.GOOS)
+	}
+	// Use TempDir() to make sure we're on a local file system,
+	// so that the group ids returned by Getgroups will be allowed
+	// on the file.  On NFS, the Getgroups groups are
+	// basically useless.
+	f := newFile("TestLchown", t)
+	defer Remove(f.Name())
+	defer f.Close()
+	dir, err := f.Stat()
+	if err != nil {
+		t.Fatalf("stat %s: %s", f.Name(), err)
+	}
+
+	linkname := f.Name() + "2"
+	if err := Link(f.Name(), linkname); err != nil {
+		t.Fatalf("link %s -> %s: %v", f.Name(), linkname, err)
+	}
+	defer Remove(linkname)
+
+	f2, err := Open(linkname)
+	if err != nil {
+		t.Fatalf("open %s: %v", linkname, err)
+	}
+	defer f2.Close()
+
+	// Can't change uid unless root, but can try
+	// changing the group id.  First try our current group.
+	gid := Getgid()
+	t.Log("gid:", gid)
+	if err = Lchown(linkname, -1, gid); err != nil {
+		t.Fatalf("lchown %s -1 %d: %s", linkname, gid, err)
+	}
+	sys := dir.Sys().(*syscall.Stat_t)
+	checkUidGid(t, linkname, int(sys.Uid), gid)
+
+	// Then try all the auxiliary groups.
+	groups, err := Getgroups()
+	if err != nil {
+		t.Fatalf("getgroups: %s", err)
+	}
+	t.Log("groups: ", groups)
+	for _, g := range groups {
+		if err = Lchown(linkname, -1, g); err != nil {
+			t.Fatalf("lchown %s -1 %d: %s", linkname, g, err)
+		}
+		checkUidGid(t, linkname, int(sys.Uid), g)
+
+		// change back to gid to test fd.Chown
+		if err = f2.Chown(-1, gid); err != nil {
+			t.Fatalf("fchown %s -1 %d: %s", linkname, gid, err)
+		}
+		checkUidGid(t, linkname, int(sys.Uid), gid)
+	}
+}
diff --git a/third_party/gofrontend/libgo/go/os/path_plan9.go b/third_party/gofrontend/libgo/go/os/path_plan9.go
index 64bad50..b09b53a 100644
--- a/third_party/gofrontend/libgo/go/os/path_plan9.go
+++ b/third_party/gofrontend/libgo/go/os/path_plan9.go
@@ -9,7 +9,7 @@
 	PathListSeparator = '\000' // OS-specific path list separator
 )
 
-// IsPathSeparator returns true if c is a directory separator character.
+// IsPathSeparator reports whether c is a directory separator character.
 func IsPathSeparator(c uint8) bool {
 	return PathSeparator == c
 }
diff --git a/third_party/gofrontend/libgo/go/os/path_test.go b/third_party/gofrontend/libgo/go/os/path_test.go
index 6f24a43..f985381 100644
--- a/third_party/gofrontend/libgo/go/os/path_test.go
+++ b/third_party/gofrontend/libgo/go/os/path_test.go
@@ -13,6 +13,8 @@
 	"testing"
 )
 
+var isReadonlyError = func(error) bool { return false }
+
 func TestMkdirAll(t *testing.T) {
 	tmpDir := TempDir()
 	path := tmpDir + "/_TestMkdirAll_/dir/./dir2"
@@ -205,16 +207,22 @@
 	switch runtime.GOOS {
 	case "android", "plan9", "windows":
 		t.Skipf("skipping on %s", runtime.GOOS)
+	case "darwin":
+		switch runtime.GOARCH {
+		case "arm", "arm64":
+			t.Skipf("skipping on darwin/%s, mkdir returns EPERM", runtime.GOARCH)
+		}
 	}
 	RemoveAll("/_go_os_test")
-	err := MkdirAll("/_go_os_test/dir", 0777)
+	const dir = "/_go_os_test/dir"
+	err := MkdirAll(dir, 0777)
 	if err != nil {
 		pathErr, ok := err.(*PathError)
 		// common for users not to be able to write to /
-		if ok && pathErr.Err == syscall.EACCES {
-			return
+		if ok && (pathErr.Err == syscall.EACCES || isReadonlyError(pathErr.Err)) {
+			t.Skipf("could not create %v: %v", dir, err)
 		}
-		t.Fatalf(`MkdirAll "/_go_os_test/dir": %v`, err)
+		t.Fatalf(`MkdirAll "/_go_os_test/dir": %v, %s`, err, pathErr.Err)
 	}
 	RemoveAll("/_go_os_test")
 }
diff --git a/third_party/gofrontend/libgo/go/os/path_unix.go b/third_party/gofrontend/libgo/go/os/path_unix.go
index 0211107..36f8e61 100644
--- a/third_party/gofrontend/libgo/go/os/path_unix.go
+++ b/third_party/gofrontend/libgo/go/os/path_unix.go
@@ -11,7 +11,7 @@
 	PathListSeparator = ':' // OS-specific path list separator
 )
 
-// IsPathSeparator returns true if c is a directory separator character.
+// IsPathSeparator reports whether c is a directory separator character.
 func IsPathSeparator(c uint8) bool {
 	return PathSeparator == c
 }
diff --git a/third_party/gofrontend/libgo/go/os/path_windows.go b/third_party/gofrontend/libgo/go/os/path_windows.go
index 61f2ca5..c96f137 100644
--- a/third_party/gofrontend/libgo/go/os/path_windows.go
+++ b/third_party/gofrontend/libgo/go/os/path_windows.go
@@ -9,7 +9,7 @@
 	PathListSeparator = ';'  // OS-specific path list separator
 )
 
-// IsPathSeparator returns true if c is a directory separator character.
+// IsPathSeparator reports whether c is a directory separator character.
 func IsPathSeparator(c uint8) bool {
 	// NOTE: Windows accept / as path separator.
 	return c == '\\' || c == '/'
diff --git a/third_party/gofrontend/libgo/go/os/proc.go b/third_party/gofrontend/libgo/go/os/proc.go
index 774f099..33a8b26 100644
--- a/third_party/gofrontend/libgo/go/os/proc.go
+++ b/third_party/gofrontend/libgo/go/os/proc.go
@@ -44,6 +44,14 @@
 
 // Exit causes the current program to exit with the given status code.
 // Conventionally, code zero indicates success, non-zero an error.
-// The program terminates immediately; deferred functions are
-// not run.
-func Exit(code int) { syscall.Exit(code) }
+// The program terminates immediately; deferred functions are not run.
+func Exit(code int) {
+	if code == 0 {
+		// Give race detector a chance to fail the program.
+		// Racy programs do not have the right to finish successfully.
+		runtime_beforeExit()
+	}
+	syscall.Exit(code)
+}
+
+func runtime_beforeExit() // implemented in runtime
diff --git a/third_party/gofrontend/libgo/go/os/signal/signal.go b/third_party/gofrontend/libgo/go/os/signal/signal.go
index 3004275..1625786 100644
--- a/third_party/gofrontend/libgo/go/os/signal/signal.go
+++ b/third_party/gofrontend/libgo/go/os/signal/signal.go
@@ -5,8 +5,6 @@
 // Package signal implements access to incoming signals.
 package signal
 
-// BUG(rsc): This package is not yet implemented on Plan 9.
-
 import (
 	"os"
 	"sync"
@@ -30,9 +28,55 @@
 	h.mask[sig/32] |= 1 << uint(sig&31)
 }
 
+func (h *handler) clear(sig int) {
+	h.mask[sig/32] &^= 1 << uint(sig&31)
+}
+
+// Stop relaying the signals, sigs, to any channels previously registered to
+// receive them and either reset the signal handlers to their original values
+// (action=disableSignal) or ignore the signals (action=ignoreSignal).
+func cancel(sigs []os.Signal, action func(int)) {
+	handlers.Lock()
+	defer handlers.Unlock()
+
+	remove := func(n int) {
+		var zerohandler handler
+
+		for c, h := range handlers.m {
+			if h.want(n) {
+				handlers.ref[n]--
+				h.clear(n)
+				if h.mask == zerohandler.mask {
+					delete(handlers.m, c)
+				}
+			}
+		}
+
+		action(n)
+	}
+
+	if len(sigs) == 0 {
+		for n := 0; n < numSig; n++ {
+			remove(n)
+		}
+	} else {
+		for _, s := range sigs {
+			remove(signum(s))
+		}
+	}
+}
+
+// Ignore causes the provided signals to be ignored. If they are received by
+// the program, nothing will happen. Ignore undoes the effect of any prior
+// calls to Notify for the provided signals.
+// If no signals are provided, all incoming signals will be ignored.
+func Ignore(sig ...os.Signal) {
+	cancel(sig, ignoreSignal)
+}
+
 // Notify causes package signal to relay incoming signals to c.
-// If no signals are listed, all incoming signals will be relayed to c.
-// Otherwise, just the listed signals will.
+// If no signals are provided, all incoming signals will be relayed to c.
+// Otherwise, just the provided signals will.
 //
 // Package signal will not block sending to c: the caller must ensure
 // that c has sufficient buffer space to keep up with the expected
@@ -87,6 +131,13 @@
 	}
 }
 
+// Reset undoes the effect of any prior calls to Notify for the provided
+// signals.
+// If no signals are provided, all signal handlers will be reset.
+func Reset(sig ...os.Signal) {
+	cancel(sig, disableSignal)
+}
+
 // Stop causes package signal to stop relaying incoming signals to c.
 // It undoes the effect of all prior calls to Notify using c.
 // When Stop returns, it is guaranteed that c will receive no more signals.
diff --git a/third_party/gofrontend/libgo/go/os/signal/signal_plan9.go b/third_party/gofrontend/libgo/go/os/signal/signal_plan9.go
new file mode 100644
index 0000000..b065ae5
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/os/signal/signal_plan9.go
@@ -0,0 +1,60 @@
+// Copyright 2012 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 signal
+
+import (
+	"os"
+	"syscall"
+)
+
+var sigtab = make(map[os.Signal]int)
+
+// In sig.s; jumps to runtime.
+func signal_disable(uint32)
+func signal_enable(uint32)
+func signal_ignore(uint32)
+func signal_recv() string
+
+func init() {
+	signal_enable(0) // first call - initialize
+	go loop()
+}
+
+func loop() {
+	for {
+		process(syscall.Note(signal_recv()))
+	}
+}
+
+const numSig = 256
+
+func signum(sig os.Signal) int {
+	switch sig := sig.(type) {
+	case syscall.Note:
+		n, ok := sigtab[sig]
+		if !ok {
+			n = len(sigtab) + 1
+			if n > numSig {
+				return -1
+			}
+			sigtab[sig] = n
+		}
+		return n
+	default:
+		return -1
+	}
+}
+
+func enableSignal(sig int) {
+	signal_enable(uint32(sig))
+}
+
+func disableSignal(sig int) {
+	signal_disable(uint32(sig))
+}
+
+func ignoreSignal(sig int) {
+	signal_ignore(uint32(sig))
+}
diff --git a/third_party/gofrontend/libgo/go/os/signal/signal_plan9_test.go b/third_party/gofrontend/libgo/go/os/signal/signal_plan9_test.go
new file mode 100644
index 0000000..10bfdc3
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/os/signal/signal_plan9_test.go
@@ -0,0 +1,181 @@
+// Copyright 2009 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 signal
+
+import (
+	"os"
+	"runtime"
+	"syscall"
+	"testing"
+	"time"
+)
+
+func waitSig(t *testing.T, c <-chan os.Signal, sig os.Signal) {
+	select {
+	case s := <-c:
+		if s != sig {
+			t.Fatalf("signal was %v, want %v", s, sig)
+		}
+	case <-time.After(1 * time.Second):
+		t.Fatalf("timeout waiting for %v", sig)
+	}
+}
+
+// Test that basic signal handling works.
+func TestSignal(t *testing.T) {
+	// Ask for hangup
+	c := make(chan os.Signal, 1)
+	Notify(c, syscall.Note("hangup"))
+	defer Stop(c)
+
+	// Send this process a hangup
+	t.Logf("hangup...")
+	postNote(syscall.Getpid(), "hangup")
+	waitSig(t, c, syscall.Note("hangup"))
+
+	// Ask for everything we can get.
+	c1 := make(chan os.Signal, 1)
+	Notify(c1)
+
+	// Send this process an alarm
+	t.Logf("alarm...")
+	postNote(syscall.Getpid(), "alarm")
+	waitSig(t, c1, syscall.Note("alarm"))
+
+	// Send two more hangups, to make sure that
+	// they get delivered on c1 and that not reading
+	// from c does not block everything.
+	t.Logf("hangup...")
+	postNote(syscall.Getpid(), "hangup")
+	waitSig(t, c1, syscall.Note("hangup"))
+	t.Logf("hangup...")
+	postNote(syscall.Getpid(), "hangup")
+	waitSig(t, c1, syscall.Note("hangup"))
+
+	// The first SIGHUP should be waiting for us on c.
+	waitSig(t, c, syscall.Note("hangup"))
+}
+
+func TestStress(t *testing.T) {
+	dur := 3 * time.Second
+	if testing.Short() {
+		dur = 100 * time.Millisecond
+	}
+	defer runtime.GOMAXPROCS(runtime.GOMAXPROCS(4))
+	done := make(chan bool)
+	finished := make(chan bool)
+	go func() {
+		sig := make(chan os.Signal, 1)
+		Notify(sig, syscall.Note("alarm"))
+		defer Stop(sig)
+	Loop:
+		for {
+			select {
+			case <-sig:
+			case <-done:
+				break Loop
+			}
+		}
+		finished <- true
+	}()
+	go func() {
+	Loop:
+		for {
+			select {
+			case <-done:
+				break Loop
+			default:
+				postNote(syscall.Getpid(), "alarm")
+				runtime.Gosched()
+			}
+		}
+		finished <- true
+	}()
+	time.Sleep(dur)
+	close(done)
+	<-finished
+	<-finished
+	// When run with 'go test -cpu=1,2,4' alarm from this test can slip
+	// into subsequent TestSignal() causing failure.
+	// Sleep for a while to reduce the possibility of the failure.
+	time.Sleep(10 * time.Millisecond)
+}
+
+// Test that Stop cancels the channel's registrations.
+func TestStop(t *testing.T) {
+	if testing.Short() {
+		t.Skip("skipping in short mode")
+	}
+	sigs := []string{
+		"alarm",
+		"hangup",
+	}
+
+	for _, sig := range sigs {
+		// Send the signal.
+		// If it's alarm, we should not see it.
+		// If it's hangup, maybe we'll die. Let the flag tell us what to do.
+		if sig != "hangup" {
+			postNote(syscall.Getpid(), sig)
+		}
+		time.Sleep(100 * time.Millisecond)
+
+		// Ask for signal
+		c := make(chan os.Signal, 1)
+		Notify(c, syscall.Note(sig))
+		defer Stop(c)
+
+		// Send this process that signal
+		postNote(syscall.Getpid(), sig)
+		waitSig(t, c, syscall.Note(sig))
+
+		Stop(c)
+		select {
+		case s := <-c:
+			t.Fatalf("unexpected signal %v", s)
+		case <-time.After(100 * time.Millisecond):
+			// nothing to read - good
+		}
+
+		// Send the signal.
+		// If it's alarm, we should not see it.
+		// If it's hangup, maybe we'll die. Let the flag tell us what to do.
+		if sig != "hangup" {
+			postNote(syscall.Getpid(), sig)
+		}
+
+		select {
+		case s := <-c:
+			t.Fatalf("unexpected signal %v", s)
+		case <-time.After(100 * time.Millisecond):
+			// nothing to read - good
+		}
+	}
+}
+
+func itoa(val int) string {
+	if val < 0 {
+		return "-" + itoa(-val)
+	}
+	var buf [32]byte // big enough for int64
+	i := len(buf) - 1
+	for val >= 10 {
+		buf[i] = byte(val%10 + '0')
+		i--
+		val /= 10
+	}
+	buf[i] = byte(val + '0')
+	return string(buf[i:])
+}
+
+func postNote(pid int, note string) error {
+	f, err := os.OpenFile("/proc/"+itoa(pid)+"/note", os.O_WRONLY, 0)
+	if err != nil {
+		return err
+	}
+	defer f.Close()
+	_, err = f.Write([]byte(note))
+	return err
+}
diff --git a/third_party/gofrontend/libgo/go/os/signal/signal_stub.go b/third_party/gofrontend/libgo/go/os/signal/signal_stub.go
deleted file mode 100644
index d0a6935..0000000
--- a/third_party/gofrontend/libgo/go/os/signal/signal_stub.go
+++ /dev/null
@@ -1,17 +0,0 @@
-// Copyright 2012 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 plan9
-
-package signal
-
-import "os"
-
-const numSig = 0
-
-func signum(sig os.Signal) int { return -1 }
-
-func disableSignal(int) {}
-
-func enableSignal(int) {}
diff --git a/third_party/gofrontend/libgo/go/os/signal/signal_test.go b/third_party/gofrontend/libgo/go/os/signal/signal_test.go
index 22337a7..a71633c 100644
--- a/third_party/gofrontend/libgo/go/os/signal/signal_test.go
+++ b/third_party/gofrontend/libgo/go/os/signal/signal_test.go
@@ -109,6 +109,72 @@
 	time.Sleep(10 * time.Millisecond)
 }
 
+func testCancel(t *testing.T, ignore bool) {
+	// Send SIGWINCH. By default this signal should be ignored.
+	syscall.Kill(syscall.Getpid(), syscall.SIGWINCH)
+	time.Sleep(100 * time.Millisecond)
+
+	// Ask to be notified on c1 when a SIGWINCH is received.
+	c1 := make(chan os.Signal, 1)
+	Notify(c1, syscall.SIGWINCH)
+	defer Stop(c1)
+
+	// Ask to be notified on c2 when a SIGHUP is received.
+	c2 := make(chan os.Signal, 1)
+	Notify(c2, syscall.SIGHUP)
+	defer Stop(c2)
+
+	// Send this process a SIGWINCH and wait for notification on c1.
+	syscall.Kill(syscall.Getpid(), syscall.SIGWINCH)
+	waitSig(t, c1, syscall.SIGWINCH)
+
+	// Send this process a SIGHUP and wait for notification on c2.
+	syscall.Kill(syscall.Getpid(), syscall.SIGHUP)
+	waitSig(t, c2, syscall.SIGHUP)
+
+	// Ignore, or reset the signal handlers for, SIGWINCH and SIGHUP.
+	if ignore {
+		Ignore(syscall.SIGWINCH, syscall.SIGHUP)
+	} else {
+		Reset(syscall.SIGWINCH, syscall.SIGHUP)
+	}
+
+	// Send this process a SIGWINCH. It should be ignored.
+	syscall.Kill(syscall.Getpid(), syscall.SIGWINCH)
+
+	// If ignoring, Send this process a SIGHUP. It should be ignored.
+	if ignore {
+		syscall.Kill(syscall.Getpid(), syscall.SIGHUP)
+	}
+
+	select {
+	case s := <-c1:
+		t.Fatalf("unexpected signal %v", s)
+	case <-time.After(100 * time.Millisecond):
+		// nothing to read - good
+	}
+
+	select {
+	case s := <-c2:
+		t.Fatalf("unexpected signal %v", s)
+	case <-time.After(100 * time.Millisecond):
+		// nothing to read - good
+	}
+
+	// Reset the signal handlers for all signals.
+	Reset()
+}
+
+// Test that Reset cancels registration for listed signals on all channels.
+func TestReset(t *testing.T) {
+	testCancel(t, false)
+}
+
+// Test that Ignore cancels registration for listed signals on all channels.
+func TestIgnore(t *testing.T) {
+	testCancel(t, true)
+}
+
 var sendUncaughtSighup = flag.Int("send_uncaught_sighup", 0, "send uncaught SIGHUP during TestStop")
 
 // Test that Stop cancels the channel's registrations.
diff --git a/third_party/gofrontend/libgo/go/os/signal/signal_unix.go b/third_party/gofrontend/libgo/go/os/signal/signal_unix.go
index 94b8ab3..1bdf1d7 100644
--- a/third_party/gofrontend/libgo/go/os/signal/signal_unix.go
+++ b/third_party/gofrontend/libgo/go/os/signal/signal_unix.go
@@ -14,6 +14,7 @@
 // In assembly.
 func signal_disable(uint32)
 func signal_enable(uint32)
+func signal_ignore(uint32)
 func signal_recv() uint32
 
 func loop() {
@@ -51,3 +52,7 @@
 func disableSignal(sig int) {
 	signal_disable(uint32(sig))
 }
+
+func ignoreSignal(sig int) {
+	signal_ignore(uint32(sig))
+}
diff --git a/third_party/gofrontend/libgo/go/os/stat_plan9.go b/third_party/gofrontend/libgo/go/os/stat_plan9.go
index 25c9a8c..fa4bd83 100644
--- a/third_party/gofrontend/libgo/go/os/stat_plan9.go
+++ b/third_party/gofrontend/libgo/go/os/stat_plan9.go
@@ -9,6 +9,8 @@
 	"time"
 )
 
+const _BIT16SZ = 2
+
 func sameFile(fs1, fs2 *fileStat) bool {
 	a := fs1.sys.(*syscall.Dir)
 	b := fs2.sys.(*syscall.Dir)
@@ -41,16 +43,14 @@
 // arg is an open *File or a path string.
 func dirstat(arg interface{}) (*syscall.Dir, error) {
 	var name string
+	var err error
 
-	// This is big enough for most stat messages
-	// and rounded to a multiple of 128 bytes.
-	size := (syscall.STATFIXLEN + 16*4 + 128) &^ 128
+	size := syscall.STATFIXLEN + 16*4
 
 	for i := 0; i < 2; i++ {
-		buf := make([]byte, size)
+		buf := make([]byte, _BIT16SZ+size)
 
 		var n int
-		var err error
 		switch a := arg.(type) {
 		case *File:
 			name = a.name
@@ -61,34 +61,36 @@
 		default:
 			panic("phase error in dirstat")
 		}
-		if err != nil {
+
+		if n < _BIT16SZ {
 			return nil, &PathError{"stat", name, err}
 		}
-		if n < syscall.STATFIXLEN {
-			return nil, &PathError{"stat", name, syscall.ErrShortStat}
-		}
 
 		// Pull the real size out of the stat message.
 		size = int(uint16(buf[0]) | uint16(buf[1])<<8)
 
 		// If the stat message is larger than our buffer we will
 		// go around the loop and allocate one that is big enough.
-		if size > n {
-			continue
+		if size <= n {
+			d, err := syscall.UnmarshalDir(buf[:n])
+			if err != nil {
+				return nil, &PathError{"stat", name, err}
+			}
+			return d, nil
 		}
 
-		d, err := syscall.UnmarshalDir(buf[:n])
-		if err != nil {
-			return nil, &PathError{"stat", name, err}
-		}
-		return d, nil
 	}
-	return nil, &PathError{"stat", name, syscall.ErrBadStat}
+
+	if err == nil {
+		err = syscall.ErrBadStat
+	}
+
+	return nil, &PathError{"stat", name, err}
 }
 
 // Stat returns a FileInfo describing the named file.
 // If there is an error, it will be of type *PathError.
-func Stat(name string) (fi FileInfo, err error) {
+func Stat(name string) (FileInfo, error) {
 	d, err := dirstat(name)
 	if err != nil {
 		return nil, err
@@ -100,7 +102,7 @@
 // If the file is a symbolic link, the returned FileInfo
 // describes the symbolic link.  Lstat makes no attempt to follow the link.
 // If there is an error, it will be of type *PathError.
-func Lstat(name string) (fi FileInfo, err error) {
+func Lstat(name string) (FileInfo, error) {
 	return Stat(name)
 }
 
diff --git a/third_party/gofrontend/libgo/go/os/sticky_bsd.go b/third_party/gofrontend/libgo/go/os/sticky_bsd.go
new file mode 100644
index 0000000..6b54c75
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/os/sticky_bsd.go
@@ -0,0 +1,11 @@
+// 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.
+
+// +build darwin dragonfly freebsd netbsd openbsd solaris
+
+package os
+
+// According to sticky(8), neither open(2) nor mkdir(2) will create
+// a file with the sticky bit set.
+const supportsCreateWithStickyBit = false
diff --git a/third_party/gofrontend/libgo/go/os/sticky_notbsd.go b/third_party/gofrontend/libgo/go/os/sticky_notbsd.go
new file mode 100644
index 0000000..834e79b
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/os/sticky_notbsd.go
@@ -0,0 +1,14 @@
+// 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.
+
+// +build !darwin
+// +build !dragonfly
+// +build !freebsd
+// +build !netbsd
+// +build !openbsd
+// +build !solaris
+
+package os
+
+const supportsCreateWithStickyBit = true
diff --git a/third_party/gofrontend/libgo/go/os/str.go b/third_party/gofrontend/libgo/go/os/str.go
index e3606b6..d3e03e9 100644
--- a/third_party/gofrontend/libgo/go/os/str.go
+++ b/third_party/gofrontend/libgo/go/os/str.go
@@ -2,21 +2,32 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-// +build plan9
+// Simple converions to avoid depending on strconv.
 
 package os
 
-func itoa(val int) string { // do it here rather than with fmt to avoid dependency
+// Convert integer to decimal string
+func itoa(val int) string {
 	if val < 0 {
-		return "-" + itoa(-val)
+		return "-" + uitoa(uint(-val))
 	}
-	var buf [32]byte // big enough for int64
+	return uitoa(uint(val))
+}
+
+// Convert unsigned integer to decimal string
+func uitoa(val uint) string {
+	if val == 0 { // avoid string allocation
+		return "0"
+	}
+	var buf [20]byte // big enough for 64bit value base 10
 	i := len(buf) - 1
 	for val >= 10 {
-		buf[i] = byte(val%10 + '0')
+		q := val / 10
+		buf[i] = byte('0' + val - q*10)
 		i--
-		val /= 10
+		val = q
 	}
-	buf[i] = byte(val + '0')
+	// val < 10
+	buf[i] = byte('0' + val)
 	return string(buf[i:])
 }
diff --git a/third_party/gofrontend/libgo/go/os/types.go b/third_party/gofrontend/libgo/go/os/types.go
index 473d431..9d6f8e1 100644
--- a/third_party/gofrontend/libgo/go/os/types.go
+++ b/third_party/gofrontend/libgo/go/os/types.go
@@ -53,7 +53,7 @@
 	// Mask for the type bits. For regular files, none will be set.
 	ModeType = ModeDir | ModeSymlink | ModeNamedPipe | ModeSocket | ModeDevice
 
-	ModePerm FileMode = 0777 // permission bits
+	ModePerm FileMode = 0777 // Unix permission bits
 )
 
 func (m FileMode) String() string {
diff --git a/third_party/gofrontend/libgo/go/os/user/lookup_unix.go b/third_party/gofrontend/libgo/go/os/user/lookup_unix.go
index 64f4576..bebb9e8 100644
--- a/third_party/gofrontend/libgo/go/os/user/lookup_unix.go
+++ b/third_party/gofrontend/libgo/go/os/user/lookup_unix.go
@@ -16,6 +16,7 @@
 )
 
 /*
+#cgo solaris CFLAGS: -D_POSIX_PTHREAD_SEMANTICS
 #include <unistd.h>
 #include <sys/types.h>
 #include <pwd.h>
@@ -23,7 +24,12 @@
 
 static int mygetpwuid_r(int uid, struct passwd *pwd,
 	char *buf, size_t buflen, struct passwd **result) {
- return getpwuid_r(uid, pwd, buf, buflen, result);
+	return getpwuid_r(uid, pwd, buf, buflen, result);
+}
+
+static int mygetpwnam_r(const char *name, struct passwd *pwd,
+	char *buf, size_t buflen, struct passwd **result) {
+	return getpwnam_r(name, pwd, buf, buflen, result);
 }
 */
 
@@ -62,9 +68,9 @@
 	const bufSize = 1024
 	buf := make([]byte, bufSize)
 	if lookupByName {
-		p := syscall.StringBytePtr(username)
+		nameC := syscall.StringBytePtr(username)
 		syscall.Entersyscall()
-		rv := libc_getpwnam_r(p,
+		rv := libc_getpwnam_r(nameC,
 			&pwd,
 			&buf[0],
 			bufSize,
diff --git a/third_party/gofrontend/libgo/go/path/filepath/example_unix_test.go b/third_party/gofrontend/libgo/go/path/filepath/example_unix_test.go
index f3fe076..27d85d1 100644
--- a/third_party/gofrontend/libgo/go/path/filepath/example_unix_test.go
+++ b/third_party/gofrontend/libgo/go/path/filepath/example_unix_test.go
@@ -37,3 +37,31 @@
 	// "/b/c": "../b/c" <nil>
 	// "./b/c": "" Rel: can't make b/c relative to /a
 }
+
+func ExampleSplit() {
+	paths := []string{
+		"/home/arnie/amelia.jpg",
+		"/mnt/photos/",
+		"rabbit.jpg",
+		"/usr/local//go",
+	}
+	fmt.Println("On Unix:")
+	for _, p := range paths {
+		dir, file := filepath.Split(p)
+		fmt.Printf("input: %q\n\tdir: %q\n\tfile: %q\n", p, dir, file)
+	}
+	// Output:
+	// On Unix:
+	// input: "/home/arnie/amelia.jpg"
+	// 	dir: "/home/arnie/"
+	// 	file: "amelia.jpg"
+	// input: "/mnt/photos/"
+	// 	dir: "/mnt/photos/"
+	// 	file: ""
+	// input: "rabbit.jpg"
+	// 	dir: ""
+	// 	file: "rabbit.jpg"
+	// input: "/usr/local//go"
+	// 	dir: "/usr/local//"
+	// 	file: "go"
+}
diff --git a/third_party/gofrontend/libgo/go/path/filepath/match.go b/third_party/gofrontend/libgo/go/path/filepath/match.go
index ecc07aa..89f16de 100644
--- a/third_party/gofrontend/libgo/go/path/filepath/match.go
+++ b/third_party/gofrontend/libgo/go/path/filepath/match.go
@@ -16,7 +16,7 @@
 // ErrBadPattern indicates a globbing pattern was malformed.
 var ErrBadPattern = errors.New("syntax error in pattern")
 
-// Match returns true if name matches the shell file name pattern.
+// Match reports whether name matches the shell file name pattern.
 // The pattern syntax is:
 //
 //	pattern:
@@ -301,7 +301,7 @@
 	return
 }
 
-// hasMeta returns true if path contains any of the magic characters
+// hasMeta reports whether path contains any of the magic characters
 // recognized by Match.
 func hasMeta(path string) bool {
 	// TODO(niemeyer): Should other magic characters be added here?
diff --git a/third_party/gofrontend/libgo/go/path/filepath/path.go b/third_party/gofrontend/libgo/go/path/filepath/path.go
index d37fc9d..5dc5cfd 100644
--- a/third_party/gofrontend/libgo/go/path/filepath/path.go
+++ b/third_party/gofrontend/libgo/go/path/filepath/path.go
@@ -4,6 +4,9 @@
 
 // Package filepath implements utility routines for manipulating filename paths
 // in a way compatible with the target operating system-defined file paths.
+//
+// Functions in this package replace any occurrences of the slash ('/') character
+// with os.PathSeparator when returning paths unless otherwise specified.
 package filepath
 
 import (
@@ -174,7 +177,8 @@
 
 // SplitList splits a list of paths joined by the OS-specific ListSeparator,
 // usually found in PATH or GOPATH environment variables.
-// Unlike strings.Split, SplitList returns an empty slice when passed an empty string.
+// Unlike strings.Split, SplitList returns an empty slice when passed an empty
+// string. SplitList does not replace slash characters in the returned paths.
 func SplitList(path string) []string {
 	return splitList(path)
 }
@@ -196,13 +200,10 @@
 // Join joins any number of path elements into a single path, adding
 // a Separator if necessary. The result is Cleaned, in particular
 // all empty strings are ignored.
+// On Windows, the result is a UNC path if and only if the first path
+// element is a UNC path.
 func Join(elem ...string) string {
-	for i, e := range elem {
-		if e != "" {
-			return Clean(strings.Join(elem[i:], string(Separator)))
-		}
-	}
-	return ""
+	return join(elem)
 }
 
 // Ext returns the file name extension used by path.
@@ -334,10 +335,11 @@
 // If there was a problem walking to the file or directory named by path, the
 // incoming error will describe the problem and the function can decide how
 // to handle that error (and Walk will not descend into that directory). If
-// an error is returned, processing stops. The sole exception is that if path
-// is a directory and the function returns the special value SkipDir, the
-// contents of the directory are skipped and processing continues as usual on
-// the next file.
+// an error is returned, processing stops. The sole exception is when the function
+// returns the special value SkipDir. If the function returns SkipDir when invoked
+// on a directory, Walk skips the directory's contents entirely.
+// If the function returns SkipDir when invoked on a non-directory file,
+// Walk skips the remaining files in the containing directory.
 type WalkFunc func(path string, info os.FileInfo, err error) error
 
 var lstat = os.Lstat // for testing
@@ -456,9 +458,9 @@
 }
 
 // VolumeName returns leading volume name.
-// Given "C:\foo\bar" it returns "C:" under windows.
+// Given "C:\foo\bar" it returns "C:" on Windows.
 // Given "\\host\share\foo" it returns "\\host\share".
 // On other platforms it returns "".
-func VolumeName(path string) (v string) {
+func VolumeName(path string) string {
 	return path[:volumeNameLen(path)]
 }
diff --git a/third_party/gofrontend/libgo/go/path/filepath/path_plan9.go b/third_party/gofrontend/libgo/go/path/filepath/path_plan9.go
index ee8912d..962774e 100644
--- a/third_party/gofrontend/libgo/go/path/filepath/path_plan9.go
+++ b/third_party/gofrontend/libgo/go/path/filepath/path_plan9.go
@@ -6,7 +6,7 @@
 
 import "strings"
 
-// IsAbs returns true if the path is absolute.
+// IsAbs reports whether the path is absolute.
 func IsAbs(path string) bool {
 	return strings.HasPrefix(path, "/") || strings.HasPrefix(path, "#")
 }
@@ -32,3 +32,13 @@
 func abs(path string) (string, error) {
 	return unixAbs(path)
 }
+
+func join(elem []string) string {
+	// If there's a bug here, fix the logic in ./path_unix.go too.
+	for i, e := range elem {
+		if e != "" {
+			return Clean(strings.Join(elem[i:], string(Separator)))
+		}
+	}
+	return ""
+}
diff --git a/third_party/gofrontend/libgo/go/path/filepath/path_test.go b/third_party/gofrontend/libgo/go/path/filepath/path_test.go
index c3ee0cb..b2536cb 100644
--- a/third_party/gofrontend/libgo/go/path/filepath/path_test.go
+++ b/third_party/gofrontend/libgo/go/path/filepath/path_test.go
@@ -245,6 +245,7 @@
 
 	// one parameter
 	{[]string{""}, ""},
+	{[]string{"/"}, "/"},
 	{[]string{"a"}, "a"},
 
 	// two parameters
@@ -252,10 +253,16 @@
 	{[]string{"a", ""}, "a"},
 	{[]string{"", "b"}, "b"},
 	{[]string{"/", "a"}, "/a"},
+	{[]string{"/", "a/b"}, "/a/b"},
 	{[]string{"/", ""}, "/"},
+	{[]string{"//", "a"}, "/a"},
+	{[]string{"/a", "b"}, "/a/b"},
 	{[]string{"a/", "b"}, "a/b"},
 	{[]string{"a/", ""}, "a"},
 	{[]string{"", ""}, ""},
+
+	// three parameters
+	{[]string{"/", "a", "b"}, "/a/b"},
 }
 
 var winjointests = []JoinTest{
@@ -265,13 +272,17 @@
 	{[]string{`C:\`, `Windows`}, `C:\Windows`},
 	{[]string{`C:`, `Windows`}, `C:\Windows`},
 	{[]string{`\\host\share`, `foo`}, `\\host\share\foo`},
+	{[]string{`\\host\share\foo`}, `\\host\share\foo`},
 	{[]string{`//host/share`, `foo/bar`}, `\\host\share\foo\bar`},
-}
-
-// join takes a []string and passes it to Join.
-func join(elem []string, args ...string) string {
-	args = elem
-	return filepath.Join(args...)
+	{[]string{`\`}, `\`},
+	{[]string{`\`, ``}, `\`},
+	{[]string{`\`, `a`}, `\a`},
+	{[]string{`\\`, `a`}, `\a`},
+	{[]string{`\`, `a`, `b`}, `\a\b`},
+	{[]string{`\\`, `a`, `b`}, `\a\b`},
+	{[]string{`\`, `\\a\b`, `c`}, `\a\b\c`},
+	{[]string{`\\a`, `b`, `c`}, `\a\b\c`},
+	{[]string{`\\a\`, `b`, `c`}, `\a\b\c`},
 }
 
 func TestJoin(t *testing.T) {
@@ -279,8 +290,9 @@
 		jointests = append(jointests, winjointests...)
 	}
 	for _, test := range jointests {
-		if p := join(test.elem); p != filepath.FromSlash(test.path) {
-			t.Errorf("join(%q) = %q, want %q", test.elem, p, test.path)
+		expected := filepath.FromSlash(test.path)
+		if p := filepath.Join(test.elem...); p != expected {
+			t.Errorf("join(%q) = %q, want %q", test.elem, p, expected)
 		}
 	}
 }
@@ -390,7 +402,34 @@
 	return nil
 }
 
+func chtmpdir(t *testing.T) (restore func()) {
+	oldwd, err := os.Getwd()
+	if err != nil {
+		t.Fatal("chtmpdir: %v", err)
+	}
+	d, err := ioutil.TempDir("", "test")
+	if err != nil {
+		t.Fatal("chtmpdir: %v", err)
+	}
+	if err := os.Chdir(d); err != nil {
+		t.Fatal("chtmpdir: %v", err)
+	}
+	return func() {
+		if err := os.Chdir(oldwd); err != nil {
+			t.Fatal("chtmpdir: %v", err)
+		}
+		os.RemoveAll(d)
+	}
+}
+
 func TestWalk(t *testing.T) {
+	if runtime.GOOS == "darwin" {
+		switch runtime.GOARCH {
+		case "arm", "arm64":
+			restore := chtmpdir(t)
+			defer restore()
+		}
+	}
 	makeTree(t)
 	errors := make([]error, 0, 10)
 	clear := true
@@ -474,6 +513,35 @@
 	}
 }
 
+func TestWalkSkipDirOnFile(t *testing.T) {
+	td, err := ioutil.TempDir("", "walktest")
+	if err != nil {
+		t.Fatal(err)
+	}
+	defer os.RemoveAll(td)
+
+	if err := os.MkdirAll(filepath.Join(td, "dir"), 0755); err != nil {
+		t.Fatal(err)
+	}
+	touch(t, filepath.Join(td, "dir/foo1"))
+	touch(t, filepath.Join(td, "dir/foo2"))
+
+	sawFoo2 := false
+	filepath.Walk(td, func(path string, info os.FileInfo, err error) error {
+		if strings.HasSuffix(path, "foo2") {
+			sawFoo2 = true
+		}
+		if strings.HasSuffix(path, "foo1") {
+			return filepath.SkipDir
+		}
+		return nil
+	})
+
+	if sawFoo2 {
+		t.Errorf("SkipDir on file foo1 did not block processing of foo2")
+	}
+}
+
 func TestWalkFileError(t *testing.T) {
 	td, err := ioutil.TempDir("", "walktest")
 	if err != nil {
@@ -999,10 +1067,14 @@
 	}
 }
 
-/* This test does not work gccgo, since the sources are arranged
-   differently.
-
-func TestBug3486(t *testing.T) { // http://code.google.com/p/go/issues/detail?id=3486
+func TestBug3486(t *testing.T) { // https://golang.org/issue/3486
+	t.Skip("skipping test because gccgo sources are arranged differently.")
+	if runtime.GOOS == "darwin" {
+		switch runtime.GOARCH {
+		case "arm", "arm64":
+			t.Skipf("skipping on %s/%s", runtime.GOOS, runtime.GOARCH)
+		}
+	}
 	root, err := filepath.EvalSymlinks(runtime.GOROOT() + "/test")
 	if err != nil {
 		t.Fatal(err)
@@ -1032,5 +1104,3 @@
 		t.Fatalf("%q not seen", ken)
 	}
 }
-
-*/
diff --git a/third_party/gofrontend/libgo/go/path/filepath/path_unix.go b/third_party/gofrontend/libgo/go/path/filepath/path_unix.go
index 4e7d0d1..d241d78 100644
--- a/third_party/gofrontend/libgo/go/path/filepath/path_unix.go
+++ b/third_party/gofrontend/libgo/go/path/filepath/path_unix.go
@@ -8,7 +8,7 @@
 
 import "strings"
 
-// IsAbs returns true if the path is absolute.
+// IsAbs reports whether the path is absolute.
 func IsAbs(path string) bool {
 	return strings.HasPrefix(path, "/")
 }
@@ -34,3 +34,13 @@
 func abs(path string) (string, error) {
 	return unixAbs(path)
 }
+
+func join(elem []string) string {
+	// If there's a bug here, fix the logic in ./path_plan9.go too.
+	for i, e := range elem {
+		if e != "" {
+			return Clean(strings.Join(elem[i:], string(Separator)))
+		}
+	}
+	return ""
+}
diff --git a/third_party/gofrontend/libgo/go/path/filepath/path_windows.go b/third_party/gofrontend/libgo/go/path/filepath/path_windows.go
index ec50f6b..bcfe0a3 100644
--- a/third_party/gofrontend/libgo/go/path/filepath/path_windows.go
+++ b/third_party/gofrontend/libgo/go/path/filepath/path_windows.go
@@ -13,7 +13,7 @@
 	return c == '\\' || c == '/'
 }
 
-// IsAbs returns true if the path is absolute.
+// IsAbs reports whether the path is absolute.
 func IsAbs(path string) (b bool) {
 	l := volumeNameLen(path)
 	if l == 0 {
@@ -108,3 +108,40 @@
 func abs(path string) (string, error) {
 	return syscall.FullPath(path)
 }
+
+func join(elem []string) string {
+	for i, e := range elem {
+		if e != "" {
+			return joinNonEmpty(elem[i:])
+		}
+	}
+	return ""
+}
+
+// joinNonEmpty is like join, but it assumes that the first element is non-empty.
+func joinNonEmpty(elem []string) string {
+	// The following logic prevents Join from inadvertently creating a
+	// UNC path on Windows. Unless the first element is a UNC path, Join
+	// shouldn't create a UNC path. See golang.org/issue/9167.
+	p := Clean(strings.Join(elem, string(Separator)))
+	if !isUNC(p) {
+		return p
+	}
+	// p == UNC only allowed when the first element is a UNC path.
+	head := Clean(elem[0])
+	if isUNC(head) {
+		return p
+	}
+	// head + tail == UNC, but joining two non-UNC paths should not result
+	// in a UNC path. Undo creation of UNC path.
+	tail := Clean(strings.Join(elem[1:], string(Separator)))
+	if head[len(head)-1] == Separator {
+		return head + tail
+	}
+	return head + string(Separator) + tail
+}
+
+// isUNC reports whether path is a UNC path.
+func isUNC(path string) bool {
+	return volumeNameLen(path) > 2
+}
diff --git a/third_party/gofrontend/libgo/go/path/filepath/symlink_windows.go b/third_party/gofrontend/libgo/go/path/filepath/symlink_windows.go
index 327c2c8..4b38f6f 100644
--- a/third_party/gofrontend/libgo/go/path/filepath/symlink_windows.go
+++ b/third_party/gofrontend/libgo/go/path/filepath/symlink_windows.go
@@ -14,18 +14,17 @@
 		return "", err
 	}
 	b := p // GetShortPathName says we can reuse buffer
-	n, err := syscall.GetShortPathName(&p[0], &b[0], uint32(len(b)))
-	if err != nil {
-		return "", err
-	}
-	if n > uint32(len(b)) {
-		b = make([]uint16, n)
+	n := uint32(len(b))
+	for {
 		n, err = syscall.GetShortPathName(&p[0], &b[0], uint32(len(b)))
 		if err != nil {
 			return "", err
 		}
+		if n <= uint32(len(b)) {
+			return syscall.UTF16ToString(b[:n]), nil
+		}
+		b = make([]uint16, n)
 	}
-	return syscall.UTF16ToString(b), nil
 }
 
 func toLong(path string) (string, error) {
@@ -34,19 +33,17 @@
 		return "", err
 	}
 	b := p // GetLongPathName says we can reuse buffer
-	n, err := syscall.GetLongPathName(&p[0], &b[0], uint32(len(b)))
-	if err != nil {
-		return "", err
-	}
-	if n > uint32(len(b)) {
-		b = make([]uint16, n)
+	n := uint32(len(b))
+	for {
 		n, err = syscall.GetLongPathName(&p[0], &b[0], uint32(len(b)))
 		if err != nil {
 			return "", err
 		}
+		if n <= uint32(len(b)) {
+			return syscall.UTF16ToString(b[:n]), nil
+		}
+		b = make([]uint16, n)
 	}
-	b = b[:n]
-	return syscall.UTF16ToString(b), nil
 }
 
 func evalSymlinks(path string) (string, error) {
diff --git a/third_party/gofrontend/libgo/go/path/match.go b/third_party/gofrontend/libgo/go/path/match.go
index 8154bf6..75dd3b3 100644
--- a/third_party/gofrontend/libgo/go/path/match.go
+++ b/third_party/gofrontend/libgo/go/path/match.go
@@ -13,7 +13,7 @@
 // ErrBadPattern indicates a globbing pattern was malformed.
 var ErrBadPattern = errors.New("syntax error in pattern")
 
-// Match returns true if name matches the shell file name pattern.
+// Match reports whether name matches the shell file name pattern.
 // The pattern syntax is:
 //
 //	pattern:
diff --git a/third_party/gofrontend/libgo/go/path/path.go b/third_party/gofrontend/libgo/go/path/path.go
index 98a6d52..77f2185 100644
--- a/third_party/gofrontend/libgo/go/path/path.go
+++ b/third_party/gofrontend/libgo/go/path/path.go
@@ -134,7 +134,7 @@
 	return out.string()
 }
 
-// Split splits path immediately following the final slash.
+// Split splits path immediately following the final slash,
 // separating it into a directory and file name component.
 // If there is no slash path, Split returns an empty dir and
 // file set to path.
@@ -192,7 +192,7 @@
 	return path
 }
 
-// IsAbs returns true if the path is absolute.
+// IsAbs reports whether the path is absolute.
 func IsAbs(path string) bool {
 	return len(path) > 0 && path[0] == '/'
 }
diff --git a/third_party/gofrontend/libgo/go/reflect/all_test.go b/third_party/gofrontend/libgo/go/reflect/all_test.go
index bda8786..33ee9ed 100644
--- a/third_party/gofrontend/libgo/go/reflect/all_test.go
+++ b/third_party/gofrontend/libgo/go/reflect/all_test.go
@@ -15,6 +15,7 @@
 	. "reflect"
 	"runtime"
 	"sort"
+	"strconv"
 	"strings"
 	"sync"
 	"testing"
@@ -1052,6 +1053,11 @@
 		ok = cv.TrySend(ValueOf(6))
 		if !ok {
 			t.Errorf("TrySend on empty chan failed")
+			select {
+			case x := <-c:
+				t.Errorf("TrySend failed but it did send %d", x)
+			default:
+			}
 		} else {
 			if i = <-c; i != 6 {
 				t.Errorf("TrySend 6, recv %d", i)
@@ -1376,7 +1382,7 @@
 	for {
 		time.Sleep(1 * time.Second)
 		selectWatch.Lock()
-		if selectWatch.info != nil && time.Since(selectWatch.now) > 1*time.Second {
+		if selectWatch.info != nil && time.Since(selectWatch.now) > 10*time.Second {
 			fmt.Fprintf(os.Stderr, "TestSelect:\n%s blocked indefinitely\n", fmtSelect(selectWatch.info))
 			panic("select stuck")
 		}
@@ -1501,6 +1507,17 @@
 	}
 }
 
+func BenchmarkCall(b *testing.B) {
+	fv := ValueOf(func(a, b string) {})
+	b.ReportAllocs()
+	b.RunParallel(func(pb *testing.PB) {
+		args := []Value{ValueOf("a"), ValueOf("b")}
+		for pb.Next() {
+			fv.Call(args)
+		}
+	})
+}
+
 func TestMakeFunc(t *testing.T) {
 	f := dummy
 	fv := MakeFunc(TypeOf(f), func(in []Value) []Value { return in })
@@ -2726,6 +2743,8 @@
 	{`protobuf:"PB(1,2)"`, `rotobuf`, ``},
 	{`protobuf:"PB(1,2)" json:"name"`, `json`, `name`},
 	{`protobuf:"PB(1,2)" json:"name"`, `protobuf`, `PB(1,2)`},
+	{`k0:"values contain spaces" k1:"and\ttabs"`, "k0", "values contain spaces"},
+	{`k0:"values contain spaces" k1:"and\ttabs"`, "k1", "and\ttabs"},
 }
 
 func TestTagGet(t *testing.T) {
@@ -3377,26 +3396,243 @@
 }
 
 func TestArrayOf(t *testing.T) {
-	// TODO(rsc): Finish ArrayOf and enable-test.
-	t.Skip("ArrayOf is not finished (and not exported)")
-
 	// check construction and use of type not in binary
-	type T int
-	at := ArrayOf(10, TypeOf(T(1)))
-	v := New(at).Elem()
-	for i := 0; i < v.Len(); i++ {
-		v.Index(i).Set(ValueOf(T(i)))
-	}
-	s := fmt.Sprint(v.Interface())
-	want := "[0 1 2 3 4 5 6 7 8 9]"
-	if s != want {
-		t.Errorf("constructed array = %s, want %s", s, want)
+	for _, table := range []struct {
+		n          int
+		value      func(i int) interface{}
+		comparable bool
+		want       string
+	}{
+		{
+			n:          0,
+			value:      func(i int) interface{} { type Tint int; return Tint(i) },
+			comparable: true,
+			want:       "[]",
+		},
+		{
+			n:          10,
+			value:      func(i int) interface{} { type Tint int; return Tint(i) },
+			comparable: true,
+			want:       "[0 1 2 3 4 5 6 7 8 9]",
+		},
+		{
+			n:          10,
+			value:      func(i int) interface{} { type Tfloat float64; return Tfloat(i) },
+			comparable: true,
+			want:       "[0 1 2 3 4 5 6 7 8 9]",
+		},
+		{
+			n:          10,
+			value:      func(i int) interface{} { type Tstring string; return Tstring(strconv.Itoa(i)) },
+			comparable: true,
+			want:       "[0 1 2 3 4 5 6 7 8 9]",
+		},
+		{
+			n:          10,
+			value:      func(i int) interface{} { type Tstruct struct{ V int }; return Tstruct{i} },
+			comparable: true,
+			want:       "[{0} {1} {2} {3} {4} {5} {6} {7} {8} {9}]",
+		},
+		{
+			n:          10,
+			value:      func(i int) interface{} { type Tint int; return []Tint{Tint(i)} },
+			comparable: false,
+			want:       "[[0] [1] [2] [3] [4] [5] [6] [7] [8] [9]]",
+		},
+		{
+			n:          10,
+			value:      func(i int) interface{} { type Tint int; return [1]Tint{Tint(i)} },
+			comparable: true,
+			want:       "[[0] [1] [2] [3] [4] [5] [6] [7] [8] [9]]",
+		},
+		{
+			n:          10,
+			value:      func(i int) interface{} { type Tstruct struct{ V [1]int }; return Tstruct{[1]int{i}} },
+			comparable: true,
+			want:       "[{[0]} {[1]} {[2]} {[3]} {[4]} {[5]} {[6]} {[7]} {[8]} {[9]}]",
+		},
+		{
+			n:          10,
+			value:      func(i int) interface{} { type Tstruct struct{ V []int }; return Tstruct{[]int{i}} },
+			comparable: false,
+			want:       "[{[0]} {[1]} {[2]} {[3]} {[4]} {[5]} {[6]} {[7]} {[8]} {[9]}]",
+		},
+		{
+			n:          10,
+			value:      func(i int) interface{} { type TstructUV struct{ U, V int }; return TstructUV{i, i} },
+			comparable: true,
+			want:       "[{0 0} {1 1} {2 2} {3 3} {4 4} {5 5} {6 6} {7 7} {8 8} {9 9}]",
+		},
+		{
+			n: 10,
+			value: func(i int) interface{} {
+				type TstructUV struct {
+					U int
+					V float64
+				}
+				return TstructUV{i, float64(i)}
+			},
+			comparable: true,
+			want:       "[{0 0} {1 1} {2 2} {3 3} {4 4} {5 5} {6 6} {7 7} {8 8} {9 9}]",
+		},
+	} {
+		at := ArrayOf(table.n, TypeOf(table.value(0)))
+		v := New(at).Elem()
+		vok := New(at).Elem()
+		vnot := New(at).Elem()
+		for i := 0; i < v.Len(); i++ {
+			v.Index(i).Set(ValueOf(table.value(i)))
+			vok.Index(i).Set(ValueOf(table.value(i)))
+			j := i
+			if i+1 == v.Len() {
+				j = i + 1
+			}
+			vnot.Index(i).Set(ValueOf(table.value(j))) // make it differ only by last element
+		}
+		s := fmt.Sprint(v.Interface())
+		if s != table.want {
+			t.Errorf("constructed array = %s, want %s", s, table.want)
+		}
+
+		if table.comparable != at.Comparable() {
+			t.Errorf("constructed array (%#v) is comparable=%v, want=%v", v.Interface(), at.Comparable(), table.comparable)
+		}
+		if table.comparable {
+			if table.n > 0 {
+				if DeepEqual(vnot.Interface(), v.Interface()) {
+					t.Errorf(
+						"arrays (%#v) compare ok (but should not)",
+						v.Interface(),
+					)
+				}
+			}
+			if !DeepEqual(vok.Interface(), v.Interface()) {
+				t.Errorf(
+					"arrays (%#v) compare NOT-ok (but should)",
+					v.Interface(),
+				)
+			}
+		}
 	}
 
 	// check that type already in binary is found
+	type T int
 	checkSameType(t, Zero(ArrayOf(5, TypeOf(T(1)))).Interface(), [5]T{})
 }
 
+func TestArrayOfGC(t *testing.T) {
+	type T *uintptr
+	tt := TypeOf(T(nil))
+	const n = 100
+	var x []interface{}
+	for i := 0; i < n; i++ {
+		v := New(ArrayOf(n, tt)).Elem()
+		for j := 0; j < v.Len(); j++ {
+			p := new(uintptr)
+			*p = uintptr(i*n + j)
+			v.Index(j).Set(ValueOf(p).Convert(tt))
+		}
+		x = append(x, v.Interface())
+	}
+	runtime.GC()
+
+	for i, xi := range x {
+		v := ValueOf(xi)
+		for j := 0; j < v.Len(); j++ {
+			k := v.Index(j).Elem().Interface()
+			if k != uintptr(i*n+j) {
+				t.Errorf("lost x[%d][%d] = %d, want %d", i, j, k, i*n+j)
+			}
+		}
+	}
+}
+
+func TestArrayOfAlg(t *testing.T) {
+	at := ArrayOf(6, TypeOf(byte(0)))
+	v1 := New(at).Elem()
+	v2 := New(at).Elem()
+	if v1.Interface() != v1.Interface() {
+		t.Errorf("constructed array %v not equal to itself", v1.Interface())
+	}
+	v1.Index(5).Set(ValueOf(byte(1)))
+	if i1, i2 := v1.Interface(), v2.Interface(); i1 == i2 {
+		t.Errorf("constructed arrays %v and %v should not be equal", i1, i2)
+	}
+
+	at = ArrayOf(6, TypeOf([]int(nil)))
+	v1 = New(at).Elem()
+	shouldPanic(func() { _ = v1.Interface() == v1.Interface() })
+}
+
+func TestArrayOfGenericAlg(t *testing.T) {
+	at1 := ArrayOf(5, TypeOf(string("")))
+	at := ArrayOf(6, at1)
+	v1 := New(at).Elem()
+	v2 := New(at).Elem()
+	if v1.Interface() != v1.Interface() {
+		t.Errorf("constructed array %v not equal to itself", v1.Interface())
+	}
+
+	v1.Index(0).Index(0).Set(ValueOf("abc"))
+	v2.Index(0).Index(0).Set(ValueOf("efg"))
+	if i1, i2 := v1.Interface(), v2.Interface(); i1 == i2 {
+		t.Errorf("constructed arrays %v and %v should not be equal", i1, i2)
+	}
+
+	v1.Index(0).Index(0).Set(ValueOf("abc"))
+	v2.Index(0).Index(0).Set(ValueOf((v1.Index(0).Index(0).String() + " ")[:3]))
+	if i1, i2 := v1.Interface(), v2.Interface(); i1 != i2 {
+		t.Errorf("constructed arrays %v and %v should be equal", i1, i2)
+	}
+
+	// Test hash
+	m := MakeMap(MapOf(at, TypeOf(int(0))))
+	m.SetMapIndex(v1, ValueOf(1))
+	if i1, i2 := v1.Interface(), v2.Interface(); !m.MapIndex(v2).IsValid() {
+		t.Errorf("constructed arrays %v and %v have different hashes", i1, i2)
+	}
+}
+
+func TestArrayOfDirectIface(t *testing.T) {
+	t.Skip("skipping test because gccgo uses a different directiface value")
+	{
+		type T [1]*byte
+		i1 := Zero(TypeOf(T{})).Interface()
+		v1 := ValueOf(&i1).Elem()
+		p1 := v1.InterfaceData()[1]
+
+		i2 := Zero(ArrayOf(1, PtrTo(TypeOf(int8(0))))).Interface()
+		v2 := ValueOf(&i2).Elem()
+		p2 := v2.InterfaceData()[1]
+
+		if p1 != 0 {
+			t.Errorf("got p1=%v. want=%v", p1, nil)
+		}
+
+		if p2 != 0 {
+			t.Errorf("got p2=%v. want=%v", p2, nil)
+		}
+	}
+	{
+		type T [0]*byte
+		i1 := Zero(TypeOf(T{})).Interface()
+		v1 := ValueOf(&i1).Elem()
+		p1 := v1.InterfaceData()[1]
+
+		i2 := Zero(ArrayOf(0, PtrTo(TypeOf(int8(0))))).Interface()
+		v2 := ValueOf(&i2).Elem()
+		p2 := v2.InterfaceData()[1]
+
+		if p1 == 0 {
+			t.Errorf("got p1=%v. want=not-%v", p1, nil)
+		}
+
+		if p2 == 0 {
+			t.Errorf("got p2=%v. want=not-%v", p2, nil)
+		}
+	}
+}
+
 func TestSliceOf(t *testing.T) {
 	// check construction and use of type not in binary
 	type T int
@@ -3489,6 +3725,26 @@
 	checkSameType(t, Zero(ChanOf(BothDir, TypeOf(T1(1)))).Interface(), (chan T1)(nil))
 }
 
+func TestChanOfDir(t *testing.T) {
+	// check construction and use of type not in binary
+	type T string
+	crt := ChanOf(RecvDir, TypeOf(T("")))
+	cst := ChanOf(SendDir, TypeOf(T("")))
+
+	// check that type already in binary is found
+	type T1 int
+	checkSameType(t, Zero(ChanOf(RecvDir, TypeOf(T1(1)))).Interface(), (<-chan T1)(nil))
+	checkSameType(t, Zero(ChanOf(SendDir, TypeOf(T1(1)))).Interface(), (chan<- T1)(nil))
+
+	// check String form of ChanDir
+	if crt.ChanDir().String() != "<-chan" {
+		t.Errorf("chan dir: have %q, want %q", crt.ChanDir().String(), "<-chan")
+	}
+	if cst.ChanDir().String() != "chan<-" {
+		t.Errorf("chan dir: have %q, want %q", cst.ChanDir().String(), "chan<-")
+	}
+}
+
 func TestChanOfGC(t *testing.T) {
 	done := make(chan bool, 1)
 	go func() {
@@ -3632,6 +3888,67 @@
 	}
 }
 
+func TestTypelinksSorted(t *testing.T) {
+	var last string
+	for i, n := range TypeLinks() {
+		if n < last {
+			t.Errorf("typelinks not sorted: %q [%d] > %q [%d]", last, i-1, n, i)
+		}
+		last = n
+	}
+}
+
+func TestFuncOf(t *testing.T) {
+	// check construction and use of type not in binary
+	type K string
+	type V float64
+
+	fn := func(args []Value) []Value {
+		if len(args) != 1 {
+			t.Errorf("args == %v, want exactly one arg", args)
+		} else if args[0].Type() != TypeOf(K("")) {
+			t.Errorf("args[0] is type %v, want %v", args[0].Type, TypeOf(K("")))
+		} else if args[0].String() != "gopher" {
+			t.Errorf("args[0] = %q, want %q", args[0].String(), "gopher")
+		}
+		return []Value{ValueOf(V(3.14))}
+	}
+	v := MakeFunc(FuncOf([]Type{TypeOf(K(""))}, []Type{TypeOf(V(0))}, false), fn)
+
+	outs := v.Call([]Value{ValueOf(K("gopher"))})
+	if len(outs) != 1 {
+		t.Fatalf("v.Call returned %v, want exactly one result", outs)
+	} else if outs[0].Type() != TypeOf(V(0)) {
+		t.Fatalf("c.Call[0] is type %v, want %v", outs[0].Type, TypeOf(V(0)))
+	}
+	f := outs[0].Float()
+	if f != 3.14 {
+		t.Errorf("constructed func returned %f, want %f", f, 3.14)
+	}
+
+	// check that types already in binary are found
+	type T1 int
+	testCases := []struct {
+		in, out  []Type
+		variadic bool
+		want     interface{}
+	}{
+		{in: []Type{TypeOf(T1(0))}, want: (func(T1))(nil)},
+		{in: []Type{TypeOf(int(0))}, want: (func(int))(nil)},
+		{in: []Type{SliceOf(TypeOf(int(0)))}, variadic: true, want: (func(...int))(nil)},
+		{in: []Type{TypeOf(int(0))}, out: []Type{TypeOf(false)}, want: (func(int) bool)(nil)},
+		{in: []Type{TypeOf(int(0))}, out: []Type{TypeOf(false), TypeOf("")}, want: (func(int) (bool, string))(nil)},
+	}
+	for _, tt := range testCases {
+		checkSameType(t, Zero(FuncOf(tt.in, tt.out, tt.variadic)).Interface(), tt.want)
+	}
+
+	// check that variadic requires last element be a slice.
+	FuncOf([]Type{TypeOf(1), TypeOf(""), SliceOf(TypeOf(false))}, nil, true)
+	shouldPanic(func() { FuncOf([]Type{TypeOf(0), TypeOf(""), TypeOf(false)}, nil, true) })
+	shouldPanic(func() { FuncOf(nil, nil, true) })
+}
+
 type B1 struct {
 	X int
 	Y int
@@ -4077,15 +4394,16 @@
 }
 
 type funcLayoutTest struct {
-	rcvr, t            Type
-	argsize, retOffset uintptr
-	stack              []byte
+	rcvr, t                  Type
+	size, argsize, retOffset uintptr
+	stack                    []byte // pointer bitmap: 1 is pointer, 0 is scalar (or uninitialized)
+	gc                       []byte
 }
 
 var funcLayoutTests []funcLayoutTest
 
 func init() {
-	var argAlign = PtrSize
+	var argAlign uintptr = PtrSize
 	if runtime.GOARCH == "amd64p32" {
 		argAlign = 2 * PtrSize
 	}
@@ -4097,24 +4415,28 @@
 		funcLayoutTest{
 			nil,
 			ValueOf(func(a, b string) string { return "" }).Type(),
+			6 * PtrSize,
 			4 * PtrSize,
 			4 * PtrSize,
-			[]byte{BitsPointer, BitsScalar, BitsPointer},
+			[]byte{1, 0, 1},
+			[]byte{1, 0, 1, 0, 1},
 		})
 
 	var r []byte
 	if PtrSize == 4 {
-		r = []byte{BitsScalar, BitsScalar, BitsScalar, BitsPointer}
+		r = []byte{0, 0, 0, 1}
 	} else {
-		r = []byte{BitsScalar, BitsScalar, BitsPointer}
+		r = []byte{0, 0, 1}
 	}
 	funcLayoutTests = append(funcLayoutTests,
 		funcLayoutTest{
 			nil,
 			ValueOf(func(a, b, c uint32, p *byte, d uint16) {}).Type(),
+			roundup(roundup(3*4, PtrSize)+PtrSize+2, argAlign),
 			roundup(3*4, PtrSize) + PtrSize + 2,
 			roundup(roundup(3*4, PtrSize)+PtrSize+2, argAlign),
 			r,
+			r,
 		})
 
 	funcLayoutTests = append(funcLayoutTests,
@@ -4123,7 +4445,9 @@
 			ValueOf(func(a map[int]int, b uintptr, c interface{}) {}).Type(),
 			4 * PtrSize,
 			4 * PtrSize,
-			[]byte{BitsPointer, BitsScalar, BitsPointer, BitsPointer},
+			4 * PtrSize,
+			[]byte{1, 0, 1, 1},
+			[]byte{1, 0, 1, 1},
 		})
 
 	type S struct {
@@ -4136,23 +4460,66 @@
 			ValueOf(func(a S) {}).Type(),
 			4 * PtrSize,
 			4 * PtrSize,
-			[]byte{BitsScalar, BitsScalar, BitsPointer, BitsPointer},
+			4 * PtrSize,
+			[]byte{0, 0, 1, 1},
+			[]byte{0, 0, 1, 1},
 		})
 
 	funcLayoutTests = append(funcLayoutTests,
 		funcLayoutTest{
 			ValueOf((*byte)(nil)).Type(),
 			ValueOf(func(a uintptr, b *int) {}).Type(),
+			roundup(3*PtrSize, argAlign),
 			3 * PtrSize,
 			roundup(3*PtrSize, argAlign),
-			[]byte{BitsPointer, BitsScalar, BitsPointer},
+			[]byte{1, 0, 1},
+			[]byte{1, 0, 1},
+		})
+
+	funcLayoutTests = append(funcLayoutTests,
+		funcLayoutTest{
+			nil,
+			ValueOf(func(a uintptr) {}).Type(),
+			roundup(PtrSize, argAlign),
+			PtrSize,
+			roundup(PtrSize, argAlign),
+			[]byte{},
+			[]byte{},
+		})
+
+	funcLayoutTests = append(funcLayoutTests,
+		funcLayoutTest{
+			nil,
+			ValueOf(func() uintptr { return 0 }).Type(),
+			PtrSize,
+			0,
+			0,
+			[]byte{},
+			[]byte{},
+		})
+
+	funcLayoutTests = append(funcLayoutTests,
+		funcLayoutTest{
+			ValueOf(uintptr(0)).Type(),
+			ValueOf(func(a uintptr) {}).Type(),
+			2 * PtrSize,
+			2 * PtrSize,
+			2 * PtrSize,
+			[]byte{1},
+			[]byte{1},
+			// Note: this one is tricky, as the receiver is not a pointer.  But we
+			// pass the receiver by reference to the autogenerated pointer-receiver
+			// version of the function.
 		})
 }
 
 func TestFuncLayout(t *testing.T) {
 	t.Skip("gccgo does not use funcLayout")
 	for _, lt := range funcLayoutTests {
-		_, argsize, retOffset, stack := FuncLayout(lt.t, lt.rcvr)
+		typ, argsize, retOffset, stack, gc, ptrs := FuncLayout(lt.t, lt.rcvr)
+		if typ.Size() != lt.size {
+			t.Errorf("funcLayout(%v, %v).size=%d, want %d", lt.t, lt.rcvr, typ.Size(), lt.size)
+		}
 		if argsize != lt.argsize {
 			t.Errorf("funcLayout(%v, %v).argsize=%d, want %d", lt.t, lt.rcvr, argsize, lt.argsize)
 		}
@@ -4162,5 +4529,260 @@
 		if !bytes.Equal(stack, lt.stack) {
 			t.Errorf("funcLayout(%v, %v).stack=%v, want %v", lt.t, lt.rcvr, stack, lt.stack)
 		}
+		if !bytes.Equal(gc, lt.gc) {
+			t.Errorf("funcLayout(%v, %v).gc=%v, want %v", lt.t, lt.rcvr, gc, lt.gc)
+		}
+		if ptrs && len(stack) == 0 || !ptrs && len(stack) > 0 {
+			t.Errorf("funcLayout(%v, %v) pointers flag=%v, want %v", lt.t, lt.rcvr, ptrs, !ptrs)
+		}
+	}
+}
+
+func verifyGCBits(t *testing.T, typ Type, bits []byte) {
+	heapBits := GCBits(New(typ).Interface())
+	if !bytes.Equal(heapBits, bits) {
+		t.Errorf("heapBits incorrect for %v\nhave %v\nwant %v", typ, heapBits, bits)
+	}
+}
+
+func verifyGCBitsSlice(t *testing.T, typ Type, cap int, bits []byte) {
+	// Creating a slice causes the runtime to repeat a bitmap,
+	// which exercises a different path from making the compiler
+	// repeat a bitmap for a small array or executing a repeat in
+	// a GC program.
+	val := MakeSlice(typ, 0, cap)
+	data := NewAt(ArrayOf(cap, typ), unsafe.Pointer(val.Pointer()))
+	heapBits := GCBits(data.Interface())
+	// Repeat the bitmap for the slice size, trimming scalars in
+	// the last element.
+	bits = rep(cap, bits)
+	for len(bits) > 2 && bits[len(bits)-1] == 0 {
+		bits = bits[:len(bits)-1]
+	}
+	if !bytes.Equal(heapBits, bits) {
+		t.Errorf("heapBits incorrect for make(%v, 0, %v)\nhave %v\nwant %v", typ, cap, heapBits, bits)
+	}
+}
+
+func TestGCBits(t *testing.T) {
+	t.Skip("gccgo does not use gcbits yet")
+
+	verifyGCBits(t, TypeOf((*byte)(nil)), []byte{1})
+
+	// Building blocks for types seen by the compiler (like [2]Xscalar).
+	// The compiler will create the type structures for the derived types,
+	// including their GC metadata.
+	type Xscalar struct{ x uintptr }
+	type Xptr struct{ x *byte }
+	type Xptrscalar struct {
+		*byte
+		uintptr
+	}
+	type Xscalarptr struct {
+		uintptr
+		*byte
+	}
+	type Xbigptrscalar struct {
+		_ [100]*byte
+		_ [100]uintptr
+	}
+
+	var Tscalar, Tint64, Tptr, Tscalarptr, Tptrscalar, Tbigptrscalar Type
+	{
+		// Building blocks for types constructed by reflect.
+		// This code is in a separate block so that code below
+		// cannot accidentally refer to these.
+		// The compiler must NOT see types derived from these
+		// (for example, [2]Scalar must NOT appear in the program),
+		// or else reflect will use it instead of having to construct one.
+		// The goal is to test the construction.
+		type Scalar struct{ x uintptr }
+		type Ptr struct{ x *byte }
+		type Ptrscalar struct {
+			*byte
+			uintptr
+		}
+		type Scalarptr struct {
+			uintptr
+			*byte
+		}
+		type Bigptrscalar struct {
+			_ [100]*byte
+			_ [100]uintptr
+		}
+		type Int64 int64
+		Tscalar = TypeOf(Scalar{})
+		Tint64 = TypeOf(Int64(0))
+		Tptr = TypeOf(Ptr{})
+		Tscalarptr = TypeOf(Scalarptr{})
+		Tptrscalar = TypeOf(Ptrscalar{})
+		Tbigptrscalar = TypeOf(Bigptrscalar{})
+	}
+
+	empty := []byte{}
+
+	verifyGCBits(t, TypeOf(Xscalar{}), empty)
+	verifyGCBits(t, Tscalar, empty)
+	verifyGCBits(t, TypeOf(Xptr{}), lit(1))
+	verifyGCBits(t, Tptr, lit(1))
+	verifyGCBits(t, TypeOf(Xscalarptr{}), lit(0, 1))
+	verifyGCBits(t, Tscalarptr, lit(0, 1))
+	verifyGCBits(t, TypeOf(Xptrscalar{}), lit(1))
+	verifyGCBits(t, Tptrscalar, lit(1))
+
+	verifyGCBits(t, TypeOf([0]Xptr{}), empty)
+	verifyGCBits(t, ArrayOf(0, Tptr), empty)
+	verifyGCBits(t, TypeOf([1]Xptrscalar{}), lit(1))
+	verifyGCBits(t, ArrayOf(1, Tptrscalar), lit(1))
+	verifyGCBits(t, TypeOf([2]Xscalar{}), empty)
+	verifyGCBits(t, ArrayOf(2, Tscalar), empty)
+	verifyGCBits(t, TypeOf([10000]Xscalar{}), empty)
+	verifyGCBits(t, ArrayOf(10000, Tscalar), empty)
+	verifyGCBits(t, TypeOf([2]Xptr{}), lit(1, 1))
+	verifyGCBits(t, ArrayOf(2, Tptr), lit(1, 1))
+	verifyGCBits(t, TypeOf([10000]Xptr{}), rep(10000, lit(1)))
+	verifyGCBits(t, ArrayOf(10000, Tptr), rep(10000, lit(1)))
+	verifyGCBits(t, TypeOf([2]Xscalarptr{}), lit(0, 1, 0, 1))
+	verifyGCBits(t, ArrayOf(2, Tscalarptr), lit(0, 1, 0, 1))
+	verifyGCBits(t, TypeOf([10000]Xscalarptr{}), rep(10000, lit(0, 1)))
+	verifyGCBits(t, ArrayOf(10000, Tscalarptr), rep(10000, lit(0, 1)))
+	verifyGCBits(t, TypeOf([2]Xptrscalar{}), lit(1, 0, 1))
+	verifyGCBits(t, ArrayOf(2, Tptrscalar), lit(1, 0, 1))
+	verifyGCBits(t, TypeOf([10000]Xptrscalar{}), rep(10000, lit(1, 0)))
+	verifyGCBits(t, ArrayOf(10000, Tptrscalar), rep(10000, lit(1, 0)))
+	verifyGCBits(t, TypeOf([1][10000]Xptrscalar{}), rep(10000, lit(1, 0)))
+	verifyGCBits(t, ArrayOf(1, ArrayOf(10000, Tptrscalar)), rep(10000, lit(1, 0)))
+	verifyGCBits(t, TypeOf([2][10000]Xptrscalar{}), rep(2*10000, lit(1, 0)))
+	verifyGCBits(t, ArrayOf(2, ArrayOf(10000, Tptrscalar)), rep(2*10000, lit(1, 0)))
+	verifyGCBits(t, TypeOf([4]Xbigptrscalar{}), join(rep(3, join(rep(100, lit(1)), rep(100, lit(0)))), rep(100, lit(1))))
+	verifyGCBits(t, ArrayOf(4, Tbigptrscalar), join(rep(3, join(rep(100, lit(1)), rep(100, lit(0)))), rep(100, lit(1))))
+
+	verifyGCBitsSlice(t, TypeOf([]Xptr{}), 0, empty)
+	verifyGCBitsSlice(t, SliceOf(Tptr), 0, empty)
+	verifyGCBitsSlice(t, TypeOf([]Xptrscalar{}), 1, lit(1))
+	verifyGCBitsSlice(t, SliceOf(Tptrscalar), 1, lit(1))
+	verifyGCBitsSlice(t, TypeOf([]Xscalar{}), 2, lit(0))
+	verifyGCBitsSlice(t, SliceOf(Tscalar), 2, lit(0))
+	verifyGCBitsSlice(t, TypeOf([]Xscalar{}), 10000, lit(0))
+	verifyGCBitsSlice(t, SliceOf(Tscalar), 10000, lit(0))
+	verifyGCBitsSlice(t, TypeOf([]Xptr{}), 2, lit(1))
+	verifyGCBitsSlice(t, SliceOf(Tptr), 2, lit(1))
+	verifyGCBitsSlice(t, TypeOf([]Xptr{}), 10000, lit(1))
+	verifyGCBitsSlice(t, SliceOf(Tptr), 10000, lit(1))
+	verifyGCBitsSlice(t, TypeOf([]Xscalarptr{}), 2, lit(0, 1))
+	verifyGCBitsSlice(t, SliceOf(Tscalarptr), 2, lit(0, 1))
+	verifyGCBitsSlice(t, TypeOf([]Xscalarptr{}), 10000, lit(0, 1))
+	verifyGCBitsSlice(t, SliceOf(Tscalarptr), 10000, lit(0, 1))
+	verifyGCBitsSlice(t, TypeOf([]Xptrscalar{}), 2, lit(1, 0))
+	verifyGCBitsSlice(t, SliceOf(Tptrscalar), 2, lit(1, 0))
+	verifyGCBitsSlice(t, TypeOf([]Xptrscalar{}), 10000, lit(1, 0))
+	verifyGCBitsSlice(t, SliceOf(Tptrscalar), 10000, lit(1, 0))
+	verifyGCBitsSlice(t, TypeOf([][10000]Xptrscalar{}), 1, rep(10000, lit(1, 0)))
+	verifyGCBitsSlice(t, SliceOf(ArrayOf(10000, Tptrscalar)), 1, rep(10000, lit(1, 0)))
+	verifyGCBitsSlice(t, TypeOf([][10000]Xptrscalar{}), 2, rep(10000, lit(1, 0)))
+	verifyGCBitsSlice(t, SliceOf(ArrayOf(10000, Tptrscalar)), 2, rep(10000, lit(1, 0)))
+	verifyGCBitsSlice(t, TypeOf([]Xbigptrscalar{}), 4, join(rep(100, lit(1)), rep(100, lit(0))))
+	verifyGCBitsSlice(t, SliceOf(Tbigptrscalar), 4, join(rep(100, lit(1)), rep(100, lit(0))))
+
+	verifyGCBits(t, TypeOf((chan [100]Xscalar)(nil)), lit(1))
+	verifyGCBits(t, ChanOf(BothDir, ArrayOf(100, Tscalar)), lit(1))
+
+	verifyGCBits(t, TypeOf((func([10000]Xscalarptr))(nil)), lit(1))
+	verifyGCBits(t, FuncOf([]Type{ArrayOf(10000, Tscalarptr)}, nil, false), lit(1))
+
+	verifyGCBits(t, TypeOf((map[[10000]Xscalarptr]Xscalar)(nil)), lit(1))
+	verifyGCBits(t, MapOf(ArrayOf(10000, Tscalarptr), Tscalar), lit(1))
+
+	verifyGCBits(t, TypeOf((*[10000]Xscalar)(nil)), lit(1))
+	verifyGCBits(t, PtrTo(ArrayOf(10000, Tscalar)), lit(1))
+
+	verifyGCBits(t, TypeOf(([][10000]Xscalar)(nil)), lit(1))
+	verifyGCBits(t, SliceOf(ArrayOf(10000, Tscalar)), lit(1))
+
+	hdr := make([]byte, 8/PtrSize)
+
+	verifyMapBucket := func(t *testing.T, k, e Type, m interface{}, want []byte) {
+		verifyGCBits(t, MapBucketOf(k, e), want)
+		verifyGCBits(t, CachedBucketOf(TypeOf(m)), want)
+	}
+	verifyMapBucket(t,
+		Tscalar, Tptr,
+		map[Xscalar]Xptr(nil),
+		join(hdr, rep(8, lit(0)), rep(8, lit(1)), lit(1)))
+	verifyMapBucket(t,
+		Tscalarptr, Tptr,
+		map[Xscalarptr]Xptr(nil),
+		join(hdr, rep(8, lit(0, 1)), rep(8, lit(1)), lit(1)))
+	verifyMapBucket(t, Tint64, Tptr,
+		map[int64]Xptr(nil),
+		join(hdr, rep(8, rep(8/PtrSize, lit(0))), rep(8, lit(1)), naclpad(), lit(1)))
+	verifyMapBucket(t,
+		Tscalar, Tscalar,
+		map[Xscalar]Xscalar(nil),
+		empty)
+	verifyMapBucket(t,
+		ArrayOf(2, Tscalarptr), ArrayOf(3, Tptrscalar),
+		map[[2]Xscalarptr][3]Xptrscalar(nil),
+		join(hdr, rep(8*2, lit(0, 1)), rep(8*3, lit(1, 0)), lit(1)))
+	verifyMapBucket(t,
+		ArrayOf(64/PtrSize, Tscalarptr), ArrayOf(64/PtrSize, Tptrscalar),
+		map[[64 / PtrSize]Xscalarptr][64 / PtrSize]Xptrscalar(nil),
+		join(hdr, rep(8*64/PtrSize, lit(0, 1)), rep(8*64/PtrSize, lit(1, 0)), lit(1)))
+	verifyMapBucket(t,
+		ArrayOf(64/PtrSize+1, Tscalarptr), ArrayOf(64/PtrSize, Tptrscalar),
+		map[[64/PtrSize + 1]Xscalarptr][64 / PtrSize]Xptrscalar(nil),
+		join(hdr, rep(8, lit(1)), rep(8*64/PtrSize, lit(1, 0)), lit(1)))
+	verifyMapBucket(t,
+		ArrayOf(64/PtrSize, Tscalarptr), ArrayOf(64/PtrSize+1, Tptrscalar),
+		map[[64 / PtrSize]Xscalarptr][64/PtrSize + 1]Xptrscalar(nil),
+		join(hdr, rep(8*64/PtrSize, lit(0, 1)), rep(8, lit(1)), lit(1)))
+	verifyMapBucket(t,
+		ArrayOf(64/PtrSize+1, Tscalarptr), ArrayOf(64/PtrSize+1, Tptrscalar),
+		map[[64/PtrSize + 1]Xscalarptr][64/PtrSize + 1]Xptrscalar(nil),
+		join(hdr, rep(8, lit(1)), rep(8, lit(1)), lit(1)))
+}
+
+func naclpad() []byte {
+	if runtime.GOARCH == "amd64p32" {
+		return lit(0)
+	}
+	return nil
+}
+
+func rep(n int, b []byte) []byte { return bytes.Repeat(b, n) }
+func join(b ...[]byte) []byte    { return bytes.Join(b, nil) }
+func lit(x ...byte) []byte       { return x }
+
+func TestTypeOfTypeOf(t *testing.T) {
+	// Check that all the type constructors return concrete *rtype implementations.
+	// It's difficult to test directly because the reflect package is only at arm's length.
+	// The easiest thing to do is just call a function that crashes if it doesn't get an *rtype.
+	check := func(name string, typ Type) {
+		if underlying := TypeOf(typ).String(); underlying != "*reflect.rtype" {
+			t.Errorf("%v returned %v, not *reflect.rtype", name, underlying)
+		}
+	}
+
+	type T struct{ int }
+	check("TypeOf", TypeOf(T{}))
+
+	check("ArrayOf", ArrayOf(10, TypeOf(T{})))
+	check("ChanOf", ChanOf(BothDir, TypeOf(T{})))
+	check("FuncOf", FuncOf([]Type{TypeOf(T{})}, nil, false))
+	check("MapOf", MapOf(TypeOf(T{}), TypeOf(T{})))
+	check("PtrTo", PtrTo(TypeOf(T{})))
+	check("SliceOf", SliceOf(TypeOf(T{})))
+}
+
+type XM struct{}
+
+func (*XM) String() string { return "" }
+
+func TestPtrToMethods(t *testing.T) {
+	var y struct{ XM }
+	yp := New(TypeOf(y)).Interface()
+	_, ok := yp.(fmt.Stringer)
+	if !ok {
+		t.Fatal("does not implement Stringer, but should")
 	}
 }
diff --git a/third_party/gofrontend/libgo/go/reflect/example_test.go b/third_party/gofrontend/libgo/go/reflect/example_test.go
index cca28ee..8ebf976 100644
--- a/third_party/gofrontend/libgo/go/reflect/example_test.go
+++ b/third_party/gofrontend/libgo/go/reflect/example_test.go
@@ -6,6 +6,8 @@
 
 import (
 	"fmt"
+	"io"
+	"os"
 	"reflect"
 )
 
@@ -64,3 +66,16 @@
 	// Output:
 	// blue gopher
 }
+
+func ExampleTypeOf() {
+	// As interface types are only used for static typing, a
+	// common idiom to find the reflection Type for an interface
+	// type Foo is to use a *Foo value.
+	writerType := reflect.TypeOf((*io.Writer)(nil)).Elem()
+
+	fileType := reflect.TypeOf((*os.File)(nil))
+	fmt.Println(fileType.Implements(writerType))
+
+	// Output:
+	// true
+}
diff --git a/third_party/gofrontend/libgo/go/reflect/export_test.go b/third_party/gofrontend/libgo/go/reflect/export_test.go
index 49c45e8..bdbd600 100644
--- a/third_party/gofrontend/libgo/go/reflect/export_test.go
+++ b/third_party/gofrontend/libgo/go/reflect/export_test.go
@@ -6,22 +6,38 @@
 
 // MakeRO returns a copy of v with the read-only flag set.
 func MakeRO(v Value) Value {
-	v.flag |= flagRO
+	v.flag |= flagStickyRO
 	return v
 }
 
 // IsRO reports whether v's read-only flag is set.
 func IsRO(v Value) bool {
-	return v.flag&flagRO != 0
+	return v.flag&flagStickyRO != 0
 }
 
-var ArrayOf = arrayOf
 var CallGC = &callGC
 
 const PtrSize = ptrSize
-const BitsPointer = bitsPointer
-const BitsScalar = bitsScalar
 
-func FuncLayout(t Type, rcvr Type) (frametype Type, argSize, retOffset uintptr, stack []byte) {
+func FuncLayout(t Type, rcvr Type) (frametype Type, argSize, retOffset uintptr, stack []byte, gc []byte, ptrs bool) {
 	return
 }
+
+func TypeLinks() []string {
+	return nil
+}
+
+var GCBits = gcbits
+
+// Will be provided by runtime eventually.
+func gcbits(interface{}) []byte {
+	return nil
+}
+
+func MapBucketOf(x, y Type) Type {
+	return nil
+}
+
+func CachedBucketOf(m Type) Type {
+	return nil
+}
diff --git a/third_party/gofrontend/libgo/go/reflect/type.go b/third_party/gofrontend/libgo/go/reflect/type.go
index 5cbf7e5..180a364 100644
--- a/third_party/gofrontend/libgo/go/reflect/type.go
+++ b/third_party/gofrontend/libgo/go/reflect/type.go
@@ -12,7 +12,7 @@
 // for that type.
 //
 // See "The Laws of Reflection" for an introduction to reflection in Go:
-// http://golang.org/doc/articles/laws_of_reflection.html
+// https://golang.org/doc/articles/laws_of_reflection.html
 package reflect
 
 import (
@@ -90,16 +90,16 @@
 	// Kind returns the specific kind of this type.
 	Kind() Kind
 
-	// Implements returns true if the type implements the interface type u.
+	// Implements reports whether the type implements the interface type u.
 	Implements(u Type) bool
 
-	// AssignableTo returns true if a value of the type is assignable to type u.
+	// AssignableTo reports whether a value of the type is assignable to type u.
 	AssignableTo(u Type) bool
 
-	// ConvertibleTo returns true if a value of the type is convertible to type u.
+	// ConvertibleTo reports whether a value of the type is convertible to type u.
 	ConvertibleTo(u Type) bool
 
-	// Comparable returns true if values of this type are comparable.
+	// Comparable reports whether values of this type are comparable.
 	Comparable() bool
 
 	// Methods applicable only to some types, depending on Kind.
@@ -123,7 +123,7 @@
 	// It panics if the type's Kind is not Chan.
 	ChanDir() ChanDir
 
-	// IsVariadic returns true if a function type's final input parameter
+	// IsVariadic reports whether a function type's final input parameter
 	// is a "..." parameter.  If so, t.In(t.NumIn() - 1) returns the parameter's
 	// implicit actual type []T.
 	//
@@ -204,9 +204,9 @@
 // See golang.org/issue/4876 for more details.
 
 /*
- * These data structures are known to the compiler (../../cmd/gc/reflect.c).
+ * These data structures are known to the compiler (../../cmd/internal/gc/reflect.go).
  * A few are known to ../runtime/type.go to convey to debuggers.
- * They are also known to ../runtime/type.h.
+ * They are also known to ../runtime/type.go.
  */
 
 // A Kind represents the specific kind of type that a Type represents.
@@ -255,14 +255,13 @@
 	size       uintptr
 	hash       uint32 // hash of type; avoids computation in hash tables
 
-	hashfn  uintptr // hash function code
-	equalfn uintptr // equality function code
+	hashfn  func(unsafe.Pointer, uintptr) uintptr              // hash function
+	equalfn func(unsafe.Pointer, unsafe.Pointer, uintptr) bool // equality function
 
 	gc            unsafe.Pointer // garbage collection data
 	string        *string        // string form; unnecessary  but undeniably useful
 	*uncommonType                // (relatively) uncommon fields
 	ptrToThis     *rtype         // type for pointer to this type, if used in binary or has methods
-	zero          unsafe.Pointer // pointer to zero value
 }
 
 // Method on non-interface type
@@ -393,7 +392,7 @@
 	// method name.  It is empty for upper case (exported) method names.
 	// The combination of PkgPath and Name uniquely identifies a method
 	// in a method set.
-	// See http://golang.org/ref/spec#Uniqueness_of_identifiers
+	// See https://golang.org/ref/spec#Uniqueness_of_identifiers
 	Name    string
 	PkgPath string
 
@@ -517,7 +516,7 @@
 	fl := flag(Func)
 	if p.pkgPath != nil {
 		m.PkgPath = *p.pkgPath
-		fl |= flagRO
+		fl |= flagStickyRO
 	}
 	mt := p.typ
 	m.Type = toType(mt)
@@ -549,7 +548,7 @@
 	return
 }
 
-// TODO(rsc): 6g supplies these, but they are not
+// TODO(rsc): gc supplies these, but they are not
 // as efficient as they could be: they have commonType
 // as the receiver instead of *rtype.
 func (t *rtype) NumMethod() int {
@@ -759,7 +758,7 @@
 	// Name is the field name.
 	// PkgPath is the package path that qualifies a lower case (unexported)
 	// field name.  It is empty for upper case (exported) field names.
-	// See http://golang.org/ref/spec#Uniqueness_of_identifiers
+	// See https://golang.org/ref/spec#Uniqueness_of_identifiers
 	Name    string
 	PkgPath string
 
@@ -785,8 +784,11 @@
 // If the tag does not have the conventional format, the value
 // returned by Get is unspecified.
 func (tag StructTag) Get(key string) string {
+	// When modifying this code, also update the validateStructTag code
+	// in golang.org/x/tools/cmd/vet/structtag.go.
+
 	for tag != "" {
-		// skip leading space
+		// Skip leading space.
 		i := 0
 		for i < len(tag) && tag[i] == ' ' {
 			i++
@@ -796,19 +798,21 @@
 			break
 		}
 
-		// scan to colon.
-		// a space or a quote is a syntax error
+		// Scan to colon. A space, a quote or a control character is a syntax error.
+		// Strictly speaking, control chars include the range [0x7f, 0x9f], not just
+		// [0x00, 0x1f], but in practice, we ignore the multi-byte control characters
+		// as it is simpler to inspect the tag's bytes than the tag's runes.
 		i = 0
-		for i < len(tag) && tag[i] != ' ' && tag[i] != ':' && tag[i] != '"' {
+		for i < len(tag) && tag[i] > ' ' && tag[i] != ':' && tag[i] != '"' && tag[i] != 0x7f {
 			i++
 		}
-		if i+1 >= len(tag) || tag[i] != ':' || tag[i+1] != '"' {
+		if i == 0 || i+1 >= len(tag) || tag[i] != ':' || tag[i+1] != '"' {
 			break
 		}
 		name := string(tag[:i])
 		tag = tag[i+1:]
 
-		// scan quoted string to find value
+		// Scan quoted string to find value.
 		i = 1
 		for i < len(tag) && tag[i] != '"' {
 			if tag[i] == '\\' {
@@ -823,7 +827,10 @@
 		tag = tag[i+1:]
 
 		if key == name {
-			value, _ := strconv.Unquote(qvalue)
+			value, err := strconv.Unquote(qvalue)
+			if err != nil {
+				break
+			}
 			return value
 		}
 	}
@@ -1025,8 +1032,8 @@
 	return t.FieldByNameFunc(func(s string) bool { return s == name })
 }
 
-// TypeOf returns the reflection Type of the value in the interface{}.
-// TypeOf(nil) returns nil.
+// TypeOf returns the reflection Type that represents the dynamic type of i.
+// If i is a nil interface value, TypeOf returns nil.
 func TypeOf(i interface{}) Type {
 	eface := *(*emptyInterface)(unsafe.Pointer(&i))
 	return toType(eface.typ)
@@ -1110,7 +1117,8 @@
 		return r.(*rtype)
 	}
 
-	// initialize p using *byte's ptrType as a prototype.
+	// Create a new ptrType starting with the description
+	// of an *unsafe.Pointer.
 	p = new(ptrType)
 	var iptr interface{} = (*unsafe.Pointer)(nil)
 	prototype := *(**ptrType)(unsafe.Pointer(&iptr))
@@ -1129,7 +1137,6 @@
 
 	p.uncommonType = nil
 	p.ptrToThis = nil
-	p.zero = unsafe.Pointer(&make([]byte, p.size)[0])
 	p.elem = t
 
 	if t.kind&kindNoPointers != 0 {
@@ -1147,6 +1154,7 @@
 	q := canonicalize(&p.rtype)
 	p = (*ptrType)(unsafe.Pointer(q.(*rtype)))
 
+	ptrMap.m[t] = p
 	ptrMap.Unlock()
 	return &p.rtype
 }
@@ -1213,7 +1221,7 @@
 	}
 }
 
-// implements returns true if the type V implements the interface type T.
+// implements reports whether the type V implements the interface type T.
 func implements(T, V *rtype) bool {
 	if T.Kind() != Interface {
 		return false
@@ -1234,7 +1242,7 @@
 	// methods along the way, or else V does not implement T.
 	// This lets us run the scan in overall linear time instead of
 	// the quadratic time  a naive search would require.
-	// See also ../runtime/iface.c.
+	// See also ../runtime/iface.go.
 	if V.Kind() == Interface {
 		v := (*interfaceType)(unsafe.Pointer(V))
 		i := 0
@@ -1267,9 +1275,9 @@
 	return false
 }
 
-// directlyAssignable returns true if a value x of type V can be directly
+// directlyAssignable reports whether a value x of type V can be directly
 // assigned (using memmove) to a value of type T.
-// http://golang.org/doc/go_spec.html#Assignability
+// https://golang.org/doc/go_spec.html#Assignability
 // Ignoring the interface rules (implemented elsewhere)
 // and the ideal constant rules (no ideal constants at run time).
 func directlyAssignable(T, V *rtype) bool {
@@ -1447,6 +1455,14 @@
 	end   uintptr // _GC_END
 }
 
+// The funcLookupCache caches FuncOf lookups.
+// FuncOf does not share the common lookupCache since cacheKey is not
+// sufficient to represent functions unambiguously.
+var funcLookupCache struct {
+	sync.RWMutex
+	m map[uint32][]*rtype // keyed by hash calculated in FuncOf
+}
+
 // ChanOf returns the channel type with the given direction and element type.
 // For example, if t represents int, ChanOf(RecvDir, t) represents <-chan int.
 //
@@ -1487,6 +1503,7 @@
 	prototype := *(**chanType)(unsafe.Pointer(&ichan))
 	ch := new(chanType)
 	*ch = *prototype
+	ch.dir = uintptr(dir)
 	ch.string = &s
 
 	// gccgo uses a different hash.
@@ -1505,7 +1522,6 @@
 	ch.elem = typ
 	ch.uncommonType = nil
 	ch.ptrToThis = nil
-	ch.zero = unsafe.Pointer(&make([]byte, ch.size)[0])
 
 	ch.gc = unsafe.Pointer(&chanGC{
 		width: ch.size,
@@ -1548,9 +1564,8 @@
 
 	// Make a map type.
 	var imap interface{} = (map[unsafe.Pointer]unsafe.Pointer)(nil)
-	prototype := *(**mapType)(unsafe.Pointer(&imap))
 	mt := new(mapType)
-	*mt = *prototype
+	*mt = **(**mapType)(unsafe.Pointer(&imap))
 	mt.string = &s
 
 	// gccgo uses a different hash
@@ -1561,7 +1576,6 @@
 	mt.elem = etyp
 	mt.uncommonType = nil
 	mt.ptrToThis = nil
-	mt.zero = unsafe.Pointer(&make([]byte, mt.size)[0])
 	// mt.gc = unsafe.Pointer(&ptrGC{
 	// 	width:  unsafe.Sizeof(uintptr(0)),
 	// 	op:     _GC_PTR,
@@ -1580,154 +1594,243 @@
 	return cachePut(ckey, &mt.rtype)
 }
 
-// gcProg is a helper type for generatation of GC pointer info.
-type gcProg struct {
-	gc     []byte
-	size   uintptr // size of type in bytes
-	hasPtr bool
-}
-
-func (gc *gcProg) append(v byte) {
-	gc.align(unsafe.Sizeof(uintptr(0)))
-	gc.appendWord(v)
-}
-
-// Appends t's type info to the current program.
-func (gc *gcProg) appendProg(t *rtype) {
-	gc.align(uintptr(t.align))
-	if !t.pointers() {
-		gc.size += t.size
-		return
+// FuncOf returns the function type with the given argument and result types.
+// For example if k represents int and e represents string,
+// FuncOf([]Type{k}, []Type{e}, false) represents func(int) string.
+//
+// The variadic argument controls whether the function is variadic. FuncOf
+// panics if the in[len(in)-1] does not represent a slice and variadic is
+// true.
+func FuncOf(in, out []Type, variadic bool) Type {
+	if variadic && (len(in) == 0 || in[len(in)-1].Kind() != Slice) {
+		panic("reflect.FuncOf: last arg of variadic func must be slice")
 	}
-	switch t.Kind() {
-	default:
-		panic("reflect: non-pointer type marked as having pointers")
-	case Ptr, UnsafePointer, Chan, Func, Map:
-		gc.appendWord(bitsPointer)
-	case Slice:
-		gc.appendWord(bitsPointer)
-		gc.appendWord(bitsScalar)
-		gc.appendWord(bitsScalar)
-	case String:
-		gc.appendWord(bitsPointer)
-		gc.appendWord(bitsScalar)
-	case Array:
-		c := t.Len()
-		e := t.Elem().common()
-		for i := 0; i < c; i++ {
-			gc.appendProg(e)
+
+	// Make a func type.
+	var ifunc interface{} = (func())(nil)
+	prototype := *(**funcType)(unsafe.Pointer(&ifunc))
+	ft := new(funcType)
+	*ft = *prototype
+
+	// Build a hash and minimally populate ft.
+	var hash uint32 = 8
+	var fin, fout []*rtype
+	shift := uint(1)
+	for _, in := range in {
+		t := in.(*rtype)
+		fin = append(fin, t)
+		hash += t.hash << shift
+		shift++
+	}
+	shift = 2
+	for _, out := range out {
+		t := out.(*rtype)
+		fout = append(fout, t)
+		hash += t.hash << shift
+		shift++
+	}
+	if variadic {
+		hash++
+	}
+	hash <<= 4
+	ft.hash = hash
+	ft.in = fin
+	ft.out = fout
+	ft.dotdotdot = variadic
+
+	// Look in cache.
+	funcLookupCache.RLock()
+	for _, t := range funcLookupCache.m[hash] {
+		if haveIdenticalUnderlyingType(&ft.rtype, t) {
+			funcLookupCache.RUnlock()
+			return t
 		}
-	case Interface:
-		gc.appendWord(bitsMultiWord)
-		if t.NumMethod() == 0 {
-			gc.appendWord(bitsEface)
+	}
+	funcLookupCache.RUnlock()
+
+	// Not in cache, lock and retry.
+	funcLookupCache.Lock()
+	defer funcLookupCache.Unlock()
+	if funcLookupCache.m == nil {
+		funcLookupCache.m = make(map[uint32][]*rtype)
+	}
+	for _, t := range funcLookupCache.m[hash] {
+		if haveIdenticalUnderlyingType(&ft.rtype, t) {
+			return t
+		}
+	}
+
+	str := funcStr(ft)
+
+	// Populate the remaining fields of ft and store in cache.
+	ft.string = &str
+	ft.uncommonType = nil
+	ft.ptrToThis = nil
+
+	// TODO(cmang): Generate GC data for funcs.
+	ft.gc = unsafe.Pointer(&ptrDataGCProg)
+
+	funcLookupCache.m[hash] = append(funcLookupCache.m[hash], &ft.rtype)
+
+	return toType(&ft.rtype)
+}
+
+// funcStr builds a string representation of a funcType.
+func funcStr(ft *funcType) string {
+	repr := make([]byte, 0, 64)
+	repr = append(repr, "func("...)
+	for i, t := range ft.in {
+		if i > 0 {
+			repr = append(repr, ", "...)
+		}
+		if ft.dotdotdot && i == len(ft.in)-1 {
+			repr = append(repr, "..."...)
+			repr = append(repr, *(*sliceType)(unsafe.Pointer(t)).elem.string...)
 		} else {
-			gc.appendWord(bitsIface)
+			repr = append(repr, *t.string...)
 		}
+	}
+	repr = append(repr, ')')
+	if l := len(ft.out); l == 1 {
+		repr = append(repr, ' ')
+	} else if l > 1 {
+		repr = append(repr, " ("...)
+	}
+	for i, t := range ft.out {
+		if i > 0 {
+			repr = append(repr, ", "...)
+		}
+		repr = append(repr, *t.string...)
+	}
+	if len(ft.out) > 1 {
+		repr = append(repr, ')')
+	}
+	return string(repr)
+}
+
+// isReflexive reports whether the == operation on the type is reflexive.
+// That is, x == x for all values x of type t.
+func isReflexive(t *rtype) bool {
+	switch t.Kind() {
+	case Bool, Int, Int8, Int16, Int32, Int64, Uint, Uint8, Uint16, Uint32, Uint64, Uintptr, Chan, Ptr, String, UnsafePointer:
+		return true
+	case Float32, Float64, Complex64, Complex128, Interface:
+		return false
+	case Array:
+		tt := (*arrayType)(unsafe.Pointer(t))
+		return isReflexive(tt.elem)
 	case Struct:
-		c := t.NumField()
-		for i := 0; i < c; i++ {
-			gc.appendProg(t.Field(i).Type.common())
+		tt := (*structType)(unsafe.Pointer(t))
+		for _, f := range tt.fields {
+			if !isReflexive(f.typ) {
+				return false
+			}
 		}
-		gc.align(uintptr(t.align))
+		return true
+	default:
+		// Func, Map, Slice, Invalid
+		panic("isReflexive called on non-key type " + t.String())
 	}
 }
 
-func (gc *gcProg) appendWord(v byte) {
-	ptrsize := unsafe.Sizeof(uintptr(0))
-	if gc.size%ptrsize != 0 {
-		panic("reflect: unaligned GC program")
-	}
-	nptr := gc.size / ptrsize
-	for uintptr(len(gc.gc)) < nptr/2+1 {
-		gc.gc = append(gc.gc, 0x44) // BitsScalar
-	}
-	gc.gc[nptr/2] &= ^(3 << ((nptr%2)*4 + 2))
-	gc.gc[nptr/2] |= v << ((nptr%2)*4 + 2)
-	gc.size += ptrsize
-	if v == bitsPointer {
-		gc.hasPtr = true
-	}
-}
-
-func (gc *gcProg) finalize() (unsafe.Pointer, bool) {
-	if gc.size == 0 {
-		return nil, false
-	}
-	ptrsize := unsafe.Sizeof(uintptr(0))
-	gc.align(ptrsize)
-	nptr := gc.size / ptrsize
-	for uintptr(len(gc.gc)) < nptr/2+1 {
-		gc.gc = append(gc.gc, 0x44) // BitsScalar
-	}
-	// If number of words is odd, repeat the mask twice.
-	// Compiler does the same.
-	if nptr%2 != 0 {
-		for i := uintptr(0); i < nptr; i++ {
-			gc.appendWord(extractGCWord(gc.gc, i))
-		}
-	}
-	return unsafe.Pointer(&gc.gc[0]), gc.hasPtr
-}
-
-func extractGCWord(gc []byte, i uintptr) byte {
-	return (gc[i/2] >> ((i%2)*4 + 2)) & 3
-}
-
-func (gc *gcProg) align(a uintptr) {
-	gc.size = align(gc.size, a)
-}
-
-// These constants must stay in sync with ../runtime/mgc0.h.
-const (
-	bitsScalar    = 1
-	bitsPointer   = 2
-	bitsMultiWord = 3
-
-	bitsIface = 2
-	bitsEface = 3
-)
-
 // Make sure these routines stay in sync with ../../runtime/hashmap.go!
 // These types exist only for GC, so we only fill out GC relevant info.
 // Currently, that's just size and the GC program.  We also fill in string
 // for possible debugging use.
 const (
-	bucketSize = 8
-	maxKeySize = 128
-	maxValSize = 128
+	bucketSize uintptr = 8
+	maxKeySize uintptr = 128
+	maxValSize uintptr = 128
 )
 
 func bucketOf(ktyp, etyp *rtype) *rtype {
+	// See comment on hmap.overflow in ../runtime/hashmap.go.
+	var kind uint8
+	if ktyp.kind&kindNoPointers != 0 && etyp.kind&kindNoPointers != 0 &&
+		ktyp.size <= maxKeySize && etyp.size <= maxValSize {
+		kind = kindNoPointers
+	}
+
 	if ktyp.size > maxKeySize {
 		ktyp = PtrTo(ktyp).(*rtype)
 	}
 	if etyp.size > maxValSize {
 		etyp = PtrTo(etyp).(*rtype)
 	}
-	ptrsize := unsafe.Sizeof(uintptr(0))
 
-	var gc gcProg
-	// topbits
-	for i := 0; i < int(bucketSize*unsafe.Sizeof(uint8(0))/ptrsize); i++ {
-		gc.append(bitsScalar)
+	// Prepare GC data if any.
+	// A bucket is at most bucketSize*(1+maxKeySize+maxValSize)+2*ptrSize bytes,
+	// or 2072 bytes, or 259 pointer-size words, or 33 bytes of pointer bitmap.
+	// Normally the enforced limit on pointer maps is 16 bytes,
+	// but larger ones are acceptable, 33 bytes isn't too too big,
+	// and it's easier to generate a pointer bitmap than a GC program.
+	// Note that since the key and value are known to be <= 128 bytes,
+	// they're guaranteed to have bitmaps instead of GC programs.
+	// var gcdata *byte
+	var ptrdata uintptr
+	var overflowPad uintptr
+
+	// On NaCl, pad if needed to make overflow end at the proper struct alignment.
+	// On other systems, align > ptrSize is not possible.
+	if runtime.GOARCH == "amd64p32" && (ktyp.align > ptrSize || etyp.align > ptrSize) {
+		overflowPad = ptrSize
 	}
-	// keys
-	for i := 0; i < bucketSize; i++ {
-		gc.appendProg(ktyp)
+	size := bucketSize*(1+ktyp.size+etyp.size) + overflowPad + ptrSize
+	if size&uintptr(ktyp.align-1) != 0 || size&uintptr(etyp.align-1) != 0 {
+		panic("reflect: bad size computation in MapOf")
 	}
-	// values
-	for i := 0; i < bucketSize; i++ {
-		gc.appendProg(etyp)
-	}
-	// overflow
-	gc.append(bitsPointer)
-	if runtime.GOARCH == "amd64p32" {
-		gc.append(bitsScalar)
+
+	if kind != kindNoPointers {
+		nptr := (bucketSize*(1+ktyp.size+etyp.size) + ptrSize) / ptrSize
+		mask := make([]byte, (nptr+7)/8)
+		base := bucketSize / ptrSize
+
+		if ktyp.kind&kindNoPointers == 0 {
+			if ktyp.kind&kindGCProg != 0 {
+				panic("reflect: unexpected GC program in MapOf")
+			}
+			kmask := (*[16]byte)(unsafe.Pointer( /*ktyp.gcdata*/ nil))
+			for i := uintptr(0); i < ktyp.size/ptrSize; i++ {
+				if (kmask[i/8]>>(i%8))&1 != 0 {
+					for j := uintptr(0); j < bucketSize; j++ {
+						word := base + j*ktyp.size/ptrSize + i
+						mask[word/8] |= 1 << (word % 8)
+					}
+				}
+			}
+		}
+		base += bucketSize * ktyp.size / ptrSize
+
+		if etyp.kind&kindNoPointers == 0 {
+			if etyp.kind&kindGCProg != 0 {
+				panic("reflect: unexpected GC program in MapOf")
+			}
+			emask := (*[16]byte)(unsafe.Pointer( /*etyp.gcdata*/ nil))
+			for i := uintptr(0); i < etyp.size/ptrSize; i++ {
+				if (emask[i/8]>>(i%8))&1 != 0 {
+					for j := uintptr(0); j < bucketSize; j++ {
+						word := base + j*etyp.size/ptrSize + i
+						mask[word/8] |= 1 << (word % 8)
+					}
+				}
+			}
+		}
+		base += bucketSize * etyp.size / ptrSize
+		base += overflowPad / ptrSize
+
+		word := base
+		mask[word/8] |= 1 << (word % 8)
+		// gcdata = &mask[0]
+		ptrdata = (word + 1) * ptrSize
+
+		// overflow word must be last
+		if ptrdata != size {
+			panic("reflect: bad layout computation in MapOf")
+		}
 	}
 
 	b := new(rtype)
-	b.size = gc.size
+	// b.size = gc.size
 	// b.gc[0], _ = gc.finalize()
 	b.kind |= kindGCProg
 	s := "bucket(" + *ktyp.string + "," + *etyp.string + ")"
@@ -1848,7 +1951,6 @@
 	slice.elem = typ
 	slice.uncommonType = nil
 	slice.ptrToThis = nil
-	slice.zero = unsafe.Pointer(&make([]byte, slice.size)[0])
 
 	if typ.size == 0 {
 		slice.gc = unsafe.Pointer(&sliceEmptyGCProg)
@@ -1868,24 +1970,25 @@
 	return cachePut(ckey, &slice.rtype)
 }
 
+// See cmd/compile/internal/gc/reflect.go for derivation of constant.
+const maxPtrmaskBytes = 2048
+
 // ArrayOf returns the array type with the given count and element type.
 // For example, if t represents int, ArrayOf(5, t) represents [5]int.
 //
 // If the resulting type would be larger than the available address space,
 // ArrayOf panics.
-//
-// TODO(rsc): Unexported for now. Export once the alg field is set correctly
-// for the type. This may require significant work.
-//
-// TODO(rsc): TestArrayOf is also disabled. Re-enable.
-func arrayOf(count int, elem Type) Type {
+func ArrayOf(count int, elem Type) Type {
 	typ := elem.(*rtype)
+	// call SliceOf here as it calls cacheGet/cachePut.
+	// ArrayOf also calls cacheGet/cachePut and thus may modify the state of
+	// the lookupCache mutex.
 	slice := SliceOf(elem)
 
 	// Look in cache.
 	ckey := cacheKey{Array, typ, nil, uintptr(count)}
-	if slice := cacheGet(ckey); slice != nil {
-		return slice
+	if array := cacheGet(ckey); array != nil {
+		return array
 	}
 
 	// Look in known types.
@@ -1896,7 +1999,6 @@
 	prototype := *(**arrayType)(unsafe.Pointer(&iarray))
 	array := new(arrayType)
 	*array = *prototype
-	// TODO: Set extra kind bits correctly.
 	array.string = &s
 
 	// gccgo uses a different hash.
@@ -1913,20 +2015,70 @@
 		panic("reflect.ArrayOf: array size would exceed virtual address space")
 	}
 	array.size = typ.size * uintptr(count)
+	// if count > 0 && typ.ptrdata != 0 {
+	// 	array.ptrdata = typ.size*uintptr(count-1) + typ.ptrdata
+	// }
 	array.align = typ.align
 	array.fieldAlign = typ.fieldAlign
-	// TODO: array.alg
-	// TODO: array.gc
-	// TODO:
 	array.uncommonType = nil
 	array.ptrToThis = nil
-	array.zero = unsafe.Pointer(&make([]byte, array.size)[0])
 	array.len = uintptr(count)
 	array.slice = slice.(*rtype)
 
+	array.kind &^= kindNoPointers
+	switch {
+	case typ.kind&kindNoPointers != 0 || array.size == 0:
+		// No pointers.
+		array.kind |= kindNoPointers
+		gc := [...]uintptr{array.size, _GC_END}
+		array.gc = unsafe.Pointer(&gc[0])
+
+	case count == 1:
+		// In memory, 1-element array looks just like the element.
+		array.kind |= typ.kind & kindGCProg
+		array.gc = typ.gc
+
+	default:
+		gc := []uintptr{array.size, _GC_ARRAY_START, 0, uintptr(count), typ.size}
+		gc = appendGCProgram(gc, typ)
+		gc = append(gc, _GC_ARRAY_NEXT, _GC_END)
+		array.gc = unsafe.Pointer(&gc[0])
+	}
+
+	array.kind &^= kindDirectIface
+
+	array.hashfn = func(p unsafe.Pointer, size uintptr) uintptr {
+		ret := uintptr(0)
+		for i := 0; i < count; i++ {
+			ret *= 33
+			ret += typ.hashfn(p, typ.size)
+			p = unsafe.Pointer(uintptr(p) + typ.size)
+		}
+		return ret
+	}
+
+	array.equalfn = func(p1, p2 unsafe.Pointer, size uintptr) bool {
+		for i := 0; i < count; i++ {
+			if !typ.equalfn(p1, p2, typ.size) {
+				return false
+			}
+			p1 = unsafe.Pointer(uintptr(p1) + typ.size)
+			p2 = unsafe.Pointer(uintptr(p2) + typ.size)
+		}
+		return true
+	}
+
 	return cachePut(ckey, &array.rtype)
 }
 
+func appendVarint(x []byte, v uintptr) []byte {
+	for ; v >= 0x80; v >>= 7 {
+		x = append(x, byte(v|0x80))
+	}
+	x = append(x, byte(v))
+	return x
+}
+
 // toType converts from a *rtype to a Type that can be returned
 // to the client of package reflect. In gc, the only concern is that
 // a nil *rtype must be replaced by a nil Type, but in gccgo this
@@ -1940,13 +2092,7 @@
 	if t == nil {
 		return nil
 	}
-	u := t.uncommon()
-	var s string
-	if u == nil || u.PkgPath() == "" {
-		s = t.rawString()
-	} else {
-		s = u.PkgPath() + "." + u.Name()
-	}
+	s := t.rawString()
 	canonicalTypeLock.RLock()
 	if r, ok := canonicalType[s]; ok {
 		canonicalTypeLock.RUnlock()
@@ -1981,56 +2127,49 @@
 	data []byte
 }
 
-// append a bit pair to the bitmap.
-func (bv *bitVector) append2(bits uint8) {
-	// assume bv.n is a multiple of 2, since append2 is the only operation.
+// append a bit to the bitmap.
+func (bv *bitVector) append(bit uint8) {
 	if bv.n%8 == 0 {
 		bv.data = append(bv.data, 0)
 	}
-	bv.data[bv.n/8] |= bits << (bv.n % 8)
-	bv.n += 2
+	bv.data[bv.n/8] |= bit << (bv.n % 8)
+	bv.n++
 }
 
-func addTypeBits(bv *bitVector, offset *uintptr, t *rtype) {
-	*offset = align(*offset, uintptr(t.align))
+func addTypeBits(bv *bitVector, offset uintptr, t *rtype) {
 	if t.kind&kindNoPointers != 0 {
-		*offset += t.size
 		return
 	}
 
 	switch Kind(t.kind & kindMask) {
 	case Chan, Func, Map, Ptr, Slice, String, UnsafePointer:
 		// 1 pointer at start of representation
-		for bv.n < 2*uint32(*offset/uintptr(ptrSize)) {
-			bv.append2(bitsScalar)
+		for bv.n < uint32(offset/uintptr(ptrSize)) {
+			bv.append(0)
 		}
-		bv.append2(bitsPointer)
+		bv.append(1)
 
 	case Interface:
 		// 2 pointers
-		for bv.n < 2*uint32(*offset/uintptr(ptrSize)) {
-			bv.append2(bitsScalar)
+		for bv.n < uint32(offset/uintptr(ptrSize)) {
+			bv.append(0)
 		}
-		bv.append2(bitsPointer)
-		bv.append2(bitsPointer)
+		bv.append(1)
+		bv.append(1)
 
 	case Array:
 		// repeat inner type
 		tt := (*arrayType)(unsafe.Pointer(t))
 		for i := 0; i < int(tt.len); i++ {
-			addTypeBits(bv, offset, tt.elem)
+			addTypeBits(bv, offset+uintptr(i)*tt.elem.size, tt.elem)
 		}
 
 	case Struct:
 		// apply fields
 		tt := (*structType)(unsafe.Pointer(t))
-		start := *offset
 		for i := range tt.fields {
 			f := &tt.fields[i]
-			off := start + f.offset
-			addTypeBits(bv, &off, f.typ)
+			addTypeBits(bv, offset+f.offset, f.typ)
 		}
 	}
-
-	*offset += t.size
 }
diff --git a/third_party/gofrontend/libgo/go/reflect/value.go b/third_party/gofrontend/libgo/go/reflect/value.go
index 7cc4f7f..8374370 100644
--- a/third_party/gofrontend/libgo/go/reflect/value.go
+++ b/third_party/gofrontend/libgo/go/reflect/value.go
@@ -10,7 +10,7 @@
 	"unsafe"
 )
 
-const ptrSize = unsafe.Sizeof((*byte)(nil))
+const ptrSize = 4 << (^uintptr(0) >> 63) // unsafe.Sizeof(uintptr(0)) but an ideal const
 const cannotSet = "cannot set value obtained from unexported struct field"
 
 // Value is the reflection interface to a Go value.
@@ -30,6 +30,10 @@
 // A Value can be used concurrently by multiple goroutines provided that
 // the underlying Go value can be used concurrently for the equivalent
 // direct operations.
+//
+// Using == on two Values does not compare the underlying values
+// they represent, but rather the contents of the Value structs.
+// To compare two Values, compare the results of the Interface method.
 type Value struct {
 	// typ holds the type of the value represented by a Value.
 	typ *rtype
@@ -40,7 +44,8 @@
 
 	// flag holds metadata about the value.
 	// The lowest bits are flag bits:
-	//	- flagRO: obtained via unexported field, so read-only
+	//	- flagStickyRO: obtained via unexported not embedded field, so read-only
+	//	- flagEmbedRO: obtained via unexported embedded field, so read-only
 	//	- flagIndir: val holds a pointer to the data
 	//	- flagAddr: v.CanAddr is true (implies flagIndir)
 	//	- flagMethod: v is a method value.
@@ -63,12 +68,14 @@
 const (
 	flagKindWidth        = 5 // there are 27 kinds
 	flagKindMask    flag = 1<<flagKindWidth - 1
-	flagRO          flag = 1 << 5
-	flagIndir       flag = 1 << 6
-	flagAddr        flag = 1 << 7
-	flagMethod      flag = 1 << 8
-	flagMethodFn    flag = 1 << 9 // gccgo: first fn parameter is always pointer
-	flagMethodShift      = 10
+	flagStickyRO    flag = 1 << 5
+	flagEmbedRO     flag = 1 << 6
+	flagIndir       flag = 1 << 7
+	flagAddr        flag = 1 << 8
+	flagMethod      flag = 1 << 9
+	flagMethodFn    flag = 1 << 10 // gccgo: first fn parameter is always pointer
+	flagMethodShift      = 11
+	flagRO          flag = flagStickyRO | flagEmbedRO
 )
 
 func (f flag) kind() Kind {
@@ -104,7 +111,7 @@
 			// TODO: pass safe boolean from valueInterface so
 			// we don't need to copy if safe==true?
 			c := unsafe_New(t)
-			memmove(c, ptr, t.size)
+			typedmemmove(t, c, ptr)
 			ptr = c
 		}
 		e.word = ptr
@@ -173,7 +180,7 @@
 
 // nonEmptyInterface is the header for a interface value with methods.
 type nonEmptyInterface struct {
-	// see ../runtime/iface.c:/Itab
+	// see ../runtime/iface.go:/Itab
 	itab *struct {
 		typ *rtype                 // dynamic concrete type
 		fun [100000]unsafe.Pointer // method table
@@ -261,7 +268,7 @@
 	return *(*[]rune)(v.ptr)
 }
 
-// CanAddr returns true if the value's address can be obtained with Addr.
+// CanAddr reports whether the value's address can be obtained with Addr.
 // Such values are called addressable.  A value is addressable if it is
 // an element of a slice, an element of an addressable array,
 // a field of an addressable struct, or the result of dereferencing a pointer.
@@ -270,11 +277,11 @@
 	return v.flag&flagAddr != 0
 }
 
-// CanSet returns true if the value of v can be changed.
+// CanSet reports whether the value of v can be changed.
 // A Value can be changed only if it is addressable and was not
 // obtained by the use of unexported struct fields.
 // If CanSet returns false, calling Set or any type-specific
-// setter (e.g., SetBool, SetInt64) will panic.
+// setter (e.g., SetBool, SetInt) will panic.
 func (v Value) CanSet() bool {
 	return v.flag&(flagAddr|flagRO) == flagAddr
 }
@@ -295,8 +302,8 @@
 
 // CallSlice calls the variadic function v with the input arguments in,
 // assigning the slice in[len(in)-1] to v's final variadic argument.
-// For example, if len(in) == 3, v.Call(in) represents the Go call v(in[0], in[1], in[2]...).
-// Call panics if v's Kind is not Func or if v is not variadic.
+// For example, if len(in) == 3, v.CallSlice(in) represents the Go call v(in[0], in[1], in[2]...).
+// CallSlice panics if v's Kind is not Func or if v is not variadic.
 // It returns the output results as Values.
 // As in Go, each input argument must be assignable to the
 // type of the function's corresponding input parameter.
@@ -613,16 +620,20 @@
 	field := &tt.fields[i]
 	typ := field.typ
 
-	// Inherit permission bits from v.
-	fl := v.flag&(flagRO|flagIndir|flagAddr) | flag(typ.Kind())
+	// Inherit permission bits from v, but clear flagEmbedRO.
+	fl := v.flag&(flagStickyRO|flagIndir|flagAddr) | flag(typ.Kind())
 	// Using an unexported field forces flagRO.
 	if field.pkgPath != nil {
-		fl |= flagRO
+		if field.name == nil {
+			fl |= flagEmbedRO
+		} else {
+			fl |= flagStickyRO
+		}
 	}
 	// Either flagIndir is set and v.ptr points at struct,
 	// or flagIndir is not set and v.ptr is the actual struct data.
 	// In the former case, we want v.ptr + offset.
-	// In the latter case, we must be have field.offset = 0,
+	// In the latter case, we must have field.offset = 0,
 	// so v.ptr + field.offset is still okay.
 	ptr := unsafe.Pointer(uintptr(v.ptr) + field.offset)
 	return Value{typ, ptr, fl}
@@ -716,7 +727,7 @@
 		}
 		tt := (*sliceType)(unsafe.Pointer(v.typ))
 		typ := tt.elem
-		val := unsafe.Pointer(uintptr(s.Data) + uintptr(i)*typ.size)
+		val := arrayAt(s.Data, i, typ.size)
 		fl := flagAddr | flagIndir | v.flag&flagRO | flag(typ.Kind())
 		return Value{typ, val, fl}
 
@@ -725,7 +736,7 @@
 		if uint(i) >= uint(s.Len) {
 			panic("reflect: string index out of range")
 		}
-		p := unsafe.Pointer(uintptr(s.Data) + uintptr(i))
+		p := arrayAt(s.Data, i, 1)
 		fl := v.flag&flagRO | flag(Uint8) | flagIndir
 		return Value{uint8Type, p, fl}
 	}
@@ -752,7 +763,7 @@
 	panic(&ValueError{"reflect.Value.Int", v.kind()})
 }
 
-// CanInterface returns true if Interface can be used without panicking.
+// CanInterface reports whether Interface can be used without panicking.
 func (v Value) CanInterface() bool {
 	if v.flag == 0 {
 		panic(&ValueError{"reflect.Value.CanInterface", Invalid})
@@ -849,7 +860,7 @@
 	panic(&ValueError{"reflect.Value.IsNil", v.kind()})
 }
 
-// IsValid returns true if v represents a value.
+// IsValid reports whether v represents a value.
 // It returns false if v is the zero Value.
 // If IsValid returns false, all other methods except String panic.
 // Most functions and methods never return an invalid value.
@@ -920,7 +931,7 @@
 		// Copy result so future changes to the map
 		// won't change the underlying value.
 		c := unsafe_New(typ)
-		memmove(c, e, typ.size)
+		typedmemmove(typ, c, e)
 		return Value{typ, c, fl | flagIndir}
 	} else {
 		return Value{typ, *(*unsafe.Pointer)(e), fl}
@@ -958,7 +969,7 @@
 			// Copy result so future changes to the map
 			// won't change the underlying value.
 			c := unsafe_New(keyType)
-			memmove(c, key, keyType.size)
+			typedmemmove(keyType, c, key)
 			a[i] = Value{keyType, c, fl | flagIndir}
 		} else {
 			a[i] = Value{keyType, *(*unsafe.Pointer)(key), fl}
@@ -982,7 +993,7 @@
 	if v.typ.Kind() == Interface && v.IsNil() {
 		panic("reflect: Method on nil interface value")
 	}
-	fl := v.flag & (flagRO | flagIndir)
+	fl := v.flag & (flagStickyRO | flagIndir) // Clear flagEmbedRO
 	fl |= flag(Func)
 	fl |= flag(i)<<flagMethodShift | flagMethod
 	return Value{v.typ, v.ptr, fl}
@@ -1026,7 +1037,7 @@
 	return len(tt.fields)
 }
 
-// OverflowComplex returns true if the complex128 x cannot be represented by v's type.
+// OverflowComplex reports whether the complex128 x cannot be represented by v's type.
 // It panics if v's Kind is not Complex64 or Complex128.
 func (v Value) OverflowComplex(x complex128) bool {
 	k := v.kind()
@@ -1039,7 +1050,7 @@
 	panic(&ValueError{"reflect.Value.OverflowComplex", v.kind()})
 }
 
-// OverflowFloat returns true if the float64 x cannot be represented by v's type.
+// OverflowFloat reports whether the float64 x cannot be represented by v's type.
 // It panics if v's Kind is not Float32 or Float64.
 func (v Value) OverflowFloat(x float64) bool {
 	k := v.kind()
@@ -1059,7 +1070,7 @@
 	return math.MaxFloat32 < x && x <= math.MaxFloat64
 }
 
-// OverflowInt returns true if the int64 x cannot be represented by v's type.
+// OverflowInt reports whether the int64 x cannot be represented by v's type.
 // It panics if v's Kind is not Int, Int8, int16, Int32, or Int64.
 func (v Value) OverflowInt(x int64) bool {
 	k := v.kind()
@@ -1072,7 +1083,7 @@
 	panic(&ValueError{"reflect.Value.OverflowInt", v.kind()})
 }
 
-// OverflowUint returns true if the uint64 x cannot be represented by v's type.
+// OverflowUint reports whether the uint64 x cannot be represented by v's type.
 // It panics if v's Kind is not Uint, Uintptr, Uint8, Uint16, Uint32, or Uint64.
 func (v Value) OverflowUint(x uint64) bool {
 	k := v.kind()
@@ -1194,7 +1205,7 @@
 	}
 	x = x.assignTo("reflect.Set", v.typ, target)
 	if x.flag&flagIndir != 0 {
-		memmove(v.ptr, x.ptr, v.typ.size)
+		typedmemmove(v.typ, v.ptr, x.ptr)
 	} else {
 		*(*unsafe.Pointer)(v.ptr) = x.ptr
 	}
@@ -1408,7 +1419,7 @@
 		if i < 0 || j < i || j > s.Len {
 			panic("reflect.Value.Slice: string slice index out of bounds")
 		}
-		t := stringHeader{unsafe.Pointer(uintptr(s.Data) + uintptr(i)), j - i}
+		t := stringHeader{arrayAt(s.Data, i, 1), j - i}
 		return Value{v.typ, unsafe.Pointer(&t), v.flag}
 	}
 
@@ -1424,7 +1435,7 @@
 	s.Len = j - i
 	s.Cap = cap - i
 	if cap-i > 0 {
-		s.Data = unsafe.Pointer(uintptr(base) + uintptr(i)*typ.elem.Size())
+		s.Data = arrayAt(base, i, typ.elem.Size())
 	} else {
 		// do not advance pointer, to avoid pointing beyond end of slice
 		s.Data = base
@@ -1476,7 +1487,7 @@
 	s.Len = j - i
 	s.Cap = k - i
 	if k-i > 0 {
-		s.Data = unsafe.Pointer(uintptr(base) + uintptr(i)*typ.elem.Size())
+		s.Data = arrayAt(base, i, typ.elem.Size())
 	} else {
 		// do not advance pointer, to avoid pointing beyond end of slice
 		s.Data = base
@@ -1490,6 +1501,8 @@
 // String is a special case because of Go's String method convention.
 // Unlike the other getters, it does not panic if v's Kind is not String.
 // Instead, it returns a string of the form "<T value>" where T is v's type.
+// The fmt package treats Values specially. It does not call their String
+// method implicitly but instead prints the concrete values they hold.
 func (v Value) String() string {
 	switch k := v.kind(); k {
 	case Invalid:
@@ -1515,7 +1528,7 @@
 
 // TrySend attempts to send x on the channel v but will not block.
 // It panics if v's Kind is not Chan.
-// It returns true if the value was sent, false otherwise.
+// It reports whether the value was sent.
 // As in Go, x's value must be assignable to the channel's element type.
 func (v Value) TrySend(x Value) bool {
 	v.mustBe(Chan)
@@ -1633,6 +1646,12 @@
 	}
 }
 
+// arrayAt returns the i-th element of p, a C-array whose elements are
+// eltSize wide (in bytes).
+func arrayAt(p unsafe.Pointer, i int, eltSize uintptr) unsafe.Pointer {
+	return unsafe.Pointer(uintptr(p) + uintptr(i)*eltSize)
+}
+
 // grow grows the slice s so that it can hold extra more values, allocating
 // more capacity if needed. It also returns the old and new slice lengths.
 func grow(s Value, extra int) (Value, int, int) {
@@ -1708,27 +1727,23 @@
 	se := src.typ.Elem()
 	typesMustMatch("reflect.Copy", de, se)
 
-	n := dst.Len()
-	if sn := src.Len(); n > sn {
-		n = sn
+	var ds, ss sliceHeader
+	if dk == Array {
+		ds.Data = dst.ptr
+		ds.Len = dst.Len()
+		ds.Cap = ds.Len
+	} else {
+		ds = *(*sliceHeader)(dst.ptr)
+	}
+	if sk == Array {
+		ss.Data = src.ptr
+		ss.Len = src.Len()
+		ss.Cap = ss.Len
+	} else {
+		ss = *(*sliceHeader)(src.ptr)
 	}
 
-	// Copy via memmove.
-	var da, sa unsafe.Pointer
-	if dk == Array {
-		da = dst.ptr
-	} else {
-		da = (*sliceHeader)(dst.ptr).Data
-	}
-	if src.flag&flagIndir == 0 {
-		sa = unsafe.Pointer(&src.ptr)
-	} else if sk == Array {
-		sa = src.ptr
-	} else {
-		sa = (*sliceHeader)(src.ptr).Data
-	}
-	memmove(da, sa, uintptr(n)*de.Size())
-	return n
+	return typedslicecopy(de.common(), ds, ss)
 }
 
 // A runtimeSelect is a single case passed to rselect.
@@ -2269,7 +2284,7 @@
 	if f&flagAddr != 0 {
 		// indirect, mutable word - make a copy
 		c := unsafe_New(t)
-		memmove(c, ptr, t.size)
+		typedmemmove(t, c, ptr)
 		ptr = c
 		f &^= flagAddr
 	}
@@ -2311,17 +2326,41 @@
 
 func makechan(typ *rtype, size uint64) (ch unsafe.Pointer)
 func makemap(t *rtype) (m unsafe.Pointer)
+
+//go:noescape
 func mapaccess(t *rtype, m unsafe.Pointer, key unsafe.Pointer) (val unsafe.Pointer)
+
 func mapassign(t *rtype, m unsafe.Pointer, key, val unsafe.Pointer)
+
+//go:noescape
 func mapdelete(t *rtype, m unsafe.Pointer, key unsafe.Pointer)
+
+// m escapes into the return value, but the caller of mapiterinit
+// doesn't let the return value escape.
+//go:noescape
 func mapiterinit(t *rtype, m unsafe.Pointer) unsafe.Pointer
+
+//go:noescape
 func mapiterkey(it unsafe.Pointer) (key unsafe.Pointer)
+
+//go:noescape
 func mapiternext(it unsafe.Pointer)
+
+//go:noescape
 func maplen(m unsafe.Pointer) int
 func call(typ *rtype, fnaddr unsafe.Pointer, isInterface bool, isMethod bool, params *unsafe.Pointer, results *unsafe.Pointer)
 
 func ifaceE2I(t *rtype, src interface{}, dst unsafe.Pointer)
 
+// typedmemmove copies a value of type t to dst from src.
+//go:noescape
+func typedmemmove(t *rtype, dst, src unsafe.Pointer)
+
+// typedslicecopy copies a slice of elemType values from src to dst,
+// returning the number of elements copied.
+//go:noescape
+func typedslicecopy(elemType *rtype, dst, src sliceHeader) int
+
 //go:noescape
 //extern memmove
 func memmove(adst, asrc unsafe.Pointer, n uintptr)
diff --git a/third_party/gofrontend/libgo/go/regexp/all_test.go b/third_party/gofrontend/libgo/go/regexp/all_test.go
index 01ea374..d78ae6a 100644
--- a/third_party/gofrontend/libgo/go/regexp/all_test.go
+++ b/third_party/gofrontend/libgo/go/regexp/all_test.go
@@ -489,6 +489,17 @@
 	}
 }
 
+// Check that the same machine can be used with the standard matcher
+// and then the backtracker when there are no captures.
+func TestSwitchBacktrack(t *testing.T) {
+	re := MustCompile(`a|b`)
+	long := make([]byte, maxBacktrackVector+1)
+
+	// The following sequence of Match calls used to panic. See issue #10319.
+	re.Match(long)     // triggers standard matcher
+	re.Match(long[:1]) // triggers backtracker
+}
+
 func BenchmarkLiteral(b *testing.B) {
 	x := strings.Repeat("x", 50) + "y"
 	b.StopTimer()
diff --git a/third_party/gofrontend/libgo/go/regexp/backtrack.go b/third_party/gofrontend/libgo/go/regexp/backtrack.go
new file mode 100644
index 0000000..fd95604
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/regexp/backtrack.go
@@ -0,0 +1,366 @@
+// 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.
+
+// backtrack is a regular expression search with submatch
+// tracking for small regular expressions and texts. It allocates
+// a bit vector with (length of input) * (length of prog) bits,
+// to make sure it never explores the same (character position, instruction)
+// state multiple times. This limits the search to run in time linear in
+// the length of the test.
+//
+// backtrack is a fast replacement for the NFA code on small
+// regexps when onepass cannot be used.
+
+package regexp
+
+import "regexp/syntax"
+
+// A job is an entry on the backtracker's job stack. It holds
+// the instruction pc and the position in the input.
+type job struct {
+	pc  uint32
+	arg int
+	pos int
+}
+
+const (
+	visitedBits        = 32
+	maxBacktrackProg   = 500        // len(prog.Inst) <= max
+	maxBacktrackVector = 256 * 1024 // bit vector size <= max (bits)
+)
+
+// bitState holds state for the backtracker.
+type bitState struct {
+	prog *syntax.Prog
+
+	end     int
+	cap     []int
+	input   input
+	jobs    []job
+	visited []uint32
+}
+
+var notBacktrack *bitState = nil
+
+// maxBitStateLen returns the maximum length of a string to search with
+// the backtracker using prog.
+func maxBitStateLen(prog *syntax.Prog) int {
+	if !shouldBacktrack(prog) {
+		return 0
+	}
+	return maxBacktrackVector / len(prog.Inst)
+}
+
+// newBitState returns a new bitState for the given prog,
+// or notBacktrack if the size of the prog exceeds the maximum size that
+// the backtracker will be run for.
+func newBitState(prog *syntax.Prog) *bitState {
+	if !shouldBacktrack(prog) {
+		return notBacktrack
+	}
+	return &bitState{
+		prog: prog,
+	}
+}
+
+// shouldBacktrack reports whether the program is too
+// long for the backtracker to run.
+func shouldBacktrack(prog *syntax.Prog) bool {
+	return len(prog.Inst) <= maxBacktrackProg
+}
+
+// reset resets the state of the backtracker.
+// end is the end position in the input.
+// ncap is the number of captures.
+func (b *bitState) reset(end int, ncap int) {
+	b.end = end
+
+	if cap(b.jobs) == 0 {
+		b.jobs = make([]job, 0, 256)
+	} else {
+		b.jobs = b.jobs[:0]
+	}
+
+	visitedSize := (len(b.prog.Inst)*(end+1) + visitedBits - 1) / visitedBits
+	if cap(b.visited) < visitedSize {
+		b.visited = make([]uint32, visitedSize, maxBacktrackVector/visitedBits)
+	} else {
+		b.visited = b.visited[:visitedSize]
+		for i := range b.visited {
+			b.visited[i] = 0
+		}
+	}
+
+	if cap(b.cap) < ncap {
+		b.cap = make([]int, ncap)
+	} else {
+		b.cap = b.cap[:ncap]
+	}
+	for i := range b.cap {
+		b.cap[i] = -1
+	}
+}
+
+// shouldVisit reports whether the combination of (pc, pos) has not
+// been visited yet.
+func (b *bitState) shouldVisit(pc uint32, pos int) bool {
+	n := uint(int(pc)*(b.end+1) + pos)
+	if b.visited[n/visitedBits]&(1<<(n&(visitedBits-1))) != 0 {
+		return false
+	}
+	b.visited[n/visitedBits] |= 1 << (n & (visitedBits - 1))
+	return true
+}
+
+// push pushes (pc, pos, arg) onto the job stack if it should be
+// visited.
+func (b *bitState) push(pc uint32, pos int, arg int) {
+	if b.prog.Inst[pc].Op == syntax.InstFail {
+		return
+	}
+
+	// Only check shouldVisit when arg == 0.
+	// When arg > 0, we are continuing a previous visit.
+	if arg == 0 && !b.shouldVisit(pc, pos) {
+		return
+	}
+
+	b.jobs = append(b.jobs, job{pc: pc, arg: arg, pos: pos})
+}
+
+// tryBacktrack runs a backtracking search starting at pos.
+func (m *machine) tryBacktrack(b *bitState, i input, pc uint32, pos int) bool {
+	longest := m.re.longest
+	m.matched = false
+
+	b.push(pc, pos, 0)
+	for len(b.jobs) > 0 {
+		l := len(b.jobs) - 1
+		// Pop job off the stack.
+		pc := b.jobs[l].pc
+		pos := b.jobs[l].pos
+		arg := b.jobs[l].arg
+		b.jobs = b.jobs[:l]
+
+		// Optimization: rather than push and pop,
+		// code that is going to Push and continue
+		// the loop simply updates ip, p, and arg
+		// and jumps to CheckAndLoop.  We have to
+		// do the ShouldVisit check that Push
+		// would have, but we avoid the stack
+		// manipulation.
+		goto Skip
+	CheckAndLoop:
+		if !b.shouldVisit(pc, pos) {
+			continue
+		}
+	Skip:
+
+		inst := b.prog.Inst[pc]
+
+		switch inst.Op {
+		default:
+			panic("bad inst")
+		case syntax.InstFail:
+			panic("unexpected InstFail")
+		case syntax.InstAlt:
+			// Cannot just
+			//   b.push(inst.Out, pos, 0)
+			//   b.push(inst.Arg, pos, 0)
+			// If during the processing of inst.Out, we encounter
+			// inst.Arg via another path, we want to process it then.
+			// Pushing it here will inhibit that. Instead, re-push
+			// inst with arg==1 as a reminder to push inst.Arg out
+			// later.
+			switch arg {
+			case 0:
+				b.push(pc, pos, 1)
+				pc = inst.Out
+				goto CheckAndLoop
+			case 1:
+				// Finished inst.Out; try inst.Arg.
+				arg = 0
+				pc = inst.Arg
+				goto CheckAndLoop
+			}
+			panic("bad arg in InstAlt")
+
+		case syntax.InstAltMatch:
+			// One opcode consumes runes; the other leads to match.
+			switch b.prog.Inst[inst.Out].Op {
+			case syntax.InstRune, syntax.InstRune1, syntax.InstRuneAny, syntax.InstRuneAnyNotNL:
+				// inst.Arg is the match.
+				b.push(inst.Arg, pos, 0)
+				pc = inst.Arg
+				pos = b.end
+				goto CheckAndLoop
+			}
+			// inst.Out is the match - non-greedy
+			b.push(inst.Out, b.end, 0)
+			pc = inst.Out
+			goto CheckAndLoop
+
+		case syntax.InstRune:
+			r, width := i.step(pos)
+			if !inst.MatchRune(r) {
+				continue
+			}
+			pos += width
+			pc = inst.Out
+			goto CheckAndLoop
+
+		case syntax.InstRune1:
+			r, width := i.step(pos)
+			if r != inst.Rune[0] {
+				continue
+			}
+			pos += width
+			pc = inst.Out
+			goto CheckAndLoop
+
+		case syntax.InstRuneAnyNotNL:
+			r, width := i.step(pos)
+			if r == '\n' || r == endOfText {
+				continue
+			}
+			pos += width
+			pc = inst.Out
+			goto CheckAndLoop
+
+		case syntax.InstRuneAny:
+			r, width := i.step(pos)
+			if r == endOfText {
+				continue
+			}
+			pos += width
+			pc = inst.Out
+			goto CheckAndLoop
+
+		case syntax.InstCapture:
+			switch arg {
+			case 0:
+				if 0 <= inst.Arg && inst.Arg < uint32(len(b.cap)) {
+					// Capture pos to register, but save old value.
+					b.push(pc, b.cap[inst.Arg], 1) // come back when we're done.
+					b.cap[inst.Arg] = pos
+				}
+				pc = inst.Out
+				goto CheckAndLoop
+			case 1:
+				// Finished inst.Out; restore the old value.
+				b.cap[inst.Arg] = pos
+				continue
+
+			}
+			panic("bad arg in InstCapture")
+			continue
+
+		case syntax.InstEmptyWidth:
+			if syntax.EmptyOp(inst.Arg)&^i.context(pos) != 0 {
+				continue
+			}
+			pc = inst.Out
+			goto CheckAndLoop
+
+		case syntax.InstNop:
+			pc = inst.Out
+			goto CheckAndLoop
+
+		case syntax.InstMatch:
+			// We found a match. If the caller doesn't care
+			// where the match is, no point going further.
+			if len(b.cap) == 0 {
+				m.matched = true
+				return m.matched
+			}
+
+			// Record best match so far.
+			// Only need to check end point, because this entire
+			// call is only considering one start position.
+			if len(b.cap) > 1 {
+				b.cap[1] = pos
+			}
+			if !m.matched || (longest && pos > 0 && pos > m.matchcap[1]) {
+				copy(m.matchcap, b.cap)
+			}
+			m.matched = true
+
+			// If going for first match, we're done.
+			if !longest {
+				return m.matched
+			}
+
+			// If we used the entire text, no longer match is possible.
+			if pos == b.end {
+				return m.matched
+			}
+
+			// Otherwise, continue on in hope of a longer match.
+			continue
+		}
+		panic("unreachable")
+	}
+
+	return m.matched
+}
+
+// backtrack runs a backtracking search of prog on the input starting at pos.
+func (m *machine) backtrack(i input, pos int, end int, ncap int) bool {
+	if !i.canCheckPrefix() {
+		panic("backtrack called for a RuneReader")
+	}
+
+	startCond := m.re.cond
+	if startCond == ^syntax.EmptyOp(0) { // impossible
+		return false
+	}
+	if startCond&syntax.EmptyBeginText != 0 && pos != 0 {
+		// Anchored match, past beginning of text.
+		return false
+	}
+
+	b := m.b
+	b.reset(end, ncap)
+
+	m.matchcap = m.matchcap[:ncap]
+	for i := range m.matchcap {
+		m.matchcap[i] = -1
+	}
+
+	// Anchored search must start at the beginning of the input
+	if startCond&syntax.EmptyBeginText != 0 {
+		if len(b.cap) > 0 {
+			b.cap[0] = pos
+		}
+		return m.tryBacktrack(b, i, uint32(m.p.Start), pos)
+	}
+
+	// Unanchored search, starting from each possible text position.
+	// Notice that we have to try the empty string at the end of
+	// the text, so the loop condition is pos <= end, not pos < end.
+	// This looks like it's quadratic in the size of the text,
+	// but we are not clearing visited between calls to TrySearch,
+	// so no work is duplicated and it ends up still being linear.
+	width := -1
+	for ; pos <= end && width != 0; pos += width {
+		if len(m.re.prefix) > 0 {
+			// Match requires literal prefix; fast search for it.
+			advance := i.index(m.re, pos)
+			if advance < 0 {
+				return false
+			}
+			pos += advance
+		}
+
+		if len(b.cap) > 0 {
+			b.cap[0] = pos
+		}
+		if m.tryBacktrack(b, i, uint32(m.p.Start), pos) {
+			// Match must be leftmost; done.
+			return true
+		}
+		_, width = i.step(pos)
+	}
+	return false
+}
diff --git a/third_party/gofrontend/libgo/go/regexp/exec.go b/third_party/gofrontend/libgo/go/regexp/exec.go
index c4cb201..5182720 100644
--- a/third_party/gofrontend/libgo/go/regexp/exec.go
+++ b/third_party/gofrontend/libgo/go/regexp/exec.go
@@ -35,13 +35,15 @@
 
 // A machine holds all the state during an NFA simulation for p.
 type machine struct {
-	re       *Regexp      // corresponding Regexp
-	p        *syntax.Prog // compiled program
-	op       *onePassProg // compiled onepass program, or notOnePass
-	q0, q1   queue        // two queues for runq, nextq
-	pool     []*thread    // pool of available threads
-	matched  bool         // whether a match was found
-	matchcap []int        // capture information for the match
+	re             *Regexp      // corresponding Regexp
+	p              *syntax.Prog // compiled program
+	op             *onePassProg // compiled onepass program, or notOnePass
+	maxBitStateLen int          // max length of string to search with bitstate
+	b              *bitState    // state for backtracker, allocated lazily
+	q0, q1         queue        // two queues for runq, nextq
+	pool           []*thread    // pool of available threads
+	matched        bool         // whether a match was found
+	matchcap       []int        // capture information for the match
 
 	// cached inputs, to avoid allocation
 	inputBytes  inputBytes
@@ -76,6 +78,9 @@
 	if ncap < 2 {
 		ncap = 2
 	}
+	if op == notOnePass {
+		m.maxBitStateLen = maxBitStateLen(p)
+	}
 	m.matchcap = make([]int, ncap)
 	return m
 }
@@ -422,18 +427,29 @@
 func (re *Regexp) doExecute(r io.RuneReader, b []byte, s string, pos int, ncap int) []int {
 	m := re.get()
 	var i input
+	var size int
 	if r != nil {
 		i = m.newInputReader(r)
 	} else if b != nil {
 		i = m.newInputBytes(b)
+		size = len(b)
 	} else {
 		i = m.newInputString(s)
+		size = len(s)
 	}
 	if m.op != notOnePass {
 		if !m.onepass(i, pos) {
 			re.put(m)
 			return nil
 		}
+	} else if size < m.maxBitStateLen && r == nil {
+		if m.b == nil {
+			m.b = newBitState(m.p)
+		}
+		if !m.backtrack(i, pos, size, ncap) {
+			re.put(m)
+			return nil
+		}
 	} else {
 		m.init(ncap)
 		if !m.match(i, pos) {
diff --git a/third_party/gofrontend/libgo/go/regexp/exec_test.go b/third_party/gofrontend/libgo/go/regexp/exec_test.go
index 70d069c..4872cb3 100644
--- a/third_party/gofrontend/libgo/go/regexp/exec_test.go
+++ b/third_party/gofrontend/libgo/go/regexp/exec_test.go
@@ -24,8 +24,8 @@
 // complexity, over all possible strings over a given alphabet,
 // up to a given size.  Rather than try to link with RE2, we read a
 // log file containing the test cases and the expected matches.
-// The log file, re2.txt, is generated by running 'make exhaustive-log'
-// in the open source RE2 distribution.  http://code.google.com/p/re2/
+// The log file, re2-exhaustive.txt, is generated by running 'make log'
+// in the open source RE2 distribution https://github.com/google/re2/.
 //
 // The test file format is a sequence of stanzas like:
 //
@@ -59,8 +59,8 @@
 // a capital letter are test names printed during RE2's test suite
 // and are echoed into t but otherwise ignored.
 //
-// At time of writing, re2.txt is 32 MB but compresses to 760 kB,
-// so we store re2.txt.gz in the repository and decompress it on the fly.
+// At time of writing, re2-exhaustive.txt is 59 MB but compresses to 385 kB,
+// so we store re2-exhaustive.txt.bz2 in the repository and decompress it on the fly.
 //
 func TestRE2Search(t *testing.T) {
 	testRE2(t, "testdata/re2-search.txt")
@@ -326,7 +326,7 @@
 
 // TestFowler runs this package's regexp API against the
 // POSIX regular expression tests collected by Glenn Fowler
-// at http://www2.research.att.com/~gsf/testregex/.
+// at http://www2.research.att.com/~astopen/testregex/testregex.html.
 func TestFowler(t *testing.T) {
 	files, err := filepath.Glob("testdata/*.dat")
 	if err != nil {
@@ -361,7 +361,7 @@
 			break Reading
 		}
 
-		// http://www2.research.att.com/~gsf/man/man1/testregex.html
+		// http://www2.research.att.com/~astopen/man/man1/testregex.html
 		//
 		// INPUT FORMAT
 		//   Input lines may be blank, a comment beginning with #, or a test
@@ -713,3 +713,15 @@
 		t.Errorf("longest match was %q, want %q", g, w)
 	}
 }
+
+// TestProgramTooLongForBacktrack tests that a regex which is too long
+// for the backtracker still executes properly.
+func TestProgramTooLongForBacktrack(t *testing.T) {
+	longRegex := MustCompile(`(one|two|three|four|five|six|seven|eight|nine|ten|eleven|twelve|thirteen|fourteen|fifteen|sixteen|seventeen|eighteen|nineteen|twenty|twentyone|twentytwo|twentythree|twentyfour|twentyfive|twentysix|twentyseven|twentyeight|twentynine|thirty|thirtyone|thirtytwo|thirtythree|thirtyfour|thirtyfive|thirtysix|thirtyseven|thirtyeight|thirtynine|forty|fortyone|fortytwo|fortythree|fortyfour|fortyfive|fortysix|fortyseven|fortyeight|fortynine|fifty|fiftyone|fiftytwo|fiftythree|fiftyfour|fiftyfive|fiftysix|fiftyseven|fiftyeight|fiftynine|sixty|sixtyone|sixtytwo|sixtythree|sixtyfour|sixtyfive|sixtysix|sixtyseven|sixtyeight|sixtynine|seventy|seventyone|seventytwo|seventythree|seventyfour|seventyfive|seventysix|seventyseven|seventyeight|seventynine|eighty|eightyone|eightytwo|eightythree|eightyfour|eightyfive|eightysix|eightyseven|eightyeight|eightynine|ninety|ninetyone|ninetytwo|ninetythree|ninetyfour|ninetyfive|ninetysix|ninetyseven|ninetyeight|ninetynine|onehundred)`)
+	if !longRegex.MatchString("two") {
+		t.Errorf("longRegex.MatchString(\"two\") was false, want true")
+	}
+	if longRegex.MatchString("xxx") {
+		t.Errorf("longRegex.MatchString(\"xxx\") was true, want false")
+	}
+}
diff --git a/third_party/gofrontend/libgo/go/regexp/regexp.go b/third_party/gofrontend/libgo/go/regexp/regexp.go
index b615acd..4e4b412 100644
--- a/third_party/gofrontend/libgo/go/regexp/regexp.go
+++ b/third_party/gofrontend/libgo/go/regexp/regexp.go
@@ -7,9 +7,9 @@
 // The syntax of the regular expressions accepted is the same
 // general syntax used by Perl, Python, and other languages.
 // More precisely, it is the syntax accepted by RE2 and described at
-// http://code.google.com/p/re2/wiki/Syntax, except for \C.
+// https://golang.org/s/re2syntax, except for \C.
 // For an overview of the syntax, run
-//   godoc regexp/syntax
+//   go doc regexp/syntax
 //
 // The regexp implementation provided by this package is
 // guaranteed to run in time linear in the size of the input.
@@ -83,7 +83,7 @@
 	// read-only after Compile
 	expr           string         // as passed to Compile
 	prog           *syntax.Prog   // compiled program
-	onepass        *onePassProg   // onpass program or nil
+	onepass        *onePassProg   // onepass program or nil
 	prefix         string         // required prefix in unanchored matches
 	prefixBytes    []byte         // prefix, as a []byte
 	prefixComplete bool           // prefix is the entire regexp
diff --git a/third_party/gofrontend/libgo/go/regexp/syntax/prog.go b/third_party/gofrontend/libgo/go/regexp/syntax/prog.go
index 29bd282..ae6db31 100644
--- a/third_party/gofrontend/libgo/go/regexp/syntax/prog.go
+++ b/third_party/gofrontend/libgo/go/regexp/syntax/prog.go
@@ -189,7 +189,7 @@
 
 const noMatch = -1
 
-// MatchRune returns true if the instruction matches (and consumes) r.
+// MatchRune reports whether the instruction matches (and consumes) r.
 // It should only be called when i.Op == InstRune.
 func (i *Inst) MatchRune(r rune) bool {
 	return i.MatchRunePos(r) != noMatch
@@ -256,7 +256,7 @@
 		('0' <= r && r <= '9')
 }
 
-// MatchEmptyWidth returns true if the instruction matches
+// MatchEmptyWidth reports whether the instruction matches
 // an empty string between the runes before and after.
 // It should only be called when i.Op == InstEmptyWidth.
 func (i *Inst) MatchEmptyWidth(before rune, after rune) bool {
diff --git a/third_party/gofrontend/libgo/go/regexp/testdata/README b/third_party/gofrontend/libgo/go/regexp/testdata/README
index b1b301b..58cec82 100644
--- a/third_party/gofrontend/libgo/go/regexp/testdata/README
+++ b/third_party/gofrontend/libgo/go/regexp/testdata/README
@@ -19,5 +19,6 @@
 RE2 Test Files
 
 re2-exhaustive.txt.bz2 and re2-search.txt are built by running
-'make log' in the RE2 distribution.  http://code.google.com/p/re2/.
+'make log' in the RE2 distribution https://github.com/google/re2/
+
 The exhaustive file is compressed because it is huge.
diff --git a/third_party/gofrontend/libgo/go/runtime/arch_386.go b/third_party/gofrontend/libgo/go/runtime/arch_386.go
deleted file mode 100644
index 79d38c7..0000000
--- a/third_party/gofrontend/libgo/go/runtime/arch_386.go
+++ /dev/null
@@ -1,8 +0,0 @@
-// 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.
-
-package runtime
-
-type uintreg uint32
-type intptr int32 // TODO(rsc): remove
diff --git a/third_party/gofrontend/libgo/go/runtime/arch_amd64.go b/third_party/gofrontend/libgo/go/runtime/arch_amd64.go
deleted file mode 100644
index 270cd7b..0000000
--- a/third_party/gofrontend/libgo/go/runtime/arch_amd64.go
+++ /dev/null
@@ -1,8 +0,0 @@
-// 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.
-
-package runtime
-
-type uintreg uint64
-type intptr int64 // TODO(rsc): remove
diff --git a/third_party/gofrontend/libgo/go/runtime/arch_amd64p32.go b/third_party/gofrontend/libgo/go/runtime/arch_amd64p32.go
deleted file mode 100644
index 5c636ae..0000000
--- a/third_party/gofrontend/libgo/go/runtime/arch_amd64p32.go
+++ /dev/null
@@ -1,8 +0,0 @@
-// 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.
-
-package runtime
-
-type uintreg uint64
-type intptr int32 // TODO(rsc): remove
diff --git a/third_party/gofrontend/libgo/go/runtime/arch_arm.go b/third_party/gofrontend/libgo/go/runtime/arch_arm.go
deleted file mode 100644
index 79d38c7..0000000
--- a/third_party/gofrontend/libgo/go/runtime/arch_arm.go
+++ /dev/null
@@ -1,8 +0,0 @@
-// 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.
-
-package runtime
-
-type uintreg uint32
-type intptr int32 // TODO(rsc): remove
diff --git a/third_party/gofrontend/libgo/go/runtime/atomic.go b/third_party/gofrontend/libgo/go/runtime/atomic.go
deleted file mode 100644
index 7e9d9b3..0000000
--- a/third_party/gofrontend/libgo/go/runtime/atomic.go
+++ /dev/null
@@ -1,51 +0,0 @@
-// 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.
-
-// +build !arm
-
-package runtime
-
-import "unsafe"
-
-//go:noescape
-func xadd(ptr *uint32, delta int32) uint32
-
-//go:noescape
-func xadd64(ptr *uint64, delta int64) uint64
-
-//go:noescape
-func xchg(ptr *uint32, new uint32) uint32
-
-//go:noescape
-func xchg64(ptr *uint64, new uint64) uint64
-
-//go:noescape
-func xchgp(ptr unsafe.Pointer, new unsafe.Pointer) unsafe.Pointer
-
-//go:noescape
-func xchguintptr(ptr *uintptr, new uintptr) uintptr
-
-//go:noescape
-func atomicload(ptr *uint32) uint32
-
-//go:noescape
-func atomicload64(ptr *uint64) uint64
-
-//go:noescape
-func atomicloadp(ptr unsafe.Pointer) unsafe.Pointer
-
-//go:noescape
-func atomicor8(ptr *uint8, val uint8)
-
-//go:noescape
-func cas64(ptr *uint64, old, new uint64) bool
-
-//go:noescape
-func atomicstore(ptr *uint32, val uint32)
-
-//go:noescape
-func atomicstore64(ptr *uint64, val uint64)
-
-//go:noescape
-func atomicstorep(ptr unsafe.Pointer, val unsafe.Pointer)
diff --git a/third_party/gofrontend/libgo/go/runtime/cgocall.go b/third_party/gofrontend/libgo/go/runtime/cgocall.go
deleted file mode 100644
index 7fd9146..0000000
--- a/third_party/gofrontend/libgo/go/runtime/cgocall.go
+++ /dev/null
@@ -1,279 +0,0 @@
-// Copyright 2009 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.
-
-// Cgo call and callback support.
-//
-// To call into the C function f from Go, the cgo-generated code calls
-// runtime.cgocall(_cgo_Cfunc_f, frame), where _cgo_Cfunc_f is a
-// gcc-compiled function written by cgo.
-//
-// runtime.cgocall (below) locks g to m, calls entersyscall
-// so as not to block other goroutines or the garbage collector,
-// and then calls runtime.asmcgocall(_cgo_Cfunc_f, frame).
-//
-// runtime.asmcgocall (in asm_$GOARCH.s) switches to the m->g0 stack
-// (assumed to be an operating system-allocated stack, so safe to run
-// gcc-compiled code on) and calls _cgo_Cfunc_f(frame).
-//
-// _cgo_Cfunc_f invokes the actual C function f with arguments
-// taken from the frame structure, records the results in the frame,
-// and returns to runtime.asmcgocall.
-//
-// After it regains control, runtime.asmcgocall switches back to the
-// original g (m->curg)'s stack and returns to runtime.cgocall.
-//
-// After it regains control, runtime.cgocall calls exitsyscall, which blocks
-// until this m can run Go code without violating the $GOMAXPROCS limit,
-// and then unlocks g from m.
-//
-// The above description skipped over the possibility of the gcc-compiled
-// function f calling back into Go.  If that happens, we continue down
-// the rabbit hole during the execution of f.
-//
-// To make it possible for gcc-compiled C code to call a Go function p.GoF,
-// cgo writes a gcc-compiled function named GoF (not p.GoF, since gcc doesn't
-// know about packages).  The gcc-compiled C function f calls GoF.
-//
-// GoF calls crosscall2(_cgoexp_GoF, frame, framesize).  Crosscall2
-// (in cgo/gcc_$GOARCH.S, a gcc-compiled assembly file) is a two-argument
-// adapter from the gcc function call ABI to the 6c function call ABI.
-// It is called from gcc to call 6c functions.  In this case it calls
-// _cgoexp_GoF(frame, framesize), still running on m->g0's stack
-// and outside the $GOMAXPROCS limit.  Thus, this code cannot yet
-// call arbitrary Go code directly and must be careful not to allocate
-// memory or use up m->g0's stack.
-//
-// _cgoexp_GoF calls runtime.cgocallback(p.GoF, frame, framesize).
-// (The reason for having _cgoexp_GoF instead of writing a crosscall3
-// to make this call directly is that _cgoexp_GoF, because it is compiled
-// with 6c instead of gcc, can refer to dotted names like
-// runtime.cgocallback and p.GoF.)
-//
-// runtime.cgocallback (in asm_$GOARCH.s) switches from m->g0's
-// stack to the original g (m->curg)'s stack, on which it calls
-// runtime.cgocallbackg(p.GoF, frame, framesize).
-// As part of the stack switch, runtime.cgocallback saves the current
-// SP as m->g0->sched.sp, so that any use of m->g0's stack during the
-// execution of the callback will be done below the existing stack frames.
-// Before overwriting m->g0->sched.sp, it pushes the old value on the
-// m->g0 stack, so that it can be restored later.
-//
-// runtime.cgocallbackg (below) is now running on a real goroutine
-// stack (not an m->g0 stack).  First it calls runtime.exitsyscall, which will
-// block until the $GOMAXPROCS limit allows running this goroutine.
-// Once exitsyscall has returned, it is safe to do things like call the memory
-// allocator or invoke the Go callback function p.GoF.  runtime.cgocallbackg
-// first defers a function to unwind m->g0.sched.sp, so that if p.GoF
-// panics, m->g0.sched.sp will be restored to its old value: the m->g0 stack
-// and the m->curg stack will be unwound in lock step.
-// Then it calls p.GoF.  Finally it pops but does not execute the deferred
-// function, calls runtime.entersyscall, and returns to runtime.cgocallback.
-//
-// After it regains control, runtime.cgocallback switches back to
-// m->g0's stack (the pointer is still in m->g0.sched.sp), restores the old
-// m->g0.sched.sp value from the stack, and returns to _cgoexp_GoF.
-//
-// _cgoexp_GoF immediately returns to crosscall2, which restores the
-// callee-save registers for gcc and returns to GoF, which returns to f.
-
-package runtime
-
-import "unsafe"
-
-// Call from Go to C.
-//go:nosplit
-func cgocall(fn, arg unsafe.Pointer) {
-	cgocall_errno(fn, arg)
-}
-
-//go:nosplit
-func cgocall_errno(fn, arg unsafe.Pointer) int32 {
-	if !iscgo && GOOS != "solaris" && GOOS != "windows" {
-		gothrow("cgocall unavailable")
-	}
-
-	if fn == nil {
-		gothrow("cgocall nil")
-	}
-
-	if raceenabled {
-		racereleasemerge(unsafe.Pointer(&racecgosync))
-	}
-
-	// Create an extra M for callbacks on threads not created by Go on first cgo call.
-	if needextram == 1 && cas(&needextram, 1, 0) {
-		onM(newextram)
-	}
-
-	/*
-	 * Lock g to m to ensure we stay on the same stack if we do a
-	 * cgo callback. Add entry to defer stack in case of panic.
-	 */
-	lockOSThread()
-	mp := getg().m
-	mp.ncgocall++
-	mp.ncgo++
-	defer endcgo(mp)
-
-	/*
-	 * Announce we are entering a system call
-	 * so that the scheduler knows to create another
-	 * M to run goroutines while we are in the
-	 * foreign code.
-	 *
-	 * The call to asmcgocall is guaranteed not to
-	 * split the stack and does not allocate memory,
-	 * so it is safe to call while "in a system call", outside
-	 * the $GOMAXPROCS accounting.
-	 */
-	entersyscall()
-	errno := asmcgocall_errno(fn, arg)
-	exitsyscall()
-
-	return errno
-}
-
-//go:nosplit
-func endcgo(mp *m) {
-	mp.ncgo--
-	if mp.ncgo == 0 {
-		// We are going back to Go and are not in a recursive
-		// call.  Let the GC collect any memory allocated via
-		// _cgo_allocate that is no longer referenced.
-		mp.cgomal = nil
-	}
-
-	if raceenabled {
-		raceacquire(unsafe.Pointer(&racecgosync))
-	}
-
-	unlockOSThread() // invalidates mp
-}
-
-// Helper functions for cgo code.
-
-// Filled by schedinit from corresponding C variables,
-// which are in turn filled in by dynamic linker when Cgo is available.
-var cgoMalloc, cgoFree unsafe.Pointer
-
-func cmalloc(n uintptr) unsafe.Pointer {
-	var args struct {
-		n   uint64
-		ret unsafe.Pointer
-	}
-	args.n = uint64(n)
-	cgocall(cgoMalloc, unsafe.Pointer(&args))
-	if args.ret == nil {
-		gothrow("C malloc failed")
-	}
-	return args.ret
-}
-
-func cfree(p unsafe.Pointer) {
-	cgocall(cgoFree, p)
-}
-
-// Call from C back to Go.
-//go:nosplit
-func cgocallbackg() {
-	gp := getg()
-	if gp != gp.m.curg {
-		println("runtime: bad g in cgocallback")
-		exit(2)
-	}
-
-	// entersyscall saves the caller's SP to allow the GC to trace the Go
-	// stack. However, since we're returning to an earlier stack frame and
-	// need to pair with the entersyscall() call made by cgocall, we must
-	// save syscall* and let reentersyscall restore them.
-	savedsp := unsafe.Pointer(gp.syscallsp)
-	savedpc := gp.syscallpc
-	exitsyscall() // coming out of cgo call
-	cgocallbackg1()
-	// going back to cgo call
-	reentersyscall(savedpc, savedsp)
-}
-
-func cgocallbackg1() {
-	gp := getg()
-	if gp.m.needextram {
-		gp.m.needextram = false
-		onM(newextram)
-	}
-
-	// Add entry to defer stack in case of panic.
-	restore := true
-	defer unwindm(&restore)
-
-	if raceenabled {
-		raceacquire(unsafe.Pointer(&racecgosync))
-	}
-
-	type args struct {
-		fn      *funcval
-		arg     unsafe.Pointer
-		argsize uintptr
-	}
-	var cb *args
-
-	// Location of callback arguments depends on stack frame layout
-	// and size of stack frame of cgocallback_gofunc.
-	sp := gp.m.g0.sched.sp
-	switch GOARCH {
-	default:
-		gothrow("cgocallbackg is unimplemented on arch")
-	case "arm":
-		// On arm, stack frame is two words and there's a saved LR between
-		// SP and the stack frame and between the stack frame and the arguments.
-		cb = (*args)(unsafe.Pointer(sp + 4*ptrSize))
-	case "amd64":
-		// On amd64, stack frame is one word, plus caller PC.
-		cb = (*args)(unsafe.Pointer(sp + 2*ptrSize))
-	case "386":
-		// On 386, stack frame is three words, plus caller PC.
-		cb = (*args)(unsafe.Pointer(sp + 4*ptrSize))
-	}
-
-	// Invoke callback.
-	reflectcall(unsafe.Pointer(cb.fn), unsafe.Pointer(cb.arg), uint32(cb.argsize), 0)
-
-	if raceenabled {
-		racereleasemerge(unsafe.Pointer(&racecgosync))
-	}
-
-	// Do not unwind m->g0->sched.sp.
-	// Our caller, cgocallback, will do that.
-	restore = false
-}
-
-func unwindm(restore *bool) {
-	if !*restore {
-		return
-	}
-	// Restore sp saved by cgocallback during
-	// unwind of g's stack (see comment at top of file).
-	mp := acquirem()
-	sched := &mp.g0.sched
-	switch GOARCH {
-	default:
-		gothrow("unwindm not implemented")
-	case "386", "amd64":
-		sched.sp = *(*uintptr)(unsafe.Pointer(sched.sp))
-	case "arm":
-		sched.sp = *(*uintptr)(unsafe.Pointer(sched.sp + 4))
-	}
-	releasem(mp)
-}
-
-// called from assembly
-func badcgocallback() {
-	gothrow("misaligned stack in cgocallback")
-}
-
-// called from (incomplete) assembly
-func cgounimpl() {
-	gothrow("cgo not implemented")
-}
-
-var racecgosync uint64 // represents possible synchronization in C code
diff --git a/third_party/gofrontend/libgo/go/runtime/cgocallback.go b/third_party/gofrontend/libgo/go/runtime/cgocallback.go
deleted file mode 100644
index 2c89143..0000000
--- a/third_party/gofrontend/libgo/go/runtime/cgocallback.go
+++ /dev/null
@@ -1,40 +0,0 @@
-// Copyright 2011 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 runtime
-
-import "unsafe"
-
-// These functions are called from C code via cgo/callbacks.c.
-
-// Allocate memory.  This allocates the requested number of bytes in
-// memory controlled by the Go runtime.  The allocated memory will be
-// zeroed.  You are responsible for ensuring that the Go garbage
-// collector can see a pointer to the allocated memory for as long as
-// it is valid, e.g., by storing a pointer in a local variable in your
-// C function, or in memory allocated by the Go runtime.  If the only
-// pointers are in a C global variable or in memory allocated via
-// malloc, then the Go garbage collector may collect the memory.
-//
-// TODO(rsc,iant): This memory is untyped.
-// Either we need to add types or we need to stop using it.
-
-func _cgo_allocate_internal(len uintptr) unsafe.Pointer {
-	if len == 0 {
-		len = 1
-	}
-	ret := unsafe.Pointer(&make([]unsafe.Pointer, (len+ptrSize-1)/ptrSize)[0])
-	c := new(cgomal)
-	c.alloc = ret
-	gp := getg()
-	c.next = gp.m.cgomal
-	gp.m.cgomal = c
-	return ret
-}
-
-// Panic.
-
-func _cgo_panic_internal(p *byte) {
-	panic(gostringnocopy(p))
-}
diff --git a/third_party/gofrontend/libgo/go/runtime/chan.go b/third_party/gofrontend/libgo/go/runtime/chan.go
deleted file mode 100644
index 0eb87df..0000000
--- a/third_party/gofrontend/libgo/go/runtime/chan.go
+++ /dev/null
@@ -1,655 +0,0 @@
-// 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.
-
-package runtime
-
-// This file contains the implementation of Go channels.
-
-import "unsafe"
-
-const (
-	maxAlign  = 8
-	hchanSize = unsafe.Sizeof(hchan{}) + uintptr(-int(unsafe.Sizeof(hchan{}))&(maxAlign-1))
-	debugChan = false
-)
-
-// TODO(khr): make hchan.buf an unsafe.Pointer, not a *uint8
-
-func makechan(t *chantype, size int64) *hchan {
-	elem := t.elem
-
-	// compiler checks this but be safe.
-	if elem.size >= 1<<16 {
-		gothrow("makechan: invalid channel element type")
-	}
-	if hchanSize%maxAlign != 0 || elem.align > maxAlign {
-		gothrow("makechan: bad alignment")
-	}
-	if size < 0 || int64(uintptr(size)) != size || (elem.size > 0 && uintptr(size) > (maxmem-hchanSize)/uintptr(elem.size)) {
-		panic("makechan: size out of range")
-	}
-
-	var c *hchan
-	if elem.kind&kindNoPointers != 0 || size == 0 {
-		// Allocate memory in one call.
-		// Hchan does not contain pointers interesting for GC in this case:
-		// buf points into the same allocation, elemtype is persistent.
-		// SudoG's are referenced from their owning thread so they can't be collected.
-		// TODO(dvyukov,rlh): Rethink when collector can move allocated objects.
-		c = (*hchan)(mallocgc(hchanSize+uintptr(size)*uintptr(elem.size), nil, flagNoScan))
-		if size > 0 && elem.size != 0 {
-			c.buf = (*uint8)(add(unsafe.Pointer(c), hchanSize))
-		} else {
-			c.buf = (*uint8)(unsafe.Pointer(c)) // race detector uses this location for synchronization
-		}
-	} else {
-		c = new(hchan)
-		c.buf = (*uint8)(newarray(elem, uintptr(size)))
-	}
-	c.elemsize = uint16(elem.size)
-	c.elemtype = elem
-	c.dataqsiz = uint(size)
-
-	if debugChan {
-		print("makechan: chan=", c, "; elemsize=", elem.size, "; elemalg=", elem.alg, "; dataqsiz=", size, "\n")
-	}
-	return c
-}
-
-// chanbuf(c, i) is pointer to the i'th slot in the buffer.
-func chanbuf(c *hchan, i uint) unsafe.Pointer {
-	return add(unsafe.Pointer(c.buf), uintptr(i)*uintptr(c.elemsize))
-}
-
-// entry point for c <- x from compiled code
-//go:nosplit
-func chansend1(t *chantype, c *hchan, elem unsafe.Pointer) {
-	chansend(t, c, elem, true, getcallerpc(unsafe.Pointer(&t)))
-}
-
-/*
- * generic single channel send/recv
- * If block is not nil,
- * then the protocol will not
- * sleep but return if it could
- * not complete.
- *
- * sleep can wake up with g.param == nil
- * when a channel involved in the sleep has
- * been closed.  it is easiest to loop and re-run
- * the operation; we'll see that it's now closed.
- */
-func chansend(t *chantype, c *hchan, ep unsafe.Pointer, block bool, callerpc uintptr) bool {
-	if raceenabled {
-		raceReadObjectPC(t.elem, ep, callerpc, funcPC(chansend))
-	}
-
-	if c == nil {
-		if !block {
-			return false
-		}
-		gopark(nil, nil, "chan send (nil chan)")
-		gothrow("unreachable")
-	}
-
-	if debugChan {
-		print("chansend: chan=", c, "\n")
-	}
-
-	if raceenabled {
-		racereadpc(unsafe.Pointer(c), callerpc, funcPC(chansend))
-	}
-
-	// Fast path: check for failed non-blocking operation without acquiring the lock.
-	//
-	// After observing that the channel is not closed, we observe that the channel is
-	// not ready for sending. Each of these observations is a single word-sized read
-	// (first c.closed and second c.recvq.first or c.qcount depending on kind of channel).
-	// Because a closed channel cannot transition from 'ready for sending' to
-	// 'not ready for sending', even if the channel is closed between the two observations,
-	// they imply a moment between the two when the channel was both not yet closed
-	// and not ready for sending. We behave as if we observed the channel at that moment,
-	// and report that the send cannot proceed.
-	//
-	// It is okay if the reads are reordered here: if we observe that the channel is not
-	// ready for sending and then observe that it is not closed, that implies that the
-	// channel wasn't closed during the first observation.
-	if !block && c.closed == 0 && ((c.dataqsiz == 0 && c.recvq.first == nil) ||
-		(c.dataqsiz > 0 && c.qcount == c.dataqsiz)) {
-		return false
-	}
-
-	var t0 int64
-	if blockprofilerate > 0 {
-		t0 = cputicks()
-	}
-
-	lock(&c.lock)
-	if c.closed != 0 {
-		unlock(&c.lock)
-		panic("send on closed channel")
-	}
-
-	if c.dataqsiz == 0 { // synchronous channel
-		sg := c.recvq.dequeue()
-		if sg != nil { // found a waiting receiver
-			if raceenabled {
-				racesync(c, sg)
-			}
-			unlock(&c.lock)
-
-			recvg := sg.g
-			if sg.elem != nil {
-				memmove(unsafe.Pointer(sg.elem), ep, uintptr(c.elemsize))
-				sg.elem = nil
-			}
-			recvg.param = unsafe.Pointer(sg)
-			if sg.releasetime != 0 {
-				sg.releasetime = cputicks()
-			}
-			goready(recvg)
-			return true
-		}
-
-		if !block {
-			unlock(&c.lock)
-			return false
-		}
-
-		// no receiver available: block on this channel.
-		gp := getg()
-		mysg := acquireSudog()
-		mysg.releasetime = 0
-		if t0 != 0 {
-			mysg.releasetime = -1
-		}
-		mysg.elem = ep
-		mysg.waitlink = nil
-		gp.waiting = mysg
-		mysg.g = gp
-		mysg.selectdone = nil
-		gp.param = nil
-		c.sendq.enqueue(mysg)
-		goparkunlock(&c.lock, "chan send")
-
-		// someone woke us up.
-		if mysg != gp.waiting {
-			gothrow("G waiting list is corrupted!")
-		}
-		gp.waiting = nil
-		if gp.param == nil {
-			if c.closed == 0 {
-				gothrow("chansend: spurious wakeup")
-			}
-			panic("send on closed channel")
-		}
-		gp.param = nil
-		if mysg.releasetime > 0 {
-			blockevent(int64(mysg.releasetime)-t0, 2)
-		}
-		releaseSudog(mysg)
-		return true
-	}
-
-	// asynchronous channel
-	// wait for some space to write our data
-	var t1 int64
-	for c.qcount >= c.dataqsiz {
-		if !block {
-			unlock(&c.lock)
-			return false
-		}
-		gp := getg()
-		mysg := acquireSudog()
-		mysg.releasetime = 0
-		if t0 != 0 {
-			mysg.releasetime = -1
-		}
-		mysg.g = gp
-		mysg.elem = nil
-		mysg.selectdone = nil
-		c.sendq.enqueue(mysg)
-		goparkunlock(&c.lock, "chan send")
-
-		// someone woke us up - try again
-		if mysg.releasetime > 0 {
-			t1 = mysg.releasetime
-		}
-		releaseSudog(mysg)
-		lock(&c.lock)
-		if c.closed != 0 {
-			unlock(&c.lock)
-			panic("send on closed channel")
-		}
-	}
-
-	// write our data into the channel buffer
-	if raceenabled {
-		raceacquire(chanbuf(c, c.sendx))
-		racerelease(chanbuf(c, c.sendx))
-	}
-	memmove(chanbuf(c, c.sendx), ep, uintptr(c.elemsize))
-	c.sendx++
-	if c.sendx == c.dataqsiz {
-		c.sendx = 0
-	}
-	c.qcount++
-
-	// wake up a waiting receiver
-	sg := c.recvq.dequeue()
-	if sg != nil {
-		recvg := sg.g
-		unlock(&c.lock)
-		if sg.releasetime != 0 {
-			sg.releasetime = cputicks()
-		}
-		goready(recvg)
-	} else {
-		unlock(&c.lock)
-	}
-	if t1 > 0 {
-		blockevent(t1-t0, 2)
-	}
-	return true
-}
-
-func closechan(c *hchan) {
-	if c == nil {
-		panic("close of nil channel")
-	}
-
-	lock(&c.lock)
-	if c.closed != 0 {
-		unlock(&c.lock)
-		panic("close of closed channel")
-	}
-
-	if raceenabled {
-		callerpc := getcallerpc(unsafe.Pointer(&c))
-		racewritepc(unsafe.Pointer(c), callerpc, funcPC(closechan))
-		racerelease(unsafe.Pointer(c))
-	}
-
-	c.closed = 1
-
-	// release all readers
-	for {
-		sg := c.recvq.dequeue()
-		if sg == nil {
-			break
-		}
-		gp := sg.g
-		sg.elem = nil
-		gp.param = nil
-		if sg.releasetime != 0 {
-			sg.releasetime = cputicks()
-		}
-		goready(gp)
-	}
-
-	// release all writers
-	for {
-		sg := c.sendq.dequeue()
-		if sg == nil {
-			break
-		}
-		gp := sg.g
-		sg.elem = nil
-		gp.param = nil
-		if sg.releasetime != 0 {
-			sg.releasetime = cputicks()
-		}
-		goready(gp)
-	}
-	unlock(&c.lock)
-}
-
-// entry points for <- c from compiled code
-//go:nosplit
-func chanrecv1(t *chantype, c *hchan, elem unsafe.Pointer) {
-	chanrecv(t, c, elem, true)
-}
-
-//go:nosplit
-func chanrecv2(t *chantype, c *hchan, elem unsafe.Pointer) (received bool) {
-	_, received = chanrecv(t, c, elem, true)
-	return
-}
-
-// chanrecv receives on channel c and writes the received data to ep.
-// ep may be nil, in which case received data is ignored.
-// If block == false and no elements are available, returns (false, false).
-// Otherwise, if c is closed, zeros *ep and returns (true, false).
-// Otherwise, fills in *ep with an element and returns (true, true).
-func chanrecv(t *chantype, c *hchan, ep unsafe.Pointer, block bool) (selected, received bool) {
-	// raceenabled: don't need to check ep, as it is always on the stack.
-
-	if debugChan {
-		print("chanrecv: chan=", c, "\n")
-	}
-
-	if c == nil {
-		if !block {
-			return
-		}
-		gopark(nil, nil, "chan receive (nil chan)")
-		gothrow("unreachable")
-	}
-
-	// Fast path: check for failed non-blocking operation without acquiring the lock.
-	//
-	// After observing that the channel is not ready for receiving, we observe that the
-	// channel is not closed. Each of these observations is a single word-sized read
-	// (first c.sendq.first or c.qcount, and second c.closed).
-	// Because a channel cannot be reopened, the later observation of the channel
-	// being not closed implies that it was also not closed at the moment of the
-	// first observation. We behave as if we observed the channel at that moment
-	// and report that the receive cannot proceed.
-	//
-	// The order of operations is important here: reversing the operations can lead to
-	// incorrect behavior when racing with a close.
-	if !block && (c.dataqsiz == 0 && c.sendq.first == nil ||
-		c.dataqsiz > 0 && atomicloaduint(&c.qcount) == 0) &&
-		atomicload(&c.closed) == 0 {
-		return
-	}
-
-	var t0 int64
-	if blockprofilerate > 0 {
-		t0 = cputicks()
-	}
-
-	lock(&c.lock)
-	if c.dataqsiz == 0 { // synchronous channel
-		if c.closed != 0 {
-			return recvclosed(c, ep)
-		}
-
-		sg := c.sendq.dequeue()
-		if sg != nil {
-			if raceenabled {
-				racesync(c, sg)
-			}
-			unlock(&c.lock)
-
-			if ep != nil {
-				memmove(ep, sg.elem, uintptr(c.elemsize))
-			}
-			sg.elem = nil
-			gp := sg.g
-			gp.param = unsafe.Pointer(sg)
-			if sg.releasetime != 0 {
-				sg.releasetime = cputicks()
-			}
-			goready(gp)
-			selected = true
-			received = true
-			return
-		}
-
-		if !block {
-			unlock(&c.lock)
-			return
-		}
-
-		// no sender available: block on this channel.
-		gp := getg()
-		mysg := acquireSudog()
-		mysg.releasetime = 0
-		if t0 != 0 {
-			mysg.releasetime = -1
-		}
-		mysg.elem = ep
-		mysg.waitlink = nil
-		gp.waiting = mysg
-		mysg.g = gp
-		mysg.selectdone = nil
-		gp.param = nil
-		c.recvq.enqueue(mysg)
-		goparkunlock(&c.lock, "chan receive")
-
-		// someone woke us up
-		if mysg != gp.waiting {
-			gothrow("G waiting list is corrupted!")
-		}
-		gp.waiting = nil
-		if mysg.releasetime > 0 {
-			blockevent(mysg.releasetime-t0, 2)
-		}
-		haveData := gp.param != nil
-		gp.param = nil
-		releaseSudog(mysg)
-
-		if haveData {
-			// a sender sent us some data. It already wrote to ep.
-			selected = true
-			received = true
-			return
-		}
-
-		lock(&c.lock)
-		if c.closed == 0 {
-			gothrow("chanrecv: spurious wakeup")
-		}
-		return recvclosed(c, ep)
-	}
-
-	// asynchronous channel
-	// wait for some data to appear
-	var t1 int64
-	for c.qcount <= 0 {
-		if c.closed != 0 {
-			selected, received = recvclosed(c, ep)
-			if t1 > 0 {
-				blockevent(t1-t0, 2)
-			}
-			return
-		}
-
-		if !block {
-			unlock(&c.lock)
-			return
-		}
-
-		// wait for someone to send an element
-		gp := getg()
-		mysg := acquireSudog()
-		mysg.releasetime = 0
-		if t0 != 0 {
-			mysg.releasetime = -1
-		}
-		mysg.elem = nil
-		mysg.g = gp
-		mysg.selectdone = nil
-
-		c.recvq.enqueue(mysg)
-		goparkunlock(&c.lock, "chan receive")
-
-		// someone woke us up - try again
-		if mysg.releasetime > 0 {
-			t1 = mysg.releasetime
-		}
-		releaseSudog(mysg)
-		lock(&c.lock)
-	}
-
-	if raceenabled {
-		raceacquire(chanbuf(c, c.recvx))
-		racerelease(chanbuf(c, c.recvx))
-	}
-	if ep != nil {
-		memmove(ep, chanbuf(c, c.recvx), uintptr(c.elemsize))
-	}
-	memclr(chanbuf(c, c.recvx), uintptr(c.elemsize))
-
-	c.recvx++
-	if c.recvx == c.dataqsiz {
-		c.recvx = 0
-	}
-	c.qcount--
-
-	// ping a sender now that there is space
-	sg := c.sendq.dequeue()
-	if sg != nil {
-		gp := sg.g
-		unlock(&c.lock)
-		if sg.releasetime != 0 {
-			sg.releasetime = cputicks()
-		}
-		goready(gp)
-	} else {
-		unlock(&c.lock)
-	}
-
-	if t1 > 0 {
-		blockevent(t1-t0, 2)
-	}
-	selected = true
-	received = true
-	return
-}
-
-// recvclosed is a helper function for chanrecv.  Handles cleanup
-// when the receiver encounters a closed channel.
-// Caller must hold c.lock, recvclosed will release the lock.
-func recvclosed(c *hchan, ep unsafe.Pointer) (selected, recevied bool) {
-	if raceenabled {
-		raceacquire(unsafe.Pointer(c))
-	}
-	unlock(&c.lock)
-	if ep != nil {
-		memclr(ep, uintptr(c.elemsize))
-	}
-	return true, false
-}
-
-// compiler implements
-//
-//	select {
-//	case c <- v:
-//		... foo
-//	default:
-//		... bar
-//	}
-//
-// as
-//
-//	if selectnbsend(c, v) {
-//		... foo
-//	} else {
-//		... bar
-//	}
-//
-func selectnbsend(t *chantype, c *hchan, elem unsafe.Pointer) (selected bool) {
-	return chansend(t, c, elem, false, getcallerpc(unsafe.Pointer(&t)))
-}
-
-// compiler implements
-//
-//	select {
-//	case v = <-c:
-//		... foo
-//	default:
-//		... bar
-//	}
-//
-// as
-//
-//	if selectnbrecv(&v, c) {
-//		... foo
-//	} else {
-//		... bar
-//	}
-//
-func selectnbrecv(t *chantype, elem unsafe.Pointer, c *hchan) (selected bool) {
-	selected, _ = chanrecv(t, c, elem, false)
-	return
-}
-
-// compiler implements
-//
-//	select {
-//	case v, ok = <-c:
-//		... foo
-//	default:
-//		... bar
-//	}
-//
-// as
-//
-//	if c != nil && selectnbrecv2(&v, &ok, c) {
-//		... foo
-//	} else {
-//		... bar
-//	}
-//
-func selectnbrecv2(t *chantype, elem unsafe.Pointer, received *bool, c *hchan) (selected bool) {
-	// TODO(khr): just return 2 values from this function, now that it is in Go.
-	selected, *received = chanrecv(t, c, elem, false)
-	return
-}
-
-func reflect_chansend(t *chantype, c *hchan, elem unsafe.Pointer, nb bool) (selected bool) {
-	return chansend(t, c, elem, !nb, getcallerpc(unsafe.Pointer(&t)))
-}
-
-func reflect_chanrecv(t *chantype, c *hchan, nb bool, elem unsafe.Pointer) (selected bool, received bool) {
-	return chanrecv(t, c, elem, !nb)
-}
-
-func reflect_chanlen(c *hchan) int {
-	if c == nil {
-		return 0
-	}
-	return int(c.qcount)
-}
-
-func reflect_chancap(c *hchan) int {
-	if c == nil {
-		return 0
-	}
-	return int(c.dataqsiz)
-}
-
-func (q *waitq) enqueue(sgp *sudog) {
-	sgp.next = nil
-	if q.first == nil {
-		q.first = sgp
-		q.last = sgp
-		return
-	}
-	q.last.next = sgp
-	q.last = sgp
-}
-
-func (q *waitq) dequeue() *sudog {
-	for {
-		sgp := q.first
-		if sgp == nil {
-			return nil
-		}
-		q.first = sgp.next
-		sgp.next = nil
-		if q.last == sgp {
-			q.last = nil
-		}
-
-		// if sgp participates in a select and is already signaled, ignore it
-		if sgp.selectdone != nil {
-			// claim the right to signal
-			if *sgp.selectdone != 0 || !cas(sgp.selectdone, 0, 1) {
-				continue
-			}
-		}
-
-		return sgp
-	}
-}
-
-func racesync(c *hchan, sg *sudog) {
-	racerelease(chanbuf(c, 0))
-	raceacquireg(sg.g, chanbuf(c, 0))
-	racereleaseg(sg.g, chanbuf(c, 0))
-	raceacquire(chanbuf(c, 0))
-}
diff --git a/third_party/gofrontend/libgo/go/runtime/chan_test.go b/third_party/gofrontend/libgo/go/runtime/chan_test.go
index 4fb305c..6553509 100644
--- a/third_party/gofrontend/libgo/go/runtime/chan_test.go
+++ b/third_party/gofrontend/libgo/go/runtime/chan_test.go
@@ -223,6 +223,81 @@
 	}
 }
 
+// This test checks that select acts on the state of the channels at one
+// moment in the execution, not over a smeared time window.
+// In the test, one goroutine does:
+//	create c1, c2
+//	make c1 ready for receiving
+//	create second goroutine
+//	make c2 ready for receiving
+//	make c1 no longer ready for receiving (if possible)
+// The second goroutine does a non-blocking select receiving from c1 and c2.
+// From the time the second goroutine is created, at least one of c1 and c2
+// is always ready for receiving, so the select in the second goroutine must
+// always receive from one or the other. It must never execute the default case.
+func TestNonblockSelectRace(t *testing.T) {
+	n := 100000
+	if testing.Short() {
+		n = 1000
+	}
+	done := make(chan bool, 1)
+	for i := 0; i < n; i++ {
+		c1 := make(chan int, 1)
+		c2 := make(chan int, 1)
+		c1 <- 1
+		go func() {
+			select {
+			case <-c1:
+			case <-c2:
+			default:
+				done <- false
+				return
+			}
+			done <- true
+		}()
+		c2 <- 1
+		select {
+		case <-c1:
+		default:
+		}
+		if !<-done {
+			t.Fatal("no chan is ready")
+		}
+	}
+}
+
+// Same as TestNonblockSelectRace, but close(c2) replaces c2 <- 1.
+func TestNonblockSelectRace2(t *testing.T) {
+	n := 100000
+	if testing.Short() {
+		n = 1000
+	}
+	done := make(chan bool, 1)
+	for i := 0; i < n; i++ {
+		c1 := make(chan int, 1)
+		c2 := make(chan int)
+		c1 <- 1
+		go func() {
+			select {
+			case <-c1:
+			case <-c2:
+			default:
+				done <- false
+				return
+			}
+			done <- true
+		}()
+		close(c2)
+		select {
+		case <-c1:
+		default:
+		}
+		if !<-done {
+			t.Fatal("no chan is ready")
+		}
+	}
+}
+
 func TestSelfSelect(t *testing.T) {
 	// Ensure that send/recv on the same chan in select
 	// does not crash nor deadlock.
@@ -458,7 +533,7 @@
 func TestShrinkStackDuringBlockedSend(t *testing.T) {
 	// make sure that channel operations still work when we are
 	// blocked on a channel send and we shrink the stack.
-	// NOTE: this test probably won't fail unless stack.c:StackDebug
+	// NOTE: this test probably won't fail unless stack1.go:stackDebug
 	// is set to >= 1.
 	const n = 10
 	c := make(chan int)
@@ -823,3 +898,30 @@
 		}
 	})
 }
+
+func BenchmarkChanPopular(b *testing.B) {
+	const n = 1000
+	c := make(chan bool)
+	var a []chan bool
+	var wg sync.WaitGroup
+	wg.Add(n)
+	for j := 0; j < n; j++ {
+		d := make(chan bool)
+		a = append(a, d)
+		go func() {
+			for i := 0; i < b.N; i++ {
+				select {
+				case <-c:
+				case <-d:
+				}
+			}
+			wg.Done()
+		}()
+	}
+	for i := 0; i < b.N; i++ {
+		for _, d := range a {
+			d <- true
+		}
+	}
+	wg.Wait()
+}
diff --git a/third_party/gofrontend/libgo/go/runtime/chanbarrier_test.go b/third_party/gofrontend/libgo/go/runtime/chanbarrier_test.go
new file mode 100644
index 0000000..770b850
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/runtime/chanbarrier_test.go
@@ -0,0 +1,83 @@
+// 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 runtime_test
+
+import (
+	"runtime"
+	"sync"
+	"testing"
+)
+
+type response struct {
+}
+
+type myError struct {
+}
+
+func (myError) Error() string { return "" }
+
+func doRequest(useSelect bool) (*response, error) {
+	type async struct {
+		resp *response
+		err  error
+	}
+	ch := make(chan *async, 0)
+	done := make(chan struct{}, 0)
+
+	if useSelect {
+		go func() {
+			select {
+			case ch <- &async{resp: nil, err: myError{}}:
+			case <-done:
+			}
+		}()
+	} else {
+		go func() {
+			ch <- &async{resp: nil, err: myError{}}
+		}()
+	}
+
+	r := <-ch
+	runtime.Gosched()
+	return r.resp, r.err
+}
+
+func TestChanSendSelectBarrier(t *testing.T) {
+	testChanSendBarrier(true)
+}
+
+func TestChanSendBarrier(t *testing.T) {
+	testChanSendBarrier(false)
+}
+
+func testChanSendBarrier(useSelect bool) {
+	var wg sync.WaitGroup
+	var globalMu sync.Mutex
+	outer := 100
+	inner := 100000
+	if testing.Short() {
+		outer = 10
+		inner = 1000
+	}
+	for i := 0; i < outer; i++ {
+		wg.Add(1)
+		go func() {
+			defer wg.Done()
+			var garbage []byte
+			for j := 0; j < inner; j++ {
+				_, err := doRequest(useSelect)
+				_, ok := err.(myError)
+				if !ok {
+					panic(1)
+				}
+				garbage = make([]byte, 1<<10)
+			}
+			globalMu.Lock()
+			global = garbage
+			globalMu.Unlock()
+		}()
+	}
+	wg.Wait()
+}
diff --git a/third_party/gofrontend/libgo/go/runtime/compiler.go b/third_party/gofrontend/libgo/go/runtime/compiler.go
index 0ed3b18..b04be61 100644
--- a/third_party/gofrontend/libgo/go/runtime/compiler.go
+++ b/third_party/gofrontend/libgo/go/runtime/compiler.go
@@ -7,7 +7,7 @@
 // Compiler is the name of the compiler toolchain that built the
 // running binary.  Known toolchains are:
 //
-//	gc      The 5g/6g/8g compiler suite at code.google.com/p/go.
+//	gc      Also known as cmd/compile.
 //	gccgo   The gccgo front end, part of the GCC compiler suite.
 //
 const Compiler = "gccgo"
diff --git a/third_party/gofrontend/libgo/go/runtime/complex.go b/third_party/gofrontend/libgo/go/runtime/complex.go
deleted file mode 100644
index ec50f89..0000000
--- a/third_party/gofrontend/libgo/go/runtime/complex.go
+++ /dev/null
@@ -1,52 +0,0 @@
-// Copyright 2010 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 runtime
-
-func complex128div(n complex128, d complex128) complex128 {
-	// Special cases as in C99.
-	ninf := real(n) == posinf || real(n) == neginf ||
-		imag(n) == posinf || imag(n) == neginf
-	dinf := real(d) == posinf || real(d) == neginf ||
-		imag(d) == posinf || imag(d) == neginf
-
-	nnan := !ninf && (real(n) != real(n) || imag(n) != imag(n))
-	dnan := !dinf && (real(d) != real(d) || imag(d) != imag(d))
-
-	switch {
-	case nnan || dnan:
-		return complex(nan, nan)
-	case ninf && !dinf:
-		return complex(posinf, posinf)
-	case !ninf && dinf:
-		return complex(0, 0)
-	case real(d) == 0 && imag(d) == 0:
-		if real(n) == 0 && imag(n) == 0 {
-			return complex(nan, nan)
-		} else {
-			return complex(posinf, posinf)
-		}
-	default:
-		// Standard complex arithmetic, factored to avoid unnecessary overflow.
-		a := real(d)
-		if a < 0 {
-			a = -a
-		}
-		b := imag(d)
-		if b < 0 {
-			b = -b
-		}
-		if a <= b {
-			ratio := real(d) / imag(d)
-			denom := real(d)*ratio + imag(d)
-			return complex((real(n)*ratio+imag(n))/denom,
-				(imag(n)*ratio-real(n))/denom)
-		} else {
-			ratio := imag(d) / real(d)
-			denom := imag(d)*ratio + real(d)
-			return complex((imag(n)*ratio+real(n))/denom,
-				(imag(n)-real(n)*ratio)/denom)
-		}
-	}
-}
diff --git a/third_party/gofrontend/libgo/go/runtime/cpuprof.go b/third_party/gofrontend/libgo/go/runtime/cpuprof.go
deleted file mode 100644
index 8b1c1c6..0000000
--- a/third_party/gofrontend/libgo/go/runtime/cpuprof.go
+++ /dev/null
@@ -1,425 +0,0 @@
-// Copyright 2011 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.
-
-// CPU profiling.
-// Based on algorithms and data structures used in
-// http://code.google.com/p/google-perftools/.
-//
-// The main difference between this code and the google-perftools
-// code is that this code is written to allow copying the profile data
-// to an arbitrary io.Writer, while the google-perftools code always
-// writes to an operating system file.
-//
-// The signal handler for the profiling clock tick adds a new stack trace
-// to a hash table tracking counts for recent traces.  Most clock ticks
-// hit in the cache.  In the event of a cache miss, an entry must be
-// evicted from the hash table, copied to a log that will eventually be
-// written as profile data.  The google-perftools code flushed the
-// log itself during the signal handler.  This code cannot do that, because
-// the io.Writer might block or need system calls or locks that are not
-// safe to use from within the signal handler.  Instead, we split the log
-// into two halves and let the signal handler fill one half while a goroutine
-// is writing out the other half.  When the signal handler fills its half, it
-// offers to swap with the goroutine.  If the writer is not done with its half,
-// we lose the stack trace for this clock tick (and record that loss).
-// The goroutine interacts with the signal handler by calling getprofile() to
-// get the next log piece to write, implicitly handing back the last log
-// piece it obtained.
-//
-// The state of this dance between the signal handler and the goroutine
-// is encoded in the Profile.handoff field.  If handoff == 0, then the goroutine
-// is not using either log half and is waiting (or will soon be waiting) for
-// a new piece by calling notesleep(&p->wait).  If the signal handler
-// changes handoff from 0 to non-zero, it must call notewakeup(&p->wait)
-// to wake the goroutine.  The value indicates the number of entries in the
-// log half being handed off.  The goroutine leaves the non-zero value in
-// place until it has finished processing the log half and then flips the number
-// back to zero.  Setting the high bit in handoff means that the profiling is over,
-// and the goroutine is now in charge of flushing the data left in the hash table
-// to the log and returning that data.
-//
-// The handoff field is manipulated using atomic operations.
-// For the most part, the manipulation of handoff is orderly: if handoff == 0
-// then the signal handler owns it and can change it to non-zero.
-// If handoff != 0 then the goroutine owns it and can change it to zero.
-// If that were the end of the story then we would not need to manipulate
-// handoff using atomic operations.  The operations are needed, however,
-// in order to let the log closer set the high bit to indicate "EOF" safely
-// in the situation when normally the goroutine "owns" handoff.
-
-package runtime
-
-import "unsafe"
-
-const (
-	numBuckets      = 1 << 10
-	logSize         = 1 << 17
-	assoc           = 4
-	maxCPUProfStack = 64
-)
-
-type cpuprofEntry struct {
-	count uintptr
-	depth uintptr
-	stack [maxCPUProfStack]uintptr
-}
-
-type cpuProfile struct {
-	on     bool    // profiling is on
-	wait   note    // goroutine waits here
-	count  uintptr // tick count
-	evicts uintptr // eviction count
-	lost   uintptr // lost ticks that need to be logged
-
-	// Active recent stack traces.
-	hash [numBuckets]struct {
-		entry [assoc]cpuprofEntry
-	}
-
-	// Log of traces evicted from hash.
-	// Signal handler has filled log[toggle][:nlog].
-	// Goroutine is writing log[1-toggle][:handoff].
-	log     [2][logSize / 2]uintptr
-	nlog    uintptr
-	toggle  int32
-	handoff uint32
-
-	// Writer state.
-	// Writer maintains its own toggle to avoid races
-	// looking at signal handler's toggle.
-	wtoggle  uint32
-	wholding bool // holding & need to release a log half
-	flushing bool // flushing hash table - profile is over
-	eodSent  bool // special end-of-data record sent; => flushing
-}
-
-var (
-	cpuprofLock mutex
-	cpuprof     *cpuProfile
-
-	eod = [3]uintptr{0, 1, 0}
-)
-
-func setcpuprofilerate_m() // proc.c
-
-func setcpuprofilerate(hz int32) {
-	g := getg()
-	g.m.scalararg[0] = uintptr(hz)
-	onM(setcpuprofilerate_m)
-}
-
-// lostProfileData is a no-op function used in profiles
-// to mark the number of profiling stack traces that were
-// discarded due to slow data writers.
-func lostProfileData() {}
-
-// SetCPUProfileRate sets the CPU profiling rate to hz samples per second.
-// If hz <= 0, SetCPUProfileRate turns off profiling.
-// If the profiler is on, the rate cannot be changed without first turning it off.
-//
-// Most clients should use the runtime/pprof package or
-// the testing package's -test.cpuprofile flag instead of calling
-// SetCPUProfileRate directly.
-func SetCPUProfileRate(hz int) {
-	// Clamp hz to something reasonable.
-	if hz < 0 {
-		hz = 0
-	}
-	if hz > 1000000 {
-		hz = 1000000
-	}
-
-	lock(&cpuprofLock)
-	if hz > 0 {
-		if cpuprof == nil {
-			cpuprof = (*cpuProfile)(sysAlloc(unsafe.Sizeof(cpuProfile{}), &memstats.other_sys))
-			if cpuprof == nil {
-				print("runtime: cpu profiling cannot allocate memory\n")
-				unlock(&cpuprofLock)
-				return
-			}
-		}
-		if cpuprof.on || cpuprof.handoff != 0 {
-			print("runtime: cannot set cpu profile rate until previous profile has finished.\n")
-			unlock(&cpuprofLock)
-			return
-		}
-
-		cpuprof.on = true
-		// pprof binary header format.
-		// http://code.google.com/p/google-perftools/source/browse/trunk/src/profiledata.cc#117
-		p := &cpuprof.log[0]
-		p[0] = 0                 // count for header
-		p[1] = 3                 // depth for header
-		p[2] = 0                 // version number
-		p[3] = uintptr(1e6 / hz) // period (microseconds)
-		p[4] = 0
-		cpuprof.nlog = 5
-		cpuprof.toggle = 0
-		cpuprof.wholding = false
-		cpuprof.wtoggle = 0
-		cpuprof.flushing = false
-		cpuprof.eodSent = false
-		noteclear(&cpuprof.wait)
-
-		setcpuprofilerate(int32(hz))
-	} else if cpuprof != nil && cpuprof.on {
-		setcpuprofilerate(0)
-		cpuprof.on = false
-
-		// Now add is not running anymore, and getprofile owns the entire log.
-		// Set the high bit in prof->handoff to tell getprofile.
-		for {
-			n := cpuprof.handoff
-			if n&0x80000000 != 0 {
-				print("runtime: setcpuprofile(off) twice\n")
-			}
-			if cas(&cpuprof.handoff, n, n|0x80000000) {
-				if n == 0 {
-					// we did the transition from 0 -> nonzero so we wake getprofile
-					notewakeup(&cpuprof.wait)
-				}
-				break
-			}
-		}
-	}
-	unlock(&cpuprofLock)
-}
-
-func cpuproftick(pc *uintptr, n int32) {
-	if n > maxCPUProfStack {
-		n = maxCPUProfStack
-	}
-	s := (*[maxCPUProfStack]uintptr)(unsafe.Pointer(pc))[:n]
-	cpuprof.add(s)
-}
-
-// add adds the stack trace to the profile.
-// It is called from signal handlers and other limited environments
-// and cannot allocate memory or acquire locks that might be
-// held at the time of the signal, nor can it use substantial amounts
-// of stack.  It is allowed to call evict.
-func (p *cpuProfile) add(pc []uintptr) {
-	// Compute hash.
-	h := uintptr(0)
-	for _, x := range pc {
-		h = h<<8 | (h >> (8 * (unsafe.Sizeof(h) - 1)))
-		h += x*31 + x*7 + x*3
-	}
-	p.count++
-
-	// Add to entry count if already present in table.
-	b := &p.hash[h%numBuckets]
-Assoc:
-	for i := range b.entry {
-		e := &b.entry[i]
-		if e.depth != uintptr(len(pc)) {
-			continue
-		}
-		for j := range pc {
-			if e.stack[j] != pc[j] {
-				continue Assoc
-			}
-		}
-		e.count++
-		return
-	}
-
-	// Evict entry with smallest count.
-	var e *cpuprofEntry
-	for i := range b.entry {
-		if e == nil || b.entry[i].count < e.count {
-			e = &b.entry[i]
-		}
-	}
-	if e.count > 0 {
-		if !p.evict(e) {
-			// Could not evict entry.  Record lost stack.
-			p.lost++
-			return
-		}
-		p.evicts++
-	}
-
-	// Reuse the newly evicted entry.
-	e.depth = uintptr(len(pc))
-	e.count = 1
-	copy(e.stack[:], pc)
-}
-
-// evict copies the given entry's data into the log, so that
-// the entry can be reused.  evict is called from add, which
-// is called from the profiling signal handler, so it must not
-// allocate memory or block.  It is safe to call flushlog.
-// evict returns true if the entry was copied to the log,
-// false if there was no room available.
-func (p *cpuProfile) evict(e *cpuprofEntry) bool {
-	d := e.depth
-	nslot := d + 2
-	log := &p.log[p.toggle]
-	if p.nlog+nslot > uintptr(len(p.log[0])) {
-		if !p.flushlog() {
-			return false
-		}
-		log = &p.log[p.toggle]
-	}
-
-	q := p.nlog
-	log[q] = e.count
-	q++
-	log[q] = d
-	q++
-	copy(log[q:], e.stack[:d])
-	q += d
-	p.nlog = q
-	e.count = 0
-	return true
-}
-
-// flushlog tries to flush the current log and switch to the other one.
-// flushlog is called from evict, called from add, called from the signal handler,
-// so it cannot allocate memory or block.  It can try to swap logs with
-// the writing goroutine, as explained in the comment at the top of this file.
-func (p *cpuProfile) flushlog() bool {
-	if !cas(&p.handoff, 0, uint32(p.nlog)) {
-		return false
-	}
-	notewakeup(&p.wait)
-
-	p.toggle = 1 - p.toggle
-	log := &p.log[p.toggle]
-	q := uintptr(0)
-	if p.lost > 0 {
-		lostPC := funcPC(lostProfileData)
-		log[0] = p.lost
-		log[1] = 1
-		log[2] = lostPC
-		q = 3
-		p.lost = 0
-	}
-	p.nlog = q
-	return true
-}
-
-// getprofile blocks until the next block of profiling data is available
-// and returns it as a []byte.  It is called from the writing goroutine.
-func (p *cpuProfile) getprofile() []byte {
-	if p == nil {
-		return nil
-	}
-
-	if p.wholding {
-		// Release previous log to signal handling side.
-		// Loop because we are racing against SetCPUProfileRate(0).
-		for {
-			n := p.handoff
-			if n == 0 {
-				print("runtime: phase error during cpu profile handoff\n")
-				return nil
-			}
-			if n&0x80000000 != 0 {
-				p.wtoggle = 1 - p.wtoggle
-				p.wholding = false
-				p.flushing = true
-				goto Flush
-			}
-			if cas(&p.handoff, n, 0) {
-				break
-			}
-		}
-		p.wtoggle = 1 - p.wtoggle
-		p.wholding = false
-	}
-
-	if p.flushing {
-		goto Flush
-	}
-
-	if !p.on && p.handoff == 0 {
-		return nil
-	}
-
-	// Wait for new log.
-	notetsleepg(&p.wait, -1)
-	noteclear(&p.wait)
-
-	switch n := p.handoff; {
-	case n == 0:
-		print("runtime: phase error during cpu profile wait\n")
-		return nil
-	case n == 0x80000000:
-		p.flushing = true
-		goto Flush
-	default:
-		n &^= 0x80000000
-
-		// Return new log to caller.
-		p.wholding = true
-
-		return uintptrBytes(p.log[p.wtoggle][:n])
-	}
-
-	// In flush mode.
-	// Add is no longer being called.  We own the log.
-	// Also, p->handoff is non-zero, so flushlog will return false.
-	// Evict the hash table into the log and return it.
-Flush:
-	for i := range p.hash {
-		b := &p.hash[i]
-		for j := range b.entry {
-			e := &b.entry[j]
-			if e.count > 0 && !p.evict(e) {
-				// Filled the log.  Stop the loop and return what we've got.
-				break Flush
-			}
-		}
-	}
-
-	// Return pending log data.
-	if p.nlog > 0 {
-		// Note that we're using toggle now, not wtoggle,
-		// because we're working on the log directly.
-		n := p.nlog
-		p.nlog = 0
-		return uintptrBytes(p.log[p.toggle][:n])
-	}
-
-	// Made it through the table without finding anything to log.
-	if !p.eodSent {
-		// We may not have space to append this to the partial log buf,
-		// so we always return a new slice for the end-of-data marker.
-		p.eodSent = true
-		return uintptrBytes(eod[:])
-	}
-
-	// Finally done.  Clean up and return nil.
-	p.flushing = false
-	if !cas(&p.handoff, p.handoff, 0) {
-		print("runtime: profile flush racing with something\n")
-	}
-	return nil
-}
-
-func uintptrBytes(p []uintptr) (ret []byte) {
-	pp := (*sliceStruct)(unsafe.Pointer(&p))
-	rp := (*sliceStruct)(unsafe.Pointer(&ret))
-
-	rp.array = pp.array
-	rp.len = pp.len * int(unsafe.Sizeof(p[0]))
-	rp.cap = rp.len
-
-	return
-}
-
-// CPUProfile returns the next chunk of binary CPU profiling stack trace data,
-// blocking until data is available.  If profiling is turned off and all the profile
-// data accumulated while it was on has been returned, CPUProfile returns nil.
-// The caller must save the returned data before calling CPUProfile again.
-//
-// Most clients should use the runtime/pprof package or
-// the testing package's -test.cpuprofile flag instead of calling
-// CPUProfile directly.
-func CPUProfile() []byte {
-	return cpuprof.getprofile()
-}
diff --git a/third_party/gofrontend/libgo/go/runtime/crash_cgo_test.go b/third_party/gofrontend/libgo/go/runtime/crash_cgo_test.go
index 29f90fa..2e65e4c 100644
--- a/third_party/gofrontend/libgo/go/runtime/crash_cgo_test.go
+++ b/third_party/gofrontend/libgo/go/runtime/crash_cgo_test.go
@@ -36,6 +36,20 @@
 	}
 }
 
+func TestCgoCallbackGC(t *testing.T) {
+	if runtime.GOOS == "plan9" || runtime.GOOS == "windows" {
+		t.Skipf("no pthreads on %s", runtime.GOOS)
+	}
+	if testing.Short() && runtime.GOOS == "dragonfly" {
+		t.Skip("see golang.org/issue/11990")
+	}
+	got := executeTest(t, cgoCallbackGCSource, nil)
+	want := "OK\n"
+	if got != want {
+		t.Fatalf("expected %q, but got %q", want, got)
+	}
+}
+
 func TestCgoExternalThreadPanic(t *testing.T) {
 	if runtime.GOOS == "plan9" {
 		t.Skipf("no pthreads on %s", runtime.GOOS)
@@ -57,16 +71,23 @@
 	case "plan9", "windows":
 		t.Skipf("no pthreads on %s", runtime.GOOS)
 	case "darwin":
-		// static constructor needs external linking, but we don't support
-		// external linking on OS X 10.6.
-		out, err := exec.Command("uname", "-r").Output()
-		if err != nil {
-			t.Fatalf("uname -r failed: %v", err)
+		if runtime.GOARCH != "arm" && runtime.GOARCH != "arm64" {
+			// static constructor needs external linking, but we don't support
+			// external linking on OS X 10.6.
+			out, err := exec.Command("uname", "-r").Output()
+			if err != nil {
+				t.Fatalf("uname -r failed: %v", err)
+			}
+			// OS X 10.6 == Darwin 10.x
+			if strings.HasPrefix(string(out), "10.") {
+				t.Skipf("no external linking on OS X 10.6")
+			}
 		}
-		// OS X 10.6 == Darwin 10.x
-		if strings.HasPrefix(string(out), "10.") {
-			t.Skipf("no external linking on OS X 10.6")
-		}
+	}
+	if runtime.GOARCH == "ppc64" || runtime.GOARCH == "ppc64le" {
+		// TODO(austin) External linking not implemented on
+		// ppc64 (issue #8912)
+		t.Skipf("no external linking on ppc64")
 	}
 	got := executeTest(t, cgoExternalThreadSIGPROFSource, nil)
 	want := "OK\n"
@@ -75,6 +96,31 @@
 	}
 }
 
+func TestCgoExternalThreadSignal(t *testing.T) {
+	// issue 10139
+	switch runtime.GOOS {
+	case "plan9", "windows":
+		t.Skipf("no pthreads on %s", runtime.GOOS)
+	}
+	got := executeTest(t, cgoExternalThreadSignalSource, nil)
+	want := "OK\n"
+	if got != want {
+		t.Fatalf("expected %q, but got %q", want, got)
+	}
+}
+
+func TestCgoDLLImports(t *testing.T) {
+	// test issue 9356
+	if runtime.GOOS != "windows" {
+		t.Skip("skipping windows specific test")
+	}
+	got := executeTest(t, cgoDLLImportsMainSource, nil, "a/a.go", cgoDLLImportsPkgSource)
+	want := "OK\n"
+	if got != want {
+		t.Fatalf("expected %q, but got %v", want, got)
+	}
+}
+
 const cgoSignalDeadlockSource = `
 package main
 
@@ -159,6 +205,83 @@
 }
 `
 
+const cgoCallbackGCSource = `
+package main
+
+import "runtime"
+
+/*
+#include <pthread.h>
+
+void go_callback();
+
+static void *thr(void *arg) {
+    go_callback();
+    return 0;
+}
+
+static void foo() {
+    pthread_t th;
+    pthread_create(&th, 0, thr, 0);
+    pthread_join(th, 0);
+}
+*/
+import "C"
+import "fmt"
+
+//export go_callback
+func go_callback() {
+	runtime.GC()
+	grow()
+	runtime.GC()
+}
+
+var cnt int
+
+func grow() {
+	x := 10000
+	sum := 0
+	if grow1(&x, &sum) == 0 {
+		panic("bad")
+	}
+}
+
+func grow1(x, sum *int) int {
+	if *x == 0 {
+		return *sum + 1
+	}
+	*x--
+	sum1 := *sum + *x
+	return grow1(x, &sum1)
+}
+
+func main() {
+	const P = 100
+	done := make(chan bool)
+	// allocate a bunch of stack frames and spray them with pointers
+	for i := 0; i < P; i++ {
+		go func() {
+			grow()
+			done <- true
+		}()
+	}
+	for i := 0; i < P; i++ {
+		<-done
+	}
+	// now give these stack frames to cgo callbacks
+	for i := 0; i < P; i++ {
+		go func() {
+			C.foo()
+			done <- true
+		}()
+	}
+	for i := 0; i < P; i++ {
+		<-done
+	}
+	fmt.Printf("OK\n")
+}
+`
+
 const cgoExternalThreadPanicSource = `
 package main
 
@@ -254,7 +377,7 @@
 func main() {
 	// This test intends to test that sending SIGPROF to foreign threads
 	// before we make any cgo call will not abort the whole process, so
-	// we cannot make any cgo call here. See http://golang.org/issue/9456.
+	// we cannot make any cgo call here. See https://golang.org/issue/9456.
 	atomic.StoreInt32((*int32)(unsafe.Pointer(&C.spinlock)), 1)
 	for atomic.LoadInt32((*int32)(unsafe.Pointer(&C.spinlock))) == 1 {
 		runtime.Gosched()
@@ -262,3 +385,97 @@
 	println("OK")
 }
 `
+
+const cgoExternalThreadSignalSource = `
+package main
+
+/*
+#include <pthread.h>
+
+void **nullptr;
+
+void *crash(void *p) {
+	*nullptr = p;
+	return 0;
+}
+
+int start_crashing_thread(void) {
+	pthread_t tid;
+	return pthread_create(&tid, 0, crash, 0);
+}
+*/
+import "C"
+
+import (
+	"fmt"
+	"os"
+	"os/exec"
+	"time"
+)
+
+func main() {
+	if len(os.Args) > 1 && os.Args[1] == "crash" {
+		i := C.start_crashing_thread()
+		if i != 0 {
+			fmt.Println("pthread_create failed:", i)
+			// Exit with 0 because parent expects us to crash.
+			return
+		}
+
+		// We should crash immediately, but give it plenty of
+		// time before failing (by exiting 0) in case we are
+		// running on a slow system.
+		time.Sleep(5 * time.Second)
+		return
+	}
+
+	out, err := exec.Command(os.Args[0], "crash").CombinedOutput()
+	if err == nil {
+		fmt.Println("C signal did not crash as expected\n")
+		fmt.Printf("%s\n", out)
+		os.Exit(1)
+	}
+
+	fmt.Println("OK")
+}
+`
+
+const cgoDLLImportsMainSource = `
+package main
+
+/*
+#include <windows.h>
+
+DWORD getthread() {
+	return GetCurrentThreadId();
+}
+*/
+import "C"
+
+import "./a"
+
+func main() {
+	C.getthread()
+	a.GetThread()
+	println("OK")
+}
+`
+
+const cgoDLLImportsPkgSource = `
+package a
+
+/*
+#cgo CFLAGS: -mnop-fun-dllimport
+
+#include <windows.h>
+
+DWORD agetthread() {
+	return GetCurrentThreadId();
+}
+*/
+import "C"
+
+func GetThread() uint32 {
+	return uint32(C.agetthread())
+}
+`
diff --git a/third_party/gofrontend/libgo/go/runtime/crash_test.go b/third_party/gofrontend/libgo/go/runtime/crash_test.go
index 7e8a2e4..8efce4d 100644
--- a/third_party/gofrontend/libgo/go/runtime/crash_test.go
+++ b/third_party/gofrontend/libgo/go/runtime/crash_test.go
@@ -5,38 +5,41 @@
 package runtime_test
 
 import (
+	"fmt"
+	"internal/testenv"
 	"io/ioutil"
 	"os"
 	"os/exec"
 	"path/filepath"
+	"regexp"
 	"runtime"
 	"strings"
+	"sync"
 	"testing"
 	"text/template"
 )
 
-// testEnv excludes GODEBUG from the environment
-// to prevent its output from breaking tests that
-// are trying to parse other command output.
 func testEnv(cmd *exec.Cmd) *exec.Cmd {
 	if cmd.Env != nil {
 		panic("environment already set")
 	}
 	for _, env := range os.Environ() {
+		// Exclude GODEBUG from the environment to prevent its output
+		// from breaking tests that are trying to parse other command output.
 		if strings.HasPrefix(env, "GODEBUG=") {
 			continue
 		}
+		// Exclude GOTRACEBACK for the same reason.
+		if strings.HasPrefix(env, "GOTRACEBACK=") {
+			continue
+		}
 		cmd.Env = append(cmd.Env, env)
 	}
 	return cmd
 }
 
 func executeTest(t *testing.T, templ string, data interface{}, extra ...string) string {
-	t.Skip("gccgo does not have a go command")
-	switch runtime.GOOS {
-	case "android", "nacl":
-		t.Skipf("skipping on %s", runtime.GOOS)
-	}
+	testenv.MustHaveGoBuild(t)
 
 	checkStaleRuntime(t)
 
@@ -63,7 +66,14 @@
 	}
 
 	for i := 0; i < len(extra); i += 2 {
-		if err := ioutil.WriteFile(filepath.Join(dir, extra[i]), []byte(extra[i+1]), 0666); err != nil {
+		fname := extra[i]
+		contents := extra[i+1]
+		if d, _ := filepath.Split(fname); d != "" {
+			if err := os.Mkdir(filepath.Join(dir, d), 0755); err != nil {
+				t.Fatal(err)
+			}
+		}
+		if err := ioutil.WriteFile(filepath.Join(dir, fname), []byte(contents), 0666); err != nil {
 			t.Fatal(err)
 		}
 	}
@@ -79,14 +89,25 @@
 	return string(got)
 }
 
+var (
+	staleRuntimeOnce sync.Once // guards init of staleRuntimeErr
+	staleRuntimeErr  error
+)
+
 func checkStaleRuntime(t *testing.T) {
-	// 'go run' uses the installed copy of runtime.a, which may be out of date.
-	out, err := testEnv(exec.Command("go", "list", "-f", "{{.Stale}}", "runtime")).CombinedOutput()
-	if err != nil {
-		t.Fatalf("failed to execute 'go list': %v\n%v", err, string(out))
-	}
-	if string(out) != "false\n" {
-		t.Fatalf("Stale runtime.a. Run 'go install runtime'.")
+	staleRuntimeOnce.Do(func() {
+		// 'go run' uses the installed copy of runtime.a, which may be out of date.
+		out, err := testEnv(exec.Command("go", "list", "-f", "{{.Stale}}", "runtime")).CombinedOutput()
+		if err != nil {
+			staleRuntimeErr = fmt.Errorf("failed to execute 'go list': %v\n%v", err, string(out))
+			return
+		}
+		if string(out) != "false\n" {
+			staleRuntimeErr = fmt.Errorf("Stale runtime.a. Run 'go install runtime'.")
+		}
+	})
+	if staleRuntimeErr != nil {
+		t.Fatal(staleRuntimeErr)
 	}
 }
 
@@ -205,6 +226,14 @@
 	}
 }
 
+func TestNoHelperGoroutines(t *testing.T) {
+	output := executeTest(t, noHelperGoroutinesSource, nil)
+	matches := regexp.MustCompile(`goroutine [0-9]+ \[`).FindAllStringSubmatch(output, -1)
+	if len(matches) != 1 || matches[0][0] != "goroutine 1 [" {
+		t.Fatalf("want to see only goroutine 1, see:\n%s", output)
+	}
+}
+
 func TestBreakpoint(t *testing.T) {
 	output := executeTest(t, breakpointSource, nil)
 	want := "runtime.Breakpoint()"
@@ -419,6 +448,22 @@
 }
 `
 
+const noHelperGoroutinesSource = `
+package main
+import (
+	"runtime"
+	"time"
+)
+func init() {
+	i := 0
+	runtime.SetFinalizer(&i, func(p *int) {})
+	time.AfterFunc(time.Hour, func() {})
+	panic("oops")
+}
+func main() {
+}
+`
+
 const breakpointSource = `
 package main
 import "runtime"
@@ -514,3 +559,31 @@
 	}()
 	runtime.Goexit()
 }
+
+func TestNetpollDeadlock(t *testing.T) {
+	output := executeTest(t, netpollDeadlockSource, nil)
+	want := "done\n"
+	if !strings.HasSuffix(output, want) {
+		t.Fatalf("output does not start with %q:\n%s", want, output)
+	}
+}
+
+const netpollDeadlockSource = `
+package main
+import (
+	"fmt"
+	"net"
+)
+func init() {
+	fmt.Println("dialing")
+	c, err := net.Dial("tcp", "localhost:14356")
+	if err == nil {
+		c.Close()
+	} else {
+		fmt.Println("error: ", err)
+	}
+}
+func main() {
+	fmt.Println("done")
+}
+`
diff --git a/third_party/gofrontend/libgo/go/runtime/crash_unix_test.go b/third_party/gofrontend/libgo/go/runtime/crash_unix_test.go
new file mode 100644
index 0000000..b925d02
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/runtime/crash_unix_test.go
@@ -0,0 +1,135 @@
+// Copyright 2012 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 darwin dragonfly freebsd linux netbsd openbsd solaris
+
+package runtime_test
+
+import (
+	"bytes"
+	"internal/testenv"
+	"io/ioutil"
+	"os"
+	"os/exec"
+	"path/filepath"
+	"runtime"
+	"syscall"
+	"testing"
+)
+
+func TestCrashDumpsAllThreads(t *testing.T) {
+	switch runtime.GOOS {
+	case "darwin", "dragonfly", "freebsd", "linux", "netbsd", "openbsd", "solaris":
+	default:
+		t.Skipf("skipping; not supported on %v", runtime.GOOS)
+	}
+
+	// We don't use executeTest because we need to kill the
+	// program while it is running.
+
+	testenv.MustHaveGoBuild(t)
+
+	checkStaleRuntime(t)
+
+	dir, err := ioutil.TempDir("", "go-build")
+	if err != nil {
+		t.Fatalf("failed to create temp directory: %v", err)
+	}
+	defer os.RemoveAll(dir)
+
+	if err := ioutil.WriteFile(filepath.Join(dir, "main.go"), []byte(crashDumpsAllThreadsSource), 0666); err != nil {
+		t.Fatalf("failed to create Go file: %v", err)
+	}
+
+	cmd := exec.Command("go", "build", "-o", "a.exe")
+	cmd.Dir = dir
+	out, err := testEnv(cmd).CombinedOutput()
+	if err != nil {
+		t.Fatalf("building source: %v\n%s", err, out)
+	}
+
+	cmd = exec.Command(filepath.Join(dir, "a.exe"))
+	cmd = testEnv(cmd)
+	cmd.Env = append(cmd.Env, "GOTRACEBACK=crash")
+	var outbuf bytes.Buffer
+	cmd.Stdout = &outbuf
+	cmd.Stderr = &outbuf
+
+	rp, wp, err := os.Pipe()
+	if err != nil {
+		t.Fatal(err)
+	}
+	cmd.ExtraFiles = []*os.File{wp}
+
+	if err := cmd.Start(); err != nil {
+		t.Fatalf("starting program: %v", err)
+	}
+
+	if err := wp.Close(); err != nil {
+		t.Logf("closing write pipe: %v", err)
+	}
+	if _, err := rp.Read(make([]byte, 1)); err != nil {
+		t.Fatalf("reading from pipe: %v", err)
+	}
+
+	if err := cmd.Process.Signal(syscall.SIGQUIT); err != nil {
+		t.Fatalf("signal: %v", err)
+	}
+
+	// No point in checking the error return from Wait--we expect
+	// it to fail.
+	cmd.Wait()
+
+	// We want to see a stack trace for each thread.
+	// Before https://golang.org/cl/2811 running threads would say
+	// "goroutine running on other thread; stack unavailable".
+	out = outbuf.Bytes()
+	n := bytes.Count(out, []byte("main.loop("))
+	if n != 4 {
+		t.Errorf("found %d instances of main.loop; expected 4", n)
+		t.Logf("%s", out)
+	}
+}
+
+const crashDumpsAllThreadsSource = `
+package main
+
+import (
+	"fmt"
+	"os"
+	"runtime"
+)
+
+func main() {
+	const count = 4
+	runtime.GOMAXPROCS(count + 1)
+
+	chans := make([]chan bool, count)
+	for i := range chans {
+		chans[i] = make(chan bool)
+		go loop(i, chans[i])
+	}
+
+	// Wait for all the goroutines to start executing.
+	for _, c := range chans {
+		<-c
+	}
+
+	// Tell our parent that all the goroutines are executing.
+	if _, err := os.NewFile(3, "pipe").WriteString("x"); err != nil {
+		fmt.Fprintf(os.Stderr, "write to pipe failed: %v\n", err)
+		os.Exit(2)
+	}
+
+	select {}
+}
+
+func loop(i int, c chan bool) {
+	close(c)
+	for {
+		for j := 0; j < 0x7fffffff; j++ {
+		}
+	}
+}
+`
diff --git a/third_party/gofrontend/libgo/go/runtime/debug/garbage.go b/third_party/gofrontend/libgo/go/runtime/debug/garbage.go
index edb3643..c3363f9 100644
--- a/third_party/gofrontend/libgo/go/runtime/debug/garbage.go
+++ b/third_party/gofrontend/libgo/go/runtime/debug/garbage.go
@@ -149,5 +149,5 @@
 
 // WriteHeapDump writes a description of the heap and the objects in
 // it to the given file descriptor.
-// The heap dump format is defined at http://golang.org/s/go13heapdump.
+// The heap dump format is defined at https://golang.org/s/go13heapdump.
 func WriteHeapDump(fd uintptr)
diff --git a/third_party/gofrontend/libgo/go/runtime/debug/garbage_test.go b/third_party/gofrontend/libgo/go/runtime/debug/garbage_test.go
index 149bafc..13e1845 100644
--- a/third_party/gofrontend/libgo/go/runtime/debug/garbage_test.go
+++ b/third_party/gofrontend/libgo/go/runtime/debug/garbage_test.go
@@ -75,6 +75,10 @@
 var big = make([]byte, 1<<20)
 
 func TestFreeOSMemory(t *testing.T) {
+	if runtime.GOARCH == "arm64" || runtime.GOARCH == "ppc64" || runtime.GOARCH == "ppc64le" ||
+		runtime.GOOS == "nacl" {
+		t.Skip("issue 9993; scavenger temporarily disabled on systems with physical pages larger than logical pages")
+	}
 	var ms1, ms2 runtime.MemStats
 
 	if big == nil {
diff --git a/third_party/gofrontend/libgo/go/runtime/debug/heapdump_test.go b/third_party/gofrontend/libgo/go/runtime/debug/heapdump_test.go
index 9201901..cb2f2f0 100644
--- a/third_party/gofrontend/libgo/go/runtime/debug/heapdump_test.go
+++ b/third_party/gofrontend/libgo/go/runtime/debug/heapdump_test.go
@@ -31,3 +31,39 @@
 		t.Fatalf("Heap dump size %d bytes, expected at least %d bytes", size, minSize)
 	}
 }
+
+type Obj struct {
+	x, y int
+}
+
+func objfin(x *Obj) {
+	println("finalized", x)
+}
+
+func TestWriteHeapDumpFinalizers(t *testing.T) {
+	if runtime.GOOS == "nacl" {
+		t.Skip("WriteHeapDump is not available on NaCl.")
+	}
+	f, err := ioutil.TempFile("", "heapdumptest")
+	if err != nil {
+		t.Fatalf("TempFile failed: %v", err)
+	}
+	defer os.Remove(f.Name())
+	defer f.Close()
+
+	// bug 9172: WriteHeapDump couldn't handle more than one finalizer
+	println("allocating objects")
+	x := &Obj{}
+	runtime.SetFinalizer(x, objfin)
+	y := &Obj{}
+	runtime.SetFinalizer(y, objfin)
+
+	// Trigger collection of x and y, queueing of their finalizers.
+	println("starting gc")
+	runtime.GC()
+
+	// Make sure WriteHeapDump doesn't fail with multiple queued finalizers.
+	println("starting dump")
+	WriteHeapDump(f.Fd())
+	println("done dump")
+}
diff --git a/third_party/gofrontend/libgo/go/runtime/debug/stack.go b/third_party/gofrontend/libgo/go/runtime/debug/stack.go
index c29b0a2..ab12bff 100644
--- a/third_party/gofrontend/libgo/go/runtime/debug/stack.go
+++ b/third_party/gofrontend/libgo/go/runtime/debug/stack.go
@@ -31,7 +31,7 @@
 // then attempts to discover, for Go functions, the calling function or
 // method and the text of the line containing the invocation.
 //
-// This function is deprecated. Use package runtime's Stack instead.
+// Deprecated: Use package runtime's Stack instead.
 func Stack() []byte {
 	return stack()
 }
diff --git a/third_party/gofrontend/libgo/go/runtime/env_posix.go b/third_party/gofrontend/libgo/go/runtime/env_posix.go
deleted file mode 100644
index 8b1dbb7..0000000
--- a/third_party/gofrontend/libgo/go/runtime/env_posix.go
+++ /dev/null
@@ -1,58 +0,0 @@
-// Copyright 2012 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 darwin dragonfly freebsd linux nacl netbsd openbsd solaris windows
-
-package runtime
-
-import "unsafe"
-
-func environ() []string
-
-func getenv(s *byte) *byte {
-	val := gogetenv(gostringnocopy(s))
-	if val == "" {
-		return nil
-	}
-	// Strings found in environment are NUL-terminated.
-	return &bytes(val)[0]
-}
-
-func gogetenv(key string) string {
-	env := environ()
-	if env == nil {
-		gothrow("getenv before env init")
-	}
-	for _, s := range environ() {
-		if len(s) > len(key) && s[len(key)] == '=' && s[:len(key)] == key {
-			return s[len(key)+1:]
-		}
-	}
-	return ""
-}
-
-//extern setenv
-func _cgo_setenv(unsafe.Pointer, unsafe.Pointer, int32)
-
-//extern unsetenv
-func _cgo_unsetenv(unsafe.Pointer)
-
-// Update the C environment if cgo is loaded.
-// Called from syscall.Setenv.
-func syscall_setenv_c(k string, v string) {
-	_cgo_setenv(cstring(k), cstring(v), 1)
-}
-
-// Update the C environment if cgo is loaded.
-// Called from syscall.unsetenv.
-func syscall_unsetenv_c(k string) {
-	_cgo_unsetenv(cstring(k))
-}
-
-func cstring(s string) unsafe.Pointer {
-	p := make([]byte, len(s)+1)
-	sp := (*_string)(unsafe.Pointer(&s))
-	memmove(unsafe.Pointer(&p[0]), unsafe.Pointer(sp.str), uintptr(len(s)))
-	return unsafe.Pointer(&p[0])
-}
diff --git a/third_party/gofrontend/libgo/go/runtime/env_test.go b/third_party/gofrontend/libgo/go/runtime/env_test.go
new file mode 100644
index 0000000..2399e46
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/runtime/env_test.go
@@ -0,0 +1,47 @@
+// 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 runtime_test
+
+import (
+	"runtime"
+	"syscall"
+	"testing"
+)
+
+func TestFixedGOROOT(t *testing.T) {
+	if runtime.GOOS == "plan9" {
+		t.Skipf("skipping plan9, it is inconsistent by allowing GOROOT to be updated by Setenv")
+	}
+
+	// Restore both the real GOROOT environment variable, and runtime's copies:
+	if orig, ok := syscall.Getenv("GOROOT"); ok {
+		defer syscall.Setenv("GOROOT", orig)
+	} else {
+		defer syscall.Unsetenv("GOROOT")
+	}
+	envs := runtime.Envs()
+	oldenvs := append([]string{}, envs...)
+	defer runtime.SetEnvs(oldenvs)
+
+	// attempt to reuse existing envs backing array.
+	want := runtime.GOROOT()
+	runtime.SetEnvs(append(envs[:0], "GOROOT="+want))
+
+	if got := runtime.GOROOT(); got != want {
+		t.Errorf(`initial runtime.GOROOT()=%q, want %q`, got, want)
+	}
+	if err := syscall.Setenv("GOROOT", "/os"); err != nil {
+		t.Fatal(err)
+	}
+	if got := runtime.GOROOT(); got != want {
+		t.Errorf(`after setenv runtime.GOROOT()=%q, want %q`, got, want)
+	}
+	if err := syscall.Unsetenv("GOROOT"); err != nil {
+		t.Fatal(err)
+	}
+	if got := runtime.GOROOT(); got != want {
+		t.Errorf(`after unsetenv runtime.GOROOT()=%q, want %q`, got, want)
+	}
+}
diff --git a/third_party/gofrontend/libgo/go/runtime/error.go b/third_party/gofrontend/libgo/go/runtime/error.go
index d759a54..c4621b6 100644
--- a/third_party/gofrontend/libgo/go/runtime/error.go
+++ b/third_party/gofrontend/libgo/go/runtime/error.go
@@ -9,9 +9,9 @@
 	error
 
 	// RuntimeError is a no-op function but
-	// serves to distinguish types that are runtime
+	// serves to distinguish types that are run time
 	// errors from ordinary errors: a type is a
-	// runtime error if it has a RuntimeError method.
+	// run time error if it has a RuntimeError method.
 	RuntimeError()
 }
 
diff --git a/third_party/gofrontend/libgo/go/internal/syscall/dummy.go b/third_party/gofrontend/libgo/go/runtime/export_arm_test.go
similarity index 70%
copy from third_party/gofrontend/libgo/go/internal/syscall/dummy.go
copy to third_party/gofrontend/libgo/go/runtime/export_arm_test.go
index b00eb27..446d264 100644
--- a/third_party/gofrontend/libgo/go/internal/syscall/dummy.go
+++ b/third_party/gofrontend/libgo/go/runtime/export_arm_test.go
@@ -2,4 +2,8 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-package syscall
+// Export guts for testing.
+
+package runtime
+
+var Usplit = usplit
diff --git a/third_party/gofrontend/libgo/go/internal/syscall/dummy.go b/third_party/gofrontend/libgo/go/runtime/export_linux_test.go
similarity index 67%
copy from third_party/gofrontend/libgo/go/internal/syscall/dummy.go
copy to third_party/gofrontend/libgo/go/runtime/export_linux_test.go
index b00eb27..37cf164 100644
--- a/third_party/gofrontend/libgo/go/internal/syscall/dummy.go
+++ b/third_party/gofrontend/libgo/go/runtime/export_linux_test.go
@@ -2,4 +2,8 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-package syscall
+// Export guts for testing.
+
+package runtime
+
+//var NewOSProc0 = newosproc0
diff --git a/third_party/gofrontend/libgo/go/runtime/export_test.go b/third_party/gofrontend/libgo/go/runtime/export_test.go
index 165bebf..8782914 100644
--- a/third_party/gofrontend/libgo/go/runtime/export_test.go
+++ b/third_party/gofrontend/libgo/go/runtime/export_test.go
@@ -6,26 +6,33 @@
 
 package runtime
 
-var Fadd64 = fadd64
-var Fsub64 = fsub64
-var Fmul64 = fmul64
-var Fdiv64 = fdiv64
-var F64to32 = f64to32
-var F32to64 = f32to64
-var Fcmp64 = fcmp64
-var Fintto64 = fintto64
-var F64toint = f64toint
+import "unsafe"
 
-func entersyscall()
-func exitsyscall()
+//var Fadd64 = fadd64
+//var Fsub64 = fsub64
+//var Fmul64 = fmul64
+//var Fdiv64 = fdiv64
+//var F64to32 = f64to32
+//var F32to64 = f32to64
+//var Fcmp64 = fcmp64
+//var Fintto64 = fintto64
+//var F64toint = f64toint
+//var Sqrt = sqrt
+
+func entersyscall(int32)
+func exitsyscall(int32)
 func golockedOSThread() bool
 
 var Entersyscall = entersyscall
 var Exitsyscall = exitsyscall
 var LockedOSThread = golockedOSThread
 
+// var Xadduintptr = xadduintptr
+
+// var FuncPC = funcPC
+
 type LFNode struct {
-	Next    *LFNode
+	Next    uint64
 	Pushcnt uintptr
 }
 
@@ -36,18 +43,16 @@
 var LFStackPop = lfstackpop_go
 
 type ParFor struct {
-	body    *byte
-	done    uint32
-	Nthr    uint32
-	nthrmax uint32
-	thrseq  uint32
-	Cnt     uint32
-	Ctx     *byte
-	wait    bool
+	body   func(*ParFor, uint32)
+	done   uint32
+	Nthr   uint32
+	thrseq uint32
+	Cnt    uint32
+	wait   bool
 }
 
 func newParFor(nthrmax uint32) *ParFor
-func parForSetup(desc *ParFor, nthr, n uint32, ctx *byte, wait bool, body func(*ParFor, uint32))
+func parForSetup(desc *ParFor, nthr, n uint32, wait bool, body func(*ParFor, uint32))
 func parForDo(desc *ParFor)
 func parForIters(desc *ParFor, tid uintptr) (uintptr, uintptr)
 
@@ -60,31 +65,110 @@
 	return uint32(begin), uint32(end)
 }
 
-func testSchedLocalQueue()
-func testSchedLocalQueueSteal()
+func GCMask(x interface{}) (ret []byte) {
+	return nil
+}
 
-var TestSchedLocalQueue1 = testSchedLocalQueue
-var TestSchedLocalQueueSteal1 = testSchedLocalQueueSteal
+//func testSchedLocalQueue()
+//func testSchedLocalQueueSteal()
+//
+//func RunSchedLocalQueueTest() {
+//	testSchedLocalQueue()
+//}
+//
+//func RunSchedLocalQueueStealTest() {
+//	testSchedLocalQueueSteal()
+//}
 
-// func haveGoodHash() bool
-// func stringHash(s string, seed uintptr) uintptr
-// func bytesHash(b []byte, seed uintptr) uintptr
-// func int32Hash(i uint32, seed uintptr) uintptr
-// func int64Hash(i uint64, seed uintptr) uintptr
+//var StringHash = stringHash
+//var BytesHash = bytesHash
+//var Int32Hash = int32Hash
+//var Int64Hash = int64Hash
+//var EfaceHash = efaceHash
+//var IfaceHash = ifaceHash
+//var MemclrBytes = memclrBytes
 
-// var HaveGoodHash = haveGoodHash
-// var StringHash = stringHash
-// var BytesHash = bytesHash
-// var Int32Hash = int32Hash
-// var Int64Hash = int64Hash
+// var HashLoad = &hashLoad
 
-var hashLoad float64 // declared in hashmap.c
-var HashLoad = &hashLoad
+// entry point for testing
+//func GostringW(w []uint16) (s string) {
+//	s = gostringw(&w[0])
+//	return
+//}
 
-func memclrBytes(b []byte)
+//var Gostringnocopy = gostringnocopy
+//var Maxstring = &maxstring
 
-var MemclrBytes = memclrBytes
+//type Uintreg uintreg
 
-// func gogoBytes() int32
+//extern __go_open
+func open(path *byte, mode int32, perm int32) int32
 
-// var GogoBytes = gogoBytes
+func Open(path *byte, mode int32, perm int32) int32 {
+	return open(path, mode, perm)
+}
+
+//extern close
+func close(int32) int32
+
+func Close(fd int32) int32 {
+	return close(fd)
+}
+
+//extern read
+func read(fd int32, buf unsafe.Pointer, size int32) int32
+
+func Read(fd int32, buf unsafe.Pointer, size int32) int32 {
+	return read(fd, buf, size)
+}
+
+//extern write
+func write(fd int32, buf unsafe.Pointer, size int32) int32
+
+func Write(fd uintptr, buf unsafe.Pointer, size int32) int32 {
+	return write(int32(fd), buf, size)
+}
+
+func envs() []string
+func setenvs([]string)
+
+var Envs = envs
+var SetEnvs = setenvs
+
+//var BigEndian = _BigEndian
+
+// For benchmarking.
+
+/*
+func BenchSetType(n int, x interface{}) {
+	e := *(*eface)(unsafe.Pointer(&x))
+	t := e._type
+	var size uintptr
+	var p unsafe.Pointer
+	switch t.kind & kindMask {
+	case _KindPtr:
+		t = (*ptrtype)(unsafe.Pointer(t)).elem
+		size = t.size
+		p = e.data
+	case _KindSlice:
+		slice := *(*struct {
+			ptr      unsafe.Pointer
+			len, cap uintptr
+		})(e.data)
+		t = (*slicetype)(unsafe.Pointer(t)).elem
+		size = t.size * slice.len
+		p = slice.ptr
+	}
+	allocSize := roundupsize(size)
+	systemstack(func() {
+		for i := 0; i < n; i++ {
+			heapBitsSetType(uintptr(p), allocSize, size, t)
+		}
+	})
+}
+
+const PtrSize = ptrSize
+
+var TestingAssertE2I2GC = &testingAssertE2I2GC
+var TestingAssertE2T2GC = &testingAssertE2T2GC
+*/
diff --git a/third_party/gofrontend/libgo/go/runtime/export_windows_test.go b/third_party/gofrontend/libgo/go/runtime/export_windows_test.go
new file mode 100644
index 0000000..61fcef9
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/runtime/export_windows_test.go
@@ -0,0 +1,9 @@
+// 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.
+
+// Export guts for testing.
+
+package runtime
+
+var TestingWER = &testingWER
diff --git a/third_party/gofrontend/libgo/go/runtime/extern.go b/third_party/gofrontend/libgo/go/runtime/extern.go
index 3c3e427..6301d01 100644
--- a/third_party/gofrontend/libgo/go/runtime/extern.go
+++ b/third_party/gofrontend/libgo/go/runtime/extern.go
@@ -19,10 +19,10 @@
 remaining after the previous collection reaches this percentage. The default
 is GOGC=100. Setting GOGC=off disables the garbage collector entirely.
 The runtime/debug package's SetGCPercent function allows changing this
-percentage at run time. See http://golang.org/pkg/runtime/debug/#SetGCPercent.
+percentage at run time. See https://golang.org/pkg/runtime/debug/#SetGCPercent.
 
-The GODEBUG variable controls debug output from the runtime. GODEBUG value is
-a comma-separated list of name=val pairs. Supported names are:
+The GODEBUG variable controls debugging variables within the runtime.
+It is a comma-separated list of name=val pairs setting these named variables:
 
 	allocfreetrace: setting allocfreetrace=1 causes every allocation to be
 	profiled and a stack trace printed on each object's allocation and free.
@@ -31,18 +31,64 @@
 	where each object is allocated on a unique page and addresses are
 	never recycled.
 
+	gccheckmark: setting gccheckmark=1 enables verification of the
+	garbage collector's concurrent mark phase by performing a
+	second mark pass while the world is stopped.  If the second
+	pass finds a reachable object that was not found by concurrent
+	mark, the garbage collector will panic.
+
+	gcpacertrace: setting gcpacertrace=1 causes the garbage collector to
+	print information about the internal state of the concurrent pacer.
+
+	gcshrinkstackoff: setting gcshrinkstackoff=1 disables moving goroutines
+	onto smaller stacks. In this mode, a goroutine's stack can only grow.
+
+	gcstackbarrieroff: setting gcstackbarrieroff=1 disables the use of stack barriers
+	that allow the garbage collector to avoid repeating a stack scan during the
+	mark termination phase.
+
+	gcstackbarrierall: setting gcstackbarrierall=1 installs stack barriers
+	in every stack frame, rather than in exponentially-spaced frames.
+
+	gcstoptheworld: setting gcstoptheworld=1 disables concurrent garbage collection,
+	making every garbage collection a stop-the-world event. Setting gcstoptheworld=2
+	also disables concurrent sweeping after the garbage collection finishes.
+
 	gctrace: setting gctrace=1 causes the garbage collector to emit a single line to standard
 	error at each collection, summarizing the amount of memory collected and the
 	length of the pause. Setting gctrace=2 emits the same summary but also
-	repeats each collection.
+	repeats each collection. The format of this line is subject to change.
+	Currently, it is:
+		gc # @#s #%: #+...+# ms clock, #+...+# ms cpu, #->#-># MB, # MB goal, # P
+	where the fields are as follows:
+		gc #        the GC number, incremented at each GC
+		@#s         time in seconds since program start
+		#%          percentage of time spent in GC since program start
+		#+...+#     wall-clock/CPU times for the phases of the GC
+		#->#-># MB  heap size at GC start, at GC end, and live heap
+		# MB goal   goal heap size
+		# P         number of processors used
+	The phases are stop-the-world (STW) sweep termination, scan,
+	synchronize Ps, mark, and STW mark termination. The CPU times
+	for mark are broken down in to assist time (GC performed in
+	line with allocation), background GC time, and idle GC time.
+	If the line ends with "(forced)", this GC was forced by a
+	runtime.GC() call and all phases are STW.
 
-	gcdead: setting gcdead=1 causes the garbage collector to clobber all stack slots
-	that it thinks are dead.
+	memprofilerate: setting memprofilerate=X will update the value of runtime.MemProfileRate.
+	When set to 0 memory profiling is disabled.  Refer to the description of
+	MemProfileRate for the default value.
 
 	memprofilerate:  setting memprofilerate=X changes the setting for
 	runtime.MemProfileRate.  Refer to the description of this variable for how
 	it is used and its default value.
 
+	sbrk: setting sbrk=1 replaces the memory allocator and garbage collector
+	with a trivial allocator that obtains memory from the operating system and
+	never reclaims any memory.
+
+	scavenge: scavenge=1 enables debugging mode of heap scavenger.
+
 	scheddetail: setting schedtrace=X and scheddetail=1 causes the scheduler to emit
 	detailed multiline info every X milliseconds, describing state of the scheduler,
 	processors, threads and goroutines.
@@ -70,7 +116,7 @@
 
 The GOARCH, GOOS, GOPATH, and GOROOT environment variables complete
 the set of Go environment variables. They influence the building of Go programs
-(see http://golang.org/cmd/go and http://golang.org/pkg/go/build).
+(see https://golang.org/cmd/go and https://golang.org/pkg/go/build).
 GOARCH, GOOS, and GOROOT are recorded at compile time and made available by
 constants or functions in this package, but they do not influence the execution
 of the run-time system.
diff --git a/third_party/gofrontend/libgo/go/runtime/gc_test.go b/third_party/gofrontend/libgo/go/runtime/gc_test.go
index fe9e839..2a95cc7 100644
--- a/third_party/gofrontend/libgo/go/runtime/gc_test.go
+++ b/third_party/gofrontend/libgo/go/runtime/gc_test.go
@@ -5,7 +5,8 @@
 package runtime_test
 
 import (
-	// "os"
+	"os"
+	"reflect"
 	"runtime"
 	"runtime/debug"
 	"testing"
@@ -14,7 +15,6 @@
 )
 
 func TestGcSys(t *testing.T) {
-	/* gccgo does not have a go command
 	if os.Getenv("GOGC") == "off" {
 		t.Skip("skipping test; GOGC=off in environment")
 	}
@@ -24,7 +24,6 @@
 	if got != want {
 		t.Fatalf("expected %q, but got %q", want, got)
 	}
-	*/
 }
 
 const testGCSysSource = `
@@ -199,45 +198,166 @@
 	}
 }
 
-func BenchmarkSetTypeNoPtr1(b *testing.B) {
-	type NoPtr1 struct {
-		p uintptr
-	}
-	var p *NoPtr1
-	for i := 0; i < b.N; i++ {
-		p = &NoPtr1{}
-	}
-	_ = p
+func BenchmarkSetTypePtr(b *testing.B) {
+	benchSetType(b, new(*byte))
 }
-func BenchmarkSetTypeNoPtr2(b *testing.B) {
-	type NoPtr2 struct {
-		p, q uintptr
-	}
-	var p *NoPtr2
-	for i := 0; i < b.N; i++ {
-		p = &NoPtr2{}
-	}
-	_ = p
+
+func BenchmarkSetTypePtr8(b *testing.B) {
+	benchSetType(b, new([8]*byte))
 }
-func BenchmarkSetTypePtr1(b *testing.B) {
-	type Ptr1 struct {
-		p *byte
-	}
-	var p *Ptr1
-	for i := 0; i < b.N; i++ {
-		p = &Ptr1{}
-	}
-	_ = p
+
+func BenchmarkSetTypePtr16(b *testing.B) {
+	benchSetType(b, new([16]*byte))
 }
-func BenchmarkSetTypePtr2(b *testing.B) {
-	type Ptr2 struct {
-		p, q *byte
+
+func BenchmarkSetTypePtr32(b *testing.B) {
+	benchSetType(b, new([32]*byte))
+}
+
+func BenchmarkSetTypePtr64(b *testing.B) {
+	benchSetType(b, new([64]*byte))
+}
+
+func BenchmarkSetTypePtr126(b *testing.B) {
+	benchSetType(b, new([126]*byte))
+}
+
+func BenchmarkSetTypePtr128(b *testing.B) {
+	benchSetType(b, new([128]*byte))
+}
+
+func BenchmarkSetTypePtrSlice(b *testing.B) {
+	benchSetType(b, make([]*byte, 1<<10))
+}
+
+type Node1 struct {
+	Value       [1]uintptr
+	Left, Right *byte
+}
+
+func BenchmarkSetTypeNode1(b *testing.B) {
+	benchSetType(b, new(Node1))
+}
+
+func BenchmarkSetTypeNode1Slice(b *testing.B) {
+	benchSetType(b, make([]Node1, 32))
+}
+
+type Node8 struct {
+	Value       [8]uintptr
+	Left, Right *byte
+}
+
+func BenchmarkSetTypeNode8(b *testing.B) {
+	benchSetType(b, new(Node8))
+}
+
+func BenchmarkSetTypeNode8Slice(b *testing.B) {
+	benchSetType(b, make([]Node8, 32))
+}
+
+type Node64 struct {
+	Value       [64]uintptr
+	Left, Right *byte
+}
+
+func BenchmarkSetTypeNode64(b *testing.B) {
+	benchSetType(b, new(Node64))
+}
+
+func BenchmarkSetTypeNode64Slice(b *testing.B) {
+	benchSetType(b, make([]Node64, 32))
+}
+
+type Node64Dead struct {
+	Left, Right *byte
+	Value       [64]uintptr
+}
+
+func BenchmarkSetTypeNode64Dead(b *testing.B) {
+	benchSetType(b, new(Node64Dead))
+}
+
+func BenchmarkSetTypeNode64DeadSlice(b *testing.B) {
+	benchSetType(b, make([]Node64Dead, 32))
+}
+
+type Node124 struct {
+	Value       [124]uintptr
+	Left, Right *byte
+}
+
+func BenchmarkSetTypeNode124(b *testing.B) {
+	benchSetType(b, new(Node124))
+}
+
+func BenchmarkSetTypeNode124Slice(b *testing.B) {
+	benchSetType(b, make([]Node124, 32))
+}
+
+type Node126 struct {
+	Value       [126]uintptr
+	Left, Right *byte
+}
+
+func BenchmarkSetTypeNode126(b *testing.B) {
+	benchSetType(b, new(Node126))
+}
+
+func BenchmarkSetTypeNode126Slice(b *testing.B) {
+	benchSetType(b, make([]Node126, 32))
+}
+
+type Node128 struct {
+	Value       [128]uintptr
+	Left, Right *byte
+}
+
+func BenchmarkSetTypeNode128(b *testing.B) {
+	benchSetType(b, new(Node128))
+}
+
+func BenchmarkSetTypeNode128Slice(b *testing.B) {
+	benchSetType(b, make([]Node128, 32))
+}
+
+type Node130 struct {
+	Value       [130]uintptr
+	Left, Right *byte
+}
+
+func BenchmarkSetTypeNode130(b *testing.B) {
+	benchSetType(b, new(Node130))
+}
+
+func BenchmarkSetTypeNode130Slice(b *testing.B) {
+	benchSetType(b, make([]Node130, 32))
+}
+
+type Node1024 struct {
+	Value       [1024]uintptr
+	Left, Right *byte
+}
+
+func BenchmarkSetTypeNode1024(b *testing.B) {
+	benchSetType(b, new(Node1024))
+}
+
+func BenchmarkSetTypeNode1024Slice(b *testing.B) {
+	benchSetType(b, make([]Node1024, 32))
+}
+
+func benchSetType(b *testing.B, x interface{}) {
+	v := reflect.ValueOf(x)
+	t := v.Type()
+	switch t.Kind() {
+	case reflect.Ptr:
+		b.SetBytes(int64(t.Elem().Size()))
+	case reflect.Slice:
+		b.SetBytes(int64(t.Elem().Size()) * int64(v.Len()))
 	}
-	var p *Ptr2
-	for i := 0; i < b.N; i++ {
-		p = &Ptr2{}
-	}
-	_ = p
+	b.ResetTimer()
+	//runtime.BenchSetType(b.N, x)
 }
 
 func BenchmarkAllocation(b *testing.B) {
@@ -292,3 +412,80 @@
 	}
 	close(done)
 }
+
+/*
+
+// The implicit y, ok := x.(error) for the case error
+// in testTypeSwitch used to not initialize the result y
+// before passing &y to assertE2I2GC.
+// Catch this by making assertE2I2 call runtime.GC,
+// which will force a stack scan and failure if there are
+// bad pointers, and then fill the stack with bad pointers
+// and run the type switch.
+func TestAssertE2I2Liveness(t *testing.T) {
+	// Note that this flag is defined in export_test.go
+	// and is not available to ordinary imports of runtime.
+	*runtime.TestingAssertE2I2GC = true
+	defer func() {
+		*runtime.TestingAssertE2I2GC = false
+	}()
+
+	poisonStack()
+	testTypeSwitch(io.EOF)
+	poisonStack()
+	testAssert(io.EOF)
+	poisonStack()
+	testAssertVar(io.EOF)
+}
+
+func poisonStack() uintptr {
+	var x [1000]uintptr
+	for i := range x {
+		x[i] = 0xff
+	}
+	return x[123]
+}
+
+func testTypeSwitch(x interface{}) error {
+	switch y := x.(type) {
+	case nil:
+		// ok
+	case error:
+		return y
+	}
+	return nil
+}
+
+func testAssert(x interface{}) error {
+	if y, ok := x.(error); ok {
+		return y
+	}
+	return nil
+}
+
+func testAssertVar(x interface{}) error {
+	var y, ok = x.(error)
+	if ok {
+		return y
+	}
+	return nil
+}
+
+func TestAssertE2T2Liveness(t *testing.T) {
+	*runtime.TestingAssertE2T2GC = true
+	defer func() {
+		*runtime.TestingAssertE2T2GC = false
+	}()
+
+	poisonStack()
+	testIfaceEqual(io.EOF)
+}
+
+func testIfaceEqual(x interface{}) {
+	if x == "abc" {
+		// Prevent inlining
+		panic("")
+	}
+}
+
+*/
diff --git a/third_party/gofrontend/libgo/go/runtime/gcinfo_test.go b/third_party/gofrontend/libgo/go/runtime/gcinfo_test.go
index 0044992..7e345e5 100644
--- a/third_party/gofrontend/libgo/go/runtime/gcinfo_test.go
+++ b/third_party/gofrontend/libgo/go/runtime/gcinfo_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 ignore
+
 package runtime_test
 
 import (
@@ -10,25 +12,16 @@
 	"testing"
 )
 
+const (
+	typeScalar  = 0
+	typePointer = 1
+)
+
 // TestGCInfo tests that various objects in heap, data and bss receive correct GC pointer type info.
 func TestGCInfo(t *testing.T) {
 	t.Skip("skipping on gccgo for now")
-	verifyGCInfo(t, "bss ScalarPtr", &bssScalarPtr, nonStackInfo(infoScalarPtr))
-	verifyGCInfo(t, "bss PtrScalar", &bssPtrScalar, nonStackInfo(infoPtrScalar))
-	verifyGCInfo(t, "bss BigStruct", &bssBigStruct, nonStackInfo(infoBigStruct()))
-	verifyGCInfo(t, "bss string", &bssString, nonStackInfo(infoString))
-	verifyGCInfo(t, "bss slice", &bssSlice, nonStackInfo(infoSlice))
-	verifyGCInfo(t, "bss eface", &bssEface, nonStackInfo(infoEface))
-	verifyGCInfo(t, "bss iface", &bssIface, nonStackInfo(infoIface))
 
-	verifyGCInfo(t, "data ScalarPtr", &dataScalarPtr, nonStackInfo(infoScalarPtr))
-	verifyGCInfo(t, "data PtrScalar", &dataPtrScalar, nonStackInfo(infoPtrScalar))
-	verifyGCInfo(t, "data BigStruct", &dataBigStruct, nonStackInfo(infoBigStruct()))
-	verifyGCInfo(t, "data string", &dataString, nonStackInfo(infoString))
-	verifyGCInfo(t, "data slice", &dataSlice, nonStackInfo(infoSlice))
-	verifyGCInfo(t, "data eface", &dataEface, nonStackInfo(infoEface))
-	verifyGCInfo(t, "data iface", &dataIface, nonStackInfo(infoIface))
-
+	verifyGCInfo(t, "stack Ptr", new(Ptr), infoPtr)
 	verifyGCInfo(t, "stack ScalarPtr", new(ScalarPtr), infoScalarPtr)
 	verifyGCInfo(t, "stack PtrScalar", new(PtrScalar), infoPtrScalar)
 	verifyGCInfo(t, "stack BigStruct", new(BigStruct), infoBigStruct())
@@ -38,40 +31,43 @@
 	verifyGCInfo(t, "stack iface", new(Iface), infoIface)
 
 	for i := 0; i < 10; i++ {
-		verifyGCInfo(t, "heap ScalarPtr", escape(new(ScalarPtr)), nonStackInfo(infoScalarPtr))
-		verifyGCInfo(t, "heap PtrScalar", escape(new(PtrScalar)), nonStackInfo(infoPtrScalar))
-		verifyGCInfo(t, "heap BigStruct", escape(new(BigStruct)), nonStackInfo(infoBigStruct()))
-		verifyGCInfo(t, "heap string", escape(new(string)), nonStackInfo(infoString))
-		verifyGCInfo(t, "heap eface", escape(new(interface{})), nonStackInfo(infoEface))
-		verifyGCInfo(t, "heap iface", escape(new(Iface)), nonStackInfo(infoIface))
+		verifyGCInfo(t, "heap Ptr", escape(new(Ptr)), trimDead(padDead(infoPtr)))
+		verifyGCInfo(t, "heap PtrSlice", escape(&make([]*byte, 10)[0]), trimDead(infoPtr10))
+		verifyGCInfo(t, "heap ScalarPtr", escape(new(ScalarPtr)), trimDead(infoScalarPtr))
+		verifyGCInfo(t, "heap ScalarPtrSlice", escape(&make([]ScalarPtr, 4)[0]), trimDead(infoScalarPtr4))
+		verifyGCInfo(t, "heap PtrScalar", escape(new(PtrScalar)), trimDead(infoPtrScalar))
+		verifyGCInfo(t, "heap BigStruct", escape(new(BigStruct)), trimDead(infoBigStruct()))
+		verifyGCInfo(t, "heap string", escape(new(string)), trimDead(infoString))
+		verifyGCInfo(t, "heap eface", escape(new(interface{})), trimDead(infoEface))
+		verifyGCInfo(t, "heap iface", escape(new(Iface)), trimDead(infoIface))
 	}
-
 }
 
 func verifyGCInfo(t *testing.T, name string, p interface{}, mask0 []byte) {
-	mask := /* runtime.GCMask(p) */ []byte(nil)
-	if len(mask) > len(mask0) {
-		mask0 = append(mask0, BitsDead)
-		mask = mask[:len(mask0)]
-	}
+	mask := runtime.GCMask(p)
 	if bytes.Compare(mask, mask0) != 0 {
 		t.Errorf("bad GC program for %v:\nwant %+v\ngot  %+v", name, mask0, mask)
 		return
 	}
 }
 
-func nonStackInfo(mask []byte) []byte {
-	// BitsDead is replaced with BitsScalar everywhere except stacks.
-	mask1 := make([]byte, len(mask))
-	mw := false
-	for i, v := range mask {
-		if !mw && v == BitsDead {
-			v = BitsScalar
-		}
-		mw = !mw && v == BitsMultiWord
-		mask1[i] = v
+func padDead(mask []byte) []byte {
+	// Because the dead bit isn't encoded until the third word,
+	// and because on 32-bit systems a one-word allocation
+	// uses a two-word block, the pointer info for a one-word
+	// object needs to be expanded to include an extra scalar
+	// on 32-bit systems to match the heap bitmap.
+	if runtime.PtrSize == 4 && len(mask) == 1 {
+		return []byte{mask[0], 0}
 	}
-	return mask1
+	return mask
+}
+
+func trimDead(mask []byte) []byte {
+	for len(mask) > 2 && mask[len(mask)-1] == typeScalar {
+		mask = mask[:len(mask)-1]
+	}
+	return mask
 }
 
 var gcinfoSink interface{}
@@ -81,19 +77,13 @@
 	return p
 }
 
-const (
-	BitsDead = iota
-	BitsScalar
-	BitsPointer
-	BitsMultiWord
-)
+var infoPtr = []byte{typePointer}
 
-const (
-	BitsString = iota // unused
-	BitsSlice         // unused
-	BitsIface
-	BitsEface
-)
+type Ptr struct {
+	*byte
+}
+
+var infoPtr10 = []byte{typePointer, typePointer, typePointer, typePointer, typePointer, typePointer, typePointer, typePointer, typePointer, typePointer}
 
 type ScalarPtr struct {
 	q int
@@ -104,7 +94,9 @@
 	y *int
 }
 
-var infoScalarPtr = []byte{BitsScalar, BitsPointer, BitsScalar, BitsPointer, BitsScalar, BitsPointer}
+var infoScalarPtr = []byte{typeScalar, typePointer, typeScalar, typePointer, typeScalar, typePointer}
+
+var infoScalarPtr4 = append(append(append(append([]byte(nil), infoScalarPtr...), infoScalarPtr...), infoScalarPtr...), infoScalarPtr...)
 
 type PtrScalar struct {
 	q *int
@@ -115,7 +107,7 @@
 	y int
 }
 
-var infoPtrScalar = []byte{BitsPointer, BitsScalar, BitsPointer, BitsScalar, BitsPointer, BitsScalar}
+var infoPtrScalar = []byte{typePointer, typeScalar, typePointer, typeScalar, typePointer, typeScalar}
 
 type BigStruct struct {
 	q *int
@@ -132,27 +124,27 @@
 	switch runtime.GOARCH {
 	case "386", "arm":
 		return []byte{
-			BitsPointer,                                                // q *int
-			BitsScalar, BitsScalar, BitsScalar, BitsScalar, BitsScalar, // w byte; e [17]byte
-			BitsPointer, BitsDead, BitsDead, // r []byte
-			BitsScalar, BitsScalar, BitsScalar, BitsScalar, // t int; y uint16; u uint64
-			BitsPointer, BitsDead, // i string
+			typePointer,                                                // q *int
+			typeScalar, typeScalar, typeScalar, typeScalar, typeScalar, // w byte; e [17]byte
+			typePointer, typeScalar, typeScalar, // r []byte
+			typeScalar, typeScalar, typeScalar, typeScalar, // t int; y uint16; u uint64
+			typePointer, typeScalar, // i string
 		}
-	case "amd64":
+	case "arm64", "amd64", "ppc64", "ppc64le":
 		return []byte{
-			BitsPointer,                        // q *int
-			BitsScalar, BitsScalar, BitsScalar, // w byte; e [17]byte
-			BitsPointer, BitsDead, BitsDead, // r []byte
-			BitsScalar, BitsScalar, BitsScalar, // t int; y uint16; u uint64
-			BitsPointer, BitsDead, // i string
+			typePointer,                        // q *int
+			typeScalar, typeScalar, typeScalar, // w byte; e [17]byte
+			typePointer, typeScalar, typeScalar, // r []byte
+			typeScalar, typeScalar, typeScalar, // t int; y uint16; u uint64
+			typePointer, typeScalar, // i string
 		}
 	case "amd64p32":
 		return []byte{
-			BitsPointer,                                                // q *int
-			BitsScalar, BitsScalar, BitsScalar, BitsScalar, BitsScalar, // w byte; e [17]byte
-			BitsPointer, BitsDead, BitsDead, // r []byte
-			BitsScalar, BitsScalar, BitsDead, BitsScalar, BitsScalar, // t int; y uint16; u uint64
-			BitsPointer, BitsDead, // i string
+			typePointer,                                                // q *int
+			typeScalar, typeScalar, typeScalar, typeScalar, typeScalar, // w byte; e [17]byte
+			typePointer, typeScalar, typeScalar, // r []byte
+			typeScalar, typeScalar, typeScalar, typeScalar, typeScalar, // t int; y uint16; u uint64
+			typePointer, typeScalar, // i string
 		}
 	default:
 		panic("unknown arch")
@@ -170,6 +162,7 @@
 
 var (
 	// BSS
+	bssPtr       Ptr
 	bssScalarPtr ScalarPtr
 	bssPtrScalar PtrScalar
 	bssBigStruct BigStruct
@@ -179,6 +172,7 @@
 	bssIface     Iface
 
 	// DATA
+	dataPtr                   = Ptr{new(byte)}
 	dataScalarPtr             = ScalarPtr{q: 1}
 	dataPtrScalar             = PtrScalar{w: 1}
 	dataBigStruct             = BigStruct{w: 1}
@@ -187,8 +181,8 @@
 	dataEface     interface{} = 42
 	dataIface     Iface       = IfaceImpl(42)
 
-	infoString = []byte{BitsPointer, BitsDead}
-	infoSlice  = []byte{BitsPointer, BitsDead, BitsDead}
-	infoEface  = []byte{BitsMultiWord, BitsEface}
-	infoIface  = []byte{BitsMultiWord, BitsIface}
+	infoString = []byte{typePointer, typeScalar}
+	infoSlice  = []byte{typePointer, typeScalar, typeScalar}
+	infoEface  = []byte{typePointer, typePointer}
+	infoIface  = []byte{typePointer, typePointer}
 )
diff --git a/third_party/gofrontend/libgo/go/runtime/hashmap.go b/third_party/gofrontend/libgo/go/runtime/hashmap.go
deleted file mode 100644
index 791af8c..0000000
--- a/third_party/gofrontend/libgo/go/runtime/hashmap.go
+++ /dev/null
@@ -1,960 +0,0 @@
-// 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.
-
-package runtime
-
-// This file contains the implementation of Go's map type.
-//
-// A map is just a hash table.  The data is arranged
-// into an array of buckets.  Each bucket contains up to
-// 8 key/value pairs.  The low-order bits of the hash are
-// used to select a bucket.  Each bucket contains a few
-// high-order bits of each hash to distinguish the entries
-// within a single bucket.
-//
-// If more than 8 keys hash to a bucket, we chain on
-// extra buckets.
-//
-// When the hashtable grows, we allocate a new array
-// of buckets twice as big.  Buckets are incrementally
-// copied from the old bucket array to the new bucket array.
-//
-// Map iterators walk through the array of buckets and
-// return the keys in walk order (bucket #, then overflow
-// chain order, then bucket index).  To maintain iteration
-// semantics, we never move keys within their bucket (if
-// we did, keys might be returned 0 or 2 times).  When
-// growing the table, iterators remain iterating through the
-// old table and must check the new table if the bucket
-// they are iterating through has been moved ("evacuated")
-// to the new table.
-
-// Picking loadFactor: too large and we have lots of overflow
-// buckets, too small and we waste a lot of space.  I wrote
-// a simple program to check some stats for different loads:
-// (64-bit, 8 byte keys and values)
-//  loadFactor    %overflow  bytes/entry     hitprobe    missprobe
-//        4.00         2.13        20.77         3.00         4.00
-//        4.50         4.05        17.30         3.25         4.50
-//        5.00         6.85        14.77         3.50         5.00
-//        5.50        10.55        12.94         3.75         5.50
-//        6.00        15.27        11.67         4.00         6.00
-//        6.50        20.90        10.79         4.25         6.50
-//        7.00        27.14        10.15         4.50         7.00
-//        7.50        34.03         9.73         4.75         7.50
-//        8.00        41.10         9.40         5.00         8.00
-//
-// %overflow   = percentage of buckets which have an overflow bucket
-// bytes/entry = overhead bytes used per key/value pair
-// hitprobe    = # of entries to check when looking up a present key
-// missprobe   = # of entries to check when looking up an absent key
-//
-// Keep in mind this data is for maximally loaded tables, i.e. just
-// before the table grows.  Typical tables will be somewhat less loaded.
-
-import (
-	"unsafe"
-)
-
-const (
-	// Maximum number of key/value pairs a bucket can hold.
-	bucketCntBits = 3
-	bucketCnt     = 1 << bucketCntBits
-
-	// Maximum average load of a bucket that triggers growth.
-	loadFactor = 6.5
-
-	// Maximum key or value size to keep inline (instead of mallocing per element).
-	// Must fit in a uint8.
-	// Fast versions cannot handle big values - the cutoff size for
-	// fast versions in ../../cmd/gc/walk.c must be at most this value.
-	maxKeySize   = 128
-	maxValueSize = 128
-
-	// data offset should be the size of the bmap struct, but needs to be
-	// aligned correctly.  For amd64p32 this means 64-bit alignment
-	// even though pointers are 32 bit.
-	dataOffset = unsafe.Offsetof(struct {
-		b bmap
-		v int64
-	}{}.v)
-
-	// Possible tophash values.  We reserve a few possibilities for special marks.
-	// Each bucket (including its overflow buckets, if any) will have either all or none of its
-	// entries in the evacuated* states (except during the evacuate() method, which only happens
-	// during map writes and thus no one else can observe the map during that time).
-	empty          = 0 // cell is empty
-	evacuatedEmpty = 1 // cell is empty, bucket is evacuated.
-	evacuatedX     = 2 // key/value is valid.  Entry has been evacuated to first half of larger table.
-	evacuatedY     = 3 // same as above, but evacuated to second half of larger table.
-	minTopHash     = 4 // minimum tophash for a normal filled cell.
-
-	// flags
-	iterator    = 1 // there may be an iterator using buckets
-	oldIterator = 2 // there may be an iterator using oldbuckets
-
-	// sentinel bucket ID for iterator checks
-	noCheck = 1<<(8*ptrSize) - 1
-
-	// trigger a garbage collection at every alloc called from this code
-	checkgc = false
-)
-
-// A header for a Go map.
-type hmap struct {
-	// Note: the format of the Hmap is encoded in ../../cmd/gc/reflect.c and
-	// ../reflect/type.go.  Don't change this structure without also changing that code!
-	count int // # live cells == size of map.  Must be first (used by len() builtin)
-	flags uint32
-	hash0 uint32 // hash seed
-	B     uint8  // log_2 of # of buckets (can hold up to loadFactor * 2^B items)
-
-	buckets    unsafe.Pointer // array of 2^B Buckets. may be nil if count==0.
-	oldbuckets unsafe.Pointer // previous bucket array of half the size, non-nil only when growing
-	nevacuate  uintptr        // progress counter for evacuation (buckets less than this have been evacuated)
-}
-
-// A bucket for a Go map.
-type bmap struct {
-	tophash [bucketCnt]uint8
-	// Followed by bucketCnt keys and then bucketCnt values.
-	// NOTE: packing all the keys together and then all the values together makes the
-	// code a bit more complicated than alternating key/value/key/value/... but it allows
-	// us to eliminate padding which would be needed for, e.g., map[int64]int8.
-	// Followed by an overflow pointer.
-}
-
-// A hash iteration structure.
-// If you modify hiter, also change cmd/gc/reflect.c to indicate
-// the layout of this structure.
-type hiter struct {
-	key         unsafe.Pointer // Must be in first position.  Write nil to indicate iteration end (see cmd/gc/range.c).
-	value       unsafe.Pointer // Must be in second position (see cmd/gc/range.c).
-	t           *maptype
-	h           *hmap
-	buckets     unsafe.Pointer // bucket ptr at hash_iter initialization time
-	bptr        *bmap          // current bucket
-	startBucket uintptr        // bucket iteration started at
-	offset      uint8          // intra-bucket offset to start from during iteration (should be big enough to hold bucketCnt-1)
-	wrapped     bool           // already wrapped around from end of bucket array to beginning
-	B           uint8
-	i           uint8
-	bucket      uintptr
-	checkBucket uintptr
-}
-
-func evacuated(b *bmap) bool {
-	h := b.tophash[0]
-	return h > empty && h < minTopHash
-}
-
-func (b *bmap) overflow(t *maptype) *bmap {
-	return *(**bmap)(add(unsafe.Pointer(b), uintptr(t.bucketsize)-regSize))
-}
-func (b *bmap) setoverflow(t *maptype, ovf *bmap) {
-	*(**bmap)(add(unsafe.Pointer(b), uintptr(t.bucketsize)-regSize)) = ovf
-}
-
-func makemap(t *maptype, hint int64) *hmap {
-	if sz := unsafe.Sizeof(hmap{}); sz > 48 || sz != uintptr(t.hmap.size) {
-		gothrow("bad hmap size")
-	}
-
-	if hint < 0 || int64(int32(hint)) != hint {
-		panic("makemap: size out of range")
-		// TODO: make hint an int, then none of this nonsense
-	}
-
-	if !ismapkey(t.key) {
-		gothrow("runtime.makemap: unsupported map key type")
-	}
-
-	// check compiler's and reflect's math
-	if t.key.size > maxKeySize && (!t.indirectkey || t.keysize != uint8(ptrSize)) ||
-		t.key.size <= maxKeySize && (t.indirectkey || t.keysize != uint8(t.key.size)) {
-		gothrow("key size wrong")
-	}
-	if t.elem.size > maxValueSize && (!t.indirectvalue || t.valuesize != uint8(ptrSize)) ||
-		t.elem.size <= maxValueSize && (t.indirectvalue || t.valuesize != uint8(t.elem.size)) {
-		gothrow("value size wrong")
-	}
-
-	// invariants we depend on.  We should probably check these at compile time
-	// somewhere, but for now we'll do it here.
-	if t.key.align > bucketCnt {
-		gothrow("key align too big")
-	}
-	if t.elem.align > bucketCnt {
-		gothrow("value align too big")
-	}
-	if uintptr(t.key.size)%uintptr(t.key.align) != 0 {
-		gothrow("key size not a multiple of key align")
-	}
-	if uintptr(t.elem.size)%uintptr(t.elem.align) != 0 {
-		gothrow("value size not a multiple of value align")
-	}
-	if bucketCnt < 8 {
-		gothrow("bucketsize too small for proper alignment")
-	}
-	if dataOffset%uintptr(t.key.align) != 0 {
-		gothrow("need padding in bucket (key)")
-	}
-	if dataOffset%uintptr(t.elem.align) != 0 {
-		gothrow("need padding in bucket (value)")
-	}
-
-	// find size parameter which will hold the requested # of elements
-	B := uint8(0)
-	for ; hint > bucketCnt && float32(hint) > loadFactor*float32(uintptr(1)<<B); B++ {
-	}
-
-	// allocate initial hash table
-	// if B == 0, the buckets field is allocated lazily later (in mapassign)
-	// If hint is large zeroing this memory could take a while.
-	var buckets unsafe.Pointer
-	if B != 0 {
-		if checkgc {
-			memstats.next_gc = memstats.heap_alloc
-		}
-		buckets = newarray(t.bucket, uintptr(1)<<B)
-	}
-
-	// initialize Hmap
-	if checkgc {
-		memstats.next_gc = memstats.heap_alloc
-	}
-	h := (*hmap)(newobject(t.hmap))
-	h.count = 0
-	h.B = B
-	h.flags = 0
-	h.hash0 = fastrand1()
-	h.buckets = buckets
-	h.oldbuckets = nil
-	h.nevacuate = 0
-
-	return h
-}
-
-// mapaccess1 returns a pointer to h[key].  Never returns nil, instead
-// it will return a reference to the zero object for the value type if
-// the key is not in the map.
-// NOTE: The returned pointer may keep the whole map live, so don't
-// hold onto it for very long.
-func mapaccess1(t *maptype, h *hmap, key unsafe.Pointer) unsafe.Pointer {
-	if raceenabled && h != nil {
-		callerpc := getcallerpc(unsafe.Pointer(&t))
-		pc := funcPC(mapaccess1)
-		racereadpc(unsafe.Pointer(h), callerpc, pc)
-		raceReadObjectPC(t.key, key, callerpc, pc)
-	}
-	if h == nil || h.count == 0 {
-		return unsafe.Pointer(t.elem.zero)
-	}
-	alg := goalg(t.key.alg)
-	hash := alg.hash(key, uintptr(t.key.size), uintptr(h.hash0))
-	m := uintptr(1)<<h.B - 1
-	b := (*bmap)(add(h.buckets, (hash&m)*uintptr(t.bucketsize)))
-	if c := h.oldbuckets; c != nil {
-		oldb := (*bmap)(add(c, (hash&(m>>1))*uintptr(t.bucketsize)))
-		if !evacuated(oldb) {
-			b = oldb
-		}
-	}
-	top := uint8(hash >> (ptrSize*8 - 8))
-	if top < minTopHash {
-		top += minTopHash
-	}
-	for {
-		for i := uintptr(0); i < bucketCnt; i++ {
-			if b.tophash[i] != top {
-				continue
-			}
-			k := add(unsafe.Pointer(b), dataOffset+i*uintptr(t.keysize))
-			if t.indirectkey {
-				k = *((*unsafe.Pointer)(k))
-			}
-			if alg.equal(key, k, uintptr(t.key.size)) {
-				v := add(unsafe.Pointer(b), dataOffset+bucketCnt*uintptr(t.keysize)+i*uintptr(t.valuesize))
-				if t.indirectvalue {
-					v = *((*unsafe.Pointer)(v))
-				}
-				return v
-			}
-		}
-		b = b.overflow(t)
-		if b == nil {
-			return unsafe.Pointer(t.elem.zero)
-		}
-	}
-}
-
-func mapaccess2(t *maptype, h *hmap, key unsafe.Pointer) (unsafe.Pointer, bool) {
-	if raceenabled && h != nil {
-		callerpc := getcallerpc(unsafe.Pointer(&t))
-		pc := funcPC(mapaccess2)
-		racereadpc(unsafe.Pointer(h), callerpc, pc)
-		raceReadObjectPC(t.key, key, callerpc, pc)
-	}
-	if h == nil || h.count == 0 {
-		return unsafe.Pointer(t.elem.zero), false
-	}
-	alg := goalg(t.key.alg)
-	hash := alg.hash(key, uintptr(t.key.size), uintptr(h.hash0))
-	m := uintptr(1)<<h.B - 1
-	b := (*bmap)(unsafe.Pointer(uintptr(h.buckets) + (hash&m)*uintptr(t.bucketsize)))
-	if c := h.oldbuckets; c != nil {
-		oldb := (*bmap)(unsafe.Pointer(uintptr(c) + (hash&(m>>1))*uintptr(t.bucketsize)))
-		if !evacuated(oldb) {
-			b = oldb
-		}
-	}
-	top := uint8(hash >> (ptrSize*8 - 8))
-	if top < minTopHash {
-		top += minTopHash
-	}
-	for {
-		for i := uintptr(0); i < bucketCnt; i++ {
-			if b.tophash[i] != top {
-				continue
-			}
-			k := add(unsafe.Pointer(b), dataOffset+i*uintptr(t.keysize))
-			if t.indirectkey {
-				k = *((*unsafe.Pointer)(k))
-			}
-			if alg.equal(key, k, uintptr(t.key.size)) {
-				v := add(unsafe.Pointer(b), dataOffset+bucketCnt*uintptr(t.keysize)+i*uintptr(t.valuesize))
-				if t.indirectvalue {
-					v = *((*unsafe.Pointer)(v))
-				}
-				return v, true
-			}
-		}
-		b = b.overflow(t)
-		if b == nil {
-			return unsafe.Pointer(t.elem.zero), false
-		}
-	}
-}
-
-// returns both key and value.  Used by map iterator
-func mapaccessK(t *maptype, h *hmap, key unsafe.Pointer) (unsafe.Pointer, unsafe.Pointer) {
-	if h == nil || h.count == 0 {
-		return nil, nil
-	}
-	alg := goalg(t.key.alg)
-	hash := alg.hash(key, uintptr(t.key.size), uintptr(h.hash0))
-	m := uintptr(1)<<h.B - 1
-	b := (*bmap)(unsafe.Pointer(uintptr(h.buckets) + (hash&m)*uintptr(t.bucketsize)))
-	if c := h.oldbuckets; c != nil {
-		oldb := (*bmap)(unsafe.Pointer(uintptr(c) + (hash&(m>>1))*uintptr(t.bucketsize)))
-		if !evacuated(oldb) {
-			b = oldb
-		}
-	}
-	top := uint8(hash >> (ptrSize*8 - 8))
-	if top < minTopHash {
-		top += minTopHash
-	}
-	for {
-		for i := uintptr(0); i < bucketCnt; i++ {
-			if b.tophash[i] != top {
-				continue
-			}
-			k := add(unsafe.Pointer(b), dataOffset+i*uintptr(t.keysize))
-			if t.indirectkey {
-				k = *((*unsafe.Pointer)(k))
-			}
-			if alg.equal(key, k, uintptr(t.key.size)) {
-				v := add(unsafe.Pointer(b), dataOffset+bucketCnt*uintptr(t.keysize)+i*uintptr(t.valuesize))
-				if t.indirectvalue {
-					v = *((*unsafe.Pointer)(v))
-				}
-				return k, v
-			}
-		}
-		b = b.overflow(t)
-		if b == nil {
-			return nil, nil
-		}
-	}
-}
-
-func mapassign1(t *maptype, h *hmap, key unsafe.Pointer, val unsafe.Pointer) {
-	if h == nil {
-		panic("assignment to entry in nil map")
-	}
-	if raceenabled {
-		callerpc := getcallerpc(unsafe.Pointer(&t))
-		pc := funcPC(mapassign1)
-		racewritepc(unsafe.Pointer(h), callerpc, pc)
-		raceReadObjectPC(t.key, key, callerpc, pc)
-		raceReadObjectPC(t.elem, val, callerpc, pc)
-	}
-
-	alg := goalg(t.key.alg)
-	hash := alg.hash(key, uintptr(t.key.size), uintptr(h.hash0))
-
-	if h.buckets == nil {
-		if checkgc {
-			memstats.next_gc = memstats.heap_alloc
-		}
-		h.buckets = newarray(t.bucket, 1)
-	}
-
-again:
-	bucket := hash & (uintptr(1)<<h.B - 1)
-	if h.oldbuckets != nil {
-		growWork(t, h, bucket)
-	}
-	b := (*bmap)(unsafe.Pointer(uintptr(h.buckets) + bucket*uintptr(t.bucketsize)))
-	top := uint8(hash >> (ptrSize*8 - 8))
-	if top < minTopHash {
-		top += minTopHash
-	}
-
-	var inserti *uint8
-	var insertk unsafe.Pointer
-	var insertv unsafe.Pointer
-	for {
-		for i := uintptr(0); i < bucketCnt; i++ {
-			if b.tophash[i] != top {
-				if b.tophash[i] == empty && inserti == nil {
-					inserti = &b.tophash[i]
-					insertk = add(unsafe.Pointer(b), dataOffset+i*uintptr(t.keysize))
-					insertv = add(unsafe.Pointer(b), dataOffset+bucketCnt*uintptr(t.keysize)+i*uintptr(t.valuesize))
-				}
-				continue
-			}
-			k := add(unsafe.Pointer(b), dataOffset+i*uintptr(t.keysize))
-			k2 := k
-			if t.indirectkey {
-				k2 = *((*unsafe.Pointer)(k2))
-			}
-			if !alg.equal(key, k2, uintptr(t.key.size)) {
-				continue
-			}
-			// already have a mapping for key.  Update it.
-			memmove(k2, key, uintptr(t.key.size))
-			v := add(unsafe.Pointer(b), dataOffset+bucketCnt*uintptr(t.keysize)+i*uintptr(t.valuesize))
-			v2 := v
-			if t.indirectvalue {
-				v2 = *((*unsafe.Pointer)(v2))
-			}
-			memmove(v2, val, uintptr(t.elem.size))
-			return
-		}
-		ovf := b.overflow(t)
-		if ovf == nil {
-			break
-		}
-		b = ovf
-	}
-
-	// did not find mapping for key.  Allocate new cell & add entry.
-	if float32(h.count) >= loadFactor*float32((uintptr(1)<<h.B)) && h.count >= bucketCnt {
-		hashGrow(t, h)
-		goto again // Growing the table invalidates everything, so try again
-	}
-
-	if inserti == nil {
-		// all current buckets are full, allocate a new one.
-		if checkgc {
-			memstats.next_gc = memstats.heap_alloc
-		}
-		newb := (*bmap)(newobject(t.bucket))
-		b.setoverflow(t, newb)
-		inserti = &newb.tophash[0]
-		insertk = add(unsafe.Pointer(newb), dataOffset)
-		insertv = add(insertk, bucketCnt*uintptr(t.keysize))
-	}
-
-	// store new key/value at insert position
-	if t.indirectkey {
-		if checkgc {
-			memstats.next_gc = memstats.heap_alloc
-		}
-		kmem := newobject(t.key)
-		*(*unsafe.Pointer)(insertk) = kmem
-		insertk = kmem
-	}
-	if t.indirectvalue {
-		if checkgc {
-			memstats.next_gc = memstats.heap_alloc
-		}
-		vmem := newobject(t.elem)
-		*(*unsafe.Pointer)(insertv) = vmem
-		insertv = vmem
-	}
-	memmove(insertk, key, uintptr(t.key.size))
-	memmove(insertv, val, uintptr(t.elem.size))
-	*inserti = top
-	h.count++
-}
-
-func mapdelete(t *maptype, h *hmap, key unsafe.Pointer) {
-	if raceenabled && h != nil {
-		callerpc := getcallerpc(unsafe.Pointer(&t))
-		pc := funcPC(mapdelete)
-		racewritepc(unsafe.Pointer(h), callerpc, pc)
-		raceReadObjectPC(t.key, key, callerpc, pc)
-	}
-	if h == nil || h.count == 0 {
-		return
-	}
-	alg := goalg(t.key.alg)
-	hash := alg.hash(key, uintptr(t.key.size), uintptr(h.hash0))
-	bucket := hash & (uintptr(1)<<h.B - 1)
-	if h.oldbuckets != nil {
-		growWork(t, h, bucket)
-	}
-	b := (*bmap)(unsafe.Pointer(uintptr(h.buckets) + bucket*uintptr(t.bucketsize)))
-	top := uint8(hash >> (ptrSize*8 - 8))
-	if top < minTopHash {
-		top += minTopHash
-	}
-	for {
-		for i := uintptr(0); i < bucketCnt; i++ {
-			if b.tophash[i] != top {
-				continue
-			}
-			k := add(unsafe.Pointer(b), dataOffset+i*uintptr(t.keysize))
-			k2 := k
-			if t.indirectkey {
-				k2 = *((*unsafe.Pointer)(k2))
-			}
-			if !alg.equal(key, k2, uintptr(t.key.size)) {
-				continue
-			}
-			memclr(k, uintptr(t.keysize))
-			v := unsafe.Pointer(uintptr(unsafe.Pointer(b)) + dataOffset + bucketCnt*uintptr(t.keysize) + i*uintptr(t.valuesize))
-			memclr(v, uintptr(t.valuesize))
-			b.tophash[i] = empty
-			h.count--
-			return
-		}
-		b = b.overflow(t)
-		if b == nil {
-			return
-		}
-	}
-}
-
-func mapiterinit(t *maptype, h *hmap, it *hiter) {
-	// Clear pointer fields so garbage collector does not complain.
-	it.key = nil
-	it.value = nil
-	it.t = nil
-	it.h = nil
-	it.buckets = nil
-	it.bptr = nil
-
-	if raceenabled && h != nil {
-		callerpc := getcallerpc(unsafe.Pointer(&t))
-		racereadpc(unsafe.Pointer(h), callerpc, funcPC(mapiterinit))
-	}
-
-	if h == nil || h.count == 0 {
-		it.key = nil
-		it.value = nil
-		return
-	}
-
-	if unsafe.Sizeof(hiter{})/ptrSize != 10 {
-		gothrow("hash_iter size incorrect") // see ../../cmd/gc/reflect.c
-	}
-	it.t = t
-	it.h = h
-
-	// grab snapshot of bucket state
-	it.B = h.B
-	it.buckets = h.buckets
-
-	// decide where to start
-	r := uintptr(fastrand1())
-	if h.B > 31-bucketCntBits {
-		r += uintptr(fastrand1()) << 31
-	}
-	it.startBucket = r & (uintptr(1)<<h.B - 1)
-	it.offset = uint8(r >> h.B & (bucketCnt - 1))
-
-	// iterator state
-	it.bucket = it.startBucket
-	it.wrapped = false
-	it.bptr = nil
-
-	// Remember we have an iterator.
-	// Can run concurrently with another hash_iter_init().
-	for {
-		old := h.flags
-		if old == old|iterator|oldIterator {
-			break
-		}
-		if cas(&h.flags, old, old|iterator|oldIterator) {
-			break
-		}
-	}
-
-	mapiternext(it)
-}
-
-func mapiternext(it *hiter) {
-	h := it.h
-	if raceenabled {
-		callerpc := getcallerpc(unsafe.Pointer(&it))
-		racereadpc(unsafe.Pointer(h), callerpc, funcPC(mapiternext))
-	}
-	t := it.t
-	bucket := it.bucket
-	b := it.bptr
-	i := it.i
-	checkBucket := it.checkBucket
-	alg := goalg(t.key.alg)
-
-next:
-	if b == nil {
-		if bucket == it.startBucket && it.wrapped {
-			// end of iteration
-			it.key = nil
-			it.value = nil
-			return
-		}
-		if h.oldbuckets != nil && it.B == h.B {
-			// Iterator was started in the middle of a grow, and the grow isn't done yet.
-			// If the bucket we're looking at hasn't been filled in yet (i.e. the old
-			// bucket hasn't been evacuated) then we need to iterate through the old
-			// bucket and only return the ones that will be migrated to this bucket.
-			oldbucket := bucket & (uintptr(1)<<(it.B-1) - 1)
-			b = (*bmap)(add(h.oldbuckets, oldbucket*uintptr(t.bucketsize)))
-			if !evacuated(b) {
-				checkBucket = bucket
-			} else {
-				b = (*bmap)(add(it.buckets, bucket*uintptr(t.bucketsize)))
-				checkBucket = noCheck
-			}
-		} else {
-			b = (*bmap)(add(it.buckets, bucket*uintptr(t.bucketsize)))
-			checkBucket = noCheck
-		}
-		bucket++
-		if bucket == uintptr(1)<<it.B {
-			bucket = 0
-			it.wrapped = true
-		}
-		i = 0
-	}
-	for ; i < bucketCnt; i++ {
-		offi := (i + it.offset) & (bucketCnt - 1)
-		k := add(unsafe.Pointer(b), dataOffset+uintptr(offi)*uintptr(t.keysize))
-		v := add(unsafe.Pointer(b), dataOffset+bucketCnt*uintptr(t.keysize)+uintptr(offi)*uintptr(t.valuesize))
-		if b.tophash[offi] != empty && b.tophash[offi] != evacuatedEmpty {
-			if checkBucket != noCheck {
-				// Special case: iterator was started during a grow and the
-				// grow is not done yet.  We're working on a bucket whose
-				// oldbucket has not been evacuated yet.  Or at least, it wasn't
-				// evacuated when we started the bucket.  So we're iterating
-				// through the oldbucket, skipping any keys that will go
-				// to the other new bucket (each oldbucket expands to two
-				// buckets during a grow).
-				k2 := k
-				if t.indirectkey {
-					k2 = *((*unsafe.Pointer)(k2))
-				}
-				if alg.equal(k2, k2, uintptr(t.key.size)) {
-					// If the item in the oldbucket is not destined for
-					// the current new bucket in the iteration, skip it.
-					hash := alg.hash(k2, uintptr(t.key.size), uintptr(h.hash0))
-					if hash&(uintptr(1)<<it.B-1) != checkBucket {
-						continue
-					}
-				} else {
-					// Hash isn't repeatable if k != k (NaNs).  We need a
-					// repeatable and randomish choice of which direction
-					// to send NaNs during evacuation.  We'll use the low
-					// bit of tophash to decide which way NaNs go.
-					// NOTE: this case is why we need two evacuate tophash
-					// values, evacuatedX and evacuatedY, that differ in
-					// their low bit.
-					if checkBucket>>(it.B-1) != uintptr(b.tophash[offi]&1) {
-						continue
-					}
-				}
-			}
-			if b.tophash[offi] != evacuatedX && b.tophash[offi] != evacuatedY {
-				// this is the golden data, we can return it.
-				if t.indirectkey {
-					k = *((*unsafe.Pointer)(k))
-				}
-				it.key = k
-				if t.indirectvalue {
-					v = *((*unsafe.Pointer)(v))
-				}
-				it.value = v
-			} else {
-				// The hash table has grown since the iterator was started.
-				// The golden data for this key is now somewhere else.
-				k2 := k
-				if t.indirectkey {
-					k2 = *((*unsafe.Pointer)(k2))
-				}
-				if alg.equal(k2, k2, uintptr(t.key.size)) {
-					// Check the current hash table for the data.
-					// This code handles the case where the key
-					// has been deleted, updated, or deleted and reinserted.
-					// NOTE: we need to regrab the key as it has potentially been
-					// updated to an equal() but not identical key (e.g. +0.0 vs -0.0).
-					rk, rv := mapaccessK(t, h, k2)
-					if rk == nil {
-						continue // key has been deleted
-					}
-					it.key = rk
-					it.value = rv
-				} else {
-					// if key!=key then the entry can't be deleted or
-					// updated, so we can just return it.  That's lucky for
-					// us because when key!=key we can't look it up
-					// successfully in the current table.
-					it.key = k2
-					if t.indirectvalue {
-						v = *((*unsafe.Pointer)(v))
-					}
-					it.value = v
-				}
-			}
-			it.bucket = bucket
-			it.bptr = b
-			it.i = i + 1
-			it.checkBucket = checkBucket
-			return
-		}
-	}
-	b = b.overflow(t)
-	i = 0
-	goto next
-}
-
-func hashGrow(t *maptype, h *hmap) {
-	if h.oldbuckets != nil {
-		gothrow("evacuation not done in time")
-	}
-	oldbuckets := h.buckets
-	if checkgc {
-		memstats.next_gc = memstats.heap_alloc
-	}
-	newbuckets := newarray(t.bucket, uintptr(1)<<(h.B+1))
-	flags := h.flags &^ (iterator | oldIterator)
-	if h.flags&iterator != 0 {
-		flags |= oldIterator
-	}
-	// commit the grow (atomic wrt gc)
-	h.B++
-	h.flags = flags
-	h.oldbuckets = oldbuckets
-	h.buckets = newbuckets
-	h.nevacuate = 0
-
-	// the actual copying of the hash table data is done incrementally
-	// by growWork() and evacuate().
-}
-
-func growWork(t *maptype, h *hmap, bucket uintptr) {
-	noldbuckets := uintptr(1) << (h.B - 1)
-
-	// make sure we evacuate the oldbucket corresponding
-	// to the bucket we're about to use
-	evacuate(t, h, bucket&(noldbuckets-1))
-
-	// evacuate one more oldbucket to make progress on growing
-	if h.oldbuckets != nil {
-		evacuate(t, h, h.nevacuate)
-	}
-}
-
-func evacuate(t *maptype, h *hmap, oldbucket uintptr) {
-	b := (*bmap)(add(h.oldbuckets, oldbucket*uintptr(t.bucketsize)))
-	newbit := uintptr(1) << (h.B - 1)
-	alg := goalg(t.key.alg)
-	if !evacuated(b) {
-		// TODO: reuse overflow buckets instead of using new ones, if there
-		// is no iterator using the old buckets.  (If !oldIterator.)
-
-		x := (*bmap)(add(h.buckets, oldbucket*uintptr(t.bucketsize)))
-		y := (*bmap)(add(h.buckets, (oldbucket+newbit)*uintptr(t.bucketsize)))
-		xi := 0
-		yi := 0
-		xk := add(unsafe.Pointer(x), dataOffset)
-		yk := add(unsafe.Pointer(y), dataOffset)
-		xv := add(xk, bucketCnt*uintptr(t.keysize))
-		yv := add(yk, bucketCnt*uintptr(t.keysize))
-		for ; b != nil; b = b.overflow(t) {
-			k := add(unsafe.Pointer(b), dataOffset)
-			v := add(k, bucketCnt*uintptr(t.keysize))
-			for i := 0; i < bucketCnt; i, k, v = i+1, add(k, uintptr(t.keysize)), add(v, uintptr(t.valuesize)) {
-				top := b.tophash[i]
-				if top == empty {
-					b.tophash[i] = evacuatedEmpty
-					continue
-				}
-				if top < minTopHash {
-					gothrow("bad map state")
-				}
-				k2 := k
-				if t.indirectkey {
-					k2 = *((*unsafe.Pointer)(k2))
-				}
-				// Compute hash to make our evacuation decision (whether we need
-				// to send this key/value to bucket x or bucket y).
-				hash := alg.hash(k2, uintptr(t.key.size), uintptr(h.hash0))
-				if h.flags&iterator != 0 {
-					if !alg.equal(k2, k2, uintptr(t.key.size)) {
-						// If key != key (NaNs), then the hash could be (and probably
-						// will be) entirely different from the old hash.  Moreover,
-						// it isn't reproducible.  Reproducibility is required in the
-						// presence of iterators, as our evacuation decision must
-						// match whatever decision the iterator made.
-						// Fortunately, we have the freedom to send these keys either
-						// way.  Also, tophash is meaningless for these kinds of keys.
-						// We let the low bit of tophash drive the evacuation decision.
-						// We recompute a new random tophash for the next level so
-						// these keys will get evenly distributed across all buckets
-						// after multiple grows.
-						if (top & 1) != 0 {
-							hash |= newbit
-						} else {
-							hash &^= newbit
-						}
-						top = uint8(hash >> (ptrSize*8 - 8))
-						if top < minTopHash {
-							top += minTopHash
-						}
-					}
-				}
-				if (hash & newbit) == 0 {
-					b.tophash[i] = evacuatedX
-					if xi == bucketCnt {
-						if checkgc {
-							memstats.next_gc = memstats.heap_alloc
-						}
-						newx := (*bmap)(newobject(t.bucket))
-						x.setoverflow(t, newx)
-						x = newx
-						xi = 0
-						xk = add(unsafe.Pointer(x), dataOffset)
-						xv = add(xk, bucketCnt*uintptr(t.keysize))
-					}
-					x.tophash[xi] = top
-					if t.indirectkey {
-						*(*unsafe.Pointer)(xk) = k2 // copy pointer
-					} else {
-						memmove(xk, k, uintptr(t.key.size)) // copy value
-					}
-					if t.indirectvalue {
-						*(*unsafe.Pointer)(xv) = *(*unsafe.Pointer)(v)
-					} else {
-						memmove(xv, v, uintptr(t.elem.size))
-					}
-					xi++
-					xk = add(xk, uintptr(t.keysize))
-					xv = add(xv, uintptr(t.valuesize))
-				} else {
-					b.tophash[i] = evacuatedY
-					if yi == bucketCnt {
-						if checkgc {
-							memstats.next_gc = memstats.heap_alloc
-						}
-						newy := (*bmap)(newobject(t.bucket))
-						y.setoverflow(t, newy)
-						y = newy
-						yi = 0
-						yk = add(unsafe.Pointer(y), dataOffset)
-						yv = add(yk, bucketCnt*uintptr(t.keysize))
-					}
-					y.tophash[yi] = top
-					if t.indirectkey {
-						*(*unsafe.Pointer)(yk) = k2
-					} else {
-						memmove(yk, k, uintptr(t.key.size))
-					}
-					if t.indirectvalue {
-						*(*unsafe.Pointer)(yv) = *(*unsafe.Pointer)(v)
-					} else {
-						memmove(yv, v, uintptr(t.elem.size))
-					}
-					yi++
-					yk = add(yk, uintptr(t.keysize))
-					yv = add(yv, uintptr(t.valuesize))
-				}
-			}
-		}
-		// Unlink the overflow buckets & clear key/value to help GC.
-		if h.flags&oldIterator == 0 {
-			b = (*bmap)(add(h.oldbuckets, oldbucket*uintptr(t.bucketsize)))
-			memclr(add(unsafe.Pointer(b), dataOffset), uintptr(t.bucketsize)-dataOffset)
-		}
-	}
-
-	// Advance evacuation mark
-	if oldbucket == h.nevacuate {
-		h.nevacuate = oldbucket + 1
-		if oldbucket+1 == newbit { // newbit == # of oldbuckets
-			// Growing is all done.  Free old main bucket array.
-			h.oldbuckets = nil
-		}
-	}
-}
-
-func ismapkey(t *_type) bool {
-	return goalg(t.alg).hash != nil
-}
-
-// Reflect stubs.  Called from ../reflect/asm_*.s
-
-func reflect_makemap(t *maptype) *hmap {
-	return makemap(t, 0)
-}
-
-func reflect_mapaccess(t *maptype, h *hmap, key unsafe.Pointer) unsafe.Pointer {
-	val, ok := mapaccess2(t, h, key)
-	if !ok {
-		// reflect wants nil for a missing element
-		val = nil
-	}
-	return val
-}
-
-func reflect_mapassign(t *maptype, h *hmap, key unsafe.Pointer, val unsafe.Pointer) {
-	mapassign1(t, h, key, val)
-}
-
-func reflect_mapdelete(t *maptype, h *hmap, key unsafe.Pointer) {
-	mapdelete(t, h, key)
-}
-
-func reflect_mapiterinit(t *maptype, h *hmap) *hiter {
-	it := new(hiter)
-	mapiterinit(t, h, it)
-	return it
-}
-
-func reflect_mapiternext(it *hiter) {
-	mapiternext(it)
-}
-
-func reflect_mapiterkey(it *hiter) unsafe.Pointer {
-	return it.key
-}
-
-func reflect_maplen(h *hmap) int {
-	if h == nil {
-		return 0
-	}
-	if raceenabled {
-		callerpc := getcallerpc(unsafe.Pointer(&h))
-		racereadpc(unsafe.Pointer(h), callerpc, funcPC(reflect_maplen))
-	}
-	return h.count
-}
-
-func reflect_ismapkey(t *_type) bool {
-	return ismapkey(t)
-}
diff --git a/third_party/gofrontend/libgo/go/runtime/hashmap_fast.go b/third_party/gofrontend/libgo/go/runtime/hashmap_fast.go
deleted file mode 100644
index afa6ecc..0000000
--- a/third_party/gofrontend/libgo/go/runtime/hashmap_fast.go
+++ /dev/null
@@ -1,379 +0,0 @@
-// 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.
-
-package runtime
-
-import (
-	"unsafe"
-)
-
-func mapaccess1_fast32(t *maptype, h *hmap, key uint32) unsafe.Pointer {
-	if raceenabled && h != nil {
-		callerpc := getcallerpc(unsafe.Pointer(&t))
-		racereadpc(unsafe.Pointer(h), callerpc, funcPC(mapaccess1_fast32))
-	}
-	if h == nil || h.count == 0 {
-		return unsafe.Pointer(t.elem.zero)
-	}
-	var b *bmap
-	if h.B == 0 {
-		// One-bucket table.  No need to hash.
-		b = (*bmap)(h.buckets)
-	} else {
-		hash := goalg(t.key.alg).hash(noescape(unsafe.Pointer(&key)), 4, uintptr(h.hash0))
-		m := uintptr(1)<<h.B - 1
-		b = (*bmap)(add(h.buckets, (hash&m)*uintptr(t.bucketsize)))
-		if c := h.oldbuckets; c != nil {
-			oldb := (*bmap)(add(c, (hash&(m>>1))*uintptr(t.bucketsize)))
-			if !evacuated(oldb) {
-				b = oldb
-			}
-		}
-	}
-	for {
-		for i := uintptr(0); i < bucketCnt; i++ {
-			k := *((*uint32)(add(unsafe.Pointer(b), dataOffset+i*4)))
-			if k != key {
-				continue
-			}
-			x := *((*uint8)(add(unsafe.Pointer(b), i))) // b.topbits[i] without the bounds check
-			if x == empty {
-				continue
-			}
-			return add(unsafe.Pointer(b), dataOffset+bucketCnt*4+i*uintptr(t.valuesize))
-		}
-		b = b.overflow(t)
-		if b == nil {
-			return unsafe.Pointer(t.elem.zero)
-		}
-	}
-}
-
-func mapaccess2_fast32(t *maptype, h *hmap, key uint32) (unsafe.Pointer, bool) {
-	if raceenabled && h != nil {
-		callerpc := getcallerpc(unsafe.Pointer(&t))
-		racereadpc(unsafe.Pointer(h), callerpc, funcPC(mapaccess2_fast32))
-	}
-	if h == nil || h.count == 0 {
-		return unsafe.Pointer(t.elem.zero), false
-	}
-	var b *bmap
-	if h.B == 0 {
-		// One-bucket table.  No need to hash.
-		b = (*bmap)(h.buckets)
-	} else {
-		hash := goalg(t.key.alg).hash(noescape(unsafe.Pointer(&key)), 4, uintptr(h.hash0))
-		m := uintptr(1)<<h.B - 1
-		b = (*bmap)(add(h.buckets, (hash&m)*uintptr(t.bucketsize)))
-		if c := h.oldbuckets; c != nil {
-			oldb := (*bmap)(add(c, (hash&(m>>1))*uintptr(t.bucketsize)))
-			if !evacuated(oldb) {
-				b = oldb
-			}
-		}
-	}
-	for {
-		for i := uintptr(0); i < bucketCnt; i++ {
-			k := *((*uint32)(add(unsafe.Pointer(b), dataOffset+i*4)))
-			if k != key {
-				continue
-			}
-			x := *((*uint8)(add(unsafe.Pointer(b), i))) // b.topbits[i] without the bounds check
-			if x == empty {
-				continue
-			}
-			return add(unsafe.Pointer(b), dataOffset+bucketCnt*4+i*uintptr(t.valuesize)), true
-		}
-		b = b.overflow(t)
-		if b == nil {
-			return unsafe.Pointer(t.elem.zero), false
-		}
-	}
-}
-
-func mapaccess1_fast64(t *maptype, h *hmap, key uint64) unsafe.Pointer {
-	if raceenabled && h != nil {
-		callerpc := getcallerpc(unsafe.Pointer(&t))
-		racereadpc(unsafe.Pointer(h), callerpc, funcPC(mapaccess1_fast64))
-	}
-	if h == nil || h.count == 0 {
-		return unsafe.Pointer(t.elem.zero)
-	}
-	var b *bmap
-	if h.B == 0 {
-		// One-bucket table.  No need to hash.
-		b = (*bmap)(h.buckets)
-	} else {
-		hash := goalg(t.key.alg).hash(noescape(unsafe.Pointer(&key)), 8, uintptr(h.hash0))
-		m := uintptr(1)<<h.B - 1
-		b = (*bmap)(add(h.buckets, (hash&m)*uintptr(t.bucketsize)))
-		if c := h.oldbuckets; c != nil {
-			oldb := (*bmap)(add(c, (hash&(m>>1))*uintptr(t.bucketsize)))
-			if !evacuated(oldb) {
-				b = oldb
-			}
-		}
-	}
-	for {
-		for i := uintptr(0); i < bucketCnt; i++ {
-			k := *((*uint64)(add(unsafe.Pointer(b), dataOffset+i*8)))
-			if k != key {
-				continue
-			}
-			x := *((*uint8)(add(unsafe.Pointer(b), i))) // b.topbits[i] without the bounds check
-			if x == empty {
-				continue
-			}
-			return add(unsafe.Pointer(b), dataOffset+bucketCnt*8+i*uintptr(t.valuesize))
-		}
-		b = b.overflow(t)
-		if b == nil {
-			return unsafe.Pointer(t.elem.zero)
-		}
-	}
-}
-
-func mapaccess2_fast64(t *maptype, h *hmap, key uint64) (unsafe.Pointer, bool) {
-	if raceenabled && h != nil {
-		callerpc := getcallerpc(unsafe.Pointer(&t))
-		racereadpc(unsafe.Pointer(h), callerpc, funcPC(mapaccess2_fast64))
-	}
-	if h == nil || h.count == 0 {
-		return unsafe.Pointer(t.elem.zero), false
-	}
-	var b *bmap
-	if h.B == 0 {
-		// One-bucket table.  No need to hash.
-		b = (*bmap)(h.buckets)
-	} else {
-		hash := goalg(t.key.alg).hash(noescape(unsafe.Pointer(&key)), 8, uintptr(h.hash0))
-		m := uintptr(1)<<h.B - 1
-		b = (*bmap)(add(h.buckets, (hash&m)*uintptr(t.bucketsize)))
-		if c := h.oldbuckets; c != nil {
-			oldb := (*bmap)(add(c, (hash&(m>>1))*uintptr(t.bucketsize)))
-			if !evacuated(oldb) {
-				b = oldb
-			}
-		}
-	}
-	for {
-		for i := uintptr(0); i < bucketCnt; i++ {
-			k := *((*uint64)(add(unsafe.Pointer(b), dataOffset+i*8)))
-			if k != key {
-				continue
-			}
-			x := *((*uint8)(add(unsafe.Pointer(b), i))) // b.topbits[i] without the bounds check
-			if x == empty {
-				continue
-			}
-			return add(unsafe.Pointer(b), dataOffset+bucketCnt*8+i*uintptr(t.valuesize)), true
-		}
-		b = b.overflow(t)
-		if b == nil {
-			return unsafe.Pointer(t.elem.zero), false
-		}
-	}
-}
-
-func mapaccess1_faststr(t *maptype, h *hmap, ky string) unsafe.Pointer {
-	if raceenabled && h != nil {
-		callerpc := getcallerpc(unsafe.Pointer(&t))
-		racereadpc(unsafe.Pointer(h), callerpc, funcPC(mapaccess1_faststr))
-	}
-	if h == nil || h.count == 0 {
-		return unsafe.Pointer(t.elem.zero)
-	}
-	key := (*stringStruct)(unsafe.Pointer(&ky))
-	if h.B == 0 {
-		// One-bucket table.
-		b := (*bmap)(h.buckets)
-		if key.len < 32 {
-			// short key, doing lots of comparisons is ok
-			for i := uintptr(0); i < bucketCnt; i++ {
-				x := *((*uint8)(add(unsafe.Pointer(b), i))) // b.topbits[i] without the bounds check
-				if x == empty {
-					continue
-				}
-				k := (*stringStruct)(add(unsafe.Pointer(b), dataOffset+i*2*ptrSize))
-				if k.len != key.len {
-					continue
-				}
-				if k.str == key.str || memeq(k.str, key.str, uintptr(key.len)) {
-					return add(unsafe.Pointer(b), dataOffset+bucketCnt*2*ptrSize+i*uintptr(t.valuesize))
-				}
-			}
-			return unsafe.Pointer(t.elem.zero)
-		}
-		// long key, try not to do more comparisons than necessary
-		keymaybe := uintptr(bucketCnt)
-		for i := uintptr(0); i < bucketCnt; i++ {
-			x := *((*uint8)(add(unsafe.Pointer(b), i))) // b.topbits[i] without the bounds check
-			if x == empty {
-				continue
-			}
-			k := (*stringStruct)(add(unsafe.Pointer(b), dataOffset+i*2*ptrSize))
-			if k.len != key.len {
-				continue
-			}
-			if k.str == key.str {
-				return add(unsafe.Pointer(b), dataOffset+bucketCnt*2*ptrSize+i*uintptr(t.valuesize))
-			}
-			// check first 4 bytes
-			// TODO: on amd64/386 at least, make this compile to one 4-byte comparison instead of
-			// four 1-byte comparisons.
-			if *((*[4]byte)(key.str)) != *((*[4]byte)(k.str)) {
-				continue
-			}
-			// check last 4 bytes
-			if *((*[4]byte)(add(key.str, uintptr(key.len)-4))) != *((*[4]byte)(add(k.str, uintptr(key.len)-4))) {
-				continue
-			}
-			if keymaybe != bucketCnt {
-				// Two keys are potential matches.  Use hash to distinguish them.
-				goto dohash
-			}
-			keymaybe = i
-		}
-		if keymaybe != bucketCnt {
-			k := (*stringStruct)(add(unsafe.Pointer(b), dataOffset+keymaybe*2*ptrSize))
-			if memeq(k.str, key.str, uintptr(key.len)) {
-				return add(unsafe.Pointer(b), dataOffset+bucketCnt*2*ptrSize+keymaybe*uintptr(t.valuesize))
-			}
-		}
-		return unsafe.Pointer(t.elem.zero)
-	}
-dohash:
-	hash := goalg(t.key.alg).hash(noescape(unsafe.Pointer(&ky)), 2*ptrSize, uintptr(h.hash0))
-	m := uintptr(1)<<h.B - 1
-	b := (*bmap)(add(h.buckets, (hash&m)*uintptr(t.bucketsize)))
-	if c := h.oldbuckets; c != nil {
-		oldb := (*bmap)(add(c, (hash&(m>>1))*uintptr(t.bucketsize)))
-		if !evacuated(oldb) {
-			b = oldb
-		}
-	}
-	top := uint8(hash >> (ptrSize*8 - 8))
-	if top < minTopHash {
-		top += minTopHash
-	}
-	for {
-		for i := uintptr(0); i < bucketCnt; i++ {
-			x := *((*uint8)(add(unsafe.Pointer(b), i))) // b.topbits[i] without the bounds check
-			if x != top {
-				continue
-			}
-			k := (*stringStruct)(add(unsafe.Pointer(b), dataOffset+i*2*ptrSize))
-			if k.len != key.len {
-				continue
-			}
-			if k.str == key.str || memeq(k.str, key.str, uintptr(key.len)) {
-				return add(unsafe.Pointer(b), dataOffset+bucketCnt*2*ptrSize+i*uintptr(t.valuesize))
-			}
-		}
-		b = b.overflow(t)
-		if b == nil {
-			return unsafe.Pointer(t.elem.zero)
-		}
-	}
-}
-
-func mapaccess2_faststr(t *maptype, h *hmap, ky string) (unsafe.Pointer, bool) {
-	if raceenabled && h != nil {
-		callerpc := getcallerpc(unsafe.Pointer(&t))
-		racereadpc(unsafe.Pointer(h), callerpc, funcPC(mapaccess2_faststr))
-	}
-	if h == nil || h.count == 0 {
-		return unsafe.Pointer(t.elem.zero), false
-	}
-	key := (*stringStruct)(unsafe.Pointer(&ky))
-	if h.B == 0 {
-		// One-bucket table.
-		b := (*bmap)(h.buckets)
-		if key.len < 32 {
-			// short key, doing lots of comparisons is ok
-			for i := uintptr(0); i < bucketCnt; i++ {
-				x := *((*uint8)(add(unsafe.Pointer(b), i))) // b.topbits[i] without the bounds check
-				if x == empty {
-					continue
-				}
-				k := (*stringStruct)(add(unsafe.Pointer(b), dataOffset+i*2*ptrSize))
-				if k.len != key.len {
-					continue
-				}
-				if k.str == key.str || memeq(k.str, key.str, uintptr(key.len)) {
-					return add(unsafe.Pointer(b), dataOffset+bucketCnt*2*ptrSize+i*uintptr(t.valuesize)), true
-				}
-			}
-			return unsafe.Pointer(t.elem.zero), false
-		}
-		// long key, try not to do more comparisons than necessary
-		keymaybe := uintptr(bucketCnt)
-		for i := uintptr(0); i < bucketCnt; i++ {
-			x := *((*uint8)(add(unsafe.Pointer(b), i))) // b.topbits[i] without the bounds check
-			if x == empty {
-				continue
-			}
-			k := (*stringStruct)(add(unsafe.Pointer(b), dataOffset+i*2*ptrSize))
-			if k.len != key.len {
-				continue
-			}
-			if k.str == key.str {
-				return add(unsafe.Pointer(b), dataOffset+bucketCnt*2*ptrSize+i*uintptr(t.valuesize)), true
-			}
-			// check first 4 bytes
-			if *((*[4]byte)(key.str)) != *((*[4]byte)(k.str)) {
-				continue
-			}
-			// check last 4 bytes
-			if *((*[4]byte)(add(key.str, uintptr(key.len)-4))) != *((*[4]byte)(add(k.str, uintptr(key.len)-4))) {
-				continue
-			}
-			if keymaybe != bucketCnt {
-				// Two keys are potential matches.  Use hash to distinguish them.
-				goto dohash
-			}
-			keymaybe = i
-		}
-		if keymaybe != bucketCnt {
-			k := (*stringStruct)(add(unsafe.Pointer(b), dataOffset+keymaybe*2*ptrSize))
-			if memeq(k.str, key.str, uintptr(key.len)) {
-				return add(unsafe.Pointer(b), dataOffset+bucketCnt*2*ptrSize+keymaybe*uintptr(t.valuesize)), true
-			}
-		}
-		return unsafe.Pointer(t.elem.zero), false
-	}
-dohash:
-	hash := goalg(t.key.alg).hash(noescape(unsafe.Pointer(&ky)), 2*ptrSize, uintptr(h.hash0))
-	m := uintptr(1)<<h.B - 1
-	b := (*bmap)(add(h.buckets, (hash&m)*uintptr(t.bucketsize)))
-	if c := h.oldbuckets; c != nil {
-		oldb := (*bmap)(add(c, (hash&(m>>1))*uintptr(t.bucketsize)))
-		if !evacuated(oldb) {
-			b = oldb
-		}
-	}
-	top := uint8(hash >> (ptrSize*8 - 8))
-	if top < minTopHash {
-		top += minTopHash
-	}
-	for {
-		for i := uintptr(0); i < bucketCnt; i++ {
-			x := *((*uint8)(add(unsafe.Pointer(b), i))) // b.topbits[i] without the bounds check
-			if x != top {
-				continue
-			}
-			k := (*stringStruct)(add(unsafe.Pointer(b), dataOffset+i*2*ptrSize))
-			if k.len != key.len {
-				continue
-			}
-			if k.str == key.str || memeq(k.str, key.str, uintptr(key.len)) {
-				return add(unsafe.Pointer(b), dataOffset+bucketCnt*2*ptrSize+i*uintptr(t.valuesize)), true
-			}
-		}
-		b = b.overflow(t)
-		if b == nil {
-			return unsafe.Pointer(t.elem.zero), false
-		}
-	}
-}
diff --git a/third_party/gofrontend/libgo/go/runtime/iface_test.go b/third_party/gofrontend/libgo/go/runtime/iface_test.go
index bca0ea0..7f27baa 100644
--- a/third_party/gofrontend/libgo/go/runtime/iface_test.go
+++ b/third_party/gofrontend/libgo/go/runtime/iface_test.go
@@ -5,6 +5,7 @@
 package runtime_test
 
 import (
+	"runtime"
 	"testing"
 )
 
@@ -36,8 +37,50 @@
 	ts TS
 	tm TM
 	tl TL
+	ok bool
 )
 
+// Issue 9370
+func TestCmpIfaceConcreteAlloc(t *testing.T) {
+	if runtime.Compiler != "gc" {
+		t.Skip("skipping on non-gc compiler")
+	}
+
+	n := testing.AllocsPerRun(1, func() {
+		_ = e == ts
+		_ = i1 == ts
+		_ = e == 1
+	})
+
+	if n > 0 {
+		t.Fatalf("iface cmp allocs=%v; want 0", n)
+	}
+}
+
+func BenchmarkEqEfaceConcrete(b *testing.B) {
+	for i := 0; i < b.N; i++ {
+		_ = e == ts
+	}
+}
+
+func BenchmarkEqIfaceConcrete(b *testing.B) {
+	for i := 0; i < b.N; i++ {
+		_ = i1 == ts
+	}
+}
+
+func BenchmarkNeEfaceConcrete(b *testing.B) {
+	for i := 0; i < b.N; i++ {
+		_ = e != ts
+	}
+}
+
+func BenchmarkNeIfaceConcrete(b *testing.B) {
+	for i := 0; i < b.N; i++ {
+		_ = i1 != ts
+	}
+}
+
 func BenchmarkConvT2ESmall(b *testing.B) {
 	for i := 0; i < b.N; i++ {
 		e = ts
@@ -136,3 +179,85 @@
 		e_ = e
 	}
 }
+
+func BenchmarkAssertE2T2(b *testing.B) {
+	e = tm
+	for i := 0; i < b.N; i++ {
+		tm, ok = e.(TM)
+	}
+}
+
+func BenchmarkAssertE2T2Blank(b *testing.B) {
+	e = tm
+	for i := 0; i < b.N; i++ {
+		_, ok = e.(TM)
+	}
+}
+
+func BenchmarkAssertI2E2(b *testing.B) {
+	i1 = tm
+	for i := 0; i < b.N; i++ {
+		e, ok = i1.(interface{})
+	}
+}
+
+func BenchmarkAssertI2E2Blank(b *testing.B) {
+	i1 = tm
+	for i := 0; i < b.N; i++ {
+		_, ok = i1.(interface{})
+	}
+}
+
+func BenchmarkAssertE2E2(b *testing.B) {
+	e = tm
+	for i := 0; i < b.N; i++ {
+		e_, ok = e.(interface{})
+	}
+}
+
+func BenchmarkAssertE2E2Blank(b *testing.B) {
+	e = tm
+	for i := 0; i < b.N; i++ {
+		_, ok = e.(interface{})
+	}
+}
+
+func TestNonEscapingConvT2E(t *testing.T) {
+	m := make(map[interface{}]bool)
+	m[42] = true
+	if !m[42] {
+		t.Fatalf("42 is not present in the map")
+	}
+	if m[0] {
+		t.Fatalf("0 is present in the map")
+	}
+
+	n := testing.AllocsPerRun(1000, func() {
+		if m[0] {
+			t.Fatalf("0 is present in the map")
+		}
+	})
+	if n != 0 {
+		t.Fatalf("want 0 allocs, got %v", n)
+	}
+}
+
+func TestNonEscapingConvT2I(t *testing.T) {
+	m := make(map[I1]bool)
+	m[TM(42)] = true
+	if !m[TM(42)] {
+		t.Fatalf("42 is not present in the map")
+	}
+	if m[TM(0)] {
+		t.Fatalf("0 is present in the map")
+	}
+
+	n := testing.AllocsPerRun(1000, func() {
+		if m[TM(0)] {
+			t.Fatalf("0 is present in the map")
+		}
+	})
+	if n != 0 {
+		t.Fatalf("want 0 allocs, got %v", n)
+	}
+}
diff --git a/third_party/gofrontend/libgo/go/runtime/lfstack_test.go b/third_party/gofrontend/libgo/go/runtime/lfstack_test.go
index e518777..fb4b459 100644
--- a/third_party/gofrontend/libgo/go/runtime/lfstack_test.go
+++ b/third_party/gofrontend/libgo/go/runtime/lfstack_test.go
@@ -24,9 +24,13 @@
 	return (*MyNode)(unsafe.Pointer(node))
 }
 
+var global interface{}
+
 func TestLFStack(t *testing.T) {
 	stack := new(uint64)
-	// Need to keep additional referenfces to nodes, the stack is not all that type-safe.
+	global = stack // force heap allocation
+
+	// Need to keep additional references to nodes, the stack is not all that type-safe.
 	var nodes []*MyNode
 
 	// Check the stack is initially empty.
@@ -121,7 +125,7 @@
 			}
 			cnt++
 			sum2 += node.data
-			node.Next = nil
+			node.Next = 0
 		}
 	}
 	if cnt != K {
diff --git a/third_party/gofrontend/libgo/go/runtime/lock_futex.go b/third_party/gofrontend/libgo/go/runtime/lock_futex.go
deleted file mode 100644
index 7259623..0000000
--- a/third_party/gofrontend/libgo/go/runtime/lock_futex.go
+++ /dev/null
@@ -1,205 +0,0 @@
-// Copyright 2011 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 dragonfly freebsd linux
-
-package runtime
-
-import "unsafe"
-
-// This implementation depends on OS-specific implementations of
-//
-//	runtime·futexsleep(uint32 *addr, uint32 val, int64 ns)
-//		Atomically,
-//			if(*addr == val) sleep
-//		Might be woken up spuriously; that's allowed.
-//		Don't sleep longer than ns; ns < 0 means forever.
-//
-//	runtime·futexwakeup(uint32 *addr, uint32 cnt)
-//		If any procs are sleeping on addr, wake up at most cnt.
-
-const (
-	mutex_unlocked = 0
-	mutex_locked   = 1
-	mutex_sleeping = 2
-
-	active_spin     = 4
-	active_spin_cnt = 30
-	passive_spin    = 1
-)
-
-// Possible lock states are mutex_unlocked, mutex_locked and mutex_sleeping.
-// mutex_sleeping means that there is presumably at least one sleeping thread.
-// Note that there can be spinning threads during all states - they do not
-// affect mutex's state.
-
-func futexsleep(addr *uint32, val uint32, ns int64)
-func futexwakeup(addr *uint32, cnt uint32)
-
-// We use the uintptr mutex.key and note.key as a uint32.
-func key32(p *uintptr) *uint32 {
-	return (*uint32)(unsafe.Pointer(p))
-}
-
-func lock(l *mutex) {
-	gp := getg()
-
-	if gp.m.locks < 0 {
-		gothrow("runtime·lock: lock count")
-	}
-	gp.m.locks++
-
-	// Speculative grab for lock.
-	v := xchg(key32(&l.key), mutex_locked)
-	if v == mutex_unlocked {
-		return
-	}
-
-	// wait is either MUTEX_LOCKED or MUTEX_SLEEPING
-	// depending on whether there is a thread sleeping
-	// on this mutex.  If we ever change l->key from
-	// MUTEX_SLEEPING to some other value, we must be
-	// careful to change it back to MUTEX_SLEEPING before
-	// returning, to ensure that the sleeping thread gets
-	// its wakeup call.
-	wait := v
-
-	// On uniprocessors, no point spinning.
-	// On multiprocessors, spin for ACTIVE_SPIN attempts.
-	spin := 0
-	if ncpu > 1 {
-		spin = active_spin
-	}
-	for {
-		// Try for lock, spinning.
-		for i := 0; i < spin; i++ {
-			for l.key == mutex_unlocked {
-				if cas(key32(&l.key), mutex_unlocked, wait) {
-					return
-				}
-			}
-			procyield(active_spin_cnt)
-		}
-
-		// Try for lock, rescheduling.
-		for i := 0; i < passive_spin; i++ {
-			for l.key == mutex_unlocked {
-				if cas(key32(&l.key), mutex_unlocked, wait) {
-					return
-				}
-			}
-			osyield()
-		}
-
-		// Sleep.
-		v = xchg(key32(&l.key), mutex_sleeping)
-		if v == mutex_unlocked {
-			return
-		}
-		wait = mutex_sleeping
-		futexsleep(key32(&l.key), mutex_sleeping, -1)
-	}
-}
-
-func unlock(l *mutex) {
-	v := xchg(key32(&l.key), mutex_unlocked)
-	if v == mutex_unlocked {
-		gothrow("unlock of unlocked lock")
-	}
-	if v == mutex_sleeping {
-		futexwakeup(key32(&l.key), 1)
-	}
-
-	gp := getg()
-	gp.m.locks--
-	if gp.m.locks < 0 {
-		gothrow("runtime·unlock: lock count")
-	}
-	if gp.m.locks == 0 && gp.preempt { // restore the preemption request in case we've cleared it in newstack
-		gp.stackguard0 = stackPreempt
-	}
-}
-
-// One-time notifications.
-func noteclear(n *note) {
-	n.key = 0
-}
-
-func notewakeup(n *note) {
-	old := xchg(key32(&n.key), 1)
-	if old != 0 {
-		print("notewakeup - double wakeup (", old, ")\n")
-		gothrow("notewakeup - double wakeup")
-	}
-	futexwakeup(key32(&n.key), 1)
-}
-
-func notesleep(n *note) {
-	gp := getg()
-	if gp != gp.m.g0 {
-		gothrow("notesleep not on g0")
-	}
-	for atomicload(key32(&n.key)) == 0 {
-		gp.m.blocked = true
-		futexsleep(key32(&n.key), 0, -1)
-		gp.m.blocked = false
-	}
-}
-
-//go:nosplit
-func notetsleep_internal(n *note, ns int64) bool {
-	gp := getg()
-
-	if ns < 0 {
-		for atomicload(key32(&n.key)) == 0 {
-			gp.m.blocked = true
-			futexsleep(key32(&n.key), 0, -1)
-			gp.m.blocked = false
-		}
-		return true
-	}
-
-	if atomicload(key32(&n.key)) != 0 {
-		return true
-	}
-
-	deadline := nanotime() + ns
-	for {
-		gp.m.blocked = true
-		futexsleep(key32(&n.key), 0, ns)
-		gp.m.blocked = false
-		if atomicload(key32(&n.key)) != 0 {
-			break
-		}
-		now := nanotime()
-		if now >= deadline {
-			break
-		}
-		ns = deadline - now
-	}
-	return atomicload(key32(&n.key)) != 0
-}
-
-func notetsleep(n *note, ns int64) bool {
-	gp := getg()
-	if gp != gp.m.g0 && gp.m.gcing == 0 {
-		gothrow("notetsleep not on g0")
-	}
-
-	return notetsleep_internal(n, ns)
-}
-
-// same as runtime·notetsleep, but called on user g (not g0)
-// calls only nosplit functions between entersyscallblock/exitsyscall
-func notetsleepg(n *note, ns int64) bool {
-	gp := getg()
-	if gp == gp.m.g0 {
-		gothrow("notetsleepg on g0")
-	}
-
-	entersyscallblock()
-	ok := notetsleep_internal(n, ns)
-	exitsyscall()
-	return ok
-}
diff --git a/third_party/gofrontend/libgo/go/runtime/lock_sema.go b/third_party/gofrontend/libgo/go/runtime/lock_sema.go
deleted file mode 100644
index d136b82..0000000
--- a/third_party/gofrontend/libgo/go/runtime/lock_sema.go
+++ /dev/null
@@ -1,270 +0,0 @@
-// Copyright 2011 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 darwin nacl netbsd openbsd plan9 solaris windows
-
-package runtime
-
-import "unsafe"
-
-// This implementation depends on OS-specific implementations of
-//
-//	uintptr runtime·semacreate(void)
-//		Create a semaphore, which will be assigned to m->waitsema.
-//		The zero value is treated as absence of any semaphore,
-//		so be sure to return a non-zero value.
-//
-//	int32 runtime·semasleep(int64 ns)
-//		If ns < 0, acquire m->waitsema and return 0.
-//		If ns >= 0, try to acquire m->waitsema for at most ns nanoseconds.
-//		Return 0 if the semaphore was acquired, -1 if interrupted or timed out.
-//
-//	int32 runtime·semawakeup(M *mp)
-//		Wake up mp, which is or will soon be sleeping on mp->waitsema.
-//
-const (
-	locked uintptr = 1
-
-	active_spin     = 4
-	active_spin_cnt = 30
-	passive_spin    = 1
-)
-
-func semacreate() uintptr
-func semasleep(int64) int32
-func semawakeup(mp *m)
-
-func lock(l *mutex) {
-	gp := getg()
-	if gp.m.locks < 0 {
-		gothrow("runtime·lock: lock count")
-	}
-	gp.m.locks++
-
-	// Speculative grab for lock.
-	if casuintptr(&l.key, 0, locked) {
-		return
-	}
-	if gp.m.waitsema == 0 {
-		gp.m.waitsema = semacreate()
-	}
-
-	// On uniprocessor's, no point spinning.
-	// On multiprocessors, spin for ACTIVE_SPIN attempts.
-	spin := 0
-	if ncpu > 1 {
-		spin = active_spin
-	}
-Loop:
-	for i := 0; ; i++ {
-		v := atomicloaduintptr(&l.key)
-		if v&locked == 0 {
-			// Unlocked. Try to lock.
-			if casuintptr(&l.key, v, v|locked) {
-				return
-			}
-			i = 0
-		}
-		if i < spin {
-			procyield(active_spin_cnt)
-		} else if i < spin+passive_spin {
-			osyield()
-		} else {
-			// Someone else has it.
-			// l->waitm points to a linked list of M's waiting
-			// for this lock, chained through m->nextwaitm.
-			// Queue this M.
-			for {
-				gp.m.nextwaitm = (*m)((unsafe.Pointer)(v &^ locked))
-				if casuintptr(&l.key, v, uintptr(unsafe.Pointer(gp.m))|locked) {
-					break
-				}
-				v = atomicloaduintptr(&l.key)
-				if v&locked == 0 {
-					continue Loop
-				}
-			}
-			if v&locked != 0 {
-				// Queued.  Wait.
-				semasleep(-1)
-				i = 0
-			}
-		}
-	}
-}
-
-func unlock(l *mutex) {
-	gp := getg()
-	var mp *m
-	for {
-		v := atomicloaduintptr(&l.key)
-		if v == locked {
-			if casuintptr(&l.key, locked, 0) {
-				break
-			}
-		} else {
-			// Other M's are waiting for the lock.
-			// Dequeue an M.
-			mp = (*m)((unsafe.Pointer)(v &^ locked))
-			if casuintptr(&l.key, v, uintptr(unsafe.Pointer(mp.nextwaitm))) {
-				// Dequeued an M.  Wake it.
-				semawakeup(mp)
-				break
-			}
-		}
-	}
-	gp.m.locks--
-	if gp.m.locks < 0 {
-		gothrow("runtime·unlock: lock count")
-	}
-	if gp.m.locks == 0 && gp.preempt { // restore the preemption request in case we've cleared it in newstack
-		gp.stackguard0 = stackPreempt
-	}
-}
-
-// One-time notifications.
-func noteclear(n *note) {
-	n.key = 0
-}
-
-func notewakeup(n *note) {
-	var v uintptr
-	for {
-		v = atomicloaduintptr(&n.key)
-		if casuintptr(&n.key, v, locked) {
-			break
-		}
-	}
-
-	// Successfully set waitm to locked.
-	// What was it before?
-	switch {
-	case v == 0:
-		// Nothing was waiting. Done.
-	case v == locked:
-		// Two notewakeups!  Not allowed.
-		gothrow("notewakeup - double wakeup")
-	default:
-		// Must be the waiting m.  Wake it up.
-		semawakeup((*m)(unsafe.Pointer(v)))
-	}
-}
-
-func notesleep(n *note) {
-	gp := getg()
-	if gp != gp.m.g0 {
-		gothrow("notesleep not on g0")
-	}
-	if gp.m.waitsema == 0 {
-		gp.m.waitsema = semacreate()
-	}
-	if !casuintptr(&n.key, 0, uintptr(unsafe.Pointer(gp.m))) {
-		// Must be locked (got wakeup).
-		if n.key != locked {
-			gothrow("notesleep - waitm out of sync")
-		}
-		return
-	}
-	// Queued.  Sleep.
-	gp.m.blocked = true
-	semasleep(-1)
-	gp.m.blocked = false
-}
-
-//go:nosplit
-func notetsleep_internal(n *note, ns int64, gp *g, deadline int64) bool {
-	// gp and deadline are logically local variables, but they are written
-	// as parameters so that the stack space they require is charged
-	// to the caller.
-	// This reduces the nosplit footprint of notetsleep_internal.
-	gp = getg()
-
-	// Register for wakeup on n->waitm.
-	if !casuintptr(&n.key, 0, uintptr(unsafe.Pointer(gp.m))) {
-		// Must be locked (got wakeup).
-		if n.key != locked {
-			gothrow("notetsleep - waitm out of sync")
-		}
-		return true
-	}
-	if ns < 0 {
-		// Queued.  Sleep.
-		gp.m.blocked = true
-		semasleep(-1)
-		gp.m.blocked = false
-		return true
-	}
-
-	deadline = nanotime() + ns
-	for {
-		// Registered.  Sleep.
-		gp.m.blocked = true
-		if semasleep(ns) >= 0 {
-			gp.m.blocked = false
-			// Acquired semaphore, semawakeup unregistered us.
-			// Done.
-			return true
-		}
-		gp.m.blocked = false
-		// Interrupted or timed out.  Still registered.  Semaphore not acquired.
-		ns = deadline - nanotime()
-		if ns <= 0 {
-			break
-		}
-		// Deadline hasn't arrived.  Keep sleeping.
-	}
-
-	// Deadline arrived.  Still registered.  Semaphore not acquired.
-	// Want to give up and return, but have to unregister first,
-	// so that any notewakeup racing with the return does not
-	// try to grant us the semaphore when we don't expect it.
-	for {
-		v := atomicloaduintptr(&n.key)
-		switch v {
-		case uintptr(unsafe.Pointer(gp.m)):
-			// No wakeup yet; unregister if possible.
-			if casuintptr(&n.key, v, 0) {
-				return false
-			}
-		case locked:
-			// Wakeup happened so semaphore is available.
-			// Grab it to avoid getting out of sync.
-			gp.m.blocked = true
-			if semasleep(-1) < 0 {
-				gothrow("runtime: unable to acquire - semaphore out of sync")
-			}
-			gp.m.blocked = false
-			return true
-		default:
-			gothrow("runtime: unexpected waitm - semaphore out of sync")
-		}
-	}
-}
-
-func notetsleep(n *note, ns int64) bool {
-	gp := getg()
-	if gp != gp.m.g0 && gp.m.gcing == 0 {
-		gothrow("notetsleep not on g0")
-	}
-	if gp.m.waitsema == 0 {
-		gp.m.waitsema = semacreate()
-	}
-	return notetsleep_internal(n, ns, nil, 0)
-}
-
-// same as runtime·notetsleep, but called on user g (not g0)
-// calls only nosplit functions between entersyscallblock/exitsyscall
-func notetsleepg(n *note, ns int64) bool {
-	gp := getg()
-	if gp == gp.m.g0 {
-		gothrow("notetsleepg on g0")
-	}
-	if gp.m.waitsema == 0 {
-		gp.m.waitsema = semacreate()
-	}
-	entersyscallblock()
-	ok := notetsleep_internal(n, ns, nil, 0)
-	exitsyscall()
-	return ok
-}
diff --git a/third_party/gofrontend/libgo/go/runtime/malloc.go b/third_party/gofrontend/libgo/go/runtime/malloc.go
deleted file mode 100644
index 1170449..0000000
--- a/third_party/gofrontend/libgo/go/runtime/malloc.go
+++ /dev/null
@@ -1,837 +0,0 @@
-// 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.
-
-package runtime
-
-import (
-	"unsafe"
-)
-
-const (
-	debugMalloc = false
-
-	flagNoScan = _FlagNoScan
-	flagNoZero = _FlagNoZero
-
-	maxTinySize   = _TinySize
-	tinySizeClass = _TinySizeClass
-	maxSmallSize  = _MaxSmallSize
-
-	pageShift = _PageShift
-	pageSize  = _PageSize
-	pageMask  = _PageMask
-
-	bitsPerPointer  = _BitsPerPointer
-	bitsMask        = _BitsMask
-	pointersPerByte = _PointersPerByte
-	maxGCMask       = _MaxGCMask
-	bitsDead        = _BitsDead
-	bitsPointer     = _BitsPointer
-
-	mSpanInUse = _MSpanInUse
-
-	concurrentSweep = _ConcurrentSweep != 0
-)
-
-// Page number (address>>pageShift)
-type pageID uintptr
-
-// base address for all 0-byte allocations
-var zerobase uintptr
-
-// Allocate an object of size bytes.
-// Small objects are allocated from the per-P cache's free lists.
-// Large objects (> 32 kB) are allocated straight from the heap.
-func mallocgc(size uintptr, typ *_type, flags uint32) unsafe.Pointer {
-	if size == 0 {
-		return unsafe.Pointer(&zerobase)
-	}
-	size0 := size
-
-	if flags&flagNoScan == 0 && typ == nil {
-		gothrow("malloc missing type")
-	}
-
-	// This function must be atomic wrt GC, but for performance reasons
-	// we don't acquirem/releasem on fast path. The code below does not have
-	// split stack checks, so it can't be preempted by GC.
-	// Functions like roundup/add are inlined. And onM/racemalloc are nosplit.
-	// If debugMalloc = true, these assumptions are checked below.
-	if debugMalloc {
-		mp := acquirem()
-		if mp.mallocing != 0 {
-			gothrow("malloc deadlock")
-		}
-		mp.mallocing = 1
-		if mp.curg != nil {
-			mp.curg.stackguard0 = ^uintptr(0xfff) | 0xbad
-		}
-	}
-
-	c := gomcache()
-	var s *mspan
-	var x unsafe.Pointer
-	if size <= maxSmallSize {
-		if flags&flagNoScan != 0 && size < maxTinySize {
-			// Tiny allocator.
-			//
-			// Tiny allocator combines several tiny allocation requests
-			// into a single memory block. The resulting memory block
-			// is freed when all subobjects are unreachable. The subobjects
-			// must be FlagNoScan (don't have pointers), this ensures that
-			// the amount of potentially wasted memory is bounded.
-			//
-			// Size of the memory block used for combining (maxTinySize) is tunable.
-			// Current setting is 16 bytes, which relates to 2x worst case memory
-			// wastage (when all but one subobjects are unreachable).
-			// 8 bytes would result in no wastage at all, but provides less
-			// opportunities for combining.
-			// 32 bytes provides more opportunities for combining,
-			// but can lead to 4x worst case wastage.
-			// The best case winning is 8x regardless of block size.
-			//
-			// Objects obtained from tiny allocator must not be freed explicitly.
-			// So when an object will be freed explicitly, we ensure that
-			// its size >= maxTinySize.
-			//
-			// SetFinalizer has a special case for objects potentially coming
-			// from tiny allocator, it such case it allows to set finalizers
-			// for an inner byte of a memory block.
-			//
-			// The main targets of tiny allocator are small strings and
-			// standalone escaping variables. On a json benchmark
-			// the allocator reduces number of allocations by ~12% and
-			// reduces heap size by ~20%.
-			tinysize := uintptr(c.tinysize)
-			if size <= tinysize {
-				tiny := unsafe.Pointer(c.tiny)
-				// Align tiny pointer for required (conservative) alignment.
-				if size&7 == 0 {
-					tiny = roundup(tiny, 8)
-				} else if size&3 == 0 {
-					tiny = roundup(tiny, 4)
-				} else if size&1 == 0 {
-					tiny = roundup(tiny, 2)
-				}
-				size1 := size + (uintptr(tiny) - uintptr(unsafe.Pointer(c.tiny)))
-				if size1 <= tinysize {
-					// The object fits into existing tiny block.
-					x = tiny
-					c.tiny = (*byte)(add(x, size))
-					c.tinysize -= uintptr(size1)
-					c.local_tinyallocs++
-					if debugMalloc {
-						mp := acquirem()
-						if mp.mallocing == 0 {
-							gothrow("bad malloc")
-						}
-						mp.mallocing = 0
-						if mp.curg != nil {
-							mp.curg.stackguard0 = mp.curg.stack.lo + _StackGuard
-						}
-						// Note: one releasem for the acquirem just above.
-						// The other for the acquirem at start of malloc.
-						releasem(mp)
-						releasem(mp)
-					}
-					return x
-				}
-			}
-			// Allocate a new maxTinySize block.
-			s = c.alloc[tinySizeClass]
-			v := s.freelist
-			if v == nil {
-				mp := acquirem()
-				mp.scalararg[0] = tinySizeClass
-				onM(mcacheRefill_m)
-				releasem(mp)
-				s = c.alloc[tinySizeClass]
-				v = s.freelist
-			}
-			s.freelist = v.next
-			s.ref++
-			//TODO: prefetch v.next
-			x = unsafe.Pointer(v)
-			(*[2]uint64)(x)[0] = 0
-			(*[2]uint64)(x)[1] = 0
-			// See if we need to replace the existing tiny block with the new one
-			// based on amount of remaining free space.
-			if maxTinySize-size > tinysize {
-				c.tiny = (*byte)(add(x, size))
-				c.tinysize = uintptr(maxTinySize - size)
-			}
-			size = maxTinySize
-		} else {
-			var sizeclass int8
-			if size <= 1024-8 {
-				sizeclass = size_to_class8[(size+7)>>3]
-			} else {
-				sizeclass = size_to_class128[(size-1024+127)>>7]
-			}
-			size = uintptr(class_to_size[sizeclass])
-			s = c.alloc[sizeclass]
-			v := s.freelist
-			if v == nil {
-				mp := acquirem()
-				mp.scalararg[0] = uintptr(sizeclass)
-				onM(mcacheRefill_m)
-				releasem(mp)
-				s = c.alloc[sizeclass]
-				v = s.freelist
-			}
-			s.freelist = v.next
-			s.ref++
-			//TODO: prefetch
-			x = unsafe.Pointer(v)
-			if flags&flagNoZero == 0 {
-				v.next = nil
-				if size > 2*ptrSize && ((*[2]uintptr)(x))[1] != 0 {
-					memclr(unsafe.Pointer(v), size)
-				}
-			}
-		}
-		c.local_cachealloc += intptr(size)
-	} else {
-		mp := acquirem()
-		mp.scalararg[0] = uintptr(size)
-		mp.scalararg[1] = uintptr(flags)
-		onM(largeAlloc_m)
-		s = (*mspan)(mp.ptrarg[0])
-		mp.ptrarg[0] = nil
-		releasem(mp)
-		x = unsafe.Pointer(uintptr(s.start << pageShift))
-		size = uintptr(s.elemsize)
-	}
-
-	if flags&flagNoScan != 0 {
-		// All objects are pre-marked as noscan.
-		goto marked
-	}
-
-	// If allocating a defer+arg block, now that we've picked a malloc size
-	// large enough to hold everything, cut the "asked for" size down to
-	// just the defer header, so that the GC bitmap will record the arg block
-	// as containing nothing at all (as if it were unused space at the end of
-	// a malloc block caused by size rounding).
-	// The defer arg areas are scanned as part of scanstack.
-	if typ == deferType {
-		size0 = unsafe.Sizeof(_defer{})
-	}
-
-	// From here till marked label marking the object as allocated
-	// and storing type info in the GC bitmap.
-	{
-		arena_start := uintptr(unsafe.Pointer(mheap_.arena_start))
-		off := (uintptr(x) - arena_start) / ptrSize
-		xbits := (*uint8)(unsafe.Pointer(arena_start - off/wordsPerBitmapByte - 1))
-		shift := (off % wordsPerBitmapByte) * gcBits
-		if debugMalloc && ((*xbits>>shift)&(bitMask|bitPtrMask)) != bitBoundary {
-			println("runtime: bits =", (*xbits>>shift)&(bitMask|bitPtrMask))
-			gothrow("bad bits in markallocated")
-		}
-
-		var ti, te uintptr
-		var ptrmask *uint8
-		if size == ptrSize {
-			// It's one word and it has pointers, it must be a pointer.
-			*xbits |= (bitsPointer << 2) << shift
-			goto marked
-		}
-		if typ.kind&kindGCProg != 0 {
-			nptr := (uintptr(typ.size) + ptrSize - 1) / ptrSize
-			masksize := nptr
-			if masksize%2 != 0 {
-				masksize *= 2 // repeated
-			}
-			masksize = masksize * pointersPerByte / 8 // 4 bits per word
-			masksize++                                // unroll flag in the beginning
-			if masksize > maxGCMask && typ.gc[1] != 0 {
-				// If the mask is too large, unroll the program directly
-				// into the GC bitmap. It's 7 times slower than copying
-				// from the pre-unrolled mask, but saves 1/16 of type size
-				// memory for the mask.
-				mp := acquirem()
-				mp.ptrarg[0] = x
-				mp.ptrarg[1] = unsafe.Pointer(typ)
-				mp.scalararg[0] = uintptr(size)
-				mp.scalararg[1] = uintptr(size0)
-				onM(unrollgcproginplace_m)
-				releasem(mp)
-				goto marked
-			}
-			ptrmask = (*uint8)(unsafe.Pointer(uintptr(typ.gc[0])))
-			// Check whether the program is already unrolled.
-			if uintptr(atomicloadp(unsafe.Pointer(ptrmask)))&0xff == 0 {
-				mp := acquirem()
-				mp.ptrarg[0] = unsafe.Pointer(typ)
-				onM(unrollgcprog_m)
-				releasem(mp)
-			}
-			ptrmask = (*uint8)(add(unsafe.Pointer(ptrmask), 1)) // skip the unroll flag byte
-		} else {
-			ptrmask = (*uint8)(unsafe.Pointer(typ.gc[0])) // pointer to unrolled mask
-		}
-		if size == 2*ptrSize {
-			*xbits = *ptrmask | bitBoundary
-			goto marked
-		}
-		te = uintptr(typ.size) / ptrSize
-		// If the type occupies odd number of words, its mask is repeated.
-		if te%2 == 0 {
-			te /= 2
-		}
-		// Copy pointer bitmask into the bitmap.
-		for i := uintptr(0); i < size0; i += 2 * ptrSize {
-			v := *(*uint8)(add(unsafe.Pointer(ptrmask), ti))
-			ti++
-			if ti == te {
-				ti = 0
-			}
-			if i == 0 {
-				v |= bitBoundary
-			}
-			if i+ptrSize == size0 {
-				v &^= uint8(bitPtrMask << 4)
-			}
-
-			*xbits = v
-			xbits = (*byte)(add(unsafe.Pointer(xbits), ^uintptr(0)))
-		}
-		if size0%(2*ptrSize) == 0 && size0 < size {
-			// Mark the word after last object's word as bitsDead.
-			*xbits = bitsDead << 2
-		}
-	}
-marked:
-	if raceenabled {
-		racemalloc(x, size)
-	}
-
-	if debugMalloc {
-		mp := acquirem()
-		if mp.mallocing == 0 {
-			gothrow("bad malloc")
-		}
-		mp.mallocing = 0
-		if mp.curg != nil {
-			mp.curg.stackguard0 = mp.curg.stack.lo + _StackGuard
-		}
-		// Note: one releasem for the acquirem just above.
-		// The other for the acquirem at start of malloc.
-		releasem(mp)
-		releasem(mp)
-	}
-
-	if debug.allocfreetrace != 0 {
-		tracealloc(x, size, typ)
-	}
-
-	if rate := MemProfileRate; rate > 0 {
-		if size < uintptr(rate) && int32(size) < c.next_sample {
-			c.next_sample -= int32(size)
-		} else {
-			mp := acquirem()
-			profilealloc(mp, x, size)
-			releasem(mp)
-		}
-	}
-
-	if memstats.heap_alloc >= memstats.next_gc {
-		gogc(0)
-	}
-
-	return x
-}
-
-// implementation of new builtin
-func newobject(typ *_type) unsafe.Pointer {
-	flags := uint32(0)
-	if typ.kind&kindNoPointers != 0 {
-		flags |= flagNoScan
-	}
-	return mallocgc(uintptr(typ.size), typ, flags)
-}
-
-// implementation of make builtin for slices
-func newarray(typ *_type, n uintptr) unsafe.Pointer {
-	flags := uint32(0)
-	if typ.kind&kindNoPointers != 0 {
-		flags |= flagNoScan
-	}
-	if int(n) < 0 || (typ.size > 0 && n > maxmem/uintptr(typ.size)) {
-		panic("runtime: allocation size out of range")
-	}
-	return mallocgc(uintptr(typ.size)*n, typ, flags)
-}
-
-// rawmem returns a chunk of pointerless memory.  It is
-// not zeroed.
-func rawmem(size uintptr) unsafe.Pointer {
-	return mallocgc(size, nil, flagNoScan|flagNoZero)
-}
-
-// round size up to next size class
-func goroundupsize(size uintptr) uintptr {
-	if size < maxSmallSize {
-		if size <= 1024-8 {
-			return uintptr(class_to_size[size_to_class8[(size+7)>>3]])
-		}
-		return uintptr(class_to_size[size_to_class128[(size-1024+127)>>7]])
-	}
-	if size+pageSize < size {
-		return size
-	}
-	return (size + pageSize - 1) &^ pageMask
-}
-
-func profilealloc(mp *m, x unsafe.Pointer, size uintptr) {
-	c := mp.mcache
-	rate := MemProfileRate
-	if size < uintptr(rate) {
-		// pick next profile time
-		// If you change this, also change allocmcache.
-		if rate > 0x3fffffff { // make 2*rate not overflow
-			rate = 0x3fffffff
-		}
-		next := int32(fastrand1()) % (2 * int32(rate))
-		// Subtract the "remainder" of the current allocation.
-		// Otherwise objects that are close in size to sampling rate
-		// will be under-sampled, because we consistently discard this remainder.
-		next -= (int32(size) - c.next_sample)
-		if next < 0 {
-			next = 0
-		}
-		c.next_sample = next
-	}
-
-	mProf_Malloc(x, size)
-}
-
-// force = 1 - do GC regardless of current heap usage
-// force = 2 - go GC and eager sweep
-func gogc(force int32) {
-	// The gc is turned off (via enablegc) until the bootstrap has completed.
-	// Also, malloc gets called in the guts of a number of libraries that might be
-	// holding locks. To avoid deadlocks during stoptheworld, don't bother
-	// trying to run gc while holding a lock. The next mallocgc without a lock
-	// will do the gc instead.
-	mp := acquirem()
-	if gp := getg(); gp == mp.g0 || mp.locks > 1 || !memstats.enablegc || panicking != 0 || gcpercent < 0 {
-		releasem(mp)
-		return
-	}
-	releasem(mp)
-	mp = nil
-
-	semacquire(&worldsema, false)
-
-	if force == 0 && memstats.heap_alloc < memstats.next_gc {
-		// typically threads which lost the race to grab
-		// worldsema exit here when gc is done.
-		semrelease(&worldsema)
-		return
-	}
-
-	// Ok, we're doing it!  Stop everybody else
-	startTime := nanotime()
-	mp = acquirem()
-	mp.gcing = 1
-	releasem(mp)
-	onM(stoptheworld)
-	if mp != acquirem() {
-		gothrow("gogc: rescheduled")
-	}
-
-	clearpools()
-
-	// Run gc on the g0 stack.  We do this so that the g stack
-	// we're currently running on will no longer change.  Cuts
-	// the root set down a bit (g0 stacks are not scanned, and
-	// we don't need to scan gc's internal state).  We also
-	// need to switch to g0 so we can shrink the stack.
-	n := 1
-	if debug.gctrace > 1 {
-		n = 2
-	}
-	for i := 0; i < n; i++ {
-		if i > 0 {
-			startTime = nanotime()
-		}
-		// switch to g0, call gc, then switch back
-		mp.scalararg[0] = uintptr(uint32(startTime)) // low 32 bits
-		mp.scalararg[1] = uintptr(startTime >> 32)   // high 32 bits
-		if force >= 2 {
-			mp.scalararg[2] = 1 // eagersweep
-		} else {
-			mp.scalararg[2] = 0
-		}
-		onM(gc_m)
-	}
-
-	// all done
-	mp.gcing = 0
-	semrelease(&worldsema)
-	onM(starttheworld)
-	releasem(mp)
-	mp = nil
-
-	// now that gc is done, kick off finalizer thread if needed
-	if !concurrentSweep {
-		// give the queued finalizers, if any, a chance to run
-		Gosched()
-	}
-}
-
-// GC runs a garbage collection.
-func GC() {
-	gogc(2)
-}
-
-// linker-provided
-var noptrdata struct{}
-var enoptrdata struct{}
-var noptrbss struct{}
-var enoptrbss struct{}
-
-// SetFinalizer sets the finalizer associated with x to f.
-// When the garbage collector finds an unreachable block
-// with an associated finalizer, it clears the association and runs
-// f(x) in a separate goroutine.  This makes x reachable again, but
-// now without an associated finalizer.  Assuming that SetFinalizer
-// is not called again, the next time the garbage collector sees
-// that x is unreachable, it will free x.
-//
-// SetFinalizer(x, nil) clears any finalizer associated with x.
-//
-// The argument x must be a pointer to an object allocated by
-// calling new or by taking the address of a composite literal.
-// The argument f must be a function that takes a single argument
-// to which x's type can be assigned, and can have arbitrary ignored return
-// values. If either of these is not true, SetFinalizer aborts the
-// program.
-//
-// Finalizers are run in dependency order: if A points at B, both have
-// finalizers, and they are otherwise unreachable, only the finalizer
-// for A runs; once A is freed, the finalizer for B can run.
-// If a cyclic structure includes a block with a finalizer, that
-// cycle is not guaranteed to be garbage collected and the finalizer
-// is not guaranteed to run, because there is no ordering that
-// respects the dependencies.
-//
-// The finalizer for x is scheduled to run at some arbitrary time after
-// x becomes unreachable.
-// There is no guarantee that finalizers will run before a program exits,
-// so typically they are useful only for releasing non-memory resources
-// associated with an object during a long-running program.
-// For example, an os.File object could use a finalizer to close the
-// associated operating system file descriptor when a program discards
-// an os.File without calling Close, but it would be a mistake
-// to depend on a finalizer to flush an in-memory I/O buffer such as a
-// bufio.Writer, because the buffer would not be flushed at program exit.
-//
-// It is not guaranteed that a finalizer will run if the size of *x is
-// zero bytes.
-//
-// It is not guaranteed that a finalizer will run for objects allocated
-// in initializers for package-level variables. Such objects may be
-// linker-allocated, not heap-allocated.
-//
-// A single goroutine runs all finalizers for a program, sequentially.
-// If a finalizer must run for a long time, it should do so by starting
-// a new goroutine.
-func SetFinalizer(obj interface{}, finalizer interface{}) {
-	e := (*eface)(unsafe.Pointer(&obj))
-	etyp := e._type
-	if etyp == nil {
-		gothrow("runtime.SetFinalizer: first argument is nil")
-	}
-	if etyp.kind&kindMask != kindPtr {
-		gothrow("runtime.SetFinalizer: first argument is " + *etyp._string + ", not pointer")
-	}
-	ot := (*ptrtype)(unsafe.Pointer(etyp))
-	if ot.elem == nil {
-		gothrow("nil elem type!")
-	}
-
-	// find the containing object
-	_, base, _ := findObject(e.data)
-
-	if base == nil {
-		// 0-length objects are okay.
-		if e.data == unsafe.Pointer(&zerobase) {
-			return
-		}
-
-		// Global initializers might be linker-allocated.
-		//	var Foo = &Object{}
-		//	func main() {
-		//		runtime.SetFinalizer(Foo, nil)
-		//	}
-		// The relevant segments are: noptrdata, data, bss, noptrbss.
-		// We cannot assume they are in any order or even contiguous,
-		// due to external linking.
-		if uintptr(unsafe.Pointer(&noptrdata)) <= uintptr(e.data) && uintptr(e.data) < uintptr(unsafe.Pointer(&enoptrdata)) ||
-			uintptr(unsafe.Pointer(&data)) <= uintptr(e.data) && uintptr(e.data) < uintptr(unsafe.Pointer(&edata)) ||
-			uintptr(unsafe.Pointer(&bss)) <= uintptr(e.data) && uintptr(e.data) < uintptr(unsafe.Pointer(&ebss)) ||
-			uintptr(unsafe.Pointer(&noptrbss)) <= uintptr(e.data) && uintptr(e.data) < uintptr(unsafe.Pointer(&enoptrbss)) {
-			return
-		}
-		gothrow("runtime.SetFinalizer: pointer not in allocated block")
-	}
-
-	if e.data != base {
-		// As an implementation detail we allow to set finalizers for an inner byte
-		// of an object if it could come from tiny alloc (see mallocgc for details).
-		if ot.elem == nil || ot.elem.kind&kindNoPointers == 0 || ot.elem.size >= maxTinySize {
-			gothrow("runtime.SetFinalizer: pointer not at beginning of allocated block")
-		}
-	}
-
-	f := (*eface)(unsafe.Pointer(&finalizer))
-	ftyp := f._type
-	if ftyp == nil {
-		// switch to M stack and remove finalizer
-		mp := acquirem()
-		mp.ptrarg[0] = e.data
-		onM(removeFinalizer_m)
-		releasem(mp)
-		return
-	}
-
-	if ftyp.kind&kindMask != kindFunc {
-		gothrow("runtime.SetFinalizer: second argument is " + *ftyp._string + ", not a function")
-	}
-	ft := (*functype)(unsafe.Pointer(ftyp))
-	ins := *(*[]*_type)(unsafe.Pointer(&ft.in))
-	if ft.dotdotdot || len(ins) != 1 {
-		gothrow("runtime.SetFinalizer: cannot pass " + *etyp._string + " to finalizer " + *ftyp._string)
-	}
-	fint := ins[0]
-	switch {
-	case fint == etyp:
-		// ok - same type
-		goto okarg
-	case fint.kind&kindMask == kindPtr:
-		if (fint.x == nil || fint.x.name == nil || etyp.x == nil || etyp.x.name == nil) && (*ptrtype)(unsafe.Pointer(fint)).elem == ot.elem {
-			// ok - not same type, but both pointers,
-			// one or the other is unnamed, and same element type, so assignable.
-			goto okarg
-		}
-	case fint.kind&kindMask == kindInterface:
-		ityp := (*interfacetype)(unsafe.Pointer(fint))
-		if len(ityp.mhdr) == 0 {
-			// ok - satisfies empty interface
-			goto okarg
-		}
-		if _, ok := assertE2I2(ityp, obj); ok {
-			goto okarg
-		}
-	}
-	gothrow("runtime.SetFinalizer: cannot pass " + *etyp._string + " to finalizer " + *ftyp._string)
-okarg:
-	// compute size needed for return parameters
-	nret := uintptr(0)
-	for _, t := range *(*[]*_type)(unsafe.Pointer(&ft.out)) {
-		nret = round(nret, uintptr(t.align)) + uintptr(t.size)
-	}
-	nret = round(nret, ptrSize)
-
-	// make sure we have a finalizer goroutine
-	createfing()
-
-	// switch to M stack to add finalizer record
-	mp := acquirem()
-	mp.ptrarg[0] = f.data
-	mp.ptrarg[1] = e.data
-	mp.scalararg[0] = nret
-	mp.ptrarg[2] = unsafe.Pointer(fint)
-	mp.ptrarg[3] = unsafe.Pointer(ot)
-	onM(setFinalizer_m)
-	if mp.scalararg[0] != 1 {
-		gothrow("runtime.SetFinalizer: finalizer already set")
-	}
-	releasem(mp)
-}
-
-// round n up to a multiple of a.  a must be a power of 2.
-func round(n, a uintptr) uintptr {
-	return (n + a - 1) &^ (a - 1)
-}
-
-// Look up pointer v in heap.  Return the span containing the object,
-// the start of the object, and the size of the object.  If the object
-// does not exist, return nil, nil, 0.
-func findObject(v unsafe.Pointer) (s *mspan, x unsafe.Pointer, n uintptr) {
-	c := gomcache()
-	c.local_nlookup++
-	if ptrSize == 4 && c.local_nlookup >= 1<<30 {
-		// purge cache stats to prevent overflow
-		lock(&mheap_.lock)
-		purgecachedstats(c)
-		unlock(&mheap_.lock)
-	}
-
-	// find span
-	arena_start := uintptr(unsafe.Pointer(mheap_.arena_start))
-	arena_used := uintptr(unsafe.Pointer(mheap_.arena_used))
-	if uintptr(v) < arena_start || uintptr(v) >= arena_used {
-		return
-	}
-	p := uintptr(v) >> pageShift
-	q := p - arena_start>>pageShift
-	s = *(**mspan)(add(unsafe.Pointer(mheap_.spans), q*ptrSize))
-	if s == nil {
-		return
-	}
-	x = unsafe.Pointer(uintptr(s.start) << pageShift)
-
-	if uintptr(v) < uintptr(x) || uintptr(v) >= uintptr(unsafe.Pointer(s.limit)) || s.state != mSpanInUse {
-		s = nil
-		x = nil
-		return
-	}
-
-	n = uintptr(s.elemsize)
-	if s.sizeclass != 0 {
-		x = add(x, (uintptr(v)-uintptr(x))/n*n)
-	}
-	return
-}
-
-var fingCreate uint32
-
-func createfing() {
-	// start the finalizer goroutine exactly once
-	if fingCreate == 0 && cas(&fingCreate, 0, 1) {
-		go runfinq()
-	}
-}
-
-// This is the goroutine that runs all of the finalizers
-func runfinq() {
-	var (
-		frame    unsafe.Pointer
-		framecap uintptr
-	)
-
-	for {
-		lock(&finlock)
-		fb := finq
-		finq = nil
-		if fb == nil {
-			gp := getg()
-			fing = gp
-			fingwait = true
-			gp.issystem = true
-			goparkunlock(&finlock, "finalizer wait")
-			gp.issystem = false
-			continue
-		}
-		unlock(&finlock)
-		if raceenabled {
-			racefingo()
-		}
-		for fb != nil {
-			for i := int32(0); i < fb.cnt; i++ {
-				f := (*finalizer)(add(unsafe.Pointer(&fb.fin), uintptr(i)*unsafe.Sizeof(finalizer{})))
-
-				framesz := unsafe.Sizeof((interface{})(nil)) + uintptr(f.nret)
-				if framecap < framesz {
-					// The frame does not contain pointers interesting for GC,
-					// all not yet finalized objects are stored in finq.
-					// If we do not mark it as FlagNoScan,
-					// the last finalized object is not collected.
-					frame = mallocgc(framesz, nil, flagNoScan)
-					framecap = framesz
-				}
-
-				if f.fint == nil {
-					gothrow("missing type in runfinq")
-				}
-				switch f.fint.kind & kindMask {
-				case kindPtr:
-					// direct use of pointer
-					*(*unsafe.Pointer)(frame) = f.arg
-				case kindInterface:
-					ityp := (*interfacetype)(unsafe.Pointer(f.fint))
-					// set up with empty interface
-					(*eface)(frame)._type = &f.ot.typ
-					(*eface)(frame).data = f.arg
-					if len(ityp.mhdr) != 0 {
-						// convert to interface with methods
-						// this conversion is guaranteed to succeed - we checked in SetFinalizer
-						*(*fInterface)(frame) = assertE2I(ityp, *(*interface{})(frame))
-					}
-				default:
-					gothrow("bad kind in runfinq")
-				}
-				reflectcall(unsafe.Pointer(f.fn), frame, uint32(framesz), uint32(framesz))
-
-				// drop finalizer queue references to finalized object
-				f.fn = nil
-				f.arg = nil
-				f.ot = nil
-			}
-			fb.cnt = 0
-			next := fb.next
-			lock(&finlock)
-			fb.next = finc
-			finc = fb
-			unlock(&finlock)
-			fb = next
-		}
-	}
-}
-
-var persistent struct {
-	lock mutex
-	pos  unsafe.Pointer
-	end  unsafe.Pointer
-}
-
-// Wrapper around sysAlloc that can allocate small chunks.
-// There is no associated free operation.
-// Intended for things like function/type/debug-related persistent data.
-// If align is 0, uses default align (currently 8).
-func persistentalloc(size, align uintptr, stat *uint64) unsafe.Pointer {
-	const (
-		chunk    = 256 << 10
-		maxBlock = 64 << 10 // VM reservation granularity is 64K on windows
-	)
-
-	if align != 0 {
-		if align&(align-1) != 0 {
-			gothrow("persistentalloc: align is not a power of 2")
-		}
-		if align > _PageSize {
-			gothrow("persistentalloc: align is too large")
-		}
-	} else {
-		align = 8
-	}
-
-	if size >= maxBlock {
-		return sysAlloc(size, stat)
-	}
-
-	lock(&persistent.lock)
-	persistent.pos = roundup(persistent.pos, align)
-	if uintptr(persistent.pos)+size > uintptr(persistent.end) {
-		persistent.pos = sysAlloc(chunk, &memstats.other_sys)
-		if persistent.pos == nil {
-			unlock(&persistent.lock)
-			gothrow("runtime: cannot allocate memory")
-		}
-		persistent.end = add(persistent.pos, chunk)
-	}
-	p := persistent.pos
-	persistent.pos = add(persistent.pos, size)
-	unlock(&persistent.lock)
-
-	if stat != &memstats.other_sys {
-		xadd64(stat, int64(size))
-		xadd64(&memstats.other_sys, -int64(size))
-	}
-	return p
-}
diff --git a/third_party/gofrontend/libgo/go/runtime/malloc_test.go b/third_party/gofrontend/libgo/go/runtime/malloc_test.go
index 054f6a7..df6a0e5 100644
--- a/third_party/gofrontend/libgo/go/runtime/malloc_test.go
+++ b/third_party/gofrontend/libgo/go/runtime/malloc_test.go
@@ -13,17 +13,74 @@
 )
 
 func TestMemStats(t *testing.T) {
+	t.Skip("skipping test with gccgo")
 	// Test that MemStats has sane values.
 	st := new(MemStats)
 	ReadMemStats(st)
-	if st.HeapSys == 0 || /* st.StackSys == 0 || */ st.MSpanSys == 0 || st.MCacheSys == 0 ||
-		st.BuckHashSys == 0 || st.GCSys == 0 || st.OtherSys == 0 {
-		t.Fatalf("Zero sys value: %+v", *st)
+
+	// Everything except HeapReleased and HeapIdle, because they indeed can be 0.
+	if st.Alloc == 0 || st.TotalAlloc == 0 || st.Sys == 0 || st.Lookups == 0 ||
+		st.Mallocs == 0 || st.Frees == 0 || st.HeapAlloc == 0 || st.HeapSys == 0 ||
+		st.HeapInuse == 0 || st.HeapObjects == 0 || st.StackInuse == 0 ||
+		st.StackSys == 0 || st.MSpanInuse == 0 || st.MSpanSys == 0 || st.MCacheInuse == 0 ||
+		st.MCacheSys == 0 || st.BuckHashSys == 0 || st.GCSys == 0 || st.OtherSys == 0 ||
+		st.NextGC == 0 || st.NumGC == 0 {
+		t.Fatalf("Zero value: %+v", *st)
+	}
+
+	if st.Alloc > 1e10 || st.TotalAlloc > 1e11 || st.Sys > 1e10 || st.Lookups > 1e10 ||
+		st.Mallocs > 1e10 || st.Frees > 1e10 || st.HeapAlloc > 1e10 || st.HeapSys > 1e10 ||
+		st.HeapIdle > 1e10 || st.HeapInuse > 1e10 || st.HeapObjects > 1e10 || st.StackInuse > 1e10 ||
+		st.StackSys > 1e10 || st.MSpanInuse > 1e10 || st.MSpanSys > 1e10 || st.MCacheInuse > 1e10 ||
+		st.MCacheSys > 1e10 || st.BuckHashSys > 1e10 || st.GCSys > 1e10 || st.OtherSys > 1e10 ||
+		st.NextGC > 1e10 || st.NumGC > 1e9 || st.PauseTotalNs > 1e11 {
+		t.Fatalf("Insanely high value (overflow?): %+v", *st)
 	}
 	if st.Sys != st.HeapSys+st.StackSys+st.MSpanSys+st.MCacheSys+
 		st.BuckHashSys+st.GCSys+st.OtherSys {
 		t.Fatalf("Bad sys value: %+v", *st)
 	}
+
+	if st.HeapIdle+st.HeapInuse != st.HeapSys {
+		t.Fatalf("HeapIdle(%d) + HeapInuse(%d) should be equal to HeapSys(%d), but isn't.", st.HeapIdle, st.HeapInuse, st.HeapSys)
+	}
+
+	if lpe := st.PauseEnd[int(st.NumGC+255)%len(st.PauseEnd)]; st.LastGC != lpe {
+		t.Fatalf("LastGC(%d) != last PauseEnd(%d)", st.LastGC, lpe)
+	}
+
+	var pauseTotal uint64
+	for _, pause := range st.PauseNs {
+		pauseTotal += pause
+	}
+	if int(st.NumGC) < len(st.PauseNs) {
+		// We have all pauses, so this should be exact.
+		if st.PauseTotalNs != pauseTotal {
+			t.Fatalf("PauseTotalNs(%d) != sum PauseNs(%d)", st.PauseTotalNs, pauseTotal)
+		}
+	} else {
+		if st.PauseTotalNs < pauseTotal {
+			t.Fatalf("PauseTotalNs(%d) < sum PauseNs(%d)", st.PauseTotalNs, pauseTotal)
+		}
+	}
+}
+
+func TestStringConcatenationAllocs(t *testing.T) {
+	t.Skip("skipping test with gccgo")
+	n := testing.AllocsPerRun(1e3, func() {
+		b := make([]byte, 10)
+		for i := 0; i < 10; i++ {
+			b[i] = byte(i) + '0'
+		}
+		s := "foo" + string(b)
+		if want := "foo0123456789"; s != want {
+			t.Fatalf("want %v, got %v", want, s)
+		}
+	})
+	// Only string concatenation allocates.
+	if n != 1 {
+		t.Fatalf("want 1 allocation, got %v", n)
+	}
 }
 
 var mallocSink uintptr
diff --git a/third_party/gofrontend/libgo/go/runtime/map_test.go b/third_party/gofrontend/libgo/go/runtime/map_test.go
index 9ed183b..ed0347a 100644
--- a/third_party/gofrontend/libgo/go/runtime/map_test.go
+++ b/third_party/gofrontend/libgo/go/runtime/map_test.go
@@ -391,7 +391,7 @@
 	nan := math.NaN()
 	const nBuckets = 16
 	// To fill nBuckets buckets takes LOAD * nBuckets keys.
-	nKeys := int(nBuckets * *runtime.HashLoad)
+	nKeys := int(nBuckets * /* *runtime.HashLoad */ 6.5)
 
 	// Get map to full point with nan keys.
 	for i := 0; i < nKeys; i++ {
@@ -537,6 +537,61 @@
 	}
 }
 
+func TestMapLargeKeyNoPointer(t *testing.T) {
+	const (
+		I = 1000
+		N = 64
+	)
+	type T [N]int
+	m := make(map[T]int)
+	for i := 0; i < I; i++ {
+		var v T
+		for j := 0; j < N; j++ {
+			v[j] = i + j
+		}
+		m[v] = i
+	}
+	runtime.GC()
+	for i := 0; i < I; i++ {
+		var v T
+		for j := 0; j < N; j++ {
+			v[j] = i + j
+		}
+		if m[v] != i {
+			t.Fatalf("corrupted map: want %+v, got %+v", i, m[v])
+		}
+	}
+}
+
+func TestMapLargeValNoPointer(t *testing.T) {
+	const (
+		I = 1000
+		N = 64
+	)
+	type T [N]int
+	m := make(map[int]T)
+	for i := 0; i < I; i++ {
+		var v T
+		for j := 0; j < N; j++ {
+			v[j] = i + j
+		}
+		m[i] = v
+	}
+	runtime.GC()
+	for i := 0; i < I; i++ {
+		var v T
+		for j := 0; j < N; j++ {
+			v[j] = i + j
+		}
+		v1 := m[i]
+		for j := 0; j < N; j++ {
+			if v1[j] != v[j] {
+				t.Fatalf("corrupted map: want %+v, got %+v", v, v1)
+			}
+		}
+	}
+}
+
 func benchmarkMapPop(b *testing.B, n int) {
 	m := map[int]int{}
 	for i := 0; i < b.N; i++ {
@@ -557,3 +612,14 @@
 func BenchmarkMapPop100(b *testing.B)   { benchmarkMapPop(b, 100) }
 func BenchmarkMapPop1000(b *testing.B)  { benchmarkMapPop(b, 1000) }
 func BenchmarkMapPop10000(b *testing.B) { benchmarkMapPop(b, 10000) }
+
+func TestNonEscapingMap(t *testing.T) {
+	t.Skip("does not work on gccgo without better escape analysis")
+	n := testing.AllocsPerRun(1000, func() {
+		m := make(map[int]int)
+		m[0] = 0
+	})
+	if n != 0 {
+		t.Fatalf("want 0 allocs, got %v", n)
+	}
+}
diff --git a/third_party/gofrontend/libgo/go/runtime/mapspeed_test.go b/third_party/gofrontend/libgo/go/runtime/mapspeed_test.go
index 119eb3f..ac93119 100644
--- a/third_party/gofrontend/libgo/go/runtime/mapspeed_test.go
+++ b/third_party/gofrontend/libgo/go/runtime/mapspeed_test.go
@@ -234,6 +234,15 @@
 	}
 }
 
+func BenchmarkNewSmallMap(b *testing.B) {
+	b.ReportAllocs()
+	for i := 0; i < b.N; i++ {
+		m := make(map[int]int)
+		m[0] = 0
+		m[1] = 1
+	}
+}
+
 func BenchmarkMapIter(b *testing.B) {
 	m := make(map[int]bool)
 	for i := 0; i < 8; i++ {
@@ -298,3 +307,22 @@
 		_ = m[5]
 	}
 }
+
+type ComplexAlgKey struct {
+	a, b, c int64
+	_       int
+	d       int32
+	_       int
+	e       string
+	_       int
+	f, g, h int64
+}
+
+func BenchmarkComplexAlgMap(b *testing.B) {
+	m := make(map[ComplexAlgKey]bool)
+	var k ComplexAlgKey
+	m[k] = true
+	for i := 0; i < b.N; i++ {
+		_ = m[k]
+	}
+}
diff --git a/third_party/gofrontend/libgo/go/runtime/mem.go b/third_party/gofrontend/libgo/go/runtime/mem.go
index fb35535..b41d741 100644
--- a/third_party/gofrontend/libgo/go/runtime/mem.go
+++ b/third_party/gofrontend/libgo/go/runtime/mem.go
@@ -41,13 +41,15 @@
 	OtherSys    uint64 // other system allocations
 
 	// Garbage collector statistics.
-	NextGC       uint64 // next run in HeapAlloc time (bytes)
-	LastGC       uint64 // last run in absolute time (ns)
-	PauseTotalNs uint64
-	PauseNs      [256]uint64 // circular buffer of recent GC pause times, most recent at [(NumGC+255)%256]
-	NumGC        uint32
-	EnableGC     bool
-	DebugGC      bool
+	NextGC        uint64 // next run in HeapAlloc time (bytes)
+	LastGC        uint64 // last run in absolute time (ns)
+	PauseTotalNs  uint64
+	PauseNs       [256]uint64 // circular buffer of recent GC pause times, most recent at [(NumGC+255)%256]
+	PauseEnd      [256]uint64 // circular buffer of recent GC pause end times
+	NumGC         uint32
+	GCCPUFraction float64 // fraction of CPU time used by GC
+	EnableGC      bool
+	DebugGC       bool
 
 	// Per-size allocation statistics.
 	// 61 is NumSizeClasses in the C code.
diff --git a/third_party/gofrontend/libgo/go/runtime/memmove_test.go b/third_party/gofrontend/libgo/go/runtime/memmove_test.go
deleted file mode 100644
index ffda4fe..0000000
--- a/third_party/gofrontend/libgo/go/runtime/memmove_test.go
+++ /dev/null
@@ -1,295 +0,0 @@
-// Copyright 2013 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 runtime_test
-
-import (
-	. "runtime"
-	"testing"
-)
-
-func TestMemmove(t *testing.T) {
-	size := 256
-	if testing.Short() {
-		size = 128 + 16
-	}
-	src := make([]byte, size)
-	dst := make([]byte, size)
-	for i := 0; i < size; i++ {
-		src[i] = byte(128 + (i & 127))
-	}
-	for i := 0; i < size; i++ {
-		dst[i] = byte(i & 127)
-	}
-	for n := 0; n <= size; n++ {
-		for x := 0; x <= size-n; x++ { // offset in src
-			for y := 0; y <= size-n; y++ { // offset in dst
-				copy(dst[y:y+n], src[x:x+n])
-				for i := 0; i < y; i++ {
-					if dst[i] != byte(i&127) {
-						t.Fatalf("prefix dst[%d] = %d", i, dst[i])
-					}
-				}
-				for i := y; i < y+n; i++ {
-					if dst[i] != byte(128+((i-y+x)&127)) {
-						t.Fatalf("copied dst[%d] = %d", i, dst[i])
-					}
-					dst[i] = byte(i & 127) // reset dst
-				}
-				for i := y + n; i < size; i++ {
-					if dst[i] != byte(i&127) {
-						t.Fatalf("suffix dst[%d] = %d", i, dst[i])
-					}
-				}
-			}
-		}
-	}
-}
-
-func TestMemmoveAlias(t *testing.T) {
-	size := 256
-	if testing.Short() {
-		size = 128 + 16
-	}
-	buf := make([]byte, size)
-	for i := 0; i < size; i++ {
-		buf[i] = byte(i)
-	}
-	for n := 0; n <= size; n++ {
-		for x := 0; x <= size-n; x++ { // src offset
-			for y := 0; y <= size-n; y++ { // dst offset
-				copy(buf[y:y+n], buf[x:x+n])
-				for i := 0; i < y; i++ {
-					if buf[i] != byte(i) {
-						t.Fatalf("prefix buf[%d] = %d", i, buf[i])
-					}
-				}
-				for i := y; i < y+n; i++ {
-					if buf[i] != byte(i-y+x) {
-						t.Fatalf("copied buf[%d] = %d", i, buf[i])
-					}
-					buf[i] = byte(i) // reset buf
-				}
-				for i := y + n; i < size; i++ {
-					if buf[i] != byte(i) {
-						t.Fatalf("suffix buf[%d] = %d", i, buf[i])
-					}
-				}
-			}
-		}
-	}
-}
-
-func bmMemmove(b *testing.B, n int) {
-	x := make([]byte, n)
-	y := make([]byte, n)
-	b.SetBytes(int64(n))
-	for i := 0; i < b.N; i++ {
-		copy(x, y)
-	}
-}
-
-func BenchmarkMemmove0(b *testing.B)    { bmMemmove(b, 0) }
-func BenchmarkMemmove1(b *testing.B)    { bmMemmove(b, 1) }
-func BenchmarkMemmove2(b *testing.B)    { bmMemmove(b, 2) }
-func BenchmarkMemmove3(b *testing.B)    { bmMemmove(b, 3) }
-func BenchmarkMemmove4(b *testing.B)    { bmMemmove(b, 4) }
-func BenchmarkMemmove5(b *testing.B)    { bmMemmove(b, 5) }
-func BenchmarkMemmove6(b *testing.B)    { bmMemmove(b, 6) }
-func BenchmarkMemmove7(b *testing.B)    { bmMemmove(b, 7) }
-func BenchmarkMemmove8(b *testing.B)    { bmMemmove(b, 8) }
-func BenchmarkMemmove9(b *testing.B)    { bmMemmove(b, 9) }
-func BenchmarkMemmove10(b *testing.B)   { bmMemmove(b, 10) }
-func BenchmarkMemmove11(b *testing.B)   { bmMemmove(b, 11) }
-func BenchmarkMemmove12(b *testing.B)   { bmMemmove(b, 12) }
-func BenchmarkMemmove13(b *testing.B)   { bmMemmove(b, 13) }
-func BenchmarkMemmove14(b *testing.B)   { bmMemmove(b, 14) }
-func BenchmarkMemmove15(b *testing.B)   { bmMemmove(b, 15) }
-func BenchmarkMemmove16(b *testing.B)   { bmMemmove(b, 16) }
-func BenchmarkMemmove32(b *testing.B)   { bmMemmove(b, 32) }
-func BenchmarkMemmove64(b *testing.B)   { bmMemmove(b, 64) }
-func BenchmarkMemmove128(b *testing.B)  { bmMemmove(b, 128) }
-func BenchmarkMemmove256(b *testing.B)  { bmMemmove(b, 256) }
-func BenchmarkMemmove512(b *testing.B)  { bmMemmove(b, 512) }
-func BenchmarkMemmove1024(b *testing.B) { bmMemmove(b, 1024) }
-func BenchmarkMemmove2048(b *testing.B) { bmMemmove(b, 2048) }
-func BenchmarkMemmove4096(b *testing.B) { bmMemmove(b, 4096) }
-
-func TestMemclr(t *testing.T) {
-	size := 512
-	if testing.Short() {
-		size = 128 + 16
-	}
-	mem := make([]byte, size)
-	for i := 0; i < size; i++ {
-		mem[i] = 0xee
-	}
-	for n := 0; n < size; n++ {
-		for x := 0; x <= size-n; x++ { // offset in mem
-			MemclrBytes(mem[x : x+n])
-			for i := 0; i < x; i++ {
-				if mem[i] != 0xee {
-					t.Fatalf("overwrite prefix mem[%d] = %d", i, mem[i])
-				}
-			}
-			for i := x; i < x+n; i++ {
-				if mem[i] != 0 {
-					t.Fatalf("failed clear mem[%d] = %d", i, mem[i])
-				}
-				mem[i] = 0xee
-			}
-			for i := x + n; i < size; i++ {
-				if mem[i] != 0xee {
-					t.Fatalf("overwrite suffix mem[%d] = %d", i, mem[i])
-				}
-			}
-		}
-	}
-}
-
-func bmMemclr(b *testing.B, n int) {
-	x := make([]byte, n)
-	b.SetBytes(int64(n))
-	for i := 0; i < b.N; i++ {
-		MemclrBytes(x)
-	}
-}
-func BenchmarkMemclr5(b *testing.B)     { bmMemclr(b, 5) }
-func BenchmarkMemclr16(b *testing.B)    { bmMemclr(b, 16) }
-func BenchmarkMemclr64(b *testing.B)    { bmMemclr(b, 64) }
-func BenchmarkMemclr256(b *testing.B)   { bmMemclr(b, 256) }
-func BenchmarkMemclr4096(b *testing.B)  { bmMemclr(b, 4096) }
-func BenchmarkMemclr65536(b *testing.B) { bmMemclr(b, 65536) }
-
-func BenchmarkClearFat8(b *testing.B) {
-	for i := 0; i < b.N; i++ {
-		var x [8 / 4]uint32
-		_ = x
-	}
-}
-func BenchmarkClearFat12(b *testing.B) {
-	for i := 0; i < b.N; i++ {
-		var x [12 / 4]uint32
-		_ = x
-	}
-}
-func BenchmarkClearFat16(b *testing.B) {
-	for i := 0; i < b.N; i++ {
-		var x [16 / 4]uint32
-		_ = x
-	}
-}
-func BenchmarkClearFat24(b *testing.B) {
-	for i := 0; i < b.N; i++ {
-		var x [24 / 4]uint32
-		_ = x
-	}
-}
-func BenchmarkClearFat32(b *testing.B) {
-	for i := 0; i < b.N; i++ {
-		var x [32 / 4]uint32
-		_ = x
-	}
-}
-func BenchmarkClearFat64(b *testing.B) {
-	for i := 0; i < b.N; i++ {
-		var x [64 / 4]uint32
-		_ = x
-	}
-}
-func BenchmarkClearFat128(b *testing.B) {
-	for i := 0; i < b.N; i++ {
-		var x [128 / 4]uint32
-		_ = x
-	}
-}
-func BenchmarkClearFat256(b *testing.B) {
-	for i := 0; i < b.N; i++ {
-		var x [256 / 4]uint32
-		_ = x
-	}
-}
-func BenchmarkClearFat512(b *testing.B) {
-	for i := 0; i < b.N; i++ {
-		var x [512 / 4]uint32
-		_ = x
-	}
-}
-func BenchmarkClearFat1024(b *testing.B) {
-	for i := 0; i < b.N; i++ {
-		var x [1024 / 4]uint32
-		_ = x
-	}
-}
-
-func BenchmarkCopyFat8(b *testing.B) {
-	var x [8 / 4]uint32
-	for i := 0; i < b.N; i++ {
-		y := x
-		_ = y
-	}
-}
-func BenchmarkCopyFat12(b *testing.B) {
-	var x [12 / 4]uint32
-	for i := 0; i < b.N; i++ {
-		y := x
-		_ = y
-	}
-}
-func BenchmarkCopyFat16(b *testing.B) {
-	var x [16 / 4]uint32
-	for i := 0; i < b.N; i++ {
-		y := x
-		_ = y
-	}
-}
-func BenchmarkCopyFat24(b *testing.B) {
-	var x [24 / 4]uint32
-	for i := 0; i < b.N; i++ {
-		y := x
-		_ = y
-	}
-}
-func BenchmarkCopyFat32(b *testing.B) {
-	var x [32 / 4]uint32
-	for i := 0; i < b.N; i++ {
-		y := x
-		_ = y
-	}
-}
-func BenchmarkCopyFat64(b *testing.B) {
-	var x [64 / 4]uint32
-	for i := 0; i < b.N; i++ {
-		y := x
-		_ = y
-	}
-}
-func BenchmarkCopyFat128(b *testing.B) {
-	var x [128 / 4]uint32
-	for i := 0; i < b.N; i++ {
-		y := x
-		_ = y
-	}
-}
-func BenchmarkCopyFat256(b *testing.B) {
-	var x [256 / 4]uint32
-	for i := 0; i < b.N; i++ {
-		y := x
-		_ = y
-	}
-}
-func BenchmarkCopyFat512(b *testing.B) {
-	var x [512 / 4]uint32
-	for i := 0; i < b.N; i++ {
-		y := x
-		_ = y
-	}
-}
-func BenchmarkCopyFat1024(b *testing.B) {
-	var x [1024 / 4]uint32
-	for i := 0; i < b.N; i++ {
-		y := x
-		_ = y
-	}
-}
diff --git a/third_party/gofrontend/libgo/go/runtime/mfinal_test.go b/third_party/gofrontend/libgo/go/runtime/mfinal_test.go
index 512a14e..e534496 100644
--- a/third_party/gofrontend/libgo/go/runtime/mfinal_test.go
+++ b/third_party/gofrontend/libgo/go/runtime/mfinal_test.go
@@ -178,9 +178,6 @@
 
 // Make sure an empty slice on the stack doesn't pin the next object in memory.
 func TestEmptySlice(t *testing.T) {
-	if true { // disable until bug 7564 is fixed.
-		return
-	}
 	if runtime.Compiler == "gccgo" {
 		t.Skip("skipping for gccgo")
 	}
diff --git a/third_party/gofrontend/libgo/go/runtime/mgc0.go b/third_party/gofrontend/libgo/go/runtime/mgc0.go
deleted file mode 100644
index cbf5e9c..0000000
--- a/third_party/gofrontend/libgo/go/runtime/mgc0.go
+++ /dev/null
@@ -1,152 +0,0 @@
-// Copyright 2012 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 runtime
-
-import "unsafe"
-
-// Called from C. Returns the Go type *m.
-func gc_m_ptr(ret *interface{}) {
-	*ret = (*m)(nil)
-}
-
-// Called from C. Returns the Go type *g.
-func gc_g_ptr(ret *interface{}) {
-	*ret = (*g)(nil)
-}
-
-// Called from C. Returns the Go type *itab.
-func gc_itab_ptr(ret *interface{}) {
-	*ret = (*itab)(nil)
-}
-
-func gc_unixnanotime(now *int64) {
-	sec, nsec := timenow()
-	*now = sec*1e9 + int64(nsec)
-}
-
-func freeOSMemory() {
-	gogc(2) // force GC and do eager sweep
-	onM(scavenge_m)
-}
-
-var poolcleanup func()
-
-func registerPoolCleanup(f func()) {
-	poolcleanup = f
-}
-
-func clearpools() {
-	// clear sync.Pools
-	if poolcleanup != nil {
-		poolcleanup()
-	}
-
-	for _, p := range &allp {
-		if p == nil {
-			break
-		}
-		// clear tinyalloc pool
-		if c := p.mcache; c != nil {
-			c.tiny = nil
-			c.tinysize = 0
-
-			// disconnect cached list before dropping it on the floor,
-			// so that a dangling ref to one entry does not pin all of them.
-			var sg, sgnext *sudog
-			for sg = c.sudogcache; sg != nil; sg = sgnext {
-				sgnext = sg.next
-				sg.next = nil
-			}
-			c.sudogcache = nil
-		}
-
-		// clear defer pools
-		for i := range p.deferpool {
-			// disconnect cached list before dropping it on the floor,
-			// so that a dangling ref to one entry does not pin all of them.
-			var d, dlink *_defer
-			for d = p.deferpool[i]; d != nil; d = dlink {
-				dlink = d.link
-				d.link = nil
-			}
-			p.deferpool[i] = nil
-		}
-	}
-}
-
-func gosweepone() uintptr
-func gosweepdone() bool
-
-func bgsweep() {
-	getg().issystem = true
-	for {
-		for gosweepone() != ^uintptr(0) {
-			sweep.nbgsweep++
-			Gosched()
-		}
-		lock(&gclock)
-		if !gosweepdone() {
-			// This can happen if a GC runs between
-			// gosweepone returning ^0 above
-			// and the lock being acquired.
-			unlock(&gclock)
-			continue
-		}
-		sweep.parked = true
-		goparkunlock(&gclock, "GC sweep wait")
-	}
-}
-
-// NOTE: Really dst *unsafe.Pointer, src unsafe.Pointer,
-// but if we do that, Go inserts a write barrier on *dst = src.
-//go:nosplit
-func writebarrierptr(dst *uintptr, src uintptr) {
-	*dst = src
-}
-
-//go:nosplit
-func writebarrierstring(dst *[2]uintptr, src [2]uintptr) {
-	dst[0] = src[0]
-	dst[1] = src[1]
-}
-
-//go:nosplit
-func writebarrierslice(dst *[3]uintptr, src [3]uintptr) {
-	dst[0] = src[0]
-	dst[1] = src[1]
-	dst[2] = src[2]
-}
-
-//go:nosplit
-func writebarrieriface(dst *[2]uintptr, src [2]uintptr) {
-	dst[0] = src[0]
-	dst[1] = src[1]
-}
-
-//go:nosplit
-func writebarrierfat2(dst *[2]uintptr, _ *byte, src [2]uintptr) {
-	dst[0] = src[0]
-	dst[1] = src[1]
-}
-
-//go:nosplit
-func writebarrierfat3(dst *[3]uintptr, _ *byte, src [3]uintptr) {
-	dst[0] = src[0]
-	dst[1] = src[1]
-	dst[2] = src[2]
-}
-
-//go:nosplit
-func writebarrierfat4(dst *[4]uintptr, _ *byte, src [4]uintptr) {
-	dst[0] = src[0]
-	dst[1] = src[1]
-	dst[2] = src[2]
-	dst[3] = src[3]
-}
-
-//go:nosplit
-func writebarrierfat(typ *_type, dst, src unsafe.Pointer) {
-	memmove(dst, src, typ.size)
-}
diff --git a/third_party/gofrontend/libgo/go/runtime/mprof.go b/third_party/gofrontend/libgo/go/runtime/mprof.go
deleted file mode 100644
index f4da45f..0000000
--- a/third_party/gofrontend/libgo/go/runtime/mprof.go
+++ /dev/null
@@ -1,668 +0,0 @@
-// Copyright 2009 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.
-
-// Malloc profiling.
-// Patterned after tcmalloc's algorithms; shorter code.
-
-package runtime
-
-import (
-	"unsafe"
-)
-
-// NOTE(rsc): Everything here could use cas if contention became an issue.
-var proflock mutex
-
-// All memory allocations are local and do not escape outside of the profiler.
-// The profiler is forbidden from referring to garbage-collected memory.
-
-const (
-	// profile types
-	memProfile bucketType = 1 + iota
-	blockProfile
-
-	// size of bucket hash table
-	buckHashSize = 179999
-
-	// max depth of stack to record in bucket
-	maxStack = 32
-)
-
-type bucketType int
-
-// A bucket holds per-call-stack profiling information.
-// The representation is a bit sleazy, inherited from C.
-// This struct defines the bucket header. It is followed in
-// memory by the stack words and then the actual record
-// data, either a memRecord or a blockRecord.
-//
-// Per-call-stack profiling information.
-// Lookup by hashing call stack into a linked-list hash table.
-type bucket struct {
-	next    *bucket
-	allnext *bucket
-	typ     bucketType // memBucket or blockBucket
-	hash    uintptr
-	size    uintptr
-	nstk    uintptr
-}
-
-// A memRecord is the bucket data for a bucket of type memProfile,
-// part of the memory profile.
-type memRecord struct {
-	// The following complex 3-stage scheme of stats accumulation
-	// is required to obtain a consistent picture of mallocs and frees
-	// for some point in time.
-	// The problem is that mallocs come in real time, while frees
-	// come only after a GC during concurrent sweeping. So if we would
-	// naively count them, we would get a skew toward mallocs.
-	//
-	// Mallocs are accounted in recent stats.
-	// Explicit frees are accounted in recent stats.
-	// GC frees are accounted in prev stats.
-	// After GC prev stats are added to final stats and
-	// recent stats are moved into prev stats.
-	allocs      uintptr
-	frees       uintptr
-	alloc_bytes uintptr
-	free_bytes  uintptr
-
-	// changes between next-to-last GC and last GC
-	prev_allocs      uintptr
-	prev_frees       uintptr
-	prev_alloc_bytes uintptr
-	prev_free_bytes  uintptr
-
-	// changes since last GC
-	recent_allocs      uintptr
-	recent_frees       uintptr
-	recent_alloc_bytes uintptr
-	recent_free_bytes  uintptr
-}
-
-// A blockRecord is the bucket data for a bucket of type blockProfile,
-// part of the blocking profile.
-type blockRecord struct {
-	count  int64
-	cycles int64
-}
-
-var (
-	mbuckets  *bucket // memory profile buckets
-	bbuckets  *bucket // blocking profile buckets
-	buckhash  *[179999]*bucket
-	bucketmem uintptr
-)
-
-// newBucket allocates a bucket with the given type and number of stack entries.
-func newBucket(typ bucketType, nstk int) *bucket {
-	size := unsafe.Sizeof(bucket{}) + uintptr(nstk)*unsafe.Sizeof(uintptr(0))
-	switch typ {
-	default:
-		gothrow("invalid profile bucket type")
-	case memProfile:
-		size += unsafe.Sizeof(memRecord{})
-	case blockProfile:
-		size += unsafe.Sizeof(blockRecord{})
-	}
-
-	b := (*bucket)(persistentalloc(size, 0, &memstats.buckhash_sys))
-	bucketmem += size
-	b.typ = typ
-	b.nstk = uintptr(nstk)
-	return b
-}
-
-// stk returns the slice in b holding the stack.
-func (b *bucket) stk() []uintptr {
-	stk := (*[maxStack]uintptr)(add(unsafe.Pointer(b), unsafe.Sizeof(*b)))
-	return stk[:b.nstk:b.nstk]
-}
-
-// mp returns the memRecord associated with the memProfile bucket b.
-func (b *bucket) mp() *memRecord {
-	if b.typ != memProfile {
-		gothrow("bad use of bucket.mp")
-	}
-	data := add(unsafe.Pointer(b), unsafe.Sizeof(*b)+b.nstk*unsafe.Sizeof(uintptr(0)))
-	return (*memRecord)(data)
-}
-
-// bp returns the blockRecord associated with the blockProfile bucket b.
-func (b *bucket) bp() *blockRecord {
-	if b.typ != blockProfile {
-		gothrow("bad use of bucket.bp")
-	}
-	data := add(unsafe.Pointer(b), unsafe.Sizeof(*b)+b.nstk*unsafe.Sizeof(uintptr(0)))
-	return (*blockRecord)(data)
-}
-
-// Return the bucket for stk[0:nstk], allocating new bucket if needed.
-func stkbucket(typ bucketType, size uintptr, stk []uintptr, alloc bool) *bucket {
-	if buckhash == nil {
-		buckhash = (*[buckHashSize]*bucket)(sysAlloc(unsafe.Sizeof(*buckhash), &memstats.buckhash_sys))
-		if buckhash == nil {
-			gothrow("runtime: cannot allocate memory")
-		}
-	}
-
-	// Hash stack.
-	var h uintptr
-	for _, pc := range stk {
-		h += pc
-		h += h << 10
-		h ^= h >> 6
-	}
-	// hash in size
-	h += size
-	h += h << 10
-	h ^= h >> 6
-	// finalize
-	h += h << 3
-	h ^= h >> 11
-
-	i := int(h % buckHashSize)
-	for b := buckhash[i]; b != nil; b = b.next {
-		if b.typ == typ && b.hash == h && b.size == size && eqslice(b.stk(), stk) {
-			return b
-		}
-	}
-
-	if !alloc {
-		return nil
-	}
-
-	// Create new bucket.
-	b := newBucket(typ, len(stk))
-	copy(b.stk(), stk)
-	b.hash = h
-	b.size = size
-	b.next = buckhash[i]
-	buckhash[i] = b
-	if typ == memProfile {
-		b.allnext = mbuckets
-		mbuckets = b
-	} else {
-		b.allnext = bbuckets
-		bbuckets = b
-	}
-	return b
-}
-
-func sysAlloc(n uintptr, stat *uint64) unsafe.Pointer
-
-func eqslice(x, y []uintptr) bool {
-	if len(x) != len(y) {
-		return false
-	}
-	for i, xi := range x {
-		if xi != y[i] {
-			return false
-		}
-	}
-	return true
-}
-
-func mprof_GC() {
-	for b := mbuckets; b != nil; b = b.allnext {
-		mp := b.mp()
-		mp.allocs += mp.prev_allocs
-		mp.frees += mp.prev_frees
-		mp.alloc_bytes += mp.prev_alloc_bytes
-		mp.free_bytes += mp.prev_free_bytes
-
-		mp.prev_allocs = mp.recent_allocs
-		mp.prev_frees = mp.recent_frees
-		mp.prev_alloc_bytes = mp.recent_alloc_bytes
-		mp.prev_free_bytes = mp.recent_free_bytes
-
-		mp.recent_allocs = 0
-		mp.recent_frees = 0
-		mp.recent_alloc_bytes = 0
-		mp.recent_free_bytes = 0
-	}
-}
-
-// Record that a gc just happened: all the 'recent' statistics are now real.
-func mProf_GC() {
-	lock(&proflock)
-	mprof_GC()
-	unlock(&proflock)
-}
-
-// Called by malloc to record a profiled block.
-func mProf_Malloc(p unsafe.Pointer, size uintptr) {
-	var stk [maxStack]uintptr
-	nstk := callers(4, &stk[0], len(stk))
-	lock(&proflock)
-	b := stkbucket(memProfile, size, stk[:nstk], true)
-	mp := b.mp()
-	mp.recent_allocs++
-	mp.recent_alloc_bytes += size
-	unlock(&proflock)
-
-	// Setprofilebucket locks a bunch of other mutexes, so we call it outside of proflock.
-	// This reduces potential contention and chances of deadlocks.
-	// Since the object must be alive during call to mProf_Malloc,
-	// it's fine to do this non-atomically.
-	setprofilebucket(p, b)
-}
-
-func setprofilebucket_m() // mheap.c
-
-func setprofilebucket(p unsafe.Pointer, b *bucket) {
-	g := getg()
-	g.m.ptrarg[0] = p
-	g.m.ptrarg[1] = unsafe.Pointer(b)
-	onM(setprofilebucket_m)
-}
-
-// Called when freeing a profiled block.
-func mProf_Free(b *bucket, size uintptr, freed bool) {
-	lock(&proflock)
-	mp := b.mp()
-	if freed {
-		mp.recent_frees++
-		mp.recent_free_bytes += size
-	} else {
-		mp.prev_frees++
-		mp.prev_free_bytes += size
-	}
-	unlock(&proflock)
-}
-
-var blockprofilerate uint64 // in CPU ticks
-
-// SetBlockProfileRate controls the fraction of goroutine blocking events
-// that are reported in the blocking profile.  The profiler aims to sample
-// an average of one blocking event per rate nanoseconds spent blocked.
-//
-// To include every blocking event in the profile, pass rate = 1.
-// To turn off profiling entirely, pass rate <= 0.
-func SetBlockProfileRate(rate int) {
-	var r int64
-	if rate <= 0 {
-		r = 0 // disable profiling
-	} else if rate == 1 {
-		r = 1 // profile everything
-	} else {
-		// convert ns to cycles, use float64 to prevent overflow during multiplication
-		r = int64(float64(rate) * float64(tickspersecond()) / (1000 * 1000 * 1000))
-		if r == 0 {
-			r = 1
-		}
-	}
-
-	atomicstore64(&blockprofilerate, uint64(r))
-}
-
-func blockevent(cycles int64, skip int) {
-	if cycles <= 0 {
-		cycles = 1
-	}
-	rate := int64(atomicload64(&blockprofilerate))
-	if rate <= 0 || (rate > cycles && int64(fastrand1())%rate > cycles) {
-		return
-	}
-	gp := getg()
-	var nstk int
-	var stk [maxStack]uintptr
-	if gp.m.curg == nil || gp.m.curg == gp {
-		nstk = callers(skip, &stk[0], len(stk))
-	} else {
-		nstk = gcallers(gp.m.curg, skip, &stk[0], len(stk))
-	}
-	lock(&proflock)
-	b := stkbucket(blockProfile, 0, stk[:nstk], true)
-	b.bp().count++
-	b.bp().cycles += cycles
-	unlock(&proflock)
-}
-
-// Go interface to profile data.
-
-// A StackRecord describes a single execution stack.
-type StackRecord struct {
-	Stack0 [32]uintptr // stack trace for this record; ends at first 0 entry
-}
-
-// Stack returns the stack trace associated with the record,
-// a prefix of r.Stack0.
-func (r *StackRecord) Stack() []uintptr {
-	for i, v := range r.Stack0 {
-		if v == 0 {
-			return r.Stack0[0:i]
-		}
-	}
-	return r.Stack0[0:]
-}
-
-// MemProfileRate controls the fraction of memory allocations
-// that are recorded and reported in the memory profile.
-// The profiler aims to sample an average of
-// one allocation per MemProfileRate bytes allocated.
-//
-// To include every allocated block in the profile, set MemProfileRate to 1.
-// To turn off profiling entirely, set MemProfileRate to 0.
-//
-// The tools that process the memory profiles assume that the
-// profile rate is constant across the lifetime of the program
-// and equal to the current value.  Programs that change the
-// memory profiling rate should do so just once, as early as
-// possible in the execution of the program (for example,
-// at the beginning of main).
-var MemProfileRate int = 512 * 1024
-
-// A MemProfileRecord describes the live objects allocated
-// by a particular call sequence (stack trace).
-type MemProfileRecord struct {
-	AllocBytes, FreeBytes     int64       // number of bytes allocated, freed
-	AllocObjects, FreeObjects int64       // number of objects allocated, freed
-	Stack0                    [32]uintptr // stack trace for this record; ends at first 0 entry
-}
-
-// InUseBytes returns the number of bytes in use (AllocBytes - FreeBytes).
-func (r *MemProfileRecord) InUseBytes() int64 { return r.AllocBytes - r.FreeBytes }
-
-// InUseObjects returns the number of objects in use (AllocObjects - FreeObjects).
-func (r *MemProfileRecord) InUseObjects() int64 {
-	return r.AllocObjects - r.FreeObjects
-}
-
-// Stack returns the stack trace associated with the record,
-// a prefix of r.Stack0.
-func (r *MemProfileRecord) Stack() []uintptr {
-	for i, v := range r.Stack0 {
-		if v == 0 {
-			return r.Stack0[0:i]
-		}
-	}
-	return r.Stack0[0:]
-}
-
-// MemProfile returns n, the number of records in the current memory profile.
-// If len(p) >= n, MemProfile copies the profile into p and returns n, true.
-// If len(p) < n, MemProfile does not change p and returns n, false.
-//
-// If inuseZero is true, the profile includes allocation records
-// where r.AllocBytes > 0 but r.AllocBytes == r.FreeBytes.
-// These are sites where memory was allocated, but it has all
-// been released back to the runtime.
-//
-// Most clients should use the runtime/pprof package or
-// the testing package's -test.memprofile flag instead
-// of calling MemProfile directly.
-func MemProfile(p []MemProfileRecord, inuseZero bool) (n int, ok bool) {
-	lock(&proflock)
-	clear := true
-	for b := mbuckets; b != nil; b = b.allnext {
-		mp := b.mp()
-		if inuseZero || mp.alloc_bytes != mp.free_bytes {
-			n++
-		}
-		if mp.allocs != 0 || mp.frees != 0 {
-			clear = false
-		}
-	}
-	if clear {
-		// Absolutely no data, suggesting that a garbage collection
-		// has not yet happened. In order to allow profiling when
-		// garbage collection is disabled from the beginning of execution,
-		// accumulate stats as if a GC just happened, and recount buckets.
-		mprof_GC()
-		mprof_GC()
-		n = 0
-		for b := mbuckets; b != nil; b = b.allnext {
-			mp := b.mp()
-			if inuseZero || mp.alloc_bytes != mp.free_bytes {
-				n++
-			}
-		}
-	}
-	if n <= len(p) {
-		ok = true
-		idx := 0
-		for b := mbuckets; b != nil; b = b.allnext {
-			mp := b.mp()
-			if inuseZero || mp.alloc_bytes != mp.free_bytes {
-				record(&p[idx], b)
-				idx++
-			}
-		}
-	}
-	unlock(&proflock)
-	return
-}
-
-// Write b's data to r.
-func record(r *MemProfileRecord, b *bucket) {
-	mp := b.mp()
-	r.AllocBytes = int64(mp.alloc_bytes)
-	r.FreeBytes = int64(mp.free_bytes)
-	r.AllocObjects = int64(mp.allocs)
-	r.FreeObjects = int64(mp.frees)
-	copy(r.Stack0[:], b.stk())
-	for i := int(b.nstk); i < len(r.Stack0); i++ {
-		r.Stack0[i] = 0
-	}
-}
-
-func iterate_memprof(fn func(*bucket, uintptr, *uintptr, uintptr, uintptr, uintptr)) {
-	lock(&proflock)
-	for b := mbuckets; b != nil; b = b.allnext {
-		mp := b.mp()
-		fn(b, uintptr(b.nstk), &b.stk()[0], b.size, mp.allocs, mp.frees)
-	}
-	unlock(&proflock)
-}
-
-// BlockProfileRecord describes blocking events originated
-// at a particular call sequence (stack trace).
-type BlockProfileRecord struct {
-	Count  int64
-	Cycles int64
-	StackRecord
-}
-
-// BlockProfile returns n, the number of records in the current blocking profile.
-// If len(p) >= n, BlockProfile copies the profile into p and returns n, true.
-// If len(p) < n, BlockProfile does not change p and returns n, false.
-//
-// Most clients should use the runtime/pprof package or
-// the testing package's -test.blockprofile flag instead
-// of calling BlockProfile directly.
-func BlockProfile(p []BlockProfileRecord) (n int, ok bool) {
-	lock(&proflock)
-	for b := bbuckets; b != nil; b = b.allnext {
-		n++
-	}
-	if n <= len(p) {
-		ok = true
-		for b := bbuckets; b != nil; b = b.allnext {
-			bp := b.bp()
-			r := &p[0]
-			r.Count = int64(bp.count)
-			r.Cycles = int64(bp.cycles)
-			i := copy(r.Stack0[:], b.stk())
-			for ; i < len(r.Stack0); i++ {
-				r.Stack0[i] = 0
-			}
-			p = p[1:]
-		}
-	}
-	unlock(&proflock)
-	return
-}
-
-// ThreadCreateProfile returns n, the number of records in the thread creation profile.
-// If len(p) >= n, ThreadCreateProfile copies the profile into p and returns n, true.
-// If len(p) < n, ThreadCreateProfile does not change p and returns n, false.
-//
-// Most clients should use the runtime/pprof package instead
-// of calling ThreadCreateProfile directly.
-func ThreadCreateProfile(p []StackRecord) (n int, ok bool) {
-	first := (*m)(atomicloadp(unsafe.Pointer(&allm)))
-	for mp := first; mp != nil; mp = mp.alllink {
-		n++
-	}
-	if n <= len(p) {
-		ok = true
-		i := 0
-		for mp := first; mp != nil; mp = mp.alllink {
-			for s := range mp.createstack {
-				p[i].Stack0[s] = uintptr(mp.createstack[s])
-			}
-			i++
-		}
-	}
-	return
-}
-
-var allgs []*g // proc.c
-
-// GoroutineProfile returns n, the number of records in the active goroutine stack profile.
-// If len(p) >= n, GoroutineProfile copies the profile into p and returns n, true.
-// If len(p) < n, GoroutineProfile does not change p and returns n, false.
-//
-// Most clients should use the runtime/pprof package instead
-// of calling GoroutineProfile directly.
-func GoroutineProfile(p []StackRecord) (n int, ok bool) {
-
-	n = NumGoroutine()
-	if n <= len(p) {
-		gp := getg()
-		semacquire(&worldsema, false)
-		gp.m.gcing = 1
-		onM(stoptheworld)
-
-		n = NumGoroutine()
-		if n <= len(p) {
-			ok = true
-			r := p
-			sp := getcallersp(unsafe.Pointer(&p))
-			pc := getcallerpc(unsafe.Pointer(&p))
-			onM(func() {
-				saveg(pc, sp, gp, &r[0])
-			})
-			r = r[1:]
-			for _, gp1 := range allgs {
-				if gp1 == gp || readgstatus(gp1) == _Gdead {
-					continue
-				}
-				saveg(^uintptr(0), ^uintptr(0), gp1, &r[0])
-				r = r[1:]
-			}
-		}
-
-		gp.m.gcing = 0
-		semrelease(&worldsema)
-		onM(starttheworld)
-	}
-
-	return n, ok
-}
-
-func saveg(pc, sp uintptr, gp *g, r *StackRecord) {
-	n := gentraceback(pc, sp, 0, gp, 0, &r.Stack0[0], len(r.Stack0), nil, nil, 0)
-	if n < len(r.Stack0) {
-		r.Stack0[n] = 0
-	}
-}
-
-// Stack formats a stack trace of the calling goroutine into buf
-// and returns the number of bytes written to buf.
-// If all is true, Stack formats stack traces of all other goroutines
-// into buf after the trace for the current goroutine.
-func Stack(buf []byte, all bool) int {
-	if all {
-		semacquire(&worldsema, false)
-		gp := getg()
-		gp.m.gcing = 1
-		onM(stoptheworld)
-	}
-
-	n := 0
-	if len(buf) > 0 {
-		gp := getg()
-		sp := getcallersp(unsafe.Pointer(&buf))
-		pc := getcallerpc(unsafe.Pointer(&buf))
-		onM(func() {
-			g0 := getg()
-			g0.writebuf = buf[0:0:len(buf)]
-			goroutineheader(gp)
-			traceback(pc, sp, 0, gp)
-			if all {
-				tracebackothers(gp)
-			}
-			n = len(g0.writebuf)
-			g0.writebuf = nil
-		})
-	}
-
-	if all {
-		gp := getg()
-		gp.m.gcing = 0
-		semrelease(&worldsema)
-		onM(starttheworld)
-	}
-	return n
-}
-
-// Tracing of alloc/free/gc.
-
-var tracelock mutex
-
-func tracealloc(p unsafe.Pointer, size uintptr, typ *_type) {
-	lock(&tracelock)
-	gp := getg()
-	gp.m.traceback = 2
-	if typ == nil {
-		print("tracealloc(", p, ", ", hex(size), ")\n")
-	} else {
-		print("tracealloc(", p, ", ", hex(size), ", ", *typ._string, ")\n")
-	}
-	if gp.m.curg == nil || gp == gp.m.curg {
-		goroutineheader(gp)
-		pc := getcallerpc(unsafe.Pointer(&p))
-		sp := getcallersp(unsafe.Pointer(&p))
-		onM(func() {
-			traceback(pc, sp, 0, gp)
-		})
-	} else {
-		goroutineheader(gp.m.curg)
-		traceback(^uintptr(0), ^uintptr(0), 0, gp.m.curg)
-	}
-	print("\n")
-	gp.m.traceback = 0
-	unlock(&tracelock)
-}
-
-func tracefree(p unsafe.Pointer, size uintptr) {
-	lock(&tracelock)
-	gp := getg()
-	gp.m.traceback = 2
-	print("tracefree(", p, ", ", hex(size), ")\n")
-	goroutineheader(gp)
-	pc := getcallerpc(unsafe.Pointer(&p))
-	sp := getcallersp(unsafe.Pointer(&p))
-	onM(func() {
-		traceback(pc, sp, 0, gp)
-	})
-	print("\n")
-	gp.m.traceback = 0
-	unlock(&tracelock)
-}
-
-func tracegc() {
-	lock(&tracelock)
-	gp := getg()
-	gp.m.traceback = 2
-	print("tracegc()\n")
-	// running on m->g0 stack; show all non-g0 goroutines
-	tracebackothers(gp)
-	print("end tracegc\n")
-	print("\n")
-	gp.m.traceback = 0
-	unlock(&tracelock)
-}
diff --git a/third_party/gofrontend/libgo/go/runtime/netpoll.go b/third_party/gofrontend/libgo/go/runtime/netpoll.go
deleted file mode 100644
index 3456e02..0000000
--- a/third_party/gofrontend/libgo/go/runtime/netpoll.go
+++ /dev/null
@@ -1,455 +0,0 @@
-// Copyright 2013 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 darwin dragonfly freebsd linux nacl netbsd openbsd solaris windows
-
-package runtime
-
-import "unsafe"
-
-// Integrated network poller (platform-independent part).
-// A particular implementation (epoll/kqueue) must define the following functions:
-// func netpollinit()			// to initialize the poller
-// func netpollopen(fd uintptr, pd *pollDesc) int32	// to arm edge-triggered notifications
-// and associate fd with pd.
-// An implementation must call the following function to denote that the pd is ready.
-// func netpollready(gpp **g, pd *pollDesc, mode int32)
-
-// pollDesc contains 2 binary semaphores, rg and wg, to park reader and writer
-// goroutines respectively. The semaphore can be in the following states:
-// pdReady - io readiness notification is pending;
-//           a goroutine consumes the notification by changing the state to nil.
-// pdWait - a goroutine prepares to park on the semaphore, but not yet parked;
-//          the goroutine commits to park by changing the state to G pointer,
-//          or, alternatively, concurrent io notification changes the state to READY,
-//          or, alternatively, concurrent timeout/close changes the state to nil.
-// G pointer - the goroutine is blocked on the semaphore;
-//             io notification or timeout/close changes the state to READY or nil respectively
-//             and unparks the goroutine.
-// nil - nothing of the above.
-const (
-	pdReady uintptr = 1
-	pdWait  uintptr = 2
-)
-
-const pollBlockSize = 4 * 1024
-
-// Network poller descriptor.
-type pollDesc struct {
-	link *pollDesc // in pollcache, protected by pollcache.lock
-
-	// The lock protects pollOpen, pollSetDeadline, pollUnblock and deadlineimpl operations.
-	// This fully covers seq, rt and wt variables. fd is constant throughout the PollDesc lifetime.
-	// pollReset, pollWait, pollWaitCanceled and runtime·netpollready (IO readiness notification)
-	// proceed w/o taking the lock. So closing, rg, rd, wg and wd are manipulated
-	// in a lock-free way by all operations.
-	// NOTE(dvyukov): the following code uses uintptr to store *g (rg/wg),
-	// that will blow up when GC starts moving objects.
-	lock    mutex // protectes the following fields
-	fd      uintptr
-	closing bool
-	seq     uintptr        // protects from stale timers and ready notifications
-	rg      uintptr        // pdReady, pdWait, G waiting for read or nil
-	rt      timer          // read deadline timer (set if rt.f != nil)
-	rd      int64          // read deadline
-	wg      uintptr        // pdReady, pdWait, G waiting for write or nil
-	wt      timer          // write deadline timer
-	wd      int64          // write deadline
-	user    unsafe.Pointer // user settable cookie
-}
-
-type pollCache struct {
-	lock  mutex
-	first *pollDesc
-	// PollDesc objects must be type-stable,
-	// because we can get ready notification from epoll/kqueue
-	// after the descriptor is closed/reused.
-	// Stale notifications are detected using seq variable,
-	// seq is incremented when deadlines are changed or descriptor is reused.
-}
-
-var pollcache pollCache
-
-func netpollServerInit() {
-	onM(netpollinit)
-}
-
-func netpollOpen(fd uintptr) (*pollDesc, int) {
-	pd := pollcache.alloc()
-	lock(&pd.lock)
-	if pd.wg != 0 && pd.wg != pdReady {
-		gothrow("netpollOpen: blocked write on free descriptor")
-	}
-	if pd.rg != 0 && pd.rg != pdReady {
-		gothrow("netpollOpen: blocked read on free descriptor")
-	}
-	pd.fd = fd
-	pd.closing = false
-	pd.seq++
-	pd.rg = 0
-	pd.rd = 0
-	pd.wg = 0
-	pd.wd = 0
-	unlock(&pd.lock)
-
-	var errno int32
-	onM(func() {
-		errno = netpollopen(fd, pd)
-	})
-	return pd, int(errno)
-}
-
-func netpollClose(pd *pollDesc) {
-	if !pd.closing {
-		gothrow("netpollClose: close w/o unblock")
-	}
-	if pd.wg != 0 && pd.wg != pdReady {
-		gothrow("netpollClose: blocked write on closing descriptor")
-	}
-	if pd.rg != 0 && pd.rg != pdReady {
-		gothrow("netpollClose: blocked read on closing descriptor")
-	}
-	onM(func() {
-		netpollclose(uintptr(pd.fd))
-	})
-	pollcache.free(pd)
-}
-
-func (c *pollCache) free(pd *pollDesc) {
-	lock(&c.lock)
-	pd.link = c.first
-	c.first = pd
-	unlock(&c.lock)
-}
-
-func netpollReset(pd *pollDesc, mode int) int {
-	err := netpollcheckerr(pd, int32(mode))
-	if err != 0 {
-		return err
-	}
-	if mode == 'r' {
-		pd.rg = 0
-	} else if mode == 'w' {
-		pd.wg = 0
-	}
-	return 0
-}
-
-func netpollWait(pd *pollDesc, mode int) int {
-	err := netpollcheckerr(pd, int32(mode))
-	if err != 0 {
-		return err
-	}
-	// As for now only Solaris uses level-triggered IO.
-	if GOOS == "solaris" {
-		onM(func() {
-			netpollarm(pd, mode)
-		})
-	}
-	for !netpollblock(pd, int32(mode), false) {
-		err = netpollcheckerr(pd, int32(mode))
-		if err != 0 {
-			return err
-		}
-		// Can happen if timeout has fired and unblocked us,
-		// but before we had a chance to run, timeout has been reset.
-		// Pretend it has not happened and retry.
-	}
-	return 0
-}
-
-func netpollWaitCanceled(pd *pollDesc, mode int) {
-	// This function is used only on windows after a failed attempt to cancel
-	// a pending async IO operation. Wait for ioready, ignore closing or timeouts.
-	for !netpollblock(pd, int32(mode), true) {
-	}
-}
-
-func netpollSetDeadline(pd *pollDesc, d int64, mode int) {
-	lock(&pd.lock)
-	if pd.closing {
-		unlock(&pd.lock)
-		return
-	}
-	pd.seq++ // invalidate current timers
-	// Reset current timers.
-	if pd.rt.f != nil {
-		deltimer(&pd.rt)
-		pd.rt.f = nil
-	}
-	if pd.wt.f != nil {
-		deltimer(&pd.wt)
-		pd.wt.f = nil
-	}
-	// Setup new timers.
-	if d != 0 && d <= nanotime() {
-		d = -1
-	}
-	if mode == 'r' || mode == 'r'+'w' {
-		pd.rd = d
-	}
-	if mode == 'w' || mode == 'r'+'w' {
-		pd.wd = d
-	}
-	if pd.rd > 0 && pd.rd == pd.wd {
-		pd.rt.f = netpollDeadline
-		pd.rt.when = pd.rd
-		// Copy current seq into the timer arg.
-		// Timer func will check the seq against current descriptor seq,
-		// if they differ the descriptor was reused or timers were reset.
-		pd.rt.arg = pd
-		pd.rt.seq = pd.seq
-		addtimer(&pd.rt)
-	} else {
-		if pd.rd > 0 {
-			pd.rt.f = netpollReadDeadline
-			pd.rt.when = pd.rd
-			pd.rt.arg = pd
-			pd.rt.seq = pd.seq
-			addtimer(&pd.rt)
-		}
-		if pd.wd > 0 {
-			pd.wt.f = netpollWriteDeadline
-			pd.wt.when = pd.wd
-			pd.wt.arg = pd
-			pd.wt.seq = pd.seq
-			addtimer(&pd.wt)
-		}
-	}
-	// If we set the new deadline in the past, unblock currently pending IO if any.
-	var rg, wg *g
-	atomicstorep(unsafe.Pointer(&wg), nil) // full memory barrier between stores to rd/wd and load of rg/wg in netpollunblock
-	if pd.rd < 0 {
-		rg = netpollunblock(pd, 'r', false)
-	}
-	if pd.wd < 0 {
-		wg = netpollunblock(pd, 'w', false)
-	}
-	unlock(&pd.lock)
-	if rg != nil {
-		goready(rg)
-	}
-	if wg != nil {
-		goready(wg)
-	}
-}
-
-func netpollUnblock(pd *pollDesc) {
-	lock(&pd.lock)
-	if pd.closing {
-		gothrow("netpollUnblock: already closing")
-	}
-	pd.closing = true
-	pd.seq++
-	var rg, wg *g
-	atomicstorep(unsafe.Pointer(&rg), nil) // full memory barrier between store to closing and read of rg/wg in netpollunblock
-	rg = netpollunblock(pd, 'r', false)
-	wg = netpollunblock(pd, 'w', false)
-	if pd.rt.f != nil {
-		deltimer(&pd.rt)
-		pd.rt.f = nil
-	}
-	if pd.wt.f != nil {
-		deltimer(&pd.wt)
-		pd.wt.f = nil
-	}
-	unlock(&pd.lock)
-	if rg != nil {
-		goready(rg)
-	}
-	if wg != nil {
-		goready(wg)
-	}
-}
-
-func netpollfd(pd *pollDesc) uintptr {
-	return pd.fd
-}
-
-func netpolluser(pd *pollDesc) *unsafe.Pointer {
-	return &pd.user
-}
-
-func netpollclosing(pd *pollDesc) bool {
-	return pd.closing
-}
-
-func netpolllock(pd *pollDesc) {
-	lock(&pd.lock)
-}
-
-func netpollunlock(pd *pollDesc) {
-	unlock(&pd.lock)
-}
-
-// make pd ready, newly runnable goroutines (if any) are returned in rg/wg
-func netpollready(gpp **g, pd *pollDesc, mode int32) {
-	var rg, wg *g
-	if mode == 'r' || mode == 'r'+'w' {
-		rg = netpollunblock(pd, 'r', true)
-	}
-	if mode == 'w' || mode == 'r'+'w' {
-		wg = netpollunblock(pd, 'w', true)
-	}
-	if rg != nil {
-		rg.schedlink = *gpp
-		*gpp = rg
-	}
-	if wg != nil {
-		wg.schedlink = *gpp
-		*gpp = wg
-	}
-}
-
-func netpollcheckerr(pd *pollDesc, mode int32) int {
-	if pd.closing {
-		return 1 // errClosing
-	}
-	if (mode == 'r' && pd.rd < 0) || (mode == 'w' && pd.wd < 0) {
-		return 2 // errTimeout
-	}
-	return 0
-}
-
-func netpollblockcommit(gp *g, gpp unsafe.Pointer) bool {
-	return casuintptr((*uintptr)(gpp), pdWait, uintptr(unsafe.Pointer(gp)))
-}
-
-// returns true if IO is ready, or false if timedout or closed
-// waitio - wait only for completed IO, ignore errors
-func netpollblock(pd *pollDesc, mode int32, waitio bool) bool {
-	gpp := &pd.rg
-	if mode == 'w' {
-		gpp = &pd.wg
-	}
-
-	// set the gpp semaphore to WAIT
-	for {
-		old := *gpp
-		if old == pdReady {
-			*gpp = 0
-			return true
-		}
-		if old != 0 {
-			gothrow("netpollblock: double wait")
-		}
-		if casuintptr(gpp, 0, pdWait) {
-			break
-		}
-	}
-
-	// need to recheck error states after setting gpp to WAIT
-	// this is necessary because runtime_pollUnblock/runtime_pollSetDeadline/deadlineimpl
-	// do the opposite: store to closing/rd/wd, membarrier, load of rg/wg
-	if waitio || netpollcheckerr(pd, mode) == 0 {
-		f := netpollblockcommit
-		gopark(**(**unsafe.Pointer)(unsafe.Pointer(&f)), unsafe.Pointer(gpp), "IO wait")
-	}
-	// be careful to not lose concurrent READY notification
-	old := xchguintptr(gpp, 0)
-	if old > pdWait {
-		gothrow("netpollblock: corrupted state")
-	}
-	return old == pdReady
-}
-
-func netpollunblock(pd *pollDesc, mode int32, ioready bool) *g {
-	gpp := &pd.rg
-	if mode == 'w' {
-		gpp = &pd.wg
-	}
-
-	for {
-		old := *gpp
-		if old == pdReady {
-			return nil
-		}
-		if old == 0 && !ioready {
-			// Only set READY for ioready. runtime_pollWait
-			// will check for timeout/cancel before waiting.
-			return nil
-		}
-		var new uintptr
-		if ioready {
-			new = pdReady
-		}
-		if casuintptr(gpp, old, new) {
-			if old == pdReady || old == pdWait {
-				old = 0
-			}
-			return (*g)(unsafe.Pointer(old))
-		}
-	}
-}
-
-func netpolldeadlineimpl(pd *pollDesc, seq uintptr, read, write bool) {
-	lock(&pd.lock)
-	// Seq arg is seq when the timer was set.
-	// If it's stale, ignore the timer event.
-	if seq != pd.seq {
-		// The descriptor was reused or timers were reset.
-		unlock(&pd.lock)
-		return
-	}
-	var rg *g
-	if read {
-		if pd.rd <= 0 || pd.rt.f == nil {
-			gothrow("netpolldeadlineimpl: inconsistent read deadline")
-		}
-		pd.rd = -1
-		atomicstorep(unsafe.Pointer(&pd.rt.f), nil) // full memory barrier between store to rd and load of rg in netpollunblock
-		rg = netpollunblock(pd, 'r', false)
-	}
-	var wg *g
-	if write {
-		if pd.wd <= 0 || pd.wt.f == nil && !read {
-			gothrow("netpolldeadlineimpl: inconsistent write deadline")
-		}
-		pd.wd = -1
-		atomicstorep(unsafe.Pointer(&pd.wt.f), nil) // full memory barrier between store to wd and load of wg in netpollunblock
-		wg = netpollunblock(pd, 'w', false)
-	}
-	unlock(&pd.lock)
-	if rg != nil {
-		goready(rg)
-	}
-	if wg != nil {
-		goready(wg)
-	}
-}
-
-func netpollDeadline(arg interface{}, seq uintptr) {
-	netpolldeadlineimpl(arg.(*pollDesc), seq, true, true)
-}
-
-func netpollReadDeadline(arg interface{}, seq uintptr) {
-	netpolldeadlineimpl(arg.(*pollDesc), seq, true, false)
-}
-
-func netpollWriteDeadline(arg interface{}, seq uintptr) {
-	netpolldeadlineimpl(arg.(*pollDesc), seq, false, true)
-}
-
-func (c *pollCache) alloc() *pollDesc {
-	lock(&c.lock)
-	if c.first == nil {
-		const pdSize = unsafe.Sizeof(pollDesc{})
-		n := pollBlockSize / pdSize
-		if n == 0 {
-			n = 1
-		}
-		// Must be in non-GC memory because can be referenced
-		// only from epoll/kqueue internals.
-		mem := persistentalloc(n*pdSize, 0, &memstats.other_sys)
-		for i := uintptr(0); i < n; i++ {
-			pd := (*pollDesc)(add(mem, i*pdSize))
-			pd.link = c.first
-			c.first = pd
-		}
-	}
-	pd := c.first
-	c.first = pd.link
-	unlock(&c.lock)
-	return pd
-}
diff --git a/third_party/gofrontend/libgo/go/runtime/netpoll_epoll.go b/third_party/gofrontend/libgo/go/runtime/netpoll_epoll.go
deleted file mode 100644
index ecfc9cd..0000000
--- a/third_party/gofrontend/libgo/go/runtime/netpoll_epoll.go
+++ /dev/null
@@ -1,97 +0,0 @@
-// Copyright 2013 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 linux
-
-package runtime
-
-import "unsafe"
-
-func epollcreate(size int32) int32
-func epollcreate1(flags int32) int32
-
-//go:noescape
-func epollctl(epfd, op, fd int32, ev *epollevent) int32
-
-//go:noescape
-func epollwait(epfd int32, ev *epollevent, nev, timeout int32) int32
-func closeonexec(fd int32)
-
-var (
-	epfd           int32 = -1 // epoll descriptor
-	netpolllasterr int32
-)
-
-func netpollinit() {
-	epfd = epollcreate1(_EPOLL_CLOEXEC)
-	if epfd >= 0 {
-		return
-	}
-	epfd = epollcreate(1024)
-	if epfd >= 0 {
-		closeonexec(epfd)
-		return
-	}
-	println("netpollinit: failed to create epoll descriptor", -epfd)
-	gothrow("netpollinit: failed to create descriptor")
-}
-
-func netpollopen(fd uintptr, pd *pollDesc) int32 {
-	var ev epollevent
-	ev.events = _EPOLLIN | _EPOLLOUT | _EPOLLRDHUP | _EPOLLET
-	*(**pollDesc)(unsafe.Pointer(&ev.data)) = pd
-	return -epollctl(epfd, _EPOLL_CTL_ADD, int32(fd), &ev)
-}
-
-func netpollclose(fd uintptr) int32 {
-	var ev epollevent
-	return -epollctl(epfd, _EPOLL_CTL_DEL, int32(fd), &ev)
-}
-
-func netpollarm(pd *pollDesc, mode int) {
-	gothrow("unused")
-}
-
-// polls for ready network connections
-// returns list of goroutines that become runnable
-func netpoll(block bool) (gp *g) {
-	if epfd == -1 {
-		return
-	}
-	waitms := int32(-1)
-	if !block {
-		waitms = 0
-	}
-	var events [128]epollevent
-retry:
-	n := epollwait(epfd, &events[0], int32(len(events)), waitms)
-	if n < 0 {
-		if n != -_EINTR && n != netpolllasterr {
-			netpolllasterr = n
-			println("runtime: epollwait on fd", epfd, "failed with", -n)
-		}
-		goto retry
-	}
-	for i := int32(0); i < n; i++ {
-		ev := &events[i]
-		if ev.events == 0 {
-			continue
-		}
-		var mode int32
-		if ev.events&(_EPOLLIN|_EPOLLRDHUP|_EPOLLHUP|_EPOLLERR) != 0 {
-			mode += 'r'
-		}
-		if ev.events&(_EPOLLOUT|_EPOLLHUP|_EPOLLERR) != 0 {
-			mode += 'w'
-		}
-		if mode != 0 {
-			pd := *(**pollDesc)(unsafe.Pointer(&ev.data))
-			netpollready((**g)(noescape(unsafe.Pointer(&gp))), pd, mode)
-		}
-	}
-	if block && gp == nil {
-		goto retry
-	}
-	return gp
-}
diff --git a/third_party/gofrontend/libgo/go/runtime/netpoll_kqueue.go b/third_party/gofrontend/libgo/go/runtime/netpoll_kqueue.go
deleted file mode 100644
index d6d55b9..0000000
--- a/third_party/gofrontend/libgo/go/runtime/netpoll_kqueue.go
+++ /dev/null
@@ -1,101 +0,0 @@
-// Copyright 2013 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 darwin dragonfly freebsd netbsd openbsd
-
-package runtime
-
-// Integrated network poller (kqueue-based implementation).
-
-import "unsafe"
-
-func kqueue() int32
-
-//go:noescape
-func kevent(kq int32, ch *keventt, nch int32, ev *keventt, nev int32, ts *timespec) int32
-func closeonexec(fd int32)
-
-var (
-	kq             int32 = -1
-	netpolllasterr int32
-)
-
-func netpollinit() {
-	kq = kqueue()
-	if kq < 0 {
-		println("netpollinit: kqueue failed with", -kq)
-		gothrow("netpollinit: kqueue failed")
-	}
-	closeonexec(kq)
-}
-
-func netpollopen(fd uintptr, pd *pollDesc) int32 {
-	// Arm both EVFILT_READ and EVFILT_WRITE in edge-triggered mode (EV_CLEAR)
-	// for the whole fd lifetime.  The notifications are automatically unregistered
-	// when fd is closed.
-	var ev [2]keventt
-	*(*uintptr)(unsafe.Pointer(&ev[0].ident)) = fd
-	ev[0].filter = _EVFILT_READ
-	ev[0].flags = _EV_ADD | _EV_CLEAR
-	ev[0].fflags = 0
-	ev[0].data = 0
-	ev[0].udata = (*byte)(unsafe.Pointer(pd))
-	ev[1] = ev[0]
-	ev[1].filter = _EVFILT_WRITE
-	n := kevent(kq, &ev[0], 2, nil, 0, nil)
-	if n < 0 {
-		return -n
-	}
-	return 0
-}
-
-func netpollclose(fd uintptr) int32 {
-	// Don't need to unregister because calling close()
-	// on fd will remove any kevents that reference the descriptor.
-	return 0
-}
-
-func netpollarm(pd *pollDesc, mode int) {
-	gothrow("unused")
-}
-
-// Polls for ready network connections.
-// Returns list of goroutines that become runnable.
-func netpoll(block bool) (gp *g) {
-	if kq == -1 {
-		return
-	}
-	var tp *timespec
-	var ts timespec
-	if !block {
-		tp = &ts
-	}
-	var events [64]keventt
-retry:
-	n := kevent(kq, nil, 0, &events[0], int32(len(events)), tp)
-	if n < 0 {
-		if n != -_EINTR && n != netpolllasterr {
-			netpolllasterr = n
-			println("runtime: kevent on fd", kq, "failed with", -n)
-		}
-		goto retry
-	}
-	for i := 0; i < int(n); i++ {
-		ev := &events[i]
-		var mode int32
-		if ev.filter == _EVFILT_READ {
-			mode += 'r'
-		}
-		if ev.filter == _EVFILT_WRITE {
-			mode += 'w'
-		}
-		if mode != 0 {
-			netpollready((**g)(noescape(unsafe.Pointer(&gp))), (*pollDesc)(unsafe.Pointer(ev.udata)), mode)
-		}
-	}
-	if block && gp == nil {
-		goto retry
-	}
-	return gp
-}
diff --git a/third_party/gofrontend/libgo/go/runtime/netpoll_nacl.go b/third_party/gofrontend/libgo/go/runtime/netpoll_nacl.go
deleted file mode 100644
index 5cbc300..0000000
--- a/third_party/gofrontend/libgo/go/runtime/netpoll_nacl.go
+++ /dev/null
@@ -1,26 +0,0 @@
-// Copyright 2013 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.
-
-// Fake network poller for NaCl.
-// Should never be used, because NaCl network connections do not honor "SetNonblock".
-
-package runtime
-
-func netpollinit() {
-}
-
-func netpollopen(fd uintptr, pd *pollDesc) int32 {
-	return 0
-}
-
-func netpollclose(fd uintptr) int32 {
-	return 0
-}
-
-func netpollarm(pd *pollDesc, mode int) {
-}
-
-func netpoll(block bool) *g {
-	return nil
-}
diff --git a/third_party/gofrontend/libgo/go/runtime/noasm_arm.go b/third_party/gofrontend/libgo/go/runtime/noasm_arm.go
deleted file mode 100644
index dd3ef82..0000000
--- a/third_party/gofrontend/libgo/go/runtime/noasm_arm.go
+++ /dev/null
@@ -1,54 +0,0 @@
-// Copyright 2013 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.
-
-// Routines that are implemented in assembly in asm_{amd64,386}.s
-// but are implemented in Go for arm.
-
-package runtime
-
-func cmpstring(s1, s2 string) int {
-	l := len(s1)
-	if len(s2) < l {
-		l = len(s2)
-	}
-	for i := 0; i < l; i++ {
-		c1, c2 := s1[i], s2[i]
-		if c1 < c2 {
-			return -1
-		}
-		if c1 > c2 {
-			return +1
-		}
-	}
-	if len(s1) < len(s2) {
-		return -1
-	}
-	if len(s1) > len(s2) {
-		return +1
-	}
-	return 0
-}
-
-func cmpbytes(s1, s2 []byte) int {
-	l := len(s1)
-	if len(s2) < l {
-		l = len(s2)
-	}
-	for i := 0; i < l; i++ {
-		c1, c2 := s1[i], s2[i]
-		if c1 < c2 {
-			return -1
-		}
-		if c1 > c2 {
-			return +1
-		}
-	}
-	if len(s1) < len(s2) {
-		return -1
-	}
-	if len(s1) > len(s2) {
-		return +1
-	}
-	return 0
-}
diff --git a/third_party/gofrontend/libgo/go/runtime/norace_test.go b/third_party/gofrontend/libgo/go/runtime/norace_test.go
index 3b17187..3681bf1 100644
--- a/third_party/gofrontend/libgo/go/runtime/norace_test.go
+++ b/third_party/gofrontend/libgo/go/runtime/norace_test.go
@@ -34,12 +34,12 @@
 	b.RunParallel(func(pb *testing.PB) {
 		foo := 42
 		for pb.Next() {
-			runtime.Entersyscall()
+			runtime.Entersyscall(0)
 			for i := 0; i < work; i++ {
 				foo *= 2
 				foo /= 2
 			}
-			runtime.Exitsyscall()
+			runtime.Exitsyscall(0)
 		}
 		_ = foo
 	})
diff --git a/third_party/gofrontend/libgo/go/runtime/os_darwin.go b/third_party/gofrontend/libgo/go/runtime/os_darwin.go
deleted file mode 100644
index 4327ced..0000000
--- a/third_party/gofrontend/libgo/go/runtime/os_darwin.go
+++ /dev/null
@@ -1,24 +0,0 @@
-// 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.
-
-package runtime
-
-import "unsafe"
-
-func bsdthread_create(stk, mm, gg, fn unsafe.Pointer) int32
-func bsdthread_register() int32
-func mach_msg_trap(h unsafe.Pointer, op int32, send_size, rcv_size, rcv_name, timeout, notify uint32) int32
-func mach_reply_port() uint32
-func mach_task_self() uint32
-func mach_thread_self() uint32
-func sysctl(mib *uint32, miblen uint32, out *byte, size *uintptr, dst *byte, ndst uintptr) int32
-func sigprocmask(sig int32, new, old unsafe.Pointer)
-func sigaction(mode uint32, new, old unsafe.Pointer)
-func sigaltstack(new, old unsafe.Pointer)
-func sigtramp()
-func setitimer(mode int32, new, old unsafe.Pointer)
-func mach_semaphore_wait(sema uint32) int32
-func mach_semaphore_timedwait(sema, sec, nsec uint32) int32
-func mach_semaphore_signal(sema uint32) int32
-func mach_semaphore_signal_all(sema uint32) int32
diff --git a/third_party/gofrontend/libgo/go/runtime/os_dragonfly.go b/third_party/gofrontend/libgo/go/runtime/os_dragonfly.go
deleted file mode 100644
index cdaa069..0000000
--- a/third_party/gofrontend/libgo/go/runtime/os_dragonfly.go
+++ /dev/null
@@ -1,20 +0,0 @@
-// 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.
-
-package runtime
-
-import "unsafe"
-
-func lwp_create(param unsafe.Pointer) int32
-func sigaltstack(new, old unsafe.Pointer)
-func sigaction(sig int32, new, old unsafe.Pointer)
-func sigprocmask(new, old unsafe.Pointer)
-func setitimer(mode int32, new, old unsafe.Pointer)
-func sysctl(mib *uint32, miblen uint32, out *byte, size *uintptr, dst *byte, ndst uintptr) int32
-func getrlimit(kind int32, limit unsafe.Pointer) int32
-func raise(sig int32)
-func sys_umtx_sleep(addr unsafe.Pointer, val, timeout int32) int32
-func sys_umtx_wakeup(addr unsafe.Pointer, val int32) int32
-
-const stackSystem = 0
diff --git a/third_party/gofrontend/libgo/go/runtime/os_freebsd.go b/third_party/gofrontend/libgo/go/runtime/os_freebsd.go
deleted file mode 100644
index 5970804..0000000
--- a/third_party/gofrontend/libgo/go/runtime/os_freebsd.go
+++ /dev/null
@@ -1,17 +0,0 @@
-// 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.
-
-package runtime
-
-import "unsafe"
-
-func thr_new(param unsafe.Pointer, size int32)
-func sigaltstack(new, old unsafe.Pointer)
-func sigaction(sig int32, new, old unsafe.Pointer)
-func sigprocmask(new, old unsafe.Pointer)
-func setitimer(mode int32, new, old unsafe.Pointer)
-func sysctl(mib *uint32, miblen uint32, out *byte, size *uintptr, dst *byte, ndst uintptr) int32
-func getrlimit(kind int32, limit unsafe.Pointer) int32
-func raise(sig int32)
-func sys_umtx_op(addr unsafe.Pointer, mode int32, val uint32, ptr2, ts unsafe.Pointer) int32
diff --git a/third_party/gofrontend/libgo/go/runtime/os_linux.go b/third_party/gofrontend/libgo/go/runtime/os_linux.go
deleted file mode 100644
index 41123ad..0000000
--- a/third_party/gofrontend/libgo/go/runtime/os_linux.go
+++ /dev/null
@@ -1,17 +0,0 @@
-// 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.
-
-package runtime
-
-import "unsafe"
-
-func futex(addr unsafe.Pointer, op int32, val uint32, ts, addr2 unsafe.Pointer, val3 uint32) int32
-func clone(flags int32, stk, mm, gg, fn unsafe.Pointer) int32
-func rt_sigaction(sig uintptr, new, old unsafe.Pointer, size uintptr) int32
-func sigaltstack(new, old unsafe.Pointer)
-func setitimer(mode int32, new, old unsafe.Pointer)
-func rtsigprocmask(sig int32, new, old unsafe.Pointer, size int32)
-func getrlimit(kind int32, limit unsafe.Pointer) int32
-func raise(sig int32)
-func sched_getaffinity(pid, len uintptr, buf *uintptr) int32
diff --git a/third_party/gofrontend/libgo/go/runtime/os_nacl.go b/third_party/gofrontend/libgo/go/runtime/os_nacl.go
deleted file mode 100644
index 8dd43ff..0000000
--- a/third_party/gofrontend/libgo/go/runtime/os_nacl.go
+++ /dev/null
@@ -1,39 +0,0 @@
-// 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.
-
-package runtime
-
-import "unsafe"
-
-func nacl_exception_stack(p unsafe.Pointer, size int32) int32
-func nacl_exception_handler(fn, arg unsafe.Pointer) int32
-func nacl_sem_create(flag int32) int32
-func nacl_sem_wait(sem int32) int32
-func nacl_sem_post(sem int32) int32
-func nacl_mutex_create(flag int32) int32
-func nacl_mutex_lock(mutex int32) int32
-func nacl_mutex_trylock(mutex int32) int32
-func nacl_mutex_unlock(mutex int32) int32
-func nacl_cond_create(flag int32) int32
-func nacl_cond_wait(cond, n int32) int32
-func nacl_cond_signal(cond int32) int32
-func nacl_cond_broadcast(cond int32) int32
-func nacl_cond_timed_wait_abs(cond, lock int32, ts unsafe.Pointer) int32
-func nacl_thread_create(fn, stk, tls, xx unsafe.Pointer) int32
-func nacl_nanosleep(ts, extra unsafe.Pointer) int32
-
-func os_sigpipe() {
-	gothrow("too many writes on closed pipe")
-}
-
-func sigpanic() {
-	g := getg()
-	if !canpanic(g) {
-		gothrow("unexpected signal during runtime execution")
-	}
-
-	// Native Client only invokes the exception handler for memory faults.
-	g.sig = _SIGSEGV
-	panicmem()
-}
diff --git a/third_party/gofrontend/libgo/go/runtime/os_netbsd.go b/third_party/gofrontend/libgo/go/runtime/os_netbsd.go
deleted file mode 100644
index f000c5e..0000000
--- a/third_party/gofrontend/libgo/go/runtime/os_netbsd.go
+++ /dev/null
@@ -1,20 +0,0 @@
-// 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.
-
-package runtime
-
-import "unsafe"
-
-func setitimer(mode int32, new, old unsafe.Pointer)
-func sigaction(sig int32, new, old unsafe.Pointer)
-func sigaltstack(new, old unsafe.Pointer)
-func sigprocmask(mode int32, new, old unsafe.Pointer)
-func sysctl(mib *uint32, miblen uint32, out *byte, size *uintptr, dst *byte, ndst uintptr) int32
-func lwp_tramp()
-func raise(sig int32)
-func getcontext(ctxt unsafe.Pointer)
-func lwp_create(ctxt unsafe.Pointer, flags uintptr, lwpid unsafe.Pointer) int32
-func lwp_park(abstime unsafe.Pointer, unpark int32, hint, unparkhint unsafe.Pointer) int32
-func lwp_unpark(lwp int32, hint unsafe.Pointer) int32
-func lwp_self() int32
diff --git a/third_party/gofrontend/libgo/go/runtime/os_openbsd.go b/third_party/gofrontend/libgo/go/runtime/os_openbsd.go
deleted file mode 100644
index a000f96..0000000
--- a/third_party/gofrontend/libgo/go/runtime/os_openbsd.go
+++ /dev/null
@@ -1,17 +0,0 @@
-// 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.
-
-package runtime
-
-import "unsafe"
-
-func setitimer(mode int32, new, old unsafe.Pointer)
-func sigaction(sig int32, new, old unsafe.Pointer)
-func sigaltstack(new, old unsafe.Pointer)
-func sigprocmask(mode int32, new uint32) uint32
-func sysctl(mib *uint32, miblen uint32, out *byte, size *uintptr, dst *byte, ndst uintptr) int32
-func raise(sig int32)
-func tfork(param unsafe.Pointer, psize uintptr, mm, gg, fn unsafe.Pointer) int32
-func thrsleep(ident unsafe.Pointer, clock_id int32, tsp, lock, abort unsafe.Pointer) int32
-func thrwakeup(ident unsafe.Pointer, n int32) int32
diff --git a/third_party/gofrontend/libgo/go/runtime/os_plan9.go b/third_party/gofrontend/libgo/go/runtime/os_plan9.go
deleted file mode 100644
index 10e5531..0000000
--- a/third_party/gofrontend/libgo/go/runtime/os_plan9.go
+++ /dev/null
@@ -1,105 +0,0 @@
-// 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.
-
-package runtime
-
-import "unsafe"
-
-const _SIGPROF = 0 // dummy value for badsignal
-
-func pread(fd int32, buf unsafe.Pointer, nbytes int32, offset int64) int32
-func pwrite(fd int32, buf unsafe.Pointer, nbytes int32, offset int64) int32
-func seek(fd int32, offset int64, whence int32) int64
-func exits(msg *byte)
-func brk_(addr unsafe.Pointer) uintptr
-func sleep(ms int32) int32
-func rfork(flags int32) int32
-func plan9_semacquire(addr *uint32, block int32) int32
-func plan9_tsemacquire(addr *uint32, ms int32) int32
-func plan9_semrelease(addr *uint32, count int32) int32
-func notify(fn unsafe.Pointer) int32
-func noted(mode int32) int32
-func nsec(*int64) int64
-func sigtramp(ureg, msg unsafe.Pointer)
-func setfpmasks()
-func tstart_plan9(newm *m)
-func errstr() string
-
-type _Plink uintptr
-
-func os_sigpipe() {
-	gothrow("too many writes on closed pipe")
-}
-
-func sigpanic() {
-	g := getg()
-	if !canpanic(g) {
-		gothrow("unexpected signal during runtime execution")
-	}
-
-	note := gostringnocopy((*byte)(unsafe.Pointer(g.m.notesig)))
-	switch g.sig {
-	case _SIGRFAULT, _SIGWFAULT:
-		addr := note[index(note, "addr=")+5:]
-		g.sigcode1 = uintptr(atolwhex(addr))
-		if g.sigcode1 < 0x1000 || g.paniconfault {
-			panicmem()
-		}
-		print("unexpected fault address ", hex(g.sigcode1), "\n")
-		gothrow("fault")
-	case _SIGTRAP:
-		if g.paniconfault {
-			panicmem()
-		}
-		gothrow(note)
-	case _SIGINTDIV:
-		panicdivide()
-	case _SIGFLOAT:
-		panicfloat()
-	default:
-		panic(errorString(note))
-	}
-}
-
-func atolwhex(p string) int64 {
-	for hasprefix(p, " ") || hasprefix(p, "\t") {
-		p = p[1:]
-	}
-	neg := false
-	if hasprefix(p, "-") || hasprefix(p, "+") {
-		neg = p[0] == '-'
-		p = p[1:]
-		for hasprefix(p, " ") || hasprefix(p, "\t") {
-			p = p[1:]
-		}
-	}
-	var n int64
-	switch {
-	case hasprefix(p, "0x"), hasprefix(p, "0X"):
-		p = p[2:]
-		for ; len(p) > 0; p = p[1:] {
-			if '0' <= p[0] && p[0] <= '9' {
-				n = n*16 + int64(p[0]-'0')
-			} else if 'a' <= p[0] && p[0] <= 'f' {
-				n = n*16 + int64(p[0]-'a'+10)
-			} else if 'A' <= p[0] && p[0] <= 'F' {
-				n = n*16 + int64(p[0]-'A'+10)
-			} else {
-				break
-			}
-		}
-	case hasprefix(p, "0"):
-		for ; len(p) > 0 && '0' <= p[0] && p[0] <= '7'; p = p[1:] {
-			n = n*8 + int64(p[0]-'0')
-		}
-	default:
-		for ; len(p) > 0 && '0' <= p[0] && p[0] <= '9'; p = p[1:] {
-			n = n*10 + int64(p[0]-'0')
-		}
-	}
-	if neg {
-		n = -n
-	}
-	return n
-}
diff --git a/third_party/gofrontend/libgo/go/runtime/os_solaris.go b/third_party/gofrontend/libgo/go/runtime/os_solaris.go
deleted file mode 100644
index ca13151..0000000
--- a/third_party/gofrontend/libgo/go/runtime/os_solaris.go
+++ /dev/null
@@ -1,100 +0,0 @@
-// 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.
-
-package runtime
-
-import "unsafe"
-
-func setitimer(mode int32, new, old unsafe.Pointer)
-func sigaction(sig int32, new, old unsafe.Pointer)
-func sigaltstack(new, old unsafe.Pointer)
-func sigprocmask(mode int32, new, old unsafe.Pointer)
-func sysctl(mib *uint32, miblen uint32, out *byte, size *uintptr, dst *byte, ndst uintptr) int32
-func getrlimit(kind int32, limit unsafe.Pointer)
-func miniterrno(fn unsafe.Pointer)
-func raise(sig int32)
-func getcontext(ctxt unsafe.Pointer)
-func tstart_sysvicall(mm unsafe.Pointer) uint32
-func nanotime1() int64
-func usleep1(usec uint32)
-func osyield1()
-func netpollinit()
-func netpollopen(fd uintptr, pd *pollDesc) int32
-func netpollclose(fd uintptr) int32
-func netpollarm(pd *pollDesc, mode int)
-
-type libcFunc byte
-
-var asmsysvicall6 libcFunc
-
-//go:nosplit
-func sysvicall0(fn *libcFunc) uintptr {
-	libcall := &getg().m.libcall
-	libcall.fn = uintptr(unsafe.Pointer(fn))
-	libcall.n = 0
-	// TODO(rsc): Why is noescape necessary here and below?
-	libcall.args = uintptr(noescape(unsafe.Pointer(&fn))) // it's unused but must be non-nil, otherwise crashes
-	asmcgocall(unsafe.Pointer(&asmsysvicall6), unsafe.Pointer(libcall))
-	return libcall.r1
-}
-
-//go:nosplit
-func sysvicall1(fn *libcFunc, a1 uintptr) uintptr {
-	libcall := &getg().m.libcall
-	libcall.fn = uintptr(unsafe.Pointer(fn))
-	libcall.n = 1
-	libcall.args = uintptr(noescape(unsafe.Pointer(&a1)))
-	asmcgocall(unsafe.Pointer(&asmsysvicall6), unsafe.Pointer(libcall))
-	return libcall.r1
-}
-
-//go:nosplit
-func sysvicall2(fn *libcFunc, a1, a2 uintptr) uintptr {
-	libcall := &getg().m.libcall
-	libcall.fn = uintptr(unsafe.Pointer(fn))
-	libcall.n = 2
-	libcall.args = uintptr(noescape(unsafe.Pointer(&a1)))
-	asmcgocall(unsafe.Pointer(&asmsysvicall6), unsafe.Pointer(libcall))
-	return libcall.r1
-}
-
-//go:nosplit
-func sysvicall3(fn *libcFunc, a1, a2, a3 uintptr) uintptr {
-	libcall := &getg().m.libcall
-	libcall.fn = uintptr(unsafe.Pointer(fn))
-	libcall.n = 3
-	libcall.args = uintptr(noescape(unsafe.Pointer(&a1)))
-	asmcgocall(unsafe.Pointer(&asmsysvicall6), unsafe.Pointer(libcall))
-	return libcall.r1
-}
-
-//go:nosplit
-func sysvicall4(fn *libcFunc, a1, a2, a3, a4 uintptr) uintptr {
-	libcall := &getg().m.libcall
-	libcall.fn = uintptr(unsafe.Pointer(fn))
-	libcall.n = 4
-	libcall.args = uintptr(noescape(unsafe.Pointer(&a1)))
-	asmcgocall(unsafe.Pointer(&asmsysvicall6), unsafe.Pointer(libcall))
-	return libcall.r1
-}
-
-//go:nosplit
-func sysvicall5(fn *libcFunc, a1, a2, a3, a4, a5 uintptr) uintptr {
-	libcall := &getg().m.libcall
-	libcall.fn = uintptr(unsafe.Pointer(fn))
-	libcall.n = 5
-	libcall.args = uintptr(noescape(unsafe.Pointer(&a1)))
-	asmcgocall(unsafe.Pointer(&asmsysvicall6), unsafe.Pointer(libcall))
-	return libcall.r1
-}
-
-//go:nosplit
-func sysvicall6(fn *libcFunc, a1, a2, a3, a4, a5, a6 uintptr) uintptr {
-	libcall := &getg().m.libcall
-	libcall.fn = uintptr(unsafe.Pointer(fn))
-	libcall.n = 6
-	libcall.args = uintptr(noescape(unsafe.Pointer(&a1)))
-	asmcgocall(unsafe.Pointer(&asmsysvicall6), unsafe.Pointer(libcall))
-	return libcall.r1
-}
diff --git a/third_party/gofrontend/libgo/go/runtime/os_windows.go b/third_party/gofrontend/libgo/go/runtime/os_windows.go
deleted file mode 100644
index 1528d2f..0000000
--- a/third_party/gofrontend/libgo/go/runtime/os_windows.go
+++ /dev/null
@@ -1,58 +0,0 @@
-// 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.
-
-package runtime
-
-import "unsafe"
-
-type stdFunction *byte
-
-func stdcall0(fn stdFunction) uintptr
-func stdcall1(fn stdFunction, a0 uintptr) uintptr
-func stdcall2(fn stdFunction, a0, a1 uintptr) uintptr
-func stdcall3(fn stdFunction, a0, a1, a2 uintptr) uintptr
-func stdcall4(fn stdFunction, a0, a1, a2, a3 uintptr) uintptr
-func stdcall5(fn stdFunction, a0, a1, a2, a3, a4 uintptr) uintptr
-func stdcall6(fn stdFunction, a0, a1, a2, a3, a4, a5 uintptr) uintptr
-func stdcall7(fn stdFunction, a0, a1, a2, a3, a4, a5, a6 uintptr) uintptr
-
-func asmstdcall(fn unsafe.Pointer)
-func getlasterror() uint32
-func setlasterror(err uint32)
-func usleep1(usec uint32)
-func netpollinit()
-func netpollopen(fd uintptr, pd *pollDesc) int32
-func netpollclose(fd uintptr) int32
-func netpollarm(pd *pollDesc, mode int)
-
-func os_sigpipe() {
-	gothrow("too many writes on closed pipe")
-}
-
-func sigpanic() {
-	g := getg()
-	if !canpanic(g) {
-		gothrow("unexpected signal during runtime execution")
-	}
-
-	switch uint32(g.sig) {
-	case _EXCEPTION_ACCESS_VIOLATION:
-		if g.sigcode1 < 0x1000 || g.paniconfault {
-			panicmem()
-		}
-		print("unexpected fault address ", hex(g.sigcode1), "\n")
-		gothrow("fault")
-	case _EXCEPTION_INT_DIVIDE_BY_ZERO:
-		panicdivide()
-	case _EXCEPTION_INT_OVERFLOW:
-		panicoverflow()
-	case _EXCEPTION_FLT_DENORMAL_OPERAND,
-		_EXCEPTION_FLT_DIVIDE_BY_ZERO,
-		_EXCEPTION_FLT_INEXACT_RESULT,
-		_EXCEPTION_FLT_OVERFLOW,
-		_EXCEPTION_FLT_UNDERFLOW:
-		panicfloat()
-	}
-	gothrow("fault")
-}
diff --git a/third_party/gofrontend/libgo/go/runtime/os_windows_386.go b/third_party/gofrontend/libgo/go/runtime/os_windows_386.go
deleted file mode 100644
index 86a1906..0000000
--- a/third_party/gofrontend/libgo/go/runtime/os_windows_386.go
+++ /dev/null
@@ -1,11 +0,0 @@
-// 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.
-
-package runtime
-
-// contextPC returns the EIP (program counter) register from the context.
-func contextPC(r *context) uintptr { return uintptr(r.eip) }
-
-// contextSP returns the ESP (stack pointer) register from the context.
-func contextSP(r *context) uintptr { return uintptr(r.esp) }
diff --git a/third_party/gofrontend/libgo/go/runtime/os_windows_amd64.go b/third_party/gofrontend/libgo/go/runtime/os_windows_amd64.go
deleted file mode 100644
index 3f4d4d0..0000000
--- a/third_party/gofrontend/libgo/go/runtime/os_windows_amd64.go
+++ /dev/null
@@ -1,11 +0,0 @@
-// 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.
-
-package runtime
-
-// contextPC returns the RIP (program counter) register from the context.
-func contextPC(r *context) uintptr { return uintptr(r.rip) }
-
-// contextSP returns the RSP (stack pointer) register from the context.
-func contextSP(r *context) uintptr { return uintptr(r.rsp) }
diff --git a/third_party/gofrontend/libgo/go/runtime/panic.go b/third_party/gofrontend/libgo/go/runtime/panic.go
deleted file mode 100644
index 685ff5c..0000000
--- a/third_party/gofrontend/libgo/go/runtime/panic.go
+++ /dev/null
@@ -1,505 +0,0 @@
-// 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.
-
-package runtime
-
-import "unsafe"
-
-var indexError = error(errorString("index out of range"))
-
-func panicindex() {
-	panic(indexError)
-}
-
-var sliceError = error(errorString("slice bounds out of range"))
-
-func panicslice() {
-	panic(sliceError)
-}
-
-var divideError = error(errorString("integer divide by zero"))
-
-func panicdivide() {
-	panic(divideError)
-}
-
-var overflowError = error(errorString("integer overflow"))
-
-func panicoverflow() {
-	panic(overflowError)
-}
-
-var floatError = error(errorString("floating point error"))
-
-func panicfloat() {
-	panic(floatError)
-}
-
-var memoryError = error(errorString("invalid memory address or nil pointer dereference"))
-
-func panicmem() {
-	panic(memoryError)
-}
-
-func throwreturn() {
-	gothrow("no return at end of a typed function - compiler is broken")
-}
-
-func throwinit() {
-	gothrow("recursive call during initialization - linker skew")
-}
-
-// Create a new deferred function fn with siz bytes of arguments.
-// The compiler turns a defer statement into a call to this.
-//go:nosplit
-func deferproc(siz int32, fn *funcval) { // arguments of fn follow fn
-	// the arguments of fn are in a perilous state.  The stack map
-	// for deferproc does not describe them.  So we can't let garbage
-	// collection or stack copying trigger until we've copied them out
-	// to somewhere safe.  deferproc_m does that.  Until deferproc_m,
-	// we can only call nosplit routines.
-	argp := uintptr(unsafe.Pointer(&fn))
-	argp += unsafe.Sizeof(fn)
-	if GOARCH == "arm" {
-		argp += ptrSize // skip caller's saved link register
-	}
-	mp := acquirem()
-	mp.scalararg[0] = uintptr(siz)
-	mp.ptrarg[0] = unsafe.Pointer(fn)
-	mp.scalararg[1] = argp
-	mp.scalararg[2] = getcallerpc(unsafe.Pointer(&siz))
-
-	if mp.curg != getg() {
-		// go code on the m stack can't defer
-		gothrow("defer on m")
-	}
-
-	onM(deferproc_m)
-
-	releasem(mp)
-
-	// deferproc returns 0 normally.
-	// a deferred func that stops a panic
-	// makes the deferproc return 1.
-	// the code the compiler generates always
-	// checks the return value and jumps to the
-	// end of the function if deferproc returns != 0.
-	return0()
-	// No code can go here - the C return register has
-	// been set and must not be clobbered.
-}
-
-// Small malloc size classes >= 16 are the multiples of 16: 16, 32, 48, 64, 80, 96, 112, 128, 144, ...
-// Each P holds a pool for defers with small arg sizes.
-// Assign defer allocations to pools by rounding to 16, to match malloc size classes.
-
-const (
-	deferHeaderSize = unsafe.Sizeof(_defer{})
-	minDeferAlloc   = (deferHeaderSize + 15) &^ 15
-	minDeferArgs    = minDeferAlloc - deferHeaderSize
-)
-
-// defer size class for arg size sz
-//go:nosplit
-func deferclass(siz uintptr) uintptr {
-	if siz <= minDeferArgs {
-		return 0
-	}
-	return (siz - minDeferArgs + 15) / 16
-}
-
-// total size of memory block for defer with arg size sz
-func totaldefersize(siz uintptr) uintptr {
-	if siz <= minDeferArgs {
-		return minDeferAlloc
-	}
-	return deferHeaderSize + siz
-}
-
-// Ensure that defer arg sizes that map to the same defer size class
-// also map to the same malloc size class.
-func testdefersizes() {
-	var m [len(p{}.deferpool)]int32
-
-	for i := range m {
-		m[i] = -1
-	}
-	for i := uintptr(0); ; i++ {
-		defersc := deferclass(i)
-		if defersc >= uintptr(len(m)) {
-			break
-		}
-		siz := goroundupsize(totaldefersize(i))
-		if m[defersc] < 0 {
-			m[defersc] = int32(siz)
-			continue
-		}
-		if m[defersc] != int32(siz) {
-			print("bad defer size class: i=", i, " siz=", siz, " defersc=", defersc, "\n")
-			gothrow("bad defer size class")
-		}
-	}
-}
-
-// The arguments associated with a deferred call are stored
-// immediately after the _defer header in memory.
-//go:nosplit
-func deferArgs(d *_defer) unsafe.Pointer {
-	return add(unsafe.Pointer(d), unsafe.Sizeof(*d))
-}
-
-var deferType *_type // type of _defer struct
-
-func init() {
-	var x interface{}
-	x = (*_defer)(nil)
-	deferType = (*(**ptrtype)(unsafe.Pointer(&x))).elem
-}
-
-// Allocate a Defer, usually using per-P pool.
-// Each defer must be released with freedefer.
-// Note: runs on M stack
-func newdefer(siz int32) *_defer {
-	var d *_defer
-	sc := deferclass(uintptr(siz))
-	mp := acquirem()
-	if sc < uintptr(len(p{}.deferpool)) {
-		pp := mp.p
-		d = pp.deferpool[sc]
-		if d != nil {
-			pp.deferpool[sc] = d.link
-		}
-	}
-	if d == nil {
-		// Allocate new defer+args.
-		total := goroundupsize(totaldefersize(uintptr(siz)))
-		d = (*_defer)(mallocgc(total, deferType, 0))
-	}
-	d.siz = siz
-	gp := mp.curg
-	d.link = gp._defer
-	gp._defer = d
-	releasem(mp)
-	return d
-}
-
-// Free the given defer.
-// The defer cannot be used after this call.
-//go:nosplit
-func freedefer(d *_defer) {
-	if d._panic != nil {
-		freedeferpanic()
-	}
-	if d.fn != nil {
-		freedeferfn()
-	}
-	sc := deferclass(uintptr(d.siz))
-	if sc < uintptr(len(p{}.deferpool)) {
-		mp := acquirem()
-		pp := mp.p
-		*d = _defer{}
-		d.link = pp.deferpool[sc]
-		pp.deferpool[sc] = d
-		releasem(mp)
-	}
-}
-
-// Separate function so that it can split stack.
-// Windows otherwise runs out of stack space.
-func freedeferpanic() {
-	// _panic must be cleared before d is unlinked from gp.
-	gothrow("freedefer with d._panic != nil")
-}
-
-func freedeferfn() {
-	// fn must be cleared before d is unlinked from gp.
-	gothrow("freedefer with d.fn != nil")
-}
-
-// Run a deferred function if there is one.
-// The compiler inserts a call to this at the end of any
-// function which calls defer.
-// If there is a deferred function, this will call runtime·jmpdefer,
-// which will jump to the deferred function such that it appears
-// to have been called by the caller of deferreturn at the point
-// just before deferreturn was called.  The effect is that deferreturn
-// is called again and again until there are no more deferred functions.
-// Cannot split the stack because we reuse the caller's frame to
-// call the deferred function.
-
-// The single argument isn't actually used - it just has its address
-// taken so it can be matched against pending defers.
-//go:nosplit
-func deferreturn(arg0 uintptr) {
-	gp := getg()
-	d := gp._defer
-	if d == nil {
-		return
-	}
-	argp := uintptr(unsafe.Pointer(&arg0))
-	if d.argp != argp {
-		return
-	}
-
-	// Moving arguments around.
-	// Do not allow preemption here, because the garbage collector
-	// won't know the form of the arguments until the jmpdefer can
-	// flip the PC over to fn.
-	mp := acquirem()
-	memmove(unsafe.Pointer(argp), deferArgs(d), uintptr(d.siz))
-	fn := d.fn
-	d.fn = nil
-	gp._defer = d.link
-	freedefer(d)
-	releasem(mp)
-	jmpdefer(fn, argp)
-}
-
-// Goexit terminates the goroutine that calls it.  No other goroutine is affected.
-// Goexit runs all deferred calls before terminating the goroutine.  Because Goexit
-// is not panic, however, any recover calls in those deferred functions will return nil.
-//
-// Calling Goexit from the main goroutine terminates that goroutine
-// without func main returning. Since func main has not returned,
-// the program continues execution of other goroutines.
-// If all other goroutines exit, the program crashes.
-func Goexit() {
-	// Run all deferred functions for the current goroutine.
-	// This code is similar to gopanic, see that implementation
-	// for detailed comments.
-	gp := getg()
-	for {
-		d := gp._defer
-		if d == nil {
-			break
-		}
-		if d.started {
-			if d._panic != nil {
-				d._panic.aborted = true
-				d._panic = nil
-			}
-			d.fn = nil
-			gp._defer = d.link
-			freedefer(d)
-			continue
-		}
-		d.started = true
-		reflectcall(unsafe.Pointer(d.fn), deferArgs(d), uint32(d.siz), uint32(d.siz))
-		if gp._defer != d {
-			gothrow("bad defer entry in Goexit")
-		}
-		d._panic = nil
-		d.fn = nil
-		gp._defer = d.link
-		freedefer(d)
-		// Note: we ignore recovers here because Goexit isn't a panic
-	}
-	goexit()
-}
-
-func canpanic(*g) bool
-
-// Print all currently active panics.  Used when crashing.
-func printpanics(p *_panic) {
-	if p.link != nil {
-		printpanics(p.link)
-		print("\t")
-	}
-	print("panic: ")
-	printany(p.arg)
-	if p.recovered {
-		print(" [recovered]")
-	}
-	print("\n")
-}
-
-// The implementation of the predeclared function panic.
-func gopanic(e interface{}) {
-	gp := getg()
-	if gp.m.curg != gp {
-		gothrow("panic on m stack")
-	}
-
-	// m.softfloat is set during software floating point.
-	// It increments m.locks to avoid preemption.
-	// We moved the memory loads out, so there shouldn't be
-	// any reason for it to panic anymore.
-	if gp.m.softfloat != 0 {
-		gp.m.locks--
-		gp.m.softfloat = 0
-		gothrow("panic during softfloat")
-	}
-	if gp.m.mallocing != 0 {
-		print("panic: ")
-		printany(e)
-		print("\n")
-		gothrow("panic during malloc")
-	}
-	if gp.m.gcing != 0 {
-		print("panic: ")
-		printany(e)
-		print("\n")
-		gothrow("panic during gc")
-	}
-	if gp.m.locks != 0 {
-		print("panic: ")
-		printany(e)
-		print("\n")
-		gothrow("panic holding locks")
-	}
-
-	var p _panic
-	p.arg = e
-	p.link = gp._panic
-	gp._panic = (*_panic)(noescape(unsafe.Pointer(&p)))
-
-	for {
-		d := gp._defer
-		if d == nil {
-			break
-		}
-
-		// If defer was started by earlier panic or Goexit (and, since we're back here, that triggered a new panic),
-		// take defer off list. The earlier panic or Goexit will not continue running.
-		if d.started {
-			if d._panic != nil {
-				d._panic.aborted = true
-			}
-			d._panic = nil
-			d.fn = nil
-			gp._defer = d.link
-			freedefer(d)
-			continue
-		}
-
-		// Mark defer as started, but keep on list, so that traceback
-		// can find and update the defer's argument frame if stack growth
-		// or a garbage collection hapens before reflectcall starts executing d.fn.
-		d.started = true
-
-		// Record the panic that is running the defer.
-		// If there is a new panic during the deferred call, that panic
-		// will find d in the list and will mark d._panic (this panic) aborted.
-		d._panic = (*_panic)(noescape((unsafe.Pointer)(&p)))
-
-		p.argp = unsafe.Pointer(getargp(0))
-		reflectcall(unsafe.Pointer(d.fn), deferArgs(d), uint32(d.siz), uint32(d.siz))
-		p.argp = nil
-
-		// reflectcall did not panic. Remove d.
-		if gp._defer != d {
-			gothrow("bad defer entry in panic")
-		}
-		d._panic = nil
-		d.fn = nil
-		gp._defer = d.link
-
-		// trigger shrinkage to test stack copy.  See stack_test.go:TestStackPanic
-		//GC()
-
-		pc := d.pc
-		argp := unsafe.Pointer(d.argp) // must be pointer so it gets adjusted during stack copy
-		freedefer(d)
-		if p.recovered {
-			gp._panic = p.link
-			// Aborted panics are marked but remain on the g.panic list.
-			// Remove them from the list.
-			for gp._panic != nil && gp._panic.aborted {
-				gp._panic = gp._panic.link
-			}
-			if gp._panic == nil { // must be done with signal
-				gp.sig = 0
-			}
-			// Pass information about recovering frame to recovery.
-			gp.sigcode0 = uintptr(argp)
-			gp.sigcode1 = pc
-			mcall(recovery_m)
-			gothrow("recovery failed") // mcall should not return
-		}
-	}
-
-	// ran out of deferred calls - old-school panic now
-	startpanic()
-	printpanics(gp._panic)
-	dopanic(0)       // should not return
-	*(*int)(nil) = 0 // not reached
-}
-
-// getargp returns the location where the caller
-// writes outgoing function call arguments.
-//go:nosplit
-func getargp(x int) uintptr {
-	// x is an argument mainly so that we can return its address.
-	// However, we need to make the function complex enough
-	// that it won't be inlined. We always pass x = 0, so this code
-	// does nothing other than keep the compiler from thinking
-	// the function is simple enough to inline.
-	if x > 0 {
-		return getcallersp(unsafe.Pointer(&x)) * 0
-	}
-	return uintptr(noescape(unsafe.Pointer(&x)))
-}
-
-// The implementation of the predeclared function recover.
-// Cannot split the stack because it needs to reliably
-// find the stack segment of its caller.
-//
-// TODO(rsc): Once we commit to CopyStackAlways,
-// this doesn't need to be nosplit.
-//go:nosplit
-func gorecover(argp uintptr) interface{} {
-	// Must be in a function running as part of a deferred call during the panic.
-	// Must be called from the topmost function of the call
-	// (the function used in the defer statement).
-	// p.argp is the argument pointer of that topmost deferred function call.
-	// Compare against argp reported by caller.
-	// If they match, the caller is the one who can recover.
-	gp := getg()
-	p := gp._panic
-	if p != nil && !p.recovered && argp == uintptr(p.argp) {
-		p.recovered = true
-		return p.arg
-	}
-	return nil
-}
-
-//go:nosplit
-func startpanic() {
-	onM_signalok(startpanic_m)
-}
-
-//go:nosplit
-func dopanic(unused int) {
-	gp := getg()
-	mp := acquirem()
-	mp.ptrarg[0] = unsafe.Pointer(gp)
-	mp.scalararg[0] = getcallerpc((unsafe.Pointer)(&unused))
-	mp.scalararg[1] = getcallersp((unsafe.Pointer)(&unused))
-	onM_signalok(dopanic_m) // should never return
-	*(*int)(nil) = 0
-}
-
-//go:nosplit
-func throw(s *byte) {
-	gp := getg()
-	if gp.m.throwing == 0 {
-		gp.m.throwing = 1
-	}
-	startpanic()
-	print("fatal error: ", gostringnocopy(s), "\n")
-	dopanic(0)
-	*(*int)(nil) = 0 // not reached
-}
-
-//go:nosplit
-func gothrow(s string) {
-	gp := getg()
-	if gp.m.throwing == 0 {
-		gp.m.throwing = 1
-	}
-	startpanic()
-	print("fatal error: ", s, "\n")
-	dopanic(0)
-	*(*int)(nil) = 0 // not reached
-}
diff --git a/third_party/gofrontend/libgo/go/runtime/parfor_test.go b/third_party/gofrontend/libgo/go/runtime/parfor_test.go
index de64285..5d22aec 100644
--- a/third_party/gofrontend/libgo/go/runtime/parfor_test.go
+++ b/third_party/gofrontend/libgo/go/runtime/parfor_test.go
@@ -10,11 +10,8 @@
 import (
 	. "runtime"
 	"testing"
-	"unsafe"
 )
 
-var gdata []uint64
-
 // Simple serial sanity test for parallelfor.
 func TestParFor(t *testing.T) {
 	const P = 1
@@ -24,12 +21,7 @@
 		data[i] = i
 	}
 	desc := NewParFor(P)
-	// Avoid making func a closure: parfor cannot invoke them.
-	// Since it doesn't happen in the C code, it's not worth doing
-	// just for the test.
-	gdata = data
-	ParForSetup(desc, P, N, nil, true, func(desc *ParFor, i uint32) {
-		data := gdata
+	ParForSetup(desc, P, N, true, func(desc *ParFor, i uint32) {
 		data[i] = data[i]*data[i] + 1
 	})
 	ParForDo(desc)
@@ -49,9 +41,8 @@
 		data[i] = i
 	}
 	desc := NewParFor(P)
-	ParForSetup(desc, P, N, (*byte)(unsafe.Pointer(&data)), false, func(desc *ParFor, i uint32) {
-		d := *(*[]uint64)(unsafe.Pointer(desc.Ctx))
-		d[i] = d[i]*d[i] + 1
+	ParForSetup(desc, P, N, false, func(desc *ParFor, i uint32) {
+		data[i] = data[i]*data[i] + 1
 	})
 	for p := 0; p < P; p++ {
 		ParForDo(desc)
@@ -70,7 +61,7 @@
 	desc := NewParFor(P)
 	for n := uint32(0); n < N; n++ {
 		for p := uint32(1); p <= P; p++ {
-			ParForSetup(desc, p, n, nil, true, func(desc *ParFor, i uint32) {})
+			ParForSetup(desc, p, n, true, func(desc *ParFor, i uint32) {})
 			sum := uint32(0)
 			size0 := uint32(0)
 			end0 := uint32(0)
@@ -113,9 +104,7 @@
 	P := GOMAXPROCS(-1)
 	c := make(chan bool, P)
 	desc := NewParFor(uint32(P))
-	gdata = data
-	ParForSetup(desc, uint32(P), uint32(N), nil, false, func(desc *ParFor, i uint32) {
-		data := gdata
+	ParForSetup(desc, uint32(P), uint32(N), false, func(desc *ParFor, i uint32) {
 		data[i] = data[i]*data[i] + 1
 	})
 	for p := 1; p < P; p++ {
diff --git a/third_party/gofrontend/libgo/go/runtime/pprof/pprof.go b/third_party/gofrontend/libgo/go/runtime/pprof/pprof.go
index 9c63ccd..dcf67cd 100644
--- a/third_party/gofrontend/libgo/go/runtime/pprof/pprof.go
+++ b/third_party/gofrontend/libgo/go/runtime/pprof/pprof.go
@@ -21,7 +21,7 @@
 )
 
 // BUG(rsc): Profiles are incomplete and inaccurate on NetBSD and OS X.
-// See http://golang.org/issue/6047 for details.
+// See https://golang.org/issue/6047 for details.
 
 // A Profile is a collection of stack traces showing the call sequences
 // that led to instances of a particular event, such as allocation.
@@ -41,6 +41,13 @@
 // These predefined profiles maintain themselves and panic on an explicit
 // Add or Remove method call.
 //
+// The heap profile reports statistics as of the most recently completed
+// garbage collection; it elides more recent allocation to avoid skewing
+// the profile away from live data and toward garbage.
+// If there has been no garbage collection at all, the heap profile reports
+// all known allocations. This exception helps mainly in programs running
+// without garbage collection enabled, usually for debugging purposes.
+//
 // The CPU profile is not available as a Profile.  It has a special API,
 // the StartCPUProfile and StopCPUProfile functions, because it streams
 // output to a writer during profiling.
@@ -351,6 +358,10 @@
 			if !show && !strings.Contains(name, ".") && strings.HasPrefix(name, "__go_") {
 				continue
 			}
+			if !show && name == "" {
+				// This can happen due to http://gcc.gnu.org/PR65797.
+				continue
+			}
 			show = true
 			fmt.Fprintf(w, "#\t%#x\t%s+%#x\t%s:%d\n", pc, name, pc-f.Entry(), file, line)
 		}
@@ -450,35 +461,33 @@
 
 	// Print memstats information too.
 	// Pprof will ignore, but useful for people
-	if debug > 0 {
-		s := new(runtime.MemStats)
-		runtime.ReadMemStats(s)
-		fmt.Fprintf(w, "\n# runtime.MemStats\n")
-		fmt.Fprintf(w, "# Alloc = %d\n", s.Alloc)
-		fmt.Fprintf(w, "# TotalAlloc = %d\n", s.TotalAlloc)
-		fmt.Fprintf(w, "# Sys = %d\n", s.Sys)
-		fmt.Fprintf(w, "# Lookups = %d\n", s.Lookups)
-		fmt.Fprintf(w, "# Mallocs = %d\n", s.Mallocs)
-		fmt.Fprintf(w, "# Frees = %d\n", s.Frees)
+	s := new(runtime.MemStats)
+	runtime.ReadMemStats(s)
+	fmt.Fprintf(w, "\n# runtime.MemStats\n")
+	fmt.Fprintf(w, "# Alloc = %d\n", s.Alloc)
+	fmt.Fprintf(w, "# TotalAlloc = %d\n", s.TotalAlloc)
+	fmt.Fprintf(w, "# Sys = %d\n", s.Sys)
+	fmt.Fprintf(w, "# Lookups = %d\n", s.Lookups)
+	fmt.Fprintf(w, "# Mallocs = %d\n", s.Mallocs)
+	fmt.Fprintf(w, "# Frees = %d\n", s.Frees)
 
-		fmt.Fprintf(w, "# HeapAlloc = %d\n", s.HeapAlloc)
-		fmt.Fprintf(w, "# HeapSys = %d\n", s.HeapSys)
-		fmt.Fprintf(w, "# HeapIdle = %d\n", s.HeapIdle)
-		fmt.Fprintf(w, "# HeapInuse = %d\n", s.HeapInuse)
-		fmt.Fprintf(w, "# HeapReleased = %d\n", s.HeapReleased)
-		fmt.Fprintf(w, "# HeapObjects = %d\n", s.HeapObjects)
+	fmt.Fprintf(w, "# HeapAlloc = %d\n", s.HeapAlloc)
+	fmt.Fprintf(w, "# HeapSys = %d\n", s.HeapSys)
+	fmt.Fprintf(w, "# HeapIdle = %d\n", s.HeapIdle)
+	fmt.Fprintf(w, "# HeapInuse = %d\n", s.HeapInuse)
+	fmt.Fprintf(w, "# HeapReleased = %d\n", s.HeapReleased)
+	fmt.Fprintf(w, "# HeapObjects = %d\n", s.HeapObjects)
 
-		fmt.Fprintf(w, "# Stack = %d / %d\n", s.StackInuse, s.StackSys)
-		fmt.Fprintf(w, "# MSpan = %d / %d\n", s.MSpanInuse, s.MSpanSys)
-		fmt.Fprintf(w, "# MCache = %d / %d\n", s.MCacheInuse, s.MCacheSys)
-		fmt.Fprintf(w, "# BuckHashSys = %d\n", s.BuckHashSys)
+	fmt.Fprintf(w, "# Stack = %d / %d\n", s.StackInuse, s.StackSys)
+	fmt.Fprintf(w, "# MSpan = %d / %d\n", s.MSpanInuse, s.MSpanSys)
+	fmt.Fprintf(w, "# MCache = %d / %d\n", s.MCacheInuse, s.MCacheSys)
+	fmt.Fprintf(w, "# BuckHashSys = %d\n", s.BuckHashSys)
 
-		fmt.Fprintf(w, "# NextGC = %d\n", s.NextGC)
-		fmt.Fprintf(w, "# PauseNs = %d\n", s.PauseNs)
-		fmt.Fprintf(w, "# NumGC = %d\n", s.NumGC)
-		fmt.Fprintf(w, "# EnableGC = %v\n", s.EnableGC)
-		fmt.Fprintf(w, "# DebugGC = %v\n", s.DebugGC)
-	}
+	fmt.Fprintf(w, "# NextGC = %d\n", s.NextGC)
+	fmt.Fprintf(w, "# PauseNs = %d\n", s.PauseNs)
+	fmt.Fprintf(w, "# NumGC = %d\n", s.NumGC)
+	fmt.Fprintf(w, "# EnableGC = %v\n", s.EnableGC)
+	fmt.Fprintf(w, "# DebugGC = %v\n", s.DebugGC)
 
 	if tw != nil {
 		tw.Flush()
diff --git a/third_party/gofrontend/libgo/go/runtime/pprof/pprof_test.go b/third_party/gofrontend/libgo/go/runtime/pprof/pprof_test.go
index 1069963..c32b847 100644
--- a/third_party/gofrontend/libgo/go/runtime/pprof/pprof_test.go
+++ b/third_party/gofrontend/libgo/go/runtime/pprof/pprof_test.go
@@ -9,7 +9,9 @@
 import (
 	"bytes"
 	"fmt"
+	"internal/testenv"
 	"math/big"
+	"os"
 	"os/exec"
 	"regexp"
 	"runtime"
@@ -121,15 +123,19 @@
 func testCPUProfile(t *testing.T, need []string, f func()) {
 	switch runtime.GOOS {
 	case "darwin":
-		out, err := exec.Command("uname", "-a").CombinedOutput()
-		if err != nil {
-			t.Fatal(err)
+		switch runtime.GOARCH {
+		case "arm", "arm64":
+			// nothing
+		default:
+			out, err := exec.Command("uname", "-a").CombinedOutput()
+			if err != nil {
+				t.Fatal(err)
+			}
+			vers := string(out)
+			t.Logf("uname -a: %v", vers)
 		}
-		vers := string(out)
-		t.Logf("uname -a: %v", vers)
 	case "plan9":
-		// unimplemented
-		return
+		t.Skip("skipping on plan9")
 	}
 
 	var prof bytes.Buffer
@@ -141,7 +147,9 @@
 
 	// Check that profile is well formed and contains need.
 	have := make([]uintptr, len(need))
+	var samples uintptr
 	parseProfile(t, prof.Bytes(), func(count uintptr, stk []uintptr) {
+		samples += count
 		for _, pc := range stk {
 			f := runtime.FuncForPC(pc)
 			if f == nil {
@@ -155,6 +163,14 @@
 			}
 		}
 	})
+	t.Logf("total %d CPU profile samples collected", samples)
+
+	if samples < 10 && runtime.GOOS == "windows" {
+		// On some windows machines we end up with
+		// not enough samples due to coarse timer
+		// resolution. Let it go.
+		t.Skip("too few samples on Windows (golang.org/issue/10842)")
+	}
 
 	if len(need) == 0 {
 		return
@@ -187,14 +203,28 @@
 			t.Skipf("ignoring failure on %s; see golang.org/issue/6047", runtime.GOOS)
 			return
 		}
+		// Ignore the failure if the tests are running in a QEMU-based emulator,
+		// QEMU is not perfect at emulating everything.
+		// IN_QEMU environmental variable is set by some of the Go builders.
+		// IN_QEMU=1 indicates that the tests are running in QEMU. See issue 9605.
+		if os.Getenv("IN_QEMU") == "1" {
+			t.Skip("ignore the failure in QEMU; see golang.org/issue/9605")
+			return
+		}
 		t.FailNow()
 	}
 }
 
+// Fork can hang if preempted with signals frequently enough (see issue 5517).
+// Ensure that we do not do this.
 func TestCPUProfileWithFork(t *testing.T) {
-	// Fork can hang if preempted with signals frequently enough (see issue 5517).
-	// Ensure that we do not do this.
+	testenv.MustHaveExec(t)
+
 	heap := 1 << 30
+	if runtime.GOOS == "android" {
+		// Use smaller size for Android to avoid crash.
+		heap = 100 << 20
+	}
 	if testing.Short() {
 		heap = 100 << 20
 	}
@@ -217,7 +247,7 @@
 	defer StopCPUProfile()
 
 	for i := 0; i < 10; i++ {
-		exec.Command("go").CombinedOutput()
+		exec.Command(os.Args[0], "-h").CombinedOutput()
 	}
 }
 
@@ -250,7 +280,7 @@
 			// exists to record a PC without a traceback. Those are okay.
 			if len(stk) == 2 {
 				f := runtime.FuncForPC(stk[1])
-				if f != nil && (f.Name() == "System" || f.Name() == "ExternalCode" || f.Name() == "GC") {
+				if f != nil && (f.Name() == "runtime._System" || f.Name() == "runtime._ExternalCode" || f.Name() == "runtime._GC") {
 					return
 				}
 			}
@@ -368,7 +398,7 @@
 	}
 
 	for _, test := range tests {
-		if !regexp.MustCompile(test.re).MatchString(prof) {
+		if !regexp.MustCompile(strings.Replace(test.re, "\t", "\t+", -1)).MatchString(prof) {
 			t.Fatalf("Bad %v entry, expect:\n%v\ngot:\n%v", test.name, test.re, prof)
 		}
 	}
diff --git a/third_party/gofrontend/libgo/go/runtime/print1.go b/third_party/gofrontend/libgo/go/runtime/print1.go
deleted file mode 100644
index 8f82688..0000000
--- a/third_party/gofrontend/libgo/go/runtime/print1.go
+++ /dev/null
@@ -1,323 +0,0 @@
-// Copyright 2009 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 runtime
-
-import "unsafe"
-
-// The compiler knows that a print of a value of this type
-// should use printhex instead of printuint (decimal).
-type hex uint64
-
-func bytes(s string) (ret []byte) {
-	rp := (*slice)(unsafe.Pointer(&ret))
-	sp := (*_string)(noescape(unsafe.Pointer(&s)))
-	rp.array = sp.str
-	rp.len = uint(sp.len)
-	rp.cap = uint(sp.len)
-	return
-}
-
-// printf is only called from C code. It has no type information for the args,
-// but C stacks are ignored by the garbage collector anyway, so having
-// type information would not add anything.
-//go:nosplit
-func printf(s *byte) {
-	vprintf(gostringnocopy(s), add(unsafe.Pointer(&s), unsafe.Sizeof(s)))
-}
-
-// sprintf is only called from C code. It has no type information for the args,
-// but C stacks are ignored by the garbage collector anyway, so having
-// type information would not add anything.
-//go:nosplit
-func snprintf(dst *byte, n int32, s *byte) {
-	buf := (*[1 << 30]byte)(unsafe.Pointer(dst))[0:n:n]
-
-	gp := getg()
-	gp.writebuf = buf[0:0 : n-1] // leave room for NUL, this is called from C
-	vprintf(gostringnocopy(s), add(unsafe.Pointer(&s), unsafe.Sizeof(s)))
-	buf[len(gp.writebuf)] = '\x00'
-	gp.writebuf = nil
-}
-
-//var debuglock mutex
-
-// write to goroutine-local buffer if diverting output,
-// or else standard error.
-func gwrite(b []byte) {
-	if len(b) == 0 {
-		return
-	}
-	gp := getg()
-	if gp == nil || gp.writebuf == nil {
-		write(2, unsafe.Pointer(&b[0]), int32(len(b)))
-		return
-	}
-
-	n := copy(gp.writebuf[len(gp.writebuf):cap(gp.writebuf)], b)
-	gp.writebuf = gp.writebuf[:len(gp.writebuf)+n]
-}
-
-func prints(s *byte) {
-	b := (*[1 << 30]byte)(unsafe.Pointer(s))
-	for i := 0; ; i++ {
-		if b[i] == 0 {
-			gwrite(b[:i])
-			return
-		}
-	}
-}
-
-func printsp() {
-	print(" ")
-}
-
-func printnl() {
-	print("\n")
-}
-
-// Very simple printf.  Only for debugging prints.
-// Do not add to this without checking with Rob.
-func vprintf(str string, arg unsafe.Pointer) {
-	//lock(&debuglock);
-
-	s := bytes(str)
-	start := 0
-	i := 0
-	for ; i < len(s); i++ {
-		if s[i] != '%' {
-			continue
-		}
-		if i > start {
-			gwrite(s[start:i])
-		}
-		if i++; i >= len(s) {
-			break
-		}
-		var siz uintptr
-		switch s[i] {
-		case 't', 'c':
-			siz = 1
-		case 'd', 'x': // 32-bit
-			arg = roundup(arg, 4)
-			siz = 4
-		case 'D', 'U', 'X', 'f': // 64-bit
-			arg = roundup(arg, unsafe.Sizeof(uintreg(0)))
-			siz = 8
-		case 'C':
-			arg = roundup(arg, unsafe.Sizeof(uintreg(0)))
-			siz = 16
-		case 'p', 's': // pointer-sized
-			arg = roundup(arg, unsafe.Sizeof(uintptr(0)))
-			siz = unsafe.Sizeof(uintptr(0))
-		case 'S': // pointer-aligned but bigger
-			arg = roundup(arg, unsafe.Sizeof(uintptr(0)))
-			siz = unsafe.Sizeof(string(""))
-		case 'a': // pointer-aligned but bigger
-			arg = roundup(arg, unsafe.Sizeof(uintptr(0)))
-			siz = unsafe.Sizeof([]byte{})
-		case 'i', 'e': // pointer-aligned but bigger
-			arg = roundup(arg, unsafe.Sizeof(uintptr(0)))
-			siz = unsafe.Sizeof(interface{}(nil))
-		}
-		switch s[i] {
-		case 'a':
-			printslice(*(*[]byte)(arg))
-		case 'c':
-			printbyte(*(*byte)(arg))
-		case 'd':
-			printint(int64(*(*int32)(arg)))
-		case 'D':
-			printint(int64(*(*int64)(arg)))
-		case 'e':
-			printeface(*(*interface{})(arg))
-		case 'f':
-			printfloat(*(*float64)(arg))
-		case 'C':
-			printcomplex(*(*complex128)(arg))
-		case 'i':
-			printiface(*(*fInterface)(arg))
-		case 'p':
-			printpointer(*(*unsafe.Pointer)(arg))
-		case 's':
-			prints(*(**byte)(arg))
-		case 'S':
-			printstring(*(*string)(arg))
-		case 't':
-			printbool(*(*bool)(arg))
-		case 'U':
-			printuint(*(*uint64)(arg))
-		case 'x':
-			printhex(uint64(*(*uint32)(arg)))
-		case 'X':
-			printhex(*(*uint64)(arg))
-		}
-		arg = add(arg, siz)
-		start = i + 1
-	}
-	if start < i {
-		gwrite(s[start:i])
-	}
-
-	//unlock(&debuglock);
-}
-
-func printpc(p unsafe.Pointer) {
-	print("PC=", hex(uintptr(p)))
-}
-
-func printbool(v bool) {
-	if v {
-		print("true")
-	} else {
-		print("false")
-	}
-}
-
-func printbyte(c byte) {
-	gwrite((*[1]byte)(unsafe.Pointer(&c))[:])
-}
-
-func printfloat(v float64) {
-	switch {
-	case v != v:
-		print("NaN")
-		return
-	case v+v == v && v > 0:
-		print("+Inf")
-		return
-	case v+v == v && v < 0:
-		print("-Inf")
-		return
-	}
-
-	const n = 7 // digits printed
-	var buf [n + 7]byte
-	buf[0] = '+'
-	e := 0 // exp
-	if v == 0 {
-		if 1/v < 0 {
-			buf[0] = '-'
-		}
-	} else {
-		if v < 0 {
-			v = -v
-			buf[0] = '-'
-		}
-
-		// normalize
-		for v >= 10 {
-			e++
-			v /= 10
-		}
-		for v < 1 {
-			e--
-			v *= 10
-		}
-
-		// round
-		h := 5.0
-		for i := 0; i < n; i++ {
-			h /= 10
-		}
-		v += h
-		if v >= 10 {
-			e++
-			v /= 10
-		}
-	}
-
-	// format +d.dddd+edd
-	for i := 0; i < n; i++ {
-		s := int(v)
-		buf[i+2] = byte(s + '0')
-		v -= float64(s)
-		v *= 10
-	}
-	buf[1] = buf[2]
-	buf[2] = '.'
-
-	buf[n+2] = 'e'
-	buf[n+3] = '+'
-	if e < 0 {
-		e = -e
-		buf[n+3] = '-'
-	}
-
-	buf[n+4] = byte(e/100) + '0'
-	buf[n+5] = byte(e/10)%10 + '0'
-	buf[n+6] = byte(e%10) + '0'
-	gwrite(buf[:])
-}
-
-func printcomplex(c complex128) {
-	print("(", real(c), imag(c), "i)")
-}
-
-func printuint(v uint64) {
-	var buf [100]byte
-	i := len(buf)
-	for i--; i > 0; i-- {
-		buf[i] = byte(v%10 + '0')
-		if v < 10 {
-			break
-		}
-		v /= 10
-	}
-	gwrite(buf[i:])
-}
-
-func printint(v int64) {
-	if v < 0 {
-		print("-")
-		v = -v
-	}
-	printuint(uint64(v))
-}
-
-func printhex(v uint64) {
-	const dig = "0123456789abcdef"
-	var buf [100]byte
-	i := len(buf)
-	for i--; i > 0; i-- {
-		buf[i] = dig[v%16]
-		if v < 16 {
-			break
-		}
-		v /= 16
-	}
-	i--
-	buf[i] = 'x'
-	i--
-	buf[i] = '0'
-	gwrite(buf[i:])
-}
-
-func printpointer(p unsafe.Pointer) {
-	printhex(uint64(uintptr(p)))
-}
-
-func printstring(s string) {
-	if uintptr(len(s)) > maxstring {
-		gwrite(bytes("[string too long]"))
-		return
-	}
-	gwrite(bytes(s))
-}
-
-func printslice(s []byte) {
-	sp := (*slice)(unsafe.Pointer(&s))
-	print("[", len(s), "/", cap(s), "]")
-	printpointer(unsafe.Pointer(sp.array))
-}
-
-func printeface(e interface{}) {
-	ep := (*eface)(unsafe.Pointer(&e))
-	print("(", ep._type, ",", ep.data, ")")
-}
-
-func printiface(i fInterface) {
-	ip := (*iface)(unsafe.Pointer(&i))
-	print("(", ip.tab, ",", ip.data, ")")
-}
diff --git a/third_party/gofrontend/libgo/go/runtime/proc.go b/third_party/gofrontend/libgo/go/runtime/proc.go
deleted file mode 100644
index 517ca03..0000000
--- a/third_party/gofrontend/libgo/go/runtime/proc.go
+++ /dev/null
@@ -1,246 +0,0 @@
-// 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.
-
-package runtime
-
-import "unsafe"
-
-func newsysmon()
-
-func runtime_init()
-func main_init()
-func main_main()
-
-// The main goroutine.
-func main() {
-	g := getg()
-
-	// Racectx of m0->g0 is used only as the parent of the main goroutine.
-	// It must not be used for anything else.
-	g.m.g0.racectx = 0
-
-	// Max stack size is 1 GB on 64-bit, 250 MB on 32-bit.
-	// Using decimal instead of binary GB and MB because
-	// they look nicer in the stack overflow failure message.
-	if ptrSize == 8 {
-		maxstacksize = 1000000000
-	} else {
-		maxstacksize = 250000000
-	}
-
-	onM(newsysmon)
-
-	// Lock the main goroutine onto this, the main OS thread,
-	// during initialization.  Most programs won't care, but a few
-	// do require certain calls to be made by the main thread.
-	// Those can arrange for main.main to run in the main thread
-	// by calling runtime.LockOSThread during initialization
-	// to preserve the lock.
-	lockOSThread()
-
-	if g.m != &m0 {
-		gothrow("runtime.main not on m0")
-	}
-
-	runtime_init() // must be before defer
-
-	// Defer unlock so that runtime.Goexit during init does the unlock too.
-	needUnlock := true
-	defer func() {
-		if needUnlock {
-			unlockOSThread()
-		}
-	}()
-
-	memstats.enablegc = true // now that runtime is initialized, GC is okay
-
-	main_init()
-
-	needUnlock = false
-	unlockOSThread()
-
-	main_main()
-	if raceenabled {
-		racefini()
-	}
-
-	// Make racy client program work: if panicking on
-	// another goroutine at the same time as main returns,
-	// let the other goroutine finish printing the panic trace.
-	// Once it does, it will exit. See issue 3934.
-	if panicking != 0 {
-		gopark(nil, nil, "panicwait")
-	}
-
-	exit(0)
-	for {
-		var x *int32
-		*x = 0
-	}
-}
-
-var parkunlock_c byte
-
-// start forcegc helper goroutine
-func init() {
-	go forcegchelper()
-}
-
-func forcegchelper() {
-	forcegc.g = getg()
-	forcegc.g.issystem = true
-	for {
-		lock(&forcegc.lock)
-		if forcegc.idle != 0 {
-			gothrow("forcegc: phase error")
-		}
-		atomicstore(&forcegc.idle, 1)
-		goparkunlock(&forcegc.lock, "force gc (idle)")
-		// this goroutine is explicitly resumed by sysmon
-		if debug.gctrace > 0 {
-			println("GC forced")
-		}
-		gogc(1)
-	}
-}
-
-//go:nosplit
-
-// Gosched yields the processor, allowing other goroutines to run.  It does not
-// suspend the current goroutine, so execution resumes automatically.
-func Gosched() {
-	mcall(gosched_m)
-}
-
-// Puts the current goroutine into a waiting state and calls unlockf.
-// If unlockf returns false, the goroutine is resumed.
-func gopark(unlockf unsafe.Pointer, lock unsafe.Pointer, reason string) {
-	mp := acquirem()
-	gp := mp.curg
-	status := readgstatus(gp)
-	if status != _Grunning && status != _Gscanrunning {
-		gothrow("gopark: bad g status")
-	}
-	mp.waitlock = lock
-	mp.waitunlockf = unlockf
-	gp.waitreason = reason
-	releasem(mp)
-	// can't do anything that might move the G between Ms here.
-	mcall(park_m)
-}
-
-// Puts the current goroutine into a waiting state and unlocks the lock.
-// The goroutine can be made runnable again by calling goready(gp).
-func goparkunlock(lock *mutex, reason string) {
-	gopark(unsafe.Pointer(&parkunlock_c), unsafe.Pointer(lock), reason)
-}
-
-func goready(gp *g) {
-	mp := acquirem()
-	mp.ptrarg[0] = unsafe.Pointer(gp)
-	onM(ready_m)
-	releasem(mp)
-}
-
-//go:nosplit
-func acquireSudog() *sudog {
-	c := gomcache()
-	s := c.sudogcache
-	if s != nil {
-		if s.elem != nil {
-			gothrow("acquireSudog: found s.elem != nil in cache")
-		}
-		c.sudogcache = s.next
-		s.next = nil
-		return s
-	}
-
-	// Delicate dance: the semaphore implementation calls
-	// acquireSudog, acquireSudog calls new(sudog),
-	// new calls malloc, malloc can call the garbage collector,
-	// and the garbage collector calls the semaphore implementation
-	// in stoptheworld.
-	// Break the cycle by doing acquirem/releasem around new(sudog).
-	// The acquirem/releasem increments m.locks during new(sudog),
-	// which keeps the garbage collector from being invoked.
-	mp := acquirem()
-	p := new(sudog)
-	releasem(mp)
-	return p
-}
-
-//go:nosplit
-func releaseSudog(s *sudog) {
-	if s.elem != nil {
-		gothrow("runtime: sudog with non-nil elem")
-	}
-	if s.selectdone != nil {
-		gothrow("runtime: sudog with non-nil selectdone")
-	}
-	if s.next != nil {
-		gothrow("runtime: sudog with non-nil next")
-	}
-	if s.prev != nil {
-		gothrow("runtime: sudog with non-nil prev")
-	}
-	if s.waitlink != nil {
-		gothrow("runtime: sudog with non-nil waitlink")
-	}
-	gp := getg()
-	if gp.param != nil {
-		gothrow("runtime: releaseSudog with non-nil gp.param")
-	}
-	c := gomcache()
-	s.next = c.sudogcache
-	c.sudogcache = s
-}
-
-// funcPC returns the entry PC of the function f.
-// It assumes that f is a func value. Otherwise the behavior is undefined.
-//go:nosplit
-func funcPC(f interface{}) uintptr {
-	return **(**uintptr)(add(unsafe.Pointer(&f), ptrSize))
-}
-
-// called from assembly
-func badmcall(fn func(*g)) {
-	gothrow("runtime: mcall called on m->g0 stack")
-}
-
-func badmcall2(fn func(*g)) {
-	gothrow("runtime: mcall function returned")
-}
-
-func badreflectcall() {
-	panic("runtime: arg size to reflect.call more than 1GB")
-}
-
-func lockedOSThread() bool {
-	gp := getg()
-	return gp.lockedm != nil && gp.m.lockedg != nil
-}
-
-func newP() *p {
-	return new(p)
-}
-
-func newM() *m {
-	return new(m)
-}
-
-func newG() *g {
-	return new(g)
-}
-
-func allgadd(gp *g) {
-	if readgstatus(gp) == _Gidle {
-		gothrow("allgadd: bad status Gidle")
-	}
-
-	lock(&allglock)
-	allgs = append(allgs, gp)
-	allg = &allgs[0]
-	allglen = uintptr(len(allgs))
-	unlock(&allglock)
-}
diff --git a/third_party/gofrontend/libgo/go/runtime/proc_test.go b/third_party/gofrontend/libgo/go/runtime/proc_test.go
index 4f364dc..4350e8f 100644
--- a/third_party/gofrontend/libgo/go/runtime/proc_test.go
+++ b/third_party/gofrontend/libgo/go/runtime/proc_test.go
@@ -7,6 +7,8 @@
 import (
 	"math"
 	"runtime"
+	"runtime/debug"
+	"sync"
 	"sync/atomic"
 	"syscall"
 	"testing"
@@ -94,6 +96,10 @@
 }
 
 func TestGoroutineParallelism(t *testing.T) {
+	if runtime.NumCPU() == 1 {
+		// Takes too long, too easy to deadlock, etc.
+		t.Skip("skipping on uniprocessor")
+	}
 	P := 4
 	N := 10
 	if testing.Short() {
@@ -101,6 +107,10 @@
 		N = 3
 	}
 	defer runtime.GOMAXPROCS(runtime.GOMAXPROCS(P))
+	// If runtime triggers a forced GC during this test then it will deadlock,
+	// since the goroutines can't be stopped/preempted.
+	// Disable GC for this test (see issue #10958).
+	defer debug.SetGCPercent(debug.SetGCPercent(-1))
 	for try := 0; try < N; try++ {
 		done := make(chan bool)
 		x := uint32(0)
@@ -289,6 +299,98 @@
 }
 `
 
+func TestPingPongHog(t *testing.T) {
+	if testing.Short() {
+		t.Skip("skipping in -short mode")
+	}
+
+	defer runtime.GOMAXPROCS(runtime.GOMAXPROCS(1))
+	done := make(chan bool)
+	hogChan, lightChan := make(chan bool), make(chan bool)
+	hogCount, lightCount := 0, 0
+
+	run := func(limit int, counter *int, wake chan bool) {
+		for {
+			select {
+			case <-done:
+				return
+
+			case <-wake:
+				for i := 0; i < limit; i++ {
+					*counter++
+				}
+				wake <- true
+			}
+		}
+	}
+
+	// Start two co-scheduled hog goroutines.
+	for i := 0; i < 2; i++ {
+		go run(1e6, &hogCount, hogChan)
+	}
+
+	// Start two co-scheduled light goroutines.
+	for i := 0; i < 2; i++ {
+		go run(1e3, &lightCount, lightChan)
+	}
+
+	// Start goroutine pairs and wait for a few preemption rounds.
+	hogChan <- true
+	lightChan <- true
+	time.Sleep(100 * time.Millisecond)
+	close(done)
+	<-hogChan
+	<-lightChan
+
+	// Check that hogCount and lightCount are within a factor of
+	// 2, which indicates that both pairs of goroutines handed off
+	// the P within a time-slice to their buddy.
+	if hogCount > lightCount*2 || lightCount > hogCount*2 {
+		t.Fatalf("want hogCount/lightCount in [0.5, 2]; got %d/%d = %g", hogCount, lightCount, float64(hogCount)/float64(lightCount))
+	}
+}
+
+func BenchmarkPingPongHog(b *testing.B) {
+	defer runtime.GOMAXPROCS(runtime.GOMAXPROCS(1))
+
+	// Create a CPU hog
+	stop, done := make(chan bool), make(chan bool)
+	go func() {
+		for {
+			select {
+			case <-stop:
+				done <- true
+				return
+			default:
+			}
+		}
+	}()
+
+	// Ping-pong b.N times
+	ping, pong := make(chan bool), make(chan bool)
+	go func() {
+		for j := 0; j < b.N; j++ {
+			pong <- <-ping
+		}
+		close(stop)
+		done <- true
+	}()
+	go func() {
+		for i := 0; i < b.N; i++ {
+			ping <- <-pong
+		}
+		done <- true
+	}()
+	b.ResetTimer()
+	ping <- true // Start ping-pong
+	<-stop
+	b.StopTimer()
+	<-ping // Let last ponger exit
+	<-done // Make sure goroutines exit
+	<-done
+	<-done
+}
+
 func stackGrowthRecursive(i int) {
 	var pad [128]uint64
 	if i != 0 && pad[0] == 0 {
@@ -364,13 +466,17 @@
 	}
 }
 
+/*
 func TestSchedLocalQueue(t *testing.T) {
 	runtime.TestSchedLocalQueue1()
 }
+*/
 
+/*
 func TestSchedLocalQueueSteal(t *testing.T) {
 	runtime.TestSchedLocalQueueSteal1()
 }
+*/
 
 func benchmarkStackGrowth(b *testing.B, rec int) {
 	b.RunParallel(func(pb *testing.PB) {
@@ -414,6 +520,37 @@
 	}
 }
 
+func BenchmarkCreateGoroutinesCapture(b *testing.B) {
+	b.ReportAllocs()
+	for i := 0; i < b.N; i++ {
+		const N = 4
+		var wg sync.WaitGroup
+		wg.Add(N)
+		for i := 0; i < N; i++ {
+			i := i
+			go func() {
+				if i >= N {
+					b.Logf("bad") // just to capture b
+				}
+				wg.Done()
+			}()
+		}
+		wg.Wait()
+	}
+}
+
+func BenchmarkClosureCall(b *testing.B) {
+	sum := 0
+	off1 := 1
+	for i := 0; i < b.N; i++ {
+		off2 := 2
+		func() {
+			sum += i + off1 + off2
+		}()
+	}
+	_ = sum
+}
+
 type Matrix [][]float64
 
 func BenchmarkMatmult(b *testing.B) {
diff --git a/third_party/gofrontend/libgo/go/runtime/race0.go b/third_party/gofrontend/libgo/go/runtime/race0.go
deleted file mode 100644
index 5d90cc8..0000000
--- a/third_party/gofrontend/libgo/go/runtime/race0.go
+++ /dev/null
@@ -1,37 +0,0 @@
-// 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.
-
-// +build !race
-
-// Dummy race detection API, used when not built with -race.
-
-package runtime
-
-import (
-	"unsafe"
-)
-
-const raceenabled = false
-
-// Because raceenabled is false, none of these functions should be called.
-
-func raceReadObjectPC(t *_type, addr unsafe.Pointer, callerpc, pc uintptr)  { gothrow("race") }
-func raceWriteObjectPC(t *_type, addr unsafe.Pointer, callerpc, pc uintptr) { gothrow("race") }
-func raceinit()                                                             { gothrow("race") }
-func racefini()                                                             { gothrow("race") }
-func racemapshadow(addr unsafe.Pointer, size uintptr)                       { gothrow("race") }
-func racewritepc(addr unsafe.Pointer, callerpc, pc uintptr)                 { gothrow("race") }
-func racereadpc(addr unsafe.Pointer, callerpc, pc uintptr)                  { gothrow("race") }
-func racereadrangepc(addr unsafe.Pointer, sz, callerpc, pc uintptr)         { gothrow("race") }
-func racewriterangepc(addr unsafe.Pointer, sz, callerpc, pc uintptr)        { gothrow("race") }
-func raceacquire(addr unsafe.Pointer)                                       { gothrow("race") }
-func raceacquireg(gp *g, addr unsafe.Pointer)                               { gothrow("race") }
-func racerelease(addr unsafe.Pointer)                                       { gothrow("race") }
-func racereleaseg(gp *g, addr unsafe.Pointer)                               { gothrow("race") }
-func racereleasemerge(addr unsafe.Pointer)                                  { gothrow("race") }
-func racereleasemergeg(gp *g, addr unsafe.Pointer)                          { gothrow("race") }
-func racefingo()                                                            { gothrow("race") }
-func racemalloc(p unsafe.Pointer, sz uintptr)                               { gothrow("race") }
-func racegostart(pc uintptr) uintptr                                        { gothrow("race"); return 0 }
-func racegoend()                                                            { gothrow("race") }
diff --git a/third_party/gofrontend/libgo/go/runtime/rdebug.go b/third_party/gofrontend/libgo/go/runtime/rdebug.go
deleted file mode 100644
index e5e6911..0000000
--- a/third_party/gofrontend/libgo/go/runtime/rdebug.go
+++ /dev/null
@@ -1,37 +0,0 @@
-// 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.
-
-package runtime
-
-func setMaxStack(in int) (out int) {
-	out = int(maxstacksize)
-	maxstacksize = uintptr(in)
-	return out
-}
-
-func setGCPercent(in int32) (out int32) {
-	mp := acquirem()
-	mp.scalararg[0] = uintptr(int(in))
-	onM(setgcpercent_m)
-	out = int32(int(mp.scalararg[0]))
-	releasem(mp)
-	return out
-}
-
-func setPanicOnFault(new bool) (old bool) {
-	mp := acquirem()
-	old = mp.curg.paniconfault
-	mp.curg.paniconfault = new
-	releasem(mp)
-	return old
-}
-
-func setMaxThreads(in int) (out int) {
-	mp := acquirem()
-	mp.scalararg[0] = uintptr(in)
-	onM(setmaxthreads_m)
-	out = int(mp.scalararg[0])
-	releasem(mp)
-	return out
-}
diff --git a/third_party/gofrontend/libgo/go/runtime/rune.go b/third_party/gofrontend/libgo/go/runtime/rune.go
deleted file mode 100644
index a9f6835..0000000
--- a/third_party/gofrontend/libgo/go/runtime/rune.go
+++ /dev/null
@@ -1,219 +0,0 @@
-/*
- * The authors of this software are Rob Pike and Ken Thompson.
- *              Copyright (c) 2002 by Lucent Technologies.
- *              Portions Copyright 2009 The Go Authors. All rights reserved.
- * Permission to use, copy, modify, and distribute this software for any
- * purpose without fee is hereby granted, provided that this entire notice
- * is included in all copies of any software which is or includes a copy
- * or modification of this software and in all copies of the supporting
- * documentation for such software.
- * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED
- * WARRANTY.  IN PARTICULAR, NEITHER THE AUTHORS NOR LUCENT TECHNOLOGIES MAKE ANY
- * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY
- * OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE.
- */
-
-/*
- * This code is copied, with slight editing due to type differences,
- * from a subset of ../lib9/utf/rune.c
- */
-
-package runtime
-
-const (
-	bit1 = 7
-	bitx = 6
-	bit2 = 5
-	bit3 = 4
-	bit4 = 3
-	bit5 = 2
-
-	t1 = ((1 << (bit1 + 1)) - 1) ^ 0xFF /* 0000 0000 */
-	tx = ((1 << (bitx + 1)) - 1) ^ 0xFF /* 1000 0000 */
-	t2 = ((1 << (bit2 + 1)) - 1) ^ 0xFF /* 1100 0000 */
-	t3 = ((1 << (bit3 + 1)) - 1) ^ 0xFF /* 1110 0000 */
-	t4 = ((1 << (bit4 + 1)) - 1) ^ 0xFF /* 1111 0000 */
-	t5 = ((1 << (bit5 + 1)) - 1) ^ 0xFF /* 1111 1000 */
-
-	rune1 = (1 << (bit1 + 0*bitx)) - 1 /* 0000 0000 0111 1111 */
-	rune2 = (1 << (bit2 + 1*bitx)) - 1 /* 0000 0111 1111 1111 */
-	rune3 = (1 << (bit3 + 2*bitx)) - 1 /* 1111 1111 1111 1111 */
-	rune4 = (1 << (bit4 + 3*bitx)) - 1 /* 0001 1111 1111 1111 1111 1111 */
-
-	maskx = (1 << bitx) - 1 /* 0011 1111 */
-	testx = maskx ^ 0xFF    /* 1100 0000 */
-
-	runeerror = 0xFFFD
-	runeself  = 0x80
-
-	surrogateMin = 0xD800
-	surrogateMax = 0xDFFF
-
-	bad = runeerror
-
-	runemax = 0x10FFFF /* maximum rune value */
-)
-
-/*
- * Modified by Wei-Hwa Huang, Google Inc., on 2004-09-24
- * This is a slower but "safe" version of the old chartorune
- * that works on strings that are not necessarily null-terminated.
- *
- * If you know for sure that your string is null-terminated,
- * chartorune will be a bit faster.
- *
- * It is guaranteed not to attempt to access "length"
- * past the incoming pointer.  This is to avoid
- * possible access violations.  If the string appears to be
- * well-formed but incomplete (i.e., to get the whole Rune
- * we'd need to read past str+length) then we'll set the Rune
- * to Bad and return 0.
- *
- * Note that if we have decoding problems for other
- * reasons, we return 1 instead of 0.
- */
-func charntorune(s string) (rune, int) {
-	/* When we're not allowed to read anything */
-	if len(s) <= 0 {
-		return bad, 1
-	}
-
-	/*
-	 * one character sequence (7-bit value)
-	 *	00000-0007F => T1
-	 */
-	c := s[0]
-	if c < tx {
-		return rune(c), 1
-	}
-
-	// If we can't read more than one character we must stop
-	if len(s) <= 1 {
-		return bad, 1
-	}
-
-	/*
-	 * two character sequence (11-bit value)
-	 *	0080-07FF => t2 tx
-	 */
-	c1 := s[1] ^ tx
-	if (c1 & testx) != 0 {
-		return bad, 1
-	}
-	if c < t3 {
-		if c < t2 {
-			return bad, 1
-		}
-		l := ((rune(c) << bitx) | rune(c1)) & rune2
-		if l <= rune1 {
-			return bad, 1
-		}
-		return l, 2
-	}
-
-	// If we can't read more than two characters we must stop
-	if len(s) <= 2 {
-		return bad, 1
-	}
-
-	/*
-	 * three character sequence (16-bit value)
-	 *	0800-FFFF => t3 tx tx
-	 */
-	c2 := s[2] ^ tx
-	if (c2 & testx) != 0 {
-		return bad, 1
-	}
-	if c < t4 {
-		l := ((((rune(c) << bitx) | rune(c1)) << bitx) | rune(c2)) & rune3
-		if l <= rune2 {
-			return bad, 1
-		}
-		if surrogateMin <= l && l <= surrogateMax {
-			return bad, 1
-		}
-		return l, 3
-	}
-
-	if len(s) <= 3 {
-		return bad, 1
-	}
-
-	/*
-	 * four character sequence (21-bit value)
-	 *	10000-1FFFFF => t4 tx tx tx
-	 */
-	c3 := s[3] ^ tx
-	if (c3 & testx) != 0 {
-		return bad, 1
-	}
-	if c < t5 {
-		l := ((((((rune(c) << bitx) | rune(c1)) << bitx) | rune(c2)) << bitx) | rune(c3)) & rune4
-		if l <= rune3 || l > runemax {
-			return bad, 1
-		}
-		return l, 4
-	}
-
-	// Support for 5-byte or longer UTF-8 would go here, but
-	// since we don't have that, we'll just return bad.
-	return bad, 1
-}
-
-// runetochar converts r to bytes and writes the result to str.
-// returns the number of bytes generated.
-func runetochar(str []byte, r rune) int {
-	/* runes are signed, so convert to unsigned for range check. */
-	c := uint32(r)
-	/*
-	 * one character sequence
-	 *	00000-0007F => 00-7F
-	 */
-	if c <= rune1 {
-		str[0] = byte(c)
-		return 1
-	}
-	/*
-	 * two character sequence
-	 *	0080-07FF => t2 tx
-	 */
-	if c <= rune2 {
-		str[0] = byte(t2 | (c >> (1 * bitx)))
-		str[1] = byte(tx | (c & maskx))
-		return 2
-	}
-
-	/*
-	 * If the rune is out of range or a surrogate half, convert it to the error rune.
-	 * Do this test here because the error rune encodes to three bytes.
-	 * Doing it earlier would duplicate work, since an out of range
-	 * rune wouldn't have fit in one or two bytes.
-	 */
-	if c > runemax {
-		c = runeerror
-	}
-	if surrogateMin <= c && c <= surrogateMax {
-		c = runeerror
-	}
-
-	/*
-	 * three character sequence
-	 *	0800-FFFF => t3 tx tx
-	 */
-	if c <= rune3 {
-		str[0] = byte(t3 | (c >> (2 * bitx)))
-		str[1] = byte(tx | ((c >> (1 * bitx)) & maskx))
-		str[2] = byte(tx | (c & maskx))
-		return 3
-	}
-
-	/*
-	 * four character sequence (21-bit value)
-	 *     10000-1FFFFF => t4 tx tx tx
-	 */
-	str[0] = byte(t4 | (c >> (3 * bitx)))
-	str[1] = byte(tx | ((c >> (2 * bitx)) & maskx))
-	str[2] = byte(tx | ((c >> (1 * bitx)) & maskx))
-	str[3] = byte(tx | (c & maskx))
-	return 4
-}
diff --git a/third_party/gofrontend/libgo/go/runtime/runtime.go b/third_party/gofrontend/libgo/go/runtime/runtime.go
deleted file mode 100644
index 4e4e1d1..0000000
--- a/third_party/gofrontend/libgo/go/runtime/runtime.go
+++ /dev/null
@@ -1,60 +0,0 @@
-// Copyright 2009 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 runtime
-
-var ticks struct {
-	lock mutex
-	val  uint64
-}
-
-var tls0 [8]uintptr // available storage for m0's TLS; not necessarily used; opaque to GC
-
-// Note: Called by runtime/pprof in addition to runtime code.
-func tickspersecond() int64 {
-	r := int64(atomicload64(&ticks.val))
-	if r != 0 {
-		return r
-	}
-	lock(&ticks.lock)
-	r = int64(ticks.val)
-	if r == 0 {
-		t0 := nanotime()
-		c0 := cputicks()
-		usleep(100 * 1000)
-		t1 := nanotime()
-		c1 := cputicks()
-		if t1 == t0 {
-			t1++
-		}
-		r = (c1 - c0) * 1000 * 1000 * 1000 / (t1 - t0)
-		if r == 0 {
-			r++
-		}
-		atomicstore64(&ticks.val, uint64(r))
-	}
-	unlock(&ticks.lock)
-	return r
-}
-
-func makeStringSlice(n int) []string {
-	return make([]string, n)
-}
-
-// TODO: Move to parfor.go when parfor.c becomes parfor.go.
-func parforalloc(nthrmax uint32) *parfor {
-	return &parfor{
-		thr:     &make([]parforthread, nthrmax)[0],
-		nthrmax: nthrmax,
-	}
-}
-
-var envs []string
-var argslice []string
-
-// called from syscall
-func runtime_envs() []string { return envs }
-
-// called from os
-func runtime_args() []string { return argslice }
diff --git a/third_party/gofrontend/libgo/go/runtime/runtime_test.go b/third_party/gofrontend/libgo/go/runtime/runtime_test.go
index 88985a4..bb8ff71 100644
--- a/third_party/gofrontend/libgo/go/runtime/runtime_test.go
+++ b/third_party/gofrontend/libgo/go/runtime/runtime_test.go
@@ -6,13 +6,8 @@
 
 import (
 	"io"
-	// "io/ioutil"
-	// "os"
-	// "os/exec"
 	. "runtime"
 	"runtime/debug"
-	// "strconv"
-	// "strings"
 	"testing"
 	"unsafe"
 )
@@ -88,51 +83,6 @@
 	}
 }
 
-/* The go tool is not present in gccgo.
-
-// The profiling signal handler needs to know whether it is executing runtime.gogo.
-// The constant RuntimeGogoBytes in arch_*.h gives the size of the function;
-// we don't have a way to obtain it from the linker (perhaps someday).
-// Test that the constant matches the size determined by 'go tool nm -S'.
-// The value reported will include the padding between runtime.gogo and the
-// next function in memory. That's fine.
-func TestRuntimeGogoBytes(t *testing.T) {
-	switch GOOS {
-	case "android", "nacl":
-		t.Skipf("skipping on %s", GOOS)
-	}
-
-	dir, err := ioutil.TempDir("", "go-build")
-	if err != nil {
-		t.Fatalf("failed to create temp directory: %v", err)
-	}
-	defer os.RemoveAll(dir)
-
-	out, err := exec.Command("go", "build", "-o", dir+"/hello", "../../test/helloworld.go").CombinedOutput()
-	if err != nil {
-		t.Fatalf("building hello world: %v\n%s", err, out)
-	}
-
-	out, err = exec.Command("go", "tool", "nm", "-size", dir+"/hello").CombinedOutput()
-	if err != nil {
-		t.Fatalf("go tool nm: %v\n%s", err, out)
-	}
-
-	for _, line := range strings.Split(string(out), "\n") {
-		f := strings.Fields(line)
-		if len(f) == 4 && f[3] == "runtime.gogo" {
-			size, _ := strconv.Atoi(f[1])
-			if GogoBytes() != int32(size) {
-				t.Fatalf("RuntimeGogoBytes = %d, should be %d", GogoBytes(), size)
-			}
-			return
-		}
-	}
-
-	t.Fatalf("go tool nm did not report size for runtime.gogo")
-}
-*/
-
 // golang.org/issue/7063
 func TestStopCPUProfilingWithProfilerOff(t *testing.T) {
 	SetCPUProfileRate(0)
@@ -176,14 +126,6 @@
 }
 
 func TestSetPanicOnFault(t *testing.T) {
-	t.Skip("skipping for llgo due to lack of non-call exception support")
-
-	// This currently results in a fault in the signal trampoline on
-	// dragonfly/386 - see issue 7421.
-	if GOOS == "dragonfly" && GOARCH == "386" {
-		t.Skip("skipping test on dragonfly/386")
-	}
-
 	old := debug.SetPanicOnFault(true)
 	defer debug.SetPanicOnFault(old)
 
@@ -252,3 +194,112 @@
 		}
 	}
 }
+
+/*
+func TestTrailingZero(t *testing.T) {
+	// make sure we add padding for structs with trailing zero-sized fields
+	type T1 struct {
+		n int32
+		z [0]byte
+	}
+	if unsafe.Sizeof(T1{}) != 8 {
+		t.Errorf("sizeof(%#v)==%d, want 8", T1{}, unsafe.Sizeof(T1{}))
+	}
+	type T2 struct {
+		n int64
+		z struct{}
+	}
+	if unsafe.Sizeof(T2{}) != 8+unsafe.Sizeof(Uintreg(0)) {
+		t.Errorf("sizeof(%#v)==%d, want %d", T2{}, unsafe.Sizeof(T2{}), 8+unsafe.Sizeof(Uintreg(0)))
+	}
+	type T3 struct {
+		n byte
+		z [4]struct{}
+	}
+	if unsafe.Sizeof(T3{}) != 2 {
+		t.Errorf("sizeof(%#v)==%d, want 2", T3{}, unsafe.Sizeof(T3{}))
+	}
+	// make sure padding can double for both zerosize and alignment
+	type T4 struct {
+		a int32
+		b int16
+		c int8
+		z struct{}
+	}
+	if unsafe.Sizeof(T4{}) != 8 {
+		t.Errorf("sizeof(%#v)==%d, want 8", T4{}, unsafe.Sizeof(T4{}))
+	}
+	// make sure we don't pad a zero-sized thing
+	type T5 struct {
+	}
+	if unsafe.Sizeof(T5{}) != 0 {
+		t.Errorf("sizeof(%#v)==%d, want 0", T5{}, unsafe.Sizeof(T5{}))
+	}
+}
+*/
+
+func TestBadOpen(t *testing.T) {
+	if GOOS == "windows" || GOOS == "nacl" {
+		t.Skip("skipping OS that doesn't have open/read/write/close")
+	}
+	// make sure we get the correct error code if open fails.  Same for
+	// read/write/close on the resulting -1 fd.  See issue 10052.
+	nonfile := []byte("/notreallyafile")
+	fd := Open(&nonfile[0], 0, 0)
+	if fd != -1 {
+		t.Errorf("open(\"%s\")=%d, want -1", string(nonfile), fd)
+	}
+	var buf [32]byte
+	r := Read(-1, unsafe.Pointer(&buf[0]), int32(len(buf)))
+	if r != -1 {
+		t.Errorf("read()=%d, want -1", r)
+	}
+	w := Write(^uintptr(0), unsafe.Pointer(&buf[0]), int32(len(buf)))
+	if w != -1 {
+		t.Errorf("write()=%d, want -1", w)
+	}
+	c := Close(-1)
+	if c != -1 {
+		t.Errorf("close()=%d, want -1", c)
+	}
+}
+
+func TestAppendGrowth(t *testing.T) {
+	var x []int64
+	check := func(want int) {
+		if cap(x) != want {
+			t.Errorf("len=%d, cap=%d, want cap=%d", len(x), cap(x), want)
+		}
+	}
+
+	check(0)
+	want := 1
+	for i := 1; i <= 100; i++ {
+		x = append(x, 1)
+		check(want)
+		if i&(i-1) == 0 {
+			want = 2 * i
+		}
+	}
+}
+
+var One = []int64{1}
+
+func TestAppendSliceGrowth(t *testing.T) {
+	var x []int64
+	check := func(want int) {
+		if cap(x) != want {
+			t.Errorf("len=%d, cap=%d, want cap=%d", len(x), cap(x), want)
+		}
+	}
+
+	check(0)
+	want := 1
+	for i := 1; i <= 100; i++ {
+		x = append(x, One...)
+		check(want)
+		if i&(i-1) == 0 {
+			want = 2 * i
+		}
+	}
+}
diff --git a/third_party/gofrontend/libgo/go/runtime/runtime_unix_test.go b/third_party/gofrontend/libgo/go/runtime/runtime_unix_test.go
index 963de8c..cfec332 100644
--- a/third_party/gofrontend/libgo/go/runtime/runtime_unix_test.go
+++ b/third_party/gofrontend/libgo/go/runtime/runtime_unix_test.go
@@ -42,7 +42,7 @@
 	if testing.Short() {
 		max = 100
 	}
-	stk := make([]runtime.StackRecord, 100)
+	stk := make([]runtime.StackRecord, 128)
 	for n := 0; n < max; n++ {
 		_, ok := runtime.GoroutineProfile(stk)
 		if !ok {
diff --git a/third_party/gofrontend/libgo/go/runtime/select.go b/third_party/gofrontend/libgo/go/runtime/select.go
deleted file mode 100644
index f735a71..0000000
--- a/third_party/gofrontend/libgo/go/runtime/select.go
+++ /dev/null
@@ -1,651 +0,0 @@
-// Copyright 2009 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 runtime
-
-// This file contains the implementation of Go select statements.
-
-import "unsafe"
-
-const (
-	debugSelect = false
-)
-
-var (
-	chansendpc = funcPC(chansend)
-	chanrecvpc = funcPC(chanrecv)
-)
-
-func selectsize(size uintptr) uintptr {
-	selsize := unsafe.Sizeof(_select{}) +
-		(size-1)*unsafe.Sizeof(_select{}.scase[0]) +
-		size*unsafe.Sizeof(*_select{}.lockorder) +
-		size*unsafe.Sizeof(*_select{}.pollorder)
-	return round(selsize, _Int64Align)
-}
-
-func newselect(sel *_select, selsize int64, size int32) {
-	if selsize != int64(selectsize(uintptr(size))) {
-		print("runtime: bad select size ", selsize, ", want ", selectsize(uintptr(size)), "\n")
-		gothrow("bad select size")
-	}
-	sel.tcase = uint16(size)
-	sel.ncase = 0
-	sel.lockorder = (**hchan)(add(unsafe.Pointer(&sel.scase), uintptr(size)*unsafe.Sizeof(_select{}.scase[0])))
-	sel.pollorder = (*uint16)(add(unsafe.Pointer(sel.lockorder), uintptr(size)*unsafe.Sizeof(*_select{}.lockorder)))
-
-	if debugSelect {
-		print("newselect s=", sel, " size=", size, "\n")
-	}
-}
-
-//go:nosplit
-func selectsend(sel *_select, c *hchan, elem unsafe.Pointer) (selected bool) {
-	// nil cases do not compete
-	if c != nil {
-		selectsendImpl(sel, c, getcallerpc(unsafe.Pointer(&sel)), elem, uintptr(unsafe.Pointer(&selected))-uintptr(unsafe.Pointer(&sel)))
-	}
-	return
-}
-
-// cut in half to give stack a chance to split
-func selectsendImpl(sel *_select, c *hchan, pc uintptr, elem unsafe.Pointer, so uintptr) {
-	i := sel.ncase
-	if i >= sel.tcase {
-		gothrow("selectsend: too many cases")
-	}
-	sel.ncase = i + 1
-	cas := (*scase)(add(unsafe.Pointer(&sel.scase), uintptr(i)*unsafe.Sizeof(sel.scase[0])))
-
-	cas.pc = pc
-	cas._chan = c
-	cas.so = uint16(so)
-	cas.kind = _CaseSend
-	cas.elem = elem
-
-	if debugSelect {
-		print("selectsend s=", sel, " pc=", hex(cas.pc), " chan=", cas._chan, " so=", cas.so, "\n")
-	}
-}
-
-//go:nosplit
-func selectrecv(sel *_select, c *hchan, elem unsafe.Pointer) (selected bool) {
-	// nil cases do not compete
-	if c != nil {
-		selectrecvImpl(sel, c, getcallerpc(unsafe.Pointer(&sel)), elem, nil, uintptr(unsafe.Pointer(&selected))-uintptr(unsafe.Pointer(&sel)))
-	}
-	return
-}
-
-//go:nosplit
-func selectrecv2(sel *_select, c *hchan, elem unsafe.Pointer, received *bool) (selected bool) {
-	// nil cases do not compete
-	if c != nil {
-		selectrecvImpl(sel, c, getcallerpc(unsafe.Pointer(&sel)), elem, received, uintptr(unsafe.Pointer(&selected))-uintptr(unsafe.Pointer(&sel)))
-	}
-	return
-}
-
-func selectrecvImpl(sel *_select, c *hchan, pc uintptr, elem unsafe.Pointer, received *bool, so uintptr) {
-	i := sel.ncase
-	if i >= sel.tcase {
-		gothrow("selectrecv: too many cases")
-	}
-	sel.ncase = i + 1
-	cas := (*scase)(add(unsafe.Pointer(&sel.scase), uintptr(i)*unsafe.Sizeof(sel.scase[0])))
-	cas.pc = pc
-	cas._chan = c
-	cas.so = uint16(so)
-	cas.kind = _CaseRecv
-	cas.elem = elem
-	cas.receivedp = received
-
-	if debugSelect {
-		print("selectrecv s=", sel, " pc=", hex(cas.pc), " chan=", cas._chan, " so=", cas.so, "\n")
-	}
-}
-
-//go:nosplit
-func selectdefault(sel *_select) (selected bool) {
-	selectdefaultImpl(sel, getcallerpc(unsafe.Pointer(&sel)), uintptr(unsafe.Pointer(&selected))-uintptr(unsafe.Pointer(&sel)))
-	return
-}
-
-func selectdefaultImpl(sel *_select, callerpc uintptr, so uintptr) {
-	i := sel.ncase
-	if i >= sel.tcase {
-		gothrow("selectdefault: too many cases")
-	}
-	sel.ncase = i + 1
-	cas := (*scase)(add(unsafe.Pointer(&sel.scase), uintptr(i)*unsafe.Sizeof(sel.scase[0])))
-	cas.pc = callerpc
-	cas._chan = nil
-	cas.so = uint16(so)
-	cas.kind = _CaseDefault
-
-	if debugSelect {
-		print("selectdefault s=", sel, " pc=", hex(cas.pc), " so=", cas.so, "\n")
-	}
-}
-
-func sellock(sel *_select) {
-	lockslice := sliceStruct{unsafe.Pointer(sel.lockorder), int(sel.ncase), int(sel.ncase)}
-	lockorder := *(*[]*hchan)(unsafe.Pointer(&lockslice))
-	var c *hchan
-	for _, c0 := range lockorder {
-		if c0 != nil && c0 != c {
-			c = c0
-			lock(&c.lock)
-		}
-	}
-}
-
-func selunlock(sel *_select) {
-	// We must be very careful here to not touch sel after we have unlocked
-	// the last lock, because sel can be freed right after the last unlock.
-	// Consider the following situation.
-	// First M calls runtime·park() in runtime·selectgo() passing the sel.
-	// Once runtime·park() has unlocked the last lock, another M makes
-	// the G that calls select runnable again and schedules it for execution.
-	// When the G runs on another M, it locks all the locks and frees sel.
-	// Now if the first M touches sel, it will access freed memory.
-	n := int(sel.ncase)
-	r := 0
-	lockslice := sliceStruct{unsafe.Pointer(sel.lockorder), n, n}
-	lockorder := *(*[]*hchan)(unsafe.Pointer(&lockslice))
-	// skip the default case
-	if n > 0 && lockorder[0] == nil {
-		r = 1
-	}
-	for i := n - 1; i >= r; i-- {
-		c := lockorder[i]
-		if i > 0 && c == lockorder[i-1] {
-			continue // will unlock it on the next iteration
-		}
-		unlock(&c.lock)
-	}
-}
-
-func selparkcommit(gp *g, sel *_select) bool {
-	selunlock(sel)
-	return true
-}
-
-func block() {
-	gopark(nil, nil, "select (no cases)") // forever
-}
-
-// overwrites return pc on stack to signal which case of the select
-// to run, so cannot appear at the top of a split stack.
-//go:nosplit
-func selectgo(sel *_select) {
-	pc, offset := selectgoImpl(sel)
-	*(*bool)(add(unsafe.Pointer(&sel), uintptr(offset))) = true
-	setcallerpc(unsafe.Pointer(&sel), pc)
-}
-
-// selectgoImpl returns scase.pc and scase.so for the select
-// case which fired.
-func selectgoImpl(sel *_select) (uintptr, uint16) {
-	if debugSelect {
-		print("select: sel=", sel, "\n")
-	}
-
-	scaseslice := sliceStruct{unsafe.Pointer(&sel.scase), int(sel.ncase), int(sel.ncase)}
-	scases := *(*[]scase)(unsafe.Pointer(&scaseslice))
-
-	var t0 int64
-	if blockprofilerate > 0 {
-		t0 = cputicks()
-		for i := 0; i < int(sel.ncase); i++ {
-			scases[i].releasetime = -1
-		}
-	}
-
-	// The compiler rewrites selects that statically have
-	// only 0 or 1 cases plus default into simpler constructs.
-	// The only way we can end up with such small sel.ncase
-	// values here is for a larger select in which most channels
-	// have been nilled out.  The general code handles those
-	// cases correctly, and they are rare enough not to bother
-	// optimizing (and needing to test).
-
-	// generate permuted order
-	pollslice := sliceStruct{unsafe.Pointer(sel.pollorder), int(sel.ncase), int(sel.ncase)}
-	pollorder := *(*[]uint16)(unsafe.Pointer(&pollslice))
-	for i := 0; i < int(sel.ncase); i++ {
-		pollorder[i] = uint16(i)
-	}
-	for i := 1; i < int(sel.ncase); i++ {
-		o := pollorder[i]
-		j := int(fastrand1()) % (i + 1)
-		pollorder[i] = pollorder[j]
-		pollorder[j] = o
-	}
-
-	// sort the cases by Hchan address to get the locking order.
-	// simple heap sort, to guarantee n log n time and constant stack footprint.
-	lockslice := sliceStruct{unsafe.Pointer(sel.lockorder), int(sel.ncase), int(sel.ncase)}
-	lockorder := *(*[]*hchan)(unsafe.Pointer(&lockslice))
-	for i := 0; i < int(sel.ncase); i++ {
-		j := i
-		c := scases[j]._chan
-		for j > 0 && lockorder[(j-1)/2].sortkey() < c.sortkey() {
-			k := (j - 1) / 2
-			lockorder[j] = lockorder[k]
-			j = k
-		}
-		lockorder[j] = c
-	}
-	for i := int(sel.ncase) - 1; i >= 0; i-- {
-		c := lockorder[i]
-		lockorder[i] = lockorder[0]
-		j := 0
-		for {
-			k := j*2 + 1
-			if k >= i {
-				break
-			}
-			if k+1 < i && lockorder[k].sortkey() < lockorder[k+1].sortkey() {
-				k++
-			}
-			if c.sortkey() < lockorder[k].sortkey() {
-				lockorder[j] = lockorder[k]
-				j = k
-				continue
-			}
-			break
-		}
-		lockorder[j] = c
-	}
-	/*
-		for i := 0; i+1 < int(sel.ncase); i++ {
-			if lockorder[i].sortkey() > lockorder[i+1].sortkey() {
-				print("i=", i, " x=", lockorder[i], " y=", lockorder[i+1], "\n")
-				gothrow("select: broken sort")
-			}
-		}
-	*/
-
-	// lock all the channels involved in the select
-	sellock(sel)
-
-	var (
-		gp     *g
-		done   uint32
-		sg     *sudog
-		c      *hchan
-		k      *scase
-		sglist *sudog
-		sgnext *sudog
-	)
-
-loop:
-	// pass 1 - look for something already waiting
-	var dfl *scase
-	var cas *scase
-	for i := 0; i < int(sel.ncase); i++ {
-		cas = &scases[pollorder[i]]
-		c = cas._chan
-
-		switch cas.kind {
-		case _CaseRecv:
-			if c.dataqsiz > 0 {
-				if c.qcount > 0 {
-					goto asyncrecv
-				}
-			} else {
-				sg = c.sendq.dequeue()
-				if sg != nil {
-					goto syncrecv
-				}
-			}
-			if c.closed != 0 {
-				goto rclose
-			}
-
-		case _CaseSend:
-			if raceenabled {
-				racereadpc(unsafe.Pointer(c), cas.pc, chansendpc)
-			}
-			if c.closed != 0 {
-				goto sclose
-			}
-			if c.dataqsiz > 0 {
-				if c.qcount < c.dataqsiz {
-					goto asyncsend
-				}
-			} else {
-				sg = c.recvq.dequeue()
-				if sg != nil {
-					goto syncsend
-				}
-			}
-
-		case _CaseDefault:
-			dfl = cas
-		}
-	}
-
-	if dfl != nil {
-		selunlock(sel)
-		cas = dfl
-		goto retc
-	}
-
-	// pass 2 - enqueue on all chans
-	gp = getg()
-	done = 0
-	for i := 0; i < int(sel.ncase); i++ {
-		cas = &scases[pollorder[i]]
-		c = cas._chan
-		sg := acquireSudog()
-		sg.g = gp
-		// Note: selectdone is adjusted for stack copies in stack.c:adjustsudogs
-		sg.selectdone = (*uint32)(noescape(unsafe.Pointer(&done)))
-		sg.elem = cas.elem
-		sg.releasetime = 0
-		if t0 != 0 {
-			sg.releasetime = -1
-		}
-		sg.waitlink = gp.waiting
-		gp.waiting = sg
-
-		switch cas.kind {
-		case _CaseRecv:
-			c.recvq.enqueue(sg)
-
-		case _CaseSend:
-			c.sendq.enqueue(sg)
-		}
-	}
-
-	// wait for someone to wake us up
-	gp.param = nil
-	gopark(unsafe.Pointer(funcPC(selparkcommit)), unsafe.Pointer(sel), "select")
-
-	// someone woke us up
-	sellock(sel)
-	sg = (*sudog)(gp.param)
-	gp.param = nil
-
-	// pass 3 - dequeue from unsuccessful chans
-	// otherwise they stack up on quiet channels
-	// record the successful case, if any.
-	// We singly-linked up the SudoGs in case order, so when
-	// iterating through the linked list they are in reverse order.
-	cas = nil
-	sglist = gp.waiting
-	// Clear all selectdone and elem before unlinking from gp.waiting.
-	// They must be cleared before being put back into the sudog cache.
-	// Clear before unlinking, because if a stack copy happens after the unlink,
-	// they will not be updated, they will be left pointing to the old stack,
-	// which creates dangling pointers, which may be detected by the
-	// garbage collector.
-	for sg1 := gp.waiting; sg1 != nil; sg1 = sg1.waitlink {
-		sg1.selectdone = nil
-		sg1.elem = nil
-	}
-	gp.waiting = nil
-	for i := int(sel.ncase) - 1; i >= 0; i-- {
-		k = &scases[pollorder[i]]
-		if sglist.releasetime > 0 {
-			k.releasetime = sglist.releasetime
-		}
-		if sg == sglist {
-			cas = k
-		} else {
-			c = k._chan
-			if k.kind == _CaseSend {
-				c.sendq.dequeueSudoG(sglist)
-			} else {
-				c.recvq.dequeueSudoG(sglist)
-			}
-		}
-		sgnext = sglist.waitlink
-		sglist.waitlink = nil
-		releaseSudog(sglist)
-		sglist = sgnext
-	}
-
-	if cas == nil {
-		goto loop
-	}
-
-	c = cas._chan
-
-	if c.dataqsiz > 0 {
-		gothrow("selectgo: shouldn't happen")
-	}
-
-	if debugSelect {
-		print("wait-return: sel=", sel, " c=", c, " cas=", cas, " kind=", cas.kind, "\n")
-	}
-
-	if cas.kind == _CaseRecv {
-		if cas.receivedp != nil {
-			*cas.receivedp = true
-		}
-	}
-
-	if raceenabled {
-		if cas.kind == _CaseRecv && cas.elem != nil {
-			raceWriteObjectPC(c.elemtype, cas.elem, cas.pc, chanrecvpc)
-		} else if cas.kind == _CaseSend {
-			raceReadObjectPC(c.elemtype, cas.elem, cas.pc, chansendpc)
-		}
-	}
-
-	selunlock(sel)
-	goto retc
-
-asyncrecv:
-	// can receive from buffer
-	if raceenabled {
-		if cas.elem != nil {
-			raceWriteObjectPC(c.elemtype, cas.elem, cas.pc, chanrecvpc)
-		}
-		raceacquire(chanbuf(c, c.recvx))
-		racerelease(chanbuf(c, c.recvx))
-	}
-	if cas.receivedp != nil {
-		*cas.receivedp = true
-	}
-	if cas.elem != nil {
-		memmove(cas.elem, chanbuf(c, c.recvx), uintptr(c.elemsize))
-	}
-	memclr(chanbuf(c, c.recvx), uintptr(c.elemsize))
-	c.recvx++
-	if c.recvx == c.dataqsiz {
-		c.recvx = 0
-	}
-	c.qcount--
-	sg = c.sendq.dequeue()
-	if sg != nil {
-		gp = sg.g
-		selunlock(sel)
-		if sg.releasetime != 0 {
-			sg.releasetime = cputicks()
-		}
-		goready(gp)
-	} else {
-		selunlock(sel)
-	}
-	goto retc
-
-asyncsend:
-	// can send to buffer
-	if raceenabled {
-		raceacquire(chanbuf(c, c.sendx))
-		racerelease(chanbuf(c, c.sendx))
-		raceReadObjectPC(c.elemtype, cas.elem, cas.pc, chansendpc)
-	}
-	memmove(chanbuf(c, c.sendx), cas.elem, uintptr(c.elemsize))
-	c.sendx++
-	if c.sendx == c.dataqsiz {
-		c.sendx = 0
-	}
-	c.qcount++
-	sg = c.recvq.dequeue()
-	if sg != nil {
-		gp = sg.g
-		selunlock(sel)
-		if sg.releasetime != 0 {
-			sg.releasetime = cputicks()
-		}
-		goready(gp)
-	} else {
-		selunlock(sel)
-	}
-	goto retc
-
-syncrecv:
-	// can receive from sleeping sender (sg)
-	if raceenabled {
-		if cas.elem != nil {
-			raceWriteObjectPC(c.elemtype, cas.elem, cas.pc, chanrecvpc)
-		}
-		racesync(c, sg)
-	}
-	selunlock(sel)
-	if debugSelect {
-		print("syncrecv: sel=", sel, " c=", c, "\n")
-	}
-	if cas.receivedp != nil {
-		*cas.receivedp = true
-	}
-	if cas.elem != nil {
-		memmove(cas.elem, sg.elem, uintptr(c.elemsize))
-	}
-	sg.elem = nil
-	gp = sg.g
-	gp.param = unsafe.Pointer(sg)
-	if sg.releasetime != 0 {
-		sg.releasetime = cputicks()
-	}
-	goready(gp)
-	goto retc
-
-rclose:
-	// read at end of closed channel
-	selunlock(sel)
-	if cas.receivedp != nil {
-		*cas.receivedp = false
-	}
-	if cas.elem != nil {
-		memclr(cas.elem, uintptr(c.elemsize))
-	}
-	if raceenabled {
-		raceacquire(unsafe.Pointer(c))
-	}
-	goto retc
-
-syncsend:
-	// can send to sleeping receiver (sg)
-	if raceenabled {
-		raceReadObjectPC(c.elemtype, cas.elem, cas.pc, chansendpc)
-		racesync(c, sg)
-	}
-	selunlock(sel)
-	if debugSelect {
-		print("syncsend: sel=", sel, " c=", c, "\n")
-	}
-	if sg.elem != nil {
-		memmove(sg.elem, cas.elem, uintptr(c.elemsize))
-	}
-	sg.elem = nil
-	gp = sg.g
-	gp.param = unsafe.Pointer(sg)
-	if sg.releasetime != 0 {
-		sg.releasetime = cputicks()
-	}
-	goready(gp)
-
-retc:
-	if cas.releasetime > 0 {
-		blockevent(cas.releasetime-t0, 2)
-	}
-	return cas.pc, cas.so
-
-sclose:
-	// send on closed channel
-	selunlock(sel)
-	panic("send on closed channel")
-}
-
-func (c *hchan) sortkey() uintptr {
-	// TODO(khr): if we have a moving garbage collector, we'll need to
-	// change this function.
-	return uintptr(unsafe.Pointer(c))
-}
-
-// A runtimeSelect is a single case passed to rselect.
-// This must match ../reflect/value.go:/runtimeSelect
-type runtimeSelect struct {
-	dir selectDir
-	typ unsafe.Pointer // channel type (not used here)
-	ch  *hchan         // channel
-	val unsafe.Pointer // ptr to data (SendDir) or ptr to receive buffer (RecvDir)
-}
-
-// These values must match ../reflect/value.go:/SelectDir.
-type selectDir int
-
-const (
-	_             selectDir = iota
-	selectSend              // case Chan <- Send
-	selectRecv              // case <-Chan:
-	selectDefault           // default
-)
-
-func reflect_rselect(cases []runtimeSelect) (chosen int, recvOK bool) {
-	// flagNoScan is safe here, because all objects are also referenced from cases.
-	size := selectsize(uintptr(len(cases)))
-	sel := (*_select)(mallocgc(size, nil, flagNoScan))
-	newselect(sel, int64(size), int32(len(cases)))
-	r := new(bool)
-	for i := range cases {
-		rc := &cases[i]
-		switch rc.dir {
-		case selectDefault:
-			selectdefaultImpl(sel, uintptr(i), 0)
-		case selectSend:
-			if rc.ch == nil {
-				break
-			}
-			selectsendImpl(sel, rc.ch, uintptr(i), rc.val, 0)
-		case selectRecv:
-			if rc.ch == nil {
-				break
-			}
-			selectrecvImpl(sel, rc.ch, uintptr(i), rc.val, r, 0)
-		}
-	}
-
-	pc, _ := selectgoImpl(sel)
-	chosen = int(pc)
-	recvOK = *r
-	return
-}
-
-func (q *waitq) dequeueSudoG(s *sudog) {
-	var prevsgp *sudog
-	l := &q.first
-	for {
-		sgp := *l
-		if sgp == nil {
-			return
-		}
-		if sgp == s {
-			*l = sgp.next
-			if q.last == sgp {
-				q.last = prevsgp
-			}
-			s.next = nil
-			return
-		}
-		l = &sgp.next
-		prevsgp = sgp
-	}
-}
diff --git a/third_party/gofrontend/libgo/go/runtime/sema.go b/third_party/gofrontend/libgo/go/runtime/sema.go
deleted file mode 100644
index 26dbd30..0000000
--- a/third_party/gofrontend/libgo/go/runtime/sema.go
+++ /dev/null
@@ -1,275 +0,0 @@
-// Copyright 2009 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.
-
-// Semaphore implementation exposed to Go.
-// Intended use is provide a sleep and wakeup
-// primitive that can be used in the contended case
-// of other synchronization primitives.
-// Thus it targets the same goal as Linux's futex,
-// but it has much simpler semantics.
-//
-// That is, don't think of these as semaphores.
-// Think of them as a way to implement sleep and wakeup
-// such that every sleep is paired with a single wakeup,
-// even if, due to races, the wakeup happens before the sleep.
-//
-// See Mullender and Cox, ``Semaphores in Plan 9,''
-// http://swtch.com/semaphore.pdf
-
-package runtime
-
-import "unsafe"
-
-// Asynchronous semaphore for sync.Mutex.
-
-type semaRoot struct {
-	lock  mutex
-	head  *sudog
-	tail  *sudog
-	nwait uint32 // Number of waiters. Read w/o the lock.
-}
-
-// Prime to not correlate with any user patterns.
-const semTabSize = 251
-
-var semtable [semTabSize]struct {
-	root semaRoot
-	pad  [_CacheLineSize - unsafe.Sizeof(semaRoot{})]byte
-}
-
-// Called from sync/net packages.
-func asyncsemacquire(addr *uint32) {
-	semacquire(addr, true)
-}
-
-func asyncsemrelease(addr *uint32) {
-	semrelease(addr)
-}
-
-// Called from runtime.
-func semacquire(addr *uint32, profile bool) {
-	gp := getg()
-	if gp != gp.m.curg {
-		gothrow("semacquire not on the G stack")
-	}
-
-	// Easy case.
-	if cansemacquire(addr) {
-		return
-	}
-
-	// Harder case:
-	//	increment waiter count
-	//	try cansemacquire one more time, return if succeeded
-	//	enqueue itself as a waiter
-	//	sleep
-	//	(waiter descriptor is dequeued by signaler)
-	s := acquireSudog()
-	root := semroot(addr)
-	t0 := int64(0)
-	s.releasetime = 0
-	if profile && blockprofilerate > 0 {
-		t0 = cputicks()
-		s.releasetime = -1
-	}
-	for {
-		lock(&root.lock)
-		// Add ourselves to nwait to disable "easy case" in semrelease.
-		xadd(&root.nwait, 1)
-		// Check cansemacquire to avoid missed wakeup.
-		if cansemacquire(addr) {
-			xadd(&root.nwait, -1)
-			unlock(&root.lock)
-			break
-		}
-		// Any semrelease after the cansemacquire knows we're waiting
-		// (we set nwait above), so go to sleep.
-		root.queue(addr, s)
-		goparkunlock(&root.lock, "semacquire")
-		if cansemacquire(addr) {
-			break
-		}
-	}
-	if s.releasetime > 0 {
-		blockevent(int64(s.releasetime)-t0, 3)
-	}
-	releaseSudog(s)
-}
-
-func semrelease(addr *uint32) {
-	root := semroot(addr)
-	xadd(addr, 1)
-
-	// Easy case: no waiters?
-	// This check must happen after the xadd, to avoid a missed wakeup
-	// (see loop in semacquire).
-	if atomicload(&root.nwait) == 0 {
-		return
-	}
-
-	// Harder case: search for a waiter and wake it.
-	lock(&root.lock)
-	if atomicload(&root.nwait) == 0 {
-		// The count is already consumed by another goroutine,
-		// so no need to wake up another goroutine.
-		unlock(&root.lock)
-		return
-	}
-	s := root.head
-	for ; s != nil; s = s.next {
-		if s.elem == unsafe.Pointer(addr) {
-			xadd(&root.nwait, -1)
-			root.dequeue(s)
-			break
-		}
-	}
-	unlock(&root.lock)
-	if s != nil {
-		if s.releasetime != 0 {
-			s.releasetime = cputicks()
-		}
-		goready(s.g)
-	}
-}
-
-func semroot(addr *uint32) *semaRoot {
-	return &semtable[(uintptr(unsafe.Pointer(addr))>>3)%semTabSize].root
-}
-
-func cansemacquire(addr *uint32) bool {
-	for {
-		v := atomicload(addr)
-		if v == 0 {
-			return false
-		}
-		if cas(addr, v, v-1) {
-			return true
-		}
-	}
-}
-
-func (root *semaRoot) queue(addr *uint32, s *sudog) {
-	s.g = getg()
-	s.elem = unsafe.Pointer(addr)
-	s.next = nil
-	s.prev = root.tail
-	if root.tail != nil {
-		root.tail.next = s
-	} else {
-		root.head = s
-	}
-	root.tail = s
-}
-
-func (root *semaRoot) dequeue(s *sudog) {
-	if s.next != nil {
-		s.next.prev = s.prev
-	} else {
-		root.tail = s.prev
-	}
-	if s.prev != nil {
-		s.prev.next = s.next
-	} else {
-		root.head = s.next
-	}
-	s.elem = nil
-	s.next = nil
-	s.prev = nil
-}
-
-// Synchronous semaphore for sync.Cond.
-type syncSema struct {
-	lock mutex
-	head *sudog
-	tail *sudog
-}
-
-// Syncsemacquire waits for a pairing syncsemrelease on the same semaphore s.
-func syncsemacquire(s *syncSema) {
-	lock(&s.lock)
-	if s.head != nil && s.head.nrelease > 0 {
-		// Have pending release, consume it.
-		var wake *sudog
-		s.head.nrelease--
-		if s.head.nrelease == 0 {
-			wake = s.head
-			s.head = wake.next
-			if s.head == nil {
-				s.tail = nil
-			}
-		}
-		unlock(&s.lock)
-		if wake != nil {
-			wake.next = nil
-			goready(wake.g)
-		}
-	} else {
-		// Enqueue itself.
-		w := acquireSudog()
-		w.g = getg()
-		w.nrelease = -1
-		w.next = nil
-		w.releasetime = 0
-		t0 := int64(0)
-		if blockprofilerate > 0 {
-			t0 = cputicks()
-			w.releasetime = -1
-		}
-		if s.tail == nil {
-			s.head = w
-		} else {
-			s.tail.next = w
-		}
-		s.tail = w
-		goparkunlock(&s.lock, "semacquire")
-		if t0 != 0 {
-			blockevent(int64(w.releasetime)-t0, 2)
-		}
-		releaseSudog(w)
-	}
-}
-
-// Syncsemrelease waits for n pairing syncsemacquire on the same semaphore s.
-func syncsemrelease(s *syncSema, n uint32) {
-	lock(&s.lock)
-	for n > 0 && s.head != nil && s.head.nrelease < 0 {
-		// Have pending acquire, satisfy it.
-		wake := s.head
-		s.head = wake.next
-		if s.head == nil {
-			s.tail = nil
-		}
-		if wake.releasetime != 0 {
-			wake.releasetime = cputicks()
-		}
-		wake.next = nil
-		goready(wake.g)
-		n--
-	}
-	if n > 0 {
-		// enqueue itself
-		w := acquireSudog()
-		w.g = getg()
-		w.nrelease = int32(n)
-		w.next = nil
-		w.releasetime = 0
-		if s.tail == nil {
-			s.head = w
-		} else {
-			s.tail.next = w
-		}
-		s.tail = w
-		goparkunlock(&s.lock, "semarelease")
-		releaseSudog(w)
-	} else {
-		unlock(&s.lock)
-	}
-}
-
-func syncsemcheck(sz uintptr) {
-	if sz != unsafe.Sizeof(syncSema{}) {
-		print("runtime: bad syncSema size - sync=", sz, " runtime=", unsafe.Sizeof(syncSema{}), "\n")
-		gothrow("bad syncSema size")
-	}
-}
diff --git a/third_party/gofrontend/libgo/go/runtime/signal_unix.go b/third_party/gofrontend/libgo/go/runtime/signal_unix.go
deleted file mode 100644
index ba77b6e..0000000
--- a/third_party/gofrontend/libgo/go/runtime/signal_unix.go
+++ /dev/null
@@ -1,13 +0,0 @@
-// Copyright 2012 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 darwin dragonfly freebsd linux netbsd openbsd solaris
-
-package runtime
-
-func sigpipe()
-
-func os_sigpipe() {
-	onM(sigpipe)
-}
diff --git a/third_party/gofrontend/libgo/go/runtime/sigpanic_unix.go b/third_party/gofrontend/libgo/go/runtime/sigpanic_unix.go
deleted file mode 100644
index 6807985..0000000
--- a/third_party/gofrontend/libgo/go/runtime/sigpanic_unix.go
+++ /dev/null
@@ -1,40 +0,0 @@
-// 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.
-
-// +build darwin dragonfly freebsd linux netbsd openbsd solaris
-
-package runtime
-
-func signame(int32) *byte
-
-func sigpanic() {
-	g := getg()
-	if !canpanic(g) {
-		gothrow("unexpected signal during runtime execution")
-	}
-
-	switch g.sig {
-	case _SIGBUS:
-		if g.sigcode0 == _BUS_ADRERR && g.sigcode1 < 0x1000 || g.paniconfault {
-			panicmem()
-		}
-		print("unexpected fault address ", hex(g.sigcode1), "\n")
-		gothrow("fault")
-	case _SIGSEGV:
-		if (g.sigcode0 == 0 || g.sigcode0 == _SEGV_MAPERR || g.sigcode0 == _SEGV_ACCERR) && g.sigcode1 < 0x1000 || g.paniconfault {
-			panicmem()
-		}
-		print("unexpected fault address ", hex(g.sigcode1), "\n")
-		gothrow("fault")
-	case _SIGFPE:
-		switch g.sigcode0 {
-		case _FPE_INTDIV:
-			panicdivide()
-		case _FPE_INTOVF:
-			panicoverflow()
-		}
-		panicfloat()
-	}
-	panic(errorString(gostringnocopy(signame(g.sig))))
-}
diff --git a/third_party/gofrontend/libgo/go/runtime/sigqueue.go b/third_party/gofrontend/libgo/go/runtime/sigqueue.go
deleted file mode 100644
index fed4560..0000000
--- a/third_party/gofrontend/libgo/go/runtime/sigqueue.go
+++ /dev/null
@@ -1,182 +0,0 @@
-// Copyright 2009 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.
-
-// This file implements runtime support for signal handling.
-//
-// Most synchronization primitives are not available from
-// the signal handler (it cannot block, allocate memory, or use locks)
-// so the handler communicates with a processing goroutine
-// via struct sig, below.
-//
-// sigsend is called by the signal handler to queue a new signal.
-// signal_recv is called by the Go program to receive a newly queued signal.
-// Synchronization between sigsend and signal_recv is based on the sig.state
-// variable.  It can be in 3 states: sigIdle, sigReceiving and sigSending.
-// sigReceiving means that signal_recv is blocked on sig.Note and there are no
-// new pending signals.
-// sigSending means that sig.mask *may* contain new pending signals,
-// signal_recv can't be blocked in this state.
-// sigIdle means that there are no new pending signals and signal_recv is not blocked.
-// Transitions between states are done atomically with CAS.
-// When signal_recv is unblocked, it resets sig.Note and rechecks sig.mask.
-// If several sigsends and signal_recv execute concurrently, it can lead to
-// unnecessary rechecks of sig.mask, but it cannot lead to missed signals
-// nor deadlocks.
-
-package runtime
-
-import "unsafe"
-
-var sig struct {
-	note   note
-	mask   [(_NSIG + 31) / 32]uint32
-	wanted [(_NSIG + 31) / 32]uint32
-	recv   [(_NSIG + 31) / 32]uint32
-	state  uint32
-	inuse  bool
-}
-
-const (
-	sigIdle = iota
-	sigReceiving
-	sigSending
-)
-
-// Called from sighandler to send a signal back out of the signal handling thread.
-// Reports whether the signal was sent. If not, the caller typically crashes the program.
-func sigsend(s int32) bool {
-	bit := uint32(1) << uint(s&31)
-	if !sig.inuse || s < 0 || int(s) >= 32*len(sig.wanted) || sig.wanted[s/32]&bit == 0 {
-		return false
-	}
-
-	// Add signal to outgoing queue.
-	for {
-		mask := sig.mask[s/32]
-		if mask&bit != 0 {
-			return true // signal already in queue
-		}
-		if cas(&sig.mask[s/32], mask, mask|bit) {
-			break
-		}
-	}
-
-	// Notify receiver that queue has new bit.
-Send:
-	for {
-		switch atomicload(&sig.state) {
-		default:
-			gothrow("sigsend: inconsistent state")
-		case sigIdle:
-			if cas(&sig.state, sigIdle, sigSending) {
-				break Send
-			}
-		case sigSending:
-			// notification already pending
-			break Send
-		case sigReceiving:
-			if cas(&sig.state, sigReceiving, sigIdle) {
-				notewakeup(&sig.note)
-				break Send
-			}
-		}
-	}
-
-	return true
-}
-
-// Called to receive the next queued signal.
-// Must only be called from a single goroutine at a time.
-func signal_recv() uint32 {
-	for {
-		// Serve any signals from local copy.
-		for i := uint32(0); i < _NSIG; i++ {
-			if sig.recv[i/32]&(1<<(i&31)) != 0 {
-				sig.recv[i/32] &^= 1 << (i & 31)
-				return i
-			}
-		}
-
-		// Wait for updates to be available from signal sender.
-	Receive:
-		for {
-			switch atomicload(&sig.state) {
-			default:
-				gothrow("signal_recv: inconsistent state")
-			case sigIdle:
-				if cas(&sig.state, sigIdle, sigReceiving) {
-					notetsleepg(&sig.note, -1)
-					noteclear(&sig.note)
-					break Receive
-				}
-			case sigSending:
-				if cas(&sig.state, sigSending, sigIdle) {
-					break Receive
-				}
-			}
-		}
-
-		// Incorporate updates from sender into local copy.
-		for i := range sig.mask {
-			sig.recv[i] = xchg(&sig.mask[i], 0)
-		}
-	}
-}
-
-// Must only be called from a single goroutine at a time.
-func signal_enable(s uint32) {
-	if !sig.inuse {
-		// The first call to signal_enable is for us
-		// to use for initialization.  It does not pass
-		// signal information in m.
-		sig.inuse = true // enable reception of signals; cannot disable
-		noteclear(&sig.note)
-		return
-	}
-
-	if int(s) >= len(sig.wanted)*32 {
-		return
-	}
-	sig.wanted[s/32] |= 1 << (s & 31)
-	sigenable_go(s)
-}
-
-// Must only be called from a single goroutine at a time.
-func signal_disable(s uint32) {
-	if int(s) >= len(sig.wanted)*32 {
-		return
-	}
-	sig.wanted[s/32] &^= 1 << (s & 31)
-	sigdisable_go(s)
-}
-
-// This runs on a foreign stack, without an m or a g.  No stack split.
-//go:nosplit
-func badsignal(sig uintptr) {
-	// Some external libraries, for example, OpenBLAS, create worker threads in
-	// a global constructor. If we're doing cpu profiling, and the SIGPROF signal
-	// comes to one of the foreign threads before we make our first cgo call, the
-	// call to cgocallback below will bring down the whole process.
-	// It's better to miss a few SIGPROF signals than to abort in this case.
-	// See http://golang.org/issue/9456.
-	if _SIGPROF != 0 && sig == _SIGPROF && needextram != 0 {
-		return
-	}
-	cgocallback(unsafe.Pointer(funcPC(sigsend)), noescape(unsafe.Pointer(&sig)), unsafe.Sizeof(sig))
-}
-
-func sigenable_m()
-func sigdisable_m()
-
-func sigenable_go(s uint32) {
-	g := getg()
-	g.m.scalararg[0] = uintptr(s)
-	onM(sigenable_m)
-}
-
-func sigdisable_go(s uint32) {
-	g := getg()
-	g.m.scalararg[0] = uintptr(s)
-	onM(sigdisable_m)
-}
diff --git a/third_party/gofrontend/libgo/go/runtime/slice.go b/third_party/gofrontend/libgo/go/runtime/slice.go
deleted file mode 100644
index 171087d..0000000
--- a/third_party/gofrontend/libgo/go/runtime/slice.go
+++ /dev/null
@@ -1,139 +0,0 @@
-// Copyright 2009 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 runtime
-
-import (
-	"unsafe"
-)
-
-type sliceStruct struct {
-	array unsafe.Pointer
-	len   int
-	cap   int
-}
-
-// TODO: take uintptrs instead of int64s?
-func makeslice(t *slicetype, len64 int64, cap64 int64) sliceStruct {
-	// NOTE: The len > MaxMem/elemsize check here is not strictly necessary,
-	// but it produces a 'len out of range' error instead of a 'cap out of range' error
-	// when someone does make([]T, bignumber). 'cap out of range' is true too,
-	// but since the cap is only being supplied implicitly, saying len is clearer.
-	// See issue 4085.
-	len := int(len64)
-	if len64 < 0 || int64(len) != len64 || t.elem.size > 0 && uintptr(len) > maxmem/uintptr(t.elem.size) {
-		panic(errorString("makeslice: len out of range"))
-	}
-	cap := int(cap64)
-	if cap < len || int64(cap) != cap64 || t.elem.size > 0 && uintptr(cap) > maxmem/uintptr(t.elem.size) {
-		panic(errorString("makeslice: cap out of range"))
-	}
-	p := newarray(t.elem, uintptr(cap))
-	return sliceStruct{p, len, cap}
-}
-
-// TODO: take uintptr instead of int64?
-func growslice(t *slicetype, old sliceStruct, n int64) sliceStruct {
-	if n < 1 {
-		panic(errorString("growslice: invalid n"))
-	}
-
-	cap64 := int64(old.cap) + n
-	cap := int(cap64)
-
-	if int64(cap) != cap64 || cap < old.cap || t.elem.size > 0 && uintptr(cap) > maxmem/uintptr(t.elem.size) {
-		panic(errorString("growslice: cap out of range"))
-	}
-
-	if raceenabled {
-		callerpc := getcallerpc(unsafe.Pointer(&t))
-		racereadrangepc(old.array, uintptr(old.len*int(t.elem.size)), callerpc, funcPC(growslice))
-	}
-
-	et := t.elem
-	if et.size == 0 {
-		return sliceStruct{old.array, old.len, cap}
-	}
-
-	newcap := old.cap
-	if newcap+newcap < cap {
-		newcap = cap
-	} else {
-		for {
-			if old.len < 1024 {
-				newcap += newcap
-			} else {
-				newcap += newcap / 4
-			}
-			if newcap >= cap {
-				break
-			}
-		}
-	}
-
-	if uintptr(newcap) >= maxmem/uintptr(et.size) {
-		panic(errorString("growslice: cap out of range"))
-	}
-	lenmem := uintptr(old.len) * uintptr(et.size)
-	capmem := goroundupsize(uintptr(newcap) * uintptr(et.size))
-	newcap = int(capmem / uintptr(et.size))
-	var p unsafe.Pointer
-	if et.kind&kindNoPointers != 0 {
-		p = rawmem(capmem)
-		memclr(add(p, lenmem), capmem-lenmem)
-	} else {
-		// Note: can't use rawmem (which avoids zeroing of memory), because then GC can scan unitialized memory
-		p = newarray(et, uintptr(newcap))
-	}
-	memmove(p, old.array, lenmem)
-
-	return sliceStruct{p, old.len, newcap}
-}
-
-func slicecopy(to sliceStruct, fm sliceStruct, width uintptr) int {
-	if fm.len == 0 || to.len == 0 || width == 0 {
-		return 0
-	}
-
-	n := fm.len
-	if to.len < n {
-		n = to.len
-	}
-
-	if raceenabled {
-		callerpc := getcallerpc(unsafe.Pointer(&to))
-		pc := funcPC(slicecopy)
-		racewriterangepc(to.array, uintptr(n*int(width)), callerpc, pc)
-		racereadrangepc(fm.array, uintptr(n*int(width)), callerpc, pc)
-	}
-
-	size := uintptr(n) * width
-	if size == 1 { // common case worth about 2x to do here
-		// TODO: is this still worth it with new memmove impl?
-		*(*byte)(to.array) = *(*byte)(fm.array) // known to be a byte pointer
-	} else {
-		memmove(to.array, fm.array, size)
-	}
-	return int(n)
-}
-
-func slicestringcopy(to []byte, fm string) int {
-	if len(fm) == 0 || len(to) == 0 {
-		return 0
-	}
-
-	n := len(fm)
-	if len(to) < n {
-		n = len(to)
-	}
-
-	if raceenabled {
-		callerpc := getcallerpc(unsafe.Pointer(&to))
-		pc := funcPC(slicestringcopy)
-		racewriterangepc(unsafe.Pointer(&to[0]), uintptr(n), callerpc, pc)
-	}
-
-	memmove(unsafe.Pointer(&to[0]), unsafe.Pointer((*stringStruct)(unsafe.Pointer(&fm)).str), uintptr(n))
-	return n
-}
diff --git a/third_party/gofrontend/libgo/go/runtime/softfloat64.go b/third_party/gofrontend/libgo/go/runtime/softfloat64.go
deleted file mode 100644
index 4fcf8f2..0000000
--- a/third_party/gofrontend/libgo/go/runtime/softfloat64.go
+++ /dev/null
@@ -1,498 +0,0 @@
-// Copyright 2010 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.
-
-// Software IEEE754 64-bit floating point.
-// Only referred to (and thus linked in) by arm port
-// and by tests in this directory.
-
-package runtime
-
-const (
-	mantbits64 uint = 52
-	expbits64  uint = 11
-	bias64          = -1<<(expbits64-1) + 1
-
-	nan64 uint64 = (1<<expbits64-1)<<mantbits64 + 1
-	inf64 uint64 = (1<<expbits64 - 1) << mantbits64
-	neg64 uint64 = 1 << (expbits64 + mantbits64)
-
-	mantbits32 uint = 23
-	expbits32  uint = 8
-	bias32          = -1<<(expbits32-1) + 1
-
-	nan32 uint32 = (1<<expbits32-1)<<mantbits32 + 1
-	inf32 uint32 = (1<<expbits32 - 1) << mantbits32
-	neg32 uint32 = 1 << (expbits32 + mantbits32)
-)
-
-func funpack64(f uint64) (sign, mant uint64, exp int, inf, nan bool) {
-	sign = f & (1 << (mantbits64 + expbits64))
-	mant = f & (1<<mantbits64 - 1)
-	exp = int(f>>mantbits64) & (1<<expbits64 - 1)
-
-	switch exp {
-	case 1<<expbits64 - 1:
-		if mant != 0 {
-			nan = true
-			return
-		}
-		inf = true
-		return
-
-	case 0:
-		// denormalized
-		if mant != 0 {
-			exp += bias64 + 1
-			for mant < 1<<mantbits64 {
-				mant <<= 1
-				exp--
-			}
-		}
-
-	default:
-		// add implicit top bit
-		mant |= 1 << mantbits64
-		exp += bias64
-	}
-	return
-}
-
-func funpack32(f uint32) (sign, mant uint32, exp int, inf, nan bool) {
-	sign = f & (1 << (mantbits32 + expbits32))
-	mant = f & (1<<mantbits32 - 1)
-	exp = int(f>>mantbits32) & (1<<expbits32 - 1)
-
-	switch exp {
-	case 1<<expbits32 - 1:
-		if mant != 0 {
-			nan = true
-			return
-		}
-		inf = true
-		return
-
-	case 0:
-		// denormalized
-		if mant != 0 {
-			exp += bias32 + 1
-			for mant < 1<<mantbits32 {
-				mant <<= 1
-				exp--
-			}
-		}
-
-	default:
-		// add implicit top bit
-		mant |= 1 << mantbits32
-		exp += bias32
-	}
-	return
-}
-
-func fpack64(sign, mant uint64, exp int, trunc uint64) uint64 {
-	mant0, exp0, trunc0 := mant, exp, trunc
-	if mant == 0 {
-		return sign
-	}
-	for mant < 1<<mantbits64 {
-		mant <<= 1
-		exp--
-	}
-	for mant >= 4<<mantbits64 {
-		trunc |= mant & 1
-		mant >>= 1
-		exp++
-	}
-	if mant >= 2<<mantbits64 {
-		if mant&1 != 0 && (trunc != 0 || mant&2 != 0) {
-			mant++
-			if mant >= 4<<mantbits64 {
-				mant >>= 1
-				exp++
-			}
-		}
-		mant >>= 1
-		exp++
-	}
-	if exp >= 1<<expbits64-1+bias64 {
-		return sign ^ inf64
-	}
-	if exp < bias64+1 {
-		if exp < bias64-int(mantbits64) {
-			return sign | 0
-		}
-		// repeat expecting denormal
-		mant, exp, trunc = mant0, exp0, trunc0
-		for exp < bias64 {
-			trunc |= mant & 1
-			mant >>= 1
-			exp++
-		}
-		if mant&1 != 0 && (trunc != 0 || mant&2 != 0) {
-			mant++
-		}
-		mant >>= 1
-		exp++
-		if mant < 1<<mantbits64 {
-			return sign | mant
-		}
-	}
-	return sign | uint64(exp-bias64)<<mantbits64 | mant&(1<<mantbits64-1)
-}
-
-func fpack32(sign, mant uint32, exp int, trunc uint32) uint32 {
-	mant0, exp0, trunc0 := mant, exp, trunc
-	if mant == 0 {
-		return sign
-	}
-	for mant < 1<<mantbits32 {
-		mant <<= 1
-		exp--
-	}
-	for mant >= 4<<mantbits32 {
-		trunc |= mant & 1
-		mant >>= 1
-		exp++
-	}
-	if mant >= 2<<mantbits32 {
-		if mant&1 != 0 && (trunc != 0 || mant&2 != 0) {
-			mant++
-			if mant >= 4<<mantbits32 {
-				mant >>= 1
-				exp++
-			}
-		}
-		mant >>= 1
-		exp++
-	}
-	if exp >= 1<<expbits32-1+bias32 {
-		return sign ^ inf32
-	}
-	if exp < bias32+1 {
-		if exp < bias32-int(mantbits32) {
-			return sign | 0
-		}
-		// repeat expecting denormal
-		mant, exp, trunc = mant0, exp0, trunc0
-		for exp < bias32 {
-			trunc |= mant & 1
-			mant >>= 1
-			exp++
-		}
-		if mant&1 != 0 && (trunc != 0 || mant&2 != 0) {
-			mant++
-		}
-		mant >>= 1
-		exp++
-		if mant < 1<<mantbits32 {
-			return sign | mant
-		}
-	}
-	return sign | uint32(exp-bias32)<<mantbits32 | mant&(1<<mantbits32-1)
-}
-
-func fadd64(f, g uint64) uint64 {
-	fs, fm, fe, fi, fn := funpack64(f)
-	gs, gm, ge, gi, gn := funpack64(g)
-
-	// Special cases.
-	switch {
-	case fn || gn: // NaN + x or x + NaN = NaN
-		return nan64
-
-	case fi && gi && fs != gs: // +Inf + -Inf or -Inf + +Inf = NaN
-		return nan64
-
-	case fi: // ±Inf + g = ±Inf
-		return f
-
-	case gi: // f + ±Inf = ±Inf
-		return g
-
-	case fm == 0 && gm == 0 && fs != 0 && gs != 0: // -0 + -0 = -0
-		return f
-
-	case fm == 0: // 0 + g = g but 0 + -0 = +0
-		if gm == 0 {
-			g ^= gs
-		}
-		return g
-
-	case gm == 0: // f + 0 = f
-		return f
-
-	}
-
-	if fe < ge || fe == ge && fm < gm {
-		f, g, fs, fm, fe, gs, gm, ge = g, f, gs, gm, ge, fs, fm, fe
-	}
-
-	shift := uint(fe - ge)
-	fm <<= 2
-	gm <<= 2
-	trunc := gm & (1<<shift - 1)
-	gm >>= shift
-	if fs == gs {
-		fm += gm
-	} else {
-		fm -= gm
-		if trunc != 0 {
-			fm--
-		}
-	}
-	if fm == 0 {
-		fs = 0
-	}
-	return fpack64(fs, fm, fe-2, trunc)
-}
-
-func fsub64(f, g uint64) uint64 {
-	return fadd64(f, fneg64(g))
-}
-
-func fneg64(f uint64) uint64 {
-	return f ^ (1 << (mantbits64 + expbits64))
-}
-
-func fmul64(f, g uint64) uint64 {
-	fs, fm, fe, fi, fn := funpack64(f)
-	gs, gm, ge, gi, gn := funpack64(g)
-
-	// Special cases.
-	switch {
-	case fn || gn: // NaN * g or f * NaN = NaN
-		return nan64
-
-	case fi && gi: // Inf * Inf = Inf (with sign adjusted)
-		return f ^ gs
-
-	case fi && gm == 0, fm == 0 && gi: // 0 * Inf = Inf * 0 = NaN
-		return nan64
-
-	case fm == 0: // 0 * x = 0 (with sign adjusted)
-		return f ^ gs
-
-	case gm == 0: // x * 0 = 0 (with sign adjusted)
-		return g ^ fs
-	}
-
-	// 53-bit * 53-bit = 107- or 108-bit
-	lo, hi := mullu(fm, gm)
-	shift := mantbits64 - 1
-	trunc := lo & (1<<shift - 1)
-	mant := hi<<(64-shift) | lo>>shift
-	return fpack64(fs^gs, mant, fe+ge-1, trunc)
-}
-
-func fdiv64(f, g uint64) uint64 {
-	fs, fm, fe, fi, fn := funpack64(f)
-	gs, gm, ge, gi, gn := funpack64(g)
-
-	// Special cases.
-	switch {
-	case fn || gn: // NaN / g = f / NaN = NaN
-		return nan64
-
-	case fi && gi: // ±Inf / ±Inf = NaN
-		return nan64
-
-	case !fi && !gi && fm == 0 && gm == 0: // 0 / 0 = NaN
-		return nan64
-
-	case fi, !gi && gm == 0: // Inf / g = f / 0 = Inf
-		return fs ^ gs ^ inf64
-
-	case gi, fm == 0: // f / Inf = 0 / g = Inf
-		return fs ^ gs ^ 0
-	}
-	_, _, _, _ = fi, fn, gi, gn
-
-	// 53-bit<<54 / 53-bit = 53- or 54-bit.
-	shift := mantbits64 + 2
-	q, r := divlu(fm>>(64-shift), fm<<shift, gm)
-	return fpack64(fs^gs, q, fe-ge-2, r)
-}
-
-func f64to32(f uint64) uint32 {
-	fs, fm, fe, fi, fn := funpack64(f)
-	if fn {
-		return nan32
-	}
-	fs32 := uint32(fs >> 32)
-	if fi {
-		return fs32 ^ inf32
-	}
-	const d = mantbits64 - mantbits32 - 1
-	return fpack32(fs32, uint32(fm>>d), fe-1, uint32(fm&(1<<d-1)))
-}
-
-func f32to64(f uint32) uint64 {
-	const d = mantbits64 - mantbits32
-	fs, fm, fe, fi, fn := funpack32(f)
-	if fn {
-		return nan64
-	}
-	fs64 := uint64(fs) << 32
-	if fi {
-		return fs64 ^ inf64
-	}
-	return fpack64(fs64, uint64(fm)<<d, fe, 0)
-}
-
-func fcmp64(f, g uint64) (cmp int, isnan bool) {
-	fs, fm, _, fi, fn := funpack64(f)
-	gs, gm, _, gi, gn := funpack64(g)
-
-	switch {
-	case fn, gn: // flag NaN
-		return 0, true
-
-	case !fi && !gi && fm == 0 && gm == 0: // ±0 == ±0
-		return 0, false
-
-	case fs > gs: // f < 0, g > 0
-		return -1, false
-
-	case fs < gs: // f > 0, g < 0
-		return +1, false
-
-	// Same sign, not NaN.
-	// Can compare encodings directly now.
-	// Reverse for sign.
-	case fs == 0 && f < g, fs != 0 && f > g:
-		return -1, false
-
-	case fs == 0 && f > g, fs != 0 && f < g:
-		return +1, false
-	}
-
-	// f == g
-	return 0, false
-}
-
-func f64toint(f uint64) (val int64, ok bool) {
-	fs, fm, fe, fi, fn := funpack64(f)
-
-	switch {
-	case fi, fn: // NaN
-		return 0, false
-
-	case fe < -1: // f < 0.5
-		return 0, false
-
-	case fe > 63: // f >= 2^63
-		if fs != 0 && fm == 0 { // f == -2^63
-			return -1 << 63, true
-		}
-		if fs != 0 {
-			return 0, false
-		}
-		return 0, false
-	}
-
-	for fe > int(mantbits64) {
-		fe--
-		fm <<= 1
-	}
-	for fe < int(mantbits64) {
-		fe++
-		fm >>= 1
-	}
-	val = int64(fm)
-	if fs != 0 {
-		val = -val
-	}
-	return val, true
-}
-
-func fintto64(val int64) (f uint64) {
-	fs := uint64(val) & (1 << 63)
-	mant := uint64(val)
-	if fs != 0 {
-		mant = -mant
-	}
-	return fpack64(fs, mant, int(mantbits64), 0)
-}
-
-// 64x64 -> 128 multiply.
-// adapted from hacker's delight.
-func mullu(u, v uint64) (lo, hi uint64) {
-	const (
-		s    = 32
-		mask = 1<<s - 1
-	)
-	u0 := u & mask
-	u1 := u >> s
-	v0 := v & mask
-	v1 := v >> s
-	w0 := u0 * v0
-	t := u1*v0 + w0>>s
-	w1 := t & mask
-	w2 := t >> s
-	w1 += u0 * v1
-	return u * v, u1*v1 + w2 + w1>>s
-}
-
-// 128/64 -> 64 quotient, 64 remainder.
-// adapted from hacker's delight
-func divlu(u1, u0, v uint64) (q, r uint64) {
-	const b = 1 << 32
-
-	if u1 >= v {
-		return 1<<64 - 1, 1<<64 - 1
-	}
-
-	// s = nlz(v); v <<= s
-	s := uint(0)
-	for v&(1<<63) == 0 {
-		s++
-		v <<= 1
-	}
-
-	vn1 := v >> 32
-	vn0 := v & (1<<32 - 1)
-	un32 := u1<<s | u0>>(64-s)
-	un10 := u0 << s
-	un1 := un10 >> 32
-	un0 := un10 & (1<<32 - 1)
-	q1 := un32 / vn1
-	rhat := un32 - q1*vn1
-
-again1:
-	if q1 >= b || q1*vn0 > b*rhat+un1 {
-		q1--
-		rhat += vn1
-		if rhat < b {
-			goto again1
-		}
-	}
-
-	un21 := un32*b + un1 - q1*v
-	q0 := un21 / vn1
-	rhat = un21 - q0*vn1
-
-again2:
-	if q0 >= b || q0*vn0 > b*rhat+un0 {
-		q0--
-		rhat += vn1
-		if rhat < b {
-			goto again2
-		}
-	}
-
-	return q1*b + q0, (un21*b + un0 - q0*v) >> s
-}
-
-// callable from C
-
-func fadd64c(f, g uint64, ret *uint64)            { *ret = fadd64(f, g) }
-func fsub64c(f, g uint64, ret *uint64)            { *ret = fsub64(f, g) }
-func fmul64c(f, g uint64, ret *uint64)            { *ret = fmul64(f, g) }
-func fdiv64c(f, g uint64, ret *uint64)            { *ret = fdiv64(f, g) }
-func fneg64c(f uint64, ret *uint64)               { *ret = fneg64(f) }
-func f32to64c(f uint32, ret *uint64)              { *ret = f32to64(f) }
-func f64to32c(f uint64, ret *uint32)              { *ret = f64to32(f) }
-func fcmp64c(f, g uint64, ret *int, retnan *bool) { *ret, *retnan = fcmp64(f, g) }
-func fintto64c(val int64, ret *uint64)            { *ret = fintto64(val) }
-func f64tointc(f uint64, ret *int64, retok *bool) { *ret, *retok = f64toint(f) }
diff --git a/third_party/gofrontend/libgo/go/runtime/softfloat64_test.go b/third_party/gofrontend/libgo/go/runtime/softfloat64_test.go
deleted file mode 100644
index df63010..0000000
--- a/third_party/gofrontend/libgo/go/runtime/softfloat64_test.go
+++ /dev/null
@@ -1,198 +0,0 @@
-// Copyright 2010 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 runtime_test
-
-import (
-	"math"
-	"math/rand"
-	. "runtime"
-	"testing"
-)
-
-// turn uint64 op into float64 op
-func fop(f func(x, y uint64) uint64) func(x, y float64) float64 {
-	return func(x, y float64) float64 {
-		bx := math.Float64bits(x)
-		by := math.Float64bits(y)
-		return math.Float64frombits(f(bx, by))
-	}
-}
-
-func add(x, y float64) float64 { return x + y }
-func sub(x, y float64) float64 { return x - y }
-func mul(x, y float64) float64 { return x * y }
-func div(x, y float64) float64 { return x / y }
-
-func TestFloat64(t *testing.T) {
-	base := []float64{
-		0,
-		math.Copysign(0, -1),
-		-1,
-		1,
-		math.NaN(),
-		math.Inf(+1),
-		math.Inf(-1),
-		0.1,
-		1.5,
-		1.9999999999999998,     // all 1s mantissa
-		1.3333333333333333,     // 1.010101010101...
-		1.1428571428571428,     // 1.001001001001...
-		1.112536929253601e-308, // first normal
-		2,
-		4,
-		8,
-		16,
-		32,
-		64,
-		128,
-		256,
-		3,
-		12,
-		1234,
-		123456,
-		-0.1,
-		-1.5,
-		-1.9999999999999998,
-		-1.3333333333333333,
-		-1.1428571428571428,
-		-2,
-		-3,
-		1e-200,
-		1e-300,
-		1e-310,
-		5e-324,
-		1e-105,
-		1e-305,
-		1e+200,
-		1e+306,
-		1e+307,
-		1e+308,
-	}
-	all := make([]float64, 200)
-	copy(all, base)
-	for i := len(base); i < len(all); i++ {
-		all[i] = rand.NormFloat64()
-	}
-
-	test(t, "+", add, fop(Fadd64), all)
-	test(t, "-", sub, fop(Fsub64), all)
-	if GOARCH != "386" { // 386 is not precise!
-		test(t, "*", mul, fop(Fmul64), all)
-		test(t, "/", div, fop(Fdiv64), all)
-	}
-}
-
-// 64 -hw-> 32 -hw-> 64
-func trunc32(f float64) float64 {
-	return float64(float32(f))
-}
-
-// 64 -sw->32 -hw-> 64
-func to32sw(f float64) float64 {
-	return float64(math.Float32frombits(F64to32(math.Float64bits(f))))
-}
-
-// 64 -hw->32 -sw-> 64
-func to64sw(f float64) float64 {
-	return math.Float64frombits(F32to64(math.Float32bits(float32(f))))
-}
-
-// float64 -hw-> int64 -hw-> float64
-func hwint64(f float64) float64 {
-	return float64(int64(f))
-}
-
-// float64 -hw-> int32 -hw-> float64
-func hwint32(f float64) float64 {
-	return float64(int32(f))
-}
-
-// float64 -sw-> int64 -hw-> float64
-func toint64sw(f float64) float64 {
-	i, ok := F64toint(math.Float64bits(f))
-	if !ok {
-		// There's no right answer for out of range.
-		// Match the hardware to pass the test.
-		i = int64(f)
-	}
-	return float64(i)
-}
-
-// float64 -hw-> int64 -sw-> float64
-func fromint64sw(f float64) float64 {
-	return math.Float64frombits(Fintto64(int64(f)))
-}
-
-var nerr int
-
-func err(t *testing.T, format string, args ...interface{}) {
-	t.Errorf(format, args...)
-
-	// cut errors off after a while.
-	// otherwise we spend all our time
-	// allocating memory to hold the
-	// formatted output.
-	if nerr++; nerr >= 10 {
-		t.Fatal("too many errors")
-	}
-}
-
-func test(t *testing.T, op string, hw, sw func(float64, float64) float64, all []float64) {
-	for _, f := range all {
-		for _, g := range all {
-			h := hw(f, g)
-			s := sw(f, g)
-			if !same(h, s) {
-				err(t, "%g %s %g = sw %g, hw %g\n", f, op, g, s, h)
-			}
-			testu(t, "to32", trunc32, to32sw, h)
-			testu(t, "to64", trunc32, to64sw, h)
-			testu(t, "toint64", hwint64, toint64sw, h)
-			testu(t, "fromint64", hwint64, fromint64sw, h)
-			testcmp(t, f, h)
-			testcmp(t, h, f)
-			testcmp(t, g, h)
-			testcmp(t, h, g)
-		}
-	}
-}
-
-func testu(t *testing.T, op string, hw, sw func(float64) float64, v float64) {
-	h := hw(v)
-	s := sw(v)
-	if !same(h, s) {
-		err(t, "%s %g = sw %g, hw %g\n", op, v, s, h)
-	}
-}
-
-func hwcmp(f, g float64) (cmp int, isnan bool) {
-	switch {
-	case f < g:
-		return -1, false
-	case f > g:
-		return +1, false
-	case f == g:
-		return 0, false
-	}
-	return 0, true // must be NaN
-}
-
-func testcmp(t *testing.T, f, g float64) {
-	hcmp, hisnan := hwcmp(f, g)
-	scmp, sisnan := Fcmp64(math.Float64bits(f), math.Float64bits(g))
-	if hcmp != scmp || hisnan != sisnan {
-		err(t, "cmp(%g, %g) = sw %v, %v, hw %v, %v\n", f, g, scmp, sisnan, hcmp, hisnan)
-	}
-}
-
-func same(f, g float64) bool {
-	if math.IsNaN(f) && math.IsNaN(g) {
-		return true
-	}
-	if math.Copysign(1, f) != math.Copysign(1, g) {
-		return false
-	}
-	return f == g
-}
diff --git a/third_party/gofrontend/libgo/go/runtime/stack.go b/third_party/gofrontend/libgo/go/runtime/stack.go
deleted file mode 100644
index f1b7d32..0000000
--- a/third_party/gofrontend/libgo/go/runtime/stack.go
+++ /dev/null
@@ -1,13 +0,0 @@
-// Copyright 2011 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 runtime
-
-const (
-	// Goroutine preemption request.
-	// Stored into g->stackguard0 to cause split stack check failure.
-	// Must be greater than any real sp.
-	// 0xfffffade in hex.
-	stackPreempt = ^uintptr(1313)
-)
diff --git a/third_party/gofrontend/libgo/go/runtime/string.go b/third_party/gofrontend/libgo/go/runtime/string.go
deleted file mode 100644
index 0809f89..0000000
--- a/third_party/gofrontend/libgo/go/runtime/string.go
+++ /dev/null
@@ -1,298 +0,0 @@
-// 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.
-
-package runtime
-
-import (
-	"unsafe"
-)
-
-func concatstrings(a []string) string {
-	idx := 0
-	l := 0
-	count := 0
-	for i, x := range a {
-		n := len(x)
-		if n == 0 {
-			continue
-		}
-		if l+n < l {
-			gothrow("string concatenation too long")
-		}
-		l += n
-		count++
-		idx = i
-	}
-	if count == 0 {
-		return ""
-	}
-	if count == 1 {
-		return a[idx]
-	}
-	s, b := rawstring(l)
-	l = 0
-	for _, x := range a {
-		copy(b[l:], x)
-		l += len(x)
-	}
-	return s
-}
-
-//go:nosplit
-func concatstring2(a [2]string) string {
-	return concatstrings(a[:])
-}
-
-//go:nosplit
-func concatstring3(a [3]string) string {
-	return concatstrings(a[:])
-}
-
-//go:nosplit
-func concatstring4(a [4]string) string {
-	return concatstrings(a[:])
-}
-
-//go:nosplit
-func concatstring5(a [5]string) string {
-	return concatstrings(a[:])
-}
-
-func slicebytetostring(b []byte) string {
-	if raceenabled && len(b) > 0 {
-		racereadrangepc(unsafe.Pointer(&b[0]),
-			uintptr(len(b)),
-			getcallerpc(unsafe.Pointer(&b)),
-			funcPC(slicebytetostring))
-	}
-	s, c := rawstring(len(b))
-	copy(c, b)
-	return s
-}
-
-func slicebytetostringtmp(b []byte) string {
-	// Return a "string" referring to the actual []byte bytes.
-	// This is only for use by internal compiler optimizations
-	// that know that the string form will be discarded before
-	// the calling goroutine could possibly modify the original
-	// slice or synchronize with another goroutine.
-	// Today, the only such case is a m[string(k)] lookup where
-	// m is a string-keyed map and k is a []byte.
-
-	if raceenabled && len(b) > 0 {
-		racereadrangepc(unsafe.Pointer(&b[0]),
-			uintptr(len(b)),
-			getcallerpc(unsafe.Pointer(&b)),
-			funcPC(slicebytetostringtmp))
-	}
-	return *(*string)(unsafe.Pointer(&b))
-}
-
-func stringtoslicebyte(s string) []byte {
-	b := rawbyteslice(len(s))
-	copy(b, s)
-	return b
-}
-
-func stringtoslicerune(s string) []rune {
-	// two passes.
-	// unlike slicerunetostring, no race because strings are immutable.
-	n := 0
-	t := s
-	for len(s) > 0 {
-		_, k := charntorune(s)
-		s = s[k:]
-		n++
-	}
-	a := rawruneslice(n)
-	n = 0
-	for len(t) > 0 {
-		r, k := charntorune(t)
-		t = t[k:]
-		a[n] = r
-		n++
-	}
-	return a
-}
-
-func slicerunetostring(a []rune) string {
-	if raceenabled && len(a) > 0 {
-		racereadrangepc(unsafe.Pointer(&a[0]),
-			uintptr(len(a))*unsafe.Sizeof(a[0]),
-			getcallerpc(unsafe.Pointer(&a)),
-			funcPC(slicerunetostring))
-	}
-	var dum [4]byte
-	size1 := 0
-	for _, r := range a {
-		size1 += runetochar(dum[:], r)
-	}
-	s, b := rawstring(size1 + 3)
-	size2 := 0
-	for _, r := range a {
-		// check for race
-		if size2 >= size1 {
-			break
-		}
-		size2 += runetochar(b[size2:], r)
-	}
-	return s[:size2]
-}
-
-type stringStruct struct {
-	str unsafe.Pointer
-	len int
-}
-
-func intstring(v int64) string {
-	s, b := rawstring(4)
-	n := runetochar(b, rune(v))
-	return s[:n]
-}
-
-// stringiter returns the index of the next
-// rune after the rune that starts at s[k].
-func stringiter(s string, k int) int {
-	if k >= len(s) {
-		// 0 is end of iteration
-		return 0
-	}
-
-	c := s[k]
-	if c < runeself {
-		return k + 1
-	}
-
-	// multi-char rune
-	_, n := charntorune(s[k:])
-	return k + n
-}
-
-// stringiter2 returns the rune that starts at s[k]
-// and the index where the next rune starts.
-func stringiter2(s string, k int) (int, rune) {
-	if k >= len(s) {
-		// 0 is end of iteration
-		return 0, 0
-	}
-
-	c := s[k]
-	if c < runeself {
-		return k + 1, rune(c)
-	}
-
-	// multi-char rune
-	r, n := charntorune(s[k:])
-	return k + n, r
-}
-
-// rawstring allocates storage for a new string. The returned
-// string and byte slice both refer to the same storage.
-// The storage is not zeroed. Callers should use
-// b to set the string contents and then drop b.
-func rawstring(size int) (s string, b []byte) {
-	p := mallocgc(uintptr(size), nil, flagNoScan|flagNoZero)
-
-	(*stringStruct)(unsafe.Pointer(&s)).str = p
-	(*stringStruct)(unsafe.Pointer(&s)).len = size
-
-	(*slice)(unsafe.Pointer(&b)).array = (*uint8)(p)
-	(*slice)(unsafe.Pointer(&b)).len = uint(size)
-	(*slice)(unsafe.Pointer(&b)).cap = uint(size)
-
-	for {
-		ms := maxstring
-		if uintptr(size) <= uintptr(ms) || casuintptr((*uintptr)(unsafe.Pointer(&maxstring)), uintptr(ms), uintptr(size)) {
-			return
-		}
-	}
-}
-
-// rawbyteslice allocates a new byte slice. The byte slice is not zeroed.
-func rawbyteslice(size int) (b []byte) {
-	cap := goroundupsize(uintptr(size))
-	p := mallocgc(cap, nil, flagNoScan|flagNoZero)
-	if cap != uintptr(size) {
-		memclr(add(p, uintptr(size)), cap-uintptr(size))
-	}
-
-	(*slice)(unsafe.Pointer(&b)).array = (*uint8)(p)
-	(*slice)(unsafe.Pointer(&b)).len = uint(size)
-	(*slice)(unsafe.Pointer(&b)).cap = uint(cap)
-	return
-}
-
-// rawruneslice allocates a new rune slice. The rune slice is not zeroed.
-func rawruneslice(size int) (b []rune) {
-	if uintptr(size) > maxmem/4 {
-		gothrow("out of memory")
-	}
-	mem := goroundupsize(uintptr(size) * 4)
-	p := mallocgc(mem, nil, flagNoScan|flagNoZero)
-	if mem != uintptr(size)*4 {
-		memclr(add(p, uintptr(size)*4), mem-uintptr(size)*4)
-	}
-
-	(*slice)(unsafe.Pointer(&b)).array = (*uint8)(p)
-	(*slice)(unsafe.Pointer(&b)).len = uint(size)
-	(*slice)(unsafe.Pointer(&b)).cap = uint(mem / 4)
-	return
-}
-
-// used by cmd/cgo
-func gobytes(p *byte, n int) []byte {
-	if n == 0 {
-		return make([]byte, 0)
-	}
-	x := make([]byte, n)
-	memmove(unsafe.Pointer(&x[0]), unsafe.Pointer(p), uintptr(n))
-	return x
-}
-
-func gostringsize(n int) string {
-	s, _ := rawstring(n)
-	return s
-}
-
-//go:noescape
-func findnull(*byte) int
-
-func gostring(p *byte) string {
-	l := findnull(p)
-	if l == 0 {
-		return ""
-	}
-	s, b := rawstring(l)
-	memmove(unsafe.Pointer(&b[0]), unsafe.Pointer(p), uintptr(l))
-	return s
-}
-
-func gostringn(p *byte, l int) string {
-	if l == 0 {
-		return ""
-	}
-	s, b := rawstring(l)
-	memmove(unsafe.Pointer(&b[0]), unsafe.Pointer(p), uintptr(l))
-	return s
-}
-
-func index(s, t string) int {
-	if len(t) == 0 {
-		return 0
-	}
-	for i := 0; i < len(s); i++ {
-		if s[i] == t[0] && hasprefix(s[i:], t) {
-			return i
-		}
-	}
-	return -1
-}
-
-func contains(s, t string) bool {
-	return index(s, t) >= 0
-}
-
-func hasprefix(s, t string) bool {
-	return len(s) >= len(t) && s[:len(t)] == t
-}
diff --git a/third_party/gofrontend/libgo/go/runtime/string_test.go b/third_party/gofrontend/libgo/go/runtime/string_test.go
index df3ff06..71bd830 100644
--- a/third_party/gofrontend/libgo/go/runtime/string_test.go
+++ b/third_party/gofrontend/libgo/go/runtime/string_test.go
@@ -5,6 +5,7 @@
 package runtime_test
 
 import (
+	"strings"
 	"testing"
 )
 
@@ -75,3 +76,165 @@
 	}
 	b.SetBytes(int64(len(s1)))
 }
+
+func BenchmarkRuneIterate(b *testing.B) {
+	bytes := make([]byte, 100)
+	for i := range bytes {
+		bytes[i] = byte('A')
+	}
+	s := string(bytes)
+	for i := 0; i < b.N; i++ {
+		for range s {
+		}
+	}
+}
+
+func BenchmarkRuneIterate2(b *testing.B) {
+	bytes := make([]byte, 100)
+	for i := range bytes {
+		bytes[i] = byte('A')
+	}
+	s := string(bytes)
+	for i := 0; i < b.N; i++ {
+		for range s {
+		}
+	}
+}
+
+/*
+func TestStringW(t *testing.T) {
+	strings := []string{
+		"hello",
+		"a\u5566\u7788b",
+	}
+
+	for _, s := range strings {
+		var b []uint16
+		for _, c := range s {
+			b = append(b, uint16(c))
+			if c != rune(uint16(c)) {
+				t.Errorf("bad test: stringW can't handle >16 bit runes")
+			}
+		}
+		b = append(b, 0)
+		r := runtime.GostringW(b)
+		if r != s {
+			t.Errorf("gostringW(%v) = %s, want %s", b, r, s)
+		}
+	}
+}
+*/
+
+func TestLargeStringConcat(t *testing.T) {
+	output := executeTest(t, largeStringConcatSource, nil)
+	want := "panic: " + strings.Repeat("0", 1<<10) + strings.Repeat("1", 1<<10) +
+		strings.Repeat("2", 1<<10) + strings.Repeat("3", 1<<10)
+	if !strings.HasPrefix(output, want) {
+		t.Fatalf("output does not start with %q:\n%s", want, output)
+	}
+}
+
+var largeStringConcatSource = `
+package main
+import "strings"
+func main() {
+	s0 := strings.Repeat("0", 1<<10)
+	s1 := strings.Repeat("1", 1<<10)
+	s2 := strings.Repeat("2", 1<<10)
+	s3 := strings.Repeat("3", 1<<10)
+	s := s0 + s1 + s2 + s3
+	panic(s)
+}
+`
+
+/*
+func TestGostringnocopy(t *testing.T) {
+	max := *runtime.Maxstring
+	b := make([]byte, max+10)
+	for i := uintptr(0); i < max+9; i++ {
+		b[i] = 'a'
+	}
+	_ = runtime.Gostringnocopy(&b[0])
+	newmax := *runtime.Maxstring
+	if newmax != max+9 {
+		t.Errorf("want %d, got %d", max+9, newmax)
+	}
+}
+*/
+
+func TestCompareTempString(t *testing.T) {
+	s := "foo"
+	b := []byte(s)
+	n := testing.AllocsPerRun(1000, func() {
+		if string(b) != s {
+			t.Fatalf("strings are not equal: '%v' and '%v'", string(b), s)
+		}
+		if string(b) == s {
+		} else {
+			t.Fatalf("strings are not equal: '%v' and '%v'", string(b), s)
+		}
+	})
+	if n != 0 {
+		t.Fatalf("want 0 allocs, got %v", n)
+	}
+}
+
+func TestStringOnStack(t *testing.T) {
+	s := ""
+	for i := 0; i < 3; i++ {
+		s = "a" + s + "b" + s + "c"
+	}
+
+	if want := "aaabcbabccbaabcbabccc"; s != want {
+		t.Fatalf("want: '%v', got '%v'", want, s)
+	}
+}
+
+func TestIntString(t *testing.T) {
+	// Non-escaping result of intstring.
+	s := ""
+	for i := 0; i < 4; i++ {
+		s += string(i+'0') + string(i+'0'+1)
+	}
+	if want := "01122334"; s != want {
+		t.Fatalf("want '%v', got '%v'", want, s)
+	}
+
+	// Escaping result of intstring.
+	var a [4]string
+	for i := 0; i < 4; i++ {
+		a[i] = string(i + '0')
+	}
+	s = a[0] + a[1] + a[2] + a[3]
+	if want := "0123"; s != want {
+		t.Fatalf("want '%v', got '%v'", want, s)
+	}
+}
+
+func TestIntStringAllocs(t *testing.T) {
+	unknown := '0'
+	n := testing.AllocsPerRun(1000, func() {
+		s1 := string(unknown)
+		s2 := string(unknown + 1)
+		if s1 == s2 {
+			t.Fatalf("bad")
+		}
+	})
+	if n != 0 {
+		t.Fatalf("want 0 allocs, got %v", n)
+	}
+}
+
+func TestRangeStringCast(t *testing.T) {
+	s := "abc"
+	n := testing.AllocsPerRun(1000, func() {
+		for i, c := range []byte(s) {
+			if c != s[i] {
+				t.Fatalf("want '%c' at pos %v, got '%c'", s[i], i, c)
+			}
+		}
+	})
+	if n != 0 {
+		t.Fatalf("want 0 allocs, got %v", n)
+	}
+}
diff --git a/third_party/gofrontend/libgo/go/runtime/stubs.go b/third_party/gofrontend/libgo/go/runtime/stubs.go
deleted file mode 100644
index fe8f9c9..0000000
--- a/third_party/gofrontend/libgo/go/runtime/stubs.go
+++ /dev/null
@@ -1,316 +0,0 @@
-// 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.
-
-package runtime
-
-import "unsafe"
-
-// Declarations for runtime services implemented in C or assembly.
-
-const ptrSize = 4 << (^uintptr(0) >> 63) // unsafe.Sizeof(uintptr(0)) but an ideal const
-const regSize = 4 << (^uintreg(0) >> 63) // unsafe.Sizeof(uintreg(0)) but an ideal const
-
-// Should be a built-in for unsafe.Pointer?
-//go:nosplit
-func add(p unsafe.Pointer, x uintptr) unsafe.Pointer {
-	return unsafe.Pointer(uintptr(p) + x)
-}
-
-// n must be a power of 2
-func roundup(p unsafe.Pointer, n uintptr) unsafe.Pointer {
-	delta := -uintptr(p) & (n - 1)
-	return unsafe.Pointer(uintptr(p) + delta)
-}
-
-// in runtime.c
-func getg() *g
-func acquirem() *m
-func releasem(mp *m)
-func gomcache() *mcache
-func readgstatus(*g) uint32 // proc.c
-
-// mcall switches from the g to the g0 stack and invokes fn(g),
-// where g is the goroutine that made the call.
-// mcall saves g's current PC/SP in g->sched so that it can be restored later.
-// It is up to fn to arrange for that later execution, typically by recording
-// g in a data structure, causing something to call ready(g) later.
-// mcall returns to the original goroutine g later, when g has been rescheduled.
-// fn must not return at all; typically it ends by calling schedule, to let the m
-// run other goroutines.
-//
-// mcall can only be called from g stacks (not g0, not gsignal).
-//go:noescape
-func mcall(fn func(*g))
-
-// onM switches from the g to the g0 stack and invokes fn().
-// When fn returns, onM switches back to the g and returns,
-// continuing execution on the g stack.
-// If arguments must be passed to fn, they can be written to
-// g->m->ptrarg (pointers) and g->m->scalararg (non-pointers)
-// before the call and then consulted during fn.
-// Similarly, fn can pass return values back in those locations.
-// If fn is written in Go, it can be a closure, which avoids the need for
-// ptrarg and scalararg entirely.
-// After reading values out of ptrarg and scalararg it is conventional
-// to zero them to avoid (memory or information) leaks.
-//
-// If onM is called from a g0 stack, it invokes fn and returns,
-// without any stack switches.
-//
-// If onM is called from a gsignal stack, it crashes the program.
-// The implication is that functions used in signal handlers must
-// not use onM.
-//
-// NOTE(rsc): We could introduce a separate onMsignal that is
-// like onM but if called from a gsignal stack would just run fn on
-// that stack. The caller of onMsignal would be required to save the
-// old values of ptrarg/scalararg and restore them when the call
-// was finished, in case the signal interrupted an onM sequence
-// in progress on the g or g0 stacks. Until there is a clear need for this,
-// we just reject onM in signal handling contexts entirely.
-//
-//go:noescape
-func onM(fn func())
-
-// onMsignal is like onM but is allowed to be used in code that
-// might run on the gsignal stack. Code running on a signal stack
-// may be interrupting an onM sequence on the main stack, so
-// if the onMsignal calling sequence writes to ptrarg/scalararg,
-// it must first save the old values and then restore them when
-// finished. As an exception to the rule, it is fine not to save and
-// restore the values if the program is trying to crash rather than
-// return from the signal handler.
-// Once all the runtime is written in Go, there will be no ptrarg/scalararg
-// and the distinction between onM and onMsignal (and perhaps mcall)
-// can go away.
-//
-// If onMsignal is called from a gsignal stack, it invokes fn directly,
-// without a stack switch. Otherwise onMsignal behaves like onM.
-//
-//go:noescape
-func onM_signalok(fn func())
-
-func badonm() {
-	gothrow("onM called from signal goroutine")
-}
-
-// C functions that run on the M stack.
-// Call using mcall.
-func gosched_m(*g)
-func park_m(*g)
-func recovery_m(*g)
-
-// More C functions that run on the M stack.
-// Call using onM.
-func mcacheRefill_m()
-func largeAlloc_m()
-func gc_m()
-func scavenge_m()
-func setFinalizer_m()
-func removeFinalizer_m()
-func markallocated_m()
-func unrollgcprog_m()
-func unrollgcproginplace_m()
-func setgcpercent_m()
-func setmaxthreads_m()
-func ready_m()
-func deferproc_m()
-func goexit_m()
-func startpanic_m()
-func dopanic_m()
-func readmemstats_m()
-func writeheapdump_m()
-
-// memclr clears n bytes starting at ptr.
-// in memclr_*.s
-//go:noescape
-func memclr(ptr unsafe.Pointer, n uintptr)
-
-// memmove copies n bytes from "from" to "to".
-// in memmove_*.s
-//go:noescape
-func memmove(to unsafe.Pointer, from unsafe.Pointer, n uintptr)
-
-func starttheworld()
-func stoptheworld()
-func newextram()
-func lockOSThread()
-func unlockOSThread()
-
-// exported value for testing
-var hashLoad = loadFactor
-
-// in asm_*.s
-func fastrand1() uint32
-
-// in asm_*.s
-//go:noescape
-func memeq(a, b unsafe.Pointer, size uintptr) bool
-
-// noescape hides a pointer from escape analysis.  noescape is
-// the identity function but escape analysis doesn't think the
-// output depends on the input.  noescape is inlined and currently
-// compiles down to a single xor instruction.
-// USE CAREFULLY!
-//go:nosplit
-func noescape(p unsafe.Pointer) unsafe.Pointer {
-	x := uintptr(p)
-	return unsafe.Pointer(x ^ 0)
-}
-
-func entersyscall()
-func reentersyscall(pc uintptr, sp unsafe.Pointer)
-func entersyscallblock()
-func exitsyscall()
-
-func cgocallback(fn, frame unsafe.Pointer, framesize uintptr)
-func gogo(buf *gobuf)
-func gosave(buf *gobuf)
-func read(fd int32, p unsafe.Pointer, n int32) int32
-func close(fd int32) int32
-func mincore(addr unsafe.Pointer, n uintptr, dst *byte) int32
-
-//go:noescape
-func jmpdefer(fv *funcval, argp uintptr)
-func exit1(code int32)
-func asminit()
-func setg(gg *g)
-func exit(code int32)
-func breakpoint()
-func nanotime() int64
-func usleep(usec uint32)
-
-// careful: cputicks is not guaranteed to be monotonic!  In particular, we have
-// noticed drift between cpus on certain os/arch combinations.  See issue 8976.
-func cputicks() int64
-
-func mmap(addr unsafe.Pointer, n uintptr, prot, flags, fd int32, off uint32) unsafe.Pointer
-func munmap(addr unsafe.Pointer, n uintptr)
-func madvise(addr unsafe.Pointer, n uintptr, flags int32)
-func reflectcall(fn, arg unsafe.Pointer, n uint32, retoffset uint32)
-func osyield()
-func procyield(cycles uint32)
-func cgocallback_gofunc(fv *funcval, frame unsafe.Pointer, framesize uintptr)
-func readgogc() int32
-func purgecachedstats(c *mcache)
-func gostringnocopy(b *byte) string
-func goexit()
-
-//go:noescape
-func write(fd uintptr, p unsafe.Pointer, n int32) int32
-
-//go:noescape
-func cas(ptr *uint32, old, new uint32) bool
-
-//go:noescape
-func casp(ptr *unsafe.Pointer, old, new unsafe.Pointer) bool
-
-//go:noescape
-func casuintptr(ptr *uintptr, old, new uintptr) bool
-
-//go:noescape
-func atomicstoreuintptr(ptr *uintptr, new uintptr)
-
-//go:noescape
-func atomicloaduintptr(ptr *uintptr) uintptr
-
-//go:noescape
-func atomicloaduint(ptr *uint) uint
-
-//go:noescape
-func setcallerpc(argp unsafe.Pointer, pc uintptr)
-
-// getcallerpc returns the program counter (PC) of its caller's caller.
-// getcallersp returns the stack pointer (SP) of its caller's caller.
-// For both, the argp must be a pointer to the caller's first function argument.
-// The implementation may or may not use argp, depending on
-// the architecture.
-//
-// For example:
-//
-//	func f(arg1, arg2, arg3 int) {
-//		pc := getcallerpc(unsafe.Pointer(&arg1))
-//		sp := getcallerpc(unsafe.Pointer(&arg2))
-//	}
-//
-// These two lines find the PC and SP immediately following
-// the call to f (where f will return).
-//
-// The call to getcallerpc and getcallersp must be done in the
-// frame being asked about. It would not be correct for f to pass &arg1
-// to another function g and let g call getcallerpc/getcallersp.
-// The call inside g might return information about g's caller or
-// information about f's caller or complete garbage.
-//
-// The result of getcallersp is correct at the time of the return,
-// but it may be invalidated by any subsequent call to a function
-// that might relocate the stack in order to grow or shrink it.
-// A general rule is that the result of getcallersp should be used
-// immediately and can only be passed to nosplit functions.
-
-//go:noescape
-func getcallerpc(argp unsafe.Pointer) uintptr
-
-//go:noescape
-func getcallersp(argp unsafe.Pointer) uintptr
-
-//go:noescape
-func asmcgocall(fn, arg unsafe.Pointer)
-
-//go:noescape
-func asmcgocall_errno(fn, arg unsafe.Pointer) int32
-
-//go:noescape
-func open(name *byte, mode, perm int32) int32
-
-//go:noescape
-func gotraceback(*bool) int32
-
-const _NoArgs = ^uintptr(0)
-
-func newstack()
-func newproc()
-func morestack()
-func mstart()
-func rt0_go()
-
-// return0 is a stub used to return 0 from deferproc.
-// It is called at the very end of deferproc to signal
-// the calling Go function that it should not jump
-// to deferreturn.
-// in asm_*.s
-func return0()
-
-// thunk to call time.now.
-func timenow() (sec int64, nsec int32)
-
-// in asm_*.s
-// not called directly; definitions here supply type information for traceback.
-func call16(fn, arg unsafe.Pointer, n, retoffset uint32)
-func call32(fn, arg unsafe.Pointer, n, retoffset uint32)
-func call64(fn, arg unsafe.Pointer, n, retoffset uint32)
-func call128(fn, arg unsafe.Pointer, n, retoffset uint32)
-func call256(fn, arg unsafe.Pointer, n, retoffset uint32)
-func call512(fn, arg unsafe.Pointer, n, retoffset uint32)
-func call1024(fn, arg unsafe.Pointer, n, retoffset uint32)
-func call2048(fn, arg unsafe.Pointer, n, retoffset uint32)
-func call4096(fn, arg unsafe.Pointer, n, retoffset uint32)
-func call8192(fn, arg unsafe.Pointer, n, retoffset uint32)
-func call16384(fn, arg unsafe.Pointer, n, retoffset uint32)
-func call32768(fn, arg unsafe.Pointer, n, retoffset uint32)
-func call65536(fn, arg unsafe.Pointer, n, retoffset uint32)
-func call131072(fn, arg unsafe.Pointer, n, retoffset uint32)
-func call262144(fn, arg unsafe.Pointer, n, retoffset uint32)
-func call524288(fn, arg unsafe.Pointer, n, retoffset uint32)
-func call1048576(fn, arg unsafe.Pointer, n, retoffset uint32)
-func call2097152(fn, arg unsafe.Pointer, n, retoffset uint32)
-func call4194304(fn, arg unsafe.Pointer, n, retoffset uint32)
-func call8388608(fn, arg unsafe.Pointer, n, retoffset uint32)
-func call16777216(fn, arg unsafe.Pointer, n, retoffset uint32)
-func call33554432(fn, arg unsafe.Pointer, n, retoffset uint32)
-func call67108864(fn, arg unsafe.Pointer, n, retoffset uint32)
-func call134217728(fn, arg unsafe.Pointer, n, retoffset uint32)
-func call268435456(fn, arg unsafe.Pointer, n, retoffset uint32)
-func call536870912(fn, arg unsafe.Pointer, n, retoffset uint32)
-func call1073741824(fn, arg unsafe.Pointer, n, retoffset uint32)
diff --git a/third_party/gofrontend/libgo/go/runtime/symtab_test.go b/third_party/gofrontend/libgo/go/runtime/symtab_test.go
index 0db63c3..8c8281f 100644
--- a/third_party/gofrontend/libgo/go/runtime/symtab_test.go
+++ b/third_party/gofrontend/libgo/go/runtime/symtab_test.go
@@ -12,9 +12,8 @@
 
 var _ = runtime.Caller
 var _ = strings.HasSuffix
-type _ testing.T
 
-/* runtime.Caller is not fully implemented for gccgo.
+type _ testing.T
 
 func TestCaller(t *testing.T) {
 	procs := runtime.GOMAXPROCS(-1)
@@ -42,8 +41,9 @@
 		f := runtime.FuncForPC(pc)
 		if !ok ||
 			!strings.HasSuffix(file, "symtab_test.go") ||
-			(i == 0 && !strings.HasSuffix(f.Name(), "testCallerBar")) ||
-			(i == 1 && !strings.HasSuffix(f.Name(), "testCallerFoo")) ||
+			// FuncForPC doesn't work gccgo, because of inlining.
+			// (i == 0 && !strings.HasSuffix(f.Name(), "testCallerBar")) ||
+			// (i == 1 && !strings.HasSuffix(f.Name(), "testCallerFoo")) ||
 			line < 5 || line > 1000 ||
 			f.Entry() >= pc {
 			t.Errorf("incorrect symbol info %d: %t %d %d %s %s %d",
@@ -52,4 +52,107 @@
 	}
 }
 
-*/
+func lineNumber() int {
+	_, _, line, _ := runtime.Caller(1)
+	return line // return 0 for error
+}
+
+// Do not add/remove lines in this block without updating the line numbers.
+var firstLine = lineNumber() // 0
+var (                        // 1
+	lineVar1             = lineNumber()               // 2
+	lineVar2a, lineVar2b = lineNumber(), lineNumber() // 3
+)                        // 4
+var compLit = []struct { // 5
+	lineA, lineB int // 6
+}{ // 7
+	{ // 8
+		lineNumber(), lineNumber(), // 9
+	}, // 10
+	{ // 11
+		lineNumber(), // 12
+		lineNumber(), // 13
+	}, // 14
+	{ // 15
+		lineB: lineNumber(), // 16
+		lineA: lineNumber(), // 17
+	}, // 18
+}                                     // 19
+var arrayLit = [...]int{lineNumber(), // 20
+	lineNumber(), lineNumber(), // 21
+	lineNumber(), // 22
+}                                  // 23
+var sliceLit = []int{lineNumber(), // 24
+	lineNumber(), lineNumber(), // 25
+	lineNumber(), // 26
+}                         // 27
+var mapLit = map[int]int{ // 28
+	29:           lineNumber(), // 29
+	30:           lineNumber(), // 30
+	lineNumber(): 31,           // 31
+	lineNumber(): 32,           // 32
+}                           // 33
+var intLit = lineNumber() + // 34
+	lineNumber() + // 35
+			lineNumber() // 36
+func trythis() { // 37
+	recordLines(lineNumber(), // 38
+		lineNumber(), // 39
+		lineNumber()) // 40
+}
+
+// Modifications below this line are okay.
+
+var l38, l39, l40 int
+
+func recordLines(a, b, c int) {
+	l38 = a
+	l39 = b
+	l40 = c
+}
+
+func TestLineNumber(t *testing.T) {
+	trythis()
+	for _, test := range []struct {
+		name string
+		val  int
+		want int
+	}{
+		{"firstLine", firstLine, 0},
+		{"lineVar1", lineVar1, 2},
+		{"lineVar2a", lineVar2a, 3},
+		{"lineVar2b", lineVar2b, 3},
+		{"compLit[0].lineA", compLit[0].lineA, 9},
+		{"compLit[0].lineB", compLit[0].lineB, 9},
+		{"compLit[1].lineA", compLit[1].lineA, 12},
+		{"compLit[1].lineB", compLit[1].lineB, 13},
+		{"compLit[2].lineA", compLit[2].lineA, 17},
+		{"compLit[2].lineB", compLit[2].lineB, 16},
+
+		{"arrayLit[0]", arrayLit[0], 20},
+		{"arrayLit[1]", arrayLit[1], 21},
+		{"arrayLit[2]", arrayLit[2], 21},
+		{"arrayLit[3]", arrayLit[3], 22},
+
+		{"sliceLit[0]", sliceLit[0], 24},
+		{"sliceLit[1]", sliceLit[1], 25},
+		{"sliceLit[2]", sliceLit[2], 25},
+		{"sliceLit[3]", sliceLit[3], 26},
+
+		{"mapLit[29]", mapLit[29], 29},
+		{"mapLit[30]", mapLit[30], 30},
+		{"mapLit[31]", mapLit[31+firstLine] + firstLine, 31}, // nb it's the key not the value
+		{"mapLit[32]", mapLit[32+firstLine] + firstLine, 32}, // nb it's the key not the value
+
+		{"intLit", intLit - 2*firstLine, 34 + 35 + 36},
+
+		{"l38", l38, 38},
+		{"l39", l39, 39},
+		{"l40", l40, 40},
+	} {
+		if got := test.val - firstLine; got != test.want {
+			t.Errorf("%s on firstLine+%d want firstLine+%d (firstLine=%d, val=%d)",
+				test.name, got, test.want, firstLine, test.val)
+		}
+	}
+}
diff --git a/third_party/gofrontend/libgo/go/runtime/syscall_windows.go b/third_party/gofrontend/libgo/go/runtime/syscall_windows.go
deleted file mode 100644
index 51004b7..0000000
--- a/third_party/gofrontend/libgo/go/runtime/syscall_windows.go
+++ /dev/null
@@ -1,174 +0,0 @@
-// 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.
-
-package runtime
-
-import (
-	"unsafe"
-)
-
-const _SIGPROF = 0 // dummy value for badsignal
-
-type callbacks struct {
-	lock mutex
-	ctxt [cb_max]*wincallbackcontext
-	n    int
-}
-
-func (c *wincallbackcontext) isCleanstack() bool {
-	return c.cleanstack
-}
-
-func (c *wincallbackcontext) setCleanstack(cleanstack bool) {
-	c.cleanstack = cleanstack
-}
-
-var (
-	cbs     callbacks
-	cbctxts **wincallbackcontext = &cbs.ctxt[0] // to simplify access to cbs.ctxt in sys_windows_*.s
-
-	callbackasm byte // type isn't really byte, it's code in runtime
-)
-
-// callbackasmAddr returns address of runtime.callbackasm
-// function adjusted by i.
-// runtime.callbackasm is just a series of CALL instructions
-// (each is 5 bytes long), and we want callback to arrive at
-// correspondent call instruction instead of start of
-// runtime.callbackasm.
-func callbackasmAddr(i int) uintptr {
-	return uintptr(add(unsafe.Pointer(&callbackasm), uintptr(i*5)))
-}
-
-func compileCallback(fn eface, cleanstack bool) (code uintptr) {
-	if fn._type == nil || (fn._type.kind&kindMask) != kindFunc {
-		panic("compilecallback: not a function")
-	}
-	ft := (*functype)(unsafe.Pointer(fn._type))
-	if len(ft.out) != 1 {
-		panic("compilecallback: function must have one output parameter")
-	}
-	uintptrSize := unsafe.Sizeof(uintptr(0))
-	if t := (**_type)(unsafe.Pointer(&ft.out[0])); (*t).size != uintptrSize {
-		panic("compilecallback: output parameter size is wrong")
-	}
-	argsize := uintptr(0)
-	if len(ft.in) > 0 {
-		for _, t := range (*[1024](*_type))(unsafe.Pointer(&ft.in[0]))[:len(ft.in)] {
-			if (*t).size > uintptrSize {
-				panic("compilecallback: input parameter size is wrong")
-			}
-			argsize += uintptrSize
-		}
-	}
-
-	lock(&cbs.lock)
-	defer unlock(&cbs.lock)
-
-	n := cbs.n
-	for i := 0; i < n; i++ {
-		if cbs.ctxt[i].gobody == fn.data && cbs.ctxt[i].isCleanstack() == cleanstack {
-			return callbackasmAddr(i)
-		}
-	}
-	if n >= cb_max {
-		gothrow("too many callback functions")
-	}
-
-	c := new(wincallbackcontext)
-	c.gobody = fn.data
-	c.argsize = argsize
-	c.setCleanstack(cleanstack)
-	if cleanstack && argsize != 0 {
-		c.restorestack = argsize
-	} else {
-		c.restorestack = 0
-	}
-	cbs.ctxt[n] = c
-	cbs.n++
-
-	return callbackasmAddr(n)
-}
-
-func getLoadLibrary() uintptr
-
-//go:nosplit
-func syscall_loadlibrary(filename *uint16) (handle, err uintptr) {
-	var c libcall
-	c.fn = getLoadLibrary()
-	c.n = 1
-	c.args = uintptr(unsafe.Pointer(&filename))
-	cgocall_errno(unsafe.Pointer(funcPC(asmstdcall)), unsafe.Pointer(&c))
-	handle = c.r1
-	if handle == 0 {
-		err = c.err
-	}
-	return
-}
-
-func getGetProcAddress() uintptr
-
-//go:nosplit
-func syscall_getprocaddress(handle uintptr, procname *byte) (outhandle, err uintptr) {
-	var c libcall
-	c.fn = getGetProcAddress()
-	c.n = 2
-	c.args = uintptr(unsafe.Pointer(&handle))
-	cgocall_errno(unsafe.Pointer(funcPC(asmstdcall)), unsafe.Pointer(&c))
-	outhandle = c.r1
-	if outhandle == 0 {
-		err = c.err
-	}
-	return
-}
-
-//go:nosplit
-func syscall_Syscall(fn, nargs, a1, a2, a3 uintptr) (r1, r2, err uintptr) {
-	var c libcall
-	c.fn = fn
-	c.n = nargs
-	c.args = uintptr(unsafe.Pointer(&a1))
-	cgocall_errno(unsafe.Pointer(funcPC(asmstdcall)), unsafe.Pointer(&c))
-	return c.r1, c.r2, c.err
-}
-
-//go:nosplit
-func syscall_Syscall6(fn, nargs, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2, err uintptr) {
-	var c libcall
-	c.fn = fn
-	c.n = nargs
-	c.args = uintptr(unsafe.Pointer(&a1))
-	cgocall_errno(unsafe.Pointer(funcPC(asmstdcall)), unsafe.Pointer(&c))
-	return c.r1, c.r2, c.err
-}
-
-//go:nosplit
-func syscall_Syscall9(fn, nargs, a1, a2, a3, a4, a5, a6, a7, a8, a9 uintptr) (r1, r2, err uintptr) {
-	var c libcall
-	c.fn = fn
-	c.n = nargs
-	c.args = uintptr(unsafe.Pointer(&a1))
-	cgocall_errno(unsafe.Pointer(funcPC(asmstdcall)), unsafe.Pointer(&c))
-	return c.r1, c.r2, c.err
-}
-
-//go:nosplit
-func syscall_Syscall12(fn, nargs, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12 uintptr) (r1, r2, err uintptr) {
-	var c libcall
-	c.fn = fn
-	c.n = nargs
-	c.args = uintptr(unsafe.Pointer(&a1))
-	cgocall_errno(unsafe.Pointer(funcPC(asmstdcall)), unsafe.Pointer(&c))
-	return c.r1, c.r2, c.err
-}
-
-//go:nosplit
-func syscall_Syscall15(fn, nargs, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15 uintptr) (r1, r2, err uintptr) {
-	var c libcall
-	c.fn = fn
-	c.n = nargs
-	c.args = uintptr(unsafe.Pointer(&a1))
-	cgocall_errno(unsafe.Pointer(funcPC(asmstdcall)), unsafe.Pointer(&c))
-	return c.r1, c.r2, c.err
-}
diff --git a/third_party/gofrontend/libgo/go/runtime/time.go b/third_party/gofrontend/libgo/go/runtime/time.go
deleted file mode 100644
index 11862c7..0000000
--- a/third_party/gofrontend/libgo/go/runtime/time.go
+++ /dev/null
@@ -1,289 +0,0 @@
-// Copyright 2009 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.
-
-// Time-related runtime and pieces of package time.
-
-package runtime
-
-import "unsafe"
-
-// Package time knows the layout of this structure.
-// If this struct changes, adjust ../time/sleep.go:/runtimeTimer.
-// For GOOS=nacl, package syscall knows the layout of this structure.
-// If this struct changes, adjust ../syscall/net_nacl.go:/runtimeTimer.
-type timer struct {
-	i int // heap index
-
-	// Timer wakes up at when, and then at when+period, ... (period > 0 only)
-	// each time calling f(now, arg) in the timer goroutine, so f must be
-	// a well-behaved function and not block.
-	when   int64
-	period int64
-	f      func(interface{}, uintptr)
-	arg    interface{}
-	seq    uintptr
-}
-
-var timers struct {
-	lock         mutex
-	gp           *g
-	created      bool
-	sleeping     bool
-	rescheduling bool
-	waitnote     note
-	t            []*timer
-}
-
-// nacl fake time support - time in nanoseconds since 1970
-var faketime int64
-
-// Package time APIs.
-// Godoc uses the comments in package time, not these.
-
-// time.now is implemented in assembly.
-
-// Sleep puts the current goroutine to sleep for at least ns nanoseconds.
-func timeSleep(ns int64) {
-	if ns <= 0 {
-		return
-	}
-
-	t := new(timer)
-	t.when = nanotime() + ns
-	t.f = goroutineReady
-	t.arg = getg()
-	lock(&timers.lock)
-	addtimerLocked(t)
-	goparkunlock(&timers.lock, "sleep")
-}
-
-// startTimer adds t to the timer heap.
-func startTimer(t *timer) {
-	if raceenabled {
-		racerelease(unsafe.Pointer(t))
-	}
-	addtimer(t)
-}
-
-// stopTimer removes t from the timer heap if it is there.
-// It returns true if t was removed, false if t wasn't even there.
-func stopTimer(t *timer) bool {
-	return deltimer(t)
-}
-
-// Go runtime.
-
-// Ready the goroutine arg.
-func goroutineReady(arg interface{}, seq uintptr) {
-	goready(arg.(*g))
-}
-
-func addtimer(t *timer) {
-	lock(&timers.lock)
-	addtimerLocked(t)
-	unlock(&timers.lock)
-}
-
-// Add a timer to the heap and start or kick the timer proc.
-// If the new timer is earlier than any of the others.
-// Timers are locked.
-func addtimerLocked(t *timer) {
-	// when must never be negative; otherwise timerproc will overflow
-	// during its delta calculation and never expire other runtime·timers.
-	if t.when < 0 {
-		t.when = 1<<63 - 1
-	}
-	t.i = len(timers.t)
-	timers.t = append(timers.t, t)
-	siftupTimer(t.i)
-	if t.i == 0 {
-		// siftup moved to top: new earliest deadline.
-		if timers.sleeping {
-			timers.sleeping = false
-			notewakeup(&timers.waitnote)
-		}
-		if timers.rescheduling {
-			timers.rescheduling = false
-			goready(timers.gp)
-		}
-	}
-	if !timers.created {
-		timers.created = true
-		go timerproc()
-	}
-}
-
-// Delete timer t from the heap.
-// Do not need to update the timerproc: if it wakes up early, no big deal.
-func deltimer(t *timer) bool {
-	// Dereference t so that any panic happens before the lock is held.
-	// Discard result, because t might be moving in the heap.
-	_ = t.i
-
-	lock(&timers.lock)
-	// t may not be registered anymore and may have
-	// a bogus i (typically 0, if generated by Go).
-	// Verify it before proceeding.
-	i := t.i
-	last := len(timers.t) - 1
-	if i < 0 || i > last || timers.t[i] != t {
-		unlock(&timers.lock)
-		return false
-	}
-	if i != last {
-		timers.t[i] = timers.t[last]
-		timers.t[i].i = i
-	}
-	timers.t[last] = nil
-	timers.t = timers.t[:last]
-	if i != last {
-		siftupTimer(i)
-		siftdownTimer(i)
-	}
-	unlock(&timers.lock)
-	return true
-}
-
-// Timerproc runs the time-driven events.
-// It sleeps until the next event in the timers heap.
-// If addtimer inserts a new earlier event, addtimer1 wakes timerproc early.
-func timerproc() {
-	timers.gp = getg()
-	timers.gp.issystem = true
-	for {
-		lock(&timers.lock)
-		timers.sleeping = false
-		now := nanotime()
-		delta := int64(-1)
-		for {
-			if len(timers.t) == 0 {
-				delta = -1
-				break
-			}
-			t := timers.t[0]
-			delta = t.when - now
-			if delta > 0 {
-				break
-			}
-			if t.period > 0 {
-				// leave in heap but adjust next time to fire
-				t.when += t.period * (1 + -delta/t.period)
-				siftdownTimer(0)
-			} else {
-				// remove from heap
-				last := len(timers.t) - 1
-				if last > 0 {
-					timers.t[0] = timers.t[last]
-					timers.t[0].i = 0
-				}
-				timers.t[last] = nil
-				timers.t = timers.t[:last]
-				if last > 0 {
-					siftdownTimer(0)
-				}
-				t.i = -1 // mark as removed
-			}
-			f := t.f
-			arg := t.arg
-			seq := t.seq
-			unlock(&timers.lock)
-			if raceenabled {
-				raceacquire(unsafe.Pointer(t))
-			}
-			f(arg, seq)
-			lock(&timers.lock)
-		}
-		if delta < 0 || faketime > 0 {
-			// No timers left - put goroutine to sleep.
-			timers.rescheduling = true
-			goparkunlock(&timers.lock, "timer goroutine (idle)")
-			continue
-		}
-		// At least one timer pending.  Sleep until then.
-		timers.sleeping = true
-		noteclear(&timers.waitnote)
-		unlock(&timers.lock)
-		notetsleepg(&timers.waitnote, delta)
-	}
-}
-
-func timejump() *g {
-	if faketime == 0 {
-		return nil
-	}
-
-	lock(&timers.lock)
-	if !timers.created || len(timers.t) == 0 {
-		unlock(&timers.lock)
-		return nil
-	}
-
-	var gp *g
-	if faketime < timers.t[0].when {
-		faketime = timers.t[0].when
-		if timers.rescheduling {
-			timers.rescheduling = false
-			gp = timers.gp
-		}
-	}
-	unlock(&timers.lock)
-	return gp
-}
-
-// Heap maintenance algorithms.
-
-func siftupTimer(i int) {
-	t := timers.t
-	when := t[i].when
-	tmp := t[i]
-	for i > 0 {
-		p := (i - 1) / 4 // parent
-		if when >= t[p].when {
-			break
-		}
-		t[i] = t[p]
-		t[i].i = i
-		t[p] = tmp
-		t[p].i = p
-		i = p
-	}
-}
-
-func siftdownTimer(i int) {
-	t := timers.t
-	n := len(t)
-	when := t[i].when
-	tmp := t[i]
-	for {
-		c := i*4 + 1 // left child
-		c3 := c + 2  // mid child
-		if c >= n {
-			break
-		}
-		w := t[c].when
-		if c+1 < n && t[c+1].when < w {
-			w = t[c+1].when
-			c++
-		}
-		if c3 < n {
-			w3 := t[c3].when
-			if c3+1 < n && t[c3+1].when < w3 {
-				w3 = t[c3+1].when
-				c3++
-			}
-			if w3 < w {
-				w = w3
-				c = c3
-			}
-		}
-		if w >= when {
-			break
-		}
-		t[i] = t[c]
-		t[i].i = i
-		t[c] = tmp
-		t[c].i = c
-		i = c
-	}
-}
diff --git a/third_party/gofrontend/libgo/go/runtime/typekind.go b/third_party/gofrontend/libgo/go/runtime/typekind.go
deleted file mode 100644
index b64ec44..0000000
--- a/third_party/gofrontend/libgo/go/runtime/typekind.go
+++ /dev/null
@@ -1,44 +0,0 @@
-// 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.
-
-package runtime
-
-const (
-	kindBool          = _KindBool
-	kindInt           = _KindInt
-	kindInt8          = _KindInt8
-	kindInt16         = _KindInt16
-	kindInt32         = _KindInt32
-	kindInt64         = _KindInt64
-	kindUint          = _KindUint
-	kindUint8         = _KindUint8
-	kindUint16        = _KindUint16
-	kindUint32        = _KindUint32
-	kindUint64        = _KindUint64
-	kindUintptr       = _KindUintptr
-	kindFloat32       = _KindFloat32
-	kindFloat64       = _KindFloat64
-	kindComplex64     = _KindComplex64
-	kindComplex128    = _KindComplex128
-	kindArray         = _KindArray
-	kindChan          = _KindChan
-	kindFunc          = _KindFunc
-	kindInterface     = _KindInterface
-	kindMap           = _KindMap
-	kindPtr           = _KindPtr
-	kindSlice         = _KindSlice
-	kindString        = _KindString
-	kindStruct        = _KindStruct
-	kindUnsafePointer = _KindUnsafePointer
-
-	kindDirectIface = _KindDirectIface
-	kindGCProg      = _KindGCProg
-	kindNoPointers  = _KindNoPointers
-	kindMask        = _KindMask
-)
-
-// isDirectIface reports whether t is stored directly in an interface value.
-func isDirectIface(t *_type) bool {
-	return t.kind&kindDirectIface != 0
-}
diff --git a/third_party/gofrontend/libgo/go/runtime/vlop_arm_test.go b/third_party/gofrontend/libgo/go/runtime/vlop_arm_test.go
deleted file mode 100644
index cd28419..0000000
--- a/third_party/gofrontend/libgo/go/runtime/vlop_arm_test.go
+++ /dev/null
@@ -1,70 +0,0 @@
-// Copyright 2012 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 runtime_test
-
-import "testing"
-
-// arm soft division benchmarks adapted from
-// http://ridiculousfish.com/files/division_benchmarks.tar.gz
-
-const numeratorsSize = 1 << 21
-
-var numerators = randomNumerators()
-
-type randstate struct {
-	hi, lo uint32
-}
-
-func (r *randstate) rand() uint32 {
-	r.hi = r.hi<<16 + r.hi>>16
-	r.hi += r.lo
-	r.lo += r.hi
-	return r.hi
-}
-
-func randomNumerators() []uint32 {
-	numerators := make([]uint32, numeratorsSize)
-	random := &randstate{2147483563, 2147483563 ^ 0x49616E42}
-	for i := range numerators {
-		numerators[i] = random.rand()
-	}
-	return numerators
-}
-
-func bmUint32Div(divisor uint32, b *testing.B) {
-	var sum uint32
-	for i := 0; i < b.N; i++ {
-		sum += numerators[i&(numeratorsSize-1)] / divisor
-	}
-}
-
-func BenchmarkUint32Div7(b *testing.B)         { bmUint32Div(7, b) }
-func BenchmarkUint32Div37(b *testing.B)        { bmUint32Div(37, b) }
-func BenchmarkUint32Div123(b *testing.B)       { bmUint32Div(123, b) }
-func BenchmarkUint32Div763(b *testing.B)       { bmUint32Div(763, b) }
-func BenchmarkUint32Div1247(b *testing.B)      { bmUint32Div(1247, b) }
-func BenchmarkUint32Div9305(b *testing.B)      { bmUint32Div(9305, b) }
-func BenchmarkUint32Div13307(b *testing.B)     { bmUint32Div(13307, b) }
-func BenchmarkUint32Div52513(b *testing.B)     { bmUint32Div(52513, b) }
-func BenchmarkUint32Div60978747(b *testing.B)  { bmUint32Div(60978747, b) }
-func BenchmarkUint32Div106956295(b *testing.B) { bmUint32Div(106956295, b) }
-
-func bmUint32Mod(divisor uint32, b *testing.B) {
-	var sum uint32
-	for i := 0; i < b.N; i++ {
-		sum += numerators[i&(numeratorsSize-1)] % divisor
-	}
-}
-
-func BenchmarkUint32Mod7(b *testing.B)         { bmUint32Mod(7, b) }
-func BenchmarkUint32Mod37(b *testing.B)        { bmUint32Mod(37, b) }
-func BenchmarkUint32Mod123(b *testing.B)       { bmUint32Mod(123, b) }
-func BenchmarkUint32Mod763(b *testing.B)       { bmUint32Mod(763, b) }
-func BenchmarkUint32Mod1247(b *testing.B)      { bmUint32Mod(1247, b) }
-func BenchmarkUint32Mod9305(b *testing.B)      { bmUint32Mod(9305, b) }
-func BenchmarkUint32Mod13307(b *testing.B)     { bmUint32Mod(13307, b) }
-func BenchmarkUint32Mod52513(b *testing.B)     { bmUint32Mod(52513, b) }
-func BenchmarkUint32Mod60978747(b *testing.B)  { bmUint32Mod(60978747, b) }
-func BenchmarkUint32Mod106956295(b *testing.B) { bmUint32Mod(106956295, b) }
diff --git a/third_party/gofrontend/libgo/go/sort/sort.go b/third_party/gofrontend/libgo/go/sort/sort.go
index e980c29..c7c3042 100644
--- a/third_party/gofrontend/libgo/go/sort/sort.go
+++ b/third_party/gofrontend/libgo/go/sort/sort.go
@@ -75,20 +75,19 @@
 // Quicksort, following Bentley and McIlroy,
 // ``Engineering a Sort Function,'' SP&E November 1993.
 
-// medianOfThree moves the median of the three values data[a], data[b], data[c] into data[a].
-func medianOfThree(data Interface, a, b, c int) {
-	m0 := b
-	m1 := a
-	m2 := c
-	// bubble sort on 3 elements
+// medianOfThree moves the median of the three values data[m0], data[m1], data[m2] into data[m1].
+func medianOfThree(data Interface, m1, m0, m2 int) {
+	// sort 3 elements
 	if data.Less(m1, m0) {
 		data.Swap(m1, m0)
 	}
+	// data[m0] <= data[m1]
 	if data.Less(m2, m1) {
 		data.Swap(m2, m1)
-	}
-	if data.Less(m1, m0) {
-		data.Swap(m1, m0)
+		// data[m0] <= data[m2] && data[m1] < data[m2]
+		if data.Less(m1, m0) {
+			data.Swap(m1, m0)
+		}
 	}
 	// now data[m0] <= data[m1] <= data[m2]
 }
@@ -297,11 +296,11 @@
 //    and Jukka Teuhola; Nordic Journal of Computing 3,1 (1996), 27-40:
 //    The given algorithms are in-place, number of Swap and Assignments
 //    grow as n log n but the algorithm is not stable.
-//  - "Fast Stable In-Plcae Sorting with O(n) Data Moves" J.I. Munro and
+//  - "Fast Stable In-Place Sorting with O(n) Data Moves" J.I. Munro and
 //    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",
@@ -316,7 +315,7 @@
 // data.Less and O(n*log(n)*log(n)) calls to data.Swap.
 func Stable(data Interface) {
 	n := data.Len()
-	blockSize := 20
+	blockSize := 20 // must be > 0
 	a, b := 0, blockSize
 	for b <= n {
 		insertionSort(data, a, b)
@@ -332,7 +331,9 @@
 			a = b
 			b += 2 * blockSize
 		}
-		symMerge(data, a, a+blockSize, n)
+		if m := a + blockSize; m < n {
+			symMerge(data, a, m, n)
+		}
 		blockSize *= 2
 	}
 }
@@ -352,72 +353,111 @@
 // rotation algorithm which uses O(M+N+gcd(M+N)) assignments. The argumentation
 // in the paper carries through for Swap operations, especially as the block
 // swapping rotate uses only O(M+N) Swaps.
+//
+// symMerge assumes non-degenerate arguments: a < m && m < b.
+// Having the caller check this condition eliminates many leaf recursion calls,
+// which improves performance.
 func symMerge(data Interface, a, m, b int) {
-	if a >= m || m >= b {
+	// Avoid unnecessary recursions of symMerge
+	// by direct insertion of data[a] into data[m:b]
+	// if data[a:m] only contains one element.
+	if m-a == 1 {
+		// Use binary search to find the lowest index i
+		// such that data[i] >= data[a] for m <= i < b.
+		// Exit the search loop with i == b in case no such index exists.
+		i := m
+		j := b
+		for i < j {
+			h := i + (j-i)/2
+			if data.Less(h, a) {
+				i = h + 1
+			} else {
+				j = h
+			}
+		}
+		// Swap values until data[a] reaches the position before i.
+		for k := a; k < i-1; k++ {
+			data.Swap(k, k+1)
+		}
+		return
+	}
+
+	// Avoid unnecessary recursions of symMerge
+	// by direct insertion of data[m] into data[a:m]
+	// if data[m:b] only contains one element.
+	if b-m == 1 {
+		// Use binary search to find the lowest index i
+		// such that data[i] > data[m] for a <= i < m.
+		// Exit the search loop with i == m in case no such index exists.
+		i := a
+		j := m
+		for i < j {
+			h := i + (j-i)/2
+			if !data.Less(m, h) {
+				i = h + 1
+			} else {
+				j = h
+			}
+		}
+		// Swap values until data[m] reaches the position i.
+		for k := m; k > i; k-- {
+			data.Swap(k, k-1)
+		}
 		return
 	}
 
 	mid := a + (b-a)/2
 	n := mid + m
-	start := 0
+	var start, r int
 	if m > mid {
 		start = n - b
-		r, p := mid, n-1
-		for start < r {
-			c := start + (r-start)/2
-			if !data.Less(p-c, c) {
-				start = c + 1
-			} else {
-				r = c
-			}
-		}
+		r = mid
 	} else {
 		start = a
-		r, p := m, n-1
-		for start < r {
-			c := start + (r-start)/2
-			if !data.Less(p-c, c) {
-				start = c + 1
-			} else {
-				r = c
-			}
+		r = m
+	}
+	p := n - 1
+
+	for start < r {
+		c := start + (r-start)/2
+		if !data.Less(p-c, c) {
+			start = c + 1
+		} else {
+			r = c
 		}
 	}
+
 	end := n - start
-	rotate(data, start, m, end)
-	symMerge(data, a, start, mid)
-	symMerge(data, mid, end, b)
+	if start < m && m < end {
+		rotate(data, start, m, end)
+	}
+	if a < start && start < mid {
+		symMerge(data, a, start, mid)
+	}
+	if mid < end && end < b {
+		symMerge(data, mid, end, b)
+	}
 }
 
 // Rotate two consecutives blocks u = data[a:m] and v = data[m:b] in data:
 // Data of the form 'x u v y' is changed to 'x v u y'.
 // Rotate performs at most b-a many calls to data.Swap.
+// Rotate assumes non-degenerate arguments: a < m && m < b.
 func rotate(data Interface, a, m, b int) {
 	i := m - a
-	if i == 0 {
-		return
-	}
 	j := b - m
-	if j == 0 {
-		return
-	}
 
-	if i == j {
-		swapRange(data, a, m, i)
-		return
-	}
-
-	p := a + i
 	for i != j {
 		if i > j {
-			swapRange(data, p-i, p, j)
+			swapRange(data, m-i, m, j)
 			i -= j
 		} else {
-			swapRange(data, p-i, p+j-i, i)
+			swapRange(data, m-i, m+j-i, i)
 			j -= i
 		}
 	}
-	swapRange(data, p-i, p, i)
+	// i == j
+	swapRange(data, m-i, m, i)
 }
 
 /*
diff --git a/third_party/gofrontend/libgo/go/strconv/atof.go b/third_party/gofrontend/libgo/go/strconv/atof.go
index beaa68d..a4f4862 100644
--- a/third_party/gofrontend/libgo/go/strconv/atof.go
+++ b/third_party/gofrontend/libgo/go/strconv/atof.go
@@ -2,8 +2,6 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-// Package strconv implements conversions to and from string representations
-// of basic data types.
 package strconv
 
 // decimal to binary floating point conversion.
diff --git a/third_party/gofrontend/libgo/go/strconv/atoi.go b/third_party/gofrontend/libgo/go/strconv/atoi.go
index 9ecec5a..965e3a2 100644
--- a/third_party/gofrontend/libgo/go/strconv/atoi.go
+++ b/third_party/gofrontend/libgo/go/strconv/atoi.go
@@ -36,13 +36,7 @@
 // IntSize is the size in bits of an int or uint value.
 const IntSize = intSize
 
-// Return the first number n such that n*base >= 1<<64.
-func cutoff64(base int) uint64 {
-	if base < 2 {
-		return 0
-	}
-	return (1<<64-1)/uint64(base) + 1
-}
+const maxUint64 = (1<<64 - 1)
 
 // ParseUint is like ParseInt but for unsigned numbers.
 func ParseUint(s string, base int, bitSize int) (n uint64, err error) {
@@ -52,7 +46,7 @@
 		bitSize = int(IntSize)
 	}
 
-	s0 := s
+	i := 0
 	switch {
 	case len(s) < 1:
 		err = ErrSyntax
@@ -65,14 +59,15 @@
 		// Look for octal, hex prefix.
 		switch {
 		case s[0] == '0' && len(s) > 1 && (s[1] == 'x' || s[1] == 'X'):
-			base = 16
-			s = s[2:]
-			if len(s) < 1 {
+			if len(s) < 3 {
 				err = ErrSyntax
 				goto Error
 			}
+			base = 16
+			i = 2
 		case s[0] == '0':
 			base = 8
+			i = 1
 		default:
 			base = 10
 		}
@@ -82,11 +77,20 @@
 		goto Error
 	}
 
-	n = 0
-	cutoff = cutoff64(base)
+	// Cutoff is the smallest number such that cutoff*base > maxUint64.
+	// Use compile-time constants for common cases.
+	switch base {
+	case 10:
+		cutoff = maxUint64/10 + 1
+	case 16:
+		cutoff = maxUint64/16 + 1
+	default:
+		cutoff = maxUint64/uint64(base) + 1
+	}
+
 	maxVal = 1<<uint(bitSize) - 1
 
-	for i := 0; i < len(s); i++ {
+	for ; i < len(s); i++ {
 		var v byte
 		d := s[i]
 		switch {
@@ -101,7 +105,7 @@
 			err = ErrSyntax
 			goto Error
 		}
-		if int(v) >= base {
+		if v >= byte(base) {
 			n = 0
 			err = ErrSyntax
 			goto Error
@@ -109,7 +113,7 @@
 
 		if n >= cutoff {
 			// n*base overflows
-			n = 1<<64 - 1
+			n = maxUint64
 			err = ErrRange
 			goto Error
 		}
@@ -118,7 +122,7 @@
 		n1 := n + uint64(v)
 		if n1 < n || n1 > maxVal {
 			// n+v overflows
-			n = 1<<64 - 1
+			n = maxUint64
 			err = ErrRange
 			goto Error
 		}
@@ -128,7 +132,7 @@
 	return n, nil
 
 Error:
-	return n, &NumError{"ParseUint", s0, err}
+	return n, &NumError{"ParseUint", s, err}
 }
 
 // ParseInt interprets a string s in the given base (2 to 36) and
diff --git a/third_party/gofrontend/libgo/go/strconv/atoi_test.go b/third_party/gofrontend/libgo/go/strconv/atoi_test.go
index 9407573..bd6a6a0 100644
--- a/third_party/gofrontend/libgo/go/strconv/atoi_test.go
+++ b/third_party/gofrontend/libgo/go/strconv/atoi_test.go
@@ -33,12 +33,16 @@
 var btoui64tests = []atoui64Test{
 	{"", 0, ErrSyntax},
 	{"0", 0, nil},
+	{"0x", 0, ErrSyntax},
+	{"0X", 0, ErrSyntax},
 	{"1", 1, nil},
 	{"12345", 12345, nil},
 	{"012345", 012345, nil},
 	{"0x12345", 0x12345, nil},
 	{"0X12345", 0x12345, nil},
 	{"12345x", 0, ErrSyntax},
+	{"0xabcdefg123", 0, ErrSyntax},
+	{"123456789abc", 0, ErrSyntax},
 	{"98765432100", 98765432100, nil},
 	{"18446744073709551615", 1<<64 - 1, nil},
 	{"18446744073709551616", 1<<64 - 1, ErrRange},
@@ -77,28 +81,61 @@
 	{"-9223372036854775809", -1 << 63, ErrRange},
 }
 
-var btoi64tests = []atoi64Test{
-	{"", 0, ErrSyntax},
-	{"0", 0, nil},
-	{"-0", 0, nil},
-	{"1", 1, nil},
-	{"-1", -1, nil},
-	{"12345", 12345, nil},
-	{"-12345", -12345, nil},
-	{"012345", 012345, nil},
-	{"-012345", -012345, nil},
-	{"0x12345", 0x12345, nil},
-	{"-0X12345", -0x12345, nil},
-	{"12345x", 0, ErrSyntax},
-	{"-12345x", 0, ErrSyntax},
-	{"98765432100", 98765432100, nil},
-	{"-98765432100", -98765432100, nil},
-	{"9223372036854775807", 1<<63 - 1, nil},
-	{"-9223372036854775807", -(1<<63 - 1), nil},
-	{"9223372036854775808", 1<<63 - 1, ErrRange},
-	{"-9223372036854775808", -1 << 63, nil},
-	{"9223372036854775809", 1<<63 - 1, ErrRange},
-	{"-9223372036854775809", -1 << 63, ErrRange},
+type btoi64Test struct {
+	in   string
+	base int
+	out  int64
+	err  error
+}
+
+var btoi64tests = []btoi64Test{
+	{"", 0, 0, ErrSyntax},
+	{"0", 0, 0, nil},
+	{"-0", 0, 0, nil},
+	{"1", 0, 1, nil},
+	{"-1", 0, -1, nil},
+	{"12345", 0, 12345, nil},
+	{"-12345", 0, -12345, nil},
+	{"012345", 0, 012345, nil},
+	{"-012345", 0, -012345, nil},
+	{"0x12345", 0, 0x12345, nil},
+	{"-0X12345", 0, -0x12345, nil},
+	{"12345x", 0, 0, ErrSyntax},
+	{"-12345x", 0, 0, ErrSyntax},
+	{"98765432100", 0, 98765432100, nil},
+	{"-98765432100", 0, -98765432100, nil},
+	{"9223372036854775807", 0, 1<<63 - 1, nil},
+	{"-9223372036854775807", 0, -(1<<63 - 1), nil},
+	{"9223372036854775808", 0, 1<<63 - 1, ErrRange},
+	{"-9223372036854775808", 0, -1 << 63, nil},
+	{"9223372036854775809", 0, 1<<63 - 1, ErrRange},
+	{"-9223372036854775809", 0, -1 << 63, ErrRange},
+
+	// other bases
+	{"g", 17, 16, nil},
+	{"10", 25, 25, nil},
+	{"holycow", 35, (((((17*35+24)*35+21)*35+34)*35+12)*35+24)*35 + 32, nil},
+	{"holycow", 36, (((((17*36+24)*36+21)*36+34)*36+12)*36+24)*36 + 32, nil},
+
+	// base 2
+	{"0", 2, 0, nil},
+	{"-1", 2, -1, nil},
+	{"1010", 2, 10, nil},
+	{"1000000000000000", 2, 1 << 15, nil},
+	{"111111111111111111111111111111111111111111111111111111111111111", 2, 1<<63 - 1, nil},
+	{"1000000000000000000000000000000000000000000000000000000000000000", 2, 1<<63 - 1, ErrRange},
+	{"-1000000000000000000000000000000000000000000000000000000000000000", 2, -1 << 63, nil},
+	{"-1000000000000000000000000000000000000000000000000000000000000001", 2, -1 << 63, ErrRange},
+
+	// base 8
+	{"-10", 8, -8, nil},
+	{"57635436545", 8, 057635436545, nil},
+	{"100000000", 8, 1 << 24, nil},
+
+	// base 16
+	{"10", 16, 16, nil},
+	{"-123456789abcdef", 16, -0x123456789abcdef, nil},
+	{"7fffffffffffffff", 16, 1<<63 - 1, nil},
 }
 
 type atoui32Test struct {
@@ -234,7 +271,7 @@
 func TestParseInt64Base(t *testing.T) {
 	for i := range btoi64tests {
 		test := &btoi64tests[i]
-		out, err := ParseInt(test.in, 0, 64)
+		out, err := ParseInt(test.in, test.base, 64)
 		if test.out != out || !reflect.DeepEqual(test.err, err) {
 			t.Errorf("ParseInt(%q) = %v, %v want %v, %v",
 				test.in, out, err, test.out, test.err)
diff --git a/third_party/gofrontend/libgo/go/strconv/decimal.go b/third_party/gofrontend/libgo/go/strconv/decimal.go
index 4260128..5252d6e 100644
--- a/third_party/gofrontend/libgo/go/strconv/decimal.go
+++ b/third_party/gofrontend/libgo/go/strconv/decimal.go
@@ -12,7 +12,7 @@
 package strconv
 
 type decimal struct {
-	d     [800]byte // digits
+	d     [800]byte // digits, big-endian representation
 	nd    int       // number of digits used
 	dp    int       // decimal point
 	neg   bool
@@ -102,16 +102,17 @@
 }
 
 // Maximum shift that we can do in one pass without overflow.
-// Signed int has 31 bits, and we have to be able to accommodate 9<<k.
-const maxShift = 27
+// A uint has 32 or 64 bits, and we have to be able to accommodate 9<<k.
+const uintSize = 32 << (^uint(0) >> 63)
+const maxShift = uintSize - 4
 
-// Binary shift right (* 2) by k bits.  k <= maxShift to avoid overflow.
+// Binary shift right (/ 2) by k bits.  k <= maxShift to avoid overflow.
 func rightShift(a *decimal, k uint) {
 	r := 0 // read pointer
 	w := 0 // write pointer
 
 	// Pick up enough leading digits to cover first shift.
-	n := 0
+	var n uint
 	for ; n>>k == 0; r++ {
 		if r >= a.nd {
 			if n == 0 {
@@ -125,14 +126,14 @@
 			}
 			break
 		}
-		c := int(a.d[r])
+		c := uint(a.d[r])
 		n = n*10 + c - '0'
 	}
 	a.dp -= r - 1
 
 	// Pick up a digit, put down a digit.
 	for ; r < a.nd; r++ {
-		c := int(a.d[r])
+		c := uint(a.d[r])
 		dig := n >> k
 		n -= dig << k
 		a.d[w] = byte(dig + '0')
@@ -169,50 +170,84 @@
 
 type leftCheat struct {
 	delta  int    // number of new digits
-	cutoff string //   minus one digit if original < a.
+	cutoff string // minus one digit if original < a.
 }
 
 var leftcheats = []leftCheat{
 	// Leading digits of 1/2^i = 5^i.
 	// 5^23 is not an exact 64-bit floating point number,
 	// so have to use bc for the math.
+	// Go up to 60 to be large enough for 32bit and 64bit platforms.
 	/*
-		seq 27 | sed 's/^/5^/' | bc |
-		awk 'BEGIN{ print "\tleftCheat{ 0, \"\" }," }
+		seq 60 | sed 's/^/5^/' | bc |
+		awk 'BEGIN{ print "\t{ 0, \"\" }," }
 		{
 			log2 = log(2)/log(10)
-			printf("\tleftCheat{ %d, \"%s\" },\t// * %d\n",
+			printf("\t{ %d, \"%s\" },\t// * %d\n",
 				int(log2*NR+1), $0, 2**NR)
 		}'
 	*/
 	{0, ""},
-	{1, "5"},                   // * 2
-	{1, "25"},                  // * 4
-	{1, "125"},                 // * 8
-	{2, "625"},                 // * 16
-	{2, "3125"},                // * 32
-	{2, "15625"},               // * 64
-	{3, "78125"},               // * 128
-	{3, "390625"},              // * 256
-	{3, "1953125"},             // * 512
-	{4, "9765625"},             // * 1024
-	{4, "48828125"},            // * 2048
-	{4, "244140625"},           // * 4096
-	{4, "1220703125"},          // * 8192
-	{5, "6103515625"},          // * 16384
-	{5, "30517578125"},         // * 32768
-	{5, "152587890625"},        // * 65536
-	{6, "762939453125"},        // * 131072
-	{6, "3814697265625"},       // * 262144
-	{6, "19073486328125"},      // * 524288
-	{7, "95367431640625"},      // * 1048576
-	{7, "476837158203125"},     // * 2097152
-	{7, "2384185791015625"},    // * 4194304
-	{7, "11920928955078125"},   // * 8388608
-	{8, "59604644775390625"},   // * 16777216
-	{8, "298023223876953125"},  // * 33554432
-	{8, "1490116119384765625"}, // * 67108864
-	{9, "7450580596923828125"}, // * 134217728
+	{1, "5"},                                           // * 2
+	{1, "25"},                                          // * 4
+	{1, "125"},                                         // * 8
+	{2, "625"},                                         // * 16
+	{2, "3125"},                                        // * 32
+	{2, "15625"},                                       // * 64
+	{3, "78125"},                                       // * 128
+	{3, "390625"},                                      // * 256
+	{3, "1953125"},                                     // * 512
+	{4, "9765625"},                                     // * 1024
+	{4, "48828125"},                                    // * 2048
+	{4, "244140625"},                                   // * 4096
+	{4, "1220703125"},                                  // * 8192
+	{5, "6103515625"},                                  // * 16384
+	{5, "30517578125"},                                 // * 32768
+	{5, "152587890625"},                                // * 65536
+	{6, "762939453125"},                                // * 131072
+	{6, "3814697265625"},                               // * 262144
+	{6, "19073486328125"},                              // * 524288
+	{7, "95367431640625"},                              // * 1048576
+	{7, "476837158203125"},                             // * 2097152
+	{7, "2384185791015625"},                            // * 4194304
+	{7, "11920928955078125"},                           // * 8388608
+	{8, "59604644775390625"},                           // * 16777216
+	{8, "298023223876953125"},                          // * 33554432
+	{8, "1490116119384765625"},                         // * 67108864
+	{9, "7450580596923828125"},                         // * 134217728
+	{9, "37252902984619140625"},                        // * 268435456
+	{9, "186264514923095703125"},                       // * 536870912
+	{10, "931322574615478515625"},                      // * 1073741824
+	{10, "4656612873077392578125"},                     // * 2147483648
+	{10, "23283064365386962890625"},                    // * 4294967296
+	{10, "116415321826934814453125"},                   // * 8589934592
+	{11, "582076609134674072265625"},                   // * 17179869184
+	{11, "2910383045673370361328125"},                  // * 34359738368
+	{11, "14551915228366851806640625"},                 // * 68719476736
+	{12, "72759576141834259033203125"},                 // * 137438953472
+	{12, "363797880709171295166015625"},                // * 274877906944
+	{12, "1818989403545856475830078125"},               // * 549755813888
+	{13, "9094947017729282379150390625"},               // * 1099511627776
+	{13, "45474735088646411895751953125"},              // * 2199023255552
+	{13, "227373675443232059478759765625"},             // * 4398046511104
+	{13, "1136868377216160297393798828125"},            // * 8796093022208
+	{14, "5684341886080801486968994140625"},            // * 17592186044416
+	{14, "28421709430404007434844970703125"},           // * 35184372088832
+	{14, "142108547152020037174224853515625"},          // * 70368744177664
+	{15, "710542735760100185871124267578125"},          // * 140737488355328
+	{15, "3552713678800500929355621337890625"},         // * 281474976710656
+	{15, "17763568394002504646778106689453125"},        // * 562949953421312
+	{16, "88817841970012523233890533447265625"},        // * 1125899906842624
+	{16, "444089209850062616169452667236328125"},       // * 2251799813685248
+	{16, "2220446049250313080847263336181640625"},      // * 4503599627370496
+	{16, "11102230246251565404236316680908203125"},     // * 9007199254740992
+	{17, "55511151231257827021181583404541015625"},     // * 18014398509481984
+	{17, "277555756156289135105907917022705078125"},    // * 36028797018963968
+	{17, "1387778780781445675529539585113525390625"},   // * 72057594037927936
+	{18, "6938893903907228377647697925567626953125"},   // * 144115188075855872
+	{18, "34694469519536141888238489627838134765625"},  // * 288230376151711744
+	{18, "173472347597680709441192448139190673828125"}, // * 576460752303423488
+	{19, "867361737988403547205962240695953369140625"}, // * 1152921504606846976
 }
 
 // Is the leading prefix of b lexicographically less than s?
@@ -228,7 +263,7 @@
 	return false
 }
 
-// Binary shift left (/ 2) by k bits.  k <= maxShift to avoid overflow.
+// Binary shift left (* 2) by k bits.  k <= maxShift to avoid overflow.
 func leftShift(a *decimal, k uint) {
 	delta := leftcheats[k].delta
 	if prefixIsLessThan(a.d[0:a.nd], leftcheats[k].cutoff) {
@@ -237,11 +272,11 @@
 
 	r := a.nd         // read index
 	w := a.nd + delta // write index
-	n := 0
 
 	// Pick up a digit, put down a digit.
+	var n uint
 	for r--; r >= 0; r-- {
-		n += (int(a.d[r]) - '0') << k
+		n += (uint(a.d[r]) - '0') << k
 		quo := n / 10
 		rem := n - 10*quo
 		w--
diff --git a/third_party/gofrontend/libgo/go/strconv/doc.go b/third_party/gofrontend/libgo/go/strconv/doc.go
new file mode 100644
index 0000000..7bc1e27
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/strconv/doc.go
@@ -0,0 +1,57 @@
+// 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 strconv implements conversions to and from string representations
+// of basic data types.
+//
+// Numeric Conversions
+//
+// The most common numeric conversions are Atoi (string to int) and Itoa (int to string).
+//
+//	i, err := strconv.Atoi("-42")
+//	s := strconv.Itoa(-42)
+//
+// These assume decimal and the Go int type.
+//
+// ParseBool, ParseFloat, ParseInt, and ParseUint convert strings to values:
+//
+//	b, err := strconv.ParseBool("true")
+//	f, err := strconv.ParseFloat("3.1415", 64)
+//	i, err := strconv.ParseInt("-42", 10, 64)
+//	u, err := strconv.ParseUint("42", 10, 64)
+//
+// The parse functions return the widest type (float64, int64, and uint64),
+// but if the size argument specifies a narrower width the result can be
+// converted to that narrower type without data loss:
+//
+//	s := "2147483647" // biggest int32
+//	i64, err := strconv.ParseInt(s, 10, 32)
+//	...
+//	i := int32(i64)
+//
+// FormatBool, FormatFloat, FormatInt, and FormatUint convert values to strings:
+//
+// 	s := strconv.FormatBool(true)
+// 	s := strconv.FormatFloat(3.1415, 'E', -1, 64)
+// 	s := strconv.FormatInt(-42, 16)
+// 	s := strconv.FormatUint(42, 16)
+//
+// AppendBool, AppendFloat, AppendInt, and AppendUint are similar but
+// append the formatted value to a destination slice.
+//
+// String Conversions
+//
+// Quote and QuoteToASCII convert strings to quoted Go string literals.
+// The latter guarantees that the result is an ASCII string, by escaping
+// any non-ASCII Unicode with \u:
+//
+//	q := Quote("Hello, 世界")
+//	q := QuoteToASCII("Hello, 世界")
+//
+// QuoteRune and QuoteRuneToASCII are similar but accept runes and
+// return quoted Go rune literals.
+//
+// Unquote and UnquoteChar unquote Go string and rune literals.
+//
+package strconv
diff --git a/third_party/gofrontend/libgo/go/strconv/example_test.go b/third_party/gofrontend/libgo/go/strconv/example_test.go
new file mode 100644
index 0000000..01fbbc0
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/strconv/example_test.go
@@ -0,0 +1,338 @@
+// 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 strconv_test
+
+import (
+	"fmt"
+	"log"
+	"strconv"
+)
+
+func ExampleAppendBool() {
+	b := []byte("bool:")
+	b = strconv.AppendBool(b, true)
+	fmt.Println(string(b))
+
+	// Output:
+	// bool:true
+}
+
+func ExampleAppendFloat() {
+	b32 := []byte("float32:")
+	b32 = strconv.AppendFloat(b32, 3.1415926535, 'E', -1, 32)
+	fmt.Println(string(b32))
+
+	b64 := []byte("float64:")
+	b64 = strconv.AppendFloat(b64, 3.1415926535, 'E', -1, 64)
+	fmt.Println(string(b64))
+
+	// Output:
+	// float32:3.1415927E+00
+	// float64:3.1415926535E+00
+}
+
+func ExampleAppendInt() {
+	b10 := []byte("int (base 10):")
+	b10 = strconv.AppendInt(b10, -42, 10)
+	fmt.Println(string(b10))
+
+	b16 := []byte("int (base 16):")
+	b16 = strconv.AppendInt(b16, -42, 16)
+	fmt.Println(string(b16))
+
+	// Output:
+	// int (base 10):-42
+	// int (base 16):-2a
+}
+
+func ExampleAppendQuote() {
+	b := []byte("quote:")
+	b = strconv.AppendQuote(b, `"Fran & Freddie's Diner"`)
+	fmt.Println(string(b))
+
+	// Output:
+	// quote:"\"Fran & Freddie's Diner\""
+}
+
+func ExampleAppendQuoteRune() {
+	b := []byte("rune:")
+	b = strconv.AppendQuoteRune(b, '☺')
+	fmt.Println(string(b))
+
+	// Output:
+	// rune:'☺'
+}
+
+func ExampleAppendQuoteRuneToASCII() {
+	b := []byte("rune (ascii):")
+	b = strconv.AppendQuoteRuneToASCII(b, '☺')
+	fmt.Println(string(b))
+
+	// Output:
+	// rune (ascii):'\u263a'
+}
+
+func ExampleAppendQuoteToASCII() {
+	b := []byte("quote (ascii):")
+	b = strconv.AppendQuoteToASCII(b, `"Fran & Freddie's Diner"`)
+	fmt.Println(string(b))
+
+	// Output:
+	// quote (ascii):"\"Fran & Freddie's Diner\""
+}
+
+func ExampleAppendUint() {
+	b10 := []byte("uint (base 10):")
+	b10 = strconv.AppendUint(b10, 42, 10)
+	fmt.Println(string(b10))
+
+	b16 := []byte("uint (base 16):")
+	b16 = strconv.AppendUint(b16, 42, 16)
+	fmt.Println(string(b16))
+
+	// Output:
+	// uint (base 10):42
+	// uint (base 16):2a
+}
+
+func ExampleAtoi() {
+	v := "10"
+	if s, err := strconv.Atoi(v); err == nil {
+		fmt.Printf("%T, %v", s, s)
+	}
+
+	// Output:
+	// int, 10
+}
+
+func ExampleCanBackquote() {
+	fmt.Println(strconv.CanBackquote("Fran & Freddie's Diner ☺"))
+	fmt.Println(strconv.CanBackquote("`can't backquote this`"))
+
+	// Output:
+	// true
+	// false
+}
+
+func ExampleFormatBool() {
+	v := true
+	s := strconv.FormatBool(v)
+	fmt.Printf("%T, %v\n", s, s)
+
+	// Output:
+	// string, true
+}
+
+func ExampleFormatFloat() {
+	v := 3.1415926535
+
+	s32 := strconv.FormatFloat(v, 'E', -1, 32)
+	fmt.Printf("%T, %v\n", s32, s32)
+
+	s64 := strconv.FormatFloat(v, 'E', -1, 64)
+	fmt.Printf("%T, %v\n", s64, s64)
+
+	// Output:
+	// string, 3.1415927E+00
+	// string, 3.1415926535E+00
+}
+
+func ExampleFormatInt() {
+	v := int64(-42)
+
+	s10 := strconv.FormatInt(v, 10)
+	fmt.Printf("%T, %v\n", s10, s10)
+
+	s16 := strconv.FormatInt(v, 16)
+	fmt.Printf("%T, %v\n", s16, s16)
+
+	// Output:
+	// string, -42
+	// string, -2a
+}
+
+func ExampleFormatUint() {
+	v := uint64(42)
+
+	s10 := strconv.FormatUint(v, 10)
+	fmt.Printf("%T, %v\n", s10, s10)
+
+	s16 := strconv.FormatUint(v, 16)
+	fmt.Printf("%T, %v\n", s16, s16)
+
+	// Output:
+	// string, 42
+	// string, 2a
+}
+
+func ExampleIsPrint() {
+	c := strconv.IsPrint('\u263a')
+	fmt.Println(c)
+
+	bel := strconv.IsPrint('\007')
+	fmt.Println(bel)
+
+	// Output:
+	// true
+	// false
+}
+
+func ExampleItoa() {
+	i := 10
+	s := strconv.Itoa(i)
+	fmt.Printf("%T, %v\n", s, s)
+
+	// Output:
+	// string, 10
+}
+
+func ExampleParseBool() {
+	v := "true"
+	if s, err := strconv.ParseBool(v); err == nil {
+		fmt.Printf("%T, %v\n", s, s)
+	}
+
+	// Output:
+	// bool, true
+}
+
+func ExampleParseFloat() {
+	v := "3.1415926535"
+	if s, err := strconv.ParseFloat(v, 32); err == nil {
+		fmt.Printf("%T, %v\n", s, s)
+	}
+	if s, err := strconv.ParseFloat(v, 64); err == nil {
+		fmt.Printf("%T, %v\n", s, s)
+	}
+
+	// Output:
+	// float64, 3.1415927410125732
+	// float64, 3.1415926535
+}
+
+func ExampleParseInt() {
+	v32 := "-354634382"
+	if s, err := strconv.ParseInt(v32, 10, 32); err == nil {
+		fmt.Printf("%T, %v\n", s, s)
+	}
+	if s, err := strconv.ParseInt(v32, 16, 32); err == nil {
+		fmt.Printf("%T, %v\n", s, s)
+	}
+
+	v64 := "-3546343826724305832"
+	if s, err := strconv.ParseInt(v64, 10, 64); err == nil {
+		fmt.Printf("%T, %v\n", s, s)
+	}
+	if s, err := strconv.ParseInt(v64, 16, 64); err == nil {
+		fmt.Printf("%T, %v\n", s, s)
+	}
+
+	// Output:
+	// int64, -354634382
+	// int64, -3546343826724305832
+}
+
+func ExampleParseUint() {
+	v := "42"
+	if s, err := strconv.ParseUint(v, 10, 32); err == nil {
+		fmt.Printf("%T, %v\n", s, s)
+	}
+	if s, err := strconv.ParseUint(v, 10, 64); err == nil {
+		fmt.Printf("%T, %v\n", s, s)
+	}
+
+	// Output:
+	// uint64, 42
+	// uint64, 42
+}
+
+func ExampleQuote() {
+	s := strconv.Quote(`"Fran & Freddie's Diner	☺"`)
+	fmt.Println(s)
+
+	// Output:
+	// "\"Fran & Freddie's Diner\t☺\""
+}
+
+func ExampleQuoteRune() {
+	s := strconv.QuoteRune('☺')
+	fmt.Println(s)
+
+	// Output:
+	// '☺'
+}
+
+func ExampleQuoteRuneToASCII() {
+	s := strconv.QuoteRuneToASCII('☺')
+	fmt.Println(s)
+
+	// Output:
+	// '\u263a'
+}
+
+func ExampleQuoteToASCII() {
+	s := strconv.QuoteToASCII(`"Fran & Freddie's Diner	☺"`)
+	fmt.Println(s)
+
+	// Output:
+	// "\"Fran & Freddie's Diner\t\u263a\""
+}
+
+func ExampleUnquote() {
+	test := func(s string) {
+		t, err := strconv.Unquote(s)
+		if err != nil {
+			fmt.Printf("Unquote(%#v): %v\n", s, err)
+		} else {
+			fmt.Printf("Unquote(%#v) = %v\n", s, t)
+		}
+	}
+
+	s := `\"Fran & Freddie's Diner\t\u263a\"\"`
+	// If the string doesn't have quotes, it can't be unquoted.
+	test(s) // invalid syntax
+	test("`" + s + "`")
+	test(`"` + s + `"`)
+	test(`'\u263a'`)
+
+	// Output:
+	// Unquote("\\\"Fran & Freddie's Diner\\t\\u263a\\\"\\\""): invalid syntax
+	// Unquote("`\\\"Fran & Freddie's Diner\\t\\u263a\\\"\\\"`") = \"Fran & Freddie's Diner\t\u263a\"\"
+	// Unquote("\"\\\"Fran & Freddie's Diner\\t\\u263a\\\"\\\"\"") = "Fran & Freddie's Diner	☺""
+	// Unquote("'\\u263a'") = ☺
+}
+
+func ExampleUnquoteChar() {
+	v, mb, t, err := strconv.UnquoteChar(`\"Fran & Freddie's Diner\"`, '"')
+	if err != nil {
+		log.Fatal(err)
+	}
+
+	fmt.Println("value:", string(v))
+	fmt.Println("multibyte:", mb)
+	fmt.Println("tail:", t)
+
+	// Output:
+	// value: "
+	// multibyte: false
+	// tail: Fran & Freddie's Diner\"
+}
+
+func ExampleNumError() {
+	str := "Not a number"
+	if _, err := strconv.ParseFloat(str, 64); err != nil {
+		e := err.(*strconv.NumError)
+		fmt.Println("Func:", e.Func)
+		fmt.Println("Num:", e.Num)
+		fmt.Println("Err:", e.Err)
+		fmt.Println(err)
+	}
+
+	// Output:
+	// Func: ParseFloat
+	// Num: Not a number
+	// Err: invalid syntax
+	// strconv.ParseFloat: parsing "Not a number": invalid syntax
+}
diff --git a/third_party/gofrontend/libgo/go/strconv/extfloat.go b/third_party/gofrontend/libgo/go/strconv/extfloat.go
index bed8b16..019b4ee 100644
--- a/third_party/gofrontend/libgo/go/strconv/extfloat.go
+++ b/third_party/gofrontend/libgo/go/strconv/extfloat.go
@@ -256,7 +256,7 @@
 }
 
 // AssignDecimal sets f to an approximate value mantissa*10^exp. It
-// returns true if the value represented by f is guaranteed to be the
+// reports whether the value represented by f is guaranteed to be the
 // best approximation of d after being rounded to a float64 or
 // float32 depending on flt.
 func (f *extFloat) AssignDecimal(mantissa uint64, exp10 int, neg bool, trunc bool, flt *floatInfo) (ok bool) {
diff --git a/third_party/gofrontend/libgo/go/strconv/ftoa.go b/third_party/gofrontend/libgo/go/strconv/ftoa.go
index 1a9c41b..468c37f 100644
--- a/third_party/gofrontend/libgo/go/strconv/ftoa.go
+++ b/third_party/gofrontend/libgo/go/strconv/ftoa.go
@@ -47,7 +47,7 @@
 
 // AppendFloat appends the string form of the floating-point number f,
 // as generated by FormatFloat, to dst and returns the extended buffer.
-func AppendFloat(dst []byte, f float64, fmt byte, prec int, bitSize int) []byte {
+func AppendFloat(dst []byte, f float64, fmt byte, prec, bitSize int) []byte {
 	return genericFtoa(dst, f, fmt, prec, bitSize)
 }
 
@@ -119,7 +119,7 @@
 		// Precision for shortest representation mode.
 		switch fmt {
 		case 'e', 'E':
-			prec = digs.nd - 1
+			prec = max(digs.nd-1, 0)
 		case 'f':
 			prec = max(digs.nd-digs.dp, 0)
 		case 'g', 'G':
@@ -223,9 +223,8 @@
 	return append(dst, '%', fmt)
 }
 
-// Round d (= mant * 2^exp) to the shortest number of digits
-// that will let the original floating point value be precisely
-// reconstructed.  Size is original floating point size (64 or 32).
+// roundShortest rounds d (= mant * 2^exp) to the shortest number of digits
+// that will let the original floating point value be precisely reconstructed.
 func roundShortest(d *decimal, mant uint64, exp int, flt *floatInfo) {
 	// If mantissa is zero, the number is zero; stop now.
 	if mant == 0 {
@@ -348,14 +347,13 @@
 	if prec > 0 {
 		dst = append(dst, '.')
 		i := 1
-		m := d.nd + prec + 1 - max(d.nd, prec+1)
-		for i < m {
-			dst = append(dst, d.d[i])
-			i++
+		m := min(d.nd, prec+1)
+		if i < m {
+			dst = append(dst, d.d[i:m]...)
+			i = m
 		}
-		for i <= prec {
+		for ; i <= prec; i++ {
 			dst = append(dst, '0')
-			i++
 		}
 	}
 
@@ -373,27 +371,16 @@
 	}
 	dst = append(dst, ch)
 
-	// dddd
-	var buf [3]byte
-	i := len(buf)
-	for exp >= 10 {
-		i--
-		buf[i] = byte(exp%10 + '0')
-		exp /= 10
+	// dd or ddd
+	switch {
+	case exp < 10:
+		dst = append(dst, '0', byte(exp)+'0')
+	case exp < 100:
+		dst = append(dst, byte(exp/10)+'0', byte(exp%10)+'0')
+	default:
+		dst = append(dst, byte(exp/100)+'0', byte(exp/10)%10+'0', byte(exp%10)+'0')
 	}
-	// exp < 10
-	i--
-	buf[i] = byte(exp + '0')
 
-	switch i {
-	case 0:
-		dst = append(dst, buf[0], buf[1], buf[2])
-	case 1:
-		dst = append(dst, buf[1], buf[2])
-	case 2:
-		// leading zeroes
-		dst = append(dst, '0', buf[2])
-	}
 	return dst
 }
 
@@ -406,11 +393,9 @@
 
 	// integer, padded with zeros as needed.
 	if d.dp > 0 {
-		var i int
-		for i = 0; i < d.dp && i < d.nd; i++ {
-			dst = append(dst, d.d[i])
-		}
-		for ; i < d.dp; i++ {
+		m := min(d.nd, d.dp)
+		dst = append(dst, d.d[:m]...)
+		for ; m < d.dp; m++ {
 			dst = append(dst, '0')
 		}
 	} else {
@@ -432,39 +417,34 @@
 	return dst
 }
 
-// %b: -ddddddddp+ddd
+// %b: -ddddddddp±ddd
 func fmtB(dst []byte, neg bool, mant uint64, exp int, flt *floatInfo) []byte {
-	var buf [50]byte
-	w := len(buf)
-	exp -= int(flt.mantbits)
-	esign := byte('+')
-	if exp < 0 {
-		esign = '-'
-		exp = -exp
-	}
-	n := 0
-	for exp > 0 || n < 1 {
-		n++
-		w--
-		buf[w] = byte(exp%10 + '0')
-		exp /= 10
-	}
-	w--
-	buf[w] = esign
-	w--
-	buf[w] = 'p'
-	n = 0
-	for mant > 0 || n < 1 {
-		n++
-		w--
-		buf[w] = byte(mant%10 + '0')
-		mant /= 10
-	}
+	// sign
 	if neg {
-		w--
-		buf[w] = '-'
+		dst = append(dst, '-')
 	}
-	return append(dst, buf[w:]...)
+
+	// mantissa
+	dst, _ = formatBits(dst, mant, 10, false, true)
+
+	// p
+	dst = append(dst, 'p')
+
+	// ±exponent
+	exp -= int(flt.mantbits)
+	if exp >= 0 {
+		dst = append(dst, '+')
+	}
+	dst, _ = formatBits(dst, uint64(exp), 10, exp < 0, true)
+
+	return dst
+}
+
+func min(a, b int) int {
+	if a < b {
+		return a
+	}
+	return b
 }
 
 func max(a, b int) int {
diff --git a/third_party/gofrontend/libgo/go/strconv/ftoa_test.go b/third_party/gofrontend/libgo/go/strconv/ftoa_test.go
index 39b8615..1b4dcd9 100644
--- a/third_party/gofrontend/libgo/go/strconv/ftoa_test.go
+++ b/third_party/gofrontend/libgo/go/strconv/ftoa_test.go
@@ -227,6 +227,7 @@
 func BenchmarkAppendFloatBig(b *testing.B) {
 	benchmarkAppendFloat(b, 123456789123456789123456789, 'g', -1, 64)
 }
+func BenchmarkAppendFloatBinaryExp(b *testing.B) { benchmarkAppendFloat(b, -1, 'b', -1, 64) }
 
 func BenchmarkAppendFloat32Integer(b *testing.B)       { benchmarkAppendFloat(b, 33909, 'g', -1, 32) }
 func BenchmarkAppendFloat32ExactFraction(b *testing.B) { benchmarkAppendFloat(b, 3.375, 'g', -1, 32) }
diff --git a/third_party/gofrontend/libgo/go/strconv/isprint.go b/third_party/gofrontend/libgo/go/strconv/isprint.go
index 80738ed..0cf363c 100644
--- a/third_party/gofrontend/libgo/go/strconv/isprint.go
+++ b/third_party/gofrontend/libgo/go/strconv/isprint.go
@@ -7,7 +7,7 @@
 
 package strconv
 
-// (468+138+67)*2 + (326)*4 = 2650 bytes
+// (470+136+73)*2 + (342)*4 = 2726 bytes
 
 var isPrint16 = []uint16{
 	0x0020, 0x007e,
@@ -26,8 +26,8 @@
 	0x0800, 0x082d,
 	0x0830, 0x085b,
 	0x085e, 0x085e,
-	0x08a0, 0x08b2,
-	0x08e4, 0x098c,
+	0x08a0, 0x08b4,
+	0x08e3, 0x098c,
 	0x098f, 0x0990,
 	0x0993, 0x09b2,
 	0x09b6, 0x09b9,
@@ -51,6 +51,7 @@
 	0x0ad0, 0x0ad0,
 	0x0ae0, 0x0ae3,
 	0x0ae6, 0x0af1,
+	0x0af9, 0x0af9,
 	0x0b01, 0x0b0c,
 	0x0b0f, 0x0b10,
 	0x0b13, 0x0b39,
@@ -73,7 +74,7 @@
 	0x0be6, 0x0bfa,
 	0x0c00, 0x0c39,
 	0x0c3d, 0x0c4d,
-	0x0c55, 0x0c59,
+	0x0c55, 0x0c5a,
 	0x0c60, 0x0c63,
 	0x0c66, 0x0c6f,
 	0x0c78, 0x0cb9,
@@ -84,7 +85,7 @@
 	0x0d01, 0x0d3a,
 	0x0d3d, 0x0d4e,
 	0x0d57, 0x0d57,
-	0x0d60, 0x0d63,
+	0x0d5f, 0x0d63,
 	0x0d66, 0x0d75,
 	0x0d79, 0x0d7f,
 	0x0d82, 0x0d96,
@@ -117,7 +118,8 @@
 	0x1318, 0x135a,
 	0x135d, 0x137c,
 	0x1380, 0x1399,
-	0x13a0, 0x13f4,
+	0x13a0, 0x13f5,
+	0x13f8, 0x13fd,
 	0x1400, 0x169c,
 	0x16a0, 0x16f8,
 	0x1700, 0x1714,
@@ -167,9 +169,9 @@
 	0x2030, 0x205e,
 	0x2070, 0x2071,
 	0x2074, 0x209c,
-	0x20a0, 0x20bd,
+	0x20a0, 0x20be,
 	0x20d0, 0x20f0,
-	0x2100, 0x2189,
+	0x2100, 0x218b,
 	0x2190, 0x23fa,
 	0x2400, 0x2426,
 	0x2440, 0x244a,
@@ -177,6 +179,7 @@
 	0x2b76, 0x2b95,
 	0x2b98, 0x2bb9,
 	0x2bbd, 0x2bd1,
+	0x2bec, 0x2bef,
 	0x2c00, 0x2cf3,
 	0x2cf9, 0x2d27,
 	0x2d2d, 0x2d2d,
@@ -193,19 +196,19 @@
 	0x3131, 0x31ba,
 	0x31c0, 0x31e3,
 	0x31f0, 0x4db5,
-	0x4dc0, 0x9fcc,
+	0x4dc0, 0x9fd5,
 	0xa000, 0xa48c,
 	0xa490, 0xa4c6,
 	0xa4d0, 0xa62b,
 	0xa640, 0xa6f7,
 	0xa700, 0xa7ad,
-	0xa7b0, 0xa7b1,
+	0xa7b0, 0xa7b7,
 	0xa7f7, 0xa82b,
 	0xa830, 0xa839,
 	0xa840, 0xa877,
 	0xa880, 0xa8c4,
 	0xa8ce, 0xa8d9,
-	0xa8e0, 0xa8fb,
+	0xa8e0, 0xa8fd,
 	0xa900, 0xa953,
 	0xa95f, 0xa97c,
 	0xa980, 0xa9d9,
@@ -217,9 +220,8 @@
 	0xab01, 0xab06,
 	0xab09, 0xab0e,
 	0xab11, 0xab16,
-	0xab20, 0xab5f,
-	0xab64, 0xab65,
-	0xabc0, 0xabed,
+	0xab20, 0xab65,
+	0xab70, 0xabed,
 	0xabf0, 0xabf9,
 	0xac00, 0xd7a3,
 	0xd7b0, 0xd7c6,
@@ -234,8 +236,7 @@
 	0xfd92, 0xfdc7,
 	0xfdf0, 0xfdfd,
 	0xfe00, 0xfe19,
-	0xfe20, 0xfe2d,
-	0xfe30, 0xfe6b,
+	0xfe20, 0xfe6b,
 	0xfe70, 0xfefc,
 	0xff01, 0xffbe,
 	0xffc2, 0xffc7,
@@ -370,8 +371,6 @@
 	0x318f,
 	0x321f,
 	0x32ff,
-	0xa69e,
-	0xa78f,
 	0xa9ce,
 	0xa9ff,
 	0xab27,
@@ -418,12 +417,13 @@
 	0x01083c, 0x01083c,
 	0x01083f, 0x01089e,
 	0x0108a7, 0x0108af,
-	0x010900, 0x01091b,
+	0x0108e0, 0x0108f5,
+	0x0108fb, 0x01091b,
 	0x01091f, 0x010939,
 	0x01093f, 0x01093f,
 	0x010980, 0x0109b7,
-	0x0109be, 0x0109bf,
-	0x010a00, 0x010a06,
+	0x0109bc, 0x0109cf,
+	0x0109d2, 0x010a06,
 	0x010a0c, 0x010a33,
 	0x010a38, 0x010a3a,
 	0x010a3f, 0x010a47,
@@ -438,6 +438,9 @@
 	0x010b99, 0x010b9c,
 	0x010ba9, 0x010baf,
 	0x010c00, 0x010c48,
+	0x010c80, 0x010cb2,
+	0x010cc0, 0x010cf2,
+	0x010cfa, 0x010cff,
 	0x010e60, 0x010e7e,
 	0x011000, 0x01104d,
 	0x011052, 0x01106f,
@@ -446,19 +449,19 @@
 	0x0110f0, 0x0110f9,
 	0x011100, 0x011143,
 	0x011150, 0x011176,
-	0x011180, 0x0111c8,
-	0x0111cd, 0x0111cd,
-	0x0111d0, 0x0111da,
-	0x0111e1, 0x0111f4,
+	0x011180, 0x0111cd,
+	0x0111d0, 0x0111f4,
 	0x011200, 0x01123d,
+	0x011280, 0x0112a9,
 	0x0112b0, 0x0112ea,
 	0x0112f0, 0x0112f9,
-	0x011301, 0x01130c,
+	0x011300, 0x01130c,
 	0x01130f, 0x011310,
 	0x011313, 0x011339,
 	0x01133c, 0x011344,
 	0x011347, 0x011348,
 	0x01134b, 0x01134d,
+	0x011350, 0x011350,
 	0x011357, 0x011357,
 	0x01135d, 0x011363,
 	0x011366, 0x01136c,
@@ -466,17 +469,22 @@
 	0x011480, 0x0114c7,
 	0x0114d0, 0x0114d9,
 	0x011580, 0x0115b5,
-	0x0115b8, 0x0115c9,
+	0x0115b8, 0x0115dd,
 	0x011600, 0x011644,
 	0x011650, 0x011659,
 	0x011680, 0x0116b7,
 	0x0116c0, 0x0116c9,
+	0x011700, 0x011719,
+	0x01171d, 0x01172b,
+	0x011730, 0x01173f,
 	0x0118a0, 0x0118f2,
 	0x0118ff, 0x0118ff,
 	0x011ac0, 0x011af8,
-	0x012000, 0x012398,
+	0x012000, 0x012399,
 	0x012400, 0x012474,
+	0x012480, 0x012543,
 	0x013000, 0x01342e,
+	0x014400, 0x014646,
 	0x016800, 0x016a38,
 	0x016a40, 0x016a69,
 	0x016a6e, 0x016a6f,
@@ -497,7 +505,7 @@
 	0x01d000, 0x01d0f5,
 	0x01d100, 0x01d126,
 	0x01d129, 0x01d172,
-	0x01d17b, 0x01d1dd,
+	0x01d17b, 0x01d1e8,
 	0x01d200, 0x01d245,
 	0x01d300, 0x01d356,
 	0x01d360, 0x01d371,
@@ -508,7 +516,8 @@
 	0x01d50d, 0x01d546,
 	0x01d54a, 0x01d6a5,
 	0x01d6a8, 0x01d7cb,
-	0x01d7ce, 0x01d7ff,
+	0x01d7ce, 0x01da8b,
+	0x01da9b, 0x01daaf,
 	0x01e800, 0x01e8c4,
 	0x01e8c7, 0x01e8d6,
 	0x01ee00, 0x01ee24,
@@ -530,13 +539,7 @@
 	0x01f210, 0x01f23a,
 	0x01f240, 0x01f248,
 	0x01f250, 0x01f251,
-	0x01f300, 0x01f32c,
-	0x01f330, 0x01f37d,
-	0x01f380, 0x01f3ce,
-	0x01f3d4, 0x01f3f7,
-	0x01f400, 0x01f54a,
-	0x01f550, 0x01f642,
-	0x01f645, 0x01f6cf,
+	0x01f300, 0x01f6d0,
 	0x01f6e0, 0x01f6ec,
 	0x01f6f0, 0x01f6f3,
 	0x01f700, 0x01f773,
@@ -546,9 +549,13 @@
 	0x01f850, 0x01f859,
 	0x01f860, 0x01f887,
 	0x01f890, 0x01f8ad,
+	0x01f910, 0x01f918,
+	0x01f980, 0x01f984,
+	0x01f9c0, 0x01f9c0,
 	0x020000, 0x02a6d6,
 	0x02a700, 0x02b734,
 	0x02b740, 0x02b81d,
+	0x02b820, 0x02cea1,
 	0x02f800, 0x02fa1d,
 	0x0e0100, 0x0e01ef,
 }
@@ -562,12 +569,18 @@
 	0x0809,
 	0x0836,
 	0x0856,
+	0x08f3,
 	0x0a04,
 	0x0a14,
 	0x0a18,
 	0x10bd,
 	0x1135,
+	0x11e0,
 	0x1212,
+	0x1287,
+	0x1289,
+	0x128e,
+	0x129e,
 	0x1304,
 	0x1329,
 	0x1331,
@@ -589,6 +602,7 @@
 	0xd53f,
 	0xd545,
 	0xd551,
+	0xdaa0,
 	0xee04,
 	0xee20,
 	0xee23,
@@ -618,7 +632,6 @@
 	0xf0c0,
 	0xf0d0,
 	0xf12f,
-	0xf4ff,
 	0xf57a,
 	0xf5a4,
 }
diff --git a/third_party/gofrontend/libgo/go/strconv/itoa.go b/third_party/gofrontend/libgo/go/strconv/itoa.go
index 67f17d8..e6f6303 100644
--- a/third_party/gofrontend/libgo/go/strconv/itoa.go
+++ b/third_party/gofrontend/libgo/go/strconv/itoa.go
@@ -40,9 +40,7 @@
 }
 
 const (
-	digits   = "0123456789abcdefghijklmnopqrstuvwxyz"
-	digits01 = "0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789"
-	digits10 = "0000000000111111111122222222223333333333444444444455555555556666666666777777777788888888889999999999"
+	digits = "0123456789abcdefghijklmnopqrstuvwxyz"
 )
 
 var shifts = [len(digits) + 1]uint{
@@ -74,23 +72,34 @@
 
 	// convert bits
 	if base == 10 {
-		// common case: use constants for / and % because
-		// the compiler can optimize it into a multiply+shift,
-		// and unroll loop
-		for u >= 100 {
-			i -= 2
-			q := u / 100
-			j := uintptr(u - q*100)
-			a[i+1] = digits01[j]
-			a[i+0] = digits10[j]
-			u = q
+		// common case: use constants for / because
+		// the compiler can optimize it into a multiply+shift
+
+		if ^uintptr(0)>>32 == 0 {
+			for u > uint64(^uintptr(0)) {
+				q := u / 1e9
+				us := uintptr(u - q*1e9) // us % 1e9 fits into a uintptr
+				for j := 9; j > 0; j-- {
+					i--
+					qs := us / 10
+					a[i] = byte(us - qs*10 + '0')
+					us = qs
+				}
+				u = q
+			}
 		}
-		if u >= 10 {
+
+		// u guaranteed to fit into a uintptr
+		us := uintptr(u)
+		for us >= 10 {
 			i--
-			q := u / 10
-			a[i] = digits[uintptr(u-q*10)]
-			u = q
+			q := us / 10
+			a[i] = byte(us - q*10 + '0')
+			us = q
 		}
+		// u < 10
+		i--
+		a[i] = byte(us + '0')
 
 	} else if s := shifts[base]; s > 0 {
 		// base is power of 2: use shifts and masks instead of / and %
@@ -101,21 +110,24 @@
 			a[i] = digits[uintptr(u)&m]
 			u >>= s
 		}
+		// u < base
+		i--
+		a[i] = digits[uintptr(u)]
 
 	} else {
 		// general case
 		b := uint64(base)
 		for u >= b {
 			i--
-			a[i] = digits[uintptr(u%b)]
-			u /= b
+			q := u / b
+			a[i] = digits[uintptr(u-q*b)]
+			u = q
 		}
+		// u < base
+		i--
+		a[i] = digits[uintptr(u)]
 	}
 
-	// u < base
-	i--
-	a[i] = digits[uintptr(u)]
-
 	// add sign, if any
 	if neg {
 		i--
diff --git a/third_party/gofrontend/libgo/go/strconv/itoa_test.go b/third_party/gofrontend/libgo/go/strconv/itoa_test.go
index e0213ae..48dc03e 100644
--- a/third_party/gofrontend/libgo/go/strconv/itoa_test.go
+++ b/third_party/gofrontend/libgo/go/strconv/itoa_test.go
@@ -51,6 +51,7 @@
 	{-0x123456789abcdef, 16, "-123456789abcdef"},
 	{1<<63 - 1, 16, "7fffffffffffffff"},
 	{1<<63 - 1, 2, "111111111111111111111111111111111111111111111111111111111111111"},
+	{-1 << 63, 2, "-1000000000000000000000000000000000000000000000000000000000000000"},
 
 	{16, 17, "g"},
 	{25, 25, "10"},
diff --git a/third_party/gofrontend/libgo/go/strconv/quote_example_test.go b/third_party/gofrontend/libgo/go/strconv/quote_example_test.go
deleted file mode 100644
index 405a57e..0000000
--- a/third_party/gofrontend/libgo/go/strconv/quote_example_test.go
+++ /dev/null
@@ -1,35 +0,0 @@
-// Copyright 2013 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 strconv_test
-
-import (
-	"fmt"
-	"strconv"
-)
-
-func ExampleUnquote() {
-	test := func(s string) {
-		t, err := strconv.Unquote(s)
-		if err != nil {
-			fmt.Printf("Unquote(%#v): %v\n", s, err)
-		} else {
-			fmt.Printf("Unquote(%#v) = %v\n", s, t)
-		}
-	}
-
-	s := `cafe\u0301`
-	// If the string doesn't have quotes, it can't be unquoted.
-	test(s) // invalid syntax
-	test("`" + s + "`")
-	test(`"` + s + `"`)
-
-	test(`'\u00e9'`)
-
-	// Output:
-	// Unquote("cafe\\u0301"): invalid syntax
-	// Unquote("`cafe\\u0301`") = cafe\u0301
-	// Unquote("\"cafe\\u0301\"") = café
-	// Unquote("'\\u00e9'") = é
-}
diff --git a/third_party/gofrontend/libgo/go/strings/compare.go b/third_party/gofrontend/libgo/go/strings/compare.go
new file mode 100644
index 0000000..b84ddde
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/strings/compare.go
@@ -0,0 +1,28 @@
+// 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 strings
+
+// Compare returns an integer comparing two strings lexicographically.
+// The result will be 0 if a==b, -1 if a < b, and +1 if a > b.
+//
+// Compare is included only for symmetry with package bytes.
+// It is usually clearer and always faster to use the built-in
+// string comparison operators ==, <, >, and so on.
+func Compare(a, b string) int {
+	// NOTE(rsc): This function does NOT call the runtime cmpstring function,
+	// because we do not want to provide any performance justification for
+	// using strings.Compare. Basically no one should use strings.Compare.
+	// As the comment above says, it is here only for symmetry with package bytes.
+	// If performance is important, the compiler should be changed to recognize
+	// the pattern so that all code doing three-way comparisons, not just code
+	// using strings.Compare, can benefit.
+	if a == b {
+		return 0
+	}
+	if a < b {
+		return -1
+	}
+	return +1
+}
diff --git a/third_party/gofrontend/libgo/go/strings/compare_test.go b/third_party/gofrontend/libgo/go/strings/compare_test.go
new file mode 100644
index 0000000..68fc88e
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/strings/compare_test.go
@@ -0,0 +1,98 @@
+// Copyright 2013 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 strings_test
+
+// Derived from bytes/compare_test.go.
+// Benchmarks omitted since the underlying implementation is identical.
+
+import (
+	. "strings"
+	"testing"
+)
+
+var compareTests = []struct {
+	a, b string
+	i    int
+}{
+	{"", "", 0},
+	{"a", "", 1},
+	{"", "a", -1},
+	{"abc", "abc", 0},
+	{"ab", "abc", -1},
+	{"abc", "ab", 1},
+	{"x", "ab", 1},
+	{"ab", "x", -1},
+	{"x", "a", 1},
+	{"b", "x", -1},
+	// test runtime·memeq's chunked implementation
+	{"abcdefgh", "abcdefgh", 0},
+	{"abcdefghi", "abcdefghi", 0},
+	{"abcdefghi", "abcdefghj", -1},
+}
+
+func TestCompare(t *testing.T) {
+	for _, tt := range compareTests {
+		cmp := Compare(tt.a, tt.b)
+		if cmp != tt.i {
+			t.Errorf(`Compare(%q, %q) = %v`, tt.a, tt.b, cmp)
+		}
+	}
+}
+
+func TestCompareIdenticalString(t *testing.T) {
+	var s = "Hello Gophers!"
+	if Compare(s, s) != 0 {
+		t.Error("s != s")
+	}
+	if Compare(s, s[:1]) != 1 {
+		t.Error("s > s[:1] failed")
+	}
+}
+
+func TestCompareStrings(t *testing.T) {
+	n := 128
+	a := make([]byte, n+1)
+	b := make([]byte, n+1)
+	for len := 0; len < 128; len++ {
+		// randomish but deterministic data.  No 0 or 255.
+		for i := 0; i < len; i++ {
+			a[i] = byte(1 + 31*i%254)
+			b[i] = byte(1 + 31*i%254)
+		}
+		// data past the end is different
+		for i := len; i <= n; i++ {
+			a[i] = 8
+			b[i] = 9
+		}
+
+		cmp := Compare(string(a[:len]), string(b[:len]))
+		if cmp != 0 {
+			t.Errorf(`CompareIdentical(%d) = %d`, len, cmp)
+		}
+		if len > 0 {
+			cmp = Compare(string(a[:len-1]), string(b[:len]))
+			if cmp != -1 {
+				t.Errorf(`CompareAshorter(%d) = %d`, len, cmp)
+			}
+			cmp = Compare(string(a[:len]), string(b[:len-1]))
+			if cmp != 1 {
+				t.Errorf(`CompareBshorter(%d) = %d`, len, cmp)
+			}
+		}
+		for k := 0; k < len; k++ {
+			b[k] = a[k] - 1
+			cmp = Compare(string(a[:len]), string(b[:len]))
+			if cmp != 1 {
+				t.Errorf(`CompareAbigger(%d,%d) = %d`, len, k, cmp)
+			}
+			b[k] = a[k] + 1
+			cmp = Compare(string(a[:len]), string(b[:len]))
+			if cmp != -1 {
+				t.Errorf(`CompareBbigger(%d,%d) = %d`, len, k, cmp)
+			}
+			b[k] = a[k]
+		}
+	}
+}
diff --git a/third_party/gofrontend/libgo/go/strings/reader.go b/third_party/gofrontend/libgo/go/strings/reader.go
index 82df974..7a872fb 100644
--- a/third_party/gofrontend/libgo/go/strings/reader.go
+++ b/third_party/gofrontend/libgo/go/strings/reader.go
@@ -28,6 +28,12 @@
 	return int(int64(len(r.s)) - r.i)
 }
 
+// Size returns the original length of the underlying string.
+// Size is the number of bytes available for reading via ReadAt.
+// The returned value is always the same and is not affected by calls
+// to any other method.
+func (r *Reader) Size() int64 { return int64(len(r.s)) }
+
 func (r *Reader) Read(b []byte) (n int, err error) {
 	if len(b) == 0 {
 		return 0, nil
diff --git a/third_party/gofrontend/libgo/go/strings/reader_test.go b/third_party/gofrontend/libgo/go/strings/reader_test.go
index bee90eb..5003a37 100644
--- a/third_party/gofrontend/libgo/go/strings/reader_test.go
+++ b/third_party/gofrontend/libgo/go/strings/reader_test.go
@@ -8,6 +8,7 @@
 	"bytes"
 	"fmt"
 	"io"
+	"io/ioutil"
 	"os"
 	"strings"
 	"sync"
@@ -157,3 +158,15 @@
 		}
 	}
 }
+
+// tests that Len is affected by reads, but Size is not.
+func TestReaderLenSize(t *testing.T) {
+	r := strings.NewReader("abc")
+	io.CopyN(ioutil.Discard, r, 1)
+	if r.Len() != 2 {
+		t.Errorf("Len = %d; want 2", r.Len())
+	}
+	if r.Size() != 3 {
+		t.Errorf("Size = %d; want 3", r.Size())
+	}
+}
diff --git a/third_party/gofrontend/libgo/go/strings/strings.go b/third_party/gofrontend/libgo/go/strings/strings.go
index 27d3849..dd51dab 100644
--- a/third_party/gofrontend/libgo/go/strings/strings.go
+++ b/third_party/gofrontend/libgo/go/strings/strings.go
@@ -2,7 +2,9 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-// Package strings implements simple functions to manipulate strings.
+// Package strings implements simple functions to manipulate UTF-8 encoded strings.
+//
+// For information about UTF-8 strings in Go, see https://blog.golang.org/strings.
 package strings
 
 import (
@@ -78,6 +80,7 @@
 }
 
 // Count counts the number of non-overlapping instances of sep in s.
+// If sep is an empty string, Count returns 1 + the number of Unicode code points in s.
 func Count(s, sep string) int {
 	n := 0
 	// special cases
@@ -125,17 +128,17 @@
 	return n
 }
 
-// Contains returns true if substr is within s.
+// Contains reports whether substr is within s.
 func Contains(s, substr string) bool {
 	return Index(s, substr) >= 0
 }
 
-// ContainsAny returns true if any Unicode code points in chars are within s.
+// ContainsAny reports whether any Unicode code points in chars are within s.
 func ContainsAny(s, chars string) bool {
 	return IndexAny(s, chars) >= 0
 }
 
-// ContainsRune returns true if the Unicode code point r is within s.
+// ContainsRune reports whether the Unicode code point r is within s.
 func ContainsRune(s string, r rune) bool {
 	return IndexRune(s, r) >= 0
 }
@@ -184,14 +187,7 @@
 	case n == 0:
 		return len(s)
 	case n == 1:
-		// special case worth making fast
-		c := sep[0]
-		for i := len(s) - 1; i >= 0; i-- {
-			if s[i] == c {
-				return i
-			}
-		}
-		return -1
+		return LastIndexByte(s, sep[0])
 	case n == len(s):
 		if sep == s {
 			return 0
@@ -270,6 +266,16 @@
 	return -1
 }
 
+// LastIndexByte returns the index of the last instance of c in s, or -1 if c is not present in s.
+func LastIndexByte(s string, c byte) int {
+	for i := len(s) - 1; i >= 0; i-- {
+		if s[i] == c {
+			return i
+		}
+	}
+	return -1
+}
+
 // Generic split: splits after each instance of sep,
 // including sepSave bytes of sep in the subarrays.
 func genSplit(s, sep string, sepSave, n int) []string {
@@ -519,7 +525,7 @@
 // Title returns a copy of the string s with all Unicode letters that begin words
 // mapped to their title case.
 //
-// BUG: The rule Title uses for word boundaries does not handle Unicode punctuation properly.
+// BUG(rsc): The rule Title uses for word boundaries does not handle Unicode punctuation properly.
 func Title(s string) string {
 	// Use a closure here to remember state.
 	// Hackish but effective. Depends on Map scanning in order and calling
diff --git a/third_party/gofrontend/libgo/go/strings/strings_test.go b/third_party/gofrontend/libgo/go/strings/strings_test.go
index 7bb81ef..4e21dea 100644
--- a/third_party/gofrontend/libgo/go/strings/strings_test.go
+++ b/third_party/gofrontend/libgo/go/strings/strings_test.go
@@ -120,6 +120,23 @@
 func TestIndexAny(t *testing.T)     { runIndexTests(t, IndexAny, "IndexAny", indexAnyTests) }
 func TestLastIndexAny(t *testing.T) { runIndexTests(t, LastIndexAny, "LastIndexAny", lastIndexAnyTests) }
 
+func TestLastIndexByte(t *testing.T) {
+	testCases := []IndexTest{
+		{"", "q", -1},
+		{"abcdef", "q", -1},
+		{"abcdefabcdef", "a", len("abcdef")},      // something in the middle
+		{"abcdefabcdef", "f", len("abcdefabcde")}, // last byte
+		{"zabcdefabcdef", "z", 0},                 // first byte
+		{"a☺b☻c☹d", "b", len("a☺")},               // non-ascii
+	}
+	for _, test := range testCases {
+		actual := LastIndexByte(test.s, test.sep[0])
+		if actual != test.out {
+			t.Errorf("LastIndexByte(%q,%c) = %v; want %v", test.s, test.sep[0], actual, test.out)
+		}
+	}
+}
+
 var indexRuneTests = []struct {
 	s    string
 	rune rune
@@ -569,6 +586,35 @@
 	}
 }
 
+func BenchmarkTrim(b *testing.B) {
+	b.ReportAllocs()
+
+	for i := 0; i < b.N; i++ {
+		for _, tc := range trimTests {
+			name := tc.f
+			var f func(string, string) string
+			switch name {
+			case "Trim":
+				f = Trim
+			case "TrimLeft":
+				f = TrimLeft
+			case "TrimRight":
+				f = TrimRight
+			case "TrimPrefix":
+				f = TrimPrefix
+			case "TrimSuffix":
+				f = TrimSuffix
+			default:
+				b.Errorf("Undefined trim function %s", name)
+			}
+			actual := f(tc.in, tc.arg)
+			if actual != tc.out {
+				b.Errorf("%s(%q, %q) = %q; want %q", name, tc.in, tc.arg, actual, tc.out)
+			}
+		}
+	}
+}
+
 type predicate struct {
 	f    func(rune) bool
 	name string
diff --git a/third_party/gofrontend/libgo/go/sync/atomic/atomic_test.go b/third_party/gofrontend/libgo/go/sync/atomic/atomic_test.go
index eaa3b6b..6dae0fd 100644
--- a/third_party/gofrontend/libgo/go/sync/atomic/atomic_test.go
+++ b/third_party/gofrontend/libgo/go/sync/atomic/atomic_test.go
@@ -164,7 +164,7 @@
 	x.before = magicptr
 	x.after = magicptr
 	var j uintptr
-	for delta := uintptr(1); delta+delta > delta; delta += delta {
+	for delta := uintptr(1 << 16); delta+delta > delta; delta += delta {
 		k := SwapPointer(&x.i, unsafe.Pointer(delta))
 		if uintptr(x.i) != delta || uintptr(k) != j {
 			t.Fatalf("delta=%d i=%d j=%d k=%d", delta, x.i, j, k)
@@ -456,7 +456,7 @@
 	magicptr := uintptr(m)
 	x.before = magicptr
 	x.after = magicptr
-	for val := uintptr(1); val+val > val; val += val {
+	for val := uintptr(1 << 16); val+val > val; val += val {
 		x.i = unsafe.Pointer(val)
 		if !CompareAndSwapPointer(&x.i, unsafe.Pointer(val), unsafe.Pointer(val+1)) {
 			t.Fatalf("should have swapped %#x %#x", val, val+1)
@@ -595,7 +595,7 @@
 	magicptr := uintptr(m)
 	x.before = magicptr
 	x.after = magicptr
-	for delta := uintptr(1); delta+delta > delta; delta += delta {
+	for delta := uintptr(1 << 16); delta+delta > delta; delta += delta {
 		k := LoadPointer(&x.i)
 		if k != x.i {
 			t.Fatalf("delta=%d i=%d k=%d", delta, x.i, k)
@@ -731,7 +731,7 @@
 	x.before = magicptr
 	x.after = magicptr
 	v := unsafe.Pointer(uintptr(0))
-	for delta := uintptr(1); delta+delta > delta; delta += delta {
+	for delta := uintptr(1 << 16); delta+delta > delta; delta += delta {
 		StorePointer(&x.i, unsafe.Pointer(v))
 		if x.i != v {
 			t.Fatalf("delta=%d i=%d v=%d", delta, x.i, v)
@@ -759,14 +759,12 @@
 	"SwapInt32":             hammerSwapInt32,
 	"SwapUint32":            hammerSwapUint32,
 	"SwapUintptr":           hammerSwapUintptr32,
-	"SwapPointer":           hammerSwapPointer32,
 	"AddInt32":              hammerAddInt32,
 	"AddUint32":             hammerAddUint32,
 	"AddUintptr":            hammerAddUintptr32,
 	"CompareAndSwapInt32":   hammerCompareAndSwapInt32,
 	"CompareAndSwapUint32":  hammerCompareAndSwapUint32,
 	"CompareAndSwapUintptr": hammerCompareAndSwapUintptr32,
-	"CompareAndSwapPointer": hammerCompareAndSwapPointer32,
 }
 
 func init() {
@@ -818,20 +816,6 @@
 	}
 }
 
-func hammerSwapPointer32(uaddr *uint32, count int) {
-	// only safe when uintptr is 32-bit.
-	// not called on 64-bit systems.
-	addr := (*unsafe.Pointer)(unsafe.Pointer(uaddr))
-	seed := int(uintptr(unsafe.Pointer(&count)))
-	for i := 0; i < count; i++ {
-		new := uintptr(seed+i)<<16 | uintptr(seed+i)<<16>>16
-		old := uintptr(SwapPointer(addr, unsafe.Pointer(new)))
-		if old>>16 != old<<16>>16 {
-			panic(fmt.Sprintf("SwapPointer is not atomic: %#08x", old))
-		}
-	}
-}
-
 func hammerAddInt32(uaddr *uint32, count int) {
 	addr := (*int32)(unsafe.Pointer(uaddr))
 	for i := 0; i < count; i++ {
@@ -891,20 +875,6 @@
 	}
 }
 
-func hammerCompareAndSwapPointer32(uaddr *uint32, count int) {
-	// only safe when uintptr is 32-bit.
-	// not called on 64-bit systems.
-	addr := (*unsafe.Pointer)(unsafe.Pointer(uaddr))
-	for i := 0; i < count; i++ {
-		for {
-			v := LoadPointer(addr)
-			if CompareAndSwapPointer(addr, v, unsafe.Pointer(uintptr(v)+1)) {
-				break
-			}
-		}
-	}
-}
-
 func TestHammer32(t *testing.T) {
 	const p = 4
 	n := 100000
@@ -940,14 +910,12 @@
 	"SwapInt64":             hammerSwapInt64,
 	"SwapUint64":            hammerSwapUint64,
 	"SwapUintptr":           hammerSwapUintptr64,
-	"SwapPointer":           hammerSwapPointer64,
 	"AddInt64":              hammerAddInt64,
 	"AddUint64":             hammerAddUint64,
 	"AddUintptr":            hammerAddUintptr64,
 	"CompareAndSwapInt64":   hammerCompareAndSwapInt64,
 	"CompareAndSwapUint64":  hammerCompareAndSwapUint64,
 	"CompareAndSwapUintptr": hammerCompareAndSwapUintptr64,
-	"CompareAndSwapPointer": hammerCompareAndSwapPointer64,
 }
 
 func init() {
@@ -999,20 +967,6 @@
 	}
 }
 
-func hammerSwapPointer64(uaddr *uint64, count int) {
-	// only safe when uintptr is 64-bit.
-	// not called on 32-bit systems.
-	addr := (*unsafe.Pointer)(unsafe.Pointer(uaddr))
-	seed := int(uintptr(unsafe.Pointer(&count)))
-	for i := 0; i < count; i++ {
-		new := uintptr(seed+i)<<32 | uintptr(seed+i)<<32>>32
-		old := uintptr(SwapPointer(addr, unsafe.Pointer(new)))
-		if old>>32 != old<<32>>32 {
-			panic(fmt.Sprintf("SwapPointer is not atomic: %v", old))
-		}
-	}
-}
-
 func hammerAddInt64(uaddr *uint64, count int) {
 	addr := (*int64)(unsafe.Pointer(uaddr))
 	for i := 0; i < count; i++ {
@@ -1072,20 +1026,6 @@
 	}
 }
 
-func hammerCompareAndSwapPointer64(uaddr *uint64, count int) {
-	// only safe when uintptr is 64-bit.
-	// not called on 32-bit systems.
-	addr := (*unsafe.Pointer)(unsafe.Pointer(uaddr))
-	for i := 0; i < count; i++ {
-		for {
-			v := LoadPointer(addr)
-			if CompareAndSwapPointer(addr, v, unsafe.Pointer(uintptr(v)+1)) {
-				break
-			}
-		}
-	}
-}
-
 func TestHammer64(t *testing.T) {
 	if test64err != nil {
 		t.Skipf("Skipping 64-bit tests: %v", test64err)
@@ -1465,9 +1405,6 @@
 }
 
 func TestNilDeref(t *testing.T) {
-	if p := runtime.GOOS + "/" + runtime.GOARCH; p == "freebsd/arm" || p == "netbsd/arm" {
-		t.Skipf("issue 7338: skipping test on %q", p)
-	}
 	funcs := [...]func(){
 		func() { CompareAndSwapInt32(nil, 0, 0) },
 		func() { CompareAndSwapInt64(nil, 0, 0) },
diff --git a/third_party/gofrontend/libgo/go/sync/export_test.go b/third_party/gofrontend/libgo/go/sync/export_test.go
index fa5983a..6f49b3b 100644
--- a/third_party/gofrontend/libgo/go/sync/export_test.go
+++ b/third_party/gofrontend/libgo/go/sync/export_test.go
@@ -7,3 +7,5 @@
 // Export for testing.
 var Runtime_Semacquire = runtime_Semacquire
 var Runtime_Semrelease = runtime_Semrelease
+
+const RaceEnabled = raceenabled
diff --git a/third_party/gofrontend/libgo/go/sync/mutex.go b/third_party/gofrontend/libgo/go/sync/mutex.go
index 73b3377..3f280ad 100644
--- a/third_party/gofrontend/libgo/go/sync/mutex.go
+++ b/third_party/gofrontend/libgo/go/sync/mutex.go
@@ -48,15 +48,31 @@
 	}
 
 	awoke := false
+	iter := 0
 	for {
 		old := m.state
 		new := old | mutexLocked
 		if old&mutexLocked != 0 {
+			if runtime_canSpin(iter) {
+				// Active spinning makes sense.
+				// Try to set mutexWoken flag to inform Unlock
+				// to not wake other blocked goroutines.
+				if !awoke && old&mutexWoken == 0 && old>>mutexWaiterShift != 0 &&
+					atomic.CompareAndSwapInt32(&m.state, old, old|mutexWoken) {
+					awoke = true
+				}
+				runtime_doSpin()
+				iter++
+				continue
+			}
 			new = old + 1<<mutexWaiterShift
 		}
 		if awoke {
 			// The goroutine has been woken from sleep,
 			// so we need to reset the flag in either case.
+			if new&mutexWoken == 0 {
+				panic("sync: inconsistent mutex state")
+			}
 			new &^= mutexWoken
 		}
 		if atomic.CompareAndSwapInt32(&m.state, old, new) {
@@ -65,6 +81,7 @@
 			}
 			runtime_Semacquire(&m.sema)
 			awoke = true
+			iter = 0
 		}
 	}
 
diff --git a/third_party/gofrontend/libgo/go/sync/mutex_test.go b/third_party/gofrontend/libgo/go/sync/mutex_test.go
index 151b25c..91a4855 100644
--- a/third_party/gofrontend/libgo/go/sync/mutex_test.go
+++ b/third_party/gofrontend/libgo/go/sync/mutex_test.go
@@ -134,3 +134,58 @@
 func BenchmarkMutexWorkSlack(b *testing.B) {
 	benchmarkMutex(b, true, true)
 }
+
+func BenchmarkMutexNoSpin(b *testing.B) {
+	// This benchmark models a situation where spinning in the mutex should be
+	// non-profitable and allows to confirm that spinning does not do harm.
+	// To achieve this we create excess of goroutines most of which do local work.
+	// These goroutines yield during local work, so that switching from
+	// a blocked goroutine to other goroutines is profitable.
+	// As a matter of fact, this benchmark still triggers some spinning in the mutex.
+	var m Mutex
+	var acc0, acc1 uint64
+	b.SetParallelism(4)
+	b.RunParallel(func(pb *testing.PB) {
+		c := make(chan bool)
+		var data [4 << 10]uint64
+		for i := 0; pb.Next(); i++ {
+			if i%4 == 0 {
+				m.Lock()
+				acc0 -= 100
+				acc1 += 100
+				m.Unlock()
+			} else {
+				for i := 0; i < len(data); i += 4 {
+					data[i]++
+				}
+				// Elaborate way to say runtime.Gosched
+				// that does not put the goroutine onto global runq.
+				go func() {
+					c <- true
+				}()
+				<-c
+			}
+		}
+	})
+}
+
+func BenchmarkMutexSpin(b *testing.B) {
+	// This benchmark models a situation where spinning in the mutex should be
+	// profitable. To achieve this we create a goroutine per-proc.
+	// These goroutines access considerable amount of local data so that
+	// unnecessary rescheduling is penalized by cache misses.
+	var m Mutex
+	var acc0, acc1 uint64
+	b.RunParallel(func(pb *testing.PB) {
+		var data [16 << 10]uint64
+		for i := 0; pb.Next(); i++ {
+			m.Lock()
+			acc0 -= 100
+			acc1 += 100
+			m.Unlock()
+			for i := 0; i < len(data); i += 4 {
+				data[i]++
+			}
+		}
+	})
+}
diff --git a/third_party/gofrontend/libgo/go/sync/runtime.go b/third_party/gofrontend/libgo/go/sync/runtime.go
index 3b86630..c66d2de 100644
--- a/third_party/gofrontend/libgo/go/sync/runtime.go
+++ b/third_party/gofrontend/libgo/go/sync/runtime.go
@@ -38,3 +38,10 @@
 	var s syncSema
 	runtime_Syncsemcheck(unsafe.Sizeof(s))
 }
+
+// Active spinning runtime support.
+// runtime_canSpin returns true is spinning makes sense at the moment.
+func runtime_canSpin(i int) bool
+
+// runtime_doSpin does active spinning.
+func runtime_doSpin()
diff --git a/third_party/gofrontend/libgo/go/sync/waitgroup.go b/third_party/gofrontend/libgo/go/sync/waitgroup.go
index 92cc57d..de399e6 100644
--- a/third_party/gofrontend/libgo/go/sync/waitgroup.go
+++ b/third_party/gofrontend/libgo/go/sync/waitgroup.go
@@ -15,23 +15,21 @@
 // runs and calls Done when finished.  At the same time,
 // Wait can be used to block until all goroutines have finished.
 type WaitGroup struct {
-	m       Mutex
-	counter int32
-	waiters int32
-	sema    *uint32
+	// 64-bit value: high 32 bits are counter, low 32 bits are waiter count.
+	// 64-bit atomic operations require 64-bit alignment, but 32-bit
+	// compilers do not ensure it. So we allocate 12 bytes and then use
+	// the aligned 8 bytes in them as state.
+	state1 [12]byte
+	sema   uint32
 }
 
-// WaitGroup creates a new semaphore each time the old semaphore
-// is released. This is to avoid the following race:
-//
-// G1: Add(1)
-// G1: go G2()
-// G1: Wait() // Context switch after Unlock() and before Semacquire().
-// G2: Done() // Release semaphore: sema == 1, waiters == 0. G1 doesn't run yet.
-// G3: Wait() // Finds counter == 0, waiters == 0, doesn't block.
-// G3: Add(1) // Makes counter == 1, waiters == 0.
-// G3: go G4()
-// G3: Wait() // G1 still hasn't run, G3 finds sema == 1, unblocked! Bug.
+func (wg *WaitGroup) state() *uint64 {
+	if uintptr(unsafe.Pointer(&wg.state1))%8 == 0 {
+		return (*uint64)(unsafe.Pointer(&wg.state1))
+	} else {
+		return (*uint64)(unsafe.Pointer(&wg.state1[4]))
+	}
+}
 
 // Add adds delta, which may be negative, to the WaitGroup counter.
 // If the counter becomes zero, all goroutines blocked on Wait are released.
@@ -43,10 +41,13 @@
 // at any time.
 // Typically this means the calls to Add should execute before the statement
 // creating the goroutine or other event to be waited for.
+// If a WaitGroup is reused to wait for several independent sets of events,
+// new Add calls must happen after all previous Wait calls have returned.
 // See the WaitGroup example.
 func (wg *WaitGroup) Add(delta int) {
+	statep := wg.state()
 	if raceenabled {
-		_ = wg.m.state // trigger nil deref early
+		_ = *statep // trigger nil deref early
 		if delta < 0 {
 			// Synchronize decrements with Wait.
 			raceReleaseMerge(unsafe.Pointer(wg))
@@ -54,7 +55,9 @@
 		raceDisable()
 		defer raceEnable()
 	}
-	v := atomic.AddInt32(&wg.counter, int32(delta))
+	state := atomic.AddUint64(statep, uint64(delta)<<32)
+	v := int32(state >> 32)
+	w := uint32(state)
 	if raceenabled {
 		if delta > 0 && v == int32(delta) {
 			// The first increment must be synchronized with Wait.
@@ -66,18 +69,25 @@
 	if v < 0 {
 		panic("sync: negative WaitGroup counter")
 	}
-	if v > 0 || atomic.LoadInt32(&wg.waiters) == 0 {
+	if w != 0 && delta > 0 && v == int32(delta) {
+		panic("sync: WaitGroup misuse: Add called concurrently with Wait")
+	}
+	if v > 0 || w == 0 {
 		return
 	}
-	wg.m.Lock()
-	if atomic.LoadInt32(&wg.counter) == 0 {
-		for i := int32(0); i < wg.waiters; i++ {
-			runtime_Semrelease(wg.sema)
-		}
-		wg.waiters = 0
-		wg.sema = nil
+	// This goroutine has set counter to 0 when waiters > 0.
+	// Now there can't be concurrent mutations of state:
+	// - Adds must not happen concurrently with Wait,
+	// - Wait does not increment waiters if it sees counter == 0.
+	// Still do a cheap sanity check to detect WaitGroup misuse.
+	if *statep != state {
+		panic("sync: WaitGroup misuse: Add called concurrently with Wait")
 	}
-	wg.m.Unlock()
+	// Reset waiters count to 0.
+	*statep = 0
+	for ; w != 0; w-- {
+		runtime_Semrelease(&wg.sema)
+	}
 }
 
 // Done decrements the WaitGroup counter.
@@ -87,51 +97,41 @@
 
 // Wait blocks until the WaitGroup counter is zero.
 func (wg *WaitGroup) Wait() {
+	statep := wg.state()
 	if raceenabled {
-		_ = wg.m.state // trigger nil deref early
+		_ = *statep // trigger nil deref early
 		raceDisable()
 	}
-	if atomic.LoadInt32(&wg.counter) == 0 {
-		if raceenabled {
-			raceEnable()
-			raceAcquire(unsafe.Pointer(wg))
+	for {
+		state := atomic.LoadUint64(statep)
+		v := int32(state >> 32)
+		w := uint32(state)
+		if v == 0 {
+			// Counter is 0, no need to wait.
+			if raceenabled {
+				raceEnable()
+				raceAcquire(unsafe.Pointer(wg))
+			}
+			return
 		}
-		return
-	}
-	wg.m.Lock()
-	w := atomic.AddInt32(&wg.waiters, 1)
-	// This code is racing with the unlocked path in Add above.
-	// The code above modifies counter and then reads waiters.
-	// We must modify waiters and then read counter (the opposite order)
-	// to avoid missing an Add.
-	if atomic.LoadInt32(&wg.counter) == 0 {
-		atomic.AddInt32(&wg.waiters, -1)
-		if raceenabled {
-			raceEnable()
-			raceAcquire(unsafe.Pointer(wg))
-			raceDisable()
+		// Increment waiters count.
+		if atomic.CompareAndSwapUint64(statep, state, state+1) {
+			if raceenabled && w == 0 {
+				// Wait must be synchronized with the first Add.
+				// Need to model this is as a write to race with the read in Add.
+				// As a consequence, can do the write only for the first waiter,
+				// otherwise concurrent Waits will race with each other.
+				raceWrite(unsafe.Pointer(&wg.sema))
+			}
+			runtime_Semacquire(&wg.sema)
+			if *statep != 0 {
+				panic("sync: WaitGroup is reused before previous Wait has returned")
+			}
+			if raceenabled {
+				raceEnable()
+				raceAcquire(unsafe.Pointer(wg))
+			}
+			return
 		}
-		wg.m.Unlock()
-		if raceenabled {
-			raceEnable()
-		}
-		return
-	}
-	if raceenabled && w == 1 {
-		// Wait must be synchronized with the first Add.
-		// Need to model this is as a write to race with the read in Add.
-		// As a consequence, can do the write only for the first waiter,
-		// otherwise concurrent Waits will race with each other.
-		raceWrite(unsafe.Pointer(&wg.sema))
-	}
-	if wg.sema == nil {
-		wg.sema = new(uint32)
-	}
-	s := wg.sema
-	wg.m.Unlock()
-	runtime_Semacquire(s)
-	if raceenabled {
-		raceEnable()
-		raceAcquire(unsafe.Pointer(wg))
 	}
 }
diff --git a/third_party/gofrontend/libgo/go/sync/waitgroup_test.go b/third_party/gofrontend/libgo/go/sync/waitgroup_test.go
index 4c0a043..3e3e3bf 100644
--- a/third_party/gofrontend/libgo/go/sync/waitgroup_test.go
+++ b/third_party/gofrontend/libgo/go/sync/waitgroup_test.go
@@ -5,6 +5,7 @@
 package sync_test
 
 import (
+	"runtime"
 	. "sync"
 	"sync/atomic"
 	"testing"
@@ -46,6 +47,12 @@
 	}
 }
 
+func knownRacy(t *testing.T) {
+	if RaceEnabled {
+		t.Skip("skipping known-racy test under the race detector")
+	}
+}
+
 func TestWaitGroupMisuse(t *testing.T) {
 	defer func() {
 		err := recover()
@@ -60,6 +67,95 @@
 	t.Fatal("Should panic")
 }
 
+func TestWaitGroupMisuse2(t *testing.T) {
+	knownRacy(t)
+	if testing.Short() {
+		t.Skip("skipping flaky test in short mode; see issue 11443")
+	}
+	if runtime.NumCPU() <= 2 {
+		t.Skip("NumCPU<=2, skipping: this test requires parallelism")
+	}
+	defer func() {
+		err := recover()
+		if err != "sync: negative WaitGroup counter" &&
+			err != "sync: WaitGroup misuse: Add called concurrently with Wait" &&
+			err != "sync: WaitGroup is reused before previous Wait has returned" {
+			t.Fatalf("Unexpected panic: %#v", err)
+		}
+	}()
+	defer runtime.GOMAXPROCS(runtime.GOMAXPROCS(4))
+	done := make(chan interface{}, 2)
+	// The detection is opportunistically, so we want it to panic
+	// at least in one run out of a million.
+	for i := 0; i < 1e6; i++ {
+		var wg WaitGroup
+		wg.Add(1)
+		go func() {
+			defer func() {
+				done <- recover()
+			}()
+			wg.Wait()
+		}()
+		go func() {
+			defer func() {
+				done <- recover()
+			}()
+			wg.Add(1) // This is the bad guy.
+			wg.Done()
+		}()
+		wg.Done()
+		for j := 0; j < 2; j++ {
+			if err := <-done; err != nil {
+				panic(err)
+			}
+		}
+	}
+	t.Fatal("Should panic")
+}
+
+func TestWaitGroupMisuse3(t *testing.T) {
+	knownRacy(t)
+	if runtime.NumCPU() <= 1 {
+		t.Skip("NumCPU==1, skipping: this test requires parallelism")
+	}
+	defer func() {
+		err := recover()
+		if err != "sync: negative WaitGroup counter" &&
+			err != "sync: WaitGroup misuse: Add called concurrently with Wait" &&
+			err != "sync: WaitGroup is reused before previous Wait has returned" {
+			t.Fatalf("Unexpected panic: %#v", err)
+		}
+	}()
+	defer runtime.GOMAXPROCS(runtime.GOMAXPROCS(4))
+	done := make(chan interface{}, 1)
+	// The detection is opportunistically, so we want it to panic
+	// at least in one run out of a million.
+	for i := 0; i < 1e6; i++ {
+		var wg WaitGroup
+		wg.Add(1)
+		go func() {
+			wg.Done()
+		}()
+		go func() {
+			defer func() {
+				done <- recover()
+			}()
+			wg.Wait()
+			// Start reusing the wg before waiting for the Wait below to return.
+			wg.Add(1)
+			go func() {
+				wg.Done()
+			}()
+			wg.Wait()
+		}()
+		wg.Wait()
+		if err := <-done; err != nil {
+			panic(err)
+		}
+	}
+	t.Fatal("Should panic")
+}
+
 func TestWaitGroupRace(t *testing.T) {
 	// Run this test for about 1ms.
 	for i := 0; i < 1000; i++ {
@@ -85,6 +181,19 @@
 	}
 }
 
+func TestWaitGroupAlign(t *testing.T) {
+	type X struct {
+		x  byte
+		wg WaitGroup
+	}
+	var x X
+	x.wg.Add(1)
+	go func(x *X) {
+		x.wg.Done()
+	}(&x)
+	x.wg.Wait()
+}
+
 func BenchmarkWaitGroupUncontended(b *testing.B) {
 	type PaddedWaitGroup struct {
 		WaitGroup
@@ -146,3 +255,17 @@
 func BenchmarkWaitGroupWaitWork(b *testing.B) {
 	benchmarkWaitGroupWait(b, 100)
 }
+
+func BenchmarkWaitGroupActuallyWait(b *testing.B) {
+	b.ReportAllocs()
+	b.RunParallel(func(pb *testing.PB) {
+		for pb.Next() {
+			var wg WaitGroup
+			wg.Add(1)
+			go func() {
+				wg.Done()
+			}()
+			wg.Wait()
+		}
+	})
+}
diff --git a/third_party/gofrontend/libgo/go/syscall/const_plan9.go b/third_party/gofrontend/libgo/go/syscall/const_plan9.go
new file mode 100644
index 0000000..ba26f12
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/syscall/const_plan9.go
@@ -0,0 +1,59 @@
+package syscall
+
+// Plan 9 Constants
+
+// Open modes
+const (
+	O_RDONLY  = 0
+	O_WRONLY  = 1
+	O_RDWR    = 2
+	O_TRUNC   = 16
+	O_CLOEXEC = 32
+	O_EXCL    = 0x1000
+)
+
+// Rfork flags
+const (
+	RFNAMEG  = 1 << 0
+	RFENVG   = 1 << 1
+	RFFDG    = 1 << 2
+	RFNOTEG  = 1 << 3
+	RFPROC   = 1 << 4
+	RFMEM    = 1 << 5
+	RFNOWAIT = 1 << 6
+	RFCNAMEG = 1 << 10
+	RFCENVG  = 1 << 11
+	RFCFDG   = 1 << 12
+	RFREND   = 1 << 13
+	RFNOMNT  = 1 << 14
+)
+
+// Qid.Type bits
+const (
+	QTDIR    = 0x80
+	QTAPPEND = 0x40
+	QTEXCL   = 0x20
+	QTMOUNT  = 0x10
+	QTAUTH   = 0x08
+	QTTMP    = 0x04
+	QTFILE   = 0x00
+)
+
+// Dir.Mode bits
+const (
+	DMDIR    = 0x80000000
+	DMAPPEND = 0x40000000
+	DMEXCL   = 0x20000000
+	DMMOUNT  = 0x10000000
+	DMAUTH   = 0x08000000
+	DMTMP    = 0x04000000
+	DMREAD   = 0x4
+	DMWRITE  = 0x2
+	DMEXEC   = 0x1
+)
+
+const (
+	STATMAX    = 65535
+	ERRMAX     = 128
+	STATFIXLEN = 49
+)
diff --git a/third_party/gofrontend/libgo/go/syscall/creds_test.go b/third_party/gofrontend/libgo/go/syscall/creds_test.go
index b1894c6..b4a14ff 100644
--- a/third_party/gofrontend/libgo/go/syscall/creds_test.go
+++ b/third_party/gofrontend/libgo/go/syscall/creds_test.go
@@ -56,7 +56,13 @@
 		ucred.Gid = 0
 		oob := syscall.UnixCredentials(&ucred)
 		_, _, err := cli.(*net.UnixConn).WriteMsgUnix(nil, oob, nil)
-		if err.(*net.OpError).Err != syscall.EPERM {
+		if op, ok := err.(*net.OpError); ok {
+			err = op.Err
+		}
+		if sys, ok := err.(*os.SyscallError); ok {
+			err = sys.Err
+		}
+		if err != syscall.EPERM {
 			t.Fatalf("WriteMsgUnix failed with %v, want EPERM", err)
 		}
 	}
diff --git a/third_party/gofrontend/libgo/go/syscall/env_plan9.go b/third_party/gofrontend/libgo/go/syscall/env_plan9.go
index 9ea36c8..cbf7f41 100644
--- a/third_party/gofrontend/libgo/go/syscall/env_plan9.go
+++ b/third_party/gofrontend/libgo/go/syscall/env_plan9.go
@@ -16,7 +16,7 @@
 )
 
 func readenv(key string) (string, error) {
-	fd, err := Open("/env/"+key, O_RDONLY)
+	fd, err := open("/env/"+key, O_RDONLY)
 	if err != nil {
 		return "", err
 	}
@@ -35,7 +35,7 @@
 }
 
 func writeenv(key, value string) error {
-	fd, err := Create("/env/"+key, O_RDWR, 0666)
+	fd, err := create("/env/"+key, O_RDWR, 0666)
 	if err != nil {
 		return err
 	}
@@ -86,7 +86,7 @@
 }
 
 func Environ() []string {
-	fd, err := Open("/env", O_RDONLY)
+	fd, err := open("/env", O_RDONLY)
 	if err != nil {
 		return nil
 	}
diff --git a/third_party/gofrontend/libgo/go/syscall/env_windows.go b/third_party/gofrontend/libgo/go/syscall/env_windows.go
index bc21690..1cb4754 100644
--- a/third_party/gofrontend/libgo/go/syscall/env_windows.go
+++ b/third_party/gofrontend/libgo/go/syscall/env_windows.go
@@ -16,19 +16,17 @@
 	if err != nil {
 		return "", false
 	}
-	b := make([]uint16, 100)
-	n, e := GetEnvironmentVariable(keyp, &b[0], uint32(len(b)))
-	if n == 0 && e == ERROR_ENVVAR_NOT_FOUND {
-		return "", false
-	}
-	if n > uint32(len(b)) {
-		b = make([]uint16, n)
-		n, e = GetEnvironmentVariable(keyp, &b[0], uint32(len(b)))
-		if n > uint32(len(b)) {
-			n = 0
+	n := uint32(100)
+	for {
+		b := make([]uint16, n)
+		n, err = GetEnvironmentVariable(keyp, &b[0], uint32(len(b)))
+		if n == 0 && err == ERROR_ENVVAR_NOT_FOUND {
+			return "", false
+		}
+		if n <= uint32(len(b)) {
+			return string(utf16.Decode(b[:n])), true
 		}
 	}
-	return string(utf16.Decode(b[0:n])), true
 }
 
 func Setenv(key, value string) error {
diff --git a/third_party/gofrontend/libgo/go/syscall/errors_plan9.go b/third_party/gofrontend/libgo/go/syscall/errors_plan9.go
new file mode 100644
index 0000000..ede3d6a
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/syscall/errors_plan9.go
@@ -0,0 +1,48 @@
+// Copyright 2011 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 syscall
+
+// Constants
+const (
+	// Invented values to support what package os expects.
+	O_CREAT    = 0x02000
+	O_APPEND   = 0x00400
+	O_NOCTTY   = 0x00000
+	O_NONBLOCK = 0x00000
+	O_SYNC     = 0x00000
+	O_ASYNC    = 0x00000
+
+	S_IFMT   = 0x1f000
+	S_IFIFO  = 0x1000
+	S_IFCHR  = 0x2000
+	S_IFDIR  = 0x4000
+	S_IFBLK  = 0x6000
+	S_IFREG  = 0x8000
+	S_IFLNK  = 0xa000
+	S_IFSOCK = 0xc000
+)
+
+// Errors
+var (
+	EINVAL       = NewError("bad arg in system call")
+	ENOTDIR      = NewError("not a directory")
+	EISDIR       = NewError("file is a directory")
+	ENOENT       = NewError("file does not exist")
+	EEXIST       = NewError("file already exists")
+	EMFILE       = NewError("no free file descriptors")
+	EIO          = NewError("i/o error")
+	ENAMETOOLONG = NewError("file name too long")
+	EINTR        = NewError("interrupted")
+	EPERM        = NewError("permission denied")
+	EBUSY        = NewError("no free devices")
+	ETIMEDOUT    = NewError("connection timed out")
+	EPLAN9       = NewError("not supported by plan 9")
+
+	// The following errors do not correspond to any
+	// Plan 9 system messages. Invented to support
+	// what package os and others expect.
+	EACCES       = NewError("access permission denied")
+	EAFNOSUPPORT = NewError("address family not supported by protocol")
+)
diff --git a/third_party/gofrontend/libgo/go/syscall/exec_bsd.go b/third_party/gofrontend/libgo/go/syscall/exec_bsd.go
index 217e0c8..9042ce2 100644
--- a/third_party/gofrontend/libgo/go/syscall/exec_bsd.go
+++ b/third_party/gofrontend/libgo/go/syscall/exec_bsd.go
@@ -15,9 +15,12 @@
 	Credential *Credential // Credential.
 	Ptrace     bool        // Enable tracing.
 	Setsid     bool        // Create session.
-	Setpgid    bool        // Set process group ID to new pid (SYSV setpgrp)
-	Setctty    bool        // Set controlling terminal to fd 0
+	Setpgid    bool        // Set process group ID to Pgid, or, if Pgid == 0, to new pid.
+	Setctty    bool        // Set controlling terminal to fd Ctty
 	Noctty     bool        // Detach fd 0 from controlling terminal
+	Ctty       int         // Controlling TTY fd
+	Foreground bool        // Place child's process group in foreground. (Implies Setpgid. Uses Ctty as fd of controlling TTY)
+	Pgid       int         // Child's process group ID if Setpgid.
 }
 
 // Implemented in runtime package.
@@ -90,8 +93,22 @@
 	}
 
 	// Set process group
-	if sys.Setpgid {
-		err1 = raw_setpgid(0, 0)
+	if sys.Setpgid || sys.Foreground {
+		// Place child in process group.
+		err1 = raw_setpgid(0, sys.Pgid)
+		if err1 != 0 {
+			goto childerror
+		}
+	}
+
+	if sys.Foreground {
+		pgrp := Pid_t(sys.Pgid)
+		if pgrp == 0 {
+			pgrp = raw_getpid()
+		}
+
+		// Place process group in foreground.
+		_, err1 = raw_ioctl_ptr(sys.Ctty, TIOCSPGRP, unsafe.Pointer(&pgrp))
 		if err1 != 0 {
 			goto childerror
 		}
@@ -215,9 +232,9 @@
 		}
 	}
 
-	// Make fd 0 the tty
+	// Set the controlling TTY to Ctty
 	if sys.Setctty {
-		_, err1 = raw_ioctl(0, TIOCSCTTY, 0)
+		_, err1 = raw_ioctl(sys.Ctty, TIOCSCTTY, 0)
 		if err1 != 0 {
 			goto childerror
 		}
diff --git a/third_party/gofrontend/libgo/go/syscall/exec_linux.go b/third_party/gofrontend/libgo/go/syscall/exec_linux.go
index 97bde0c..540efb3 100644
--- a/third_party/gofrontend/libgo/go/syscall/exec_linux.go
+++ b/third_party/gofrontend/libgo/go/syscall/exec_linux.go
@@ -27,14 +27,21 @@
 	Credential  *Credential    // Credential.
 	Ptrace      bool           // Enable tracing.
 	Setsid      bool           // Create session.
-	Setpgid     bool           // Set process group ID to new pid (SYSV setpgrp)
+	Setpgid     bool           // Set process group ID to Pgid, or, if Pgid == 0, to new pid.
 	Setctty     bool           // Set controlling terminal to fd Ctty (only meaningful if Setsid is set)
 	Noctty      bool           // Detach fd 0 from controlling terminal
-	Ctty        int            // Controlling TTY fd (Linux only)
+	Ctty        int            // Controlling TTY fd
+	Foreground  bool           // Place child's process group in foreground. (Implies Setpgid. Uses Ctty as fd of controlling TTY)
+	Pgid        int            // Child's process group ID if Setpgid.
 	Pdeathsig   Signal         // Signal that the process will get when its parent dies (Linux only)
 	Cloneflags  uintptr        // Flags for clone calls (Linux only)
 	UidMappings []SysProcIDMap // User ID mappings for user namespaces.
 	GidMappings []SysProcIDMap // Group ID mappings for user namespaces.
+	// GidMappingsEnableSetgroups enabling setgroups syscall.
+	// If false, then setgroups syscall will be disabled for the child process.
+	// This parameter is no-op if GidMappings == nil. Otherwise for unprivileged
+	// users this should be set to false for mappings work.
+	GidMappingsEnableSetgroups bool
 }
 
 // Implemented in runtime package.
@@ -62,6 +69,9 @@
 		p      [2]int
 	)
 
+	// Record parent PID so child can test if it has died.
+	ppid := raw_getpid()
+
 	// Guard against side effects of shuffling fds below.
 	// Make sure that nextfd is beyond any currently open files so
 	// that we can't run the risk of overwriting any of them.
@@ -135,27 +145,6 @@
 		}
 	}
 
-	// Parent death signal
-	if sys.Pdeathsig != 0 {
-		_, err1 = raw_prctl(PR_SET_PDEATHSIG, int(sys.Pdeathsig), 0, 0, 0)
-		if err1 != 0 {
-			goto childerror
-		}
-
-		// Signal self if parent is already dead. This might cause a
-		// duplicate signal in rare cases, but it won't matter when
-		// using SIGKILL.
-		ppid := Getppid()
-		if ppid == 1 {
-			pid = Getpid()
-			err2 := Kill(pid, sys.Pdeathsig)
-			if err2 != nil {
-				err1 = err2.(Errno)
-				goto childerror
-			}
-		}
-	}
-
 	// Enable tracing if requested.
 	if sys.Ptrace {
 		err1 = raw_ptrace(_PTRACE_TRACEME, 0, nil, nil)
@@ -173,8 +162,22 @@
 	}
 
 	// Set process group
-	if sys.Setpgid {
-		err1 = raw_setpgid(0, 0)
+	if sys.Setpgid || sys.Foreground {
+		// Place child in process group.
+		err1 = raw_setpgid(0, sys.Pgid)
+		if err1 != 0 {
+			goto childerror
+		}
+	}
+
+	if sys.Foreground {
+		pgrp := Pid_t(sys.Pgid)
+		if pgrp == 0 {
+			pgrp = raw_getpid()
+		}
+
+		// Place process group in foreground.
+		_, err1 = raw_ioctl_ptr(sys.Ctty, TIOCSPGRP, unsafe.Pointer(&pgrp))
 		if err1 != 0 {
 			goto childerror
 		}
@@ -191,36 +194,19 @@
 	// User and groups
 	if cred := sys.Credential; cred != nil {
 		ngroups := len(cred.Groups)
-		if ngroups == 0 {
-			err2 := setgroups(0, nil)
-			if err2 == nil {
-				err1 = 0
-			} else {
-				err1 = err2.(Errno)
-			}
-		} else {
-			groups := make([]Gid_t, ngroups)
-			for i, v := range cred.Groups {
-				groups[i] = Gid_t(v)
-			}
-			err2 := setgroups(ngroups, &groups[0])
-			if err2 == nil {
-				err1 = 0
-			} else {
-				err1 = err2.(Errno)
+		if ngroups > 0 {
+			groups := unsafe.Pointer(&cred.Groups[0])
+			err1 = raw_setgroups(ngroups, groups)
+			if err1 != 0 {
+				goto childerror
 			}
 		}
+		err1 = raw_setgid(int(cred.Gid))
 		if err1 != 0 {
 			goto childerror
 		}
-		err2 := Setgid(int(cred.Gid))
-		if err2 != nil {
-			err1 = err2.(Errno)
-			goto childerror
-		}
-		err2 = Setuid(int(cred.Uid))
-		if err2 != nil {
-			err1 = err2.(Errno)
+		err1 = raw_setuid(int(cred.Uid))
+		if err1 != 0 {
 			goto childerror
 		}
 	}
@@ -233,6 +219,26 @@
 		}
 	}
 
+	// Parent death signal
+	if sys.Pdeathsig != 0 {
+		_, err1 = raw_prctl(PR_SET_PDEATHSIG, int(sys.Pdeathsig), 0, 0, 0)
+		if err1 != 0 {
+			goto childerror
+		}
+
+		// Signal self if parent is already dead. This might cause a
+		// duplicate signal in rare cases, but it won't matter when
+		// using SIGKILL.
+		r1 := raw_getppid()
+		if r1 != ppid {
+			pid := raw_getpid()
+			err1 = raw_kill(pid, sys.Pdeathsig)
+			if err1 != 0 {
+				goto childerror
+			}
+		}
+	}
+
 	// Pass 1: look for fd[i] < i and move those up above len(fd)
 	// so that pass 2 won't stomp on an fd it needs later.
 	if pipe < nextfd {
@@ -298,9 +304,9 @@
 		}
 	}
 
-	// Make fd 0 the tty
-	if sys.Setctty && sys.Ctty >= 0 {
-		_, err1 = raw_ioctl(0, TIOCSCTTY, sys.Ctty)
+	// Set the controlling TTY to Ctty
+	if sys.Setctty {
+		_, err1 = raw_ioctl(sys.Ctty, TIOCSCTTY, 0)
 		if err1 != 0 {
 			goto childerror
 		}
@@ -364,6 +370,32 @@
 	return nil
 }
 
+// writeSetgroups writes to /proc/PID/setgroups "deny" if enable is false
+// and "allow" if enable is true.
+// This is needed since kernel 3.19, because you can't write gid_map without
+// disabling setgroups() system call.
+func writeSetgroups(pid int, enable bool) error {
+	sgf := "/proc/" + itoa(pid) + "/setgroups"
+	fd, err := Open(sgf, O_RDWR, 0)
+	if err != nil {
+		return err
+	}
+
+	var data []byte
+	if enable {
+		data = []byte("allow")
+	} else {
+		data = []byte("deny")
+	}
+
+	if _, err := Write(fd, data); err != nil {
+		Close(fd)
+		return err
+	}
+
+	return Close(fd)
+}
+
 // writeUidGidMappings writes User ID and Group ID mappings for user namespaces
 // for a process and it is called from the parent process.
 func writeUidGidMappings(pid int, sys *SysProcAttr) error {
@@ -375,6 +407,10 @@
 	}
 
 	if sys.GidMappings != nil {
+		// If the kernel is too old to support /proc/PID/setgroups, writeSetGroups will return ENOENT; this is OK.
+		if err := writeSetgroups(pid, sys.GidMappingsEnableSetgroups); err != nil && err != ENOENT {
+			return err
+		}
 		gidf := "/proc/" + itoa(pid) + "/gid_map"
 		if err := writeIDMappings(gidf, sys.GidMappings); err != nil {
 			return err
diff --git a/third_party/gofrontend/libgo/go/syscall/exec_linux_test.go b/third_party/gofrontend/libgo/go/syscall/exec_linux_test.go
new file mode 100644
index 0000000..60d2734
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/syscall/exec_linux_test.go
@@ -0,0 +1,111 @@
+// 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 linux
+
+package syscall_test
+
+import (
+	"io/ioutil"
+	"os"
+	"os/exec"
+	"regexp"
+	"strconv"
+	"strings"
+	"syscall"
+	"testing"
+)
+
+func whoamiCmd(t *testing.T, uid, gid int, setgroups bool) *exec.Cmd {
+	if _, err := os.Stat("/proc/self/ns/user"); err != nil {
+		if os.IsNotExist(err) {
+			t.Skip("kernel doesn't support user namespaces")
+		}
+		t.Fatalf("Failed to stat /proc/self/ns/user: %v", err)
+	}
+	cmd := exec.Command("whoami")
+	cmd.SysProcAttr = &syscall.SysProcAttr{
+		Cloneflags: syscall.CLONE_NEWUSER,
+		UidMappings: []syscall.SysProcIDMap{
+			{ContainerID: 0, HostID: uid, Size: 1},
+		},
+		GidMappings: []syscall.SysProcIDMap{
+			{ContainerID: 0, HostID: gid, Size: 1},
+		},
+		GidMappingsEnableSetgroups: setgroups,
+	}
+	return cmd
+}
+
+func testNEWUSERRemap(t *testing.T, uid, gid int, setgroups bool) {
+	cmd := whoamiCmd(t, uid, gid, setgroups)
+	out, err := cmd.CombinedOutput()
+	if err != nil {
+		// On some systems, there is a sysctl setting.
+		if os.IsPermission(err) && os.Getuid() != 0 {
+			data, errRead := ioutil.ReadFile("/proc/sys/kernel/unprivileged_userns_clone")
+			if errRead == nil && data[0] == '0' {
+				t.Skip("kernel prohibits user namespace in unprivileged process")
+			}
+		}
+
+		t.Fatalf("Cmd failed with err %v, output: %s", err, out)
+	}
+	sout := strings.TrimSpace(string(out))
+	want := "root"
+	if sout != want {
+		t.Fatalf("whoami = %q; want %q", out, want)
+	}
+}
+
+func TestCloneNEWUSERAndRemapRootDisableSetgroups(t *testing.T) {
+	if os.Getuid() != 0 {
+		t.Skip("skipping root only test")
+	}
+	testNEWUSERRemap(t, 0, 0, false)
+}
+
+func TestCloneNEWUSERAndRemapRootEnableSetgroups(t *testing.T) {
+	if os.Getuid() != 0 {
+		t.Skip("skipping root only test")
+	}
+	testNEWUSERRemap(t, 0, 0, false)
+}
+
+// kernelVersion returns the major and minor versions of the Linux
+// kernel version.  It calls t.Skip if it can't figure it out.
+func kernelVersion(t *testing.T) (int, int) {
+	bytes, err := ioutil.ReadFile("/proc/version")
+	if err != nil {
+		t.Skipf("can't get kernel version: %v", err)
+	}
+	matches := regexp.MustCompile("([0-9]+).([0-9]+)").FindSubmatch(bytes)
+	if len(matches) < 3 {
+		t.Skipf("can't get kernel version from %s", bytes)
+	}
+	major, _ := strconv.Atoi(string(matches[1]))
+	minor, _ := strconv.Atoi(string(matches[2]))
+	return major, minor
+}
+
+func TestCloneNEWUSERAndRemapNoRootDisableSetgroups(t *testing.T) {
+	if os.Getuid() == 0 {
+		t.Skip("skipping unprivileged user only test")
+	}
+	testNEWUSERRemap(t, os.Getuid(), os.Getgid(), false)
+}
+
+func TestCloneNEWUSERAndRemapNoRootSetgroupsEnableSetgroups(t *testing.T) {
+	if os.Getuid() == 0 {
+		t.Skip("skipping unprivileged user only test")
+	}
+	cmd := whoamiCmd(t, os.Getuid(), os.Getgid(), true)
+	err := cmd.Run()
+	if err == nil {
+		t.Skip("probably old kernel without security fix")
+	}
+	if !os.IsPermission(err) {
+		t.Fatalf("Unprivileged gid_map rewriting with GidMappingsEnableSetgroups must fail")
+	}
+}
diff --git a/third_party/gofrontend/libgo/go/syscall/exec_solaris_test.go b/third_party/gofrontend/libgo/go/syscall/exec_solaris_test.go
new file mode 100644
index 0000000..6b8f1ad
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/syscall/exec_solaris_test.go
@@ -0,0 +1,37 @@
+// 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 solaris
+
+package syscall
+
+import "unsafe"
+
+//go:cgo_import_dynamic libc_Getpgid getpgid "libc.so"
+//go:cgo_import_dynamic libc_Getpgrp getpgrp "libc.so"
+
+//go:linkname libc_Getpgid libc_Getpgid
+//go:linkname libc_Getpgrp libc_Getpgrp
+
+var (
+	libc_Getpgid,
+	libc_Getpgrp libcFunc
+)
+
+func Getpgid(pid int) (pgid int, err error) {
+	r0, _, e1 := sysvicall6(uintptr(unsafe.Pointer(&libc_Getpgid)), 1, uintptr(pid), 0, 0, 0, 0, 0)
+	pgid = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+func Getpgrp() (pgrp int) {
+	r0, _, _ := sysvicall6(uintptr(unsafe.Pointer(&libc_Getpgrp)), 0, 0, 0, 0, 0, 0, 0)
+	pgrp = int(r0)
+	return
+}
+
+var Ioctl = ioctl
diff --git a/third_party/gofrontend/libgo/go/syscall/exec_unix.go b/third_party/gofrontend/libgo/go/syscall/exec_unix.go
index a49d95b..d1927de 100644
--- a/third_party/gofrontend/libgo/go/syscall/exec_unix.go
+++ b/third_party/gofrontend/libgo/go/syscall/exec_unix.go
@@ -17,6 +17,12 @@
 //sysnb	raw_fork() (pid Pid_t, err Errno)
 //fork() Pid_t
 
+//sysnb	raw_getpid() (pid Pid_t)
+//getpid() Pid_t
+
+//sysnb	raw_getppid() (pid Pid_t)
+//getppid() Pid_t
+
 //sysnb raw_setsid() (err Errno)
 //setsid() Pid_t
 
@@ -35,8 +41,11 @@
 //sysnb	raw_close(fd int) (err Errno)
 //close(fd _C_int) _C_int
 
-//sysnb	raw_ioctl(fd int, cmd int, val int) (rval int, err Errno)
-//ioctl(fd _C_int, cmd _C_int, val _C_int) _C_int
+//sysnb	raw_ioctl(fd int, cmd uintptr, val int) (rval int, err Errno)
+//__go_ioctl(fd _C_int, cmd _C_int, val _C_int) _C_int
+
+//sysnb raw_ioctl_ptr(fd int, cmd uintptr, val unsafe.Pointer) (rval int, err Errno)
+//__go_ioctl_ptr(fd _C_int, cmd _C_int, val unsafe.Pointer) _C_int
 
 //sysnb	raw_execve(argv0 *byte, argv **byte, envv **byte) (err Errno)
 //execve(argv0 *byte, argv **byte, envv **byte) _C_int
@@ -50,6 +59,18 @@
 //sysnb raw_dup2(oldfd int, newfd int) (err Errno)
 //dup2(oldfd _C_int, newfd _C_int) _C_int
 
+//sysnb raw_kill(pid Pid_t, sig Signal) (err Errno)
+//kill(pid Pid_t, sig _C_int) _C_int
+
+//sysnb raw_setgroups(size int, list unsafe.Pointer) (err Errno)
+//setgroups(size Size_t, list *Gid_t) _C_int
+
+//sysnb raw_setuid(uid int) (err Errno)
+//setuid(uid Uid_t) _C_int
+
+//sysnb raw_setgid(gid int) (err Errno)
+//setgid(gid Gid_t) _C_int
+
 // Lock synchronizing creation of new file descriptors with fork.
 //
 // We want the child in a fork/exec sequence to inherit only the
@@ -99,9 +120,11 @@
 
 var ForkLock sync.RWMutex
 
-// StringSlicePtr is deprecated. Use SlicePtrFromStrings instead.
-// If any string contains a NUL byte this function panics instead
-// of returning an error.
+// StringSlicePtr converts a slice of strings to a slice of pointers
+// to NUL-terminated byte arrays. If any string contains a NUL byte
+// this function panics instead of returning an error.
+//
+// Deprecated: Use SlicePtrFromStrings instead.
 func StringSlicePtr(ss []string) []*byte {
 	bb := make([]*byte, len(ss)+1)
 	for i := 0; i < len(ss); i++ {
@@ -112,7 +135,7 @@
 }
 
 // SlicePtrFromStrings converts a slice of strings to a slice of
-// pointers to NUL-terminated byte slices. If any string contains
+// pointers to NUL-terminated byte arrays. If any string contains
 // a NUL byte, it returns (nil, EINVAL).
 func SlicePtrFromStrings(ss []string) ([]*byte, error) {
 	var err error
diff --git a/third_party/gofrontend/libgo/go/syscall/exec_unix_test.go b/third_party/gofrontend/libgo/go/syscall/exec_unix_test.go
new file mode 100644
index 0000000..69c4a1f
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/syscall/exec_unix_test.go
@@ -0,0 +1,215 @@
+// 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 darwin dragonfly freebsd linux netbsd openbsd solaris
+
+package syscall_test
+
+import (
+	"internal/testenv"
+	"io"
+	"os"
+	"os/exec"
+	"os/signal"
+	"syscall"
+	"testing"
+	"unsafe"
+)
+
+type command struct {
+	pipe io.WriteCloser
+	proc *exec.Cmd
+	test *testing.T
+}
+
+func (c *command) Info() (pid, pgrp int) {
+	pid = c.proc.Process.Pid
+
+	pgrp, err := syscall.Getpgid(pid)
+	if err != nil {
+		c.test.Fatal(err)
+	}
+
+	return
+}
+
+func (c *command) Start() {
+	if err := c.proc.Start(); err != nil {
+		c.test.Fatal(err)
+	}
+}
+
+func (c *command) Stop() {
+	c.pipe.Close()
+	if err := c.proc.Wait(); err != nil {
+		c.test.Fatal(err)
+	}
+}
+
+func create(t *testing.T) *command {
+	testenv.MustHaveExec(t)
+
+	proc := exec.Command("cat")
+	stdin, err := proc.StdinPipe()
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	return &command{stdin, proc, t}
+}
+
+func parent() (pid, pgrp int) {
+	return syscall.Getpid(), syscall.Getpgrp()
+}
+
+func TestZeroSysProcAttr(t *testing.T) {
+	ppid, ppgrp := parent()
+
+	cmd := create(t)
+
+	cmd.Start()
+	defer cmd.Stop()
+
+	cpid, cpgrp := cmd.Info()
+
+	if cpid == ppid {
+		t.Fatalf("Parent and child have the same process ID")
+	}
+
+	if cpgrp != ppgrp {
+		t.Fatalf("Child is not in parent's process group")
+	}
+}
+
+func TestSetpgid(t *testing.T) {
+	ppid, ppgrp := parent()
+
+	cmd := create(t)
+
+	cmd.proc.SysProcAttr = &syscall.SysProcAttr{Setpgid: true}
+	cmd.Start()
+	defer cmd.Stop()
+
+	cpid, cpgrp := cmd.Info()
+
+	if cpid == ppid {
+		t.Fatalf("Parent and child have the same process ID")
+	}
+
+	if cpgrp == ppgrp {
+		t.Fatalf("Parent and child are in the same process group")
+	}
+
+	if cpid != cpgrp {
+		t.Fatalf("Child's process group is not the child's process ID")
+	}
+}
+
+func TestPgid(t *testing.T) {
+	ppid, ppgrp := parent()
+
+	cmd1 := create(t)
+
+	cmd1.proc.SysProcAttr = &syscall.SysProcAttr{Setpgid: true}
+	cmd1.Start()
+	defer cmd1.Stop()
+
+	cpid1, cpgrp1 := cmd1.Info()
+
+	if cpid1 == ppid {
+		t.Fatalf("Parent and child 1 have the same process ID")
+	}
+
+	if cpgrp1 == ppgrp {
+		t.Fatalf("Parent and child 1 are in the same process group")
+	}
+
+	if cpid1 != cpgrp1 {
+		t.Fatalf("Child 1's process group is not its process ID")
+	}
+
+	cmd2 := create(t)
+
+	cmd2.proc.SysProcAttr = &syscall.SysProcAttr{
+		Setpgid: true,
+		Pgid:    cpgrp1,
+	}
+	cmd2.Start()
+	defer cmd2.Stop()
+
+	cpid2, cpgrp2 := cmd2.Info()
+
+	if cpid2 == ppid {
+		t.Fatalf("Parent and child 2 have the same process ID")
+	}
+
+	if cpgrp2 == ppgrp {
+		t.Fatalf("Parent and child 2 are in the same process group")
+	}
+
+	if cpid2 == cpgrp2 {
+		t.Fatalf("Child 2's process group is its process ID")
+	}
+
+	if cpid1 == cpid2 {
+		t.Fatalf("Child 1 and 2 have the same process ID")
+	}
+
+	if cpgrp1 != cpgrp2 {
+		t.Fatalf("Child 1 and 2 are not in the same process group")
+	}
+}
+
+func TestForeground(t *testing.T) {
+	signal.Ignore(syscall.SIGTTIN, syscall.SIGTTOU)
+
+	tty, err := os.OpenFile("/dev/tty", os.O_RDWR, 0)
+	if err != nil {
+		t.Skipf("Can't test Foreground. Couldn't open /dev/tty: %s", err)
+	}
+
+	fpgrp := syscall.Pid_t(0)
+
+	errno := syscall.Ioctl(tty.Fd(), syscall.TIOCGPGRP, uintptr(unsafe.Pointer(&fpgrp)))
+	if errno != 0 {
+		t.Fatalf("TIOCGPGRP failed with error code: %s", errno)
+	}
+
+	if fpgrp == 0 {
+		t.Fatalf("Foreground process group is zero")
+	}
+
+	ppid, ppgrp := parent()
+
+	cmd := create(t)
+
+	cmd.proc.SysProcAttr = &syscall.SysProcAttr{
+		Ctty:       int(tty.Fd()),
+		Foreground: true,
+	}
+	cmd.Start()
+
+	cpid, cpgrp := cmd.Info()
+
+	if cpid == ppid {
+		t.Fatalf("Parent and child have the same process ID")
+	}
+
+	if cpgrp == ppgrp {
+		t.Fatalf("Parent and child are in the same process group")
+	}
+
+	if cpid != cpgrp {
+		t.Fatalf("Child's process group is not the child's process ID")
+	}
+
+	cmd.Stop()
+
+	errno = syscall.Ioctl(tty.Fd(), syscall.TIOCSPGRP, uintptr(unsafe.Pointer(&fpgrp)))
+	if errno != 0 {
+		t.Fatalf("TIOCSPGRP failed with error code: %s", errno)
+	}
+
+	signal.Reset()
+}
diff --git a/third_party/gofrontend/libgo/go/syscall/exec_windows.go b/third_party/gofrontend/libgo/go/syscall/exec_windows.go
index 936aeb5..5a01843 100644
--- a/third_party/gofrontend/libgo/go/syscall/exec_windows.go
+++ b/third_party/gofrontend/libgo/go/syscall/exec_windows.go
@@ -135,23 +135,17 @@
 	if err != nil {
 		return "", err
 	}
-	buf := make([]uint16, 100)
-	n, err := GetFullPathName(p, uint32(len(buf)), &buf[0], nil)
-	if err != nil {
-		return "", err
-	}
-	if n > uint32(len(buf)) {
-		// Windows is asking for bigger buffer.
-		buf = make([]uint16, n)
+	n := uint32(100)
+	for {
+		buf := make([]uint16, n)
 		n, err = GetFullPathName(p, uint32(len(buf)), &buf[0], nil)
 		if err != nil {
 			return "", err
 		}
-		if n > uint32(len(buf)) {
-			return "", EINVAL
+		if n <= uint32(len(buf)) {
+			return UTF16ToString(buf[:n]), nil
 		}
 	}
-	return UTF16ToString(buf[:n]), nil
 }
 
 func isSlash(c uint8) bool {
@@ -250,6 +244,9 @@
 	if len(attr.Files) > 3 {
 		return 0, 0, EWINDOWS
 	}
+	if len(attr.Files) < 3 {
+		return 0, 0, EINVAL
+	}
 
 	if len(attr.Dir) != 0 {
 		// StartProcess assumes that argv0 is relative to attr.Dir,
diff --git a/third_party/gofrontend/libgo/go/syscall/export_unix_test.go b/third_party/gofrontend/libgo/go/syscall/export_unix_test.go
new file mode 100644
index 0000000..b41fe2f
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/syscall/export_unix_test.go
@@ -0,0 +1,12 @@
+// 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 darwin dragonfly freebsd linux netbsd openbsd
+
+package syscall
+
+func Ioctl(fd, req, arg uintptr) (err Errno) {
+	_, _, err = Syscall(SYS_IOCTL, fd, req, arg)
+	return err
+}
diff --git a/third_party/gofrontend/libgo/go/syscall/libcall_bsd.go b/third_party/gofrontend/libgo/go/syscall/libcall_bsd.go
new file mode 100644
index 0000000..f772608
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/syscall/libcall_bsd.go
@@ -0,0 +1,28 @@
+// 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.
+
+// BSD library calls.
+
+package syscall
+
+import "unsafe"
+
+//sys	sendfile(outfd int, infd int, offset *Offset_t, count int) (written int, err error)
+//sendfile(outfd _C_int, infd _C_int, offset *Offset_t, count Size_t) Ssize_t
+func Sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) {
+	if raceenabled {
+		raceReleaseMerge(unsafe.Pointer(&ioSync))
+	}
+	var soff Offset_t
+	var psoff *Offset_t
+	if offset != nil {
+		soff = Offset_t(*offset)
+		psoff = &soff
+	}
+	written, err = sendfile(outfd, infd, psoff, count)
+	if offset != nil {
+		*offset = int64(soff)
+	}
+	return
+}
diff --git a/third_party/gofrontend/libgo/go/syscall/libcall_linux.go b/third_party/gofrontend/libgo/go/syscall/libcall_linux.go
index d5bedd0..f0479eb 100644
--- a/third_party/gofrontend/libgo/go/syscall/libcall_linux.go
+++ b/third_party/gofrontend/libgo/go/syscall/libcall_linux.go
@@ -223,7 +223,6 @@
 	} else {
 		p = (*byte)(unsafe.Pointer(&_zero))
 	}
-	Entersyscall()
 	s := SYS_GETDENTS64
 	if s == 0 {
 		s = SYS_GETDENTS
@@ -233,7 +232,6 @@
 	if n < 0 {
 		err = errno
 	}
-	Exitsyscall()
 	return
 }
 
@@ -329,6 +327,7 @@
 	var soff Offset_t
 	var psoff *Offset_t
 	if offset != nil {
+		soff = Offset_t(*offset)
 		psoff = &soff
 	}
 	written, err = sendfile(outfd, infd, psoff, count)
@@ -410,6 +409,3 @@
 
 //sys	Unshare(flags int) (err error)
 //unshare(flags _C_int) _C_int
-
-//sys	Ustat(dev int, ubuf *Ustat_t) (err error)
-//ustat(dev _dev_t, ubuf *Ustat_t) _C_int
diff --git a/third_party/gofrontend/libgo/go/syscall/libcall_linux_ustat.go b/third_party/gofrontend/libgo/go/syscall/libcall_linux_ustat.go
new file mode 100644
index 0000000..f7f3406
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/syscall/libcall_linux_ustat.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.
+
+// GNU/Linux library ustat call.
+// This is not supported on some kernels, such as arm64.
+
+package syscall
+
+//sys	Ustat(dev int, ubuf *Ustat_t) (err error)
+//ustat(dev _dev_t, ubuf *Ustat_t) _C_int
diff --git a/third_party/gofrontend/libgo/go/syscall/pwd_plan9.go b/third_party/gofrontend/libgo/go/syscall/pwd_plan9.go
new file mode 100644
index 0000000..1248613
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/syscall/pwd_plan9.go
@@ -0,0 +1,83 @@
+// 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.
+
+// The working directory in Plan 9 is effectively per P, so different
+// goroutines and even the same goroutine as it's rescheduled on
+// different Ps can see different working directories.
+//
+// Instead, track a Go process-wide intent of the current working directory,
+// and switch to it at important points.
+
+package syscall
+
+import "sync"
+
+var (
+	wdmu  sync.Mutex // guards following
+	wdSet bool
+	wdStr string
+)
+
+func Fixwd() {
+	wdmu.Lock()
+	defer wdmu.Unlock()
+	fixwdLocked()
+}
+
+func fixwdLocked() {
+	if !wdSet {
+		return
+	}
+	// always call chdir when getwd returns an error
+	wd, _ := getwd()
+	if wd == wdStr {
+		return
+	}
+	if err := chdir(wdStr); err != nil {
+		return
+	}
+}
+
+// goroutine-specific getwd
+func getwd() (wd string, err error) {
+	fd, err := open(".", O_RDONLY)
+	if err != nil {
+		return "", err
+	}
+	defer Close(fd)
+	return Fd2path(fd)
+}
+
+func Getwd() (wd string, err error) {
+	wdmu.Lock()
+	defer wdmu.Unlock()
+
+	if wdSet {
+		return wdStr, nil
+	}
+	wd, err = getwd()
+	if err != nil {
+		return
+	}
+	wdSet = true
+	wdStr = wd
+	return wd, nil
+}
+
+func Chdir(path string) error {
+	wdmu.Lock()
+	defer wdmu.Unlock()
+
+	if err := chdir(path); err != nil {
+		return err
+	}
+
+	wd, err := getwd()
+	if err != nil {
+		return err
+	}
+	wdSet = true
+	wdStr = wd
+	return nil
+}
diff --git a/third_party/gofrontend/libgo/go/syscall/route_bsd.go b/third_party/gofrontend/libgo/go/syscall/route_bsd.go
index 1dabe42..c62fdc3 100644
--- a/third_party/gofrontend/libgo/go/syscall/route_bsd.go
+++ b/third_party/gofrontend/libgo/go/syscall/route_bsd.go
@@ -4,23 +4,37 @@
 
 // +build darwin dragonfly freebsd netbsd openbsd
 
-// Routing sockets and messages
-
 package syscall
 
-import "unsafe"
+import (
+	"runtime"
+	"unsafe"
+)
+
+var (
+	freebsdConfArch       string // "machine $arch" line in kern.conftxt on freebsd
+	minRoutingSockaddrLen = rsaAlignOf(0)
+)
 
 // Round the length of a raw sockaddr up to align it properly.
 func rsaAlignOf(salen int) int {
 	salign := sizeofPtr
-	// NOTE: It seems like 64-bit Darwin kernel still requires
-	// 32-bit aligned access to BSD subsystem. Also NetBSD 6
-	// kernel and beyond require 64-bit aligned access to routing
-	// facilities.
 	if darwin64Bit {
+		// Darwin kernels require 32-bit aligned access to
+		// routing facilities.
 		salign = 4
 	} else if netbsd32Bit {
+		// NetBSD 6 and beyond kernels require 64-bit aligned
+		// access to routing facilities.
 		salign = 8
+	} else if runtime.GOOS == "freebsd" {
+		// In the case of kern.supported_archs="amd64 i386",
+		// we need to know the underlying kernel's
+		// architecture because the alignment for routing
+		// facilities are set at the build time of the kernel.
+		if freebsdConfArch == "amd64" {
+			salign = 8
+		}
 	}
 	if salen == 0 {
 		return salign
@@ -28,6 +42,134 @@
 	return (salen + salign - 1) & ^(salign - 1)
 }
 
+// parseSockaddrLink parses b as a datalink socket address.
+func parseSockaddrLink(b []byte) (*SockaddrDatalink, error) {
+	sa, _, err := parseLinkLayerAddr(b[4:])
+	if err != nil {
+		return nil, err
+	}
+	rsa := (*RawSockaddrDatalink)(unsafe.Pointer(&b[0]))
+	sa.Len = rsa.Len
+	sa.Family = rsa.Family
+	sa.Index = rsa.Index
+	return sa, nil
+}
+
+// parseLinkLayerAddr parses b as a datalink socket address in
+// conventional BSD kernel form.
+func parseLinkLayerAddr(b []byte) (*SockaddrDatalink, int, error) {
+	// The encoding looks like the following:
+	// +----------------------------+
+	// | Type             (1 octet) |
+	// +----------------------------+
+	// | Name length      (1 octet) |
+	// +----------------------------+
+	// | Address length   (1 octet) |
+	// +----------------------------+
+	// | Selector length  (1 octet) |
+	// +----------------------------+
+	// | Data            (variable) |
+	// +----------------------------+
+	type linkLayerAddr struct {
+		Type byte
+		Nlen byte
+		Alen byte
+		Slen byte
+	}
+	lla := (*linkLayerAddr)(unsafe.Pointer(&b[0]))
+	l := rsaAlignOf(int(4 + lla.Nlen + lla.Alen + lla.Slen))
+	if len(b) < l {
+		return nil, 0, EINVAL
+	}
+	b = b[4:]
+	sa := &SockaddrDatalink{Type: lla.Type, Nlen: lla.Nlen, Alen: lla.Alen, Slen: lla.Slen}
+	for i := 0; len(sa.Data) > i && i < int(lla.Nlen+lla.Alen+lla.Slen); i++ {
+		sa.Data[i] = int8(b[i])
+	}
+	return sa, l, nil
+}
+
+// parseSockaddrInet parses b as an internet socket address.
+func parseSockaddrInet(b []byte, family byte) (Sockaddr, error) {
+	switch family {
+	case AF_INET:
+		if len(b) < SizeofSockaddrInet4 {
+			return nil, EINVAL
+		}
+		rsa := (*RawSockaddrAny)(unsafe.Pointer(&b[0]))
+		return anyToSockaddr(rsa)
+	case AF_INET6:
+		if len(b) < SizeofSockaddrInet6 {
+			return nil, EINVAL
+		}
+		rsa := (*RawSockaddrAny)(unsafe.Pointer(&b[0]))
+		return anyToSockaddr(rsa)
+	default:
+		return nil, EINVAL
+	}
+}
+
+const (
+	offsetofInet4 = int(unsafe.Offsetof(RawSockaddrInet4{}.Addr))
+	offsetofInet6 = int(unsafe.Offsetof(RawSockaddrInet6{}.Addr))
+)
+
+// parseNetworkLayerAddr parses b as an internet socket address in
+// conventional BSD kernel form.
+func parseNetworkLayerAddr(b []byte, family byte) (Sockaddr, error) {
+	// The encoding looks similar to the NLRI encoding.
+	// +----------------------------+
+	// | Length           (1 octet) |
+	// +----------------------------+
+	// | Address prefix  (variable) |
+	// +----------------------------+
+	//
+	// The differences between the kernel form and the NLRI
+	// encoding are:
+	//
+	// - The length field of the kernel form indicates the prefix
+	//   length in bytes, not in bits
+	//
+	// - In the kernel form, zero value of the length field
+	//   doesn't mean 0.0.0.0/0 or ::/0
+	//
+	// - The kernel form appends leading bytes to the prefix field
+	//   to make the <length, prefix> tuple to be conformed with
+	//   the routing messeage boundary
+	l := int(rsaAlignOf(int(b[0])))
+	if len(b) < l {
+		return nil, EINVAL
+	}
+	// Don't reorder case expressions.
+	// The case expressions for IPv6 must come first.
+	switch {
+	case b[0] == SizeofSockaddrInet6:
+		sa := &SockaddrInet6{}
+		copy(sa.Addr[:], b[offsetofInet6:])
+		return sa, nil
+	case family == AF_INET6:
+		sa := &SockaddrInet6{}
+		if l-1 < offsetofInet6 {
+			copy(sa.Addr[:], b[1:l])
+		} else {
+			copy(sa.Addr[:], b[l-offsetofInet6:l])
+		}
+		return sa, nil
+	case b[0] == SizeofSockaddrInet4:
+		sa := &SockaddrInet4{}
+		copy(sa.Addr[:], b[offsetofInet4:])
+		return sa, nil
+	default: // an old fashion, AF_UNSPEC or unknown means AF_INET
+		sa := &SockaddrInet4{}
+		if l-1 < offsetofInet4 {
+			copy(sa.Addr[:], b[1:l])
+		} else {
+			copy(sa.Addr[:], b[l-offsetofInet4:l])
+		}
+		return sa, nil
+	}
+}
+
 // RouteRIB returns routing information base, as known as RIB,
 // which consists of network facility information, states and
 // parameters.
@@ -50,7 +192,7 @@
 
 // RoutingMessage represents a routing message.
 type RoutingMessage interface {
-	sockaddr() []Sockaddr
+	sockaddr() ([]Sockaddr, error)
 }
 
 const anyMessageLen = int(unsafe.Sizeof(anyMessage{}))
@@ -68,50 +210,41 @@
 	Data   []byte
 }
 
-const rtaRtMask = RTA_DST | RTA_GATEWAY | RTA_NETMASK | RTA_GENMASK
-
-func (m *RouteMessage) sockaddr() []Sockaddr {
-	var (
-		af  int
-		sas [4]Sockaddr
-	)
+func (m *RouteMessage) sockaddr() ([]Sockaddr, error) {
+	var sas [RTAX_MAX]Sockaddr
 	b := m.Data[:]
-	for i := uint(0); i < RTAX_MAX; i++ {
-		if m.Header.Addrs&rtaRtMask&(1<<i) == 0 {
+	family := uint8(AF_UNSPEC)
+	for i := uint(0); i < RTAX_MAX && len(b) >= minRoutingSockaddrLen; i++ {
+		if m.Header.Addrs&(1<<i) == 0 {
 			continue
 		}
 		rsa := (*RawSockaddr)(unsafe.Pointer(&b[0]))
-		switch i {
-		case RTAX_DST, RTAX_GATEWAY:
-			sa, err := anyToSockaddr((*RawSockaddrAny)(unsafe.Pointer(rsa)))
+		switch rsa.Family {
+		case AF_LINK:
+			sa, err := parseSockaddrLink(b)
 			if err != nil {
-				return nil
-			}
-			if i == RTAX_DST {
-				af = int(rsa.Family)
+				return nil, err
 			}
 			sas[i] = sa
-		case RTAX_NETMASK, RTAX_GENMASK:
-			switch af {
-			case AF_INET:
-				rsa4 := (*RawSockaddrInet4)(unsafe.Pointer(&b[0]))
-				sa := new(SockaddrInet4)
-				for j := 0; rsa4.Len > 0 && j < int(rsa4.Len)-int(unsafe.Offsetof(rsa4.Addr)); j++ {
-					sa.Addr[j] = rsa4.Addr[j]
-				}
-				sas[i] = sa
-			case AF_INET6:
-				rsa6 := (*RawSockaddrInet6)(unsafe.Pointer(&b[0]))
-				sa := new(SockaddrInet6)
-				for j := 0; rsa6.Len > 0 && j < int(rsa6.Len)-int(unsafe.Offsetof(rsa6.Addr)); j++ {
-					sa.Addr[j] = rsa6.Addr[j]
-				}
-				sas[i] = sa
+			b = b[rsaAlignOf(int(rsa.Len)):]
+		case AF_INET, AF_INET6:
+			sa, err := parseSockaddrInet(b, rsa.Family)
+			if err != nil {
+				return nil, err
 			}
+			sas[i] = sa
+			b = b[rsaAlignOf(int(rsa.Len)):]
+			family = rsa.Family
+		default:
+			sa, err := parseNetworkLayerAddr(b, family)
+			if err != nil {
+				return nil, err
+			}
+			sas[i] = sa
+			b = b[rsaAlignOf(int(b[0])):]
 		}
-		b = b[rsaAlignOf(int(rsa.Len)):]
 	}
-	return sas[:]
+	return sas[:], nil
 }
 
 // InterfaceMessage represents a routing message containing
@@ -121,15 +254,17 @@
 	Data   []byte
 }
 
-func (m *InterfaceMessage) sockaddr() (sas []Sockaddr) {
+func (m *InterfaceMessage) sockaddr() ([]Sockaddr, error) {
+	var sas [RTAX_MAX]Sockaddr
 	if m.Header.Addrs&RTA_IFP == 0 {
-		return nil
+		return nil, nil
 	}
-	sa, err := anyToSockaddr((*RawSockaddrAny)(unsafe.Pointer(&m.Data[0])))
+	sa, err := parseSockaddrLink(m.Data[:])
 	if err != nil {
-		return nil
+		return nil, err
 	}
-	return append(sas, sa)
+	sas[RTAX_IFP] = sa
+	return sas[:], nil
 }
 
 // InterfaceAddrMessage represents a routing message containing
@@ -139,79 +274,63 @@
 	Data   []byte
 }
 
-const rtaIfaMask = RTA_IFA | RTA_NETMASK | RTA_BRD
-
-func (m *InterfaceAddrMessage) sockaddr() (sas []Sockaddr) {
-	if m.Header.Addrs&rtaIfaMask == 0 {
-		return nil
-	}
+func (m *InterfaceAddrMessage) sockaddr() ([]Sockaddr, error) {
+	var sas [RTAX_MAX]Sockaddr
 	b := m.Data[:]
-	// We still see AF_UNSPEC in socket addresses on some
-	// platforms. To identify each address family correctly, we
-	// will use the address family of RTAX_NETMASK as a preferred
-	// one on the 32-bit NetBSD kernel, also use the length of
-	// RTAX_NETMASK socket address on the FreeBSD kernel.
-	preferredFamily := uint8(AF_UNSPEC)
-	for i := uint(0); i < RTAX_MAX; i++ {
+	family := uint8(AF_UNSPEC)
+	for i := uint(0); i < RTAX_MAX && len(b) >= minRoutingSockaddrLen; i++ {
 		if m.Header.Addrs&(1<<i) == 0 {
 			continue
 		}
 		rsa := (*RawSockaddr)(unsafe.Pointer(&b[0]))
-		switch i {
-		case RTAX_IFA:
-			if rsa.Family == AF_UNSPEC {
-				rsa.Family = preferredFamily
-			}
-			sa, err := anyToSockaddr((*RawSockaddrAny)(unsafe.Pointer(rsa)))
+		switch rsa.Family {
+		case AF_LINK:
+			sa, err := parseSockaddrLink(b)
 			if err != nil {
-				return nil
+				return nil, err
 			}
-			sas = append(sas, sa)
-		case RTAX_NETMASK:
-			switch rsa.Family {
-			case AF_UNSPEC:
-				switch rsa.Len {
-				case SizeofSockaddrInet4:
-					rsa.Family = AF_INET
-				case SizeofSockaddrInet6:
-					rsa.Family = AF_INET6
-				default:
-					rsa.Family = AF_INET // an old fashion, AF_UNSPEC means AF_INET
-				}
-			case AF_INET, AF_INET6:
-				preferredFamily = rsa.Family
-			default:
-				return nil
-			}
-			sa, err := anyToSockaddr((*RawSockaddrAny)(unsafe.Pointer(rsa)))
+			sas[i] = sa
+			b = b[rsaAlignOf(int(rsa.Len)):]
+		case AF_INET, AF_INET6:
+			sa, err := parseSockaddrInet(b, rsa.Family)
 			if err != nil {
-				return nil
+				return nil, err
 			}
-			sas = append(sas, sa)
-		case RTAX_BRD:
-			// nothing to do
+			sas[i] = sa
+			b = b[rsaAlignOf(int(rsa.Len)):]
+			family = rsa.Family
+		default:
+			sa, err := parseNetworkLayerAddr(b, family)
+			if err != nil {
+				return nil, err
+			}
+			sas[i] = sa
+			b = b[rsaAlignOf(int(b[0])):]
 		}
-		b = b[rsaAlignOf(int(rsa.Len)):]
 	}
-	return sas
+	return sas[:], nil
 }
 
 // ParseRoutingMessage parses b as routing messages and returns the
 // slice containing the RoutingMessage interfaces.
 func ParseRoutingMessage(b []byte) (msgs []RoutingMessage, err error) {
-	msgCount := 0
+	nmsgs, nskips := 0, 0
 	for len(b) >= anyMessageLen {
-		msgCount++
+		nmsgs++
 		any := (*anyMessage)(unsafe.Pointer(&b[0]))
 		if any.Version != RTM_VERSION {
 			b = b[any.Msglen:]
 			continue
 		}
-		msgs = append(msgs, any.toRoutingMessage(b))
+		if m := any.toRoutingMessage(b); m == nil {
+			nskips++
+		} else {
+			msgs = append(msgs, m)
+		}
 		b = b[any.Msglen:]
 	}
 	// We failed to parse any of the messages - version mismatch?
-	if msgCount > 0 && len(msgs) == 0 {
+	if nmsgs != len(msgs)+nskips {
 		return nil, EINVAL
 	}
 	return msgs, nil
@@ -219,6 +338,10 @@
 
 // ParseRoutingMessage parses msg's payload as raw sockaddrs and
 // returns the slice containing the Sockaddr interfaces.
-func ParseRoutingSockaddr(msg RoutingMessage) (sas []Sockaddr, err error) {
-	return append(sas, msg.sockaddr()...), nil
+func ParseRoutingSockaddr(msg RoutingMessage) ([]Sockaddr, error) {
+	sas, err := msg.sockaddr()
+	if err != nil {
+		return nil, err
+	}
+	return sas, nil
 }
diff --git a/third_party/gofrontend/libgo/go/syscall/route_bsd_test.go b/third_party/gofrontend/libgo/go/syscall/route_bsd_test.go
new file mode 100644
index 0000000..8617663
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/syscall/route_bsd_test.go
@@ -0,0 +1,225 @@
+// 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 darwin dragonfly freebsd netbsd openbsd
+
+package syscall_test
+
+import (
+	"fmt"
+	"net"
+	"os"
+	"syscall"
+	"testing"
+	"time"
+)
+
+func TestRouteRIB(t *testing.T) {
+	for _, facility := range []int{syscall.NET_RT_DUMP, syscall.NET_RT_IFLIST} {
+		for _, param := range []int{syscall.AF_UNSPEC, syscall.AF_INET, syscall.AF_INET6} {
+			var err error
+			var b []byte
+			// The VM allocator wrapper functions can
+			// return ENOMEM easily.
+			for i := 0; i < 3; i++ {
+				b, err = syscall.RouteRIB(facility, param)
+				if err != nil {
+					time.Sleep(5 * time.Millisecond)
+					continue
+				}
+				break
+			}
+			if err != nil {
+				t.Error(facility, param, err)
+				continue
+			}
+			msgs, err := syscall.ParseRoutingMessage(b)
+			if err != nil {
+				t.Error(facility, param, err)
+				continue
+			}
+			var ipv4loopback, ipv6loopback bool
+			for _, m := range msgs {
+				flags, err := parseRoutingMessageHeader(m)
+				if err != nil {
+					t.Error(err)
+					continue
+				}
+				sas, err := parseRoutingSockaddrs(m)
+				if err != nil {
+					t.Error(err)
+					continue
+				}
+				if flags&(syscall.RTA_DST|syscall.RTA_IFA) != 0 {
+					sa := sas[syscall.RTAX_DST]
+					if sa == nil {
+						sa = sas[syscall.RTAX_IFA]
+					}
+					switch sa := sa.(type) {
+					case *syscall.SockaddrInet4:
+						if net.IP(sa.Addr[:]).IsLoopback() {
+							ipv4loopback = true
+						}
+					case *syscall.SockaddrInet6:
+						if net.IP(sa.Addr[:]).IsLoopback() {
+							ipv6loopback = true
+						}
+					}
+				}
+				t.Log(facility, param, flags, sockaddrs(sas))
+			}
+			if param == syscall.AF_UNSPEC && len(msgs) > 0 && !ipv4loopback && !ipv6loopback {
+				t.Errorf("no loopback facility found: ipv4/ipv6=%v/%v, %v", ipv4loopback, ipv6loopback, len(msgs))
+				continue
+			}
+		}
+	}
+}
+
+func TestRouteMonitor(t *testing.T) {
+	if testing.Short() || os.Getuid() != 0 {
+		t.Skip("must be root")
+	}
+
+	s, err := syscall.Socket(syscall.AF_ROUTE, syscall.SOCK_RAW, syscall.AF_UNSPEC)
+	if err != nil {
+		t.Fatal(err)
+	}
+	defer syscall.Close(s)
+
+	tmo := time.After(30 * time.Second)
+	go func() {
+		b := make([]byte, os.Getpagesize())
+		for {
+			n, err := syscall.Read(s, b)
+			if err != nil {
+				return
+			}
+			msgs, err := syscall.ParseRoutingMessage(b[:n])
+			if err != nil {
+				t.Error(err)
+				return
+			}
+			for _, m := range msgs {
+				flags, err := parseRoutingMessageHeader(m)
+				if err != nil {
+					t.Error(err)
+					continue
+				}
+				sas, err := parseRoutingSockaddrs(m)
+				if err != nil {
+					t.Error(err)
+					continue
+				}
+				t.Log(flags, sockaddrs(sas))
+			}
+		}
+	}()
+	<-tmo
+}
+
+type addrFamily byte
+
+func (f addrFamily) String() string {
+	switch f {
+	case syscall.AF_UNSPEC:
+		return "unspec"
+	case syscall.AF_LINK:
+		return "link"
+	case syscall.AF_INET:
+		return "inet4"
+	case syscall.AF_INET6:
+		return "inet6"
+	default:
+		return fmt.Sprintf("unknown %d", f)
+	}
+}
+
+type addrFlags uint32
+
+var addrFlagNames = [...]string{
+	"dst",
+	"gateway",
+	"netmask",
+	"genmask",
+	"ifp",
+	"ifa",
+	"author",
+	"brd",
+	"mpls1,tag,src", // sockaddr_mpls=dragonfly,netbsd, sockaddr_in/in6=openbsd
+	"mpls2,srcmask", // sockaddr_mpls=dragonfly, sockaddr_in/in6=openbsd
+	"mpls3,label",   // sockaddr_mpls=dragonfly, sockaddr_rtlabel=openbsd
+}
+
+func (f addrFlags) String() string {
+	var s string
+	for i, name := range addrFlagNames {
+		if f&(1<<uint(i)) != 0 {
+			if s != "" {
+				s += "|"
+			}
+			s += name
+		}
+	}
+	if s == "" {
+		return "<nil>"
+	}
+	return s
+}
+
+type sockaddrs []syscall.Sockaddr
+
+func (sas sockaddrs) String() string {
+	var s string
+	for _, sa := range sas {
+		if sa == nil {
+			continue
+		}
+		if len(s) > 0 {
+			s += " "
+		}
+		switch sa := sa.(type) {
+		case *syscall.SockaddrDatalink:
+			s += fmt.Sprintf("[%v/%v/%v t/n/a/s=%v/%v/%v/%v]", sa.Len, addrFamily(sa.Family), sa.Index, sa.Type, sa.Nlen, sa.Alen, sa.Slen)
+		case *syscall.SockaddrInet4:
+			s += fmt.Sprintf("%v", net.IP(sa.Addr[:]).To4())
+		case *syscall.SockaddrInet6:
+			s += fmt.Sprintf("%v", net.IP(sa.Addr[:]).To16())
+		}
+	}
+	if s == "" {
+		return "<nil>"
+	}
+	return s
+}
+
+func (sas sockaddrs) match(flags addrFlags) error {
+	var f addrFlags
+	family := syscall.AF_UNSPEC
+	for i := range sas {
+		if sas[i] != nil {
+			f |= 1 << uint(i)
+		}
+		switch sas[i].(type) {
+		case *syscall.SockaddrInet4:
+			if family == syscall.AF_UNSPEC {
+				family = syscall.AF_INET
+			}
+			if family != syscall.AF_INET {
+				return fmt.Errorf("got %v; want %v", sockaddrs(sas), family)
+			}
+		case *syscall.SockaddrInet6:
+			if family == syscall.AF_UNSPEC {
+				family = syscall.AF_INET6
+			}
+			if family != syscall.AF_INET6 {
+				return fmt.Errorf("got %v; want %v", sockaddrs(sas), family)
+			}
+		}
+	}
+	if f != flags {
+		return fmt.Errorf("got %v; want %v", f, flags)
+	}
+	return nil
+}
diff --git a/third_party/gofrontend/libgo/go/syscall/route_darwin.go b/third_party/gofrontend/libgo/go/syscall/route_darwin.go
index ad27907..89bca12 100644
--- a/third_party/gofrontend/libgo/go/syscall/route_darwin.go
+++ b/third_party/gofrontend/libgo/go/syscall/route_darwin.go
@@ -2,8 +2,6 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-// Routing sockets and messages for Darwin
-
 package syscall
 
 import "unsafe"
@@ -33,29 +31,37 @@
 	Data   []byte
 }
 
-const rtaIfmaMask = RTA_GATEWAY | RTA_IFP | RTA_IFA
-
-func (m *InterfaceMulticastAddrMessage) sockaddr() (sas []Sockaddr) {
-	if m.Header.Addrs&rtaIfmaMask == 0 {
-		return nil
-	}
+func (m *InterfaceMulticastAddrMessage) sockaddr() ([]Sockaddr, error) {
+	var sas [RTAX_MAX]Sockaddr
 	b := m.Data[:]
-	for i := uint(0); i < RTAX_MAX; i++ {
-		if m.Header.Addrs&rtaIfmaMask&(1<<i) == 0 {
+	for i := uint(0); i < RTAX_MAX && len(b) >= minRoutingSockaddrLen; i++ {
+		if m.Header.Addrs&(1<<i) == 0 {
 			continue
 		}
 		rsa := (*RawSockaddr)(unsafe.Pointer(&b[0]))
-		switch i {
-		case RTAX_IFA:
-			sa, e := anyToSockaddr((*RawSockaddrAny)(unsafe.Pointer(rsa)))
-			if e != nil {
-				return nil
+		switch rsa.Family {
+		case AF_LINK:
+			sa, err := parseSockaddrLink(b)
+			if err != nil {
+				return nil, err
 			}
-			sas = append(sas, sa)
-		case RTAX_GATEWAY, RTAX_IFP:
-			// nothing to do
+			sas[i] = sa
+			b = b[rsaAlignOf(int(rsa.Len)):]
+		case AF_INET, AF_INET6:
+			sa, err := parseSockaddrInet(b, rsa.Family)
+			if err != nil {
+				return nil, err
+			}
+			sas[i] = sa
+			b = b[rsaAlignOf(int(rsa.Len)):]
+		default:
+			sa, l, err := parseLinkLayerAddr(b)
+			if err != nil {
+				return nil, err
+			}
+			sas[i] = sa
+			b = b[l:]
 		}
-		b = b[rsaAlignOf(int(rsa.Len)):]
 	}
-	return sas
+	return sas[:], nil
 }
diff --git a/third_party/gofrontend/libgo/go/syscall/route_dragonfly.go b/third_party/gofrontend/libgo/go/syscall/route_dragonfly.go
index 79190d2..5226f7f 100644
--- a/third_party/gofrontend/libgo/go/syscall/route_dragonfly.go
+++ b/third_party/gofrontend/libgo/go/syscall/route_dragonfly.go
@@ -2,8 +2,6 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-// Routing sockets and messages for Dragonfly
-
 package syscall
 
 import "unsafe"
@@ -12,6 +10,8 @@
 	switch any.Type {
 	case RTM_ADD, RTM_DELETE, RTM_CHANGE, RTM_GET, RTM_LOSING, RTM_REDIRECT, RTM_MISS, RTM_LOCK, RTM_RESOLVE:
 		p := (*RouteMessage)(unsafe.Pointer(any))
+		// We don't support sockaddr_mpls for now.
+		p.Header.Addrs &= RTA_DST | RTA_GATEWAY | RTA_NETMASK | RTA_GENMASK | RTA_IFA | RTA_IFP | RTA_BRD | RTA_AUTHOR
 		return &RouteMessage{Header: p.Header, Data: b[SizeofRtMsghdr:any.Msglen]}
 	case RTM_IFINFO:
 		p := (*InterfaceMessage)(unsafe.Pointer(any))
@@ -35,7 +35,7 @@
 	Header IfAnnounceMsghdr
 }
 
-func (m *InterfaceAnnounceMessage) sockaddr() (sas []Sockaddr) { return nil }
+func (m *InterfaceAnnounceMessage) sockaddr() ([]Sockaddr, error) { return nil, nil }
 
 // InterfaceMulticastAddrMessage represents a routing message
 // containing network interface address entries.
@@ -44,29 +44,37 @@
 	Data   []byte
 }
 
-const rtaIfmaMask = RTA_GATEWAY | RTA_IFP | RTA_IFA
-
-func (m *InterfaceMulticastAddrMessage) sockaddr() (sas []Sockaddr) {
-	if m.Header.Addrs&rtaIfmaMask == 0 {
-		return nil
-	}
+func (m *InterfaceMulticastAddrMessage) sockaddr() ([]Sockaddr, error) {
+	var sas [RTAX_MAX]Sockaddr
 	b := m.Data[:]
-	for i := uint(0); i < RTAX_MAX; i++ {
-		if m.Header.Addrs&rtaIfmaMask&(1<<i) == 0 {
+	for i := uint(0); i < RTAX_MAX && len(b) >= minRoutingSockaddrLen; i++ {
+		if m.Header.Addrs&(1<<i) == 0 {
 			continue
 		}
 		rsa := (*RawSockaddr)(unsafe.Pointer(&b[0]))
-		switch i {
-		case RTAX_IFA:
-			sa, e := anyToSockaddr((*RawSockaddrAny)(unsafe.Pointer(rsa)))
-			if e != nil {
-				return nil
+		switch rsa.Family {
+		case AF_LINK:
+			sa, err := parseSockaddrLink(b)
+			if err != nil {
+				return nil, err
 			}
-			sas = append(sas, sa)
-		case RTAX_GATEWAY, RTAX_IFP:
-			// nothing to do
+			sas[i] = sa
+			b = b[rsaAlignOf(int(rsa.Len)):]
+		case AF_INET, AF_INET6:
+			sa, err := parseSockaddrInet(b, rsa.Family)
+			if err != nil {
+				return nil, err
+			}
+			sas[i] = sa
+			b = b[rsaAlignOf(int(rsa.Len)):]
+		default:
+			sa, l, err := parseLinkLayerAddr(b)
+			if err != nil {
+				return nil, err
+			}
+			sas[i] = sa
+			b = b[l:]
 		}
-		b = b[rsaAlignOf(int(rsa.Len)):]
 	}
-	return sas
+	return sas[:], nil
 }
diff --git a/third_party/gofrontend/libgo/go/syscall/route_freebsd.go b/third_party/gofrontend/libgo/go/syscall/route_freebsd.go
index 15897b1..0e18103 100644
--- a/third_party/gofrontend/libgo/go/syscall/route_freebsd.go
+++ b/third_party/gofrontend/libgo/go/syscall/route_freebsd.go
@@ -2,8 +2,6 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-// Routing sockets and messages for FreeBSD
-
 package syscall
 
 import "unsafe"
@@ -13,13 +11,31 @@
 
 func init() {
 	freebsdVersion, _ = SysctlUint32("kern.osreldate")
+	conf, _ := Sysctl("kern.conftxt")
+	for i, j := 0, 0; j < len(conf); j++ {
+		if conf[j] != '\n' {
+			continue
+		}
+		s := conf[i:j]
+		i = j + 1
+		if len(s) > len("machine") && s[:len("machine")] == "machine" {
+			s = s[len("machine"):]
+			for k := 0; k < len(s); k++ {
+				if s[k] == ' ' || s[k] == '\t' {
+					s = s[1:]
+				}
+				break
+			}
+			freebsdConfArch = s
+			break
+		}
+	}
 }
 
 func (any *anyMessage) toRoutingMessage(b []byte) RoutingMessage {
 	switch any.Type {
 	case RTM_ADD, RTM_DELETE, RTM_CHANGE, RTM_GET, RTM_LOSING, RTM_REDIRECT, RTM_MISS, RTM_LOCK, RTM_RESOLVE:
-		p := (*RouteMessage)(unsafe.Pointer(any))
-		return &RouteMessage{Header: p.Header, Data: b[SizeofRtMsghdr:any.Msglen]}
+		return any.parseRouteMessage(b)
 	case RTM_IFINFO:
 		return any.parseInterfaceMessage(b)
 	case RTM_IFANNOUNCE:
@@ -41,7 +57,7 @@
 	Header IfAnnounceMsghdr
 }
 
-func (m *InterfaceAnnounceMessage) sockaddr() (sas []Sockaddr) { return nil }
+func (m *InterfaceAnnounceMessage) sockaddr() ([]Sockaddr, error) { return nil, nil }
 
 // InterfaceMulticastAddrMessage represents a routing message
 // containing network interface address entries.
@@ -50,29 +66,37 @@
 	Data   []byte
 }
 
-const rtaIfmaMask = RTA_GATEWAY | RTA_IFP | RTA_IFA
-
-func (m *InterfaceMulticastAddrMessage) sockaddr() (sas []Sockaddr) {
-	if m.Header.Addrs&rtaIfmaMask == 0 {
-		return nil
-	}
+func (m *InterfaceMulticastAddrMessage) sockaddr() ([]Sockaddr, error) {
+	var sas [RTAX_MAX]Sockaddr
 	b := m.Data[:]
-	for i := uint(0); i < RTAX_MAX; i++ {
-		if m.Header.Addrs&rtaIfmaMask&(1<<i) == 0 {
+	for i := uint(0); i < RTAX_MAX && len(b) >= minRoutingSockaddrLen; i++ {
+		if m.Header.Addrs&(1<<i) == 0 {
 			continue
 		}
 		rsa := (*RawSockaddr)(unsafe.Pointer(&b[0]))
-		switch i {
-		case RTAX_IFA:
-			sa, e := anyToSockaddr((*RawSockaddrAny)(unsafe.Pointer(rsa)))
-			if e != nil {
-				return nil
+		switch rsa.Family {
+		case AF_LINK:
+			sa, err := parseSockaddrLink(b)
+			if err != nil {
+				return nil, err
 			}
-			sas = append(sas, sa)
-		case RTAX_GATEWAY, RTAX_IFP:
-			// nothing to do
+			sas[i] = sa
+			b = b[rsaAlignOf(int(rsa.Len)):]
+		case AF_INET, AF_INET6:
+			sa, err := parseSockaddrInet(b, rsa.Family)
+			if err != nil {
+				return nil, err
+			}
+			sas[i] = sa
+			b = b[rsaAlignOf(int(rsa.Len)):]
+		default:
+			sa, l, err := parseLinkLayerAddr(b)
+			if err != nil {
+				return nil, err
+			}
+			sas[i] = sa
+			b = b[l:]
 		}
-		b = b[rsaAlignOf(int(rsa.Len)):]
 	}
-	return sas
+	return sas[:], nil
 }
diff --git a/third_party/gofrontend/libgo/go/syscall/route_freebsd_32bit.go b/third_party/gofrontend/libgo/go/syscall/route_freebsd_32bit.go
index 93efddd..5c10b05 100644
--- a/third_party/gofrontend/libgo/go/syscall/route_freebsd_32bit.go
+++ b/third_party/gofrontend/libgo/go/syscall/route_freebsd_32bit.go
@@ -8,6 +8,15 @@
 
 import "unsafe"
 
+func (any *anyMessage) parseRouteMessage(b []byte) *RouteMessage {
+	p := (*RouteMessage)(unsafe.Pointer(any))
+	off := int(unsafe.Offsetof(p.Header.Rmx)) + SizeofRtMetrics
+	if freebsdConfArch == "amd64" {
+		off += SizeofRtMetrics // rt_metrics on amd64 is simply doubled
+	}
+	return &RouteMessage{Header: p.Header, Data: b[rsaAlignOf(off):any.Msglen]}
+}
+
 func (any *anyMessage) parseInterfaceMessage(b []byte) *InterfaceMessage {
 	p := (*InterfaceMessage)(unsafe.Pointer(any))
 	// FreeBSD 10 and beyond have a restructured mbuf
@@ -18,7 +27,7 @@
 		p.Header.Data.Hwassist = uint32(m.Data.Hwassist)
 		p.Header.Data.Epoch = m.Data.Epoch
 		p.Header.Data.Lastchange = m.Data.Lastchange
-		return &InterfaceMessage{Header: p.Header, Data: b[sizeofIfMsghdr:any.Msglen]}
+		return &InterfaceMessage{Header: p.Header, Data: b[int(unsafe.Offsetof(p.Header.Data))+int(p.Header.Data.Datalen) : any.Msglen]}
 	}
-	return &InterfaceMessage{Header: p.Header, Data: b[SizeofIfMsghdr:any.Msglen]}
+	return &InterfaceMessage{Header: p.Header, Data: b[int(unsafe.Offsetof(p.Header.Data))+int(p.Header.Data.Datalen) : any.Msglen]}
 }
diff --git a/third_party/gofrontend/libgo/go/syscall/route_freebsd_64bit.go b/third_party/gofrontend/libgo/go/syscall/route_freebsd_64bit.go
index 9377f2f..728837e 100644
--- a/third_party/gofrontend/libgo/go/syscall/route_freebsd_64bit.go
+++ b/third_party/gofrontend/libgo/go/syscall/route_freebsd_64bit.go
@@ -8,7 +8,12 @@
 
 import "unsafe"
 
+func (any *anyMessage) parseRouteMessage(b []byte) *RouteMessage {
+	p := (*RouteMessage)(unsafe.Pointer(any))
+	return &RouteMessage{Header: p.Header, Data: b[rsaAlignOf(int(unsafe.Offsetof(p.Header.Rmx))+SizeofRtMetrics):any.Msglen]}
+}
+
 func (any *anyMessage) parseInterfaceMessage(b []byte) *InterfaceMessage {
 	p := (*InterfaceMessage)(unsafe.Pointer(any))
-	return &InterfaceMessage{Header: p.Header, Data: b[SizeofIfMsghdr:any.Msglen]}
+	return &InterfaceMessage{Header: p.Header, Data: b[int(unsafe.Offsetof(p.Header.Data))+int(p.Header.Data.Datalen) : any.Msglen]}
 }
diff --git a/third_party/gofrontend/libgo/go/syscall/route_ifma_test.go b/third_party/gofrontend/libgo/go/syscall/route_ifma_test.go
new file mode 100644
index 0000000..af2b67d
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/syscall/route_ifma_test.go
@@ -0,0 +1,74 @@
+// 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 darwin dragonfly freebsd
+
+package syscall_test
+
+import (
+	"fmt"
+	"syscall"
+)
+
+func parseRoutingMessageHeader(m syscall.RoutingMessage) (addrFlags, error) {
+	switch m := m.(type) {
+	case *syscall.RouteMessage:
+		errno := syscall.Errno(uintptr(m.Header.Errno))
+		if errno != 0 {
+			return 0, fmt.Errorf("%T: %v, %#v", m, errno, m.Header)
+		}
+		return addrFlags(m.Header.Addrs), nil
+	case *syscall.InterfaceMessage:
+		return addrFlags(m.Header.Addrs), nil
+	case *syscall.InterfaceAddrMessage:
+		return addrFlags(m.Header.Addrs), nil
+	case *syscall.InterfaceMulticastAddrMessage:
+		return addrFlags(m.Header.Addrs), nil
+	default:
+		panic(fmt.Sprintf("unknown routing message type: %T", m))
+	}
+}
+
+func parseRoutingSockaddrs(m syscall.RoutingMessage) ([]syscall.Sockaddr, error) {
+	switch m := m.(type) {
+	case *syscall.RouteMessage:
+		sas, err := syscall.ParseRoutingSockaddr(m)
+		if err != nil {
+			return nil, fmt.Errorf("%T: %v, %#v", m, err, m.Data)
+		}
+		if err = sockaddrs(sas).match(addrFlags(m.Header.Addrs)); err != nil {
+			return nil, err
+		}
+		return sas, nil
+	case *syscall.InterfaceMessage:
+		sas, err := syscall.ParseRoutingSockaddr(m)
+		if err != nil {
+			return nil, fmt.Errorf("%T: %v, %#v", m, err, m.Data)
+		}
+		if err = sockaddrs(sas).match(addrFlags(m.Header.Addrs)); err != nil {
+			return nil, err
+		}
+		return sas, nil
+	case *syscall.InterfaceAddrMessage:
+		sas, err := syscall.ParseRoutingSockaddr(m)
+		if err != nil {
+			return nil, fmt.Errorf("%T: %v, %#v", m, err, m.Data)
+		}
+		if err = sockaddrs(sas).match(addrFlags(m.Header.Addrs)); err != nil {
+			return nil, err
+		}
+		return sas, nil
+	case *syscall.InterfaceMulticastAddrMessage:
+		sas, err := syscall.ParseRoutingSockaddr(m)
+		if err != nil {
+			return nil, fmt.Errorf("%T: %v, %#v", m, err, m.Data)
+		}
+		if err = sockaddrs(sas).match(addrFlags(m.Header.Addrs)); err != nil {
+			return nil, err
+		}
+		return sas, nil
+	default:
+		panic(fmt.Sprintf("unknown routing message type: %T", m))
+	}
+}
diff --git a/third_party/gofrontend/libgo/go/syscall/route_netbsd.go b/third_party/gofrontend/libgo/go/syscall/route_netbsd.go
index 9883aeb..d605ffa 100644
--- a/third_party/gofrontend/libgo/go/syscall/route_netbsd.go
+++ b/third_party/gofrontend/libgo/go/syscall/route_netbsd.go
@@ -2,8 +2,6 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-// Routing sockets and messages for NetBSD
-
 package syscall
 
 import "unsafe"
@@ -12,6 +10,8 @@
 	switch any.Type {
 	case RTM_ADD, RTM_DELETE, RTM_CHANGE, RTM_GET, RTM_LOSING, RTM_REDIRECT, RTM_MISS, RTM_LOCK, RTM_RESOLVE:
 		p := (*RouteMessage)(unsafe.Pointer(any))
+		// We don't support sockaddr_mpls for now.
+		p.Header.Addrs &= RTA_DST | RTA_GATEWAY | RTA_NETMASK | RTA_GENMASK | RTA_IFA | RTA_IFP | RTA_BRD | RTA_AUTHOR
 		return &RouteMessage{Header: p.Header, Data: b[SizeofRtMsghdr:any.Msglen]}
 	case RTM_IFINFO:
 		p := (*InterfaceMessage)(unsafe.Pointer(any))
@@ -32,4 +32,4 @@
 	Header IfAnnounceMsghdr
 }
 
-func (m *InterfaceAnnounceMessage) sockaddr() (sas []Sockaddr) { return nil }
+func (m *InterfaceAnnounceMessage) sockaddr() ([]Sockaddr, error) { return nil, nil }
diff --git a/third_party/gofrontend/libgo/go/syscall/route_noifma_test.go b/third_party/gofrontend/libgo/go/syscall/route_noifma_test.go
new file mode 100644
index 0000000..19d5d8e
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/syscall/route_noifma_test.go
@@ -0,0 +1,63 @@
+// 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 netbsd openbsd
+
+package syscall_test
+
+import (
+	"fmt"
+	"syscall"
+)
+
+func parseRoutingMessageHeader(m syscall.RoutingMessage) (addrFlags, error) {
+	switch m := m.(type) {
+	case *syscall.RouteMessage:
+		errno := syscall.Errno(uintptr(m.Header.Errno))
+		if errno != 0 {
+			return 0, fmt.Errorf("%T: %v, %#v", m, errno, m.Header)
+		}
+		return addrFlags(m.Header.Addrs), nil
+	case *syscall.InterfaceMessage:
+		return addrFlags(m.Header.Addrs), nil
+	case *syscall.InterfaceAddrMessage:
+		return addrFlags(m.Header.Addrs), nil
+	default:
+		panic(fmt.Sprintf("unknown routing message type: %T", m))
+	}
+}
+
+func parseRoutingSockaddrs(m syscall.RoutingMessage) ([]syscall.Sockaddr, error) {
+	switch m := m.(type) {
+	case *syscall.RouteMessage:
+		sas, err := syscall.ParseRoutingSockaddr(m)
+		if err != nil {
+			return nil, fmt.Errorf("%T: %v, %#v", m, err, m.Data)
+		}
+		if err = sockaddrs(sas).match(addrFlags(m.Header.Addrs)); err != nil {
+			return nil, err
+		}
+		return sas, nil
+	case *syscall.InterfaceMessage:
+		sas, err := syscall.ParseRoutingSockaddr(m)
+		if err != nil {
+			return nil, fmt.Errorf("%T: %v, %#v", m, err, m.Data)
+		}
+		if err = sockaddrs(sas).match(addrFlags(m.Header.Addrs)); err != nil {
+			return nil, err
+		}
+		return sas, nil
+	case *syscall.InterfaceAddrMessage:
+		sas, err := syscall.ParseRoutingSockaddr(m)
+		if err != nil {
+			return nil, fmt.Errorf("%T: %v, %#v", m, err, m.Data)
+		}
+		if err = sockaddrs(sas).match(addrFlags(m.Header.Addrs)); err != nil {
+			return nil, err
+		}
+		return sas, nil
+	default:
+		panic(fmt.Sprintf("unknown routing message type: %T", m))
+	}
+}
diff --git a/third_party/gofrontend/libgo/go/syscall/route_openbsd.go b/third_party/gofrontend/libgo/go/syscall/route_openbsd.go
index e508640..7804a08 100644
--- a/third_party/gofrontend/libgo/go/syscall/route_openbsd.go
+++ b/third_party/gofrontend/libgo/go/syscall/route_openbsd.go
@@ -2,8 +2,6 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-// Routing sockets and messages for OpenBSD
-
 package syscall
 
 import "unsafe"
@@ -12,6 +10,8 @@
 	switch any.Type {
 	case RTM_ADD, RTM_DELETE, RTM_CHANGE, RTM_GET, RTM_LOSING, RTM_REDIRECT, RTM_MISS, RTM_LOCK, RTM_RESOLVE:
 		p := (*RouteMessage)(unsafe.Pointer(any))
+		// We don't support sockaddr_rtlabel for now.
+		p.Header.Addrs &= RTA_DST | RTA_GATEWAY | RTA_NETMASK | RTA_GENMASK | RTA_IFA | RTA_IFP | RTA_BRD | RTA_AUTHOR | RTA_SRC | RTA_SRCMASK
 		return &RouteMessage{Header: p.Header, Data: b[p.Header.Hdrlen:any.Msglen]}
 	case RTM_IFINFO:
 		p := (*InterfaceMessage)(unsafe.Pointer(any))
@@ -32,4 +32,4 @@
 	Header IfAnnounceMsghdr
 }
 
-func (m *InterfaceAnnounceMessage) sockaddr() (sas []Sockaddr) { return nil }
+func (m *InterfaceAnnounceMessage) sockaddr() ([]Sockaddr, error) { return nil, nil }
diff --git a/third_party/gofrontend/libgo/go/syscall/security_windows.go b/third_party/gofrontend/libgo/go/syscall/security_windows.go
index b22ecf5..1625b07 100644
--- a/third_party/gofrontend/libgo/go/syscall/security_windows.go
+++ b/third_party/gofrontend/libgo/go/syscall/security_windows.go
@@ -41,21 +41,20 @@
 	if e != nil {
 		return "", e
 	}
-	b := make([]uint16, 50)
-	n := uint32(len(b))
-	e = TranslateName(u, from, to, &b[0], &n)
-	if e != nil {
+	n := uint32(50)
+	for {
+		b := make([]uint16, n)
+		e = TranslateName(u, from, to, &b[0], &n)
+		if e == nil {
+			return UTF16ToString(b[:n]), nil
+		}
 		if e != ERROR_INSUFFICIENT_BUFFER {
 			return "", e
 		}
-		// make receive buffers of requested size and try again
-		b = make([]uint16, n)
-		e = TranslateName(u, from, to, &b[0], &n)
-		if e != nil {
+		if n <= uint32(len(b)) {
 			return "", e
 		}
 	}
-	return UTF16ToString(b), nil
 }
 
 const (
@@ -136,26 +135,23 @@
 			return nil, "", 0, e
 		}
 	}
-	db := make([]uint16, 50)
-	dn := uint32(len(db))
-	b := make([]byte, 50)
-	n := uint32(len(b))
-	sid = (*SID)(unsafe.Pointer(&b[0]))
-	e = LookupAccountName(sys, acc, sid, &n, &db[0], &dn, &accType)
-	if e != nil {
+	n := uint32(50)
+	dn := uint32(50)
+	for {
+		b := make([]byte, n)
+		db := make([]uint16, dn)
+		sid = (*SID)(unsafe.Pointer(&b[0]))
+		e = LookupAccountName(sys, acc, sid, &n, &db[0], &dn, &accType)
+		if e == nil {
+			return sid, UTF16ToString(db), accType, nil
+		}
 		if e != ERROR_INSUFFICIENT_BUFFER {
 			return nil, "", 0, e
 		}
-		// make receive buffers of requested size and try again
-		b = make([]byte, n)
-		sid = (*SID)(unsafe.Pointer(&b[0]))
-		db = make([]uint16, dn)
-		e = LookupAccountName(sys, acc, sid, &n, &db[0], &dn, &accType)
-		if e != nil {
+		if n <= uint32(len(b)) {
 			return nil, "", 0, e
 		}
 	}
-	return sid, UTF16ToString(db), accType, nil
 }
 
 // String converts sid to a string format
@@ -197,24 +193,22 @@
 			return "", "", 0, err
 		}
 	}
-	b := make([]uint16, 50)
-	n := uint32(len(b))
-	db := make([]uint16, 50)
-	dn := uint32(len(db))
-	e := LookupAccountSid(sys, sid, &b[0], &n, &db[0], &dn, &accType)
-	if e != nil {
+	n := uint32(50)
+	dn := uint32(50)
+	for {
+		b := make([]uint16, n)
+		db := make([]uint16, dn)
+		e := LookupAccountSid(sys, sid, &b[0], &n, &db[0], &dn, &accType)
+		if e == nil {
+			return UTF16ToString(b), UTF16ToString(db), accType, nil
+		}
 		if e != ERROR_INSUFFICIENT_BUFFER {
 			return "", "", 0, e
 		}
-		// make receive buffers of requested size and try again
-		b = make([]uint16, n)
-		db = make([]uint16, dn)
-		e = LookupAccountSid(nil, sid, &b[0], &n, &db[0], &dn, &accType)
-		if e != nil {
+		if n <= uint32(len(b)) {
 			return "", "", 0, e
 		}
 	}
-	return UTF16ToString(b), UTF16ToString(db), accType, nil
 }
 
 const (
@@ -326,21 +320,20 @@
 
 // getInfo retrieves a specified type of information about an access token.
 func (t Token) getInfo(class uint32, initSize int) (unsafe.Pointer, error) {
-	b := make([]byte, initSize)
-	var n uint32
-	e := GetTokenInformation(t, class, &b[0], uint32(len(b)), &n)
-	if e != nil {
+	n := uint32(initSize)
+	for {
+		b := make([]byte, n)
+		e := GetTokenInformation(t, class, &b[0], uint32(len(b)), &n)
+		if e == nil {
+			return unsafe.Pointer(&b[0]), nil
+		}
 		if e != ERROR_INSUFFICIENT_BUFFER {
 			return nil, e
 		}
-		// make receive buffers of requested size and try again
-		b = make([]byte, n)
-		e = GetTokenInformation(t, class, &b[0], uint32(len(b)), &n)
-		if e != nil {
+		if n <= uint32(len(b)) {
 			return nil, e
 		}
 	}
-	return unsafe.Pointer(&b[0]), nil
 }
 
 // GetTokenUser retrieves access token t user account information.
@@ -366,19 +359,18 @@
 // GetUserProfileDirectory retrieves path to the
 // root directory of the access token t user's profile.
 func (t Token) GetUserProfileDirectory() (string, error) {
-	b := make([]uint16, 100)
-	n := uint32(len(b))
-	e := GetUserProfileDirectory(t, &b[0], &n)
-	if e != nil {
+	n := uint32(100)
+	for {
+		b := make([]uint16, n)
+		e := GetUserProfileDirectory(t, &b[0], &n)
+		if e == nil {
+			return UTF16ToString(b), nil
+		}
 		if e != ERROR_INSUFFICIENT_BUFFER {
 			return "", e
 		}
-		// make receive buffers of requested size and try again
-		b = make([]uint16, n)
-		e = GetUserProfileDirectory(t, &b[0], &n)
-		if e != nil {
+		if n <= uint32(len(b)) {
 			return "", e
 		}
 	}
-	return UTF16ToString(b), nil
 }
diff --git a/third_party/gofrontend/libgo/go/syscall/socket_linux.go b/third_party/gofrontend/libgo/go/syscall/socket_linux.go
index 8546abc..5064e77 100644
--- a/third_party/gofrontend/libgo/go/syscall/socket_linux.go
+++ b/third_party/gofrontend/libgo/go/syscall/socket_linux.go
@@ -136,11 +136,6 @@
 	Groups uint32
 }
 
-type RawSockaddr struct {
-	Family uint16
-	Data   [14]int8
-}
-
 // BindToDevice binds the socket associated with fd to device.
 func BindToDevice(fd int, device string) (err error) {
 	return SetsockoptString(fd, SOL_SOCKET, SO_BINDTODEVICE, device)
diff --git a/third_party/gofrontend/libgo/go/syscall/socket_linux_ppc64x_type.go b/third_party/gofrontend/libgo/go/syscall/socket_linux_ppc64x_type.go
new file mode 100644
index 0000000..8a707ce
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/syscall/socket_linux_ppc64x_type.go
@@ -0,0 +1,14 @@
+// socket_linux_ppc64x_type.go -- Socket handling specific to ppc64 GNU/Linux.
+
+// 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 syscall
+
+// Type needed on ppc64le & ppc64
+
+type RawSockaddr struct {
+	Family uint16
+	Data   [14]uint8
+}
diff --git a/third_party/gofrontend/libgo/go/syscall/socket_linux_type.go b/third_party/gofrontend/libgo/go/syscall/socket_linux_type.go
new file mode 100644
index 0000000..45b8c6e
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/syscall/socket_linux_type.go
@@ -0,0 +1,14 @@
+// socket_linux_type.go -- Socket handling specific to GNU/Linux.
+
+// 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 syscall
+
+// Type needed if not on ppc64le or ppc64
+
+type RawSockaddr struct {
+	Family uint16
+	Data   [14]int8
+}
diff --git a/third_party/gofrontend/libgo/go/syscall/syscall.go b/third_party/gofrontend/libgo/go/syscall/syscall.go
index ef9d7d6..ff09711 100644
--- a/third_party/gofrontend/libgo/go/syscall/syscall.go
+++ b/third_party/gofrontend/libgo/go/syscall/syscall.go
@@ -20,7 +20,7 @@
 //
 // NOTE: This package is locked down. Code outside the standard
 // Go repository should be migrated to use the corresponding
-// package in the go.sys subrepository. That is also where updates
+// package in the golang.org/x/sys repository. That is also where updates
 // required by new systems or versions should be applied.
 // See https://golang.org/s/go1.4-syscall for more information.
 //
@@ -28,9 +28,11 @@
 
 import "unsafe"
 
-// StringByteSlice is deprecated. Use ByteSliceFromString instead.
+// StringByteSlice converts a string to a NUL-terminated []byte,
 // If s contains a NUL byte this function panics instead of
 // returning an error.
+//
+// Deprecated: Use ByteSliceFromString instead.
 func StringByteSlice(s string) []byte {
 	a, err := ByteSliceFromString(s)
 	if err != nil {
@@ -53,9 +55,11 @@
 	return a, nil
 }
 
-// StringBytePtr is deprecated. Use BytePtrFromString instead.
-// If s contains a NUL byte this function panics instead of
-// returning an error.
+// StringBytePtr returns a pointer to a NUL-terminated array of bytes.
+// If s contains a NUL byte this function panics instead of returning
+// an error.
+//
+// Deprecated: Use BytePtrFromString instead.
 func StringBytePtr(s string) *byte { return &StringByteSlice(s)[0] }
 
 // BytePtrFromString returns a pointer to a NUL-terminated array of
diff --git a/third_party/gofrontend/libgo/go/syscall/syscall_linux_test.go b/third_party/gofrontend/libgo/go/syscall/syscall_linux_test.go
new file mode 100644
index 0000000..40fce6d
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/syscall/syscall_linux_test.go
@@ -0,0 +1,140 @@
+// 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 syscall_test
+
+import (
+	"bufio"
+	"fmt"
+	"io"
+	"io/ioutil"
+	"os"
+	"os/exec"
+	"os/signal"
+	"path/filepath"
+	"syscall"
+	"testing"
+	"time"
+)
+
+func TestMain(m *testing.M) {
+	if os.Getenv("GO_DEATHSIG_PARENT") == "1" {
+		deathSignalParent()
+	} else if os.Getenv("GO_DEATHSIG_CHILD") == "1" {
+		deathSignalChild()
+	}
+
+	os.Exit(m.Run())
+}
+
+func TestLinuxDeathSignal(t *testing.T) {
+	if os.Getuid() != 0 {
+		t.Skip("skipping root only test")
+	}
+
+	// Copy the test binary to a location that a non-root user can read/execute
+	// after we drop privileges
+	tempDir, err := ioutil.TempDir("", "TestDeathSignal")
+	if err != nil {
+		t.Fatalf("cannot create temporary directory: %v", err)
+	}
+	defer os.RemoveAll(tempDir)
+	os.Chmod(tempDir, 0755)
+
+	tmpBinary := filepath.Join(tempDir, filepath.Base(os.Args[0]))
+
+	src, err := os.Open(os.Args[0])
+	if err != nil {
+		t.Fatalf("cannot open binary %q, %v", os.Args[0], err)
+	}
+	defer src.Close()
+
+	dst, err := os.OpenFile(tmpBinary, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0755)
+	if err != nil {
+		t.Fatalf("cannot create temporary binary %q, %v", tmpBinary, err)
+	}
+	if _, err := io.Copy(dst, src); err != nil {
+		t.Fatalf("failed to copy test binary to %q, %v", tmpBinary, err)
+	}
+	err = dst.Close()
+	if err != nil {
+		t.Fatalf("failed to close test binary %q, %v", tmpBinary, err)
+	}
+
+	cmd := exec.Command(tmpBinary)
+	cmd.Env = []string{"GO_DEATHSIG_PARENT=1"}
+	chldStdin, err := cmd.StdinPipe()
+	if err != nil {
+		t.Fatal("failed to create new stdin pipe: %v", err)
+	}
+	chldStdout, err := cmd.StdoutPipe()
+	if err != nil {
+		t.Fatal("failed to create new stdout pipe: %v", err)
+	}
+	cmd.Stderr = os.Stderr
+
+	err = cmd.Start()
+	defer cmd.Wait()
+	if err != nil {
+		t.Fatalf("failed to start first child process: %v", err)
+	}
+
+	chldPipe := bufio.NewReader(chldStdout)
+
+	if got, err := chldPipe.ReadString('\n'); got == "start\n" {
+		syscall.Kill(cmd.Process.Pid, syscall.SIGTERM)
+
+		go func() {
+			time.Sleep(5 * time.Second)
+			chldStdin.Close()
+		}()
+
+		want := "ok\n"
+		if got, err = chldPipe.ReadString('\n'); got != want {
+			t.Fatalf("expected %q, received %q, %v", want, got, err)
+		}
+	} else {
+		t.Fatalf("did not receive start from child, received %q, %v", got, err)
+	}
+}
+
+func deathSignalParent() {
+	cmd := exec.Command(os.Args[0])
+	cmd.Env = []string{"GO_DEATHSIG_CHILD=1"}
+	cmd.Stdin = os.Stdin
+	cmd.Stdout = os.Stdout
+	attrs := syscall.SysProcAttr{
+		Pdeathsig: syscall.SIGUSR1,
+		// UID/GID 99 is the user/group "nobody" on RHEL/Fedora and is
+		// unused on Ubuntu
+		Credential: &syscall.Credential{Uid: 99, Gid: 99},
+	}
+	cmd.SysProcAttr = &attrs
+
+	err := cmd.Start()
+	if err != nil {
+		fmt.Fprintf(os.Stderr, "death signal parent error: %v\n")
+		os.Exit(1)
+	}
+	cmd.Wait()
+	os.Exit(0)
+}
+
+func deathSignalChild() {
+	c := make(chan os.Signal, 1)
+	signal.Notify(c, syscall.SIGUSR1)
+	go func() {
+		<-c
+		fmt.Println("ok")
+		os.Exit(0)
+	}()
+	fmt.Println("start")
+
+	buf := make([]byte, 32)
+	os.Stdin.Read(buf)
+
+	// We expected to be signaled before stdin closed
+	fmt.Println("not ok")
+	os.Exit(1)
+}
diff --git a/third_party/gofrontend/libgo/go/syscall/syscall_unix.go b/third_party/gofrontend/libgo/go/syscall/syscall_unix.go
index 74f10c2..21bf6ea 100644
--- a/third_party/gofrontend/libgo/go/syscall/syscall_unix.go
+++ b/third_party/gofrontend/libgo/go/syscall/syscall_unix.go
@@ -172,6 +172,30 @@
 	return mapper.Munmap(b)
 }
 
+// Do the interface allocations only once for common
+// Errno values.
+var (
+	errEAGAIN error = EAGAIN
+	errEINVAL error = EINVAL
+	errENOENT error = ENOENT
+)
+
+// errnoErr returns common boxed Errno values, to prevent
+// allocations at runtime.
+func errnoErr(e Errno) error {
+	switch e {
+	case 0:
+		return nil
+	case EAGAIN:
+		return errEAGAIN
+	case EINVAL:
+		return errEINVAL
+	case ENOENT:
+		return errENOENT
+	}
+	return e
+}
+
 // A Signal is a number describing a process signal.
 // It implements the os.Signal interface.
 type Signal int
diff --git a/third_party/gofrontend/libgo/go/syscall/syscall_unix_test.go b/third_party/gofrontend/libgo/go/syscall/syscall_unix_test.go
index 897ad18..c7b4560 100644
--- a/third_party/gofrontend/libgo/go/syscall/syscall_unix_test.go
+++ b/third_party/gofrontend/libgo/go/syscall/syscall_unix_test.go
@@ -9,6 +9,7 @@
 import (
 	"flag"
 	"fmt"
+	"internal/testenv"
 	"io/ioutil"
 	"net"
 	"os"
@@ -60,20 +61,58 @@
 
 // TestFcntlFlock tests whether the file locking structure matches
 // the calling convention of each kernel.
+// On some Linux systems, glibc uses another set of values for the
+// commands and translates them to the correct value that the kernel
+// expects just before the actual fcntl syscall. As Go uses raw
+// syscalls directly, it must use the real value, not the glibc value.
+// Thus this test also verifies that the Flock_t structure can be
+// roundtripped with F_SETLK and F_GETLK.
 func TestFcntlFlock(t *testing.T) {
-	name := filepath.Join(os.TempDir(), "TestFcntlFlock")
-	fd, err := syscall.Open(name, syscall.O_CREAT|syscall.O_RDWR|syscall.O_CLOEXEC, 0)
-	if err != nil {
-		t.Fatalf("Open failed: %v", err)
+	if runtime.GOOS == "darwin" && (runtime.GOARCH == "arm" || runtime.GOARCH == "arm64") {
+		t.Skip("skipping; no child processes allowed on iOS")
 	}
-	defer syscall.Unlink(name)
-	defer syscall.Close(fd)
 	flock := syscall.Flock_t{
-		Type:  syscall.F_RDLCK,
-		Start: 0, Len: 0, Whence: 1,
+		Type:  syscall.F_WRLCK,
+		Start: 31415, Len: 271828, Whence: 1,
 	}
-	if err := syscall.FcntlFlock(uintptr(fd), syscall.F_GETLK, &flock); err != nil {
-		t.Fatalf("FcntlFlock failed: %v", err)
+	if os.Getenv("GO_WANT_HELPER_PROCESS") == "" {
+		// parent
+		name := filepath.Join(os.TempDir(), "TestFcntlFlock")
+		fd, err := syscall.Open(name, syscall.O_CREAT|syscall.O_RDWR|syscall.O_CLOEXEC, 0)
+		if err != nil {
+			t.Fatalf("Open failed: %v", err)
+		}
+		defer syscall.Unlink(name)
+		defer syscall.Close(fd)
+		if err := syscall.Ftruncate(fd, 1<<20); err != nil {
+			t.Fatalf("Ftruncate(1<<20) failed: %v", err)
+		}
+		if err := syscall.FcntlFlock(uintptr(fd), syscall.F_SETLK, &flock); err != nil {
+			t.Fatalf("FcntlFlock(F_SETLK) failed: %v", err)
+		}
+		cmd := exec.Command(os.Args[0], "-test.run=^TestFcntlFlock$")
+		cmd.Env = append(os.Environ(), "GO_WANT_HELPER_PROCESS=1")
+		cmd.ExtraFiles = []*os.File{os.NewFile(uintptr(fd), name)}
+		out, err := cmd.CombinedOutput()
+		if len(out) > 0 || err != nil {
+			t.Fatalf("child process: %q, %v", out, err)
+		}
+	} else {
+		// child
+		got := flock
+		// make sure the child lock is conflicting with the parent lock
+		got.Start--
+		got.Len++
+		if err := syscall.FcntlFlock(3, syscall.F_GETLK, &got); err != nil {
+			t.Fatalf("FcntlFlock(F_GETLK) failed: %v", err)
+		}
+		flock.Pid = int32(syscall.Getppid())
+		// Linux kernel always set Whence to 0
+		flock.Whence = 0
+		if got.Type == flock.Type && got.Start == flock.Start && got.Len == flock.Len && got.Pid == flock.Pid && got.Whence == flock.Whence {
+			os.Exit(0)
+		}
+		t.Fatalf("FcntlFlock got %v, want %v", got, flock)
 	}
 }
 
@@ -93,6 +132,9 @@
 		// TODO(aram): Figure out why ReadMsgUnix is returning empty message.
 		t.Skip("skipping test on solaris, see issue 7402")
 	}
+
+	testenv.MustHaveExec(t)
+
 	if os.Getenv("GO_WANT_HELPER_PROCESS") == "1" {
 		passFDChild()
 		return
@@ -116,11 +158,7 @@
 	defer readFile.Close()
 
 	cmd := exec.Command(os.Args[0], "-test.run=^TestPassFD$", "--", tempDir)
-	cmd.Env = []string{"GO_WANT_HELPER_PROCESS=1"}
-	path := os.Getenv("LD_LIBRARY_PATH")
-	if path != "" {
-		cmd.Env = append(cmd.Env, "LD_LIBRARY_PATH="+path)
-	}
+	cmd.Env = append(os.Environ(), "GO_WANT_HELPER_PROCESS=1")
 	cmd.ExtraFiles = []*os.File{writeFile}
 
 	out, err := cmd.CombinedOutput()
@@ -179,7 +217,7 @@
 	defer os.Exit(0)
 
 	// Look for our fd. It should be fd 3, but we work around an fd leak
-	// bug here (http://golang.org/issue/2603) to let it be elsewhere.
+	// bug here (https://golang.org/issue/2603) to let it be elsewhere.
 	var uc *net.UnixConn
 	for fd := uintptr(3); fd <= 10; fd++ {
 		f := os.NewFile(fd, "unix-conn")
diff --git a/third_party/gofrontend/libgo/go/testing/benchmark.go b/third_party/gofrontend/libgo/go/testing/benchmark.go
index ffd5376..62e696d 100644
--- a/third_party/gofrontend/libgo/go/testing/benchmark.go
+++ b/third_party/gofrontend/libgo/go/testing/benchmark.go
@@ -280,6 +280,14 @@
 		r.AllocedBytesPerOp(), r.AllocsPerOp())
 }
 
+// benchmarkName returns full name of benchmark including procs suffix.
+func benchmarkName(name string, n int) string {
+	if n != 1 {
+		return fmt.Sprintf("%s-%d", name, n)
+	}
+	return name
+}
+
 // An internal function but exported because it is cross-package; part of the implementation
 // of the "go test" command.
 func RunBenchmarks(matchString func(pat, str string) (bool, error), benchmarks []InternalBenchmark) {
@@ -287,15 +295,30 @@
 	if len(*matchBenchmarks) == 0 {
 		return
 	}
+	// Collect matching benchmarks and determine longest name.
+	maxprocs := 1
+	for _, procs := range cpuList {
+		if procs > maxprocs {
+			maxprocs = procs
+		}
+	}
+	maxlen := 0
+	var bs []InternalBenchmark
 	for _, Benchmark := range benchmarks {
 		matched, err := matchString(*matchBenchmarks, Benchmark.Name)
 		if err != nil {
 			fmt.Fprintf(os.Stderr, "testing: invalid regexp for -test.bench: %s\n", err)
 			os.Exit(1)
 		}
-		if !matched {
-			continue
+		if matched {
+			bs = append(bs, Benchmark)
+			benchName := benchmarkName(Benchmark.Name, maxprocs)
+			if l := len(benchName); l > maxlen {
+				maxlen = l
+			}
 		}
+	}
+	for _, Benchmark := range bs {
 		for _, procs := range cpuList {
 			runtime.GOMAXPROCS(procs)
 			b := &B{
@@ -304,11 +327,8 @@
 				},
 				benchmark: Benchmark,
 			}
-			benchName := Benchmark.Name
-			if procs != 1 {
-				benchName = fmt.Sprintf("%s-%d", Benchmark.Name, procs)
-			}
-			fmt.Printf("%s\t", benchName)
+			benchName := benchmarkName(Benchmark.Name, procs)
+			fmt.Printf("%-*s\t", maxlen, benchName)
 			r := b.run()
 			if b.failed {
 				// The output could be very long here, but probably isn't.
diff --git a/third_party/gofrontend/libgo/go/testing/example.go b/third_party/gofrontend/libgo/go/testing/example.go
index f5762e4..30baf27 100644
--- a/third_party/gofrontend/libgo/go/testing/example.go
+++ b/third_party/gofrontend/libgo/go/testing/example.go
@@ -43,7 +43,7 @@
 
 func runExample(eg InternalExample) (ok bool) {
 	if *chatty {
-		fmt.Printf("=== RUN: %s\n", eg.Name)
+		fmt.Printf("=== RUN   %s\n", eg.Name)
 	}
 
 	// Capture stdout.
@@ -56,8 +56,8 @@
 	os.Stdout = w
 	outC := make(chan string)
 	go func() {
-		buf := new(bytes.Buffer)
-		_, err := io.Copy(buf, r)
+		var buf bytes.Buffer
+		_, err := io.Copy(&buf, r)
 		r.Close()
 		if err != nil {
 			fmt.Fprintf(os.Stderr, "testing: copying pipe: %v\n", err)
diff --git a/third_party/gofrontend/libgo/go/testing/iotest/logger.go b/third_party/gofrontend/libgo/go/testing/iotest/logger.go
index 1475d9b..0aec15c 100644
--- a/third_party/gofrontend/libgo/go/testing/iotest/logger.go
+++ b/third_party/gofrontend/libgo/go/testing/iotest/logger.go
@@ -48,7 +48,7 @@
 
 // NewReadLogger returns a reader that behaves like r except
 // that it logs (using log.Print) each read to standard error,
-// printing the prefix and the hexadecimal data written.
+// printing the prefix and the hexadecimal data read.
 func NewReadLogger(prefix string, r io.Reader) io.Reader {
 	return &readLogger{prefix, r}
 }
diff --git a/third_party/gofrontend/libgo/go/testing/quick/quick.go b/third_party/gofrontend/libgo/go/testing/quick/quick.go
index 909c65f..13c56cd 100644
--- a/third_party/gofrontend/libgo/go/testing/quick/quick.go
+++ b/third_party/gofrontend/libgo/go/testing/quick/quick.go
@@ -102,12 +102,16 @@
 			v.SetMapIndex(key, value)
 		}
 	case reflect.Ptr:
-		elem, ok := Value(concrete.Elem(), rand)
-		if !ok {
-			return reflect.Value{}, false
+		if rand.Intn(complexSize) == 0 {
+			v.Set(reflect.Zero(concrete)) // Generate nil pointer.
+		} else {
+			elem, ok := Value(concrete.Elem(), rand)
+			if !ok {
+				return reflect.Value{}, false
+			}
+			v.Set(reflect.New(concrete.Elem()))
+			v.Elem().Set(elem)
 		}
-		v.Set(reflect.New(concrete.Elem()))
-		v.Elem().Set(elem)
 	case reflect.Slice:
 		numElems := rand.Intn(complexSize)
 		v.Set(reflect.MakeSlice(concrete, numElems, numElems))
@@ -118,6 +122,14 @@
 			}
 			v.Index(i).Set(elem)
 		}
+	case reflect.Array:
+		for i := 0; i < v.Len(); i++ {
+			elem, ok := Value(concrete.Elem(), rand)
+			if !ok {
+				return reflect.Value{}, false
+			}
+			v.Index(i).Set(elem)
+		}
 	case reflect.String:
 		numChars := rand.Intn(complexSize)
 		codePoints := make([]rune, numChars)
@@ -153,7 +165,7 @@
 	Rand *rand.Rand
 	// If non-nil, the Values function generates a slice of arbitrary
 	// reflect.Values that are congruent with the arguments to the function
-	// being tested. Otherwise, the top-level Values function is used
+	// being tested. Otherwise, the top-level Value function is used
 	// to generate them.
 	Values func([]reflect.Value, *rand.Rand)
 }
@@ -237,7 +249,7 @@
 	}
 
 	if fType.NumOut() != 1 {
-		err = SetupError("function returns more than one value.")
+		err = SetupError("function does not return one value")
 		return
 	}
 	if fType.Out(0).Kind() != reflect.Bool {
diff --git a/third_party/gofrontend/libgo/go/testing/quick/quick_test.go b/third_party/gofrontend/libgo/go/testing/quick/quick_test.go
index e925ba6..c79f30e 100644
--- a/third_party/gofrontend/libgo/go/testing/quick/quick_test.go
+++ b/third_party/gofrontend/libgo/go/testing/quick/quick_test.go
@@ -10,6 +10,12 @@
 	"testing"
 )
 
+func fArray(a [4]byte) [4]byte { return a }
+
+type TestArrayAlias [4]byte
+
+func fArrayAlias(a TestArrayAlias) TestArrayAlias { return a }
+
 func fBool(a bool) bool { return a }
 
 type TestBoolAlias bool
@@ -76,6 +82,18 @@
 
 func fMapAlias(a TestMapAlias) TestMapAlias { return a }
 
+func fPtr(a *int) *int {
+	if a == nil {
+		return nil
+	}
+	b := *a
+	return &b
+}
+
+type TestPtrAlias *int
+
+func fPtrAlias(a TestPtrAlias) TestPtrAlias { return a }
+
 func fSlice(a []byte) []byte { return a }
 
 type TestSliceAlias []byte
@@ -135,15 +153,6 @@
 
 func fUintptrAlias(a TestUintptrAlias) TestUintptrAlias { return a }
 
-func fIntptr(a *int) *int {
-	b := *a
-	return &b
-}
-
-type TestIntptrAlias *int
-
-func fIntptrAlias(a TestIntptrAlias) TestIntptrAlias { return a }
-
 func reportError(property string, err error, t *testing.T) {
 	if err != nil {
 		t.Errorf("%s: %s", property, err)
@@ -151,6 +160,8 @@
 }
 
 func TestCheckEqual(t *testing.T) {
+	reportError("fArray", CheckEqual(fArray, fArray, nil), t)
+	reportError("fArrayAlias", CheckEqual(fArrayAlias, fArrayAlias, nil), t)
 	reportError("fBool", CheckEqual(fBool, fBool, nil), t)
 	reportError("fBoolAlias", CheckEqual(fBoolAlias, fBoolAlias, nil), t)
 	reportError("fFloat32", CheckEqual(fFloat32, fFloat32, nil), t)
@@ -175,6 +186,8 @@
 	reportError("fInt32Alias", CheckEqual(fInt32Alias, fInt32Alias, nil), t)
 	reportError("fMap", CheckEqual(fMap, fMap, nil), t)
 	reportError("fMapAlias", CheckEqual(fMapAlias, fMapAlias, nil), t)
+	reportError("fPtr", CheckEqual(fPtr, fPtr, nil), t)
+	reportError("fPtrAlias", CheckEqual(fPtrAlias, fPtrAlias, nil), t)
 	reportError("fSlice", CheckEqual(fSlice, fSlice, nil), t)
 	reportError("fSliceAlias", CheckEqual(fSliceAlias, fSliceAlias, nil), t)
 	reportError("fString", CheckEqual(fString, fString, nil), t)
@@ -193,8 +206,6 @@
 	reportError("fUintAlias", CheckEqual(fUintAlias, fUintAlias, nil), t)
 	reportError("fUintptr", CheckEqual(fUintptr, fUintptr, nil), t)
 	reportError("fUintptrAlias", CheckEqual(fUintptrAlias, fUintptrAlias, nil), t)
-	reportError("fIntptr", CheckEqual(fIntptr, fIntptr, nil), t)
-	reportError("fIntptrAlias", CheckEqual(fIntptrAlias, fIntptrAlias, nil), t)
 }
 
 // This tests that ArbitraryValue is working by checking that all the arbitrary
@@ -247,3 +258,17 @@
 		t.Errorf("#3 Error was not a SetupError: %s", err)
 	}
 }
+
+// The following test didn't terminate because nil pointers were not
+// generated.
+// Issue 8818.
+func TestNilPointers(t *testing.T) {
+	type Recursive struct {
+		Next *Recursive
+	}
+
+	f := func(rec Recursive) bool {
+		return true
+	}
+	Check(f, nil)
+}
diff --git a/third_party/gofrontend/libgo/go/testing/testing.go b/third_party/gofrontend/libgo/go/testing/testing.go
index e54a3b8..9ec3869 100644
--- a/third_party/gofrontend/libgo/go/testing/testing.go
+++ b/third_party/gofrontend/libgo/go/testing/testing.go
@@ -34,7 +34,7 @@
 // its -bench flag is provided. Benchmarks are run sequentially.
 //
 // For a description of the testing flags, see
-// http://golang.org/cmd/go/#hdr-Description_of_testing_flags.
+// https://golang.org/cmd/go/#hdr-Description_of_testing_flags.
 //
 // A sample benchmark function looks like this:
 //     func BenchmarkHello(b *testing.B) {
@@ -44,7 +44,7 @@
 //     }
 //
 // The benchmark function must run the target code b.N times.
-// During benchark execution, b.N is adjusted until the benchmark function lasts
+// During benchmark execution, b.N is adjusted until the benchmark function lasts
 // long enough to be timed reliably.  The output
 //     BenchmarkHello    10000000    282 ns/op
 // means that the loop ran 10000000 times at a speed of 282 ns per loop.
@@ -130,13 +130,17 @@
 // then the generated test will call TestMain(m) instead of running the tests
 // directly. TestMain runs in the main goroutine and can do whatever setup
 // and teardown is necessary around a call to m.Run. It should then call
-// os.Exit with the result of m.Run.
+// os.Exit with the result of m.Run. When TestMain is called, flag.Parse has
+// not been run. If TestMain depends on command-line flags, including those
+// of the testing package, it should call flag.Parse explicitly.
 //
-// The minimal implementation of TestMain is:
+// A simple implementation of TestMain is:
 //
-//	func TestMain(m *testing.M) { os.Exit(m.Run()) }
+//	func TestMain(m *testing.M) {
+//		flag.Parse()
+//		os.Exit(m.Run())
+//	}
 //
-// In effect, that is the implementation used when no TestMain is explicitly defined.
 package testing
 
 import (
@@ -168,6 +172,7 @@
 
 	// Report as tests are run; default is silent for success.
 	chatty           = flag.Bool("test.v", false, "verbose: print additional output")
+	count            = flag.Uint("test.count", 1, "run tests and benchmarks `n` times")
 	coverProfile     = flag.String("test.coverprofile", "", "write a coverage profile to the named file after execution")
 	match            = flag.String("test.run", "", "regular expression to select tests and examples to run")
 	memProfile       = flag.String("test.memprofile", "", "write a memory profile to the named file after execution")
@@ -175,6 +180,7 @@
 	cpuProfile       = flag.String("test.cpuprofile", "", "write a cpu profile to the named file during execution")
 	blockProfile     = flag.String("test.blockprofile", "", "write a goroutine blocking profile to the named file after execution")
 	blockProfileRate = flag.Int("test.blockprofilerate", 1, "if >= 0, calls runtime.SetBlockProfileRate()")
+	traceFile        = flag.String("test.trace", "", "write an execution trace to the named file after execution")
 	timeout          = flag.Duration("test.timeout", 0, "if positive, sets an aggregate time limit for all tests")
 	cpuListStr       = flag.String("test.cpu", "", "comma-separated list of number of CPUs to use for each test")
 	parallel         = flag.Int("test.parallel", runtime.GOMAXPROCS(0), "maximum test parallelism")
@@ -337,13 +343,15 @@
 }
 
 // Log formats its arguments using default formatting, analogous to Println,
-// and records the text in the error log. The text will be printed only if
-// the test fails or the -test.v flag is set.
+// and records the text in the error log. For tests, the text will be printed only if
+// the test fails or the -test.v flag is set. For benchmarks, the text is always
+// printed to avoid having performance depend on the value of the -test.v flag.
 func (c *common) Log(args ...interface{}) { c.log(fmt.Sprintln(args...)) }
 
 // Logf formats its arguments according to the format, analogous to Printf,
-// and records the text in the error log. The text will be printed only if
-// the test fails or the -test.v flag is set.
+// and records the text in the error log. For tests, the text will be printed only if
+// the test fails or the -test.v flag is set. For benchmarks, the text is always
+// printed to avoid having performance depend on the value of the -test.v flag.
 func (c *common) Logf(format string, args ...interface{}) { c.log(fmt.Sprintf(format, args...)) }
 
 // Error is equivalent to Log followed by Fail.
@@ -538,9 +546,6 @@
 				continue
 			}
 			testName := tests[i].Name
-			if procs != 1 {
-				testName = fmt.Sprintf("%s-%d", tests[i].Name, procs)
-			}
 			t := &T{
 				common: common{
 					signal: make(chan interface{}),
@@ -550,7 +555,7 @@
 			}
 			t.self = t
 			if *chatty {
-				fmt.Printf("=== RUN %s\n", t.name)
+				fmt.Printf("=== RUN   %s\n", t.name)
 			}
 			go tRunner(t, &tests[i])
 			out := (<-t.signal).(*T)
@@ -600,6 +605,22 @@
 		}
 		// Could save f so after can call f.Close; not worth the effort.
 	}
+	if *traceFile != "" {
+		f, err := os.Create(toOutputDir(*traceFile))
+		if err != nil {
+			fmt.Fprintf(os.Stderr, "testing: %s", err)
+			return
+		}
+		/*
+			if err := trace.Start(f); err != nil {
+				fmt.Fprintf(os.Stderr, "testing: can't start tracing: %s", err)
+				f.Close()
+				return
+			}
+		*/
+		_ = f
+		// Could save f so after can call f.Close; not worth the effort.
+	}
 	if *blockProfile != "" && *blockProfileRate >= 0 {
 		runtime.SetBlockProfileRate(*blockProfileRate)
 	}
@@ -614,6 +635,11 @@
 	if *cpuProfile != "" {
 		pprof.StopCPUProfile() // flushes profile to disk
 	}
+	if *traceFile != "" {
+		/*
+			trace.Stop() // flushes trace to disk
+		*/
+	}
 	if *memProfile != "" {
 		f, err := os.Create(toOutputDir(*memProfile))
 		if err != nil {
@@ -701,9 +727,13 @@
 			fmt.Fprintf(os.Stderr, "testing: invalid value %q for -test.cpu\n", val)
 			os.Exit(1)
 		}
-		cpuList = append(cpuList, cpu)
+		for i := uint(0); i < *count; i++ {
+			cpuList = append(cpuList, cpu)
+		}
 	}
 	if cpuList == nil {
-		cpuList = append(cpuList, runtime.GOMAXPROCS(-1))
+		for i := uint(0); i < *count; i++ {
+			cpuList = append(cpuList, runtime.GOMAXPROCS(-1))
+		}
 	}
 }
diff --git a/third_party/gofrontend/libgo/go/text/scanner/example_test.go b/third_party/gofrontend/libgo/go/text/scanner/example_test.go
new file mode 100644
index 0000000..f8b51b7
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/text/scanner/example_test.go
@@ -0,0 +1,40 @@
+// 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 ignore
+
+package scanner_test
+
+import (
+	"fmt"
+	"strings"
+	"text/scanner"
+)
+
+func Example() {
+	const src = `
+	// This is scanned code.
+	if a > 10 {
+		someParsable = text
+	}`
+	var s scanner.Scanner
+	s.Init(strings.NewReader(src))
+	var tok rune
+	for tok != scanner.EOF {
+		tok = s.Scan()
+		fmt.Println("At position", s.Pos(), ":", s.TokenText())
+	}
+
+	// Output:
+	// At position 3:4 : if
+	// At position 3:6 : a
+	// At position 3:8 : >
+	// At position 3:11 : 10
+	// At position 3:13 : {
+	// At position 4:15 : someParsable
+	// At position 4:17 : =
+	// At position 4:22 : text
+	// At position 5:3 : }
+	// At position 5:3 :
+}
diff --git a/third_party/gofrontend/libgo/go/text/scanner/scanner.go b/third_party/gofrontend/libgo/go/text/scanner/scanner.go
index 5199ee4..3ab01ed 100644
--- a/third_party/gofrontend/libgo/go/text/scanner/scanner.go
+++ b/third_party/gofrontend/libgo/go/text/scanner/scanner.go
@@ -12,17 +12,6 @@
 // literals as defined by the Go language specification.  It may be
 // customized to recognize only a subset of those literals and to recognize
 // different identifier and white space characters.
-//
-// Basic usage pattern:
-//
-//	var s scanner.Scanner
-//	s.Init(src)
-//	tok := s.Scan()
-//	for tok != scanner.EOF {
-//		// do something with tok
-//		tok = s.Scan()
-//	}
-//
 package scanner
 
 import (
@@ -43,7 +32,7 @@
 	Column   int    // column number, starting at 1 (character count per line)
 }
 
-// IsValid returns true if the position is valid.
+// IsValid reports whether the position is valid.
 func (pos *Position) IsValid() bool { return pos.Line > 0 }
 
 func (pos Position) String() string {
@@ -208,7 +197,7 @@
 	s.tokPos = -1
 
 	// initialize one character look-ahead
-	s.ch = -1 // no char read yet
+	s.ch = -2 // no char read yet, not EOF
 
 	// initialize public fields
 	s.Error = nil
@@ -314,7 +303,9 @@
 	s.tokPos = -1 // don't collect token text
 	s.Line = 0    // invalidate token position
 	ch := s.Peek()
-	s.ch = s.next()
+	if ch != EOF {
+		s.ch = s.next()
+	}
 	return ch
 }
 
@@ -322,7 +313,7 @@
 // the scanner. It returns EOF if the scanner's position is at the last
 // character of the source.
 func (s *Scanner) Peek() rune {
-	if s.ch < 0 {
+	if s.ch == -2 {
 		// this code is only run for the very first character
 		s.ch = s.next()
 		if s.ch == '\uFEFF' {
@@ -597,6 +588,8 @@
 		}
 	default:
 		switch ch {
+		case EOF:
+			break
 		case '"':
 			if s.Mode&ScanStrings != 0 {
 				s.scanString('"')
diff --git a/third_party/gofrontend/libgo/go/text/scanner/scanner_test.go b/third_party/gofrontend/libgo/go/text/scanner/scanner_test.go
index 702fac2..798bed7 100644
--- a/third_party/gofrontend/libgo/go/text/scanner/scanner_test.go
+++ b/third_party/gofrontend/libgo/go/text/scanner/scanner_test.go
@@ -616,3 +616,52 @@
 		t.Errorf("%d errors", s.ErrorCount)
 	}
 }
+
+type countReader int
+
+func (r *countReader) Read([]byte) (int, error) {
+	*r++
+	return 0, io.EOF
+}
+
+func TestNextEOFHandling(t *testing.T) {
+	var r countReader
+
+	// corner case: empty source
+	s := new(Scanner).Init(&r)
+
+	tok := s.Next()
+	if tok != EOF {
+		t.Error("1) EOF not reported")
+	}
+
+	tok = s.Peek()
+	if tok != EOF {
+		t.Error("2) EOF not reported")
+	}
+
+	if r != 1 {
+		t.Errorf("scanner called Read %d times, not once", r)
+	}
+}
+
+func TestScanEOFHandling(t *testing.T) {
+	var r countReader
+
+	// corner case: empty source
+	s := new(Scanner).Init(&r)
+
+	tok := s.Scan()
+	if tok != EOF {
+		t.Error("1) EOF not reported")
+	}
+
+	tok = s.Peek()
+	if tok != EOF {
+		t.Error("2) EOF not reported")
+	}
+
+	if r != 1 {
+		t.Errorf("scanner called Read %d times, not once", r)
+	}
+}
diff --git a/third_party/gofrontend/libgo/go/text/template/doc.go b/third_party/gofrontend/libgo/go/text/template/doc.go
index 223c595..0ce63f6 100644
--- a/third_party/gofrontend/libgo/go/text/template/doc.go
+++ b/third_party/gofrontend/libgo/go/text/template/doc.go
@@ -18,7 +18,7 @@
 The input text for a template is UTF-8-encoded text in any format.
 "Actions"--data evaluations or control structures--are delimited by
 "{{" and "}}"; all text outside actions is copied to the output unchanged.
-Actions may not span newlines, although comments can.
+Except for raw strings, actions may not span newlines, although comments can.
 
 Once parsed, a template may be executed safely in parallel.
 
@@ -106,7 +106,7 @@
 
 	- A boolean, string, character, integer, floating-point, imaginary
 	  or complex constant in Go syntax. These behave like Go's untyped
-	  constants, although raw strings may not span newlines.
+	  constants.
 	- The keyword nil, representing an untyped Go nil.
 	- The character '.' (period):
 		.
diff --git a/third_party/gofrontend/libgo/go/text/template/exec.go b/third_party/gofrontend/libgo/go/text/template/exec.go
index b00e10c..daba788 100644
--- a/third_party/gofrontend/libgo/go/text/template/exec.go
+++ b/third_party/gofrontend/libgo/go/text/template/exec.go
@@ -113,7 +113,10 @@
 // the output writer.
 // A template may be executed safely in parallel.
 func (t *Template) ExecuteTemplate(wr io.Writer, name string, data interface{}) error {
-	tmpl := t.tmpl[name]
+	var tmpl *Template
+	if t.common != nil {
+		tmpl = t.tmpl[name]
+	}
 	if tmpl == nil {
 		return fmt.Errorf("template: no template %q associated with template %q", name, t.name)
 	}
@@ -134,28 +137,38 @@
 		wr:   wr,
 		vars: []variable{{"$", value}},
 	}
-	t.init()
 	if t.Tree == nil || t.Root == nil {
-		var b bytes.Buffer
-		for name, tmpl := range t.tmpl {
-			if tmpl.Tree == nil || tmpl.Root == nil {
-				continue
-			}
-			if b.Len() > 0 {
-				b.WriteString(", ")
-			}
-			fmt.Fprintf(&b, "%q", name)
-		}
-		var s string
-		if b.Len() > 0 {
-			s = "; defined templates are: " + b.String()
-		}
-		state.errorf("%q is an incomplete or empty template%s", t.Name(), s)
+		state.errorf("%q is an incomplete or empty template%s", t.Name(), t.DefinedTemplates())
 	}
 	state.walk(value, t.Root)
 	return
 }
 
+// DefinedTemplates returns a string listing the defined templates,
+// prefixed by the string "defined templates are: ". If there are none,
+// it returns the empty string. For generating an error message here
+// and in html/template.
+func (t *Template) DefinedTemplates() string {
+	if t.common == nil {
+		return ""
+	}
+	var b bytes.Buffer
+	for name, tmpl := range t.tmpl {
+		if tmpl.Tree == nil || tmpl.Root == nil {
+			continue
+		}
+		if b.Len() > 0 {
+			b.WriteString(", ")
+		}
+		fmt.Fprintf(&b, "%q", name)
+	}
+	var s string
+	if b.Len() > 0 {
+		s = "; defined templates are: " + b.String()
+	}
+	return s
+}
+
 // Walk functions step through the major pieces of the template structure,
 // generating output as they go.
 func (s *state) walk(dot reflect.Value, node parse.Node) {
@@ -418,11 +431,14 @@
 
 func (s *state) evalChainNode(dot reflect.Value, chain *parse.ChainNode, args []parse.Node, final reflect.Value) reflect.Value {
 	s.at(chain)
-	// (pipe).Field1.Field2 has pipe as .Node, fields as .Field. Eval the pipeline, then the fields.
-	pipe := s.evalArg(dot, nil, chain.Node)
 	if len(chain.Field) == 0 {
 		s.errorf("internal error: no fields in evalChainNode")
 	}
+	if chain.Node.Type() == parse.NodeNil {
+		s.errorf("indirection through explicit nil in %s", chain)
+	}
+	// (pipe).Field1.Field2 has pipe as .Node, fields as .Field. Eval the pipeline, then the fields.
+	pipe := s.evalArg(dot, nil, chain.Node)
 	return s.evalFieldChain(dot, pipe, chain, chain.Field, args, final)
 }
 
@@ -505,7 +521,18 @@
 			if hasArgs {
 				s.errorf("%s is not a method but has arguments", fieldName)
 			}
-			return receiver.MapIndex(nameVal)
+			result := receiver.MapIndex(nameVal)
+			if !result.IsValid() {
+				switch s.tmpl.option.missingKey {
+				case mapInvalid:
+					// Just use the invalid value.
+				case mapZeroValue:
+					result = reflect.Zero(receiver.Type().Elem())
+				case mapError:
+					s.errorf("map has no entry for key %q", fieldName)
+				}
+			}
+			return result
 		}
 	}
 	s.errorf("can't evaluate field %s in type %s", fieldName, typ)
@@ -560,7 +587,15 @@
 	if final.IsValid() {
 		t := typ.In(typ.NumIn() - 1)
 		if typ.IsVariadic() {
-			t = t.Elem()
+			if numIn-1 < numFixed {
+				// The added final argument corresponds to a fixed parameter of the function.
+				// Validate against the type of the actual parameter.
+				t = typ.In(numIn - 1)
+			} else {
+				// The added final argument corresponds to the variadic part.
+				// Validate against the type of the elements of the variadic slice.
+				t = t.Elem()
+			}
 		}
 		argv[i] = s.validateType(final, t)
 	}
@@ -635,7 +670,7 @@
 	case *parse.PipeNode:
 		return s.validateType(s.evalPipeline(dot, arg), typ)
 	case *parse.IdentifierNode:
-		return s.evalFunction(dot, arg, arg, nil, zero)
+		return s.validateType(s.evalFunction(dot, arg, arg, nil, zero), typ)
 	case *parse.ChainNode:
 		return s.validateType(s.evalChainNode(dot, arg, nil, zero), typ)
 	}
diff --git a/third_party/gofrontend/libgo/go/text/template/exec_test.go b/third_party/gofrontend/libgo/go/text/template/exec_test.go
index 69c213e..ba0e434 100644
--- a/third_party/gofrontend/libgo/go/text/template/exec_test.go
+++ b/third_party/gofrontend/libgo/go/text/template/exec_test.go
@@ -527,6 +527,24 @@
 	{"bug12XE", "{{printf `%T` 0XEE}}", "int", T{}, true},
 	// Chained nodes did not work as arguments. Issue 8473.
 	{"bug13", "{{print (.Copy).I}}", "17", tVal, true},
+	// Didn't protect against nil or literal values in field chains.
+	{"bug14a", "{{(nil).True}}", "", tVal, false},
+	{"bug14b", "{{$x := nil}}{{$x.anything}}", "", tVal, false},
+	{"bug14c", `{{$x := (1.0)}}{{$y := ("hello")}}{{$x.anything}}{{$y.true}}`, "", tVal, false},
+	// Didn't call validateType on function results. Issue 10800.
+	{"bug15", "{{valueString returnInt}}", "", tVal, false},
+	// Variadic function corner cases. Issue 10946.
+	{"bug16a", "{{true|printf}}", "", tVal, false},
+	{"bug16b", "{{1|printf}}", "", tVal, false},
+	{"bug16c", "{{1.1|printf}}", "", tVal, false},
+	{"bug16d", "{{'x'|printf}}", "", tVal, false},
+	{"bug16e", "{{0i|printf}}", "", tVal, false},
+	{"bug16f", "{{true|twoArgs \"xxx\"}}", "", tVal, false},
+	{"bug16g", "{{\"aaa\" |twoArgs \"bbb\"}}", "twoArgs=bbbaaa", tVal, true},
+	{"bug16h", "{{1|oneArg}}", "", tVal, false},
+	{"bug16i", "{{\"aaa\"|oneArg}}", "oneArg=aaa", tVal, true},
+	{"bug16j", "{{1+2i|printf \"%v\"}}", "(1+2i)", tVal, true},
+	{"bug16k", "{{\"aaa\"|printf }}", "aaa", tVal, true},
 }
 
 func zeroArgs() string {
@@ -537,6 +555,10 @@
 	return "oneArg=" + a
 }
 
+func twoArgs(a, b string) string {
+	return "twoArgs=" + a + b
+}
+
 func dddArg(a int, b ...string) string {
 	return fmt.Sprintln(a, b)
 }
@@ -566,6 +588,11 @@
 	return "value is ignored"
 }
 
+// returnInt returns an int
+func returnInt() int {
+	return 7
+}
+
 func add(args ...int) int {
 	sum := 0
 	for _, x := range args {
@@ -607,7 +634,9 @@
 		"makemap":     makemap,
 		"mapOfThree":  mapOfThree,
 		"oneArg":      oneArg,
+		"returnInt":   returnInt,
 		"stringer":    stringer,
+		"twoArgs":     twoArgs,
 		"typeOf":      typeOf,
 		"valueString": valueString,
 		"vfunc":       vfunc,
@@ -853,7 +882,13 @@
 
 func TestExecuteOnNewTemplate(t *testing.T) {
 	// This is issue 3872.
-	_ = New("Name").Templates()
+	New("Name").Templates()
+	// This is issue 11379.
+	new(Template).Templates()
+	new(Template).Parse("")
+	new(Template).New("abc").Parse("")
+	new(Template).Execute(nil, nil)                // returns an error (but does not crash)
+	new(Template).ExecuteTemplate(nil, "XXX", nil) // returns an error (but does not crash)
 }
 
 const testTemplates = `{{define "one"}}one{{end}}{{define "two"}}two{{end}}`
@@ -1042,3 +1077,67 @@
 		}
 	}
 }
+
+func TestMissingMapKey(t *testing.T) {
+	data := map[string]int{
+		"x": 99,
+	}
+	tmpl, err := New("t1").Parse("{{.x}} {{.y}}")
+	if err != nil {
+		t.Fatal(err)
+	}
+	var b bytes.Buffer
+	// By default, just get "<no value>"
+	err = tmpl.Execute(&b, data)
+	if err != nil {
+		t.Fatal(err)
+	}
+	want := "99 <no value>"
+	got := b.String()
+	if got != want {
+		t.Errorf("got %q; expected %q", got, want)
+	}
+	// Same if we set the option explicitly to the default.
+	tmpl.Option("missingkey=default")
+	b.Reset()
+	err = tmpl.Execute(&b, data)
+	if err != nil {
+		t.Fatal("default:", err)
+	}
+	want = "99 <no value>"
+	got = b.String()
+	if got != want {
+		t.Errorf("got %q; expected %q", got, want)
+	}
+	// Next we ask for a zero value
+	tmpl.Option("missingkey=zero")
+	b.Reset()
+	err = tmpl.Execute(&b, data)
+	if err != nil {
+		t.Fatal("zero:", err)
+	}
+	want = "99 0"
+	got = b.String()
+	if got != want {
+		t.Errorf("got %q; expected %q", got, want)
+	}
+	// Now we ask for an error.
+	tmpl.Option("missingkey=error")
+	err = tmpl.Execute(&b, data)
+	if err == nil {
+		t.Errorf("expected error; got none")
+	}
+}
+
+// Test that the error message for multiline unterminated string
+// refers to the line number of the opening quote.
+func TestUnterminatedStringError(t *testing.T) {
+	_, err := New("X").Parse("hello\n\n{{`unterminated\n\n\n\n}}\n some more\n\n")
+	if err == nil {
+		t.Fatal("expected error")
+	}
+	str := err.Error()
+	if !strings.Contains(str, "X:3: unexpected unterminated raw quoted strin") {
+		t.Fatalf("unexpected error: %s", str)
+	}
+}
diff --git a/third_party/gofrontend/libgo/go/text/template/funcs.go b/third_party/gofrontend/libgo/go/text/template/funcs.go
index 39ee5ed..ccd0dfc 100644
--- a/third_party/gofrontend/libgo/go/text/template/funcs.go
+++ b/third_party/gofrontend/libgo/go/text/template/funcs.go
@@ -92,6 +92,8 @@
 // findFunction looks for a function in the template, and global map.
 func findFunction(name string, tmpl *Template) (reflect.Value, bool) {
 	if tmpl != nil && tmpl.common != nil {
+		tmpl.muFuncs.RLock()
+		defer tmpl.muFuncs.RUnlock()
 		if fn := tmpl.execFuncs[name]; fn.IsValid() {
 			return fn, true
 		}
@@ -590,7 +592,7 @@
 			a, ok := printableValue(reflect.ValueOf(arg))
 			if ok {
 				args[i] = a
-			} // else left fmt do its thing
+			} // else let fmt do its thing
 		}
 		s = fmt.Sprint(args...)
 	}
diff --git a/third_party/gofrontend/libgo/go/text/template/helper.go b/third_party/gofrontend/libgo/go/text/template/helper.go
index 3636fb5..787ca62 100644
--- a/third_party/gofrontend/libgo/go/text/template/helper.go
+++ b/third_party/gofrontend/libgo/go/text/template/helper.go
@@ -26,8 +26,8 @@
 }
 
 // ParseFiles creates a new Template and parses the template definitions from
-// the named files. The returned template's name will have the (base) name and
-// (parsed) contents of the first file. There must be at least one file.
+// the named files. The returned template's name will have the base name and
+// parsed contents of the first file. There must be at least one file.
 // If an error occurs, parsing stops and the returned *Template is nil.
 func ParseFiles(filenames ...string) (*Template, error) {
 	return parseFiles(nil, filenames...)
@@ -36,7 +36,13 @@
 // ParseFiles parses the named files and associates the resulting templates with
 // t. If an error occurs, parsing stops and the returned template is nil;
 // otherwise it is t. There must be at least one file.
+// Since the templates created by ParseFiles are named by the base
+// names of the argument files, t should usually have the name of one
+// of the (base) names of the files. If it does not, depending on t's
+// contents before calling ParseFiles, t.Execute may fail. In that
+// case use t.ExecuteTemplate to execute a valid template.
 func (t *Template) ParseFiles(filenames ...string) (*Template, error) {
+	t.init()
 	return parseFiles(t, filenames...)
 }
 
@@ -92,6 +98,7 @@
 // equivalent to calling t.ParseFiles with the list of files matched by the
 // pattern.
 func (t *Template) ParseGlob(pattern string) (*Template, error) {
+	t.init()
 	return parseGlob(t, pattern)
 }
 
diff --git a/third_party/gofrontend/libgo/go/text/template/multi_test.go b/third_party/gofrontend/libgo/go/text/template/multi_test.go
index e4e8048..ea01875 100644
--- a/third_party/gofrontend/libgo/go/text/template/multi_test.go
+++ b/third_party/gofrontend/libgo/go/text/template/multi_test.go
@@ -290,3 +290,76 @@
 		t.Fatalf("expected redefinition error; got %v", err)
 	}
 }
+
+// Issue 10879
+func TestEmptyTemplateCloneCrash(t *testing.T) {
+	t1 := New("base")
+	t1.Clone() // used to panic
+}
+
+// Issue 10910, 10926
+func TestTemplateLookUp(t *testing.T) {
+	t1 := New("foo")
+	if t1.Lookup("foo") != nil {
+		t.Error("Lookup returned non-nil value for undefined template foo")
+	}
+	t1.New("bar")
+	if t1.Lookup("bar") != nil {
+		t.Error("Lookup returned non-nil value for undefined template bar")
+	}
+	t1.Parse(`{{define "foo"}}test{{end}}`)
+	if t1.Lookup("foo") == nil {
+		t.Error("Lookup returned nil value for defined template")
+	}
+}
+
+func TestNew(t *testing.T) {
+	// template with same name already exists
+	t1, _ := New("test").Parse(`{{define "test"}}foo{{end}}`)
+	t2 := t1.New("test")
+
+	if t1.common != t2.common {
+		t.Errorf("t1 & t2 didn't share common struct; got %v != %v", t1.common, t2.common)
+	}
+	if t1.Tree == nil {
+		t.Error("defined template got nil Tree")
+	}
+	if t2.Tree != nil {
+		t.Error("undefined template got non-nil Tree")
+	}
+
+	containsT1 := false
+	for _, tmpl := range t1.Templates() {
+		if tmpl == t2 {
+			t.Error("Templates included undefined template")
+		}
+		if tmpl == t1 {
+			containsT1 = true
+		}
+	}
+	if !containsT1 {
+		t.Error("Templates didn't include defined template")
+	}
+}
+
+func TestParse(t *testing.T) {
+	// In multiple calls to Parse with the same receiver template, only one call
+	// can contain text other than space, comments, and template definitions
+	var err error
+	t1 := New("test")
+	if _, err := t1.Parse(`{{define "test"}}{{end}}`); err != nil {
+		t.Fatalf("parsing test: %s", err)
+	}
+	if _, err := t1.Parse(`{{define "test"}}{{/* this is a comment */}}{{end}}`); err != nil {
+		t.Fatalf("parsing test: %s", err)
+	}
+	if _, err := t1.Parse(`{{define "test"}}foo{{end}}`); err != nil {
+		t.Fatalf("parsing test: %s", err)
+	}
+	if _, err = t1.Parse(`{{define "test"}}foo{{end}}`); err == nil {
+		t.Fatal("no error from redefining a template")
+	}
+	if !strings.Contains(err.Error(), "redefinition") {
+		t.Fatalf("expected redefinition error; got %v", err)
+	}
+}
diff --git a/third_party/gofrontend/libgo/go/text/template/option.go b/third_party/gofrontend/libgo/go/text/template/option.go
new file mode 100644
index 0000000..addce2d
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/text/template/option.go
@@ -0,0 +1,74 @@
+// 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.
+
+// This file contains the code to handle template options.
+
+package template
+
+import "strings"
+
+// missingKeyAction defines how to respond to indexing a map with a key that is not present.
+type missingKeyAction int
+
+const (
+	mapInvalid   missingKeyAction = iota // Return an invalid reflect.Value.
+	mapZeroValue                         // Return the zero value for the map element.
+	mapError                             // Error out
+)
+
+type option struct {
+	missingKey missingKeyAction
+}
+
+// Option sets options for the template. Options are described by
+// strings, either a simple string or "key=value". There can be at
+// most one equals sign in an option string. If the option string
+// is unrecognized or otherwise invalid, Option panics.
+//
+// Known options:
+//
+// missingkey: Control the behavior during execution if a map is
+// indexed with a key that is not present in the map.
+//	"missingkey=default" or "missingkey=invalid"
+//		The default behavior: Do nothing and continue execution.
+//		If printed, the result of the index operation is the string
+//		"<no value>".
+//	"missingkey=zero"
+//		The operation returns the zero value for the map type's element.
+//	"missingkey=error"
+//		Execution stops immediately with an error.
+//
+func (t *Template) Option(opt ...string) *Template {
+	t.init()
+	for _, s := range opt {
+		t.setOption(s)
+	}
+	return t
+}
+
+func (t *Template) setOption(opt string) {
+	if opt == "" {
+		panic("empty option string")
+	}
+	elems := strings.Split(opt, "=")
+	switch len(elems) {
+	case 2:
+		// key=value
+		switch elems[0] {
+		case "missingkey":
+			switch elems[1] {
+			case "invalid", "default":
+				t.option.missingKey = mapInvalid
+				return
+			case "zero":
+				t.option.missingKey = mapZeroValue
+				return
+			case "error":
+				t.option.missingKey = mapError
+				return
+			}
+		}
+	}
+	panic("unrecognized option: " + opt)
+}
diff --git a/third_party/gofrontend/libgo/go/text/template/parse/lex.go b/third_party/gofrontend/libgo/go/text/template/parse/lex.go
index 1674aaf..8f9fe1d 100644
--- a/third_party/gofrontend/libgo/go/text/template/parse/lex.go
+++ b/third_party/gofrontend/libgo/go/text/template/parse/lex.go
@@ -167,12 +167,20 @@
 }
 
 // nextItem returns the next item from the input.
+// Called by the parser, not in the lexing goroutine.
 func (l *lexer) nextItem() item {
 	item := <-l.items
 	l.lastPos = item.pos
 	return item
 }
 
+// drain drains the output so the lexing goroutine will exit.
+// Called by the parser, not in the lexing goroutine.
+func (l *lexer) drain() {
+	for range l.items {
+	}
+}
+
 // lex creates a new scanner for the input string.
 func lex(name, input, left, right string) *lexer {
 	if left == "" {
@@ -197,6 +205,7 @@
 	for l.state = lexText; l.state != nil; {
 		l.state = l.state(l)
 	}
+	close(l.items)
 }
 
 // state functions
@@ -313,14 +322,12 @@
 	case r == '(':
 		l.emit(itemLeftParen)
 		l.parenDepth++
-		return lexInsideAction
 	case r == ')':
 		l.emit(itemRightParen)
 		l.parenDepth--
 		if l.parenDepth < 0 {
 			return l.errorf("unexpected right paren %#U", r)
 		}
-		return lexInsideAction
 	case r <= unicode.MaxASCII && unicode.IsPrint(r):
 		l.emit(itemChar)
 		return lexInsideAction
@@ -525,7 +532,7 @@
 Loop:
 	for {
 		switch l.next() {
-		case eof, '\n':
+		case eof:
 			return l.errorf("unterminated raw quoted string")
 		case '`':
 			break Loop
diff --git a/third_party/gofrontend/libgo/go/text/template/parse/lex_test.go b/third_party/gofrontend/libgo/go/text/template/parse/lex_test.go
index d251ccf..be551d8 100644
--- a/third_party/gofrontend/libgo/go/text/template/parse/lex_test.go
+++ b/third_party/gofrontend/libgo/go/text/template/parse/lex_test.go
@@ -58,18 +58,20 @@
 }
 
 var (
-	tEOF      = item{itemEOF, 0, ""}
-	tFor      = item{itemIdentifier, 0, "for"}
-	tLeft     = item{itemLeftDelim, 0, "{{"}
-	tLpar     = item{itemLeftParen, 0, "("}
-	tPipe     = item{itemPipe, 0, "|"}
-	tQuote    = item{itemString, 0, `"abc \n\t\" "`}
-	tRange    = item{itemRange, 0, "range"}
-	tRight    = item{itemRightDelim, 0, "}}"}
-	tRpar     = item{itemRightParen, 0, ")"}
-	tSpace    = item{itemSpace, 0, " "}
-	raw       = "`" + `abc\n\t\" ` + "`"
-	tRawQuote = item{itemRawString, 0, raw}
+	tEOF        = item{itemEOF, 0, ""}
+	tFor        = item{itemIdentifier, 0, "for"}
+	tLeft       = item{itemLeftDelim, 0, "{{"}
+	tLpar       = item{itemLeftParen, 0, "("}
+	tPipe       = item{itemPipe, 0, "|"}
+	tQuote      = item{itemString, 0, `"abc \n\t\" "`}
+	tRange      = item{itemRange, 0, "range"}
+	tRight      = item{itemRightDelim, 0, "}}"}
+	tRpar       = item{itemRightParen, 0, ")"}
+	tSpace      = item{itemSpace, 0, " "}
+	raw         = "`" + `abc\n\t\" ` + "`"
+	rawNL       = "`now is{{\n}}the time`" // Contains newline inside raw quote.
+	tRawQuote   = item{itemRawString, 0, raw}
+	tRawQuoteNL = item{itemRawString, 0, rawNL}
 )
 
 var lexTests = []lexTest{
@@ -104,6 +106,7 @@
 	{"for", `{{for}}`, []item{tLeft, tFor, tRight, tEOF}},
 	{"quote", `{{"abc \n\t\" "}}`, []item{tLeft, tQuote, tRight, tEOF}},
 	{"raw quote", "{{" + raw + "}}", []item{tLeft, tRawQuote, tRight, tEOF}},
+	{"raw quote with newline", "{{" + rawNL + "}}", []item{tLeft, tRawQuoteNL, tRight, tEOF}},
 	{"numbers", "{{1 02 0x14 -7.2i 1e3 +1.2e-4 4.2i 1+2i}}", []item{
 		tLeft,
 		{itemNumber, 0, "1"},
@@ -294,7 +297,7 @@
 		tLeft,
 		{itemError, 0, "unterminated quoted string"},
 	}},
-	{"unclosed raw quote", "{{`xx\n`}}", []item{
+	{"unclosed raw quote", "{{`xx}}", []item{
 		tLeft,
 		{itemError, 0, "unterminated raw quoted string"},
 	}},
@@ -463,3 +466,31 @@
 		}
 	}
 }
+
+// Test that an error shuts down the lexing goroutine.
+func TestShutdown(t *testing.T) {
+	// We need to duplicate template.Parse here to hold on to the lexer.
+	const text = "erroneous{{define}}{{else}}1234"
+	lexer := lex("foo", text, "{{", "}}")
+	_, err := New("root").parseLexer(lexer, text)
+	if err == nil {
+		t.Fatalf("expected error")
+	}
+	// The error should have drained the input. Therefore, the lexer should be shut down.
+	token, ok := <-lexer.items
+	if ok {
+		t.Fatalf("input was not drained; got %v", token)
+	}
+}
+
+// parseLexer is a local version of parse that lets us pass in the lexer instead of building it.
+// We expect an error, so the tree set and funcs list are explicitly nil.
+func (t *Tree) parseLexer(lex *lexer, text string) (tree *Tree, err error) {
+	defer t.recover(&err)
+	t.ParseName = t.Name
+	t.startParse(nil, lex)
+	t.parse(nil)
+	t.add(nil)
+	t.stopParse()
+	return t, nil
+}
diff --git a/third_party/gofrontend/libgo/go/text/template/parse/node.go b/third_party/gofrontend/libgo/go/text/template/parse/node.go
index 55c37f6..55ff46c 100644
--- a/third_party/gofrontend/libgo/go/text/template/parse/node.go
+++ b/third_party/gofrontend/libgo/go/text/template/parse/node.go
@@ -145,7 +145,7 @@
 	NodeType
 	Pos
 	tr   *Tree
-	Line int             // The line number in the input (deprecated; kept for compatibility)
+	Line int             // The line number in the input. Deprecated: Kept for compatibility.
 	Decl []*VariableNode // Variable declarations in lexical order.
 	Cmds []*CommandNode  // The commands in lexical order.
 }
@@ -208,7 +208,7 @@
 	NodeType
 	Pos
 	tr   *Tree
-	Line int       // The line number in the input (deprecated; kept for compatibility)
+	Line int       // The line number in the input. Deprecated: Kept for compatibility.
 	Pipe *PipeNode // The pipeline in the action.
 }
 
@@ -592,6 +592,11 @@
 	} else {
 		f, err := strconv.ParseFloat(text, 64)
 		if err == nil {
+			// If we parsed it as a float but it looks like an integer,
+			// it's a huge number too large to fit in an int. Reject it.
+			if !strings.ContainsAny(text, ".eE") {
+				return nil, fmt.Errorf("integer overflow: %q", text)
+			}
 			n.IsFloat = true
 			n.Float64 = f
 			// If a floating-point extraction succeeded, extract the int if needed.
@@ -696,7 +701,7 @@
 	NodeType
 	Pos
 	tr   *Tree
-	Line int // The line number in the input (deprecated; kept for compatibility)
+	Line int // The line number in the input. Deprecated: Kept for compatibility.
 }
 
 func (t *Tree) newElse(pos Pos, line int) *elseNode {
@@ -724,7 +729,7 @@
 	NodeType
 	Pos
 	tr       *Tree
-	Line     int       // The line number in the input (deprecated; kept for compatibility)
+	Line     int       // The line number in the input. Deprecated: Kept for compatibility.
 	Pipe     *PipeNode // The pipeline to be evaluated.
 	List     *ListNode // What to execute if the value is non-empty.
 	ElseList *ListNode // What to execute if the value is empty (nil if absent).
@@ -809,7 +814,7 @@
 	NodeType
 	Pos
 	tr   *Tree
-	Line int       // The line number in the input (deprecated; kept for compatibility)
+	Line int       // The line number in the input. Deprecated: Kept for compatibility.
 	Name string    // The name of the template (unquoted).
 	Pipe *PipeNode // The command to evaluate as dot for the template.
 }
diff --git a/third_party/gofrontend/libgo/go/text/template/parse/parse.go b/third_party/gofrontend/libgo/go/text/template/parse/parse.go
index af33880..88aacd1 100644
--- a/third_party/gofrontend/libgo/go/text/template/parse/parse.go
+++ b/third_party/gofrontend/libgo/go/text/template/parse/parse.go
@@ -196,6 +196,7 @@
 			panic(e)
 		}
 		if t != nil {
+			t.lex.drain()
 			t.stopParse()
 		}
 		*errp = e.(error)
@@ -288,11 +289,12 @@
 			}
 			t.backup2(delim)
 		}
-		n := t.textOrAction()
-		if n.Type() == nodeEnd {
+		switch n := t.textOrAction(); n.Type() {
+		case nodeEnd, nodeElse:
 			t.errorf("unexpected %s", n)
+		default:
+			t.Root.append(n)
 		}
-		t.Root.append(n)
 	}
 	return nil
 }
@@ -411,9 +413,8 @@
 	for {
 		switch token := t.nextNonSpace(); token.typ {
 		case itemRightDelim, itemRightParen:
-			if len(pipe.Cmds) == 0 {
-				t.errorf("missing value for %s", context)
-			}
+			// At this point, the pipeline is complete
+			t.checkPipeline(pipe, context)
 			if token.typ == itemRightParen {
 				t.backup()
 			}
@@ -428,6 +429,21 @@
 	}
 }
 
+func (t *Tree) checkPipeline(pipe *PipeNode, context string) {
+	// Reject empty pipelines
+	if len(pipe.Cmds) == 0 {
+		t.errorf("missing value for %s", context)
+	}
+	// Only the first command of a pipeline can start with a non executable operand
+	for i, c := range pipe.Cmds[1:] {
+		switch c.Args[0].Type() {
+		case NodeBool, NodeDot, NodeNil, NodeNumber, NodeString:
+			// With A|B|C, pipeline stage 2 is B
+			t.errorf("non executable command in pipeline stage %d", i+2)
+		}
+	}
+}
+
 func (t *Tree) parseControl(allowElseIf bool, context string) (pos Pos, line int, pipe *PipeNode, list, elseList *ListNode) {
 	defer t.popVars(len(t.vars))
 	line = t.lex.lineNumber()
@@ -553,7 +569,7 @@
 			t.backup()
 		case itemPipe:
 		default:
-			t.errorf("unexpected %s in operand; missing space?", token)
+			t.errorf("unexpected %s in operand", token)
 		}
 		break
 	}
@@ -581,12 +597,15 @@
 		// Compatibility with original API: If the term is of type NodeField
 		// or NodeVariable, just put more fields on the original.
 		// Otherwise, keep the Chain node.
-		// TODO: Switch to Chains always when we can.
+		// Obvious parsing errors involving literal values are detected here.
+		// More complex error cases will have to be handled at execution time.
 		switch node.Type() {
 		case NodeField:
 			node = t.newField(chain.Position(), chain.String())
 		case NodeVariable:
 			node = t.newVariable(chain.Position(), chain.String())
+		case NodeBool, NodeString, NodeNumber, NodeNil, NodeDot:
+			t.errorf("unexpected . after term %q", node.String())
 		default:
 			node = chain
 		}
diff --git a/third_party/gofrontend/libgo/go/text/template/parse/parse_test.go b/third_party/gofrontend/libgo/go/text/template/parse/parse_test.go
index 4a504fa..200d50c 100644
--- a/third_party/gofrontend/libgo/go/text/template/parse/parse_test.go
+++ b/third_party/gofrontend/libgo/go/text/template/parse/parse_test.go
@@ -69,6 +69,7 @@
 	{text: "1+2."},
 	{text: "'x"},
 	{text: "'xx'"},
+	{text: "'433937734937734969526500969526500'"}, // Integer too large - issue 10634.
 	// Issue 8622 - 0xe parsed as floating point. Very embarrassing.
 	{"0xef", true, true, true, false, 0xef, 0xef, 0xef, 0},
 }
@@ -230,6 +231,9 @@
 	// Errors.
 	{"unclosed action", "hello{{range", hasError, ""},
 	{"unmatched end", "{{end}}", hasError, ""},
+	{"unmatched else", "{{else}}", hasError, ""},
+	{"unmatched else after if", "{{if .X}}hello{{end}}{{else}}", hasError, ""},
+	{"multiple else", "{{if .X}}1{{else}}2{{else}}3{{end}}", hasError, ""},
 	{"missing end", "hello{{range .x}}", hasError, ""},
 	{"missing end after else", "hello{{range .x}}{{else}}", hasError, ""},
 	{"undefined function", "hello{{undefined}}", hasError, ""},
@@ -257,6 +261,22 @@
 	{"bug1a", "{{$x:=.}}{{$x!2}}", hasError, ""},                     // ! is just illegal here.
 	{"bug1b", "{{$x:=.}}{{$x+2}}", hasError, ""},                     // $x+2 should not parse as ($x) (+2).
 	{"bug1c", "{{$x:=.}}{{$x +2}}", noError, "{{$x := .}}{{$x +2}}"}, // It's OK with a space.
+	// dot following a literal value
+	{"dot after integer", "{{1.E}}", hasError, ""},
+	{"dot after float", "{{0.1.E}}", hasError, ""},
+	{"dot after boolean", "{{true.E}}", hasError, ""},
+	{"dot after char", "{{'a'.any}}", hasError, ""},
+	{"dot after string", `{{"hello".guys}}`, hasError, ""},
+	{"dot after dot", "{{..E}}", hasError, ""},
+	{"dot after nil", "{{nil.E}}", hasError, ""},
+	// Wrong pipeline
+	{"wrong pipeline dot", "{{12|.}}", hasError, ""},
+	{"wrong pipeline number", "{{.|12|printf}}", hasError, ""},
+	{"wrong pipeline string", "{{.|printf|\"error\"}}", hasError, ""},
+	{"wrong pipeline char", "{{12|printf|'e'}}", hasError, ""},
+	{"wrong pipeline boolean", "{{.|true}}", hasError, ""},
+	{"wrong pipeline nil", "{{'c'|nil}}", hasError, ""},
+	{"empty pipeline", `{{printf "%d" ( ) }}`, hasError, ""},
 }
 
 var builtins = map[string]interface{}{
@@ -375,7 +395,7 @@
 		hasError, `unexpected ")"`},
 	{"space",
 		"{{`x`3}}",
-		hasError, `missing space?`},
+		hasError, `in operand`},
 	{"idchar",
 		"{{a#}}",
 		hasError, `'#'`},
@@ -407,6 +427,15 @@
 	{"undefvar",
 		"{{$a}}",
 		hasError, `undefined variable`},
+	{"wrongdot",
+		"{{true.any}}",
+		hasError, `unexpected . after term`},
+	{"wrongpipeline",
+		"{{12|false}}",
+		hasError, `non executable command in pipeline`},
+	{"emptypipeline",
+		`{{ ( ) }}`,
+		hasError, `missing value for parenthesized pipeline`},
 }
 
 func TestErrors(t *testing.T) {
diff --git a/third_party/gofrontend/libgo/go/text/template/template.go b/third_party/gofrontend/libgo/go/text/template/template.go
index 249d0cb..3e80982 100644
--- a/third_party/gofrontend/libgo/go/text/template/template.go
+++ b/third_party/gofrontend/libgo/go/text/template/template.go
@@ -7,15 +7,18 @@
 import (
 	"fmt"
 	"reflect"
+	"sync"
 	"text/template/parse"
 )
 
 // common holds the information shared by related templates.
 type common struct {
-	tmpl map[string]*Template
+	tmpl   map[string]*Template // Map from name to defined templates.
+	option option
 	// We use two maps, one for parsing and one for execution.
 	// This separation makes the API cleaner since it doesn't
 	// expose reflection to the client.
+	muFuncs    sync.RWMutex // protects parseFuncs and execFuncs
 	parseFuncs FuncMap
 	execFuncs  map[string]reflect.Value
 }
@@ -31,11 +34,13 @@
 	rightDelim string
 }
 
-// New allocates a new template with the given name.
+// New allocates a new, undefined template with the given name.
 func New(name string) *Template {
-	return &Template{
+	t := &Template{
 		name: name,
 	}
+	t.init()
+	return t
 }
 
 // Name returns the name of the template.
@@ -43,25 +48,28 @@
 	return t.name
 }
 
-// New allocates a new template associated with the given one and with the same
+// New allocates a new, undefined template associated with the given one and with the same
 // delimiters. The association, which is transitive, allows one template to
 // invoke another with a {{template}} action.
 func (t *Template) New(name string) *Template {
 	t.init()
-	return &Template{
+	nt := &Template{
 		name:       name,
 		common:     t.common,
 		leftDelim:  t.leftDelim,
 		rightDelim: t.rightDelim,
 	}
+	return nt
 }
 
+// init guarantees that t has a valid common structure.
 func (t *Template) init() {
 	if t.common == nil {
-		t.common = new(common)
-		t.tmpl = make(map[string]*Template)
-		t.parseFuncs = make(FuncMap)
-		t.execFuncs = make(map[string]reflect.Value)
+		c := new(common)
+		c.tmpl = make(map[string]*Template)
+		c.parseFuncs = make(FuncMap)
+		c.execFuncs = make(map[string]reflect.Value)
+		t.common = c
 	}
 }
 
@@ -74,15 +82,20 @@
 func (t *Template) Clone() (*Template, error) {
 	nt := t.copy(nil)
 	nt.init()
-	nt.tmpl[t.name] = nt
+	if t.common == nil {
+		return nt, nil
+	}
 	for k, v := range t.tmpl {
-		if k == t.name { // Already installed.
+		if k == t.name {
+			nt.tmpl[t.name] = nt
 			continue
 		}
 		// The associated templates share nt's common structure.
 		tmpl := v.copy(nt.common)
 		nt.tmpl[k] = tmpl
 	}
+	t.muFuncs.RLock()
+	defer t.muFuncs.RUnlock()
 	for k, v := range t.parseFuncs {
 		nt.parseFuncs[k] = v
 	}
@@ -102,20 +115,27 @@
 	return nt
 }
 
-// AddParseTree creates a new template with the name and parse tree
-// and associates it with t.
+// AddParseTree adds parse tree for template with given name and associates it with t.
+// If the template does not already exist, it will create a new one.
+// It is an error to reuse a name except to overwrite an empty template.
 func (t *Template) AddParseTree(name string, tree *parse.Tree) (*Template, error) {
-	if t.common != nil && t.tmpl[name] != nil {
-		return nil, fmt.Errorf("template: redefinition of template %q", name)
+	t.init()
+	// If the name is the name of this template, overwrite this template.
+	// The associate method checks it's not a redefinition.
+	nt := t
+	if name != t.name {
+		nt = t.New(name)
 	}
-	nt := t.New(name)
-	nt.Tree = tree
-	t.tmpl[name] = nt
+	// Even if nt == t, we need to install it in the common.tmpl map.
+	if replace, err := t.associate(nt, tree); err != nil {
+		return nil, err
+	} else if replace {
+		nt.Tree = tree
+	}
 	return nt, nil
 }
 
-// Templates returns a slice of the templates associated with t, including t
-// itself.
+// Templates returns a slice of defined templates associated with t.
 func (t *Template) Templates() []*Template {
 	if t.common == nil {
 		return nil
@@ -134,6 +154,7 @@
 // corresponding default: {{ or }}.
 // The return value is the template, so calls can be chained.
 func (t *Template) Delims(left, right string) *Template {
+	t.init()
 	t.leftDelim = left
 	t.rightDelim = right
 	return t
@@ -145,13 +166,15 @@
 // value is the template, so calls can be chained.
 func (t *Template) Funcs(funcMap FuncMap) *Template {
 	t.init()
+	t.muFuncs.Lock()
+	defer t.muFuncs.Unlock()
 	addValueFuncs(t.execFuncs, funcMap)
 	addFuncs(t.parseFuncs, funcMap)
 	return t
 }
 
-// Lookup returns the template with the given name that is associated with t,
-// or nil if there is no such template.
+// Lookup returns the template with the given name that is associated with t.
+// It returns nil if there is no such template or the template has no definition.
 func (t *Template) Lookup(name string) *Template {
 	if t.common == nil {
 		return nil
@@ -159,7 +182,7 @@
 	return t.tmpl[name]
 }
 
-// Parse parses a string into a template. Nested template definitions will be
+// Parse defines the template by parsing the text. Nested template definitions will be
 // associated with the top-level template t. Parse may be called multiple times
 // to parse definitions of templates to associate with t. It is an error if a
 // resulting template is non-empty (contains content other than template
@@ -168,26 +191,17 @@
 // can contain text other than space, comments, and template definitions.)
 func (t *Template) Parse(text string) (*Template, error) {
 	t.init()
+	t.muFuncs.RLock()
 	trees, err := parse.Parse(t.name, text, t.leftDelim, t.rightDelim, t.parseFuncs, builtins)
+	t.muFuncs.RUnlock()
 	if err != nil {
 		return nil, err
 	}
 	// Add the newly parsed trees, including the one for t, into our common structure.
 	for name, tree := range trees {
-		// If the name we parsed is the name of this template, overwrite this template.
-		// The associate method checks it's not a redefinition.
-		tmpl := t
-		if name != t.name {
-			tmpl = t.New(name)
-		}
-		// Even if t == tmpl, we need to install it in the common.tmpl map.
-		if replace, err := t.associate(tmpl, tree); err != nil {
+		if _, err := t.AddParseTree(name, tree); err != nil {
 			return nil, err
-		} else if replace {
-			tmpl.Tree = tree
 		}
-		tmpl.leftDelim = t.leftDelim
-		tmpl.rightDelim = t.rightDelim
 	}
 	return t, nil
 }
diff --git a/third_party/gofrontend/libgo/go/time/example_test.go b/third_party/gofrontend/libgo/go/time/example_test.go
index a37e8b8..f76fdcd 100644
--- a/third_party/gofrontend/libgo/go/time/example_test.go
+++ b/third_party/gofrontend/libgo/go/time/example_test.go
@@ -58,17 +58,127 @@
 }
 
 func ExampleTime_Format() {
-	// layout shows by example how the reference time should be represented.
-	const layout = "Jan 2, 2006 at 3:04pm (MST)"
-	t := time.Date(2009, time.November, 10, 15, 0, 0, 0, time.Local)
-	fmt.Println(t.Format(layout))
-	fmt.Println(t.UTC().Format(layout))
+	// Parse a time value from a string in the standard Unix format.
+	t, err := time.Parse(time.UnixDate, "Sat Mar  7 11:06:39 PST 2015")
+	if err != nil { // Always check errors even if they should not happen.
+		panic(err)
+	}
+
+	// time.Time's Stringer method is useful without any format.
+	fmt.Println("default format:", t)
+
+	// Predefined constants in the package implement common layouts.
+	fmt.Println("Unix format:", t.Format(time.UnixDate))
+
+	// The time zone attached to the time value affects its output.
+	fmt.Println("Same, in UTC:", t.UTC().Format(time.UnixDate))
+
+	// The rest of this function demonstrates the properties of the
+	// layout string used in the format.
+
+	// The layout string used by the Parse function and Format method
+	// shows by example how the reference time should be represented.
+	// We stress that one must show how the reference time is formatted,
+	// not a time of the user's choosing. Thus each layout string is a
+	// representation of the time stamp,
+	//	Jan 2 15:04:05 2006 MST
+	// An easy way to remember this value is that it holds, when presented
+	// in this order, the values (lined up with the elements above):
+	//	  1 2  3  4  5    6  -7
+	// There are some wrinkles illustrated below.
+
+	// Most uses of Format and Parse use constant layout strings such as
+	// the ones defined in this package, but the interface is flexible,
+	// as these examples show.
+
+	// Define a helper function to make the examples' output look nice.
+	do := func(name, layout, want string) {
+		got := t.Format(layout)
+		if want != got {
+			fmt.Printf("error: for %q got %q; expected %q\n", layout, got, want)
+			return
+		}
+		fmt.Printf("%-15s %q gives %q\n", name, layout, got)
+	}
+
+	// Print a header in our output.
+	fmt.Printf("\nFormats:\n\n")
+
+	// A simple starter example.
+	do("Basic", "Mon Jan 2 15:04:05 MST 2006", "Sat Mar 7 11:06:39 PST 2015")
+
+	// For fixed-width printing of values, such as the date, that may be one or
+	// two characters (7 vs. 07), use an _ instead of a space in the layout string.
+	// Here we print just the day, which is 2 in our layout string and 7 in our
+	// value.
+	do("No pad", "<2>", "<7>")
+
+	// An underscore represents a zero pad, if required.
+	do("Spaces", "<_2>", "< 7>")
+
+	// Similarly, a 0 indicates zero padding.
+	do("Zeros", "<02>", "<07>")
+
+	// If the value is already the right width, padding is not used.
+	// For instance, the second (05 in the reference time) in our value is 39,
+	// so it doesn't need padding, but the minutes (04, 06) does.
+	do("Suppressed pad", "04:05", "06:39")
+
+	// The predefined constant Unix uses an underscore to pad the day.
+	// Compare with our simple starter example.
+	do("Unix", time.UnixDate, "Sat Mar  7 11:06:39 PST 2015")
+
+	// The hour of the reference time is 15, or 3PM. The layout can express
+	// it either way, and since our value is the morning we should see it as
+	// an AM time. We show both in one format string. Lower case too.
+	do("AM/PM", "3PM==3pm==15h", "11AM==11am==11h")
+
+	// When parsing, if the seconds value is followed by a decimal point
+	// and some digits, that is taken as a fraction of a second even if
+	// the layout string does not represent the fractional second.
+	// Here we add a fractional second to our time value used above.
+	t, err = time.Parse(time.UnixDate, "Sat Mar  7 11:06:39.1234 PST 2015")
+	if err != nil {
+		panic(err)
+	}
+	// It does not appear in the output if the layout string does not contain
+	// a representation of the fractional second.
+	do("No fraction", time.UnixDate, "Sat Mar  7 11:06:39 PST 2015")
+
+	// Fractional seconds can be printed by adding a run of 0s or 9s after
+	// a decimal point in the seconds value in the layout string.
+	// If the layout digits are 0s, the fractional second is of the specified
+	// width. Note that the output has a trailing zero.
+	do("0s for fraction", "15:04:05.00000", "11:06:39.12340")
+
+	// If the fraction in the layout is 9s, trailing zeros are dropped.
+	do("9s for fraction", "15:04:05.99999999", "11:06:39.1234")
+
 	// Output:
-	// Nov 10, 2009 at 3:00pm (PST)
-	// Nov 10, 2009 at 11:00pm (UTC)
+	// default format: 2015-03-07 11:06:39 -0800 PST
+	// Unix format: Sat Mar  7 11:06:39 PST 2015
+	// Same, in UTC: Sat Mar  7 19:06:39 UTC 2015
+	//
+	// Formats:
+	//
+	// Basic           "Mon Jan 2 15:04:05 MST 2006" gives "Sat Mar 7 11:06:39 PST 2015"
+	// No pad          "<2>" gives "<7>"
+	// Spaces          "<_2>" gives "< 7>"
+	// Zeros           "<02>" gives "<07>"
+	// Suppressed pad  "04:05" gives "06:39"
+	// Unix            "Mon Jan _2 15:04:05 MST 2006" gives "Sat Mar  7 11:06:39 PST 2015"
+	// AM/PM           "3PM==3pm==15h" gives "11AM==11am==11h"
+	// No fraction     "Mon Jan _2 15:04:05 MST 2006" gives "Sat Mar  7 11:06:39 PST 2015"
+	// 0s for fraction "15:04:05.00000" gives "11:06:39.12340"
+	// 9s for fraction "15:04:05.99999999" gives "11:06:39.1234"
+
 }
 
 func ExampleParse() {
+	// See the example for time.Format for a thorough description of how
+	// to define the layout string to parse a time.Time value; Parse and
+	// Format use the same model to describe their input and output.
+
 	// longForm shows by example how the reference time would be represented in
 	// the desired layout.
 	const longForm = "Jan 2, 2006 at 3:04pm (MST)"
diff --git a/third_party/gofrontend/libgo/go/time/format.go b/third_party/gofrontend/libgo/go/time/format.go
index 04e79f3..873d3ff 100644
--- a/third_party/gofrontend/libgo/go/time/format.go
+++ b/third_party/gofrontend/libgo/go/time/format.go
@@ -39,6 +39,9 @@
 // offset for the UTC zone.  Thus:
 //	Z0700  Z or ±hhmm
 //	Z07:00 Z or ±hh:mm
+//
+// The executable example for time.Format demonstrates the working
+// of the layout string in detail and is a good reference.
 const (
 	ANSIC       = "Mon Jan _2 15:04:05 2006"
 	UnixDate    = "Mon Jan _2 15:04:05 MST 2006"
@@ -288,7 +291,7 @@
 	"December",
 }
 
-// match returns true if s1 and s2 match ignoring case.
+// match reports whether s1 and s2 match ignoring case.
 // It is assumed s1 and s2 are the same length.
 func match(s1, s2 string) bool {
 	for i := 0; i < len(s1); i++ {
@@ -315,36 +318,34 @@
 	return -1, val, errBad
 }
 
-// appendUint appends the decimal form of x to b and returns the result.
-// If x is a single-digit number and pad != 0, appendUint inserts the pad byte
-// before the digit.
+// appendInt appends the decimal form of x to b and returns the result.
+// If the decimal form (excluding sign) is shorter than width, the result is padded with leading 0's.
 // Duplicates functionality in strconv, but avoids dependency.
-func appendUint(b []byte, x uint, pad byte) []byte {
-	if x < 10 {
-		if pad != 0 {
-			b = append(b, pad)
-		}
-		return append(b, byte('0'+x))
-	}
-	if x < 100 {
-		b = append(b, byte('0'+x/10))
-		b = append(b, byte('0'+x%10))
-		return b
+func appendInt(b []byte, x int, width int) []byte {
+	u := uint(x)
+	if x < 0 {
+		b = append(b, '-')
+		u = uint(-x)
 	}
 
-	var buf [32]byte
-	n := len(buf)
-	if x == 0 {
-		return append(b, '0')
+	// Assemble decimal in reverse order.
+	var buf [20]byte
+	i := len(buf)
+	for u >= 10 {
+		i--
+		q := u / 10
+		buf[i] = byte('0' + u - q*10)
+		u = q
 	}
-	for x >= 10 {
-		n--
-		buf[n] = byte(x%10 + '0')
-		x /= 10
+	i--
+	buf[i] = byte('0' + u)
+
+	// Add 0-padding.
+	for w := len(buf) - i; w < width; w++ {
+		b = append(b, '0')
 	}
-	n--
-	buf[n] = byte(x + '0')
-	return append(b, buf[n:]...)
+
+	return append(b, buf[i:]...)
 }
 
 // Never printed, just needs to be non-nil for return by atoi.
@@ -407,11 +408,32 @@
 // would be displayed if it were the value; it serves as an example of the
 // desired output. The same display rules will then be applied to the time
 // value.
+//
+// A fractional second is represented by adding a period and zeros
+// to the end of the seconds section of layout string, as in "15:04:05.000"
+// to format a time stamp with millisecond precision.
+//
 // Predefined layouts ANSIC, UnixDate, RFC3339 and others describe standard
 // and convenient representations of the reference time. For more information
 // about the formats and the definition of the reference time, see the
 // documentation for ANSIC and the other constants defined by this package.
 func (t Time) Format(layout string) string {
+	const bufSize = 64
+	var b []byte
+	max := len(layout) + 10
+	if max < bufSize {
+		var buf [bufSize]byte
+		b = buf[:0]
+	} else {
+		b = make([]byte, 0, max)
+	}
+	b = t.AppendFormat(b, layout)
+	return string(b)
+}
+
+// AppendFormat is like Format but appends the textual
+// representation to b and returns the extended buffer.
+func (t Time) AppendFormat(b []byte, layout string) []byte {
 	var (
 		name, offset, abs = t.locabs()
 
@@ -421,16 +443,7 @@
 		hour  int = -1
 		min   int
 		sec   int
-
-		b   []byte
-		buf [64]byte
 	)
-	max := len(layout) + 10
-	if max <= len(buf) {
-		b = buf[:0]
-	} else {
-		b = make([]byte, 0, max)
-	}
 	// Each iteration generates one std value.
 	for layout != "" {
 		prefix, std, suffix := nextStdChunk(layout)
@@ -458,75 +471,56 @@
 			if y < 0 {
 				y = -y
 			}
-			b = appendUint(b, uint(y%100), '0')
+			b = appendInt(b, y%100, 2)
 		case stdLongYear:
-			// Pad year to at least 4 digits.
-			y := year
-			switch {
-			case year <= -1000:
-				b = append(b, '-')
-				y = -y
-			case year <= -100:
-				b = append(b, "-0"...)
-				y = -y
-			case year <= -10:
-				b = append(b, "-00"...)
-				y = -y
-			case year < 0:
-				b = append(b, "-000"...)
-				y = -y
-			case year < 10:
-				b = append(b, "000"...)
-			case year < 100:
-				b = append(b, "00"...)
-			case year < 1000:
-				b = append(b, '0')
-			}
-			b = appendUint(b, uint(y), 0)
+			b = appendInt(b, year, 4)
 		case stdMonth:
 			b = append(b, month.String()[:3]...)
 		case stdLongMonth:
 			m := month.String()
 			b = append(b, m...)
 		case stdNumMonth:
-			b = appendUint(b, uint(month), 0)
+			b = appendInt(b, int(month), 0)
 		case stdZeroMonth:
-			b = appendUint(b, uint(month), '0')
+			b = appendInt(b, int(month), 2)
 		case stdWeekDay:
 			b = append(b, absWeekday(abs).String()[:3]...)
 		case stdLongWeekDay:
 			s := absWeekday(abs).String()
 			b = append(b, s...)
 		case stdDay:
-			b = appendUint(b, uint(day), 0)
+			b = appendInt(b, day, 0)
 		case stdUnderDay:
-			b = appendUint(b, uint(day), ' ')
+			if day < 10 {
+				b = append(b, ' ')
+			}
+			b = appendInt(b, day, 0)
 		case stdZeroDay:
-			b = appendUint(b, uint(day), '0')
+			b = appendInt(b, day, 2)
 		case stdHour:
-			b = appendUint(b, uint(hour), '0')
+			b = appendInt(b, hour, 2)
 		case stdHour12:
 			// Noon is 12PM, midnight is 12AM.
 			hr := hour % 12
 			if hr == 0 {
 				hr = 12
 			}
-			b = appendUint(b, uint(hr), 0)
+			b = appendInt(b, hr, 0)
 		case stdZeroHour12:
 			// Noon is 12PM, midnight is 12AM.
 			hr := hour % 12
 			if hr == 0 {
 				hr = 12
 			}
-			b = appendUint(b, uint(hr), '0')
+			b = appendInt(b, hr, 2)
 		case stdMinute:
-			b = appendUint(b, uint(min), 0)
+			b = appendInt(b, min, 0)
 		case stdZeroMinute:
-			b = appendUint(b, uint(min), '0')
+			b = appendInt(b, min, 2)
 		case stdSecond:
-			b = appendUint(b, uint(sec), 0)
+			b = appendInt(b, sec, 2)
 		case stdZeroSecond:
-			b = appendUint(b, uint(sec), '0')
+			b = appendInt(b, sec, 2)
 		case stdPM:
 			if hour >= 12 {
 				b = append(b, "PM"...)
@@ -555,18 +549,18 @@
 			} else {
 				b = append(b, '+')
 			}
-			b = appendUint(b, uint(zone/60), '0')
+			b = appendInt(b, zone/60, 2)
 			if std == stdISO8601ColonTZ || std == stdNumColonTZ || std == stdISO8601ColonSecondsTZ || std == stdNumColonSecondsTZ {
 				b = append(b, ':')
 			}
-			b = appendUint(b, uint(zone%60), '0')
+			b = appendInt(b, zone%60, 2)
 
 			// append seconds if appropriate
 			if std == stdISO8601SecondsTZ || std == stdNumSecondsTz || std == stdNumColonSecondsTZ || std == stdISO8601ColonSecondsTZ {
 				if std == stdNumColonSecondsTZ || std == stdISO8601ColonSecondsTZ {
 					b = append(b, ':')
 				}
-				b = appendUint(b, uint(absoffset%60), '0')
+				b = appendInt(b, absoffset%60, 2)
 			}
 
 		case stdTZ:
@@ -583,13 +577,13 @@
 			} else {
 				b = append(b, '+')
 			}
-			b = appendUint(b, uint(zone/60), '0')
-			b = appendUint(b, uint(zone%60), '0')
+			b = appendInt(b, zone/60, 2)
+			b = appendInt(b, zone%60, 2)
 		case stdFracSecond0, stdFracSecond9:
 			b = formatNano(b, uint(t.Nanosecond()), std>>stdArgShift, std&stdMask == stdFracSecond9)
 		}
 	}
-	return string(b)
+	return b
 }
 
 var errBad = errors.New("bad value for field") // placeholder not passed to user
@@ -620,8 +614,7 @@
 		quote(e.Value) + e.Message
 }
 
-// isDigit returns true if s[i] is a decimal digit, false if not or
-// if s[i] is out of range.
+// isDigit reports whether s[i] is in range and is a decimal digit.
 func isDigit(s string, i int) bool {
 	if len(s) <= i {
 		return false
@@ -681,10 +674,13 @@
 // would be interpreted if it were the value; it serves as an example of
 // the input format. The same interpretation will then be made to the
 // input string.
+//
 // Predefined layouts ANSIC, UnixDate, RFC3339 and others describe standard
 // and convenient representations of the reference time. For more information
 // about the formats and the definition of the reference time, see the
 // documentation for ANSIC and the other constants defined by this package.
+// Also, the executable example for time.Format demonstrates the working
+// of the layout string in detail and is a good reference.
 //
 // Elements omitted from the value are assumed to be zero or, when
 // zero is impossible, one, so parsing "3:04pm" returns the time
@@ -1131,24 +1127,28 @@
 		if c < '0' || c > '9' {
 			break
 		}
-		if x >= (1<<63-10)/10 {
+		if x > (1<<63-1)/10 {
 			// overflow
 			return 0, "", errLeadingInt
 		}
 		x = x*10 + int64(c) - '0'
+		if x < 0 {
+			// overflow
+			return 0, "", errLeadingInt
+		}
 	}
 	return x, s[i:], nil
 }
 
-var unitMap = map[string]float64{
-	"ns": float64(Nanosecond),
-	"us": float64(Microsecond),
-	"µs": float64(Microsecond), // U+00B5 = micro symbol
-	"μs": float64(Microsecond), // U+03BC = Greek letter mu
-	"ms": float64(Millisecond),
-	"s":  float64(Second),
-	"m":  float64(Minute),
-	"h":  float64(Hour),
+var unitMap = map[string]int64{
+	"ns": int64(Nanosecond),
+	"us": int64(Microsecond),
+	"µs": int64(Microsecond), // U+00B5 = micro symbol
+	"μs": int64(Microsecond), // U+03BC = Greek letter mu
+	"ms": int64(Millisecond),
+	"s":  int64(Second),
+	"m":  int64(Minute),
+	"h":  int64(Hour),
 }
 
 // ParseDuration parses a duration string.
@@ -1159,7 +1159,7 @@
 func ParseDuration(s string) (Duration, error) {
 	// [-+]?([0-9]*(\.[0-9]*)?[a-z]+)+
 	orig := s
-	f := float64(0)
+	var d int64
 	neg := false
 
 	// Consume [-+]?
@@ -1178,22 +1178,23 @@
 		return 0, errors.New("time: invalid duration " + orig)
 	}
 	for s != "" {
-		g := float64(0) // this element of the sequence
+		var (
+			v, f  int64       // integers before, after decimal point
+			scale float64 = 1 // value = v + f/scale
+		)
 
-		var x int64
 		var err error
 
 		// The next character must be [0-9.]
-		if !(s[0] == '.' || ('0' <= s[0] && s[0] <= '9')) {
+		if !(s[0] == '.' || '0' <= s[0] && s[0] <= '9') {
 			return 0, errors.New("time: invalid duration " + orig)
 		}
 		// Consume [0-9]*
 		pl := len(s)
-		x, s, err = leadingInt(s)
+		v, s, err = leadingInt(s)
 		if err != nil {
 			return 0, errors.New("time: invalid duration " + orig)
 		}
-		g = float64(x)
 		pre := pl != len(s) // whether we consumed anything before a period
 
 		// Consume (\.[0-9]*)?
@@ -1201,15 +1202,13 @@
 		if s != "" && s[0] == '.' {
 			s = s[1:]
 			pl := len(s)
-			x, s, err = leadingInt(s)
+			f, s, err = leadingInt(s)
 			if err != nil {
 				return 0, errors.New("time: invalid duration " + orig)
 			}
-			scale := 1.0
 			for n := pl - len(s); n > 0; n-- {
 				scale *= 10
 			}
-			g += float64(x) / scale
 			post = pl != len(s)
 		}
 		if !pre && !post {
@@ -1221,7 +1220,7 @@
 		i := 0
 		for ; i < len(s); i++ {
 			c := s[i]
-			if c == '.' || ('0' <= c && c <= '9') {
+			if c == '.' || '0' <= c && c <= '9' {
 				break
 			}
 		}
@@ -1234,15 +1233,29 @@
 		if !ok {
 			return 0, errors.New("time: unknown unit " + u + " in duration " + orig)
 		}
-
-		f += g * unit
+		if v > (1<<63-1)/unit {
+			// overflow
+			return 0, errors.New("time: invalid duration " + orig)
+		}
+		v *= unit
+		if f > 0 {
+			// float64 is needed to be nanosecond accurate for fractions of hours.
+			// v >= 0 && (f*unit/scale) <= 3.6e+12 (ns/h, h is the largest unit)
+			v += int64(float64(f) * (float64(unit) / scale))
+			if v < 0 {
+				// overflow
+				return 0, errors.New("time: invalid duration " + orig)
+			}
+		}
+		d += v
+		if d < 0 {
+			// overflow
+			return 0, errors.New("time: invalid duration " + orig)
+		}
 	}
 
 	if neg {
-		f = -f
+		d = -d
 	}
-	if f < float64(-1<<63) || f > float64(1<<63-1) {
-		return 0, errors.New("time: overflow parsing duration")
-	}
-	return Duration(f), nil
+	return Duration(d), nil
 }
diff --git a/third_party/gofrontend/libgo/go/time/sleep_test.go b/third_party/gofrontend/libgo/go/time/sleep_test.go
index c21eb99..c286bd0 100644
--- a/third_party/gofrontend/libgo/go/time/sleep_test.go
+++ b/third_party/gofrontend/libgo/go/time/sleep_test.go
@@ -8,7 +8,6 @@
 	"errors"
 	"fmt"
 	"runtime"
-	"sort"
 	"strings"
 	"sync"
 	"sync/atomic"
@@ -224,10 +223,11 @@
 func TestAfterQueuing(t *testing.T) {
 	// This test flakes out on some systems,
 	// so we'll try it a few times before declaring it a failure.
-	const attempts = 3
+	const attempts = 5
 	err := errors.New("!=nil")
 	for i := 0; i < attempts && err != nil; i++ {
-		if err = testAfterQueuing(t); err != nil {
+		delta := Duration(20+i*50) * Millisecond
+		if err = testAfterQueuing(t, delta); err != nil {
 			t.Logf("attempt %v failed: %v", i, err)
 		}
 	}
@@ -248,11 +248,7 @@
 	result <- afterResult{slot, <-ac}
 }
 
-func testAfterQueuing(t *testing.T) error {
-	Delta := 100 * Millisecond
-	if testing.Short() {
-		Delta = 20 * Millisecond
-	}
+func testAfterQueuing(t *testing.T, delta Duration) error {
 	// make the result channel buffered because we don't want
 	// to depend on channel queueing semantics that might
 	// possibly change in the future.
@@ -260,18 +256,25 @@
 
 	t0 := Now()
 	for _, slot := range slots {
-		go await(slot, result, After(Duration(slot)*Delta))
+		go await(slot, result, After(Duration(slot)*delta))
 	}
-	sort.Ints(slots)
-	for _, slot := range slots {
+	var order []int
+	var times []Time
+	for range slots {
 		r := <-result
-		if r.slot != slot {
-			return fmt.Errorf("after slot %d, expected %d", r.slot, slot)
+		order = append(order, r.slot)
+		times = append(times, r.t)
+	}
+	for i := range order {
+		if i > 0 && order[i] < order[i-1] {
+			return fmt.Errorf("After calls returned out of order: %v", order)
 		}
-		dt := r.t.Sub(t0)
-		target := Duration(slot) * Delta
-		if dt < target-Delta/2 || dt > target+Delta*10 {
-			return fmt.Errorf("After(%s) arrived at %s, expected [%s,%s]", target, dt, target-Delta/2, target+Delta*10)
+	}
+	for i, t := range times {
+		dt := t.Sub(t0)
+		target := Duration(order[i]) * delta
+		if dt < target-delta/2 || dt > target+delta*10 {
+			return fmt.Errorf("After(%s) arrived at %s, expected [%s,%s]", target, dt, target-delta/2, target+delta*10)
 		}
 	}
 	return nil
@@ -384,6 +387,10 @@
 // Test that a panic while deleting a timer does not leave
 // the timers mutex held, deadlocking a ticker.Stop in a defer.
 func TestIssue5745(t *testing.T) {
+	if runtime.GOOS == "darwin" && runtime.GOARCH == "arm" {
+		t.Skipf("skipping on %s/%s, see issue 10043", runtime.GOOS, runtime.GOARCH)
+	}
+
 	ticker := NewTicker(Hour)
 	defer func() {
 		// would deadlock here before the fix due to
diff --git a/third_party/gofrontend/libgo/go/time/sys_unix.go b/third_party/gofrontend/libgo/go/time/sys_unix.go
index 379e13d..e592415 100644
--- a/third_party/gofrontend/libgo/go/time/sys_unix.go
+++ b/third_party/gofrontend/libgo/go/time/sys_unix.go
@@ -74,3 +74,5 @@
 	}
 	return nil
 }
+
+func isNotExist(err error) bool { return err == syscall.ENOENT }
diff --git a/third_party/gofrontend/libgo/go/time/tick.go b/third_party/gofrontend/libgo/go/time/tick.go
index 1900784..196e8ac 100644
--- a/third_party/gofrontend/libgo/go/time/tick.go
+++ b/third_party/gofrontend/libgo/go/time/tick.go
@@ -47,7 +47,9 @@
 }
 
 // Tick is a convenience wrapper for NewTicker providing access to the ticking
-// channel only.  Useful for clients that have no need to shut down the ticker.
+// channel only. While Tick is useful for clients that have no need to shut down
+// the Ticker, be aware that without a way to shut it down the underlying
+// Ticker cannot be recovered by the garbage collector; it "leaks".
 func Tick(d Duration) <-chan Time {
 	if d <= 0 {
 		return nil
diff --git a/third_party/gofrontend/libgo/go/time/time.go b/third_party/gofrontend/libgo/go/time/time.go
index 0300e84..294cc77 100644
--- a/third_party/gofrontend/libgo/go/time/time.go
+++ b/third_party/gofrontend/libgo/go/time/time.go
@@ -966,6 +966,8 @@
 // Unix returns the local Time corresponding to the given Unix time,
 // sec seconds and nsec nanoseconds since January 1, 1970 UTC.
 // It is valid to pass nsec outside the range [0, 999999999].
+// Not all sec values have a corresponding time value. One such
+// value is 1<<63-1 (the largest int64 value).
 func Unix(sec int64, nsec int64) Time {
 	if nsec < 0 || nsec >= 1e9 {
 		n := nsec / 1e9
diff --git a/third_party/gofrontend/libgo/go/time/time_test.go b/third_party/gofrontend/libgo/go/time/time_test.go
index 7e31dd7..2d16ea5 100644
--- a/third_party/gofrontend/libgo/go/time/time_test.go
+++ b/third_party/gofrontend/libgo/go/time/time_test.go
@@ -830,8 +830,16 @@
 	{"39h9m14.425s", true, 39*Hour + 9*Minute + 14*Second + 425*Millisecond},
 	// large value
 	{"52763797000ns", true, 52763797000 * Nanosecond},
-	// more than 9 digits after decimal point, see http://golang.org/issue/6617
+	// more than 9 digits after decimal point, see https://golang.org/issue/6617
 	{"0.3333333333333333333h", true, 20 * Minute},
+	// 9007199254740993 = 1<<53+1 cannot be stored precisely in a float64
+	{"9007199254740993ns", true, (1<<53 + 1) * Nanosecond},
+	// largest duration that can be represented by int64 in nanoseconds
+	{"9223372036854775807ns", true, (1<<63 - 1) * Nanosecond},
+	{"9223372036854775.807us", true, (1<<63 - 1) * Nanosecond},
+	{"9223372036s854ms775us807ns", true, (1<<63 - 1) * Nanosecond},
+	// large negative value
+	{"-9223372036854775807ns", true, -1<<63 + 1*Nanosecond},
 
 	// errors
 	{"", false, 0},
@@ -842,7 +850,13 @@
 	{"-.", false, 0},
 	{".s", false, 0},
 	{"+.s", false, 0},
-	{"3000000h", false, 0}, // overflow
+	{"3000000h", false, 0},                  // overflow
+	{"9223372036854775808ns", false, 0},     // overflow
+	{"9223372036854775.808us", false, 0},    // overflow
+	{"9223372036854ms775us808ns", false, 0}, // overflow
+	// largest negative value of type int64 in nanoseconds should fail
+	// see https://go-review.googlesource.com/#/c/2461/
+	{"-9223372036854775808ns", false, 0},
 }
 
 func TestParseDuration(t *testing.T) {
@@ -1052,6 +1066,13 @@
 	}
 }
 
+func BenchmarkParseDuration(b *testing.B) {
+	for i := 0; i < b.N; i++ {
+		ParseDuration("9007199254.740993ms")
+		ParseDuration("9007199254740993ns")
+	}
+}
+
 func BenchmarkHour(b *testing.B) {
 	t := Now()
 	for i := 0; i < b.N; i++ {
diff --git a/third_party/gofrontend/libgo/go/time/zoneinfo_ios.go b/third_party/gofrontend/libgo/go/time/zoneinfo_ios.go
new file mode 100644
index 0000000..f09166c
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/time/zoneinfo_ios.go
@@ -0,0 +1,51 @@
+// 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 darwin
+// +build arm arm64
+
+package time
+
+import "syscall"
+
+var zoneFile string
+
+func init() {
+	wd, err := syscall.Getwd()
+	if err != nil {
+		return
+	}
+
+	// The working directory at initialization is the root of the
+	// app bundle: "/private/.../bundlename.app". That's where we
+	// keep zoneinfo.zip.
+	zoneFile = wd + "/zoneinfo.zip"
+}
+
+func forceZipFileForTesting(zipOnly bool) {
+	// On iOS we only have the zip file.
+}
+
+func initTestingZone() {
+	z, err := loadZoneFile(zoneFile, "America/Los_Angeles")
+	if err != nil {
+		panic("cannot load America/Los_Angeles for testing: " + err.Error())
+	}
+	z.name = "Local"
+	localLoc = *z
+}
+
+func initLocal() {
+	// TODO(crawshaw): [NSTimeZone localTimeZone]
+	localLoc = *UTC
+}
+
+func loadLocation(name string) (*Location, error) {
+	z, err := loadZoneFile(zoneFile, name)
+	if err != nil {
+		return nil, err
+	}
+	z.name = name
+	return z, nil
+}
diff --git a/third_party/gofrontend/libgo/go/time/zoneinfo_plan9.go b/third_party/gofrontend/libgo/go/time/zoneinfo_plan9.go
index 4bb0cb3..0694f0a 100644
--- a/third_party/gofrontend/libgo/go/time/zoneinfo_plan9.go
+++ b/third_party/gofrontend/libgo/go/time/zoneinfo_plan9.go
@@ -7,7 +7,6 @@
 package time
 
 import (
-	"errors"
 	"runtime"
 	"syscall"
 )
@@ -148,11 +147,12 @@
 }
 
 func loadLocation(name string) (*Location, error) {
-	if z, err := loadZoneFile(runtime.GOROOT()+"/lib/time/zoneinfo.zip", name); err == nil {
-		z.name = name
-		return z, nil
+	z, err := loadZoneFile(runtime.GOROOT()+"/lib/time/zoneinfo.zip", name)
+	if err != nil {
+		return nil, err
 	}
-	return nil, errors.New("unknown time zone " + name)
+	z.name = name
+	return z, nil
 }
 
 func forceZipFileForTesting(zipOnly bool) {
diff --git a/third_party/gofrontend/libgo/go/time/zoneinfo_unix.go b/third_party/gofrontend/libgo/go/time/zoneinfo_unix.go
index 3fe8e55..5fc669e 100644
--- a/third_party/gofrontend/libgo/go/time/zoneinfo_unix.go
+++ b/third_party/gofrontend/libgo/go/time/zoneinfo_unix.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 darwin dragonfly freebsd linux nacl netbsd openbsd solaris
+// +build darwin,386 darwin,amd64 dragonfly freebsd linux nacl netbsd openbsd solaris
 
 // Parse "zoneinfo" time zone file.
 // This is a fairly standard file format used on OS X, Linux, BSD, Sun, and others.
@@ -70,11 +70,17 @@
 }
 
 func loadLocation(name string) (*Location, error) {
+	var firstErr error
 	for _, zoneDir := range zoneDirs {
 		if z, err := loadZoneFile(zoneDir, name); err == nil {
 			z.name = name
 			return z, nil
+		} else if firstErr == nil && !isNotExist(err) {
+			firstErr = err
 		}
 	}
+	if firstErr != nil {
+		return nil, firstErr
+	}
 	return nil, errors.New("unknown time zone " + name)
 }
diff --git a/third_party/gofrontend/libgo/go/time/zoneinfo_windows.go b/third_party/gofrontend/libgo/go/time/zoneinfo_windows.go
index 02d8e0e..d04ebec 100644
--- a/third_party/gofrontend/libgo/go/time/zoneinfo_windows.go
+++ b/third_party/gofrontend/libgo/go/time/zoneinfo_windows.go
@@ -6,9 +6,9 @@
 
 import (
 	"errors"
+	"internal/syscall/windows/registry"
 	"runtime"
 	"syscall"
-	"unsafe"
 )
 
 //go:generate go run genzabbrs.go -output zoneinfo_abbrs_windows.go
@@ -20,39 +20,23 @@
 // The implementation assumes that this year's rules for daylight savings
 // time apply to all previous and future years as well.
 
-// getKeyValue retrieves the string value kname associated with the open registry key kh.
-func getKeyValue(kh syscall.Handle, kname string) (string, error) {
-	var buf [50]uint16 // buf needs to be large enough to fit zone descriptions
-	var typ uint32
-	n := uint32(len(buf) * 2) // RegQueryValueEx's signature expects array of bytes, not uint16
-	p, _ := syscall.UTF16PtrFromString(kname)
-	if err := syscall.RegQueryValueEx(kh, p, nil, &typ, (*byte)(unsafe.Pointer(&buf[0])), &n); err != nil {
-		return "", err
-	}
-	if typ != syscall.REG_SZ { // null terminated strings only
-		return "", errors.New("Key is not string")
-	}
-	return syscall.UTF16ToString(buf[:]), nil
-}
-
 // matchZoneKey checks if stdname and dstname match the corresponding "Std"
 // and "Dlt" key values in the kname key stored under the open registry key zones.
-func matchZoneKey(zones syscall.Handle, kname string, stdname, dstname string) (matched bool, err2 error) {
-	var h syscall.Handle
-	p, _ := syscall.UTF16PtrFromString(kname)
-	if err := syscall.RegOpenKeyEx(zones, p, 0, syscall.KEY_READ, &h); err != nil {
+func matchZoneKey(zones registry.Key, kname string, stdname, dstname string) (matched bool, err2 error) {
+	k, err := registry.OpenKey(zones, kname, registry.READ)
+	if err != nil {
 		return false, err
 	}
-	defer syscall.RegCloseKey(h)
+	defer k.Close()
 
-	s, err := getKeyValue(h, "Std")
+	s, _, err := k.GetStringValue("Std")
 	if err != nil {
 		return false, err
 	}
 	if s != stdname {
 		return false, nil
 	}
-	s, err = getKeyValue(h, "Dlt")
+	s, _, err = k.GetStringValue("Dlt")
 	if err != nil {
 		return false, err
 	}
@@ -65,28 +49,20 @@
 // toEnglishName searches the registry for an English name of a time zone
 // whose zone names are stdname and dstname and returns the English name.
 func toEnglishName(stdname, dstname string) (string, error) {
-	var zones syscall.Handle
-	p, _ := syscall.UTF16PtrFromString(`SOFTWARE\Microsoft\Windows NT\CurrentVersion\Time Zones`)
-	if err := syscall.RegOpenKeyEx(syscall.HKEY_LOCAL_MACHINE, p, 0, syscall.KEY_READ, &zones); err != nil {
+	k, err := registry.OpenKey(registry.LOCAL_MACHINE, `SOFTWARE\Microsoft\Windows NT\CurrentVersion\Time Zones`, registry.ENUMERATE_SUB_KEYS|registry.QUERY_VALUE)
+	if err != nil {
 		return "", err
 	}
-	defer syscall.RegCloseKey(zones)
+	defer k.Close()
 
-	var count uint32
-	if err := syscall.RegQueryInfoKey(zones, nil, nil, nil, &count, nil, nil, nil, nil, nil, nil, nil); err != nil {
+	names, err := k.ReadSubKeyNames(-1)
+	if err != nil {
 		return "", err
 	}
-
-	var buf [50]uint16 // buf needs to be large enough to fit zone descriptions
-	for i := uint32(0); i < count; i++ {
-		n := uint32(len(buf))
-		if syscall.RegEnumKeyEx(zones, i, &buf[0], &n, nil, nil, nil, nil) != nil {
-			continue
-		}
-		kname := syscall.UTF16ToString(buf[:])
-		matched, err := matchZoneKey(zones, kname, stdname, dstname)
+	for _, name := range names {
+		matched, err := matchZoneKey(k, name, stdname, dstname)
 		if err == nil && matched {
-			return kname, nil
+			return name, nil
 		}
 	}
 	return "", errors.New(`English name for time zone "` + stdname + `" not found in registry`)
@@ -260,11 +236,12 @@
 }
 
 func loadLocation(name string) (*Location, error) {
-	if z, err := loadZoneFile(runtime.GOROOT()+`\lib\time\zoneinfo.zip`, name); err == nil {
-		z.name = name
-		return z, nil
+	z, err := loadZoneFile(runtime.GOROOT()+`\lib\time\zoneinfo.zip`, name)
+	if err != nil {
+		return nil, err
 	}
-	return nil, errors.New("unknown time zone " + name)
+	z.name = name
+	return z, nil
 }
 
 func forceZipFileForTesting(zipOnly bool) {
diff --git a/third_party/gofrontend/libgo/go/unicode/graphic.go b/third_party/gofrontend/libgo/go/unicode/graphic.go
index ba90b4e..81eae3e 100644
--- a/third_party/gofrontend/libgo/go/unicode/graphic.go
+++ b/third_party/gofrontend/libgo/go/unicode/graphic.go
@@ -82,7 +82,7 @@
 	if uint32(r) <= MaxLatin1 {
 		return properties[uint8(r)]&pC != 0
 	}
-	// All control characters are < Latin1Max.
+	// All control characters are < MaxLatin1.
 	return false
 }
 
diff --git a/third_party/gofrontend/libgo/go/unicode/letter_test.go b/third_party/gofrontend/libgo/go/unicode/letter_test.go
index 4ee11fb..a40b412 100644
--- a/third_party/gofrontend/libgo/go/unicode/letter_test.go
+++ b/third_party/gofrontend/libgo/go/unicode/letter_test.go
@@ -24,6 +24,7 @@
 	0x181,
 	0x376,
 	0x3cf,
+	0x13bd,
 	0x1f2a,
 	0x2102,
 	0x2c00,
@@ -46,6 +47,7 @@
 	0x377,
 	0x387,
 	0x2150,
+	0xab7d,
 	0xffff,
 	0x10000,
 }
@@ -194,6 +196,15 @@
 	{LowerCase, 0x0148, 0x0148},
 	{TitleCase, 0x0148, 0x0147},
 
+	// Lowercase lower than uppercase.
+	// AB78;CHEROKEE SMALL LETTER GE;Ll;0;L;;;;;N;;;13A8;;13A8
+	{UpperCase, 0xab78, 0x13a8},
+	{LowerCase, 0xab78, 0xab78},
+	{TitleCase, 0xab78, 0x13a8},
+	{UpperCase, 0x13a8, 0x13a8},
+	{LowerCase, 0x13a8, 0xab78},
+	{TitleCase, 0x13a8, 0x13a8},
+
 	// Last block in the 5.1.0 table
 	// 10400;DESERET CAPITAL LETTER LONG I;Lu;0;L;;;;;N;;;;10428;
 	{UpperCase, 0x10400, 0x10400},
@@ -405,6 +416,9 @@
 	// Extra special cases: has lower/upper but no case fold.
 	"İ",
 	"ı",
+
+	// Upper comes before lower (Cherokee).
+	"\u13b0\uab80",
 }
 
 func TestSimpleFold(t *testing.T) {
diff --git a/third_party/gofrontend/libgo/go/unicode/script_test.go b/third_party/gofrontend/libgo/go/unicode/script_test.go
index 795cb4e..935c225 100644
--- a/third_party/gofrontend/libgo/go/unicode/script_test.go
+++ b/third_party/gofrontend/libgo/go/unicode/script_test.go
@@ -14,9 +14,11 @@
 	script string
 }
 
-// Hand-chosen tests from Unicode 5.1.0, 6.0.0, 6.2.0, 6.3.0 and 7.0.0 mostly to
-// discover when new scripts and categories arise.
+// Hand-chosen tests from Unicode 5.1.0, 6.0.0, 6.2.0, 6.3.0, 7.0.0 and 8.0.0
+// mostly to discover when new scripts and categories arise.
 var inTest = []T{
+	{0x11711, "Ahom"},
+	{0x14646, "Anatolian_Hieroglyphs"},
 	{0x06e2, "Arabic"},
 	{0x0567, "Armenian"},
 	{0x10b20, "Avestan"},
@@ -58,6 +60,7 @@
 	{0x3028, "Han"},
 	{0x11b8, "Hangul"},
 	{0x1727, "Hanunoo"},
+	{0x108FF, "Hatran"},
 	{0x05a0, "Hebrew"},
 	{0x3058, "Hiragana"},
 	{0x10841, "Imperial_Aramaic"},
@@ -94,12 +97,14 @@
 	{0x11611, "Modi"},
 	{0x1822, "Mongolian"},
 	{0x16a60, "Mro"},
+	{0x11293, "Multani"},
 	{0x104c, "Myanmar"},
 	{0x10880, "Nabataean"},
 	{0x19c3, "New_Tai_Lue"},
 	{0x07f8, "Nko"},
 	{0x169b, "Ogham"},
 	{0x1c6a, "Ol_Chiki"},
+	{0x10C80, "Old_Hungarian"},
 	{0x10310, "Old_Italic"},
 	{0x10a80, "Old_North_Arabian"},
 	{0x10350, "Old_Permic"},
@@ -121,6 +126,7 @@
 	{0x111a0, "Sharada"},
 	{0x10463, "Shavian"},
 	{0x115c1, "Siddham"},
+	{0x1D920, "SignWriting"},
 	{0x0dbd, "Sinhala"},
 	{0x110d0, "Sora_Sompeng"},
 	{0x1ba3, "Sundanese"},
diff --git a/third_party/gofrontend/libgo/go/unicode/tables.go b/third_party/gofrontend/libgo/go/unicode/tables.go
index 8b77dd6..370a9d1 100644
--- a/third_party/gofrontend/libgo/go/unicode/tables.go
+++ b/third_party/gofrontend/libgo/go/unicode/tables.go
@@ -3,13 +3,13 @@
 // license that can be found in the LICENSE file.
 
 // Generated by running
-//	maketables --tables=all --data=http://www.unicode.org/Public/7.0.0/ucd/UnicodeData.txt --casefolding=http://www.unicode.org/Public/7.0.0/ucd/CaseFolding.txt
+//	maketables --tables=all --data=http://www.unicode.org/Public/8.0.0/ucd/UnicodeData.txt --casefolding=http://www.unicode.org/Public/8.0.0/ucd/CaseFolding.txt
 // DO NOT EDIT
 
 package unicode
 
 // Version is the Unicode edition from which the tables are derived.
-const Version = "7.0.0"
+const Version = "8.0.0"
 
 // Categories is the set of Unicode category tables.
 var Categories = map[string]*RangeTable{
@@ -170,7 +170,7 @@
 		{0x081a, 0x0824, 10},
 		{0x0828, 0x0840, 24},
 		{0x0841, 0x0858, 1},
-		{0x08a0, 0x08b2, 1},
+		{0x08a0, 0x08b4, 1},
 		{0x0904, 0x0939, 1},
 		{0x093d, 0x0950, 19},
 		{0x0958, 0x0961, 1},
@@ -203,7 +203,8 @@
 		{0x0ab5, 0x0ab9, 1},
 		{0x0abd, 0x0ad0, 19},
 		{0x0ae0, 0x0ae1, 1},
-		{0x0b05, 0x0b0c, 1},
+		{0x0af9, 0x0b05, 12},
+		{0x0b06, 0x0b0c, 1},
 		{0x0b0f, 0x0b10, 1},
 		{0x0b13, 0x0b28, 1},
 		{0x0b2a, 0x0b30, 1},
@@ -228,9 +229,9 @@
 		{0x0c12, 0x0c28, 1},
 		{0x0c2a, 0x0c39, 1},
 		{0x0c3d, 0x0c58, 27},
-		{0x0c59, 0x0c60, 7},
-		{0x0c61, 0x0c85, 36},
-		{0x0c86, 0x0c8c, 1},
+		{0x0c59, 0x0c5a, 1},
+		{0x0c60, 0x0c61, 1},
+		{0x0c85, 0x0c8c, 1},
 		{0x0c8e, 0x0c90, 1},
 		{0x0c92, 0x0ca8, 1},
 		{0x0caa, 0x0cb3, 1},
@@ -241,7 +242,7 @@
 		{0x0d05, 0x0d0c, 1},
 		{0x0d0e, 0x0d10, 1},
 		{0x0d12, 0x0d3a, 1},
-		{0x0d3d, 0x0d4e, 17},
+		{0x0d3d, 0x0d5f, 17},
 		{0x0d60, 0x0d61, 1},
 		{0x0d7a, 0x0d7f, 1},
 		{0x0d85, 0x0d96, 1},
@@ -300,7 +301,8 @@
 		{0x1312, 0x1315, 1},
 		{0x1318, 0x135a, 1},
 		{0x1380, 0x138f, 1},
-		{0x13a0, 0x13f4, 1},
+		{0x13a0, 0x13f5, 1},
+		{0x13f8, 0x13fd, 1},
 		{0x1401, 0x166c, 1},
 		{0x166f, 0x167f, 1},
 		{0x1681, 0x169a, 1},
@@ -322,7 +324,7 @@
 		{0x1950, 0x196d, 1},
 		{0x1970, 0x1974, 1},
 		{0x1980, 0x19ab, 1},
-		{0x19c1, 0x19c7, 1},
+		{0x19b0, 0x19c9, 1},
 		{0x1a00, 0x1a16, 1},
 		{0x1a20, 0x1a54, 1},
 		{0x1aa7, 0x1b05, 94},
@@ -399,7 +401,7 @@
 		{0x31a0, 0x31ba, 1},
 		{0x31f0, 0x31ff, 1},
 		{0x3400, 0x4db5, 1},
-		{0x4e00, 0x9fcc, 1},
+		{0x4e00, 0x9fd5, 1},
 		{0xa000, 0xa48c, 1},
 		{0xa4d0, 0xa4fd, 1},
 		{0xa500, 0xa60c, 1},
@@ -410,9 +412,8 @@
 		{0xa6a0, 0xa6e5, 1},
 		{0xa717, 0xa71f, 1},
 		{0xa722, 0xa788, 1},
-		{0xa78b, 0xa78e, 1},
-		{0xa790, 0xa7ad, 1},
-		{0xa7b0, 0xa7b1, 1},
+		{0xa78b, 0xa7ad, 1},
+		{0xa7b0, 0xa7b7, 1},
 		{0xa7f7, 0xa801, 1},
 		{0xa803, 0xa805, 1},
 		{0xa807, 0xa80a, 1},
@@ -420,8 +421,8 @@
 		{0xa840, 0xa873, 1},
 		{0xa882, 0xa8b3, 1},
 		{0xa8f2, 0xa8f7, 1},
-		{0xa8fb, 0xa90a, 15},
-		{0xa90b, 0xa925, 1},
+		{0xa8fb, 0xa8fd, 2},
+		{0xa90a, 0xa925, 1},
 		{0xa930, 0xa946, 1},
 		{0xa960, 0xa97c, 1},
 		{0xa984, 0xa9b2, 1},
@@ -448,9 +449,8 @@
 		{0xab20, 0xab26, 1},
 		{0xab28, 0xab2e, 1},
 		{0xab30, 0xab5a, 1},
-		{0xab5c, 0xab5f, 1},
-		{0xab64, 0xab65, 1},
-		{0xabc0, 0xabe2, 1},
+		{0xab5c, 0xab65, 1},
+		{0xab70, 0xabe2, 1},
 		{0xac00, 0xd7a3, 1},
 		{0xd7b0, 0xd7c6, 1},
 		{0xd7cb, 0xd7fb, 1},
@@ -511,6 +511,8 @@
 		{0x10840, 0x10855, 1},
 		{0x10860, 0x10876, 1},
 		{0x10880, 0x1089e, 1},
+		{0x108e0, 0x108f2, 1},
+		{0x108f4, 0x108f5, 1},
 		{0x10900, 0x10915, 1},
 		{0x10920, 0x10939, 1},
 		{0x10980, 0x109b7, 1},
@@ -528,6 +530,8 @@
 		{0x10b60, 0x10b72, 1},
 		{0x10b80, 0x10b91, 1},
 		{0x10c00, 0x10c48, 1},
+		{0x10c80, 0x10cb2, 1},
+		{0x10cc0, 0x10cf2, 1},
 		{0x11003, 0x11037, 1},
 		{0x11083, 0x110af, 1},
 		{0x110d0, 0x110e8, 1},
@@ -536,9 +540,14 @@
 		{0x11176, 0x11183, 13},
 		{0x11184, 0x111b2, 1},
 		{0x111c1, 0x111c4, 1},
-		{0x111da, 0x11200, 38},
-		{0x11201, 0x11211, 1},
+		{0x111da, 0x111dc, 2},
+		{0x11200, 0x11211, 1},
 		{0x11213, 0x1122b, 1},
+		{0x11280, 0x11286, 1},
+		{0x11288, 0x1128a, 2},
+		{0x1128b, 0x1128d, 1},
+		{0x1128f, 0x1129d, 1},
+		{0x1129f, 0x112a8, 1},
 		{0x112b0, 0x112de, 1},
 		{0x11305, 0x1130c, 1},
 		{0x1130f, 0x11310, 1},
@@ -546,20 +555,24 @@
 		{0x1132a, 0x11330, 1},
 		{0x11332, 0x11333, 1},
 		{0x11335, 0x11339, 1},
-		{0x1133d, 0x1135d, 32},
-		{0x1135e, 0x11361, 1},
+		{0x1133d, 0x11350, 19},
+		{0x1135d, 0x11361, 1},
 		{0x11480, 0x114af, 1},
 		{0x114c4, 0x114c5, 1},
 		{0x114c7, 0x11580, 185},
 		{0x11581, 0x115ae, 1},
+		{0x115d8, 0x115db, 1},
 		{0x11600, 0x1162f, 1},
 		{0x11644, 0x11680, 60},
 		{0x11681, 0x116aa, 1},
+		{0x11700, 0x11719, 1},
 		{0x118a0, 0x118df, 1},
 		{0x118ff, 0x11ac0, 449},
 		{0x11ac1, 0x11af8, 1},
-		{0x12000, 0x12398, 1},
+		{0x12000, 0x12399, 1},
+		{0x12480, 0x12543, 1},
 		{0x13000, 0x1342e, 1},
+		{0x14400, 0x14646, 1},
 		{0x16800, 0x16a38, 1},
 		{0x16a40, 0x16a5e, 1},
 		{0x16ad0, 0x16aed, 1},
@@ -633,6 +646,7 @@
 		{0x20000, 0x2a6d6, 1},
 		{0x2a700, 0x2b734, 1},
 		{0x2b740, 0x2b81d, 1},
+		{0x2b820, 0x2cea1, 1},
 		{0x2f800, 0x2fa1d, 1},
 	},
 	LatinOffset: 6,
@@ -691,6 +705,7 @@
 		{0x04c2, 0x04ce, 2},
 		{0x04cf, 0x052f, 2},
 		{0x0561, 0x0587, 1},
+		{0x13f8, 0x13fd, 1},
 		{0x1d00, 0x1d2b, 1},
 		{0x1d6b, 0x1d77, 1},
 		{0x1d79, 0x1d9a, 1},
@@ -747,15 +762,18 @@
 		{0xa791, 0xa793, 2},
 		{0xa794, 0xa795, 1},
 		{0xa797, 0xa7a9, 2},
+		{0xa7b5, 0xa7b7, 2},
 		{0xa7fa, 0xab30, 822},
 		{0xab31, 0xab5a, 1},
-		{0xab64, 0xab65, 1},
+		{0xab60, 0xab65, 1},
+		{0xab70, 0xabbf, 1},
 		{0xfb00, 0xfb06, 1},
 		{0xfb13, 0xfb17, 1},
 		{0xff41, 0xff5a, 1},
 	},
 	R32: []Range32{
 		{0x10428, 0x1044f, 1},
+		{0x10cc0, 0x10cf2, 1},
 		{0x118c0, 0x118df, 1},
 		{0x1d41a, 0x1d433, 1},
 		{0x1d44e, 0x1d454, 1},
@@ -861,7 +879,7 @@
 		{0x07cb, 0x07ea, 1},
 		{0x0800, 0x0815, 1},
 		{0x0840, 0x0858, 1},
-		{0x08a0, 0x08b2, 1},
+		{0x08a0, 0x08b4, 1},
 		{0x0904, 0x0939, 1},
 		{0x093d, 0x0950, 19},
 		{0x0958, 0x0961, 1},
@@ -894,7 +912,8 @@
 		{0x0ab5, 0x0ab9, 1},
 		{0x0abd, 0x0ad0, 19},
 		{0x0ae0, 0x0ae1, 1},
-		{0x0b05, 0x0b0c, 1},
+		{0x0af9, 0x0b05, 12},
+		{0x0b06, 0x0b0c, 1},
 		{0x0b0f, 0x0b10, 1},
 		{0x0b13, 0x0b28, 1},
 		{0x0b2a, 0x0b30, 1},
@@ -919,9 +938,9 @@
 		{0x0c12, 0x0c28, 1},
 		{0x0c2a, 0x0c39, 1},
 		{0x0c3d, 0x0c58, 27},
-		{0x0c59, 0x0c60, 7},
-		{0x0c61, 0x0c85, 36},
-		{0x0c86, 0x0c8c, 1},
+		{0x0c59, 0x0c5a, 1},
+		{0x0c60, 0x0c61, 1},
+		{0x0c85, 0x0c8c, 1},
 		{0x0c8e, 0x0c90, 1},
 		{0x0c92, 0x0ca8, 1},
 		{0x0caa, 0x0cb3, 1},
@@ -932,7 +951,7 @@
 		{0x0d05, 0x0d0c, 1},
 		{0x0d0e, 0x0d10, 1},
 		{0x0d12, 0x0d3a, 1},
-		{0x0d3d, 0x0d4e, 17},
+		{0x0d3d, 0x0d5f, 17},
 		{0x0d60, 0x0d61, 1},
 		{0x0d7a, 0x0d7f, 1},
 		{0x0d85, 0x0d96, 1},
@@ -988,7 +1007,6 @@
 		{0x1312, 0x1315, 1},
 		{0x1318, 0x135a, 1},
 		{0x1380, 0x138f, 1},
-		{0x13a0, 0x13f4, 1},
 		{0x1401, 0x166c, 1},
 		{0x166f, 0x167f, 1},
 		{0x1681, 0x169a, 1},
@@ -1011,7 +1029,7 @@
 		{0x1950, 0x196d, 1},
 		{0x1970, 0x1974, 1},
 		{0x1980, 0x19ab, 1},
-		{0x19c1, 0x19c7, 1},
+		{0x19b0, 0x19c9, 1},
 		{0x1a00, 0x1a16, 1},
 		{0x1a20, 0x1a54, 1},
 		{0x1b05, 0x1b33, 1},
@@ -1046,7 +1064,7 @@
 		{0x31a0, 0x31ba, 1},
 		{0x31f0, 0x31ff, 1},
 		{0x3400, 0x4db5, 1},
-		{0x4e00, 0x9fcc, 1},
+		{0x4e00, 0x9fd5, 1},
 		{0xa000, 0xa014, 1},
 		{0xa016, 0xa48c, 1},
 		{0xa4d0, 0xa4f7, 1},
@@ -1055,16 +1073,16 @@
 		{0xa62a, 0xa62b, 1},
 		{0xa66e, 0xa6a0, 50},
 		{0xa6a1, 0xa6e5, 1},
-		{0xa7f7, 0xa7fb, 4},
-		{0xa7fc, 0xa801, 1},
+		{0xa78f, 0xa7f7, 104},
+		{0xa7fb, 0xa801, 1},
 		{0xa803, 0xa805, 1},
 		{0xa807, 0xa80a, 1},
 		{0xa80c, 0xa822, 1},
 		{0xa840, 0xa873, 1},
 		{0xa882, 0xa8b3, 1},
 		{0xa8f2, 0xa8f7, 1},
-		{0xa8fb, 0xa90a, 15},
-		{0xa90b, 0xa925, 1},
+		{0xa8fb, 0xa8fd, 2},
+		{0xa90a, 0xa925, 1},
 		{0xa930, 0xa946, 1},
 		{0xa960, 0xa97c, 1},
 		{0xa984, 0xa9b2, 1},
@@ -1149,6 +1167,8 @@
 		{0x10840, 0x10855, 1},
 		{0x10860, 0x10876, 1},
 		{0x10880, 0x1089e, 1},
+		{0x108e0, 0x108f2, 1},
+		{0x108f4, 0x108f5, 1},
 		{0x10900, 0x10915, 1},
 		{0x10920, 0x10939, 1},
 		{0x10980, 0x109b7, 1},
@@ -1174,9 +1194,14 @@
 		{0x11176, 0x11183, 13},
 		{0x11184, 0x111b2, 1},
 		{0x111c1, 0x111c4, 1},
-		{0x111da, 0x11200, 38},
-		{0x11201, 0x11211, 1},
+		{0x111da, 0x111dc, 2},
+		{0x11200, 0x11211, 1},
 		{0x11213, 0x1122b, 1},
+		{0x11280, 0x11286, 1},
+		{0x11288, 0x1128a, 2},
+		{0x1128b, 0x1128d, 1},
+		{0x1128f, 0x1129d, 1},
+		{0x1129f, 0x112a8, 1},
 		{0x112b0, 0x112de, 1},
 		{0x11305, 0x1130c, 1},
 		{0x1130f, 0x11310, 1},
@@ -1184,19 +1209,23 @@
 		{0x1132a, 0x11330, 1},
 		{0x11332, 0x11333, 1},
 		{0x11335, 0x11339, 1},
-		{0x1133d, 0x1135d, 32},
-		{0x1135e, 0x11361, 1},
+		{0x1133d, 0x11350, 19},
+		{0x1135d, 0x11361, 1},
 		{0x11480, 0x114af, 1},
 		{0x114c4, 0x114c5, 1},
 		{0x114c7, 0x11580, 185},
 		{0x11581, 0x115ae, 1},
+		{0x115d8, 0x115db, 1},
 		{0x11600, 0x1162f, 1},
 		{0x11644, 0x11680, 60},
 		{0x11681, 0x116aa, 1},
+		{0x11700, 0x11719, 1},
 		{0x118ff, 0x11ac0, 449},
 		{0x11ac1, 0x11af8, 1},
-		{0x12000, 0x12398, 1},
+		{0x12000, 0x12399, 1},
+		{0x12480, 0x12543, 1},
 		{0x13000, 0x1342e, 1},
+		{0x14400, 0x14646, 1},
 		{0x16800, 0x16a38, 1},
 		{0x16a40, 0x16a5e, 1},
 		{0x16ad0, 0x16aed, 1},
@@ -1238,6 +1267,7 @@
 		{0x20000, 0x2a6d6, 1},
 		{0x2a700, 0x2b734, 1},
 		{0x2b740, 0x2b81d, 1},
+		{0x2b820, 0x2cea1, 1},
 		{0x2f800, 0x2fa1d, 1},
 	},
 	LatinOffset: 1,
@@ -1312,6 +1342,7 @@
 		{0x0531, 0x0556, 1},
 		{0x10a0, 0x10c5, 1},
 		{0x10c7, 0x10cd, 6},
+		{0x13a0, 0x13f5, 1},
 		{0x1e00, 0x1e94, 2},
 		{0x1e9e, 0x1efe, 2},
 		{0x1f08, 0x1f0f, 1},
@@ -1356,11 +1387,13 @@
 		{0xa790, 0xa792, 2},
 		{0xa796, 0xa7aa, 2},
 		{0xa7ab, 0xa7ad, 1},
-		{0xa7b0, 0xa7b1, 1},
-		{0xff21, 0xff3a, 1},
+		{0xa7b0, 0xa7b4, 1},
+		{0xa7b6, 0xff21, 22379},
+		{0xff22, 0xff3a, 1},
 	},
 	R32: []Range32{
 		{0x10400, 0x10427, 1},
+		{0x10c80, 0x10cb2, 1},
 		{0x118a0, 0x118bf, 1},
 		{0x1d400, 0x1d419, 1},
 		{0x1d434, 0x1d44d, 1},
@@ -1420,7 +1453,7 @@
 		{0x0825, 0x0827, 1},
 		{0x0829, 0x082d, 1},
 		{0x0859, 0x085b, 1},
-		{0x08e4, 0x0903, 1},
+		{0x08e3, 0x0903, 1},
 		{0x093a, 0x093c, 1},
 		{0x093e, 0x094f, 1},
 		{0x0951, 0x0957, 1},
@@ -1516,8 +1549,6 @@
 		{0x18a9, 0x1920, 119},
 		{0x1921, 0x192b, 1},
 		{0x1930, 0x193b, 1},
-		{0x19b0, 0x19c0, 1},
-		{0x19c8, 0x19c9, 1},
 		{0x1a17, 0x1a1b, 1},
 		{0x1a55, 0x1a5e, 1},
 		{0x1a60, 0x1a7c, 1},
@@ -1545,10 +1576,11 @@
 		{0x3099, 0x309a, 1},
 		{0xa66f, 0xa672, 1},
 		{0xa674, 0xa67d, 1},
-		{0xa69f, 0xa6f0, 81},
-		{0xa6f1, 0xa802, 273},
-		{0xa806, 0xa80b, 5},
-		{0xa823, 0xa827, 1},
+		{0xa69e, 0xa69f, 1},
+		{0xa6f0, 0xa6f1, 1},
+		{0xa802, 0xa806, 4},
+		{0xa80b, 0xa823, 24},
+		{0xa824, 0xa827, 1},
 		{0xa880, 0xa881, 1},
 		{0xa8b4, 0xa8c4, 1},
 		{0xa8e0, 0xa8f1, 1},
@@ -1572,7 +1604,7 @@
 		{0xabec, 0xabed, 1},
 		{0xfb1e, 0xfe00, 738},
 		{0xfe01, 0xfe0f, 1},
-		{0xfe20, 0xfe2d, 1},
+		{0xfe20, 0xfe2f, 1},
 	},
 	R32: []Range32{
 		{0x101fd, 0x102e0, 227},
@@ -1592,9 +1624,10 @@
 		{0x11173, 0x11180, 13},
 		{0x11181, 0x11182, 1},
 		{0x111b3, 0x111c0, 1},
+		{0x111ca, 0x111cc, 1},
 		{0x1122c, 0x11237, 1},
 		{0x112df, 0x112ea, 1},
-		{0x11301, 0x11303, 1},
+		{0x11300, 0x11303, 1},
 		{0x1133c, 0x1133e, 2},
 		{0x1133f, 0x11344, 1},
 		{0x11347, 0x11348, 1},
@@ -1606,8 +1639,10 @@
 		{0x114b0, 0x114c3, 1},
 		{0x115af, 0x115b5, 1},
 		{0x115b8, 0x115c0, 1},
+		{0x115dc, 0x115dd, 1},
 		{0x11630, 0x11640, 1},
 		{0x116ab, 0x116b7, 1},
+		{0x1171d, 0x1172b, 1},
 		{0x16af0, 0x16af4, 1},
 		{0x16b30, 0x16b36, 1},
 		{0x16f51, 0x16f7e, 1},
@@ -1619,6 +1654,11 @@
 		{0x1d185, 0x1d18b, 1},
 		{0x1d1aa, 0x1d1ad, 1},
 		{0x1d242, 0x1d244, 1},
+		{0x1da00, 0x1da36, 1},
+		{0x1da3b, 0x1da6c, 1},
+		{0x1da75, 0x1da84, 15},
+		{0x1da9b, 0x1da9f, 1},
+		{0x1daa1, 0x1daaf, 1},
 		{0x1e8d0, 0x1e8d6, 1},
 		{0xe0100, 0xe01ef, 1},
 	},
@@ -1685,8 +1725,6 @@
 		{0x1929, 0x192b, 1},
 		{0x1930, 0x1931, 1},
 		{0x1933, 0x1938, 1},
-		{0x19b0, 0x19c0, 1},
-		{0x19c8, 0x19c9, 1},
 		{0x1a19, 0x1a1a, 1},
 		{0x1a55, 0x1a57, 2},
 		{0x1a61, 0x1a63, 2},
@@ -1755,8 +1793,9 @@
 		{0x1163b, 0x1163c, 1},
 		{0x1163e, 0x116ac, 110},
 		{0x116ae, 0x116af, 1},
-		{0x116b6, 0x16f51, 22683},
-		{0x16f52, 0x16f7e, 1},
+		{0x116b6, 0x11720, 106},
+		{0x11721, 0x11726, 5},
+		{0x16f51, 0x16f7e, 1},
 		{0x1d165, 0x1d166, 1},
 		{0x1d16d, 0x1d172, 1},
 	},
@@ -1796,7 +1835,7 @@
 		{0x0825, 0x0827, 1},
 		{0x0829, 0x082d, 1},
 		{0x0859, 0x085b, 1},
-		{0x08e4, 0x0902, 1},
+		{0x08e3, 0x0902, 1},
 		{0x093a, 0x093c, 2},
 		{0x0941, 0x0948, 1},
 		{0x094d, 0x0951, 4},
@@ -1918,12 +1957,12 @@
 		{0x3099, 0x309a, 1},
 		{0xa66f, 0xa674, 5},
 		{0xa675, 0xa67d, 1},
-		{0xa69f, 0xa6f0, 81},
-		{0xa6f1, 0xa802, 273},
-		{0xa806, 0xa80b, 5},
-		{0xa825, 0xa826, 1},
-		{0xa8c4, 0xa8e0, 28},
-		{0xa8e1, 0xa8f1, 1},
+		{0xa69e, 0xa69f, 1},
+		{0xa6f0, 0xa6f1, 1},
+		{0xa802, 0xa806, 4},
+		{0xa80b, 0xa825, 26},
+		{0xa826, 0xa8c4, 158},
+		{0xa8e0, 0xa8f1, 1},
 		{0xa926, 0xa92d, 1},
 		{0xa947, 0xa951, 1},
 		{0xa980, 0xa982, 1},
@@ -1943,7 +1982,7 @@
 		{0xabe5, 0xabe8, 3},
 		{0xabed, 0xfb1e, 20273},
 		{0xfe00, 0xfe0f, 1},
-		{0xfe20, 0xfe2d, 1},
+		{0xfe20, 0xfe2f, 1},
 	},
 	R32: []Range32{
 		{0x101fd, 0x102e0, 227},
@@ -1964,13 +2003,14 @@
 		{0x11173, 0x11180, 13},
 		{0x11181, 0x111b6, 53},
 		{0x111b7, 0x111be, 1},
+		{0x111ca, 0x111cc, 1},
 		{0x1122f, 0x11231, 1},
 		{0x11234, 0x11236, 2},
 		{0x11237, 0x112df, 168},
 		{0x112e3, 0x112ea, 1},
-		{0x11301, 0x1133c, 59},
-		{0x11340, 0x11366, 38},
-		{0x11367, 0x1136c, 1},
+		{0x11300, 0x11301, 1},
+		{0x1133c, 0x11340, 4},
+		{0x11366, 0x1136c, 1},
 		{0x11370, 0x11374, 1},
 		{0x114b3, 0x114b8, 1},
 		{0x114ba, 0x114bf, 5},
@@ -1979,13 +2019,17 @@
 		{0x115b3, 0x115b5, 1},
 		{0x115bc, 0x115bd, 1},
 		{0x115bf, 0x115c0, 1},
+		{0x115dc, 0x115dd, 1},
 		{0x11633, 0x1163a, 1},
 		{0x1163d, 0x1163f, 2},
 		{0x11640, 0x116ab, 107},
 		{0x116ad, 0x116b0, 3},
 		{0x116b1, 0x116b5, 1},
-		{0x116b7, 0x16af0, 21561},
-		{0x16af1, 0x16af4, 1},
+		{0x116b7, 0x1171d, 102},
+		{0x1171e, 0x1171f, 1},
+		{0x11722, 0x11725, 1},
+		{0x11727, 0x1172b, 1},
+		{0x16af0, 0x16af4, 1},
 		{0x16b30, 0x16b36, 1},
 		{0x16f8f, 0x16f92, 1},
 		{0x1bc9d, 0x1bc9e, 1},
@@ -1994,6 +2038,11 @@
 		{0x1d185, 0x1d18b, 1},
 		{0x1d1aa, 0x1d1ad, 1},
 		{0x1d242, 0x1d244, 1},
+		{0x1da00, 0x1da36, 1},
+		{0x1da3b, 0x1da6c, 1},
+		{0x1da75, 0x1da84, 15},
+		{0x1da9b, 0x1da9f, 1},
+		{0x1daa1, 0x1daaf, 1},
 		{0x1e8d0, 0x1e8d6, 1},
 		{0xe0100, 0xe01ef, 1},
 	},
@@ -2079,7 +2128,11 @@
 		{0x10858, 0x1085f, 1},
 		{0x10879, 0x1087f, 1},
 		{0x108a7, 0x108af, 1},
+		{0x108fb, 0x108ff, 1},
 		{0x10916, 0x1091b, 1},
+		{0x109bc, 0x109bd, 1},
+		{0x109c0, 0x109cf, 1},
+		{0x109d2, 0x109ff, 1},
 		{0x10a40, 0x10a47, 1},
 		{0x10a7d, 0x10a7e, 1},
 		{0x10a9d, 0x10a9f, 1},
@@ -2087,6 +2140,7 @@
 		{0x10b58, 0x10b5f, 1},
 		{0x10b78, 0x10b7f, 1},
 		{0x10ba9, 0x10baf, 1},
+		{0x10cfa, 0x10cff, 1},
 		{0x10e60, 0x10e7e, 1},
 		{0x11052, 0x1106f, 1},
 		{0x110f0, 0x110f9, 1},
@@ -2097,6 +2151,7 @@
 		{0x114d0, 0x114d9, 1},
 		{0x11650, 0x11659, 1},
 		{0x116c0, 0x116c9, 1},
+		{0x11730, 0x1173b, 1},
 		{0x118e0, 0x118f2, 1},
 		{0x12400, 0x1246e, 1},
 		{0x16a60, 0x16a69, 1},
@@ -2160,6 +2215,7 @@
 		{0x114d0, 0x114d9, 1},
 		{0x11650, 0x11659, 1},
 		{0x116c0, 0x116c9, 1},
+		{0x11730, 0x11739, 1},
 		{0x118e0, 0x118e9, 1},
 		{0x16a60, 0x16a69, 1},
 		{0x16b50, 0x16b59, 1},
@@ -2225,7 +2281,11 @@
 		{0x10858, 0x1085f, 1},
 		{0x10879, 0x1087f, 1},
 		{0x108a7, 0x108af, 1},
+		{0x108fb, 0x108ff, 1},
 		{0x10916, 0x1091b, 1},
+		{0x109bc, 0x109bd, 1},
+		{0x109c0, 0x109cf, 1},
+		{0x109d2, 0x109ff, 1},
 		{0x10a40, 0x10a47, 1},
 		{0x10a7d, 0x10a7e, 1},
 		{0x10a9d, 0x10a9f, 1},
@@ -2233,9 +2293,11 @@
 		{0x10b58, 0x10b5f, 1},
 		{0x10b78, 0x10b7f, 1},
 		{0x10ba9, 0x10baf, 1},
+		{0x10cfa, 0x10cff, 1},
 		{0x10e60, 0x10e7e, 1},
 		{0x11052, 0x11065, 1},
 		{0x111e1, 0x111f4, 1},
+		{0x1173a, 0x1173b, 1},
 		{0x118ea, 0x118f2, 1},
 		{0x16b5b, 0x16b61, 1},
 		{0x1d360, 0x1d371, 1},
@@ -2336,9 +2398,9 @@
 		{0xa874, 0xa877, 1},
 		{0xa8ce, 0xa8cf, 1},
 		{0xa8f8, 0xa8fa, 1},
-		{0xa92e, 0xa92f, 1},
-		{0xa95f, 0xa9c1, 98},
-		{0xa9c2, 0xa9cd, 1},
+		{0xa8fc, 0xa92e, 50},
+		{0xa92f, 0xa95f, 48},
+		{0xa9c1, 0xa9cd, 1},
 		{0xa9de, 0xa9df, 1},
 		{0xaa5c, 0xaa5f, 1},
 		{0xaade, 0xaadf, 1},
@@ -2375,17 +2437,20 @@
 		{0x110be, 0x110c1, 1},
 		{0x11140, 0x11143, 1},
 		{0x11174, 0x11175, 1},
-		{0x111c5, 0x111c8, 1},
-		{0x111cd, 0x11238, 107},
-		{0x11239, 0x1123d, 1},
-		{0x114c6, 0x115c1, 251},
-		{0x115c2, 0x115c9, 1},
+		{0x111c5, 0x111c9, 1},
+		{0x111cd, 0x111db, 14},
+		{0x111dd, 0x111df, 1},
+		{0x11238, 0x1123d, 1},
+		{0x112a9, 0x114c6, 541},
+		{0x115c1, 0x115d7, 1},
 		{0x11641, 0x11643, 1},
+		{0x1173c, 0x1173e, 1},
 		{0x12470, 0x12474, 1},
 		{0x16a6e, 0x16a6f, 1},
 		{0x16af5, 0x16b37, 66},
 		{0x16b38, 0x16b3b, 1},
 		{0x16b44, 0x1bc9f, 20827},
+		{0x1da87, 0x1da8b, 1},
 	},
 	LatinOffset: 11,
 }
@@ -2550,9 +2615,9 @@
 		{0xa874, 0xa877, 1},
 		{0xa8ce, 0xa8cf, 1},
 		{0xa8f8, 0xa8fa, 1},
-		{0xa92e, 0xa92f, 1},
-		{0xa95f, 0xa9c1, 98},
-		{0xa9c2, 0xa9cd, 1},
+		{0xa8fc, 0xa92e, 50},
+		{0xa92f, 0xa95f, 48},
+		{0xa9c1, 0xa9cd, 1},
 		{0xa9de, 0xa9df, 1},
 		{0xaa5c, 0xaa5f, 1},
 		{0xaade, 0xaadf, 1},
@@ -2592,17 +2657,20 @@
 		{0x110be, 0x110c1, 1},
 		{0x11140, 0x11143, 1},
 		{0x11174, 0x11175, 1},
-		{0x111c5, 0x111c8, 1},
-		{0x111cd, 0x11238, 107},
-		{0x11239, 0x1123d, 1},
-		{0x114c6, 0x115c1, 251},
-		{0x115c2, 0x115c9, 1},
+		{0x111c5, 0x111c9, 1},
+		{0x111cd, 0x111db, 14},
+		{0x111dd, 0x111df, 1},
+		{0x11238, 0x1123d, 1},
+		{0x112a9, 0x114c6, 541},
+		{0x115c1, 0x115d7, 1},
 		{0x11641, 0x11643, 1},
+		{0x1173c, 0x1173e, 1},
 		{0x12470, 0x12474, 1},
 		{0x16a6e, 0x16a6f, 1},
 		{0x16af5, 0x16b37, 66},
 		{0x16b38, 0x16b3b, 1},
 		{0x16b44, 0x1bc9f, 20827},
+		{0x1da87, 0x1da8b, 1},
 	},
 	LatinOffset: 8,
 }
@@ -2694,7 +2762,7 @@
 		{0x2044, 0x2052, 14},
 		{0x207a, 0x207c, 1},
 		{0x208a, 0x208c, 1},
-		{0x20a0, 0x20bd, 1},
+		{0x20a0, 0x20be, 1},
 		{0x2100, 0x2101, 1},
 		{0x2103, 0x2106, 1},
 		{0x2108, 0x2109, 1},
@@ -2706,7 +2774,8 @@
 		{0x213b, 0x2140, 5},
 		{0x2141, 0x2144, 1},
 		{0x214a, 0x214d, 1},
-		{0x214f, 0x2190, 65},
+		{0x214f, 0x218a, 59},
+		{0x218b, 0x2190, 5},
 		{0x2191, 0x2307, 1},
 		{0x230c, 0x2328, 1},
 		{0x232b, 0x23fa, 1},
@@ -2724,6 +2793,7 @@
 		{0x2b98, 0x2bb9, 1},
 		{0x2bbd, 0x2bc8, 1},
 		{0x2bca, 0x2bd1, 1},
+		{0x2bec, 0x2bef, 1},
 		{0x2ce5, 0x2cea, 1},
 		{0x2e80, 0x2e99, 1},
 		{0x2e9b, 0x2ef3, 1},
@@ -2774,8 +2844,8 @@
 		{0x101a0, 0x101d0, 48},
 		{0x101d1, 0x101fc, 1},
 		{0x10877, 0x10878, 1},
-		{0x10ac8, 0x16b3c, 24692},
-		{0x16b3d, 0x16b3f, 1},
+		{0x10ac8, 0x1173f, 3191},
+		{0x16b3c, 0x16b3f, 1},
 		{0x16b45, 0x1bc9c, 20823},
 		{0x1d000, 0x1d0f5, 1},
 		{0x1d100, 0x1d126, 1},
@@ -2783,7 +2853,7 @@
 		{0x1d16a, 0x1d16c, 1},
 		{0x1d183, 0x1d184, 1},
 		{0x1d18c, 0x1d1a9, 1},
-		{0x1d1ae, 0x1d1dd, 1},
+		{0x1d1ae, 0x1d1e8, 1},
 		{0x1d200, 0x1d241, 1},
 		{0x1d245, 0x1d300, 187},
 		{0x1d301, 0x1d356, 1},
@@ -2792,6 +2862,11 @@
 		{0x1d735, 0x1d74f, 26},
 		{0x1d76f, 0x1d789, 26},
 		{0x1d7a9, 0x1d7c3, 26},
+		{0x1d800, 0x1d9ff, 1},
+		{0x1da37, 0x1da3a, 1},
+		{0x1da6d, 0x1da74, 1},
+		{0x1da76, 0x1da83, 1},
+		{0x1da85, 0x1da86, 1},
 		{0x1eef0, 0x1eef1, 1},
 		{0x1f000, 0x1f02b, 1},
 		{0x1f030, 0x1f093, 1},
@@ -2806,16 +2881,9 @@
 		{0x1f210, 0x1f23a, 1},
 		{0x1f240, 0x1f248, 1},
 		{0x1f250, 0x1f251, 1},
-		{0x1f300, 0x1f32c, 1},
-		{0x1f330, 0x1f37d, 1},
-		{0x1f380, 0x1f3ce, 1},
-		{0x1f3d4, 0x1f3f7, 1},
-		{0x1f400, 0x1f4fe, 1},
-		{0x1f500, 0x1f54a, 1},
-		{0x1f550, 0x1f579, 1},
+		{0x1f300, 0x1f579, 1},
 		{0x1f57b, 0x1f5a3, 1},
-		{0x1f5a5, 0x1f642, 1},
-		{0x1f645, 0x1f6cf, 1},
+		{0x1f5a5, 0x1f6d0, 1},
 		{0x1f6e0, 0x1f6ec, 1},
 		{0x1f6f0, 0x1f6f3, 1},
 		{0x1f700, 0x1f773, 1},
@@ -2825,6 +2893,9 @@
 		{0x1f850, 0x1f859, 1},
 		{0x1f860, 0x1f887, 1},
 		{0x1f890, 0x1f8ad, 1},
+		{0x1f910, 0x1f918, 1},
+		{0x1f980, 0x1f984, 1},
+		{0x1f9c0, 0x1f9c0, 1},
 	},
 	LatinOffset: 10,
 }
@@ -2838,7 +2909,7 @@
 		{0x09fb, 0x0af1, 246},
 		{0x0bf9, 0x0e3f, 582},
 		{0x17db, 0x20a0, 2245},
-		{0x20a1, 0x20bd, 1},
+		{0x20a1, 0x20be, 1},
 		{0xa838, 0xfdfc, 21956},
 		{0xfe69, 0xff04, 155},
 		{0xffe0, 0xffe1, 1},
@@ -2873,6 +2944,10 @@
 		{0xff3e, 0xff40, 2},
 		{0xffe3, 0xffe3, 1},
 	},
+	R32: []Range32{
+		{0x1f3fb, 0x1f3fb, 1},
+		{0x1f3fc, 0x1f3ff, 1},
+	},
 	LatinOffset: 3,
 }
 
@@ -2971,7 +3046,8 @@
 		{0x212e, 0x213a, 12},
 		{0x213b, 0x214a, 15},
 		{0x214c, 0x214d, 1},
-		{0x214f, 0x2195, 70},
+		{0x214f, 0x218a, 59},
+		{0x218b, 0x2195, 10},
 		{0x2196, 0x2199, 1},
 		{0x219c, 0x219f, 1},
 		{0x21a1, 0x21a2, 1},
@@ -3005,6 +3081,7 @@
 		{0x2b98, 0x2bb9, 1},
 		{0x2bbd, 0x2bc8, 1},
 		{0x2bca, 0x2bd1, 1},
+		{0x2bec, 0x2bef, 1},
 		{0x2ce5, 0x2cea, 1},
 		{0x2e80, 0x2e99, 1},
 		{0x2e9b, 0x2ef3, 1},
@@ -3044,8 +3121,8 @@
 		{0x101a0, 0x101d0, 48},
 		{0x101d1, 0x101fc, 1},
 		{0x10877, 0x10878, 1},
-		{0x10ac8, 0x16b3c, 24692},
-		{0x16b3d, 0x16b3f, 1},
+		{0x10ac8, 0x1173f, 3191},
+		{0x16b3c, 0x16b3f, 1},
 		{0x16b45, 0x1bc9c, 20823},
 		{0x1d000, 0x1d0f5, 1},
 		{0x1d100, 0x1d126, 1},
@@ -3053,10 +3130,15 @@
 		{0x1d16a, 0x1d16c, 1},
 		{0x1d183, 0x1d184, 1},
 		{0x1d18c, 0x1d1a9, 1},
-		{0x1d1ae, 0x1d1dd, 1},
+		{0x1d1ae, 0x1d1e8, 1},
 		{0x1d200, 0x1d241, 1},
 		{0x1d245, 0x1d300, 187},
 		{0x1d301, 0x1d356, 1},
+		{0x1d800, 0x1d9ff, 1},
+		{0x1da37, 0x1da3a, 1},
+		{0x1da6d, 0x1da74, 1},
+		{0x1da76, 0x1da83, 1},
+		{0x1da85, 0x1da86, 1},
 		{0x1f000, 0x1f02b, 1},
 		{0x1f030, 0x1f093, 1},
 		{0x1f0a0, 0x1f0ae, 1},
@@ -3070,16 +3152,10 @@
 		{0x1f210, 0x1f23a, 1},
 		{0x1f240, 0x1f248, 1},
 		{0x1f250, 0x1f251, 1},
-		{0x1f300, 0x1f32c, 1},
-		{0x1f330, 0x1f37d, 1},
-		{0x1f380, 0x1f3ce, 1},
-		{0x1f3d4, 0x1f3f7, 1},
-		{0x1f400, 0x1f4fe, 1},
-		{0x1f500, 0x1f54a, 1},
-		{0x1f550, 0x1f579, 1},
+		{0x1f300, 0x1f3fa, 1},
+		{0x1f400, 0x1f579, 1},
 		{0x1f57b, 0x1f5a3, 1},
-		{0x1f5a5, 0x1f642, 1},
-		{0x1f645, 0x1f6cf, 1},
+		{0x1f5a5, 0x1f6d0, 1},
 		{0x1f6e0, 0x1f6ec, 1},
 		{0x1f6f0, 0x1f6f3, 1},
 		{0x1f700, 0x1f773, 1},
@@ -3089,6 +3165,9 @@
 		{0x1f850, 0x1f859, 1},
 		{0x1f860, 0x1f887, 1},
 		{0x1f890, 0x1f8ad, 1},
+		{0x1f910, 0x1f918, 1},
+		{0x1f980, 0x1f984, 1},
+		{0x1f9c0, 0x1f9c0, 1},
 	},
 	LatinOffset: 2,
 }
@@ -3180,11 +3259,13 @@
 )
 
 // Generated by running
-//	maketables --scripts=all --url=http://www.unicode.org/Public/7.0.0/ucd/
+//	maketables --scripts=all --url=http://www.unicode.org/Public/8.0.0/ucd/
 // DO NOT EDIT
 
 // Scripts is the set of Unicode script tables.
 var Scripts = map[string]*RangeTable{
+	"Ahom":                   Ahom,
+	"Anatolian_Hieroglyphs":  Anatolian_Hieroglyphs,
 	"Arabic":                 Arabic,
 	"Armenian":               Armenian,
 	"Avestan":                Avestan,
@@ -3225,6 +3306,7 @@
 	"Han":                    Han,
 	"Hangul":                 Hangul,
 	"Hanunoo":                Hanunoo,
+	"Hatran":                 Hatran,
 	"Hebrew":                 Hebrew,
 	"Hiragana":               Hiragana,
 	"Imperial_Aramaic":       Imperial_Aramaic,
@@ -3261,12 +3343,14 @@
 	"Modi":                   Modi,
 	"Mongolian":              Mongolian,
 	"Mro":                    Mro,
+	"Multani":                Multani,
 	"Myanmar":                Myanmar,
 	"Nabataean":              Nabataean,
 	"New_Tai_Lue":            New_Tai_Lue,
 	"Nko":                    Nko,
 	"Ogham":                  Ogham,
 	"Ol_Chiki":               Ol_Chiki,
+	"Old_Hungarian":          Old_Hungarian,
 	"Old_Italic":             Old_Italic,
 	"Old_North_Arabian":      Old_North_Arabian,
 	"Old_Permic":             Old_Permic,
@@ -3288,6 +3372,7 @@
 	"Sharada":                Sharada,
 	"Shavian":                Shavian,
 	"Siddham":                Siddham,
+	"SignWriting":            SignWriting,
 	"Sinhala":                Sinhala,
 	"Sora_Sompeng":           Sora_Sompeng,
 	"Sundanese":              Sundanese,
@@ -3312,6 +3397,22 @@
 	"Yi":                     Yi,
 }
 
+var _Ahom = &RangeTable{
+	R16: []Range16{},
+	R32: []Range32{
+		{0x11700, 0x11719, 1},
+		{0x1171d, 0x1172b, 1},
+		{0x11730, 0x1173f, 1},
+	},
+}
+
+var _Anatolian_Hieroglyphs = &RangeTable{
+	R16: []Range16{},
+	R32: []Range32{
+		{0x14400, 0x14646, 1},
+	},
+}
+
 var _Arabic = &RangeTable{
 	R16: []Range16{
 		{0x0600, 0x0604, 1},
@@ -3320,13 +3421,12 @@
 		{0x061e, 0x061e, 1},
 		{0x0620, 0x063f, 1},
 		{0x0641, 0x064a, 1},
-		{0x0656, 0x065f, 1},
-		{0x066a, 0x066f, 1},
+		{0x0656, 0x066f, 1},
 		{0x0671, 0x06dc, 1},
 		{0x06de, 0x06ff, 1},
 		{0x0750, 0x077f, 1},
-		{0x08a0, 0x08b2, 1},
-		{0x08e4, 0x08ff, 1},
+		{0x08a0, 0x08b4, 1},
+		{0x08e3, 0x08ff, 1},
 		{0xfb50, 0xfbc1, 1},
 		{0xfbd3, 0xfd3d, 1},
 		{0xfd50, 0xfd8f, 1},
@@ -3520,7 +3620,9 @@
 
 var _Cherokee = &RangeTable{
 	R16: []Range16{
-		{0x13a0, 0x13f4, 1},
+		{0x13a0, 0x13f5, 1},
+		{0x13f8, 0x13fd, 1},
+		{0xab70, 0xabbf, 1},
 	},
 }
 
@@ -3546,7 +3648,6 @@
 		{0x061b, 0x061c, 1},
 		{0x061f, 0x061f, 1},
 		{0x0640, 0x0640, 1},
-		{0x0660, 0x0669, 1},
 		{0x06dd, 0x06dd, 1},
 		{0x0964, 0x0965, 1},
 		{0x0e3f, 0x0e3f, 1},
@@ -3566,13 +3667,13 @@
 		{0x2066, 0x2070, 1},
 		{0x2074, 0x207e, 1},
 		{0x2080, 0x208e, 1},
-		{0x20a0, 0x20bd, 1},
+		{0x20a0, 0x20be, 1},
 		{0x2100, 0x2125, 1},
 		{0x2127, 0x2129, 1},
 		{0x212c, 0x2131, 1},
 		{0x2133, 0x214d, 1},
 		{0x214f, 0x215f, 1},
-		{0x2189, 0x2189, 1},
+		{0x2189, 0x218b, 1},
 		{0x2190, 0x23fa, 1},
 		{0x2400, 0x2426, 1},
 		{0x2440, 0x244a, 1},
@@ -3582,6 +3683,7 @@
 		{0x2b98, 0x2bb9, 1},
 		{0x2bbd, 0x2bc8, 1},
 		{0x2bca, 0x2bd1, 1},
+		{0x2bec, 0x2bef, 1},
 		{0x2e00, 0x2e42, 1},
 		{0x2ff0, 0x2ffb, 1},
 		{0x3000, 0x3004, 1},
@@ -3633,7 +3735,7 @@
 		{0x1d16a, 0x1d17a, 1},
 		{0x1d183, 0x1d184, 1},
 		{0x1d18c, 0x1d1a9, 1},
-		{0x1d1ae, 0x1d1dd, 1},
+		{0x1d1ae, 0x1d1e8, 1},
 		{0x1d300, 0x1d356, 1},
 		{0x1d360, 0x1d371, 1},
 		{0x1d400, 0x1d454, 1},
@@ -3672,16 +3774,9 @@
 		{0x1f210, 0x1f23a, 1},
 		{0x1f240, 0x1f248, 1},
 		{0x1f250, 0x1f251, 1},
-		{0x1f300, 0x1f32c, 1},
-		{0x1f330, 0x1f37d, 1},
-		{0x1f380, 0x1f3ce, 1},
-		{0x1f3d4, 0x1f3f7, 1},
-		{0x1f400, 0x1f4fe, 1},
-		{0x1f500, 0x1f54a, 1},
-		{0x1f550, 0x1f579, 1},
+		{0x1f300, 0x1f579, 1},
 		{0x1f57b, 0x1f5a3, 1},
-		{0x1f5a5, 0x1f642, 1},
-		{0x1f645, 0x1f6cf, 1},
+		{0x1f5a5, 0x1f6d0, 1},
 		{0x1f6e0, 0x1f6ec, 1},
 		{0x1f6f0, 0x1f6f3, 1},
 		{0x1f700, 0x1f773, 1},
@@ -3691,6 +3786,9 @@
 		{0x1f850, 0x1f859, 1},
 		{0x1f860, 0x1f887, 1},
 		{0x1f890, 0x1f8ad, 1},
+		{0x1f910, 0x1f918, 1},
+		{0x1f980, 0x1f984, 1},
+		{0x1f9c0, 0x1f9c0, 1},
 		{0xe0001, 0xe0001, 1},
 		{0xe0020, 0xe007f, 1},
 	},
@@ -3708,9 +3806,10 @@
 var _Cuneiform = &RangeTable{
 	R16: []Range16{},
 	R32: []Range32{
-		{0x12000, 0x12398, 1},
+		{0x12000, 0x12399, 1},
 		{0x12400, 0x1246e, 1},
 		{0x12470, 0x12474, 1},
+		{0x12480, 0x12543, 1},
 	},
 }
 
@@ -3733,8 +3832,8 @@
 		{0x1d2b, 0x1d2b, 1},
 		{0x1d78, 0x1d78, 1},
 		{0x2de0, 0x2dff, 1},
-		{0xa640, 0xa69d, 1},
-		{0xa69f, 0xa69f, 1},
+		{0xa640, 0xa69f, 1},
+		{0xfe2e, 0xfe2f, 1},
 	},
 }
 
@@ -3750,7 +3849,7 @@
 		{0x0900, 0x0950, 1},
 		{0x0953, 0x0963, 1},
 		{0x0966, 0x097f, 1},
-		{0xa8e0, 0xa8fb, 1},
+		{0xa8e0, 0xa8fd, 1},
 	},
 }
 
@@ -3846,7 +3945,7 @@
 var _Grantha = &RangeTable{
 	R16: []Range16{},
 	R32: []Range32{
-		{0x11301, 0x11303, 1},
+		{0x11300, 0x11303, 1},
 		{0x11305, 0x1130c, 1},
 		{0x1130f, 0x11310, 1},
 		{0x11313, 0x11328, 1},
@@ -3856,6 +3955,7 @@
 		{0x1133c, 0x11344, 1},
 		{0x11347, 0x11348, 1},
 		{0x1134b, 0x1134d, 1},
+		{0x11350, 0x11350, 1},
 		{0x11357, 0x11357, 1},
 		{0x1135d, 0x11363, 1},
 		{0x11366, 0x1136c, 1},
@@ -3921,6 +4021,7 @@
 		{0x0ad0, 0x0ad0, 1},
 		{0x0ae0, 0x0ae3, 1},
 		{0x0ae6, 0x0af1, 1},
+		{0x0af9, 0x0af9, 1},
 	},
 }
 
@@ -3955,7 +4056,7 @@
 		{0x3021, 0x3029, 1},
 		{0x3038, 0x303b, 1},
 		{0x3400, 0x4db5, 1},
-		{0x4e00, 0x9fcc, 1},
+		{0x4e00, 0x9fd5, 1},
 		{0xf900, 0xfa6d, 1},
 		{0xfa70, 0xfad9, 1},
 	},
@@ -3963,6 +4064,7 @@
 		{0x20000, 0x2a6d6, 1},
 		{0x2a700, 0x2b734, 1},
 		{0x2b740, 0x2b81d, 1},
+		{0x2b820, 0x2cea1, 1},
 		{0x2f800, 0x2fa1d, 1},
 	},
 }
@@ -3992,6 +4094,15 @@
 	},
 }
 
+var _Hatran = &RangeTable{
+	R16: []Range16{},
+	R32: []Range32{
+		{0x108e0, 0x108f2, 1},
+		{0x108f4, 0x108f5, 1},
+		{0x108fb, 0x108ff, 1},
+	},
+}
+
 var _Hebrew = &RangeTable{
 	R16: []Range16{
 		{0x0591, 0x05c7, 1},
@@ -4218,13 +4329,11 @@
 		{0x2160, 0x2188, 1},
 		{0x2c60, 0x2c7f, 1},
 		{0xa722, 0xa787, 1},
-		{0xa78b, 0xa78e, 1},
-		{0xa790, 0xa7ad, 1},
-		{0xa7b0, 0xa7b1, 1},
+		{0xa78b, 0xa7ad, 1},
+		{0xa7b0, 0xa7b7, 1},
 		{0xa7f7, 0xa7ff, 1},
 		{0xab30, 0xab5a, 1},
-		{0xab5c, 0xab5f, 1},
-		{0xab64, 0xab64, 1},
+		{0xab5c, 0xab64, 1},
 		{0xfb00, 0xfb06, 1},
 		{0xff21, 0xff3a, 1},
 		{0xff41, 0xff5a, 1},
@@ -4310,7 +4419,7 @@
 		{0x0d46, 0x0d48, 1},
 		{0x0d4a, 0x0d4e, 1},
 		{0x0d57, 0x0d57, 1},
-		{0x0d60, 0x0d63, 1},
+		{0x0d5f, 0x0d63, 1},
 		{0x0d66, 0x0d75, 1},
 		{0x0d79, 0x0d7f, 1},
 	},
@@ -4351,7 +4460,8 @@
 	R16: []Range16{},
 	R32: []Range32{
 		{0x109a0, 0x109b7, 1},
-		{0x109be, 0x109bf, 1},
+		{0x109bc, 0x109cf, 1},
+		{0x109d2, 0x109ff, 1},
 	},
 }
 
@@ -4399,6 +4509,17 @@
 	},
 }
 
+var _Multani = &RangeTable{
+	R16: []Range16{},
+	R32: []Range32{
+		{0x11280, 0x11286, 1},
+		{0x11288, 0x11288, 1},
+		{0x1128a, 0x1128d, 1},
+		{0x1128f, 0x1129d, 1},
+		{0x1129f, 0x112a9, 1},
+	},
+}
+
 var _Myanmar = &RangeTable{
 	R16: []Range16{
 		{0x1000, 0x109f, 1},
@@ -4442,6 +4563,15 @@
 	},
 }
 
+var _Old_Hungarian = &RangeTable{
+	R16: []Range16{},
+	R32: []Range32{
+		{0x10c80, 0x10cb2, 1},
+		{0x10cc0, 0x10cf2, 1},
+		{0x10cfa, 0x10cff, 1},
+	},
+}
+
 var _Old_Italic = &RangeTable{
 	R16: []Range16{},
 	R32: []Range32{
@@ -4591,9 +4721,8 @@
 var _Sharada = &RangeTable{
 	R16: []Range16{},
 	R32: []Range32{
-		{0x11180, 0x111c8, 1},
-		{0x111cd, 0x111cd, 1},
-		{0x111d0, 0x111da, 1},
+		{0x11180, 0x111cd, 1},
+		{0x111d0, 0x111df, 1},
 	},
 }
 
@@ -4608,7 +4737,16 @@
 	R16: []Range16{},
 	R32: []Range32{
 		{0x11580, 0x115b5, 1},
-		{0x115b8, 0x115c9, 1},
+		{0x115b8, 0x115dd, 1},
+	},
+}
+
+var _SignWriting = &RangeTable{
+	R16: []Range16{},
+	R32: []Range32{
+		{0x1d800, 0x1da8b, 1},
+		{0x1da9b, 0x1da9f, 1},
+		{0x1daa1, 0x1daaf, 1},
 	},
 }
 
@@ -4740,7 +4878,7 @@
 		{0x0c46, 0x0c48, 1},
 		{0x0c4a, 0x0c4d, 1},
 		{0x0c55, 0x0c56, 1},
-		{0x0c58, 0x0c59, 1},
+		{0x0c58, 0x0c5a, 1},
 		{0x0c60, 0x0c63, 1},
 		{0x0c66, 0x0c6f, 1},
 		{0x0c78, 0x0c7f, 1},
@@ -4819,6 +4957,8 @@
 
 // These variables have type *RangeTable.
 var (
+	Ahom                   = _Ahom                   // Ahom is the set of Unicode characters in script Ahom.
+	Anatolian_Hieroglyphs  = _Anatolian_Hieroglyphs  // Anatolian_Hieroglyphs is the set of Unicode characters in script Anatolian_Hieroglyphs.
 	Arabic                 = _Arabic                 // Arabic is the set of Unicode characters in script Arabic.
 	Armenian               = _Armenian               // Armenian is the set of Unicode characters in script Armenian.
 	Avestan                = _Avestan                // Avestan is the set of Unicode characters in script Avestan.
@@ -4859,6 +4999,7 @@
 	Han                    = _Han                    // Han is the set of Unicode characters in script Han.
 	Hangul                 = _Hangul                 // Hangul is the set of Unicode characters in script Hangul.
 	Hanunoo                = _Hanunoo                // Hanunoo is the set of Unicode characters in script Hanunoo.
+	Hatran                 = _Hatran                 // Hatran is the set of Unicode characters in script Hatran.
 	Hebrew                 = _Hebrew                 // Hebrew is the set of Unicode characters in script Hebrew.
 	Hiragana               = _Hiragana               // Hiragana is the set of Unicode characters in script Hiragana.
 	Imperial_Aramaic       = _Imperial_Aramaic       // Imperial_Aramaic is the set of Unicode characters in script Imperial_Aramaic.
@@ -4895,12 +5036,14 @@
 	Modi                   = _Modi                   // Modi is the set of Unicode characters in script Modi.
 	Mongolian              = _Mongolian              // Mongolian is the set of Unicode characters in script Mongolian.
 	Mro                    = _Mro                    // Mro is the set of Unicode characters in script Mro.
+	Multani                = _Multani                // Multani is the set of Unicode characters in script Multani.
 	Myanmar                = _Myanmar                // Myanmar is the set of Unicode characters in script Myanmar.
 	Nabataean              = _Nabataean              // Nabataean is the set of Unicode characters in script Nabataean.
 	New_Tai_Lue            = _New_Tai_Lue            // New_Tai_Lue is the set of Unicode characters in script New_Tai_Lue.
 	Nko                    = _Nko                    // Nko is the set of Unicode characters in script Nko.
 	Ogham                  = _Ogham                  // Ogham is the set of Unicode characters in script Ogham.
 	Ol_Chiki               = _Ol_Chiki               // Ol_Chiki is the set of Unicode characters in script Ol_Chiki.
+	Old_Hungarian          = _Old_Hungarian          // Old_Hungarian is the set of Unicode characters in script Old_Hungarian.
 	Old_Italic             = _Old_Italic             // Old_Italic is the set of Unicode characters in script Old_Italic.
 	Old_North_Arabian      = _Old_North_Arabian      // Old_North_Arabian is the set of Unicode characters in script Old_North_Arabian.
 	Old_Permic             = _Old_Permic             // Old_Permic is the set of Unicode characters in script Old_Permic.
@@ -4922,6 +5065,7 @@
 	Sharada                = _Sharada                // Sharada is the set of Unicode characters in script Sharada.
 	Shavian                = _Shavian                // Shavian is the set of Unicode characters in script Shavian.
 	Siddham                = _Siddham                // Siddham is the set of Unicode characters in script Siddham.
+	SignWriting            = _SignWriting            // SignWriting is the set of Unicode characters in script SignWriting.
 	Sinhala                = _Sinhala                // Sinhala is the set of Unicode characters in script Sinhala.
 	Sora_Sompeng           = _Sora_Sompeng           // Sora_Sompeng is the set of Unicode characters in script Sora_Sompeng.
 	Sundanese              = _Sundanese              // Sundanese is the set of Unicode characters in script Sundanese.
@@ -4947,7 +5091,7 @@
 )
 
 // Generated by running
-//	maketables --props=all --url=http://www.unicode.org/Public/7.0.0/ucd/
+//	maketables --props=all --url=http://www.unicode.org/Public/8.0.0/ucd/
 // DO NOT EDIT
 
 // Properties is the set of Unicode property tables.
@@ -5043,7 +5187,7 @@
 	},
 	R32: []Range32{
 		{0xe0001, 0xe0001, 1},
-		{0xe0020, 0xe007f, 1},
+		{0xe007f, 0xe007f, 1},
 	},
 }
 
@@ -5077,7 +5221,7 @@
 		{0x07a6, 0x07b0, 1},
 		{0x07eb, 0x07f5, 1},
 		{0x0818, 0x0819, 1},
-		{0x08e4, 0x08fe, 1},
+		{0x08e3, 0x08fe, 1},
 		{0x093c, 0x093c, 1},
 		{0x094d, 0x094d, 1},
 		{0x0951, 0x0954, 1},
@@ -5164,7 +5308,7 @@
 		{0xab5b, 0xab5f, 1},
 		{0xabec, 0xabed, 1},
 		{0xfb1e, 0xfb1e, 1},
-		{0xfe20, 0xfe2d, 1},
+		{0xfe20, 0xfe2f, 1},
 		{0xff3e, 0xff3e, 1},
 		{0xff40, 0xff40, 1},
 		{0xff70, 0xff70, 1},
@@ -5178,6 +5322,7 @@
 		{0x11133, 0x11134, 1},
 		{0x11173, 0x11173, 1},
 		{0x111c0, 0x111c0, 1},
+		{0x111ca, 0x111cc, 1},
 		{0x11235, 0x11236, 1},
 		{0x112e9, 0x112ea, 1},
 		{0x1133c, 0x1133c, 1},
@@ -5188,6 +5333,7 @@
 		{0x115bf, 0x115c0, 1},
 		{0x1163f, 0x1163f, 1},
 		{0x116b6, 0x116b7, 1},
+		{0x1172b, 0x1172b, 1},
 		{0x16af0, 0x16af4, 1},
 		{0x16f8f, 0x16f9f, 1},
 		{0x1d167, 0x1d169, 1},
@@ -5281,7 +5427,7 @@
 		{0x3021, 0x3029, 1},
 		{0x3038, 0x303a, 1},
 		{0x3400, 0x4db5, 1},
-		{0x4e00, 0x9fcc, 1},
+		{0x4e00, 0x9fd5, 1},
 		{0xf900, 0xfa6d, 1},
 		{0xfa70, 0xfad9, 1},
 	},
@@ -5289,6 +5435,7 @@
 		{0x20000, 0x2a6d6, 1},
 		{0x2a700, 0x2b734, 1},
 		{0x2b740, 0x2b81d, 1},
+		{0x2b820, 0x2cea1, 1},
 		{0x2f800, 0x2fa1d, 1},
 	},
 }
@@ -5303,6 +5450,8 @@
 	R16: []Range16{
 		{0x0e40, 0x0e44, 1},
 		{0x0ec0, 0x0ec4, 1},
+		{0x19b5, 0x19b7, 1},
+		{0x19ba, 0x19ba, 1},
 		{0xaab5, 0xaab6, 1},
 		{0xaab9, 0xaab9, 1},
 		{0xaabb, 0xaabc, 1},
@@ -5357,7 +5506,7 @@
 		{0x081b, 0x0823, 1},
 		{0x0825, 0x0827, 1},
 		{0x0829, 0x082c, 1},
-		{0x08e4, 0x08e9, 1},
+		{0x08e3, 0x08e9, 1},
 		{0x08f0, 0x0903, 1},
 		{0x093a, 0x093b, 1},
 		{0x093e, 0x094c, 1},
@@ -5445,8 +5594,6 @@
 		{0x18a9, 0x18a9, 1},
 		{0x1920, 0x192b, 1},
 		{0x1930, 0x1938, 1},
-		{0x19b0, 0x19c0, 1},
-		{0x19c8, 0x19c9, 1},
 		{0x1a17, 0x1a1b, 1},
 		{0x1a55, 0x1a5e, 1},
 		{0x1a61, 0x1a74, 1},
@@ -5462,7 +5609,7 @@
 		{0x24b6, 0x24e9, 1},
 		{0x2de0, 0x2dff, 1},
 		{0xa674, 0xa67b, 1},
-		{0xa69f, 0xa69f, 1},
+		{0xa69e, 0xa69f, 1},
 		{0xa823, 0xa827, 1},
 		{0xa880, 0xa881, 1},
 		{0xa8b4, 0xa8c3, 1},
@@ -5498,7 +5645,7 @@
 		{0x1122c, 0x11234, 1},
 		{0x11237, 0x11237, 1},
 		{0x112df, 0x112e8, 1},
-		{0x11301, 0x11303, 1},
+		{0x11300, 0x11303, 1},
 		{0x1133e, 0x11344, 1},
 		{0x11347, 0x11348, 1},
 		{0x1134b, 0x1134c, 1},
@@ -5507,9 +5654,11 @@
 		{0x114b0, 0x114c1, 1},
 		{0x115af, 0x115b5, 1},
 		{0x115b8, 0x115be, 1},
+		{0x115dc, 0x115dd, 1},
 		{0x11630, 0x1163e, 1},
 		{0x11640, 0x11640, 1},
 		{0x116ab, 0x116b5, 1},
+		{0x1171d, 0x1172a, 1},
 		{0x16b30, 0x16b36, 1},
 		{0x16f51, 0x16f7e, 1},
 		{0x1bc9e, 0x1bc9e, 1},
@@ -5890,16 +6039,20 @@
 		{0x11141, 0x11143, 1},
 		{0x111c5, 0x111c6, 1},
 		{0x111cd, 0x111cd, 1},
+		{0x111de, 0x111df, 1},
 		{0x11238, 0x11239, 1},
 		{0x1123b, 0x1123c, 1},
+		{0x112a9, 0x112a9, 1},
 		{0x115c2, 0x115c3, 1},
-		{0x115c9, 0x115c9, 1},
+		{0x115c9, 0x115d7, 1},
 		{0x11641, 0x11642, 1},
+		{0x1173c, 0x1173e, 1},
 		{0x16a6e, 0x16a6f, 1},
 		{0x16af5, 0x16af5, 1},
 		{0x16b37, 0x16b38, 1},
 		{0x16b44, 0x16b44, 1},
 		{0x1bc9f, 0x1bc9f, 1},
+		{0x1da88, 0x1da88, 1},
 	},
 	LatinOffset: 3,
 }
@@ -6023,16 +6176,20 @@
 		{0x11141, 0x11143, 1},
 		{0x111c5, 0x111c6, 1},
 		{0x111cd, 0x111cd, 1},
+		{0x111de, 0x111df, 1},
 		{0x11238, 0x1123c, 1},
+		{0x112a9, 0x112a9, 1},
 		{0x115c2, 0x115c5, 1},
-		{0x115c9, 0x115c9, 1},
+		{0x115c9, 0x115d7, 1},
 		{0x11641, 0x11642, 1},
+		{0x1173c, 0x1173e, 1},
 		{0x12470, 0x12474, 1},
 		{0x16a6e, 0x16a6f, 1},
 		{0x16af5, 0x16af5, 1},
 		{0x16b37, 0x16b39, 1},
 		{0x16b44, 0x16b44, 1},
 		{0x1bc9f, 0x1bc9f, 1},
+		{0x1da87, 0x1da8a, 1},
 	},
 	LatinOffset: 5,
 }
@@ -6040,7 +6197,7 @@
 var _Unified_Ideograph = &RangeTable{
 	R16: []Range16{
 		{0x3400, 0x4db5, 1},
-		{0x4e00, 0x9fcc, 1},
+		{0x4e00, 0x9fd5, 1},
 		{0xfa0e, 0xfa0f, 1},
 		{0xfa11, 0xfa11, 1},
 		{0xfa13, 0xfa14, 1},
@@ -6053,6 +6210,7 @@
 		{0x20000, 0x2a6d6, 1},
 		{0x2a700, 0x2b734, 1},
 		{0x2b740, 0x2b81d, 1},
+		{0x2b820, 0x2cea1, 1},
 	},
 }
 
@@ -6119,7 +6277,7 @@
 )
 
 // Generated by running
-//	maketables --data=http://www.unicode.org/Public/7.0.0/ucd/UnicodeData.txt --casefolding=http://www.unicode.org/Public/7.0.0/ucd/CaseFolding.txt
+//	maketables --data=http://www.unicode.org/Public/8.0.0/ucd/UnicodeData.txt --casefolding=http://www.unicode.org/Public/8.0.0/ucd/CaseFolding.txt
 // DO NOT EDIT
 
 // CaseRanges is the table describing case mappings for all letters with
@@ -6240,6 +6398,7 @@
 	{0x028A, 0x028B, d{-217, 0, -217}},
 	{0x028C, 0x028C, d{-71, 0, -71}},
 	{0x0292, 0x0292, d{-219, 0, -219}},
+	{0x029D, 0x029D, d{42261, 0, 42261}},
 	{0x029E, 0x029E, d{42258, 0, 42258}},
 	{0x0345, 0x0345, d{84, 0, 84}},
 	{0x0370, 0x0373, d{UpperLower, UpperLower, UpperLower}},
@@ -6291,6 +6450,9 @@
 	{0x10A0, 0x10C5, d{0, 7264, 0}},
 	{0x10C7, 0x10C7, d{0, 7264, 0}},
 	{0x10CD, 0x10CD, d{0, 7264, 0}},
+	{0x13A0, 0x13EF, d{0, 38864, 0}},
+	{0x13F0, 0x13F5, d{0, 8, 0}},
+	{0x13F8, 0x13FD, d{-8, 0, -8}},
 	{0x1D79, 0x1D79, d{35332, 0, 35332}},
 	{0x1D7D, 0x1D7D, d{3814, 0, 3814}},
 	{0x1E00, 0x1E95, d{UpperLower, UpperLower, UpperLower}},
@@ -6399,10 +6561,17 @@
 	{0xA7AD, 0xA7AD, d{0, -42305, 0}},
 	{0xA7B0, 0xA7B0, d{0, -42258, 0}},
 	{0xA7B1, 0xA7B1, d{0, -42282, 0}},
+	{0xA7B2, 0xA7B2, d{0, -42261, 0}},
+	{0xA7B3, 0xA7B3, d{0, 928, 0}},
+	{0xA7B4, 0xA7B7, d{UpperLower, UpperLower, UpperLower}},
+	{0xAB53, 0xAB53, d{-928, 0, -928}},
+	{0xAB70, 0xABBF, d{-38864, 0, -38864}},
 	{0xFF21, 0xFF3A, d{0, 32, 0}},
 	{0xFF41, 0xFF5A, d{-32, 0, -32}},
 	{0x10400, 0x10427, d{0, 40, 0}},
 	{0x10428, 0x1044F, d{-40, 0, -40}},
+	{0x10C80, 0x10CB2, d{0, 64, 0}},
+	{0x10CC0, 0x10CF2, d{-64, 0, -64}},
 	{0x118A0, 0x118BF, d{0, 32, 0}},
 	{0x118C0, 0x118DF, d{-32, 0, -32}},
 }
@@ -6832,6 +7001,7 @@
 		{0x0531, 0x0556, 1},
 		{0x10a0, 0x10c5, 1},
 		{0x10c7, 0x10cd, 6},
+		{0x13a0, 0x13f5, 1},
 		{0x1e00, 0x1e94, 2},
 		{0x1e9e, 0x1efe, 2},
 		{0x1f08, 0x1f0f, 1},
@@ -6872,11 +7042,13 @@
 		{0xa790, 0xa792, 2},
 		{0xa796, 0xa7aa, 2},
 		{0xa7ab, 0xa7ad, 1},
-		{0xa7b0, 0xa7b1, 1},
-		{0xff21, 0xff3a, 1},
+		{0xa7b0, 0xa7b4, 1},
+		{0xa7b6, 0xff21, 22379},
+		{0xff22, 0xff3a, 1},
 	},
 	R32: []Range32{
 		{0x10400, 0x10427, 1},
+		{0x10c80, 0x10cb2, 1},
 		{0x118a0, 0x118bf, 1},
 	},
 	LatinOffset: 3,
@@ -6942,9 +7114,10 @@
 		{0x0275, 0x027d, 8},
 		{0x0280, 0x0283, 3},
 		{0x0287, 0x028c, 1},
-		{0x0292, 0x029e, 12},
-		{0x0345, 0x0371, 44},
-		{0x0373, 0x037b, 4},
+		{0x0292, 0x029d, 11},
+		{0x029e, 0x0345, 167},
+		{0x0371, 0x0373, 2},
+		{0x0377, 0x037b, 4},
 		{0x037c, 0x037d, 1},
 		{0x03ac, 0x03af, 1},
 		{0x03b1, 0x03ce, 1},
@@ -6959,6 +7132,7 @@
 		{0x04c2, 0x04ce, 2},
 		{0x04cf, 0x052f, 2},
 		{0x0561, 0x0586, 1},
+		{0x13f8, 0x13fd, 1},
 		{0x1d79, 0x1d7d, 4},
 		{0x1e01, 0x1e95, 2},
 		{0x1e9b, 0x1ea1, 6},
@@ -6994,10 +7168,14 @@
 		{0xa78c, 0xa791, 5},
 		{0xa793, 0xa797, 4},
 		{0xa799, 0xa7a9, 2},
+		{0xa7b5, 0xa7b7, 2},
+		{0xab53, 0xab70, 29},
+		{0xab71, 0xabbf, 1},
 		{0xff41, 0xff5a, 1},
 	},
 	R32: []Range32{
 		{0x10428, 0x1044f, 1},
+		{0x10cc0, 0x10cf2, 1},
 		{0x118c0, 0x118df, 1},
 	},
 	LatinOffset: 4,
@@ -7023,7 +7201,7 @@
 // If there is no entry for a script name, there are no such points.
 var FoldScript = map[string]*RangeTable{}
 
-// Range entries: 3532 16-bit, 1204 32-bit, 4736 total.
-// Range bytes: 21192 16-bit, 14448 32-bit, 35640 total.
+// Range entries: 3546 16-bit, 1306 32-bit, 4852 total.
+// Range bytes: 21276 16-bit, 15672 32-bit, 36948 total.
 
 // Fold orbit bytes: 63 pairs, 252 bytes
diff --git a/third_party/gofrontend/libgo/go/unicode/utf16/utf16.go b/third_party/gofrontend/libgo/go/unicode/utf16/utf16.go
index c0e47c5..b497500 100644
--- a/third_party/gofrontend/libgo/go/unicode/utf16/utf16.go
+++ b/third_party/gofrontend/libgo/go/unicode/utf16/utf16.go
@@ -25,7 +25,7 @@
 	surrSelf = 0x10000
 )
 
-// IsSurrogate returns true if the specified Unicode code point
+// IsSurrogate reports whether the specified Unicode code point
 // can appear in a surrogate pair.
 func IsSurrogate(r rune) bool {
 	return surr1 <= r && r < surr3
diff --git a/third_party/gofrontend/libgo/merge.sh b/third_party/gofrontend/libgo/merge.sh
index c79f759..24f63d9 100755
--- a/third_party/gofrontend/libgo/merge.sh
+++ b/third_party/gofrontend/libgo/merge.sh
@@ -8,7 +8,7 @@
 # into the libgo library.  This does the easy stuff; the hard stuff is
 # left to the user.
 
-# The file MERGE should hold the Mercurial revision number of the last
+# The file MERGE should hold the Git revision number of the last
 # revision which was merged into these sources.  Given that, and given
 # the current sources, we can run the usual diff3 algorithm to merge
 # all changes into our sources.
@@ -30,7 +30,7 @@
 1) ;;
 2) rev=$2 ;;
 *)
-  echo 1>&2 "merge.sh: Usage: merge.sh mercurial-repository [revision]"
+  echo 1>&2 "merge.sh: Usage: merge.sh git-repository [revision]"
   exit 1
   ;;
 esac
@@ -66,7 +66,7 @@
     else
       echo "merge.sh: ${name}: REMOVED"
       rm -f ${libgo}
-      hg rm ${libgo}
+      git rm ${libgo}
     fi
   elif test -f ${old}; then
     # The file exists in the old version.
@@ -97,7 +97,6 @@
       1)
         echo "merge.sh: $name: CONFLICTS"
         mv ${libgo}.tmp ${libgo}
-        hg resolve -u ${libgo}
         ;;
       *)
         echo 1>&2 "merge.sh: $name: diff3 failure"
@@ -118,7 +117,7 @@
         mkdir -p ${dir}
       fi
       cp ${new} ${libgo}
-      hg add ${libgo}
+      git add ${libgo}
     fi
   fi
 }
@@ -174,35 +173,6 @@
   done
 done
 
-cmdlist="cgo go gofmt"
-for c in $cmdlist; do
-  (cd ${NEWDIR}/src/cmd/$c && find . -name '*.go' -print) | while read f; do
-    oldfile=${OLDDIR}/src/cmd/$c/$f
-    newfile=${NEWDIR}/src/cmd/$c/$f
-    libgofile=go/cmd/$c/$f
-    merge $f ${oldfile} ${newfile} ${libgofile}
-  done
-
-  (cd ${NEWDIR}/src/cmd/$c && find . -name testdata -print) | while read d; do
-    oldtd=${OLDDIR}/src/cmd/$c/$d
-    newtd=${NEWDIR}/src/cmd/$c/$d
-    libgotd=go/cmd/$c/$d
-    if ! test -d ${oldtd}; then
-      continue
-    fi
-    (cd ${oldtd} && git ls-files .) | while read f; do
-      if test "`basename $f`" = ".gitignore"; then
-        continue
-      fi
-      name=$d/$f
-      oldfile=${oldtd}/$f
-      newfile=${newtd}/$f
-      libgofile=${libgotd}/$f
-      merge ${name} ${oldfile} ${newfile} ${libgofile}
-    done
-  done
-done
-
 runtime="chan.goc chan.h cpuprof.goc env_posix.c heapdump.c lock_futex.c lfstack.goc lock_sema.c mcache.c mcentral.c mfixalloc.c mgc0.c mgc0.h mheap.c msize.c netpoll.goc netpoll_epoll.c netpoll_kqueue.c netpoll_stub.c panic.c print.c proc.c race.h rdebug.goc runtime.c runtime.h signal_unix.c signal_unix.h malloc.h malloc.goc mprof.goc parfor.c runtime1.goc sema.goc sigqueue.goc string.goc time.goc"
 for f in $runtime; do
   # merge_c $f $f
@@ -224,7 +194,7 @@
   fi
   echo "merge.sh: ${libgofile}: REMOVED"
   rm -f ${libgofile}
-  hg rm ${libgofile}
+  git rm ${libgofile}
 done
 
 (echo ${new_rev}; sed -ne '2,$p' MERGE) > MERGE.tmp
diff --git a/third_party/gofrontend/libgo/mksysinfo.sh b/third_party/gofrontend/libgo/mksysinfo.sh
index a977f56..662619f 100755
--- a/third_party/gofrontend/libgo/mksysinfo.sh
+++ b/third_party/gofrontend/libgo/mksysinfo.sh
@@ -183,6 +183,12 @@
 #ifdef TIOCSCTTY
   TIOCSCTTY_val = TIOCSCTTY,
 #endif
+#ifdef TIOCGPGRP
+  TIOCGPGRP_val = TIOCGPGRP,
+#endif
+#ifdef TIOCSPGRP
+  TIOCSPGRP_val = TIOCSPGRP,
+#endif
 #ifdef TIOCGPTN
   TIOCGPTN_val = TIOCGPTN,
 #endif
@@ -201,6 +207,67 @@
 #ifdef TCSETS
   TCSETS_val = TCSETS,
 #endif
+#ifdef TUNSETIFF
+  TUNSETIFF_val = TUNSETIFF,
+#endif
+#ifdef TUNSETNOCSUM
+  TUNSETNOCSUM_val = TUNSETNOCSUM,
+#endif
+#ifdef TUNSETDEBUG
+  TUNSETDEBUG_val = TUNSETDEBUG,
+#endif
+#ifdef TUNSETPERSIST
+  TUNSETPERSIST_val = TUNSETPERSIST,
+#endif
+#ifdef TUNSETOWNER
+  TUNSETOWNER_val = TUNSETOWNER,
+#endif
+#ifdef TUNSETLINK
+  TUNSETLINK_val = TUNSETLINK,
+#endif
+#ifdef TUNSETGROUP
+  TUNSETGROUP_val = TUNSETGROUP,
+#endif
+#ifdef TUNGETFEATURES
+  TUNGETFEATURES_val = TUNGETFEATURES,
+#endif
+#ifdef TUNSETOFFLOAD
+  TUNSETOFFLOAD_val = TUNSETOFFLOAD,
+#endif
+#ifdef TUNSETTXFILTER
+  TUNSETTXFILTER_val = TUNSETTXFILTER,
+#endif
+#ifdef TUNGETIFF
+  TUNGETIFF_val = TUNGETIFF,
+#endif
+#ifdef TUNGETSNDBUF
+  TUNGETSNDBUF_val = TUNGETSNDBUF,
+#endif
+#ifdef TUNSETSNDBUF
+  TUNSETSNDBUF_val = TUNSETSNDBUF,
+#endif
+#ifdef TUNATTACHFILTER
+  TUNATTACHFILTER_val = TUNATTACHFILTER,
+#endif
+#ifdef TUNDETACHFILTER
+  TUNDETACHFILTER_val = TUNDETACHFILTER,
+#endif
+#ifdef TUNGETVNETHDRSZ
+  TUNGETVNETHDRSZ_val = TUNGETVNETHDRSZ,
+#endif
+#ifdef TUNSETVNETHDRSZ
+  TUNSETVNETHDRSZ_val = TUNSETVNETHDRSZ,
+#endif
+#ifdef TUNSETQUEUE
+  TUNSETQUEUE_val = TUNSETQUEUE,
+#endif
+#ifdef TUNSETIFINDEX
+  TUNSETIFINDEX_val = TUNSETIFINDEX,
+#endif
+#ifdef TUNGETFILTER
+  TUNGETFILTER_val = TUNGETFILTER,
+#endif
+
 };
 EOF
 
@@ -470,7 +537,7 @@
 # GNU/Linux specific; it should do no harm if there is no
 # _user_regs_struct.
 regs=`grep '^type _user_regs_struct struct' gen-sysinfo.go || true`
-if test "$regs" == ""; then
+if test "$regs" = ""; then
   # s390
   regs=`grep '^type __user_regs_struct struct' gen-sysinfo.go || true`
   if test "$regs" != ""; then
@@ -814,11 +881,13 @@
       -e 's/ ai_/ Ai_/g' \
     >> ${OUT}
 
-# The addrinfo flags and errors.
+# The addrinfo and nameinfo flags and errors.
 grep '^const _AI_' gen-sysinfo.go | \
   sed -e 's/^\(const \)_\(AI_[^= ]*\)\(.*\)$/\1\2 = _\2/' >> ${OUT}
 grep '^const _EAI_' gen-sysinfo.go | \
   sed -e 's/^\(const \)_\(EAI_[^= ]*\)\(.*\)$/\1\2 = _\2/' >> ${OUT}
+grep '^const _NI_' gen-sysinfo.go | \
+  sed -e 's/^\(const \)_\(NI_[^= ]*\)\(.*\)$/\1\2 = _\2/' >> ${OUT}
 
 # The passwd struct.
 grep '^type _passwd ' gen-sysinfo.go | \
@@ -830,6 +899,9 @@
 grep '^const _TIOC' gen-sysinfo.go | \
     grep -v '_val =' | \
     sed -e 's/^\(const \)_\(TIOC[^= ]*\)\(.*\)$/\1\2 = _\2/' >> ${OUT}
+grep '^const _TUNSET' gen-sysinfo.go | \
+    grep -v '_val =' | \
+    sed -e 's/^\(const \)_\(TUNSET[^= ]*\)\(.*\)$/\1\2 = _\2/' >> ${OUT}
 # We need TIOCGWINSZ.
 if ! grep '^const TIOCGWINSZ' ${OUT} >/dev/null 2>&1; then
   if grep '^const _TIOCGWINSZ_val' ${OUT} >/dev/null 2>&1; then
@@ -851,6 +923,16 @@
     echo 'const TIOCSCTTY = _TIOCSCTTY_val' >> ${OUT}
   fi
 fi
+if ! grep '^const TIOCGPGRP' ${OUT} >/dev/null 2>&1; then
+  if grep '^const _TIOCGPGRP_val' ${OUT} >/dev/null 2>&1; then
+    echo 'const TIOCGPGRP = _TIOCGPGRP_val' >> ${OUT}
+  fi
+fi
+if ! grep '^const TIOCSPGRP' ${OUT} >/dev/null 2>&1; then
+  if grep '^const _TIOCSPGRP_val' ${OUT} >/dev/null 2>&1; then
+    echo 'const TIOCSPGRP = _TIOCSPGRP_val' >> ${OUT}
+  fi
+fi
 if ! grep '^const TIOCGPTN' ${OUT} >/dev/null 2>&1; then
   if grep '^const _TIOCGPTN_val' ${OUT} >/dev/null 2>&1; then
     echo 'const TIOCGPTN = _TIOCGPTN_val' >> ${OUT}
@@ -872,6 +954,129 @@
   fi
 fi
 
+if ! grep '^const TUNSETNOCSUM' ${OUT} >/dev/null 2>&1; then
+  if grep '^const _TUNSETNOCSUM_val' ${OUT} >/dev/null 2>&1; then
+    echo 'const TUNSETNOCSUM = _TUNSETNOCSUM_val' >> ${OUT}
+  fi
+fi
+
+if ! grep '^const TUNSETDEBUG' ${OUT} >/dev/null 2>&1; then
+  if grep '^const _TUNSETDEBUG_val' ${OUT} >/dev/null 2>&1; then
+    echo 'const TUNSETDEBUG = _TUNSETDEBUG_val' >> ${OUT}
+  fi
+fi
+
+if ! grep '^const TUNSETIFF' ${OUT} >/dev/null 2>&1; then
+  if grep '^const _TUNSETIFF_val' ${OUT} >/dev/null 2>&1; then
+    echo 'const TUNSETIFF = _TUNSETIFF_val' >> ${OUT}
+  fi
+fi
+
+if ! grep '^const TUNSETPERSIST' ${OUT} >/dev/null 2>&1; then
+  if grep '^const _TUNSETPERSIST_val' ${OUT} >/dev/null 2>&1; then
+    echo 'const TUNSETPERSIST = _TUNSETPERSIST_val' >> ${OUT}
+  fi
+fi
+
+if ! grep '^const TUNSETOWNER' ${OUT} >/dev/null 2>&1; then
+  if grep '^const _TUNSETOWNER_val' ${OUT} >/dev/null 2>&1; then
+    echo 'const TUNSETOWNER = _TUNSETOWNER_val' >> ${OUT}
+  fi
+fi
+
+if ! grep '^const TUNSETLINK' ${OUT} >/dev/null 2>&1; then
+  if grep '^const _TUNSETLINK_val' ${OUT} >/dev/null 2>&1; then
+    echo 'const TUNSETLINK = _TUNSETLINK_val' >> ${OUT}
+  fi
+fi
+
+if ! grep '^const TUNSETGROUP' ${OUT} >/dev/null 2>&1; then
+  if grep '^const _TUNSETGROUP_val' ${OUT} >/dev/null 2>&1; then
+    echo 'const TUNSETGROUP = _TUNSETGROUP_val' >> ${OUT}
+  fi
+fi
+
+if ! grep '^const TUNGETFEATURES' ${OUT} >/dev/null 2>&1; then
+  if grep '^const _TUNGETFEATURES_val' ${OUT} >/dev/null 2>&1; then
+    echo 'const TUNGETFEATURES = _TUNGETFEATURES_val' >> ${OUT}
+  fi
+fi
+
+if ! grep '^const TUNSETOFFLOAD' ${OUT} >/dev/null 2>&1; then
+  if grep '^const _TUNSETOFFLOAD_val' ${OUT} >/dev/null 2>&1; then
+    echo 'const TUNSETOFFLOAD = _TUNSETOFFLOAD_val' >> ${OUT}
+  fi
+fi
+
+if ! grep '^const TUNSETTXFILTER' ${OUT} >/dev/null 2>&1; then
+  if grep '^const _TUNSETTXFILTER_val' ${OUT} >/dev/null 2>&1; then
+    echo 'const TUNSETTXFILTER = _TUNSETTXFILTER_val' >> ${OUT}
+  fi
+fi
+
+if ! grep '^const TUNGETIFF' ${OUT} >/dev/null 2>&1; then
+  if grep '^const _TUNGETIFF_val' ${OUT} >/dev/null 2>&1; then
+    echo 'const TUNGETIFF = _TUNGETIFF_val' >> ${OUT}
+  fi
+fi
+
+if ! grep '^const TUNGETSNDBUF' ${OUT} >/dev/null 2>&1; then
+  if grep '^const _TUNGETSNDBUF_val' ${OUT} >/dev/null 2>&1; then
+    echo 'const TUNGETSNDBUF = _TUNGETSNDBUF_val' >> ${OUT}
+  fi
+fi
+
+if ! grep '^const TUNSETSNDBUF' ${OUT} >/dev/null 2>&1; then
+  if grep '^const _TUNSETSNDBUF_val' ${OUT} >/dev/null 2>&1; then
+    echo 'const TUNSETSNDBUF = _TUNSETSNDBUF_val' >> ${OUT}
+  fi
+fi
+
+if ! grep '^const TUNATTACHFILTER' ${OUT} >/dev/null 2>&1; then
+  if grep '^const _TUNATTACHFILTER_val' ${OUT} >/dev/null 2>&1; then
+    echo 'const TUNATTACHFILTER = _TUNATTACHFILTER_val' >> ${OUT}
+  fi
+fi
+
+if ! grep '^const TUNDETACHFILTER' ${OUT} >/dev/null 2>&1; then
+  if grep '^const _TUNDETACHFILTER_val' ${OUT} >/dev/null 2>&1; then
+    echo 'const TUNDETACHFILTER = _TUNDETACHFILTER_val' >> ${OUT}
+  fi
+fi
+
+if ! grep '^const TUNGETVNETHDRSZ' ${OUT} >/dev/null 2>&1; then
+  if grep '^const _TUNGETVNETHDRSZ_val' ${OUT} >/dev/null 2>&1; then
+    echo 'const TUNGETVNETHDRSZ = _TUNGETVNETHDRSZ_val' >> ${OUT}
+  fi
+fi
+
+if ! grep '^const TUNSETVNETHDRSZ' ${OUT} >/dev/null 2>&1; then
+  if grep '^const _TUNSETVNETHDRSZ_val' ${OUT} >/dev/null 2>&1; then
+    echo 'const TUNSETVNETHDRSZ = _TUNSETVNETHDRSZ_val' >> ${OUT}
+  fi
+fi
+
+if ! grep '^const TUNSETQUEUE' ${OUT} >/dev/null 2>&1; then
+  if grep '^const _TUNSETQUEUE_val' ${OUT} >/dev/null 2>&1; then
+    echo 'const TUNSETQUEUE = _TUNSETQUEUE_val' >> ${OUT}
+  fi
+fi
+
+
+if ! grep '^const TUNSETIFINDEX' ${OUT} >/dev/null 2>&1; then
+  if grep '^const _TUNSETIFINDEX_val' ${OUT} >/dev/null 2>&1; then
+    echo 'const TUNSETIFINDEX = _TUNSETIFINDEX_val' >> ${OUT}
+  fi
+fi
+
+if ! grep '^const TUNGETFILTER' ${OUT} >/dev/null 2>&1; then
+  if grep '^const _TUNGETFILTER_val' ${OUT} >/dev/null 2>&1; then
+    echo 'const TUNGETFILTER = _TUNGETFILTER_val' >> ${OUT}
+  fi
+fi
+
+
+
 # The ioctl flags for terminal control
 grep '^const _TC[GS]ET' gen-sysinfo.go | grep -v _val | \
     sed -e 's/^\(const \)_\(TC[GS]ET[^= ]*\)\(.*\)$/\1\2 = _\2/' >> ${OUT}
@@ -1239,6 +1444,11 @@
 # The GNU/Linux CLONE flags.
 grep '^const _CLONE_' gen-sysinfo.go | \
   sed -e 's/^\(const \)_\(CLONE_[^= ]*\)\(.*\)$/\1\2 = _\2/' >> ${OUT}
+# We need some CLONE constants that are not defined in older versions
+# of glibc.
+if ! grep '^const CLONE_NEWUSER ' ${OUT} > /dev/null 2>&1; then
+  echo "const CLONE_NEWUSER = 0x10000000" >> ${OUT}
+fi
 
 # Struct sizes.
 set cmsghdr Cmsghdr ip_mreq IPMreq ip_mreqn IPMreqn ipv6_mreq IPv6Mreq \
@@ -1273,4 +1483,29 @@
     echo 'const SizeofICMPv6Filter = 32' >> ${OUT}
 fi
 
+# The Solaris 11 Update 1 _zone_net_addr_t struct.
+grep '^type _zone_net_addr_t ' gen-sysinfo.go | \
+    sed -e 's/_in6_addr/[16]byte/' \
+    >> ${OUT}
+
+# The Solaris 12 _flow_arp_desc_t struct.
+grep '^type _flow_arp_desc_t ' gen-sysinfo.go | \
+    sed -e 's/_in6_addr_t/[16]byte/g' \
+    >> ${OUT}
+
+# The Solaris 12 _flow_l3_desc_t struct.
+grep '^type _flow_l3_desc_t ' gen-sysinfo.go | \
+    sed -e 's/_in6_addr_t/[16]byte/g' \
+    >> ${OUT}
+
+# The Solaris 12 _mac_ipaddr_t struct.
+grep '^type _mac_ipaddr_t ' gen-sysinfo.go | \
+    sed -e 's/_in6_addr_t/[16]byte/g' \
+    >> ${OUT}
+
+# The Solaris 12 _mactun_info_t struct.
+grep '^type _mactun_info_t ' gen-sysinfo.go | \
+    sed -e 's/_in6_addr_t/[16]byte/g' \
+    >> ${OUT}
+
 exit $?
diff --git a/third_party/gofrontend/libgo/runtime/env_posix.c b/third_party/gofrontend/libgo/runtime/env_posix.c
index ee3e451..b93edd6 100644
--- a/third_party/gofrontend/libgo/runtime/env_posix.c
+++ b/third_party/gofrontend/libgo/runtime/env_posix.c
@@ -11,7 +11,7 @@
 
 extern Slice envs;
 
-const byte*
+String
 runtime_getenv(const char *s)
 {
 	int32 i, j;
@@ -19,6 +19,7 @@
 	const byte *v, *bs;
 	String* envv;
 	int32 envc;
+	String ret;
 
 	bs = (const byte*)s;
 	len = runtime_findnull(bs);
@@ -33,8 +34,12 @@
 				goto nomatch;
 		if(v[len] != '=')
 			goto nomatch;
-		return v+len+1;
+		ret.str = v+len+1;
+		ret.len = envv[i].len-len-1;
+		return ret;
 	nomatch:;
 	}
-	return nil;
+	ret.str = nil;
+	ret.len = 0;
+	return ret;
 }
diff --git a/third_party/gofrontend/libgo/runtime/go-caller.c b/third_party/gofrontend/libgo/runtime/go-caller.c
index ad151ec..d6901e0 100644
--- a/third_party/gofrontend/libgo/runtime/go-caller.c
+++ b/third_party/gofrontend/libgo/runtime/go-caller.c
@@ -166,7 +166,7 @@
 
   runtime_memclr (&ret, sizeof ret);
   n = runtime_callers (skip + 1, &loc, 1, false);
-  if (n < 1)
+  if (n < 1 || loc.pc == 0)
     return ret;
   ret.pc = loc.pc;
   ret.file = loc.filename;
@@ -231,6 +231,8 @@
 String
 runtime_funcname_go (Func *f)
 {
+  if (f == NULL)
+    return runtime_gostringnocopy ((const byte *) "");
   return f->name;
 }
 
diff --git a/third_party/gofrontend/libgo/runtime/go-callers.c b/third_party/gofrontend/libgo/runtime/go-callers.c
index 34a2118..b5ab3be 100644
--- a/third_party/gofrontend/libgo/runtime/go-callers.c
+++ b/third_party/gofrontend/libgo/runtime/go-callers.c
@@ -83,7 +83,20 @@
     }
 
   loc = &arg->locbuf[arg->index];
-  loc->pc = pc;
+
+  /* On the call to backtrace_full the pc value was most likely
+     decremented if there was a normal call, since the pc referred to
+     the instruction where the call returned and not the call itself.
+     This was done so that the line number referred to the call
+     instruction.  To make sure the actual pc from the call stack is
+     used, it is incremented here.
+
+     In the case of a signal, the pc was not decremented by
+     backtrace_full but still incremented here.  That doesn't really
+     hurt anything since the line number is right and the pc refers to
+     the same instruction.  */
+
+  loc->pc = pc + 1;
 
   /* The libbacktrace library says that these strings might disappear,
      but with the current implementation they won't.  We can't easily
diff --git a/third_party/gofrontend/libgo/runtime/go-cgo.c b/third_party/gofrontend/libgo/runtime/go-cgo.c
index 2b7baa4..a36eac9 100644
--- a/third_party/gofrontend/libgo/runtime/go-cgo.c
+++ b/third_party/gofrontend/libgo/runtime/go-cgo.c
@@ -8,6 +8,9 @@
 #include "go-alloc.h"
 #include "interface.h"
 #include "go-panic.h"
+#include "go-type.h"
+
+extern void __go_receive (ChanType *, Hchan *, byte *);
 
 /* Prepare to call from code written in Go to code written in C or
    C++.  This takes the current goroutine out of the Go scheduler, as
@@ -86,6 +89,15 @@
 
   runtime_exitsyscall ();
 
+  if (runtime_g ()->ncgo == 0)
+    {
+      /* The C call to Go came from a thread not currently running any
+	 Go.  In the case of -buildmode=c-archive or c-shared, this
+	 call may be coming in before package initialization is
+	 complete.  Wait until it is.  */
+      __go_receive (NULL, runtime_main_init_done, NULL);
+    }
+
   mp = runtime_m ();
   if (mp->needextram)
     {
@@ -177,3 +189,65 @@
 
   __go_panic (e);
 }
+
+/* Used for _cgo_wait_runtime_init_done.  This is based on code in
+   runtime/cgo/gcc_libinit.c in the master library.  */
+
+static pthread_cond_t runtime_init_cond = PTHREAD_COND_INITIALIZER;
+static pthread_mutex_t runtime_init_mu = PTHREAD_MUTEX_INITIALIZER;
+static _Bool runtime_init_done;
+
+/* This is called by exported cgo functions to ensure that the runtime
+   has been initialized before we enter the function.  This is needed
+   when building with -buildmode=c-archive or similar.  */
+
+void
+_cgo_wait_runtime_init_done (void)
+{
+  int err;
+
+  if (__atomic_load_n (&runtime_init_done, __ATOMIC_ACQUIRE))
+    return;
+
+  err = pthread_mutex_lock (&runtime_init_mu);
+  if (err != 0)
+    abort ();
+  while (!__atomic_load_n (&runtime_init_done, __ATOMIC_ACQUIRE))
+    {
+      err = pthread_cond_wait (&runtime_init_cond, &runtime_init_mu);
+      if (err != 0)
+	abort ();
+    }
+  err = pthread_mutex_unlock (&runtime_init_mu);
+  if (err != 0)
+    abort ();
+}
+
+/* This is called by runtime_main after the Go runtime is
+   initialized.  */
+
+void
+_cgo_notify_runtime_init_done (void)
+{
+  int err;
+
+  err = pthread_mutex_lock (&runtime_init_mu);
+  if (err != 0)
+    abort ();
+  __atomic_store_n (&runtime_init_done, 1, __ATOMIC_RELEASE);
+  err = pthread_cond_broadcast (&runtime_init_cond);
+  if (err != 0)
+    abort ();
+  err = pthread_mutex_unlock (&runtime_init_mu);
+  if (err != 0)
+    abort ();
+}
+
+// runtime_iscgo is set to true if some cgo code is linked in.
+// This is done by a constructor in the cgo generated code.
+_Bool runtime_iscgo;
+
+// runtime_cgoHasExtraM is set on startup when an extra M is created
+// for cgo.  The extra M must be created before any C/C++ code calls
+// cgocallback.
+_Bool runtime_cgoHasExtraM;
diff --git a/third_party/gofrontend/libgo/runtime/go-eface-compare.c b/third_party/gofrontend/libgo/runtime/go-eface-compare.c
index 3555a65..40b716e 100644
--- a/third_party/gofrontend/libgo/runtime/go-eface-compare.c
+++ b/third_party/gofrontend/libgo/runtime/go-eface-compare.c
@@ -28,8 +28,8 @@
     return 1;
   if (__go_is_pointer_type (left_descriptor))
     return left.__object == right.__object ? 0 : 1;
-  if (!left_descriptor->__equalfn (left.__object, right.__object,
-				   left_descriptor->__size))
+  if (!__go_call_equalfn (left_descriptor->__equalfn, left.__object,
+			  right.__object, left_descriptor->__size))
     return 1;
   return 0;
 }
diff --git a/third_party/gofrontend/libgo/runtime/go-eface-val-compare.c b/third_party/gofrontend/libgo/runtime/go-eface-val-compare.c
index 743f126..e810750 100644
--- a/third_party/gofrontend/libgo/runtime/go-eface-val-compare.c
+++ b/third_party/gofrontend/libgo/runtime/go-eface-val-compare.c
@@ -26,8 +26,8 @@
     return 1;
   if (__go_is_pointer_type (left_descriptor))
     return left.__object == val ? 0 : 1;
-  if (!left_descriptor->__equalfn (left.__object, val,
-				   left_descriptor->__size))
+  if (!__go_call_equalfn (left_descriptor->__equalfn, left.__object, val,
+			  left_descriptor->__size))
     return 1;
   return 0;
 }
diff --git a/third_party/gofrontend/libgo/runtime/go-interface-compare.c b/third_party/gofrontend/libgo/runtime/go-interface-compare.c
index 6374bd2..1d36775 100644
--- a/third_party/gofrontend/libgo/runtime/go-interface-compare.c
+++ b/third_party/gofrontend/libgo/runtime/go-interface-compare.c
@@ -28,8 +28,8 @@
     return 1;
   if (__go_is_pointer_type (left_descriptor))
     return left.__object == right.__object ? 0 : 1;
-  if (!left_descriptor->__equalfn (left.__object, right.__object,
-				   left_descriptor->__size))
+  if (!__go_call_equalfn (left_descriptor->__equalfn, left.__object,
+			  right.__object, left_descriptor->__size))
     return 1;
   return 0;
 }
diff --git a/third_party/gofrontend/libgo/runtime/go-interface-eface-compare.c b/third_party/gofrontend/libgo/runtime/go-interface-eface-compare.c
index a38917f..d1e6fd0 100644
--- a/third_party/gofrontend/libgo/runtime/go-interface-eface-compare.c
+++ b/third_party/gofrontend/libgo/runtime/go-interface-eface-compare.c
@@ -27,8 +27,8 @@
     return 1;
   if (__go_is_pointer_type (left_descriptor))
     return left.__object == right.__object ? 0 : 1;
-  if (!left_descriptor->__equalfn (left.__object, right.__object,
-				   left_descriptor->__size))
+  if (!__go_call_equalfn (left_descriptor->__equalfn, left.__object,
+			  right.__object, left_descriptor->__size))
     return 1;
   return 0;
 }
diff --git a/third_party/gofrontend/libgo/runtime/go-interface-val-compare.c b/third_party/gofrontend/libgo/runtime/go-interface-val-compare.c
index e2dae6a..36b6efd 100644
--- a/third_party/gofrontend/libgo/runtime/go-interface-val-compare.c
+++ b/third_party/gofrontend/libgo/runtime/go-interface-val-compare.c
@@ -26,8 +26,8 @@
     return 1;
   if (__go_is_pointer_type (left_descriptor))
     return left.__object == val ? 0 : 1;
-  if (!left_descriptor->__equalfn (left.__object, val,
-				   left_descriptor->__size))
+  if (!__go_call_equalfn (left_descriptor->__equalfn, left.__object, val,
+			  left_descriptor->__size))
     return 1;
   return 0;
 }
diff --git a/third_party/gofrontend/libgo/runtime/go-libmain.c b/third_party/gofrontend/libgo/runtime/go-libmain.c
new file mode 100644
index 0000000..f578aab
--- /dev/null
+++ b/third_party/gofrontend/libgo/runtime/go-libmain.c
@@ -0,0 +1,114 @@
+/* go-libmain.c -- the startup function for a Go library.
+
+   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.  */
+
+#include "config.h"
+
+#include <errno.h>
+#include <pthread.h>
+#include <stdlib.h>
+#include <time.h>
+#include <unistd.h>
+
+#include "runtime.h"
+#include "go-alloc.h"
+#include "array.h"
+#include "arch.h"
+#include "malloc.h"
+
+/* This is used when building a standalone Go library using the Go
+   command's -buildmode=c-archive or -buildmode=c-shared option.  It
+   starts up the Go code as a global constructor but does not take any
+   other action.  The main program is written in some other language
+   and calls exported Go functions as needed.  */
+
+static void die (const char *, int);
+static void initfn (int, char **, char **);
+static void *gostart (void *);
+
+/* Used to pass arguments to the thread that runs the Go startup.  */
+
+struct args {
+  int argc;
+  char **argv;
+};
+
+/* We use .init_array so that we can get the command line arguments.
+   This obviously assumes .init_array support; different systems may
+   require other approaches.  */
+
+typedef void (*initarrayfn) (int, char **, char **);
+
+static initarrayfn initarray[1]
+__attribute__ ((section (".init_array"), used)) =
+  { initfn };
+
+/* This function is called at program startup time.  It starts a new
+   thread to do the actual Go startup, so that program startup is not
+   paused waiting for the Go initialization functions.  Exported cgo
+   functions will wait for initialization to complete if
+   necessary.  */
+
+static void
+initfn (int argc, char **argv, char** env __attribute__ ((unused)))
+{
+  int err;
+  pthread_attr_t attr;
+  struct args *a;
+  pthread_t tid;
+
+  a = (struct args *) malloc (sizeof *a);
+  if (a == NULL)
+    die ("malloc", errno);
+  a->argc = argc;
+  a->argv = argv;
+
+  err = pthread_attr_init (&attr);
+  if (err != 0)
+    die ("pthread_attr_init", err);
+  err = pthread_attr_setdetachstate (&attr, PTHREAD_CREATE_DETACHED);
+  if (err != 0)
+    die ("pthread_attr_setdetachstate", err);
+
+  err = pthread_create (&tid, &attr, gostart, (void *) a);
+  if (err != 0)
+    die ("pthread_create", err);
+
+  err = pthread_attr_destroy (&attr);
+  if (err != 0)
+    die ("pthread_attr_destroy", err);
+}
+
+/* Start up the Go runtime.  */
+
+static void *
+gostart (void *arg)
+{
+  struct args *a = (struct args *) arg;
+
+  runtime_isarchive = true;
+
+  if (runtime_isstarted)
+    return NULL;
+  runtime_isstarted = true;
+
+  runtime_check ();
+  runtime_args (a->argc, (byte **) a->argv);
+  runtime_osinit ();
+  runtime_schedinit ();
+  __go_go (runtime_main, NULL);
+  runtime_mstart (runtime_m ());
+  abort ();
+}
+
+/* If something goes wrong during program startup, crash.  There is no
+   way to report failure and nobody to whom to report it.  */
+
+static void
+die (const char *fn, int err)
+{
+  fprintf (stderr, "%s: %d\n", fn, err);
+  exit (EXIT_FAILURE);
+}
diff --git a/third_party/gofrontend/libgo/runtime/go-main.c b/third_party/gofrontend/libgo/runtime/go-main.c
index 77233d3..026469b 100644
--- a/third_party/gofrontend/libgo/runtime/go-main.c
+++ b/third_party/gofrontend/libgo/runtime/go-main.c
@@ -35,6 +35,12 @@
 int
 main (int argc, char **argv)
 {
+  runtime_isarchive = false;
+
+  if (runtime_isstarted)
+    return 0;
+  runtime_isstarted = true;
+
   runtime_check ();
   runtime_args (argc, (byte **) argv);
   runtime_osinit ();
diff --git a/third_party/gofrontend/libgo/runtime/go-map-delete.c b/third_party/gofrontend/libgo/runtime/go-map-delete.c
index aff25d1..fb7c331 100644
--- a/third_party/gofrontend/libgo/runtime/go-map-delete.c
+++ b/third_party/gofrontend/libgo/runtime/go-map-delete.c
@@ -21,7 +21,7 @@
   const struct __go_map_descriptor *descriptor;
   const struct __go_type_descriptor *key_descriptor;
   uintptr_t key_offset;
-  _Bool (*equalfn) (const void*, const void*, uintptr_t);
+  const FuncVal *equalfn;
   size_t key_hash;
   size_t key_size;
   size_t bucket_index;
@@ -41,14 +41,14 @@
   __go_assert (key_size != -1UL);
   equalfn = key_descriptor->__equalfn;
 
-  key_hash = key_descriptor->__hashfn (key, key_size);
+  key_hash = __go_call_hashfn (key_descriptor->__hashfn, key, key_size);
   bucket_index = key_hash % map->__bucket_count;
 
   pentry = map->__buckets + bucket_index;
   while (*pentry != NULL)
     {
       char *entry = (char *) *pentry;
-      if (equalfn (key, entry + key_offset, key_size))
+      if (__go_call_equalfn (equalfn, key, entry + key_offset, key_size))
 	{
 	  *pentry = *(void **) entry;
 	  if (descriptor->__entry_size >= TinySize)
diff --git a/third_party/gofrontend/libgo/runtime/go-map-index.c b/third_party/gofrontend/libgo/runtime/go-map-index.c
index 616b00c..353041d 100644
--- a/third_party/gofrontend/libgo/runtime/go-map-index.c
+++ b/third_party/gofrontend/libgo/runtime/go-map-index.c
@@ -22,7 +22,7 @@
   const struct __go_type_descriptor *key_descriptor;
   uintptr_t key_offset;
   size_t key_size;
-  uintptr_t (*hashfn) (const void *, uintptr_t);
+  const FuncVal *hashfn;
   uintptr_t old_bucket_count;
   void **old_buckets;
   uintptr_t new_bucket_count;
@@ -55,7 +55,7 @@
 
 	  /* We could speed up rehashing at the cost of memory space
 	     by caching the hash code.  */
-	  key_hash = hashfn (entry + key_offset, key_size);
+	  key_hash = __go_call_hashfn (hashfn, entry + key_offset, key_size);
 	  new_bucket_index = key_hash % new_bucket_count;
 
 	  next = *(char **) entry;
@@ -82,7 +82,7 @@
   const struct __go_map_descriptor *descriptor;
   const struct __go_type_descriptor *key_descriptor;
   uintptr_t key_offset;
-  _Bool (*equalfn) (const void*, const void*, uintptr_t);
+  const FuncVal *equalfn;
   size_t key_hash;
   size_t key_size;
   size_t bucket_index;
@@ -103,13 +103,13 @@
   __go_assert (key_size != -1UL);
   equalfn = key_descriptor->__equalfn;
 
-  key_hash = key_descriptor->__hashfn (key, key_size);
+  key_hash = __go_call_hashfn (key_descriptor->__hashfn, key, key_size);
   bucket_index = key_hash % map->__bucket_count;
 
   entry = (char *) map->__buckets[bucket_index];
   while (entry != NULL)
     {
-      if (equalfn (key, entry + key_offset, key_size))
+      if (__go_call_equalfn (equalfn, key, entry + key_offset, key_size))
 	return entry + descriptor->__val_offset;
       entry = *(char **) entry;
     }
diff --git a/third_party/gofrontend/libgo/runtime/go-new.c b/third_party/gofrontend/libgo/runtime/go-new.c
index dad6efb..01bc2af 100644
--- a/third_party/gofrontend/libgo/runtime/go-new.c
+++ b/third_party/gofrontend/libgo/runtime/go-new.c
@@ -8,19 +8,12 @@
 #include "runtime.h"
 #include "arch.h"
 #include "malloc.h"
+#include "go-type.h"
 
 void *
 __go_new (const struct __go_type_descriptor *td, uintptr_t size)
 {
   return runtime_mallocgc (size,
 			   (uintptr) td | TypeInfo_SingleObject,
-			   0);
-}
-
-void *
-__go_new_nopointers (const struct __go_type_descriptor *td,  uintptr_t size)
-{
-  return runtime_mallocgc (size,
-			   (uintptr) td | TypeInfo_SingleObject,
-			   FlagNoScan);
+			   td->__code & GO_NO_POINTERS ? FlagNoScan : 0);
 }
diff --git a/third_party/gofrontend/libgo/runtime/go-now.c b/third_party/gofrontend/libgo/runtime/go-now.c
index ea8d070..d24e6ee 100644
--- a/third_party/gofrontend/libgo/runtime/go-now.c
+++ b/third_party/gofrontend/libgo/runtime/go-now.c
@@ -13,11 +13,11 @@
 struct time_now_ret
 now()
 {
-  struct timeval tv;
+  struct timespec ts;
   struct time_now_ret ret;
 
-  gettimeofday (&tv, NULL);
-  ret.sec = tv.tv_sec;
-  ret.nsec = tv.tv_usec * 1000;
+  clock_gettime (CLOCK_REALTIME, &ts);
+  ret.sec = ts.tv_sec;
+  ret.nsec = ts.tv_nsec;
   return ret;
 }
diff --git a/third_party/gofrontend/libgo/runtime/go-reflect-call.c b/third_party/gofrontend/libgo/runtime/go-reflect-call.c
index 29e814a..2a14d6c 100644
--- a/third_party/gofrontend/libgo/runtime/go-reflect-call.c
+++ b/third_party/gofrontend/libgo/runtime/go-reflect-call.c
@@ -81,6 +81,12 @@
 
   off = (off + maxalign - 1) & ~ (maxalign - 1);
 
+  // The libffi library doesn't understand a struct with no fields.
+  // We generate a struct with a single field of type void.  When used
+  // as a return value, libffi will think that requires a byte.
+  if (off == 0)
+    off = 1;
+
   return off;
 }
 
diff --git a/third_party/gofrontend/libgo/runtime/go-reflect-map.c b/third_party/gofrontend/libgo/runtime/go-reflect-map.c
index 58e1b34..36f3102 100644
--- a/third_party/gofrontend/libgo/runtime/go-reflect-map.c
+++ b/third_party/gofrontend/libgo/runtime/go-reflect-map.c
@@ -151,5 +151,6 @@
 _Bool
 ismapkey (const struct __go_type_descriptor *typ)
 {
-  return typ != NULL && typ->__hashfn != __go_type_hash_error;
+  return (typ != NULL
+	  && (void *) typ->__hashfn->fn != (void *) __go_type_hash_error);
 }
diff --git a/third_party/gofrontend/libgo/runtime/go-type-complex.c b/third_party/gofrontend/libgo/runtime/go-type-complex.c
index 0f8f062..585984e 100644
--- a/third_party/gofrontend/libgo/runtime/go-type-complex.c
+++ b/third_party/gofrontend/libgo/runtime/go-type-complex.c
@@ -84,6 +84,9 @@
     runtime_throw ("__go_type_hash_complex: invalid complex size");
 }
 
+const FuncVal __go_type_hash_complex_descriptor =
+  { (void *) __go_type_hash_complex };
+
 /* Equality function for complex types.  */
 
 _Bool
@@ -112,3 +115,6 @@
   else
     runtime_throw ("__go_type_equal_complex: invalid complex size");
 }
+
+const FuncVal __go_type_equal_complex_descriptor =
+  { (void *) __go_type_equal_complex };
diff --git a/third_party/gofrontend/libgo/runtime/go-type-eface.c b/third_party/gofrontend/libgo/runtime/go-type-eface.c
index 30614d2..315c30e 100644
--- a/third_party/gofrontend/libgo/runtime/go-type-eface.c
+++ b/third_party/gofrontend/libgo/runtime/go-type-eface.c
@@ -24,11 +24,14 @@
     return 0;
   size = descriptor->__size;
   if (__go_is_pointer_type (descriptor))
-    return descriptor->__hashfn (&val->__object, size);
+    return __go_call_hashfn (descriptor->__hashfn, &val->__object, size);
   else
-    return descriptor->__hashfn (val->__object, size);
+    return __go_call_hashfn (descriptor->__hashfn, val->__object, size);
 }
 
+const FuncVal __go_type_hash_empty_interface_descriptor =
+  { (void *) __go_type_hash_empty_interface };
+
 /* An equality function for an empty interface.  */
 
 _Bool
@@ -51,6 +54,9 @@
   if (__go_is_pointer_type (v1_descriptor))
     return v1->__object == v2->__object;
   else
-    return v1_descriptor->__equalfn (v1->__object, v2->__object,
-				     v1_descriptor->__size);
+    return __go_call_equalfn (v1_descriptor->__equalfn, v1->__object,
+			      v2->__object, v1_descriptor->__size);
 }
+
+const FuncVal __go_type_equal_empty_interface_descriptor =
+  { (void *) __go_type_equal_empty_interface };
diff --git a/third_party/gofrontend/libgo/runtime/go-type-error.c b/third_party/gofrontend/libgo/runtime/go-type-error.c
index b4c609b..8881a86 100644
--- a/third_party/gofrontend/libgo/runtime/go-type-error.c
+++ b/third_party/gofrontend/libgo/runtime/go-type-error.c
@@ -17,6 +17,9 @@
   runtime_panicstring ("hash of unhashable type");
 }
 
+const FuncVal __go_type_hash_error_descriptor =
+  { (void *) __go_type_hash_error };
+
 /* An equality function for an interface.  */
 
 _Bool
@@ -26,3 +29,6 @@
 {
   runtime_panicstring ("comparing uncomparable types");
 }
+
+const FuncVal __go_type_equal_error_descriptor =
+  { (void *) __go_type_equal_error };
diff --git a/third_party/gofrontend/libgo/runtime/go-type-float.c b/third_party/gofrontend/libgo/runtime/go-type-float.c
index 4ae7347..39f9b29 100644
--- a/third_party/gofrontend/libgo/runtime/go-type-float.c
+++ b/third_party/gofrontend/libgo/runtime/go-type-float.c
@@ -56,6 +56,9 @@
     runtime_throw ("__go_type_hash_float: invalid float size");
 }
 
+const FuncVal __go_type_hash_float_descriptor =
+  { (void *) __go_type_hash_float };
+
 /* Equality function for float types.  */
 
 _Bool
@@ -84,3 +87,6 @@
   else
     runtime_throw ("__go_type_equal_float: invalid float size");
 }
+
+const FuncVal __go_type_equal_float_descriptor =
+  { (void *) __go_type_equal_float };
diff --git a/third_party/gofrontend/libgo/runtime/go-type-identity.c b/third_party/gofrontend/libgo/runtime/go-type-identity.c
index ed510f7..a334d56 100644
--- a/third_party/gofrontend/libgo/runtime/go-type-identity.c
+++ b/third_party/gofrontend/libgo/runtime/go-type-identity.c
@@ -45,6 +45,9 @@
   return ret;
 }
 
+const FuncVal __go_type_hash_identity_descriptor =
+  { (void *) __go_type_hash_identity };
+
 /* An identity equality function for a type.  This is used for types
    where we can check for equality by checking that the values have
    the same bits.  */
@@ -54,3 +57,6 @@
 {
   return __builtin_memcmp (k1, k2, key_size) == 0;
 }
+
+const FuncVal __go_type_equal_identity_descriptor =
+  { (void *) __go_type_equal_identity };
diff --git a/third_party/gofrontend/libgo/runtime/go-type-interface.c b/third_party/gofrontend/libgo/runtime/go-type-interface.c
index 9aad720..e9e5779 100644
--- a/third_party/gofrontend/libgo/runtime/go-type-interface.c
+++ b/third_party/gofrontend/libgo/runtime/go-type-interface.c
@@ -24,11 +24,14 @@
   descriptor = (const struct __go_type_descriptor *) val->__methods[0];
   size = descriptor->__size;
   if (__go_is_pointer_type (descriptor))
-    return descriptor->__hashfn (&val->__object, size);
+    return __go_call_hashfn (descriptor->__hashfn, &val->__object, size);
   else
-    return descriptor->__hashfn (val->__object, size);
+    return __go_call_hashfn (descriptor->__hashfn, val->__object, size);
 }
 
+const FuncVal __go_type_hash_interface_descriptor =
+  { (void *) __go_type_hash_interface };
+
 /* An equality function for an interface.  */
 
 _Bool
@@ -51,6 +54,9 @@
   if (__go_is_pointer_type (v1_descriptor))
     return v1->__object == v2->__object;
   else
-    return v1_descriptor->__equalfn (v1->__object, v2->__object,
-				     v1_descriptor->__size);
+    return __go_call_equalfn (v1_descriptor->__equalfn, v1->__object,
+			      v2->__object, v1_descriptor->__size);
 }
+
+const FuncVal __go_type_equal_interface_descriptor =
+  { (void *) __go_type_equal_interface };
diff --git a/third_party/gofrontend/libgo/runtime/go-type-string.c b/third_party/gofrontend/libgo/runtime/go-type-string.c
index a96af02..3d33d6e 100644
--- a/third_party/gofrontend/libgo/runtime/go-type-string.c
+++ b/third_party/gofrontend/libgo/runtime/go-type-string.c
@@ -28,6 +28,9 @@
   return ret;
 }
 
+const FuncVal __go_type_hash_string_descriptor =
+  { (void *) __go_type_hash_string };
+
 /* A string equality function for a map.  */
 
 _Bool
@@ -41,3 +44,6 @@
   k2 = (const String *) vk2;
   return __go_ptr_strings_equal (k1, k2);
 }
+
+const FuncVal __go_type_equal_string_descriptor =
+  { (void *) __go_type_equal_string };
diff --git a/third_party/gofrontend/libgo/runtime/go-type.h b/third_party/gofrontend/libgo/runtime/go-type.h
index d769335..eb063ec 100644
--- a/third_party/gofrontend/libgo/runtime/go-type.h
+++ b/third_party/gofrontend/libgo/runtime/go-type.h
@@ -89,11 +89,11 @@
      size of this type, and returns a hash code.  We pass the size
      explicitly becaues it means that we can share a single instance
      of this function for various different types.  */
-  uintptr_t (*__hashfn) (const void *, uintptr_t);
+  const FuncVal *__hashfn;
 
   /* This function takes two pointers to values of this type, and the
      size of this type, and returns whether the values are equal.  */
-  _Bool (*__equalfn) (const void *, const void *, uintptr_t);
+  const FuncVal *__equalfn;
 
   /* The garbage collection data. */
   const uintptr *__gc;
@@ -108,11 +108,6 @@
   /* The descriptor for the type which is a pointer to this type.
      This may be NULL.  */
   const struct __go_type_descriptor *__pointer_to_this;
-
-  /* A pointer to a zero value for this type.  All types will point to
-     the same zero value, go$zerovalue, which is a common variable so
-     that it will be large enough.  */
-  void *__zero;
 };
 
 /* The information we store for each method of a type.  */
@@ -316,21 +311,52 @@
 	  || (td->__code & GO_CODE_MASK) == GO_UNSAFE_POINTER);
 }
 
+/* Call a type hash function, given the __hashfn value.  */
+
+static inline uintptr_t
+__go_call_hashfn (const FuncVal *hashfn, const void *p, uintptr_t size)
+{
+  uintptr_t (*h) (const void *, uintptr_t) = (void *) hashfn->fn;
+  return __builtin_call_with_static_chain (h (p, size), hashfn);
+}
+
+/* Call a type equality function, given the __equalfn value.  */
+
+static inline _Bool
+__go_call_equalfn (const FuncVal *equalfn, const void *p1, const void *p2,
+		   uintptr_t size)
+{
+  _Bool (*e) (const void *, const void *, uintptr_t) = (void *) equalfn->fn;
+  return __builtin_call_with_static_chain (e (p1, p2, size), equalfn);
+}
+
 extern _Bool
 __go_type_descriptors_equal(const struct __go_type_descriptor*,
 			    const struct __go_type_descriptor*);
 
 extern uintptr_t __go_type_hash_identity (const void *, uintptr_t);
+extern const FuncVal __go_type_hash_identity_descriptor;
 extern _Bool __go_type_equal_identity (const void *, const void *, uintptr_t);
+extern const FuncVal __go_type_equal_identity_descriptor;
 extern uintptr_t __go_type_hash_string (const void *, uintptr_t);
+extern const FuncVal __go_type_hash_string_descriptor;
 extern _Bool __go_type_equal_string (const void *, const void *, uintptr_t);
+extern const FuncVal __go_type_equal_string_descriptor;
 extern uintptr_t __go_type_hash_float (const void *, uintptr_t);
+extern const FuncVal __go_type_hash_float_descriptor;
 extern _Bool __go_type_equal_float (const void *, const void *, uintptr_t);
+extern const FuncVal __go_type_equal_float_descriptor;
 extern uintptr_t __go_type_hash_complex (const void *, uintptr_t);
+extern const FuncVal __go_type_hash_complex_descriptor;
 extern _Bool __go_type_equal_complex (const void *, const void *, uintptr_t);
+extern const FuncVal __go_type_equal_complex_descriptor;
 extern uintptr_t __go_type_hash_interface (const void *, uintptr_t);
+extern const FuncVal __go_type_hash_interface_descriptor;
 extern _Bool __go_type_equal_interface (const void *, const void *, uintptr_t);
+extern const FuncVal __go_type_equal_interface_descriptor;
 extern uintptr_t __go_type_hash_error (const void *, uintptr_t);
+extern const FuncVal __go_type_hash_error_descriptor;
 extern _Bool __go_type_equal_error (const void *, const void *, uintptr_t);
+extern const FuncVal __go_type_equal_error_descriptor;
 
 #endif /* !defined(LIBGO_GO_TYPE_H) */
diff --git a/third_party/gofrontend/libgo/runtime/go-typedesc-equal.c b/third_party/gofrontend/libgo/runtime/go-typedesc-equal.c
index f8474fc..90079f2 100644
--- a/third_party/gofrontend/libgo/runtime/go-typedesc-equal.c
+++ b/third_party/gofrontend/libgo/runtime/go-typedesc-equal.c
@@ -24,16 +24,5 @@
     return 0;
   if (td1->__code != td2->__code || td1->__hash != td2->__hash)
     return 0;
-  if (td1->__uncommon != NULL && td1->__uncommon->__name != NULL)
-    {
-      if (td2->__uncommon == NULL || td2->__uncommon->__name == NULL)
-	return 0;
-      return (__go_ptr_strings_equal (td1->__uncommon->__name,
-				      td2->__uncommon->__name)
-	      && __go_ptr_strings_equal (td1->__uncommon->__pkg_path,
-					 td2->__uncommon->__pkg_path));
-    }
-  if (td2->__uncommon != NULL && td2->__uncommon->__name != NULL)
-    return 0;
   return __go_ptr_strings_equal (td1->__reflection, td2->__reflection);
 }
diff --git a/third_party/gofrontend/libgo/runtime/go-unsafe-pointer.c b/third_party/gofrontend/libgo/runtime/go-unsafe-pointer.c
index 71364f5..ce82fcd 100644
--- a/third_party/gofrontend/libgo/runtime/go-unsafe-pointer.c
+++ b/third_party/gofrontend/libgo/runtime/go-unsafe-pointer.c
@@ -10,9 +10,6 @@
 #include "go-type.h"
 #include "mgc0.h"
 
-/* A pointer with a zero value.  */
-static void *zero_pointer;
-
 /* This file provides the type descriptor for the unsafe.Pointer type.
    The unsafe package is defined by the compiler itself, which means
    that there is no package to compile to define the type
@@ -54,9 +51,9 @@
   /* __hash */
   78501163U,
   /* __hashfn */
-  __go_type_hash_identity,
+  &__go_type_hash_identity_descriptor,
   /* __equalfn */
-  __go_type_equal_identity,
+  &__go_type_equal_identity_descriptor,
   /* __gc */
   unsafe_Pointer_gc,
   /* __reflection */
@@ -64,9 +61,7 @@
   /* __uncommon */
   NULL,
   /* __pointer_to_this */
-  NULL,
-  /* __zero */
-  &zero_pointer
+  NULL
 };
 
 /* We also need the type descriptor for the pointer to unsafe.Pointer,
@@ -99,9 +94,9 @@
     /* __hash */
     1256018616U,
     /* __hashfn */
-    __go_type_hash_identity,
+    &__go_type_hash_identity_descriptor,
     /* __equalfn */
-    __go_type_equal_identity,
+    &__go_type_equal_identity_descriptor,
     /* __gc */
     unsafe_Pointer_gc,
     /* __reflection */
@@ -109,9 +104,7 @@
     /* __uncommon */
     NULL,
     /* __pointer_to_this */
-    NULL,
-    /* __zero */
-    &zero_pointer
+    NULL
   },
   /* __element_type */
   &unsafe_Pointer
diff --git a/third_party/gofrontend/libgo/runtime/go-unwind.c b/third_party/gofrontend/libgo/runtime/go-unwind.c
index 849256b..87d9eb3 100644
--- a/third_party/gofrontend/libgo/runtime/go-unwind.c
+++ b/third_party/gofrontend/libgo/runtime/go-unwind.c
@@ -141,7 +141,7 @@
 
   hdr = (struct _Unwind_Exception *) g->exception;
 
-#ifdef LIBGO_SJLJ_EXCEPTIONS
+#ifdef __USING_SJLJ_EXCEPTIONS__
   _Unwind_SjLj_Resume_or_Rethrow (hdr);
 #else
 #if defined(_LIBUNWIND_STD_ABI)
diff --git a/third_party/gofrontend/libgo/runtime/go-varargs.c b/third_party/gofrontend/libgo/runtime/go-varargs.c
index 705f55e..691ee56 100644
--- a/third_party/gofrontend/libgo/runtime/go-varargs.c
+++ b/third_party/gofrontend/libgo/runtime/go-varargs.c
@@ -6,8 +6,12 @@
 
 #include "config.h"
 
+#include <errno.h>
+#include <stdint.h>
+#include <unistd.h>
 #include <sys/types.h>
 #include <fcntl.h>
+#include <sys/ioctl.h>
 
 /* The syscall package calls C functions.  The Go compiler can not
    represent a C varargs functions.  On some systems it's important
@@ -32,6 +36,40 @@
   return fcntl (fd, cmd, arg);
 }
 
+// This is for the net package.  We use uintptr_t to make sure that
+// the types match, since the Go and C "int" types are not the same.
+struct go_fcntl_ret {
+  uintptr_t r;
+  uintptr_t err;
+};
+
+struct go_fcntl_ret
+__go_fcntl_uintptr (uintptr_t fd, uintptr_t cmd, uintptr_t arg)
+{
+  int r;
+  struct go_fcntl_ret ret;
+
+  r = fcntl ((int) fd, (int) cmd, (int) arg);
+  ret.r = (uintptr_t) r;
+  if (r < 0)
+    ret.err = (uintptr_t) errno;
+  else
+    ret.err = 0;
+  return ret;
+}
+
+int
+__go_ioctl (int d, int request, int arg)
+{
+  return ioctl (d, request, arg);
+}
+
+int
+__go_ioctl_ptr (int d, int request, void *arg)
+{
+  return ioctl (d, request, arg);
+}
+
 #ifdef HAVE_OPEN64
 
 int
diff --git a/third_party/gofrontend/libgo/runtime/lfstack.goc b/third_party/gofrontend/libgo/runtime/lfstack.goc
index 060a0cc..5ab1baa 100644
--- a/third_party/gofrontend/libgo/runtime/lfstack.goc
+++ b/third_party/gofrontend/libgo/runtime/lfstack.goc
@@ -9,25 +9,41 @@
 #include "arch.h"
 
 #if __SIZEOF_POINTER__ == 8
-// Amd64 uses 48-bit virtual addresses, 47-th bit is used as kernel/user flag.
-// So we use 17msb of pointers as ABA counter.
-# define PTR_BITS 47
-#else
-# define PTR_BITS 32
-#endif
-#define PTR_MASK ((1ull<<PTR_BITS)-1)
-#define CNT_MASK (0ull-1)
-
-#if __SIZEOF_POINTER__ == 8 && (defined(__sparc__) || (defined(__sun__) && defined(__amd64__)))
 // SPARC64 and Solaris on AMD64 uses all 64 bits of virtual addresses.
 // Use low-order three bits as ABA counter.
 // http://docs.oracle.com/cd/E19120-01/open.solaris/816-5138/6mba6ua5p/index.html
-#undef PTR_BITS
-#undef CNT_MASK
-#undef PTR_MASK
-#define PTR_BITS 0
-#define CNT_MASK 7
-#define PTR_MASK ((0ull-1)<<3)
+# if defined(__sparc__) || (defined(__sun__) && defined(__amd64__))
+static inline uint64 lfPack(LFNode *node, uintptr cnt) {
+	return ((uint64)(node)) | ((cnt)&7);
+}
+static inline LFNode* lfUnpack(uint64 val) {
+	return (LFNode*)(val&~7);
+}
+# else
+#  if defined(__aarch64__)
+// Depending on the kernel options, pointers on arm64 can have up to 48 significant
+// bits (see https://www.kernel.org/doc/Documentation/arm64/memory.txt).
+#   define PTR_BITS 48
+#  else
+// Amd64 uses 48-bit virtual addresses, 47-th bit is used as kernel/user flag.
+// So we use 17msb of pointers as ABA counter.
+#   define PTR_BITS 47
+#  endif
+# define CNT_BITS (64 - PTR_BITS + 3)
+static inline uint64 lfPack(LFNode *node, uintptr cnt) {
+	return ((uint64)(node)<<(64-PTR_BITS)) | (cnt&(((1<<CNT_BITS)-1)));
+}
+static inline LFNode* lfUnpack(uint64 val) {
+	return (LFNode*)((val >> CNT_BITS) << 3);
+}
+# endif
+#else
+static inline uint64 lfPack(LFNode *node, uintptr cnt) {
+	return ((uint64)(uintptr)(node)<<32) | cnt;
+}
+static inline LFNode* lfUnpack(uint64 val) {
+	return (LFNode*)(uintptr)(val >> 32);
+}
 #endif
 
 void
@@ -35,16 +51,16 @@
 {
 	uint64 old, new;
 
-	if((uintptr)node != ((uintptr)node&PTR_MASK)) {
+	if(node != lfUnpack(lfPack(node, 0))) {
 		runtime_printf("p=%p\n", node);
 		runtime_throw("runtime_lfstackpush: invalid pointer");
 	}
 
 	node->pushcnt++;
-	new = (uint64)(uintptr)node|(((uint64)node->pushcnt&CNT_MASK)<<PTR_BITS);
+	new = lfPack(node, node->pushcnt);
 	for(;;) {
 		old = runtime_atomicload64(head);
-		node->next = (LFNode*)(uintptr)(old&PTR_MASK);
+		node->next = lfUnpack(old);
 		if(runtime_cas64(head, old, new))
 			break;
 	}
@@ -60,11 +76,11 @@
 		old = runtime_atomicload64(head);
 		if(old == 0)
 			return nil;
-		node = (LFNode*)(uintptr)(old&PTR_MASK);
+		node = lfUnpack(old);
 		node2 = runtime_atomicloadp(&node->next);
 		new = 0;
 		if(node2 != nil)
-			new = (uint64)(uintptr)node2|(((uint64)node2->pushcnt&CNT_MASK)<<PTR_BITS);
+			new = lfPack(node2, node2->pushcnt);
 		if(runtime_cas64(head, old, new))
 			return node;
 	}
diff --git a/third_party/gofrontend/libgo/runtime/malloc.goc b/third_party/gofrontend/libgo/runtime/malloc.goc
index fd5a1cf..b29a01b 100644
--- a/third_party/gofrontend/libgo/runtime/malloc.goc
+++ b/third_party/gofrontend/libgo/runtime/malloc.goc
@@ -64,7 +64,7 @@
   __asm__ (GOSYM_PREFIX "runtime.MemProfileRate");
 
 static MSpan* largealloc(uint32, uintptr*);
-static void profilealloc(void *v, uintptr size);
+static void runtime_profilealloc(void *v, uintptr size);
 static void settype(MSpan *s, void *v, uintptr typ);
 
 // Allocate an object of at least size bytes.
@@ -250,7 +250,7 @@
 		if(size < (uintptr)rate && size < (uintptr)(uint32)c->next_sample)
 			c->next_sample -= size;
 		else
-			profilealloc(v, size);
+			runtime_profilealloc(v, size);
 	}
 
 	m->locks--;
@@ -290,7 +290,7 @@
 }
 
 static void
-profilealloc(void *v, uintptr size)
+runtime_profilealloc(void *v, uintptr size)
 {
 	uintptr rate;
 	int32 next;
diff --git a/third_party/gofrontend/libgo/runtime/malloc.h b/third_party/gofrontend/libgo/runtime/malloc.h
index b2a6e19..d0d1cb2 100644
--- a/third_party/gofrontend/libgo/runtime/malloc.h
+++ b/third_party/gofrontend/libgo/runtime/malloc.h
@@ -263,7 +263,9 @@
 	uint64  last_gc;	// last GC (in absolute time)
 	uint64	pause_total_ns;
 	uint64	pause_ns[256];
+	uint64	pause_end[256];
 	uint32	numgc;
+	float64	gc_cpu_fraction;
 	bool	enablegc;
 	bool	debuggc;
 
diff --git a/third_party/gofrontend/libgo/runtime/mgc0.c b/third_party/gofrontend/libgo/runtime/mgc0.c
index e1452a4..73fe2ba 100644
--- a/third_party/gofrontend/libgo/runtime/mgc0.c
+++ b/third_party/gofrontend/libgo/runtime/mgc0.c
@@ -1368,6 +1368,8 @@
 		scanblock(wbuf, false);
 }
 
+static const FuncVal markroot_funcval = { (void *) markroot };
+
 // Get an empty work buffer off the work.empty list,
 // allocating new buffers as needed.
 static Workbuf*
@@ -2102,14 +2104,16 @@
 static int32
 readgogc(void)
 {
+	String s;
 	const byte *p;
 
-	p = runtime_getenv("GOGC");
-	if(p == nil || p[0] == '\0')
+	s = runtime_getenv("GOGC");
+	if(s.len == 0)
 		return 100;
-	if(runtime_strcmp((const char *)p, "off") == 0)
+	p = s.str;
+	if(s.len == 3 && runtime_strcmp((const char *)p, "off") == 0)
 		return -1;
-	return runtime_atoi(p);
+	return runtime_atoi(p, s.len);
 }
 
 // force = 1 - do GC regardless of current heap usage
@@ -2252,7 +2256,7 @@
 	work.nwait = 0;
 	work.ndone = 0;
 	work.nproc = runtime_gcprocs();
-	runtime_parforsetup(work.markfor, work.nproc, RootCount + runtime_allglen, nil, false, markroot);
+	runtime_parforsetup(work.markfor, work.nproc, RootCount + runtime_allglen, false, &markroot_funcval);
 	if(work.nproc > 1) {
 		runtime_noteclear(&work.alldone);
 		runtime_helpgc(work.nproc);
@@ -2280,11 +2284,12 @@
 	heap0 = mstats.next_gc*100/(gcpercent+100);
 	// conservatively set next_gc to high value assuming that everything is live
 	// concurrent/lazy sweep will reduce this number while discovering new garbage
-	mstats.next_gc = mstats.heap_alloc+mstats.heap_alloc*gcpercent/100;
+	mstats.next_gc = mstats.heap_alloc+(mstats.heap_alloc-runtime_stacks_sys)*gcpercent/100;
 
 	t4 = runtime_nanotime();
 	mstats.last_gc = runtime_unixnanotime();  // must be Unix time to make sense to user
 	mstats.pause_ns[mstats.numgc%nelem(mstats.pause_ns)] = t4 - t0;
+	mstats.pause_end[mstats.numgc%nelem(mstats.pause_end)] = mstats.last_gc;
 	mstats.pause_total_ns += t4 - t0;
 	mstats.numgc++;
 	if(mstats.debuggc)
@@ -2749,3 +2754,38 @@
 	runtime_SysMap(h->arena_start - n, n - h->bitmap_mapped, h->arena_reserved, &mstats.gc_sys);
 	h->bitmap_mapped = n;
 }
+
+// typedmemmove copies a value of type t to dst from src.
+
+extern void typedmemmove(const Type* td, void *dst, const void *src)
+  __asm__ (GOSYM_PREFIX "reflect.typedmemmove");
+
+void
+typedmemmove(const Type* td, void *dst, const void *src)
+{
+	runtime_memmove(dst, src, td->__size);
+}
+
+// typedslicecopy copies a slice of elemType values from src to dst,
+// returning the number of elements copied.
+
+extern intgo typedslicecopy(const Type* elem, Slice dst, Slice src)
+  __asm__ (GOSYM_PREFIX "reflect.typedslicecopy");
+
+intgo
+typedslicecopy(const Type* elem, Slice dst, Slice src)
+{
+	intgo n;
+	void *dstp;
+	void *srcp;
+
+	n = dst.__count;
+	if (n > src.__count)
+		n = src.__count;
+	if (n == 0)
+		return 0;
+	dstp = dst.__values;
+	srcp = src.__values;
+	memmove(dstp, srcp, (uintptr_t)n * elem->__size);
+	return n;
+}
diff --git a/third_party/gofrontend/libgo/runtime/mprof.goc b/third_party/gofrontend/libgo/runtime/mprof.goc
index d9c220b..4e8cfc9 100644
--- a/third_party/gofrontend/libgo/runtime/mprof.goc
+++ b/third_party/gofrontend/libgo/runtime/mprof.goc
@@ -402,10 +402,9 @@
 }
 
 func Stack(b Slice, all bool) (n int) {
-	byte *pc, *sp;
-	bool enablegc;
+	byte *pc;
+	bool enablegc = false;
 	
-	sp = runtime_getcallersp(&b);
 	pc = (byte*)(uintptr)runtime_getcallerpc(&b);
 
 	if(all) {
@@ -423,7 +422,6 @@
 		g->writebuf = (byte*)b.__values;
 		g->writenbuf = b.__count;
 		USED(pc);
-		USED(sp);
 		runtime_goroutineheader(g);
 		runtime_traceback();
 		runtime_printcreatedby(g);
diff --git a/third_party/gofrontend/libgo/runtime/netpoll_select.c b/third_party/gofrontend/libgo/runtime/netpoll_select.c
index b461335..033661d 100644
--- a/third_party/gofrontend/libgo/runtime/netpoll_select.c
+++ b/third_party/gofrontend/libgo/runtime/netpoll_select.c
@@ -135,6 +135,8 @@
 	byte b;
 	struct stat st;
 
+	allocatedfds = false;
+
  retry:
 	runtime_lock(&selectlock);
 
@@ -146,11 +148,13 @@
 	}
 
 	if(inuse) {
-		prfds = runtime_SysAlloc(4 * sizeof fds, &mstats.other_sys);
-		pwfds = prfds + 1;
-		pefds = pwfds + 1;
-		ptfds = pefds + 1;
-		allocatedfds = true;
+		if(!allocatedfds) {
+			prfds = runtime_SysAlloc(4 * sizeof fds, &mstats.other_sys);
+			pwfds = prfds + 1;
+			pefds = pwfds + 1;
+			ptfds = pefds + 1;
+			allocatedfds = true;
+		}
 	} else {
 		prfds = &grfds;
 		pwfds = &gwfds;
@@ -216,7 +220,7 @@
 			mode = 'r' + 'w';
 			--c;
 		}
-		if(i == rdwake) {
+		if(i == rdwake && mode != 0) {
 			while(read(rdwake, &b, sizeof b) > 0)
 				;
 			continue;
diff --git a/third_party/gofrontend/libgo/runtime/parfor.c b/third_party/gofrontend/libgo/runtime/parfor.c
index 386faea..ede921b 100644
--- a/third_party/gofrontend/libgo/runtime/parfor.c
+++ b/third_party/gofrontend/libgo/runtime/parfor.c
@@ -34,7 +34,7 @@
 }
 
 void
-runtime_parforsetup(ParFor *desc, uint32 nthr, uint32 n, void *ctx, bool wait, void (*body)(ParFor*, uint32))
+runtime_parforsetup(ParFor *desc, uint32 nthr, uint32 n, bool wait, const FuncVal *body)
 {
 	uint32 i, begin, end;
 	uint64 *pos;
@@ -49,7 +49,6 @@
 	desc->nthr = nthr;
 	desc->thrseq = 0;
 	desc->cnt = n;
-	desc->ctx = ctx;
 	desc->wait = wait;
 	desc->nsteal = 0;
 	desc->nstealcnt = 0;
@@ -72,7 +71,8 @@
 	ParForThread *me;
 	uint32 tid, begin, end, begin2, try, victim, i;
 	uint64 *mypos, *victimpos, pos, newpos;
-	void (*body)(ParFor*, uint32);
+	const FuncVal *body;
+	void (*bodyfn)(ParFor*, uint32);
 	bool idle;
 
 	// Obtain 0-based thread index.
@@ -82,14 +82,16 @@
 		runtime_throw("parfor: invalid tid");
 	}
 
+	body = desc->body;
+	bodyfn = (void (*)(ParFor*, uint32))(void*)body->fn;
+
 	// If single-threaded, just execute the for serially.
 	if(desc->nthr==1) {
 		for(i=0; i<desc->cnt; i++)
-			desc->body(desc, i);
+		  __builtin_call_with_static_chain (bodyfn(desc, i), body);
 		return;
 	}
 
-	body = desc->body;
 	me = &desc->thr[tid];
 	mypos = &me->pos;
 	for(;;) {
@@ -100,7 +102,7 @@
 			begin = (uint32)pos-1;
 			end = (uint32)(pos>>32);
 			if(begin < end) {
-				body(desc, begin);
+				__builtin_call_with_static_chain(bodyfn(desc, begin), body);
 				continue;
 			}
 			break;
diff --git a/third_party/gofrontend/libgo/runtime/proc.c b/third_party/gofrontend/libgo/runtime/proc.c
index 6facd40..2d013f0 100644
--- a/third_party/gofrontend/libgo/runtime/proc.c
+++ b/third_party/gofrontend/libgo/runtime/proc.c
@@ -372,7 +372,6 @@
 Sched	runtime_sched;
 int32	runtime_gomaxprocs;
 uint32	runtime_needextram = 1;
-bool	runtime_iscgo = true;
 M	runtime_m0;
 G	runtime_g0;	// idle goroutine for m0
 G*	runtime_lastg;
@@ -389,6 +388,8 @@
 uintptr runtime_allglen;
 static	uintptr allgcap;
 
+bool	runtime_isarchive;
+
 void* runtime_mstart(void*);
 static void runqput(P*, G*);
 static G* runqget(P*);
@@ -428,6 +429,8 @@
 static bool exitsyscallfast(void);
 static void allgadd(G*);
 
+bool runtime_isstarted;
+
 // The bootstrap sequence is:
 //
 //	call osinit
@@ -440,6 +443,7 @@
 runtime_schedinit(void)
 {
 	int32 n, procs;
+	String s;
 	const byte *p;
 	Eface i;
 
@@ -474,8 +478,9 @@
 
 	runtime_sched.lastpoll = runtime_nanotime();
 	procs = 1;
-	p = runtime_getenv("GOMAXPROCS");
-	if(p != nil && (n = runtime_atoi(p)) > 0) {
+	s = runtime_getenv("GOMAXPROCS");
+	p = s.str;
+	if(p != nil && (n = runtime_atoi(p, s.len)) > 0) {
 		if(n > MaxGomaxprocs)
 			n = MaxGomaxprocs;
 		procs = n;
@@ -490,6 +495,62 @@
 extern void main_init(void) __asm__ (GOSYM_PREFIX "__go_init_main");
 extern void main_main(void) __asm__ (GOSYM_PREFIX "main.main");
 
+// Used to determine the field alignment.
+
+struct field_align
+{
+  char c;
+  Hchan *p;
+};
+
+// main_init_done is a signal used by cgocallbackg that initialization
+// has been completed.  It is made before _cgo_notify_runtime_init_done,
+// so all cgo calls can rely on it existing.  When main_init is
+// complete, it is closed, meaning cgocallbackg can reliably receive
+// from it.
+Hchan *runtime_main_init_done;
+
+// The chan bool type, for runtime_main_init_done.
+
+extern const struct __go_type_descriptor bool_type_descriptor
+  __asm__ (GOSYM_PREFIX "__go_tdn_bool");
+
+static struct __go_channel_type chan_bool_type_descriptor =
+  {
+    /* __common */
+    {
+      /* __code */
+      GO_CHAN,
+      /* __align */
+      __alignof (Hchan *),
+      /* __field_align */
+      offsetof (struct field_align, p) - 1,
+      /* __size */
+      sizeof (Hchan *),
+      /* __hash */
+      0, /* This value doesn't matter.  */
+      /* __hashfn */
+      &__go_type_hash_error_descriptor,
+      /* __equalfn */
+      &__go_type_equal_error_descriptor,
+      /* __gc */
+      NULL, /* This value doesn't matter */
+      /* __reflection */
+      NULL, /* This value doesn't matter */
+      /* __uncommon */
+      NULL,
+      /* __pointer_to_this */
+      NULL
+    },
+    /* __element_type */
+    &bool_type_descriptor,
+    /* __dir */
+    CHANNEL_BOTH_DIR
+  };
+
+extern Hchan *__go_new_channel (ChanType *, uintptr);
+extern void closechan(Hchan *) __asm__ (GOSYM_PREFIX "runtime.closechan");
+
 static void
 initDone(void *arg __attribute__ ((unused))) {
 	runtime_unlockOSThread();
@@ -535,8 +596,15 @@
 	if(m != &runtime_m0)
 		runtime_throw("runtime_main not on m0");
 	__go_go(runtime_MHeap_Scavenger, nil);
+
+	runtime_main_init_done = __go_new_channel(&chan_bool_type_descriptor, 0);
+
+	_cgo_notify_runtime_init_done();
+
 	main_init();
 
+	closechan(runtime_main_init_done);
+
 	if(g->defer != &d || d.__pfn != initDone)
 		runtime_throw("runtime: bad defer entry after init");
 	g->defer = d.__next;
@@ -547,6 +615,14 @@
 	// roots.
 	mstats.enablegc = 1;
 
+	if(runtime_isarchive) {
+		// This is not a complete program, but is instead a
+		// library built using -buildmode=c-archive or
+		// c-shared.  Now that we are initialized, there is
+		// nothing further to do.
+		return;
+	}
+
 	main_main();
 
 	// Make racy client program work: if panicking on
@@ -1011,8 +1087,14 @@
 
 	// Install signal handlers; after minit so that minit can
 	// prepare the thread to be able to handle the signals.
-	if(m == &runtime_m0)
+	if(m == &runtime_m0) {
+		if(runtime_iscgo && !runtime_cgoHasExtraM) {
+			runtime_cgoHasExtraM = true;
+			runtime_newextram();
+			runtime_needextram = 0;
+		}
 		runtime_initsig();
+	}
 	
 	if(m->mstartfn)
 		m->mstartfn();
@@ -2168,11 +2250,24 @@
 		__splitstack_block_signals_context(&newg->stack_context[0],
 						   &dont_block_signals, nil);
 #else
-		*ret_stack = runtime_mallocgc(stacksize, 0, FlagNoProfiling|FlagNoGC);
+                // In 64-bit mode, the maximum Go allocation space is
+                // 128G.  Our stack size is 4M, which only permits 32K
+                // goroutines.  In order to not limit ourselves,
+                // allocate the stacks out of separate memory.  In
+                // 32-bit mode, the Go allocation space is all of
+                // memory anyhow.
+		if(sizeof(void*) == 8) {
+			void *p = runtime_SysAlloc(stacksize, &mstats.other_sys);
+			if(p == nil)
+				runtime_throw("runtime: cannot allocate memory for goroutine stack");
+			*ret_stack = (byte*)p;
+		} else {
+			*ret_stack = runtime_mallocgc(stacksize, 0, FlagNoProfiling|FlagNoGC);
+			runtime_xadd(&runtime_stacks_sys, stacksize);
+		}
 		*ret_stacksize = stacksize;
 		newg->gcinitial_sp = *ret_stack;
 		newg->gcstack_size = stacksize;
-		runtime_xadd(&runtime_stacks_sys, stacksize);
 #endif
 	}
 	return newg;
@@ -2188,19 +2283,19 @@
 // are available sequentially after &fn; they would not be
 // copied if a stack split occurred.  It's OK for this to call
 // functions that split the stack.
-void runtime_testing_entersyscall(void)
+void runtime_testing_entersyscall(int32)
   __asm__ (GOSYM_PREFIX "runtime.entersyscall");
 void
-runtime_testing_entersyscall()
+runtime_testing_entersyscall(int32 dummy __attribute__ ((unused)))
 {
 	runtime_entersyscall();
 }
 
-void runtime_testing_exitsyscall(void)
+void runtime_testing_exitsyscall(int32)
   __asm__ (GOSYM_PREFIX "runtime.exitsyscall");
 
 void
-runtime_testing_exitsyscall()
+runtime_testing_exitsyscall(int32 dummy __attribute__ ((unused)))
 {
 	runtime_exitsyscall();
 }
@@ -2747,6 +2842,13 @@
 	int32 run, grunning, s;
 	uintptr i;
 
+	// For -buildmode=c-shared or -buildmode=c-archive it's OK if
+	// there are no running goroutines.  The calling program is
+	// assumed to be running.
+	if(runtime_isarchive) {
+		return;
+	}
+
 	// -1 for sysmon
 	run = runtime_sched.mcount - runtime_sched.nmidle - runtime_sched.nmidlelocked - 1 - countextra();
 	if(run > 0)
@@ -3332,6 +3434,7 @@
 runtime_proc_scan(struct Workbuf** wbufp, void (*enqueue1)(struct Workbuf**, Obj))
 {
 	enqueue1(wbufp, (Obj){(byte*)&runtime_sched, sizeof runtime_sched, 0});
+	enqueue1(wbufp, (Obj){(byte*)&runtime_main_init_done, sizeof runtime_main_init_done, 0});
 }
 
 // Return whether we are waiting for a GC.  This gc toolchain uses
@@ -3341,3 +3444,54 @@
 {
 	return runtime_sched.gcwaiting;
 }
+
+// os_beforeExit is called from os.Exit(0).
+//go:linkname os_beforeExit os.runtime_beforeExit
+
+extern void os_beforeExit() __asm__ (GOSYM_PREFIX "os.runtime_beforeExit");
+
+void
+os_beforeExit()
+{
+}
+
+// Active spinning for sync.Mutex.
+//go:linkname sync_runtime_canSpin sync.runtime_canSpin
+
+enum
+{
+	ACTIVE_SPIN = 4,
+	ACTIVE_SPIN_CNT = 30,
+};
+
+extern _Bool sync_runtime_canSpin(intgo i)
+  __asm__ (GOSYM_PREFIX "sync.runtime_canSpin");
+
+_Bool
+sync_runtime_canSpin(intgo i)
+{
+	P *p;
+
+	// sync.Mutex is cooperative, so we are conservative with spinning.
+	// Spin only few times and only if running on a multicore machine and
+	// GOMAXPROCS>1 and there is at least one other running P and local runq is empty.
+	// As opposed to runtime mutex we don't do passive spinning here,
+	// because there can be work on global runq on on other Ps.
+	if (i >= ACTIVE_SPIN || runtime_ncpu <= 1 || runtime_gomaxprocs <= (int32)(runtime_sched.npidle+runtime_sched.nmspinning)+1) {
+		return false;
+	}
+	p = m->p;
+	return p != nil && p->runqhead == p->runqtail;
+}
+
+//go:linkname sync_runtime_doSpin sync.runtime_doSpin
+//go:nosplit
+
+extern void sync_runtime_doSpin(void)
+  __asm__ (GOSYM_PREFIX "sync.runtime_doSpin");
+
+void
+sync_runtime_doSpin()
+{
+	runtime_procyield(ACTIVE_SPIN_CNT);
+}
diff --git a/third_party/gofrontend/libgo/runtime/runtime.c b/third_party/gofrontend/libgo/runtime/runtime.c
index e332035..be7ccbd 100644
--- a/third_party/gofrontend/libgo/runtime/runtime.c
+++ b/third_party/gofrontend/libgo/runtime/runtime.c
@@ -35,6 +35,7 @@
 int32
 runtime_gotraceback(bool *crash)
 {
+	String s;
 	const byte *p;
 	uint32 x;
 
@@ -44,15 +45,14 @@
 		return runtime_m()->traceback;
 	x = runtime_atomicload(&traceback_cache);
 	if(x == ~(uint32)0) {
-		p = runtime_getenv("GOTRACEBACK");
-		if(p == nil)
-			p = (const byte*)"";
-		if(p[0] == '\0')
+		s = runtime_getenv("GOTRACEBACK");
+		p = s.str;
+		if(s.len == 0)
 			x = 1<<1;
-		else if(runtime_strcmp((const char *)p, "crash") == 0)
+		else if(s.len == 5 && runtime_strcmp((const char *)p, "crash") == 0)
 			x = (2<<1) | 1;
 		else
-			x = runtime_atoi(p)<<1;	
+			x = runtime_atoi(p, s.len)<<1;	
 		runtime_atomicstore(&traceback_cache, x);
 	}
 	if(crash != nil)
@@ -136,13 +136,15 @@
 }
 
 int32
-runtime_atoi(const byte *p)
+runtime_atoi(const byte *p, intgo len)
 {
 	int32 n;
 
 	n = 0;
-	while('0' <= *p && *p <= '9')
+	while(len > 0 && '0' <= *p && *p <= '9') {
 		n = n*10 + *p++ - '0';
+		len--;
+	}
 	return n;
 }
 
@@ -339,7 +341,9 @@
 void
 runtime_parsedebugvars(void)
 {
-	const byte *p;
+	String s;
+	const byte *p, *pn;
+	intgo len;
 	intgo i, n;
 	bool tmp;
 	
@@ -352,24 +356,27 @@
 	traceback_cache = ~(uint32)0;
 	runtime_gotraceback(&tmp);
 
-	p = runtime_getenv("GODEBUG");
-	if(p == nil)
+	s = runtime_getenv("GODEBUG");
+	if(s.len == 0)
 		return;
+	p = s.str;
+	len = s.len;
 	for(;;) {
 		for(i=0; i<(intgo)nelem(dbgvar); i++) {
 			n = runtime_findnull((const byte*)dbgvar[i].name);
-			if(runtime_mcmp(p, "memprofilerate", n) == 0 && p[n] == '=')
+			if(len > n && runtime_mcmp(p, "memprofilerate", n) == 0 && p[n] == '=')
 				// Set the MemProfileRate directly since it
 				// is an int, not int32, and should only lbe
 				// set here if specified by GODEBUG
-				runtime_MemProfileRate = runtime_atoi(p+n+1);
-			else if(runtime_mcmp(p, dbgvar[i].name, n) == 0 && p[n] == '=')
-				*dbgvar[i].value = runtime_atoi(p+n+1);
+				runtime_MemProfileRate = runtime_atoi(p+n+1, len-(n+1));
+			else if(len > n && runtime_mcmp(p, dbgvar[i].name, n) == 0 && p[n] == '=')
+				*dbgvar[i].value = runtime_atoi(p+n+1, len-(n+1));
 		}
-		p = (const byte *)runtime_strstr((const char *)p, ",");
-		if(p == nil)
+		pn = (const byte *)runtime_strstr((const char *)p, ",");
+		if(pn == nil || pn - p >= len)
 			break;
-		p++;
+		len -= (pn - p) - 1;
+		p = pn + 1;
 	}
 }
 
diff --git a/third_party/gofrontend/libgo/runtime/runtime.h b/third_party/gofrontend/libgo/runtime/runtime.h
index 7e2a375..d1bf5a9 100644
--- a/third_party/gofrontend/libgo/runtime/runtime.h
+++ b/third_party/gofrontend/libgo/runtime/runtime.h
@@ -421,17 +421,15 @@
 // Parallel for descriptor.
 struct ParFor
 {
-	void (*body)(ParFor*, uint32);	// executed for each element
+	const FuncVal *body;		// executed for each element
 	uint32 done;			// number of idle threads
 	uint32 nthr;			// total number of threads
 	uint32 nthrmax;			// maximum number of threads
 	uint32 thrseq;			// thread id sequencer
 	uint32 cnt;			// iteration space [0, cnt)
-	void *ctx;			// arbitrary user context
 	bool wait;			// if true, wait while all threads finish processing,
 					// otherwise parfor may return while other threads are still working
 	ParForThread *thr;		// array of thread descriptors
-	uint32 pad;			// to align ParForThread.pos for 64-bit atomic operations
 	// stats
 	uint64 nsteal;
 	uint64 nstealcnt;
@@ -509,6 +507,9 @@
 extern	DebugVars	runtime_debug;
 extern	uintptr	runtime_maxstacksize;
 
+extern	bool	runtime_isstarted;
+extern	bool	runtime_isarchive;
+
 /*
  * common functions and data
  */
@@ -541,6 +542,7 @@
 void	runtime_initsig(void);
 void	runtime_sigenable(uint32 sig);
 void	runtime_sigdisable(uint32 sig);
+void	runtime_sigignore(uint32 sig);
 int32	runtime_gotraceback(bool *crash);
 void	runtime_goroutineheader(G*);
 void	runtime_printtrace(Location*, int32, bool);
@@ -549,8 +551,8 @@
 #define runtime_write(d, v, n) write((d), (v), (n))
 #define runtime_close(d) close(d)
 void	runtime_ready(G*);
-const byte*	runtime_getenv(const char*);
-int32	runtime_atoi(const byte*);
+String	runtime_getenv(const char*);
+int32	runtime_atoi(const byte*, intgo);
 void*	runtime_mstart(void*);
 G*	runtime_malg(int32, byte**, size_t*);
 void	runtime_mpreinit(M*);
@@ -710,12 +712,11 @@
  * Parallel for over [0, n).
  * body() is executed for each iteration.
  * nthr - total number of worker threads.
- * ctx - arbitrary user context.
  * if wait=true, threads return from parfor() when all work is done;
  * otherwise, threads can return while other threads are still finishing processing.
  */
 ParFor*	runtime_parforalloc(uint32 nthrmax);
-void	runtime_parforsetup(ParFor *desc, uint32 nthr, uint32 n, void *ctx, bool wait, void (*body)(ParFor*, uint32));
+void	runtime_parforsetup(ParFor *desc, uint32 nthr, uint32 n, bool wait, const FuncVal *body);
 void	runtime_parfordo(ParFor *desc);
 void	runtime_parforiters(ParFor*, uintptr, uintptr*, uintptr*);
 
@@ -845,3 +846,9 @@
 
 struct time_now_ret now() __asm__ (GOSYM_PREFIX "time.now")
   __attribute__ ((no_split_stack));
+
+extern void _cgo_wait_runtime_init_done (void);
+extern void _cgo_notify_runtime_init_done (void);
+extern _Bool runtime_iscgo;
+extern _Bool runtime_cgoHasExtraM;
+extern Hchan *runtime_main_init_done;
diff --git a/third_party/gofrontend/libgo/runtime/runtime1.goc b/third_party/gofrontend/libgo/runtime/runtime1.goc
index 6d8f09a..cd9d301 100644
--- a/third_party/gofrontend/libgo/runtime/runtime1.goc
+++ b/third_party/gofrontend/libgo/runtime/runtime1.goc
@@ -27,8 +27,8 @@
 	desc = runtime_parforalloc(nthrmax);
 }
 
-func parForSetup(desc *ParFor, nthr uint32, n uint32, ctx *byte, wait bool, body *byte) {
-	runtime_parforsetup(desc, nthr, n, ctx, wait, *(void(**)(ParFor*, uint32))body);
+func parForSetup(desc *ParFor, nthr uint32, n uint32, wait bool, body *byte) {
+	runtime_parforsetup(desc, nthr, n, wait, (const FuncVal*) body);
 }
 
 func parForDo(desc *ParFor) {
@@ -52,10 +52,7 @@
 }
 
 func getgoroot() (out String) {
-	const byte *p;
-
-	p = runtime_getenv("GOROOT");
-	out = runtime_gostringnocopy(p);
+	out = runtime_getenv("GOROOT");
 }
 
 func runtime_pprof.runtime_cyclesPerSecond() (res int64) {
@@ -87,3 +84,13 @@
 func sync_atomic.runtime_procUnpin() {
 	runtime_m()->locks--;
 }
+
+extern Slice envs;
+
+func envs() (s Slice) {
+	s = envs;
+}
+
+func setenvs(e Slice) {
+	envs = e;
+}
diff --git a/third_party/gofrontend/libgo/runtime/signal_unix.c b/third_party/gofrontend/libgo/runtime/signal_unix.c
index 66638de..43be0d8 100644
--- a/third_party/gofrontend/libgo/runtime/signal_unix.c
+++ b/third_party/gofrontend/libgo/runtime/signal_unix.c
@@ -93,6 +93,29 @@
 }
 
 void
+runtime_sigignore(uint32 sig)
+{
+	int32 i;
+	SigTab *t;
+
+	t = nil;
+	for(i = 0; runtime_sigtab[i].sig != -1; i++) {
+		if(runtime_sigtab[i].sig == (int32)sig) {
+			t = &runtime_sigtab[i];
+			break;
+		}
+	}
+
+	if(t == nil)
+		return;
+
+	if((t->flags & SigNotify) != 0) {
+		t->flags &= ~SigHandling;
+		runtime_setsig(i, GO_SIG_IGN, true);
+	}
+}
+
+void
 runtime_resetcpuprofiler(int32 hz)
 {
 	struct itimerval it;
diff --git a/third_party/gofrontend/libgo/runtime/sigqueue.goc b/third_party/gofrontend/libgo/runtime/sigqueue.goc
index 7853598..d9537c2 100644
--- a/third_party/gofrontend/libgo/runtime/sigqueue.goc
+++ b/third_party/gofrontend/libgo/runtime/sigqueue.goc
@@ -156,6 +156,14 @@
 	runtime_sigdisable(s);
 }
 
+// Must only be called from a single goroutine at a time.
+func signal_ignore(s uint32) {
+	if (s >= nelem(sig.wanted)*32)
+		return;
+	sig.wanted[s/32] &= ~(1U<<(s&31));
+	runtime_sigignore(s);
+}
+
 // This runs on a foreign stack, without an m or a g.  No stack split.
 void
 runtime_badsignal(int sig)
diff --git a/third_party/gofrontend/libgo/testsuite/Makefile.in b/third_party/gofrontend/libgo/testsuite/Makefile.in
index 7f7fb74..ba04a50 100644
--- a/third_party/gofrontend/libgo/testsuite/Makefile.in
+++ b/third_party/gofrontend/libgo/testsuite/Makefile.in
@@ -1,9 +1,9 @@
-# Makefile.in generated by automake 1.11.1 from Makefile.am.
+# Makefile.in generated by automake 1.11.6 from Makefile.am.
 # @configure_input@
 
 # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
-# 2003, 2004, 2005, 2006, 2007, 2008, 2009  Free Software Foundation,
-# Inc.
+# 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software
+# Foundation, Inc.
 # This Makefile.in is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
 # with or without modifications, as long as this notice is preserved.
@@ -15,6 +15,23 @@
 
 @SET_MAKE@
 VPATH = @srcdir@
+am__make_dryrun = \
+  { \
+    am__dry=no; \
+    case $$MAKEFLAGS in \
+      *\\[\ \	]*) \
+        echo 'am--echo: ; @echo "AM"  OK' | $(MAKE) -f - 2>/dev/null \
+          | grep '^AM OK$$' >/dev/null || am__dry=yes;; \
+      *) \
+        for am__flg in $$MAKEFLAGS; do \
+          case $$am__flg in \
+            *=*|--*) ;; \
+            *n*) am__dry=yes; break;; \
+          esac; \
+        done;; \
+    esac; \
+    test $$am__dry = yes; \
+  }
 pkgdatadir = $(datadir)/@PACKAGE@
 pkgincludedir = $(includedir)/@PACKAGE@
 pkglibdir = $(libdir)/@PACKAGE@
@@ -54,6 +71,11 @@
 CONFIG_CLEAN_FILES =
 CONFIG_CLEAN_VPATH_FILES =
 SOURCES =
+am__can_run_installinfo = \
+  case $$AM_UPDATE_INFO_DIR in \
+    n|no|NO) false;; \
+    *) (install-info --version) >/dev/null 2>&1;; \
+  esac
 DEJATOOL = $(PACKAGE)
 RUNTESTDEFAULTFLAGS = --tool $$tool --srcdir $$srcdir
 ACLOCAL = @ACLOCAL@
@@ -86,6 +108,7 @@
 GOOS = @GOOS@
 GO_LIBCALL_OS_ARCH_FILE = @GO_LIBCALL_OS_ARCH_FILE@
 GO_LIBCALL_OS_FILE = @GO_LIBCALL_OS_FILE@
+GO_SPLIT_STACK = @GO_SPLIT_STACK@
 GO_SYSCALL_OS_ARCH_FILE = @GO_SYSCALL_OS_ARCH_FILE@
 GO_SYSCALL_OS_FILE = @GO_SYSCALL_OS_FILE@
 GREP = @GREP@
@@ -270,7 +293,7 @@
 
 
 check-DEJAGNU: site.exp
-	srcdir=`$(am__cd) $(srcdir) && pwd`; export srcdir; \
+	srcdir='$(srcdir)'; export srcdir; \
 	EXPECT=$(EXPECT); export EXPECT; \
 	runtest=$(RUNTEST); \
 	if $(SHELL) -c "$$runtest --version" > /dev/null 2>&1; then \
@@ -281,12 +304,12 @@
 	else echo "WARNING: could not find \`runtest'" 1>&2; :;\
 	fi; \
 	exit $$exit_status
-site.exp: Makefile
+site.exp: Makefile $(EXTRA_DEJAGNU_SITE_CONFIG)
 	@echo 'Making a new site.exp file...'
 	@echo '## these variables are automatically generated by make ##' >site.tmp
 	@echo '# Do not edit here.  If you wish to override these values' >>site.tmp
 	@echo '# edit the last section' >>site.tmp
-	@echo 'set srcdir $(srcdir)' >>site.tmp
+	@echo 'set srcdir "$(srcdir)"' >>site.tmp
 	@echo "set objdir `pwd`" >>site.tmp
 	@echo 'set build_alias "$(build_alias)"' >>site.tmp
 	@echo 'set build_triplet $(build_triplet)' >>site.tmp
@@ -294,9 +317,16 @@
 	@echo 'set host_triplet $(host_triplet)' >>site.tmp
 	@echo 'set target_alias "$(target_alias)"' >>site.tmp
 	@echo 'set target_triplet $(target_triplet)' >>site.tmp
-	@echo '## All variables above are generated by configure. Do Not Edit ##' >>site.tmp
-	@test ! -f site.exp || \
-	  sed '1,/^## All variables above are.*##/ d' site.exp >> site.tmp
+	@list='$(EXTRA_DEJAGNU_SITE_CONFIG)'; for f in $$list; do \
+	  echo "## Begin content included from file $$f.  Do not modify. ##" \
+	   && cat `test -f "$$f" || echo '$(srcdir)/'`$$f \
+	   && echo "## End content included from file $$f. ##" \
+	   || exit 1; \
+	 done >> site.tmp
+	@echo "## End of auto-generated content; you can edit from here. ##" >> site.tmp
+	@if test -f site.exp; then \
+	   sed -e '1,/^## End of auto-generated content.*##/d' site.exp >> site.tmp; \
+	 fi
 	@-rm -f site.bak
 	@test ! -f site.exp || mv site.exp site.bak
 	@mv site.tmp site.exp
@@ -321,10 +351,15 @@
 
 installcheck: installcheck-am
 install-strip:
-	$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
-	  install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
-	  `test -z '$(STRIP)' || \
-	    echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+	if test -z '$(STRIP)'; then \
+	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	      install; \
+	else \
+	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	    "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+	fi
 mostlyclean-generic:
 
 clean-generic:
diff --git a/third_party/gofrontend/libgo/testsuite/gotest b/third_party/gofrontend/libgo/testsuite/gotest
index 3596d72..19cc6be 100755
--- a/third_party/gofrontend/libgo/testsuite/gotest
+++ b/third_party/gofrontend/libgo/testsuite/gotest
@@ -26,14 +26,15 @@
 # gofiles are the test files.  pkgfiles are the source files.
 srcdir=.
 basedir=.
+goarch=""
 gofiles=""
+goos=""
 pkgfiles=""
 loop=true
 keep=false
 pkgpath=
 prefix=
 dejagnu=no
-GOARCH=""
 timeout=240
 testname=""
 bench=""
@@ -58,6 +59,24 @@
 		basedir=`echo $1 | sed -e 's/^--basedir=//'`
 		shift
 		;;
+	x--goarch)
+		goarch=$2
+		shift
+		shift
+		;;
+	x--goarch=*)
+		goarch=`echo $1 | sed -e 's/^--goarch=//'`
+		shift
+		;;
+	x--goos)
+		goos=$2
+		shift
+		shift
+		;;
+	x--goos=*)
+		goos=`echo $1 | sed -e 's/^--goos=//'`
+		shift
+		;;
 	x--pkgpath)
 		pkgpath=$2
 		shift
@@ -98,15 +117,6 @@
 		dejagnu=`echo $1 | sed -e 's/^--dejagnu=//'`
 		shift
 		;;
-	x--goarch)
-		GOARCH=$2
-		shift
-		shift
-		;;
-	x--goarch=*)
-		GOARCH=`echo $1 | sed -e 's/^--goarch=//'`
-		shift
-		;;
 	x--timeout)
 		timeout=$2
 		shift
@@ -268,7 +278,96 @@
 
 case "x$gofiles" in
 x)
-	gofiles=`ls *_test.go 2>/dev/null`
+	for f in `ls *_test.go`; do
+	    tag1=`echo $f | sed -e 's/^.*_\([^_]*\)_test.go$/\1/'`
+	    tag2=`echo $f | sed -e 's/^.*_\([^_]*\)_[^_]*_test.go$/\1/'`
+	    if test x$tag1 = x$f; then
+		tag1=
+	    fi
+	    if test x$tag2 = x$f; then
+		tag2=
+	    fi
+
+	    case "$tag1" in
+	    "") ;;
+	    $goarch) ;;
+	    $goos) ;;
+	    android | darwin | dragonfly | freebsd | linux | nacl | netbsd | openbsd | plan9 | solaris | windows)
+		tag1=nonmatchingtag
+		;;
+	    386 | amd64 | amd64p32 | arm | armbe | arm64 | arm64be | alpha | m68k | ppc64 | ppc64le | mips | mipsle | mips64 | mips64le | mips64p32 | mips64p32le | mipso32 | mipsn32 | mipsn64 | mipso64 | ppc | s390 | s390x | sparc | sparc64)
+		tag1=nonmatchingtag
+		;;
+	    esac
+
+	    case "$tag2" in
+	    "") ;;
+	    $goarch) ;;
+	    $goos) ;;
+	    android | darwin | dragonfly | freebsd | linux | nacl | netbsd | openbsd | plan9 | solaris | windows)
+		tag2=nonmatchingtag
+		;;
+	    386 | amd64 | amd64p32 | arm | armbe | arm64 | arm64be | alpha | m68k | ppc64 | ppc64le | mips | mipsle | mips64 | mips64le | mips64p32 | mips64p32le | mipso32 | mipsn32 | mipsn64 | mipso64 | ppc | s390 | s390x | sparc | sparc64)
+		tag2=nonmatchingtag
+		;;
+	    esac
+
+	    if test x$tag1 != xnonmatchingtag -a x$tag2 != xnonmatchingtag; then
+		taglines=`sed '/^package /q' < $f | fgrep '// +build '`
+		if test "$taglines" = ""; then
+		    omatch=true
+		else
+		    omatch=false
+		fi
+		for tags in $taglines; do
+		    match=false
+		    for tag in $tags; do
+			reverse=false
+			case $tag in
+			"!"*)
+			    reverse=true
+			    tag=`echo $tag | sed -e 's/^!//'`
+			    ;;
+			esac
+
+			case $tag in
+			"//" | "+build")
+			    ;;
+			$goos | $goarch | cgo)
+			    match=true
+			    ;;
+			*,*)
+			    match=true
+			    for ctag in `echo $tag | sed -e 's/,/ /g'`; do
+				case $ctag in
+				$goos | $goarch | cgo)
+				    ;;
+				*)
+				    match=false
+				    ;;
+				esac
+			    done
+			    ;;
+			esac
+
+			if test "$reverse" = true; then
+			    if test "$match" = true; then
+				match=false
+			    else
+				match=true
+			    fi
+			fi
+		    done
+		    if test "$match" = "true"; then
+			omatch=true
+		    fi
+		done
+
+		if test "$omatch" = "true"; then
+		    gofiles="$gofiles $f"
+		fi
+	    fi
+	done
 	;;
 *)
 	xgofiles=$gofiles
@@ -387,7 +486,7 @@
 
 {
 	text="T"
-	case "$GOARCH" in
+	case "$goarch" in
 	ppc64*) text="[TD]" ;;
 	esac
 
@@ -504,6 +603,7 @@
 	fi
 	${GL} *.o ${GOLIBS}
 
+	set +e
 	if test "$bench" = ""; then
 		if test "$trace" = "true"; then
 		    echo ./a.out -test.short -test.timeout=${timeout}s "$@"
@@ -518,7 +618,12 @@
 		wait $pid
 		status=$?
 		if ! test -f gotest-timeout; then
+		    sleeppid=`ps -o pid,ppid,cmd | grep " $alarmpid " | grep sleep | sed -e 's/ *\([0-9]*\) .*$/\1/'`
 		    kill $alarmpid
+		    wait $alarmpid
+		    if test "$sleeppid" != ""; then
+			kill $sleeppid
+		    fi
 		fi
 	else
 		if test "$trace" = "true"; then
diff --git a/third_party/gotools/go/ssa/lift.go b/third_party/gotools/go/ssa/lift.go
index 56abe6d..e7996cc 100644
--- a/third_party/gotools/go/ssa/lift.go
+++ b/third_party/gotools/go/ssa/lift.go
@@ -18,8 +18,8 @@
 // Software Practice and Experience 2001, 4:1-10.
 // http://www.hipersoft.rice.edu/grads/publications/dom14.pdf
 //
-// Daniel Berlin, llvm-dev mailing list, 2012.
-// http://lists.llvm.org/pipermail/llvm-dev/2012-January/046638.html
+// Daniel Berlin, llvmdev mailing list, 2012.
+// http://lists.cs.uiuc.edu/pipermail/llvmdev/2012-January/046638.html
 // (Be sure to expand the whole thread.)
 
 // TODO(adonovan): opt: there are many optimizations worth evaluating, and
diff --git a/third_party/liner/README.md b/third_party/liner/README.md
index 99027c6..9148b24 100644
--- a/third_party/liner/README.md
+++ b/third_party/liner/README.md
@@ -21,8 +21,8 @@
 Ctrl-E, End  | Move cursor to end of line
 Ctrl-B, Left | Move cursor one character left
 Ctrl-F, Right| Move cursor one character right
-Ctrl-Left    | Move cursor to previous word
-Ctrl-Right   | Move cursor to next word
+Ctrl-Left, Alt-B    | Move cursor to previous word
+Ctrl-Right, Alt-F   | Move cursor to next word
 Ctrl-D, Del  | (if line is *not* empty) Delete character under cursor
 Ctrl-D       | (if line *is* empty) End of File - usually quits application
 Ctrl-C       | Reset input (create new empty prompt)
@@ -48,13 +48,14 @@
 import (
 	"log"
 	"os"
+	"path/filepath"
 	"strings"
 
 	"github.com/peterh/liner"
 )
 
 var (
-	history_fn = "/tmp/.liner_history"
+	history_fn = filepath.Join(os.TempDir(), ".liner_example_history")
 	names      = []string{"john", "james", "mary", "nancy"}
 )
 
@@ -62,6 +63,8 @@
 	line := liner.NewLiner()
 	defer line.Close()
 
+	line.SetCtrlCAborts(true)
+
 	line.SetCompleter(func(line string) (c []string) {
 		for _, n := range names {
 			if strings.HasPrefix(n, strings.ToLower(line)) {
@@ -76,11 +79,13 @@
 		f.Close()
 	}
 
-	if name, err := line.Prompt("What is your name? "); err != nil {
-		log.Print("Error reading line: ", err)
-	} else {
+	if name, err := line.Prompt("What is your name? "); err == nil {
 		log.Print("Got: ", name)
 		line.AppendHistory(name)
+	} else if err == liner.ErrPromptAborted {
+		log.Print("Aborted")
+	} else {
+		log.Print("Error reading line: ", err)
 	}
 
 	if f, err := os.Create(history_fn); err != nil {
diff --git a/third_party/liner/common.go b/third_party/liner/common.go
index 9424abe..53b8f8f 100644
--- a/third_party/liner/common.go
+++ b/third_party/liner/common.go
@@ -29,6 +29,9 @@
 	ctrlCAborts       bool
 	r                 *bufio.Reader
 	tabStyle          TabStyle
+	multiLineMode     bool
+	cursorRows        int
+	maxRows           int
 }
 
 // TabStyle is used to select how tab completions are displayed.
@@ -207,6 +210,11 @@
 	s.ctrlCAborts = aborts
 }
 
+// SetMultiLineMode sets whether line is auto-wrapped. The default is false (single line).
+func (s *State) SetMultiLineMode(mlmode bool) {
+	s.multiLineMode = mlmode
+}
+
 func (s *State) promptUnsupported(p string) (string, error) {
 	if !s.inputRedirected || !s.terminalSupported {
 		fmt.Print(p)
diff --git a/third_party/liner/input.go b/third_party/liner/input.go
index 94a8215..c80c85f 100644
--- a/third_party/liner/input.go
+++ b/third_party/liner/input.go
@@ -329,6 +329,12 @@
 		default:
 			return unknown, nil
 		}
+	case 'b':
+		s.pending = s.pending[:0] // escape code complete
+		return altB, nil
+	case 'f':
+		s.pending = s.pending[:0] // escape code complete
+		return altF, nil
 	case 'y':
 		s.pending = s.pending[:0] // escape code complete
 		return altY, nil
diff --git a/third_party/liner/input_windows.go b/third_party/liner/input_windows.go
index cc98719..9dcc311 100644
--- a/third_party/liner/input_windows.go
+++ b/third_party/liner/input_windows.go
@@ -132,6 +132,8 @@
 	vk_f10    = 0x79
 	vk_f11    = 0x7a
 	vk_f12    = 0x7b
+	bKey      = 0x42
+	fKey      = 0x46
 	yKey      = 0x59
 )
 
@@ -178,6 +180,12 @@
 
 		if ke.VirtualKeyCode == vk_tab && ke.ControlKeyState&modKeys == shiftPressed {
 			s.key = shiftTab
+		} else if ke.VirtualKeyCode == bKey && (ke.ControlKeyState&modKeys == leftAltPressed ||
+			ke.ControlKeyState&modKeys == rightAltPressed) {
+			s.key = altB
+		} else if ke.VirtualKeyCode == fKey && (ke.ControlKeyState&modKeys == leftAltPressed ||
+			ke.ControlKeyState&modKeys == rightAltPressed) {
+			s.key = altF
 		} else if ke.VirtualKeyCode == yKey && (ke.ControlKeyState&modKeys == leftAltPressed ||
 			ke.ControlKeyState&modKeys == rightAltPressed) {
 			s.key = altY
diff --git a/third_party/liner/line.go b/third_party/liner/line.go
index 87ce693..daa66b9 100644
--- a/third_party/liner/line.go
+++ b/third_party/liner/line.go
@@ -37,6 +37,8 @@
 	f10
 	f11
 	f12
+	altB
+	altF
 	altY
 	shiftTab
 	wordLeft
@@ -88,6 +90,14 @@
 )
 
 func (s *State) refresh(prompt []rune, buf []rune, pos int) error {
+	if s.multiLineMode {
+		return s.refreshMultiLine(prompt, buf, pos)
+	} else {
+		return s.refreshSingleLine(prompt, buf, pos)
+	}
+}
+
+func (s *State) refreshSingleLine(prompt []rune, buf []rune, pos int) error {
 	s.cursorPos(0)
 	_, err := fmt.Print(string(prompt))
 	if err != nil {
@@ -143,6 +153,82 @@
 	return err
 }
 
+func (s *State) refreshMultiLine(prompt []rune, buf []rune, pos int) error {
+	promptColumns := countMultiLineGlyphs(prompt, s.columns, 0)
+	totalColumns := countMultiLineGlyphs(buf, s.columns, promptColumns)
+	totalRows := (totalColumns + s.columns - 1) / s.columns
+	maxRows := s.maxRows
+	if totalRows > s.maxRows {
+		s.maxRows = totalRows
+	}
+	cursorRows := s.cursorRows
+	if cursorRows == 0 {
+		cursorRows = 1
+	}
+
+	/* First step: clear all the lines used before. To do so start by
+	* going to the last row. */
+	if maxRows-cursorRows > 0 {
+		s.moveDown(maxRows - cursorRows)
+	}
+
+	/* Now for every row clear it, go up. */
+	for i := 0; i < maxRows-1; i++ {
+		s.cursorPos(0)
+		s.eraseLine()
+		s.moveUp(1)
+	}
+
+	/* Clean the top line. */
+	s.cursorPos(0)
+	s.eraseLine()
+
+	/* Write the prompt and the current buffer content */
+	if _, err := fmt.Print(string(prompt)); err != nil {
+		return err
+	}
+	if _, err := fmt.Print(string(buf)); err != nil {
+		return err
+	}
+
+	/* If we are at the very end of the screen with our prompt, we need to
+	 * emit a newline and move the prompt to the first column. */
+	cursorColumns := countMultiLineGlyphs(buf[:pos], s.columns, promptColumns)
+	if cursorColumns == totalColumns && totalColumns%s.columns == 0 {
+		s.emitNewLine()
+		s.cursorPos(0)
+		totalRows++
+		if totalRows > s.maxRows {
+			s.maxRows = totalRows
+		}
+	}
+
+	/* Move cursor to right position. */
+	cursorRows = (cursorColumns + s.columns) / s.columns
+	if s.cursorRows > 0 && totalRows-cursorRows > 0 {
+		s.moveUp(totalRows - cursorRows)
+	}
+	/* Set column. */
+	s.cursorPos(cursorColumns % s.columns)
+
+	s.cursorRows = cursorRows
+	return nil
+}
+
+func (s *State) resetMultiLine(prompt []rune, buf []rune, pos int) {
+	columns := countMultiLineGlyphs(prompt, s.columns, 0)
+	columns = countMultiLineGlyphs(buf[:pos], s.columns, columns)
+	columns += 2 // ^C
+	cursorRows := (columns + s.columns) / s.columns
+	if s.maxRows-cursorRows > 0 {
+		for i := 0; i < s.maxRows-cursorRows; i++ {
+			fmt.Println() // always moves the cursor down or scrolls the window up as needed
+		}
+	}
+	s.maxRows = 1
+	s.cursorRows = 0
+}
+
 func longestCommonPrefix(strs []string) string {
 	if len(strs) == 0 {
 		return ""
@@ -179,6 +265,29 @@
 	}
 }
 
+func calculateColumns(screenWidth int, items []string) (numColumns, numRows, maxWidth int) {
+	for _, item := range items {
+		if len(item) >= screenWidth {
+			return 1, len(items), screenWidth - 1
+		}
+		if len(item) >= maxWidth {
+			maxWidth = len(item) + 1
+		}
+	}
+
+	numColumns = screenWidth / maxWidth
+	numRows = len(items) / numColumns
+	if len(items)%numColumns > 0 {
+		numRows++
+	}
+
+	if len(items) <= numColumns {
+		maxWidth = 0
+	}
+
+	return
+}
+
 func (s *State) printedTabs(items []string) func(tabDirection) (string, error) {
 	numTabs := 1
 	prefix := longestCommonPrefix(items)
@@ -206,27 +315,14 @@
 				}
 			}
 			fmt.Println("")
-			maxWidth := 0
-			for _, item := range items {
-				if len(item) >= maxWidth {
-					maxWidth = len(item) + 1
-				}
-			}
 
-			numColumns := s.columns / maxWidth
-			numRows := len(items) / numColumns
-			if len(items)%numColumns > 0 {
-				numRows++
-			}
+			numColumns, numRows, maxWidth := calculateColumns(s.columns, items)
 
-			if len(items) <= numColumns {
-				maxWidth = 0
-			}
 			for i := 0; i < numRows; i++ {
 				for j := 0; j < numColumns*numRows; j += numRows {
 					if i+j < len(items) {
 						if maxWidth > 0 {
-							fmt.Printf("%-*s", maxWidth, items[i+j])
+							fmt.Printf("%-*.[1]*s", maxWidth, items[i+j])
 						} else {
 							fmt.Printf("%v ", items[i+j])
 						}
@@ -500,6 +596,9 @@
 		case rune:
 			switch v {
 			case cr, lf:
+				if s.multiLineMode {
+					s.resetMultiLine(p, line, pos)
+				}
 				fmt.Println()
 				break mainLoop
 			case ctrlA: // Start of line
@@ -601,6 +700,9 @@
 				s.refresh(p, line, pos)
 			case ctrlC: // reset
 				fmt.Println("^C")
+				if s.multiLineMode {
+					s.resetMultiLine(p, line, pos)
+				}
 				if s.ctrlCAborts {
 					return "", ErrPromptAborted
 				}
@@ -685,7 +787,7 @@
 			case 0, 28, 29, 30, 31:
 				fmt.Print(beep)
 			default:
-				if pos == len(line) && len(p)+len(line) < s.columns-1 {
+				if pos == len(line) && !s.multiLineMode && countGlyphs(p)+countGlyphs(line) < s.columns-1 {
 					line = append(line, v)
 					fmt.Printf("%c", v)
 					pos++
@@ -710,11 +812,21 @@
 				} else {
 					fmt.Print(beep)
 				}
-			case wordLeft:
+			case wordLeft, altB:
 				if pos > 0 {
+					var spaceHere, spaceLeft, leftKnown bool
 					for {
 						pos--
-						if pos == 0 || unicode.IsSpace(line[pos-1]) {
+						if pos == 0 {
+							break
+						}
+						if leftKnown {
+							spaceHere = spaceLeft
+						} else {
+							spaceHere = unicode.IsSpace(line[pos])
+						}
+						spaceLeft, leftKnown = unicode.IsSpace(line[pos-1]), true
+						if !spaceHere && spaceLeft {
 							break
 						}
 					}
@@ -727,11 +839,21 @@
 				} else {
 					fmt.Print(beep)
 				}
-			case wordRight:
+			case wordRight, altF:
 				if pos < len(line) {
+					var spaceHere, spaceLeft, hereKnown bool
 					for {
 						pos++
-						if pos == len(line) || unicode.IsSpace(line[pos]) {
+						if pos == len(line) {
+							break
+						}
+						if hereKnown {
+							spaceLeft = spaceHere
+						} else {
+							spaceLeft = unicode.IsSpace(line[pos-1])
+						}
+						spaceHere, hereKnown = unicode.IsSpace(line[pos]), true
+						if spaceHere && !spaceLeft {
 							break
 						}
 					}
@@ -767,6 +889,19 @@
 				pos = 0
 			case end: // End of line
 				pos = len(line)
+			case winch: // Window change
+				if s.multiLineMode {
+					if s.maxRows-s.cursorRows > 0 {
+						s.moveDown(s.maxRows - s.cursorRows)
+					}
+					for i := 0; i < s.maxRows-1; i++ {
+						s.cursorPos(0)
+						s.eraseLine()
+						s.moveUp(1)
+					}
+					s.maxRows = 1
+					s.cursorRows = 1
+				}
 			}
 			s.refresh(p, line, pos)
 		}
@@ -814,6 +949,9 @@
 		case rune:
 			switch v {
 			case cr, lf:
+				if s.multiLineMode {
+					s.resetMultiLine(p, line, pos)
+				}
 				fmt.Println()
 				break mainLoop
 			case ctrlD: // del
@@ -838,6 +976,9 @@
 				}
 			case ctrlC:
 				fmt.Println("^C")
+				if s.multiLineMode {
+					s.resetMultiLine(p, line, pos)
+				}
 				if s.ctrlCAborts {
 					return "", ErrPromptAborted
 				}
diff --git a/third_party/liner/line_test.go b/third_party/liner/line_test.go
index 727da6c..42aeb2f 100644
--- a/third_party/liner/line_test.go
+++ b/third_party/liner/line_test.go
@@ -2,6 +2,7 @@
 
 import (
 	"bytes"
+	"fmt"
 	"strings"
 	"testing"
 )
@@ -88,3 +89,49 @@
 		t.Fatal("Wrong number of history entries read the 3rd time")
 	}
 }
+
+func TestColumns(t *testing.T) {
+	list := []string{"foo", "food", "This entry is quite a bit longer than the typical entry"}
+
+	output := []struct {
+		width, columns, rows, maxWidth int
+	}{
+		{80, 1, 3, len(list[2]) + 1},
+		{120, 2, 2, len(list[2]) + 1},
+		{800, 14, 1, 0},
+		{8, 1, 3, 7},
+	}
+
+	for i, o := range output {
+		col, row, max := calculateColumns(o.width, list)
+		if col != o.columns {
+			t.Fatalf("Wrong number of columns, %d != %d, in TestColumns %d\n", col, o.columns, i)
+		}
+		if row != o.rows {
+			t.Fatalf("Wrong number of rows, %d != %d, in TestColumns %d\n", row, o.rows, i)
+		}
+		if max != o.maxWidth {
+			t.Fatalf("Wrong column width, %d != %d, in TestColumns %d\n", max, o.maxWidth, i)
+		}
+	}
+}
+
+// This example demonstrates a way to retrieve the current
+// history buffer without using a file.
+func ExampleState_WriteHistory() {
+	var s State
+	s.AppendHistory("foo")
+	s.AppendHistory("bar")
+
+	buf := new(bytes.Buffer)
+	_, err := s.WriteHistory(buf)
+	if err == nil {
+		history := strings.Split(strings.TrimSpace(buf.String()), "\n")
+		for i, line := range history {
+			fmt.Println("History entry", i, ":", line)
+		}
+	}
+	// Output:
+	// History entry 0 : foo
+	// History entry 1 : bar
+}
diff --git a/third_party/liner/output.go b/third_party/liner/output.go
index e91f4ea..049273b 100644
--- a/third_party/liner/output.go
+++ b/third_party/liner/output.go
@@ -31,6 +31,18 @@
 	fmt.Print("\x1b[H\x1b[2J")
 }
 
+func (s *State) moveUp(lines int) {
+	fmt.Printf("\x1b[%dA", lines)
+}
+
+func (s *State) moveDown(lines int) {
+	fmt.Printf("\x1b[%dB", lines)
+}
+
+func (s *State) emitNewLine() {
+	fmt.Print("\n")
+}
+
 type winSize struct {
 	row, col       uint16
 	xpixel, ypixel uint16
diff --git a/third_party/liner/output_windows.go b/third_party/liner/output_windows.go
index 27ae55a..45cd978 100644
--- a/third_party/liner/output_windows.go
+++ b/third_party/liner/output_windows.go
@@ -47,6 +47,24 @@
 	procSetConsoleCursorPosition.Call(uintptr(s.hOut), 0)
 }
 
+func (s *State) moveUp(lines int) {
+	var sbi consoleScreenBufferInfo
+	procGetConsoleScreenBufferInfo.Call(uintptr(s.hOut), uintptr(unsafe.Pointer(&sbi)))
+	procSetConsoleCursorPosition.Call(uintptr(s.hOut),
+		uintptr(int(sbi.dwCursorPosition.x)&0xFFFF|(int(sbi.dwCursorPosition.y)-lines)<<16))
+}
+
+func (s *State) moveDown(lines int) {
+	var sbi consoleScreenBufferInfo
+	procGetConsoleScreenBufferInfo.Call(uintptr(s.hOut), uintptr(unsafe.Pointer(&sbi)))
+	procSetConsoleCursorPosition.Call(uintptr(s.hOut),
+		uintptr(int(sbi.dwCursorPosition.x)&0xFFFF|(int(sbi.dwCursorPosition.y)+lines)<<16))
+}
+
+func (s *State) emitNewLine() {
+	// windows doesn't need to omit a new line
+}
+
 func (s *State) getColumns() {
 	var sbi consoleScreenBufferInfo
 	procGetConsoleScreenBufferInfo.Call(uintptr(s.hOut), uintptr(unsafe.Pointer(&sbi)))
diff --git a/third_party/liner/width.go b/third_party/liner/width.go
index 5c6bf68..d8984aa 100644
--- a/third_party/liner/width.go
+++ b/third_party/liner/width.go
@@ -36,6 +36,25 @@
 	return n
 }
 
+func countMultiLineGlyphs(s []rune, columns int, start int) int {
+	n := start
+	for _, r := range s {
+		switch {
+		case unicode.IsOneOf(zeroWidth, r):
+		case unicode.IsOneOf(doubleWidth, r):
+			n += 2
+			// no room for a 2-glyphs-wide char in the ending
+			// so skip a column and display it at the beginning
+			if n%columns == 1 {
+				n++
+			}
+		default:
+			n++
+		}
+	}
+	return n
+}
+
 func getPrefixGlyphs(s []rune, num int) []rune {
 	p := 0
 	for n := 0; n < num && p < len(s); p++ {
diff --git a/update_third_party.sh b/update_third_party.sh
index 29b13e9..9b9daed 100755
--- a/update_third_party.sh
+++ b/update_third_party.sh
@@ -4,8 +4,8 @@
 llgosrcdir=$(dirname "$scriptpath")
 cd $llgosrcdir
 
-gofrontendrepo=https://code.google.com/p/gofrontend
-gofrontendrev=15a24202fa42
+gofrontendrepo=https://go.googlesource.com/gofrontend
+gofrontendrev=81eb6a3f425b2158c67ee32c0cc973a72ce9d6be
 
 gccrepo=svn://gcc.gnu.org/svn/gcc/trunk
 gccrev=219477
@@ -14,7 +14,7 @@
 gotoolsrev=d4e70101500b43ffe705d4c45e50dd4f1c8e3b2e
 
 linerrepo=https://github.com/peterh/liner.git
-linerrev=1bb0d1c1a25ed393d8feb09bab039b2b1b1fbced
+linerrev=4d47685ab2fd2dbb46c66b831344d558bc4be5b9
 
 tempdir=$(mktemp -d /tmp/update_third_party.XXXXXX)
 gofrontenddir=$tempdir/gofrontend
@@ -24,9 +24,21 @@
 rm -rf third_party
 mkdir -p third_party/gofrontend third_party/gotools
 
+git_clone() {
+    repo=$1
+    dir=$2
+    rev=$3
+    git clone $repo $dir
+    (
+        cd $dir
+        git checkout $rev
+        rm -fr .git
+    )
+}
+
 # --------------------- gofrontend ---------------------
 
-hg clone -r $gofrontendrev $gofrontendrepo $gofrontenddir
+git_clone $gofrontendrepo $gofrontenddir $gofrontendrev
 
 cp -r $gofrontenddir/LICENSE $gofrontenddir/libgo third_party/gofrontend
 
@@ -60,8 +72,8 @@
 cp include/unwind-pe.h third_party/gofrontend/libgcc/
 
 # Note: this expects the llgo source tree to be located at llvm/tools/llgo.
-cp ../../autoconf/config.guess third_party/gofrontend/
-cp ../../autoconf/config.sub third_party/gofrontend/
+cp ../../cmake/config.guess third_party/gofrontend/
+cp autoconf/config.sub third_party/gofrontend/
 
 for d in libbacktrace libffi ; do
   svn export -r $gccrev $gccrepo/$d third_party/gofrontend/$d
@@ -88,8 +100,7 @@
 
 # --------------------- go.tools ---------------------
 
-git clone $gotoolsrepo $gotoolsdir
-(cd $gotoolsdir && git checkout $gotoolsrev)
+git_clone $gotoolsrepo $gotoolsdir $gotoolsrev
 
 cp -r $gotoolsdir/LICENSE $gotoolsdir/go third_party/gotools
 
@@ -99,8 +110,7 @@
 
 # --------------------- peterh/liner -----------------
 
-git clone $linerrepo $linerdir
-(cd $linerdir && git checkout $linerrev && rm -rf .git)
+git_clone $linerrepo $linerdir $linerrev
 
 # --------------------- license check ---------------------