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];
129 #define TARGET_CONFIG_CPU_32 1
132 * For ARM syscalls, we encode the syscall number into the instruction.
134 #define SWI_SYS_SIGRETURN (0xef000000|(TARGET_NR_sigreturn + ARM_SYSCALL_BASE))
135 #define SWI_SYS_RT_SIGRETURN (0xef000000|(TARGET_NR_rt_sigreturn + ARM_SYSCALL_BASE))
138 * For Thumb syscalls, we pass the syscall number via r7. We therefore
139 * need two 16-bit instructions.
141 #define SWI_THUMB_SIGRETURN (0xdf00 << 16 | 0x2700 | (TARGET_NR_sigreturn))
142 #define SWI_THUMB_RT_SIGRETURN (0xdf00 << 16 | 0x2700 | (TARGET_NR_rt_sigreturn))
144 static const abi_ulong retcodes
[4] = {
145 SWI_SYS_SIGRETURN
, SWI_THUMB_SIGRETURN
,
146 SWI_SYS_RT_SIGRETURN
, SWI_THUMB_RT_SIGRETURN
150 * Stub needed to make sure the FD register (r9) contains the right
153 static const unsigned long sigreturn_fdpic_codes
[3] = {
154 0xe59fc004, /* ldr r12, [pc, #4] to read function descriptor */
155 0xe59c9004, /* ldr r9, [r12, #4] to setup GOT */
156 0xe59cf000 /* ldr pc, [r12] to jump into restorer */
159 static const unsigned long sigreturn_fdpic_thumb_codes
[3] = {
160 0xc008f8df, /* ldr r12, [pc, #8] to read function descriptor */
161 0x9004f8dc, /* ldr r9, [r12, #4] to setup GOT */
162 0xf000f8dc /* ldr pc, [r12] to jump into restorer */
165 static inline int valid_user_regs(CPUARMState
*regs
)
171 setup_sigcontext(struct target_sigcontext
*sc
, /*struct _fpstate *fpstate,*/
172 CPUARMState
*env
, abi_ulong mask
)
174 __put_user(env
->regs
[0], &sc
->arm_r0
);
175 __put_user(env
->regs
[1], &sc
->arm_r1
);
176 __put_user(env
->regs
[2], &sc
->arm_r2
);
177 __put_user(env
->regs
[3], &sc
->arm_r3
);
178 __put_user(env
->regs
[4], &sc
->arm_r4
);
179 __put_user(env
->regs
[5], &sc
->arm_r5
);
180 __put_user(env
->regs
[6], &sc
->arm_r6
);
181 __put_user(env
->regs
[7], &sc
->arm_r7
);
182 __put_user(env
->regs
[8], &sc
->arm_r8
);
183 __put_user(env
->regs
[9], &sc
->arm_r9
);
184 __put_user(env
->regs
[10], &sc
->arm_r10
);
185 __put_user(env
->regs
[11], &sc
->arm_fp
);
186 __put_user(env
->regs
[12], &sc
->arm_ip
);
187 __put_user(env
->regs
[13], &sc
->arm_sp
);
188 __put_user(env
->regs
[14], &sc
->arm_lr
);
189 __put_user(env
->regs
[15], &sc
->arm_pc
);
190 #ifdef TARGET_CONFIG_CPU_32
191 __put_user(cpsr_read(env
), &sc
->arm_cpsr
);
194 __put_user(/* current->thread.trap_no */ 0, &sc
->trap_no
);
195 __put_user(/* current->thread.error_code */ 0, &sc
->error_code
);
196 __put_user(/* current->thread.address */ 0, &sc
->fault_address
);
197 __put_user(mask
, &sc
->oldmask
);
200 static inline abi_ulong
201 get_sigframe(struct target_sigaction
*ka
, CPUARMState
*regs
, int framesize
)
205 sp
= target_sigsp(get_sp_from_cpustate(regs
), ka
);
207 * ATPCS B01 mandates 8-byte alignment
209 return (sp
- framesize
) & ~7;
213 setup_return(CPUARMState
*env
, struct target_sigaction
*ka
,
214 abi_ulong
*rc
, abi_ulong frame_addr
, int usig
, abi_ulong rc_addr
)
216 abi_ulong handler
= 0;
217 abi_ulong handler_fdpic_GOT
= 0;
221 int is_fdpic
= info_is_fdpic(((TaskState
*)thread_cpu
->opaque
)->info
);
224 /* In FDPIC mode, ka->_sa_handler points to a function
225 * descriptor (FD). The first word contains the address of the
226 * handler. The second word contains the value of the PIC
228 abi_ulong funcdesc_ptr
= ka
->_sa_handler
;
229 if (get_user_ual(handler
, funcdesc_ptr
)
230 || get_user_ual(handler_fdpic_GOT
, funcdesc_ptr
+ 4)) {
234 handler
= ka
->_sa_handler
;
239 uint32_t cpsr
= cpsr_read(env
);
248 if (ka
->sa_flags
& TARGET_SA_RESTORER
) {
250 /* For FDPIC we ensure that the restorer is called with a
251 * correct r9 value. For that we need to write code on
252 * the stack that sets r9 and jumps back to restorer
256 __put_user(sigreturn_fdpic_thumb_codes
[0], rc
);
257 __put_user(sigreturn_fdpic_thumb_codes
[1], rc
+ 1);
258 __put_user(sigreturn_fdpic_thumb_codes
[2], rc
+ 2);
259 __put_user((abi_ulong
)ka
->sa_restorer
, rc
+ 3);
261 __put_user(sigreturn_fdpic_codes
[0], rc
);
262 __put_user(sigreturn_fdpic_codes
[1], rc
+ 1);
263 __put_user(sigreturn_fdpic_codes
[2], rc
+ 2);
264 __put_user((abi_ulong
)ka
->sa_restorer
, rc
+ 3);
267 retcode
= rc_addr
+ thumb
;
269 retcode
= ka
->sa_restorer
;
272 unsigned int idx
= thumb
;
274 if (ka
->sa_flags
& TARGET_SA_SIGINFO
) {
278 __put_user(retcodes
[idx
], rc
);
280 retcode
= rc_addr
+ thumb
;
285 env
->regs
[9] = handler_fdpic_GOT
;
287 env
->regs
[13] = frame_addr
;
288 env
->regs
[14] = retcode
;
289 env
->regs
[15] = handler
& (thumb
? ~1 : ~3);
290 cpsr_write(env
, cpsr
, CPSR_IT
| CPSR_T
, CPSRWriteByInstr
);
295 static abi_ulong
*setup_sigframe_v2_vfp(abi_ulong
*regspace
, CPUARMState
*env
)
298 struct target_vfp_sigframe
*vfpframe
;
299 vfpframe
= (struct target_vfp_sigframe
*)regspace
;
300 __put_user(TARGET_VFP_MAGIC
, &vfpframe
->magic
);
301 __put_user(sizeof(*vfpframe
), &vfpframe
->size
);
302 for (i
= 0; i
< 32; i
++) {
303 __put_user(*aa32_vfp_dreg(env
, i
), &vfpframe
->ufp
.fpregs
[i
]);
305 __put_user(vfp_get_fpscr(env
), &vfpframe
->ufp
.fpscr
);
306 __put_user(env
->vfp
.xregs
[ARM_VFP_FPEXC
], &vfpframe
->ufp_exc
.fpexc
);
307 __put_user(env
->vfp
.xregs
[ARM_VFP_FPINST
], &vfpframe
->ufp_exc
.fpinst
);
308 __put_user(env
->vfp
.xregs
[ARM_VFP_FPINST2
], &vfpframe
->ufp_exc
.fpinst2
);
309 return (abi_ulong
*)(vfpframe
+1);
312 static abi_ulong
*setup_sigframe_v2_iwmmxt(abi_ulong
*regspace
,
316 struct target_iwmmxt_sigframe
*iwmmxtframe
;
317 iwmmxtframe
= (struct target_iwmmxt_sigframe
*)regspace
;
318 __put_user(TARGET_IWMMXT_MAGIC
, &iwmmxtframe
->magic
);
319 __put_user(sizeof(*iwmmxtframe
), &iwmmxtframe
->size
);
320 for (i
= 0; i
< 16; i
++) {
321 __put_user(env
->iwmmxt
.regs
[i
], &iwmmxtframe
->regs
[i
]);
323 __put_user(env
->vfp
.xregs
[ARM_IWMMXT_wCSSF
], &iwmmxtframe
->wcssf
);
324 __put_user(env
->vfp
.xregs
[ARM_IWMMXT_wCASF
], &iwmmxtframe
->wcssf
);
325 __put_user(env
->vfp
.xregs
[ARM_IWMMXT_wCGR0
], &iwmmxtframe
->wcgr0
);
326 __put_user(env
->vfp
.xregs
[ARM_IWMMXT_wCGR1
], &iwmmxtframe
->wcgr1
);
327 __put_user(env
->vfp
.xregs
[ARM_IWMMXT_wCGR2
], &iwmmxtframe
->wcgr2
);
328 __put_user(env
->vfp
.xregs
[ARM_IWMMXT_wCGR3
], &iwmmxtframe
->wcgr3
);
329 return (abi_ulong
*)(iwmmxtframe
+1);
332 static void setup_sigframe_v2(struct target_ucontext_v2
*uc
,
333 target_sigset_t
*set
, CPUARMState
*env
)
335 struct target_sigaltstack stack
;
339 /* Clear all the bits of the ucontext we don't use. */
340 memset(uc
, 0, offsetof(struct target_ucontext_v2
, tuc_mcontext
));
342 memset(&stack
, 0, sizeof(stack
));
343 target_save_altstack(&stack
, env
);
344 memcpy(&uc
->tuc_stack
, &stack
, sizeof(stack
));
346 setup_sigcontext(&uc
->tuc_mcontext
, env
, set
->sig
[0]);
347 /* Save coprocessor signal frame. */
348 regspace
= uc
->tuc_regspace
;
349 if (arm_feature(env
, ARM_FEATURE_VFP
)) {
350 regspace
= setup_sigframe_v2_vfp(regspace
, env
);
352 if (arm_feature(env
, ARM_FEATURE_IWMMXT
)) {
353 regspace
= setup_sigframe_v2_iwmmxt(regspace
, env
);
356 /* Write terminating magic word */
357 __put_user(0, regspace
);
359 for(i
= 0; i
< TARGET_NSIG_WORDS
; i
++) {
360 __put_user(set
->sig
[i
], &uc
->tuc_sigmask
.sig
[i
]);
364 /* compare linux/arch/arm/kernel/signal.c:setup_frame() */
365 static void setup_frame_v1(int usig
, struct target_sigaction
*ka
,
366 target_sigset_t
*set
, CPUARMState
*regs
)
368 struct sigframe_v1
*frame
;
369 abi_ulong frame_addr
= get_sigframe(ka
, regs
, sizeof(*frame
));
372 trace_user_setup_frame(regs
, frame_addr
);
373 if (!lock_user_struct(VERIFY_WRITE
, frame
, frame_addr
, 0)) {
377 setup_sigcontext(&frame
->sc
, regs
, set
->sig
[0]);
379 for(i
= 1; i
< TARGET_NSIG_WORDS
; i
++) {
380 __put_user(set
->sig
[i
], &frame
->extramask
[i
- 1]);
383 if (setup_return(regs
, ka
, frame
->retcode
, frame_addr
, usig
,
384 frame_addr
+ offsetof(struct sigframe_v1
, retcode
))) {
388 unlock_user_struct(frame
, frame_addr
, 1);
391 unlock_user_struct(frame
, frame_addr
, 1);
395 static void setup_frame_v2(int usig
, struct target_sigaction
*ka
,
396 target_sigset_t
*set
, CPUARMState
*regs
)
398 struct sigframe_v2
*frame
;
399 abi_ulong frame_addr
= get_sigframe(ka
, regs
, sizeof(*frame
));
401 trace_user_setup_frame(regs
, frame_addr
);
402 if (!lock_user_struct(VERIFY_WRITE
, frame
, frame_addr
, 0)) {
406 setup_sigframe_v2(&frame
->uc
, set
, regs
);
408 if (setup_return(regs
, ka
, frame
->retcode
, frame_addr
, usig
,
409 frame_addr
+ offsetof(struct sigframe_v2
, retcode
))) {
413 unlock_user_struct(frame
, frame_addr
, 1);
416 unlock_user_struct(frame
, frame_addr
, 1);
420 void setup_frame(int usig
, struct target_sigaction
*ka
,
421 target_sigset_t
*set
, CPUARMState
*regs
)
423 if (get_osversion() >= 0x020612) {
424 setup_frame_v2(usig
, ka
, set
, regs
);
426 setup_frame_v1(usig
, ka
, set
, regs
);
430 /* compare linux/arch/arm/kernel/signal.c:setup_rt_frame() */
431 static void setup_rt_frame_v1(int usig
, struct target_sigaction
*ka
,
432 target_siginfo_t
*info
,
433 target_sigset_t
*set
, CPUARMState
*env
)
435 struct rt_sigframe_v1
*frame
;
436 abi_ulong frame_addr
= get_sigframe(ka
, env
, sizeof(*frame
));
437 struct target_sigaltstack stack
;
439 abi_ulong info_addr
, uc_addr
;
441 trace_user_setup_rt_frame(env
, frame_addr
);
442 if (!lock_user_struct(VERIFY_WRITE
, frame
, frame_addr
, 0)) {
446 info_addr
= frame_addr
+ offsetof(struct rt_sigframe_v1
, info
);
447 __put_user(info_addr
, &frame
->pinfo
);
448 uc_addr
= frame_addr
+ offsetof(struct rt_sigframe_v1
, uc
);
449 __put_user(uc_addr
, &frame
->puc
);
450 tswap_siginfo(&frame
->info
, info
);
452 /* Clear all the bits of the ucontext we don't use. */
453 memset(&frame
->uc
, 0, offsetof(struct target_ucontext_v1
, tuc_mcontext
));
455 memset(&stack
, 0, sizeof(stack
));
456 target_save_altstack(&stack
, env
);
457 memcpy(&frame
->uc
.tuc_stack
, &stack
, sizeof(stack
));
459 setup_sigcontext(&frame
->uc
.tuc_mcontext
, env
, set
->sig
[0]);
460 for(i
= 0; i
< TARGET_NSIG_WORDS
; i
++) {
461 __put_user(set
->sig
[i
], &frame
->uc
.tuc_sigmask
.sig
[i
]);
464 if (setup_return(env
, ka
, frame
->retcode
, frame_addr
, usig
,
465 frame_addr
+ offsetof(struct rt_sigframe_v1
, retcode
))) {
469 env
->regs
[1] = info_addr
;
470 env
->regs
[2] = uc_addr
;
472 unlock_user_struct(frame
, frame_addr
, 1);
475 unlock_user_struct(frame
, frame_addr
, 1);
479 static void setup_rt_frame_v2(int usig
, struct target_sigaction
*ka
,
480 target_siginfo_t
*info
,
481 target_sigset_t
*set
, CPUARMState
*env
)
483 struct rt_sigframe_v2
*frame
;
484 abi_ulong frame_addr
= get_sigframe(ka
, env
, sizeof(*frame
));
485 abi_ulong info_addr
, uc_addr
;
487 trace_user_setup_rt_frame(env
, frame_addr
);
488 if (!lock_user_struct(VERIFY_WRITE
, frame
, frame_addr
, 0)) {
492 info_addr
= frame_addr
+ offsetof(struct rt_sigframe_v2
, info
);
493 uc_addr
= frame_addr
+ offsetof(struct rt_sigframe_v2
, uc
);
494 tswap_siginfo(&frame
->info
, info
);
496 setup_sigframe_v2(&frame
->uc
, set
, env
);
498 if (setup_return(env
, ka
, frame
->retcode
, frame_addr
, usig
,
499 frame_addr
+ offsetof(struct rt_sigframe_v2
, retcode
))) {
503 env
->regs
[1] = info_addr
;
504 env
->regs
[2] = uc_addr
;
506 unlock_user_struct(frame
, frame_addr
, 1);
509 unlock_user_struct(frame
, frame_addr
, 1);
513 void setup_rt_frame(int usig
, struct target_sigaction
*ka
,
514 target_siginfo_t
*info
,
515 target_sigset_t
*set
, CPUARMState
*env
)
517 if (get_osversion() >= 0x020612) {
518 setup_rt_frame_v2(usig
, ka
, info
, set
, env
);
520 setup_rt_frame_v1(usig
, ka
, info
, set
, env
);
525 restore_sigcontext(CPUARMState
*env
, struct target_sigcontext
*sc
)
530 __get_user(env
->regs
[0], &sc
->arm_r0
);
531 __get_user(env
->regs
[1], &sc
->arm_r1
);
532 __get_user(env
->regs
[2], &sc
->arm_r2
);
533 __get_user(env
->regs
[3], &sc
->arm_r3
);
534 __get_user(env
->regs
[4], &sc
->arm_r4
);
535 __get_user(env
->regs
[5], &sc
->arm_r5
);
536 __get_user(env
->regs
[6], &sc
->arm_r6
);
537 __get_user(env
->regs
[7], &sc
->arm_r7
);
538 __get_user(env
->regs
[8], &sc
->arm_r8
);
539 __get_user(env
->regs
[9], &sc
->arm_r9
);
540 __get_user(env
->regs
[10], &sc
->arm_r10
);
541 __get_user(env
->regs
[11], &sc
->arm_fp
);
542 __get_user(env
->regs
[12], &sc
->arm_ip
);
543 __get_user(env
->regs
[13], &sc
->arm_sp
);
544 __get_user(env
->regs
[14], &sc
->arm_lr
);
545 __get_user(env
->regs
[15], &sc
->arm_pc
);
546 #ifdef TARGET_CONFIG_CPU_32
547 __get_user(cpsr
, &sc
->arm_cpsr
);
548 cpsr_write(env
, cpsr
, CPSR_USER
| CPSR_EXEC
, CPSRWriteByInstr
);
551 err
|= !valid_user_regs(env
);
556 static long do_sigreturn_v1(CPUARMState
*env
)
558 abi_ulong frame_addr
;
559 struct sigframe_v1
*frame
= NULL
;
565 * Since we stacked the signal on a 64-bit boundary,
566 * then 'sp' should be word aligned here. If it's
567 * not, then the user is trying to mess with us.
569 frame_addr
= env
->regs
[13];
570 trace_user_do_sigreturn(env
, frame_addr
);
571 if (frame_addr
& 7) {
575 if (!lock_user_struct(VERIFY_READ
, frame
, frame_addr
, 1)) {
579 __get_user(set
.sig
[0], &frame
->sc
.oldmask
);
580 for(i
= 1; i
< TARGET_NSIG_WORDS
; i
++) {
581 __get_user(set
.sig
[i
], &frame
->extramask
[i
- 1]);
584 target_to_host_sigset_internal(&host_set
, &set
);
585 set_sigmask(&host_set
);
587 if (restore_sigcontext(env
, &frame
->sc
)) {
592 /* Send SIGTRAP if we're single-stepping */
593 if (ptrace_cancel_bpt(current
))
594 send_sig(SIGTRAP
, current
, 1);
596 unlock_user_struct(frame
, frame_addr
, 0);
597 return -TARGET_QEMU_ESIGRETURN
;
600 force_sig(TARGET_SIGSEGV
);
601 return -TARGET_QEMU_ESIGRETURN
;
604 static abi_ulong
*restore_sigframe_v2_vfp(CPUARMState
*env
, abi_ulong
*regspace
)
608 uint32_t fpscr
, fpexc
;
609 struct target_vfp_sigframe
*vfpframe
;
610 vfpframe
= (struct target_vfp_sigframe
*)regspace
;
612 __get_user(magic
, &vfpframe
->magic
);
613 __get_user(sz
, &vfpframe
->size
);
614 if (magic
!= TARGET_VFP_MAGIC
|| sz
!= sizeof(*vfpframe
)) {
617 for (i
= 0; i
< 32; i
++) {
618 __get_user(*aa32_vfp_dreg(env
, i
), &vfpframe
->ufp
.fpregs
[i
]);
620 __get_user(fpscr
, &vfpframe
->ufp
.fpscr
);
621 vfp_set_fpscr(env
, fpscr
);
622 __get_user(fpexc
, &vfpframe
->ufp_exc
.fpexc
);
623 /* Sanitise FPEXC: ensure VFP is enabled, FPINST2 is invalid
624 * and the exception flag is cleared
627 fpexc
&= ~((1 << 31) | (1 << 28));
628 env
->vfp
.xregs
[ARM_VFP_FPEXC
] = fpexc
;
629 __get_user(env
->vfp
.xregs
[ARM_VFP_FPINST
], &vfpframe
->ufp_exc
.fpinst
);
630 __get_user(env
->vfp
.xregs
[ARM_VFP_FPINST2
], &vfpframe
->ufp_exc
.fpinst2
);
631 return (abi_ulong
*)(vfpframe
+ 1);
634 static abi_ulong
*restore_sigframe_v2_iwmmxt(CPUARMState
*env
,
639 struct target_iwmmxt_sigframe
*iwmmxtframe
;
640 iwmmxtframe
= (struct target_iwmmxt_sigframe
*)regspace
;
642 __get_user(magic
, &iwmmxtframe
->magic
);
643 __get_user(sz
, &iwmmxtframe
->size
);
644 if (magic
!= TARGET_IWMMXT_MAGIC
|| sz
!= sizeof(*iwmmxtframe
)) {
647 for (i
= 0; i
< 16; i
++) {
648 __get_user(env
->iwmmxt
.regs
[i
], &iwmmxtframe
->regs
[i
]);
650 __get_user(env
->vfp
.xregs
[ARM_IWMMXT_wCSSF
], &iwmmxtframe
->wcssf
);
651 __get_user(env
->vfp
.xregs
[ARM_IWMMXT_wCASF
], &iwmmxtframe
->wcssf
);
652 __get_user(env
->vfp
.xregs
[ARM_IWMMXT_wCGR0
], &iwmmxtframe
->wcgr0
);
653 __get_user(env
->vfp
.xregs
[ARM_IWMMXT_wCGR1
], &iwmmxtframe
->wcgr1
);
654 __get_user(env
->vfp
.xregs
[ARM_IWMMXT_wCGR2
], &iwmmxtframe
->wcgr2
);
655 __get_user(env
->vfp
.xregs
[ARM_IWMMXT_wCGR3
], &iwmmxtframe
->wcgr3
);
656 return (abi_ulong
*)(iwmmxtframe
+ 1);
659 static int do_sigframe_return_v2(CPUARMState
*env
,
660 target_ulong context_addr
,
661 struct target_ucontext_v2
*uc
)
666 target_to_host_sigset(&host_set
, &uc
->tuc_sigmask
);
667 set_sigmask(&host_set
);
669 if (restore_sigcontext(env
, &uc
->tuc_mcontext
))
672 /* Restore coprocessor signal frame */
673 regspace
= uc
->tuc_regspace
;
674 if (arm_feature(env
, ARM_FEATURE_VFP
)) {
675 regspace
= restore_sigframe_v2_vfp(env
, regspace
);
680 if (arm_feature(env
, ARM_FEATURE_IWMMXT
)) {
681 regspace
= restore_sigframe_v2_iwmmxt(env
, regspace
);
687 if (do_sigaltstack(context_addr
688 + offsetof(struct target_ucontext_v2
, tuc_stack
),
689 0, get_sp_from_cpustate(env
)) == -EFAULT
) {
694 /* Send SIGTRAP if we're single-stepping */
695 if (ptrace_cancel_bpt(current
))
696 send_sig(SIGTRAP
, current
, 1);
702 static long do_sigreturn_v2(CPUARMState
*env
)
704 abi_ulong frame_addr
;
705 struct sigframe_v2
*frame
= NULL
;
708 * Since we stacked the signal on a 64-bit boundary,
709 * then 'sp' should be word aligned here. If it's
710 * not, then the user is trying to mess with us.
712 frame_addr
= env
->regs
[13];
713 trace_user_do_sigreturn(env
, frame_addr
);
714 if (frame_addr
& 7) {
718 if (!lock_user_struct(VERIFY_READ
, frame
, frame_addr
, 1)) {
722 if (do_sigframe_return_v2(env
,
724 + offsetof(struct sigframe_v2
, uc
),
729 unlock_user_struct(frame
, frame_addr
, 0);
730 return -TARGET_QEMU_ESIGRETURN
;
733 unlock_user_struct(frame
, frame_addr
, 0);
734 force_sig(TARGET_SIGSEGV
);
735 return -TARGET_QEMU_ESIGRETURN
;
738 long do_sigreturn(CPUARMState
*env
)
740 if (get_osversion() >= 0x020612) {
741 return do_sigreturn_v2(env
);
743 return do_sigreturn_v1(env
);
747 static long do_rt_sigreturn_v1(CPUARMState
*env
)
749 abi_ulong frame_addr
;
750 struct rt_sigframe_v1
*frame
= NULL
;
754 * Since we stacked the signal on a 64-bit boundary,
755 * then 'sp' should be word aligned here. If it's
756 * not, then the user is trying to mess with us.
758 frame_addr
= env
->regs
[13];
759 trace_user_do_rt_sigreturn(env
, frame_addr
);
760 if (frame_addr
& 7) {
764 if (!lock_user_struct(VERIFY_READ
, frame
, frame_addr
, 1)) {
768 target_to_host_sigset(&host_set
, &frame
->uc
.tuc_sigmask
);
769 set_sigmask(&host_set
);
771 if (restore_sigcontext(env
, &frame
->uc
.tuc_mcontext
)) {
775 if (do_sigaltstack(frame_addr
+ offsetof(struct rt_sigframe_v1
, uc
.tuc_stack
), 0, get_sp_from_cpustate(env
)) == -EFAULT
)
779 /* Send SIGTRAP if we're single-stepping */
780 if (ptrace_cancel_bpt(current
))
781 send_sig(SIGTRAP
, current
, 1);
783 unlock_user_struct(frame
, frame_addr
, 0);
784 return -TARGET_QEMU_ESIGRETURN
;
787 unlock_user_struct(frame
, frame_addr
, 0);
788 force_sig(TARGET_SIGSEGV
);
789 return -TARGET_QEMU_ESIGRETURN
;
792 static long do_rt_sigreturn_v2(CPUARMState
*env
)
794 abi_ulong frame_addr
;
795 struct rt_sigframe_v2
*frame
= NULL
;
798 * Since we stacked the signal on a 64-bit boundary,
799 * then 'sp' should be word aligned here. If it's
800 * not, then the user is trying to mess with us.
802 frame_addr
= env
->regs
[13];
803 trace_user_do_rt_sigreturn(env
, frame_addr
);
804 if (frame_addr
& 7) {
808 if (!lock_user_struct(VERIFY_READ
, frame
, frame_addr
, 1)) {
812 if (do_sigframe_return_v2(env
,
814 + offsetof(struct rt_sigframe_v2
, uc
),
819 unlock_user_struct(frame
, frame_addr
, 0);
820 return -TARGET_QEMU_ESIGRETURN
;
823 unlock_user_struct(frame
, frame_addr
, 0);
824 force_sig(TARGET_SIGSEGV
);
825 return -TARGET_QEMU_ESIGRETURN
;
828 long do_rt_sigreturn(CPUARMState
*env
)
830 if (get_osversion() >= 0x020612) {
831 return do_rt_sigreturn_v2(env
);
833 return do_rt_sigreturn_v1(env
);