]> Cypherpunks repositories - gostls13.git/commitdiff
runtime: fix netbsd signal handling
authorJoel Sing <jsing@google.com>
Tue, 15 May 2012 15:53:26 +0000 (01:53 +1000)
committerJoel Sing <jsing@google.com>
Tue, 15 May 2012 15:53:26 +0000 (01:53 +1000)
Update/correct NetBSD signal handling - most of this is needed due to
the correctly generated runtime definitions.

R=golang-dev, m4dh4tt3r, rsc
CC=golang-dev
https://golang.org/cl/6195079

src/pkg/runtime/signal_netbsd_386.c
src/pkg/runtime/signal_netbsd_amd64.c
src/pkg/runtime/signals_netbsd.h

index b4871ee8e0837a1a3076fa5f56b6f2271bd49b18..f5eb913b60e257005375da7dd3dd215fa09dd902 100644 (file)
@@ -19,64 +19,66 @@ typedef struct sigaction {
 } Sigaction;
 
 void
-runtime·dumpregs(Sigcontext *r)
+runtime·dumpregs(McontextT *mc)
 {
-       runtime·printf("eax     %x\n", r->sc_eax);
-       runtime·printf("ebx     %x\n", r->sc_ebx);
-       runtime·printf("ecx     %x\n", r->sc_ecx);
-       runtime·printf("edx     %x\n", r->sc_edx);
-       runtime·printf("edi     %x\n", r->sc_edi);
-       runtime·printf("esi     %x\n", r->sc_esi);
-       runtime·printf("ebp     %x\n", r->sc_ebp);
-       runtime·printf("esp     %x\n", r->sc_esp);
-       runtime·printf("eip     %x\n", r->sc_eip);
-       runtime·printf("eflags  %x\n", r->sc_eflags);
-       runtime·printf("cs      %x\n", r->sc_cs);
-       runtime·printf("fs      %x\n", r->sc_fs);
-       runtime·printf("gs      %x\n", r->sc_gs);
+       runtime·printf("eax     %x\n", mc->__gregs[REG_EAX]);
+       runtime·printf("ebx     %x\n", mc->__gregs[REG_EBX]);
+       runtime·printf("ecx     %x\n", mc->__gregs[REG_ECX]);
+       runtime·printf("edx     %x\n", mc->__gregs[REG_EDX]);
+       runtime·printf("edi     %x\n", mc->__gregs[REG_EDI]);
+       runtime·printf("esi     %x\n", mc->__gregs[REG_ESI]);
+       runtime·printf("ebp     %x\n", mc->__gregs[REG_EBP]);
+       runtime·printf("esp     %x\n", mc->__gregs[REG_ESP]);
+       runtime·printf("eip     %x\n", mc->__gregs[REG_EIP]);
+       runtime·printf("eflags  %x\n", mc->__gregs[REG_EFL]);
+       runtime·printf("cs      %x\n", mc->__gregs[REG_CS]);
+       runtime·printf("fs      %x\n", mc->__gregs[REG_FS]);
+       runtime·printf("gs      %x\n", mc->__gregs[REG_GS]);
 }
 
 void
 runtime·sighandler(int32 sig, Siginfo *info, void *context, G *gp)
 {
-       Sigcontext *r = context;
+       UcontextT *uc = context;
+       McontextT *mc = &uc->uc_mcontext;
        uintptr *sp;
        SigTab *t;
 
        if(sig == SIGPROF) {
-               runtime·sigprof((uint8*)r->sc_eip, (uint8*)r->sc_esp, nil, gp);
+               runtime·sigprof((uint8*)mc->__gregs[REG_EIP],
+                       (uint8*)mc->__gregs[REG_ESP], nil, gp);
                return;
        }
 
        t = &runtime·sigtab[sig];
-       if(info->si_code != SI_USER && (t->flags & SigPanic)) {
+       if(info->_code != SI_USER && (t->flags & SigPanic)) {
                if(gp == nil)
                        goto Throw;
                // Make it look like a call to the signal func.
-               // Have to pass arguments out of band since
+               // We need to pass arguments out of band since
                // augmenting the stack frame would break
                // the unwinding code.
                gp->sig = sig;
-               gp->sigcode0 = info->si_code;
-               gp->sigcode1 = *(uintptr*)((byte*)info + 12); /* si_addr */
-               gp->sigpc = r->sc_eip;
-
-               // Only push runtime·sigpanic if r->sc_eip != 0.
-               // If r->sc_eip == 0, probably panicked because of a
-               // call to a nil func.  Not pushing that onto sp will
-               // make the trace look like a call to runtime·sigpanic instead.
-               // (Otherwise the trace will end at runtime·sigpanic and we
-               // won't get to see who faulted.)
-               if(r->sc_eip != 0) {
-                       sp = (uintptr*)r->sc_esp;
-                       *--sp = r->sc_eip;
-                       r->sc_esp = (uintptr)sp;
+               gp->sigcode0 = info->_code;
+               gp->sigcode1 = *(uintptr*)&info->_reason[0]; /* _addr */
+               gp->sigpc = mc->__gregs[REG_EIP];
+
+               // Only push runtime·sigpanic if __gregs[REG_EIP] != 0.
+               // If __gregs[REG_EIP] == 0, probably panicked because of a
+               // call to a nil func. Not pushing that onto sp will make the
+               // trace look like a call to runtime·sigpanic instead.
+               // (Otherwise the trace will end at runtime·sigpanic
+               // and we won't get to see who faulted.)
+               if(mc->__gregs[REG_EIP] != 0) {
+                       sp = (uintptr*)mc->__gregs[REG_ESP];
+                       *--sp = mc->__gregs[REG_EIP];
+                       mc->__gregs[REG_ESP] = (uintptr)sp;
                }
-               r->sc_eip = (uintptr)runtime·sigpanic;
+               mc->__gregs[REG_EIP] = (uintptr)runtime·sigpanic;
                return;
        }
 
-       if(info->si_code == SI_USER || (t->flags & SigNotify))
+       if(info->_code == SI_USER || (t->flags & SigNotify))
                if(runtime·sigsend(sig))
                        return;
        if(t->flags & SigKill)
@@ -92,13 +94,14 @@ Throw:
        else
                runtime·printf("%s\n", runtime·sigtab[sig].name);
 
-       runtime·printf("PC=%X\n", r->sc_eip);
+       runtime·printf("PC=%X\n", mc->__gregs[REG_EIP]);
        runtime·printf("\n");
 
        if(runtime·gotraceback()){
-               runtime·traceback((void*)r->sc_eip, (void*)r->sc_esp, 0, gp);
+               runtime·traceback((void*)mc->__gregs[REG_EIP],
+                       (void*)mc->__gregs[REG_ESP], 0, gp);
                runtime·tracebackothers(gp);
-               runtime·dumpregs(r);
+               runtime·dumpregs(mc);
        }
 
        runtime·exit(2);
@@ -109,7 +112,7 @@ runtime·signalstack(byte *p, int32 n)
 {
        Sigaltstack st;
 
-       st.ss_sp = (int8*)p;
+       st.ss_sp = p;
        st.ss_size = n;
        st.ss_flags = 0;
        runtime·sigaltstack(&st, nil);
index a27f9db24db3166870e35be1a91ff156bd0dea70..f8172c31f0e766032c1f1fba948adcdab38a63c1 100644 (file)
@@ -19,73 +19,73 @@ typedef struct sigaction {
 } Sigaction;
 
 void
-runtime·dumpregs(Sigcontext *r)
+runtime·dumpregs(McontextT *mc)
 {
-       runtime·printf("rax     %X\n", r->sc_rax);
-       runtime·printf("rbx     %X\n", r->sc_rbx);
-       runtime·printf("rcx     %X\n", r->sc_rcx);
-       runtime·printf("rdx     %X\n", r->sc_rdx);
-       runtime·printf("rdi     %X\n", r->sc_rdi);
-       runtime·printf("rsi     %X\n", r->sc_rsi);
-       runtime·printf("rbp     %X\n", r->sc_rbp);
-       runtime·printf("rsp     %X\n", r->sc_rsp);
-       runtime·printf("r8      %X\n", r->sc_r8);
-       runtime·printf("r9      %X\n", r->sc_r9);
-       runtime·printf("r10     %X\n", r->sc_r10);
-       runtime·printf("r11     %X\n", r->sc_r11);
-       runtime·printf("r12     %X\n", r->sc_r12);
-       runtime·printf("r13     %X\n", r->sc_r13);
-       runtime·printf("r14     %X\n", r->sc_r14);
-       runtime·printf("r15     %X\n", r->sc_r15);
-       runtime·printf("rip     %X\n", r->sc_rip);
-       runtime·printf("rflags  %X\n", r->sc_rflags);
-       runtime·printf("cs      %X\n", r->sc_cs);
-       runtime·printf("fs      %X\n", r->sc_fs);
-       runtime·printf("gs      %X\n", r->sc_gs);
+       runtime·printf("rax     %X\n", mc->__gregs[REG_RAX]);
+       runtime·printf("rbx     %X\n", mc->__gregs[REG_RBX]);
+       runtime·printf("rcx     %X\n", mc->__gregs[REG_RCX]);
+       runtime·printf("rdx     %X\n", mc->__gregs[REG_RDX]);
+       runtime·printf("rdi     %X\n", mc->__gregs[REG_RDI]);
+       runtime·printf("rsi     %X\n", mc->__gregs[REG_RSI]);
+       runtime·printf("rbp     %X\n", mc->__gregs[REG_RBP]);
+       runtime·printf("rsp     %X\n", mc->__gregs[REG_RSP]);
+       runtime·printf("r8      %X\n", mc->__gregs[REG_R8]);
+       runtime·printf("r9      %X\n", mc->__gregs[REG_R9]);
+       runtime·printf("r10     %X\n", mc->__gregs[REG_R10]);
+       runtime·printf("r11     %X\n", mc->__gregs[REG_R11]);
+       runtime·printf("r12     %X\n", mc->__gregs[REG_R12]);
+       runtime·printf("r13     %X\n", mc->__gregs[REG_R13]);
+       runtime·printf("r14     %X\n", mc->__gregs[REG_R14]);
+       runtime·printf("r15     %X\n", mc->__gregs[REG_R15]);
+       runtime·printf("rip     %X\n", mc->__gregs[REG_RIP]);
+       runtime·printf("rflags  %X\n", mc->__gregs[REG_RFLAGS]);
+       runtime·printf("cs      %X\n", mc->__gregs[REG_CS]);
+       runtime·printf("fs      %X\n", mc->__gregs[REG_FS]);
+       runtime·printf("gs      %X\n", mc->__gregs[REG_GS]);
 }
 
 void
 runtime·sighandler(int32 sig, Siginfo *info, void *context, G *gp)
 {
-       Sigcontext *r = context;
+       UcontextT *uc = context;
+       McontextT *mc = &uc->uc_mcontext;
        uintptr *sp;
        SigTab *t;
 
        if(sig == SIGPROF) {
-               runtime·sigprof((uint8*)r->sc_rip,
-                       (uint8*)r->sc_rsp, nil, gp);
+               runtime·sigprof((uint8*)mc->__gregs[REG_RIP],
+                       (uint8*)mc->__gregs[REG_RSP], nil, gp);
                return;
        }
 
        t = &runtime·sigtab[sig];
-       if(info->si_code != SI_USER && (t->flags & SigPanic)) {
+       if(info->_code != SI_USER && (t->flags & SigPanic)) {
                if(gp == nil)
                        goto Throw;
                // Make it look like a call to the signal func.
-               // Have to pass arguments out of band since
-               // augmenting the stack frame would break
-               // the unwinding code.
+               // We need to pass arguments out of band since augmenting the
+               // stack frame would break the unwinding code.
                gp->sig = sig;
-               gp->sigcode0 = info->si_code;
-               gp->sigcode1 = *(uintptr*)((byte*)info + 16); /* si_addr */
-               gp->sigpc = r->sc_rip;
-
-               // Only push runtime·sigpanic if r->mc_rip != 0.
-               // If r->mc_rip == 0, probably panicked because of a
-               // call to a nil func.  Not pushing that onto sp will
-               // make the trace look like a call to runtime·sigpanic instead.
-               // (Otherwise the trace will end at runtime·sigpanic and we
-               // won't get to see who faulted.)
-               if(r->sc_rip != 0) {
-                       sp = (uintptr*)r->sc_rsp;
-                       *--sp = r->sc_rip;
-                       r->sc_rsp = (uintptr)sp;
+               gp->sigcode0 = info->_code;
+               gp->sigcode1 = *(uintptr*)&info->_reason[0]; /* _addr */
+               gp->sigpc = mc->__gregs[REG_RIP];
+
+               // Only push runtime·sigpanic if __gregs[REG_RIP] != 0.
+               // If __gregs[REG_RIP] == 0, probably panicked because of a
+               // call to a nil func. Not pushing that onto sp will make the
+               // trace look like a call to runtime·sigpanic instead.
+               // (Otherwise the trace will end at runtime·sigpanic
+               // and we won't get to see who faulted.)
+               if(mc->__gregs[REG_RIP] != 0) {
+                       sp = (uintptr*)mc->__gregs[REG_RSP];
+                       *--sp = mc->__gregs[REG_RIP];
+                       mc->__gregs[REG_RSP] = (uintptr)sp;
                }
-               r->sc_rip = (uintptr)runtime·sigpanic;
+               mc->__gregs[REG_RIP] = (uintptr)runtime·sigpanic;
                return;
        }
 
-       if(info->si_code == SI_USER || (t->flags & SigNotify))
+       if(info->_code == SI_USER || (t->flags & SigNotify))
                if(runtime·sigsend(sig))
                        return;
        if(t->flags & SigKill)
@@ -101,13 +101,14 @@ Throw:
        else
                runtime·printf("%s\n", runtime·sigtab[sig].name);
 
-       runtime·printf("PC=%X\n", r->sc_rip);
+       runtime·printf("PC=%X\n", mc->__gregs[REG_RIP]);
        runtime·printf("\n");
 
        if(runtime·gotraceback()){
-               runtime·traceback((void*)r->sc_rip, (void*)r->sc_rsp, 0, gp);
+               runtime·traceback((void*)mc->__gregs[REG_RIP],
+                       (void*)mc->__gregs[REG_RSP], 0, gp);
                runtime·tracebackothers(gp);
-               runtime·dumpregs(r);
+               runtime·dumpregs(mc);
        }
 
        runtime·exit(2);
@@ -118,7 +119,7 @@ runtime·signalstack(byte *p, int32 n)
 {
        Sigaltstack st;
 
-       st.ss_sp = (int8*)p;
+       st.ss_sp = p;
        st.ss_size = n;
        st.ss_flags = 0;
        runtime·sigaltstack(&st, nil);
index 4d27e050d089de91e83ba4b399d4254d60435716..7140de86fcfc3bb9c777dfd8f8c21b3566a5120d 100644 (file)
@@ -9,16 +9,16 @@
 #define D SigDefault
 
 SigTab runtime·sigtab[] = {
-       /* 0 */ 0, "SIGNONE: no trap",
-       /* 1 */ N+K, "SIGHUP: terminal line hangup",
-       /* 2 */ N+K, "SIGINT: interrupt",
-       /* 3 */ N+T, "SIGQUIT: quit",
-       /* 4 */ T, "SIGILL: illegal instruction",
-       /* 5 */ T, "SIGTRAP: trace trap",
-       /* 6 */ N+T, "SIGABRT: abort",
-       /* 7 */ T, "SIGEMT: emulate instruction executed",
-       /* 8 */ P, "SIGFPE: floating-point exception",
-       /* 9 */ 0, "SIGKILL: kill",
+       /*  0 */        0, "SIGNONE: no trap",
+       /*  1 */        N+K, "SIGHUP: terminal line hangup",
+       /*  2 */        N+K, "SIGINT: interrupt",
+       /*  3 */        N+T, "SIGQUIT: quit",
+       /*  4 */        T, "SIGILL: illegal instruction",
+       /*  5 */        T, "SIGTRAP: trace trap",
+       /*  6 */        N+T, "SIGABRT: abort",
+       /*  7 */        T, "SIGEMT: emulate instruction executed",
+       /*  8 */        P, "SIGFPE: floating-point exception",
+       /*  9 */        0, "SIGKILL: kill",
        /* 10 */        P, "SIGBUS: bus error",
        /* 11 */        P, "SIGSEGV: segmentation violation",
        /* 12 */        T, "SIGSYS: bad system call",