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 env
->iaoq_f
|= PRIV_USER
;
105 __get_user(env
->iaoq_b
, &sc
->sc_iaoq
[1]);
106 env
->iaoq_b
|= PRIV_USER
;
107 __get_user(env
->cr
[CR_SAR
], &sc
->sc_sar
);
110 void setup_rt_frame(int sig
, struct target_sigaction
*ka
,
111 target_siginfo_t
*info
,
112 target_sigset_t
*set
, CPUArchState
*env
)
114 abi_ulong frame_addr
, sp
, haddr
;
115 struct target_rt_sigframe
*frame
;
117 TaskState
*ts
= get_task_state(thread_cpu
);
119 sp
= get_sp_from_cpustate(env
);
120 if ((ka
->sa_flags
& TARGET_SA_ONSTACK
) && !sas_ss_flags(sp
)) {
121 sp
= (ts
->sigaltstack_used
.ss_sp
+ 0x7f) & ~0x3f;
123 frame_addr
= QEMU_ALIGN_UP(sp
, SIGFRAME
);
124 sp
= frame_addr
+ PARISC_RT_SIGFRAME_SIZE32
;
126 trace_user_setup_rt_frame(env
, frame_addr
);
128 if (!lock_user_struct(VERIFY_WRITE
, frame
, frame_addr
, 0)) {
133 frame
->uc
.tuc_flags
= 0;
134 frame
->uc
.tuc_link
= 0;
136 target_save_altstack(&frame
->uc
.tuc_stack
, env
);
138 for (i
= 0; i
< TARGET_NSIG_WORDS
; i
++) {
139 __put_user(set
->sig
[i
], &frame
->uc
.tuc_sigmask
.sig
[i
]);
142 setup_sigcontext(&frame
->uc
.tuc_mcontext
, env
);
144 unlock_user_struct(frame
, frame_addr
, 1);
146 env
->gr
[2] = default_rt_sigreturn
;
149 env
->gr
[25] = h2g(&frame
->info
);
150 env
->gr
[24] = h2g(&frame
->uc
);
152 haddr
= ka
->_sa_handler
;
154 /* Function descriptor. */
155 abi_ptr
*fdesc
, dest
;
158 fdesc
= lock_user(VERIFY_READ
, haddr
, 2 * sizeof(abi_ptr
), 1);
162 __get_user(dest
, fdesc
);
163 __get_user(env
->gr
[19], fdesc
+ 1);
164 unlock_user(fdesc
, haddr
, 0);
167 env
->iaoq_f
= haddr
| PRIV_USER
;
168 env
->iaoq_b
= env
->iaoq_f
+ 4;
176 long do_rt_sigreturn(CPUArchState
*env
)
178 abi_ulong frame_addr
= env
->gr
[30] - PARISC_RT_SIGFRAME_SIZE32
;
179 struct target_rt_sigframe
*frame
;
182 trace_user_do_rt_sigreturn(env
, frame_addr
);
183 if (!lock_user_struct(VERIFY_READ
, frame
, frame_addr
, 1)) {
186 target_to_host_sigset(&set
, &frame
->uc
.tuc_sigmask
);
189 restore_sigcontext(env
, &frame
->uc
.tuc_mcontext
);
190 target_restore_altstack(&frame
->uc
.tuc_stack
, env
);
192 unlock_user_struct(frame
, frame_addr
, 0);
193 return -QEMU_ESIGRETURN
;
196 force_sig(TARGET_SIGSEGV
);
197 return -QEMU_ESIGRETURN
;
200 void setup_sigtramp(abi_ulong sigtramp_page
)
202 uint32_t *tramp
= lock_user(VERIFY_WRITE
, sigtramp_page
, 6*4, 0);
203 abi_ulong SIGFRAME_CONTEXT_REGS32
;
204 assert(tramp
!= NULL
);
206 SIGFRAME_CONTEXT_REGS32
= offsetof(struct target_rt_sigframe
, uc
.tuc_mcontext
);
207 SIGFRAME_CONTEXT_REGS32
-= PARISC_RT_SIGFRAME_SIZE32
;
209 __put_user(SIGFRAME_CONTEXT_REGS32
, tramp
+ 0);
210 __put_user(0x08000240, tramp
+ 1); /* nop - b/c dwarf2 unwind routines */
211 __put_user(0x34190000, tramp
+ 2); /* ldi 0, %r25 (in_syscall=0) */
212 __put_user(0x3414015a, tramp
+ 3); /* ldi __NR_rt_sigreturn, %r20 */
213 __put_user(0xe4008200, tramp
+ 4); /* ble 0x100(%sr2, %r0) */
214 __put_user(0x08000240, tramp
+ 5); /* nop */
216 default_rt_sigreturn
= (sigtramp_page
+ 8) | 3;
217 unlock_user(tramp
, sigtramp_page
, 6*4);