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 "target_signal.h"
22 #include "signal-common.h"
23 #include "linux-user/trace.h"
25 struct target_sigcontext
{
46 abi_ulong fault_address
;
49 struct target_ucontext_v1
{
52 target_stack_t tuc_stack
;
53 struct target_sigcontext tuc_mcontext
;
54 target_sigset_t tuc_sigmask
; /* mask last for extensibility */
57 struct target_ucontext_v2
{
60 target_stack_t tuc_stack
;
61 struct target_sigcontext tuc_mcontext
;
62 target_sigset_t tuc_sigmask
; /* mask last for extensibility */
63 char __unused
[128 - sizeof(target_sigset_t
)];
64 abi_ulong tuc_regspace
[128] __attribute__((__aligned__(8)));
67 struct target_user_vfp
{
72 struct target_user_vfp_exc
{
78 struct target_vfp_sigframe
{
81 struct target_user_vfp ufp
;
82 struct target_user_vfp_exc ufp_exc
;
83 } __attribute__((__aligned__(8)));
85 struct target_iwmmxt_sigframe
{
89 /* Note that not all the coprocessor control registers are stored here */
96 } __attribute__((__aligned__(8)));
98 #define TARGET_VFP_MAGIC 0x56465001
99 #define TARGET_IWMMXT_MAGIC 0x12ef842a
103 struct target_sigcontext sc
;
104 abi_ulong extramask
[TARGET_NSIG_WORDS
-1];
105 abi_ulong retcode
[4];
110 struct target_ucontext_v2 uc
;
111 abi_ulong retcode
[4];
114 struct rt_sigframe_v1
118 struct target_siginfo info
;
119 struct target_ucontext_v1 uc
;
120 abi_ulong retcode
[4];
123 struct rt_sigframe_v2
125 struct target_siginfo info
;
126 struct target_ucontext_v2 uc
;
127 abi_ulong retcode
[4];
130 #define TARGET_CONFIG_CPU_32 1
133 * For ARM syscalls, we encode the syscall number into the instruction.
135 #define SWI_SYS_SIGRETURN (0xef000000|(TARGET_NR_sigreturn + ARM_SYSCALL_BASE))
136 #define SWI_SYS_RT_SIGRETURN (0xef000000|(TARGET_NR_rt_sigreturn + ARM_SYSCALL_BASE))
139 * For Thumb syscalls, we pass the syscall number via r7. We therefore
140 * need two 16-bit instructions.
142 #define SWI_THUMB_SIGRETURN (0xdf00 << 16 | 0x2700 | (TARGET_NR_sigreturn))
143 #define SWI_THUMB_RT_SIGRETURN (0xdf00 << 16 | 0x2700 | (TARGET_NR_rt_sigreturn))
145 static const abi_ulong retcodes
[4] = {
146 SWI_SYS_SIGRETURN
, SWI_THUMB_SIGRETURN
,
147 SWI_SYS_RT_SIGRETURN
, SWI_THUMB_RT_SIGRETURN
151 * Stub needed to make sure the FD register (r9) contains the right
154 static const unsigned long sigreturn_fdpic_codes
[3] = {
155 0xe59fc004, /* ldr r12, [pc, #4] to read function descriptor */
156 0xe59c9004, /* ldr r9, [r12, #4] to setup GOT */
157 0xe59cf000 /* ldr pc, [r12] to jump into restorer */
160 static const unsigned long sigreturn_fdpic_thumb_codes
[3] = {
161 0xc008f8df, /* ldr r12, [pc, #8] to read function descriptor */
162 0x9004f8dc, /* ldr r9, [r12, #4] to setup GOT */
163 0xf000f8dc /* ldr pc, [r12] to jump into restorer */
166 static inline int valid_user_regs(CPUARMState
*regs
)
172 setup_sigcontext(struct target_sigcontext
*sc
, /*struct _fpstate *fpstate,*/
173 CPUARMState
*env
, abi_ulong mask
)
175 __put_user(env
->regs
[0], &sc
->arm_r0
);
176 __put_user(env
->regs
[1], &sc
->arm_r1
);
177 __put_user(env
->regs
[2], &sc
->arm_r2
);
178 __put_user(env
->regs
[3], &sc
->arm_r3
);
179 __put_user(env
->regs
[4], &sc
->arm_r4
);
180 __put_user(env
->regs
[5], &sc
->arm_r5
);
181 __put_user(env
->regs
[6], &sc
->arm_r6
);
182 __put_user(env
->regs
[7], &sc
->arm_r7
);
183 __put_user(env
->regs
[8], &sc
->arm_r8
);
184 __put_user(env
->regs
[9], &sc
->arm_r9
);
185 __put_user(env
->regs
[10], &sc
->arm_r10
);
186 __put_user(env
->regs
[11], &sc
->arm_fp
);
187 __put_user(env
->regs
[12], &sc
->arm_ip
);
188 __put_user(env
->regs
[13], &sc
->arm_sp
);
189 __put_user(env
->regs
[14], &sc
->arm_lr
);
190 __put_user(env
->regs
[15], &sc
->arm_pc
);
191 #ifdef TARGET_CONFIG_CPU_32
192 __put_user(cpsr_read(env
), &sc
->arm_cpsr
);
195 __put_user(/* current->thread.trap_no */ 0, &sc
->trap_no
);
196 __put_user(/* current->thread.error_code */ 0, &sc
->error_code
);
197 __put_user(/* current->thread.address */ 0, &sc
->fault_address
);
198 __put_user(mask
, &sc
->oldmask
);
201 static inline abi_ulong
202 get_sigframe(struct target_sigaction
*ka
, CPUARMState
*regs
, int framesize
)
206 sp
= target_sigsp(get_sp_from_cpustate(regs
), ka
);
208 * ATPCS B01 mandates 8-byte alignment
210 return (sp
- framesize
) & ~7;
214 setup_return(CPUARMState
*env
, struct target_sigaction
*ka
,
215 abi_ulong
*rc
, abi_ulong frame_addr
, int usig
, abi_ulong rc_addr
)
217 abi_ulong handler
= 0;
218 abi_ulong handler_fdpic_GOT
= 0;
222 int is_fdpic
= info_is_fdpic(((TaskState
*)thread_cpu
->opaque
)->info
);
225 /* In FDPIC mode, ka->_sa_handler points to a function
226 * descriptor (FD). The first word contains the address of the
227 * handler. The second word contains the value of the PIC
229 abi_ulong funcdesc_ptr
= ka
->_sa_handler
;
230 if (get_user_ual(handler
, funcdesc_ptr
)
231 || get_user_ual(handler_fdpic_GOT
, funcdesc_ptr
+ 4)) {
235 handler
= ka
->_sa_handler
;
240 uint32_t cpsr
= cpsr_read(env
);
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
, 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 (arm_feature(env
, ARM_FEATURE_VFP
)) {
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 #ifdef TARGET_CONFIG_CPU_32
548 __get_user(cpsr
, &sc
->arm_cpsr
);
549 cpsr_write(env
, cpsr
, CPSR_USER
| CPSR_EXEC
, CPSRWriteByInstr
);
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 (arm_feature(env
, ARM_FEATURE_VFP
)) {
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 if (do_sigaltstack(context_addr
689 + offsetof(struct target_ucontext_v2
, tuc_stack
),
690 0, get_sp_from_cpustate(env
)) == -EFAULT
) {
695 /* Send SIGTRAP if we're single-stepping */
696 if (ptrace_cancel_bpt(current
))
697 send_sig(SIGTRAP
, current
, 1);
703 static long do_sigreturn_v2(CPUARMState
*env
)
705 abi_ulong frame_addr
;
706 struct sigframe_v2
*frame
= NULL
;
709 * Since we stacked the signal on a 64-bit boundary,
710 * then 'sp' should be word aligned here. If it's
711 * not, then the user is trying to mess with us.
713 frame_addr
= env
->regs
[13];
714 trace_user_do_sigreturn(env
, frame_addr
);
715 if (frame_addr
& 7) {
719 if (!lock_user_struct(VERIFY_READ
, frame
, frame_addr
, 1)) {
723 if (do_sigframe_return_v2(env
,
725 + offsetof(struct sigframe_v2
, uc
),
730 unlock_user_struct(frame
, frame_addr
, 0);
731 return -TARGET_QEMU_ESIGRETURN
;
734 unlock_user_struct(frame
, frame_addr
, 0);
735 force_sig(TARGET_SIGSEGV
);
736 return -TARGET_QEMU_ESIGRETURN
;
739 long do_sigreturn(CPUARMState
*env
)
741 if (get_osversion() >= 0x020612) {
742 return do_sigreturn_v2(env
);
744 return do_sigreturn_v1(env
);
748 static long do_rt_sigreturn_v1(CPUARMState
*env
)
750 abi_ulong frame_addr
;
751 struct rt_sigframe_v1
*frame
= NULL
;
755 * Since we stacked the signal on a 64-bit boundary,
756 * then 'sp' should be word aligned here. If it's
757 * not, then the user is trying to mess with us.
759 frame_addr
= env
->regs
[13];
760 trace_user_do_rt_sigreturn(env
, frame_addr
);
761 if (frame_addr
& 7) {
765 if (!lock_user_struct(VERIFY_READ
, frame
, frame_addr
, 1)) {
769 target_to_host_sigset(&host_set
, &frame
->uc
.tuc_sigmask
);
770 set_sigmask(&host_set
);
772 if (restore_sigcontext(env
, &frame
->uc
.tuc_mcontext
)) {
776 if (do_sigaltstack(frame_addr
+ offsetof(struct rt_sigframe_v1
, uc
.tuc_stack
), 0, get_sp_from_cpustate(env
)) == -EFAULT
)
780 /* Send SIGTRAP if we're single-stepping */
781 if (ptrace_cancel_bpt(current
))
782 send_sig(SIGTRAP
, current
, 1);
784 unlock_user_struct(frame
, frame_addr
, 0);
785 return -TARGET_QEMU_ESIGRETURN
;
788 unlock_user_struct(frame
, frame_addr
, 0);
789 force_sig(TARGET_SIGSEGV
);
790 return -TARGET_QEMU_ESIGRETURN
;
793 static long do_rt_sigreturn_v2(CPUARMState
*env
)
795 abi_ulong frame_addr
;
796 struct rt_sigframe_v2
*frame
= NULL
;
799 * Since we stacked the signal on a 64-bit boundary,
800 * then 'sp' should be word aligned here. If it's
801 * not, then the user is trying to mess with us.
803 frame_addr
= env
->regs
[13];
804 trace_user_do_rt_sigreturn(env
, frame_addr
);
805 if (frame_addr
& 7) {
809 if (!lock_user_struct(VERIFY_READ
, frame
, frame_addr
, 1)) {
813 if (do_sigframe_return_v2(env
,
815 + offsetof(struct rt_sigframe_v2
, uc
),
820 unlock_user_struct(frame
, frame_addr
, 0);
821 return -TARGET_QEMU_ESIGRETURN
;
824 unlock_user_struct(frame
, frame_addr
, 0);
825 force_sig(TARGET_SIGSEGV
);
826 return -TARGET_QEMU_ESIGRETURN
;
829 long do_rt_sigreturn(CPUARMState
*env
)
831 if (get_osversion() >= 0x020612) {
832 return do_rt_sigreturn_v2(env
);
834 return do_rt_sigreturn_v1(env
);