From: Dmitry V. Levin Date: Wed, 4 Mar 2015 23:05:53 +0000 (+0000) Subject: aarch64: implement rt_sigreturn decoding X-Git-Tag: v4.10~12 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=5b9b7e1d347eb4556084cdccad75e8247c535ed5;p=strace aarch64: implement rt_sigreturn decoding * linux/64/syscallent.h (139): Use sys_sigreturn for rt_sigreturn decoding. * syscall.c [ARM] (arm_regs): Make static. [ARM] (arm_sp_ptr): New variable. [AARCH64] (aarch64_sp_ptr, arm_sp_ptr): New variables. * linux/aarch64/arch_regs.h: New file. * linux/arm/arch_regs.h (arm_regs): Remove. (arm_sp_ptr): New declaration. * signal.c (sys_sigreturn) [ARM]: Use arm_sp_ptr. [AARCH64]: Print signal mask. --- diff --git a/linux/64/syscallent.h b/linux/64/syscallent.h index 6c67c9c1..dda9be91 100644 --- a/linux/64/syscallent.h +++ b/linux/64/syscallent.h @@ -137,7 +137,7 @@ [136] = { 2, TS, sys_rt_sigpending, "rt_sigpending" }, [137] = { 4, TS, sys_rt_sigtimedwait, "rt_sigtimedwait" }, [138] = { 3, TS, sys_rt_sigqueueinfo, "rt_sigqueueinfo" }, -[139] = { 0, TS, sys_rt_sigreturn, "rt_sigreturn" }, +[139] = { 0, TS, sys_sigreturn, "rt_sigreturn" }, [140] = { 3, 0, sys_setpriority, "setpriority" }, [141] = { 2, 0, sys_getpriority, "getpriority" }, [142] = { 4, 0, sys_reboot, "reboot" }, diff --git a/linux/aarch64/arch_regs.h b/linux/aarch64/arch_regs.h new file mode 100644 index 00000000..290a00ee --- /dev/null +++ b/linux/aarch64/arch_regs.h @@ -0,0 +1,2 @@ +extern uint64_t *const aarch64_sp_ptr; +extern int *const arm_sp_ptr; diff --git a/linux/arm/arch_regs.h b/linux/arm/arch_regs.h index b7638aeb..bdbc8e95 100644 --- a/linux/arm/arch_regs.h +++ b/linux/arm/arch_regs.h @@ -1 +1 @@ -extern struct pt_regs arm_regs; +extern long *const arm_sp_ptr; diff --git a/signal.c b/signal.c index bc78379c..1d52f735 100644 --- a/signal.c +++ b/signal.c @@ -690,16 +690,19 @@ sys_signal(struct tcb *tcp) int sys_sigreturn(struct tcb *tcp) { -#if defined(ARM) +#if defined AARCH64 || defined ARM if (entering(tcp)) { - /* - * Kernel fills out uc.sc.oldmask too when it sets up signal stack, - * but for sigmask restore, sigreturn syscall uses uc.uc_sigmask instead. - */ +# define SIZEOF_STRUCT_SIGINFO 128 # define SIZEOF_STRUCT_SIGCONTEXT (21 * 4) # define OFFSETOF_STRUCT_UCONTEXT_UC_SIGMASK (5 * 4 + SIZEOF_STRUCT_SIGCONTEXT) - const long addr = arm_regs.ARM_sp + - OFFSETOF_STRUCT_UCONTEXT_UC_SIGMASK; + const long addr = +# ifdef AARCH64 + current_personality == 0 ? + (*aarch64_sp_ptr + SIZEOF_STRUCT_SIGINFO + + offsetof(struct ucontext, uc_sigmask)) : +# endif + (*arm_sp_ptr + + OFFSETOF_STRUCT_UCONTEXT_UC_SIGMASK); tprints(") (mask "); print_sigset_addr_len(tcp, addr, NSIG / 8); } diff --git a/syscall.c b/syscall.c index cfedc9f1..59f7d9a6 100644 --- a/syscall.c +++ b/syscall.c @@ -712,7 +712,8 @@ static long m68k_d0; #elif defined(BFIN) static long bfin_r0; #elif defined(ARM) -struct pt_regs arm_regs; /* not static */ +static struct pt_regs arm_regs; +long *const arm_sp_ptr = &arm_regs.ARM_sp; # define ARCH_REGS_FOR_GETREGS arm_regs #elif defined(AARCH64) struct arm_pt_regs { @@ -742,6 +743,8 @@ static union { } arm_regs_union; # define aarch64_regs arm_regs_union.aarch64_r # define arm_regs arm_regs_union.arm_r +uint64_t *const aarch64_sp_ptr = &aarch64_regs.sp; +int *const arm_sp_ptr = &arm_regs.ARM_sp; static struct iovec aarch64_io = { .iov_base = &arm_regs_union };