# DO NOT EDIT. Automatically generated by gobuild.
# gobuild -m errstr_darwin.go file_darwin.go socket_darwin.go\
# syscall_amd64_darwin.go time_amd64_darwin.go types_amd64_darwin.go\
-# asm_amd64_darwin.s cast_amd64.s syscall.go >Makefile
+# asm_amd64_darwin.s cast_amd64.s syscall.go signal_amd64_darwin.go >Makefile
O=6
GC=$(O)g
CC=$(O)c -w
asm_$(GOARCH)_$(GOOS).$O\
cast_$(GOARCH).$O\
syscall.$O\
+ signal_$(GOARCH)_$(GOOS).$O\
O2=\
file_$(GOOS).$O\
syscall.a: a1 a2
a1: $(O1)
- $(AR) grc syscall.a errstr_$(GOOS).$O syscall_$(GOARCH)_$(GOOS).$O types_$(GOARCH)_$(GOOS).$O asm_$(GOARCH)_$(GOOS).$O cast_$(GOARCH).$O syscall.$O
+ $(AR) grc syscall.a errstr_$(GOOS).$O syscall_$(GOARCH)_$(GOOS).$O types_$(GOARCH)_$(GOOS).$O asm_$(GOARCH)_$(GOOS).$O cast_$(GOARCH).$O syscall.$O signal_$(GOARCH)_$(GOOS).$O
rm -f $(O1)
a2: $(O2)
MOVQ $0, 80(SP) // errno
CALL sys·exitsyscall(SB)
RET
+
+TEXT syscall·RawSyscall(SB),7,$0
+ MOVQ 16(SP), DI
+ MOVQ 24(SP), SI
+ MOVQ 32(SP), DX
+ MOVQ 8(SP), AX // syscall entry
+ ADDQ $0x2000000, AX
+ SYSCALL
+ JCC ok1
+ MOVQ $-1, 40(SP) // r1
+ MOVQ $0, 48(SP) // r2
+ MOVQ AX, 56(SP) // errno
+ RET
+ok1:
+ MOVQ AX, 40(SP) // r1
+ MOVQ DX, 48(SP) // r2
+ MOVQ $0, 56(SP) // errno
+ RET
MOVQ $0, 80(SP) // errno
CALL sys·exitsyscall(SB)
RET
+
+TEXT syscall·RawSyscall(SB),7,$0
+ MOVQ 16(SP), DI
+ MOVQ 24(SP), SI
+ MOVQ 32(SP), DX
+ MOVQ 8(SP), AX // syscall entry
+ SYSCALL
+ CMPQ AX, $0xfffffffffffff001
+ JLS ok1
+ MOVQ $-1, 40(SP) // r1
+ MOVQ $0, 48(SP) // r2
+ NEGQ AX
+ MOVQ AX, 56(SP) // errno
+ RET
+ok1:
+ MOVQ AX, 40(SP) // r1
+ MOVQ DX, 48(SP) // r2
+ MOVQ $0, 56(SP) // errno
+ RET
MOVQ AX, 16(SP)
RET
+TEXT syscall·BytePtrPtr(SB),7,$-8
+ MOVQ 8(SP), AX
+ MOVQ AX, 16(SP)
+ RET
+
TEXT syscall·Int32Ptr(SB),7,$-8
MOVQ 8(SP), AX
MOVQ AX, 16(SP)
MOVQ AX, 16(SP)
RET
+TEXT syscall·RusagePtr(SB),7,$-8
+ MOVQ 8(SP), AX
+ MOVQ AX, 16(SP)
+ RET
+
TEXT syscall·SockaddrToSockaddrInet4(SB),7,$-8
MOVQ 8(SP), AX
MOVQ AX, 16(SP)
r1, r2, err := Syscall(SYS_MKDIR, BytePtr(&namebuf[0]), perm, 0);
return r1, err;
}
+
+export func dup2(fd1, fd2 int64) (ret int64, errno int64) {
+ r1, r2, err := Syscall(SYS_DUP2, fd1, fd2, 0);
+ return r1, err;
+}
+
r1, r2, err := Syscall(SYS_MKDIR, BytePtr(&namebuf[0]), perm, 0);
return r1, err;
}
+
+export func dup2(fd1, fd2 int64) (ret int64, errno int64) {
+ r1, r2, err := Syscall(SYS_DUP2, fd1, fd2, 0);
+ return r1, err;
+}
+
export func Syscall(trap int64, a1, a2, a3 int64) (r1, r2, err int64);
export func Syscall6(trap int64, a1, a2, a3, a4, a5, a6 int64) (r1, r2, err int64);
+export func RawSyscall(trap int64, a1, a2, a3 int64) (r1, r2, err int64);
export func BytePtr(b *byte) int64;
export func Int32Ptr(p *int32) int64;
export func Int64Ptr(p *int64) int64;
+export func BytePtrPtr(b **byte) int64;
/*
* Used to convert file names to byte arrays for passing to kernel,
export func TimevalPtr(t *Timeval) int64;
+// Processes
+
+export type Rusage struct {
+ utime Timeval;
+ stime Timeval;
+ maxrss int64;
+ ixrss int64;
+ idrss int64;
+ isrss int64;
+ minflt int64;
+ majflt int64;
+ nswap int64;
+ inblock int64;
+ oublock int64;
+ msgsnd int64;
+ msgrcv int64;
+ nsignals int64;
+ nvcsw int64;
+ nivcsw int64;
+}
+export func RusagePtr(r *Rusage) int64;
+
+
// Files
export const (
O_SYNC = 0x80;
O_TRUNC = 0x400;
+ F_GETFD = 1;
+ F_SETFD = 2;
+
F_GETFL = 3;
F_SETFL = 4;
+
+ FD_CLOEXEC = 1;
)
export type Stat struct {
export func TimevalPtr(t *Timeval) int64;
+// Processes
+
+export type Rusage struct {
+ utime Timeval;
+ stime Timeval;
+ maxrss int64;
+ ixrss int64;
+ idrss int64;
+ isrss int64;
+ minflt int64;
+ majflt int64;
+ nswap int64;
+ inblock int64;
+ oublock int64;
+ msgsnd int64;
+ msgrcv int64;
+ nsignals int64;
+ nvcsw int64;
+ nivcsw int64;
+}
+export func RusagePtr(r *Rusage) int64;
+
+
// Files
export const (
O_SYNC = 0x1000;
O_TRUNC = 0x200;
+ F_GETFD = 1;
+ F_SETFD = 2;
+
F_GETFL = 3;
F_SETFL = 4;
+
+ FD_CLOEXEC = 1;
)
export type Stat struct {
#include "runtime.h"
#include "amd64_darwin.h"
-#include "signals.h"
+#include "signals_darwin.h"
typedef uint64 __uint64_t;
/*
* This assembler routine takes the args from registers, puts them on the stack,
- * and calls sighandler().
+ * and calls the registered handler.
*/
-extern void sigtramp();
-
+extern void sigtramp(void);
/*
* Rudimentary reverse-engineered definition of signal interface.
* You'd think it would be documented.
*/
-typedef struct siginfo {
+struct siginfo {
int32 si_signo; /* signal number */
int32 si_errno; /* errno association */
int32 si_code; /* signal code */
int32 si_status; /* exit value */
void *si_addr; /* faulting address */
/* more stuff here */
-} siginfo;
-
+};
-typedef struct sigaction {
- union {
- void (*sa_handler)(int32);
- void (*sa_sigaction)(int32, siginfo *, void *);
- } u; /* signal handler */
- void (*sa_trampoline)(void); /* kernel callback point; calls sighandler() */
- uint8 sa_mask[4]; /* signal mask to apply */
- int32 sa_flags; /* see signal options below */
-} sigaction;
+struct sigaction {
+ void (*sa_handler)(int32, struct siginfo*, void*); // actual handler
+ void (*sa_trampoline)(void); // assembly trampoline
+ uint32 sa_mask; // signal mask during handler
+ int32 sa_flags; // flags below
+};
void
-sighandler(int32 sig, siginfo *info, void *context)
+sighandler(int32 sig, struct siginfo *info, void *context)
{
if(panicking) // traceback already printed
sys·exit(2);
sys·exit(2);
}
+void
+sigignore(int32, struct siginfo*, void*)
+{
+}
+
struct stack_t {
byte *sp;
int64 size;
int32 flags;
};
-sigaction a;
-extern void sigtramp(void);
-
void
signalstack(byte *p, int32 n)
{
sigaltstack(&st, nil);
}
+void sigaction(int64, void*, void*);
+
+enum {
+ SA_SIGINFO = 0x40,
+ SA_RESTART = 0x02,
+ SA_ONSTACK = 0x01,
+ SA_USERTRAMP = 0x100,
+ SA_64REGSET = 0x200,
+};
+
void
initsig(void)
{
int32 i;
-
- a.u.sa_sigaction = (void*)sigtramp;
- a.sa_flags |= 0x41; /* SA_SIGINFO, SA_ONSTACK */
- for(i=0; i<sizeof(a.sa_mask); i++)
- a.sa_mask[i] = 0xFF;
- a.sa_trampoline = sigtramp;
-
- for(i = 0; i <NSIG; i++)
- if(sigtab[i].catch){
- sys·sigaction(i, &a, (void*)0);
+ static struct sigaction sa;
+
+ sa.sa_flags |= SA_SIGINFO|SA_ONSTACK;
+ sa.sa_mask = 0; // 0xFFFFFFFFU;
+ sa.sa_trampoline = sigtramp;
+ for(i = 0; i<NSIG; i++) {
+ if(sigtab[i].flags) {
+ if(sigtab[i].flags & SigCatch) {
+ sa.sa_handler = sighandler;
+ } else {
+ sa.sa_handler = sigignore;
+ }
+ if(sigtab[i].flags & SigRestart)
+ sa.sa_flags |= SA_RESTART;
+ else
+ sa.sa_flags &= ~SA_RESTART;
+ sigaction(i, &sa, nil);
}
+ }
}
static void
#include "runtime.h"
#include "amd64_linux.h"
-#include "signals.h"
+#include "signals_linux.h"
/* From /usr/include/asm-x86_64/sigcontext.h */
struct _fpstate {
* This assembler routine takes the args from registers, puts them on the stack,
* and calls sighandler().
*/
-extern void sigtramp();
+extern void sigtramp(void);
+extern void sigignore(void); // just returns
+extern void sigreturn(void); // calls sigreturn
/*
* Rudimentary reverse-engineered definition of signal interface.
* You'd think it would be documented.
*/
/* From /usr/include/bits/siginfo.h */
-typedef struct siginfo {
+struct siginfo {
int32 si_signo; /* signal number */
int32 si_errno; /* errno association */
int32 si_code; /* signal code */
int32 si_status; /* exit value */
void *si_addr; /* faulting address */
/* more stuff here */
-} siginfo;
-
+};
-/* From /usr/include/bits/sigaction.h */
-/* (gri) Is this correct? See e.g. /usr/include/asm-x86_64/signal.h */
-typedef struct sigaction {
- union {
- void (*sa_handler)(int32);
- void (*sa_sigaction)(int32, siginfo *, void *);
- } u; /* signal handler */
- uint8 sa_mask[128]; /* signal mask to apply. 128? are they KIDDING? */
- int32 sa_flags; /* see signal options below */
- void (*sa_restorer) (void); /* unused here; needed to return from trap? */
-} sigaction;
+// This is a struct sigaction from /usr/include/asm/signal.h
+struct sigaction {
+ void (*sa_handler)(int32, struct siginfo*, void*);
+ uint64 sa_flags;
+ void (*sa_restorer)(void);
+ uint64 sa_mask;
+};
void
-sighandler(int32 sig, siginfo* info, void** context)
+sighandler(int32 sig, struct siginfo* info, void** context)
{
if(panicking) // traceback already printed
sys·exit(2);
sigaltstack(&st, nil);
}
-static sigaction a;
+void rt_sigaction(int64, void*, void*, uint64);
+
+enum {
+ SA_RESTART = 0x10000000,
+ SA_ONSTACK = 0x08000000,
+ SA_RESTORER = 0x04000000,
+ SA_SIGINFO = 0x00000004,
+};
void
initsig(void)
{
+ static struct sigaction sa;
+
int32 i;
- a.u.sa_sigaction = (void*)sigtramp;
- a.sa_flags = 0x08000004; /* SA_ONSTACK, SA_SIGINFO */
- for(i=0; i<sizeof(a.sa_mask); i++)
- a.sa_mask[i] = 0xFF;
-
- for(i = 0; i<NSIG; i++)
- if(sigtab[i].catch){
- sys·rt_sigaction(i, &a, (void*)0, 8);
+ sa.sa_flags = SA_ONSTACK | SA_SIGINFO | SA_RESTORER;
+ sa.sa_mask = 0xFFFFFFFFFFFFFFFFULL;
+ sa.sa_restorer = (void*)sigreturn;
+ for(i = 0; i<NSIG; i++) {
+ if(sigtab[i].flags) {
+ if(sigtab[i].flags & SigCatch)
+ sa.sa_handler = (void*)sigtramp;
+ else
+ sa.sa_handler = (void*)sigignore;
+ if(sigtab[i].flags & SigRestart)
+ sa.sa_flags |= SA_RESTART;
+ else
+ sa.sa_flags &= ~SA_RESTART;
+ rt_sigaction(i, &sa, nil, 8);
}
+ }
}
typedef struct Stktop Stktop;
typedef struct String *string;
typedef struct Usema Usema;
+typedef struct SigTab SigTab;
/*
* per cpu declaration
};
struct SigTab
{
- int32 catch;
+ int32 flags;
int8 *name;
};
+enum
+{
+ SigCatch = 1<<0,
+ SigIgnore = 1<<1,
+ SigRestart = 1<<2,
+};
// (will be) shared with go; edit ../cmd/6g/sys.go too.
// should move out of sys.go eventually.
void sys·memclr(byte*, uint32);
void sys·setcallerpc(void*, void*);
void* sys·getcallerpc(void*);
-void sys·sigaction(int64, void*, void*);
-void sys·rt_sigaction(int64, void*, void*, uint64);
/*
* runtime go-called
+++ /dev/null
-// 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.
-
-
-static struct SigTab sigtab[] = {
- /* 0 */ 0, "SIGNONE: no trap",
- /* 1 */ 0, "SIGHUP: terminal line hangup",
- /* 2 */ 0, "SIGINT: interrupt program",
- /* 3 */ 1, "SIGQUIT: quit program",
- /* 4 */ 1, "SIGILL: illegal instruction",
- /* 5 */ 1, "SIGTRAP: trace trap", /* used by panic and array out of bounds, etc. */
- /* 6 */ 1, "SIGABRT: abort program",
- /* 7 */ 1, "SIGEMT: emulate instruction executed",
- /* 8 */ 1, "SIGFPE: floating-point exception",
- /* 9 */ 0, "SIGKILL: kill program",
- /* 10 */ 1, "SIGBUS: bus error",
- /* 11 */ 1, "SIGSEGV: segmentation violation",
- /* 12 */ 1, "SIGSYS: non-existent system call invoked",
- /* 13 */ 0, "SIGPIPE: write on a pipe with no reader",
- /* 14 */ 0, "SIGALRM: real-time timer expired",
- /* 15 */ 0, "SIGTERM: software termination signal",
- /* 16 */ 0, "SIGURG: urgent condition present on socket",
- /* 17 */ 0, "SIGSTOP: stop",
- /* 18 */ 0, "SIGTSTP: stop signal generated from keyboard",
- /* 19 */ 0, "SIGCONT: continue after stop",
- /* 20 */ 0, "SIGCHLD: child status has changed",
- /* 21 */ 0, "SIGTTIN: background read attempted from control terminal",
- /* 22 */ 0, "SIGTTOU: background write attempted to control terminal",
- /* 23 */ 0, "SIGIO: I/O is possible on a descriptor",
- /* 24 */ 0, "SIGXCPU: cpu time limit exceeded",
- /* 25 */ 0, "SIGXFSZ: file size limit exceeded",
- /* 26 */ 0, "SIGVTALRM: virtual time alarm",
- /* 27 */ 0, "SIGPROF: profiling timer alarm",
- /* 28 */ 0, "SIGWINCH: Window size change",
- /* 29 */ 0, "SIGINFO: status request from keyboard",
- /* 30 */ 0, "SIGUSR1: User defined signal 1",
- /* 31 */ 0, "SIGUSR2: User defined signal 2",
-};
-#define NSIG 32
--- /dev/null
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+
+#define C SigCatch
+#define I SigIgnore
+#define R SigRestart
+
+static SigTab sigtab[] = {
+ /* 0 */ 0, "SIGNONE: no trap",
+ /* 1 */ 0, "SIGHUP: terminal line hangup",
+ /* 2 */ 0, "SIGINT: interrupt",
+ /* 3 */ C, "SIGQUIT: quit",
+ /* 4 */ C, "SIGILL: illegal instruction",
+ /* 5 */ C, "SIGTRAP: trace trap", /* used by panic and array out of bounds, etc. */
+ /* 6 */ C, "SIGABRT: abort",
+ /* 7 */ C, "SIGEMT: emulate instruction executed",
+ /* 8 */ C, "SIGFPE: floating-point exception",
+ /* 9 */ 0, "SIGKILL: kill",
+ /* 10 */ C, "SIGBUS: bus error",
+ /* 11 */ C, "SIGSEGV: segmentation violation",
+ /* 12 */ C, "SIGSYS: bad system call",
+ /* 13 */ 0, "SIGPIPE: write to broken pipe",
+ /* 14 */ 0, "SIGALRM: alarm clock",
+ /* 15 */ 0, "SIGTERM: termination",
+ /* 16 */ 0, "SIGURG: urgent condition on socket",
+ /* 17 */ 0, "SIGSTOP: stop",
+ /* 18 */ 0, "SIGTSTP: keyboard stop",
+ /* 19 */ 0, "SIGCONT: continue after stop",
+ /* 20 */ I+R, "SIGCHLD: child status has changed",
+ /* 21 */ 0, "SIGTTIN: background read from tty",
+ /* 22 */ 0, "SIGTTOU: background write to tty",
+ /* 23 */ 0, "SIGIO: i/o now possible",
+ /* 24 */ 0, "SIGXCPU: cpu limit exceeded",
+ /* 25 */ 0, "SIGXFSZ: file size limit exceeded",
+ /* 26 */ 0, "SIGVTALRM: virtual alarm clock",
+ /* 27 */ 0, "SIGPROF: profiling alarm clock",
+ /* 28 */ I+R, "SIGWINCH: window size change",
+ /* 29 */ 0, "SIGINFO: status request from keyboard",
+ /* 30 */ 0, "SIGUSR1: user-defined signal 1",
+ /* 31 */ 0, "SIGUSR2: user-defined signal 2",
+};
+#undef C
+#undef I
+#undef R
+
+#define NSIG 32
--- /dev/null
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+
+#define C SigCatch
+#define I SigIgnore
+#define R SigRestart
+
+static SigTab sigtab[] = {
+ /* 0 */ 0, "SIGNONE: no trap",
+ /* 1 */ 0, "SIGHUP: terminal line hangup",
+ /* 2 */ 0, "SIGINT: interrupt",
+ /* 3 */ C, "SIGQUIT: quit",
+ /* 4 */ C, "SIGILL: illegal instruction",
+ /* 5 */ C, "SIGTRAP: trace trap",
+ /* 6 */ C, "SIGABRT: abort",
+ /* 7 */ C, "SIGBUS: bus error",
+ /* 8 */ C, "SIGFPE: floating-point exception",
+ /* 9 */ 0, "SIGKILL: kill",
+ /* 10 */ 0, "SIGUSR1: user-defined signal 1",
+ /* 11 */ C, "SIGSEGV: segmentation violation",
+ /* 12 */ 0, "SIGUSR2: user-defined signal 2",
+ /* 13 */ 0, "SIGPIPE: write to broken pipe",
+ /* 14 */ 0, "SIGALRM: alarm clock",
+ /* 15 */ 0, "SIGTERM: termination",
+ /* 16 */ 0, "SIGSTKFLT: stack fault",
+ /* 17 */ I+R, "SIGCHLD: child status has changed",
+ /* 18 */ 0, "SIGCONT: continue",
+ /* 19 */ 0, "SIGSTOP: stop, unblockable",
+ /* 20 */ 0, "SIGTSTP: keyboard stop",
+ /* 21 */ 0, "SIGTTIN: background read from tty",
+ /* 22 */ 0, "SIGTTOU: background write to tty",
+ /* 23 */ 0, "SIGURG: urgent condition on socket",
+ /* 24 */ 0, "SIGXCPU: cpu limit exceeded",
+ /* 25 */ 0, "SIGXFSZ: file size limit exceeded",
+ /* 26 */ 0, "SIGVTALRM: virtual alarm clock",
+ /* 27 */ 0, "SIGPROF: profiling alarm clock",
+ /* 28 */ I+R, "SIGWINCH: window size change",
+ /* 29 */ 0, "SIGIO: i/o now possible",
+ /* 30 */ 0, "SIGPWR: power failure restart",
+ /* 31 */ C, "SIGSYS: bad system call",
+};
+#undef C
+#undef I
+#undef R
+
+#define NSIG 32
SYSCALL
RET
-TEXT sys·sigaction(SB),7,$-8
+TEXT sigaction(SB),7,$-8
MOVL 8(SP), DI // arg 1 sig
MOVQ 16(SP), SI // arg 2 act
MOVQ 24(SP), DX // arg 3 oact
CALL notok(SB)
RET
-TEXT sigtramp(SB),7,$24
+TEXT sigtramp(SB),7,$40
MOVQ 32(R14), R15 // g = m->gsignal
MOVL DX,0(SP)
MOVQ CX,8(SP)
MOVQ R8,16(SP)
- CALL sighandler(SB)
- RET
+ MOVQ R8, 24(SP) // save ucontext
+ MOVQ SI, 32(SP) // save infostyle
+ CALL DI
+ MOVL $(0x2000000+184), AX // sigreturn(ucontext, infostyle)
+ MOVQ 24(SP), DI // saved ucontext
+ MOVQ 32(SP), SI // saved infostyle
+ SYSCALL
+ INT $3 // not reached
TEXT sys·mmap(SB),7,$-8
MOVQ 8(SP), DI // arg 1 addr
SYSCALL
RET
-TEXT sys·rt_sigaction(SB),7,$0-32
+TEXT rt_sigaction(SB),7,$0-32
MOVL 8(SP), DI
MOVQ 16(SP), SI
MOVQ 24(SP), DX
CALL sighandler(SB)
RET
+TEXT sigignore(SB),7,$0
+ RET
+
+TEXT sigreturn(SB),7,$0
+ MOVL $15, AX // rt_sigreturn
+ SYSCALL
+ INT $3 // not reached
+
TEXT sys·mmap(SB),7,$0-32
MOVQ 8(SP), DI
MOVQ $0, SI
-9223372036854775808
9223372036854775807
+=========== ./sigchld.go
+survived SIGCHLD
+
=========== ./turing.go
Hello World!
--- /dev/null
+// $G $D/$F.go && $L $F.$A && ./$A.out
+
+// 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.
+
+package main
+
+import "syscall"
+
+func getpid() int64 {
+ r1, r2, err := syscall.Syscall(syscall.SYS_GETPID, 0, 0, 0);
+ return r1;
+}
+
+func main() {
+ syscall.Syscall(syscall.SYS_KILL, getpid(), syscall.SIGCHLD, 0);
+ println("survived SIGCHLD");
+}