From e088e16256a00447c6d5cded22ceb62bcdcc4698 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Aram=20H=C4=83v=C4=83rneanu?= Date: Thu, 13 Nov 2014 16:07:10 +0100 Subject: [PATCH] [dev.cc] runtime: convert Solaris port to Go 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 --- src/liblink/asm6.c | 5 +- src/runtime/defs1_solaris_amd64.go | 5 + src/runtime/mem_bsd.go | 2 +- src/runtime/mem_solaris.c | 101 ---- src/runtime/netpoll.go | 50 +- .../{netpoll_solaris.c => netpoll_solaris.go} | 259 ++++---- src/runtime/os2_solaris.go | 13 + src/runtime/os3_solaris.go | 493 ++++++++++++++++ src/runtime/os_solaris.c | 557 ------------------ src/runtime/os_solaris.go | 52 +- src/runtime/os_solaris.h | 55 -- src/runtime/signal_solaris.go | 88 +++ src/runtime/signal_solaris_amd64.go | 46 ++ src/runtime/signal_solaris_amd64.h | 31 - src/runtime/signals_solaris.h | 97 --- src/runtime/stubs.go | 14 - src/runtime/stubs2.go | 27 + src/runtime/sys_solaris_amd64.s | 12 +- src/runtime/syscall2_solaris.go | 47 ++ src/runtime/syscall_solaris.c | 23 - src/runtime/syscall_solaris.go | 79 ++- src/runtime/thunk_solaris_amd64.s | 89 --- 22 files changed, 914 insertions(+), 1231 deletions(-) delete mode 100644 src/runtime/mem_solaris.c rename src/runtime/{netpoll_solaris.c => netpoll_solaris.go} (55%) create mode 100644 src/runtime/os2_solaris.go create mode 100644 src/runtime/os3_solaris.go delete mode 100644 src/runtime/os_solaris.c delete mode 100644 src/runtime/os_solaris.h create mode 100644 src/runtime/signal_solaris.go create mode 100644 src/runtime/signal_solaris_amd64.go delete mode 100644 src/runtime/signal_solaris_amd64.h delete mode 100644 src/runtime/signals_solaris.h create mode 100644 src/runtime/stubs2.go create mode 100644 src/runtime/syscall2_solaris.go delete mode 100644 src/runtime/syscall_solaris.c delete mode 100644 src/runtime/thunk_solaris_amd64.s diff --git a/src/liblink/asm6.c b/src/liblink/asm6.c index 428eb9442b..7971022b56 100644 --- a/src/liblink/asm6.c +++ b/src/liblink/asm6.c @@ -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. diff --git a/src/runtime/defs1_solaris_amd64.go b/src/runtime/defs1_solaris_amd64.go index 280cf815f9..3bb6f69bf4 100644 --- a/src/runtime/defs1_solaris_amd64.go +++ b/src/runtime/defs1_solaris_amd64.go @@ -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 } diff --git a/src/runtime/mem_bsd.go b/src/runtime/mem_bsd.go index fffb350ed1..4bd40a39fc 100644 --- a/src/runtime/mem_bsd.go +++ b/src/runtime/mem_bsd.go @@ -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 index 8e90ba1d9e..0000000000 --- a/src/runtime/mem_solaris.c +++ /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"); -} diff --git a/src/runtime/netpoll.go b/src/runtime/netpoll.go index dd00b2a96d..7a99f18ad2 100644 --- a/src/runtime/netpoll.go +++ b/src/runtime/netpoll.go @@ -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 diff --git a/src/runtime/netpoll_solaris.c b/src/runtime/netpoll_solaris.go similarity index 55% rename from src/runtime/netpoll_solaris.c rename to src/runtime/netpoll_solaris.go index d422719cf1..40e8a1a651 100644 --- a/src/runtime/netpoll_solaris.c +++ b/src/runtime/netpoll_solaris.go @@ -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 @@ -68,179 +67,157 @@ // 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 index 0000000000..26ca15f628 --- /dev/null +++ b/src/runtime/os2_solaris.go @@ -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 index 0000000000..1df74faad2 --- /dev/null +++ b/src/runtime/os3_solaris.go @@ -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 index e16b8e6370..0000000000 --- a/src/runtime/os_solaris.c +++ /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; -} diff --git a/src/runtime/os_solaris.go b/src/runtime/os_solaris.go index ca13151204..6864ef9383 100644 --- a/src/runtime/os_solaris.go +++ b/src/runtime/os_solaris.go @@ -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 index 3d9e1a2406..0000000000 --- a/src/runtime/os_solaris.h +++ /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 index 0000000000..2986c5aabc --- /dev/null +++ b/src/runtime/signal_solaris.go @@ -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 index 0000000000..967835ad2c --- /dev/null +++ b/src/runtime/signal_solaris_amd64.go @@ -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 index c2e0a15497..0000000000 --- a/src/runtime/signal_solaris_amd64.h +++ /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 index 1f0a65ea62..0000000000 --- a/src/runtime/signals_solaris.h +++ /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 diff --git a/src/runtime/stubs.go b/src/runtime/stubs.go index bca0a1d7cd..217307a1ed 100644 --- a/src/runtime/stubs.go +++ b/src/runtime/stubs.go @@ -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 index 0000000000..526b3c5691 --- /dev/null +++ b/src/runtime/stubs2.go @@ -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) diff --git a/src/runtime/sys_solaris_amd64.s b/src/runtime/sys_solaris_amd64.s index 3b63b49888..5fe8387ead 100644 --- a/src/runtime/sys_solaris_amd64.s +++ b/src/runtime/sys_solaris_amd64.s @@ -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 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 index 0000000000..f4ffa74105 --- /dev/null +++ b/src/runtime/syscall2_solaris.go @@ -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 index 13ac31bde2..0000000000 --- a/src/runtime/syscall_solaris.c +++ /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" diff --git a/src/runtime/syscall_solaris.go b/src/runtime/syscall_solaris.go index 50d3a1d36d..9b99716747 100644 --- a/src/runtime/syscall_solaris.go +++ b/src/runtime/syscall_solaris.go @@ -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 index 1dc9e746d1..0000000000 --- a/src/runtime/thunk_solaris_amd64.s +++ /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 -- 2.48.1