From 3311e1b6731219c0e4f2681e3cefa3ae9dfa1547 Mon Sep 17 00:00:00 2001 From: Robert Griesemer Date: Wed, 25 Jun 2008 17:07:22 -0700 Subject: [PATCH] - dump registers in case of signal (linux) SVN=124702 --- src/runtime/rt1_amd64_darwin.c | 19 +++-- src/runtime/rt1_amd64_linux.c | 138 +++++++++++++++++++++++++++++---- test/golden.out | 38 ++++++++- 3 files changed, 169 insertions(+), 26 deletions(-) diff --git a/src/runtime/rt1_amd64_darwin.c b/src/runtime/rt1_amd64_darwin.c index 4603b792cf9..b39c298ee75 100644 --- a/src/runtime/rt1_amd64_darwin.c +++ b/src/runtime/rt1_amd64_darwin.c @@ -8,7 +8,7 @@ typedef uint64 __uint64_t; -// From /usr/include/mach/i386/_structs.h +/* From /usr/include/mach/i386/_structs.h */ #define _STRUCT_X86_THREAD_STATE64 struct __darwin_x86_thread_state64 _STRUCT_X86_THREAD_STATE64 { @@ -64,7 +64,7 @@ print_thread_state(_STRUCT_X86_THREAD_STATE64* ss) } -/* Code generated via: g++ -m64 signals.cc && a.out */ +/* Code generated via: g++ -m64 gen_signals_support.cc && a.out */ static void *adr_at(void *ptr, int32 offs) { return (void *)((uint8 *)ptr + offs); @@ -119,16 +119,18 @@ typedef struct siginfo { /* 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 */ + 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) { @@ -152,6 +154,7 @@ sighandler(int32 sig, siginfo *info, void *context) sys·exit(2); } + sigaction a; extern void sigtramp(void); diff --git a/src/runtime/rt1_amd64_linux.c b/src/runtime/rt1_amd64_linux.c index 6c187a44eff..e7dfbc79b45 100644 --- a/src/runtime/rt1_amd64_linux.c +++ b/src/runtime/rt1_amd64_linux.c @@ -5,6 +5,101 @@ #include "runtime.h" #include "signals.h" +/* From /usr/include/asm-x86_64/sigcontext.h */ +struct _fpstate { + uint16 cwd; + uint16 swd; + uint16 twd; /* Note this is not the same as the 32bit/x87/FSAVE twd */ + uint16 fop; + uint64 rip; + uint32 rdp; + uint32 mxcsr; + uint32 mxcsr_mask; + uint32 st_space[32]; /* 8*16 bytes for each FP-reg */ + uint32 xmm_space[64]; /* 16*16 bytes for each XMM-reg */ + uint32 reserved2[24]; +}; + +struct sigcontext { + uint64 r8; + uint64 r9; + uint64 r10; + uint64 r11; + uint64 r12; + uint64 r13; + uint64 r14; + uint64 r15; + uint64 rdi; + uint64 rsi; + uint64 rbp; + uint64 rbx; + uint64 rdx; + uint64 rax; + uint64 rcx; + uint64 rsp; + uint64 rip; + uint64 eflags; /* RFLAGS */ + uint16 cs; + uint16 gs; + uint16 fs; + uint16 __pad0; + uint64 err; + uint64 trapno; + uint64 oldmask; + uint64 cr2; + struct _fpstate *fpstate; /* zero when no FPU context */ + uint64 reserved1[8]; +}; + + +/* From /usr/include/asm-x86_64/signal.h */ +typedef struct sigaltstack { + void /*__user*/ *ss_sp; + int32 ss_flags; + uint64 ss_size; +} stack_t; + +typedef uint64 sigset_t; + + +/* From /usr/include/asm-x86_64/ucontext.h */ +struct ucontext { + uint64 uc_flags; + struct ucontext *uc_link; + stack_t uc_stack; + struct sigcontext uc_mcontext; + sigset_t uc_sigmask; /* mask last for extensibility */ +}; + + +void +print_sigcontext(struct sigcontext *sc) +{ + prints("\nrax 0x"); sys·printpointer((void*)sc->rax); + prints("\nrbx 0x"); sys·printpointer((void*)sc->rbx); + prints("\nrcx 0x"); sys·printpointer((void*)sc->rcx); + prints("\nrdx 0x"); sys·printpointer((void*)sc->rdx); + prints("\nrdi 0x"); sys·printpointer((void*)sc->rdi); + prints("\nrsi 0x"); sys·printpointer((void*)sc->rsi); + prints("\nrbp 0x"); sys·printpointer((void*)sc->rbp); + prints("\nrsp 0x"); sys·printpointer((void*)sc->rsp); + prints("\nr8 0x"); sys·printpointer((void*)sc->r8 ); + prints("\nr9 0x"); sys·printpointer((void*)sc->r9 ); + prints("\nr10 0x"); sys·printpointer((void*)sc->r10); + prints("\nr11 0x"); sys·printpointer((void*)sc->r11); + prints("\nr12 0x"); sys·printpointer((void*)sc->r12); + prints("\nr13 0x"); sys·printpointer((void*)sc->r13); + prints("\nr14 0x"); sys·printpointer((void*)sc->r14); + prints("\nr15 0x"); sys·printpointer((void*)sc->r15); + prints("\nrip 0x"); sys·printpointer((void*)sc->rip); + prints("\nrflags 0x"); sys·printpointer((void*)sc->eflags); + prints("\ncs 0x"); sys·printpointer((void*)sc->cs); + prints("\nfs 0x"); sys·printpointer((void*)sc->fs); + prints("\ngs 0x"); sys·printpointer((void*)sc->gs); + prints("\n"); +} + + /* * This assembler routine takes the args from registers, puts them on the stack, * and calls sighandler(). @@ -15,6 +110,7 @@ extern void sigtramp(); * Rudimentary reverse-engineered definition of signal interface. * You'd think it would be documented. */ +/* From /usr/include/bits/siginfo.h */ typedef struct siginfo { int32 si_signo; /* signal number */ int32 si_errno; /* errno association */ @@ -24,18 +120,23 @@ typedef struct siginfo { /* more stuff here */ } siginfo; -typedef struct sigaction { + +/* From /usr/include/bits/sigaction.h */ +/* (gri) Is this correct? See e.g. /usr/include/asm-x86_64/signal.h */ +typedef struct sigaction { union { - void (*sa_handler)(int32); - void (*sa_sigaction)(int32, siginfo *, void *); - } u; /* signal handler */ - uint8 sa_mask[128]; /* signal mask to apply. 128? are they MORONS? */ - int32 sa_flags; /* see signal options below */ + void (*sa_handler)(int32); + void (*sa_sigaction)(int32, siginfo *, void *); + } u; /* signal handler */ + uint8 sa_mask[128]; /* signal mask to apply. 128? are they MORONS? */ + int32 sa_flags; /* see signal options below */ void (*sa_restorer) (void); /* unused here; needed to return from trap? */ } sigaction; + void -sighandler(int32 sig, siginfo* info, void** context) { +sighandler(int32 sig, siginfo* info, void** context) +{ int32 i; if(sig < 0 || sig >= NSIG){ @@ -44,18 +145,21 @@ sighandler(int32 sig, siginfo* info, void** context) { }else{ prints(sigtab[sig].name); } - prints("\nFaulting address: 0x"); - sys·printpointer(info->si_addr); - prints("\nPC: 0x"); - sys·printpointer(context[21]); - prints("\nSP: 0x"); - sys·printpointer(context[20]); - prints("\n"); - traceback(context[21], context[20]); /* empirically discovered locations */ + + struct sigcontext *sc = &(((struct ucontext *)context)->uc_mcontext); + + prints("\nFaulting address: 0x"); sys·printpointer(info->si_addr); + prints("\npc: 0x"); sys·printpointer((void *)sc->rip); + prints("\n\n"); + + traceback((void *)sc->rip, (void *)sc->rsp); + print_sigcontext(sc); + sys·breakpoint(); sys·exit(2); } + sigaction a; void @@ -63,11 +167,11 @@ initsig(void) { int32 i; a.u.sa_sigaction = (void*)sigtramp; - a.sa_flags |= 0x04; /* SA_SIGINFO */ + a.sa_flags = 0x04; /* SA_SIGINFO */ for(i=0; i