all: merge NaCl branch (part 1)

See golang.org/s/go13nacl for design overview.

This CL is the mostly mechanical changes from rsc's Go 1.2 based NaCl branch, specifically 39cb35750369 to 500771b477cf from https://code.google.com/r/rsc-go13nacl. This CL does not include working NaCl support, there are probably two or three more large merges to come.

CL 15750044 is not included as it involves more invasive changes to the linker which will need to be merged separately.

The exact change lists included are

15050047: syscall: support for Native Client
15360044: syscall: unzip implementation for Native Client
15370044: syscall: Native Client SRPC implementation
15400047: cmd/dist, cmd/go, go/build, test: support for Native Client
15410048: runtime: support for Native Client
15410049: syscall: file descriptor table for Native Client
15410050: syscall: in-memory file system for Native Client
15440048: all: update +build lines for Native Client port
15540045: cmd/6g, cmd/8g, cmd/gc: support for Native Client
15570045: os: support for Native Client
15680044: crypto/..., hash/crc32, reflect, sync/atomic: support for amd64p32
15690044: net: support for Native Client
15690048: runtime: support for fake time like on Go Playground
15690051: build: disable various tests on Native Client

LGTM=rsc
R=rsc
CC=golang-codereviews
https://golang.org/cl/68150047
diff --git a/src/pkg/syscall/fd_nacl.go b/src/pkg/syscall/fd_nacl.go
new file mode 100644
index 0000000..cbc8315
--- /dev/null
+++ b/src/pkg/syscall/fd_nacl.go
@@ -0,0 +1,320 @@
+// 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.
+
+// File descriptor support for Native Client.
+// We want to provide access to a broader range of (simulated) files than
+// Native Client allows, so we maintain our own file descriptor table exposed
+// to higher-level packages.
+
+package syscall
+
+import (
+	"sync"
+)
+
+// files is the table indexed by a file descriptor.
+var files struct {
+	sync.RWMutex
+	tab []*file
+}
+
+// A file is an open file, something with a file descriptor.
+// A particular *file may appear in files multiple times, due to use of Dup or Dup2.
+type file struct {
+	fdref int      // uses in files.tab
+	impl  fileImpl // underlying implementation
+}
+
+// A fileImpl is the implementation of something that can be a file.
+type fileImpl interface {
+	// Standard operations.
+	// These can be called concurrently from multiple goroutines.
+	stat(*Stat_t) error
+	read([]byte) (int, error)
+	write([]byte) (int, error)
+	seek(int64, int) (int64, error)
+	pread([]byte, int64) (int, error)
+	pwrite([]byte, int64) (int, error)
+
+	// Close is called when the last reference to a *file is removed
+	// from the file descriptor table. It may be called concurrently
+	// with active operations such as blocked read or write calls.
+	close() error
+}
+
+// newFD adds impl to the file descriptor table,
+// returning the new file descriptor.
+// Like Unix, it uses the lowest available descriptor.
+func newFD(impl fileImpl) int {
+	files.Lock()
+	defer files.Unlock()
+	f := &file{impl: impl, fdref: 1}
+	for fd, oldf := range files.tab {
+		if oldf == nil {
+			files.tab[fd] = f
+			return fd
+		}
+	}
+	fd := len(files.tab)
+	files.tab = append(files.tab, f)
+	return fd
+}
+
+// Install Native Client stdin, stdout, stderr.
+func init() {
+	newFD(&naclFile{naclFD: 0})
+	newFD(&naclFile{naclFD: 1})
+	newFD(&naclFile{naclFD: 2})
+}
+
+// fdToFile retrieves the *file corresponding to a file descriptor.
+func fdToFile(fd int) (*file, error) {
+	files.Lock()
+	defer files.Unlock()
+	if fd < 0 || fd >= len(files.tab) || files.tab[fd] == nil {
+		return nil, EBADF
+	}
+	return files.tab[fd], nil
+}
+
+func Close(fd int) error {
+	files.Lock()
+	if fd < 0 || fd >= len(files.tab) || files.tab[fd] == nil {
+		files.Unlock()
+		return EBADF
+	}
+	f := files.tab[fd]
+	files.tab[fd] = nil
+	f.fdref--
+	fdref := f.fdref
+	files.Unlock()
+	if fdref > 0 {
+		return nil
+	}
+	return f.impl.close()
+}
+
+func CloseOnExec(fd int) {
+	// nothing to do - no exec
+}
+
+func Dup(fd int) (int, error) {
+	files.Lock()
+	defer files.Unlock()
+	if fd < 0 || fd >= len(files.tab) || files.tab[fd] == nil {
+		return -1, EBADF
+	}
+	f := files.tab[fd]
+	f.fdref++
+	for newfd, oldf := range files.tab {
+		if oldf == nil {
+			files.tab[newfd] = f
+			return newfd, nil
+		}
+	}
+	newfd := len(files.tab)
+	files.tab = append(files.tab, f)
+	return newfd, nil
+}
+
+func Dup2(fd, newfd int) error {
+	files.Lock()
+	defer files.Unlock()
+	if fd < 0 || fd >= len(files.tab) || files.tab[fd] == nil || newfd < 0 || newfd >= len(files.tab)+100 {
+		files.Unlock()
+		return EBADF
+	}
+	f := files.tab[fd]
+	f.fdref++
+	for cap(files.tab) <= newfd {
+		files.tab = append(files.tab[:cap(files.tab)], nil)
+	}
+	oldf := files.tab[newfd]
+	var oldfdref int
+	if oldf != nil {
+		oldf.fdref--
+		oldfdref = oldf.fdref
+	}
+	files.tab[newfd] = f
+	files.Unlock()
+	if oldf != nil {
+		if oldfdref == 0 {
+			oldf.impl.close()
+		}
+	}
+	return nil
+}
+
+func Fstat(fd int, st *Stat_t) error {
+	f, err := fdToFile(fd)
+	if err != nil {
+		return err
+	}
+	return f.impl.stat(st)
+}
+
+func Read(fd int, b []byte) (int, error) {
+	f, err := fdToFile(fd)
+	if err != nil {
+		return 0, err
+	}
+	return f.impl.read(b)
+}
+
+func Write(fd int, b []byte) (int, error) {
+	f, err := fdToFile(fd)
+	if err != nil {
+		return 0, err
+	}
+	return f.impl.write(b)
+}
+
+func Pread(fd int, b []byte, offset int64) (int, error) {
+	f, err := fdToFile(fd)
+	if err != nil {
+		return 0, err
+	}
+	return f.impl.pread(b, offset)
+}
+
+func Pwrite(fd int, b []byte, offset int64) (int, error) {
+	f, err := fdToFile(fd)
+	if err != nil {
+		return 0, err
+	}
+	return f.impl.pwrite(b, offset)
+}
+
+func Seek(fd int, offset int64, whence int) (int64, error) {
+	f, err := fdToFile(fd)
+	if err != nil {
+		return 0, err
+	}
+	return f.impl.seek(offset, whence)
+}
+
+// defaulFileImpl imlements fileImpl.
+// It can be embedded to complete a partial fileImpl implementation.
+type defaultFileImpl struct{}
+
+func (*defaultFileImpl) close() error                      { return nil }
+func (*defaultFileImpl) stat(*Stat_t) error                { return ENOSYS }
+func (*defaultFileImpl) read([]byte) (int, error)          { return 0, ENOSYS }
+func (*defaultFileImpl) write([]byte) (int, error)         { return 0, ENOSYS }
+func (*defaultFileImpl) seek(int64, int) (int64, error)    { return 0, ENOSYS }
+func (*defaultFileImpl) pread([]byte, int64) (int, error)  { return 0, ENOSYS }
+func (*defaultFileImpl) pwrite([]byte, int64) (int, error) { return 0, ENOSYS }
+
+// naclFile is the fileImpl implementation for a Native Client file descriptor.
+type naclFile struct {
+	defaultFileImpl
+	naclFD int
+}
+
+func (f *naclFile) stat(st *Stat_t) error {
+	return naclFstat(f.naclFD, st)
+}
+
+func (f *naclFile) read(b []byte) (int, error) {
+	n, err := naclRead(f.naclFD, b)
+	if err != nil {
+		n = 0
+	}
+	return n, err
+}
+
+// implemented in package runtime, to add time header on playground
+func naclWrite(fd int, b []byte) int
+
+func (f *naclFile) write(b []byte) (int, error) {
+	n := naclWrite(f.naclFD, b)
+	if n < 0 {
+		return 0, Errno(-n)
+	}
+	return n, nil
+}
+
+func (f *naclFile) seek(off int64, whence int) (int64, error) {
+	old := off
+	err := naclSeek(f.naclFD, &off, whence)
+	if err != nil {
+		return old, err
+	}
+	return off, nil
+}
+
+func (f *naclFile) prw(b []byte, offset int64, rw func([]byte) (int, error)) (int, error) {
+	// NaCl has no pread; simulate with seek and hope for no races.
+	old, err := f.seek(0, 1)
+	if err != nil {
+		return 0, err
+	}
+	if _, err := f.seek(offset, 0); err != nil {
+		return 0, err
+	}
+	n, err := rw(b)
+	f.seek(old, 0)
+	return n, err
+}
+
+func (f *naclFile) pread(b []byte, offset int64) (int, error) {
+	return f.prw(b, offset, f.read)
+}
+
+func (f *naclFile) pwrite(b []byte, offset int64) (int, error) {
+	return f.prw(b, offset, f.write)
+}
+
+func (f *naclFile) close() error {
+	err := naclClose(f.naclFD)
+	f.naclFD = -1
+	return err
+}
+
+// A pipeFile is an in-memory implementation of a pipe.
+// The byteq implementation is in net_nacl.go.
+type pipeFile struct {
+	defaultFileImpl
+	rd *byteq
+	wr *byteq
+}
+
+func (f *pipeFile) close() error {
+	if f.rd != nil {
+		f.rd.close()
+	}
+	if f.wr != nil {
+		f.wr.close()
+	}
+	return nil
+}
+
+func (f *pipeFile) read(b []byte) (int, error) {
+	if f.rd == nil {
+		return 0, EINVAL
+	}
+	n, err := f.rd.read(b, 0)
+	if err == EAGAIN {
+		err = nil
+	}
+	return n, err
+}
+
+func (f *pipeFile) write(b []byte) (int, error) {
+	if f.wr == nil {
+		return 0, EINVAL
+	}
+	n, err := f.wr.write(b, 0)
+	if err == EAGAIN {
+		err = EPIPE
+	}
+	return n, err
+}
+
+func Pipe(fd []int) error {
+	q := newByteq()
+	fd[0] = newFD(&pipeFile{rd: q})
+	fd[1] = newFD(&pipeFile{wr: q})
+	return nil
+}