1
0
mirror of https://github.com/golang/go synced 2024-11-12 09:20:22 -07:00

runtime: add support for GOOS=solaris

R=alex.brainman, dave, jsing, gobot, rsc
CC=golang-codereviews
https://golang.org/cl/35990043
This commit is contained in:
Aram Hăvărneanu 2014-01-17 17:58:10 +13:00 committed by Joel Sing
parent f8225bdb35
commit a46b434931
28 changed files with 2071 additions and 38 deletions

View File

@ -178,7 +178,7 @@ static struct {
"#define g(r) 0(GS)\n"
"#define m(r) 4(GS)\n"
},
{"amd64", "windows",
"#define get_tls(r) MOVQ 0x28(GS), r\n"
"#define g(r) 0(r)\n"
@ -190,6 +190,11 @@ static struct {
"#define m(r) 8(GS)\n"
"#define procid(r) 16(GS)\n"
},
{"amd64", "solaris",
"#define get_tls(r) MOVQ 0(FS), r\n"
"#define g(r) -16(r)(FS*1)\n"
"#define m(r) -8(r)(FS*1)\n"
},
// The TLS accessors here are defined here to use initial exec model.
// If the linker is not outputting a shared library, it will reduce
// the TLS accessors to the local exec model, effectively removing
@ -284,8 +289,8 @@ ok:
aggr = "p";
else if(streq(fields.p[1], "Gobuf"))
aggr = "gobuf";
else if(streq(fields.p[1], "WinCall"))
aggr = "wincall";
else if(streq(fields.p[1], "LibCall"))
aggr = "libcall";
else if(streq(fields.p[1], "WinCallbackContext"))
aggr = "cbctxt";
else if(streq(fields.p[1], "SEH"))

View File

@ -6,6 +6,10 @@ enum {
thechar = '6',
BigEndian = 0,
CacheLineSize = 64,
#ifdef GOOS_solaris
RuntimeGogoBytes = 80,
#else
RuntimeGogoBytes = 64,
#endif
PCQuantum = 1
};

View File

@ -53,6 +53,9 @@ needtls:
// skip TLS setup on Plan 9
CMPL runtime·isplan9(SB), $1
JEQ ok
// skip TLS setup on Solaris
CMPL runtime·issolaris(SB), $1
JEQ ok
LEAQ runtime·tls0(SB), DI
CALL runtime·settls(SB)
@ -614,10 +617,16 @@ TEXT runtime·asmcgocall(SB),NOSPLIT,$0-16
MOVQ m_g0(BP), SI
MOVQ g(CX), DI
CMPQ SI, DI
JEQ 4(PC)
JEQ nosave
MOVQ m_gsignal(BP), SI
CMPQ SI, DI
JEQ nosave
MOVQ m_g0(BP), SI
CALL gosave<>(SB)
MOVQ SI, g(CX)
MOVQ (g_sched+gobuf_sp)(SI), SP
nosave:
// Now on a scheduling stack (a pthread-created stack).
// Make sure we have enough room for 4 stack-backed fast-call

View File

@ -104,7 +104,7 @@ runtime·cgocall(void (*fn)(void*), void *arg)
return;
}
if(!runtime·iscgo && !Windows)
if(!runtime·iscgo && !Solaris && !Windows)
runtime·throw("cgocall unavailable");
if(fn == 0)

View File

@ -0,0 +1,156 @@
// Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// +build ignore
/*
Input to cgo.
GOARCH=amd64 go tool cgo -cdefs defs_solaris.go >defs_solaris_amd64.h
*/
package runtime
/*
#include <sys/types.h>
#include <sys/mman.h>
#include <sys/select.h>
#include <sys/siginfo.h>
#include <sys/signal.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <sys/ucontext.h>
#include <sys/regset.h>
#include <sys/unistd.h>
#include <sys/fork.h>
#include <sys/port.h>
#include <semaphore.h>
#include <errno.h>
#include <signal.h>
#include <pthread.h>
#include <netdb.h>
*/
import "C"
const (
EINTR = C.EINTR
EBADF = C.EBADF
EFAULT = C.EFAULT
EAGAIN = C.EAGAIN
ETIMEDOUT = C.ETIMEDOUT
EWOULDBLOCK = C.EWOULDBLOCK
EINPROGRESS = C.EINPROGRESS
PROT_NONE = C.PROT_NONE
PROT_READ = C.PROT_READ
PROT_WRITE = C.PROT_WRITE
PROT_EXEC = C.PROT_EXEC
MAP_ANON = C.MAP_ANON
MAP_PRIVATE = C.MAP_PRIVATE
MAP_FIXED = C.MAP_FIXED
MADV_FREE = C.MADV_FREE
SA_SIGINFO = C.SA_SIGINFO
SA_RESTART = C.SA_RESTART
SA_ONSTACK = C.SA_ONSTACK
SIGHUP = C.SIGHUP
SIGINT = C.SIGINT
SIGQUIT = C.SIGQUIT
SIGILL = C.SIGILL
SIGTRAP = C.SIGTRAP
SIGABRT = C.SIGABRT
SIGEMT = C.SIGEMT
SIGFPE = C.SIGFPE
SIGKILL = C.SIGKILL
SIGBUS = C.SIGBUS
SIGSEGV = C.SIGSEGV
SIGSYS = C.SIGSYS
SIGPIPE = C.SIGPIPE
SIGALRM = C.SIGALRM
SIGTERM = C.SIGTERM
SIGURG = C.SIGURG
SIGSTOP = C.SIGSTOP
SIGTSTP = C.SIGTSTP
SIGCONT = C.SIGCONT
SIGCHLD = C.SIGCHLD
SIGTTIN = C.SIGTTIN
SIGTTOU = C.SIGTTOU
SIGIO = C.SIGIO
SIGXCPU = C.SIGXCPU
SIGXFSZ = C.SIGXFSZ
SIGVTALRM = C.SIGVTALRM
SIGPROF = C.SIGPROF
SIGWINCH = C.SIGWINCH
SIGUSR1 = C.SIGUSR1
SIGUSR2 = C.SIGUSR2
FPE_INTDIV = C.FPE_INTDIV
FPE_INTOVF = C.FPE_INTOVF
FPE_FLTDIV = C.FPE_FLTDIV
FPE_FLTOVF = C.FPE_FLTOVF
FPE_FLTUND = C.FPE_FLTUND
FPE_FLTRES = C.FPE_FLTRES
FPE_FLTINV = C.FPE_FLTINV
FPE_FLTSUB = C.FPE_FLTSUB
BUS_ADRALN = C.BUS_ADRALN
BUS_ADRERR = C.BUS_ADRERR
BUS_OBJERR = C.BUS_OBJERR
SEGV_MAPERR = C.SEGV_MAPERR
SEGV_ACCERR = C.SEGV_ACCERR
ITIMER_REAL = C.ITIMER_REAL
ITIMER_VIRTUAL = C.ITIMER_VIRTUAL
ITIMER_PROF = C.ITIMER_PROF
_SC_NPROCESSORS_ONLN = C._SC_NPROCESSORS_ONLN
PTHREAD_CREATE_DETACHED = C.PTHREAD_CREATE_DETACHED
FORK_NOSIGCHLD = C.FORK_NOSIGCHLD
FORK_WAITPID = C.FORK_WAITPID
MAXHOSTNAMELEN = C.MAXHOSTNAMELEN
O_NONBLOCK = C.O_NONBLOCK
FD_CLOEXEC = C.FD_CLOEXEC
F_GETFL = C.F_GETFL
F_SETFL = C.F_SETFL
F_SETFD = C.F_SETFD
POLLIN = C.POLLIN
POLLOUT = C.POLLOUT
POLLHUP = C.POLLHUP
POLLERR = C.POLLERR
PORT_SOURCE_FD = C.PORT_SOURCE_FD
)
type SemT C.sem_t
type Sigaltstack C.struct_sigaltstack
type Sigset C.sigset_t
type StackT C.stack_t
type Siginfo C.siginfo_t
type Sigaction C.struct_sigaction
type Fpregset C.fpregset_t
type Mcontext C.mcontext_t
type Ucontext C.ucontext_t
type Timespec C.struct_timespec
type Timeval C.struct_timeval
type Itimerval C.struct_itimerval
type PortEvent C.port_event_t
type Pthread C.pthread_t
type PthreadAttr C.pthread_attr_t
// depends on Timespec, must appear below
type Stat C.struct_stat

View File

@ -0,0 +1,48 @@
// Copyright 2013 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// +build ignore
/*
Input to cgo.
GOARCH=amd64 go tool cgo -cdefs defs_solaris.go defs_solaris_amd64.go >defs_solaris_amd64.h
*/
package runtime
/*
#include <sys/types.h>
#include <sys/regset.h>
*/
import "C"
const (
REG_RDI = C.REG_RDI
REG_RSI = C.REG_RSI
REG_RDX = C.REG_RDX
REG_RCX = C.REG_RCX
REG_R8 = C.REG_R8
REG_R9 = C.REG_R9
REG_R10 = C.REG_R10
REG_R11 = C.REG_R11
REG_R12 = C.REG_R12
REG_R13 = C.REG_R13
REG_R14 = C.REG_R14
REG_R15 = C.REG_R15
REG_RBP = C.REG_RBP
REG_RBX = C.REG_RBX
REG_RAX = C.REG_RAX
REG_GS = C.REG_GS
REG_FS = C.REG_FS
REG_ES = C.REG_ES
REG_DS = C.REG_DS
REG_TRAPNO = C.REG_TRAPNO
REG_ERR = C.REG_ERR
REG_RIP = C.REG_RIP
REG_CS = C.REG_CS
REG_RFLAGS = C.REG_RFL
REG_RSP = C.REG_RSP
REG_SS = C.REG_SS
)

View File

@ -0,0 +1,254 @@
// Created by cgo -cdefs - DO NOT EDIT
// cgo -cdefs defs_solaris.go defs_solaris_amd64.go
enum {
EINTR = 0x4,
EBADF = 0x9,
EFAULT = 0xe,
EAGAIN = 0xb,
ETIMEDOUT = 0x91,
EWOULDBLOCK = 0xb,
EINPROGRESS = 0x96,
PROT_NONE = 0x0,
PROT_READ = 0x1,
PROT_WRITE = 0x2,
PROT_EXEC = 0x4,
MAP_ANON = 0x100,
MAP_PRIVATE = 0x2,
MAP_FIXED = 0x10,
MADV_FREE = 0x5,
SA_SIGINFO = 0x8,
SA_RESTART = 0x4,
SA_ONSTACK = 0x1,
SIGHUP = 0x1,
SIGINT = 0x2,
SIGQUIT = 0x3,
SIGILL = 0x4,
SIGTRAP = 0x5,
SIGABRT = 0x6,
SIGEMT = 0x7,
SIGFPE = 0x8,
SIGKILL = 0x9,
SIGBUS = 0xa,
SIGSEGV = 0xb,
SIGSYS = 0xc,
SIGPIPE = 0xd,
SIGALRM = 0xe,
SIGTERM = 0xf,
SIGURG = 0x15,
SIGSTOP = 0x17,
SIGTSTP = 0x18,
SIGCONT = 0x19,
SIGCHLD = 0x12,
SIGTTIN = 0x1a,
SIGTTOU = 0x1b,
SIGIO = 0x16,
SIGXCPU = 0x1e,
SIGXFSZ = 0x1f,
SIGVTALRM = 0x1c,
SIGPROF = 0x1d,
SIGWINCH = 0x14,
SIGUSR1 = 0x10,
SIGUSR2 = 0x11,
FPE_INTDIV = 0x1,
FPE_INTOVF = 0x2,
FPE_FLTDIV = 0x3,
FPE_FLTOVF = 0x4,
FPE_FLTUND = 0x5,
FPE_FLTRES = 0x6,
FPE_FLTINV = 0x7,
FPE_FLTSUB = 0x8,
BUS_ADRALN = 0x1,
BUS_ADRERR = 0x2,
BUS_OBJERR = 0x3,
SEGV_MAPERR = 0x1,
SEGV_ACCERR = 0x2,
ITIMER_REAL = 0x0,
ITIMER_VIRTUAL = 0x1,
ITIMER_PROF = 0x2,
_SC_NPROCESSORS_ONLN = 0xf,
PTHREAD_CREATE_DETACHED = 0x40,
FORK_NOSIGCHLD = 0x1,
FORK_WAITPID = 0x2,
MAXHOSTNAMELEN = 0x100,
O_NONBLOCK = 0x80,
FD_CLOEXEC = 0x1,
F_GETFL = 0x3,
F_SETFL = 0x4,
F_SETFD = 0x2,
POLLIN = 0x1,
POLLOUT = 0x4,
POLLHUP = 0x10,
POLLERR = 0x8,
PORT_SOURCE_FD = 0x4,
};
typedef struct SemT SemT;
typedef struct Sigaltstack Sigaltstack;
typedef struct Sigset Sigset;
typedef struct StackT StackT;
typedef struct Siginfo Siginfo;
typedef struct Sigaction Sigaction;
typedef struct Fpregset Fpregset;
typedef struct Mcontext Mcontext;
typedef struct Ucontext Ucontext;
typedef struct Timespec Timespec;
typedef struct Timeval Timeval;
typedef struct Itimerval Itimerval;
typedef struct PortEvent PortEvent;
typedef struct PthreadAttr PthreadAttr;
typedef struct Stat Stat;
#pragma pack on
struct SemT {
uint32 sem_count;
uint16 sem_type;
uint16 sem_magic;
uint64 sem_pad1[3];
uint64 sem_pad2[2];
};
struct Sigaltstack {
byte *ss_sp;
uint64 ss_size;
int32 ss_flags;
byte Pad_cgo_0[4];
};
struct Sigset {
uint32 __sigbits[4];
};
struct StackT {
byte *ss_sp;
uint64 ss_size;
int32 ss_flags;
byte Pad_cgo_0[4];
};
struct Siginfo {
int32 si_signo;
int32 si_code;
int32 si_errno;
int32 si_pad;
byte __data[240];
};
struct Sigaction {
int32 sa_flags;
byte Pad_cgo_0[4];
byte _funcptr[8];
Sigset sa_mask;
};
struct Fpregset {
byte fp_reg_set[528];
};
struct Mcontext {
int64 gregs[28];
Fpregset fpregs;
};
struct Ucontext {
uint64 uc_flags;
Ucontext *uc_link;
Sigset uc_sigmask;
StackT uc_stack;
byte Pad_cgo_0[8];
Mcontext uc_mcontext;
int64 uc_filler[5];
byte Pad_cgo_1[8];
};
struct Timespec {
int64 tv_sec;
int64 tv_nsec;
};
struct Timeval {
int64 tv_sec;
int64 tv_usec;
};
struct Itimerval {
Timeval it_interval;
Timeval it_value;
};
struct PortEvent {
int32 portev_events;
uint16 portev_source;
uint16 portev_pad;
uint64 portev_object;
byte *portev_user;
};
typedef uint32 Pthread;
struct PthreadAttr {
byte *__pthread_attrp;
};
struct Stat {
uint64 st_dev;
uint64 st_ino;
uint32 st_mode;
uint32 st_nlink;
uint32 st_uid;
uint32 st_gid;
uint64 st_rdev;
int64 st_size;
Timespec st_atim;
Timespec st_mtim;
Timespec st_ctim;
int32 st_blksize;
byte Pad_cgo_0[4];
int64 st_blocks;
int8 st_fstype[16];
};
#pragma pack off
// Created by cgo -cdefs - DO NOT EDIT
// cgo -cdefs defs_solaris.go defs_solaris_amd64.go
enum {
REG_RDI = 0x8,
REG_RSI = 0x9,
REG_RDX = 0xc,
REG_RCX = 0xd,
REG_R8 = 0x7,
REG_R9 = 0x6,
REG_R10 = 0x5,
REG_R11 = 0x4,
REG_R12 = 0x3,
REG_R13 = 0x2,
REG_R14 = 0x1,
REG_R15 = 0x0,
REG_RBP = 0xa,
REG_RBX = 0xb,
REG_RAX = 0xe,
REG_GS = 0x17,
REG_FS = 0x16,
REG_ES = 0x18,
REG_DS = 0x19,
REG_TRAPNO = 0xf,
REG_ERR = 0x10,
REG_RIP = 0x11,
REG_CS = 0x12,
REG_RFLAGS = 0x13,
REG_RSP = 0x14,
REG_SS = 0x15,
};

View File

@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// +build darwin dragonfly freebsd linux netbsd openbsd windows
// +build darwin dragonfly freebsd linux netbsd openbsd solaris windows
#include "runtime.h"

View File

@ -17,6 +17,20 @@
#define PTR_MASK ((1ull<<PTR_BITS)-1)
#define CNT_MASK (0ull-1)
#ifdef _64BIT
#ifdef GOOS_solaris
// SPARC64 and Solaris on AMD64 uses all 64 bits of virtual addresses.
// Use low-order three bits as ABA counter.
// http://docs.oracle.com/cd/E19120-01/open.solaris/816-5138/6mba6ua5p/index.html
#undef PTR_BITS
#undef CNT_MASK
#undef PTR_MASK
#define PTR_BITS 0
#define CNT_MASK 7
#define PTR_MASK ((0ull-1)<<3)
#endif
#endif
void
runtime·lfstackpush(uint64 *head, LFNode *node)
{

View File

@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// +build darwin netbsd openbsd plan9 windows
// +build darwin netbsd openbsd plan9 solaris windows
#include "runtime.h"
#include "stack.h"

View File

@ -0,0 +1,90 @@
// Copyright 2010 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
#include "runtime.h"
#include "arch_GOARCH.h"
#include "defs_GOOS_GOARCH.h"
#include "os_GOOS.h"
#include "malloc.h"
enum
{
ENOMEM = 12,
};
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·SysReserve(void *v, uintptr n)
{
void *p;
// On 64-bit, people with ulimit -v set complain if we reserve too
// much address space. Instead, assume that the reservation is okay
// and check the assumption in SysMap.
if(sizeof(void*) == 8)
return v;
p = runtime·mmap(v, n, PROT_NONE, MAP_ANON|MAP_PRIVATE, -1, 0);
if(p < (void*)4096)
return nil;
return p;
}
void
runtime·SysMap(void *v, uintptr n, uint64 *stat)
{
void *p;
runtime·xadd64(stat, n);
// On 64-bit, we don't actually have v reserved, so tread carefully.
if(sizeof(void*) == 8) {
p = runtime·mmap(v, n, PROT_READ|PROT_WRITE, MAP_ANON|MAP_PRIVATE, -1, 0);
if(p == (void*)ENOMEM)
runtime·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");
}

View File

@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// +build darwin dragonfly freebsd linux netbsd openbsd windows
// +build darwin dragonfly freebsd linux netbsd openbsd solaris windows
package net
@ -113,6 +113,12 @@ func runtime_pollWait(pd *PollDesc, mode int) (err int) {
runtime·lock(pd);
err = checkerr(pd, mode);
if(err == 0) {
#ifdef GOOS_solaris
if(mode == 'r')
runtime·netpollarmread(pd->fd);
else if(mode == 'w')
runtime·netpollarmwrite(pd->fd);
#endif
while(!netpollblock(pd, mode)) {
err = checkerr(pd, mode);
if(err != 0)
@ -127,6 +133,12 @@ func runtime_pollWait(pd *PollDesc, mode int) (err int) {
func runtime_pollWaitCanceled(pd *PollDesc, mode int) {
runtime·lock(pd);
#ifdef GOOS_solaris
if(mode == 'r')
runtime·netpollarmread(pd->fd);
else if(mode == 'w')
runtime·netpollarmwrite(pd->fd);
#endif
// wait for ioready, ignore closing or timeouts.
while(!netpollblock(pd, mode))
;

View File

@ -0,0 +1,579 @@
// 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 "../../cmd/ld/textflag.h"
#pragma dynexport end _end
#pragma dynexport etext _etext
#pragma dynexport 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, };
// Calling sysvcall on os stack.
#pragma textflag NOSPLIT
uintptr
runtime·sysvicall6(uintptr fn, int32 count, ...)
{
runtime·memclr((byte*)&m->scratch, sizeof(m->scratch));
m->libcall.fn = (void*)fn;
m->libcall.n = (uintptr)count;
for(;count; count--)
m->scratch.v[count - 1] = *((uintptr*)&count + count);
m->libcall.args = (uintptr*)&m->scratch.v[0];
runtime·asmcgocall(runtime·asmsysvicall6, &m->libcall);
return m->libcall.r1;
}
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;
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");
if(runtime·pthread_attr_getstack(&attr, (void**)&mp->g0->stackbase, &mp->g0->stacksize) != 0)
runtime·throw("pthread_attr_getstack");
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");
}
}
void
runtime·get_random_data(byte **rnd, int32 *rnd_len)
{
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);
}
// 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*)m->gsignal->stackguard - StackGuard, 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);
}
void
runtime·sigpanic(void)
{
switch(g->sig) {
case SIGBUS:
if(g->sigcode0 == BUS_ADRERR && g->sigcode1 < 0x1000) {
if(g->sigpc == 0)
runtime·panicstring("call of nil func value");
runtime·panicstring("invalid memory address or nil pointer dereference");
}
runtime·printf("unexpected fault address %p\n", g->sigcode1);
runtime·throw("fault");
case SIGSEGV:
if((g->sigcode0 == 0 || g->sigcode0 == SEGV_MAPERR || g->sigcode0 == SEGV_ACCERR) && g->sigcode1 < 0x1000) {
if(g->sigpc == 0)
runtime·panicstring("call of nil func value");
runtime·panicstring("invalid memory address or nil pointer dereference");
}
runtime·printf("unexpected fault address %p\n", g->sigcode1);
runtime·throw("fault");
case SIGFPE:
switch(g->sigcode0) {
case FPE_INTDIV:
runtime·panicstring("integer divide by zero");
case FPE_INTOVF:
runtime·panicstring("integer overflow");
}
runtime·panicstring("floating point error");
}
runtime·panicstring(runtime·sigtab[g->sig].name);
}
uintptr
runtime·memlimit(void)
{
Rlimit rl;
extern byte text[], 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 = end - 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)
{
Sigaction 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)
{
Sigaction 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.
m->libcall.fn = (void*)libc·malloc;
m->libcall.n = 1;
runtime·memclr((byte*)&m->scratch, sizeof(m->scratch));
m->scratch.v[0] = (uintptr)sizeof(*sem);
m->libcall.args = (uintptr*)&m->scratch;
runtime·asmcgocall(runtime·asmsysvicall6, &m->libcall);
sem = (void*)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)
{
if(ns >= 0) {
m->ts.tv_sec = ns / 1000000000LL;
m->ts.tv_nsec = ns % 1000000000LL;
m->libcall.fn = (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*)&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 = (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*)&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");
}
int32
runtime·close(int32 fd)
{
return runtime·sysvicall6(libc·close, 1, (uintptr)fd);
}
void
runtime·exit(int32 r)
{
runtime·sysvicall6(libc·exit, 1, (uintptr)r);
}
/* int32 */ void
runtime·getcontext(Ucontext* context)
{
runtime·sysvicall6(libc·getcontext, 1, (uintptr)context);
}
int32
runtime·getrlimit(int32 res, Rlimit* rlp)
{
return runtime·sysvicall6(libc·getrlimit, 2, (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);
}
void
runtime·munmap(byte* addr, uintptr len)
{
runtime·sysvicall6(libc·munmap, 2, (uintptr)addr, (uintptr)len);
}
extern int64 runtime·nanotime1(void);
#pragma textflag NOSPLIT
int64
runtime·nanotime(void)
{
return runtime·sysvicall6((uintptr)runtime·nanotime1, 0);
}
void
time·now(int64 sec, int32 usec)
{
int64 ns;
ns = runtime·nanotime();
sec = ns / 1000000000LL;
usec = ns - sec * 1000000000LL;
FLUSH(&sec);
FLUSH(&usec);
}
int32
runtime·open(int8* path, int32 oflag, int32 mode)
{
return runtime·sysvicall6(libc·open, 3, (uintptr)path, (uintptr)oflag, (uintptr)mode);
}
int32
runtime·pthread_attr_destroy(PthreadAttr* attr)
{
return runtime·sysvicall6(libc·pthread_attr_destroy, 1, (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);
}
int32
runtime·pthread_attr_init(PthreadAttr* attr)
{
return runtime·sysvicall6(libc·pthread_attr_init, 1, (uintptr)attr);
}
int32
runtime·pthread_attr_setdetachstate(PthreadAttr* attr, int32 state)
{
return runtime·sysvicall6(libc·pthread_attr_setdetachstate, 2, (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);
}
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);
}
/* int32 */ void
runtime·raise(int32 sig)
{
runtime·sysvicall6(libc·raise, 1, (uintptr)sig);
}
int32
runtime·read(int32 fd, void* buf, int32 nbyte)
{
return runtime·sysvicall6(libc·read, 3, (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);
}
#pragma textflag NOSPLIT
int32
runtime·sem_post(SemT* sem)
{
return runtime·sysvicall6(libc·sem_post, 1, (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);
}
#pragma textflag NOSPLIT
int32
runtime·sem_wait(SemT* sem)
{
return runtime·sysvicall6(libc·sem_wait, 1, (uintptr)sem);
}
/* int32 */ void
runtime·setitimer(int32 which, Itimerval* value, Itimerval* ovalue)
{
runtime·sysvicall6(libc·setitimer, 3, (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);
}
/* int32 */ void
runtime·sigaltstack(Sigaltstack* ss, Sigaltstack* oss)
{
runtime·sysvicall6(libc·sigaltstack, 2, (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);
}
int64
runtime·sysconf(int32 name)
{
return runtime·sysvicall6(libc·sysconf, 1, (uintptr)name);
}
void
runtime·usleep(uint32 us)
{
runtime·sysvicall6(libc·usleep, 1, (uintptr)us);
}
int32
runtime·write(int32 fd, void* buf, int32 nbyte)
{
return runtime·sysvicall6(libc·write, 3, (uintptr)fd, (uintptr)buf, (uintptr)nbyte);
}
void
runtime·osyield(void)
{
runtime·sysvicall6(libc·sched_yield, 0);
}

View File

@ -0,0 +1,51 @@
// Copyright 2013 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
#define SS_DISABLE 2
#define SIG_BLOCK 1
#define SIG_UNBLOCK 2
#define SIG_SETMASK 3
typedef uintptr kevent_udata;
struct sigaction;
void runtime·sigpanic(void);
void runtime·setitimer(int32, Itimerval*, Itimerval*);
void runtime·sigaction(int32, struct Sigaction*, struct Sigaction*);
void runtime·sigaltstack(Sigaltstack*, Sigaltstack*);
void runtime·sigprocmask(int32, Sigset*, Sigset*);
void runtime·unblocksignals(void);
int32 runtime·sysctl(uint32*, uint32, byte*, uintptr*, byte*, uintptr);
#define NSIG 73 /* number of signals in runtime·SigTab array */
#define SI_USER 0
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);
#define _UC_SIGMASK 0x01
#define _UC_CPU 0x04
#define RLIMIT_AS 10
typedef struct Rlimit Rlimit;
struct Rlimit {
int64 rlim_cur;
int64 rlim_max;
};
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
void runtime·asmsysvicall6(void *c);
uintptr runtime·sysvicall6(uintptr fn, int32 count, ...);
void runtime·miniterrno(void *fn);

View File

@ -285,11 +285,11 @@ time·now(int64 sec, int32 usec)
void *
runtime·stdcall(void *fn, int32 count, ...)
{
m->wincall.fn = fn;
m->wincall.n = count;
m->wincall.args = (uintptr*)&count + 1;
runtime·asmcgocall(runtime·asmstdcall, &m->wincall);
return (void*)m->wincall.r1;
m->libcall.fn = fn;
m->libcall.n = count;
m->libcall.args = (uintptr*)&count + 1;
runtime·asmcgocall(runtime·asmstdcall, &m->libcall);
return (void*)m->libcall.r1;
}
extern void runtime·usleep1(uint32);

View File

@ -653,9 +653,9 @@ runtime·allocm(P *p)
mp = runtime·cnew(mtype);
mcommoninit(mp);
// In case of cgo, pthread_create will make us a stack.
// In case of cgo or Solaris, pthread_create will make us a stack.
// Windows will layout sched stack on OS stack.
if(runtime·iscgo || Windows)
if(runtime·iscgo || Solaris || Windows)
mp->g0 = runtime·malg(-1);
else
mp->g0 = runtime·malg(8192);

View File

@ -0,0 +1,18 @@
// Copyright 2013 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
#include "../../cmd/ld/textflag.h"
TEXT _rt0_amd64_solaris(SB),NOSPLIT,$-8
LEAQ 8(SP), SI // argv
MOVQ 0(SP), DI // argc
MOVQ $main(SB), AX
JMP AX
TEXT main(SB),NOSPLIT,$-8
MOVQ $_rt0_go(SB), AX
JMP AX
DATA runtime·issolaris(SB)/4, $1
GLOBL runtime·issolaris(SB), $4

View File

@ -87,6 +87,7 @@ runtime·args(int32 c, uint8 **v)
}
int32 runtime·isplan9;
int32 runtime·issolaris;
int32 runtime·iswindows;
// Information about what cpu features are available.

View File

@ -76,7 +76,7 @@ typedef struct Hmap Hmap;
typedef struct Hchan Hchan;
typedef struct Complex64 Complex64;
typedef struct Complex128 Complex128;
typedef struct WinCall WinCall;
typedef struct LibCall LibCall;
typedef struct SEH SEH;
typedef struct WinCallbackContext WinCallbackContext;
typedef struct Timers Timers;
@ -224,7 +224,7 @@ struct GCStats
uint64 nsleep;
};
struct WinCall
struct LibCall
{
void (*fn)(void*);
uintptr n; // number of parameters
@ -351,7 +351,22 @@ struct M
#ifdef GOOS_windows
void* thread; // thread handle
WinCall wincall;
// these are here because they are too large to be on the stack
// of low-level NOSPLIT functions.
LibCall libcall;
#endif
#ifdef GOOS_solaris
int32* perrno; // pointer to TLS errno
// these are here because they are too large to be on the stack
// of low-level NOSPLIT functions.
LibCall libcall;
struct {
int64 tv_sec;
int64 tv_nsec;
} ts;
struct {
uintptr v[6];
} scratch;
#endif
#ifdef GOOS_plan9
int8* notesig;
@ -467,6 +482,15 @@ enum {
Windows = 0
};
#endif
#ifdef GOOS_solaris
enum {
Solaris = 1
};
#else
enum {
Solaris = 0
};
#endif
struct Timers
{
@ -865,6 +889,8 @@ int32 runtime·netpollopen(uintptr, PollDesc*);
int32 runtime·netpollclose(uintptr);
void runtime·netpollready(G**, PollDesc*, int32);
uintptr runtime·netpollfd(PollDesc*);
void runtime·netpollarmread(uintptr fd);
void runtime·netpollarmwrite(uintptr fd);
void runtime·crash(void);
void runtime·parsedebugvars(void);
void _rt0_go(void);

View File

@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// +build darwin dragonfly freebsd linux netbsd openbsd
// +build darwin dragonfly freebsd linux netbsd openbsd solaris
#include "runtime.h"
#include "defs_GOOS_GOARCH.h"

View File

@ -0,0 +1,31 @@
// Copyright 2013 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
#define SIG_REGS(ctxt) (((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])

View File

@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// +build darwin dragonfly freebsd linux openbsd netbsd
// +build darwin dragonfly freebsd linux netbsd openbsd solaris
#include "runtime.h"
#include "defs_GOOS_GOARCH.h"

View File

@ -0,0 +1,94 @@
// Copyright 2013 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
#define N SigNotify
#define K SigKill
#define T SigThrow
#define P SigPanic
#define D SigDefault
SigTab runtime·sigtab[] = {
/* 0 */ 0, "SIGNONE: no trap",
/* 1 */ N+K, "SIGHUP: 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

View File

@ -0,0 +1,267 @@
// Copyright 2013 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
//
// System calls and other sys.stuff for AMD64, SunOS
// /usr/include/sys/syscall.h for syscall numbers.
//
#include "zasm_GOOS_GOARCH.h"
#include "../../cmd/ld/textflag.h"
// This is needed by asm_amd64.s
TEXT runtime·settls(SB),NOSPLIT,$8
RET
// void libc·miniterrno(void *(*___errno)(void));
//
// Set the TLS errno pointer in M.
//
// Called using runtime·asmcgocall from os_solaris.c:/minit.
TEXT runtime·miniterrno(SB),NOSPLIT,$0
// asmcgocall will put first argument into DI.
CALL DI // SysV ABI so returns in AX
get_tls(CX)
MOVQ m(CX), BX
MOVQ AX, m_perrno(BX)
RET
// int64 runtime·nanotime1(void);
//
// clock_gettime(3c) wrapper because Timespec is too large for
// runtime·nanotime stack.
//
// Called using runtime·sysvicall6 from os_solaris.c:/nanotime.
TEXT runtime·nanotime1(SB),NOSPLIT,$0
// need space for the timespec argument.
SUBQ $64, SP // 16 bytes will do, but who knows in the future?
MOVQ $3, DI // CLOCK_REALTIME from <sys/time_impl.h>
MOVQ SP, SI
MOVQ libc·clock_gettime(SB), AX
CALL AX
MOVQ (SP), AX // tv_sec from struct timespec
IMULQ $1000000000, AX // multiply into nanoseconds
ADDQ 8(SP), AX // tv_nsec, offset should be stable.
ADDQ $64, SP
RET
// pipe(3c) wrapper that returns fds in AX, DX.
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
CALL AX
MOVL 0(SP), AX
MOVL 4(SP), DX
ADDQ $16, SP
RET
// Call a library function with SysV calling conventions.
// The called function can take a maximum of 6 INTEGER class arguments,
// see
// Michael Matz, Jan Hubicka, Andreas Jaeger, and Mark Mitchell
// System V Application Binary Interface
// AMD64 Architecture Processor Supplement
// section 3.2.3.
//
// Called by runtime·asmcgocall or runtime·cgocall.
TEXT runtime·asmsysvicall6(SB),NOSPLIT,$0
// asmcgocall will put first argument into DI.
PUSHQ DI // save for later
MOVQ libcall_fn(DI), AX
MOVQ libcall_args(DI), R11
MOVQ libcall_n(DI), R10
get_tls(CX)
MOVQ m(CX), BX
MOVQ m_perrno(BX), DX
CMPQ DX, $0
JEQ skiperrno1
MOVL $0, 0(DX)
skiperrno1:
CMPQ R11, $0
JEQ skipargs
// Load 6 args into correspondent registers.
MOVQ 0(R11), DI
MOVQ 8(R11), SI
MOVQ 16(R11), DX
MOVQ 24(R11), CX
MOVQ 32(R11), R8
MOVQ 40(R11), R9
skipargs:
// Call SysV function
CALL AX
// Return result
POPQ DI
MOVQ AX, libcall_r1(DI)
MOVQ DX, libcall_r2(DI)
get_tls(CX)
MOVQ m(CX), BX
MOVQ m_perrno(BX), AX
CMPQ AX, $0
JEQ skiperrno2
MOVL 0(AX), AX
MOVQ AX, libcall_err(DI)
skiperrno2:
RET
// uint32 tstart_sysvicall(M *newm);
TEXT runtime·tstart_sysvicall(SB),NOSPLIT,$0
// DI contains first arg newm
MOVQ m_g0(DI), DX // g
// Make TLS entries point at g and m.
get_tls(BX)
MOVQ DX, g(BX)
MOVQ DI, m(BX)
// Layout new m scheduler stack on os stack.
MOVQ SP, AX
MOVQ AX, g_stackbase(DX)
SUBQ $(0x100000), AX // stack size
MOVQ AX, g_stackguard(DX)
MOVQ AX, g_stackguard0(DX)
// Someday the convention will be D is always cleared.
CLD
CALL runtime·stackcheck(SB) // clobbers AX,CX
CALL runtime·mstart(SB)
XORL AX, AX // return 0 == success
RET
// Careful, this is called by __sighndlr, a libc function. We must preserve
// registers as per AMD 64 ABI.
TEXT runtime·sigtramp(SB),NOSPLIT,$0
// Note that we are executing on altsigstack here, so we have
// more stack available than NOSPLIT would have us believe.
// To defeat the linker, we make our own stack frame with
// more space:
SUBQ $184, SP
// save registers
MOVQ BX, 32(SP)
MOVQ BP, 40(SP)
MOVQ R12, 48(SP)
MOVQ R13, 56(SP)
MOVQ R14, 64(SP)
MOVQ R15, 72(SP)
get_tls(BX)
// check that m exists
MOVQ m(BX), BP
CMPQ BP, $0
JNE allgood
MOVQ DI, 0(SP)
MOVQ $runtime·badsignal(SB), AX
CALL AX
RET
allgood:
// save g
MOVQ g(BX), R10
MOVQ R10, 80(SP)
// Save m->libcall and m->scratch. We need to do this because we
// might get interrupted by a signal in runtime·asmcgocall.
// save m->libcall
LEAQ m_libcall(BP), R11
MOVQ libcall_fn(R11), R10
MOVQ R10, 88(SP)
MOVQ libcall_args(R11), R10
MOVQ R10, 96(SP)
MOVQ libcall_n(R11), R10
MOVQ R10, 104(SP)
MOVQ libcall_r1(R11), R10
MOVQ R10, 168(SP)
MOVQ libcall_r2(R11), R10
MOVQ R10, 176(SP)
// save m->scratch
LEAQ m_scratch(BP), R11
MOVQ 0(R11), R10
MOVQ R10, 112(SP)
MOVQ 8(R11), R10
MOVQ R10, 120(SP)
MOVQ 16(R11), R10
MOVQ R10, 128(SP)
MOVQ 24(R11), R10
MOVQ R10, 136(SP)
MOVQ 32(R11), R10
MOVQ R10, 144(SP)
MOVQ 40(R11), R10
MOVQ R10, 152(SP)
// save errno, it might be EINTR; stuff we do here might reset it.
MOVQ m_perrno(BP), R10
MOVL 0(R10), R10
MOVQ R10, 160(SP)
MOVQ g(BX), R10
// g = m->gsignal
MOVQ m_gsignal(BP), BP
MOVQ BP, g(BX)
// prepare call
MOVQ DI, 0(SP)
MOVQ SI, 8(SP)
MOVQ DX, 16(SP)
MOVQ R10, 24(SP)
CALL runtime·sighandler(SB)
get_tls(BX)
MOVQ m(BX), BP
// restore libcall
LEAQ m_libcall(BP), R11
MOVQ 88(SP), R10
MOVQ R10, libcall_fn(R11)
MOVQ 96(SP), R10
MOVQ R10, libcall_args(R11)
MOVQ 104(SP), R10
MOVQ R10, libcall_n(R11)
MOVQ 168(SP), R10
MOVQ R10, libcall_r1(R11)
MOVQ 176(SP), R10
MOVQ R10, libcall_r2(R11)
// restore scratch
LEAQ m_scratch(BP), R11
MOVQ 112(SP), R10
MOVQ R10, 0(R11)
MOVQ 120(SP), R10
MOVQ R10, 8(R11)
MOVQ 128(SP), R10
MOVQ R10, 16(R11)
MOVQ 136(SP), R10
MOVQ R10, 24(R11)
MOVQ 144(SP), R10
MOVQ R10, 32(R11)
MOVQ 152(SP), R10
MOVQ R10, 40(R11)
// restore errno
MOVQ m_perrno(BP), R11
MOVQ 160(SP), R10
MOVL R10, 0(R11)
// restore g
MOVQ 80(SP), R10
MOVQ R10, g(BX)
// restore registers
MOVQ 32(SP), BX
MOVQ 40(SP), BP
MOVQ 48(SP), R12
MOVQ 56(SP), R13
MOVQ 64(SP), R14
MOVQ 72(SP), R15
ADDQ $184, SP
RET

View File

@ -14,28 +14,28 @@ TEXT runtime·asmstdcall(SB),NOSPLIT,$0
// Copy args to the stack.
MOVL SP, BP
MOVL wincall_n(BX), CX // words
MOVL libcall_n(BX), CX // words
MOVL CX, AX
SALL $2, AX
SUBL AX, SP // room for args
MOVL SP, DI
MOVL wincall_args(BX), SI
MOVL libcall_args(BX), SI
CLD
REP; MOVSL
// Call stdcall or cdecl function.
// DI SI BP BX are preserved, SP is not
CALL wincall_fn(BX)
CALL libcall_fn(BX)
MOVL BP, SP
// Return result.
MOVL c+0(FP), BX
MOVL AX, wincall_r1(BX)
MOVL DX, wincall_r2(BX)
MOVL AX, libcall_r1(BX)
MOVL DX, libcall_r2(BX)
// GetLastError().
MOVL 0x34(FS), AX
MOVL AX, wincall_err(BX)
MOVL AX, libcall_err(BX)
RET

View File

@ -13,9 +13,9 @@
TEXT runtime·asmstdcall(SB),NOSPLIT,$0
// asmcgocall will put first argument into CX.
PUSHQ CX // save for later
MOVQ wincall_fn(CX), AX
MOVQ wincall_args(CX), SI
MOVQ wincall_n(CX), CX
MOVQ libcall_fn(CX), AX
MOVQ libcall_args(CX), SI
MOVQ libcall_n(CX), CX
// SetLastError(0).
MOVQ 0x30(GS), DI
@ -52,12 +52,12 @@ loadregs:
// Return result.
POPQ CX
MOVQ AX, wincall_r1(CX)
MOVQ AX, libcall_r1(CX)
// GetLastError().
MOVQ 0x30(GS), DI
MOVL 0x68(DI), AX
MOVQ AX, wincall_err(CX)
MOVQ AX, libcall_err(CX)
RET

View File

@ -0,0 +1,374 @@
// Copyright 2013 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package syscall
#include "runtime.h"
#include "defs_GOOS_GOARCH.h"
#include "os_GOOS.h"
#include "cgocall.h"
#include "../../cmd/ld/textflag.h"
#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"
extern uintptr libc·chdir;
extern uintptr libc·chroot;
extern uintptr libc·close;
extern uintptr libc·dlclose;
extern uintptr libc·dlopen;
extern uintptr libc·dlsym;
extern uintptr libc·execve;
extern uintptr libc·exit;
extern uintptr libc·fcntl;
extern uintptr libc·gethostname;
extern uintptr libc·ioctl;
extern uintptr libc·pipe;
extern uintptr libc·setgid;
extern uintptr libc·setgroups;
extern uintptr libc·setsid;
extern uintptr libc·setuid;
extern uintptr libc·setpgid;
extern uintptr libc·syscall;
extern uintptr libc·forkx;
extern uintptr libc·wait4;
extern uintptr libc·write;
func Sysvicall6(func uintptr, nargs uintptr, a1 uintptr, a2 uintptr, a3 uintptr, a4 uintptr, a5 uintptr, a6 uintptr) (r1 uintptr, r2 uintptr, err uintptr)
{
LibCall c;
USED(a2);
USED(a3);
USED(a4);
USED(a5);
USED(a6);
c.fn = (void*)func;
c.n = nargs;
c.args = (void*)&a1;
runtime·cgocall(runtime·asmsysvicall6, &c);
err = c.err;
r1 = c.r1;
r2 = c.r2;
}
#pragma textflag NOSPLIT
func RawSysvicall6(func uintptr, nargs uintptr, a1 uintptr, a2 uintptr, a3 uintptr, a4 uintptr, a5 uintptr, a6 uintptr) (r1 uintptr, r2 uintptr, err uintptr)
{
LibCall c;
USED(a2);
USED(a3);
USED(a4);
USED(a5);
USED(a6);
c.fn = (void*)func;
c.n = nargs;
c.args = (void*)&a1;
runtime·asmcgocall(runtime·asmsysvicall6, &c);
err = c.err;
r1 = c.r1;
r2 = c.r2;
}
#pragma textflag NOSPLIT
func chdir(path uintptr) (err uintptr) {
LibCall c;
c.fn = (void*)libc·chdir;
c.n = 1;
c.args = (void*)&path;
runtime·asmcgocall(runtime·asmsysvicall6, &c);
err = c.err;
}
#pragma textflag NOSPLIT
func chroot1(path uintptr) (err uintptr) {
LibCall c;
c.fn = (void*)libc·chroot;
c.n = 1;
c.args = (void*)&path;
runtime·asmcgocall(runtime·asmsysvicall6, &c);
err = c.err;
}
#pragma textflag NOSPLIT
func close(fd uintptr) (err uintptr) {
LibCall c;
c.fn = (void*)libc·close;
c.n = 1;
c.args = (void*)&fd;
runtime·asmcgocall(runtime·asmsysvicall6, &c);
err = c.err;
}
func dlclose(handle uintptr) (err uintptr) {
LibCall c;
USED(handle);
c.fn = (void*)libc·dlclose;
c.n = 1;
c.args = (void*)&handle;
runtime·cgocall(runtime·asmsysvicall6, &c);
err = c.r1;
}
func dlopen(name *uint8, mode uintptr) (handle uintptr, err uintptr) {
LibCall c;
USED(mode);
c.fn = (void*)libc·dlopen;
c.n = 2;
c.args = (void*)&name;
runtime·cgocall(runtime·asmsysvicall6, &c);
handle = c.r1;
if(handle == 0)
err = c.err;
else
err = 0;
}
func dlsym(handle uintptr, name *uint8) (proc uintptr, err uintptr) {
LibCall c;
USED(name);
c.fn = (void*)libc·dlsym;
c.n = 2;
c.args = &handle;
runtime·cgocall(runtime·asmsysvicall6, &c);
proc = c.r1;
if(proc == 0)
err = c.err;
else
err = 0;
}
#pragma textflag NOSPLIT
func execve(path uintptr, argv uintptr, envp uintptr) (err uintptr) {
LibCall c;
USED(argv);
USED(envp);
c.fn = (void*)libc·execve;
c.n = 3;
c.args = (void*)&path;
runtime·cgocall(runtime·asmsysvicall6, &c);
err = c.err;
}
#pragma textflag NOSPLIT
func exit(code uintptr) {
LibCall c;
c.fn = (void*)libc·exit;
c.n = 1;
c.args = (void*)&code;
runtime·asmcgocall(runtime·asmsysvicall6, &c);
}
#pragma textflag NOSPLIT
func fcntl1(fd uintptr, cmd uintptr, arg uintptr) (val uintptr, err uintptr) {
LibCall c;
USED(cmd);
USED(arg);
c.fn = (void*)libc·fcntl;
c.n = 3;
c.args = (void*)&fd;
runtime·cgocall(runtime·asmsysvicall6, &c);
err = c.err;
val = c.r1;
}
func gethostname() (name String, err uintptr) {
struct { uintptr v[2]; } args;
uint8 cname[MAXHOSTNAMELEN];
LibCall c;
c.fn = (void*)libc·gethostname;
c.n = 2;
args.v[0] = (uintptr)&cname[0];
args.v[1] = MAXHOSTNAMELEN;
c.args = (void*)&args;
runtime·cgocall(runtime·asmsysvicall6, &c);
err = c.err;
if(c.r1) {
name = runtime·emptystring;
return;
}
cname[MAXHOSTNAMELEN - 1] = 0;
name = runtime·gostring(cname);
}
#pragma textflag NOSPLIT
func ioctl(fd uintptr, req uintptr, arg uintptr) (err uintptr) {
LibCall c;
USED(req);
USED(arg);
c.fn = (void*)libc·ioctl;
c.n = 3;
c.args = (void*)&fd;
runtime·cgocall(runtime·asmsysvicall6, &c);
err = c.err;
}
func wait4(pid uintptr, wstatus *uint32, options uintptr, rusage *void) (wpid int, err uintptr) {
LibCall c;
USED(wstatus);
USED(options);
USED(rusage);
c.fn = (void*)libc·wait4;
c.n = 4;
c.args = (void*)&pid;
runtime·cgocall(runtime·asmsysvicall6, &c);
err = c.err;
wpid = c.r1;
}
#pragma textflag NOSPLIT
func setgid(gid uintptr) (err uintptr) {
LibCall c;
c.fn = (void*)libc·setgid;
c.n = 1;
c.args = (void*)&gid;
runtime·asmcgocall(runtime·asmsysvicall6, &c);
err = c.err;
}
#pragma textflag NOSPLIT
func setgroups1(ngid uintptr, gid uintptr) (err uintptr) {
LibCall c;
USED(gid);
c.fn = (void*)libc·setgroups;
c.n = 2;
c.args = (void*)&ngid;
runtime·asmcgocall(runtime·asmsysvicall6, &c);
err = c.err;
}
#pragma textflag NOSPLIT
func setsid() (pid uintptr, err uintptr) {
LibCall c;
c.fn = (void*)libc·setsid;
c.n = 0;
c.args = (void*)0;
runtime·asmcgocall(runtime·asmsysvicall6, &c);
err = c.err;
pid = c.r1;
}
#pragma textflag NOSPLIT
func setuid(uid uintptr) (err uintptr) {
LibCall c;
c.fn = (void*)libc·setuid;
c.n = 1;
c.args = (void*)&uid;
runtime·asmcgocall(runtime·asmsysvicall6, &c);
err = c.err;
}
#pragma textflag NOSPLIT
func setpgid(pid uintptr, pgid uintptr) (err uintptr) {
LibCall c;
USED(pgid);
c.fn = (void*)libc·setpgid;
c.n = 2;
c.args = (void*)&pid;
runtime·asmcgocall(runtime·asmsysvicall6, &c);
err = c.err;
}
#pragma textflag NOSPLIT
func forkx(flags uintptr) (pid uintptr, err uintptr) {
LibCall c;
c.fn = (void*)libc·forkx;
c.n = 1;
c.args = (void*)&flags;
runtime·asmcgocall(runtime·asmsysvicall6, &c);
err = c.err;
pid = c.r1;
}
void runtime·pipe1(void);
func pipe() (r uintptr, w uintptr, err uintptr) {
LibCall c;
c.fn = (void*)runtime·pipe1;
c.n = 0;
c.args = (void*)0;
runtime·cgocall(runtime·asmsysvicall6, &c);
err = c.err;
r = c.r1;
w = c.r2;
}
#pragma textflag NOSPLIT
func write1(fd uintptr, buf uintptr, nbyte uintptr) (n uintptr, err uintptr) {
LibCall c;
USED(buf);
USED(nbyte);
c.fn = (void*)libc·write;
c.n = 3;
c.args = (void*)fd;
runtime·cgocall(runtime·asmsysvicall6, &c);
err = c.err;
n = c.r1;
}
func Syscall(trap uintptr, a1 uintptr, a2 uintptr, a3 uintptr) (r1 uintptr, r2 uintptr, err uintptr) {
LibCall c;
USED(a1);
USED(a2);
USED(a3);
c.fn = (void*)libc·syscall;
c.n = 4;
c.args = &trap;
runtime·cgocall(runtime·asmsysvicall6, &c);
err = c.err;
r1 = c.r1;
r2 = c.r2;
}
func RawSyscall(trap uintptr, a1 uintptr, a2 uintptr, a3 uintptr) (r1 uintptr, r2 uintptr, err uintptr) {
LibCall c;
USED(a1);
USED(a2);
USED(a3);
c.fn = (void*)libc·syscall;
c.n = 4;
c.args = &trap;
runtime·asmcgocall(runtime·asmsysvicall6, &c);
err = c.err;
r1 = c.r1;
r2 = c.r2;
}

View File

@ -8,7 +8,7 @@ package syscall
#include "cgocall.h"
func loadlibrary(filename *uint16) (handle uintptr, err uintptr) {
WinCall c;
LibCall c;
c.fn = runtime·LoadLibrary;
c.n = 1;
@ -22,7 +22,7 @@ func loadlibrary(filename *uint16) (handle uintptr, err uintptr) {
}
func getprocaddress(handle uintptr, procname *uint8) (proc uintptr, err uintptr) {
WinCall c;
LibCall c;
USED(procname);
c.fn = runtime·GetProcAddress;
@ -45,7 +45,7 @@ func NewCallbackCDecl(fn Eface) (code uintptr) {
}
func Syscall(fn uintptr, nargs uintptr, a1 uintptr, a2 uintptr, a3 uintptr) (r1 uintptr, r2 uintptr, err uintptr) {
WinCall c;
LibCall c;
USED(a2);
USED(a3);
@ -59,7 +59,7 @@ func Syscall(fn uintptr, nargs uintptr, a1 uintptr, a2 uintptr, a3 uintptr) (r1
}
func Syscall6(fn uintptr, nargs uintptr, a1 uintptr, a2 uintptr, a3 uintptr, a4 uintptr, a5 uintptr, a6 uintptr) (r1 uintptr, r2 uintptr, err uintptr) {
WinCall c;
LibCall c;
USED(a2);
USED(a3);
@ -76,7 +76,7 @@ func Syscall6(fn uintptr, nargs uintptr, a1 uintptr, a2 uintptr, a3 uintptr, a4
}
func Syscall9(fn uintptr, nargs uintptr, a1 uintptr, a2 uintptr, a3 uintptr, a4 uintptr, a5 uintptr, a6 uintptr, a7 uintptr, a8 uintptr, a9 uintptr) (r1 uintptr, r2 uintptr, err uintptr) {
WinCall c;
LibCall c;
USED(a2);
USED(a3);
@ -96,7 +96,7 @@ func Syscall9(fn uintptr, nargs uintptr, a1 uintptr, a2 uintptr, a3 uintptr, a4
}
func Syscall12(fn uintptr, nargs uintptr, a1 uintptr, a2 uintptr, a3 uintptr, a4 uintptr, a5 uintptr, a6 uintptr, a7 uintptr, a8 uintptr, a9 uintptr, a10 uintptr, a11 uintptr, a12 uintptr) (r1 uintptr, r2 uintptr, err uintptr) {
WinCall c;
LibCall c;
USED(a2);
USED(a3);
@ -119,7 +119,7 @@ func Syscall12(fn uintptr, nargs uintptr, a1 uintptr, a2 uintptr, a3 uintptr, a4
}
func Syscall15(fn uintptr, nargs uintptr, a1 uintptr, a2 uintptr, a3 uintptr, a4 uintptr, a5 uintptr, a6 uintptr, a7 uintptr, a8 uintptr, a9 uintptr, a10 uintptr, a11 uintptr, a12 uintptr, a13 uintptr, a14 uintptr, a15 uintptr) (r1 uintptr, r2 uintptr, err uintptr) {
WinCall c;
LibCall c;
USED(a2);
USED(a3);