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 /* Wrapper for sigprocmask function
201 * Emulates a sigprocmask in a safe way for the guest. Note that set and oldset
202 * are host signal set, not guest ones. This wraps the sigprocmask host calls
203 * that should be protected (calls originated from guest)
205 int do_sigprocmask(int how
, const sigset_t
*set
, sigset_t
*oldset
)
209 sigset_t
*temp
= NULL
;
210 CPUState
*cpu
= thread_cpu
;
211 TaskState
*ts
= (TaskState
*)cpu
->opaque
;
212 bool segv_was_blocked
= ts
->sigsegv_blocked
;
215 bool has_sigsegv
= sigismember(set
, SIGSEGV
);
219 sigdelset(temp
, SIGSEGV
);
224 ts
->sigsegv_blocked
= true;
229 ts
->sigsegv_blocked
= false;
233 ts
->sigsegv_blocked
= has_sigsegv
;
236 g_assert_not_reached();
240 ret
= sigprocmask(how
, temp
, oldset
);
242 if (oldset
&& segv_was_blocked
) {
243 sigaddset(oldset
, SIGSEGV
);
249 /* siginfo conversion */
251 static inline void host_to_target_siginfo_noswap(target_siginfo_t
*tinfo
,
252 const siginfo_t
*info
)
254 int sig
= host_to_target_signal(info
->si_signo
);
255 tinfo
->si_signo
= sig
;
257 tinfo
->si_code
= info
->si_code
;
259 if (sig
== TARGET_SIGILL
|| sig
== TARGET_SIGFPE
|| sig
== TARGET_SIGSEGV
260 || sig
== TARGET_SIGBUS
|| sig
== TARGET_SIGTRAP
) {
261 /* Should never come here, but who knows. The information for
262 the target is irrelevant. */
263 tinfo
->_sifields
._sigfault
._addr
= 0;
264 } else if (sig
== TARGET_SIGIO
) {
265 tinfo
->_sifields
._sigpoll
._band
= info
->si_band
;
266 tinfo
->_sifields
._sigpoll
._fd
= info
->si_fd
;
267 } else if (sig
== TARGET_SIGCHLD
) {
268 tinfo
->_sifields
._sigchld
._pid
= info
->si_pid
;
269 tinfo
->_sifields
._sigchld
._uid
= info
->si_uid
;
270 tinfo
->_sifields
._sigchld
._status
271 = host_to_target_waitstatus(info
->si_status
);
272 tinfo
->_sifields
._sigchld
._utime
= info
->si_utime
;
273 tinfo
->_sifields
._sigchld
._stime
= info
->si_stime
;
274 } else if (sig
>= TARGET_SIGRTMIN
) {
275 tinfo
->_sifields
._rt
._pid
= info
->si_pid
;
276 tinfo
->_sifields
._rt
._uid
= info
->si_uid
;
277 /* XXX: potential problem if 64 bit */
278 tinfo
->_sifields
._rt
._sigval
.sival_ptr
279 = (abi_ulong
)(unsigned long)info
->si_value
.sival_ptr
;
283 static void tswap_siginfo(target_siginfo_t
*tinfo
,
284 const target_siginfo_t
*info
)
286 int sig
= info
->si_signo
;
287 tinfo
->si_signo
= tswap32(sig
);
288 tinfo
->si_errno
= tswap32(info
->si_errno
);
289 tinfo
->si_code
= tswap32(info
->si_code
);
291 if (sig
== TARGET_SIGILL
|| sig
== TARGET_SIGFPE
|| sig
== TARGET_SIGSEGV
292 || sig
== TARGET_SIGBUS
|| sig
== TARGET_SIGTRAP
) {
293 tinfo
->_sifields
._sigfault
._addr
294 = tswapal(info
->_sifields
._sigfault
._addr
);
295 } else if (sig
== TARGET_SIGIO
) {
296 tinfo
->_sifields
._sigpoll
._band
297 = tswap32(info
->_sifields
._sigpoll
._band
);
298 tinfo
->_sifields
._sigpoll
._fd
= tswap32(info
->_sifields
._sigpoll
._fd
);
299 } else if (sig
== TARGET_SIGCHLD
) {
300 tinfo
->_sifields
._sigchld
._pid
301 = tswap32(info
->_sifields
._sigchld
._pid
);
302 tinfo
->_sifields
._sigchld
._uid
303 = tswap32(info
->_sifields
._sigchld
._uid
);
304 tinfo
->_sifields
._sigchld
._status
305 = tswap32(info
->_sifields
._sigchld
._status
);
306 tinfo
->_sifields
._sigchld
._utime
307 = tswapal(info
->_sifields
._sigchld
._utime
);
308 tinfo
->_sifields
._sigchld
._stime
309 = tswapal(info
->_sifields
._sigchld
._stime
);
310 } else if (sig
>= TARGET_SIGRTMIN
) {
311 tinfo
->_sifields
._rt
._pid
= tswap32(info
->_sifields
._rt
._pid
);
312 tinfo
->_sifields
._rt
._uid
= tswap32(info
->_sifields
._rt
._uid
);
313 tinfo
->_sifields
._rt
._sigval
.sival_ptr
314 = tswapal(info
->_sifields
._rt
._sigval
.sival_ptr
);
319 void host_to_target_siginfo(target_siginfo_t
*tinfo
, const siginfo_t
*info
)
321 host_to_target_siginfo_noswap(tinfo
, info
);
322 tswap_siginfo(tinfo
, tinfo
);
325 /* XXX: we support only POSIX RT signals are used. */
326 /* XXX: find a solution for 64 bit (additional malloced data is needed) */
327 void target_to_host_siginfo(siginfo_t
*info
, const target_siginfo_t
*tinfo
)
329 info
->si_signo
= tswap32(tinfo
->si_signo
);
330 info
->si_errno
= tswap32(tinfo
->si_errno
);
331 info
->si_code
= tswap32(tinfo
->si_code
);
332 info
->si_pid
= tswap32(tinfo
->_sifields
._rt
._pid
);
333 info
->si_uid
= tswap32(tinfo
->_sifields
._rt
._uid
);
334 info
->si_value
.sival_ptr
=
335 (void *)(long)tswapal(tinfo
->_sifields
._rt
._sigval
.sival_ptr
);
338 static int fatal_signal (int sig
)
343 case TARGET_SIGWINCH
:
344 /* Ignored by default. */
351 /* Job control signals. */
358 /* returns 1 if given signal should dump core if not handled */
359 static int core_dump_signal(int sig
)
375 void signal_init(void)
377 struct sigaction act
;
378 struct sigaction oact
;
382 /* generate signal conversion tables */
383 for(i
= 1; i
< _NSIG
; i
++) {
384 if (host_to_target_signal_table
[i
] == 0)
385 host_to_target_signal_table
[i
] = i
;
387 for(i
= 1; i
< _NSIG
; i
++) {
388 j
= host_to_target_signal_table
[i
];
389 target_to_host_signal_table
[j
] = i
;
392 /* set all host signal handlers. ALL signals are blocked during
393 the handlers to serialize them. */
394 memset(sigact_table
, 0, sizeof(sigact_table
));
396 sigfillset(&act
.sa_mask
);
397 act
.sa_flags
= SA_SIGINFO
;
398 act
.sa_sigaction
= host_signal_handler
;
399 for(i
= 1; i
<= TARGET_NSIG
; i
++) {
400 host_sig
= target_to_host_signal(i
);
401 sigaction(host_sig
, NULL
, &oact
);
402 if (oact
.sa_sigaction
== (void *)SIG_IGN
) {
403 sigact_table
[i
- 1]._sa_handler
= TARGET_SIG_IGN
;
404 } else if (oact
.sa_sigaction
== (void *)SIG_DFL
) {
405 sigact_table
[i
- 1]._sa_handler
= TARGET_SIG_DFL
;
407 /* If there's already a handler installed then something has
408 gone horribly wrong, so don't even try to handle that case. */
409 /* Install some handlers for our own use. We need at least
410 SIGSEGV and SIGBUS, to detect exceptions. We can not just
411 trap all signals because it affects syscall interrupt
412 behavior. But do trap all default-fatal signals. */
413 if (fatal_signal (i
))
414 sigaction(host_sig
, &act
, NULL
);
418 /* signal queue handling */
420 static inline struct sigqueue
*alloc_sigqueue(CPUArchState
*env
)
422 CPUState
*cpu
= ENV_GET_CPU(env
);
423 TaskState
*ts
= cpu
->opaque
;
424 struct sigqueue
*q
= ts
->first_free
;
427 ts
->first_free
= q
->next
;
431 static inline void free_sigqueue(CPUArchState
*env
, struct sigqueue
*q
)
433 CPUState
*cpu
= ENV_GET_CPU(env
);
434 TaskState
*ts
= cpu
->opaque
;
436 q
->next
= ts
->first_free
;
440 /* abort execution with signal */
441 static void QEMU_NORETURN
force_sig(int target_sig
)
443 CPUState
*cpu
= thread_cpu
;
444 CPUArchState
*env
= cpu
->env_ptr
;
445 TaskState
*ts
= (TaskState
*)cpu
->opaque
;
446 int host_sig
, core_dumped
= 0;
447 struct sigaction act
;
448 host_sig
= target_to_host_signal(target_sig
);
449 gdb_signalled(env
, target_sig
);
451 /* dump core if supported by target binary format */
452 if (core_dump_signal(target_sig
) && (ts
->bprm
->core_dump
!= NULL
)) {
455 ((*ts
->bprm
->core_dump
)(target_sig
, env
) == 0);
458 /* we already dumped the core of target process, we don't want
459 * a coredump of qemu itself */
460 struct rlimit nodump
;
461 getrlimit(RLIMIT_CORE
, &nodump
);
463 setrlimit(RLIMIT_CORE
, &nodump
);
464 (void) fprintf(stderr
, "qemu: uncaught target signal %d (%s) - %s\n",
465 target_sig
, strsignal(host_sig
), "core dumped" );
468 /* The proper exit code for dying from an uncaught signal is
469 * -<signal>. The kernel doesn't allow exit() or _exit() to pass
470 * a negative value. To get the proper exit code we need to
471 * actually die from an uncaught signal. Here the default signal
472 * handler is installed, we send ourself a signal and we wait for
474 sigfillset(&act
.sa_mask
);
475 act
.sa_handler
= SIG_DFL
;
477 sigaction(host_sig
, &act
, NULL
);
479 /* For some reason raise(host_sig) doesn't send the signal when
480 * statically linked on x86-64. */
481 kill(getpid(), host_sig
);
483 /* Make sure the signal isn't masked (just reuse the mask inside
485 sigdelset(&act
.sa_mask
, host_sig
);
486 sigsuspend(&act
.sa_mask
);
492 /* queue a signal so that it will be send to the virtual CPU as soon
494 int queue_signal(CPUArchState
*env
, int sig
, target_siginfo_t
*info
)
496 CPUState
*cpu
= ENV_GET_CPU(env
);
497 TaskState
*ts
= cpu
->opaque
;
498 struct emulated_sigtable
*k
;
499 struct sigqueue
*q
, **pq
;
503 #if defined(DEBUG_SIGNAL)
504 fprintf(stderr
, "queue_signal: sig=%d\n",
507 k
= &ts
->sigtab
[sig
- 1];
508 queue
= gdb_queuesig ();
509 handler
= sigact_table
[sig
- 1]._sa_handler
;
511 if (ts
->sigsegv_blocked
&& sig
== TARGET_SIGSEGV
) {
512 /* Guest has blocked SIGSEGV but we got one anyway. Assume this
513 * is a forced SIGSEGV (ie one the kernel handles via force_sig_info
514 * because it got a real MMU fault). A blocked SIGSEGV in that
515 * situation is treated as if using the default handler. This is
516 * not correct if some other process has randomly sent us a SIGSEGV
517 * via kill(), but that is not easy to distinguish at this point,
518 * so we assume it doesn't happen.
520 handler
= TARGET_SIG_DFL
;
523 if (!queue
&& handler
== TARGET_SIG_DFL
) {
524 if (sig
== TARGET_SIGTSTP
|| sig
== TARGET_SIGTTIN
|| sig
== TARGET_SIGTTOU
) {
525 kill(getpid(),SIGSTOP
);
528 /* default handler : ignore some signal. The other are fatal */
529 if (sig
!= TARGET_SIGCHLD
&&
530 sig
!= TARGET_SIGURG
&&
531 sig
!= TARGET_SIGWINCH
&&
532 sig
!= TARGET_SIGCONT
) {
535 return 0; /* indicate ignored */
537 } else if (!queue
&& handler
== TARGET_SIG_IGN
) {
540 } else if (!queue
&& handler
== TARGET_SIG_ERR
) {
544 if (sig
< TARGET_SIGRTMIN
) {
545 /* if non real time signal, we queue exactly one signal */
555 q
= alloc_sigqueue(env
);
566 /* signal that a new signal is pending */
567 ts
->signal_pending
= 1;
568 return 1; /* indicates that the signal was queued */
572 static void host_signal_handler(int host_signum
, siginfo_t
*info
,
575 CPUArchState
*env
= thread_cpu
->env_ptr
;
577 target_siginfo_t tinfo
;
579 /* the CPU emulator uses some host signals to detect exceptions,
580 we forward to it some signals */
581 if ((host_signum
== SIGSEGV
|| host_signum
== SIGBUS
)
582 && info
->si_code
> 0) {
583 if (cpu_signal_handler(host_signum
, info
, puc
))
587 /* get target signal number */
588 sig
= host_to_target_signal(host_signum
);
589 if (sig
< 1 || sig
> TARGET_NSIG
)
591 #if defined(DEBUG_SIGNAL)
592 fprintf(stderr
, "qemu: got signal %d\n", sig
);
594 host_to_target_siginfo_noswap(&tinfo
, info
);
595 if (queue_signal(env
, sig
, &tinfo
) == 1) {
596 /* interrupt the virtual CPU as soon as possible */
597 cpu_exit(thread_cpu
);
601 /* do_sigaltstack() returns target values and errnos. */
602 /* compare linux/kernel/signal.c:do_sigaltstack() */
603 abi_long
do_sigaltstack(abi_ulong uss_addr
, abi_ulong uoss_addr
, abi_ulong sp
)
606 struct target_sigaltstack oss
;
608 /* XXX: test errors */
611 __put_user(target_sigaltstack_used
.ss_sp
, &oss
.ss_sp
);
612 __put_user(target_sigaltstack_used
.ss_size
, &oss
.ss_size
);
613 __put_user(sas_ss_flags(sp
), &oss
.ss_flags
);
618 struct target_sigaltstack
*uss
;
619 struct target_sigaltstack ss
;
621 ret
= -TARGET_EFAULT
;
622 if (!lock_user_struct(VERIFY_READ
, uss
, uss_addr
, 1)) {
625 __get_user(ss
.ss_sp
, &uss
->ss_sp
);
626 __get_user(ss
.ss_size
, &uss
->ss_size
);
627 __get_user(ss
.ss_flags
, &uss
->ss_flags
);
628 unlock_user_struct(uss
, uss_addr
, 0);
631 if (on_sig_stack(sp
))
634 ret
= -TARGET_EINVAL
;
635 if (ss
.ss_flags
!= TARGET_SS_DISABLE
636 && ss
.ss_flags
!= TARGET_SS_ONSTACK
640 if (ss
.ss_flags
== TARGET_SS_DISABLE
) {
644 ret
= -TARGET_ENOMEM
;
645 if (ss
.ss_size
< MINSIGSTKSZ
)
649 target_sigaltstack_used
.ss_sp
= ss
.ss_sp
;
650 target_sigaltstack_used
.ss_size
= ss
.ss_size
;
654 ret
= -TARGET_EFAULT
;
655 if (copy_to_user(uoss_addr
, &oss
, sizeof(oss
)))
664 /* do_sigaction() return host values and errnos */
665 int do_sigaction(int sig
, const struct target_sigaction
*act
,
666 struct target_sigaction
*oact
)
668 struct target_sigaction
*k
;
669 struct sigaction act1
;
673 if (sig
< 1 || sig
> TARGET_NSIG
|| sig
== TARGET_SIGKILL
|| sig
== TARGET_SIGSTOP
)
675 k
= &sigact_table
[sig
- 1];
676 #if defined(DEBUG_SIGNAL)
677 fprintf(stderr
, "sigaction sig=%d act=0x%p, oact=0x%p\n",
681 __put_user(k
->_sa_handler
, &oact
->_sa_handler
);
682 __put_user(k
->sa_flags
, &oact
->sa_flags
);
683 #if !defined(TARGET_MIPS)
684 __put_user(k
->sa_restorer
, &oact
->sa_restorer
);
687 oact
->sa_mask
= k
->sa_mask
;
690 /* FIXME: This is not threadsafe. */
691 __get_user(k
->_sa_handler
, &act
->_sa_handler
);
692 __get_user(k
->sa_flags
, &act
->sa_flags
);
693 #if !defined(TARGET_MIPS)
694 __get_user(k
->sa_restorer
, &act
->sa_restorer
);
696 /* To be swapped in target_to_host_sigset. */
697 k
->sa_mask
= act
->sa_mask
;
699 /* we update the host linux signal state */
700 host_sig
= target_to_host_signal(sig
);
701 if (host_sig
!= SIGSEGV
&& host_sig
!= SIGBUS
) {
702 sigfillset(&act1
.sa_mask
);
703 act1
.sa_flags
= SA_SIGINFO
;
704 if (k
->sa_flags
& TARGET_SA_RESTART
)
705 act1
.sa_flags
|= SA_RESTART
;
706 /* NOTE: it is important to update the host kernel signal
707 ignore state to avoid getting unexpected interrupted
709 if (k
->_sa_handler
== TARGET_SIG_IGN
) {
710 act1
.sa_sigaction
= (void *)SIG_IGN
;
711 } else if (k
->_sa_handler
== TARGET_SIG_DFL
) {
712 if (fatal_signal (sig
))
713 act1
.sa_sigaction
= host_signal_handler
;
715 act1
.sa_sigaction
= (void *)SIG_DFL
;
717 act1
.sa_sigaction
= host_signal_handler
;
719 ret
= sigaction(host_sig
, &act1
, NULL
);
725 static inline void copy_siginfo_to_user(target_siginfo_t
*tinfo
,
726 const target_siginfo_t
*info
)
728 tswap_siginfo(tinfo
, info
);
731 static inline int current_exec_domain_sig(int sig
)
733 return /* current->exec_domain && current->exec_domain->signal_invmap
734 && sig < 32 ? current->exec_domain->signal_invmap[sig] : */ sig
;
737 #if defined(TARGET_I386) && TARGET_ABI_BITS == 32
739 /* from the Linux kernel */
741 struct target_fpreg
{
742 uint16_t significand
[4];
746 struct target_fpxreg
{
747 uint16_t significand
[4];
752 struct target_xmmreg
{
753 abi_ulong element
[4];
756 struct target_fpstate
{
757 /* Regular FPU environment */
765 struct target_fpreg _st
[8];
767 uint16_t magic
; /* 0xffff = regular FPU data only */
769 /* FXSR FPU environment */
770 abi_ulong _fxsr_env
[6]; /* FXSR FPU env is ignored */
773 struct target_fpxreg _fxsr_st
[8]; /* FXSR FPU reg data is ignored */
774 struct target_xmmreg _xmm
[8];
775 abi_ulong padding
[56];
778 #define X86_FXSR_MAGIC 0x0000
780 struct target_sigcontext
{
798 abi_ulong esp_at_signal
;
800 abi_ulong fpstate
; /* pointer */
805 struct target_ucontext
{
808 target_stack_t tuc_stack
;
809 struct target_sigcontext tuc_mcontext
;
810 target_sigset_t tuc_sigmask
; /* mask last for extensibility */
817 struct target_sigcontext sc
;
818 struct target_fpstate fpstate
;
819 abi_ulong extramask
[TARGET_NSIG_WORDS
-1];
829 struct target_siginfo info
;
830 struct target_ucontext uc
;
831 struct target_fpstate fpstate
;
836 * Set up a signal frame.
839 /* XXX: save x87 state */
840 static void setup_sigcontext(struct target_sigcontext
*sc
,
841 struct target_fpstate
*fpstate
, CPUX86State
*env
, abi_ulong mask
,
842 abi_ulong fpstate_addr
)
844 CPUState
*cs
= CPU(x86_env_get_cpu(env
));
847 /* already locked in setup_frame() */
848 __put_user(env
->segs
[R_GS
].selector
, (unsigned int *)&sc
->gs
);
849 __put_user(env
->segs
[R_FS
].selector
, (unsigned int *)&sc
->fs
);
850 __put_user(env
->segs
[R_ES
].selector
, (unsigned int *)&sc
->es
);
851 __put_user(env
->segs
[R_DS
].selector
, (unsigned int *)&sc
->ds
);
852 __put_user(env
->regs
[R_EDI
], &sc
->edi
);
853 __put_user(env
->regs
[R_ESI
], &sc
->esi
);
854 __put_user(env
->regs
[R_EBP
], &sc
->ebp
);
855 __put_user(env
->regs
[R_ESP
], &sc
->esp
);
856 __put_user(env
->regs
[R_EBX
], &sc
->ebx
);
857 __put_user(env
->regs
[R_EDX
], &sc
->edx
);
858 __put_user(env
->regs
[R_ECX
], &sc
->ecx
);
859 __put_user(env
->regs
[R_EAX
], &sc
->eax
);
860 __put_user(cs
->exception_index
, &sc
->trapno
);
861 __put_user(env
->error_code
, &sc
->err
);
862 __put_user(env
->eip
, &sc
->eip
);
863 __put_user(env
->segs
[R_CS
].selector
, (unsigned int *)&sc
->cs
);
864 __put_user(env
->eflags
, &sc
->eflags
);
865 __put_user(env
->regs
[R_ESP
], &sc
->esp_at_signal
);
866 __put_user(env
->segs
[R_SS
].selector
, (unsigned int *)&sc
->ss
);
868 cpu_x86_fsave(env
, fpstate_addr
, 1);
869 fpstate
->status
= fpstate
->sw
;
871 __put_user(magic
, &fpstate
->magic
);
872 __put_user(fpstate_addr
, &sc
->fpstate
);
874 /* non-iBCS2 extensions.. */
875 __put_user(mask
, &sc
->oldmask
);
876 __put_user(env
->cr
[2], &sc
->cr2
);
880 * Determine which stack to use..
883 static inline abi_ulong
884 get_sigframe(struct target_sigaction
*ka
, CPUX86State
*env
, size_t frame_size
)
888 /* Default to using normal stack */
889 esp
= env
->regs
[R_ESP
];
890 /* This is the X/Open sanctioned signal stack switching. */
891 if (ka
->sa_flags
& TARGET_SA_ONSTACK
) {
892 if (sas_ss_flags(esp
) == 0)
893 esp
= target_sigaltstack_used
.ss_sp
+ target_sigaltstack_used
.ss_size
;
896 /* This is the legacy signal stack switching. */
898 if ((env
->segs
[R_SS
].selector
& 0xffff) != __USER_DS
&&
899 !(ka
->sa_flags
& TARGET_SA_RESTORER
) &&
901 esp
= (unsigned long) ka
->sa_restorer
;
903 return (esp
- frame_size
) & -8ul;
906 /* compare linux/arch/i386/kernel/signal.c:setup_frame() */
907 static void setup_frame(int sig
, struct target_sigaction
*ka
,
908 target_sigset_t
*set
, CPUX86State
*env
)
910 abi_ulong frame_addr
;
911 struct sigframe
*frame
;
914 frame_addr
= get_sigframe(ka
, env
, sizeof(*frame
));
916 if (!lock_user_struct(VERIFY_WRITE
, frame
, frame_addr
, 0))
919 __put_user(current_exec_domain_sig(sig
),
922 setup_sigcontext(&frame
->sc
, &frame
->fpstate
, env
, set
->sig
[0],
923 frame_addr
+ offsetof(struct sigframe
, fpstate
));
925 for(i
= 1; i
< TARGET_NSIG_WORDS
; i
++) {
926 __put_user(set
->sig
[i
], &frame
->extramask
[i
- 1]);
929 /* Set up to return from userspace. If provided, use a stub
930 already in userspace. */
931 if (ka
->sa_flags
& TARGET_SA_RESTORER
) {
932 __put_user(ka
->sa_restorer
, &frame
->pretcode
);
935 abi_ulong retcode_addr
;
936 retcode_addr
= frame_addr
+ offsetof(struct sigframe
, retcode
);
937 __put_user(retcode_addr
, &frame
->pretcode
);
938 /* This is popl %eax ; movl $,%eax ; int $0x80 */
940 __put_user(val16
, (uint16_t *)(frame
->retcode
+0));
941 __put_user(TARGET_NR_sigreturn
, (int *)(frame
->retcode
+2));
943 __put_user(val16
, (uint16_t *)(frame
->retcode
+6));
947 /* Set up registers for signal handler */
948 env
->regs
[R_ESP
] = frame_addr
;
949 env
->eip
= ka
->_sa_handler
;
951 cpu_x86_load_seg(env
, R_DS
, __USER_DS
);
952 cpu_x86_load_seg(env
, R_ES
, __USER_DS
);
953 cpu_x86_load_seg(env
, R_SS
, __USER_DS
);
954 cpu_x86_load_seg(env
, R_CS
, __USER_CS
);
955 env
->eflags
&= ~TF_MASK
;
957 unlock_user_struct(frame
, frame_addr
, 1);
962 if (sig
== TARGET_SIGSEGV
)
963 ka
->_sa_handler
= TARGET_SIG_DFL
;
964 force_sig(TARGET_SIGSEGV
/* , current */);
967 /* compare linux/arch/i386/kernel/signal.c:setup_rt_frame() */
968 static void setup_rt_frame(int sig
, struct target_sigaction
*ka
,
969 target_siginfo_t
*info
,
970 target_sigset_t
*set
, CPUX86State
*env
)
972 abi_ulong frame_addr
, addr
;
973 struct rt_sigframe
*frame
;
976 frame_addr
= get_sigframe(ka
, env
, sizeof(*frame
));
978 if (!lock_user_struct(VERIFY_WRITE
, frame
, frame_addr
, 0))
981 __put_user(current_exec_domain_sig(sig
), &frame
->sig
);
982 addr
= frame_addr
+ offsetof(struct rt_sigframe
, info
);
983 __put_user(addr
, &frame
->pinfo
);
984 addr
= frame_addr
+ offsetof(struct rt_sigframe
, uc
);
985 __put_user(addr
, &frame
->puc
);
986 copy_siginfo_to_user(&frame
->info
, info
);
988 /* Create the ucontext. */
989 __put_user(0, &frame
->uc
.tuc_flags
);
990 __put_user(0, &frame
->uc
.tuc_link
);
991 __put_user(target_sigaltstack_used
.ss_sp
, &frame
->uc
.tuc_stack
.ss_sp
);
992 __put_user(sas_ss_flags(get_sp_from_cpustate(env
)),
993 &frame
->uc
.tuc_stack
.ss_flags
);
994 __put_user(target_sigaltstack_used
.ss_size
,
995 &frame
->uc
.tuc_stack
.ss_size
);
996 setup_sigcontext(&frame
->uc
.tuc_mcontext
, &frame
->fpstate
, env
,
997 set
->sig
[0], frame_addr
+ offsetof(struct rt_sigframe
, fpstate
));
999 for(i
= 0; i
< TARGET_NSIG_WORDS
; i
++) {
1000 __put_user(set
->sig
[i
], &frame
->uc
.tuc_sigmask
.sig
[i
]);
1003 /* Set up to return from userspace. If provided, use a stub
1004 already in userspace. */
1005 if (ka
->sa_flags
& TARGET_SA_RESTORER
) {
1006 __put_user(ka
->sa_restorer
, &frame
->pretcode
);
1009 addr
= frame_addr
+ offsetof(struct rt_sigframe
, retcode
);
1010 __put_user(addr
, &frame
->pretcode
);
1011 /* This is movl $,%eax ; int $0x80 */
1012 __put_user(0xb8, (char *)(frame
->retcode
+0));
1013 __put_user(TARGET_NR_rt_sigreturn
, (int *)(frame
->retcode
+1));
1015 __put_user(val16
, (uint16_t *)(frame
->retcode
+5));
1018 /* Set up registers for signal handler */
1019 env
->regs
[R_ESP
] = frame_addr
;
1020 env
->eip
= ka
->_sa_handler
;
1022 cpu_x86_load_seg(env
, R_DS
, __USER_DS
);
1023 cpu_x86_load_seg(env
, R_ES
, __USER_DS
);
1024 cpu_x86_load_seg(env
, R_SS
, __USER_DS
);
1025 cpu_x86_load_seg(env
, R_CS
, __USER_CS
);
1026 env
->eflags
&= ~TF_MASK
;
1028 unlock_user_struct(frame
, frame_addr
, 1);
1033 if (sig
== TARGET_SIGSEGV
)
1034 ka
->_sa_handler
= TARGET_SIG_DFL
;
1035 force_sig(TARGET_SIGSEGV
/* , current */);
1039 restore_sigcontext(CPUX86State
*env
, struct target_sigcontext
*sc
, int *peax
)
1041 unsigned int err
= 0;
1042 abi_ulong fpstate_addr
;
1043 unsigned int tmpflags
;
1045 cpu_x86_load_seg(env
, R_GS
, tswap16(sc
->gs
));
1046 cpu_x86_load_seg(env
, R_FS
, tswap16(sc
->fs
));
1047 cpu_x86_load_seg(env
, R_ES
, tswap16(sc
->es
));
1048 cpu_x86_load_seg(env
, R_DS
, tswap16(sc
->ds
));
1050 env
->regs
[R_EDI
] = tswapl(sc
->edi
);
1051 env
->regs
[R_ESI
] = tswapl(sc
->esi
);
1052 env
->regs
[R_EBP
] = tswapl(sc
->ebp
);
1053 env
->regs
[R_ESP
] = tswapl(sc
->esp
);
1054 env
->regs
[R_EBX
] = tswapl(sc
->ebx
);
1055 env
->regs
[R_EDX
] = tswapl(sc
->edx
);
1056 env
->regs
[R_ECX
] = tswapl(sc
->ecx
);
1057 env
->eip
= tswapl(sc
->eip
);
1059 cpu_x86_load_seg(env
, R_CS
, lduw_p(&sc
->cs
) | 3);
1060 cpu_x86_load_seg(env
, R_SS
, lduw_p(&sc
->ss
) | 3);
1062 tmpflags
= tswapl(sc
->eflags
);
1063 env
->eflags
= (env
->eflags
& ~0x40DD5) | (tmpflags
& 0x40DD5);
1064 // regs->orig_eax = -1; /* disable syscall checks */
1066 fpstate_addr
= tswapl(sc
->fpstate
);
1067 if (fpstate_addr
!= 0) {
1068 if (!access_ok(VERIFY_READ
, fpstate_addr
,
1069 sizeof(struct target_fpstate
)))
1071 cpu_x86_frstor(env
, fpstate_addr
, 1);
1074 *peax
= tswapl(sc
->eax
);
1080 long do_sigreturn(CPUX86State
*env
)
1082 struct sigframe
*frame
;
1083 abi_ulong frame_addr
= env
->regs
[R_ESP
] - 8;
1084 target_sigset_t target_set
;
1088 #if defined(DEBUG_SIGNAL)
1089 fprintf(stderr
, "do_sigreturn\n");
1091 if (!lock_user_struct(VERIFY_READ
, frame
, frame_addr
, 1))
1093 /* set blocked signals */
1094 __get_user(target_set
.sig
[0], &frame
->sc
.oldmask
);
1095 for(i
= 1; i
< TARGET_NSIG_WORDS
; i
++) {
1096 __get_user(target_set
.sig
[i
], &frame
->extramask
[i
- 1]);
1099 target_to_host_sigset_internal(&set
, &target_set
);
1100 do_sigprocmask(SIG_SETMASK
, &set
, NULL
);
1102 /* restore registers */
1103 if (restore_sigcontext(env
, &frame
->sc
, &eax
))
1105 unlock_user_struct(frame
, frame_addr
, 0);
1109 unlock_user_struct(frame
, frame_addr
, 0);
1110 force_sig(TARGET_SIGSEGV
);
1114 long do_rt_sigreturn(CPUX86State
*env
)
1116 abi_ulong frame_addr
;
1117 struct rt_sigframe
*frame
;
1121 frame_addr
= env
->regs
[R_ESP
] - 4;
1122 if (!lock_user_struct(VERIFY_READ
, frame
, frame_addr
, 1))
1124 target_to_host_sigset(&set
, &frame
->uc
.tuc_sigmask
);
1125 do_sigprocmask(SIG_SETMASK
, &set
, NULL
);
1127 if (restore_sigcontext(env
, &frame
->uc
.tuc_mcontext
, &eax
))
1130 if (do_sigaltstack(frame_addr
+ offsetof(struct rt_sigframe
, uc
.tuc_stack
), 0,
1131 get_sp_from_cpustate(env
)) == -EFAULT
)
1134 unlock_user_struct(frame
, frame_addr
, 0);
1138 unlock_user_struct(frame
, frame_addr
, 0);
1139 force_sig(TARGET_SIGSEGV
);
1143 #elif defined(TARGET_AARCH64)
1145 struct target_sigcontext
{
1146 uint64_t fault_address
;
1147 /* AArch64 registers */
1152 /* 4K reserved for FP/SIMD state and future expansion */
1153 char __reserved
[4096] __attribute__((__aligned__(16)));
1156 struct target_ucontext
{
1157 abi_ulong tuc_flags
;
1159 target_stack_t tuc_stack
;
1160 target_sigset_t tuc_sigmask
;
1161 /* glibc uses a 1024-bit sigset_t */
1162 char __unused
[1024 / 8 - sizeof(target_sigset_t
)];
1163 /* last for future expansion */
1164 struct target_sigcontext tuc_mcontext
;
1168 * Header to be used at the beginning of structures extending the user
1169 * context. Such structures must be placed after the rt_sigframe on the stack
1170 * and be 16-byte aligned. The last structure must be a dummy one with the
1171 * magic and size set to 0.
1173 struct target_aarch64_ctx
{
1178 #define TARGET_FPSIMD_MAGIC 0x46508001
1180 struct target_fpsimd_context
{
1181 struct target_aarch64_ctx head
;
1184 uint64_t vregs
[32 * 2]; /* really uint128_t vregs[32] */
1188 * Auxiliary context saved in the sigcontext.__reserved array. Not exported to
1189 * user space as it will change with the addition of new context. User space
1190 * should check the magic/size information.
1192 struct target_aux_context
{
1193 struct target_fpsimd_context fpsimd
;
1194 /* additional context to be added before "end" */
1195 struct target_aarch64_ctx end
;
1198 struct target_rt_sigframe
{
1199 struct target_siginfo info
;
1200 struct target_ucontext uc
;
1206 static int target_setup_sigframe(struct target_rt_sigframe
*sf
,
1207 CPUARMState
*env
, target_sigset_t
*set
)
1210 struct target_aux_context
*aux
=
1211 (struct target_aux_context
*)sf
->uc
.tuc_mcontext
.__reserved
;
1213 /* set up the stack frame for unwinding */
1214 __put_user(env
->xregs
[29], &sf
->fp
);
1215 __put_user(env
->xregs
[30], &sf
->lr
);
1217 for (i
= 0; i
< 31; i
++) {
1218 __put_user(env
->xregs
[i
], &sf
->uc
.tuc_mcontext
.regs
[i
]);
1220 __put_user(env
->xregs
[31], &sf
->uc
.tuc_mcontext
.sp
);
1221 __put_user(env
->pc
, &sf
->uc
.tuc_mcontext
.pc
);
1222 __put_user(pstate_read(env
), &sf
->uc
.tuc_mcontext
.pstate
);
1224 __put_user(env
->exception
.vaddress
, &sf
->uc
.tuc_mcontext
.fault_address
);
1226 for (i
= 0; i
< TARGET_NSIG_WORDS
; i
++) {
1227 __put_user(set
->sig
[i
], &sf
->uc
.tuc_sigmask
.sig
[i
]);
1230 for (i
= 0; i
< 32; i
++) {
1231 #ifdef TARGET_WORDS_BIGENDIAN
1232 __put_user(env
->vfp
.regs
[i
* 2], &aux
->fpsimd
.vregs
[i
* 2 + 1]);
1233 __put_user(env
->vfp
.regs
[i
* 2 + 1], &aux
->fpsimd
.vregs
[i
* 2]);
1235 __put_user(env
->vfp
.regs
[i
* 2], &aux
->fpsimd
.vregs
[i
* 2]);
1236 __put_user(env
->vfp
.regs
[i
* 2 + 1], &aux
->fpsimd
.vregs
[i
* 2 + 1]);
1239 __put_user(vfp_get_fpsr(env
), &aux
->fpsimd
.fpsr
);
1240 __put_user(vfp_get_fpcr(env
), &aux
->fpsimd
.fpcr
);
1241 __put_user(TARGET_FPSIMD_MAGIC
, &aux
->fpsimd
.head
.magic
);
1242 __put_user(sizeof(struct target_fpsimd_context
),
1243 &aux
->fpsimd
.head
.size
);
1245 /* set the "end" magic */
1246 __put_user(0, &aux
->end
.magic
);
1247 __put_user(0, &aux
->end
.size
);
1252 static int target_restore_sigframe(CPUARMState
*env
,
1253 struct target_rt_sigframe
*sf
)
1257 struct target_aux_context
*aux
=
1258 (struct target_aux_context
*)sf
->uc
.tuc_mcontext
.__reserved
;
1259 uint32_t magic
, size
, fpsr
, fpcr
;
1262 target_to_host_sigset(&set
, &sf
->uc
.tuc_sigmask
);
1263 do_sigprocmask(SIG_SETMASK
, &set
, NULL
);
1265 for (i
= 0; i
< 31; i
++) {
1266 __get_user(env
->xregs
[i
], &sf
->uc
.tuc_mcontext
.regs
[i
]);
1269 __get_user(env
->xregs
[31], &sf
->uc
.tuc_mcontext
.sp
);
1270 __get_user(env
->pc
, &sf
->uc
.tuc_mcontext
.pc
);
1271 __get_user(pstate
, &sf
->uc
.tuc_mcontext
.pstate
);
1272 pstate_write(env
, pstate
);
1274 __get_user(magic
, &aux
->fpsimd
.head
.magic
);
1275 __get_user(size
, &aux
->fpsimd
.head
.size
);
1277 if (magic
!= TARGET_FPSIMD_MAGIC
1278 || size
!= sizeof(struct target_fpsimd_context
)) {
1282 for (i
= 0; i
< 32; i
++) {
1283 #ifdef TARGET_WORDS_BIGENDIAN
1284 __get_user(env
->vfp
.regs
[i
* 2], &aux
->fpsimd
.vregs
[i
* 2 + 1]);
1285 __get_user(env
->vfp
.regs
[i
* 2 + 1], &aux
->fpsimd
.vregs
[i
* 2]);
1287 __get_user(env
->vfp
.regs
[i
* 2], &aux
->fpsimd
.vregs
[i
* 2]);
1288 __get_user(env
->vfp
.regs
[i
* 2 + 1], &aux
->fpsimd
.vregs
[i
* 2 + 1]);
1291 __get_user(fpsr
, &aux
->fpsimd
.fpsr
);
1292 vfp_set_fpsr(env
, fpsr
);
1293 __get_user(fpcr
, &aux
->fpsimd
.fpcr
);
1294 vfp_set_fpcr(env
, fpcr
);
1299 static abi_ulong
get_sigframe(struct target_sigaction
*ka
, CPUARMState
*env
)
1303 sp
= env
->xregs
[31];
1306 * This is the X/Open sanctioned signal stack switching.
1308 if ((ka
->sa_flags
& SA_ONSTACK
) && !sas_ss_flags(sp
)) {
1309 sp
= target_sigaltstack_used
.ss_sp
+ target_sigaltstack_used
.ss_size
;
1312 sp
= (sp
- sizeof(struct target_rt_sigframe
)) & ~15;
1317 static void target_setup_frame(int usig
, struct target_sigaction
*ka
,
1318 target_siginfo_t
*info
, target_sigset_t
*set
,
1321 struct target_rt_sigframe
*frame
;
1322 abi_ulong frame_addr
, return_addr
;
1324 frame_addr
= get_sigframe(ka
, env
);
1325 if (!lock_user_struct(VERIFY_WRITE
, frame
, frame_addr
, 0)) {
1329 __put_user(0, &frame
->uc
.tuc_flags
);
1330 __put_user(0, &frame
->uc
.tuc_link
);
1332 __put_user(target_sigaltstack_used
.ss_sp
,
1333 &frame
->uc
.tuc_stack
.ss_sp
);
1334 __put_user(sas_ss_flags(env
->xregs
[31]),
1335 &frame
->uc
.tuc_stack
.ss_flags
);
1336 __put_user(target_sigaltstack_used
.ss_size
,
1337 &frame
->uc
.tuc_stack
.ss_size
);
1338 target_setup_sigframe(frame
, env
, set
);
1339 if (ka
->sa_flags
& TARGET_SA_RESTORER
) {
1340 return_addr
= ka
->sa_restorer
;
1342 /* mov x8,#__NR_rt_sigreturn; svc #0 */
1343 __put_user(0xd2801168, &frame
->tramp
[0]);
1344 __put_user(0xd4000001, &frame
->tramp
[1]);
1345 return_addr
= frame_addr
+ offsetof(struct target_rt_sigframe
, tramp
);
1347 env
->xregs
[0] = usig
;
1348 env
->xregs
[31] = frame_addr
;
1349 env
->xregs
[29] = env
->xregs
[31] + offsetof(struct target_rt_sigframe
, fp
);
1350 env
->pc
= ka
->_sa_handler
;
1351 env
->xregs
[30] = return_addr
;
1353 copy_siginfo_to_user(&frame
->info
, info
);
1354 env
->xregs
[1] = frame_addr
+ offsetof(struct target_rt_sigframe
, info
);
1355 env
->xregs
[2] = frame_addr
+ offsetof(struct target_rt_sigframe
, uc
);
1358 unlock_user_struct(frame
, frame_addr
, 1);
1362 unlock_user_struct(frame
, frame_addr
, 1);
1363 force_sig(TARGET_SIGSEGV
);
1366 static void setup_rt_frame(int sig
, struct target_sigaction
*ka
,
1367 target_siginfo_t
*info
, target_sigset_t
*set
,
1370 target_setup_frame(sig
, ka
, info
, set
, env
);
1373 static void setup_frame(int sig
, struct target_sigaction
*ka
,
1374 target_sigset_t
*set
, CPUARMState
*env
)
1376 target_setup_frame(sig
, ka
, 0, set
, env
);
1379 long do_rt_sigreturn(CPUARMState
*env
)
1381 struct target_rt_sigframe
*frame
= NULL
;
1382 abi_ulong frame_addr
= env
->xregs
[31];
1384 if (frame_addr
& 15) {
1388 if (!lock_user_struct(VERIFY_READ
, frame
, frame_addr
, 1)) {
1392 if (target_restore_sigframe(env
, frame
)) {
1396 if (do_sigaltstack(frame_addr
+
1397 offsetof(struct target_rt_sigframe
, uc
.tuc_stack
),
1398 0, get_sp_from_cpustate(env
)) == -EFAULT
) {
1402 unlock_user_struct(frame
, frame_addr
, 0);
1403 return env
->xregs
[0];
1406 unlock_user_struct(frame
, frame_addr
, 0);
1407 force_sig(TARGET_SIGSEGV
);
1411 long do_sigreturn(CPUARMState
*env
)
1413 return do_rt_sigreturn(env
);
1416 #elif defined(TARGET_ARM)
1418 struct target_sigcontext
{
1420 abi_ulong error_code
;
1439 abi_ulong fault_address
;
1442 struct target_ucontext_v1
{
1443 abi_ulong tuc_flags
;
1445 target_stack_t tuc_stack
;
1446 struct target_sigcontext tuc_mcontext
;
1447 target_sigset_t tuc_sigmask
; /* mask last for extensibility */
1450 struct target_ucontext_v2
{
1451 abi_ulong tuc_flags
;
1453 target_stack_t tuc_stack
;
1454 struct target_sigcontext tuc_mcontext
;
1455 target_sigset_t tuc_sigmask
; /* mask last for extensibility */
1456 char __unused
[128 - sizeof(target_sigset_t
)];
1457 abi_ulong tuc_regspace
[128] __attribute__((__aligned__(8)));
1460 struct target_user_vfp
{
1461 uint64_t fpregs
[32];
1465 struct target_user_vfp_exc
{
1471 struct target_vfp_sigframe
{
1474 struct target_user_vfp ufp
;
1475 struct target_user_vfp_exc ufp_exc
;
1476 } __attribute__((__aligned__(8)));
1478 struct target_iwmmxt_sigframe
{
1482 /* Note that not all the coprocessor control registers are stored here */
1489 } __attribute__((__aligned__(8)));
1491 #define TARGET_VFP_MAGIC 0x56465001
1492 #define TARGET_IWMMXT_MAGIC 0x12ef842a
1496 struct target_sigcontext sc
;
1497 abi_ulong extramask
[TARGET_NSIG_WORDS
-1];
1503 struct target_ucontext_v2 uc
;
1507 struct rt_sigframe_v1
1511 struct target_siginfo info
;
1512 struct target_ucontext_v1 uc
;
1516 struct rt_sigframe_v2
1518 struct target_siginfo info
;
1519 struct target_ucontext_v2 uc
;
1523 #define TARGET_CONFIG_CPU_32 1
1526 * For ARM syscalls, we encode the syscall number into the instruction.
1528 #define SWI_SYS_SIGRETURN (0xef000000|(TARGET_NR_sigreturn + ARM_SYSCALL_BASE))
1529 #define SWI_SYS_RT_SIGRETURN (0xef000000|(TARGET_NR_rt_sigreturn + ARM_SYSCALL_BASE))
1532 * For Thumb syscalls, we pass the syscall number via r7. We therefore
1533 * need two 16-bit instructions.
1535 #define SWI_THUMB_SIGRETURN (0xdf00 << 16 | 0x2700 | (TARGET_NR_sigreturn))
1536 #define SWI_THUMB_RT_SIGRETURN (0xdf00 << 16 | 0x2700 | (TARGET_NR_rt_sigreturn))
1538 static const abi_ulong retcodes
[4] = {
1539 SWI_SYS_SIGRETURN
, SWI_THUMB_SIGRETURN
,
1540 SWI_SYS_RT_SIGRETURN
, SWI_THUMB_RT_SIGRETURN
1544 static inline int valid_user_regs(CPUARMState
*regs
)
1550 setup_sigcontext(struct target_sigcontext
*sc
, /*struct _fpstate *fpstate,*/
1551 CPUARMState
*env
, abi_ulong mask
)
1553 __put_user(env
->regs
[0], &sc
->arm_r0
);
1554 __put_user(env
->regs
[1], &sc
->arm_r1
);
1555 __put_user(env
->regs
[2], &sc
->arm_r2
);
1556 __put_user(env
->regs
[3], &sc
->arm_r3
);
1557 __put_user(env
->regs
[4], &sc
->arm_r4
);
1558 __put_user(env
->regs
[5], &sc
->arm_r5
);
1559 __put_user(env
->regs
[6], &sc
->arm_r6
);
1560 __put_user(env
->regs
[7], &sc
->arm_r7
);
1561 __put_user(env
->regs
[8], &sc
->arm_r8
);
1562 __put_user(env
->regs
[9], &sc
->arm_r9
);
1563 __put_user(env
->regs
[10], &sc
->arm_r10
);
1564 __put_user(env
->regs
[11], &sc
->arm_fp
);
1565 __put_user(env
->regs
[12], &sc
->arm_ip
);
1566 __put_user(env
->regs
[13], &sc
->arm_sp
);
1567 __put_user(env
->regs
[14], &sc
->arm_lr
);
1568 __put_user(env
->regs
[15], &sc
->arm_pc
);
1569 #ifdef TARGET_CONFIG_CPU_32
1570 __put_user(cpsr_read(env
), &sc
->arm_cpsr
);
1573 __put_user(/* current->thread.trap_no */ 0, &sc
->trap_no
);
1574 __put_user(/* current->thread.error_code */ 0, &sc
->error_code
);
1575 __put_user(/* current->thread.address */ 0, &sc
->fault_address
);
1576 __put_user(mask
, &sc
->oldmask
);
1579 static inline abi_ulong
1580 get_sigframe(struct target_sigaction
*ka
, CPUARMState
*regs
, int framesize
)
1582 unsigned long sp
= regs
->regs
[13];
1585 * This is the X/Open sanctioned signal stack switching.
1587 if ((ka
->sa_flags
& TARGET_SA_ONSTACK
) && !sas_ss_flags(sp
))
1588 sp
= target_sigaltstack_used
.ss_sp
+ target_sigaltstack_used
.ss_size
;
1590 * ATPCS B01 mandates 8-byte alignment
1592 return (sp
- framesize
) & ~7;
1596 setup_return(CPUARMState
*env
, struct target_sigaction
*ka
,
1597 abi_ulong
*rc
, abi_ulong frame_addr
, int usig
, abi_ulong rc_addr
)
1599 abi_ulong handler
= ka
->_sa_handler
;
1601 int thumb
= handler
& 1;
1602 uint32_t cpsr
= cpsr_read(env
);
1611 if (ka
->sa_flags
& TARGET_SA_RESTORER
) {
1612 retcode
= ka
->sa_restorer
;
1614 unsigned int idx
= thumb
;
1616 if (ka
->sa_flags
& TARGET_SA_SIGINFO
)
1619 __put_user(retcodes
[idx
], rc
);
1621 retcode
= rc_addr
+ thumb
;
1624 env
->regs
[0] = usig
;
1625 env
->regs
[13] = frame_addr
;
1626 env
->regs
[14] = retcode
;
1627 env
->regs
[15] = handler
& (thumb
? ~1 : ~3);
1628 cpsr_write(env
, cpsr
, 0xffffffff);
1631 static abi_ulong
*setup_sigframe_v2_vfp(abi_ulong
*regspace
, CPUARMState
*env
)
1634 struct target_vfp_sigframe
*vfpframe
;
1635 vfpframe
= (struct target_vfp_sigframe
*)regspace
;
1636 __put_user(TARGET_VFP_MAGIC
, &vfpframe
->magic
);
1637 __put_user(sizeof(*vfpframe
), &vfpframe
->size
);
1638 for (i
= 0; i
< 32; i
++) {
1639 __put_user(float64_val(env
->vfp
.regs
[i
]), &vfpframe
->ufp
.fpregs
[i
]);
1641 __put_user(vfp_get_fpscr(env
), &vfpframe
->ufp
.fpscr
);
1642 __put_user(env
->vfp
.xregs
[ARM_VFP_FPEXC
], &vfpframe
->ufp_exc
.fpexc
);
1643 __put_user(env
->vfp
.xregs
[ARM_VFP_FPINST
], &vfpframe
->ufp_exc
.fpinst
);
1644 __put_user(env
->vfp
.xregs
[ARM_VFP_FPINST2
], &vfpframe
->ufp_exc
.fpinst2
);
1645 return (abi_ulong
*)(vfpframe
+1);
1648 static abi_ulong
*setup_sigframe_v2_iwmmxt(abi_ulong
*regspace
,
1652 struct target_iwmmxt_sigframe
*iwmmxtframe
;
1653 iwmmxtframe
= (struct target_iwmmxt_sigframe
*)regspace
;
1654 __put_user(TARGET_IWMMXT_MAGIC
, &iwmmxtframe
->magic
);
1655 __put_user(sizeof(*iwmmxtframe
), &iwmmxtframe
->size
);
1656 for (i
= 0; i
< 16; i
++) {
1657 __put_user(env
->iwmmxt
.regs
[i
], &iwmmxtframe
->regs
[i
]);
1659 __put_user(env
->vfp
.xregs
[ARM_IWMMXT_wCSSF
], &iwmmxtframe
->wcssf
);
1660 __put_user(env
->vfp
.xregs
[ARM_IWMMXT_wCASF
], &iwmmxtframe
->wcssf
);
1661 __put_user(env
->vfp
.xregs
[ARM_IWMMXT_wCGR0
], &iwmmxtframe
->wcgr0
);
1662 __put_user(env
->vfp
.xregs
[ARM_IWMMXT_wCGR1
], &iwmmxtframe
->wcgr1
);
1663 __put_user(env
->vfp
.xregs
[ARM_IWMMXT_wCGR2
], &iwmmxtframe
->wcgr2
);
1664 __put_user(env
->vfp
.xregs
[ARM_IWMMXT_wCGR3
], &iwmmxtframe
->wcgr3
);
1665 return (abi_ulong
*)(iwmmxtframe
+1);
1668 static void setup_sigframe_v2(struct target_ucontext_v2
*uc
,
1669 target_sigset_t
*set
, CPUARMState
*env
)
1671 struct target_sigaltstack stack
;
1673 abi_ulong
*regspace
;
1675 /* Clear all the bits of the ucontext we don't use. */
1676 memset(uc
, 0, offsetof(struct target_ucontext_v2
, tuc_mcontext
));
1678 memset(&stack
, 0, sizeof(stack
));
1679 __put_user(target_sigaltstack_used
.ss_sp
, &stack
.ss_sp
);
1680 __put_user(target_sigaltstack_used
.ss_size
, &stack
.ss_size
);
1681 __put_user(sas_ss_flags(get_sp_from_cpustate(env
)), &stack
.ss_flags
);
1682 memcpy(&uc
->tuc_stack
, &stack
, sizeof(stack
));
1684 setup_sigcontext(&uc
->tuc_mcontext
, env
, set
->sig
[0]);
1685 /* Save coprocessor signal frame. */
1686 regspace
= uc
->tuc_regspace
;
1687 if (arm_feature(env
, ARM_FEATURE_VFP
)) {
1688 regspace
= setup_sigframe_v2_vfp(regspace
, env
);
1690 if (arm_feature(env
, ARM_FEATURE_IWMMXT
)) {
1691 regspace
= setup_sigframe_v2_iwmmxt(regspace
, env
);
1694 /* Write terminating magic word */
1695 __put_user(0, regspace
);
1697 for(i
= 0; i
< TARGET_NSIG_WORDS
; i
++) {
1698 __put_user(set
->sig
[i
], &uc
->tuc_sigmask
.sig
[i
]);
1702 /* compare linux/arch/arm/kernel/signal.c:setup_frame() */
1703 static void setup_frame_v1(int usig
, struct target_sigaction
*ka
,
1704 target_sigset_t
*set
, CPUARMState
*regs
)
1706 struct sigframe_v1
*frame
;
1707 abi_ulong frame_addr
= get_sigframe(ka
, regs
, sizeof(*frame
));
1710 if (!lock_user_struct(VERIFY_WRITE
, frame
, frame_addr
, 0))
1713 setup_sigcontext(&frame
->sc
, regs
, set
->sig
[0]);
1715 for(i
= 1; i
< TARGET_NSIG_WORDS
; i
++) {
1716 __put_user(set
->sig
[i
], &frame
->extramask
[i
- 1]);
1719 setup_return(regs
, ka
, &frame
->retcode
, frame_addr
, usig
,
1720 frame_addr
+ offsetof(struct sigframe_v1
, retcode
));
1722 unlock_user_struct(frame
, frame_addr
, 1);
1725 static void setup_frame_v2(int usig
, struct target_sigaction
*ka
,
1726 target_sigset_t
*set
, CPUARMState
*regs
)
1728 struct sigframe_v2
*frame
;
1729 abi_ulong frame_addr
= get_sigframe(ka
, regs
, sizeof(*frame
));
1731 if (!lock_user_struct(VERIFY_WRITE
, frame
, frame_addr
, 0))
1734 setup_sigframe_v2(&frame
->uc
, set
, regs
);
1736 setup_return(regs
, ka
, &frame
->retcode
, frame_addr
, usig
,
1737 frame_addr
+ offsetof(struct sigframe_v2
, retcode
));
1739 unlock_user_struct(frame
, frame_addr
, 1);
1742 static void setup_frame(int usig
, struct target_sigaction
*ka
,
1743 target_sigset_t
*set
, CPUARMState
*regs
)
1745 if (get_osversion() >= 0x020612) {
1746 setup_frame_v2(usig
, ka
, set
, regs
);
1748 setup_frame_v1(usig
, ka
, set
, regs
);
1752 /* compare linux/arch/arm/kernel/signal.c:setup_rt_frame() */
1753 static void setup_rt_frame_v1(int usig
, struct target_sigaction
*ka
,
1754 target_siginfo_t
*info
,
1755 target_sigset_t
*set
, CPUARMState
*env
)
1757 struct rt_sigframe_v1
*frame
;
1758 abi_ulong frame_addr
= get_sigframe(ka
, env
, sizeof(*frame
));
1759 struct target_sigaltstack stack
;
1761 abi_ulong info_addr
, uc_addr
;
1763 if (!lock_user_struct(VERIFY_WRITE
, frame
, frame_addr
, 0))
1766 info_addr
= frame_addr
+ offsetof(struct rt_sigframe_v1
, info
);
1767 __put_user(info_addr
, &frame
->pinfo
);
1768 uc_addr
= frame_addr
+ offsetof(struct rt_sigframe_v1
, uc
);
1769 __put_user(uc_addr
, &frame
->puc
);
1770 copy_siginfo_to_user(&frame
->info
, info
);
1772 /* Clear all the bits of the ucontext we don't use. */
1773 memset(&frame
->uc
, 0, offsetof(struct target_ucontext_v1
, tuc_mcontext
));
1775 memset(&stack
, 0, sizeof(stack
));
1776 __put_user(target_sigaltstack_used
.ss_sp
, &stack
.ss_sp
);
1777 __put_user(target_sigaltstack_used
.ss_size
, &stack
.ss_size
);
1778 __put_user(sas_ss_flags(get_sp_from_cpustate(env
)), &stack
.ss_flags
);
1779 memcpy(&frame
->uc
.tuc_stack
, &stack
, sizeof(stack
));
1781 setup_sigcontext(&frame
->uc
.tuc_mcontext
, env
, set
->sig
[0]);
1782 for(i
= 0; i
< TARGET_NSIG_WORDS
; i
++) {
1783 __put_user(set
->sig
[i
], &frame
->uc
.tuc_sigmask
.sig
[i
]);
1786 setup_return(env
, ka
, &frame
->retcode
, frame_addr
, usig
,
1787 frame_addr
+ offsetof(struct rt_sigframe_v1
, retcode
));
1789 env
->regs
[1] = info_addr
;
1790 env
->regs
[2] = uc_addr
;
1792 unlock_user_struct(frame
, frame_addr
, 1);
1795 static void setup_rt_frame_v2(int usig
, struct target_sigaction
*ka
,
1796 target_siginfo_t
*info
,
1797 target_sigset_t
*set
, CPUARMState
*env
)
1799 struct rt_sigframe_v2
*frame
;
1800 abi_ulong frame_addr
= get_sigframe(ka
, env
, sizeof(*frame
));
1801 abi_ulong info_addr
, uc_addr
;
1803 if (!lock_user_struct(VERIFY_WRITE
, frame
, frame_addr
, 0))
1806 info_addr
= frame_addr
+ offsetof(struct rt_sigframe_v2
, info
);
1807 uc_addr
= frame_addr
+ offsetof(struct rt_sigframe_v2
, uc
);
1808 copy_siginfo_to_user(&frame
->info
, info
);
1810 setup_sigframe_v2(&frame
->uc
, set
, env
);
1812 setup_return(env
, ka
, &frame
->retcode
, frame_addr
, usig
,
1813 frame_addr
+ offsetof(struct rt_sigframe_v2
, retcode
));
1815 env
->regs
[1] = info_addr
;
1816 env
->regs
[2] = uc_addr
;
1818 unlock_user_struct(frame
, frame_addr
, 1);
1821 static void setup_rt_frame(int usig
, struct target_sigaction
*ka
,
1822 target_siginfo_t
*info
,
1823 target_sigset_t
*set
, CPUARMState
*env
)
1825 if (get_osversion() >= 0x020612) {
1826 setup_rt_frame_v2(usig
, ka
, info
, set
, env
);
1828 setup_rt_frame_v1(usig
, ka
, info
, set
, env
);
1833 restore_sigcontext(CPUARMState
*env
, struct target_sigcontext
*sc
)
1838 __get_user(env
->regs
[0], &sc
->arm_r0
);
1839 __get_user(env
->regs
[1], &sc
->arm_r1
);
1840 __get_user(env
->regs
[2], &sc
->arm_r2
);
1841 __get_user(env
->regs
[3], &sc
->arm_r3
);
1842 __get_user(env
->regs
[4], &sc
->arm_r4
);
1843 __get_user(env
->regs
[5], &sc
->arm_r5
);
1844 __get_user(env
->regs
[6], &sc
->arm_r6
);
1845 __get_user(env
->regs
[7], &sc
->arm_r7
);
1846 __get_user(env
->regs
[8], &sc
->arm_r8
);
1847 __get_user(env
->regs
[9], &sc
->arm_r9
);
1848 __get_user(env
->regs
[10], &sc
->arm_r10
);
1849 __get_user(env
->regs
[11], &sc
->arm_fp
);
1850 __get_user(env
->regs
[12], &sc
->arm_ip
);
1851 __get_user(env
->regs
[13], &sc
->arm_sp
);
1852 __get_user(env
->regs
[14], &sc
->arm_lr
);
1853 __get_user(env
->regs
[15], &sc
->arm_pc
);
1854 #ifdef TARGET_CONFIG_CPU_32
1855 __get_user(cpsr
, &sc
->arm_cpsr
);
1856 cpsr_write(env
, cpsr
, CPSR_USER
| CPSR_EXEC
);
1859 err
|= !valid_user_regs(env
);
1864 static long do_sigreturn_v1(CPUARMState
*env
)
1866 abi_ulong frame_addr
;
1867 struct sigframe_v1
*frame
= NULL
;
1868 target_sigset_t set
;
1873 * Since we stacked the signal on a 64-bit boundary,
1874 * then 'sp' should be word aligned here. If it's
1875 * not, then the user is trying to mess with us.
1877 frame_addr
= env
->regs
[13];
1878 if (frame_addr
& 7) {
1882 if (!lock_user_struct(VERIFY_READ
, frame
, frame_addr
, 1))
1885 __get_user(set
.sig
[0], &frame
->sc
.oldmask
);
1886 for(i
= 1; i
< TARGET_NSIG_WORDS
; i
++) {
1887 __get_user(set
.sig
[i
], &frame
->extramask
[i
- 1]);
1890 target_to_host_sigset_internal(&host_set
, &set
);
1891 do_sigprocmask(SIG_SETMASK
, &host_set
, NULL
);
1893 if (restore_sigcontext(env
, &frame
->sc
))
1897 /* Send SIGTRAP if we're single-stepping */
1898 if (ptrace_cancel_bpt(current
))
1899 send_sig(SIGTRAP
, current
, 1);
1901 unlock_user_struct(frame
, frame_addr
, 0);
1902 return env
->regs
[0];
1905 force_sig(TARGET_SIGSEGV
/* , current */);
1909 static abi_ulong
*restore_sigframe_v2_vfp(CPUARMState
*env
, abi_ulong
*regspace
)
1912 abi_ulong magic
, sz
;
1913 uint32_t fpscr
, fpexc
;
1914 struct target_vfp_sigframe
*vfpframe
;
1915 vfpframe
= (struct target_vfp_sigframe
*)regspace
;
1917 __get_user(magic
, &vfpframe
->magic
);
1918 __get_user(sz
, &vfpframe
->size
);
1919 if (magic
!= TARGET_VFP_MAGIC
|| sz
!= sizeof(*vfpframe
)) {
1922 for (i
= 0; i
< 32; i
++) {
1923 __get_user(float64_val(env
->vfp
.regs
[i
]), &vfpframe
->ufp
.fpregs
[i
]);
1925 __get_user(fpscr
, &vfpframe
->ufp
.fpscr
);
1926 vfp_set_fpscr(env
, fpscr
);
1927 __get_user(fpexc
, &vfpframe
->ufp_exc
.fpexc
);
1928 /* Sanitise FPEXC: ensure VFP is enabled, FPINST2 is invalid
1929 * and the exception flag is cleared
1932 fpexc
&= ~((1 << 31) | (1 << 28));
1933 env
->vfp
.xregs
[ARM_VFP_FPEXC
] = fpexc
;
1934 __get_user(env
->vfp
.xregs
[ARM_VFP_FPINST
], &vfpframe
->ufp_exc
.fpinst
);
1935 __get_user(env
->vfp
.xregs
[ARM_VFP_FPINST2
], &vfpframe
->ufp_exc
.fpinst2
);
1936 return (abi_ulong
*)(vfpframe
+ 1);
1939 static abi_ulong
*restore_sigframe_v2_iwmmxt(CPUARMState
*env
,
1940 abi_ulong
*regspace
)
1943 abi_ulong magic
, sz
;
1944 struct target_iwmmxt_sigframe
*iwmmxtframe
;
1945 iwmmxtframe
= (struct target_iwmmxt_sigframe
*)regspace
;
1947 __get_user(magic
, &iwmmxtframe
->magic
);
1948 __get_user(sz
, &iwmmxtframe
->size
);
1949 if (magic
!= TARGET_IWMMXT_MAGIC
|| sz
!= sizeof(*iwmmxtframe
)) {
1952 for (i
= 0; i
< 16; i
++) {
1953 __get_user(env
->iwmmxt
.regs
[i
], &iwmmxtframe
->regs
[i
]);
1955 __get_user(env
->vfp
.xregs
[ARM_IWMMXT_wCSSF
], &iwmmxtframe
->wcssf
);
1956 __get_user(env
->vfp
.xregs
[ARM_IWMMXT_wCASF
], &iwmmxtframe
->wcssf
);
1957 __get_user(env
->vfp
.xregs
[ARM_IWMMXT_wCGR0
], &iwmmxtframe
->wcgr0
);
1958 __get_user(env
->vfp
.xregs
[ARM_IWMMXT_wCGR1
], &iwmmxtframe
->wcgr1
);
1959 __get_user(env
->vfp
.xregs
[ARM_IWMMXT_wCGR2
], &iwmmxtframe
->wcgr2
);
1960 __get_user(env
->vfp
.xregs
[ARM_IWMMXT_wCGR3
], &iwmmxtframe
->wcgr3
);
1961 return (abi_ulong
*)(iwmmxtframe
+ 1);
1964 static int do_sigframe_return_v2(CPUARMState
*env
, target_ulong frame_addr
,
1965 struct target_ucontext_v2
*uc
)
1968 abi_ulong
*regspace
;
1970 target_to_host_sigset(&host_set
, &uc
->tuc_sigmask
);
1971 do_sigprocmask(SIG_SETMASK
, &host_set
, NULL
);
1973 if (restore_sigcontext(env
, &uc
->tuc_mcontext
))
1976 /* Restore coprocessor signal frame */
1977 regspace
= uc
->tuc_regspace
;
1978 if (arm_feature(env
, ARM_FEATURE_VFP
)) {
1979 regspace
= restore_sigframe_v2_vfp(env
, regspace
);
1984 if (arm_feature(env
, ARM_FEATURE_IWMMXT
)) {
1985 regspace
= restore_sigframe_v2_iwmmxt(env
, regspace
);
1991 if (do_sigaltstack(frame_addr
+ offsetof(struct target_ucontext_v2
, tuc_stack
), 0, get_sp_from_cpustate(env
)) == -EFAULT
)
1995 /* Send SIGTRAP if we're single-stepping */
1996 if (ptrace_cancel_bpt(current
))
1997 send_sig(SIGTRAP
, current
, 1);
2003 static long do_sigreturn_v2(CPUARMState
*env
)
2005 abi_ulong frame_addr
;
2006 struct sigframe_v2
*frame
= NULL
;
2009 * Since we stacked the signal on a 64-bit boundary,
2010 * then 'sp' should be word aligned here. If it's
2011 * not, then the user is trying to mess with us.
2013 frame_addr
= env
->regs
[13];
2014 if (frame_addr
& 7) {
2018 if (!lock_user_struct(VERIFY_READ
, frame
, frame_addr
, 1))
2021 if (do_sigframe_return_v2(env
, frame_addr
, &frame
->uc
))
2024 unlock_user_struct(frame
, frame_addr
, 0);
2025 return env
->regs
[0];
2028 unlock_user_struct(frame
, frame_addr
, 0);
2029 force_sig(TARGET_SIGSEGV
/* , current */);
2033 long do_sigreturn(CPUARMState
*env
)
2035 if (get_osversion() >= 0x020612) {
2036 return do_sigreturn_v2(env
);
2038 return do_sigreturn_v1(env
);
2042 static long do_rt_sigreturn_v1(CPUARMState
*env
)
2044 abi_ulong frame_addr
;
2045 struct rt_sigframe_v1
*frame
= NULL
;
2049 * Since we stacked the signal on a 64-bit boundary,
2050 * then 'sp' should be word aligned here. If it's
2051 * not, then the user is trying to mess with us.
2053 frame_addr
= env
->regs
[13];
2054 if (frame_addr
& 7) {
2058 if (!lock_user_struct(VERIFY_READ
, frame
, frame_addr
, 1))
2061 target_to_host_sigset(&host_set
, &frame
->uc
.tuc_sigmask
);
2062 do_sigprocmask(SIG_SETMASK
, &host_set
, NULL
);
2064 if (restore_sigcontext(env
, &frame
->uc
.tuc_mcontext
))
2067 if (do_sigaltstack(frame_addr
+ offsetof(struct rt_sigframe_v1
, uc
.tuc_stack
), 0, get_sp_from_cpustate(env
)) == -EFAULT
)
2071 /* Send SIGTRAP if we're single-stepping */
2072 if (ptrace_cancel_bpt(current
))
2073 send_sig(SIGTRAP
, current
, 1);
2075 unlock_user_struct(frame
, frame_addr
, 0);
2076 return env
->regs
[0];
2079 unlock_user_struct(frame
, frame_addr
, 0);
2080 force_sig(TARGET_SIGSEGV
/* , current */);
2084 static long do_rt_sigreturn_v2(CPUARMState
*env
)
2086 abi_ulong frame_addr
;
2087 struct rt_sigframe_v2
*frame
= NULL
;
2090 * Since we stacked the signal on a 64-bit boundary,
2091 * then 'sp' should be word aligned here. If it's
2092 * not, then the user is trying to mess with us.
2094 frame_addr
= env
->regs
[13];
2095 if (frame_addr
& 7) {
2099 if (!lock_user_struct(VERIFY_READ
, frame
, frame_addr
, 1))
2102 if (do_sigframe_return_v2(env
, frame_addr
, &frame
->uc
))
2105 unlock_user_struct(frame
, frame_addr
, 0);
2106 return env
->regs
[0];
2109 unlock_user_struct(frame
, frame_addr
, 0);
2110 force_sig(TARGET_SIGSEGV
/* , current */);
2114 long do_rt_sigreturn(CPUARMState
*env
)
2116 if (get_osversion() >= 0x020612) {
2117 return do_rt_sigreturn_v2(env
);
2119 return do_rt_sigreturn_v1(env
);
2123 #elif defined(TARGET_SPARC)
2125 #define __SUNOS_MAXWIN 31
2127 /* This is what SunOS does, so shall I. */
2128 struct target_sigcontext
{
2129 abi_ulong sigc_onstack
; /* state to restore */
2131 abi_ulong sigc_mask
; /* sigmask to restore */
2132 abi_ulong sigc_sp
; /* stack pointer */
2133 abi_ulong sigc_pc
; /* program counter */
2134 abi_ulong sigc_npc
; /* next program counter */
2135 abi_ulong sigc_psr
; /* for condition codes etc */
2136 abi_ulong sigc_g1
; /* User uses these two registers */
2137 abi_ulong sigc_o0
; /* within the trampoline code. */
2139 /* Now comes information regarding the users window set
2140 * at the time of the signal.
2142 abi_ulong sigc_oswins
; /* outstanding windows */
2144 /* stack ptrs for each regwin buf */
2145 char *sigc_spbuf
[__SUNOS_MAXWIN
];
2147 /* Windows to restore after signal */
2149 abi_ulong locals
[8];
2151 } sigc_wbuf
[__SUNOS_MAXWIN
];
2153 /* A Sparc stack frame */
2154 struct sparc_stackf
{
2155 abi_ulong locals
[8];
2157 /* It's simpler to treat fp and callers_pc as elements of ins[]
2158 * since we never need to access them ourselves.
2162 abi_ulong xxargs
[1];
2171 abi_ulong u_regs
[16]; /* globals and ins */
2177 abi_ulong si_float_regs
[32];
2178 unsigned long si_fsr
;
2179 unsigned long si_fpqdepth
;
2181 unsigned long *insn_addr
;
2184 } qemu_siginfo_fpu_t
;
2187 struct target_signal_frame
{
2188 struct sparc_stackf ss
;
2191 abi_ulong insns
[2] __attribute__ ((aligned (8)));
2192 abi_ulong extramask
[TARGET_NSIG_WORDS
- 1];
2193 abi_ulong extra_size
; /* Should be 0 */
2194 qemu_siginfo_fpu_t fpu_state
;
2196 struct target_rt_signal_frame
{
2197 struct sparc_stackf ss
;
2202 unsigned int insns
[2];
2204 unsigned int extra_size
; /* Should be 0 */
2205 qemu_siginfo_fpu_t fpu_state
;
2219 #define UREG_FP UREG_I6
2220 #define UREG_SP UREG_O6
2222 static inline abi_ulong
get_sigframe(struct target_sigaction
*sa
,
2224 unsigned long framesize
)
2228 sp
= env
->regwptr
[UREG_FP
];
2230 /* This is the X/Open sanctioned signal stack switching. */
2231 if (sa
->sa_flags
& TARGET_SA_ONSTACK
) {
2232 if (!on_sig_stack(sp
)
2233 && !((target_sigaltstack_used
.ss_sp
+ target_sigaltstack_used
.ss_size
) & 7))
2234 sp
= target_sigaltstack_used
.ss_sp
+ target_sigaltstack_used
.ss_size
;
2236 return sp
- framesize
;
2240 setup___siginfo(__siginfo_t
*si
, CPUSPARCState
*env
, abi_ulong mask
)
2244 __put_user(env
->psr
, &si
->si_regs
.psr
);
2245 __put_user(env
->pc
, &si
->si_regs
.pc
);
2246 __put_user(env
->npc
, &si
->si_regs
.npc
);
2247 __put_user(env
->y
, &si
->si_regs
.y
);
2248 for (i
=0; i
< 8; i
++) {
2249 __put_user(env
->gregs
[i
], &si
->si_regs
.u_regs
[i
]);
2251 for (i
=0; i
< 8; i
++) {
2252 __put_user(env
->regwptr
[UREG_I0
+ i
], &si
->si_regs
.u_regs
[i
+8]);
2254 __put_user(mask
, &si
->si_mask
);
2260 setup_sigcontext(struct target_sigcontext
*sc
, /*struct _fpstate *fpstate,*/
2261 CPUSPARCState
*env
, unsigned long mask
)
2265 __put_user(mask
, &sc
->sigc_mask
);
2266 __put_user(env
->regwptr
[UREG_SP
], &sc
->sigc_sp
);
2267 __put_user(env
->pc
, &sc
->sigc_pc
);
2268 __put_user(env
->npc
, &sc
->sigc_npc
);
2269 __put_user(env
->psr
, &sc
->sigc_psr
);
2270 __put_user(env
->gregs
[1], &sc
->sigc_g1
);
2271 __put_user(env
->regwptr
[UREG_O0
], &sc
->sigc_o0
);
2276 #define NF_ALIGNEDSZ (((sizeof(struct target_signal_frame) + 7) & (~7)))
2278 static void setup_frame(int sig
, struct target_sigaction
*ka
,
2279 target_sigset_t
*set
, CPUSPARCState
*env
)
2282 struct target_signal_frame
*sf
;
2283 int sigframe_size
, err
, i
;
2285 /* 1. Make sure everything is clean */
2286 //synchronize_user_stack();
2288 sigframe_size
= NF_ALIGNEDSZ
;
2289 sf_addr
= get_sigframe(ka
, env
, sigframe_size
);
2291 sf
= lock_user(VERIFY_WRITE
, sf_addr
,
2292 sizeof(struct target_signal_frame
), 0);
2296 //fprintf(stderr, "sf: %x pc %x fp %x sp %x\n", sf, env->pc, env->regwptr[UREG_FP], env->regwptr[UREG_SP]);
2298 if (invalid_frame_pointer(sf
, sigframe_size
))
2299 goto sigill_and_return
;
2301 /* 2. Save the current process state */
2302 err
= setup___siginfo(&sf
->info
, env
, set
->sig
[0]);
2303 __put_user(0, &sf
->extra_size
);
2305 //save_fpu_state(regs, &sf->fpu_state);
2306 //__put_user(&sf->fpu_state, &sf->fpu_save);
2308 __put_user(set
->sig
[0], &sf
->info
.si_mask
);
2309 for (i
= 0; i
< TARGET_NSIG_WORDS
- 1; i
++) {
2310 __put_user(set
->sig
[i
+ 1], &sf
->extramask
[i
]);
2313 for (i
= 0; i
< 8; i
++) {
2314 __put_user(env
->regwptr
[i
+ UREG_L0
], &sf
->ss
.locals
[i
]);
2316 for (i
= 0; i
< 8; i
++) {
2317 __put_user(env
->regwptr
[i
+ UREG_I0
], &sf
->ss
.ins
[i
]);
2322 /* 3. signal handler back-trampoline and parameters */
2323 env
->regwptr
[UREG_FP
] = sf_addr
;
2324 env
->regwptr
[UREG_I0
] = sig
;
2325 env
->regwptr
[UREG_I1
] = sf_addr
+
2326 offsetof(struct target_signal_frame
, info
);
2327 env
->regwptr
[UREG_I2
] = sf_addr
+
2328 offsetof(struct target_signal_frame
, info
);
2330 /* 4. signal handler */
2331 env
->pc
= ka
->_sa_handler
;
2332 env
->npc
= (env
->pc
+ 4);
2333 /* 5. return to kernel instructions */
2334 if (ka
->sa_restorer
)
2335 env
->regwptr
[UREG_I7
] = ka
->sa_restorer
;
2339 env
->regwptr
[UREG_I7
] = sf_addr
+
2340 offsetof(struct target_signal_frame
, insns
) - 2 * 4;
2342 /* mov __NR_sigreturn, %g1 */
2344 __put_user(val32
, &sf
->insns
[0]);
2348 __put_user(val32
, &sf
->insns
[1]);
2352 /* Flush instruction space. */
2353 //flush_sig_insns(current->mm, (unsigned long) &(sf->insns[0]));
2356 unlock_user(sf
, sf_addr
, sizeof(struct target_signal_frame
));
2360 force_sig(TARGET_SIGILL
);
2363 //fprintf(stderr, "force_sig\n");
2364 unlock_user(sf
, sf_addr
, sizeof(struct target_signal_frame
));
2365 force_sig(TARGET_SIGSEGV
);
2368 static void setup_rt_frame(int sig
, struct target_sigaction
*ka
,
2369 target_siginfo_t
*info
,
2370 target_sigset_t
*set
, CPUSPARCState
*env
)
2372 fprintf(stderr
, "setup_rt_frame: not implemented\n");
2375 long do_sigreturn(CPUSPARCState
*env
)
2378 struct target_signal_frame
*sf
;
2379 uint32_t up_psr
, pc
, npc
;
2380 target_sigset_t set
;
2384 sf_addr
= env
->regwptr
[UREG_FP
];
2385 if (!lock_user_struct(VERIFY_READ
, sf
, sf_addr
, 1))
2388 fprintf(stderr
, "sigreturn\n");
2389 fprintf(stderr
, "sf: %x pc %x fp %x sp %x\n", sf
, env
->pc
, env
->regwptr
[UREG_FP
], env
->regwptr
[UREG_SP
]);
2391 //cpu_dump_state(env, stderr, fprintf, 0);
2393 /* 1. Make sure we are not getting garbage from the user */
2398 __get_user(pc
, &sf
->info
.si_regs
.pc
);
2399 __get_user(npc
, &sf
->info
.si_regs
.npc
);
2404 /* 2. Restore the state */
2405 __get_user(up_psr
, &sf
->info
.si_regs
.psr
);
2407 /* User can only change condition codes and FPU enabling in %psr. */
2408 env
->psr
= (up_psr
& (PSR_ICC
/* | PSR_EF */))
2409 | (env
->psr
& ~(PSR_ICC
/* | PSR_EF */));
2413 __get_user(env
->y
, &sf
->info
.si_regs
.y
);
2414 for (i
=0; i
< 8; i
++) {
2415 __get_user(env
->gregs
[i
], &sf
->info
.si_regs
.u_regs
[i
]);
2417 for (i
=0; i
< 8; i
++) {
2418 __get_user(env
->regwptr
[i
+ UREG_I0
], &sf
->info
.si_regs
.u_regs
[i
+8]);
2421 /* FIXME: implement FPU save/restore:
2422 * __get_user(fpu_save, &sf->fpu_save);
2424 * err |= restore_fpu_state(env, fpu_save);
2427 /* This is pretty much atomic, no amount locking would prevent
2428 * the races which exist anyways.
2430 __get_user(set
.sig
[0], &sf
->info
.si_mask
);
2431 for(i
= 1; i
< TARGET_NSIG_WORDS
; i
++) {
2432 __get_user(set
.sig
[i
], &sf
->extramask
[i
- 1]);
2435 target_to_host_sigset_internal(&host_set
, &set
);
2436 do_sigprocmask(SIG_SETMASK
, &host_set
, NULL
);
2440 unlock_user_struct(sf
, sf_addr
, 0);
2441 return env
->regwptr
[0];
2444 unlock_user_struct(sf
, sf_addr
, 0);
2445 force_sig(TARGET_SIGSEGV
);
2448 long do_rt_sigreturn(CPUSPARCState
*env
)
2450 fprintf(stderr
, "do_rt_sigreturn: not implemented\n");
2451 return -TARGET_ENOSYS
;
2454 #if defined(TARGET_SPARC64) && !defined(TARGET_ABI32)
2476 typedef abi_ulong target_mc_greg_t
;
2477 typedef target_mc_greg_t target_mc_gregset_t
[MC_NGREG
];
2479 struct target_mc_fq
{
2480 abi_ulong
*mcfq_addr
;
2484 struct target_mc_fpu
{
2488 //uint128_t qregs[16];
2490 abi_ulong mcfpu_fsr
;
2491 abi_ulong mcfpu_fprs
;
2492 abi_ulong mcfpu_gsr
;
2493 struct target_mc_fq
*mcfpu_fq
;
2494 unsigned char mcfpu_qcnt
;
2495 unsigned char mcfpu_qentsz
;
2496 unsigned char mcfpu_enab
;
2498 typedef struct target_mc_fpu target_mc_fpu_t
;
2501 target_mc_gregset_t mc_gregs
;
2502 target_mc_greg_t mc_fp
;
2503 target_mc_greg_t mc_i7
;
2504 target_mc_fpu_t mc_fpregs
;
2505 } target_mcontext_t
;
2507 struct target_ucontext
{
2508 struct target_ucontext
*tuc_link
;
2509 abi_ulong tuc_flags
;
2510 target_sigset_t tuc_sigmask
;
2511 target_mcontext_t tuc_mcontext
;
2514 /* A V9 register window */
2515 struct target_reg_window
{
2516 abi_ulong locals
[8];
2520 #define TARGET_STACK_BIAS 2047
2522 /* {set, get}context() needed for 64-bit SparcLinux userland. */
2523 void sparc64_set_context(CPUSPARCState
*env
)
2526 struct target_ucontext
*ucp
;
2527 target_mc_gregset_t
*grp
;
2528 abi_ulong pc
, npc
, tstate
;
2529 abi_ulong fp
, i7
, w_addr
;
2533 ucp_addr
= env
->regwptr
[UREG_I0
];
2534 if (!lock_user_struct(VERIFY_READ
, ucp
, ucp_addr
, 1))
2536 grp
= &ucp
->tuc_mcontext
.mc_gregs
;
2537 __get_user(pc
, &((*grp
)[MC_PC
]));
2538 __get_user(npc
, &((*grp
)[MC_NPC
]));
2539 if (err
|| ((pc
| npc
) & 3))
2541 if (env
->regwptr
[UREG_I1
]) {
2542 target_sigset_t target_set
;
2545 if (TARGET_NSIG_WORDS
== 1) {
2546 if (__get_user(target_set
.sig
[0], &ucp
->tuc_sigmask
.sig
[0]))
2549 abi_ulong
*src
, *dst
;
2550 src
= ucp
->tuc_sigmask
.sig
;
2551 dst
= target_set
.sig
;
2552 for (i
= 0; i
< TARGET_NSIG_WORDS
; i
++, dst
++, src
++) {
2553 __get_user(*dst
, src
);
2558 target_to_host_sigset_internal(&set
, &target_set
);
2559 do_sigprocmask(SIG_SETMASK
, &set
, NULL
);
2563 __get_user(env
->y
, &((*grp
)[MC_Y
]));
2564 __get_user(tstate
, &((*grp
)[MC_TSTATE
]));
2565 env
->asi
= (tstate
>> 24) & 0xff;
2566 cpu_put_ccr(env
, tstate
>> 32);
2567 cpu_put_cwp64(env
, tstate
& 0x1f);
2568 __get_user(env
->gregs
[1], (&(*grp
)[MC_G1
]));
2569 __get_user(env
->gregs
[2], (&(*grp
)[MC_G2
]));
2570 __get_user(env
->gregs
[3], (&(*grp
)[MC_G3
]));
2571 __get_user(env
->gregs
[4], (&(*grp
)[MC_G4
]));
2572 __get_user(env
->gregs
[5], (&(*grp
)[MC_G5
]));
2573 __get_user(env
->gregs
[6], (&(*grp
)[MC_G6
]));
2574 __get_user(env
->gregs
[7], (&(*grp
)[MC_G7
]));
2575 __get_user(env
->regwptr
[UREG_I0
], (&(*grp
)[MC_O0
]));
2576 __get_user(env
->regwptr
[UREG_I1
], (&(*grp
)[MC_O1
]));
2577 __get_user(env
->regwptr
[UREG_I2
], (&(*grp
)[MC_O2
]));
2578 __get_user(env
->regwptr
[UREG_I3
], (&(*grp
)[MC_O3
]));
2579 __get_user(env
->regwptr
[UREG_I4
], (&(*grp
)[MC_O4
]));
2580 __get_user(env
->regwptr
[UREG_I5
], (&(*grp
)[MC_O5
]));
2581 __get_user(env
->regwptr
[UREG_I6
], (&(*grp
)[MC_O6
]));
2582 __get_user(env
->regwptr
[UREG_I7
], (&(*grp
)[MC_O7
]));
2584 __get_user(fp
, &(ucp
->tuc_mcontext
.mc_fp
));
2585 __get_user(i7
, &(ucp
->tuc_mcontext
.mc_i7
));
2587 w_addr
= TARGET_STACK_BIAS
+env
->regwptr
[UREG_I6
];
2588 if (put_user(fp
, w_addr
+ offsetof(struct target_reg_window
, ins
[6]),
2591 if (put_user(i7
, w_addr
+ offsetof(struct target_reg_window
, ins
[7]),
2594 /* FIXME this does not match how the kernel handles the FPU in
2595 * its sparc64_set_context implementation. In particular the FPU
2596 * is only restored if fenab is non-zero in:
2597 * __get_user(fenab, &(ucp->tuc_mcontext.mc_fpregs.mcfpu_enab));
2599 err
|= __get_user(env
->fprs
, &(ucp
->tuc_mcontext
.mc_fpregs
.mcfpu_fprs
));
2601 uint32_t *src
= ucp
->tuc_mcontext
.mc_fpregs
.mcfpu_fregs
.sregs
;
2602 for (i
= 0; i
< 64; i
++, src
++) {
2604 __get_user(env
->fpr
[i
/2].l
.lower
, src
);
2606 __get_user(env
->fpr
[i
/2].l
.upper
, src
);
2610 __get_user(env
->fsr
,
2611 &(ucp
->tuc_mcontext
.mc_fpregs
.mcfpu_fsr
));
2612 __get_user(env
->gsr
,
2613 &(ucp
->tuc_mcontext
.mc_fpregs
.mcfpu_gsr
));
2616 unlock_user_struct(ucp
, ucp_addr
, 0);
2619 unlock_user_struct(ucp
, ucp_addr
, 0);
2620 force_sig(TARGET_SIGSEGV
);
2623 void sparc64_get_context(CPUSPARCState
*env
)
2626 struct target_ucontext
*ucp
;
2627 target_mc_gregset_t
*grp
;
2628 target_mcontext_t
*mcp
;
2629 abi_ulong fp
, i7
, w_addr
;
2632 target_sigset_t target_set
;
2635 ucp_addr
= env
->regwptr
[UREG_I0
];
2636 if (!lock_user_struct(VERIFY_WRITE
, ucp
, ucp_addr
, 0))
2639 mcp
= &ucp
->tuc_mcontext
;
2640 grp
= &mcp
->mc_gregs
;
2642 /* Skip over the trap instruction, first. */
2648 do_sigprocmask(0, NULL
, &set
);
2649 host_to_target_sigset_internal(&target_set
, &set
);
2650 if (TARGET_NSIG_WORDS
== 1) {
2651 __put_user(target_set
.sig
[0],
2652 (abi_ulong
*)&ucp
->tuc_sigmask
);
2654 abi_ulong
*src
, *dst
;
2655 src
= target_set
.sig
;
2656 dst
= ucp
->tuc_sigmask
.sig
;
2657 for (i
= 0; i
< TARGET_NSIG_WORDS
; i
++, dst
++, src
++) {
2658 __put_user(*src
, dst
);
2664 /* XXX: tstate must be saved properly */
2665 // __put_user(env->tstate, &((*grp)[MC_TSTATE]));
2666 __put_user(env
->pc
, &((*grp
)[MC_PC
]));
2667 __put_user(env
->npc
, &((*grp
)[MC_NPC
]));
2668 __put_user(env
->y
, &((*grp
)[MC_Y
]));
2669 __put_user(env
->gregs
[1], &((*grp
)[MC_G1
]));
2670 __put_user(env
->gregs
[2], &((*grp
)[MC_G2
]));
2671 __put_user(env
->gregs
[3], &((*grp
)[MC_G3
]));
2672 __put_user(env
->gregs
[4], &((*grp
)[MC_G4
]));
2673 __put_user(env
->gregs
[5], &((*grp
)[MC_G5
]));
2674 __put_user(env
->gregs
[6], &((*grp
)[MC_G6
]));
2675 __put_user(env
->gregs
[7], &((*grp
)[MC_G7
]));
2676 __put_user(env
->regwptr
[UREG_I0
], &((*grp
)[MC_O0
]));
2677 __put_user(env
->regwptr
[UREG_I1
], &((*grp
)[MC_O1
]));
2678 __put_user(env
->regwptr
[UREG_I2
], &((*grp
)[MC_O2
]));
2679 __put_user(env
->regwptr
[UREG_I3
], &((*grp
)[MC_O3
]));
2680 __put_user(env
->regwptr
[UREG_I4
], &((*grp
)[MC_O4
]));
2681 __put_user(env
->regwptr
[UREG_I5
], &((*grp
)[MC_O5
]));
2682 __put_user(env
->regwptr
[UREG_I6
], &((*grp
)[MC_O6
]));
2683 __put_user(env
->regwptr
[UREG_I7
], &((*grp
)[MC_O7
]));
2685 w_addr
= TARGET_STACK_BIAS
+env
->regwptr
[UREG_I6
];
2687 if (get_user(fp
, w_addr
+ offsetof(struct target_reg_window
, ins
[6]),
2690 if (get_user(i7
, w_addr
+ offsetof(struct target_reg_window
, ins
[7]),
2693 __put_user(fp
, &(mcp
->mc_fp
));
2694 __put_user(i7
, &(mcp
->mc_i7
));
2697 uint32_t *dst
= ucp
->tuc_mcontext
.mc_fpregs
.mcfpu_fregs
.sregs
;
2698 for (i
= 0; i
< 64; i
++, dst
++) {
2700 __put_user(env
->fpr
[i
/2].l
.lower
, dst
);
2702 __put_user(env
->fpr
[i
/2].l
.upper
, dst
);
2706 __put_user(env
->fsr
, &(mcp
->mc_fpregs
.mcfpu_fsr
));
2707 __put_user(env
->gsr
, &(mcp
->mc_fpregs
.mcfpu_gsr
));
2708 __put_user(env
->fprs
, &(mcp
->mc_fpregs
.mcfpu_fprs
));
2712 unlock_user_struct(ucp
, ucp_addr
, 1);
2715 unlock_user_struct(ucp
, ucp_addr
, 1);
2716 force_sig(TARGET_SIGSEGV
);
2719 #elif defined(TARGET_MIPS) || defined(TARGET_MIPS64)
2721 # if defined(TARGET_ABI_MIPSO32)
2722 struct target_sigcontext
{
2723 uint32_t sc_regmask
; /* Unused */
2726 uint64_t sc_regs
[32];
2727 uint64_t sc_fpregs
[32];
2728 uint32_t sc_ownedfp
; /* Unused */
2729 uint32_t sc_fpc_csr
;
2730 uint32_t sc_fpc_eir
; /* Unused */
2731 uint32_t sc_used_math
;
2732 uint32_t sc_dsp
; /* dsp status, was sc_ssflags */
2736 target_ulong sc_hi1
; /* Was sc_cause */
2737 target_ulong sc_lo1
; /* Was sc_badvaddr */
2738 target_ulong sc_hi2
; /* Was sc_sigset[4] */
2739 target_ulong sc_lo2
;
2740 target_ulong sc_hi3
;
2741 target_ulong sc_lo3
;
2743 # else /* N32 || N64 */
2744 struct target_sigcontext
{
2745 uint64_t sc_regs
[32];
2746 uint64_t sc_fpregs
[32];
2756 uint32_t sc_fpc_csr
;
2757 uint32_t sc_used_math
;
2759 uint32_t sc_reserved
;
2764 uint32_t sf_ass
[4]; /* argument save space for o32 */
2765 uint32_t sf_code
[2]; /* signal trampoline */
2766 struct target_sigcontext sf_sc
;
2767 target_sigset_t sf_mask
;
2770 struct target_ucontext
{
2771 target_ulong tuc_flags
;
2772 target_ulong tuc_link
;
2773 target_stack_t tuc_stack
;
2775 struct target_sigcontext tuc_mcontext
;
2776 target_sigset_t tuc_sigmask
;
2779 struct target_rt_sigframe
{
2780 uint32_t rs_ass
[4]; /* argument save space for o32 */
2781 uint32_t rs_code
[2]; /* signal trampoline */
2782 struct target_siginfo rs_info
;
2783 struct target_ucontext rs_uc
;
2786 /* Install trampoline to jump back from signal handler */
2787 static inline int install_sigtramp(unsigned int *tramp
, unsigned int syscall
)
2792 * Set up the return code ...
2794 * li v0, __NR__foo_sigreturn
2798 __put_user(0x24020000 + syscall
, tramp
+ 0);
2799 __put_user(0x0000000c , tramp
+ 1);
2803 static inline void setup_sigcontext(CPUMIPSState
*regs
,
2804 struct target_sigcontext
*sc
)
2808 __put_user(exception_resume_pc(regs
), &sc
->sc_pc
);
2809 regs
->hflags
&= ~MIPS_HFLAG_BMASK
;
2811 __put_user(0, &sc
->sc_regs
[0]);
2812 for (i
= 1; i
< 32; ++i
) {
2813 __put_user(regs
->active_tc
.gpr
[i
], &sc
->sc_regs
[i
]);
2816 __put_user(regs
->active_tc
.HI
[0], &sc
->sc_mdhi
);
2817 __put_user(regs
->active_tc
.LO
[0], &sc
->sc_mdlo
);
2819 /* Rather than checking for dsp existence, always copy. The storage
2820 would just be garbage otherwise. */
2821 __put_user(regs
->active_tc
.HI
[1], &sc
->sc_hi1
);
2822 __put_user(regs
->active_tc
.HI
[2], &sc
->sc_hi2
);
2823 __put_user(regs
->active_tc
.HI
[3], &sc
->sc_hi3
);
2824 __put_user(regs
->active_tc
.LO
[1], &sc
->sc_lo1
);
2825 __put_user(regs
->active_tc
.LO
[2], &sc
->sc_lo2
);
2826 __put_user(regs
->active_tc
.LO
[3], &sc
->sc_lo3
);
2828 uint32_t dsp
= cpu_rddsp(0x3ff, regs
);
2829 __put_user(dsp
, &sc
->sc_dsp
);
2832 __put_user(1, &sc
->sc_used_math
);
2834 for (i
= 0; i
< 32; ++i
) {
2835 __put_user(regs
->active_fpu
.fpr
[i
].d
, &sc
->sc_fpregs
[i
]);
2840 restore_sigcontext(CPUMIPSState
*regs
, struct target_sigcontext
*sc
)
2844 __get_user(regs
->CP0_EPC
, &sc
->sc_pc
);
2846 __get_user(regs
->active_tc
.HI
[0], &sc
->sc_mdhi
);
2847 __get_user(regs
->active_tc
.LO
[0], &sc
->sc_mdlo
);
2849 for (i
= 1; i
< 32; ++i
) {
2850 __get_user(regs
->active_tc
.gpr
[i
], &sc
->sc_regs
[i
]);
2853 __get_user(regs
->active_tc
.HI
[1], &sc
->sc_hi1
);
2854 __get_user(regs
->active_tc
.HI
[2], &sc
->sc_hi2
);
2855 __get_user(regs
->active_tc
.HI
[3], &sc
->sc_hi3
);
2856 __get_user(regs
->active_tc
.LO
[1], &sc
->sc_lo1
);
2857 __get_user(regs
->active_tc
.LO
[2], &sc
->sc_lo2
);
2858 __get_user(regs
->active_tc
.LO
[3], &sc
->sc_lo3
);
2861 __get_user(dsp
, &sc
->sc_dsp
);
2862 cpu_wrdsp(dsp
, 0x3ff, regs
);
2865 for (i
= 0; i
< 32; ++i
) {
2866 __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 setup_sigcontext(regs
, &frame
->sf_sc
);
2922 for(i
= 0; i
< TARGET_NSIG_WORDS
; i
++) {
2923 __put_user(set
->sig
[i
], &frame
->sf_mask
.sig
[i
]);
2927 * Arguments to signal handler:
2929 * a0 = signal number
2930 * a1 = 0 (should be cause)
2931 * a2 = pointer to struct sigcontext
2933 * $25 and PC point to the signal handler, $29 points to the
2936 regs
->active_tc
.gpr
[ 4] = sig
;
2937 regs
->active_tc
.gpr
[ 5] = 0;
2938 regs
->active_tc
.gpr
[ 6] = frame_addr
+ offsetof(struct sigframe
, sf_sc
);
2939 regs
->active_tc
.gpr
[29] = frame_addr
;
2940 regs
->active_tc
.gpr
[31] = frame_addr
+ offsetof(struct sigframe
, sf_code
);
2941 /* The original kernel code sets CP0_EPC to the handler
2942 * since it returns to userland using eret
2943 * we cannot do this here, and we must set PC directly */
2944 regs
->active_tc
.PC
= regs
->active_tc
.gpr
[25] = ka
->_sa_handler
;
2945 mips_set_hflags_isa_mode_from_pc(regs
);
2946 unlock_user_struct(frame
, frame_addr
, 1);
2950 force_sig(TARGET_SIGSEGV
/*, current*/);
2953 long do_sigreturn(CPUMIPSState
*regs
)
2955 struct sigframe
*frame
;
2956 abi_ulong frame_addr
;
2958 target_sigset_t target_set
;
2961 #if defined(DEBUG_SIGNAL)
2962 fprintf(stderr
, "do_sigreturn\n");
2964 frame_addr
= regs
->active_tc
.gpr
[29];
2965 if (!lock_user_struct(VERIFY_READ
, frame
, frame_addr
, 1))
2968 for(i
= 0; i
< TARGET_NSIG_WORDS
; i
++) {
2969 __get_user(target_set
.sig
[i
], &frame
->sf_mask
.sig
[i
]);
2972 target_to_host_sigset_internal(&blocked
, &target_set
);
2973 do_sigprocmask(SIG_SETMASK
, &blocked
, NULL
);
2975 restore_sigcontext(regs
, &frame
->sf_sc
);
2979 * Don't let your children do this ...
2981 __asm__
__volatile__(
2989 regs
->active_tc
.PC
= regs
->CP0_EPC
;
2990 mips_set_hflags_isa_mode_from_pc(regs
);
2991 /* I am not sure this is right, but it seems to work
2992 * maybe a problem with nested signals ? */
2994 return -TARGET_QEMU_ESIGRETURN
;
2997 force_sig(TARGET_SIGSEGV
/*, current*/);
3002 static void setup_rt_frame(int sig
, struct target_sigaction
*ka
,
3003 target_siginfo_t
*info
,
3004 target_sigset_t
*set
, CPUMIPSState
*env
)
3006 struct target_rt_sigframe
*frame
;
3007 abi_ulong frame_addr
;
3010 frame_addr
= get_sigframe(ka
, env
, sizeof(*frame
));
3011 if (!lock_user_struct(VERIFY_WRITE
, frame
, frame_addr
, 0))
3014 install_sigtramp(frame
->rs_code
, TARGET_NR_rt_sigreturn
);
3016 copy_siginfo_to_user(&frame
->rs_info
, info
);
3018 __put_user(0, &frame
->rs_uc
.tuc_flags
);
3019 __put_user(0, &frame
->rs_uc
.tuc_link
);
3020 __put_user(target_sigaltstack_used
.ss_sp
, &frame
->rs_uc
.tuc_stack
.ss_sp
);
3021 __put_user(target_sigaltstack_used
.ss_size
, &frame
->rs_uc
.tuc_stack
.ss_size
);
3022 __put_user(sas_ss_flags(get_sp_from_cpustate(env
)),
3023 &frame
->rs_uc
.tuc_stack
.ss_flags
);
3025 setup_sigcontext(env
, &frame
->rs_uc
.tuc_mcontext
);
3027 for(i
= 0; i
< TARGET_NSIG_WORDS
; i
++) {
3028 __put_user(set
->sig
[i
], &frame
->rs_uc
.tuc_sigmask
.sig
[i
]);
3032 * Arguments to signal handler:
3034 * a0 = signal number
3035 * a1 = pointer to siginfo_t
3036 * a2 = pointer to struct ucontext
3038 * $25 and PC point to the signal handler, $29 points to the
3041 env
->active_tc
.gpr
[ 4] = sig
;
3042 env
->active_tc
.gpr
[ 5] = frame_addr
3043 + offsetof(struct target_rt_sigframe
, rs_info
);
3044 env
->active_tc
.gpr
[ 6] = frame_addr
3045 + offsetof(struct target_rt_sigframe
, rs_uc
);
3046 env
->active_tc
.gpr
[29] = frame_addr
;
3047 env
->active_tc
.gpr
[31] = frame_addr
3048 + offsetof(struct target_rt_sigframe
, rs_code
);
3049 /* The original kernel code sets CP0_EPC to the handler
3050 * since it returns to userland using eret
3051 * we cannot do this here, and we must set PC directly */
3052 env
->active_tc
.PC
= env
->active_tc
.gpr
[25] = ka
->_sa_handler
;
3053 mips_set_hflags_isa_mode_from_pc(env
);
3054 unlock_user_struct(frame
, frame_addr
, 1);
3058 unlock_user_struct(frame
, frame_addr
, 1);
3059 force_sig(TARGET_SIGSEGV
/*, current*/);
3062 long do_rt_sigreturn(CPUMIPSState
*env
)
3064 struct target_rt_sigframe
*frame
;
3065 abi_ulong frame_addr
;
3068 #if defined(DEBUG_SIGNAL)
3069 fprintf(stderr
, "do_rt_sigreturn\n");
3071 frame_addr
= env
->active_tc
.gpr
[29];
3072 if (!lock_user_struct(VERIFY_READ
, frame
, frame_addr
, 1))
3075 target_to_host_sigset(&blocked
, &frame
->rs_uc
.tuc_sigmask
);
3076 do_sigprocmask(SIG_SETMASK
, &blocked
, NULL
);
3078 restore_sigcontext(env
, &frame
->rs_uc
.tuc_mcontext
);
3080 if (do_sigaltstack(frame_addr
+
3081 offsetof(struct target_rt_sigframe
, rs_uc
.tuc_stack
),
3082 0, get_sp_from_cpustate(env
)) == -EFAULT
)
3085 env
->active_tc
.PC
= env
->CP0_EPC
;
3086 mips_set_hflags_isa_mode_from_pc(env
);
3087 /* I am not sure this is right, but it seems to work
3088 * maybe a problem with nested signals ? */
3090 return -TARGET_QEMU_ESIGRETURN
;
3093 force_sig(TARGET_SIGSEGV
/*, current*/);
3097 #elif defined(TARGET_SH4)
3100 * code and data structures from linux kernel:
3101 * include/asm-sh/sigcontext.h
3102 * arch/sh/kernel/signal.c
3105 struct target_sigcontext
{
3106 target_ulong oldmask
;
3109 target_ulong sc_gregs
[16];
3113 target_ulong sc_gbr
;
3114 target_ulong sc_mach
;
3115 target_ulong sc_macl
;
3118 target_ulong sc_fpregs
[16];
3119 target_ulong sc_xfpregs
[16];
3120 unsigned int sc_fpscr
;
3121 unsigned int sc_fpul
;
3122 unsigned int sc_ownedfp
;
3125 struct target_sigframe
3127 struct target_sigcontext sc
;
3128 target_ulong extramask
[TARGET_NSIG_WORDS
-1];
3129 uint16_t retcode
[3];
3133 struct target_ucontext
{
3134 target_ulong tuc_flags
;
3135 struct target_ucontext
*tuc_link
;
3136 target_stack_t tuc_stack
;
3137 struct target_sigcontext tuc_mcontext
;
3138 target_sigset_t tuc_sigmask
; /* mask last for extensibility */
3141 struct target_rt_sigframe
3143 struct target_siginfo info
;
3144 struct target_ucontext uc
;
3145 uint16_t retcode
[3];
3149 #define MOVW(n) (0x9300|((n)-2)) /* Move mem word at PC+n to R3 */
3150 #define TRAP_NOARG 0xc310 /* Syscall w/no args (NR in R3) SH3/4 */
3152 static abi_ulong
get_sigframe(struct target_sigaction
*ka
,
3153 unsigned long sp
, size_t frame_size
)
3155 if ((ka
->sa_flags
& TARGET_SA_ONSTACK
) && (sas_ss_flags(sp
) == 0)) {
3156 sp
= target_sigaltstack_used
.ss_sp
+ target_sigaltstack_used
.ss_size
;
3159 return (sp
- frame_size
) & -8ul;
3162 static void setup_sigcontext(struct target_sigcontext
*sc
,
3163 CPUSH4State
*regs
, unsigned long mask
)
3167 #define COPY(x) __put_user(regs->x, &sc->sc_##x)
3168 COPY(gregs
[0]); COPY(gregs
[1]);
3169 COPY(gregs
[2]); COPY(gregs
[3]);
3170 COPY(gregs
[4]); COPY(gregs
[5]);
3171 COPY(gregs
[6]); COPY(gregs
[7]);
3172 COPY(gregs
[8]); COPY(gregs
[9]);
3173 COPY(gregs
[10]); COPY(gregs
[11]);
3174 COPY(gregs
[12]); COPY(gregs
[13]);
3175 COPY(gregs
[14]); COPY(gregs
[15]);
3176 COPY(gbr
); COPY(mach
);
3177 COPY(macl
); COPY(pr
);
3181 for (i
=0; i
<16; i
++) {
3182 __put_user(regs
->fregs
[i
], &sc
->sc_fpregs
[i
]);
3184 __put_user(regs
->fpscr
, &sc
->sc_fpscr
);
3185 __put_user(regs
->fpul
, &sc
->sc_fpul
);
3187 /* non-iBCS2 extensions.. */
3188 __put_user(mask
, &sc
->oldmask
);
3191 static void restore_sigcontext(CPUSH4State
*regs
, struct target_sigcontext
*sc
,
3196 #define COPY(x) __get_user(regs->x, &sc->sc_##x)
3198 COPY(gregs
[2]); COPY(gregs
[3]);
3199 COPY(gregs
[4]); COPY(gregs
[5]);
3200 COPY(gregs
[6]); COPY(gregs
[7]);
3201 COPY(gregs
[8]); COPY(gregs
[9]);
3202 COPY(gregs
[10]); COPY(gregs
[11]);
3203 COPY(gregs
[12]); COPY(gregs
[13]);
3204 COPY(gregs
[14]); COPY(gregs
[15]);
3205 COPY(gbr
); COPY(mach
);
3206 COPY(macl
); COPY(pr
);
3210 for (i
=0; i
<16; i
++) {
3211 __get_user(regs
->fregs
[i
], &sc
->sc_fpregs
[i
]);
3213 __get_user(regs
->fpscr
, &sc
->sc_fpscr
);
3214 __get_user(regs
->fpul
, &sc
->sc_fpul
);
3216 regs
->tra
= -1; /* disable syscall checks */
3217 __get_user(*r0_p
, &sc
->sc_gregs
[0]);
3220 static void setup_frame(int sig
, struct target_sigaction
*ka
,
3221 target_sigset_t
*set
, CPUSH4State
*regs
)
3223 struct target_sigframe
*frame
;
3224 abi_ulong frame_addr
;
3229 frame_addr
= get_sigframe(ka
, regs
->gregs
[15], sizeof(*frame
));
3230 if (!lock_user_struct(VERIFY_WRITE
, frame
, frame_addr
, 0))
3233 signal
= current_exec_domain_sig(sig
);
3235 setup_sigcontext(&frame
->sc
, regs
, set
->sig
[0]);
3237 for (i
= 0; i
< TARGET_NSIG_WORDS
- 1; i
++) {
3238 __put_user(set
->sig
[i
+ 1], &frame
->extramask
[i
]);
3241 /* Set up to return from userspace. If provided, use a stub
3242 already in userspace. */
3243 if (ka
->sa_flags
& TARGET_SA_RESTORER
) {
3244 regs
->pr
= (unsigned long) ka
->sa_restorer
;
3246 /* Generate return code (system call to sigreturn) */
3247 __put_user(MOVW(2), &frame
->retcode
[0]);
3248 __put_user(TRAP_NOARG
, &frame
->retcode
[1]);
3249 __put_user((TARGET_NR_sigreturn
), &frame
->retcode
[2]);
3250 regs
->pr
= (unsigned long) frame
->retcode
;
3256 /* Set up registers for signal handler */
3257 regs
->gregs
[15] = frame_addr
;
3258 regs
->gregs
[4] = signal
; /* Arg for signal handler */
3260 regs
->gregs
[6] = frame_addr
+= offsetof(typeof(*frame
), sc
);
3261 regs
->pc
= (unsigned long) ka
->_sa_handler
;
3263 unlock_user_struct(frame
, frame_addr
, 1);
3267 unlock_user_struct(frame
, frame_addr
, 1);
3268 force_sig(TARGET_SIGSEGV
);
3271 static void setup_rt_frame(int sig
, struct target_sigaction
*ka
,
3272 target_siginfo_t
*info
,
3273 target_sigset_t
*set
, CPUSH4State
*regs
)
3275 struct target_rt_sigframe
*frame
;
3276 abi_ulong frame_addr
;
3281 frame_addr
= get_sigframe(ka
, regs
->gregs
[15], sizeof(*frame
));
3282 if (!lock_user_struct(VERIFY_WRITE
, frame
, frame_addr
, 0))
3285 signal
= current_exec_domain_sig(sig
);
3287 copy_siginfo_to_user(&frame
->info
, info
);
3289 /* Create the ucontext. */
3290 __put_user(0, &frame
->uc
.tuc_flags
);
3291 __put_user(0, (unsigned long *)&frame
->uc
.tuc_link
);
3292 __put_user((unsigned long)target_sigaltstack_used
.ss_sp
,
3293 &frame
->uc
.tuc_stack
.ss_sp
);
3294 __put_user(sas_ss_flags(regs
->gregs
[15]),
3295 &frame
->uc
.tuc_stack
.ss_flags
);
3296 __put_user(target_sigaltstack_used
.ss_size
,
3297 &frame
->uc
.tuc_stack
.ss_size
);
3298 setup_sigcontext(&frame
->uc
.tuc_mcontext
,
3300 for(i
= 0; i
< TARGET_NSIG_WORDS
; i
++) {
3301 __put_user(set
->sig
[i
], &frame
->uc
.tuc_sigmask
.sig
[i
]);
3304 /* Set up to return from userspace. If provided, use a stub
3305 already in userspace. */
3306 if (ka
->sa_flags
& TARGET_SA_RESTORER
) {
3307 regs
->pr
= (unsigned long) ka
->sa_restorer
;
3309 /* Generate return code (system call to sigreturn) */
3310 __put_user(MOVW(2), &frame
->retcode
[0]);
3311 __put_user(TRAP_NOARG
, &frame
->retcode
[1]);
3312 __put_user((TARGET_NR_rt_sigreturn
), &frame
->retcode
[2]);
3313 regs
->pr
= (unsigned long) frame
->retcode
;
3319 /* Set up registers for signal handler */
3320 regs
->gregs
[15] = frame_addr
;
3321 regs
->gregs
[4] = signal
; /* Arg for signal handler */
3322 regs
->gregs
[5] = frame_addr
+ offsetof(typeof(*frame
), info
);
3323 regs
->gregs
[6] = frame_addr
+ offsetof(typeof(*frame
), uc
);
3324 regs
->pc
= (unsigned long) ka
->_sa_handler
;
3326 unlock_user_struct(frame
, frame_addr
, 1);
3330 unlock_user_struct(frame
, frame_addr
, 1);
3331 force_sig(TARGET_SIGSEGV
);
3334 long do_sigreturn(CPUSH4State
*regs
)
3336 struct target_sigframe
*frame
;
3337 abi_ulong frame_addr
;
3339 target_sigset_t target_set
;
3344 #if defined(DEBUG_SIGNAL)
3345 fprintf(stderr
, "do_sigreturn\n");
3347 frame_addr
= regs
->gregs
[15];
3348 if (!lock_user_struct(VERIFY_READ
, frame
, frame_addr
, 1))
3351 __get_user(target_set
.sig
[0], &frame
->sc
.oldmask
);
3352 for(i
= 1; i
< TARGET_NSIG_WORDS
; i
++) {
3353 __get_user(target_set
.sig
[i
], &frame
->extramask
[i
- 1]);
3359 target_to_host_sigset_internal(&blocked
, &target_set
);
3360 do_sigprocmask(SIG_SETMASK
, &blocked
, NULL
);
3362 restore_sigcontext(regs
, &frame
->sc
, &r0
);
3364 unlock_user_struct(frame
, frame_addr
, 0);
3368 unlock_user_struct(frame
, frame_addr
, 0);
3369 force_sig(TARGET_SIGSEGV
);
3373 long do_rt_sigreturn(CPUSH4State
*regs
)
3375 struct target_rt_sigframe
*frame
;
3376 abi_ulong frame_addr
;
3380 #if defined(DEBUG_SIGNAL)
3381 fprintf(stderr
, "do_rt_sigreturn\n");
3383 frame_addr
= regs
->gregs
[15];
3384 if (!lock_user_struct(VERIFY_READ
, frame
, frame_addr
, 1))
3387 target_to_host_sigset(&blocked
, &frame
->uc
.tuc_sigmask
);
3388 do_sigprocmask(SIG_SETMASK
, &blocked
, NULL
);
3390 restore_sigcontext(regs
, &frame
->uc
.tuc_mcontext
, &r0
);
3392 if (do_sigaltstack(frame_addr
+
3393 offsetof(struct target_rt_sigframe
, uc
.tuc_stack
),
3394 0, get_sp_from_cpustate(regs
)) == -EFAULT
)
3397 unlock_user_struct(frame
, frame_addr
, 0);
3401 unlock_user_struct(frame
, frame_addr
, 0);
3402 force_sig(TARGET_SIGSEGV
);
3405 #elif defined(TARGET_MICROBLAZE)
3407 struct target_sigcontext
{
3408 struct target_pt_regs regs
; /* needs to be first */
3412 struct target_stack_t
{
3415 unsigned int ss_size
;
3418 struct target_ucontext
{
3419 abi_ulong tuc_flags
;
3421 struct target_stack_t tuc_stack
;
3422 struct target_sigcontext tuc_mcontext
;
3423 uint32_t tuc_extramask
[TARGET_NSIG_WORDS
- 1];
3426 /* Signal frames. */
3427 struct target_signal_frame
{
3428 struct target_ucontext uc
;
3429 uint32_t extramask
[TARGET_NSIG_WORDS
- 1];
3433 struct rt_signal_frame
{
3439 static void setup_sigcontext(struct target_sigcontext
*sc
, CPUMBState
*env
)
3441 __put_user(env
->regs
[0], &sc
->regs
.r0
);
3442 __put_user(env
->regs
[1], &sc
->regs
.r1
);
3443 __put_user(env
->regs
[2], &sc
->regs
.r2
);
3444 __put_user(env
->regs
[3], &sc
->regs
.r3
);
3445 __put_user(env
->regs
[4], &sc
->regs
.r4
);
3446 __put_user(env
->regs
[5], &sc
->regs
.r5
);
3447 __put_user(env
->regs
[6], &sc
->regs
.r6
);
3448 __put_user(env
->regs
[7], &sc
->regs
.r7
);
3449 __put_user(env
->regs
[8], &sc
->regs
.r8
);
3450 __put_user(env
->regs
[9], &sc
->regs
.r9
);
3451 __put_user(env
->regs
[10], &sc
->regs
.r10
);
3452 __put_user(env
->regs
[11], &sc
->regs
.r11
);
3453 __put_user(env
->regs
[12], &sc
->regs
.r12
);
3454 __put_user(env
->regs
[13], &sc
->regs
.r13
);
3455 __put_user(env
->regs
[14], &sc
->regs
.r14
);
3456 __put_user(env
->regs
[15], &sc
->regs
.r15
);
3457 __put_user(env
->regs
[16], &sc
->regs
.r16
);
3458 __put_user(env
->regs
[17], &sc
->regs
.r17
);
3459 __put_user(env
->regs
[18], &sc
->regs
.r18
);
3460 __put_user(env
->regs
[19], &sc
->regs
.r19
);
3461 __put_user(env
->regs
[20], &sc
->regs
.r20
);
3462 __put_user(env
->regs
[21], &sc
->regs
.r21
);
3463 __put_user(env
->regs
[22], &sc
->regs
.r22
);
3464 __put_user(env
->regs
[23], &sc
->regs
.r23
);
3465 __put_user(env
->regs
[24], &sc
->regs
.r24
);
3466 __put_user(env
->regs
[25], &sc
->regs
.r25
);
3467 __put_user(env
->regs
[26], &sc
->regs
.r26
);
3468 __put_user(env
->regs
[27], &sc
->regs
.r27
);
3469 __put_user(env
->regs
[28], &sc
->regs
.r28
);
3470 __put_user(env
->regs
[29], &sc
->regs
.r29
);
3471 __put_user(env
->regs
[30], &sc
->regs
.r30
);
3472 __put_user(env
->regs
[31], &sc
->regs
.r31
);
3473 __put_user(env
->sregs
[SR_PC
], &sc
->regs
.pc
);
3476 static void restore_sigcontext(struct target_sigcontext
*sc
, CPUMBState
*env
)
3478 __get_user(env
->regs
[0], &sc
->regs
.r0
);
3479 __get_user(env
->regs
[1], &sc
->regs
.r1
);
3480 __get_user(env
->regs
[2], &sc
->regs
.r2
);
3481 __get_user(env
->regs
[3], &sc
->regs
.r3
);
3482 __get_user(env
->regs
[4], &sc
->regs
.r4
);
3483 __get_user(env
->regs
[5], &sc
->regs
.r5
);
3484 __get_user(env
->regs
[6], &sc
->regs
.r6
);
3485 __get_user(env
->regs
[7], &sc
->regs
.r7
);
3486 __get_user(env
->regs
[8], &sc
->regs
.r8
);
3487 __get_user(env
->regs
[9], &sc
->regs
.r9
);
3488 __get_user(env
->regs
[10], &sc
->regs
.r10
);
3489 __get_user(env
->regs
[11], &sc
->regs
.r11
);
3490 __get_user(env
->regs
[12], &sc
->regs
.r12
);
3491 __get_user(env
->regs
[13], &sc
->regs
.r13
);
3492 __get_user(env
->regs
[14], &sc
->regs
.r14
);
3493 __get_user(env
->regs
[15], &sc
->regs
.r15
);
3494 __get_user(env
->regs
[16], &sc
->regs
.r16
);
3495 __get_user(env
->regs
[17], &sc
->regs
.r17
);
3496 __get_user(env
->regs
[18], &sc
->regs
.r18
);
3497 __get_user(env
->regs
[19], &sc
->regs
.r19
);
3498 __get_user(env
->regs
[20], &sc
->regs
.r20
);
3499 __get_user(env
->regs
[21], &sc
->regs
.r21
);
3500 __get_user(env
->regs
[22], &sc
->regs
.r22
);
3501 __get_user(env
->regs
[23], &sc
->regs
.r23
);
3502 __get_user(env
->regs
[24], &sc
->regs
.r24
);
3503 __get_user(env
->regs
[25], &sc
->regs
.r25
);
3504 __get_user(env
->regs
[26], &sc
->regs
.r26
);
3505 __get_user(env
->regs
[27], &sc
->regs
.r27
);
3506 __get_user(env
->regs
[28], &sc
->regs
.r28
);
3507 __get_user(env
->regs
[29], &sc
->regs
.r29
);
3508 __get_user(env
->regs
[30], &sc
->regs
.r30
);
3509 __get_user(env
->regs
[31], &sc
->regs
.r31
);
3510 __get_user(env
->sregs
[SR_PC
], &sc
->regs
.pc
);
3513 static abi_ulong
get_sigframe(struct target_sigaction
*ka
,
3514 CPUMBState
*env
, int frame_size
)
3516 abi_ulong sp
= env
->regs
[1];
3518 if ((ka
->sa_flags
& SA_ONSTACK
) != 0 && !on_sig_stack(sp
))
3519 sp
= target_sigaltstack_used
.ss_sp
+ target_sigaltstack_used
.ss_size
;
3521 return ((sp
- frame_size
) & -8UL);
3524 static void setup_frame(int sig
, struct target_sigaction
*ka
,
3525 target_sigset_t
*set
, CPUMBState
*env
)
3527 struct target_signal_frame
*frame
;
3528 abi_ulong frame_addr
;
3531 frame_addr
= get_sigframe(ka
, env
, sizeof *frame
);
3532 if (!lock_user_struct(VERIFY_WRITE
, frame
, frame_addr
, 0))
3535 /* Save the mask. */
3536 __put_user(set
->sig
[0], &frame
->uc
.tuc_mcontext
.oldmask
);
3538 for(i
= 1; i
< TARGET_NSIG_WORDS
; i
++) {
3539 __put_user(set
->sig
[i
], &frame
->extramask
[i
- 1]);
3542 setup_sigcontext(&frame
->uc
.tuc_mcontext
, env
);
3544 /* Set up to return from userspace. If provided, use a stub
3545 already in userspace. */
3546 /* minus 8 is offset to cater for "rtsd r15,8" offset */
3547 if (ka
->sa_flags
& TARGET_SA_RESTORER
) {
3548 env
->regs
[15] = ((unsigned long)ka
->sa_restorer
)-8;
3551 /* Note, these encodings are _big endian_! */
3552 /* addi r12, r0, __NR_sigreturn */
3553 t
= 0x31800000UL
| TARGET_NR_sigreturn
;
3554 __put_user(t
, frame
->tramp
+ 0);
3557 __put_user(t
, frame
->tramp
+ 1);
3559 /* Return from sighandler will jump to the tramp.
3560 Negative 8 offset because return is rtsd r15, 8 */
3561 env
->regs
[15] = ((unsigned long)frame
->tramp
) - 8;
3564 /* Set up registers for signal handler */
3565 env
->regs
[1] = frame_addr
;
3566 /* Signal handler args: */
3567 env
->regs
[5] = sig
; /* Arg 0: signum */
3569 /* arg 1: sigcontext */
3570 env
->regs
[7] = frame_addr
+= offsetof(typeof(*frame
), uc
);
3572 /* Offset of 4 to handle microblaze rtid r14, 0 */
3573 env
->sregs
[SR_PC
] = (unsigned long)ka
->_sa_handler
;
3575 unlock_user_struct(frame
, frame_addr
, 1);
3578 force_sig(TARGET_SIGSEGV
);
3581 static void setup_rt_frame(int sig
, struct target_sigaction
*ka
,
3582 target_siginfo_t
*info
,
3583 target_sigset_t
*set
, CPUMBState
*env
)
3585 fprintf(stderr
, "Microblaze setup_rt_frame: not implemented\n");
3588 long do_sigreturn(CPUMBState
*env
)
3590 struct target_signal_frame
*frame
;
3591 abi_ulong frame_addr
;
3592 target_sigset_t target_set
;
3596 frame_addr
= env
->regs
[R_SP
];
3597 /* Make sure the guest isn't playing games. */
3598 if (!lock_user_struct(VERIFY_WRITE
, frame
, frame_addr
, 1))
3601 /* Restore blocked signals */
3602 __get_user(target_set
.sig
[0], &frame
->uc
.tuc_mcontext
.oldmask
);
3603 for(i
= 1; i
< TARGET_NSIG_WORDS
; i
++) {
3604 __get_user(target_set
.sig
[i
], &frame
->extramask
[i
- 1]);
3606 target_to_host_sigset_internal(&set
, &target_set
);
3607 do_sigprocmask(SIG_SETMASK
, &set
, NULL
);
3609 restore_sigcontext(&frame
->uc
.tuc_mcontext
, env
);
3610 /* We got here through a sigreturn syscall, our path back is via an
3611 rtb insn so setup r14 for that. */
3612 env
->regs
[14] = env
->sregs
[SR_PC
];
3614 unlock_user_struct(frame
, frame_addr
, 0);
3615 return env
->regs
[10];
3617 force_sig(TARGET_SIGSEGV
);
3620 long do_rt_sigreturn(CPUMBState
*env
)
3622 fprintf(stderr
, "Microblaze do_rt_sigreturn: not implemented\n");
3623 return -TARGET_ENOSYS
;
3626 #elif defined(TARGET_CRIS)
3628 struct target_sigcontext
{
3629 struct target_pt_regs regs
; /* needs to be first */
3631 uint32_t usp
; /* usp before stacking this gunk on it */
3634 /* Signal frames. */
3635 struct target_signal_frame
{
3636 struct target_sigcontext sc
;
3637 uint32_t extramask
[TARGET_NSIG_WORDS
- 1];
3638 uint16_t retcode
[4]; /* Trampoline code. */
3641 struct rt_signal_frame
{
3646 uint16_t retcode
[4]; /* Trampoline code. */
3649 static void setup_sigcontext(struct target_sigcontext
*sc
, CPUCRISState
*env
)
3651 __put_user(env
->regs
[0], &sc
->regs
.r0
);
3652 __put_user(env
->regs
[1], &sc
->regs
.r1
);
3653 __put_user(env
->regs
[2], &sc
->regs
.r2
);
3654 __put_user(env
->regs
[3], &sc
->regs
.r3
);
3655 __put_user(env
->regs
[4], &sc
->regs
.r4
);
3656 __put_user(env
->regs
[5], &sc
->regs
.r5
);
3657 __put_user(env
->regs
[6], &sc
->regs
.r6
);
3658 __put_user(env
->regs
[7], &sc
->regs
.r7
);
3659 __put_user(env
->regs
[8], &sc
->regs
.r8
);
3660 __put_user(env
->regs
[9], &sc
->regs
.r9
);
3661 __put_user(env
->regs
[10], &sc
->regs
.r10
);
3662 __put_user(env
->regs
[11], &sc
->regs
.r11
);
3663 __put_user(env
->regs
[12], &sc
->regs
.r12
);
3664 __put_user(env
->regs
[13], &sc
->regs
.r13
);
3665 __put_user(env
->regs
[14], &sc
->usp
);
3666 __put_user(env
->regs
[15], &sc
->regs
.acr
);
3667 __put_user(env
->pregs
[PR_MOF
], &sc
->regs
.mof
);
3668 __put_user(env
->pregs
[PR_SRP
], &sc
->regs
.srp
);
3669 __put_user(env
->pc
, &sc
->regs
.erp
);
3672 static void restore_sigcontext(struct target_sigcontext
*sc
, CPUCRISState
*env
)
3674 __get_user(env
->regs
[0], &sc
->regs
.r0
);
3675 __get_user(env
->regs
[1], &sc
->regs
.r1
);
3676 __get_user(env
->regs
[2], &sc
->regs
.r2
);
3677 __get_user(env
->regs
[3], &sc
->regs
.r3
);
3678 __get_user(env
->regs
[4], &sc
->regs
.r4
);
3679 __get_user(env
->regs
[5], &sc
->regs
.r5
);
3680 __get_user(env
->regs
[6], &sc
->regs
.r6
);
3681 __get_user(env
->regs
[7], &sc
->regs
.r7
);
3682 __get_user(env
->regs
[8], &sc
->regs
.r8
);
3683 __get_user(env
->regs
[9], &sc
->regs
.r9
);
3684 __get_user(env
->regs
[10], &sc
->regs
.r10
);
3685 __get_user(env
->regs
[11], &sc
->regs
.r11
);
3686 __get_user(env
->regs
[12], &sc
->regs
.r12
);
3687 __get_user(env
->regs
[13], &sc
->regs
.r13
);
3688 __get_user(env
->regs
[14], &sc
->usp
);
3689 __get_user(env
->regs
[15], &sc
->regs
.acr
);
3690 __get_user(env
->pregs
[PR_MOF
], &sc
->regs
.mof
);
3691 __get_user(env
->pregs
[PR_SRP
], &sc
->regs
.srp
);
3692 __get_user(env
->pc
, &sc
->regs
.erp
);
3695 static abi_ulong
get_sigframe(CPUCRISState
*env
, int framesize
)
3698 /* Align the stack downwards to 4. */
3699 sp
= (env
->regs
[R_SP
] & ~3);
3700 return sp
- framesize
;
3703 static void setup_frame(int sig
, struct target_sigaction
*ka
,
3704 target_sigset_t
*set
, CPUCRISState
*env
)
3706 struct target_signal_frame
*frame
;
3707 abi_ulong frame_addr
;
3710 frame_addr
= get_sigframe(env
, sizeof *frame
);
3711 if (!lock_user_struct(VERIFY_WRITE
, frame
, frame_addr
, 0))
3715 * The CRIS signal return trampoline. A real linux/CRIS kernel doesn't
3716 * use this trampoline anymore but it sets it up for GDB.
3717 * In QEMU, using the trampoline simplifies things a bit so we use it.
3719 * This is movu.w __NR_sigreturn, r9; break 13;
3721 __put_user(0x9c5f, frame
->retcode
+0);
3722 __put_user(TARGET_NR_sigreturn
,
3723 frame
->retcode
+ 1);
3724 __put_user(0xe93d, frame
->retcode
+ 2);
3726 /* Save the mask. */
3727 __put_user(set
->sig
[0], &frame
->sc
.oldmask
);
3729 for(i
= 1; i
< TARGET_NSIG_WORDS
; i
++) {
3730 __put_user(set
->sig
[i
], &frame
->extramask
[i
- 1]);
3733 setup_sigcontext(&frame
->sc
, env
);
3735 /* Move the stack and setup the arguments for the handler. */
3736 env
->regs
[R_SP
] = frame_addr
;
3737 env
->regs
[10] = sig
;
3738 env
->pc
= (unsigned long) ka
->_sa_handler
;
3739 /* Link SRP so the guest returns through the trampoline. */
3740 env
->pregs
[PR_SRP
] = frame_addr
+ offsetof(typeof(*frame
), retcode
);
3742 unlock_user_struct(frame
, frame_addr
, 1);
3745 force_sig(TARGET_SIGSEGV
);
3748 static void setup_rt_frame(int sig
, struct target_sigaction
*ka
,
3749 target_siginfo_t
*info
,
3750 target_sigset_t
*set
, CPUCRISState
*env
)
3752 fprintf(stderr
, "CRIS setup_rt_frame: not implemented\n");
3755 long do_sigreturn(CPUCRISState
*env
)
3757 struct target_signal_frame
*frame
;
3758 abi_ulong frame_addr
;
3759 target_sigset_t target_set
;
3763 frame_addr
= env
->regs
[R_SP
];
3764 /* Make sure the guest isn't playing games. */
3765 if (!lock_user_struct(VERIFY_WRITE
, frame
, frame_addr
, 1))
3768 /* Restore blocked signals */
3769 __get_user(target_set
.sig
[0], &frame
->sc
.oldmask
);
3770 for(i
= 1; i
< TARGET_NSIG_WORDS
; i
++) {
3771 __get_user(target_set
.sig
[i
], &frame
->extramask
[i
- 1]);
3773 target_to_host_sigset_internal(&set
, &target_set
);
3774 do_sigprocmask(SIG_SETMASK
, &set
, NULL
);
3776 restore_sigcontext(&frame
->sc
, env
);
3777 unlock_user_struct(frame
, frame_addr
, 0);
3778 return env
->regs
[10];
3780 force_sig(TARGET_SIGSEGV
);
3783 long do_rt_sigreturn(CPUCRISState
*env
)
3785 fprintf(stderr
, "CRIS do_rt_sigreturn: not implemented\n");
3786 return -TARGET_ENOSYS
;
3789 #elif defined(TARGET_OPENRISC)
3791 struct target_sigcontext
{
3792 struct target_pt_regs regs
;
3797 struct target_ucontext
{
3798 abi_ulong tuc_flags
;
3800 target_stack_t tuc_stack
;
3801 struct target_sigcontext tuc_mcontext
;
3802 target_sigset_t tuc_sigmask
; /* mask last for extensibility */
3805 struct target_rt_sigframe
{
3808 struct target_siginfo info
;
3809 struct target_sigcontext sc
;
3810 struct target_ucontext uc
;
3811 unsigned char retcode
[16]; /* trampoline code */
3814 /* This is the asm-generic/ucontext.h version */
3816 static int restore_sigcontext(CPUOpenRISCState
*regs
,
3817 struct target_sigcontext
*sc
)
3819 unsigned int err
= 0;
3820 unsigned long old_usp
;
3822 /* Alwys make any pending restarted system call return -EINTR */
3823 current_thread_info()->restart_block
.fn
= do_no_restart_syscall
;
3825 /* restore the regs from &sc->regs (same as sc, since regs is first)
3826 * (sc is already checked for VERIFY_READ since the sigframe was
3827 * checked in sys_sigreturn previously)
3830 if (copy_from_user(regs
, &sc
, sizeof(struct target_pt_regs
))) {
3834 /* make sure the U-flag is set so user-mode cannot fool us */
3838 /* restore the old USP as it was before we stacked the sc etc.
3839 * (we cannot just pop the sigcontext since we aligned the sp and
3840 * stuff after pushing it)
3843 __get_user(old_usp
, &sc
->usp
);
3844 phx_signal("old_usp 0x%lx", old_usp
);
3846 __PHX__ REALLY
/* ??? */
3848 regs
->gpr
[1] = old_usp
;
3850 /* TODO: the other ports use regs->orig_XX to disable syscall checks
3851 * after this completes, but we don't use that mechanism. maybe we can
3862 /* Set up a signal frame. */
3864 static void setup_sigcontext(struct target_sigcontext
*sc
,
3865 CPUOpenRISCState
*regs
,
3868 unsigned long usp
= regs
->gpr
[1];
3870 /* copy the regs. they are first in sc so we can use sc directly */
3872 /*copy_to_user(&sc, regs, sizeof(struct target_pt_regs));*/
3874 /* Set the frametype to CRIS_FRAME_NORMAL for the execution of
3875 the signal handler. The frametype will be restored to its previous
3876 value in restore_sigcontext. */
3877 /*regs->frametype = CRIS_FRAME_NORMAL;*/
3879 /* then some other stuff */
3880 __put_user(mask
, &sc
->oldmask
);
3881 __put_user(usp
, &sc
->usp
);
3884 static inline unsigned long align_sigframe(unsigned long sp
)
3891 static inline abi_ulong
get_sigframe(struct target_sigaction
*ka
,
3892 CPUOpenRISCState
*regs
,
3895 unsigned long sp
= regs
->gpr
[1];
3896 int onsigstack
= on_sig_stack(sp
);
3899 /* This is the X/Open sanctioned signal stack switching. */
3900 if ((ka
->sa_flags
& SA_ONSTACK
) != 0 && !onsigstack
) {
3901 sp
= target_sigaltstack_used
.ss_sp
+ target_sigaltstack_used
.ss_size
;
3904 sp
= align_sigframe(sp
- frame_size
);
3907 * If we are on the alternate signal stack and would overflow it, don't.
3908 * Return an always-bogus address instead so we will die with SIGSEGV.
3911 if (onsigstack
&& !likely(on_sig_stack(sp
))) {
3918 static void setup_frame(int sig
, struct target_sigaction
*ka
,
3919 target_sigset_t
*set
, CPUOpenRISCState
*env
)
3921 qemu_log("Not implement.\n");
3924 static void setup_rt_frame(int sig
, struct target_sigaction
*ka
,
3925 target_siginfo_t
*info
,
3926 target_sigset_t
*set
, CPUOpenRISCState
*env
)
3929 abi_ulong frame_addr
;
3930 unsigned long return_ip
;
3931 struct target_rt_sigframe
*frame
;
3932 abi_ulong info_addr
, uc_addr
;
3934 frame_addr
= get_sigframe(ka
, env
, sizeof(*frame
));
3935 if (!lock_user_struct(VERIFY_WRITE
, frame
, frame_addr
, 0)) {
3939 info_addr
= frame_addr
+ offsetof(struct target_rt_sigframe
, info
);
3940 __put_user(info_addr
, &frame
->pinfo
);
3941 uc_addr
= frame_addr
+ offsetof(struct target_rt_sigframe
, uc
);
3942 __put_user(uc_addr
, &frame
->puc
);
3944 if (ka
->sa_flags
& SA_SIGINFO
) {
3945 copy_siginfo_to_user(&frame
->info
, info
);
3948 /*err |= __clear_user(&frame->uc, offsetof(struct ucontext, uc_mcontext));*/
3949 __put_user(0, &frame
->uc
.tuc_flags
);
3950 __put_user(0, &frame
->uc
.tuc_link
);
3951 __put_user(target_sigaltstack_used
.ss_sp
,
3952 &frame
->uc
.tuc_stack
.ss_sp
);
3953 __put_user(sas_ss_flags(env
->gpr
[1]), &frame
->uc
.tuc_stack
.ss_flags
);
3954 __put_user(target_sigaltstack_used
.ss_size
,
3955 &frame
->uc
.tuc_stack
.ss_size
);
3956 setup_sigcontext(&frame
->sc
, env
, set
->sig
[0]);
3958 /*err |= copy_to_user(frame->uc.tuc_sigmask, set, sizeof(*set));*/
3960 /* trampoline - the desired return ip is the retcode itself */
3961 return_ip
= (unsigned long)&frame
->retcode
;
3962 /* This is l.ori r11,r0,__NR_sigreturn, l.sys 1 */
3963 __put_user(0xa960, (short *)(frame
->retcode
+ 0));
3964 __put_user(TARGET_NR_rt_sigreturn
, (short *)(frame
->retcode
+ 2));
3965 __put_user(0x20000001, (unsigned long *)(frame
->retcode
+ 4));
3966 __put_user(0x15000000, (unsigned long *)(frame
->retcode
+ 8));
3972 /* TODO what is the current->exec_domain stuff and invmap ? */
3974 /* Set up registers for signal handler */
3975 env
->pc
= (unsigned long)ka
->_sa_handler
; /* what we enter NOW */
3976 env
->gpr
[9] = (unsigned long)return_ip
; /* what we enter LATER */
3977 env
->gpr
[3] = (unsigned long)sig
; /* arg 1: signo */
3978 env
->gpr
[4] = (unsigned long)&frame
->info
; /* arg 2: (siginfo_t*) */
3979 env
->gpr
[5] = (unsigned long)&frame
->uc
; /* arg 3: ucontext */
3981 /* actually move the usp to reflect the stacked frame */
3982 env
->gpr
[1] = (unsigned long)frame
;
3987 unlock_user_struct(frame
, frame_addr
, 1);
3988 if (sig
== TARGET_SIGSEGV
) {
3989 ka
->_sa_handler
= TARGET_SIG_DFL
;
3991 force_sig(TARGET_SIGSEGV
);
3994 long do_sigreturn(CPUOpenRISCState
*env
)
3997 qemu_log("do_sigreturn: not implemented\n");
3998 return -TARGET_ENOSYS
;
4001 long do_rt_sigreturn(CPUOpenRISCState
*env
)
4003 qemu_log("do_rt_sigreturn: not implemented\n");
4004 return -TARGET_ENOSYS
;
4006 /* TARGET_OPENRISC */
4008 #elif defined(TARGET_S390X)
4010 #define __NUM_GPRS 16
4011 #define __NUM_FPRS 16
4012 #define __NUM_ACRS 16
4014 #define S390_SYSCALL_SIZE 2
4015 #define __SIGNAL_FRAMESIZE 160 /* FIXME: 31-bit mode -> 96 */
4017 #define _SIGCONTEXT_NSIG 64
4018 #define _SIGCONTEXT_NSIG_BPW 64 /* FIXME: 31-bit mode -> 32 */
4019 #define _SIGCONTEXT_NSIG_WORDS (_SIGCONTEXT_NSIG / _SIGCONTEXT_NSIG_BPW)
4020 #define _SIGMASK_COPY_SIZE (sizeof(unsigned long)*_SIGCONTEXT_NSIG_WORDS)
4021 #define PSW_ADDR_AMODE 0x0000000000000000UL /* 0x80000000UL for 31-bit */
4022 #define S390_SYSCALL_OPCODE ((uint16_t)0x0a00)
4026 target_ulong gprs
[__NUM_GPRS
];
4027 unsigned int acrs
[__NUM_ACRS
];
4028 } target_s390_regs_common
;
4032 double fprs
[__NUM_FPRS
];
4033 } target_s390_fp_regs
;
4036 target_s390_regs_common regs
;
4037 target_s390_fp_regs fpregs
;
4040 struct target_sigcontext
{
4041 target_ulong oldmask
[_SIGCONTEXT_NSIG_WORDS
];
4042 target_sigregs
*sregs
;
4046 uint8_t callee_used_stack
[__SIGNAL_FRAMESIZE
];
4047 struct target_sigcontext sc
;
4048 target_sigregs sregs
;
4050 uint8_t retcode
[S390_SYSCALL_SIZE
];
4053 struct target_ucontext
{
4054 target_ulong tuc_flags
;
4055 struct target_ucontext
*tuc_link
;
4056 target_stack_t tuc_stack
;
4057 target_sigregs tuc_mcontext
;
4058 target_sigset_t tuc_sigmask
; /* mask last for extensibility */
4062 uint8_t callee_used_stack
[__SIGNAL_FRAMESIZE
];
4063 uint8_t retcode
[S390_SYSCALL_SIZE
];
4064 struct target_siginfo info
;
4065 struct target_ucontext uc
;
4068 static inline abi_ulong
4069 get_sigframe(struct target_sigaction
*ka
, CPUS390XState
*env
, size_t frame_size
)
4073 /* Default to using normal stack */
4076 /* This is the X/Open sanctioned signal stack switching. */
4077 if (ka
->sa_flags
& TARGET_SA_ONSTACK
) {
4078 if (!sas_ss_flags(sp
)) {
4079 sp
= target_sigaltstack_used
.ss_sp
+
4080 target_sigaltstack_used
.ss_size
;
4084 /* This is the legacy signal stack switching. */
4085 else if (/* FIXME !user_mode(regs) */ 0 &&
4086 !(ka
->sa_flags
& TARGET_SA_RESTORER
) &&
4088 sp
= (abi_ulong
) ka
->sa_restorer
;
4091 return (sp
- frame_size
) & -8ul;
4094 static void save_sigregs(CPUS390XState
*env
, target_sigregs
*sregs
)
4097 //save_access_regs(current->thread.acrs); FIXME
4099 /* Copy a 'clean' PSW mask to the user to avoid leaking
4100 information about whether PER is currently on. */
4101 __put_user(env
->psw
.mask
, &sregs
->regs
.psw
.mask
);
4102 __put_user(env
->psw
.addr
, &sregs
->regs
.psw
.addr
);
4103 for (i
= 0; i
< 16; i
++) {
4104 __put_user(env
->regs
[i
], &sregs
->regs
.gprs
[i
]);
4106 for (i
= 0; i
< 16; i
++) {
4107 __put_user(env
->aregs
[i
], &sregs
->regs
.acrs
[i
]);
4110 * We have to store the fp registers to current->thread.fp_regs
4111 * to merge them with the emulated registers.
4113 //save_fp_regs(¤t->thread.fp_regs); FIXME
4114 for (i
= 0; i
< 16; i
++) {
4115 __put_user(env
->fregs
[i
].ll
, &sregs
->fpregs
.fprs
[i
]);
4119 static void setup_frame(int sig
, struct target_sigaction
*ka
,
4120 target_sigset_t
*set
, CPUS390XState
*env
)
4123 abi_ulong frame_addr
;
4125 frame_addr
= get_sigframe(ka
, env
, sizeof(*frame
));
4126 qemu_log("%s: frame_addr 0x%llx\n", __FUNCTION__
,
4127 (unsigned long long)frame_addr
);
4128 if (!lock_user_struct(VERIFY_WRITE
, frame
, frame_addr
, 0)) {
4132 qemu_log("%s: 1\n", __FUNCTION__
);
4133 __put_user(set
->sig
[0], &frame
->sc
.oldmask
[0]);
4135 save_sigregs(env
, &frame
->sregs
);
4137 __put_user((abi_ulong
)(unsigned long)&frame
->sregs
,
4138 (abi_ulong
*)&frame
->sc
.sregs
);
4140 /* Set up to return from userspace. If provided, use a stub
4141 already in userspace. */
4142 if (ka
->sa_flags
& TARGET_SA_RESTORER
) {
4143 env
->regs
[14] = (unsigned long)
4144 ka
->sa_restorer
| PSW_ADDR_AMODE
;
4146 env
->regs
[14] = (unsigned long)
4147 frame
->retcode
| PSW_ADDR_AMODE
;
4148 __put_user(S390_SYSCALL_OPCODE
| TARGET_NR_sigreturn
,
4149 (uint16_t *)(frame
->retcode
));
4152 /* Set up backchain. */
4153 __put_user(env
->regs
[15], (abi_ulong
*) frame
);
4155 /* Set up registers for signal handler */
4156 env
->regs
[15] = frame_addr
;
4157 env
->psw
.addr
= (target_ulong
) ka
->_sa_handler
| PSW_ADDR_AMODE
;
4159 env
->regs
[2] = sig
; //map_signal(sig);
4160 env
->regs
[3] = frame_addr
+= offsetof(typeof(*frame
), sc
);
4162 /* We forgot to include these in the sigcontext.
4163 To avoid breaking binary compatibility, they are passed as args. */
4164 env
->regs
[4] = 0; // FIXME: no clue... current->thread.trap_no;
4165 env
->regs
[5] = 0; // FIXME: no clue... current->thread.prot_addr;
4167 /* Place signal number on stack to allow backtrace from handler. */
4168 __put_user(env
->regs
[2], (int *) &frame
->signo
);
4169 unlock_user_struct(frame
, frame_addr
, 1);
4173 qemu_log("%s: give_sigsegv\n", __FUNCTION__
);
4174 force_sig(TARGET_SIGSEGV
);
4177 static void setup_rt_frame(int sig
, struct target_sigaction
*ka
,
4178 target_siginfo_t
*info
,
4179 target_sigset_t
*set
, CPUS390XState
*env
)
4183 abi_ulong frame_addr
;
4185 frame_addr
= get_sigframe(ka
, env
, sizeof *frame
);
4186 qemu_log("%s: frame_addr 0x%llx\n", __FUNCTION__
,
4187 (unsigned long long)frame_addr
);
4188 if (!lock_user_struct(VERIFY_WRITE
, frame
, frame_addr
, 0)) {
4192 qemu_log("%s: 1\n", __FUNCTION__
);
4193 copy_siginfo_to_user(&frame
->info
, info
);
4195 /* Create the ucontext. */
4196 __put_user(0, &frame
->uc
.tuc_flags
);
4197 __put_user((abi_ulong
)0, (abi_ulong
*)&frame
->uc
.tuc_link
);
4198 __put_user(target_sigaltstack_used
.ss_sp
, &frame
->uc
.tuc_stack
.ss_sp
);
4199 __put_user(sas_ss_flags(get_sp_from_cpustate(env
)),
4200 &frame
->uc
.tuc_stack
.ss_flags
);
4201 __put_user(target_sigaltstack_used
.ss_size
, &frame
->uc
.tuc_stack
.ss_size
);
4202 save_sigregs(env
, &frame
->uc
.tuc_mcontext
);
4203 for (i
= 0; i
< TARGET_NSIG_WORDS
; i
++) {
4204 __put_user((abi_ulong
)set
->sig
[i
],
4205 (abi_ulong
*)&frame
->uc
.tuc_sigmask
.sig
[i
]);
4208 /* Set up to return from userspace. If provided, use a stub
4209 already in userspace. */
4210 if (ka
->sa_flags
& TARGET_SA_RESTORER
) {
4211 env
->regs
[14] = (unsigned long) ka
->sa_restorer
| PSW_ADDR_AMODE
;
4213 env
->regs
[14] = (unsigned long) frame
->retcode
| PSW_ADDR_AMODE
;
4214 __put_user(S390_SYSCALL_OPCODE
| TARGET_NR_rt_sigreturn
,
4215 (uint16_t *)(frame
->retcode
));
4218 /* Set up backchain. */
4219 __put_user(env
->regs
[15], (abi_ulong
*) frame
);
4221 /* Set up registers for signal handler */
4222 env
->regs
[15] = frame_addr
;
4223 env
->psw
.addr
= (target_ulong
) ka
->_sa_handler
| PSW_ADDR_AMODE
;
4225 env
->regs
[2] = sig
; //map_signal(sig);
4226 env
->regs
[3] = frame_addr
+ offsetof(typeof(*frame
), info
);
4227 env
->regs
[4] = frame_addr
+ offsetof(typeof(*frame
), uc
);
4231 qemu_log("%s: give_sigsegv\n", __FUNCTION__
);
4232 force_sig(TARGET_SIGSEGV
);
4236 restore_sigregs(CPUS390XState
*env
, target_sigregs
*sc
)
4241 for (i
= 0; i
< 16; i
++) {
4242 __get_user(env
->regs
[i
], &sc
->regs
.gprs
[i
]);
4245 __get_user(env
->psw
.mask
, &sc
->regs
.psw
.mask
);
4246 qemu_log("%s: sc->regs.psw.addr 0x%llx env->psw.addr 0x%llx\n",
4247 __FUNCTION__
, (unsigned long long)sc
->regs
.psw
.addr
,
4248 (unsigned long long)env
->psw
.addr
);
4249 __get_user(env
->psw
.addr
, &sc
->regs
.psw
.addr
);
4250 /* FIXME: 31-bit -> | PSW_ADDR_AMODE */
4252 for (i
= 0; i
< 16; i
++) {
4253 __get_user(env
->aregs
[i
], &sc
->regs
.acrs
[i
]);
4255 for (i
= 0; i
< 16; i
++) {
4256 __get_user(env
->fregs
[i
].ll
, &sc
->fpregs
.fprs
[i
]);
4262 long do_sigreturn(CPUS390XState
*env
)
4265 abi_ulong frame_addr
= env
->regs
[15];
4266 qemu_log("%s: frame_addr 0x%llx\n", __FUNCTION__
,
4267 (unsigned long long)frame_addr
);
4268 target_sigset_t target_set
;
4271 if (!lock_user_struct(VERIFY_READ
, frame
, frame_addr
, 1)) {
4274 __get_user(target_set
.sig
[0], &frame
->sc
.oldmask
[0]);
4276 target_to_host_sigset_internal(&set
, &target_set
);
4277 do_sigprocmask(SIG_SETMASK
, &set
, NULL
); /* ~_BLOCKABLE? */
4279 if (restore_sigregs(env
, &frame
->sregs
)) {
4283 unlock_user_struct(frame
, frame_addr
, 0);
4284 return env
->regs
[2];
4287 force_sig(TARGET_SIGSEGV
);
4291 long do_rt_sigreturn(CPUS390XState
*env
)
4294 abi_ulong frame_addr
= env
->regs
[15];
4295 qemu_log("%s: frame_addr 0x%llx\n", __FUNCTION__
,
4296 (unsigned long long)frame_addr
);
4299 if (!lock_user_struct(VERIFY_READ
, frame
, frame_addr
, 1)) {
4302 target_to_host_sigset(&set
, &frame
->uc
.tuc_sigmask
);
4304 do_sigprocmask(SIG_SETMASK
, &set
, NULL
); /* ~_BLOCKABLE? */
4306 if (restore_sigregs(env
, &frame
->uc
.tuc_mcontext
)) {
4310 if (do_sigaltstack(frame_addr
+ offsetof(rt_sigframe
, uc
.tuc_stack
), 0,
4311 get_sp_from_cpustate(env
)) == -EFAULT
) {
4314 unlock_user_struct(frame
, frame_addr
, 0);
4315 return env
->regs
[2];
4318 unlock_user_struct(frame
, frame_addr
, 0);
4319 force_sig(TARGET_SIGSEGV
);
4323 #elif defined(TARGET_PPC) && !defined(TARGET_PPC64)
4325 /* FIXME: Many of the structures are defined for both PPC and PPC64, but
4326 the signal handling is different enough that we haven't implemented
4327 support for PPC64 yet. Hence the restriction above.
4329 There are various #if'd blocks for code for TARGET_PPC64. These
4330 blocks should go away so that we can successfully run 32-bit and
4331 64-bit binaries on a QEMU configured for PPC64. */
4333 /* Size of dummy stack frame allocated when calling signal handler.
4334 See arch/powerpc/include/asm/ptrace.h. */
4335 #if defined(TARGET_PPC64)
4336 #define SIGNAL_FRAMESIZE 128
4338 #define SIGNAL_FRAMESIZE 64
4341 /* See arch/powerpc/include/asm/sigcontext.h. */
4342 struct target_sigcontext
{
4343 target_ulong _unused
[4];
4345 #if defined(TARGET_PPC64)
4348 target_ulong handler
;
4349 target_ulong oldmask
;
4350 target_ulong regs
; /* struct pt_regs __user * */
4351 /* TODO: PPC64 includes extra bits here. */
4354 /* Indices for target_mcontext.mc_gregs, below.
4355 See arch/powerpc/include/asm/ptrace.h for details. */
4391 TARGET_PT_ORIG_R3
= 34,
4396 /* Yes, there are two registers with #39. One is 64-bit only. */
4398 TARGET_PT_SOFTE
= 39,
4399 TARGET_PT_TRAP
= 40,
4401 TARGET_PT_DSISR
= 42,
4402 TARGET_PT_RESULT
= 43,
4403 TARGET_PT_REGS_COUNT
= 44
4406 /* See arch/powerpc/include/asm/ucontext.h. Only used for 32-bit PPC;
4407 on 64-bit PPC, sigcontext and mcontext are one and the same. */
4408 struct target_mcontext
{
4409 target_ulong mc_gregs
[48];
4410 /* Includes fpscr. */
4411 uint64_t mc_fregs
[33];
4412 target_ulong mc_pad
[2];
4413 /* We need to handle Altivec and SPE at the same time, which no
4414 kernel needs to do. Fortunately, the kernel defines this bit to
4415 be Altivec-register-large all the time, rather than trying to
4416 twiddle it based on the specific platform. */
4418 /* SPE vector registers. One extra for SPEFSCR. */
4420 /* Altivec vector registers. The packing of VSCR and VRSAVE
4421 varies depending on whether we're PPC64 or not: PPC64 splits
4422 them apart; PPC32 stuffs them together. */
4423 #if defined(TARGET_PPC64)
4424 #define QEMU_NVRREG 34
4426 #define QEMU_NVRREG 33
4428 ppc_avr_t altivec
[QEMU_NVRREG
];
4430 } mc_vregs
__attribute__((__aligned__(16)));
4433 struct target_ucontext
{
4434 target_ulong tuc_flags
;
4435 target_ulong tuc_link
; /* struct ucontext __user * */
4436 struct target_sigaltstack tuc_stack
;
4437 #if !defined(TARGET_PPC64)
4439 target_ulong tuc_regs
; /* struct mcontext __user *
4440 points to uc_mcontext field */
4442 target_sigset_t tuc_sigmask
;
4443 #if defined(TARGET_PPC64)
4444 target_sigset_t unused
[15]; /* Allow for uc_sigmask growth */
4445 struct target_sigcontext tuc_mcontext
;
4447 int32_t tuc_maskext
[30];
4448 int32_t tuc_pad2
[3];
4449 struct target_mcontext tuc_mcontext
;
4453 /* See arch/powerpc/kernel/signal_32.c. */
4454 struct target_sigframe
{
4455 struct target_sigcontext sctx
;
4456 struct target_mcontext mctx
;
4460 struct target_rt_sigframe
{
4461 struct target_siginfo info
;
4462 struct target_ucontext uc
;
4466 /* We use the mc_pad field for the signal return trampoline. */
4467 #define tramp mc_pad
4469 /* See arch/powerpc/kernel/signal.c. */
4470 static target_ulong
get_sigframe(struct target_sigaction
*ka
,
4474 target_ulong oldsp
, newsp
;
4476 oldsp
= env
->gpr
[1];
4478 if ((ka
->sa_flags
& TARGET_SA_ONSTACK
) &&
4479 (sas_ss_flags(oldsp
) == 0)) {
4480 oldsp
= (target_sigaltstack_used
.ss_sp
4481 + target_sigaltstack_used
.ss_size
);
4484 newsp
= (oldsp
- frame_size
) & ~0xFUL
;
4489 static void save_user_regs(CPUPPCState
*env
, struct target_mcontext
*frame
,
4492 target_ulong msr
= env
->msr
;
4494 target_ulong ccr
= 0;
4496 /* In general, the kernel attempts to be intelligent about what it
4497 needs to save for Altivec/FP/SPE registers. We don't care that
4498 much, so we just go ahead and save everything. */
4500 /* Save general registers. */
4501 for (i
= 0; i
< ARRAY_SIZE(env
->gpr
); i
++) {
4502 __put_user(env
->gpr
[i
], &frame
->mc_gregs
[i
]);
4504 __put_user(env
->nip
, &frame
->mc_gregs
[TARGET_PT_NIP
]);
4505 __put_user(env
->ctr
, &frame
->mc_gregs
[TARGET_PT_CTR
]);
4506 __put_user(env
->lr
, &frame
->mc_gregs
[TARGET_PT_LNK
]);
4507 __put_user(env
->xer
, &frame
->mc_gregs
[TARGET_PT_XER
]);
4509 for (i
= 0; i
< ARRAY_SIZE(env
->crf
); i
++) {
4510 ccr
|= env
->crf
[i
] << (32 - ((i
+ 1) * 4));
4512 __put_user(ccr
, &frame
->mc_gregs
[TARGET_PT_CCR
]);
4514 /* Save Altivec registers if necessary. */
4515 if (env
->insns_flags
& PPC_ALTIVEC
) {
4516 for (i
= 0; i
< ARRAY_SIZE(env
->avr
); i
++) {
4517 ppc_avr_t
*avr
= &env
->avr
[i
];
4518 ppc_avr_t
*vreg
= &frame
->mc_vregs
.altivec
[i
];
4520 __put_user(avr
->u64
[0], &vreg
->u64
[0]);
4521 __put_user(avr
->u64
[1], &vreg
->u64
[1]);
4523 /* Set MSR_VR in the saved MSR value to indicate that
4524 frame->mc_vregs contains valid data. */
4526 __put_user((uint32_t)env
->spr
[SPR_VRSAVE
],
4527 &frame
->mc_vregs
.altivec
[32].u32
[3]);
4530 /* Save floating point registers. */
4531 if (env
->insns_flags
& PPC_FLOAT
) {
4532 for (i
= 0; i
< ARRAY_SIZE(env
->fpr
); i
++) {
4533 __put_user(env
->fpr
[i
], &frame
->mc_fregs
[i
]);
4535 __put_user((uint64_t) env
->fpscr
, &frame
->mc_fregs
[32]);
4538 /* Save SPE registers. The kernel only saves the high half. */
4539 if (env
->insns_flags
& PPC_SPE
) {
4540 #if defined(TARGET_PPC64)
4541 for (i
= 0; i
< ARRAY_SIZE(env
->gpr
); i
++) {
4542 __put_user(env
->gpr
[i
] >> 32, &frame
->mc_vregs
.spe
[i
]);
4545 for (i
= 0; i
< ARRAY_SIZE(env
->gprh
); i
++) {
4546 __put_user(env
->gprh
[i
], &frame
->mc_vregs
.spe
[i
]);
4549 /* Set MSR_SPE in the saved MSR value to indicate that
4550 frame->mc_vregs contains valid data. */
4552 __put_user(env
->spe_fscr
, &frame
->mc_vregs
.spe
[32]);
4556 __put_user(msr
, &frame
->mc_gregs
[TARGET_PT_MSR
]);
4558 /* Set up the sigreturn trampoline: li r0,sigret; sc. */
4560 __put_user(0x38000000UL
| sigret
, &frame
->tramp
[0]);
4561 __put_user(0x44000002UL
, &frame
->tramp
[1]);
4565 static void restore_user_regs(CPUPPCState
*env
,
4566 struct target_mcontext
*frame
, int sig
)
4568 target_ulong save_r2
= 0;
4575 save_r2
= env
->gpr
[2];
4578 /* Restore general registers. */
4579 for (i
= 0; i
< ARRAY_SIZE(env
->gpr
); i
++) {
4580 __get_user(env
->gpr
[i
], &frame
->mc_gregs
[i
]);
4582 __get_user(env
->nip
, &frame
->mc_gregs
[TARGET_PT_NIP
]);
4583 __get_user(env
->ctr
, &frame
->mc_gregs
[TARGET_PT_CTR
]);
4584 __get_user(env
->lr
, &frame
->mc_gregs
[TARGET_PT_LNK
]);
4585 __get_user(env
->xer
, &frame
->mc_gregs
[TARGET_PT_XER
]);
4586 __get_user(ccr
, &frame
->mc_gregs
[TARGET_PT_CCR
]);
4588 for (i
= 0; i
< ARRAY_SIZE(env
->crf
); i
++) {
4589 env
->crf
[i
] = (ccr
>> (32 - ((i
+ 1) * 4))) & 0xf;
4593 env
->gpr
[2] = save_r2
;
4596 __get_user(msr
, &frame
->mc_gregs
[TARGET_PT_MSR
]);
4598 /* If doing signal return, restore the previous little-endian mode. */
4600 env
->msr
= (env
->msr
& ~MSR_LE
) | (msr
& MSR_LE
);
4602 /* Restore Altivec registers if necessary. */
4603 if (env
->insns_flags
& PPC_ALTIVEC
) {
4604 for (i
= 0; i
< ARRAY_SIZE(env
->avr
); i
++) {
4605 ppc_avr_t
*avr
= &env
->avr
[i
];
4606 ppc_avr_t
*vreg
= &frame
->mc_vregs
.altivec
[i
];
4608 __get_user(avr
->u64
[0], &vreg
->u64
[0]);
4609 __get_user(avr
->u64
[1], &vreg
->u64
[1]);
4611 /* Set MSR_VEC in the saved MSR value to indicate that
4612 frame->mc_vregs contains valid data. */
4613 __get_user(env
->spr
[SPR_VRSAVE
],
4614 (target_ulong
*)(&frame
->mc_vregs
.altivec
[32].u32
[3]));
4617 /* Restore floating point registers. */
4618 if (env
->insns_flags
& PPC_FLOAT
) {
4620 for (i
= 0; i
< ARRAY_SIZE(env
->fpr
); i
++) {
4621 __get_user(env
->fpr
[i
], &frame
->mc_fregs
[i
]);
4623 __get_user(fpscr
, &frame
->mc_fregs
[32]);
4624 env
->fpscr
= (uint32_t) fpscr
;
4627 /* Save SPE registers. The kernel only saves the high half. */
4628 if (env
->insns_flags
& PPC_SPE
) {
4629 #if defined(TARGET_PPC64)
4630 for (i
= 0; i
< ARRAY_SIZE(env
->gpr
); i
++) {
4633 __get_user(hi
, &frame
->mc_vregs
.spe
[i
]);
4634 env
->gpr
[i
] = ((uint64_t)hi
<< 32) | ((uint32_t) env
->gpr
[i
]);
4637 for (i
= 0; i
< ARRAY_SIZE(env
->gprh
); i
++) {
4638 __get_user(env
->gprh
[i
], &frame
->mc_vregs
.spe
[i
]);
4641 __get_user(env
->spe_fscr
, &frame
->mc_vregs
.spe
[32]);
4645 static void setup_frame(int sig
, struct target_sigaction
*ka
,
4646 target_sigset_t
*set
, CPUPPCState
*env
)
4648 struct target_sigframe
*frame
;
4649 struct target_sigcontext
*sc
;
4650 target_ulong frame_addr
, newsp
;
4654 frame_addr
= get_sigframe(ka
, env
, sizeof(*frame
));
4655 if (!lock_user_struct(VERIFY_WRITE
, frame
, frame_addr
, 1))
4659 signal
= current_exec_domain_sig(sig
);
4661 __put_user(ka
->_sa_handler
, &sc
->handler
);
4662 __put_user(set
->sig
[0], &sc
->oldmask
);
4663 #if defined(TARGET_PPC64)
4664 __put_user(set
->sig
[0] >> 32, &sc
->_unused
[3]);
4666 __put_user(set
->sig
[1], &sc
->_unused
[3]);
4668 __put_user(h2g(&frame
->mctx
), &sc
->regs
);
4669 __put_user(sig
, &sc
->signal
);
4671 /* Save user regs. */
4672 save_user_regs(env
, &frame
->mctx
, TARGET_NR_sigreturn
);
4674 /* The kernel checks for the presence of a VDSO here. We don't
4675 emulate a vdso, so use a sigreturn system call. */
4676 env
->lr
= (target_ulong
) h2g(frame
->mctx
.tramp
);
4678 /* Turn off all fp exceptions. */
4681 /* Create a stack frame for the caller of the handler. */
4682 newsp
= frame_addr
- SIGNAL_FRAMESIZE
;
4683 err
|= put_user(env
->gpr
[1], newsp
, target_ulong
);
4688 /* Set up registers for signal handler. */
4689 env
->gpr
[1] = newsp
;
4690 env
->gpr
[3] = signal
;
4691 env
->gpr
[4] = frame_addr
+ offsetof(struct target_sigframe
, sctx
);
4692 env
->nip
= (target_ulong
) ka
->_sa_handler
;
4693 /* Signal handlers are entered in big-endian mode. */
4694 env
->msr
&= ~MSR_LE
;
4696 unlock_user_struct(frame
, frame_addr
, 1);
4700 unlock_user_struct(frame
, frame_addr
, 1);
4701 qemu_log("segfaulting from setup_frame\n");
4702 force_sig(TARGET_SIGSEGV
);
4705 static void setup_rt_frame(int sig
, struct target_sigaction
*ka
,
4706 target_siginfo_t
*info
,
4707 target_sigset_t
*set
, CPUPPCState
*env
)
4709 struct target_rt_sigframe
*rt_sf
;
4710 struct target_mcontext
*frame
;
4711 target_ulong rt_sf_addr
, newsp
= 0;
4715 rt_sf_addr
= get_sigframe(ka
, env
, sizeof(*rt_sf
));
4716 if (!lock_user_struct(VERIFY_WRITE
, rt_sf
, rt_sf_addr
, 1))
4719 signal
= current_exec_domain_sig(sig
);
4721 copy_siginfo_to_user(&rt_sf
->info
, info
);
4723 __put_user(0, &rt_sf
->uc
.tuc_flags
);
4724 __put_user(0, &rt_sf
->uc
.tuc_link
);
4725 __put_user((target_ulong
)target_sigaltstack_used
.ss_sp
,
4726 &rt_sf
->uc
.tuc_stack
.ss_sp
);
4727 __put_user(sas_ss_flags(env
->gpr
[1]),
4728 &rt_sf
->uc
.tuc_stack
.ss_flags
);
4729 __put_user(target_sigaltstack_used
.ss_size
,
4730 &rt_sf
->uc
.tuc_stack
.ss_size
);
4731 __put_user(h2g (&rt_sf
->uc
.tuc_mcontext
),
4732 &rt_sf
->uc
.tuc_regs
);
4733 for(i
= 0; i
< TARGET_NSIG_WORDS
; i
++) {
4734 __put_user(set
->sig
[i
], &rt_sf
->uc
.tuc_sigmask
.sig
[i
]);
4737 frame
= &rt_sf
->uc
.tuc_mcontext
;
4738 save_user_regs(env
, frame
, TARGET_NR_rt_sigreturn
);
4740 /* The kernel checks for the presence of a VDSO here. We don't
4741 emulate a vdso, so use a sigreturn system call. */
4742 env
->lr
= (target_ulong
) h2g(frame
->tramp
);
4744 /* Turn off all fp exceptions. */
4747 /* Create a stack frame for the caller of the handler. */
4748 newsp
= rt_sf_addr
- (SIGNAL_FRAMESIZE
+ 16);
4749 __put_user(env
->gpr
[1], (target_ulong
*)(uintptr_t) newsp
);
4754 /* Set up registers for signal handler. */
4755 env
->gpr
[1] = newsp
;
4756 env
->gpr
[3] = (target_ulong
) signal
;
4757 env
->gpr
[4] = (target_ulong
) h2g(&rt_sf
->info
);
4758 env
->gpr
[5] = (target_ulong
) h2g(&rt_sf
->uc
);
4759 env
->gpr
[6] = (target_ulong
) h2g(rt_sf
);
4760 env
->nip
= (target_ulong
) ka
->_sa_handler
;
4761 /* Signal handlers are entered in big-endian mode. */
4762 env
->msr
&= ~MSR_LE
;
4764 unlock_user_struct(rt_sf
, rt_sf_addr
, 1);
4768 unlock_user_struct(rt_sf
, rt_sf_addr
, 1);
4769 qemu_log("segfaulting from setup_rt_frame\n");
4770 force_sig(TARGET_SIGSEGV
);
4774 long do_sigreturn(CPUPPCState
*env
)
4776 struct target_sigcontext
*sc
= NULL
;
4777 struct target_mcontext
*sr
= NULL
;
4778 target_ulong sr_addr
= 0, sc_addr
;
4780 target_sigset_t set
;
4782 sc_addr
= env
->gpr
[1] + SIGNAL_FRAMESIZE
;
4783 if (!lock_user_struct(VERIFY_READ
, sc
, sc_addr
, 1))
4786 #if defined(TARGET_PPC64)
4787 set
.sig
[0] = sc
->oldmask
+ ((long)(sc
->_unused
[3]) << 32);
4789 __get_user(set
.sig
[0], &sc
->oldmask
);
4790 __get_user(set
.sig
[1], &sc
->_unused
[3]);
4792 target_to_host_sigset_internal(&blocked
, &set
);
4793 do_sigprocmask(SIG_SETMASK
, &blocked
, NULL
);
4795 __get_user(sr_addr
, &sc
->regs
);
4796 if (!lock_user_struct(VERIFY_READ
, sr
, sr_addr
, 1))
4798 restore_user_regs(env
, sr
, 1);
4800 unlock_user_struct(sr
, sr_addr
, 1);
4801 unlock_user_struct(sc
, sc_addr
, 1);
4802 return -TARGET_QEMU_ESIGRETURN
;
4805 unlock_user_struct(sr
, sr_addr
, 1);
4806 unlock_user_struct(sc
, sc_addr
, 1);
4807 qemu_log("segfaulting from do_sigreturn\n");
4808 force_sig(TARGET_SIGSEGV
);
4812 /* See arch/powerpc/kernel/signal_32.c. */
4813 static int do_setcontext(struct target_ucontext
*ucp
, CPUPPCState
*env
, int sig
)
4815 struct target_mcontext
*mcp
;
4816 target_ulong mcp_addr
;
4818 target_sigset_t set
;
4820 if (copy_from_user(&set
, h2g(ucp
) + offsetof(struct target_ucontext
, tuc_sigmask
),
4824 #if defined(TARGET_PPC64)
4825 fprintf (stderr
, "do_setcontext: not implemented\n");
4828 if (__get_user(mcp_addr
, &ucp
->tuc_regs
))
4831 if (!lock_user_struct(VERIFY_READ
, mcp
, mcp_addr
, 1))
4834 target_to_host_sigset_internal(&blocked
, &set
);
4835 do_sigprocmask(SIG_SETMASK
, &blocked
, NULL
);
4836 restore_user_regs(env
, mcp
, sig
);
4838 unlock_user_struct(mcp
, mcp_addr
, 1);
4843 long do_rt_sigreturn(CPUPPCState
*env
)
4845 struct target_rt_sigframe
*rt_sf
= NULL
;
4846 target_ulong rt_sf_addr
;
4848 rt_sf_addr
= env
->gpr
[1] + SIGNAL_FRAMESIZE
+ 16;
4849 if (!lock_user_struct(VERIFY_READ
, rt_sf
, rt_sf_addr
, 1))
4852 if (do_setcontext(&rt_sf
->uc
, env
, 1))
4855 do_sigaltstack(rt_sf_addr
4856 + offsetof(struct target_rt_sigframe
, uc
.tuc_stack
),
4859 unlock_user_struct(rt_sf
, rt_sf_addr
, 1);
4860 return -TARGET_QEMU_ESIGRETURN
;
4863 unlock_user_struct(rt_sf
, rt_sf_addr
, 1);
4864 qemu_log("segfaulting from do_rt_sigreturn\n");
4865 force_sig(TARGET_SIGSEGV
);
4869 #elif defined(TARGET_M68K)
4871 struct target_sigcontext
{
4878 unsigned short sc_sr
;
4882 struct target_sigframe
4889 abi_ulong extramask
[TARGET_NSIG_WORDS
-1];
4890 struct target_sigcontext sc
;
4893 typedef int target_greg_t
;
4894 #define TARGET_NGREG 18
4895 typedef target_greg_t target_gregset_t
[TARGET_NGREG
];
4897 typedef struct target_fpregset
{
4900 } target_fpregset_t
;
4902 struct target_mcontext
{
4904 target_gregset_t gregs
;
4905 target_fpregset_t fpregs
;
4908 #define TARGET_MCONTEXT_VERSION 2
4910 struct target_ucontext
{
4911 abi_ulong tuc_flags
;
4913 target_stack_t tuc_stack
;
4914 struct target_mcontext tuc_mcontext
;
4915 abi_long tuc_filler
[80];
4916 target_sigset_t tuc_sigmask
;
4919 struct target_rt_sigframe
4926 struct target_siginfo info
;
4927 struct target_ucontext uc
;
4930 static void setup_sigcontext(struct target_sigcontext
*sc
, CPUM68KState
*env
,
4933 __put_user(mask
, &sc
->sc_mask
);
4934 __put_user(env
->aregs
[7], &sc
->sc_usp
);
4935 __put_user(env
->dregs
[0], &sc
->sc_d0
);
4936 __put_user(env
->dregs
[1], &sc
->sc_d1
);
4937 __put_user(env
->aregs
[0], &sc
->sc_a0
);
4938 __put_user(env
->aregs
[1], &sc
->sc_a1
);
4939 __put_user(env
->sr
, &sc
->sc_sr
);
4940 __put_user(env
->pc
, &sc
->sc_pc
);
4944 restore_sigcontext(CPUM68KState
*env
, struct target_sigcontext
*sc
, int *pd0
)
4948 __get_user(env
->aregs
[7], &sc
->sc_usp
);
4949 __get_user(env
->dregs
[1], &sc
->sc_d1
);
4950 __get_user(env
->aregs
[0], &sc
->sc_a0
);
4951 __get_user(env
->aregs
[1], &sc
->sc_a1
);
4952 __get_user(env
->pc
, &sc
->sc_pc
);
4953 __get_user(temp
, &sc
->sc_sr
);
4954 env
->sr
= (env
->sr
& 0xff00) | (temp
& 0xff);
4956 *pd0
= tswapl(sc
->sc_d0
);
4960 * Determine which stack to use..
4962 static inline abi_ulong
4963 get_sigframe(struct target_sigaction
*ka
, CPUM68KState
*regs
,
4968 sp
= regs
->aregs
[7];
4970 /* This is the X/Open sanctioned signal stack switching. */
4971 if ((ka
->sa_flags
& TARGET_SA_ONSTACK
) && (sas_ss_flags (sp
) == 0)) {
4972 sp
= target_sigaltstack_used
.ss_sp
+ target_sigaltstack_used
.ss_size
;
4975 return ((sp
- frame_size
) & -8UL);
4978 static void setup_frame(int sig
, struct target_sigaction
*ka
,
4979 target_sigset_t
*set
, CPUM68KState
*env
)
4981 struct target_sigframe
*frame
;
4982 abi_ulong frame_addr
;
4983 abi_ulong retcode_addr
;
4987 frame_addr
= get_sigframe(ka
, env
, sizeof *frame
);
4988 if (!lock_user_struct(VERIFY_WRITE
, frame
, frame_addr
, 0))
4991 __put_user(sig
, &frame
->sig
);
4993 sc_addr
= frame_addr
+ offsetof(struct target_sigframe
, sc
);
4994 __put_user(sc_addr
, &frame
->psc
);
4996 setup_sigcontext(&frame
->sc
, env
, set
->sig
[0]);
4998 for(i
= 1; i
< TARGET_NSIG_WORDS
; i
++) {
4999 __put_user(set
->sig
[i
], &frame
->extramask
[i
- 1]);
5002 /* Set up to return from userspace. */
5004 retcode_addr
= frame_addr
+ offsetof(struct target_sigframe
, retcode
);
5005 __put_user(retcode_addr
, &frame
->pretcode
);
5007 /* moveq #,d0; trap #0 */
5009 __put_user(0x70004e40 + (TARGET_NR_sigreturn
<< 16),
5010 (long *)(frame
->retcode
));
5012 /* Set up to return from userspace */
5014 env
->aregs
[7] = frame_addr
;
5015 env
->pc
= ka
->_sa_handler
;
5017 unlock_user_struct(frame
, frame_addr
, 1);
5021 force_sig(TARGET_SIGSEGV
);
5024 static inline int target_rt_setup_ucontext(struct target_ucontext
*uc
,
5027 target_greg_t
*gregs
= uc
->tuc_mcontext
.gregs
;
5029 __put_user(TARGET_MCONTEXT_VERSION
, &uc
->tuc_mcontext
.version
);
5030 __put_user(env
->dregs
[0], &gregs
[0]);
5031 __put_user(env
->dregs
[1], &gregs
[1]);
5032 __put_user(env
->dregs
[2], &gregs
[2]);
5033 __put_user(env
->dregs
[3], &gregs
[3]);
5034 __put_user(env
->dregs
[4], &gregs
[4]);
5035 __put_user(env
->dregs
[5], &gregs
[5]);
5036 __put_user(env
->dregs
[6], &gregs
[6]);
5037 __put_user(env
->dregs
[7], &gregs
[7]);
5038 __put_user(env
->aregs
[0], &gregs
[8]);
5039 __put_user(env
->aregs
[1], &gregs
[9]);
5040 __put_user(env
->aregs
[2], &gregs
[10]);
5041 __put_user(env
->aregs
[3], &gregs
[11]);
5042 __put_user(env
->aregs
[4], &gregs
[12]);
5043 __put_user(env
->aregs
[5], &gregs
[13]);
5044 __put_user(env
->aregs
[6], &gregs
[14]);
5045 __put_user(env
->aregs
[7], &gregs
[15]);
5046 __put_user(env
->pc
, &gregs
[16]);
5047 __put_user(env
->sr
, &gregs
[17]);
5052 static inline int target_rt_restore_ucontext(CPUM68KState
*env
,
5053 struct target_ucontext
*uc
,
5057 target_greg_t
*gregs
= uc
->tuc_mcontext
.gregs
;
5059 __get_user(temp
, &uc
->tuc_mcontext
.version
);
5060 if (temp
!= TARGET_MCONTEXT_VERSION
)
5063 /* restore passed registers */
5064 __get_user(env
->dregs
[0], &gregs
[0]);
5065 __get_user(env
->dregs
[1], &gregs
[1]);
5066 __get_user(env
->dregs
[2], &gregs
[2]);
5067 __get_user(env
->dregs
[3], &gregs
[3]);
5068 __get_user(env
->dregs
[4], &gregs
[4]);
5069 __get_user(env
->dregs
[5], &gregs
[5]);
5070 __get_user(env
->dregs
[6], &gregs
[6]);
5071 __get_user(env
->dregs
[7], &gregs
[7]);
5072 __get_user(env
->aregs
[0], &gregs
[8]);
5073 __get_user(env
->aregs
[1], &gregs
[9]);
5074 __get_user(env
->aregs
[2], &gregs
[10]);
5075 __get_user(env
->aregs
[3], &gregs
[11]);
5076 __get_user(env
->aregs
[4], &gregs
[12]);
5077 __get_user(env
->aregs
[5], &gregs
[13]);
5078 __get_user(env
->aregs
[6], &gregs
[14]);
5079 __get_user(env
->aregs
[7], &gregs
[15]);
5080 __get_user(env
->pc
, &gregs
[16]);
5081 __get_user(temp
, &gregs
[17]);
5082 env
->sr
= (env
->sr
& 0xff00) | (temp
& 0xff);
5084 *pd0
= env
->dregs
[0];
5091 static void setup_rt_frame(int sig
, struct target_sigaction
*ka
,
5092 target_siginfo_t
*info
,
5093 target_sigset_t
*set
, CPUM68KState
*env
)
5095 struct target_rt_sigframe
*frame
;
5096 abi_ulong frame_addr
;
5097 abi_ulong retcode_addr
;
5098 abi_ulong info_addr
;
5103 frame_addr
= get_sigframe(ka
, env
, sizeof *frame
);
5104 if (!lock_user_struct(VERIFY_WRITE
, frame
, frame_addr
, 0))
5107 __put_user(sig
, &frame
->sig
);
5109 info_addr
= frame_addr
+ offsetof(struct target_rt_sigframe
, info
);
5110 __put_user(info_addr
, &frame
->pinfo
);
5112 uc_addr
= frame_addr
+ offsetof(struct target_rt_sigframe
, uc
);
5113 __put_user(uc_addr
, &frame
->puc
);
5115 copy_siginfo_to_user(&frame
->info
, info
);
5117 /* Create the ucontext */
5119 __put_user(0, &frame
->uc
.tuc_flags
);
5120 __put_user(0, &frame
->uc
.tuc_link
);
5121 __put_user(target_sigaltstack_used
.ss_sp
,
5122 &frame
->uc
.tuc_stack
.ss_sp
);
5123 __put_user(sas_ss_flags(env
->aregs
[7]),
5124 &frame
->uc
.tuc_stack
.ss_flags
);
5125 __put_user(target_sigaltstack_used
.ss_size
,
5126 &frame
->uc
.tuc_stack
.ss_size
);
5127 err
|= target_rt_setup_ucontext(&frame
->uc
, env
);
5132 for(i
= 0; i
< TARGET_NSIG_WORDS
; i
++) {
5133 __put_user(set
->sig
[i
], &frame
->uc
.tuc_sigmask
.sig
[i
]);
5136 /* Set up to return from userspace. */
5138 retcode_addr
= frame_addr
+ offsetof(struct target_sigframe
, retcode
);
5139 __put_user(retcode_addr
, &frame
->pretcode
);
5141 /* moveq #,d0; notb d0; trap #0 */
5143 __put_user(0x70004600 + ((TARGET_NR_rt_sigreturn
^ 0xff) << 16),
5144 (long *)(frame
->retcode
+ 0));
5145 __put_user(0x4e40, (short *)(frame
->retcode
+ 4));
5150 /* Set up to return from userspace */
5152 env
->aregs
[7] = frame_addr
;
5153 env
->pc
= ka
->_sa_handler
;
5155 unlock_user_struct(frame
, frame_addr
, 1);
5159 unlock_user_struct(frame
, frame_addr
, 1);
5160 force_sig(TARGET_SIGSEGV
);
5163 long do_sigreturn(CPUM68KState
*env
)
5165 struct target_sigframe
*frame
;
5166 abi_ulong frame_addr
= env
->aregs
[7] - 4;
5167 target_sigset_t target_set
;
5171 if (!lock_user_struct(VERIFY_READ
, frame
, frame_addr
, 1))
5174 /* set blocked signals */
5176 __get_user(target_set
.sig
[0], &frame
->sc
.sc_mask
);
5178 for(i
= 1; i
< TARGET_NSIG_WORDS
; i
++) {
5179 __get_user(target_set
.sig
[i
], &frame
->extramask
[i
- 1]);
5182 target_to_host_sigset_internal(&set
, &target_set
);
5183 do_sigprocmask(SIG_SETMASK
, &set
, NULL
);
5185 /* restore registers */
5187 restore_sigcontext(env
, &frame
->sc
, &d0
);
5189 unlock_user_struct(frame
, frame_addr
, 0);
5193 force_sig(TARGET_SIGSEGV
);
5197 long do_rt_sigreturn(CPUM68KState
*env
)
5199 struct target_rt_sigframe
*frame
;
5200 abi_ulong frame_addr
= env
->aregs
[7] - 4;
5201 target_sigset_t target_set
;
5205 if (!lock_user_struct(VERIFY_READ
, frame
, frame_addr
, 1))
5208 target_to_host_sigset_internal(&set
, &target_set
);
5209 do_sigprocmask(SIG_SETMASK
, &set
, NULL
);
5211 /* restore registers */
5213 if (target_rt_restore_ucontext(env
, &frame
->uc
, &d0
))
5216 if (do_sigaltstack(frame_addr
+
5217 offsetof(struct target_rt_sigframe
, uc
.tuc_stack
),
5218 0, get_sp_from_cpustate(env
)) == -EFAULT
)
5221 unlock_user_struct(frame
, frame_addr
, 0);
5225 unlock_user_struct(frame
, frame_addr
, 0);
5226 force_sig(TARGET_SIGSEGV
);
5230 #elif defined(TARGET_ALPHA)
5232 struct target_sigcontext
{
5233 abi_long sc_onstack
;
5237 abi_long sc_regs
[32];
5238 abi_long sc_ownedfp
;
5239 abi_long sc_fpregs
[32];
5241 abi_ulong sc_fp_control
;
5242 abi_ulong sc_reserved1
;
5243 abi_ulong sc_reserved2
;
5246 abi_ulong sc_traparg_a0
;
5247 abi_ulong sc_traparg_a1
;
5248 abi_ulong sc_traparg_a2
;
5249 abi_ulong sc_fp_trap_pc
;
5250 abi_ulong sc_fp_trigger_sum
;
5251 abi_ulong sc_fp_trigger_inst
;
5254 struct target_ucontext
{
5255 abi_ulong tuc_flags
;
5257 abi_ulong tuc_osf_sigmask
;
5258 target_stack_t tuc_stack
;
5259 struct target_sigcontext tuc_mcontext
;
5260 target_sigset_t tuc_sigmask
;
5263 struct target_sigframe
{
5264 struct target_sigcontext sc
;
5265 unsigned int retcode
[3];
5268 struct target_rt_sigframe
{
5269 target_siginfo_t info
;
5270 struct target_ucontext uc
;
5271 unsigned int retcode
[3];
5274 #define INSN_MOV_R30_R16 0x47fe0410
5275 #define INSN_LDI_R0 0x201f0000
5276 #define INSN_CALLSYS 0x00000083
5278 static void setup_sigcontext(struct target_sigcontext
*sc
, CPUAlphaState
*env
,
5279 abi_ulong frame_addr
, target_sigset_t
*set
)
5283 __put_user(on_sig_stack(frame_addr
), &sc
->sc_onstack
);
5284 __put_user(set
->sig
[0], &sc
->sc_mask
);
5285 __put_user(env
->pc
, &sc
->sc_pc
);
5286 __put_user(8, &sc
->sc_ps
);
5288 for (i
= 0; i
< 31; ++i
) {
5289 __put_user(env
->ir
[i
], &sc
->sc_regs
[i
]);
5291 __put_user(0, &sc
->sc_regs
[31]);
5293 for (i
= 0; i
< 31; ++i
) {
5294 __put_user(env
->fir
[i
], &sc
->sc_fpregs
[i
]);
5296 __put_user(0, &sc
->sc_fpregs
[31]);
5297 __put_user(cpu_alpha_load_fpcr(env
), &sc
->sc_fpcr
);
5299 __put_user(0, &sc
->sc_traparg_a0
); /* FIXME */
5300 __put_user(0, &sc
->sc_traparg_a1
); /* FIXME */
5301 __put_user(0, &sc
->sc_traparg_a2
); /* FIXME */
5304 static void restore_sigcontext(CPUAlphaState
*env
,
5305 struct target_sigcontext
*sc
)
5310 __get_user(env
->pc
, &sc
->sc_pc
);
5312 for (i
= 0; i
< 31; ++i
) {
5313 __get_user(env
->ir
[i
], &sc
->sc_regs
[i
]);
5315 for (i
= 0; i
< 31; ++i
) {
5316 __get_user(env
->fir
[i
], &sc
->sc_fpregs
[i
]);
5319 __get_user(fpcr
, &sc
->sc_fpcr
);
5320 cpu_alpha_store_fpcr(env
, fpcr
);
5323 static inline abi_ulong
get_sigframe(struct target_sigaction
*sa
,
5325 unsigned long framesize
)
5327 abi_ulong sp
= env
->ir
[IR_SP
];
5329 /* This is the X/Open sanctioned signal stack switching. */
5330 if ((sa
->sa_flags
& TARGET_SA_ONSTACK
) != 0 && !sas_ss_flags(sp
)) {
5331 sp
= target_sigaltstack_used
.ss_sp
+ target_sigaltstack_used
.ss_size
;
5333 return (sp
- framesize
) & -32;
5336 static void setup_frame(int sig
, struct target_sigaction
*ka
,
5337 target_sigset_t
*set
, CPUAlphaState
*env
)
5339 abi_ulong frame_addr
, r26
;
5340 struct target_sigframe
*frame
;
5343 frame_addr
= get_sigframe(ka
, env
, sizeof(*frame
));
5344 if (!lock_user_struct(VERIFY_WRITE
, frame
, frame_addr
, 0)) {
5348 setup_sigcontext(&frame
->sc
, env
, frame_addr
, set
);
5350 if (ka
->sa_restorer
) {
5351 r26
= ka
->sa_restorer
;
5353 __put_user(INSN_MOV_R30_R16
, &frame
->retcode
[0]);
5354 __put_user(INSN_LDI_R0
+ TARGET_NR_sigreturn
,
5355 &frame
->retcode
[1]);
5356 __put_user(INSN_CALLSYS
, &frame
->retcode
[2]);
5361 unlock_user_struct(frame
, frame_addr
, 1);
5365 if (sig
== TARGET_SIGSEGV
) {
5366 ka
->_sa_handler
= TARGET_SIG_DFL
;
5368 force_sig(TARGET_SIGSEGV
);
5371 env
->ir
[IR_RA
] = r26
;
5372 env
->ir
[IR_PV
] = env
->pc
= ka
->_sa_handler
;
5373 env
->ir
[IR_A0
] = sig
;
5375 env
->ir
[IR_A2
] = frame_addr
+ offsetof(struct target_sigframe
, sc
);
5376 env
->ir
[IR_SP
] = frame_addr
;
5379 static void setup_rt_frame(int sig
, struct target_sigaction
*ka
,
5380 target_siginfo_t
*info
,
5381 target_sigset_t
*set
, CPUAlphaState
*env
)
5383 abi_ulong frame_addr
, r26
;
5384 struct target_rt_sigframe
*frame
;
5387 frame_addr
= get_sigframe(ka
, env
, sizeof(*frame
));
5388 if (!lock_user_struct(VERIFY_WRITE
, frame
, frame_addr
, 0)) {
5392 copy_siginfo_to_user(&frame
->info
, info
);
5394 __put_user(0, &frame
->uc
.tuc_flags
);
5395 __put_user(0, &frame
->uc
.tuc_link
);
5396 __put_user(set
->sig
[0], &frame
->uc
.tuc_osf_sigmask
);
5397 __put_user(target_sigaltstack_used
.ss_sp
,
5398 &frame
->uc
.tuc_stack
.ss_sp
);
5399 __put_user(sas_ss_flags(env
->ir
[IR_SP
]),
5400 &frame
->uc
.tuc_stack
.ss_flags
);
5401 __put_user(target_sigaltstack_used
.ss_size
,
5402 &frame
->uc
.tuc_stack
.ss_size
);
5403 setup_sigcontext(&frame
->uc
.tuc_mcontext
, env
, frame_addr
, set
);
5404 for (i
= 0; i
< TARGET_NSIG_WORDS
; ++i
) {
5405 __put_user(set
->sig
[i
], &frame
->uc
.tuc_sigmask
.sig
[i
]);
5408 if (ka
->sa_restorer
) {
5409 r26
= ka
->sa_restorer
;
5411 __put_user(INSN_MOV_R30_R16
, &frame
->retcode
[0]);
5412 __put_user(INSN_LDI_R0
+ TARGET_NR_rt_sigreturn
,
5413 &frame
->retcode
[1]);
5414 __put_user(INSN_CALLSYS
, &frame
->retcode
[2]);
5421 if (sig
== TARGET_SIGSEGV
) {
5422 ka
->_sa_handler
= TARGET_SIG_DFL
;
5424 force_sig(TARGET_SIGSEGV
);
5427 env
->ir
[IR_RA
] = r26
;
5428 env
->ir
[IR_PV
] = env
->pc
= ka
->_sa_handler
;
5429 env
->ir
[IR_A0
] = sig
;
5430 env
->ir
[IR_A1
] = frame_addr
+ offsetof(struct target_rt_sigframe
, info
);
5431 env
->ir
[IR_A2
] = frame_addr
+ offsetof(struct target_rt_sigframe
, uc
);
5432 env
->ir
[IR_SP
] = frame_addr
;
5435 long do_sigreturn(CPUAlphaState
*env
)
5437 struct target_sigcontext
*sc
;
5438 abi_ulong sc_addr
= env
->ir
[IR_A0
];
5439 target_sigset_t target_set
;
5442 if (!lock_user_struct(VERIFY_READ
, sc
, sc_addr
, 1)) {
5446 target_sigemptyset(&target_set
);
5447 __get_user(target_set
.sig
[0], &sc
->sc_mask
);
5449 target_to_host_sigset_internal(&set
, &target_set
);
5450 do_sigprocmask(SIG_SETMASK
, &set
, NULL
);
5452 restore_sigcontext(env
, sc
);
5453 unlock_user_struct(sc
, sc_addr
, 0);
5454 return env
->ir
[IR_V0
];
5457 force_sig(TARGET_SIGSEGV
);
5460 long do_rt_sigreturn(CPUAlphaState
*env
)
5462 abi_ulong frame_addr
= env
->ir
[IR_A0
];
5463 struct target_rt_sigframe
*frame
;
5466 if (!lock_user_struct(VERIFY_READ
, frame
, frame_addr
, 1)) {
5469 target_to_host_sigset(&set
, &frame
->uc
.tuc_sigmask
);
5470 do_sigprocmask(SIG_SETMASK
, &set
, NULL
);
5472 restore_sigcontext(env
, &frame
->uc
.tuc_mcontext
);
5473 if (do_sigaltstack(frame_addr
+ offsetof(struct target_rt_sigframe
,
5475 0, env
->ir
[IR_SP
]) == -EFAULT
) {
5479 unlock_user_struct(frame
, frame_addr
, 0);
5480 return env
->ir
[IR_V0
];
5484 unlock_user_struct(frame
, frame_addr
, 0);
5485 force_sig(TARGET_SIGSEGV
);
5490 static void setup_frame(int sig
, struct target_sigaction
*ka
,
5491 target_sigset_t
*set
, CPUArchState
*env
)
5493 fprintf(stderr
, "setup_frame: not implemented\n");
5496 static void setup_rt_frame(int sig
, struct target_sigaction
*ka
,
5497 target_siginfo_t
*info
,
5498 target_sigset_t
*set
, CPUArchState
*env
)
5500 fprintf(stderr
, "setup_rt_frame: not implemented\n");
5503 long do_sigreturn(CPUArchState
*env
)
5505 fprintf(stderr
, "do_sigreturn: not implemented\n");
5506 return -TARGET_ENOSYS
;
5509 long do_rt_sigreturn(CPUArchState
*env
)
5511 fprintf(stderr
, "do_rt_sigreturn: not implemented\n");
5512 return -TARGET_ENOSYS
;
5517 void process_pending_signals(CPUArchState
*cpu_env
)
5519 CPUState
*cpu
= ENV_GET_CPU(cpu_env
);
5522 sigset_t set
, old_set
;
5523 target_sigset_t target_old_set
;
5524 struct emulated_sigtable
*k
;
5525 struct target_sigaction
*sa
;
5527 TaskState
*ts
= cpu
->opaque
;
5529 if (!ts
->signal_pending
)
5532 /* FIXME: This is not threadsafe. */
5534 for(sig
= 1; sig
<= TARGET_NSIG
; sig
++) {
5539 /* if no signal is pending, just return */
5540 ts
->signal_pending
= 0;
5545 fprintf(stderr
, "qemu: process signal %d\n", sig
);
5547 /* dequeue signal */
5553 sig
= gdb_handlesig(cpu
, sig
);
5556 handler
= TARGET_SIG_IGN
;
5558 sa
= &sigact_table
[sig
- 1];
5559 handler
= sa
->_sa_handler
;
5562 if (ts
->sigsegv_blocked
&& sig
== TARGET_SIGSEGV
) {
5563 /* Guest has blocked SIGSEGV but we got one anyway. Assume this
5564 * is a forced SIGSEGV (ie one the kernel handles via force_sig_info
5565 * because it got a real MMU fault), and treat as if default handler.
5567 handler
= TARGET_SIG_DFL
;
5570 if (handler
== TARGET_SIG_DFL
) {
5571 /* default handler : ignore some signal. The other are job control or fatal */
5572 if (sig
== TARGET_SIGTSTP
|| sig
== TARGET_SIGTTIN
|| sig
== TARGET_SIGTTOU
) {
5573 kill(getpid(),SIGSTOP
);
5574 } else if (sig
!= TARGET_SIGCHLD
&&
5575 sig
!= TARGET_SIGURG
&&
5576 sig
!= TARGET_SIGWINCH
&&
5577 sig
!= TARGET_SIGCONT
) {
5580 } else if (handler
== TARGET_SIG_IGN
) {
5582 } else if (handler
== TARGET_SIG_ERR
) {
5585 /* compute the blocked signals during the handler execution */
5586 target_to_host_sigset(&set
, &sa
->sa_mask
);
5587 /* SA_NODEFER indicates that the current signal should not be
5588 blocked during the handler */
5589 if (!(sa
->sa_flags
& TARGET_SA_NODEFER
))
5590 sigaddset(&set
, target_to_host_signal(sig
));
5592 /* block signals in the handler using Linux */
5593 do_sigprocmask(SIG_BLOCK
, &set
, &old_set
);
5594 /* save the previous blocked signal state to restore it at the
5595 end of the signal execution (see do_sigreturn) */
5596 host_to_target_sigset_internal(&target_old_set
, &old_set
);
5598 /* if the CPU is in VM86 mode, we restore the 32 bit values */
5599 #if defined(TARGET_I386) && !defined(TARGET_X86_64)
5601 CPUX86State
*env
= cpu_env
;
5602 if (env
->eflags
& VM_MASK
)
5603 save_v86_state(env
);
5606 /* prepare the stack frame of the virtual CPU */
5607 #if defined(TARGET_ABI_MIPSN32) || defined(TARGET_ABI_MIPSN64)
5608 /* These targets do not have traditional signals. */
5609 setup_rt_frame(sig
, sa
, &q
->info
, &target_old_set
, cpu_env
);
5611 if (sa
->sa_flags
& TARGET_SA_SIGINFO
)
5612 setup_rt_frame(sig
, sa
, &q
->info
, &target_old_set
, cpu_env
);
5614 setup_frame(sig
, sa
, &target_old_set
, cpu_env
);
5616 if (sa
->sa_flags
& TARGET_SA_RESETHAND
)
5617 sa
->_sa_handler
= TARGET_SIG_DFL
;
5620 free_sigqueue(cpu_env
, q
);