From patchwork Tue Apr 24 19:26:30 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Laurent Vivier X-Patchwork-Id: 903803 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=2001:4830:134:3::11; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=vivier.eu Received: from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 40Vtnh4x4kz9ryr for ; Wed, 25 Apr 2018 05:34:48 +1000 (AEST) Received: from localhost ([::1]:60460 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fB3iA-0005hw-JE for incoming@patchwork.ozlabs.org; Tue, 24 Apr 2018 15:34:46 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:57798) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fB3bH-0000XL-EP for qemu-devel@nongnu.org; Tue, 24 Apr 2018 15:27:42 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1fB3bE-00052x-7o for qemu-devel@nongnu.org; Tue, 24 Apr 2018 15:27:39 -0400 Received: from mout.kundenserver.de ([212.227.126.134]:43183) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1fB3bD-00052b-Re; Tue, 24 Apr 2018 15:27:36 -0400 Received: from localhost.localdomain ([78.238.229.36]) by mrelayeu.kundenserver.de (mreue005 [212.227.15.167]) with ESMTPSA (Nemesis) id 0LqYLt-1eX40X2G9p-00e5Lp; Tue, 24 Apr 2018 21:27:21 +0200 From: Laurent Vivier To: qemu-devel@nongnu.org Date: Tue, 24 Apr 2018 21:26:30 +0200 Message-Id: <20180424192635.6027-16-laurent@vivier.eu> X-Mailer: git-send-email 2.14.3 In-Reply-To: <20180424192635.6027-1-laurent@vivier.eu> References: <20180424192635.6027-1-laurent@vivier.eu> MIME-Version: 1.0 X-Provags-ID: V03:K1:Rr2IHPaAMvaAfiNG4E0qnwoSuaf2snpI1CQOKpi4NYjSXSADPZl iJn18wWG7dCd5GQL39/vgkuq0ZKDva9x8JD+FKnZr3XQogSHH4O82R9B2a0UkmDR8DGuG+3 EeEgUrRJTufnFQ6TfnMrw6KMnC8Iv5Z7AP3ySivS/jIUbWG97l9CQHfytyp1v+zX02oIBcI NzKEL6B/jIJsoG6xUNabw== X-UI-Out-Filterresults: notjunk:1; V01:K0:FU63P59i6pc=:ZdEsosIryN9v6M5dACMzQq dYOaPGsLTiT0tzbPQrojJOVLlDYoS1M8QUt/aNvNyQJSF7fROR8EeAcnExzw6Uj2+W9LPz4yD 10KFBG8tpILDZqKelfML24LXTXL+q7Y0bRWaTNrPxCeUplXlMlr8GOHetAqzz2hjD6aCC2/Rw SgoV70o+EU0JW9+WplKnvy1BztLEQf7ailKsV/JoIFFZ46dvyqQrWOyg0mIb3qfahVopQiy89 hikQrsII4WhMU6ZFuOr+Xcz98+fv6WDKH46kD3RwyTEDdPhL2vaZIYfoiErWc41c6A0lhb7Bz tYrkOqn+ZIEx/7tnXTpCP4BL30zplCU9Daa6OkyvqpKUrCd3xt3yDWmFRms26iLbQzdoG8OKp joMXHdKSJsBiD/OTohGHheI6f8XBawUw1Y7SocaC7oNCDhLjnTT/mSBWEV9ataMv3lX2WmJTv 5H8/rBUy/pU51Szr5sSKdqTz6G+snSQBAaS/Vv6H8aPHyv9mxVkl7pYByunmz2b3picCa/6SY 6V+Y+qZM94UXyUx5fgX+LB+40A7tITO7qT4GuXm9MuDm02V7ZwP3+ooy2XszjPzIajjBQtkl8 Hx9hPFhHy479WBIrRZEnhr+fUSVPq3RpAdU9JQr/Llk07L9iFZHqXU2EaVygOWqN8IttzYTzN /vZbMNZjs59voAuF406acTAyf/aYzIbpuXXz2R7Et0KsmtzqdlBiudB8vCYohnyagqNZaX1EL Gu6J/8RIiD2HnbqpKtWvfD0bm90Km7nscIh/UexTCNdBHY7kOBHxd17XdcQ= X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 212.227.126.134 Subject: [Qemu-devel] [PATCH for 2.13 v4 15/20] linux-user: move xtensa signal.c parts to xtensa directory 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: Peter Maydell , Riku Voipio , Cornelia Huck , Richard Henderson , =?utf-8?q?Philippe_Mathieu-Daud=C3=A9?= , Laurent Vivier , qemu-s390x@nongnu.org, =?utf-8?q?Alex_Benn=C3=A9e?= Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" No code change, only move code from signal.c to xtensa/signal.c, except adding includes and exporting setup_rt_frame(). Signed-off-by: Laurent Vivier Reviewed-by: Alex Bennée Reviewed-by: Richard Henderson --- Notes: v3: report changes introduced by 20ef667060 target/xtensa: fix flush_window_regs linux-user/signal.c | 247 ------------------------------------- linux-user/xtensa/signal.c | 250 ++++++++++++++++++++++++++++++++++++++ linux-user/xtensa/target_signal.h | 3 + 3 files changed, 253 insertions(+), 247 deletions(-) diff --git a/linux-user/signal.c b/linux-user/signal.c index 58bbb7693c..b9ad4c14a3 100644 --- a/linux-user/signal.c +++ b/linux-user/signal.c @@ -3031,253 +3031,6 @@ sigsegv: force_sig(TARGET_SIGSEGV); return -TARGET_QEMU_ESIGRETURN; } - -#elif defined(TARGET_XTENSA) - -struct target_sigcontext { - abi_ulong sc_pc; - abi_ulong sc_ps; - abi_ulong sc_lbeg; - abi_ulong sc_lend; - abi_ulong sc_lcount; - abi_ulong sc_sar; - abi_ulong sc_acclo; - abi_ulong sc_acchi; - abi_ulong sc_a[16]; - abi_ulong sc_xtregs; -}; - -struct target_ucontext { - abi_ulong tuc_flags; - abi_ulong tuc_link; - target_stack_t tuc_stack; - struct target_sigcontext tuc_mcontext; - target_sigset_t tuc_sigmask; -}; - -struct target_rt_sigframe { - target_siginfo_t info; - struct target_ucontext uc; - /* TODO: xtregs */ - uint8_t retcode[6]; - abi_ulong window[4]; -}; - -static abi_ulong get_sigframe(struct target_sigaction *sa, - CPUXtensaState *env, - unsigned long framesize) -{ - abi_ulong sp = env->regs[1]; - - /* This is the X/Open sanctioned signal stack switching. */ - if ((sa->sa_flags & TARGET_SA_ONSTACK) != 0 && !sas_ss_flags(sp)) { - sp = target_sigaltstack_used.ss_sp + target_sigaltstack_used.ss_size; - } - return (sp - framesize) & -16; -} - -static int flush_window_regs(CPUXtensaState *env) -{ - uint32_t wb = env->sregs[WINDOW_BASE]; - uint32_t ws = xtensa_replicate_windowstart(env) >> (wb + 1); - unsigned d = ctz32(ws) + 1; - unsigned i; - int ret = 0; - - for (i = d; i < env->config->nareg / 4; i += d) { - uint32_t ssp, osp; - unsigned j; - - ws >>= d; - xtensa_rotate_window(env, d); - - if (ws & 0x1) { - ssp = env->regs[5]; - d = 1; - } else if (ws & 0x2) { - ssp = env->regs[9]; - ret |= get_user_ual(osp, env->regs[1] - 12); - osp -= 32; - d = 2; - } else if (ws & 0x4) { - ssp = env->regs[13]; - ret |= get_user_ual(osp, env->regs[1] - 12); - osp -= 48; - d = 3; - } else { - g_assert_not_reached(); - } - - for (j = 0; j < 4; ++j) { - ret |= put_user_ual(env->regs[j], ssp - 16 + j * 4); - } - for (j = 4; j < d * 4; ++j) { - ret |= put_user_ual(env->regs[j], osp - 16 + j * 4); - } - } - xtensa_rotate_window(env, d); - g_assert(env->sregs[WINDOW_BASE] == wb); - return ret == 0; -} - -static int setup_sigcontext(struct target_rt_sigframe *frame, - CPUXtensaState *env) -{ - struct target_sigcontext *sc = &frame->uc.tuc_mcontext; - int i; - - __put_user(env->pc, &sc->sc_pc); - __put_user(env->sregs[PS], &sc->sc_ps); - __put_user(env->sregs[LBEG], &sc->sc_lbeg); - __put_user(env->sregs[LEND], &sc->sc_lend); - __put_user(env->sregs[LCOUNT], &sc->sc_lcount); - if (!flush_window_regs(env)) { - return 0; - } - for (i = 0; i < 16; ++i) { - __put_user(env->regs[i], sc->sc_a + i); - } - __put_user(0, &sc->sc_xtregs); - /* TODO: xtregs */ - return 1; -} - -static void setup_rt_frame(int sig, struct target_sigaction *ka, - target_siginfo_t *info, - target_sigset_t *set, CPUXtensaState *env) -{ - abi_ulong frame_addr; - struct target_rt_sigframe *frame; - uint32_t ra; - int i; - - frame_addr = get_sigframe(ka, env, sizeof(*frame)); - trace_user_setup_rt_frame(env, frame_addr); - - if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0)) { - goto give_sigsegv; - } - - if (ka->sa_flags & SA_SIGINFO) { - tswap_siginfo(&frame->info, info); - } - - __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); - if (!setup_sigcontext(frame, env)) { - unlock_user_struct(frame, frame_addr, 0); - goto give_sigsegv; - } - for (i = 0; i < TARGET_NSIG_WORDS; ++i) { - __put_user(set->sig[i], &frame->uc.tuc_sigmask.sig[i]); - } - - if (ka->sa_flags & TARGET_SA_RESTORER) { - ra = ka->sa_restorer; - } else { - ra = frame_addr + offsetof(struct target_rt_sigframe, retcode); -#ifdef TARGET_WORDS_BIGENDIAN - /* Generate instruction: MOVI a2, __NR_rt_sigreturn */ - __put_user(0x22, &frame->retcode[0]); - __put_user(0x0a, &frame->retcode[1]); - __put_user(TARGET_NR_rt_sigreturn, &frame->retcode[2]); - /* Generate instruction: SYSCALL */ - __put_user(0x00, &frame->retcode[3]); - __put_user(0x05, &frame->retcode[4]); - __put_user(0x00, &frame->retcode[5]); -#else - /* Generate instruction: MOVI a2, __NR_rt_sigreturn */ - __put_user(0x22, &frame->retcode[0]); - __put_user(0xa0, &frame->retcode[1]); - __put_user(TARGET_NR_rt_sigreturn, &frame->retcode[2]); - /* Generate instruction: SYSCALL */ - __put_user(0x00, &frame->retcode[3]); - __put_user(0x50, &frame->retcode[4]); - __put_user(0x00, &frame->retcode[5]); -#endif - } - env->sregs[PS] = PS_UM | (3 << PS_RING_SHIFT); - if (xtensa_option_enabled(env->config, XTENSA_OPTION_WINDOWED_REGISTER)) { - env->sregs[PS] |= PS_WOE | (1 << PS_CALLINC_SHIFT); - } - memset(env->regs, 0, sizeof(env->regs)); - env->pc = ka->_sa_handler; - env->regs[1] = frame_addr; - env->sregs[WINDOW_BASE] = 0; - env->sregs[WINDOW_START] = 1; - - env->regs[4] = (ra & 0x3fffffff) | 0x40000000; - env->regs[6] = sig; - env->regs[7] = frame_addr + offsetof(struct target_rt_sigframe, info); - env->regs[8] = frame_addr + offsetof(struct target_rt_sigframe, uc); - unlock_user_struct(frame, frame_addr, 1); - return; - -give_sigsegv: - force_sigsegv(sig); - return; -} - -static void restore_sigcontext(CPUXtensaState *env, - struct target_rt_sigframe *frame) -{ - struct target_sigcontext *sc = &frame->uc.tuc_mcontext; - uint32_t ps; - int i; - - __get_user(env->pc, &sc->sc_pc); - __get_user(ps, &sc->sc_ps); - __get_user(env->sregs[LBEG], &sc->sc_lbeg); - __get_user(env->sregs[LEND], &sc->sc_lend); - __get_user(env->sregs[LCOUNT], &sc->sc_lcount); - - env->sregs[WINDOW_BASE] = 0; - env->sregs[WINDOW_START] = 1; - env->sregs[PS] = deposit32(env->sregs[PS], - PS_CALLINC_SHIFT, - PS_CALLINC_LEN, - extract32(ps, PS_CALLINC_SHIFT, - PS_CALLINC_LEN)); - for (i = 0; i < 16; ++i) { - __get_user(env->regs[i], sc->sc_a + i); - } - /* TODO: xtregs */ -} - -long do_rt_sigreturn(CPUXtensaState *env) -{ - abi_ulong frame_addr = env->regs[1]; - struct target_rt_sigframe *frame; - sigset_t set; - - trace_user_do_rt_sigreturn(env, frame_addr); - if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1)) { - goto badframe; - } - target_to_host_sigset(&set, &frame->uc.tuc_sigmask); - set_sigmask(&set); - - restore_sigcontext(env, frame); - - if (do_sigaltstack(frame_addr + - offsetof(struct target_rt_sigframe, uc.tuc_stack), - 0, get_sp_from_cpustate(env)) == -TARGET_EFAULT) { - goto badframe; - } - unlock_user_struct(frame, frame_addr, 0); - return -TARGET_QEMU_ESIGRETURN; - -badframe: - unlock_user_struct(frame, frame_addr, 0); - force_sig(TARGET_SIGSEGV); - return -TARGET_QEMU_ESIGRETURN; -} #endif static void handle_pending_signal(CPUArchState *cpu_env, int sig, diff --git a/linux-user/xtensa/signal.c b/linux-user/xtensa/signal.c index 02ca338b6c..1e98910c1b 100644 --- a/linux-user/xtensa/signal.c +++ b/linux-user/xtensa/signal.c @@ -16,3 +16,253 @@ * You should have received a copy of the GNU General Public License * along with this program; if not, see . */ +#include "qemu/osdep.h" +#include "qemu.h" +#include "target_signal.h" +#include "signal-common.h" +#include "linux-user/trace.h" + +struct target_sigcontext { + abi_ulong sc_pc; + abi_ulong sc_ps; + abi_ulong sc_lbeg; + abi_ulong sc_lend; + abi_ulong sc_lcount; + abi_ulong sc_sar; + abi_ulong sc_acclo; + abi_ulong sc_acchi; + abi_ulong sc_a[16]; + abi_ulong sc_xtregs; +}; + +struct target_ucontext { + abi_ulong tuc_flags; + abi_ulong tuc_link; + target_stack_t tuc_stack; + struct target_sigcontext tuc_mcontext; + target_sigset_t tuc_sigmask; +}; + +struct target_rt_sigframe { + target_siginfo_t info; + struct target_ucontext uc; + /* TODO: xtregs */ + uint8_t retcode[6]; + abi_ulong window[4]; +}; + +static abi_ulong get_sigframe(struct target_sigaction *sa, + CPUXtensaState *env, + unsigned long framesize) +{ + abi_ulong sp = env->regs[1]; + + /* This is the X/Open sanctioned signal stack switching. */ + if ((sa->sa_flags & TARGET_SA_ONSTACK) != 0 && !sas_ss_flags(sp)) { + sp = target_sigaltstack_used.ss_sp + target_sigaltstack_used.ss_size; + } + return (sp - framesize) & -16; +} + +static int flush_window_regs(CPUXtensaState *env) +{ + uint32_t wb = env->sregs[WINDOW_BASE]; + uint32_t ws = xtensa_replicate_windowstart(env) >> (wb + 1); + unsigned d = ctz32(ws) + 1; + unsigned i; + int ret = 0; + + for (i = d; i < env->config->nareg / 4; i += d) { + uint32_t ssp, osp; + unsigned j; + + ws >>= d; + xtensa_rotate_window(env, d); + + if (ws & 0x1) { + ssp = env->regs[5]; + d = 1; + } else if (ws & 0x2) { + ssp = env->regs[9]; + ret |= get_user_ual(osp, env->regs[1] - 12); + osp -= 32; + d = 2; + } else if (ws & 0x4) { + ssp = env->regs[13]; + ret |= get_user_ual(osp, env->regs[1] - 12); + osp -= 48; + d = 3; + } else { + g_assert_not_reached(); + } + + for (j = 0; j < 4; ++j) { + ret |= put_user_ual(env->regs[j], ssp - 16 + j * 4); + } + for (j = 4; j < d * 4; ++j) { + ret |= put_user_ual(env->regs[j], osp - 16 + j * 4); + } + } + xtensa_rotate_window(env, d); + g_assert(env->sregs[WINDOW_BASE] == wb); + return ret == 0; +} + +static int setup_sigcontext(struct target_rt_sigframe *frame, + CPUXtensaState *env) +{ + struct target_sigcontext *sc = &frame->uc.tuc_mcontext; + int i; + + __put_user(env->pc, &sc->sc_pc); + __put_user(env->sregs[PS], &sc->sc_ps); + __put_user(env->sregs[LBEG], &sc->sc_lbeg); + __put_user(env->sregs[LEND], &sc->sc_lend); + __put_user(env->sregs[LCOUNT], &sc->sc_lcount); + if (!flush_window_regs(env)) { + return 0; + } + for (i = 0; i < 16; ++i) { + __put_user(env->regs[i], sc->sc_a + i); + } + __put_user(0, &sc->sc_xtregs); + /* TODO: xtregs */ + return 1; +} + +void setup_rt_frame(int sig, struct target_sigaction *ka, + target_siginfo_t *info, + target_sigset_t *set, CPUXtensaState *env) +{ + abi_ulong frame_addr; + struct target_rt_sigframe *frame; + uint32_t ra; + int i; + + frame_addr = get_sigframe(ka, env, sizeof(*frame)); + trace_user_setup_rt_frame(env, frame_addr); + + if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0)) { + goto give_sigsegv; + } + + if (ka->sa_flags & SA_SIGINFO) { + tswap_siginfo(&frame->info, info); + } + + __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); + if (!setup_sigcontext(frame, env)) { + unlock_user_struct(frame, frame_addr, 0); + goto give_sigsegv; + } + for (i = 0; i < TARGET_NSIG_WORDS; ++i) { + __put_user(set->sig[i], &frame->uc.tuc_sigmask.sig[i]); + } + + if (ka->sa_flags & TARGET_SA_RESTORER) { + ra = ka->sa_restorer; + } else { + ra = frame_addr + offsetof(struct target_rt_sigframe, retcode); +#ifdef TARGET_WORDS_BIGENDIAN + /* Generate instruction: MOVI a2, __NR_rt_sigreturn */ + __put_user(0x22, &frame->retcode[0]); + __put_user(0x0a, &frame->retcode[1]); + __put_user(TARGET_NR_rt_sigreturn, &frame->retcode[2]); + /* Generate instruction: SYSCALL */ + __put_user(0x00, &frame->retcode[3]); + __put_user(0x05, &frame->retcode[4]); + __put_user(0x00, &frame->retcode[5]); +#else + /* Generate instruction: MOVI a2, __NR_rt_sigreturn */ + __put_user(0x22, &frame->retcode[0]); + __put_user(0xa0, &frame->retcode[1]); + __put_user(TARGET_NR_rt_sigreturn, &frame->retcode[2]); + /* Generate instruction: SYSCALL */ + __put_user(0x00, &frame->retcode[3]); + __put_user(0x50, &frame->retcode[4]); + __put_user(0x00, &frame->retcode[5]); +#endif + } + env->sregs[PS] = PS_UM | (3 << PS_RING_SHIFT); + if (xtensa_option_enabled(env->config, XTENSA_OPTION_WINDOWED_REGISTER)) { + env->sregs[PS] |= PS_WOE | (1 << PS_CALLINC_SHIFT); + } + memset(env->regs, 0, sizeof(env->regs)); + env->pc = ka->_sa_handler; + env->regs[1] = frame_addr; + env->sregs[WINDOW_BASE] = 0; + env->sregs[WINDOW_START] = 1; + + env->regs[4] = (ra & 0x3fffffff) | 0x40000000; + env->regs[6] = sig; + env->regs[7] = frame_addr + offsetof(struct target_rt_sigframe, info); + env->regs[8] = frame_addr + offsetof(struct target_rt_sigframe, uc); + unlock_user_struct(frame, frame_addr, 1); + return; + +give_sigsegv: + force_sigsegv(sig); + return; +} + +static void restore_sigcontext(CPUXtensaState *env, + struct target_rt_sigframe *frame) +{ + struct target_sigcontext *sc = &frame->uc.tuc_mcontext; + uint32_t ps; + int i; + + __get_user(env->pc, &sc->sc_pc); + __get_user(ps, &sc->sc_ps); + __get_user(env->sregs[LBEG], &sc->sc_lbeg); + __get_user(env->sregs[LEND], &sc->sc_lend); + __get_user(env->sregs[LCOUNT], &sc->sc_lcount); + + env->sregs[WINDOW_BASE] = 0; + env->sregs[WINDOW_START] = 1; + env->sregs[PS] = deposit32(env->sregs[PS], + PS_CALLINC_SHIFT, + PS_CALLINC_LEN, + extract32(ps, PS_CALLINC_SHIFT, + PS_CALLINC_LEN)); + for (i = 0; i < 16; ++i) { + __get_user(env->regs[i], sc->sc_a + i); + } + /* TODO: xtregs */ +} + +long do_rt_sigreturn(CPUXtensaState *env) +{ + abi_ulong frame_addr = env->regs[1]; + struct target_rt_sigframe *frame; + sigset_t set; + + trace_user_do_rt_sigreturn(env, frame_addr); + if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1)) { + goto badframe; + } + target_to_host_sigset(&set, &frame->uc.tuc_sigmask); + set_sigmask(&set); + + restore_sigcontext(env, frame); + + if (do_sigaltstack(frame_addr + + offsetof(struct target_rt_sigframe, uc.tuc_stack), + 0, get_sp_from_cpustate(env)) == -TARGET_EFAULT) { + goto badframe; + } + unlock_user_struct(frame, frame_addr, 0); + return -TARGET_QEMU_ESIGRETURN; + +badframe: + unlock_user_struct(frame, frame_addr, 0); + force_sig(TARGET_SIGSEGV); + return -TARGET_QEMU_ESIGRETURN; +} diff --git a/linux-user/xtensa/target_signal.h b/linux-user/xtensa/target_signal.h index c6962e70af..f6545903a4 100644 --- a/linux-user/xtensa/target_signal.h +++ b/linux-user/xtensa/target_signal.h @@ -25,4 +25,7 @@ static inline abi_ulong get_sp_from_cpustate(CPUXtensaState *state) return state->regs[1]; } +void setup_rt_frame(int sig, struct target_sigaction *ka, + target_siginfo_t *info, + target_sigset_t *set, CPUXtensaState *env); #endif