From nobody Thu May 2 08:37:31 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1523475900484168.51538348994836; Wed, 11 Apr 2018 12:45:00 -0700 (PDT) Received: from localhost ([::1]:51118 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1f6Lfq-0006UM-Bb for importer@patchew.org; Wed, 11 Apr 2018 15:44:54 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:51037) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1f6LLq-0004Ub-HU for qemu-devel@nongnu.org; Wed, 11 Apr 2018 15:24:17 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1f6LLn-0000Nd-JI for qemu-devel@nongnu.org; Wed, 11 Apr 2018 15:24:14 -0400 Received: from mout.kundenserver.de ([212.227.126.187]:39283) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1f6LLn-0000N9-4l for qemu-devel@nongnu.org; Wed, 11 Apr 2018 15:24:11 -0400 Received: from localhost.localdomain ([78.238.229.36]) by mrelayeu.kundenserver.de (mreue002 [212.227.15.167]) with ESMTPSA (Nemesis) id 0MBezu-1fDStU2UmU-00AXuV; Wed, 11 Apr 2018 21:23:59 +0200 From: Laurent Vivier To: qemu-devel@nongnu.org Date: Wed, 11 Apr 2018 21:23:47 +0200 Message-Id: <20180411192347.30228-1-laurent@vivier.eu> X-Mailer: git-send-email 2.14.3 X-Provags-ID: V03:K1:pWXipvI5tWr8Q1Fxzl4wCexxJ5ilUCdOR6EKHc3joaVj3hgeYTD iZ/tBVomVpvcK2FDgZfoVejE1y895iWju9re2jVfKghEHfBJLeDX5v8g0RbqbJpeXScNzVw tku/0C2nULH46e2Fc2BPAOyNawRYOLVfxhV8k7OPKXaRCTSW9YZoPSfp/VRqVPwKYSAsg3j Ws28aK5/usGXS74O4rhAA== X-UI-Out-Filterresults: notjunk:1;V01:K0:T/Uz3n0qlLE=:xA8zjBExdp8p2/mnf+n6ub 4dHuD+hEfWGQaPfbMJrnxwfVuX62ZsbjFQsLz7Pvqr9wsm77y1ensuio7WtlpDplv/4dDdCy/ Mg4bNVD0cyETHeRKkzKcoHhyi4xXR30trUQhaE+XWFvQeP4aCbObRwwVg99SM4F5PsxD695b6 F2TgQRm4vR1oVEF6pGVF2OjoARFAUQ0vX5tfh13PRl3nJPmCkyBqXO9AZs8+fjsaL+LCv3BVh xMHcxl4U9bwFCvGQhQr9hkHAwDcLh+2h3lJwG57UJDtICqjSQ/ggu12XAXnBSutkDt76+XZ29 vNla+b4W+Zfcm0NPlWj0lbbwb74gh55rSaS1iiAQhETp7jUmUw1VsGBpBixy4RpE0AdOjAd/N sS8W3Rka1SXCyyjyzlK43lTpBvumMH/QTKxxiYDflfoXwvpgtEkzHx+SWdRVz6iqkDWMDZrBj ZUgEBaoOsXR8H61yzBuvxUE+3CKyLw0rd0AZqeVS4BO2zNL9eQV8JLguPvAwrrFi25LYDxqC6 s8f2rCMotnOfzt6+ehfVtnJsbA8HMlC0uROyr1B6VLwqqrBy3so4VWM3uGM9agr0FWL3WtJ/W efQnfO63bF+PE+qC31iT+S3gA5xBhjTiKjI2QryFyLaWUrkKYKyWy/6r/7q+rHBrWTfUdsPmo kY17o2ZBscG202nkuCr/Nl24kNze5B7ZLwceTfW15aGLnzFEiPpRynJlg9zByuX/NxP8ZEVyn P+RhXq7UxWrgLH5TRXLJ3KZ138kZVY9bpCkH5A== X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 212.227.126.187 Subject: [Qemu-devel] [PATCH for 2.13] linux-user: introduce target_sigsp() and target_save_altstack() X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Riku Voipio , Laurent Vivier Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Signed-off-by: Laurent Vivier Reviewed-by: Richard Henderson --- Based-on: <20180411185651.21351-1-laurent@vivier.eu> "[PATCH for 2.13 v2 00/19] linux-user: move arch specific parts from main.c= to arch directories" linux-user/aarch64/signal.c | 13 ++----------- linux-user/alpha/signal.c | 17 ++++++----------- linux-user/arm/signal.c | 17 ++++------------- linux-user/hppa/signal.c | 14 ++++---------- linux-user/i386/signal.c | 12 +++--------- linux-user/m68k/signal.c | 15 +++------------ linux-user/microblaze/signal.c | 4 +--- linux-user/mips/signal.c | 15 ++------------- linux-user/nios2/signal.c | 21 ++------------------- linux-user/openrisc/signal.c | 14 +++----------- linux-user/ppc/signal.c | 15 ++------------- linux-user/riscv/signal.c | 28 +++++++++------------------- linux-user/s390x/signal.c | 12 +++--------- linux-user/sh4/signal.c | 11 ++--------- linux-user/signal-common.h | 15 ++++----------- linux-user/signal.c | 32 ++++++++++++++++++++++++++++++++ linux-user/sparc/signal.c | 28 +++++++++++++++++++--------- linux-user/tilegx/signal.c | 13 +++---------- linux-user/xtensa/signal.c | 15 ++++----------- 19 files changed, 108 insertions(+), 203 deletions(-) diff --git a/linux-user/aarch64/signal.c b/linux-user/aarch64/signal.c index 72d20975f3..dc6f1c6d2e 100644 --- a/linux-user/aarch64/signal.c +++ b/linux-user/aarch64/signal.c @@ -120,9 +120,7 @@ static void target_setup_general_frame(struct target_rt= _sigframe *sf, __put_user(0, &sf->uc.tuc_flags); __put_user(0, &sf->uc.tuc_link); =20 - __put_user(target_sigaltstack_used.ss_sp, &sf->uc.tuc_stack.ss_sp); - __put_user(sas_ss_flags(env->xregs[31]), &sf->uc.tuc_stack.ss_flags); - __put_user(target_sigaltstack_used.ss_size, &sf->uc.tuc_stack.ss_size); + target_save_altstack(&sf->uc.tuc_stack, env); =20 for (i =3D 0; i < 31; i++) { __put_user(env->xregs[i], &sf->uc.tuc_mcontext.regs[i]); @@ -372,14 +370,7 @@ static abi_ulong get_sigframe(struct target_sigaction = *ka, { abi_ulong sp; =20 - sp =3D env->xregs[31]; - - /* - * This is the X/Open sanctioned signal stack switching. - */ - if ((ka->sa_flags & TARGET_SA_ONSTACK) && !sas_ss_flags(sp)) { - sp =3D target_sigaltstack_used.ss_sp + target_sigaltstack_used.ss_= size; - } + sp =3D target_sigsp(get_sp_from_cpustate(env), ka); =20 sp =3D (sp - size) & ~15; =20 diff --git a/linux-user/alpha/signal.c b/linux-user/alpha/signal.c index a8c718f2c6..f24de02c6f 100644 --- a/linux-user/alpha/signal.c +++ b/linux-user/alpha/signal.c @@ -117,12 +117,10 @@ static inline abi_ulong get_sigframe(struct target_si= gaction *sa, CPUAlphaState *env, unsigned long framesize) { - abi_ulong sp =3D env->ir[IR_SP]; + abi_ulong sp; + + sp =3D target_sigsp(get_sp_from_cpustate(env), sa); =20 - /* This is the X/Open sanctioned signal stack switching. */ - if ((sa->sa_flags & TARGET_SA_ONSTACK) !=3D 0 && !sas_ss_flags(sp)) { - sp =3D target_sigaltstack_used.ss_sp + target_sigaltstack_used.ss_= size; - } return (sp - framesize) & -32; } =20 @@ -187,12 +185,9 @@ void setup_rt_frame(int sig, struct target_sigaction *= ka, __put_user(0, &frame->uc.tuc_flags); __put_user(0, &frame->uc.tuc_link); __put_user(set->sig[0], &frame->uc.tuc_osf_sigmask); - __put_user(target_sigaltstack_used.ss_sp, - &frame->uc.tuc_stack.ss_sp); - __put_user(sas_ss_flags(env->ir[IR_SP]), - &frame->uc.tuc_stack.ss_flags); - __put_user(target_sigaltstack_used.ss_size, - &frame->uc.tuc_stack.ss_size); + + target_save_altstack(&frame->uc.tuc_stack, env); + setup_sigcontext(&frame->uc.tuc_mcontext, env, frame_addr, set); for (i =3D 0; i < TARGET_NSIG_WORDS; ++i) { __put_user(set->sig[i], &frame->uc.tuc_sigmask.sig[i]); diff --git a/linux-user/arm/signal.c b/linux-user/arm/signal.c index 0c1ec53025..0759b5dd8f 100644 --- a/linux-user/arm/signal.c +++ b/linux-user/arm/signal.c @@ -186,14 +186,9 @@ setup_sigcontext(struct target_sigcontext *sc, /*struc= t _fpstate *fpstate,*/ static inline abi_ulong get_sigframe(struct target_sigaction *ka, CPUARMState *regs, int framesize) { - unsigned long sp =3D regs->regs[13]; + unsigned long sp; =20 - /* - * This is the X/Open sanctioned signal stack switching. - */ - if ((ka->sa_flags & TARGET_SA_ONSTACK) && !sas_ss_flags(sp)) { - sp =3D target_sigaltstack_used.ss_sp + target_sigaltstack_used.ss_= size; - } + sp =3D target_sigsp(get_sp_from_cpustate(regs), ka); /* * ATPCS B01 mandates 8-byte alignment */ @@ -285,9 +280,7 @@ static void setup_sigframe_v2(struct target_ucontext_v2= *uc, memset(uc, 0, offsetof(struct target_ucontext_v2, tuc_mcontext)); =20 memset(&stack, 0, sizeof(stack)); - __put_user(target_sigaltstack_used.ss_sp, &stack.ss_sp); - __put_user(target_sigaltstack_used.ss_size, &stack.ss_size); - __put_user(sas_ss_flags(get_sp_from_cpustate(env)), &stack.ss_flags); + target_save_altstack(&stack, env); memcpy(&uc->tuc_stack, &stack, sizeof(stack)); =20 setup_sigcontext(&uc->tuc_mcontext, env, set->sig[0]); @@ -394,9 +387,7 @@ static void setup_rt_frame_v1(int usig, struct target_s= igaction *ka, memset(&frame->uc, 0, offsetof(struct target_ucontext_v1, tuc_mcontext= )); =20 memset(&stack, 0, sizeof(stack)); - __put_user(target_sigaltstack_used.ss_sp, &stack.ss_sp); - __put_user(target_sigaltstack_used.ss_size, &stack.ss_size); - __put_user(sas_ss_flags(get_sp_from_cpustate(env)), &stack.ss_flags); + target_save_altstack(&stack, env); memcpy(&frame->uc.tuc_stack, &stack, sizeof(stack)); =20 setup_sigcontext(&frame->uc.tuc_mcontext, env, set->sig[0]); diff --git a/linux-user/hppa/signal.c b/linux-user/hppa/signal.c index 585af3a37f..6e7a295aee 100644 --- a/linux-user/hppa/signal.c +++ b/linux-user/hppa/signal.c @@ -113,11 +113,9 @@ void setup_rt_frame(int sig, struct target_sigaction *= ka, struct target_rt_sigframe *frame; int i; =20 - sp =3D env->gr[30]; - if (ka->sa_flags & TARGET_SA_ONSTACK) { - if (sas_ss_flags(sp) =3D=3D 0) { - sp =3D (target_sigaltstack_used.ss_sp + 0x7f) & ~0x3f; - } + sp =3D get_sp_from_cpustate(env); + if ((ka->sa_flags & TARGET_SA_ONSTACK) && !sas_ss_flags(sp)) { + sp =3D (target_sigaltstack_used.ss_sp + 0x7f) & ~0x3f; } frame_addr =3D QEMU_ALIGN_UP(sp, 64); sp =3D frame_addr + PARISC_RT_SIGFRAME_SIZE32; @@ -132,11 +130,7 @@ void setup_rt_frame(int sig, struct target_sigaction *= ka, frame->uc.tuc_flags =3D 0; frame->uc.tuc_link =3D 0; =20 - __put_user(target_sigaltstack_used.ss_sp, &frame->uc.tuc_stack.ss_sp); - __put_user(sas_ss_flags(get_sp_from_cpustate(env)), - &frame->uc.tuc_stack.ss_flags); - __put_user(target_sigaltstack_used.ss_size, - &frame->uc.tuc_stack.ss_size); + target_save_altstack(&frame->uc.tuc_stack, env); =20 for (i =3D 0; i < TARGET_NSIG_WORDS; i++) { __put_user(set->sig[i], &frame->uc.tuc_sigmask.sig[i]); diff --git a/linux-user/i386/signal.c b/linux-user/i386/signal.c index 4a190e6435..e9a23a2dec 100644 --- a/linux-user/i386/signal.c +++ b/linux-user/i386/signal.c @@ -283,16 +283,14 @@ get_sigframe(struct target_sigaction *ka, CPUX86State= *env, size_t frame_size) unsigned long esp; =20 /* Default to using normal stack */ - esp =3D env->regs[R_ESP]; + esp =3D get_sp_from_cpustate(env); #ifdef TARGET_X86_64 esp -=3D 128; /* this is the redzone */ #endif =20 /* This is the X/Open sanctioned signal stack switching. */ if (ka->sa_flags & TARGET_SA_ONSTACK) { - if (sas_ss_flags(esp) =3D=3D 0) { - esp =3D target_sigaltstack_used.ss_sp + target_sigaltstack_use= d.ss_size; - } + esp =3D target_sigsp(esp, ka); } else { #ifndef TARGET_X86_64 /* This is the legacy signal stack switching. */ @@ -404,11 +402,7 @@ void setup_rt_frame(int sig, struct target_sigaction *= ka, /* Create the ucontext. */ __put_user(0, &frame->uc.tuc_flags); __put_user(0, &frame->uc.tuc_link); - __put_user(target_sigaltstack_used.ss_sp, &frame->uc.tuc_stack.ss_sp); - __put_user(sas_ss_flags(get_sp_from_cpustate(env)), - &frame->uc.tuc_stack.ss_flags); - __put_user(target_sigaltstack_used.ss_size, - &frame->uc.tuc_stack.ss_size); + target_save_altstack(&frame->uc.tuc_stack, env); setup_sigcontext(&frame->uc.tuc_mcontext, &frame->fpstate, env, set->sig[0], frame_addr + offsetof(struct rt_sigframe, fpstate= )); =20 diff --git a/linux-user/m68k/signal.c b/linux-user/m68k/signal.c index fc72468a81..5dd8bb5f99 100644 --- a/linux-user/m68k/signal.c +++ b/linux-user/m68k/signal.c @@ -117,14 +117,10 @@ static inline abi_ulong get_sigframe(struct target_sigaction *ka, CPUM68KState *regs, size_t frame_size) { - unsigned long sp; + abi_ulong sp; =20 - sp =3D regs->aregs[7]; + sp =3D target_sigsp(get_sp_from_cpustate(regs), ka); =20 - /* This is the X/Open sanctioned signal stack switching. */ - if ((ka->sa_flags & TARGET_SA_ONSTACK) && (sas_ss_flags (sp) =3D=3D 0)= ) { - sp =3D target_sigaltstack_used.ss_sp + target_sigaltstack_used.ss_= size; - } =20 return ((sp - frame_size) & -8UL); } @@ -318,12 +314,7 @@ void setup_rt_frame(int sig, struct target_sigaction *= ka, =20 __put_user(0, &frame->uc.tuc_flags); __put_user(0, &frame->uc.tuc_link); - __put_user(target_sigaltstack_used.ss_sp, - &frame->uc.tuc_stack.ss_sp); - __put_user(sas_ss_flags(env->aregs[7]), - &frame->uc.tuc_stack.ss_flags); - __put_user(target_sigaltstack_used.ss_size, - &frame->uc.tuc_stack.ss_size); + target_save_altstack(&frame->uc.tuc_stack, env); err |=3D target_rt_setup_ucontext(&frame->uc, env); =20 if (err) diff --git a/linux-user/microblaze/signal.c b/linux-user/microblaze/signal.c index 5572baa7dc..fada0f1495 100644 --- a/linux-user/microblaze/signal.c +++ b/linux-user/microblaze/signal.c @@ -133,9 +133,7 @@ static abi_ulong get_sigframe(struct target_sigaction *= ka, { abi_ulong sp =3D env->regs[1]; =20 - if ((ka->sa_flags & TARGET_SA_ONSTACK) !=3D 0 && !on_sig_stack(sp)) { - sp =3D target_sigaltstack_used.ss_sp + target_sigaltstack_used.ss_= size; - } + sp =3D target_sigsp(sp, ka); =20 return ((sp - frame_size) & -8UL); } diff --git a/linux-user/mips/signal.c b/linux-user/mips/signal.c index adeb5a4241..ed9849c7f6 100644 --- a/linux-user/mips/signal.c +++ b/linux-user/mips/signal.c @@ -179,20 +179,12 @@ get_sigframe(struct target_sigaction *ka, CPUMIPSStat= e *regs, size_t frame_size) { unsigned long sp; =20 - /* Default to using normal stack */ - sp =3D regs->active_tc.gpr[29]; - /* * FPU emulator may have its own trampoline active just * above the user stack, 16-bytes before the next lowest * 16 byte boundary. Try to avoid trashing it. */ - sp -=3D 32; - - /* This is the X/Open sanctioned signal stack switching. */ - if ((ka->sa_flags & TARGET_SA_ONSTACK) && (sas_ss_flags (sp) =3D=3D 0)= ) { - sp =3D target_sigaltstack_used.ss_sp + target_sigaltstack_used.ss_= size; - } + sp =3D target_sigsp(get_sp_from_cpustate(regs) - 32, ka); =20 return (sp - frame_size) & ~7; } @@ -323,10 +315,7 @@ void setup_rt_frame(int sig, struct target_sigaction *= ka, =20 __put_user(0, &frame->rs_uc.tuc_flags); __put_user(0, &frame->rs_uc.tuc_link); - __put_user(target_sigaltstack_used.ss_sp, &frame->rs_uc.tuc_stack.ss_s= p); - __put_user(target_sigaltstack_used.ss_size, &frame->rs_uc.tuc_stack.ss= _size); - __put_user(sas_ss_flags(get_sp_from_cpustate(env)), - &frame->rs_uc.tuc_stack.ss_flags); + target_save_altstack(&frame->rs_uc.tuc_stack, env); =20 setup_sigcontext(env, &frame->rs_uc.tuc_mcontext); =20 diff --git a/linux-user/nios2/signal.c b/linux-user/nios2/signal.c index 816eed90f1..9a0b36e5ad 100644 --- a/linux-user/nios2/signal.c +++ b/linux-user/nios2/signal.c @@ -42,18 +42,6 @@ struct target_rt_sigframe { struct target_ucontext uc; }; =20 -static unsigned long sigsp(unsigned long sp, struct target_sigaction *ka) -{ - if (unlikely((ka->sa_flags & SA_ONSTACK)) && !sas_ss_flags(sp)) { -#ifdef CONFIG_STACK_GROWSUP - return target_sigaltstack_used.ss_sp; -#else - return target_sigaltstack_used.ss_sp + target_sigaltstack_used.ss_= size; -#endif - } - return sp; -} - static int rt_setup_ucontext(struct target_ucontext *uc, CPUNios2State *en= v) { unsigned long *gregs =3D uc->tuc_mcontext.gregs; @@ -158,11 +146,8 @@ static void *get_sigframe(struct target_sigaction *ka,= CPUNios2State *env, { unsigned long usp; =20 - /* Default to using normal stack. */ - usp =3D env->regs[R_SP]; - /* This is the X/Open sanctioned signal stack switching. */ - usp =3D sigsp(usp, ka); + usp =3D target_sigsp(get_sp_from_cpustate(env), ka); =20 /* Verify, is it 32 or 64 bit aligned */ return (void *)((usp - frame_size) & -8UL); @@ -185,9 +170,7 @@ void setup_rt_frame(int sig, struct target_sigaction *k= a, /* Create the ucontext. */ __put_user(0, &frame->uc.tuc_flags); __put_user(0, &frame->uc.tuc_link); - __put_user(target_sigaltstack_used.ss_sp, &frame->uc.tuc_stack.ss_sp); - __put_user(sas_ss_flags(env->regs[R_SP]), &frame->uc.tuc_stack.ss_flag= s); - __put_user(target_sigaltstack_used.ss_size, &frame->uc.tuc_stack.ss_si= ze); + target_save_altstack(&frame->uc.tuc_stack, env); err |=3D rt_setup_ucontext(&frame->uc, env); for (i =3D 0; i < TARGET_NSIG_WORDS; i++) { __put_user((abi_ulong)set->sig[i], diff --git a/linux-user/openrisc/signal.c b/linux-user/openrisc/signal.c index 0276808b59..ecf2897ccd 100644 --- a/linux-user/openrisc/signal.c +++ b/linux-user/openrisc/signal.c @@ -124,14 +124,11 @@ static inline abi_ulong get_sigframe(struct target_si= gaction *ka, CPUOpenRISCState *regs, size_t frame_size) { - unsigned long sp =3D cpu_get_gpr(regs, 1); + unsigned long sp =3D get_sp_from_cpustate(regs); int onsigstack =3D on_sig_stack(sp); =20 /* redzone */ - /* This is the X/Open sanctioned signal stack switching. */ - if ((ka->sa_flags & TARGET_SA_ONSTACK) !=3D 0 && !onsigstack) { - sp =3D target_sigaltstack_used.ss_sp + target_sigaltstack_used.ss_= size; - } + sp =3D target_sigsp(sp, ka); =20 sp =3D align_sigframe(sp - frame_size); =20 @@ -175,12 +172,7 @@ void setup_rt_frame(int sig, struct target_sigaction *= ka, /*err |=3D __clear_user(&frame->uc, offsetof(ucontext_t, uc_mcontext))= ;*/ __put_user(0, &frame->uc.tuc_flags); __put_user(0, &frame->uc.tuc_link); - __put_user(target_sigaltstack_used.ss_sp, - &frame->uc.tuc_stack.ss_sp); - __put_user(sas_ss_flags(cpu_get_gpr(env, 1)), - &frame->uc.tuc_stack.ss_flags); - __put_user(target_sigaltstack_used.ss_size, - &frame->uc.tuc_stack.ss_size); + target_save_altstack(&frame->uc.tuc_stack, env); setup_sigcontext(&frame->sc, env, set->sig[0]); =20 /*err |=3D copy_to_user(frame->uc.tuc_sigmask, set, sizeof(*set));*/ diff --git a/linux-user/ppc/signal.c b/linux-user/ppc/signal.c index 15148d54a9..cacc9afb5a 100644 --- a/linux-user/ppc/signal.c +++ b/linux-user/ppc/signal.c @@ -217,13 +217,7 @@ static target_ulong get_sigframe(struct target_sigacti= on *ka, { target_ulong oldsp; =20 - oldsp =3D env->gpr[1]; - - if ((ka->sa_flags & TARGET_SA_ONSTACK) && - (sas_ss_flags(oldsp) =3D=3D 0)) { - oldsp =3D (target_sigaltstack_used.ss_sp - + target_sigaltstack_used.ss_size); - } + oldsp =3D target_sigsp(get_sp_from_cpustate(env), ka); =20 return (oldsp - frame_size) & ~0xFUL; } @@ -515,12 +509,7 @@ void setup_rt_frame(int sig, struct target_sigaction *= ka, =20 __put_user(0, &rt_sf->uc.tuc_flags); __put_user(0, &rt_sf->uc.tuc_link); - __put_user((target_ulong)target_sigaltstack_used.ss_sp, - &rt_sf->uc.tuc_stack.ss_sp); - __put_user(sas_ss_flags(env->gpr[1]), - &rt_sf->uc.tuc_stack.ss_flags); - __put_user(target_sigaltstack_used.ss_size, - &rt_sf->uc.tuc_stack.ss_size); + target_save_altstack(&rt_sf->uc.tuc_stack, env); #if !defined(TARGET_PPC64) __put_user(h2g (&rt_sf->uc.tuc_mcontext), &rt_sf->uc.tuc_regs); diff --git a/linux-user/riscv/signal.c b/linux-user/riscv/signal.c index 718f3a5679..ef599e319a 100644 --- a/linux-user/riscv/signal.c +++ b/linux-user/riscv/signal.c @@ -54,24 +54,20 @@ struct target_rt_sigframe { static abi_ulong get_sigframe(struct target_sigaction *ka, CPURISCVState *regs, size_t framesize) { - abi_ulong sp =3D regs->gpr[xSP]; - int onsigstack =3D on_sig_stack(sp); - - /* redzone */ - /* This is the X/Open sanctioned signal stack switching. */ - if ((ka->sa_flags & TARGET_SA_ONSTACK) !=3D 0 && !onsigstack) { - sp =3D target_sigaltstack_used.ss_sp + target_sigaltstack_used.ss_= size; - } - - sp -=3D framesize; - sp &=3D ~3UL; /* align sp on 4-byte boundary */ + abi_ulong sp =3D get_sp_from_cpustate(regs); =20 /* If we are on the alternate signal stack and would overflow it, don'= t. Return an always-bogus address instead so we will die with SIGSEGV.= */ - if (onsigstack && !likely(on_sig_stack(sp))) { + if (on_sig_stack(sp) && !likely(on_sig_stack(sp - framesize))) { return -1L; } =20 + /* This is the X/Open sanctioned signal stack switching. */ + sp =3D target_sigsp(sp, ka) - framesize; + + /* XXX: kernel aligns with 0xf ? */ + sp &=3D ~3UL; /* align sp on 4-byte boundary */ + return sp; } =20 @@ -95,16 +91,10 @@ static void setup_sigcontext(struct target_sigcontext *= sc, CPURISCVState *env) static void setup_ucontext(struct target_ucontext *uc, CPURISCVState *env, target_sigset_t *set) { - abi_ulong ss_sp =3D (target_ulong)target_sigaltstack_used.ss_sp; - abi_ulong ss_flags =3D sas_ss_flags(env->gpr[xSP]); - abi_ulong ss_size =3D target_sigaltstack_used.ss_size; - __put_user(0, &(uc->uc_flags)); __put_user(0, &(uc->uc_link)); =20 - __put_user(ss_sp, &(uc->uc_stack.ss_sp)); - __put_user(ss_flags, &(uc->uc_stack.ss_flags)); - __put_user(ss_size, &(uc->uc_stack.ss_size)); + target_save_altstack(&uc->uc_stack, env); =20 int i; for (i =3D 0; i < TARGET_NSIG_WORDS; i++) { diff --git a/linux-user/s390x/signal.c b/linux-user/s390x/signal.c index a204a85e4a..e35cbe6870 100644 --- a/linux-user/s390x/signal.c +++ b/linux-user/s390x/signal.c @@ -86,14 +86,11 @@ get_sigframe(struct target_sigaction *ka, CPUS390XState= *env, size_t frame_size) abi_ulong sp; =20 /* Default to using normal stack */ - sp =3D env->regs[15]; + sp =3D get_sp_from_cpustate(env); =20 /* This is the X/Open sanctioned signal stack switching. */ if (ka->sa_flags & TARGET_SA_ONSTACK) { - if (!sas_ss_flags(sp)) { - sp =3D target_sigaltstack_used.ss_sp + - target_sigaltstack_used.ss_size; - } + sp =3D target_sigsp(sp, ka); } =20 /* This is the legacy signal stack switching. */ @@ -205,10 +202,7 @@ void setup_rt_frame(int sig, struct target_sigaction *= ka, /* Create the ucontext. */ __put_user(0, &frame->uc.tuc_flags); __put_user((abi_ulong)0, (abi_ulong *)&frame->uc.tuc_link); - __put_user(target_sigaltstack_used.ss_sp, &frame->uc.tuc_stack.ss_sp); - __put_user(sas_ss_flags(get_sp_from_cpustate(env)), - &frame->uc.tuc_stack.ss_flags); - __put_user(target_sigaltstack_used.ss_size, &frame->uc.tuc_stack.ss_si= ze); + target_save_altstack(&frame->uc.tuc_stack, env); save_sigregs(env, &frame->uc.tuc_mcontext); for (i =3D 0; i < TARGET_NSIG_WORDS; i++) { __put_user((abi_ulong)set->sig[i], diff --git a/linux-user/sh4/signal.c b/linux-user/sh4/signal.c index 5ce182aff7..2a5378e16e 100644 --- a/linux-user/sh4/signal.c +++ b/linux-user/sh4/signal.c @@ -78,9 +78,7 @@ struct target_rt_sigframe static abi_ulong get_sigframe(struct target_sigaction *ka, unsigned long sp, size_t frame_size) { - if ((ka->sa_flags & TARGET_SA_ONSTACK) && (sas_ss_flags(sp) =3D=3D 0))= { - sp =3D target_sigaltstack_used.ss_sp + target_sigaltstack_used.ss_= size; - } + sp =3D target_sigsp(sp, ka); =20 return (sp - frame_size) & -8ul; } @@ -238,12 +236,7 @@ void setup_rt_frame(int sig, struct target_sigaction *= ka, /* Create the ucontext. */ __put_user(0, &frame->uc.tuc_flags); __put_user(0, (unsigned long *)&frame->uc.tuc_link); - __put_user((unsigned long)target_sigaltstack_used.ss_sp, - &frame->uc.tuc_stack.ss_sp); - __put_user(sas_ss_flags(regs->gregs[15]), - &frame->uc.tuc_stack.ss_flags); - __put_user(target_sigaltstack_used.ss_size, - &frame->uc.tuc_stack.ss_size); + target_save_altstack(&frame->uc.tuc_stack, regs); setup_sigcontext(&frame->uc.tuc_mcontext, regs, set->sig[0]); for(i =3D 0; i < TARGET_NSIG_WORDS; i++) { diff --git a/linux-user/signal-common.h b/linux-user/signal-common.h index fbb8d4365c..51030a9306 100644 --- a/linux-user/signal-common.h +++ b/linux-user/signal-common.h @@ -21,17 +21,10 @@ #define SIGNAL_COMMON_H extern struct target_sigaltstack target_sigaltstack_used; =20 -static inline int on_sig_stack(unsigned long sp) -{ - return (sp - target_sigaltstack_used.ss_sp - < target_sigaltstack_used.ss_size); -} - -static inline int sas_ss_flags(unsigned long sp) -{ - return (target_sigaltstack_used.ss_size =3D=3D 0 ? SS_DISABLE - : on_sig_stack(sp) ? SS_ONSTACK : 0); -} +int on_sig_stack(unsigned long sp); +int sas_ss_flags(unsigned long sp); +abi_ulong target_sigsp(abi_ulong sp, struct target_sigaction *ka); +void target_save_altstack(target_stack_t *uss, CPUArchState *env); =20 static inline void target_sigemptyset(target_sigset_t *set) { diff --git a/linux-user/signal.c b/linux-user/signal.c index a3022c2f04..01de433e3a 100644 --- a/linux-user/signal.c +++ b/linux-user/signal.c @@ -249,6 +249,38 @@ void set_sigmask(const sigset_t *set) } #endif =20 +/* sigaltstack management */ + +int on_sig_stack(unsigned long sp) +{ + return (sp - target_sigaltstack_used.ss_sp + < target_sigaltstack_used.ss_size); +} + +int sas_ss_flags(unsigned long sp) +{ + return (target_sigaltstack_used.ss_size =3D=3D 0 ? SS_DISABLE + : on_sig_stack(sp) ? SS_ONSTACK : 0); +} + +abi_ulong target_sigsp(abi_ulong sp, struct target_sigaction *ka) +{ + /* + * This is the X/Open sanctioned signal stack switching. + */ + if ((ka->sa_flags & TARGET_SA_ONSTACK) && !sas_ss_flags(sp)) { + return target_sigaltstack_used.ss_sp + target_sigaltstack_used.ss_= size; + } + return sp; +} + +void target_save_altstack(target_stack_t *uss, CPUArchState *env) +{ + __put_user(target_sigaltstack_used.ss_sp, &uss->ss_sp); + __put_user(sas_ss_flags(get_sp_from_cpustate(env)), &uss->ss_flags); + __put_user(target_sigaltstack_used.ss_size, &uss->ss_size); +} + /* siginfo conversion */ =20 static inline void host_to_target_siginfo_noswap(target_siginfo_t *tinfo, diff --git a/linux-user/sparc/signal.c b/linux-user/sparc/signal.c index c823e61cee..45e922f328 100644 --- a/linux-user/sparc/signal.c +++ b/linux-user/sparc/signal.c @@ -123,18 +123,28 @@ static inline abi_ulong get_sigframe(struct target_si= gaction *sa, CPUSPARCState *env, unsigned long framesize) { - abi_ulong sp; + abi_ulong sp =3D get_sp_from_cpustate(env); =20 - sp =3D env->regwptr[UREG_FP]; + /* + * If we are on the alternate signal stack and would overflow it, don'= t. + * Return an always-bogus address instead so we will die with SIGSEGV. + */ + if (on_sig_stack(sp) && !likely(on_sig_stack(sp - framesize))) { + return -1; + } =20 /* This is the X/Open sanctioned signal stack switching. */ - if (sa->sa_flags & TARGET_SA_ONSTACK) { - if (!on_sig_stack(sp) - && !((target_sigaltstack_used.ss_sp + target_sigaltstack_u= sed.ss_size) & 7)) { - sp =3D target_sigaltstack_used.ss_sp + target_sigaltstack_used= .ss_size; - } - } - return sp - framesize; + sp =3D target_sigsp(sp, sa) - framesize; + + /* Always align the stack frame. This handles two cases. First, + * sigaltstack need not be mindful of platform specific stack + * alignment. Second, if we took this signal because the stack + * is not aligned properly, we'd like to take the signal cleanly + * and report that. + */ + sp &=3D ~15UL; + + return sp; } =20 static int diff --git a/linux-user/tilegx/signal.c b/linux-user/tilegx/signal.c index 8f54f54f95..d0ed3de569 100644 --- a/linux-user/tilegx/signal.c +++ b/linux-user/tilegx/signal.c @@ -86,17 +86,13 @@ static void restore_sigcontext(CPUTLGState *env, struct= target_sigcontext *sc) static abi_ulong get_sigframe(struct target_sigaction *ka, CPUArchState *e= nv, size_t frame_size) { - unsigned long sp =3D env->regs[TILEGX_R_SP]; + unsigned long sp =3D get_sp_from_cpustate(env); =20 if (on_sig_stack(sp) && !likely(on_sig_stack(sp - frame_size))) { return -1UL; } =20 - if ((ka->sa_flags & SA_ONSTACK) && !sas_ss_flags(sp)) { - sp =3D target_sigaltstack_used.ss_sp + target_sigaltstack_used.ss_= size; - } - - sp -=3D frame_size; + sp =3D target_sigsp(sp, ka) - frame_size; sp &=3D -16UL; return sp; } @@ -127,10 +123,7 @@ void setup_rt_frame(int sig, struct target_sigaction *= ka, /* Create the ucontext. */ __put_user(0, &frame->uc.tuc_flags); __put_user(0, &frame->uc.tuc_link); - __put_user(target_sigaltstack_used.ss_sp, &frame->uc.tuc_stack.ss_sp); - __put_user(sas_ss_flags(env->regs[TILEGX_R_SP]), - &frame->uc.tuc_stack.ss_flags); - __put_user(target_sigaltstack_used.ss_size, &frame->uc.tuc_stack.ss_si= ze); + target_save_altstack(&frame->uc.tuc_stack, env); setup_sigcontext(&frame->uc.tuc_mcontext, env, info->si_signo); =20 if (ka->sa_flags & TARGET_SA_RESTORER) { diff --git a/linux-user/xtensa/signal.c b/linux-user/xtensa/signal.c index 1e98910c1b..3e483efc61 100644 --- a/linux-user/xtensa/signal.c +++ b/linux-user/xtensa/signal.c @@ -55,12 +55,10 @@ static abi_ulong get_sigframe(struct target_sigaction *= sa, CPUXtensaState *env, unsigned long framesize) { - abi_ulong sp =3D env->regs[1]; + abi_ulong sp; + + sp =3D target_sigsp(get_sp_from_cpustate(env), sa); =20 - /* This is the X/Open sanctioned signal stack switching. */ - if ((sa->sa_flags & TARGET_SA_ONSTACK) !=3D 0 && !sas_ss_flags(sp)) { - sp =3D target_sigaltstack_used.ss_sp + target_sigaltstack_used.ss_= size; - } return (sp - framesize) & -16; } =20 @@ -152,12 +150,7 @@ void setup_rt_frame(int sig, struct target_sigaction *= ka, =20 __put_user(0, &frame->uc.tuc_flags); __put_user(0, &frame->uc.tuc_link); - __put_user(target_sigaltstack_used.ss_sp, - &frame->uc.tuc_stack.ss_sp); - __put_user(sas_ss_flags(env->regs[1]), - &frame->uc.tuc_stack.ss_flags); - __put_user(target_sigaltstack_used.ss_size, - &frame->uc.tuc_stack.ss_size); + target_save_altstack(&frame->uc.tuc_stack, env); if (!setup_sigcontext(frame, env)) { unlock_user_struct(frame, frame_addr, 0); goto give_sigsegv; --=20 2.14.3