diff options
| author | Robert Griesemer <gri@golang.org> | 2008-06-25 17:07:22 -0700 |
|---|---|---|
| committer | Robert Griesemer <gri@golang.org> | 2008-06-25 17:07:22 -0700 |
| commit | 3311e1b6731219c0e4f2681e3cefa3ae9dfa1547 (patch) | |
| tree | bd8f6fbb5374b323f70559ab5ded010db92e93b1 /src/runtime/rt1_amd64_linux.c | |
| parent | c137d6b8e4fa0f117bf81c8ca5d3ab338f1f2cbe (diff) | |
| download | go-3311e1b6731219c0e4f2681e3cefa3ae9dfa1547.tar.xz | |
- dump registers in case of signal (linux)
SVN=124702
Diffstat (limited to 'src/runtime/rt1_amd64_linux.c')
| -rw-r--r-- | src/runtime/rt1_amd64_linux.c | 138 |
1 files changed, 121 insertions, 17 deletions
diff --git a/src/runtime/rt1_amd64_linux.c b/src/runtime/rt1_amd64_linux.c index 6c187a44ef..e7dfbc79b4 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<sizeof(a.sa_mask); i++) a.sa_mask[i] = 0xFF; - for(i = 0; i <NSIG; i++) + for(i = 0; i<NSIG; i++) if(sigtab[i].catch){ sys·rt_sigaction(i, &a, (void*)0, 8); } |
