From: Dmitry V. Levin Date: Wed, 4 Mar 2015 12:19:55 +0000 (+0000) Subject: x86_64, x32: implement rt_sigreturn decoding X-Git-Tag: v4.10~16 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=ccb4fdac4388f1e07591f4087a723ea1bb142076;p=strace x86_64, x32: implement rt_sigreturn decoding * syscall.c [X86_64 || X32] (x86_64_rsp_ptr): New variable. * linux/x86_64/arch_regs.h (x86_64_rsp_ptr): New declaration. * linux/x86_64/syscallent.h (15): Use sys_sigreturn for rt_sigreturn decoding. * linux/x32/syscallent.h (513): Likewise. * signal.c (sys_sigreturn) [X86_64 || X32]: Print signal mask for non-i386 personalities. --- diff --git a/linux/x32/syscallent.h b/linux/x32/syscallent.h index e9918071..3996b425 100644 --- a/linux/x32/syscallent.h +++ b/linux/x32/syscallent.h @@ -327,7 +327,7 @@ * for native 64-bit operation. */ [512] = { 4, TS, sys_rt_sigaction, "rt_sigaction" }, -[513] = { 0, TS, sys_rt_sigreturn, "rt_sigreturn" }, +[513] = { 0, TS, sys_sigreturn, "rt_sigreturn" }, [514] = { 3, TD, sys_ioctl, "ioctl" }, [515] = { 3, TD, sys_readv, "readv" }, [516] = { 3, TD, sys_writev, "writev" }, diff --git a/linux/x86_64/arch_regs.h b/linux/x86_64/arch_regs.h index eeb4ebea..c2ccee67 100644 --- a/linux/x86_64/arch_regs.h +++ b/linux/x86_64/arch_regs.h @@ -1 +1,2 @@ extern uint32_t *const i386_esp_ptr; +extern uint64_t *const x86_64_rsp_ptr; diff --git a/linux/x86_64/syscallent.h b/linux/x86_64/syscallent.h index c1fedea2..f4844025 100644 --- a/linux/x86_64/syscallent.h +++ b/linux/x86_64/syscallent.h @@ -13,7 +13,7 @@ [ 12] = { 1, TM|SI, sys_brk, "brk" }, [ 13] = { 4, TS, sys_rt_sigaction, "rt_sigaction" }, [ 14] = { 4, TS, sys_rt_sigprocmask, "rt_sigprocmask" }, -[ 15] = { 0, TS, sys_rt_sigreturn, "rt_sigreturn" }, +[ 15] = { 0, TS, sys_sigreturn, "rt_sigreturn" }, [ 16] = { 3, TD, sys_ioctl, "ioctl" }, [ 17] = { 4, TD, sys_pread, "pread" }, [ 18] = { 4, TD, sys_pwrite, "pwrite" }, diff --git a/signal.c b/signal.c index d34fd725..f084772a 100644 --- a/signal.c +++ b/signal.c @@ -747,12 +747,17 @@ sys_sigreturn(struct tcb *tcp) tprintsigmask_addr(") (mask ", sc.oldmask); } #elif defined I386 || defined X86_64 || defined X32 + if (entering(tcp)) { # ifndef I386 - /* sys_sigreturn is i386 personality only */ - if (current_personality != 1) - return 0; + if (current_personality != 1) { + const unsigned long addr = + (unsigned long) *x86_64_rsp_ptr + + offsetof(struct ucontext, uc_sigmask); + tprints(") (mask "); + print_sigset_addr_len(tcp, addr, NSIG / 8); + return 0; + } # endif - if (entering(tcp)) { struct i386_sigcontext_struct { uint16_t gs, __gsh; uint16_t fs, __fsh; diff --git a/syscall.c b/syscall.c index 228536b4..cfedc9f1 100644 --- a/syscall.c +++ b/syscall.c @@ -695,6 +695,7 @@ static union { # define x86_64_regs x86_regs_union.x86_64_r # define i386_regs x86_regs_union.i386_r uint32_t *const i386_esp_ptr = &i386_regs.esp; +uint64_t *const x86_64_rsp_ptr = (uint64_t *) &x86_64_regs.rsp; static struct iovec x86_io = { .iov_base = &x86_regs_union };