summaryrefslogtreecommitdiff
path: root/src/pkg/syscall
diff options
context:
space:
mode:
authorRuss Cox <rsc@golang.org>2009-09-22 07:49:31 -0700
committerRuss Cox <rsc@golang.org>2009-09-22 07:49:31 -0700
commit5c68a98ecad84edb4f00e7194759b575913b35bf (patch)
tree559a6c61ae320938538c0decd4018efbc42d666f /src/pkg/syscall
parent00c5348f530f965b6fc663a54a01448913a1512f (diff)
downloadgolang-5c68a98ecad84edb4f00e7194759b575913b35bf.tar.gz
nacl syscall package.
similar tweaks to make debug/proc, net, os build. R=r DELTA=861 (855 added, 4 deleted, 2 changed) OCL=34877 CL=34890
Diffstat (limited to 'src/pkg/syscall')
-rwxr-xr-xsrc/pkg/syscall/PORT.sh9
-rw-r--r--src/pkg/syscall/asm_nacl_386.s120
-rwxr-xr-xsrc/pkg/syscall/mkerrors_nacl.sh41
-rw-r--r--src/pkg/syscall/mksysnum_nacl.sh29
-rw-r--r--src/pkg/syscall/syscall_nacl.go329
-rw-r--r--src/pkg/syscall/syscall_nacl_386.go15
-rw-r--r--src/pkg/syscall/types_nacl.c115
7 files changed, 658 insertions, 0 deletions
diff --git a/src/pkg/syscall/PORT.sh b/src/pkg/syscall/PORT.sh
index 3e165f87b..acc0760b9 100755
--- a/src/pkg/syscall/PORT.sh
+++ b/src/pkg/syscall/PORT.sh
@@ -103,6 +103,15 @@ linux_amd64)
mksysnum="mksysnum_linux.sh /usr/include/asm/unistd_64.h"
mktypes="godefs -gsyscall -f-m64"
;;
+nacl_386)
+ NACL="/home/rsc/pub/nacl/native_client"
+ NACLRUN="$NACL/src/trusted/service_runtime"
+ NACLSDK="$NACL/src/third_party/nacl_sdk/linux/sdk/nacl-sdk/nacl"
+ mksyscall="mksyscall.sh -l32"
+ mksysnum="mksysnum_nacl.sh $NACLRUN/include/bits/nacl_syscalls.h"
+ mktypes="godefs -gsyscall -f-m32 -f-I$NACLSDK/include -f-I$NACL"
+ mkerrors="mkerrors_nacl.sh $NACLRUN/include/sys/errno.h"
+ ;;
*)
echo 'unrecognized $GOOS_$GOARCH: ' "$GOOSARCH" 1>&2
exit 1
diff --git a/src/pkg/syscall/asm_nacl_386.s b/src/pkg/syscall/asm_nacl_386.s
new file mode 100644
index 000000000..0e993ef30
--- /dev/null
+++ b/src/pkg/syscall/asm_nacl_386.s
@@ -0,0 +1,120 @@
+// 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.
+
+//
+// System calls for 386, Native Client
+//
+
+#define SYSCALL(x) $(0x10000+x * 32)
+
+// func Syscall(trap uintptr, a1, a2, a3 uintptr) (r1, r2, err uintptr);
+// Trap # in AX, args in BX CX DX SI DI, return in AX
+
+TEXT syscall·Syscall(SB),7,$20
+ CALL sys·entersyscall(SB)
+ MOVL trap+0(FP), AX // syscall entry
+ MOVL a1+4(FP), BX
+ MOVL a2+8(FP), CX
+ MOVL a3+12(FP), DX
+ MOVL $0, SI
+ MOVL $0, DI
+
+ MOVL BX, 0(SP)
+ MOVL CX, 4(SP)
+ MOVL DX, 8(SP)
+ MOVL SI, 12(SP)
+ MOVL DI, 16(SP)
+
+ // Call $(0x10000+32*AX)
+ SHLL $5, AX
+ ADDL $0x10000, AX
+ CALL AX
+
+ CMPL AX, $0xfffff001
+ JLS ok
+ MOVL $-1, 20(SP) // r1
+ MOVL $0, 24(SP) // r2
+ NEGL AX
+ MOVL AX, 28(SP) // errno
+ CALL sys·exitsyscall(SB)
+ RET
+ok:
+ MOVL AX, 20(SP) // r1
+ MOVL DX, 24(SP) // r2
+ MOVL $0, 28(SP) // errno
+ CALL sys·exitsyscall(SB)
+ RET
+
+// func Syscall6(trap uintptr, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2, err uintptr);
+// Actually Syscall5 but the rest of the code expects it to be named Syscall6.
+TEXT syscall·Syscall6(SB),7,$20
+ CALL sys·entersyscall(SB)
+ MOVL trap+0(FP), AX // syscall entry
+ MOVL a1+4(FP), BX
+ MOVL a2+8(FP), CX
+ MOVL a3+12(FP), DX
+ MOVL a4+16(FP), SI
+ MOVL a5+20(FP), DI
+ // a6+24(FP) is ignored
+
+ MOVL BX, 0(SP)
+ MOVL CX, 4(SP)
+ MOVL DX, 8(SP)
+ MOVL SI, 12(SP)
+ MOVL DI, 16(SP)
+
+ // Call $(0x10000+32*AX)
+ SHLL $5, AX
+ ADDL $0x10000, AX
+ CALL AX
+
+ CMPL AX, $0xfffff001
+ JLS ok6
+ MOVL $-1, 32(SP) // r1
+ MOVL $0, 36(SP) // r2
+ NEGL AX
+ MOVL AX, 40(SP) // errno
+ CALL sys·exitsyscall(SB)
+ RET
+ok6:
+ MOVL AX, 32(SP) // r1
+ MOVL DX, 36(SP) // r2
+ MOVL $0, 40(SP) // errno
+ CALL sys·exitsyscall(SB)
+ RET
+
+// func RawSyscall(trap uintptr, a1, a2, a3 uintptr) (r1, r2, err uintptr);
+TEXT syscall·RawSyscall(SB),7,$0
+TEXT syscall·Syscall(SB),7,$20
+ MOVL trap+0(FP), AX // syscall entry
+ MOVL a1+4(FP), BX
+ MOVL a2+8(FP), CX
+ MOVL a3+12(FP), DX
+ MOVL $0, SI
+ MOVL $0, DI
+
+ MOVL BX, 0(SP)
+ MOVL CX, 4(SP)
+ MOVL DX, 8(SP)
+ MOVL SI, 12(SP)
+ MOVL DI, 16(SP)
+
+ // Call $(0x10000+32*AX)
+ SHLL $5, AX
+ ADDL $0x10000, AX
+ CALL AX
+
+ CMPL AX, $0xfffff001
+ JLS ok1
+ MOVL $-1, 20(SP) // r1
+ MOVL $0, 24(SP) // r2
+ NEGL AX
+ MOVL AX, 28(SP) // errno
+ RET
+ok1:
+ MOVL AX, 20(SP) // r1
+ MOVL DX, 24(SP) // r2
+ MOVL $0, 28(SP) // errno
+ RET
+
diff --git a/src/pkg/syscall/mkerrors_nacl.sh b/src/pkg/syscall/mkerrors_nacl.sh
new file mode 100755
index 000000000..f8abff9c2
--- /dev/null
+++ b/src/pkg/syscall/mkerrors_nacl.sh
@@ -0,0 +1,41 @@
+#!/bin/sh
+# 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.
+
+# Generate Go code listing error values (ENAMETOOLONG etc)
+# for Native Client.
+
+echo '// mkerrors_nacl.sh' "$@"
+echo '// MACHINE GENERATED BY THE COMMAND ABOVE; DO NOT EDIT'
+echo
+echo 'package syscall'
+echo
+echo 'const ('
+perl -n -e '
+ if(/#define\s+NACL_ABI_(\S*)\s+([0-9]+)/) {
+ print "\t$1 = $2;\n"
+ }
+' $1
+echo ' ENACL = 99; /* otherwise unused */'
+echo ')'
+echo
+echo
+echo '// Error table'
+echo 'var errors = [...]string {'
+perl -n -e '
+ if(/#define\s+NACL_ABI_(\S*)\s+([0-9]+)\s+\/\* (.*) \*\//) {
+ $err = $1;
+ $text = $3;
+ if($text =~ /^[A-Z][a-z]/) {
+ # lowercase first letter: Bad -> bad, but STREAM -> STREAM.
+ $l = substr($text, 0, 1);
+ $rest = substr($text, 1);
+ $l =~ y/A-Z/a-z/;
+ $text = $l . $rest;
+ }
+ print "\t$err: \"$text\",\n";
+ }
+' $1
+echo ' ENACL: "not supported by native client",'
+echo '}'
diff --git a/src/pkg/syscall/mksysnum_nacl.sh b/src/pkg/syscall/mksysnum_nacl.sh
new file mode 100644
index 000000000..f42f45056
--- /dev/null
+++ b/src/pkg/syscall/mksysnum_nacl.sh
@@ -0,0 +1,29 @@
+#!/usr/bin/perl
+# 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.
+
+my $command = "mksysnum_nacl.sh ". join(' ', @ARGV);
+
+print <<EOF;
+// $command
+// MACHINE GENERATED BY THE ABOVE COMMAND; DO NOT EDIT
+
+package syscall
+
+const(
+EOF
+
+while(<>){
+ if(/^#define NACL_sys_(\w+)\s+([0-9]+)/){
+ my $name = "SYS_$1";
+ my $num = $2;
+ $name =~ y/a-z/A-Z/;
+ print " $name = $num;\n";
+ }
+}
+
+print <<EOF;
+)
+
+EOF
diff --git a/src/pkg/syscall/syscall_nacl.go b/src/pkg/syscall/syscall_nacl.go
new file mode 100644
index 000000000..4466f028a
--- /dev/null
+++ b/src/pkg/syscall/syscall_nacl.go
@@ -0,0 +1,329 @@
+// 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.
+
+// Native Client system calls.
+
+package syscall
+
+const OS = "nacl"
+
+// Auto-generated
+
+//sys Chmod(path string, mode int) (errno int)
+//sys Clock() (clock int)
+//sys Close(fd int) (errno int)
+//sys Exit(code int)
+//sys Fstat(fd int, stat *Stat_t) (errno int)
+//sys Getdents(fd int, buf []byte) (n int, errno int)
+//sys Getpid() (pid int)
+//sys Gettimeofday(tv *Timeval) (errno int)
+//sys Open(path string, mode int, perm int) (fd int, errno int)
+//sys Read(fd int, p []byte) (n int, errno int)
+//sys read(fd int, buf *byte, nbuf int) (n int, errno int)
+//sys Stat(path string, stat *Stat_t) (errno int)
+//sys Write(fd int, p []byte) (n int, errno int)
+
+// Hand-written
+
+func Seek(fd int, offset int64, whence int) (newoffset int64, errno int) {
+ // Offset passed to system call is 32 bits. Failure of vision by NaCl.
+ if int64(int32(offset)) != offset {
+ return 0, ERANGE
+ }
+ o, _, e := Syscall(SYS_LSEEK, uintptr(fd), uintptr(offset), uintptr(whence));
+ return int64(o), int(e);
+}
+
+// Implemented in NaCl but not here:
+// SYS_IOCTL
+// SYS_SYSBRK
+// SYS_MMAP
+// SYS_MUNMAP
+// SYS_MULTIMEDIA_*
+// SYS_VIDEO_*
+// SYS_AUDIO_*
+// SYS_IMC_*
+// SYS_MUTEX_*
+// SYS_COND_*
+// SYS_THREAD_*
+// SYS_TLS_*
+// SYS_SRPC_*
+// SYS_SEM_*
+// SYS_SCHED_YIELD
+// SYS_SYSCONF
+
+// Not implemented in NaCl but needed to compile other packages.
+
+const (
+ SIGTRAP = 5;
+)
+
+func Pipe(p []int) (errno int) {
+ return ENACL;
+}
+
+func fcntl(fd, cmd, arg int) (val int, errno int) {
+ return 0, ENACL;
+}
+
+func Pread(fd int, p []byte, offset int64) (n int, errno int) {
+ return 0, ENACL;
+}
+
+func Pwrite(fd int, p []byte, offset int64) (n int, errno int) {
+ return 0, ENACL;
+}
+
+func Mkdir(path string, mode int) (errno int) {
+ return ENACL;
+}
+
+func Lstat(path string, stat *Stat_t) (errno int) {
+ return ENACL;
+}
+
+func Chdir(path string) (errno int) {
+ return ENACL;
+}
+
+func Fchdir(fd int) (errno int) {
+ return ENACL;
+}
+
+func Unlink(path string) (errno int) {
+ return ENACL;
+}
+
+func Rmdir(path string) (errno int) {
+ return ENACL;
+}
+
+func Link(oldpath, newpath string) (errno int) {
+ return ENACL;
+}
+
+func Symlink(path, link string) (errno int) {
+ return ENACL;
+}
+
+func Readlink(path string, buf []byte) (n int, errno int) {
+ return 0, ENACL;
+}
+
+func Fchmod(fd int, mode int) (errno int) {
+ return ENACL;
+}
+
+func Chown(path string, uid int, gid int) (errno int) {
+ return ENACL;
+}
+
+func Lchown(path string, uid int, gid int) (errno int) {
+ return ENACL;
+}
+
+func Fchown(fd int, uid int, gid int) (errno int) {
+ return ENACL;
+}
+
+func Truncate(name string, size int64) (errno int) {
+ return ENACL;
+}
+
+func Ftruncate(fd int, length int64) (errno int) {
+ return ENACL;
+}
+
+// TODO(rsc): There must be a way to sleep, perhaps
+// via the multimedia system calls.
+
+func Sleep(ns int64) (errno int) {
+ return ENACL;
+}
+
+// NaCL doesn't actually implement Getwd, but it also
+// don't implement Chdir, so the fallback algorithm
+// fails worse than calling Getwd does.
+
+const ImplementsGetwd = true;
+
+func Getwd() (wd string, errno int) {
+ return "", ENACL;
+}
+
+func Getuid() (uid int) {
+ return -1
+}
+
+func Geteuid() (euid int) {
+ return -1
+}
+
+func Getgid() (gid int) {
+ return -1
+}
+
+func Getegid() (egid int) {
+ return -1
+}
+
+func Getppid() (ppid int) {
+ return -1
+}
+
+func Getgroups() (gids []int, errno int) {
+ return nil, ENACL
+}
+
+type Sockaddr interface {
+ sockaddr()
+}
+
+type SockaddrInet4 struct {
+ Port int;
+ Addr [4]byte;
+}
+
+func (*SockaddrInet4) sockaddr() {
+}
+
+type SockaddrInet6 struct {
+ Port int;
+ Addr [16]byte;
+}
+
+func (*SockaddrInet6) sockaddr() {
+}
+
+type SockaddrUnix struct {
+ Name string;
+}
+
+func (*SockaddrUnix) sockaddr() {
+}
+
+const (
+ AF_INET = 1+iota;
+ AF_INET6;
+ AF_UNIX;
+ IPPROTO_TCP;
+ SOCK_DGRAM;
+ SOCK_STREAM;
+ SOL_SOCKET;
+ SOMAXCONN;
+ SO_DONTROUTE;
+ SO_KEEPALIVE;
+ SO_LINGER;
+ SO_RCVBUF;
+ SO_REUSEADDR;
+ SO_SNDBUF;
+ TCP_NODELAY;
+ _PTRACE_TRACEME;
+)
+
+func Accept(fd int) (nfd int, sa Sockaddr, errno int) {
+ return 0, nil, ENACL;
+}
+
+func Getsockname(fd int) (sa Sockaddr, errno int) {
+ return nil, ENACL;
+}
+
+func Getpeername(fd int) (sa Sockaddr, errno int) {
+ return nil, ENACL;
+}
+
+func Bind(fd int, sa Sockaddr) (errno int) {
+ return ENACL;
+}
+
+func Connect(fd int, sa Sockaddr) (errno int) {
+ return ENACL;
+}
+
+func Socket(domain, typ, proto int) (fd, errno int) {
+ return 0, ENACL;
+}
+
+func SetsockoptInt(fd, level, opt int, value int) (errno int) {
+ return ENACL;
+}
+
+func SetsockoptTimeval(fd, level, opt int, tv *Timeval) (errno int) {
+ return ENACL;
+}
+
+type Linger struct {
+ Onoff int32;
+ Linger int32;
+}
+
+func SetsockoptLinger(fd, level, opt int, l *Linger) (errno int) {
+ return ENACL;
+}
+
+func Listen(s int, n int) (errno int) {
+ return ENACL;
+}
+
+type Rusage struct {
+ Utime Timeval;
+ Stime Timeval;
+ Maxrss int32;
+ Ixrss int32;
+ Idrss int32;
+ Isrss int32;
+ Minflt int32;
+ Majflt int32;
+ Nswap int32;
+ Inblock int32;
+ Oublock int32;
+ Msgsnd int32;
+ Msgrcv int32;
+ Nsignals int32;
+ Nvcsw int32;
+ Nivcsw int32;
+}
+
+func Wait4(pid int, wstatus *WaitStatus, options int, rusage *Rusage) (wpid int, errno int) {
+ return 0, ENACL;
+}
+
+type WaitStatus uint32
+
+func (WaitStatus) Exited() bool {
+ return false
+}
+
+func (WaitStatus) ExitStatus() int {
+ return -1
+}
+
+func (WaitStatus) Signal() int {
+ return -1
+}
+
+func (WaitStatus) CoreDump() bool {
+ return false
+}
+
+func (WaitStatus) Stopped() bool {
+ return false
+}
+
+func (WaitStatus) Continued() bool {
+ return false
+}
+
+func (WaitStatus) StopSignal() int {
+ return -1
+}
+
+func (WaitStatus) Signaled() bool {
+ return false
+}
+
+func (WaitStatus) TrapCause() int {
+ return -1
+}
diff --git a/src/pkg/syscall/syscall_nacl_386.go b/src/pkg/syscall/syscall_nacl_386.go
new file mode 100644
index 000000000..e0a7acb6c
--- /dev/null
+++ b/src/pkg/syscall/syscall_nacl_386.go
@@ -0,0 +1,15 @@
+// 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 Getpagesize() int {
+ return 4096
+}
+
+func NsecToTimeval(nsec int64) (tv Timeval) {
+ tv.Sec = int32(nsec/1e9);
+ tv.Usec = int32(nsec%1e9);
+ return;
+}
diff --git a/src/pkg/syscall/types_nacl.c b/src/pkg/syscall/types_nacl.c
new file mode 100644
index 000000000..f594061a2
--- /dev/null
+++ b/src/pkg/syscall/types_nacl.c
@@ -0,0 +1,115 @@
+// 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.
+
+/*
+Input to godefs. See PORT.sh
+ */
+
+#define _LARGEFILE_SOURCE
+#define _LARGEFILE64_SOURCE
+#define _FILE_OFFSET_BITS 64
+#define _GNU_SOURCE
+
+#define __native_client__ 1
+
+#define suseconds_t nacl_suseconds_t_1
+#include <sys/types.h>
+#undef suseconds_t
+
+#include <sys/dirent.h>
+#include <sys/mman.h>
+#include <sys/fcntl.h>
+#include <sys/stat.h>
+#include <sys/time.h>
+#include <sys/unistd.h>
+
+// Machine characteristics; for internal use.
+
+enum
+{
+ $sizeofPtr = sizeof(void*),
+ $sizeofShort = sizeof(short),
+ $sizeofInt = sizeof(int),
+ $sizeofLong = sizeof(long),
+ $sizeofLongLong = sizeof(long long),
+};
+
+
+// Unimplemented system calls
+enum {
+ $SYS_FORK = 0,
+ $SYS_PTRACE = 0,
+ $SYS_CHDIR = 0,
+ $SYS_DUP2 = 0,
+ $SYS_FCNTL = 0,
+ $SYS_EXECVE = 0
+};
+
+// Basic types
+
+typedef short $_C_short;
+typedef int $_C_int;
+typedef long $_C_long;
+typedef long long $_C_long_long;
+typedef off_t $_C_off_t;
+
+// Time
+
+typedef struct timespec $Timespec;
+typedef struct timeval $Timeval;
+typedef time_t $Time_t;
+
+// Processes
+
+//typedef struct rusage $Rusage;
+//typedef struct rlimit $Rlimit;
+
+typedef gid_t $_Gid_t;
+
+// Files
+
+enum
+{
+ $O_RDONLY = O_RDONLY,
+ $O_WRONLY = O_WRONLY,
+ $O_RDWR = O_RDWR,
+ $O_APPEND = O_APPEND,
+ $O_ASYNC = O_ASYNC,
+ $O_CREAT = O_CREAT,
+ $O_NOCTTY = 0, // not supported
+ $O_NONBLOCK = O_NONBLOCK,
+ $O_SYNC = O_SYNC,
+ $O_TRUNC = O_TRUNC,
+ $O_CLOEXEC = 0, // not supported
+
+ $F_GETFD = F_GETFD,
+ $F_SETFD = F_SETFD,
+
+ $F_GETFL = F_GETFL,
+ $F_SETFL = F_SETFL,
+
+ $FD_CLOEXEC = 0, // not supported
+};
+
+enum
+{ // Directory mode bits
+ $S_IFMT = S_IFMT,
+ $S_IFIFO = S_IFIFO,
+ $S_IFCHR = S_IFCHR,
+ $S_IFDIR = S_IFDIR,
+ $S_IFBLK = S_IFBLK,
+ $S_IFREG = S_IFREG,
+ $S_IFLNK = S_IFLNK,
+ $S_IFSOCK = S_IFSOCK,
+ $S_ISUID = S_ISUID,
+ $S_ISGID = S_ISGID,
+ $S_ISVTX = S_ISVTX,
+ $S_IRUSR = S_IRUSR,
+ $S_IWUSR = S_IWUSR,
+ $S_IXUSR = S_IXUSR,
+};
+
+typedef struct stat $Stat_t;
+
+typedef struct dirent $Dirent;