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 "signal-common.h"
22 #include "linux-user/trace.h"
24 struct target_sigcontext
{
45 abi_ulong fault_address
;
48 struct target_ucontext_v1
{
51 target_stack_t tuc_stack
;
52 struct target_sigcontext tuc_mcontext
;
53 target_sigset_t tuc_sigmask
; /* mask last for extensibility */
56 struct target_ucontext_v2
{
59 target_stack_t tuc_stack
;
60 struct target_sigcontext tuc_mcontext
;
61 target_sigset_t tuc_sigmask
; /* mask last for extensibility */
62 char __unused
[128 - sizeof(target_sigset_t
)];
63 abi_ulong tuc_regspace
[128] __attribute__((__aligned__(8)));
66 struct target_user_vfp
{
71 struct target_user_vfp_exc
{
77 struct target_vfp_sigframe
{
80 struct target_user_vfp ufp
;
81 struct target_user_vfp_exc ufp_exc
;
82 } __attribute__((__aligned__(8)));
84 struct target_iwmmxt_sigframe
{
88 /* Note that not all the coprocessor control registers are stored here */
95 } __attribute__((__aligned__(8)));
97 #define TARGET_VFP_MAGIC 0x56465001
98 #define TARGET_IWMMXT_MAGIC 0x12ef842a
102 struct target_sigcontext sc
;
103 abi_ulong extramask
[TARGET_NSIG_WORDS
-1];
104 abi_ulong retcode
[4];
109 struct target_ucontext_v2 uc
;
110 abi_ulong retcode
[4];
113 struct rt_sigframe_v1
117 struct target_siginfo info
;
118 struct target_ucontext_v1 uc
;
119 abi_ulong retcode
[4];
122 struct rt_sigframe_v2
124 struct target_siginfo info
;
125 struct target_ucontext_v2 uc
;
126 abi_ulong retcode
[4];
130 * For ARM syscalls, we encode the syscall number into the instruction.
132 #define SWI_SYS_SIGRETURN (0xef000000|(TARGET_NR_sigreturn + ARM_SYSCALL_BASE))
133 #define SWI_SYS_RT_SIGRETURN (0xef000000|(TARGET_NR_rt_sigreturn + ARM_SYSCALL_BASE))
136 * For Thumb syscalls, we pass the syscall number via r7. We therefore
137 * need two 16-bit instructions.
139 #define SWI_THUMB_SIGRETURN (0xdf00 << 16 | 0x2700 | (TARGET_NR_sigreturn))
140 #define SWI_THUMB_RT_SIGRETURN (0xdf00 << 16 | 0x2700 | (TARGET_NR_rt_sigreturn))
142 static const abi_ulong retcodes
[4] = {
143 SWI_SYS_SIGRETURN
, SWI_THUMB_SIGRETURN
,
144 SWI_SYS_RT_SIGRETURN
, SWI_THUMB_RT_SIGRETURN
148 * Stub needed to make sure the FD register (r9) contains the right
151 static const unsigned long sigreturn_fdpic_codes
[3] = {
152 0xe59fc004, /* ldr r12, [pc, #4] to read function descriptor */
153 0xe59c9004, /* ldr r9, [r12, #4] to setup GOT */
154 0xe59cf000 /* ldr pc, [r12] to jump into restorer */
157 static const unsigned long sigreturn_fdpic_thumb_codes
[3] = {
158 0xc008f8df, /* ldr r12, [pc, #8] to read function descriptor */
159 0x9004f8dc, /* ldr r9, [r12, #4] to setup GOT */
160 0xf000f8dc /* ldr pc, [r12] to jump into restorer */
163 static inline int valid_user_regs(CPUARMState
*regs
)
169 setup_sigcontext(struct target_sigcontext
*sc
, /*struct _fpstate *fpstate,*/
170 CPUARMState
*env
, abi_ulong mask
)
172 __put_user(env
->regs
[0], &sc
->arm_r0
);
173 __put_user(env
->regs
[1], &sc
->arm_r1
);
174 __put_user(env
->regs
[2], &sc
->arm_r2
);
175 __put_user(env
->regs
[3], &sc
->arm_r3
);
176 __put_user(env
->regs
[4], &sc
->arm_r4
);
177 __put_user(env
->regs
[5], &sc
->arm_r5
);
178 __put_user(env
->regs
[6], &sc
->arm_r6
);
179 __put_user(env
->regs
[7], &sc
->arm_r7
);
180 __put_user(env
->regs
[8], &sc
->arm_r8
);
181 __put_user(env
->regs
[9], &sc
->arm_r9
);
182 __put_user(env
->regs
[10], &sc
->arm_r10
);
183 __put_user(env
->regs
[11], &sc
->arm_fp
);
184 __put_user(env
->regs
[12], &sc
->arm_ip
);
185 __put_user(env
->regs
[13], &sc
->arm_sp
);
186 __put_user(env
->regs
[14], &sc
->arm_lr
);
187 __put_user(env
->regs
[15], &sc
->arm_pc
);
188 __put_user(cpsr_read(env
), &sc
->arm_cpsr
);
190 __put_user(/* current->thread.trap_no */ 0, &sc
->trap_no
);
191 __put_user(/* current->thread.error_code */ 0, &sc
->error_code
);
192 __put_user(/* current->thread.address */ 0, &sc
->fault_address
);
193 __put_user(mask
, &sc
->oldmask
);
196 static inline abi_ulong
197 get_sigframe(struct target_sigaction
*ka
, CPUARMState
*regs
, int framesize
)
201 sp
= target_sigsp(get_sp_from_cpustate(regs
), ka
);
203 * ATPCS B01 mandates 8-byte alignment
205 return (sp
- framesize
) & ~7;
209 setup_return(CPUARMState
*env
, struct target_sigaction
*ka
,
210 abi_ulong
*rc
, abi_ulong frame_addr
, int usig
, abi_ulong rc_addr
)
212 abi_ulong handler
= 0;
213 abi_ulong handler_fdpic_GOT
= 0;
217 int is_fdpic
= info_is_fdpic(((TaskState
*)thread_cpu
->opaque
)->info
);
220 /* In FDPIC mode, ka->_sa_handler points to a function
221 * descriptor (FD). The first word contains the address of the
222 * handler. The second word contains the value of the PIC
224 abi_ulong funcdesc_ptr
= ka
->_sa_handler
;
225 if (get_user_ual(handler
, funcdesc_ptr
)
226 || get_user_ual(handler_fdpic_GOT
, funcdesc_ptr
+ 4)) {
230 handler
= ka
->_sa_handler
;
235 uint32_t cpsr
= cpsr_read(env
);
243 if (env
->cp15
.sctlr_el
[1] & SCTLR_E0E
) {
249 if (ka
->sa_flags
& TARGET_SA_RESTORER
) {
251 /* For FDPIC we ensure that the restorer is called with a
252 * correct r9 value. For that we need to write code on
253 * the stack that sets r9 and jumps back to restorer
257 __put_user(sigreturn_fdpic_thumb_codes
[0], rc
);
258 __put_user(sigreturn_fdpic_thumb_codes
[1], rc
+ 1);
259 __put_user(sigreturn_fdpic_thumb_codes
[2], rc
+ 2);
260 __put_user((abi_ulong
)ka
->sa_restorer
, rc
+ 3);
262 __put_user(sigreturn_fdpic_codes
[0], rc
);
263 __put_user(sigreturn_fdpic_codes
[1], rc
+ 1);
264 __put_user(sigreturn_fdpic_codes
[2], rc
+ 2);
265 __put_user((abi_ulong
)ka
->sa_restorer
, rc
+ 3);
268 retcode
= rc_addr
+ thumb
;
270 retcode
= ka
->sa_restorer
;
273 unsigned int idx
= thumb
;
275 if (ka
->sa_flags
& TARGET_SA_SIGINFO
) {
279 __put_user(retcodes
[idx
], rc
);
281 retcode
= rc_addr
+ thumb
;
286 env
->regs
[9] = handler_fdpic_GOT
;
288 env
->regs
[13] = frame_addr
;
289 env
->regs
[14] = retcode
;
290 env
->regs
[15] = handler
& (thumb
? ~1 : ~3);
291 cpsr_write(env
, cpsr
, CPSR_IT
| CPSR_T
| CPSR_E
, CPSRWriteByInstr
);
296 static abi_ulong
*setup_sigframe_v2_vfp(abi_ulong
*regspace
, CPUARMState
*env
)
299 struct target_vfp_sigframe
*vfpframe
;
300 vfpframe
= (struct target_vfp_sigframe
*)regspace
;
301 __put_user(TARGET_VFP_MAGIC
, &vfpframe
->magic
);
302 __put_user(sizeof(*vfpframe
), &vfpframe
->size
);
303 for (i
= 0; i
< 32; i
++) {
304 __put_user(*aa32_vfp_dreg(env
, i
), &vfpframe
->ufp
.fpregs
[i
]);
306 __put_user(vfp_get_fpscr(env
), &vfpframe
->ufp
.fpscr
);
307 __put_user(env
->vfp
.xregs
[ARM_VFP_FPEXC
], &vfpframe
->ufp_exc
.fpexc
);
308 __put_user(env
->vfp
.xregs
[ARM_VFP_FPINST
], &vfpframe
->ufp_exc
.fpinst
);
309 __put_user(env
->vfp
.xregs
[ARM_VFP_FPINST2
], &vfpframe
->ufp_exc
.fpinst2
);
310 return (abi_ulong
*)(vfpframe
+1);
313 static abi_ulong
*setup_sigframe_v2_iwmmxt(abi_ulong
*regspace
,
317 struct target_iwmmxt_sigframe
*iwmmxtframe
;
318 iwmmxtframe
= (struct target_iwmmxt_sigframe
*)regspace
;
319 __put_user(TARGET_IWMMXT_MAGIC
, &iwmmxtframe
->magic
);
320 __put_user(sizeof(*iwmmxtframe
), &iwmmxtframe
->size
);
321 for (i
= 0; i
< 16; i
++) {
322 __put_user(env
->iwmmxt
.regs
[i
], &iwmmxtframe
->regs
[i
]);
324 __put_user(env
->vfp
.xregs
[ARM_IWMMXT_wCSSF
], &iwmmxtframe
->wcssf
);
325 __put_user(env
->vfp
.xregs
[ARM_IWMMXT_wCASF
], &iwmmxtframe
->wcssf
);
326 __put_user(env
->vfp
.xregs
[ARM_IWMMXT_wCGR0
], &iwmmxtframe
->wcgr0
);
327 __put_user(env
->vfp
.xregs
[ARM_IWMMXT_wCGR1
], &iwmmxtframe
->wcgr1
);
328 __put_user(env
->vfp
.xregs
[ARM_IWMMXT_wCGR2
], &iwmmxtframe
->wcgr2
);
329 __put_user(env
->vfp
.xregs
[ARM_IWMMXT_wCGR3
], &iwmmxtframe
->wcgr3
);
330 return (abi_ulong
*)(iwmmxtframe
+1);
333 static void setup_sigframe_v2(struct target_ucontext_v2
*uc
,
334 target_sigset_t
*set
, CPUARMState
*env
)
336 struct target_sigaltstack stack
;
340 /* Clear all the bits of the ucontext we don't use. */
341 memset(uc
, 0, offsetof(struct target_ucontext_v2
, tuc_mcontext
));
343 memset(&stack
, 0, sizeof(stack
));
344 target_save_altstack(&stack
, env
);
345 memcpy(&uc
->tuc_stack
, &stack
, sizeof(stack
));
347 setup_sigcontext(&uc
->tuc_mcontext
, env
, set
->sig
[0]);
348 /* Save coprocessor signal frame. */
349 regspace
= uc
->tuc_regspace
;
350 if (cpu_isar_feature(aa32_vfp_simd
, env_archcpu(env
))) {
351 regspace
= setup_sigframe_v2_vfp(regspace
, env
);
353 if (arm_feature(env
, ARM_FEATURE_IWMMXT
)) {
354 regspace
= setup_sigframe_v2_iwmmxt(regspace
, env
);
357 /* Write terminating magic word */
358 __put_user(0, regspace
);
360 for(i
= 0; i
< TARGET_NSIG_WORDS
; i
++) {
361 __put_user(set
->sig
[i
], &uc
->tuc_sigmask
.sig
[i
]);
365 /* compare linux/arch/arm/kernel/signal.c:setup_frame() */
366 static void setup_frame_v1(int usig
, struct target_sigaction
*ka
,
367 target_sigset_t
*set
, CPUARMState
*regs
)
369 struct sigframe_v1
*frame
;
370 abi_ulong frame_addr
= get_sigframe(ka
, regs
, sizeof(*frame
));
373 trace_user_setup_frame(regs
, frame_addr
);
374 if (!lock_user_struct(VERIFY_WRITE
, frame
, frame_addr
, 0)) {
378 setup_sigcontext(&frame
->sc
, regs
, set
->sig
[0]);
380 for(i
= 1; i
< TARGET_NSIG_WORDS
; i
++) {
381 __put_user(set
->sig
[i
], &frame
->extramask
[i
- 1]);
384 if (setup_return(regs
, ka
, frame
->retcode
, frame_addr
, usig
,
385 frame_addr
+ offsetof(struct sigframe_v1
, retcode
))) {
389 unlock_user_struct(frame
, frame_addr
, 1);
392 unlock_user_struct(frame
, frame_addr
, 1);
396 static void setup_frame_v2(int usig
, struct target_sigaction
*ka
,
397 target_sigset_t
*set
, CPUARMState
*regs
)
399 struct sigframe_v2
*frame
;
400 abi_ulong frame_addr
= get_sigframe(ka
, regs
, sizeof(*frame
));
402 trace_user_setup_frame(regs
, frame_addr
);
403 if (!lock_user_struct(VERIFY_WRITE
, frame
, frame_addr
, 0)) {
407 setup_sigframe_v2(&frame
->uc
, set
, regs
);
409 if (setup_return(regs
, ka
, frame
->retcode
, frame_addr
, usig
,
410 frame_addr
+ offsetof(struct sigframe_v2
, retcode
))) {
414 unlock_user_struct(frame
, frame_addr
, 1);
417 unlock_user_struct(frame
, frame_addr
, 1);
421 void setup_frame(int usig
, struct target_sigaction
*ka
,
422 target_sigset_t
*set
, CPUARMState
*regs
)
424 if (get_osversion() >= 0x020612) {
425 setup_frame_v2(usig
, ka
, set
, regs
);
427 setup_frame_v1(usig
, ka
, set
, regs
);
431 /* compare linux/arch/arm/kernel/signal.c:setup_rt_frame() */
432 static void setup_rt_frame_v1(int usig
, struct target_sigaction
*ka
,
433 target_siginfo_t
*info
,
434 target_sigset_t
*set
, CPUARMState
*env
)
436 struct rt_sigframe_v1
*frame
;
437 abi_ulong frame_addr
= get_sigframe(ka
, env
, sizeof(*frame
));
438 struct target_sigaltstack stack
;
440 abi_ulong info_addr
, uc_addr
;
442 trace_user_setup_rt_frame(env
, frame_addr
);
443 if (!lock_user_struct(VERIFY_WRITE
, frame
, frame_addr
, 0)) {
447 info_addr
= frame_addr
+ offsetof(struct rt_sigframe_v1
, info
);
448 __put_user(info_addr
, &frame
->pinfo
);
449 uc_addr
= frame_addr
+ offsetof(struct rt_sigframe_v1
, uc
);
450 __put_user(uc_addr
, &frame
->puc
);
451 tswap_siginfo(&frame
->info
, info
);
453 /* Clear all the bits of the ucontext we don't use. */
454 memset(&frame
->uc
, 0, offsetof(struct target_ucontext_v1
, tuc_mcontext
));
456 memset(&stack
, 0, sizeof(stack
));
457 target_save_altstack(&stack
, env
);
458 memcpy(&frame
->uc
.tuc_stack
, &stack
, sizeof(stack
));
460 setup_sigcontext(&frame
->uc
.tuc_mcontext
, env
, set
->sig
[0]);
461 for(i
= 0; i
< TARGET_NSIG_WORDS
; i
++) {
462 __put_user(set
->sig
[i
], &frame
->uc
.tuc_sigmask
.sig
[i
]);
465 if (setup_return(env
, ka
, frame
->retcode
, frame_addr
, usig
,
466 frame_addr
+ offsetof(struct rt_sigframe_v1
, retcode
))) {
470 env
->regs
[1] = info_addr
;
471 env
->regs
[2] = uc_addr
;
473 unlock_user_struct(frame
, frame_addr
, 1);
476 unlock_user_struct(frame
, frame_addr
, 1);
480 static void setup_rt_frame_v2(int usig
, struct target_sigaction
*ka
,
481 target_siginfo_t
*info
,
482 target_sigset_t
*set
, CPUARMState
*env
)
484 struct rt_sigframe_v2
*frame
;
485 abi_ulong frame_addr
= get_sigframe(ka
, env
, sizeof(*frame
));
486 abi_ulong info_addr
, uc_addr
;
488 trace_user_setup_rt_frame(env
, frame_addr
);
489 if (!lock_user_struct(VERIFY_WRITE
, frame
, frame_addr
, 0)) {
493 info_addr
= frame_addr
+ offsetof(struct rt_sigframe_v2
, info
);
494 uc_addr
= frame_addr
+ offsetof(struct rt_sigframe_v2
, uc
);
495 tswap_siginfo(&frame
->info
, info
);
497 setup_sigframe_v2(&frame
->uc
, set
, env
);
499 if (setup_return(env
, ka
, frame
->retcode
, frame_addr
, usig
,
500 frame_addr
+ offsetof(struct rt_sigframe_v2
, retcode
))) {
504 env
->regs
[1] = info_addr
;
505 env
->regs
[2] = uc_addr
;
507 unlock_user_struct(frame
, frame_addr
, 1);
510 unlock_user_struct(frame
, frame_addr
, 1);
514 void setup_rt_frame(int usig
, struct target_sigaction
*ka
,
515 target_siginfo_t
*info
,
516 target_sigset_t
*set
, CPUARMState
*env
)
518 if (get_osversion() >= 0x020612) {
519 setup_rt_frame_v2(usig
, ka
, info
, set
, env
);
521 setup_rt_frame_v1(usig
, ka
, info
, set
, env
);
526 restore_sigcontext(CPUARMState
*env
, struct target_sigcontext
*sc
)
531 __get_user(env
->regs
[0], &sc
->arm_r0
);
532 __get_user(env
->regs
[1], &sc
->arm_r1
);
533 __get_user(env
->regs
[2], &sc
->arm_r2
);
534 __get_user(env
->regs
[3], &sc
->arm_r3
);
535 __get_user(env
->regs
[4], &sc
->arm_r4
);
536 __get_user(env
->regs
[5], &sc
->arm_r5
);
537 __get_user(env
->regs
[6], &sc
->arm_r6
);
538 __get_user(env
->regs
[7], &sc
->arm_r7
);
539 __get_user(env
->regs
[8], &sc
->arm_r8
);
540 __get_user(env
->regs
[9], &sc
->arm_r9
);
541 __get_user(env
->regs
[10], &sc
->arm_r10
);
542 __get_user(env
->regs
[11], &sc
->arm_fp
);
543 __get_user(env
->regs
[12], &sc
->arm_ip
);
544 __get_user(env
->regs
[13], &sc
->arm_sp
);
545 __get_user(env
->regs
[14], &sc
->arm_lr
);
546 __get_user(env
->regs
[15], &sc
->arm_pc
);
547 __get_user(cpsr
, &sc
->arm_cpsr
);
548 cpsr_write(env
, cpsr
, CPSR_USER
| CPSR_EXEC
, CPSRWriteByInstr
);
550 err
|= !valid_user_regs(env
);
555 static long do_sigreturn_v1(CPUARMState
*env
)
557 abi_ulong frame_addr
;
558 struct sigframe_v1
*frame
= NULL
;
564 * Since we stacked the signal on a 64-bit boundary,
565 * then 'sp' should be word aligned here. If it's
566 * not, then the user is trying to mess with us.
568 frame_addr
= env
->regs
[13];
569 trace_user_do_sigreturn(env
, frame_addr
);
570 if (frame_addr
& 7) {
574 if (!lock_user_struct(VERIFY_READ
, frame
, frame_addr
, 1)) {
578 __get_user(set
.sig
[0], &frame
->sc
.oldmask
);
579 for(i
= 1; i
< TARGET_NSIG_WORDS
; i
++) {
580 __get_user(set
.sig
[i
], &frame
->extramask
[i
- 1]);
583 target_to_host_sigset_internal(&host_set
, &set
);
584 set_sigmask(&host_set
);
586 if (restore_sigcontext(env
, &frame
->sc
)) {
591 /* Send SIGTRAP if we're single-stepping */
592 if (ptrace_cancel_bpt(current
))
593 send_sig(SIGTRAP
, current
, 1);
595 unlock_user_struct(frame
, frame_addr
, 0);
596 return -TARGET_QEMU_ESIGRETURN
;
599 force_sig(TARGET_SIGSEGV
);
600 return -TARGET_QEMU_ESIGRETURN
;
603 static abi_ulong
*restore_sigframe_v2_vfp(CPUARMState
*env
, abi_ulong
*regspace
)
607 uint32_t fpscr
, fpexc
;
608 struct target_vfp_sigframe
*vfpframe
;
609 vfpframe
= (struct target_vfp_sigframe
*)regspace
;
611 __get_user(magic
, &vfpframe
->magic
);
612 __get_user(sz
, &vfpframe
->size
);
613 if (magic
!= TARGET_VFP_MAGIC
|| sz
!= sizeof(*vfpframe
)) {
616 for (i
= 0; i
< 32; i
++) {
617 __get_user(*aa32_vfp_dreg(env
, i
), &vfpframe
->ufp
.fpregs
[i
]);
619 __get_user(fpscr
, &vfpframe
->ufp
.fpscr
);
620 vfp_set_fpscr(env
, fpscr
);
621 __get_user(fpexc
, &vfpframe
->ufp_exc
.fpexc
);
622 /* Sanitise FPEXC: ensure VFP is enabled, FPINST2 is invalid
623 * and the exception flag is cleared
626 fpexc
&= ~((1 << 31) | (1 << 28));
627 env
->vfp
.xregs
[ARM_VFP_FPEXC
] = fpexc
;
628 __get_user(env
->vfp
.xregs
[ARM_VFP_FPINST
], &vfpframe
->ufp_exc
.fpinst
);
629 __get_user(env
->vfp
.xregs
[ARM_VFP_FPINST2
], &vfpframe
->ufp_exc
.fpinst2
);
630 return (abi_ulong
*)(vfpframe
+ 1);
633 static abi_ulong
*restore_sigframe_v2_iwmmxt(CPUARMState
*env
,
638 struct target_iwmmxt_sigframe
*iwmmxtframe
;
639 iwmmxtframe
= (struct target_iwmmxt_sigframe
*)regspace
;
641 __get_user(magic
, &iwmmxtframe
->magic
);
642 __get_user(sz
, &iwmmxtframe
->size
);
643 if (magic
!= TARGET_IWMMXT_MAGIC
|| sz
!= sizeof(*iwmmxtframe
)) {
646 for (i
= 0; i
< 16; i
++) {
647 __get_user(env
->iwmmxt
.regs
[i
], &iwmmxtframe
->regs
[i
]);
649 __get_user(env
->vfp
.xregs
[ARM_IWMMXT_wCSSF
], &iwmmxtframe
->wcssf
);
650 __get_user(env
->vfp
.xregs
[ARM_IWMMXT_wCASF
], &iwmmxtframe
->wcssf
);
651 __get_user(env
->vfp
.xregs
[ARM_IWMMXT_wCGR0
], &iwmmxtframe
->wcgr0
);
652 __get_user(env
->vfp
.xregs
[ARM_IWMMXT_wCGR1
], &iwmmxtframe
->wcgr1
);
653 __get_user(env
->vfp
.xregs
[ARM_IWMMXT_wCGR2
], &iwmmxtframe
->wcgr2
);
654 __get_user(env
->vfp
.xregs
[ARM_IWMMXT_wCGR3
], &iwmmxtframe
->wcgr3
);
655 return (abi_ulong
*)(iwmmxtframe
+ 1);
658 static int do_sigframe_return_v2(CPUARMState
*env
,
659 target_ulong context_addr
,
660 struct target_ucontext_v2
*uc
)
665 target_to_host_sigset(&host_set
, &uc
->tuc_sigmask
);
666 set_sigmask(&host_set
);
668 if (restore_sigcontext(env
, &uc
->tuc_mcontext
))
671 /* Restore coprocessor signal frame */
672 regspace
= uc
->tuc_regspace
;
673 if (cpu_isar_feature(aa32_vfp_simd
, env_archcpu(env
))) {
674 regspace
= restore_sigframe_v2_vfp(env
, regspace
);
679 if (arm_feature(env
, ARM_FEATURE_IWMMXT
)) {
680 regspace
= restore_sigframe_v2_iwmmxt(env
, regspace
);
686 target_restore_altstack(&uc
->tuc_stack
, env
);
689 /* Send SIGTRAP if we're single-stepping */
690 if (ptrace_cancel_bpt(current
))
691 send_sig(SIGTRAP
, current
, 1);
697 static long do_sigreturn_v2(CPUARMState
*env
)
699 abi_ulong frame_addr
;
700 struct sigframe_v2
*frame
= NULL
;
703 * Since we stacked the signal on a 64-bit boundary,
704 * then 'sp' should be word aligned here. If it's
705 * not, then the user is trying to mess with us.
707 frame_addr
= env
->regs
[13];
708 trace_user_do_sigreturn(env
, frame_addr
);
709 if (frame_addr
& 7) {
713 if (!lock_user_struct(VERIFY_READ
, frame
, frame_addr
, 1)) {
717 if (do_sigframe_return_v2(env
,
719 + offsetof(struct sigframe_v2
, uc
),
724 unlock_user_struct(frame
, frame_addr
, 0);
725 return -TARGET_QEMU_ESIGRETURN
;
728 unlock_user_struct(frame
, frame_addr
, 0);
729 force_sig(TARGET_SIGSEGV
);
730 return -TARGET_QEMU_ESIGRETURN
;
733 long do_sigreturn(CPUARMState
*env
)
735 if (get_osversion() >= 0x020612) {
736 return do_sigreturn_v2(env
);
738 return do_sigreturn_v1(env
);
742 static long do_rt_sigreturn_v1(CPUARMState
*env
)
744 abi_ulong frame_addr
;
745 struct rt_sigframe_v1
*frame
= NULL
;
749 * Since we stacked the signal on a 64-bit boundary,
750 * then 'sp' should be word aligned here. If it's
751 * not, then the user is trying to mess with us.
753 frame_addr
= env
->regs
[13];
754 trace_user_do_rt_sigreturn(env
, frame_addr
);
755 if (frame_addr
& 7) {
759 if (!lock_user_struct(VERIFY_READ
, frame
, frame_addr
, 1)) {
763 target_to_host_sigset(&host_set
, &frame
->uc
.tuc_sigmask
);
764 set_sigmask(&host_set
);
766 if (restore_sigcontext(env
, &frame
->uc
.tuc_mcontext
)) {
770 target_restore_altstack(&frame
->uc
.tuc_stack
, env
);
773 /* Send SIGTRAP if we're single-stepping */
774 if (ptrace_cancel_bpt(current
))
775 send_sig(SIGTRAP
, current
, 1);
777 unlock_user_struct(frame
, frame_addr
, 0);
778 return -TARGET_QEMU_ESIGRETURN
;
781 unlock_user_struct(frame
, frame_addr
, 0);
782 force_sig(TARGET_SIGSEGV
);
783 return -TARGET_QEMU_ESIGRETURN
;
786 static long do_rt_sigreturn_v2(CPUARMState
*env
)
788 abi_ulong frame_addr
;
789 struct rt_sigframe_v2
*frame
= NULL
;
792 * Since we stacked the signal on a 64-bit boundary,
793 * then 'sp' should be word aligned here. If it's
794 * not, then the user is trying to mess with us.
796 frame_addr
= env
->regs
[13];
797 trace_user_do_rt_sigreturn(env
, frame_addr
);
798 if (frame_addr
& 7) {
802 if (!lock_user_struct(VERIFY_READ
, frame
, frame_addr
, 1)) {
806 if (do_sigframe_return_v2(env
,
808 + offsetof(struct rt_sigframe_v2
, uc
),
813 unlock_user_struct(frame
, frame_addr
, 0);
814 return -TARGET_QEMU_ESIGRETURN
;
817 unlock_user_struct(frame
, frame_addr
, 0);
818 force_sig(TARGET_SIGSEGV
);
819 return -TARGET_QEMU_ESIGRETURN
;
822 long do_rt_sigreturn(CPUARMState
*env
)
824 if (get_osversion() >= 0x020612) {
825 return do_rt_sigreturn_v2(env
);
827 return do_rt_sigreturn_v1(env
);