diff options
Diffstat (limited to 'src/runtime/darwin/signal.c')
-rw-r--r-- | src/runtime/darwin/signal.c | 246 |
1 files changed, 49 insertions, 197 deletions
diff --git a/src/runtime/darwin/signal.c b/src/runtime/darwin/signal.c index 937f402e4..2325b503c 100644 --- a/src/runtime/darwin/signal.c +++ b/src/runtime/darwin/signal.c @@ -4,204 +4,100 @@ #include "runtime.h" #include "defs.h" +#include "os.h" #include "signals.h" -typedef uint64 __uint64_t; - -/* From /usr/include/mach/i386/_structs.h */ -#define _STRUCT_X86_THREAD_STATE64 struct __darwin_x86_thread_state64 -_STRUCT_X86_THREAD_STATE64 -{ - __uint64_t __rax; - __uint64_t __rbx; - __uint64_t __rcx; - __uint64_t __rdx; - __uint64_t __rdi; - __uint64_t __rsi; - __uint64_t __rbp; - __uint64_t __rsp; - __uint64_t __r8; - __uint64_t __r9; - __uint64_t __r10; - __uint64_t __r11; - __uint64_t __r12; - __uint64_t __r13; - __uint64_t __r14; - __uint64_t __r15; - __uint64_t __rip; - __uint64_t __rflags; - __uint64_t __cs; - __uint64_t __fs; - __uint64_t __gs; -}; - - void -print_thread_state(_STRUCT_X86_THREAD_STATE64* ss) +dumpregs(Regs *r) { - prints("\nrax "); sys·printhex(ss->__rax); - prints("\nrbx "); sys·printhex(ss->__rbx); - prints("\nrcx "); sys·printhex(ss->__rcx); - prints("\nrdx "); sys·printhex(ss->__rdx); - prints("\nrdi "); sys·printhex(ss->__rdi); - prints("\nrsi "); sys·printhex(ss->__rsi); - prints("\nrbp "); sys·printhex(ss->__rbp); - prints("\nrsp "); sys·printhex(ss->__rsp); - prints("\nr8 "); sys·printhex(ss->__r8 ); - prints("\nr9 "); sys·printhex(ss->__r9 ); - prints("\nr10 "); sys·printhex(ss->__r10); - prints("\nr11 "); sys·printhex(ss->__r11); - prints("\nr12 "); sys·printhex(ss->__r12); - prints("\nr13 "); sys·printhex(ss->__r13); - prints("\nr14 "); sys·printhex(ss->__r14); - prints("\nr15 "); sys·printhex(ss->__r15); - prints("\nrip "); sys·printhex(ss->__rip); - prints("\nrflags "); sys·printhex(ss->__rflags); - prints("\ncs "); sys·printhex(ss->__cs); - prints("\nfs "); sys·printhex(ss->__fs); - prints("\ngs "); sys·printhex(ss->__gs); - prints("\n"); -} - - -/* Code generated via: g++ -m64 gen_signals_support.cc && a.out */ - -static void *adr_at(void *ptr, int32 offs) { - return (void *)((uint8 *)ptr + offs); -} - -static void *ptr_at(void *ptr, int32 offs) { - return *(void **)((uint8 *)ptr + offs); -} - -typedef void ucontext_t; -typedef void _STRUCT_MCONTEXT64; -typedef void _STRUCT_X86_EXCEPTION_STATE64; -typedef void _STRUCT_X86_FLOAT_STATE64; - -static _STRUCT_MCONTEXT64 *get_uc_mcontext(ucontext_t *ptr) { - return (_STRUCT_MCONTEXT64 *)ptr_at(ptr, 48); -} - -static _STRUCT_X86_EXCEPTION_STATE64 *get___es(_STRUCT_MCONTEXT64 *ptr) { - return (_STRUCT_X86_EXCEPTION_STATE64 *)adr_at(ptr, 0); -} - -static _STRUCT_X86_THREAD_STATE64 *get___ss(_STRUCT_MCONTEXT64 *ptr) { - return (_STRUCT_X86_THREAD_STATE64 *)adr_at(ptr, 16); + printf("rax %X\n", r->rax); + printf("rbx %X\n", r->rbx); + printf("rcx %X\n", r->rcx); + printf("rdx %X\n", r->rdx); + printf("rdi %X\n", r->rdi); + printf("rsi %X\n", r->rsi); + printf("rbp %X\n", r->rbp); + printf("rsp %X\n", r->rsp); + printf("r8 %X\n", r->r8 ); + printf("r9 %X\n", r->r9 ); + printf("r10 %X\n", r->r10); + printf("r11 %X\n", r->r11); + printf("r12 %X\n", r->r12); + printf("r13 %X\n", r->r13); + printf("r14 %X\n", r->r14); + printf("r15 %X\n", r->r15); + printf("rip %X\n", r->rip); + printf("rflags %X\n", r->rflags); + printf("cs %X\n", r->cs); + printf("fs %X\n", r->fs); + printf("gs %X\n", r->gs); } -static _STRUCT_X86_FLOAT_STATE64 *get___fs(_STRUCT_MCONTEXT64 *ptr) { - return (_STRUCT_X86_FLOAT_STATE64 *)adr_at(ptr, 184); -} - -/* End of generated code */ - - -/* - * This assembler routine takes the args from registers, puts them on the stack, - * and calls the registered handler. - */ -extern void sigtramp(void); -/* - * Rudimentary reverse-engineered definition of signal interface. - * You'd think it would be documented. - */ -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 */ -}; - -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, struct siginfo *info, void *context) +sighandler(int32 sig, Siginfo *info, void *context) { + Ucontext *uc; + Mcontext *mc; + Regs *r; + if(panicking) // traceback already printed sys_Exit(2); panicking = 1; - _STRUCT_MCONTEXT64 *uc_mcontext = get_uc_mcontext(context); - _STRUCT_X86_THREAD_STATE64 *ss = get___ss(uc_mcontext); - if(sig < 0 || sig >= NSIG){ - prints("Signal "); - sys·printint(sig); + printf("Signal %d\n", sig); }else{ - prints(sigtab[sig].name); + printf("%s\n", sigtab[sig].name); } - prints("\nFaulting address: "); sys·printpointer(info->si_addr); - prints("\npc: "); sys·printhex(ss->__rip); - prints("\n\n"); + uc = context; + mc = uc->uc_mcontext; + r = &mc->ss; + + printf("Faulting address: %p\n", info->si_addr); + printf("PC=%X\n", r->rip); + printf("\n"); if(gotraceback()){ - traceback((void *)ss->__rip, (void *)ss->__rsp, (void*)ss->__r15); - tracebackothers((void*)ss->__r15); - print_thread_state(ss); + traceback((void*)r->rip, (void*)r->rsp, (void*)r->r15); + tracebackothers((void*)r->r15); + dumpregs(r); } sys_Exit(2); } void -sigignore(int32, struct siginfo*, void*) +sigignore(int32, Siginfo*, void*) { } -struct stack_t { - byte *sp; - int64 size; - int32 flags; -}; - void signalstack(byte *p, int32 n) { - struct stack_t st; + StackT st; - st.sp = p; - st.size = n; - st.flags = 0; + st.ss_sp = p; + st.ss_size = n; + st.ss_flags = 0; 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; + static Sigaction sa; sa.sa_flags |= SA_SIGINFO|SA_ONSTACK; sa.sa_mask = 0; // 0xFFFFFFFFU; - sa.sa_trampoline = sigtramp; + sa.sa_tramp = sigtramp; // sigtramp's job is to call into real handler for(i = 0; i<NSIG; i++) { if(sigtab[i].flags) { if(sigtab[i].flags & SigCatch) { - sa.sa_handler = sighandler; + sa.__sigaction_u.__sa_sigaction = sighandler; } else { - sa.sa_handler = sigignore; + sa.__sigaction_u.__sa_sigaction = sigignore; } if(sigtab[i].flags & SigRestart) sa.sa_flags |= SA_RESTART; @@ -212,47 +108,3 @@ initsig(void) } } -static void -unimplemented(int8 *name) -{ - prints(name); - prints(" not implemented\n"); - *(int32*)1231 = 1231; -} - -// Thread-safe allocation of a semaphore. -// Psema points at a kernel semaphore key. -// It starts out zero, meaning no semaphore. -// Fill it in, being careful of others calling initsema -// simultaneously. -static void -initsema(uint32 *psema) -{ - uint32 sema; - - if(*psema != 0) // already have one - return; - - sema = mach_semcreate(); - if(!cas(psema, 0, sema)){ - // Someone else filled it in. Use theirs. - mach_semdestroy(sema); - return; - } -} - - -// Atomic add and return new value. -static uint32 -xadd(uint32 volatile *val, int32 delta) -{ - uint32 oval, nval; - - for(;;){ - oval = *val; - nval = oval + delta; - if(cas(val, oval, nval)) - return nval; - } -} - |