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 "target_signal.h"
33 //#define DEBUG_SIGNAL
35 static struct target_sigaltstack target_sigaltstack_used
= {
38 .ss_flags
= TARGET_SS_DISABLE
,
41 static struct target_sigaction sigact_table
[TARGET_NSIG
];
43 static void host_signal_handler(int host_signum
, siginfo_t
*info
,
46 static uint8_t host_to_target_signal_table
[65] = {
47 [SIGHUP
] = TARGET_SIGHUP
,
48 [SIGINT
] = TARGET_SIGINT
,
49 [SIGQUIT
] = TARGET_SIGQUIT
,
50 [SIGILL
] = TARGET_SIGILL
,
51 [SIGTRAP
] = TARGET_SIGTRAP
,
52 [SIGABRT
] = TARGET_SIGABRT
,
53 /* [SIGIOT] = TARGET_SIGIOT,*/
54 [SIGBUS
] = TARGET_SIGBUS
,
55 [SIGFPE
] = TARGET_SIGFPE
,
56 [SIGKILL
] = TARGET_SIGKILL
,
57 [SIGUSR1
] = TARGET_SIGUSR1
,
58 [SIGSEGV
] = TARGET_SIGSEGV
,
59 [SIGUSR2
] = TARGET_SIGUSR2
,
60 [SIGPIPE
] = TARGET_SIGPIPE
,
61 [SIGALRM
] = TARGET_SIGALRM
,
62 [SIGTERM
] = TARGET_SIGTERM
,
64 [SIGSTKFLT
] = TARGET_SIGSTKFLT
,
66 [SIGCHLD
] = TARGET_SIGCHLD
,
67 [SIGCONT
] = TARGET_SIGCONT
,
68 [SIGSTOP
] = TARGET_SIGSTOP
,
69 [SIGTSTP
] = TARGET_SIGTSTP
,
70 [SIGTTIN
] = TARGET_SIGTTIN
,
71 [SIGTTOU
] = TARGET_SIGTTOU
,
72 [SIGURG
] = TARGET_SIGURG
,
73 [SIGXCPU
] = TARGET_SIGXCPU
,
74 [SIGXFSZ
] = TARGET_SIGXFSZ
,
75 [SIGVTALRM
] = TARGET_SIGVTALRM
,
76 [SIGPROF
] = TARGET_SIGPROF
,
77 [SIGWINCH
] = TARGET_SIGWINCH
,
78 [SIGIO
] = TARGET_SIGIO
,
79 [SIGPWR
] = TARGET_SIGPWR
,
80 [SIGSYS
] = TARGET_SIGSYS
,
81 /* next signals stay the same */
82 /* Nasty hack: Reverse SIGRTMIN and SIGRTMAX to avoid overlap with
83 host libpthread signals. This assumes noone actually uses SIGRTMAX :-/
84 To fix this properly we need to do manual signal delivery multiplexed
85 over a single host signal. */
86 [__SIGRTMIN
] = __SIGRTMAX
,
87 [__SIGRTMAX
] = __SIGRTMIN
,
89 static uint8_t target_to_host_signal_table
[65];
91 static inline int on_sig_stack(unsigned long sp
)
93 return (sp
- target_sigaltstack_used
.ss_sp
94 < target_sigaltstack_used
.ss_size
);
97 static inline int sas_ss_flags(unsigned long sp
)
99 return (target_sigaltstack_used
.ss_size
== 0 ? SS_DISABLE
100 : on_sig_stack(sp
) ? SS_ONSTACK
: 0);
103 static inline int host_to_target_signal(int sig
)
107 return host_to_target_signal_table
[sig
];
110 int target_to_host_signal(int sig
)
114 return target_to_host_signal_table
[sig
];
117 static inline void target_sigemptyset(target_sigset_t
*set
)
119 memset(set
, 0, sizeof(*set
));
122 static inline void target_sigaddset(target_sigset_t
*set
, int signum
)
125 abi_ulong mask
= (abi_ulong
)1 << (signum
% TARGET_NSIG_BPW
);
126 set
->sig
[signum
/ TARGET_NSIG_BPW
] |= mask
;
129 static inline int target_sigismember(const target_sigset_t
*set
, int signum
)
132 abi_ulong mask
= (abi_ulong
)1 << (signum
% TARGET_NSIG_BPW
);
133 return ((set
->sig
[signum
/ TARGET_NSIG_BPW
] & mask
) != 0);
136 static void host_to_target_sigset_internal(target_sigset_t
*d
,
140 target_sigemptyset(d
);
141 for (i
= 1; i
<= TARGET_NSIG
; i
++) {
142 if (sigismember(s
, i
)) {
143 target_sigaddset(d
, host_to_target_signal(i
));
148 void host_to_target_sigset(target_sigset_t
*d
, const sigset_t
*s
)
153 host_to_target_sigset_internal(&d1
, s
);
154 for(i
= 0;i
< TARGET_NSIG_WORDS
; i
++)
155 d
->sig
[i
] = tswapl(d1
.sig
[i
]);
158 static void target_to_host_sigset_internal(sigset_t
*d
,
159 const target_sigset_t
*s
)
163 for (i
= 1; i
<= TARGET_NSIG
; i
++) {
164 if (target_sigismember(s
, i
)) {
165 sigaddset(d
, target_to_host_signal(i
));
170 void target_to_host_sigset(sigset_t
*d
, const target_sigset_t
*s
)
175 for(i
= 0;i
< TARGET_NSIG_WORDS
; i
++)
176 s1
.sig
[i
] = tswapl(s
->sig
[i
]);
177 target_to_host_sigset_internal(d
, &s1
);
180 void host_to_target_old_sigset(abi_ulong
*old_sigset
,
181 const sigset_t
*sigset
)
184 host_to_target_sigset(&d
, sigset
);
185 *old_sigset
= d
.sig
[0];
188 void target_to_host_old_sigset(sigset_t
*sigset
,
189 const abi_ulong
*old_sigset
)
194 d
.sig
[0] = *old_sigset
;
195 for(i
= 1;i
< TARGET_NSIG_WORDS
; i
++)
197 target_to_host_sigset(sigset
, &d
);
200 /* siginfo conversion */
202 static inline void host_to_target_siginfo_noswap(target_siginfo_t
*tinfo
,
203 const siginfo_t
*info
)
206 sig
= host_to_target_signal(info
->si_signo
);
207 tinfo
->si_signo
= sig
;
209 tinfo
->si_code
= info
->si_code
;
210 if (sig
== SIGILL
|| sig
== SIGFPE
|| sig
== SIGSEGV
||
211 sig
== SIGBUS
|| sig
== SIGTRAP
) {
212 /* should never come here, but who knows. The information for
213 the target is irrelevant */
214 tinfo
->_sifields
._sigfault
._addr
= 0;
215 } else if (sig
== SIGIO
) {
216 tinfo
->_sifields
._sigpoll
._fd
= info
->si_fd
;
217 } else if (sig
>= TARGET_SIGRTMIN
) {
218 tinfo
->_sifields
._rt
._pid
= info
->si_pid
;
219 tinfo
->_sifields
._rt
._uid
= info
->si_uid
;
220 /* XXX: potential problem if 64 bit */
221 tinfo
->_sifields
._rt
._sigval
.sival_ptr
=
222 (abi_ulong
)(unsigned long)info
->si_value
.sival_ptr
;
226 static void tswap_siginfo(target_siginfo_t
*tinfo
,
227 const target_siginfo_t
*info
)
230 sig
= info
->si_signo
;
231 tinfo
->si_signo
= tswap32(sig
);
232 tinfo
->si_errno
= tswap32(info
->si_errno
);
233 tinfo
->si_code
= tswap32(info
->si_code
);
234 if (sig
== SIGILL
|| sig
== SIGFPE
|| sig
== SIGSEGV
||
235 sig
== SIGBUS
|| sig
== SIGTRAP
) {
236 tinfo
->_sifields
._sigfault
._addr
=
237 tswapl(info
->_sifields
._sigfault
._addr
);
238 } else if (sig
== SIGIO
) {
239 tinfo
->_sifields
._sigpoll
._fd
= tswap32(info
->_sifields
._sigpoll
._fd
);
240 } else if (sig
>= TARGET_SIGRTMIN
) {
241 tinfo
->_sifields
._rt
._pid
= tswap32(info
->_sifields
._rt
._pid
);
242 tinfo
->_sifields
._rt
._uid
= tswap32(info
->_sifields
._rt
._uid
);
243 tinfo
->_sifields
._rt
._sigval
.sival_ptr
=
244 tswapl(info
->_sifields
._rt
._sigval
.sival_ptr
);
249 void host_to_target_siginfo(target_siginfo_t
*tinfo
, const siginfo_t
*info
)
251 host_to_target_siginfo_noswap(tinfo
, info
);
252 tswap_siginfo(tinfo
, tinfo
);
255 /* XXX: we support only POSIX RT signals are used. */
256 /* XXX: find a solution for 64 bit (additional malloced data is needed) */
257 void target_to_host_siginfo(siginfo_t
*info
, const target_siginfo_t
*tinfo
)
259 info
->si_signo
= tswap32(tinfo
->si_signo
);
260 info
->si_errno
= tswap32(tinfo
->si_errno
);
261 info
->si_code
= tswap32(tinfo
->si_code
);
262 info
->si_pid
= tswap32(tinfo
->_sifields
._rt
._pid
);
263 info
->si_uid
= tswap32(tinfo
->_sifields
._rt
._uid
);
264 info
->si_value
.sival_ptr
=
265 (void *)(long)tswapl(tinfo
->_sifields
._rt
._sigval
.sival_ptr
);
268 static int fatal_signal (int sig
)
273 case TARGET_SIGWINCH
:
274 /* Ignored by default. */
281 /* Job control signals. */
288 void signal_init(void)
290 struct sigaction act
;
291 struct sigaction oact
;
295 /* generate signal conversion tables */
296 for(i
= 1; i
<= 64; i
++) {
297 if (host_to_target_signal_table
[i
] == 0)
298 host_to_target_signal_table
[i
] = i
;
300 for(i
= 1; i
<= 64; i
++) {
301 j
= host_to_target_signal_table
[i
];
302 target_to_host_signal_table
[j
] = i
;
305 /* set all host signal handlers. ALL signals are blocked during
306 the handlers to serialize them. */
307 memset(sigact_table
, 0, sizeof(sigact_table
));
309 sigfillset(&act
.sa_mask
);
310 act
.sa_flags
= SA_SIGINFO
;
311 act
.sa_sigaction
= host_signal_handler
;
312 for(i
= 1; i
<= TARGET_NSIG
; i
++) {
313 host_sig
= target_to_host_signal(i
);
314 sigaction(host_sig
, NULL
, &oact
);
315 if (oact
.sa_sigaction
== (void *)SIG_IGN
) {
316 sigact_table
[i
- 1]._sa_handler
= TARGET_SIG_IGN
;
317 } else if (oact
.sa_sigaction
== (void *)SIG_DFL
) {
318 sigact_table
[i
- 1]._sa_handler
= TARGET_SIG_DFL
;
320 /* If there's already a handler installed then something has
321 gone horribly wrong, so don't even try to handle that case. */
322 /* Install some handlers for our own use. We need at least
323 SIGSEGV and SIGBUS, to detect exceptions. We can not just
324 trap all signals because it affects syscall interrupt
325 behavior. But do trap all default-fatal signals. */
326 if (fatal_signal (i
))
327 sigaction(host_sig
, &act
, NULL
);
331 /* signal queue handling */
333 static inline struct sigqueue
*alloc_sigqueue(CPUState
*env
)
335 TaskState
*ts
= env
->opaque
;
336 struct sigqueue
*q
= ts
->first_free
;
339 ts
->first_free
= q
->next
;
343 static inline void free_sigqueue(CPUState
*env
, struct sigqueue
*q
)
345 TaskState
*ts
= env
->opaque
;
346 q
->next
= ts
->first_free
;
350 /* abort execution with signal */
351 static void __attribute((noreturn
)) force_sig(int sig
)
354 host_sig
= target_to_host_signal(sig
);
355 fprintf(stderr
, "qemu: uncaught target signal %d (%s) - exiting\n",
356 sig
, strsignal(host_sig
));
358 gdb_signalled(thread_env
, sig
);
362 struct sigaction act
;
363 sigemptyset(&act
.sa_mask
);
364 act
.sa_flags
= SA_SIGINFO
;
365 act
.sa_sigaction
= SIG_DFL
;
366 sigaction(SIGABRT
, &act
, NULL
);
372 /* queue a signal so that it will be send to the virtual CPU as soon
374 int queue_signal(CPUState
*env
, int sig
, target_siginfo_t
*info
)
376 TaskState
*ts
= env
->opaque
;
377 struct emulated_sigtable
*k
;
378 struct sigqueue
*q
, **pq
;
382 #if defined(DEBUG_SIGNAL)
383 fprintf(stderr
, "queue_signal: sig=%d\n",
386 k
= &ts
->sigtab
[sig
- 1];
387 queue
= gdb_queuesig ();
388 handler
= sigact_table
[sig
- 1]._sa_handler
;
389 if (!queue
&& handler
== TARGET_SIG_DFL
) {
390 if (sig
== TARGET_SIGTSTP
|| sig
== TARGET_SIGTTIN
|| sig
== TARGET_SIGTTOU
) {
391 kill(getpid(),SIGSTOP
);
394 /* default handler : ignore some signal. The other are fatal */
395 if (sig
!= TARGET_SIGCHLD
&&
396 sig
!= TARGET_SIGURG
&&
397 sig
!= TARGET_SIGWINCH
&&
398 sig
!= TARGET_SIGCONT
) {
401 return 0; /* indicate ignored */
403 } else if (!queue
&& handler
== TARGET_SIG_IGN
) {
406 } else if (!queue
&& handler
== TARGET_SIG_ERR
) {
410 if (sig
< TARGET_SIGRTMIN
) {
411 /* if non real time signal, we queue exactly one signal */
421 q
= alloc_sigqueue(env
);
432 /* signal that a new signal is pending */
433 ts
->signal_pending
= 1;
434 return 1; /* indicates that the signal was queued */
438 static void host_signal_handler(int host_signum
, siginfo_t
*info
,
442 target_siginfo_t tinfo
;
444 /* the CPU emulator uses some host signals to detect exceptions,
445 we forward to it some signals */
446 if ((host_signum
== SIGSEGV
|| host_signum
== SIGBUS
)
447 && info
->si_code
> 0) {
448 if (cpu_signal_handler(host_signum
, info
, puc
))
452 /* get target signal number */
453 sig
= host_to_target_signal(host_signum
);
454 if (sig
< 1 || sig
> TARGET_NSIG
)
456 #if defined(DEBUG_SIGNAL)
457 fprintf(stderr
, "qemu: got signal %d\n", sig
);
459 host_to_target_siginfo_noswap(&tinfo
, info
);
460 if (queue_signal(thread_env
, sig
, &tinfo
) == 1) {
461 /* interrupt the virtual CPU as soon as possible */
462 cpu_interrupt(thread_env
, CPU_INTERRUPT_EXIT
);
466 /* do_sigaltstack() returns target values and errnos. */
467 /* compare linux/kernel/signal.c:do_sigaltstack() */
468 abi_long
do_sigaltstack(abi_ulong uss_addr
, abi_ulong uoss_addr
, abi_ulong sp
)
471 struct target_sigaltstack oss
;
473 /* XXX: test errors */
476 __put_user(target_sigaltstack_used
.ss_sp
, &oss
.ss_sp
);
477 __put_user(target_sigaltstack_used
.ss_size
, &oss
.ss_size
);
478 __put_user(sas_ss_flags(sp
), &oss
.ss_flags
);
483 struct target_sigaltstack
*uss
;
484 struct target_sigaltstack ss
;
486 ret
= -TARGET_EFAULT
;
487 if (!lock_user_struct(VERIFY_READ
, uss
, uss_addr
, 1)
488 || __get_user(ss
.ss_sp
, &uss
->ss_sp
)
489 || __get_user(ss
.ss_size
, &uss
->ss_size
)
490 || __get_user(ss
.ss_flags
, &uss
->ss_flags
))
492 unlock_user_struct(uss
, uss_addr
, 0);
495 if (on_sig_stack(sp
))
498 ret
= -TARGET_EINVAL
;
499 if (ss
.ss_flags
!= TARGET_SS_DISABLE
500 && ss
.ss_flags
!= TARGET_SS_ONSTACK
504 if (ss
.ss_flags
== TARGET_SS_DISABLE
) {
508 ret
= -TARGET_ENOMEM
;
509 if (ss
.ss_size
< MINSIGSTKSZ
)
513 target_sigaltstack_used
.ss_sp
= ss
.ss_sp
;
514 target_sigaltstack_used
.ss_size
= ss
.ss_size
;
518 ret
= -TARGET_EFAULT
;
519 if (copy_to_user(uoss_addr
, &oss
, sizeof(oss
)))
528 /* do_sigaction() return host values and errnos */
529 int do_sigaction(int sig
, const struct target_sigaction
*act
,
530 struct target_sigaction
*oact
)
532 struct target_sigaction
*k
;
533 struct sigaction act1
;
537 if (sig
< 1 || sig
> TARGET_NSIG
|| sig
== TARGET_SIGKILL
|| sig
== TARGET_SIGSTOP
)
539 k
= &sigact_table
[sig
- 1];
540 #if defined(DEBUG_SIGNAL)
541 fprintf(stderr
, "sigaction sig=%d act=0x%08x, oact=0x%08x\n",
542 sig
, (int)act
, (int)oact
);
545 oact
->_sa_handler
= tswapl(k
->_sa_handler
);
546 oact
->sa_flags
= tswapl(k
->sa_flags
);
547 #if !defined(TARGET_MIPS)
548 oact
->sa_restorer
= tswapl(k
->sa_restorer
);
550 oact
->sa_mask
= k
->sa_mask
;
553 /* FIXME: This is not threadsafe. */
554 k
->_sa_handler
= tswapl(act
->_sa_handler
);
555 k
->sa_flags
= tswapl(act
->sa_flags
);
556 #if !defined(TARGET_MIPS)
557 k
->sa_restorer
= tswapl(act
->sa_restorer
);
559 k
->sa_mask
= act
->sa_mask
;
561 /* we update the host linux signal state */
562 host_sig
= target_to_host_signal(sig
);
563 if (host_sig
!= SIGSEGV
&& host_sig
!= SIGBUS
) {
564 sigfillset(&act1
.sa_mask
);
565 act1
.sa_flags
= SA_SIGINFO
;
566 if (k
->sa_flags
& TARGET_SA_RESTART
)
567 act1
.sa_flags
|= SA_RESTART
;
568 /* NOTE: it is important to update the host kernel signal
569 ignore state to avoid getting unexpected interrupted
571 if (k
->_sa_handler
== TARGET_SIG_IGN
) {
572 act1
.sa_sigaction
= (void *)SIG_IGN
;
573 } else if (k
->_sa_handler
== TARGET_SIG_DFL
) {
574 if (fatal_signal (sig
))
575 act1
.sa_sigaction
= host_signal_handler
;
577 act1
.sa_sigaction
= (void *)SIG_DFL
;
579 act1
.sa_sigaction
= host_signal_handler
;
581 ret
= sigaction(host_sig
, &act1
, NULL
);
587 static inline int copy_siginfo_to_user(target_siginfo_t
*tinfo
,
588 const target_siginfo_t
*info
)
590 tswap_siginfo(tinfo
, info
);
594 static inline int current_exec_domain_sig(int sig
)
596 return /* current->exec_domain && current->exec_domain->signal_invmap
597 && sig < 32 ? current->exec_domain->signal_invmap[sig] : */ sig
;
600 #if defined(TARGET_I386) && TARGET_ABI_BITS == 32
602 /* from the Linux kernel */
604 struct target_fpreg
{
605 uint16_t significand
[4];
609 struct target_fpxreg
{
610 uint16_t significand
[4];
615 struct target_xmmreg
{
616 abi_ulong element
[4];
619 struct target_fpstate
{
620 /* Regular FPU environment */
628 struct target_fpreg _st
[8];
630 uint16_t magic
; /* 0xffff = regular FPU data only */
632 /* FXSR FPU environment */
633 abi_ulong _fxsr_env
[6]; /* FXSR FPU env is ignored */
636 struct target_fpxreg _fxsr_st
[8]; /* FXSR FPU reg data is ignored */
637 struct target_xmmreg _xmm
[8];
638 abi_ulong padding
[56];
641 #define X86_FXSR_MAGIC 0x0000
643 struct target_sigcontext
{
661 abi_ulong esp_at_signal
;
663 abi_ulong fpstate
; /* pointer */
668 struct target_ucontext
{
671 target_stack_t tuc_stack
;
672 struct target_sigcontext tuc_mcontext
;
673 target_sigset_t tuc_sigmask
; /* mask last for extensibility */
680 struct target_sigcontext sc
;
681 struct target_fpstate fpstate
;
682 abi_ulong extramask
[TARGET_NSIG_WORDS
-1];
692 struct target_siginfo info
;
693 struct target_ucontext uc
;
694 struct target_fpstate fpstate
;
699 * Set up a signal frame.
702 /* XXX: save x87 state */
704 setup_sigcontext(struct target_sigcontext
*sc
, struct target_fpstate
*fpstate
,
705 CPUX86State
*env
, abi_ulong mask
, abi_ulong fpstate_addr
)
710 /* already locked in setup_frame() */
711 err
|= __put_user(env
->segs
[R_GS
].selector
, (unsigned int *)&sc
->gs
);
712 err
|= __put_user(env
->segs
[R_FS
].selector
, (unsigned int *)&sc
->fs
);
713 err
|= __put_user(env
->segs
[R_ES
].selector
, (unsigned int *)&sc
->es
);
714 err
|= __put_user(env
->segs
[R_DS
].selector
, (unsigned int *)&sc
->ds
);
715 err
|= __put_user(env
->regs
[R_EDI
], &sc
->edi
);
716 err
|= __put_user(env
->regs
[R_ESI
], &sc
->esi
);
717 err
|= __put_user(env
->regs
[R_EBP
], &sc
->ebp
);
718 err
|= __put_user(env
->regs
[R_ESP
], &sc
->esp
);
719 err
|= __put_user(env
->regs
[R_EBX
], &sc
->ebx
);
720 err
|= __put_user(env
->regs
[R_EDX
], &sc
->edx
);
721 err
|= __put_user(env
->regs
[R_ECX
], &sc
->ecx
);
722 err
|= __put_user(env
->regs
[R_EAX
], &sc
->eax
);
723 err
|= __put_user(env
->exception_index
, &sc
->trapno
);
724 err
|= __put_user(env
->error_code
, &sc
->err
);
725 err
|= __put_user(env
->eip
, &sc
->eip
);
726 err
|= __put_user(env
->segs
[R_CS
].selector
, (unsigned int *)&sc
->cs
);
727 err
|= __put_user(env
->eflags
, &sc
->eflags
);
728 err
|= __put_user(env
->regs
[R_ESP
], &sc
->esp_at_signal
);
729 err
|= __put_user(env
->segs
[R_SS
].selector
, (unsigned int *)&sc
->ss
);
731 cpu_x86_fsave(env
, fpstate_addr
, 1);
732 fpstate
->status
= fpstate
->sw
;
734 err
|= __put_user(magic
, &fpstate
->magic
);
735 err
|= __put_user(fpstate_addr
, &sc
->fpstate
);
737 /* non-iBCS2 extensions.. */
738 err
|= __put_user(mask
, &sc
->oldmask
);
739 err
|= __put_user(env
->cr
[2], &sc
->cr2
);
744 * Determine which stack to use..
747 static inline abi_ulong
748 get_sigframe(struct target_sigaction
*ka
, CPUX86State
*env
, size_t frame_size
)
752 /* Default to using normal stack */
753 esp
= env
->regs
[R_ESP
];
754 /* This is the X/Open sanctioned signal stack switching. */
755 if (ka
->sa_flags
& TARGET_SA_ONSTACK
) {
756 if (sas_ss_flags(esp
) == 0)
757 esp
= target_sigaltstack_used
.ss_sp
+ target_sigaltstack_used
.ss_size
;
760 /* This is the legacy signal stack switching. */
762 if ((env
->segs
[R_SS
].selector
& 0xffff) != __USER_DS
&&
763 !(ka
->sa_flags
& TARGET_SA_RESTORER
) &&
765 esp
= (unsigned long) ka
->sa_restorer
;
767 return (esp
- frame_size
) & -8ul;
770 /* compare linux/arch/i386/kernel/signal.c:setup_frame() */
771 static void setup_frame(int sig
, struct target_sigaction
*ka
,
772 target_sigset_t
*set
, CPUX86State
*env
)
774 abi_ulong frame_addr
;
775 struct sigframe
*frame
;
778 frame_addr
= get_sigframe(ka
, env
, sizeof(*frame
));
780 if (!lock_user_struct(VERIFY_WRITE
, frame
, frame_addr
, 0))
783 err
|= __put_user(current_exec_domain_sig(sig
),
788 setup_sigcontext(&frame
->sc
, &frame
->fpstate
, env
, set
->sig
[0],
789 frame_addr
+ offsetof(struct sigframe
, fpstate
));
793 for(i
= 1; i
< TARGET_NSIG_WORDS
; i
++) {
794 if (__put_user(set
->sig
[i
], &frame
->extramask
[i
- 1]))
798 /* Set up to return from userspace. If provided, use a stub
799 already in userspace. */
800 if (ka
->sa_flags
& TARGET_SA_RESTORER
) {
801 err
|= __put_user(ka
->sa_restorer
, &frame
->pretcode
);
804 abi_ulong retcode_addr
;
805 retcode_addr
= frame_addr
+ offsetof(struct sigframe
, retcode
);
806 err
|= __put_user(retcode_addr
, &frame
->pretcode
);
807 /* This is popl %eax ; movl $,%eax ; int $0x80 */
809 err
|= __put_user(val16
, (uint16_t *)(frame
->retcode
+0));
810 err
|= __put_user(TARGET_NR_sigreturn
, (int *)(frame
->retcode
+2));
812 err
|= __put_user(val16
, (uint16_t *)(frame
->retcode
+6));
818 /* Set up registers for signal handler */
819 env
->regs
[R_ESP
] = frame_addr
;
820 env
->eip
= ka
->_sa_handler
;
822 cpu_x86_load_seg(env
, R_DS
, __USER_DS
);
823 cpu_x86_load_seg(env
, R_ES
, __USER_DS
);
824 cpu_x86_load_seg(env
, R_SS
, __USER_DS
);
825 cpu_x86_load_seg(env
, R_CS
, __USER_CS
);
826 env
->eflags
&= ~TF_MASK
;
828 unlock_user_struct(frame
, frame_addr
, 1);
833 unlock_user_struct(frame
, frame_addr
, 1);
834 if (sig
== TARGET_SIGSEGV
)
835 ka
->_sa_handler
= TARGET_SIG_DFL
;
836 force_sig(TARGET_SIGSEGV
/* , current */);
839 /* compare linux/arch/i386/kernel/signal.c:setup_rt_frame() */
840 static void setup_rt_frame(int sig
, struct target_sigaction
*ka
,
841 target_siginfo_t
*info
,
842 target_sigset_t
*set
, CPUX86State
*env
)
844 abi_ulong frame_addr
, addr
;
845 struct rt_sigframe
*frame
;
848 frame_addr
= get_sigframe(ka
, env
, sizeof(*frame
));
850 if (!lock_user_struct(VERIFY_WRITE
, frame
, frame_addr
, 0))
853 err
|= __put_user(current_exec_domain_sig(sig
),
855 addr
= frame_addr
+ offsetof(struct rt_sigframe
, info
);
856 err
|= __put_user(addr
, &frame
->pinfo
);
857 addr
= frame_addr
+ offsetof(struct rt_sigframe
, uc
);
858 err
|= __put_user(addr
, &frame
->puc
);
859 err
|= copy_siginfo_to_user(&frame
->info
, info
);
863 /* Create the ucontext. */
864 err
|= __put_user(0, &frame
->uc
.tuc_flags
);
865 err
|= __put_user(0, &frame
->uc
.tuc_link
);
866 err
|= __put_user(target_sigaltstack_used
.ss_sp
,
867 &frame
->uc
.tuc_stack
.ss_sp
);
868 err
|= __put_user(sas_ss_flags(get_sp_from_cpustate(env
)),
869 &frame
->uc
.tuc_stack
.ss_flags
);
870 err
|= __put_user(target_sigaltstack_used
.ss_size
,
871 &frame
->uc
.tuc_stack
.ss_size
);
872 err
|= setup_sigcontext(&frame
->uc
.tuc_mcontext
, &frame
->fpstate
,
874 frame_addr
+ offsetof(struct rt_sigframe
, fpstate
));
875 for(i
= 0; i
< TARGET_NSIG_WORDS
; i
++) {
876 if (__put_user(set
->sig
[i
], &frame
->uc
.tuc_sigmask
.sig
[i
]))
880 /* Set up to return from userspace. If provided, use a stub
881 already in userspace. */
882 if (ka
->sa_flags
& TARGET_SA_RESTORER
) {
883 err
|= __put_user(ka
->sa_restorer
, &frame
->pretcode
);
886 addr
= frame_addr
+ offsetof(struct rt_sigframe
, retcode
);
887 err
|= __put_user(addr
, &frame
->pretcode
);
888 /* This is movl $,%eax ; int $0x80 */
889 err
|= __put_user(0xb8, (char *)(frame
->retcode
+0));
890 err
|= __put_user(TARGET_NR_rt_sigreturn
, (int *)(frame
->retcode
+1));
892 err
|= __put_user(val16
, (uint16_t *)(frame
->retcode
+5));
898 /* Set up registers for signal handler */
899 env
->regs
[R_ESP
] = frame_addr
;
900 env
->eip
= ka
->_sa_handler
;
902 cpu_x86_load_seg(env
, R_DS
, __USER_DS
);
903 cpu_x86_load_seg(env
, R_ES
, __USER_DS
);
904 cpu_x86_load_seg(env
, R_SS
, __USER_DS
);
905 cpu_x86_load_seg(env
, R_CS
, __USER_CS
);
906 env
->eflags
&= ~TF_MASK
;
908 unlock_user_struct(frame
, frame_addr
, 1);
913 unlock_user_struct(frame
, frame_addr
, 1);
914 if (sig
== TARGET_SIGSEGV
)
915 ka
->_sa_handler
= TARGET_SIG_DFL
;
916 force_sig(TARGET_SIGSEGV
/* , current */);
920 restore_sigcontext(CPUX86State
*env
, struct target_sigcontext
*sc
, int *peax
)
922 unsigned int err
= 0;
923 abi_ulong fpstate_addr
;
924 unsigned int tmpflags
;
926 cpu_x86_load_seg(env
, R_GS
, tswap16(sc
->gs
));
927 cpu_x86_load_seg(env
, R_FS
, tswap16(sc
->fs
));
928 cpu_x86_load_seg(env
, R_ES
, tswap16(sc
->es
));
929 cpu_x86_load_seg(env
, R_DS
, tswap16(sc
->ds
));
931 env
->regs
[R_EDI
] = tswapl(sc
->edi
);
932 env
->regs
[R_ESI
] = tswapl(sc
->esi
);
933 env
->regs
[R_EBP
] = tswapl(sc
->ebp
);
934 env
->regs
[R_ESP
] = tswapl(sc
->esp
);
935 env
->regs
[R_EBX
] = tswapl(sc
->ebx
);
936 env
->regs
[R_EDX
] = tswapl(sc
->edx
);
937 env
->regs
[R_ECX
] = tswapl(sc
->ecx
);
938 env
->eip
= tswapl(sc
->eip
);
940 cpu_x86_load_seg(env
, R_CS
, lduw(&sc
->cs
) | 3);
941 cpu_x86_load_seg(env
, R_SS
, lduw(&sc
->ss
) | 3);
943 tmpflags
= tswapl(sc
->eflags
);
944 env
->eflags
= (env
->eflags
& ~0x40DD5) | (tmpflags
& 0x40DD5);
945 // regs->orig_eax = -1; /* disable syscall checks */
947 fpstate_addr
= tswapl(sc
->fpstate
);
948 if (fpstate_addr
!= 0) {
949 if (!access_ok(VERIFY_READ
, fpstate_addr
,
950 sizeof(struct target_fpstate
)))
952 cpu_x86_frstor(env
, fpstate_addr
, 1);
955 *peax
= tswapl(sc
->eax
);
961 long do_sigreturn(CPUX86State
*env
)
963 struct sigframe
*frame
;
964 abi_ulong frame_addr
= env
->regs
[R_ESP
] - 8;
965 target_sigset_t target_set
;
969 #if defined(DEBUG_SIGNAL)
970 fprintf(stderr
, "do_sigreturn\n");
972 if (!lock_user_struct(VERIFY_READ
, frame
, frame_addr
, 1))
974 /* set blocked signals */
975 if (__get_user(target_set
.sig
[0], &frame
->sc
.oldmask
))
977 for(i
= 1; i
< TARGET_NSIG_WORDS
; i
++) {
978 if (__get_user(target_set
.sig
[i
], &frame
->extramask
[i
- 1]))
982 target_to_host_sigset_internal(&set
, &target_set
);
983 sigprocmask(SIG_SETMASK
, &set
, NULL
);
985 /* restore registers */
986 if (restore_sigcontext(env
, &frame
->sc
, &eax
))
988 unlock_user_struct(frame
, frame_addr
, 0);
992 unlock_user_struct(frame
, frame_addr
, 0);
993 force_sig(TARGET_SIGSEGV
);
997 long do_rt_sigreturn(CPUX86State
*env
)
999 abi_ulong frame_addr
;
1000 struct rt_sigframe
*frame
;
1004 frame_addr
= env
->regs
[R_ESP
] - 4;
1005 if (!lock_user_struct(VERIFY_READ
, frame
, frame_addr
, 1))
1007 target_to_host_sigset(&set
, &frame
->uc
.tuc_sigmask
);
1008 sigprocmask(SIG_SETMASK
, &set
, NULL
);
1010 if (restore_sigcontext(env
, &frame
->uc
.tuc_mcontext
, &eax
))
1013 if (do_sigaltstack(frame_addr
+ offsetof(struct rt_sigframe
, uc
.tuc_stack
), 0,
1014 get_sp_from_cpustate(env
)) == -EFAULT
)
1017 unlock_user_struct(frame
, frame_addr
, 0);
1021 unlock_user_struct(frame
, frame_addr
, 0);
1022 force_sig(TARGET_SIGSEGV
);
1026 #elif defined(TARGET_ARM)
1028 struct target_sigcontext
{
1030 abi_ulong error_code
;
1049 abi_ulong fault_address
;
1052 struct target_ucontext_v1
{
1053 abi_ulong tuc_flags
;
1055 target_stack_t tuc_stack
;
1056 struct target_sigcontext tuc_mcontext
;
1057 target_sigset_t tuc_sigmask
; /* mask last for extensibility */
1060 struct target_ucontext_v2
{
1061 abi_ulong tuc_flags
;
1063 target_stack_t tuc_stack
;
1064 struct target_sigcontext tuc_mcontext
;
1065 target_sigset_t tuc_sigmask
; /* mask last for extensibility */
1066 char __unused
[128 - sizeof(sigset_t
)];
1067 abi_ulong tuc_regspace
[128] __attribute__((__aligned__(8)));
1072 struct target_sigcontext sc
;
1073 abi_ulong extramask
[TARGET_NSIG_WORDS
-1];
1079 struct target_ucontext_v2 uc
;
1083 struct rt_sigframe_v1
1087 struct target_siginfo info
;
1088 struct target_ucontext_v1 uc
;
1092 struct rt_sigframe_v2
1094 struct target_siginfo info
;
1095 struct target_ucontext_v2 uc
;
1099 #define TARGET_CONFIG_CPU_32 1
1102 * For ARM syscalls, we encode the syscall number into the instruction.
1104 #define SWI_SYS_SIGRETURN (0xef000000|(TARGET_NR_sigreturn + ARM_SYSCALL_BASE))
1105 #define SWI_SYS_RT_SIGRETURN (0xef000000|(TARGET_NR_rt_sigreturn + ARM_SYSCALL_BASE))
1108 * For Thumb syscalls, we pass the syscall number via r7. We therefore
1109 * need two 16-bit instructions.
1111 #define SWI_THUMB_SIGRETURN (0xdf00 << 16 | 0x2700 | (TARGET_NR_sigreturn))
1112 #define SWI_THUMB_RT_SIGRETURN (0xdf00 << 16 | 0x2700 | (TARGET_NR_rt_sigreturn))
1114 static const abi_ulong retcodes
[4] = {
1115 SWI_SYS_SIGRETURN
, SWI_THUMB_SIGRETURN
,
1116 SWI_SYS_RT_SIGRETURN
, SWI_THUMB_RT_SIGRETURN
1120 #define __get_user_error(x,p,e) __get_user(x, p)
1122 static inline int valid_user_regs(CPUState
*regs
)
1128 setup_sigcontext(struct target_sigcontext
*sc
, /*struct _fpstate *fpstate,*/
1129 CPUState
*env
, abi_ulong mask
)
1131 __put_user(env
->regs
[0], &sc
->arm_r0
);
1132 __put_user(env
->regs
[1], &sc
->arm_r1
);
1133 __put_user(env
->regs
[2], &sc
->arm_r2
);
1134 __put_user(env
->regs
[3], &sc
->arm_r3
);
1135 __put_user(env
->regs
[4], &sc
->arm_r4
);
1136 __put_user(env
->regs
[5], &sc
->arm_r5
);
1137 __put_user(env
->regs
[6], &sc
->arm_r6
);
1138 __put_user(env
->regs
[7], &sc
->arm_r7
);
1139 __put_user(env
->regs
[8], &sc
->arm_r8
);
1140 __put_user(env
->regs
[9], &sc
->arm_r9
);
1141 __put_user(env
->regs
[10], &sc
->arm_r10
);
1142 __put_user(env
->regs
[11], &sc
->arm_fp
);
1143 __put_user(env
->regs
[12], &sc
->arm_ip
);
1144 __put_user(env
->regs
[13], &sc
->arm_sp
);
1145 __put_user(env
->regs
[14], &sc
->arm_lr
);
1146 __put_user(env
->regs
[15], &sc
->arm_pc
);
1147 #ifdef TARGET_CONFIG_CPU_32
1148 __put_user(cpsr_read(env
), &sc
->arm_cpsr
);
1151 __put_user(/* current->thread.trap_no */ 0, &sc
->trap_no
);
1152 __put_user(/* current->thread.error_code */ 0, &sc
->error_code
);
1153 __put_user(/* current->thread.address */ 0, &sc
->fault_address
);
1154 __put_user(mask
, &sc
->oldmask
);
1157 static inline abi_ulong
1158 get_sigframe(struct target_sigaction
*ka
, CPUState
*regs
, int framesize
)
1160 unsigned long sp
= regs
->regs
[13];
1163 * This is the X/Open sanctioned signal stack switching.
1165 if ((ka
->sa_flags
& TARGET_SA_ONSTACK
) && !sas_ss_flags(sp
))
1166 sp
= target_sigaltstack_used
.ss_sp
+ target_sigaltstack_used
.ss_size
;
1168 * ATPCS B01 mandates 8-byte alignment
1170 return (sp
- framesize
) & ~7;
1174 setup_return(CPUState
*env
, struct target_sigaction
*ka
,
1175 abi_ulong
*rc
, abi_ulong frame_addr
, int usig
, abi_ulong rc_addr
)
1177 abi_ulong handler
= ka
->_sa_handler
;
1179 int thumb
= handler
& 1;
1181 if (ka
->sa_flags
& TARGET_SA_RESTORER
) {
1182 retcode
= ka
->sa_restorer
;
1184 unsigned int idx
= thumb
;
1186 if (ka
->sa_flags
& TARGET_SA_SIGINFO
)
1189 if (__put_user(retcodes
[idx
], rc
))
1192 flush_icache_range((abi_ulong
)rc
,
1193 (abi_ulong
)(rc
+ 1));
1195 retcode
= rc_addr
+ thumb
;
1198 env
->regs
[0] = usig
;
1199 env
->regs
[13] = frame_addr
;
1200 env
->regs
[14] = retcode
;
1201 env
->regs
[15] = handler
& (thumb
? ~1 : ~3);
1205 #ifdef TARGET_CONFIG_CPU_32
1213 static void setup_sigframe_v2(struct target_ucontext_v2
*uc
,
1214 target_sigset_t
*set
, CPUState
*env
)
1216 struct target_sigaltstack stack
;
1219 /* Clear all the bits of the ucontext we don't use. */
1220 memset(uc
, 0, offsetof(struct target_ucontext_v2
, tuc_mcontext
));
1222 memset(&stack
, 0, sizeof(stack
));
1223 __put_user(target_sigaltstack_used
.ss_sp
, &stack
.ss_sp
);
1224 __put_user(target_sigaltstack_used
.ss_size
, &stack
.ss_size
);
1225 __put_user(sas_ss_flags(get_sp_from_cpustate(env
)), &stack
.ss_flags
);
1226 memcpy(&uc
->tuc_stack
, &stack
, sizeof(stack
));
1228 setup_sigcontext(&uc
->tuc_mcontext
, env
, set
->sig
[0]);
1229 /* FIXME: Save coprocessor signal frame. */
1230 for(i
= 0; i
< TARGET_NSIG_WORDS
; i
++) {
1231 __put_user(set
->sig
[i
], &uc
->tuc_sigmask
.sig
[i
]);
1235 /* compare linux/arch/arm/kernel/signal.c:setup_frame() */
1236 static void setup_frame_v1(int usig
, struct target_sigaction
*ka
,
1237 target_sigset_t
*set
, CPUState
*regs
)
1239 struct sigframe_v1
*frame
;
1240 abi_ulong frame_addr
= get_sigframe(ka
, regs
, sizeof(*frame
));
1243 if (!lock_user_struct(VERIFY_WRITE
, frame
, frame_addr
, 0))
1246 setup_sigcontext(&frame
->sc
, regs
, set
->sig
[0]);
1248 for(i
= 1; i
< TARGET_NSIG_WORDS
; i
++) {
1249 if (__put_user(set
->sig
[i
], &frame
->extramask
[i
- 1]))
1253 setup_return(regs
, ka
, &frame
->retcode
, frame_addr
, usig
,
1254 frame_addr
+ offsetof(struct sigframe_v1
, retcode
));
1257 unlock_user_struct(frame
, frame_addr
, 1);
1260 static void setup_frame_v2(int usig
, struct target_sigaction
*ka
,
1261 target_sigset_t
*set
, CPUState
*regs
)
1263 struct sigframe_v2
*frame
;
1264 abi_ulong frame_addr
= get_sigframe(ka
, regs
, sizeof(*frame
));
1266 if (!lock_user_struct(VERIFY_WRITE
, frame
, frame_addr
, 0))
1269 setup_sigframe_v2(&frame
->uc
, set
, regs
);
1271 setup_return(regs
, ka
, &frame
->retcode
, frame_addr
, usig
,
1272 frame_addr
+ offsetof(struct sigframe_v2
, retcode
));
1274 unlock_user_struct(frame
, frame_addr
, 1);
1277 static void setup_frame(int usig
, struct target_sigaction
*ka
,
1278 target_sigset_t
*set
, CPUState
*regs
)
1280 if (get_osversion() >= 0x020612) {
1281 setup_frame_v2(usig
, ka
, set
, regs
);
1283 setup_frame_v1(usig
, ka
, set
, regs
);
1287 /* compare linux/arch/arm/kernel/signal.c:setup_rt_frame() */
1288 static void setup_rt_frame_v1(int usig
, struct target_sigaction
*ka
,
1289 target_siginfo_t
*info
,
1290 target_sigset_t
*set
, CPUState
*env
)
1292 struct rt_sigframe_v1
*frame
;
1293 abi_ulong frame_addr
= get_sigframe(ka
, env
, sizeof(*frame
));
1294 struct target_sigaltstack stack
;
1296 abi_ulong info_addr
, uc_addr
;
1298 if (!lock_user_struct(VERIFY_WRITE
, frame
, frame_addr
, 0))
1301 info_addr
= frame_addr
+ offsetof(struct rt_sigframe_v1
, info
);
1302 __put_user(info_addr
, &frame
->pinfo
);
1303 uc_addr
= frame_addr
+ offsetof(struct rt_sigframe_v1
, uc
);
1304 __put_user(uc_addr
, &frame
->puc
);
1305 copy_siginfo_to_user(&frame
->info
, info
);
1307 /* Clear all the bits of the ucontext we don't use. */
1308 memset(&frame
->uc
, 0, offsetof(struct target_ucontext_v1
, tuc_mcontext
));
1310 memset(&stack
, 0, sizeof(stack
));
1311 __put_user(target_sigaltstack_used
.ss_sp
, &stack
.ss_sp
);
1312 __put_user(target_sigaltstack_used
.ss_size
, &stack
.ss_size
);
1313 __put_user(sas_ss_flags(get_sp_from_cpustate(env
)), &stack
.ss_flags
);
1314 memcpy(&frame
->uc
.tuc_stack
, &stack
, sizeof(stack
));
1316 setup_sigcontext(&frame
->uc
.tuc_mcontext
, env
, set
->sig
[0]);
1317 for(i
= 0; i
< TARGET_NSIG_WORDS
; i
++) {
1318 if (__put_user(set
->sig
[i
], &frame
->uc
.tuc_sigmask
.sig
[i
]))
1322 setup_return(env
, ka
, &frame
->retcode
, frame_addr
, usig
,
1323 frame_addr
+ offsetof(struct rt_sigframe_v1
, retcode
));
1325 env
->regs
[1] = info_addr
;
1326 env
->regs
[2] = uc_addr
;
1329 unlock_user_struct(frame
, frame_addr
, 1);
1332 static void setup_rt_frame_v2(int usig
, struct target_sigaction
*ka
,
1333 target_siginfo_t
*info
,
1334 target_sigset_t
*set
, CPUState
*env
)
1336 struct rt_sigframe_v2
*frame
;
1337 abi_ulong frame_addr
= get_sigframe(ka
, env
, sizeof(*frame
));
1338 abi_ulong info_addr
, uc_addr
;
1340 if (!lock_user_struct(VERIFY_WRITE
, frame
, frame_addr
, 0))
1343 info_addr
= frame_addr
+ offsetof(struct rt_sigframe_v2
, info
);
1344 uc_addr
= frame_addr
+ offsetof(struct rt_sigframe_v2
, uc
);
1345 copy_siginfo_to_user(&frame
->info
, info
);
1347 setup_sigframe_v2(&frame
->uc
, set
, env
);
1349 setup_return(env
, ka
, &frame
->retcode
, frame_addr
, usig
,
1350 frame_addr
+ offsetof(struct rt_sigframe_v2
, retcode
));
1352 env
->regs
[1] = info_addr
;
1353 env
->regs
[2] = uc_addr
;
1355 unlock_user_struct(frame
, frame_addr
, 1);
1358 static void setup_rt_frame(int usig
, struct target_sigaction
*ka
,
1359 target_siginfo_t
*info
,
1360 target_sigset_t
*set
, CPUState
*env
)
1362 if (get_osversion() >= 0x020612) {
1363 setup_rt_frame_v2(usig
, ka
, info
, set
, env
);
1365 setup_rt_frame_v1(usig
, ka
, info
, set
, env
);
1370 restore_sigcontext(CPUState
*env
, struct target_sigcontext
*sc
)
1375 __get_user_error(env
->regs
[0], &sc
->arm_r0
, err
);
1376 __get_user_error(env
->regs
[1], &sc
->arm_r1
, err
);
1377 __get_user_error(env
->regs
[2], &sc
->arm_r2
, err
);
1378 __get_user_error(env
->regs
[3], &sc
->arm_r3
, err
);
1379 __get_user_error(env
->regs
[4], &sc
->arm_r4
, err
);
1380 __get_user_error(env
->regs
[5], &sc
->arm_r5
, err
);
1381 __get_user_error(env
->regs
[6], &sc
->arm_r6
, err
);
1382 __get_user_error(env
->regs
[7], &sc
->arm_r7
, err
);
1383 __get_user_error(env
->regs
[8], &sc
->arm_r8
, err
);
1384 __get_user_error(env
->regs
[9], &sc
->arm_r9
, err
);
1385 __get_user_error(env
->regs
[10], &sc
->arm_r10
, err
);
1386 __get_user_error(env
->regs
[11], &sc
->arm_fp
, err
);
1387 __get_user_error(env
->regs
[12], &sc
->arm_ip
, err
);
1388 __get_user_error(env
->regs
[13], &sc
->arm_sp
, err
);
1389 __get_user_error(env
->regs
[14], &sc
->arm_lr
, err
);
1390 __get_user_error(env
->regs
[15], &sc
->arm_pc
, err
);
1391 #ifdef TARGET_CONFIG_CPU_32
1392 __get_user_error(cpsr
, &sc
->arm_cpsr
, err
);
1393 cpsr_write(env
, cpsr
, CPSR_USER
| CPSR_EXEC
);
1396 err
|= !valid_user_regs(env
);
1401 long do_sigreturn_v1(CPUState
*env
)
1403 abi_ulong frame_addr
;
1404 struct sigframe_v1
*frame
;
1405 target_sigset_t set
;
1410 * Since we stacked the signal on a 64-bit boundary,
1411 * then 'sp' should be word aligned here. If it's
1412 * not, then the user is trying to mess with us.
1414 if (env
->regs
[13] & 7)
1417 frame_addr
= env
->regs
[13];
1418 if (!lock_user_struct(VERIFY_READ
, frame
, frame_addr
, 1))
1421 if (__get_user(set
.sig
[0], &frame
->sc
.oldmask
))
1423 for(i
= 1; i
< TARGET_NSIG_WORDS
; i
++) {
1424 if (__get_user(set
.sig
[i
], &frame
->extramask
[i
- 1]))
1428 target_to_host_sigset_internal(&host_set
, &set
);
1429 sigprocmask(SIG_SETMASK
, &host_set
, NULL
);
1431 if (restore_sigcontext(env
, &frame
->sc
))
1435 /* Send SIGTRAP if we're single-stepping */
1436 if (ptrace_cancel_bpt(current
))
1437 send_sig(SIGTRAP
, current
, 1);
1439 unlock_user_struct(frame
, frame_addr
, 0);
1440 return env
->regs
[0];
1443 unlock_user_struct(frame
, frame_addr
, 0);
1444 force_sig(SIGSEGV
/* , current */);
1448 static int do_sigframe_return_v2(CPUState
*env
, target_ulong frame_addr
,
1449 struct target_ucontext_v2
*uc
)
1453 target_to_host_sigset(&host_set
, &uc
->tuc_sigmask
);
1454 sigprocmask(SIG_SETMASK
, &host_set
, NULL
);
1456 if (restore_sigcontext(env
, &uc
->tuc_mcontext
))
1459 if (do_sigaltstack(frame_addr
+ offsetof(struct target_ucontext_v2
, tuc_stack
), 0, get_sp_from_cpustate(env
)) == -EFAULT
)
1463 /* Send SIGTRAP if we're single-stepping */
1464 if (ptrace_cancel_bpt(current
))
1465 send_sig(SIGTRAP
, current
, 1);
1471 long do_sigreturn_v2(CPUState
*env
)
1473 abi_ulong frame_addr
;
1474 struct sigframe_v2
*frame
;
1477 * Since we stacked the signal on a 64-bit boundary,
1478 * then 'sp' should be word aligned here. If it's
1479 * not, then the user is trying to mess with us.
1481 if (env
->regs
[13] & 7)
1484 frame_addr
= env
->regs
[13];
1485 if (!lock_user_struct(VERIFY_READ
, frame
, frame_addr
, 1))
1488 if (do_sigframe_return_v2(env
, frame_addr
, &frame
->uc
))
1491 unlock_user_struct(frame
, frame_addr
, 0);
1492 return env
->regs
[0];
1495 unlock_user_struct(frame
, frame_addr
, 0);
1496 force_sig(SIGSEGV
/* , current */);
1500 long do_sigreturn(CPUState
*env
)
1502 if (get_osversion() >= 0x020612) {
1503 return do_sigreturn_v2(env
);
1505 return do_sigreturn_v1(env
);
1509 long do_rt_sigreturn_v1(CPUState
*env
)
1511 abi_ulong frame_addr
;
1512 struct rt_sigframe_v1
*frame
;
1516 * Since we stacked the signal on a 64-bit boundary,
1517 * then 'sp' should be word aligned here. If it's
1518 * not, then the user is trying to mess with us.
1520 if (env
->regs
[13] & 7)
1523 frame_addr
= env
->regs
[13];
1524 if (!lock_user_struct(VERIFY_READ
, frame
, frame_addr
, 1))
1527 target_to_host_sigset(&host_set
, &frame
->uc
.tuc_sigmask
);
1528 sigprocmask(SIG_SETMASK
, &host_set
, NULL
);
1530 if (restore_sigcontext(env
, &frame
->uc
.tuc_mcontext
))
1533 if (do_sigaltstack(frame_addr
+ offsetof(struct rt_sigframe_v1
, uc
.tuc_stack
), 0, get_sp_from_cpustate(env
)) == -EFAULT
)
1537 /* Send SIGTRAP if we're single-stepping */
1538 if (ptrace_cancel_bpt(current
))
1539 send_sig(SIGTRAP
, current
, 1);
1541 unlock_user_struct(frame
, frame_addr
, 0);
1542 return env
->regs
[0];
1545 unlock_user_struct(frame
, frame_addr
, 0);
1546 force_sig(SIGSEGV
/* , current */);
1550 long do_rt_sigreturn_v2(CPUState
*env
)
1552 abi_ulong frame_addr
;
1553 struct rt_sigframe_v2
*frame
;
1556 * Since we stacked the signal on a 64-bit boundary,
1557 * then 'sp' should be word aligned here. If it's
1558 * not, then the user is trying to mess with us.
1560 if (env
->regs
[13] & 7)
1563 frame_addr
= env
->regs
[13];
1564 if (!lock_user_struct(VERIFY_READ
, frame
, frame_addr
, 1))
1567 if (do_sigframe_return_v2(env
, frame_addr
, &frame
->uc
))
1570 unlock_user_struct(frame
, frame_addr
, 0);
1571 return env
->regs
[0];
1574 unlock_user_struct(frame
, frame_addr
, 0);
1575 force_sig(SIGSEGV
/* , current */);
1579 long do_rt_sigreturn(CPUState
*env
)
1581 if (get_osversion() >= 0x020612) {
1582 return do_rt_sigreturn_v2(env
);
1584 return do_rt_sigreturn_v1(env
);
1588 #elif defined(TARGET_SPARC)
1590 #define __SUNOS_MAXWIN 31
1592 /* This is what SunOS does, so shall I. */
1593 struct target_sigcontext
{
1594 abi_ulong sigc_onstack
; /* state to restore */
1596 abi_ulong sigc_mask
; /* sigmask to restore */
1597 abi_ulong sigc_sp
; /* stack pointer */
1598 abi_ulong sigc_pc
; /* program counter */
1599 abi_ulong sigc_npc
; /* next program counter */
1600 abi_ulong sigc_psr
; /* for condition codes etc */
1601 abi_ulong sigc_g1
; /* User uses these two registers */
1602 abi_ulong sigc_o0
; /* within the trampoline code. */
1604 /* Now comes information regarding the users window set
1605 * at the time of the signal.
1607 abi_ulong sigc_oswins
; /* outstanding windows */
1609 /* stack ptrs for each regwin buf */
1610 char *sigc_spbuf
[__SUNOS_MAXWIN
];
1612 /* Windows to restore after signal */
1614 abi_ulong locals
[8];
1616 } sigc_wbuf
[__SUNOS_MAXWIN
];
1618 /* A Sparc stack frame */
1619 struct sparc_stackf
{
1620 abi_ulong locals
[8];
1622 struct sparc_stackf
*fp
;
1623 abi_ulong callers_pc
;
1626 abi_ulong xxargs
[1];
1635 abi_ulong u_regs
[16]; /* globals and ins */
1641 unsigned long si_float_regs
[32];
1642 unsigned long si_fsr
;
1643 unsigned long si_fpqdepth
;
1645 unsigned long *insn_addr
;
1648 } qemu_siginfo_fpu_t
;
1651 struct target_signal_frame
{
1652 struct sparc_stackf ss
;
1655 abi_ulong insns
[2] __attribute__ ((aligned (8)));
1656 abi_ulong extramask
[TARGET_NSIG_WORDS
- 1];
1657 abi_ulong extra_size
; /* Should be 0 */
1658 qemu_siginfo_fpu_t fpu_state
;
1660 struct target_rt_signal_frame
{
1661 struct sparc_stackf ss
;
1666 unsigned int insns
[2];
1668 unsigned int extra_size
; /* Should be 0 */
1669 qemu_siginfo_fpu_t fpu_state
;
1683 #define UREG_FP UREG_I6
1684 #define UREG_SP UREG_O6
1686 static inline abi_ulong
get_sigframe(struct target_sigaction
*sa
,
1687 CPUState
*env
, unsigned long framesize
)
1691 sp
= env
->regwptr
[UREG_FP
];
1693 /* This is the X/Open sanctioned signal stack switching. */
1694 if (sa
->sa_flags
& TARGET_SA_ONSTACK
) {
1695 if (!on_sig_stack(sp
)
1696 && !((target_sigaltstack_used
.ss_sp
+ target_sigaltstack_used
.ss_size
) & 7))
1697 sp
= target_sigaltstack_used
.ss_sp
+ target_sigaltstack_used
.ss_size
;
1699 return sp
- framesize
;
1703 setup___siginfo(__siginfo_t
*si
, CPUState
*env
, abi_ulong mask
)
1707 err
|= __put_user(env
->psr
, &si
->si_regs
.psr
);
1708 err
|= __put_user(env
->pc
, &si
->si_regs
.pc
);
1709 err
|= __put_user(env
->npc
, &si
->si_regs
.npc
);
1710 err
|= __put_user(env
->y
, &si
->si_regs
.y
);
1711 for (i
=0; i
< 8; i
++) {
1712 err
|= __put_user(env
->gregs
[i
], &si
->si_regs
.u_regs
[i
]);
1714 for (i
=0; i
< 8; i
++) {
1715 err
|= __put_user(env
->regwptr
[UREG_I0
+ i
], &si
->si_regs
.u_regs
[i
+8]);
1717 err
|= __put_user(mask
, &si
->si_mask
);
1723 setup_sigcontext(struct target_sigcontext
*sc
, /*struct _fpstate *fpstate,*/
1724 CPUState
*env
, unsigned long mask
)
1728 err
|= __put_user(mask
, &sc
->sigc_mask
);
1729 err
|= __put_user(env
->regwptr
[UREG_SP
], &sc
->sigc_sp
);
1730 err
|= __put_user(env
->pc
, &sc
->sigc_pc
);
1731 err
|= __put_user(env
->npc
, &sc
->sigc_npc
);
1732 err
|= __put_user(env
->psr
, &sc
->sigc_psr
);
1733 err
|= __put_user(env
->gregs
[1], &sc
->sigc_g1
);
1734 err
|= __put_user(env
->regwptr
[UREG_O0
], &sc
->sigc_o0
);
1739 #define NF_ALIGNEDSZ (((sizeof(struct target_signal_frame) + 7) & (~7)))
1741 static void setup_frame(int sig
, struct target_sigaction
*ka
,
1742 target_sigset_t
*set
, CPUState
*env
)
1745 struct target_signal_frame
*sf
;
1746 int sigframe_size
, err
, i
;
1748 /* 1. Make sure everything is clean */
1749 //synchronize_user_stack();
1751 sigframe_size
= NF_ALIGNEDSZ
;
1752 sf_addr
= get_sigframe(ka
, env
, sigframe_size
);
1754 sf
= lock_user(VERIFY_WRITE
, sf_addr
,
1755 sizeof(struct target_signal_frame
), 0);
1759 //fprintf(stderr, "sf: %x pc %x fp %x sp %x\n", sf, env->pc, env->regwptr[UREG_FP], env->regwptr[UREG_SP]);
1761 if (invalid_frame_pointer(sf
, sigframe_size
))
1762 goto sigill_and_return
;
1764 /* 2. Save the current process state */
1765 err
= setup___siginfo(&sf
->info
, env
, set
->sig
[0]);
1766 err
|= __put_user(0, &sf
->extra_size
);
1768 //err |= save_fpu_state(regs, &sf->fpu_state);
1769 //err |= __put_user(&sf->fpu_state, &sf->fpu_save);
1771 err
|= __put_user(set
->sig
[0], &sf
->info
.si_mask
);
1772 for (i
= 0; i
< TARGET_NSIG_WORDS
- 1; i
++) {
1773 err
|= __put_user(set
->sig
[i
+ 1], &sf
->extramask
[i
]);
1776 for (i
= 0; i
< 8; i
++) {
1777 err
|= __put_user(env
->regwptr
[i
+ UREG_L0
], &sf
->ss
.locals
[i
]);
1779 for (i
= 0; i
< 8; i
++) {
1780 err
|= __put_user(env
->regwptr
[i
+ UREG_I0
], &sf
->ss
.ins
[i
]);
1785 /* 3. signal handler back-trampoline and parameters */
1786 env
->regwptr
[UREG_FP
] = sf_addr
;
1787 env
->regwptr
[UREG_I0
] = sig
;
1788 env
->regwptr
[UREG_I1
] = sf_addr
+
1789 offsetof(struct target_signal_frame
, info
);
1790 env
->regwptr
[UREG_I2
] = sf_addr
+
1791 offsetof(struct target_signal_frame
, info
);
1793 /* 4. signal handler */
1794 env
->pc
= ka
->_sa_handler
;
1795 env
->npc
= (env
->pc
+ 4);
1796 /* 5. return to kernel instructions */
1797 if (ka
->sa_restorer
)
1798 env
->regwptr
[UREG_I7
] = ka
->sa_restorer
;
1802 env
->regwptr
[UREG_I7
] = sf_addr
+
1803 offsetof(struct target_signal_frame
, insns
) - 2 * 4;
1805 /* mov __NR_sigreturn, %g1 */
1807 err
|= __put_user(val32
, &sf
->insns
[0]);
1811 err
|= __put_user(val32
, &sf
->insns
[1]);
1815 /* Flush instruction space. */
1816 //flush_sig_insns(current->mm, (unsigned long) &(sf->insns[0]));
1819 unlock_user(sf
, sf_addr
, sizeof(struct target_signal_frame
));
1823 force_sig(TARGET_SIGILL
);
1826 //fprintf(stderr, "force_sig\n");
1827 unlock_user(sf
, sf_addr
, sizeof(struct target_signal_frame
));
1828 force_sig(TARGET_SIGSEGV
);
1831 restore_fpu_state(CPUState
*env
, qemu_siginfo_fpu_t
*fpu
)
1836 if (current
->flags
& PF_USEDFPU
)
1837 regs
->psr
&= ~PSR_EF
;
1839 if (current
== last_task_used_math
) {
1840 last_task_used_math
= 0;
1841 regs
->psr
&= ~PSR_EF
;
1844 current
->used_math
= 1;
1845 current
->flags
&= ~PF_USEDFPU
;
1848 if (verify_area (VERIFY_READ
, fpu
, sizeof(*fpu
)))
1853 /* XXX: incorrect */
1854 err
= __copy_from_user(&env
->fpr
[0], &fpu
->si_float_regs
[0],
1855 (sizeof(unsigned long) * 32));
1857 err
|= __get_user(env
->fsr
, &fpu
->si_fsr
);
1859 err
|= __get_user(current
->thread
.fpqdepth
, &fpu
->si_fpqdepth
);
1860 if (current
->thread
.fpqdepth
!= 0)
1861 err
|= __copy_from_user(¤t
->thread
.fpqueue
[0],
1862 &fpu
->si_fpqueue
[0],
1863 ((sizeof(unsigned long) +
1864 (sizeof(unsigned long *)))*16));
1870 static void setup_rt_frame(int sig
, struct target_sigaction
*ka
,
1871 target_siginfo_t
*info
,
1872 target_sigset_t
*set
, CPUState
*env
)
1874 fprintf(stderr
, "setup_rt_frame: not implemented\n");
1877 long do_sigreturn(CPUState
*env
)
1880 struct target_signal_frame
*sf
;
1881 uint32_t up_psr
, pc
, npc
;
1882 target_sigset_t set
;
1884 abi_ulong fpu_save_addr
;
1887 sf_addr
= env
->regwptr
[UREG_FP
];
1888 if (!lock_user_struct(VERIFY_READ
, sf
, sf_addr
, 1))
1891 fprintf(stderr
, "sigreturn\n");
1892 fprintf(stderr
, "sf: %x pc %x fp %x sp %x\n", sf
, env
->pc
, env
->regwptr
[UREG_FP
], env
->regwptr
[UREG_SP
]);
1894 //cpu_dump_state(env, stderr, fprintf, 0);
1896 /* 1. Make sure we are not getting garbage from the user */
1901 err
= __get_user(pc
, &sf
->info
.si_regs
.pc
);
1902 err
|= __get_user(npc
, &sf
->info
.si_regs
.npc
);
1907 /* 2. Restore the state */
1908 err
|= __get_user(up_psr
, &sf
->info
.si_regs
.psr
);
1910 /* User can only change condition codes and FPU enabling in %psr. */
1911 env
->psr
= (up_psr
& (PSR_ICC
/* | PSR_EF */))
1912 | (env
->psr
& ~(PSR_ICC
/* | PSR_EF */));
1916 err
|= __get_user(env
->y
, &sf
->info
.si_regs
.y
);
1917 for (i
=0; i
< 8; i
++) {
1918 err
|= __get_user(env
->gregs
[i
], &sf
->info
.si_regs
.u_regs
[i
]);
1920 for (i
=0; i
< 8; i
++) {
1921 err
|= __get_user(env
->regwptr
[i
+ UREG_I0
], &sf
->info
.si_regs
.u_regs
[i
+8]);
1924 err
|= __get_user(fpu_save_addr
, &sf
->fpu_save
);
1927 // err |= restore_fpu_state(env, fpu_save);
1929 /* This is pretty much atomic, no amount locking would prevent
1930 * the races which exist anyways.
1932 err
|= __get_user(set
.sig
[0], &sf
->info
.si_mask
);
1933 for(i
= 1; i
< TARGET_NSIG_WORDS
; i
++) {
1934 err
|= (__get_user(set
.sig
[i
], &sf
->extramask
[i
- 1]));
1937 target_to_host_sigset_internal(&host_set
, &set
);
1938 sigprocmask(SIG_SETMASK
, &host_set
, NULL
);
1942 unlock_user_struct(sf
, sf_addr
, 0);
1943 return env
->regwptr
[0];
1946 unlock_user_struct(sf
, sf_addr
, 0);
1947 force_sig(TARGET_SIGSEGV
);
1950 long do_rt_sigreturn(CPUState
*env
)
1952 fprintf(stderr
, "do_rt_sigreturn: not implemented\n");
1953 return -TARGET_ENOSYS
;
1956 #if defined(TARGET_SPARC64) && !defined(TARGET_ABI32)
1978 typedef abi_ulong target_mc_greg_t
;
1979 typedef target_mc_greg_t target_mc_gregset_t
[MC_NGREG
];
1981 struct target_mc_fq
{
1982 abi_ulong
*mcfq_addr
;
1986 struct target_mc_fpu
{
1990 //uint128_t qregs[16];
1992 abi_ulong mcfpu_fsr
;
1993 abi_ulong mcfpu_fprs
;
1994 abi_ulong mcfpu_gsr
;
1995 struct target_mc_fq
*mcfpu_fq
;
1996 unsigned char mcfpu_qcnt
;
1997 unsigned char mcfpu_qentsz
;
1998 unsigned char mcfpu_enab
;
2000 typedef struct target_mc_fpu target_mc_fpu_t
;
2003 target_mc_gregset_t mc_gregs
;
2004 target_mc_greg_t mc_fp
;
2005 target_mc_greg_t mc_i7
;
2006 target_mc_fpu_t mc_fpregs
;
2007 } target_mcontext_t
;
2009 struct target_ucontext
{
2010 struct target_ucontext
*uc_link
;
2012 target_sigset_t uc_sigmask
;
2013 target_mcontext_t uc_mcontext
;
2016 /* A V9 register window */
2017 struct target_reg_window
{
2018 abi_ulong locals
[8];
2022 #define TARGET_STACK_BIAS 2047
2024 /* {set, get}context() needed for 64-bit SparcLinux userland. */
2025 void sparc64_set_context(CPUSPARCState
*env
)
2028 struct target_ucontext
*ucp
;
2029 target_mc_gregset_t
*grp
;
2030 abi_ulong pc
, npc
, tstate
;
2031 abi_ulong fp
, i7
, w_addr
;
2032 unsigned char fenab
;
2036 ucp_addr
= env
->regwptr
[UREG_I0
];
2037 if (!lock_user_struct(VERIFY_READ
, ucp
, ucp_addr
, 1))
2039 grp
= &ucp
->uc_mcontext
.mc_gregs
;
2040 err
= __get_user(pc
, &((*grp
)[MC_PC
]));
2041 err
|= __get_user(npc
, &((*grp
)[MC_NPC
]));
2042 if (err
|| ((pc
| npc
) & 3))
2044 if (env
->regwptr
[UREG_I1
]) {
2045 target_sigset_t target_set
;
2048 if (TARGET_NSIG_WORDS
== 1) {
2049 if (__get_user(target_set
.sig
[0], &ucp
->uc_sigmask
.sig
[0]))
2052 abi_ulong
*src
, *dst
;
2053 src
= ucp
->uc_sigmask
.sig
;
2054 dst
= target_set
.sig
;
2055 for (i
= 0; i
< sizeof(target_sigset_t
) / sizeof(abi_ulong
);
2057 err
|= __get_user(*dst
, src
);
2061 target_to_host_sigset_internal(&set
, &target_set
);
2062 sigprocmask(SIG_SETMASK
, &set
, NULL
);
2066 err
|= __get_user(env
->y
, &((*grp
)[MC_Y
]));
2067 err
|= __get_user(tstate
, &((*grp
)[MC_TSTATE
]));
2068 env
->asi
= (tstate
>> 24) & 0xff;
2069 PUT_CCR(env
, tstate
>> 32);
2070 PUT_CWP64(env
, tstate
& 0x1f);
2071 err
|= __get_user(env
->gregs
[1], (&(*grp
)[MC_G1
]));
2072 err
|= __get_user(env
->gregs
[2], (&(*grp
)[MC_G2
]));
2073 err
|= __get_user(env
->gregs
[3], (&(*grp
)[MC_G3
]));
2074 err
|= __get_user(env
->gregs
[4], (&(*grp
)[MC_G4
]));
2075 err
|= __get_user(env
->gregs
[5], (&(*grp
)[MC_G5
]));
2076 err
|= __get_user(env
->gregs
[6], (&(*grp
)[MC_G6
]));
2077 err
|= __get_user(env
->gregs
[7], (&(*grp
)[MC_G7
]));
2078 err
|= __get_user(env
->regwptr
[UREG_I0
], (&(*grp
)[MC_O0
]));
2079 err
|= __get_user(env
->regwptr
[UREG_I1
], (&(*grp
)[MC_O1
]));
2080 err
|= __get_user(env
->regwptr
[UREG_I2
], (&(*grp
)[MC_O2
]));
2081 err
|= __get_user(env
->regwptr
[UREG_I3
], (&(*grp
)[MC_O3
]));
2082 err
|= __get_user(env
->regwptr
[UREG_I4
], (&(*grp
)[MC_O4
]));
2083 err
|= __get_user(env
->regwptr
[UREG_I5
], (&(*grp
)[MC_O5
]));
2084 err
|= __get_user(env
->regwptr
[UREG_I6
], (&(*grp
)[MC_O6
]));
2085 err
|= __get_user(env
->regwptr
[UREG_I7
], (&(*grp
)[MC_O7
]));
2087 err
|= __get_user(fp
, &(ucp
->uc_mcontext
.mc_fp
));
2088 err
|= __get_user(i7
, &(ucp
->uc_mcontext
.mc_i7
));
2090 w_addr
= TARGET_STACK_BIAS
+env
->regwptr
[UREG_I6
];
2091 if (put_user(fp
, w_addr
+ offsetof(struct target_reg_window
, ins
[6]),
2094 if (put_user(i7
, w_addr
+ offsetof(struct target_reg_window
, ins
[7]),
2097 err
|= __get_user(fenab
, &(ucp
->uc_mcontext
.mc_fpregs
.mcfpu_enab
));
2098 err
|= __get_user(env
->fprs
, &(ucp
->uc_mcontext
.mc_fpregs
.mcfpu_fprs
));
2100 uint32_t *src
, *dst
;
2101 src
= ucp
->uc_mcontext
.mc_fpregs
.mcfpu_fregs
.sregs
;
2103 /* XXX: check that the CPU storage is the same as user context */
2104 for (i
= 0; i
< 64; i
++, dst
++, src
++)
2105 err
|= __get_user(*dst
, src
);
2107 err
|= __get_user(env
->fsr
,
2108 &(ucp
->uc_mcontext
.mc_fpregs
.mcfpu_fsr
));
2109 err
|= __get_user(env
->gsr
,
2110 &(ucp
->uc_mcontext
.mc_fpregs
.mcfpu_gsr
));
2113 unlock_user_struct(ucp
, ucp_addr
, 0);
2116 unlock_user_struct(ucp
, ucp_addr
, 0);
2120 void sparc64_get_context(CPUSPARCState
*env
)
2123 struct target_ucontext
*ucp
;
2124 target_mc_gregset_t
*grp
;
2125 target_mcontext_t
*mcp
;
2126 abi_ulong fp
, i7
, w_addr
;
2129 target_sigset_t target_set
;
2132 ucp_addr
= env
->regwptr
[UREG_I0
];
2133 if (!lock_user_struct(VERIFY_WRITE
, ucp
, ucp_addr
, 0))
2136 mcp
= &ucp
->uc_mcontext
;
2137 grp
= &mcp
->mc_gregs
;
2139 /* Skip over the trap instruction, first. */
2145 sigprocmask(0, NULL
, &set
);
2146 host_to_target_sigset_internal(&target_set
, &set
);
2147 if (TARGET_NSIG_WORDS
== 1) {
2148 err
|= __put_user(target_set
.sig
[0],
2149 (abi_ulong
*)&ucp
->uc_sigmask
);
2151 abi_ulong
*src
, *dst
;
2152 src
= target_set
.sig
;
2153 dst
= ucp
->uc_sigmask
.sig
;
2154 for (i
= 0; i
< sizeof(target_sigset_t
) / sizeof(abi_ulong
);
2156 err
|= __put_user(*src
, dst
);
2161 /* XXX: tstate must be saved properly */
2162 // err |= __put_user(env->tstate, &((*grp)[MC_TSTATE]));
2163 err
|= __put_user(env
->pc
, &((*grp
)[MC_PC
]));
2164 err
|= __put_user(env
->npc
, &((*grp
)[MC_NPC
]));
2165 err
|= __put_user(env
->y
, &((*grp
)[MC_Y
]));
2166 err
|= __put_user(env
->gregs
[1], &((*grp
)[MC_G1
]));
2167 err
|= __put_user(env
->gregs
[2], &((*grp
)[MC_G2
]));
2168 err
|= __put_user(env
->gregs
[3], &((*grp
)[MC_G3
]));
2169 err
|= __put_user(env
->gregs
[4], &((*grp
)[MC_G4
]));
2170 err
|= __put_user(env
->gregs
[5], &((*grp
)[MC_G5
]));
2171 err
|= __put_user(env
->gregs
[6], &((*grp
)[MC_G6
]));
2172 err
|= __put_user(env
->gregs
[7], &((*grp
)[MC_G7
]));
2173 err
|= __put_user(env
->regwptr
[UREG_I0
], &((*grp
)[MC_O0
]));
2174 err
|= __put_user(env
->regwptr
[UREG_I1
], &((*grp
)[MC_O1
]));
2175 err
|= __put_user(env
->regwptr
[UREG_I2
], &((*grp
)[MC_O2
]));
2176 err
|= __put_user(env
->regwptr
[UREG_I3
], &((*grp
)[MC_O3
]));
2177 err
|= __put_user(env
->regwptr
[UREG_I4
], &((*grp
)[MC_O4
]));
2178 err
|= __put_user(env
->regwptr
[UREG_I5
], &((*grp
)[MC_O5
]));
2179 err
|= __put_user(env
->regwptr
[UREG_I6
], &((*grp
)[MC_O6
]));
2180 err
|= __put_user(env
->regwptr
[UREG_I7
], &((*grp
)[MC_O7
]));
2182 w_addr
= TARGET_STACK_BIAS
+env
->regwptr
[UREG_I6
];
2184 if (get_user(fp
, w_addr
+ offsetof(struct target_reg_window
, ins
[6]),
2187 if (get_user(i7
, w_addr
+ offsetof(struct target_reg_window
, ins
[7]),
2190 err
|= __put_user(fp
, &(mcp
->mc_fp
));
2191 err
|= __put_user(i7
, &(mcp
->mc_i7
));
2194 uint32_t *src
, *dst
;
2196 dst
= ucp
->uc_mcontext
.mc_fpregs
.mcfpu_fregs
.sregs
;
2197 /* XXX: check that the CPU storage is the same as user context */
2198 for (i
= 0; i
< 64; i
++, dst
++, src
++)
2199 err
|= __put_user(*src
, dst
);
2201 err
|= __put_user(env
->fsr
, &(mcp
->mc_fpregs
.mcfpu_fsr
));
2202 err
|= __put_user(env
->gsr
, &(mcp
->mc_fpregs
.mcfpu_gsr
));
2203 err
|= __put_user(env
->fprs
, &(mcp
->mc_fpregs
.mcfpu_fprs
));
2207 unlock_user_struct(ucp
, ucp_addr
, 1);
2210 unlock_user_struct(ucp
, ucp_addr
, 1);
2214 #elif defined(TARGET_ABI_MIPSN64)
2216 # warning signal handling not implemented
2218 static void setup_frame(int sig
, struct target_sigaction
*ka
,
2219 target_sigset_t
*set
, CPUState
*env
)
2221 fprintf(stderr
, "setup_frame: not implemented\n");
2224 static void setup_rt_frame(int sig
, struct target_sigaction
*ka
,
2225 target_siginfo_t
*info
,
2226 target_sigset_t
*set
, CPUState
*env
)
2228 fprintf(stderr
, "setup_rt_frame: not implemented\n");
2231 long do_sigreturn(CPUState
*env
)
2233 fprintf(stderr
, "do_sigreturn: not implemented\n");
2234 return -TARGET_ENOSYS
;
2237 long do_rt_sigreturn(CPUState
*env
)
2239 fprintf(stderr
, "do_rt_sigreturn: not implemented\n");
2240 return -TARGET_ENOSYS
;
2243 #elif defined(TARGET_ABI_MIPSN32)
2245 # warning signal handling not implemented
2247 static void setup_frame(int sig
, struct target_sigaction
*ka
,
2248 target_sigset_t
*set
, CPUState
*env
)
2250 fprintf(stderr
, "setup_frame: not implemented\n");
2253 static void setup_rt_frame(int sig
, struct target_sigaction
*ka
,
2254 target_siginfo_t
*info
,
2255 target_sigset_t
*set
, CPUState
*env
)
2257 fprintf(stderr
, "setup_rt_frame: not implemented\n");
2260 long do_sigreturn(CPUState
*env
)
2262 fprintf(stderr
, "do_sigreturn: not implemented\n");
2263 return -TARGET_ENOSYS
;
2266 long do_rt_sigreturn(CPUState
*env
)
2268 fprintf(stderr
, "do_rt_sigreturn: not implemented\n");
2269 return -TARGET_ENOSYS
;
2272 #elif defined(TARGET_ABI_MIPSO32)
2274 struct target_sigcontext
{
2275 uint32_t sc_regmask
; /* Unused */
2278 uint64_t sc_regs
[32];
2279 uint64_t sc_fpregs
[32];
2280 uint32_t sc_ownedfp
; /* Unused */
2281 uint32_t sc_fpc_csr
;
2282 uint32_t sc_fpc_eir
; /* Unused */
2283 uint32_t sc_used_math
;
2284 uint32_t sc_dsp
; /* dsp status, was sc_ssflags */
2287 target_ulong sc_hi1
; /* Was sc_cause */
2288 target_ulong sc_lo1
; /* Was sc_badvaddr */
2289 target_ulong sc_hi2
; /* Was sc_sigset[4] */
2290 target_ulong sc_lo2
;
2291 target_ulong sc_hi3
;
2292 target_ulong sc_lo3
;
2296 uint32_t sf_ass
[4]; /* argument save space for o32 */
2297 uint32_t sf_code
[2]; /* signal trampoline */
2298 struct target_sigcontext sf_sc
;
2299 target_sigset_t sf_mask
;
2302 /* Install trampoline to jump back from signal handler */
2303 static inline int install_sigtramp(unsigned int *tramp
, unsigned int syscall
)
2308 * Set up the return code ...
2310 * li v0, __NR__foo_sigreturn
2314 err
= __put_user(0x24020000 + syscall
, tramp
+ 0);
2315 err
|= __put_user(0x0000000c , tramp
+ 1);
2316 /* flush_cache_sigtramp((unsigned long) tramp); */
2321 setup_sigcontext(CPUState
*regs
, struct target_sigcontext
*sc
)
2325 err
|= __put_user(regs
->active_tc
.PC
, &sc
->sc_pc
);
2327 #define save_gp_reg(i) do { \
2328 err |= __put_user(regs->active_tc.gpr[i], &sc->sc_regs[i]); \
2330 __put_user(0, &sc
->sc_regs
[0]); save_gp_reg(1); save_gp_reg(2);
2331 save_gp_reg(3); save_gp_reg(4); save_gp_reg(5); save_gp_reg(6);
2332 save_gp_reg(7); save_gp_reg(8); save_gp_reg(9); save_gp_reg(10);
2333 save_gp_reg(11); save_gp_reg(12); save_gp_reg(13); save_gp_reg(14);
2334 save_gp_reg(15); save_gp_reg(16); save_gp_reg(17); save_gp_reg(18);
2335 save_gp_reg(19); save_gp_reg(20); save_gp_reg(21); save_gp_reg(22);
2336 save_gp_reg(23); save_gp_reg(24); save_gp_reg(25); save_gp_reg(26);
2337 save_gp_reg(27); save_gp_reg(28); save_gp_reg(29); save_gp_reg(30);
2341 err
|= __put_user(regs
->active_tc
.HI
[0], &sc
->sc_mdhi
);
2342 err
|= __put_user(regs
->active_tc
.LO
[0], &sc
->sc_mdlo
);
2344 /* Not used yet, but might be useful if we ever have DSP suppport */
2347 err
|= __put_user(mfhi1(), &sc
->sc_hi1
);
2348 err
|= __put_user(mflo1(), &sc
->sc_lo1
);
2349 err
|= __put_user(mfhi2(), &sc
->sc_hi2
);
2350 err
|= __put_user(mflo2(), &sc
->sc_lo2
);
2351 err
|= __put_user(mfhi3(), &sc
->sc_hi3
);
2352 err
|= __put_user(mflo3(), &sc
->sc_lo3
);
2353 err
|= __put_user(rddsp(DSP_MASK
), &sc
->sc_dsp
);
2355 /* same with 64 bit */
2357 err
|= __put_user(regs
->hi
, &sc
->sc_hi
[0]);
2358 err
|= __put_user(regs
->lo
, &sc
->sc_lo
[0]);
2360 err
|= __put_user(mfhi1(), &sc
->sc_hi
[1]);
2361 err
|= __put_user(mflo1(), &sc
->sc_lo
[1]);
2362 err
|= __put_user(mfhi2(), &sc
->sc_hi
[2]);
2363 err
|= __put_user(mflo2(), &sc
->sc_lo
[2]);
2364 err
|= __put_user(mfhi3(), &sc
->sc_hi
[3]);
2365 err
|= __put_user(mflo3(), &sc
->sc_lo
[3]);
2366 err
|= __put_user(rddsp(DSP_MASK
), &sc
->sc_dsp
);
2372 err
|= __put_user(!!used_math(), &sc
->sc_used_math
);
2378 * Save FPU state to signal context. Signal handler will "inherit"
2379 * current FPU state.
2383 if (!is_fpu_owner()) {
2385 restore_fp(current
);
2387 err
|= save_fp_context(sc
);
2396 restore_sigcontext(CPUState
*regs
, struct target_sigcontext
*sc
)
2400 err
|= __get_user(regs
->CP0_EPC
, &sc
->sc_pc
);
2402 err
|= __get_user(regs
->active_tc
.HI
[0], &sc
->sc_mdhi
);
2403 err
|= __get_user(regs
->active_tc
.LO
[0], &sc
->sc_mdlo
);
2405 #define restore_gp_reg(i) do { \
2406 err |= __get_user(regs->active_tc.gpr[i], &sc->sc_regs[i]); \
2408 restore_gp_reg( 1); restore_gp_reg( 2); restore_gp_reg( 3);
2409 restore_gp_reg( 4); restore_gp_reg( 5); restore_gp_reg( 6);
2410 restore_gp_reg( 7); restore_gp_reg( 8); restore_gp_reg( 9);
2411 restore_gp_reg(10); restore_gp_reg(11); restore_gp_reg(12);
2412 restore_gp_reg(13); restore_gp_reg(14); restore_gp_reg(15);
2413 restore_gp_reg(16); restore_gp_reg(17); restore_gp_reg(18);
2414 restore_gp_reg(19); restore_gp_reg(20); restore_gp_reg(21);
2415 restore_gp_reg(22); restore_gp_reg(23); restore_gp_reg(24);
2416 restore_gp_reg(25); restore_gp_reg(26); restore_gp_reg(27);
2417 restore_gp_reg(28); restore_gp_reg(29); restore_gp_reg(30);
2419 #undef restore_gp_reg
2423 err
|= __get_user(treg
, &sc
->sc_hi1
); mthi1(treg
);
2424 err
|= __get_user(treg
, &sc
->sc_lo1
); mtlo1(treg
);
2425 err
|= __get_user(treg
, &sc
->sc_hi2
); mthi2(treg
);
2426 err
|= __get_user(treg
, &sc
->sc_lo2
); mtlo2(treg
);
2427 err
|= __get_user(treg
, &sc
->sc_hi3
); mthi3(treg
);
2428 err
|= __get_user(treg
, &sc
->sc_lo3
); mtlo3(treg
);
2429 err
|= __get_user(treg
, &sc
->sc_dsp
); wrdsp(treg
, DSP_MASK
);
2432 err
|= __get_user(regs
->hi
, &sc
->sc_hi
[0]);
2433 err
|= __get_user(regs
->lo
, &sc
->sc_lo
[0]);
2435 err
|= __get_user(treg
, &sc
->sc_hi
[1]); mthi1(treg
);
2436 err
|= __get_user(treg
, &sc
->sc_lo
[1]); mthi1(treg
);
2437 err
|= __get_user(treg
, &sc
->sc_hi
[2]); mthi2(treg
);
2438 err
|= __get_user(treg
, &sc
->sc_lo
[2]); mthi2(treg
);
2439 err
|= __get_user(treg
, &sc
->sc_hi
[3]); mthi3(treg
);
2440 err
|= __get_user(treg
, &sc
->sc_lo
[3]); mthi3(treg
);
2441 err
|= __get_user(treg
, &sc
->sc_dsp
); wrdsp(treg
, DSP_MASK
);
2445 err
|= __get_user(used_math
, &sc
->sc_used_math
);
2446 conditional_used_math(used_math
);
2451 /* restore fpu context if we have used it before */
2453 err
|= restore_fp_context(sc
);
2455 /* signal handler may have used FPU. Give it up. */
2464 * Determine which stack to use..
2466 static inline abi_ulong
2467 get_sigframe(struct target_sigaction
*ka
, CPUState
*regs
, size_t frame_size
)
2471 /* Default to using normal stack */
2472 sp
= regs
->active_tc
.gpr
[29];
2475 * FPU emulator may have it's own trampoline active just
2476 * above the user stack, 16-bytes before the next lowest
2477 * 16 byte boundary. Try to avoid trashing it.
2481 /* This is the X/Open sanctioned signal stack switching. */
2482 if ((ka
->sa_flags
& TARGET_SA_ONSTACK
) && (sas_ss_flags (sp
) == 0)) {
2483 sp
= target_sigaltstack_used
.ss_sp
+ target_sigaltstack_used
.ss_size
;
2486 return (sp
- frame_size
) & ~7;
2489 /* compare linux/arch/mips/kernel/signal.c:setup_frame() */
2490 static void setup_frame(int sig
, struct target_sigaction
* ka
,
2491 target_sigset_t
*set
, CPUState
*regs
)
2493 struct sigframe
*frame
;
2494 abi_ulong frame_addr
;
2497 frame_addr
= get_sigframe(ka
, regs
, sizeof(*frame
));
2498 if (!lock_user_struct(VERIFY_WRITE
, frame
, frame_addr
, 0))
2501 install_sigtramp(frame
->sf_code
, TARGET_NR_sigreturn
);
2503 if(setup_sigcontext(regs
, &frame
->sf_sc
))
2506 for(i
= 0; i
< TARGET_NSIG_WORDS
; i
++) {
2507 if(__put_user(set
->sig
[i
], &frame
->sf_mask
.sig
[i
]))
2512 * Arguments to signal handler:
2514 * a0 = signal number
2515 * a1 = 0 (should be cause)
2516 * a2 = pointer to struct sigcontext
2518 * $25 and PC point to the signal handler, $29 points to the
2521 regs
->active_tc
.gpr
[ 4] = sig
;
2522 regs
->active_tc
.gpr
[ 5] = 0;
2523 regs
->active_tc
.gpr
[ 6] = frame_addr
+ offsetof(struct sigframe
, sf_sc
);
2524 regs
->active_tc
.gpr
[29] = frame_addr
;
2525 regs
->active_tc
.gpr
[31] = frame_addr
+ offsetof(struct sigframe
, sf_code
);
2526 /* The original kernel code sets CP0_EPC to the handler
2527 * since it returns to userland using eret
2528 * we cannot do this here, and we must set PC directly */
2529 regs
->active_tc
.PC
= regs
->active_tc
.gpr
[25] = ka
->_sa_handler
;
2530 unlock_user_struct(frame
, frame_addr
, 1);
2534 unlock_user_struct(frame
, frame_addr
, 1);
2535 force_sig(TARGET_SIGSEGV
/*, current*/);
2539 long do_sigreturn(CPUState
*regs
)
2541 struct sigframe
*frame
;
2542 abi_ulong frame_addr
;
2544 target_sigset_t target_set
;
2547 #if defined(DEBUG_SIGNAL)
2548 fprintf(stderr
, "do_sigreturn\n");
2550 frame_addr
= regs
->active_tc
.gpr
[29];
2551 if (!lock_user_struct(VERIFY_READ
, frame
, frame_addr
, 1))
2554 for(i
= 0; i
< TARGET_NSIG_WORDS
; i
++) {
2555 if(__get_user(target_set
.sig
[i
], &frame
->sf_mask
.sig
[i
]))
2559 target_to_host_sigset_internal(&blocked
, &target_set
);
2560 sigprocmask(SIG_SETMASK
, &blocked
, NULL
);
2562 if (restore_sigcontext(regs
, &frame
->sf_sc
))
2567 * Don't let your children do this ...
2569 __asm__
__volatile__(
2577 regs
->active_tc
.PC
= regs
->CP0_EPC
;
2578 /* I am not sure this is right, but it seems to work
2579 * maybe a problem with nested signals ? */
2584 force_sig(TARGET_SIGSEGV
/*, current*/);
2588 static void setup_rt_frame(int sig
, struct target_sigaction
*ka
,
2589 target_siginfo_t
*info
,
2590 target_sigset_t
*set
, CPUState
*env
)
2592 fprintf(stderr
, "setup_rt_frame: not implemented\n");
2595 long do_rt_sigreturn(CPUState
*env
)
2597 fprintf(stderr
, "do_rt_sigreturn: not implemented\n");
2598 return -TARGET_ENOSYS
;
2601 #elif defined(TARGET_SH4)
2604 * code and data structures from linux kernel:
2605 * include/asm-sh/sigcontext.h
2606 * arch/sh/kernel/signal.c
2609 struct target_sigcontext
{
2610 target_ulong oldmask
;
2613 target_ulong sc_gregs
[16];
2617 target_ulong sc_gbr
;
2618 target_ulong sc_mach
;
2619 target_ulong sc_macl
;
2622 target_ulong sc_fpregs
[16];
2623 target_ulong sc_xfpregs
[16];
2624 unsigned int sc_fpscr
;
2625 unsigned int sc_fpul
;
2626 unsigned int sc_ownedfp
;
2629 struct target_sigframe
2631 struct target_sigcontext sc
;
2632 target_ulong extramask
[TARGET_NSIG_WORDS
-1];
2633 uint16_t retcode
[3];
2637 struct target_ucontext
{
2638 target_ulong uc_flags
;
2639 struct target_ucontext
*uc_link
;
2640 target_stack_t uc_stack
;
2641 struct target_sigcontext uc_mcontext
;
2642 target_sigset_t uc_sigmask
; /* mask last for extensibility */
2645 struct target_rt_sigframe
2647 struct target_siginfo info
;
2648 struct target_ucontext uc
;
2649 uint16_t retcode
[3];
2653 #define MOVW(n) (0x9300|((n)-2)) /* Move mem word at PC+n to R3 */
2654 #define TRAP_NOARG 0xc310 /* Syscall w/no args (NR in R3) SH3/4 */
2656 static abi_ulong
get_sigframe(struct target_sigaction
*ka
,
2657 unsigned long sp
, size_t frame_size
)
2659 if ((ka
->sa_flags
& TARGET_SA_ONSTACK
) && (sas_ss_flags(sp
) == 0)) {
2660 sp
= target_sigaltstack_used
.ss_sp
+ target_sigaltstack_used
.ss_size
;
2663 return (sp
- frame_size
) & -8ul;
2666 static int setup_sigcontext(struct target_sigcontext
*sc
,
2667 CPUState
*regs
, unsigned long mask
)
2671 #define COPY(x) err |= __put_user(regs->x, &sc->sc_##x)
2672 COPY(gregs
[0]); COPY(gregs
[1]);
2673 COPY(gregs
[2]); COPY(gregs
[3]);
2674 COPY(gregs
[4]); COPY(gregs
[5]);
2675 COPY(gregs
[6]); COPY(gregs
[7]);
2676 COPY(gregs
[8]); COPY(gregs
[9]);
2677 COPY(gregs
[10]); COPY(gregs
[11]);
2678 COPY(gregs
[12]); COPY(gregs
[13]);
2679 COPY(gregs
[14]); COPY(gregs
[15]);
2680 COPY(gbr
); COPY(mach
);
2681 COPY(macl
); COPY(pr
);
2685 /* todo: save FPU registers here */
2687 /* non-iBCS2 extensions.. */
2688 err
|= __put_user(mask
, &sc
->oldmask
);
2693 static int restore_sigcontext(struct CPUState
*regs
,
2694 struct target_sigcontext
*sc
)
2696 unsigned int err
= 0;
2698 #define COPY(x) err |= __get_user(regs->x, &sc->sc_##x)
2700 COPY(gregs
[2]); COPY(gregs
[3]);
2701 COPY(gregs
[4]); COPY(gregs
[5]);
2702 COPY(gregs
[6]); COPY(gregs
[7]);
2703 COPY(gregs
[8]); COPY(gregs
[9]);
2704 COPY(gregs
[10]); COPY(gregs
[11]);
2705 COPY(gregs
[12]); COPY(gregs
[13]);
2706 COPY(gregs
[14]); COPY(gregs
[15]);
2707 COPY(gbr
); COPY(mach
);
2708 COPY(macl
); COPY(pr
);
2712 /* todo: restore FPU registers here */
2714 regs
->tra
= -1; /* disable syscall checks */
2718 static void setup_frame(int sig
, struct target_sigaction
*ka
,
2719 target_sigset_t
*set
, CPUState
*regs
)
2721 struct target_sigframe
*frame
;
2722 abi_ulong frame_addr
;
2727 frame_addr
= get_sigframe(ka
, regs
->gregs
[15], sizeof(*frame
));
2728 if (!lock_user_struct(VERIFY_WRITE
, frame
, frame_addr
, 0))
2731 signal
= current_exec_domain_sig(sig
);
2733 err
|= setup_sigcontext(&frame
->sc
, regs
, set
->sig
[0]);
2735 for (i
= 0; i
< TARGET_NSIG_WORDS
- 1; i
++) {
2736 err
|= __put_user(set
->sig
[i
+ 1], &frame
->extramask
[i
]);
2739 /* Set up to return from userspace. If provided, use a stub
2740 already in userspace. */
2741 if (ka
->sa_flags
& TARGET_SA_RESTORER
) {
2742 regs
->pr
= (unsigned long) ka
->sa_restorer
;
2744 /* Generate return code (system call to sigreturn) */
2745 err
|= __put_user(MOVW(2), &frame
->retcode
[0]);
2746 err
|= __put_user(TRAP_NOARG
, &frame
->retcode
[1]);
2747 err
|= __put_user((TARGET_NR_sigreturn
), &frame
->retcode
[2]);
2748 regs
->pr
= (unsigned long) frame
->retcode
;
2754 /* Set up registers for signal handler */
2755 regs
->gregs
[15] = (unsigned long) frame
;
2756 regs
->gregs
[4] = signal
; /* Arg for signal handler */
2758 regs
->gregs
[6] = (unsigned long) &frame
->sc
;
2759 regs
->pc
= (unsigned long) ka
->_sa_handler
;
2761 unlock_user_struct(frame
, frame_addr
, 1);
2765 unlock_user_struct(frame
, frame_addr
, 1);
2769 static void setup_rt_frame(int sig
, struct target_sigaction
*ka
,
2770 target_siginfo_t
*info
,
2771 target_sigset_t
*set
, CPUState
*regs
)
2773 struct target_rt_sigframe
*frame
;
2774 abi_ulong frame_addr
;
2779 frame_addr
= get_sigframe(ka
, regs
->gregs
[15], sizeof(*frame
));
2780 if (!lock_user_struct(VERIFY_WRITE
, frame
, frame_addr
, 0))
2783 signal
= current_exec_domain_sig(sig
);
2785 err
|= copy_siginfo_to_user(&frame
->info
, info
);
2787 /* Create the ucontext. */
2788 err
|= __put_user(0, &frame
->uc
.uc_flags
);
2789 err
|= __put_user(0, (unsigned long *)&frame
->uc
.uc_link
);
2790 err
|= __put_user((unsigned long)target_sigaltstack_used
.ss_sp
,
2791 &frame
->uc
.uc_stack
.ss_sp
);
2792 err
|= __put_user(sas_ss_flags(regs
->gregs
[15]),
2793 &frame
->uc
.uc_stack
.ss_flags
);
2794 err
|= __put_user(target_sigaltstack_used
.ss_size
,
2795 &frame
->uc
.uc_stack
.ss_size
);
2796 err
|= setup_sigcontext(&frame
->uc
.uc_mcontext
,
2798 for(i
= 0; i
< TARGET_NSIG_WORDS
; i
++) {
2799 err
|= __put_user(set
->sig
[i
], &frame
->uc
.uc_sigmask
.sig
[i
]);
2802 /* Set up to return from userspace. If provided, use a stub
2803 already in userspace. */
2804 if (ka
->sa_flags
& TARGET_SA_RESTORER
) {
2805 regs
->pr
= (unsigned long) ka
->sa_restorer
;
2807 /* Generate return code (system call to sigreturn) */
2808 err
|= __put_user(MOVW(2), &frame
->retcode
[0]);
2809 err
|= __put_user(TRAP_NOARG
, &frame
->retcode
[1]);
2810 err
|= __put_user((TARGET_NR_rt_sigreturn
), &frame
->retcode
[2]);
2811 regs
->pr
= (unsigned long) frame
->retcode
;
2817 /* Set up registers for signal handler */
2818 regs
->gregs
[15] = (unsigned long) frame
;
2819 regs
->gregs
[4] = signal
; /* Arg for signal handler */
2820 regs
->gregs
[5] = (unsigned long) &frame
->info
;
2821 regs
->gregs
[6] = (unsigned long) &frame
->uc
;
2822 regs
->pc
= (unsigned long) ka
->_sa_handler
;
2824 unlock_user_struct(frame
, frame_addr
, 1);
2828 unlock_user_struct(frame
, frame_addr
, 1);
2832 long do_sigreturn(CPUState
*regs
)
2834 struct target_sigframe
*frame
;
2835 abi_ulong frame_addr
;
2837 target_sigset_t target_set
;
2841 #if defined(DEBUG_SIGNAL)
2842 fprintf(stderr
, "do_sigreturn\n");
2844 frame_addr
= regs
->gregs
[15];
2845 if (!lock_user_struct(VERIFY_READ
, frame
, frame_addr
, 1))
2848 err
|= __get_user(target_set
.sig
[0], &frame
->sc
.oldmask
);
2849 for(i
= 1; i
< TARGET_NSIG_WORDS
; i
++) {
2850 err
|= (__get_user(target_set
.sig
[i
], &frame
->extramask
[i
- 1]));
2856 target_to_host_sigset_internal(&blocked
, &target_set
);
2857 sigprocmask(SIG_SETMASK
, &blocked
, NULL
);
2859 if (restore_sigcontext(regs
, &frame
->sc
))
2862 unlock_user_struct(frame
, frame_addr
, 0);
2863 return regs
->gregs
[0];
2866 unlock_user_struct(frame
, frame_addr
, 0);
2867 force_sig(TARGET_SIGSEGV
);
2871 long do_rt_sigreturn(CPUState
*regs
)
2873 struct target_rt_sigframe
*frame
;
2874 abi_ulong frame_addr
;
2877 #if defined(DEBUG_SIGNAL)
2878 fprintf(stderr
, "do_rt_sigreturn\n");
2880 frame_addr
= regs
->gregs
[15];
2881 if (!lock_user_struct(VERIFY_READ
, frame
, frame_addr
, 1))
2884 target_to_host_sigset(&blocked
, &frame
->uc
.uc_sigmask
);
2885 sigprocmask(SIG_SETMASK
, &blocked
, NULL
);
2887 if (restore_sigcontext(regs
, &frame
->uc
.uc_mcontext
))
2890 if (do_sigaltstack(frame_addr
+
2891 offsetof(struct target_rt_sigframe
, uc
.uc_stack
),
2892 0, get_sp_from_cpustate(regs
)) == -EFAULT
)
2895 unlock_user_struct(frame
, frame_addr
, 0);
2896 return regs
->gregs
[0];
2899 unlock_user_struct(frame
, frame_addr
, 0);
2900 force_sig(TARGET_SIGSEGV
);
2903 #elif defined(TARGET_CRIS)
2905 struct target_sigcontext
{
2906 struct target_pt_regs regs
; /* needs to be first */
2908 uint32_t usp
; /* usp before stacking this gunk on it */
2911 /* Signal frames. */
2912 struct target_signal_frame
{
2913 struct target_sigcontext sc
;
2914 uint32_t extramask
[TARGET_NSIG_WORDS
- 1];
2915 uint8_t retcode
[8]; /* Trampoline code. */
2918 struct rt_signal_frame
{
2919 struct siginfo
*pinfo
;
2921 struct siginfo info
;
2923 uint8_t retcode
[8]; /* Trampoline code. */
2926 static void setup_sigcontext(struct target_sigcontext
*sc
, CPUState
*env
)
2928 __put_user(env
->regs
[0], &sc
->regs
.r0
);
2929 __put_user(env
->regs
[1], &sc
->regs
.r1
);
2930 __put_user(env
->regs
[2], &sc
->regs
.r2
);
2931 __put_user(env
->regs
[3], &sc
->regs
.r3
);
2932 __put_user(env
->regs
[4], &sc
->regs
.r4
);
2933 __put_user(env
->regs
[5], &sc
->regs
.r5
);
2934 __put_user(env
->regs
[6], &sc
->regs
.r6
);
2935 __put_user(env
->regs
[7], &sc
->regs
.r7
);
2936 __put_user(env
->regs
[8], &sc
->regs
.r8
);
2937 __put_user(env
->regs
[9], &sc
->regs
.r9
);
2938 __put_user(env
->regs
[10], &sc
->regs
.r10
);
2939 __put_user(env
->regs
[11], &sc
->regs
.r11
);
2940 __put_user(env
->regs
[12], &sc
->regs
.r12
);
2941 __put_user(env
->regs
[13], &sc
->regs
.r13
);
2942 __put_user(env
->regs
[14], &sc
->usp
);
2943 __put_user(env
->regs
[15], &sc
->regs
.acr
);
2944 __put_user(env
->pregs
[PR_MOF
], &sc
->regs
.mof
);
2945 __put_user(env
->pregs
[PR_SRP
], &sc
->regs
.srp
);
2946 __put_user(env
->pc
, &sc
->regs
.erp
);
2949 static void restore_sigcontext(struct target_sigcontext
*sc
, CPUState
*env
)
2951 __get_user(env
->regs
[0], &sc
->regs
.r0
);
2952 __get_user(env
->regs
[1], &sc
->regs
.r1
);
2953 __get_user(env
->regs
[2], &sc
->regs
.r2
);
2954 __get_user(env
->regs
[3], &sc
->regs
.r3
);
2955 __get_user(env
->regs
[4], &sc
->regs
.r4
);
2956 __get_user(env
->regs
[5], &sc
->regs
.r5
);
2957 __get_user(env
->regs
[6], &sc
->regs
.r6
);
2958 __get_user(env
->regs
[7], &sc
->regs
.r7
);
2959 __get_user(env
->regs
[8], &sc
->regs
.r8
);
2960 __get_user(env
->regs
[9], &sc
->regs
.r9
);
2961 __get_user(env
->regs
[10], &sc
->regs
.r10
);
2962 __get_user(env
->regs
[11], &sc
->regs
.r11
);
2963 __get_user(env
->regs
[12], &sc
->regs
.r12
);
2964 __get_user(env
->regs
[13], &sc
->regs
.r13
);
2965 __get_user(env
->regs
[14], &sc
->usp
);
2966 __get_user(env
->regs
[15], &sc
->regs
.acr
);
2967 __get_user(env
->pregs
[PR_MOF
], &sc
->regs
.mof
);
2968 __get_user(env
->pregs
[PR_SRP
], &sc
->regs
.srp
);
2969 __get_user(env
->pc
, &sc
->regs
.erp
);
2972 static abi_ulong
get_sigframe(CPUState
*env
, int framesize
)
2975 /* Align the stack downwards to 4. */
2976 sp
= (env
->regs
[R_SP
] & ~3);
2977 return sp
- framesize
;
2980 static void setup_frame(int sig
, struct target_sigaction
*ka
,
2981 target_sigset_t
*set
, CPUState
*env
)
2983 struct target_signal_frame
*frame
;
2984 abi_ulong frame_addr
;
2988 frame_addr
= get_sigframe(env
, sizeof *frame
);
2989 if (!lock_user_struct(VERIFY_WRITE
, frame
, frame_addr
, 0))
2993 * The CRIS signal return trampoline. A real linux/CRIS kernel doesn't
2994 * use this trampoline anymore but it sets it up for GDB.
2995 * In QEMU, using the trampoline simplifies things a bit so we use it.
2997 * This is movu.w __NR_sigreturn, r9; break 13;
2999 err
|= __put_user(0x9c5f, frame
->retcode
+0);
3000 err
|= __put_user(TARGET_NR_sigreturn
,
3002 err
|= __put_user(0xe93d, frame
->retcode
+4);
3004 /* Save the mask. */
3005 err
|= __put_user(set
->sig
[0], &frame
->sc
.oldmask
);
3009 for(i
= 1; i
< TARGET_NSIG_WORDS
; i
++) {
3010 if (__put_user(set
->sig
[i
], &frame
->extramask
[i
- 1]))
3014 setup_sigcontext(&frame
->sc
, env
);
3016 /* Move the stack and setup the arguments for the handler. */
3017 env
->regs
[R_SP
] = (uint32_t) (unsigned long) frame
;
3018 env
->regs
[10] = sig
;
3019 env
->pc
= (unsigned long) ka
->_sa_handler
;
3020 /* Link SRP so the guest returns through the trampoline. */
3021 env
->pregs
[PR_SRP
] = (uint32_t) (unsigned long) &frame
->retcode
[0];
3023 unlock_user_struct(frame
, frame_addr
, 1);
3026 unlock_user_struct(frame
, frame_addr
, 1);
3027 force_sig(TARGET_SIGSEGV
);
3030 static void setup_rt_frame(int sig
, struct target_sigaction
*ka
,
3031 target_siginfo_t
*info
,
3032 target_sigset_t
*set
, CPUState
*env
)
3034 fprintf(stderr
, "CRIS setup_rt_frame: not implemented\n");
3037 long do_sigreturn(CPUState
*env
)
3039 struct target_signal_frame
*frame
;
3040 abi_ulong frame_addr
;
3041 target_sigset_t target_set
;
3045 frame_addr
= env
->regs
[R_SP
];
3046 /* Make sure the guest isn't playing games. */
3047 if (!lock_user_struct(VERIFY_WRITE
, frame
, frame_addr
, 1))
3050 /* Restore blocked signals */
3051 if (__get_user(target_set
.sig
[0], &frame
->sc
.oldmask
))
3053 for(i
= 1; i
< TARGET_NSIG_WORDS
; i
++) {
3054 if (__get_user(target_set
.sig
[i
], &frame
->extramask
[i
- 1]))
3057 target_to_host_sigset_internal(&set
, &target_set
);
3058 sigprocmask(SIG_SETMASK
, &set
, NULL
);
3060 restore_sigcontext(&frame
->sc
, env
);
3061 unlock_user_struct(frame
, frame_addr
, 0);
3062 return env
->regs
[10];
3064 unlock_user_struct(frame
, frame_addr
, 0);
3065 force_sig(TARGET_SIGSEGV
);
3068 long do_rt_sigreturn(CPUState
*env
)
3070 fprintf(stderr
, "CRIS do_rt_sigreturn: not implemented\n");
3071 return -TARGET_ENOSYS
;
3076 static void setup_frame(int sig
, struct target_sigaction
*ka
,
3077 target_sigset_t
*set
, CPUState
*env
)
3079 fprintf(stderr
, "setup_frame: not implemented\n");
3082 static void setup_rt_frame(int sig
, struct target_sigaction
*ka
,
3083 target_siginfo_t
*info
,
3084 target_sigset_t
*set
, CPUState
*env
)
3086 fprintf(stderr
, "setup_rt_frame: not implemented\n");
3089 long do_sigreturn(CPUState
*env
)
3091 fprintf(stderr
, "do_sigreturn: not implemented\n");
3092 return -TARGET_ENOSYS
;
3095 long do_rt_sigreturn(CPUState
*env
)
3097 fprintf(stderr
, "do_rt_sigreturn: not implemented\n");
3098 return -TARGET_ENOSYS
;
3103 void process_pending_signals(CPUState
*cpu_env
)
3107 sigset_t set
, old_set
;
3108 target_sigset_t target_old_set
;
3109 struct emulated_sigtable
*k
;
3110 struct target_sigaction
*sa
;
3112 TaskState
*ts
= cpu_env
->opaque
;
3114 if (!ts
->signal_pending
)
3117 /* FIXME: This is not threadsafe. */
3119 for(sig
= 1; sig
<= TARGET_NSIG
; sig
++) {
3124 /* if no signal is pending, just return */
3125 ts
->signal_pending
= 0;
3130 fprintf(stderr
, "qemu: process signal %d\n", sig
);
3132 /* dequeue signal */
3138 sig
= gdb_handlesig (cpu_env
, sig
);
3141 handler
= TARGET_SIG_IGN
;
3143 sa
= &sigact_table
[sig
- 1];
3144 handler
= sa
->_sa_handler
;
3147 if (handler
== TARGET_SIG_DFL
) {
3148 /* default handler : ignore some signal. The other are job control or fatal */
3149 if (sig
== TARGET_SIGTSTP
|| sig
== TARGET_SIGTTIN
|| sig
== TARGET_SIGTTOU
) {
3150 kill(getpid(),SIGSTOP
);
3151 } else if (sig
!= TARGET_SIGCHLD
&&
3152 sig
!= TARGET_SIGURG
&&
3153 sig
!= TARGET_SIGWINCH
&&
3154 sig
!= TARGET_SIGCONT
) {
3157 } else if (handler
== TARGET_SIG_IGN
) {
3159 } else if (handler
== TARGET_SIG_ERR
) {
3162 /* compute the blocked signals during the handler execution */
3163 target_to_host_sigset(&set
, &sa
->sa_mask
);
3164 /* SA_NODEFER indicates that the current signal should not be
3165 blocked during the handler */
3166 if (!(sa
->sa_flags
& TARGET_SA_NODEFER
))
3167 sigaddset(&set
, target_to_host_signal(sig
));
3169 /* block signals in the handler using Linux */
3170 sigprocmask(SIG_BLOCK
, &set
, &old_set
);
3171 /* save the previous blocked signal state to restore it at the
3172 end of the signal execution (see do_sigreturn) */
3173 host_to_target_sigset_internal(&target_old_set
, &old_set
);
3175 /* if the CPU is in VM86 mode, we restore the 32 bit values */
3176 #if defined(TARGET_I386) && !defined(TARGET_X86_64)
3178 CPUX86State
*env
= cpu_env
;
3179 if (env
->eflags
& VM_MASK
)
3180 save_v86_state(env
);
3183 /* prepare the stack frame of the virtual CPU */
3184 if (sa
->sa_flags
& TARGET_SA_SIGINFO
)
3185 setup_rt_frame(sig
, sa
, &q
->info
, &target_old_set
, cpu_env
);
3187 setup_frame(sig
, sa
, &target_old_set
, cpu_env
);
3188 if (sa
->sa_flags
& TARGET_SA_RESETHAND
)
3189 sa
->_sa_handler
= TARGET_SIG_DFL
;
3192 free_sigqueue(cpu_env
, q
);