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,
28 #include <sys/ucontext.h>
31 #include "qemu-common.h"
32 #include "target_signal.h"
34 //#define DEBUG_SIGNAL
36 static struct target_sigaltstack target_sigaltstack_used
= {
39 .ss_flags
= TARGET_SS_DISABLE
,
42 static struct target_sigaction sigact_table
[TARGET_NSIG
];
44 static void host_signal_handler(int host_signum
, siginfo_t
*info
,
47 static uint8_t host_to_target_signal_table
[65] = {
48 [SIGHUP
] = TARGET_SIGHUP
,
49 [SIGINT
] = TARGET_SIGINT
,
50 [SIGQUIT
] = TARGET_SIGQUIT
,
51 [SIGILL
] = TARGET_SIGILL
,
52 [SIGTRAP
] = TARGET_SIGTRAP
,
53 [SIGABRT
] = TARGET_SIGABRT
,
54 /* [SIGIOT] = TARGET_SIGIOT,*/
55 [SIGBUS
] = TARGET_SIGBUS
,
56 [SIGFPE
] = TARGET_SIGFPE
,
57 [SIGKILL
] = TARGET_SIGKILL
,
58 [SIGUSR1
] = TARGET_SIGUSR1
,
59 [SIGSEGV
] = TARGET_SIGSEGV
,
60 [SIGUSR2
] = TARGET_SIGUSR2
,
61 [SIGPIPE
] = TARGET_SIGPIPE
,
62 [SIGALRM
] = TARGET_SIGALRM
,
63 [SIGTERM
] = TARGET_SIGTERM
,
65 [SIGSTKFLT
] = TARGET_SIGSTKFLT
,
67 [SIGCHLD
] = TARGET_SIGCHLD
,
68 [SIGCONT
] = TARGET_SIGCONT
,
69 [SIGSTOP
] = TARGET_SIGSTOP
,
70 [SIGTSTP
] = TARGET_SIGTSTP
,
71 [SIGTTIN
] = TARGET_SIGTTIN
,
72 [SIGTTOU
] = TARGET_SIGTTOU
,
73 [SIGURG
] = TARGET_SIGURG
,
74 [SIGXCPU
] = TARGET_SIGXCPU
,
75 [SIGXFSZ
] = TARGET_SIGXFSZ
,
76 [SIGVTALRM
] = TARGET_SIGVTALRM
,
77 [SIGPROF
] = TARGET_SIGPROF
,
78 [SIGWINCH
] = TARGET_SIGWINCH
,
79 [SIGIO
] = TARGET_SIGIO
,
80 [SIGPWR
] = TARGET_SIGPWR
,
81 [SIGSYS
] = TARGET_SIGSYS
,
82 /* next signals stay the same */
83 /* Nasty hack: Reverse SIGRTMIN and SIGRTMAX to avoid overlap with
84 host libpthread signals. This assumes noone actually uses SIGRTMAX :-/
85 To fix this properly we need to do manual signal delivery multiplexed
86 over a single host signal. */
87 [__SIGRTMIN
] = __SIGRTMAX
,
88 [__SIGRTMAX
] = __SIGRTMIN
,
90 static uint8_t target_to_host_signal_table
[65];
92 static inline int on_sig_stack(unsigned long sp
)
94 return (sp
- target_sigaltstack_used
.ss_sp
95 < target_sigaltstack_used
.ss_size
);
98 static inline int sas_ss_flags(unsigned long sp
)
100 return (target_sigaltstack_used
.ss_size
== 0 ? SS_DISABLE
101 : on_sig_stack(sp
) ? SS_ONSTACK
: 0);
104 static inline int host_to_target_signal(int sig
)
108 return host_to_target_signal_table
[sig
];
111 int target_to_host_signal(int sig
)
115 return target_to_host_signal_table
[sig
];
118 static inline void target_sigemptyset(target_sigset_t
*set
)
120 memset(set
, 0, sizeof(*set
));
123 static inline void target_sigaddset(target_sigset_t
*set
, int signum
)
126 abi_ulong mask
= (abi_ulong
)1 << (signum
% TARGET_NSIG_BPW
);
127 set
->sig
[signum
/ TARGET_NSIG_BPW
] |= mask
;
130 static inline int target_sigismember(const target_sigset_t
*set
, int signum
)
133 abi_ulong mask
= (abi_ulong
)1 << (signum
% TARGET_NSIG_BPW
);
134 return ((set
->sig
[signum
/ TARGET_NSIG_BPW
] & mask
) != 0);
137 static void host_to_target_sigset_internal(target_sigset_t
*d
,
141 target_sigemptyset(d
);
142 for (i
= 1; i
<= TARGET_NSIG
; i
++) {
143 if (sigismember(s
, i
)) {
144 target_sigaddset(d
, host_to_target_signal(i
));
149 void host_to_target_sigset(target_sigset_t
*d
, const sigset_t
*s
)
154 host_to_target_sigset_internal(&d1
, s
);
155 for(i
= 0;i
< TARGET_NSIG_WORDS
; i
++)
156 d
->sig
[i
] = tswapl(d1
.sig
[i
]);
159 static void target_to_host_sigset_internal(sigset_t
*d
,
160 const target_sigset_t
*s
)
164 for (i
= 1; i
<= TARGET_NSIG
; i
++) {
165 if (target_sigismember(s
, i
)) {
166 sigaddset(d
, target_to_host_signal(i
));
171 void target_to_host_sigset(sigset_t
*d
, const target_sigset_t
*s
)
176 for(i
= 0;i
< TARGET_NSIG_WORDS
; i
++)
177 s1
.sig
[i
] = tswapl(s
->sig
[i
]);
178 target_to_host_sigset_internal(d
, &s1
);
181 void host_to_target_old_sigset(abi_ulong
*old_sigset
,
182 const sigset_t
*sigset
)
185 host_to_target_sigset(&d
, sigset
);
186 *old_sigset
= d
.sig
[0];
189 void target_to_host_old_sigset(sigset_t
*sigset
,
190 const abi_ulong
*old_sigset
)
195 d
.sig
[0] = *old_sigset
;
196 for(i
= 1;i
< TARGET_NSIG_WORDS
; i
++)
198 target_to_host_sigset(sigset
, &d
);
201 /* siginfo conversion */
203 static inline void host_to_target_siginfo_noswap(target_siginfo_t
*tinfo
,
204 const siginfo_t
*info
)
207 sig
= host_to_target_signal(info
->si_signo
);
208 tinfo
->si_signo
= sig
;
210 tinfo
->si_code
= info
->si_code
;
211 if (sig
== SIGILL
|| sig
== SIGFPE
|| sig
== SIGSEGV
||
212 sig
== SIGBUS
|| sig
== SIGTRAP
) {
213 /* should never come here, but who knows. The information for
214 the target is irrelevant */
215 tinfo
->_sifields
._sigfault
._addr
= 0;
216 } else if (sig
== SIGIO
) {
217 tinfo
->_sifields
._sigpoll
._fd
= info
->si_fd
;
218 } else if (sig
>= TARGET_SIGRTMIN
) {
219 tinfo
->_sifields
._rt
._pid
= info
->si_pid
;
220 tinfo
->_sifields
._rt
._uid
= info
->si_uid
;
221 /* XXX: potential problem if 64 bit */
222 tinfo
->_sifields
._rt
._sigval
.sival_ptr
=
223 (abi_ulong
)(unsigned long)info
->si_value
.sival_ptr
;
227 static void tswap_siginfo(target_siginfo_t
*tinfo
,
228 const target_siginfo_t
*info
)
231 sig
= info
->si_signo
;
232 tinfo
->si_signo
= tswap32(sig
);
233 tinfo
->si_errno
= tswap32(info
->si_errno
);
234 tinfo
->si_code
= tswap32(info
->si_code
);
235 if (sig
== SIGILL
|| sig
== SIGFPE
|| sig
== SIGSEGV
||
236 sig
== SIGBUS
|| sig
== SIGTRAP
) {
237 tinfo
->_sifields
._sigfault
._addr
=
238 tswapl(info
->_sifields
._sigfault
._addr
);
239 } else if (sig
== SIGIO
) {
240 tinfo
->_sifields
._sigpoll
._fd
= tswap32(info
->_sifields
._sigpoll
._fd
);
241 } else if (sig
>= TARGET_SIGRTMIN
) {
242 tinfo
->_sifields
._rt
._pid
= tswap32(info
->_sifields
._rt
._pid
);
243 tinfo
->_sifields
._rt
._uid
= tswap32(info
->_sifields
._rt
._uid
);
244 tinfo
->_sifields
._rt
._sigval
.sival_ptr
=
245 tswapl(info
->_sifields
._rt
._sigval
.sival_ptr
);
250 void host_to_target_siginfo(target_siginfo_t
*tinfo
, const siginfo_t
*info
)
252 host_to_target_siginfo_noswap(tinfo
, info
);
253 tswap_siginfo(tinfo
, tinfo
);
256 /* XXX: we support only POSIX RT signals are used. */
257 /* XXX: find a solution for 64 bit (additional malloced data is needed) */
258 void target_to_host_siginfo(siginfo_t
*info
, const target_siginfo_t
*tinfo
)
260 info
->si_signo
= tswap32(tinfo
->si_signo
);
261 info
->si_errno
= tswap32(tinfo
->si_errno
);
262 info
->si_code
= tswap32(tinfo
->si_code
);
263 info
->si_pid
= tswap32(tinfo
->_sifields
._rt
._pid
);
264 info
->si_uid
= tswap32(tinfo
->_sifields
._rt
._uid
);
265 info
->si_value
.sival_ptr
=
266 (void *)(long)tswapl(tinfo
->_sifields
._rt
._sigval
.sival_ptr
);
269 static int fatal_signal (int sig
)
274 case TARGET_SIGWINCH
:
275 /* Ignored by default. */
282 /* Job control signals. */
289 void signal_init(void)
291 struct sigaction act
;
292 struct sigaction oact
;
296 /* generate signal conversion tables */
297 for(i
= 1; i
<= 64; i
++) {
298 if (host_to_target_signal_table
[i
] == 0)
299 host_to_target_signal_table
[i
] = i
;
301 for(i
= 1; i
<= 64; i
++) {
302 j
= host_to_target_signal_table
[i
];
303 target_to_host_signal_table
[j
] = i
;
306 /* set all host signal handlers. ALL signals are blocked during
307 the handlers to serialize them. */
308 memset(sigact_table
, 0, sizeof(sigact_table
));
310 sigfillset(&act
.sa_mask
);
311 act
.sa_flags
= SA_SIGINFO
;
312 act
.sa_sigaction
= host_signal_handler
;
313 for(i
= 1; i
<= TARGET_NSIG
; i
++) {
314 host_sig
= target_to_host_signal(i
);
315 sigaction(host_sig
, NULL
, &oact
);
316 if (oact
.sa_sigaction
== (void *)SIG_IGN
) {
317 sigact_table
[i
- 1]._sa_handler
= TARGET_SIG_IGN
;
318 } else if (oact
.sa_sigaction
== (void *)SIG_DFL
) {
319 sigact_table
[i
- 1]._sa_handler
= TARGET_SIG_DFL
;
321 /* If there's already a handler installed then something has
322 gone horribly wrong, so don't even try to handle that case. */
323 /* Install some handlers for our own use. We need at least
324 SIGSEGV and SIGBUS, to detect exceptions. We can not just
325 trap all signals because it affects syscall interrupt
326 behavior. But do trap all default-fatal signals. */
327 if (fatal_signal (i
))
328 sigaction(host_sig
, &act
, NULL
);
332 /* signal queue handling */
334 static inline struct sigqueue
*alloc_sigqueue(CPUState
*env
)
336 TaskState
*ts
= env
->opaque
;
337 struct sigqueue
*q
= ts
->first_free
;
340 ts
->first_free
= q
->next
;
344 static inline void free_sigqueue(CPUState
*env
, struct sigqueue
*q
)
346 TaskState
*ts
= env
->opaque
;
347 q
->next
= ts
->first_free
;
351 /* abort execution with signal */
352 static void QEMU_NORETURN
force_sig(int sig
)
355 host_sig
= target_to_host_signal(sig
);
356 fprintf(stderr
, "qemu: uncaught target signal %d (%s) - exiting\n",
357 sig
, strsignal(host_sig
));
359 gdb_signalled(thread_env
, sig
);
363 struct sigaction act
;
364 sigemptyset(&act
.sa_mask
);
365 act
.sa_flags
= SA_SIGINFO
;
366 act
.sa_sigaction
= SIG_DFL
;
367 sigaction(SIGABRT
, &act
, NULL
);
373 /* queue a signal so that it will be send to the virtual CPU as soon
375 int queue_signal(CPUState
*env
, int sig
, target_siginfo_t
*info
)
377 TaskState
*ts
= env
->opaque
;
378 struct emulated_sigtable
*k
;
379 struct sigqueue
*q
, **pq
;
383 #if defined(DEBUG_SIGNAL)
384 fprintf(stderr
, "queue_signal: sig=%d\n",
387 k
= &ts
->sigtab
[sig
- 1];
388 queue
= gdb_queuesig ();
389 handler
= sigact_table
[sig
- 1]._sa_handler
;
390 if (!queue
&& handler
== TARGET_SIG_DFL
) {
391 if (sig
== TARGET_SIGTSTP
|| sig
== TARGET_SIGTTIN
|| sig
== TARGET_SIGTTOU
) {
392 kill(getpid(),SIGSTOP
);
395 /* default handler : ignore some signal. The other are fatal */
396 if (sig
!= TARGET_SIGCHLD
&&
397 sig
!= TARGET_SIGURG
&&
398 sig
!= TARGET_SIGWINCH
&&
399 sig
!= TARGET_SIGCONT
) {
402 return 0; /* indicate ignored */
404 } else if (!queue
&& handler
== TARGET_SIG_IGN
) {
407 } else if (!queue
&& handler
== TARGET_SIG_ERR
) {
411 if (sig
< TARGET_SIGRTMIN
) {
412 /* if non real time signal, we queue exactly one signal */
422 q
= alloc_sigqueue(env
);
433 /* signal that a new signal is pending */
434 ts
->signal_pending
= 1;
435 return 1; /* indicates that the signal was queued */
439 static void host_signal_handler(int host_signum
, siginfo_t
*info
,
443 target_siginfo_t tinfo
;
445 /* the CPU emulator uses some host signals to detect exceptions,
446 we forward to it some signals */
447 if ((host_signum
== SIGSEGV
|| host_signum
== SIGBUS
)
448 && info
->si_code
> 0) {
449 if (cpu_signal_handler(host_signum
, info
, puc
))
453 /* get target signal number */
454 sig
= host_to_target_signal(host_signum
);
455 if (sig
< 1 || sig
> TARGET_NSIG
)
457 #if defined(DEBUG_SIGNAL)
458 fprintf(stderr
, "qemu: got signal %d\n", sig
);
460 host_to_target_siginfo_noswap(&tinfo
, info
);
461 if (queue_signal(thread_env
, sig
, &tinfo
) == 1) {
462 /* interrupt the virtual CPU as soon as possible */
463 cpu_interrupt(thread_env
, CPU_INTERRUPT_EXIT
);
467 /* do_sigaltstack() returns target values and errnos. */
468 /* compare linux/kernel/signal.c:do_sigaltstack() */
469 abi_long
do_sigaltstack(abi_ulong uss_addr
, abi_ulong uoss_addr
, abi_ulong sp
)
472 struct target_sigaltstack oss
;
474 /* XXX: test errors */
477 __put_user(target_sigaltstack_used
.ss_sp
, &oss
.ss_sp
);
478 __put_user(target_sigaltstack_used
.ss_size
, &oss
.ss_size
);
479 __put_user(sas_ss_flags(sp
), &oss
.ss_flags
);
484 struct target_sigaltstack
*uss
;
485 struct target_sigaltstack ss
;
487 ret
= -TARGET_EFAULT
;
488 if (!lock_user_struct(VERIFY_READ
, uss
, uss_addr
, 1)
489 || __get_user(ss
.ss_sp
, &uss
->ss_sp
)
490 || __get_user(ss
.ss_size
, &uss
->ss_size
)
491 || __get_user(ss
.ss_flags
, &uss
->ss_flags
))
493 unlock_user_struct(uss
, uss_addr
, 0);
496 if (on_sig_stack(sp
))
499 ret
= -TARGET_EINVAL
;
500 if (ss
.ss_flags
!= TARGET_SS_DISABLE
501 && ss
.ss_flags
!= TARGET_SS_ONSTACK
505 if (ss
.ss_flags
== TARGET_SS_DISABLE
) {
509 ret
= -TARGET_ENOMEM
;
510 if (ss
.ss_size
< MINSIGSTKSZ
)
514 target_sigaltstack_used
.ss_sp
= ss
.ss_sp
;
515 target_sigaltstack_used
.ss_size
= ss
.ss_size
;
519 ret
= -TARGET_EFAULT
;
520 if (copy_to_user(uoss_addr
, &oss
, sizeof(oss
)))
529 /* do_sigaction() return host values and errnos */
530 int do_sigaction(int sig
, const struct target_sigaction
*act
,
531 struct target_sigaction
*oact
)
533 struct target_sigaction
*k
;
534 struct sigaction act1
;
538 if (sig
< 1 || sig
> TARGET_NSIG
|| sig
== TARGET_SIGKILL
|| sig
== TARGET_SIGSTOP
)
540 k
= &sigact_table
[sig
- 1];
541 #if defined(DEBUG_SIGNAL)
542 fprintf(stderr
, "sigaction sig=%d act=0x%08x, oact=0x%08x\n",
543 sig
, (int)act
, (int)oact
);
546 oact
->_sa_handler
= tswapl(k
->_sa_handler
);
547 oact
->sa_flags
= tswapl(k
->sa_flags
);
548 #if !defined(TARGET_MIPS)
549 oact
->sa_restorer
= tswapl(k
->sa_restorer
);
551 oact
->sa_mask
= k
->sa_mask
;
554 /* FIXME: This is not threadsafe. */
555 k
->_sa_handler
= tswapl(act
->_sa_handler
);
556 k
->sa_flags
= tswapl(act
->sa_flags
);
557 #if !defined(TARGET_MIPS)
558 k
->sa_restorer
= tswapl(act
->sa_restorer
);
560 k
->sa_mask
= act
->sa_mask
;
562 /* we update the host linux signal state */
563 host_sig
= target_to_host_signal(sig
);
564 if (host_sig
!= SIGSEGV
&& host_sig
!= SIGBUS
) {
565 sigfillset(&act1
.sa_mask
);
566 act1
.sa_flags
= SA_SIGINFO
;
567 if (k
->sa_flags
& TARGET_SA_RESTART
)
568 act1
.sa_flags
|= SA_RESTART
;
569 /* NOTE: it is important to update the host kernel signal
570 ignore state to avoid getting unexpected interrupted
572 if (k
->_sa_handler
== TARGET_SIG_IGN
) {
573 act1
.sa_sigaction
= (void *)SIG_IGN
;
574 } else if (k
->_sa_handler
== TARGET_SIG_DFL
) {
575 if (fatal_signal (sig
))
576 act1
.sa_sigaction
= host_signal_handler
;
578 act1
.sa_sigaction
= (void *)SIG_DFL
;
580 act1
.sa_sigaction
= host_signal_handler
;
582 ret
= sigaction(host_sig
, &act1
, NULL
);
588 static inline int copy_siginfo_to_user(target_siginfo_t
*tinfo
,
589 const target_siginfo_t
*info
)
591 tswap_siginfo(tinfo
, info
);
595 static inline int current_exec_domain_sig(int sig
)
597 return /* current->exec_domain && current->exec_domain->signal_invmap
598 && sig < 32 ? current->exec_domain->signal_invmap[sig] : */ sig
;
601 #if defined(TARGET_I386) && TARGET_ABI_BITS == 32
603 /* from the Linux kernel */
605 struct target_fpreg
{
606 uint16_t significand
[4];
610 struct target_fpxreg
{
611 uint16_t significand
[4];
616 struct target_xmmreg
{
617 abi_ulong element
[4];
620 struct target_fpstate
{
621 /* Regular FPU environment */
629 struct target_fpreg _st
[8];
631 uint16_t magic
; /* 0xffff = regular FPU data only */
633 /* FXSR FPU environment */
634 abi_ulong _fxsr_env
[6]; /* FXSR FPU env is ignored */
637 struct target_fpxreg _fxsr_st
[8]; /* FXSR FPU reg data is ignored */
638 struct target_xmmreg _xmm
[8];
639 abi_ulong padding
[56];
642 #define X86_FXSR_MAGIC 0x0000
644 struct target_sigcontext
{
662 abi_ulong esp_at_signal
;
664 abi_ulong fpstate
; /* pointer */
669 struct target_ucontext
{
672 target_stack_t tuc_stack
;
673 struct target_sigcontext tuc_mcontext
;
674 target_sigset_t tuc_sigmask
; /* mask last for extensibility */
681 struct target_sigcontext sc
;
682 struct target_fpstate fpstate
;
683 abi_ulong extramask
[TARGET_NSIG_WORDS
-1];
693 struct target_siginfo info
;
694 struct target_ucontext uc
;
695 struct target_fpstate fpstate
;
700 * Set up a signal frame.
703 /* XXX: save x87 state */
705 setup_sigcontext(struct target_sigcontext
*sc
, struct target_fpstate
*fpstate
,
706 CPUX86State
*env
, abi_ulong mask
, abi_ulong fpstate_addr
)
711 /* already locked in setup_frame() */
712 err
|= __put_user(env
->segs
[R_GS
].selector
, (unsigned int *)&sc
->gs
);
713 err
|= __put_user(env
->segs
[R_FS
].selector
, (unsigned int *)&sc
->fs
);
714 err
|= __put_user(env
->segs
[R_ES
].selector
, (unsigned int *)&sc
->es
);
715 err
|= __put_user(env
->segs
[R_DS
].selector
, (unsigned int *)&sc
->ds
);
716 err
|= __put_user(env
->regs
[R_EDI
], &sc
->edi
);
717 err
|= __put_user(env
->regs
[R_ESI
], &sc
->esi
);
718 err
|= __put_user(env
->regs
[R_EBP
], &sc
->ebp
);
719 err
|= __put_user(env
->regs
[R_ESP
], &sc
->esp
);
720 err
|= __put_user(env
->regs
[R_EBX
], &sc
->ebx
);
721 err
|= __put_user(env
->regs
[R_EDX
], &sc
->edx
);
722 err
|= __put_user(env
->regs
[R_ECX
], &sc
->ecx
);
723 err
|= __put_user(env
->regs
[R_EAX
], &sc
->eax
);
724 err
|= __put_user(env
->exception_index
, &sc
->trapno
);
725 err
|= __put_user(env
->error_code
, &sc
->err
);
726 err
|= __put_user(env
->eip
, &sc
->eip
);
727 err
|= __put_user(env
->segs
[R_CS
].selector
, (unsigned int *)&sc
->cs
);
728 err
|= __put_user(env
->eflags
, &sc
->eflags
);
729 err
|= __put_user(env
->regs
[R_ESP
], &sc
->esp_at_signal
);
730 err
|= __put_user(env
->segs
[R_SS
].selector
, (unsigned int *)&sc
->ss
);
732 cpu_x86_fsave(env
, fpstate_addr
, 1);
733 fpstate
->status
= fpstate
->sw
;
735 err
|= __put_user(magic
, &fpstate
->magic
);
736 err
|= __put_user(fpstate_addr
, &sc
->fpstate
);
738 /* non-iBCS2 extensions.. */
739 err
|= __put_user(mask
, &sc
->oldmask
);
740 err
|= __put_user(env
->cr
[2], &sc
->cr2
);
745 * Determine which stack to use..
748 static inline abi_ulong
749 get_sigframe(struct target_sigaction
*ka
, CPUX86State
*env
, size_t frame_size
)
753 /* Default to using normal stack */
754 esp
= env
->regs
[R_ESP
];
755 /* This is the X/Open sanctioned signal stack switching. */
756 if (ka
->sa_flags
& TARGET_SA_ONSTACK
) {
757 if (sas_ss_flags(esp
) == 0)
758 esp
= target_sigaltstack_used
.ss_sp
+ target_sigaltstack_used
.ss_size
;
761 /* This is the legacy signal stack switching. */
763 if ((env
->segs
[R_SS
].selector
& 0xffff) != __USER_DS
&&
764 !(ka
->sa_flags
& TARGET_SA_RESTORER
) &&
766 esp
= (unsigned long) ka
->sa_restorer
;
768 return (esp
- frame_size
) & -8ul;
771 /* compare linux/arch/i386/kernel/signal.c:setup_frame() */
772 static void setup_frame(int sig
, struct target_sigaction
*ka
,
773 target_sigset_t
*set
, CPUX86State
*env
)
775 abi_ulong frame_addr
;
776 struct sigframe
*frame
;
779 frame_addr
= get_sigframe(ka
, env
, sizeof(*frame
));
781 if (!lock_user_struct(VERIFY_WRITE
, frame
, frame_addr
, 0))
784 err
|= __put_user(current_exec_domain_sig(sig
),
789 setup_sigcontext(&frame
->sc
, &frame
->fpstate
, env
, set
->sig
[0],
790 frame_addr
+ offsetof(struct sigframe
, fpstate
));
794 for(i
= 1; i
< TARGET_NSIG_WORDS
; i
++) {
795 if (__put_user(set
->sig
[i
], &frame
->extramask
[i
- 1]))
799 /* Set up to return from userspace. If provided, use a stub
800 already in userspace. */
801 if (ka
->sa_flags
& TARGET_SA_RESTORER
) {
802 err
|= __put_user(ka
->sa_restorer
, &frame
->pretcode
);
805 abi_ulong retcode_addr
;
806 retcode_addr
= frame_addr
+ offsetof(struct sigframe
, retcode
);
807 err
|= __put_user(retcode_addr
, &frame
->pretcode
);
808 /* This is popl %eax ; movl $,%eax ; int $0x80 */
810 err
|= __put_user(val16
, (uint16_t *)(frame
->retcode
+0));
811 err
|= __put_user(TARGET_NR_sigreturn
, (int *)(frame
->retcode
+2));
813 err
|= __put_user(val16
, (uint16_t *)(frame
->retcode
+6));
819 /* Set up registers for signal handler */
820 env
->regs
[R_ESP
] = frame_addr
;
821 env
->eip
= ka
->_sa_handler
;
823 cpu_x86_load_seg(env
, R_DS
, __USER_DS
);
824 cpu_x86_load_seg(env
, R_ES
, __USER_DS
);
825 cpu_x86_load_seg(env
, R_SS
, __USER_DS
);
826 cpu_x86_load_seg(env
, R_CS
, __USER_CS
);
827 env
->eflags
&= ~TF_MASK
;
829 unlock_user_struct(frame
, frame_addr
, 1);
834 unlock_user_struct(frame
, frame_addr
, 1);
835 if (sig
== TARGET_SIGSEGV
)
836 ka
->_sa_handler
= TARGET_SIG_DFL
;
837 force_sig(TARGET_SIGSEGV
/* , current */);
840 /* compare linux/arch/i386/kernel/signal.c:setup_rt_frame() */
841 static void setup_rt_frame(int sig
, struct target_sigaction
*ka
,
842 target_siginfo_t
*info
,
843 target_sigset_t
*set
, CPUX86State
*env
)
845 abi_ulong frame_addr
, addr
;
846 struct rt_sigframe
*frame
;
849 frame_addr
= get_sigframe(ka
, env
, sizeof(*frame
));
851 if (!lock_user_struct(VERIFY_WRITE
, frame
, frame_addr
, 0))
854 err
|= __put_user(current_exec_domain_sig(sig
),
856 addr
= frame_addr
+ offsetof(struct rt_sigframe
, info
);
857 err
|= __put_user(addr
, &frame
->pinfo
);
858 addr
= frame_addr
+ offsetof(struct rt_sigframe
, uc
);
859 err
|= __put_user(addr
, &frame
->puc
);
860 err
|= copy_siginfo_to_user(&frame
->info
, info
);
864 /* Create the ucontext. */
865 err
|= __put_user(0, &frame
->uc
.tuc_flags
);
866 err
|= __put_user(0, &frame
->uc
.tuc_link
);
867 err
|= __put_user(target_sigaltstack_used
.ss_sp
,
868 &frame
->uc
.tuc_stack
.ss_sp
);
869 err
|= __put_user(sas_ss_flags(get_sp_from_cpustate(env
)),
870 &frame
->uc
.tuc_stack
.ss_flags
);
871 err
|= __put_user(target_sigaltstack_used
.ss_size
,
872 &frame
->uc
.tuc_stack
.ss_size
);
873 err
|= setup_sigcontext(&frame
->uc
.tuc_mcontext
, &frame
->fpstate
,
875 frame_addr
+ offsetof(struct rt_sigframe
, fpstate
));
876 for(i
= 0; i
< TARGET_NSIG_WORDS
; i
++) {
877 if (__put_user(set
->sig
[i
], &frame
->uc
.tuc_sigmask
.sig
[i
]))
881 /* Set up to return from userspace. If provided, use a stub
882 already in userspace. */
883 if (ka
->sa_flags
& TARGET_SA_RESTORER
) {
884 err
|= __put_user(ka
->sa_restorer
, &frame
->pretcode
);
887 addr
= frame_addr
+ offsetof(struct rt_sigframe
, retcode
);
888 err
|= __put_user(addr
, &frame
->pretcode
);
889 /* This is movl $,%eax ; int $0x80 */
890 err
|= __put_user(0xb8, (char *)(frame
->retcode
+0));
891 err
|= __put_user(TARGET_NR_rt_sigreturn
, (int *)(frame
->retcode
+1));
893 err
|= __put_user(val16
, (uint16_t *)(frame
->retcode
+5));
899 /* Set up registers for signal handler */
900 env
->regs
[R_ESP
] = frame_addr
;
901 env
->eip
= ka
->_sa_handler
;
903 cpu_x86_load_seg(env
, R_DS
, __USER_DS
);
904 cpu_x86_load_seg(env
, R_ES
, __USER_DS
);
905 cpu_x86_load_seg(env
, R_SS
, __USER_DS
);
906 cpu_x86_load_seg(env
, R_CS
, __USER_CS
);
907 env
->eflags
&= ~TF_MASK
;
909 unlock_user_struct(frame
, frame_addr
, 1);
914 unlock_user_struct(frame
, frame_addr
, 1);
915 if (sig
== TARGET_SIGSEGV
)
916 ka
->_sa_handler
= TARGET_SIG_DFL
;
917 force_sig(TARGET_SIGSEGV
/* , current */);
921 restore_sigcontext(CPUX86State
*env
, struct target_sigcontext
*sc
, int *peax
)
923 unsigned int err
= 0;
924 abi_ulong fpstate_addr
;
925 unsigned int tmpflags
;
927 cpu_x86_load_seg(env
, R_GS
, tswap16(sc
->gs
));
928 cpu_x86_load_seg(env
, R_FS
, tswap16(sc
->fs
));
929 cpu_x86_load_seg(env
, R_ES
, tswap16(sc
->es
));
930 cpu_x86_load_seg(env
, R_DS
, tswap16(sc
->ds
));
932 env
->regs
[R_EDI
] = tswapl(sc
->edi
);
933 env
->regs
[R_ESI
] = tswapl(sc
->esi
);
934 env
->regs
[R_EBP
] = tswapl(sc
->ebp
);
935 env
->regs
[R_ESP
] = tswapl(sc
->esp
);
936 env
->regs
[R_EBX
] = tswapl(sc
->ebx
);
937 env
->regs
[R_EDX
] = tswapl(sc
->edx
);
938 env
->regs
[R_ECX
] = tswapl(sc
->ecx
);
939 env
->eip
= tswapl(sc
->eip
);
941 cpu_x86_load_seg(env
, R_CS
, lduw(&sc
->cs
) | 3);
942 cpu_x86_load_seg(env
, R_SS
, lduw(&sc
->ss
) | 3);
944 tmpflags
= tswapl(sc
->eflags
);
945 env
->eflags
= (env
->eflags
& ~0x40DD5) | (tmpflags
& 0x40DD5);
946 // regs->orig_eax = -1; /* disable syscall checks */
948 fpstate_addr
= tswapl(sc
->fpstate
);
949 if (fpstate_addr
!= 0) {
950 if (!access_ok(VERIFY_READ
, fpstate_addr
,
951 sizeof(struct target_fpstate
)))
953 cpu_x86_frstor(env
, fpstate_addr
, 1);
956 *peax
= tswapl(sc
->eax
);
962 long do_sigreturn(CPUX86State
*env
)
964 struct sigframe
*frame
;
965 abi_ulong frame_addr
= env
->regs
[R_ESP
] - 8;
966 target_sigset_t target_set
;
970 #if defined(DEBUG_SIGNAL)
971 fprintf(stderr
, "do_sigreturn\n");
973 if (!lock_user_struct(VERIFY_READ
, frame
, frame_addr
, 1))
975 /* set blocked signals */
976 if (__get_user(target_set
.sig
[0], &frame
->sc
.oldmask
))
978 for(i
= 1; i
< TARGET_NSIG_WORDS
; i
++) {
979 if (__get_user(target_set
.sig
[i
], &frame
->extramask
[i
- 1]))
983 target_to_host_sigset_internal(&set
, &target_set
);
984 sigprocmask(SIG_SETMASK
, &set
, NULL
);
986 /* restore registers */
987 if (restore_sigcontext(env
, &frame
->sc
, &eax
))
989 unlock_user_struct(frame
, frame_addr
, 0);
993 unlock_user_struct(frame
, frame_addr
, 0);
994 force_sig(TARGET_SIGSEGV
);
998 long do_rt_sigreturn(CPUX86State
*env
)
1000 abi_ulong frame_addr
;
1001 struct rt_sigframe
*frame
;
1005 frame_addr
= env
->regs
[R_ESP
] - 4;
1006 if (!lock_user_struct(VERIFY_READ
, frame
, frame_addr
, 1))
1008 target_to_host_sigset(&set
, &frame
->uc
.tuc_sigmask
);
1009 sigprocmask(SIG_SETMASK
, &set
, NULL
);
1011 if (restore_sigcontext(env
, &frame
->uc
.tuc_mcontext
, &eax
))
1014 if (do_sigaltstack(frame_addr
+ offsetof(struct rt_sigframe
, uc
.tuc_stack
), 0,
1015 get_sp_from_cpustate(env
)) == -EFAULT
)
1018 unlock_user_struct(frame
, frame_addr
, 0);
1022 unlock_user_struct(frame
, frame_addr
, 0);
1023 force_sig(TARGET_SIGSEGV
);
1027 #elif defined(TARGET_ARM)
1029 struct target_sigcontext
{
1031 abi_ulong error_code
;
1050 abi_ulong fault_address
;
1053 struct target_ucontext_v1
{
1054 abi_ulong tuc_flags
;
1056 target_stack_t tuc_stack
;
1057 struct target_sigcontext tuc_mcontext
;
1058 target_sigset_t tuc_sigmask
; /* mask last for extensibility */
1061 struct target_ucontext_v2
{
1062 abi_ulong tuc_flags
;
1064 target_stack_t tuc_stack
;
1065 struct target_sigcontext tuc_mcontext
;
1066 target_sigset_t tuc_sigmask
; /* mask last for extensibility */
1067 char __unused
[128 - sizeof(sigset_t
)];
1068 abi_ulong tuc_regspace
[128] __attribute__((__aligned__(8)));
1073 struct target_sigcontext sc
;
1074 abi_ulong extramask
[TARGET_NSIG_WORDS
-1];
1080 struct target_ucontext_v2 uc
;
1084 struct rt_sigframe_v1
1088 struct target_siginfo info
;
1089 struct target_ucontext_v1 uc
;
1093 struct rt_sigframe_v2
1095 struct target_siginfo info
;
1096 struct target_ucontext_v2 uc
;
1100 #define TARGET_CONFIG_CPU_32 1
1103 * For ARM syscalls, we encode the syscall number into the instruction.
1105 #define SWI_SYS_SIGRETURN (0xef000000|(TARGET_NR_sigreturn + ARM_SYSCALL_BASE))
1106 #define SWI_SYS_RT_SIGRETURN (0xef000000|(TARGET_NR_rt_sigreturn + ARM_SYSCALL_BASE))
1109 * For Thumb syscalls, we pass the syscall number via r7. We therefore
1110 * need two 16-bit instructions.
1112 #define SWI_THUMB_SIGRETURN (0xdf00 << 16 | 0x2700 | (TARGET_NR_sigreturn))
1113 #define SWI_THUMB_RT_SIGRETURN (0xdf00 << 16 | 0x2700 | (TARGET_NR_rt_sigreturn))
1115 static const abi_ulong retcodes
[4] = {
1116 SWI_SYS_SIGRETURN
, SWI_THUMB_SIGRETURN
,
1117 SWI_SYS_RT_SIGRETURN
, SWI_THUMB_RT_SIGRETURN
1121 #define __get_user_error(x,p,e) __get_user(x, p)
1123 static inline int valid_user_regs(CPUState
*regs
)
1129 setup_sigcontext(struct target_sigcontext
*sc
, /*struct _fpstate *fpstate,*/
1130 CPUState
*env
, abi_ulong mask
)
1132 __put_user(env
->regs
[0], &sc
->arm_r0
);
1133 __put_user(env
->regs
[1], &sc
->arm_r1
);
1134 __put_user(env
->regs
[2], &sc
->arm_r2
);
1135 __put_user(env
->regs
[3], &sc
->arm_r3
);
1136 __put_user(env
->regs
[4], &sc
->arm_r4
);
1137 __put_user(env
->regs
[5], &sc
->arm_r5
);
1138 __put_user(env
->regs
[6], &sc
->arm_r6
);
1139 __put_user(env
->regs
[7], &sc
->arm_r7
);
1140 __put_user(env
->regs
[8], &sc
->arm_r8
);
1141 __put_user(env
->regs
[9], &sc
->arm_r9
);
1142 __put_user(env
->regs
[10], &sc
->arm_r10
);
1143 __put_user(env
->regs
[11], &sc
->arm_fp
);
1144 __put_user(env
->regs
[12], &sc
->arm_ip
);
1145 __put_user(env
->regs
[13], &sc
->arm_sp
);
1146 __put_user(env
->regs
[14], &sc
->arm_lr
);
1147 __put_user(env
->regs
[15], &sc
->arm_pc
);
1148 #ifdef TARGET_CONFIG_CPU_32
1149 __put_user(cpsr_read(env
), &sc
->arm_cpsr
);
1152 __put_user(/* current->thread.trap_no */ 0, &sc
->trap_no
);
1153 __put_user(/* current->thread.error_code */ 0, &sc
->error_code
);
1154 __put_user(/* current->thread.address */ 0, &sc
->fault_address
);
1155 __put_user(mask
, &sc
->oldmask
);
1158 static inline abi_ulong
1159 get_sigframe(struct target_sigaction
*ka
, CPUState
*regs
, int framesize
)
1161 unsigned long sp
= regs
->regs
[13];
1164 * This is the X/Open sanctioned signal stack switching.
1166 if ((ka
->sa_flags
& TARGET_SA_ONSTACK
) && !sas_ss_flags(sp
))
1167 sp
= target_sigaltstack_used
.ss_sp
+ target_sigaltstack_used
.ss_size
;
1169 * ATPCS B01 mandates 8-byte alignment
1171 return (sp
- framesize
) & ~7;
1175 setup_return(CPUState
*env
, struct target_sigaction
*ka
,
1176 abi_ulong
*rc
, abi_ulong frame_addr
, int usig
, abi_ulong rc_addr
)
1178 abi_ulong handler
= ka
->_sa_handler
;
1180 int thumb
= handler
& 1;
1182 if (ka
->sa_flags
& TARGET_SA_RESTORER
) {
1183 retcode
= ka
->sa_restorer
;
1185 unsigned int idx
= thumb
;
1187 if (ka
->sa_flags
& TARGET_SA_SIGINFO
)
1190 if (__put_user(retcodes
[idx
], rc
))
1193 flush_icache_range((abi_ulong
)rc
,
1194 (abi_ulong
)(rc
+ 1));
1196 retcode
= rc_addr
+ thumb
;
1199 env
->regs
[0] = usig
;
1200 env
->regs
[13] = frame_addr
;
1201 env
->regs
[14] = retcode
;
1202 env
->regs
[15] = handler
& (thumb
? ~1 : ~3);
1206 #ifdef TARGET_CONFIG_CPU_32
1214 static void setup_sigframe_v2(struct target_ucontext_v2
*uc
,
1215 target_sigset_t
*set
, CPUState
*env
)
1217 struct target_sigaltstack stack
;
1220 /* Clear all the bits of the ucontext we don't use. */
1221 memset(uc
, 0, offsetof(struct target_ucontext_v2
, tuc_mcontext
));
1223 memset(&stack
, 0, sizeof(stack
));
1224 __put_user(target_sigaltstack_used
.ss_sp
, &stack
.ss_sp
);
1225 __put_user(target_sigaltstack_used
.ss_size
, &stack
.ss_size
);
1226 __put_user(sas_ss_flags(get_sp_from_cpustate(env
)), &stack
.ss_flags
);
1227 memcpy(&uc
->tuc_stack
, &stack
, sizeof(stack
));
1229 setup_sigcontext(&uc
->tuc_mcontext
, env
, set
->sig
[0]);
1230 /* FIXME: Save coprocessor signal frame. */
1231 for(i
= 0; i
< TARGET_NSIG_WORDS
; i
++) {
1232 __put_user(set
->sig
[i
], &uc
->tuc_sigmask
.sig
[i
]);
1236 /* compare linux/arch/arm/kernel/signal.c:setup_frame() */
1237 static void setup_frame_v1(int usig
, struct target_sigaction
*ka
,
1238 target_sigset_t
*set
, CPUState
*regs
)
1240 struct sigframe_v1
*frame
;
1241 abi_ulong frame_addr
= get_sigframe(ka
, regs
, sizeof(*frame
));
1244 if (!lock_user_struct(VERIFY_WRITE
, frame
, frame_addr
, 0))
1247 setup_sigcontext(&frame
->sc
, regs
, set
->sig
[0]);
1249 for(i
= 1; i
< TARGET_NSIG_WORDS
; i
++) {
1250 if (__put_user(set
->sig
[i
], &frame
->extramask
[i
- 1]))
1254 setup_return(regs
, ka
, &frame
->retcode
, frame_addr
, usig
,
1255 frame_addr
+ offsetof(struct sigframe_v1
, retcode
));
1258 unlock_user_struct(frame
, frame_addr
, 1);
1261 static void setup_frame_v2(int usig
, struct target_sigaction
*ka
,
1262 target_sigset_t
*set
, CPUState
*regs
)
1264 struct sigframe_v2
*frame
;
1265 abi_ulong frame_addr
= get_sigframe(ka
, regs
, sizeof(*frame
));
1267 if (!lock_user_struct(VERIFY_WRITE
, frame
, frame_addr
, 0))
1270 setup_sigframe_v2(&frame
->uc
, set
, regs
);
1272 setup_return(regs
, ka
, &frame
->retcode
, frame_addr
, usig
,
1273 frame_addr
+ offsetof(struct sigframe_v2
, retcode
));
1275 unlock_user_struct(frame
, frame_addr
, 1);
1278 static void setup_frame(int usig
, struct target_sigaction
*ka
,
1279 target_sigset_t
*set
, CPUState
*regs
)
1281 if (get_osversion() >= 0x020612) {
1282 setup_frame_v2(usig
, ka
, set
, regs
);
1284 setup_frame_v1(usig
, ka
, set
, regs
);
1288 /* compare linux/arch/arm/kernel/signal.c:setup_rt_frame() */
1289 static void setup_rt_frame_v1(int usig
, struct target_sigaction
*ka
,
1290 target_siginfo_t
*info
,
1291 target_sigset_t
*set
, CPUState
*env
)
1293 struct rt_sigframe_v1
*frame
;
1294 abi_ulong frame_addr
= get_sigframe(ka
, env
, sizeof(*frame
));
1295 struct target_sigaltstack stack
;
1297 abi_ulong info_addr
, uc_addr
;
1299 if (!lock_user_struct(VERIFY_WRITE
, frame
, frame_addr
, 0))
1302 info_addr
= frame_addr
+ offsetof(struct rt_sigframe_v1
, info
);
1303 __put_user(info_addr
, &frame
->pinfo
);
1304 uc_addr
= frame_addr
+ offsetof(struct rt_sigframe_v1
, uc
);
1305 __put_user(uc_addr
, &frame
->puc
);
1306 copy_siginfo_to_user(&frame
->info
, info
);
1308 /* Clear all the bits of the ucontext we don't use. */
1309 memset(&frame
->uc
, 0, offsetof(struct target_ucontext_v1
, tuc_mcontext
));
1311 memset(&stack
, 0, sizeof(stack
));
1312 __put_user(target_sigaltstack_used
.ss_sp
, &stack
.ss_sp
);
1313 __put_user(target_sigaltstack_used
.ss_size
, &stack
.ss_size
);
1314 __put_user(sas_ss_flags(get_sp_from_cpustate(env
)), &stack
.ss_flags
);
1315 memcpy(&frame
->uc
.tuc_stack
, &stack
, sizeof(stack
));
1317 setup_sigcontext(&frame
->uc
.tuc_mcontext
, env
, set
->sig
[0]);
1318 for(i
= 0; i
< TARGET_NSIG_WORDS
; i
++) {
1319 if (__put_user(set
->sig
[i
], &frame
->uc
.tuc_sigmask
.sig
[i
]))
1323 setup_return(env
, ka
, &frame
->retcode
, frame_addr
, usig
,
1324 frame_addr
+ offsetof(struct rt_sigframe_v1
, retcode
));
1326 env
->regs
[1] = info_addr
;
1327 env
->regs
[2] = uc_addr
;
1330 unlock_user_struct(frame
, frame_addr
, 1);
1333 static void setup_rt_frame_v2(int usig
, struct target_sigaction
*ka
,
1334 target_siginfo_t
*info
,
1335 target_sigset_t
*set
, CPUState
*env
)
1337 struct rt_sigframe_v2
*frame
;
1338 abi_ulong frame_addr
= get_sigframe(ka
, env
, sizeof(*frame
));
1339 abi_ulong info_addr
, uc_addr
;
1341 if (!lock_user_struct(VERIFY_WRITE
, frame
, frame_addr
, 0))
1344 info_addr
= frame_addr
+ offsetof(struct rt_sigframe_v2
, info
);
1345 uc_addr
= frame_addr
+ offsetof(struct rt_sigframe_v2
, uc
);
1346 copy_siginfo_to_user(&frame
->info
, info
);
1348 setup_sigframe_v2(&frame
->uc
, set
, env
);
1350 setup_return(env
, ka
, &frame
->retcode
, frame_addr
, usig
,
1351 frame_addr
+ offsetof(struct rt_sigframe_v2
, retcode
));
1353 env
->regs
[1] = info_addr
;
1354 env
->regs
[2] = uc_addr
;
1356 unlock_user_struct(frame
, frame_addr
, 1);
1359 static void setup_rt_frame(int usig
, struct target_sigaction
*ka
,
1360 target_siginfo_t
*info
,
1361 target_sigset_t
*set
, CPUState
*env
)
1363 if (get_osversion() >= 0x020612) {
1364 setup_rt_frame_v2(usig
, ka
, info
, set
, env
);
1366 setup_rt_frame_v1(usig
, ka
, info
, set
, env
);
1371 restore_sigcontext(CPUState
*env
, struct target_sigcontext
*sc
)
1376 __get_user_error(env
->regs
[0], &sc
->arm_r0
, err
);
1377 __get_user_error(env
->regs
[1], &sc
->arm_r1
, err
);
1378 __get_user_error(env
->regs
[2], &sc
->arm_r2
, err
);
1379 __get_user_error(env
->regs
[3], &sc
->arm_r3
, err
);
1380 __get_user_error(env
->regs
[4], &sc
->arm_r4
, err
);
1381 __get_user_error(env
->regs
[5], &sc
->arm_r5
, err
);
1382 __get_user_error(env
->regs
[6], &sc
->arm_r6
, err
);
1383 __get_user_error(env
->regs
[7], &sc
->arm_r7
, err
);
1384 __get_user_error(env
->regs
[8], &sc
->arm_r8
, err
);
1385 __get_user_error(env
->regs
[9], &sc
->arm_r9
, err
);
1386 __get_user_error(env
->regs
[10], &sc
->arm_r10
, err
);
1387 __get_user_error(env
->regs
[11], &sc
->arm_fp
, err
);
1388 __get_user_error(env
->regs
[12], &sc
->arm_ip
, err
);
1389 __get_user_error(env
->regs
[13], &sc
->arm_sp
, err
);
1390 __get_user_error(env
->regs
[14], &sc
->arm_lr
, err
);
1391 __get_user_error(env
->regs
[15], &sc
->arm_pc
, err
);
1392 #ifdef TARGET_CONFIG_CPU_32
1393 __get_user_error(cpsr
, &sc
->arm_cpsr
, err
);
1394 cpsr_write(env
, cpsr
, CPSR_USER
| CPSR_EXEC
);
1397 err
|= !valid_user_regs(env
);
1402 static long do_sigreturn_v1(CPUState
*env
)
1404 abi_ulong frame_addr
;
1405 struct sigframe_v1
*frame
;
1406 target_sigset_t set
;
1411 * Since we stacked the signal on a 64-bit boundary,
1412 * then 'sp' should be word aligned here. If it's
1413 * not, then the user is trying to mess with us.
1415 if (env
->regs
[13] & 7)
1418 frame_addr
= env
->regs
[13];
1419 if (!lock_user_struct(VERIFY_READ
, frame
, frame_addr
, 1))
1422 if (__get_user(set
.sig
[0], &frame
->sc
.oldmask
))
1424 for(i
= 1; i
< TARGET_NSIG_WORDS
; i
++) {
1425 if (__get_user(set
.sig
[i
], &frame
->extramask
[i
- 1]))
1429 target_to_host_sigset_internal(&host_set
, &set
);
1430 sigprocmask(SIG_SETMASK
, &host_set
, NULL
);
1432 if (restore_sigcontext(env
, &frame
->sc
))
1436 /* Send SIGTRAP if we're single-stepping */
1437 if (ptrace_cancel_bpt(current
))
1438 send_sig(SIGTRAP
, current
, 1);
1440 unlock_user_struct(frame
, frame_addr
, 0);
1441 return env
->regs
[0];
1444 unlock_user_struct(frame
, frame_addr
, 0);
1445 force_sig(SIGSEGV
/* , current */);
1449 static int do_sigframe_return_v2(CPUState
*env
, target_ulong frame_addr
,
1450 struct target_ucontext_v2
*uc
)
1454 target_to_host_sigset(&host_set
, &uc
->tuc_sigmask
);
1455 sigprocmask(SIG_SETMASK
, &host_set
, NULL
);
1457 if (restore_sigcontext(env
, &uc
->tuc_mcontext
))
1460 if (do_sigaltstack(frame_addr
+ offsetof(struct target_ucontext_v2
, tuc_stack
), 0, get_sp_from_cpustate(env
)) == -EFAULT
)
1464 /* Send SIGTRAP if we're single-stepping */
1465 if (ptrace_cancel_bpt(current
))
1466 send_sig(SIGTRAP
, current
, 1);
1472 static long do_sigreturn_v2(CPUState
*env
)
1474 abi_ulong frame_addr
;
1475 struct sigframe_v2
*frame
;
1478 * Since we stacked the signal on a 64-bit boundary,
1479 * then 'sp' should be word aligned here. If it's
1480 * not, then the user is trying to mess with us.
1482 if (env
->regs
[13] & 7)
1485 frame_addr
= env
->regs
[13];
1486 if (!lock_user_struct(VERIFY_READ
, frame
, frame_addr
, 1))
1489 if (do_sigframe_return_v2(env
, frame_addr
, &frame
->uc
))
1492 unlock_user_struct(frame
, frame_addr
, 0);
1493 return env
->regs
[0];
1496 unlock_user_struct(frame
, frame_addr
, 0);
1497 force_sig(SIGSEGV
/* , current */);
1501 long do_sigreturn(CPUState
*env
)
1503 if (get_osversion() >= 0x020612) {
1504 return do_sigreturn_v2(env
);
1506 return do_sigreturn_v1(env
);
1510 static long do_rt_sigreturn_v1(CPUState
*env
)
1512 abi_ulong frame_addr
;
1513 struct rt_sigframe_v1
*frame
;
1517 * Since we stacked the signal on a 64-bit boundary,
1518 * then 'sp' should be word aligned here. If it's
1519 * not, then the user is trying to mess with us.
1521 if (env
->regs
[13] & 7)
1524 frame_addr
= env
->regs
[13];
1525 if (!lock_user_struct(VERIFY_READ
, frame
, frame_addr
, 1))
1528 target_to_host_sigset(&host_set
, &frame
->uc
.tuc_sigmask
);
1529 sigprocmask(SIG_SETMASK
, &host_set
, NULL
);
1531 if (restore_sigcontext(env
, &frame
->uc
.tuc_mcontext
))
1534 if (do_sigaltstack(frame_addr
+ offsetof(struct rt_sigframe_v1
, uc
.tuc_stack
), 0, get_sp_from_cpustate(env
)) == -EFAULT
)
1538 /* Send SIGTRAP if we're single-stepping */
1539 if (ptrace_cancel_bpt(current
))
1540 send_sig(SIGTRAP
, current
, 1);
1542 unlock_user_struct(frame
, frame_addr
, 0);
1543 return env
->regs
[0];
1546 unlock_user_struct(frame
, frame_addr
, 0);
1547 force_sig(SIGSEGV
/* , current */);
1551 static long do_rt_sigreturn_v2(CPUState
*env
)
1553 abi_ulong frame_addr
;
1554 struct rt_sigframe_v2
*frame
;
1557 * Since we stacked the signal on a 64-bit boundary,
1558 * then 'sp' should be word aligned here. If it's
1559 * not, then the user is trying to mess with us.
1561 if (env
->regs
[13] & 7)
1564 frame_addr
= env
->regs
[13];
1565 if (!lock_user_struct(VERIFY_READ
, frame
, frame_addr
, 1))
1568 if (do_sigframe_return_v2(env
, frame_addr
, &frame
->uc
))
1571 unlock_user_struct(frame
, frame_addr
, 0);
1572 return env
->regs
[0];
1575 unlock_user_struct(frame
, frame_addr
, 0);
1576 force_sig(SIGSEGV
/* , current */);
1580 long do_rt_sigreturn(CPUState
*env
)
1582 if (get_osversion() >= 0x020612) {
1583 return do_rt_sigreturn_v2(env
);
1585 return do_rt_sigreturn_v1(env
);
1589 #elif defined(TARGET_SPARC)
1591 #define __SUNOS_MAXWIN 31
1593 /* This is what SunOS does, so shall I. */
1594 struct target_sigcontext
{
1595 abi_ulong sigc_onstack
; /* state to restore */
1597 abi_ulong sigc_mask
; /* sigmask to restore */
1598 abi_ulong sigc_sp
; /* stack pointer */
1599 abi_ulong sigc_pc
; /* program counter */
1600 abi_ulong sigc_npc
; /* next program counter */
1601 abi_ulong sigc_psr
; /* for condition codes etc */
1602 abi_ulong sigc_g1
; /* User uses these two registers */
1603 abi_ulong sigc_o0
; /* within the trampoline code. */
1605 /* Now comes information regarding the users window set
1606 * at the time of the signal.
1608 abi_ulong sigc_oswins
; /* outstanding windows */
1610 /* stack ptrs for each regwin buf */
1611 char *sigc_spbuf
[__SUNOS_MAXWIN
];
1613 /* Windows to restore after signal */
1615 abi_ulong locals
[8];
1617 } sigc_wbuf
[__SUNOS_MAXWIN
];
1619 /* A Sparc stack frame */
1620 struct sparc_stackf
{
1621 abi_ulong locals
[8];
1623 struct sparc_stackf
*fp
;
1624 abi_ulong callers_pc
;
1627 abi_ulong xxargs
[1];
1636 abi_ulong u_regs
[16]; /* globals and ins */
1642 unsigned long si_float_regs
[32];
1643 unsigned long si_fsr
;
1644 unsigned long si_fpqdepth
;
1646 unsigned long *insn_addr
;
1649 } qemu_siginfo_fpu_t
;
1652 struct target_signal_frame
{
1653 struct sparc_stackf ss
;
1656 abi_ulong insns
[2] __attribute__ ((aligned (8)));
1657 abi_ulong extramask
[TARGET_NSIG_WORDS
- 1];
1658 abi_ulong extra_size
; /* Should be 0 */
1659 qemu_siginfo_fpu_t fpu_state
;
1661 struct target_rt_signal_frame
{
1662 struct sparc_stackf ss
;
1667 unsigned int insns
[2];
1669 unsigned int extra_size
; /* Should be 0 */
1670 qemu_siginfo_fpu_t fpu_state
;
1684 #define UREG_FP UREG_I6
1685 #define UREG_SP UREG_O6
1687 static inline abi_ulong
get_sigframe(struct target_sigaction
*sa
,
1688 CPUState
*env
, unsigned long framesize
)
1692 sp
= env
->regwptr
[UREG_FP
];
1694 /* This is the X/Open sanctioned signal stack switching. */
1695 if (sa
->sa_flags
& TARGET_SA_ONSTACK
) {
1696 if (!on_sig_stack(sp
)
1697 && !((target_sigaltstack_used
.ss_sp
+ target_sigaltstack_used
.ss_size
) & 7))
1698 sp
= target_sigaltstack_used
.ss_sp
+ target_sigaltstack_used
.ss_size
;
1700 return sp
- framesize
;
1704 setup___siginfo(__siginfo_t
*si
, CPUState
*env
, abi_ulong mask
)
1708 err
|= __put_user(env
->psr
, &si
->si_regs
.psr
);
1709 err
|= __put_user(env
->pc
, &si
->si_regs
.pc
);
1710 err
|= __put_user(env
->npc
, &si
->si_regs
.npc
);
1711 err
|= __put_user(env
->y
, &si
->si_regs
.y
);
1712 for (i
=0; i
< 8; i
++) {
1713 err
|= __put_user(env
->gregs
[i
], &si
->si_regs
.u_regs
[i
]);
1715 for (i
=0; i
< 8; i
++) {
1716 err
|= __put_user(env
->regwptr
[UREG_I0
+ i
], &si
->si_regs
.u_regs
[i
+8]);
1718 err
|= __put_user(mask
, &si
->si_mask
);
1724 setup_sigcontext(struct target_sigcontext
*sc
, /*struct _fpstate *fpstate,*/
1725 CPUState
*env
, unsigned long mask
)
1729 err
|= __put_user(mask
, &sc
->sigc_mask
);
1730 err
|= __put_user(env
->regwptr
[UREG_SP
], &sc
->sigc_sp
);
1731 err
|= __put_user(env
->pc
, &sc
->sigc_pc
);
1732 err
|= __put_user(env
->npc
, &sc
->sigc_npc
);
1733 err
|= __put_user(env
->psr
, &sc
->sigc_psr
);
1734 err
|= __put_user(env
->gregs
[1], &sc
->sigc_g1
);
1735 err
|= __put_user(env
->regwptr
[UREG_O0
], &sc
->sigc_o0
);
1740 #define NF_ALIGNEDSZ (((sizeof(struct target_signal_frame) + 7) & (~7)))
1742 static void setup_frame(int sig
, struct target_sigaction
*ka
,
1743 target_sigset_t
*set
, CPUState
*env
)
1746 struct target_signal_frame
*sf
;
1747 int sigframe_size
, err
, i
;
1749 /* 1. Make sure everything is clean */
1750 //synchronize_user_stack();
1752 sigframe_size
= NF_ALIGNEDSZ
;
1753 sf_addr
= get_sigframe(ka
, env
, sigframe_size
);
1755 sf
= lock_user(VERIFY_WRITE
, sf_addr
,
1756 sizeof(struct target_signal_frame
), 0);
1760 //fprintf(stderr, "sf: %x pc %x fp %x sp %x\n", sf, env->pc, env->regwptr[UREG_FP], env->regwptr[UREG_SP]);
1762 if (invalid_frame_pointer(sf
, sigframe_size
))
1763 goto sigill_and_return
;
1765 /* 2. Save the current process state */
1766 err
= setup___siginfo(&sf
->info
, env
, set
->sig
[0]);
1767 err
|= __put_user(0, &sf
->extra_size
);
1769 //err |= save_fpu_state(regs, &sf->fpu_state);
1770 //err |= __put_user(&sf->fpu_state, &sf->fpu_save);
1772 err
|= __put_user(set
->sig
[0], &sf
->info
.si_mask
);
1773 for (i
= 0; i
< TARGET_NSIG_WORDS
- 1; i
++) {
1774 err
|= __put_user(set
->sig
[i
+ 1], &sf
->extramask
[i
]);
1777 for (i
= 0; i
< 8; i
++) {
1778 err
|= __put_user(env
->regwptr
[i
+ UREG_L0
], &sf
->ss
.locals
[i
]);
1780 for (i
= 0; i
< 8; i
++) {
1781 err
|= __put_user(env
->regwptr
[i
+ UREG_I0
], &sf
->ss
.ins
[i
]);
1786 /* 3. signal handler back-trampoline and parameters */
1787 env
->regwptr
[UREG_FP
] = sf_addr
;
1788 env
->regwptr
[UREG_I0
] = sig
;
1789 env
->regwptr
[UREG_I1
] = sf_addr
+
1790 offsetof(struct target_signal_frame
, info
);
1791 env
->regwptr
[UREG_I2
] = sf_addr
+
1792 offsetof(struct target_signal_frame
, info
);
1794 /* 4. signal handler */
1795 env
->pc
= ka
->_sa_handler
;
1796 env
->npc
= (env
->pc
+ 4);
1797 /* 5. return to kernel instructions */
1798 if (ka
->sa_restorer
)
1799 env
->regwptr
[UREG_I7
] = ka
->sa_restorer
;
1803 env
->regwptr
[UREG_I7
] = sf_addr
+
1804 offsetof(struct target_signal_frame
, insns
) - 2 * 4;
1806 /* mov __NR_sigreturn, %g1 */
1808 err
|= __put_user(val32
, &sf
->insns
[0]);
1812 err
|= __put_user(val32
, &sf
->insns
[1]);
1816 /* Flush instruction space. */
1817 //flush_sig_insns(current->mm, (unsigned long) &(sf->insns[0]));
1820 unlock_user(sf
, sf_addr
, sizeof(struct target_signal_frame
));
1824 force_sig(TARGET_SIGILL
);
1827 //fprintf(stderr, "force_sig\n");
1828 unlock_user(sf
, sf_addr
, sizeof(struct target_signal_frame
));
1829 force_sig(TARGET_SIGSEGV
);
1832 restore_fpu_state(CPUState
*env
, qemu_siginfo_fpu_t
*fpu
)
1837 if (current
->flags
& PF_USEDFPU
)
1838 regs
->psr
&= ~PSR_EF
;
1840 if (current
== last_task_used_math
) {
1841 last_task_used_math
= 0;
1842 regs
->psr
&= ~PSR_EF
;
1845 current
->used_math
= 1;
1846 current
->flags
&= ~PF_USEDFPU
;
1849 if (verify_area (VERIFY_READ
, fpu
, sizeof(*fpu
)))
1854 /* XXX: incorrect */
1855 err
= __copy_from_user(&env
->fpr
[0], &fpu
->si_float_regs
[0],
1856 (sizeof(unsigned long) * 32));
1858 err
|= __get_user(env
->fsr
, &fpu
->si_fsr
);
1860 err
|= __get_user(current
->thread
.fpqdepth
, &fpu
->si_fpqdepth
);
1861 if (current
->thread
.fpqdepth
!= 0)
1862 err
|= __copy_from_user(¤t
->thread
.fpqueue
[0],
1863 &fpu
->si_fpqueue
[0],
1864 ((sizeof(unsigned long) +
1865 (sizeof(unsigned long *)))*16));
1871 static void setup_rt_frame(int sig
, struct target_sigaction
*ka
,
1872 target_siginfo_t
*info
,
1873 target_sigset_t
*set
, CPUState
*env
)
1875 fprintf(stderr
, "setup_rt_frame: not implemented\n");
1878 long do_sigreturn(CPUState
*env
)
1881 struct target_signal_frame
*sf
;
1882 uint32_t up_psr
, pc
, npc
;
1883 target_sigset_t set
;
1885 abi_ulong fpu_save_addr
;
1888 sf_addr
= env
->regwptr
[UREG_FP
];
1889 if (!lock_user_struct(VERIFY_READ
, sf
, sf_addr
, 1))
1892 fprintf(stderr
, "sigreturn\n");
1893 fprintf(stderr
, "sf: %x pc %x fp %x sp %x\n", sf
, env
->pc
, env
->regwptr
[UREG_FP
], env
->regwptr
[UREG_SP
]);
1895 //cpu_dump_state(env, stderr, fprintf, 0);
1897 /* 1. Make sure we are not getting garbage from the user */
1902 err
= __get_user(pc
, &sf
->info
.si_regs
.pc
);
1903 err
|= __get_user(npc
, &sf
->info
.si_regs
.npc
);
1908 /* 2. Restore the state */
1909 err
|= __get_user(up_psr
, &sf
->info
.si_regs
.psr
);
1911 /* User can only change condition codes and FPU enabling in %psr. */
1912 env
->psr
= (up_psr
& (PSR_ICC
/* | PSR_EF */))
1913 | (env
->psr
& ~(PSR_ICC
/* | PSR_EF */));
1917 err
|= __get_user(env
->y
, &sf
->info
.si_regs
.y
);
1918 for (i
=0; i
< 8; i
++) {
1919 err
|= __get_user(env
->gregs
[i
], &sf
->info
.si_regs
.u_regs
[i
]);
1921 for (i
=0; i
< 8; i
++) {
1922 err
|= __get_user(env
->regwptr
[i
+ UREG_I0
], &sf
->info
.si_regs
.u_regs
[i
+8]);
1925 err
|= __get_user(fpu_save_addr
, &sf
->fpu_save
);
1928 // err |= restore_fpu_state(env, fpu_save);
1930 /* This is pretty much atomic, no amount locking would prevent
1931 * the races which exist anyways.
1933 err
|= __get_user(set
.sig
[0], &sf
->info
.si_mask
);
1934 for(i
= 1; i
< TARGET_NSIG_WORDS
; i
++) {
1935 err
|= (__get_user(set
.sig
[i
], &sf
->extramask
[i
- 1]));
1938 target_to_host_sigset_internal(&host_set
, &set
);
1939 sigprocmask(SIG_SETMASK
, &host_set
, NULL
);
1943 unlock_user_struct(sf
, sf_addr
, 0);
1944 return env
->regwptr
[0];
1947 unlock_user_struct(sf
, sf_addr
, 0);
1948 force_sig(TARGET_SIGSEGV
);
1951 long do_rt_sigreturn(CPUState
*env
)
1953 fprintf(stderr
, "do_rt_sigreturn: not implemented\n");
1954 return -TARGET_ENOSYS
;
1957 #if defined(TARGET_SPARC64) && !defined(TARGET_ABI32)
1979 typedef abi_ulong target_mc_greg_t
;
1980 typedef target_mc_greg_t target_mc_gregset_t
[MC_NGREG
];
1982 struct target_mc_fq
{
1983 abi_ulong
*mcfq_addr
;
1987 struct target_mc_fpu
{
1991 //uint128_t qregs[16];
1993 abi_ulong mcfpu_fsr
;
1994 abi_ulong mcfpu_fprs
;
1995 abi_ulong mcfpu_gsr
;
1996 struct target_mc_fq
*mcfpu_fq
;
1997 unsigned char mcfpu_qcnt
;
1998 unsigned char mcfpu_qentsz
;
1999 unsigned char mcfpu_enab
;
2001 typedef struct target_mc_fpu target_mc_fpu_t
;
2004 target_mc_gregset_t mc_gregs
;
2005 target_mc_greg_t mc_fp
;
2006 target_mc_greg_t mc_i7
;
2007 target_mc_fpu_t mc_fpregs
;
2008 } target_mcontext_t
;
2010 struct target_ucontext
{
2011 struct target_ucontext
*uc_link
;
2013 target_sigset_t uc_sigmask
;
2014 target_mcontext_t uc_mcontext
;
2017 /* A V9 register window */
2018 struct target_reg_window
{
2019 abi_ulong locals
[8];
2023 #define TARGET_STACK_BIAS 2047
2025 /* {set, get}context() needed for 64-bit SparcLinux userland. */
2026 void sparc64_set_context(CPUSPARCState
*env
)
2029 struct target_ucontext
*ucp
;
2030 target_mc_gregset_t
*grp
;
2031 abi_ulong pc
, npc
, tstate
;
2032 abi_ulong fp
, i7
, w_addr
;
2033 unsigned char fenab
;
2037 ucp_addr
= env
->regwptr
[UREG_I0
];
2038 if (!lock_user_struct(VERIFY_READ
, ucp
, ucp_addr
, 1))
2040 grp
= &ucp
->uc_mcontext
.mc_gregs
;
2041 err
= __get_user(pc
, &((*grp
)[MC_PC
]));
2042 err
|= __get_user(npc
, &((*grp
)[MC_NPC
]));
2043 if (err
|| ((pc
| npc
) & 3))
2045 if (env
->regwptr
[UREG_I1
]) {
2046 target_sigset_t target_set
;
2049 if (TARGET_NSIG_WORDS
== 1) {
2050 if (__get_user(target_set
.sig
[0], &ucp
->uc_sigmask
.sig
[0]))
2053 abi_ulong
*src
, *dst
;
2054 src
= ucp
->uc_sigmask
.sig
;
2055 dst
= target_set
.sig
;
2056 for (i
= 0; i
< sizeof(target_sigset_t
) / sizeof(abi_ulong
);
2058 err
|= __get_user(*dst
, src
);
2062 target_to_host_sigset_internal(&set
, &target_set
);
2063 sigprocmask(SIG_SETMASK
, &set
, NULL
);
2067 err
|= __get_user(env
->y
, &((*grp
)[MC_Y
]));
2068 err
|= __get_user(tstate
, &((*grp
)[MC_TSTATE
]));
2069 env
->asi
= (tstate
>> 24) & 0xff;
2070 PUT_CCR(env
, tstate
>> 32);
2071 PUT_CWP64(env
, tstate
& 0x1f);
2072 err
|= __get_user(env
->gregs
[1], (&(*grp
)[MC_G1
]));
2073 err
|= __get_user(env
->gregs
[2], (&(*grp
)[MC_G2
]));
2074 err
|= __get_user(env
->gregs
[3], (&(*grp
)[MC_G3
]));
2075 err
|= __get_user(env
->gregs
[4], (&(*grp
)[MC_G4
]));
2076 err
|= __get_user(env
->gregs
[5], (&(*grp
)[MC_G5
]));
2077 err
|= __get_user(env
->gregs
[6], (&(*grp
)[MC_G6
]));
2078 err
|= __get_user(env
->gregs
[7], (&(*grp
)[MC_G7
]));
2079 err
|= __get_user(env
->regwptr
[UREG_I0
], (&(*grp
)[MC_O0
]));
2080 err
|= __get_user(env
->regwptr
[UREG_I1
], (&(*grp
)[MC_O1
]));
2081 err
|= __get_user(env
->regwptr
[UREG_I2
], (&(*grp
)[MC_O2
]));
2082 err
|= __get_user(env
->regwptr
[UREG_I3
], (&(*grp
)[MC_O3
]));
2083 err
|= __get_user(env
->regwptr
[UREG_I4
], (&(*grp
)[MC_O4
]));
2084 err
|= __get_user(env
->regwptr
[UREG_I5
], (&(*grp
)[MC_O5
]));
2085 err
|= __get_user(env
->regwptr
[UREG_I6
], (&(*grp
)[MC_O6
]));
2086 err
|= __get_user(env
->regwptr
[UREG_I7
], (&(*grp
)[MC_O7
]));
2088 err
|= __get_user(fp
, &(ucp
->uc_mcontext
.mc_fp
));
2089 err
|= __get_user(i7
, &(ucp
->uc_mcontext
.mc_i7
));
2091 w_addr
= TARGET_STACK_BIAS
+env
->regwptr
[UREG_I6
];
2092 if (put_user(fp
, w_addr
+ offsetof(struct target_reg_window
, ins
[6]),
2095 if (put_user(i7
, w_addr
+ offsetof(struct target_reg_window
, ins
[7]),
2098 err
|= __get_user(fenab
, &(ucp
->uc_mcontext
.mc_fpregs
.mcfpu_enab
));
2099 err
|= __get_user(env
->fprs
, &(ucp
->uc_mcontext
.mc_fpregs
.mcfpu_fprs
));
2101 uint32_t *src
, *dst
;
2102 src
= ucp
->uc_mcontext
.mc_fpregs
.mcfpu_fregs
.sregs
;
2104 /* XXX: check that the CPU storage is the same as user context */
2105 for (i
= 0; i
< 64; i
++, dst
++, src
++)
2106 err
|= __get_user(*dst
, src
);
2108 err
|= __get_user(env
->fsr
,
2109 &(ucp
->uc_mcontext
.mc_fpregs
.mcfpu_fsr
));
2110 err
|= __get_user(env
->gsr
,
2111 &(ucp
->uc_mcontext
.mc_fpregs
.mcfpu_gsr
));
2114 unlock_user_struct(ucp
, ucp_addr
, 0);
2117 unlock_user_struct(ucp
, ucp_addr
, 0);
2121 void sparc64_get_context(CPUSPARCState
*env
)
2124 struct target_ucontext
*ucp
;
2125 target_mc_gregset_t
*grp
;
2126 target_mcontext_t
*mcp
;
2127 abi_ulong fp
, i7
, w_addr
;
2130 target_sigset_t target_set
;
2133 ucp_addr
= env
->regwptr
[UREG_I0
];
2134 if (!lock_user_struct(VERIFY_WRITE
, ucp
, ucp_addr
, 0))
2137 mcp
= &ucp
->uc_mcontext
;
2138 grp
= &mcp
->mc_gregs
;
2140 /* Skip over the trap instruction, first. */
2146 sigprocmask(0, NULL
, &set
);
2147 host_to_target_sigset_internal(&target_set
, &set
);
2148 if (TARGET_NSIG_WORDS
== 1) {
2149 err
|= __put_user(target_set
.sig
[0],
2150 (abi_ulong
*)&ucp
->uc_sigmask
);
2152 abi_ulong
*src
, *dst
;
2153 src
= target_set
.sig
;
2154 dst
= ucp
->uc_sigmask
.sig
;
2155 for (i
= 0; i
< sizeof(target_sigset_t
) / sizeof(abi_ulong
);
2157 err
|= __put_user(*src
, dst
);
2162 /* XXX: tstate must be saved properly */
2163 // err |= __put_user(env->tstate, &((*grp)[MC_TSTATE]));
2164 err
|= __put_user(env
->pc
, &((*grp
)[MC_PC
]));
2165 err
|= __put_user(env
->npc
, &((*grp
)[MC_NPC
]));
2166 err
|= __put_user(env
->y
, &((*grp
)[MC_Y
]));
2167 err
|= __put_user(env
->gregs
[1], &((*grp
)[MC_G1
]));
2168 err
|= __put_user(env
->gregs
[2], &((*grp
)[MC_G2
]));
2169 err
|= __put_user(env
->gregs
[3], &((*grp
)[MC_G3
]));
2170 err
|= __put_user(env
->gregs
[4], &((*grp
)[MC_G4
]));
2171 err
|= __put_user(env
->gregs
[5], &((*grp
)[MC_G5
]));
2172 err
|= __put_user(env
->gregs
[6], &((*grp
)[MC_G6
]));
2173 err
|= __put_user(env
->gregs
[7], &((*grp
)[MC_G7
]));
2174 err
|= __put_user(env
->regwptr
[UREG_I0
], &((*grp
)[MC_O0
]));
2175 err
|= __put_user(env
->regwptr
[UREG_I1
], &((*grp
)[MC_O1
]));
2176 err
|= __put_user(env
->regwptr
[UREG_I2
], &((*grp
)[MC_O2
]));
2177 err
|= __put_user(env
->regwptr
[UREG_I3
], &((*grp
)[MC_O3
]));
2178 err
|= __put_user(env
->regwptr
[UREG_I4
], &((*grp
)[MC_O4
]));
2179 err
|= __put_user(env
->regwptr
[UREG_I5
], &((*grp
)[MC_O5
]));
2180 err
|= __put_user(env
->regwptr
[UREG_I6
], &((*grp
)[MC_O6
]));
2181 err
|= __put_user(env
->regwptr
[UREG_I7
], &((*grp
)[MC_O7
]));
2183 w_addr
= TARGET_STACK_BIAS
+env
->regwptr
[UREG_I6
];
2185 if (get_user(fp
, w_addr
+ offsetof(struct target_reg_window
, ins
[6]),
2188 if (get_user(i7
, w_addr
+ offsetof(struct target_reg_window
, ins
[7]),
2191 err
|= __put_user(fp
, &(mcp
->mc_fp
));
2192 err
|= __put_user(i7
, &(mcp
->mc_i7
));
2195 uint32_t *src
, *dst
;
2197 dst
= ucp
->uc_mcontext
.mc_fpregs
.mcfpu_fregs
.sregs
;
2198 /* XXX: check that the CPU storage is the same as user context */
2199 for (i
= 0; i
< 64; i
++, dst
++, src
++)
2200 err
|= __put_user(*src
, dst
);
2202 err
|= __put_user(env
->fsr
, &(mcp
->mc_fpregs
.mcfpu_fsr
));
2203 err
|= __put_user(env
->gsr
, &(mcp
->mc_fpregs
.mcfpu_gsr
));
2204 err
|= __put_user(env
->fprs
, &(mcp
->mc_fpregs
.mcfpu_fprs
));
2208 unlock_user_struct(ucp
, ucp_addr
, 1);
2211 unlock_user_struct(ucp
, ucp_addr
, 1);
2215 #elif defined(TARGET_ABI_MIPSN64)
2217 # warning signal handling not implemented
2219 static void setup_frame(int sig
, struct target_sigaction
*ka
,
2220 target_sigset_t
*set
, CPUState
*env
)
2222 fprintf(stderr
, "setup_frame: not implemented\n");
2225 static void setup_rt_frame(int sig
, struct target_sigaction
*ka
,
2226 target_siginfo_t
*info
,
2227 target_sigset_t
*set
, CPUState
*env
)
2229 fprintf(stderr
, "setup_rt_frame: not implemented\n");
2232 long do_sigreturn(CPUState
*env
)
2234 fprintf(stderr
, "do_sigreturn: not implemented\n");
2235 return -TARGET_ENOSYS
;
2238 long do_rt_sigreturn(CPUState
*env
)
2240 fprintf(stderr
, "do_rt_sigreturn: not implemented\n");
2241 return -TARGET_ENOSYS
;
2244 #elif defined(TARGET_ABI_MIPSN32)
2246 # warning signal handling not implemented
2248 static void setup_frame(int sig
, struct target_sigaction
*ka
,
2249 target_sigset_t
*set
, CPUState
*env
)
2251 fprintf(stderr
, "setup_frame: not implemented\n");
2254 static void setup_rt_frame(int sig
, struct target_sigaction
*ka
,
2255 target_siginfo_t
*info
,
2256 target_sigset_t
*set
, CPUState
*env
)
2258 fprintf(stderr
, "setup_rt_frame: not implemented\n");
2261 long do_sigreturn(CPUState
*env
)
2263 fprintf(stderr
, "do_sigreturn: not implemented\n");
2264 return -TARGET_ENOSYS
;
2267 long do_rt_sigreturn(CPUState
*env
)
2269 fprintf(stderr
, "do_rt_sigreturn: not implemented\n");
2270 return -TARGET_ENOSYS
;
2273 #elif defined(TARGET_ABI_MIPSO32)
2275 struct target_sigcontext
{
2276 uint32_t sc_regmask
; /* Unused */
2279 uint64_t sc_regs
[32];
2280 uint64_t sc_fpregs
[32];
2281 uint32_t sc_ownedfp
; /* Unused */
2282 uint32_t sc_fpc_csr
;
2283 uint32_t sc_fpc_eir
; /* Unused */
2284 uint32_t sc_used_math
;
2285 uint32_t sc_dsp
; /* dsp status, was sc_ssflags */
2288 target_ulong sc_hi1
; /* Was sc_cause */
2289 target_ulong sc_lo1
; /* Was sc_badvaddr */
2290 target_ulong sc_hi2
; /* Was sc_sigset[4] */
2291 target_ulong sc_lo2
;
2292 target_ulong sc_hi3
;
2293 target_ulong sc_lo3
;
2297 uint32_t sf_ass
[4]; /* argument save space for o32 */
2298 uint32_t sf_code
[2]; /* signal trampoline */
2299 struct target_sigcontext sf_sc
;
2300 target_sigset_t sf_mask
;
2303 /* Install trampoline to jump back from signal handler */
2304 static inline int install_sigtramp(unsigned int *tramp
, unsigned int syscall
)
2309 * Set up the return code ...
2311 * li v0, __NR__foo_sigreturn
2315 err
= __put_user(0x24020000 + syscall
, tramp
+ 0);
2316 err
|= __put_user(0x0000000c , tramp
+ 1);
2317 /* flush_cache_sigtramp((unsigned long) tramp); */
2322 setup_sigcontext(CPUState
*regs
, struct target_sigcontext
*sc
)
2326 err
|= __put_user(regs
->active_tc
.PC
, &sc
->sc_pc
);
2328 #define save_gp_reg(i) do { \
2329 err |= __put_user(regs->active_tc.gpr[i], &sc->sc_regs[i]); \
2331 __put_user(0, &sc
->sc_regs
[0]); save_gp_reg(1); save_gp_reg(2);
2332 save_gp_reg(3); save_gp_reg(4); save_gp_reg(5); save_gp_reg(6);
2333 save_gp_reg(7); save_gp_reg(8); save_gp_reg(9); save_gp_reg(10);
2334 save_gp_reg(11); save_gp_reg(12); save_gp_reg(13); save_gp_reg(14);
2335 save_gp_reg(15); save_gp_reg(16); save_gp_reg(17); save_gp_reg(18);
2336 save_gp_reg(19); save_gp_reg(20); save_gp_reg(21); save_gp_reg(22);
2337 save_gp_reg(23); save_gp_reg(24); save_gp_reg(25); save_gp_reg(26);
2338 save_gp_reg(27); save_gp_reg(28); save_gp_reg(29); save_gp_reg(30);
2342 err
|= __put_user(regs
->active_tc
.HI
[0], &sc
->sc_mdhi
);
2343 err
|= __put_user(regs
->active_tc
.LO
[0], &sc
->sc_mdlo
);
2345 /* Not used yet, but might be useful if we ever have DSP suppport */
2348 err
|= __put_user(mfhi1(), &sc
->sc_hi1
);
2349 err
|= __put_user(mflo1(), &sc
->sc_lo1
);
2350 err
|= __put_user(mfhi2(), &sc
->sc_hi2
);
2351 err
|= __put_user(mflo2(), &sc
->sc_lo2
);
2352 err
|= __put_user(mfhi3(), &sc
->sc_hi3
);
2353 err
|= __put_user(mflo3(), &sc
->sc_lo3
);
2354 err
|= __put_user(rddsp(DSP_MASK
), &sc
->sc_dsp
);
2356 /* same with 64 bit */
2358 err
|= __put_user(regs
->hi
, &sc
->sc_hi
[0]);
2359 err
|= __put_user(regs
->lo
, &sc
->sc_lo
[0]);
2361 err
|= __put_user(mfhi1(), &sc
->sc_hi
[1]);
2362 err
|= __put_user(mflo1(), &sc
->sc_lo
[1]);
2363 err
|= __put_user(mfhi2(), &sc
->sc_hi
[2]);
2364 err
|= __put_user(mflo2(), &sc
->sc_lo
[2]);
2365 err
|= __put_user(mfhi3(), &sc
->sc_hi
[3]);
2366 err
|= __put_user(mflo3(), &sc
->sc_lo
[3]);
2367 err
|= __put_user(rddsp(DSP_MASK
), &sc
->sc_dsp
);
2373 err
|= __put_user(!!used_math(), &sc
->sc_used_math
);
2379 * Save FPU state to signal context. Signal handler will "inherit"
2380 * current FPU state.
2384 if (!is_fpu_owner()) {
2386 restore_fp(current
);
2388 err
|= save_fp_context(sc
);
2397 restore_sigcontext(CPUState
*regs
, struct target_sigcontext
*sc
)
2401 err
|= __get_user(regs
->CP0_EPC
, &sc
->sc_pc
);
2403 err
|= __get_user(regs
->active_tc
.HI
[0], &sc
->sc_mdhi
);
2404 err
|= __get_user(regs
->active_tc
.LO
[0], &sc
->sc_mdlo
);
2406 #define restore_gp_reg(i) do { \
2407 err |= __get_user(regs->active_tc.gpr[i], &sc->sc_regs[i]); \
2409 restore_gp_reg( 1); restore_gp_reg( 2); restore_gp_reg( 3);
2410 restore_gp_reg( 4); restore_gp_reg( 5); restore_gp_reg( 6);
2411 restore_gp_reg( 7); restore_gp_reg( 8); restore_gp_reg( 9);
2412 restore_gp_reg(10); restore_gp_reg(11); restore_gp_reg(12);
2413 restore_gp_reg(13); restore_gp_reg(14); restore_gp_reg(15);
2414 restore_gp_reg(16); restore_gp_reg(17); restore_gp_reg(18);
2415 restore_gp_reg(19); restore_gp_reg(20); restore_gp_reg(21);
2416 restore_gp_reg(22); restore_gp_reg(23); restore_gp_reg(24);
2417 restore_gp_reg(25); restore_gp_reg(26); restore_gp_reg(27);
2418 restore_gp_reg(28); restore_gp_reg(29); restore_gp_reg(30);
2420 #undef restore_gp_reg
2424 err
|= __get_user(treg
, &sc
->sc_hi1
); mthi1(treg
);
2425 err
|= __get_user(treg
, &sc
->sc_lo1
); mtlo1(treg
);
2426 err
|= __get_user(treg
, &sc
->sc_hi2
); mthi2(treg
);
2427 err
|= __get_user(treg
, &sc
->sc_lo2
); mtlo2(treg
);
2428 err
|= __get_user(treg
, &sc
->sc_hi3
); mthi3(treg
);
2429 err
|= __get_user(treg
, &sc
->sc_lo3
); mtlo3(treg
);
2430 err
|= __get_user(treg
, &sc
->sc_dsp
); wrdsp(treg
, DSP_MASK
);
2433 err
|= __get_user(regs
->hi
, &sc
->sc_hi
[0]);
2434 err
|= __get_user(regs
->lo
, &sc
->sc_lo
[0]);
2436 err
|= __get_user(treg
, &sc
->sc_hi
[1]); mthi1(treg
);
2437 err
|= __get_user(treg
, &sc
->sc_lo
[1]); mthi1(treg
);
2438 err
|= __get_user(treg
, &sc
->sc_hi
[2]); mthi2(treg
);
2439 err
|= __get_user(treg
, &sc
->sc_lo
[2]); mthi2(treg
);
2440 err
|= __get_user(treg
, &sc
->sc_hi
[3]); mthi3(treg
);
2441 err
|= __get_user(treg
, &sc
->sc_lo
[3]); mthi3(treg
);
2442 err
|= __get_user(treg
, &sc
->sc_dsp
); wrdsp(treg
, DSP_MASK
);
2446 err
|= __get_user(used_math
, &sc
->sc_used_math
);
2447 conditional_used_math(used_math
);
2452 /* restore fpu context if we have used it before */
2454 err
|= restore_fp_context(sc
);
2456 /* signal handler may have used FPU. Give it up. */
2465 * Determine which stack to use..
2467 static inline abi_ulong
2468 get_sigframe(struct target_sigaction
*ka
, CPUState
*regs
, size_t frame_size
)
2472 /* Default to using normal stack */
2473 sp
= regs
->active_tc
.gpr
[29];
2476 * FPU emulator may have it's own trampoline active just
2477 * above the user stack, 16-bytes before the next lowest
2478 * 16 byte boundary. Try to avoid trashing it.
2482 /* This is the X/Open sanctioned signal stack switching. */
2483 if ((ka
->sa_flags
& TARGET_SA_ONSTACK
) && (sas_ss_flags (sp
) == 0)) {
2484 sp
= target_sigaltstack_used
.ss_sp
+ target_sigaltstack_used
.ss_size
;
2487 return (sp
- frame_size
) & ~7;
2490 /* compare linux/arch/mips/kernel/signal.c:setup_frame() */
2491 static void setup_frame(int sig
, struct target_sigaction
* ka
,
2492 target_sigset_t
*set
, CPUState
*regs
)
2494 struct sigframe
*frame
;
2495 abi_ulong frame_addr
;
2498 frame_addr
= get_sigframe(ka
, regs
, sizeof(*frame
));
2499 if (!lock_user_struct(VERIFY_WRITE
, frame
, frame_addr
, 0))
2502 install_sigtramp(frame
->sf_code
, TARGET_NR_sigreturn
);
2504 if(setup_sigcontext(regs
, &frame
->sf_sc
))
2507 for(i
= 0; i
< TARGET_NSIG_WORDS
; i
++) {
2508 if(__put_user(set
->sig
[i
], &frame
->sf_mask
.sig
[i
]))
2513 * Arguments to signal handler:
2515 * a0 = signal number
2516 * a1 = 0 (should be cause)
2517 * a2 = pointer to struct sigcontext
2519 * $25 and PC point to the signal handler, $29 points to the
2522 regs
->active_tc
.gpr
[ 4] = sig
;
2523 regs
->active_tc
.gpr
[ 5] = 0;
2524 regs
->active_tc
.gpr
[ 6] = frame_addr
+ offsetof(struct sigframe
, sf_sc
);
2525 regs
->active_tc
.gpr
[29] = frame_addr
;
2526 regs
->active_tc
.gpr
[31] = frame_addr
+ offsetof(struct sigframe
, sf_code
);
2527 /* The original kernel code sets CP0_EPC to the handler
2528 * since it returns to userland using eret
2529 * we cannot do this here, and we must set PC directly */
2530 regs
->active_tc
.PC
= regs
->active_tc
.gpr
[25] = ka
->_sa_handler
;
2531 unlock_user_struct(frame
, frame_addr
, 1);
2535 unlock_user_struct(frame
, frame_addr
, 1);
2536 force_sig(TARGET_SIGSEGV
/*, current*/);
2540 long do_sigreturn(CPUState
*regs
)
2542 struct sigframe
*frame
;
2543 abi_ulong frame_addr
;
2545 target_sigset_t target_set
;
2548 #if defined(DEBUG_SIGNAL)
2549 fprintf(stderr
, "do_sigreturn\n");
2551 frame_addr
= regs
->active_tc
.gpr
[29];
2552 if (!lock_user_struct(VERIFY_READ
, frame
, frame_addr
, 1))
2555 for(i
= 0; i
< TARGET_NSIG_WORDS
; i
++) {
2556 if(__get_user(target_set
.sig
[i
], &frame
->sf_mask
.sig
[i
]))
2560 target_to_host_sigset_internal(&blocked
, &target_set
);
2561 sigprocmask(SIG_SETMASK
, &blocked
, NULL
);
2563 if (restore_sigcontext(regs
, &frame
->sf_sc
))
2568 * Don't let your children do this ...
2570 __asm__
__volatile__(
2578 regs
->active_tc
.PC
= regs
->CP0_EPC
;
2579 /* I am not sure this is right, but it seems to work
2580 * maybe a problem with nested signals ? */
2585 force_sig(TARGET_SIGSEGV
/*, current*/);
2589 static void setup_rt_frame(int sig
, struct target_sigaction
*ka
,
2590 target_siginfo_t
*info
,
2591 target_sigset_t
*set
, CPUState
*env
)
2593 fprintf(stderr
, "setup_rt_frame: not implemented\n");
2596 long do_rt_sigreturn(CPUState
*env
)
2598 fprintf(stderr
, "do_rt_sigreturn: not implemented\n");
2599 return -TARGET_ENOSYS
;
2602 #elif defined(TARGET_SH4)
2605 * code and data structures from linux kernel:
2606 * include/asm-sh/sigcontext.h
2607 * arch/sh/kernel/signal.c
2610 struct target_sigcontext
{
2611 target_ulong oldmask
;
2614 target_ulong sc_gregs
[16];
2618 target_ulong sc_gbr
;
2619 target_ulong sc_mach
;
2620 target_ulong sc_macl
;
2623 target_ulong sc_fpregs
[16];
2624 target_ulong sc_xfpregs
[16];
2625 unsigned int sc_fpscr
;
2626 unsigned int sc_fpul
;
2627 unsigned int sc_ownedfp
;
2630 struct target_sigframe
2632 struct target_sigcontext sc
;
2633 target_ulong extramask
[TARGET_NSIG_WORDS
-1];
2634 uint16_t retcode
[3];
2638 struct target_ucontext
{
2639 target_ulong uc_flags
;
2640 struct target_ucontext
*uc_link
;
2641 target_stack_t uc_stack
;
2642 struct target_sigcontext uc_mcontext
;
2643 target_sigset_t uc_sigmask
; /* mask last for extensibility */
2646 struct target_rt_sigframe
2648 struct target_siginfo info
;
2649 struct target_ucontext uc
;
2650 uint16_t retcode
[3];
2654 #define MOVW(n) (0x9300|((n)-2)) /* Move mem word at PC+n to R3 */
2655 #define TRAP_NOARG 0xc310 /* Syscall w/no args (NR in R3) SH3/4 */
2657 static abi_ulong
get_sigframe(struct target_sigaction
*ka
,
2658 unsigned long sp
, size_t frame_size
)
2660 if ((ka
->sa_flags
& TARGET_SA_ONSTACK
) && (sas_ss_flags(sp
) == 0)) {
2661 sp
= target_sigaltstack_used
.ss_sp
+ target_sigaltstack_used
.ss_size
;
2664 return (sp
- frame_size
) & -8ul;
2667 static int setup_sigcontext(struct target_sigcontext
*sc
,
2668 CPUState
*regs
, unsigned long mask
)
2672 #define COPY(x) err |= __put_user(regs->x, &sc->sc_##x)
2673 COPY(gregs
[0]); COPY(gregs
[1]);
2674 COPY(gregs
[2]); COPY(gregs
[3]);
2675 COPY(gregs
[4]); COPY(gregs
[5]);
2676 COPY(gregs
[6]); COPY(gregs
[7]);
2677 COPY(gregs
[8]); COPY(gregs
[9]);
2678 COPY(gregs
[10]); COPY(gregs
[11]);
2679 COPY(gregs
[12]); COPY(gregs
[13]);
2680 COPY(gregs
[14]); COPY(gregs
[15]);
2681 COPY(gbr
); COPY(mach
);
2682 COPY(macl
); COPY(pr
);
2686 /* todo: save FPU registers here */
2688 /* non-iBCS2 extensions.. */
2689 err
|= __put_user(mask
, &sc
->oldmask
);
2694 static int restore_sigcontext(struct CPUState
*regs
,
2695 struct target_sigcontext
*sc
)
2697 unsigned int err
= 0;
2699 #define COPY(x) err |= __get_user(regs->x, &sc->sc_##x)
2701 COPY(gregs
[2]); COPY(gregs
[3]);
2702 COPY(gregs
[4]); COPY(gregs
[5]);
2703 COPY(gregs
[6]); COPY(gregs
[7]);
2704 COPY(gregs
[8]); COPY(gregs
[9]);
2705 COPY(gregs
[10]); COPY(gregs
[11]);
2706 COPY(gregs
[12]); COPY(gregs
[13]);
2707 COPY(gregs
[14]); COPY(gregs
[15]);
2708 COPY(gbr
); COPY(mach
);
2709 COPY(macl
); COPY(pr
);
2713 /* todo: restore FPU registers here */
2715 regs
->tra
= -1; /* disable syscall checks */
2719 static void setup_frame(int sig
, struct target_sigaction
*ka
,
2720 target_sigset_t
*set
, CPUState
*regs
)
2722 struct target_sigframe
*frame
;
2723 abi_ulong frame_addr
;
2728 frame_addr
= get_sigframe(ka
, regs
->gregs
[15], sizeof(*frame
));
2729 if (!lock_user_struct(VERIFY_WRITE
, frame
, frame_addr
, 0))
2732 signal
= current_exec_domain_sig(sig
);
2734 err
|= setup_sigcontext(&frame
->sc
, regs
, set
->sig
[0]);
2736 for (i
= 0; i
< TARGET_NSIG_WORDS
- 1; i
++) {
2737 err
|= __put_user(set
->sig
[i
+ 1], &frame
->extramask
[i
]);
2740 /* Set up to return from userspace. If provided, use a stub
2741 already in userspace. */
2742 if (ka
->sa_flags
& TARGET_SA_RESTORER
) {
2743 regs
->pr
= (unsigned long) ka
->sa_restorer
;
2745 /* Generate return code (system call to sigreturn) */
2746 err
|= __put_user(MOVW(2), &frame
->retcode
[0]);
2747 err
|= __put_user(TRAP_NOARG
, &frame
->retcode
[1]);
2748 err
|= __put_user((TARGET_NR_sigreturn
), &frame
->retcode
[2]);
2749 regs
->pr
= (unsigned long) frame
->retcode
;
2755 /* Set up registers for signal handler */
2756 regs
->gregs
[15] = (unsigned long) frame
;
2757 regs
->gregs
[4] = signal
; /* Arg for signal handler */
2759 regs
->gregs
[6] = (unsigned long) &frame
->sc
;
2760 regs
->pc
= (unsigned long) ka
->_sa_handler
;
2762 unlock_user_struct(frame
, frame_addr
, 1);
2766 unlock_user_struct(frame
, frame_addr
, 1);
2770 static void setup_rt_frame(int sig
, struct target_sigaction
*ka
,
2771 target_siginfo_t
*info
,
2772 target_sigset_t
*set
, CPUState
*regs
)
2774 struct target_rt_sigframe
*frame
;
2775 abi_ulong frame_addr
;
2780 frame_addr
= get_sigframe(ka
, regs
->gregs
[15], sizeof(*frame
));
2781 if (!lock_user_struct(VERIFY_WRITE
, frame
, frame_addr
, 0))
2784 signal
= current_exec_domain_sig(sig
);
2786 err
|= copy_siginfo_to_user(&frame
->info
, info
);
2788 /* Create the ucontext. */
2789 err
|= __put_user(0, &frame
->uc
.uc_flags
);
2790 err
|= __put_user(0, (unsigned long *)&frame
->uc
.uc_link
);
2791 err
|= __put_user((unsigned long)target_sigaltstack_used
.ss_sp
,
2792 &frame
->uc
.uc_stack
.ss_sp
);
2793 err
|= __put_user(sas_ss_flags(regs
->gregs
[15]),
2794 &frame
->uc
.uc_stack
.ss_flags
);
2795 err
|= __put_user(target_sigaltstack_used
.ss_size
,
2796 &frame
->uc
.uc_stack
.ss_size
);
2797 err
|= setup_sigcontext(&frame
->uc
.uc_mcontext
,
2799 for(i
= 0; i
< TARGET_NSIG_WORDS
; i
++) {
2800 err
|= __put_user(set
->sig
[i
], &frame
->uc
.uc_sigmask
.sig
[i
]);
2803 /* Set up to return from userspace. If provided, use a stub
2804 already in userspace. */
2805 if (ka
->sa_flags
& TARGET_SA_RESTORER
) {
2806 regs
->pr
= (unsigned long) ka
->sa_restorer
;
2808 /* Generate return code (system call to sigreturn) */
2809 err
|= __put_user(MOVW(2), &frame
->retcode
[0]);
2810 err
|= __put_user(TRAP_NOARG
, &frame
->retcode
[1]);
2811 err
|= __put_user((TARGET_NR_rt_sigreturn
), &frame
->retcode
[2]);
2812 regs
->pr
= (unsigned long) frame
->retcode
;
2818 /* Set up registers for signal handler */
2819 regs
->gregs
[15] = (unsigned long) frame
;
2820 regs
->gregs
[4] = signal
; /* Arg for signal handler */
2821 regs
->gregs
[5] = (unsigned long) &frame
->info
;
2822 regs
->gregs
[6] = (unsigned long) &frame
->uc
;
2823 regs
->pc
= (unsigned long) ka
->_sa_handler
;
2825 unlock_user_struct(frame
, frame_addr
, 1);
2829 unlock_user_struct(frame
, frame_addr
, 1);
2833 long do_sigreturn(CPUState
*regs
)
2835 struct target_sigframe
*frame
;
2836 abi_ulong frame_addr
;
2838 target_sigset_t target_set
;
2842 #if defined(DEBUG_SIGNAL)
2843 fprintf(stderr
, "do_sigreturn\n");
2845 frame_addr
= regs
->gregs
[15];
2846 if (!lock_user_struct(VERIFY_READ
, frame
, frame_addr
, 1))
2849 err
|= __get_user(target_set
.sig
[0], &frame
->sc
.oldmask
);
2850 for(i
= 1; i
< TARGET_NSIG_WORDS
; i
++) {
2851 err
|= (__get_user(target_set
.sig
[i
], &frame
->extramask
[i
- 1]));
2857 target_to_host_sigset_internal(&blocked
, &target_set
);
2858 sigprocmask(SIG_SETMASK
, &blocked
, NULL
);
2860 if (restore_sigcontext(regs
, &frame
->sc
))
2863 unlock_user_struct(frame
, frame_addr
, 0);
2864 return regs
->gregs
[0];
2867 unlock_user_struct(frame
, frame_addr
, 0);
2868 force_sig(TARGET_SIGSEGV
);
2872 long do_rt_sigreturn(CPUState
*regs
)
2874 struct target_rt_sigframe
*frame
;
2875 abi_ulong frame_addr
;
2878 #if defined(DEBUG_SIGNAL)
2879 fprintf(stderr
, "do_rt_sigreturn\n");
2881 frame_addr
= regs
->gregs
[15];
2882 if (!lock_user_struct(VERIFY_READ
, frame
, frame_addr
, 1))
2885 target_to_host_sigset(&blocked
, &frame
->uc
.uc_sigmask
);
2886 sigprocmask(SIG_SETMASK
, &blocked
, NULL
);
2888 if (restore_sigcontext(regs
, &frame
->uc
.uc_mcontext
))
2891 if (do_sigaltstack(frame_addr
+
2892 offsetof(struct target_rt_sigframe
, uc
.uc_stack
),
2893 0, get_sp_from_cpustate(regs
)) == -EFAULT
)
2896 unlock_user_struct(frame
, frame_addr
, 0);
2897 return regs
->gregs
[0];
2900 unlock_user_struct(frame
, frame_addr
, 0);
2901 force_sig(TARGET_SIGSEGV
);
2904 #elif defined(TARGET_CRIS)
2906 struct target_sigcontext
{
2907 struct target_pt_regs regs
; /* needs to be first */
2909 uint32_t usp
; /* usp before stacking this gunk on it */
2912 /* Signal frames. */
2913 struct target_signal_frame
{
2914 struct target_sigcontext sc
;
2915 uint32_t extramask
[TARGET_NSIG_WORDS
- 1];
2916 uint8_t retcode
[8]; /* Trampoline code. */
2919 struct rt_signal_frame
{
2920 struct siginfo
*pinfo
;
2922 struct siginfo info
;
2924 uint8_t retcode
[8]; /* Trampoline code. */
2927 static void setup_sigcontext(struct target_sigcontext
*sc
, CPUState
*env
)
2929 __put_user(env
->regs
[0], &sc
->regs
.r0
);
2930 __put_user(env
->regs
[1], &sc
->regs
.r1
);
2931 __put_user(env
->regs
[2], &sc
->regs
.r2
);
2932 __put_user(env
->regs
[3], &sc
->regs
.r3
);
2933 __put_user(env
->regs
[4], &sc
->regs
.r4
);
2934 __put_user(env
->regs
[5], &sc
->regs
.r5
);
2935 __put_user(env
->regs
[6], &sc
->regs
.r6
);
2936 __put_user(env
->regs
[7], &sc
->regs
.r7
);
2937 __put_user(env
->regs
[8], &sc
->regs
.r8
);
2938 __put_user(env
->regs
[9], &sc
->regs
.r9
);
2939 __put_user(env
->regs
[10], &sc
->regs
.r10
);
2940 __put_user(env
->regs
[11], &sc
->regs
.r11
);
2941 __put_user(env
->regs
[12], &sc
->regs
.r12
);
2942 __put_user(env
->regs
[13], &sc
->regs
.r13
);
2943 __put_user(env
->regs
[14], &sc
->usp
);
2944 __put_user(env
->regs
[15], &sc
->regs
.acr
);
2945 __put_user(env
->pregs
[PR_MOF
], &sc
->regs
.mof
);
2946 __put_user(env
->pregs
[PR_SRP
], &sc
->regs
.srp
);
2947 __put_user(env
->pc
, &sc
->regs
.erp
);
2950 static void restore_sigcontext(struct target_sigcontext
*sc
, CPUState
*env
)
2952 __get_user(env
->regs
[0], &sc
->regs
.r0
);
2953 __get_user(env
->regs
[1], &sc
->regs
.r1
);
2954 __get_user(env
->regs
[2], &sc
->regs
.r2
);
2955 __get_user(env
->regs
[3], &sc
->regs
.r3
);
2956 __get_user(env
->regs
[4], &sc
->regs
.r4
);
2957 __get_user(env
->regs
[5], &sc
->regs
.r5
);
2958 __get_user(env
->regs
[6], &sc
->regs
.r6
);
2959 __get_user(env
->regs
[7], &sc
->regs
.r7
);
2960 __get_user(env
->regs
[8], &sc
->regs
.r8
);
2961 __get_user(env
->regs
[9], &sc
->regs
.r9
);
2962 __get_user(env
->regs
[10], &sc
->regs
.r10
);
2963 __get_user(env
->regs
[11], &sc
->regs
.r11
);
2964 __get_user(env
->regs
[12], &sc
->regs
.r12
);
2965 __get_user(env
->regs
[13], &sc
->regs
.r13
);
2966 __get_user(env
->regs
[14], &sc
->usp
);
2967 __get_user(env
->regs
[15], &sc
->regs
.acr
);
2968 __get_user(env
->pregs
[PR_MOF
], &sc
->regs
.mof
);
2969 __get_user(env
->pregs
[PR_SRP
], &sc
->regs
.srp
);
2970 __get_user(env
->pc
, &sc
->regs
.erp
);
2973 static abi_ulong
get_sigframe(CPUState
*env
, int framesize
)
2976 /* Align the stack downwards to 4. */
2977 sp
= (env
->regs
[R_SP
] & ~3);
2978 return sp
- framesize
;
2981 static void setup_frame(int sig
, struct target_sigaction
*ka
,
2982 target_sigset_t
*set
, CPUState
*env
)
2984 struct target_signal_frame
*frame
;
2985 abi_ulong frame_addr
;
2989 frame_addr
= get_sigframe(env
, sizeof *frame
);
2990 if (!lock_user_struct(VERIFY_WRITE
, frame
, frame_addr
, 0))
2994 * The CRIS signal return trampoline. A real linux/CRIS kernel doesn't
2995 * use this trampoline anymore but it sets it up for GDB.
2996 * In QEMU, using the trampoline simplifies things a bit so we use it.
2998 * This is movu.w __NR_sigreturn, r9; break 13;
3000 err
|= __put_user(0x9c5f, frame
->retcode
+0);
3001 err
|= __put_user(TARGET_NR_sigreturn
,
3003 err
|= __put_user(0xe93d, frame
->retcode
+4);
3005 /* Save the mask. */
3006 err
|= __put_user(set
->sig
[0], &frame
->sc
.oldmask
);
3010 for(i
= 1; i
< TARGET_NSIG_WORDS
; i
++) {
3011 if (__put_user(set
->sig
[i
], &frame
->extramask
[i
- 1]))
3015 setup_sigcontext(&frame
->sc
, env
);
3017 /* Move the stack and setup the arguments for the handler. */
3018 env
->regs
[R_SP
] = (uint32_t) (unsigned long) frame
;
3019 env
->regs
[10] = sig
;
3020 env
->pc
= (unsigned long) ka
->_sa_handler
;
3021 /* Link SRP so the guest returns through the trampoline. */
3022 env
->pregs
[PR_SRP
] = (uint32_t) (unsigned long) &frame
->retcode
[0];
3024 unlock_user_struct(frame
, frame_addr
, 1);
3027 unlock_user_struct(frame
, frame_addr
, 1);
3028 force_sig(TARGET_SIGSEGV
);
3031 static void setup_rt_frame(int sig
, struct target_sigaction
*ka
,
3032 target_siginfo_t
*info
,
3033 target_sigset_t
*set
, CPUState
*env
)
3035 fprintf(stderr
, "CRIS setup_rt_frame: not implemented\n");
3038 long do_sigreturn(CPUState
*env
)
3040 struct target_signal_frame
*frame
;
3041 abi_ulong frame_addr
;
3042 target_sigset_t target_set
;
3046 frame_addr
= env
->regs
[R_SP
];
3047 /* Make sure the guest isn't playing games. */
3048 if (!lock_user_struct(VERIFY_WRITE
, frame
, frame_addr
, 1))
3051 /* Restore blocked signals */
3052 if (__get_user(target_set
.sig
[0], &frame
->sc
.oldmask
))
3054 for(i
= 1; i
< TARGET_NSIG_WORDS
; i
++) {
3055 if (__get_user(target_set
.sig
[i
], &frame
->extramask
[i
- 1]))
3058 target_to_host_sigset_internal(&set
, &target_set
);
3059 sigprocmask(SIG_SETMASK
, &set
, NULL
);
3061 restore_sigcontext(&frame
->sc
, env
);
3062 unlock_user_struct(frame
, frame_addr
, 0);
3063 return env
->regs
[10];
3065 unlock_user_struct(frame
, frame_addr
, 0);
3066 force_sig(TARGET_SIGSEGV
);
3069 long do_rt_sigreturn(CPUState
*env
)
3071 fprintf(stderr
, "CRIS do_rt_sigreturn: not implemented\n");
3072 return -TARGET_ENOSYS
;
3077 static void setup_frame(int sig
, struct target_sigaction
*ka
,
3078 target_sigset_t
*set
, CPUState
*env
)
3080 fprintf(stderr
, "setup_frame: not implemented\n");
3083 static void setup_rt_frame(int sig
, struct target_sigaction
*ka
,
3084 target_siginfo_t
*info
,
3085 target_sigset_t
*set
, CPUState
*env
)
3087 fprintf(stderr
, "setup_rt_frame: not implemented\n");
3090 long do_sigreturn(CPUState
*env
)
3092 fprintf(stderr
, "do_sigreturn: not implemented\n");
3093 return -TARGET_ENOSYS
;
3096 long do_rt_sigreturn(CPUState
*env
)
3098 fprintf(stderr
, "do_rt_sigreturn: not implemented\n");
3099 return -TARGET_ENOSYS
;
3104 void process_pending_signals(CPUState
*cpu_env
)
3108 sigset_t set
, old_set
;
3109 target_sigset_t target_old_set
;
3110 struct emulated_sigtable
*k
;
3111 struct target_sigaction
*sa
;
3113 TaskState
*ts
= cpu_env
->opaque
;
3115 if (!ts
->signal_pending
)
3118 /* FIXME: This is not threadsafe. */
3120 for(sig
= 1; sig
<= TARGET_NSIG
; sig
++) {
3125 /* if no signal is pending, just return */
3126 ts
->signal_pending
= 0;
3131 fprintf(stderr
, "qemu: process signal %d\n", sig
);
3133 /* dequeue signal */
3139 sig
= gdb_handlesig (cpu_env
, sig
);
3142 handler
= TARGET_SIG_IGN
;
3144 sa
= &sigact_table
[sig
- 1];
3145 handler
= sa
->_sa_handler
;
3148 if (handler
== TARGET_SIG_DFL
) {
3149 /* default handler : ignore some signal. The other are job control or fatal */
3150 if (sig
== TARGET_SIGTSTP
|| sig
== TARGET_SIGTTIN
|| sig
== TARGET_SIGTTOU
) {
3151 kill(getpid(),SIGSTOP
);
3152 } else if (sig
!= TARGET_SIGCHLD
&&
3153 sig
!= TARGET_SIGURG
&&
3154 sig
!= TARGET_SIGWINCH
&&
3155 sig
!= TARGET_SIGCONT
) {
3158 } else if (handler
== TARGET_SIG_IGN
) {
3160 } else if (handler
== TARGET_SIG_ERR
) {
3163 /* compute the blocked signals during the handler execution */
3164 target_to_host_sigset(&set
, &sa
->sa_mask
);
3165 /* SA_NODEFER indicates that the current signal should not be
3166 blocked during the handler */
3167 if (!(sa
->sa_flags
& TARGET_SA_NODEFER
))
3168 sigaddset(&set
, target_to_host_signal(sig
));
3170 /* block signals in the handler using Linux */
3171 sigprocmask(SIG_BLOCK
, &set
, &old_set
);
3172 /* save the previous blocked signal state to restore it at the
3173 end of the signal execution (see do_sigreturn) */
3174 host_to_target_sigset_internal(&target_old_set
, &old_set
);
3176 /* if the CPU is in VM86 mode, we restore the 32 bit values */
3177 #if defined(TARGET_I386) && !defined(TARGET_X86_64)
3179 CPUX86State
*env
= cpu_env
;
3180 if (env
->eflags
& VM_MASK
)
3181 save_v86_state(env
);
3184 /* prepare the stack frame of the virtual CPU */
3185 if (sa
->sa_flags
& TARGET_SA_SIGINFO
)
3186 setup_rt_frame(sig
, sa
, &q
->info
, &target_old_set
, cpu_env
);
3188 setup_frame(sig
, sa
, &target_old_set
, cpu_env
);
3189 if (sa
->sa_flags
& TARGET_SA_RESETHAND
)
3190 sa
->_sa_handler
= TARGET_SIG_DFL
;
3193 free_sigqueue(cpu_env
, q
);