diff --git a/src/pkg/runtime/netpoll_solaris.c b/src/pkg/runtime/netpoll_solaris.c index 569aee52d4..d422719cf1 100644 --- a/src/pkg/runtime/netpoll_solaris.c +++ b/src/pkg/runtime/netpoll_solaris.c @@ -84,35 +84,31 @@ extern uintptr libc·port_getn; int32 runtime·fcntl(int32 fd, int32 cmd, uintptr arg) { - return runtime·sysvicall6(libc·fcntl, 3, - (uintptr)fd, (uintptr)cmd, (uintptr)arg); + return runtime·sysvicall3(libc·fcntl, (uintptr)fd, (uintptr)cmd, (uintptr)arg); } int32 runtime·port_create(void) { - return runtime·sysvicall6(libc·port_create, 0); + return runtime·sysvicall0(libc·port_create); } int32 runtime·port_associate(int32 port, int32 source, uintptr object, int32 events, uintptr user) { - return runtime·sysvicall6(libc·port_associate, - 5, (uintptr)port, (uintptr)source, object, (uintptr)events, user); + return runtime·sysvicall5(libc·port_associate, (uintptr)port, (uintptr)source, object, (uintptr)events, user); } int32 runtime·port_dissociate(int32 port, int32 source, uintptr object) { - return runtime·sysvicall6(libc·port_dissociate, - 3, (uintptr)port, (uintptr)source, object); + return runtime·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·sysvicall6(libc·port_getn, 5, (uintptr)port, - (uintptr)evs, (uintptr)max, (uintptr)nget, (uintptr)timeout); + return runtime·sysvicall5(libc·port_getn, (uintptr)port, (uintptr)evs, (uintptr)max, (uintptr)nget, (uintptr)timeout); } static int32 portfd = -1; diff --git a/src/pkg/runtime/os_solaris.c b/src/pkg/runtime/os_solaris.c index 272e07cdb5..0cdfd52c9b 100644 --- a/src/pkg/runtime/os_solaris.c +++ b/src/pkg/runtime/os_solaris.c @@ -97,21 +97,6 @@ extern SigTab runtime·sigtab[]; static Sigset sigset_none; static Sigset sigset_all = { ~(uint32)0, ~(uint32)0, ~(uint32)0, ~(uint32)0, }; -// Calling sysvcall on os stack. -#pragma textflag NOSPLIT -uintptr -runtime·sysvicall6(uintptr fn, int32 count, ...) -{ - runtime·memclr((byte*)&g->m->scratch, sizeof(g->m->scratch)); - g->m->libcall.fn = (void*)fn; - g->m->libcall.n = (uintptr)count; - for(;count; count--) - g->m->scratch.v[count - 1] = *((uintptr*)&count + count); - g->m->libcall.args = (uintptr*)&g->m->scratch.v[0]; - runtime·asmcgocall(runtime·asmsysvicall6, &g->m->libcall); - return g->m->libcall.r1; -} - static int32 getncpu(void) { @@ -403,37 +388,37 @@ runtime·semawakeup(M *mp) int32 runtime·close(int32 fd) { - return runtime·sysvicall6(libc·close, 1, (uintptr)fd); + return runtime·sysvicall1(libc·close, (uintptr)fd); } void runtime·exit(int32 r) { - runtime·sysvicall6(libc·exit, 1, (uintptr)r); + runtime·sysvicall1(libc·exit, (uintptr)r); } /* int32 */ void runtime·getcontext(Ucontext* context) { - runtime·sysvicall6(libc·getcontext, 1, (uintptr)context); + runtime·sysvicall1(libc·getcontext, (uintptr)context); } int32 runtime·getrlimit(int32 res, Rlimit* rlp) { - return runtime·sysvicall6(libc·getrlimit, 2, (uintptr)res, (uintptr)rlp); + return runtime·sysvicall2(libc·getrlimit, (uintptr)res, (uintptr)rlp); } uint8* runtime·mmap(byte* addr, uintptr len, int32 prot, int32 flags, int32 fildes, uint32 off) { - return (uint8*)runtime·sysvicall6(libc·mmap, 6, (uintptr)addr, (uintptr)len, (uintptr)prot, (uintptr)flags, (uintptr)fildes, (uintptr)off); + return (uint8*)runtime·sysvicall6(libc·mmap, (uintptr)addr, (uintptr)len, (uintptr)prot, (uintptr)flags, (uintptr)fildes, (uintptr)off); } void runtime·munmap(byte* addr, uintptr len) { - runtime·sysvicall6(libc·munmap, 2, (uintptr)addr, (uintptr)len); + runtime·sysvicall2(libc·munmap, (uintptr)addr, (uintptr)len); } extern int64 runtime·nanotime1(void); @@ -441,7 +426,7 @@ extern int64 runtime·nanotime1(void); int64 runtime·nanotime(void) { - return runtime·sysvicall6((uintptr)runtime·nanotime1, 0); + return runtime·sysvicall0((uintptr)runtime·nanotime1); } void @@ -459,113 +444,113 @@ time·now(int64 sec, int32 usec) int32 runtime·open(int8* path, int32 oflag, int32 mode) { - return runtime·sysvicall6(libc·open, 3, (uintptr)path, (uintptr)oflag, (uintptr)mode); + return runtime·sysvicall3(libc·open, (uintptr)path, (uintptr)oflag, (uintptr)mode); } int32 runtime·pthread_attr_destroy(PthreadAttr* attr) { - return runtime·sysvicall6(libc·pthread_attr_destroy, 1, (uintptr)attr); + return runtime·sysvicall1(libc·pthread_attr_destroy, (uintptr)attr); } int32 runtime·pthread_attr_getstack(PthreadAttr* attr, void** addr, uint64* size) { - return runtime·sysvicall6(libc·pthread_attr_getstack, 3, (uintptr)attr, (uintptr)addr, (uintptr)size); + return runtime·sysvicall3(libc·pthread_attr_getstack, (uintptr)attr, (uintptr)addr, (uintptr)size); } int32 runtime·pthread_attr_init(PthreadAttr* attr) { - return runtime·sysvicall6(libc·pthread_attr_init, 1, (uintptr)attr); + return runtime·sysvicall1(libc·pthread_attr_init, (uintptr)attr); } int32 runtime·pthread_attr_setdetachstate(PthreadAttr* attr, int32 state) { - return runtime·sysvicall6(libc·pthread_attr_setdetachstate, 2, (uintptr)attr, (uintptr)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·sysvicall6(libc·pthread_attr_setstack, 3, (uintptr)attr, (uintptr)addr, (uintptr)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·sysvicall6(libc·pthread_create, 4, (uintptr)thread, (uintptr)attr, (uintptr)fn, (uintptr)arg); + return runtime·sysvicall4(libc·pthread_create, (uintptr)thread, (uintptr)attr, (uintptr)fn, (uintptr)arg); } /* int32 */ void runtime·raise(int32 sig) { - runtime·sysvicall6(libc·raise, 1, (uintptr)sig); + runtime·sysvicall1(libc·raise, (uintptr)sig); } int32 runtime·read(int32 fd, void* buf, int32 nbyte) { - return runtime·sysvicall6(libc·read, 3, (uintptr)fd, (uintptr)buf, (uintptr)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·sysvicall6(libc·sem_init, 3, (uintptr)sem, (uintptr)pshared, (uintptr)value); + return runtime·sysvicall3(libc·sem_init, (uintptr)sem, (uintptr)pshared, (uintptr)value); } #pragma textflag NOSPLIT int32 runtime·sem_post(SemT* sem) { - return runtime·sysvicall6(libc·sem_post, 1, (uintptr)sem); + return runtime·sysvicall1(libc·sem_post, (uintptr)sem); } #pragma textflag NOSPLIT int32 runtime·sem_reltimedwait_np(SemT* sem, Timespec* timeout) { - return runtime·sysvicall6(libc·sem_reltimedwait_np, 2, (uintptr)sem, (uintptr)timeout); + return runtime·sysvicall2(libc·sem_reltimedwait_np, (uintptr)sem, (uintptr)timeout); } #pragma textflag NOSPLIT int32 runtime·sem_wait(SemT* sem) { - return runtime·sysvicall6(libc·sem_wait, 1, (uintptr)sem); + return runtime·sysvicall1(libc·sem_wait, (uintptr)sem); } /* int32 */ void runtime·setitimer(int32 which, Itimerval* value, Itimerval* ovalue) { - runtime·sysvicall6(libc·setitimer, 3, (uintptr)which, (uintptr)value, (uintptr)ovalue); + runtime·sysvicall3(libc·setitimer, (uintptr)which, (uintptr)value, (uintptr)ovalue); } /* int32 */ void runtime·sigaction(int32 sig, struct Sigaction* act, struct Sigaction* oact) { - runtime·sysvicall6(libc·sigaction, 3, (uintptr)sig, (uintptr)act, (uintptr)oact); + runtime·sysvicall3(libc·sigaction, (uintptr)sig, (uintptr)act, (uintptr)oact); } /* int32 */ void runtime·sigaltstack(Sigaltstack* ss, Sigaltstack* oss) { - runtime·sysvicall6(libc·sigaltstack, 2, (uintptr)ss, (uintptr)oss); + runtime·sysvicall2(libc·sigaltstack, (uintptr)ss, (uintptr)oss); } /* int32 */ void runtime·sigprocmask(int32 how, Sigset* set, Sigset* oset) { - runtime·sysvicall6(libc·sigprocmask, 3, (uintptr)how, (uintptr)set, (uintptr)oset); + runtime·sysvicall3(libc·sigprocmask, (uintptr)how, (uintptr)set, (uintptr)oset); } int64 runtime·sysconf(int32 name) { - return runtime·sysvicall6(libc·sysconf, 1, (uintptr)name); + return runtime·sysvicall1(libc·sysconf, (uintptr)name); } extern void runtime·usleep1(uint32); @@ -580,7 +565,7 @@ runtime·usleep(uint32 µs) int32 runtime·write(uintptr fd, void* buf, int32 nbyte) { - return runtime·sysvicall6(libc·write, 3, (uintptr)fd, (uintptr)buf, (uintptr)nbyte); + return runtime·sysvicall3(libc·write, (uintptr)fd, (uintptr)buf, (uintptr)nbyte); } extern void runtime·osyield1(void); @@ -592,7 +577,7 @@ 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·sysvicall6(libc·sched_yield, 0); + runtime·sysvicall0(libc·sched_yield); return; } runtime·osyield1(); diff --git a/src/pkg/runtime/os_solaris.go b/src/pkg/runtime/os_solaris.go index 72528c7997..7bc42ef52d 100644 --- a/src/pkg/runtime/os_solaris.go +++ b/src/pkg/runtime/os_solaris.go @@ -12,7 +12,6 @@ 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 asmsysvicall6(fn unsafe.Pointer) func miniterrno(fn unsafe.Pointer) func raise(sig int32) func getcontext(ctxt unsafe.Pointer) @@ -20,3 +19,77 @@ func tstart_sysvicall(mm unsafe.Pointer) uint32 func nanotime1() int64 func usleep1(usec uint32) func osyield1() + +type libcFunc byte + +var asmsysvicall6 libcFunc + +//go:nosplit +func sysvicall0(fn *libcFunc) uintptr { + libcall := &getg().m.libcall + libcall.fn = unsafe.Pointer(fn) + libcall.n = 0 + libcall.args = unsafe.Pointer(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 { + libcall := &getg().m.libcall + libcall.fn = unsafe.Pointer(fn) + libcall.n = 1 + libcall.args = noescape(unsafe.Pointer(&a1)) + asmcgocall(unsafe.Pointer(&asmsysvicall6), unsafe.Pointer(libcall)) + return libcall.r1 +} + +//go:nosplit +func sysvicall2(fn *libcFunc, a1, a2 uintptr) uintptr { + libcall := &getg().m.libcall + libcall.fn = unsafe.Pointer(fn) + libcall.n = 2 + libcall.args = noescape(unsafe.Pointer(&a1)) + asmcgocall(unsafe.Pointer(&asmsysvicall6), unsafe.Pointer(libcall)) + return libcall.r1 +} + +//go:nosplit +func sysvicall3(fn *libcFunc, a1, a2, a3 uintptr) uintptr { + libcall := &getg().m.libcall + libcall.fn = unsafe.Pointer(fn) + libcall.n = 3 + libcall.args = noescape(unsafe.Pointer(&a1)) + asmcgocall(unsafe.Pointer(&asmsysvicall6), unsafe.Pointer(libcall)) + return libcall.r1 +} + +//go:nosplit +func sysvicall4(fn *libcFunc, a1, a2, a3, a4 uintptr) uintptr { + libcall := &getg().m.libcall + libcall.fn = unsafe.Pointer(fn) + libcall.n = 4 + libcall.args = noescape(unsafe.Pointer(&a1)) + asmcgocall(unsafe.Pointer(&asmsysvicall6), unsafe.Pointer(libcall)) + return libcall.r1 +} + +//go:nosplit +func sysvicall5(fn *libcFunc, a1, a2, a3, a4, a5 uintptr) uintptr { + libcall := &getg().m.libcall + libcall.fn = unsafe.Pointer(fn) + libcall.n = 5 + libcall.args = noescape(unsafe.Pointer(&a1)) + asmcgocall(unsafe.Pointer(&asmsysvicall6), unsafe.Pointer(libcall)) + return libcall.r1 +} + +//go:nosplit +func sysvicall6(fn *libcFunc, a1, a2, a3, a4, a5, a6 uintptr) uintptr { + libcall := &getg().m.libcall + libcall.fn = unsafe.Pointer(fn) + libcall.n = 6 + libcall.args = noescape(unsafe.Pointer(&a1)) + asmcgocall(unsafe.Pointer(&asmsysvicall6), unsafe.Pointer(libcall)) + return libcall.r1 +} diff --git a/src/pkg/runtime/os_solaris.h b/src/pkg/runtime/os_solaris.h index f3fae5da2a..355cdf5589 100644 --- a/src/pkg/runtime/os_solaris.h +++ b/src/pkg/runtime/os_solaris.h @@ -40,12 +40,15 @@ struct Rlimit { }; int32 runtime·getrlimit(int32, Rlimit*); -// Call a library function with SysV conventions, -// and switch to os stack during the call. -#pragma varargck countpos runtime·sysvicall6 2 -#pragma varargck type runtime·sysvicall6 uintptr -#pragma varargck type runtime·sysvicall6 int32 +// 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); -uintptr runtime·sysvicall6(uintptr fn, int32 count, ...); void runtime·miniterrno(void *fn); diff --git a/src/pkg/runtime/runtime.h b/src/pkg/runtime/runtime.h index 21ccb76b3c..27b945e979 100644 --- a/src/pkg/runtime/runtime.h +++ b/src/pkg/runtime/runtime.h @@ -248,7 +248,7 @@ struct GCStats struct LibCall { - void (*fn)(void*); + void* fn; uintptr n; // number of parameters void* args; // parameters uintptr r1; // return values