2 * Emulation of Linux signals
4 * Copyright (c) 2003 Fabrice Bellard
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, see <http://www.gnu.org/licenses/>.
19 #include "qemu/osdep.h"
21 #include "user-internals.h"
22 #include "signal-common.h"
23 #include "linux-user/trace.h"
24 #include "vdso-asmoffset.h"
26 struct target_sigcontext
{
35 struct target_ucontext
{
38 target_stack_t tuc_stack
;
40 struct target_sigcontext tuc_mcontext
;
41 target_sigset_t tuc_sigmask
;
44 struct target_rt_sigframe
{
45 abi_uint tramp
[2]; /* syscall restart return address */
46 target_siginfo_t info
;
47 struct target_ucontext uc
;
48 /* hidden location of upper halves of pa2.0 64-bit gregs */
51 QEMU_BUILD_BUG_ON(sizeof(struct target_rt_sigframe
) != sizeof_rt_sigframe
);
52 QEMU_BUILD_BUG_ON(offsetof(struct target_rt_sigframe
, uc
.tuc_mcontext
)
53 != offsetof_sigcontext
);
54 QEMU_BUILD_BUG_ON(offsetof(struct target_sigcontext
, sc_gr
)
55 != offsetof_sigcontext_gr
);
56 QEMU_BUILD_BUG_ON(offsetof(struct target_sigcontext
, sc_fr
)
57 != offsetof_sigcontext_fr
);
58 QEMU_BUILD_BUG_ON(offsetof(struct target_sigcontext
, sc_iaoq
)
59 != offsetof_sigcontext_iaoq
);
60 QEMU_BUILD_BUG_ON(offsetof(struct target_sigcontext
, sc_sar
)
61 != offsetof_sigcontext_sar
);
64 static void setup_sigcontext(struct target_sigcontext
*sc
, CPUArchState
*env
)
68 __put_user(env
->iaoq_f
, &sc
->sc_iaoq
[0]);
69 __put_user(env
->iaoq_b
, &sc
->sc_iaoq
[1]);
70 __put_user(0, &sc
->sc_iasq
[0]);
71 __put_user(0, &sc
->sc_iasq
[1]);
72 __put_user(0, &sc
->sc_flags
);
74 __put_user(cpu_hppa_get_psw(env
), &sc
->sc_gr
[0]);
75 for (i
= 1; i
< 32; ++i
) {
76 __put_user(env
->gr
[i
], &sc
->sc_gr
[i
]);
79 __put_user((uint64_t)env
->fr0_shadow
<< 32, &sc
->sc_fr
[0]);
80 for (i
= 1; i
< 32; ++i
) {
81 __put_user(env
->fr
[i
], &sc
->sc_fr
[i
]);
84 __put_user(env
->cr
[CR_SAR
], &sc
->sc_sar
);
87 static void restore_sigcontext(CPUArchState
*env
, struct target_sigcontext
*sc
)
92 __get_user(psw
, &sc
->sc_gr
[0]);
93 cpu_hppa_put_psw(env
, psw
);
95 for (i
= 1; i
< 32; ++i
) {
96 __get_user(env
->gr
[i
], &sc
->sc_gr
[i
]);
98 for (i
= 0; i
< 32; ++i
) {
99 __get_user(env
->fr
[i
], &sc
->sc_fr
[i
]);
101 cpu_hppa_loaded_fr0(env
);
103 __get_user(env
->iaoq_f
, &sc
->sc_iaoq
[0]);
104 __get_user(env
->iaoq_b
, &sc
->sc_iaoq
[1]);
105 __get_user(env
->cr
[CR_SAR
], &sc
->sc_sar
);
108 void setup_rt_frame(int sig
, struct target_sigaction
*ka
,
109 target_siginfo_t
*info
,
110 target_sigset_t
*set
, CPUArchState
*env
)
112 abi_ulong frame_addr
, sp
, haddr
;
113 struct target_rt_sigframe
*frame
;
115 TaskState
*ts
= (TaskState
*)thread_cpu
->opaque
;
117 sp
= get_sp_from_cpustate(env
);
118 if ((ka
->sa_flags
& TARGET_SA_ONSTACK
) && !sas_ss_flags(sp
)) {
119 sp
= (ts
->sigaltstack_used
.ss_sp
+ 0x7f) & ~0x3f;
121 frame_addr
= QEMU_ALIGN_UP(sp
, SIGFRAME
);
122 sp
= frame_addr
+ PARISC_RT_SIGFRAME_SIZE32
;
124 trace_user_setup_rt_frame(env
, frame_addr
);
126 if (!lock_user_struct(VERIFY_WRITE
, frame
, frame_addr
, 0)) {
130 tswap_siginfo(&frame
->info
, info
);
131 frame
->uc
.tuc_flags
= 0;
132 frame
->uc
.tuc_link
= 0;
134 target_save_altstack(&frame
->uc
.tuc_stack
, env
);
136 for (i
= 0; i
< TARGET_NSIG_WORDS
; i
++) {
137 __put_user(set
->sig
[i
], &frame
->uc
.tuc_sigmask
.sig
[i
]);
140 setup_sigcontext(&frame
->uc
.tuc_mcontext
, env
);
142 unlock_user_struct(frame
, frame_addr
, 1);
144 env
->gr
[2] = default_rt_sigreturn
;
147 env
->gr
[25] = h2g(&frame
->info
);
148 env
->gr
[24] = h2g(&frame
->uc
);
150 haddr
= ka
->_sa_handler
;
152 /* Function descriptor. */
153 abi_ptr
*fdesc
, dest
;
156 fdesc
= lock_user(VERIFY_READ
, haddr
, 2 * sizeof(abi_ptr
), 1);
160 __get_user(dest
, fdesc
);
161 __get_user(env
->gr
[19], fdesc
+ 1);
162 unlock_user(fdesc
, haddr
, 0);
166 env
->iaoq_b
= haddr
+ 4;
174 long do_rt_sigreturn(CPUArchState
*env
)
176 abi_ulong frame_addr
= env
->gr
[30] - PARISC_RT_SIGFRAME_SIZE32
;
177 struct target_rt_sigframe
*frame
;
180 trace_user_do_rt_sigreturn(env
, frame_addr
);
181 if (!lock_user_struct(VERIFY_READ
, frame
, frame_addr
, 1)) {
184 target_to_host_sigset(&set
, &frame
->uc
.tuc_sigmask
);
187 restore_sigcontext(env
, &frame
->uc
.tuc_mcontext
);
188 target_restore_altstack(&frame
->uc
.tuc_stack
, env
);
190 unlock_user_struct(frame
, frame_addr
, 0);
191 return -QEMU_ESIGRETURN
;
194 force_sig(TARGET_SIGSEGV
);
195 return -QEMU_ESIGRETURN
;
198 void setup_sigtramp(abi_ulong sigtramp_page
)
200 uint32_t *tramp
= lock_user(VERIFY_WRITE
, sigtramp_page
, 6*4, 0);
201 abi_ulong SIGFRAME_CONTEXT_REGS32
;
202 assert(tramp
!= NULL
);
204 SIGFRAME_CONTEXT_REGS32
= offsetof(struct target_rt_sigframe
, uc
.tuc_mcontext
);
205 SIGFRAME_CONTEXT_REGS32
-= PARISC_RT_SIGFRAME_SIZE32
;
207 __put_user(SIGFRAME_CONTEXT_REGS32
, tramp
+ 0);
208 __put_user(0x08000240, tramp
+ 1); /* nop - b/c dwarf2 unwind routines */
209 __put_user(0x34190000, tramp
+ 2); /* ldi 0, %r25 (in_syscall=0) */
210 __put_user(0x3414015a, tramp
+ 3); /* ldi __NR_rt_sigreturn, %r20 */
211 __put_user(0xe4008200, tramp
+ 4); /* ble 0x100(%sr2, %r0) */
212 __put_user(0x08000240, tramp
+ 5); /* nop */
214 default_rt_sigreturn
= (sigtramp_page
+ 8) | 3;
215 unlock_user(tramp
, sigtramp_page
, 6*4);