]> Cypherpunks repositories - gostls13.git/commitdiff
add signal handling to mac runtime
authorRob Pike <r@golang.org>
Mon, 23 Jun 2008 23:34:17 +0000 (16:34 -0700)
committerRob Pike <r@golang.org>
Mon, 23 Jun 2008 23:34:17 +0000 (16:34 -0700)
SVN=124184

src/runtime/rt0_amd64_darwin.s
src/runtime/rt1_amd64_darwin.c

index 824a602554ea38fdf580c745103aeff8eb8f95e5..16592b90ae28c565def384971ebc0ba41c337fb9 100644 (file)
@@ -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
index fe92d0b292f88c50a205fc8595eefd4e5623ef78..c24b40fae5bb53dc649df0e3dbe04ffaacd05320 100644 (file)
@@ -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<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);
+               }
 }