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., 675 Mass Ave, Cambridge, MA 02139, USA.
27 #include <sys/ucontext.h>
30 #include "target_signal.h"
32 //#define DEBUG_SIGNAL
34 static struct target_sigaltstack target_sigaltstack_used
= {
37 .ss_flags
= TARGET_SS_DISABLE
,
40 static struct target_sigaction sigact_table
[TARGET_NSIG
];
42 static void host_signal_handler(int host_signum
, siginfo_t
*info
,
45 static uint8_t host_to_target_signal_table
[65] = {
46 [SIGHUP
] = TARGET_SIGHUP
,
47 [SIGINT
] = TARGET_SIGINT
,
48 [SIGQUIT
] = TARGET_SIGQUIT
,
49 [SIGILL
] = TARGET_SIGILL
,
50 [SIGTRAP
] = TARGET_SIGTRAP
,
51 [SIGABRT
] = TARGET_SIGABRT
,
52 /* [SIGIOT] = TARGET_SIGIOT,*/
53 [SIGBUS
] = TARGET_SIGBUS
,
54 [SIGFPE
] = TARGET_SIGFPE
,
55 [SIGKILL
] = TARGET_SIGKILL
,
56 [SIGUSR1
] = TARGET_SIGUSR1
,
57 [SIGSEGV
] = TARGET_SIGSEGV
,
58 [SIGUSR2
] = TARGET_SIGUSR2
,
59 [SIGPIPE
] = TARGET_SIGPIPE
,
60 [SIGALRM
] = TARGET_SIGALRM
,
61 [SIGTERM
] = TARGET_SIGTERM
,
63 [SIGSTKFLT
] = TARGET_SIGSTKFLT
,
65 [SIGCHLD
] = TARGET_SIGCHLD
,
66 [SIGCONT
] = TARGET_SIGCONT
,
67 [SIGSTOP
] = TARGET_SIGSTOP
,
68 [SIGTSTP
] = TARGET_SIGTSTP
,
69 [SIGTTIN
] = TARGET_SIGTTIN
,
70 [SIGTTOU
] = TARGET_SIGTTOU
,
71 [SIGURG
] = TARGET_SIGURG
,
72 [SIGXCPU
] = TARGET_SIGXCPU
,
73 [SIGXFSZ
] = TARGET_SIGXFSZ
,
74 [SIGVTALRM
] = TARGET_SIGVTALRM
,
75 [SIGPROF
] = TARGET_SIGPROF
,
76 [SIGWINCH
] = TARGET_SIGWINCH
,
77 [SIGIO
] = TARGET_SIGIO
,
78 [SIGPWR
] = TARGET_SIGPWR
,
79 [SIGSYS
] = TARGET_SIGSYS
,
80 /* next signals stay the same */
81 /* Nasty hack: Reverse SIGRTMIN and SIGRTMAX to avoid overlap with
82 host libpthread signals. This assumes noone actually uses SIGRTMAX :-/
83 To fix this properly we need to do manual signal delivery multiplexed
84 over a single host signal. */
85 [__SIGRTMIN
] = __SIGRTMAX
,
86 [__SIGRTMAX
] = __SIGRTMIN
,
88 static uint8_t target_to_host_signal_table
[65];
90 static inline int on_sig_stack(unsigned long sp
)
92 return (sp
- target_sigaltstack_used
.ss_sp
93 < target_sigaltstack_used
.ss_size
);
96 static inline int sas_ss_flags(unsigned long sp
)
98 return (target_sigaltstack_used
.ss_size
== 0 ? SS_DISABLE
99 : on_sig_stack(sp
) ? SS_ONSTACK
: 0);
102 static inline int host_to_target_signal(int sig
)
106 return host_to_target_signal_table
[sig
];
109 int target_to_host_signal(int sig
)
113 return target_to_host_signal_table
[sig
];
116 static inline void target_sigemptyset(target_sigset_t
*set
)
118 memset(set
, 0, sizeof(*set
));
121 static inline void target_sigaddset(target_sigset_t
*set
, int signum
)
124 abi_ulong mask
= (abi_ulong
)1 << (signum
% TARGET_NSIG_BPW
);
125 set
->sig
[signum
/ TARGET_NSIG_BPW
] |= mask
;
128 static inline int target_sigismember(const target_sigset_t
*set
, int signum
)
131 abi_ulong mask
= (abi_ulong
)1 << (signum
% TARGET_NSIG_BPW
);
132 return ((set
->sig
[signum
/ TARGET_NSIG_BPW
] & mask
) != 0);
135 static void host_to_target_sigset_internal(target_sigset_t
*d
,
139 target_sigemptyset(d
);
140 for (i
= 1; i
<= TARGET_NSIG
; i
++) {
141 if (sigismember(s
, i
)) {
142 target_sigaddset(d
, host_to_target_signal(i
));
147 void host_to_target_sigset(target_sigset_t
*d
, const sigset_t
*s
)
152 host_to_target_sigset_internal(&d1
, s
);
153 for(i
= 0;i
< TARGET_NSIG_WORDS
; i
++)
154 d
->sig
[i
] = tswapl(d1
.sig
[i
]);
157 static void target_to_host_sigset_internal(sigset_t
*d
,
158 const target_sigset_t
*s
)
162 for (i
= 1; i
<= TARGET_NSIG
; i
++) {
163 if (target_sigismember(s
, i
)) {
164 sigaddset(d
, target_to_host_signal(i
));
169 void target_to_host_sigset(sigset_t
*d
, const target_sigset_t
*s
)
174 for(i
= 0;i
< TARGET_NSIG_WORDS
; i
++)
175 s1
.sig
[i
] = tswapl(s
->sig
[i
]);
176 target_to_host_sigset_internal(d
, &s1
);
179 void host_to_target_old_sigset(abi_ulong
*old_sigset
,
180 const sigset_t
*sigset
)
183 host_to_target_sigset(&d
, sigset
);
184 *old_sigset
= d
.sig
[0];
187 void target_to_host_old_sigset(sigset_t
*sigset
,
188 const abi_ulong
*old_sigset
)
193 d
.sig
[0] = *old_sigset
;
194 for(i
= 1;i
< TARGET_NSIG_WORDS
; i
++)
196 target_to_host_sigset(sigset
, &d
);
199 /* siginfo conversion */
201 static inline void host_to_target_siginfo_noswap(target_siginfo_t
*tinfo
,
202 const siginfo_t
*info
)
205 sig
= host_to_target_signal(info
->si_signo
);
206 tinfo
->si_signo
= sig
;
208 tinfo
->si_code
= info
->si_code
;
209 if (sig
== SIGILL
|| sig
== SIGFPE
|| sig
== SIGSEGV
||
210 sig
== SIGBUS
|| sig
== SIGTRAP
) {
211 /* should never come here, but who knows. The information for
212 the target is irrelevant */
213 tinfo
->_sifields
._sigfault
._addr
= 0;
214 } else if (sig
== SIGIO
) {
215 tinfo
->_sifields
._sigpoll
._fd
= info
->si_fd
;
216 } else if (sig
>= TARGET_SIGRTMIN
) {
217 tinfo
->_sifields
._rt
._pid
= info
->si_pid
;
218 tinfo
->_sifields
._rt
._uid
= info
->si_uid
;
219 /* XXX: potential problem if 64 bit */
220 tinfo
->_sifields
._rt
._sigval
.sival_ptr
=
221 (abi_ulong
)(unsigned long)info
->si_value
.sival_ptr
;
225 static void tswap_siginfo(target_siginfo_t
*tinfo
,
226 const target_siginfo_t
*info
)
229 sig
= info
->si_signo
;
230 tinfo
->si_signo
= tswap32(sig
);
231 tinfo
->si_errno
= tswap32(info
->si_errno
);
232 tinfo
->si_code
= tswap32(info
->si_code
);
233 if (sig
== SIGILL
|| sig
== SIGFPE
|| sig
== SIGSEGV
||
234 sig
== SIGBUS
|| sig
== SIGTRAP
) {
235 tinfo
->_sifields
._sigfault
._addr
=
236 tswapl(info
->_sifields
._sigfault
._addr
);
237 } else if (sig
== SIGIO
) {
238 tinfo
->_sifields
._sigpoll
._fd
= tswap32(info
->_sifields
._sigpoll
._fd
);
239 } else if (sig
>= TARGET_SIGRTMIN
) {
240 tinfo
->_sifields
._rt
._pid
= tswap32(info
->_sifields
._rt
._pid
);
241 tinfo
->_sifields
._rt
._uid
= tswap32(info
->_sifields
._rt
._uid
);
242 tinfo
->_sifields
._rt
._sigval
.sival_ptr
=
243 tswapl(info
->_sifields
._rt
._sigval
.sival_ptr
);
248 void host_to_target_siginfo(target_siginfo_t
*tinfo
, const siginfo_t
*info
)
250 host_to_target_siginfo_noswap(tinfo
, info
);
251 tswap_siginfo(tinfo
, tinfo
);
254 /* XXX: we support only POSIX RT signals are used. */
255 /* XXX: find a solution for 64 bit (additional malloced data is needed) */
256 void target_to_host_siginfo(siginfo_t
*info
, const target_siginfo_t
*tinfo
)
258 info
->si_signo
= tswap32(tinfo
->si_signo
);
259 info
->si_errno
= tswap32(tinfo
->si_errno
);
260 info
->si_code
= tswap32(tinfo
->si_code
);
261 info
->si_pid
= tswap32(tinfo
->_sifields
._rt
._pid
);
262 info
->si_uid
= tswap32(tinfo
->_sifields
._rt
._uid
);
263 info
->si_value
.sival_ptr
=
264 (void *)(long)tswapl(tinfo
->_sifields
._rt
._sigval
.sival_ptr
);
267 static int fatal_signal (int sig
)
272 case TARGET_SIGWINCH
:
273 /* Ignored by default. */
280 /* Job control signals. */
287 void signal_init(void)
289 struct sigaction act
;
290 struct sigaction oact
;
294 /* generate signal conversion tables */
295 for(i
= 1; i
<= 64; i
++) {
296 if (host_to_target_signal_table
[i
] == 0)
297 host_to_target_signal_table
[i
] = i
;
299 for(i
= 1; i
<= 64; i
++) {
300 j
= host_to_target_signal_table
[i
];
301 target_to_host_signal_table
[j
] = i
;
304 /* set all host signal handlers. ALL signals are blocked during
305 the handlers to serialize them. */
306 memset(sigact_table
, 0, sizeof(sigact_table
));
308 sigfillset(&act
.sa_mask
);
309 act
.sa_flags
= SA_SIGINFO
;
310 act
.sa_sigaction
= host_signal_handler
;
311 for(i
= 1; i
<= TARGET_NSIG
; i
++) {
312 host_sig
= target_to_host_signal(i
);
313 sigaction(host_sig
, NULL
, &oact
);
314 if (oact
.sa_sigaction
== (void *)SIG_IGN
) {
315 sigact_table
[i
- 1]._sa_handler
= TARGET_SIG_IGN
;
316 } else if (oact
.sa_sigaction
== (void *)SIG_DFL
) {
317 sigact_table
[i
- 1]._sa_handler
= TARGET_SIG_DFL
;
319 /* If there's already a handler installed then something has
320 gone horribly wrong, so don't even try to handle that case. */
321 /* Install some handlers for our own use. We need at least
322 SIGSEGV and SIGBUS, to detect exceptions. We can not just
323 trap all signals because it affects syscall interrupt
324 behavior. But do trap all default-fatal signals. */
325 if (fatal_signal (i
))
326 sigaction(host_sig
, &act
, NULL
);
330 /* signal queue handling */
332 static inline struct sigqueue
*alloc_sigqueue(CPUState
*env
)
334 TaskState
*ts
= env
->opaque
;
335 struct sigqueue
*q
= ts
->first_free
;
338 ts
->first_free
= q
->next
;
342 static inline void free_sigqueue(CPUState
*env
, struct sigqueue
*q
)
344 TaskState
*ts
= env
->opaque
;
345 q
->next
= ts
->first_free
;
349 /* abort execution with signal */
350 static void __attribute((noreturn
)) force_sig(int sig
)
353 host_sig
= target_to_host_signal(sig
);
354 fprintf(stderr
, "qemu: uncaught target signal %d (%s) - exiting\n",
355 sig
, strsignal(host_sig
));
357 gdb_signalled(thread_env
, sig
);
361 struct sigaction act
;
362 sigemptyset(&act
.sa_mask
);
363 act
.sa_flags
= SA_SIGINFO
;
364 act
.sa_sigaction
= SIG_DFL
;
365 sigaction(SIGABRT
, &act
, NULL
);
371 /* queue a signal so that it will be send to the virtual CPU as soon
373 int queue_signal(CPUState
*env
, int sig
, target_siginfo_t
*info
)
375 TaskState
*ts
= env
->opaque
;
376 struct emulated_sigtable
*k
;
377 struct sigqueue
*q
, **pq
;
381 #if defined(DEBUG_SIGNAL)
382 fprintf(stderr
, "queue_signal: sig=%d\n",
385 k
= &ts
->sigtab
[sig
- 1];
386 queue
= gdb_queuesig ();
387 handler
= sigact_table
[sig
- 1]._sa_handler
;
388 if (!queue
&& handler
== TARGET_SIG_DFL
) {
389 if (sig
== TARGET_SIGTSTP
|| sig
== TARGET_SIGTTIN
|| sig
== TARGET_SIGTTOU
) {
390 kill(getpid(),SIGSTOP
);
393 /* default handler : ignore some signal. The other are fatal */
394 if (sig
!= TARGET_SIGCHLD
&&
395 sig
!= TARGET_SIGURG
&&
396 sig
!= TARGET_SIGWINCH
&&
397 sig
!= TARGET_SIGCONT
) {
400 return 0; /* indicate ignored */
402 } else if (!queue
&& handler
== TARGET_SIG_IGN
) {
405 } else if (!queue
&& handler
== TARGET_SIG_ERR
) {
409 if (sig
< TARGET_SIGRTMIN
) {
410 /* if non real time signal, we queue exactly one signal */
420 q
= alloc_sigqueue(env
);
431 /* signal that a new signal is pending */
432 ts
->signal_pending
= 1;
433 return 1; /* indicates that the signal was queued */
437 static void host_signal_handler(int host_signum
, siginfo_t
*info
,
441 target_siginfo_t tinfo
;
443 /* the CPU emulator uses some host signals to detect exceptions,
444 we forward to it some signals */
445 if ((host_signum
== SIGSEGV
|| host_signum
== SIGBUS
)
446 && info
->si_code
> 0) {
447 if (cpu_signal_handler(host_signum
, info
, puc
))
451 /* get target signal number */
452 sig
= host_to_target_signal(host_signum
);
453 if (sig
< 1 || sig
> TARGET_NSIG
)
455 #if defined(DEBUG_SIGNAL)
456 fprintf(stderr
, "qemu: got signal %d\n", sig
);
458 host_to_target_siginfo_noswap(&tinfo
, info
);
459 if (queue_signal(thread_env
, sig
, &tinfo
) == 1) {
460 /* interrupt the virtual CPU as soon as possible */
461 cpu_interrupt(thread_env
, CPU_INTERRUPT_EXIT
);
465 /* do_sigaltstack() returns target values and errnos. */
466 /* compare linux/kernel/signal.c:do_sigaltstack() */
467 abi_long
do_sigaltstack(abi_ulong uss_addr
, abi_ulong uoss_addr
, abi_ulong sp
)
470 struct target_sigaltstack oss
;
472 /* XXX: test errors */
475 __put_user(target_sigaltstack_used
.ss_sp
, &oss
.ss_sp
);
476 __put_user(target_sigaltstack_used
.ss_size
, &oss
.ss_size
);
477 __put_user(sas_ss_flags(sp
), &oss
.ss_flags
);
482 struct target_sigaltstack
*uss
;
483 struct target_sigaltstack ss
;
485 ret
= -TARGET_EFAULT
;
486 if (!lock_user_struct(VERIFY_READ
, uss
, uss_addr
, 1)
487 || __get_user(ss
.ss_sp
, &uss
->ss_sp
)
488 || __get_user(ss
.ss_size
, &uss
->ss_size
)
489 || __get_user(ss
.ss_flags
, &uss
->ss_flags
))
491 unlock_user_struct(uss
, uss_addr
, 0);
494 if (on_sig_stack(sp
))
497 ret
= -TARGET_EINVAL
;
498 if (ss
.ss_flags
!= TARGET_SS_DISABLE
499 && ss
.ss_flags
!= TARGET_SS_ONSTACK
503 if (ss
.ss_flags
== TARGET_SS_DISABLE
) {
507 ret
= -TARGET_ENOMEM
;
508 if (ss
.ss_size
< MINSIGSTKSZ
)
512 target_sigaltstack_used
.ss_sp
= ss
.ss_sp
;
513 target_sigaltstack_used
.ss_size
= ss
.ss_size
;
517 ret
= -TARGET_EFAULT
;
518 if (copy_to_user(uoss_addr
, &oss
, sizeof(oss
)))
527 /* do_sigaction() return host values and errnos */
528 int do_sigaction(int sig
, const struct target_sigaction
*act
,
529 struct target_sigaction
*oact
)
531 struct target_sigaction
*k
;
532 struct sigaction act1
;
536 if (sig
< 1 || sig
> TARGET_NSIG
|| sig
== TARGET_SIGKILL
|| sig
== TARGET_SIGSTOP
)
538 k
= &sigact_table
[sig
- 1];
539 #if defined(DEBUG_SIGNAL)
540 fprintf(stderr
, "sigaction sig=%d act=0x%08x, oact=0x%08x\n",
541 sig
, (int)act
, (int)oact
);
544 oact
->_sa_handler
= tswapl(k
->_sa_handler
);
545 oact
->sa_flags
= tswapl(k
->sa_flags
);
546 #if !defined(TARGET_MIPS)
547 oact
->sa_restorer
= tswapl(k
->sa_restorer
);
549 oact
->sa_mask
= k
->sa_mask
;
552 /* FIXME: This is not threadsafe. */
553 k
->_sa_handler
= tswapl(act
->_sa_handler
);
554 k
->sa_flags
= tswapl(act
->sa_flags
);
555 #if !defined(TARGET_MIPS)
556 k
->sa_restorer
= tswapl(act
->sa_restorer
);
558 k
->sa_mask
= act
->sa_mask
;
560 /* we update the host linux signal state */
561 host_sig
= target_to_host_signal(sig
);
562 if (host_sig
!= SIGSEGV
&& host_sig
!= SIGBUS
) {
563 sigfillset(&act1
.sa_mask
);
564 act1
.sa_flags
= SA_SIGINFO
;
565 if (k
->sa_flags
& TARGET_SA_RESTART
)
566 act1
.sa_flags
|= SA_RESTART
;
567 /* NOTE: it is important to update the host kernel signal
568 ignore state to avoid getting unexpected interrupted
570 if (k
->_sa_handler
== TARGET_SIG_IGN
) {
571 act1
.sa_sigaction
= (void *)SIG_IGN
;
572 } else if (k
->_sa_handler
== TARGET_SIG_DFL
) {
573 if (fatal_signal (sig
))
574 act1
.sa_sigaction
= host_signal_handler
;
576 act1
.sa_sigaction
= (void *)SIG_DFL
;
578 act1
.sa_sigaction
= host_signal_handler
;
580 ret
= sigaction(host_sig
, &act1
, NULL
);
586 static inline int copy_siginfo_to_user(target_siginfo_t
*tinfo
,
587 const target_siginfo_t
*info
)
589 tswap_siginfo(tinfo
, info
);
593 static inline int current_exec_domain_sig(int sig
)
595 return /* current->exec_domain && current->exec_domain->signal_invmap
596 && sig < 32 ? current->exec_domain->signal_invmap[sig] : */ sig
;
599 #if defined(TARGET_I386) && TARGET_ABI_BITS == 32
601 /* from the Linux kernel */
603 struct target_fpreg
{
604 uint16_t significand
[4];
608 struct target_fpxreg
{
609 uint16_t significand
[4];
614 struct target_xmmreg
{
615 abi_ulong element
[4];
618 struct target_fpstate
{
619 /* Regular FPU environment */
627 struct target_fpreg _st
[8];
629 uint16_t magic
; /* 0xffff = regular FPU data only */
631 /* FXSR FPU environment */
632 abi_ulong _fxsr_env
[6]; /* FXSR FPU env is ignored */
635 struct target_fpxreg _fxsr_st
[8]; /* FXSR FPU reg data is ignored */
636 struct target_xmmreg _xmm
[8];
637 abi_ulong padding
[56];
640 #define X86_FXSR_MAGIC 0x0000
642 struct target_sigcontext
{
660 abi_ulong esp_at_signal
;
662 abi_ulong fpstate
; /* pointer */
667 struct target_ucontext
{
670 target_stack_t tuc_stack
;
671 struct target_sigcontext tuc_mcontext
;
672 target_sigset_t tuc_sigmask
; /* mask last for extensibility */
679 struct target_sigcontext sc
;
680 struct target_fpstate fpstate
;
681 abi_ulong extramask
[TARGET_NSIG_WORDS
-1];
691 struct target_siginfo info
;
692 struct target_ucontext uc
;
693 struct target_fpstate fpstate
;
698 * Set up a signal frame.
701 /* XXX: save x87 state */
703 setup_sigcontext(struct target_sigcontext
*sc
, struct target_fpstate
*fpstate
,
704 CPUX86State
*env
, abi_ulong mask
, abi_ulong fpstate_addr
)
709 /* already locked in setup_frame() */
710 err
|= __put_user(env
->segs
[R_GS
].selector
, (unsigned int *)&sc
->gs
);
711 err
|= __put_user(env
->segs
[R_FS
].selector
, (unsigned int *)&sc
->fs
);
712 err
|= __put_user(env
->segs
[R_ES
].selector
, (unsigned int *)&sc
->es
);
713 err
|= __put_user(env
->segs
[R_DS
].selector
, (unsigned int *)&sc
->ds
);
714 err
|= __put_user(env
->regs
[R_EDI
], &sc
->edi
);
715 err
|= __put_user(env
->regs
[R_ESI
], &sc
->esi
);
716 err
|= __put_user(env
->regs
[R_EBP
], &sc
->ebp
);
717 err
|= __put_user(env
->regs
[R_ESP
], &sc
->esp
);
718 err
|= __put_user(env
->regs
[R_EBX
], &sc
->ebx
);
719 err
|= __put_user(env
->regs
[R_EDX
], &sc
->edx
);
720 err
|= __put_user(env
->regs
[R_ECX
], &sc
->ecx
);
721 err
|= __put_user(env
->regs
[R_EAX
], &sc
->eax
);
722 err
|= __put_user(env
->exception_index
, &sc
->trapno
);
723 err
|= __put_user(env
->error_code
, &sc
->err
);
724 err
|= __put_user(env
->eip
, &sc
->eip
);
725 err
|= __put_user(env
->segs
[R_CS
].selector
, (unsigned int *)&sc
->cs
);
726 err
|= __put_user(env
->eflags
, &sc
->eflags
);
727 err
|= __put_user(env
->regs
[R_ESP
], &sc
->esp_at_signal
);
728 err
|= __put_user(env
->segs
[R_SS
].selector
, (unsigned int *)&sc
->ss
);
730 cpu_x86_fsave(env
, fpstate_addr
, 1);
731 fpstate
->status
= fpstate
->sw
;
733 err
|= __put_user(magic
, &fpstate
->magic
);
734 err
|= __put_user(fpstate_addr
, &sc
->fpstate
);
736 /* non-iBCS2 extensions.. */
737 err
|= __put_user(mask
, &sc
->oldmask
);
738 err
|= __put_user(env
->cr
[2], &sc
->cr2
);
743 * Determine which stack to use..
746 static inline abi_ulong
747 get_sigframe(struct target_sigaction
*ka
, CPUX86State
*env
, size_t frame_size
)
751 /* Default to using normal stack */
752 esp
= env
->regs
[R_ESP
];
753 /* This is the X/Open sanctioned signal stack switching. */
754 if (ka
->sa_flags
& TARGET_SA_ONSTACK
) {
755 if (sas_ss_flags(esp
) == 0)
756 esp
= target_sigaltstack_used
.ss_sp
+ target_sigaltstack_used
.ss_size
;
759 /* This is the legacy signal stack switching. */
761 if ((env
->segs
[R_SS
].selector
& 0xffff) != __USER_DS
&&
762 !(ka
->sa_flags
& TARGET_SA_RESTORER
) &&
764 esp
= (unsigned long) ka
->sa_restorer
;
766 return (esp
- frame_size
) & -8ul;
769 /* compare linux/arch/i386/kernel/signal.c:setup_frame() */
770 static void setup_frame(int sig
, struct target_sigaction
*ka
,
771 target_sigset_t
*set
, CPUX86State
*env
)
773 abi_ulong frame_addr
;
774 struct sigframe
*frame
;
777 frame_addr
= get_sigframe(ka
, env
, sizeof(*frame
));
779 if (!lock_user_struct(VERIFY_WRITE
, frame
, frame_addr
, 0))
782 err
|= __put_user(current_exec_domain_sig(sig
),
787 setup_sigcontext(&frame
->sc
, &frame
->fpstate
, env
, set
->sig
[0],
788 frame_addr
+ offsetof(struct sigframe
, fpstate
));
792 for(i
= 1; i
< TARGET_NSIG_WORDS
; i
++) {
793 if (__put_user(set
->sig
[i
], &frame
->extramask
[i
- 1]))
797 /* Set up to return from userspace. If provided, use a stub
798 already in userspace. */
799 if (ka
->sa_flags
& TARGET_SA_RESTORER
) {
800 err
|= __put_user(ka
->sa_restorer
, &frame
->pretcode
);
803 abi_ulong retcode_addr
;
804 retcode_addr
= frame_addr
+ offsetof(struct sigframe
, retcode
);
805 err
|= __put_user(retcode_addr
, &frame
->pretcode
);
806 /* This is popl %eax ; movl $,%eax ; int $0x80 */
808 err
|= __put_user(val16
, (uint16_t *)(frame
->retcode
+0));
809 err
|= __put_user(TARGET_NR_sigreturn
, (int *)(frame
->retcode
+2));
811 err
|= __put_user(val16
, (uint16_t *)(frame
->retcode
+6));
817 /* Set up registers for signal handler */
818 env
->regs
[R_ESP
] = frame_addr
;
819 env
->eip
= ka
->_sa_handler
;
821 cpu_x86_load_seg(env
, R_DS
, __USER_DS
);
822 cpu_x86_load_seg(env
, R_ES
, __USER_DS
);
823 cpu_x86_load_seg(env
, R_SS
, __USER_DS
);
824 cpu_x86_load_seg(env
, R_CS
, __USER_CS
);
825 env
->eflags
&= ~TF_MASK
;
827 unlock_user_struct(frame
, frame_addr
, 1);
832 unlock_user_struct(frame
, frame_addr
, 1);
833 if (sig
== TARGET_SIGSEGV
)
834 ka
->_sa_handler
= TARGET_SIG_DFL
;
835 force_sig(TARGET_SIGSEGV
/* , current */);
838 /* compare linux/arch/i386/kernel/signal.c:setup_rt_frame() */
839 static void setup_rt_frame(int sig
, struct target_sigaction
*ka
,
840 target_siginfo_t
*info
,
841 target_sigset_t
*set
, CPUX86State
*env
)
843 abi_ulong frame_addr
, addr
;
844 struct rt_sigframe
*frame
;
847 frame_addr
= get_sigframe(ka
, env
, sizeof(*frame
));
849 if (!lock_user_struct(VERIFY_WRITE
, frame
, frame_addr
, 0))
852 err
|= __put_user(current_exec_domain_sig(sig
),
854 addr
= frame_addr
+ offsetof(struct rt_sigframe
, info
);
855 err
|= __put_user(addr
, &frame
->pinfo
);
856 addr
= frame_addr
+ offsetof(struct rt_sigframe
, uc
);
857 err
|= __put_user(addr
, &frame
->puc
);
858 err
|= copy_siginfo_to_user(&frame
->info
, info
);
862 /* Create the ucontext. */
863 err
|= __put_user(0, &frame
->uc
.tuc_flags
);
864 err
|= __put_user(0, &frame
->uc
.tuc_link
);
865 err
|= __put_user(target_sigaltstack_used
.ss_sp
,
866 &frame
->uc
.tuc_stack
.ss_sp
);
867 err
|= __put_user(sas_ss_flags(get_sp_from_cpustate(env
)),
868 &frame
->uc
.tuc_stack
.ss_flags
);
869 err
|= __put_user(target_sigaltstack_used
.ss_size
,
870 &frame
->uc
.tuc_stack
.ss_size
);
871 err
|= setup_sigcontext(&frame
->uc
.tuc_mcontext
, &frame
->fpstate
,
873 frame_addr
+ offsetof(struct rt_sigframe
, fpstate
));
874 for(i
= 0; i
< TARGET_NSIG_WORDS
; i
++) {
875 if (__put_user(set
->sig
[i
], &frame
->uc
.tuc_sigmask
.sig
[i
]))
879 /* Set up to return from userspace. If provided, use a stub
880 already in userspace. */
881 if (ka
->sa_flags
& TARGET_SA_RESTORER
) {
882 err
|= __put_user(ka
->sa_restorer
, &frame
->pretcode
);
885 addr
= frame_addr
+ offsetof(struct rt_sigframe
, retcode
);
886 err
|= __put_user(addr
, &frame
->pretcode
);
887 /* This is movl $,%eax ; int $0x80 */
888 err
|= __put_user(0xb8, (char *)(frame
->retcode
+0));
889 err
|= __put_user(TARGET_NR_rt_sigreturn
, (int *)(frame
->retcode
+1));
891 err
|= __put_user(val16
, (uint16_t *)(frame
->retcode
+5));
897 /* Set up registers for signal handler */
898 env
->regs
[R_ESP
] = frame_addr
;
899 env
->eip
= ka
->_sa_handler
;
901 cpu_x86_load_seg(env
, R_DS
, __USER_DS
);
902 cpu_x86_load_seg(env
, R_ES
, __USER_DS
);
903 cpu_x86_load_seg(env
, R_SS
, __USER_DS
);
904 cpu_x86_load_seg(env
, R_CS
, __USER_CS
);
905 env
->eflags
&= ~TF_MASK
;
907 unlock_user_struct(frame
, frame_addr
, 1);
912 unlock_user_struct(frame
, frame_addr
, 1);
913 if (sig
== TARGET_SIGSEGV
)
914 ka
->_sa_handler
= TARGET_SIG_DFL
;
915 force_sig(TARGET_SIGSEGV
/* , current */);
919 restore_sigcontext(CPUX86State
*env
, struct target_sigcontext
*sc
, int *peax
)
921 unsigned int err
= 0;
922 abi_ulong fpstate_addr
;
923 unsigned int tmpflags
;
925 cpu_x86_load_seg(env
, R_GS
, tswap16(sc
->gs
));
926 cpu_x86_load_seg(env
, R_FS
, tswap16(sc
->fs
));
927 cpu_x86_load_seg(env
, R_ES
, tswap16(sc
->es
));
928 cpu_x86_load_seg(env
, R_DS
, tswap16(sc
->ds
));
930 env
->regs
[R_EDI
] = tswapl(sc
->edi
);
931 env
->regs
[R_ESI
] = tswapl(sc
->esi
);
932 env
->regs
[R_EBP
] = tswapl(sc
->ebp
);
933 env
->regs
[R_ESP
] = tswapl(sc
->esp
);
934 env
->regs
[R_EBX
] = tswapl(sc
->ebx
);
935 env
->regs
[R_EDX
] = tswapl(sc
->edx
);
936 env
->regs
[R_ECX
] = tswapl(sc
->ecx
);
937 env
->eip
= tswapl(sc
->eip
);
939 cpu_x86_load_seg(env
, R_CS
, lduw(&sc
->cs
) | 3);
940 cpu_x86_load_seg(env
, R_SS
, lduw(&sc
->ss
) | 3);
942 tmpflags
= tswapl(sc
->eflags
);
943 env
->eflags
= (env
->eflags
& ~0x40DD5) | (tmpflags
& 0x40DD5);
944 // regs->orig_eax = -1; /* disable syscall checks */
946 fpstate_addr
= tswapl(sc
->fpstate
);
947 if (fpstate_addr
!= 0) {
948 if (!access_ok(VERIFY_READ
, fpstate_addr
,
949 sizeof(struct target_fpstate
)))
951 cpu_x86_frstor(env
, fpstate_addr
, 1);
954 *peax
= tswapl(sc
->eax
);
960 long do_sigreturn(CPUX86State
*env
)
962 struct sigframe
*frame
;
963 abi_ulong frame_addr
= env
->regs
[R_ESP
] - 8;
964 target_sigset_t target_set
;
968 #if defined(DEBUG_SIGNAL)
969 fprintf(stderr
, "do_sigreturn\n");
971 if (!lock_user_struct(VERIFY_READ
, frame
, frame_addr
, 1))
973 /* set blocked signals */
974 if (__get_user(target_set
.sig
[0], &frame
->sc
.oldmask
))
976 for(i
= 1; i
< TARGET_NSIG_WORDS
; i
++) {
977 if (__get_user(target_set
.sig
[i
], &frame
->extramask
[i
- 1]))
981 target_to_host_sigset_internal(&set
, &target_set
);
982 sigprocmask(SIG_SETMASK
, &set
, NULL
);
984 /* restore registers */
985 if (restore_sigcontext(env
, &frame
->sc
, &eax
))
987 unlock_user_struct(frame
, frame_addr
, 0);
991 unlock_user_struct(frame
, frame_addr
, 0);
992 force_sig(TARGET_SIGSEGV
);
996 long do_rt_sigreturn(CPUX86State
*env
)
998 abi_ulong frame_addr
;
999 struct rt_sigframe
*frame
;
1003 frame_addr
= env
->regs
[R_ESP
] - 4;
1004 if (!lock_user_struct(VERIFY_READ
, frame
, frame_addr
, 1))
1006 target_to_host_sigset(&set
, &frame
->uc
.tuc_sigmask
);
1007 sigprocmask(SIG_SETMASK
, &set
, NULL
);
1009 if (restore_sigcontext(env
, &frame
->uc
.tuc_mcontext
, &eax
))
1012 if (do_sigaltstack(frame_addr
+ offsetof(struct rt_sigframe
, uc
.tuc_stack
), 0,
1013 get_sp_from_cpustate(env
)) == -EFAULT
)
1016 unlock_user_struct(frame
, frame_addr
, 0);
1020 unlock_user_struct(frame
, frame_addr
, 0);
1021 force_sig(TARGET_SIGSEGV
);
1025 #elif defined(TARGET_ARM)
1027 struct target_sigcontext
{
1029 abi_ulong error_code
;
1048 abi_ulong fault_address
;
1051 struct target_ucontext_v1
{
1052 abi_ulong tuc_flags
;
1054 target_stack_t tuc_stack
;
1055 struct target_sigcontext tuc_mcontext
;
1056 target_sigset_t tuc_sigmask
; /* mask last for extensibility */
1059 struct target_ucontext_v2
{
1060 abi_ulong tuc_flags
;
1062 target_stack_t tuc_stack
;
1063 struct target_sigcontext tuc_mcontext
;
1064 target_sigset_t tuc_sigmask
; /* mask last for extensibility */
1065 char __unused
[128 - sizeof(sigset_t
)];
1066 abi_ulong tuc_regspace
[128] __attribute__((__aligned__(8)));
1071 struct target_sigcontext sc
;
1072 abi_ulong extramask
[TARGET_NSIG_WORDS
-1];
1078 struct target_ucontext_v2 uc
;
1082 struct rt_sigframe_v1
1086 struct target_siginfo info
;
1087 struct target_ucontext_v1 uc
;
1091 struct rt_sigframe_v2
1093 struct target_siginfo info
;
1094 struct target_ucontext_v2 uc
;
1098 #define TARGET_CONFIG_CPU_32 1
1101 * For ARM syscalls, we encode the syscall number into the instruction.
1103 #define SWI_SYS_SIGRETURN (0xef000000|(TARGET_NR_sigreturn + ARM_SYSCALL_BASE))
1104 #define SWI_SYS_RT_SIGRETURN (0xef000000|(TARGET_NR_rt_sigreturn + ARM_SYSCALL_BASE))
1107 * For Thumb syscalls, we pass the syscall number via r7. We therefore
1108 * need two 16-bit instructions.
1110 #define SWI_THUMB_SIGRETURN (0xdf00 << 16 | 0x2700 | (TARGET_NR_sigreturn))
1111 #define SWI_THUMB_RT_SIGRETURN (0xdf00 << 16 | 0x2700 | (TARGET_NR_rt_sigreturn))
1113 static const abi_ulong retcodes
[4] = {
1114 SWI_SYS_SIGRETURN
, SWI_THUMB_SIGRETURN
,
1115 SWI_SYS_RT_SIGRETURN
, SWI_THUMB_RT_SIGRETURN
1119 #define __get_user_error(x,p,e) __get_user(x, p)
1121 static inline int valid_user_regs(CPUState
*regs
)
1127 setup_sigcontext(struct target_sigcontext
*sc
, /*struct _fpstate *fpstate,*/
1128 CPUState
*env
, abi_ulong mask
)
1130 __put_user(env
->regs
[0], &sc
->arm_r0
);
1131 __put_user(env
->regs
[1], &sc
->arm_r1
);
1132 __put_user(env
->regs
[2], &sc
->arm_r2
);
1133 __put_user(env
->regs
[3], &sc
->arm_r3
);
1134 __put_user(env
->regs
[4], &sc
->arm_r4
);
1135 __put_user(env
->regs
[5], &sc
->arm_r5
);
1136 __put_user(env
->regs
[6], &sc
->arm_r6
);
1137 __put_user(env
->regs
[7], &sc
->arm_r7
);
1138 __put_user(env
->regs
[8], &sc
->arm_r8
);
1139 __put_user(env
->regs
[9], &sc
->arm_r9
);
1140 __put_user(env
->regs
[10], &sc
->arm_r10
);
1141 __put_user(env
->regs
[11], &sc
->arm_fp
);
1142 __put_user(env
->regs
[12], &sc
->arm_ip
);
1143 __put_user(env
->regs
[13], &sc
->arm_sp
);
1144 __put_user(env
->regs
[14], &sc
->arm_lr
);
1145 __put_user(env
->regs
[15], &sc
->arm_pc
);
1146 #ifdef TARGET_CONFIG_CPU_32
1147 __put_user(cpsr_read(env
), &sc
->arm_cpsr
);
1150 __put_user(/* current->thread.trap_no */ 0, &sc
->trap_no
);
1151 __put_user(/* current->thread.error_code */ 0, &sc
->error_code
);
1152 __put_user(/* current->thread.address */ 0, &sc
->fault_address
);
1153 __put_user(mask
, &sc
->oldmask
);
1156 static inline abi_ulong
1157 get_sigframe(struct target_sigaction
*ka
, CPUState
*regs
, int framesize
)
1159 unsigned long sp
= regs
->regs
[13];
1162 * This is the X/Open sanctioned signal stack switching.
1164 if ((ka
->sa_flags
& TARGET_SA_ONSTACK
) && !sas_ss_flags(sp
))
1165 sp
= target_sigaltstack_used
.ss_sp
+ target_sigaltstack_used
.ss_size
;
1167 * ATPCS B01 mandates 8-byte alignment
1169 return (sp
- framesize
) & ~7;
1173 setup_return(CPUState
*env
, struct target_sigaction
*ka
,
1174 abi_ulong
*rc
, abi_ulong frame_addr
, int usig
, abi_ulong rc_addr
)
1176 abi_ulong handler
= ka
->_sa_handler
;
1178 int thumb
= handler
& 1;
1180 if (ka
->sa_flags
& TARGET_SA_RESTORER
) {
1181 retcode
= ka
->sa_restorer
;
1183 unsigned int idx
= thumb
;
1185 if (ka
->sa_flags
& TARGET_SA_SIGINFO
)
1188 if (__put_user(retcodes
[idx
], rc
))
1191 flush_icache_range((abi_ulong
)rc
,
1192 (abi_ulong
)(rc
+ 1));
1194 retcode
= rc_addr
+ thumb
;
1197 env
->regs
[0] = usig
;
1198 env
->regs
[13] = frame_addr
;
1199 env
->regs
[14] = retcode
;
1200 env
->regs
[15] = handler
& (thumb
? ~1 : ~3);
1204 #ifdef TARGET_CONFIG_CPU_32
1212 static void setup_sigframe_v2(struct target_ucontext_v2
*uc
,
1213 target_sigset_t
*set
, CPUState
*env
)
1215 struct target_sigaltstack stack
;
1218 /* Clear all the bits of the ucontext we don't use. */
1219 memset(uc
, 0, offsetof(struct target_ucontext_v2
, tuc_mcontext
));
1221 memset(&stack
, 0, sizeof(stack
));
1222 __put_user(target_sigaltstack_used
.ss_sp
, &stack
.ss_sp
);
1223 __put_user(target_sigaltstack_used
.ss_size
, &stack
.ss_size
);
1224 __put_user(sas_ss_flags(get_sp_from_cpustate(env
)), &stack
.ss_flags
);
1225 memcpy(&uc
->tuc_stack
, &stack
, sizeof(stack
));
1227 setup_sigcontext(&uc
->tuc_mcontext
, env
, set
->sig
[0]);
1228 /* FIXME: Save coprocessor signal frame. */
1229 for(i
= 0; i
< TARGET_NSIG_WORDS
; i
++) {
1230 __put_user(set
->sig
[i
], &uc
->tuc_sigmask
.sig
[i
]);
1234 /* compare linux/arch/arm/kernel/signal.c:setup_frame() */
1235 static void setup_frame_v1(int usig
, struct target_sigaction
*ka
,
1236 target_sigset_t
*set
, CPUState
*regs
)
1238 struct sigframe_v1
*frame
;
1239 abi_ulong frame_addr
= get_sigframe(ka
, regs
, sizeof(*frame
));
1242 if (!lock_user_struct(VERIFY_WRITE
, frame
, frame_addr
, 0))
1245 setup_sigcontext(&frame
->sc
, regs
, set
->sig
[0]);
1247 for(i
= 1; i
< TARGET_NSIG_WORDS
; i
++) {
1248 if (__put_user(set
->sig
[i
], &frame
->extramask
[i
- 1]))
1252 setup_return(regs
, ka
, &frame
->retcode
, frame_addr
, usig
,
1253 frame_addr
+ offsetof(struct sigframe_v1
, retcode
));
1256 unlock_user_struct(frame
, frame_addr
, 1);
1259 static void setup_frame_v2(int usig
, struct target_sigaction
*ka
,
1260 target_sigset_t
*set
, CPUState
*regs
)
1262 struct sigframe_v2
*frame
;
1263 abi_ulong frame_addr
= get_sigframe(ka
, regs
, sizeof(*frame
));
1265 if (!lock_user_struct(VERIFY_WRITE
, frame
, frame_addr
, 0))
1268 setup_sigframe_v2(&frame
->uc
, set
, regs
);
1270 setup_return(regs
, ka
, &frame
->retcode
, frame_addr
, usig
,
1271 frame_addr
+ offsetof(struct sigframe_v2
, retcode
));
1273 unlock_user_struct(frame
, frame_addr
, 1);
1276 static void setup_frame(int usig
, struct target_sigaction
*ka
,
1277 target_sigset_t
*set
, CPUState
*regs
)
1279 if (get_osversion() >= 0x020612) {
1280 setup_frame_v2(usig
, ka
, set
, regs
);
1282 setup_frame_v1(usig
, ka
, set
, regs
);
1286 /* compare linux/arch/arm/kernel/signal.c:setup_rt_frame() */
1287 static void setup_rt_frame_v1(int usig
, struct target_sigaction
*ka
,
1288 target_siginfo_t
*info
,
1289 target_sigset_t
*set
, CPUState
*env
)
1291 struct rt_sigframe_v1
*frame
;
1292 abi_ulong frame_addr
= get_sigframe(ka
, env
, sizeof(*frame
));
1293 struct target_sigaltstack stack
;
1295 abi_ulong info_addr
, uc_addr
;
1297 if (!lock_user_struct(VERIFY_WRITE
, frame
, frame_addr
, 0))
1300 info_addr
= frame_addr
+ offsetof(struct rt_sigframe_v1
, info
);
1301 __put_user(info_addr
, &frame
->pinfo
);
1302 uc_addr
= frame_addr
+ offsetof(struct rt_sigframe_v1
, uc
);
1303 __put_user(uc_addr
, &frame
->puc
);
1304 copy_siginfo_to_user(&frame
->info
, info
);
1306 /* Clear all the bits of the ucontext we don't use. */
1307 memset(&frame
->uc
, 0, offsetof(struct target_ucontext_v1
, tuc_mcontext
));
1309 memset(&stack
, 0, sizeof(stack
));
1310 __put_user(target_sigaltstack_used
.ss_sp
, &stack
.ss_sp
);
1311 __put_user(target_sigaltstack_used
.ss_size
, &stack
.ss_size
);
1312 __put_user(sas_ss_flags(get_sp_from_cpustate(env
)), &stack
.ss_flags
);
1313 memcpy(&frame
->uc
.tuc_stack
, &stack
, sizeof(stack
));
1315 setup_sigcontext(&frame
->uc
.tuc_mcontext
, env
, set
->sig
[0]);
1316 for(i
= 0; i
< TARGET_NSIG_WORDS
; i
++) {
1317 if (__put_user(set
->sig
[i
], &frame
->uc
.tuc_sigmask
.sig
[i
]))
1321 setup_return(env
, ka
, &frame
->retcode
, frame_addr
, usig
,
1322 frame_addr
+ offsetof(struct rt_sigframe_v1
, retcode
));
1324 env
->regs
[1] = info_addr
;
1325 env
->regs
[2] = uc_addr
;
1328 unlock_user_struct(frame
, frame_addr
, 1);
1331 static void setup_rt_frame_v2(int usig
, struct target_sigaction
*ka
,
1332 target_siginfo_t
*info
,
1333 target_sigset_t
*set
, CPUState
*env
)
1335 struct rt_sigframe_v2
*frame
;
1336 abi_ulong frame_addr
= get_sigframe(ka
, env
, sizeof(*frame
));
1337 abi_ulong info_addr
, uc_addr
;
1339 if (!lock_user_struct(VERIFY_WRITE
, frame
, frame_addr
, 0))
1342 info_addr
= frame_addr
+ offsetof(struct rt_sigframe_v2
, info
);
1343 uc_addr
= frame_addr
+ offsetof(struct rt_sigframe_v2
, uc
);
1344 copy_siginfo_to_user(&frame
->info
, info
);
1346 setup_sigframe_v2(&frame
->uc
, set
, env
);
1348 setup_return(env
, ka
, &frame
->retcode
, frame_addr
, usig
,
1349 frame_addr
+ offsetof(struct rt_sigframe_v2
, retcode
));
1351 env
->regs
[1] = info_addr
;
1352 env
->regs
[2] = uc_addr
;
1354 unlock_user_struct(frame
, frame_addr
, 1);
1357 static void setup_rt_frame(int usig
, struct target_sigaction
*ka
,
1358 target_siginfo_t
*info
,
1359 target_sigset_t
*set
, CPUState
*env
)
1361 if (get_osversion() >= 0x020612) {
1362 setup_rt_frame_v2(usig
, ka
, info
, set
, env
);
1364 setup_rt_frame_v1(usig
, ka
, info
, set
, env
);
1369 restore_sigcontext(CPUState
*env
, struct target_sigcontext
*sc
)
1374 __get_user_error(env
->regs
[0], &sc
->arm_r0
, err
);
1375 __get_user_error(env
->regs
[1], &sc
->arm_r1
, err
);
1376 __get_user_error(env
->regs
[2], &sc
->arm_r2
, err
);
1377 __get_user_error(env
->regs
[3], &sc
->arm_r3
, err
);
1378 __get_user_error(env
->regs
[4], &sc
->arm_r4
, err
);
1379 __get_user_error(env
->regs
[5], &sc
->arm_r5
, err
);
1380 __get_user_error(env
->regs
[6], &sc
->arm_r6
, err
);
1381 __get_user_error(env
->regs
[7], &sc
->arm_r7
, err
);
1382 __get_user_error(env
->regs
[8], &sc
->arm_r8
, err
);
1383 __get_user_error(env
->regs
[9], &sc
->arm_r9
, err
);
1384 __get_user_error(env
->regs
[10], &sc
->arm_r10
, err
);
1385 __get_user_error(env
->regs
[11], &sc
->arm_fp
, err
);
1386 __get_user_error(env
->regs
[12], &sc
->arm_ip
, err
);
1387 __get_user_error(env
->regs
[13], &sc
->arm_sp
, err
);
1388 __get_user_error(env
->regs
[14], &sc
->arm_lr
, err
);
1389 __get_user_error(env
->regs
[15], &sc
->arm_pc
, err
);
1390 #ifdef TARGET_CONFIG_CPU_32
1391 __get_user_error(cpsr
, &sc
->arm_cpsr
, err
);
1392 cpsr_write(env
, cpsr
, CPSR_USER
| CPSR_EXEC
);
1395 err
|= !valid_user_regs(env
);
1400 long do_sigreturn_v1(CPUState
*env
)
1402 abi_ulong frame_addr
;
1403 struct sigframe_v1
*frame
;
1404 target_sigset_t set
;
1409 * Since we stacked the signal on a 64-bit boundary,
1410 * then 'sp' should be word aligned here. If it's
1411 * not, then the user is trying to mess with us.
1413 if (env
->regs
[13] & 7)
1416 frame_addr
= env
->regs
[13];
1417 if (!lock_user_struct(VERIFY_READ
, frame
, frame_addr
, 1))
1420 if (__get_user(set
.sig
[0], &frame
->sc
.oldmask
))
1422 for(i
= 1; i
< TARGET_NSIG_WORDS
; i
++) {
1423 if (__get_user(set
.sig
[i
], &frame
->extramask
[i
- 1]))
1427 target_to_host_sigset_internal(&host_set
, &set
);
1428 sigprocmask(SIG_SETMASK
, &host_set
, NULL
);
1430 if (restore_sigcontext(env
, &frame
->sc
))
1434 /* Send SIGTRAP if we're single-stepping */
1435 if (ptrace_cancel_bpt(current
))
1436 send_sig(SIGTRAP
, current
, 1);
1438 unlock_user_struct(frame
, frame_addr
, 0);
1439 return env
->regs
[0];
1442 unlock_user_struct(frame
, frame_addr
, 0);
1443 force_sig(SIGSEGV
/* , current */);
1447 static int do_sigframe_return_v2(CPUState
*env
, target_ulong frame_addr
,
1448 struct target_ucontext_v2
*uc
)
1452 target_to_host_sigset(&host_set
, &uc
->tuc_sigmask
);
1453 sigprocmask(SIG_SETMASK
, &host_set
, NULL
);
1455 if (restore_sigcontext(env
, &uc
->tuc_mcontext
))
1458 if (do_sigaltstack(frame_addr
+ offsetof(struct target_ucontext_v2
, tuc_stack
), 0, get_sp_from_cpustate(env
)) == -EFAULT
)
1462 /* Send SIGTRAP if we're single-stepping */
1463 if (ptrace_cancel_bpt(current
))
1464 send_sig(SIGTRAP
, current
, 1);
1470 long do_sigreturn_v2(CPUState
*env
)
1472 abi_ulong frame_addr
;
1473 struct sigframe_v2
*frame
;
1476 * Since we stacked the signal on a 64-bit boundary,
1477 * then 'sp' should be word aligned here. If it's
1478 * not, then the user is trying to mess with us.
1480 if (env
->regs
[13] & 7)
1483 frame_addr
= env
->regs
[13];
1484 if (!lock_user_struct(VERIFY_READ
, frame
, frame_addr
, 1))
1487 if (do_sigframe_return_v2(env
, frame_addr
, &frame
->uc
))
1490 unlock_user_struct(frame
, frame_addr
, 0);
1491 return env
->regs
[0];
1494 unlock_user_struct(frame
, frame_addr
, 0);
1495 force_sig(SIGSEGV
/* , current */);
1499 long do_sigreturn(CPUState
*env
)
1501 if (get_osversion() >= 0x020612) {
1502 return do_sigreturn_v2(env
);
1504 return do_sigreturn_v1(env
);
1508 long do_rt_sigreturn_v1(CPUState
*env
)
1510 abi_ulong frame_addr
;
1511 struct rt_sigframe_v1
*frame
;
1515 * Since we stacked the signal on a 64-bit boundary,
1516 * then 'sp' should be word aligned here. If it's
1517 * not, then the user is trying to mess with us.
1519 if (env
->regs
[13] & 7)
1522 frame_addr
= env
->regs
[13];
1523 if (!lock_user_struct(VERIFY_READ
, frame
, frame_addr
, 1))
1526 target_to_host_sigset(&host_set
, &frame
->uc
.tuc_sigmask
);
1527 sigprocmask(SIG_SETMASK
, &host_set
, NULL
);
1529 if (restore_sigcontext(env
, &frame
->uc
.tuc_mcontext
))
1532 if (do_sigaltstack(frame_addr
+ offsetof(struct rt_sigframe_v1
, uc
.tuc_stack
), 0, get_sp_from_cpustate(env
)) == -EFAULT
)
1536 /* Send SIGTRAP if we're single-stepping */
1537 if (ptrace_cancel_bpt(current
))
1538 send_sig(SIGTRAP
, current
, 1);
1540 unlock_user_struct(frame
, frame_addr
, 0);
1541 return env
->regs
[0];
1544 unlock_user_struct(frame
, frame_addr
, 0);
1545 force_sig(SIGSEGV
/* , current */);
1549 long do_rt_sigreturn_v2(CPUState
*env
)
1551 abi_ulong frame_addr
;
1552 struct rt_sigframe_v2
*frame
;
1555 * Since we stacked the signal on a 64-bit boundary,
1556 * then 'sp' should be word aligned here. If it's
1557 * not, then the user is trying to mess with us.
1559 if (env
->regs
[13] & 7)
1562 frame_addr
= env
->regs
[13];
1563 if (!lock_user_struct(VERIFY_READ
, frame
, frame_addr
, 1))
1566 if (do_sigframe_return_v2(env
, frame_addr
, &frame
->uc
))
1569 unlock_user_struct(frame
, frame_addr
, 0);
1570 return env
->regs
[0];
1573 unlock_user_struct(frame
, frame_addr
, 0);
1574 force_sig(SIGSEGV
/* , current */);
1578 long do_rt_sigreturn(CPUState
*env
)
1580 if (get_osversion() >= 0x020612) {
1581 return do_rt_sigreturn_v2(env
);
1583 return do_rt_sigreturn_v1(env
);
1587 #elif defined(TARGET_SPARC)
1589 #define __SUNOS_MAXWIN 31
1591 /* This is what SunOS does, so shall I. */
1592 struct target_sigcontext
{
1593 abi_ulong sigc_onstack
; /* state to restore */
1595 abi_ulong sigc_mask
; /* sigmask to restore */
1596 abi_ulong sigc_sp
; /* stack pointer */
1597 abi_ulong sigc_pc
; /* program counter */
1598 abi_ulong sigc_npc
; /* next program counter */
1599 abi_ulong sigc_psr
; /* for condition codes etc */
1600 abi_ulong sigc_g1
; /* User uses these two registers */
1601 abi_ulong sigc_o0
; /* within the trampoline code. */
1603 /* Now comes information regarding the users window set
1604 * at the time of the signal.
1606 abi_ulong sigc_oswins
; /* outstanding windows */
1608 /* stack ptrs for each regwin buf */
1609 char *sigc_spbuf
[__SUNOS_MAXWIN
];
1611 /* Windows to restore after signal */
1613 abi_ulong locals
[8];
1615 } sigc_wbuf
[__SUNOS_MAXWIN
];
1617 /* A Sparc stack frame */
1618 struct sparc_stackf
{
1619 abi_ulong locals
[8];
1621 struct sparc_stackf
*fp
;
1622 abi_ulong callers_pc
;
1625 abi_ulong xxargs
[1];
1634 abi_ulong u_regs
[16]; /* globals and ins */
1640 unsigned long si_float_regs
[32];
1641 unsigned long si_fsr
;
1642 unsigned long si_fpqdepth
;
1644 unsigned long *insn_addr
;
1647 } qemu_siginfo_fpu_t
;
1650 struct target_signal_frame
{
1651 struct sparc_stackf ss
;
1654 abi_ulong insns
[2] __attribute__ ((aligned (8)));
1655 abi_ulong extramask
[TARGET_NSIG_WORDS
- 1];
1656 abi_ulong extra_size
; /* Should be 0 */
1657 qemu_siginfo_fpu_t fpu_state
;
1659 struct target_rt_signal_frame
{
1660 struct sparc_stackf ss
;
1665 unsigned int insns
[2];
1667 unsigned int extra_size
; /* Should be 0 */
1668 qemu_siginfo_fpu_t fpu_state
;
1682 #define UREG_FP UREG_I6
1683 #define UREG_SP UREG_O6
1685 static inline abi_ulong
get_sigframe(struct target_sigaction
*sa
,
1686 CPUState
*env
, unsigned long framesize
)
1690 sp
= env
->regwptr
[UREG_FP
];
1692 /* This is the X/Open sanctioned signal stack switching. */
1693 if (sa
->sa_flags
& TARGET_SA_ONSTACK
) {
1694 if (!on_sig_stack(sp
)
1695 && !((target_sigaltstack_used
.ss_sp
+ target_sigaltstack_used
.ss_size
) & 7))
1696 sp
= target_sigaltstack_used
.ss_sp
+ target_sigaltstack_used
.ss_size
;
1698 return sp
- framesize
;
1702 setup___siginfo(__siginfo_t
*si
, CPUState
*env
, abi_ulong mask
)
1706 err
|= __put_user(env
->psr
, &si
->si_regs
.psr
);
1707 err
|= __put_user(env
->pc
, &si
->si_regs
.pc
);
1708 err
|= __put_user(env
->npc
, &si
->si_regs
.npc
);
1709 err
|= __put_user(env
->y
, &si
->si_regs
.y
);
1710 for (i
=0; i
< 8; i
++) {
1711 err
|= __put_user(env
->gregs
[i
], &si
->si_regs
.u_regs
[i
]);
1713 for (i
=0; i
< 8; i
++) {
1714 err
|= __put_user(env
->regwptr
[UREG_I0
+ i
], &si
->si_regs
.u_regs
[i
+8]);
1716 err
|= __put_user(mask
, &si
->si_mask
);
1722 setup_sigcontext(struct target_sigcontext
*sc
, /*struct _fpstate *fpstate,*/
1723 CPUState
*env
, unsigned long mask
)
1727 err
|= __put_user(mask
, &sc
->sigc_mask
);
1728 err
|= __put_user(env
->regwptr
[UREG_SP
], &sc
->sigc_sp
);
1729 err
|= __put_user(env
->pc
, &sc
->sigc_pc
);
1730 err
|= __put_user(env
->npc
, &sc
->sigc_npc
);
1731 err
|= __put_user(env
->psr
, &sc
->sigc_psr
);
1732 err
|= __put_user(env
->gregs
[1], &sc
->sigc_g1
);
1733 err
|= __put_user(env
->regwptr
[UREG_O0
], &sc
->sigc_o0
);
1738 #define NF_ALIGNEDSZ (((sizeof(struct target_signal_frame) + 7) & (~7)))
1740 static void setup_frame(int sig
, struct target_sigaction
*ka
,
1741 target_sigset_t
*set
, CPUState
*env
)
1744 struct target_signal_frame
*sf
;
1745 int sigframe_size
, err
, i
;
1747 /* 1. Make sure everything is clean */
1748 //synchronize_user_stack();
1750 sigframe_size
= NF_ALIGNEDSZ
;
1751 sf_addr
= get_sigframe(ka
, env
, sigframe_size
);
1753 sf
= lock_user(VERIFY_WRITE
, sf_addr
,
1754 sizeof(struct target_signal_frame
), 0);
1758 //fprintf(stderr, "sf: %x pc %x fp %x sp %x\n", sf, env->pc, env->regwptr[UREG_FP], env->regwptr[UREG_SP]);
1760 if (invalid_frame_pointer(sf
, sigframe_size
))
1761 goto sigill_and_return
;
1763 /* 2. Save the current process state */
1764 err
= setup___siginfo(&sf
->info
, env
, set
->sig
[0]);
1765 err
|= __put_user(0, &sf
->extra_size
);
1767 //err |= save_fpu_state(regs, &sf->fpu_state);
1768 //err |= __put_user(&sf->fpu_state, &sf->fpu_save);
1770 err
|= __put_user(set
->sig
[0], &sf
->info
.si_mask
);
1771 for (i
= 0; i
< TARGET_NSIG_WORDS
- 1; i
++) {
1772 err
|= __put_user(set
->sig
[i
+ 1], &sf
->extramask
[i
]);
1775 for (i
= 0; i
< 8; i
++) {
1776 err
|= __put_user(env
->regwptr
[i
+ UREG_L0
], &sf
->ss
.locals
[i
]);
1778 for (i
= 0; i
< 8; i
++) {
1779 err
|= __put_user(env
->regwptr
[i
+ UREG_I0
], &sf
->ss
.ins
[i
]);
1784 /* 3. signal handler back-trampoline and parameters */
1785 env
->regwptr
[UREG_FP
] = sf_addr
;
1786 env
->regwptr
[UREG_I0
] = sig
;
1787 env
->regwptr
[UREG_I1
] = sf_addr
+
1788 offsetof(struct target_signal_frame
, info
);
1789 env
->regwptr
[UREG_I2
] = sf_addr
+
1790 offsetof(struct target_signal_frame
, info
);
1792 /* 4. signal handler */
1793 env
->pc
= ka
->_sa_handler
;
1794 env
->npc
= (env
->pc
+ 4);
1795 /* 5. return to kernel instructions */
1796 if (ka
->sa_restorer
)
1797 env
->regwptr
[UREG_I7
] = ka
->sa_restorer
;
1801 env
->regwptr
[UREG_I7
] = sf_addr
+
1802 offsetof(struct target_signal_frame
, insns
) - 2 * 4;
1804 /* mov __NR_sigreturn, %g1 */
1806 err
|= __put_user(val32
, &sf
->insns
[0]);
1810 err
|= __put_user(val32
, &sf
->insns
[1]);
1814 /* Flush instruction space. */
1815 //flush_sig_insns(current->mm, (unsigned long) &(sf->insns[0]));
1818 unlock_user(sf
, sf_addr
, sizeof(struct target_signal_frame
));
1822 force_sig(TARGET_SIGILL
);
1825 //fprintf(stderr, "force_sig\n");
1826 unlock_user(sf
, sf_addr
, sizeof(struct target_signal_frame
));
1827 force_sig(TARGET_SIGSEGV
);
1830 restore_fpu_state(CPUState
*env
, qemu_siginfo_fpu_t
*fpu
)
1835 if (current
->flags
& PF_USEDFPU
)
1836 regs
->psr
&= ~PSR_EF
;
1838 if (current
== last_task_used_math
) {
1839 last_task_used_math
= 0;
1840 regs
->psr
&= ~PSR_EF
;
1843 current
->used_math
= 1;
1844 current
->flags
&= ~PF_USEDFPU
;
1847 if (verify_area (VERIFY_READ
, fpu
, sizeof(*fpu
)))
1852 /* XXX: incorrect */
1853 err
= __copy_from_user(&env
->fpr
[0], &fpu
->si_float_regs
[0],
1854 (sizeof(unsigned long) * 32));
1856 err
|= __get_user(env
->fsr
, &fpu
->si_fsr
);
1858 err
|= __get_user(current
->thread
.fpqdepth
, &fpu
->si_fpqdepth
);
1859 if (current
->thread
.fpqdepth
!= 0)
1860 err
|= __copy_from_user(¤t
->thread
.fpqueue
[0],
1861 &fpu
->si_fpqueue
[0],
1862 ((sizeof(unsigned long) +
1863 (sizeof(unsigned long *)))*16));
1869 static void setup_rt_frame(int sig
, struct target_sigaction
*ka
,
1870 target_siginfo_t
*info
,
1871 target_sigset_t
*set
, CPUState
*env
)
1873 fprintf(stderr
, "setup_rt_frame: not implemented\n");
1876 long do_sigreturn(CPUState
*env
)
1879 struct target_signal_frame
*sf
;
1880 uint32_t up_psr
, pc
, npc
;
1881 target_sigset_t set
;
1883 abi_ulong fpu_save_addr
;
1886 sf_addr
= env
->regwptr
[UREG_FP
];
1887 if (!lock_user_struct(VERIFY_READ
, sf
, sf_addr
, 1))
1890 fprintf(stderr
, "sigreturn\n");
1891 fprintf(stderr
, "sf: %x pc %x fp %x sp %x\n", sf
, env
->pc
, env
->regwptr
[UREG_FP
], env
->regwptr
[UREG_SP
]);
1893 //cpu_dump_state(env, stderr, fprintf, 0);
1895 /* 1. Make sure we are not getting garbage from the user */
1900 err
= __get_user(pc
, &sf
->info
.si_regs
.pc
);
1901 err
|= __get_user(npc
, &sf
->info
.si_regs
.npc
);
1906 /* 2. Restore the state */
1907 err
|= __get_user(up_psr
, &sf
->info
.si_regs
.psr
);
1909 /* User can only change condition codes and FPU enabling in %psr. */
1910 env
->psr
= (up_psr
& (PSR_ICC
/* | PSR_EF */))
1911 | (env
->psr
& ~(PSR_ICC
/* | PSR_EF */));
1915 err
|= __get_user(env
->y
, &sf
->info
.si_regs
.y
);
1916 for (i
=0; i
< 8; i
++) {
1917 err
|= __get_user(env
->gregs
[i
], &sf
->info
.si_regs
.u_regs
[i
]);
1919 for (i
=0; i
< 8; i
++) {
1920 err
|= __get_user(env
->regwptr
[i
+ UREG_I0
], &sf
->info
.si_regs
.u_regs
[i
+8]);
1923 err
|= __get_user(fpu_save_addr
, &sf
->fpu_save
);
1926 // err |= restore_fpu_state(env, fpu_save);
1928 /* This is pretty much atomic, no amount locking would prevent
1929 * the races which exist anyways.
1931 err
|= __get_user(set
.sig
[0], &sf
->info
.si_mask
);
1932 for(i
= 1; i
< TARGET_NSIG_WORDS
; i
++) {
1933 err
|= (__get_user(set
.sig
[i
], &sf
->extramask
[i
- 1]));
1936 target_to_host_sigset_internal(&host_set
, &set
);
1937 sigprocmask(SIG_SETMASK
, &host_set
, NULL
);
1941 unlock_user_struct(sf
, sf_addr
, 0);
1942 return env
->regwptr
[0];
1945 unlock_user_struct(sf
, sf_addr
, 0);
1946 force_sig(TARGET_SIGSEGV
);
1949 long do_rt_sigreturn(CPUState
*env
)
1951 fprintf(stderr
, "do_rt_sigreturn: not implemented\n");
1952 return -TARGET_ENOSYS
;
1955 #if defined(TARGET_SPARC64) && !defined(TARGET_ABI32)
1977 typedef abi_ulong target_mc_greg_t
;
1978 typedef target_mc_greg_t target_mc_gregset_t
[MC_NGREG
];
1980 struct target_mc_fq
{
1981 abi_ulong
*mcfq_addr
;
1985 struct target_mc_fpu
{
1989 //uint128_t qregs[16];
1991 abi_ulong mcfpu_fsr
;
1992 abi_ulong mcfpu_fprs
;
1993 abi_ulong mcfpu_gsr
;
1994 struct target_mc_fq
*mcfpu_fq
;
1995 unsigned char mcfpu_qcnt
;
1996 unsigned char mcfpu_qentsz
;
1997 unsigned char mcfpu_enab
;
1999 typedef struct target_mc_fpu target_mc_fpu_t
;
2002 target_mc_gregset_t mc_gregs
;
2003 target_mc_greg_t mc_fp
;
2004 target_mc_greg_t mc_i7
;
2005 target_mc_fpu_t mc_fpregs
;
2006 } target_mcontext_t
;
2008 struct target_ucontext
{
2009 struct target_ucontext
*uc_link
;
2011 target_sigset_t uc_sigmask
;
2012 target_mcontext_t uc_mcontext
;
2015 /* A V9 register window */
2016 struct target_reg_window
{
2017 abi_ulong locals
[8];
2021 #define TARGET_STACK_BIAS 2047
2023 /* {set, get}context() needed for 64-bit SparcLinux userland. */
2024 void sparc64_set_context(CPUSPARCState
*env
)
2027 struct target_ucontext
*ucp
;
2028 target_mc_gregset_t
*grp
;
2029 abi_ulong pc
, npc
, tstate
;
2030 abi_ulong fp
, i7
, w_addr
;
2031 unsigned char fenab
;
2035 ucp_addr
= env
->regwptr
[UREG_I0
];
2036 if (!lock_user_struct(VERIFY_READ
, ucp
, ucp_addr
, 1))
2038 grp
= &ucp
->uc_mcontext
.mc_gregs
;
2039 err
= __get_user(pc
, &((*grp
)[MC_PC
]));
2040 err
|= __get_user(npc
, &((*grp
)[MC_NPC
]));
2041 if (err
|| ((pc
| npc
) & 3))
2043 if (env
->regwptr
[UREG_I1
]) {
2044 target_sigset_t target_set
;
2047 if (TARGET_NSIG_WORDS
== 1) {
2048 if (__get_user(target_set
.sig
[0], &ucp
->uc_sigmask
.sig
[0]))
2051 abi_ulong
*src
, *dst
;
2052 src
= ucp
->uc_sigmask
.sig
;
2053 dst
= target_set
.sig
;
2054 for (i
= 0; i
< sizeof(target_sigset_t
) / sizeof(abi_ulong
);
2056 err
|= __get_user(*dst
, src
);
2060 target_to_host_sigset_internal(&set
, &target_set
);
2061 sigprocmask(SIG_SETMASK
, &set
, NULL
);
2065 err
|= __get_user(env
->y
, &((*grp
)[MC_Y
]));
2066 err
|= __get_user(tstate
, &((*grp
)[MC_TSTATE
]));
2067 env
->asi
= (tstate
>> 24) & 0xff;
2068 PUT_CCR(env
, tstate
>> 32);
2069 PUT_CWP64(env
, tstate
& 0x1f);
2070 err
|= __get_user(env
->gregs
[1], (&(*grp
)[MC_G1
]));
2071 err
|= __get_user(env
->gregs
[2], (&(*grp
)[MC_G2
]));
2072 err
|= __get_user(env
->gregs
[3], (&(*grp
)[MC_G3
]));
2073 err
|= __get_user(env
->gregs
[4], (&(*grp
)[MC_G4
]));
2074 err
|= __get_user(env
->gregs
[5], (&(*grp
)[MC_G5
]));
2075 err
|= __get_user(env
->gregs
[6], (&(*grp
)[MC_G6
]));
2076 err
|= __get_user(env
->gregs
[7], (&(*grp
)[MC_G7
]));
2077 err
|= __get_user(env
->regwptr
[UREG_I0
], (&(*grp
)[MC_O0
]));
2078 err
|= __get_user(env
->regwptr
[UREG_I1
], (&(*grp
)[MC_O1
]));
2079 err
|= __get_user(env
->regwptr
[UREG_I2
], (&(*grp
)[MC_O2
]));
2080 err
|= __get_user(env
->regwptr
[UREG_I3
], (&(*grp
)[MC_O3
]));
2081 err
|= __get_user(env
->regwptr
[UREG_I4
], (&(*grp
)[MC_O4
]));
2082 err
|= __get_user(env
->regwptr
[UREG_I5
], (&(*grp
)[MC_O5
]));
2083 err
|= __get_user(env
->regwptr
[UREG_I6
], (&(*grp
)[MC_O6
]));
2084 err
|= __get_user(env
->regwptr
[UREG_I7
], (&(*grp
)[MC_O7
]));
2086 err
|= __get_user(fp
, &(ucp
->uc_mcontext
.mc_fp
));
2087 err
|= __get_user(i7
, &(ucp
->uc_mcontext
.mc_i7
));
2089 w_addr
= TARGET_STACK_BIAS
+env
->regwptr
[UREG_I6
];
2090 if (put_user(fp
, w_addr
+ offsetof(struct target_reg_window
, ins
[6]),
2093 if (put_user(i7
, w_addr
+ offsetof(struct target_reg_window
, ins
[7]),
2096 err
|= __get_user(fenab
, &(ucp
->uc_mcontext
.mc_fpregs
.mcfpu_enab
));
2097 err
|= __get_user(env
->fprs
, &(ucp
->uc_mcontext
.mc_fpregs
.mcfpu_fprs
));
2099 uint32_t *src
, *dst
;
2100 src
= ucp
->uc_mcontext
.mc_fpregs
.mcfpu_fregs
.sregs
;
2102 /* XXX: check that the CPU storage is the same as user context */
2103 for (i
= 0; i
< 64; i
++, dst
++, src
++)
2104 err
|= __get_user(*dst
, src
);
2106 err
|= __get_user(env
->fsr
,
2107 &(ucp
->uc_mcontext
.mc_fpregs
.mcfpu_fsr
));
2108 err
|= __get_user(env
->gsr
,
2109 &(ucp
->uc_mcontext
.mc_fpregs
.mcfpu_gsr
));
2112 unlock_user_struct(ucp
, ucp_addr
, 0);
2115 unlock_user_struct(ucp
, ucp_addr
, 0);
2119 void sparc64_get_context(CPUSPARCState
*env
)
2122 struct target_ucontext
*ucp
;
2123 target_mc_gregset_t
*grp
;
2124 target_mcontext_t
*mcp
;
2125 abi_ulong fp
, i7
, w_addr
;
2128 target_sigset_t target_set
;
2131 ucp_addr
= env
->regwptr
[UREG_I0
];
2132 if (!lock_user_struct(VERIFY_WRITE
, ucp
, ucp_addr
, 0))
2135 mcp
= &ucp
->uc_mcontext
;
2136 grp
= &mcp
->mc_gregs
;
2138 /* Skip over the trap instruction, first. */
2144 sigprocmask(0, NULL
, &set
);
2145 host_to_target_sigset_internal(&target_set
, &set
);
2146 if (TARGET_NSIG_WORDS
== 1) {
2147 err
|= __put_user(target_set
.sig
[0],
2148 (abi_ulong
*)&ucp
->uc_sigmask
);
2150 abi_ulong
*src
, *dst
;
2151 src
= target_set
.sig
;
2152 dst
= ucp
->uc_sigmask
.sig
;
2153 for (i
= 0; i
< sizeof(target_sigset_t
) / sizeof(abi_ulong
);
2155 err
|= __put_user(*src
, dst
);
2160 /* XXX: tstate must be saved properly */
2161 // err |= __put_user(env->tstate, &((*grp)[MC_TSTATE]));
2162 err
|= __put_user(env
->pc
, &((*grp
)[MC_PC
]));
2163 err
|= __put_user(env
->npc
, &((*grp
)[MC_NPC
]));
2164 err
|= __put_user(env
->y
, &((*grp
)[MC_Y
]));
2165 err
|= __put_user(env
->gregs
[1], &((*grp
)[MC_G1
]));
2166 err
|= __put_user(env
->gregs
[2], &((*grp
)[MC_G2
]));
2167 err
|= __put_user(env
->gregs
[3], &((*grp
)[MC_G3
]));
2168 err
|= __put_user(env
->gregs
[4], &((*grp
)[MC_G4
]));
2169 err
|= __put_user(env
->gregs
[5], &((*grp
)[MC_G5
]));
2170 err
|= __put_user(env
->gregs
[6], &((*grp
)[MC_G6
]));
2171 err
|= __put_user(env
->gregs
[7], &((*grp
)[MC_G7
]));
2172 err
|= __put_user(env
->regwptr
[UREG_I0
], &((*grp
)[MC_O0
]));
2173 err
|= __put_user(env
->regwptr
[UREG_I1
], &((*grp
)[MC_O1
]));
2174 err
|= __put_user(env
->regwptr
[UREG_I2
], &((*grp
)[MC_O2
]));
2175 err
|= __put_user(env
->regwptr
[UREG_I3
], &((*grp
)[MC_O3
]));
2176 err
|= __put_user(env
->regwptr
[UREG_I4
], &((*grp
)[MC_O4
]));
2177 err
|= __put_user(env
->regwptr
[UREG_I5
], &((*grp
)[MC_O5
]));
2178 err
|= __put_user(env
->regwptr
[UREG_I6
], &((*grp
)[MC_O6
]));
2179 err
|= __put_user(env
->regwptr
[UREG_I7
], &((*grp
)[MC_O7
]));
2181 w_addr
= TARGET_STACK_BIAS
+env
->regwptr
[UREG_I6
];
2183 if (get_user(fp
, w_addr
+ offsetof(struct target_reg_window
, ins
[6]),
2186 if (get_user(i7
, w_addr
+ offsetof(struct target_reg_window
, ins
[7]),
2189 err
|= __put_user(fp
, &(mcp
->mc_fp
));
2190 err
|= __put_user(i7
, &(mcp
->mc_i7
));
2193 uint32_t *src
, *dst
;
2195 dst
= ucp
->uc_mcontext
.mc_fpregs
.mcfpu_fregs
.sregs
;
2196 /* XXX: check that the CPU storage is the same as user context */
2197 for (i
= 0; i
< 64; i
++, dst
++, src
++)
2198 err
|= __put_user(*src
, dst
);
2200 err
|= __put_user(env
->fsr
, &(mcp
->mc_fpregs
.mcfpu_fsr
));
2201 err
|= __put_user(env
->gsr
, &(mcp
->mc_fpregs
.mcfpu_gsr
));
2202 err
|= __put_user(env
->fprs
, &(mcp
->mc_fpregs
.mcfpu_fprs
));
2206 unlock_user_struct(ucp
, ucp_addr
, 1);
2209 unlock_user_struct(ucp
, ucp_addr
, 1);
2213 #elif defined(TARGET_ABI_MIPSN64)
2215 # warning signal handling not implemented
2217 static void setup_frame(int sig
, struct target_sigaction
*ka
,
2218 target_sigset_t
*set
, CPUState
*env
)
2220 fprintf(stderr
, "setup_frame: not implemented\n");
2223 static void setup_rt_frame(int sig
, struct target_sigaction
*ka
,
2224 target_siginfo_t
*info
,
2225 target_sigset_t
*set
, CPUState
*env
)
2227 fprintf(stderr
, "setup_rt_frame: not implemented\n");
2230 long do_sigreturn(CPUState
*env
)
2232 fprintf(stderr
, "do_sigreturn: not implemented\n");
2233 return -TARGET_ENOSYS
;
2236 long do_rt_sigreturn(CPUState
*env
)
2238 fprintf(stderr
, "do_rt_sigreturn: not implemented\n");
2239 return -TARGET_ENOSYS
;
2242 #elif defined(TARGET_ABI_MIPSN32)
2244 # warning signal handling not implemented
2246 static void setup_frame(int sig
, struct target_sigaction
*ka
,
2247 target_sigset_t
*set
, CPUState
*env
)
2249 fprintf(stderr
, "setup_frame: not implemented\n");
2252 static void setup_rt_frame(int sig
, struct target_sigaction
*ka
,
2253 target_siginfo_t
*info
,
2254 target_sigset_t
*set
, CPUState
*env
)
2256 fprintf(stderr
, "setup_rt_frame: not implemented\n");
2259 long do_sigreturn(CPUState
*env
)
2261 fprintf(stderr
, "do_sigreturn: not implemented\n");
2262 return -TARGET_ENOSYS
;
2265 long do_rt_sigreturn(CPUState
*env
)
2267 fprintf(stderr
, "do_rt_sigreturn: not implemented\n");
2268 return -TARGET_ENOSYS
;
2271 #elif defined(TARGET_ABI_MIPSO32)
2273 struct target_sigcontext
{
2274 uint32_t sc_regmask
; /* Unused */
2277 uint64_t sc_regs
[32];
2278 uint64_t sc_fpregs
[32];
2279 uint32_t sc_ownedfp
; /* Unused */
2280 uint32_t sc_fpc_csr
;
2281 uint32_t sc_fpc_eir
; /* Unused */
2282 uint32_t sc_used_math
;
2283 uint32_t sc_dsp
; /* dsp status, was sc_ssflags */
2286 target_ulong sc_hi1
; /* Was sc_cause */
2287 target_ulong sc_lo1
; /* Was sc_badvaddr */
2288 target_ulong sc_hi2
; /* Was sc_sigset[4] */
2289 target_ulong sc_lo2
;
2290 target_ulong sc_hi3
;
2291 target_ulong sc_lo3
;
2295 uint32_t sf_ass
[4]; /* argument save space for o32 */
2296 uint32_t sf_code
[2]; /* signal trampoline */
2297 struct target_sigcontext sf_sc
;
2298 target_sigset_t sf_mask
;
2301 /* Install trampoline to jump back from signal handler */
2302 static inline int install_sigtramp(unsigned int *tramp
, unsigned int syscall
)
2307 * Set up the return code ...
2309 * li v0, __NR__foo_sigreturn
2313 err
= __put_user(0x24020000 + syscall
, tramp
+ 0);
2314 err
|= __put_user(0x0000000c , tramp
+ 1);
2315 /* flush_cache_sigtramp((unsigned long) tramp); */
2320 setup_sigcontext(CPUState
*regs
, struct target_sigcontext
*sc
)
2324 err
|= __put_user(regs
->active_tc
.PC
, &sc
->sc_pc
);
2326 #define save_gp_reg(i) do { \
2327 err |= __put_user(regs->active_tc.gpr[i], &sc->sc_regs[i]); \
2329 __put_user(0, &sc
->sc_regs
[0]); save_gp_reg(1); save_gp_reg(2);
2330 save_gp_reg(3); save_gp_reg(4); save_gp_reg(5); save_gp_reg(6);
2331 save_gp_reg(7); save_gp_reg(8); save_gp_reg(9); save_gp_reg(10);
2332 save_gp_reg(11); save_gp_reg(12); save_gp_reg(13); save_gp_reg(14);
2333 save_gp_reg(15); save_gp_reg(16); save_gp_reg(17); save_gp_reg(18);
2334 save_gp_reg(19); save_gp_reg(20); save_gp_reg(21); save_gp_reg(22);
2335 save_gp_reg(23); save_gp_reg(24); save_gp_reg(25); save_gp_reg(26);
2336 save_gp_reg(27); save_gp_reg(28); save_gp_reg(29); save_gp_reg(30);
2340 err
|= __put_user(regs
->active_tc
.HI
[0], &sc
->sc_mdhi
);
2341 err
|= __put_user(regs
->active_tc
.LO
[0], &sc
->sc_mdlo
);
2343 /* Not used yet, but might be useful if we ever have DSP suppport */
2346 err
|= __put_user(mfhi1(), &sc
->sc_hi1
);
2347 err
|= __put_user(mflo1(), &sc
->sc_lo1
);
2348 err
|= __put_user(mfhi2(), &sc
->sc_hi2
);
2349 err
|= __put_user(mflo2(), &sc
->sc_lo2
);
2350 err
|= __put_user(mfhi3(), &sc
->sc_hi3
);
2351 err
|= __put_user(mflo3(), &sc
->sc_lo3
);
2352 err
|= __put_user(rddsp(DSP_MASK
), &sc
->sc_dsp
);
2354 /* same with 64 bit */
2356 err
|= __put_user(regs
->hi
, &sc
->sc_hi
[0]);
2357 err
|= __put_user(regs
->lo
, &sc
->sc_lo
[0]);
2359 err
|= __put_user(mfhi1(), &sc
->sc_hi
[1]);
2360 err
|= __put_user(mflo1(), &sc
->sc_lo
[1]);
2361 err
|= __put_user(mfhi2(), &sc
->sc_hi
[2]);
2362 err
|= __put_user(mflo2(), &sc
->sc_lo
[2]);
2363 err
|= __put_user(mfhi3(), &sc
->sc_hi
[3]);
2364 err
|= __put_user(mflo3(), &sc
->sc_lo
[3]);
2365 err
|= __put_user(rddsp(DSP_MASK
), &sc
->sc_dsp
);
2371 err
|= __put_user(!!used_math(), &sc
->sc_used_math
);
2377 * Save FPU state to signal context. Signal handler will "inherit"
2378 * current FPU state.
2382 if (!is_fpu_owner()) {
2384 restore_fp(current
);
2386 err
|= save_fp_context(sc
);
2395 restore_sigcontext(CPUState
*regs
, struct target_sigcontext
*sc
)
2399 err
|= __get_user(regs
->CP0_EPC
, &sc
->sc_pc
);
2401 err
|= __get_user(regs
->active_tc
.HI
[0], &sc
->sc_mdhi
);
2402 err
|= __get_user(regs
->active_tc
.LO
[0], &sc
->sc_mdlo
);
2404 #define restore_gp_reg(i) do { \
2405 err |= __get_user(regs->active_tc.gpr[i], &sc->sc_regs[i]); \
2407 restore_gp_reg( 1); restore_gp_reg( 2); restore_gp_reg( 3);
2408 restore_gp_reg( 4); restore_gp_reg( 5); restore_gp_reg( 6);
2409 restore_gp_reg( 7); restore_gp_reg( 8); restore_gp_reg( 9);
2410 restore_gp_reg(10); restore_gp_reg(11); restore_gp_reg(12);
2411 restore_gp_reg(13); restore_gp_reg(14); restore_gp_reg(15);
2412 restore_gp_reg(16); restore_gp_reg(17); restore_gp_reg(18);
2413 restore_gp_reg(19); restore_gp_reg(20); restore_gp_reg(21);
2414 restore_gp_reg(22); restore_gp_reg(23); restore_gp_reg(24);
2415 restore_gp_reg(25); restore_gp_reg(26); restore_gp_reg(27);
2416 restore_gp_reg(28); restore_gp_reg(29); restore_gp_reg(30);
2418 #undef restore_gp_reg
2422 err
|= __get_user(treg
, &sc
->sc_hi1
); mthi1(treg
);
2423 err
|= __get_user(treg
, &sc
->sc_lo1
); mtlo1(treg
);
2424 err
|= __get_user(treg
, &sc
->sc_hi2
); mthi2(treg
);
2425 err
|= __get_user(treg
, &sc
->sc_lo2
); mtlo2(treg
);
2426 err
|= __get_user(treg
, &sc
->sc_hi3
); mthi3(treg
);
2427 err
|= __get_user(treg
, &sc
->sc_lo3
); mtlo3(treg
);
2428 err
|= __get_user(treg
, &sc
->sc_dsp
); wrdsp(treg
, DSP_MASK
);
2431 err
|= __get_user(regs
->hi
, &sc
->sc_hi
[0]);
2432 err
|= __get_user(regs
->lo
, &sc
->sc_lo
[0]);
2434 err
|= __get_user(treg
, &sc
->sc_hi
[1]); mthi1(treg
);
2435 err
|= __get_user(treg
, &sc
->sc_lo
[1]); mthi1(treg
);
2436 err
|= __get_user(treg
, &sc
->sc_hi
[2]); mthi2(treg
);
2437 err
|= __get_user(treg
, &sc
->sc_lo
[2]); mthi2(treg
);
2438 err
|= __get_user(treg
, &sc
->sc_hi
[3]); mthi3(treg
);
2439 err
|= __get_user(treg
, &sc
->sc_lo
[3]); mthi3(treg
);
2440 err
|= __get_user(treg
, &sc
->sc_dsp
); wrdsp(treg
, DSP_MASK
);
2444 err
|= __get_user(used_math
, &sc
->sc_used_math
);
2445 conditional_used_math(used_math
);
2450 /* restore fpu context if we have used it before */
2452 err
|= restore_fp_context(sc
);
2454 /* signal handler may have used FPU. Give it up. */
2463 * Determine which stack to use..
2465 static inline abi_ulong
2466 get_sigframe(struct target_sigaction
*ka
, CPUState
*regs
, size_t frame_size
)
2470 /* Default to using normal stack */
2471 sp
= regs
->active_tc
.gpr
[29];
2474 * FPU emulator may have it's own trampoline active just
2475 * above the user stack, 16-bytes before the next lowest
2476 * 16 byte boundary. Try to avoid trashing it.
2480 /* This is the X/Open sanctioned signal stack switching. */
2481 if ((ka
->sa_flags
& TARGET_SA_ONSTACK
) && (sas_ss_flags (sp
) == 0)) {
2482 sp
= target_sigaltstack_used
.ss_sp
+ target_sigaltstack_used
.ss_size
;
2485 return (sp
- frame_size
) & ~7;
2488 /* compare linux/arch/mips/kernel/signal.c:setup_frame() */
2489 static void setup_frame(int sig
, struct target_sigaction
* ka
,
2490 target_sigset_t
*set
, CPUState
*regs
)
2492 struct sigframe
*frame
;
2493 abi_ulong frame_addr
;
2496 frame_addr
= get_sigframe(ka
, regs
, sizeof(*frame
));
2497 if (!lock_user_struct(VERIFY_WRITE
, frame
, frame_addr
, 0))
2500 install_sigtramp(frame
->sf_code
, TARGET_NR_sigreturn
);
2502 if(setup_sigcontext(regs
, &frame
->sf_sc
))
2505 for(i
= 0; i
< TARGET_NSIG_WORDS
; i
++) {
2506 if(__put_user(set
->sig
[i
], &frame
->sf_mask
.sig
[i
]))
2511 * Arguments to signal handler:
2513 * a0 = signal number
2514 * a1 = 0 (should be cause)
2515 * a2 = pointer to struct sigcontext
2517 * $25 and PC point to the signal handler, $29 points to the
2520 regs
->active_tc
.gpr
[ 4] = sig
;
2521 regs
->active_tc
.gpr
[ 5] = 0;
2522 regs
->active_tc
.gpr
[ 6] = frame_addr
+ offsetof(struct sigframe
, sf_sc
);
2523 regs
->active_tc
.gpr
[29] = frame_addr
;
2524 regs
->active_tc
.gpr
[31] = frame_addr
+ offsetof(struct sigframe
, sf_code
);
2525 /* The original kernel code sets CP0_EPC to the handler
2526 * since it returns to userland using eret
2527 * we cannot do this here, and we must set PC directly */
2528 regs
->active_tc
.PC
= regs
->active_tc
.gpr
[25] = ka
->_sa_handler
;
2529 unlock_user_struct(frame
, frame_addr
, 1);
2533 unlock_user_struct(frame
, frame_addr
, 1);
2534 force_sig(TARGET_SIGSEGV
/*, current*/);
2538 long do_sigreturn(CPUState
*regs
)
2540 struct sigframe
*frame
;
2541 abi_ulong frame_addr
;
2543 target_sigset_t target_set
;
2546 #if defined(DEBUG_SIGNAL)
2547 fprintf(stderr
, "do_sigreturn\n");
2549 frame_addr
= regs
->active_tc
.gpr
[29];
2550 if (!lock_user_struct(VERIFY_READ
, frame
, frame_addr
, 1))
2553 for(i
= 0; i
< TARGET_NSIG_WORDS
; i
++) {
2554 if(__get_user(target_set
.sig
[i
], &frame
->sf_mask
.sig
[i
]))
2558 target_to_host_sigset_internal(&blocked
, &target_set
);
2559 sigprocmask(SIG_SETMASK
, &blocked
, NULL
);
2561 if (restore_sigcontext(regs
, &frame
->sf_sc
))
2566 * Don't let your children do this ...
2568 __asm__
__volatile__(
2576 regs
->active_tc
.PC
= regs
->CP0_EPC
;
2577 /* I am not sure this is right, but it seems to work
2578 * maybe a problem with nested signals ? */
2583 force_sig(TARGET_SIGSEGV
/*, current*/);
2587 static void setup_rt_frame(int sig
, struct target_sigaction
*ka
,
2588 target_siginfo_t
*info
,
2589 target_sigset_t
*set
, CPUState
*env
)
2591 fprintf(stderr
, "setup_rt_frame: not implemented\n");
2594 long do_rt_sigreturn(CPUState
*env
)
2596 fprintf(stderr
, "do_rt_sigreturn: not implemented\n");
2597 return -TARGET_ENOSYS
;
2600 #elif defined(TARGET_SH4)
2603 * code and data structures from linux kernel:
2604 * include/asm-sh/sigcontext.h
2605 * arch/sh/kernel/signal.c
2608 struct target_sigcontext
{
2609 target_ulong oldmask
;
2612 target_ulong sc_gregs
[16];
2616 target_ulong sc_gbr
;
2617 target_ulong sc_mach
;
2618 target_ulong sc_macl
;
2621 target_ulong sc_fpregs
[16];
2622 target_ulong sc_xfpregs
[16];
2623 unsigned int sc_fpscr
;
2624 unsigned int sc_fpul
;
2625 unsigned int sc_ownedfp
;
2628 struct target_sigframe
2630 struct target_sigcontext sc
;
2631 target_ulong extramask
[TARGET_NSIG_WORDS
-1];
2632 uint16_t retcode
[3];
2636 struct target_ucontext
{
2637 target_ulong uc_flags
;
2638 struct target_ucontext
*uc_link
;
2639 target_stack_t uc_stack
;
2640 struct target_sigcontext uc_mcontext
;
2641 target_sigset_t uc_sigmask
; /* mask last for extensibility */
2644 struct target_rt_sigframe
2646 struct target_siginfo info
;
2647 struct target_ucontext uc
;
2648 uint16_t retcode
[3];
2652 #define MOVW(n) (0x9300|((n)-2)) /* Move mem word at PC+n to R3 */
2653 #define TRAP_NOARG 0xc310 /* Syscall w/no args (NR in R3) SH3/4 */
2655 static abi_ulong
get_sigframe(struct target_sigaction
*ka
,
2656 unsigned long sp
, size_t frame_size
)
2658 if ((ka
->sa_flags
& TARGET_SA_ONSTACK
) && (sas_ss_flags(sp
) == 0)) {
2659 sp
= target_sigaltstack_used
.ss_sp
+ target_sigaltstack_used
.ss_size
;
2662 return (sp
- frame_size
) & -8ul;
2665 static int setup_sigcontext(struct target_sigcontext
*sc
,
2666 CPUState
*regs
, unsigned long mask
)
2670 #define COPY(x) err |= __put_user(regs->x, &sc->sc_##x)
2671 COPY(gregs
[0]); COPY(gregs
[1]);
2672 COPY(gregs
[2]); COPY(gregs
[3]);
2673 COPY(gregs
[4]); COPY(gregs
[5]);
2674 COPY(gregs
[6]); COPY(gregs
[7]);
2675 COPY(gregs
[8]); COPY(gregs
[9]);
2676 COPY(gregs
[10]); COPY(gregs
[11]);
2677 COPY(gregs
[12]); COPY(gregs
[13]);
2678 COPY(gregs
[14]); COPY(gregs
[15]);
2679 COPY(gbr
); COPY(mach
);
2680 COPY(macl
); COPY(pr
);
2684 /* todo: save FPU registers here */
2686 /* non-iBCS2 extensions.. */
2687 err
|= __put_user(mask
, &sc
->oldmask
);
2692 static int restore_sigcontext(struct CPUState
*regs
,
2693 struct target_sigcontext
*sc
)
2695 unsigned int err
= 0;
2697 #define COPY(x) err |= __get_user(regs->x, &sc->sc_##x)
2699 COPY(gregs
[2]); COPY(gregs
[3]);
2700 COPY(gregs
[4]); COPY(gregs
[5]);
2701 COPY(gregs
[6]); COPY(gregs
[7]);
2702 COPY(gregs
[8]); COPY(gregs
[9]);
2703 COPY(gregs
[10]); COPY(gregs
[11]);
2704 COPY(gregs
[12]); COPY(gregs
[13]);
2705 COPY(gregs
[14]); COPY(gregs
[15]);
2706 COPY(gbr
); COPY(mach
);
2707 COPY(macl
); COPY(pr
);
2711 /* todo: restore FPU registers here */
2713 regs
->tra
= -1; /* disable syscall checks */
2717 static void setup_frame(int sig
, struct target_sigaction
*ka
,
2718 target_sigset_t
*set
, CPUState
*regs
)
2720 struct target_sigframe
*frame
;
2721 abi_ulong frame_addr
;
2726 frame_addr
= get_sigframe(ka
, regs
->gregs
[15], sizeof(*frame
));
2727 if (!lock_user_struct(VERIFY_WRITE
, frame
, frame_addr
, 0))
2730 signal
= current_exec_domain_sig(sig
);
2732 err
|= setup_sigcontext(&frame
->sc
, regs
, set
->sig
[0]);
2734 for (i
= 0; i
< TARGET_NSIG_WORDS
- 1; i
++) {
2735 err
|= __put_user(set
->sig
[i
+ 1], &frame
->extramask
[i
]);
2738 /* Set up to return from userspace. If provided, use a stub
2739 already in userspace. */
2740 if (ka
->sa_flags
& TARGET_SA_RESTORER
) {
2741 regs
->pr
= (unsigned long) ka
->sa_restorer
;
2743 /* Generate return code (system call to sigreturn) */
2744 err
|= __put_user(MOVW(2), &frame
->retcode
[0]);
2745 err
|= __put_user(TRAP_NOARG
, &frame
->retcode
[1]);
2746 err
|= __put_user((TARGET_NR_sigreturn
), &frame
->retcode
[2]);
2747 regs
->pr
= (unsigned long) frame
->retcode
;
2753 /* Set up registers for signal handler */
2754 regs
->gregs
[15] = (unsigned long) frame
;
2755 regs
->gregs
[4] = signal
; /* Arg for signal handler */
2757 regs
->gregs
[6] = (unsigned long) &frame
->sc
;
2758 regs
->pc
= (unsigned long) ka
->_sa_handler
;
2760 unlock_user_struct(frame
, frame_addr
, 1);
2764 unlock_user_struct(frame
, frame_addr
, 1);
2768 static void setup_rt_frame(int sig
, struct target_sigaction
*ka
,
2769 target_siginfo_t
*info
,
2770 target_sigset_t
*set
, CPUState
*regs
)
2772 struct target_rt_sigframe
*frame
;
2773 abi_ulong frame_addr
;
2778 frame_addr
= get_sigframe(ka
, regs
->gregs
[15], sizeof(*frame
));
2779 if (!lock_user_struct(VERIFY_WRITE
, frame
, frame_addr
, 0))
2782 signal
= current_exec_domain_sig(sig
);
2784 err
|= copy_siginfo_to_user(&frame
->info
, info
);
2786 /* Create the ucontext. */
2787 err
|= __put_user(0, &frame
->uc
.uc_flags
);
2788 err
|= __put_user(0, (unsigned long *)&frame
->uc
.uc_link
);
2789 err
|= __put_user((unsigned long)target_sigaltstack_used
.ss_sp
,
2790 &frame
->uc
.uc_stack
.ss_sp
);
2791 err
|= __put_user(sas_ss_flags(regs
->gregs
[15]),
2792 &frame
->uc
.uc_stack
.ss_flags
);
2793 err
|= __put_user(target_sigaltstack_used
.ss_size
,
2794 &frame
->uc
.uc_stack
.ss_size
);
2795 err
|= setup_sigcontext(&frame
->uc
.uc_mcontext
,
2797 for(i
= 0; i
< TARGET_NSIG_WORDS
; i
++) {
2798 err
|= __put_user(set
->sig
[i
], &frame
->uc
.uc_sigmask
.sig
[i
]);
2801 /* Set up to return from userspace. If provided, use a stub
2802 already in userspace. */
2803 if (ka
->sa_flags
& TARGET_SA_RESTORER
) {
2804 regs
->pr
= (unsigned long) ka
->sa_restorer
;
2806 /* Generate return code (system call to sigreturn) */
2807 err
|= __put_user(MOVW(2), &frame
->retcode
[0]);
2808 err
|= __put_user(TRAP_NOARG
, &frame
->retcode
[1]);
2809 err
|= __put_user((TARGET_NR_rt_sigreturn
), &frame
->retcode
[2]);
2810 regs
->pr
= (unsigned long) frame
->retcode
;
2816 /* Set up registers for signal handler */
2817 regs
->gregs
[15] = (unsigned long) frame
;
2818 regs
->gregs
[4] = signal
; /* Arg for signal handler */
2819 regs
->gregs
[5] = (unsigned long) &frame
->info
;
2820 regs
->gregs
[6] = (unsigned long) &frame
->uc
;
2821 regs
->pc
= (unsigned long) ka
->_sa_handler
;
2823 unlock_user_struct(frame
, frame_addr
, 1);
2827 unlock_user_struct(frame
, frame_addr
, 1);
2831 long do_sigreturn(CPUState
*regs
)
2833 struct target_sigframe
*frame
;
2834 abi_ulong frame_addr
;
2836 target_sigset_t target_set
;
2840 #if defined(DEBUG_SIGNAL)
2841 fprintf(stderr
, "do_sigreturn\n");
2843 frame_addr
= regs
->gregs
[15];
2844 if (!lock_user_struct(VERIFY_READ
, frame
, frame_addr
, 1))
2847 err
|= __get_user(target_set
.sig
[0], &frame
->sc
.oldmask
);
2848 for(i
= 1; i
< TARGET_NSIG_WORDS
; i
++) {
2849 err
|= (__get_user(target_set
.sig
[i
], &frame
->extramask
[i
- 1]));
2855 target_to_host_sigset_internal(&blocked
, &target_set
);
2856 sigprocmask(SIG_SETMASK
, &blocked
, NULL
);
2858 if (restore_sigcontext(regs
, &frame
->sc
))
2861 unlock_user_struct(frame
, frame_addr
, 0);
2862 return regs
->gregs
[0];
2865 unlock_user_struct(frame
, frame_addr
, 0);
2866 force_sig(TARGET_SIGSEGV
);
2870 long do_rt_sigreturn(CPUState
*regs
)
2872 struct target_rt_sigframe
*frame
;
2873 abi_ulong frame_addr
;
2876 #if defined(DEBUG_SIGNAL)
2877 fprintf(stderr
, "do_rt_sigreturn\n");
2879 frame_addr
= regs
->gregs
[15];
2880 if (!lock_user_struct(VERIFY_READ
, frame
, frame_addr
, 1))
2883 target_to_host_sigset(&blocked
, &frame
->uc
.uc_sigmask
);
2884 sigprocmask(SIG_SETMASK
, &blocked
, NULL
);
2886 if (restore_sigcontext(regs
, &frame
->uc
.uc_mcontext
))
2889 if (do_sigaltstack(frame_addr
+
2890 offsetof(struct target_rt_sigframe
, uc
.uc_stack
),
2891 0, get_sp_from_cpustate(regs
)) == -EFAULT
)
2894 unlock_user_struct(frame
, frame_addr
, 0);
2895 return regs
->gregs
[0];
2898 unlock_user_struct(frame
, frame_addr
, 0);
2899 force_sig(TARGET_SIGSEGV
);
2902 #elif defined(TARGET_CRIS)
2904 struct target_sigcontext
{
2905 struct target_pt_regs regs
; /* needs to be first */
2907 uint32_t usp
; /* usp before stacking this gunk on it */
2910 /* Signal frames. */
2911 struct target_signal_frame
{
2912 struct target_sigcontext sc
;
2913 uint32_t extramask
[TARGET_NSIG_WORDS
- 1];
2914 uint8_t retcode
[8]; /* Trampoline code. */
2917 struct rt_signal_frame
{
2918 struct siginfo
*pinfo
;
2920 struct siginfo info
;
2922 uint8_t retcode
[8]; /* Trampoline code. */
2925 static void setup_sigcontext(struct target_sigcontext
*sc
, CPUState
*env
)
2927 __put_user(env
->regs
[0], &sc
->regs
.r0
);
2928 __put_user(env
->regs
[1], &sc
->regs
.r1
);
2929 __put_user(env
->regs
[2], &sc
->regs
.r2
);
2930 __put_user(env
->regs
[3], &sc
->regs
.r3
);
2931 __put_user(env
->regs
[4], &sc
->regs
.r4
);
2932 __put_user(env
->regs
[5], &sc
->regs
.r5
);
2933 __put_user(env
->regs
[6], &sc
->regs
.r6
);
2934 __put_user(env
->regs
[7], &sc
->regs
.r7
);
2935 __put_user(env
->regs
[8], &sc
->regs
.r8
);
2936 __put_user(env
->regs
[9], &sc
->regs
.r9
);
2937 __put_user(env
->regs
[10], &sc
->regs
.r10
);
2938 __put_user(env
->regs
[11], &sc
->regs
.r11
);
2939 __put_user(env
->regs
[12], &sc
->regs
.r12
);
2940 __put_user(env
->regs
[13], &sc
->regs
.r13
);
2941 __put_user(env
->regs
[14], &sc
->usp
);
2942 __put_user(env
->regs
[15], &sc
->regs
.acr
);
2943 __put_user(env
->pregs
[PR_MOF
], &sc
->regs
.mof
);
2944 __put_user(env
->pregs
[PR_SRP
], &sc
->regs
.srp
);
2945 __put_user(env
->pc
, &sc
->regs
.erp
);
2948 static void restore_sigcontext(struct target_sigcontext
*sc
, CPUState
*env
)
2950 __get_user(env
->regs
[0], &sc
->regs
.r0
);
2951 __get_user(env
->regs
[1], &sc
->regs
.r1
);
2952 __get_user(env
->regs
[2], &sc
->regs
.r2
);
2953 __get_user(env
->regs
[3], &sc
->regs
.r3
);
2954 __get_user(env
->regs
[4], &sc
->regs
.r4
);
2955 __get_user(env
->regs
[5], &sc
->regs
.r5
);
2956 __get_user(env
->regs
[6], &sc
->regs
.r6
);
2957 __get_user(env
->regs
[7], &sc
->regs
.r7
);
2958 __get_user(env
->regs
[8], &sc
->regs
.r8
);
2959 __get_user(env
->regs
[9], &sc
->regs
.r9
);
2960 __get_user(env
->regs
[10], &sc
->regs
.r10
);
2961 __get_user(env
->regs
[11], &sc
->regs
.r11
);
2962 __get_user(env
->regs
[12], &sc
->regs
.r12
);
2963 __get_user(env
->regs
[13], &sc
->regs
.r13
);
2964 __get_user(env
->regs
[14], &sc
->usp
);
2965 __get_user(env
->regs
[15], &sc
->regs
.acr
);
2966 __get_user(env
->pregs
[PR_MOF
], &sc
->regs
.mof
);
2967 __get_user(env
->pregs
[PR_SRP
], &sc
->regs
.srp
);
2968 __get_user(env
->pc
, &sc
->regs
.erp
);
2971 static abi_ulong
get_sigframe(CPUState
*env
, int framesize
)
2974 /* Align the stack downwards to 4. */
2975 sp
= (env
->regs
[R_SP
] & ~3);
2976 return sp
- framesize
;
2979 static void setup_frame(int sig
, struct target_sigaction
*ka
,
2980 target_sigset_t
*set
, CPUState
*env
)
2982 struct target_signal_frame
*frame
;
2983 abi_ulong frame_addr
;
2987 frame_addr
= get_sigframe(env
, sizeof *frame
);
2988 if (!lock_user_struct(VERIFY_WRITE
, frame
, frame_addr
, 0))
2992 * The CRIS signal return trampoline. A real linux/CRIS kernel doesn't
2993 * use this trampoline anymore but it sets it up for GDB.
2994 * In QEMU, using the trampoline simplifies things a bit so we use it.
2996 * This is movu.w __NR_sigreturn, r9; break 13;
2998 err
|= __put_user(0x9c5f, frame
->retcode
+0);
2999 err
|= __put_user(TARGET_NR_sigreturn
,
3001 err
|= __put_user(0xe93d, frame
->retcode
+4);
3003 /* Save the mask. */
3004 err
|= __put_user(set
->sig
[0], &frame
->sc
.oldmask
);
3008 for(i
= 1; i
< TARGET_NSIG_WORDS
; i
++) {
3009 if (__put_user(set
->sig
[i
], &frame
->extramask
[i
- 1]))
3013 setup_sigcontext(&frame
->sc
, env
);
3015 /* Move the stack and setup the arguments for the handler. */
3016 env
->regs
[R_SP
] = (uint32_t) (unsigned long) frame
;
3017 env
->regs
[10] = sig
;
3018 env
->pc
= (unsigned long) ka
->_sa_handler
;
3019 /* Link SRP so the guest returns through the trampoline. */
3020 env
->pregs
[PR_SRP
] = (uint32_t) (unsigned long) &frame
->retcode
[0];
3022 unlock_user_struct(frame
, frame_addr
, 1);
3025 unlock_user_struct(frame
, frame_addr
, 1);
3026 force_sig(TARGET_SIGSEGV
);
3029 static void setup_rt_frame(int sig
, struct target_sigaction
*ka
,
3030 target_siginfo_t
*info
,
3031 target_sigset_t
*set
, CPUState
*env
)
3033 fprintf(stderr
, "CRIS setup_rt_frame: not implemented\n");
3036 long do_sigreturn(CPUState
*env
)
3038 struct target_signal_frame
*frame
;
3039 abi_ulong frame_addr
;
3040 target_sigset_t target_set
;
3044 frame_addr
= env
->regs
[R_SP
];
3045 /* Make sure the guest isn't playing games. */
3046 if (!lock_user_struct(VERIFY_WRITE
, frame
, frame_addr
, 1))
3049 /* Restore blocked signals */
3050 if (__get_user(target_set
.sig
[0], &frame
->sc
.oldmask
))
3052 for(i
= 1; i
< TARGET_NSIG_WORDS
; i
++) {
3053 if (__get_user(target_set
.sig
[i
], &frame
->extramask
[i
- 1]))
3056 target_to_host_sigset_internal(&set
, &target_set
);
3057 sigprocmask(SIG_SETMASK
, &set
, NULL
);
3059 restore_sigcontext(&frame
->sc
, env
);
3060 unlock_user_struct(frame
, frame_addr
, 0);
3061 return env
->regs
[10];
3063 unlock_user_struct(frame
, frame_addr
, 0);
3064 force_sig(TARGET_SIGSEGV
);
3067 long do_rt_sigreturn(CPUState
*env
)
3069 fprintf(stderr
, "CRIS do_rt_sigreturn: not implemented\n");
3070 return -TARGET_ENOSYS
;
3075 static void setup_frame(int sig
, struct target_sigaction
*ka
,
3076 target_sigset_t
*set
, CPUState
*env
)
3078 fprintf(stderr
, "setup_frame: not implemented\n");
3081 static void setup_rt_frame(int sig
, struct target_sigaction
*ka
,
3082 target_siginfo_t
*info
,
3083 target_sigset_t
*set
, CPUState
*env
)
3085 fprintf(stderr
, "setup_rt_frame: not implemented\n");
3088 long do_sigreturn(CPUState
*env
)
3090 fprintf(stderr
, "do_sigreturn: not implemented\n");
3091 return -TARGET_ENOSYS
;
3094 long do_rt_sigreturn(CPUState
*env
)
3096 fprintf(stderr
, "do_rt_sigreturn: not implemented\n");
3097 return -TARGET_ENOSYS
;
3102 void process_pending_signals(CPUState
*cpu_env
)
3106 sigset_t set
, old_set
;
3107 target_sigset_t target_old_set
;
3108 struct emulated_sigtable
*k
;
3109 struct target_sigaction
*sa
;
3111 TaskState
*ts
= cpu_env
->opaque
;
3113 if (!ts
->signal_pending
)
3116 /* FIXME: This is not threadsafe. */
3118 for(sig
= 1; sig
<= TARGET_NSIG
; sig
++) {
3123 /* if no signal is pending, just return */
3124 ts
->signal_pending
= 0;
3129 fprintf(stderr
, "qemu: process signal %d\n", sig
);
3131 /* dequeue signal */
3137 sig
= gdb_handlesig (cpu_env
, sig
);
3140 handler
= TARGET_SIG_IGN
;
3142 sa
= &sigact_table
[sig
- 1];
3143 handler
= sa
->_sa_handler
;
3146 if (handler
== TARGET_SIG_DFL
) {
3147 /* default handler : ignore some signal. The other are job control or fatal */
3148 if (sig
== TARGET_SIGTSTP
|| sig
== TARGET_SIGTTIN
|| sig
== TARGET_SIGTTOU
) {
3149 kill(getpid(),SIGSTOP
);
3150 } else if (sig
!= TARGET_SIGCHLD
&&
3151 sig
!= TARGET_SIGURG
&&
3152 sig
!= TARGET_SIGWINCH
&&
3153 sig
!= TARGET_SIGCONT
) {
3156 } else if (handler
== TARGET_SIG_IGN
) {
3158 } else if (handler
== TARGET_SIG_ERR
) {
3161 /* compute the blocked signals during the handler execution */
3162 target_to_host_sigset(&set
, &sa
->sa_mask
);
3163 /* SA_NODEFER indicates that the current signal should not be
3164 blocked during the handler */
3165 if (!(sa
->sa_flags
& TARGET_SA_NODEFER
))
3166 sigaddset(&set
, target_to_host_signal(sig
));
3168 /* block signals in the handler using Linux */
3169 sigprocmask(SIG_BLOCK
, &set
, &old_set
);
3170 /* save the previous blocked signal state to restore it at the
3171 end of the signal execution (see do_sigreturn) */
3172 host_to_target_sigset_internal(&target_old_set
, &old_set
);
3174 /* if the CPU is in VM86 mode, we restore the 32 bit values */
3175 #if defined(TARGET_I386) && !defined(TARGET_X86_64)
3177 CPUX86State
*env
= cpu_env
;
3178 if (env
->eflags
& VM_MASK
)
3179 save_v86_state(env
);
3182 /* prepare the stack frame of the virtual CPU */
3183 if (sa
->sa_flags
& TARGET_SA_SIGINFO
)
3184 setup_rt_frame(sig
, sa
, &q
->info
, &target_old_set
, cpu_env
);
3186 setup_frame(sig
, sa
, &target_old_set
, cpu_env
);
3187 if (sa
->sa_flags
& TARGET_SA_RESETHAND
)
3188 sa
->_sa_handler
= TARGET_SIG_DFL
;
3191 free_sigqueue(cpu_env
, q
);