master
c 126 lines 3.29 KB
Raw
1 /*
2 * ARM AArch64 specific signal definitions for bsd-user
3 *
4 * Copyright (c) 2015 Stacey D. Son
5 *
6 * SPDX-License-Identifier: GPL-2.0-or-later
7 */
8 #include "qemu/osdep.h"
9
10 #include "qemu.h"
11
12 /*
13 * Compare to sendsig() in sys/arm64/arm64/exec_machdep.c
14 * Assumes that target stack frame memory is locked.
15 */
16 abi_long set_sigtramp_args(CPUARMState *regs, int sig,
17 struct target_sigframe *frame,
18 abi_ulong frame_addr,
19 struct target_sigaction *ka)
20 {
21 /*
22 * Arguments to signal handler:
23 * x0 = signal number
24 * x1 = siginfo pointer
25 * x2 = ucontext pointer
26 * pc/elr = signal handler pointer
27 * sp = sigframe struct pointer
28 * lr = sigtramp at base of user stack
29 */
30
31 regs->xregs[0] = sig;
32 regs->xregs[1] = frame_addr +
33 offsetof(struct target_sigframe, sf_si);
34 regs->xregs[2] = frame_addr +
35 offsetof(struct target_sigframe, sf_uc);
36
37 regs->pc = ka->_sa_handler;
38 regs->xregs[TARGET_REG_SP] = frame_addr;
39 regs->xregs[TARGET_REG_LR] = TARGET_PS_STRINGS - TARGET_SZSIGCODE;
40
41 return 0;
42 }
43
44 /*
45 * Compare to get_mcontext() in arm64/arm64/machdep.c
46 * Assumes that the memory is locked if mcp points to user memory.
47 */
48 abi_long get_mcontext(CPUARMState *regs, target_mcontext_t *mcp, int flags)
49 {
50 int err = 0, i;
51 uint64_t *gr = mcp->mc_gpregs.gp_x;
52
53 mcp->mc_gpregs.gp_spsr = pstate_read(regs);
54 if (flags & TARGET_MC_GET_CLEAR_RET) {
55 gr[0] = 0UL;
56 mcp->mc_gpregs.gp_spsr &= ~CPSR_C;
57 } else {
58 gr[0] = tswap64(regs->xregs[0]);
59 }
60
61 for (i = 1; i < 30; i++) {
62 gr[i] = tswap64(regs->xregs[i]);
63 }
64
65 mcp->mc_gpregs.gp_sp = tswap64(regs->xregs[TARGET_REG_SP]);
66 mcp->mc_gpregs.gp_lr = tswap64(regs->xregs[TARGET_REG_LR]);
67 mcp->mc_gpregs.gp_elr = tswap64(regs->pc);
68
69 /* XXX FP? */
70
71 return err;
72 }
73
74 /*
75 * Compare to arm64/arm64/exec_machdep.c sendsig()
76 * Assumes that the memory is locked if frame points to user memory.
77 */
78 abi_long setup_sigframe_arch(CPUARMState *env, abi_ulong frame_addr,
79 struct target_sigframe *frame, int flags)
80 {
81 target_mcontext_t *mcp = &frame->sf_uc.uc_mcontext;
82
83 get_mcontext(env, mcp, flags);
84 return 0;
85 }
86
87 /*
88 * Compare to set_mcontext() in arm64/arm64/machdep.c
89 * Assumes that the memory is locked if frame points to user memory.
90 */
91 abi_long set_mcontext(CPUARMState *regs, target_mcontext_t *mcp, int srflag)
92 {
93 int err = 0, i;
94 const uint64_t *gr = mcp->mc_gpregs.gp_x;
95
96 for (i = 0; i < 30; i++) {
97 regs->xregs[i] = tswap64(gr[i]);
98 }
99
100 regs->xregs[TARGET_REG_SP] = tswap64(mcp->mc_gpregs.gp_sp);
101 regs->xregs[TARGET_REG_LR] = tswap64(mcp->mc_gpregs.gp_lr);
102 regs->pc = mcp->mc_gpregs.gp_elr;
103 pstate_write(regs, mcp->mc_gpregs.gp_spsr);
104
105 /* XXX FP? */
106
107 return err;
108 }
109
110 /* Compare to sys_sigreturn() in arm64/arm64/machdep.c */
111 abi_long get_ucontext_sigreturn(CPUARMState *regs, abi_ulong target_sf,
112 abi_ulong *target_uc)
113 {
114 uint32_t pstate = pstate_read(regs);
115
116 *target_uc = 0;
117
118 if ((pstate & PSTATE_M) != PSTATE_MODE_EL0t ||
119 (pstate & (PSTATE_F | PSTATE_I | PSTATE_A | PSTATE_D)) != 0) {
120 return -TARGET_EINVAL;
121 }
122
123 *target_uc = target_sf;
124
125 return 0;
126 }