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
);
292 arm_rebuild_hflags(env
);
297 static abi_ulong
*setup_sigframe_v2_vfp(abi_ulong
*regspace
, CPUARMState
*env
)
300 struct target_vfp_sigframe
*vfpframe
;
301 vfpframe
= (struct target_vfp_sigframe
*)regspace
;
302 __put_user(TARGET_VFP_MAGIC
, &vfpframe
->magic
);
303 __put_user(sizeof(*vfpframe
), &vfpframe
->size
);
304 for (i
= 0; i
< 32; i
++) {
305 __put_user(*aa32_vfp_dreg(env
, i
), &vfpframe
->ufp
.fpregs
[i
]);
307 __put_user(vfp_get_fpscr(env
), &vfpframe
->ufp
.fpscr
);
308 __put_user(env
->vfp
.xregs
[ARM_VFP_FPEXC
], &vfpframe
->ufp_exc
.fpexc
);
309 __put_user(env
->vfp
.xregs
[ARM_VFP_FPINST
], &vfpframe
->ufp_exc
.fpinst
);
310 __put_user(env
->vfp
.xregs
[ARM_VFP_FPINST2
], &vfpframe
->ufp_exc
.fpinst2
);
311 return (abi_ulong
*)(vfpframe
+1);
314 static abi_ulong
*setup_sigframe_v2_iwmmxt(abi_ulong
*regspace
,
318 struct target_iwmmxt_sigframe
*iwmmxtframe
;
319 iwmmxtframe
= (struct target_iwmmxt_sigframe
*)regspace
;
320 __put_user(TARGET_IWMMXT_MAGIC
, &iwmmxtframe
->magic
);
321 __put_user(sizeof(*iwmmxtframe
), &iwmmxtframe
->size
);
322 for (i
= 0; i
< 16; i
++) {
323 __put_user(env
->iwmmxt
.regs
[i
], &iwmmxtframe
->regs
[i
]);
325 __put_user(env
->vfp
.xregs
[ARM_IWMMXT_wCSSF
], &iwmmxtframe
->wcssf
);
326 __put_user(env
->vfp
.xregs
[ARM_IWMMXT_wCASF
], &iwmmxtframe
->wcssf
);
327 __put_user(env
->vfp
.xregs
[ARM_IWMMXT_wCGR0
], &iwmmxtframe
->wcgr0
);
328 __put_user(env
->vfp
.xregs
[ARM_IWMMXT_wCGR1
], &iwmmxtframe
->wcgr1
);
329 __put_user(env
->vfp
.xregs
[ARM_IWMMXT_wCGR2
], &iwmmxtframe
->wcgr2
);
330 __put_user(env
->vfp
.xregs
[ARM_IWMMXT_wCGR3
], &iwmmxtframe
->wcgr3
);
331 return (abi_ulong
*)(iwmmxtframe
+1);
334 static void setup_sigframe_v2(struct target_ucontext_v2
*uc
,
335 target_sigset_t
*set
, CPUARMState
*env
)
337 struct target_sigaltstack stack
;
341 /* Clear all the bits of the ucontext we don't use. */
342 memset(uc
, 0, offsetof(struct target_ucontext_v2
, tuc_mcontext
));
344 memset(&stack
, 0, sizeof(stack
));
345 target_save_altstack(&stack
, env
);
346 memcpy(&uc
->tuc_stack
, &stack
, sizeof(stack
));
348 setup_sigcontext(&uc
->tuc_mcontext
, env
, set
->sig
[0]);
349 /* Save coprocessor signal frame. */
350 regspace
= uc
->tuc_regspace
;
351 if (cpu_isar_feature(aa32_vfp_simd
, env_archcpu(env
))) {
352 regspace
= setup_sigframe_v2_vfp(regspace
, env
);
354 if (arm_feature(env
, ARM_FEATURE_IWMMXT
)) {
355 regspace
= setup_sigframe_v2_iwmmxt(regspace
, env
);
358 /* Write terminating magic word */
359 __put_user(0, regspace
);
361 for(i
= 0; i
< TARGET_NSIG_WORDS
; i
++) {
362 __put_user(set
->sig
[i
], &uc
->tuc_sigmask
.sig
[i
]);
366 /* compare linux/arch/arm/kernel/signal.c:setup_frame() */
367 static void setup_frame_v1(int usig
, struct target_sigaction
*ka
,
368 target_sigset_t
*set
, CPUARMState
*regs
)
370 struct sigframe_v1
*frame
;
371 abi_ulong frame_addr
= get_sigframe(ka
, regs
, sizeof(*frame
));
374 trace_user_setup_frame(regs
, frame_addr
);
375 if (!lock_user_struct(VERIFY_WRITE
, frame
, frame_addr
, 0)) {
379 setup_sigcontext(&frame
->sc
, regs
, set
->sig
[0]);
381 for(i
= 1; i
< TARGET_NSIG_WORDS
; i
++) {
382 __put_user(set
->sig
[i
], &frame
->extramask
[i
- 1]);
385 if (setup_return(regs
, ka
, frame
->retcode
, frame_addr
, usig
,
386 frame_addr
+ offsetof(struct sigframe_v1
, retcode
))) {
390 unlock_user_struct(frame
, frame_addr
, 1);
393 unlock_user_struct(frame
, frame_addr
, 1);
397 static void setup_frame_v2(int usig
, struct target_sigaction
*ka
,
398 target_sigset_t
*set
, CPUARMState
*regs
)
400 struct sigframe_v2
*frame
;
401 abi_ulong frame_addr
= get_sigframe(ka
, regs
, sizeof(*frame
));
403 trace_user_setup_frame(regs
, frame_addr
);
404 if (!lock_user_struct(VERIFY_WRITE
, frame
, frame_addr
, 0)) {
408 setup_sigframe_v2(&frame
->uc
, set
, regs
);
410 if (setup_return(regs
, ka
, frame
->retcode
, frame_addr
, usig
,
411 frame_addr
+ offsetof(struct sigframe_v2
, retcode
))) {
415 unlock_user_struct(frame
, frame_addr
, 1);
418 unlock_user_struct(frame
, frame_addr
, 1);
422 void setup_frame(int usig
, struct target_sigaction
*ka
,
423 target_sigset_t
*set
, CPUARMState
*regs
)
425 if (get_osversion() >= 0x020612) {
426 setup_frame_v2(usig
, ka
, set
, regs
);
428 setup_frame_v1(usig
, ka
, set
, regs
);
432 /* compare linux/arch/arm/kernel/signal.c:setup_rt_frame() */
433 static void setup_rt_frame_v1(int usig
, struct target_sigaction
*ka
,
434 target_siginfo_t
*info
,
435 target_sigset_t
*set
, CPUARMState
*env
)
437 struct rt_sigframe_v1
*frame
;
438 abi_ulong frame_addr
= get_sigframe(ka
, env
, sizeof(*frame
));
439 struct target_sigaltstack stack
;
441 abi_ulong info_addr
, uc_addr
;
443 trace_user_setup_rt_frame(env
, frame_addr
);
444 if (!lock_user_struct(VERIFY_WRITE
, frame
, frame_addr
, 0)) {
448 info_addr
= frame_addr
+ offsetof(struct rt_sigframe_v1
, info
);
449 __put_user(info_addr
, &frame
->pinfo
);
450 uc_addr
= frame_addr
+ offsetof(struct rt_sigframe_v1
, uc
);
451 __put_user(uc_addr
, &frame
->puc
);
452 tswap_siginfo(&frame
->info
, info
);
454 /* Clear all the bits of the ucontext we don't use. */
455 memset(&frame
->uc
, 0, offsetof(struct target_ucontext_v1
, tuc_mcontext
));
457 memset(&stack
, 0, sizeof(stack
));
458 target_save_altstack(&stack
, env
);
459 memcpy(&frame
->uc
.tuc_stack
, &stack
, sizeof(stack
));
461 setup_sigcontext(&frame
->uc
.tuc_mcontext
, env
, set
->sig
[0]);
462 for(i
= 0; i
< TARGET_NSIG_WORDS
; i
++) {
463 __put_user(set
->sig
[i
], &frame
->uc
.tuc_sigmask
.sig
[i
]);
466 if (setup_return(env
, ka
, frame
->retcode
, frame_addr
, usig
,
467 frame_addr
+ offsetof(struct rt_sigframe_v1
, retcode
))) {
471 env
->regs
[1] = info_addr
;
472 env
->regs
[2] = uc_addr
;
474 unlock_user_struct(frame
, frame_addr
, 1);
477 unlock_user_struct(frame
, frame_addr
, 1);
481 static void setup_rt_frame_v2(int usig
, struct target_sigaction
*ka
,
482 target_siginfo_t
*info
,
483 target_sigset_t
*set
, CPUARMState
*env
)
485 struct rt_sigframe_v2
*frame
;
486 abi_ulong frame_addr
= get_sigframe(ka
, env
, sizeof(*frame
));
487 abi_ulong info_addr
, uc_addr
;
489 trace_user_setup_rt_frame(env
, frame_addr
);
490 if (!lock_user_struct(VERIFY_WRITE
, frame
, frame_addr
, 0)) {
494 info_addr
= frame_addr
+ offsetof(struct rt_sigframe_v2
, info
);
495 uc_addr
= frame_addr
+ offsetof(struct rt_sigframe_v2
, uc
);
496 tswap_siginfo(&frame
->info
, info
);
498 setup_sigframe_v2(&frame
->uc
, set
, env
);
500 if (setup_return(env
, ka
, frame
->retcode
, frame_addr
, usig
,
501 frame_addr
+ offsetof(struct rt_sigframe_v2
, retcode
))) {
505 env
->regs
[1] = info_addr
;
506 env
->regs
[2] = uc_addr
;
508 unlock_user_struct(frame
, frame_addr
, 1);
511 unlock_user_struct(frame
, frame_addr
, 1);
515 void setup_rt_frame(int usig
, struct target_sigaction
*ka
,
516 target_siginfo_t
*info
,
517 target_sigset_t
*set
, CPUARMState
*env
)
519 if (get_osversion() >= 0x020612) {
520 setup_rt_frame_v2(usig
, ka
, info
, set
, env
);
522 setup_rt_frame_v1(usig
, ka
, info
, set
, env
);
527 restore_sigcontext(CPUARMState
*env
, struct target_sigcontext
*sc
)
532 __get_user(env
->regs
[0], &sc
->arm_r0
);
533 __get_user(env
->regs
[1], &sc
->arm_r1
);
534 __get_user(env
->regs
[2], &sc
->arm_r2
);
535 __get_user(env
->regs
[3], &sc
->arm_r3
);
536 __get_user(env
->regs
[4], &sc
->arm_r4
);
537 __get_user(env
->regs
[5], &sc
->arm_r5
);
538 __get_user(env
->regs
[6], &sc
->arm_r6
);
539 __get_user(env
->regs
[7], &sc
->arm_r7
);
540 __get_user(env
->regs
[8], &sc
->arm_r8
);
541 __get_user(env
->regs
[9], &sc
->arm_r9
);
542 __get_user(env
->regs
[10], &sc
->arm_r10
);
543 __get_user(env
->regs
[11], &sc
->arm_fp
);
544 __get_user(env
->regs
[12], &sc
->arm_ip
);
545 __get_user(env
->regs
[13], &sc
->arm_sp
);
546 __get_user(env
->regs
[14], &sc
->arm_lr
);
547 __get_user(env
->regs
[15], &sc
->arm_pc
);
548 __get_user(cpsr
, &sc
->arm_cpsr
);
549 cpsr_write(env
, cpsr
, CPSR_USER
| CPSR_EXEC
, CPSRWriteByInstr
);
550 arm_rebuild_hflags(env
);
552 err
|= !valid_user_regs(env
);
557 static long do_sigreturn_v1(CPUARMState
*env
)
559 abi_ulong frame_addr
;
560 struct sigframe_v1
*frame
= NULL
;
566 * Since we stacked the signal on a 64-bit boundary,
567 * then 'sp' should be word aligned here. If it's
568 * not, then the user is trying to mess with us.
570 frame_addr
= env
->regs
[13];
571 trace_user_do_sigreturn(env
, frame_addr
);
572 if (frame_addr
& 7) {
576 if (!lock_user_struct(VERIFY_READ
, frame
, frame_addr
, 1)) {
580 __get_user(set
.sig
[0], &frame
->sc
.oldmask
);
581 for(i
= 1; i
< TARGET_NSIG_WORDS
; i
++) {
582 __get_user(set
.sig
[i
], &frame
->extramask
[i
- 1]);
585 target_to_host_sigset_internal(&host_set
, &set
);
586 set_sigmask(&host_set
);
588 if (restore_sigcontext(env
, &frame
->sc
)) {
593 /* Send SIGTRAP if we're single-stepping */
594 if (ptrace_cancel_bpt(current
))
595 send_sig(SIGTRAP
, current
, 1);
597 unlock_user_struct(frame
, frame_addr
, 0);
598 return -TARGET_QEMU_ESIGRETURN
;
601 force_sig(TARGET_SIGSEGV
);
602 return -TARGET_QEMU_ESIGRETURN
;
605 static abi_ulong
*restore_sigframe_v2_vfp(CPUARMState
*env
, abi_ulong
*regspace
)
609 uint32_t fpscr
, fpexc
;
610 struct target_vfp_sigframe
*vfpframe
;
611 vfpframe
= (struct target_vfp_sigframe
*)regspace
;
613 __get_user(magic
, &vfpframe
->magic
);
614 __get_user(sz
, &vfpframe
->size
);
615 if (magic
!= TARGET_VFP_MAGIC
|| sz
!= sizeof(*vfpframe
)) {
618 for (i
= 0; i
< 32; i
++) {
619 __get_user(*aa32_vfp_dreg(env
, i
), &vfpframe
->ufp
.fpregs
[i
]);
621 __get_user(fpscr
, &vfpframe
->ufp
.fpscr
);
622 vfp_set_fpscr(env
, fpscr
);
623 __get_user(fpexc
, &vfpframe
->ufp_exc
.fpexc
);
624 /* Sanitise FPEXC: ensure VFP is enabled, FPINST2 is invalid
625 * and the exception flag is cleared
628 fpexc
&= ~((1 << 31) | (1 << 28));
629 env
->vfp
.xregs
[ARM_VFP_FPEXC
] = fpexc
;
630 __get_user(env
->vfp
.xregs
[ARM_VFP_FPINST
], &vfpframe
->ufp_exc
.fpinst
);
631 __get_user(env
->vfp
.xregs
[ARM_VFP_FPINST2
], &vfpframe
->ufp_exc
.fpinst2
);
632 return (abi_ulong
*)(vfpframe
+ 1);
635 static abi_ulong
*restore_sigframe_v2_iwmmxt(CPUARMState
*env
,
640 struct target_iwmmxt_sigframe
*iwmmxtframe
;
641 iwmmxtframe
= (struct target_iwmmxt_sigframe
*)regspace
;
643 __get_user(magic
, &iwmmxtframe
->magic
);
644 __get_user(sz
, &iwmmxtframe
->size
);
645 if (magic
!= TARGET_IWMMXT_MAGIC
|| sz
!= sizeof(*iwmmxtframe
)) {
648 for (i
= 0; i
< 16; i
++) {
649 __get_user(env
->iwmmxt
.regs
[i
], &iwmmxtframe
->regs
[i
]);
651 __get_user(env
->vfp
.xregs
[ARM_IWMMXT_wCSSF
], &iwmmxtframe
->wcssf
);
652 __get_user(env
->vfp
.xregs
[ARM_IWMMXT_wCASF
], &iwmmxtframe
->wcssf
);
653 __get_user(env
->vfp
.xregs
[ARM_IWMMXT_wCGR0
], &iwmmxtframe
->wcgr0
);
654 __get_user(env
->vfp
.xregs
[ARM_IWMMXT_wCGR1
], &iwmmxtframe
->wcgr1
);
655 __get_user(env
->vfp
.xregs
[ARM_IWMMXT_wCGR2
], &iwmmxtframe
->wcgr2
);
656 __get_user(env
->vfp
.xregs
[ARM_IWMMXT_wCGR3
], &iwmmxtframe
->wcgr3
);
657 return (abi_ulong
*)(iwmmxtframe
+ 1);
660 static int do_sigframe_return_v2(CPUARMState
*env
,
661 target_ulong context_addr
,
662 struct target_ucontext_v2
*uc
)
667 target_to_host_sigset(&host_set
, &uc
->tuc_sigmask
);
668 set_sigmask(&host_set
);
670 if (restore_sigcontext(env
, &uc
->tuc_mcontext
))
673 /* Restore coprocessor signal frame */
674 regspace
= uc
->tuc_regspace
;
675 if (cpu_isar_feature(aa32_vfp_simd
, env_archcpu(env
))) {
676 regspace
= restore_sigframe_v2_vfp(env
, regspace
);
681 if (arm_feature(env
, ARM_FEATURE_IWMMXT
)) {
682 regspace
= restore_sigframe_v2_iwmmxt(env
, regspace
);
688 target_restore_altstack(&uc
->tuc_stack
, env
);
691 /* Send SIGTRAP if we're single-stepping */
692 if (ptrace_cancel_bpt(current
))
693 send_sig(SIGTRAP
, current
, 1);
699 static long do_sigreturn_v2(CPUARMState
*env
)
701 abi_ulong frame_addr
;
702 struct sigframe_v2
*frame
= NULL
;
705 * Since we stacked the signal on a 64-bit boundary,
706 * then 'sp' should be word aligned here. If it's
707 * not, then the user is trying to mess with us.
709 frame_addr
= env
->regs
[13];
710 trace_user_do_sigreturn(env
, frame_addr
);
711 if (frame_addr
& 7) {
715 if (!lock_user_struct(VERIFY_READ
, frame
, frame_addr
, 1)) {
719 if (do_sigframe_return_v2(env
,
721 + offsetof(struct sigframe_v2
, uc
),
726 unlock_user_struct(frame
, frame_addr
, 0);
727 return -TARGET_QEMU_ESIGRETURN
;
730 unlock_user_struct(frame
, frame_addr
, 0);
731 force_sig(TARGET_SIGSEGV
);
732 return -TARGET_QEMU_ESIGRETURN
;
735 long do_sigreturn(CPUARMState
*env
)
737 if (get_osversion() >= 0x020612) {
738 return do_sigreturn_v2(env
);
740 return do_sigreturn_v1(env
);
744 static long do_rt_sigreturn_v1(CPUARMState
*env
)
746 abi_ulong frame_addr
;
747 struct rt_sigframe_v1
*frame
= NULL
;
751 * Since we stacked the signal on a 64-bit boundary,
752 * then 'sp' should be word aligned here. If it's
753 * not, then the user is trying to mess with us.
755 frame_addr
= env
->regs
[13];
756 trace_user_do_rt_sigreturn(env
, frame_addr
);
757 if (frame_addr
& 7) {
761 if (!lock_user_struct(VERIFY_READ
, frame
, frame_addr
, 1)) {
765 target_to_host_sigset(&host_set
, &frame
->uc
.tuc_sigmask
);
766 set_sigmask(&host_set
);
768 if (restore_sigcontext(env
, &frame
->uc
.tuc_mcontext
)) {
772 target_restore_altstack(&frame
->uc
.tuc_stack
, env
);
775 /* Send SIGTRAP if we're single-stepping */
776 if (ptrace_cancel_bpt(current
))
777 send_sig(SIGTRAP
, current
, 1);
779 unlock_user_struct(frame
, frame_addr
, 0);
780 return -TARGET_QEMU_ESIGRETURN
;
783 unlock_user_struct(frame
, frame_addr
, 0);
784 force_sig(TARGET_SIGSEGV
);
785 return -TARGET_QEMU_ESIGRETURN
;
788 static long do_rt_sigreturn_v2(CPUARMState
*env
)
790 abi_ulong frame_addr
;
791 struct rt_sigframe_v2
*frame
= NULL
;
794 * Since we stacked the signal on a 64-bit boundary,
795 * then 'sp' should be word aligned here. If it's
796 * not, then the user is trying to mess with us.
798 frame_addr
= env
->regs
[13];
799 trace_user_do_rt_sigreturn(env
, frame_addr
);
800 if (frame_addr
& 7) {
804 if (!lock_user_struct(VERIFY_READ
, frame
, frame_addr
, 1)) {
808 if (do_sigframe_return_v2(env
,
810 + offsetof(struct rt_sigframe_v2
, uc
),
815 unlock_user_struct(frame
, frame_addr
, 0);
816 return -TARGET_QEMU_ESIGRETURN
;
819 unlock_user_struct(frame
, frame_addr
, 0);
820 force_sig(TARGET_SIGSEGV
);
821 return -TARGET_QEMU_ESIGRETURN
;
824 long do_rt_sigreturn(CPUARMState
*env
)
826 if (get_osversion() >= 0x020612) {
827 return do_rt_sigreturn_v2(env
);
829 return do_rt_sigreturn_v1(env
);