]> Cypherpunks repositories - gostls13.git/commitdiff
[dev.cc] runtime: convert Solaris port to Go
authorAram Hăvărneanu <aram@mgk.ro>
Thu, 13 Nov 2014 15:07:10 +0000 (16:07 +0100)
committerAram Hăvărneanu <aram@mgk.ro>
Thu, 13 Nov 2014 15:07:10 +0000 (16:07 +0100)
Memory management was consolitated with the BSD ports, since
it was almost identical.

Assembly thunks are gone, being replaced by the new //go:linkname
feature.

This change supersedes CL 138390043 (runtime: convert solaris
netpoll to Go), which was previously reviewed and tested.

This change is only the first step, the port now builds,
but doesn't run. Binaries fail to exec:

    ld.so.1: 6.out: fatal: 6.out: TLS requirement failure : TLS support is unavailable
    Killed

This seems to happen because binaries don't link with libc.so
anymore. We will have to solve that in a different CL.

Also this change is just a rough translation of the original
C code, cleanup will come in a different CL.

[This CL is part of the removal of C code from package runtime.
See golang.org/s/dev.cc for an overview.]

LGTM=rsc
R=rsc, dave
CC=golang-codereviews, iant, khr, minux, r, rlh
https://golang.org/cl/174960043

22 files changed:
src/liblink/asm6.c
src/runtime/defs1_solaris_amd64.go
src/runtime/mem_bsd.go
src/runtime/mem_solaris.c [deleted file]
src/runtime/netpoll.go
src/runtime/netpoll_solaris.go [moved from src/runtime/netpoll_solaris.c with 55% similarity]
src/runtime/os2_solaris.go [new file with mode: 0644]
src/runtime/os3_solaris.go [new file with mode: 0644]
src/runtime/os_solaris.c [deleted file]
src/runtime/os_solaris.go
src/runtime/os_solaris.h [deleted file]
src/runtime/signal_solaris.go [new file with mode: 0644]
src/runtime/signal_solaris_amd64.go [new file with mode: 0644]
src/runtime/signal_solaris_amd64.h [deleted file]
src/runtime/signals_solaris.h [deleted file]
src/runtime/stubs.go
src/runtime/stubs2.go [new file with mode: 0644]
src/runtime/sys_solaris_amd64.s
src/runtime/syscall2_solaris.go [new file with mode: 0644]
src/runtime/syscall_solaris.c [deleted file]
src/runtime/syscall_solaris.go
src/runtime/thunk_solaris_amd64.s [deleted file]

index 428eb9442bff8f343dee3343f9a98ec42494881e..7971022b56b399f61ecad0ad05922ac8e3fda597 100644 (file)
@@ -1543,9 +1543,8 @@ static vlong      vaddr(Link*, Addr*, Reloc*);
 static int
 isextern(LSym *s)
 {
-       // All the Solaris dynamic imports from libc.so begin with "libc·", which
-       // the compiler rewrites to "libc." by the time liblink gets it.
-       return strncmp(s->name, "libc.", 5) == 0;
+       // All the Solaris dynamic imports from libc.so begin with "libc_".
+       return strncmp(s->name, "libc_", 5) == 0;
 }
 
 // single-instruction no-ops of various lengths.
index 280cf815f9b615a265e526111d8f1fe96bf82241..3bb6f69bf4350b2bc4b38541ade0a873195b4af9 100644 (file)
@@ -172,6 +172,10 @@ type timeval struct {
        tv_usec int64
 }
 
+func (tv *timeval) set_usec(x int32) {
+       tv.tv_usec = int64(x)
+}
+
 type itimerval struct {
        it_interval timeval
        it_value    timeval
@@ -185,6 +189,7 @@ type portevent struct {
        portev_user   *byte
 }
 
+type pthread uint32
 type pthreadattr struct {
        __pthread_attrp *byte
 }
index fffb350ed10459112e4a063a7e1b065854f59459..4bd40a39fcb2859c77f0ec84f977b14ea5adf823 100644 (file)
@@ -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 dragonfly freebsd netbsd openbsd
+// +build dragonfly freebsd netbsd openbsd solaris
 
 package runtime
 
diff --git a/src/runtime/mem_solaris.c b/src/runtime/mem_solaris.c
deleted file mode 100644 (file)
index 8e90ba1..0000000
+++ /dev/null
@@ -1,101 +0,0 @@
-// 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"
-#include "textflag.h"
-
-enum
-{
-       ENOMEM = 12,
-};
-
-#pragma textflag NOSPLIT
-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)
-               return nil;
-       runtime·xadd64(stat, n);
-       return v;
-}
-
-void
-runtime·SysUnused(void *v, uintptr n)
-{
-       USED(v);
-       USED(n);
-}
-
-void
-runtime·SysUsed(void *v, uintptr n)
-{
-       USED(v);
-       USED(n);
-}
-
-void
-runtime·SysFree(void *v, uintptr n, uint64 *stat)
-{
-       runtime·xadd64(stat, -(uint64)n);
-       runtime·munmap(v, n);
-}
-
-void
-runtime·SysFault(void *v, uintptr n)
-{
-       runtime·mmap(v, n, PROT_NONE, MAP_ANON|MAP_PRIVATE|MAP_FIXED, -1, 0);
-}
-
-void*
-runtime·SysReserve(void *v, uintptr n, bool *reserved)
-{
-       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(sizeof(void*) == 8 && n > 1LL<<32) {
-               *reserved = false;
-               return v;
-       }
-       
-       p = runtime·mmap(v, n, PROT_NONE, MAP_ANON|MAP_PRIVATE, -1, 0);
-       if(p < (void*)4096)
-               return nil;
-       *reserved = true;
-       return p;
-}
-
-void
-runtime·SysMap(void *v, uintptr n, bool reserved, uint64 *stat)
-{
-       void *p;
-       
-       runtime·xadd64(stat, n);
-
-       // On 64-bit, we don't actually have v reserved, so tread carefully.
-       if(!reserved) {
-               p = runtime·mmap(v, n, PROT_READ|PROT_WRITE, MAP_ANON|MAP_PRIVATE, -1, 0);
-               if(p == (void*)ENOMEM)
-                       runtime·throw("runtime: out of memory");
-               if(p != v) {
-                       runtime·printf("runtime: address space conflict: map(%p) = %p\n", v, p);
-                       runtime·throw("runtime: address space conflict");
-               }
-               return;
-       }
-
-       p = runtime·mmap(v, n, PROT_READ|PROT_WRITE, MAP_ANON|MAP_FIXED|MAP_PRIVATE, -1, 0);
-       if(p == (void*)ENOMEM)
-               runtime·throw("runtime: out of memory");
-       if(p != v)
-               runtime·throw("runtime: cannot map pages in arena address space");
-}
index dd00b2a96d495e64f7544e34a5b0d638f6d990d4..7a99f18ad214e0a6300fb11995ff346e982805b2 100644 (file)
@@ -49,14 +49,14 @@ type pollDesc struct {
        lock    mutex // protectes the following fields
        fd      uintptr
        closing bool
-       seq     uintptr        // protects from stale timers and ready notifications
-       rg      uintptr        // pdReady, pdWait, G waiting for read or nil
-       rt      timer          // read deadline timer (set if rt.f != nil)
-       rd      int64          // read deadline
-       wg      uintptr        // pdReady, pdWait, G waiting for write or nil
-       wt      timer          // write deadline timer
-       wd      int64          // write deadline
-       user    unsafe.Pointer // user settable cookie
+       seq     uintptr // protects from stale timers and ready notifications
+       rg      uintptr // pdReady, pdWait, G waiting for read or nil
+       rt      timer   // read deadline timer (set if rt.f != nil)
+       rd      int64   // read deadline
+       wg      uintptr // pdReady, pdWait, G waiting for write or nil
+       wt      timer   // write deadline timer
+       wd      int64   // write deadline
+       user    uint32  // user settable cookie
 }
 
 type pollCache struct {
@@ -72,7 +72,7 @@ type pollCache struct {
 var pollcache pollCache
 
 func netpollServerInit() {
-       systemstack(netpollinit)
+       netpollinit()
 }
 
 func netpollOpen(fd uintptr) (*pollDesc, int) {
@@ -94,9 +94,7 @@ func netpollOpen(fd uintptr) (*pollDesc, int) {
        unlock(&pd.lock)
 
        var errno int32
-       systemstack(func() {
-               errno = netpollopen(fd, pd)
-       })
+       errno = netpollopen(fd, pd)
        return pd, int(errno)
 }
 
@@ -110,9 +108,7 @@ func netpollClose(pd *pollDesc) {
        if pd.rg != 0 && pd.rg != pdReady {
                gothrow("netpollClose: blocked read on closing descriptor")
        }
-       systemstack(func() {
-               netpollclose(uintptr(pd.fd))
-       })
+       netpollclose(uintptr(pd.fd))
        pollcache.free(pd)
 }
 
@@ -143,9 +139,7 @@ func netpollWait(pd *pollDesc, mode int) int {
        }
        // As for now only Solaris uses level-triggered IO.
        if GOOS == "solaris" {
-               systemstack(func() {
-                       netpollarm(pd, mode)
-               })
+               netpollarm(pd, mode)
        }
        for !netpollblock(pd, int32(mode), false) {
                err = netpollcheckerr(pd, int32(mode))
@@ -263,26 +257,6 @@ func netpollUnblock(pd *pollDesc) {
        }
 }
 
-func netpollfd(pd *pollDesc) uintptr {
-       return pd.fd
-}
-
-func netpolluser(pd *pollDesc) *unsafe.Pointer {
-       return &pd.user
-}
-
-func netpollclosing(pd *pollDesc) bool {
-       return pd.closing
-}
-
-func netpolllock(pd *pollDesc) {
-       lock(&pd.lock)
-}
-
-func netpollunlock(pd *pollDesc) {
-       unlock(&pd.lock)
-}
-
 // make pd ready, newly runnable goroutines (if any) are returned in rg/wg
 func netpollready(gpp **g, pd *pollDesc, mode int32) {
        var rg, wg *g
similarity index 55%
rename from src/runtime/netpoll_solaris.c
rename to src/runtime/netpoll_solaris.go
index d422719cf1abe9b0f05acf0ce6241b46a296637b..40e8a1a6516dacddf5cc4a9cef47d39bda349dab 100644 (file)
@@ -2,13 +2,12 @@
 // 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"
+package runtime
+
+import "unsafe"
 
 // Solaris runtime-integrated network poller.
-// 
+//
 // Solaris uses event ports for scalable network I/O. Event
 // ports are level-triggered, unlike epoll and kqueue which
 // can be configured in both level-triggered and edge-triggered
@@ -18,7 +17,7 @@
 // events for that descriptor. When doing this we must keep track of
 // what kind of events the goroutines are currently interested in,
 // for example a fd may be open both for reading and writing.
-// 
+//
 // A description of the high level operation of this code
 // follows. Networking code will get a file descriptor by some means
 // and will register it with the netpolling mechanism by a code path
@@ -29,7 +28,7 @@
 // readiness notification at some point in the future. If I/O becomes
 // ready when nobody is listening, when we finally care about it,
 // nobody will tell us anymore.
-// 
+//
 // Beside calling runtime·netpollopen, the networking code paths
 // will call runtime·netpollarm each time goroutines are interested
 // in doing network I/O. Because now we know what kind of I/O we
@@ -39,7 +38,7 @@
 // when we now call port_associate, we will unblock the main poller
 // loop (in runtime·netpoll) right away if the socket is actually
 // ready for I/O.
-// 
+//
 // The main poller loop runs in its own thread waiting for events
 // using port_getn. When an event happens, it will tell the scheduler
 // about it using runtime·netpollready. Besides doing this, it must
@@ -47,7 +46,7 @@
 // notification with the file descriptor. Failing to do this would
 // mean each notification will prevent concurrent code using the
 // same file descriptor in parallel.
-// 
+//
 // The logic dealing with re-associations is encapsulated in
 // runtime·netpollupdate. This function takes care to associate the
 // descriptor only with the subset of events that were previously
@@ -56,7 +55,7 @@
 // are level triggered so it would cause a busy loop. Instead, that
 // association is effected only by the runtime·netpollarm code path,
 // when Go code actually asks for I/O.
-// 
+//
 // The open and arming mechanisms are serialized using the lock
 // inside PollDesc. This is required because the netpoll loop runs
 // asynchonously in respect to other Go code and by the time we get
 // again we know for sure we are always talking about the same file
 // descriptor and can safely access the data we want (the event set).
 
-#pragma dynimport libc·fcntl fcntl "libc.so"
-#pragma dynimport libc·port_create port_create "libc.so"
-#pragma dynimport libc·port_associate port_associate "libc.so"
-#pragma dynimport libc·port_dissociate port_dissociate "libc.so"
-#pragma dynimport libc·port_getn port_getn "libc.so"
-extern uintptr libc·fcntl;
-extern uintptr libc·port_create;
-extern uintptr libc·port_associate;
-extern uintptr libc·port_dissociate;
-extern uintptr libc·port_getn;
-
-#define errno (*g->m->perrno)
+//go:cgo_import_dynamic libc_port_create port_create "libc.so"
+//go:cgo_import_dynamic libc_port_associate port_associate "libc.so"
+//go:cgo_import_dynamic libc_port_dissociate port_dissociate "libc.so"
+//go:cgo_import_dynamic libc_port_getn port_getn "libc.so"
+
+//go:linkname libc_port_create libc_port_create
+//go:linkname libc_port_associate libc_port_associate
+//go:linkname libc_port_dissociate libc_port_dissociate
+//go:linkname libc_port_getn libc_port_getn
+
+var (
+       libc_port_create,
+       libc_port_associate,
+       libc_port_dissociate,
+       libc_port_getn libcFunc
+)
+
+func errno() int32 {
+       return *getg().m.perrno
+}
 
-int32
-runtime·fcntl(int32 fd, int32 cmd, uintptr arg)
-{
-       return runtime·sysvicall3(libc·fcntl, (uintptr)fd, (uintptr)cmd, (uintptr)arg);
+func fcntl(fd, cmd int32, arg uintptr) int32 {
+       return int32(sysvicall3(libc_fcntl, uintptr(fd), uintptr(cmd), arg))
 }
 
-int32
-runtime·port_create(void)
-{
-       return runtime·sysvicall0(libc·port_create);
+func port_create() int32 {
+       return int32(sysvicall0(libc_port_create))
 }
 
-int32
-runtime·port_associate(int32 port, int32 source, uintptr object, int32 events, uintptr user)
-{
-       return runtime·sysvicall5(libc·port_associate, (uintptr)port, (uintptr)source, object, (uintptr)events, user);
+func port_associate(port, source int32, object uintptr, events uint32, user uintptr) int32 {
+       return int32(sysvicall5(libc_port_associate, uintptr(port), uintptr(source), object, uintptr(events), user))
 }
 
-int32
-runtime·port_dissociate(int32 port, int32 source, uintptr object)
-{
-       return runtime·sysvicall3(libc·port_dissociate, (uintptr)port, (uintptr)source, object);
+func port_dissociate(port, source int32, object uintptr) int32 {
+       return int32(sysvicall3(libc_port_dissociate, uintptr(port), uintptr(source), object))
 }
 
-int32
-runtime·port_getn(int32 port, PortEvent *evs, uint32 max, uint32 *nget, Timespec *timeout)
-{
-       return runtime·sysvicall5(libc·port_getn, (uintptr)port, (uintptr)evs, (uintptr)max, (uintptr)nget, (uintptr)timeout);
+func port_getn(port int32, evs *portevent, max uint32, nget *uint32, timeout *timespec) int32 {
+       return int32(sysvicall5(libc_port_getn, uintptr(port), uintptr(unsafe.Pointer(evs)), uintptr(max), uintptr(unsafe.Pointer(nget)), uintptr(unsafe.Pointer(timeout))))
 }
 
-static int32 portfd = -1;
+var portfd int32 = -1
 
-void
-runtime·netpollinit(void)
-{
-       if((portfd = runtime·port_create()) >= 0) {
-               runtime·fcntl(portfd, F_SETFD, FD_CLOEXEC);
-               return;
+func netpollinit() {
+       portfd = port_create()
+       if portfd >= 0 {
+               fcntl(portfd, _F_SETFD, _FD_CLOEXEC)
+               return
        }
 
-       runtime·printf("netpollinit: failed to create port (%d)\n", errno);
-       runtime·throw("netpollinit: failed to create port");
+       print("netpollinit: failed to create port (", errno(), ")\n")
+       gothrow("netpollinit: failed to create port")
 }
 
-int32
-runtime·netpollopen(uintptr fd, PollDesc *pd)
-{
-       int32 r;
-
-       runtime·netpolllock(pd);
+func netpollopen(fd uintptr, pd *pollDesc) int32 {
+       lock(&pd.lock)
        // We don't register for any specific type of events yet, that's
        // netpollarm's job. We merely ensure we call port_associate before
        // asynchonous connect/accept completes, so when we actually want
        // to do any I/O, the call to port_associate (from netpollarm,
        // with the interested event set) will unblock port_getn right away
        // because of the I/O readiness notification.
-       *runtime·netpolluser(pd) = 0;
-       r = runtime·port_associate(portfd, PORT_SOURCE_FD, fd, 0, (uintptr)pd);
-       runtime·netpollunlock(pd);
-       return r;
+       pd.user = 0
+       r := port_associate(portfd, _PORT_SOURCE_FD, fd, 0, uintptr(unsafe.Pointer(pd)))
+       unlock(&pd.lock)
+       return r
 }
 
-int32
-runtime·netpollclose(uintptr fd)
-{
-       return runtime·port_dissociate(portfd, PORT_SOURCE_FD, fd);
+func netpollclose(fd uintptr) int32 {
+       return port_dissociate(portfd, _PORT_SOURCE_FD, fd)
 }
 
 // Updates the association with a new set of interested events. After
 // this call, port_getn will return one and only one event for that
 // particular descriptor, so this function needs to be called again.
-void
-runtime·netpollupdate(PollDesc* pd, uint32 set, uint32 clear)
-{
-       uint32 *ep, old, events;
-       uintptr fd = runtime·netpollfd(pd);
-       ep = (uint32*)runtime·netpolluser(pd);
-
-       if(runtime·netpollclosing(pd))
-               return;
+func netpollupdate(pd *pollDesc, set, clear uint32) {
+       if pd.closing {
+               return
+       }
 
-       old = *ep;
-       events = (old & ~clear) | set;
-       if(old == events)
-               return;
+       old := pd.user
+       events := (old & ^clear) | set
+       if old == events {
+               return
+       }
 
-       if(events && runtime·port_associate(portfd, PORT_SOURCE_FD, fd, events, (uintptr)pd) != 0) {
-               runtime·printf("netpollupdate: failed to associate (%d)\n", errno);
-               runtime·throw("netpollupdate: failed to associate");
-       } 
-       *ep = events;
+       if events != 0 && port_associate(portfd, _PORT_SOURCE_FD, pd.fd, events, uintptr(unsafe.Pointer(pd))) != 0 {
+               print("netpollupdate: failed to associate (", errno(), ")\n")
+               gothrow("netpollupdate: failed to associate")
+       }
+       pd.user = events
 }
 
 // subscribe the fd to the port such that port_getn will return one event.
-void
-runtime·netpollarm(PollDesc* pd, int32 mode)
-{
-       runtime·netpolllock(pd);
-       switch(mode) {
+func netpollarm(pd *pollDesc, mode int) {
+       lock(&pd.lock)
+       switch mode {
        case 'r':
-               runtime·netpollupdate(pd, POLLIN, 0);
-               break;
+               netpollupdate(pd, _POLLIN, 0)
        case 'w':
-               runtime·netpollupdate(pd, POLLOUT, 0);
-               break;
+               netpollupdate(pd, _POLLOUT, 0)
        default:
-               runtime·throw("netpollarm: bad mode");
+               gothrow("netpollarm: bad mode")
        }
-       runtime·netpollunlock(pd);
+       unlock(&pd.lock)
 }
 
+// netpolllasterr holds the last error code returned by port_getn to prevent log spamming
+var netpolllasterr int32
+
 // polls for ready network connections
 // returns list of goroutines that become runnable
-G*
-runtime·netpoll(bool block)
-{
-       static int32 lasterr;
-       PortEvent events[128], *ev;
-       PollDesc *pd;
-       int32 i, mode, clear;
-       uint32 n;
-       Timespec *wait = nil, zero;
-       G *gp;
-
-       if(portfd == -1)
-               return (nil);
+func netpoll(block bool) (gp *g) {
+       if portfd == -1 {
+               return
+       }
 
-       if(!block) {
-               zero.tv_sec = 0;
-               zero.tv_nsec = 0;
-               wait = &zero;
+       var wait *timespec
+       var zero timespec
+       if !block {
+               wait = &zero
        }
 
+       var events [128]portevent
 retry:
-       n = 1;
-       if(runtime·port_getn(portfd, events, nelem(events), &n, wait) < 0) {
-               if(errno != EINTR && errno != lasterr) {
-                       lasterr = errno;
-                       runtime·printf("runtime: port_getn on fd %d failed with %d\n", portfd, errno);
+       var n uint32 = 1
+       if port_getn(portfd, &events[0], uint32(len(events)), &n, wait) < 0 {
+               if e := errno(); e != _EINTR && e != netpolllasterr {
+                       netpolllasterr = e
+                       print("runtime: port_getn on fd ", portfd, " failed with ", e, "\n")
                }
-               goto retry;
+               goto retry
        }
 
-       gp = nil;
-       for(i = 0; i < n; i++) {
-               ev = &events[i];
+       gp = nil
+       for i := 0; i < int(n); i++ {
+               ev := &events[i]
 
-               if(ev->portev_events == 0)
-                       continue;
-               pd = (PollDesc *)ev->portev_user;
+               if ev.portev_events == 0 {
+                       continue
+               }
+               pd := (*pollDesc)(unsafe.Pointer(ev.portev_user))
 
-               mode = 0;
-               clear = 0;
-               if(ev->portev_events & (POLLIN|POLLHUP|POLLERR)) {
-                       mode += 'r';
-                       clear |= POLLIN;
+               var mode, clear int32
+               if (ev.portev_events & (_POLLIN | _POLLHUP | _POLLERR)) != 0 {
+                       mode += 'r'
+                       clear |= _POLLIN
                }
-               if(ev->portev_events & (POLLOUT|POLLHUP|POLLERR)) {
-                       mode += 'w';
-                       clear |= POLLOUT;
+               if (ev.portev_events & (_POLLOUT | _POLLHUP | _POLLERR)) != 0 {
+                       mode += 'w'
+                       clear |= _POLLOUT
                }
                // To effect edge-triggered events, we need to be sure to
                // update our association with whatever events were not
@@ -248,17 +225,19 @@ retry:
                // for POLLIN|POLLOUT, and we get POLLIN, besides waking
                // the goroutine interested in POLLIN we have to not forget
                // about the one interested in POLLOUT.
-               if(clear != 0) {
-                       runtime·netpolllock(pd);
-                       runtime·netpollupdate(pd, 0, clear);
-                       runtime·netpollunlock(pd);
+               if clear != 0 {
+                       lock(&pd.lock)
+                       netpollupdate(pd, 0, uint32(clear))
+                       unlock(&pd.lock)
                }
 
-               if(mode)
-                       runtime·netpollready(&gp, pd, mode);
+               if mode != 0 {
+                       netpollready((**g)(noescape(unsafe.Pointer(&gp))), pd, mode)
+               }
        }
 
-       if(block && gp == nil)
-               goto retry;
-       return gp;
+       if block && gp == nil {
+               goto retry
+       }
+       return gp
 }
diff --git a/src/runtime/os2_solaris.go b/src/runtime/os2_solaris.go
new file mode 100644 (file)
index 0000000..26ca15f
--- /dev/null
@@ -0,0 +1,13 @@
+// Copyright 2014 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 runtime
+
+const (
+       _SS_DISABLE  = 2
+       _SIG_SETMASK = 3
+       _NSIG        = 73 /* number of signals in sigtable array */
+       _SI_USER     = 0
+       _RLIMIT_AS   = 10
+)
diff --git a/src/runtime/os3_solaris.go b/src/runtime/os3_solaris.go
new file mode 100644 (file)
index 0000000..1df74fa
--- /dev/null
@@ -0,0 +1,493 @@
+// 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.
+
+package runtime
+
+import "unsafe"
+
+//go:cgo_export_dynamic runtime.end _end
+//go:cgo_export_dynamic runtime.etext _etext
+//go:cgo_export_dynamic runtime.edata _edata
+
+//go:cgo_import_dynamic libc____errno ___errno "libc.so"
+//go:cgo_import_dynamic libc_clock_gettime clock_gettime "libc.so"
+//go:cgo_import_dynamic libc_close close "libc.so"
+//go:cgo_import_dynamic libc_exit exit "libc.so"
+//go:cgo_import_dynamic libc_fstat fstat "libc.so"
+//go:cgo_import_dynamic libc_getcontext getcontext "libc.so"
+//go:cgo_import_dynamic libc_getrlimit getrlimit "libc.so"
+//go:cgo_import_dynamic libc_madvise madvise "libc.so"
+//go:cgo_import_dynamic libc_malloc malloc "libc.so"
+//go:cgo_import_dynamic libc_mmap mmap "libc.so"
+//go:cgo_import_dynamic libc_munmap munmap "libc.so"
+//go:cgo_import_dynamic libc_open open "libc.so"
+//go:cgo_import_dynamic libc_pthread_attr_destroy pthread_attr_destroy "libc.so"
+//go:cgo_import_dynamic libc_pthread_attr_getstack pthread_attr_getstack "libc.so"
+//go:cgo_import_dynamic libc_pthread_attr_init pthread_attr_init "libc.so"
+//go:cgo_import_dynamic libc_pthread_attr_setdetachstate pthread_attr_setdetachstate "libc.so"
+//go:cgo_import_dynamic libc_pthread_attr_setstack pthread_attr_setstack "libc.so"
+//go:cgo_import_dynamic libc_pthread_create pthread_create "libc.so"
+//go:cgo_import_dynamic libc_raise raise "libc.so"
+//go:cgo_import_dynamic libc_read read "libc.so"
+//go:cgo_import_dynamic libc_select select "libc.so"
+//go:cgo_import_dynamic libc_sched_yield sched_yield "libc.so"
+//go:cgo_import_dynamic libc_sem_init sem_init "libc.so"
+//go:cgo_import_dynamic libc_sem_post sem_post "libc.so"
+//go:cgo_import_dynamic libc_sem_reltimedwait_np sem_reltimedwait_np "libc.so"
+//go:cgo_import_dynamic libc_sem_wait sem_wait "libc.so"
+//go:cgo_import_dynamic libc_setitimer setitimer "libc.so"
+//go:cgo_import_dynamic libc_sigaction sigaction "libc.so"
+//go:cgo_import_dynamic libc_sigaltstack sigaltstack "libc.so"
+//go:cgo_import_dynamic libc_sigprocmask sigprocmask "libc.so"
+//go:cgo_import_dynamic libc_sysconf sysconf "libc.so"
+//go:cgo_import_dynamic libc_usleep usleep "libc.so"
+//go:cgo_import_dynamic libc_write write "libc.so"
+
+//go:linkname libc____errno libc____errno
+//go:linkname libc_clock_gettime libc_clock_gettime
+//go:linkname libc_close libc_close
+//go:linkname libc_exit libc_exit
+//go:linkname libc_fstat libc_fstat
+//go:linkname libc_getcontext libc_getcontext
+//go:linkname libc_getrlimit libc_getrlimit
+//go:linkname libc_madvise libc_madvise
+//go:linkname libc_malloc libc_malloc
+//go:linkname libc_mmap libc_mmap
+//go:linkname libc_munmap libc_munmap
+//go:linkname libc_open libc_open
+//go:linkname libc_pthread_attr_destroy libc_pthread_attr_destroy
+//go:linkname libc_pthread_attr_getstack libc_pthread_attr_getstack
+//go:linkname libc_pthread_attr_init libc_pthread_attr_init
+//go:linkname libc_pthread_attr_setdetachstate libc_pthread_attr_setdetachstate
+//go:linkname libc_pthread_attr_setstack libc_pthread_attr_setstack
+//go:linkname libc_pthread_create libc_pthread_create
+//go:linkname libc_raise libc_raise
+//go:linkname libc_read libc_read
+//go:linkname libc_select libc_select
+//go:linkname libc_sched_yield libc_sched_yield
+//go:linkname libc_sem_init libc_sem_init
+//go:linkname libc_sem_post libc_sem_post
+//go:linkname libc_sem_reltimedwait_np libc_sem_reltimedwait_np
+//go:linkname libc_sem_wait libc_sem_wait
+//go:linkname libc_setitimer libc_setitimer
+//go:linkname libc_sigaction libc_sigaction
+//go:linkname libc_sigaltstack libc_sigaltstack
+//go:linkname libc_sigprocmask libc_sigprocmask
+//go:linkname libc_sysconf libc_sysconf
+//go:linkname libc_usleep libc_usleep
+//go:linkname libc_write libc_write
+
+var (
+       libc____errno,
+       libc_clock_gettime,
+       libc_close,
+       libc_exit,
+       libc_fstat,
+       libc_getcontext,
+       libc_getrlimit,
+       libc_madvise,
+       libc_malloc,
+       libc_mmap,
+       libc_munmap,
+       libc_open,
+       libc_pthread_attr_destroy,
+       libc_pthread_attr_getstack,
+       libc_pthread_attr_init,
+       libc_pthread_attr_setdetachstate,
+       libc_pthread_attr_setstack,
+       libc_pthread_create,
+       libc_raise,
+       libc_read,
+       libc_sched_yield,
+       libc_select,
+       libc_sem_init,
+       libc_sem_post,
+       libc_sem_reltimedwait_np,
+       libc_sem_wait,
+       libc_setitimer,
+       libc_sigaction,
+       libc_sigaltstack,
+       libc_sigprocmask,
+       libc_sysconf,
+       libc_usleep,
+       libc_write libcFunc
+)
+
+var sigset_none = sigset{}
+var sigset_all = sigset{[4]uint32{^uint32(0), ^uint32(0), ^uint32(0), ^uint32(0)}}
+
+func getncpu() int32 {
+       n := int32(sysconf(__SC_NPROCESSORS_ONLN))
+       if n < 1 {
+               return 1
+       }
+       return n
+}
+
+func osinit() {
+       ncpu = getncpu()
+}
+
+func tstart_sysvicall()
+
+func newosproc(mp *m, _ unsafe.Pointer) {
+       var (
+               attr pthreadattr
+               oset sigset
+               tid  pthread
+               ret  int32
+               size uint64
+       )
+
+       if pthread_attr_init(&attr) != 0 {
+               gothrow("pthread_attr_init")
+       }
+       if pthread_attr_setstack(&attr, 0, 0x200000) != 0 {
+               gothrow("pthread_attr_setstack")
+       }
+       if pthread_attr_getstack(&attr, unsafe.Pointer(&mp.g0.stack.hi), &size) != 0 {
+               gothrow("pthread_attr_getstack")
+       }
+       mp.g0.stack.lo = mp.g0.stack.hi - uintptr(size)
+       if pthread_attr_setdetachstate(&attr, _PTHREAD_CREATE_DETACHED) != 0 {
+               gothrow("pthread_attr_setdetachstate")
+       }
+
+       // Disable signals during create, so that the new thread starts
+       // with signals disabled.  It will enable them in minit.
+       sigprocmask(_SIG_SETMASK, &sigset_all, &oset)
+       ret = pthread_create(&tid, &attr, funcPC(tstart_sysvicall), unsafe.Pointer(mp))
+       sigprocmask(_SIG_SETMASK, &oset, nil)
+       if ret != 0 {
+               print("runtime: failed to create new OS thread (have ", mcount(), " already; errno=", ret, ")\n")
+               gothrow("newosproc")
+       }
+}
+
+var urandom_data [_HashRandomBytes]byte
+var urandom_dev = []byte("/dev/random\x00")
+
+//go:nosplit
+func get_random_data(rnd *unsafe.Pointer, rnd_len *int32) {
+       fd := open(&urandom_dev[0], 0 /* O_RDONLY */, 0)
+       if read(fd, unsafe.Pointer(&urandom_data), _HashRandomBytes) == _HashRandomBytes {
+               *rnd = unsafe.Pointer(&urandom_data[0])
+               *rnd_len = _HashRandomBytes
+       } else {
+               *rnd = nil
+               *rnd_len = 0
+       }
+       close(fd)
+}
+
+func goenvs() {
+       goenvs_unix()
+}
+
+// Called to initialize a new m (including the bootstrap m).
+// Called on the parent thread (main thread in case of bootstrap), can allocate memory.
+func mpreinit(mp *m) {
+       mp.gsignal = malg(32 * 1024)
+       mp.gsignal.m = mp
+}
+
+func miniterrno()
+
+// Called to initialize a new m (including the bootstrap m).
+// Called on the new thread, can not allocate memory.
+func minit() {
+       _g_ := getg()
+       asmcgocall(unsafe.Pointer(funcPC(miniterrno)), unsafe.Pointer(libc____errno))
+       // Initialize signal handling
+       signalstack((*byte)(unsafe.Pointer(_g_.m.gsignal.stack.lo)), 32*1024)
+       sigprocmask(_SIG_SETMASK, &sigset_none, nil)
+}
+
+// Called from dropm to undo the effect of an minit.
+func unminit() {
+       signalstack(nil, 0)
+}
+
+func memlimit() uintptr {
+       /*
+               TODO: Convert to Go when something actually uses the result.
+               Rlimit rl;
+               extern byte runtime·text[], runtime·end[];
+               uintptr used;
+
+               if(runtime·getrlimit(RLIMIT_AS, &rl) != 0)
+                       return 0;
+               if(rl.rlim_cur >= 0x7fffffff)
+                       return 0;
+
+               // Estimate our VM footprint excluding the heap.
+               // Not an exact science: use size of binary plus
+               // some room for thread stacks.
+               used = runtime·end - runtime·text + (64<<20);
+               if(used >= rl.rlim_cur)
+                       return 0;
+
+               // If there's not at least 16 MB left, we're probably
+               // not going to be able to do much.  Treat as no limit.
+               rl.rlim_cur -= used;
+               if(rl.rlim_cur < (16<<20))
+                       return 0;
+
+               return rl.rlim_cur - used;
+       */
+
+       return 0
+}
+
+func sigtramp()
+
+func setsig(i int32, fn uintptr, restart bool) {
+       var sa sigactiont
+
+       sa.sa_flags = _SA_SIGINFO | _SA_ONSTACK
+       sa.sa_flags = _SA_SIGINFO | _SA_ONSTACK
+       if restart {
+               sa.sa_flags |= _SA_RESTART
+       }
+       sa.sa_mask = sigset_all
+       if fn == funcPC(sighandler) {
+               fn = funcPC(sigtramp)
+       }
+       *((*uintptr)(unsafe.Pointer(&sa._funcptr))) = fn
+       sigaction(i, &sa, nil)
+}
+
+func getsig(i int32) uintptr {
+       var sa sigactiont
+       sigaction(i, nil, &sa)
+       if *((*uintptr)(unsafe.Pointer(&sa._funcptr))) == funcPC(sigtramp) {
+               return funcPC(sighandler)
+       }
+       return *((*uintptr)(unsafe.Pointer(&sa._funcptr)))
+}
+
+func signalstack(p *byte, n int32) {
+       var st sigaltstackt
+       st.ss_sp = (*byte)(unsafe.Pointer(p))
+       st.ss_size = uint64(n)
+       st.ss_flags = 0
+       if p == nil {
+               st.ss_flags = _SS_DISABLE
+       }
+       sigaltstack(&st, nil)
+}
+
+func unblocksignals() {
+       sigprocmask(_SIG_SETMASK, &sigset_none, nil)
+}
+
+//go:nosplit
+func semacreate() uintptr {
+       var sem *semt
+       _g_ := getg()
+
+       // Call libc's malloc rather than malloc.  This will
+       // allocate space on the C heap.  We can't call malloc
+       // here because it could cause a deadlock.
+       _g_.m.libcall.fn = uintptr(libc_malloc)
+       _g_.m.libcall.n = 1
+       memclr(unsafe.Pointer(&_g_.m.scratch), uintptr(len(_g_.m.scratch.v)))
+       _g_.m.scratch.v[0] = unsafe.Sizeof(*sem)
+       _g_.m.libcall.args = uintptr(unsafe.Pointer(&_g_.m.scratch))
+       asmcgocall(unsafe.Pointer(&asmsysvicall6), unsafe.Pointer(&_g_.m.libcall))
+       sem = (*semt)(unsafe.Pointer(_g_.m.libcall.r1))
+       if sem_init(sem, 0, 0) != 0 {
+               gothrow("sem_init")
+       }
+       return uintptr(unsafe.Pointer(sem))
+}
+
+//go:nosplit
+func semasleep(ns int64) int32 {
+       _m_ := getg().m
+       if ns >= 0 {
+               _m_.ts.tv_sec = ns / 1000000000
+               _m_.ts.tv_nsec = ns % 1000000000
+
+               _m_.libcall.fn = uintptr(unsafe.Pointer(libc_sem_reltimedwait_np))
+               _m_.libcall.n = 2
+               memclr(unsafe.Pointer(&_m_.scratch), uintptr(len(_m_.scratch.v)))
+               _m_.scratch.v[0] = _m_.waitsema
+               _m_.scratch.v[1] = uintptr(unsafe.Pointer(&_m_.ts))
+               _m_.libcall.args = uintptr(unsafe.Pointer(&_m_.scratch))
+               asmcgocall(unsafe.Pointer(&asmsysvicall6), unsafe.Pointer(&_m_.libcall))
+               if *_m_.perrno != 0 {
+                       if *_m_.perrno == _ETIMEDOUT || *_m_.perrno == _EAGAIN || *_m_.perrno == _EINTR {
+                               return -1
+                       }
+                       gothrow("sem_reltimedwait_np")
+               }
+               return 0
+       }
+       for {
+               _m_.libcall.fn = uintptr(unsafe.Pointer(libc_sem_wait))
+               _m_.libcall.n = 1
+               memclr(unsafe.Pointer(&_m_.scratch), uintptr(len(_m_.scratch.v)))
+               _m_.scratch.v[0] = _m_.waitsema
+               _m_.libcall.args = uintptr(unsafe.Pointer(&_m_.scratch))
+               asmcgocall(unsafe.Pointer(&asmsysvicall6), unsafe.Pointer(&_m_.libcall))
+               if _m_.libcall.r1 == 0 {
+                       break
+               }
+               if *_m_.perrno == _EINTR {
+                       continue
+               }
+               gothrow("sem_wait")
+       }
+       return 0
+}
+
+//go:nosplit
+func semawakeup(mp *m) {
+       if sem_post((*semt)(unsafe.Pointer(mp.waitsema))) != 0 {
+               gothrow("sem_post")
+       }
+}
+
+//go:nosplit
+func close(fd int32) int32 {
+       return int32(sysvicall1(libc_close, uintptr(fd)))
+}
+
+//go:nosplit
+func exit(r int32) {
+       sysvicall1(libc_exit, uintptr(r))
+}
+
+//go:nosplit
+func getcontext(context *ucontext) /* int32 */ {
+       sysvicall1(libc_getcontext, uintptr(unsafe.Pointer(context)))
+}
+
+//go:nosplit
+func madvise(addr unsafe.Pointer, n uintptr, flags int32) {
+       sysvicall3(libc_madvise, uintptr(addr), uintptr(n), uintptr(flags))
+}
+
+//go:nosplit
+func mmap(addr unsafe.Pointer, n uintptr, prot, flags, fd int32, off uint32) unsafe.Pointer {
+       return unsafe.Pointer(sysvicall6(libc_mmap, uintptr(addr), uintptr(n), uintptr(prot), uintptr(flags), uintptr(fd), uintptr(off)))
+}
+
+//go:nosplit
+func munmap(addr unsafe.Pointer, n uintptr) {
+       sysvicall2(libc_munmap, uintptr(addr), uintptr(n))
+}
+
+func nanotime1()
+
+//go:nosplit
+func nanotime() int64 {
+       return int64(sysvicall0(libcFunc(funcPC(nanotime1))))
+}
+
+//go:nosplit
+func open(path *byte, mode, perm int32) int32 {
+       return int32(sysvicall3(libc_open, uintptr(unsafe.Pointer(path)), uintptr(mode), uintptr(perm)))
+}
+
+func pthread_attr_destroy(attr *pthreadattr) int32 {
+       return int32(sysvicall1(libc_pthread_attr_destroy, uintptr(unsafe.Pointer(attr))))
+}
+
+func pthread_attr_getstack(attr *pthreadattr, addr unsafe.Pointer, size *uint64) int32 {
+       return int32(sysvicall3(libc_pthread_attr_getstack, uintptr(unsafe.Pointer(attr)), uintptr(addr), uintptr(unsafe.Pointer(size))))
+}
+
+func pthread_attr_init(attr *pthreadattr) int32 {
+       return int32(sysvicall1(libc_pthread_attr_init, uintptr(unsafe.Pointer(attr))))
+}
+
+func pthread_attr_setdetachstate(attr *pthreadattr, state int32) int32 {
+       return int32(sysvicall2(libc_pthread_attr_setdetachstate, uintptr(unsafe.Pointer(attr)), uintptr(state)))
+}
+
+func pthread_attr_setstack(attr *pthreadattr, addr uintptr, size uint64) int32 {
+       return int32(sysvicall3(libc_pthread_attr_setstack, uintptr(unsafe.Pointer(attr)), uintptr(addr), uintptr(size)))
+}
+
+func pthread_create(thread *pthread, attr *pthreadattr, fn uintptr, arg unsafe.Pointer) int32 {
+       return int32(sysvicall4(libc_pthread_create, uintptr(unsafe.Pointer(thread)), uintptr(unsafe.Pointer(attr)), uintptr(fn), uintptr(arg)))
+}
+
+func raise(sig int32) /* int32 */ {
+       sysvicall1(libc_raise, uintptr(sig))
+}
+
+//go:nosplit
+func read(fd int32, buf unsafe.Pointer, nbyte int32) int32 {
+       return int32(sysvicall3(libc_read, uintptr(fd), uintptr(buf), uintptr(nbyte)))
+}
+
+//go:nosplit
+func sem_init(sem *semt, pshared int32, value uint32) int32 {
+       return int32(sysvicall3(libc_sem_init, uintptr(unsafe.Pointer(sem)), uintptr(pshared), uintptr(value)))
+}
+
+//go:nosplit
+func sem_post(sem *semt) int32 {
+       return int32(sysvicall1(libc_sem_post, uintptr(unsafe.Pointer(sem))))
+}
+
+//go:nosplit
+func sem_reltimedwait_np(sem *semt, timeout *timespec) int32 {
+       return int32(sysvicall2(libc_sem_reltimedwait_np, uintptr(unsafe.Pointer(sem)), uintptr(unsafe.Pointer(timeout))))
+}
+
+//go:nosplit
+func sem_wait(sem *semt) int32 {
+       return int32(sysvicall1(libc_sem_wait, uintptr(unsafe.Pointer(sem))))
+}
+
+func setitimer(which int32, value *itimerval, ovalue *itimerval) /* int32 */ {
+       sysvicall3(libc_setitimer, uintptr(which), uintptr(unsafe.Pointer(value)), uintptr(unsafe.Pointer(ovalue)))
+}
+
+func sigaction(sig int32, act *sigactiont, oact *sigactiont) /* int32 */ {
+       sysvicall3(libc_sigaction, uintptr(sig), uintptr(unsafe.Pointer(act)), uintptr(unsafe.Pointer(oact)))
+}
+
+func sigaltstack(ss *sigaltstackt, oss *sigaltstackt) /* int32 */ {
+       sysvicall2(libc_sigaltstack, uintptr(unsafe.Pointer(ss)), uintptr(unsafe.Pointer(oss)))
+}
+
+func sigprocmask(how int32, set *sigset, oset *sigset) /* int32 */ {
+       sysvicall3(libc_sigprocmask, uintptr(how), uintptr(unsafe.Pointer(set)), uintptr(unsafe.Pointer(oset)))
+}
+
+func sysconf(name int32) int64 {
+       return int64(sysvicall1(libc_sysconf, uintptr(name)))
+}
+
+func usleep1(uint32)
+
+//go:nosplit
+func usleep(µs uint32) {
+       usleep1(µs)
+}
+
+//go:nosplit
+func write(fd uintptr, buf unsafe.Pointer, nbyte int32) int32 {
+       return int32(sysvicall3(libc_write, uintptr(fd), uintptr(buf), uintptr(nbyte)))
+}
+
+func osyield1()
+
+//go:nosplit
+func osyield() {
+       _g_ := getg()
+
+       // Check the validity of m because we might be called in cgo callback
+       // path early enough where there isn't a m available yet.
+       if _g_ != nil && _g_.m != nil {
+               sysvicall0(libc_sched_yield)
+               return
+       }
+       osyield1()
+}
diff --git a/src/runtime/os_solaris.c b/src/runtime/os_solaris.c
deleted file mode 100644 (file)
index e16b8e6..0000000
+++ /dev/null
@@ -1,557 +0,0 @@
-// 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.
-
-#include "runtime.h"
-#include "defs_GOOS_GOARCH.h"
-#include "os_GOOS.h"
-#include "signal_unix.h"
-#include "stack.h"
-#include "textflag.h"
-
-#pragma dynexport runtime·end _end
-#pragma dynexport runtime·etext _etext
-#pragma dynexport runtime·edata _edata
-
-#pragma dynimport libc·___errno ___errno "libc.so"
-#pragma dynimport libc·clock_gettime clock_gettime "libc.so"
-#pragma dynimport libc·close close "libc.so"
-#pragma dynimport libc·exit exit "libc.so"
-#pragma dynimport libc·fstat fstat "libc.so"
-#pragma dynimport libc·getcontext getcontext "libc.so"
-#pragma dynimport libc·getrlimit getrlimit "libc.so"
-#pragma dynimport libc·malloc malloc "libc.so"
-#pragma dynimport libc·mmap mmap "libc.so"
-#pragma dynimport libc·munmap munmap "libc.so"
-#pragma dynimport libc·open open "libc.so"
-#pragma dynimport libc·pthread_attr_destroy pthread_attr_destroy "libc.so"
-#pragma dynimport libc·pthread_attr_getstack pthread_attr_getstack "libc.so"
-#pragma dynimport libc·pthread_attr_init pthread_attr_init "libc.so"
-#pragma dynimport libc·pthread_attr_setdetachstate pthread_attr_setdetachstate "libc.so"
-#pragma dynimport libc·pthread_attr_setstack pthread_attr_setstack "libc.so"
-#pragma dynimport libc·pthread_create pthread_create "libc.so"
-#pragma dynimport libc·raise raise "libc.so"
-#pragma dynimport libc·read read "libc.so"
-#pragma dynimport libc·select select "libc.so"
-#pragma dynimport libc·sched_yield sched_yield "libc.so"
-#pragma dynimport libc·sem_init sem_init "libc.so"
-#pragma dynimport libc·sem_post sem_post "libc.so"
-#pragma dynimport libc·sem_reltimedwait_np sem_reltimedwait_np "libc.so"
-#pragma dynimport libc·sem_wait sem_wait "libc.so"
-#pragma dynimport libc·setitimer setitimer "libc.so"
-#pragma dynimport libc·sigaction sigaction "libc.so"
-#pragma dynimport libc·sigaltstack sigaltstack "libc.so"
-#pragma dynimport libc·sigprocmask sigprocmask "libc.so"
-#pragma dynimport libc·sysconf sysconf "libc.so"
-#pragma dynimport libc·usleep usleep "libc.so"
-#pragma dynimport libc·write write "libc.so"
-
-extern uintptr libc·___errno;
-extern uintptr libc·clock_gettime;
-extern uintptr libc·close;
-extern uintptr libc·exit;
-extern uintptr libc·fstat;
-extern uintptr libc·getcontext;
-extern uintptr libc·getrlimit;
-extern uintptr libc·malloc;
-extern uintptr libc·mmap;
-extern uintptr libc·munmap;
-extern uintptr libc·open;
-extern uintptr libc·pthread_attr_destroy;
-extern uintptr libc·pthread_attr_getstack;
-extern uintptr libc·pthread_attr_init;
-extern uintptr libc·pthread_attr_setdetachstate;
-extern uintptr libc·pthread_attr_setstack;
-extern uintptr libc·pthread_create;
-extern uintptr libc·raise;
-extern uintptr libc·read;
-extern uintptr libc·sched_yield;
-extern uintptr libc·select;
-extern uintptr libc·sem_init;
-extern uintptr libc·sem_post;
-extern uintptr libc·sem_reltimedwait_np;
-extern uintptr libc·sem_wait;
-extern uintptr libc·setitimer;
-extern uintptr libc·sigaction;
-extern uintptr libc·sigaltstack;
-extern uintptr libc·sigprocmask;
-extern uintptr libc·sysconf;
-extern uintptr libc·usleep;
-extern uintptr libc·write;
-
-void   runtime·getcontext(Ucontext *context);
-int32  runtime·pthread_attr_destroy(PthreadAttr* attr);
-int32  runtime·pthread_attr_init(PthreadAttr* attr);
-int32  runtime·pthread_attr_getstack(PthreadAttr* attr, void** addr, uint64* size);
-int32  runtime·pthread_attr_setdetachstate(PthreadAttr* attr, int32 state);
-int32  runtime·pthread_attr_setstack(PthreadAttr* attr, void* addr, uint64 size);
-int32  runtime·pthread_create(Pthread* thread, PthreadAttr* attr, void(*fn)(void), void *arg);
-uint32 runtime·tstart_sysvicall(M *newm);
-int32  runtime·sem_init(SemT* sem, int32 pshared, uint32 value);
-int32  runtime·sem_post(SemT* sem);
-int32  runtime·sem_reltimedwait_np(SemT* sem, Timespec* timeout);
-int32  runtime·sem_wait(SemT* sem);
-int64  runtime·sysconf(int32 name);
-
-extern SigTab runtime·sigtab[];
-static Sigset sigset_none;
-static Sigset sigset_all = { ~(uint32)0, ~(uint32)0, ~(uint32)0, ~(uint32)0, };
-
-static int32
-getncpu(void) 
-{
-       int32 n;
-       
-       n = (int32)runtime·sysconf(_SC_NPROCESSORS_ONLN);
-       if(n < 1)
-               return 1;
-       return n;
-}
-
-void
-runtime·osinit(void)
-{
-       runtime·ncpu = getncpu(); 
-}
-
-void
-runtime·newosproc(M *mp, void *stk)
-{
-       PthreadAttr attr;
-       Sigset oset;
-       Pthread tid;
-       int32 ret;
-       uint64 size;
-
-       USED(stk);
-       if(runtime·pthread_attr_init(&attr) != 0)
-               runtime·throw("pthread_attr_init");
-       if(runtime·pthread_attr_setstack(&attr, 0, 0x200000) != 0)
-               runtime·throw("pthread_attr_setstack");
-       size = 0;
-       if(runtime·pthread_attr_getstack(&attr, (void**)&mp->g0->stack.hi, &size) != 0)
-               runtime·throw("pthread_attr_getstack");        
-       mp->g0->stack.lo = mp->g0->stack.hi - size;
-       if(runtime·pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED) != 0)
-               runtime·throw("pthread_attr_setdetachstate");
-
-       // Disable signals during create, so that the new thread starts
-       // with signals disabled.  It will enable them in minit.
-       runtime·sigprocmask(SIG_SETMASK, &sigset_all, &oset);
-       ret = runtime·pthread_create(&tid, &attr, (void (*)(void))runtime·tstart_sysvicall, mp);
-       runtime·sigprocmask(SIG_SETMASK, &oset, nil);
-       if(ret != 0) {
-               runtime·printf("runtime: failed to create new OS thread (have %d already; errno=%d)\n", runtime·mcount(), ret);
-               runtime·throw("runtime.newosproc");
-       }
-}
-
-#pragma textflag NOSPLIT
-void
-runtime·get_random_data(byte **rnd, int32 *rnd_len)
-{
-       #pragma dataflag NOPTR
-       static byte urandom_data[HashRandomBytes];
-       int32 fd;
-       fd = runtime·open("/dev/urandom", 0 /* O_RDONLY */, 0);
-       if(runtime·read(fd, urandom_data, HashRandomBytes) == HashRandomBytes) {
-               *rnd = urandom_data;
-               *rnd_len = HashRandomBytes;
-       } else {
-               *rnd = nil;
-               *rnd_len = 0;
-       }
-       runtime·close(fd);
-}
-
-void
-runtime·goenvs(void)
-{
-       runtime·goenvs_unix();
-}
-
-// 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);
-       mp->gsignal->m = mp;
-}
-
-// Called to initialize a new m (including the bootstrap m).
-// Called on the new thread, can not allocate memory.
-void
-runtime·minit(void)
-{
-       runtime·asmcgocall(runtime·miniterrno, (void *)libc·___errno);
-       // Initialize signal handling
-       runtime·signalstack((byte*)g->m->gsignal->stack.lo, 32*1024);
-       runtime·sigprocmask(SIG_SETMASK, &sigset_none, nil);
-}
-
-// Called from dropm to undo the effect of an minit.
-void
-runtime·unminit(void)
-{
-       runtime·signalstack(nil, 0);
-}
-
-uintptr
-runtime·memlimit(void)
-{
-       Rlimit rl;
-       extern byte runtime·text[], runtime·end[];
-       uintptr used;
-       
-       if(runtime·getrlimit(RLIMIT_AS, &rl) != 0)
-               return 0;
-       if(rl.rlim_cur >= 0x7fffffff)
-               return 0;
-
-       // Estimate our VM footprint excluding the heap.
-       // Not an exact science: use size of binary plus
-       // some room for thread stacks.
-       used = runtime·end - runtime·text + (64<<20);
-       if(used >= rl.rlim_cur)
-               return 0;
-
-       // If there's not at least 16 MB left, we're probably
-       // not going to be able to do much.  Treat as no limit.
-       rl.rlim_cur -= used;
-       if(rl.rlim_cur < (16<<20))
-               return 0;
-
-       return rl.rlim_cur - used;
-}
-
-void
-runtime·setprof(bool on)
-{
-       USED(on);
-}
-
-extern void runtime·sigtramp(void);
-
-void
-runtime·setsig(int32 i, GoSighandler *fn, bool restart)
-{
-       SigactionT sa;
-
-       runtime·memclr((byte*)&sa, sizeof sa);
-       sa.sa_flags = SA_SIGINFO|SA_ONSTACK;
-       if(restart)
-               sa.sa_flags |= SA_RESTART;
-       sa.sa_mask.__sigbits[0] = ~(uint32)0;
-       sa.sa_mask.__sigbits[1] = ~(uint32)0;
-       sa.sa_mask.__sigbits[2] = ~(uint32)0;
-       sa.sa_mask.__sigbits[3] = ~(uint32)0;
-       if(fn == runtime·sighandler)
-               fn = (void*)runtime·sigtramp;
-       *((void**)&sa._funcptr[0]) = (void*)fn;
-       runtime·sigaction(i, &sa, nil);
-}
-
-GoSighandler*
-runtime·getsig(int32 i)
-{
-       SigactionT sa;
-
-       runtime·memclr((byte*)&sa, sizeof sa);
-       runtime·sigaction(i, nil, &sa);
-       if(*((void**)&sa._funcptr[0]) == runtime·sigtramp)
-               return runtime·sighandler;
-       return *((void**)&sa._funcptr[0]);
-}
-
-void
-runtime·signalstack(byte *p, int32 n)
-{
-       StackT st;
-
-       st.ss_sp = (void*)p;
-       st.ss_size = n;
-       st.ss_flags = 0;
-       if(p == nil)
-               st.ss_flags = SS_DISABLE;
-       runtime·sigaltstack(&st, nil);
-}
-
-void
-runtime·unblocksignals(void)
-{
-       runtime·sigprocmask(SIG_SETMASK, &sigset_none, nil);
-}
-
-#pragma textflag NOSPLIT
-uintptr
-runtime·semacreate(void)
-{
-       SemT* sem;
-
-       // Call libc's malloc rather than runtime·malloc.  This will
-       // allocate space on the C heap.  We can't call runtime·malloc
-       // here because it could cause a deadlock.
-       g->m->libcall.fn = (uintptr)(void*)libc·malloc;
-       g->m->libcall.n = 1;
-       runtime·memclr((byte*)&g->m->scratch, sizeof(g->m->scratch));
-       g->m->scratch.v[0] = (uintptr)sizeof(*sem);
-       g->m->libcall.args = (uintptr)(uintptr*)&g->m->scratch;
-       runtime·asmcgocall(runtime·asmsysvicall6, &g->m->libcall);
-       sem = (void*)g->m->libcall.r1;
-       if(runtime·sem_init(sem, 0, 0) != 0)
-               runtime·throw("sem_init");
-       return (uintptr)sem;
-}
-
-#pragma textflag NOSPLIT
-int32
-runtime·semasleep(int64 ns)
-{
-       M *m;
-
-       m = g->m;
-       if(ns >= 0) {
-               m->ts.tv_sec = ns / 1000000000LL;
-               m->ts.tv_nsec = ns % 1000000000LL;
-
-               m->libcall.fn = (uintptr)(void*)libc·sem_reltimedwait_np;
-               m->libcall.n = 2;
-               runtime·memclr((byte*)&m->scratch, sizeof(m->scratch));
-               m->scratch.v[0] = m->waitsema;
-               m->scratch.v[1] = (uintptr)&m->ts;
-               m->libcall.args = (uintptr)(uintptr*)&m->scratch;
-               runtime·asmcgocall(runtime·asmsysvicall6, &m->libcall);
-               if(*m->perrno != 0) {
-                       if(*m->perrno == ETIMEDOUT || *m->perrno == EAGAIN || *m->perrno == EINTR)
-                               return -1;
-                       runtime·throw("sem_reltimedwait_np");
-               }
-               return 0;
-       }
-       for(;;) {
-               m->libcall.fn = (uintptr)(void*)libc·sem_wait;
-               m->libcall.n = 1;
-               runtime·memclr((byte*)&m->scratch, sizeof(m->scratch));
-               m->scratch.v[0] = m->waitsema;
-               m->libcall.args = (uintptr)(uintptr*)&m->scratch;
-               runtime·asmcgocall(runtime·asmsysvicall6, &m->libcall);
-               if(m->libcall.r1 == 0)
-                       break;
-               if(*m->perrno == EINTR) 
-                       continue;
-               runtime·throw("sem_wait");
-       }
-       return 0;
-}
-
-#pragma textflag NOSPLIT
-void
-runtime·semawakeup(M *mp)
-{
-       SemT* sem = (SemT*)mp->waitsema;
-       if(runtime·sem_post(sem) != 0)
-               runtime·throw("sem_post");
-}
-
-#pragma textflag NOSPLIT
-int32
-runtime·close(int32 fd)
-{
-       return runtime·sysvicall1(libc·close, (uintptr)fd);
-}
-
-#pragma textflag NOSPLIT
-void
-runtime·exit(int32 r)
-{
-       runtime·sysvicall1(libc·exit, (uintptr)r);
-}
-
-#pragma textflag NOSPLIT
-/* int32 */ void
-runtime·getcontext(Ucontext* context)
-{
-       runtime·sysvicall1(libc·getcontext, (uintptr)context);
-}
-
-#pragma textflag NOSPLIT
-int32
-runtime·getrlimit(int32 res, Rlimit* rlp)
-{
-       return runtime·sysvicall2(libc·getrlimit, (uintptr)res, (uintptr)rlp);
-}
-
-#pragma textflag NOSPLIT
-uint8*
-runtime·mmap(byte* addr, uintptr len, int32 prot, int32 flags, int32 fildes, uint32 off)
-{
-       return (uint8*)runtime·sysvicall6(libc·mmap, (uintptr)addr, (uintptr)len, (uintptr)prot, (uintptr)flags, (uintptr)fildes, (uintptr)off);
-}
-
-#pragma textflag NOSPLIT
-void
-runtime·munmap(byte* addr, uintptr len)
-{
-       runtime·sysvicall2(libc·munmap, (uintptr)addr, (uintptr)len);
-}
-
-extern int64 runtime·nanotime1(void);
-#pragma textflag NOSPLIT
-int64
-runtime·nanotime(void)
-{
-       return runtime·sysvicall0((uintptr)runtime·nanotime1);
-}
-
-#pragma textflag NOSPLIT
-int32
-runtime·open(int8* path, int32 oflag, int32 mode)
-{
-       return runtime·sysvicall3(libc·open, (uintptr)path, (uintptr)oflag, (uintptr)mode);
-}
-
-int32
-runtime·pthread_attr_destroy(PthreadAttr* attr)
-{
-       return runtime·sysvicall1(libc·pthread_attr_destroy, (uintptr)attr);
-}
-
-int32
-runtime·pthread_attr_getstack(PthreadAttr* attr, void** addr, uint64* size)
-{
-       return runtime·sysvicall3(libc·pthread_attr_getstack, (uintptr)attr, (uintptr)addr, (uintptr)size);
-}
-
-int32
-runtime·pthread_attr_init(PthreadAttr* attr)
-{
-       return runtime·sysvicall1(libc·pthread_attr_init, (uintptr)attr);
-}
-
-int32
-runtime·pthread_attr_setdetachstate(PthreadAttr* attr, int32 state)
-{
-       return runtime·sysvicall2(libc·pthread_attr_setdetachstate, (uintptr)attr, (uintptr)state);
-}
-
-int32
-runtime·pthread_attr_setstack(PthreadAttr* attr, void* addr, uint64 size)
-{
-       return runtime·sysvicall3(libc·pthread_attr_setstack, (uintptr)attr, (uintptr)addr, (uintptr)size);
-}
-
-int32
-runtime·pthread_create(Pthread* thread, PthreadAttr* attr, void(*fn)(void), void *arg)
-{
-       return runtime·sysvicall4(libc·pthread_create, (uintptr)thread, (uintptr)attr, (uintptr)fn, (uintptr)arg);
-}
-
-/* int32 */ void
-runtime·raise(int32 sig)
-{
-       runtime·sysvicall1(libc·raise, (uintptr)sig);
-}
-
-#pragma textflag NOSPLIT
-int32
-runtime·read(int32 fd, void* buf, int32 nbyte)
-{
-       return runtime·sysvicall3(libc·read, (uintptr)fd, (uintptr)buf, (uintptr)nbyte);
-}
-
-#pragma textflag NOSPLIT
-int32
-runtime·sem_init(SemT* sem, int32 pshared, uint32 value)
-{
-       return runtime·sysvicall3(libc·sem_init, (uintptr)sem, (uintptr)pshared, (uintptr)value);
-}
-
-#pragma textflag NOSPLIT
-int32
-runtime·sem_post(SemT* sem)
-{
-       return runtime·sysvicall1(libc·sem_post, (uintptr)sem);
-}
-
-#pragma textflag NOSPLIT
-int32
-runtime·sem_reltimedwait_np(SemT* sem, Timespec* timeout)
-{
-       return runtime·sysvicall2(libc·sem_reltimedwait_np, (uintptr)sem, (uintptr)timeout);
-}
-
-#pragma textflag NOSPLIT
-int32
-runtime·sem_wait(SemT* sem)
-{
-       return runtime·sysvicall1(libc·sem_wait, (uintptr)sem);
-}
-
-/* int32 */ void
-runtime·setitimer(int32 which, Itimerval* value, Itimerval* ovalue)
-{
-       runtime·sysvicall3(libc·setitimer, (uintptr)which, (uintptr)value, (uintptr)ovalue);
-}
-
-/* int32 */ void
-runtime·sigaction(int32 sig, struct SigactionT* act, struct SigactionT* oact)
-{
-       runtime·sysvicall3(libc·sigaction, (uintptr)sig, (uintptr)act, (uintptr)oact);
-}
-
-/* int32 */ void
-runtime·sigaltstack(SigaltstackT* ss, SigaltstackT* oss)
-{
-       runtime·sysvicall2(libc·sigaltstack, (uintptr)ss, (uintptr)oss);
-}
-
-/* int32 */ void
-runtime·sigprocmask(int32 how, Sigset* set, Sigset* oset)
-{
-       runtime·sysvicall3(libc·sigprocmask, (uintptr)how, (uintptr)set, (uintptr)oset);
-}
-
-int64
-runtime·sysconf(int32 name)
-{
-       return runtime·sysvicall1(libc·sysconf, (uintptr)name);
-}
-
-extern void runtime·usleep1(uint32);
-
-#pragma textflag NOSPLIT
-void
-runtime·usleep(uint32 µs)
-{
-       runtime·usleep1(µs);
-}
-
-#pragma textflag NOSPLIT
-int32
-runtime·write(uintptr fd, void* buf, int32 nbyte)
-{
-       return runtime·sysvicall3(libc·write, (uintptr)fd, (uintptr)buf, (uintptr)nbyte);
-}
-
-extern void runtime·osyield1(void);
-
-#pragma textflag NOSPLIT
-void
-runtime·osyield(void)
-{
-       // Check the validity of m because we might be called in cgo callback
-       // path early enough where there isn't a m available yet.
-       if(g && g->m != nil) {
-               runtime·sysvicall0(libc·sched_yield);
-               return;
-       }
-       runtime·osyield1();
-}
-
-#pragma textflag NOSPLIT
-int8*
-runtime·signame(int32 sig)
-{
-       return runtime·sigtab[sig].name;
-}
index ca13151204a5e213cec566103e234f17cf22f722..6864ef9383482006528551d35495dbbbc0b05e90 100644 (file)
@@ -6,53 +6,35 @@ package runtime
 
 import "unsafe"
 
-func setitimer(mode int32, new, old unsafe.Pointer)
-func sigaction(sig int32, new, old unsafe.Pointer)
-func sigaltstack(new, old unsafe.Pointer)
-func sigprocmask(mode int32, new, old unsafe.Pointer)
-func sysctl(mib *uint32, miblen uint32, out *byte, size *uintptr, dst *byte, ndst uintptr) int32
-func getrlimit(kind int32, limit unsafe.Pointer)
-func miniterrno(fn unsafe.Pointer)
-func raise(sig int32)
-func getcontext(ctxt unsafe.Pointer)
-func tstart_sysvicall(mm unsafe.Pointer) uint32
-func nanotime1() int64
-func usleep1(usec uint32)
-func osyield1()
-func netpollinit()
-func netpollopen(fd uintptr, pd *pollDesc) int32
-func netpollclose(fd uintptr) int32
-func netpollarm(pd *pollDesc, mode int)
-
-type libcFunc byte
+type libcFunc uintptr
 
 var asmsysvicall6 libcFunc
 
 //go:nosplit
-func sysvicall0(fn *libcFunc) uintptr {
+func sysvicall0(fn libcFunc) uintptr {
        libcall := &getg().m.libcall
-       libcall.fn = uintptr(unsafe.Pointer(fn))
+       libcall.fn = uintptr(fn)
        libcall.n = 0
-       // TODO(rsc): Why is noescape necessary here and below?
-       libcall.args = uintptr(noescape(unsafe.Pointer(&fn))) // it's unused but must be non-nil, otherwise crashes
+       libcall.args = uintptr(fn) // it's unused but must be non-nil, otherwise crashes
        asmcgocall(unsafe.Pointer(&asmsysvicall6), unsafe.Pointer(libcall))
        return libcall.r1
 }
 
 //go:nosplit
-func sysvicall1(fn *libcFunc, a1 uintptr) uintptr {
+func sysvicall1(fn libcFunc, a1 uintptr) uintptr {
        libcall := &getg().m.libcall
-       libcall.fn = uintptr(unsafe.Pointer(fn))
+       libcall.fn = uintptr(fn)
        libcall.n = 1
+       // TODO(rsc): Why is noescape necessary here and below?
        libcall.args = uintptr(noescape(unsafe.Pointer(&a1)))
        asmcgocall(unsafe.Pointer(&asmsysvicall6), unsafe.Pointer(libcall))
        return libcall.r1
 }
 
 //go:nosplit
-func sysvicall2(fn *libcFunc, a1, a2 uintptr) uintptr {
+func sysvicall2(fn libcFunc, a1, a2 uintptr) uintptr {
        libcall := &getg().m.libcall
-       libcall.fn = uintptr(unsafe.Pointer(fn))
+       libcall.fn = uintptr(fn)
        libcall.n = 2
        libcall.args = uintptr(noescape(unsafe.Pointer(&a1)))
        asmcgocall(unsafe.Pointer(&asmsysvicall6), unsafe.Pointer(libcall))
@@ -60,9 +42,9 @@ func sysvicall2(fn *libcFunc, a1, a2 uintptr) uintptr {
 }
 
 //go:nosplit
-func sysvicall3(fn *libcFunc, a1, a2, a3 uintptr) uintptr {
+func sysvicall3(fn libcFunc, a1, a2, a3 uintptr) uintptr {
        libcall := &getg().m.libcall
-       libcall.fn = uintptr(unsafe.Pointer(fn))
+       libcall.fn = uintptr(fn)
        libcall.n = 3
        libcall.args = uintptr(noescape(unsafe.Pointer(&a1)))
        asmcgocall(unsafe.Pointer(&asmsysvicall6), unsafe.Pointer(libcall))
@@ -70,9 +52,9 @@ func sysvicall3(fn *libcFunc, a1, a2, a3 uintptr) uintptr {
 }
 
 //go:nosplit
-func sysvicall4(fn *libcFunc, a1, a2, a3, a4 uintptr) uintptr {
+func sysvicall4(fn libcFunc, a1, a2, a3, a4 uintptr) uintptr {
        libcall := &getg().m.libcall
-       libcall.fn = uintptr(unsafe.Pointer(fn))
+       libcall.fn = uintptr(fn)
        libcall.n = 4
        libcall.args = uintptr(noescape(unsafe.Pointer(&a1)))
        asmcgocall(unsafe.Pointer(&asmsysvicall6), unsafe.Pointer(libcall))
@@ -80,9 +62,9 @@ func sysvicall4(fn *libcFunc, a1, a2, a3, a4 uintptr) uintptr {
 }
 
 //go:nosplit
-func sysvicall5(fn *libcFunc, a1, a2, a3, a4, a5 uintptr) uintptr {
+func sysvicall5(fn libcFunc, a1, a2, a3, a4, a5 uintptr) uintptr {
        libcall := &getg().m.libcall
-       libcall.fn = uintptr(unsafe.Pointer(fn))
+       libcall.fn = uintptr(fn)
        libcall.n = 5
        libcall.args = uintptr(noescape(unsafe.Pointer(&a1)))
        asmcgocall(unsafe.Pointer(&asmsysvicall6), unsafe.Pointer(libcall))
@@ -90,9 +72,9 @@ func sysvicall5(fn *libcFunc, a1, a2, a3, a4, a5 uintptr) uintptr {
 }
 
 //go:nosplit
-func sysvicall6(fn *libcFunc, a1, a2, a3, a4, a5, a6 uintptr) uintptr {
+func sysvicall6(fn libcFunc, a1, a2, a3, a4, a5, a6 uintptr) uintptr {
        libcall := &getg().m.libcall
-       libcall.fn = uintptr(unsafe.Pointer(fn))
+       libcall.fn = uintptr(fn)
        libcall.n = 6
        libcall.args = uintptr(noescape(unsafe.Pointer(&a1)))
        asmcgocall(unsafe.Pointer(&asmsysvicall6), unsafe.Pointer(libcall))
diff --git a/src/runtime/os_solaris.h b/src/runtime/os_solaris.h
deleted file mode 100644 (file)
index 3d9e1a2..0000000
+++ /dev/null
@@ -1,55 +0,0 @@
-// Copyright 2014 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.
-
-
-typedef uintptr kevent_udata;
-
-struct sigaction;
-
-void   runtime·sigpanic(void);
-
-void   runtime·setitimer(int32, Itimerval*, Itimerval*);
-void   runtime·sigaction(int32, struct SigactionT*, struct SigactionT*);
-void   runtime·sigaltstack(SigaltstackT*, SigaltstackT*);
-void   runtime·sigprocmask(int32, Sigset*, Sigset*);
-void   runtime·unblocksignals(void);
-int32  runtime·sysctl(uint32*, uint32, byte*, uintptr*, byte*, uintptr);
-
-
-void   runtime·raisesigpipe(void);
-void   runtime·setsig(int32, void(*)(int32, Siginfo*, void*, G*), bool);
-void   runtime·sighandler(int32 sig, Siginfo *info, void *context, G *gp);
-void   runtime·sigpanic(void);
-
-enum {
-       SS_DISABLE = 2,
-       SIG_BLOCK = 1,
-       SIG_UNBLOCK = 2,
-       SIG_SETMASK = 3,
-       NSIG = 73, /* number of signals in runtime·SigTab array */
-       SI_USER = 0,
-       _UC_SIGMASK = 0x01,
-       _UC_CPU = 0x04,
-       RLIMIT_AS = 10,
-};
-
-typedef struct Rlimit Rlimit;
-struct Rlimit {
-       int64   rlim_cur;
-       int64   rlim_max;
-};
-int32   runtime·getrlimit(int32, Rlimit*);
-
-// Call an external library function described by {fn, a0, ..., an}, with
-// SysV conventions, switching to os stack during the call, if necessary.
-uintptr        runtime·sysvicall0(uintptr fn);
-uintptr        runtime·sysvicall1(uintptr fn, uintptr a1);
-uintptr        runtime·sysvicall2(uintptr fn, uintptr a1, uintptr a2);
-uintptr        runtime·sysvicall3(uintptr fn, uintptr a1, uintptr a2, uintptr a3);
-uintptr        runtime·sysvicall4(uintptr fn, uintptr a1, uintptr a2, uintptr a3, uintptr a4);
-uintptr        runtime·sysvicall5(uintptr fn, uintptr a1, uintptr a2, uintptr a3, uintptr a4, uintptr a5);
-uintptr        runtime·sysvicall6(uintptr fn, uintptr a1, uintptr a2, uintptr a3, uintptr a4, uintptr a5, uintptr a6);
-void   runtime·asmsysvicall6(void *c);
-
-void   runtime·miniterrno(void *fn);
diff --git a/src/runtime/signal_solaris.go b/src/runtime/signal_solaris.go
new file mode 100644 (file)
index 0000000..2986c5a
--- /dev/null
@@ -0,0 +1,88 @@
+// Copyright 2014 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 runtime
+
+type sigTabT struct {
+       flags int32
+       name  string
+}
+
+var sigtable = [...]sigTabT{
+       /* 0 */ {0, "SIGNONE: no trap"},
+       /* 1 */ {_SigNotify + _SigKill, "SIGHUP: hangup"},
+       /* 2 */ {_SigNotify + _SigKill, "SIGINT: interrupt (rubout)"},
+       /* 3 */ {_SigNotify + _SigThrow, "SIGQUIT: quit (ASCII FS)"},
+       /* 4 */ {_SigThrow, "SIGILL: illegal instruction (not reset when caught)"},
+       /* 5 */ {_SigThrow, "SIGTRAP: trace trap (not reset when caught)"},
+       /* 6 */ {_SigNotify + _SigThrow, "SIGABRT: used by abort, replace SIGIOT in the future"},
+       /* 7 */ {_SigThrow, "SIGEMT: EMT instruction"},
+       /* 8 */ {_SigPanic, "SIGFPE: floating point exception"},
+       /* 9 */ {0, "SIGKILL: kill (cannot be caught or ignored)"},
+       /* 10 */ {_SigPanic, "SIGBUS: bus error"},
+       /* 11 */ {_SigPanic, "SIGSEGV: segmentation violation"},
+       /* 12 */ {_SigThrow, "SIGSYS: bad argument to system call"},
+       /* 13 */ {_SigNotify, "SIGPIPE: write on a pipe with no one to read it"},
+       /* 14 */ {_SigNotify, "SIGALRM: alarm clock"},
+       /* 15 */ {_SigNotify + _SigKill, "SIGTERM: software termination signal from kill"},
+       /* 16 */ {_SigNotify, "SIGUSR1: user defined signal 1"},
+       /* 17 */ {_SigNotify, "SIGUSR2: user defined signal 2"},
+       /* 18 */ {_SigNotify, "SIGCHLD: child status change alias (POSIX)"},
+       /* 19 */ {_SigNotify, "SIGPWR: power-fail restart"},
+       /* 20 */ {_SigNotify, "SIGWINCH: window size change"},
+       /* 21 */ {_SigNotify, "SIGURG: urgent socket condition"},
+       /* 22 */ {_SigNotify, "SIGPOLL: pollable event occured"},
+       /* 23 */ {_SigNotify + _SigDefault, "SIGSTOP: stop (cannot be caught or ignored)"},
+       /* 24 */ {0, "SIGTSTP: user stop requested from tty"},
+       /* 25 */ {0, "SIGCONT: stopped process has been continued"},
+       /* 26 */ {_SigNotify + _SigDefault, "SIGTTIN: background tty read attempted"},
+       /* 27 */ {_SigNotify + _SigDefault, "SIGTTOU: background tty write attempted"},
+       /* 28 */ {_SigNotify, "SIGVTALRM: virtual timer expired"},
+       /* 29 */ {_SigNotify, "SIGPROF: profiling timer expired"},
+       /* 30 */ {_SigNotify, "SIGXCPU: exceeded cpu limit"},
+       /* 31 */ {_SigNotify, "SIGXFSZ: exceeded file size limit"},
+       /* 32 */ {_SigNotify, "SIGWAITING: reserved signal no longer used by"},
+       /* 33 */ {_SigNotify, "SIGLWP: reserved signal no longer used by"},
+       /* 34 */ {_SigNotify, "SIGFREEZE: special signal used by CPR"},
+       /* 35 */ {_SigNotify, "SIGTHAW: special signal used by CPR"},
+       /* 36 */ {0, "SIGCANCEL: reserved signal for thread cancellation"},
+       /* 37 */ {_SigNotify, "SIGLOST: resource lost (eg, record-lock lost)"},
+       /* 38 */ {_SigNotify, "SIGXRES: resource control exceeded"},
+       /* 39 */ {_SigNotify, "SIGJVM1: reserved signal for Java Virtual Machine"},
+       /* 40 */ {_SigNotify, "SIGJVM2: reserved signal for Java Virtual Machine"},
+
+       /* TODO(aram): what should be do about these signals? _SigDefault or _SigNotify? is this set static? */
+       /* 41 */ {_SigNotify, "real time signal"},
+       /* 42 */ {_SigNotify, "real time signal"},
+       /* 43 */ {_SigNotify, "real time signal"},
+       /* 44 */ {_SigNotify, "real time signal"},
+       /* 45 */ {_SigNotify, "real time signal"},
+       /* 46 */ {_SigNotify, "real time signal"},
+       /* 47 */ {_SigNotify, "real time signal"},
+       /* 48 */ {_SigNotify, "real time signal"},
+       /* 49 */ {_SigNotify, "real time signal"},
+       /* 50 */ {_SigNotify, "real time signal"},
+       /* 51 */ {_SigNotify, "real time signal"},
+       /* 52 */ {_SigNotify, "real time signal"},
+       /* 53 */ {_SigNotify, "real time signal"},
+       /* 54 */ {_SigNotify, "real time signal"},
+       /* 55 */ {_SigNotify, "real time signal"},
+       /* 56 */ {_SigNotify, "real time signal"},
+       /* 57 */ {_SigNotify, "real time signal"},
+       /* 58 */ {_SigNotify, "real time signal"},
+       /* 59 */ {_SigNotify, "real time signal"},
+       /* 60 */ {_SigNotify, "real time signal"},
+       /* 61 */ {_SigNotify, "real time signal"},
+       /* 62 */ {_SigNotify, "real time signal"},
+       /* 63 */ {_SigNotify, "real time signal"},
+       /* 64 */ {_SigNotify, "real time signal"},
+       /* 65 */ {_SigNotify, "real time signal"},
+       /* 66 */ {_SigNotify, "real time signal"},
+       /* 67 */ {_SigNotify, "real time signal"},
+       /* 68 */ {_SigNotify, "real time signal"},
+       /* 69 */ {_SigNotify, "real time signal"},
+       /* 70 */ {_SigNotify, "real time signal"},
+       /* 71 */ {_SigNotify, "real time signal"},
+       /* 72 */ {_SigNotify, "real time signal"},
+}
diff --git a/src/runtime/signal_solaris_amd64.go b/src/runtime/signal_solaris_amd64.go
new file mode 100644 (file)
index 0000000..967835a
--- /dev/null
@@ -0,0 +1,46 @@
+// Copyright 2014 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 runtime
+
+import "unsafe"
+
+type sigctxt struct {
+       info *siginfo
+       ctxt unsafe.Pointer
+}
+
+func (c *sigctxt) regs() *mcontext {
+       return (*mcontext)(unsafe.Pointer(&(*ucontext)(c.ctxt).uc_mcontext))
+}
+func (c *sigctxt) rax() uint64     { return uint64(c.regs().gregs[_REG_RAX]) }
+func (c *sigctxt) rbx() uint64     { return uint64(c.regs().gregs[_REG_RBX]) }
+func (c *sigctxt) rcx() uint64     { return uint64(c.regs().gregs[_REG_RCX]) }
+func (c *sigctxt) rdx() uint64     { return uint64(c.regs().gregs[_REG_RDX]) }
+func (c *sigctxt) rdi() uint64     { return uint64(c.regs().gregs[_REG_RDI]) }
+func (c *sigctxt) rsi() uint64     { return uint64(c.regs().gregs[_REG_RSI]) }
+func (c *sigctxt) rbp() uint64     { return uint64(c.regs().gregs[_REG_RBP]) }
+func (c *sigctxt) rsp() uint64     { return uint64(c.regs().gregs[_REG_RSP]) }
+func (c *sigctxt) r8() uint64      { return uint64(c.regs().gregs[_REG_R8]) }
+func (c *sigctxt) r9() uint64      { return uint64(c.regs().gregs[_REG_R9]) }
+func (c *sigctxt) r10() uint64     { return uint64(c.regs().gregs[_REG_R10]) }
+func (c *sigctxt) r11() uint64     { return uint64(c.regs().gregs[_REG_R11]) }
+func (c *sigctxt) r12() uint64     { return uint64(c.regs().gregs[_REG_R12]) }
+func (c *sigctxt) r13() uint64     { return uint64(c.regs().gregs[_REG_R13]) }
+func (c *sigctxt) r14() uint64     { return uint64(c.regs().gregs[_REG_R14]) }
+func (c *sigctxt) r15() uint64     { return uint64(c.regs().gregs[_REG_R15]) }
+func (c *sigctxt) rip() uint64     { return uint64(c.regs().gregs[_REG_RIP]) }
+func (c *sigctxt) rflags() uint64  { return uint64(c.regs().gregs[_REG_RFLAGS]) }
+func (c *sigctxt) cs() uint64      { return uint64(c.regs().gregs[_REG_CS]) }
+func (c *sigctxt) fs() uint64      { return uint64(c.regs().gregs[_REG_FS]) }
+func (c *sigctxt) gs() uint64      { return uint64(c.regs().gregs[_REG_GS]) }
+func (c *sigctxt) sigcode() uint64 { return uint64(c.info.si_code) }
+func (c *sigctxt) sigaddr() uint64 { return uint64(uintptr(unsafe.Pointer(&c.info.__data[0]))) }
+
+func (c *sigctxt) set_rip(x uint64)     { c.regs().gregs[_REG_RIP] = int64(x) }
+func (c *sigctxt) set_rsp(x uint64)     { c.regs().gregs[_REG_RSP] = int64(x) }
+func (c *sigctxt) set_sigcode(x uint64) { c.info.si_code = int32(x) }
+func (c *sigctxt) set_sigaddr(x uint64) {
+       *(*uintptr)(unsafe.Pointer(&c.info.__data[0])) = uintptr(x)
+}
diff --git a/src/runtime/signal_solaris_amd64.h b/src/runtime/signal_solaris_amd64.h
deleted file mode 100644 (file)
index c2e0a15..0000000
+++ /dev/null
@@ -1,31 +0,0 @@
-// Copyright 2014 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) (((Ucontext*)(ctxt))->uc_mcontext)
-
-#define SIG_RAX(info, ctxt) (SIG_REGS(ctxt).gregs[REG_RAX])
-#define SIG_RBX(info, ctxt) (SIG_REGS(ctxt).gregs[REG_RBX])
-#define SIG_RCX(info, ctxt) (SIG_REGS(ctxt).gregs[REG_RCX])
-#define SIG_RDX(info, ctxt) (SIG_REGS(ctxt).gregs[REG_RDX])
-#define SIG_RDI(info, ctxt) (SIG_REGS(ctxt).gregs[REG_RDI])
-#define SIG_RSI(info, ctxt) (SIG_REGS(ctxt).gregs[REG_RSI])
-#define SIG_RBP(info, ctxt) (SIG_REGS(ctxt).gregs[REG_RBP])
-#define SIG_RSP(info, ctxt) (SIG_REGS(ctxt).gregs[REG_RSP])
-#define SIG_R8(info, ctxt) (SIG_REGS(ctxt).gregs[REG_R8])
-#define SIG_R9(info, ctxt) (SIG_REGS(ctxt).gregs[REG_R9])
-#define SIG_R10(info, ctxt) (SIG_REGS(ctxt).gregs[REG_R10])
-#define SIG_R11(info, ctxt) (SIG_REGS(ctxt).gregs[REG_R11])
-#define SIG_R12(info, ctxt) (SIG_REGS(ctxt).gregs[REG_R12])
-#define SIG_R13(info, ctxt) (SIG_REGS(ctxt).gregs[REG_R13])
-#define SIG_R14(info, ctxt) (SIG_REGS(ctxt).gregs[REG_R14])
-#define SIG_R15(info, ctxt) (SIG_REGS(ctxt).gregs[REG_R15])
-#define SIG_RIP(info, ctxt) (SIG_REGS(ctxt).gregs[REG_RIP])
-#define SIG_RFLAGS(info, ctxt) (SIG_REGS(ctxt).gregs[REG_RFLAGS])
-
-#define SIG_CS(info, ctxt) (SIG_REGS(ctxt).gregs[REG_CS])
-#define SIG_FS(info, ctxt) (SIG_REGS(ctxt).gregs[REG_FS])
-#define SIG_GS(info, ctxt) (SIG_REGS(ctxt).gregs[REG_GS])
-
-#define SIG_CODE0(info, ctxt) ((info)->si_code)
-#define SIG_CODE1(info, ctxt) (*(uintptr*)&(info)->__data[0])
diff --git a/src/runtime/signals_solaris.h b/src/runtime/signals_solaris.h
deleted file mode 100644 (file)
index 1f0a65e..0000000
+++ /dev/null
@@ -1,97 +0,0 @@
-// Copyright 2014 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 "textflag.h"
-
-#define N SigNotify
-#define K SigKill
-#define T SigThrow
-#define P SigPanic
-#define D SigDefault
-
-#pragma dataflag NOPTR
-SigTab runtime·sigtab[] = {
-       /* 0 */         0, "SIGNONE: no trap",
-       /* 1 */         N+K, "SIGHUP: hangup",
-       /* 2 */         N+K, "SIGINT: interrupt (rubout)",
-       /* 3 */         N+T, "SIGQUIT: quit (ASCII FS)",
-       /* 4 */         T, "SIGILL: illegal instruction (not reset when caught)",
-       /* 5 */         T, "SIGTRAP: trace trap (not reset when caught)",
-       /* 6 */         N+T, "SIGABRT: used by abort, replace SIGIOT in the future",
-       /* 7 */         T, "SIGEMT: EMT instruction",
-       /* 8 */         P, "SIGFPE: floating point exception",
-       /* 9 */         0, "SIGKILL: kill (cannot be caught or ignored)",
-       /* 10 */        P, "SIGBUS: bus error",
-       /* 11 */        P, "SIGSEGV: segmentation violation",
-       /* 12 */        T, "SIGSYS: bad argument to system call",
-       /* 13 */        N, "SIGPIPE: write on a pipe with no one to read it",
-       /* 14 */        N, "SIGALRM: alarm clock",
-       /* 15 */        N+K, "SIGTERM: software termination signal from kill",
-       /* 16 */        N, "SIGUSR1: user defined signal 1",
-       /* 17 */        N, "SIGUSR2: user defined signal 2",
-       /* 18 */        N, "SIGCLD: child status change",
-       /* 18 */        N, "SIGCHLD: child status change alias (POSIX)",
-       /* 19 */        N, "SIGPWR: power-fail restart",
-       /* 20 */        N, "SIGWINCH: window size change",
-       /* 21 */        N, "SIGURG: urgent socket condition",
-       /* 22 */        N, "SIGPOLL: pollable event occured",
-       /* 23 */        N+D, "SIGSTOP: stop (cannot be caught or ignored)",
-       /* 24 */        0, "SIGTSTP: user stop requested from tty",
-       /* 25 */        0, "SIGCONT: stopped process has been continued",
-       /* 26 */        N+D, "SIGTTIN: background tty read attempted",
-       /* 27 */        N+D, "SIGTTOU: background tty write attempted",
-       /* 28 */        N, "SIGVTALRM: virtual timer expired",
-       /* 29 */        N, "SIGPROF: profiling timer expired",
-       /* 30 */        N, "SIGXCPU: exceeded cpu limit",
-       /* 31 */        N, "SIGXFSZ: exceeded file size limit",
-       /* 32 */        N, "SIGWAITING: reserved signal no longer used by",
-       /* 33 */        N, "SIGLWP: reserved signal no longer used by",
-       /* 34 */        N, "SIGFREEZE: special signal used by CPR",
-       /* 35 */        N, "SIGTHAW: special signal used by CPR",
-       /* 36 */        0, "SIGCANCEL: reserved signal for thread cancellation",
-       /* 37 */        N, "SIGLOST: resource lost (eg, record-lock lost)",
-       /* 38 */        N, "SIGXRES: resource control exceeded",
-       /* 39 */        N, "SIGJVM1: reserved signal for Java Virtual Machine",
-       /* 40 */        N, "SIGJVM2: reserved signal for Java Virtual Machine",
-
-       /* TODO(aram): what should be do about these signals? D or N? is this set static? */
-       /* 41 */        N, "real time signal",
-       /* 42 */        N, "real time signal",
-       /* 43 */        N, "real time signal",
-       /* 44 */        N, "real time signal",
-       /* 45 */        N, "real time signal",
-       /* 46 */        N, "real time signal",
-       /* 47 */        N, "real time signal",
-       /* 48 */        N, "real time signal",
-       /* 49 */        N, "real time signal",
-       /* 50 */        N, "real time signal",
-       /* 51 */        N, "real time signal",
-       /* 52 */        N, "real time signal",
-       /* 53 */        N, "real time signal",
-       /* 54 */        N, "real time signal",
-       /* 55 */        N, "real time signal",
-       /* 56 */        N, "real time signal",
-       /* 57 */        N, "real time signal",
-       /* 58 */        N, "real time signal",
-       /* 59 */        N, "real time signal",
-       /* 60 */        N, "real time signal",
-       /* 61 */        N, "real time signal",
-       /* 62 */        N, "real time signal",
-       /* 63 */        N, "real time signal",
-       /* 64 */        N, "real time signal",
-       /* 65 */        N, "real time signal",
-       /* 66 */        N, "real time signal",
-       /* 67 */        N, "real time signal",
-       /* 68 */        N, "real time signal",
-       /* 69 */        N, "real time signal",
-       /* 70 */        N, "real time signal",
-       /* 71 */        N, "real time signal",
-       /* 72 */        N, "real time signal",
-};
-
-#undef N
-#undef K
-#undef T
-#undef P
-#undef D
index bca0a1d7cd8ba3a969eebde505b6aa6a6818c7ba..217307a1ed0a65260a4cdcb87d760ae522291ed2 100644 (file)
@@ -96,8 +96,6 @@ func noescape(p unsafe.Pointer) unsafe.Pointer {
 func cgocallback(fn, frame unsafe.Pointer, framesize uintptr)
 func gogo(buf *gobuf)
 func gosave(buf *gobuf)
-func read(fd int32, p unsafe.Pointer, n int32) int32
-func close(fd int32) int32
 func mincore(addr unsafe.Pointer, n uintptr, dst *byte) int32
 
 //go:noescape
@@ -105,22 +103,13 @@ func jmpdefer(fv *funcval, argp uintptr)
 func exit1(code int32)
 func asminit()
 func setg(gg *g)
-func exit(code int32)
 func breakpoint()
-func nanotime() int64
-func usleep(usec uint32)
 
-func mmap(addr unsafe.Pointer, n uintptr, prot, flags, fd int32, off uint32) unsafe.Pointer
-func munmap(addr unsafe.Pointer, n uintptr)
-func madvise(addr unsafe.Pointer, n uintptr, flags int32)
 func reflectcall(fn, arg unsafe.Pointer, n uint32, retoffset uint32)
 func procyield(cycles uint32)
 func cgocallback_gofunc(fv *funcval, frame unsafe.Pointer, framesize uintptr)
 func goexit()
 
-//go:noescape
-func write(fd uintptr, p unsafe.Pointer, n int32) int32
-
 //go:noescape
 func cas(ptr *uint32, old, new uint32) bool
 
@@ -195,9 +184,6 @@ func asmcgocall(fn, arg unsafe.Pointer)
 //go:noescape
 func asmcgocall_errno(fn, arg unsafe.Pointer) int32
 
-//go:noescape
-func open(name *byte, mode, perm int32) int32
-
 // argp used in Defer structs when there is no argp.
 const _NoArgs = ^uintptr(0)
 
diff --git a/src/runtime/stubs2.go b/src/runtime/stubs2.go
new file mode 100644 (file)
index 0000000..526b3c5
--- /dev/null
@@ -0,0 +1,27 @@
+// Copyright 2014 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.
+
+// +build !solaris
+
+package runtime
+
+import "unsafe"
+
+func read(fd int32, p unsafe.Pointer, n int32) int32
+func close(fd int32) int32
+
+func exit(code int32)
+func nanotime() int64
+func usleep(usec uint32)
+
+func mmap(addr unsafe.Pointer, n uintptr, prot, flags, fd int32, off uint32) unsafe.Pointer
+func munmap(addr unsafe.Pointer, n uintptr)
+
+//go:noescape
+func write(fd uintptr, p unsafe.Pointer, n int32) int32
+
+//go:noescape
+func open(name *byte, mode, perm int32) int32
+
+func madvise(addr unsafe.Pointer, n uintptr, flags int32)
index 3b63b4988892735a6e223669973fe030a1fc16db..5fe8387ead6c019d7b8542c18990aa022304d41f 100644 (file)
@@ -14,7 +14,7 @@
 TEXT runtime·settls(SB),NOSPLIT,$8
        RET
 
-// void libc·miniterrno(void *(*___errno)(void));
+// void libc_miniterrno(void *(*___errno)(void));
 //
 // Set the TLS errno pointer in M.
 //
@@ -41,7 +41,7 @@ TEXT runtime·nanotime1(SB),NOSPLIT,$0
        SUBQ    $64, SP // 16 bytes will do, but who knows in the future?
        MOVQ    $3, DI  // CLOCK_REALTIME from <sys/time_impl.h>
        MOVQ    SP, SI
-       MOVQ    libc·clock_gettime(SB), AX
+       MOVQ    libc_clock_gettime(SB), AX
        CALL    AX
        MOVQ    (SP), AX        // tv_sec from struct timespec
        IMULQ   $1000000000, AX // multiply into nanoseconds
@@ -54,7 +54,7 @@ TEXT runtime·nanotime1(SB),NOSPLIT,$0
 TEXT runtime·pipe1(SB),NOSPLIT,$0
        SUBQ    $16, SP // 8 bytes will do, but stack has to be 16-byte alligned
        MOVQ    SP, DI
-       MOVQ    libc·pipe(SB), AX
+       MOVQ    libc_pipe(SB), AX
        CALL    AX
        MOVL    0(SP), AX
        MOVL    4(SP), DX
@@ -133,7 +133,7 @@ TEXT runtime·tstart_sysvicall(SB),NOSPLIT,$0
        MOVQ    AX, (g_stack+stack_hi)(DX)
        SUBQ    $(0x100000), AX         // stack size
        MOVQ    AX, (g_stack+stack_lo)(DX)
-       ADDQ    $const_StackGuard, AX
+       ADDQ    $const__StackGuard, AX
        MOVQ    AX, g_stackguard0(DX)
        MOVQ    AX, g_stackguard1(DX)
 
@@ -321,13 +321,13 @@ usleep1_noswitch:
 
 // Runs on OS stack. duration (in µs units) is in DI.
 TEXT runtime·usleep2(SB),NOSPLIT,$0
-       MOVQ    libc·usleep(SB), AX
+       MOVQ    libc_usleep(SB), AX
        CALL    AX
        RET
 
 // Runs on OS stack, called from runtime·osyield.
 TEXT runtime·osyield1(SB),NOSPLIT,$0
-       MOVQ    libc·sched_yield(SB), AX
+       MOVQ    libc_sched_yield(SB), AX
        CALL    AX
        RET
 
diff --git a/src/runtime/syscall2_solaris.go b/src/runtime/syscall2_solaris.go
new file mode 100644 (file)
index 0000000..f4ffa74
--- /dev/null
@@ -0,0 +1,47 @@
+// Copyright 2014 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 runtime
+
+import _ "unsafe"
+
+//go:cgo_import_dynamic libc_chdir chdir "libc.so"
+//go:cgo_import_dynamic libc_chroot chroot "libc.so"
+//go:cgo_import_dynamic libc_close close "libc.so"
+//go:cgo_import_dynamic libc_dlclose dlclose "libc.so"
+//go:cgo_import_dynamic libc_dlopen dlopen "libc.so"
+//go:cgo_import_dynamic libc_dlsym dlsym "libc.so"
+//go:cgo_import_dynamic libc_execve execve "libc.so"
+//go:cgo_import_dynamic libc_fcntl fcntl "libc.so"
+//go:cgo_import_dynamic libc_gethostname gethostname "libc.so"
+//go:cgo_import_dynamic libc_ioctl ioctl "libc.so"
+//go:cgo_import_dynamic libc_pipe pipe "libc.so"
+//go:cgo_import_dynamic libc_setgid setgid "libc.so"
+//go:cgo_import_dynamic libc_setgroups setgroups "libc.so"
+//go:cgo_import_dynamic libc_setsid setsid "libc.so"
+//go:cgo_import_dynamic libc_setuid setuid "libc.so"
+//go:cgo_import_dynamic libc_setpgid setsid "libc.so"
+//go:cgo_import_dynamic libc_syscall syscall "libc.so"
+//go:cgo_import_dynamic libc_forkx forkx "libc.so"
+//go:cgo_import_dynamic libc_wait4 wait4 "libc.so"
+
+//go:linkname libc_chdir libc_chdir
+//go:linkname libc_chroot libc_chroot
+//go:linkname libc_close libc_close
+//go:linkname libc_dlclose libc_dlclose
+//go:linkname libc_dlopen libc_dlopen
+//go:linkname libc_dlsym libc_dlsym
+//go:linkname libc_execve libc_execve
+//go:linkname libc_fcntl libc_fcntl
+//go:linkname libc_gethostname libc_gethostname
+//go:linkname libc_ioctl libc_ioctl
+//go:linkname libc_pipe libc_pipe
+//go:linkname libc_setgid libc_setgid
+//go:linkname libc_setgroups libc_setgroups
+//go:linkname libc_setsid libc_setsid
+//go:linkname libc_setuid libc_setuid
+//go:linkname libc_setpgid libc_setpgid
+//go:linkname libc_syscall libc_syscall
+//go:linkname libc_forkx libc_forkx
+//go:linkname libc_wait4 libc_wait4
diff --git a/src/runtime/syscall_solaris.c b/src/runtime/syscall_solaris.c
deleted file mode 100644 (file)
index 13ac31b..0000000
+++ /dev/null
@@ -1,23 +0,0 @@
-// Copyright 2014 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.
-
-#pragma dynimport libc·chdir chdir "libc.so"
-#pragma dynimport libc·chroot chroot "libc.so"
-#pragma dynimport libc·close close "libc.so"
-#pragma dynimport libc·dlclose dlclose "libc.so"
-#pragma dynimport libc·dlopen dlopen "libc.so"
-#pragma dynimport libc·dlsym dlsym "libc.so"
-#pragma dynimport libc·execve execve "libc.so"
-#pragma dynimport libc·fcntl fcntl "libc.so"
-#pragma dynimport libc·gethostname gethostname "libc.so"
-#pragma dynimport libc·ioctl ioctl "libc.so"
-#pragma dynimport libc·pipe pipe "libc.so"
-#pragma dynimport libc·setgid setgid "libc.so"
-#pragma dynimport libc·setgroups setgroups "libc.so"
-#pragma dynimport libc·setsid setsid "libc.so"
-#pragma dynimport libc·setuid setuid "libc.so"
-#pragma dynimport libc·setpgid setsid "libc.so"
-#pragma dynimport libc·syscall syscall "libc.so"
-#pragma dynimport libc·forkx forkx "libc.so"
-#pragma dynimport libc·wait4 wait4 "libc.so"
index 50d3a1d36dc0c41ac2d861ce2785d496c78c4cdd..9b9971674797b12a8ac6699350eb68c9849f3520 100644 (file)
@@ -9,12 +9,10 @@ import "unsafe"
 var (
        libc_chdir,
        libc_chroot,
-       libc_close,
        libc_dlopen,
        libc_dlclose,
        libc_dlsym,
        libc_execve,
-       libc_exit,
        libc_fcntl,
        libc_forkx,
        libc_gethostname,
@@ -27,7 +25,6 @@ var (
        libc_setpgid,
        libc_syscall,
        libc_wait4,
-       libc_write,
        pipe1 libcFunc
 )
 
@@ -38,9 +35,9 @@ func syscall_sysvicall6(fn, nargs, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2, err
                n:    nargs,
                args: uintptr(unsafe.Pointer(&a1)),
        }
-       entersyscallblock()
+       entersyscallblock(0)
        asmcgocall(unsafe.Pointer(&asmsysvicall6), unsafe.Pointer(&call))
-       exitsyscall()
+       exitsyscall(0)
        return call.r1, call.r2, call.err
 }
 
@@ -62,7 +59,7 @@ func syscall_rawsysvicall6(fn, nargs, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2, e
 //go:nosplit
 func syscall_chdir(path uintptr) (err uintptr) {
        call := libcall{
-               fn:   uintptr(unsafe.Pointer(&libc_chdir)),
+               fn:   uintptr(unsafe.Pointer(libc_chdir)),
                n:    1,
                args: uintptr(unsafe.Pointer(&path)),
        }
@@ -73,7 +70,7 @@ func syscall_chdir(path uintptr) (err uintptr) {
 //go:nosplit
 func syscall_chroot(path uintptr) (err uintptr) {
        call := libcall{
-               fn:   uintptr(unsafe.Pointer(&libc_chroot)),
+               fn:   uintptr(unsafe.Pointer(libc_chroot)),
                n:    1,
                args: uintptr(unsafe.Pointer(&path)),
        }
@@ -84,18 +81,18 @@ func syscall_chroot(path uintptr) (err uintptr) {
 // like close, but must not split stack, for forkx.
 //go:nosplit
 func syscall_close(fd int32) int32 {
-       return int32(sysvicall1(&libc_close, uintptr(fd)))
+       return int32(sysvicall1(libc_close, uintptr(fd)))
 }
 
 func syscall_dlopen(name *byte, mode uintptr) (handle uintptr, err uintptr) {
        call := libcall{
-               fn:   uintptr(unsafe.Pointer(&libc_dlopen)),
+               fn:   uintptr(unsafe.Pointer(libc_dlopen)),
                n:    2,
                args: uintptr(unsafe.Pointer(&name)),
        }
-       entersyscallblock()
+       entersyscallblock(0)
        asmcgocall(unsafe.Pointer(&asmsysvicall6), unsafe.Pointer(&call))
-       exitsyscall()
+       exitsyscall(0)
        if call.r1 == 0 {
                return call.r1, call.err
        }
@@ -104,25 +101,25 @@ func syscall_dlopen(name *byte, mode uintptr) (handle uintptr, err uintptr) {
 
 func syscall_dlclose(handle uintptr) (err uintptr) {
        call := libcall{
-               fn:   uintptr(unsafe.Pointer(&libc_dlclose)),
+               fn:   uintptr(unsafe.Pointer(libc_dlclose)),
                n:    1,
                args: uintptr(unsafe.Pointer(&handle)),
        }
-       entersyscallblock()
+       entersyscallblock(0)
        asmcgocall(unsafe.Pointer(&asmsysvicall6), unsafe.Pointer(&call))
-       exitsyscall()
+       exitsyscall(0)
        return call.r1
 }
 
 func syscall_dlsym(handle uintptr, name *byte) (proc uintptr, err uintptr) {
        call := libcall{
-               fn:   uintptr(unsafe.Pointer(&libc_dlsym)),
+               fn:   uintptr(unsafe.Pointer(libc_dlsym)),
                n:    2,
                args: uintptr(unsafe.Pointer(&handle)),
        }
-       entersyscallblock()
+       entersyscallblock(0)
        asmcgocall(unsafe.Pointer(&asmsysvicall6), unsafe.Pointer(&call))
-       exitsyscall()
+       exitsyscall(0)
        if call.r1 == 0 {
                return call.r1, call.err
        }
@@ -132,7 +129,7 @@ func syscall_dlsym(handle uintptr, name *byte) (proc uintptr, err uintptr) {
 //go:nosplit
 func syscall_execve(path, argv, envp uintptr) (err uintptr) {
        call := libcall{
-               fn:   uintptr(unsafe.Pointer(&libc_execve)),
+               fn:   uintptr(unsafe.Pointer(libc_execve)),
                n:    3,
                args: uintptr(unsafe.Pointer(&path)),
        }
@@ -143,13 +140,13 @@ func syscall_execve(path, argv, envp uintptr) (err uintptr) {
 // like exit, but must not split stack, for forkx.
 //go:nosplit
 func syscall_exit(code uintptr) {
-       sysvicall1(&libc_exit, code)
+       sysvicall1(libc_exit, code)
 }
 
 //go:nosplit
 func syscall_fcntl(fd, cmd, arg uintptr) (val, err uintptr) {
        call := libcall{
-               fn:   uintptr(unsafe.Pointer(&libc_fcntl)),
+               fn:   uintptr(unsafe.Pointer(libc_fcntl)),
                n:    3,
                args: uintptr(unsafe.Pointer(&fd)),
        }
@@ -160,7 +157,7 @@ func syscall_fcntl(fd, cmd, arg uintptr) (val, err uintptr) {
 //go:nosplit
 func syscall_forkx(flags uintptr) (pid uintptr, err uintptr) {
        call := libcall{
-               fn:   uintptr(unsafe.Pointer(&libc_forkx)),
+               fn:   uintptr(unsafe.Pointer(libc_forkx)),
                n:    1,
                args: uintptr(unsafe.Pointer(&flags)),
        }
@@ -172,13 +169,13 @@ func syscall_gethostname() (name string, err uintptr) {
        cname := new([_MAXHOSTNAMELEN]byte)
        var args = [2]uintptr{uintptr(unsafe.Pointer(&cname[0])), _MAXHOSTNAMELEN}
        call := libcall{
-               fn:   uintptr(unsafe.Pointer(&libc_gethostname)),
+               fn:   uintptr(unsafe.Pointer(libc_gethostname)),
                n:    2,
                args: uintptr(unsafe.Pointer(&args[0])),
        }
-       entersyscallblock()
+       entersyscallblock(0)
        asmcgocall(unsafe.Pointer(&asmsysvicall6), unsafe.Pointer(&call))
-       exitsyscall()
+       exitsyscall(0)
        if call.r1 != 0 {
                return "", call.err
        }
@@ -189,7 +186,7 @@ func syscall_gethostname() (name string, err uintptr) {
 //go:nosplit
 func syscall_ioctl(fd, req, arg uintptr) (err uintptr) {
        call := libcall{
-               fn:   uintptr(unsafe.Pointer(&libc_ioctl)),
+               fn:   uintptr(unsafe.Pointer(libc_ioctl)),
                n:    3,
                args: uintptr(unsafe.Pointer(&fd)),
        }
@@ -203,9 +200,9 @@ func syscall_pipe() (r, w, err uintptr) {
                n:    0,
                args: uintptr(unsafe.Pointer(&pipe1)), // it's unused but must be non-nil, otherwise crashes
        }
-       entersyscallblock()
+       entersyscallblock(0)
        asmcgocall(unsafe.Pointer(&asmsysvicall6), unsafe.Pointer(&call))
-       exitsyscall()
+       exitsyscall(0)
        return call.r1, call.r2, call.err
 }
 
@@ -217,7 +214,7 @@ func syscall_pipe() (r, w, err uintptr) {
 // TODO(aram): make this panic once we stop calling fcntl(2) in net using it.
 func syscall_rawsyscall(trap, a1, a2, a3 uintptr) (r1, r2, err uintptr) {
        call := libcall{
-               fn:   uintptr(unsafe.Pointer(&libc_syscall)),
+               fn:   uintptr(unsafe.Pointer(libc_syscall)),
                n:    4,
                args: uintptr(unsafe.Pointer(&trap)),
        }
@@ -228,7 +225,7 @@ func syscall_rawsyscall(trap, a1, a2, a3 uintptr) (r1, r2, err uintptr) {
 //go:nosplit
 func syscall_setgid(gid uintptr) (err uintptr) {
        call := libcall{
-               fn:   uintptr(unsafe.Pointer(&libc_setgid)),
+               fn:   uintptr(unsafe.Pointer(libc_setgid)),
                n:    1,
                args: uintptr(unsafe.Pointer(&gid)),
        }
@@ -239,7 +236,7 @@ func syscall_setgid(gid uintptr) (err uintptr) {
 //go:nosplit
 func syscall_setgroups(ngid, gid uintptr) (err uintptr) {
        call := libcall{
-               fn:   uintptr(unsafe.Pointer(&libc_setgroups)),
+               fn:   uintptr(unsafe.Pointer(libc_setgroups)),
                n:    2,
                args: uintptr(unsafe.Pointer(&ngid)),
        }
@@ -250,9 +247,9 @@ func syscall_setgroups(ngid, gid uintptr) (err uintptr) {
 //go:nosplit
 func syscall_setsid() (pid, err uintptr) {
        call := libcall{
-               fn:   uintptr(unsafe.Pointer(&libc_setsid)),
+               fn:   uintptr(unsafe.Pointer(libc_setsid)),
                n:    0,
-               args: uintptr(unsafe.Pointer(&libc_setsid)), // it's unused but must be non-nil, otherwise crashes
+               args: uintptr(unsafe.Pointer(libc_setsid)), // it's unused but must be non-nil, otherwise crashes
        }
        asmcgocall(unsafe.Pointer(&asmsysvicall6), unsafe.Pointer(&call))
        return call.r1, call.err
@@ -261,7 +258,7 @@ func syscall_setsid() (pid, err uintptr) {
 //go:nosplit
 func syscall_setuid(uid uintptr) (err uintptr) {
        call := libcall{
-               fn:   uintptr(unsafe.Pointer(&libc_setuid)),
+               fn:   uintptr(unsafe.Pointer(libc_setuid)),
                n:    1,
                args: uintptr(unsafe.Pointer(&uid)),
        }
@@ -272,7 +269,7 @@ func syscall_setuid(uid uintptr) (err uintptr) {
 //go:nosplit
 func syscall_setpgid(pid, pgid uintptr) (err uintptr) {
        call := libcall{
-               fn:   uintptr(unsafe.Pointer(&libc_setpgid)),
+               fn:   uintptr(unsafe.Pointer(libc_setpgid)),
                n:    2,
                args: uintptr(unsafe.Pointer(&pid)),
        }
@@ -288,32 +285,32 @@ func syscall_setpgid(pid, pgid uintptr) (err uintptr) {
 // TODO(aram): make this panic once we stop calling fcntl(2) in net using it.
 func syscall_syscall(trap, a1, a2, a3 uintptr) (r1, r2, err uintptr) {
        call := libcall{
-               fn:   uintptr(unsafe.Pointer(&libc_syscall)),
+               fn:   uintptr(unsafe.Pointer(libc_syscall)),
                n:    4,
                args: uintptr(unsafe.Pointer(&trap)),
        }
-       entersyscallblock()
+       entersyscallblock(0)
        asmcgocall(unsafe.Pointer(&asmsysvicall6), unsafe.Pointer(&call))
-       exitsyscall()
+       exitsyscall(0)
        return call.r1, call.r2, call.err
 }
 
 func syscall_wait4(pid uintptr, wstatus *uint32, options uintptr, rusage unsafe.Pointer) (wpid int, err uintptr) {
        call := libcall{
-               fn:   uintptr(unsafe.Pointer(&libc_wait4)),
+               fn:   uintptr(unsafe.Pointer(libc_wait4)),
                n:    4,
                args: uintptr(unsafe.Pointer(&pid)),
        }
-       entersyscallblock()
+       entersyscallblock(0)
        asmcgocall(unsafe.Pointer(&asmsysvicall6), unsafe.Pointer(&call))
-       exitsyscall()
+       exitsyscall(0)
        return int(call.r1), call.err
 }
 
 //go:nosplit
 func syscall_write(fd, buf, nbyte uintptr) (n, err uintptr) {
        call := libcall{
-               fn:   uintptr(unsafe.Pointer(&libc_write)),
+               fn:   uintptr(unsafe.Pointer(libc_write)),
                n:    3,
                args: uintptr(unsafe.Pointer(&fd)),
        }
diff --git a/src/runtime/thunk_solaris_amd64.s b/src/runtime/thunk_solaris_amd64.s
deleted file mode 100644 (file)
index 1dc9e74..0000000
+++ /dev/null
@@ -1,89 +0,0 @@
-// Copyright 2014 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.
-
-// This file exposes various external library functions to Go code in the runtime.
-
-#include "go_asm.h"
-#include "go_tls.h"
-#include "textflag.h"
-
-TEXT runtime·libc_chdir(SB),NOSPLIT,$0
-       MOVQ    libc·chdir(SB), AX
-       JMP     AX
-
-TEXT runtime·libc_chroot(SB),NOSPLIT,$0
-       MOVQ    libc·chroot(SB), AX
-       JMP     AX
-
-TEXT runtime·libc_close(SB),NOSPLIT,$0
-       MOVQ    libc·close(SB), AX
-       JMP     AX
-
-TEXT runtime·libc_dlopen(SB),NOSPLIT,$0
-       MOVQ    libc·dlopen(SB), AX
-       JMP     AX
-
-TEXT runtime·libc_dlclose(SB),NOSPLIT,$0
-       MOVQ    libc·dlclose(SB), AX
-       JMP     AX
-
-TEXT runtime·libc_dlsym(SB),NOSPLIT,$0
-       MOVQ    libc·dlsym(SB), AX
-       JMP     AX
-
-TEXT runtime·libc_execve(SB),NOSPLIT,$0
-       MOVQ    libc·execve(SB), AX
-       JMP     AX
-
-TEXT runtime·libc_exit(SB),NOSPLIT,$0
-       MOVQ    libc·exit(SB), AX
-       JMP     AX
-
-TEXT runtime·libc_fcntl(SB),NOSPLIT,$0
-       MOVQ    libc·fcntl(SB), AX
-       JMP     AX
-
-TEXT runtime·libc_forkx(SB),NOSPLIT,$0
-       MOVQ    libc·forkx(SB), AX
-       JMP     AX
-
-TEXT runtime·libc_gethostname(SB),NOSPLIT,$0
-       MOVQ    libc·gethostname(SB), AX
-       JMP     AX
-
-TEXT runtime·libc_ioctl(SB),NOSPLIT,$0
-       MOVQ    libc·ioctl(SB), AX
-       JMP     AX
-
-TEXT runtime·libc_setgid(SB),NOSPLIT,$0
-       MOVQ    libc·setgid(SB), AX
-       JMP     AX
-
-TEXT runtime·libc_setgroups(SB),NOSPLIT,$0
-       MOVQ    libc·setgroups(SB), AX
-       JMP     AX
-
-TEXT runtime·libc_setsid(SB),NOSPLIT,$0
-       MOVQ    libc·setsid(SB), AX
-       JMP     AX
-
-TEXT runtime·libc_setuid(SB),NOSPLIT,$0
-       MOVQ    libc·setuid(SB), AX
-       JMP     AX
-
-TEXT runtime·libc_setpgid(SB),NOSPLIT,$0
-       MOVQ    libc·setpgid(SB), AX
-       JMP     AX
-
-TEXT runtime·libc_syscall(SB),NOSPLIT,$0
-       MOVQ    libc·syscall(SB), AX
-       JMP     AX
-
-TEXT runtime·libc_wait4(SB),NOSPLIT,$0
-       MOVQ    libc·wait4(SB), AX
-       JMP     AX
-
-TEXT runtime·libc_write(SB),NOSPLIT,$0
-       MOVQ    libc·write(SB), AX
-       JMP     AX