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, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
29 #include <sys/ucontext.h>
32 #include "qemu-common.h"
33 #include "target_signal.h"
35 //#define DEBUG_SIGNAL
37 static struct target_sigaltstack target_sigaltstack_used
= {
40 .ss_flags
= TARGET_SS_DISABLE
,
43 static struct target_sigaction sigact_table
[TARGET_NSIG
];
45 static void host_signal_handler(int host_signum
, siginfo_t
*info
,
48 static uint8_t host_to_target_signal_table
[65] = {
49 [SIGHUP
] = TARGET_SIGHUP
,
50 [SIGINT
] = TARGET_SIGINT
,
51 [SIGQUIT
] = TARGET_SIGQUIT
,
52 [SIGILL
] = TARGET_SIGILL
,
53 [SIGTRAP
] = TARGET_SIGTRAP
,
54 [SIGABRT
] = TARGET_SIGABRT
,
55 /* [SIGIOT] = TARGET_SIGIOT,*/
56 [SIGBUS
] = TARGET_SIGBUS
,
57 [SIGFPE
] = TARGET_SIGFPE
,
58 [SIGKILL
] = TARGET_SIGKILL
,
59 [SIGUSR1
] = TARGET_SIGUSR1
,
60 [SIGSEGV
] = TARGET_SIGSEGV
,
61 [SIGUSR2
] = TARGET_SIGUSR2
,
62 [SIGPIPE
] = TARGET_SIGPIPE
,
63 [SIGALRM
] = TARGET_SIGALRM
,
64 [SIGTERM
] = TARGET_SIGTERM
,
66 [SIGSTKFLT
] = TARGET_SIGSTKFLT
,
68 [SIGCHLD
] = TARGET_SIGCHLD
,
69 [SIGCONT
] = TARGET_SIGCONT
,
70 [SIGSTOP
] = TARGET_SIGSTOP
,
71 [SIGTSTP
] = TARGET_SIGTSTP
,
72 [SIGTTIN
] = TARGET_SIGTTIN
,
73 [SIGTTOU
] = TARGET_SIGTTOU
,
74 [SIGURG
] = TARGET_SIGURG
,
75 [SIGXCPU
] = TARGET_SIGXCPU
,
76 [SIGXFSZ
] = TARGET_SIGXFSZ
,
77 [SIGVTALRM
] = TARGET_SIGVTALRM
,
78 [SIGPROF
] = TARGET_SIGPROF
,
79 [SIGWINCH
] = TARGET_SIGWINCH
,
80 [SIGIO
] = TARGET_SIGIO
,
81 [SIGPWR
] = TARGET_SIGPWR
,
82 [SIGSYS
] = TARGET_SIGSYS
,
83 /* next signals stay the same */
84 /* Nasty hack: Reverse SIGRTMIN and SIGRTMAX to avoid overlap with
85 host libpthread signals. This assumes noone actually uses SIGRTMAX :-/
86 To fix this properly we need to do manual signal delivery multiplexed
87 over a single host signal. */
88 [__SIGRTMIN
] = __SIGRTMAX
,
89 [__SIGRTMAX
] = __SIGRTMIN
,
91 static uint8_t target_to_host_signal_table
[65];
93 static inline int on_sig_stack(unsigned long sp
)
95 return (sp
- target_sigaltstack_used
.ss_sp
96 < target_sigaltstack_used
.ss_size
);
99 static inline int sas_ss_flags(unsigned long sp
)
101 return (target_sigaltstack_used
.ss_size
== 0 ? SS_DISABLE
102 : on_sig_stack(sp
) ? SS_ONSTACK
: 0);
105 int host_to_target_signal(int sig
)
109 return host_to_target_signal_table
[sig
];
112 int target_to_host_signal(int sig
)
116 return target_to_host_signal_table
[sig
];
119 static inline void target_sigemptyset(target_sigset_t
*set
)
121 memset(set
, 0, sizeof(*set
));
124 static inline void target_sigaddset(target_sigset_t
*set
, int signum
)
127 abi_ulong mask
= (abi_ulong
)1 << (signum
% TARGET_NSIG_BPW
);
128 set
->sig
[signum
/ TARGET_NSIG_BPW
] |= mask
;
131 static inline int target_sigismember(const target_sigset_t
*set
, int signum
)
134 abi_ulong mask
= (abi_ulong
)1 << (signum
% TARGET_NSIG_BPW
);
135 return ((set
->sig
[signum
/ TARGET_NSIG_BPW
] & mask
) != 0);
138 static void host_to_target_sigset_internal(target_sigset_t
*d
,
142 target_sigemptyset(d
);
143 for (i
= 1; i
<= TARGET_NSIG
; i
++) {
144 if (sigismember(s
, i
)) {
145 target_sigaddset(d
, host_to_target_signal(i
));
150 void host_to_target_sigset(target_sigset_t
*d
, const sigset_t
*s
)
155 host_to_target_sigset_internal(&d1
, s
);
156 for(i
= 0;i
< TARGET_NSIG_WORDS
; i
++)
157 d
->sig
[i
] = tswapl(d1
.sig
[i
]);
160 static void target_to_host_sigset_internal(sigset_t
*d
,
161 const target_sigset_t
*s
)
165 for (i
= 1; i
<= TARGET_NSIG
; i
++) {
166 if (target_sigismember(s
, i
)) {
167 sigaddset(d
, target_to_host_signal(i
));
172 void target_to_host_sigset(sigset_t
*d
, const target_sigset_t
*s
)
177 for(i
= 0;i
< TARGET_NSIG_WORDS
; i
++)
178 s1
.sig
[i
] = tswapl(s
->sig
[i
]);
179 target_to_host_sigset_internal(d
, &s1
);
182 void host_to_target_old_sigset(abi_ulong
*old_sigset
,
183 const sigset_t
*sigset
)
186 host_to_target_sigset(&d
, sigset
);
187 *old_sigset
= d
.sig
[0];
190 void target_to_host_old_sigset(sigset_t
*sigset
,
191 const abi_ulong
*old_sigset
)
196 d
.sig
[0] = *old_sigset
;
197 for(i
= 1;i
< TARGET_NSIG_WORDS
; i
++)
199 target_to_host_sigset(sigset
, &d
);
202 /* siginfo conversion */
204 static inline void host_to_target_siginfo_noswap(target_siginfo_t
*tinfo
,
205 const siginfo_t
*info
)
208 sig
= host_to_target_signal(info
->si_signo
);
209 tinfo
->si_signo
= sig
;
211 tinfo
->si_code
= info
->si_code
;
212 if (sig
== SIGILL
|| sig
== SIGFPE
|| sig
== SIGSEGV
||
213 sig
== SIGBUS
|| sig
== SIGTRAP
) {
214 /* should never come here, but who knows. The information for
215 the target is irrelevant */
216 tinfo
->_sifields
._sigfault
._addr
= 0;
217 } else if (sig
== SIGIO
) {
218 tinfo
->_sifields
._sigpoll
._fd
= info
->si_fd
;
219 } else if (sig
>= TARGET_SIGRTMIN
) {
220 tinfo
->_sifields
._rt
._pid
= info
->si_pid
;
221 tinfo
->_sifields
._rt
._uid
= info
->si_uid
;
222 /* XXX: potential problem if 64 bit */
223 tinfo
->_sifields
._rt
._sigval
.sival_ptr
=
224 (abi_ulong
)(unsigned long)info
->si_value
.sival_ptr
;
228 static void tswap_siginfo(target_siginfo_t
*tinfo
,
229 const target_siginfo_t
*info
)
232 sig
= info
->si_signo
;
233 tinfo
->si_signo
= tswap32(sig
);
234 tinfo
->si_errno
= tswap32(info
->si_errno
);
235 tinfo
->si_code
= tswap32(info
->si_code
);
236 if (sig
== SIGILL
|| sig
== SIGFPE
|| sig
== SIGSEGV
||
237 sig
== SIGBUS
|| sig
== SIGTRAP
) {
238 tinfo
->_sifields
._sigfault
._addr
=
239 tswapl(info
->_sifields
._sigfault
._addr
);
240 } else if (sig
== SIGIO
) {
241 tinfo
->_sifields
._sigpoll
._fd
= tswap32(info
->_sifields
._sigpoll
._fd
);
242 } else if (sig
>= TARGET_SIGRTMIN
) {
243 tinfo
->_sifields
._rt
._pid
= tswap32(info
->_sifields
._rt
._pid
);
244 tinfo
->_sifields
._rt
._uid
= tswap32(info
->_sifields
._rt
._uid
);
245 tinfo
->_sifields
._rt
._sigval
.sival_ptr
=
246 tswapl(info
->_sifields
._rt
._sigval
.sival_ptr
);
251 void host_to_target_siginfo(target_siginfo_t
*tinfo
, const siginfo_t
*info
)
253 host_to_target_siginfo_noswap(tinfo
, info
);
254 tswap_siginfo(tinfo
, tinfo
);
257 /* XXX: we support only POSIX RT signals are used. */
258 /* XXX: find a solution for 64 bit (additional malloced data is needed) */
259 void target_to_host_siginfo(siginfo_t
*info
, const target_siginfo_t
*tinfo
)
261 info
->si_signo
= tswap32(tinfo
->si_signo
);
262 info
->si_errno
= tswap32(tinfo
->si_errno
);
263 info
->si_code
= tswap32(tinfo
->si_code
);
264 info
->si_pid
= tswap32(tinfo
->_sifields
._rt
._pid
);
265 info
->si_uid
= tswap32(tinfo
->_sifields
._rt
._uid
);
266 info
->si_value
.sival_ptr
=
267 (void *)(long)tswapl(tinfo
->_sifields
._rt
._sigval
.sival_ptr
);
270 static int fatal_signal (int sig
)
275 case TARGET_SIGWINCH
:
276 /* Ignored by default. */
283 /* Job control signals. */
290 void signal_init(void)
292 struct sigaction act
;
293 struct sigaction oact
;
297 /* generate signal conversion tables */
298 for(i
= 1; i
<= 64; i
++) {
299 if (host_to_target_signal_table
[i
] == 0)
300 host_to_target_signal_table
[i
] = i
;
302 for(i
= 1; i
<= 64; i
++) {
303 j
= host_to_target_signal_table
[i
];
304 target_to_host_signal_table
[j
] = i
;
307 /* set all host signal handlers. ALL signals are blocked during
308 the handlers to serialize them. */
309 memset(sigact_table
, 0, sizeof(sigact_table
));
311 sigfillset(&act
.sa_mask
);
312 act
.sa_flags
= SA_SIGINFO
;
313 act
.sa_sigaction
= host_signal_handler
;
314 for(i
= 1; i
<= TARGET_NSIG
; i
++) {
315 host_sig
= target_to_host_signal(i
);
316 sigaction(host_sig
, NULL
, &oact
);
317 if (oact
.sa_sigaction
== (void *)SIG_IGN
) {
318 sigact_table
[i
- 1]._sa_handler
= TARGET_SIG_IGN
;
319 } else if (oact
.sa_sigaction
== (void *)SIG_DFL
) {
320 sigact_table
[i
- 1]._sa_handler
= TARGET_SIG_DFL
;
322 /* If there's already a handler installed then something has
323 gone horribly wrong, so don't even try to handle that case. */
324 /* Install some handlers for our own use. We need at least
325 SIGSEGV and SIGBUS, to detect exceptions. We can not just
326 trap all signals because it affects syscall interrupt
327 behavior. But do trap all default-fatal signals. */
328 if (fatal_signal (i
))
329 sigaction(host_sig
, &act
, NULL
);
333 /* signal queue handling */
335 static inline struct sigqueue
*alloc_sigqueue(CPUState
*env
)
337 TaskState
*ts
= env
->opaque
;
338 struct sigqueue
*q
= ts
->first_free
;
341 ts
->first_free
= q
->next
;
345 static inline void free_sigqueue(CPUState
*env
, struct sigqueue
*q
)
347 TaskState
*ts
= env
->opaque
;
348 q
->next
= ts
->first_free
;
352 /* abort execution with signal */
353 static void QEMU_NORETURN
force_sig(int sig
)
356 struct sigaction act
;
357 host_sig
= target_to_host_signal(sig
);
358 fprintf(stderr
, "qemu: uncaught target signal %d (%s) - exiting\n",
359 sig
, strsignal(host_sig
));
360 gdb_signalled(thread_env
, sig
);
362 /* The proper exit code for dieing from an uncaught signal is
363 * -<signal>. The kernel doesn't allow exit() or _exit() to pass
364 * a negative value. To get the proper exit code we need to
365 * actually die from an uncaught signal. Here the default signal
366 * handler is installed, we send ourself a signal and we wait for
368 sigfillset(&act
.sa_mask
);
369 act
.sa_handler
= SIG_DFL
;
370 sigaction(host_sig
, &act
, NULL
);
372 /* For some reason raise(host_sig) doesn't send the signal when
373 * statically linked on x86-64. */
374 kill(getpid(), host_sig
);
376 /* Make sure the signal isn't masked (just reuse the mask inside
378 sigdelset(&act
.sa_mask
, host_sig
);
379 sigsuspend(&act
.sa_mask
);
386 /* queue a signal so that it will be send to the virtual CPU as soon
388 int queue_signal(CPUState
*env
, int sig
, target_siginfo_t
*info
)
390 TaskState
*ts
= env
->opaque
;
391 struct emulated_sigtable
*k
;
392 struct sigqueue
*q
, **pq
;
396 #if defined(DEBUG_SIGNAL)
397 fprintf(stderr
, "queue_signal: sig=%d\n",
400 k
= &ts
->sigtab
[sig
- 1];
401 queue
= gdb_queuesig ();
402 handler
= sigact_table
[sig
- 1]._sa_handler
;
403 if (!queue
&& handler
== TARGET_SIG_DFL
) {
404 if (sig
== TARGET_SIGTSTP
|| sig
== TARGET_SIGTTIN
|| sig
== TARGET_SIGTTOU
) {
405 kill(getpid(),SIGSTOP
);
408 /* default handler : ignore some signal. The other are fatal */
409 if (sig
!= TARGET_SIGCHLD
&&
410 sig
!= TARGET_SIGURG
&&
411 sig
!= TARGET_SIGWINCH
&&
412 sig
!= TARGET_SIGCONT
) {
415 return 0; /* indicate ignored */
417 } else if (!queue
&& handler
== TARGET_SIG_IGN
) {
420 } else if (!queue
&& handler
== TARGET_SIG_ERR
) {
424 if (sig
< TARGET_SIGRTMIN
) {
425 /* if non real time signal, we queue exactly one signal */
435 q
= alloc_sigqueue(env
);
446 /* signal that a new signal is pending */
447 ts
->signal_pending
= 1;
448 return 1; /* indicates that the signal was queued */
452 static void host_signal_handler(int host_signum
, siginfo_t
*info
,
456 target_siginfo_t tinfo
;
458 /* the CPU emulator uses some host signals to detect exceptions,
459 we forward to it some signals */
460 if ((host_signum
== SIGSEGV
|| host_signum
== SIGBUS
)
461 && info
->si_code
> 0) {
462 if (cpu_signal_handler(host_signum
, info
, puc
))
466 /* get target signal number */
467 sig
= host_to_target_signal(host_signum
);
468 if (sig
< 1 || sig
> TARGET_NSIG
)
470 #if defined(DEBUG_SIGNAL)
471 fprintf(stderr
, "qemu: got signal %d\n", sig
);
473 host_to_target_siginfo_noswap(&tinfo
, info
);
474 if (queue_signal(thread_env
, sig
, &tinfo
) == 1) {
475 /* interrupt the virtual CPU as soon as possible */
476 cpu_exit(thread_env
);
480 /* do_sigaltstack() returns target values and errnos. */
481 /* compare linux/kernel/signal.c:do_sigaltstack() */
482 abi_long
do_sigaltstack(abi_ulong uss_addr
, abi_ulong uoss_addr
, abi_ulong sp
)
485 struct target_sigaltstack oss
;
487 /* XXX: test errors */
490 __put_user(target_sigaltstack_used
.ss_sp
, &oss
.ss_sp
);
491 __put_user(target_sigaltstack_used
.ss_size
, &oss
.ss_size
);
492 __put_user(sas_ss_flags(sp
), &oss
.ss_flags
);
497 struct target_sigaltstack
*uss
;
498 struct target_sigaltstack ss
;
500 ret
= -TARGET_EFAULT
;
501 if (!lock_user_struct(VERIFY_READ
, uss
, uss_addr
, 1)
502 || __get_user(ss
.ss_sp
, &uss
->ss_sp
)
503 || __get_user(ss
.ss_size
, &uss
->ss_size
)
504 || __get_user(ss
.ss_flags
, &uss
->ss_flags
))
506 unlock_user_struct(uss
, uss_addr
, 0);
509 if (on_sig_stack(sp
))
512 ret
= -TARGET_EINVAL
;
513 if (ss
.ss_flags
!= TARGET_SS_DISABLE
514 && ss
.ss_flags
!= TARGET_SS_ONSTACK
518 if (ss
.ss_flags
== TARGET_SS_DISABLE
) {
522 ret
= -TARGET_ENOMEM
;
523 if (ss
.ss_size
< MINSIGSTKSZ
)
527 target_sigaltstack_used
.ss_sp
= ss
.ss_sp
;
528 target_sigaltstack_used
.ss_size
= ss
.ss_size
;
532 ret
= -TARGET_EFAULT
;
533 if (copy_to_user(uoss_addr
, &oss
, sizeof(oss
)))
542 /* do_sigaction() return host values and errnos */
543 int do_sigaction(int sig
, const struct target_sigaction
*act
,
544 struct target_sigaction
*oact
)
546 struct target_sigaction
*k
;
547 struct sigaction act1
;
551 if (sig
< 1 || sig
> TARGET_NSIG
|| sig
== TARGET_SIGKILL
|| sig
== TARGET_SIGSTOP
)
553 k
= &sigact_table
[sig
- 1];
554 #if defined(DEBUG_SIGNAL)
555 fprintf(stderr
, "sigaction sig=%d act=0x%08x, oact=0x%08x\n",
556 sig
, (int)act
, (int)oact
);
559 oact
->_sa_handler
= tswapl(k
->_sa_handler
);
560 oact
->sa_flags
= tswapl(k
->sa_flags
);
561 #if !defined(TARGET_MIPS)
562 oact
->sa_restorer
= tswapl(k
->sa_restorer
);
564 oact
->sa_mask
= k
->sa_mask
;
567 /* FIXME: This is not threadsafe. */
568 k
->_sa_handler
= tswapl(act
->_sa_handler
);
569 k
->sa_flags
= tswapl(act
->sa_flags
);
570 #if !defined(TARGET_MIPS)
571 k
->sa_restorer
= tswapl(act
->sa_restorer
);
573 k
->sa_mask
= act
->sa_mask
;
575 /* we update the host linux signal state */
576 host_sig
= target_to_host_signal(sig
);
577 if (host_sig
!= SIGSEGV
&& host_sig
!= SIGBUS
) {
578 sigfillset(&act1
.sa_mask
);
579 act1
.sa_flags
= SA_SIGINFO
;
580 if (k
->sa_flags
& TARGET_SA_RESTART
)
581 act1
.sa_flags
|= SA_RESTART
;
582 /* NOTE: it is important to update the host kernel signal
583 ignore state to avoid getting unexpected interrupted
585 if (k
->_sa_handler
== TARGET_SIG_IGN
) {
586 act1
.sa_sigaction
= (void *)SIG_IGN
;
587 } else if (k
->_sa_handler
== TARGET_SIG_DFL
) {
588 if (fatal_signal (sig
))
589 act1
.sa_sigaction
= host_signal_handler
;
591 act1
.sa_sigaction
= (void *)SIG_DFL
;
593 act1
.sa_sigaction
= host_signal_handler
;
595 ret
= sigaction(host_sig
, &act1
, NULL
);
601 static inline int copy_siginfo_to_user(target_siginfo_t
*tinfo
,
602 const target_siginfo_t
*info
)
604 tswap_siginfo(tinfo
, info
);
608 static inline int current_exec_domain_sig(int sig
)
610 return /* current->exec_domain && current->exec_domain->signal_invmap
611 && sig < 32 ? current->exec_domain->signal_invmap[sig] : */ sig
;
614 #if defined(TARGET_I386) && TARGET_ABI_BITS == 32
616 /* from the Linux kernel */
618 struct target_fpreg
{
619 uint16_t significand
[4];
623 struct target_fpxreg
{
624 uint16_t significand
[4];
629 struct target_xmmreg
{
630 abi_ulong element
[4];
633 struct target_fpstate
{
634 /* Regular FPU environment */
642 struct target_fpreg _st
[8];
644 uint16_t magic
; /* 0xffff = regular FPU data only */
646 /* FXSR FPU environment */
647 abi_ulong _fxsr_env
[6]; /* FXSR FPU env is ignored */
650 struct target_fpxreg _fxsr_st
[8]; /* FXSR FPU reg data is ignored */
651 struct target_xmmreg _xmm
[8];
652 abi_ulong padding
[56];
655 #define X86_FXSR_MAGIC 0x0000
657 struct target_sigcontext
{
675 abi_ulong esp_at_signal
;
677 abi_ulong fpstate
; /* pointer */
682 struct target_ucontext
{
685 target_stack_t tuc_stack
;
686 struct target_sigcontext tuc_mcontext
;
687 target_sigset_t tuc_sigmask
; /* mask last for extensibility */
694 struct target_sigcontext sc
;
695 struct target_fpstate fpstate
;
696 abi_ulong extramask
[TARGET_NSIG_WORDS
-1];
706 struct target_siginfo info
;
707 struct target_ucontext uc
;
708 struct target_fpstate fpstate
;
713 * Set up a signal frame.
716 /* XXX: save x87 state */
718 setup_sigcontext(struct target_sigcontext
*sc
, struct target_fpstate
*fpstate
,
719 CPUX86State
*env
, abi_ulong mask
, abi_ulong fpstate_addr
)
724 /* already locked in setup_frame() */
725 err
|= __put_user(env
->segs
[R_GS
].selector
, (unsigned int *)&sc
->gs
);
726 err
|= __put_user(env
->segs
[R_FS
].selector
, (unsigned int *)&sc
->fs
);
727 err
|= __put_user(env
->segs
[R_ES
].selector
, (unsigned int *)&sc
->es
);
728 err
|= __put_user(env
->segs
[R_DS
].selector
, (unsigned int *)&sc
->ds
);
729 err
|= __put_user(env
->regs
[R_EDI
], &sc
->edi
);
730 err
|= __put_user(env
->regs
[R_ESI
], &sc
->esi
);
731 err
|= __put_user(env
->regs
[R_EBP
], &sc
->ebp
);
732 err
|= __put_user(env
->regs
[R_ESP
], &sc
->esp
);
733 err
|= __put_user(env
->regs
[R_EBX
], &sc
->ebx
);
734 err
|= __put_user(env
->regs
[R_EDX
], &sc
->edx
);
735 err
|= __put_user(env
->regs
[R_ECX
], &sc
->ecx
);
736 err
|= __put_user(env
->regs
[R_EAX
], &sc
->eax
);
737 err
|= __put_user(env
->exception_index
, &sc
->trapno
);
738 err
|= __put_user(env
->error_code
, &sc
->err
);
739 err
|= __put_user(env
->eip
, &sc
->eip
);
740 err
|= __put_user(env
->segs
[R_CS
].selector
, (unsigned int *)&sc
->cs
);
741 err
|= __put_user(env
->eflags
, &sc
->eflags
);
742 err
|= __put_user(env
->regs
[R_ESP
], &sc
->esp_at_signal
);
743 err
|= __put_user(env
->segs
[R_SS
].selector
, (unsigned int *)&sc
->ss
);
745 cpu_x86_fsave(env
, fpstate_addr
, 1);
746 fpstate
->status
= fpstate
->sw
;
748 err
|= __put_user(magic
, &fpstate
->magic
);
749 err
|= __put_user(fpstate_addr
, &sc
->fpstate
);
751 /* non-iBCS2 extensions.. */
752 err
|= __put_user(mask
, &sc
->oldmask
);
753 err
|= __put_user(env
->cr
[2], &sc
->cr2
);
758 * Determine which stack to use..
761 static inline abi_ulong
762 get_sigframe(struct target_sigaction
*ka
, CPUX86State
*env
, size_t frame_size
)
766 /* Default to using normal stack */
767 esp
= env
->regs
[R_ESP
];
768 /* This is the X/Open sanctioned signal stack switching. */
769 if (ka
->sa_flags
& TARGET_SA_ONSTACK
) {
770 if (sas_ss_flags(esp
) == 0)
771 esp
= target_sigaltstack_used
.ss_sp
+ target_sigaltstack_used
.ss_size
;
774 /* This is the legacy signal stack switching. */
776 if ((env
->segs
[R_SS
].selector
& 0xffff) != __USER_DS
&&
777 !(ka
->sa_flags
& TARGET_SA_RESTORER
) &&
779 esp
= (unsigned long) ka
->sa_restorer
;
781 return (esp
- frame_size
) & -8ul;
784 /* compare linux/arch/i386/kernel/signal.c:setup_frame() */
785 static void setup_frame(int sig
, struct target_sigaction
*ka
,
786 target_sigset_t
*set
, CPUX86State
*env
)
788 abi_ulong frame_addr
;
789 struct sigframe
*frame
;
792 frame_addr
= get_sigframe(ka
, env
, sizeof(*frame
));
794 if (!lock_user_struct(VERIFY_WRITE
, frame
, frame_addr
, 0))
797 err
|= __put_user(current_exec_domain_sig(sig
),
802 setup_sigcontext(&frame
->sc
, &frame
->fpstate
, env
, set
->sig
[0],
803 frame_addr
+ offsetof(struct sigframe
, fpstate
));
807 for(i
= 1; i
< TARGET_NSIG_WORDS
; i
++) {
808 if (__put_user(set
->sig
[i
], &frame
->extramask
[i
- 1]))
812 /* Set up to return from userspace. If provided, use a stub
813 already in userspace. */
814 if (ka
->sa_flags
& TARGET_SA_RESTORER
) {
815 err
|= __put_user(ka
->sa_restorer
, &frame
->pretcode
);
818 abi_ulong retcode_addr
;
819 retcode_addr
= frame_addr
+ offsetof(struct sigframe
, retcode
);
820 err
|= __put_user(retcode_addr
, &frame
->pretcode
);
821 /* This is popl %eax ; movl $,%eax ; int $0x80 */
823 err
|= __put_user(val16
, (uint16_t *)(frame
->retcode
+0));
824 err
|= __put_user(TARGET_NR_sigreturn
, (int *)(frame
->retcode
+2));
826 err
|= __put_user(val16
, (uint16_t *)(frame
->retcode
+6));
832 /* Set up registers for signal handler */
833 env
->regs
[R_ESP
] = frame_addr
;
834 env
->eip
= ka
->_sa_handler
;
836 cpu_x86_load_seg(env
, R_DS
, __USER_DS
);
837 cpu_x86_load_seg(env
, R_ES
, __USER_DS
);
838 cpu_x86_load_seg(env
, R_SS
, __USER_DS
);
839 cpu_x86_load_seg(env
, R_CS
, __USER_CS
);
840 env
->eflags
&= ~TF_MASK
;
842 unlock_user_struct(frame
, frame_addr
, 1);
847 unlock_user_struct(frame
, frame_addr
, 1);
848 if (sig
== TARGET_SIGSEGV
)
849 ka
->_sa_handler
= TARGET_SIG_DFL
;
850 force_sig(TARGET_SIGSEGV
/* , current */);
853 /* compare linux/arch/i386/kernel/signal.c:setup_rt_frame() */
854 static void setup_rt_frame(int sig
, struct target_sigaction
*ka
,
855 target_siginfo_t
*info
,
856 target_sigset_t
*set
, CPUX86State
*env
)
858 abi_ulong frame_addr
, addr
;
859 struct rt_sigframe
*frame
;
862 frame_addr
= get_sigframe(ka
, env
, sizeof(*frame
));
864 if (!lock_user_struct(VERIFY_WRITE
, frame
, frame_addr
, 0))
867 err
|= __put_user(current_exec_domain_sig(sig
),
869 addr
= frame_addr
+ offsetof(struct rt_sigframe
, info
);
870 err
|= __put_user(addr
, &frame
->pinfo
);
871 addr
= frame_addr
+ offsetof(struct rt_sigframe
, uc
);
872 err
|= __put_user(addr
, &frame
->puc
);
873 err
|= copy_siginfo_to_user(&frame
->info
, info
);
877 /* Create the ucontext. */
878 err
|= __put_user(0, &frame
->uc
.tuc_flags
);
879 err
|= __put_user(0, &frame
->uc
.tuc_link
);
880 err
|= __put_user(target_sigaltstack_used
.ss_sp
,
881 &frame
->uc
.tuc_stack
.ss_sp
);
882 err
|= __put_user(sas_ss_flags(get_sp_from_cpustate(env
)),
883 &frame
->uc
.tuc_stack
.ss_flags
);
884 err
|= __put_user(target_sigaltstack_used
.ss_size
,
885 &frame
->uc
.tuc_stack
.ss_size
);
886 err
|= setup_sigcontext(&frame
->uc
.tuc_mcontext
, &frame
->fpstate
,
888 frame_addr
+ offsetof(struct rt_sigframe
, fpstate
));
889 for(i
= 0; i
< TARGET_NSIG_WORDS
; i
++) {
890 if (__put_user(set
->sig
[i
], &frame
->uc
.tuc_sigmask
.sig
[i
]))
894 /* Set up to return from userspace. If provided, use a stub
895 already in userspace. */
896 if (ka
->sa_flags
& TARGET_SA_RESTORER
) {
897 err
|= __put_user(ka
->sa_restorer
, &frame
->pretcode
);
900 addr
= frame_addr
+ offsetof(struct rt_sigframe
, retcode
);
901 err
|= __put_user(addr
, &frame
->pretcode
);
902 /* This is movl $,%eax ; int $0x80 */
903 err
|= __put_user(0xb8, (char *)(frame
->retcode
+0));
904 err
|= __put_user(TARGET_NR_rt_sigreturn
, (int *)(frame
->retcode
+1));
906 err
|= __put_user(val16
, (uint16_t *)(frame
->retcode
+5));
912 /* Set up registers for signal handler */
913 env
->regs
[R_ESP
] = frame_addr
;
914 env
->eip
= ka
->_sa_handler
;
916 cpu_x86_load_seg(env
, R_DS
, __USER_DS
);
917 cpu_x86_load_seg(env
, R_ES
, __USER_DS
);
918 cpu_x86_load_seg(env
, R_SS
, __USER_DS
);
919 cpu_x86_load_seg(env
, R_CS
, __USER_CS
);
920 env
->eflags
&= ~TF_MASK
;
922 unlock_user_struct(frame
, frame_addr
, 1);
927 unlock_user_struct(frame
, frame_addr
, 1);
928 if (sig
== TARGET_SIGSEGV
)
929 ka
->_sa_handler
= TARGET_SIG_DFL
;
930 force_sig(TARGET_SIGSEGV
/* , current */);
934 restore_sigcontext(CPUX86State
*env
, struct target_sigcontext
*sc
, int *peax
)
936 unsigned int err
= 0;
937 abi_ulong fpstate_addr
;
938 unsigned int tmpflags
;
940 cpu_x86_load_seg(env
, R_GS
, tswap16(sc
->gs
));
941 cpu_x86_load_seg(env
, R_FS
, tswap16(sc
->fs
));
942 cpu_x86_load_seg(env
, R_ES
, tswap16(sc
->es
));
943 cpu_x86_load_seg(env
, R_DS
, tswap16(sc
->ds
));
945 env
->regs
[R_EDI
] = tswapl(sc
->edi
);
946 env
->regs
[R_ESI
] = tswapl(sc
->esi
);
947 env
->regs
[R_EBP
] = tswapl(sc
->ebp
);
948 env
->regs
[R_ESP
] = tswapl(sc
->esp
);
949 env
->regs
[R_EBX
] = tswapl(sc
->ebx
);
950 env
->regs
[R_EDX
] = tswapl(sc
->edx
);
951 env
->regs
[R_ECX
] = tswapl(sc
->ecx
);
952 env
->eip
= tswapl(sc
->eip
);
954 cpu_x86_load_seg(env
, R_CS
, lduw(&sc
->cs
) | 3);
955 cpu_x86_load_seg(env
, R_SS
, lduw(&sc
->ss
) | 3);
957 tmpflags
= tswapl(sc
->eflags
);
958 env
->eflags
= (env
->eflags
& ~0x40DD5) | (tmpflags
& 0x40DD5);
959 // regs->orig_eax = -1; /* disable syscall checks */
961 fpstate_addr
= tswapl(sc
->fpstate
);
962 if (fpstate_addr
!= 0) {
963 if (!access_ok(VERIFY_READ
, fpstate_addr
,
964 sizeof(struct target_fpstate
)))
966 cpu_x86_frstor(env
, fpstate_addr
, 1);
969 *peax
= tswapl(sc
->eax
);
975 long do_sigreturn(CPUX86State
*env
)
977 struct sigframe
*frame
;
978 abi_ulong frame_addr
= env
->regs
[R_ESP
] - 8;
979 target_sigset_t target_set
;
983 #if defined(DEBUG_SIGNAL)
984 fprintf(stderr
, "do_sigreturn\n");
986 if (!lock_user_struct(VERIFY_READ
, frame
, frame_addr
, 1))
988 /* set blocked signals */
989 if (__get_user(target_set
.sig
[0], &frame
->sc
.oldmask
))
991 for(i
= 1; i
< TARGET_NSIG_WORDS
; i
++) {
992 if (__get_user(target_set
.sig
[i
], &frame
->extramask
[i
- 1]))
996 target_to_host_sigset_internal(&set
, &target_set
);
997 sigprocmask(SIG_SETMASK
, &set
, NULL
);
999 /* restore registers */
1000 if (restore_sigcontext(env
, &frame
->sc
, &eax
))
1002 unlock_user_struct(frame
, frame_addr
, 0);
1006 unlock_user_struct(frame
, frame_addr
, 0);
1007 force_sig(TARGET_SIGSEGV
);
1011 long do_rt_sigreturn(CPUX86State
*env
)
1013 abi_ulong frame_addr
;
1014 struct rt_sigframe
*frame
;
1018 frame_addr
= env
->regs
[R_ESP
] - 4;
1019 if (!lock_user_struct(VERIFY_READ
, frame
, frame_addr
, 1))
1021 target_to_host_sigset(&set
, &frame
->uc
.tuc_sigmask
);
1022 sigprocmask(SIG_SETMASK
, &set
, NULL
);
1024 if (restore_sigcontext(env
, &frame
->uc
.tuc_mcontext
, &eax
))
1027 if (do_sigaltstack(frame_addr
+ offsetof(struct rt_sigframe
, uc
.tuc_stack
), 0,
1028 get_sp_from_cpustate(env
)) == -EFAULT
)
1031 unlock_user_struct(frame
, frame_addr
, 0);
1035 unlock_user_struct(frame
, frame_addr
, 0);
1036 force_sig(TARGET_SIGSEGV
);
1040 #elif defined(TARGET_ARM)
1042 struct target_sigcontext
{
1044 abi_ulong error_code
;
1063 abi_ulong fault_address
;
1066 struct target_ucontext_v1
{
1067 abi_ulong tuc_flags
;
1069 target_stack_t tuc_stack
;
1070 struct target_sigcontext tuc_mcontext
;
1071 target_sigset_t tuc_sigmask
; /* mask last for extensibility */
1074 struct target_ucontext_v2
{
1075 abi_ulong tuc_flags
;
1077 target_stack_t tuc_stack
;
1078 struct target_sigcontext tuc_mcontext
;
1079 target_sigset_t tuc_sigmask
; /* mask last for extensibility */
1080 char __unused
[128 - sizeof(sigset_t
)];
1081 abi_ulong tuc_regspace
[128] __attribute__((__aligned__(8)));
1086 struct target_sigcontext sc
;
1087 abi_ulong extramask
[TARGET_NSIG_WORDS
-1];
1093 struct target_ucontext_v2 uc
;
1097 struct rt_sigframe_v1
1101 struct target_siginfo info
;
1102 struct target_ucontext_v1 uc
;
1106 struct rt_sigframe_v2
1108 struct target_siginfo info
;
1109 struct target_ucontext_v2 uc
;
1113 #define TARGET_CONFIG_CPU_32 1
1116 * For ARM syscalls, we encode the syscall number into the instruction.
1118 #define SWI_SYS_SIGRETURN (0xef000000|(TARGET_NR_sigreturn + ARM_SYSCALL_BASE))
1119 #define SWI_SYS_RT_SIGRETURN (0xef000000|(TARGET_NR_rt_sigreturn + ARM_SYSCALL_BASE))
1122 * For Thumb syscalls, we pass the syscall number via r7. We therefore
1123 * need two 16-bit instructions.
1125 #define SWI_THUMB_SIGRETURN (0xdf00 << 16 | 0x2700 | (TARGET_NR_sigreturn))
1126 #define SWI_THUMB_RT_SIGRETURN (0xdf00 << 16 | 0x2700 | (TARGET_NR_rt_sigreturn))
1128 static const abi_ulong retcodes
[4] = {
1129 SWI_SYS_SIGRETURN
, SWI_THUMB_SIGRETURN
,
1130 SWI_SYS_RT_SIGRETURN
, SWI_THUMB_RT_SIGRETURN
1134 #define __get_user_error(x,p,e) __get_user(x, p)
1136 static inline int valid_user_regs(CPUState
*regs
)
1142 setup_sigcontext(struct target_sigcontext
*sc
, /*struct _fpstate *fpstate,*/
1143 CPUState
*env
, abi_ulong mask
)
1145 __put_user(env
->regs
[0], &sc
->arm_r0
);
1146 __put_user(env
->regs
[1], &sc
->arm_r1
);
1147 __put_user(env
->regs
[2], &sc
->arm_r2
);
1148 __put_user(env
->regs
[3], &sc
->arm_r3
);
1149 __put_user(env
->regs
[4], &sc
->arm_r4
);
1150 __put_user(env
->regs
[5], &sc
->arm_r5
);
1151 __put_user(env
->regs
[6], &sc
->arm_r6
);
1152 __put_user(env
->regs
[7], &sc
->arm_r7
);
1153 __put_user(env
->regs
[8], &sc
->arm_r8
);
1154 __put_user(env
->regs
[9], &sc
->arm_r9
);
1155 __put_user(env
->regs
[10], &sc
->arm_r10
);
1156 __put_user(env
->regs
[11], &sc
->arm_fp
);
1157 __put_user(env
->regs
[12], &sc
->arm_ip
);
1158 __put_user(env
->regs
[13], &sc
->arm_sp
);
1159 __put_user(env
->regs
[14], &sc
->arm_lr
);
1160 __put_user(env
->regs
[15], &sc
->arm_pc
);
1161 #ifdef TARGET_CONFIG_CPU_32
1162 __put_user(cpsr_read(env
), &sc
->arm_cpsr
);
1165 __put_user(/* current->thread.trap_no */ 0, &sc
->trap_no
);
1166 __put_user(/* current->thread.error_code */ 0, &sc
->error_code
);
1167 __put_user(/* current->thread.address */ 0, &sc
->fault_address
);
1168 __put_user(mask
, &sc
->oldmask
);
1171 static inline abi_ulong
1172 get_sigframe(struct target_sigaction
*ka
, CPUState
*regs
, int framesize
)
1174 unsigned long sp
= regs
->regs
[13];
1177 * This is the X/Open sanctioned signal stack switching.
1179 if ((ka
->sa_flags
& TARGET_SA_ONSTACK
) && !sas_ss_flags(sp
))
1180 sp
= target_sigaltstack_used
.ss_sp
+ target_sigaltstack_used
.ss_size
;
1182 * ATPCS B01 mandates 8-byte alignment
1184 return (sp
- framesize
) & ~7;
1188 setup_return(CPUState
*env
, struct target_sigaction
*ka
,
1189 abi_ulong
*rc
, abi_ulong frame_addr
, int usig
, abi_ulong rc_addr
)
1191 abi_ulong handler
= ka
->_sa_handler
;
1193 int thumb
= handler
& 1;
1195 if (ka
->sa_flags
& TARGET_SA_RESTORER
) {
1196 retcode
= ka
->sa_restorer
;
1198 unsigned int idx
= thumb
;
1200 if (ka
->sa_flags
& TARGET_SA_SIGINFO
)
1203 if (__put_user(retcodes
[idx
], rc
))
1206 flush_icache_range((abi_ulong
)rc
,
1207 (abi_ulong
)(rc
+ 1));
1209 retcode
= rc_addr
+ thumb
;
1212 env
->regs
[0] = usig
;
1213 env
->regs
[13] = frame_addr
;
1214 env
->regs
[14] = retcode
;
1215 env
->regs
[15] = handler
& (thumb
? ~1 : ~3);
1219 #ifdef TARGET_CONFIG_CPU_32
1227 static void setup_sigframe_v2(struct target_ucontext_v2
*uc
,
1228 target_sigset_t
*set
, CPUState
*env
)
1230 struct target_sigaltstack stack
;
1233 /* Clear all the bits of the ucontext we don't use. */
1234 memset(uc
, 0, offsetof(struct target_ucontext_v2
, tuc_mcontext
));
1236 memset(&stack
, 0, sizeof(stack
));
1237 __put_user(target_sigaltstack_used
.ss_sp
, &stack
.ss_sp
);
1238 __put_user(target_sigaltstack_used
.ss_size
, &stack
.ss_size
);
1239 __put_user(sas_ss_flags(get_sp_from_cpustate(env
)), &stack
.ss_flags
);
1240 memcpy(&uc
->tuc_stack
, &stack
, sizeof(stack
));
1242 setup_sigcontext(&uc
->tuc_mcontext
, env
, set
->sig
[0]);
1243 /* FIXME: Save coprocessor signal frame. */
1244 for(i
= 0; i
< TARGET_NSIG_WORDS
; i
++) {
1245 __put_user(set
->sig
[i
], &uc
->tuc_sigmask
.sig
[i
]);
1249 /* compare linux/arch/arm/kernel/signal.c:setup_frame() */
1250 static void setup_frame_v1(int usig
, struct target_sigaction
*ka
,
1251 target_sigset_t
*set
, CPUState
*regs
)
1253 struct sigframe_v1
*frame
;
1254 abi_ulong frame_addr
= get_sigframe(ka
, regs
, sizeof(*frame
));
1257 if (!lock_user_struct(VERIFY_WRITE
, frame
, frame_addr
, 0))
1260 setup_sigcontext(&frame
->sc
, regs
, set
->sig
[0]);
1262 for(i
= 1; i
< TARGET_NSIG_WORDS
; i
++) {
1263 if (__put_user(set
->sig
[i
], &frame
->extramask
[i
- 1]))
1267 setup_return(regs
, ka
, &frame
->retcode
, frame_addr
, usig
,
1268 frame_addr
+ offsetof(struct sigframe_v1
, retcode
));
1271 unlock_user_struct(frame
, frame_addr
, 1);
1274 static void setup_frame_v2(int usig
, struct target_sigaction
*ka
,
1275 target_sigset_t
*set
, CPUState
*regs
)
1277 struct sigframe_v2
*frame
;
1278 abi_ulong frame_addr
= get_sigframe(ka
, regs
, sizeof(*frame
));
1280 if (!lock_user_struct(VERIFY_WRITE
, frame
, frame_addr
, 0))
1283 setup_sigframe_v2(&frame
->uc
, set
, regs
);
1285 setup_return(regs
, ka
, &frame
->retcode
, frame_addr
, usig
,
1286 frame_addr
+ offsetof(struct sigframe_v2
, retcode
));
1288 unlock_user_struct(frame
, frame_addr
, 1);
1291 static void setup_frame(int usig
, struct target_sigaction
*ka
,
1292 target_sigset_t
*set
, CPUState
*regs
)
1294 if (get_osversion() >= 0x020612) {
1295 setup_frame_v2(usig
, ka
, set
, regs
);
1297 setup_frame_v1(usig
, ka
, set
, regs
);
1301 /* compare linux/arch/arm/kernel/signal.c:setup_rt_frame() */
1302 static void setup_rt_frame_v1(int usig
, struct target_sigaction
*ka
,
1303 target_siginfo_t
*info
,
1304 target_sigset_t
*set
, CPUState
*env
)
1306 struct rt_sigframe_v1
*frame
;
1307 abi_ulong frame_addr
= get_sigframe(ka
, env
, sizeof(*frame
));
1308 struct target_sigaltstack stack
;
1310 abi_ulong info_addr
, uc_addr
;
1312 if (!lock_user_struct(VERIFY_WRITE
, frame
, frame_addr
, 0))
1315 info_addr
= frame_addr
+ offsetof(struct rt_sigframe_v1
, info
);
1316 __put_user(info_addr
, &frame
->pinfo
);
1317 uc_addr
= frame_addr
+ offsetof(struct rt_sigframe_v1
, uc
);
1318 __put_user(uc_addr
, &frame
->puc
);
1319 copy_siginfo_to_user(&frame
->info
, info
);
1321 /* Clear all the bits of the ucontext we don't use. */
1322 memset(&frame
->uc
, 0, offsetof(struct target_ucontext_v1
, tuc_mcontext
));
1324 memset(&stack
, 0, sizeof(stack
));
1325 __put_user(target_sigaltstack_used
.ss_sp
, &stack
.ss_sp
);
1326 __put_user(target_sigaltstack_used
.ss_size
, &stack
.ss_size
);
1327 __put_user(sas_ss_flags(get_sp_from_cpustate(env
)), &stack
.ss_flags
);
1328 memcpy(&frame
->uc
.tuc_stack
, &stack
, sizeof(stack
));
1330 setup_sigcontext(&frame
->uc
.tuc_mcontext
, env
, set
->sig
[0]);
1331 for(i
= 0; i
< TARGET_NSIG_WORDS
; i
++) {
1332 if (__put_user(set
->sig
[i
], &frame
->uc
.tuc_sigmask
.sig
[i
]))
1336 setup_return(env
, ka
, &frame
->retcode
, frame_addr
, usig
,
1337 frame_addr
+ offsetof(struct rt_sigframe_v1
, retcode
));
1339 env
->regs
[1] = info_addr
;
1340 env
->regs
[2] = uc_addr
;
1343 unlock_user_struct(frame
, frame_addr
, 1);
1346 static void setup_rt_frame_v2(int usig
, struct target_sigaction
*ka
,
1347 target_siginfo_t
*info
,
1348 target_sigset_t
*set
, CPUState
*env
)
1350 struct rt_sigframe_v2
*frame
;
1351 abi_ulong frame_addr
= get_sigframe(ka
, env
, sizeof(*frame
));
1352 abi_ulong info_addr
, uc_addr
;
1354 if (!lock_user_struct(VERIFY_WRITE
, frame
, frame_addr
, 0))
1357 info_addr
= frame_addr
+ offsetof(struct rt_sigframe_v2
, info
);
1358 uc_addr
= frame_addr
+ offsetof(struct rt_sigframe_v2
, uc
);
1359 copy_siginfo_to_user(&frame
->info
, info
);
1361 setup_sigframe_v2(&frame
->uc
, set
, env
);
1363 setup_return(env
, ka
, &frame
->retcode
, frame_addr
, usig
,
1364 frame_addr
+ offsetof(struct rt_sigframe_v2
, retcode
));
1366 env
->regs
[1] = info_addr
;
1367 env
->regs
[2] = uc_addr
;
1369 unlock_user_struct(frame
, frame_addr
, 1);
1372 static void setup_rt_frame(int usig
, struct target_sigaction
*ka
,
1373 target_siginfo_t
*info
,
1374 target_sigset_t
*set
, CPUState
*env
)
1376 if (get_osversion() >= 0x020612) {
1377 setup_rt_frame_v2(usig
, ka
, info
, set
, env
);
1379 setup_rt_frame_v1(usig
, ka
, info
, set
, env
);
1384 restore_sigcontext(CPUState
*env
, struct target_sigcontext
*sc
)
1389 __get_user_error(env
->regs
[0], &sc
->arm_r0
, err
);
1390 __get_user_error(env
->regs
[1], &sc
->arm_r1
, err
);
1391 __get_user_error(env
->regs
[2], &sc
->arm_r2
, err
);
1392 __get_user_error(env
->regs
[3], &sc
->arm_r3
, err
);
1393 __get_user_error(env
->regs
[4], &sc
->arm_r4
, err
);
1394 __get_user_error(env
->regs
[5], &sc
->arm_r5
, err
);
1395 __get_user_error(env
->regs
[6], &sc
->arm_r6
, err
);
1396 __get_user_error(env
->regs
[7], &sc
->arm_r7
, err
);
1397 __get_user_error(env
->regs
[8], &sc
->arm_r8
, err
);
1398 __get_user_error(env
->regs
[9], &sc
->arm_r9
, err
);
1399 __get_user_error(env
->regs
[10], &sc
->arm_r10
, err
);
1400 __get_user_error(env
->regs
[11], &sc
->arm_fp
, err
);
1401 __get_user_error(env
->regs
[12], &sc
->arm_ip
, err
);
1402 __get_user_error(env
->regs
[13], &sc
->arm_sp
, err
);
1403 __get_user_error(env
->regs
[14], &sc
->arm_lr
, err
);
1404 __get_user_error(env
->regs
[15], &sc
->arm_pc
, err
);
1405 #ifdef TARGET_CONFIG_CPU_32
1406 __get_user_error(cpsr
, &sc
->arm_cpsr
, err
);
1407 cpsr_write(env
, cpsr
, CPSR_USER
| CPSR_EXEC
);
1410 err
|= !valid_user_regs(env
);
1415 static long do_sigreturn_v1(CPUState
*env
)
1417 abi_ulong frame_addr
;
1418 struct sigframe_v1
*frame
;
1419 target_sigset_t set
;
1424 * Since we stacked the signal on a 64-bit boundary,
1425 * then 'sp' should be word aligned here. If it's
1426 * not, then the user is trying to mess with us.
1428 if (env
->regs
[13] & 7)
1431 frame_addr
= env
->regs
[13];
1432 if (!lock_user_struct(VERIFY_READ
, frame
, frame_addr
, 1))
1435 if (__get_user(set
.sig
[0], &frame
->sc
.oldmask
))
1437 for(i
= 1; i
< TARGET_NSIG_WORDS
; i
++) {
1438 if (__get_user(set
.sig
[i
], &frame
->extramask
[i
- 1]))
1442 target_to_host_sigset_internal(&host_set
, &set
);
1443 sigprocmask(SIG_SETMASK
, &host_set
, NULL
);
1445 if (restore_sigcontext(env
, &frame
->sc
))
1449 /* Send SIGTRAP if we're single-stepping */
1450 if (ptrace_cancel_bpt(current
))
1451 send_sig(SIGTRAP
, current
, 1);
1453 unlock_user_struct(frame
, frame_addr
, 0);
1454 return env
->regs
[0];
1457 unlock_user_struct(frame
, frame_addr
, 0);
1458 force_sig(SIGSEGV
/* , current */);
1462 static int do_sigframe_return_v2(CPUState
*env
, target_ulong frame_addr
,
1463 struct target_ucontext_v2
*uc
)
1467 target_to_host_sigset(&host_set
, &uc
->tuc_sigmask
);
1468 sigprocmask(SIG_SETMASK
, &host_set
, NULL
);
1470 if (restore_sigcontext(env
, &uc
->tuc_mcontext
))
1473 if (do_sigaltstack(frame_addr
+ offsetof(struct target_ucontext_v2
, tuc_stack
), 0, get_sp_from_cpustate(env
)) == -EFAULT
)
1477 /* Send SIGTRAP if we're single-stepping */
1478 if (ptrace_cancel_bpt(current
))
1479 send_sig(SIGTRAP
, current
, 1);
1485 static long do_sigreturn_v2(CPUState
*env
)
1487 abi_ulong frame_addr
;
1488 struct sigframe_v2
*frame
;
1491 * Since we stacked the signal on a 64-bit boundary,
1492 * then 'sp' should be word aligned here. If it's
1493 * not, then the user is trying to mess with us.
1495 if (env
->regs
[13] & 7)
1498 frame_addr
= env
->regs
[13];
1499 if (!lock_user_struct(VERIFY_READ
, frame
, frame_addr
, 1))
1502 if (do_sigframe_return_v2(env
, frame_addr
, &frame
->uc
))
1505 unlock_user_struct(frame
, frame_addr
, 0);
1506 return env
->regs
[0];
1509 unlock_user_struct(frame
, frame_addr
, 0);
1510 force_sig(SIGSEGV
/* , current */);
1514 long do_sigreturn(CPUState
*env
)
1516 if (get_osversion() >= 0x020612) {
1517 return do_sigreturn_v2(env
);
1519 return do_sigreturn_v1(env
);
1523 static long do_rt_sigreturn_v1(CPUState
*env
)
1525 abi_ulong frame_addr
;
1526 struct rt_sigframe_v1
*frame
;
1530 * Since we stacked the signal on a 64-bit boundary,
1531 * then 'sp' should be word aligned here. If it's
1532 * not, then the user is trying to mess with us.
1534 if (env
->regs
[13] & 7)
1537 frame_addr
= env
->regs
[13];
1538 if (!lock_user_struct(VERIFY_READ
, frame
, frame_addr
, 1))
1541 target_to_host_sigset(&host_set
, &frame
->uc
.tuc_sigmask
);
1542 sigprocmask(SIG_SETMASK
, &host_set
, NULL
);
1544 if (restore_sigcontext(env
, &frame
->uc
.tuc_mcontext
))
1547 if (do_sigaltstack(frame_addr
+ offsetof(struct rt_sigframe_v1
, uc
.tuc_stack
), 0, get_sp_from_cpustate(env
)) == -EFAULT
)
1551 /* Send SIGTRAP if we're single-stepping */
1552 if (ptrace_cancel_bpt(current
))
1553 send_sig(SIGTRAP
, current
, 1);
1555 unlock_user_struct(frame
, frame_addr
, 0);
1556 return env
->regs
[0];
1559 unlock_user_struct(frame
, frame_addr
, 0);
1560 force_sig(SIGSEGV
/* , current */);
1564 static long do_rt_sigreturn_v2(CPUState
*env
)
1566 abi_ulong frame_addr
;
1567 struct rt_sigframe_v2
*frame
;
1570 * Since we stacked the signal on a 64-bit boundary,
1571 * then 'sp' should be word aligned here. If it's
1572 * not, then the user is trying to mess with us.
1574 if (env
->regs
[13] & 7)
1577 frame_addr
= env
->regs
[13];
1578 if (!lock_user_struct(VERIFY_READ
, frame
, frame_addr
, 1))
1581 if (do_sigframe_return_v2(env
, frame_addr
, &frame
->uc
))
1584 unlock_user_struct(frame
, frame_addr
, 0);
1585 return env
->regs
[0];
1588 unlock_user_struct(frame
, frame_addr
, 0);
1589 force_sig(SIGSEGV
/* , current */);
1593 long do_rt_sigreturn(CPUState
*env
)
1595 if (get_osversion() >= 0x020612) {
1596 return do_rt_sigreturn_v2(env
);
1598 return do_rt_sigreturn_v1(env
);
1602 #elif defined(TARGET_SPARC)
1604 #define __SUNOS_MAXWIN 31
1606 /* This is what SunOS does, so shall I. */
1607 struct target_sigcontext
{
1608 abi_ulong sigc_onstack
; /* state to restore */
1610 abi_ulong sigc_mask
; /* sigmask to restore */
1611 abi_ulong sigc_sp
; /* stack pointer */
1612 abi_ulong sigc_pc
; /* program counter */
1613 abi_ulong sigc_npc
; /* next program counter */
1614 abi_ulong sigc_psr
; /* for condition codes etc */
1615 abi_ulong sigc_g1
; /* User uses these two registers */
1616 abi_ulong sigc_o0
; /* within the trampoline code. */
1618 /* Now comes information regarding the users window set
1619 * at the time of the signal.
1621 abi_ulong sigc_oswins
; /* outstanding windows */
1623 /* stack ptrs for each regwin buf */
1624 char *sigc_spbuf
[__SUNOS_MAXWIN
];
1626 /* Windows to restore after signal */
1628 abi_ulong locals
[8];
1630 } sigc_wbuf
[__SUNOS_MAXWIN
];
1632 /* A Sparc stack frame */
1633 struct sparc_stackf
{
1634 abi_ulong locals
[8];
1636 struct sparc_stackf
*fp
;
1637 abi_ulong callers_pc
;
1640 abi_ulong xxargs
[1];
1649 abi_ulong u_regs
[16]; /* globals and ins */
1655 unsigned long si_float_regs
[32];
1656 unsigned long si_fsr
;
1657 unsigned long si_fpqdepth
;
1659 unsigned long *insn_addr
;
1662 } qemu_siginfo_fpu_t
;
1665 struct target_signal_frame
{
1666 struct sparc_stackf ss
;
1669 abi_ulong insns
[2] __attribute__ ((aligned (8)));
1670 abi_ulong extramask
[TARGET_NSIG_WORDS
- 1];
1671 abi_ulong extra_size
; /* Should be 0 */
1672 qemu_siginfo_fpu_t fpu_state
;
1674 struct target_rt_signal_frame
{
1675 struct sparc_stackf ss
;
1680 unsigned int insns
[2];
1682 unsigned int extra_size
; /* Should be 0 */
1683 qemu_siginfo_fpu_t fpu_state
;
1697 #define UREG_FP UREG_I6
1698 #define UREG_SP UREG_O6
1700 static inline abi_ulong
get_sigframe(struct target_sigaction
*sa
,
1701 CPUState
*env
, unsigned long framesize
)
1705 sp
= env
->regwptr
[UREG_FP
];
1707 /* This is the X/Open sanctioned signal stack switching. */
1708 if (sa
->sa_flags
& TARGET_SA_ONSTACK
) {
1709 if (!on_sig_stack(sp
)
1710 && !((target_sigaltstack_used
.ss_sp
+ target_sigaltstack_used
.ss_size
) & 7))
1711 sp
= target_sigaltstack_used
.ss_sp
+ target_sigaltstack_used
.ss_size
;
1713 return sp
- framesize
;
1717 setup___siginfo(__siginfo_t
*si
, CPUState
*env
, abi_ulong mask
)
1721 err
|= __put_user(env
->psr
, &si
->si_regs
.psr
);
1722 err
|= __put_user(env
->pc
, &si
->si_regs
.pc
);
1723 err
|= __put_user(env
->npc
, &si
->si_regs
.npc
);
1724 err
|= __put_user(env
->y
, &si
->si_regs
.y
);
1725 for (i
=0; i
< 8; i
++) {
1726 err
|= __put_user(env
->gregs
[i
], &si
->si_regs
.u_regs
[i
]);
1728 for (i
=0; i
< 8; i
++) {
1729 err
|= __put_user(env
->regwptr
[UREG_I0
+ i
], &si
->si_regs
.u_regs
[i
+8]);
1731 err
|= __put_user(mask
, &si
->si_mask
);
1737 setup_sigcontext(struct target_sigcontext
*sc
, /*struct _fpstate *fpstate,*/
1738 CPUState
*env
, unsigned long mask
)
1742 err
|= __put_user(mask
, &sc
->sigc_mask
);
1743 err
|= __put_user(env
->regwptr
[UREG_SP
], &sc
->sigc_sp
);
1744 err
|= __put_user(env
->pc
, &sc
->sigc_pc
);
1745 err
|= __put_user(env
->npc
, &sc
->sigc_npc
);
1746 err
|= __put_user(env
->psr
, &sc
->sigc_psr
);
1747 err
|= __put_user(env
->gregs
[1], &sc
->sigc_g1
);
1748 err
|= __put_user(env
->regwptr
[UREG_O0
], &sc
->sigc_o0
);
1753 #define NF_ALIGNEDSZ (((sizeof(struct target_signal_frame) + 7) & (~7)))
1755 static void setup_frame(int sig
, struct target_sigaction
*ka
,
1756 target_sigset_t
*set
, CPUState
*env
)
1759 struct target_signal_frame
*sf
;
1760 int sigframe_size
, err
, i
;
1762 /* 1. Make sure everything is clean */
1763 //synchronize_user_stack();
1765 sigframe_size
= NF_ALIGNEDSZ
;
1766 sf_addr
= get_sigframe(ka
, env
, sigframe_size
);
1768 sf
= lock_user(VERIFY_WRITE
, sf_addr
,
1769 sizeof(struct target_signal_frame
), 0);
1773 //fprintf(stderr, "sf: %x pc %x fp %x sp %x\n", sf, env->pc, env->regwptr[UREG_FP], env->regwptr[UREG_SP]);
1775 if (invalid_frame_pointer(sf
, sigframe_size
))
1776 goto sigill_and_return
;
1778 /* 2. Save the current process state */
1779 err
= setup___siginfo(&sf
->info
, env
, set
->sig
[0]);
1780 err
|= __put_user(0, &sf
->extra_size
);
1782 //err |= save_fpu_state(regs, &sf->fpu_state);
1783 //err |= __put_user(&sf->fpu_state, &sf->fpu_save);
1785 err
|= __put_user(set
->sig
[0], &sf
->info
.si_mask
);
1786 for (i
= 0; i
< TARGET_NSIG_WORDS
- 1; i
++) {
1787 err
|= __put_user(set
->sig
[i
+ 1], &sf
->extramask
[i
]);
1790 for (i
= 0; i
< 8; i
++) {
1791 err
|= __put_user(env
->regwptr
[i
+ UREG_L0
], &sf
->ss
.locals
[i
]);
1793 for (i
= 0; i
< 8; i
++) {
1794 err
|= __put_user(env
->regwptr
[i
+ UREG_I0
], &sf
->ss
.ins
[i
]);
1799 /* 3. signal handler back-trampoline and parameters */
1800 env
->regwptr
[UREG_FP
] = sf_addr
;
1801 env
->regwptr
[UREG_I0
] = sig
;
1802 env
->regwptr
[UREG_I1
] = sf_addr
+
1803 offsetof(struct target_signal_frame
, info
);
1804 env
->regwptr
[UREG_I2
] = sf_addr
+
1805 offsetof(struct target_signal_frame
, info
);
1807 /* 4. signal handler */
1808 env
->pc
= ka
->_sa_handler
;
1809 env
->npc
= (env
->pc
+ 4);
1810 /* 5. return to kernel instructions */
1811 if (ka
->sa_restorer
)
1812 env
->regwptr
[UREG_I7
] = ka
->sa_restorer
;
1816 env
->regwptr
[UREG_I7
] = sf_addr
+
1817 offsetof(struct target_signal_frame
, insns
) - 2 * 4;
1819 /* mov __NR_sigreturn, %g1 */
1821 err
|= __put_user(val32
, &sf
->insns
[0]);
1825 err
|= __put_user(val32
, &sf
->insns
[1]);
1829 /* Flush instruction space. */
1830 //flush_sig_insns(current->mm, (unsigned long) &(sf->insns[0]));
1833 unlock_user(sf
, sf_addr
, sizeof(struct target_signal_frame
));
1837 force_sig(TARGET_SIGILL
);
1840 //fprintf(stderr, "force_sig\n");
1841 unlock_user(sf
, sf_addr
, sizeof(struct target_signal_frame
));
1842 force_sig(TARGET_SIGSEGV
);
1845 restore_fpu_state(CPUState
*env
, qemu_siginfo_fpu_t
*fpu
)
1850 if (current
->flags
& PF_USEDFPU
)
1851 regs
->psr
&= ~PSR_EF
;
1853 if (current
== last_task_used_math
) {
1854 last_task_used_math
= 0;
1855 regs
->psr
&= ~PSR_EF
;
1858 current
->used_math
= 1;
1859 current
->flags
&= ~PF_USEDFPU
;
1862 if (verify_area (VERIFY_READ
, fpu
, sizeof(*fpu
)))
1867 /* XXX: incorrect */
1868 err
= __copy_from_user(&env
->fpr
[0], &fpu
->si_float_regs
[0],
1869 (sizeof(unsigned long) * 32));
1871 err
|= __get_user(env
->fsr
, &fpu
->si_fsr
);
1873 err
|= __get_user(current
->thread
.fpqdepth
, &fpu
->si_fpqdepth
);
1874 if (current
->thread
.fpqdepth
!= 0)
1875 err
|= __copy_from_user(¤t
->thread
.fpqueue
[0],
1876 &fpu
->si_fpqueue
[0],
1877 ((sizeof(unsigned long) +
1878 (sizeof(unsigned long *)))*16));
1884 static void setup_rt_frame(int sig
, struct target_sigaction
*ka
,
1885 target_siginfo_t
*info
,
1886 target_sigset_t
*set
, CPUState
*env
)
1888 fprintf(stderr
, "setup_rt_frame: not implemented\n");
1891 long do_sigreturn(CPUState
*env
)
1894 struct target_signal_frame
*sf
;
1895 uint32_t up_psr
, pc
, npc
;
1896 target_sigset_t set
;
1898 abi_ulong fpu_save_addr
;
1901 sf_addr
= env
->regwptr
[UREG_FP
];
1902 if (!lock_user_struct(VERIFY_READ
, sf
, sf_addr
, 1))
1905 fprintf(stderr
, "sigreturn\n");
1906 fprintf(stderr
, "sf: %x pc %x fp %x sp %x\n", sf
, env
->pc
, env
->regwptr
[UREG_FP
], env
->regwptr
[UREG_SP
]);
1908 //cpu_dump_state(env, stderr, fprintf, 0);
1910 /* 1. Make sure we are not getting garbage from the user */
1915 err
= __get_user(pc
, &sf
->info
.si_regs
.pc
);
1916 err
|= __get_user(npc
, &sf
->info
.si_regs
.npc
);
1921 /* 2. Restore the state */
1922 err
|= __get_user(up_psr
, &sf
->info
.si_regs
.psr
);
1924 /* User can only change condition codes and FPU enabling in %psr. */
1925 env
->psr
= (up_psr
& (PSR_ICC
/* | PSR_EF */))
1926 | (env
->psr
& ~(PSR_ICC
/* | PSR_EF */));
1930 err
|= __get_user(env
->y
, &sf
->info
.si_regs
.y
);
1931 for (i
=0; i
< 8; i
++) {
1932 err
|= __get_user(env
->gregs
[i
], &sf
->info
.si_regs
.u_regs
[i
]);
1934 for (i
=0; i
< 8; i
++) {
1935 err
|= __get_user(env
->regwptr
[i
+ UREG_I0
], &sf
->info
.si_regs
.u_regs
[i
+8]);
1938 err
|= __get_user(fpu_save_addr
, &sf
->fpu_save
);
1941 // err |= restore_fpu_state(env, fpu_save);
1943 /* This is pretty much atomic, no amount locking would prevent
1944 * the races which exist anyways.
1946 err
|= __get_user(set
.sig
[0], &sf
->info
.si_mask
);
1947 for(i
= 1; i
< TARGET_NSIG_WORDS
; i
++) {
1948 err
|= (__get_user(set
.sig
[i
], &sf
->extramask
[i
- 1]));
1951 target_to_host_sigset_internal(&host_set
, &set
);
1952 sigprocmask(SIG_SETMASK
, &host_set
, NULL
);
1956 unlock_user_struct(sf
, sf_addr
, 0);
1957 return env
->regwptr
[0];
1960 unlock_user_struct(sf
, sf_addr
, 0);
1961 force_sig(TARGET_SIGSEGV
);
1964 long do_rt_sigreturn(CPUState
*env
)
1966 fprintf(stderr
, "do_rt_sigreturn: not implemented\n");
1967 return -TARGET_ENOSYS
;
1970 #if defined(TARGET_SPARC64) && !defined(TARGET_ABI32)
1992 typedef abi_ulong target_mc_greg_t
;
1993 typedef target_mc_greg_t target_mc_gregset_t
[MC_NGREG
];
1995 struct target_mc_fq
{
1996 abi_ulong
*mcfq_addr
;
2000 struct target_mc_fpu
{
2004 //uint128_t qregs[16];
2006 abi_ulong mcfpu_fsr
;
2007 abi_ulong mcfpu_fprs
;
2008 abi_ulong mcfpu_gsr
;
2009 struct target_mc_fq
*mcfpu_fq
;
2010 unsigned char mcfpu_qcnt
;
2011 unsigned char mcfpu_qentsz
;
2012 unsigned char mcfpu_enab
;
2014 typedef struct target_mc_fpu target_mc_fpu_t
;
2017 target_mc_gregset_t mc_gregs
;
2018 target_mc_greg_t mc_fp
;
2019 target_mc_greg_t mc_i7
;
2020 target_mc_fpu_t mc_fpregs
;
2021 } target_mcontext_t
;
2023 struct target_ucontext
{
2024 struct target_ucontext
*uc_link
;
2026 target_sigset_t uc_sigmask
;
2027 target_mcontext_t uc_mcontext
;
2030 /* A V9 register window */
2031 struct target_reg_window
{
2032 abi_ulong locals
[8];
2036 #define TARGET_STACK_BIAS 2047
2038 /* {set, get}context() needed for 64-bit SparcLinux userland. */
2039 void sparc64_set_context(CPUSPARCState
*env
)
2042 struct target_ucontext
*ucp
;
2043 target_mc_gregset_t
*grp
;
2044 abi_ulong pc
, npc
, tstate
;
2045 abi_ulong fp
, i7
, w_addr
;
2046 unsigned char fenab
;
2050 ucp_addr
= env
->regwptr
[UREG_I0
];
2051 if (!lock_user_struct(VERIFY_READ
, ucp
, ucp_addr
, 1))
2053 grp
= &ucp
->uc_mcontext
.mc_gregs
;
2054 err
= __get_user(pc
, &((*grp
)[MC_PC
]));
2055 err
|= __get_user(npc
, &((*grp
)[MC_NPC
]));
2056 if (err
|| ((pc
| npc
) & 3))
2058 if (env
->regwptr
[UREG_I1
]) {
2059 target_sigset_t target_set
;
2062 if (TARGET_NSIG_WORDS
== 1) {
2063 if (__get_user(target_set
.sig
[0], &ucp
->uc_sigmask
.sig
[0]))
2066 abi_ulong
*src
, *dst
;
2067 src
= ucp
->uc_sigmask
.sig
;
2068 dst
= target_set
.sig
;
2069 for (i
= 0; i
< sizeof(target_sigset_t
) / sizeof(abi_ulong
);
2071 err
|= __get_user(*dst
, src
);
2075 target_to_host_sigset_internal(&set
, &target_set
);
2076 sigprocmask(SIG_SETMASK
, &set
, NULL
);
2080 err
|= __get_user(env
->y
, &((*grp
)[MC_Y
]));
2081 err
|= __get_user(tstate
, &((*grp
)[MC_TSTATE
]));
2082 env
->asi
= (tstate
>> 24) & 0xff;
2083 PUT_CCR(env
, tstate
>> 32);
2084 PUT_CWP64(env
, tstate
& 0x1f);
2085 err
|= __get_user(env
->gregs
[1], (&(*grp
)[MC_G1
]));
2086 err
|= __get_user(env
->gregs
[2], (&(*grp
)[MC_G2
]));
2087 err
|= __get_user(env
->gregs
[3], (&(*grp
)[MC_G3
]));
2088 err
|= __get_user(env
->gregs
[4], (&(*grp
)[MC_G4
]));
2089 err
|= __get_user(env
->gregs
[5], (&(*grp
)[MC_G5
]));
2090 err
|= __get_user(env
->gregs
[6], (&(*grp
)[MC_G6
]));
2091 err
|= __get_user(env
->gregs
[7], (&(*grp
)[MC_G7
]));
2092 err
|= __get_user(env
->regwptr
[UREG_I0
], (&(*grp
)[MC_O0
]));
2093 err
|= __get_user(env
->regwptr
[UREG_I1
], (&(*grp
)[MC_O1
]));
2094 err
|= __get_user(env
->regwptr
[UREG_I2
], (&(*grp
)[MC_O2
]));
2095 err
|= __get_user(env
->regwptr
[UREG_I3
], (&(*grp
)[MC_O3
]));
2096 err
|= __get_user(env
->regwptr
[UREG_I4
], (&(*grp
)[MC_O4
]));
2097 err
|= __get_user(env
->regwptr
[UREG_I5
], (&(*grp
)[MC_O5
]));
2098 err
|= __get_user(env
->regwptr
[UREG_I6
], (&(*grp
)[MC_O6
]));
2099 err
|= __get_user(env
->regwptr
[UREG_I7
], (&(*grp
)[MC_O7
]));
2101 err
|= __get_user(fp
, &(ucp
->uc_mcontext
.mc_fp
));
2102 err
|= __get_user(i7
, &(ucp
->uc_mcontext
.mc_i7
));
2104 w_addr
= TARGET_STACK_BIAS
+env
->regwptr
[UREG_I6
];
2105 if (put_user(fp
, w_addr
+ offsetof(struct target_reg_window
, ins
[6]),
2108 if (put_user(i7
, w_addr
+ offsetof(struct target_reg_window
, ins
[7]),
2111 err
|= __get_user(fenab
, &(ucp
->uc_mcontext
.mc_fpregs
.mcfpu_enab
));
2112 err
|= __get_user(env
->fprs
, &(ucp
->uc_mcontext
.mc_fpregs
.mcfpu_fprs
));
2114 uint32_t *src
, *dst
;
2115 src
= ucp
->uc_mcontext
.mc_fpregs
.mcfpu_fregs
.sregs
;
2117 /* XXX: check that the CPU storage is the same as user context */
2118 for (i
= 0; i
< 64; i
++, dst
++, src
++)
2119 err
|= __get_user(*dst
, src
);
2121 err
|= __get_user(env
->fsr
,
2122 &(ucp
->uc_mcontext
.mc_fpregs
.mcfpu_fsr
));
2123 err
|= __get_user(env
->gsr
,
2124 &(ucp
->uc_mcontext
.mc_fpregs
.mcfpu_gsr
));
2127 unlock_user_struct(ucp
, ucp_addr
, 0);
2130 unlock_user_struct(ucp
, ucp_addr
, 0);
2134 void sparc64_get_context(CPUSPARCState
*env
)
2137 struct target_ucontext
*ucp
;
2138 target_mc_gregset_t
*grp
;
2139 target_mcontext_t
*mcp
;
2140 abi_ulong fp
, i7
, w_addr
;
2143 target_sigset_t target_set
;
2146 ucp_addr
= env
->regwptr
[UREG_I0
];
2147 if (!lock_user_struct(VERIFY_WRITE
, ucp
, ucp_addr
, 0))
2150 mcp
= &ucp
->uc_mcontext
;
2151 grp
= &mcp
->mc_gregs
;
2153 /* Skip over the trap instruction, first. */
2159 sigprocmask(0, NULL
, &set
);
2160 host_to_target_sigset_internal(&target_set
, &set
);
2161 if (TARGET_NSIG_WORDS
== 1) {
2162 err
|= __put_user(target_set
.sig
[0],
2163 (abi_ulong
*)&ucp
->uc_sigmask
);
2165 abi_ulong
*src
, *dst
;
2166 src
= target_set
.sig
;
2167 dst
= ucp
->uc_sigmask
.sig
;
2168 for (i
= 0; i
< sizeof(target_sigset_t
) / sizeof(abi_ulong
);
2170 err
|= __put_user(*src
, dst
);
2175 /* XXX: tstate must be saved properly */
2176 // err |= __put_user(env->tstate, &((*grp)[MC_TSTATE]));
2177 err
|= __put_user(env
->pc
, &((*grp
)[MC_PC
]));
2178 err
|= __put_user(env
->npc
, &((*grp
)[MC_NPC
]));
2179 err
|= __put_user(env
->y
, &((*grp
)[MC_Y
]));
2180 err
|= __put_user(env
->gregs
[1], &((*grp
)[MC_G1
]));
2181 err
|= __put_user(env
->gregs
[2], &((*grp
)[MC_G2
]));
2182 err
|= __put_user(env
->gregs
[3], &((*grp
)[MC_G3
]));
2183 err
|= __put_user(env
->gregs
[4], &((*grp
)[MC_G4
]));
2184 err
|= __put_user(env
->gregs
[5], &((*grp
)[MC_G5
]));
2185 err
|= __put_user(env
->gregs
[6], &((*grp
)[MC_G6
]));
2186 err
|= __put_user(env
->gregs
[7], &((*grp
)[MC_G7
]));
2187 err
|= __put_user(env
->regwptr
[UREG_I0
], &((*grp
)[MC_O0
]));
2188 err
|= __put_user(env
->regwptr
[UREG_I1
], &((*grp
)[MC_O1
]));
2189 err
|= __put_user(env
->regwptr
[UREG_I2
], &((*grp
)[MC_O2
]));
2190 err
|= __put_user(env
->regwptr
[UREG_I3
], &((*grp
)[MC_O3
]));
2191 err
|= __put_user(env
->regwptr
[UREG_I4
], &((*grp
)[MC_O4
]));
2192 err
|= __put_user(env
->regwptr
[UREG_I5
], &((*grp
)[MC_O5
]));
2193 err
|= __put_user(env
->regwptr
[UREG_I6
], &((*grp
)[MC_O6
]));
2194 err
|= __put_user(env
->regwptr
[UREG_I7
], &((*grp
)[MC_O7
]));
2196 w_addr
= TARGET_STACK_BIAS
+env
->regwptr
[UREG_I6
];
2198 if (get_user(fp
, w_addr
+ offsetof(struct target_reg_window
, ins
[6]),
2201 if (get_user(i7
, w_addr
+ offsetof(struct target_reg_window
, ins
[7]),
2204 err
|= __put_user(fp
, &(mcp
->mc_fp
));
2205 err
|= __put_user(i7
, &(mcp
->mc_i7
));
2208 uint32_t *src
, *dst
;
2210 dst
= ucp
->uc_mcontext
.mc_fpregs
.mcfpu_fregs
.sregs
;
2211 /* XXX: check that the CPU storage is the same as user context */
2212 for (i
= 0; i
< 64; i
++, dst
++, src
++)
2213 err
|= __put_user(*src
, dst
);
2215 err
|= __put_user(env
->fsr
, &(mcp
->mc_fpregs
.mcfpu_fsr
));
2216 err
|= __put_user(env
->gsr
, &(mcp
->mc_fpregs
.mcfpu_gsr
));
2217 err
|= __put_user(env
->fprs
, &(mcp
->mc_fpregs
.mcfpu_fprs
));
2221 unlock_user_struct(ucp
, ucp_addr
, 1);
2224 unlock_user_struct(ucp
, ucp_addr
, 1);
2228 #elif defined(TARGET_ABI_MIPSN64)
2230 # warning signal handling not implemented
2232 static void setup_frame(int sig
, struct target_sigaction
*ka
,
2233 target_sigset_t
*set
, CPUState
*env
)
2235 fprintf(stderr
, "setup_frame: not implemented\n");
2238 static void setup_rt_frame(int sig
, struct target_sigaction
*ka
,
2239 target_siginfo_t
*info
,
2240 target_sigset_t
*set
, CPUState
*env
)
2242 fprintf(stderr
, "setup_rt_frame: not implemented\n");
2245 long do_sigreturn(CPUState
*env
)
2247 fprintf(stderr
, "do_sigreturn: not implemented\n");
2248 return -TARGET_ENOSYS
;
2251 long do_rt_sigreturn(CPUState
*env
)
2253 fprintf(stderr
, "do_rt_sigreturn: not implemented\n");
2254 return -TARGET_ENOSYS
;
2257 #elif defined(TARGET_ABI_MIPSN32)
2259 # warning signal handling not implemented
2261 static void setup_frame(int sig
, struct target_sigaction
*ka
,
2262 target_sigset_t
*set
, CPUState
*env
)
2264 fprintf(stderr
, "setup_frame: not implemented\n");
2267 static void setup_rt_frame(int sig
, struct target_sigaction
*ka
,
2268 target_siginfo_t
*info
,
2269 target_sigset_t
*set
, CPUState
*env
)
2271 fprintf(stderr
, "setup_rt_frame: not implemented\n");
2274 long do_sigreturn(CPUState
*env
)
2276 fprintf(stderr
, "do_sigreturn: not implemented\n");
2277 return -TARGET_ENOSYS
;
2280 long do_rt_sigreturn(CPUState
*env
)
2282 fprintf(stderr
, "do_rt_sigreturn: not implemented\n");
2283 return -TARGET_ENOSYS
;
2286 #elif defined(TARGET_ABI_MIPSO32)
2288 struct target_sigcontext
{
2289 uint32_t sc_regmask
; /* Unused */
2292 uint64_t sc_regs
[32];
2293 uint64_t sc_fpregs
[32];
2294 uint32_t sc_ownedfp
; /* Unused */
2295 uint32_t sc_fpc_csr
;
2296 uint32_t sc_fpc_eir
; /* Unused */
2297 uint32_t sc_used_math
;
2298 uint32_t sc_dsp
; /* dsp status, was sc_ssflags */
2301 target_ulong sc_hi1
; /* Was sc_cause */
2302 target_ulong sc_lo1
; /* Was sc_badvaddr */
2303 target_ulong sc_hi2
; /* Was sc_sigset[4] */
2304 target_ulong sc_lo2
;
2305 target_ulong sc_hi3
;
2306 target_ulong sc_lo3
;
2310 uint32_t sf_ass
[4]; /* argument save space for o32 */
2311 uint32_t sf_code
[2]; /* signal trampoline */
2312 struct target_sigcontext sf_sc
;
2313 target_sigset_t sf_mask
;
2316 struct target_ucontext
{
2317 target_ulong uc_flags
;
2318 target_ulong uc_link
;
2319 target_stack_t uc_stack
;
2320 struct target_sigcontext uc_mcontext
;
2321 target_sigset_t uc_sigmask
;
2324 struct target_rt_sigframe
{
2325 uint32_t rs_ass
[4]; /* argument save space for o32 */
2326 uint32_t rs_code
[2]; /* signal trampoline */
2327 struct target_siginfo rs_info
;
2328 struct target_ucontext rs_uc
;
2331 /* Install trampoline to jump back from signal handler */
2332 static inline int install_sigtramp(unsigned int *tramp
, unsigned int syscall
)
2337 * Set up the return code ...
2339 * li v0, __NR__foo_sigreturn
2343 err
= __put_user(0x24020000 + syscall
, tramp
+ 0);
2344 err
|= __put_user(0x0000000c , tramp
+ 1);
2345 /* flush_cache_sigtramp((unsigned long) tramp); */
2350 setup_sigcontext(CPUState
*regs
, struct target_sigcontext
*sc
)
2354 err
|= __put_user(regs
->active_tc
.PC
, &sc
->sc_pc
);
2356 #define save_gp_reg(i) do { \
2357 err |= __put_user(regs->active_tc.gpr[i], &sc->sc_regs[i]); \
2359 __put_user(0, &sc
->sc_regs
[0]); save_gp_reg(1); save_gp_reg(2);
2360 save_gp_reg(3); save_gp_reg(4); save_gp_reg(5); save_gp_reg(6);
2361 save_gp_reg(7); save_gp_reg(8); save_gp_reg(9); save_gp_reg(10);
2362 save_gp_reg(11); save_gp_reg(12); save_gp_reg(13); save_gp_reg(14);
2363 save_gp_reg(15); save_gp_reg(16); save_gp_reg(17); save_gp_reg(18);
2364 save_gp_reg(19); save_gp_reg(20); save_gp_reg(21); save_gp_reg(22);
2365 save_gp_reg(23); save_gp_reg(24); save_gp_reg(25); save_gp_reg(26);
2366 save_gp_reg(27); save_gp_reg(28); save_gp_reg(29); save_gp_reg(30);
2370 err
|= __put_user(regs
->active_tc
.HI
[0], &sc
->sc_mdhi
);
2371 err
|= __put_user(regs
->active_tc
.LO
[0], &sc
->sc_mdlo
);
2373 /* Not used yet, but might be useful if we ever have DSP suppport */
2376 err
|= __put_user(mfhi1(), &sc
->sc_hi1
);
2377 err
|= __put_user(mflo1(), &sc
->sc_lo1
);
2378 err
|= __put_user(mfhi2(), &sc
->sc_hi2
);
2379 err
|= __put_user(mflo2(), &sc
->sc_lo2
);
2380 err
|= __put_user(mfhi3(), &sc
->sc_hi3
);
2381 err
|= __put_user(mflo3(), &sc
->sc_lo3
);
2382 err
|= __put_user(rddsp(DSP_MASK
), &sc
->sc_dsp
);
2384 /* same with 64 bit */
2386 err
|= __put_user(regs
->hi
, &sc
->sc_hi
[0]);
2387 err
|= __put_user(regs
->lo
, &sc
->sc_lo
[0]);
2389 err
|= __put_user(mfhi1(), &sc
->sc_hi
[1]);
2390 err
|= __put_user(mflo1(), &sc
->sc_lo
[1]);
2391 err
|= __put_user(mfhi2(), &sc
->sc_hi
[2]);
2392 err
|= __put_user(mflo2(), &sc
->sc_lo
[2]);
2393 err
|= __put_user(mfhi3(), &sc
->sc_hi
[3]);
2394 err
|= __put_user(mflo3(), &sc
->sc_lo
[3]);
2395 err
|= __put_user(rddsp(DSP_MASK
), &sc
->sc_dsp
);
2401 err
|= __put_user(!!used_math(), &sc
->sc_used_math
);
2407 * Save FPU state to signal context. Signal handler will "inherit"
2408 * current FPU state.
2412 if (!is_fpu_owner()) {
2414 restore_fp(current
);
2416 err
|= save_fp_context(sc
);
2425 restore_sigcontext(CPUState
*regs
, struct target_sigcontext
*sc
)
2429 err
|= __get_user(regs
->CP0_EPC
, &sc
->sc_pc
);
2431 err
|= __get_user(regs
->active_tc
.HI
[0], &sc
->sc_mdhi
);
2432 err
|= __get_user(regs
->active_tc
.LO
[0], &sc
->sc_mdlo
);
2434 #define restore_gp_reg(i) do { \
2435 err |= __get_user(regs->active_tc.gpr[i], &sc->sc_regs[i]); \
2437 restore_gp_reg( 1); restore_gp_reg( 2); restore_gp_reg( 3);
2438 restore_gp_reg( 4); restore_gp_reg( 5); restore_gp_reg( 6);
2439 restore_gp_reg( 7); restore_gp_reg( 8); restore_gp_reg( 9);
2440 restore_gp_reg(10); restore_gp_reg(11); restore_gp_reg(12);
2441 restore_gp_reg(13); restore_gp_reg(14); restore_gp_reg(15);
2442 restore_gp_reg(16); restore_gp_reg(17); restore_gp_reg(18);
2443 restore_gp_reg(19); restore_gp_reg(20); restore_gp_reg(21);
2444 restore_gp_reg(22); restore_gp_reg(23); restore_gp_reg(24);
2445 restore_gp_reg(25); restore_gp_reg(26); restore_gp_reg(27);
2446 restore_gp_reg(28); restore_gp_reg(29); restore_gp_reg(30);
2448 #undef restore_gp_reg
2452 err
|= __get_user(treg
, &sc
->sc_hi1
); mthi1(treg
);
2453 err
|= __get_user(treg
, &sc
->sc_lo1
); mtlo1(treg
);
2454 err
|= __get_user(treg
, &sc
->sc_hi2
); mthi2(treg
);
2455 err
|= __get_user(treg
, &sc
->sc_lo2
); mtlo2(treg
);
2456 err
|= __get_user(treg
, &sc
->sc_hi3
); mthi3(treg
);
2457 err
|= __get_user(treg
, &sc
->sc_lo3
); mtlo3(treg
);
2458 err
|= __get_user(treg
, &sc
->sc_dsp
); wrdsp(treg
, DSP_MASK
);
2461 err
|= __get_user(regs
->hi
, &sc
->sc_hi
[0]);
2462 err
|= __get_user(regs
->lo
, &sc
->sc_lo
[0]);
2464 err
|= __get_user(treg
, &sc
->sc_hi
[1]); mthi1(treg
);
2465 err
|= __get_user(treg
, &sc
->sc_lo
[1]); mthi1(treg
);
2466 err
|= __get_user(treg
, &sc
->sc_hi
[2]); mthi2(treg
);
2467 err
|= __get_user(treg
, &sc
->sc_lo
[2]); mthi2(treg
);
2468 err
|= __get_user(treg
, &sc
->sc_hi
[3]); mthi3(treg
);
2469 err
|= __get_user(treg
, &sc
->sc_lo
[3]); mthi3(treg
);
2470 err
|= __get_user(treg
, &sc
->sc_dsp
); wrdsp(treg
, DSP_MASK
);
2474 err
|= __get_user(used_math
, &sc
->sc_used_math
);
2475 conditional_used_math(used_math
);
2480 /* restore fpu context if we have used it before */
2482 err
|= restore_fp_context(sc
);
2484 /* signal handler may have used FPU. Give it up. */
2493 * Determine which stack to use..
2495 static inline abi_ulong
2496 get_sigframe(struct target_sigaction
*ka
, CPUState
*regs
, size_t frame_size
)
2500 /* Default to using normal stack */
2501 sp
= regs
->active_tc
.gpr
[29];
2504 * FPU emulator may have it's own trampoline active just
2505 * above the user stack, 16-bytes before the next lowest
2506 * 16 byte boundary. Try to avoid trashing it.
2510 /* This is the X/Open sanctioned signal stack switching. */
2511 if ((ka
->sa_flags
& TARGET_SA_ONSTACK
) && (sas_ss_flags (sp
) == 0)) {
2512 sp
= target_sigaltstack_used
.ss_sp
+ target_sigaltstack_used
.ss_size
;
2515 return (sp
- frame_size
) & ~7;
2518 /* compare linux/arch/mips/kernel/signal.c:setup_frame() */
2519 static void setup_frame(int sig
, struct target_sigaction
* ka
,
2520 target_sigset_t
*set
, CPUState
*regs
)
2522 struct sigframe
*frame
;
2523 abi_ulong frame_addr
;
2526 frame_addr
= get_sigframe(ka
, regs
, sizeof(*frame
));
2527 if (!lock_user_struct(VERIFY_WRITE
, frame
, frame_addr
, 0))
2530 install_sigtramp(frame
->sf_code
, TARGET_NR_sigreturn
);
2532 if(setup_sigcontext(regs
, &frame
->sf_sc
))
2535 for(i
= 0; i
< TARGET_NSIG_WORDS
; i
++) {
2536 if(__put_user(set
->sig
[i
], &frame
->sf_mask
.sig
[i
]))
2541 * Arguments to signal handler:
2543 * a0 = signal number
2544 * a1 = 0 (should be cause)
2545 * a2 = pointer to struct sigcontext
2547 * $25 and PC point to the signal handler, $29 points to the
2550 regs
->active_tc
.gpr
[ 4] = sig
;
2551 regs
->active_tc
.gpr
[ 5] = 0;
2552 regs
->active_tc
.gpr
[ 6] = frame_addr
+ offsetof(struct sigframe
, sf_sc
);
2553 regs
->active_tc
.gpr
[29] = frame_addr
;
2554 regs
->active_tc
.gpr
[31] = frame_addr
+ offsetof(struct sigframe
, sf_code
);
2555 /* The original kernel code sets CP0_EPC to the handler
2556 * since it returns to userland using eret
2557 * we cannot do this here, and we must set PC directly */
2558 regs
->active_tc
.PC
= regs
->active_tc
.gpr
[25] = ka
->_sa_handler
;
2559 unlock_user_struct(frame
, frame_addr
, 1);
2563 unlock_user_struct(frame
, frame_addr
, 1);
2564 force_sig(TARGET_SIGSEGV
/*, current*/);
2568 long do_sigreturn(CPUState
*regs
)
2570 struct sigframe
*frame
;
2571 abi_ulong frame_addr
;
2573 target_sigset_t target_set
;
2576 #if defined(DEBUG_SIGNAL)
2577 fprintf(stderr
, "do_sigreturn\n");
2579 frame_addr
= regs
->active_tc
.gpr
[29];
2580 if (!lock_user_struct(VERIFY_READ
, frame
, frame_addr
, 1))
2583 for(i
= 0; i
< TARGET_NSIG_WORDS
; i
++) {
2584 if(__get_user(target_set
.sig
[i
], &frame
->sf_mask
.sig
[i
]))
2588 target_to_host_sigset_internal(&blocked
, &target_set
);
2589 sigprocmask(SIG_SETMASK
, &blocked
, NULL
);
2591 if (restore_sigcontext(regs
, &frame
->sf_sc
))
2596 * Don't let your children do this ...
2598 __asm__
__volatile__(
2606 regs
->active_tc
.PC
= regs
->CP0_EPC
;
2607 /* I am not sure this is right, but it seems to work
2608 * maybe a problem with nested signals ? */
2610 return -TARGET_QEMU_ESIGRETURN
;
2613 force_sig(TARGET_SIGSEGV
/*, current*/);
2617 static void setup_rt_frame(int sig
, struct target_sigaction
*ka
,
2618 target_siginfo_t
*info
,
2619 target_sigset_t
*set
, CPUState
*env
)
2621 struct target_rt_sigframe
*frame
;
2622 abi_ulong frame_addr
;
2625 frame_addr
= get_sigframe(ka
, env
, sizeof(*frame
));
2626 if (!lock_user_struct(VERIFY_WRITE
, frame
, frame_addr
, 0))
2629 install_sigtramp(frame
->rs_code
, TARGET_NR_rt_sigreturn
);
2631 copy_siginfo_to_user(&frame
->rs_info
, info
);
2633 __put_user(0, &frame
->rs_uc
.uc_flags
);
2634 __put_user(0, &frame
->rs_uc
.uc_link
);
2635 __put_user(target_sigaltstack_used
.ss_sp
, &frame
->rs_uc
.uc_stack
.ss_sp
);
2636 __put_user(target_sigaltstack_used
.ss_size
, &frame
->rs_uc
.uc_stack
.ss_size
);
2637 __put_user(sas_ss_flags(get_sp_from_cpustate(env
)),
2638 &frame
->rs_uc
.uc_stack
.ss_flags
);
2640 setup_sigcontext(env
, &frame
->rs_uc
.uc_mcontext
);
2642 for(i
= 0; i
< TARGET_NSIG_WORDS
; i
++) {
2643 __put_user(set
->sig
[i
], &frame
->rs_uc
.uc_sigmask
.sig
[i
]);
2647 * Arguments to signal handler:
2649 * a0 = signal number
2650 * a1 = pointer to struct siginfo
2651 * a2 = pointer to struct ucontext
2653 * $25 and PC point to the signal handler, $29 points to the
2656 env
->active_tc
.gpr
[ 4] = sig
;
2657 env
->active_tc
.gpr
[ 5] = frame_addr
2658 + offsetof(struct target_rt_sigframe
, rs_info
);
2659 env
->active_tc
.gpr
[ 6] = frame_addr
2660 + offsetof(struct target_rt_sigframe
, rs_uc
);
2661 env
->active_tc
.gpr
[29] = frame_addr
;
2662 env
->active_tc
.gpr
[31] = frame_addr
2663 + offsetof(struct target_rt_sigframe
, rs_code
);
2664 /* The original kernel code sets CP0_EPC to the handler
2665 * since it returns to userland using eret
2666 * we cannot do this here, and we must set PC directly */
2667 env
->active_tc
.PC
= env
->active_tc
.gpr
[25] = ka
->_sa_handler
;
2668 unlock_user_struct(frame
, frame_addr
, 1);
2672 unlock_user_struct(frame
, frame_addr
, 1);
2673 force_sig(TARGET_SIGSEGV
/*, current*/);
2677 long do_rt_sigreturn(CPUState
*env
)
2679 struct target_rt_sigframe
*frame
;
2680 abi_ulong frame_addr
;
2683 #if defined(DEBUG_SIGNAL)
2684 fprintf(stderr
, "do_rt_sigreturn\n");
2686 frame_addr
= env
->active_tc
.gpr
[29];
2687 if (!lock_user_struct(VERIFY_READ
, frame
, frame_addr
, 1))
2690 target_to_host_sigset(&blocked
, &frame
->rs_uc
.uc_sigmask
);
2691 sigprocmask(SIG_SETMASK
, &blocked
, NULL
);
2693 if (restore_sigcontext(env
, &frame
->rs_uc
.uc_mcontext
))
2696 if (do_sigaltstack(frame_addr
+
2697 offsetof(struct target_rt_sigframe
, rs_uc
.uc_stack
),
2698 0, get_sp_from_cpustate(env
)) == -EFAULT
)
2701 env
->active_tc
.PC
= env
->CP0_EPC
;
2702 /* I am not sure this is right, but it seems to work
2703 * maybe a problem with nested signals ? */
2705 return -TARGET_QEMU_ESIGRETURN
;
2708 force_sig(TARGET_SIGSEGV
/*, current*/);
2712 #elif defined(TARGET_SH4)
2715 * code and data structures from linux kernel:
2716 * include/asm-sh/sigcontext.h
2717 * arch/sh/kernel/signal.c
2720 struct target_sigcontext
{
2721 target_ulong oldmask
;
2724 target_ulong sc_gregs
[16];
2728 target_ulong sc_gbr
;
2729 target_ulong sc_mach
;
2730 target_ulong sc_macl
;
2733 target_ulong sc_fpregs
[16];
2734 target_ulong sc_xfpregs
[16];
2735 unsigned int sc_fpscr
;
2736 unsigned int sc_fpul
;
2737 unsigned int sc_ownedfp
;
2740 struct target_sigframe
2742 struct target_sigcontext sc
;
2743 target_ulong extramask
[TARGET_NSIG_WORDS
-1];
2744 uint16_t retcode
[3];
2748 struct target_ucontext
{
2749 target_ulong uc_flags
;
2750 struct target_ucontext
*uc_link
;
2751 target_stack_t uc_stack
;
2752 struct target_sigcontext uc_mcontext
;
2753 target_sigset_t uc_sigmask
; /* mask last for extensibility */
2756 struct target_rt_sigframe
2758 struct target_siginfo info
;
2759 struct target_ucontext uc
;
2760 uint16_t retcode
[3];
2764 #define MOVW(n) (0x9300|((n)-2)) /* Move mem word at PC+n to R3 */
2765 #define TRAP_NOARG 0xc310 /* Syscall w/no args (NR in R3) SH3/4 */
2767 static abi_ulong
get_sigframe(struct target_sigaction
*ka
,
2768 unsigned long sp
, size_t frame_size
)
2770 if ((ka
->sa_flags
& TARGET_SA_ONSTACK
) && (sas_ss_flags(sp
) == 0)) {
2771 sp
= target_sigaltstack_used
.ss_sp
+ target_sigaltstack_used
.ss_size
;
2774 return (sp
- frame_size
) & -8ul;
2777 static int setup_sigcontext(struct target_sigcontext
*sc
,
2778 CPUState
*regs
, unsigned long mask
)
2782 #define COPY(x) err |= __put_user(regs->x, &sc->sc_##x)
2783 COPY(gregs
[0]); COPY(gregs
[1]);
2784 COPY(gregs
[2]); COPY(gregs
[3]);
2785 COPY(gregs
[4]); COPY(gregs
[5]);
2786 COPY(gregs
[6]); COPY(gregs
[7]);
2787 COPY(gregs
[8]); COPY(gregs
[9]);
2788 COPY(gregs
[10]); COPY(gregs
[11]);
2789 COPY(gregs
[12]); COPY(gregs
[13]);
2790 COPY(gregs
[14]); COPY(gregs
[15]);
2791 COPY(gbr
); COPY(mach
);
2792 COPY(macl
); COPY(pr
);
2796 /* todo: save FPU registers here */
2798 /* non-iBCS2 extensions.. */
2799 err
|= __put_user(mask
, &sc
->oldmask
);
2804 static int restore_sigcontext(CPUState
*regs
,
2805 struct target_sigcontext
*sc
)
2807 unsigned int err
= 0;
2809 #define COPY(x) err |= __get_user(regs->x, &sc->sc_##x)
2811 COPY(gregs
[2]); COPY(gregs
[3]);
2812 COPY(gregs
[4]); COPY(gregs
[5]);
2813 COPY(gregs
[6]); COPY(gregs
[7]);
2814 COPY(gregs
[8]); COPY(gregs
[9]);
2815 COPY(gregs
[10]); COPY(gregs
[11]);
2816 COPY(gregs
[12]); COPY(gregs
[13]);
2817 COPY(gregs
[14]); COPY(gregs
[15]);
2818 COPY(gbr
); COPY(mach
);
2819 COPY(macl
); COPY(pr
);
2823 /* todo: restore FPU registers here */
2825 regs
->tra
= -1; /* disable syscall checks */
2829 static void setup_frame(int sig
, struct target_sigaction
*ka
,
2830 target_sigset_t
*set
, CPUState
*regs
)
2832 struct target_sigframe
*frame
;
2833 abi_ulong frame_addr
;
2838 frame_addr
= get_sigframe(ka
, regs
->gregs
[15], sizeof(*frame
));
2839 if (!lock_user_struct(VERIFY_WRITE
, frame
, frame_addr
, 0))
2842 signal
= current_exec_domain_sig(sig
);
2844 err
|= setup_sigcontext(&frame
->sc
, regs
, set
->sig
[0]);
2846 for (i
= 0; i
< TARGET_NSIG_WORDS
- 1; i
++) {
2847 err
|= __put_user(set
->sig
[i
+ 1], &frame
->extramask
[i
]);
2850 /* Set up to return from userspace. If provided, use a stub
2851 already in userspace. */
2852 if (ka
->sa_flags
& TARGET_SA_RESTORER
) {
2853 regs
->pr
= (unsigned long) ka
->sa_restorer
;
2855 /* Generate return code (system call to sigreturn) */
2856 err
|= __put_user(MOVW(2), &frame
->retcode
[0]);
2857 err
|= __put_user(TRAP_NOARG
, &frame
->retcode
[1]);
2858 err
|= __put_user((TARGET_NR_sigreturn
), &frame
->retcode
[2]);
2859 regs
->pr
= (unsigned long) frame
->retcode
;
2865 /* Set up registers for signal handler */
2866 regs
->gregs
[15] = (unsigned long) frame
;
2867 regs
->gregs
[4] = signal
; /* Arg for signal handler */
2869 regs
->gregs
[6] = (unsigned long) &frame
->sc
;
2870 regs
->pc
= (unsigned long) ka
->_sa_handler
;
2872 unlock_user_struct(frame
, frame_addr
, 1);
2876 unlock_user_struct(frame
, frame_addr
, 1);
2880 static void setup_rt_frame(int sig
, struct target_sigaction
*ka
,
2881 target_siginfo_t
*info
,
2882 target_sigset_t
*set
, CPUState
*regs
)
2884 struct target_rt_sigframe
*frame
;
2885 abi_ulong frame_addr
;
2890 frame_addr
= get_sigframe(ka
, regs
->gregs
[15], sizeof(*frame
));
2891 if (!lock_user_struct(VERIFY_WRITE
, frame
, frame_addr
, 0))
2894 signal
= current_exec_domain_sig(sig
);
2896 err
|= copy_siginfo_to_user(&frame
->info
, info
);
2898 /* Create the ucontext. */
2899 err
|= __put_user(0, &frame
->uc
.uc_flags
);
2900 err
|= __put_user(0, (unsigned long *)&frame
->uc
.uc_link
);
2901 err
|= __put_user((unsigned long)target_sigaltstack_used
.ss_sp
,
2902 &frame
->uc
.uc_stack
.ss_sp
);
2903 err
|= __put_user(sas_ss_flags(regs
->gregs
[15]),
2904 &frame
->uc
.uc_stack
.ss_flags
);
2905 err
|= __put_user(target_sigaltstack_used
.ss_size
,
2906 &frame
->uc
.uc_stack
.ss_size
);
2907 err
|= setup_sigcontext(&frame
->uc
.uc_mcontext
,
2909 for(i
= 0; i
< TARGET_NSIG_WORDS
; i
++) {
2910 err
|= __put_user(set
->sig
[i
], &frame
->uc
.uc_sigmask
.sig
[i
]);
2913 /* Set up to return from userspace. If provided, use a stub
2914 already in userspace. */
2915 if (ka
->sa_flags
& TARGET_SA_RESTORER
) {
2916 regs
->pr
= (unsigned long) ka
->sa_restorer
;
2918 /* Generate return code (system call to sigreturn) */
2919 err
|= __put_user(MOVW(2), &frame
->retcode
[0]);
2920 err
|= __put_user(TRAP_NOARG
, &frame
->retcode
[1]);
2921 err
|= __put_user((TARGET_NR_rt_sigreturn
), &frame
->retcode
[2]);
2922 regs
->pr
= (unsigned long) frame
->retcode
;
2928 /* Set up registers for signal handler */
2929 regs
->gregs
[15] = (unsigned long) frame
;
2930 regs
->gregs
[4] = signal
; /* Arg for signal handler */
2931 regs
->gregs
[5] = (unsigned long) &frame
->info
;
2932 regs
->gregs
[6] = (unsigned long) &frame
->uc
;
2933 regs
->pc
= (unsigned long) ka
->_sa_handler
;
2935 unlock_user_struct(frame
, frame_addr
, 1);
2939 unlock_user_struct(frame
, frame_addr
, 1);
2943 long do_sigreturn(CPUState
*regs
)
2945 struct target_sigframe
*frame
;
2946 abi_ulong frame_addr
;
2948 target_sigset_t target_set
;
2952 #if defined(DEBUG_SIGNAL)
2953 fprintf(stderr
, "do_sigreturn\n");
2955 frame_addr
= regs
->gregs
[15];
2956 if (!lock_user_struct(VERIFY_READ
, frame
, frame_addr
, 1))
2959 err
|= __get_user(target_set
.sig
[0], &frame
->sc
.oldmask
);
2960 for(i
= 1; i
< TARGET_NSIG_WORDS
; i
++) {
2961 err
|= (__get_user(target_set
.sig
[i
], &frame
->extramask
[i
- 1]));
2967 target_to_host_sigset_internal(&blocked
, &target_set
);
2968 sigprocmask(SIG_SETMASK
, &blocked
, NULL
);
2970 if (restore_sigcontext(regs
, &frame
->sc
))
2973 unlock_user_struct(frame
, frame_addr
, 0);
2974 return regs
->gregs
[0];
2977 unlock_user_struct(frame
, frame_addr
, 0);
2978 force_sig(TARGET_SIGSEGV
);
2982 long do_rt_sigreturn(CPUState
*regs
)
2984 struct target_rt_sigframe
*frame
;
2985 abi_ulong frame_addr
;
2988 #if defined(DEBUG_SIGNAL)
2989 fprintf(stderr
, "do_rt_sigreturn\n");
2991 frame_addr
= regs
->gregs
[15];
2992 if (!lock_user_struct(VERIFY_READ
, frame
, frame_addr
, 1))
2995 target_to_host_sigset(&blocked
, &frame
->uc
.uc_sigmask
);
2996 sigprocmask(SIG_SETMASK
, &blocked
, NULL
);
2998 if (restore_sigcontext(regs
, &frame
->uc
.uc_mcontext
))
3001 if (do_sigaltstack(frame_addr
+
3002 offsetof(struct target_rt_sigframe
, uc
.uc_stack
),
3003 0, get_sp_from_cpustate(regs
)) == -EFAULT
)
3006 unlock_user_struct(frame
, frame_addr
, 0);
3007 return regs
->gregs
[0];
3010 unlock_user_struct(frame
, frame_addr
, 0);
3011 force_sig(TARGET_SIGSEGV
);
3014 #elif defined(TARGET_MICROBLAZE)
3016 struct target_sigcontext
{
3017 struct target_pt_regs regs
; /* needs to be first */
3021 /* Signal frames. */
3022 struct target_signal_frame
{
3023 struct target_sigcontext sc
;
3024 uint32_t extramask
[TARGET_NSIG_WORDS
- 1];
3028 struct rt_signal_frame
{
3029 struct siginfo info
;
3034 static void setup_sigcontext(struct target_sigcontext
*sc
, CPUState
*env
)
3036 __put_user(env
->regs
[0], &sc
->regs
.r0
);
3037 __put_user(env
->regs
[1], &sc
->regs
.r1
);
3038 __put_user(env
->regs
[2], &sc
->regs
.r2
);
3039 __put_user(env
->regs
[3], &sc
->regs
.r3
);
3040 __put_user(env
->regs
[4], &sc
->regs
.r4
);
3041 __put_user(env
->regs
[5], &sc
->regs
.r5
);
3042 __put_user(env
->regs
[6], &sc
->regs
.r6
);
3043 __put_user(env
->regs
[7], &sc
->regs
.r7
);
3044 __put_user(env
->regs
[8], &sc
->regs
.r8
);
3045 __put_user(env
->regs
[9], &sc
->regs
.r9
);
3046 __put_user(env
->regs
[10], &sc
->regs
.r10
);
3047 __put_user(env
->regs
[11], &sc
->regs
.r11
);
3048 __put_user(env
->regs
[12], &sc
->regs
.r12
);
3049 __put_user(env
->regs
[13], &sc
->regs
.r13
);
3050 __put_user(env
->regs
[14], &sc
->regs
.r14
);
3051 __put_user(env
->regs
[15], &sc
->regs
.r15
);
3052 __put_user(env
->regs
[16], &sc
->regs
.r16
);
3053 __put_user(env
->regs
[17], &sc
->regs
.r17
);
3054 __put_user(env
->regs
[18], &sc
->regs
.r18
);
3055 __put_user(env
->regs
[19], &sc
->regs
.r19
);
3056 __put_user(env
->regs
[20], &sc
->regs
.r20
);
3057 __put_user(env
->regs
[21], &sc
->regs
.r21
);
3058 __put_user(env
->regs
[22], &sc
->regs
.r22
);
3059 __put_user(env
->regs
[23], &sc
->regs
.r23
);
3060 __put_user(env
->regs
[24], &sc
->regs
.r24
);
3061 __put_user(env
->regs
[25], &sc
->regs
.r25
);
3062 __put_user(env
->regs
[26], &sc
->regs
.r26
);
3063 __put_user(env
->regs
[27], &sc
->regs
.r27
);
3064 __put_user(env
->regs
[28], &sc
->regs
.r28
);
3065 __put_user(env
->regs
[29], &sc
->regs
.r29
);
3066 __put_user(env
->regs
[30], &sc
->regs
.r30
);
3067 __put_user(env
->regs
[31], &sc
->regs
.r31
);
3068 __put_user(env
->sregs
[SR_PC
], &sc
->regs
.pc
);
3071 static void restore_sigcontext(struct target_sigcontext
*sc
, CPUState
*env
)
3073 __get_user(env
->regs
[0], &sc
->regs
.r0
);
3074 __get_user(env
->regs
[1], &sc
->regs
.r1
);
3075 __get_user(env
->regs
[2], &sc
->regs
.r2
);
3076 __get_user(env
->regs
[3], &sc
->regs
.r3
);
3077 __get_user(env
->regs
[4], &sc
->regs
.r4
);
3078 __get_user(env
->regs
[5], &sc
->regs
.r5
);
3079 __get_user(env
->regs
[6], &sc
->regs
.r6
);
3080 __get_user(env
->regs
[7], &sc
->regs
.r7
);
3081 __get_user(env
->regs
[8], &sc
->regs
.r8
);
3082 __get_user(env
->regs
[9], &sc
->regs
.r9
);
3083 __get_user(env
->regs
[10], &sc
->regs
.r10
);
3084 __get_user(env
->regs
[11], &sc
->regs
.r11
);
3085 __get_user(env
->regs
[12], &sc
->regs
.r12
);
3086 __get_user(env
->regs
[13], &sc
->regs
.r13
);
3087 __get_user(env
->regs
[14], &sc
->regs
.r14
);
3088 __get_user(env
->regs
[15], &sc
->regs
.r15
);
3089 __get_user(env
->regs
[16], &sc
->regs
.r16
);
3090 __get_user(env
->regs
[17], &sc
->regs
.r17
);
3091 __get_user(env
->regs
[18], &sc
->regs
.r18
);
3092 __get_user(env
->regs
[19], &sc
->regs
.r19
);
3093 __get_user(env
->regs
[20], &sc
->regs
.r20
);
3094 __get_user(env
->regs
[21], &sc
->regs
.r21
);
3095 __get_user(env
->regs
[22], &sc
->regs
.r22
);
3096 __get_user(env
->regs
[23], &sc
->regs
.r23
);
3097 __get_user(env
->regs
[24], &sc
->regs
.r24
);
3098 __get_user(env
->regs
[25], &sc
->regs
.r25
);
3099 __get_user(env
->regs
[26], &sc
->regs
.r26
);
3100 __get_user(env
->regs
[27], &sc
->regs
.r27
);
3101 __get_user(env
->regs
[28], &sc
->regs
.r28
);
3102 __get_user(env
->regs
[29], &sc
->regs
.r29
);
3103 __get_user(env
->regs
[30], &sc
->regs
.r30
);
3104 __get_user(env
->regs
[31], &sc
->regs
.r31
);
3105 __get_user(env
->sregs
[SR_PC
], &sc
->regs
.pc
);
3108 static abi_ulong
get_sigframe(struct target_sigaction
*ka
,
3109 CPUState
*env
, int frame_size
)
3111 abi_ulong sp
= env
->regs
[1];
3113 if ((ka
->sa_flags
& SA_ONSTACK
) != 0 && !on_sig_stack(sp
))
3114 sp
= target_sigaltstack_used
.ss_sp
+ target_sigaltstack_used
.ss_size
;
3116 return ((sp
- frame_size
) & -8UL);
3119 static void setup_frame(int sig
, struct target_sigaction
*ka
,
3120 target_sigset_t
*set
, CPUState
*env
)
3122 struct target_signal_frame
*frame
;
3123 abi_ulong frame_addr
;
3127 frame_addr
= get_sigframe(ka
, env
, sizeof *frame
);
3128 if (!lock_user_struct(VERIFY_WRITE
, frame
, frame_addr
, 0))
3131 /* Save the mask. */
3132 err
|= __put_user(set
->sig
[0], &frame
->sc
.oldmask
);
3136 for(i
= 1; i
< TARGET_NSIG_WORDS
; i
++) {
3137 if (__put_user(set
->sig
[i
], &frame
->extramask
[i
- 1]))
3141 setup_sigcontext(&frame
->sc
, env
);
3143 /* Set up to return from userspace. If provided, use a stub
3144 already in userspace. */
3145 /* minus 8 is offset to cater for "rtsd r15,8" offset */
3146 if (ka
->sa_flags
& TARGET_SA_RESTORER
) {
3147 env
->regs
[15] = ((unsigned long)ka
->sa_restorer
)-8;
3150 /* Note, these encodings are _big endian_! */
3151 /* addi r12, r0, __NR_sigreturn */
3152 t
= 0x31800000UL
| TARGET_NR_sigreturn
;
3153 err
|= __put_user(t
, frame
->tramp
+ 0);
3156 err
|= __put_user(t
, frame
->tramp
+ 1);
3158 /* Return from sighandler will jump to the tramp.
3159 Negative 8 offset because return is rtsd r15, 8 */
3160 env
->regs
[15] = ((unsigned long)frame
->tramp
) - 8;
3166 /* Set up registers for signal handler */
3167 env
->regs
[1] = (unsigned long) frame
;
3168 /* Signal handler args: */
3169 env
->regs
[5] = sig
; /* Arg 0: signum */
3170 env
->regs
[6] = (unsigned long) &frame
->sc
; /* arg 1: sigcontext */
3172 /* Offset of 4 to handle microblaze rtid r14, 0 */
3173 env
->sregs
[SR_PC
] = (unsigned long)ka
->_sa_handler
;
3175 unlock_user_struct(frame
, frame_addr
, 1);
3178 unlock_user_struct(frame
, frame_addr
, 1);
3179 force_sig(TARGET_SIGSEGV
);
3182 static void setup_rt_frame(int sig
, struct target_sigaction
*ka
,
3183 target_siginfo_t
*info
,
3184 target_sigset_t
*set
, CPUState
*env
)
3186 fprintf(stderr
, "Microblaze setup_rt_frame: not implemented\n");
3189 long do_sigreturn(CPUState
*env
)
3191 struct target_signal_frame
*frame
;
3192 abi_ulong frame_addr
;
3193 target_sigset_t target_set
;
3197 frame_addr
= env
->regs
[R_SP
];
3198 /* Make sure the guest isn't playing games. */
3199 if (!lock_user_struct(VERIFY_WRITE
, frame
, frame_addr
, 1))
3202 /* Restore blocked signals */
3203 if (__get_user(target_set
.sig
[0], &frame
->sc
.oldmask
))
3205 for(i
= 1; i
< TARGET_NSIG_WORDS
; i
++) {
3206 if (__get_user(target_set
.sig
[i
], &frame
->extramask
[i
- 1]))
3209 target_to_host_sigset_internal(&set
, &target_set
);
3210 sigprocmask(SIG_SETMASK
, &set
, NULL
);
3212 restore_sigcontext(&frame
->sc
, env
);
3213 /* We got here through a sigreturn syscall, our path back is via an
3214 rtb insn so setup r14 for that. */
3215 env
->regs
[14] = env
->sregs
[SR_PC
];
3217 unlock_user_struct(frame
, frame_addr
, 0);
3218 return env
->regs
[10];
3220 unlock_user_struct(frame
, frame_addr
, 0);
3221 force_sig(TARGET_SIGSEGV
);
3224 long do_rt_sigreturn(CPUState
*env
)
3226 fprintf(stderr
, "Microblaze do_rt_sigreturn: not implemented\n");
3227 return -TARGET_ENOSYS
;
3230 #elif defined(TARGET_CRIS)
3232 struct target_sigcontext
{
3233 struct target_pt_regs regs
; /* needs to be first */
3235 uint32_t usp
; /* usp before stacking this gunk on it */
3238 /* Signal frames. */
3239 struct target_signal_frame
{
3240 struct target_sigcontext sc
;
3241 uint32_t extramask
[TARGET_NSIG_WORDS
- 1];
3242 uint8_t retcode
[8]; /* Trampoline code. */
3245 struct rt_signal_frame
{
3246 struct siginfo
*pinfo
;
3248 struct siginfo info
;
3250 uint8_t retcode
[8]; /* Trampoline code. */
3253 static void setup_sigcontext(struct target_sigcontext
*sc
, CPUState
*env
)
3255 __put_user(env
->regs
[0], &sc
->regs
.r0
);
3256 __put_user(env
->regs
[1], &sc
->regs
.r1
);
3257 __put_user(env
->regs
[2], &sc
->regs
.r2
);
3258 __put_user(env
->regs
[3], &sc
->regs
.r3
);
3259 __put_user(env
->regs
[4], &sc
->regs
.r4
);
3260 __put_user(env
->regs
[5], &sc
->regs
.r5
);
3261 __put_user(env
->regs
[6], &sc
->regs
.r6
);
3262 __put_user(env
->regs
[7], &sc
->regs
.r7
);
3263 __put_user(env
->regs
[8], &sc
->regs
.r8
);
3264 __put_user(env
->regs
[9], &sc
->regs
.r9
);
3265 __put_user(env
->regs
[10], &sc
->regs
.r10
);
3266 __put_user(env
->regs
[11], &sc
->regs
.r11
);
3267 __put_user(env
->regs
[12], &sc
->regs
.r12
);
3268 __put_user(env
->regs
[13], &sc
->regs
.r13
);
3269 __put_user(env
->regs
[14], &sc
->usp
);
3270 __put_user(env
->regs
[15], &sc
->regs
.acr
);
3271 __put_user(env
->pregs
[PR_MOF
], &sc
->regs
.mof
);
3272 __put_user(env
->pregs
[PR_SRP
], &sc
->regs
.srp
);
3273 __put_user(env
->pc
, &sc
->regs
.erp
);
3276 static void restore_sigcontext(struct target_sigcontext
*sc
, CPUState
*env
)
3278 __get_user(env
->regs
[0], &sc
->regs
.r0
);
3279 __get_user(env
->regs
[1], &sc
->regs
.r1
);
3280 __get_user(env
->regs
[2], &sc
->regs
.r2
);
3281 __get_user(env
->regs
[3], &sc
->regs
.r3
);
3282 __get_user(env
->regs
[4], &sc
->regs
.r4
);
3283 __get_user(env
->regs
[5], &sc
->regs
.r5
);
3284 __get_user(env
->regs
[6], &sc
->regs
.r6
);
3285 __get_user(env
->regs
[7], &sc
->regs
.r7
);
3286 __get_user(env
->regs
[8], &sc
->regs
.r8
);
3287 __get_user(env
->regs
[9], &sc
->regs
.r9
);
3288 __get_user(env
->regs
[10], &sc
->regs
.r10
);
3289 __get_user(env
->regs
[11], &sc
->regs
.r11
);
3290 __get_user(env
->regs
[12], &sc
->regs
.r12
);
3291 __get_user(env
->regs
[13], &sc
->regs
.r13
);
3292 __get_user(env
->regs
[14], &sc
->usp
);
3293 __get_user(env
->regs
[15], &sc
->regs
.acr
);
3294 __get_user(env
->pregs
[PR_MOF
], &sc
->regs
.mof
);
3295 __get_user(env
->pregs
[PR_SRP
], &sc
->regs
.srp
);
3296 __get_user(env
->pc
, &sc
->regs
.erp
);
3299 static abi_ulong
get_sigframe(CPUState
*env
, int framesize
)
3302 /* Align the stack downwards to 4. */
3303 sp
= (env
->regs
[R_SP
] & ~3);
3304 return sp
- framesize
;
3307 static void setup_frame(int sig
, struct target_sigaction
*ka
,
3308 target_sigset_t
*set
, CPUState
*env
)
3310 struct target_signal_frame
*frame
;
3311 abi_ulong frame_addr
;
3315 frame_addr
= get_sigframe(env
, sizeof *frame
);
3316 if (!lock_user_struct(VERIFY_WRITE
, frame
, frame_addr
, 0))
3320 * The CRIS signal return trampoline. A real linux/CRIS kernel doesn't
3321 * use this trampoline anymore but it sets it up for GDB.
3322 * In QEMU, using the trampoline simplifies things a bit so we use it.
3324 * This is movu.w __NR_sigreturn, r9; break 13;
3326 err
|= __put_user(0x9c5f, frame
->retcode
+0);
3327 err
|= __put_user(TARGET_NR_sigreturn
,
3329 err
|= __put_user(0xe93d, frame
->retcode
+4);
3331 /* Save the mask. */
3332 err
|= __put_user(set
->sig
[0], &frame
->sc
.oldmask
);
3336 for(i
= 1; i
< TARGET_NSIG_WORDS
; i
++) {
3337 if (__put_user(set
->sig
[i
], &frame
->extramask
[i
- 1]))
3341 setup_sigcontext(&frame
->sc
, env
);
3343 /* Move the stack and setup the arguments for the handler. */
3344 env
->regs
[R_SP
] = (uint32_t) (unsigned long) frame
;
3345 env
->regs
[10] = sig
;
3346 env
->pc
= (unsigned long) ka
->_sa_handler
;
3347 /* Link SRP so the guest returns through the trampoline. */
3348 env
->pregs
[PR_SRP
] = (uint32_t) (unsigned long) &frame
->retcode
[0];
3350 unlock_user_struct(frame
, frame_addr
, 1);
3353 unlock_user_struct(frame
, frame_addr
, 1);
3354 force_sig(TARGET_SIGSEGV
);
3357 static void setup_rt_frame(int sig
, struct target_sigaction
*ka
,
3358 target_siginfo_t
*info
,
3359 target_sigset_t
*set
, CPUState
*env
)
3361 fprintf(stderr
, "CRIS setup_rt_frame: not implemented\n");
3364 long do_sigreturn(CPUState
*env
)
3366 struct target_signal_frame
*frame
;
3367 abi_ulong frame_addr
;
3368 target_sigset_t target_set
;
3372 frame_addr
= env
->regs
[R_SP
];
3373 /* Make sure the guest isn't playing games. */
3374 if (!lock_user_struct(VERIFY_WRITE
, frame
, frame_addr
, 1))
3377 /* Restore blocked signals */
3378 if (__get_user(target_set
.sig
[0], &frame
->sc
.oldmask
))
3380 for(i
= 1; i
< TARGET_NSIG_WORDS
; i
++) {
3381 if (__get_user(target_set
.sig
[i
], &frame
->extramask
[i
- 1]))
3384 target_to_host_sigset_internal(&set
, &target_set
);
3385 sigprocmask(SIG_SETMASK
, &set
, NULL
);
3387 restore_sigcontext(&frame
->sc
, env
);
3388 unlock_user_struct(frame
, frame_addr
, 0);
3389 return env
->regs
[10];
3391 unlock_user_struct(frame
, frame_addr
, 0);
3392 force_sig(TARGET_SIGSEGV
);
3395 long do_rt_sigreturn(CPUState
*env
)
3397 fprintf(stderr
, "CRIS do_rt_sigreturn: not implemented\n");
3398 return -TARGET_ENOSYS
;
3401 #elif defined(TARGET_PPC) && !defined(TARGET_PPC64)
3403 /* FIXME: Many of the structures are defined for both PPC and PPC64, but
3404 the signal handling is different enough that we haven't implemented
3405 support for PPC64 yet. Hence the restriction above.
3407 There are various #if'd blocks for code for TARGET_PPC64. These
3408 blocks should go away so that we can successfully run 32-bit and
3409 64-bit binaries on a QEMU configured for PPC64. */
3411 /* Size of dummy stack frame allocated when calling signal handler.
3412 See arch/powerpc/include/asm/ptrace.h. */
3413 #if defined(TARGET_PPC64)
3414 #define SIGNAL_FRAMESIZE 128
3416 #define SIGNAL_FRAMESIZE 64
3419 /* See arch/powerpc/include/asm/sigcontext.h. */
3420 struct target_sigcontext
{
3421 target_ulong _unused
[4];
3423 #if defined(TARGET_PPC64)
3426 target_ulong handler
;
3427 target_ulong oldmask
;
3428 target_ulong regs
; /* struct pt_regs __user * */
3429 /* TODO: PPC64 includes extra bits here. */
3432 /* Indices for target_mcontext.mc_gregs, below.
3433 See arch/powerpc/include/asm/ptrace.h for details. */
3469 TARGET_PT_ORIG_R3
= 34,
3474 /* Yes, there are two registers with #39. One is 64-bit only. */
3476 TARGET_PT_SOFTE
= 39,
3477 TARGET_PT_TRAP
= 40,
3479 TARGET_PT_DSISR
= 42,
3480 TARGET_PT_RESULT
= 43,
3481 TARGET_PT_REGS_COUNT
= 44
3484 /* See arch/powerpc/include/asm/ucontext.h. Only used for 32-bit PPC;
3485 on 64-bit PPC, sigcontext and mcontext are one and the same. */
3486 struct target_mcontext
{
3487 target_ulong mc_gregs
[48];
3488 /* Includes fpscr. */
3489 uint64_t mc_fregs
[33];
3490 target_ulong mc_pad
[2];
3491 /* We need to handle Altivec and SPE at the same time, which no
3492 kernel needs to do. Fortunately, the kernel defines this bit to
3493 be Altivec-register-large all the time, rather than trying to
3494 twiddle it based on the specific platform. */
3496 /* SPE vector registers. One extra for SPEFSCR. */
3498 /* Altivec vector registers. The packing of VSCR and VRSAVE
3499 varies depending on whether we're PPC64 or not: PPC64 splits
3500 them apart; PPC32 stuffs them together. */
3501 #if defined(TARGET_PPC64)
3506 ppc_avr_t altivec
[NVRREG
];
3508 } mc_vregs
__attribute__((__aligned__(16)));
3511 struct target_ucontext
{
3512 target_ulong uc_flags
;
3513 target_ulong uc_link
; /* struct ucontext __user * */
3514 struct target_sigaltstack uc_stack
;
3515 #if !defined(TARGET_PPC64)
3517 target_ulong uc_regs
; /* struct mcontext __user *
3518 points to uc_mcontext field */
3520 target_sigset_t uc_sigmask
;
3521 #if defined(TARGET_PPC64)
3522 target_sigset_t unused
[15]; /* Allow for uc_sigmask growth */
3523 struct target_sigcontext uc_mcontext
;
3525 int32_t uc_maskext
[30];
3527 struct target_mcontext uc_mcontext
;
3531 /* See arch/powerpc/kernel/signal_32.c. */
3532 struct target_sigframe
{
3533 struct target_sigcontext sctx
;
3534 struct target_mcontext mctx
;
3538 struct target_rt_sigframe
{
3539 struct target_siginfo info
;
3540 struct target_ucontext uc
;
3544 /* We use the mc_pad field for the signal return trampoline. */
3545 #define tramp mc_pad
3547 /* See arch/powerpc/kernel/signal.c. */
3548 static target_ulong
get_sigframe(struct target_sigaction
*ka
,
3552 target_ulong oldsp
, newsp
;
3554 oldsp
= env
->gpr
[1];
3556 if ((ka
->sa_flags
& TARGET_SA_ONSTACK
) &&
3557 (sas_ss_flags(oldsp
))) {
3558 oldsp
= (target_sigaltstack_used
.ss_sp
3559 + target_sigaltstack_used
.ss_size
);
3562 newsp
= (oldsp
- frame_size
) & ~0xFUL
;
3567 static int save_user_regs(CPUState
*env
, struct target_mcontext
*frame
,
3570 target_ulong msr
= env
->msr
;
3572 target_ulong ccr
= 0;
3574 /* In general, the kernel attempts to be intelligent about what it
3575 needs to save for Altivec/FP/SPE registers. We don't care that
3576 much, so we just go ahead and save everything. */
3578 /* Save general registers. */
3579 for (i
= 0; i
< ARRAY_SIZE(env
->gpr
); i
++) {
3580 if (__put_user(env
->gpr
[i
], &frame
->mc_gregs
[i
])) {
3584 if (__put_user(env
->nip
, &frame
->mc_gregs
[TARGET_PT_NIP
])
3585 || __put_user(env
->ctr
, &frame
->mc_gregs
[TARGET_PT_CTR
])
3586 || __put_user(env
->lr
, &frame
->mc_gregs
[TARGET_PT_LNK
])
3587 || __put_user(env
->xer
, &frame
->mc_gregs
[TARGET_PT_XER
]))
3590 for (i
= 0; i
< ARRAY_SIZE(env
->crf
); i
++) {
3591 ccr
|= env
->crf
[i
] << (32 - ((i
+ 1) * 4));
3593 if (__put_user(ccr
, &frame
->mc_gregs
[TARGET_PT_CCR
]))
3596 /* Save Altivec registers if necessary. */
3597 if (env
->insns_flags
& PPC_ALTIVEC
) {
3598 for (i
= 0; i
< ARRAY_SIZE(env
->avr
); i
++) {
3599 ppc_avr_t
*avr
= &env
->avr
[i
];
3600 ppc_avr_t
*vreg
= &frame
->mc_vregs
.altivec
[i
];
3602 if (__put_user(avr
->u64
[0], &vreg
->u64
[0]) ||
3603 __put_user(avr
->u64
[1], &vreg
->u64
[1])) {
3607 /* Set MSR_VR in the saved MSR value to indicate that
3608 frame->mc_vregs contains valid data. */
3610 if (__put_user((uint32_t)env
->spr
[SPR_VRSAVE
],
3611 &frame
->mc_vregs
.altivec
[32].u32
[3]))
3615 /* Save floating point registers. */
3616 if (env
->insns_flags
& PPC_FLOAT
) {
3617 for (i
= 0; i
< ARRAY_SIZE(env
->fpr
); i
++) {
3618 if (__put_user(env
->fpr
[i
], &frame
->mc_fregs
[i
])) {
3622 if (__put_user((uint64_t) env
->fpscr
, &frame
->mc_fregs
[32]))
3626 /* Save SPE registers. The kernel only saves the high half. */
3627 if (env
->insns_flags
& PPC_SPE
) {
3628 #if defined(TARGET_PPC64)
3629 for (i
= 0; i
< ARRAY_SIZE(env
->gpr
); i
++) {
3630 if (__put_user(env
->gpr
[i
] >> 32, &frame
->mc_vregs
.spe
[i
])) {
3635 for (i
= 0; i
< ARRAY_SIZE(env
->gprh
); i
++) {
3636 if (__put_user(env
->gprh
[i
], &frame
->mc_vregs
.spe
[i
])) {
3641 /* Set MSR_SPE in the saved MSR value to indicate that
3642 frame->mc_vregs contains valid data. */
3644 if (__put_user(env
->spe_fscr
, &frame
->mc_vregs
.spe
[32]))
3649 if (__put_user(msr
, &frame
->mc_gregs
[TARGET_PT_MSR
]))
3652 /* Set up the sigreturn trampoline: li r0,sigret; sc. */
3654 if (__put_user(0x38000000UL
| sigret
, &frame
->tramp
[0]) ||
3655 __put_user(0x44000002UL
, &frame
->tramp
[1])) {
3663 static int restore_user_regs(CPUState
*env
,
3664 struct target_mcontext
*frame
, int sig
)
3666 target_ulong save_r2
= 0;
3673 save_r2
= env
->gpr
[2];
3676 /* Restore general registers. */
3677 for (i
= 0; i
< ARRAY_SIZE(env
->gpr
); i
++) {
3678 if (__get_user(env
->gpr
[i
], &frame
->mc_gregs
[i
])) {
3682 if (__get_user(env
->nip
, &frame
->mc_gregs
[TARGET_PT_NIP
])
3683 || __get_user(env
->ctr
, &frame
->mc_gregs
[TARGET_PT_CTR
])
3684 || __get_user(env
->lr
, &frame
->mc_gregs
[TARGET_PT_LNK
])
3685 || __get_user(env
->xer
, &frame
->mc_gregs
[TARGET_PT_XER
]))
3687 if (__get_user(ccr
, &frame
->mc_gregs
[TARGET_PT_CCR
]))
3690 for (i
= 0; i
< ARRAY_SIZE(env
->crf
); i
++) {
3691 env
->crf
[i
] = (ccr
>> (32 - ((i
+ 1) * 4))) & 0xf;
3695 env
->gpr
[2] = save_r2
;
3698 if (__get_user(msr
, &frame
->mc_gregs
[TARGET_PT_MSR
]))
3701 /* If doing signal return, restore the previous little-endian mode. */
3703 env
->msr
= (env
->msr
& ~MSR_LE
) | (msr
& MSR_LE
);
3705 /* Restore Altivec registers if necessary. */
3706 if (env
->insns_flags
& PPC_ALTIVEC
) {
3707 for (i
= 0; i
< ARRAY_SIZE(env
->avr
); i
++) {
3708 ppc_avr_t
*avr
= &env
->avr
[i
];
3709 ppc_avr_t
*vreg
= &frame
->mc_vregs
.altivec
[i
];
3711 if (__get_user(avr
->u64
[0], &vreg
->u64
[0]) ||
3712 __get_user(avr
->u64
[1], &vreg
->u64
[1])) {
3716 /* Set MSR_VEC in the saved MSR value to indicate that
3717 frame->mc_vregs contains valid data. */
3718 if (__get_user(env
->spr
[SPR_VRSAVE
],
3719 (target_ulong
*)(&frame
->mc_vregs
.altivec
[32].u32
[3])))
3723 /* Restore floating point registers. */
3724 if (env
->insns_flags
& PPC_FLOAT
) {
3726 for (i
= 0; i
< ARRAY_SIZE(env
->fpr
); i
++) {
3727 if (__get_user(env
->fpr
[i
], &frame
->mc_fregs
[i
])) {
3731 if (__get_user(fpscr
, &frame
->mc_fregs
[32]))
3733 env
->fpscr
= (uint32_t) fpscr
;
3736 /* Save SPE registers. The kernel only saves the high half. */
3737 if (env
->insns_flags
& PPC_SPE
) {
3738 #if defined(TARGET_PPC64)
3739 for (i
= 0; i
< ARRAY_SIZE(env
->gpr
); i
++) {
3742 if (__get_user(hi
, &frame
->mc_vregs
.spe
[i
])) {
3745 env
->gpr
[i
] = ((uint64_t)hi
<< 32) | ((uint32_t) env
->gpr
[i
]);
3748 for (i
= 0; i
< ARRAY_SIZE(env
->gprh
); i
++) {
3749 if (__get_user(env
->gprh
[i
], &frame
->mc_vregs
.spe
[i
])) {
3754 if (__get_user(env
->spe_fscr
, &frame
->mc_vregs
.spe
[32]))
3761 static void setup_frame(int sig
, struct target_sigaction
*ka
,
3762 target_sigset_t
*set
, CPUState
*env
)
3764 struct target_sigframe
*frame
;
3765 struct target_sigcontext
*sc
;
3766 target_ulong frame_addr
, newsp
;
3770 frame_addr
= get_sigframe(ka
, env
, sizeof(*frame
));
3771 if (!lock_user_struct(VERIFY_WRITE
, frame
, frame_addr
, 1))
3775 signal
= current_exec_domain_sig(sig
);
3777 err
|= __put_user(h2g(ka
->_sa_handler
), &sc
->handler
);
3778 err
|= __put_user(set
->sig
[0], &sc
->oldmask
);
3779 #if defined(TARGET_PPC64)
3780 err
|= __put_user(set
->sig
[0] >> 32, &sc
->_unused
[3]);
3782 err
|= __put_user(set
->sig
[1], &sc
->_unused
[3]);
3784 err
|= __put_user(h2g(&frame
->mctx
), &sc
->regs
);
3785 err
|= __put_user(sig
, &sc
->signal
);
3787 /* Save user regs. */
3788 err
|= save_user_regs(env
, &frame
->mctx
, TARGET_NR_sigreturn
);
3790 /* The kernel checks for the presence of a VDSO here. We don't
3791 emulate a vdso, so use a sigreturn system call. */
3792 env
->lr
= (target_ulong
) h2g(frame
->mctx
.tramp
);
3794 /* Turn off all fp exceptions. */
3797 /* Create a stack frame for the caller of the handler. */
3798 newsp
= frame_addr
- SIGNAL_FRAMESIZE
;
3799 err
|= __put_user(env
->gpr
[1], (target_ulong
*)(uintptr_t) newsp
);
3804 /* Set up registers for signal handler. */
3805 env
->gpr
[1] = newsp
;
3806 env
->gpr
[3] = signal
;
3807 env
->gpr
[4] = (target_ulong
) h2g(sc
);
3808 env
->nip
= (target_ulong
) ka
->_sa_handler
;
3809 /* Signal handlers are entered in big-endian mode. */
3810 env
->msr
&= ~MSR_LE
;
3812 unlock_user_struct(frame
, frame_addr
, 1);
3816 unlock_user_struct(frame
, frame_addr
, 1);
3818 fprintf (logfile
, "segfaulting from setup_frame\n");
3822 static void setup_rt_frame(int sig
, struct target_sigaction
*ka
,
3823 target_siginfo_t
*info
,
3824 target_sigset_t
*set
, CPUState
*env
)
3826 struct target_rt_sigframe
*rt_sf
;
3827 struct target_mcontext
*frame
;
3828 target_ulong rt_sf_addr
, newsp
= 0;
3832 rt_sf_addr
= get_sigframe(ka
, env
, sizeof(*rt_sf
));
3833 if (!lock_user_struct(VERIFY_WRITE
, rt_sf
, rt_sf_addr
, 1))
3836 signal
= current_exec_domain_sig(sig
);
3838 err
|= copy_siginfo_to_user(&rt_sf
->info
, info
);
3840 err
|= __put_user(0, &rt_sf
->uc
.uc_flags
);
3841 err
|= __put_user(0, &rt_sf
->uc
.uc_link
);
3842 err
|= __put_user((target_ulong
)target_sigaltstack_used
.ss_sp
,
3843 &rt_sf
->uc
.uc_stack
.ss_sp
);
3844 err
|= __put_user(sas_ss_flags(env
->gpr
[1]),
3845 &rt_sf
->uc
.uc_stack
.ss_flags
);
3846 err
|= __put_user(target_sigaltstack_used
.ss_size
,
3847 &rt_sf
->uc
.uc_stack
.ss_size
);
3848 err
|= __put_user(h2g (&rt_sf
->uc
.uc_mcontext
),
3849 &rt_sf
->uc
.uc_regs
);
3850 for(i
= 0; i
< TARGET_NSIG_WORDS
; i
++) {
3851 err
|= __put_user(set
->sig
[i
], &rt_sf
->uc
.uc_sigmask
.sig
[i
]);
3854 frame
= &rt_sf
->uc
.uc_mcontext
;
3855 err
|= save_user_regs(env
, frame
, TARGET_NR_rt_sigreturn
);
3857 /* The kernel checks for the presence of a VDSO here. We don't
3858 emulate a vdso, so use a sigreturn system call. */
3859 env
->lr
= (target_ulong
) h2g(frame
->tramp
);
3861 /* Turn off all fp exceptions. */
3864 /* Create a stack frame for the caller of the handler. */
3865 newsp
= rt_sf_addr
- (SIGNAL_FRAMESIZE
+ 16);
3866 err
|= __put_user(env
->gpr
[1], (target_ulong
*)(uintptr_t) newsp
);
3871 /* Set up registers for signal handler. */
3872 env
->gpr
[1] = newsp
;
3873 env
->gpr
[3] = (target_ulong
) signal
;
3874 env
->gpr
[4] = (target_ulong
) h2g(&rt_sf
->info
);
3875 env
->gpr
[5] = (target_ulong
) h2g(&rt_sf
->uc
);
3876 env
->gpr
[6] = (target_ulong
) h2g(rt_sf
);
3877 env
->nip
= (target_ulong
) ka
->_sa_handler
;
3878 /* Signal handlers are entered in big-endian mode. */
3879 env
->msr
&= ~MSR_LE
;
3881 unlock_user_struct(rt_sf
, rt_sf_addr
, 1);
3885 unlock_user_struct(rt_sf
, rt_sf_addr
, 1);
3887 fprintf (logfile
, "segfaulting from setup_rt_frame\n");
3892 long do_sigreturn(CPUState
*env
)
3894 struct target_sigcontext
*sc
= NULL
;
3895 struct target_mcontext
*sr
= NULL
;
3896 target_ulong sr_addr
, sc_addr
;
3898 target_sigset_t set
;
3900 sc_addr
= env
->gpr
[1] + SIGNAL_FRAMESIZE
;
3901 if (!lock_user_struct(VERIFY_READ
, sc
, sc_addr
, 1))
3904 #if defined(TARGET_PPC64)
3905 set
.sig
[0] = sc
->oldmask
+ ((long)(sc
->_unused
[3]) << 32);
3907 if(__get_user(set
.sig
[0], &sc
->oldmask
) ||
3908 __get_user(set
.sig
[1], &sc
->_unused
[3]))
3911 target_to_host_sigset_internal(&blocked
, &set
);
3912 sigprocmask(SIG_SETMASK
, &blocked
, NULL
);
3914 if (__get_user(sr_addr
, &sc
->regs
))
3916 if (!lock_user_struct(VERIFY_READ
, sr
, sr_addr
, 1))
3918 if (restore_user_regs(env
, sr
, 1))
3921 unlock_user_struct(sr
, sr_addr
, 1);
3922 unlock_user_struct(sc
, sc_addr
, 1);
3923 return -TARGET_QEMU_ESIGRETURN
;
3926 unlock_user_struct(sr
, sr_addr
, 1);
3927 unlock_user_struct(sc
, sc_addr
, 1);
3929 fprintf (logfile
, "segfaulting from do_sigreturn\n");
3934 /* See arch/powerpc/kernel/signal_32.c. */
3935 static int do_setcontext(struct target_ucontext
*ucp
, CPUState
*env
, int sig
)
3937 struct target_mcontext
*mcp
;
3938 target_ulong mcp_addr
;
3940 target_sigset_t set
;
3942 if (copy_from_user(&set
, h2g(ucp
) + offsetof(struct target_ucontext
, uc_sigmask
),
3946 #if defined(TARGET_PPC64)
3947 fprintf (stderr
, "do_setcontext: not implemented\n");
3950 if (__get_user(mcp_addr
, &ucp
->uc_regs
))
3953 if (!lock_user_struct(VERIFY_READ
, mcp
, mcp_addr
, 1))
3956 target_to_host_sigset_internal(&blocked
, &set
);
3957 sigprocmask(SIG_SETMASK
, &blocked
, NULL
);
3958 if (restore_user_regs(env
, mcp
, sig
))
3961 unlock_user_struct(mcp
, mcp_addr
, 1);
3965 unlock_user_struct(mcp
, mcp_addr
, 1);
3970 long do_rt_sigreturn(CPUState
*env
)
3972 struct target_rt_sigframe
*rt_sf
= NULL
;
3973 target_ulong rt_sf_addr
;
3975 rt_sf_addr
= env
->gpr
[1] + SIGNAL_FRAMESIZE
+ 16;
3976 if (!lock_user_struct(VERIFY_READ
, rt_sf
, rt_sf_addr
, 1))
3979 if (do_setcontext(&rt_sf
->uc
, env
, 1))
3982 do_sigaltstack(rt_sf_addr
3983 + offsetof(struct target_rt_sigframe
, uc
.uc_stack
),
3986 unlock_user_struct(rt_sf
, rt_sf_addr
, 1);
3987 return -TARGET_QEMU_ESIGRETURN
;
3990 unlock_user_struct(rt_sf
, rt_sf_addr
, 1);
3992 fprintf (logfile
, "segfaulting from do_rt_sigreturn\n");
3999 static void setup_frame(int sig
, struct target_sigaction
*ka
,
4000 target_sigset_t
*set
, CPUState
*env
)
4002 fprintf(stderr
, "setup_frame: not implemented\n");
4005 static void setup_rt_frame(int sig
, struct target_sigaction
*ka
,
4006 target_siginfo_t
*info
,
4007 target_sigset_t
*set
, CPUState
*env
)
4009 fprintf(stderr
, "setup_rt_frame: not implemented\n");
4012 long do_sigreturn(CPUState
*env
)
4014 fprintf(stderr
, "do_sigreturn: not implemented\n");
4015 return -TARGET_ENOSYS
;
4018 long do_rt_sigreturn(CPUState
*env
)
4020 fprintf(stderr
, "do_rt_sigreturn: not implemented\n");
4021 return -TARGET_ENOSYS
;
4026 void process_pending_signals(CPUState
*cpu_env
)
4030 sigset_t set
, old_set
;
4031 target_sigset_t target_old_set
;
4032 struct emulated_sigtable
*k
;
4033 struct target_sigaction
*sa
;
4035 TaskState
*ts
= cpu_env
->opaque
;
4037 if (!ts
->signal_pending
)
4040 /* FIXME: This is not threadsafe. */
4042 for(sig
= 1; sig
<= TARGET_NSIG
; sig
++) {
4047 /* if no signal is pending, just return */
4048 ts
->signal_pending
= 0;
4053 fprintf(stderr
, "qemu: process signal %d\n", sig
);
4055 /* dequeue signal */
4061 sig
= gdb_handlesig (cpu_env
, sig
);
4064 handler
= TARGET_SIG_IGN
;
4066 sa
= &sigact_table
[sig
- 1];
4067 handler
= sa
->_sa_handler
;
4070 if (handler
== TARGET_SIG_DFL
) {
4071 /* default handler : ignore some signal. The other are job control or fatal */
4072 if (sig
== TARGET_SIGTSTP
|| sig
== TARGET_SIGTTIN
|| sig
== TARGET_SIGTTOU
) {
4073 kill(getpid(),SIGSTOP
);
4074 } else if (sig
!= TARGET_SIGCHLD
&&
4075 sig
!= TARGET_SIGURG
&&
4076 sig
!= TARGET_SIGWINCH
&&
4077 sig
!= TARGET_SIGCONT
) {
4080 } else if (handler
== TARGET_SIG_IGN
) {
4082 } else if (handler
== TARGET_SIG_ERR
) {
4085 /* compute the blocked signals during the handler execution */
4086 target_to_host_sigset(&set
, &sa
->sa_mask
);
4087 /* SA_NODEFER indicates that the current signal should not be
4088 blocked during the handler */
4089 if (!(sa
->sa_flags
& TARGET_SA_NODEFER
))
4090 sigaddset(&set
, target_to_host_signal(sig
));
4092 /* block signals in the handler using Linux */
4093 sigprocmask(SIG_BLOCK
, &set
, &old_set
);
4094 /* save the previous blocked signal state to restore it at the
4095 end of the signal execution (see do_sigreturn) */
4096 host_to_target_sigset_internal(&target_old_set
, &old_set
);
4098 /* if the CPU is in VM86 mode, we restore the 32 bit values */
4099 #if defined(TARGET_I386) && !defined(TARGET_X86_64)
4101 CPUX86State
*env
= cpu_env
;
4102 if (env
->eflags
& VM_MASK
)
4103 save_v86_state(env
);
4106 /* prepare the stack frame of the virtual CPU */
4107 if (sa
->sa_flags
& TARGET_SA_SIGINFO
)
4108 setup_rt_frame(sig
, sa
, &q
->info
, &target_old_set
, cpu_env
);
4110 setup_frame(sig
, sa
, &target_old_set
, cpu_env
);
4111 if (sa
->sa_flags
& TARGET_SA_RESETHAND
)
4112 sa
->_sa_handler
= TARGET_SIG_DFL
;
4115 free_sigqueue(cpu_env
, q
);