From ae5feb49c2fe43965e4ddae8fd1cbbed41dc3ae6 Mon Sep 17 00:00:00 2001 From: "Dmitry V. Levin" Date: Sun, 21 Aug 2016 22:02:09 +0000 Subject: [PATCH] sparc64: fix sigreturn decoding for sparc personality * linux/sparc/arch_sigreturn.c (arch_sigreturn): Parametrize member types of struct signal_frame. * linux/sparc64/arch_sigreturn.c (sparc64_arch_sigreturn, sparc32_arch_sigreturn): New functions. (arch_sigreturn): Use them. --- linux/sparc/arch_sigreturn.c | 26 ++++++++++++++++++++------ linux/sparc64/arch_sigreturn.c | 18 ++++++++++++++++++ 2 files changed, 38 insertions(+), 6 deletions(-) diff --git a/linux/sparc/arch_sigreturn.c b/linux/sparc/arch_sigreturn.c index 9e86efa9..0c0e5112 100644 --- a/linux/sparc/arch_sigreturn.c +++ b/linux/sparc/arch_sigreturn.c @@ -1,12 +1,22 @@ +#ifndef SIZEOF_STRUCT_SPARC_STACKF +# define SIZEOF_STRUCT_SPARC_STACKF sizeof(struct sparc_stackf) +#endif +#ifndef SIZEOF_STRUCT_PT_REGS +# define SIZEOF_STRUCT_PT_REGS sizeof(struct pt_regs) +#endif +#ifndef PERSONALITY_WORDSIZE +# define PERSONALITY_WORDSIZE PERSONALITY0_WORDSIZE +#endif + static void arch_sigreturn(struct tcb *tcp) { - long fp = sparc_regs.u_regs[U_REG_FP] + sizeof(struct sparc_stackf); + long fp = sparc_regs.u_regs[U_REG_FP] + + SIZEOF_STRUCT_SPARC_STACKF + SIZEOF_STRUCT_PT_REGS; struct { - struct pt_regs si_regs; - int si_mask; - void *fpu_save; - long insns[2] ATTRIBUTE_ALIGNED(8); + unsigned int mask; + char fpu_save[PERSONALITY_WORDSIZE]; + char insns[PERSONALITY_WORDSIZE * 2] ATTRIBUTE_ALIGNED(8); unsigned int extramask[NSIG / 8 / sizeof(int) - 1]; } frame; @@ -15,9 +25,13 @@ arch_sigreturn(struct tcb *tcp) } else { unsigned int mask[NSIG / 8 / sizeof(int)]; - mask[0] = frame.si_mask; + mask[0] = frame.mask; memcpy(mask + 1, frame.extramask, sizeof(frame.extramask)); tprintsigmask_addr("{mask=", mask); tprints("}"); } } + +#undef PERSONALITY_WORDSIZE +#undef SIZEOF_STRUCT_PT_REGS +#undef SIZEOF_STRUCT_SPARC_STACKF diff --git a/linux/sparc64/arch_sigreturn.c b/linux/sparc64/arch_sigreturn.c index aeec9817..feac9da6 100644 --- a/linux/sparc64/arch_sigreturn.c +++ b/linux/sparc64/arch_sigreturn.c @@ -1 +1,19 @@ +#define arch_sigreturn sparc64_arch_sigreturn #include "sparc/arch_sigreturn.c" +#undef arch_sigreturn + +#define SIZEOF_STRUCT_SPARC_STACKF sizeof(struct sparc_stackf32) +#define SIZEOF_STRUCT_PT_REGS sizeof(struct pt_regs32) +#define PERSONALITY_WORDSIZE PERSONALITY1_WORDSIZE +#define arch_sigreturn sparc32_arch_sigreturn +#include "sparc/arch_sigreturn.c" +#undef arch_sigreturn + +static void +arch_sigreturn(struct tcb *tcp) +{ + if (current_personality == 1) + sparc32_arch_sigreturn(tcp); + else + sparc64_arch_sigreturn(tcp); +} -- 2.40.0