2 * Emulation of Linux signals
4 * Copyright (c) 2003 Fabrice Bellard
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, see <http://www.gnu.org/licenses/>.
27 #include <sys/ucontext.h>
28 #include <sys/resource.h>
31 #include "qemu-common.h"
32 #include "target_signal.h"
34 //#define DEBUG_SIGNAL
36 static struct target_sigaltstack target_sigaltstack_used
= {
39 .ss_flags
= TARGET_SS_DISABLE
,
42 static struct target_sigaction sigact_table
[TARGET_NSIG
];
44 static void host_signal_handler(int host_signum
, siginfo_t
*info
,
47 static uint8_t host_to_target_signal_table
[_NSIG
] = {
48 [SIGHUP
] = TARGET_SIGHUP
,
49 [SIGINT
] = TARGET_SIGINT
,
50 [SIGQUIT
] = TARGET_SIGQUIT
,
51 [SIGILL
] = TARGET_SIGILL
,
52 [SIGTRAP
] = TARGET_SIGTRAP
,
53 [SIGABRT
] = TARGET_SIGABRT
,
54 /* [SIGIOT] = TARGET_SIGIOT,*/
55 [SIGBUS
] = TARGET_SIGBUS
,
56 [SIGFPE
] = TARGET_SIGFPE
,
57 [SIGKILL
] = TARGET_SIGKILL
,
58 [SIGUSR1
] = TARGET_SIGUSR1
,
59 [SIGSEGV
] = TARGET_SIGSEGV
,
60 [SIGUSR2
] = TARGET_SIGUSR2
,
61 [SIGPIPE
] = TARGET_SIGPIPE
,
62 [SIGALRM
] = TARGET_SIGALRM
,
63 [SIGTERM
] = TARGET_SIGTERM
,
65 [SIGSTKFLT
] = TARGET_SIGSTKFLT
,
67 [SIGCHLD
] = TARGET_SIGCHLD
,
68 [SIGCONT
] = TARGET_SIGCONT
,
69 [SIGSTOP
] = TARGET_SIGSTOP
,
70 [SIGTSTP
] = TARGET_SIGTSTP
,
71 [SIGTTIN
] = TARGET_SIGTTIN
,
72 [SIGTTOU
] = TARGET_SIGTTOU
,
73 [SIGURG
] = TARGET_SIGURG
,
74 [SIGXCPU
] = TARGET_SIGXCPU
,
75 [SIGXFSZ
] = TARGET_SIGXFSZ
,
76 [SIGVTALRM
] = TARGET_SIGVTALRM
,
77 [SIGPROF
] = TARGET_SIGPROF
,
78 [SIGWINCH
] = TARGET_SIGWINCH
,
79 [SIGIO
] = TARGET_SIGIO
,
80 [SIGPWR
] = TARGET_SIGPWR
,
81 [SIGSYS
] = TARGET_SIGSYS
,
82 /* next signals stay the same */
83 /* Nasty hack: Reverse SIGRTMIN and SIGRTMAX to avoid overlap with
84 host libpthread signals. This assumes noone actually uses SIGRTMAX :-/
85 To fix this properly we need to do manual signal delivery multiplexed
86 over a single host signal. */
87 [__SIGRTMIN
] = __SIGRTMAX
,
88 [__SIGRTMAX
] = __SIGRTMIN
,
90 static uint8_t target_to_host_signal_table
[_NSIG
];
92 static inline int on_sig_stack(unsigned long sp
)
94 return (sp
- target_sigaltstack_used
.ss_sp
95 < target_sigaltstack_used
.ss_size
);
98 static inline int sas_ss_flags(unsigned long sp
)
100 return (target_sigaltstack_used
.ss_size
== 0 ? SS_DISABLE
101 : on_sig_stack(sp
) ? SS_ONSTACK
: 0);
104 int host_to_target_signal(int sig
)
108 return host_to_target_signal_table
[sig
];
111 int target_to_host_signal(int sig
)
115 return target_to_host_signal_table
[sig
];
118 static inline void target_sigemptyset(target_sigset_t
*set
)
120 memset(set
, 0, sizeof(*set
));
123 static inline void target_sigaddset(target_sigset_t
*set
, int signum
)
126 abi_ulong mask
= (abi_ulong
)1 << (signum
% TARGET_NSIG_BPW
);
127 set
->sig
[signum
/ TARGET_NSIG_BPW
] |= mask
;
130 static inline int target_sigismember(const target_sigset_t
*set
, int signum
)
133 abi_ulong mask
= (abi_ulong
)1 << (signum
% TARGET_NSIG_BPW
);
134 return ((set
->sig
[signum
/ TARGET_NSIG_BPW
] & mask
) != 0);
137 static void host_to_target_sigset_internal(target_sigset_t
*d
,
141 target_sigemptyset(d
);
142 for (i
= 1; i
<= TARGET_NSIG
; i
++) {
143 if (sigismember(s
, i
)) {
144 target_sigaddset(d
, host_to_target_signal(i
));
149 void host_to_target_sigset(target_sigset_t
*d
, const sigset_t
*s
)
154 host_to_target_sigset_internal(&d1
, s
);
155 for(i
= 0;i
< TARGET_NSIG_WORDS
; i
++)
156 d
->sig
[i
] = tswapl(d1
.sig
[i
]);
159 static void target_to_host_sigset_internal(sigset_t
*d
,
160 const target_sigset_t
*s
)
164 for (i
= 1; i
<= TARGET_NSIG
; i
++) {
165 if (target_sigismember(s
, i
)) {
166 sigaddset(d
, target_to_host_signal(i
));
171 void target_to_host_sigset(sigset_t
*d
, const target_sigset_t
*s
)
176 for(i
= 0;i
< TARGET_NSIG_WORDS
; i
++)
177 s1
.sig
[i
] = tswapl(s
->sig
[i
]);
178 target_to_host_sigset_internal(d
, &s1
);
181 void host_to_target_old_sigset(abi_ulong
*old_sigset
,
182 const sigset_t
*sigset
)
185 host_to_target_sigset(&d
, sigset
);
186 *old_sigset
= d
.sig
[0];
189 void target_to_host_old_sigset(sigset_t
*sigset
,
190 const abi_ulong
*old_sigset
)
195 d
.sig
[0] = *old_sigset
;
196 for(i
= 1;i
< TARGET_NSIG_WORDS
; i
++)
198 target_to_host_sigset(sigset
, &d
);
201 /* siginfo conversion */
203 static inline void host_to_target_siginfo_noswap(target_siginfo_t
*tinfo
,
204 const siginfo_t
*info
)
207 sig
= host_to_target_signal(info
->si_signo
);
208 tinfo
->si_signo
= sig
;
210 tinfo
->si_code
= info
->si_code
;
211 if (sig
== SIGILL
|| sig
== SIGFPE
|| sig
== SIGSEGV
||
212 sig
== SIGBUS
|| sig
== SIGTRAP
) {
213 /* should never come here, but who knows. The information for
214 the target is irrelevant */
215 tinfo
->_sifields
._sigfault
._addr
= 0;
216 } else if (sig
== SIGIO
) {
217 tinfo
->_sifields
._sigpoll
._fd
= info
->si_fd
;
218 } else if (sig
>= TARGET_SIGRTMIN
) {
219 tinfo
->_sifields
._rt
._pid
= info
->si_pid
;
220 tinfo
->_sifields
._rt
._uid
= info
->si_uid
;
221 /* XXX: potential problem if 64 bit */
222 tinfo
->_sifields
._rt
._sigval
.sival_ptr
=
223 (abi_ulong
)(unsigned long)info
->si_value
.sival_ptr
;
227 static void tswap_siginfo(target_siginfo_t
*tinfo
,
228 const target_siginfo_t
*info
)
231 sig
= info
->si_signo
;
232 tinfo
->si_signo
= tswap32(sig
);
233 tinfo
->si_errno
= tswap32(info
->si_errno
);
234 tinfo
->si_code
= tswap32(info
->si_code
);
235 if (sig
== SIGILL
|| sig
== SIGFPE
|| sig
== SIGSEGV
||
236 sig
== SIGBUS
|| sig
== SIGTRAP
) {
237 tinfo
->_sifields
._sigfault
._addr
=
238 tswapl(info
->_sifields
._sigfault
._addr
);
239 } else if (sig
== SIGIO
) {
240 tinfo
->_sifields
._sigpoll
._fd
= tswap32(info
->_sifields
._sigpoll
._fd
);
241 } else if (sig
>= TARGET_SIGRTMIN
) {
242 tinfo
->_sifields
._rt
._pid
= tswap32(info
->_sifields
._rt
._pid
);
243 tinfo
->_sifields
._rt
._uid
= tswap32(info
->_sifields
._rt
._uid
);
244 tinfo
->_sifields
._rt
._sigval
.sival_ptr
=
245 tswapl(info
->_sifields
._rt
._sigval
.sival_ptr
);
250 void host_to_target_siginfo(target_siginfo_t
*tinfo
, const siginfo_t
*info
)
252 host_to_target_siginfo_noswap(tinfo
, info
);
253 tswap_siginfo(tinfo
, tinfo
);
256 /* XXX: we support only POSIX RT signals are used. */
257 /* XXX: find a solution for 64 bit (additional malloced data is needed) */
258 void target_to_host_siginfo(siginfo_t
*info
, const target_siginfo_t
*tinfo
)
260 info
->si_signo
= tswap32(tinfo
->si_signo
);
261 info
->si_errno
= tswap32(tinfo
->si_errno
);
262 info
->si_code
= tswap32(tinfo
->si_code
);
263 info
->si_pid
= tswap32(tinfo
->_sifields
._rt
._pid
);
264 info
->si_uid
= tswap32(tinfo
->_sifields
._rt
._uid
);
265 info
->si_value
.sival_ptr
=
266 (void *)(long)tswapl(tinfo
->_sifields
._rt
._sigval
.sival_ptr
);
269 static int fatal_signal (int sig
)
274 case TARGET_SIGWINCH
:
275 /* Ignored by default. */
282 /* Job control signals. */
289 /* returns 1 if given signal should dump core if not handled */
290 static int core_dump_signal(int sig
)
306 void signal_init(void)
308 struct sigaction act
;
309 struct sigaction oact
;
313 /* generate signal conversion tables */
314 for(i
= 1; i
< _NSIG
; i
++) {
315 if (host_to_target_signal_table
[i
] == 0)
316 host_to_target_signal_table
[i
] = i
;
318 for(i
= 1; i
< _NSIG
; i
++) {
319 j
= host_to_target_signal_table
[i
];
320 target_to_host_signal_table
[j
] = i
;
323 /* set all host signal handlers. ALL signals are blocked during
324 the handlers to serialize them. */
325 memset(sigact_table
, 0, sizeof(sigact_table
));
327 sigfillset(&act
.sa_mask
);
328 act
.sa_flags
= SA_SIGINFO
;
329 act
.sa_sigaction
= host_signal_handler
;
330 for(i
= 1; i
<= TARGET_NSIG
; i
++) {
331 host_sig
= target_to_host_signal(i
);
332 sigaction(host_sig
, NULL
, &oact
);
333 if (oact
.sa_sigaction
== (void *)SIG_IGN
) {
334 sigact_table
[i
- 1]._sa_handler
= TARGET_SIG_IGN
;
335 } else if (oact
.sa_sigaction
== (void *)SIG_DFL
) {
336 sigact_table
[i
- 1]._sa_handler
= TARGET_SIG_DFL
;
338 /* If there's already a handler installed then something has
339 gone horribly wrong, so don't even try to handle that case. */
340 /* Install some handlers for our own use. We need at least
341 SIGSEGV and SIGBUS, to detect exceptions. We can not just
342 trap all signals because it affects syscall interrupt
343 behavior. But do trap all default-fatal signals. */
344 if (fatal_signal (i
))
345 sigaction(host_sig
, &act
, NULL
);
349 /* signal queue handling */
351 static inline struct sigqueue
*alloc_sigqueue(CPUState
*env
)
353 TaskState
*ts
= env
->opaque
;
354 struct sigqueue
*q
= ts
->first_free
;
357 ts
->first_free
= q
->next
;
361 static inline void free_sigqueue(CPUState
*env
, struct sigqueue
*q
)
363 TaskState
*ts
= env
->opaque
;
364 q
->next
= ts
->first_free
;
368 /* abort execution with signal */
369 static void QEMU_NORETURN
force_sig(int target_sig
)
371 TaskState
*ts
= (TaskState
*)thread_env
->opaque
;
372 int host_sig
, core_dumped
= 0;
373 struct sigaction act
;
374 host_sig
= target_to_host_signal(target_sig
);
375 gdb_signalled(thread_env
, target_sig
);
377 /* dump core if supported by target binary format */
378 if (core_dump_signal(target_sig
) && (ts
->bprm
->core_dump
!= NULL
)) {
381 ((*ts
->bprm
->core_dump
)(target_sig
, thread_env
) == 0);
384 /* we already dumped the core of target process, we don't want
385 * a coredump of qemu itself */
386 struct rlimit nodump
;
387 getrlimit(RLIMIT_CORE
, &nodump
);
389 setrlimit(RLIMIT_CORE
, &nodump
);
390 (void) fprintf(stderr
, "qemu: uncaught target signal %d (%s) - %s\n",
391 target_sig
, strsignal(host_sig
), "core dumped" );
394 /* The proper exit code for dieing from an uncaught signal is
395 * -<signal>. The kernel doesn't allow exit() or _exit() to pass
396 * a negative value. To get the proper exit code we need to
397 * actually die from an uncaught signal. Here the default signal
398 * handler is installed, we send ourself a signal and we wait for
400 sigfillset(&act
.sa_mask
);
401 act
.sa_handler
= SIG_DFL
;
402 sigaction(host_sig
, &act
, NULL
);
404 /* For some reason raise(host_sig) doesn't send the signal when
405 * statically linked on x86-64. */
406 kill(getpid(), host_sig
);
408 /* Make sure the signal isn't masked (just reuse the mask inside
410 sigdelset(&act
.sa_mask
, host_sig
);
411 sigsuspend(&act
.sa_mask
);
417 /* queue a signal so that it will be send to the virtual CPU as soon
419 int queue_signal(CPUState
*env
, int sig
, target_siginfo_t
*info
)
421 TaskState
*ts
= env
->opaque
;
422 struct emulated_sigtable
*k
;
423 struct sigqueue
*q
, **pq
;
427 #if defined(DEBUG_SIGNAL)
428 fprintf(stderr
, "queue_signal: sig=%d\n",
431 k
= &ts
->sigtab
[sig
- 1];
432 queue
= gdb_queuesig ();
433 handler
= sigact_table
[sig
- 1]._sa_handler
;
434 if (!queue
&& handler
== TARGET_SIG_DFL
) {
435 if (sig
== TARGET_SIGTSTP
|| sig
== TARGET_SIGTTIN
|| sig
== TARGET_SIGTTOU
) {
436 kill(getpid(),SIGSTOP
);
439 /* default handler : ignore some signal. The other are fatal */
440 if (sig
!= TARGET_SIGCHLD
&&
441 sig
!= TARGET_SIGURG
&&
442 sig
!= TARGET_SIGWINCH
&&
443 sig
!= TARGET_SIGCONT
) {
446 return 0; /* indicate ignored */
448 } else if (!queue
&& handler
== TARGET_SIG_IGN
) {
451 } else if (!queue
&& handler
== TARGET_SIG_ERR
) {
455 if (sig
< TARGET_SIGRTMIN
) {
456 /* if non real time signal, we queue exactly one signal */
466 q
= alloc_sigqueue(env
);
477 /* signal that a new signal is pending */
478 ts
->signal_pending
= 1;
479 return 1; /* indicates that the signal was queued */
483 static void host_signal_handler(int host_signum
, siginfo_t
*info
,
487 target_siginfo_t tinfo
;
489 /* the CPU emulator uses some host signals to detect exceptions,
490 we forward to it some signals */
491 if ((host_signum
== SIGSEGV
|| host_signum
== SIGBUS
)
492 && info
->si_code
> 0) {
493 if (cpu_signal_handler(host_signum
, info
, puc
))
497 /* get target signal number */
498 sig
= host_to_target_signal(host_signum
);
499 if (sig
< 1 || sig
> TARGET_NSIG
)
501 #if defined(DEBUG_SIGNAL)
502 fprintf(stderr
, "qemu: got signal %d\n", sig
);
504 host_to_target_siginfo_noswap(&tinfo
, info
);
505 if (queue_signal(thread_env
, sig
, &tinfo
) == 1) {
506 /* interrupt the virtual CPU as soon as possible */
507 cpu_exit(thread_env
);
511 /* do_sigaltstack() returns target values and errnos. */
512 /* compare linux/kernel/signal.c:do_sigaltstack() */
513 abi_long
do_sigaltstack(abi_ulong uss_addr
, abi_ulong uoss_addr
, abi_ulong sp
)
516 struct target_sigaltstack oss
;
518 /* XXX: test errors */
521 __put_user(target_sigaltstack_used
.ss_sp
, &oss
.ss_sp
);
522 __put_user(target_sigaltstack_used
.ss_size
, &oss
.ss_size
);
523 __put_user(sas_ss_flags(sp
), &oss
.ss_flags
);
528 struct target_sigaltstack
*uss
;
529 struct target_sigaltstack ss
;
531 ret
= -TARGET_EFAULT
;
532 if (!lock_user_struct(VERIFY_READ
, uss
, uss_addr
, 1)
533 || __get_user(ss
.ss_sp
, &uss
->ss_sp
)
534 || __get_user(ss
.ss_size
, &uss
->ss_size
)
535 || __get_user(ss
.ss_flags
, &uss
->ss_flags
))
537 unlock_user_struct(uss
, uss_addr
, 0);
540 if (on_sig_stack(sp
))
543 ret
= -TARGET_EINVAL
;
544 if (ss
.ss_flags
!= TARGET_SS_DISABLE
545 && ss
.ss_flags
!= TARGET_SS_ONSTACK
549 if (ss
.ss_flags
== TARGET_SS_DISABLE
) {
553 ret
= -TARGET_ENOMEM
;
554 if (ss
.ss_size
< MINSIGSTKSZ
)
558 target_sigaltstack_used
.ss_sp
= ss
.ss_sp
;
559 target_sigaltstack_used
.ss_size
= ss
.ss_size
;
563 ret
= -TARGET_EFAULT
;
564 if (copy_to_user(uoss_addr
, &oss
, sizeof(oss
)))
573 /* do_sigaction() return host values and errnos */
574 int do_sigaction(int sig
, const struct target_sigaction
*act
,
575 struct target_sigaction
*oact
)
577 struct target_sigaction
*k
;
578 struct sigaction act1
;
582 if (sig
< 1 || sig
> TARGET_NSIG
|| sig
== TARGET_SIGKILL
|| sig
== TARGET_SIGSTOP
)
584 k
= &sigact_table
[sig
- 1];
585 #if defined(DEBUG_SIGNAL)
586 fprintf(stderr
, "sigaction sig=%d act=0x%p, oact=0x%p\n",
590 oact
->_sa_handler
= tswapl(k
->_sa_handler
);
591 oact
->sa_flags
= tswapl(k
->sa_flags
);
592 #if !defined(TARGET_MIPS)
593 oact
->sa_restorer
= tswapl(k
->sa_restorer
);
595 oact
->sa_mask
= k
->sa_mask
;
598 /* FIXME: This is not threadsafe. */
599 k
->_sa_handler
= tswapl(act
->_sa_handler
);
600 k
->sa_flags
= tswapl(act
->sa_flags
);
601 #if !defined(TARGET_MIPS)
602 k
->sa_restorer
= tswapl(act
->sa_restorer
);
604 k
->sa_mask
= act
->sa_mask
;
606 /* we update the host linux signal state */
607 host_sig
= target_to_host_signal(sig
);
608 if (host_sig
!= SIGSEGV
&& host_sig
!= SIGBUS
) {
609 sigfillset(&act1
.sa_mask
);
610 act1
.sa_flags
= SA_SIGINFO
;
611 if (k
->sa_flags
& TARGET_SA_RESTART
)
612 act1
.sa_flags
|= SA_RESTART
;
613 /* NOTE: it is important to update the host kernel signal
614 ignore state to avoid getting unexpected interrupted
616 if (k
->_sa_handler
== TARGET_SIG_IGN
) {
617 act1
.sa_sigaction
= (void *)SIG_IGN
;
618 } else if (k
->_sa_handler
== TARGET_SIG_DFL
) {
619 if (fatal_signal (sig
))
620 act1
.sa_sigaction
= host_signal_handler
;
622 act1
.sa_sigaction
= (void *)SIG_DFL
;
624 act1
.sa_sigaction
= host_signal_handler
;
626 ret
= sigaction(host_sig
, &act1
, NULL
);
632 static inline int copy_siginfo_to_user(target_siginfo_t
*tinfo
,
633 const target_siginfo_t
*info
)
635 tswap_siginfo(tinfo
, info
);
639 static inline int current_exec_domain_sig(int sig
)
641 return /* current->exec_domain && current->exec_domain->signal_invmap
642 && sig < 32 ? current->exec_domain->signal_invmap[sig] : */ sig
;
645 #if defined(TARGET_I386) && TARGET_ABI_BITS == 32
647 /* from the Linux kernel */
649 struct target_fpreg
{
650 uint16_t significand
[4];
654 struct target_fpxreg
{
655 uint16_t significand
[4];
660 struct target_xmmreg
{
661 abi_ulong element
[4];
664 struct target_fpstate
{
665 /* Regular FPU environment */
673 struct target_fpreg _st
[8];
675 uint16_t magic
; /* 0xffff = regular FPU data only */
677 /* FXSR FPU environment */
678 abi_ulong _fxsr_env
[6]; /* FXSR FPU env is ignored */
681 struct target_fpxreg _fxsr_st
[8]; /* FXSR FPU reg data is ignored */
682 struct target_xmmreg _xmm
[8];
683 abi_ulong padding
[56];
686 #define X86_FXSR_MAGIC 0x0000
688 struct target_sigcontext
{
706 abi_ulong esp_at_signal
;
708 abi_ulong fpstate
; /* pointer */
713 struct target_ucontext
{
716 target_stack_t tuc_stack
;
717 struct target_sigcontext tuc_mcontext
;
718 target_sigset_t tuc_sigmask
; /* mask last for extensibility */
725 struct target_sigcontext sc
;
726 struct target_fpstate fpstate
;
727 abi_ulong extramask
[TARGET_NSIG_WORDS
-1];
737 struct target_siginfo info
;
738 struct target_ucontext uc
;
739 struct target_fpstate fpstate
;
744 * Set up a signal frame.
747 /* XXX: save x87 state */
749 setup_sigcontext(struct target_sigcontext
*sc
, struct target_fpstate
*fpstate
,
750 CPUX86State
*env
, abi_ulong mask
, abi_ulong fpstate_addr
)
755 /* already locked in setup_frame() */
756 err
|= __put_user(env
->segs
[R_GS
].selector
, (unsigned int *)&sc
->gs
);
757 err
|= __put_user(env
->segs
[R_FS
].selector
, (unsigned int *)&sc
->fs
);
758 err
|= __put_user(env
->segs
[R_ES
].selector
, (unsigned int *)&sc
->es
);
759 err
|= __put_user(env
->segs
[R_DS
].selector
, (unsigned int *)&sc
->ds
);
760 err
|= __put_user(env
->regs
[R_EDI
], &sc
->edi
);
761 err
|= __put_user(env
->regs
[R_ESI
], &sc
->esi
);
762 err
|= __put_user(env
->regs
[R_EBP
], &sc
->ebp
);
763 err
|= __put_user(env
->regs
[R_ESP
], &sc
->esp
);
764 err
|= __put_user(env
->regs
[R_EBX
], &sc
->ebx
);
765 err
|= __put_user(env
->regs
[R_EDX
], &sc
->edx
);
766 err
|= __put_user(env
->regs
[R_ECX
], &sc
->ecx
);
767 err
|= __put_user(env
->regs
[R_EAX
], &sc
->eax
);
768 err
|= __put_user(env
->exception_index
, &sc
->trapno
);
769 err
|= __put_user(env
->error_code
, &sc
->err
);
770 err
|= __put_user(env
->eip
, &sc
->eip
);
771 err
|= __put_user(env
->segs
[R_CS
].selector
, (unsigned int *)&sc
->cs
);
772 err
|= __put_user(env
->eflags
, &sc
->eflags
);
773 err
|= __put_user(env
->regs
[R_ESP
], &sc
->esp_at_signal
);
774 err
|= __put_user(env
->segs
[R_SS
].selector
, (unsigned int *)&sc
->ss
);
776 cpu_x86_fsave(env
, fpstate_addr
, 1);
777 fpstate
->status
= fpstate
->sw
;
779 err
|= __put_user(magic
, &fpstate
->magic
);
780 err
|= __put_user(fpstate_addr
, &sc
->fpstate
);
782 /* non-iBCS2 extensions.. */
783 err
|= __put_user(mask
, &sc
->oldmask
);
784 err
|= __put_user(env
->cr
[2], &sc
->cr2
);
789 * Determine which stack to use..
792 static inline abi_ulong
793 get_sigframe(struct target_sigaction
*ka
, CPUX86State
*env
, size_t frame_size
)
797 /* Default to using normal stack */
798 esp
= env
->regs
[R_ESP
];
799 /* This is the X/Open sanctioned signal stack switching. */
800 if (ka
->sa_flags
& TARGET_SA_ONSTACK
) {
801 if (sas_ss_flags(esp
) == 0)
802 esp
= target_sigaltstack_used
.ss_sp
+ target_sigaltstack_used
.ss_size
;
805 /* This is the legacy signal stack switching. */
807 if ((env
->segs
[R_SS
].selector
& 0xffff) != __USER_DS
&&
808 !(ka
->sa_flags
& TARGET_SA_RESTORER
) &&
810 esp
= (unsigned long) ka
->sa_restorer
;
812 return (esp
- frame_size
) & -8ul;
815 /* compare linux/arch/i386/kernel/signal.c:setup_frame() */
816 static void setup_frame(int sig
, struct target_sigaction
*ka
,
817 target_sigset_t
*set
, CPUX86State
*env
)
819 abi_ulong frame_addr
;
820 struct sigframe
*frame
;
823 frame_addr
= get_sigframe(ka
, env
, sizeof(*frame
));
825 if (!lock_user_struct(VERIFY_WRITE
, frame
, frame_addr
, 0))
828 err
|= __put_user(current_exec_domain_sig(sig
),
833 setup_sigcontext(&frame
->sc
, &frame
->fpstate
, env
, set
->sig
[0],
834 frame_addr
+ offsetof(struct sigframe
, fpstate
));
838 for(i
= 1; i
< TARGET_NSIG_WORDS
; i
++) {
839 if (__put_user(set
->sig
[i
], &frame
->extramask
[i
- 1]))
843 /* Set up to return from userspace. If provided, use a stub
844 already in userspace. */
845 if (ka
->sa_flags
& TARGET_SA_RESTORER
) {
846 err
|= __put_user(ka
->sa_restorer
, &frame
->pretcode
);
849 abi_ulong retcode_addr
;
850 retcode_addr
= frame_addr
+ offsetof(struct sigframe
, retcode
);
851 err
|= __put_user(retcode_addr
, &frame
->pretcode
);
852 /* This is popl %eax ; movl $,%eax ; int $0x80 */
854 err
|= __put_user(val16
, (uint16_t *)(frame
->retcode
+0));
855 err
|= __put_user(TARGET_NR_sigreturn
, (int *)(frame
->retcode
+2));
857 err
|= __put_user(val16
, (uint16_t *)(frame
->retcode
+6));
863 /* Set up registers for signal handler */
864 env
->regs
[R_ESP
] = frame_addr
;
865 env
->eip
= ka
->_sa_handler
;
867 cpu_x86_load_seg(env
, R_DS
, __USER_DS
);
868 cpu_x86_load_seg(env
, R_ES
, __USER_DS
);
869 cpu_x86_load_seg(env
, R_SS
, __USER_DS
);
870 cpu_x86_load_seg(env
, R_CS
, __USER_CS
);
871 env
->eflags
&= ~TF_MASK
;
873 unlock_user_struct(frame
, frame_addr
, 1);
878 unlock_user_struct(frame
, frame_addr
, 1);
879 if (sig
== TARGET_SIGSEGV
)
880 ka
->_sa_handler
= TARGET_SIG_DFL
;
881 force_sig(TARGET_SIGSEGV
/* , current */);
884 /* compare linux/arch/i386/kernel/signal.c:setup_rt_frame() */
885 static void setup_rt_frame(int sig
, struct target_sigaction
*ka
,
886 target_siginfo_t
*info
,
887 target_sigset_t
*set
, CPUX86State
*env
)
889 abi_ulong frame_addr
, addr
;
890 struct rt_sigframe
*frame
;
893 frame_addr
= get_sigframe(ka
, env
, sizeof(*frame
));
895 if (!lock_user_struct(VERIFY_WRITE
, frame
, frame_addr
, 0))
898 err
|= __put_user(current_exec_domain_sig(sig
),
900 addr
= frame_addr
+ offsetof(struct rt_sigframe
, info
);
901 err
|= __put_user(addr
, &frame
->pinfo
);
902 addr
= frame_addr
+ offsetof(struct rt_sigframe
, uc
);
903 err
|= __put_user(addr
, &frame
->puc
);
904 err
|= copy_siginfo_to_user(&frame
->info
, info
);
908 /* Create the ucontext. */
909 err
|= __put_user(0, &frame
->uc
.tuc_flags
);
910 err
|= __put_user(0, &frame
->uc
.tuc_link
);
911 err
|= __put_user(target_sigaltstack_used
.ss_sp
,
912 &frame
->uc
.tuc_stack
.ss_sp
);
913 err
|= __put_user(sas_ss_flags(get_sp_from_cpustate(env
)),
914 &frame
->uc
.tuc_stack
.ss_flags
);
915 err
|= __put_user(target_sigaltstack_used
.ss_size
,
916 &frame
->uc
.tuc_stack
.ss_size
);
917 err
|= setup_sigcontext(&frame
->uc
.tuc_mcontext
, &frame
->fpstate
,
919 frame_addr
+ offsetof(struct rt_sigframe
, fpstate
));
920 for(i
= 0; i
< TARGET_NSIG_WORDS
; i
++) {
921 if (__put_user(set
->sig
[i
], &frame
->uc
.tuc_sigmask
.sig
[i
]))
925 /* Set up to return from userspace. If provided, use a stub
926 already in userspace. */
927 if (ka
->sa_flags
& TARGET_SA_RESTORER
) {
928 err
|= __put_user(ka
->sa_restorer
, &frame
->pretcode
);
931 addr
= frame_addr
+ offsetof(struct rt_sigframe
, retcode
);
932 err
|= __put_user(addr
, &frame
->pretcode
);
933 /* This is movl $,%eax ; int $0x80 */
934 err
|= __put_user(0xb8, (char *)(frame
->retcode
+0));
935 err
|= __put_user(TARGET_NR_rt_sigreturn
, (int *)(frame
->retcode
+1));
937 err
|= __put_user(val16
, (uint16_t *)(frame
->retcode
+5));
943 /* Set up registers for signal handler */
944 env
->regs
[R_ESP
] = frame_addr
;
945 env
->eip
= ka
->_sa_handler
;
947 cpu_x86_load_seg(env
, R_DS
, __USER_DS
);
948 cpu_x86_load_seg(env
, R_ES
, __USER_DS
);
949 cpu_x86_load_seg(env
, R_SS
, __USER_DS
);
950 cpu_x86_load_seg(env
, R_CS
, __USER_CS
);
951 env
->eflags
&= ~TF_MASK
;
953 unlock_user_struct(frame
, frame_addr
, 1);
958 unlock_user_struct(frame
, frame_addr
, 1);
959 if (sig
== TARGET_SIGSEGV
)
960 ka
->_sa_handler
= TARGET_SIG_DFL
;
961 force_sig(TARGET_SIGSEGV
/* , current */);
965 restore_sigcontext(CPUX86State
*env
, struct target_sigcontext
*sc
, int *peax
)
967 unsigned int err
= 0;
968 abi_ulong fpstate_addr
;
969 unsigned int tmpflags
;
971 cpu_x86_load_seg(env
, R_GS
, tswap16(sc
->gs
));
972 cpu_x86_load_seg(env
, R_FS
, tswap16(sc
->fs
));
973 cpu_x86_load_seg(env
, R_ES
, tswap16(sc
->es
));
974 cpu_x86_load_seg(env
, R_DS
, tswap16(sc
->ds
));
976 env
->regs
[R_EDI
] = tswapl(sc
->edi
);
977 env
->regs
[R_ESI
] = tswapl(sc
->esi
);
978 env
->regs
[R_EBP
] = tswapl(sc
->ebp
);
979 env
->regs
[R_ESP
] = tswapl(sc
->esp
);
980 env
->regs
[R_EBX
] = tswapl(sc
->ebx
);
981 env
->regs
[R_EDX
] = tswapl(sc
->edx
);
982 env
->regs
[R_ECX
] = tswapl(sc
->ecx
);
983 env
->eip
= tswapl(sc
->eip
);
985 cpu_x86_load_seg(env
, R_CS
, lduw(&sc
->cs
) | 3);
986 cpu_x86_load_seg(env
, R_SS
, lduw(&sc
->ss
) | 3);
988 tmpflags
= tswapl(sc
->eflags
);
989 env
->eflags
= (env
->eflags
& ~0x40DD5) | (tmpflags
& 0x40DD5);
990 // regs->orig_eax = -1; /* disable syscall checks */
992 fpstate_addr
= tswapl(sc
->fpstate
);
993 if (fpstate_addr
!= 0) {
994 if (!access_ok(VERIFY_READ
, fpstate_addr
,
995 sizeof(struct target_fpstate
)))
997 cpu_x86_frstor(env
, fpstate_addr
, 1);
1000 *peax
= tswapl(sc
->eax
);
1006 long do_sigreturn(CPUX86State
*env
)
1008 struct sigframe
*frame
;
1009 abi_ulong frame_addr
= env
->regs
[R_ESP
] - 8;
1010 target_sigset_t target_set
;
1014 #if defined(DEBUG_SIGNAL)
1015 fprintf(stderr
, "do_sigreturn\n");
1017 if (!lock_user_struct(VERIFY_READ
, frame
, frame_addr
, 1))
1019 /* set blocked signals */
1020 if (__get_user(target_set
.sig
[0], &frame
->sc
.oldmask
))
1022 for(i
= 1; i
< TARGET_NSIG_WORDS
; i
++) {
1023 if (__get_user(target_set
.sig
[i
], &frame
->extramask
[i
- 1]))
1027 target_to_host_sigset_internal(&set
, &target_set
);
1028 sigprocmask(SIG_SETMASK
, &set
, NULL
);
1030 /* restore registers */
1031 if (restore_sigcontext(env
, &frame
->sc
, &eax
))
1033 unlock_user_struct(frame
, frame_addr
, 0);
1037 unlock_user_struct(frame
, frame_addr
, 0);
1038 force_sig(TARGET_SIGSEGV
);
1042 long do_rt_sigreturn(CPUX86State
*env
)
1044 abi_ulong frame_addr
;
1045 struct rt_sigframe
*frame
;
1049 frame_addr
= env
->regs
[R_ESP
] - 4;
1050 if (!lock_user_struct(VERIFY_READ
, frame
, frame_addr
, 1))
1052 target_to_host_sigset(&set
, &frame
->uc
.tuc_sigmask
);
1053 sigprocmask(SIG_SETMASK
, &set
, NULL
);
1055 if (restore_sigcontext(env
, &frame
->uc
.tuc_mcontext
, &eax
))
1058 if (do_sigaltstack(frame_addr
+ offsetof(struct rt_sigframe
, uc
.tuc_stack
), 0,
1059 get_sp_from_cpustate(env
)) == -EFAULT
)
1062 unlock_user_struct(frame
, frame_addr
, 0);
1066 unlock_user_struct(frame
, frame_addr
, 0);
1067 force_sig(TARGET_SIGSEGV
);
1071 #elif defined(TARGET_ARM)
1073 struct target_sigcontext
{
1075 abi_ulong error_code
;
1094 abi_ulong fault_address
;
1097 struct target_ucontext_v1
{
1098 abi_ulong tuc_flags
;
1100 target_stack_t tuc_stack
;
1101 struct target_sigcontext tuc_mcontext
;
1102 target_sigset_t tuc_sigmask
; /* mask last for extensibility */
1105 struct target_ucontext_v2
{
1106 abi_ulong tuc_flags
;
1108 target_stack_t tuc_stack
;
1109 struct target_sigcontext tuc_mcontext
;
1110 target_sigset_t tuc_sigmask
; /* mask last for extensibility */
1111 char __unused
[128 - sizeof(target_sigset_t
)];
1112 abi_ulong tuc_regspace
[128] __attribute__((__aligned__(8)));
1115 struct target_user_vfp
{
1116 uint64_t fpregs
[32];
1120 struct target_user_vfp_exc
{
1126 struct target_vfp_sigframe
{
1129 struct target_user_vfp ufp
;
1130 struct target_user_vfp_exc ufp_exc
;
1131 } __attribute__((__aligned__(8)));
1133 #define TARGET_VFP_MAGIC 0x56465001
1137 struct target_sigcontext sc
;
1138 abi_ulong extramask
[TARGET_NSIG_WORDS
-1];
1144 struct target_ucontext_v2 uc
;
1148 struct rt_sigframe_v1
1152 struct target_siginfo info
;
1153 struct target_ucontext_v1 uc
;
1157 struct rt_sigframe_v2
1159 struct target_siginfo info
;
1160 struct target_ucontext_v2 uc
;
1164 #define TARGET_CONFIG_CPU_32 1
1167 * For ARM syscalls, we encode the syscall number into the instruction.
1169 #define SWI_SYS_SIGRETURN (0xef000000|(TARGET_NR_sigreturn + ARM_SYSCALL_BASE))
1170 #define SWI_SYS_RT_SIGRETURN (0xef000000|(TARGET_NR_rt_sigreturn + ARM_SYSCALL_BASE))
1173 * For Thumb syscalls, we pass the syscall number via r7. We therefore
1174 * need two 16-bit instructions.
1176 #define SWI_THUMB_SIGRETURN (0xdf00 << 16 | 0x2700 | (TARGET_NR_sigreturn))
1177 #define SWI_THUMB_RT_SIGRETURN (0xdf00 << 16 | 0x2700 | (TARGET_NR_rt_sigreturn))
1179 static const abi_ulong retcodes
[4] = {
1180 SWI_SYS_SIGRETURN
, SWI_THUMB_SIGRETURN
,
1181 SWI_SYS_RT_SIGRETURN
, SWI_THUMB_RT_SIGRETURN
1185 #define __get_user_error(x,p,e) __get_user(x, p)
1187 static inline int valid_user_regs(CPUState
*regs
)
1193 setup_sigcontext(struct target_sigcontext
*sc
, /*struct _fpstate *fpstate,*/
1194 CPUState
*env
, abi_ulong mask
)
1196 __put_user(env
->regs
[0], &sc
->arm_r0
);
1197 __put_user(env
->regs
[1], &sc
->arm_r1
);
1198 __put_user(env
->regs
[2], &sc
->arm_r2
);
1199 __put_user(env
->regs
[3], &sc
->arm_r3
);
1200 __put_user(env
->regs
[4], &sc
->arm_r4
);
1201 __put_user(env
->regs
[5], &sc
->arm_r5
);
1202 __put_user(env
->regs
[6], &sc
->arm_r6
);
1203 __put_user(env
->regs
[7], &sc
->arm_r7
);
1204 __put_user(env
->regs
[8], &sc
->arm_r8
);
1205 __put_user(env
->regs
[9], &sc
->arm_r9
);
1206 __put_user(env
->regs
[10], &sc
->arm_r10
);
1207 __put_user(env
->regs
[11], &sc
->arm_fp
);
1208 __put_user(env
->regs
[12], &sc
->arm_ip
);
1209 __put_user(env
->regs
[13], &sc
->arm_sp
);
1210 __put_user(env
->regs
[14], &sc
->arm_lr
);
1211 __put_user(env
->regs
[15], &sc
->arm_pc
);
1212 #ifdef TARGET_CONFIG_CPU_32
1213 __put_user(cpsr_read(env
), &sc
->arm_cpsr
);
1216 __put_user(/* current->thread.trap_no */ 0, &sc
->trap_no
);
1217 __put_user(/* current->thread.error_code */ 0, &sc
->error_code
);
1218 __put_user(/* current->thread.address */ 0, &sc
->fault_address
);
1219 __put_user(mask
, &sc
->oldmask
);
1222 static inline abi_ulong
1223 get_sigframe(struct target_sigaction
*ka
, CPUState
*regs
, int framesize
)
1225 unsigned long sp
= regs
->regs
[13];
1228 * This is the X/Open sanctioned signal stack switching.
1230 if ((ka
->sa_flags
& TARGET_SA_ONSTACK
) && !sas_ss_flags(sp
))
1231 sp
= target_sigaltstack_used
.ss_sp
+ target_sigaltstack_used
.ss_size
;
1233 * ATPCS B01 mandates 8-byte alignment
1235 return (sp
- framesize
) & ~7;
1239 setup_return(CPUState
*env
, struct target_sigaction
*ka
,
1240 abi_ulong
*rc
, abi_ulong frame_addr
, int usig
, abi_ulong rc_addr
)
1242 abi_ulong handler
= ka
->_sa_handler
;
1244 int thumb
= handler
& 1;
1246 if (ka
->sa_flags
& TARGET_SA_RESTORER
) {
1247 retcode
= ka
->sa_restorer
;
1249 unsigned int idx
= thumb
;
1251 if (ka
->sa_flags
& TARGET_SA_SIGINFO
)
1254 if (__put_user(retcodes
[idx
], rc
))
1257 flush_icache_range((abi_ulong
)rc
,
1258 (abi_ulong
)(rc
+ 1));
1260 retcode
= rc_addr
+ thumb
;
1263 env
->regs
[0] = usig
;
1264 env
->regs
[13] = frame_addr
;
1265 env
->regs
[14] = retcode
;
1266 env
->regs
[15] = handler
& (thumb
? ~1 : ~3);
1270 #ifdef TARGET_CONFIG_CPU_32
1278 static abi_ulong
*setup_sigframe_v2_vfp(abi_ulong
*regspace
, CPUState
*env
)
1281 struct target_vfp_sigframe
*vfpframe
;
1282 vfpframe
= (struct target_vfp_sigframe
*)regspace
;
1283 __put_user(TARGET_VFP_MAGIC
, &vfpframe
->magic
);
1284 __put_user(sizeof(*vfpframe
), &vfpframe
->size
);
1285 for (i
= 0; i
< 32; i
++) {
1286 __put_user(env
->vfp
.regs
[i
], &vfpframe
->ufp
.fpregs
[i
]);
1288 __put_user(vfp_get_fpscr(env
), &vfpframe
->ufp
.fpscr
);
1289 __put_user(env
->vfp
.xregs
[ARM_VFP_FPEXC
], &vfpframe
->ufp_exc
.fpexc
);
1290 __put_user(env
->vfp
.xregs
[ARM_VFP_FPINST
], &vfpframe
->ufp_exc
.fpinst
);
1291 __put_user(env
->vfp
.xregs
[ARM_VFP_FPINST2
], &vfpframe
->ufp_exc
.fpinst2
);
1292 return (abi_ulong
*)(vfpframe
+1);
1295 static void setup_sigframe_v2(struct target_ucontext_v2
*uc
,
1296 target_sigset_t
*set
, CPUState
*env
)
1298 struct target_sigaltstack stack
;
1300 abi_ulong
*regspace
;
1302 /* Clear all the bits of the ucontext we don't use. */
1303 memset(uc
, 0, offsetof(struct target_ucontext_v2
, tuc_mcontext
));
1305 memset(&stack
, 0, sizeof(stack
));
1306 __put_user(target_sigaltstack_used
.ss_sp
, &stack
.ss_sp
);
1307 __put_user(target_sigaltstack_used
.ss_size
, &stack
.ss_size
);
1308 __put_user(sas_ss_flags(get_sp_from_cpustate(env
)), &stack
.ss_flags
);
1309 memcpy(&uc
->tuc_stack
, &stack
, sizeof(stack
));
1311 setup_sigcontext(&uc
->tuc_mcontext
, env
, set
->sig
[0]);
1312 /* Save coprocessor signal frame. */
1313 regspace
= uc
->tuc_regspace
;
1314 if (arm_feature(env
, ARM_FEATURE_VFP
)) {
1315 regspace
= setup_sigframe_v2_vfp(regspace
, env
);
1317 /* Write terminating magic word */
1318 __put_user(0, regspace
);
1320 for(i
= 0; i
< TARGET_NSIG_WORDS
; i
++) {
1321 __put_user(set
->sig
[i
], &uc
->tuc_sigmask
.sig
[i
]);
1325 /* compare linux/arch/arm/kernel/signal.c:setup_frame() */
1326 static void setup_frame_v1(int usig
, struct target_sigaction
*ka
,
1327 target_sigset_t
*set
, CPUState
*regs
)
1329 struct sigframe_v1
*frame
;
1330 abi_ulong frame_addr
= get_sigframe(ka
, regs
, sizeof(*frame
));
1333 if (!lock_user_struct(VERIFY_WRITE
, frame
, frame_addr
, 0))
1336 setup_sigcontext(&frame
->sc
, regs
, set
->sig
[0]);
1338 for(i
= 1; i
< TARGET_NSIG_WORDS
; i
++) {
1339 if (__put_user(set
->sig
[i
], &frame
->extramask
[i
- 1]))
1343 setup_return(regs
, ka
, &frame
->retcode
, frame_addr
, usig
,
1344 frame_addr
+ offsetof(struct sigframe_v1
, retcode
));
1347 unlock_user_struct(frame
, frame_addr
, 1);
1350 static void setup_frame_v2(int usig
, struct target_sigaction
*ka
,
1351 target_sigset_t
*set
, CPUState
*regs
)
1353 struct sigframe_v2
*frame
;
1354 abi_ulong frame_addr
= get_sigframe(ka
, regs
, sizeof(*frame
));
1356 if (!lock_user_struct(VERIFY_WRITE
, frame
, frame_addr
, 0))
1359 setup_sigframe_v2(&frame
->uc
, set
, regs
);
1361 setup_return(regs
, ka
, &frame
->retcode
, frame_addr
, usig
,
1362 frame_addr
+ offsetof(struct sigframe_v2
, retcode
));
1364 unlock_user_struct(frame
, frame_addr
, 1);
1367 static void setup_frame(int usig
, struct target_sigaction
*ka
,
1368 target_sigset_t
*set
, CPUState
*regs
)
1370 if (get_osversion() >= 0x020612) {
1371 setup_frame_v2(usig
, ka
, set
, regs
);
1373 setup_frame_v1(usig
, ka
, set
, regs
);
1377 /* compare linux/arch/arm/kernel/signal.c:setup_rt_frame() */
1378 static void setup_rt_frame_v1(int usig
, struct target_sigaction
*ka
,
1379 target_siginfo_t
*info
,
1380 target_sigset_t
*set
, CPUState
*env
)
1382 struct rt_sigframe_v1
*frame
;
1383 abi_ulong frame_addr
= get_sigframe(ka
, env
, sizeof(*frame
));
1384 struct target_sigaltstack stack
;
1386 abi_ulong info_addr
, uc_addr
;
1388 if (!lock_user_struct(VERIFY_WRITE
, frame
, frame_addr
, 0))
1391 info_addr
= frame_addr
+ offsetof(struct rt_sigframe_v1
, info
);
1392 __put_user(info_addr
, &frame
->pinfo
);
1393 uc_addr
= frame_addr
+ offsetof(struct rt_sigframe_v1
, uc
);
1394 __put_user(uc_addr
, &frame
->puc
);
1395 copy_siginfo_to_user(&frame
->info
, info
);
1397 /* Clear all the bits of the ucontext we don't use. */
1398 memset(&frame
->uc
, 0, offsetof(struct target_ucontext_v1
, tuc_mcontext
));
1400 memset(&stack
, 0, sizeof(stack
));
1401 __put_user(target_sigaltstack_used
.ss_sp
, &stack
.ss_sp
);
1402 __put_user(target_sigaltstack_used
.ss_size
, &stack
.ss_size
);
1403 __put_user(sas_ss_flags(get_sp_from_cpustate(env
)), &stack
.ss_flags
);
1404 memcpy(&frame
->uc
.tuc_stack
, &stack
, sizeof(stack
));
1406 setup_sigcontext(&frame
->uc
.tuc_mcontext
, env
, set
->sig
[0]);
1407 for(i
= 0; i
< TARGET_NSIG_WORDS
; i
++) {
1408 if (__put_user(set
->sig
[i
], &frame
->uc
.tuc_sigmask
.sig
[i
]))
1412 setup_return(env
, ka
, &frame
->retcode
, frame_addr
, usig
,
1413 frame_addr
+ offsetof(struct rt_sigframe_v1
, retcode
));
1415 env
->regs
[1] = info_addr
;
1416 env
->regs
[2] = uc_addr
;
1419 unlock_user_struct(frame
, frame_addr
, 1);
1422 static void setup_rt_frame_v2(int usig
, struct target_sigaction
*ka
,
1423 target_siginfo_t
*info
,
1424 target_sigset_t
*set
, CPUState
*env
)
1426 struct rt_sigframe_v2
*frame
;
1427 abi_ulong frame_addr
= get_sigframe(ka
, env
, sizeof(*frame
));
1428 abi_ulong info_addr
, uc_addr
;
1430 if (!lock_user_struct(VERIFY_WRITE
, frame
, frame_addr
, 0))
1433 info_addr
= frame_addr
+ offsetof(struct rt_sigframe_v2
, info
);
1434 uc_addr
= frame_addr
+ offsetof(struct rt_sigframe_v2
, uc
);
1435 copy_siginfo_to_user(&frame
->info
, info
);
1437 setup_sigframe_v2(&frame
->uc
, set
, env
);
1439 setup_return(env
, ka
, &frame
->retcode
, frame_addr
, usig
,
1440 frame_addr
+ offsetof(struct rt_sigframe_v2
, retcode
));
1442 env
->regs
[1] = info_addr
;
1443 env
->regs
[2] = uc_addr
;
1445 unlock_user_struct(frame
, frame_addr
, 1);
1448 static void setup_rt_frame(int usig
, struct target_sigaction
*ka
,
1449 target_siginfo_t
*info
,
1450 target_sigset_t
*set
, CPUState
*env
)
1452 if (get_osversion() >= 0x020612) {
1453 setup_rt_frame_v2(usig
, ka
, info
, set
, env
);
1455 setup_rt_frame_v1(usig
, ka
, info
, set
, env
);
1460 restore_sigcontext(CPUState
*env
, struct target_sigcontext
*sc
)
1465 __get_user_error(env
->regs
[0], &sc
->arm_r0
, err
);
1466 __get_user_error(env
->regs
[1], &sc
->arm_r1
, err
);
1467 __get_user_error(env
->regs
[2], &sc
->arm_r2
, err
);
1468 __get_user_error(env
->regs
[3], &sc
->arm_r3
, err
);
1469 __get_user_error(env
->regs
[4], &sc
->arm_r4
, err
);
1470 __get_user_error(env
->regs
[5], &sc
->arm_r5
, err
);
1471 __get_user_error(env
->regs
[6], &sc
->arm_r6
, err
);
1472 __get_user_error(env
->regs
[7], &sc
->arm_r7
, err
);
1473 __get_user_error(env
->regs
[8], &sc
->arm_r8
, err
);
1474 __get_user_error(env
->regs
[9], &sc
->arm_r9
, err
);
1475 __get_user_error(env
->regs
[10], &sc
->arm_r10
, err
);
1476 __get_user_error(env
->regs
[11], &sc
->arm_fp
, err
);
1477 __get_user_error(env
->regs
[12], &sc
->arm_ip
, err
);
1478 __get_user_error(env
->regs
[13], &sc
->arm_sp
, err
);
1479 __get_user_error(env
->regs
[14], &sc
->arm_lr
, err
);
1480 __get_user_error(env
->regs
[15], &sc
->arm_pc
, err
);
1481 #ifdef TARGET_CONFIG_CPU_32
1482 __get_user_error(cpsr
, &sc
->arm_cpsr
, err
);
1483 cpsr_write(env
, cpsr
, CPSR_USER
| CPSR_EXEC
);
1486 err
|= !valid_user_regs(env
);
1491 static long do_sigreturn_v1(CPUState
*env
)
1493 abi_ulong frame_addr
;
1494 struct sigframe_v1
*frame
;
1495 target_sigset_t set
;
1500 * Since we stacked the signal on a 64-bit boundary,
1501 * then 'sp' should be word aligned here. If it's
1502 * not, then the user is trying to mess with us.
1504 if (env
->regs
[13] & 7)
1507 frame_addr
= env
->regs
[13];
1508 if (!lock_user_struct(VERIFY_READ
, frame
, frame_addr
, 1))
1511 if (__get_user(set
.sig
[0], &frame
->sc
.oldmask
))
1513 for(i
= 1; i
< TARGET_NSIG_WORDS
; i
++) {
1514 if (__get_user(set
.sig
[i
], &frame
->extramask
[i
- 1]))
1518 target_to_host_sigset_internal(&host_set
, &set
);
1519 sigprocmask(SIG_SETMASK
, &host_set
, NULL
);
1521 if (restore_sigcontext(env
, &frame
->sc
))
1525 /* Send SIGTRAP if we're single-stepping */
1526 if (ptrace_cancel_bpt(current
))
1527 send_sig(SIGTRAP
, current
, 1);
1529 unlock_user_struct(frame
, frame_addr
, 0);
1530 return env
->regs
[0];
1533 unlock_user_struct(frame
, frame_addr
, 0);
1534 force_sig(TARGET_SIGSEGV
/* , current */);
1538 static abi_ulong
*restore_sigframe_v2_vfp(CPUState
*env
, abi_ulong
*regspace
)
1541 abi_ulong magic
, sz
;
1542 uint32_t fpscr
, fpexc
;
1543 struct target_vfp_sigframe
*vfpframe
;
1544 vfpframe
= (struct target_vfp_sigframe
*)regspace
;
1546 __get_user(magic
, &vfpframe
->magic
);
1547 __get_user(sz
, &vfpframe
->size
);
1548 if (magic
!= TARGET_VFP_MAGIC
|| sz
!= sizeof(*vfpframe
)) {
1551 for (i
= 0; i
< 32; i
++) {
1552 __get_user(env
->vfp
.regs
[i
], &vfpframe
->ufp
.fpregs
[i
]);
1554 __get_user(fpscr
, &vfpframe
->ufp
.fpscr
);
1555 vfp_set_fpscr(env
, fpscr
);
1556 __get_user(fpexc
, &vfpframe
->ufp_exc
.fpexc
);
1557 /* Sanitise FPEXC: ensure VFP is enabled, FPINST2 is invalid
1558 * and the exception flag is cleared
1561 fpexc
&= ~((1 << 31) | (1 << 28));
1562 env
->vfp
.xregs
[ARM_VFP_FPEXC
] = fpexc
;
1563 __get_user(env
->vfp
.xregs
[ARM_VFP_FPINST
], &vfpframe
->ufp_exc
.fpinst
);
1564 __get_user(env
->vfp
.xregs
[ARM_VFP_FPINST2
], &vfpframe
->ufp_exc
.fpinst2
);
1565 return (abi_ulong
*)(vfpframe
+ 1);
1568 static int do_sigframe_return_v2(CPUState
*env
, target_ulong frame_addr
,
1569 struct target_ucontext_v2
*uc
)
1572 abi_ulong
*regspace
;
1574 target_to_host_sigset(&host_set
, &uc
->tuc_sigmask
);
1575 sigprocmask(SIG_SETMASK
, &host_set
, NULL
);
1577 if (restore_sigcontext(env
, &uc
->tuc_mcontext
))
1580 /* Restore coprocessor signal frame */
1581 regspace
= uc
->tuc_regspace
;
1582 if (arm_feature(env
, ARM_FEATURE_VFP
)) {
1583 regspace
= restore_sigframe_v2_vfp(env
, regspace
);
1589 if (do_sigaltstack(frame_addr
+ offsetof(struct target_ucontext_v2
, tuc_stack
), 0, get_sp_from_cpustate(env
)) == -EFAULT
)
1593 /* Send SIGTRAP if we're single-stepping */
1594 if (ptrace_cancel_bpt(current
))
1595 send_sig(SIGTRAP
, current
, 1);
1601 static long do_sigreturn_v2(CPUState
*env
)
1603 abi_ulong frame_addr
;
1604 struct sigframe_v2
*frame
;
1607 * Since we stacked the signal on a 64-bit boundary,
1608 * then 'sp' should be word aligned here. If it's
1609 * not, then the user is trying to mess with us.
1611 if (env
->regs
[13] & 7)
1614 frame_addr
= env
->regs
[13];
1615 if (!lock_user_struct(VERIFY_READ
, frame
, frame_addr
, 1))
1618 if (do_sigframe_return_v2(env
, frame_addr
, &frame
->uc
))
1621 unlock_user_struct(frame
, frame_addr
, 0);
1622 return env
->regs
[0];
1625 unlock_user_struct(frame
, frame_addr
, 0);
1626 force_sig(TARGET_SIGSEGV
/* , current */);
1630 long do_sigreturn(CPUState
*env
)
1632 if (get_osversion() >= 0x020612) {
1633 return do_sigreturn_v2(env
);
1635 return do_sigreturn_v1(env
);
1639 static long do_rt_sigreturn_v1(CPUState
*env
)
1641 abi_ulong frame_addr
;
1642 struct rt_sigframe_v1
*frame
;
1646 * Since we stacked the signal on a 64-bit boundary,
1647 * then 'sp' should be word aligned here. If it's
1648 * not, then the user is trying to mess with us.
1650 if (env
->regs
[13] & 7)
1653 frame_addr
= env
->regs
[13];
1654 if (!lock_user_struct(VERIFY_READ
, frame
, frame_addr
, 1))
1657 target_to_host_sigset(&host_set
, &frame
->uc
.tuc_sigmask
);
1658 sigprocmask(SIG_SETMASK
, &host_set
, NULL
);
1660 if (restore_sigcontext(env
, &frame
->uc
.tuc_mcontext
))
1663 if (do_sigaltstack(frame_addr
+ offsetof(struct rt_sigframe_v1
, uc
.tuc_stack
), 0, get_sp_from_cpustate(env
)) == -EFAULT
)
1667 /* Send SIGTRAP if we're single-stepping */
1668 if (ptrace_cancel_bpt(current
))
1669 send_sig(SIGTRAP
, current
, 1);
1671 unlock_user_struct(frame
, frame_addr
, 0);
1672 return env
->regs
[0];
1675 unlock_user_struct(frame
, frame_addr
, 0);
1676 force_sig(TARGET_SIGSEGV
/* , current */);
1680 static long do_rt_sigreturn_v2(CPUState
*env
)
1682 abi_ulong frame_addr
;
1683 struct rt_sigframe_v2
*frame
;
1686 * Since we stacked the signal on a 64-bit boundary,
1687 * then 'sp' should be word aligned here. If it's
1688 * not, then the user is trying to mess with us.
1690 if (env
->regs
[13] & 7)
1693 frame_addr
= env
->regs
[13];
1694 if (!lock_user_struct(VERIFY_READ
, frame
, frame_addr
, 1))
1697 if (do_sigframe_return_v2(env
, frame_addr
, &frame
->uc
))
1700 unlock_user_struct(frame
, frame_addr
, 0);
1701 return env
->regs
[0];
1704 unlock_user_struct(frame
, frame_addr
, 0);
1705 force_sig(TARGET_SIGSEGV
/* , current */);
1709 long do_rt_sigreturn(CPUState
*env
)
1711 if (get_osversion() >= 0x020612) {
1712 return do_rt_sigreturn_v2(env
);
1714 return do_rt_sigreturn_v1(env
);
1718 #elif defined(TARGET_SPARC)
1720 #define __SUNOS_MAXWIN 31
1722 /* This is what SunOS does, so shall I. */
1723 struct target_sigcontext
{
1724 abi_ulong sigc_onstack
; /* state to restore */
1726 abi_ulong sigc_mask
; /* sigmask to restore */
1727 abi_ulong sigc_sp
; /* stack pointer */
1728 abi_ulong sigc_pc
; /* program counter */
1729 abi_ulong sigc_npc
; /* next program counter */
1730 abi_ulong sigc_psr
; /* for condition codes etc */
1731 abi_ulong sigc_g1
; /* User uses these two registers */
1732 abi_ulong sigc_o0
; /* within the trampoline code. */
1734 /* Now comes information regarding the users window set
1735 * at the time of the signal.
1737 abi_ulong sigc_oswins
; /* outstanding windows */
1739 /* stack ptrs for each regwin buf */
1740 char *sigc_spbuf
[__SUNOS_MAXWIN
];
1742 /* Windows to restore after signal */
1744 abi_ulong locals
[8];
1746 } sigc_wbuf
[__SUNOS_MAXWIN
];
1748 /* A Sparc stack frame */
1749 struct sparc_stackf
{
1750 abi_ulong locals
[8];
1752 struct sparc_stackf
*fp
;
1753 abi_ulong callers_pc
;
1756 abi_ulong xxargs
[1];
1765 abi_ulong u_regs
[16]; /* globals and ins */
1771 unsigned long si_float_regs
[32];
1772 unsigned long si_fsr
;
1773 unsigned long si_fpqdepth
;
1775 unsigned long *insn_addr
;
1778 } qemu_siginfo_fpu_t
;
1781 struct target_signal_frame
{
1782 struct sparc_stackf ss
;
1785 abi_ulong insns
[2] __attribute__ ((aligned (8)));
1786 abi_ulong extramask
[TARGET_NSIG_WORDS
- 1];
1787 abi_ulong extra_size
; /* Should be 0 */
1788 qemu_siginfo_fpu_t fpu_state
;
1790 struct target_rt_signal_frame
{
1791 struct sparc_stackf ss
;
1796 unsigned int insns
[2];
1798 unsigned int extra_size
; /* Should be 0 */
1799 qemu_siginfo_fpu_t fpu_state
;
1813 #define UREG_FP UREG_I6
1814 #define UREG_SP UREG_O6
1816 static inline abi_ulong
get_sigframe(struct target_sigaction
*sa
,
1817 CPUState
*env
, unsigned long framesize
)
1821 sp
= env
->regwptr
[UREG_FP
];
1823 /* This is the X/Open sanctioned signal stack switching. */
1824 if (sa
->sa_flags
& TARGET_SA_ONSTACK
) {
1825 if (!on_sig_stack(sp
)
1826 && !((target_sigaltstack_used
.ss_sp
+ target_sigaltstack_used
.ss_size
) & 7))
1827 sp
= target_sigaltstack_used
.ss_sp
+ target_sigaltstack_used
.ss_size
;
1829 return sp
- framesize
;
1833 setup___siginfo(__siginfo_t
*si
, CPUState
*env
, abi_ulong mask
)
1837 err
|= __put_user(env
->psr
, &si
->si_regs
.psr
);
1838 err
|= __put_user(env
->pc
, &si
->si_regs
.pc
);
1839 err
|= __put_user(env
->npc
, &si
->si_regs
.npc
);
1840 err
|= __put_user(env
->y
, &si
->si_regs
.y
);
1841 for (i
=0; i
< 8; i
++) {
1842 err
|= __put_user(env
->gregs
[i
], &si
->si_regs
.u_regs
[i
]);
1844 for (i
=0; i
< 8; i
++) {
1845 err
|= __put_user(env
->regwptr
[UREG_I0
+ i
], &si
->si_regs
.u_regs
[i
+8]);
1847 err
|= __put_user(mask
, &si
->si_mask
);
1853 setup_sigcontext(struct target_sigcontext
*sc
, /*struct _fpstate *fpstate,*/
1854 CPUState
*env
, unsigned long mask
)
1858 err
|= __put_user(mask
, &sc
->sigc_mask
);
1859 err
|= __put_user(env
->regwptr
[UREG_SP
], &sc
->sigc_sp
);
1860 err
|= __put_user(env
->pc
, &sc
->sigc_pc
);
1861 err
|= __put_user(env
->npc
, &sc
->sigc_npc
);
1862 err
|= __put_user(env
->psr
, &sc
->sigc_psr
);
1863 err
|= __put_user(env
->gregs
[1], &sc
->sigc_g1
);
1864 err
|= __put_user(env
->regwptr
[UREG_O0
], &sc
->sigc_o0
);
1869 #define NF_ALIGNEDSZ (((sizeof(struct target_signal_frame) + 7) & (~7)))
1871 static void setup_frame(int sig
, struct target_sigaction
*ka
,
1872 target_sigset_t
*set
, CPUState
*env
)
1875 struct target_signal_frame
*sf
;
1876 int sigframe_size
, err
, i
;
1878 /* 1. Make sure everything is clean */
1879 //synchronize_user_stack();
1881 sigframe_size
= NF_ALIGNEDSZ
;
1882 sf_addr
= get_sigframe(ka
, env
, sigframe_size
);
1884 sf
= lock_user(VERIFY_WRITE
, sf_addr
,
1885 sizeof(struct target_signal_frame
), 0);
1889 //fprintf(stderr, "sf: %x pc %x fp %x sp %x\n", sf, env->pc, env->regwptr[UREG_FP], env->regwptr[UREG_SP]);
1891 if (invalid_frame_pointer(sf
, sigframe_size
))
1892 goto sigill_and_return
;
1894 /* 2. Save the current process state */
1895 err
= setup___siginfo(&sf
->info
, env
, set
->sig
[0]);
1896 err
|= __put_user(0, &sf
->extra_size
);
1898 //err |= save_fpu_state(regs, &sf->fpu_state);
1899 //err |= __put_user(&sf->fpu_state, &sf->fpu_save);
1901 err
|= __put_user(set
->sig
[0], &sf
->info
.si_mask
);
1902 for (i
= 0; i
< TARGET_NSIG_WORDS
- 1; i
++) {
1903 err
|= __put_user(set
->sig
[i
+ 1], &sf
->extramask
[i
]);
1906 for (i
= 0; i
< 8; i
++) {
1907 err
|= __put_user(env
->regwptr
[i
+ UREG_L0
], &sf
->ss
.locals
[i
]);
1909 for (i
= 0; i
< 8; i
++) {
1910 err
|= __put_user(env
->regwptr
[i
+ UREG_I0
], &sf
->ss
.ins
[i
]);
1915 /* 3. signal handler back-trampoline and parameters */
1916 env
->regwptr
[UREG_FP
] = sf_addr
;
1917 env
->regwptr
[UREG_I0
] = sig
;
1918 env
->regwptr
[UREG_I1
] = sf_addr
+
1919 offsetof(struct target_signal_frame
, info
);
1920 env
->regwptr
[UREG_I2
] = sf_addr
+
1921 offsetof(struct target_signal_frame
, info
);
1923 /* 4. signal handler */
1924 env
->pc
= ka
->_sa_handler
;
1925 env
->npc
= (env
->pc
+ 4);
1926 /* 5. return to kernel instructions */
1927 if (ka
->sa_restorer
)
1928 env
->regwptr
[UREG_I7
] = ka
->sa_restorer
;
1932 env
->regwptr
[UREG_I7
] = sf_addr
+
1933 offsetof(struct target_signal_frame
, insns
) - 2 * 4;
1935 /* mov __NR_sigreturn, %g1 */
1937 err
|= __put_user(val32
, &sf
->insns
[0]);
1941 err
|= __put_user(val32
, &sf
->insns
[1]);
1945 /* Flush instruction space. */
1946 //flush_sig_insns(current->mm, (unsigned long) &(sf->insns[0]));
1949 unlock_user(sf
, sf_addr
, sizeof(struct target_signal_frame
));
1953 force_sig(TARGET_SIGILL
);
1956 //fprintf(stderr, "force_sig\n");
1957 unlock_user(sf
, sf_addr
, sizeof(struct target_signal_frame
));
1958 force_sig(TARGET_SIGSEGV
);
1961 restore_fpu_state(CPUState
*env
, qemu_siginfo_fpu_t
*fpu
)
1966 if (current
->flags
& PF_USEDFPU
)
1967 regs
->psr
&= ~PSR_EF
;
1969 if (current
== last_task_used_math
) {
1970 last_task_used_math
= 0;
1971 regs
->psr
&= ~PSR_EF
;
1974 current
->used_math
= 1;
1975 current
->flags
&= ~PF_USEDFPU
;
1978 if (verify_area (VERIFY_READ
, fpu
, sizeof(*fpu
)))
1983 /* XXX: incorrect */
1984 err
= __copy_from_user(&env
->fpr
[0], &fpu
->si_float_regs
[0],
1985 (sizeof(unsigned long) * 32));
1987 err
|= __get_user(env
->fsr
, &fpu
->si_fsr
);
1989 err
|= __get_user(current
->thread
.fpqdepth
, &fpu
->si_fpqdepth
);
1990 if (current
->thread
.fpqdepth
!= 0)
1991 err
|= __copy_from_user(¤t
->thread
.fpqueue
[0],
1992 &fpu
->si_fpqueue
[0],
1993 ((sizeof(unsigned long) +
1994 (sizeof(unsigned long *)))*16));
2000 static void setup_rt_frame(int sig
, struct target_sigaction
*ka
,
2001 target_siginfo_t
*info
,
2002 target_sigset_t
*set
, CPUState
*env
)
2004 fprintf(stderr
, "setup_rt_frame: not implemented\n");
2007 long do_sigreturn(CPUState
*env
)
2010 struct target_signal_frame
*sf
;
2011 uint32_t up_psr
, pc
, npc
;
2012 target_sigset_t set
;
2014 abi_ulong fpu_save_addr
;
2017 sf_addr
= env
->regwptr
[UREG_FP
];
2018 if (!lock_user_struct(VERIFY_READ
, sf
, sf_addr
, 1))
2021 fprintf(stderr
, "sigreturn\n");
2022 fprintf(stderr
, "sf: %x pc %x fp %x sp %x\n", sf
, env
->pc
, env
->regwptr
[UREG_FP
], env
->regwptr
[UREG_SP
]);
2024 //cpu_dump_state(env, stderr, fprintf, 0);
2026 /* 1. Make sure we are not getting garbage from the user */
2031 err
= __get_user(pc
, &sf
->info
.si_regs
.pc
);
2032 err
|= __get_user(npc
, &sf
->info
.si_regs
.npc
);
2037 /* 2. Restore the state */
2038 err
|= __get_user(up_psr
, &sf
->info
.si_regs
.psr
);
2040 /* User can only change condition codes and FPU enabling in %psr. */
2041 env
->psr
= (up_psr
& (PSR_ICC
/* | PSR_EF */))
2042 | (env
->psr
& ~(PSR_ICC
/* | PSR_EF */));
2046 err
|= __get_user(env
->y
, &sf
->info
.si_regs
.y
);
2047 for (i
=0; i
< 8; i
++) {
2048 err
|= __get_user(env
->gregs
[i
], &sf
->info
.si_regs
.u_regs
[i
]);
2050 for (i
=0; i
< 8; i
++) {
2051 err
|= __get_user(env
->regwptr
[i
+ UREG_I0
], &sf
->info
.si_regs
.u_regs
[i
+8]);
2054 err
|= __get_user(fpu_save_addr
, &sf
->fpu_save
);
2057 // err |= restore_fpu_state(env, fpu_save);
2059 /* This is pretty much atomic, no amount locking would prevent
2060 * the races which exist anyways.
2062 err
|= __get_user(set
.sig
[0], &sf
->info
.si_mask
);
2063 for(i
= 1; i
< TARGET_NSIG_WORDS
; i
++) {
2064 err
|= (__get_user(set
.sig
[i
], &sf
->extramask
[i
- 1]));
2067 target_to_host_sigset_internal(&host_set
, &set
);
2068 sigprocmask(SIG_SETMASK
, &host_set
, NULL
);
2072 unlock_user_struct(sf
, sf_addr
, 0);
2073 return env
->regwptr
[0];
2076 unlock_user_struct(sf
, sf_addr
, 0);
2077 force_sig(TARGET_SIGSEGV
);
2080 long do_rt_sigreturn(CPUState
*env
)
2082 fprintf(stderr
, "do_rt_sigreturn: not implemented\n");
2083 return -TARGET_ENOSYS
;
2086 #if defined(TARGET_SPARC64) && !defined(TARGET_ABI32)
2108 typedef abi_ulong target_mc_greg_t
;
2109 typedef target_mc_greg_t target_mc_gregset_t
[MC_NGREG
];
2111 struct target_mc_fq
{
2112 abi_ulong
*mcfq_addr
;
2116 struct target_mc_fpu
{
2120 //uint128_t qregs[16];
2122 abi_ulong mcfpu_fsr
;
2123 abi_ulong mcfpu_fprs
;
2124 abi_ulong mcfpu_gsr
;
2125 struct target_mc_fq
*mcfpu_fq
;
2126 unsigned char mcfpu_qcnt
;
2127 unsigned char mcfpu_qentsz
;
2128 unsigned char mcfpu_enab
;
2130 typedef struct target_mc_fpu target_mc_fpu_t
;
2133 target_mc_gregset_t mc_gregs
;
2134 target_mc_greg_t mc_fp
;
2135 target_mc_greg_t mc_i7
;
2136 target_mc_fpu_t mc_fpregs
;
2137 } target_mcontext_t
;
2139 struct target_ucontext
{
2140 struct target_ucontext
*tuc_link
;
2141 abi_ulong tuc_flags
;
2142 target_sigset_t tuc_sigmask
;
2143 target_mcontext_t tuc_mcontext
;
2146 /* A V9 register window */
2147 struct target_reg_window
{
2148 abi_ulong locals
[8];
2152 #define TARGET_STACK_BIAS 2047
2154 /* {set, get}context() needed for 64-bit SparcLinux userland. */
2155 void sparc64_set_context(CPUSPARCState
*env
)
2158 struct target_ucontext
*ucp
;
2159 target_mc_gregset_t
*grp
;
2160 abi_ulong pc
, npc
, tstate
;
2161 abi_ulong fp
, i7
, w_addr
;
2162 unsigned char fenab
;
2166 ucp_addr
= env
->regwptr
[UREG_I0
];
2167 if (!lock_user_struct(VERIFY_READ
, ucp
, ucp_addr
, 1))
2169 grp
= &ucp
->tuc_mcontext
.mc_gregs
;
2170 err
= __get_user(pc
, &((*grp
)[MC_PC
]));
2171 err
|= __get_user(npc
, &((*grp
)[MC_NPC
]));
2172 if (err
|| ((pc
| npc
) & 3))
2174 if (env
->regwptr
[UREG_I1
]) {
2175 target_sigset_t target_set
;
2178 if (TARGET_NSIG_WORDS
== 1) {
2179 if (__get_user(target_set
.sig
[0], &ucp
->tuc_sigmask
.sig
[0]))
2182 abi_ulong
*src
, *dst
;
2183 src
= ucp
->tuc_sigmask
.sig
;
2184 dst
= target_set
.sig
;
2185 for (i
= 0; i
< sizeof(target_sigset_t
) / sizeof(abi_ulong
);
2187 err
|= __get_user(*dst
, src
);
2191 target_to_host_sigset_internal(&set
, &target_set
);
2192 sigprocmask(SIG_SETMASK
, &set
, NULL
);
2196 err
|= __get_user(env
->y
, &((*grp
)[MC_Y
]));
2197 err
|= __get_user(tstate
, &((*grp
)[MC_TSTATE
]));
2198 env
->asi
= (tstate
>> 24) & 0xff;
2199 cpu_put_ccr(env
, tstate
>> 32);
2200 cpu_put_cwp64(env
, tstate
& 0x1f);
2201 err
|= __get_user(env
->gregs
[1], (&(*grp
)[MC_G1
]));
2202 err
|= __get_user(env
->gregs
[2], (&(*grp
)[MC_G2
]));
2203 err
|= __get_user(env
->gregs
[3], (&(*grp
)[MC_G3
]));
2204 err
|= __get_user(env
->gregs
[4], (&(*grp
)[MC_G4
]));
2205 err
|= __get_user(env
->gregs
[5], (&(*grp
)[MC_G5
]));
2206 err
|= __get_user(env
->gregs
[6], (&(*grp
)[MC_G6
]));
2207 err
|= __get_user(env
->gregs
[7], (&(*grp
)[MC_G7
]));
2208 err
|= __get_user(env
->regwptr
[UREG_I0
], (&(*grp
)[MC_O0
]));
2209 err
|= __get_user(env
->regwptr
[UREG_I1
], (&(*grp
)[MC_O1
]));
2210 err
|= __get_user(env
->regwptr
[UREG_I2
], (&(*grp
)[MC_O2
]));
2211 err
|= __get_user(env
->regwptr
[UREG_I3
], (&(*grp
)[MC_O3
]));
2212 err
|= __get_user(env
->regwptr
[UREG_I4
], (&(*grp
)[MC_O4
]));
2213 err
|= __get_user(env
->regwptr
[UREG_I5
], (&(*grp
)[MC_O5
]));
2214 err
|= __get_user(env
->regwptr
[UREG_I6
], (&(*grp
)[MC_O6
]));
2215 err
|= __get_user(env
->regwptr
[UREG_I7
], (&(*grp
)[MC_O7
]));
2217 err
|= __get_user(fp
, &(ucp
->tuc_mcontext
.mc_fp
));
2218 err
|= __get_user(i7
, &(ucp
->tuc_mcontext
.mc_i7
));
2220 w_addr
= TARGET_STACK_BIAS
+env
->regwptr
[UREG_I6
];
2221 if (put_user(fp
, w_addr
+ offsetof(struct target_reg_window
, ins
[6]),
2224 if (put_user(i7
, w_addr
+ offsetof(struct target_reg_window
, ins
[7]),
2227 err
|= __get_user(fenab
, &(ucp
->tuc_mcontext
.mc_fpregs
.mcfpu_enab
));
2228 err
|= __get_user(env
->fprs
, &(ucp
->tuc_mcontext
.mc_fpregs
.mcfpu_fprs
));
2230 uint32_t *src
, *dst
;
2231 src
= ucp
->tuc_mcontext
.mc_fpregs
.mcfpu_fregs
.sregs
;
2233 /* XXX: check that the CPU storage is the same as user context */
2234 for (i
= 0; i
< 64; i
++, dst
++, src
++)
2235 err
|= __get_user(*dst
, src
);
2237 err
|= __get_user(env
->fsr
,
2238 &(ucp
->tuc_mcontext
.mc_fpregs
.mcfpu_fsr
));
2239 err
|= __get_user(env
->gsr
,
2240 &(ucp
->tuc_mcontext
.mc_fpregs
.mcfpu_gsr
));
2243 unlock_user_struct(ucp
, ucp_addr
, 0);
2246 unlock_user_struct(ucp
, ucp_addr
, 0);
2247 force_sig(TARGET_SIGSEGV
);
2250 void sparc64_get_context(CPUSPARCState
*env
)
2253 struct target_ucontext
*ucp
;
2254 target_mc_gregset_t
*grp
;
2255 target_mcontext_t
*mcp
;
2256 abi_ulong fp
, i7
, w_addr
;
2259 target_sigset_t target_set
;
2262 ucp_addr
= env
->regwptr
[UREG_I0
];
2263 if (!lock_user_struct(VERIFY_WRITE
, ucp
, ucp_addr
, 0))
2266 mcp
= &ucp
->tuc_mcontext
;
2267 grp
= &mcp
->mc_gregs
;
2269 /* Skip over the trap instruction, first. */
2275 sigprocmask(0, NULL
, &set
);
2276 host_to_target_sigset_internal(&target_set
, &set
);
2277 if (TARGET_NSIG_WORDS
== 1) {
2278 err
|= __put_user(target_set
.sig
[0],
2279 (abi_ulong
*)&ucp
->tuc_sigmask
);
2281 abi_ulong
*src
, *dst
;
2282 src
= target_set
.sig
;
2283 dst
= ucp
->tuc_sigmask
.sig
;
2284 for (i
= 0; i
< sizeof(target_sigset_t
) / sizeof(abi_ulong
);
2286 err
|= __put_user(*src
, dst
);
2291 /* XXX: tstate must be saved properly */
2292 // err |= __put_user(env->tstate, &((*grp)[MC_TSTATE]));
2293 err
|= __put_user(env
->pc
, &((*grp
)[MC_PC
]));
2294 err
|= __put_user(env
->npc
, &((*grp
)[MC_NPC
]));
2295 err
|= __put_user(env
->y
, &((*grp
)[MC_Y
]));
2296 err
|= __put_user(env
->gregs
[1], &((*grp
)[MC_G1
]));
2297 err
|= __put_user(env
->gregs
[2], &((*grp
)[MC_G2
]));
2298 err
|= __put_user(env
->gregs
[3], &((*grp
)[MC_G3
]));
2299 err
|= __put_user(env
->gregs
[4], &((*grp
)[MC_G4
]));
2300 err
|= __put_user(env
->gregs
[5], &((*grp
)[MC_G5
]));
2301 err
|= __put_user(env
->gregs
[6], &((*grp
)[MC_G6
]));
2302 err
|= __put_user(env
->gregs
[7], &((*grp
)[MC_G7
]));
2303 err
|= __put_user(env
->regwptr
[UREG_I0
], &((*grp
)[MC_O0
]));
2304 err
|= __put_user(env
->regwptr
[UREG_I1
], &((*grp
)[MC_O1
]));
2305 err
|= __put_user(env
->regwptr
[UREG_I2
], &((*grp
)[MC_O2
]));
2306 err
|= __put_user(env
->regwptr
[UREG_I3
], &((*grp
)[MC_O3
]));
2307 err
|= __put_user(env
->regwptr
[UREG_I4
], &((*grp
)[MC_O4
]));
2308 err
|= __put_user(env
->regwptr
[UREG_I5
], &((*grp
)[MC_O5
]));
2309 err
|= __put_user(env
->regwptr
[UREG_I6
], &((*grp
)[MC_O6
]));
2310 err
|= __put_user(env
->regwptr
[UREG_I7
], &((*grp
)[MC_O7
]));
2312 w_addr
= TARGET_STACK_BIAS
+env
->regwptr
[UREG_I6
];
2314 if (get_user(fp
, w_addr
+ offsetof(struct target_reg_window
, ins
[6]),
2317 if (get_user(i7
, w_addr
+ offsetof(struct target_reg_window
, ins
[7]),
2320 err
|= __put_user(fp
, &(mcp
->mc_fp
));
2321 err
|= __put_user(i7
, &(mcp
->mc_i7
));
2324 uint32_t *src
, *dst
;
2326 dst
= ucp
->tuc_mcontext
.mc_fpregs
.mcfpu_fregs
.sregs
;
2327 /* XXX: check that the CPU storage is the same as user context */
2328 for (i
= 0; i
< 64; i
++, dst
++, src
++)
2329 err
|= __put_user(*src
, dst
);
2331 err
|= __put_user(env
->fsr
, &(mcp
->mc_fpregs
.mcfpu_fsr
));
2332 err
|= __put_user(env
->gsr
, &(mcp
->mc_fpregs
.mcfpu_gsr
));
2333 err
|= __put_user(env
->fprs
, &(mcp
->mc_fpregs
.mcfpu_fprs
));
2337 unlock_user_struct(ucp
, ucp_addr
, 1);
2340 unlock_user_struct(ucp
, ucp_addr
, 1);
2341 force_sig(TARGET_SIGSEGV
);
2344 #elif defined(TARGET_ABI_MIPSN64)
2346 # warning signal handling not implemented
2348 static void setup_frame(int sig
, struct target_sigaction
*ka
,
2349 target_sigset_t
*set
, CPUState
*env
)
2351 fprintf(stderr
, "setup_frame: not implemented\n");
2354 static void setup_rt_frame(int sig
, struct target_sigaction
*ka
,
2355 target_siginfo_t
*info
,
2356 target_sigset_t
*set
, CPUState
*env
)
2358 fprintf(stderr
, "setup_rt_frame: not implemented\n");
2361 long do_sigreturn(CPUState
*env
)
2363 fprintf(stderr
, "do_sigreturn: not implemented\n");
2364 return -TARGET_ENOSYS
;
2367 long do_rt_sigreturn(CPUState
*env
)
2369 fprintf(stderr
, "do_rt_sigreturn: not implemented\n");
2370 return -TARGET_ENOSYS
;
2373 #elif defined(TARGET_ABI_MIPSN32)
2375 # warning signal handling not implemented
2377 static void setup_frame(int sig
, struct target_sigaction
*ka
,
2378 target_sigset_t
*set
, CPUState
*env
)
2380 fprintf(stderr
, "setup_frame: not implemented\n");
2383 static void setup_rt_frame(int sig
, struct target_sigaction
*ka
,
2384 target_siginfo_t
*info
,
2385 target_sigset_t
*set
, CPUState
*env
)
2387 fprintf(stderr
, "setup_rt_frame: not implemented\n");
2390 long do_sigreturn(CPUState
*env
)
2392 fprintf(stderr
, "do_sigreturn: not implemented\n");
2393 return -TARGET_ENOSYS
;
2396 long do_rt_sigreturn(CPUState
*env
)
2398 fprintf(stderr
, "do_rt_sigreturn: not implemented\n");
2399 return -TARGET_ENOSYS
;
2402 #elif defined(TARGET_ABI_MIPSO32)
2404 struct target_sigcontext
{
2405 uint32_t sc_regmask
; /* Unused */
2408 uint64_t sc_regs
[32];
2409 uint64_t sc_fpregs
[32];
2410 uint32_t sc_ownedfp
; /* Unused */
2411 uint32_t sc_fpc_csr
;
2412 uint32_t sc_fpc_eir
; /* Unused */
2413 uint32_t sc_used_math
;
2414 uint32_t sc_dsp
; /* dsp status, was sc_ssflags */
2418 target_ulong sc_hi1
; /* Was sc_cause */
2419 target_ulong sc_lo1
; /* Was sc_badvaddr */
2420 target_ulong sc_hi2
; /* Was sc_sigset[4] */
2421 target_ulong sc_lo2
;
2422 target_ulong sc_hi3
;
2423 target_ulong sc_lo3
;
2427 uint32_t sf_ass
[4]; /* argument save space for o32 */
2428 uint32_t sf_code
[2]; /* signal trampoline */
2429 struct target_sigcontext sf_sc
;
2430 target_sigset_t sf_mask
;
2433 struct target_ucontext
{
2434 target_ulong tuc_flags
;
2435 target_ulong tuc_link
;
2436 target_stack_t tuc_stack
;
2438 struct target_sigcontext tuc_mcontext
;
2439 target_sigset_t tuc_sigmask
;
2442 struct target_rt_sigframe
{
2443 uint32_t rs_ass
[4]; /* argument save space for o32 */
2444 uint32_t rs_code
[2]; /* signal trampoline */
2445 struct target_siginfo rs_info
;
2446 struct target_ucontext rs_uc
;
2449 /* Install trampoline to jump back from signal handler */
2450 static inline int install_sigtramp(unsigned int *tramp
, unsigned int syscall
)
2455 * Set up the return code ...
2457 * li v0, __NR__foo_sigreturn
2461 err
= __put_user(0x24020000 + syscall
, tramp
+ 0);
2462 err
|= __put_user(0x0000000c , tramp
+ 1);
2463 /* flush_cache_sigtramp((unsigned long) tramp); */
2468 setup_sigcontext(CPUState
*regs
, struct target_sigcontext
*sc
)
2472 err
|= __put_user(regs
->active_tc
.PC
, &sc
->sc_pc
);
2474 #define save_gp_reg(i) do { \
2475 err |= __put_user(regs->active_tc.gpr[i], &sc->sc_regs[i]); \
2477 __put_user(0, &sc
->sc_regs
[0]); save_gp_reg(1); save_gp_reg(2);
2478 save_gp_reg(3); save_gp_reg(4); save_gp_reg(5); save_gp_reg(6);
2479 save_gp_reg(7); save_gp_reg(8); save_gp_reg(9); save_gp_reg(10);
2480 save_gp_reg(11); save_gp_reg(12); save_gp_reg(13); save_gp_reg(14);
2481 save_gp_reg(15); save_gp_reg(16); save_gp_reg(17); save_gp_reg(18);
2482 save_gp_reg(19); save_gp_reg(20); save_gp_reg(21); save_gp_reg(22);
2483 save_gp_reg(23); save_gp_reg(24); save_gp_reg(25); save_gp_reg(26);
2484 save_gp_reg(27); save_gp_reg(28); save_gp_reg(29); save_gp_reg(30);
2488 err
|= __put_user(regs
->active_tc
.HI
[0], &sc
->sc_mdhi
);
2489 err
|= __put_user(regs
->active_tc
.LO
[0], &sc
->sc_mdlo
);
2491 /* Not used yet, but might be useful if we ever have DSP suppport */
2494 err
|= __put_user(mfhi1(), &sc
->sc_hi1
);
2495 err
|= __put_user(mflo1(), &sc
->sc_lo1
);
2496 err
|= __put_user(mfhi2(), &sc
->sc_hi2
);
2497 err
|= __put_user(mflo2(), &sc
->sc_lo2
);
2498 err
|= __put_user(mfhi3(), &sc
->sc_hi3
);
2499 err
|= __put_user(mflo3(), &sc
->sc_lo3
);
2500 err
|= __put_user(rddsp(DSP_MASK
), &sc
->sc_dsp
);
2502 /* same with 64 bit */
2504 err
|= __put_user(regs
->hi
, &sc
->sc_hi
[0]);
2505 err
|= __put_user(regs
->lo
, &sc
->sc_lo
[0]);
2507 err
|= __put_user(mfhi1(), &sc
->sc_hi
[1]);
2508 err
|= __put_user(mflo1(), &sc
->sc_lo
[1]);
2509 err
|= __put_user(mfhi2(), &sc
->sc_hi
[2]);
2510 err
|= __put_user(mflo2(), &sc
->sc_lo
[2]);
2511 err
|= __put_user(mfhi3(), &sc
->sc_hi
[3]);
2512 err
|= __put_user(mflo3(), &sc
->sc_lo
[3]);
2513 err
|= __put_user(rddsp(DSP_MASK
), &sc
->sc_dsp
);
2519 err
|= __put_user(!!used_math(), &sc
->sc_used_math
);
2525 * Save FPU state to signal context. Signal handler will "inherit"
2526 * current FPU state.
2530 if (!is_fpu_owner()) {
2532 restore_fp(current
);
2534 err
|= save_fp_context(sc
);
2543 restore_sigcontext(CPUState
*regs
, struct target_sigcontext
*sc
)
2547 err
|= __get_user(regs
->CP0_EPC
, &sc
->sc_pc
);
2549 err
|= __get_user(regs
->active_tc
.HI
[0], &sc
->sc_mdhi
);
2550 err
|= __get_user(regs
->active_tc
.LO
[0], &sc
->sc_mdlo
);
2552 #define restore_gp_reg(i) do { \
2553 err |= __get_user(regs->active_tc.gpr[i], &sc->sc_regs[i]); \
2555 restore_gp_reg( 1); restore_gp_reg( 2); restore_gp_reg( 3);
2556 restore_gp_reg( 4); restore_gp_reg( 5); restore_gp_reg( 6);
2557 restore_gp_reg( 7); restore_gp_reg( 8); restore_gp_reg( 9);
2558 restore_gp_reg(10); restore_gp_reg(11); restore_gp_reg(12);
2559 restore_gp_reg(13); restore_gp_reg(14); restore_gp_reg(15);
2560 restore_gp_reg(16); restore_gp_reg(17); restore_gp_reg(18);
2561 restore_gp_reg(19); restore_gp_reg(20); restore_gp_reg(21);
2562 restore_gp_reg(22); restore_gp_reg(23); restore_gp_reg(24);
2563 restore_gp_reg(25); restore_gp_reg(26); restore_gp_reg(27);
2564 restore_gp_reg(28); restore_gp_reg(29); restore_gp_reg(30);
2566 #undef restore_gp_reg
2570 err
|= __get_user(treg
, &sc
->sc_hi1
); mthi1(treg
);
2571 err
|= __get_user(treg
, &sc
->sc_lo1
); mtlo1(treg
);
2572 err
|= __get_user(treg
, &sc
->sc_hi2
); mthi2(treg
);
2573 err
|= __get_user(treg
, &sc
->sc_lo2
); mtlo2(treg
);
2574 err
|= __get_user(treg
, &sc
->sc_hi3
); mthi3(treg
);
2575 err
|= __get_user(treg
, &sc
->sc_lo3
); mtlo3(treg
);
2576 err
|= __get_user(treg
, &sc
->sc_dsp
); wrdsp(treg
, DSP_MASK
);
2579 err
|= __get_user(regs
->hi
, &sc
->sc_hi
[0]);
2580 err
|= __get_user(regs
->lo
, &sc
->sc_lo
[0]);
2582 err
|= __get_user(treg
, &sc
->sc_hi
[1]); mthi1(treg
);
2583 err
|= __get_user(treg
, &sc
->sc_lo
[1]); mthi1(treg
);
2584 err
|= __get_user(treg
, &sc
->sc_hi
[2]); mthi2(treg
);
2585 err
|= __get_user(treg
, &sc
->sc_lo
[2]); mthi2(treg
);
2586 err
|= __get_user(treg
, &sc
->sc_hi
[3]); mthi3(treg
);
2587 err
|= __get_user(treg
, &sc
->sc_lo
[3]); mthi3(treg
);
2588 err
|= __get_user(treg
, &sc
->sc_dsp
); wrdsp(treg
, DSP_MASK
);
2592 err
|= __get_user(used_math
, &sc
->sc_used_math
);
2593 conditional_used_math(used_math
);
2598 /* restore fpu context if we have used it before */
2600 err
|= restore_fp_context(sc
);
2602 /* signal handler may have used FPU. Give it up. */
2611 * Determine which stack to use..
2613 static inline abi_ulong
2614 get_sigframe(struct target_sigaction
*ka
, CPUState
*regs
, size_t frame_size
)
2618 /* Default to using normal stack */
2619 sp
= regs
->active_tc
.gpr
[29];
2622 * FPU emulator may have it's own trampoline active just
2623 * above the user stack, 16-bytes before the next lowest
2624 * 16 byte boundary. Try to avoid trashing it.
2628 /* This is the X/Open sanctioned signal stack switching. */
2629 if ((ka
->sa_flags
& TARGET_SA_ONSTACK
) && (sas_ss_flags (sp
) == 0)) {
2630 sp
= target_sigaltstack_used
.ss_sp
+ target_sigaltstack_used
.ss_size
;
2633 return (sp
- frame_size
) & ~7;
2636 /* compare linux/arch/mips/kernel/signal.c:setup_frame() */
2637 static void setup_frame(int sig
, struct target_sigaction
* ka
,
2638 target_sigset_t
*set
, CPUState
*regs
)
2640 struct sigframe
*frame
;
2641 abi_ulong frame_addr
;
2644 frame_addr
= get_sigframe(ka
, regs
, sizeof(*frame
));
2645 if (!lock_user_struct(VERIFY_WRITE
, frame
, frame_addr
, 0))
2648 install_sigtramp(frame
->sf_code
, TARGET_NR_sigreturn
);
2650 if(setup_sigcontext(regs
, &frame
->sf_sc
))
2653 for(i
= 0; i
< TARGET_NSIG_WORDS
; i
++) {
2654 if(__put_user(set
->sig
[i
], &frame
->sf_mask
.sig
[i
]))
2659 * Arguments to signal handler:
2661 * a0 = signal number
2662 * a1 = 0 (should be cause)
2663 * a2 = pointer to struct sigcontext
2665 * $25 and PC point to the signal handler, $29 points to the
2668 regs
->active_tc
.gpr
[ 4] = sig
;
2669 regs
->active_tc
.gpr
[ 5] = 0;
2670 regs
->active_tc
.gpr
[ 6] = frame_addr
+ offsetof(struct sigframe
, sf_sc
);
2671 regs
->active_tc
.gpr
[29] = frame_addr
;
2672 regs
->active_tc
.gpr
[31] = frame_addr
+ offsetof(struct sigframe
, sf_code
);
2673 /* The original kernel code sets CP0_EPC to the handler
2674 * since it returns to userland using eret
2675 * we cannot do this here, and we must set PC directly */
2676 regs
->active_tc
.PC
= regs
->active_tc
.gpr
[25] = ka
->_sa_handler
;
2677 unlock_user_struct(frame
, frame_addr
, 1);
2681 unlock_user_struct(frame
, frame_addr
, 1);
2682 force_sig(TARGET_SIGSEGV
/*, current*/);
2686 long do_sigreturn(CPUState
*regs
)
2688 struct sigframe
*frame
;
2689 abi_ulong frame_addr
;
2691 target_sigset_t target_set
;
2694 #if defined(DEBUG_SIGNAL)
2695 fprintf(stderr
, "do_sigreturn\n");
2697 frame_addr
= regs
->active_tc
.gpr
[29];
2698 if (!lock_user_struct(VERIFY_READ
, frame
, frame_addr
, 1))
2701 for(i
= 0; i
< TARGET_NSIG_WORDS
; i
++) {
2702 if(__get_user(target_set
.sig
[i
], &frame
->sf_mask
.sig
[i
]))
2706 target_to_host_sigset_internal(&blocked
, &target_set
);
2707 sigprocmask(SIG_SETMASK
, &blocked
, NULL
);
2709 if (restore_sigcontext(regs
, &frame
->sf_sc
))
2714 * Don't let your children do this ...
2716 __asm__
__volatile__(
2724 regs
->active_tc
.PC
= regs
->CP0_EPC
;
2725 /* I am not sure this is right, but it seems to work
2726 * maybe a problem with nested signals ? */
2728 return -TARGET_QEMU_ESIGRETURN
;
2731 force_sig(TARGET_SIGSEGV
/*, current*/);
2735 static void setup_rt_frame(int sig
, struct target_sigaction
*ka
,
2736 target_siginfo_t
*info
,
2737 target_sigset_t
*set
, CPUState
*env
)
2739 struct target_rt_sigframe
*frame
;
2740 abi_ulong frame_addr
;
2743 frame_addr
= get_sigframe(ka
, env
, sizeof(*frame
));
2744 if (!lock_user_struct(VERIFY_WRITE
, frame
, frame_addr
, 0))
2747 install_sigtramp(frame
->rs_code
, TARGET_NR_rt_sigreturn
);
2749 copy_siginfo_to_user(&frame
->rs_info
, info
);
2751 __put_user(0, &frame
->rs_uc
.tuc_flags
);
2752 __put_user(0, &frame
->rs_uc
.tuc_link
);
2753 __put_user(target_sigaltstack_used
.ss_sp
, &frame
->rs_uc
.tuc_stack
.ss_sp
);
2754 __put_user(target_sigaltstack_used
.ss_size
, &frame
->rs_uc
.tuc_stack
.ss_size
);
2755 __put_user(sas_ss_flags(get_sp_from_cpustate(env
)),
2756 &frame
->rs_uc
.tuc_stack
.ss_flags
);
2758 setup_sigcontext(env
, &frame
->rs_uc
.tuc_mcontext
);
2760 for(i
= 0; i
< TARGET_NSIG_WORDS
; i
++) {
2761 __put_user(set
->sig
[i
], &frame
->rs_uc
.tuc_sigmask
.sig
[i
]);
2765 * Arguments to signal handler:
2767 * a0 = signal number
2768 * a1 = pointer to struct siginfo
2769 * a2 = pointer to struct ucontext
2771 * $25 and PC point to the signal handler, $29 points to the
2774 env
->active_tc
.gpr
[ 4] = sig
;
2775 env
->active_tc
.gpr
[ 5] = frame_addr
2776 + offsetof(struct target_rt_sigframe
, rs_info
);
2777 env
->active_tc
.gpr
[ 6] = frame_addr
2778 + offsetof(struct target_rt_sigframe
, rs_uc
);
2779 env
->active_tc
.gpr
[29] = frame_addr
;
2780 env
->active_tc
.gpr
[31] = frame_addr
2781 + offsetof(struct target_rt_sigframe
, rs_code
);
2782 /* The original kernel code sets CP0_EPC to the handler
2783 * since it returns to userland using eret
2784 * we cannot do this here, and we must set PC directly */
2785 env
->active_tc
.PC
= env
->active_tc
.gpr
[25] = ka
->_sa_handler
;
2786 unlock_user_struct(frame
, frame_addr
, 1);
2790 unlock_user_struct(frame
, frame_addr
, 1);
2791 force_sig(TARGET_SIGSEGV
/*, current*/);
2795 long do_rt_sigreturn(CPUState
*env
)
2797 struct target_rt_sigframe
*frame
;
2798 abi_ulong frame_addr
;
2801 #if defined(DEBUG_SIGNAL)
2802 fprintf(stderr
, "do_rt_sigreturn\n");
2804 frame_addr
= env
->active_tc
.gpr
[29];
2805 if (!lock_user_struct(VERIFY_READ
, frame
, frame_addr
, 1))
2808 target_to_host_sigset(&blocked
, &frame
->rs_uc
.tuc_sigmask
);
2809 sigprocmask(SIG_SETMASK
, &blocked
, NULL
);
2811 if (restore_sigcontext(env
, &frame
->rs_uc
.tuc_mcontext
))
2814 if (do_sigaltstack(frame_addr
+
2815 offsetof(struct target_rt_sigframe
, rs_uc
.tuc_stack
),
2816 0, get_sp_from_cpustate(env
)) == -EFAULT
)
2819 env
->active_tc
.PC
= env
->CP0_EPC
;
2820 /* I am not sure this is right, but it seems to work
2821 * maybe a problem with nested signals ? */
2823 return -TARGET_QEMU_ESIGRETURN
;
2826 force_sig(TARGET_SIGSEGV
/*, current*/);
2830 #elif defined(TARGET_SH4)
2833 * code and data structures from linux kernel:
2834 * include/asm-sh/sigcontext.h
2835 * arch/sh/kernel/signal.c
2838 struct target_sigcontext
{
2839 target_ulong oldmask
;
2842 target_ulong sc_gregs
[16];
2846 target_ulong sc_gbr
;
2847 target_ulong sc_mach
;
2848 target_ulong sc_macl
;
2851 target_ulong sc_fpregs
[16];
2852 target_ulong sc_xfpregs
[16];
2853 unsigned int sc_fpscr
;
2854 unsigned int sc_fpul
;
2855 unsigned int sc_ownedfp
;
2858 struct target_sigframe
2860 struct target_sigcontext sc
;
2861 target_ulong extramask
[TARGET_NSIG_WORDS
-1];
2862 uint16_t retcode
[3];
2866 struct target_ucontext
{
2867 target_ulong tuc_flags
;
2868 struct target_ucontext
*tuc_link
;
2869 target_stack_t tuc_stack
;
2870 struct target_sigcontext tuc_mcontext
;
2871 target_sigset_t tuc_sigmask
; /* mask last for extensibility */
2874 struct target_rt_sigframe
2876 struct target_siginfo info
;
2877 struct target_ucontext uc
;
2878 uint16_t retcode
[3];
2882 #define MOVW(n) (0x9300|((n)-2)) /* Move mem word at PC+n to R3 */
2883 #define TRAP_NOARG 0xc310 /* Syscall w/no args (NR in R3) SH3/4 */
2885 static abi_ulong
get_sigframe(struct target_sigaction
*ka
,
2886 unsigned long sp
, size_t frame_size
)
2888 if ((ka
->sa_flags
& TARGET_SA_ONSTACK
) && (sas_ss_flags(sp
) == 0)) {
2889 sp
= target_sigaltstack_used
.ss_sp
+ target_sigaltstack_used
.ss_size
;
2892 return (sp
- frame_size
) & -8ul;
2895 static int setup_sigcontext(struct target_sigcontext
*sc
,
2896 CPUState
*regs
, unsigned long mask
)
2901 #define COPY(x) err |= __put_user(regs->x, &sc->sc_##x)
2902 COPY(gregs
[0]); COPY(gregs
[1]);
2903 COPY(gregs
[2]); COPY(gregs
[3]);
2904 COPY(gregs
[4]); COPY(gregs
[5]);
2905 COPY(gregs
[6]); COPY(gregs
[7]);
2906 COPY(gregs
[8]); COPY(gregs
[9]);
2907 COPY(gregs
[10]); COPY(gregs
[11]);
2908 COPY(gregs
[12]); COPY(gregs
[13]);
2909 COPY(gregs
[14]); COPY(gregs
[15]);
2910 COPY(gbr
); COPY(mach
);
2911 COPY(macl
); COPY(pr
);
2915 for (i
=0; i
<16; i
++) {
2916 err
|= __put_user(regs
->fregs
[i
], &sc
->sc_fpregs
[i
]);
2918 err
|= __put_user(regs
->fpscr
, &sc
->sc_fpscr
);
2919 err
|= __put_user(regs
->fpul
, &sc
->sc_fpul
);
2921 /* non-iBCS2 extensions.. */
2922 err
|= __put_user(mask
, &sc
->oldmask
);
2927 static int restore_sigcontext(CPUState
*regs
, struct target_sigcontext
*sc
,
2930 unsigned int err
= 0;
2933 #define COPY(x) err |= __get_user(regs->x, &sc->sc_##x)
2935 COPY(gregs
[2]); COPY(gregs
[3]);
2936 COPY(gregs
[4]); COPY(gregs
[5]);
2937 COPY(gregs
[6]); COPY(gregs
[7]);
2938 COPY(gregs
[8]); COPY(gregs
[9]);
2939 COPY(gregs
[10]); COPY(gregs
[11]);
2940 COPY(gregs
[12]); COPY(gregs
[13]);
2941 COPY(gregs
[14]); COPY(gregs
[15]);
2942 COPY(gbr
); COPY(mach
);
2943 COPY(macl
); COPY(pr
);
2947 for (i
=0; i
<16; i
++) {
2948 err
|= __get_user(regs
->fregs
[i
], &sc
->sc_fpregs
[i
]);
2950 err
|= __get_user(regs
->fpscr
, &sc
->sc_fpscr
);
2951 err
|= __get_user(regs
->fpul
, &sc
->sc_fpul
);
2953 regs
->tra
= -1; /* disable syscall checks */
2954 err
|= __get_user(*r0_p
, &sc
->sc_gregs
[0]);
2958 static void setup_frame(int sig
, struct target_sigaction
*ka
,
2959 target_sigset_t
*set
, CPUState
*regs
)
2961 struct target_sigframe
*frame
;
2962 abi_ulong frame_addr
;
2967 frame_addr
= get_sigframe(ka
, regs
->gregs
[15], sizeof(*frame
));
2968 if (!lock_user_struct(VERIFY_WRITE
, frame
, frame_addr
, 0))
2971 signal
= current_exec_domain_sig(sig
);
2973 err
|= setup_sigcontext(&frame
->sc
, regs
, set
->sig
[0]);
2975 for (i
= 0; i
< TARGET_NSIG_WORDS
- 1; i
++) {
2976 err
|= __put_user(set
->sig
[i
+ 1], &frame
->extramask
[i
]);
2979 /* Set up to return from userspace. If provided, use a stub
2980 already in userspace. */
2981 if (ka
->sa_flags
& TARGET_SA_RESTORER
) {
2982 regs
->pr
= (unsigned long) ka
->sa_restorer
;
2984 /* Generate return code (system call to sigreturn) */
2985 err
|= __put_user(MOVW(2), &frame
->retcode
[0]);
2986 err
|= __put_user(TRAP_NOARG
, &frame
->retcode
[1]);
2987 err
|= __put_user((TARGET_NR_sigreturn
), &frame
->retcode
[2]);
2988 regs
->pr
= (unsigned long) frame
->retcode
;
2994 /* Set up registers for signal handler */
2995 regs
->gregs
[15] = (unsigned long) frame
;
2996 regs
->gregs
[4] = signal
; /* Arg for signal handler */
2998 regs
->gregs
[6] = (unsigned long) &frame
->sc
;
2999 regs
->pc
= (unsigned long) ka
->_sa_handler
;
3001 unlock_user_struct(frame
, frame_addr
, 1);
3005 unlock_user_struct(frame
, frame_addr
, 1);
3006 force_sig(TARGET_SIGSEGV
);
3009 static void setup_rt_frame(int sig
, struct target_sigaction
*ka
,
3010 target_siginfo_t
*info
,
3011 target_sigset_t
*set
, CPUState
*regs
)
3013 struct target_rt_sigframe
*frame
;
3014 abi_ulong frame_addr
;
3019 frame_addr
= get_sigframe(ka
, regs
->gregs
[15], sizeof(*frame
));
3020 if (!lock_user_struct(VERIFY_WRITE
, frame
, frame_addr
, 0))
3023 signal
= current_exec_domain_sig(sig
);
3025 err
|= copy_siginfo_to_user(&frame
->info
, info
);
3027 /* Create the ucontext. */
3028 err
|= __put_user(0, &frame
->uc
.tuc_flags
);
3029 err
|= __put_user(0, (unsigned long *)&frame
->uc
.tuc_link
);
3030 err
|= __put_user((unsigned long)target_sigaltstack_used
.ss_sp
,
3031 &frame
->uc
.tuc_stack
.ss_sp
);
3032 err
|= __put_user(sas_ss_flags(regs
->gregs
[15]),
3033 &frame
->uc
.tuc_stack
.ss_flags
);
3034 err
|= __put_user(target_sigaltstack_used
.ss_size
,
3035 &frame
->uc
.tuc_stack
.ss_size
);
3036 err
|= setup_sigcontext(&frame
->uc
.tuc_mcontext
,
3038 for(i
= 0; i
< TARGET_NSIG_WORDS
; i
++) {
3039 err
|= __put_user(set
->sig
[i
], &frame
->uc
.tuc_sigmask
.sig
[i
]);
3042 /* Set up to return from userspace. If provided, use a stub
3043 already in userspace. */
3044 if (ka
->sa_flags
& TARGET_SA_RESTORER
) {
3045 regs
->pr
= (unsigned long) ka
->sa_restorer
;
3047 /* Generate return code (system call to sigreturn) */
3048 err
|= __put_user(MOVW(2), &frame
->retcode
[0]);
3049 err
|= __put_user(TRAP_NOARG
, &frame
->retcode
[1]);
3050 err
|= __put_user((TARGET_NR_rt_sigreturn
), &frame
->retcode
[2]);
3051 regs
->pr
= (unsigned long) frame
->retcode
;
3057 /* Set up registers for signal handler */
3058 regs
->gregs
[15] = (unsigned long) frame
;
3059 regs
->gregs
[4] = signal
; /* Arg for signal handler */
3060 regs
->gregs
[5] = (unsigned long) &frame
->info
;
3061 regs
->gregs
[6] = (unsigned long) &frame
->uc
;
3062 regs
->pc
= (unsigned long) ka
->_sa_handler
;
3064 unlock_user_struct(frame
, frame_addr
, 1);
3068 unlock_user_struct(frame
, frame_addr
, 1);
3069 force_sig(TARGET_SIGSEGV
);
3072 long do_sigreturn(CPUState
*regs
)
3074 struct target_sigframe
*frame
;
3075 abi_ulong frame_addr
;
3077 target_sigset_t target_set
;
3082 #if defined(DEBUG_SIGNAL)
3083 fprintf(stderr
, "do_sigreturn\n");
3085 frame_addr
= regs
->gregs
[15];
3086 if (!lock_user_struct(VERIFY_READ
, frame
, frame_addr
, 1))
3089 err
|= __get_user(target_set
.sig
[0], &frame
->sc
.oldmask
);
3090 for(i
= 1; i
< TARGET_NSIG_WORDS
; i
++) {
3091 err
|= (__get_user(target_set
.sig
[i
], &frame
->extramask
[i
- 1]));
3097 target_to_host_sigset_internal(&blocked
, &target_set
);
3098 sigprocmask(SIG_SETMASK
, &blocked
, NULL
);
3100 if (restore_sigcontext(regs
, &frame
->sc
, &r0
))
3103 unlock_user_struct(frame
, frame_addr
, 0);
3107 unlock_user_struct(frame
, frame_addr
, 0);
3108 force_sig(TARGET_SIGSEGV
);
3112 long do_rt_sigreturn(CPUState
*regs
)
3114 struct target_rt_sigframe
*frame
;
3115 abi_ulong frame_addr
;
3119 #if defined(DEBUG_SIGNAL)
3120 fprintf(stderr
, "do_rt_sigreturn\n");
3122 frame_addr
= regs
->gregs
[15];
3123 if (!lock_user_struct(VERIFY_READ
, frame
, frame_addr
, 1))
3126 target_to_host_sigset(&blocked
, &frame
->uc
.tuc_sigmask
);
3127 sigprocmask(SIG_SETMASK
, &blocked
, NULL
);
3129 if (restore_sigcontext(regs
, &frame
->uc
.tuc_mcontext
, &r0
))
3132 if (do_sigaltstack(frame_addr
+
3133 offsetof(struct target_rt_sigframe
, uc
.tuc_stack
),
3134 0, get_sp_from_cpustate(regs
)) == -EFAULT
)
3137 unlock_user_struct(frame
, frame_addr
, 0);
3141 unlock_user_struct(frame
, frame_addr
, 0);
3142 force_sig(TARGET_SIGSEGV
);
3145 #elif defined(TARGET_MICROBLAZE)
3147 struct target_sigcontext
{
3148 struct target_pt_regs regs
; /* needs to be first */
3152 struct target_stack_t
{
3155 unsigned int ss_size
;
3158 struct target_ucontext
{
3159 abi_ulong tuc_flags
;
3161 struct target_stack_t tuc_stack
;
3162 struct target_sigcontext tuc_mcontext
;
3163 uint32_t tuc_extramask
[TARGET_NSIG_WORDS
- 1];
3166 /* Signal frames. */
3167 struct target_signal_frame
{
3168 struct target_ucontext uc
;
3169 uint32_t extramask
[TARGET_NSIG_WORDS
- 1];
3173 struct rt_signal_frame
{
3174 struct siginfo info
;
3179 static void setup_sigcontext(struct target_sigcontext
*sc
, CPUState
*env
)
3181 __put_user(env
->regs
[0], &sc
->regs
.r0
);
3182 __put_user(env
->regs
[1], &sc
->regs
.r1
);
3183 __put_user(env
->regs
[2], &sc
->regs
.r2
);
3184 __put_user(env
->regs
[3], &sc
->regs
.r3
);
3185 __put_user(env
->regs
[4], &sc
->regs
.r4
);
3186 __put_user(env
->regs
[5], &sc
->regs
.r5
);
3187 __put_user(env
->regs
[6], &sc
->regs
.r6
);
3188 __put_user(env
->regs
[7], &sc
->regs
.r7
);
3189 __put_user(env
->regs
[8], &sc
->regs
.r8
);
3190 __put_user(env
->regs
[9], &sc
->regs
.r9
);
3191 __put_user(env
->regs
[10], &sc
->regs
.r10
);
3192 __put_user(env
->regs
[11], &sc
->regs
.r11
);
3193 __put_user(env
->regs
[12], &sc
->regs
.r12
);
3194 __put_user(env
->regs
[13], &sc
->regs
.r13
);
3195 __put_user(env
->regs
[14], &sc
->regs
.r14
);
3196 __put_user(env
->regs
[15], &sc
->regs
.r15
);
3197 __put_user(env
->regs
[16], &sc
->regs
.r16
);
3198 __put_user(env
->regs
[17], &sc
->regs
.r17
);
3199 __put_user(env
->regs
[18], &sc
->regs
.r18
);
3200 __put_user(env
->regs
[19], &sc
->regs
.r19
);
3201 __put_user(env
->regs
[20], &sc
->regs
.r20
);
3202 __put_user(env
->regs
[21], &sc
->regs
.r21
);
3203 __put_user(env
->regs
[22], &sc
->regs
.r22
);
3204 __put_user(env
->regs
[23], &sc
->regs
.r23
);
3205 __put_user(env
->regs
[24], &sc
->regs
.r24
);
3206 __put_user(env
->regs
[25], &sc
->regs
.r25
);
3207 __put_user(env
->regs
[26], &sc
->regs
.r26
);
3208 __put_user(env
->regs
[27], &sc
->regs
.r27
);
3209 __put_user(env
->regs
[28], &sc
->regs
.r28
);
3210 __put_user(env
->regs
[29], &sc
->regs
.r29
);
3211 __put_user(env
->regs
[30], &sc
->regs
.r30
);
3212 __put_user(env
->regs
[31], &sc
->regs
.r31
);
3213 __put_user(env
->sregs
[SR_PC
], &sc
->regs
.pc
);
3216 static void restore_sigcontext(struct target_sigcontext
*sc
, CPUState
*env
)
3218 __get_user(env
->regs
[0], &sc
->regs
.r0
);
3219 __get_user(env
->regs
[1], &sc
->regs
.r1
);
3220 __get_user(env
->regs
[2], &sc
->regs
.r2
);
3221 __get_user(env
->regs
[3], &sc
->regs
.r3
);
3222 __get_user(env
->regs
[4], &sc
->regs
.r4
);
3223 __get_user(env
->regs
[5], &sc
->regs
.r5
);
3224 __get_user(env
->regs
[6], &sc
->regs
.r6
);
3225 __get_user(env
->regs
[7], &sc
->regs
.r7
);
3226 __get_user(env
->regs
[8], &sc
->regs
.r8
);
3227 __get_user(env
->regs
[9], &sc
->regs
.r9
);
3228 __get_user(env
->regs
[10], &sc
->regs
.r10
);
3229 __get_user(env
->regs
[11], &sc
->regs
.r11
);
3230 __get_user(env
->regs
[12], &sc
->regs
.r12
);
3231 __get_user(env
->regs
[13], &sc
->regs
.r13
);
3232 __get_user(env
->regs
[14], &sc
->regs
.r14
);
3233 __get_user(env
->regs
[15], &sc
->regs
.r15
);
3234 __get_user(env
->regs
[16], &sc
->regs
.r16
);
3235 __get_user(env
->regs
[17], &sc
->regs
.r17
);
3236 __get_user(env
->regs
[18], &sc
->regs
.r18
);
3237 __get_user(env
->regs
[19], &sc
->regs
.r19
);
3238 __get_user(env
->regs
[20], &sc
->regs
.r20
);
3239 __get_user(env
->regs
[21], &sc
->regs
.r21
);
3240 __get_user(env
->regs
[22], &sc
->regs
.r22
);
3241 __get_user(env
->regs
[23], &sc
->regs
.r23
);
3242 __get_user(env
->regs
[24], &sc
->regs
.r24
);
3243 __get_user(env
->regs
[25], &sc
->regs
.r25
);
3244 __get_user(env
->regs
[26], &sc
->regs
.r26
);
3245 __get_user(env
->regs
[27], &sc
->regs
.r27
);
3246 __get_user(env
->regs
[28], &sc
->regs
.r28
);
3247 __get_user(env
->regs
[29], &sc
->regs
.r29
);
3248 __get_user(env
->regs
[30], &sc
->regs
.r30
);
3249 __get_user(env
->regs
[31], &sc
->regs
.r31
);
3250 __get_user(env
->sregs
[SR_PC
], &sc
->regs
.pc
);
3253 static abi_ulong
get_sigframe(struct target_sigaction
*ka
,
3254 CPUState
*env
, int frame_size
)
3256 abi_ulong sp
= env
->regs
[1];
3258 if ((ka
->sa_flags
& SA_ONSTACK
) != 0 && !on_sig_stack(sp
))
3259 sp
= target_sigaltstack_used
.ss_sp
+ target_sigaltstack_used
.ss_size
;
3261 return ((sp
- frame_size
) & -8UL);
3264 static void setup_frame(int sig
, struct target_sigaction
*ka
,
3265 target_sigset_t
*set
, CPUState
*env
)
3267 struct target_signal_frame
*frame
;
3268 abi_ulong frame_addr
;
3272 frame_addr
= get_sigframe(ka
, env
, sizeof *frame
);
3273 if (!lock_user_struct(VERIFY_WRITE
, frame
, frame_addr
, 0))
3276 /* Save the mask. */
3277 err
|= __put_user(set
->sig
[0], &frame
->uc
.tuc_mcontext
.oldmask
);
3281 for(i
= 1; i
< TARGET_NSIG_WORDS
; i
++) {
3282 if (__put_user(set
->sig
[i
], &frame
->extramask
[i
- 1]))
3286 setup_sigcontext(&frame
->uc
.tuc_mcontext
, env
);
3288 /* Set up to return from userspace. If provided, use a stub
3289 already in userspace. */
3290 /* minus 8 is offset to cater for "rtsd r15,8" offset */
3291 if (ka
->sa_flags
& TARGET_SA_RESTORER
) {
3292 env
->regs
[15] = ((unsigned long)ka
->sa_restorer
)-8;
3295 /* Note, these encodings are _big endian_! */
3296 /* addi r12, r0, __NR_sigreturn */
3297 t
= 0x31800000UL
| TARGET_NR_sigreturn
;
3298 err
|= __put_user(t
, frame
->tramp
+ 0);
3301 err
|= __put_user(t
, frame
->tramp
+ 1);
3303 /* Return from sighandler will jump to the tramp.
3304 Negative 8 offset because return is rtsd r15, 8 */
3305 env
->regs
[15] = ((unsigned long)frame
->tramp
) - 8;
3311 /* Set up registers for signal handler */
3312 env
->regs
[1] = (unsigned long) frame
;
3313 /* Signal handler args: */
3314 env
->regs
[5] = sig
; /* Arg 0: signum */
3316 env
->regs
[7] = (unsigned long) &frame
->uc
; /* arg 1: sigcontext */
3318 /* Offset of 4 to handle microblaze rtid r14, 0 */
3319 env
->sregs
[SR_PC
] = (unsigned long)ka
->_sa_handler
;
3321 unlock_user_struct(frame
, frame_addr
, 1);
3324 unlock_user_struct(frame
, frame_addr
, 1);
3325 force_sig(TARGET_SIGSEGV
);
3328 static void setup_rt_frame(int sig
, struct target_sigaction
*ka
,
3329 target_siginfo_t
*info
,
3330 target_sigset_t
*set
, CPUState
*env
)
3332 fprintf(stderr
, "Microblaze setup_rt_frame: not implemented\n");
3335 long do_sigreturn(CPUState
*env
)
3337 struct target_signal_frame
*frame
;
3338 abi_ulong frame_addr
;
3339 target_sigset_t target_set
;
3343 frame_addr
= env
->regs
[R_SP
];
3344 /* Make sure the guest isn't playing games. */
3345 if (!lock_user_struct(VERIFY_WRITE
, frame
, frame_addr
, 1))
3348 /* Restore blocked signals */
3349 if (__get_user(target_set
.sig
[0], &frame
->uc
.tuc_mcontext
.oldmask
))
3351 for(i
= 1; i
< TARGET_NSIG_WORDS
; i
++) {
3352 if (__get_user(target_set
.sig
[i
], &frame
->extramask
[i
- 1]))
3355 target_to_host_sigset_internal(&set
, &target_set
);
3356 sigprocmask(SIG_SETMASK
, &set
, NULL
);
3358 restore_sigcontext(&frame
->uc
.tuc_mcontext
, env
);
3359 /* We got here through a sigreturn syscall, our path back is via an
3360 rtb insn so setup r14 for that. */
3361 env
->regs
[14] = env
->sregs
[SR_PC
];
3363 unlock_user_struct(frame
, frame_addr
, 0);
3364 return env
->regs
[10];
3366 unlock_user_struct(frame
, frame_addr
, 0);
3367 force_sig(TARGET_SIGSEGV
);
3370 long do_rt_sigreturn(CPUState
*env
)
3372 fprintf(stderr
, "Microblaze do_rt_sigreturn: not implemented\n");
3373 return -TARGET_ENOSYS
;
3376 #elif defined(TARGET_CRIS)
3378 struct target_sigcontext
{
3379 struct target_pt_regs regs
; /* needs to be first */
3381 uint32_t usp
; /* usp before stacking this gunk on it */
3384 /* Signal frames. */
3385 struct target_signal_frame
{
3386 struct target_sigcontext sc
;
3387 uint32_t extramask
[TARGET_NSIG_WORDS
- 1];
3388 uint8_t retcode
[8]; /* Trampoline code. */
3391 struct rt_signal_frame
{
3392 struct siginfo
*pinfo
;
3394 struct siginfo info
;
3396 uint8_t retcode
[8]; /* Trampoline code. */
3399 static void setup_sigcontext(struct target_sigcontext
*sc
, CPUState
*env
)
3401 __put_user(env
->regs
[0], &sc
->regs
.r0
);
3402 __put_user(env
->regs
[1], &sc
->regs
.r1
);
3403 __put_user(env
->regs
[2], &sc
->regs
.r2
);
3404 __put_user(env
->regs
[3], &sc
->regs
.r3
);
3405 __put_user(env
->regs
[4], &sc
->regs
.r4
);
3406 __put_user(env
->regs
[5], &sc
->regs
.r5
);
3407 __put_user(env
->regs
[6], &sc
->regs
.r6
);
3408 __put_user(env
->regs
[7], &sc
->regs
.r7
);
3409 __put_user(env
->regs
[8], &sc
->regs
.r8
);
3410 __put_user(env
->regs
[9], &sc
->regs
.r9
);
3411 __put_user(env
->regs
[10], &sc
->regs
.r10
);
3412 __put_user(env
->regs
[11], &sc
->regs
.r11
);
3413 __put_user(env
->regs
[12], &sc
->regs
.r12
);
3414 __put_user(env
->regs
[13], &sc
->regs
.r13
);
3415 __put_user(env
->regs
[14], &sc
->usp
);
3416 __put_user(env
->regs
[15], &sc
->regs
.acr
);
3417 __put_user(env
->pregs
[PR_MOF
], &sc
->regs
.mof
);
3418 __put_user(env
->pregs
[PR_SRP
], &sc
->regs
.srp
);
3419 __put_user(env
->pc
, &sc
->regs
.erp
);
3422 static void restore_sigcontext(struct target_sigcontext
*sc
, CPUState
*env
)
3424 __get_user(env
->regs
[0], &sc
->regs
.r0
);
3425 __get_user(env
->regs
[1], &sc
->regs
.r1
);
3426 __get_user(env
->regs
[2], &sc
->regs
.r2
);
3427 __get_user(env
->regs
[3], &sc
->regs
.r3
);
3428 __get_user(env
->regs
[4], &sc
->regs
.r4
);
3429 __get_user(env
->regs
[5], &sc
->regs
.r5
);
3430 __get_user(env
->regs
[6], &sc
->regs
.r6
);
3431 __get_user(env
->regs
[7], &sc
->regs
.r7
);
3432 __get_user(env
->regs
[8], &sc
->regs
.r8
);
3433 __get_user(env
->regs
[9], &sc
->regs
.r9
);
3434 __get_user(env
->regs
[10], &sc
->regs
.r10
);
3435 __get_user(env
->regs
[11], &sc
->regs
.r11
);
3436 __get_user(env
->regs
[12], &sc
->regs
.r12
);
3437 __get_user(env
->regs
[13], &sc
->regs
.r13
);
3438 __get_user(env
->regs
[14], &sc
->usp
);
3439 __get_user(env
->regs
[15], &sc
->regs
.acr
);
3440 __get_user(env
->pregs
[PR_MOF
], &sc
->regs
.mof
);
3441 __get_user(env
->pregs
[PR_SRP
], &sc
->regs
.srp
);
3442 __get_user(env
->pc
, &sc
->regs
.erp
);
3445 static abi_ulong
get_sigframe(CPUState
*env
, int framesize
)
3448 /* Align the stack downwards to 4. */
3449 sp
= (env
->regs
[R_SP
] & ~3);
3450 return sp
- framesize
;
3453 static void setup_frame(int sig
, struct target_sigaction
*ka
,
3454 target_sigset_t
*set
, CPUState
*env
)
3456 struct target_signal_frame
*frame
;
3457 abi_ulong frame_addr
;
3461 frame_addr
= get_sigframe(env
, sizeof *frame
);
3462 if (!lock_user_struct(VERIFY_WRITE
, frame
, frame_addr
, 0))
3466 * The CRIS signal return trampoline. A real linux/CRIS kernel doesn't
3467 * use this trampoline anymore but it sets it up for GDB.
3468 * In QEMU, using the trampoline simplifies things a bit so we use it.
3470 * This is movu.w __NR_sigreturn, r9; break 13;
3472 err
|= __put_user(0x9c5f, frame
->retcode
+0);
3473 err
|= __put_user(TARGET_NR_sigreturn
,
3475 err
|= __put_user(0xe93d, frame
->retcode
+4);
3477 /* Save the mask. */
3478 err
|= __put_user(set
->sig
[0], &frame
->sc
.oldmask
);
3482 for(i
= 1; i
< TARGET_NSIG_WORDS
; i
++) {
3483 if (__put_user(set
->sig
[i
], &frame
->extramask
[i
- 1]))
3487 setup_sigcontext(&frame
->sc
, env
);
3489 /* Move the stack and setup the arguments for the handler. */
3490 env
->regs
[R_SP
] = (uint32_t) (unsigned long) frame
;
3491 env
->regs
[10] = sig
;
3492 env
->pc
= (unsigned long) ka
->_sa_handler
;
3493 /* Link SRP so the guest returns through the trampoline. */
3494 env
->pregs
[PR_SRP
] = (uint32_t) (unsigned long) &frame
->retcode
[0];
3496 unlock_user_struct(frame
, frame_addr
, 1);
3499 unlock_user_struct(frame
, frame_addr
, 1);
3500 force_sig(TARGET_SIGSEGV
);
3503 static void setup_rt_frame(int sig
, struct target_sigaction
*ka
,
3504 target_siginfo_t
*info
,
3505 target_sigset_t
*set
, CPUState
*env
)
3507 fprintf(stderr
, "CRIS setup_rt_frame: not implemented\n");
3510 long do_sigreturn(CPUState
*env
)
3512 struct target_signal_frame
*frame
;
3513 abi_ulong frame_addr
;
3514 target_sigset_t target_set
;
3518 frame_addr
= env
->regs
[R_SP
];
3519 /* Make sure the guest isn't playing games. */
3520 if (!lock_user_struct(VERIFY_WRITE
, frame
, frame_addr
, 1))
3523 /* Restore blocked signals */
3524 if (__get_user(target_set
.sig
[0], &frame
->sc
.oldmask
))
3526 for(i
= 1; i
< TARGET_NSIG_WORDS
; i
++) {
3527 if (__get_user(target_set
.sig
[i
], &frame
->extramask
[i
- 1]))
3530 target_to_host_sigset_internal(&set
, &target_set
);
3531 sigprocmask(SIG_SETMASK
, &set
, NULL
);
3533 restore_sigcontext(&frame
->sc
, env
);
3534 unlock_user_struct(frame
, frame_addr
, 0);
3535 return env
->regs
[10];
3537 unlock_user_struct(frame
, frame_addr
, 0);
3538 force_sig(TARGET_SIGSEGV
);
3541 long do_rt_sigreturn(CPUState
*env
)
3543 fprintf(stderr
, "CRIS do_rt_sigreturn: not implemented\n");
3544 return -TARGET_ENOSYS
;
3547 #elif defined(TARGET_PPC) && !defined(TARGET_PPC64)
3549 /* FIXME: Many of the structures are defined for both PPC and PPC64, but
3550 the signal handling is different enough that we haven't implemented
3551 support for PPC64 yet. Hence the restriction above.
3553 There are various #if'd blocks for code for TARGET_PPC64. These
3554 blocks should go away so that we can successfully run 32-bit and
3555 64-bit binaries on a QEMU configured for PPC64. */
3557 /* Size of dummy stack frame allocated when calling signal handler.
3558 See arch/powerpc/include/asm/ptrace.h. */
3559 #if defined(TARGET_PPC64)
3560 #define SIGNAL_FRAMESIZE 128
3562 #define SIGNAL_FRAMESIZE 64
3565 /* See arch/powerpc/include/asm/sigcontext.h. */
3566 struct target_sigcontext
{
3567 target_ulong _unused
[4];
3569 #if defined(TARGET_PPC64)
3572 target_ulong handler
;
3573 target_ulong oldmask
;
3574 target_ulong regs
; /* struct pt_regs __user * */
3575 /* TODO: PPC64 includes extra bits here. */
3578 /* Indices for target_mcontext.mc_gregs, below.
3579 See arch/powerpc/include/asm/ptrace.h for details. */
3615 TARGET_PT_ORIG_R3
= 34,
3620 /* Yes, there are two registers with #39. One is 64-bit only. */
3622 TARGET_PT_SOFTE
= 39,
3623 TARGET_PT_TRAP
= 40,
3625 TARGET_PT_DSISR
= 42,
3626 TARGET_PT_RESULT
= 43,
3627 TARGET_PT_REGS_COUNT
= 44
3630 /* See arch/powerpc/include/asm/ucontext.h. Only used for 32-bit PPC;
3631 on 64-bit PPC, sigcontext and mcontext are one and the same. */
3632 struct target_mcontext
{
3633 target_ulong mc_gregs
[48];
3634 /* Includes fpscr. */
3635 uint64_t mc_fregs
[33];
3636 target_ulong mc_pad
[2];
3637 /* We need to handle Altivec and SPE at the same time, which no
3638 kernel needs to do. Fortunately, the kernel defines this bit to
3639 be Altivec-register-large all the time, rather than trying to
3640 twiddle it based on the specific platform. */
3642 /* SPE vector registers. One extra for SPEFSCR. */
3644 /* Altivec vector registers. The packing of VSCR and VRSAVE
3645 varies depending on whether we're PPC64 or not: PPC64 splits
3646 them apart; PPC32 stuffs them together. */
3647 #if defined(TARGET_PPC64)
3648 #define QEMU_NVRREG 34
3650 #define QEMU_NVRREG 33
3652 ppc_avr_t altivec
[QEMU_NVRREG
];
3654 } mc_vregs
__attribute__((__aligned__(16)));
3657 struct target_ucontext
{
3658 target_ulong tuc_flags
;
3659 target_ulong tuc_link
; /* struct ucontext __user * */
3660 struct target_sigaltstack tuc_stack
;
3661 #if !defined(TARGET_PPC64)
3663 target_ulong tuc_regs
; /* struct mcontext __user *
3664 points to uc_mcontext field */
3666 target_sigset_t tuc_sigmask
;
3667 #if defined(TARGET_PPC64)
3668 target_sigset_t unused
[15]; /* Allow for uc_sigmask growth */
3669 struct target_sigcontext tuc_mcontext
;
3671 int32_t tuc_maskext
[30];
3672 int32_t tuc_pad2
[3];
3673 struct target_mcontext tuc_mcontext
;
3677 /* See arch/powerpc/kernel/signal_32.c. */
3678 struct target_sigframe
{
3679 struct target_sigcontext sctx
;
3680 struct target_mcontext mctx
;
3684 struct target_rt_sigframe
{
3685 struct target_siginfo info
;
3686 struct target_ucontext uc
;
3690 /* We use the mc_pad field for the signal return trampoline. */
3691 #define tramp mc_pad
3693 /* See arch/powerpc/kernel/signal.c. */
3694 static target_ulong
get_sigframe(struct target_sigaction
*ka
,
3698 target_ulong oldsp
, newsp
;
3700 oldsp
= env
->gpr
[1];
3702 if ((ka
->sa_flags
& TARGET_SA_ONSTACK
) &&
3703 (sas_ss_flags(oldsp
))) {
3704 oldsp
= (target_sigaltstack_used
.ss_sp
3705 + target_sigaltstack_used
.ss_size
);
3708 newsp
= (oldsp
- frame_size
) & ~0xFUL
;
3713 static int save_user_regs(CPUState
*env
, struct target_mcontext
*frame
,
3716 target_ulong msr
= env
->msr
;
3718 target_ulong ccr
= 0;
3720 /* In general, the kernel attempts to be intelligent about what it
3721 needs to save for Altivec/FP/SPE registers. We don't care that
3722 much, so we just go ahead and save everything. */
3724 /* Save general registers. */
3725 for (i
= 0; i
< ARRAY_SIZE(env
->gpr
); i
++) {
3726 if (__put_user(env
->gpr
[i
], &frame
->mc_gregs
[i
])) {
3730 if (__put_user(env
->nip
, &frame
->mc_gregs
[TARGET_PT_NIP
])
3731 || __put_user(env
->ctr
, &frame
->mc_gregs
[TARGET_PT_CTR
])
3732 || __put_user(env
->lr
, &frame
->mc_gregs
[TARGET_PT_LNK
])
3733 || __put_user(env
->xer
, &frame
->mc_gregs
[TARGET_PT_XER
]))
3736 for (i
= 0; i
< ARRAY_SIZE(env
->crf
); i
++) {
3737 ccr
|= env
->crf
[i
] << (32 - ((i
+ 1) * 4));
3739 if (__put_user(ccr
, &frame
->mc_gregs
[TARGET_PT_CCR
]))
3742 /* Save Altivec registers if necessary. */
3743 if (env
->insns_flags
& PPC_ALTIVEC
) {
3744 for (i
= 0; i
< ARRAY_SIZE(env
->avr
); i
++) {
3745 ppc_avr_t
*avr
= &env
->avr
[i
];
3746 ppc_avr_t
*vreg
= &frame
->mc_vregs
.altivec
[i
];
3748 if (__put_user(avr
->u64
[0], &vreg
->u64
[0]) ||
3749 __put_user(avr
->u64
[1], &vreg
->u64
[1])) {
3753 /* Set MSR_VR in the saved MSR value to indicate that
3754 frame->mc_vregs contains valid data. */
3756 if (__put_user((uint32_t)env
->spr
[SPR_VRSAVE
],
3757 &frame
->mc_vregs
.altivec
[32].u32
[3]))
3761 /* Save floating point registers. */
3762 if (env
->insns_flags
& PPC_FLOAT
) {
3763 for (i
= 0; i
< ARRAY_SIZE(env
->fpr
); i
++) {
3764 if (__put_user(env
->fpr
[i
], &frame
->mc_fregs
[i
])) {
3768 if (__put_user((uint64_t) env
->fpscr
, &frame
->mc_fregs
[32]))
3772 /* Save SPE registers. The kernel only saves the high half. */
3773 if (env
->insns_flags
& PPC_SPE
) {
3774 #if defined(TARGET_PPC64)
3775 for (i
= 0; i
< ARRAY_SIZE(env
->gpr
); i
++) {
3776 if (__put_user(env
->gpr
[i
] >> 32, &frame
->mc_vregs
.spe
[i
])) {
3781 for (i
= 0; i
< ARRAY_SIZE(env
->gprh
); i
++) {
3782 if (__put_user(env
->gprh
[i
], &frame
->mc_vregs
.spe
[i
])) {
3787 /* Set MSR_SPE in the saved MSR value to indicate that
3788 frame->mc_vregs contains valid data. */
3790 if (__put_user(env
->spe_fscr
, &frame
->mc_vregs
.spe
[32]))
3795 if (__put_user(msr
, &frame
->mc_gregs
[TARGET_PT_MSR
]))
3798 /* Set up the sigreturn trampoline: li r0,sigret; sc. */
3800 if (__put_user(0x38000000UL
| sigret
, &frame
->tramp
[0]) ||
3801 __put_user(0x44000002UL
, &frame
->tramp
[1])) {
3809 static int restore_user_regs(CPUState
*env
,
3810 struct target_mcontext
*frame
, int sig
)
3812 target_ulong save_r2
= 0;
3819 save_r2
= env
->gpr
[2];
3822 /* Restore general registers. */
3823 for (i
= 0; i
< ARRAY_SIZE(env
->gpr
); i
++) {
3824 if (__get_user(env
->gpr
[i
], &frame
->mc_gregs
[i
])) {
3828 if (__get_user(env
->nip
, &frame
->mc_gregs
[TARGET_PT_NIP
])
3829 || __get_user(env
->ctr
, &frame
->mc_gregs
[TARGET_PT_CTR
])
3830 || __get_user(env
->lr
, &frame
->mc_gregs
[TARGET_PT_LNK
])
3831 || __get_user(env
->xer
, &frame
->mc_gregs
[TARGET_PT_XER
]))
3833 if (__get_user(ccr
, &frame
->mc_gregs
[TARGET_PT_CCR
]))
3836 for (i
= 0; i
< ARRAY_SIZE(env
->crf
); i
++) {
3837 env
->crf
[i
] = (ccr
>> (32 - ((i
+ 1) * 4))) & 0xf;
3841 env
->gpr
[2] = save_r2
;
3844 if (__get_user(msr
, &frame
->mc_gregs
[TARGET_PT_MSR
]))
3847 /* If doing signal return, restore the previous little-endian mode. */
3849 env
->msr
= (env
->msr
& ~MSR_LE
) | (msr
& MSR_LE
);
3851 /* Restore Altivec registers if necessary. */
3852 if (env
->insns_flags
& PPC_ALTIVEC
) {
3853 for (i
= 0; i
< ARRAY_SIZE(env
->avr
); i
++) {
3854 ppc_avr_t
*avr
= &env
->avr
[i
];
3855 ppc_avr_t
*vreg
= &frame
->mc_vregs
.altivec
[i
];
3857 if (__get_user(avr
->u64
[0], &vreg
->u64
[0]) ||
3858 __get_user(avr
->u64
[1], &vreg
->u64
[1])) {
3862 /* Set MSR_VEC in the saved MSR value to indicate that
3863 frame->mc_vregs contains valid data. */
3864 if (__get_user(env
->spr
[SPR_VRSAVE
],
3865 (target_ulong
*)(&frame
->mc_vregs
.altivec
[32].u32
[3])))
3869 /* Restore floating point registers. */
3870 if (env
->insns_flags
& PPC_FLOAT
) {
3872 for (i
= 0; i
< ARRAY_SIZE(env
->fpr
); i
++) {
3873 if (__get_user(env
->fpr
[i
], &frame
->mc_fregs
[i
])) {
3877 if (__get_user(fpscr
, &frame
->mc_fregs
[32]))
3879 env
->fpscr
= (uint32_t) fpscr
;
3882 /* Save SPE registers. The kernel only saves the high half. */
3883 if (env
->insns_flags
& PPC_SPE
) {
3884 #if defined(TARGET_PPC64)
3885 for (i
= 0; i
< ARRAY_SIZE(env
->gpr
); i
++) {
3888 if (__get_user(hi
, &frame
->mc_vregs
.spe
[i
])) {
3891 env
->gpr
[i
] = ((uint64_t)hi
<< 32) | ((uint32_t) env
->gpr
[i
]);
3894 for (i
= 0; i
< ARRAY_SIZE(env
->gprh
); i
++) {
3895 if (__get_user(env
->gprh
[i
], &frame
->mc_vregs
.spe
[i
])) {
3900 if (__get_user(env
->spe_fscr
, &frame
->mc_vregs
.spe
[32]))
3907 static void setup_frame(int sig
, struct target_sigaction
*ka
,
3908 target_sigset_t
*set
, CPUState
*env
)
3910 struct target_sigframe
*frame
;
3911 struct target_sigcontext
*sc
;
3912 target_ulong frame_addr
, newsp
;
3916 frame_addr
= get_sigframe(ka
, env
, sizeof(*frame
));
3917 if (!lock_user_struct(VERIFY_WRITE
, frame
, frame_addr
, 1))
3921 signal
= current_exec_domain_sig(sig
);
3923 err
|= __put_user(h2g(ka
->_sa_handler
), &sc
->handler
);
3924 err
|= __put_user(set
->sig
[0], &sc
->oldmask
);
3925 #if defined(TARGET_PPC64)
3926 err
|= __put_user(set
->sig
[0] >> 32, &sc
->_unused
[3]);
3928 err
|= __put_user(set
->sig
[1], &sc
->_unused
[3]);
3930 err
|= __put_user(h2g(&frame
->mctx
), &sc
->regs
);
3931 err
|= __put_user(sig
, &sc
->signal
);
3933 /* Save user regs. */
3934 err
|= save_user_regs(env
, &frame
->mctx
, TARGET_NR_sigreturn
);
3936 /* The kernel checks for the presence of a VDSO here. We don't
3937 emulate a vdso, so use a sigreturn system call. */
3938 env
->lr
= (target_ulong
) h2g(frame
->mctx
.tramp
);
3940 /* Turn off all fp exceptions. */
3943 /* Create a stack frame for the caller of the handler. */
3944 newsp
= frame_addr
- SIGNAL_FRAMESIZE
;
3945 err
|= __put_user(env
->gpr
[1], (target_ulong
*)(uintptr_t) newsp
);
3950 /* Set up registers for signal handler. */
3951 env
->gpr
[1] = newsp
;
3952 env
->gpr
[3] = signal
;
3953 env
->gpr
[4] = (target_ulong
) h2g(sc
);
3954 env
->nip
= (target_ulong
) ka
->_sa_handler
;
3955 /* Signal handlers are entered in big-endian mode. */
3956 env
->msr
&= ~MSR_LE
;
3958 unlock_user_struct(frame
, frame_addr
, 1);
3962 unlock_user_struct(frame
, frame_addr
, 1);
3964 fprintf (logfile
, "segfaulting from setup_frame\n");
3965 force_sig(TARGET_SIGSEGV
);
3968 static void setup_rt_frame(int sig
, struct target_sigaction
*ka
,
3969 target_siginfo_t
*info
,
3970 target_sigset_t
*set
, CPUState
*env
)
3972 struct target_rt_sigframe
*rt_sf
;
3973 struct target_mcontext
*frame
;
3974 target_ulong rt_sf_addr
, newsp
= 0;
3978 rt_sf_addr
= get_sigframe(ka
, env
, sizeof(*rt_sf
));
3979 if (!lock_user_struct(VERIFY_WRITE
, rt_sf
, rt_sf_addr
, 1))
3982 signal
= current_exec_domain_sig(sig
);
3984 err
|= copy_siginfo_to_user(&rt_sf
->info
, info
);
3986 err
|= __put_user(0, &rt_sf
->uc
.tuc_flags
);
3987 err
|= __put_user(0, &rt_sf
->uc
.tuc_link
);
3988 err
|= __put_user((target_ulong
)target_sigaltstack_used
.ss_sp
,
3989 &rt_sf
->uc
.tuc_stack
.ss_sp
);
3990 err
|= __put_user(sas_ss_flags(env
->gpr
[1]),
3991 &rt_sf
->uc
.tuc_stack
.ss_flags
);
3992 err
|= __put_user(target_sigaltstack_used
.ss_size
,
3993 &rt_sf
->uc
.tuc_stack
.ss_size
);
3994 err
|= __put_user(h2g (&rt_sf
->uc
.tuc_mcontext
),
3995 &rt_sf
->uc
.tuc_regs
);
3996 for(i
= 0; i
< TARGET_NSIG_WORDS
; i
++) {
3997 err
|= __put_user(set
->sig
[i
], &rt_sf
->uc
.tuc_sigmask
.sig
[i
]);
4000 frame
= &rt_sf
->uc
.tuc_mcontext
;
4001 err
|= save_user_regs(env
, frame
, TARGET_NR_rt_sigreturn
);
4003 /* The kernel checks for the presence of a VDSO here. We don't
4004 emulate a vdso, so use a sigreturn system call. */
4005 env
->lr
= (target_ulong
) h2g(frame
->tramp
);
4007 /* Turn off all fp exceptions. */
4010 /* Create a stack frame for the caller of the handler. */
4011 newsp
= rt_sf_addr
- (SIGNAL_FRAMESIZE
+ 16);
4012 err
|= __put_user(env
->gpr
[1], (target_ulong
*)(uintptr_t) newsp
);
4017 /* Set up registers for signal handler. */
4018 env
->gpr
[1] = newsp
;
4019 env
->gpr
[3] = (target_ulong
) signal
;
4020 env
->gpr
[4] = (target_ulong
) h2g(&rt_sf
->info
);
4021 env
->gpr
[5] = (target_ulong
) h2g(&rt_sf
->uc
);
4022 env
->gpr
[6] = (target_ulong
) h2g(rt_sf
);
4023 env
->nip
= (target_ulong
) ka
->_sa_handler
;
4024 /* Signal handlers are entered in big-endian mode. */
4025 env
->msr
&= ~MSR_LE
;
4027 unlock_user_struct(rt_sf
, rt_sf_addr
, 1);
4031 unlock_user_struct(rt_sf
, rt_sf_addr
, 1);
4033 fprintf (logfile
, "segfaulting from setup_rt_frame\n");
4034 force_sig(TARGET_SIGSEGV
);
4038 long do_sigreturn(CPUState
*env
)
4040 struct target_sigcontext
*sc
= NULL
;
4041 struct target_mcontext
*sr
= NULL
;
4042 target_ulong sr_addr
, sc_addr
;
4044 target_sigset_t set
;
4046 sc_addr
= env
->gpr
[1] + SIGNAL_FRAMESIZE
;
4047 if (!lock_user_struct(VERIFY_READ
, sc
, sc_addr
, 1))
4050 #if defined(TARGET_PPC64)
4051 set
.sig
[0] = sc
->oldmask
+ ((long)(sc
->_unused
[3]) << 32);
4053 if(__get_user(set
.sig
[0], &sc
->oldmask
) ||
4054 __get_user(set
.sig
[1], &sc
->_unused
[3]))
4057 target_to_host_sigset_internal(&blocked
, &set
);
4058 sigprocmask(SIG_SETMASK
, &blocked
, NULL
);
4060 if (__get_user(sr_addr
, &sc
->regs
))
4062 if (!lock_user_struct(VERIFY_READ
, sr
, sr_addr
, 1))
4064 if (restore_user_regs(env
, sr
, 1))
4067 unlock_user_struct(sr
, sr_addr
, 1);
4068 unlock_user_struct(sc
, sc_addr
, 1);
4069 return -TARGET_QEMU_ESIGRETURN
;
4072 unlock_user_struct(sr
, sr_addr
, 1);
4073 unlock_user_struct(sc
, sc_addr
, 1);
4075 fprintf (logfile
, "segfaulting from do_sigreturn\n");
4076 force_sig(TARGET_SIGSEGV
);
4080 /* See arch/powerpc/kernel/signal_32.c. */
4081 static int do_setcontext(struct target_ucontext
*ucp
, CPUState
*env
, int sig
)
4083 struct target_mcontext
*mcp
;
4084 target_ulong mcp_addr
;
4086 target_sigset_t set
;
4088 if (copy_from_user(&set
, h2g(ucp
) + offsetof(struct target_ucontext
, tuc_sigmask
),
4092 #if defined(TARGET_PPC64)
4093 fprintf (stderr
, "do_setcontext: not implemented\n");
4096 if (__get_user(mcp_addr
, &ucp
->tuc_regs
))
4099 if (!lock_user_struct(VERIFY_READ
, mcp
, mcp_addr
, 1))
4102 target_to_host_sigset_internal(&blocked
, &set
);
4103 sigprocmask(SIG_SETMASK
, &blocked
, NULL
);
4104 if (restore_user_regs(env
, mcp
, sig
))
4107 unlock_user_struct(mcp
, mcp_addr
, 1);
4111 unlock_user_struct(mcp
, mcp_addr
, 1);
4116 long do_rt_sigreturn(CPUState
*env
)
4118 struct target_rt_sigframe
*rt_sf
= NULL
;
4119 target_ulong rt_sf_addr
;
4121 rt_sf_addr
= env
->gpr
[1] + SIGNAL_FRAMESIZE
+ 16;
4122 if (!lock_user_struct(VERIFY_READ
, rt_sf
, rt_sf_addr
, 1))
4125 if (do_setcontext(&rt_sf
->uc
, env
, 1))
4128 do_sigaltstack(rt_sf_addr
4129 + offsetof(struct target_rt_sigframe
, uc
.tuc_stack
),
4132 unlock_user_struct(rt_sf
, rt_sf_addr
, 1);
4133 return -TARGET_QEMU_ESIGRETURN
;
4136 unlock_user_struct(rt_sf
, rt_sf_addr
, 1);
4138 fprintf (logfile
, "segfaulting from do_rt_sigreturn\n");
4139 force_sig(TARGET_SIGSEGV
);
4143 #elif defined(TARGET_M68K)
4145 struct target_sigcontext
{
4152 unsigned short sc_sr
;
4156 struct target_sigframe
4163 abi_ulong extramask
[TARGET_NSIG_WORDS
-1];
4164 struct target_sigcontext sc
;
4167 typedef int target_greg_t
;
4168 #define TARGET_NGREG 18
4169 typedef target_greg_t target_gregset_t
[TARGET_NGREG
];
4171 typedef struct target_fpregset
{
4174 } target_fpregset_t
;
4176 struct target_mcontext
{
4178 target_gregset_t gregs
;
4179 target_fpregset_t fpregs
;
4182 #define TARGET_MCONTEXT_VERSION 2
4184 struct target_ucontext
{
4185 abi_ulong tuc_flags
;
4187 target_stack_t tuc_stack
;
4188 struct target_mcontext tuc_mcontext
;
4189 abi_long tuc_filler
[80];
4190 target_sigset_t tuc_sigmask
;
4193 struct target_rt_sigframe
4200 struct target_siginfo info
;
4201 struct target_ucontext uc
;
4205 setup_sigcontext(struct target_sigcontext
*sc
, CPUState
*env
, abi_ulong mask
)
4209 err
|= __put_user(mask
, &sc
->sc_mask
);
4210 err
|= __put_user(env
->aregs
[7], &sc
->sc_usp
);
4211 err
|= __put_user(env
->dregs
[0], &sc
->sc_d0
);
4212 err
|= __put_user(env
->dregs
[1], &sc
->sc_d1
);
4213 err
|= __put_user(env
->aregs
[0], &sc
->sc_a0
);
4214 err
|= __put_user(env
->aregs
[1], &sc
->sc_a1
);
4215 err
|= __put_user(env
->sr
, &sc
->sc_sr
);
4216 err
|= __put_user(env
->pc
, &sc
->sc_pc
);
4222 restore_sigcontext(CPUState
*env
, struct target_sigcontext
*sc
, int *pd0
)
4227 err
|= __get_user(env
->aregs
[7], &sc
->sc_usp
);
4228 err
|= __get_user(env
->dregs
[1], &sc
->sc_d1
);
4229 err
|= __get_user(env
->aregs
[0], &sc
->sc_a0
);
4230 err
|= __get_user(env
->aregs
[1], &sc
->sc_a1
);
4231 err
|= __get_user(env
->pc
, &sc
->sc_pc
);
4232 err
|= __get_user(temp
, &sc
->sc_sr
);
4233 env
->sr
= (env
->sr
& 0xff00) | (temp
& 0xff);
4235 *pd0
= tswapl(sc
->sc_d0
);
4241 * Determine which stack to use..
4243 static inline abi_ulong
4244 get_sigframe(struct target_sigaction
*ka
, CPUState
*regs
, size_t frame_size
)
4248 sp
= regs
->aregs
[7];
4250 /* This is the X/Open sanctioned signal stack switching. */
4251 if ((ka
->sa_flags
& TARGET_SA_ONSTACK
) && (sas_ss_flags (sp
) == 0)) {
4252 sp
= target_sigaltstack_used
.ss_sp
+ target_sigaltstack_used
.ss_size
;
4255 return ((sp
- frame_size
) & -8UL);
4258 static void setup_frame(int sig
, struct target_sigaction
*ka
,
4259 target_sigset_t
*set
, CPUState
*env
)
4261 struct target_sigframe
*frame
;
4262 abi_ulong frame_addr
;
4263 abi_ulong retcode_addr
;
4268 frame_addr
= get_sigframe(ka
, env
, sizeof *frame
);
4269 if (!lock_user_struct(VERIFY_WRITE
, frame
, frame_addr
, 0))
4272 err
|= __put_user(sig
, &frame
->sig
);
4274 sc_addr
= frame_addr
+ offsetof(struct target_sigframe
, sc
);
4275 err
|= __put_user(sc_addr
, &frame
->psc
);
4277 err
|= setup_sigcontext(&frame
->sc
, env
, set
->sig
[0]);
4281 for(i
= 1; i
< TARGET_NSIG_WORDS
; i
++) {
4282 if (__put_user(set
->sig
[i
], &frame
->extramask
[i
- 1]))
4286 /* Set up to return from userspace. */
4288 retcode_addr
= frame_addr
+ offsetof(struct target_sigframe
, retcode
);
4289 err
|= __put_user(retcode_addr
, &frame
->pretcode
);
4291 /* moveq #,d0; trap #0 */
4293 err
|= __put_user(0x70004e40 + (TARGET_NR_sigreturn
<< 16),
4294 (long *)(frame
->retcode
));
4299 /* Set up to return from userspace */
4301 env
->aregs
[7] = frame_addr
;
4302 env
->pc
= ka
->_sa_handler
;
4304 unlock_user_struct(frame
, frame_addr
, 1);
4308 unlock_user_struct(frame
, frame_addr
, 1);
4309 force_sig(TARGET_SIGSEGV
);
4312 static inline int target_rt_setup_ucontext(struct target_ucontext
*uc
,
4315 target_greg_t
*gregs
= uc
->tuc_mcontext
.gregs
;
4318 err
= __put_user(TARGET_MCONTEXT_VERSION
, &uc
->tuc_mcontext
.version
);
4319 err
|= __put_user(env
->dregs
[0], &gregs
[0]);
4320 err
|= __put_user(env
->dregs
[1], &gregs
[1]);
4321 err
|= __put_user(env
->dregs
[2], &gregs
[2]);
4322 err
|= __put_user(env
->dregs
[3], &gregs
[3]);
4323 err
|= __put_user(env
->dregs
[4], &gregs
[4]);
4324 err
|= __put_user(env
->dregs
[5], &gregs
[5]);
4325 err
|= __put_user(env
->dregs
[6], &gregs
[6]);
4326 err
|= __put_user(env
->dregs
[7], &gregs
[7]);
4327 err
|= __put_user(env
->aregs
[0], &gregs
[8]);
4328 err
|= __put_user(env
->aregs
[1], &gregs
[9]);
4329 err
|= __put_user(env
->aregs
[2], &gregs
[10]);
4330 err
|= __put_user(env
->aregs
[3], &gregs
[11]);
4331 err
|= __put_user(env
->aregs
[4], &gregs
[12]);
4332 err
|= __put_user(env
->aregs
[5], &gregs
[13]);
4333 err
|= __put_user(env
->aregs
[6], &gregs
[14]);
4334 err
|= __put_user(env
->aregs
[7], &gregs
[15]);
4335 err
|= __put_user(env
->pc
, &gregs
[16]);
4336 err
|= __put_user(env
->sr
, &gregs
[17]);
4341 static inline int target_rt_restore_ucontext(CPUState
*env
,
4342 struct target_ucontext
*uc
,
4347 target_greg_t
*gregs
= uc
->tuc_mcontext
.gregs
;
4349 err
= __get_user(temp
, &uc
->tuc_mcontext
.version
);
4350 if (temp
!= TARGET_MCONTEXT_VERSION
)
4353 /* restore passed registers */
4354 err
|= __get_user(env
->dregs
[0], &gregs
[0]);
4355 err
|= __get_user(env
->dregs
[1], &gregs
[1]);
4356 err
|= __get_user(env
->dregs
[2], &gregs
[2]);
4357 err
|= __get_user(env
->dregs
[3], &gregs
[3]);
4358 err
|= __get_user(env
->dregs
[4], &gregs
[4]);
4359 err
|= __get_user(env
->dregs
[5], &gregs
[5]);
4360 err
|= __get_user(env
->dregs
[6], &gregs
[6]);
4361 err
|= __get_user(env
->dregs
[7], &gregs
[7]);
4362 err
|= __get_user(env
->aregs
[0], &gregs
[8]);
4363 err
|= __get_user(env
->aregs
[1], &gregs
[9]);
4364 err
|= __get_user(env
->aregs
[2], &gregs
[10]);
4365 err
|= __get_user(env
->aregs
[3], &gregs
[11]);
4366 err
|= __get_user(env
->aregs
[4], &gregs
[12]);
4367 err
|= __get_user(env
->aregs
[5], &gregs
[13]);
4368 err
|= __get_user(env
->aregs
[6], &gregs
[14]);
4369 err
|= __get_user(env
->aregs
[7], &gregs
[15]);
4370 err
|= __get_user(env
->pc
, &gregs
[16]);
4371 err
|= __get_user(temp
, &gregs
[17]);
4372 env
->sr
= (env
->sr
& 0xff00) | (temp
& 0xff);
4374 *pd0
= env
->dregs
[0];
4381 static void setup_rt_frame(int sig
, struct target_sigaction
*ka
,
4382 target_siginfo_t
*info
,
4383 target_sigset_t
*set
, CPUState
*env
)
4385 struct target_rt_sigframe
*frame
;
4386 abi_ulong frame_addr
;
4387 abi_ulong retcode_addr
;
4388 abi_ulong info_addr
;
4393 frame_addr
= get_sigframe(ka
, env
, sizeof *frame
);
4394 if (!lock_user_struct(VERIFY_WRITE
, frame
, frame_addr
, 0))
4397 err
|= __put_user(sig
, &frame
->sig
);
4399 info_addr
= frame_addr
+ offsetof(struct target_rt_sigframe
, info
);
4400 err
|= __put_user(info_addr
, &frame
->pinfo
);
4402 uc_addr
= frame_addr
+ offsetof(struct target_rt_sigframe
, uc
);
4403 err
|= __put_user(uc_addr
, &frame
->puc
);
4405 err
|= copy_siginfo_to_user(&frame
->info
, info
);
4407 /* Create the ucontext */
4409 err
|= __put_user(0, &frame
->uc
.tuc_flags
);
4410 err
|= __put_user(0, &frame
->uc
.tuc_link
);
4411 err
|= __put_user(target_sigaltstack_used
.ss_sp
,
4412 &frame
->uc
.tuc_stack
.ss_sp
);
4413 err
|= __put_user(sas_ss_flags(env
->aregs
[7]),
4414 &frame
->uc
.tuc_stack
.ss_flags
);
4415 err
|= __put_user(target_sigaltstack_used
.ss_size
,
4416 &frame
->uc
.tuc_stack
.ss_size
);
4417 err
|= target_rt_setup_ucontext(&frame
->uc
, env
);
4422 for(i
= 0; i
< TARGET_NSIG_WORDS
; i
++) {
4423 if (__put_user(set
->sig
[i
], &frame
->uc
.tuc_sigmask
.sig
[i
]))
4427 /* Set up to return from userspace. */
4429 retcode_addr
= frame_addr
+ offsetof(struct target_sigframe
, retcode
);
4430 err
|= __put_user(retcode_addr
, &frame
->pretcode
);
4432 /* moveq #,d0; notb d0; trap #0 */
4434 err
|= __put_user(0x70004600 + ((TARGET_NR_rt_sigreturn
^ 0xff) << 16),
4435 (long *)(frame
->retcode
+ 0));
4436 err
|= __put_user(0x4e40, (short *)(frame
->retcode
+ 4));
4441 /* Set up to return from userspace */
4443 env
->aregs
[7] = frame_addr
;
4444 env
->pc
= ka
->_sa_handler
;
4446 unlock_user_struct(frame
, frame_addr
, 1);
4450 unlock_user_struct(frame
, frame_addr
, 1);
4451 force_sig(TARGET_SIGSEGV
);
4454 long do_sigreturn(CPUState
*env
)
4456 struct target_sigframe
*frame
;
4457 abi_ulong frame_addr
= env
->aregs
[7] - 4;
4458 target_sigset_t target_set
;
4462 if (!lock_user_struct(VERIFY_READ
, frame
, frame_addr
, 1))
4465 /* set blocked signals */
4467 if (__get_user(target_set
.sig
[0], &frame
->sc
.sc_mask
))
4470 for(i
= 1; i
< TARGET_NSIG_WORDS
; i
++) {
4471 if (__get_user(target_set
.sig
[i
], &frame
->extramask
[i
- 1]))
4475 target_to_host_sigset_internal(&set
, &target_set
);
4476 sigprocmask(SIG_SETMASK
, &set
, NULL
);
4478 /* restore registers */
4480 if (restore_sigcontext(env
, &frame
->sc
, &d0
))
4483 unlock_user_struct(frame
, frame_addr
, 0);
4487 unlock_user_struct(frame
, frame_addr
, 0);
4488 force_sig(TARGET_SIGSEGV
);
4492 long do_rt_sigreturn(CPUState
*env
)
4494 struct target_rt_sigframe
*frame
;
4495 abi_ulong frame_addr
= env
->aregs
[7] - 4;
4496 target_sigset_t target_set
;
4500 if (!lock_user_struct(VERIFY_READ
, frame
, frame_addr
, 1))
4503 target_to_host_sigset_internal(&set
, &target_set
);
4504 sigprocmask(SIG_SETMASK
, &set
, NULL
);
4506 /* restore registers */
4508 if (target_rt_restore_ucontext(env
, &frame
->uc
, &d0
))
4511 if (do_sigaltstack(frame_addr
+
4512 offsetof(struct target_rt_sigframe
, uc
.tuc_stack
),
4513 0, get_sp_from_cpustate(env
)) == -EFAULT
)
4516 unlock_user_struct(frame
, frame_addr
, 0);
4520 unlock_user_struct(frame
, frame_addr
, 0);
4521 force_sig(TARGET_SIGSEGV
);
4525 #elif defined(TARGET_ALPHA)
4527 struct target_sigcontext
{
4528 abi_long sc_onstack
;
4532 abi_long sc_regs
[32];
4533 abi_long sc_ownedfp
;
4534 abi_long sc_fpregs
[32];
4536 abi_ulong sc_fp_control
;
4537 abi_ulong sc_reserved1
;
4538 abi_ulong sc_reserved2
;
4541 abi_ulong sc_traparg_a0
;
4542 abi_ulong sc_traparg_a1
;
4543 abi_ulong sc_traparg_a2
;
4544 abi_ulong sc_fp_trap_pc
;
4545 abi_ulong sc_fp_trigger_sum
;
4546 abi_ulong sc_fp_trigger_inst
;
4549 struct target_ucontext
{
4550 abi_ulong tuc_flags
;
4552 abi_ulong tuc_osf_sigmask
;
4553 target_stack_t tuc_stack
;
4554 struct target_sigcontext tuc_mcontext
;
4555 target_sigset_t tuc_sigmask
;
4558 struct target_sigframe
{
4559 struct target_sigcontext sc
;
4560 unsigned int retcode
[3];
4563 struct target_rt_sigframe
{
4564 target_siginfo_t info
;
4565 struct target_ucontext uc
;
4566 unsigned int retcode
[3];
4569 #define INSN_MOV_R30_R16 0x47fe0410
4570 #define INSN_LDI_R0 0x201f0000
4571 #define INSN_CALLSYS 0x00000083
4573 static int setup_sigcontext(struct target_sigcontext
*sc
, CPUState
*env
,
4574 abi_ulong frame_addr
, target_sigset_t
*set
)
4578 err
|= __put_user(on_sig_stack(frame_addr
), &sc
->sc_onstack
);
4579 err
|= __put_user(set
->sig
[0], &sc
->sc_mask
);
4580 err
|= __put_user(env
->pc
, &sc
->sc_pc
);
4581 err
|= __put_user(8, &sc
->sc_ps
);
4583 for (i
= 0; i
< 31; ++i
) {
4584 err
|= __put_user(env
->ir
[i
], &sc
->sc_regs
[i
]);
4586 err
|= __put_user(0, &sc
->sc_regs
[31]);
4588 for (i
= 0; i
< 31; ++i
) {
4589 err
|= __put_user(env
->fir
[i
], &sc
->sc_fpregs
[i
]);
4591 err
|= __put_user(0, &sc
->sc_fpregs
[31]);
4592 err
|= __put_user(cpu_alpha_load_fpcr(env
), &sc
->sc_fpcr
);
4594 err
|= __put_user(0, &sc
->sc_traparg_a0
); /* FIXME */
4595 err
|= __put_user(0, &sc
->sc_traparg_a1
); /* FIXME */
4596 err
|= __put_user(0, &sc
->sc_traparg_a2
); /* FIXME */
4601 static int restore_sigcontext(CPUState
*env
, struct target_sigcontext
*sc
)
4606 err
|= __get_user(env
->pc
, &sc
->sc_pc
);
4608 for (i
= 0; i
< 31; ++i
) {
4609 err
|= __get_user(env
->ir
[i
], &sc
->sc_regs
[i
]);
4611 for (i
= 0; i
< 31; ++i
) {
4612 err
|= __get_user(env
->fir
[i
], &sc
->sc_fpregs
[i
]);
4615 err
|= __get_user(fpcr
, &sc
->sc_fpcr
);
4616 cpu_alpha_store_fpcr(env
, fpcr
);
4621 static inline abi_ulong
get_sigframe(struct target_sigaction
*sa
,
4622 CPUState
*env
, unsigned long framesize
)
4624 abi_ulong sp
= env
->ir
[IR_SP
];
4626 /* This is the X/Open sanctioned signal stack switching. */
4627 if ((sa
->sa_flags
& TARGET_SA_ONSTACK
) != 0 && !sas_ss_flags(sp
)) {
4628 sp
= target_sigaltstack_used
.ss_sp
+ target_sigaltstack_used
.ss_size
;
4630 return (sp
- framesize
) & -32;
4633 static void setup_frame(int sig
, struct target_sigaction
*ka
,
4634 target_sigset_t
*set
, CPUState
*env
)
4636 abi_ulong frame_addr
, r26
;
4637 struct target_sigframe
*frame
;
4640 frame_addr
= get_sigframe(ka
, env
, sizeof(*frame
));
4641 if (!lock_user_struct(VERIFY_WRITE
, frame
, frame_addr
, 0)) {
4645 err
|= setup_sigcontext(&frame
->sc
, env
, frame_addr
, set
);
4647 if (ka
->sa_restorer
) {
4648 r26
= ka
->sa_restorer
;
4650 err
|= __put_user(INSN_MOV_R30_R16
, &frame
->retcode
[0]);
4651 err
|= __put_user(INSN_LDI_R0
+ TARGET_NR_sigreturn
,
4652 &frame
->retcode
[1]);
4653 err
|= __put_user(INSN_CALLSYS
, &frame
->retcode
[2]);
4658 unlock_user_struct(frame
, frame_addr
, 1);
4662 if (sig
== TARGET_SIGSEGV
) {
4663 ka
->_sa_handler
= TARGET_SIG_DFL
;
4665 force_sig(TARGET_SIGSEGV
);
4668 env
->ir
[IR_RA
] = r26
;
4669 env
->ir
[IR_PV
] = env
->pc
= ka
->_sa_handler
;
4670 env
->ir
[IR_A0
] = sig
;
4672 env
->ir
[IR_A2
] = frame_addr
+ offsetof(struct target_sigframe
, sc
);
4673 env
->ir
[IR_SP
] = frame_addr
;
4676 static void setup_rt_frame(int sig
, struct target_sigaction
*ka
,
4677 target_siginfo_t
*info
,
4678 target_sigset_t
*set
, CPUState
*env
)
4680 abi_ulong frame_addr
, r26
;
4681 struct target_rt_sigframe
*frame
;
4684 frame_addr
= get_sigframe(ka
, env
, sizeof(*frame
));
4685 if (!lock_user_struct(VERIFY_WRITE
, frame
, frame_addr
, 0)) {
4689 err
|= copy_siginfo_to_user(&frame
->info
, info
);
4691 err
|= __put_user(0, &frame
->uc
.tuc_flags
);
4692 err
|= __put_user(0, &frame
->uc
.tuc_link
);
4693 err
|= __put_user(set
->sig
[0], &frame
->uc
.tuc_osf_sigmask
);
4694 err
|= __put_user(target_sigaltstack_used
.ss_sp
,
4695 &frame
->uc
.tuc_stack
.ss_sp
);
4696 err
|= __put_user(sas_ss_flags(env
->ir
[IR_SP
]),
4697 &frame
->uc
.tuc_stack
.ss_flags
);
4698 err
|= __put_user(target_sigaltstack_used
.ss_size
,
4699 &frame
->uc
.tuc_stack
.ss_size
);
4700 err
|= setup_sigcontext(&frame
->uc
.tuc_mcontext
, env
, frame_addr
, set
);
4701 for (i
= 0; i
< TARGET_NSIG_WORDS
; ++i
) {
4702 err
|= __put_user(set
->sig
[i
], &frame
->uc
.tuc_sigmask
.sig
[i
]);
4705 if (ka
->sa_restorer
) {
4706 r26
= ka
->sa_restorer
;
4708 err
|= __put_user(INSN_MOV_R30_R16
, &frame
->retcode
[0]);
4709 err
|= __put_user(INSN_LDI_R0
+ TARGET_NR_rt_sigreturn
,
4710 &frame
->retcode
[1]);
4711 err
|= __put_user(INSN_CALLSYS
, &frame
->retcode
[2]);
4718 if (sig
== TARGET_SIGSEGV
) {
4719 ka
->_sa_handler
= TARGET_SIG_DFL
;
4721 force_sig(TARGET_SIGSEGV
);
4724 env
->ir
[IR_RA
] = r26
;
4725 env
->ir
[IR_PV
] = env
->pc
= ka
->_sa_handler
;
4726 env
->ir
[IR_A0
] = sig
;
4727 env
->ir
[IR_A1
] = frame_addr
+ offsetof(struct target_rt_sigframe
, info
);
4728 env
->ir
[IR_A2
] = frame_addr
+ offsetof(struct target_rt_sigframe
, uc
);
4729 env
->ir
[IR_SP
] = frame_addr
;
4732 long do_sigreturn(CPUState
*env
)
4734 struct target_sigcontext
*sc
;
4735 abi_ulong sc_addr
= env
->ir
[IR_A0
];
4736 target_sigset_t target_set
;
4739 if (!lock_user_struct(VERIFY_READ
, sc
, sc_addr
, 1)) {
4743 target_sigemptyset(&target_set
);
4744 if (__get_user(target_set
.sig
[0], &sc
->sc_mask
)) {
4748 target_to_host_sigset_internal(&set
, &target_set
);
4749 sigprocmask(SIG_SETMASK
, &set
, NULL
);
4751 if (restore_sigcontext(env
, sc
)) {
4754 unlock_user_struct(sc
, sc_addr
, 0);
4755 return env
->ir
[IR_V0
];
4758 unlock_user_struct(sc
, sc_addr
, 0);
4759 force_sig(TARGET_SIGSEGV
);
4762 long do_rt_sigreturn(CPUState
*env
)
4764 abi_ulong frame_addr
= env
->ir
[IR_A0
];
4765 struct target_rt_sigframe
*frame
;
4768 if (!lock_user_struct(VERIFY_READ
, frame
, frame_addr
, 1)) {
4771 target_to_host_sigset(&set
, &frame
->uc
.tuc_sigmask
);
4772 sigprocmask(SIG_SETMASK
, &set
, NULL
);
4774 if (restore_sigcontext(env
, &frame
->uc
.tuc_mcontext
)) {
4777 if (do_sigaltstack(frame_addr
+ offsetof(struct target_rt_sigframe
,
4779 0, env
->ir
[IR_SP
]) == -EFAULT
) {
4783 unlock_user_struct(frame
, frame_addr
, 0);
4784 return env
->ir
[IR_V0
];
4788 unlock_user_struct(frame
, frame_addr
, 0);
4789 force_sig(TARGET_SIGSEGV
);
4794 static void setup_frame(int sig
, struct target_sigaction
*ka
,
4795 target_sigset_t
*set
, CPUState
*env
)
4797 fprintf(stderr
, "setup_frame: not implemented\n");
4800 static void setup_rt_frame(int sig
, struct target_sigaction
*ka
,
4801 target_siginfo_t
*info
,
4802 target_sigset_t
*set
, CPUState
*env
)
4804 fprintf(stderr
, "setup_rt_frame: not implemented\n");
4807 long do_sigreturn(CPUState
*env
)
4809 fprintf(stderr
, "do_sigreturn: not implemented\n");
4810 return -TARGET_ENOSYS
;
4813 long do_rt_sigreturn(CPUState
*env
)
4815 fprintf(stderr
, "do_rt_sigreturn: not implemented\n");
4816 return -TARGET_ENOSYS
;
4821 void process_pending_signals(CPUState
*cpu_env
)
4825 sigset_t set
, old_set
;
4826 target_sigset_t target_old_set
;
4827 struct emulated_sigtable
*k
;
4828 struct target_sigaction
*sa
;
4830 TaskState
*ts
= cpu_env
->opaque
;
4832 if (!ts
->signal_pending
)
4835 /* FIXME: This is not threadsafe. */
4837 for(sig
= 1; sig
<= TARGET_NSIG
; sig
++) {
4842 /* if no signal is pending, just return */
4843 ts
->signal_pending
= 0;
4848 fprintf(stderr
, "qemu: process signal %d\n", sig
);
4850 /* dequeue signal */
4856 sig
= gdb_handlesig (cpu_env
, sig
);
4859 handler
= TARGET_SIG_IGN
;
4861 sa
= &sigact_table
[sig
- 1];
4862 handler
= sa
->_sa_handler
;
4865 if (handler
== TARGET_SIG_DFL
) {
4866 /* default handler : ignore some signal. The other are job control or fatal */
4867 if (sig
== TARGET_SIGTSTP
|| sig
== TARGET_SIGTTIN
|| sig
== TARGET_SIGTTOU
) {
4868 kill(getpid(),SIGSTOP
);
4869 } else if (sig
!= TARGET_SIGCHLD
&&
4870 sig
!= TARGET_SIGURG
&&
4871 sig
!= TARGET_SIGWINCH
&&
4872 sig
!= TARGET_SIGCONT
) {
4875 } else if (handler
== TARGET_SIG_IGN
) {
4877 } else if (handler
== TARGET_SIG_ERR
) {
4880 /* compute the blocked signals during the handler execution */
4881 target_to_host_sigset(&set
, &sa
->sa_mask
);
4882 /* SA_NODEFER indicates that the current signal should not be
4883 blocked during the handler */
4884 if (!(sa
->sa_flags
& TARGET_SA_NODEFER
))
4885 sigaddset(&set
, target_to_host_signal(sig
));
4887 /* block signals in the handler using Linux */
4888 sigprocmask(SIG_BLOCK
, &set
, &old_set
);
4889 /* save the previous blocked signal state to restore it at the
4890 end of the signal execution (see do_sigreturn) */
4891 host_to_target_sigset_internal(&target_old_set
, &old_set
);
4893 /* if the CPU is in VM86 mode, we restore the 32 bit values */
4894 #if defined(TARGET_I386) && !defined(TARGET_X86_64)
4896 CPUX86State
*env
= cpu_env
;
4897 if (env
->eflags
& VM_MASK
)
4898 save_v86_state(env
);
4901 /* prepare the stack frame of the virtual CPU */
4902 if (sa
->sa_flags
& TARGET_SA_SIGINFO
)
4903 setup_rt_frame(sig
, sa
, &q
->info
, &target_old_set
, cpu_env
);
4905 setup_frame(sig
, sa
, &target_old_set
, cpu_env
);
4906 if (sa
->sa_flags
& TARGET_SA_RESETHAND
)
4907 sa
->_sa_handler
= TARGET_SIG_DFL
;
4910 free_sigqueue(cpu_env
, q
);