diff mbox

Go patch committed: Update libgo to Go release r60

Message ID mcrpqj0xzdv.fsf@coign.corp.google.com
State New
Headers show

Commit Message

Ian Lance Taylor Sept. 16, 2011, 3:47 p.m. UTC
I've committed a patch to mainline which updates libgo to the version in
the Go r60 release.  I haven't appended all the changes here, as they
are too large, and in any case most of them are just copied directly
from the master Go library repository.  I have only appended the changes
to files which are not directly copied.  Bootstrapped and ran Go
testsuite on x86_64-unknown-linux-gnu.  Committed to mainline.

History shows that Go library updates sometimes break the Go build on
non-GNU/Linux targets.  I tried to be careful this time, but please let
me know about any new problems.

Ian

Comments

Rainer Orth Sept. 22, 2011, 4:37 p.m. UTC | #1
Ian Lance Taylor <iant@google.com> writes:

> History shows that Go library updates sometimes break the Go build on
> non-GNU/Linux targets.  I tried to be careful this time, but please let
> me know about any new problems.

As expected, this did break Solaris bootstrap and will also break IRIX
bootstrap:

* The Solaris 11/x86 libgo bootstrap dies like this:

/vol/gcc/src/hg/trunk/local/libgo/syscalls/exec.go:11:14: error: imported and not used: unsafe
/vol/gcc/src/hg/trunk/local/libgo/syscalls/exec.go:172:20: error: reference to undefined name 'TIOCNOTTY'
/vol/gcc/src/hg/trunk/local/libgo/syscalls/exec.go:179:20: error: reference to undefined name 'TIOCSCTTY'

  Don't know about the first one, but the two ioctl's are missing from
  sysinfo.go.  They are defined in <sys/termios.h>, but if I include
  that in mksysinfo.sh, they only show up as 

// unknowndefine TIOCNOTTY (tIOC|113)

  in gen-sysinfo.go.  No idea why yet.

* IRIX will be worse: while it has TIOCNOTTY, it completely lacks
  TIOCSCTTY.

Suggestions?

	Rainer
Ian Lance Taylor Sept. 22, 2011, 5:09 p.m. UTC | #2
Rainer Orth <ro@CeBiTec.Uni-Bielefeld.DE> writes:

> Ian Lance Taylor <iant@google.com> writes:
>
>> History shows that Go library updates sometimes break the Go build on
>> non-GNU/Linux targets.  I tried to be careful this time, but please let
>> me know about any new problems.
>
> As expected, this did break Solaris bootstrap and will also break IRIX
> bootstrap:
>
> * The Solaris 11/x86 libgo bootstrap dies like this:
>
> /vol/gcc/src/hg/trunk/local/libgo/syscalls/exec.go:11:14: error: imported and not used: unsafe

That is odd since the file clearly does use unsafe.  Perhaps it is
somehow a consequence of the other errors.


> /vol/gcc/src/hg/trunk/local/libgo/syscalls/exec.go:172:20: error: reference to undefined name 'TIOCNOTTY'
> /vol/gcc/src/hg/trunk/local/libgo/syscalls/exec.go:179:20: error: reference to undefined name 'TIOCSCTTY'
>
>   Don't know about the first one, but the two ioctl's are missing from
>   sysinfo.go.  They are defined in <sys/termios.h>, but if I include
>   that in mksysinfo.sh, they only show up as 
>
> // unknowndefine TIOCNOTTY (tIOC|113)
>
>   in gen-sysinfo.go.  No idea why yet.

Is tIOC defined in gen-sysinfo.go?  In <sys/termios.h>?  Does some other
header file need to be #included first?


> * IRIX will be worse: while it has TIOCNOTTY, it completely lacks
>   TIOCSCTTY.
>
> Suggestions?

For a missing TIOCSCTTY I think the simplest solution will be to set it
in syscall_irix.go to some innocuous value if there is one.  E.g.,
TIOCNXCL if Irix supports that.  If there is no innocuous value, let's
just set it to 0 and test for 0 in exec.go before calling ioctl.

Similarly, if we can't get TIOCNOTTY defined in sysinfo.go, then I think
it's OK to just define it directly in syscall_irix.go and
syscall_solaris.go.  Those values are not going to change with different
versions of the OS.

Thanks for looking at this.

Ian
Rainer Orth Sept. 23, 2011, 11:39 a.m. UTC | #3
Ian Lance Taylor <iant@google.com> writes:

>> * The Solaris 11/x86 libgo bootstrap dies like this:
>>
>> /vol/gcc/src/hg/trunk/local/libgo/syscalls/exec.go:11:14: error: imported and not used: unsafe
>
> That is odd since the file clearly does use unsafe.  Perhaps it is
> somehow a consequence of the other errors.

Perhaps, we'll see.

>> /vol/gcc/src/hg/trunk/local/libgo/syscalls/exec.go:172:20: error: reference to undefined name 'TIOCNOTTY'
>> /vol/gcc/src/hg/trunk/local/libgo/syscalls/exec.go:179:20: error: reference to undefined name 'TIOCSCTTY'
>>
>>   Don't know about the first one, but the two ioctl's are missing from
>>   sysinfo.go.  They are defined in <sys/termios.h>, but if I include
>>   that in mksysinfo.sh, they only show up as 
>>
>> // unknowndefine TIOCNOTTY (tIOC|113)
>>
>>   in gen-sysinfo.go.  No idea why yet.
>
> Is tIOC defined in gen-sysinfo.go?  In <sys/termios.h>?  Does some other

Only as

// unknowndefine tIOC ('t'<<8)

> header file need to be #included first?

No, <sys/termios.h> is self-contained.

>> * IRIX will be worse: while it has TIOCNOTTY, it completely lacks
>>   TIOCSCTTY.
>>
>> Suggestions?
>
> For a missing TIOCSCTTY I think the simplest solution will be to set it
> in syscall_irix.go to some innocuous value if there is one.  E.g.,
> TIOCNXCL if Irix supports that.  If there is no innocuous value, let's

Yep, IRIX has that.

> just set it to 0 and test for 0 in exec.go before calling ioctl.
>
> Similarly, if we can't get TIOCNOTTY defined in sysinfo.go, then I think
> it's OK to just define it directly in syscall_irix.go and
> syscall_solaris.go.  Those values are not going to change with different
> versions of the OS.

That certainly works as a fallback, but I'd rather avoid the hardcoding
if it can be reasonably avoided.

	Rainer
diff mbox

Patch

diff -r b6085c06b2eb libgo/MERGE
--- a/libgo/MERGE	Thu Sep 15 22:42:45 2011 -0700
+++ b/libgo/MERGE	Fri Sep 16 07:26:10 2011 -0700
@@ -1,4 +1,4 @@ 
-aea0ba6e5935
+504f4e9b079c
 
 The first line of this file holds the Mercurial revision number of the
 last merge done from the master library sources.
diff -r b6085c06b2eb libgo/Makefile.am
--- a/libgo/Makefile.am	Thu Sep 15 22:42:45 2011 -0700
+++ b/libgo/Makefile.am	Fri Sep 16 07:26:10 2011 -0700
@@ -106,6 +106,7 @@ 
 	bytes.gox \
 	cmath.gox \
 	crypto.gox \
+	csv.gox \
 	ebnf.gox \
 	exec.gox \
 	expvar.gox \
@@ -120,6 +121,7 @@ 
 	json.gox \
 	log.gox \
 	math.gox \
+	mail.gox \
 	mime.gox \
 	net.gox \
 	netchan.gox \
@@ -145,6 +147,7 @@ 
 	time.gox \
 	try.gox \
 	unicode.gox \
+	url.gox \
 	utf16.gox \
 	utf8.gox \
 	websocket.gox \
@@ -206,10 +209,16 @@ 
 
 toolexeclibgocryptoopenpgp_DATA = \
 	crypto/openpgp/armor.gox \
+	crypto/openpgp/elgamal.gox \
 	crypto/openpgp/error.gox \
 	crypto/openpgp/packet.gox \
 	crypto/openpgp/s2k.gox
 
+toolexeclibgocryptox509dir = $(toolexeclibgocryptodir)/x509
+
+toolexeclibgocryptox509_DATA = \
+	crypto/x509/pkix.gox
+
 toolexeclibgodebugdir = $(toolexeclibgodir)/debug
 
 toolexeclibgodebug_DATA = \
@@ -217,8 +226,7 @@ 
 	debug/elf.gox \
 	debug/gosym.gox \
 	debug/macho.gox \
-	debug/pe.gox \
-	debug/proc.gox
+	debug/pe.gox
 
 toolexeclibgoencodingdir = $(toolexeclibgodir)/encoding
 
@@ -227,7 +235,6 @@ 
 	encoding/base32.gox \
 	encoding/base64.gox \
 	encoding/binary.gox \
-	encoding/line.gox \
 	encoding/git85.gox \
 	encoding/hex.gox \
 	encoding/pem.gox
@@ -236,13 +243,30 @@ 
 
 toolexeclibgoexp_DATA = \
 	exp/datafmt.gox \
-	exp/draw.gox \
-	exp/eval.gox
+	exp/gui.gox \
+	exp/norm.gox \
+	exp/regexp.gox
+
+toolexeclibgoexpguidir = $(toolexeclibgoexpdir)/gui
+
+toolexeclibgoexpgui_DATA = \
+	exp/gui/x11.gox
+
+toolexeclibgoexpregexpdir = $(toolexeclibgoexpdir)/regexp
+
+toolexeclibgoexpregexp_DATA = \
+	exp/regexp/syntax.gox
+
+toolexeclibgoexptemplatedir = $(toolexeclibgoexpdir)/template
+
+toolexeclibgoexptemplate_DATA = \
+	exp/template/html.gox
 
 toolexeclibgogodir = $(toolexeclibgodir)/go
 
 toolexeclibgogo_DATA = \
 	go/ast.gox \
+	go/build.gox \
 	go/doc.gox \
 	go/parser.gox \
 	go/printer.gox \
@@ -271,6 +295,8 @@ 
 toolexeclibgoimagedir = $(toolexeclibgodir)/image
 
 toolexeclibgoimage_DATA = \
+	image/bmp.gox \
+	image/draw.gox \
 	image/gif.gox \
 	image/jpeg.gox \
 	image/png.gox \
@@ -298,6 +324,11 @@ 
 	net/dict.gox \
 	net/textproto.gox
 
+toolexeclibgoolddir = $(toolexeclibgodir)/old
+
+toolexeclibgoold_DATA = \
+	old/template.gox
+
 toolexeclibgoosdir = $(toolexeclibgodir)/os
 
 if LIBGO_IS_LINUX
@@ -328,6 +359,11 @@ 
 	runtime/debug.gox \
 	runtime/pprof.gox
 
+toolexeclibgotemplatedir = $(toolexeclibgodir)/template
+
+toolexeclibgotemplate_DATA = \
+	template/parse.gox
+
 toolexeclibgosyncdir = $(toolexeclibgodir)/sync
 
 toolexeclibgosync_DATA = \
@@ -394,6 +430,7 @@ 
 	runtime/go-panic.c \
 	runtime/go-panic-defer.c \
 	runtime/go-print.c \
+	runtime/go-rand.c \
 	runtime/go-rec-big.c \
 	runtime/go-rec-nb-big.c \
 	runtime/go-rec-nb-small.c \
@@ -519,6 +556,10 @@ 
 go_crypto_files = \
 	go/crypto/crypto.go
 
+go_csv_files = \
+	go/csv/reader.go \
+	go/csv/writer.go
+
 go_ebnf_files = \
 	go/ebnf/ebnf.go \
 	go/ebnf/parser.go
@@ -552,9 +593,11 @@ 
 	go/hash/hash.go
 
 go_html_files = \
+	go/html/const.go \
 	go/html/doc.go \
 	go/html/entity.go \
 	go/html/escape.go \
+	go/html/node.go \
 	go/html/parse.go \
 	go/html/token.go
 
@@ -571,10 +614,10 @@ 
 	go/http/response.go \
 	go/http/reverseproxy.go \
 	go/http/server.go \
+	go/http/sniff.go \
 	go/http/status.go \
 	go/http/transfer.go \
-	go/http/transport.go \
-	go/http/url.go
+	go/http/transport.go
 
 go_image_files = \
 	go/image/color.go \
@@ -646,6 +689,9 @@ 
 	go/math/tanh.go \
 	go/math/unsafe.go
 
+go_mail_files = \
+	go/mail/message.go
+
 go_mime_files = \
 	go/mime/grammar.go \
 	go/mime/mediatype.go \
@@ -684,11 +730,24 @@ 
 endif
 endif
 
+if LIBGO_IS_LINUX
+go_net_sendfile_file = go/net/sendfile_linux.go
+else
+go_net_sendfile_file = go/net/sendfile_stub.go
+endif
+
+if LIBGO_IS_LINUX
+go_net_interface_file = go/net/interface_linux.go
+else
+go_net_interface_file = go/net/interface_stub.go
+endif
+
 go_net_files = \
 	go/net/cgo_unix.go \
 	$(go_net_cgo_file) \
 	go/net/dial.go \
 	go/net/dnsclient.go \
+	go/net/dnsclient_unix.go \
 	go/net/dnsconfig.go \
 	go/net/dnsmsg.go \
 	$(go_net_newpollserver_file) \
@@ -696,19 +755,27 @@ 
 	$(go_net_fd_os_file) \
 	go/net/file.go \
 	go/net/hosts.go \
+	go/net/interface.go \
+	$(go_net_interface_file) \
 	go/net/ip.go \
 	go/net/iprawsock.go \
+	go/net/iprawsock_posix.go \
 	go/net/ipsock.go \
-	go/net/lookup.go \
+	go/net/ipsock_posix.go \
+	go/net/lookup_unix.go \
 	go/net/net.go \
 	go/net/parse.go \
 	go/net/pipe.go \
 	go/net/port.go \
+	$(go_net_sendfile_file) \
 	go/net/sock.go \
 	$(go_net_sock_file) \
 	go/net/tcpsock.go \
+	go/net/tcpsock_posix.go \
 	go/net/udpsock.go \
-	go/net/unixsock.go
+	go/net/udpsock_posix.go \
+	go/net/unixsock.go \
+	go/net/unixsock_posix.go
 
 go_netchan_files = \
 	go/netchan/common.go \
@@ -766,11 +833,14 @@ 
 	go/os/file_unix.go \
 	go/os/getwd.go \
 	go/os/path.go \
+	go/os/path_unix.go \
 	go/os/proc.go \
 	go/os/stat.go \
+	go/os/str.go \
 	$(go_os_sys_file) \
 	go/os/time.go \
-	go/os/types.go
+	go/os/types.go \
+	signal_unix.go
 
 go_patch_files = \
 	go/patch/apply.go \
@@ -874,8 +944,12 @@ 
 	go/tabwriter/tabwriter.go
 
 go_template_files = \
-	go/template/format.go \
-	go/template/template.go
+	go/template/doc.go \
+	go/template/exec.go \
+	go/template/funcs.go \
+	go/template/helper.go \
+	go/template/parse.go \
+	go/template/set.go
 
 go_testing_files = \
 	go/testing/benchmark.go \
@@ -885,8 +959,10 @@ 
 	go/time/format.go \
 	go/time/sleep.go \
 	go/time/sys.go \
+	go/time/sys_posix.go \
 	go/time/tick.go \
 	go/time/time.go \
+	go/time/zoneinfo_posix.go \
 	go/time/zoneinfo_unix.go
 
 go_try_files = \
@@ -895,9 +971,13 @@ 
 go_unicode_files = \
 	go/unicode/casetables.go \
 	go/unicode/digit.go \
+	go/unicode/graphic.go \
 	go/unicode/letter.go \
 	go/unicode/tables.go
 
+go_url_files = \
+	go/url/url.go
+
 go_utf16_files = \
 	go/utf16/utf16.go
 
@@ -911,6 +991,7 @@ 
 	go/websocket/websocket.go
 
 go_xml_files = \
+	go/xml/marshal.go \
 	go/xml/read.go \
 	go/xml/xml.go
 
@@ -921,7 +1002,8 @@ 
 
 go_archive_zip_files = \
 	go/archive/zip/reader.go \
-	go/archive/zip/struct.go
+	go/archive/zip/struct.go \
+	go/archive/zip/writer.go
 
 go_compress_bzip2_files = \
 	go/compress/bzip2/bit_reader.go \
@@ -1010,7 +1092,8 @@ 
 	go/crypto/openpgp/write.go
 go_crypto_rand_files = \
 	go/crypto/rand/rand.go \
-	go/crypto/rand/rand_unix.go
+	go/crypto/rand/rand_unix.go \
+	go/crypto/rand/util.go
 go_crypto_rc4_files = \
 	go/crypto/rc4/rc4.go
 go_crypto_ripemd160_files = \
@@ -1054,6 +1137,8 @@ 
 go_crypto_openpgp_armor_files = \
 	go/crypto/openpgp/armor/armor.go \
 	go/crypto/openpgp/armor/encode.go
+go_crypto_openpgp_elgamal_files = \
+	go/crypto/openpgp/elgamal/elgamal.go
 go_crypto_openpgp_error_files = \
 	go/crypto/openpgp/error/error.go
 go_crypto_openpgp_packet_files = \
@@ -1072,6 +1157,9 @@ 
 go_crypto_openpgp_s2k_files = \
 	go/crypto/openpgp/s2k/s2k.go
 
+go_crypto_x509_pkix_files = \
+	go/crypto/x509/pkix/pkix.go
+
 go_debug_dwarf_files = \
 	go/debug/dwarf/buf.go \
 	go/debug/dwarf/const.go \
@@ -1092,11 +1180,6 @@ 
 	go/debug/pe/file.go \
 	go/debug/pe/pe.go
 
-go_debug_proc_files = \
-	go/debug/proc/proc.go \
-	go/debug/proc/proc_$(GOOS).go \
-	$(GO_DEBUG_PROC_REGS_OS_ARCH_FILE)
-
 go_encoding_ascii85_files = \
 	go/encoding/ascii85/ascii85.go
 go_encoding_base32_files = \
@@ -1109,30 +1192,39 @@ 
 	go/encoding/git85/git.go
 go_encoding_hex_files = \
 	go/encoding/hex/hex.go
-go_encoding_line_files = \
-	go/encoding/line/line.go
 go_encoding_pem_files = \
 	go/encoding/pem/pem.go
 
 go_exp_datafmt_files = \
 	go/exp/datafmt/datafmt.go \
 	go/exp/datafmt/parser.go
-go_exp_draw_files = \
-	go/exp/draw/draw.go \
-	go/exp/draw/event.go
-go_exp_eval_files = \
-	go/exp/eval/abort.go \
-	go/exp/eval/bridge.go \
-	go/exp/eval/compiler.go \
-	go/exp/eval/expr.go \
-	go/exp/eval/expr1.go \
-	go/exp/eval/func.go \
-	go/exp/eval/scope.go \
-	go/exp/eval/stmt.go \
-	go/exp/eval/type.go \
-	go/exp/eval/typec.go \
-	go/exp/eval/value.go \
-	go/exp/eval/world.go
+go_exp_gui_files = \
+	go/exp/gui/gui.go
+go_exp_norm_files = \
+	go/exp/norm/composition.go \
+	go/exp/norm/forminfo.go \
+	go/exp/norm/normalize.go \
+	go/exp/norm/tables.go \
+	go/exp/norm/trie.go
+go_exp_regexp_files = \
+	go/exp/regexp/exec.go \
+	go/exp/regexp/regexp.go
+
+go_exp_gui_x11_files = \
+	go/exp/gui/x11/auth.go \
+	go/exp/gui/x11/conn.go
+
+go_exp_template_html_files = \
+	go/exp/template/html/context.go \
+	go/exp/template/html/escape.go
+
+go_exp_regexp_syntax_files = \
+	go/exp/regexp/syntax/compile.go \
+	go/exp/regexp/syntax/parse.go \
+	go/exp/regexp/syntax/perl_groups.go \
+	go/exp/regexp/syntax/prog.go \
+	go/exp/regexp/syntax/regexp.go \
+	go/exp/regexp/syntax/simplify.go
 
 go_go_ast_files = \
 	go/go/ast/ast.go \
@@ -1141,6 +1233,11 @@ 
 	go/go/ast/resolve.go \
 	go/go/ast/scope.go \
 	go/go/ast/walk.go
+go_go_build_files = \
+	go/go/build/build.go \
+	go/go/build/dir.go \
+	go/go/build/path.go \
+	syslist.go
 go_go_doc_files = \
 	go/go/doc/comment.go \
 	go/go/doc/doc.go
@@ -1162,6 +1259,7 @@ 
 	go/go/typechecker/typechecker.go \
 	go/go/typechecker/universe.go
 go_go_types_files = \
+	go/go/types/check.go \
 	go/go/types/const.go \
 	go/go/types/exportdata.go \
 	go/go/types/gcimporter.go \
@@ -1171,7 +1269,8 @@ 
 go_hash_adler32_files = \
 	go/hash/adler32/adler32.go
 go_hash_crc32_files = \
-	go/hash/crc32/crc32.go
+	go/hash/crc32/crc32.go \
+	go/hash/crc32/crc32_generic.go
 go_hash_crc64_files = \
 	go/hash/crc64/crc64.go
 go_hash_fnv_files = \
@@ -1189,7 +1288,15 @@ 
 go_http_pprof_files = \
 	go/http/pprof/pprof.go
 go_http_spdy_files = \
-	go/http/spdy/protocol.go
+	go/http/spdy/read.go \
+	go/http/spdy/types.go \
+	go/http/spdy/write.go
+
+go_image_bmp_files = \
+	go/image/bmp/reader.go
+
+go_image_draw_files = \
+	go/image/draw/draw.go
 
 go_image_gif_files = \
 	go/image/gif/reader.go
@@ -1223,7 +1330,8 @@ 
 
 go_mime_multipart_files = \
 	go/mime/multipart/formdata.go \
-	go/mime/multipart/multipart.go
+	go/mime/multipart/multipart.go \
+	go/mime/multipart/writer.go
 
 go_net_dict_files = \
 	go/net/dict/dict.go
@@ -1235,6 +1343,12 @@ 
 	go/net/textproto/textproto.go \
 	go/net/textproto/writer.go
 
+go_old_template_files = \
+	go/old/template/doc.go \
+	go/old/template/execute.go \
+	go/old/template/format.go \
+	go/old/template/parse.go
+
 go_os_inotify_files = \
 	go/os/inotify/inotify_linux.go
 
@@ -1243,8 +1357,7 @@ 
 	go/os/user/lookup_unix.go
 
 go_os_signal_files = \
-	go/os/signal/signal.go \
-	unix.go
+	go/os/signal/signal.go
 
 go_path_filepath_files = \
 	go/path/filepath/match.go \
@@ -1260,6 +1373,12 @@ 
 go_runtime_pprof_files = \
 	go/runtime/pprof/pprof.go
 
+go_template_parse_files = \
+	go/template/parse/lex.go \
+	go/template/parse/node.go \
+	go/template/parse/parse.go \
+	go/template/parse/set.go
+
 go_sync_atomic_files = \
 	go/sync/atomic/doc.go
 go_sync_atomic_c_files = \
@@ -1391,6 +1510,13 @@ 
 syscall_uname_file = syscalls/syscall_uname.go
 endif
 
+# Support for netlink sockets and messages.
+if LIBGO_IS_LINUX
+syscall_netlink_file = syscalls/netlink_linux.go
+else
+syscall_netlink_file =
+endif
+
 syscall_arch.go: s-syscall_arch; @true
 s-syscall_arch: Makefile
 	rm -f syscall_arch.go.tmp
@@ -1407,6 +1533,7 @@ 
 	$(syscall_exec_os_file) \
 	$(syscall_wait_file) \
 	$(syscall_filesize_file) \
+	$(syscall_netlink_file) \
 	$(syscall_stat_file) \
 	$(syscall_sleep_file) \
 	syscalls/socket.go \
@@ -1439,6 +1566,7 @@ 
 	bytes/index.lo \
 	cmath/cmath.lo \
 	crypto/crypto.lo \
+	csv/csv.lo \
 	ebnf/ebnf.lo \
 	exec/exec.lo \
 	expvar/expvar.lo \
@@ -1453,6 +1581,7 @@ 
 	json/json.lo \
 	log/log.lo \
 	math/math.lo \
+	mail/mail.lo \
 	mime/mime.lo \
 	net/net.lo \
 	netchan/netchan.lo \
@@ -1477,6 +1606,7 @@ 
 	time/time.lo \
 	try/try.lo \
 	unicode/unicode.lo \
+	url/url.lo \
 	utf16/utf16.lo \
 	utf8/utf8.lo \
 	websocket/websocket.lo \
@@ -1518,27 +1648,32 @@ 
 	crypto/x509.lo \
 	crypto/xtea.lo \
 	crypto/openpgp/armor.lo \
+	crypto/openpgp/elgamal.lo \
 	crypto/openpgp/error.lo \
 	crypto/openpgp/packet.lo \
 	crypto/openpgp/s2k.lo \
+	crypto/x509/pkix.lo \
 	debug/dwarf.lo \
 	debug/elf.lo \
 	debug/gosym.lo \
 	debug/macho.lo \
 	debug/pe.lo \
-	debug/proc.lo \
 	encoding/ascii85.lo \
 	encoding/base32.lo \
 	encoding/base64.lo \
 	encoding/binary.lo \
 	encoding/git85.lo \
 	encoding/hex.lo \
-	encoding/line.lo \
 	encoding/pem.lo \
 	exp/datafmt.lo \
-	exp/draw.lo \
-	exp/eval.lo \
+	exp/gui.lo \
+	exp/norm.lo \
+	exp/regexp.lo \
+	exp/gui/x11.lo \
+	exp/regexp/syntax.lo \
+	exp/template/html.lo \
 	go/ast.lo \
+	go/build.lo \
 	go/doc.lo \
 	go/parser.lo \
 	go/printer.lo \
@@ -1555,6 +1690,8 @@ 
 	http/httptest.lo \
 	http/pprof.lo \
 	http/spdy.lo \
+	image/bmp.lo \
+	image/draw.lo \
 	image/gif.lo \
 	image/jpeg.lo \
 	image/png.lo \
@@ -1565,6 +1702,7 @@ 
 	mime/multipart.lo \
 	net/dict.lo \
 	net/textproto.lo \
+	old/template.lo \
 	$(os_lib_inotify_lo) \
 	os/user.lo \
 	os/signal.lo \
@@ -1576,6 +1714,7 @@ 
 	sync/atomic_c.lo \
 	syscalls/syscall.lo \
 	syscalls/errno.lo \
+	template/parse.lo \
 	testing/testing.lo \
 	testing/iotest.lo \
 	testing/quick.lo \
@@ -1647,18 +1786,6 @@ 
 	  fi; \
 	fi
 
-# Check a package that is only tested if GCCGO_RUN_ALL_TESTS is set.
-CHECK_ON_REQUEST = \
-	if test "$$GCCGO_RUN_ALL_TESTS" != ""; then \
-	  $(CHECK); \
-	else \
-	  rm -f $@-testsum $@-testlog; \
-	  echo "Set GCCGO_RUN_ALL_TESTS in environment to run $(@D) test" > $@-testlog; \
-	  echo "UNTESTED: $(@D)" >> $@-testlog; \
-	  echo "UNTESTED: $(@D)"; \
-	  echo "UNTESTED: $(@D)" > $@-testsum; \
-	fi
-
 # Build all packages before checking any.
 CHECK_DEPS = libgo.la libgobegin.a \
 	$(toolexeclibgo_DATA) \
@@ -1685,14 +1812,15 @@ 
 	$(toolexeclibgosync_DATA) \
 	$(toolexeclibgotesting_DATA)
 
-asn1/asn1.lo: $(go_asn1_files) bytes.gox fmt.gox io.gox os.gox reflect.gox \
-		strconv.gox strings.gox time.gox
+asn1/asn1.lo: $(go_asn1_files) big.gox bytes.gox fmt.gox io.gox os.gox \
+		reflect.gox strconv.gox strings.gox time.gox
 	$(BUILDPACKAGE)
 asn1/check: $(CHECK_DEPS)
 	@$(CHECK)
 .PHONY: asn1/check
 
-big/big.lo: $(go_big_files) fmt.gox rand.gox strings.gox os.gox
+big/big.lo: $(go_big_files) encoding/binary.gox fmt.gox io.gox os.gox \
+		rand.gox strings.gox
 	$(BUILDPACKAGE)
 big/check: $(CHECK_DEPS)
 	@$(CHECK)
@@ -1724,6 +1852,13 @@ 
 	@$(CHECK)
 .PHONY: crypto/check
 
+csv/csv.lo: $(go_csv_files) bufio.gox bytes.gox fmt.gox io.gox os.gox \
+		strings.gox unicode.gox utf8.gox
+	$(BUILDPACKAGE)
+csv/check: $(CHECK_DEPS)
+	@$(CHECK)
+.PHONY: csv/check
+
 ebnf/ebnf.lo: $(go_ebnf_files) container/vector.gox go/scanner.gox \
 		go/token.gox os.gox strconv.gox unicode.gox utf8.gox
 	$(BUILDPACKAGE)
@@ -1731,7 +1866,8 @@ 
 	@$(CHECK)
 .PHONY: ebnf/check
 
-exec/exec.lo: $(go_exec_files) os.gox strconv.gox strings.gox
+exec/exec.lo: $(go_exec_files) bytes.gox io.gox os.gox strconv.gox \
+		strings.gox syscall.gox
 	$(BUILDPACKAGE)
 exec/check: $(CHECK_DEPS)
 	@$(CHECK)
@@ -1779,11 +1915,11 @@ 
 .PHONY: html/check
 
 http/http.lo: $(go_http_files) bufio.gox bytes.gox compress/gzip.gox \
-		container/vector.gox crypto/rand.gox crypto/tls.gox \
-		encoding/base64.gox fmt.gox io.gox io/ioutil.gox log.gox \
+		crypto/rand.gox crypto/tls.gox encoding/base64.gox \
+		encoding/binary.gox fmt.gox io.gox io/ioutil.gox log.gox \
 		mime.gox mime/multipart.gox net.gox net/textproto.gox os.gox \
-		path.gox path/filepath.gox sort.gox strconv.gox strings.gox \
-		sync.gox time.gox utf8.gox
+		path.gox path/filepath.gox runtime/debug.gox sort.gox \
+		strconv.gox strings.gox sync.gox time.gox url.gox utf8.gox
 	$(BUILDPACKAGE)
 http/check: $(CHECK_DEPS)
 	@$(CHECK)
@@ -1801,10 +1937,9 @@ 
 	@$(CHECK)
 .PHONY: io/check
 
-json/json.lo: $(go_json_files) bytes.gox container/vector.gox \
-		encoding/base64.gox fmt.gox io.gox math.gox os.gox \
-		reflect.gox runtime.gox strconv.gox strings.gox unicode.gox \
-		utf16.gox utf8.gox
+json/json.lo: $(go_json_files) bytes.gox encoding/base64.gox fmt.gox io.gox \
+		math.gox os.gox reflect.gox runtime.gox strconv.gox \
+		strings.gox unicode.gox utf16.gox utf8.gox
 	$(BUILDPACKAGE)
 json/check: $(CHECK_DEPS)
 	@$(CHECK)
@@ -1823,6 +1958,14 @@ 
 	@$(CHECK)
 .PHONY: math/check
 
+mail/mail.lo: $(go_mail_files) bufio.gox bytes.gox encoding/base64.gox \
+		fmt.gox io.gox io/ioutil.gox log.gox net/textproto.gox os.gox \
+		strconv.gox strings.gox time.gox
+	$(BUILDPACKAGE)
+mail/check: $(CHECK_DEPS)
+	@$(CHECK)
+.PHONY: mail/check
+
 mime/mime.lo: $(go_mime_files) bufio.gox bytes.gox fmt.gox os.gox strings.gox \
 		sync.gox unicode.gox
 	$(BUILDPACKAGE)
@@ -1835,7 +1978,7 @@ 
 		syscall.gox time.gox
 	$(BUILDPACKAGE)
 net/check: $(CHECK_DEPS)
-	@$(CHECK_ON_REQUEST)
+	@$(CHECK)
 .PHONY: net/check
 
 netchan/netchan.lo: $(go_netchan_files) gob.gox io.gox log.gox net.gox os.gox \
@@ -1851,6 +1994,10 @@ 
 	@$(CHECK)
 .PHONY: os/check
 
+signal_unix.go: $(srcdir)/go/os/mkunixsignals.sh sysinfo.go
+	$(SHELL) $(srcdir)/go/os/mkunixsignals.sh sysinfo.go > $@.tmp
+	mv -f $@.tmp $@
+
 patch/patch.lo: $(go_patch_files) bytes.gox compress/zlib.gox \
 		crypto/sha1.gox encoding/git85.gox fmt.gox io.gox os.gox \
 		path.gox strings.gox
@@ -1913,7 +2060,7 @@ 
 	@$(CHECK)
 .PHONY: smtp/check
 
-sort/sort.lo: $(go_sort_files)
+sort/sort.lo: $(go_sort_files) math.gox
 	$(BUILDPACKAGE)
 sort/check: $(CHECK_DEPS)
 	@$(CHECK)
@@ -1943,7 +2090,7 @@ 
 syslog/syslog_c.lo: $(go_syslog_c_files) syslog/syslog.lo
 	$(LTCOMPILE) -c -o $@ $(srcdir)/go/syslog/syslog_c.c
 syslog/check: $(CHECK_DEPS)
-	@$(CHECK_ON_REQUEST)
+	@$(CHECK)
 .PHONY: syslog/check
 
 tabwriter/tabwriter.lo: $(go_tabwriter_files) bytes.gox io.gox os.gox utf8.gox
@@ -1952,15 +2099,17 @@ 
 	@$(CHECK)
 .PHONY: tabwriter/check
 
-template/template.lo: $(go_template_files) bytes.gox fmt.gox io.gox os.gox \
-		reflect.gox runtime.gox strings.gox container/vector.gox
+template/template.lo: $(go_template_files) bytes.gox fmt.gox io.gox \
+		io/ioutil.gox os.gox path/filepath.gox reflect.gox \
+		runtime.gox strings.gox template/parse.gox unicode.gox \
+		url.gox utf8.gox
 	$(BUILDPACKAGE)
 template/check: $(CHECK_DEPS)
 	@$(CHECK)
 .PHONY: template/check
 
 testing/testing.lo: $(go_testing_files) flag.gox fmt.gox os.gox regexp.gox \
-		runtime.gox runtime/pprof.gox time.gox
+		runtime.gox runtime/pprof.gox strings.gox strconv.gox time.gox
 	$(BUILDPACKAGE)
 testing/check: $(CHECK_DEPS)
 	@$(CHECK)
@@ -1985,6 +2134,12 @@ 
 	@$(CHECK)
 .PHONY: unicode/check
 
+url/url.lo: $(go_url_files) os.gox strconv.gox strings.gox
+	$(BUILDPACKAGE)
+url/check: $(CHECK_DEPS)
+	@$(CHECK)
+.PHONY: url/check
+
 utf16/utf16.lo: $(go_utf16_files) unicode.gox
 	$(BUILDPACKAGE)
 utf16/check: $(CHECK_DEPS)
@@ -1998,9 +2153,8 @@ 
 .PHONY: utf8/check
 
 websocket/websocket.lo: $(go_websocket_files) bufio.gox bytes.gox \
-		container/vector.gox crypto/md5.gox crypto/tls.gox \
-		encoding/binary.gox fmt.gox http.gox io.gox net.gox os.gox \
-		rand.gox strings.gox
+		crypto/md5.gox crypto/tls.gox encoding/binary.gox fmt.gox \
+		http.gox io.gox net.gox os.gox rand.gox strings.gox url.gox
 	$(BUILDPACKAGE)
 websocket/check: $(CHECK_DEPS)
 	@$(CHECK)
@@ -2021,9 +2175,9 @@ 
 	@$(CHECK)
 .PHONY: archive/tar/check
 
-archive/zip.lo: $(go_archive_zip_files) bufio.gox bytes.gox \
-		compress/flate.gox hash.gox hash/crc32.gox \
-		encoding/binary.gox io.gox io/ioutil.gox os.gox
+archive/zip.lo: $(go_archive_zip_files) bufio.gox compress/flate.gox \
+		encoding/binary.gox hash.gox hash/crc32.gox \
+		encoding/binary.gox io.gox io/ioutil.gox os.gox time.gox
 	$(BUILDPACKAGE)
 archive/zip/check: $(CHECK_DEPS)
 	@$(MKDIR_P) archive/zip
@@ -2176,25 +2330,27 @@ 
 .PHONY: crypto/md5/check
 
 crypto/ocsp.lo: $(go_crypto_ocsp_files) asn1.gox crypto.gox crypto/rsa.gox \
-		crypto/sha1.gox crypto/x509.gox os.gox time.gox
+		crypto/sha1.gox crypto/x509.gox crypto/x509/pkix.gox os.gox \
+		time.gox
 	$(BUILDPACKAGE)
 crypto/ocsp/check: $(CHECK_DEPS)
 	@$(MKDIR_P) crypto/ocsp
 	@$(CHECK)
 .PHONY: crypto/ocsp/check
 
-crypto/openpgp.lo: $(go_crypto_openpgp_files) crypto.gox crypto/dsa.gox \
+crypto/openpgp.lo: $(go_crypto_openpgp_files) crypto.gox \
 		crypto/openpgp/armor.gox crypto/openpgp/error.gox \
-		crypto/openpgp/packet.gox crypto/rsa.gox crypto/sha256.gox \
-		hash.gox io.gox os.gox strconv.gox time.gox
+		crypto/openpgp/packet.gox crypto/openpgp/s2k.gox \
+		crypto/rand.gox crypto/rsa.gox crypto/sha256.gox hash.gox \
+		io.gox os.gox strconv.gox time.gox
 	$(BUILDPACKAGE)
 crypto/openpgp/check: $(CHECK_DEPS)
 	@$(MKDIR_P) crypto/openpgp
 	@$(CHECK)
 .PHONY: crypto/openpgp/check
 
-crypto/rand.lo: $(go_crypto_rand_files) bufio.gox crypto/aes.gox io.gox \
-		os.gox sync.gox time.gox
+crypto/rand.lo: $(go_crypto_rand_files) big.gox bufio.gox crypto/aes.gox \
+		io.gox os.gox sync.gox time.gox
 	$(BUILDPACKAGE)
 crypto/rand/check: $(CHECK_DEPS)
 	@$(MKDIR_P) crypto/rand
@@ -2215,8 +2371,9 @@ 
 	@$(CHECK)
 .PHONY: crypto/ripemd160/check
 
-crypto/rsa.lo: $(go_crypto_rsa_files) big.gox crypto.gox crypto/sha1.gox \
-		crypto/subtle.gox encoding/hex.gox hash.gox io.gox os.gox
+crypto/rsa.lo: $(go_crypto_rsa_files) big.gox crypto.gox crypto/rand.gox \
+		crypto/sha1.gox crypto/subtle.gox encoding/hex.gox hash.gox \
+		io.gox os.gox
 	$(BUILDPACKAGE)
 crypto/rsa/check: $(CHECK_DEPS)
 	@$(MKDIR_P) crypto/rsa
@@ -2255,9 +2412,9 @@ 
 		crypto/aes.gox crypto/cipher.gox crypto/elliptic.gox \
 		crypto/hmac.gox crypto/md5.gox crypto/rand.gox crypto/rc4.gox \
 		crypto/rsa.gox crypto/sha1.gox crypto/subtle.gox \
-		crypto/x509.gox encoding/pem.gox hash.gox io.gox \
-		io/ioutil.gox net.gox os.gox strconv.gox strings.gox sync.gox \
-		time.gox
+		crypto/x509.gox crypto/x509/pkix.gox encoding/pem.gox \
+		hash.gox io.gox io/ioutil.gox net.gox os.gox strconv.gox \
+		strings.gox sync.gox time.gox
 	$(BUILDPACKAGE)
 crypto/tls/check: $(CHECK_DEPS)
 	@$(MKDIR_P) crypto/tls
@@ -2271,9 +2428,9 @@ 
 	@$(CHECK)
 .PHONY: crypto/twofish/check
 
-crypto/x509.lo: $(go_crypto_x509_files) asn1.gox big.gox bytes.gox \
-		container/vector.gox crypto.gox crypto/rsa.gox \
-		crypto/sha1.gox encoding/pem.gox hash.gox os.gox strings.gox \
+crypto/x509.lo: $(go_crypto_x509_files) asn1.gox big.gox bytes.gox crypto.gox \
+		crypto/dsa.gox crypto/rsa.gox crypto/sha1.gox \
+		crypto/x509/pkix.gox encoding/pem.gox os.gox strings.gox \
 		time.gox
 	$(BUILDPACKAGE)
 crypto/x509/check: $(CHECK_DEPS)
@@ -2296,6 +2453,14 @@ 
 	@$(CHECK)
 .PHONY: crypto/openpgp/armor/check
 
+crypto/openpgp/elgamal.lo: $(go_crypto_openpgp_elgamal_files) big.gox \
+		crypto/rand.gox crypto/subtle.gox io.gox os.gox
+	$(BUILDPACKAGE)
+crypto/openpgp/elgamal/check: $(CHECK_DEPS)
+	@$(MKDIR_P) crypto/openpgp/elgamal
+	@$(CHECK)
+.PHONY: crypto/openpgp/elgamal/check
+
 crypto/openpgp/error.lo: $(go_crypto_openpgp_error_files) strconv.gox
 	$(BUILDPACKAGE)
 crypto/openpgp/error/check: $(CHECK_DEPS)
@@ -2306,9 +2471,10 @@ 
 crypto/openpgp/packet.lo: $(go_crypto_openpgp_packet_files) big.gox bytes.gox \
 		compress/flate.gox compress/zlib.gox crypto.gox \
 		crypto/aes.gox crypto/cast5.gox crypto/cipher.gox \
-		crypto/dsa.gox crypto/openpgp/error.gox \
-		crypto/openpgp/s2k.gox crypto/rand.gox crypto/rsa.gox \
-		crypto/sha1.gox crypto/subtle.gox encoding/binary.gox fmt.gox \
+		crypto/dsa.gox crypto/openpgp/elgamal.gox \
+		crypto/openpgp/error.gox crypto/openpgp/s2k.gox \
+		crypto/rand.gox crypto/rsa.gox crypto/sha1.gox \
+		crypto/subtle.gox encoding/binary.gox fmt.gox \
 		hash.gox io.gox io/ioutil.gox os.gox strconv.gox strings.gox
 	$(BUILDPACKAGE)
 crypto/openpgp/packet/check: $(CHECK_DEPS)
@@ -2317,15 +2483,22 @@ 
 .PHONY: crypto/openpgp/packet/check
 
 crypto/openpgp/s2k.lo: $(go_crypto_openpgp_s2k_files) crypto.gox \
-		crypto/md5.gox crypto/openpgp/error.gox crypto/ripemd160.gox \
-		crypto/sha1.gox crypto/sha256.gox crypto/sha512.gox hash.gox \
-		io.gox os.gox
+		crypto/md5.gox crypto/openpgp/error.gox crypto/rand.gox \
+		crypto/ripemd160.gox crypto/sha1.gox crypto/sha256.gox \
+		crypto/sha512.gox hash.gox io.gox os.gox
 	$(BUILDPACKAGE)
 crypto/openpgp/s2k/check: $(CHECK_DEPS)
 	@$(MKDIR_P) crypto/openpgp/s2k
 	@$(CHECK)
 .PHONY: crypto/openpgp/s2k/check
 
+crypto/x509/pkix.lo: $(go_crypto_x509_pkix_files) asn1.gox big.gox time.gox
+	$(BUILDPACKAGE)
+crypto/x509/pkix/check: $(CHECK_DEPS)
+	@$(MKDIR_P) crypto/x509/pkix
+	@$(CHECK)
+.PHONY: crypto/x509/pkix/check
+
 debug/dwarf.lo: $(go_debug_dwarf_files) encoding/binary.gox os.gox strconv.gox
 	$(BUILDPACKAGE)
 debug/dwarf/check: $(CHECK_DEPS)
@@ -2365,15 +2538,6 @@ 
 	@$(CHECK)
 .PHONY: debug/pe/check
 
-debug/proc.lo: $(go_debug_proc_files) container/vector.gox fmt.gox \
-		io/ioutil.gox os.gox runtime.gox strconv.gox strings.gox \
-		sync.gox syscall.gox
-	$(BUILDPACKAGE)
-debug/proc/check: $(CHECK_DEPS)
-	@$(MKDIR_P) debug/proc
-	@$(CHECK)
-.PHONY: debug/proc/check
-
 encoding/ascii85.lo: $(go_encoding_ascii85_files) io.gox os.gox strconv.gox
 	$(BUILDPACKAGE)
 encoding/ascii85/check: $(CHECK_DEPS)
@@ -2411,20 +2575,13 @@ 
 	@$(CHECK)
 .PHONY: encoding/git85/check
 
-encoding/hex.lo: $(go_encoding_hex_files) os.gox strconv.gox
+encoding/hex.lo: $(go_encoding_hex_files) bytes.gox io.gox os.gox strconv.gox
 	$(BUILDPACKAGE)
 encoding/hex/check: $(CHECK_DEPS)
 	@$(MKDIR_P) encoding/hex
 	@$(CHECK)
 .PHONY: encoding/hex/check
 
-encoding/line.lo: $(go_encoding_line_files) io.gox os.gox
-	$(BUILDPACKAGE)
-encoding/line/check: $(CHECK_DEPS)
-	@$(MKDIR_P) encoding/line
-	@$(CHECK)
-.PHONY: encoding/line/check
-
 encoding/pem.lo: $(go_encoding_pem_files) bytes.gox encoding/base64.gox
 	$(BUILDPACKAGE)
 encoding/pem/check: $(CHECK_DEPS)
@@ -2432,39 +2589,87 @@ 
 	@$(CHECK)
 .PHONY: encoding/pem/check
 
-exp/datafmt.lo: $(go_exp_datafmt_files) bytes.gox container/vector.gox \
-		fmt.gox go/scanner.gox go/token.gox io.gox os.gox reflect.gox \
-		runtime.gox strconv.gox strings.gox
+exp/datafmt.lo: $(go_exp_datafmt_files) bytes.gox fmt.gox go/scanner.gox \
+		go/token.gox io.gox os.gox reflect.gox runtime.gox \
+		strconv.gox strings.gox
 	$(BUILDPACKAGE)
 exp/datafmt/check: $(CHECK_DEPS)
 	@$(MKDIR_P) exp/datafmt
 	@$(CHECK)
 .PHONY: exp/datafmt/check
 
-exp/draw.lo: $(go_exp_draw_files) image.gox image/ycbcr.gox os.gox
+exp/gui.lo: $(go_exp_gui_files) image.gox image/draw.gox os.gox
 	$(BUILDPACKAGE)
-exp/draw/check: $(CHECK_DEPS)
-	@$(MKDIR_P) exp/draw
+exp/gui/check: $(CHECK_DEPS)
+	@$(MKDIR_P) exp/gui
 	@$(CHECK)
-.PHONY: exp/draw/check
-
-exp/eval.lo: $(go_exp_eval_files) big.gox go/ast.gox go/parser.gox \
-		go/scanner.gox go/token.gox fmt.gox log.gox strconv.gox \
-		strings.gox os.gox reflect.gox runtime.gox sort.gox template.gox
+.PHONY: exp/gui/check
+
+exp/norm.lo: $(go_exp_norm_files) utf8.gox
 	$(BUILDPACKAGE)
-exp/eval/check: $(CHECK_DEPS)
-	@$(MKDIR_P) exp/eval
+exp/norm/check: $(CHECK_DEPS)
+	@$(MKDIR_P) exp/norm
 	@$(CHECK)
-.PHONY: exp/eval/check
+.PHONY: exp/norm/check
+
+exp/regexp.lo: $(go_exp_regexp_files) bytes.gox exp/regexp/syntax.gox io.gox \
+		os.gox strings.gox sync.gox utf8.gox
+	$(BUILDPACKAGE)
+exp/regexp/check: $(CHECK_DEPS)
+	@$(MKDIR_P) exp/regexp
+	@$(CHECK)
+.PHONY: exp/regexp/check
+
+exp/gui/x11.lo: $(go_exp_gui_x11_files) bufio.gox exp/gui.gox image.gox \
+		image/draw.gox io.gox log.gox net.gox os.gox strconv.gox \
+		strings.gox time.gox
+	$(BUILDPACKAGE)
+exp/gui/x11/check: $(CHECK_DEPS)
+	@$(MKDIR_P) exp/gui/x11
+	@$(CHECK)
+.PHONY: exp/gui/x11/check
+
+exp/regexp/syntax.lo: $(go_exp_regexp_syntax_files) bytes.gox os.gox sort.gox strconv.gox strings.gox unicode.gox utf8.gox
+	$(BUILDPACKAGE)
+exp/regexp/syntax/check: $(CHECK_DEPS)
+	@$(MKDIR_P) exp/regexp/syntax
+	@$(CHECK)
+.PHONY: exp/regexp/syntax/check
+
+exp/template/html.lo: $(go_exp_template_html_files) fmt.gox template.gox \
+		template/parse.gox
+	$(BUILDPACKAGE)
+exp/template/html/check: $(CHECK_DEPS)
+	@$(MKDIR_P) exp/template/html
+	@$(CHECK)
+.PHONY: exp/template/html/check
 
 go/ast.lo: $(go_go_ast_files) bytes.gox fmt.gox go/scanner.gox go/token.gox \
-		io.gox os.gox reflect.gox unicode.gox utf8.gox
+		io.gox os.gox reflect.gox strconv.gox unicode.gox utf8.gox
 	$(BUILDPACKAGE)
 go/ast/check: $(CHECK_DEPS)
 	@$(MKDIR_P) go/ast
 	@$(CHECK)
 .PHONY: go/ast/check
 
+go/build.lo: $(go_go_build_files) bytes.gox exec.gox fmt.gox go/parser.gox \
+		go/token.gox log.gox os.gox path/filepath.gox regexp.gox \
+		runtime.gox strconv.gox strings.gox runtime.gox
+	$(BUILDPACKAGE)
+go/build/check: $(CHECK_DEPS)
+	@$(MKDIR_P) go/build
+	@$(CHECK)
+.PHONY: go/build/check
+
+syslist.go: s-syslist; @true
+s-syslist: Makefile
+	echo '// Generated automatically by make.' >syslist.go.tmp
+	echo 'package build' >>syslist.go.tmp
+	echo 'const goosList = "$(GOOS)"' >>syslist.go.tmp
+	echo 'const goarchList = "$(GOARCH)"' >>syslist.go.tmp
+	$(SHELL) $(srcdir)/../move-if-change syslist.go.tmp syslist.go
+	$(STAMP) $@
+
 go/doc.lo: $(go_go_doc_files) go/ast.gox go/token.gox io.gox regexp.gox \
 		sort.gox strings.gox template.gox
 	$(BUILDPACKAGE)
@@ -2491,9 +2696,9 @@ 
 	@$(CHECK)
 .PHONY: go/printer/check
 
-go/scanner.lo: $(go_go_scanner_files) bytes.gox container/vector.gox fmt.gox \
-		go/token.gox io.gox os.gox path/filepath.gox sort.gox \
-		strconv.gox unicode.gox utf8.gox
+go/scanner.lo: $(go_go_scanner_files) bytes.gox fmt.gox go/token.gox io.gox \
+		os.gox path/filepath.gox sort.gox strconv.gox unicode.gox \
+		utf8.gox
 	$(BUILDPACKAGE)
 go/scanner/check: $(CHECK_DEPS)
 	@$(MKDIR_P) go/scanner
@@ -2517,7 +2722,7 @@ 
 
 go/types.lo: $(go_go_types_files) big.gox bufio.gox fmt.gox go/ast.gox \
 		go/token.gox io.gox os.gox path/filepath.gox runtime.gox \
-		scanner.gox strconv.gox strings.gox
+		scanner.gox sort.gox strconv.gox strings.gox
 	$(BUILDPACKAGE)
 go/types/check: $(CHECK_DEPS)
 	@$(MKDIR_P) go/types
@@ -2531,7 +2736,7 @@ 
 	@$(CHECK)
 .PHONY: hash/adler32/check
 
-hash/crc32.lo: $(go_hash_crc32_files) hash.gox os.gox
+hash/crc32.lo: $(go_hash_crc32_files) hash.gox os.gox sync.gox
 	$(BUILDPACKAGE)
 hash/crc32/check: $(CHECK_DEPS)
 	@$(MKDIR_P) hash/crc32
@@ -2552,10 +2757,9 @@ 
 	@$(CHECK)
 .PHONY: hash/fnv/check
 
-http/cgi.lo: $(go_http_cgi_files) bufio.gox bytes.gox crypto/tls.gox \
-		exec.gox fmt.gox http.gox net.gox io.gox io/ioutil.gox \
-		log.gox os.gox path/filepath.gox regexp.gox strconv.gox \
-		strings.gox
+http/cgi.lo: $(go_http_cgi_files) bufio.gox crypto/tls.gox exec.gox fmt.gox \
+		http.gox net.gox io.gox io/ioutil.gox log.gox os.gox \
+		path/filepath.gox regexp.gox strconv.gox strings.gox url.gox
 	$(BUILDPACKAGE)
 http/cgi/check: $(CHECK_DEPS)
 	@$(MKDIR_P) http/cgi
@@ -2572,7 +2776,8 @@ 
 .PHONY: http/fcgi/check
 
 http/httptest.lo: $(go_http_httptest_files) bytes.gox crypto/rand.gox \
-		crypto/tls.gox fmt.gox http.gox net.gox os.gox time.gox
+		crypto/tls.gox flag.gox fmt.gox http.gox net.gox os.gox \
+		time.gox
 	$(BUILDPACKAGE)
 http/httptest/check: $(CHECK_DEPS)
 	@$(MKDIR_P) http/httptest
@@ -2596,6 +2801,20 @@ 
 	@$(CHECK)
 .PHONY: http/spdy/check
 
+image/bmp.lo: $(go_image_bmp_files) image.gox io.gox os.gox
+	$(BUILDPACKAGE)
+image/bmp/check: $(CHECK_DEPS)
+	@$(MKDIR_P) image/bmp
+	@$(CHECK)
+.PHONY: image/bmp/check
+
+image/draw.lo: $(go_image_draw_files) image.gox image/ycbcr.gox
+	$(BUILDPACKAGE)
+image/draw/check: $(CHECK_DEPS)
+	@$(MKDIR_P) image/draw
+	@$(CHECK)
+.PHONY: image/draw/check
+
 image/gif.lo: $(go_image_gif_files) bufio.gox compress/lzw.gox fmt.gox \
 		image.gox io.gox os.gox
 	$(BUILDPACKAGE)
@@ -2651,28 +2870,36 @@ 
 	@$(CHECK)
 .PHONY: io/ioutil/check
 
-mime/multipart.lo: $(go_mime_multipart_files) bufio.gox bytes.gox fmt.gox \
-		io.gox io/ioutil.gox mime.gox net/textproto.gox os.gox \
-		regexp.gox
+mime/multipart.lo: $(go_mime_multipart_files) bufio.gox bytes.gox \
+		crypto/rand.gox fmt.gox io.gox io/ioutil.gox mime.gox \
+		net/textproto.gox os.gox strings.gox
 	$(BUILDPACKAGE)
 mime/multipart/check: $(CHECK_DEPS)
 	@$(MKDIR_P) mime/multipart
 	@$(CHECK)
 .PHONY: mime/multipart/check
 
-net/dict.lo: $(go_net_dict_files) container/vector.gox net/textproto.gox \
-		os.gox strconv.gox strings.gox
+net/dict.lo: $(go_net_dict_files) net/textproto.gox os.gox strconv.gox \
+		strings.gox
 	$(BUILDPACKAGE)
 
-net/textproto.lo: $(go_net_textproto_files) bufio.gox bytes.gox \
-		container/vector.gox fmt.gox io.gox io/ioutil.gox net.gox \
-		os.gox strconv.gox sync.gox
+net/textproto.lo: $(go_net_textproto_files) bufio.gox bytes.gox fmt.gox \
+		io.gox io/ioutil.gox net.gox os.gox strconv.gox sync.gox
 	$(BUILDPACKAGE)
 net/textproto/check: $(CHECK_DEPS)
 	@$(MKDIR_P) net/textproto
 	@$(CHECK)
 .PHONY: net/textproto/check
 
+old/template.lo: $(go_old_template_files) bytes.gox fmt.gox io.gox \
+		io/ioutil.gox os.gox reflect.gox strconv.gox strings.gox \
+		unicode.gox utf8.gox
+	$(BUILDPACKAGE)
+old/template/check: $(CHECK_DEPS)
+	@$(MKDIR_P) old/template
+	@$(CHECK)
+.PHONY: old/template/check
+
 os/inotify.lo: $(go_os_inotify_files) fmt.gox os.gox strings.gox syscall.gox
 	$(BUILDPACKAGE)
 os/inotify/check: $(CHECK_DEPS)
@@ -2688,19 +2915,15 @@ 
 	@$(CHECK)
 .PHONY: os/user/check
 
-os/signal.lo: $(go_os_signal_files) runtime.gox strconv.gox
+os/signal.lo: $(go_os_signal_files) os.gox runtime.gox
 	$(BUILDPACKAGE)
 os/signal/check: $(CHECK_DEPS)
 	@$(MKDIR_P) os/signal
 	@$(CHECK)
 .PHONY: os/signal/check
 
-unix.go: $(srcdir)/go/os/signal/mkunix.sh sysinfo.go
-	$(SHELL) $(srcdir)/go/os/signal/mkunix.sh sysinfo.go > $@.tmp
-	mv -f $@.tmp $@
-
-path/filepath.lo: $(go_path_filepath_files) bytes.gox os.gox sort.gox \
-		strings.gox utf8.gox
+path/filepath.lo: $(go_path_filepath_files) bytes.gox os.gox runtime.gox \
+		sort.gox strings.gox utf8.gox
 	$(BUILDPACKAGE)
 path/filepath/check: $(CHECK_DEPS)
 	@$(MKDIR_P) path/filepath
@@ -2740,6 +2963,14 @@ 
 	@$(CHECK)
 .PHONY: sync/atomic/check
 
+template/parse.lo: $(go_template_parse_files) bytes.gox fmt.gox os.gox \
+		runtime.gox strconv.gox strings.gox unicode.gox utf8.gox
+	$(BUILDPACKAGE)
+template/parse/check: $(CHECK_DEPS)
+	@$(MKDIR_P) template/parse
+	@$(CHECK)
+.PHONY: template/parse/check
+
 testing/iotest.lo: $(go_testing_iotest_files) io.gox log.gox os.gox
 	$(BUILDPACKAGE)
 testing/iotest/check: $(CHECK_DEPS)
@@ -2791,6 +3022,8 @@ 
 	$(BUILDGOX)
 crypto.gox: crypto/crypto.lo
 	$(BUILDGOX)
+csv.gox: csv/csv.lo
+	$(BUILDGOX)
 ebnf.gox: ebnf/ebnf.lo
 	$(BUILDGOX)
 exec.gox: exec/exec.lo
@@ -2819,6 +3052,8 @@ 
 	$(BUILDGOX)
 math.gox: math/math.lo
 	$(BUILDGOX)
+mail.gox: mail/mail.lo
+	$(BUILDGOX)
 mime.gox: mime/mime.lo
 	$(BUILDGOX)
 net.gox: net/net.lo
@@ -2869,6 +3104,8 @@ 
 	$(BUILDGOX)
 unicode.gox: unicode/unicode.lo
 	$(BUILDGOX)
+url.gox: url/url.lo
+	$(BUILDGOX)
 utf16.gox: utf16/utf16.lo
 	$(BUILDGOX)
 utf8.gox: utf8/utf8.lo
@@ -2956,6 +3193,8 @@ 
 
 crypto/openpgp/armor.gox: crypto/openpgp/armor.lo
 	$(BUILDGOX)
+crypto/openpgp/elgamal.gox: crypto/openpgp/elgamal.lo
+	$(BUILDGOX)
 crypto/openpgp/error.gox: crypto/openpgp/error.lo
 	$(BUILDGOX)
 crypto/openpgp/packet.gox: crypto/openpgp/packet.lo
@@ -2963,6 +3202,9 @@ 
 crypto/openpgp/s2k.gox: crypto/openpgp/s2k.lo
 	$(BUILDGOX)
 
+crypto/x509/pkix.gox: crypto/x509/pkix.lo
+	$(BUILDGOX)
+
 debug/dwarf.gox: debug/dwarf.lo
 	$(BUILDGOX)
 debug/elf.gox: debug/elf.lo
@@ -2973,8 +3215,6 @@ 
 	$(BUILDGOX)
 debug/pe.gox: debug/pe.lo
 	$(BUILDGOX)
-debug/proc.gox: debug/proc.lo
-	$(BUILDGOX)
 
 encoding/ascii85.gox: encoding/ascii85.lo
 	$(BUILDGOX)
@@ -2988,20 +3228,31 @@ 
 	$(BUILDGOX)
 encoding/hex.gox: encoding/hex.lo
 	$(BUILDGOX)
-encoding/line.gox: encoding/line.lo
-	$(BUILDGOX)
 encoding/pem.gox: encoding/pem.lo
 	$(BUILDGOX)
 
 exp/datafmt.gox: exp/datafmt.lo
 	$(BUILDGOX)
-exp/draw.gox: exp/draw.lo
+exp/gui.gox: exp/gui.lo
 	$(BUILDGOX)
-exp/eval.gox: exp/eval.lo
+exp/norm.gox: exp/norm.lo
 	$(BUILDGOX)
+exp/regexp.gox: exp/regexp.lo
+	$(BUILDGOX)
+
+exp/gui/x11.gox: exp/gui/x11.lo
+	$(BUILDGOX)
+
+exp/regexp/syntax.gox: exp/regexp/syntax.lo
+	$(BUILDGOX)
+
+exp/template/html.gox: exp/template/html.lo
+	$(BUILDGOX)
 
 go/ast.gox: go/ast.lo
 	$(BUILDGOX)
+go/build.gox: go/build.lo
+	$(BUILDGOX)
 go/doc.gox: go/doc.lo
 	$(BUILDGOX)
 go/parser.gox: go/parser.lo
@@ -3037,6 +3288,10 @@ 
 http/spdy.gox: http/spdy.lo
 	$(BUILDGOX)
 
+image/bmp.gox: image/bmp.lo
+	$(BUILDGOX)
+image/draw.gox: image/draw.lo
+	$(BUILDGOX)
 image/gif.gox: image/gif.lo
 	$(BUILDGOX)
 image/jpeg.gox: image/jpeg.lo
@@ -3062,6 +3317,9 @@ 
 net/textproto.gox: net/textproto.lo
 	$(BUILDGOX)
 
+old/template.gox: old/template.lo
+	$(BUILDGOX)
+
 os/inotify.gox: os/inotify.lo
 	$(BUILDGOX)
 os/user.gox: os/user.lo
@@ -3083,6 +3341,9 @@ 
 sync/atomic.gox: sync/atomic.lo
 	$(BUILDGOX)
 
+template/parse.gox: template/parse.lo
+	$(BUILDGOX)
+
 testing/iotest.gox: testing/iotest.lo
 	$(BUILDGOX)
 testing/quick.gox: testing/quick.lo
@@ -3103,6 +3364,7 @@ 
 	bufio/check \
 	bytes/check \
 	cmath/check \
+	csv/check \
 	ebnf/check \
 	exec/check \
 	expvar/check \
@@ -3111,10 +3373,12 @@ 
 	gob/check \
 	html/check \
 	http/check \
+	image/check \
 	io/check \
 	json/check \
 	log/check \
 	math/check \
+	mail/check \
 	mime/check \
 	net/check \
 	netchan/check \
@@ -3138,6 +3402,7 @@ 
 	time/check \
 	try/check \
 	unicode/check \
+	url/check \
 	utf16/check \
 	utf8/check \
 	websocket/check \
@@ -3179,6 +3444,7 @@ 
 	crypto/x509/check \
 	crypto/xtea/check \
 	crypto/openpgp/armor/check \
+	crypto/openpgp/elgamal/check \
 	crypto/openpgp/packet/check \
 	crypto/openpgp/s2k/check \
 	debug/dwarf/check \
@@ -3191,12 +3457,14 @@ 
 	encoding/binary/check \
 	encoding/git85/check \
 	encoding/hex/check \
-	encoding/line/check \
 	encoding/pem/check \
 	exp/datafmt/check \
-	exp/draw/check \
-	exp/eval/check \
+	exp/norm/check \
+	exp/regexp/check \
+	exp/regexp/syntax/check \
+	exp/template/html/check \
 	go/ast/check \
+	$(go_build_check_omitted_since_it_calls_6g) \
 	go/parser/check \
 	go/printer/check \
 	go/scanner/check \
@@ -3210,6 +3478,7 @@ 
 	http/cgi/check \
 	http/fcgi/check \
 	http/spdy/check \
+	image/draw/check \
 	image/jpeg/check \
 	image/png/check \
 	image/tiff/check \
@@ -3218,12 +3487,14 @@ 
 	io/ioutil/check \
 	mime/multipart/check \
 	net/textproto/check \
+	old/template/check \
 	$(os_inotify_check) \
 	os/user/check \
 	os/signal/check \
 	path/filepath/check \
 	rpc/jsonrpc/check \
 	sync/atomic/check \
+	template/parse/check \
 	testing/quick/check \
 	testing/script/check
 
diff -r b6085c06b2eb libgo/configure.ac
--- a/libgo/configure.ac	Thu Sep 15 22:42:45 2011 -0700
+++ b/libgo/configure.ac	Fri Sep 16 07:26:10 2011 -0700
@@ -255,12 +255,6 @@ 
 fi
 AC_SUBST(GO_SYSCALLS_SYSCALL_OS_ARCH_FILE)
 
-GO_DEBUG_PROC_REGS_OS_ARCH_FILE=
-if test -f ${srcdir}/go/debug/proc/regs_${GOOS}_${GOARCH}.go; then
-  GO_DEBUG_PROC_REGS_OS_ARCH_FILE=go/debug/proc/regs_${GOOS}_${GOARCH}.go
-fi
-AC_SUBST(GO_DEBUG_PROC_REGS_OS_ARCH_FILE)
-
 dnl Some targets need special flags to build sysinfo.go.
 case "$target" in
     mips-sgi-irix6.5*)
@@ -431,7 +425,14 @@ 
   ;;
 esac
 
-AC_CHECK_HEADERS(sys/mman.h syscall.h sys/epoll.h sys/ptrace.h sys/syscall.h sys/user.h sys/utsname.h sys/select.h)
+AC_CHECK_HEADERS(sys/mman.h syscall.h sys/epoll.h sys/ptrace.h sys/syscall.h sys/user.h sys/utsname.h sys/select.h sys/socket.h net/if.h)
+
+AC_CHECK_HEADERS([linux/filter.h linux/netlink.h linux/rtnetlink.h], [], [],
+[#ifdef HAVE_SYS_SOCKET_H
+#include <sys/socket.h>
+#endif
+])
+
 AM_CONDITIONAL(HAVE_SYS_MMAN_H, test "$ac_cv_header_sys_mman_h" = yes)
 
 AC_CHECK_FUNCS(srandom random strerror_r strsignal wait4 mincore setenv)
diff -r b6085c06b2eb libgo/merge.sh
--- a/libgo/merge.sh	Thu Sep 15 22:42:45 2011 -0700
+++ b/libgo/merge.sh	Fri Sep 16 07:26:10 2011 -0700
@@ -32,13 +32,13 @@ 
 
 repository=$1
 
-merge_rev=`sed 1q MERGE`
+old_rev=`sed 1q MERGE`
 
 rm -rf ${OLDDIR}
-hg clone -r ${merge_rev} ${repository} ${OLDDIR}
+hg clone -r ${old_rev} ${repository} ${OLDDIR}
 
 rm -rf ${NEWDIR}
-hg clone ${repository} ${NEWDIR}
+hg clone -u release ${repository} ${NEWDIR}
 
 new_rev=`cd ${NEWDIR} && hg log | sed 1q | sed -e 's/.*://'`
 
diff -r b6085c06b2eb libgo/mksysinfo.sh
--- a/libgo/mksysinfo.sh	Thu Sep 15 22:42:45 2011 -0700
+++ b/libgo/mksysinfo.sh	Fri Sep 16 07:26:10 2011 -0700
@@ -42,6 +42,7 @@ 
 #endif
 #include <netinet/tcp.h>
 #include <signal.h>
+#include <sys/ioctl.h>
 #if defined(HAVE_SYSCALL_H)
 #include <syscall.h>
 #endif
@@ -76,11 +77,24 @@ 
 #include <unistd.h>
 #include <netdb.h>
 #include <pwd.h>
+#if defined(HAVE_LINUX_FILTER_H)
+#include <linux/filter.h>
+#endif
+#if defined(HAVE_LINUX_NETLINK_H)
+#include <linux/netlink.h>
+#endif
+#if defined(HAVE_LINUX_RTNETLINK_H)
+#include <linux/rtnetlink.h>
+#endif
+#if defined(HAVE_NET_IF_H)
+#include <net/if.h>
+#endif
 EOF
 
 ${CC} -fdump-go-spec=gen-sysinfo.go -std=gnu99 -S -o sysinfo.s sysinfo.c
 
 echo 'package syscall' > ${OUT}
+echo 'import "unsafe"' >> ${OUT}
 
 # Get all the consts and types, skipping ones which could not be
 # represented in Go and ones which we need to rewrite.  We also skip
@@ -449,7 +463,7 @@ 
 
 # The ip_mreq struct
 grep '^type _ip_mreq ' gen-sysinfo.go | \
-    sed -e 's/_ip_mreq/IpMreq/' \
+    sed -e 's/_ip_mreq/IPMreq/' \
       -e 's/imr_multiaddr/Multiaddr/' \
       -e 's/imr_interface/Interface/' \
       -e 's/_in_addr/[4]byte/g' \
@@ -479,4 +493,96 @@ 
       -e 's/ pw_/ Pw_/g' \
     >> ${OUT}
 
+# The ioctl flags for the controlling TTY.
+grep '^const _TIOC' gen-sysinfo.go | \
+    sed -e 's/^\(const \)_\(TIOC[^= ]*\)\(.*\)$/\1\2 = _\2/' >> ${OUT}
+
+# The nlmsghdr struct.
+grep '^type _nlmsghdr ' gen-sysinfo.go | \
+    sed -e 's/_nlmsghdr/NlMsghdr/' \
+      -e 's/nlmsg_len/Len/' \
+      -e 's/nlmsg_type/Type/' \
+      -e 's/nlmsg_flags/Flags/' \
+      -e 's/nlmsg_seq/Seq/' \
+      -e 's/nlmsg_pid/Pid/' \
+    >> ${OUT}
+
+# The nlmsg flags and operators.
+grep '^const _NLM' gen-sysinfo.go | \
+    sed -e 's/^\(const \)_\(NLM[^= ]*\)\(.*\)$/\1\2 = _\2/' >> ${OUT}
+
+# NLMSG_HDRLEN is defined as an expression using sizeof.
+if ! grep '^const NLMSG_HDRLEN' ${OUT} > /dev/null 2>&1; then
+  if grep '^type NlMsghdr ' ${OUT} > /dev/null 2>&1; then
+    echo 'var NLMSG_HDRLEN = int((unsafe.Sizeof(NlMsghdr{}) + (NLMSG_ALIGNTO-1)) &^ (NLMSG_ALIGNTO-1))' >> ${OUT}
+  fi
+fi
+
+# The rtgenmsg struct.
+grep '^type _rtgenmsg ' gen-sysinfo.go | \
+    sed -e 's/_rtgenmsg/RtGenmsg/' \
+      -e 's/rtgen_family/Family/' \
+    >> ${OUT}
+
+# The routing message flags.
+grep '^const _RTA' gen-sysinfo.go | \
+    sed -e 's/^\(const \)_\(RTA[^= ]*\)\(.*\)$/\1\2 = _\2/' >> ${OUT}
+grep '^const _RTM' gen-sysinfo.go | \
+    sed -e 's/^\(const \)_\(RTM[^= ]*\)\(.*\)$/\1\2 = _\2/' >> ${OUT}
+
+# The size of the rtgenmsg struct.
+if grep 'type RtGenmsg ' ${OUT} > /dev/null 2>&1; then
+  echo 'var SizeofRtGenmsg = int(unsafe.Sizeof(RtGenmsg{}))' >> ${OUT}
+fi
+
+# The ifinfomsg struct.
+grep '^type _ifinfomsg ' gen-sysinfo.go | \
+    sed -e 's/_ifinfomsg/IfInfomsg/' \
+      -e 's/ifi_family/Family/' \
+      -e 's/ifi_type/Type/' \
+      -e 's/ifi_index/Index/' \
+      -e 's/ifi_flags/Flags/' \
+      -e 's/ifi_change/Change/' \
+    >> ${OUT}
+
+# The interface information types and flags.
+grep '^const _IFA' gen-sysinfo.go | \
+    sed -e 's/^\(const \)_\(IFA[^= ]*\)\(.*\)$/\1\2 = _\2/' >> ${OUT}
+grep '^const _IFLA' gen-sysinfo.go | \
+    sed -e 's/^\(const \)_\(IFLA[^= ]*\)\(.*\)$/\1\2 = _\2/' >> ${OUT}
+grep '^const _IFF' gen-sysinfo.go | \
+    sed -e 's/^\(const \)_\(IFF[^= ]*\)\(.*\)$/\1\2 = _\2/' >> ${OUT}
+
+# The size of the ifinfomsg struct.
+if grep 'type IfInfomsg ' ${OUT} > /dev/null 2>&1; then
+  echo 'var SizeofIfInfomsg = int(unsafe.Sizeof(IfInfomsg{}))' >> ${OUT}
+fi
+
+# The ifaddrmsg struct.
+grep '^type _ifaddrmsg ' gen-sysinfo.go | \
+    sed -e 's/_ifaddrmsg/IfAddrmsg/' \
+      -e 's/ifa_family/Family/' \
+      -e 's/ifa_prefixlen/Prefixlen/' \
+      -e 's/ifa_flags/Flags/' \
+      -e 's/ifa_scope/Scope/' \
+      -e 's/ifa_index/Index/' \
+    >> ${OUT}
+
+# The size of the ifaddrmsg struct.
+if grep 'type IfAddrmsg ' ${OUT} > /dev/null 2>&1; then
+  echo 'var SizeofIfAddrmsg = int(unsafe.Sizeof(IfAddrmsg{}))' >> ${OUT}
+fi
+
+# The rtattr struct.
+grep '^type _rtattr ' gen-sysinfo.go | \
+    sed -e 's/_rtattr/RtAttr/' \
+      -e 's/rta_len/Len/' \
+      -e 's/rta_type/Type/' \
+    >> ${OUT}
+
+# The size of the rtattr struct.
+if grep 'type RtAttr ' ${OUT} > /dev/null 2>&1; then
+  echo 'var SizeofRtAttr = int(unsafe.Sizeof(RtAttr{}))' >> ${OUT}
+fi
+
 exit $?
diff -r b6085c06b2eb libgo/runtime/go-go.c
--- a/libgo/runtime/go-go.c	Thu Sep 15 22:42:45 2011 -0700
+++ b/libgo/runtime/go-go.c	Fri Sep 16 07:26:10 2011 -0700
@@ -73,7 +73,7 @@ 
 /* Remove the current thread from the list of threads.  */
 
 static void
-remove_current_thread (void)
+remove_current_thread (void *dummy __attribute__ ((unused)))
 {
   struct __go_thread_id *list_entry;
   MCache *mcache;
@@ -92,7 +92,7 @@ 
   if (list_entry->next != NULL)
     list_entry->next->prev = list_entry->prev;
 
-  /* This will look runtime_mheap as needed.  */
+  /* This will lock runtime_mheap as needed.  */
   runtime_MCache_ReleaseAll (mcache);
 
   /* This should never deadlock--there shouldn't be any code that
@@ -139,6 +139,8 @@ 
 
   m = newm;
 
+  pthread_cleanup_push (remove_current_thread, NULL);
+
   list_entry = newm->list_entry;
 
   pfn = list_entry->pfn;
@@ -166,7 +168,7 @@ 
 
   (*pfn) (arg);
 
-  remove_current_thread ();
+  pthread_cleanup_pop (1);
 
   return NULL;
 }
@@ -178,11 +180,14 @@ 
 void
 Goexit (void)
 {
-  remove_current_thread ();
   pthread_exit (NULL);
   abort ();
 }
 
+/* Count of threads created.  */
+
+static volatile int mcount;
+
 /* Implement the go statement.  */
 
 void
@@ -224,6 +229,9 @@ 
 
   newm->list_entry = list_entry;
 
+  newm->id = __sync_fetch_and_add (&mcount, 1);
+  newm->fastrand = 0x49f6428aUL + newm->id;
+
   newm->mcache = runtime_allocmcache ();
 
   /* Add the thread to the list of all threads, marked as tentative
@@ -536,12 +544,17 @@ 
   for (p = __go_all_thread_ids; p != NULL; p = p->next)
     {
       MCache *c;
+      int i;
 
+      runtime_purgecachedstats(p->m);
       c = p->m->mcache;
-      mstats.heap_alloc += c->local_alloc;
-      c->local_alloc = 0;
-      mstats.heap_objects += c->local_objects;
-      c->local_objects = 0;
+      for (i = 0; i < NumSizeClasses; ++i)
+	{
+	  mstats.by_size[i].nmalloc += c->local_by_size[i].nmalloc;
+	  c->local_by_size[i].nmalloc = 0;
+	  mstats.by_size[i].nfree += c->local_by_size[i].nfree;
+	  c->local_by_size[i].nfree = 0;
+	}
     }
 }
 
diff -r b6085c06b2eb libgo/runtime/go-gomaxprocs.c
--- a/libgo/runtime/go-gomaxprocs.c	Thu Sep 15 22:42:45 2011 -0700
+++ b/libgo/runtime/go-gomaxprocs.c	Fri Sep 16 07:26:10 2011 -0700
@@ -7,9 +7,17 @@ 
 /* This is the runtime.GOMAXPROCS function.  This currently does
    nothing, since each goroutine runs in a separate thread anyhow.  */
 
-void GOMAXPROCS (int) asm ("libgo_runtime.runtime.GOMAXPROCS");
+extern int GOMAXPROCS (int) asm ("libgo_runtime.runtime.GOMAXPROCS");
 
-void
-GOMAXPROCS (int n __attribute__ ((unused)))
+static int set = 1;
+
+int
+GOMAXPROCS (int n)
 {
+  int ret;
+
+  ret = set;
+  if (n > 0)
+    set = n;
+  return ret;
 }
diff -r b6085c06b2eb libgo/runtime/go-rand.c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libgo/runtime/go-rand.c	Fri Sep 16 07:26:10 2011 -0700
@@ -0,0 +1,18 @@ 
+// 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.
+
+#include "runtime.h"
+
+uint32
+runtime_fastrand1(void)
+{
+	uint32 x;
+
+	x = m->fastrand;
+	x += x;
+	if(x & 0x80000000L)
+		x ^= 0x88888eefUL;
+	m->fastrand = x;
+	return x;
+}
diff -r b6085c06b2eb libgo/runtime/go-reflect-chan.c
--- a/libgo/runtime/go-reflect-chan.c	Thu Sep 15 22:42:45 2011 -0700
+++ b/libgo/runtime/go-reflect-chan.c	Fri Sep 16 07:26:10 2011 -0700
@@ -33,16 +33,21 @@ 
   return (uintptr_t) ret;
 }
 
-extern _Bool chansend (uintptr_t, uintptr_t, _Bool)
+extern _Bool chansend (struct __go_channel_type *, uintptr_t, uintptr_t, _Bool)
   asm ("libgo_reflect.reflect.chansend");
 
 _Bool
-chansend (uintptr_t ch, uintptr_t val_i, _Bool nb)
+chansend (struct __go_channel_type *ct, uintptr_t ch, uintptr_t val_i,
+	  _Bool nb)
 {
   struct __go_channel *channel = (struct __go_channel *) ch;
   uintptr_t element_size;
   void *pv;
 
+  __go_assert (ct->__common.__code == GO_CHAN);
+  __go_assert (__go_type_descriptors_equal (ct->__element_type,
+					    channel->element_type));
+
   if (channel == NULL)
     __go_panic_msg ("send to nil channel");
 
@@ -94,17 +99,22 @@ 
   _Bool received;
 };
 
-extern struct chanrecv_ret chanrecv (uintptr_t, _Bool)
+extern struct chanrecv_ret chanrecv (struct __go_channel_type *, uintptr_t,
+				     _Bool)
   asm ("libgo_reflect.reflect.chanrecv");
 
 struct chanrecv_ret
-chanrecv (uintptr_t ch, _Bool nb)
+chanrecv (struct __go_channel_type *ct, uintptr_t ch, _Bool nb)
 {
   struct __go_channel *channel = (struct __go_channel *) ch;
   void *pv;
   uintptr_t element_size;
   struct chanrecv_ret ret;
 
+  __go_assert (ct->__common.__code == GO_CHAN);
+  __go_assert (__go_type_descriptors_equal (ct->__element_type,
+					    channel->element_type));
+
   element_size = channel->element_type->__size;
 
   if (__go_is_pointer_type (channel->element_type))
diff -r b6085c06b2eb libgo/runtime/go-reflect-map.c
--- a/libgo/runtime/go-reflect-map.c	Thu Sep 15 22:42:45 2011 -0700
+++ b/libgo/runtime/go-reflect-map.c	Fri Sep 16 07:26:10 2011 -0700
@@ -8,6 +8,7 @@ 
 #include <stdint.h>
 
 #include "go-alloc.h"
+#include "go-assert.h"
 #include "go-panic.h"
 #include "go-type.h"
 #include "map.h"
@@ -21,11 +22,12 @@ 
   _Bool pres;
 };
 
-extern struct mapaccess_ret mapaccess (uintptr_t, uintptr_t)
+extern struct mapaccess_ret mapaccess (struct __go_map_type *, uintptr_t,
+				       uintptr_t)
   asm ("libgo_reflect.reflect.mapaccess");
 
 struct mapaccess_ret
-mapaccess (uintptr_t m, uintptr_t key_i)
+mapaccess (struct __go_map_type *mt, uintptr_t m, uintptr_t key_i)
 {
   struct __go_map *map = (struct __go_map *) m;
   void *key;
@@ -36,18 +38,20 @@ 
   void *val;
   void *pv;
 
-  if (map == NULL)
-    __go_panic_msg ("lookup in nil map");
+  __go_assert (mt->__common.__code == GO_MAP);
 
-  key_descriptor = map->__descriptor->__map_descriptor->__key_type;
+  key_descriptor = mt->__key_type;
   if (__go_is_pointer_type (key_descriptor))
     key = &key_i;
   else
     key = (void *) key_i;
 
-  p = __go_map_index (map, key, 0);
+  if (map == NULL)
+    p = NULL;
+  else
+    p = __go_map_index (map, key, 0);
 
-  val_descriptor = map->__descriptor->__map_descriptor->__val_type;
+  val_descriptor = mt->__val_type;
   if (__go_is_pointer_type (val_descriptor))
     {
       val = NULL;
@@ -71,20 +75,24 @@ 
   return ret;
 }
 
-extern void mapassign (uintptr_t, uintptr_t, uintptr_t, _Bool)
+extern void mapassign (struct __go_map_type *, uintptr_t, uintptr_t,
+		       uintptr_t, _Bool)
   asm ("libgo_reflect.reflect.mapassign");
 
 void
-mapassign (uintptr_t m, uintptr_t key_i, uintptr_t val_i, _Bool pres)
+mapassign (struct __go_map_type *mt, uintptr_t m, uintptr_t key_i,
+	   uintptr_t val_i, _Bool pres)
 {
   struct __go_map *map = (struct __go_map *) m;
   const struct __go_type_descriptor *key_descriptor;
   void *key;
 
+  __go_assert (mt->__common.__code == GO_MAP);
+
   if (map == NULL)
-    __go_panic_msg ("lookup in nil map");
+    __go_panic_msg ("assignment to entry in nil map");
 
-  key_descriptor = map->__descriptor->__map_descriptor->__key_type;
+  key_descriptor = mt->__key_type;
   if (__go_is_pointer_type (key_descriptor))
     key = &key_i;
   else
@@ -100,7 +108,7 @@ 
 
       p = __go_map_index (map, key, 1);
 
-      val_descriptor = map->__descriptor->__map_descriptor->__val_type;
+      val_descriptor = mt->__val_type;
       if (__go_is_pointer_type (val_descriptor))
 	pv = &val_i;
       else
@@ -122,14 +130,15 @@ 
   return (int32_t) map->__element_count;
 }
 
-extern unsigned char *mapiterinit (uintptr_t)
+extern unsigned char *mapiterinit (struct __go_map_type *, uintptr_t)
   asm ("libgo_reflect.reflect.mapiterinit");
 
 unsigned char *
-mapiterinit (uintptr_t m)
+mapiterinit (struct __go_map_type *mt, uintptr_t m)
 {
   struct __go_hash_iter *it;
 
+  __go_assert (mt->__common.__code == GO_MAP);
   it = __go_alloc (sizeof (struct __go_hash_iter));
   __go_mapiterinit ((struct __go_map *) m, it);
   return (unsigned char *) it;
diff -r b6085c06b2eb libgo/runtime/go-select.c
--- a/libgo/runtime/go-select.c	Thu Sep 15 22:42:45 2011 -0700
+++ b/libgo/runtime/go-select.c	Fri Sep 16 07:26:10 2011 -0700
@@ -533,7 +533,9 @@ 
 	  uintptr_t j;
 
 	  /* A channel may be selected for both read and write.  */
-	  if (channels[channels[i].dup_index].is_send != is_send)
+	  if (channels[channels[i].dup_index].is_send == is_send)
+	    continue;
+	  else
 	    {
 	      for (j = channels[i].dup_index + 1; j < i; ++j)
 		{
diff -r b6085c06b2eb libgo/runtime/go-semacquire.c
--- a/libgo/runtime/go-semacquire.c	Thu Sep 15 22:42:45 2011 -0700
+++ b/libgo/runtime/go-semacquire.c	Fri Sep 16 07:26:10 2011 -0700
@@ -44,7 +44,7 @@ 
    and it remains nonnegative.  */
 
 void
-semacquire (uint32 *addr)
+runtime_semacquire (uint32 *addr)
 {
   while (1)
     {
@@ -86,7 +86,7 @@ 
    process.  */
 
 void
-semrelease (uint32 *addr)
+runtime_semrelease (uint32 *addr)
 {
   int32_t val;
 
diff -r b6085c06b2eb libgo/syscalls/exec.go
--- a/libgo/syscalls/exec.go	Thu Sep 15 22:42:45 2011 -0700
+++ b/libgo/syscalls/exec.go	Fri Sep 16 07:26:10 2011 -0700
@@ -13,8 +13,14 @@ 
 func libc_fcntl(fd int, cmd int, arg int) int __asm__ ("fcntl")
 func libc_fork() Pid_t __asm__ ("fork")
 func libc_setsid() Pid_t __asm__ ("setsid")
+func libc_setpgid(Pid_t, Pid_t) int __asm__ ("setpgid")
+func libc_chroot(path *byte) int __asm__ ("chroot")
+func libc_setuid(Uid_t) int __asm__ ("setuid")
+func libc_setgid(Gid_t) int __asm__ ("setgid")
+func libc_setgroups(Size_t, *Gid_t) int __asm__ ("setgroups")
 func libc_chdir(name *byte) int __asm__ ("chdir")
 func libc_dup2(int, int) int __asm__ ("dup2")
+func libc_ioctl(int, int) int __asm__ ("ioctl")
 func libc_execve(*byte, **byte, **byte) int __asm__ ("execve")
 func libc_sysexit(int) __asm__ ("_exit")
 
@@ -24,7 +30,7 @@ 
 // In the child, this function must not acquire any locks, because
 // they might have been locked at the time of the fork.  This means
 // no rescheduling, no malloc calls, and no new stack segments.
-func forkAndExecInChild(argv0 *byte, argv, envv []*byte, dir *byte, attr *ProcAttr, pipe int) (pid int, err int) {
+func forkAndExecInChild(argv0 *byte, argv, envv []*byte, chroot, dir *byte, attr *ProcAttr, sys *SysProcAttr, pipe int) (pid int, err int) {
 	// Declare all variables at top in case any
 	// declarations require heap allocation (e.g., err1).
 	var r1, r2, err1 uintptr
@@ -51,19 +57,51 @@ 
 	// Fork succeeded, now in child.
 
 	// Enable tracing if requested.
-	if attr.Ptrace {
+	if sys.Ptrace {
 		if libc_ptrace(_PTRACE_TRACEME, 0, 0, nil) < 0 {
 			goto childerror
 		}
 	}
 
 	// Session ID
-	if attr.Setsid {
+	if sys.Setsid {
 		if libc_setsid() == Pid_t(-1) {
 			goto childerror
 		}
 	}
 
+	// Set process group
+	if sys.Setpgid {
+		if libc_setpgid(0, 0) < 0 {
+			goto childerror
+		}
+	}
+
+	// Chroot
+	if chroot != nil {
+		if libc_chroot(chroot) < 0 {
+			goto childerror
+		}
+	}
+
+	// User and groups
+	if cred := sys.Credential; cred != nil {
+		ngroups := uintptr(len(cred.Groups))
+		var groups *Gid_t
+		if ngroups > 0 {
+			groups = (*Gid_t)(unsafe.Pointer(&cred.Groups[0]))
+		}
+		if libc_setgroups(Size_t(ngroups), groups) < 0 {
+			goto childerror
+		}
+		if libc_setgid(Gid_t(cred.Gid)) < 0 {
+			goto childerror
+		}
+		if libc_setuid(Uid_t(cred.Uid)) < 0 {
+			goto childerror
+		}
+	}
+
 	// Chdir
 	if dir != nil {
 		if libc_chdir(dir) < 0 {
@@ -129,6 +167,20 @@ 
 		libc_close(i)
 	}
 
+	// Detach fd 0 from tty
+	if sys.Noctty {
+		if libc_ioctl(0, TIOCNOTTY) < 0 {
+			goto childerror
+		}
+	}
+
+	// Make fd 0 the tty
+	if sys.Setctty {
+		if libc_ioctl(0, TIOCSCTTY) < 0 {
+			goto childerror
+		}
+	}
+
 	// Time to exec.
 	libc_execve(argv0, &argv[0], &envv[0])
 
@@ -147,16 +199,35 @@ 
 	panic("unreached")
 }
 
-
-type ProcAttr struct {
-	Setsid bool     // Create session.
-	Ptrace bool     // Enable tracing.
-	Dir    string   // Current working directory.
-	Env    []string // Environment.
-	Files  []int    // File descriptors.
+// Credential holds user and group identities to be assumed
+// by a child process started by StartProcess.
+type Credential struct {
+	Uid    uint32   // User ID.
+	Gid    uint32   // Group ID.
+	Groups []uint32 // Supplementary group IDs.
 }
 
-var zeroAttributes ProcAttr
+// ProcAttr holds attributes that will be applied to a new process started
+// by StartProcess.
+type ProcAttr struct {
+	Dir   string   // Current working directory.
+	Env   []string // Environment.
+	Files []int    // File descriptors.
+	Sys   *SysProcAttr
+}
+
+type SysProcAttr struct {
+	Chroot     string      // Chroot.
+	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
+	Noctty     bool        // Detach fd 0 from controlling terminal
+}
+
+var zeroProcAttr ProcAttr
+var zeroSysProcAttr SysProcAttr
 
 func forkExec(argv0 string, argv []string, attr *ProcAttr) (pid int, err int) {
 	var p [2]int
@@ -165,7 +236,11 @@ 
 	var wstatus WaitStatus
 
 	if attr == nil {
-		attr = &zeroAttributes
+		attr = &zeroProcAttr
+	}
+	sys := attr.Sys
+	if sys == nil {
+		sys = &zeroSysProcAttr
 	}
 
 	p[0] = -1
@@ -180,6 +255,10 @@ 
 		argvp[0] = argv0p
 	}
 
+	var chroot *byte
+	if sys.Chroot != "" {
+		chroot = StringBytePtr(sys.Chroot)
+	}
 	var dir *byte
 	if attr.Dir != "" {
 		dir = StringBytePtr(attr.Dir)
@@ -202,7 +281,7 @@ 
 	}
 
 	// Kick off child.
-	pid, err = forkAndExecInChild(argv0p, argvp, envvp, dir, attr, p[1])
+	pid, err = forkAndExecInChild(argv0p, argvp, envvp, chroot, dir, attr, sys, p[1])
 	if err != 0 {
 	error:
 		if p[0] >= 0 {
diff -r b6085c06b2eb libgo/syscalls/netlink_linux.go
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libgo/syscalls/netlink_linux.go	Fri Sep 16 07:26:10 2011 -0700
@@ -0,0 +1,227 @@ 
+// 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.
+
+// Netlink sockets and messages
+
+package syscall
+
+import (
+	"unsafe"
+)
+
+// Round the length of a netlink message up to align it properly.
+func nlmAlignOf(msglen int) int {
+	return (msglen + NLMSG_ALIGNTO - 1) & ^(NLMSG_ALIGNTO - 1)
+}
+
+// Round the length of a netlink route attribute up to align it
+// properly.
+func rtaAlignOf(attrlen int) int {
+	return (attrlen + RTA_ALIGNTO - 1) & ^(RTA_ALIGNTO - 1)
+}
+
+// NetlinkRouteRequest represents the request message to receive
+// routing and link states from the kernel.
+type NetlinkRouteRequest struct {
+	Header NlMsghdr
+	Data   RtGenmsg
+}
+
+func (rr *NetlinkRouteRequest) toWireFormat() []byte {
+	b := make([]byte, rr.Header.Len)
+	b[0] = byte(rr.Header.Len)
+	b[1] = byte(rr.Header.Len >> 8)
+	b[2] = byte(rr.Header.Len >> 16)
+	b[3] = byte(rr.Header.Len >> 24)
+	b[4] = byte(rr.Header.Type)
+	b[5] = byte(rr.Header.Type >> 8)
+	b[6] = byte(rr.Header.Flags)
+	b[7] = byte(rr.Header.Flags >> 8)
+	b[8] = byte(rr.Header.Seq)
+	b[9] = byte(rr.Header.Seq >> 8)
+	b[10] = byte(rr.Header.Seq >> 16)
+	b[11] = byte(rr.Header.Seq >> 24)
+	b[12] = byte(rr.Header.Pid)
+	b[13] = byte(rr.Header.Pid >> 8)
+	b[14] = byte(rr.Header.Pid >> 16)
+	b[15] = byte(rr.Header.Pid >> 24)
+	b[16] = byte(rr.Data.Family)
+	return b
+}
+
+func newNetlinkRouteRequest(proto, seq, family int) []byte {
+	rr := &NetlinkRouteRequest{}
+	rr.Header.Len = uint32(NLMSG_HDRLEN + SizeofRtGenmsg)
+	rr.Header.Type = uint16(proto)
+	rr.Header.Flags = NLM_F_DUMP | NLM_F_REQUEST
+	rr.Header.Seq = uint32(seq)
+	rr.Data.Family = uint8(family)
+	return rr.toWireFormat()
+}
+
+// NetlinkRIB returns routing information base, as known as RIB,
+// which consists of network facility information, states and
+// parameters.
+func NetlinkRIB(proto, family int) ([]byte, int) {
+	var (
+		s     int
+		e     int
+		lsanl SockaddrNetlink
+		seq   int
+		tab   []byte
+	)
+
+	s, e = Socket(AF_NETLINK, SOCK_RAW, 0)
+	if e != 0 {
+		return nil, e
+	}
+	defer Close(s)
+
+	lsanl.Family = AF_NETLINK
+	e = Bind(s, &lsanl)
+	if e != 0 {
+		return nil, e
+	}
+
+	seq++
+	wb := newNetlinkRouteRequest(proto, seq, family)
+	e = Sendto(s, wb, 0, &lsanl)
+	if e != 0 {
+		return nil, e
+	}
+
+	for {
+		var (
+			rb  []byte
+			nr  int
+			lsa Sockaddr
+		)
+
+		rb = make([]byte, Getpagesize())
+		nr, _, e = Recvfrom(s, rb, 0)
+		if e != 0 {
+			return nil, e
+		}
+		if nr < NLMSG_HDRLEN {
+			return nil, EINVAL
+		}
+		rb = rb[:nr]
+		tab = append(tab, rb...)
+
+		msgs, _ := ParseNetlinkMessage(rb)
+		for _, m := range msgs {
+			if lsa, e = Getsockname(s); e != 0 {
+				return nil, e
+			}
+			switch v := lsa.(type) {
+			case *SockaddrNetlink:
+				if m.Header.Seq != uint32(seq) || m.Header.Pid != v.Pid {
+					return nil, EINVAL
+				}
+			default:
+				return nil, EINVAL
+			}
+			if m.Header.Type == NLMSG_DONE {
+				goto done
+			}
+			if m.Header.Type == NLMSG_ERROR {
+				return nil, EINVAL
+			}
+		}
+	}
+
+done:
+	return tab, 0
+}
+
+// NetlinkMessage represents the netlink message.
+type NetlinkMessage struct {
+	Header NlMsghdr
+	Data   []byte
+}
+
+// ParseNetlinkMessage parses buf as netlink messages and returns
+// the slice containing the NetlinkMessage structs.
+func ParseNetlinkMessage(buf []byte) ([]NetlinkMessage, int) {
+	var (
+		h    *NlMsghdr
+		dbuf []byte
+		dlen int
+		e    int
+		msgs []NetlinkMessage
+	)
+
+	for len(buf) >= NLMSG_HDRLEN {
+		h, dbuf, dlen, e = netlinkMessageHeaderAndData(buf)
+		if e != 0 {
+			break
+		}
+		m := NetlinkMessage{}
+		m.Header = *h
+		m.Data = dbuf[:int(h.Len)-NLMSG_HDRLEN]
+		msgs = append(msgs, m)
+		buf = buf[dlen:]
+	}
+
+	return msgs, e
+}
+
+func netlinkMessageHeaderAndData(buf []byte) (*NlMsghdr, []byte, int, int) {
+	h := (*NlMsghdr)(unsafe.Pointer(&buf[0]))
+	if int(h.Len) < NLMSG_HDRLEN || int(h.Len) > len(buf) {
+		return nil, nil, 0, EINVAL
+	}
+	return h, buf[NLMSG_HDRLEN:], nlmAlignOf(int(h.Len)), 0
+}
+
+// NetlinkRouteAttr represents the netlink route attribute.
+type NetlinkRouteAttr struct {
+	Attr  RtAttr
+	Value []byte
+}
+
+// ParseNetlinkRouteAttr parses msg's payload as netlink route
+// attributes and returns the slice containing the NetlinkRouteAttr
+// structs.
+func ParseNetlinkRouteAttr(msg *NetlinkMessage) ([]NetlinkRouteAttr, int) {
+	var (
+		buf   []byte
+		a     *RtAttr
+		alen  int
+		vbuf  []byte
+		e     int
+		attrs []NetlinkRouteAttr
+	)
+
+	switch msg.Header.Type {
+	case RTM_NEWLINK:
+		buf = msg.Data[SizeofIfInfomsg:]
+	case RTM_NEWADDR:
+		buf = msg.Data[SizeofIfAddrmsg:]
+	default:
+		return nil, EINVAL
+	}
+
+	for len(buf) >= SizeofRtAttr {
+		a, vbuf, alen, e = netlinkRouteAttrAndValue(buf)
+		if e != 0 {
+			break
+		}
+		ra := NetlinkRouteAttr{}
+		ra.Attr = *a
+		ra.Value = vbuf[:int(a.Len)-SizeofRtAttr]
+		attrs = append(attrs, ra)
+		buf = buf[alen:]
+	}
+
+	return attrs, 0
+}
+
+func netlinkRouteAttrAndValue(buf []byte) (*RtAttr, []byte, int, int) {
+	h := (*RtAttr)(unsafe.Pointer(&buf[0]))
+	if int(h.Len) < SizeofRtAttr || int(h.Len) > len(buf) {
+		return nil, nil, 0, EINVAL
+	}
+	return h, buf[SizeofRtAttr:], rtaAlignOf(int(h.Len)), 0
+}
diff -r b6085c06b2eb libgo/syscalls/socket.go
--- a/libgo/syscalls/socket.go	Thu Sep 15 22:42:45 2011 -0700
+++ b/libgo/syscalls/socket.go	Fri Sep 16 07:26:10 2011 -0700
@@ -131,7 +131,7 @@ 
 		}
 		return sa, 0;
 	}
-	return nil, EAFNOSUPPORT;
+	return anyToSockaddrOS(rsa)
 }
 
 func libc_accept(fd int, sa *RawSockaddrAny, len *Socklen_t) int __asm__ ("accept");
@@ -239,7 +239,7 @@ 
 	return setsockopt(fd, level, opt, uintptr(unsafe.Pointer(&[]byte(s)[0])), Socklen_t(len(s)))
 }
 
-func SetsockoptIpMreq(fd, level, opt int, mreq *IpMreq) (errno int) {
+func SetsockoptIPMreq(fd, level, opt int, mreq *IPMreq) (errno int) {
 	return setsockopt(fd, level, opt, uintptr(unsafe.Pointer(mreq)), unsafe.Sizeof(*mreq))
 }
 
diff -r b6085c06b2eb libgo/syscalls/socket_bsd.go
--- a/libgo/syscalls/socket_bsd.go	Thu Sep 15 22:42:45 2011 -0700
+++ b/libgo/syscalls/socket_bsd.go	Fri Sep 16 07:26:10 2011 -0700
@@ -72,3 +72,7 @@ 
 func BindToDevice(fd int, device string) (errno int) {
 	return ENOSYS
 }
+
+func anyToSockaddrOS(rsa *RawSockaddrAny) (Sockaddr, int) {
+	return nil, EAFNOSUPPORT;
+}
diff -r b6085c06b2eb libgo/syscalls/socket_irix.go
--- a/libgo/syscalls/socket_irix.go	Thu Sep 15 22:42:45 2011 -0700
+++ b/libgo/syscalls/socket_irix.go	Fri Sep 16 07:26:10 2011 -0700
@@ -78,7 +78,7 @@ 
 // This could be enabled with -D_SGI_SOURCE, but conflicts with
 // -D_XOPEN_SOURCE=500 required for msg_control etc. in struct msghgr, so
 // simply provide it here.
-type IpMreq struct {
+type IPMreq struct {
 	Multiaddr [4]byte
 	Interface [4]byte
 }
@@ -123,3 +123,7 @@ 
 	EAI_OVERFLOW	= 13
 	EAI_MAX		= 14
 )
+
+func anyToSockaddrOS(rsa *RawSockaddrAny) (Sockaddr, int) {
+	return nil, EAFNOSUPPORT;
+}
diff -r b6085c06b2eb libgo/syscalls/socket_linux.go
--- a/libgo/syscalls/socket_linux.go	Thu Sep 15 22:42:45 2011 -0700
+++ b/libgo/syscalls/socket_linux.go	Fri Sep 16 07:26:10 2011 -0700
@@ -6,9 +6,55 @@ 
 
 package syscall
 
+import "unsafe"
+
 const SizeofSockaddrInet4 = 16
 const SizeofSockaddrInet6 = 28
 const SizeofSockaddrUnix = 110
+const SizeofSockaddrLinklayer = 20
+const SizeofSockaddrNetlink = 12
+
+type SockaddrLinklayer struct {
+	Protocol uint16
+	Ifindex  int
+	Hatype   uint16
+	Pkttype  uint8
+	Halen    uint8
+	Addr     [8]byte
+	raw      RawSockaddrLinklayer
+}
+
+func (sa *SockaddrLinklayer) sockaddr() (*RawSockaddrAny, Socklen_t, int) {
+	if sa.Ifindex < 0 || sa.Ifindex > 0x7fffffff {
+		return nil, 0, EINVAL
+	}
+	sa.raw.Family = AF_PACKET
+	sa.raw.Protocol = sa.Protocol
+	sa.raw.Ifindex = int32(sa.Ifindex)
+	sa.raw.Hatype = sa.Hatype
+	sa.raw.Pkttype = sa.Pkttype
+	sa.raw.Halen = sa.Halen
+	for i := 0; i < len(sa.Addr); i++ {
+		sa.raw.Addr[i] = sa.Addr[i]
+	}
+	return (*RawSockaddrAny)(unsafe.Pointer(&sa.raw)), SizeofSockaddrLinklayer, 0
+}
+
+type SockaddrNetlink struct {
+	Family uint16
+	Pad    uint16
+	Pid    uint32
+	Groups uint32
+	raw    RawSockaddrNetlink
+}
+
+func (sa *SockaddrNetlink) sockaddr() (*RawSockaddrAny, Socklen_t, int) {
+	sa.raw.Family = AF_NETLINK
+	sa.raw.Pad = sa.Pad
+	sa.raw.Pid = sa.Pid
+	sa.raw.Groups = sa.Groups
+	return (*RawSockaddrAny)(unsafe.Pointer(&sa.raw)), SizeofSockaddrNetlink, 0
+}
 
 type RawSockaddrInet4 struct {
 	Family uint16;
@@ -64,6 +110,23 @@ 
 	return n, 0
 }
 
+type RawSockaddrLinklayer struct {
+	Family   uint16
+	Protocol uint16
+	Ifindex  int32
+	Hatype   uint16
+	Pkttype  uint8
+	Halen    uint8
+	Addr     [8]uint8
+}
+
+type RawSockaddrNetlink struct {
+	Family uint16
+	Pad    uint16
+	Pid    uint32
+	Groups uint32
+}
+
 type RawSockaddr struct {
 	Family uint16;
 	Data [14]int8;
@@ -73,3 +136,30 @@ 
 func BindToDevice(fd int, device string) (errno int) {
 	return SetsockoptString(fd, SOL_SOCKET, SO_BINDTODEVICE, device)
 }
+
+func anyToSockaddrOS(rsa *RawSockaddrAny) (Sockaddr, int) {
+	switch rsa.Addr.Family {
+	case AF_NETLINK:
+		pp := (*RawSockaddrNetlink)(unsafe.Pointer(rsa))
+		sa := new(SockaddrNetlink)
+		sa.Family = pp.Family
+		sa.Pad = pp.Pad
+		sa.Pid = pp.Pid
+		sa.Groups = pp.Groups
+		return sa, 0
+
+	case AF_PACKET:
+		pp := (*RawSockaddrLinklayer)(unsafe.Pointer(rsa))
+		sa := new(SockaddrLinklayer)
+		sa.Protocol = pp.Protocol
+		sa.Ifindex = int(pp.Ifindex)
+		sa.Hatype = pp.Hatype
+		sa.Pkttype = pp.Pkttype
+		sa.Halen = pp.Halen
+		for i := 0; i < len(sa.Addr); i++ {
+			sa.Addr[i] = pp.Addr[i]
+		}
+		return sa, 0
+	}
+	return nil, EAFNOSUPPORT;
+}
diff -r b6085c06b2eb libgo/syscalls/socket_solaris.go
--- a/libgo/syscalls/socket_solaris.go	Thu Sep 15 22:42:45 2011 -0700
+++ b/libgo/syscalls/socket_solaris.go	Fri Sep 16 07:26:10 2011 -0700
@@ -74,3 +74,7 @@ 
 func BindToDevice(fd int, device string) (errno int) {
 	return ENOSYS
 }
+
+func anyToSockaddrOS(rsa *RawSockaddrAny) (Sockaddr, int) {
+	return nil, EAFNOSUPPORT;
+}
diff -r b6085c06b2eb libgo/syscalls/syscall_linux.go
--- a/libgo/syscalls/syscall_linux.go	Thu Sep 15 22:42:45 2011 -0700
+++ b/libgo/syscalls/syscall_linux.go	Fri Sep 16 07:26:10 2011 -0700
@@ -9,6 +9,7 @@ 
 import "unsafe"
 
 func libc_ptrace(request int, pid Pid_t, addr uintptr, data *byte) _C_long __asm__ ("ptrace")
+func libc_sendfile(int, int, *Offset_t, Size_t) Ssize_t __asm__ ("sendfile")
 
 var dummy *byte
 const sizeofPtr uintptr = uintptr(unsafe.Sizeof(dummy))
@@ -186,3 +187,20 @@ 
 				 uintptr(sig));
 	return int(err);
 }
+
+func Sendfile(outfd int, infd int, offset *int64, count int) (written int, errno int) {
+	var o Offset_t
+	var po *Offset_t
+	if offset != nil {
+		o = Offset_t(*offset)
+		po = &o
+	}
+	w := libc_sendfile(outfd, infd, po, Size_t(count))
+	if offset != nil {
+		*offset = int64(o)
+	}
+	if w < 0 {
+		return 0, GetErrno()
+	}
+	return int(w), 0
+}
diff -r b6085c06b2eb libgo/testsuite/gotest
--- a/libgo/testsuite/gotest	Thu Sep 15 22:42:45 2011 -0700
+++ b/libgo/testsuite/gotest	Fri Sep 16 07:26:10 2011 -0700
@@ -34,6 +34,7 @@ 
 dejagnu=no
 timeout=60
 testname=""
+trace=false
 while $loop; do
 	case "x$1" in
         x--srcdir)
@@ -103,6 +104,10 @@ 
 		testname=`echo $1 | sed -e 's/^--testname=//'`
 		shift
 		;;
+	x--trace)
+		trace=true
+		shift
+		;;
 	x-*)
 		loop=false
 		;;
@@ -288,10 +293,17 @@ 
 	prefixarg="-fgo-prefix=$prefix"
 fi
 
+if test "$trace" = "true"; then
+  echo $GC -g $prefixarg -c -I . -fno-toplevel-reorder -o _gotest_.o $gofiles $pkgbasefiles
+fi
 $GC -g $prefixarg -c -I . -fno-toplevel-reorder -o _gotest_.o $gofiles $pkgbasefiles
+
 if $havex; then
 	mkdir -p `dirname $package`
 	cp _gotest_.o `dirname $package`/lib`basename $package`.a
+	if test "$trace" = "true"; then
+	    echo $GC -g -c -I . -fno-toplevel-reorder -o $xofile $xgofiles
+	fi
 	$GC -g -c -I . -fno-toplevel-reorder -o $xofile $xgofiles
 fi
 
@@ -375,9 +387,19 @@ 
 
 case "x$dejagnu" in
 xno)
+	if test "$trace" = "true"; then
+	    echo ${GC} -g -c _testmain.go
+	fi
 	${GC} -g -c _testmain.go
+
+	if test "$trace" = "true"; then
+	    echo ${GL} *.o ${GOLIBS}
+	fi
 	${GL} *.o ${GOLIBS}
 
+	if test "$trace" = "true"; then
+	    echo ./a.out -test.short -test.timeout=$timeout "$@"
+	fi
 	./a.out -test.short -test.timeout=$timeout "$@" &
 	pid=$!
 	(sleep `expr $timeout + 10`