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/>.
26 #include <sys/ucontext.h>
27 #include <sys/resource.h>
30 #include "qemu-common.h"
31 #include "target_signal.h"
33 //#define DEBUG_SIGNAL
35 static struct target_sigaltstack target_sigaltstack_used
= {
38 .ss_flags
= TARGET_SS_DISABLE
,
41 static struct target_sigaction sigact_table
[TARGET_NSIG
];
43 static void host_signal_handler(int host_signum
, siginfo_t
*info
,
46 static uint8_t host_to_target_signal_table
[_NSIG
] = {
47 [SIGHUP
] = TARGET_SIGHUP
,
48 [SIGINT
] = TARGET_SIGINT
,
49 [SIGQUIT
] = TARGET_SIGQUIT
,
50 [SIGILL
] = TARGET_SIGILL
,
51 [SIGTRAP
] = TARGET_SIGTRAP
,
52 [SIGABRT
] = TARGET_SIGABRT
,
53 /* [SIGIOT] = TARGET_SIGIOT,*/
54 [SIGBUS
] = TARGET_SIGBUS
,
55 [SIGFPE
] = TARGET_SIGFPE
,
56 [SIGKILL
] = TARGET_SIGKILL
,
57 [SIGUSR1
] = TARGET_SIGUSR1
,
58 [SIGSEGV
] = TARGET_SIGSEGV
,
59 [SIGUSR2
] = TARGET_SIGUSR2
,
60 [SIGPIPE
] = TARGET_SIGPIPE
,
61 [SIGALRM
] = TARGET_SIGALRM
,
62 [SIGTERM
] = TARGET_SIGTERM
,
64 [SIGSTKFLT
] = TARGET_SIGSTKFLT
,
66 [SIGCHLD
] = TARGET_SIGCHLD
,
67 [SIGCONT
] = TARGET_SIGCONT
,
68 [SIGSTOP
] = TARGET_SIGSTOP
,
69 [SIGTSTP
] = TARGET_SIGTSTP
,
70 [SIGTTIN
] = TARGET_SIGTTIN
,
71 [SIGTTOU
] = TARGET_SIGTTOU
,
72 [SIGURG
] = TARGET_SIGURG
,
73 [SIGXCPU
] = TARGET_SIGXCPU
,
74 [SIGXFSZ
] = TARGET_SIGXFSZ
,
75 [SIGVTALRM
] = TARGET_SIGVTALRM
,
76 [SIGPROF
] = TARGET_SIGPROF
,
77 [SIGWINCH
] = TARGET_SIGWINCH
,
78 [SIGIO
] = TARGET_SIGIO
,
79 [SIGPWR
] = TARGET_SIGPWR
,
80 [SIGSYS
] = TARGET_SIGSYS
,
81 /* next signals stay the same */
82 /* Nasty hack: Reverse SIGRTMIN and SIGRTMAX to avoid overlap with
83 host libpthread signals. This assumes no one actually uses SIGRTMAX :-/
84 To fix this properly we need to do manual signal delivery multiplexed
85 over a single host signal. */
86 [__SIGRTMIN
] = __SIGRTMAX
,
87 [__SIGRTMAX
] = __SIGRTMIN
,
89 static uint8_t target_to_host_signal_table
[_NSIG
];
91 static inline int on_sig_stack(unsigned long sp
)
93 return (sp
- target_sigaltstack_used
.ss_sp
94 < target_sigaltstack_used
.ss_size
);
97 static inline int sas_ss_flags(unsigned long sp
)
99 return (target_sigaltstack_used
.ss_size
== 0 ? SS_DISABLE
100 : on_sig_stack(sp
) ? SS_ONSTACK
: 0);
103 int host_to_target_signal(int sig
)
105 if (sig
< 0 || sig
>= _NSIG
)
107 return host_to_target_signal_table
[sig
];
110 int target_to_host_signal(int sig
)
112 if (sig
< 0 || sig
>= _NSIG
)
114 return target_to_host_signal_table
[sig
];
117 static inline void target_sigemptyset(target_sigset_t
*set
)
119 memset(set
, 0, sizeof(*set
));
122 static inline void target_sigaddset(target_sigset_t
*set
, int signum
)
125 abi_ulong mask
= (abi_ulong
)1 << (signum
% TARGET_NSIG_BPW
);
126 set
->sig
[signum
/ TARGET_NSIG_BPW
] |= mask
;
129 static inline int target_sigismember(const target_sigset_t
*set
, int signum
)
132 abi_ulong mask
= (abi_ulong
)1 << (signum
% TARGET_NSIG_BPW
);
133 return ((set
->sig
[signum
/ TARGET_NSIG_BPW
] & mask
) != 0);
136 static void host_to_target_sigset_internal(target_sigset_t
*d
,
140 target_sigemptyset(d
);
141 for (i
= 1; i
<= TARGET_NSIG
; i
++) {
142 if (sigismember(s
, i
)) {
143 target_sigaddset(d
, host_to_target_signal(i
));
148 void host_to_target_sigset(target_sigset_t
*d
, const sigset_t
*s
)
153 host_to_target_sigset_internal(&d1
, s
);
154 for(i
= 0;i
< TARGET_NSIG_WORDS
; i
++)
155 d
->sig
[i
] = tswapal(d1
.sig
[i
]);
158 static void target_to_host_sigset_internal(sigset_t
*d
,
159 const target_sigset_t
*s
)
163 for (i
= 1; i
<= TARGET_NSIG
; i
++) {
164 if (target_sigismember(s
, i
)) {
165 sigaddset(d
, target_to_host_signal(i
));
170 void target_to_host_sigset(sigset_t
*d
, const target_sigset_t
*s
)
175 for(i
= 0;i
< TARGET_NSIG_WORDS
; i
++)
176 s1
.sig
[i
] = tswapal(s
->sig
[i
]);
177 target_to_host_sigset_internal(d
, &s1
);
180 void host_to_target_old_sigset(abi_ulong
*old_sigset
,
181 const sigset_t
*sigset
)
184 host_to_target_sigset(&d
, sigset
);
185 *old_sigset
= d
.sig
[0];
188 void target_to_host_old_sigset(sigset_t
*sigset
,
189 const abi_ulong
*old_sigset
)
194 d
.sig
[0] = *old_sigset
;
195 for(i
= 1;i
< TARGET_NSIG_WORDS
; i
++)
197 target_to_host_sigset(sigset
, &d
);
200 /* siginfo conversion */
202 static inline void host_to_target_siginfo_noswap(target_siginfo_t
*tinfo
,
203 const siginfo_t
*info
)
205 int sig
= host_to_target_signal(info
->si_signo
);
206 tinfo
->si_signo
= sig
;
208 tinfo
->si_code
= info
->si_code
;
210 if (sig
== TARGET_SIGILL
|| sig
== TARGET_SIGFPE
|| sig
== TARGET_SIGSEGV
211 || sig
== TARGET_SIGBUS
|| sig
== TARGET_SIGTRAP
) {
212 /* Should never come here, but who knows. The information for
213 the target is irrelevant. */
214 tinfo
->_sifields
._sigfault
._addr
= 0;
215 } else if (sig
== TARGET_SIGIO
) {
216 tinfo
->_sifields
._sigpoll
._band
= info
->si_band
;
217 tinfo
->_sifields
._sigpoll
._fd
= info
->si_fd
;
218 } else if (sig
== TARGET_SIGCHLD
) {
219 tinfo
->_sifields
._sigchld
._pid
= info
->si_pid
;
220 tinfo
->_sifields
._sigchld
._uid
= info
->si_uid
;
221 tinfo
->_sifields
._sigchld
._status
222 = host_to_target_waitstatus(info
->si_status
);
223 tinfo
->_sifields
._sigchld
._utime
= info
->si_utime
;
224 tinfo
->_sifields
._sigchld
._stime
= info
->si_stime
;
225 } else if (sig
>= TARGET_SIGRTMIN
) {
226 tinfo
->_sifields
._rt
._pid
= info
->si_pid
;
227 tinfo
->_sifields
._rt
._uid
= info
->si_uid
;
228 /* XXX: potential problem if 64 bit */
229 tinfo
->_sifields
._rt
._sigval
.sival_ptr
230 = (abi_ulong
)(unsigned long)info
->si_value
.sival_ptr
;
234 static void tswap_siginfo(target_siginfo_t
*tinfo
,
235 const target_siginfo_t
*info
)
237 int sig
= info
->si_signo
;
238 tinfo
->si_signo
= tswap32(sig
);
239 tinfo
->si_errno
= tswap32(info
->si_errno
);
240 tinfo
->si_code
= tswap32(info
->si_code
);
242 if (sig
== TARGET_SIGILL
|| sig
== TARGET_SIGFPE
|| sig
== TARGET_SIGSEGV
243 || sig
== TARGET_SIGBUS
|| sig
== TARGET_SIGTRAP
) {
244 tinfo
->_sifields
._sigfault
._addr
245 = tswapal(info
->_sifields
._sigfault
._addr
);
246 } else if (sig
== TARGET_SIGIO
) {
247 tinfo
->_sifields
._sigpoll
._band
248 = tswap32(info
->_sifields
._sigpoll
._band
);
249 tinfo
->_sifields
._sigpoll
._fd
= tswap32(info
->_sifields
._sigpoll
._fd
);
250 } else if (sig
== TARGET_SIGCHLD
) {
251 tinfo
->_sifields
._sigchld
._pid
252 = tswap32(info
->_sifields
._sigchld
._pid
);
253 tinfo
->_sifields
._sigchld
._uid
254 = tswap32(info
->_sifields
._sigchld
._uid
);
255 tinfo
->_sifields
._sigchld
._status
256 = tswap32(info
->_sifields
._sigchld
._status
);
257 tinfo
->_sifields
._sigchld
._utime
258 = tswapal(info
->_sifields
._sigchld
._utime
);
259 tinfo
->_sifields
._sigchld
._stime
260 = tswapal(info
->_sifields
._sigchld
._stime
);
261 } else if (sig
>= TARGET_SIGRTMIN
) {
262 tinfo
->_sifields
._rt
._pid
= tswap32(info
->_sifields
._rt
._pid
);
263 tinfo
->_sifields
._rt
._uid
= tswap32(info
->_sifields
._rt
._uid
);
264 tinfo
->_sifields
._rt
._sigval
.sival_ptr
265 = tswapal(info
->_sifields
._rt
._sigval
.sival_ptr
);
270 void host_to_target_siginfo(target_siginfo_t
*tinfo
, const siginfo_t
*info
)
272 host_to_target_siginfo_noswap(tinfo
, info
);
273 tswap_siginfo(tinfo
, tinfo
);
276 /* XXX: we support only POSIX RT signals are used. */
277 /* XXX: find a solution for 64 bit (additional malloced data is needed) */
278 void target_to_host_siginfo(siginfo_t
*info
, const target_siginfo_t
*tinfo
)
280 info
->si_signo
= tswap32(tinfo
->si_signo
);
281 info
->si_errno
= tswap32(tinfo
->si_errno
);
282 info
->si_code
= tswap32(tinfo
->si_code
);
283 info
->si_pid
= tswap32(tinfo
->_sifields
._rt
._pid
);
284 info
->si_uid
= tswap32(tinfo
->_sifields
._rt
._uid
);
285 info
->si_value
.sival_ptr
=
286 (void *)(long)tswapal(tinfo
->_sifields
._rt
._sigval
.sival_ptr
);
289 static int fatal_signal (int sig
)
294 case TARGET_SIGWINCH
:
295 /* Ignored by default. */
302 /* Job control signals. */
309 /* returns 1 if given signal should dump core if not handled */
310 static int core_dump_signal(int sig
)
326 void signal_init(void)
328 struct sigaction act
;
329 struct sigaction oact
;
333 /* generate signal conversion tables */
334 for(i
= 1; i
< _NSIG
; i
++) {
335 if (host_to_target_signal_table
[i
] == 0)
336 host_to_target_signal_table
[i
] = i
;
338 for(i
= 1; i
< _NSIG
; i
++) {
339 j
= host_to_target_signal_table
[i
];
340 target_to_host_signal_table
[j
] = i
;
343 /* set all host signal handlers. ALL signals are blocked during
344 the handlers to serialize them. */
345 memset(sigact_table
, 0, sizeof(sigact_table
));
347 sigfillset(&act
.sa_mask
);
348 act
.sa_flags
= SA_SIGINFO
;
349 act
.sa_sigaction
= host_signal_handler
;
350 for(i
= 1; i
<= TARGET_NSIG
; i
++) {
351 host_sig
= target_to_host_signal(i
);
352 sigaction(host_sig
, NULL
, &oact
);
353 if (oact
.sa_sigaction
== (void *)SIG_IGN
) {
354 sigact_table
[i
- 1]._sa_handler
= TARGET_SIG_IGN
;
355 } else if (oact
.sa_sigaction
== (void *)SIG_DFL
) {
356 sigact_table
[i
- 1]._sa_handler
= TARGET_SIG_DFL
;
358 /* If there's already a handler installed then something has
359 gone horribly wrong, so don't even try to handle that case. */
360 /* Install some handlers for our own use. We need at least
361 SIGSEGV and SIGBUS, to detect exceptions. We can not just
362 trap all signals because it affects syscall interrupt
363 behavior. But do trap all default-fatal signals. */
364 if (fatal_signal (i
))
365 sigaction(host_sig
, &act
, NULL
);
369 /* signal queue handling */
371 static inline struct sigqueue
*alloc_sigqueue(CPUArchState
*env
)
373 TaskState
*ts
= env
->opaque
;
374 struct sigqueue
*q
= ts
->first_free
;
377 ts
->first_free
= q
->next
;
381 static inline void free_sigqueue(CPUArchState
*env
, struct sigqueue
*q
)
383 TaskState
*ts
= env
->opaque
;
384 q
->next
= ts
->first_free
;
388 /* abort execution with signal */
389 static void QEMU_NORETURN
force_sig(int target_sig
)
391 CPUArchState
*env
= thread_cpu
->env_ptr
;
392 TaskState
*ts
= (TaskState
*)env
->opaque
;
393 int host_sig
, core_dumped
= 0;
394 struct sigaction act
;
395 host_sig
= target_to_host_signal(target_sig
);
396 gdb_signalled(env
, target_sig
);
398 /* dump core if supported by target binary format */
399 if (core_dump_signal(target_sig
) && (ts
->bprm
->core_dump
!= NULL
)) {
402 ((*ts
->bprm
->core_dump
)(target_sig
, env
) == 0);
405 /* we already dumped the core of target process, we don't want
406 * a coredump of qemu itself */
407 struct rlimit nodump
;
408 getrlimit(RLIMIT_CORE
, &nodump
);
410 setrlimit(RLIMIT_CORE
, &nodump
);
411 (void) fprintf(stderr
, "qemu: uncaught target signal %d (%s) - %s\n",
412 target_sig
, strsignal(host_sig
), "core dumped" );
415 /* The proper exit code for dying from an uncaught signal is
416 * -<signal>. The kernel doesn't allow exit() or _exit() to pass
417 * a negative value. To get the proper exit code we need to
418 * actually die from an uncaught signal. Here the default signal
419 * handler is installed, we send ourself a signal and we wait for
421 sigfillset(&act
.sa_mask
);
422 act
.sa_handler
= SIG_DFL
;
423 sigaction(host_sig
, &act
, NULL
);
425 /* For some reason raise(host_sig) doesn't send the signal when
426 * statically linked on x86-64. */
427 kill(getpid(), host_sig
);
429 /* Make sure the signal isn't masked (just reuse the mask inside
431 sigdelset(&act
.sa_mask
, host_sig
);
432 sigsuspend(&act
.sa_mask
);
438 /* queue a signal so that it will be send to the virtual CPU as soon
440 int queue_signal(CPUArchState
*env
, int sig
, target_siginfo_t
*info
)
442 TaskState
*ts
= env
->opaque
;
443 struct emulated_sigtable
*k
;
444 struct sigqueue
*q
, **pq
;
448 #if defined(DEBUG_SIGNAL)
449 fprintf(stderr
, "queue_signal: sig=%d\n",
452 k
= &ts
->sigtab
[sig
- 1];
453 queue
= gdb_queuesig ();
454 handler
= sigact_table
[sig
- 1]._sa_handler
;
455 if (!queue
&& handler
== TARGET_SIG_DFL
) {
456 if (sig
== TARGET_SIGTSTP
|| sig
== TARGET_SIGTTIN
|| sig
== TARGET_SIGTTOU
) {
457 kill(getpid(),SIGSTOP
);
460 /* default handler : ignore some signal. The other are fatal */
461 if (sig
!= TARGET_SIGCHLD
&&
462 sig
!= TARGET_SIGURG
&&
463 sig
!= TARGET_SIGWINCH
&&
464 sig
!= TARGET_SIGCONT
) {
467 return 0; /* indicate ignored */
469 } else if (!queue
&& handler
== TARGET_SIG_IGN
) {
472 } else if (!queue
&& handler
== TARGET_SIG_ERR
) {
476 if (sig
< TARGET_SIGRTMIN
) {
477 /* if non real time signal, we queue exactly one signal */
487 q
= alloc_sigqueue(env
);
498 /* signal that a new signal is pending */
499 ts
->signal_pending
= 1;
500 return 1; /* indicates that the signal was queued */
504 static void host_signal_handler(int host_signum
, siginfo_t
*info
,
507 CPUArchState
*env
= thread_cpu
->env_ptr
;
509 target_siginfo_t tinfo
;
511 /* the CPU emulator uses some host signals to detect exceptions,
512 we forward to it some signals */
513 if ((host_signum
== SIGSEGV
|| host_signum
== SIGBUS
)
514 && info
->si_code
> 0) {
515 if (cpu_signal_handler(host_signum
, info
, puc
))
519 /* get target signal number */
520 sig
= host_to_target_signal(host_signum
);
521 if (sig
< 1 || sig
> TARGET_NSIG
)
523 #if defined(DEBUG_SIGNAL)
524 fprintf(stderr
, "qemu: got signal %d\n", sig
);
526 host_to_target_siginfo_noswap(&tinfo
, info
);
527 if (queue_signal(env
, sig
, &tinfo
) == 1) {
528 /* interrupt the virtual CPU as soon as possible */
529 cpu_exit(thread_cpu
);
533 /* do_sigaltstack() returns target values and errnos. */
534 /* compare linux/kernel/signal.c:do_sigaltstack() */
535 abi_long
do_sigaltstack(abi_ulong uss_addr
, abi_ulong uoss_addr
, abi_ulong sp
)
538 struct target_sigaltstack oss
;
540 /* XXX: test errors */
543 __put_user(target_sigaltstack_used
.ss_sp
, &oss
.ss_sp
);
544 __put_user(target_sigaltstack_used
.ss_size
, &oss
.ss_size
);
545 __put_user(sas_ss_flags(sp
), &oss
.ss_flags
);
550 struct target_sigaltstack
*uss
;
551 struct target_sigaltstack ss
;
553 ret
= -TARGET_EFAULT
;
554 if (!lock_user_struct(VERIFY_READ
, uss
, uss_addr
, 1)
555 || __get_user(ss
.ss_sp
, &uss
->ss_sp
)
556 || __get_user(ss
.ss_size
, &uss
->ss_size
)
557 || __get_user(ss
.ss_flags
, &uss
->ss_flags
))
559 unlock_user_struct(uss
, uss_addr
, 0);
562 if (on_sig_stack(sp
))
565 ret
= -TARGET_EINVAL
;
566 if (ss
.ss_flags
!= TARGET_SS_DISABLE
567 && ss
.ss_flags
!= TARGET_SS_ONSTACK
571 if (ss
.ss_flags
== TARGET_SS_DISABLE
) {
575 ret
= -TARGET_ENOMEM
;
576 if (ss
.ss_size
< MINSIGSTKSZ
)
580 target_sigaltstack_used
.ss_sp
= ss
.ss_sp
;
581 target_sigaltstack_used
.ss_size
= ss
.ss_size
;
585 ret
= -TARGET_EFAULT
;
586 if (copy_to_user(uoss_addr
, &oss
, sizeof(oss
)))
595 /* do_sigaction() return host values and errnos */
596 int do_sigaction(int sig
, const struct target_sigaction
*act
,
597 struct target_sigaction
*oact
)
599 struct target_sigaction
*k
;
600 struct sigaction act1
;
604 if (sig
< 1 || sig
> TARGET_NSIG
|| sig
== TARGET_SIGKILL
|| sig
== TARGET_SIGSTOP
)
606 k
= &sigact_table
[sig
- 1];
607 #if defined(DEBUG_SIGNAL)
608 fprintf(stderr
, "sigaction sig=%d act=0x%p, oact=0x%p\n",
612 __put_user(k
->_sa_handler
, &oact
->_sa_handler
);
613 __put_user(k
->sa_flags
, &oact
->sa_flags
);
614 #if !defined(TARGET_MIPS)
615 __put_user(k
->sa_restorer
, &oact
->sa_restorer
);
618 oact
->sa_mask
= k
->sa_mask
;
621 /* FIXME: This is not threadsafe. */
622 __get_user(k
->_sa_handler
, &act
->_sa_handler
);
623 __get_user(k
->sa_flags
, &act
->sa_flags
);
624 #if !defined(TARGET_MIPS)
625 __get_user(k
->sa_restorer
, &act
->sa_restorer
);
627 /* To be swapped in target_to_host_sigset. */
628 k
->sa_mask
= act
->sa_mask
;
630 /* we update the host linux signal state */
631 host_sig
= target_to_host_signal(sig
);
632 if (host_sig
!= SIGSEGV
&& host_sig
!= SIGBUS
) {
633 sigfillset(&act1
.sa_mask
);
634 act1
.sa_flags
= SA_SIGINFO
;
635 if (k
->sa_flags
& TARGET_SA_RESTART
)
636 act1
.sa_flags
|= SA_RESTART
;
637 /* NOTE: it is important to update the host kernel signal
638 ignore state to avoid getting unexpected interrupted
640 if (k
->_sa_handler
== TARGET_SIG_IGN
) {
641 act1
.sa_sigaction
= (void *)SIG_IGN
;
642 } else if (k
->_sa_handler
== TARGET_SIG_DFL
) {
643 if (fatal_signal (sig
))
644 act1
.sa_sigaction
= host_signal_handler
;
646 act1
.sa_sigaction
= (void *)SIG_DFL
;
648 act1
.sa_sigaction
= host_signal_handler
;
650 ret
= sigaction(host_sig
, &act1
, NULL
);
656 static inline int copy_siginfo_to_user(target_siginfo_t
*tinfo
,
657 const target_siginfo_t
*info
)
659 tswap_siginfo(tinfo
, info
);
663 static inline int current_exec_domain_sig(int sig
)
665 return /* current->exec_domain && current->exec_domain->signal_invmap
666 && sig < 32 ? current->exec_domain->signal_invmap[sig] : */ sig
;
669 #if defined(TARGET_I386) && TARGET_ABI_BITS == 32
671 /* from the Linux kernel */
673 struct target_fpreg
{
674 uint16_t significand
[4];
678 struct target_fpxreg
{
679 uint16_t significand
[4];
684 struct target_xmmreg
{
685 abi_ulong element
[4];
688 struct target_fpstate
{
689 /* Regular FPU environment */
697 struct target_fpreg _st
[8];
699 uint16_t magic
; /* 0xffff = regular FPU data only */
701 /* FXSR FPU environment */
702 abi_ulong _fxsr_env
[6]; /* FXSR FPU env is ignored */
705 struct target_fpxreg _fxsr_st
[8]; /* FXSR FPU reg data is ignored */
706 struct target_xmmreg _xmm
[8];
707 abi_ulong padding
[56];
710 #define X86_FXSR_MAGIC 0x0000
712 struct target_sigcontext
{
730 abi_ulong esp_at_signal
;
732 abi_ulong fpstate
; /* pointer */
737 struct target_ucontext
{
740 target_stack_t tuc_stack
;
741 struct target_sigcontext tuc_mcontext
;
742 target_sigset_t tuc_sigmask
; /* mask last for extensibility */
749 struct target_sigcontext sc
;
750 struct target_fpstate fpstate
;
751 abi_ulong extramask
[TARGET_NSIG_WORDS
-1];
761 struct target_siginfo info
;
762 struct target_ucontext uc
;
763 struct target_fpstate fpstate
;
768 * Set up a signal frame.
771 /* XXX: save x87 state */
773 setup_sigcontext(struct target_sigcontext
*sc
, struct target_fpstate
*fpstate
,
774 CPUX86State
*env
, abi_ulong mask
, abi_ulong fpstate_addr
)
779 /* already locked in setup_frame() */
780 err
|= __put_user(env
->segs
[R_GS
].selector
, (unsigned int *)&sc
->gs
);
781 err
|= __put_user(env
->segs
[R_FS
].selector
, (unsigned int *)&sc
->fs
);
782 err
|= __put_user(env
->segs
[R_ES
].selector
, (unsigned int *)&sc
->es
);
783 err
|= __put_user(env
->segs
[R_DS
].selector
, (unsigned int *)&sc
->ds
);
784 err
|= __put_user(env
->regs
[R_EDI
], &sc
->edi
);
785 err
|= __put_user(env
->regs
[R_ESI
], &sc
->esi
);
786 err
|= __put_user(env
->regs
[R_EBP
], &sc
->ebp
);
787 err
|= __put_user(env
->regs
[R_ESP
], &sc
->esp
);
788 err
|= __put_user(env
->regs
[R_EBX
], &sc
->ebx
);
789 err
|= __put_user(env
->regs
[R_EDX
], &sc
->edx
);
790 err
|= __put_user(env
->regs
[R_ECX
], &sc
->ecx
);
791 err
|= __put_user(env
->regs
[R_EAX
], &sc
->eax
);
792 err
|= __put_user(env
->exception_index
, &sc
->trapno
);
793 err
|= __put_user(env
->error_code
, &sc
->err
);
794 err
|= __put_user(env
->eip
, &sc
->eip
);
795 err
|= __put_user(env
->segs
[R_CS
].selector
, (unsigned int *)&sc
->cs
);
796 err
|= __put_user(env
->eflags
, &sc
->eflags
);
797 err
|= __put_user(env
->regs
[R_ESP
], &sc
->esp_at_signal
);
798 err
|= __put_user(env
->segs
[R_SS
].selector
, (unsigned int *)&sc
->ss
);
800 cpu_x86_fsave(env
, fpstate_addr
, 1);
801 fpstate
->status
= fpstate
->sw
;
803 err
|= __put_user(magic
, &fpstate
->magic
);
804 err
|= __put_user(fpstate_addr
, &sc
->fpstate
);
806 /* non-iBCS2 extensions.. */
807 err
|= __put_user(mask
, &sc
->oldmask
);
808 err
|= __put_user(env
->cr
[2], &sc
->cr2
);
813 * Determine which stack to use..
816 static inline abi_ulong
817 get_sigframe(struct target_sigaction
*ka
, CPUX86State
*env
, size_t frame_size
)
821 /* Default to using normal stack */
822 esp
= env
->regs
[R_ESP
];
823 /* This is the X/Open sanctioned signal stack switching. */
824 if (ka
->sa_flags
& TARGET_SA_ONSTACK
) {
825 if (sas_ss_flags(esp
) == 0)
826 esp
= target_sigaltstack_used
.ss_sp
+ target_sigaltstack_used
.ss_size
;
829 /* This is the legacy signal stack switching. */
831 if ((env
->segs
[R_SS
].selector
& 0xffff) != __USER_DS
&&
832 !(ka
->sa_flags
& TARGET_SA_RESTORER
) &&
834 esp
= (unsigned long) ka
->sa_restorer
;
836 return (esp
- frame_size
) & -8ul;
839 /* compare linux/arch/i386/kernel/signal.c:setup_frame() */
840 static void setup_frame(int sig
, struct target_sigaction
*ka
,
841 target_sigset_t
*set
, CPUX86State
*env
)
843 abi_ulong frame_addr
;
844 struct sigframe
*frame
;
847 frame_addr
= get_sigframe(ka
, env
, sizeof(*frame
));
849 if (!lock_user_struct(VERIFY_WRITE
, frame
, frame_addr
, 0))
852 err
|= __put_user(current_exec_domain_sig(sig
),
857 setup_sigcontext(&frame
->sc
, &frame
->fpstate
, env
, set
->sig
[0],
858 frame_addr
+ offsetof(struct sigframe
, fpstate
));
862 for(i
= 1; i
< TARGET_NSIG_WORDS
; i
++) {
863 if (__put_user(set
->sig
[i
], &frame
->extramask
[i
- 1]))
867 /* Set up to return from userspace. If provided, use a stub
868 already in userspace. */
869 if (ka
->sa_flags
& TARGET_SA_RESTORER
) {
870 err
|= __put_user(ka
->sa_restorer
, &frame
->pretcode
);
873 abi_ulong retcode_addr
;
874 retcode_addr
= frame_addr
+ offsetof(struct sigframe
, retcode
);
875 err
|= __put_user(retcode_addr
, &frame
->pretcode
);
876 /* This is popl %eax ; movl $,%eax ; int $0x80 */
878 err
|= __put_user(val16
, (uint16_t *)(frame
->retcode
+0));
879 err
|= __put_user(TARGET_NR_sigreturn
, (int *)(frame
->retcode
+2));
881 err
|= __put_user(val16
, (uint16_t *)(frame
->retcode
+6));
887 /* Set up registers for signal handler */
888 env
->regs
[R_ESP
] = frame_addr
;
889 env
->eip
= ka
->_sa_handler
;
891 cpu_x86_load_seg(env
, R_DS
, __USER_DS
);
892 cpu_x86_load_seg(env
, R_ES
, __USER_DS
);
893 cpu_x86_load_seg(env
, R_SS
, __USER_DS
);
894 cpu_x86_load_seg(env
, R_CS
, __USER_CS
);
895 env
->eflags
&= ~TF_MASK
;
897 unlock_user_struct(frame
, frame_addr
, 1);
902 unlock_user_struct(frame
, frame_addr
, 1);
903 if (sig
== TARGET_SIGSEGV
)
904 ka
->_sa_handler
= TARGET_SIG_DFL
;
905 force_sig(TARGET_SIGSEGV
/* , current */);
908 /* compare linux/arch/i386/kernel/signal.c:setup_rt_frame() */
909 static void setup_rt_frame(int sig
, struct target_sigaction
*ka
,
910 target_siginfo_t
*info
,
911 target_sigset_t
*set
, CPUX86State
*env
)
913 abi_ulong frame_addr
, addr
;
914 struct rt_sigframe
*frame
;
917 frame_addr
= get_sigframe(ka
, env
, sizeof(*frame
));
919 if (!lock_user_struct(VERIFY_WRITE
, frame
, frame_addr
, 0))
922 err
|= __put_user(current_exec_domain_sig(sig
),
924 addr
= frame_addr
+ offsetof(struct rt_sigframe
, info
);
925 err
|= __put_user(addr
, &frame
->pinfo
);
926 addr
= frame_addr
+ offsetof(struct rt_sigframe
, uc
);
927 err
|= __put_user(addr
, &frame
->puc
);
928 err
|= copy_siginfo_to_user(&frame
->info
, info
);
932 /* Create the ucontext. */
933 err
|= __put_user(0, &frame
->uc
.tuc_flags
);
934 err
|= __put_user(0, &frame
->uc
.tuc_link
);
935 err
|= __put_user(target_sigaltstack_used
.ss_sp
,
936 &frame
->uc
.tuc_stack
.ss_sp
);
937 err
|= __put_user(sas_ss_flags(get_sp_from_cpustate(env
)),
938 &frame
->uc
.tuc_stack
.ss_flags
);
939 err
|= __put_user(target_sigaltstack_used
.ss_size
,
940 &frame
->uc
.tuc_stack
.ss_size
);
941 err
|= setup_sigcontext(&frame
->uc
.tuc_mcontext
, &frame
->fpstate
,
943 frame_addr
+ offsetof(struct rt_sigframe
, fpstate
));
944 for(i
= 0; i
< TARGET_NSIG_WORDS
; i
++) {
945 if (__put_user(set
->sig
[i
], &frame
->uc
.tuc_sigmask
.sig
[i
]))
949 /* Set up to return from userspace. If provided, use a stub
950 already in userspace. */
951 if (ka
->sa_flags
& TARGET_SA_RESTORER
) {
952 err
|= __put_user(ka
->sa_restorer
, &frame
->pretcode
);
955 addr
= frame_addr
+ offsetof(struct rt_sigframe
, retcode
);
956 err
|= __put_user(addr
, &frame
->pretcode
);
957 /* This is movl $,%eax ; int $0x80 */
958 err
|= __put_user(0xb8, (char *)(frame
->retcode
+0));
959 err
|= __put_user(TARGET_NR_rt_sigreturn
, (int *)(frame
->retcode
+1));
961 err
|= __put_user(val16
, (uint16_t *)(frame
->retcode
+5));
967 /* Set up registers for signal handler */
968 env
->regs
[R_ESP
] = frame_addr
;
969 env
->eip
= ka
->_sa_handler
;
971 cpu_x86_load_seg(env
, R_DS
, __USER_DS
);
972 cpu_x86_load_seg(env
, R_ES
, __USER_DS
);
973 cpu_x86_load_seg(env
, R_SS
, __USER_DS
);
974 cpu_x86_load_seg(env
, R_CS
, __USER_CS
);
975 env
->eflags
&= ~TF_MASK
;
977 unlock_user_struct(frame
, frame_addr
, 1);
982 unlock_user_struct(frame
, frame_addr
, 1);
983 if (sig
== TARGET_SIGSEGV
)
984 ka
->_sa_handler
= TARGET_SIG_DFL
;
985 force_sig(TARGET_SIGSEGV
/* , current */);
989 restore_sigcontext(CPUX86State
*env
, struct target_sigcontext
*sc
, int *peax
)
991 unsigned int err
= 0;
992 abi_ulong fpstate_addr
;
993 unsigned int tmpflags
;
995 cpu_x86_load_seg(env
, R_GS
, tswap16(sc
->gs
));
996 cpu_x86_load_seg(env
, R_FS
, tswap16(sc
->fs
));
997 cpu_x86_load_seg(env
, R_ES
, tswap16(sc
->es
));
998 cpu_x86_load_seg(env
, R_DS
, tswap16(sc
->ds
));
1000 env
->regs
[R_EDI
] = tswapl(sc
->edi
);
1001 env
->regs
[R_ESI
] = tswapl(sc
->esi
);
1002 env
->regs
[R_EBP
] = tswapl(sc
->ebp
);
1003 env
->regs
[R_ESP
] = tswapl(sc
->esp
);
1004 env
->regs
[R_EBX
] = tswapl(sc
->ebx
);
1005 env
->regs
[R_EDX
] = tswapl(sc
->edx
);
1006 env
->regs
[R_ECX
] = tswapl(sc
->ecx
);
1007 env
->eip
= tswapl(sc
->eip
);
1009 cpu_x86_load_seg(env
, R_CS
, lduw_p(&sc
->cs
) | 3);
1010 cpu_x86_load_seg(env
, R_SS
, lduw_p(&sc
->ss
) | 3);
1012 tmpflags
= tswapl(sc
->eflags
);
1013 env
->eflags
= (env
->eflags
& ~0x40DD5) | (tmpflags
& 0x40DD5);
1014 // regs->orig_eax = -1; /* disable syscall checks */
1016 fpstate_addr
= tswapl(sc
->fpstate
);
1017 if (fpstate_addr
!= 0) {
1018 if (!access_ok(VERIFY_READ
, fpstate_addr
,
1019 sizeof(struct target_fpstate
)))
1021 cpu_x86_frstor(env
, fpstate_addr
, 1);
1024 *peax
= tswapl(sc
->eax
);
1030 long do_sigreturn(CPUX86State
*env
)
1032 struct sigframe
*frame
;
1033 abi_ulong frame_addr
= env
->regs
[R_ESP
] - 8;
1034 target_sigset_t target_set
;
1038 #if defined(DEBUG_SIGNAL)
1039 fprintf(stderr
, "do_sigreturn\n");
1041 if (!lock_user_struct(VERIFY_READ
, frame
, frame_addr
, 1))
1043 /* set blocked signals */
1044 if (__get_user(target_set
.sig
[0], &frame
->sc
.oldmask
))
1046 for(i
= 1; i
< TARGET_NSIG_WORDS
; i
++) {
1047 if (__get_user(target_set
.sig
[i
], &frame
->extramask
[i
- 1]))
1051 target_to_host_sigset_internal(&set
, &target_set
);
1052 sigprocmask(SIG_SETMASK
, &set
, NULL
);
1054 /* restore registers */
1055 if (restore_sigcontext(env
, &frame
->sc
, &eax
))
1057 unlock_user_struct(frame
, frame_addr
, 0);
1061 unlock_user_struct(frame
, frame_addr
, 0);
1062 force_sig(TARGET_SIGSEGV
);
1066 long do_rt_sigreturn(CPUX86State
*env
)
1068 abi_ulong frame_addr
;
1069 struct rt_sigframe
*frame
;
1073 frame_addr
= env
->regs
[R_ESP
] - 4;
1074 if (!lock_user_struct(VERIFY_READ
, frame
, frame_addr
, 1))
1076 target_to_host_sigset(&set
, &frame
->uc
.tuc_sigmask
);
1077 sigprocmask(SIG_SETMASK
, &set
, NULL
);
1079 if (restore_sigcontext(env
, &frame
->uc
.tuc_mcontext
, &eax
))
1082 if (do_sigaltstack(frame_addr
+ offsetof(struct rt_sigframe
, uc
.tuc_stack
), 0,
1083 get_sp_from_cpustate(env
)) == -EFAULT
)
1086 unlock_user_struct(frame
, frame_addr
, 0);
1090 unlock_user_struct(frame
, frame_addr
, 0);
1091 force_sig(TARGET_SIGSEGV
);
1095 #elif defined(TARGET_AARCH64)
1097 struct target_sigcontext
{
1098 uint64_t fault_address
;
1099 /* AArch64 registers */
1104 /* 4K reserved for FP/SIMD state and future expansion */
1105 char __reserved
[4096] __attribute__((__aligned__(16)));
1108 struct target_ucontext
{
1109 abi_ulong tuc_flags
;
1111 target_stack_t tuc_stack
;
1112 target_sigset_t tuc_sigmask
;
1113 /* glibc uses a 1024-bit sigset_t */
1114 char __unused
[1024 / 8 - sizeof(target_sigset_t
)];
1115 /* last for future expansion */
1116 struct target_sigcontext tuc_mcontext
;
1120 * Header to be used at the beginning of structures extending the user
1121 * context. Such structures must be placed after the rt_sigframe on the stack
1122 * and be 16-byte aligned. The last structure must be a dummy one with the
1123 * magic and size set to 0.
1125 struct target_aarch64_ctx
{
1130 #define TARGET_FPSIMD_MAGIC 0x46508001
1132 struct target_fpsimd_context
{
1133 struct target_aarch64_ctx head
;
1136 uint64_t vregs
[32 * 2]; /* really uint128_t vregs[32] */
1140 * Auxiliary context saved in the sigcontext.__reserved array. Not exported to
1141 * user space as it will change with the addition of new context. User space
1142 * should check the magic/size information.
1144 struct target_aux_context
{
1145 struct target_fpsimd_context fpsimd
;
1146 /* additional context to be added before "end" */
1147 struct target_aarch64_ctx end
;
1150 struct target_rt_sigframe
{
1151 struct target_siginfo info
;
1152 struct target_ucontext uc
;
1158 static int target_setup_sigframe(struct target_rt_sigframe
*sf
,
1159 CPUARMState
*env
, target_sigset_t
*set
)
1162 struct target_aux_context
*aux
=
1163 (struct target_aux_context
*)sf
->uc
.tuc_mcontext
.__reserved
;
1165 /* set up the stack frame for unwinding */
1166 __put_user(env
->xregs
[29], &sf
->fp
);
1167 __put_user(env
->xregs
[30], &sf
->lr
);
1169 for (i
= 0; i
< 31; i
++) {
1170 __put_user(env
->xregs
[i
], &sf
->uc
.tuc_mcontext
.regs
[i
]);
1172 __put_user(env
->xregs
[31], &sf
->uc
.tuc_mcontext
.sp
);
1173 __put_user(env
->pc
, &sf
->uc
.tuc_mcontext
.pc
);
1174 __put_user(pstate_read(env
), &sf
->uc
.tuc_mcontext
.pstate
);
1176 __put_user(/*current->thread.fault_address*/ 0,
1177 &sf
->uc
.tuc_mcontext
.fault_address
);
1179 for (i
= 0; i
< TARGET_NSIG_WORDS
; i
++) {
1180 __put_user(set
->sig
[i
], &sf
->uc
.tuc_sigmask
.sig
[i
]);
1183 for (i
= 0; i
< 32; i
++) {
1184 #ifdef TARGET_WORDS_BIGENDIAN
1185 __put_user(env
->vfp
.regs
[i
* 2], &aux
->fpsimd
.vregs
[i
* 2 + 1]);
1186 __put_user(env
->vfp
.regs
[i
* 2 + 1], &aux
->fpsimd
.vregs
[i
* 2]);
1188 __put_user(env
->vfp
.regs
[i
* 2], &aux
->fpsimd
.vregs
[i
* 2]);
1189 __put_user(env
->vfp
.regs
[i
* 2 + 1], &aux
->fpsimd
.vregs
[i
* 2 + 1]);
1192 __put_user(vfp_get_fpsr(env
), &aux
->fpsimd
.fpsr
);
1193 __put_user(vfp_get_fpcr(env
), &aux
->fpsimd
.fpcr
);
1194 __put_user(TARGET_FPSIMD_MAGIC
, &aux
->fpsimd
.head
.magic
);
1195 __put_user(sizeof(struct target_fpsimd_context
),
1196 &aux
->fpsimd
.head
.size
);
1198 /* set the "end" magic */
1199 __put_user(0, &aux
->end
.magic
);
1200 __put_user(0, &aux
->end
.size
);
1205 static int target_restore_sigframe(CPUARMState
*env
,
1206 struct target_rt_sigframe
*sf
)
1210 struct target_aux_context
*aux
=
1211 (struct target_aux_context
*)sf
->uc
.tuc_mcontext
.__reserved
;
1212 uint32_t magic
, size
, fpsr
, fpcr
;
1215 target_to_host_sigset(&set
, &sf
->uc
.tuc_sigmask
);
1216 sigprocmask(SIG_SETMASK
, &set
, NULL
);
1218 for (i
= 0; i
< 31; i
++) {
1219 __get_user(env
->xregs
[i
], &sf
->uc
.tuc_mcontext
.regs
[i
]);
1222 __get_user(env
->xregs
[31], &sf
->uc
.tuc_mcontext
.sp
);
1223 __get_user(env
->pc
, &sf
->uc
.tuc_mcontext
.pc
);
1224 __get_user(pstate
, &sf
->uc
.tuc_mcontext
.pstate
);
1225 pstate_write(env
, pstate
);
1227 __get_user(magic
, &aux
->fpsimd
.head
.magic
);
1228 __get_user(size
, &aux
->fpsimd
.head
.size
);
1230 if (magic
!= TARGET_FPSIMD_MAGIC
1231 || size
!= sizeof(struct target_fpsimd_context
)) {
1235 for (i
= 0; i
< 32 * 2; i
++) {
1236 __get_user(env
->vfp
.regs
[i
], &aux
->fpsimd
.vregs
[i
]);
1238 __get_user(fpsr
, &aux
->fpsimd
.fpsr
);
1239 vfp_set_fpsr(env
, fpsr
);
1240 __get_user(fpcr
, &aux
->fpsimd
.fpcr
);
1241 vfp_set_fpcr(env
, fpcr
);
1246 static abi_ulong
get_sigframe(struct target_sigaction
*ka
, CPUARMState
*env
)
1250 sp
= env
->xregs
[31];
1253 * This is the X/Open sanctioned signal stack switching.
1255 if ((ka
->sa_flags
& SA_ONSTACK
) && !sas_ss_flags(sp
)) {
1256 sp
= target_sigaltstack_used
.ss_sp
+ target_sigaltstack_used
.ss_size
;
1259 sp
= (sp
- sizeof(struct target_rt_sigframe
)) & ~15;
1264 static void target_setup_frame(int usig
, struct target_sigaction
*ka
,
1265 target_siginfo_t
*info
, target_sigset_t
*set
,
1268 struct target_rt_sigframe
*frame
;
1269 abi_ulong frame_addr
;
1271 frame_addr
= get_sigframe(ka
, env
);
1272 if (!lock_user_struct(VERIFY_WRITE
, frame
, frame_addr
, 0)) {
1276 __put_user(0, &frame
->uc
.tuc_flags
);
1277 __put_user(0, &frame
->uc
.tuc_link
);
1279 __put_user(target_sigaltstack_used
.ss_sp
,
1280 &frame
->uc
.tuc_stack
.ss_sp
);
1281 __put_user(sas_ss_flags(env
->xregs
[31]),
1282 &frame
->uc
.tuc_stack
.ss_flags
);
1283 __put_user(target_sigaltstack_used
.ss_size
,
1284 &frame
->uc
.tuc_stack
.ss_size
);
1285 target_setup_sigframe(frame
, env
, set
);
1286 /* mov x8,#__NR_rt_sigreturn; svc #0 */
1287 __put_user(0xd2801168, &frame
->tramp
[0]);
1288 __put_user(0xd4000001, &frame
->tramp
[1]);
1289 env
->xregs
[0] = usig
;
1290 env
->xregs
[31] = frame_addr
;
1291 env
->xregs
[29] = env
->xregs
[31] + offsetof(struct target_rt_sigframe
, fp
);
1292 env
->pc
= ka
->_sa_handler
;
1293 env
->xregs
[30] = env
->xregs
[31] +
1294 offsetof(struct target_rt_sigframe
, tramp
);
1296 if (copy_siginfo_to_user(&frame
->info
, info
)) {
1299 env
->xregs
[1] = frame_addr
+ offsetof(struct target_rt_sigframe
, info
);
1300 env
->xregs
[2] = frame_addr
+ offsetof(struct target_rt_sigframe
, uc
);
1303 unlock_user_struct(frame
, frame_addr
, 1);
1307 unlock_user_struct(frame
, frame_addr
, 1);
1308 force_sig(TARGET_SIGSEGV
);
1311 static void setup_rt_frame(int sig
, struct target_sigaction
*ka
,
1312 target_siginfo_t
*info
, target_sigset_t
*set
,
1315 target_setup_frame(sig
, ka
, info
, set
, env
);
1318 static void setup_frame(int sig
, struct target_sigaction
*ka
,
1319 target_sigset_t
*set
, CPUARMState
*env
)
1321 target_setup_frame(sig
, ka
, 0, set
, env
);
1324 long do_rt_sigreturn(CPUARMState
*env
)
1326 struct target_rt_sigframe
*frame
;
1327 abi_ulong frame_addr
= env
->xregs
[31];
1329 if (frame_addr
& 15) {
1333 if (!lock_user_struct(VERIFY_READ
, frame
, frame_addr
, 1)) {
1337 if (target_restore_sigframe(env
, frame
)) {
1341 if (do_sigaltstack(frame_addr
+
1342 offsetof(struct target_rt_sigframe
, uc
.tuc_stack
),
1343 0, get_sp_from_cpustate(env
)) == -EFAULT
) {
1347 unlock_user_struct(frame
, frame_addr
, 0);
1348 return env
->xregs
[0];
1351 unlock_user_struct(frame
, frame_addr
, 0);
1352 force_sig(TARGET_SIGSEGV
);
1356 long do_sigreturn(CPUARMState
*env
)
1358 return do_rt_sigreturn(env
);
1361 #elif defined(TARGET_ARM)
1363 struct target_sigcontext
{
1365 abi_ulong error_code
;
1384 abi_ulong fault_address
;
1387 struct target_ucontext_v1
{
1388 abi_ulong tuc_flags
;
1390 target_stack_t tuc_stack
;
1391 struct target_sigcontext tuc_mcontext
;
1392 target_sigset_t tuc_sigmask
; /* mask last for extensibility */
1395 struct target_ucontext_v2
{
1396 abi_ulong tuc_flags
;
1398 target_stack_t tuc_stack
;
1399 struct target_sigcontext tuc_mcontext
;
1400 target_sigset_t tuc_sigmask
; /* mask last for extensibility */
1401 char __unused
[128 - sizeof(target_sigset_t
)];
1402 abi_ulong tuc_regspace
[128] __attribute__((__aligned__(8)));
1405 struct target_user_vfp
{
1406 uint64_t fpregs
[32];
1410 struct target_user_vfp_exc
{
1416 struct target_vfp_sigframe
{
1419 struct target_user_vfp ufp
;
1420 struct target_user_vfp_exc ufp_exc
;
1421 } __attribute__((__aligned__(8)));
1423 struct target_iwmmxt_sigframe
{
1427 /* Note that not all the coprocessor control registers are stored here */
1434 } __attribute__((__aligned__(8)));
1436 #define TARGET_VFP_MAGIC 0x56465001
1437 #define TARGET_IWMMXT_MAGIC 0x12ef842a
1441 struct target_sigcontext sc
;
1442 abi_ulong extramask
[TARGET_NSIG_WORDS
-1];
1448 struct target_ucontext_v2 uc
;
1452 struct rt_sigframe_v1
1456 struct target_siginfo info
;
1457 struct target_ucontext_v1 uc
;
1461 struct rt_sigframe_v2
1463 struct target_siginfo info
;
1464 struct target_ucontext_v2 uc
;
1468 #define TARGET_CONFIG_CPU_32 1
1471 * For ARM syscalls, we encode the syscall number into the instruction.
1473 #define SWI_SYS_SIGRETURN (0xef000000|(TARGET_NR_sigreturn + ARM_SYSCALL_BASE))
1474 #define SWI_SYS_RT_SIGRETURN (0xef000000|(TARGET_NR_rt_sigreturn + ARM_SYSCALL_BASE))
1477 * For Thumb syscalls, we pass the syscall number via r7. We therefore
1478 * need two 16-bit instructions.
1480 #define SWI_THUMB_SIGRETURN (0xdf00 << 16 | 0x2700 | (TARGET_NR_sigreturn))
1481 #define SWI_THUMB_RT_SIGRETURN (0xdf00 << 16 | 0x2700 | (TARGET_NR_rt_sigreturn))
1483 static const abi_ulong retcodes
[4] = {
1484 SWI_SYS_SIGRETURN
, SWI_THUMB_SIGRETURN
,
1485 SWI_SYS_RT_SIGRETURN
, SWI_THUMB_RT_SIGRETURN
1489 #define __get_user_error(x,p,e) __get_user(x, p)
1491 static inline int valid_user_regs(CPUARMState
*regs
)
1497 setup_sigcontext(struct target_sigcontext
*sc
, /*struct _fpstate *fpstate,*/
1498 CPUARMState
*env
, abi_ulong mask
)
1500 __put_user(env
->regs
[0], &sc
->arm_r0
);
1501 __put_user(env
->regs
[1], &sc
->arm_r1
);
1502 __put_user(env
->regs
[2], &sc
->arm_r2
);
1503 __put_user(env
->regs
[3], &sc
->arm_r3
);
1504 __put_user(env
->regs
[4], &sc
->arm_r4
);
1505 __put_user(env
->regs
[5], &sc
->arm_r5
);
1506 __put_user(env
->regs
[6], &sc
->arm_r6
);
1507 __put_user(env
->regs
[7], &sc
->arm_r7
);
1508 __put_user(env
->regs
[8], &sc
->arm_r8
);
1509 __put_user(env
->regs
[9], &sc
->arm_r9
);
1510 __put_user(env
->regs
[10], &sc
->arm_r10
);
1511 __put_user(env
->regs
[11], &sc
->arm_fp
);
1512 __put_user(env
->regs
[12], &sc
->arm_ip
);
1513 __put_user(env
->regs
[13], &sc
->arm_sp
);
1514 __put_user(env
->regs
[14], &sc
->arm_lr
);
1515 __put_user(env
->regs
[15], &sc
->arm_pc
);
1516 #ifdef TARGET_CONFIG_CPU_32
1517 __put_user(cpsr_read(env
), &sc
->arm_cpsr
);
1520 __put_user(/* current->thread.trap_no */ 0, &sc
->trap_no
);
1521 __put_user(/* current->thread.error_code */ 0, &sc
->error_code
);
1522 __put_user(/* current->thread.address */ 0, &sc
->fault_address
);
1523 __put_user(mask
, &sc
->oldmask
);
1526 static inline abi_ulong
1527 get_sigframe(struct target_sigaction
*ka
, CPUARMState
*regs
, int framesize
)
1529 unsigned long sp
= regs
->regs
[13];
1532 * This is the X/Open sanctioned signal stack switching.
1534 if ((ka
->sa_flags
& TARGET_SA_ONSTACK
) && !sas_ss_flags(sp
))
1535 sp
= target_sigaltstack_used
.ss_sp
+ target_sigaltstack_used
.ss_size
;
1537 * ATPCS B01 mandates 8-byte alignment
1539 return (sp
- framesize
) & ~7;
1543 setup_return(CPUARMState
*env
, struct target_sigaction
*ka
,
1544 abi_ulong
*rc
, abi_ulong frame_addr
, int usig
, abi_ulong rc_addr
)
1546 abi_ulong handler
= ka
->_sa_handler
;
1548 int thumb
= handler
& 1;
1549 uint32_t cpsr
= cpsr_read(env
);
1558 if (ka
->sa_flags
& TARGET_SA_RESTORER
) {
1559 retcode
= ka
->sa_restorer
;
1561 unsigned int idx
= thumb
;
1563 if (ka
->sa_flags
& TARGET_SA_SIGINFO
)
1566 if (__put_user(retcodes
[idx
], rc
))
1569 retcode
= rc_addr
+ thumb
;
1572 env
->regs
[0] = usig
;
1573 env
->regs
[13] = frame_addr
;
1574 env
->regs
[14] = retcode
;
1575 env
->regs
[15] = handler
& (thumb
? ~1 : ~3);
1576 cpsr_write(env
, cpsr
, 0xffffffff);
1581 static abi_ulong
*setup_sigframe_v2_vfp(abi_ulong
*regspace
, CPUARMState
*env
)
1584 struct target_vfp_sigframe
*vfpframe
;
1585 vfpframe
= (struct target_vfp_sigframe
*)regspace
;
1586 __put_user(TARGET_VFP_MAGIC
, &vfpframe
->magic
);
1587 __put_user(sizeof(*vfpframe
), &vfpframe
->size
);
1588 for (i
= 0; i
< 32; i
++) {
1589 __put_user(float64_val(env
->vfp
.regs
[i
]), &vfpframe
->ufp
.fpregs
[i
]);
1591 __put_user(vfp_get_fpscr(env
), &vfpframe
->ufp
.fpscr
);
1592 __put_user(env
->vfp
.xregs
[ARM_VFP_FPEXC
], &vfpframe
->ufp_exc
.fpexc
);
1593 __put_user(env
->vfp
.xregs
[ARM_VFP_FPINST
], &vfpframe
->ufp_exc
.fpinst
);
1594 __put_user(env
->vfp
.xregs
[ARM_VFP_FPINST2
], &vfpframe
->ufp_exc
.fpinst2
);
1595 return (abi_ulong
*)(vfpframe
+1);
1598 static abi_ulong
*setup_sigframe_v2_iwmmxt(abi_ulong
*regspace
,
1602 struct target_iwmmxt_sigframe
*iwmmxtframe
;
1603 iwmmxtframe
= (struct target_iwmmxt_sigframe
*)regspace
;
1604 __put_user(TARGET_IWMMXT_MAGIC
, &iwmmxtframe
->magic
);
1605 __put_user(sizeof(*iwmmxtframe
), &iwmmxtframe
->size
);
1606 for (i
= 0; i
< 16; i
++) {
1607 __put_user(env
->iwmmxt
.regs
[i
], &iwmmxtframe
->regs
[i
]);
1609 __put_user(env
->vfp
.xregs
[ARM_IWMMXT_wCSSF
], &iwmmxtframe
->wcssf
);
1610 __put_user(env
->vfp
.xregs
[ARM_IWMMXT_wCASF
], &iwmmxtframe
->wcssf
);
1611 __put_user(env
->vfp
.xregs
[ARM_IWMMXT_wCGR0
], &iwmmxtframe
->wcgr0
);
1612 __put_user(env
->vfp
.xregs
[ARM_IWMMXT_wCGR1
], &iwmmxtframe
->wcgr1
);
1613 __put_user(env
->vfp
.xregs
[ARM_IWMMXT_wCGR2
], &iwmmxtframe
->wcgr2
);
1614 __put_user(env
->vfp
.xregs
[ARM_IWMMXT_wCGR3
], &iwmmxtframe
->wcgr3
);
1615 return (abi_ulong
*)(iwmmxtframe
+1);
1618 static void setup_sigframe_v2(struct target_ucontext_v2
*uc
,
1619 target_sigset_t
*set
, CPUARMState
*env
)
1621 struct target_sigaltstack stack
;
1623 abi_ulong
*regspace
;
1625 /* Clear all the bits of the ucontext we don't use. */
1626 memset(uc
, 0, offsetof(struct target_ucontext_v2
, tuc_mcontext
));
1628 memset(&stack
, 0, sizeof(stack
));
1629 __put_user(target_sigaltstack_used
.ss_sp
, &stack
.ss_sp
);
1630 __put_user(target_sigaltstack_used
.ss_size
, &stack
.ss_size
);
1631 __put_user(sas_ss_flags(get_sp_from_cpustate(env
)), &stack
.ss_flags
);
1632 memcpy(&uc
->tuc_stack
, &stack
, sizeof(stack
));
1634 setup_sigcontext(&uc
->tuc_mcontext
, env
, set
->sig
[0]);
1635 /* Save coprocessor signal frame. */
1636 regspace
= uc
->tuc_regspace
;
1637 if (arm_feature(env
, ARM_FEATURE_VFP
)) {
1638 regspace
= setup_sigframe_v2_vfp(regspace
, env
);
1640 if (arm_feature(env
, ARM_FEATURE_IWMMXT
)) {
1641 regspace
= setup_sigframe_v2_iwmmxt(regspace
, env
);
1644 /* Write terminating magic word */
1645 __put_user(0, regspace
);
1647 for(i
= 0; i
< TARGET_NSIG_WORDS
; i
++) {
1648 __put_user(set
->sig
[i
], &uc
->tuc_sigmask
.sig
[i
]);
1652 /* compare linux/arch/arm/kernel/signal.c:setup_frame() */
1653 static void setup_frame_v1(int usig
, struct target_sigaction
*ka
,
1654 target_sigset_t
*set
, CPUARMState
*regs
)
1656 struct sigframe_v1
*frame
;
1657 abi_ulong frame_addr
= get_sigframe(ka
, regs
, sizeof(*frame
));
1660 if (!lock_user_struct(VERIFY_WRITE
, frame
, frame_addr
, 0))
1663 setup_sigcontext(&frame
->sc
, regs
, set
->sig
[0]);
1665 for(i
= 1; i
< TARGET_NSIG_WORDS
; i
++) {
1666 if (__put_user(set
->sig
[i
], &frame
->extramask
[i
- 1]))
1670 setup_return(regs
, ka
, &frame
->retcode
, frame_addr
, usig
,
1671 frame_addr
+ offsetof(struct sigframe_v1
, retcode
));
1674 unlock_user_struct(frame
, frame_addr
, 1);
1677 static void setup_frame_v2(int usig
, struct target_sigaction
*ka
,
1678 target_sigset_t
*set
, CPUARMState
*regs
)
1680 struct sigframe_v2
*frame
;
1681 abi_ulong frame_addr
= get_sigframe(ka
, regs
, sizeof(*frame
));
1683 if (!lock_user_struct(VERIFY_WRITE
, frame
, frame_addr
, 0))
1686 setup_sigframe_v2(&frame
->uc
, set
, regs
);
1688 setup_return(regs
, ka
, &frame
->retcode
, frame_addr
, usig
,
1689 frame_addr
+ offsetof(struct sigframe_v2
, retcode
));
1691 unlock_user_struct(frame
, frame_addr
, 1);
1694 static void setup_frame(int usig
, struct target_sigaction
*ka
,
1695 target_sigset_t
*set
, CPUARMState
*regs
)
1697 if (get_osversion() >= 0x020612) {
1698 setup_frame_v2(usig
, ka
, set
, regs
);
1700 setup_frame_v1(usig
, ka
, set
, regs
);
1704 /* compare linux/arch/arm/kernel/signal.c:setup_rt_frame() */
1705 static void setup_rt_frame_v1(int usig
, struct target_sigaction
*ka
,
1706 target_siginfo_t
*info
,
1707 target_sigset_t
*set
, CPUARMState
*env
)
1709 struct rt_sigframe_v1
*frame
;
1710 abi_ulong frame_addr
= get_sigframe(ka
, env
, sizeof(*frame
));
1711 struct target_sigaltstack stack
;
1713 abi_ulong info_addr
, uc_addr
;
1715 if (!lock_user_struct(VERIFY_WRITE
, frame
, frame_addr
, 0))
1718 info_addr
= frame_addr
+ offsetof(struct rt_sigframe_v1
, info
);
1719 __put_user(info_addr
, &frame
->pinfo
);
1720 uc_addr
= frame_addr
+ offsetof(struct rt_sigframe_v1
, uc
);
1721 __put_user(uc_addr
, &frame
->puc
);
1722 copy_siginfo_to_user(&frame
->info
, info
);
1724 /* Clear all the bits of the ucontext we don't use. */
1725 memset(&frame
->uc
, 0, offsetof(struct target_ucontext_v1
, tuc_mcontext
));
1727 memset(&stack
, 0, sizeof(stack
));
1728 __put_user(target_sigaltstack_used
.ss_sp
, &stack
.ss_sp
);
1729 __put_user(target_sigaltstack_used
.ss_size
, &stack
.ss_size
);
1730 __put_user(sas_ss_flags(get_sp_from_cpustate(env
)), &stack
.ss_flags
);
1731 memcpy(&frame
->uc
.tuc_stack
, &stack
, sizeof(stack
));
1733 setup_sigcontext(&frame
->uc
.tuc_mcontext
, env
, set
->sig
[0]);
1734 for(i
= 0; i
< TARGET_NSIG_WORDS
; i
++) {
1735 if (__put_user(set
->sig
[i
], &frame
->uc
.tuc_sigmask
.sig
[i
]))
1739 setup_return(env
, ka
, &frame
->retcode
, frame_addr
, usig
,
1740 frame_addr
+ offsetof(struct rt_sigframe_v1
, retcode
));
1742 env
->regs
[1] = info_addr
;
1743 env
->regs
[2] = uc_addr
;
1746 unlock_user_struct(frame
, frame_addr
, 1);
1749 static void setup_rt_frame_v2(int usig
, struct target_sigaction
*ka
,
1750 target_siginfo_t
*info
,
1751 target_sigset_t
*set
, CPUARMState
*env
)
1753 struct rt_sigframe_v2
*frame
;
1754 abi_ulong frame_addr
= get_sigframe(ka
, env
, sizeof(*frame
));
1755 abi_ulong info_addr
, uc_addr
;
1757 if (!lock_user_struct(VERIFY_WRITE
, frame
, frame_addr
, 0))
1760 info_addr
= frame_addr
+ offsetof(struct rt_sigframe_v2
, info
);
1761 uc_addr
= frame_addr
+ offsetof(struct rt_sigframe_v2
, uc
);
1762 copy_siginfo_to_user(&frame
->info
, info
);
1764 setup_sigframe_v2(&frame
->uc
, set
, env
);
1766 setup_return(env
, ka
, &frame
->retcode
, frame_addr
, usig
,
1767 frame_addr
+ offsetof(struct rt_sigframe_v2
, retcode
));
1769 env
->regs
[1] = info_addr
;
1770 env
->regs
[2] = uc_addr
;
1772 unlock_user_struct(frame
, frame_addr
, 1);
1775 static void setup_rt_frame(int usig
, struct target_sigaction
*ka
,
1776 target_siginfo_t
*info
,
1777 target_sigset_t
*set
, CPUARMState
*env
)
1779 if (get_osversion() >= 0x020612) {
1780 setup_rt_frame_v2(usig
, ka
, info
, set
, env
);
1782 setup_rt_frame_v1(usig
, ka
, info
, set
, env
);
1787 restore_sigcontext(CPUARMState
*env
, struct target_sigcontext
*sc
)
1792 __get_user_error(env
->regs
[0], &sc
->arm_r0
, err
);
1793 __get_user_error(env
->regs
[1], &sc
->arm_r1
, err
);
1794 __get_user_error(env
->regs
[2], &sc
->arm_r2
, err
);
1795 __get_user_error(env
->regs
[3], &sc
->arm_r3
, err
);
1796 __get_user_error(env
->regs
[4], &sc
->arm_r4
, err
);
1797 __get_user_error(env
->regs
[5], &sc
->arm_r5
, err
);
1798 __get_user_error(env
->regs
[6], &sc
->arm_r6
, err
);
1799 __get_user_error(env
->regs
[7], &sc
->arm_r7
, err
);
1800 __get_user_error(env
->regs
[8], &sc
->arm_r8
, err
);
1801 __get_user_error(env
->regs
[9], &sc
->arm_r9
, err
);
1802 __get_user_error(env
->regs
[10], &sc
->arm_r10
, err
);
1803 __get_user_error(env
->regs
[11], &sc
->arm_fp
, err
);
1804 __get_user_error(env
->regs
[12], &sc
->arm_ip
, err
);
1805 __get_user_error(env
->regs
[13], &sc
->arm_sp
, err
);
1806 __get_user_error(env
->regs
[14], &sc
->arm_lr
, err
);
1807 __get_user_error(env
->regs
[15], &sc
->arm_pc
, err
);
1808 #ifdef TARGET_CONFIG_CPU_32
1809 __get_user_error(cpsr
, &sc
->arm_cpsr
, err
);
1810 cpsr_write(env
, cpsr
, CPSR_USER
| CPSR_EXEC
);
1813 err
|= !valid_user_regs(env
);
1818 static long do_sigreturn_v1(CPUARMState
*env
)
1820 abi_ulong frame_addr
;
1821 struct sigframe_v1
*frame
= NULL
;
1822 target_sigset_t set
;
1827 * Since we stacked the signal on a 64-bit boundary,
1828 * then 'sp' should be word aligned here. If it's
1829 * not, then the user is trying to mess with us.
1831 frame_addr
= env
->regs
[13];
1832 if (frame_addr
& 7) {
1836 if (!lock_user_struct(VERIFY_READ
, frame
, frame_addr
, 1))
1839 if (__get_user(set
.sig
[0], &frame
->sc
.oldmask
))
1841 for(i
= 1; i
< TARGET_NSIG_WORDS
; i
++) {
1842 if (__get_user(set
.sig
[i
], &frame
->extramask
[i
- 1]))
1846 target_to_host_sigset_internal(&host_set
, &set
);
1847 sigprocmask(SIG_SETMASK
, &host_set
, NULL
);
1849 if (restore_sigcontext(env
, &frame
->sc
))
1853 /* Send SIGTRAP if we're single-stepping */
1854 if (ptrace_cancel_bpt(current
))
1855 send_sig(SIGTRAP
, current
, 1);
1857 unlock_user_struct(frame
, frame_addr
, 0);
1858 return env
->regs
[0];
1861 unlock_user_struct(frame
, frame_addr
, 0);
1862 force_sig(TARGET_SIGSEGV
/* , current */);
1866 static abi_ulong
*restore_sigframe_v2_vfp(CPUARMState
*env
, abi_ulong
*regspace
)
1869 abi_ulong magic
, sz
;
1870 uint32_t fpscr
, fpexc
;
1871 struct target_vfp_sigframe
*vfpframe
;
1872 vfpframe
= (struct target_vfp_sigframe
*)regspace
;
1874 __get_user(magic
, &vfpframe
->magic
);
1875 __get_user(sz
, &vfpframe
->size
);
1876 if (magic
!= TARGET_VFP_MAGIC
|| sz
!= sizeof(*vfpframe
)) {
1879 for (i
= 0; i
< 32; i
++) {
1880 __get_user(float64_val(env
->vfp
.regs
[i
]), &vfpframe
->ufp
.fpregs
[i
]);
1882 __get_user(fpscr
, &vfpframe
->ufp
.fpscr
);
1883 vfp_set_fpscr(env
, fpscr
);
1884 __get_user(fpexc
, &vfpframe
->ufp_exc
.fpexc
);
1885 /* Sanitise FPEXC: ensure VFP is enabled, FPINST2 is invalid
1886 * and the exception flag is cleared
1889 fpexc
&= ~((1 << 31) | (1 << 28));
1890 env
->vfp
.xregs
[ARM_VFP_FPEXC
] = fpexc
;
1891 __get_user(env
->vfp
.xregs
[ARM_VFP_FPINST
], &vfpframe
->ufp_exc
.fpinst
);
1892 __get_user(env
->vfp
.xregs
[ARM_VFP_FPINST2
], &vfpframe
->ufp_exc
.fpinst2
);
1893 return (abi_ulong
*)(vfpframe
+ 1);
1896 static abi_ulong
*restore_sigframe_v2_iwmmxt(CPUARMState
*env
,
1897 abi_ulong
*regspace
)
1900 abi_ulong magic
, sz
;
1901 struct target_iwmmxt_sigframe
*iwmmxtframe
;
1902 iwmmxtframe
= (struct target_iwmmxt_sigframe
*)regspace
;
1904 __get_user(magic
, &iwmmxtframe
->magic
);
1905 __get_user(sz
, &iwmmxtframe
->size
);
1906 if (magic
!= TARGET_IWMMXT_MAGIC
|| sz
!= sizeof(*iwmmxtframe
)) {
1909 for (i
= 0; i
< 16; i
++) {
1910 __get_user(env
->iwmmxt
.regs
[i
], &iwmmxtframe
->regs
[i
]);
1912 __get_user(env
->vfp
.xregs
[ARM_IWMMXT_wCSSF
], &iwmmxtframe
->wcssf
);
1913 __get_user(env
->vfp
.xregs
[ARM_IWMMXT_wCASF
], &iwmmxtframe
->wcssf
);
1914 __get_user(env
->vfp
.xregs
[ARM_IWMMXT_wCGR0
], &iwmmxtframe
->wcgr0
);
1915 __get_user(env
->vfp
.xregs
[ARM_IWMMXT_wCGR1
], &iwmmxtframe
->wcgr1
);
1916 __get_user(env
->vfp
.xregs
[ARM_IWMMXT_wCGR2
], &iwmmxtframe
->wcgr2
);
1917 __get_user(env
->vfp
.xregs
[ARM_IWMMXT_wCGR3
], &iwmmxtframe
->wcgr3
);
1918 return (abi_ulong
*)(iwmmxtframe
+ 1);
1921 static int do_sigframe_return_v2(CPUARMState
*env
, target_ulong frame_addr
,
1922 struct target_ucontext_v2
*uc
)
1925 abi_ulong
*regspace
;
1927 target_to_host_sigset(&host_set
, &uc
->tuc_sigmask
);
1928 sigprocmask(SIG_SETMASK
, &host_set
, NULL
);
1930 if (restore_sigcontext(env
, &uc
->tuc_mcontext
))
1933 /* Restore coprocessor signal frame */
1934 regspace
= uc
->tuc_regspace
;
1935 if (arm_feature(env
, ARM_FEATURE_VFP
)) {
1936 regspace
= restore_sigframe_v2_vfp(env
, regspace
);
1941 if (arm_feature(env
, ARM_FEATURE_IWMMXT
)) {
1942 regspace
= restore_sigframe_v2_iwmmxt(env
, regspace
);
1948 if (do_sigaltstack(frame_addr
+ offsetof(struct target_ucontext_v2
, tuc_stack
), 0, get_sp_from_cpustate(env
)) == -EFAULT
)
1952 /* Send SIGTRAP if we're single-stepping */
1953 if (ptrace_cancel_bpt(current
))
1954 send_sig(SIGTRAP
, current
, 1);
1960 static long do_sigreturn_v2(CPUARMState
*env
)
1962 abi_ulong frame_addr
;
1963 struct sigframe_v2
*frame
= NULL
;
1966 * Since we stacked the signal on a 64-bit boundary,
1967 * then 'sp' should be word aligned here. If it's
1968 * not, then the user is trying to mess with us.
1970 frame_addr
= env
->regs
[13];
1971 if (frame_addr
& 7) {
1975 if (!lock_user_struct(VERIFY_READ
, frame
, frame_addr
, 1))
1978 if (do_sigframe_return_v2(env
, frame_addr
, &frame
->uc
))
1981 unlock_user_struct(frame
, frame_addr
, 0);
1982 return env
->regs
[0];
1985 unlock_user_struct(frame
, frame_addr
, 0);
1986 force_sig(TARGET_SIGSEGV
/* , current */);
1990 long do_sigreturn(CPUARMState
*env
)
1992 if (get_osversion() >= 0x020612) {
1993 return do_sigreturn_v2(env
);
1995 return do_sigreturn_v1(env
);
1999 static long do_rt_sigreturn_v1(CPUARMState
*env
)
2001 abi_ulong frame_addr
;
2002 struct rt_sigframe_v1
*frame
= NULL
;
2006 * Since we stacked the signal on a 64-bit boundary,
2007 * then 'sp' should be word aligned here. If it's
2008 * not, then the user is trying to mess with us.
2010 frame_addr
= env
->regs
[13];
2011 if (frame_addr
& 7) {
2015 if (!lock_user_struct(VERIFY_READ
, frame
, frame_addr
, 1))
2018 target_to_host_sigset(&host_set
, &frame
->uc
.tuc_sigmask
);
2019 sigprocmask(SIG_SETMASK
, &host_set
, NULL
);
2021 if (restore_sigcontext(env
, &frame
->uc
.tuc_mcontext
))
2024 if (do_sigaltstack(frame_addr
+ offsetof(struct rt_sigframe_v1
, uc
.tuc_stack
), 0, get_sp_from_cpustate(env
)) == -EFAULT
)
2028 /* Send SIGTRAP if we're single-stepping */
2029 if (ptrace_cancel_bpt(current
))
2030 send_sig(SIGTRAP
, current
, 1);
2032 unlock_user_struct(frame
, frame_addr
, 0);
2033 return env
->regs
[0];
2036 unlock_user_struct(frame
, frame_addr
, 0);
2037 force_sig(TARGET_SIGSEGV
/* , current */);
2041 static long do_rt_sigreturn_v2(CPUARMState
*env
)
2043 abi_ulong frame_addr
;
2044 struct rt_sigframe_v2
*frame
= NULL
;
2047 * Since we stacked the signal on a 64-bit boundary,
2048 * then 'sp' should be word aligned here. If it's
2049 * not, then the user is trying to mess with us.
2051 frame_addr
= env
->regs
[13];
2052 if (frame_addr
& 7) {
2056 if (!lock_user_struct(VERIFY_READ
, frame
, frame_addr
, 1))
2059 if (do_sigframe_return_v2(env
, frame_addr
, &frame
->uc
))
2062 unlock_user_struct(frame
, frame_addr
, 0);
2063 return env
->regs
[0];
2066 unlock_user_struct(frame
, frame_addr
, 0);
2067 force_sig(TARGET_SIGSEGV
/* , current */);
2071 long do_rt_sigreturn(CPUARMState
*env
)
2073 if (get_osversion() >= 0x020612) {
2074 return do_rt_sigreturn_v2(env
);
2076 return do_rt_sigreturn_v1(env
);
2080 #elif defined(TARGET_SPARC)
2082 #define __SUNOS_MAXWIN 31
2084 /* This is what SunOS does, so shall I. */
2085 struct target_sigcontext
{
2086 abi_ulong sigc_onstack
; /* state to restore */
2088 abi_ulong sigc_mask
; /* sigmask to restore */
2089 abi_ulong sigc_sp
; /* stack pointer */
2090 abi_ulong sigc_pc
; /* program counter */
2091 abi_ulong sigc_npc
; /* next program counter */
2092 abi_ulong sigc_psr
; /* for condition codes etc */
2093 abi_ulong sigc_g1
; /* User uses these two registers */
2094 abi_ulong sigc_o0
; /* within the trampoline code. */
2096 /* Now comes information regarding the users window set
2097 * at the time of the signal.
2099 abi_ulong sigc_oswins
; /* outstanding windows */
2101 /* stack ptrs for each regwin buf */
2102 char *sigc_spbuf
[__SUNOS_MAXWIN
];
2104 /* Windows to restore after signal */
2106 abi_ulong locals
[8];
2108 } sigc_wbuf
[__SUNOS_MAXWIN
];
2110 /* A Sparc stack frame */
2111 struct sparc_stackf
{
2112 abi_ulong locals
[8];
2114 /* It's simpler to treat fp and callers_pc as elements of ins[]
2115 * since we never need to access them ourselves.
2119 abi_ulong xxargs
[1];
2128 abi_ulong u_regs
[16]; /* globals and ins */
2134 abi_ulong si_float_regs
[32];
2135 unsigned long si_fsr
;
2136 unsigned long si_fpqdepth
;
2138 unsigned long *insn_addr
;
2141 } qemu_siginfo_fpu_t
;
2144 struct target_signal_frame
{
2145 struct sparc_stackf ss
;
2148 abi_ulong insns
[2] __attribute__ ((aligned (8)));
2149 abi_ulong extramask
[TARGET_NSIG_WORDS
- 1];
2150 abi_ulong extra_size
; /* Should be 0 */
2151 qemu_siginfo_fpu_t fpu_state
;
2153 struct target_rt_signal_frame
{
2154 struct sparc_stackf ss
;
2159 unsigned int insns
[2];
2161 unsigned int extra_size
; /* Should be 0 */
2162 qemu_siginfo_fpu_t fpu_state
;
2176 #define UREG_FP UREG_I6
2177 #define UREG_SP UREG_O6
2179 static inline abi_ulong
get_sigframe(struct target_sigaction
*sa
,
2181 unsigned long framesize
)
2185 sp
= env
->regwptr
[UREG_FP
];
2187 /* This is the X/Open sanctioned signal stack switching. */
2188 if (sa
->sa_flags
& TARGET_SA_ONSTACK
) {
2189 if (!on_sig_stack(sp
)
2190 && !((target_sigaltstack_used
.ss_sp
+ target_sigaltstack_used
.ss_size
) & 7))
2191 sp
= target_sigaltstack_used
.ss_sp
+ target_sigaltstack_used
.ss_size
;
2193 return sp
- framesize
;
2197 setup___siginfo(__siginfo_t
*si
, CPUSPARCState
*env
, abi_ulong mask
)
2201 err
|= __put_user(env
->psr
, &si
->si_regs
.psr
);
2202 err
|= __put_user(env
->pc
, &si
->si_regs
.pc
);
2203 err
|= __put_user(env
->npc
, &si
->si_regs
.npc
);
2204 err
|= __put_user(env
->y
, &si
->si_regs
.y
);
2205 for (i
=0; i
< 8; i
++) {
2206 err
|= __put_user(env
->gregs
[i
], &si
->si_regs
.u_regs
[i
]);
2208 for (i
=0; i
< 8; i
++) {
2209 err
|= __put_user(env
->regwptr
[UREG_I0
+ i
], &si
->si_regs
.u_regs
[i
+8]);
2211 err
|= __put_user(mask
, &si
->si_mask
);
2217 setup_sigcontext(struct target_sigcontext
*sc
, /*struct _fpstate *fpstate,*/
2218 CPUSPARCState
*env
, unsigned long mask
)
2222 err
|= __put_user(mask
, &sc
->sigc_mask
);
2223 err
|= __put_user(env
->regwptr
[UREG_SP
], &sc
->sigc_sp
);
2224 err
|= __put_user(env
->pc
, &sc
->sigc_pc
);
2225 err
|= __put_user(env
->npc
, &sc
->sigc_npc
);
2226 err
|= __put_user(env
->psr
, &sc
->sigc_psr
);
2227 err
|= __put_user(env
->gregs
[1], &sc
->sigc_g1
);
2228 err
|= __put_user(env
->regwptr
[UREG_O0
], &sc
->sigc_o0
);
2233 #define NF_ALIGNEDSZ (((sizeof(struct target_signal_frame) + 7) & (~7)))
2235 static void setup_frame(int sig
, struct target_sigaction
*ka
,
2236 target_sigset_t
*set
, CPUSPARCState
*env
)
2239 struct target_signal_frame
*sf
;
2240 int sigframe_size
, err
, i
;
2242 /* 1. Make sure everything is clean */
2243 //synchronize_user_stack();
2245 sigframe_size
= NF_ALIGNEDSZ
;
2246 sf_addr
= get_sigframe(ka
, env
, sigframe_size
);
2248 sf
= lock_user(VERIFY_WRITE
, sf_addr
,
2249 sizeof(struct target_signal_frame
), 0);
2253 //fprintf(stderr, "sf: %x pc %x fp %x sp %x\n", sf, env->pc, env->regwptr[UREG_FP], env->regwptr[UREG_SP]);
2255 if (invalid_frame_pointer(sf
, sigframe_size
))
2256 goto sigill_and_return
;
2258 /* 2. Save the current process state */
2259 err
= setup___siginfo(&sf
->info
, env
, set
->sig
[0]);
2260 err
|= __put_user(0, &sf
->extra_size
);
2262 //err |= save_fpu_state(regs, &sf->fpu_state);
2263 //err |= __put_user(&sf->fpu_state, &sf->fpu_save);
2265 err
|= __put_user(set
->sig
[0], &sf
->info
.si_mask
);
2266 for (i
= 0; i
< TARGET_NSIG_WORDS
- 1; i
++) {
2267 err
|= __put_user(set
->sig
[i
+ 1], &sf
->extramask
[i
]);
2270 for (i
= 0; i
< 8; i
++) {
2271 err
|= __put_user(env
->regwptr
[i
+ UREG_L0
], &sf
->ss
.locals
[i
]);
2273 for (i
= 0; i
< 8; i
++) {
2274 err
|= __put_user(env
->regwptr
[i
+ UREG_I0
], &sf
->ss
.ins
[i
]);
2279 /* 3. signal handler back-trampoline and parameters */
2280 env
->regwptr
[UREG_FP
] = sf_addr
;
2281 env
->regwptr
[UREG_I0
] = sig
;
2282 env
->regwptr
[UREG_I1
] = sf_addr
+
2283 offsetof(struct target_signal_frame
, info
);
2284 env
->regwptr
[UREG_I2
] = sf_addr
+
2285 offsetof(struct target_signal_frame
, info
);
2287 /* 4. signal handler */
2288 env
->pc
= ka
->_sa_handler
;
2289 env
->npc
= (env
->pc
+ 4);
2290 /* 5. return to kernel instructions */
2291 if (ka
->sa_restorer
)
2292 env
->regwptr
[UREG_I7
] = ka
->sa_restorer
;
2296 env
->regwptr
[UREG_I7
] = sf_addr
+
2297 offsetof(struct target_signal_frame
, insns
) - 2 * 4;
2299 /* mov __NR_sigreturn, %g1 */
2301 err
|= __put_user(val32
, &sf
->insns
[0]);
2305 err
|= __put_user(val32
, &sf
->insns
[1]);
2309 /* Flush instruction space. */
2310 //flush_sig_insns(current->mm, (unsigned long) &(sf->insns[0]));
2313 unlock_user(sf
, sf_addr
, sizeof(struct target_signal_frame
));
2317 force_sig(TARGET_SIGILL
);
2320 //fprintf(stderr, "force_sig\n");
2321 unlock_user(sf
, sf_addr
, sizeof(struct target_signal_frame
));
2322 force_sig(TARGET_SIGSEGV
);
2325 restore_fpu_state(CPUSPARCState
*env
, qemu_siginfo_fpu_t
*fpu
)
2330 if (current
->flags
& PF_USEDFPU
)
2331 regs
->psr
&= ~PSR_EF
;
2333 if (current
== last_task_used_math
) {
2334 last_task_used_math
= 0;
2335 regs
->psr
&= ~PSR_EF
;
2338 current
->used_math
= 1;
2339 current
->flags
&= ~PF_USEDFPU
;
2342 if (verify_area (VERIFY_READ
, fpu
, sizeof(*fpu
)))
2346 /* XXX: incorrect */
2347 err
= copy_from_user(&env
->fpr
[0], fpu
->si_float_regs
[0],
2348 (sizeof(abi_ulong
) * 32));
2349 err
|= __get_user(env
->fsr
, &fpu
->si_fsr
);
2351 err
|= __get_user(current
->thread
.fpqdepth
, &fpu
->si_fpqdepth
);
2352 if (current
->thread
.fpqdepth
!= 0)
2353 err
|= __copy_from_user(¤t
->thread
.fpqueue
[0],
2354 &fpu
->si_fpqueue
[0],
2355 ((sizeof(unsigned long) +
2356 (sizeof(unsigned long *)))*16));
2362 static void setup_rt_frame(int sig
, struct target_sigaction
*ka
,
2363 target_siginfo_t
*info
,
2364 target_sigset_t
*set
, CPUSPARCState
*env
)
2366 fprintf(stderr
, "setup_rt_frame: not implemented\n");
2369 long do_sigreturn(CPUSPARCState
*env
)
2372 struct target_signal_frame
*sf
;
2373 uint32_t up_psr
, pc
, npc
;
2374 target_sigset_t set
;
2378 sf_addr
= env
->regwptr
[UREG_FP
];
2379 if (!lock_user_struct(VERIFY_READ
, sf
, sf_addr
, 1))
2382 fprintf(stderr
, "sigreturn\n");
2383 fprintf(stderr
, "sf: %x pc %x fp %x sp %x\n", sf
, env
->pc
, env
->regwptr
[UREG_FP
], env
->regwptr
[UREG_SP
]);
2385 //cpu_dump_state(env, stderr, fprintf, 0);
2387 /* 1. Make sure we are not getting garbage from the user */
2392 err
= __get_user(pc
, &sf
->info
.si_regs
.pc
);
2393 err
|= __get_user(npc
, &sf
->info
.si_regs
.npc
);
2398 /* 2. Restore the state */
2399 err
|= __get_user(up_psr
, &sf
->info
.si_regs
.psr
);
2401 /* User can only change condition codes and FPU enabling in %psr. */
2402 env
->psr
= (up_psr
& (PSR_ICC
/* | PSR_EF */))
2403 | (env
->psr
& ~(PSR_ICC
/* | PSR_EF */));
2407 err
|= __get_user(env
->y
, &sf
->info
.si_regs
.y
);
2408 for (i
=0; i
< 8; i
++) {
2409 err
|= __get_user(env
->gregs
[i
], &sf
->info
.si_regs
.u_regs
[i
]);
2411 for (i
=0; i
< 8; i
++) {
2412 err
|= __get_user(env
->regwptr
[i
+ UREG_I0
], &sf
->info
.si_regs
.u_regs
[i
+8]);
2415 /* FIXME: implement FPU save/restore:
2416 * __get_user(fpu_save, &sf->fpu_save);
2418 * err |= restore_fpu_state(env, fpu_save);
2421 /* This is pretty much atomic, no amount locking would prevent
2422 * the races which exist anyways.
2424 err
|= __get_user(set
.sig
[0], &sf
->info
.si_mask
);
2425 for(i
= 1; i
< TARGET_NSIG_WORDS
; i
++) {
2426 err
|= (__get_user(set
.sig
[i
], &sf
->extramask
[i
- 1]));
2429 target_to_host_sigset_internal(&host_set
, &set
);
2430 sigprocmask(SIG_SETMASK
, &host_set
, NULL
);
2434 unlock_user_struct(sf
, sf_addr
, 0);
2435 return env
->regwptr
[0];
2438 unlock_user_struct(sf
, sf_addr
, 0);
2439 force_sig(TARGET_SIGSEGV
);
2442 long do_rt_sigreturn(CPUSPARCState
*env
)
2444 fprintf(stderr
, "do_rt_sigreturn: not implemented\n");
2445 return -TARGET_ENOSYS
;
2448 #if defined(TARGET_SPARC64) && !defined(TARGET_ABI32)
2470 typedef abi_ulong target_mc_greg_t
;
2471 typedef target_mc_greg_t target_mc_gregset_t
[MC_NGREG
];
2473 struct target_mc_fq
{
2474 abi_ulong
*mcfq_addr
;
2478 struct target_mc_fpu
{
2482 //uint128_t qregs[16];
2484 abi_ulong mcfpu_fsr
;
2485 abi_ulong mcfpu_fprs
;
2486 abi_ulong mcfpu_gsr
;
2487 struct target_mc_fq
*mcfpu_fq
;
2488 unsigned char mcfpu_qcnt
;
2489 unsigned char mcfpu_qentsz
;
2490 unsigned char mcfpu_enab
;
2492 typedef struct target_mc_fpu target_mc_fpu_t
;
2495 target_mc_gregset_t mc_gregs
;
2496 target_mc_greg_t mc_fp
;
2497 target_mc_greg_t mc_i7
;
2498 target_mc_fpu_t mc_fpregs
;
2499 } target_mcontext_t
;
2501 struct target_ucontext
{
2502 struct target_ucontext
*tuc_link
;
2503 abi_ulong tuc_flags
;
2504 target_sigset_t tuc_sigmask
;
2505 target_mcontext_t tuc_mcontext
;
2508 /* A V9 register window */
2509 struct target_reg_window
{
2510 abi_ulong locals
[8];
2514 #define TARGET_STACK_BIAS 2047
2516 /* {set, get}context() needed for 64-bit SparcLinux userland. */
2517 void sparc64_set_context(CPUSPARCState
*env
)
2520 struct target_ucontext
*ucp
;
2521 target_mc_gregset_t
*grp
;
2522 abi_ulong pc
, npc
, tstate
;
2523 abi_ulong fp
, i7
, w_addr
;
2527 ucp_addr
= env
->regwptr
[UREG_I0
];
2528 if (!lock_user_struct(VERIFY_READ
, ucp
, ucp_addr
, 1))
2530 grp
= &ucp
->tuc_mcontext
.mc_gregs
;
2531 err
= __get_user(pc
, &((*grp
)[MC_PC
]));
2532 err
|= __get_user(npc
, &((*grp
)[MC_NPC
]));
2533 if (err
|| ((pc
| npc
) & 3))
2535 if (env
->regwptr
[UREG_I1
]) {
2536 target_sigset_t target_set
;
2539 if (TARGET_NSIG_WORDS
== 1) {
2540 if (__get_user(target_set
.sig
[0], &ucp
->tuc_sigmask
.sig
[0]))
2543 abi_ulong
*src
, *dst
;
2544 src
= ucp
->tuc_sigmask
.sig
;
2545 dst
= target_set
.sig
;
2546 for (i
= 0; i
< TARGET_NSIG_WORDS
; i
++, dst
++, src
++) {
2547 err
|= __get_user(*dst
, src
);
2552 target_to_host_sigset_internal(&set
, &target_set
);
2553 sigprocmask(SIG_SETMASK
, &set
, NULL
);
2557 err
|= __get_user(env
->y
, &((*grp
)[MC_Y
]));
2558 err
|= __get_user(tstate
, &((*grp
)[MC_TSTATE
]));
2559 env
->asi
= (tstate
>> 24) & 0xff;
2560 cpu_put_ccr(env
, tstate
>> 32);
2561 cpu_put_cwp64(env
, tstate
& 0x1f);
2562 err
|= __get_user(env
->gregs
[1], (&(*grp
)[MC_G1
]));
2563 err
|= __get_user(env
->gregs
[2], (&(*grp
)[MC_G2
]));
2564 err
|= __get_user(env
->gregs
[3], (&(*grp
)[MC_G3
]));
2565 err
|= __get_user(env
->gregs
[4], (&(*grp
)[MC_G4
]));
2566 err
|= __get_user(env
->gregs
[5], (&(*grp
)[MC_G5
]));
2567 err
|= __get_user(env
->gregs
[6], (&(*grp
)[MC_G6
]));
2568 err
|= __get_user(env
->gregs
[7], (&(*grp
)[MC_G7
]));
2569 err
|= __get_user(env
->regwptr
[UREG_I0
], (&(*grp
)[MC_O0
]));
2570 err
|= __get_user(env
->regwptr
[UREG_I1
], (&(*grp
)[MC_O1
]));
2571 err
|= __get_user(env
->regwptr
[UREG_I2
], (&(*grp
)[MC_O2
]));
2572 err
|= __get_user(env
->regwptr
[UREG_I3
], (&(*grp
)[MC_O3
]));
2573 err
|= __get_user(env
->regwptr
[UREG_I4
], (&(*grp
)[MC_O4
]));
2574 err
|= __get_user(env
->regwptr
[UREG_I5
], (&(*grp
)[MC_O5
]));
2575 err
|= __get_user(env
->regwptr
[UREG_I6
], (&(*grp
)[MC_O6
]));
2576 err
|= __get_user(env
->regwptr
[UREG_I7
], (&(*grp
)[MC_O7
]));
2578 err
|= __get_user(fp
, &(ucp
->tuc_mcontext
.mc_fp
));
2579 err
|= __get_user(i7
, &(ucp
->tuc_mcontext
.mc_i7
));
2581 w_addr
= TARGET_STACK_BIAS
+env
->regwptr
[UREG_I6
];
2582 if (put_user(fp
, w_addr
+ offsetof(struct target_reg_window
, ins
[6]),
2585 if (put_user(i7
, w_addr
+ offsetof(struct target_reg_window
, ins
[7]),
2588 /* FIXME this does not match how the kernel handles the FPU in
2589 * its sparc64_set_context implementation. In particular the FPU
2590 * is only restored if fenab is non-zero in:
2591 * __get_user(fenab, &(ucp->tuc_mcontext.mc_fpregs.mcfpu_enab));
2593 err
|= __get_user(env
->fprs
, &(ucp
->tuc_mcontext
.mc_fpregs
.mcfpu_fprs
));
2595 uint32_t *src
= ucp
->tuc_mcontext
.mc_fpregs
.mcfpu_fregs
.sregs
;
2596 for (i
= 0; i
< 64; i
++, src
++) {
2598 err
|= __get_user(env
->fpr
[i
/2].l
.lower
, src
);
2600 err
|= __get_user(env
->fpr
[i
/2].l
.upper
, src
);
2604 err
|= __get_user(env
->fsr
,
2605 &(ucp
->tuc_mcontext
.mc_fpregs
.mcfpu_fsr
));
2606 err
|= __get_user(env
->gsr
,
2607 &(ucp
->tuc_mcontext
.mc_fpregs
.mcfpu_gsr
));
2610 unlock_user_struct(ucp
, ucp_addr
, 0);
2613 unlock_user_struct(ucp
, ucp_addr
, 0);
2614 force_sig(TARGET_SIGSEGV
);
2617 void sparc64_get_context(CPUSPARCState
*env
)
2620 struct target_ucontext
*ucp
;
2621 target_mc_gregset_t
*grp
;
2622 target_mcontext_t
*mcp
;
2623 abi_ulong fp
, i7
, w_addr
;
2626 target_sigset_t target_set
;
2629 ucp_addr
= env
->regwptr
[UREG_I0
];
2630 if (!lock_user_struct(VERIFY_WRITE
, ucp
, ucp_addr
, 0))
2633 mcp
= &ucp
->tuc_mcontext
;
2634 grp
= &mcp
->mc_gregs
;
2636 /* Skip over the trap instruction, first. */
2642 sigprocmask(0, NULL
, &set
);
2643 host_to_target_sigset_internal(&target_set
, &set
);
2644 if (TARGET_NSIG_WORDS
== 1) {
2645 err
|= __put_user(target_set
.sig
[0],
2646 (abi_ulong
*)&ucp
->tuc_sigmask
);
2648 abi_ulong
*src
, *dst
;
2649 src
= target_set
.sig
;
2650 dst
= ucp
->tuc_sigmask
.sig
;
2651 for (i
= 0; i
< TARGET_NSIG_WORDS
; i
++, dst
++, src
++) {
2652 err
|= __put_user(*src
, dst
);
2658 /* XXX: tstate must be saved properly */
2659 // err |= __put_user(env->tstate, &((*grp)[MC_TSTATE]));
2660 err
|= __put_user(env
->pc
, &((*grp
)[MC_PC
]));
2661 err
|= __put_user(env
->npc
, &((*grp
)[MC_NPC
]));
2662 err
|= __put_user(env
->y
, &((*grp
)[MC_Y
]));
2663 err
|= __put_user(env
->gregs
[1], &((*grp
)[MC_G1
]));
2664 err
|= __put_user(env
->gregs
[2], &((*grp
)[MC_G2
]));
2665 err
|= __put_user(env
->gregs
[3], &((*grp
)[MC_G3
]));
2666 err
|= __put_user(env
->gregs
[4], &((*grp
)[MC_G4
]));
2667 err
|= __put_user(env
->gregs
[5], &((*grp
)[MC_G5
]));
2668 err
|= __put_user(env
->gregs
[6], &((*grp
)[MC_G6
]));
2669 err
|= __put_user(env
->gregs
[7], &((*grp
)[MC_G7
]));
2670 err
|= __put_user(env
->regwptr
[UREG_I0
], &((*grp
)[MC_O0
]));
2671 err
|= __put_user(env
->regwptr
[UREG_I1
], &((*grp
)[MC_O1
]));
2672 err
|= __put_user(env
->regwptr
[UREG_I2
], &((*grp
)[MC_O2
]));
2673 err
|= __put_user(env
->regwptr
[UREG_I3
], &((*grp
)[MC_O3
]));
2674 err
|= __put_user(env
->regwptr
[UREG_I4
], &((*grp
)[MC_O4
]));
2675 err
|= __put_user(env
->regwptr
[UREG_I5
], &((*grp
)[MC_O5
]));
2676 err
|= __put_user(env
->regwptr
[UREG_I6
], &((*grp
)[MC_O6
]));
2677 err
|= __put_user(env
->regwptr
[UREG_I7
], &((*grp
)[MC_O7
]));
2679 w_addr
= TARGET_STACK_BIAS
+env
->regwptr
[UREG_I6
];
2681 if (get_user(fp
, w_addr
+ offsetof(struct target_reg_window
, ins
[6]),
2684 if (get_user(i7
, w_addr
+ offsetof(struct target_reg_window
, ins
[7]),
2687 err
|= __put_user(fp
, &(mcp
->mc_fp
));
2688 err
|= __put_user(i7
, &(mcp
->mc_i7
));
2691 uint32_t *dst
= ucp
->tuc_mcontext
.mc_fpregs
.mcfpu_fregs
.sregs
;
2692 for (i
= 0; i
< 64; i
++, dst
++) {
2694 err
|= __put_user(env
->fpr
[i
/2].l
.lower
, dst
);
2696 err
|= __put_user(env
->fpr
[i
/2].l
.upper
, dst
);
2700 err
|= __put_user(env
->fsr
, &(mcp
->mc_fpregs
.mcfpu_fsr
));
2701 err
|= __put_user(env
->gsr
, &(mcp
->mc_fpregs
.mcfpu_gsr
));
2702 err
|= __put_user(env
->fprs
, &(mcp
->mc_fpregs
.mcfpu_fprs
));
2706 unlock_user_struct(ucp
, ucp_addr
, 1);
2709 unlock_user_struct(ucp
, ucp_addr
, 1);
2710 force_sig(TARGET_SIGSEGV
);
2713 #elif defined(TARGET_MIPS) || defined(TARGET_MIPS64)
2715 # if defined(TARGET_ABI_MIPSO32)
2716 struct target_sigcontext
{
2717 uint32_t sc_regmask
; /* Unused */
2720 uint64_t sc_regs
[32];
2721 uint64_t sc_fpregs
[32];
2722 uint32_t sc_ownedfp
; /* Unused */
2723 uint32_t sc_fpc_csr
;
2724 uint32_t sc_fpc_eir
; /* Unused */
2725 uint32_t sc_used_math
;
2726 uint32_t sc_dsp
; /* dsp status, was sc_ssflags */
2730 target_ulong sc_hi1
; /* Was sc_cause */
2731 target_ulong sc_lo1
; /* Was sc_badvaddr */
2732 target_ulong sc_hi2
; /* Was sc_sigset[4] */
2733 target_ulong sc_lo2
;
2734 target_ulong sc_hi3
;
2735 target_ulong sc_lo3
;
2737 # else /* N32 || N64 */
2738 struct target_sigcontext
{
2739 uint64_t sc_regs
[32];
2740 uint64_t sc_fpregs
[32];
2750 uint32_t sc_fpc_csr
;
2751 uint32_t sc_used_math
;
2753 uint32_t sc_reserved
;
2758 uint32_t sf_ass
[4]; /* argument save space for o32 */
2759 uint32_t sf_code
[2]; /* signal trampoline */
2760 struct target_sigcontext sf_sc
;
2761 target_sigset_t sf_mask
;
2764 struct target_ucontext
{
2765 target_ulong tuc_flags
;
2766 target_ulong tuc_link
;
2767 target_stack_t tuc_stack
;
2769 struct target_sigcontext tuc_mcontext
;
2770 target_sigset_t tuc_sigmask
;
2773 struct target_rt_sigframe
{
2774 uint32_t rs_ass
[4]; /* argument save space for o32 */
2775 uint32_t rs_code
[2]; /* signal trampoline */
2776 struct target_siginfo rs_info
;
2777 struct target_ucontext rs_uc
;
2780 /* Install trampoline to jump back from signal handler */
2781 static inline int install_sigtramp(unsigned int *tramp
, unsigned int syscall
)
2786 * Set up the return code ...
2788 * li v0, __NR__foo_sigreturn
2792 err
|= __put_user(0x24020000 + syscall
, tramp
+ 0);
2793 err
|= __put_user(0x0000000c , tramp
+ 1);
2798 setup_sigcontext(CPUMIPSState
*regs
, struct target_sigcontext
*sc
)
2803 err
|= __put_user(exception_resume_pc(regs
), &sc
->sc_pc
);
2804 regs
->hflags
&= ~MIPS_HFLAG_BMASK
;
2806 __put_user(0, &sc
->sc_regs
[0]);
2807 for (i
= 1; i
< 32; ++i
) {
2808 err
|= __put_user(regs
->active_tc
.gpr
[i
], &sc
->sc_regs
[i
]);
2811 err
|= __put_user(regs
->active_tc
.HI
[0], &sc
->sc_mdhi
);
2812 err
|= __put_user(regs
->active_tc
.LO
[0], &sc
->sc_mdlo
);
2814 /* Rather than checking for dsp existence, always copy. The storage
2815 would just be garbage otherwise. */
2816 err
|= __put_user(regs
->active_tc
.HI
[1], &sc
->sc_hi1
);
2817 err
|= __put_user(regs
->active_tc
.HI
[2], &sc
->sc_hi2
);
2818 err
|= __put_user(regs
->active_tc
.HI
[3], &sc
->sc_hi3
);
2819 err
|= __put_user(regs
->active_tc
.LO
[1], &sc
->sc_lo1
);
2820 err
|= __put_user(regs
->active_tc
.LO
[2], &sc
->sc_lo2
);
2821 err
|= __put_user(regs
->active_tc
.LO
[3], &sc
->sc_lo3
);
2823 uint32_t dsp
= cpu_rddsp(0x3ff, regs
);
2824 err
|= __put_user(dsp
, &sc
->sc_dsp
);
2827 err
|= __put_user(1, &sc
->sc_used_math
);
2829 for (i
= 0; i
< 32; ++i
) {
2830 err
|= __put_user(regs
->active_fpu
.fpr
[i
].d
, &sc
->sc_fpregs
[i
]);
2837 restore_sigcontext(CPUMIPSState
*regs
, struct target_sigcontext
*sc
)
2842 err
|= __get_user(regs
->CP0_EPC
, &sc
->sc_pc
);
2844 err
|= __get_user(regs
->active_tc
.HI
[0], &sc
->sc_mdhi
);
2845 err
|= __get_user(regs
->active_tc
.LO
[0], &sc
->sc_mdlo
);
2847 for (i
= 1; i
< 32; ++i
) {
2848 err
|= __get_user(regs
->active_tc
.gpr
[i
], &sc
->sc_regs
[i
]);
2851 err
|= __get_user(regs
->active_tc
.HI
[1], &sc
->sc_hi1
);
2852 err
|= __get_user(regs
->active_tc
.HI
[2], &sc
->sc_hi2
);
2853 err
|= __get_user(regs
->active_tc
.HI
[3], &sc
->sc_hi3
);
2854 err
|= __get_user(regs
->active_tc
.LO
[1], &sc
->sc_lo1
);
2855 err
|= __get_user(regs
->active_tc
.LO
[2], &sc
->sc_lo2
);
2856 err
|= __get_user(regs
->active_tc
.LO
[3], &sc
->sc_lo3
);
2859 err
|= __get_user(dsp
, &sc
->sc_dsp
);
2860 cpu_wrdsp(dsp
, 0x3ff, regs
);
2863 for (i
= 0; i
< 32; ++i
) {
2864 err
|= __get_user(regs
->active_fpu
.fpr
[i
].d
, &sc
->sc_fpregs
[i
]);
2871 * Determine which stack to use..
2873 static inline abi_ulong
2874 get_sigframe(struct target_sigaction
*ka
, CPUMIPSState
*regs
, size_t frame_size
)
2878 /* Default to using normal stack */
2879 sp
= regs
->active_tc
.gpr
[29];
2882 * FPU emulator may have its own trampoline active just
2883 * above the user stack, 16-bytes before the next lowest
2884 * 16 byte boundary. Try to avoid trashing it.
2888 /* This is the X/Open sanctioned signal stack switching. */
2889 if ((ka
->sa_flags
& TARGET_SA_ONSTACK
) && (sas_ss_flags (sp
) == 0)) {
2890 sp
= target_sigaltstack_used
.ss_sp
+ target_sigaltstack_used
.ss_size
;
2893 return (sp
- frame_size
) & ~7;
2896 static void mips_set_hflags_isa_mode_from_pc(CPUMIPSState
*env
)
2898 if (env
->insn_flags
& (ASE_MIPS16
| ASE_MICROMIPS
)) {
2899 env
->hflags
&= ~MIPS_HFLAG_M16
;
2900 env
->hflags
|= (env
->active_tc
.PC
& 1) << MIPS_HFLAG_M16_SHIFT
;
2901 env
->active_tc
.PC
&= ~(target_ulong
) 1;
2905 # if defined(TARGET_ABI_MIPSO32)
2906 /* compare linux/arch/mips/kernel/signal.c:setup_frame() */
2907 static void setup_frame(int sig
, struct target_sigaction
* ka
,
2908 target_sigset_t
*set
, CPUMIPSState
*regs
)
2910 struct sigframe
*frame
;
2911 abi_ulong frame_addr
;
2914 frame_addr
= get_sigframe(ka
, regs
, sizeof(*frame
));
2915 if (!lock_user_struct(VERIFY_WRITE
, frame
, frame_addr
, 0))
2918 install_sigtramp(frame
->sf_code
, TARGET_NR_sigreturn
);
2920 if(setup_sigcontext(regs
, &frame
->sf_sc
))
2923 for(i
= 0; i
< TARGET_NSIG_WORDS
; i
++) {
2924 if(__put_user(set
->sig
[i
], &frame
->sf_mask
.sig
[i
]))
2929 * Arguments to signal handler:
2931 * a0 = signal number
2932 * a1 = 0 (should be cause)
2933 * a2 = pointer to struct sigcontext
2935 * $25 and PC point to the signal handler, $29 points to the
2938 regs
->active_tc
.gpr
[ 4] = sig
;
2939 regs
->active_tc
.gpr
[ 5] = 0;
2940 regs
->active_tc
.gpr
[ 6] = frame_addr
+ offsetof(struct sigframe
, sf_sc
);
2941 regs
->active_tc
.gpr
[29] = frame_addr
;
2942 regs
->active_tc
.gpr
[31] = frame_addr
+ offsetof(struct sigframe
, sf_code
);
2943 /* The original kernel code sets CP0_EPC to the handler
2944 * since it returns to userland using eret
2945 * we cannot do this here, and we must set PC directly */
2946 regs
->active_tc
.PC
= regs
->active_tc
.gpr
[25] = ka
->_sa_handler
;
2947 mips_set_hflags_isa_mode_from_pc(regs
);
2948 unlock_user_struct(frame
, frame_addr
, 1);
2952 unlock_user_struct(frame
, frame_addr
, 1);
2953 force_sig(TARGET_SIGSEGV
/*, current*/);
2956 long do_sigreturn(CPUMIPSState
*regs
)
2958 struct sigframe
*frame
;
2959 abi_ulong frame_addr
;
2961 target_sigset_t target_set
;
2964 #if defined(DEBUG_SIGNAL)
2965 fprintf(stderr
, "do_sigreturn\n");
2967 frame_addr
= regs
->active_tc
.gpr
[29];
2968 if (!lock_user_struct(VERIFY_READ
, frame
, frame_addr
, 1))
2971 for(i
= 0; i
< TARGET_NSIG_WORDS
; i
++) {
2972 if(__get_user(target_set
.sig
[i
], &frame
->sf_mask
.sig
[i
]))
2976 target_to_host_sigset_internal(&blocked
, &target_set
);
2977 sigprocmask(SIG_SETMASK
, &blocked
, NULL
);
2979 if (restore_sigcontext(regs
, &frame
->sf_sc
))
2984 * Don't let your children do this ...
2986 __asm__
__volatile__(
2994 regs
->active_tc
.PC
= regs
->CP0_EPC
;
2995 mips_set_hflags_isa_mode_from_pc(regs
);
2996 /* I am not sure this is right, but it seems to work
2997 * maybe a problem with nested signals ? */
2999 return -TARGET_QEMU_ESIGRETURN
;
3002 force_sig(TARGET_SIGSEGV
/*, current*/);
3007 static void setup_rt_frame(int sig
, struct target_sigaction
*ka
,
3008 target_siginfo_t
*info
,
3009 target_sigset_t
*set
, CPUMIPSState
*env
)
3011 struct target_rt_sigframe
*frame
;
3012 abi_ulong frame_addr
;
3015 frame_addr
= get_sigframe(ka
, env
, sizeof(*frame
));
3016 if (!lock_user_struct(VERIFY_WRITE
, frame
, frame_addr
, 0))
3019 install_sigtramp(frame
->rs_code
, TARGET_NR_rt_sigreturn
);
3021 copy_siginfo_to_user(&frame
->rs_info
, info
);
3023 __put_user(0, &frame
->rs_uc
.tuc_flags
);
3024 __put_user(0, &frame
->rs_uc
.tuc_link
);
3025 __put_user(target_sigaltstack_used
.ss_sp
, &frame
->rs_uc
.tuc_stack
.ss_sp
);
3026 __put_user(target_sigaltstack_used
.ss_size
, &frame
->rs_uc
.tuc_stack
.ss_size
);
3027 __put_user(sas_ss_flags(get_sp_from_cpustate(env
)),
3028 &frame
->rs_uc
.tuc_stack
.ss_flags
);
3030 setup_sigcontext(env
, &frame
->rs_uc
.tuc_mcontext
);
3032 for(i
= 0; i
< TARGET_NSIG_WORDS
; i
++) {
3033 __put_user(set
->sig
[i
], &frame
->rs_uc
.tuc_sigmask
.sig
[i
]);
3037 * Arguments to signal handler:
3039 * a0 = signal number
3040 * a1 = pointer to siginfo_t
3041 * a2 = pointer to struct ucontext
3043 * $25 and PC point to the signal handler, $29 points to the
3046 env
->active_tc
.gpr
[ 4] = sig
;
3047 env
->active_tc
.gpr
[ 5] = frame_addr
3048 + offsetof(struct target_rt_sigframe
, rs_info
);
3049 env
->active_tc
.gpr
[ 6] = frame_addr
3050 + offsetof(struct target_rt_sigframe
, rs_uc
);
3051 env
->active_tc
.gpr
[29] = frame_addr
;
3052 env
->active_tc
.gpr
[31] = frame_addr
3053 + offsetof(struct target_rt_sigframe
, rs_code
);
3054 /* The original kernel code sets CP0_EPC to the handler
3055 * since it returns to userland using eret
3056 * we cannot do this here, and we must set PC directly */
3057 env
->active_tc
.PC
= env
->active_tc
.gpr
[25] = ka
->_sa_handler
;
3058 mips_set_hflags_isa_mode_from_pc(env
);
3059 unlock_user_struct(frame
, frame_addr
, 1);
3063 unlock_user_struct(frame
, frame_addr
, 1);
3064 force_sig(TARGET_SIGSEGV
/*, current*/);
3067 long do_rt_sigreturn(CPUMIPSState
*env
)
3069 struct target_rt_sigframe
*frame
;
3070 abi_ulong frame_addr
;
3073 #if defined(DEBUG_SIGNAL)
3074 fprintf(stderr
, "do_rt_sigreturn\n");
3076 frame_addr
= env
->active_tc
.gpr
[29];
3077 if (!lock_user_struct(VERIFY_READ
, frame
, frame_addr
, 1))
3080 target_to_host_sigset(&blocked
, &frame
->rs_uc
.tuc_sigmask
);
3081 sigprocmask(SIG_SETMASK
, &blocked
, NULL
);
3083 if (restore_sigcontext(env
, &frame
->rs_uc
.tuc_mcontext
))
3086 if (do_sigaltstack(frame_addr
+
3087 offsetof(struct target_rt_sigframe
, rs_uc
.tuc_stack
),
3088 0, get_sp_from_cpustate(env
)) == -EFAULT
)
3091 env
->active_tc
.PC
= env
->CP0_EPC
;
3092 mips_set_hflags_isa_mode_from_pc(env
);
3093 /* I am not sure this is right, but it seems to work
3094 * maybe a problem with nested signals ? */
3096 return -TARGET_QEMU_ESIGRETURN
;
3099 force_sig(TARGET_SIGSEGV
/*, current*/);
3103 #elif defined(TARGET_SH4)
3106 * code and data structures from linux kernel:
3107 * include/asm-sh/sigcontext.h
3108 * arch/sh/kernel/signal.c
3111 struct target_sigcontext
{
3112 target_ulong oldmask
;
3115 target_ulong sc_gregs
[16];
3119 target_ulong sc_gbr
;
3120 target_ulong sc_mach
;
3121 target_ulong sc_macl
;
3124 target_ulong sc_fpregs
[16];
3125 target_ulong sc_xfpregs
[16];
3126 unsigned int sc_fpscr
;
3127 unsigned int sc_fpul
;
3128 unsigned int sc_ownedfp
;
3131 struct target_sigframe
3133 struct target_sigcontext sc
;
3134 target_ulong extramask
[TARGET_NSIG_WORDS
-1];
3135 uint16_t retcode
[3];
3139 struct target_ucontext
{
3140 target_ulong tuc_flags
;
3141 struct target_ucontext
*tuc_link
;
3142 target_stack_t tuc_stack
;
3143 struct target_sigcontext tuc_mcontext
;
3144 target_sigset_t tuc_sigmask
; /* mask last for extensibility */
3147 struct target_rt_sigframe
3149 struct target_siginfo info
;
3150 struct target_ucontext uc
;
3151 uint16_t retcode
[3];
3155 #define MOVW(n) (0x9300|((n)-2)) /* Move mem word at PC+n to R3 */
3156 #define TRAP_NOARG 0xc310 /* Syscall w/no args (NR in R3) SH3/4 */
3158 static abi_ulong
get_sigframe(struct target_sigaction
*ka
,
3159 unsigned long sp
, size_t frame_size
)
3161 if ((ka
->sa_flags
& TARGET_SA_ONSTACK
) && (sas_ss_flags(sp
) == 0)) {
3162 sp
= target_sigaltstack_used
.ss_sp
+ target_sigaltstack_used
.ss_size
;
3165 return (sp
- frame_size
) & -8ul;
3168 static int setup_sigcontext(struct target_sigcontext
*sc
,
3169 CPUSH4State
*regs
, unsigned long mask
)
3174 #define COPY(x) err |= __put_user(regs->x, &sc->sc_##x)
3175 COPY(gregs
[0]); COPY(gregs
[1]);
3176 COPY(gregs
[2]); COPY(gregs
[3]);
3177 COPY(gregs
[4]); COPY(gregs
[5]);
3178 COPY(gregs
[6]); COPY(gregs
[7]);
3179 COPY(gregs
[8]); COPY(gregs
[9]);
3180 COPY(gregs
[10]); COPY(gregs
[11]);
3181 COPY(gregs
[12]); COPY(gregs
[13]);
3182 COPY(gregs
[14]); COPY(gregs
[15]);
3183 COPY(gbr
); COPY(mach
);
3184 COPY(macl
); COPY(pr
);
3188 for (i
=0; i
<16; i
++) {
3189 err
|= __put_user(regs
->fregs
[i
], &sc
->sc_fpregs
[i
]);
3191 err
|= __put_user(regs
->fpscr
, &sc
->sc_fpscr
);
3192 err
|= __put_user(regs
->fpul
, &sc
->sc_fpul
);
3194 /* non-iBCS2 extensions.. */
3195 err
|= __put_user(mask
, &sc
->oldmask
);
3200 static int restore_sigcontext(CPUSH4State
*regs
, struct target_sigcontext
*sc
,
3203 unsigned int err
= 0;
3206 #define COPY(x) err |= __get_user(regs->x, &sc->sc_##x)
3208 COPY(gregs
[2]); COPY(gregs
[3]);
3209 COPY(gregs
[4]); COPY(gregs
[5]);
3210 COPY(gregs
[6]); COPY(gregs
[7]);
3211 COPY(gregs
[8]); COPY(gregs
[9]);
3212 COPY(gregs
[10]); COPY(gregs
[11]);
3213 COPY(gregs
[12]); COPY(gregs
[13]);
3214 COPY(gregs
[14]); COPY(gregs
[15]);
3215 COPY(gbr
); COPY(mach
);
3216 COPY(macl
); COPY(pr
);
3220 for (i
=0; i
<16; i
++) {
3221 err
|= __get_user(regs
->fregs
[i
], &sc
->sc_fpregs
[i
]);
3223 err
|= __get_user(regs
->fpscr
, &sc
->sc_fpscr
);
3224 err
|= __get_user(regs
->fpul
, &sc
->sc_fpul
);
3226 regs
->tra
= -1; /* disable syscall checks */
3227 err
|= __get_user(*r0_p
, &sc
->sc_gregs
[0]);
3231 static void setup_frame(int sig
, struct target_sigaction
*ka
,
3232 target_sigset_t
*set
, CPUSH4State
*regs
)
3234 struct target_sigframe
*frame
;
3235 abi_ulong frame_addr
;
3240 frame_addr
= get_sigframe(ka
, regs
->gregs
[15], sizeof(*frame
));
3241 if (!lock_user_struct(VERIFY_WRITE
, frame
, frame_addr
, 0))
3244 signal
= current_exec_domain_sig(sig
);
3246 err
|= setup_sigcontext(&frame
->sc
, regs
, set
->sig
[0]);
3248 for (i
= 0; i
< TARGET_NSIG_WORDS
- 1; i
++) {
3249 err
|= __put_user(set
->sig
[i
+ 1], &frame
->extramask
[i
]);
3252 /* Set up to return from userspace. If provided, use a stub
3253 already in userspace. */
3254 if (ka
->sa_flags
& TARGET_SA_RESTORER
) {
3255 regs
->pr
= (unsigned long) ka
->sa_restorer
;
3257 /* Generate return code (system call to sigreturn) */
3258 err
|= __put_user(MOVW(2), &frame
->retcode
[0]);
3259 err
|= __put_user(TRAP_NOARG
, &frame
->retcode
[1]);
3260 err
|= __put_user((TARGET_NR_sigreturn
), &frame
->retcode
[2]);
3261 regs
->pr
= (unsigned long) frame
->retcode
;
3267 /* Set up registers for signal handler */
3268 regs
->gregs
[15] = frame_addr
;
3269 regs
->gregs
[4] = signal
; /* Arg for signal handler */
3271 regs
->gregs
[6] = frame_addr
+= offsetof(typeof(*frame
), sc
);
3272 regs
->pc
= (unsigned long) ka
->_sa_handler
;
3274 unlock_user_struct(frame
, frame_addr
, 1);
3278 unlock_user_struct(frame
, frame_addr
, 1);
3279 force_sig(TARGET_SIGSEGV
);
3282 static void setup_rt_frame(int sig
, struct target_sigaction
*ka
,
3283 target_siginfo_t
*info
,
3284 target_sigset_t
*set
, CPUSH4State
*regs
)
3286 struct target_rt_sigframe
*frame
;
3287 abi_ulong frame_addr
;
3292 frame_addr
= get_sigframe(ka
, regs
->gregs
[15], sizeof(*frame
));
3293 if (!lock_user_struct(VERIFY_WRITE
, frame
, frame_addr
, 0))
3296 signal
= current_exec_domain_sig(sig
);
3298 err
|= copy_siginfo_to_user(&frame
->info
, info
);
3300 /* Create the ucontext. */
3301 err
|= __put_user(0, &frame
->uc
.tuc_flags
);
3302 err
|= __put_user(0, (unsigned long *)&frame
->uc
.tuc_link
);
3303 err
|= __put_user((unsigned long)target_sigaltstack_used
.ss_sp
,
3304 &frame
->uc
.tuc_stack
.ss_sp
);
3305 err
|= __put_user(sas_ss_flags(regs
->gregs
[15]),
3306 &frame
->uc
.tuc_stack
.ss_flags
);
3307 err
|= __put_user(target_sigaltstack_used
.ss_size
,
3308 &frame
->uc
.tuc_stack
.ss_size
);
3309 err
|= setup_sigcontext(&frame
->uc
.tuc_mcontext
,
3311 for(i
= 0; i
< TARGET_NSIG_WORDS
; i
++) {
3312 err
|= __put_user(set
->sig
[i
], &frame
->uc
.tuc_sigmask
.sig
[i
]);
3315 /* Set up to return from userspace. If provided, use a stub
3316 already in userspace. */
3317 if (ka
->sa_flags
& TARGET_SA_RESTORER
) {
3318 regs
->pr
= (unsigned long) ka
->sa_restorer
;
3320 /* Generate return code (system call to sigreturn) */
3321 err
|= __put_user(MOVW(2), &frame
->retcode
[0]);
3322 err
|= __put_user(TRAP_NOARG
, &frame
->retcode
[1]);
3323 err
|= __put_user((TARGET_NR_rt_sigreturn
), &frame
->retcode
[2]);
3324 regs
->pr
= (unsigned long) frame
->retcode
;
3330 /* Set up registers for signal handler */
3331 regs
->gregs
[15] = frame_addr
;
3332 regs
->gregs
[4] = signal
; /* Arg for signal handler */
3333 regs
->gregs
[5] = frame_addr
+ offsetof(typeof(*frame
), info
);
3334 regs
->gregs
[6] = frame_addr
+ offsetof(typeof(*frame
), uc
);
3335 regs
->pc
= (unsigned long) ka
->_sa_handler
;
3337 unlock_user_struct(frame
, frame_addr
, 1);
3341 unlock_user_struct(frame
, frame_addr
, 1);
3342 force_sig(TARGET_SIGSEGV
);
3345 long do_sigreturn(CPUSH4State
*regs
)
3347 struct target_sigframe
*frame
;
3348 abi_ulong frame_addr
;
3350 target_sigset_t target_set
;
3355 #if defined(DEBUG_SIGNAL)
3356 fprintf(stderr
, "do_sigreturn\n");
3358 frame_addr
= regs
->gregs
[15];
3359 if (!lock_user_struct(VERIFY_READ
, frame
, frame_addr
, 1))
3362 err
|= __get_user(target_set
.sig
[0], &frame
->sc
.oldmask
);
3363 for(i
= 1; i
< TARGET_NSIG_WORDS
; i
++) {
3364 err
|= (__get_user(target_set
.sig
[i
], &frame
->extramask
[i
- 1]));
3370 target_to_host_sigset_internal(&blocked
, &target_set
);
3371 sigprocmask(SIG_SETMASK
, &blocked
, NULL
);
3373 if (restore_sigcontext(regs
, &frame
->sc
, &r0
))
3376 unlock_user_struct(frame
, frame_addr
, 0);
3380 unlock_user_struct(frame
, frame_addr
, 0);
3381 force_sig(TARGET_SIGSEGV
);
3385 long do_rt_sigreturn(CPUSH4State
*regs
)
3387 struct target_rt_sigframe
*frame
;
3388 abi_ulong frame_addr
;
3392 #if defined(DEBUG_SIGNAL)
3393 fprintf(stderr
, "do_rt_sigreturn\n");
3395 frame_addr
= regs
->gregs
[15];
3396 if (!lock_user_struct(VERIFY_READ
, frame
, frame_addr
, 1))
3399 target_to_host_sigset(&blocked
, &frame
->uc
.tuc_sigmask
);
3400 sigprocmask(SIG_SETMASK
, &blocked
, NULL
);
3402 if (restore_sigcontext(regs
, &frame
->uc
.tuc_mcontext
, &r0
))
3405 if (do_sigaltstack(frame_addr
+
3406 offsetof(struct target_rt_sigframe
, uc
.tuc_stack
),
3407 0, get_sp_from_cpustate(regs
)) == -EFAULT
)
3410 unlock_user_struct(frame
, frame_addr
, 0);
3414 unlock_user_struct(frame
, frame_addr
, 0);
3415 force_sig(TARGET_SIGSEGV
);
3418 #elif defined(TARGET_MICROBLAZE)
3420 struct target_sigcontext
{
3421 struct target_pt_regs regs
; /* needs to be first */
3425 struct target_stack_t
{
3428 unsigned int ss_size
;
3431 struct target_ucontext
{
3432 abi_ulong tuc_flags
;
3434 struct target_stack_t tuc_stack
;
3435 struct target_sigcontext tuc_mcontext
;
3436 uint32_t tuc_extramask
[TARGET_NSIG_WORDS
- 1];
3439 /* Signal frames. */
3440 struct target_signal_frame
{
3441 struct target_ucontext uc
;
3442 uint32_t extramask
[TARGET_NSIG_WORDS
- 1];
3446 struct rt_signal_frame
{
3452 static void setup_sigcontext(struct target_sigcontext
*sc
, CPUMBState
*env
)
3454 __put_user(env
->regs
[0], &sc
->regs
.r0
);
3455 __put_user(env
->regs
[1], &sc
->regs
.r1
);
3456 __put_user(env
->regs
[2], &sc
->regs
.r2
);
3457 __put_user(env
->regs
[3], &sc
->regs
.r3
);
3458 __put_user(env
->regs
[4], &sc
->regs
.r4
);
3459 __put_user(env
->regs
[5], &sc
->regs
.r5
);
3460 __put_user(env
->regs
[6], &sc
->regs
.r6
);
3461 __put_user(env
->regs
[7], &sc
->regs
.r7
);
3462 __put_user(env
->regs
[8], &sc
->regs
.r8
);
3463 __put_user(env
->regs
[9], &sc
->regs
.r9
);
3464 __put_user(env
->regs
[10], &sc
->regs
.r10
);
3465 __put_user(env
->regs
[11], &sc
->regs
.r11
);
3466 __put_user(env
->regs
[12], &sc
->regs
.r12
);
3467 __put_user(env
->regs
[13], &sc
->regs
.r13
);
3468 __put_user(env
->regs
[14], &sc
->regs
.r14
);
3469 __put_user(env
->regs
[15], &sc
->regs
.r15
);
3470 __put_user(env
->regs
[16], &sc
->regs
.r16
);
3471 __put_user(env
->regs
[17], &sc
->regs
.r17
);
3472 __put_user(env
->regs
[18], &sc
->regs
.r18
);
3473 __put_user(env
->regs
[19], &sc
->regs
.r19
);
3474 __put_user(env
->regs
[20], &sc
->regs
.r20
);
3475 __put_user(env
->regs
[21], &sc
->regs
.r21
);
3476 __put_user(env
->regs
[22], &sc
->regs
.r22
);
3477 __put_user(env
->regs
[23], &sc
->regs
.r23
);
3478 __put_user(env
->regs
[24], &sc
->regs
.r24
);
3479 __put_user(env
->regs
[25], &sc
->regs
.r25
);
3480 __put_user(env
->regs
[26], &sc
->regs
.r26
);
3481 __put_user(env
->regs
[27], &sc
->regs
.r27
);
3482 __put_user(env
->regs
[28], &sc
->regs
.r28
);
3483 __put_user(env
->regs
[29], &sc
->regs
.r29
);
3484 __put_user(env
->regs
[30], &sc
->regs
.r30
);
3485 __put_user(env
->regs
[31], &sc
->regs
.r31
);
3486 __put_user(env
->sregs
[SR_PC
], &sc
->regs
.pc
);
3489 static void restore_sigcontext(struct target_sigcontext
*sc
, CPUMBState
*env
)
3491 __get_user(env
->regs
[0], &sc
->regs
.r0
);
3492 __get_user(env
->regs
[1], &sc
->regs
.r1
);
3493 __get_user(env
->regs
[2], &sc
->regs
.r2
);
3494 __get_user(env
->regs
[3], &sc
->regs
.r3
);
3495 __get_user(env
->regs
[4], &sc
->regs
.r4
);
3496 __get_user(env
->regs
[5], &sc
->regs
.r5
);
3497 __get_user(env
->regs
[6], &sc
->regs
.r6
);
3498 __get_user(env
->regs
[7], &sc
->regs
.r7
);
3499 __get_user(env
->regs
[8], &sc
->regs
.r8
);
3500 __get_user(env
->regs
[9], &sc
->regs
.r9
);
3501 __get_user(env
->regs
[10], &sc
->regs
.r10
);
3502 __get_user(env
->regs
[11], &sc
->regs
.r11
);
3503 __get_user(env
->regs
[12], &sc
->regs
.r12
);
3504 __get_user(env
->regs
[13], &sc
->regs
.r13
);
3505 __get_user(env
->regs
[14], &sc
->regs
.r14
);
3506 __get_user(env
->regs
[15], &sc
->regs
.r15
);
3507 __get_user(env
->regs
[16], &sc
->regs
.r16
);
3508 __get_user(env
->regs
[17], &sc
->regs
.r17
);
3509 __get_user(env
->regs
[18], &sc
->regs
.r18
);
3510 __get_user(env
->regs
[19], &sc
->regs
.r19
);
3511 __get_user(env
->regs
[20], &sc
->regs
.r20
);
3512 __get_user(env
->regs
[21], &sc
->regs
.r21
);
3513 __get_user(env
->regs
[22], &sc
->regs
.r22
);
3514 __get_user(env
->regs
[23], &sc
->regs
.r23
);
3515 __get_user(env
->regs
[24], &sc
->regs
.r24
);
3516 __get_user(env
->regs
[25], &sc
->regs
.r25
);
3517 __get_user(env
->regs
[26], &sc
->regs
.r26
);
3518 __get_user(env
->regs
[27], &sc
->regs
.r27
);
3519 __get_user(env
->regs
[28], &sc
->regs
.r28
);
3520 __get_user(env
->regs
[29], &sc
->regs
.r29
);
3521 __get_user(env
->regs
[30], &sc
->regs
.r30
);
3522 __get_user(env
->regs
[31], &sc
->regs
.r31
);
3523 __get_user(env
->sregs
[SR_PC
], &sc
->regs
.pc
);
3526 static abi_ulong
get_sigframe(struct target_sigaction
*ka
,
3527 CPUMBState
*env
, int frame_size
)
3529 abi_ulong sp
= env
->regs
[1];
3531 if ((ka
->sa_flags
& SA_ONSTACK
) != 0 && !on_sig_stack(sp
))
3532 sp
= target_sigaltstack_used
.ss_sp
+ target_sigaltstack_used
.ss_size
;
3534 return ((sp
- frame_size
) & -8UL);
3537 static void setup_frame(int sig
, struct target_sigaction
*ka
,
3538 target_sigset_t
*set
, CPUMBState
*env
)
3540 struct target_signal_frame
*frame
;
3541 abi_ulong frame_addr
;
3545 frame_addr
= get_sigframe(ka
, env
, sizeof *frame
);
3546 if (!lock_user_struct(VERIFY_WRITE
, frame
, frame_addr
, 0))
3549 /* Save the mask. */
3550 err
|= __put_user(set
->sig
[0], &frame
->uc
.tuc_mcontext
.oldmask
);
3554 for(i
= 1; i
< TARGET_NSIG_WORDS
; i
++) {
3555 if (__put_user(set
->sig
[i
], &frame
->extramask
[i
- 1]))
3559 setup_sigcontext(&frame
->uc
.tuc_mcontext
, env
);
3561 /* Set up to return from userspace. If provided, use a stub
3562 already in userspace. */
3563 /* minus 8 is offset to cater for "rtsd r15,8" offset */
3564 if (ka
->sa_flags
& TARGET_SA_RESTORER
) {
3565 env
->regs
[15] = ((unsigned long)ka
->sa_restorer
)-8;
3568 /* Note, these encodings are _big endian_! */
3569 /* addi r12, r0, __NR_sigreturn */
3570 t
= 0x31800000UL
| TARGET_NR_sigreturn
;
3571 err
|= __put_user(t
, frame
->tramp
+ 0);
3574 err
|= __put_user(t
, frame
->tramp
+ 1);
3576 /* Return from sighandler will jump to the tramp.
3577 Negative 8 offset because return is rtsd r15, 8 */
3578 env
->regs
[15] = ((unsigned long)frame
->tramp
) - 8;
3584 /* Set up registers for signal handler */
3585 env
->regs
[1] = frame_addr
;
3586 /* Signal handler args: */
3587 env
->regs
[5] = sig
; /* Arg 0: signum */
3589 /* arg 1: sigcontext */
3590 env
->regs
[7] = frame_addr
+= offsetof(typeof(*frame
), uc
);
3592 /* Offset of 4 to handle microblaze rtid r14, 0 */
3593 env
->sregs
[SR_PC
] = (unsigned long)ka
->_sa_handler
;
3595 unlock_user_struct(frame
, frame_addr
, 1);
3598 unlock_user_struct(frame
, frame_addr
, 1);
3599 force_sig(TARGET_SIGSEGV
);
3602 static void setup_rt_frame(int sig
, struct target_sigaction
*ka
,
3603 target_siginfo_t
*info
,
3604 target_sigset_t
*set
, CPUMBState
*env
)
3606 fprintf(stderr
, "Microblaze setup_rt_frame: not implemented\n");
3609 long do_sigreturn(CPUMBState
*env
)
3611 struct target_signal_frame
*frame
;
3612 abi_ulong frame_addr
;
3613 target_sigset_t target_set
;
3617 frame_addr
= env
->regs
[R_SP
];
3618 /* Make sure the guest isn't playing games. */
3619 if (!lock_user_struct(VERIFY_WRITE
, frame
, frame_addr
, 1))
3622 /* Restore blocked signals */
3623 if (__get_user(target_set
.sig
[0], &frame
->uc
.tuc_mcontext
.oldmask
))
3625 for(i
= 1; i
< TARGET_NSIG_WORDS
; i
++) {
3626 if (__get_user(target_set
.sig
[i
], &frame
->extramask
[i
- 1]))
3629 target_to_host_sigset_internal(&set
, &target_set
);
3630 sigprocmask(SIG_SETMASK
, &set
, NULL
);
3632 restore_sigcontext(&frame
->uc
.tuc_mcontext
, env
);
3633 /* We got here through a sigreturn syscall, our path back is via an
3634 rtb insn so setup r14 for that. */
3635 env
->regs
[14] = env
->sregs
[SR_PC
];
3637 unlock_user_struct(frame
, frame_addr
, 0);
3638 return env
->regs
[10];
3640 unlock_user_struct(frame
, frame_addr
, 0);
3641 force_sig(TARGET_SIGSEGV
);
3644 long do_rt_sigreturn(CPUMBState
*env
)
3646 fprintf(stderr
, "Microblaze do_rt_sigreturn: not implemented\n");
3647 return -TARGET_ENOSYS
;
3650 #elif defined(TARGET_CRIS)
3652 struct target_sigcontext
{
3653 struct target_pt_regs regs
; /* needs to be first */
3655 uint32_t usp
; /* usp before stacking this gunk on it */
3658 /* Signal frames. */
3659 struct target_signal_frame
{
3660 struct target_sigcontext sc
;
3661 uint32_t extramask
[TARGET_NSIG_WORDS
- 1];
3662 uint8_t retcode
[8]; /* Trampoline code. */
3665 struct rt_signal_frame
{
3670 uint8_t retcode
[8]; /* Trampoline code. */
3673 static void setup_sigcontext(struct target_sigcontext
*sc
, CPUCRISState
*env
)
3675 __put_user(env
->regs
[0], &sc
->regs
.r0
);
3676 __put_user(env
->regs
[1], &sc
->regs
.r1
);
3677 __put_user(env
->regs
[2], &sc
->regs
.r2
);
3678 __put_user(env
->regs
[3], &sc
->regs
.r3
);
3679 __put_user(env
->regs
[4], &sc
->regs
.r4
);
3680 __put_user(env
->regs
[5], &sc
->regs
.r5
);
3681 __put_user(env
->regs
[6], &sc
->regs
.r6
);
3682 __put_user(env
->regs
[7], &sc
->regs
.r7
);
3683 __put_user(env
->regs
[8], &sc
->regs
.r8
);
3684 __put_user(env
->regs
[9], &sc
->regs
.r9
);
3685 __put_user(env
->regs
[10], &sc
->regs
.r10
);
3686 __put_user(env
->regs
[11], &sc
->regs
.r11
);
3687 __put_user(env
->regs
[12], &sc
->regs
.r12
);
3688 __put_user(env
->regs
[13], &sc
->regs
.r13
);
3689 __put_user(env
->regs
[14], &sc
->usp
);
3690 __put_user(env
->regs
[15], &sc
->regs
.acr
);
3691 __put_user(env
->pregs
[PR_MOF
], &sc
->regs
.mof
);
3692 __put_user(env
->pregs
[PR_SRP
], &sc
->regs
.srp
);
3693 __put_user(env
->pc
, &sc
->regs
.erp
);
3696 static void restore_sigcontext(struct target_sigcontext
*sc
, CPUCRISState
*env
)
3698 __get_user(env
->regs
[0], &sc
->regs
.r0
);
3699 __get_user(env
->regs
[1], &sc
->regs
.r1
);
3700 __get_user(env
->regs
[2], &sc
->regs
.r2
);
3701 __get_user(env
->regs
[3], &sc
->regs
.r3
);
3702 __get_user(env
->regs
[4], &sc
->regs
.r4
);
3703 __get_user(env
->regs
[5], &sc
->regs
.r5
);
3704 __get_user(env
->regs
[6], &sc
->regs
.r6
);
3705 __get_user(env
->regs
[7], &sc
->regs
.r7
);
3706 __get_user(env
->regs
[8], &sc
->regs
.r8
);
3707 __get_user(env
->regs
[9], &sc
->regs
.r9
);
3708 __get_user(env
->regs
[10], &sc
->regs
.r10
);
3709 __get_user(env
->regs
[11], &sc
->regs
.r11
);
3710 __get_user(env
->regs
[12], &sc
->regs
.r12
);
3711 __get_user(env
->regs
[13], &sc
->regs
.r13
);
3712 __get_user(env
->regs
[14], &sc
->usp
);
3713 __get_user(env
->regs
[15], &sc
->regs
.acr
);
3714 __get_user(env
->pregs
[PR_MOF
], &sc
->regs
.mof
);
3715 __get_user(env
->pregs
[PR_SRP
], &sc
->regs
.srp
);
3716 __get_user(env
->pc
, &sc
->regs
.erp
);
3719 static abi_ulong
get_sigframe(CPUCRISState
*env
, int framesize
)
3722 /* Align the stack downwards to 4. */
3723 sp
= (env
->regs
[R_SP
] & ~3);
3724 return sp
- framesize
;
3727 static void setup_frame(int sig
, struct target_sigaction
*ka
,
3728 target_sigset_t
*set
, CPUCRISState
*env
)
3730 struct target_signal_frame
*frame
;
3731 abi_ulong frame_addr
;
3735 frame_addr
= get_sigframe(env
, sizeof *frame
);
3736 if (!lock_user_struct(VERIFY_WRITE
, frame
, frame_addr
, 0))
3740 * The CRIS signal return trampoline. A real linux/CRIS kernel doesn't
3741 * use this trampoline anymore but it sets it up for GDB.
3742 * In QEMU, using the trampoline simplifies things a bit so we use it.
3744 * This is movu.w __NR_sigreturn, r9; break 13;
3746 err
|= __put_user(0x9c5f, frame
->retcode
+0);
3747 err
|= __put_user(TARGET_NR_sigreturn
,
3749 err
|= __put_user(0xe93d, frame
->retcode
+4);
3751 /* Save the mask. */
3752 err
|= __put_user(set
->sig
[0], &frame
->sc
.oldmask
);
3756 for(i
= 1; i
< TARGET_NSIG_WORDS
; i
++) {
3757 if (__put_user(set
->sig
[i
], &frame
->extramask
[i
- 1]))
3761 setup_sigcontext(&frame
->sc
, env
);
3763 /* Move the stack and setup the arguments for the handler. */
3764 env
->regs
[R_SP
] = frame_addr
;
3765 env
->regs
[10] = sig
;
3766 env
->pc
= (unsigned long) ka
->_sa_handler
;
3767 /* Link SRP so the guest returns through the trampoline. */
3768 env
->pregs
[PR_SRP
] = frame_addr
+ offsetof(typeof(*frame
), retcode
);
3770 unlock_user_struct(frame
, frame_addr
, 1);
3773 unlock_user_struct(frame
, frame_addr
, 1);
3774 force_sig(TARGET_SIGSEGV
);
3777 static void setup_rt_frame(int sig
, struct target_sigaction
*ka
,
3778 target_siginfo_t
*info
,
3779 target_sigset_t
*set
, CPUCRISState
*env
)
3781 fprintf(stderr
, "CRIS setup_rt_frame: not implemented\n");
3784 long do_sigreturn(CPUCRISState
*env
)
3786 struct target_signal_frame
*frame
;
3787 abi_ulong frame_addr
;
3788 target_sigset_t target_set
;
3792 frame_addr
= env
->regs
[R_SP
];
3793 /* Make sure the guest isn't playing games. */
3794 if (!lock_user_struct(VERIFY_WRITE
, frame
, frame_addr
, 1))
3797 /* Restore blocked signals */
3798 if (__get_user(target_set
.sig
[0], &frame
->sc
.oldmask
))
3800 for(i
= 1; i
< TARGET_NSIG_WORDS
; i
++) {
3801 if (__get_user(target_set
.sig
[i
], &frame
->extramask
[i
- 1]))
3804 target_to_host_sigset_internal(&set
, &target_set
);
3805 sigprocmask(SIG_SETMASK
, &set
, NULL
);
3807 restore_sigcontext(&frame
->sc
, env
);
3808 unlock_user_struct(frame
, frame_addr
, 0);
3809 return env
->regs
[10];
3811 unlock_user_struct(frame
, frame_addr
, 0);
3812 force_sig(TARGET_SIGSEGV
);
3815 long do_rt_sigreturn(CPUCRISState
*env
)
3817 fprintf(stderr
, "CRIS do_rt_sigreturn: not implemented\n");
3818 return -TARGET_ENOSYS
;
3821 #elif defined(TARGET_OPENRISC)
3823 struct target_sigcontext
{
3824 struct target_pt_regs regs
;
3829 struct target_ucontext
{
3830 abi_ulong tuc_flags
;
3832 target_stack_t tuc_stack
;
3833 struct target_sigcontext tuc_mcontext
;
3834 target_sigset_t tuc_sigmask
; /* mask last for extensibility */
3837 struct target_rt_sigframe
{
3840 struct target_siginfo info
;
3841 struct target_sigcontext sc
;
3842 struct target_ucontext uc
;
3843 unsigned char retcode
[16]; /* trampoline code */
3846 /* This is the asm-generic/ucontext.h version */
3848 static int restore_sigcontext(CPUOpenRISCState
*regs
,
3849 struct target_sigcontext
*sc
)
3851 unsigned int err
= 0;
3852 unsigned long old_usp
;
3854 /* Alwys make any pending restarted system call return -EINTR */
3855 current_thread_info()->restart_block
.fn
= do_no_restart_syscall
;
3857 /* restore the regs from &sc->regs (same as sc, since regs is first)
3858 * (sc is already checked for VERIFY_READ since the sigframe was
3859 * checked in sys_sigreturn previously)
3862 if (copy_from_user(regs
, &sc
, sizeof(struct target_pt_regs
))) {
3866 /* make sure the U-flag is set so user-mode cannot fool us */
3870 /* restore the old USP as it was before we stacked the sc etc.
3871 * (we cannot just pop the sigcontext since we aligned the sp and
3872 * stuff after pushing it)
3875 err
|= __get_user(old_usp
, &sc
->usp
);
3876 phx_signal("old_usp 0x%lx", old_usp
);
3878 __PHX__ REALLY
/* ??? */
3880 regs
->gpr
[1] = old_usp
;
3882 /* TODO: the other ports use regs->orig_XX to disable syscall checks
3883 * after this completes, but we don't use that mechanism. maybe we can
3894 /* Set up a signal frame. */
3896 static int setup_sigcontext(struct target_sigcontext
*sc
,
3897 CPUOpenRISCState
*regs
,
3901 unsigned long usp
= regs
->gpr
[1];
3903 /* copy the regs. they are first in sc so we can use sc directly */
3905 /*err |= copy_to_user(&sc, regs, sizeof(struct target_pt_regs));*/
3907 /* Set the frametype to CRIS_FRAME_NORMAL for the execution of
3908 the signal handler. The frametype will be restored to its previous
3909 value in restore_sigcontext. */
3910 /*regs->frametype = CRIS_FRAME_NORMAL;*/
3912 /* then some other stuff */
3913 err
|= __put_user(mask
, &sc
->oldmask
);
3914 err
|= __put_user(usp
, &sc
->usp
); return err
;
3917 static inline unsigned long align_sigframe(unsigned long sp
)
3924 static inline abi_ulong
get_sigframe(struct target_sigaction
*ka
,
3925 CPUOpenRISCState
*regs
,
3928 unsigned long sp
= regs
->gpr
[1];
3929 int onsigstack
= on_sig_stack(sp
);
3932 /* This is the X/Open sanctioned signal stack switching. */
3933 if ((ka
->sa_flags
& SA_ONSTACK
) != 0 && !onsigstack
) {
3934 sp
= target_sigaltstack_used
.ss_sp
+ target_sigaltstack_used
.ss_size
;
3937 sp
= align_sigframe(sp
- frame_size
);
3940 * If we are on the alternate signal stack and would overflow it, don't.
3941 * Return an always-bogus address instead so we will die with SIGSEGV.
3944 if (onsigstack
&& !likely(on_sig_stack(sp
))) {
3951 static void setup_frame(int sig
, struct target_sigaction
*ka
,
3952 target_sigset_t
*set
, CPUOpenRISCState
*env
)
3954 qemu_log("Not implement.\n");
3957 static void setup_rt_frame(int sig
, struct target_sigaction
*ka
,
3958 target_siginfo_t
*info
,
3959 target_sigset_t
*set
, CPUOpenRISCState
*env
)
3962 abi_ulong frame_addr
;
3963 unsigned long return_ip
;
3964 struct target_rt_sigframe
*frame
;
3965 abi_ulong info_addr
, uc_addr
;
3967 frame_addr
= get_sigframe(ka
, env
, sizeof *frame
);
3969 frame_addr
= get_sigframe(ka
, env
, sizeof(*frame
));
3970 if (!lock_user_struct(VERIFY_WRITE
, frame
, frame_addr
, 0)) {
3974 info_addr
= frame_addr
+ offsetof(struct target_rt_sigframe
, info
);
3975 err
|= __put_user(info_addr
, &frame
->pinfo
);
3976 uc_addr
= frame_addr
+ offsetof(struct target_rt_sigframe
, uc
);
3977 err
|= __put_user(uc_addr
, &frame
->puc
);
3979 if (ka
->sa_flags
& SA_SIGINFO
) {
3980 err
|= copy_siginfo_to_user(&frame
->info
, info
);
3986 /*err |= __clear_user(&frame->uc, offsetof(struct ucontext, uc_mcontext));*/
3987 err
|= __put_user(0, &frame
->uc
.tuc_flags
);
3988 err
|= __put_user(0, &frame
->uc
.tuc_link
);
3989 err
|= __put_user(target_sigaltstack_used
.ss_sp
,
3990 &frame
->uc
.tuc_stack
.ss_sp
);
3991 err
|= __put_user(sas_ss_flags(env
->gpr
[1]), &frame
->uc
.tuc_stack
.ss_flags
);
3992 err
|= __put_user(target_sigaltstack_used
.ss_size
,
3993 &frame
->uc
.tuc_stack
.ss_size
);
3994 err
|= setup_sigcontext(&frame
->sc
, env
, set
->sig
[0]);
3996 /*err |= copy_to_user(frame->uc.tuc_sigmask, set, sizeof(*set));*/
4002 /* trampoline - the desired return ip is the retcode itself */
4003 return_ip
= (unsigned long)&frame
->retcode
;
4004 /* This is l.ori r11,r0,__NR_sigreturn, l.sys 1 */
4005 err
|= __put_user(0xa960, (short *)(frame
->retcode
+ 0));
4006 err
|= __put_user(TARGET_NR_rt_sigreturn
, (short *)(frame
->retcode
+ 2));
4007 err
|= __put_user(0x20000001, (unsigned long *)(frame
->retcode
+ 4));
4008 err
|= __put_user(0x15000000, (unsigned long *)(frame
->retcode
+ 8));
4014 /* TODO what is the current->exec_domain stuff and invmap ? */
4016 /* Set up registers for signal handler */
4017 env
->pc
= (unsigned long)ka
->_sa_handler
; /* what we enter NOW */
4018 env
->gpr
[9] = (unsigned long)return_ip
; /* what we enter LATER */
4019 env
->gpr
[3] = (unsigned long)sig
; /* arg 1: signo */
4020 env
->gpr
[4] = (unsigned long)&frame
->info
; /* arg 2: (siginfo_t*) */
4021 env
->gpr
[5] = (unsigned long)&frame
->uc
; /* arg 3: ucontext */
4023 /* actually move the usp to reflect the stacked frame */
4024 env
->gpr
[1] = (unsigned long)frame
;
4029 unlock_user_struct(frame
, frame_addr
, 1);
4030 if (sig
== TARGET_SIGSEGV
) {
4031 ka
->_sa_handler
= TARGET_SIG_DFL
;
4033 force_sig(TARGET_SIGSEGV
);
4036 long do_sigreturn(CPUOpenRISCState
*env
)
4039 qemu_log("do_sigreturn: not implemented\n");
4040 return -TARGET_ENOSYS
;
4043 long do_rt_sigreturn(CPUOpenRISCState
*env
)
4045 qemu_log("do_rt_sigreturn: not implemented\n");
4046 return -TARGET_ENOSYS
;
4048 /* TARGET_OPENRISC */
4050 #elif defined(TARGET_S390X)
4052 #define __NUM_GPRS 16
4053 #define __NUM_FPRS 16
4054 #define __NUM_ACRS 16
4056 #define S390_SYSCALL_SIZE 2
4057 #define __SIGNAL_FRAMESIZE 160 /* FIXME: 31-bit mode -> 96 */
4059 #define _SIGCONTEXT_NSIG 64
4060 #define _SIGCONTEXT_NSIG_BPW 64 /* FIXME: 31-bit mode -> 32 */
4061 #define _SIGCONTEXT_NSIG_WORDS (_SIGCONTEXT_NSIG / _SIGCONTEXT_NSIG_BPW)
4062 #define _SIGMASK_COPY_SIZE (sizeof(unsigned long)*_SIGCONTEXT_NSIG_WORDS)
4063 #define PSW_ADDR_AMODE 0x0000000000000000UL /* 0x80000000UL for 31-bit */
4064 #define S390_SYSCALL_OPCODE ((uint16_t)0x0a00)
4068 target_ulong gprs
[__NUM_GPRS
];
4069 unsigned int acrs
[__NUM_ACRS
];
4070 } target_s390_regs_common
;
4074 double fprs
[__NUM_FPRS
];
4075 } target_s390_fp_regs
;
4078 target_s390_regs_common regs
;
4079 target_s390_fp_regs fpregs
;
4082 struct target_sigcontext
{
4083 target_ulong oldmask
[_SIGCONTEXT_NSIG_WORDS
];
4084 target_sigregs
*sregs
;
4088 uint8_t callee_used_stack
[__SIGNAL_FRAMESIZE
];
4089 struct target_sigcontext sc
;
4090 target_sigregs sregs
;
4092 uint8_t retcode
[S390_SYSCALL_SIZE
];
4095 struct target_ucontext
{
4096 target_ulong tuc_flags
;
4097 struct target_ucontext
*tuc_link
;
4098 target_stack_t tuc_stack
;
4099 target_sigregs tuc_mcontext
;
4100 target_sigset_t tuc_sigmask
; /* mask last for extensibility */
4104 uint8_t callee_used_stack
[__SIGNAL_FRAMESIZE
];
4105 uint8_t retcode
[S390_SYSCALL_SIZE
];
4106 struct target_siginfo info
;
4107 struct target_ucontext uc
;
4110 static inline abi_ulong
4111 get_sigframe(struct target_sigaction
*ka
, CPUS390XState
*env
, size_t frame_size
)
4115 /* Default to using normal stack */
4118 /* This is the X/Open sanctioned signal stack switching. */
4119 if (ka
->sa_flags
& TARGET_SA_ONSTACK
) {
4120 if (!sas_ss_flags(sp
)) {
4121 sp
= target_sigaltstack_used
.ss_sp
+
4122 target_sigaltstack_used
.ss_size
;
4126 /* This is the legacy signal stack switching. */
4127 else if (/* FIXME !user_mode(regs) */ 0 &&
4128 !(ka
->sa_flags
& TARGET_SA_RESTORER
) &&
4130 sp
= (abi_ulong
) ka
->sa_restorer
;
4133 return (sp
- frame_size
) & -8ul;
4136 static void save_sigregs(CPUS390XState
*env
, target_sigregs
*sregs
)
4139 //save_access_regs(current->thread.acrs); FIXME
4141 /* Copy a 'clean' PSW mask to the user to avoid leaking
4142 information about whether PER is currently on. */
4143 __put_user(env
->psw
.mask
, &sregs
->regs
.psw
.mask
);
4144 __put_user(env
->psw
.addr
, &sregs
->regs
.psw
.addr
);
4145 for (i
= 0; i
< 16; i
++) {
4146 __put_user(env
->regs
[i
], &sregs
->regs
.gprs
[i
]);
4148 for (i
= 0; i
< 16; i
++) {
4149 __put_user(env
->aregs
[i
], &sregs
->regs
.acrs
[i
]);
4152 * We have to store the fp registers to current->thread.fp_regs
4153 * to merge them with the emulated registers.
4155 //save_fp_regs(¤t->thread.fp_regs); FIXME
4156 for (i
= 0; i
< 16; i
++) {
4157 __put_user(env
->fregs
[i
].ll
, &sregs
->fpregs
.fprs
[i
]);
4161 static void setup_frame(int sig
, struct target_sigaction
*ka
,
4162 target_sigset_t
*set
, CPUS390XState
*env
)
4165 abi_ulong frame_addr
;
4167 frame_addr
= get_sigframe(ka
, env
, sizeof(*frame
));
4168 qemu_log("%s: frame_addr 0x%llx\n", __FUNCTION__
,
4169 (unsigned long long)frame_addr
);
4170 if (!lock_user_struct(VERIFY_WRITE
, frame
, frame_addr
, 0)) {
4174 qemu_log("%s: 1\n", __FUNCTION__
);
4175 if (__put_user(set
->sig
[0], &frame
->sc
.oldmask
[0])) {
4179 save_sigregs(env
, &frame
->sregs
);
4181 __put_user((abi_ulong
)(unsigned long)&frame
->sregs
,
4182 (abi_ulong
*)&frame
->sc
.sregs
);
4184 /* Set up to return from userspace. If provided, use a stub
4185 already in userspace. */
4186 if (ka
->sa_flags
& TARGET_SA_RESTORER
) {
4187 env
->regs
[14] = (unsigned long)
4188 ka
->sa_restorer
| PSW_ADDR_AMODE
;
4190 env
->regs
[14] = (unsigned long)
4191 frame
->retcode
| PSW_ADDR_AMODE
;
4192 if (__put_user(S390_SYSCALL_OPCODE
| TARGET_NR_sigreturn
,
4193 (uint16_t *)(frame
->retcode
)))
4197 /* Set up backchain. */
4198 if (__put_user(env
->regs
[15], (abi_ulong
*) frame
)) {
4202 /* Set up registers for signal handler */
4203 env
->regs
[15] = frame_addr
;
4204 env
->psw
.addr
= (target_ulong
) ka
->_sa_handler
| PSW_ADDR_AMODE
;
4206 env
->regs
[2] = sig
; //map_signal(sig);
4207 env
->regs
[3] = frame_addr
+= offsetof(typeof(*frame
), sc
);
4209 /* We forgot to include these in the sigcontext.
4210 To avoid breaking binary compatibility, they are passed as args. */
4211 env
->regs
[4] = 0; // FIXME: no clue... current->thread.trap_no;
4212 env
->regs
[5] = 0; // FIXME: no clue... current->thread.prot_addr;
4214 /* Place signal number on stack to allow backtrace from handler. */
4215 if (__put_user(env
->regs
[2], (int *) &frame
->signo
)) {
4218 unlock_user_struct(frame
, frame_addr
, 1);
4222 qemu_log("%s: give_sigsegv\n", __FUNCTION__
);
4223 unlock_user_struct(frame
, frame_addr
, 1);
4224 force_sig(TARGET_SIGSEGV
);
4227 static void setup_rt_frame(int sig
, struct target_sigaction
*ka
,
4228 target_siginfo_t
*info
,
4229 target_sigset_t
*set
, CPUS390XState
*env
)
4233 abi_ulong frame_addr
;
4235 frame_addr
= get_sigframe(ka
, env
, sizeof *frame
);
4236 qemu_log("%s: frame_addr 0x%llx\n", __FUNCTION__
,
4237 (unsigned long long)frame_addr
);
4238 if (!lock_user_struct(VERIFY_WRITE
, frame
, frame_addr
, 0)) {
4242 qemu_log("%s: 1\n", __FUNCTION__
);
4243 if (copy_siginfo_to_user(&frame
->info
, info
)) {
4247 /* Create the ucontext. */
4248 __put_user(0, &frame
->uc
.tuc_flags
);
4249 __put_user((abi_ulong
)0, (abi_ulong
*)&frame
->uc
.tuc_link
);
4250 __put_user(target_sigaltstack_used
.ss_sp
, &frame
->uc
.tuc_stack
.ss_sp
);
4251 __put_user(sas_ss_flags(get_sp_from_cpustate(env
)),
4252 &frame
->uc
.tuc_stack
.ss_flags
);
4253 __put_user(target_sigaltstack_used
.ss_size
, &frame
->uc
.tuc_stack
.ss_size
);
4254 save_sigregs(env
, &frame
->uc
.tuc_mcontext
);
4255 for (i
= 0; i
< TARGET_NSIG_WORDS
; i
++) {
4256 __put_user((abi_ulong
)set
->sig
[i
],
4257 (abi_ulong
*)&frame
->uc
.tuc_sigmask
.sig
[i
]);
4260 /* Set up to return from userspace. If provided, use a stub
4261 already in userspace. */
4262 if (ka
->sa_flags
& TARGET_SA_RESTORER
) {
4263 env
->regs
[14] = (unsigned long) ka
->sa_restorer
| PSW_ADDR_AMODE
;
4265 env
->regs
[14] = (unsigned long) frame
->retcode
| PSW_ADDR_AMODE
;
4266 if (__put_user(S390_SYSCALL_OPCODE
| TARGET_NR_rt_sigreturn
,
4267 (uint16_t *)(frame
->retcode
))) {
4272 /* Set up backchain. */
4273 if (__put_user(env
->regs
[15], (abi_ulong
*) frame
)) {
4277 /* Set up registers for signal handler */
4278 env
->regs
[15] = frame_addr
;
4279 env
->psw
.addr
= (target_ulong
) ka
->_sa_handler
| PSW_ADDR_AMODE
;
4281 env
->regs
[2] = sig
; //map_signal(sig);
4282 env
->regs
[3] = frame_addr
+ offsetof(typeof(*frame
), info
);
4283 env
->regs
[4] = frame_addr
+ offsetof(typeof(*frame
), uc
);
4287 qemu_log("%s: give_sigsegv\n", __FUNCTION__
);
4288 unlock_user_struct(frame
, frame_addr
, 1);
4289 force_sig(TARGET_SIGSEGV
);
4293 restore_sigregs(CPUS390XState
*env
, target_sigregs
*sc
)
4298 for (i
= 0; i
< 16; i
++) {
4299 err
|= __get_user(env
->regs
[i
], &sc
->regs
.gprs
[i
]);
4302 err
|= __get_user(env
->psw
.mask
, &sc
->regs
.psw
.mask
);
4303 qemu_log("%s: sc->regs.psw.addr 0x%llx env->psw.addr 0x%llx\n",
4304 __FUNCTION__
, (unsigned long long)sc
->regs
.psw
.addr
,
4305 (unsigned long long)env
->psw
.addr
);
4306 err
|= __get_user(env
->psw
.addr
, &sc
->regs
.psw
.addr
);
4307 /* FIXME: 31-bit -> | PSW_ADDR_AMODE */
4309 for (i
= 0; i
< 16; i
++) {
4310 err
|= __get_user(env
->aregs
[i
], &sc
->regs
.acrs
[i
]);
4312 for (i
= 0; i
< 16; i
++) {
4313 err
|= __get_user(env
->fregs
[i
].ll
, &sc
->fpregs
.fprs
[i
]);
4319 long do_sigreturn(CPUS390XState
*env
)
4322 abi_ulong frame_addr
= env
->regs
[15];
4323 qemu_log("%s: frame_addr 0x%llx\n", __FUNCTION__
,
4324 (unsigned long long)frame_addr
);
4325 target_sigset_t target_set
;
4328 if (!lock_user_struct(VERIFY_READ
, frame
, frame_addr
, 1)) {
4331 if (__get_user(target_set
.sig
[0], &frame
->sc
.oldmask
[0])) {
4335 target_to_host_sigset_internal(&set
, &target_set
);
4336 sigprocmask(SIG_SETMASK
, &set
, NULL
); /* ~_BLOCKABLE? */
4338 if (restore_sigregs(env
, &frame
->sregs
)) {
4342 unlock_user_struct(frame
, frame_addr
, 0);
4343 return env
->regs
[2];
4346 unlock_user_struct(frame
, frame_addr
, 0);
4347 force_sig(TARGET_SIGSEGV
);
4351 long do_rt_sigreturn(CPUS390XState
*env
)
4354 abi_ulong frame_addr
= env
->regs
[15];
4355 qemu_log("%s: frame_addr 0x%llx\n", __FUNCTION__
,
4356 (unsigned long long)frame_addr
);
4359 if (!lock_user_struct(VERIFY_READ
, frame
, frame_addr
, 1)) {
4362 target_to_host_sigset(&set
, &frame
->uc
.tuc_sigmask
);
4364 sigprocmask(SIG_SETMASK
, &set
, NULL
); /* ~_BLOCKABLE? */
4366 if (restore_sigregs(env
, &frame
->uc
.tuc_mcontext
)) {
4370 if (do_sigaltstack(frame_addr
+ offsetof(rt_sigframe
, uc
.tuc_stack
), 0,
4371 get_sp_from_cpustate(env
)) == -EFAULT
) {
4374 unlock_user_struct(frame
, frame_addr
, 0);
4375 return env
->regs
[2];
4378 unlock_user_struct(frame
, frame_addr
, 0);
4379 force_sig(TARGET_SIGSEGV
);
4383 #elif defined(TARGET_PPC) && !defined(TARGET_PPC64)
4385 /* FIXME: Many of the structures are defined for both PPC and PPC64, but
4386 the signal handling is different enough that we haven't implemented
4387 support for PPC64 yet. Hence the restriction above.
4389 There are various #if'd blocks for code for TARGET_PPC64. These
4390 blocks should go away so that we can successfully run 32-bit and
4391 64-bit binaries on a QEMU configured for PPC64. */
4393 /* Size of dummy stack frame allocated when calling signal handler.
4394 See arch/powerpc/include/asm/ptrace.h. */
4395 #if defined(TARGET_PPC64)
4396 #define SIGNAL_FRAMESIZE 128
4398 #define SIGNAL_FRAMESIZE 64
4401 /* See arch/powerpc/include/asm/sigcontext.h. */
4402 struct target_sigcontext
{
4403 target_ulong _unused
[4];
4405 #if defined(TARGET_PPC64)
4408 target_ulong handler
;
4409 target_ulong oldmask
;
4410 target_ulong regs
; /* struct pt_regs __user * */
4411 /* TODO: PPC64 includes extra bits here. */
4414 /* Indices for target_mcontext.mc_gregs, below.
4415 See arch/powerpc/include/asm/ptrace.h for details. */
4451 TARGET_PT_ORIG_R3
= 34,
4456 /* Yes, there are two registers with #39. One is 64-bit only. */
4458 TARGET_PT_SOFTE
= 39,
4459 TARGET_PT_TRAP
= 40,
4461 TARGET_PT_DSISR
= 42,
4462 TARGET_PT_RESULT
= 43,
4463 TARGET_PT_REGS_COUNT
= 44
4466 /* See arch/powerpc/include/asm/ucontext.h. Only used for 32-bit PPC;
4467 on 64-bit PPC, sigcontext and mcontext are one and the same. */
4468 struct target_mcontext
{
4469 target_ulong mc_gregs
[48];
4470 /* Includes fpscr. */
4471 uint64_t mc_fregs
[33];
4472 target_ulong mc_pad
[2];
4473 /* We need to handle Altivec and SPE at the same time, which no
4474 kernel needs to do. Fortunately, the kernel defines this bit to
4475 be Altivec-register-large all the time, rather than trying to
4476 twiddle it based on the specific platform. */
4478 /* SPE vector registers. One extra for SPEFSCR. */
4480 /* Altivec vector registers. The packing of VSCR and VRSAVE
4481 varies depending on whether we're PPC64 or not: PPC64 splits
4482 them apart; PPC32 stuffs them together. */
4483 #if defined(TARGET_PPC64)
4484 #define QEMU_NVRREG 34
4486 #define QEMU_NVRREG 33
4488 ppc_avr_t altivec
[QEMU_NVRREG
];
4490 } mc_vregs
__attribute__((__aligned__(16)));
4493 struct target_ucontext
{
4494 target_ulong tuc_flags
;
4495 target_ulong tuc_link
; /* struct ucontext __user * */
4496 struct target_sigaltstack tuc_stack
;
4497 #if !defined(TARGET_PPC64)
4499 target_ulong tuc_regs
; /* struct mcontext __user *
4500 points to uc_mcontext field */
4502 target_sigset_t tuc_sigmask
;
4503 #if defined(TARGET_PPC64)
4504 target_sigset_t unused
[15]; /* Allow for uc_sigmask growth */
4505 struct target_sigcontext tuc_mcontext
;
4507 int32_t tuc_maskext
[30];
4508 int32_t tuc_pad2
[3];
4509 struct target_mcontext tuc_mcontext
;
4513 /* See arch/powerpc/kernel/signal_32.c. */
4514 struct target_sigframe
{
4515 struct target_sigcontext sctx
;
4516 struct target_mcontext mctx
;
4520 struct target_rt_sigframe
{
4521 struct target_siginfo info
;
4522 struct target_ucontext uc
;
4526 /* We use the mc_pad field for the signal return trampoline. */
4527 #define tramp mc_pad
4529 /* See arch/powerpc/kernel/signal.c. */
4530 static target_ulong
get_sigframe(struct target_sigaction
*ka
,
4534 target_ulong oldsp
, newsp
;
4536 oldsp
= env
->gpr
[1];
4538 if ((ka
->sa_flags
& TARGET_SA_ONSTACK
) &&
4539 (sas_ss_flags(oldsp
) == 0)) {
4540 oldsp
= (target_sigaltstack_used
.ss_sp
4541 + target_sigaltstack_used
.ss_size
);
4544 newsp
= (oldsp
- frame_size
) & ~0xFUL
;
4549 static int save_user_regs(CPUPPCState
*env
, struct target_mcontext
*frame
,
4552 target_ulong msr
= env
->msr
;
4554 target_ulong ccr
= 0;
4556 /* In general, the kernel attempts to be intelligent about what it
4557 needs to save for Altivec/FP/SPE registers. We don't care that
4558 much, so we just go ahead and save everything. */
4560 /* Save general registers. */
4561 for (i
= 0; i
< ARRAY_SIZE(env
->gpr
); i
++) {
4562 if (__put_user(env
->gpr
[i
], &frame
->mc_gregs
[i
])) {
4566 if (__put_user(env
->nip
, &frame
->mc_gregs
[TARGET_PT_NIP
])
4567 || __put_user(env
->ctr
, &frame
->mc_gregs
[TARGET_PT_CTR
])
4568 || __put_user(env
->lr
, &frame
->mc_gregs
[TARGET_PT_LNK
])
4569 || __put_user(env
->xer
, &frame
->mc_gregs
[TARGET_PT_XER
]))
4572 for (i
= 0; i
< ARRAY_SIZE(env
->crf
); i
++) {
4573 ccr
|= env
->crf
[i
] << (32 - ((i
+ 1) * 4));
4575 if (__put_user(ccr
, &frame
->mc_gregs
[TARGET_PT_CCR
]))
4578 /* Save Altivec registers if necessary. */
4579 if (env
->insns_flags
& PPC_ALTIVEC
) {
4580 for (i
= 0; i
< ARRAY_SIZE(env
->avr
); i
++) {
4581 ppc_avr_t
*avr
= &env
->avr
[i
];
4582 ppc_avr_t
*vreg
= &frame
->mc_vregs
.altivec
[i
];
4584 if (__put_user(avr
->u64
[0], &vreg
->u64
[0]) ||
4585 __put_user(avr
->u64
[1], &vreg
->u64
[1])) {
4589 /* Set MSR_VR in the saved MSR value to indicate that
4590 frame->mc_vregs contains valid data. */
4592 if (__put_user((uint32_t)env
->spr
[SPR_VRSAVE
],
4593 &frame
->mc_vregs
.altivec
[32].u32
[3]))
4597 /* Save floating point registers. */
4598 if (env
->insns_flags
& PPC_FLOAT
) {
4599 for (i
= 0; i
< ARRAY_SIZE(env
->fpr
); i
++) {
4600 if (__put_user(env
->fpr
[i
], &frame
->mc_fregs
[i
])) {
4604 if (__put_user((uint64_t) env
->fpscr
, &frame
->mc_fregs
[32]))
4608 /* Save SPE registers. The kernel only saves the high half. */
4609 if (env
->insns_flags
& PPC_SPE
) {
4610 #if defined(TARGET_PPC64)
4611 for (i
= 0; i
< ARRAY_SIZE(env
->gpr
); i
++) {
4612 if (__put_user(env
->gpr
[i
] >> 32, &frame
->mc_vregs
.spe
[i
])) {
4617 for (i
= 0; i
< ARRAY_SIZE(env
->gprh
); i
++) {
4618 if (__put_user(env
->gprh
[i
], &frame
->mc_vregs
.spe
[i
])) {
4623 /* Set MSR_SPE in the saved MSR value to indicate that
4624 frame->mc_vregs contains valid data. */
4626 if (__put_user(env
->spe_fscr
, &frame
->mc_vregs
.spe
[32]))
4631 if (__put_user(msr
, &frame
->mc_gregs
[TARGET_PT_MSR
]))
4634 /* Set up the sigreturn trampoline: li r0,sigret; sc. */
4636 if (__put_user(0x38000000UL
| sigret
, &frame
->tramp
[0]) ||
4637 __put_user(0x44000002UL
, &frame
->tramp
[1])) {
4645 static int restore_user_regs(CPUPPCState
*env
,
4646 struct target_mcontext
*frame
, int sig
)
4648 target_ulong save_r2
= 0;
4655 save_r2
= env
->gpr
[2];
4658 /* Restore general registers. */
4659 for (i
= 0; i
< ARRAY_SIZE(env
->gpr
); i
++) {
4660 if (__get_user(env
->gpr
[i
], &frame
->mc_gregs
[i
])) {
4664 if (__get_user(env
->nip
, &frame
->mc_gregs
[TARGET_PT_NIP
])
4665 || __get_user(env
->ctr
, &frame
->mc_gregs
[TARGET_PT_CTR
])
4666 || __get_user(env
->lr
, &frame
->mc_gregs
[TARGET_PT_LNK
])
4667 || __get_user(env
->xer
, &frame
->mc_gregs
[TARGET_PT_XER
]))
4669 if (__get_user(ccr
, &frame
->mc_gregs
[TARGET_PT_CCR
]))
4672 for (i
= 0; i
< ARRAY_SIZE(env
->crf
); i
++) {
4673 env
->crf
[i
] = (ccr
>> (32 - ((i
+ 1) * 4))) & 0xf;
4677 env
->gpr
[2] = save_r2
;
4680 if (__get_user(msr
, &frame
->mc_gregs
[TARGET_PT_MSR
]))
4683 /* If doing signal return, restore the previous little-endian mode. */
4685 env
->msr
= (env
->msr
& ~MSR_LE
) | (msr
& MSR_LE
);
4687 /* Restore Altivec registers if necessary. */
4688 if (env
->insns_flags
& PPC_ALTIVEC
) {
4689 for (i
= 0; i
< ARRAY_SIZE(env
->avr
); i
++) {
4690 ppc_avr_t
*avr
= &env
->avr
[i
];
4691 ppc_avr_t
*vreg
= &frame
->mc_vregs
.altivec
[i
];
4693 if (__get_user(avr
->u64
[0], &vreg
->u64
[0]) ||
4694 __get_user(avr
->u64
[1], &vreg
->u64
[1])) {
4698 /* Set MSR_VEC in the saved MSR value to indicate that
4699 frame->mc_vregs contains valid data. */
4700 if (__get_user(env
->spr
[SPR_VRSAVE
],
4701 (target_ulong
*)(&frame
->mc_vregs
.altivec
[32].u32
[3])))
4705 /* Restore floating point registers. */
4706 if (env
->insns_flags
& PPC_FLOAT
) {
4708 for (i
= 0; i
< ARRAY_SIZE(env
->fpr
); i
++) {
4709 if (__get_user(env
->fpr
[i
], &frame
->mc_fregs
[i
])) {
4713 if (__get_user(fpscr
, &frame
->mc_fregs
[32]))
4715 env
->fpscr
= (uint32_t) fpscr
;
4718 /* Save SPE registers. The kernel only saves the high half. */
4719 if (env
->insns_flags
& PPC_SPE
) {
4720 #if defined(TARGET_PPC64)
4721 for (i
= 0; i
< ARRAY_SIZE(env
->gpr
); i
++) {
4724 if (__get_user(hi
, &frame
->mc_vregs
.spe
[i
])) {
4727 env
->gpr
[i
] = ((uint64_t)hi
<< 32) | ((uint32_t) env
->gpr
[i
]);
4730 for (i
= 0; i
< ARRAY_SIZE(env
->gprh
); i
++) {
4731 if (__get_user(env
->gprh
[i
], &frame
->mc_vregs
.spe
[i
])) {
4736 if (__get_user(env
->spe_fscr
, &frame
->mc_vregs
.spe
[32]))
4743 static void setup_frame(int sig
, struct target_sigaction
*ka
,
4744 target_sigset_t
*set
, CPUPPCState
*env
)
4746 struct target_sigframe
*frame
;
4747 struct target_sigcontext
*sc
;
4748 target_ulong frame_addr
, newsp
;
4752 frame_addr
= get_sigframe(ka
, env
, sizeof(*frame
));
4753 if (!lock_user_struct(VERIFY_WRITE
, frame
, frame_addr
, 1))
4757 signal
= current_exec_domain_sig(sig
);
4759 err
|= __put_user(ka
->_sa_handler
, &sc
->handler
);
4760 err
|= __put_user(set
->sig
[0], &sc
->oldmask
);
4761 #if defined(TARGET_PPC64)
4762 err
|= __put_user(set
->sig
[0] >> 32, &sc
->_unused
[3]);
4764 err
|= __put_user(set
->sig
[1], &sc
->_unused
[3]);
4766 err
|= __put_user(h2g(&frame
->mctx
), &sc
->regs
);
4767 err
|= __put_user(sig
, &sc
->signal
);
4769 /* Save user regs. */
4770 err
|= save_user_regs(env
, &frame
->mctx
, TARGET_NR_sigreturn
);
4772 /* The kernel checks for the presence of a VDSO here. We don't
4773 emulate a vdso, so use a sigreturn system call. */
4774 env
->lr
= (target_ulong
) h2g(frame
->mctx
.tramp
);
4776 /* Turn off all fp exceptions. */
4779 /* Create a stack frame for the caller of the handler. */
4780 newsp
= frame_addr
- SIGNAL_FRAMESIZE
;
4781 err
|= put_user(env
->gpr
[1], newsp
, target_ulong
);
4786 /* Set up registers for signal handler. */
4787 env
->gpr
[1] = newsp
;
4788 env
->gpr
[3] = signal
;
4789 env
->gpr
[4] = frame_addr
+ offsetof(struct target_sigframe
, sctx
);
4790 env
->nip
= (target_ulong
) ka
->_sa_handler
;
4791 /* Signal handlers are entered in big-endian mode. */
4792 env
->msr
&= ~MSR_LE
;
4794 unlock_user_struct(frame
, frame_addr
, 1);
4798 unlock_user_struct(frame
, frame_addr
, 1);
4799 qemu_log("segfaulting from setup_frame\n");
4800 force_sig(TARGET_SIGSEGV
);
4803 static void setup_rt_frame(int sig
, struct target_sigaction
*ka
,
4804 target_siginfo_t
*info
,
4805 target_sigset_t
*set
, CPUPPCState
*env
)
4807 struct target_rt_sigframe
*rt_sf
;
4808 struct target_mcontext
*frame
;
4809 target_ulong rt_sf_addr
, newsp
= 0;
4813 rt_sf_addr
= get_sigframe(ka
, env
, sizeof(*rt_sf
));
4814 if (!lock_user_struct(VERIFY_WRITE
, rt_sf
, rt_sf_addr
, 1))
4817 signal
= current_exec_domain_sig(sig
);
4819 err
|= copy_siginfo_to_user(&rt_sf
->info
, info
);
4821 err
|= __put_user(0, &rt_sf
->uc
.tuc_flags
);
4822 err
|= __put_user(0, &rt_sf
->uc
.tuc_link
);
4823 err
|= __put_user((target_ulong
)target_sigaltstack_used
.ss_sp
,
4824 &rt_sf
->uc
.tuc_stack
.ss_sp
);
4825 err
|= __put_user(sas_ss_flags(env
->gpr
[1]),
4826 &rt_sf
->uc
.tuc_stack
.ss_flags
);
4827 err
|= __put_user(target_sigaltstack_used
.ss_size
,
4828 &rt_sf
->uc
.tuc_stack
.ss_size
);
4829 err
|= __put_user(h2g (&rt_sf
->uc
.tuc_mcontext
),
4830 &rt_sf
->uc
.tuc_regs
);
4831 for(i
= 0; i
< TARGET_NSIG_WORDS
; i
++) {
4832 err
|= __put_user(set
->sig
[i
], &rt_sf
->uc
.tuc_sigmask
.sig
[i
]);
4835 frame
= &rt_sf
->uc
.tuc_mcontext
;
4836 err
|= save_user_regs(env
, frame
, TARGET_NR_rt_sigreturn
);
4838 /* The kernel checks for the presence of a VDSO here. We don't
4839 emulate a vdso, so use a sigreturn system call. */
4840 env
->lr
= (target_ulong
) h2g(frame
->tramp
);
4842 /* Turn off all fp exceptions. */
4845 /* Create a stack frame for the caller of the handler. */
4846 newsp
= rt_sf_addr
- (SIGNAL_FRAMESIZE
+ 16);
4847 err
|= __put_user(env
->gpr
[1], (target_ulong
*)(uintptr_t) newsp
);
4852 /* Set up registers for signal handler. */
4853 env
->gpr
[1] = newsp
;
4854 env
->gpr
[3] = (target_ulong
) signal
;
4855 env
->gpr
[4] = (target_ulong
) h2g(&rt_sf
->info
);
4856 env
->gpr
[5] = (target_ulong
) h2g(&rt_sf
->uc
);
4857 env
->gpr
[6] = (target_ulong
) h2g(rt_sf
);
4858 env
->nip
= (target_ulong
) ka
->_sa_handler
;
4859 /* Signal handlers are entered in big-endian mode. */
4860 env
->msr
&= ~MSR_LE
;
4862 unlock_user_struct(rt_sf
, rt_sf_addr
, 1);
4866 unlock_user_struct(rt_sf
, rt_sf_addr
, 1);
4867 qemu_log("segfaulting from setup_rt_frame\n");
4868 force_sig(TARGET_SIGSEGV
);
4872 long do_sigreturn(CPUPPCState
*env
)
4874 struct target_sigcontext
*sc
= NULL
;
4875 struct target_mcontext
*sr
= NULL
;
4876 target_ulong sr_addr
= 0, sc_addr
;
4878 target_sigset_t set
;
4880 sc_addr
= env
->gpr
[1] + SIGNAL_FRAMESIZE
;
4881 if (!lock_user_struct(VERIFY_READ
, sc
, sc_addr
, 1))
4884 #if defined(TARGET_PPC64)
4885 set
.sig
[0] = sc
->oldmask
+ ((long)(sc
->_unused
[3]) << 32);
4887 if(__get_user(set
.sig
[0], &sc
->oldmask
) ||
4888 __get_user(set
.sig
[1], &sc
->_unused
[3]))
4891 target_to_host_sigset_internal(&blocked
, &set
);
4892 sigprocmask(SIG_SETMASK
, &blocked
, NULL
);
4894 if (__get_user(sr_addr
, &sc
->regs
))
4896 if (!lock_user_struct(VERIFY_READ
, sr
, sr_addr
, 1))
4898 if (restore_user_regs(env
, sr
, 1))
4901 unlock_user_struct(sr
, sr_addr
, 1);
4902 unlock_user_struct(sc
, sc_addr
, 1);
4903 return -TARGET_QEMU_ESIGRETURN
;
4906 unlock_user_struct(sr
, sr_addr
, 1);
4907 unlock_user_struct(sc
, sc_addr
, 1);
4908 qemu_log("segfaulting from do_sigreturn\n");
4909 force_sig(TARGET_SIGSEGV
);
4913 /* See arch/powerpc/kernel/signal_32.c. */
4914 static int do_setcontext(struct target_ucontext
*ucp
, CPUPPCState
*env
, int sig
)
4916 struct target_mcontext
*mcp
;
4917 target_ulong mcp_addr
;
4919 target_sigset_t set
;
4921 if (copy_from_user(&set
, h2g(ucp
) + offsetof(struct target_ucontext
, tuc_sigmask
),
4925 #if defined(TARGET_PPC64)
4926 fprintf (stderr
, "do_setcontext: not implemented\n");
4929 if (__get_user(mcp_addr
, &ucp
->tuc_regs
))
4932 if (!lock_user_struct(VERIFY_READ
, mcp
, mcp_addr
, 1))
4935 target_to_host_sigset_internal(&blocked
, &set
);
4936 sigprocmask(SIG_SETMASK
, &blocked
, NULL
);
4937 if (restore_user_regs(env
, mcp
, sig
))
4940 unlock_user_struct(mcp
, mcp_addr
, 1);
4944 unlock_user_struct(mcp
, mcp_addr
, 1);
4949 long do_rt_sigreturn(CPUPPCState
*env
)
4951 struct target_rt_sigframe
*rt_sf
= NULL
;
4952 target_ulong rt_sf_addr
;
4954 rt_sf_addr
= env
->gpr
[1] + SIGNAL_FRAMESIZE
+ 16;
4955 if (!lock_user_struct(VERIFY_READ
, rt_sf
, rt_sf_addr
, 1))
4958 if (do_setcontext(&rt_sf
->uc
, env
, 1))
4961 do_sigaltstack(rt_sf_addr
4962 + offsetof(struct target_rt_sigframe
, uc
.tuc_stack
),
4965 unlock_user_struct(rt_sf
, rt_sf_addr
, 1);
4966 return -TARGET_QEMU_ESIGRETURN
;
4969 unlock_user_struct(rt_sf
, rt_sf_addr
, 1);
4970 qemu_log("segfaulting from do_rt_sigreturn\n");
4971 force_sig(TARGET_SIGSEGV
);
4975 #elif defined(TARGET_M68K)
4977 struct target_sigcontext
{
4984 unsigned short sc_sr
;
4988 struct target_sigframe
4995 abi_ulong extramask
[TARGET_NSIG_WORDS
-1];
4996 struct target_sigcontext sc
;
4999 typedef int target_greg_t
;
5000 #define TARGET_NGREG 18
5001 typedef target_greg_t target_gregset_t
[TARGET_NGREG
];
5003 typedef struct target_fpregset
{
5006 } target_fpregset_t
;
5008 struct target_mcontext
{
5010 target_gregset_t gregs
;
5011 target_fpregset_t fpregs
;
5014 #define TARGET_MCONTEXT_VERSION 2
5016 struct target_ucontext
{
5017 abi_ulong tuc_flags
;
5019 target_stack_t tuc_stack
;
5020 struct target_mcontext tuc_mcontext
;
5021 abi_long tuc_filler
[80];
5022 target_sigset_t tuc_sigmask
;
5025 struct target_rt_sigframe
5032 struct target_siginfo info
;
5033 struct target_ucontext uc
;
5037 setup_sigcontext(struct target_sigcontext
*sc
, CPUM68KState
*env
,
5042 err
|= __put_user(mask
, &sc
->sc_mask
);
5043 err
|= __put_user(env
->aregs
[7], &sc
->sc_usp
);
5044 err
|= __put_user(env
->dregs
[0], &sc
->sc_d0
);
5045 err
|= __put_user(env
->dregs
[1], &sc
->sc_d1
);
5046 err
|= __put_user(env
->aregs
[0], &sc
->sc_a0
);
5047 err
|= __put_user(env
->aregs
[1], &sc
->sc_a1
);
5048 err
|= __put_user(env
->sr
, &sc
->sc_sr
);
5049 err
|= __put_user(env
->pc
, &sc
->sc_pc
);
5055 restore_sigcontext(CPUM68KState
*env
, struct target_sigcontext
*sc
, int *pd0
)
5060 err
|= __get_user(env
->aregs
[7], &sc
->sc_usp
);
5061 err
|= __get_user(env
->dregs
[1], &sc
->sc_d1
);
5062 err
|= __get_user(env
->aregs
[0], &sc
->sc_a0
);
5063 err
|= __get_user(env
->aregs
[1], &sc
->sc_a1
);
5064 err
|= __get_user(env
->pc
, &sc
->sc_pc
);
5065 err
|= __get_user(temp
, &sc
->sc_sr
);
5066 env
->sr
= (env
->sr
& 0xff00) | (temp
& 0xff);
5068 *pd0
= tswapl(sc
->sc_d0
);
5074 * Determine which stack to use..
5076 static inline abi_ulong
5077 get_sigframe(struct target_sigaction
*ka
, CPUM68KState
*regs
,
5082 sp
= regs
->aregs
[7];
5084 /* This is the X/Open sanctioned signal stack switching. */
5085 if ((ka
->sa_flags
& TARGET_SA_ONSTACK
) && (sas_ss_flags (sp
) == 0)) {
5086 sp
= target_sigaltstack_used
.ss_sp
+ target_sigaltstack_used
.ss_size
;
5089 return ((sp
- frame_size
) & -8UL);
5092 static void setup_frame(int sig
, struct target_sigaction
*ka
,
5093 target_sigset_t
*set
, CPUM68KState
*env
)
5095 struct target_sigframe
*frame
;
5096 abi_ulong frame_addr
;
5097 abi_ulong retcode_addr
;
5102 frame_addr
= get_sigframe(ka
, env
, sizeof *frame
);
5103 if (!lock_user_struct(VERIFY_WRITE
, frame
, frame_addr
, 0))
5106 err
|= __put_user(sig
, &frame
->sig
);
5108 sc_addr
= frame_addr
+ offsetof(struct target_sigframe
, sc
);
5109 err
|= __put_user(sc_addr
, &frame
->psc
);
5111 err
|= setup_sigcontext(&frame
->sc
, env
, set
->sig
[0]);
5115 for(i
= 1; i
< TARGET_NSIG_WORDS
; i
++) {
5116 if (__put_user(set
->sig
[i
], &frame
->extramask
[i
- 1]))
5120 /* Set up to return from userspace. */
5122 retcode_addr
= frame_addr
+ offsetof(struct target_sigframe
, retcode
);
5123 err
|= __put_user(retcode_addr
, &frame
->pretcode
);
5125 /* moveq #,d0; trap #0 */
5127 err
|= __put_user(0x70004e40 + (TARGET_NR_sigreturn
<< 16),
5128 (long *)(frame
->retcode
));
5133 /* Set up to return from userspace */
5135 env
->aregs
[7] = frame_addr
;
5136 env
->pc
= ka
->_sa_handler
;
5138 unlock_user_struct(frame
, frame_addr
, 1);
5142 unlock_user_struct(frame
, frame_addr
, 1);
5143 force_sig(TARGET_SIGSEGV
);
5146 static inline int target_rt_setup_ucontext(struct target_ucontext
*uc
,
5149 target_greg_t
*gregs
= uc
->tuc_mcontext
.gregs
;
5152 err
= __put_user(TARGET_MCONTEXT_VERSION
, &uc
->tuc_mcontext
.version
);
5153 err
|= __put_user(env
->dregs
[0], &gregs
[0]);
5154 err
|= __put_user(env
->dregs
[1], &gregs
[1]);
5155 err
|= __put_user(env
->dregs
[2], &gregs
[2]);
5156 err
|= __put_user(env
->dregs
[3], &gregs
[3]);
5157 err
|= __put_user(env
->dregs
[4], &gregs
[4]);
5158 err
|= __put_user(env
->dregs
[5], &gregs
[5]);
5159 err
|= __put_user(env
->dregs
[6], &gregs
[6]);
5160 err
|= __put_user(env
->dregs
[7], &gregs
[7]);
5161 err
|= __put_user(env
->aregs
[0], &gregs
[8]);
5162 err
|= __put_user(env
->aregs
[1], &gregs
[9]);
5163 err
|= __put_user(env
->aregs
[2], &gregs
[10]);
5164 err
|= __put_user(env
->aregs
[3], &gregs
[11]);
5165 err
|= __put_user(env
->aregs
[4], &gregs
[12]);
5166 err
|= __put_user(env
->aregs
[5], &gregs
[13]);
5167 err
|= __put_user(env
->aregs
[6], &gregs
[14]);
5168 err
|= __put_user(env
->aregs
[7], &gregs
[15]);
5169 err
|= __put_user(env
->pc
, &gregs
[16]);
5170 err
|= __put_user(env
->sr
, &gregs
[17]);
5175 static inline int target_rt_restore_ucontext(CPUM68KState
*env
,
5176 struct target_ucontext
*uc
,
5181 target_greg_t
*gregs
= uc
->tuc_mcontext
.gregs
;
5183 err
= __get_user(temp
, &uc
->tuc_mcontext
.version
);
5184 if (temp
!= TARGET_MCONTEXT_VERSION
)
5187 /* restore passed registers */
5188 err
|= __get_user(env
->dregs
[0], &gregs
[0]);
5189 err
|= __get_user(env
->dregs
[1], &gregs
[1]);
5190 err
|= __get_user(env
->dregs
[2], &gregs
[2]);
5191 err
|= __get_user(env
->dregs
[3], &gregs
[3]);
5192 err
|= __get_user(env
->dregs
[4], &gregs
[4]);
5193 err
|= __get_user(env
->dregs
[5], &gregs
[5]);
5194 err
|= __get_user(env
->dregs
[6], &gregs
[6]);
5195 err
|= __get_user(env
->dregs
[7], &gregs
[7]);
5196 err
|= __get_user(env
->aregs
[0], &gregs
[8]);
5197 err
|= __get_user(env
->aregs
[1], &gregs
[9]);
5198 err
|= __get_user(env
->aregs
[2], &gregs
[10]);
5199 err
|= __get_user(env
->aregs
[3], &gregs
[11]);
5200 err
|= __get_user(env
->aregs
[4], &gregs
[12]);
5201 err
|= __get_user(env
->aregs
[5], &gregs
[13]);
5202 err
|= __get_user(env
->aregs
[6], &gregs
[14]);
5203 err
|= __get_user(env
->aregs
[7], &gregs
[15]);
5204 err
|= __get_user(env
->pc
, &gregs
[16]);
5205 err
|= __get_user(temp
, &gregs
[17]);
5206 env
->sr
= (env
->sr
& 0xff00) | (temp
& 0xff);
5208 *pd0
= env
->dregs
[0];
5215 static void setup_rt_frame(int sig
, struct target_sigaction
*ka
,
5216 target_siginfo_t
*info
,
5217 target_sigset_t
*set
, CPUM68KState
*env
)
5219 struct target_rt_sigframe
*frame
;
5220 abi_ulong frame_addr
;
5221 abi_ulong retcode_addr
;
5222 abi_ulong info_addr
;
5227 frame_addr
= get_sigframe(ka
, env
, sizeof *frame
);
5228 if (!lock_user_struct(VERIFY_WRITE
, frame
, frame_addr
, 0))
5231 err
|= __put_user(sig
, &frame
->sig
);
5233 info_addr
= frame_addr
+ offsetof(struct target_rt_sigframe
, info
);
5234 err
|= __put_user(info_addr
, &frame
->pinfo
);
5236 uc_addr
= frame_addr
+ offsetof(struct target_rt_sigframe
, uc
);
5237 err
|= __put_user(uc_addr
, &frame
->puc
);
5239 err
|= copy_siginfo_to_user(&frame
->info
, info
);
5241 /* Create the ucontext */
5243 err
|= __put_user(0, &frame
->uc
.tuc_flags
);
5244 err
|= __put_user(0, &frame
->uc
.tuc_link
);
5245 err
|= __put_user(target_sigaltstack_used
.ss_sp
,
5246 &frame
->uc
.tuc_stack
.ss_sp
);
5247 err
|= __put_user(sas_ss_flags(env
->aregs
[7]),
5248 &frame
->uc
.tuc_stack
.ss_flags
);
5249 err
|= __put_user(target_sigaltstack_used
.ss_size
,
5250 &frame
->uc
.tuc_stack
.ss_size
);
5251 err
|= target_rt_setup_ucontext(&frame
->uc
, env
);
5256 for(i
= 0; i
< TARGET_NSIG_WORDS
; i
++) {
5257 if (__put_user(set
->sig
[i
], &frame
->uc
.tuc_sigmask
.sig
[i
]))
5261 /* Set up to return from userspace. */
5263 retcode_addr
= frame_addr
+ offsetof(struct target_sigframe
, retcode
);
5264 err
|= __put_user(retcode_addr
, &frame
->pretcode
);
5266 /* moveq #,d0; notb d0; trap #0 */
5268 err
|= __put_user(0x70004600 + ((TARGET_NR_rt_sigreturn
^ 0xff) << 16),
5269 (long *)(frame
->retcode
+ 0));
5270 err
|= __put_user(0x4e40, (short *)(frame
->retcode
+ 4));
5275 /* Set up to return from userspace */
5277 env
->aregs
[7] = frame_addr
;
5278 env
->pc
= ka
->_sa_handler
;
5280 unlock_user_struct(frame
, frame_addr
, 1);
5284 unlock_user_struct(frame
, frame_addr
, 1);
5285 force_sig(TARGET_SIGSEGV
);
5288 long do_sigreturn(CPUM68KState
*env
)
5290 struct target_sigframe
*frame
;
5291 abi_ulong frame_addr
= env
->aregs
[7] - 4;
5292 target_sigset_t target_set
;
5296 if (!lock_user_struct(VERIFY_READ
, frame
, frame_addr
, 1))
5299 /* set blocked signals */
5301 if (__get_user(target_set
.sig
[0], &frame
->sc
.sc_mask
))
5304 for(i
= 1; i
< TARGET_NSIG_WORDS
; i
++) {
5305 if (__get_user(target_set
.sig
[i
], &frame
->extramask
[i
- 1]))
5309 target_to_host_sigset_internal(&set
, &target_set
);
5310 sigprocmask(SIG_SETMASK
, &set
, NULL
);
5312 /* restore registers */
5314 if (restore_sigcontext(env
, &frame
->sc
, &d0
))
5317 unlock_user_struct(frame
, frame_addr
, 0);
5321 unlock_user_struct(frame
, frame_addr
, 0);
5322 force_sig(TARGET_SIGSEGV
);
5326 long do_rt_sigreturn(CPUM68KState
*env
)
5328 struct target_rt_sigframe
*frame
;
5329 abi_ulong frame_addr
= env
->aregs
[7] - 4;
5330 target_sigset_t target_set
;
5334 if (!lock_user_struct(VERIFY_READ
, frame
, frame_addr
, 1))
5337 target_to_host_sigset_internal(&set
, &target_set
);
5338 sigprocmask(SIG_SETMASK
, &set
, NULL
);
5340 /* restore registers */
5342 if (target_rt_restore_ucontext(env
, &frame
->uc
, &d0
))
5345 if (do_sigaltstack(frame_addr
+
5346 offsetof(struct target_rt_sigframe
, uc
.tuc_stack
),
5347 0, get_sp_from_cpustate(env
)) == -EFAULT
)
5350 unlock_user_struct(frame
, frame_addr
, 0);
5354 unlock_user_struct(frame
, frame_addr
, 0);
5355 force_sig(TARGET_SIGSEGV
);
5359 #elif defined(TARGET_ALPHA)
5361 struct target_sigcontext
{
5362 abi_long sc_onstack
;
5366 abi_long sc_regs
[32];
5367 abi_long sc_ownedfp
;
5368 abi_long sc_fpregs
[32];
5370 abi_ulong sc_fp_control
;
5371 abi_ulong sc_reserved1
;
5372 abi_ulong sc_reserved2
;
5375 abi_ulong sc_traparg_a0
;
5376 abi_ulong sc_traparg_a1
;
5377 abi_ulong sc_traparg_a2
;
5378 abi_ulong sc_fp_trap_pc
;
5379 abi_ulong sc_fp_trigger_sum
;
5380 abi_ulong sc_fp_trigger_inst
;
5383 struct target_ucontext
{
5384 abi_ulong tuc_flags
;
5386 abi_ulong tuc_osf_sigmask
;
5387 target_stack_t tuc_stack
;
5388 struct target_sigcontext tuc_mcontext
;
5389 target_sigset_t tuc_sigmask
;
5392 struct target_sigframe
{
5393 struct target_sigcontext sc
;
5394 unsigned int retcode
[3];
5397 struct target_rt_sigframe
{
5398 target_siginfo_t info
;
5399 struct target_ucontext uc
;
5400 unsigned int retcode
[3];
5403 #define INSN_MOV_R30_R16 0x47fe0410
5404 #define INSN_LDI_R0 0x201f0000
5405 #define INSN_CALLSYS 0x00000083
5407 static int setup_sigcontext(struct target_sigcontext
*sc
, CPUAlphaState
*env
,
5408 abi_ulong frame_addr
, target_sigset_t
*set
)
5412 err
|= __put_user(on_sig_stack(frame_addr
), &sc
->sc_onstack
);
5413 err
|= __put_user(set
->sig
[0], &sc
->sc_mask
);
5414 err
|= __put_user(env
->pc
, &sc
->sc_pc
);
5415 err
|= __put_user(8, &sc
->sc_ps
);
5417 for (i
= 0; i
< 31; ++i
) {
5418 err
|= __put_user(env
->ir
[i
], &sc
->sc_regs
[i
]);
5420 err
|= __put_user(0, &sc
->sc_regs
[31]);
5422 for (i
= 0; i
< 31; ++i
) {
5423 err
|= __put_user(env
->fir
[i
], &sc
->sc_fpregs
[i
]);
5425 err
|= __put_user(0, &sc
->sc_fpregs
[31]);
5426 err
|= __put_user(cpu_alpha_load_fpcr(env
), &sc
->sc_fpcr
);
5428 err
|= __put_user(0, &sc
->sc_traparg_a0
); /* FIXME */
5429 err
|= __put_user(0, &sc
->sc_traparg_a1
); /* FIXME */
5430 err
|= __put_user(0, &sc
->sc_traparg_a2
); /* FIXME */
5435 static int restore_sigcontext(CPUAlphaState
*env
,
5436 struct target_sigcontext
*sc
)
5441 err
|= __get_user(env
->pc
, &sc
->sc_pc
);
5443 for (i
= 0; i
< 31; ++i
) {
5444 err
|= __get_user(env
->ir
[i
], &sc
->sc_regs
[i
]);
5446 for (i
= 0; i
< 31; ++i
) {
5447 err
|= __get_user(env
->fir
[i
], &sc
->sc_fpregs
[i
]);
5450 err
|= __get_user(fpcr
, &sc
->sc_fpcr
);
5451 cpu_alpha_store_fpcr(env
, fpcr
);
5456 static inline abi_ulong
get_sigframe(struct target_sigaction
*sa
,
5458 unsigned long framesize
)
5460 abi_ulong sp
= env
->ir
[IR_SP
];
5462 /* This is the X/Open sanctioned signal stack switching. */
5463 if ((sa
->sa_flags
& TARGET_SA_ONSTACK
) != 0 && !sas_ss_flags(sp
)) {
5464 sp
= target_sigaltstack_used
.ss_sp
+ target_sigaltstack_used
.ss_size
;
5466 return (sp
- framesize
) & -32;
5469 static void setup_frame(int sig
, struct target_sigaction
*ka
,
5470 target_sigset_t
*set
, CPUAlphaState
*env
)
5472 abi_ulong frame_addr
, r26
;
5473 struct target_sigframe
*frame
;
5476 frame_addr
= get_sigframe(ka
, env
, sizeof(*frame
));
5477 if (!lock_user_struct(VERIFY_WRITE
, frame
, frame_addr
, 0)) {
5481 err
|= setup_sigcontext(&frame
->sc
, env
, frame_addr
, set
);
5483 if (ka
->sa_restorer
) {
5484 r26
= ka
->sa_restorer
;
5486 err
|= __put_user(INSN_MOV_R30_R16
, &frame
->retcode
[0]);
5487 err
|= __put_user(INSN_LDI_R0
+ TARGET_NR_sigreturn
,
5488 &frame
->retcode
[1]);
5489 err
|= __put_user(INSN_CALLSYS
, &frame
->retcode
[2]);
5494 unlock_user_struct(frame
, frame_addr
, 1);
5498 if (sig
== TARGET_SIGSEGV
) {
5499 ka
->_sa_handler
= TARGET_SIG_DFL
;
5501 force_sig(TARGET_SIGSEGV
);
5504 env
->ir
[IR_RA
] = r26
;
5505 env
->ir
[IR_PV
] = env
->pc
= ka
->_sa_handler
;
5506 env
->ir
[IR_A0
] = sig
;
5508 env
->ir
[IR_A2
] = frame_addr
+ offsetof(struct target_sigframe
, sc
);
5509 env
->ir
[IR_SP
] = frame_addr
;
5512 static void setup_rt_frame(int sig
, struct target_sigaction
*ka
,
5513 target_siginfo_t
*info
,
5514 target_sigset_t
*set
, CPUAlphaState
*env
)
5516 abi_ulong frame_addr
, r26
;
5517 struct target_rt_sigframe
*frame
;
5520 frame_addr
= get_sigframe(ka
, env
, sizeof(*frame
));
5521 if (!lock_user_struct(VERIFY_WRITE
, frame
, frame_addr
, 0)) {
5525 err
|= copy_siginfo_to_user(&frame
->info
, info
);
5527 err
|= __put_user(0, &frame
->uc
.tuc_flags
);
5528 err
|= __put_user(0, &frame
->uc
.tuc_link
);
5529 err
|= __put_user(set
->sig
[0], &frame
->uc
.tuc_osf_sigmask
);
5530 err
|= __put_user(target_sigaltstack_used
.ss_sp
,
5531 &frame
->uc
.tuc_stack
.ss_sp
);
5532 err
|= __put_user(sas_ss_flags(env
->ir
[IR_SP
]),
5533 &frame
->uc
.tuc_stack
.ss_flags
);
5534 err
|= __put_user(target_sigaltstack_used
.ss_size
,
5535 &frame
->uc
.tuc_stack
.ss_size
);
5536 err
|= setup_sigcontext(&frame
->uc
.tuc_mcontext
, env
, frame_addr
, set
);
5537 for (i
= 0; i
< TARGET_NSIG_WORDS
; ++i
) {
5538 err
|= __put_user(set
->sig
[i
], &frame
->uc
.tuc_sigmask
.sig
[i
]);
5541 if (ka
->sa_restorer
) {
5542 r26
= ka
->sa_restorer
;
5544 err
|= __put_user(INSN_MOV_R30_R16
, &frame
->retcode
[0]);
5545 err
|= __put_user(INSN_LDI_R0
+ TARGET_NR_rt_sigreturn
,
5546 &frame
->retcode
[1]);
5547 err
|= __put_user(INSN_CALLSYS
, &frame
->retcode
[2]);
5554 if (sig
== TARGET_SIGSEGV
) {
5555 ka
->_sa_handler
= TARGET_SIG_DFL
;
5557 force_sig(TARGET_SIGSEGV
);
5560 env
->ir
[IR_RA
] = r26
;
5561 env
->ir
[IR_PV
] = env
->pc
= ka
->_sa_handler
;
5562 env
->ir
[IR_A0
] = sig
;
5563 env
->ir
[IR_A1
] = frame_addr
+ offsetof(struct target_rt_sigframe
, info
);
5564 env
->ir
[IR_A2
] = frame_addr
+ offsetof(struct target_rt_sigframe
, uc
);
5565 env
->ir
[IR_SP
] = frame_addr
;
5568 long do_sigreturn(CPUAlphaState
*env
)
5570 struct target_sigcontext
*sc
;
5571 abi_ulong sc_addr
= env
->ir
[IR_A0
];
5572 target_sigset_t target_set
;
5575 if (!lock_user_struct(VERIFY_READ
, sc
, sc_addr
, 1)) {
5579 target_sigemptyset(&target_set
);
5580 if (__get_user(target_set
.sig
[0], &sc
->sc_mask
)) {
5584 target_to_host_sigset_internal(&set
, &target_set
);
5585 sigprocmask(SIG_SETMASK
, &set
, NULL
);
5587 if (restore_sigcontext(env
, sc
)) {
5590 unlock_user_struct(sc
, sc_addr
, 0);
5591 return env
->ir
[IR_V0
];
5594 unlock_user_struct(sc
, sc_addr
, 0);
5595 force_sig(TARGET_SIGSEGV
);
5598 long do_rt_sigreturn(CPUAlphaState
*env
)
5600 abi_ulong frame_addr
= env
->ir
[IR_A0
];
5601 struct target_rt_sigframe
*frame
;
5604 if (!lock_user_struct(VERIFY_READ
, frame
, frame_addr
, 1)) {
5607 target_to_host_sigset(&set
, &frame
->uc
.tuc_sigmask
);
5608 sigprocmask(SIG_SETMASK
, &set
, NULL
);
5610 if (restore_sigcontext(env
, &frame
->uc
.tuc_mcontext
)) {
5613 if (do_sigaltstack(frame_addr
+ offsetof(struct target_rt_sigframe
,
5615 0, env
->ir
[IR_SP
]) == -EFAULT
) {
5619 unlock_user_struct(frame
, frame_addr
, 0);
5620 return env
->ir
[IR_V0
];
5624 unlock_user_struct(frame
, frame_addr
, 0);
5625 force_sig(TARGET_SIGSEGV
);
5630 static void setup_frame(int sig
, struct target_sigaction
*ka
,
5631 target_sigset_t
*set
, CPUArchState
*env
)
5633 fprintf(stderr
, "setup_frame: not implemented\n");
5636 static void setup_rt_frame(int sig
, struct target_sigaction
*ka
,
5637 target_siginfo_t
*info
,
5638 target_sigset_t
*set
, CPUArchState
*env
)
5640 fprintf(stderr
, "setup_rt_frame: not implemented\n");
5643 long do_sigreturn(CPUArchState
*env
)
5645 fprintf(stderr
, "do_sigreturn: not implemented\n");
5646 return -TARGET_ENOSYS
;
5649 long do_rt_sigreturn(CPUArchState
*env
)
5651 fprintf(stderr
, "do_rt_sigreturn: not implemented\n");
5652 return -TARGET_ENOSYS
;
5657 void process_pending_signals(CPUArchState
*cpu_env
)
5659 CPUState
*cpu
= ENV_GET_CPU(cpu_env
);
5662 sigset_t set
, old_set
;
5663 target_sigset_t target_old_set
;
5664 struct emulated_sigtable
*k
;
5665 struct target_sigaction
*sa
;
5667 TaskState
*ts
= cpu_env
->opaque
;
5669 if (!ts
->signal_pending
)
5672 /* FIXME: This is not threadsafe. */
5674 for(sig
= 1; sig
<= TARGET_NSIG
; sig
++) {
5679 /* if no signal is pending, just return */
5680 ts
->signal_pending
= 0;
5685 fprintf(stderr
, "qemu: process signal %d\n", sig
);
5687 /* dequeue signal */
5693 sig
= gdb_handlesig(cpu
, sig
);
5696 handler
= TARGET_SIG_IGN
;
5698 sa
= &sigact_table
[sig
- 1];
5699 handler
= sa
->_sa_handler
;
5702 if (handler
== TARGET_SIG_DFL
) {
5703 /* default handler : ignore some signal. The other are job control or fatal */
5704 if (sig
== TARGET_SIGTSTP
|| sig
== TARGET_SIGTTIN
|| sig
== TARGET_SIGTTOU
) {
5705 kill(getpid(),SIGSTOP
);
5706 } else if (sig
!= TARGET_SIGCHLD
&&
5707 sig
!= TARGET_SIGURG
&&
5708 sig
!= TARGET_SIGWINCH
&&
5709 sig
!= TARGET_SIGCONT
) {
5712 } else if (handler
== TARGET_SIG_IGN
) {
5714 } else if (handler
== TARGET_SIG_ERR
) {
5717 /* compute the blocked signals during the handler execution */
5718 target_to_host_sigset(&set
, &sa
->sa_mask
);
5719 /* SA_NODEFER indicates that the current signal should not be
5720 blocked during the handler */
5721 if (!(sa
->sa_flags
& TARGET_SA_NODEFER
))
5722 sigaddset(&set
, target_to_host_signal(sig
));
5724 /* block signals in the handler using Linux */
5725 sigprocmask(SIG_BLOCK
, &set
, &old_set
);
5726 /* save the previous blocked signal state to restore it at the
5727 end of the signal execution (see do_sigreturn) */
5728 host_to_target_sigset_internal(&target_old_set
, &old_set
);
5730 /* if the CPU is in VM86 mode, we restore the 32 bit values */
5731 #if defined(TARGET_I386) && !defined(TARGET_X86_64)
5733 CPUX86State
*env
= cpu_env
;
5734 if (env
->eflags
& VM_MASK
)
5735 save_v86_state(env
);
5738 /* prepare the stack frame of the virtual CPU */
5739 #if defined(TARGET_ABI_MIPSN32) || defined(TARGET_ABI_MIPSN64)
5740 /* These targets do not have traditional signals. */
5741 setup_rt_frame(sig
, sa
, &q
->info
, &target_old_set
, cpu_env
);
5743 if (sa
->sa_flags
& TARGET_SA_SIGINFO
)
5744 setup_rt_frame(sig
, sa
, &q
->info
, &target_old_set
, cpu_env
);
5746 setup_frame(sig
, sa
, &target_old_set
, cpu_env
);
5748 if (sa
->sa_flags
& TARGET_SA_RESETHAND
)
5749 sa
->_sa_handler
= TARGET_SIG_DFL
;
5752 free_sigqueue(cpu_env
, q
);