OFILES=\
        syscall.$O \
        errstr_$(GOOS).$O \
-       stat_$(GOARCH)_$(GOOS).$O \
+       file_$(GOARCH)_$(GOOS).$O \
        syscall_$(GOARCH)_$(GOOS).$O \
 
 
 
        EBADMACHO=88;
        ECANCELED=89;
        EIDRM=90;
-       ENOMSG=91   ;
+       ENOMSG=91;
        EILSEQ=92;
        ENOATTR=93;
        EBADMSG=94;
 
--- /dev/null
+// 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 syscall
+
+import syscall "syscall"
+
+export Stat
+export stat, fstat, lstat
+export open, close, read, write, pipe
+
+func   StatToInt(s *Stat) int64;
+
+// Stat and relatives for Darwin
+
+type dev_t uint32;
+type ino_t uint64;
+type mode_t uint16;
+type nlink_t uint16;
+type uid_t uint32;
+type gid_t uint32;
+type off_t int64;
+type blksize_t int64;
+type blkcnt_t int64;
+type time_t int64;
+
+type Timespec struct {
+       tv_sec  time_t;
+       tv_nsec int64;
+}
+
+type Stat struct {
+       st_dev  dev_t;     /* ID of device containing file */
+       st_mode mode_t;    /* protection */
+       st_nlink        nlink_t;   /* number of hard links */
+       st_ino  ino_t;     /* inode number */
+       st_uid  uid_t;     /* user ID of owner */
+       st_gid  gid_t;     /* group ID of owner */
+       st_rdev dev_t;    /* device ID (if special file) */
+       st_atime        Timespec;   /* time of last access */
+       st_mtime        Timespec;   /* time of last modification */
+       st_ctime        Timespec;   /* time of last status change */
+       st_birthtimespec        Timespec;   /* birth time */
+       st_size off_t;    /* total size, in bytes */
+       st_blocks       blkcnt_t;  /* number of blocks allocated */
+       st_blksize      blksize_t; /* blocksize for filesystem I/O */
+       st_flags        uint32;
+       st_gen          uint32;
+       st_qspare[2]    int64;
+}
+
+func open(name *byte, mode int64) (ret int64, errno int64) {
+       const SYSOPEN = 5;
+       r1, r2, err := syscall.Syscall(SYSOPEN, AddrToInt(name), mode, 0);
+       return r1, err;
+}
+
+func close(fd int64) (ret int64, errno int64) {
+       const SYSCLOSE = 6;
+       r1, r2, err := syscall.Syscall(SYSCLOSE, fd, 0, 0);
+       return r1, err;
+}
+
+func read(fd int64, buf *byte, nbytes int64) (ret int64, errno int64) {
+       const SYSREAD = 3;
+       r1, r2, err := syscall.Syscall(SYSREAD, fd, AddrToInt(buf), nbytes);
+       return r1, err;
+}
+
+func write(fd int64, buf *byte, nbytes int64) (ret int64, errno int64) {
+       const SYSWRITE = 4;
+       r1, r2, err := syscall.Syscall(SYSWRITE, fd, AddrToInt(buf), nbytes);
+       return r1, err;
+}
+
+func pipe(fds *[2]int64) (ret int64, errno int64) {
+       const SYSPIPE = 42;
+       r1, r2, err := syscall.Syscall(SYSPIPE, 0, 0, 0);
+       if r1 < 0 {
+               return r1, err;
+       }
+       fds[0] = r1;
+       fds[1] = r2;
+       return 0, err;
+}
+
+func stat(name *byte, buf *Stat) (ret int64, errno int64) {
+       const SYSSTAT = 338;
+       r1, r2, err := syscall.Syscall(SYSSTAT, AddrToInt(name), StatToInt(buf), 0);
+       return r1, err;
+}
+
+func lstat(name *byte, buf *Stat) (ret int64, errno int64) {
+       const SYSLSTAT = 340;
+       r1, r2, err := syscall.Syscall(SYSLSTAT, AddrToInt(name), StatToInt(buf), 0);
+       return r1, err;
+}
+
+func fstat(fd int64, buf *Stat) (ret int64, errno int64) {
+       const SYSFSTAT = 339;
+       r1, r2, err := syscall.Syscall(SYSFSTAT, fd, StatToInt(buf), 0);
+       return r1, err;
+}
 
--- /dev/null
+// 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 syscall
+
+import syscall "syscall"
+
+export Stat
+export stat, fstat, lstat
+export open, close, read, write, pipe
+
+func   StatToInt(s *Stat) int64;
+
+// Stat and relatives for Linux
+
+type dev_t uint64;
+type ino_t uint64;
+type mode_t uint32;
+type nlink_t uint64;
+type uid_t uint32;
+type gid_t uint32;
+type off_t int64;
+type blksize_t int64;
+type blkcnt_t int64;
+type time_t int64;
+
+type Timespec struct {
+       tv_sec  time_t;
+       tv_nsec int64;
+}
+
+type Stat struct {
+       st_dev  dev_t;     /* ID of device containing file */
+       st_ino  ino_t;     /* inode number */
+       st_nlink        nlink_t;   /* number of hard links */
+       st_mode mode_t;    /* protection */
+       st_uid  uid_t;     /* user ID of owner */
+       st_gid  gid_t;     /* group ID of owner */
+       pad0    int32;
+       st_rdev dev_t;    /* device ID (if special file) */
+       st_size off_t;    /* total size, in bytes */
+       st_blksize      blksize_t; /* blocksize for filesystem I/O */
+       st_blocks       blkcnt_t;  /* number of blocks allocated */
+       st_atime        Timespec;   /* time of last access */
+       st_mtime        Timespec;   /* time of last modification */
+       st_ctime        Timespec;   /* time of last status change */
+}
+
+func open(name *byte, mode int64) (ret int64, errno int64) {
+       const SYSOPEN = 2;
+       r1, r2, err := syscall.Syscall(SYSOPEN, AddrToInt(name), mode, 0);
+       return r1, err;
+}
+
+func close(fd int64) (ret int64, errno int64) {
+       const SYSCLOSE = 3;
+       r1, r2, err := syscall.Syscall(SYSCLOSE, fd, 0, 0);
+       return r1, err;
+}
+
+func read(fd int64, buf *byte, nbytes int64) (ret int64, errno int64) {
+       const SYSREAD = 0;
+       r1, r2, err := syscall.Syscall(SYSREAD, fd, AddrToInt(buf), nbytes);
+       return r1, err;
+}
+
+func write(fd int64, buf *byte, nbytes int64) (ret int64, errno int64) {
+       const SYSWRITE = 1;
+       r1, r2, err := syscall.Syscall(SYSWRITE, fd, AddrToInt(buf), nbytes);
+       return r1, err;
+}
+
+func pipe(fds *[2]int64) (ret int64, errno int64) {
+       const SYSPIPE = 22;
+       r1, r2, err := syscall.Syscall(SYSPIPE, 0, 0, 0);
+       if r1 < 0 {
+               return r1, err;
+       }
+       fds[0] = r1;
+       fds[1] = r2;
+       return 0, err;
+}
+
+func stat(name *byte, buf *Stat) (ret int64, errno int64) {
+       const SYSSTAT = 4;
+       r1, r2, err := syscall.Syscall(SYSSTAT, AddrToInt(name), StatToInt(buf), 0);
+       return r1, err;
+}
+
+func lstat(name *byte, buf *Stat) (ret int64, errno int64) {
+       const SYSLSTAT = 6;
+       r1, r2, err := syscall.Syscall(SYSLSTAT, AddrToInt(name), StatToInt(buf), 0);
+       return r1, err;
+}
+
+func fstat(fd int64, buf *Stat) (ret int64, errno int64) {
+       const SYSFSTAT = 5;
+       r1, r2, err := syscall.Syscall(SYSFSTAT, fd, StatToInt(buf), 0);
+       return r1, err;
+}
+
 
+++ /dev/null
-// 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 syscall
-
-func stat(name *byte, buf *Stat) (ret int64, errno int64);
-func fstat(fd int64, buf *Stat) (ret int64, errno int64);
-func lstat(name *byte, buf *Stat) (ret int64, errno int64);
-
-export Stat
-export stat, fstat, lstat
-
-// Stat and relatives for Darwin
-
-type dev_t uint32;
-type ino_t uint64;
-type mode_t uint16;
-type nlink_t uint16;
-type uid_t uint32;
-type gid_t uint32;
-type off_t int64;
-type blksize_t int64;
-type blkcnt_t int64;
-type time_t int64;
-
-type Timespec struct {
-       tv_sec  time_t;
-       tv_nsec int64;
-}
-
-type Stat struct {
-       st_dev  dev_t;     /* ID of device containing file */
-       st_mode mode_t;    /* protection */
-       st_nlink        nlink_t;   /* number of hard links */
-       st_ino  ino_t;     /* inode number */
-       st_uid  uid_t;     /* user ID of owner */
-       st_gid  gid_t;     /* group ID of owner */
-       st_rdev dev_t;    /* device ID (if special file) */
-       st_atime        Timespec;   /* time of last access */
-       st_mtime        Timespec;   /* time of last modification */
-       st_ctime        Timespec;   /* time of last status change */
-       st_birthtimespec        Timespec;   /* birth time */
-       st_size off_t;    /* total size, in bytes */
-       st_blocks       blkcnt_t;  /* number of blocks allocated */
-       st_blksize      blksize_t; /* blocksize for filesystem I/O */
-       st_flags        uint32;
-       st_gen          uint32;
-       st_qspare[2]    int64;
-}
 
+++ /dev/null
-// 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 syscall
-
-func stat(name *byte, buf *Stat) (ret int64, errno int64);
-func fstat(fd int64, buf *Stat) (ret int64, errno int64);
-func lstat(name *byte, buf *Stat) (ret int64, errno int64);
-
-export Stat
-export stat, fstat, lstat
-
-// Stat and relatives for Linux
-
-type dev_t uint64;
-type ino_t uint64;
-type mode_t uint32;
-type nlink_t uint64;
-type uid_t uint32;
-type gid_t uint32;
-type off_t int64;
-type blksize_t int64;
-type blkcnt_t int64;
-type time_t int64;
-
-type Timespec struct {
-       tv_sec  time_t;
-       tv_nsec int64;
-}
-
-type Stat struct {
-       st_dev  dev_t;     /* ID of device containing file */
-       st_ino  ino_t;     /* inode number */
-       st_nlink        nlink_t;   /* number of hard links */
-       st_mode mode_t;    /* protection */
-       st_uid  uid_t;     /* user ID of owner */
-       st_gid  gid_t;     /* group ID of owner */
-       pad0    int32;
-       st_rdev dev_t;    /* device ID (if special file) */
-       st_size off_t;    /* total size, in bytes */
-       st_blksize      blksize_t; /* blocksize for filesystem I/O */
-       st_blocks       blkcnt_t;  /* number of blocks allocated */
-       st_atime        Timespec;   /* time of last access */
-       st_mtime        Timespec;   /* time of last modification */
-       st_ctime        Timespec;   /* time of last status change */
-}
-
 
  * These calls have signatures that are independent of operating system.
  *
  * For simplicity of addressing in assembler, all integers are 64 bits
- * in these calling sequences.
+ * in these calling sequences (although it complicates some, such as pipe)
  */
 
-func open(name *byte, mode int64) (ret int64, errno int64);
-func close(fd int64) (ret int64, errno int64);
-func read(fd int64, buf *byte, nbytes int64) (ret int64, errno int64);
-func write(fd int64, buf *byte, nbytes int64) (ret int64, errno int64);
+func Syscall(trap int64, a1, a2, a3 int64) (r1, r2, err int64);
+func   AddrToInt(b *byte) int64;
+
+export Syscall
+export AddrToInt
+
 
-export open, close, read, write
 
 // license that can be found in the LICENSE file.
 
 //
-// System calls for AMD64, Darwin
+// System call support for AMD64, Darwin
 //
 
-TEXT   syscall·open(SB),1,$-8
-       MOVQ    8(SP), DI
-       MOVQ    16(SP), SI
-       MOVQ    $0, R10
-       MOVL    $(0x2000000+5), AX      // syscall entry
-       SYSCALL
-       JCC     4(PC)
-       MOVQ    $-1, 24(SP)
-       MOVQ    AX, 32(SP)
-       RET
-       MOVQ    AX, 24(SP)
-       MOVQ    $0, 32(SP)
-       RET
-
-TEXT   syscall·close(SB),1,$-8
-       MOVL    8(SP), DI
-       MOVL    $(0x2000000+6), AX      // syscall entry
-       SYSCALL
-       JCC     4(PC)
-       MOVQ    $-1, 16(SP)
-       MOVQ    AX, 24(SP)
-       RET
-       MOVQ    AX, 16(SP)
-       MOVQ    $0, 24(SP)
-       RET
-
-TEXT   syscall·read(SB),1,$-8
-       MOVQ    8(SP), DI
-       MOVQ    16(SP), SI
-       MOVQ    24(SP), DX
-       MOVL    $(0x2000000+3), AX      // syscall entry
-       SYSCALL
-       JCC     4(PC)
-       MOVQ    $-1, 32(SP)
-       MOVQ    AX, 40(SP)
-       RET
-       MOVQ    AX, 32(SP)
-       MOVQ    $0, 40(SP)
-       RET
-
-TEXT   syscall·write(SB),1,$-8
-       MOVQ    8(SP), DI
-       MOVQ    16(SP), SI
-       MOVQ    24(SP), DX
-       MOVL    $(0x2000000+4), AX      // syscall entry
-       SYSCALL
-       JCC     4(PC)
-       MOVQ    $-1, 32(SP)
-       MOVQ    AX, 40(SP)
-       RET
-       MOVQ    AX, 32(SP)
-       MOVQ    $0, 40(SP)
-       RET
+// func Syscall(trap int64, a1, a2, a3 int64) (r1, r2, err int64);
+// Trap # in AX, args in DI SI DX, return in AX DX
 
-TEXT   syscall·stat(SB),1,$-8
-       MOVQ    8(SP), DI
-       MOVQ    16(SP), SI
-       MOVL    $(0x2000000+338), AX    // syscall entry
+TEXT   syscall·Syscall(SB),1,$-8
+       MOVQ    16(SP), DI
+       MOVQ    24(SP), SI
+       MOVQ    32(SP), DX
+       MOVQ    8(SP), AX       // syscall entry
+       ADDQ    $0x2000000, AX
        SYSCALL
-       JCC     4(PC)
-       MOVQ    $-1, 24(SP)
-       MOVQ    AX, 32(SP)
+       JCC     5(PC)
+       MOVQ    $-1, 40(SP)     // r1
+       MOVQ    $0, 48(SP)      // r2
+       MOVQ    AX, 56(SP)  // errno
        RET
-       MOVQ    AX, 24(SP)
-       MOVQ    $0, 32(SP)
+       MOVQ    AX, 40(SP)      // r1
+       MOVQ    DX, 48(SP)      // r2
+       MOVQ    $0, 56(SP)      // errno
        RET
 
-TEXT   syscall·fstat(SB),1,$-8
-       MOVQ    8(SP), DI
-       MOVQ    16(SP), SI
-       MOVL    $(0x2000000+339), AX    // syscall entry
-       SYSCALL
-       JCC     4(PC)
-       MOVQ    $-1, 24(SP)
-       MOVQ    AX, 32(SP)
-       RET
-       MOVQ    AX, 24(SP)
-       MOVQ    $0, 32(SP)
+TEXT   syscall·AddrToInt(SB),1,$-8
+       MOVQ    8(SP), AX
+       MOVQ    AX, 16(SP)
        RET
 
-TEXT   syscall·lstat(SB),1,$-8
-       MOVQ    8(SP), DI
-       MOVQ    16(SP), SI
-       MOVL    $(0x2000000+340), AX    // syscall entry
-       SYSCALL
-       JCC     4(PC)
-       MOVQ    $-1, 24(SP)
-       MOVQ    AX, 32(SP)
-       RET
-       MOVQ    AX, 24(SP)
-       MOVQ    $0, 32(SP)
+TEXT   syscall·StatToInt(SB),1,$-8
+       MOVQ    8(SP), AX
+       MOVQ    AX, 16(SP)
        RET
 
 // System calls for AMD64, Linux
 //
 
-TEXT   syscall·open(SB),1,$0-16
-       MOVQ    8(SP), DI
-       MOVQ    16(SP), SI
-       MOVQ    $0, DX
-       MOVQ    $2, AX                  // syscall entry
+// func Syscall(trap int64, a1, a2, a3 int64) (r1, r2, err int64);
+// Trap # in AX, args in DI SI DX, return in AX DX
+
+TEXT   syscall·Syscall(SB),1,$-8
+       MOVQ    16(SP), DI
+       MOVQ    24(SP), SI
+       MOVQ    32(SP), DX
+       MOVQ    8(SP), AX       // syscall entry
        SYSCALL
        CMPQ    AX, $0xfffffffffffff001
-       JLS     5(PC)
-       MOVQ    $-1, 24(SP)
+       JLS     6(PC)
+       MOVQ    $-1, 40(SP)     // r1
+       MOVQ    $0, 48(SP)      // r2
        NEGQ    AX
-       MOVQ    AX, 32(SP)
+       MOVQ    AX, 56(SP)  // errno
        RET
-       MOVQ    AX, 24(SP)
-       MOVQ    $0, 32(SP)
+       MOVQ    AX, 40(SP)      // r1
+       MOVQ    DX, 48(SP)      // r2
+       MOVQ    $0, 56(SP)      // errno
        RET
 
-TEXT   syscall·close(SB),1,$0-16
-       MOVQ    8(SP), DI
-       MOVL    $3, AX                  // syscall entry
-       SYSCALL
-       CMPQ    AX, $0xfffffffffffff001
-       JLS     5(PC)
-       MOVQ    $-1, 16(SP)
-       NEGQ    AX
-       MOVQ    AX, 24(SP)
-       RET
+TEXT   syscall·AddrToInt(SB),1,$-8
+       MOVQ    8(SP), AX
        MOVQ    AX, 16(SP)
-       MOVQ    $0, 24(SP)
        RET
 
-TEXT   syscall·read(SB),1,$0-16
-       MOVL    8(SP), DI
-       MOVQ    16(SP), SI
-       MOVL    24(SP), DX
-       MOVL    $0, AX                  // syscall entry
-       SYSCALL
-       CMPQ    AX, $0xfffffffffffff001
-       JLS     5(PC)
-       MOVQ    $-1, 32(SP)
-       NEGQ    AX
-       MOVQ    AX, 40(SP)
-       RET
-       MOVQ    AX, 32(SP)
-       MOVQ    $0, 40(SP)
-       RET
-
-TEXT   syscall·write(SB),1,$0-16
-       MOVL    8(SP), DI
-       MOVQ    16(SP), SI
-       MOVL    24(SP), DX
-       MOVL    $1, AX                  // syscall entry
-       SYSCALL
-       CMPQ    AX, $0xfffffffffffff001
-       JLS     5(PC)
-       MOVQ    $-1, 32(SP)
-       NEGQ    AX
-       MOVQ    AX, 40(SP)
-       RET
-       MOVQ    AX, 32(SP)
-       MOVQ    $0, 40(SP)
-       RET
-
-TEXT   syscall·stat(SB),1,$0-16
-       MOVQ    8(SP), DI
-       MOVQ    16(SP), SI
-       MOVQ    $0, DX
-       MOVQ    $5, AX                  // syscall entry
-       SYSCALL
-       CMPQ    AX, $0xfffffffffffff001
-       JLS     5(PC)
-       MOVQ    $-1, 24(SP)
-       NEGQ    AX
-       MOVQ    AX, 32(SP)
-       RET
-       MOVQ    AX, 24(SP)
-       MOVQ    $0, 32(SP)
-       RET
-
-TEXT   syscall·fstat(SB),1,$0-16
-       MOVL    8(SP), DI
-       MOVQ    16(SP), SI
-       MOVQ    $0, DX
-       MOVQ    $5, AX                  // syscall entry
-       SYSCALL
-       CMPQ    AX, $0xfffffffffffff001
-       JLS     5(PC)
-       MOVQ    $-1, 24(SP)
-       NEGQ    AX
-       MOVQ    AX, 32(SP)
-       RET
-       MOVQ    AX, 24(SP)
-       MOVQ    $0, 32(SP)
-       RET
-
-TEXT   syscall·lstat(SB),1,$0-16
-       MOVL    8(SP), DI
-       MOVQ    16(SP), SI
-       MOVQ    $0, DX
-       MOVQ    $6, AX                  // syscall entry
-       SYSCALL
-       CMPQ    AX, $0xfffffffffffff001
-       JLS     5(PC)
-       MOVQ    $-1, 24(SP)
-       NEGQ    AX
-       MOVQ    AX, 32(SP)
-       RET
-       MOVQ    AX, 24(SP)
-       MOVQ    $0, 32(SP)
+TEXT   syscall·StatToInt(SB),1,$-8
+       MOVQ    8(SP), AX
+       MOVQ    AX, 16(SP)
        RET