diff options
Diffstat (limited to 'src/pkg/runtime')
| -rw-r--r-- | src/pkg/runtime/arch_386.h | 5 | ||||
| -rw-r--r-- | src/pkg/runtime/arch_amd64.h | 5 | ||||
| -rw-r--r-- | src/pkg/runtime/arch_amd64p32.h | 20 | ||||
| -rw-r--r-- | src/pkg/runtime/arch_arm.h | 1 | ||||
| -rw-r--r-- | src/pkg/runtime/mem_linux.c | 1 | ||||
| -rw-r--r-- | src/pkg/runtime/mem_nacl.c | 109 | ||||
| -rw-r--r-- | src/pkg/runtime/mgc0.c | 1 | ||||
| -rw-r--r-- | src/pkg/runtime/mheap.c | 2 | ||||
| -rw-r--r-- | src/pkg/runtime/mknacl.sh | 15 | ||||
| -rw-r--r-- | src/pkg/runtime/netpoll.goc | 2 | ||||
| -rw-r--r-- | src/pkg/runtime/netpoll_nacl.c | 37 | ||||
| -rw-r--r-- | src/pkg/runtime/os_nacl.c | 275 | ||||
| -rw-r--r-- | src/pkg/runtime/os_nacl.h | 162 | ||||
| -rw-r--r-- | src/pkg/runtime/runtime.h | 40 | ||||
| -rw-r--r-- | src/pkg/runtime/signal_386.c | 2 | ||||
| -rw-r--r-- | src/pkg/runtime/signal_nacl_386.h | 23 | ||||
| -rw-r--r-- | src/pkg/runtime/signal_nacl_amd64p32.h | 31 | ||||
| -rw-r--r-- | src/pkg/runtime/signals_nacl.h | 50 | ||||
| -rw-r--r-- | src/pkg/runtime/sys_x86.c | 4 | ||||
| -rw-r--r-- | src/pkg/runtime/syscall_nacl.h | 71 | ||||
| -rw-r--r-- | src/pkg/runtime/traceback_x86.c | 10 | ||||
| -rw-r--r-- | src/pkg/runtime/vlrt_386.c | 12 | ||||
| -rw-r--r-- | src/pkg/runtime/vlrt_arm.c | 6 |
23 files changed, 856 insertions, 28 deletions
diff --git a/src/pkg/runtime/arch_386.h b/src/pkg/runtime/arch_386.h index ebdb3ff4e2..5c0a54f8c0 100644 --- a/src/pkg/runtime/arch_386.h +++ b/src/pkg/runtime/arch_386.h @@ -7,5 +7,10 @@ enum { BigEndian = 0, CacheLineSize = 64, RuntimeGogoBytes = 64, +#ifdef GOOS_nacl + PhysPageSize = 65536, +#else + PhysPageSize = 4096, +#endif PCQuantum = 1 }; diff --git a/src/pkg/runtime/arch_amd64.h b/src/pkg/runtime/arch_amd64.h index 171839481b..88b68cc6df 100644 --- a/src/pkg/runtime/arch_amd64.h +++ b/src/pkg/runtime/arch_amd64.h @@ -11,5 +11,10 @@ enum { #else RuntimeGogoBytes = 64, #endif +#ifdef GOOS_nacl + PhysPageSize = 65536, +#else + PhysPageSize = 4096, +#endif PCQuantum = 1 }; diff --git a/src/pkg/runtime/arch_amd64p32.h b/src/pkg/runtime/arch_amd64p32.h new file mode 100644 index 0000000000..88b68cc6df --- /dev/null +++ b/src/pkg/runtime/arch_amd64p32.h @@ -0,0 +1,20 @@ +// 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. + +enum { + thechar = '6', + BigEndian = 0, + CacheLineSize = 64, +#ifdef GOOS_solaris + RuntimeGogoBytes = 80, +#else + RuntimeGogoBytes = 64, +#endif +#ifdef GOOS_nacl + PhysPageSize = 65536, +#else + PhysPageSize = 4096, +#endif + PCQuantum = 1 +}; diff --git a/src/pkg/runtime/arch_arm.h b/src/pkg/runtime/arch_arm.h index e5da01c603..b9711289f4 100644 --- a/src/pkg/runtime/arch_arm.h +++ b/src/pkg/runtime/arch_arm.h @@ -7,5 +7,6 @@ enum { BigEndian = 0, CacheLineSize = 32, RuntimeGogoBytes = 80, + PhysPageSize = 4096, PCQuantum = 4 }; diff --git a/src/pkg/runtime/mem_linux.c b/src/pkg/runtime/mem_linux.c index b0f2956335..2786ad70f6 100644 --- a/src/pkg/runtime/mem_linux.c +++ b/src/pkg/runtime/mem_linux.c @@ -11,6 +11,7 @@ enum { _PAGE_SIZE = 4096, + EACCES = 13, }; static int32 diff --git a/src/pkg/runtime/mem_nacl.c b/src/pkg/runtime/mem_nacl.c new file mode 100644 index 0000000000..993d194dd5 --- /dev/null +++ b/src/pkg/runtime/mem_nacl.c @@ -0,0 +1,109 @@ +// Copyright 2010 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +#include "runtime.h" +#include "arch_GOARCH.h" +#include "defs_GOOS_GOARCH.h" +#include "os_GOOS.h" +#include "malloc.h" + +enum +{ + Debug = 0, +}; + +void* +runtime·SysAlloc(uintptr n, uint64 *stat) +{ + void *v; + + v = runtime·mmap(nil, n, PROT_READ|PROT_WRITE, MAP_ANON|MAP_PRIVATE, -1, 0); + if(v < (void*)4096) { + if(Debug) + runtime·printf("SysAlloc(%p): %p\n", n, v); + return nil; + } + runtime·xadd64(stat, n); + if(Debug) + runtime·printf("SysAlloc(%p) = %p\n", n, v); + return v; +} + +void +runtime·SysUnused(void *v, uintptr n) +{ + if(Debug) + runtime·printf("SysUnused(%p, %p)\n", v, n); +} + +void +runtime·SysUsed(void *v, uintptr n) +{ + USED(v); + USED(n); +} + +void +runtime·SysFree(void *v, uintptr n, uint64 *stat) +{ + if(Debug) + runtime·printf("SysFree(%p, %p)\n", v, n); + runtime·xadd64(stat, -(uint64)n); + runtime·munmap(v, n); +} + +void* +runtime·SysReserve(void *v, uintptr n) +{ + void *p; + + // On 64-bit, people with ulimit -v set complain if we reserve too + // much address space. Instead, assume that the reservation is okay + // and check the assumption in SysMap. + if(NaCl || sizeof(void*) == 8) + return v; + + p = runtime·mmap(v, n, PROT_NONE, MAP_ANON|MAP_PRIVATE, -1, 0); + if(p < (void*)4096) + return nil; + return p; +} + +void +runtime·SysMap(void *v, uintptr n, uint64 *stat) +{ + void *p; + + runtime·xadd64(stat, n); + + // On 64-bit, we don't actually have v reserved, so tread carefully. + if(sizeof(void*) == 8) { + p = runtime·mmap(v, n, PROT_READ|PROT_WRITE, MAP_ANON|MAP_PRIVATE, -1, 0); + if(p == (void*)ENOMEM) { + runtime·printf("SysMap(%p, %p): %p\n", v, n, p); + runtime·throw("runtime: out of memory"); + } + if(p != v) { + runtime·printf("SysMap(%p, %p): %p\n", v, n, p); + runtime·printf("runtime: address space conflict: map(%p) = %p\n", v, p); + runtime·throw("runtime: address space conflict"); + } + if(Debug) + runtime·printf("SysMap(%p, %p) = %p\n", v, n, p); + return; + } + + p = runtime·mmap(v, n, PROT_READ|PROT_WRITE, MAP_ANON|MAP_FIXED|MAP_PRIVATE, -1, 0); + if(p == (void*)ENOMEM) { + runtime·printf("SysMap(%p, %p): %p\n", v, n, p); + runtime·throw("runtime: out of memory"); + } + if(p != v) { + runtime·printf("SysMap(%p, %p): %p\n", v, n, p); + runtime·printf("mmap MAP_FIXED %p returned %p\n", v, p); + runtime·throw("runtime: cannot map pages in arena address space"); + } + if(Debug) + runtime·printf("SysMap(%p, %p) = %p\n", v, n, p); +} diff --git a/src/pkg/runtime/mgc0.c b/src/pkg/runtime/mgc0.c index 95c3e83151..8d91a6db2e 100644 --- a/src/pkg/runtime/mgc0.c +++ b/src/pkg/runtime/mgc0.c @@ -2771,6 +2771,7 @@ runtime·MHeap_MapBits(MHeap *h) n = (h->arena_used - h->arena_start) / wordsPerBitmapWord; n = ROUND(n, bitmapChunk); + n = ROUND(n, PhysPageSize); if(h->bitmap_mapped >= n) return; diff --git a/src/pkg/runtime/mheap.c b/src/pkg/runtime/mheap.c index ba46b6404e..d89512d3f1 100644 --- a/src/pkg/runtime/mheap.c +++ b/src/pkg/runtime/mheap.c @@ -82,7 +82,7 @@ runtime·MHeap_MapSpans(MHeap *h) n = (uintptr)h->arena_used; n -= (uintptr)h->arena_start; n = n / PageSize * sizeof(h->spans[0]); - n = ROUND(n, PageSize); + n = ROUND(n, PhysPageSize); if(h->spans_mapped >= n) return; runtime·SysMap((byte*)h->spans + h->spans_mapped, n - h->spans_mapped, &mstats.other_sys); diff --git a/src/pkg/runtime/mknacl.sh b/src/pkg/runtime/mknacl.sh new file mode 100644 index 0000000000..47fb7bd88b --- /dev/null +++ b/src/pkg/runtime/mknacl.sh @@ -0,0 +1,15 @@ +#!/bin/bash +# 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. + +cat /Users/rsc/pub/native_client/src/trusted/service_runtime/include/bits/nacl_syscalls.h | + awk ' + BEGIN { + printf("// generated by mknacl.sh - do not edit\n") + } + NF==3 && $1=="#define" && $2~/^NACL_sys_/ { + name=$2 + sub(/^NACL_sys_/, "SYS_", name) + printf("#define %s %s\n", name, $3) + }' >syscall_nacl.h diff --git a/src/pkg/runtime/netpoll.goc b/src/pkg/runtime/netpoll.goc index 9cc5eb5a36..77ddde9d60 100644 --- a/src/pkg/runtime/netpoll.goc +++ b/src/pkg/runtime/netpoll.goc @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -// +build darwin dragonfly freebsd linux netbsd openbsd solaris windows +// +build darwin dragonfly freebsd linux nacl netbsd openbsd solaris windows package net diff --git a/src/pkg/runtime/netpoll_nacl.c b/src/pkg/runtime/netpoll_nacl.c new file mode 100644 index 0000000000..b75753a23b --- /dev/null +++ b/src/pkg/runtime/netpoll_nacl.c @@ -0,0 +1,37 @@ +// 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. + +#include "runtime.h" +#include "defs_GOOS_GOARCH.h" +#include "os_GOOS.h" + +// Fake network poller for NaCl. +// Should never be used, because NaCl network connections do not honor "SetNonblock". + +void +runtime·netpollinit(void) +{ +} + +int32 +runtime·netpollopen(uintptr fd, PollDesc *pd) +{ + USED(fd); + USED(pd); + return 0; +} + +int32 +runtime·netpollclose(uintptr fd) +{ + USED(fd); + return 0; +} + +G* +runtime·netpoll(bool block) +{ + USED(block); + return nil; +} diff --git a/src/pkg/runtime/os_nacl.c b/src/pkg/runtime/os_nacl.c new file mode 100644 index 0000000000..3c5e487ad1 --- /dev/null +++ b/src/pkg/runtime/os_nacl.c @@ -0,0 +1,275 @@ +// Copyright 2010 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +#include "runtime.h" +#include "defs_GOOS_GOARCH.h" +#include "os_GOOS.h" +#include "arch_GOARCH.h" +#include "../../cmd/ld/textflag.h" +#include "stack.h" + +int8 *goos = "nacl"; +extern SigTab runtime·sigtab[]; + +void runtime·sigtramp(void); + +// Called to initialize a new m (including the bootstrap m). +// Called on the parent thread (main thread in case of bootstrap), can allocate memory. +void +runtime·mpreinit(M *mp) +{ + mp->gsignal = runtime·malg(32*1024); // OS X wants >=8K, Linux >=2K +} + +// Called to initialize a new m (including the bootstrap m). +// Called on the new thread, can not allocate memory. +void +runtime·minit(void) +{ + int32 ret; + + // Initialize signal handling + ret = runtime·nacl_exception_stack((byte*)m->gsignal->stackguard - StackGuard, 32*1024); + if(ret < 0) + runtime·printf("runtime: nacl_exception_stack: error %d\n", -ret); + + ret = runtime·nacl_exception_handler(runtime·sigtramp, nil); + if(ret < 0) + runtime·printf("runtime: nacl_exception_handler: error %d\n", -ret); +} + +// Called from dropm to undo the effect of an minit. +void +runtime·unminit(void) +{ +} + +int8 runtime·sigtrampf[] = "runtime: signal at PC=%X AX=%X CX=%X DX=%X BX=%X DI=%X R15=%X *SP=%X\n"; +int8 runtime·sigtrampp[] = "runtime: sigtramp"; + +extern byte runtime·tls0[]; + +void +runtime·osinit(void) +{ + runtime·ncpu = 1; + m->procid = 2; +//runtime·nacl_exception_handler(runtime·sigtramp, nil); +} + +void +runtime·crash(void) +{ + *(int32*)0 = 0; +} + +void +runtime·get_random_data(byte **rnd, int32 *rnd_len) +{ + *rnd = nil; + *rnd_len = 0; +} + +void +runtime·goenvs(void) +{ + runtime·goenvs_unix(); +} + +void +runtime·initsig(void) +{ +} + +#pragma textflag NOSPLIT +void +runtime·usleep(uint32 us) +{ + Timespec ts; + + ts.tv_sec = us/1000000; + ts.tv_nsec = (us%1000000)*1000; + runtime·nacl_nanosleep(&ts, nil); +} + +void runtime·mstart_nacl(void); + +void +runtime·newosproc(M *mp, void *stk) +{ + int32 ret; + void **tls; + + tls = (void**)mp->tls; + tls[0] = mp->g0; + tls[1] = mp; + ret = runtime·nacl_thread_create(runtime·mstart_nacl, stk, tls+2, 0); + if(ret < 0) { + runtime·printf("nacl_thread_create: error %d\n", -ret); + runtime·throw("newosproc"); + } +} + +uintptr +runtime·semacreate(void) +{ + int32 mu, cond; + + mu = runtime·nacl_mutex_create(0); + if(mu < 0) { + runtime·printf("nacl_mutex_create: error %d\n", -mu); + runtime·throw("semacreate"); + } + cond = runtime·nacl_cond_create(0); + if(cond < 0) { + runtime·printf("nacl_cond_create: error %d\n", -cond); + runtime·throw("semacreate"); + } + m->waitsemalock = mu; + return cond; // assigned to m->waitsema +} + +#pragma textflag NOSPLIT +int32 +runtime·semasleep(int64 ns) +{ + int32 ret; + + ret = runtime·nacl_mutex_lock(m->waitsemalock); + if(ret < 0) { + //runtime·printf("nacl_mutex_lock: error %d\n", -ret); + runtime·throw("semasleep"); + } + if(m->waitsemacount > 0) { + m->waitsemacount = 0; + runtime·nacl_mutex_unlock(m->waitsemalock); + return 0; + } + + while(m->waitsemacount == 0) { + if(ns < 0) { + ret = runtime·nacl_cond_wait(m->waitsema, m->waitsemalock); + if(ret < 0) { + //runtime·printf("nacl_cond_wait: error %d\n", -ret); + runtime·throw("semasleep"); + } + } else { + Timespec ts; + + ns += runtime·nanotime(); + ts.tv_sec = runtime·timediv(ns, 1000000000, (int32*)&ts.tv_nsec); + ret = runtime·nacl_cond_timed_wait_abs(m->waitsema, m->waitsemalock, &ts); + if(ret == -ETIMEDOUT) { + runtime·nacl_mutex_unlock(m->waitsemalock); + return -1; + } + if(ret < 0) { + //runtime·printf("nacl_cond_timed_wait_abs: error %d\n", -ret); + runtime·throw("semasleep"); + } + } + } + + m->waitsemacount = 0; + runtime·nacl_mutex_unlock(m->waitsemalock); + return 0; +} + +void +runtime·semawakeup(M *mp) +{ + int32 ret; + + ret = runtime·nacl_mutex_lock(mp->waitsemalock); + if(ret < 0) { + //runtime·printf("nacl_mutex_lock: error %d\n", -ret); + runtime·throw("semawakeup"); + } + if(mp->waitsemacount != 0) { + //runtime·printf("semawakeup: double wakeup\n"); + runtime·throw("semawakeup"); + } + mp->waitsemacount = 1; + runtime·nacl_cond_signal(mp->waitsema); + runtime·nacl_mutex_unlock(mp->waitsemalock); +} + +void +os·sigpipe(void) +{ + runtime·throw("too many writes on closed pipe"); +} + +uintptr +runtime·memlimit(void) +{ + runtime·printf("memlimit\n"); + return 0; +} + +#pragma dataflag NOPTR +static int8 badsignal[] = "runtime: signal received on thread not created by Go.\n"; + +// This runs on a foreign stack, without an m or a g. No stack split. +#pragma textflag NOSPLIT +void +runtime·badsignal2(void) +{ + runtime·write(2, badsignal, sizeof badsignal - 1); + runtime·exit(2); +} + +void runtime·madvise(byte*, uintptr, int32) { } +void runtime·munmap(byte*, uintptr) {} + +void +runtime·resetcpuprofiler(int32 hz) +{ + USED(hz); +} + +void +runtime·sigdisable(uint32) +{ +} + +void +runtime·sigenable(uint32) +{ +} + +void +runtime·closeonexec(int32) +{ +} + +void +runtime·sigpanic(void) +{ + // Native Client only invokes the exception handler for memory faults. + g->sig = SIGSEGV; + if(g->sigpc == 0) + runtime·panicstring("call of nil func value"); + runtime·panicstring("invalid memory address or nil pointer dereference"); +} + +uint32 runtime·writelock; // test-and-set spin lock for runtime.write + +/* +An attempt at IRT. Doesn't work. See end of sys_nacl_amd64.s. + +void (*runtime·nacl_irt_query)(void); + +int8 runtime·nacl_irt_basic_v0_1_str[] = "nacl-irt-basic-0.1"; +void *runtime·nacl_irt_basic_v0_1[6]; // exit, gettod, clock, nanosleep, sched_yield, sysconf +int32 runtime·nacl_irt_basic_v0_1_size = sizeof(runtime·nacl_irt_basic_v0_1); + +int8 runtime·nacl_irt_memory_v0_3_str[] = "nacl-irt-memory-0.3"; +void *runtime·nacl_irt_memory_v0_3[3]; // mmap, munmap, mprotect +int32 runtime·nacl_irt_memory_v0_3_size = sizeof(runtime·nacl_irt_memory_v0_3); + +int8 runtime·nacl_irt_thread_v0_1_str[] = "nacl-irt-thread-0.1"; +void *runtime·nacl_irt_thread_v0_1[3]; // thread_create, thread_exit, thread_nice +int32 runtime·nacl_irt_thread_v0_1_size = sizeof(runtime·nacl_irt_thread_v0_1); +*/
\ No newline at end of file diff --git a/src/pkg/runtime/os_nacl.h b/src/pkg/runtime/os_nacl.h new file mode 100644 index 0000000000..7c9d9c242f --- /dev/null +++ b/src/pkg/runtime/os_nacl.h @@ -0,0 +1,162 @@ +enum { + NSIG = 32, + SI_USER = 1, + + // native_client/src/trusted/service_runtime/include/sys/errno.h + // The errors are mainly copied from Linux. + EPERM = 1, /* Operation not permitted */ + ENOENT = 2, /* No such file or directory */ + ESRCH = 3, /* No such process */ + EINTR = 4, /* Interrupted system call */ + EIO = 5, /* I/O error */ + ENXIO = 6, /* No such device or address */ + E2BIG = 7, /* Argument list too long */ + ENOEXEC = 8, /* Exec format error */ + EBADF = 9, /* Bad file number */ + ECHILD = 10, /* No child processes */ + EAGAIN = 11, /* Try again */ + ENOMEM = 12, /* Out of memory */ + EACCES = 13, /* Permission denied */ + EFAULT = 14, /* Bad address */ + EBUSY = 16, /* Device or resource busy */ + EEXIST = 17, /* File exists */ + EXDEV = 18, /* Cross-device link */ + ENODEV = 19, /* No such device */ + ENOTDIR = 20, /* Not a directory */ + EISDIR = 21, /* Is a directory */ + EINVAL = 22, /* Invalid argument */ + ENFILE = 23, /* File table overflow */ + EMFILE = 24, /* Too many open files */ + ENOTTY = 25, /* Not a typewriter */ + EFBIG = 27, /* File too large */ + ENOSPC = 28, /* No space left on device */ + ESPIPE = 29, /* Illegal seek */ + EROFS = 30, /* Read-only file system */ + EMLINK = 31, /* Too many links */ + EPIPE = 32, /* Broken pipe */ + ENAMETOOLONG = 36, /* File name too long */ + ENOSYS = 38, /* Function not implemented */ + EDQUOT = 122, /* Quota exceeded */ + EDOM = 33, /* Math arg out of domain of func */ + ERANGE = 34, /* Math result not representable */ + EDEADLK = 35, /* Deadlock condition */ + ENOLCK = 37, /* No record locks available */ + ENOTEMPTY = 39, /* Directory not empty */ + ELOOP = 40, /* Too many symbolic links */ + ENOMSG = 42, /* No message of desired type */ + EIDRM = 43, /* Identifier removed */ + ECHRNG = 44, /* Channel number out of range */ + EL2NSYNC = 45, /* Level 2 not synchronized */ + EL3HLT = 46, /* Level 3 halted */ + EL3RST = 47, /* Level 3 reset */ + ELNRNG = 48, /* Link number out of range */ + EUNATCH = 49, /* Protocol driver not attached */ + ENOCSI = 50, /* No CSI structure available */ + EL2HLT = 51, /* Level 2 halted */ + EBADE = 52, /* Invalid exchange */ + EBADR = 53, /* Invalid request descriptor */ + EXFULL = 54, /* Exchange full */ + ENOANO = 55, /* No anode */ + EBADRQC = 56, /* Invalid request code */ + EBADSLT = 57, /* Invalid slot */ + EDEADLOCK = EDEADLK, /* File locking deadlock error */ + EBFONT = 59, /* Bad font file fmt */ + ENOSTR = 60, /* Device not a stream */ + ENODATA = 61, /* No data (for no delay io) */ + ETIME = 62, /* Timer expired */ + ENOSR = 63, /* Out of streams resources */ + ENONET = 64, /* Machine is not on the network */ + ENOPKG = 65, /* Package not installed */ + EREMOTE = 66, /* The object is remote */ + ENOLINK = 67, /* The link has been severed */ + EADV = 68, /* Advertise error */ + ESRMNT = 69, /* Srmount error */ + ECOMM = 70, /* Communication error on send */ + EPROTO = 71, /* Protocol error */ + EMULTIHOP = 72, /* Multihop attempted */ + EDOTDOT = 73, /* Cross mount point (not really error) */ + EBADMSG = 74, /* Trying to read unreadable message */ + EOVERFLOW = 75, /* Value too large for defined data type */ + ENOTUNIQ = 76, /* Given log. name not unique */ + EBADFD = 77, /* f.d. invalid for this operation */ + EREMCHG = 78, /* Remote address changed */ + ELIBACC = 79, /* Can't access a needed shared lib */ + ELIBBAD = 80, /* Accessing a corrupted shared lib */ + ELIBSCN = 81, /* .lib section in a.out corrupted */ + ELIBMAX = 82, /* Attempting to link in too many libs */ + ELIBEXEC = 83, /* Attempting to exec a shared library */ + EILSEQ = 84, + EUSERS = 87, + ENOTSOCK = 88, /* Socket operation on non-socket */ + EDESTADDRREQ = 89, /* Destination address required */ + EMSGSIZE = 90, /* Message too long */ + EPROTOTYPE = 91, /* Protocol wrong type for socket */ + ENOPROTOOPT = 92, /* Protocol not available */ + EPROTONOSUPPORT = 93, /* Unknown protocol */ + ESOCKTNOSUPPORT = 94, /* Socket type not supported */ + EOPNOTSUPP = 95, /* Operation not supported on transport endpoint */ + EPFNOSUPPORT = 96, /* Protocol family not supported */ + EAFNOSUPPORT = 97, /* Address family not supported by protocol family */ + EADDRINUSE = 98, /* Address already in use */ + EADDRNOTAVAIL = 99, /* Address not available */ + ENETDOWN = 100, /* Network interface is not configured */ + ENETUNREACH = 101, /* Network is unreachable */ + ENETRESET = 102, + ECONNABORTED = 103, /* Connection aborted */ + ECONNRESET = 104, /* Connection reset by peer */ + ENOBUFS = 105, /* No buffer space available */ + EISCONN = 106, /* Socket is already connected */ + ENOTCONN = 107, /* Socket is not connected */ + ESHUTDOWN = 108, /* Can't send after socket shutdown */ + ETOOMANYREFS = 109, + ETIMEDOUT = 110, /* Connection timed out */ + ECONNREFUSED = 111, /* Connection refused */ + EHOSTDOWN = 112, /* Host is down */ + EHOSTUNREACH = 113, /* Host is unreachable */ + EALREADY = 114, /* Socket already connected */ + EINPROGRESS = 115, /* Connection already in progress */ + ESTALE = 116, + ENOTSUP = EOPNOTSUPP, /* Not supported */ + ENOMEDIUM = 123, /* No medium (in tape drive) */ + ECANCELED = 125, /* Operation canceled. */ + ELBIN = 2048, /* Inode is remote (not really error) */ + EFTYPE = 2049, /* Inappropriate file type or format */ + ENMFILE = 2050, /* No more files */ + EPROCLIM = 2051, + ENOSHARE = 2052, /* No such host or network path */ + ECASECLASH = 2053, /* Filename exists with different case */ + EWOULDBLOCK = EAGAIN, /* Operation would block */ + + // native_client/src/trusted/service_runtime/include/bits/mman.h. + // NOTE: DO NOT USE native_client/src/shared/imc/nacl_imc_c.h. + // Those MAP_*values are different from these. + PROT_NONE = 0x0, + PROT_READ = 0x1, + PROT_WRITE = 0x2, + PROT_EXEC = 0x4, + + MAP_SHARED = 0x1, + MAP_PRIVATE = 0x2, + MAP_FIXED = 0x10, + MAP_ANON = 0x20, +}; +typedef byte* kevent_udata; + +int32 runtime·nacl_exception_stack(byte*, int32); +int32 runtime·nacl_exception_handler(void*, void*); +int32 runtime·nacl_sem_create(int32); +int32 runtime·nacl_sem_wait(int32); +int32 runtime·nacl_sem_post(int32); +int32 runtime·nacl_mutex_create(int32); +int32 runtime·nacl_mutex_lock(int32); +int32 runtime·nacl_mutex_trylock(int32); +int32 runtime·nacl_mutex_unlock(int32); +int32 runtime·nacl_cond_create(int32); +int32 runtime·nacl_cond_wait(int32, int32); +int32 runtime·nacl_cond_signal(int32); +int32 runtime·nacl_cond_broadcast(int32); +int32 runtime·nacl_cond_timed_wait_abs(int32, int32, Timespec*); +int32 runtime·nacl_thread_create(void*, void*, void*, void*); +int32 runtime·nacl_nanosleep(Timespec*, Timespec*); + +void runtime·sigpanic(void); diff --git a/src/pkg/runtime/runtime.h b/src/pkg/runtime/runtime.h index c9887b6637..0069d5a774 100644 --- a/src/pkg/runtime/runtime.h +++ b/src/pkg/runtime/runtime.h @@ -21,11 +21,19 @@ typedef uint64 uintptr; typedef int64 intptr; typedef int64 intgo; // Go's int typedef uint64 uintgo; // Go's uint +typedef uint64 uintreg; #else typedef uint32 uintptr; typedef int32 intptr; typedef int32 intgo; // Go's int typedef uint32 uintgo; // Go's uint +typedef uint32 uintreg; +#endif + +#ifdef _64BITREG +//typedef uint64 uintreg; +#else +//typedef uint32 uintreg; #endif /* @@ -209,8 +217,8 @@ struct Gobuf uintptr sp; uintptr pc; G* g; - uintptr ret; void* ctxt; + uintreg ret; uintptr lr; }; struct GCStats @@ -295,8 +303,8 @@ struct M // Fields not known to debuggers. uint32 moreframesize; // size arguments to morestack - uint32 moreargsize; - uintptr cret; // return value from C + uint32 moreargsize; // known by amd64 asm to follow moreframesize + uintreg cret; // return value from C uint64 procid; // for debuggers, but offset not hard-coded G* gsignal; // signal-handling G uintptr tls[4]; // thread-local storage (for x86 extern register) @@ -479,6 +487,16 @@ struct Itab void (*fun[])(void); }; +#ifdef GOOS_nacl +enum { + NaCl = 1, +}; +#else +enum { + NaCl = 0, +}; +#endif + #ifdef GOOS_windows enum { Windows = 1 @@ -512,6 +530,8 @@ struct Timers // Package time knows the layout of this structure. // If this struct changes, adjust ../time/sleep.go:/runtimeTimer. +// For GOOS=nacl, package syscall knows the layout of this structure. +// If this struct changes, adjust ../syscall/net_nacl.go:/runtimeTimer. struct Timer { int32 i; // heap index @@ -588,7 +608,7 @@ extern bool runtime·precisestack; * known to compiler */ enum { - Structrnd = sizeof(uintptr) + Structrnd = sizeof(uintreg), }; /* @@ -762,6 +782,7 @@ void runtime·dump(byte*, int32); int32 runtime·runetochar(byte*, int32); int32 runtime·charntorune(int32*, uint8*, int32); + /* * This macro is used when writing C functions * called as if they were Go functions. @@ -774,8 +795,6 @@ int32 runtime·charntorune(int32*, uint8*, int32); * first output value. Almost all code should write such * functions in .goc files, where goc2c (part of cmd/dist) * can arrange the correct alignment for the target system. - * Goc2c also takes care of conveying to the garbage collector - * which parts of the argument list are input vs outputs. * * Therefore, do NOT use this macro if at all possible. */ @@ -926,6 +945,7 @@ void runtime·parsedebugvars(void); void _rt0_go(void); void* runtime·funcdata(Func*, int32); int32 runtime·setmaxthreads(int32); +G* runtime·timejump(void); #pragma varargck argpos runtime·printf 1 #pragma varargck type "c" int32 @@ -1017,13 +1037,6 @@ void runtime·parfordo(ParFor *desc); void runtime·parforiters(ParFor*, uintptr, uintptr*, uintptr*); /* - * This is consistent across Linux and BSD. - * If a new OS is added that is different, move this to - * $GOOS/$GOARCH/defs.h. - */ -#define EACCES 13 - -/* * low level C-called */ // for mmap, we only pass the lower 32 bits of file offset to the @@ -1057,6 +1070,7 @@ void reflect·call(FuncVal*, byte*, uint32); void runtime·panic(Eface); void runtime·panicindex(void); void runtime·panicslice(void); +void runtime·panicdivide(void); /* * runtime c-called (but written in Go) diff --git a/src/pkg/runtime/signal_386.c b/src/pkg/runtime/signal_386.c index 553ea87e49..9f3f52179c 100644 --- a/src/pkg/runtime/signal_386.c +++ b/src/pkg/runtime/signal_386.c @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -// +build darwin dragonfly freebsd linux netbsd openbsd +// +build darwin dragonfly freebsd linux nacl netbsd openbsd #include "runtime.h" #include "defs_GOOS_GOARCH.h" diff --git a/src/pkg/runtime/signal_nacl_386.h b/src/pkg/runtime/signal_nacl_386.h new file mode 100644 index 0000000000..c9481b5f4f --- /dev/null +++ b/src/pkg/runtime/signal_nacl_386.h @@ -0,0 +1,23 @@ +// 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. + +#define SIG_REGS(ctxt) (((ExcContext*)(ctxt))->regs) + +#define SIG_EAX(info, ctxt) (SIG_REGS(ctxt).eax) +#define SIG_EBX(info, ctxt) (SIG_REGS(ctxt).ebx) +#define SIG_ECX(info, ctxt) (SIG_REGS(ctxt).ecx) +#define SIG_EDX(info, ctxt) (SIG_REGS(ctxt).edx) +#define SIG_EDI(info, ctxt) (SIG_REGS(ctxt).edi) +#define SIG_ESI(info, ctxt) (SIG_REGS(ctxt).esi) +#define SIG_EBP(info, ctxt) (SIG_REGS(ctxt).ebp) +#define SIG_ESP(info, ctxt) (SIG_REGS(ctxt).esp) +#define SIG_EIP(info, ctxt) (SIG_REGS(ctxt).eip) +#define SIG_EFLAGS(info, ctxt) (SIG_REGS(ctxt).eflags) + +#define SIG_CS(info, ctxt) (~0) +#define SIG_FS(info, ctxt) (~0) +#define SIG_GS(info, ctxt) (~0) + +#define SIG_CODE0(info, ctxt) (~0) +#define SIG_CODE1(info, ctxt) (0) diff --git a/src/pkg/runtime/signal_nacl_amd64p32.h b/src/pkg/runtime/signal_nacl_amd64p32.h new file mode 100644 index 0000000000..c58593a291 --- /dev/null +++ b/src/pkg/runtime/signal_nacl_amd64p32.h @@ -0,0 +1,31 @@ +// Copyright 2013 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +#define SIG_REGS(ctxt) (((ExcContext*)(ctxt))->regs64) + +#define SIG_RAX(info, ctxt) (SIG_REGS(ctxt).rax) +#define SIG_RBX(info, ctxt) (SIG_REGS(ctxt).rbx) +#define SIG_RCX(info, ctxt) (SIG_REGS(ctxt).rcx) +#define SIG_RDX(info, ctxt) (SIG_REGS(ctxt).rdx) +#define SIG_RDI(info, ctxt) (SIG_REGS(ctxt).rdi) +#define SIG_RSI(info, ctxt) (SIG_REGS(ctxt).rsi) +#define SIG_RBP(info, ctxt) (SIG_REGS(ctxt).rbp) +#define SIG_RSP(info, ctxt) (SIG_REGS(ctxt).rsp) +#define SIG_R8(info, ctxt) (SIG_REGS(ctxt).r8) +#define SIG_R9(info, ctxt) (SIG_REGS(ctxt).r9) +#define SIG_R10(info, ctxt) (SIG_REGS(ctxt).r10) +#define SIG_R11(info, ctxt) (SIG_REGS(ctxt).r11) +#define SIG_R12(info, ctxt) (SIG_REGS(ctxt).r12) +#define SIG_R13(info, ctxt) (SIG_REGS(ctxt).r13) +#define SIG_R14(info, ctxt) (SIG_REGS(ctxt).r14) +#define SIG_R15(info, ctxt) (SIG_REGS(ctxt).r15) +#define SIG_RIP(info, ctxt) (SIG_REGS(ctxt).rip) +#define SIG_RFLAGS(info, ctxt) (SIG_REGS(ctxt).rflags) + +#define SIG_CS(info, ctxt) (~0) +#define SIG_FS(info, ctxt) (~0) +#define SIG_GS(info, ctxt) (~0) + +#define SIG_CODE0(info, ctxt) (~0) +#define SIG_CODE1(info, ctxt) (0) diff --git a/src/pkg/runtime/signals_nacl.h b/src/pkg/runtime/signals_nacl.h new file mode 100644 index 0000000000..229b585902 --- /dev/null +++ b/src/pkg/runtime/signals_nacl.h @@ -0,0 +1,50 @@ +// 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. + +#define N SigNotify +#define K SigKill +#define T SigThrow +#define P SigPanic +#define D SigDefault + +SigTab runtime·sigtab[] = { + /* 0 */ 0, "SIGNONE: no trap", + /* 1 */ N+K, "SIGHUP: terminal line hangup", + /* 2 */ N+K, "SIGINT: interrupt", + /* 3 */ N+T, "SIGQUIT: quit", + /* 4 */ T, "SIGILL: illegal instruction", + /* 5 */ T, "SIGTRAP: trace trap", + /* 6 */ N+T, "SIGABRT: abort", + /* 7 */ T, "SIGEMT: emulate instruction executed", + /* 8 */ P, "SIGFPE: floating-point exception", + /* 9 */ 0, "SIGKILL: kill", + /* 10 */ P, "SIGBUS: bus error", + /* 11 */ P, "SIGSEGV: segmentation violation", + /* 12 */ T, "SIGSYS: bad system call", + /* 13 */ N, "SIGPIPE: write to broken pipe", + /* 14 */ N, "SIGALRM: alarm clock", + /* 15 */ N+K, "SIGTERM: termination", + /* 16 */ N, "SIGURG: urgent condition on socket", + /* 17 */ 0, "SIGSTOP: stop", + /* 18 */ N+D, "SIGTSTP: keyboard stop", + /* 19 */ 0, "SIGCONT: continue after stop", + /* 20 */ N, "SIGCHLD: child status has changed", + /* 21 */ N+D, "SIGTTIN: background read from tty", + /* 22 */ N+D, "SIGTTOU: background write to tty", + /* 23 */ N, "SIGIO: i/o now possible", + /* 24 */ N, "SIGXCPU: cpu limit exceeded", + /* 25 */ N, "SIGXFSZ: file size limit exceeded", + /* 26 */ N, "SIGVTALRM: virtual alarm clock", + /* 27 */ N, "SIGPROF: profiling alarm clock", + /* 28 */ N, "SIGWINCH: window size change", + /* 29 */ N, "SIGINFO: status request from keyboard", + /* 30 */ N, "SIGUSR1: user-defined signal 1", + /* 31 */ N, "SIGUSR2: user-defined signal 2", +}; + +#undef N +#undef K +#undef T +#undef P +#undef D diff --git a/src/pkg/runtime/sys_x86.c b/src/pkg/runtime/sys_x86.c index f24337eac7..a450b3e584 100644 --- a/src/pkg/runtime/sys_x86.c +++ b/src/pkg/runtime/sys_x86.c @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -// +build amd64 386 +// +build amd64 amd64p32 386 #include "runtime.h" @@ -14,6 +14,8 @@ runtime·gostartcall(Gobuf *gobuf, void (*fn)(void), void *ctxt) uintptr *sp; sp = (uintptr*)gobuf->sp; + if(sizeof(uintreg) > sizeof(uintptr)) + *--sp = 0; *--sp = (uintptr)gobuf->pc; gobuf->sp = (uintptr)sp; gobuf->pc = (uintptr)fn; diff --git a/src/pkg/runtime/syscall_nacl.h b/src/pkg/runtime/syscall_nacl.h new file mode 100644 index 0000000000..b33852ec8d --- /dev/null +++ b/src/pkg/runtime/syscall_nacl.h @@ -0,0 +1,71 @@ +// generated by mknacl.sh - do not edit +#define SYS_null 1 +#define SYS_nameservice 2 +#define SYS_dup 8 +#define SYS_dup2 9 +#define SYS_open 10 +#define SYS_close 11 +#define SYS_read 12 +#define SYS_write 13 +#define SYS_lseek 14 +#define SYS_ioctl 15 +#define SYS_stat 16 +#define SYS_fstat 17 +#define SYS_chmod 18 +#define SYS_brk 20 +#define SYS_mmap 21 +#define SYS_munmap 22 +#define SYS_getdents 23 +#define SYS_mprotect 24 +#define SYS_list_mappings 25 +#define SYS_exit 30 +#define SYS_getpid 31 +#define SYS_sched_yield 32 +#define SYS_sysconf 33 +#define SYS_gettimeofday 40 +#define SYS_clock 41 +#define SYS_nanosleep 42 +#define SYS_clock_getres 43 +#define SYS_clock_gettime 44 +#define SYS_mkdir 45 +#define SYS_rmdir 46 +#define SYS_chdir 47 +#define SYS_getcwd 48 +#define SYS_unlink 49 +#define SYS_imc_makeboundsock 60 +#define SYS_imc_accept 61 +#define SYS_imc_connect 62 +#define SYS_imc_sendmsg 63 +#define SYS_imc_recvmsg 64 +#define SYS_imc_mem_obj_create 65 +#define SYS_imc_socketpair 66 +#define SYS_mutex_create 70 +#define SYS_mutex_lock 71 +#define SYS_mutex_trylock 72 +#define SYS_mutex_unlock 73 +#define SYS_cond_create 74 +#define SYS_cond_wait 75 +#define SYS_cond_signal 76 +#define SYS_cond_broadcast 77 +#define SYS_cond_timed_wait_abs 79 +#define SYS_thread_create 80 +#define SYS_thread_exit 81 +#define SYS_tls_init 82 +#define SYS_thread_nice 83 +#define SYS_tls_get 84 +#define SYS_second_tls_set 85 +#define SYS_second_tls_get 86 +#define SYS_exception_handler 87 +#define SYS_exception_stack 88 +#define SYS_exception_clear_flag 89 +#define SYS_sem_create 100 +#define SYS_sem_wait 101 +#define SYS_sem_post 102 +#define SYS_sem_get_value 103 +#define SYS_dyncode_create 104 +#define SYS_dyncode_modify 105 +#define SYS_dyncode_delete 106 +#define SYS_test_infoleak 109 +#define SYS_test_crash 110 +#define SYS_test_syscall_1 111 +#define SYS_test_syscall_2 112 diff --git a/src/pkg/runtime/traceback_x86.c b/src/pkg/runtime/traceback_x86.c index fa46d547a8..bd431be224 100644 --- a/src/pkg/runtime/traceback_x86.c +++ b/src/pkg/runtime/traceback_x86.c @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -// +build amd64 386 +// +build amd64 amd64p32 386 #include "runtime.h" #include "arch_GOARCH.h" @@ -52,7 +52,7 @@ runtime·gentraceback(uintptr pc0, uintptr sp0, uintptr lr0, G *gp, int32 skip, // Start in the caller's frame. if(frame.pc == 0) { frame.pc = *(uintptr*)frame.sp; - frame.sp += sizeof(uintptr); + frame.sp += sizeof(uintreg); } f = runtime·findfunc(frame.pc); @@ -101,14 +101,14 @@ runtime·gentraceback(uintptr pc0, uintptr sp0, uintptr lr0, G *gp, int32 skip, // Derive frame pointer and link register. if(frame.fp == 0) { frame.fp = frame.sp + runtime·funcspdelta(f, frame.pc); - frame.fp += sizeof(uintptr); // caller PC + frame.fp += sizeof(uintreg); // caller PC } if(runtime·topofstack(f)) { frame.lr = 0; flr = nil; } else { if(frame.lr == 0) - frame.lr = ((uintptr*)frame.fp)[-1]; + frame.lr = ((uintreg*)frame.fp)[-1]; flr = runtime·findfunc(frame.lr); if(flr == nil) { runtime·printf("runtime: unexpected return pc for %s called from %p\n", runtime·funcname(f), frame.lr); @@ -117,7 +117,7 @@ runtime·gentraceback(uintptr pc0, uintptr sp0, uintptr lr0, G *gp, int32 skip, } } - frame.varp = (byte*)frame.fp - sizeof(uintptr); + frame.varp = (byte*)frame.fp - sizeof(uintreg); // Derive size of arguments. // Most functions have a fixed-size argument block, diff --git a/src/pkg/runtime/vlrt_386.c b/src/pkg/runtime/vlrt_386.c index 8d965c086e..ace1beb4cc 100644 --- a/src/pkg/runtime/vlrt_386.c +++ b/src/pkg/runtime/vlrt_386.c @@ -32,6 +32,8 @@ * to generate the code directly now. Find and remove. */ +extern void runtime·panicdivide(void); + typedef unsigned long ulong; typedef unsigned int uint; typedef unsigned short ushort; @@ -240,6 +242,8 @@ dodiv(Vlong num, Vlong den, Vlong *qp, Vlong *rp) } } else { if(num.hi >= den.lo){ + if(den.lo == 0) + runtime·panicdivide(); q.hi = n = num.hi/den.lo; num.hi -= den.lo*n; } else { @@ -263,6 +267,8 @@ _divvu(Vlong *q, Vlong n, Vlong d) { if(n.hi == 0 && d.hi == 0) { + if(d.lo == 0) + runtime·panicdivide(); q->hi = 0; q->lo = n.lo / d.lo; return; @@ -281,6 +287,8 @@ _modvu(Vlong *r, Vlong n, Vlong d) { if(n.hi == 0 && d.hi == 0) { + if(d.lo == 0) + runtime·panicdivide(); r->hi = 0; r->lo = n.lo % d.lo; return; @@ -319,6 +327,8 @@ _divv(Vlong *q, Vlong n, Vlong d) q->hi = 0; return; } + if(d.lo == 0) + runtime·panicdivide(); q->lo = (long)n.lo / (long)d.lo; q->hi = ((long)q->lo) >> 31; return; @@ -353,6 +363,8 @@ _modv(Vlong *r, Vlong n, Vlong d) r->hi = 0; return; } + if(d.lo == 0) + runtime·panicdivide(); r->lo = (long)n.lo % (long)d.lo; r->hi = ((long)r->lo) >> 31; return; diff --git a/src/pkg/runtime/vlrt_arm.c b/src/pkg/runtime/vlrt_arm.c index 219163c60f..9606e16076 100644 --- a/src/pkg/runtime/vlrt_arm.c +++ b/src/pkg/runtime/vlrt_arm.c @@ -36,12 +36,6 @@ typedef signed char schar; #define SIGN(n) (1UL<<(n-1)) -void -runtime·panicdivide(void) -{ - runtime·panicstring("integer divide by zero"); -} - typedef struct Vlong Vlong; struct Vlong { |
