diff --git a/src/runtime/rt0_amd64_darwin.s b/src/runtime/rt0_amd64_darwin.s index 824a602554e..16592b90ae2 100644 --- a/src/runtime/rt0_amd64_darwin.s +++ b/src/runtime/rt0_amd64_darwin.s @@ -52,6 +52,25 @@ TEXT sys_write(SB),1,$-8 CALL notok(SB) RET +TEXT sys_sigaction(SB),1,$-8 + MOVL 8(SP), DI // arg 1 sig + MOVQ 16(SP), SI // arg 2 act + MOVQ 24(SP), DX // arg 3 oact + MOVQ 24(SP), CX // arg 3 oact + MOVQ 24(SP), R10 // arg 3 oact + MOVL $(0x2000000+46), AX // syscall entry + SYSCALL + JCC 2(PC) + CALL notok(SB) + RET + +TEXT sigtramp(SB),1,$-24 + MOVL DX,0(SP) + MOVQ CX,8(SP) + MOVQ R8,16(SP) + CALL sighandler(SB) + RET + TEXT sys_breakpoint(SB),1,$-8 BYTE $0xcc RET diff --git a/src/runtime/rt1_amd64_darwin.c b/src/runtime/rt1_amd64_darwin.c index fe92d0b292f..c24b40fae5b 100644 --- a/src/runtime/rt1_amd64_darwin.c +++ b/src/runtime/rt1_amd64_darwin.c @@ -3,9 +3,75 @@ // license that can be found in the LICENSE file. #include "runtime.h" +#include "signals.h" + +/* + * This assembler routine takes the args from registers, puts them on the stack, + * and calls sighandler(). + */ +extern void sigtramp(); + +/* + * Rudimentary reverse-engineered definition of signal interface. + * You'd think it would be documented. + */ +typedef struct siginfo { + int32 si_signo; /* signal number */ + int32 si_errno; /* errno association */ + int32 si_code; /* signal code */ + int32 si_pid; /* sending process */ + int32 si_uid; /* sender's ruid */ + 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; + +void +sighandler(int32 sig, siginfo* info, void** context) { + int32 i; + + if(sig < 0 || sig >= NSIG){ + prints("Signal "); + sys_printint(sig); + }else{ + prints(sigtab[sig].name); + } + prints("\nFaulting address: 0x"); + sys_printpointer(info->si_addr); + prints("\nPC: 0x"); + sys_printpointer(((void**)((&sig)+1))[22]); + prints("\nSP: 0x"); + sys_printpointer(((void**)((&sig)+1))[13]); + prints("\n"); + traceback(((void**)((&sig)+1))[22], ((void**)((&sig)+1))[13]); /* empirically discovered locations */ + sys_exit(2); +} + +sigaction a; +extern void sigtramp(void); void initsig(void) { - /* no signal handler on mac yet */ + int32 i; + a.u.sa_sigaction = (void*)sigtramp; + a.sa_flags |= 0x40; /* SA_SIGINFO */ + for(i=0; i