From dfa5893d4f5a5724e36e1265eba4e148ca42911f Mon Sep 17 00:00:00 2001 From: Russ Cox Date: Wed, 3 Dec 2008 14:21:28 -0800 Subject: [PATCH] preparation for exec. * syscall: add syscall.RawSyscall, which doesn't use sys.entersyscall/sys.exitsyscall add syscall.dup2 add syscall.BytePtrPtr add syscall.Rusage, RusagePtr add syscall.F_GETFD, F_SETFD, FD_CLOEXEC * runtime: clean up, correct signal handling. can now survive (continue running after) a signal. R=r DELTA=394 (286 added, 51 deleted, 57 changed) OCL=20351 CL=20369 --- src/lib/syscall/Makefile | 5 +- src/lib/syscall/asm_amd64_darwin.s | 18 +++++++ src/lib/syscall/asm_amd64_linux.s | 19 +++++++ src/lib/syscall/cast_amd64.s | 10 ++++ src/lib/syscall/file_darwin.go | 6 +++ src/lib/syscall/file_linux.go | 6 +++ src/lib/syscall/syscall.go | 2 + src/lib/syscall/types_amd64_darwin.go | 28 ++++++++++ src/lib/syscall/types_amd64_linux.go | 28 ++++++++++ src/runtime/rt1_amd64_darwin.c | 73 ++++++++++++++++----------- src/runtime/rt1_amd64_linux.c | 65 ++++++++++++++---------- src/runtime/runtime.h | 11 ++-- src/runtime/signals.h | 40 --------------- src/runtime/signals_darwin.h | 48 ++++++++++++++++++ src/runtime/signals_linux.h | 48 ++++++++++++++++++ src/runtime/sys_amd64_darwin.s | 14 +++-- src/runtime/sys_amd64_linux.s | 10 +++- test/golden.out | 3 ++ test/sigchld.go | 19 +++++++ 19 files changed, 348 insertions(+), 105 deletions(-) delete mode 100644 src/runtime/signals.h create mode 100644 src/runtime/signals_darwin.h create mode 100644 src/runtime/signals_linux.h create mode 100644 test/sigchld.go diff --git a/src/lib/syscall/Makefile b/src/lib/syscall/Makefile index 8dd3d2fe0f..5f613b9b42 100644 --- a/src/lib/syscall/Makefile +++ b/src/lib/syscall/Makefile @@ -5,7 +5,7 @@ # 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 @@ -40,6 +40,7 @@ O1=\ asm_$(GOARCH)_$(GOOS).$O\ cast_$(GOARCH).$O\ syscall.$O\ + signal_$(GOARCH)_$(GOOS).$O\ O2=\ file_$(GOOS).$O\ @@ -49,7 +50,7 @@ O2=\ 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) diff --git a/src/lib/syscall/asm_amd64_darwin.s b/src/lib/syscall/asm_amd64_darwin.s index 3cf6aad831..dbc345c19d 100644 --- a/src/lib/syscall/asm_amd64_darwin.s +++ b/src/lib/syscall/asm_amd64_darwin.s @@ -54,3 +54,21 @@ ok6: 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 diff --git a/src/lib/syscall/asm_amd64_linux.s b/src/lib/syscall/asm_amd64_linux.s index e0c1153878..2826c1b580 100644 --- a/src/lib/syscall/asm_amd64_linux.s +++ b/src/lib/syscall/asm_amd64_linux.s @@ -57,3 +57,22 @@ ok6: 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 diff --git a/src/lib/syscall/cast_amd64.s b/src/lib/syscall/cast_amd64.s index c2205b990e..3eaa5e70e6 100644 --- a/src/lib/syscall/cast_amd64.s +++ b/src/lib/syscall/cast_amd64.s @@ -8,6 +8,11 @@ TEXT syscall·BytePtr(SB),7,$-8 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) @@ -53,6 +58,11 @@ TEXT syscall·TimevalPtr(SB),7,$-8 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) diff --git a/src/lib/syscall/file_darwin.go b/src/lib/syscall/file_darwin.go index 2cb78ffe5c..0c6a38a3ad 100644 --- a/src/lib/syscall/file_darwin.go +++ b/src/lib/syscall/file_darwin.go @@ -94,3 +94,9 @@ export func mkdir(name string, perm int64) (ret int64, errno int64) { 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; +} + diff --git a/src/lib/syscall/file_linux.go b/src/lib/syscall/file_linux.go index af7728a6b1..3fa2588aff 100644 --- a/src/lib/syscall/file_linux.go +++ b/src/lib/syscall/file_linux.go @@ -95,3 +95,9 @@ export func mkdir(name string, perm int64) (ret int64, errno int64) { 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; +} + diff --git a/src/lib/syscall/syscall.go b/src/lib/syscall/syscall.go index 6420684ce0..eb1ad36a64 100644 --- a/src/lib/syscall/syscall.go +++ b/src/lib/syscall/syscall.go @@ -10,10 +10,12 @@ package syscall 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, diff --git a/src/lib/syscall/types_amd64_darwin.go b/src/lib/syscall/types_amd64_darwin.go index bb715ccb16..2c98fd521e 100644 --- a/src/lib/syscall/types_amd64_darwin.go +++ b/src/lib/syscall/types_amd64_darwin.go @@ -23,6 +23,29 @@ export type Timeval 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 ( @@ -38,8 +61,13 @@ 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 { diff --git a/src/lib/syscall/types_amd64_linux.go b/src/lib/syscall/types_amd64_linux.go index 534827e3e9..ccca2671cd 100644 --- a/src/lib/syscall/types_amd64_linux.go +++ b/src/lib/syscall/types_amd64_linux.go @@ -23,6 +23,29 @@ export type Timeval 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 ( @@ -38,8 +61,13 @@ 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 { diff --git a/src/runtime/rt1_amd64_darwin.c b/src/runtime/rt1_amd64_darwin.c index 82999b89f9..7bd7c78fdc 100644 --- a/src/runtime/rt1_amd64_darwin.c +++ b/src/runtime/rt1_amd64_darwin.c @@ -4,7 +4,7 @@ #include "runtime.h" #include "amd64_darwin.h" -#include "signals.h" +#include "signals_darwin.h" typedef uint64 __uint64_t; @@ -100,15 +100,14 @@ static _STRUCT_X86_FLOAT_STATE64 *get___fs(_STRUCT_MCONTEXT64 *ptr) { /* * 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 */ @@ -117,21 +116,17 @@ typedef struct siginfo { 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); @@ -159,15 +154,17 @@ sighandler(int32 sig, siginfo *info, void *context) 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) { @@ -179,21 +176,39 @@ 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; + static struct sigaction sa; - a.u.sa_sigaction = (void*)sigtramp; - a.sa_flags |= 0x41; /* SA_SIGINFO, SA_ONSTACK */ - for(i=0; igsignal 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 diff --git a/src/runtime/sys_amd64_linux.s b/src/runtime/sys_amd64_linux.s index 581bf15ab5..d385bb43ec 100644 --- a/src/runtime/sys_amd64_linux.s +++ b/src/runtime/sys_amd64_linux.s @@ -63,7 +63,7 @@ TEXT sys·write(SB),7,$0-24 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 @@ -80,6 +80,14 @@ TEXT sigtramp(SB),7,$24-16 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 diff --git a/test/golden.out b/test/golden.out index 24f56b63a2..4489d69cbd 100644 --- a/test/golden.out +++ b/test/golden.out @@ -56,6 +56,9 @@ BUG: errchk: command succeeded unexpectedly: 6g ./method2.go -9223372036854775808 9223372036854775807 +=========== ./sigchld.go +survived SIGCHLD + =========== ./turing.go Hello World! diff --git a/test/sigchld.go b/test/sigchld.go new file mode 100644 index 0000000000..417b833c70 --- /dev/null +++ b/test/sigchld.go @@ -0,0 +1,19 @@ +// $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"); +}