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/>.
25 #include <sys/ucontext.h>
26 #include <sys/resource.h>
29 #include "qemu-common.h"
30 #include "target_signal.h"
32 //#define DEBUG_SIGNAL
34 static struct target_sigaltstack target_sigaltstack_used
= {
37 .ss_flags
= TARGET_SS_DISABLE
,
40 static struct target_sigaction sigact_table
[TARGET_NSIG
];
42 static void host_signal_handler(int host_signum
, siginfo_t
*info
,
45 static uint8_t host_to_target_signal_table
[_NSIG
] = {
46 [SIGHUP
] = TARGET_SIGHUP
,
47 [SIGINT
] = TARGET_SIGINT
,
48 [SIGQUIT
] = TARGET_SIGQUIT
,
49 [SIGILL
] = TARGET_SIGILL
,
50 [SIGTRAP
] = TARGET_SIGTRAP
,
51 [SIGABRT
] = TARGET_SIGABRT
,
52 /* [SIGIOT] = TARGET_SIGIOT,*/
53 [SIGBUS
] = TARGET_SIGBUS
,
54 [SIGFPE
] = TARGET_SIGFPE
,
55 [SIGKILL
] = TARGET_SIGKILL
,
56 [SIGUSR1
] = TARGET_SIGUSR1
,
57 [SIGSEGV
] = TARGET_SIGSEGV
,
58 [SIGUSR2
] = TARGET_SIGUSR2
,
59 [SIGPIPE
] = TARGET_SIGPIPE
,
60 [SIGALRM
] = TARGET_SIGALRM
,
61 [SIGTERM
] = TARGET_SIGTERM
,
63 [SIGSTKFLT
] = TARGET_SIGSTKFLT
,
65 [SIGCHLD
] = TARGET_SIGCHLD
,
66 [SIGCONT
] = TARGET_SIGCONT
,
67 [SIGSTOP
] = TARGET_SIGSTOP
,
68 [SIGTSTP
] = TARGET_SIGTSTP
,
69 [SIGTTIN
] = TARGET_SIGTTIN
,
70 [SIGTTOU
] = TARGET_SIGTTOU
,
71 [SIGURG
] = TARGET_SIGURG
,
72 [SIGXCPU
] = TARGET_SIGXCPU
,
73 [SIGXFSZ
] = TARGET_SIGXFSZ
,
74 [SIGVTALRM
] = TARGET_SIGVTALRM
,
75 [SIGPROF
] = TARGET_SIGPROF
,
76 [SIGWINCH
] = TARGET_SIGWINCH
,
77 [SIGIO
] = TARGET_SIGIO
,
78 [SIGPWR
] = TARGET_SIGPWR
,
79 [SIGSYS
] = TARGET_SIGSYS
,
80 /* next signals stay the same */
81 /* Nasty hack: Reverse SIGRTMIN and SIGRTMAX to avoid overlap with
82 host libpthread signals. This assumes no one actually uses SIGRTMAX :-/
83 To fix this properly we need to do manual signal delivery multiplexed
84 over a single host signal. */
85 [__SIGRTMIN
] = __SIGRTMAX
,
86 [__SIGRTMAX
] = __SIGRTMIN
,
88 static uint8_t target_to_host_signal_table
[_NSIG
];
90 static inline int on_sig_stack(unsigned long sp
)
92 return (sp
- target_sigaltstack_used
.ss_sp
93 < target_sigaltstack_used
.ss_size
);
96 static inline int sas_ss_flags(unsigned long sp
)
98 return (target_sigaltstack_used
.ss_size
== 0 ? SS_DISABLE
99 : on_sig_stack(sp
) ? SS_ONSTACK
: 0);
102 int host_to_target_signal(int sig
)
104 if (sig
< 0 || sig
>= _NSIG
)
106 return host_to_target_signal_table
[sig
];
109 int target_to_host_signal(int sig
)
111 if (sig
< 0 || sig
>= _NSIG
)
113 return target_to_host_signal_table
[sig
];
116 static inline void target_sigemptyset(target_sigset_t
*set
)
118 memset(set
, 0, sizeof(*set
));
121 static inline void target_sigaddset(target_sigset_t
*set
, int signum
)
124 abi_ulong mask
= (abi_ulong
)1 << (signum
% TARGET_NSIG_BPW
);
125 set
->sig
[signum
/ TARGET_NSIG_BPW
] |= mask
;
128 static inline int target_sigismember(const target_sigset_t
*set
, int signum
)
131 abi_ulong mask
= (abi_ulong
)1 << (signum
% TARGET_NSIG_BPW
);
132 return ((set
->sig
[signum
/ TARGET_NSIG_BPW
] & mask
) != 0);
135 static void host_to_target_sigset_internal(target_sigset_t
*d
,
139 target_sigemptyset(d
);
140 for (i
= 1; i
<= TARGET_NSIG
; i
++) {
141 if (sigismember(s
, i
)) {
142 target_sigaddset(d
, host_to_target_signal(i
));
147 void host_to_target_sigset(target_sigset_t
*d
, const sigset_t
*s
)
152 host_to_target_sigset_internal(&d1
, s
);
153 for(i
= 0;i
< TARGET_NSIG_WORDS
; i
++)
154 d
->sig
[i
] = tswapal(d1
.sig
[i
]);
157 static void target_to_host_sigset_internal(sigset_t
*d
,
158 const target_sigset_t
*s
)
162 for (i
= 1; i
<= TARGET_NSIG
; i
++) {
163 if (target_sigismember(s
, i
)) {
164 sigaddset(d
, target_to_host_signal(i
));
169 void target_to_host_sigset(sigset_t
*d
, const target_sigset_t
*s
)
174 for(i
= 0;i
< TARGET_NSIG_WORDS
; i
++)
175 s1
.sig
[i
] = tswapal(s
->sig
[i
]);
176 target_to_host_sigset_internal(d
, &s1
);
179 void host_to_target_old_sigset(abi_ulong
*old_sigset
,
180 const sigset_t
*sigset
)
183 host_to_target_sigset(&d
, sigset
);
184 *old_sigset
= d
.sig
[0];
187 void target_to_host_old_sigset(sigset_t
*sigset
,
188 const abi_ulong
*old_sigset
)
193 d
.sig
[0] = *old_sigset
;
194 for(i
= 1;i
< TARGET_NSIG_WORDS
; i
++)
196 target_to_host_sigset(sigset
, &d
);
199 /* Wrapper for sigprocmask function
200 * Emulates a sigprocmask in a safe way for the guest. Note that set and oldset
201 * are host signal set, not guest ones. This wraps the sigprocmask host calls
202 * that should be protected (calls originated from guest)
204 int do_sigprocmask(int how
, const sigset_t
*set
, sigset_t
*oldset
)
208 sigset_t
*temp
= NULL
;
209 CPUState
*cpu
= thread_cpu
;
210 TaskState
*ts
= (TaskState
*)cpu
->opaque
;
211 bool segv_was_blocked
= ts
->sigsegv_blocked
;
214 bool has_sigsegv
= sigismember(set
, SIGSEGV
);
218 sigdelset(temp
, SIGSEGV
);
223 ts
->sigsegv_blocked
= true;
228 ts
->sigsegv_blocked
= false;
232 ts
->sigsegv_blocked
= has_sigsegv
;
235 g_assert_not_reached();
239 ret
= sigprocmask(how
, temp
, oldset
);
241 if (oldset
&& segv_was_blocked
) {
242 sigaddset(oldset
, SIGSEGV
);
248 /* siginfo conversion */
250 static inline void host_to_target_siginfo_noswap(target_siginfo_t
*tinfo
,
251 const siginfo_t
*info
)
253 int sig
= host_to_target_signal(info
->si_signo
);
254 tinfo
->si_signo
= sig
;
256 tinfo
->si_code
= info
->si_code
;
258 if (sig
== TARGET_SIGILL
|| sig
== TARGET_SIGFPE
|| sig
== TARGET_SIGSEGV
259 || sig
== TARGET_SIGBUS
|| sig
== TARGET_SIGTRAP
) {
260 /* Should never come here, but who knows. The information for
261 the target is irrelevant. */
262 tinfo
->_sifields
._sigfault
._addr
= 0;
263 } else if (sig
== TARGET_SIGIO
) {
264 tinfo
->_sifields
._sigpoll
._band
= info
->si_band
;
265 tinfo
->_sifields
._sigpoll
._fd
= info
->si_fd
;
266 } else if (sig
== TARGET_SIGCHLD
) {
267 tinfo
->_sifields
._sigchld
._pid
= info
->si_pid
;
268 tinfo
->_sifields
._sigchld
._uid
= info
->si_uid
;
269 tinfo
->_sifields
._sigchld
._status
270 = host_to_target_waitstatus(info
->si_status
);
271 tinfo
->_sifields
._sigchld
._utime
= info
->si_utime
;
272 tinfo
->_sifields
._sigchld
._stime
= info
->si_stime
;
273 } else if (sig
>= TARGET_SIGRTMIN
) {
274 tinfo
->_sifields
._rt
._pid
= info
->si_pid
;
275 tinfo
->_sifields
._rt
._uid
= info
->si_uid
;
276 /* XXX: potential problem if 64 bit */
277 tinfo
->_sifields
._rt
._sigval
.sival_ptr
278 = (abi_ulong
)(unsigned long)info
->si_value
.sival_ptr
;
282 static void tswap_siginfo(target_siginfo_t
*tinfo
,
283 const target_siginfo_t
*info
)
285 int sig
= info
->si_signo
;
286 tinfo
->si_signo
= tswap32(sig
);
287 tinfo
->si_errno
= tswap32(info
->si_errno
);
288 tinfo
->si_code
= tswap32(info
->si_code
);
290 if (sig
== TARGET_SIGILL
|| sig
== TARGET_SIGFPE
|| sig
== TARGET_SIGSEGV
291 || sig
== TARGET_SIGBUS
|| sig
== TARGET_SIGTRAP
) {
292 tinfo
->_sifields
._sigfault
._addr
293 = tswapal(info
->_sifields
._sigfault
._addr
);
294 } else if (sig
== TARGET_SIGIO
) {
295 tinfo
->_sifields
._sigpoll
._band
296 = tswap32(info
->_sifields
._sigpoll
._band
);
297 tinfo
->_sifields
._sigpoll
._fd
= tswap32(info
->_sifields
._sigpoll
._fd
);
298 } else if (sig
== TARGET_SIGCHLD
) {
299 tinfo
->_sifields
._sigchld
._pid
300 = tswap32(info
->_sifields
._sigchld
._pid
);
301 tinfo
->_sifields
._sigchld
._uid
302 = tswap32(info
->_sifields
._sigchld
._uid
);
303 tinfo
->_sifields
._sigchld
._status
304 = tswap32(info
->_sifields
._sigchld
._status
);
305 tinfo
->_sifields
._sigchld
._utime
306 = tswapal(info
->_sifields
._sigchld
._utime
);
307 tinfo
->_sifields
._sigchld
._stime
308 = tswapal(info
->_sifields
._sigchld
._stime
);
309 } else if (sig
>= TARGET_SIGRTMIN
) {
310 tinfo
->_sifields
._rt
._pid
= tswap32(info
->_sifields
._rt
._pid
);
311 tinfo
->_sifields
._rt
._uid
= tswap32(info
->_sifields
._rt
._uid
);
312 tinfo
->_sifields
._rt
._sigval
.sival_ptr
313 = tswapal(info
->_sifields
._rt
._sigval
.sival_ptr
);
318 void host_to_target_siginfo(target_siginfo_t
*tinfo
, const siginfo_t
*info
)
320 host_to_target_siginfo_noswap(tinfo
, info
);
321 tswap_siginfo(tinfo
, tinfo
);
324 /* XXX: we support only POSIX RT signals are used. */
325 /* XXX: find a solution for 64 bit (additional malloced data is needed) */
326 void target_to_host_siginfo(siginfo_t
*info
, const target_siginfo_t
*tinfo
)
328 info
->si_signo
= tswap32(tinfo
->si_signo
);
329 info
->si_errno
= tswap32(tinfo
->si_errno
);
330 info
->si_code
= tswap32(tinfo
->si_code
);
331 info
->si_pid
= tswap32(tinfo
->_sifields
._rt
._pid
);
332 info
->si_uid
= tswap32(tinfo
->_sifields
._rt
._uid
);
333 info
->si_value
.sival_ptr
=
334 (void *)(long)tswapal(tinfo
->_sifields
._rt
._sigval
.sival_ptr
);
337 static int fatal_signal (int sig
)
342 case TARGET_SIGWINCH
:
343 /* Ignored by default. */
350 /* Job control signals. */
357 /* returns 1 if given signal should dump core if not handled */
358 static int core_dump_signal(int sig
)
374 void signal_init(void)
376 struct sigaction act
;
377 struct sigaction oact
;
381 /* generate signal conversion tables */
382 for(i
= 1; i
< _NSIG
; i
++) {
383 if (host_to_target_signal_table
[i
] == 0)
384 host_to_target_signal_table
[i
] = i
;
386 for(i
= 1; i
< _NSIG
; i
++) {
387 j
= host_to_target_signal_table
[i
];
388 target_to_host_signal_table
[j
] = i
;
391 /* set all host signal handlers. ALL signals are blocked during
392 the handlers to serialize them. */
393 memset(sigact_table
, 0, sizeof(sigact_table
));
395 sigfillset(&act
.sa_mask
);
396 act
.sa_flags
= SA_SIGINFO
;
397 act
.sa_sigaction
= host_signal_handler
;
398 for(i
= 1; i
<= TARGET_NSIG
; i
++) {
399 host_sig
= target_to_host_signal(i
);
400 sigaction(host_sig
, NULL
, &oact
);
401 if (oact
.sa_sigaction
== (void *)SIG_IGN
) {
402 sigact_table
[i
- 1]._sa_handler
= TARGET_SIG_IGN
;
403 } else if (oact
.sa_sigaction
== (void *)SIG_DFL
) {
404 sigact_table
[i
- 1]._sa_handler
= TARGET_SIG_DFL
;
406 /* If there's already a handler installed then something has
407 gone horribly wrong, so don't even try to handle that case. */
408 /* Install some handlers for our own use. We need at least
409 SIGSEGV and SIGBUS, to detect exceptions. We can not just
410 trap all signals because it affects syscall interrupt
411 behavior. But do trap all default-fatal signals. */
412 if (fatal_signal (i
))
413 sigaction(host_sig
, &act
, NULL
);
417 /* signal queue handling */
419 static inline struct sigqueue
*alloc_sigqueue(CPUArchState
*env
)
421 CPUState
*cpu
= ENV_GET_CPU(env
);
422 TaskState
*ts
= cpu
->opaque
;
423 struct sigqueue
*q
= ts
->first_free
;
426 ts
->first_free
= q
->next
;
430 static inline void free_sigqueue(CPUArchState
*env
, struct sigqueue
*q
)
432 CPUState
*cpu
= ENV_GET_CPU(env
);
433 TaskState
*ts
= cpu
->opaque
;
435 q
->next
= ts
->first_free
;
439 /* abort execution with signal */
440 static void QEMU_NORETURN
force_sig(int target_sig
)
442 CPUState
*cpu
= thread_cpu
;
443 CPUArchState
*env
= cpu
->env_ptr
;
444 TaskState
*ts
= (TaskState
*)cpu
->opaque
;
445 int host_sig
, core_dumped
= 0;
446 struct sigaction act
;
447 host_sig
= target_to_host_signal(target_sig
);
448 gdb_signalled(env
, target_sig
);
450 /* dump core if supported by target binary format */
451 if (core_dump_signal(target_sig
) && (ts
->bprm
->core_dump
!= NULL
)) {
454 ((*ts
->bprm
->core_dump
)(target_sig
, env
) == 0);
457 /* we already dumped the core of target process, we don't want
458 * a coredump of qemu itself */
459 struct rlimit nodump
;
460 getrlimit(RLIMIT_CORE
, &nodump
);
462 setrlimit(RLIMIT_CORE
, &nodump
);
463 (void) fprintf(stderr
, "qemu: uncaught target signal %d (%s) - %s\n",
464 target_sig
, strsignal(host_sig
), "core dumped" );
467 /* The proper exit code for dying from an uncaught signal is
468 * -<signal>. The kernel doesn't allow exit() or _exit() to pass
469 * a negative value. To get the proper exit code we need to
470 * actually die from an uncaught signal. Here the default signal
471 * handler is installed, we send ourself a signal and we wait for
473 sigfillset(&act
.sa_mask
);
474 act
.sa_handler
= SIG_DFL
;
476 sigaction(host_sig
, &act
, NULL
);
478 /* For some reason raise(host_sig) doesn't send the signal when
479 * statically linked on x86-64. */
480 kill(getpid(), host_sig
);
482 /* Make sure the signal isn't masked (just reuse the mask inside
484 sigdelset(&act
.sa_mask
, host_sig
);
485 sigsuspend(&act
.sa_mask
);
491 /* queue a signal so that it will be send to the virtual CPU as soon
493 int queue_signal(CPUArchState
*env
, int sig
, target_siginfo_t
*info
)
495 CPUState
*cpu
= ENV_GET_CPU(env
);
496 TaskState
*ts
= cpu
->opaque
;
497 struct emulated_sigtable
*k
;
498 struct sigqueue
*q
, **pq
;
502 #if defined(DEBUG_SIGNAL)
503 fprintf(stderr
, "queue_signal: sig=%d\n",
506 k
= &ts
->sigtab
[sig
- 1];
507 queue
= gdb_queuesig ();
508 handler
= sigact_table
[sig
- 1]._sa_handler
;
510 if (ts
->sigsegv_blocked
&& sig
== TARGET_SIGSEGV
) {
511 /* Guest has blocked SIGSEGV but we got one anyway. Assume this
512 * is a forced SIGSEGV (ie one the kernel handles via force_sig_info
513 * because it got a real MMU fault). A blocked SIGSEGV in that
514 * situation is treated as if using the default handler. This is
515 * not correct if some other process has randomly sent us a SIGSEGV
516 * via kill(), but that is not easy to distinguish at this point,
517 * so we assume it doesn't happen.
519 handler
= TARGET_SIG_DFL
;
522 if (!queue
&& handler
== TARGET_SIG_DFL
) {
523 if (sig
== TARGET_SIGTSTP
|| sig
== TARGET_SIGTTIN
|| sig
== TARGET_SIGTTOU
) {
524 kill(getpid(),SIGSTOP
);
527 /* default handler : ignore some signal. The other are fatal */
528 if (sig
!= TARGET_SIGCHLD
&&
529 sig
!= TARGET_SIGURG
&&
530 sig
!= TARGET_SIGWINCH
&&
531 sig
!= TARGET_SIGCONT
) {
534 return 0; /* indicate ignored */
536 } else if (!queue
&& handler
== TARGET_SIG_IGN
) {
539 } else if (!queue
&& handler
== TARGET_SIG_ERR
) {
543 if (sig
< TARGET_SIGRTMIN
) {
544 /* if non real time signal, we queue exactly one signal */
554 q
= alloc_sigqueue(env
);
565 /* signal that a new signal is pending */
566 ts
->signal_pending
= 1;
567 return 1; /* indicates that the signal was queued */
571 static void host_signal_handler(int host_signum
, siginfo_t
*info
,
574 CPUArchState
*env
= thread_cpu
->env_ptr
;
576 target_siginfo_t tinfo
;
578 /* the CPU emulator uses some host signals to detect exceptions,
579 we forward to it some signals */
580 if ((host_signum
== SIGSEGV
|| host_signum
== SIGBUS
)
581 && info
->si_code
> 0) {
582 if (cpu_signal_handler(host_signum
, info
, puc
))
586 /* get target signal number */
587 sig
= host_to_target_signal(host_signum
);
588 if (sig
< 1 || sig
> TARGET_NSIG
)
590 #if defined(DEBUG_SIGNAL)
591 fprintf(stderr
, "qemu: got signal %d\n", sig
);
593 host_to_target_siginfo_noswap(&tinfo
, info
);
594 if (queue_signal(env
, sig
, &tinfo
) == 1) {
595 /* interrupt the virtual CPU as soon as possible */
596 cpu_exit(thread_cpu
);
600 /* do_sigaltstack() returns target values and errnos. */
601 /* compare linux/kernel/signal.c:do_sigaltstack() */
602 abi_long
do_sigaltstack(abi_ulong uss_addr
, abi_ulong uoss_addr
, abi_ulong sp
)
605 struct target_sigaltstack oss
;
607 /* XXX: test errors */
610 __put_user(target_sigaltstack_used
.ss_sp
, &oss
.ss_sp
);
611 __put_user(target_sigaltstack_used
.ss_size
, &oss
.ss_size
);
612 __put_user(sas_ss_flags(sp
), &oss
.ss_flags
);
617 struct target_sigaltstack
*uss
;
618 struct target_sigaltstack ss
;
619 size_t minstacksize
= TARGET_MINSIGSTKSZ
;
621 #if defined(TARGET_PPC64)
622 /* ELF V2 for PPC64 has a 4K minimum stack size for signal handlers */
623 struct image_info
*image
= ((TaskState
*)thread_cpu
->opaque
)->info
;
624 if (get_ppc64_abi(image
) > 1) {
629 ret
= -TARGET_EFAULT
;
630 if (!lock_user_struct(VERIFY_READ
, uss
, uss_addr
, 1)) {
633 __get_user(ss
.ss_sp
, &uss
->ss_sp
);
634 __get_user(ss
.ss_size
, &uss
->ss_size
);
635 __get_user(ss
.ss_flags
, &uss
->ss_flags
);
636 unlock_user_struct(uss
, uss_addr
, 0);
639 if (on_sig_stack(sp
))
642 ret
= -TARGET_EINVAL
;
643 if (ss
.ss_flags
!= TARGET_SS_DISABLE
644 && ss
.ss_flags
!= TARGET_SS_ONSTACK
648 if (ss
.ss_flags
== TARGET_SS_DISABLE
) {
652 ret
= -TARGET_ENOMEM
;
653 if (ss
.ss_size
< minstacksize
) {
658 target_sigaltstack_used
.ss_sp
= ss
.ss_sp
;
659 target_sigaltstack_used
.ss_size
= ss
.ss_size
;
663 ret
= -TARGET_EFAULT
;
664 if (copy_to_user(uoss_addr
, &oss
, sizeof(oss
)))
673 /* do_sigaction() return host values and errnos */
674 int do_sigaction(int sig
, const struct target_sigaction
*act
,
675 struct target_sigaction
*oact
)
677 struct target_sigaction
*k
;
678 struct sigaction act1
;
682 if (sig
< 1 || sig
> TARGET_NSIG
|| sig
== TARGET_SIGKILL
|| sig
== TARGET_SIGSTOP
)
684 k
= &sigact_table
[sig
- 1];
685 #if defined(DEBUG_SIGNAL)
686 fprintf(stderr
, "sigaction sig=%d act=0x%p, oact=0x%p\n",
690 __put_user(k
->_sa_handler
, &oact
->_sa_handler
);
691 __put_user(k
->sa_flags
, &oact
->sa_flags
);
692 #if !defined(TARGET_MIPS)
693 __put_user(k
->sa_restorer
, &oact
->sa_restorer
);
696 oact
->sa_mask
= k
->sa_mask
;
699 /* FIXME: This is not threadsafe. */
700 __get_user(k
->_sa_handler
, &act
->_sa_handler
);
701 __get_user(k
->sa_flags
, &act
->sa_flags
);
702 #if !defined(TARGET_MIPS)
703 __get_user(k
->sa_restorer
, &act
->sa_restorer
);
705 /* To be swapped in target_to_host_sigset. */
706 k
->sa_mask
= act
->sa_mask
;
708 /* we update the host linux signal state */
709 host_sig
= target_to_host_signal(sig
);
710 if (host_sig
!= SIGSEGV
&& host_sig
!= SIGBUS
) {
711 sigfillset(&act1
.sa_mask
);
712 act1
.sa_flags
= SA_SIGINFO
;
713 if (k
->sa_flags
& TARGET_SA_RESTART
)
714 act1
.sa_flags
|= SA_RESTART
;
715 /* NOTE: it is important to update the host kernel signal
716 ignore state to avoid getting unexpected interrupted
718 if (k
->_sa_handler
== TARGET_SIG_IGN
) {
719 act1
.sa_sigaction
= (void *)SIG_IGN
;
720 } else if (k
->_sa_handler
== TARGET_SIG_DFL
) {
721 if (fatal_signal (sig
))
722 act1
.sa_sigaction
= host_signal_handler
;
724 act1
.sa_sigaction
= (void *)SIG_DFL
;
726 act1
.sa_sigaction
= host_signal_handler
;
728 ret
= sigaction(host_sig
, &act1
, NULL
);
734 #if defined(TARGET_I386) && TARGET_ABI_BITS == 32
736 /* from the Linux kernel */
738 struct target_fpreg
{
739 uint16_t significand
[4];
743 struct target_fpxreg
{
744 uint16_t significand
[4];
749 struct target_xmmreg
{
750 abi_ulong element
[4];
753 struct target_fpstate
{
754 /* Regular FPU environment */
762 struct target_fpreg _st
[8];
764 uint16_t magic
; /* 0xffff = regular FPU data only */
766 /* FXSR FPU environment */
767 abi_ulong _fxsr_env
[6]; /* FXSR FPU env is ignored */
770 struct target_fpxreg _fxsr_st
[8]; /* FXSR FPU reg data is ignored */
771 struct target_xmmreg _xmm
[8];
772 abi_ulong padding
[56];
775 #define X86_FXSR_MAGIC 0x0000
777 struct target_sigcontext
{
795 abi_ulong esp_at_signal
;
797 abi_ulong fpstate
; /* pointer */
802 struct target_ucontext
{
805 target_stack_t tuc_stack
;
806 struct target_sigcontext tuc_mcontext
;
807 target_sigset_t tuc_sigmask
; /* mask last for extensibility */
814 struct target_sigcontext sc
;
815 struct target_fpstate fpstate
;
816 abi_ulong extramask
[TARGET_NSIG_WORDS
-1];
826 struct target_siginfo info
;
827 struct target_ucontext uc
;
828 struct target_fpstate fpstate
;
833 * Set up a signal frame.
836 /* XXX: save x87 state */
837 static void setup_sigcontext(struct target_sigcontext
*sc
,
838 struct target_fpstate
*fpstate
, CPUX86State
*env
, abi_ulong mask
,
839 abi_ulong fpstate_addr
)
841 CPUState
*cs
= CPU(x86_env_get_cpu(env
));
844 /* already locked in setup_frame() */
845 __put_user(env
->segs
[R_GS
].selector
, (unsigned int *)&sc
->gs
);
846 __put_user(env
->segs
[R_FS
].selector
, (unsigned int *)&sc
->fs
);
847 __put_user(env
->segs
[R_ES
].selector
, (unsigned int *)&sc
->es
);
848 __put_user(env
->segs
[R_DS
].selector
, (unsigned int *)&sc
->ds
);
849 __put_user(env
->regs
[R_EDI
], &sc
->edi
);
850 __put_user(env
->regs
[R_ESI
], &sc
->esi
);
851 __put_user(env
->regs
[R_EBP
], &sc
->ebp
);
852 __put_user(env
->regs
[R_ESP
], &sc
->esp
);
853 __put_user(env
->regs
[R_EBX
], &sc
->ebx
);
854 __put_user(env
->regs
[R_EDX
], &sc
->edx
);
855 __put_user(env
->regs
[R_ECX
], &sc
->ecx
);
856 __put_user(env
->regs
[R_EAX
], &sc
->eax
);
857 __put_user(cs
->exception_index
, &sc
->trapno
);
858 __put_user(env
->error_code
, &sc
->err
);
859 __put_user(env
->eip
, &sc
->eip
);
860 __put_user(env
->segs
[R_CS
].selector
, (unsigned int *)&sc
->cs
);
861 __put_user(env
->eflags
, &sc
->eflags
);
862 __put_user(env
->regs
[R_ESP
], &sc
->esp_at_signal
);
863 __put_user(env
->segs
[R_SS
].selector
, (unsigned int *)&sc
->ss
);
865 cpu_x86_fsave(env
, fpstate_addr
, 1);
866 fpstate
->status
= fpstate
->sw
;
868 __put_user(magic
, &fpstate
->magic
);
869 __put_user(fpstate_addr
, &sc
->fpstate
);
871 /* non-iBCS2 extensions.. */
872 __put_user(mask
, &sc
->oldmask
);
873 __put_user(env
->cr
[2], &sc
->cr2
);
877 * Determine which stack to use..
880 static inline abi_ulong
881 get_sigframe(struct target_sigaction
*ka
, CPUX86State
*env
, size_t frame_size
)
885 /* Default to using normal stack */
886 esp
= env
->regs
[R_ESP
];
887 /* This is the X/Open sanctioned signal stack switching. */
888 if (ka
->sa_flags
& TARGET_SA_ONSTACK
) {
889 if (sas_ss_flags(esp
) == 0)
890 esp
= target_sigaltstack_used
.ss_sp
+ target_sigaltstack_used
.ss_size
;
893 /* This is the legacy signal stack switching. */
895 if ((env
->segs
[R_SS
].selector
& 0xffff) != __USER_DS
&&
896 !(ka
->sa_flags
& TARGET_SA_RESTORER
) &&
898 esp
= (unsigned long) ka
->sa_restorer
;
900 return (esp
- frame_size
) & -8ul;
903 /* compare linux/arch/i386/kernel/signal.c:setup_frame() */
904 static void setup_frame(int sig
, struct target_sigaction
*ka
,
905 target_sigset_t
*set
, CPUX86State
*env
)
907 abi_ulong frame_addr
;
908 struct sigframe
*frame
;
911 frame_addr
= get_sigframe(ka
, env
, sizeof(*frame
));
913 if (!lock_user_struct(VERIFY_WRITE
, frame
, frame_addr
, 0))
916 __put_user(sig
, &frame
->sig
);
918 setup_sigcontext(&frame
->sc
, &frame
->fpstate
, env
, set
->sig
[0],
919 frame_addr
+ offsetof(struct sigframe
, fpstate
));
921 for(i
= 1; i
< TARGET_NSIG_WORDS
; i
++) {
922 __put_user(set
->sig
[i
], &frame
->extramask
[i
- 1]);
925 /* Set up to return from userspace. If provided, use a stub
926 already in userspace. */
927 if (ka
->sa_flags
& TARGET_SA_RESTORER
) {
928 __put_user(ka
->sa_restorer
, &frame
->pretcode
);
931 abi_ulong retcode_addr
;
932 retcode_addr
= frame_addr
+ offsetof(struct sigframe
, retcode
);
933 __put_user(retcode_addr
, &frame
->pretcode
);
934 /* This is popl %eax ; movl $,%eax ; int $0x80 */
936 __put_user(val16
, (uint16_t *)(frame
->retcode
+0));
937 __put_user(TARGET_NR_sigreturn
, (int *)(frame
->retcode
+2));
939 __put_user(val16
, (uint16_t *)(frame
->retcode
+6));
943 /* Set up registers for signal handler */
944 env
->regs
[R_ESP
] = frame_addr
;
945 env
->eip
= ka
->_sa_handler
;
947 cpu_x86_load_seg(env
, R_DS
, __USER_DS
);
948 cpu_x86_load_seg(env
, R_ES
, __USER_DS
);
949 cpu_x86_load_seg(env
, R_SS
, __USER_DS
);
950 cpu_x86_load_seg(env
, R_CS
, __USER_CS
);
951 env
->eflags
&= ~TF_MASK
;
953 unlock_user_struct(frame
, frame_addr
, 1);
958 if (sig
== TARGET_SIGSEGV
)
959 ka
->_sa_handler
= TARGET_SIG_DFL
;
960 force_sig(TARGET_SIGSEGV
/* , current */);
963 /* compare linux/arch/i386/kernel/signal.c:setup_rt_frame() */
964 static void setup_rt_frame(int sig
, struct target_sigaction
*ka
,
965 target_siginfo_t
*info
,
966 target_sigset_t
*set
, CPUX86State
*env
)
968 abi_ulong frame_addr
, addr
;
969 struct rt_sigframe
*frame
;
972 frame_addr
= get_sigframe(ka
, env
, sizeof(*frame
));
974 if (!lock_user_struct(VERIFY_WRITE
, frame
, frame_addr
, 0))
977 __put_user(sig
, &frame
->sig
);
978 addr
= frame_addr
+ offsetof(struct rt_sigframe
, info
);
979 __put_user(addr
, &frame
->pinfo
);
980 addr
= frame_addr
+ offsetof(struct rt_sigframe
, uc
);
981 __put_user(addr
, &frame
->puc
);
982 tswap_siginfo(&frame
->info
, info
);
984 /* Create the ucontext. */
985 __put_user(0, &frame
->uc
.tuc_flags
);
986 __put_user(0, &frame
->uc
.tuc_link
);
987 __put_user(target_sigaltstack_used
.ss_sp
, &frame
->uc
.tuc_stack
.ss_sp
);
988 __put_user(sas_ss_flags(get_sp_from_cpustate(env
)),
989 &frame
->uc
.tuc_stack
.ss_flags
);
990 __put_user(target_sigaltstack_used
.ss_size
,
991 &frame
->uc
.tuc_stack
.ss_size
);
992 setup_sigcontext(&frame
->uc
.tuc_mcontext
, &frame
->fpstate
, env
,
993 set
->sig
[0], frame_addr
+ offsetof(struct rt_sigframe
, fpstate
));
995 for(i
= 0; i
< TARGET_NSIG_WORDS
; i
++) {
996 __put_user(set
->sig
[i
], &frame
->uc
.tuc_sigmask
.sig
[i
]);
999 /* Set up to return from userspace. If provided, use a stub
1000 already in userspace. */
1001 if (ka
->sa_flags
& TARGET_SA_RESTORER
) {
1002 __put_user(ka
->sa_restorer
, &frame
->pretcode
);
1005 addr
= frame_addr
+ offsetof(struct rt_sigframe
, retcode
);
1006 __put_user(addr
, &frame
->pretcode
);
1007 /* This is movl $,%eax ; int $0x80 */
1008 __put_user(0xb8, (char *)(frame
->retcode
+0));
1009 __put_user(TARGET_NR_rt_sigreturn
, (int *)(frame
->retcode
+1));
1011 __put_user(val16
, (uint16_t *)(frame
->retcode
+5));
1014 /* Set up registers for signal handler */
1015 env
->regs
[R_ESP
] = frame_addr
;
1016 env
->eip
= ka
->_sa_handler
;
1018 cpu_x86_load_seg(env
, R_DS
, __USER_DS
);
1019 cpu_x86_load_seg(env
, R_ES
, __USER_DS
);
1020 cpu_x86_load_seg(env
, R_SS
, __USER_DS
);
1021 cpu_x86_load_seg(env
, R_CS
, __USER_CS
);
1022 env
->eflags
&= ~TF_MASK
;
1024 unlock_user_struct(frame
, frame_addr
, 1);
1029 if (sig
== TARGET_SIGSEGV
)
1030 ka
->_sa_handler
= TARGET_SIG_DFL
;
1031 force_sig(TARGET_SIGSEGV
/* , current */);
1035 restore_sigcontext(CPUX86State
*env
, struct target_sigcontext
*sc
, int *peax
)
1037 unsigned int err
= 0;
1038 abi_ulong fpstate_addr
;
1039 unsigned int tmpflags
;
1041 cpu_x86_load_seg(env
, R_GS
, tswap16(sc
->gs
));
1042 cpu_x86_load_seg(env
, R_FS
, tswap16(sc
->fs
));
1043 cpu_x86_load_seg(env
, R_ES
, tswap16(sc
->es
));
1044 cpu_x86_load_seg(env
, R_DS
, tswap16(sc
->ds
));
1046 env
->regs
[R_EDI
] = tswapl(sc
->edi
);
1047 env
->regs
[R_ESI
] = tswapl(sc
->esi
);
1048 env
->regs
[R_EBP
] = tswapl(sc
->ebp
);
1049 env
->regs
[R_ESP
] = tswapl(sc
->esp
);
1050 env
->regs
[R_EBX
] = tswapl(sc
->ebx
);
1051 env
->regs
[R_EDX
] = tswapl(sc
->edx
);
1052 env
->regs
[R_ECX
] = tswapl(sc
->ecx
);
1053 env
->eip
= tswapl(sc
->eip
);
1055 cpu_x86_load_seg(env
, R_CS
, lduw_p(&sc
->cs
) | 3);
1056 cpu_x86_load_seg(env
, R_SS
, lduw_p(&sc
->ss
) | 3);
1058 tmpflags
= tswapl(sc
->eflags
);
1059 env
->eflags
= (env
->eflags
& ~0x40DD5) | (tmpflags
& 0x40DD5);
1060 // regs->orig_eax = -1; /* disable syscall checks */
1062 fpstate_addr
= tswapl(sc
->fpstate
);
1063 if (fpstate_addr
!= 0) {
1064 if (!access_ok(VERIFY_READ
, fpstate_addr
,
1065 sizeof(struct target_fpstate
)))
1067 cpu_x86_frstor(env
, fpstate_addr
, 1);
1070 *peax
= tswapl(sc
->eax
);
1076 long do_sigreturn(CPUX86State
*env
)
1078 struct sigframe
*frame
;
1079 abi_ulong frame_addr
= env
->regs
[R_ESP
] - 8;
1080 target_sigset_t target_set
;
1084 #if defined(DEBUG_SIGNAL)
1085 fprintf(stderr
, "do_sigreturn\n");
1087 if (!lock_user_struct(VERIFY_READ
, frame
, frame_addr
, 1))
1089 /* set blocked signals */
1090 __get_user(target_set
.sig
[0], &frame
->sc
.oldmask
);
1091 for(i
= 1; i
< TARGET_NSIG_WORDS
; i
++) {
1092 __get_user(target_set
.sig
[i
], &frame
->extramask
[i
- 1]);
1095 target_to_host_sigset_internal(&set
, &target_set
);
1096 do_sigprocmask(SIG_SETMASK
, &set
, NULL
);
1098 /* restore registers */
1099 if (restore_sigcontext(env
, &frame
->sc
, &eax
))
1101 unlock_user_struct(frame
, frame_addr
, 0);
1105 unlock_user_struct(frame
, frame_addr
, 0);
1106 force_sig(TARGET_SIGSEGV
);
1110 long do_rt_sigreturn(CPUX86State
*env
)
1112 abi_ulong frame_addr
;
1113 struct rt_sigframe
*frame
;
1117 frame_addr
= env
->regs
[R_ESP
] - 4;
1118 if (!lock_user_struct(VERIFY_READ
, frame
, frame_addr
, 1))
1120 target_to_host_sigset(&set
, &frame
->uc
.tuc_sigmask
);
1121 do_sigprocmask(SIG_SETMASK
, &set
, NULL
);
1123 if (restore_sigcontext(env
, &frame
->uc
.tuc_mcontext
, &eax
))
1126 if (do_sigaltstack(frame_addr
+ offsetof(struct rt_sigframe
, uc
.tuc_stack
), 0,
1127 get_sp_from_cpustate(env
)) == -EFAULT
)
1130 unlock_user_struct(frame
, frame_addr
, 0);
1134 unlock_user_struct(frame
, frame_addr
, 0);
1135 force_sig(TARGET_SIGSEGV
);
1139 #elif defined(TARGET_AARCH64)
1141 struct target_sigcontext
{
1142 uint64_t fault_address
;
1143 /* AArch64 registers */
1148 /* 4K reserved for FP/SIMD state and future expansion */
1149 char __reserved
[4096] __attribute__((__aligned__(16)));
1152 struct target_ucontext
{
1153 abi_ulong tuc_flags
;
1155 target_stack_t tuc_stack
;
1156 target_sigset_t tuc_sigmask
;
1157 /* glibc uses a 1024-bit sigset_t */
1158 char __unused
[1024 / 8 - sizeof(target_sigset_t
)];
1159 /* last for future expansion */
1160 struct target_sigcontext tuc_mcontext
;
1164 * Header to be used at the beginning of structures extending the user
1165 * context. Such structures must be placed after the rt_sigframe on the stack
1166 * and be 16-byte aligned. The last structure must be a dummy one with the
1167 * magic and size set to 0.
1169 struct target_aarch64_ctx
{
1174 #define TARGET_FPSIMD_MAGIC 0x46508001
1176 struct target_fpsimd_context
{
1177 struct target_aarch64_ctx head
;
1180 uint64_t vregs
[32 * 2]; /* really uint128_t vregs[32] */
1184 * Auxiliary context saved in the sigcontext.__reserved array. Not exported to
1185 * user space as it will change with the addition of new context. User space
1186 * should check the magic/size information.
1188 struct target_aux_context
{
1189 struct target_fpsimd_context fpsimd
;
1190 /* additional context to be added before "end" */
1191 struct target_aarch64_ctx end
;
1194 struct target_rt_sigframe
{
1195 struct target_siginfo info
;
1196 struct target_ucontext uc
;
1202 static int target_setup_sigframe(struct target_rt_sigframe
*sf
,
1203 CPUARMState
*env
, target_sigset_t
*set
)
1206 struct target_aux_context
*aux
=
1207 (struct target_aux_context
*)sf
->uc
.tuc_mcontext
.__reserved
;
1209 /* set up the stack frame for unwinding */
1210 __put_user(env
->xregs
[29], &sf
->fp
);
1211 __put_user(env
->xregs
[30], &sf
->lr
);
1213 for (i
= 0; i
< 31; i
++) {
1214 __put_user(env
->xregs
[i
], &sf
->uc
.tuc_mcontext
.regs
[i
]);
1216 __put_user(env
->xregs
[31], &sf
->uc
.tuc_mcontext
.sp
);
1217 __put_user(env
->pc
, &sf
->uc
.tuc_mcontext
.pc
);
1218 __put_user(pstate_read(env
), &sf
->uc
.tuc_mcontext
.pstate
);
1220 __put_user(env
->exception
.vaddress
, &sf
->uc
.tuc_mcontext
.fault_address
);
1222 for (i
= 0; i
< TARGET_NSIG_WORDS
; i
++) {
1223 __put_user(set
->sig
[i
], &sf
->uc
.tuc_sigmask
.sig
[i
]);
1226 for (i
= 0; i
< 32; i
++) {
1227 #ifdef TARGET_WORDS_BIGENDIAN
1228 __put_user(env
->vfp
.regs
[i
* 2], &aux
->fpsimd
.vregs
[i
* 2 + 1]);
1229 __put_user(env
->vfp
.regs
[i
* 2 + 1], &aux
->fpsimd
.vregs
[i
* 2]);
1231 __put_user(env
->vfp
.regs
[i
* 2], &aux
->fpsimd
.vregs
[i
* 2]);
1232 __put_user(env
->vfp
.regs
[i
* 2 + 1], &aux
->fpsimd
.vregs
[i
* 2 + 1]);
1235 __put_user(vfp_get_fpsr(env
), &aux
->fpsimd
.fpsr
);
1236 __put_user(vfp_get_fpcr(env
), &aux
->fpsimd
.fpcr
);
1237 __put_user(TARGET_FPSIMD_MAGIC
, &aux
->fpsimd
.head
.magic
);
1238 __put_user(sizeof(struct target_fpsimd_context
),
1239 &aux
->fpsimd
.head
.size
);
1241 /* set the "end" magic */
1242 __put_user(0, &aux
->end
.magic
);
1243 __put_user(0, &aux
->end
.size
);
1248 static int target_restore_sigframe(CPUARMState
*env
,
1249 struct target_rt_sigframe
*sf
)
1253 struct target_aux_context
*aux
=
1254 (struct target_aux_context
*)sf
->uc
.tuc_mcontext
.__reserved
;
1255 uint32_t magic
, size
, fpsr
, fpcr
;
1258 target_to_host_sigset(&set
, &sf
->uc
.tuc_sigmask
);
1259 do_sigprocmask(SIG_SETMASK
, &set
, NULL
);
1261 for (i
= 0; i
< 31; i
++) {
1262 __get_user(env
->xregs
[i
], &sf
->uc
.tuc_mcontext
.regs
[i
]);
1265 __get_user(env
->xregs
[31], &sf
->uc
.tuc_mcontext
.sp
);
1266 __get_user(env
->pc
, &sf
->uc
.tuc_mcontext
.pc
);
1267 __get_user(pstate
, &sf
->uc
.tuc_mcontext
.pstate
);
1268 pstate_write(env
, pstate
);
1270 __get_user(magic
, &aux
->fpsimd
.head
.magic
);
1271 __get_user(size
, &aux
->fpsimd
.head
.size
);
1273 if (magic
!= TARGET_FPSIMD_MAGIC
1274 || size
!= sizeof(struct target_fpsimd_context
)) {
1278 for (i
= 0; i
< 32; i
++) {
1279 #ifdef TARGET_WORDS_BIGENDIAN
1280 __get_user(env
->vfp
.regs
[i
* 2], &aux
->fpsimd
.vregs
[i
* 2 + 1]);
1281 __get_user(env
->vfp
.regs
[i
* 2 + 1], &aux
->fpsimd
.vregs
[i
* 2]);
1283 __get_user(env
->vfp
.regs
[i
* 2], &aux
->fpsimd
.vregs
[i
* 2]);
1284 __get_user(env
->vfp
.regs
[i
* 2 + 1], &aux
->fpsimd
.vregs
[i
* 2 + 1]);
1287 __get_user(fpsr
, &aux
->fpsimd
.fpsr
);
1288 vfp_set_fpsr(env
, fpsr
);
1289 __get_user(fpcr
, &aux
->fpsimd
.fpcr
);
1290 vfp_set_fpcr(env
, fpcr
);
1295 static abi_ulong
get_sigframe(struct target_sigaction
*ka
, CPUARMState
*env
)
1299 sp
= env
->xregs
[31];
1302 * This is the X/Open sanctioned signal stack switching.
1304 if ((ka
->sa_flags
& TARGET_SA_ONSTACK
) && !sas_ss_flags(sp
)) {
1305 sp
= target_sigaltstack_used
.ss_sp
+ target_sigaltstack_used
.ss_size
;
1308 sp
= (sp
- sizeof(struct target_rt_sigframe
)) & ~15;
1313 static void target_setup_frame(int usig
, struct target_sigaction
*ka
,
1314 target_siginfo_t
*info
, target_sigset_t
*set
,
1317 struct target_rt_sigframe
*frame
;
1318 abi_ulong frame_addr
, return_addr
;
1320 frame_addr
= get_sigframe(ka
, env
);
1321 if (!lock_user_struct(VERIFY_WRITE
, frame
, frame_addr
, 0)) {
1325 __put_user(0, &frame
->uc
.tuc_flags
);
1326 __put_user(0, &frame
->uc
.tuc_link
);
1328 __put_user(target_sigaltstack_used
.ss_sp
,
1329 &frame
->uc
.tuc_stack
.ss_sp
);
1330 __put_user(sas_ss_flags(env
->xregs
[31]),
1331 &frame
->uc
.tuc_stack
.ss_flags
);
1332 __put_user(target_sigaltstack_used
.ss_size
,
1333 &frame
->uc
.tuc_stack
.ss_size
);
1334 target_setup_sigframe(frame
, env
, set
);
1335 if (ka
->sa_flags
& TARGET_SA_RESTORER
) {
1336 return_addr
= ka
->sa_restorer
;
1338 /* mov x8,#__NR_rt_sigreturn; svc #0 */
1339 __put_user(0xd2801168, &frame
->tramp
[0]);
1340 __put_user(0xd4000001, &frame
->tramp
[1]);
1341 return_addr
= frame_addr
+ offsetof(struct target_rt_sigframe
, tramp
);
1343 env
->xregs
[0] = usig
;
1344 env
->xregs
[31] = frame_addr
;
1345 env
->xregs
[29] = env
->xregs
[31] + offsetof(struct target_rt_sigframe
, fp
);
1346 env
->pc
= ka
->_sa_handler
;
1347 env
->xregs
[30] = return_addr
;
1349 tswap_siginfo(&frame
->info
, info
);
1350 env
->xregs
[1] = frame_addr
+ offsetof(struct target_rt_sigframe
, info
);
1351 env
->xregs
[2] = frame_addr
+ offsetof(struct target_rt_sigframe
, uc
);
1354 unlock_user_struct(frame
, frame_addr
, 1);
1358 unlock_user_struct(frame
, frame_addr
, 1);
1359 force_sig(TARGET_SIGSEGV
);
1362 static void setup_rt_frame(int sig
, struct target_sigaction
*ka
,
1363 target_siginfo_t
*info
, target_sigset_t
*set
,
1366 target_setup_frame(sig
, ka
, info
, set
, env
);
1369 static void setup_frame(int sig
, struct target_sigaction
*ka
,
1370 target_sigset_t
*set
, CPUARMState
*env
)
1372 target_setup_frame(sig
, ka
, 0, set
, env
);
1375 long do_rt_sigreturn(CPUARMState
*env
)
1377 struct target_rt_sigframe
*frame
= NULL
;
1378 abi_ulong frame_addr
= env
->xregs
[31];
1380 if (frame_addr
& 15) {
1384 if (!lock_user_struct(VERIFY_READ
, frame
, frame_addr
, 1)) {
1388 if (target_restore_sigframe(env
, frame
)) {
1392 if (do_sigaltstack(frame_addr
+
1393 offsetof(struct target_rt_sigframe
, uc
.tuc_stack
),
1394 0, get_sp_from_cpustate(env
)) == -EFAULT
) {
1398 unlock_user_struct(frame
, frame_addr
, 0);
1399 return env
->xregs
[0];
1402 unlock_user_struct(frame
, frame_addr
, 0);
1403 force_sig(TARGET_SIGSEGV
);
1407 long do_sigreturn(CPUARMState
*env
)
1409 return do_rt_sigreturn(env
);
1412 #elif defined(TARGET_ARM)
1414 struct target_sigcontext
{
1416 abi_ulong error_code
;
1435 abi_ulong fault_address
;
1438 struct target_ucontext_v1
{
1439 abi_ulong tuc_flags
;
1441 target_stack_t tuc_stack
;
1442 struct target_sigcontext tuc_mcontext
;
1443 target_sigset_t tuc_sigmask
; /* mask last for extensibility */
1446 struct target_ucontext_v2
{
1447 abi_ulong tuc_flags
;
1449 target_stack_t tuc_stack
;
1450 struct target_sigcontext tuc_mcontext
;
1451 target_sigset_t tuc_sigmask
; /* mask last for extensibility */
1452 char __unused
[128 - sizeof(target_sigset_t
)];
1453 abi_ulong tuc_regspace
[128] __attribute__((__aligned__(8)));
1456 struct target_user_vfp
{
1457 uint64_t fpregs
[32];
1461 struct target_user_vfp_exc
{
1467 struct target_vfp_sigframe
{
1470 struct target_user_vfp ufp
;
1471 struct target_user_vfp_exc ufp_exc
;
1472 } __attribute__((__aligned__(8)));
1474 struct target_iwmmxt_sigframe
{
1478 /* Note that not all the coprocessor control registers are stored here */
1485 } __attribute__((__aligned__(8)));
1487 #define TARGET_VFP_MAGIC 0x56465001
1488 #define TARGET_IWMMXT_MAGIC 0x12ef842a
1492 struct target_sigcontext sc
;
1493 abi_ulong extramask
[TARGET_NSIG_WORDS
-1];
1499 struct target_ucontext_v2 uc
;
1503 struct rt_sigframe_v1
1507 struct target_siginfo info
;
1508 struct target_ucontext_v1 uc
;
1512 struct rt_sigframe_v2
1514 struct target_siginfo info
;
1515 struct target_ucontext_v2 uc
;
1519 #define TARGET_CONFIG_CPU_32 1
1522 * For ARM syscalls, we encode the syscall number into the instruction.
1524 #define SWI_SYS_SIGRETURN (0xef000000|(TARGET_NR_sigreturn + ARM_SYSCALL_BASE))
1525 #define SWI_SYS_RT_SIGRETURN (0xef000000|(TARGET_NR_rt_sigreturn + ARM_SYSCALL_BASE))
1528 * For Thumb syscalls, we pass the syscall number via r7. We therefore
1529 * need two 16-bit instructions.
1531 #define SWI_THUMB_SIGRETURN (0xdf00 << 16 | 0x2700 | (TARGET_NR_sigreturn))
1532 #define SWI_THUMB_RT_SIGRETURN (0xdf00 << 16 | 0x2700 | (TARGET_NR_rt_sigreturn))
1534 static const abi_ulong retcodes
[4] = {
1535 SWI_SYS_SIGRETURN
, SWI_THUMB_SIGRETURN
,
1536 SWI_SYS_RT_SIGRETURN
, SWI_THUMB_RT_SIGRETURN
1540 static inline int valid_user_regs(CPUARMState
*regs
)
1546 setup_sigcontext(struct target_sigcontext
*sc
, /*struct _fpstate *fpstate,*/
1547 CPUARMState
*env
, abi_ulong mask
)
1549 __put_user(env
->regs
[0], &sc
->arm_r0
);
1550 __put_user(env
->regs
[1], &sc
->arm_r1
);
1551 __put_user(env
->regs
[2], &sc
->arm_r2
);
1552 __put_user(env
->regs
[3], &sc
->arm_r3
);
1553 __put_user(env
->regs
[4], &sc
->arm_r4
);
1554 __put_user(env
->regs
[5], &sc
->arm_r5
);
1555 __put_user(env
->regs
[6], &sc
->arm_r6
);
1556 __put_user(env
->regs
[7], &sc
->arm_r7
);
1557 __put_user(env
->regs
[8], &sc
->arm_r8
);
1558 __put_user(env
->regs
[9], &sc
->arm_r9
);
1559 __put_user(env
->regs
[10], &sc
->arm_r10
);
1560 __put_user(env
->regs
[11], &sc
->arm_fp
);
1561 __put_user(env
->regs
[12], &sc
->arm_ip
);
1562 __put_user(env
->regs
[13], &sc
->arm_sp
);
1563 __put_user(env
->regs
[14], &sc
->arm_lr
);
1564 __put_user(env
->regs
[15], &sc
->arm_pc
);
1565 #ifdef TARGET_CONFIG_CPU_32
1566 __put_user(cpsr_read(env
), &sc
->arm_cpsr
);
1569 __put_user(/* current->thread.trap_no */ 0, &sc
->trap_no
);
1570 __put_user(/* current->thread.error_code */ 0, &sc
->error_code
);
1571 __put_user(/* current->thread.address */ 0, &sc
->fault_address
);
1572 __put_user(mask
, &sc
->oldmask
);
1575 static inline abi_ulong
1576 get_sigframe(struct target_sigaction
*ka
, CPUARMState
*regs
, int framesize
)
1578 unsigned long sp
= regs
->regs
[13];
1581 * This is the X/Open sanctioned signal stack switching.
1583 if ((ka
->sa_flags
& TARGET_SA_ONSTACK
) && !sas_ss_flags(sp
))
1584 sp
= target_sigaltstack_used
.ss_sp
+ target_sigaltstack_used
.ss_size
;
1586 * ATPCS B01 mandates 8-byte alignment
1588 return (sp
- framesize
) & ~7;
1592 setup_return(CPUARMState
*env
, struct target_sigaction
*ka
,
1593 abi_ulong
*rc
, abi_ulong frame_addr
, int usig
, abi_ulong rc_addr
)
1595 abi_ulong handler
= ka
->_sa_handler
;
1597 int thumb
= handler
& 1;
1598 uint32_t cpsr
= cpsr_read(env
);
1607 if (ka
->sa_flags
& TARGET_SA_RESTORER
) {
1608 retcode
= ka
->sa_restorer
;
1610 unsigned int idx
= thumb
;
1612 if (ka
->sa_flags
& TARGET_SA_SIGINFO
)
1615 __put_user(retcodes
[idx
], rc
);
1617 retcode
= rc_addr
+ thumb
;
1620 env
->regs
[0] = usig
;
1621 env
->regs
[13] = frame_addr
;
1622 env
->regs
[14] = retcode
;
1623 env
->regs
[15] = handler
& (thumb
? ~1 : ~3);
1624 cpsr_write(env
, cpsr
, 0xffffffff);
1627 static abi_ulong
*setup_sigframe_v2_vfp(abi_ulong
*regspace
, CPUARMState
*env
)
1630 struct target_vfp_sigframe
*vfpframe
;
1631 vfpframe
= (struct target_vfp_sigframe
*)regspace
;
1632 __put_user(TARGET_VFP_MAGIC
, &vfpframe
->magic
);
1633 __put_user(sizeof(*vfpframe
), &vfpframe
->size
);
1634 for (i
= 0; i
< 32; i
++) {
1635 __put_user(float64_val(env
->vfp
.regs
[i
]), &vfpframe
->ufp
.fpregs
[i
]);
1637 __put_user(vfp_get_fpscr(env
), &vfpframe
->ufp
.fpscr
);
1638 __put_user(env
->vfp
.xregs
[ARM_VFP_FPEXC
], &vfpframe
->ufp_exc
.fpexc
);
1639 __put_user(env
->vfp
.xregs
[ARM_VFP_FPINST
], &vfpframe
->ufp_exc
.fpinst
);
1640 __put_user(env
->vfp
.xregs
[ARM_VFP_FPINST2
], &vfpframe
->ufp_exc
.fpinst2
);
1641 return (abi_ulong
*)(vfpframe
+1);
1644 static abi_ulong
*setup_sigframe_v2_iwmmxt(abi_ulong
*regspace
,
1648 struct target_iwmmxt_sigframe
*iwmmxtframe
;
1649 iwmmxtframe
= (struct target_iwmmxt_sigframe
*)regspace
;
1650 __put_user(TARGET_IWMMXT_MAGIC
, &iwmmxtframe
->magic
);
1651 __put_user(sizeof(*iwmmxtframe
), &iwmmxtframe
->size
);
1652 for (i
= 0; i
< 16; i
++) {
1653 __put_user(env
->iwmmxt
.regs
[i
], &iwmmxtframe
->regs
[i
]);
1655 __put_user(env
->vfp
.xregs
[ARM_IWMMXT_wCSSF
], &iwmmxtframe
->wcssf
);
1656 __put_user(env
->vfp
.xregs
[ARM_IWMMXT_wCASF
], &iwmmxtframe
->wcssf
);
1657 __put_user(env
->vfp
.xregs
[ARM_IWMMXT_wCGR0
], &iwmmxtframe
->wcgr0
);
1658 __put_user(env
->vfp
.xregs
[ARM_IWMMXT_wCGR1
], &iwmmxtframe
->wcgr1
);
1659 __put_user(env
->vfp
.xregs
[ARM_IWMMXT_wCGR2
], &iwmmxtframe
->wcgr2
);
1660 __put_user(env
->vfp
.xregs
[ARM_IWMMXT_wCGR3
], &iwmmxtframe
->wcgr3
);
1661 return (abi_ulong
*)(iwmmxtframe
+1);
1664 static void setup_sigframe_v2(struct target_ucontext_v2
*uc
,
1665 target_sigset_t
*set
, CPUARMState
*env
)
1667 struct target_sigaltstack stack
;
1669 abi_ulong
*regspace
;
1671 /* Clear all the bits of the ucontext we don't use. */
1672 memset(uc
, 0, offsetof(struct target_ucontext_v2
, tuc_mcontext
));
1674 memset(&stack
, 0, sizeof(stack
));
1675 __put_user(target_sigaltstack_used
.ss_sp
, &stack
.ss_sp
);
1676 __put_user(target_sigaltstack_used
.ss_size
, &stack
.ss_size
);
1677 __put_user(sas_ss_flags(get_sp_from_cpustate(env
)), &stack
.ss_flags
);
1678 memcpy(&uc
->tuc_stack
, &stack
, sizeof(stack
));
1680 setup_sigcontext(&uc
->tuc_mcontext
, env
, set
->sig
[0]);
1681 /* Save coprocessor signal frame. */
1682 regspace
= uc
->tuc_regspace
;
1683 if (arm_feature(env
, ARM_FEATURE_VFP
)) {
1684 regspace
= setup_sigframe_v2_vfp(regspace
, env
);
1686 if (arm_feature(env
, ARM_FEATURE_IWMMXT
)) {
1687 regspace
= setup_sigframe_v2_iwmmxt(regspace
, env
);
1690 /* Write terminating magic word */
1691 __put_user(0, regspace
);
1693 for(i
= 0; i
< TARGET_NSIG_WORDS
; i
++) {
1694 __put_user(set
->sig
[i
], &uc
->tuc_sigmask
.sig
[i
]);
1698 /* compare linux/arch/arm/kernel/signal.c:setup_frame() */
1699 static void setup_frame_v1(int usig
, struct target_sigaction
*ka
,
1700 target_sigset_t
*set
, CPUARMState
*regs
)
1702 struct sigframe_v1
*frame
;
1703 abi_ulong frame_addr
= get_sigframe(ka
, regs
, sizeof(*frame
));
1706 if (!lock_user_struct(VERIFY_WRITE
, frame
, frame_addr
, 0))
1709 setup_sigcontext(&frame
->sc
, regs
, set
->sig
[0]);
1711 for(i
= 1; i
< TARGET_NSIG_WORDS
; i
++) {
1712 __put_user(set
->sig
[i
], &frame
->extramask
[i
- 1]);
1715 setup_return(regs
, ka
, &frame
->retcode
, frame_addr
, usig
,
1716 frame_addr
+ offsetof(struct sigframe_v1
, retcode
));
1718 unlock_user_struct(frame
, frame_addr
, 1);
1721 static void setup_frame_v2(int usig
, struct target_sigaction
*ka
,
1722 target_sigset_t
*set
, CPUARMState
*regs
)
1724 struct sigframe_v2
*frame
;
1725 abi_ulong frame_addr
= get_sigframe(ka
, regs
, sizeof(*frame
));
1727 if (!lock_user_struct(VERIFY_WRITE
, frame
, frame_addr
, 0))
1730 setup_sigframe_v2(&frame
->uc
, set
, regs
);
1732 setup_return(regs
, ka
, &frame
->retcode
, frame_addr
, usig
,
1733 frame_addr
+ offsetof(struct sigframe_v2
, retcode
));
1735 unlock_user_struct(frame
, frame_addr
, 1);
1738 static void setup_frame(int usig
, struct target_sigaction
*ka
,
1739 target_sigset_t
*set
, CPUARMState
*regs
)
1741 if (get_osversion() >= 0x020612) {
1742 setup_frame_v2(usig
, ka
, set
, regs
);
1744 setup_frame_v1(usig
, ka
, set
, regs
);
1748 /* compare linux/arch/arm/kernel/signal.c:setup_rt_frame() */
1749 static void setup_rt_frame_v1(int usig
, struct target_sigaction
*ka
,
1750 target_siginfo_t
*info
,
1751 target_sigset_t
*set
, CPUARMState
*env
)
1753 struct rt_sigframe_v1
*frame
;
1754 abi_ulong frame_addr
= get_sigframe(ka
, env
, sizeof(*frame
));
1755 struct target_sigaltstack stack
;
1757 abi_ulong info_addr
, uc_addr
;
1759 if (!lock_user_struct(VERIFY_WRITE
, frame
, frame_addr
, 0))
1762 info_addr
= frame_addr
+ offsetof(struct rt_sigframe_v1
, info
);
1763 __put_user(info_addr
, &frame
->pinfo
);
1764 uc_addr
= frame_addr
+ offsetof(struct rt_sigframe_v1
, uc
);
1765 __put_user(uc_addr
, &frame
->puc
);
1766 tswap_siginfo(&frame
->info
, info
);
1768 /* Clear all the bits of the ucontext we don't use. */
1769 memset(&frame
->uc
, 0, offsetof(struct target_ucontext_v1
, tuc_mcontext
));
1771 memset(&stack
, 0, sizeof(stack
));
1772 __put_user(target_sigaltstack_used
.ss_sp
, &stack
.ss_sp
);
1773 __put_user(target_sigaltstack_used
.ss_size
, &stack
.ss_size
);
1774 __put_user(sas_ss_flags(get_sp_from_cpustate(env
)), &stack
.ss_flags
);
1775 memcpy(&frame
->uc
.tuc_stack
, &stack
, sizeof(stack
));
1777 setup_sigcontext(&frame
->uc
.tuc_mcontext
, env
, set
->sig
[0]);
1778 for(i
= 0; i
< TARGET_NSIG_WORDS
; i
++) {
1779 __put_user(set
->sig
[i
], &frame
->uc
.tuc_sigmask
.sig
[i
]);
1782 setup_return(env
, ka
, &frame
->retcode
, frame_addr
, usig
,
1783 frame_addr
+ offsetof(struct rt_sigframe_v1
, retcode
));
1785 env
->regs
[1] = info_addr
;
1786 env
->regs
[2] = uc_addr
;
1788 unlock_user_struct(frame
, frame_addr
, 1);
1791 static void setup_rt_frame_v2(int usig
, struct target_sigaction
*ka
,
1792 target_siginfo_t
*info
,
1793 target_sigset_t
*set
, CPUARMState
*env
)
1795 struct rt_sigframe_v2
*frame
;
1796 abi_ulong frame_addr
= get_sigframe(ka
, env
, sizeof(*frame
));
1797 abi_ulong info_addr
, uc_addr
;
1799 if (!lock_user_struct(VERIFY_WRITE
, frame
, frame_addr
, 0))
1802 info_addr
= frame_addr
+ offsetof(struct rt_sigframe_v2
, info
);
1803 uc_addr
= frame_addr
+ offsetof(struct rt_sigframe_v2
, uc
);
1804 tswap_siginfo(&frame
->info
, info
);
1806 setup_sigframe_v2(&frame
->uc
, set
, env
);
1808 setup_return(env
, ka
, &frame
->retcode
, frame_addr
, usig
,
1809 frame_addr
+ offsetof(struct rt_sigframe_v2
, retcode
));
1811 env
->regs
[1] = info_addr
;
1812 env
->regs
[2] = uc_addr
;
1814 unlock_user_struct(frame
, frame_addr
, 1);
1817 static void setup_rt_frame(int usig
, struct target_sigaction
*ka
,
1818 target_siginfo_t
*info
,
1819 target_sigset_t
*set
, CPUARMState
*env
)
1821 if (get_osversion() >= 0x020612) {
1822 setup_rt_frame_v2(usig
, ka
, info
, set
, env
);
1824 setup_rt_frame_v1(usig
, ka
, info
, set
, env
);
1829 restore_sigcontext(CPUARMState
*env
, struct target_sigcontext
*sc
)
1834 __get_user(env
->regs
[0], &sc
->arm_r0
);
1835 __get_user(env
->regs
[1], &sc
->arm_r1
);
1836 __get_user(env
->regs
[2], &sc
->arm_r2
);
1837 __get_user(env
->regs
[3], &sc
->arm_r3
);
1838 __get_user(env
->regs
[4], &sc
->arm_r4
);
1839 __get_user(env
->regs
[5], &sc
->arm_r5
);
1840 __get_user(env
->regs
[6], &sc
->arm_r6
);
1841 __get_user(env
->regs
[7], &sc
->arm_r7
);
1842 __get_user(env
->regs
[8], &sc
->arm_r8
);
1843 __get_user(env
->regs
[9], &sc
->arm_r9
);
1844 __get_user(env
->regs
[10], &sc
->arm_r10
);
1845 __get_user(env
->regs
[11], &sc
->arm_fp
);
1846 __get_user(env
->regs
[12], &sc
->arm_ip
);
1847 __get_user(env
->regs
[13], &sc
->arm_sp
);
1848 __get_user(env
->regs
[14], &sc
->arm_lr
);
1849 __get_user(env
->regs
[15], &sc
->arm_pc
);
1850 #ifdef TARGET_CONFIG_CPU_32
1851 __get_user(cpsr
, &sc
->arm_cpsr
);
1852 cpsr_write(env
, cpsr
, CPSR_USER
| CPSR_EXEC
);
1855 err
|= !valid_user_regs(env
);
1860 static long do_sigreturn_v1(CPUARMState
*env
)
1862 abi_ulong frame_addr
;
1863 struct sigframe_v1
*frame
= NULL
;
1864 target_sigset_t set
;
1869 * Since we stacked the signal on a 64-bit boundary,
1870 * then 'sp' should be word aligned here. If it's
1871 * not, then the user is trying to mess with us.
1873 frame_addr
= env
->regs
[13];
1874 if (frame_addr
& 7) {
1878 if (!lock_user_struct(VERIFY_READ
, frame
, frame_addr
, 1))
1881 __get_user(set
.sig
[0], &frame
->sc
.oldmask
);
1882 for(i
= 1; i
< TARGET_NSIG_WORDS
; i
++) {
1883 __get_user(set
.sig
[i
], &frame
->extramask
[i
- 1]);
1886 target_to_host_sigset_internal(&host_set
, &set
);
1887 do_sigprocmask(SIG_SETMASK
, &host_set
, NULL
);
1889 if (restore_sigcontext(env
, &frame
->sc
))
1893 /* Send SIGTRAP if we're single-stepping */
1894 if (ptrace_cancel_bpt(current
))
1895 send_sig(SIGTRAP
, current
, 1);
1897 unlock_user_struct(frame
, frame_addr
, 0);
1898 return env
->regs
[0];
1901 force_sig(TARGET_SIGSEGV
/* , current */);
1905 static abi_ulong
*restore_sigframe_v2_vfp(CPUARMState
*env
, abi_ulong
*regspace
)
1908 abi_ulong magic
, sz
;
1909 uint32_t fpscr
, fpexc
;
1910 struct target_vfp_sigframe
*vfpframe
;
1911 vfpframe
= (struct target_vfp_sigframe
*)regspace
;
1913 __get_user(magic
, &vfpframe
->magic
);
1914 __get_user(sz
, &vfpframe
->size
);
1915 if (magic
!= TARGET_VFP_MAGIC
|| sz
!= sizeof(*vfpframe
)) {
1918 for (i
= 0; i
< 32; i
++) {
1919 __get_user(float64_val(env
->vfp
.regs
[i
]), &vfpframe
->ufp
.fpregs
[i
]);
1921 __get_user(fpscr
, &vfpframe
->ufp
.fpscr
);
1922 vfp_set_fpscr(env
, fpscr
);
1923 __get_user(fpexc
, &vfpframe
->ufp_exc
.fpexc
);
1924 /* Sanitise FPEXC: ensure VFP is enabled, FPINST2 is invalid
1925 * and the exception flag is cleared
1928 fpexc
&= ~((1 << 31) | (1 << 28));
1929 env
->vfp
.xregs
[ARM_VFP_FPEXC
] = fpexc
;
1930 __get_user(env
->vfp
.xregs
[ARM_VFP_FPINST
], &vfpframe
->ufp_exc
.fpinst
);
1931 __get_user(env
->vfp
.xregs
[ARM_VFP_FPINST2
], &vfpframe
->ufp_exc
.fpinst2
);
1932 return (abi_ulong
*)(vfpframe
+ 1);
1935 static abi_ulong
*restore_sigframe_v2_iwmmxt(CPUARMState
*env
,
1936 abi_ulong
*regspace
)
1939 abi_ulong magic
, sz
;
1940 struct target_iwmmxt_sigframe
*iwmmxtframe
;
1941 iwmmxtframe
= (struct target_iwmmxt_sigframe
*)regspace
;
1943 __get_user(magic
, &iwmmxtframe
->magic
);
1944 __get_user(sz
, &iwmmxtframe
->size
);
1945 if (magic
!= TARGET_IWMMXT_MAGIC
|| sz
!= sizeof(*iwmmxtframe
)) {
1948 for (i
= 0; i
< 16; i
++) {
1949 __get_user(env
->iwmmxt
.regs
[i
], &iwmmxtframe
->regs
[i
]);
1951 __get_user(env
->vfp
.xregs
[ARM_IWMMXT_wCSSF
], &iwmmxtframe
->wcssf
);
1952 __get_user(env
->vfp
.xregs
[ARM_IWMMXT_wCASF
], &iwmmxtframe
->wcssf
);
1953 __get_user(env
->vfp
.xregs
[ARM_IWMMXT_wCGR0
], &iwmmxtframe
->wcgr0
);
1954 __get_user(env
->vfp
.xregs
[ARM_IWMMXT_wCGR1
], &iwmmxtframe
->wcgr1
);
1955 __get_user(env
->vfp
.xregs
[ARM_IWMMXT_wCGR2
], &iwmmxtframe
->wcgr2
);
1956 __get_user(env
->vfp
.xregs
[ARM_IWMMXT_wCGR3
], &iwmmxtframe
->wcgr3
);
1957 return (abi_ulong
*)(iwmmxtframe
+ 1);
1960 static int do_sigframe_return_v2(CPUARMState
*env
, target_ulong frame_addr
,
1961 struct target_ucontext_v2
*uc
)
1964 abi_ulong
*regspace
;
1966 target_to_host_sigset(&host_set
, &uc
->tuc_sigmask
);
1967 do_sigprocmask(SIG_SETMASK
, &host_set
, NULL
);
1969 if (restore_sigcontext(env
, &uc
->tuc_mcontext
))
1972 /* Restore coprocessor signal frame */
1973 regspace
= uc
->tuc_regspace
;
1974 if (arm_feature(env
, ARM_FEATURE_VFP
)) {
1975 regspace
= restore_sigframe_v2_vfp(env
, regspace
);
1980 if (arm_feature(env
, ARM_FEATURE_IWMMXT
)) {
1981 regspace
= restore_sigframe_v2_iwmmxt(env
, regspace
);
1987 if (do_sigaltstack(frame_addr
+ offsetof(struct target_ucontext_v2
, tuc_stack
), 0, get_sp_from_cpustate(env
)) == -EFAULT
)
1991 /* Send SIGTRAP if we're single-stepping */
1992 if (ptrace_cancel_bpt(current
))
1993 send_sig(SIGTRAP
, current
, 1);
1999 static long do_sigreturn_v2(CPUARMState
*env
)
2001 abi_ulong frame_addr
;
2002 struct sigframe_v2
*frame
= NULL
;
2005 * Since we stacked the signal on a 64-bit boundary,
2006 * then 'sp' should be word aligned here. If it's
2007 * not, then the user is trying to mess with us.
2009 frame_addr
= env
->regs
[13];
2010 if (frame_addr
& 7) {
2014 if (!lock_user_struct(VERIFY_READ
, frame
, frame_addr
, 1))
2017 if (do_sigframe_return_v2(env
, frame_addr
, &frame
->uc
))
2020 unlock_user_struct(frame
, frame_addr
, 0);
2021 return env
->regs
[0];
2024 unlock_user_struct(frame
, frame_addr
, 0);
2025 force_sig(TARGET_SIGSEGV
/* , current */);
2029 long do_sigreturn(CPUARMState
*env
)
2031 if (get_osversion() >= 0x020612) {
2032 return do_sigreturn_v2(env
);
2034 return do_sigreturn_v1(env
);
2038 static long do_rt_sigreturn_v1(CPUARMState
*env
)
2040 abi_ulong frame_addr
;
2041 struct rt_sigframe_v1
*frame
= NULL
;
2045 * Since we stacked the signal on a 64-bit boundary,
2046 * then 'sp' should be word aligned here. If it's
2047 * not, then the user is trying to mess with us.
2049 frame_addr
= env
->regs
[13];
2050 if (frame_addr
& 7) {
2054 if (!lock_user_struct(VERIFY_READ
, frame
, frame_addr
, 1))
2057 target_to_host_sigset(&host_set
, &frame
->uc
.tuc_sigmask
);
2058 do_sigprocmask(SIG_SETMASK
, &host_set
, NULL
);
2060 if (restore_sigcontext(env
, &frame
->uc
.tuc_mcontext
))
2063 if (do_sigaltstack(frame_addr
+ offsetof(struct rt_sigframe_v1
, uc
.tuc_stack
), 0, get_sp_from_cpustate(env
)) == -EFAULT
)
2067 /* Send SIGTRAP if we're single-stepping */
2068 if (ptrace_cancel_bpt(current
))
2069 send_sig(SIGTRAP
, current
, 1);
2071 unlock_user_struct(frame
, frame_addr
, 0);
2072 return env
->regs
[0];
2075 unlock_user_struct(frame
, frame_addr
, 0);
2076 force_sig(TARGET_SIGSEGV
/* , current */);
2080 static long do_rt_sigreturn_v2(CPUARMState
*env
)
2082 abi_ulong frame_addr
;
2083 struct rt_sigframe_v2
*frame
= NULL
;
2086 * Since we stacked the signal on a 64-bit boundary,
2087 * then 'sp' should be word aligned here. If it's
2088 * not, then the user is trying to mess with us.
2090 frame_addr
= env
->regs
[13];
2091 if (frame_addr
& 7) {
2095 if (!lock_user_struct(VERIFY_READ
, frame
, frame_addr
, 1))
2098 if (do_sigframe_return_v2(env
, frame_addr
, &frame
->uc
))
2101 unlock_user_struct(frame
, frame_addr
, 0);
2102 return env
->regs
[0];
2105 unlock_user_struct(frame
, frame_addr
, 0);
2106 force_sig(TARGET_SIGSEGV
/* , current */);
2110 long do_rt_sigreturn(CPUARMState
*env
)
2112 if (get_osversion() >= 0x020612) {
2113 return do_rt_sigreturn_v2(env
);
2115 return do_rt_sigreturn_v1(env
);
2119 #elif defined(TARGET_SPARC)
2121 #define __SUNOS_MAXWIN 31
2123 /* This is what SunOS does, so shall I. */
2124 struct target_sigcontext
{
2125 abi_ulong sigc_onstack
; /* state to restore */
2127 abi_ulong sigc_mask
; /* sigmask to restore */
2128 abi_ulong sigc_sp
; /* stack pointer */
2129 abi_ulong sigc_pc
; /* program counter */
2130 abi_ulong sigc_npc
; /* next program counter */
2131 abi_ulong sigc_psr
; /* for condition codes etc */
2132 abi_ulong sigc_g1
; /* User uses these two registers */
2133 abi_ulong sigc_o0
; /* within the trampoline code. */
2135 /* Now comes information regarding the users window set
2136 * at the time of the signal.
2138 abi_ulong sigc_oswins
; /* outstanding windows */
2140 /* stack ptrs for each regwin buf */
2141 char *sigc_spbuf
[__SUNOS_MAXWIN
];
2143 /* Windows to restore after signal */
2145 abi_ulong locals
[8];
2147 } sigc_wbuf
[__SUNOS_MAXWIN
];
2149 /* A Sparc stack frame */
2150 struct sparc_stackf
{
2151 abi_ulong locals
[8];
2153 /* It's simpler to treat fp and callers_pc as elements of ins[]
2154 * since we never need to access them ourselves.
2158 abi_ulong xxargs
[1];
2167 abi_ulong u_regs
[16]; /* globals and ins */
2173 abi_ulong si_float_regs
[32];
2174 unsigned long si_fsr
;
2175 unsigned long si_fpqdepth
;
2177 unsigned long *insn_addr
;
2180 } qemu_siginfo_fpu_t
;
2183 struct target_signal_frame
{
2184 struct sparc_stackf ss
;
2187 abi_ulong insns
[2] __attribute__ ((aligned (8)));
2188 abi_ulong extramask
[TARGET_NSIG_WORDS
- 1];
2189 abi_ulong extra_size
; /* Should be 0 */
2190 qemu_siginfo_fpu_t fpu_state
;
2192 struct target_rt_signal_frame
{
2193 struct sparc_stackf ss
;
2198 unsigned int insns
[2];
2200 unsigned int extra_size
; /* Should be 0 */
2201 qemu_siginfo_fpu_t fpu_state
;
2215 #define UREG_FP UREG_I6
2216 #define UREG_SP UREG_O6
2218 static inline abi_ulong
get_sigframe(struct target_sigaction
*sa
,
2220 unsigned long framesize
)
2224 sp
= env
->regwptr
[UREG_FP
];
2226 /* This is the X/Open sanctioned signal stack switching. */
2227 if (sa
->sa_flags
& TARGET_SA_ONSTACK
) {
2228 if (!on_sig_stack(sp
)
2229 && !((target_sigaltstack_used
.ss_sp
+ target_sigaltstack_used
.ss_size
) & 7))
2230 sp
= target_sigaltstack_used
.ss_sp
+ target_sigaltstack_used
.ss_size
;
2232 return sp
- framesize
;
2236 setup___siginfo(__siginfo_t
*si
, CPUSPARCState
*env
, abi_ulong mask
)
2240 __put_user(env
->psr
, &si
->si_regs
.psr
);
2241 __put_user(env
->pc
, &si
->si_regs
.pc
);
2242 __put_user(env
->npc
, &si
->si_regs
.npc
);
2243 __put_user(env
->y
, &si
->si_regs
.y
);
2244 for (i
=0; i
< 8; i
++) {
2245 __put_user(env
->gregs
[i
], &si
->si_regs
.u_regs
[i
]);
2247 for (i
=0; i
< 8; i
++) {
2248 __put_user(env
->regwptr
[UREG_I0
+ i
], &si
->si_regs
.u_regs
[i
+8]);
2250 __put_user(mask
, &si
->si_mask
);
2256 setup_sigcontext(struct target_sigcontext
*sc
, /*struct _fpstate *fpstate,*/
2257 CPUSPARCState
*env
, unsigned long mask
)
2261 __put_user(mask
, &sc
->sigc_mask
);
2262 __put_user(env
->regwptr
[UREG_SP
], &sc
->sigc_sp
);
2263 __put_user(env
->pc
, &sc
->sigc_pc
);
2264 __put_user(env
->npc
, &sc
->sigc_npc
);
2265 __put_user(env
->psr
, &sc
->sigc_psr
);
2266 __put_user(env
->gregs
[1], &sc
->sigc_g1
);
2267 __put_user(env
->regwptr
[UREG_O0
], &sc
->sigc_o0
);
2272 #define NF_ALIGNEDSZ (((sizeof(struct target_signal_frame) + 7) & (~7)))
2274 static void setup_frame(int sig
, struct target_sigaction
*ka
,
2275 target_sigset_t
*set
, CPUSPARCState
*env
)
2278 struct target_signal_frame
*sf
;
2279 int sigframe_size
, err
, i
;
2281 /* 1. Make sure everything is clean */
2282 //synchronize_user_stack();
2284 sigframe_size
= NF_ALIGNEDSZ
;
2285 sf_addr
= get_sigframe(ka
, env
, sigframe_size
);
2287 sf
= lock_user(VERIFY_WRITE
, sf_addr
,
2288 sizeof(struct target_signal_frame
), 0);
2292 //fprintf(stderr, "sf: %x pc %x fp %x sp %x\n", sf, env->pc, env->regwptr[UREG_FP], env->regwptr[UREG_SP]);
2294 if (invalid_frame_pointer(sf
, sigframe_size
))
2295 goto sigill_and_return
;
2297 /* 2. Save the current process state */
2298 err
= setup___siginfo(&sf
->info
, env
, set
->sig
[0]);
2299 __put_user(0, &sf
->extra_size
);
2301 //save_fpu_state(regs, &sf->fpu_state);
2302 //__put_user(&sf->fpu_state, &sf->fpu_save);
2304 __put_user(set
->sig
[0], &sf
->info
.si_mask
);
2305 for (i
= 0; i
< TARGET_NSIG_WORDS
- 1; i
++) {
2306 __put_user(set
->sig
[i
+ 1], &sf
->extramask
[i
]);
2309 for (i
= 0; i
< 8; i
++) {
2310 __put_user(env
->regwptr
[i
+ UREG_L0
], &sf
->ss
.locals
[i
]);
2312 for (i
= 0; i
< 8; i
++) {
2313 __put_user(env
->regwptr
[i
+ UREG_I0
], &sf
->ss
.ins
[i
]);
2318 /* 3. signal handler back-trampoline and parameters */
2319 env
->regwptr
[UREG_FP
] = sf_addr
;
2320 env
->regwptr
[UREG_I0
] = sig
;
2321 env
->regwptr
[UREG_I1
] = sf_addr
+
2322 offsetof(struct target_signal_frame
, info
);
2323 env
->regwptr
[UREG_I2
] = sf_addr
+
2324 offsetof(struct target_signal_frame
, info
);
2326 /* 4. signal handler */
2327 env
->pc
= ka
->_sa_handler
;
2328 env
->npc
= (env
->pc
+ 4);
2329 /* 5. return to kernel instructions */
2330 if (ka
->sa_restorer
)
2331 env
->regwptr
[UREG_I7
] = ka
->sa_restorer
;
2335 env
->regwptr
[UREG_I7
] = sf_addr
+
2336 offsetof(struct target_signal_frame
, insns
) - 2 * 4;
2338 /* mov __NR_sigreturn, %g1 */
2340 __put_user(val32
, &sf
->insns
[0]);
2344 __put_user(val32
, &sf
->insns
[1]);
2348 /* Flush instruction space. */
2349 //flush_sig_insns(current->mm, (unsigned long) &(sf->insns[0]));
2350 // tb_flush(CPU(sparc_env_get_cpu(env)));
2352 unlock_user(sf
, sf_addr
, sizeof(struct target_signal_frame
));
2356 force_sig(TARGET_SIGILL
);
2359 //fprintf(stderr, "force_sig\n");
2360 unlock_user(sf
, sf_addr
, sizeof(struct target_signal_frame
));
2361 force_sig(TARGET_SIGSEGV
);
2364 static void setup_rt_frame(int sig
, struct target_sigaction
*ka
,
2365 target_siginfo_t
*info
,
2366 target_sigset_t
*set
, CPUSPARCState
*env
)
2368 fprintf(stderr
, "setup_rt_frame: not implemented\n");
2371 long do_sigreturn(CPUSPARCState
*env
)
2374 struct target_signal_frame
*sf
;
2375 uint32_t up_psr
, pc
, npc
;
2376 target_sigset_t set
;
2380 sf_addr
= env
->regwptr
[UREG_FP
];
2381 if (!lock_user_struct(VERIFY_READ
, sf
, sf_addr
, 1))
2384 fprintf(stderr
, "sigreturn\n");
2385 fprintf(stderr
, "sf: %x pc %x fp %x sp %x\n", sf
, env
->pc
, env
->regwptr
[UREG_FP
], env
->regwptr
[UREG_SP
]);
2387 //cpu_dump_state(env, stderr, fprintf, 0);
2389 /* 1. Make sure we are not getting garbage from the user */
2394 __get_user(pc
, &sf
->info
.si_regs
.pc
);
2395 __get_user(npc
, &sf
->info
.si_regs
.npc
);
2400 /* 2. Restore the state */
2401 __get_user(up_psr
, &sf
->info
.si_regs
.psr
);
2403 /* User can only change condition codes and FPU enabling in %psr. */
2404 env
->psr
= (up_psr
& (PSR_ICC
/* | PSR_EF */))
2405 | (env
->psr
& ~(PSR_ICC
/* | PSR_EF */));
2409 __get_user(env
->y
, &sf
->info
.si_regs
.y
);
2410 for (i
=0; i
< 8; i
++) {
2411 __get_user(env
->gregs
[i
], &sf
->info
.si_regs
.u_regs
[i
]);
2413 for (i
=0; i
< 8; i
++) {
2414 __get_user(env
->regwptr
[i
+ UREG_I0
], &sf
->info
.si_regs
.u_regs
[i
+8]);
2417 /* FIXME: implement FPU save/restore:
2418 * __get_user(fpu_save, &sf->fpu_save);
2420 * err |= restore_fpu_state(env, fpu_save);
2423 /* This is pretty much atomic, no amount locking would prevent
2424 * the races which exist anyways.
2426 __get_user(set
.sig
[0], &sf
->info
.si_mask
);
2427 for(i
= 1; i
< TARGET_NSIG_WORDS
; i
++) {
2428 __get_user(set
.sig
[i
], &sf
->extramask
[i
- 1]);
2431 target_to_host_sigset_internal(&host_set
, &set
);
2432 do_sigprocmask(SIG_SETMASK
, &host_set
, NULL
);
2436 unlock_user_struct(sf
, sf_addr
, 0);
2437 return env
->regwptr
[0];
2440 unlock_user_struct(sf
, sf_addr
, 0);
2441 force_sig(TARGET_SIGSEGV
);
2444 long do_rt_sigreturn(CPUSPARCState
*env
)
2446 fprintf(stderr
, "do_rt_sigreturn: not implemented\n");
2447 return -TARGET_ENOSYS
;
2450 #if defined(TARGET_SPARC64) && !defined(TARGET_ABI32)
2472 typedef abi_ulong target_mc_greg_t
;
2473 typedef target_mc_greg_t target_mc_gregset_t
[MC_NGREG
];
2475 struct target_mc_fq
{
2476 abi_ulong
*mcfq_addr
;
2480 struct target_mc_fpu
{
2484 //uint128_t qregs[16];
2486 abi_ulong mcfpu_fsr
;
2487 abi_ulong mcfpu_fprs
;
2488 abi_ulong mcfpu_gsr
;
2489 struct target_mc_fq
*mcfpu_fq
;
2490 unsigned char mcfpu_qcnt
;
2491 unsigned char mcfpu_qentsz
;
2492 unsigned char mcfpu_enab
;
2494 typedef struct target_mc_fpu target_mc_fpu_t
;
2497 target_mc_gregset_t mc_gregs
;
2498 target_mc_greg_t mc_fp
;
2499 target_mc_greg_t mc_i7
;
2500 target_mc_fpu_t mc_fpregs
;
2501 } target_mcontext_t
;
2503 struct target_ucontext
{
2504 struct target_ucontext
*tuc_link
;
2505 abi_ulong tuc_flags
;
2506 target_sigset_t tuc_sigmask
;
2507 target_mcontext_t tuc_mcontext
;
2510 /* A V9 register window */
2511 struct target_reg_window
{
2512 abi_ulong locals
[8];
2516 #define TARGET_STACK_BIAS 2047
2518 /* {set, get}context() needed for 64-bit SparcLinux userland. */
2519 void sparc64_set_context(CPUSPARCState
*env
)
2522 struct target_ucontext
*ucp
;
2523 target_mc_gregset_t
*grp
;
2524 abi_ulong pc
, npc
, tstate
;
2525 abi_ulong fp
, i7
, w_addr
;
2528 ucp_addr
= env
->regwptr
[UREG_I0
];
2529 if (!lock_user_struct(VERIFY_READ
, ucp
, ucp_addr
, 1))
2531 grp
= &ucp
->tuc_mcontext
.mc_gregs
;
2532 __get_user(pc
, &((*grp
)[MC_PC
]));
2533 __get_user(npc
, &((*grp
)[MC_NPC
]));
2536 if (env
->regwptr
[UREG_I1
]) {
2537 target_sigset_t target_set
;
2540 if (TARGET_NSIG_WORDS
== 1) {
2541 __get_user(target_set
.sig
[0], &ucp
->tuc_sigmask
.sig
[0]);
2543 abi_ulong
*src
, *dst
;
2544 src
= ucp
->tuc_sigmask
.sig
;
2545 dst
= target_set
.sig
;
2546 for (i
= 0; i
< TARGET_NSIG_WORDS
; i
++, dst
++, src
++) {
2547 __get_user(*dst
, src
);
2550 target_to_host_sigset_internal(&set
, &target_set
);
2551 do_sigprocmask(SIG_SETMASK
, &set
, NULL
);
2555 __get_user(env
->y
, &((*grp
)[MC_Y
]));
2556 __get_user(tstate
, &((*grp
)[MC_TSTATE
]));
2557 env
->asi
= (tstate
>> 24) & 0xff;
2558 cpu_put_ccr(env
, tstate
>> 32);
2559 cpu_put_cwp64(env
, tstate
& 0x1f);
2560 __get_user(env
->gregs
[1], (&(*grp
)[MC_G1
]));
2561 __get_user(env
->gregs
[2], (&(*grp
)[MC_G2
]));
2562 __get_user(env
->gregs
[3], (&(*grp
)[MC_G3
]));
2563 __get_user(env
->gregs
[4], (&(*grp
)[MC_G4
]));
2564 __get_user(env
->gregs
[5], (&(*grp
)[MC_G5
]));
2565 __get_user(env
->gregs
[6], (&(*grp
)[MC_G6
]));
2566 __get_user(env
->gregs
[7], (&(*grp
)[MC_G7
]));
2567 __get_user(env
->regwptr
[UREG_I0
], (&(*grp
)[MC_O0
]));
2568 __get_user(env
->regwptr
[UREG_I1
], (&(*grp
)[MC_O1
]));
2569 __get_user(env
->regwptr
[UREG_I2
], (&(*grp
)[MC_O2
]));
2570 __get_user(env
->regwptr
[UREG_I3
], (&(*grp
)[MC_O3
]));
2571 __get_user(env
->regwptr
[UREG_I4
], (&(*grp
)[MC_O4
]));
2572 __get_user(env
->regwptr
[UREG_I5
], (&(*grp
)[MC_O5
]));
2573 __get_user(env
->regwptr
[UREG_I6
], (&(*grp
)[MC_O6
]));
2574 __get_user(env
->regwptr
[UREG_I7
], (&(*grp
)[MC_O7
]));
2576 __get_user(fp
, &(ucp
->tuc_mcontext
.mc_fp
));
2577 __get_user(i7
, &(ucp
->tuc_mcontext
.mc_i7
));
2579 w_addr
= TARGET_STACK_BIAS
+env
->regwptr
[UREG_I6
];
2580 if (put_user(fp
, w_addr
+ offsetof(struct target_reg_window
, ins
[6]),
2583 if (put_user(i7
, w_addr
+ offsetof(struct target_reg_window
, ins
[7]),
2586 /* FIXME this does not match how the kernel handles the FPU in
2587 * its sparc64_set_context implementation. In particular the FPU
2588 * is only restored if fenab is non-zero in:
2589 * __get_user(fenab, &(ucp->tuc_mcontext.mc_fpregs.mcfpu_enab));
2591 __get_user(env
->fprs
, &(ucp
->tuc_mcontext
.mc_fpregs
.mcfpu_fprs
));
2593 uint32_t *src
= ucp
->tuc_mcontext
.mc_fpregs
.mcfpu_fregs
.sregs
;
2594 for (i
= 0; i
< 64; i
++, src
++) {
2596 __get_user(env
->fpr
[i
/2].l
.lower
, src
);
2598 __get_user(env
->fpr
[i
/2].l
.upper
, src
);
2602 __get_user(env
->fsr
,
2603 &(ucp
->tuc_mcontext
.mc_fpregs
.mcfpu_fsr
));
2604 __get_user(env
->gsr
,
2605 &(ucp
->tuc_mcontext
.mc_fpregs
.mcfpu_gsr
));
2606 unlock_user_struct(ucp
, ucp_addr
, 0);
2609 unlock_user_struct(ucp
, ucp_addr
, 0);
2610 force_sig(TARGET_SIGSEGV
);
2613 void sparc64_get_context(CPUSPARCState
*env
)
2616 struct target_ucontext
*ucp
;
2617 target_mc_gregset_t
*grp
;
2618 target_mcontext_t
*mcp
;
2619 abi_ulong fp
, i7
, w_addr
;
2622 target_sigset_t target_set
;
2625 ucp_addr
= env
->regwptr
[UREG_I0
];
2626 if (!lock_user_struct(VERIFY_WRITE
, ucp
, ucp_addr
, 0))
2629 mcp
= &ucp
->tuc_mcontext
;
2630 grp
= &mcp
->mc_gregs
;
2632 /* Skip over the trap instruction, first. */
2638 do_sigprocmask(0, NULL
, &set
);
2639 host_to_target_sigset_internal(&target_set
, &set
);
2640 if (TARGET_NSIG_WORDS
== 1) {
2641 __put_user(target_set
.sig
[0],
2642 (abi_ulong
*)&ucp
->tuc_sigmask
);
2644 abi_ulong
*src
, *dst
;
2645 src
= target_set
.sig
;
2646 dst
= ucp
->tuc_sigmask
.sig
;
2647 for (i
= 0; i
< TARGET_NSIG_WORDS
; i
++, dst
++, src
++) {
2648 __put_user(*src
, dst
);
2654 /* XXX: tstate must be saved properly */
2655 // __put_user(env->tstate, &((*grp)[MC_TSTATE]));
2656 __put_user(env
->pc
, &((*grp
)[MC_PC
]));
2657 __put_user(env
->npc
, &((*grp
)[MC_NPC
]));
2658 __put_user(env
->y
, &((*grp
)[MC_Y
]));
2659 __put_user(env
->gregs
[1], &((*grp
)[MC_G1
]));
2660 __put_user(env
->gregs
[2], &((*grp
)[MC_G2
]));
2661 __put_user(env
->gregs
[3], &((*grp
)[MC_G3
]));
2662 __put_user(env
->gregs
[4], &((*grp
)[MC_G4
]));
2663 __put_user(env
->gregs
[5], &((*grp
)[MC_G5
]));
2664 __put_user(env
->gregs
[6], &((*grp
)[MC_G6
]));
2665 __put_user(env
->gregs
[7], &((*grp
)[MC_G7
]));
2666 __put_user(env
->regwptr
[UREG_I0
], &((*grp
)[MC_O0
]));
2667 __put_user(env
->regwptr
[UREG_I1
], &((*grp
)[MC_O1
]));
2668 __put_user(env
->regwptr
[UREG_I2
], &((*grp
)[MC_O2
]));
2669 __put_user(env
->regwptr
[UREG_I3
], &((*grp
)[MC_O3
]));
2670 __put_user(env
->regwptr
[UREG_I4
], &((*grp
)[MC_O4
]));
2671 __put_user(env
->regwptr
[UREG_I5
], &((*grp
)[MC_O5
]));
2672 __put_user(env
->regwptr
[UREG_I6
], &((*grp
)[MC_O6
]));
2673 __put_user(env
->regwptr
[UREG_I7
], &((*grp
)[MC_O7
]));
2675 w_addr
= TARGET_STACK_BIAS
+env
->regwptr
[UREG_I6
];
2677 if (get_user(fp
, w_addr
+ offsetof(struct target_reg_window
, ins
[6]),
2680 if (get_user(i7
, w_addr
+ offsetof(struct target_reg_window
, ins
[7]),
2683 __put_user(fp
, &(mcp
->mc_fp
));
2684 __put_user(i7
, &(mcp
->mc_i7
));
2687 uint32_t *dst
= ucp
->tuc_mcontext
.mc_fpregs
.mcfpu_fregs
.sregs
;
2688 for (i
= 0; i
< 64; i
++, dst
++) {
2690 __put_user(env
->fpr
[i
/2].l
.lower
, dst
);
2692 __put_user(env
->fpr
[i
/2].l
.upper
, dst
);
2696 __put_user(env
->fsr
, &(mcp
->mc_fpregs
.mcfpu_fsr
));
2697 __put_user(env
->gsr
, &(mcp
->mc_fpregs
.mcfpu_gsr
));
2698 __put_user(env
->fprs
, &(mcp
->mc_fpregs
.mcfpu_fprs
));
2702 unlock_user_struct(ucp
, ucp_addr
, 1);
2705 unlock_user_struct(ucp
, ucp_addr
, 1);
2706 force_sig(TARGET_SIGSEGV
);
2709 #elif defined(TARGET_MIPS) || defined(TARGET_MIPS64)
2711 # if defined(TARGET_ABI_MIPSO32)
2712 struct target_sigcontext
{
2713 uint32_t sc_regmask
; /* Unused */
2716 uint64_t sc_regs
[32];
2717 uint64_t sc_fpregs
[32];
2718 uint32_t sc_ownedfp
; /* Unused */
2719 uint32_t sc_fpc_csr
;
2720 uint32_t sc_fpc_eir
; /* Unused */
2721 uint32_t sc_used_math
;
2722 uint32_t sc_dsp
; /* dsp status, was sc_ssflags */
2726 target_ulong sc_hi1
; /* Was sc_cause */
2727 target_ulong sc_lo1
; /* Was sc_badvaddr */
2728 target_ulong sc_hi2
; /* Was sc_sigset[4] */
2729 target_ulong sc_lo2
;
2730 target_ulong sc_hi3
;
2731 target_ulong sc_lo3
;
2733 # else /* N32 || N64 */
2734 struct target_sigcontext
{
2735 uint64_t sc_regs
[32];
2736 uint64_t sc_fpregs
[32];
2746 uint32_t sc_fpc_csr
;
2747 uint32_t sc_used_math
;
2749 uint32_t sc_reserved
;
2754 uint32_t sf_ass
[4]; /* argument save space for o32 */
2755 uint32_t sf_code
[2]; /* signal trampoline */
2756 struct target_sigcontext sf_sc
;
2757 target_sigset_t sf_mask
;
2760 struct target_ucontext
{
2761 target_ulong tuc_flags
;
2762 target_ulong tuc_link
;
2763 target_stack_t tuc_stack
;
2765 struct target_sigcontext tuc_mcontext
;
2766 target_sigset_t tuc_sigmask
;
2769 struct target_rt_sigframe
{
2770 uint32_t rs_ass
[4]; /* argument save space for o32 */
2771 uint32_t rs_code
[2]; /* signal trampoline */
2772 struct target_siginfo rs_info
;
2773 struct target_ucontext rs_uc
;
2776 /* Install trampoline to jump back from signal handler */
2777 static inline int install_sigtramp(unsigned int *tramp
, unsigned int syscall
)
2782 * Set up the return code ...
2784 * li v0, __NR__foo_sigreturn
2788 __put_user(0x24020000 + syscall
, tramp
+ 0);
2789 __put_user(0x0000000c , tramp
+ 1);
2793 static inline void setup_sigcontext(CPUMIPSState
*regs
,
2794 struct target_sigcontext
*sc
)
2798 __put_user(exception_resume_pc(regs
), &sc
->sc_pc
);
2799 regs
->hflags
&= ~MIPS_HFLAG_BMASK
;
2801 __put_user(0, &sc
->sc_regs
[0]);
2802 for (i
= 1; i
< 32; ++i
) {
2803 __put_user(regs
->active_tc
.gpr
[i
], &sc
->sc_regs
[i
]);
2806 __put_user(regs
->active_tc
.HI
[0], &sc
->sc_mdhi
);
2807 __put_user(regs
->active_tc
.LO
[0], &sc
->sc_mdlo
);
2809 /* Rather than checking for dsp existence, always copy. The storage
2810 would just be garbage otherwise. */
2811 __put_user(regs
->active_tc
.HI
[1], &sc
->sc_hi1
);
2812 __put_user(regs
->active_tc
.HI
[2], &sc
->sc_hi2
);
2813 __put_user(regs
->active_tc
.HI
[3], &sc
->sc_hi3
);
2814 __put_user(regs
->active_tc
.LO
[1], &sc
->sc_lo1
);
2815 __put_user(regs
->active_tc
.LO
[2], &sc
->sc_lo2
);
2816 __put_user(regs
->active_tc
.LO
[3], &sc
->sc_lo3
);
2818 uint32_t dsp
= cpu_rddsp(0x3ff, regs
);
2819 __put_user(dsp
, &sc
->sc_dsp
);
2822 __put_user(1, &sc
->sc_used_math
);
2824 for (i
= 0; i
< 32; ++i
) {
2825 __put_user(regs
->active_fpu
.fpr
[i
].d
, &sc
->sc_fpregs
[i
]);
2830 restore_sigcontext(CPUMIPSState
*regs
, struct target_sigcontext
*sc
)
2834 __get_user(regs
->CP0_EPC
, &sc
->sc_pc
);
2836 __get_user(regs
->active_tc
.HI
[0], &sc
->sc_mdhi
);
2837 __get_user(regs
->active_tc
.LO
[0], &sc
->sc_mdlo
);
2839 for (i
= 1; i
< 32; ++i
) {
2840 __get_user(regs
->active_tc
.gpr
[i
], &sc
->sc_regs
[i
]);
2843 __get_user(regs
->active_tc
.HI
[1], &sc
->sc_hi1
);
2844 __get_user(regs
->active_tc
.HI
[2], &sc
->sc_hi2
);
2845 __get_user(regs
->active_tc
.HI
[3], &sc
->sc_hi3
);
2846 __get_user(regs
->active_tc
.LO
[1], &sc
->sc_lo1
);
2847 __get_user(regs
->active_tc
.LO
[2], &sc
->sc_lo2
);
2848 __get_user(regs
->active_tc
.LO
[3], &sc
->sc_lo3
);
2851 __get_user(dsp
, &sc
->sc_dsp
);
2852 cpu_wrdsp(dsp
, 0x3ff, regs
);
2855 for (i
= 0; i
< 32; ++i
) {
2856 __get_user(regs
->active_fpu
.fpr
[i
].d
, &sc
->sc_fpregs
[i
]);
2861 * Determine which stack to use..
2863 static inline abi_ulong
2864 get_sigframe(struct target_sigaction
*ka
, CPUMIPSState
*regs
, size_t frame_size
)
2868 /* Default to using normal stack */
2869 sp
= regs
->active_tc
.gpr
[29];
2872 * FPU emulator may have its own trampoline active just
2873 * above the user stack, 16-bytes before the next lowest
2874 * 16 byte boundary. Try to avoid trashing it.
2878 /* This is the X/Open sanctioned signal stack switching. */
2879 if ((ka
->sa_flags
& TARGET_SA_ONSTACK
) && (sas_ss_flags (sp
) == 0)) {
2880 sp
= target_sigaltstack_used
.ss_sp
+ target_sigaltstack_used
.ss_size
;
2883 return (sp
- frame_size
) & ~7;
2886 static void mips_set_hflags_isa_mode_from_pc(CPUMIPSState
*env
)
2888 if (env
->insn_flags
& (ASE_MIPS16
| ASE_MICROMIPS
)) {
2889 env
->hflags
&= ~MIPS_HFLAG_M16
;
2890 env
->hflags
|= (env
->active_tc
.PC
& 1) << MIPS_HFLAG_M16_SHIFT
;
2891 env
->active_tc
.PC
&= ~(target_ulong
) 1;
2895 # if defined(TARGET_ABI_MIPSO32)
2896 /* compare linux/arch/mips/kernel/signal.c:setup_frame() */
2897 static void setup_frame(int sig
, struct target_sigaction
* ka
,
2898 target_sigset_t
*set
, CPUMIPSState
*regs
)
2900 struct sigframe
*frame
;
2901 abi_ulong frame_addr
;
2904 frame_addr
= get_sigframe(ka
, regs
, sizeof(*frame
));
2905 if (!lock_user_struct(VERIFY_WRITE
, frame
, frame_addr
, 0))
2908 install_sigtramp(frame
->sf_code
, TARGET_NR_sigreturn
);
2910 setup_sigcontext(regs
, &frame
->sf_sc
);
2912 for(i
= 0; i
< TARGET_NSIG_WORDS
; i
++) {
2913 __put_user(set
->sig
[i
], &frame
->sf_mask
.sig
[i
]);
2917 * Arguments to signal handler:
2919 * a0 = signal number
2920 * a1 = 0 (should be cause)
2921 * a2 = pointer to struct sigcontext
2923 * $25 and PC point to the signal handler, $29 points to the
2926 regs
->active_tc
.gpr
[ 4] = sig
;
2927 regs
->active_tc
.gpr
[ 5] = 0;
2928 regs
->active_tc
.gpr
[ 6] = frame_addr
+ offsetof(struct sigframe
, sf_sc
);
2929 regs
->active_tc
.gpr
[29] = frame_addr
;
2930 regs
->active_tc
.gpr
[31] = frame_addr
+ offsetof(struct sigframe
, sf_code
);
2931 /* The original kernel code sets CP0_EPC to the handler
2932 * since it returns to userland using eret
2933 * we cannot do this here, and we must set PC directly */
2934 regs
->active_tc
.PC
= regs
->active_tc
.gpr
[25] = ka
->_sa_handler
;
2935 mips_set_hflags_isa_mode_from_pc(regs
);
2936 unlock_user_struct(frame
, frame_addr
, 1);
2940 force_sig(TARGET_SIGSEGV
/*, current*/);
2943 long do_sigreturn(CPUMIPSState
*regs
)
2945 struct sigframe
*frame
;
2946 abi_ulong frame_addr
;
2948 target_sigset_t target_set
;
2951 #if defined(DEBUG_SIGNAL)
2952 fprintf(stderr
, "do_sigreturn\n");
2954 frame_addr
= regs
->active_tc
.gpr
[29];
2955 if (!lock_user_struct(VERIFY_READ
, frame
, frame_addr
, 1))
2958 for(i
= 0; i
< TARGET_NSIG_WORDS
; i
++) {
2959 __get_user(target_set
.sig
[i
], &frame
->sf_mask
.sig
[i
]);
2962 target_to_host_sigset_internal(&blocked
, &target_set
);
2963 do_sigprocmask(SIG_SETMASK
, &blocked
, NULL
);
2965 restore_sigcontext(regs
, &frame
->sf_sc
);
2969 * Don't let your children do this ...
2971 __asm__
__volatile__(
2979 regs
->active_tc
.PC
= regs
->CP0_EPC
;
2980 mips_set_hflags_isa_mode_from_pc(regs
);
2981 /* I am not sure this is right, but it seems to work
2982 * maybe a problem with nested signals ? */
2984 return -TARGET_QEMU_ESIGRETURN
;
2987 force_sig(TARGET_SIGSEGV
/*, current*/);
2992 static void setup_rt_frame(int sig
, struct target_sigaction
*ka
,
2993 target_siginfo_t
*info
,
2994 target_sigset_t
*set
, CPUMIPSState
*env
)
2996 struct target_rt_sigframe
*frame
;
2997 abi_ulong frame_addr
;
3000 frame_addr
= get_sigframe(ka
, env
, sizeof(*frame
));
3001 if (!lock_user_struct(VERIFY_WRITE
, frame
, frame_addr
, 0))
3004 install_sigtramp(frame
->rs_code
, TARGET_NR_rt_sigreturn
);
3006 tswap_siginfo(&frame
->rs_info
, info
);
3008 __put_user(0, &frame
->rs_uc
.tuc_flags
);
3009 __put_user(0, &frame
->rs_uc
.tuc_link
);
3010 __put_user(target_sigaltstack_used
.ss_sp
, &frame
->rs_uc
.tuc_stack
.ss_sp
);
3011 __put_user(target_sigaltstack_used
.ss_size
, &frame
->rs_uc
.tuc_stack
.ss_size
);
3012 __put_user(sas_ss_flags(get_sp_from_cpustate(env
)),
3013 &frame
->rs_uc
.tuc_stack
.ss_flags
);
3015 setup_sigcontext(env
, &frame
->rs_uc
.tuc_mcontext
);
3017 for(i
= 0; i
< TARGET_NSIG_WORDS
; i
++) {
3018 __put_user(set
->sig
[i
], &frame
->rs_uc
.tuc_sigmask
.sig
[i
]);
3022 * Arguments to signal handler:
3024 * a0 = signal number
3025 * a1 = pointer to siginfo_t
3026 * a2 = pointer to struct ucontext
3028 * $25 and PC point to the signal handler, $29 points to the
3031 env
->active_tc
.gpr
[ 4] = sig
;
3032 env
->active_tc
.gpr
[ 5] = frame_addr
3033 + offsetof(struct target_rt_sigframe
, rs_info
);
3034 env
->active_tc
.gpr
[ 6] = frame_addr
3035 + offsetof(struct target_rt_sigframe
, rs_uc
);
3036 env
->active_tc
.gpr
[29] = frame_addr
;
3037 env
->active_tc
.gpr
[31] = frame_addr
3038 + offsetof(struct target_rt_sigframe
, rs_code
);
3039 /* The original kernel code sets CP0_EPC to the handler
3040 * since it returns to userland using eret
3041 * we cannot do this here, and we must set PC directly */
3042 env
->active_tc
.PC
= env
->active_tc
.gpr
[25] = ka
->_sa_handler
;
3043 mips_set_hflags_isa_mode_from_pc(env
);
3044 unlock_user_struct(frame
, frame_addr
, 1);
3048 unlock_user_struct(frame
, frame_addr
, 1);
3049 force_sig(TARGET_SIGSEGV
/*, current*/);
3052 long do_rt_sigreturn(CPUMIPSState
*env
)
3054 struct target_rt_sigframe
*frame
;
3055 abi_ulong frame_addr
;
3058 #if defined(DEBUG_SIGNAL)
3059 fprintf(stderr
, "do_rt_sigreturn\n");
3061 frame_addr
= env
->active_tc
.gpr
[29];
3062 if (!lock_user_struct(VERIFY_READ
, frame
, frame_addr
, 1))
3065 target_to_host_sigset(&blocked
, &frame
->rs_uc
.tuc_sigmask
);
3066 do_sigprocmask(SIG_SETMASK
, &blocked
, NULL
);
3068 restore_sigcontext(env
, &frame
->rs_uc
.tuc_mcontext
);
3070 if (do_sigaltstack(frame_addr
+
3071 offsetof(struct target_rt_sigframe
, rs_uc
.tuc_stack
),
3072 0, get_sp_from_cpustate(env
)) == -EFAULT
)
3075 env
->active_tc
.PC
= env
->CP0_EPC
;
3076 mips_set_hflags_isa_mode_from_pc(env
);
3077 /* I am not sure this is right, but it seems to work
3078 * maybe a problem with nested signals ? */
3080 return -TARGET_QEMU_ESIGRETURN
;
3083 force_sig(TARGET_SIGSEGV
/*, current*/);
3087 #elif defined(TARGET_SH4)
3090 * code and data structures from linux kernel:
3091 * include/asm-sh/sigcontext.h
3092 * arch/sh/kernel/signal.c
3095 struct target_sigcontext
{
3096 target_ulong oldmask
;
3099 target_ulong sc_gregs
[16];
3103 target_ulong sc_gbr
;
3104 target_ulong sc_mach
;
3105 target_ulong sc_macl
;
3108 target_ulong sc_fpregs
[16];
3109 target_ulong sc_xfpregs
[16];
3110 unsigned int sc_fpscr
;
3111 unsigned int sc_fpul
;
3112 unsigned int sc_ownedfp
;
3115 struct target_sigframe
3117 struct target_sigcontext sc
;
3118 target_ulong extramask
[TARGET_NSIG_WORDS
-1];
3119 uint16_t retcode
[3];
3123 struct target_ucontext
{
3124 target_ulong tuc_flags
;
3125 struct target_ucontext
*tuc_link
;
3126 target_stack_t tuc_stack
;
3127 struct target_sigcontext tuc_mcontext
;
3128 target_sigset_t tuc_sigmask
; /* mask last for extensibility */
3131 struct target_rt_sigframe
3133 struct target_siginfo info
;
3134 struct target_ucontext uc
;
3135 uint16_t retcode
[3];
3139 #define MOVW(n) (0x9300|((n)-2)) /* Move mem word at PC+n to R3 */
3140 #define TRAP_NOARG 0xc310 /* Syscall w/no args (NR in R3) SH3/4 */
3142 static abi_ulong
get_sigframe(struct target_sigaction
*ka
,
3143 unsigned long sp
, size_t frame_size
)
3145 if ((ka
->sa_flags
& TARGET_SA_ONSTACK
) && (sas_ss_flags(sp
) == 0)) {
3146 sp
= target_sigaltstack_used
.ss_sp
+ target_sigaltstack_used
.ss_size
;
3149 return (sp
- frame_size
) & -8ul;
3152 static void setup_sigcontext(struct target_sigcontext
*sc
,
3153 CPUSH4State
*regs
, unsigned long mask
)
3157 #define COPY(x) __put_user(regs->x, &sc->sc_##x)
3158 COPY(gregs
[0]); COPY(gregs
[1]);
3159 COPY(gregs
[2]); COPY(gregs
[3]);
3160 COPY(gregs
[4]); COPY(gregs
[5]);
3161 COPY(gregs
[6]); COPY(gregs
[7]);
3162 COPY(gregs
[8]); COPY(gregs
[9]);
3163 COPY(gregs
[10]); COPY(gregs
[11]);
3164 COPY(gregs
[12]); COPY(gregs
[13]);
3165 COPY(gregs
[14]); COPY(gregs
[15]);
3166 COPY(gbr
); COPY(mach
);
3167 COPY(macl
); COPY(pr
);
3171 for (i
=0; i
<16; i
++) {
3172 __put_user(regs
->fregs
[i
], &sc
->sc_fpregs
[i
]);
3174 __put_user(regs
->fpscr
, &sc
->sc_fpscr
);
3175 __put_user(regs
->fpul
, &sc
->sc_fpul
);
3177 /* non-iBCS2 extensions.. */
3178 __put_user(mask
, &sc
->oldmask
);
3181 static void restore_sigcontext(CPUSH4State
*regs
, struct target_sigcontext
*sc
,
3186 #define COPY(x) __get_user(regs->x, &sc->sc_##x)
3188 COPY(gregs
[2]); COPY(gregs
[3]);
3189 COPY(gregs
[4]); COPY(gregs
[5]);
3190 COPY(gregs
[6]); COPY(gregs
[7]);
3191 COPY(gregs
[8]); COPY(gregs
[9]);
3192 COPY(gregs
[10]); COPY(gregs
[11]);
3193 COPY(gregs
[12]); COPY(gregs
[13]);
3194 COPY(gregs
[14]); COPY(gregs
[15]);
3195 COPY(gbr
); COPY(mach
);
3196 COPY(macl
); COPY(pr
);
3200 for (i
=0; i
<16; i
++) {
3201 __get_user(regs
->fregs
[i
], &sc
->sc_fpregs
[i
]);
3203 __get_user(regs
->fpscr
, &sc
->sc_fpscr
);
3204 __get_user(regs
->fpul
, &sc
->sc_fpul
);
3206 regs
->tra
= -1; /* disable syscall checks */
3207 __get_user(*r0_p
, &sc
->sc_gregs
[0]);
3210 static void setup_frame(int sig
, struct target_sigaction
*ka
,
3211 target_sigset_t
*set
, CPUSH4State
*regs
)
3213 struct target_sigframe
*frame
;
3214 abi_ulong frame_addr
;
3218 frame_addr
= get_sigframe(ka
, regs
->gregs
[15], sizeof(*frame
));
3219 if (!lock_user_struct(VERIFY_WRITE
, frame
, frame_addr
, 0))
3222 setup_sigcontext(&frame
->sc
, regs
, set
->sig
[0]);
3224 for (i
= 0; i
< TARGET_NSIG_WORDS
- 1; i
++) {
3225 __put_user(set
->sig
[i
+ 1], &frame
->extramask
[i
]);
3228 /* Set up to return from userspace. If provided, use a stub
3229 already in userspace. */
3230 if (ka
->sa_flags
& TARGET_SA_RESTORER
) {
3231 regs
->pr
= (unsigned long) ka
->sa_restorer
;
3233 /* Generate return code (system call to sigreturn) */
3234 __put_user(MOVW(2), &frame
->retcode
[0]);
3235 __put_user(TRAP_NOARG
, &frame
->retcode
[1]);
3236 __put_user((TARGET_NR_sigreturn
), &frame
->retcode
[2]);
3237 regs
->pr
= (unsigned long) frame
->retcode
;
3243 /* Set up registers for signal handler */
3244 regs
->gregs
[15] = frame_addr
;
3245 regs
->gregs
[4] = sig
; /* Arg for signal handler */
3247 regs
->gregs
[6] = frame_addr
+= offsetof(typeof(*frame
), sc
);
3248 regs
->pc
= (unsigned long) ka
->_sa_handler
;
3250 unlock_user_struct(frame
, frame_addr
, 1);
3254 unlock_user_struct(frame
, frame_addr
, 1);
3255 force_sig(TARGET_SIGSEGV
);
3258 static void setup_rt_frame(int sig
, struct target_sigaction
*ka
,
3259 target_siginfo_t
*info
,
3260 target_sigset_t
*set
, CPUSH4State
*regs
)
3262 struct target_rt_sigframe
*frame
;
3263 abi_ulong frame_addr
;
3267 frame_addr
= get_sigframe(ka
, regs
->gregs
[15], sizeof(*frame
));
3268 if (!lock_user_struct(VERIFY_WRITE
, frame
, frame_addr
, 0))
3271 tswap_siginfo(&frame
->info
, info
);
3273 /* Create the ucontext. */
3274 __put_user(0, &frame
->uc
.tuc_flags
);
3275 __put_user(0, (unsigned long *)&frame
->uc
.tuc_link
);
3276 __put_user((unsigned long)target_sigaltstack_used
.ss_sp
,
3277 &frame
->uc
.tuc_stack
.ss_sp
);
3278 __put_user(sas_ss_flags(regs
->gregs
[15]),
3279 &frame
->uc
.tuc_stack
.ss_flags
);
3280 __put_user(target_sigaltstack_used
.ss_size
,
3281 &frame
->uc
.tuc_stack
.ss_size
);
3282 setup_sigcontext(&frame
->uc
.tuc_mcontext
,
3284 for(i
= 0; i
< TARGET_NSIG_WORDS
; i
++) {
3285 __put_user(set
->sig
[i
], &frame
->uc
.tuc_sigmask
.sig
[i
]);
3288 /* Set up to return from userspace. If provided, use a stub
3289 already in userspace. */
3290 if (ka
->sa_flags
& TARGET_SA_RESTORER
) {
3291 regs
->pr
= (unsigned long) ka
->sa_restorer
;
3293 /* Generate return code (system call to sigreturn) */
3294 __put_user(MOVW(2), &frame
->retcode
[0]);
3295 __put_user(TRAP_NOARG
, &frame
->retcode
[1]);
3296 __put_user((TARGET_NR_rt_sigreturn
), &frame
->retcode
[2]);
3297 regs
->pr
= (unsigned long) frame
->retcode
;
3303 /* Set up registers for signal handler */
3304 regs
->gregs
[15] = frame_addr
;
3305 regs
->gregs
[4] = sig
; /* Arg for signal handler */
3306 regs
->gregs
[5] = frame_addr
+ offsetof(typeof(*frame
), info
);
3307 regs
->gregs
[6] = frame_addr
+ offsetof(typeof(*frame
), uc
);
3308 regs
->pc
= (unsigned long) ka
->_sa_handler
;
3310 unlock_user_struct(frame
, frame_addr
, 1);
3314 unlock_user_struct(frame
, frame_addr
, 1);
3315 force_sig(TARGET_SIGSEGV
);
3318 long do_sigreturn(CPUSH4State
*regs
)
3320 struct target_sigframe
*frame
;
3321 abi_ulong frame_addr
;
3323 target_sigset_t target_set
;
3328 #if defined(DEBUG_SIGNAL)
3329 fprintf(stderr
, "do_sigreturn\n");
3331 frame_addr
= regs
->gregs
[15];
3332 if (!lock_user_struct(VERIFY_READ
, frame
, frame_addr
, 1))
3335 __get_user(target_set
.sig
[0], &frame
->sc
.oldmask
);
3336 for(i
= 1; i
< TARGET_NSIG_WORDS
; i
++) {
3337 __get_user(target_set
.sig
[i
], &frame
->extramask
[i
- 1]);
3343 target_to_host_sigset_internal(&blocked
, &target_set
);
3344 do_sigprocmask(SIG_SETMASK
, &blocked
, NULL
);
3346 restore_sigcontext(regs
, &frame
->sc
, &r0
);
3348 unlock_user_struct(frame
, frame_addr
, 0);
3352 unlock_user_struct(frame
, frame_addr
, 0);
3353 force_sig(TARGET_SIGSEGV
);
3357 long do_rt_sigreturn(CPUSH4State
*regs
)
3359 struct target_rt_sigframe
*frame
;
3360 abi_ulong frame_addr
;
3364 #if defined(DEBUG_SIGNAL)
3365 fprintf(stderr
, "do_rt_sigreturn\n");
3367 frame_addr
= regs
->gregs
[15];
3368 if (!lock_user_struct(VERIFY_READ
, frame
, frame_addr
, 1))
3371 target_to_host_sigset(&blocked
, &frame
->uc
.tuc_sigmask
);
3372 do_sigprocmask(SIG_SETMASK
, &blocked
, NULL
);
3374 restore_sigcontext(regs
, &frame
->uc
.tuc_mcontext
, &r0
);
3376 if (do_sigaltstack(frame_addr
+
3377 offsetof(struct target_rt_sigframe
, uc
.tuc_stack
),
3378 0, get_sp_from_cpustate(regs
)) == -EFAULT
)
3381 unlock_user_struct(frame
, frame_addr
, 0);
3385 unlock_user_struct(frame
, frame_addr
, 0);
3386 force_sig(TARGET_SIGSEGV
);
3389 #elif defined(TARGET_MICROBLAZE)
3391 struct target_sigcontext
{
3392 struct target_pt_regs regs
; /* needs to be first */
3396 struct target_stack_t
{
3399 unsigned int ss_size
;
3402 struct target_ucontext
{
3403 abi_ulong tuc_flags
;
3405 struct target_stack_t tuc_stack
;
3406 struct target_sigcontext tuc_mcontext
;
3407 uint32_t tuc_extramask
[TARGET_NSIG_WORDS
- 1];
3410 /* Signal frames. */
3411 struct target_signal_frame
{
3412 struct target_ucontext uc
;
3413 uint32_t extramask
[TARGET_NSIG_WORDS
- 1];
3417 struct rt_signal_frame
{
3423 static void setup_sigcontext(struct target_sigcontext
*sc
, CPUMBState
*env
)
3425 __put_user(env
->regs
[0], &sc
->regs
.r0
);
3426 __put_user(env
->regs
[1], &sc
->regs
.r1
);
3427 __put_user(env
->regs
[2], &sc
->regs
.r2
);
3428 __put_user(env
->regs
[3], &sc
->regs
.r3
);
3429 __put_user(env
->regs
[4], &sc
->regs
.r4
);
3430 __put_user(env
->regs
[5], &sc
->regs
.r5
);
3431 __put_user(env
->regs
[6], &sc
->regs
.r6
);
3432 __put_user(env
->regs
[7], &sc
->regs
.r7
);
3433 __put_user(env
->regs
[8], &sc
->regs
.r8
);
3434 __put_user(env
->regs
[9], &sc
->regs
.r9
);
3435 __put_user(env
->regs
[10], &sc
->regs
.r10
);
3436 __put_user(env
->regs
[11], &sc
->regs
.r11
);
3437 __put_user(env
->regs
[12], &sc
->regs
.r12
);
3438 __put_user(env
->regs
[13], &sc
->regs
.r13
);
3439 __put_user(env
->regs
[14], &sc
->regs
.r14
);
3440 __put_user(env
->regs
[15], &sc
->regs
.r15
);
3441 __put_user(env
->regs
[16], &sc
->regs
.r16
);
3442 __put_user(env
->regs
[17], &sc
->regs
.r17
);
3443 __put_user(env
->regs
[18], &sc
->regs
.r18
);
3444 __put_user(env
->regs
[19], &sc
->regs
.r19
);
3445 __put_user(env
->regs
[20], &sc
->regs
.r20
);
3446 __put_user(env
->regs
[21], &sc
->regs
.r21
);
3447 __put_user(env
->regs
[22], &sc
->regs
.r22
);
3448 __put_user(env
->regs
[23], &sc
->regs
.r23
);
3449 __put_user(env
->regs
[24], &sc
->regs
.r24
);
3450 __put_user(env
->regs
[25], &sc
->regs
.r25
);
3451 __put_user(env
->regs
[26], &sc
->regs
.r26
);
3452 __put_user(env
->regs
[27], &sc
->regs
.r27
);
3453 __put_user(env
->regs
[28], &sc
->regs
.r28
);
3454 __put_user(env
->regs
[29], &sc
->regs
.r29
);
3455 __put_user(env
->regs
[30], &sc
->regs
.r30
);
3456 __put_user(env
->regs
[31], &sc
->regs
.r31
);
3457 __put_user(env
->sregs
[SR_PC
], &sc
->regs
.pc
);
3460 static void restore_sigcontext(struct target_sigcontext
*sc
, CPUMBState
*env
)
3462 __get_user(env
->regs
[0], &sc
->regs
.r0
);
3463 __get_user(env
->regs
[1], &sc
->regs
.r1
);
3464 __get_user(env
->regs
[2], &sc
->regs
.r2
);
3465 __get_user(env
->regs
[3], &sc
->regs
.r3
);
3466 __get_user(env
->regs
[4], &sc
->regs
.r4
);
3467 __get_user(env
->regs
[5], &sc
->regs
.r5
);
3468 __get_user(env
->regs
[6], &sc
->regs
.r6
);
3469 __get_user(env
->regs
[7], &sc
->regs
.r7
);
3470 __get_user(env
->regs
[8], &sc
->regs
.r8
);
3471 __get_user(env
->regs
[9], &sc
->regs
.r9
);
3472 __get_user(env
->regs
[10], &sc
->regs
.r10
);
3473 __get_user(env
->regs
[11], &sc
->regs
.r11
);
3474 __get_user(env
->regs
[12], &sc
->regs
.r12
);
3475 __get_user(env
->regs
[13], &sc
->regs
.r13
);
3476 __get_user(env
->regs
[14], &sc
->regs
.r14
);
3477 __get_user(env
->regs
[15], &sc
->regs
.r15
);
3478 __get_user(env
->regs
[16], &sc
->regs
.r16
);
3479 __get_user(env
->regs
[17], &sc
->regs
.r17
);
3480 __get_user(env
->regs
[18], &sc
->regs
.r18
);
3481 __get_user(env
->regs
[19], &sc
->regs
.r19
);
3482 __get_user(env
->regs
[20], &sc
->regs
.r20
);
3483 __get_user(env
->regs
[21], &sc
->regs
.r21
);
3484 __get_user(env
->regs
[22], &sc
->regs
.r22
);
3485 __get_user(env
->regs
[23], &sc
->regs
.r23
);
3486 __get_user(env
->regs
[24], &sc
->regs
.r24
);
3487 __get_user(env
->regs
[25], &sc
->regs
.r25
);
3488 __get_user(env
->regs
[26], &sc
->regs
.r26
);
3489 __get_user(env
->regs
[27], &sc
->regs
.r27
);
3490 __get_user(env
->regs
[28], &sc
->regs
.r28
);
3491 __get_user(env
->regs
[29], &sc
->regs
.r29
);
3492 __get_user(env
->regs
[30], &sc
->regs
.r30
);
3493 __get_user(env
->regs
[31], &sc
->regs
.r31
);
3494 __get_user(env
->sregs
[SR_PC
], &sc
->regs
.pc
);
3497 static abi_ulong
get_sigframe(struct target_sigaction
*ka
,
3498 CPUMBState
*env
, int frame_size
)
3500 abi_ulong sp
= env
->regs
[1];
3502 if ((ka
->sa_flags
& TARGET_SA_ONSTACK
) != 0 && !on_sig_stack(sp
)) {
3503 sp
= target_sigaltstack_used
.ss_sp
+ target_sigaltstack_used
.ss_size
;
3506 return ((sp
- frame_size
) & -8UL);
3509 static void setup_frame(int sig
, struct target_sigaction
*ka
,
3510 target_sigset_t
*set
, CPUMBState
*env
)
3512 struct target_signal_frame
*frame
;
3513 abi_ulong frame_addr
;
3516 frame_addr
= get_sigframe(ka
, env
, sizeof *frame
);
3517 if (!lock_user_struct(VERIFY_WRITE
, frame
, frame_addr
, 0))
3520 /* Save the mask. */
3521 __put_user(set
->sig
[0], &frame
->uc
.tuc_mcontext
.oldmask
);
3523 for(i
= 1; i
< TARGET_NSIG_WORDS
; i
++) {
3524 __put_user(set
->sig
[i
], &frame
->extramask
[i
- 1]);
3527 setup_sigcontext(&frame
->uc
.tuc_mcontext
, env
);
3529 /* Set up to return from userspace. If provided, use a stub
3530 already in userspace. */
3531 /* minus 8 is offset to cater for "rtsd r15,8" offset */
3532 if (ka
->sa_flags
& TARGET_SA_RESTORER
) {
3533 env
->regs
[15] = ((unsigned long)ka
->sa_restorer
)-8;
3536 /* Note, these encodings are _big endian_! */
3537 /* addi r12, r0, __NR_sigreturn */
3538 t
= 0x31800000UL
| TARGET_NR_sigreturn
;
3539 __put_user(t
, frame
->tramp
+ 0);
3542 __put_user(t
, frame
->tramp
+ 1);
3544 /* Return from sighandler will jump to the tramp.
3545 Negative 8 offset because return is rtsd r15, 8 */
3546 env
->regs
[15] = ((unsigned long)frame
->tramp
) - 8;
3549 /* Set up registers for signal handler */
3550 env
->regs
[1] = frame_addr
;
3551 /* Signal handler args: */
3552 env
->regs
[5] = sig
; /* Arg 0: signum */
3554 /* arg 1: sigcontext */
3555 env
->regs
[7] = frame_addr
+= offsetof(typeof(*frame
), uc
);
3557 /* Offset of 4 to handle microblaze rtid r14, 0 */
3558 env
->sregs
[SR_PC
] = (unsigned long)ka
->_sa_handler
;
3560 unlock_user_struct(frame
, frame_addr
, 1);
3563 force_sig(TARGET_SIGSEGV
);
3566 static void setup_rt_frame(int sig
, struct target_sigaction
*ka
,
3567 target_siginfo_t
*info
,
3568 target_sigset_t
*set
, CPUMBState
*env
)
3570 fprintf(stderr
, "Microblaze setup_rt_frame: not implemented\n");
3573 long do_sigreturn(CPUMBState
*env
)
3575 struct target_signal_frame
*frame
;
3576 abi_ulong frame_addr
;
3577 target_sigset_t target_set
;
3581 frame_addr
= env
->regs
[R_SP
];
3582 /* Make sure the guest isn't playing games. */
3583 if (!lock_user_struct(VERIFY_WRITE
, frame
, frame_addr
, 1))
3586 /* Restore blocked signals */
3587 __get_user(target_set
.sig
[0], &frame
->uc
.tuc_mcontext
.oldmask
);
3588 for(i
= 1; i
< TARGET_NSIG_WORDS
; i
++) {
3589 __get_user(target_set
.sig
[i
], &frame
->extramask
[i
- 1]);
3591 target_to_host_sigset_internal(&set
, &target_set
);
3592 do_sigprocmask(SIG_SETMASK
, &set
, NULL
);
3594 restore_sigcontext(&frame
->uc
.tuc_mcontext
, env
);
3595 /* We got here through a sigreturn syscall, our path back is via an
3596 rtb insn so setup r14 for that. */
3597 env
->regs
[14] = env
->sregs
[SR_PC
];
3599 unlock_user_struct(frame
, frame_addr
, 0);
3600 return env
->regs
[10];
3602 force_sig(TARGET_SIGSEGV
);
3605 long do_rt_sigreturn(CPUMBState
*env
)
3607 fprintf(stderr
, "Microblaze do_rt_sigreturn: not implemented\n");
3608 return -TARGET_ENOSYS
;
3611 #elif defined(TARGET_CRIS)
3613 struct target_sigcontext
{
3614 struct target_pt_regs regs
; /* needs to be first */
3616 uint32_t usp
; /* usp before stacking this gunk on it */
3619 /* Signal frames. */
3620 struct target_signal_frame
{
3621 struct target_sigcontext sc
;
3622 uint32_t extramask
[TARGET_NSIG_WORDS
- 1];
3623 uint16_t retcode
[4]; /* Trampoline code. */
3626 struct rt_signal_frame
{
3631 uint16_t retcode
[4]; /* Trampoline code. */
3634 static void setup_sigcontext(struct target_sigcontext
*sc
, CPUCRISState
*env
)
3636 __put_user(env
->regs
[0], &sc
->regs
.r0
);
3637 __put_user(env
->regs
[1], &sc
->regs
.r1
);
3638 __put_user(env
->regs
[2], &sc
->regs
.r2
);
3639 __put_user(env
->regs
[3], &sc
->regs
.r3
);
3640 __put_user(env
->regs
[4], &sc
->regs
.r4
);
3641 __put_user(env
->regs
[5], &sc
->regs
.r5
);
3642 __put_user(env
->regs
[6], &sc
->regs
.r6
);
3643 __put_user(env
->regs
[7], &sc
->regs
.r7
);
3644 __put_user(env
->regs
[8], &sc
->regs
.r8
);
3645 __put_user(env
->regs
[9], &sc
->regs
.r9
);
3646 __put_user(env
->regs
[10], &sc
->regs
.r10
);
3647 __put_user(env
->regs
[11], &sc
->regs
.r11
);
3648 __put_user(env
->regs
[12], &sc
->regs
.r12
);
3649 __put_user(env
->regs
[13], &sc
->regs
.r13
);
3650 __put_user(env
->regs
[14], &sc
->usp
);
3651 __put_user(env
->regs
[15], &sc
->regs
.acr
);
3652 __put_user(env
->pregs
[PR_MOF
], &sc
->regs
.mof
);
3653 __put_user(env
->pregs
[PR_SRP
], &sc
->regs
.srp
);
3654 __put_user(env
->pc
, &sc
->regs
.erp
);
3657 static void restore_sigcontext(struct target_sigcontext
*sc
, CPUCRISState
*env
)
3659 __get_user(env
->regs
[0], &sc
->regs
.r0
);
3660 __get_user(env
->regs
[1], &sc
->regs
.r1
);
3661 __get_user(env
->regs
[2], &sc
->regs
.r2
);
3662 __get_user(env
->regs
[3], &sc
->regs
.r3
);
3663 __get_user(env
->regs
[4], &sc
->regs
.r4
);
3664 __get_user(env
->regs
[5], &sc
->regs
.r5
);
3665 __get_user(env
->regs
[6], &sc
->regs
.r6
);
3666 __get_user(env
->regs
[7], &sc
->regs
.r7
);
3667 __get_user(env
->regs
[8], &sc
->regs
.r8
);
3668 __get_user(env
->regs
[9], &sc
->regs
.r9
);
3669 __get_user(env
->regs
[10], &sc
->regs
.r10
);
3670 __get_user(env
->regs
[11], &sc
->regs
.r11
);
3671 __get_user(env
->regs
[12], &sc
->regs
.r12
);
3672 __get_user(env
->regs
[13], &sc
->regs
.r13
);
3673 __get_user(env
->regs
[14], &sc
->usp
);
3674 __get_user(env
->regs
[15], &sc
->regs
.acr
);
3675 __get_user(env
->pregs
[PR_MOF
], &sc
->regs
.mof
);
3676 __get_user(env
->pregs
[PR_SRP
], &sc
->regs
.srp
);
3677 __get_user(env
->pc
, &sc
->regs
.erp
);
3680 static abi_ulong
get_sigframe(CPUCRISState
*env
, int framesize
)
3683 /* Align the stack downwards to 4. */
3684 sp
= (env
->regs
[R_SP
] & ~3);
3685 return sp
- framesize
;
3688 static void setup_frame(int sig
, struct target_sigaction
*ka
,
3689 target_sigset_t
*set
, CPUCRISState
*env
)
3691 struct target_signal_frame
*frame
;
3692 abi_ulong frame_addr
;
3695 frame_addr
= get_sigframe(env
, sizeof *frame
);
3696 if (!lock_user_struct(VERIFY_WRITE
, frame
, frame_addr
, 0))
3700 * The CRIS signal return trampoline. A real linux/CRIS kernel doesn't
3701 * use this trampoline anymore but it sets it up for GDB.
3702 * In QEMU, using the trampoline simplifies things a bit so we use it.
3704 * This is movu.w __NR_sigreturn, r9; break 13;
3706 __put_user(0x9c5f, frame
->retcode
+0);
3707 __put_user(TARGET_NR_sigreturn
,
3708 frame
->retcode
+ 1);
3709 __put_user(0xe93d, frame
->retcode
+ 2);
3711 /* Save the mask. */
3712 __put_user(set
->sig
[0], &frame
->sc
.oldmask
);
3714 for(i
= 1; i
< TARGET_NSIG_WORDS
; i
++) {
3715 __put_user(set
->sig
[i
], &frame
->extramask
[i
- 1]);
3718 setup_sigcontext(&frame
->sc
, env
);
3720 /* Move the stack and setup the arguments for the handler. */
3721 env
->regs
[R_SP
] = frame_addr
;
3722 env
->regs
[10] = sig
;
3723 env
->pc
= (unsigned long) ka
->_sa_handler
;
3724 /* Link SRP so the guest returns through the trampoline. */
3725 env
->pregs
[PR_SRP
] = frame_addr
+ offsetof(typeof(*frame
), retcode
);
3727 unlock_user_struct(frame
, frame_addr
, 1);
3730 force_sig(TARGET_SIGSEGV
);
3733 static void setup_rt_frame(int sig
, struct target_sigaction
*ka
,
3734 target_siginfo_t
*info
,
3735 target_sigset_t
*set
, CPUCRISState
*env
)
3737 fprintf(stderr
, "CRIS setup_rt_frame: not implemented\n");
3740 long do_sigreturn(CPUCRISState
*env
)
3742 struct target_signal_frame
*frame
;
3743 abi_ulong frame_addr
;
3744 target_sigset_t target_set
;
3748 frame_addr
= env
->regs
[R_SP
];
3749 /* Make sure the guest isn't playing games. */
3750 if (!lock_user_struct(VERIFY_WRITE
, frame
, frame_addr
, 1))
3753 /* Restore blocked signals */
3754 __get_user(target_set
.sig
[0], &frame
->sc
.oldmask
);
3755 for(i
= 1; i
< TARGET_NSIG_WORDS
; i
++) {
3756 __get_user(target_set
.sig
[i
], &frame
->extramask
[i
- 1]);
3758 target_to_host_sigset_internal(&set
, &target_set
);
3759 do_sigprocmask(SIG_SETMASK
, &set
, NULL
);
3761 restore_sigcontext(&frame
->sc
, env
);
3762 unlock_user_struct(frame
, frame_addr
, 0);
3763 return env
->regs
[10];
3765 force_sig(TARGET_SIGSEGV
);
3768 long do_rt_sigreturn(CPUCRISState
*env
)
3770 fprintf(stderr
, "CRIS do_rt_sigreturn: not implemented\n");
3771 return -TARGET_ENOSYS
;
3774 #elif defined(TARGET_OPENRISC)
3776 struct target_sigcontext
{
3777 struct target_pt_regs regs
;
3782 struct target_ucontext
{
3783 abi_ulong tuc_flags
;
3785 target_stack_t tuc_stack
;
3786 struct target_sigcontext tuc_mcontext
;
3787 target_sigset_t tuc_sigmask
; /* mask last for extensibility */
3790 struct target_rt_sigframe
{
3793 struct target_siginfo info
;
3794 struct target_sigcontext sc
;
3795 struct target_ucontext uc
;
3796 unsigned char retcode
[16]; /* trampoline code */
3799 /* This is the asm-generic/ucontext.h version */
3801 static int restore_sigcontext(CPUOpenRISCState
*regs
,
3802 struct target_sigcontext
*sc
)
3804 unsigned int err
= 0;
3805 unsigned long old_usp
;
3807 /* Alwys make any pending restarted system call return -EINTR */
3808 current_thread_info()->restart_block
.fn
= do_no_restart_syscall
;
3810 /* restore the regs from &sc->regs (same as sc, since regs is first)
3811 * (sc is already checked for VERIFY_READ since the sigframe was
3812 * checked in sys_sigreturn previously)
3815 if (copy_from_user(regs
, &sc
, sizeof(struct target_pt_regs
))) {
3819 /* make sure the U-flag is set so user-mode cannot fool us */
3823 /* restore the old USP as it was before we stacked the sc etc.
3824 * (we cannot just pop the sigcontext since we aligned the sp and
3825 * stuff after pushing it)
3828 __get_user(old_usp
, &sc
->usp
);
3829 phx_signal("old_usp 0x%lx", old_usp
);
3831 __PHX__ REALLY
/* ??? */
3833 regs
->gpr
[1] = old_usp
;
3835 /* TODO: the other ports use regs->orig_XX to disable syscall checks
3836 * after this completes, but we don't use that mechanism. maybe we can
3847 /* Set up a signal frame. */
3849 static void setup_sigcontext(struct target_sigcontext
*sc
,
3850 CPUOpenRISCState
*regs
,
3853 unsigned long usp
= regs
->gpr
[1];
3855 /* copy the regs. they are first in sc so we can use sc directly */
3857 /*copy_to_user(&sc, regs, sizeof(struct target_pt_regs));*/
3859 /* Set the frametype to CRIS_FRAME_NORMAL for the execution of
3860 the signal handler. The frametype will be restored to its previous
3861 value in restore_sigcontext. */
3862 /*regs->frametype = CRIS_FRAME_NORMAL;*/
3864 /* then some other stuff */
3865 __put_user(mask
, &sc
->oldmask
);
3866 __put_user(usp
, &sc
->usp
);
3869 static inline unsigned long align_sigframe(unsigned long sp
)
3876 static inline abi_ulong
get_sigframe(struct target_sigaction
*ka
,
3877 CPUOpenRISCState
*regs
,
3880 unsigned long sp
= regs
->gpr
[1];
3881 int onsigstack
= on_sig_stack(sp
);
3884 /* This is the X/Open sanctioned signal stack switching. */
3885 if ((ka
->sa_flags
& TARGET_SA_ONSTACK
) != 0 && !onsigstack
) {
3886 sp
= target_sigaltstack_used
.ss_sp
+ target_sigaltstack_used
.ss_size
;
3889 sp
= align_sigframe(sp
- frame_size
);
3892 * If we are on the alternate signal stack and would overflow it, don't.
3893 * Return an always-bogus address instead so we will die with SIGSEGV.
3896 if (onsigstack
&& !likely(on_sig_stack(sp
))) {
3903 static void setup_frame(int sig
, struct target_sigaction
*ka
,
3904 target_sigset_t
*set
, CPUOpenRISCState
*env
)
3906 qemu_log("Not implement.\n");
3909 static void setup_rt_frame(int sig
, struct target_sigaction
*ka
,
3910 target_siginfo_t
*info
,
3911 target_sigset_t
*set
, CPUOpenRISCState
*env
)
3914 abi_ulong frame_addr
;
3915 unsigned long return_ip
;
3916 struct target_rt_sigframe
*frame
;
3917 abi_ulong info_addr
, uc_addr
;
3919 frame_addr
= get_sigframe(ka
, env
, sizeof(*frame
));
3920 if (!lock_user_struct(VERIFY_WRITE
, frame
, frame_addr
, 0)) {
3924 info_addr
= frame_addr
+ offsetof(struct target_rt_sigframe
, info
);
3925 __put_user(info_addr
, &frame
->pinfo
);
3926 uc_addr
= frame_addr
+ offsetof(struct target_rt_sigframe
, uc
);
3927 __put_user(uc_addr
, &frame
->puc
);
3929 if (ka
->sa_flags
& SA_SIGINFO
) {
3930 tswap_siginfo(&frame
->info
, info
);
3933 /*err |= __clear_user(&frame->uc, offsetof(struct ucontext, uc_mcontext));*/
3934 __put_user(0, &frame
->uc
.tuc_flags
);
3935 __put_user(0, &frame
->uc
.tuc_link
);
3936 __put_user(target_sigaltstack_used
.ss_sp
,
3937 &frame
->uc
.tuc_stack
.ss_sp
);
3938 __put_user(sas_ss_flags(env
->gpr
[1]), &frame
->uc
.tuc_stack
.ss_flags
);
3939 __put_user(target_sigaltstack_used
.ss_size
,
3940 &frame
->uc
.tuc_stack
.ss_size
);
3941 setup_sigcontext(&frame
->sc
, env
, set
->sig
[0]);
3943 /*err |= copy_to_user(frame->uc.tuc_sigmask, set, sizeof(*set));*/
3945 /* trampoline - the desired return ip is the retcode itself */
3946 return_ip
= (unsigned long)&frame
->retcode
;
3947 /* This is l.ori r11,r0,__NR_sigreturn, l.sys 1 */
3948 __put_user(0xa960, (short *)(frame
->retcode
+ 0));
3949 __put_user(TARGET_NR_rt_sigreturn
, (short *)(frame
->retcode
+ 2));
3950 __put_user(0x20000001, (unsigned long *)(frame
->retcode
+ 4));
3951 __put_user(0x15000000, (unsigned long *)(frame
->retcode
+ 8));
3957 /* TODO what is the current->exec_domain stuff and invmap ? */
3959 /* Set up registers for signal handler */
3960 env
->pc
= (unsigned long)ka
->_sa_handler
; /* what we enter NOW */
3961 env
->gpr
[9] = (unsigned long)return_ip
; /* what we enter LATER */
3962 env
->gpr
[3] = (unsigned long)sig
; /* arg 1: signo */
3963 env
->gpr
[4] = (unsigned long)&frame
->info
; /* arg 2: (siginfo_t*) */
3964 env
->gpr
[5] = (unsigned long)&frame
->uc
; /* arg 3: ucontext */
3966 /* actually move the usp to reflect the stacked frame */
3967 env
->gpr
[1] = (unsigned long)frame
;
3972 unlock_user_struct(frame
, frame_addr
, 1);
3973 if (sig
== TARGET_SIGSEGV
) {
3974 ka
->_sa_handler
= TARGET_SIG_DFL
;
3976 force_sig(TARGET_SIGSEGV
);
3979 long do_sigreturn(CPUOpenRISCState
*env
)
3982 qemu_log("do_sigreturn: not implemented\n");
3983 return -TARGET_ENOSYS
;
3986 long do_rt_sigreturn(CPUOpenRISCState
*env
)
3988 qemu_log("do_rt_sigreturn: not implemented\n");
3989 return -TARGET_ENOSYS
;
3991 /* TARGET_OPENRISC */
3993 #elif defined(TARGET_S390X)
3995 #define __NUM_GPRS 16
3996 #define __NUM_FPRS 16
3997 #define __NUM_ACRS 16
3999 #define S390_SYSCALL_SIZE 2
4000 #define __SIGNAL_FRAMESIZE 160 /* FIXME: 31-bit mode -> 96 */
4002 #define _SIGCONTEXT_NSIG 64
4003 #define _SIGCONTEXT_NSIG_BPW 64 /* FIXME: 31-bit mode -> 32 */
4004 #define _SIGCONTEXT_NSIG_WORDS (_SIGCONTEXT_NSIG / _SIGCONTEXT_NSIG_BPW)
4005 #define _SIGMASK_COPY_SIZE (sizeof(unsigned long)*_SIGCONTEXT_NSIG_WORDS)
4006 #define PSW_ADDR_AMODE 0x0000000000000000UL /* 0x80000000UL for 31-bit */
4007 #define S390_SYSCALL_OPCODE ((uint16_t)0x0a00)
4011 target_ulong gprs
[__NUM_GPRS
];
4012 unsigned int acrs
[__NUM_ACRS
];
4013 } target_s390_regs_common
;
4017 double fprs
[__NUM_FPRS
];
4018 } target_s390_fp_regs
;
4021 target_s390_regs_common regs
;
4022 target_s390_fp_regs fpregs
;
4025 struct target_sigcontext
{
4026 target_ulong oldmask
[_SIGCONTEXT_NSIG_WORDS
];
4027 target_sigregs
*sregs
;
4031 uint8_t callee_used_stack
[__SIGNAL_FRAMESIZE
];
4032 struct target_sigcontext sc
;
4033 target_sigregs sregs
;
4035 uint8_t retcode
[S390_SYSCALL_SIZE
];
4038 struct target_ucontext
{
4039 target_ulong tuc_flags
;
4040 struct target_ucontext
*tuc_link
;
4041 target_stack_t tuc_stack
;
4042 target_sigregs tuc_mcontext
;
4043 target_sigset_t tuc_sigmask
; /* mask last for extensibility */
4047 uint8_t callee_used_stack
[__SIGNAL_FRAMESIZE
];
4048 uint8_t retcode
[S390_SYSCALL_SIZE
];
4049 struct target_siginfo info
;
4050 struct target_ucontext uc
;
4053 static inline abi_ulong
4054 get_sigframe(struct target_sigaction
*ka
, CPUS390XState
*env
, size_t frame_size
)
4058 /* Default to using normal stack */
4061 /* This is the X/Open sanctioned signal stack switching. */
4062 if (ka
->sa_flags
& TARGET_SA_ONSTACK
) {
4063 if (!sas_ss_flags(sp
)) {
4064 sp
= target_sigaltstack_used
.ss_sp
+
4065 target_sigaltstack_used
.ss_size
;
4069 /* This is the legacy signal stack switching. */
4070 else if (/* FIXME !user_mode(regs) */ 0 &&
4071 !(ka
->sa_flags
& TARGET_SA_RESTORER
) &&
4073 sp
= (abi_ulong
) ka
->sa_restorer
;
4076 return (sp
- frame_size
) & -8ul;
4079 static void save_sigregs(CPUS390XState
*env
, target_sigregs
*sregs
)
4082 //save_access_regs(current->thread.acrs); FIXME
4084 /* Copy a 'clean' PSW mask to the user to avoid leaking
4085 information about whether PER is currently on. */
4086 __put_user(env
->psw
.mask
, &sregs
->regs
.psw
.mask
);
4087 __put_user(env
->psw
.addr
, &sregs
->regs
.psw
.addr
);
4088 for (i
= 0; i
< 16; i
++) {
4089 __put_user(env
->regs
[i
], &sregs
->regs
.gprs
[i
]);
4091 for (i
= 0; i
< 16; i
++) {
4092 __put_user(env
->aregs
[i
], &sregs
->regs
.acrs
[i
]);
4095 * We have to store the fp registers to current->thread.fp_regs
4096 * to merge them with the emulated registers.
4098 //save_fp_regs(¤t->thread.fp_regs); FIXME
4099 for (i
= 0; i
< 16; i
++) {
4100 __put_user(get_freg(env
, i
)->ll
, &sregs
->fpregs
.fprs
[i
]);
4104 static void setup_frame(int sig
, struct target_sigaction
*ka
,
4105 target_sigset_t
*set
, CPUS390XState
*env
)
4108 abi_ulong frame_addr
;
4110 frame_addr
= get_sigframe(ka
, env
, sizeof(*frame
));
4111 qemu_log("%s: frame_addr 0x%llx\n", __FUNCTION__
,
4112 (unsigned long long)frame_addr
);
4113 if (!lock_user_struct(VERIFY_WRITE
, frame
, frame_addr
, 0)) {
4117 qemu_log("%s: 1\n", __FUNCTION__
);
4118 __put_user(set
->sig
[0], &frame
->sc
.oldmask
[0]);
4120 save_sigregs(env
, &frame
->sregs
);
4122 __put_user((abi_ulong
)(unsigned long)&frame
->sregs
,
4123 (abi_ulong
*)&frame
->sc
.sregs
);
4125 /* Set up to return from userspace. If provided, use a stub
4126 already in userspace. */
4127 if (ka
->sa_flags
& TARGET_SA_RESTORER
) {
4128 env
->regs
[14] = (unsigned long)
4129 ka
->sa_restorer
| PSW_ADDR_AMODE
;
4131 env
->regs
[14] = (unsigned long)
4132 frame
->retcode
| PSW_ADDR_AMODE
;
4133 __put_user(S390_SYSCALL_OPCODE
| TARGET_NR_sigreturn
,
4134 (uint16_t *)(frame
->retcode
));
4137 /* Set up backchain. */
4138 __put_user(env
->regs
[15], (abi_ulong
*) frame
);
4140 /* Set up registers for signal handler */
4141 env
->regs
[15] = frame_addr
;
4142 env
->psw
.addr
= (target_ulong
) ka
->_sa_handler
| PSW_ADDR_AMODE
;
4144 env
->regs
[2] = sig
; //map_signal(sig);
4145 env
->regs
[3] = frame_addr
+= offsetof(typeof(*frame
), sc
);
4147 /* We forgot to include these in the sigcontext.
4148 To avoid breaking binary compatibility, they are passed as args. */
4149 env
->regs
[4] = 0; // FIXME: no clue... current->thread.trap_no;
4150 env
->regs
[5] = 0; // FIXME: no clue... current->thread.prot_addr;
4152 /* Place signal number on stack to allow backtrace from handler. */
4153 __put_user(env
->regs
[2], (int *) &frame
->signo
);
4154 unlock_user_struct(frame
, frame_addr
, 1);
4158 qemu_log("%s: give_sigsegv\n", __FUNCTION__
);
4159 force_sig(TARGET_SIGSEGV
);
4162 static void setup_rt_frame(int sig
, struct target_sigaction
*ka
,
4163 target_siginfo_t
*info
,
4164 target_sigset_t
*set
, CPUS390XState
*env
)
4168 abi_ulong frame_addr
;
4170 frame_addr
= get_sigframe(ka
, env
, sizeof *frame
);
4171 qemu_log("%s: frame_addr 0x%llx\n", __FUNCTION__
,
4172 (unsigned long long)frame_addr
);
4173 if (!lock_user_struct(VERIFY_WRITE
, frame
, frame_addr
, 0)) {
4177 qemu_log("%s: 1\n", __FUNCTION__
);
4178 tswap_siginfo(&frame
->info
, info
);
4180 /* Create the ucontext. */
4181 __put_user(0, &frame
->uc
.tuc_flags
);
4182 __put_user((abi_ulong
)0, (abi_ulong
*)&frame
->uc
.tuc_link
);
4183 __put_user(target_sigaltstack_used
.ss_sp
, &frame
->uc
.tuc_stack
.ss_sp
);
4184 __put_user(sas_ss_flags(get_sp_from_cpustate(env
)),
4185 &frame
->uc
.tuc_stack
.ss_flags
);
4186 __put_user(target_sigaltstack_used
.ss_size
, &frame
->uc
.tuc_stack
.ss_size
);
4187 save_sigregs(env
, &frame
->uc
.tuc_mcontext
);
4188 for (i
= 0; i
< TARGET_NSIG_WORDS
; i
++) {
4189 __put_user((abi_ulong
)set
->sig
[i
],
4190 (abi_ulong
*)&frame
->uc
.tuc_sigmask
.sig
[i
]);
4193 /* Set up to return from userspace. If provided, use a stub
4194 already in userspace. */
4195 if (ka
->sa_flags
& TARGET_SA_RESTORER
) {
4196 env
->regs
[14] = (unsigned long) ka
->sa_restorer
| PSW_ADDR_AMODE
;
4198 env
->regs
[14] = (unsigned long) frame
->retcode
| PSW_ADDR_AMODE
;
4199 __put_user(S390_SYSCALL_OPCODE
| TARGET_NR_rt_sigreturn
,
4200 (uint16_t *)(frame
->retcode
));
4203 /* Set up backchain. */
4204 __put_user(env
->regs
[15], (abi_ulong
*) frame
);
4206 /* Set up registers for signal handler */
4207 env
->regs
[15] = frame_addr
;
4208 env
->psw
.addr
= (target_ulong
) ka
->_sa_handler
| PSW_ADDR_AMODE
;
4210 env
->regs
[2] = sig
; //map_signal(sig);
4211 env
->regs
[3] = frame_addr
+ offsetof(typeof(*frame
), info
);
4212 env
->regs
[4] = frame_addr
+ offsetof(typeof(*frame
), uc
);
4216 qemu_log("%s: give_sigsegv\n", __FUNCTION__
);
4217 force_sig(TARGET_SIGSEGV
);
4221 restore_sigregs(CPUS390XState
*env
, target_sigregs
*sc
)
4226 for (i
= 0; i
< 16; i
++) {
4227 __get_user(env
->regs
[i
], &sc
->regs
.gprs
[i
]);
4230 __get_user(env
->psw
.mask
, &sc
->regs
.psw
.mask
);
4231 qemu_log("%s: sc->regs.psw.addr 0x%llx env->psw.addr 0x%llx\n",
4232 __FUNCTION__
, (unsigned long long)sc
->regs
.psw
.addr
,
4233 (unsigned long long)env
->psw
.addr
);
4234 __get_user(env
->psw
.addr
, &sc
->regs
.psw
.addr
);
4235 /* FIXME: 31-bit -> | PSW_ADDR_AMODE */
4237 for (i
= 0; i
< 16; i
++) {
4238 __get_user(env
->aregs
[i
], &sc
->regs
.acrs
[i
]);
4240 for (i
= 0; i
< 16; i
++) {
4241 __get_user(get_freg(env
, i
)->ll
, &sc
->fpregs
.fprs
[i
]);
4247 long do_sigreturn(CPUS390XState
*env
)
4250 abi_ulong frame_addr
= env
->regs
[15];
4251 qemu_log("%s: frame_addr 0x%llx\n", __FUNCTION__
,
4252 (unsigned long long)frame_addr
);
4253 target_sigset_t target_set
;
4256 if (!lock_user_struct(VERIFY_READ
, frame
, frame_addr
, 1)) {
4259 __get_user(target_set
.sig
[0], &frame
->sc
.oldmask
[0]);
4261 target_to_host_sigset_internal(&set
, &target_set
);
4262 do_sigprocmask(SIG_SETMASK
, &set
, NULL
); /* ~_BLOCKABLE? */
4264 if (restore_sigregs(env
, &frame
->sregs
)) {
4268 unlock_user_struct(frame
, frame_addr
, 0);
4269 return env
->regs
[2];
4272 force_sig(TARGET_SIGSEGV
);
4276 long do_rt_sigreturn(CPUS390XState
*env
)
4279 abi_ulong frame_addr
= env
->regs
[15];
4280 qemu_log("%s: frame_addr 0x%llx\n", __FUNCTION__
,
4281 (unsigned long long)frame_addr
);
4284 if (!lock_user_struct(VERIFY_READ
, frame
, frame_addr
, 1)) {
4287 target_to_host_sigset(&set
, &frame
->uc
.tuc_sigmask
);
4289 do_sigprocmask(SIG_SETMASK
, &set
, NULL
); /* ~_BLOCKABLE? */
4291 if (restore_sigregs(env
, &frame
->uc
.tuc_mcontext
)) {
4295 if (do_sigaltstack(frame_addr
+ offsetof(rt_sigframe
, uc
.tuc_stack
), 0,
4296 get_sp_from_cpustate(env
)) == -EFAULT
) {
4299 unlock_user_struct(frame
, frame_addr
, 0);
4300 return env
->regs
[2];
4303 unlock_user_struct(frame
, frame_addr
, 0);
4304 force_sig(TARGET_SIGSEGV
);
4308 #elif defined(TARGET_PPC)
4310 /* Size of dummy stack frame allocated when calling signal handler.
4311 See arch/powerpc/include/asm/ptrace.h. */
4312 #if defined(TARGET_PPC64)
4313 #define SIGNAL_FRAMESIZE 128
4315 #define SIGNAL_FRAMESIZE 64
4318 /* See arch/powerpc/include/asm/ucontext.h. Only used for 32-bit PPC;
4319 on 64-bit PPC, sigcontext and mcontext are one and the same. */
4320 struct target_mcontext
{
4321 target_ulong mc_gregs
[48];
4322 /* Includes fpscr. */
4323 uint64_t mc_fregs
[33];
4324 target_ulong mc_pad
[2];
4325 /* We need to handle Altivec and SPE at the same time, which no
4326 kernel needs to do. Fortunately, the kernel defines this bit to
4327 be Altivec-register-large all the time, rather than trying to
4328 twiddle it based on the specific platform. */
4330 /* SPE vector registers. One extra for SPEFSCR. */
4332 /* Altivec vector registers. The packing of VSCR and VRSAVE
4333 varies depending on whether we're PPC64 or not: PPC64 splits
4334 them apart; PPC32 stuffs them together. */
4335 #if defined(TARGET_PPC64)
4336 #define QEMU_NVRREG 34
4338 #define QEMU_NVRREG 33
4340 ppc_avr_t altivec
[QEMU_NVRREG
];
4342 } mc_vregs
__attribute__((__aligned__(16)));
4345 /* See arch/powerpc/include/asm/sigcontext.h. */
4346 struct target_sigcontext
{
4347 target_ulong _unused
[4];
4349 #if defined(TARGET_PPC64)
4352 target_ulong handler
;
4353 target_ulong oldmask
;
4354 target_ulong regs
; /* struct pt_regs __user * */
4355 #if defined(TARGET_PPC64)
4356 struct target_mcontext mcontext
;
4360 /* Indices for target_mcontext.mc_gregs, below.
4361 See arch/powerpc/include/asm/ptrace.h for details. */
4397 TARGET_PT_ORIG_R3
= 34,
4402 /* Yes, there are two registers with #39. One is 64-bit only. */
4404 TARGET_PT_SOFTE
= 39,
4405 TARGET_PT_TRAP
= 40,
4407 TARGET_PT_DSISR
= 42,
4408 TARGET_PT_RESULT
= 43,
4409 TARGET_PT_REGS_COUNT
= 44
4413 struct target_ucontext
{
4414 target_ulong tuc_flags
;
4415 target_ulong tuc_link
; /* struct ucontext __user * */
4416 struct target_sigaltstack tuc_stack
;
4417 #if !defined(TARGET_PPC64)
4419 target_ulong tuc_regs
; /* struct mcontext __user *
4420 points to uc_mcontext field */
4422 target_sigset_t tuc_sigmask
;
4423 #if defined(TARGET_PPC64)
4424 target_sigset_t unused
[15]; /* Allow for uc_sigmask growth */
4425 struct target_sigcontext tuc_sigcontext
;
4427 int32_t tuc_maskext
[30];
4428 int32_t tuc_pad2
[3];
4429 struct target_mcontext tuc_mcontext
;
4433 /* See arch/powerpc/kernel/signal_32.c. */
4434 struct target_sigframe
{
4435 struct target_sigcontext sctx
;
4436 struct target_mcontext mctx
;
4440 #if defined(TARGET_PPC64)
4442 #define TARGET_TRAMP_SIZE 6
4444 struct target_rt_sigframe
{
4445 /* sys_rt_sigreturn requires the ucontext be the first field */
4446 struct target_ucontext uc
;
4447 target_ulong _unused
[2];
4448 uint32_t trampoline
[TARGET_TRAMP_SIZE
];
4449 target_ulong pinfo
; /* struct siginfo __user * */
4450 target_ulong puc
; /* void __user * */
4451 struct target_siginfo info
;
4452 /* 64 bit ABI allows for 288 bytes below sp before decrementing it. */
4454 } __attribute__((aligned(16)));
4458 struct target_rt_sigframe
{
4459 struct target_siginfo info
;
4460 struct target_ucontext uc
;
4466 #if defined(TARGET_PPC64)
4468 struct target_func_ptr
{
4475 /* We use the mc_pad field for the signal return trampoline. */
4476 #define tramp mc_pad
4478 /* See arch/powerpc/kernel/signal.c. */
4479 static target_ulong
get_sigframe(struct target_sigaction
*ka
,
4483 target_ulong oldsp
, newsp
;
4485 oldsp
= env
->gpr
[1];
4487 if ((ka
->sa_flags
& TARGET_SA_ONSTACK
) &&
4488 (sas_ss_flags(oldsp
) == 0)) {
4489 oldsp
= (target_sigaltstack_used
.ss_sp
4490 + target_sigaltstack_used
.ss_size
);
4493 newsp
= (oldsp
- frame_size
) & ~0xFUL
;
4498 static void save_user_regs(CPUPPCState
*env
, struct target_mcontext
*frame
)
4500 target_ulong msr
= env
->msr
;
4502 target_ulong ccr
= 0;
4504 /* In general, the kernel attempts to be intelligent about what it
4505 needs to save for Altivec/FP/SPE registers. We don't care that
4506 much, so we just go ahead and save everything. */
4508 /* Save general registers. */
4509 for (i
= 0; i
< ARRAY_SIZE(env
->gpr
); i
++) {
4510 __put_user(env
->gpr
[i
], &frame
->mc_gregs
[i
]);
4512 __put_user(env
->nip
, &frame
->mc_gregs
[TARGET_PT_NIP
]);
4513 __put_user(env
->ctr
, &frame
->mc_gregs
[TARGET_PT_CTR
]);
4514 __put_user(env
->lr
, &frame
->mc_gregs
[TARGET_PT_LNK
]);
4515 __put_user(env
->xer
, &frame
->mc_gregs
[TARGET_PT_XER
]);
4517 for (i
= 0; i
< ARRAY_SIZE(env
->crf
); i
++) {
4518 ccr
|= env
->crf
[i
] << (32 - ((i
+ 1) * 4));
4520 __put_user(ccr
, &frame
->mc_gregs
[TARGET_PT_CCR
]);
4522 /* Save Altivec registers if necessary. */
4523 if (env
->insns_flags
& PPC_ALTIVEC
) {
4524 for (i
= 0; i
< ARRAY_SIZE(env
->avr
); i
++) {
4525 ppc_avr_t
*avr
= &env
->avr
[i
];
4526 ppc_avr_t
*vreg
= &frame
->mc_vregs
.altivec
[i
];
4528 __put_user(avr
->u64
[0], &vreg
->u64
[0]);
4529 __put_user(avr
->u64
[1], &vreg
->u64
[1]);
4531 /* Set MSR_VR in the saved MSR value to indicate that
4532 frame->mc_vregs contains valid data. */
4534 __put_user((uint32_t)env
->spr
[SPR_VRSAVE
],
4535 &frame
->mc_vregs
.altivec
[32].u32
[3]);
4538 /* Save floating point registers. */
4539 if (env
->insns_flags
& PPC_FLOAT
) {
4540 for (i
= 0; i
< ARRAY_SIZE(env
->fpr
); i
++) {
4541 __put_user(env
->fpr
[i
], &frame
->mc_fregs
[i
]);
4543 __put_user((uint64_t) env
->fpscr
, &frame
->mc_fregs
[32]);
4546 /* Save SPE registers. The kernel only saves the high half. */
4547 if (env
->insns_flags
& PPC_SPE
) {
4548 #if defined(TARGET_PPC64)
4549 for (i
= 0; i
< ARRAY_SIZE(env
->gpr
); i
++) {
4550 __put_user(env
->gpr
[i
] >> 32, &frame
->mc_vregs
.spe
[i
]);
4553 for (i
= 0; i
< ARRAY_SIZE(env
->gprh
); i
++) {
4554 __put_user(env
->gprh
[i
], &frame
->mc_vregs
.spe
[i
]);
4557 /* Set MSR_SPE in the saved MSR value to indicate that
4558 frame->mc_vregs contains valid data. */
4560 __put_user(env
->spe_fscr
, &frame
->mc_vregs
.spe
[32]);
4564 __put_user(msr
, &frame
->mc_gregs
[TARGET_PT_MSR
]);
4567 static void encode_trampoline(int sigret
, uint32_t *tramp
)
4569 /* Set up the sigreturn trampoline: li r0,sigret; sc. */
4571 __put_user(0x38000000 | sigret
, &tramp
[0]);
4572 __put_user(0x44000002, &tramp
[1]);
4576 static void restore_user_regs(CPUPPCState
*env
,
4577 struct target_mcontext
*frame
, int sig
)
4579 target_ulong save_r2
= 0;
4586 save_r2
= env
->gpr
[2];
4589 /* Restore general registers. */
4590 for (i
= 0; i
< ARRAY_SIZE(env
->gpr
); i
++) {
4591 __get_user(env
->gpr
[i
], &frame
->mc_gregs
[i
]);
4593 __get_user(env
->nip
, &frame
->mc_gregs
[TARGET_PT_NIP
]);
4594 __get_user(env
->ctr
, &frame
->mc_gregs
[TARGET_PT_CTR
]);
4595 __get_user(env
->lr
, &frame
->mc_gregs
[TARGET_PT_LNK
]);
4596 __get_user(env
->xer
, &frame
->mc_gregs
[TARGET_PT_XER
]);
4597 __get_user(ccr
, &frame
->mc_gregs
[TARGET_PT_CCR
]);
4599 for (i
= 0; i
< ARRAY_SIZE(env
->crf
); i
++) {
4600 env
->crf
[i
] = (ccr
>> (32 - ((i
+ 1) * 4))) & 0xf;
4604 env
->gpr
[2] = save_r2
;
4607 __get_user(msr
, &frame
->mc_gregs
[TARGET_PT_MSR
]);
4609 /* If doing signal return, restore the previous little-endian mode. */
4611 env
->msr
= (env
->msr
& ~MSR_LE
) | (msr
& MSR_LE
);
4613 /* Restore Altivec registers if necessary. */
4614 if (env
->insns_flags
& PPC_ALTIVEC
) {
4615 for (i
= 0; i
< ARRAY_SIZE(env
->avr
); i
++) {
4616 ppc_avr_t
*avr
= &env
->avr
[i
];
4617 ppc_avr_t
*vreg
= &frame
->mc_vregs
.altivec
[i
];
4619 __get_user(avr
->u64
[0], &vreg
->u64
[0]);
4620 __get_user(avr
->u64
[1], &vreg
->u64
[1]);
4622 /* Set MSR_VEC in the saved MSR value to indicate that
4623 frame->mc_vregs contains valid data. */
4624 __get_user(env
->spr
[SPR_VRSAVE
],
4625 (target_ulong
*)(&frame
->mc_vregs
.altivec
[32].u32
[3]));
4628 /* Restore floating point registers. */
4629 if (env
->insns_flags
& PPC_FLOAT
) {
4631 for (i
= 0; i
< ARRAY_SIZE(env
->fpr
); i
++) {
4632 __get_user(env
->fpr
[i
], &frame
->mc_fregs
[i
]);
4634 __get_user(fpscr
, &frame
->mc_fregs
[32]);
4635 env
->fpscr
= (uint32_t) fpscr
;
4638 /* Save SPE registers. The kernel only saves the high half. */
4639 if (env
->insns_flags
& PPC_SPE
) {
4640 #if defined(TARGET_PPC64)
4641 for (i
= 0; i
< ARRAY_SIZE(env
->gpr
); i
++) {
4644 __get_user(hi
, &frame
->mc_vregs
.spe
[i
]);
4645 env
->gpr
[i
] = ((uint64_t)hi
<< 32) | ((uint32_t) env
->gpr
[i
]);
4648 for (i
= 0; i
< ARRAY_SIZE(env
->gprh
); i
++) {
4649 __get_user(env
->gprh
[i
], &frame
->mc_vregs
.spe
[i
]);
4652 __get_user(env
->spe_fscr
, &frame
->mc_vregs
.spe
[32]);
4656 static void setup_frame(int sig
, struct target_sigaction
*ka
,
4657 target_sigset_t
*set
, CPUPPCState
*env
)
4659 struct target_sigframe
*frame
;
4660 struct target_sigcontext
*sc
;
4661 target_ulong frame_addr
, newsp
;
4663 #if defined(TARGET_PPC64)
4664 struct image_info
*image
= ((TaskState
*)thread_cpu
->opaque
)->info
;
4667 frame_addr
= get_sigframe(ka
, env
, sizeof(*frame
));
4668 if (!lock_user_struct(VERIFY_WRITE
, frame
, frame_addr
, 1))
4672 __put_user(ka
->_sa_handler
, &sc
->handler
);
4673 __put_user(set
->sig
[0], &sc
->oldmask
);
4674 #if TARGET_ABI_BITS == 64
4675 __put_user(set
->sig
[0] >> 32, &sc
->_unused
[3]);
4677 __put_user(set
->sig
[1], &sc
->_unused
[3]);
4679 __put_user(h2g(&frame
->mctx
), &sc
->regs
);
4680 __put_user(sig
, &sc
->signal
);
4682 /* Save user regs. */
4683 save_user_regs(env
, &frame
->mctx
);
4685 /* Construct the trampoline code on the stack. */
4686 encode_trampoline(TARGET_NR_sigreturn
, (uint32_t *)&frame
->mctx
.tramp
);
4688 /* The kernel checks for the presence of a VDSO here. We don't
4689 emulate a vdso, so use a sigreturn system call. */
4690 env
->lr
= (target_ulong
) h2g(frame
->mctx
.tramp
);
4692 /* Turn off all fp exceptions. */
4695 /* Create a stack frame for the caller of the handler. */
4696 newsp
= frame_addr
- SIGNAL_FRAMESIZE
;
4697 err
|= put_user(env
->gpr
[1], newsp
, target_ulong
);
4702 /* Set up registers for signal handler. */
4703 env
->gpr
[1] = newsp
;
4705 env
->gpr
[4] = frame_addr
+ offsetof(struct target_sigframe
, sctx
);
4707 #if defined(TARGET_PPC64)
4708 if (get_ppc64_abi(image
) < 2) {
4709 /* ELFv1 PPC64 function pointers are pointers to OPD entries. */
4710 struct target_func_ptr
*handler
=
4711 (struct target_func_ptr
*)g2h(ka
->_sa_handler
);
4712 env
->nip
= tswapl(handler
->entry
);
4713 env
->gpr
[2] = tswapl(handler
->toc
);
4715 /* ELFv2 PPC64 function pointers are entry points, but R12
4716 * must also be set */
4717 env
->nip
= tswapl((target_ulong
) ka
->_sa_handler
);
4718 env
->gpr
[12] = env
->nip
;
4721 env
->nip
= (target_ulong
) ka
->_sa_handler
;
4724 /* Signal handlers are entered in big-endian mode. */
4725 env
->msr
&= ~MSR_LE
;
4727 unlock_user_struct(frame
, frame_addr
, 1);
4731 unlock_user_struct(frame
, frame_addr
, 1);
4732 qemu_log("segfaulting from setup_frame\n");
4733 force_sig(TARGET_SIGSEGV
);
4736 static void setup_rt_frame(int sig
, struct target_sigaction
*ka
,
4737 target_siginfo_t
*info
,
4738 target_sigset_t
*set
, CPUPPCState
*env
)
4740 struct target_rt_sigframe
*rt_sf
;
4741 uint32_t *trampptr
= 0;
4742 struct target_mcontext
*mctx
= 0;
4743 target_ulong rt_sf_addr
, newsp
= 0;
4745 #if defined(TARGET_PPC64)
4746 struct image_info
*image
= ((TaskState
*)thread_cpu
->opaque
)->info
;
4749 rt_sf_addr
= get_sigframe(ka
, env
, sizeof(*rt_sf
));
4750 if (!lock_user_struct(VERIFY_WRITE
, rt_sf
, rt_sf_addr
, 1))
4753 tswap_siginfo(&rt_sf
->info
, info
);
4755 __put_user(0, &rt_sf
->uc
.tuc_flags
);
4756 __put_user(0, &rt_sf
->uc
.tuc_link
);
4757 __put_user((target_ulong
)target_sigaltstack_used
.ss_sp
,
4758 &rt_sf
->uc
.tuc_stack
.ss_sp
);
4759 __put_user(sas_ss_flags(env
->gpr
[1]),
4760 &rt_sf
->uc
.tuc_stack
.ss_flags
);
4761 __put_user(target_sigaltstack_used
.ss_size
,
4762 &rt_sf
->uc
.tuc_stack
.ss_size
);
4763 #if !defined(TARGET_PPC64)
4764 __put_user(h2g (&rt_sf
->uc
.tuc_mcontext
),
4765 &rt_sf
->uc
.tuc_regs
);
4767 for(i
= 0; i
< TARGET_NSIG_WORDS
; i
++) {
4768 __put_user(set
->sig
[i
], &rt_sf
->uc
.tuc_sigmask
.sig
[i
]);
4771 #if defined(TARGET_PPC64)
4772 mctx
= &rt_sf
->uc
.tuc_sigcontext
.mcontext
;
4773 trampptr
= &rt_sf
->trampoline
[0];
4775 mctx
= &rt_sf
->uc
.tuc_mcontext
;
4776 trampptr
= (uint32_t *)&rt_sf
->uc
.tuc_mcontext
.tramp
;
4779 save_user_regs(env
, mctx
);
4780 encode_trampoline(TARGET_NR_rt_sigreturn
, trampptr
);
4782 /* The kernel checks for the presence of a VDSO here. We don't
4783 emulate a vdso, so use a sigreturn system call. */
4784 env
->lr
= (target_ulong
) h2g(trampptr
);
4786 /* Turn off all fp exceptions. */
4789 /* Create a stack frame for the caller of the handler. */
4790 newsp
= rt_sf_addr
- (SIGNAL_FRAMESIZE
+ 16);
4791 err
|= put_user(env
->gpr
[1], newsp
, target_ulong
);
4796 /* Set up registers for signal handler. */
4797 env
->gpr
[1] = newsp
;
4798 env
->gpr
[3] = (target_ulong
) sig
;
4799 env
->gpr
[4] = (target_ulong
) h2g(&rt_sf
->info
);
4800 env
->gpr
[5] = (target_ulong
) h2g(&rt_sf
->uc
);
4801 env
->gpr
[6] = (target_ulong
) h2g(rt_sf
);
4803 #if defined(TARGET_PPC64)
4804 if (get_ppc64_abi(image
) < 2) {
4805 /* ELFv1 PPC64 function pointers are pointers to OPD entries. */
4806 struct target_func_ptr
*handler
=
4807 (struct target_func_ptr
*)g2h(ka
->_sa_handler
);
4808 env
->nip
= tswapl(handler
->entry
);
4809 env
->gpr
[2] = tswapl(handler
->toc
);
4811 /* ELFv2 PPC64 function pointers are entry points, but R12
4812 * must also be set */
4813 env
->nip
= tswapl((target_ulong
) ka
->_sa_handler
);
4814 env
->gpr
[12] = env
->nip
;
4817 env
->nip
= (target_ulong
) ka
->_sa_handler
;
4820 /* Signal handlers are entered in big-endian mode. */
4821 env
->msr
&= ~MSR_LE
;
4823 unlock_user_struct(rt_sf
, rt_sf_addr
, 1);
4827 unlock_user_struct(rt_sf
, rt_sf_addr
, 1);
4828 qemu_log("segfaulting from setup_rt_frame\n");
4829 force_sig(TARGET_SIGSEGV
);
4833 long do_sigreturn(CPUPPCState
*env
)
4835 struct target_sigcontext
*sc
= NULL
;
4836 struct target_mcontext
*sr
= NULL
;
4837 target_ulong sr_addr
= 0, sc_addr
;
4839 target_sigset_t set
;
4841 sc_addr
= env
->gpr
[1] + SIGNAL_FRAMESIZE
;
4842 if (!lock_user_struct(VERIFY_READ
, sc
, sc_addr
, 1))
4845 #if defined(TARGET_PPC64)
4846 set
.sig
[0] = sc
->oldmask
+ ((uint64_t)(sc
->_unused
[3]) << 32);
4848 __get_user(set
.sig
[0], &sc
->oldmask
);
4849 __get_user(set
.sig
[1], &sc
->_unused
[3]);
4851 target_to_host_sigset_internal(&blocked
, &set
);
4852 do_sigprocmask(SIG_SETMASK
, &blocked
, NULL
);
4854 __get_user(sr_addr
, &sc
->regs
);
4855 if (!lock_user_struct(VERIFY_READ
, sr
, sr_addr
, 1))
4857 restore_user_regs(env
, sr
, 1);
4859 unlock_user_struct(sr
, sr_addr
, 1);
4860 unlock_user_struct(sc
, sc_addr
, 1);
4861 return -TARGET_QEMU_ESIGRETURN
;
4864 unlock_user_struct(sr
, sr_addr
, 1);
4865 unlock_user_struct(sc
, sc_addr
, 1);
4866 qemu_log("segfaulting from do_sigreturn\n");
4867 force_sig(TARGET_SIGSEGV
);
4871 /* See arch/powerpc/kernel/signal_32.c. */
4872 static int do_setcontext(struct target_ucontext
*ucp
, CPUPPCState
*env
, int sig
)
4874 struct target_mcontext
*mcp
;
4875 target_ulong mcp_addr
;
4877 target_sigset_t set
;
4879 if (copy_from_user(&set
, h2g(ucp
) + offsetof(struct target_ucontext
, tuc_sigmask
),
4883 #if defined(TARGET_PPC64)
4884 mcp_addr
= h2g(ucp
) +
4885 offsetof(struct target_ucontext
, tuc_sigcontext
.mcontext
);
4887 __get_user(mcp_addr
, &ucp
->tuc_regs
);
4890 if (!lock_user_struct(VERIFY_READ
, mcp
, mcp_addr
, 1))
4893 target_to_host_sigset_internal(&blocked
, &set
);
4894 do_sigprocmask(SIG_SETMASK
, &blocked
, NULL
);
4895 restore_user_regs(env
, mcp
, sig
);
4897 unlock_user_struct(mcp
, mcp_addr
, 1);
4901 long do_rt_sigreturn(CPUPPCState
*env
)
4903 struct target_rt_sigframe
*rt_sf
= NULL
;
4904 target_ulong rt_sf_addr
;
4906 rt_sf_addr
= env
->gpr
[1] + SIGNAL_FRAMESIZE
+ 16;
4907 if (!lock_user_struct(VERIFY_READ
, rt_sf
, rt_sf_addr
, 1))
4910 if (do_setcontext(&rt_sf
->uc
, env
, 1))
4913 do_sigaltstack(rt_sf_addr
4914 + offsetof(struct target_rt_sigframe
, uc
.tuc_stack
),
4917 unlock_user_struct(rt_sf
, rt_sf_addr
, 1);
4918 return -TARGET_QEMU_ESIGRETURN
;
4921 unlock_user_struct(rt_sf
, rt_sf_addr
, 1);
4922 qemu_log("segfaulting from do_rt_sigreturn\n");
4923 force_sig(TARGET_SIGSEGV
);
4927 #elif defined(TARGET_M68K)
4929 struct target_sigcontext
{
4936 unsigned short sc_sr
;
4940 struct target_sigframe
4947 abi_ulong extramask
[TARGET_NSIG_WORDS
-1];
4948 struct target_sigcontext sc
;
4951 typedef int target_greg_t
;
4952 #define TARGET_NGREG 18
4953 typedef target_greg_t target_gregset_t
[TARGET_NGREG
];
4955 typedef struct target_fpregset
{
4958 } target_fpregset_t
;
4960 struct target_mcontext
{
4962 target_gregset_t gregs
;
4963 target_fpregset_t fpregs
;
4966 #define TARGET_MCONTEXT_VERSION 2
4968 struct target_ucontext
{
4969 abi_ulong tuc_flags
;
4971 target_stack_t tuc_stack
;
4972 struct target_mcontext tuc_mcontext
;
4973 abi_long tuc_filler
[80];
4974 target_sigset_t tuc_sigmask
;
4977 struct target_rt_sigframe
4984 struct target_siginfo info
;
4985 struct target_ucontext uc
;
4988 static void setup_sigcontext(struct target_sigcontext
*sc
, CPUM68KState
*env
,
4991 __put_user(mask
, &sc
->sc_mask
);
4992 __put_user(env
->aregs
[7], &sc
->sc_usp
);
4993 __put_user(env
->dregs
[0], &sc
->sc_d0
);
4994 __put_user(env
->dregs
[1], &sc
->sc_d1
);
4995 __put_user(env
->aregs
[0], &sc
->sc_a0
);
4996 __put_user(env
->aregs
[1], &sc
->sc_a1
);
4997 __put_user(env
->sr
, &sc
->sc_sr
);
4998 __put_user(env
->pc
, &sc
->sc_pc
);
5002 restore_sigcontext(CPUM68KState
*env
, struct target_sigcontext
*sc
, int *pd0
)
5006 __get_user(env
->aregs
[7], &sc
->sc_usp
);
5007 __get_user(env
->dregs
[1], &sc
->sc_d1
);
5008 __get_user(env
->aregs
[0], &sc
->sc_a0
);
5009 __get_user(env
->aregs
[1], &sc
->sc_a1
);
5010 __get_user(env
->pc
, &sc
->sc_pc
);
5011 __get_user(temp
, &sc
->sc_sr
);
5012 env
->sr
= (env
->sr
& 0xff00) | (temp
& 0xff);
5014 *pd0
= tswapl(sc
->sc_d0
);
5018 * Determine which stack to use..
5020 static inline abi_ulong
5021 get_sigframe(struct target_sigaction
*ka
, CPUM68KState
*regs
,
5026 sp
= regs
->aregs
[7];
5028 /* This is the X/Open sanctioned signal stack switching. */
5029 if ((ka
->sa_flags
& TARGET_SA_ONSTACK
) && (sas_ss_flags (sp
) == 0)) {
5030 sp
= target_sigaltstack_used
.ss_sp
+ target_sigaltstack_used
.ss_size
;
5033 return ((sp
- frame_size
) & -8UL);
5036 static void setup_frame(int sig
, struct target_sigaction
*ka
,
5037 target_sigset_t
*set
, CPUM68KState
*env
)
5039 struct target_sigframe
*frame
;
5040 abi_ulong frame_addr
;
5041 abi_ulong retcode_addr
;
5045 frame_addr
= get_sigframe(ka
, env
, sizeof *frame
);
5046 if (!lock_user_struct(VERIFY_WRITE
, frame
, frame_addr
, 0))
5049 __put_user(sig
, &frame
->sig
);
5051 sc_addr
= frame_addr
+ offsetof(struct target_sigframe
, sc
);
5052 __put_user(sc_addr
, &frame
->psc
);
5054 setup_sigcontext(&frame
->sc
, env
, set
->sig
[0]);
5056 for(i
= 1; i
< TARGET_NSIG_WORDS
; i
++) {
5057 __put_user(set
->sig
[i
], &frame
->extramask
[i
- 1]);
5060 /* Set up to return from userspace. */
5062 retcode_addr
= frame_addr
+ offsetof(struct target_sigframe
, retcode
);
5063 __put_user(retcode_addr
, &frame
->pretcode
);
5065 /* moveq #,d0; trap #0 */
5067 __put_user(0x70004e40 + (TARGET_NR_sigreturn
<< 16),
5068 (uint32_t *)(frame
->retcode
));
5070 /* Set up to return from userspace */
5072 env
->aregs
[7] = frame_addr
;
5073 env
->pc
= ka
->_sa_handler
;
5075 unlock_user_struct(frame
, frame_addr
, 1);
5079 force_sig(TARGET_SIGSEGV
);
5082 static inline int target_rt_setup_ucontext(struct target_ucontext
*uc
,
5085 target_greg_t
*gregs
= uc
->tuc_mcontext
.gregs
;
5087 __put_user(TARGET_MCONTEXT_VERSION
, &uc
->tuc_mcontext
.version
);
5088 __put_user(env
->dregs
[0], &gregs
[0]);
5089 __put_user(env
->dregs
[1], &gregs
[1]);
5090 __put_user(env
->dregs
[2], &gregs
[2]);
5091 __put_user(env
->dregs
[3], &gregs
[3]);
5092 __put_user(env
->dregs
[4], &gregs
[4]);
5093 __put_user(env
->dregs
[5], &gregs
[5]);
5094 __put_user(env
->dregs
[6], &gregs
[6]);
5095 __put_user(env
->dregs
[7], &gregs
[7]);
5096 __put_user(env
->aregs
[0], &gregs
[8]);
5097 __put_user(env
->aregs
[1], &gregs
[9]);
5098 __put_user(env
->aregs
[2], &gregs
[10]);
5099 __put_user(env
->aregs
[3], &gregs
[11]);
5100 __put_user(env
->aregs
[4], &gregs
[12]);
5101 __put_user(env
->aregs
[5], &gregs
[13]);
5102 __put_user(env
->aregs
[6], &gregs
[14]);
5103 __put_user(env
->aregs
[7], &gregs
[15]);
5104 __put_user(env
->pc
, &gregs
[16]);
5105 __put_user(env
->sr
, &gregs
[17]);
5110 static inline int target_rt_restore_ucontext(CPUM68KState
*env
,
5111 struct target_ucontext
*uc
,
5115 target_greg_t
*gregs
= uc
->tuc_mcontext
.gregs
;
5117 __get_user(temp
, &uc
->tuc_mcontext
.version
);
5118 if (temp
!= TARGET_MCONTEXT_VERSION
)
5121 /* restore passed registers */
5122 __get_user(env
->dregs
[0], &gregs
[0]);
5123 __get_user(env
->dregs
[1], &gregs
[1]);
5124 __get_user(env
->dregs
[2], &gregs
[2]);
5125 __get_user(env
->dregs
[3], &gregs
[3]);
5126 __get_user(env
->dregs
[4], &gregs
[4]);
5127 __get_user(env
->dregs
[5], &gregs
[5]);
5128 __get_user(env
->dregs
[6], &gregs
[6]);
5129 __get_user(env
->dregs
[7], &gregs
[7]);
5130 __get_user(env
->aregs
[0], &gregs
[8]);
5131 __get_user(env
->aregs
[1], &gregs
[9]);
5132 __get_user(env
->aregs
[2], &gregs
[10]);
5133 __get_user(env
->aregs
[3], &gregs
[11]);
5134 __get_user(env
->aregs
[4], &gregs
[12]);
5135 __get_user(env
->aregs
[5], &gregs
[13]);
5136 __get_user(env
->aregs
[6], &gregs
[14]);
5137 __get_user(env
->aregs
[7], &gregs
[15]);
5138 __get_user(env
->pc
, &gregs
[16]);
5139 __get_user(temp
, &gregs
[17]);
5140 env
->sr
= (env
->sr
& 0xff00) | (temp
& 0xff);
5142 *pd0
= env
->dregs
[0];
5149 static void setup_rt_frame(int sig
, struct target_sigaction
*ka
,
5150 target_siginfo_t
*info
,
5151 target_sigset_t
*set
, CPUM68KState
*env
)
5153 struct target_rt_sigframe
*frame
;
5154 abi_ulong frame_addr
;
5155 abi_ulong retcode_addr
;
5156 abi_ulong info_addr
;
5161 frame_addr
= get_sigframe(ka
, env
, sizeof *frame
);
5162 if (!lock_user_struct(VERIFY_WRITE
, frame
, frame_addr
, 0))
5165 __put_user(sig
, &frame
->sig
);
5167 info_addr
= frame_addr
+ offsetof(struct target_rt_sigframe
, info
);
5168 __put_user(info_addr
, &frame
->pinfo
);
5170 uc_addr
= frame_addr
+ offsetof(struct target_rt_sigframe
, uc
);
5171 __put_user(uc_addr
, &frame
->puc
);
5173 tswap_siginfo(&frame
->info
, info
);
5175 /* Create the ucontext */
5177 __put_user(0, &frame
->uc
.tuc_flags
);
5178 __put_user(0, &frame
->uc
.tuc_link
);
5179 __put_user(target_sigaltstack_used
.ss_sp
,
5180 &frame
->uc
.tuc_stack
.ss_sp
);
5181 __put_user(sas_ss_flags(env
->aregs
[7]),
5182 &frame
->uc
.tuc_stack
.ss_flags
);
5183 __put_user(target_sigaltstack_used
.ss_size
,
5184 &frame
->uc
.tuc_stack
.ss_size
);
5185 err
|= target_rt_setup_ucontext(&frame
->uc
, env
);
5190 for(i
= 0; i
< TARGET_NSIG_WORDS
; i
++) {
5191 __put_user(set
->sig
[i
], &frame
->uc
.tuc_sigmask
.sig
[i
]);
5194 /* Set up to return from userspace. */
5196 retcode_addr
= frame_addr
+ offsetof(struct target_sigframe
, retcode
);
5197 __put_user(retcode_addr
, &frame
->pretcode
);
5199 /* moveq #,d0; notb d0; trap #0 */
5201 __put_user(0x70004600 + ((TARGET_NR_rt_sigreturn
^ 0xff) << 16),
5202 (uint32_t *)(frame
->retcode
+ 0));
5203 __put_user(0x4e40, (uint16_t *)(frame
->retcode
+ 4));
5208 /* Set up to return from userspace */
5210 env
->aregs
[7] = frame_addr
;
5211 env
->pc
= ka
->_sa_handler
;
5213 unlock_user_struct(frame
, frame_addr
, 1);
5217 unlock_user_struct(frame
, frame_addr
, 1);
5218 force_sig(TARGET_SIGSEGV
);
5221 long do_sigreturn(CPUM68KState
*env
)
5223 struct target_sigframe
*frame
;
5224 abi_ulong frame_addr
= env
->aregs
[7] - 4;
5225 target_sigset_t target_set
;
5229 if (!lock_user_struct(VERIFY_READ
, frame
, frame_addr
, 1))
5232 /* set blocked signals */
5234 __get_user(target_set
.sig
[0], &frame
->sc
.sc_mask
);
5236 for(i
= 1; i
< TARGET_NSIG_WORDS
; i
++) {
5237 __get_user(target_set
.sig
[i
], &frame
->extramask
[i
- 1]);
5240 target_to_host_sigset_internal(&set
, &target_set
);
5241 do_sigprocmask(SIG_SETMASK
, &set
, NULL
);
5243 /* restore registers */
5245 restore_sigcontext(env
, &frame
->sc
, &d0
);
5247 unlock_user_struct(frame
, frame_addr
, 0);
5251 force_sig(TARGET_SIGSEGV
);
5255 long do_rt_sigreturn(CPUM68KState
*env
)
5257 struct target_rt_sigframe
*frame
;
5258 abi_ulong frame_addr
= env
->aregs
[7] - 4;
5259 target_sigset_t target_set
;
5263 if (!lock_user_struct(VERIFY_READ
, frame
, frame_addr
, 1))
5266 target_to_host_sigset_internal(&set
, &target_set
);
5267 do_sigprocmask(SIG_SETMASK
, &set
, NULL
);
5269 /* restore registers */
5271 if (target_rt_restore_ucontext(env
, &frame
->uc
, &d0
))
5274 if (do_sigaltstack(frame_addr
+
5275 offsetof(struct target_rt_sigframe
, uc
.tuc_stack
),
5276 0, get_sp_from_cpustate(env
)) == -EFAULT
)
5279 unlock_user_struct(frame
, frame_addr
, 0);
5283 unlock_user_struct(frame
, frame_addr
, 0);
5284 force_sig(TARGET_SIGSEGV
);
5288 #elif defined(TARGET_ALPHA)
5290 struct target_sigcontext
{
5291 abi_long sc_onstack
;
5295 abi_long sc_regs
[32];
5296 abi_long sc_ownedfp
;
5297 abi_long sc_fpregs
[32];
5299 abi_ulong sc_fp_control
;
5300 abi_ulong sc_reserved1
;
5301 abi_ulong sc_reserved2
;
5304 abi_ulong sc_traparg_a0
;
5305 abi_ulong sc_traparg_a1
;
5306 abi_ulong sc_traparg_a2
;
5307 abi_ulong sc_fp_trap_pc
;
5308 abi_ulong sc_fp_trigger_sum
;
5309 abi_ulong sc_fp_trigger_inst
;
5312 struct target_ucontext
{
5313 abi_ulong tuc_flags
;
5315 abi_ulong tuc_osf_sigmask
;
5316 target_stack_t tuc_stack
;
5317 struct target_sigcontext tuc_mcontext
;
5318 target_sigset_t tuc_sigmask
;
5321 struct target_sigframe
{
5322 struct target_sigcontext sc
;
5323 unsigned int retcode
[3];
5326 struct target_rt_sigframe
{
5327 target_siginfo_t info
;
5328 struct target_ucontext uc
;
5329 unsigned int retcode
[3];
5332 #define INSN_MOV_R30_R16 0x47fe0410
5333 #define INSN_LDI_R0 0x201f0000
5334 #define INSN_CALLSYS 0x00000083
5336 static void setup_sigcontext(struct target_sigcontext
*sc
, CPUAlphaState
*env
,
5337 abi_ulong frame_addr
, target_sigset_t
*set
)
5341 __put_user(on_sig_stack(frame_addr
), &sc
->sc_onstack
);
5342 __put_user(set
->sig
[0], &sc
->sc_mask
);
5343 __put_user(env
->pc
, &sc
->sc_pc
);
5344 __put_user(8, &sc
->sc_ps
);
5346 for (i
= 0; i
< 31; ++i
) {
5347 __put_user(env
->ir
[i
], &sc
->sc_regs
[i
]);
5349 __put_user(0, &sc
->sc_regs
[31]);
5351 for (i
= 0; i
< 31; ++i
) {
5352 __put_user(env
->fir
[i
], &sc
->sc_fpregs
[i
]);
5354 __put_user(0, &sc
->sc_fpregs
[31]);
5355 __put_user(cpu_alpha_load_fpcr(env
), &sc
->sc_fpcr
);
5357 __put_user(0, &sc
->sc_traparg_a0
); /* FIXME */
5358 __put_user(0, &sc
->sc_traparg_a1
); /* FIXME */
5359 __put_user(0, &sc
->sc_traparg_a2
); /* FIXME */
5362 static void restore_sigcontext(CPUAlphaState
*env
,
5363 struct target_sigcontext
*sc
)
5368 __get_user(env
->pc
, &sc
->sc_pc
);
5370 for (i
= 0; i
< 31; ++i
) {
5371 __get_user(env
->ir
[i
], &sc
->sc_regs
[i
]);
5373 for (i
= 0; i
< 31; ++i
) {
5374 __get_user(env
->fir
[i
], &sc
->sc_fpregs
[i
]);
5377 __get_user(fpcr
, &sc
->sc_fpcr
);
5378 cpu_alpha_store_fpcr(env
, fpcr
);
5381 static inline abi_ulong
get_sigframe(struct target_sigaction
*sa
,
5383 unsigned long framesize
)
5385 abi_ulong sp
= env
->ir
[IR_SP
];
5387 /* This is the X/Open sanctioned signal stack switching. */
5388 if ((sa
->sa_flags
& TARGET_SA_ONSTACK
) != 0 && !sas_ss_flags(sp
)) {
5389 sp
= target_sigaltstack_used
.ss_sp
+ target_sigaltstack_used
.ss_size
;
5391 return (sp
- framesize
) & -32;
5394 static void setup_frame(int sig
, struct target_sigaction
*ka
,
5395 target_sigset_t
*set
, CPUAlphaState
*env
)
5397 abi_ulong frame_addr
, r26
;
5398 struct target_sigframe
*frame
;
5401 frame_addr
= get_sigframe(ka
, env
, sizeof(*frame
));
5402 if (!lock_user_struct(VERIFY_WRITE
, frame
, frame_addr
, 0)) {
5406 setup_sigcontext(&frame
->sc
, env
, frame_addr
, set
);
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_sigreturn
,
5413 &frame
->retcode
[1]);
5414 __put_user(INSN_CALLSYS
, &frame
->retcode
[2]);
5419 unlock_user_struct(frame
, frame_addr
, 1);
5423 if (sig
== TARGET_SIGSEGV
) {
5424 ka
->_sa_handler
= TARGET_SIG_DFL
;
5426 force_sig(TARGET_SIGSEGV
);
5429 env
->ir
[IR_RA
] = r26
;
5430 env
->ir
[IR_PV
] = env
->pc
= ka
->_sa_handler
;
5431 env
->ir
[IR_A0
] = sig
;
5433 env
->ir
[IR_A2
] = frame_addr
+ offsetof(struct target_sigframe
, sc
);
5434 env
->ir
[IR_SP
] = frame_addr
;
5437 static void setup_rt_frame(int sig
, struct target_sigaction
*ka
,
5438 target_siginfo_t
*info
,
5439 target_sigset_t
*set
, CPUAlphaState
*env
)
5441 abi_ulong frame_addr
, r26
;
5442 struct target_rt_sigframe
*frame
;
5445 frame_addr
= get_sigframe(ka
, env
, sizeof(*frame
));
5446 if (!lock_user_struct(VERIFY_WRITE
, frame
, frame_addr
, 0)) {
5450 tswap_siginfo(&frame
->info
, info
);
5452 __put_user(0, &frame
->uc
.tuc_flags
);
5453 __put_user(0, &frame
->uc
.tuc_link
);
5454 __put_user(set
->sig
[0], &frame
->uc
.tuc_osf_sigmask
);
5455 __put_user(target_sigaltstack_used
.ss_sp
,
5456 &frame
->uc
.tuc_stack
.ss_sp
);
5457 __put_user(sas_ss_flags(env
->ir
[IR_SP
]),
5458 &frame
->uc
.tuc_stack
.ss_flags
);
5459 __put_user(target_sigaltstack_used
.ss_size
,
5460 &frame
->uc
.tuc_stack
.ss_size
);
5461 setup_sigcontext(&frame
->uc
.tuc_mcontext
, env
, frame_addr
, set
);
5462 for (i
= 0; i
< TARGET_NSIG_WORDS
; ++i
) {
5463 __put_user(set
->sig
[i
], &frame
->uc
.tuc_sigmask
.sig
[i
]);
5466 if (ka
->sa_restorer
) {
5467 r26
= ka
->sa_restorer
;
5469 __put_user(INSN_MOV_R30_R16
, &frame
->retcode
[0]);
5470 __put_user(INSN_LDI_R0
+ TARGET_NR_rt_sigreturn
,
5471 &frame
->retcode
[1]);
5472 __put_user(INSN_CALLSYS
, &frame
->retcode
[2]);
5479 if (sig
== TARGET_SIGSEGV
) {
5480 ka
->_sa_handler
= TARGET_SIG_DFL
;
5482 force_sig(TARGET_SIGSEGV
);
5485 env
->ir
[IR_RA
] = r26
;
5486 env
->ir
[IR_PV
] = env
->pc
= ka
->_sa_handler
;
5487 env
->ir
[IR_A0
] = sig
;
5488 env
->ir
[IR_A1
] = frame_addr
+ offsetof(struct target_rt_sigframe
, info
);
5489 env
->ir
[IR_A2
] = frame_addr
+ offsetof(struct target_rt_sigframe
, uc
);
5490 env
->ir
[IR_SP
] = frame_addr
;
5493 long do_sigreturn(CPUAlphaState
*env
)
5495 struct target_sigcontext
*sc
;
5496 abi_ulong sc_addr
= env
->ir
[IR_A0
];
5497 target_sigset_t target_set
;
5500 if (!lock_user_struct(VERIFY_READ
, sc
, sc_addr
, 1)) {
5504 target_sigemptyset(&target_set
);
5505 __get_user(target_set
.sig
[0], &sc
->sc_mask
);
5507 target_to_host_sigset_internal(&set
, &target_set
);
5508 do_sigprocmask(SIG_SETMASK
, &set
, NULL
);
5510 restore_sigcontext(env
, sc
);
5511 unlock_user_struct(sc
, sc_addr
, 0);
5512 return env
->ir
[IR_V0
];
5515 force_sig(TARGET_SIGSEGV
);
5518 long do_rt_sigreturn(CPUAlphaState
*env
)
5520 abi_ulong frame_addr
= env
->ir
[IR_A0
];
5521 struct target_rt_sigframe
*frame
;
5524 if (!lock_user_struct(VERIFY_READ
, frame
, frame_addr
, 1)) {
5527 target_to_host_sigset(&set
, &frame
->uc
.tuc_sigmask
);
5528 do_sigprocmask(SIG_SETMASK
, &set
, NULL
);
5530 restore_sigcontext(env
, &frame
->uc
.tuc_mcontext
);
5531 if (do_sigaltstack(frame_addr
+ offsetof(struct target_rt_sigframe
,
5533 0, env
->ir
[IR_SP
]) == -EFAULT
) {
5537 unlock_user_struct(frame
, frame_addr
, 0);
5538 return env
->ir
[IR_V0
];
5542 unlock_user_struct(frame
, frame_addr
, 0);
5543 force_sig(TARGET_SIGSEGV
);
5548 static void setup_frame(int sig
, struct target_sigaction
*ka
,
5549 target_sigset_t
*set
, CPUArchState
*env
)
5551 fprintf(stderr
, "setup_frame: not implemented\n");
5554 static void setup_rt_frame(int sig
, struct target_sigaction
*ka
,
5555 target_siginfo_t
*info
,
5556 target_sigset_t
*set
, CPUArchState
*env
)
5558 fprintf(stderr
, "setup_rt_frame: not implemented\n");
5561 long do_sigreturn(CPUArchState
*env
)
5563 fprintf(stderr
, "do_sigreturn: not implemented\n");
5564 return -TARGET_ENOSYS
;
5567 long do_rt_sigreturn(CPUArchState
*env
)
5569 fprintf(stderr
, "do_rt_sigreturn: not implemented\n");
5570 return -TARGET_ENOSYS
;
5575 void process_pending_signals(CPUArchState
*cpu_env
)
5577 CPUState
*cpu
= ENV_GET_CPU(cpu_env
);
5580 sigset_t set
, old_set
;
5581 target_sigset_t target_old_set
;
5582 struct emulated_sigtable
*k
;
5583 struct target_sigaction
*sa
;
5585 TaskState
*ts
= cpu
->opaque
;
5587 if (!ts
->signal_pending
)
5590 /* FIXME: This is not threadsafe. */
5592 for(sig
= 1; sig
<= TARGET_NSIG
; sig
++) {
5597 /* if no signal is pending, just return */
5598 ts
->signal_pending
= 0;
5603 fprintf(stderr
, "qemu: process signal %d\n", sig
);
5605 /* dequeue signal */
5611 sig
= gdb_handlesig(cpu
, sig
);
5614 handler
= TARGET_SIG_IGN
;
5616 sa
= &sigact_table
[sig
- 1];
5617 handler
= sa
->_sa_handler
;
5620 if (ts
->sigsegv_blocked
&& sig
== TARGET_SIGSEGV
) {
5621 /* Guest has blocked SIGSEGV but we got one anyway. Assume this
5622 * is a forced SIGSEGV (ie one the kernel handles via force_sig_info
5623 * because it got a real MMU fault), and treat as if default handler.
5625 handler
= TARGET_SIG_DFL
;
5628 if (handler
== TARGET_SIG_DFL
) {
5629 /* default handler : ignore some signal. The other are job control or fatal */
5630 if (sig
== TARGET_SIGTSTP
|| sig
== TARGET_SIGTTIN
|| sig
== TARGET_SIGTTOU
) {
5631 kill(getpid(),SIGSTOP
);
5632 } else if (sig
!= TARGET_SIGCHLD
&&
5633 sig
!= TARGET_SIGURG
&&
5634 sig
!= TARGET_SIGWINCH
&&
5635 sig
!= TARGET_SIGCONT
) {
5638 } else if (handler
== TARGET_SIG_IGN
) {
5640 } else if (handler
== TARGET_SIG_ERR
) {
5643 /* compute the blocked signals during the handler execution */
5644 target_to_host_sigset(&set
, &sa
->sa_mask
);
5645 /* SA_NODEFER indicates that the current signal should not be
5646 blocked during the handler */
5647 if (!(sa
->sa_flags
& TARGET_SA_NODEFER
))
5648 sigaddset(&set
, target_to_host_signal(sig
));
5650 /* block signals in the handler using Linux */
5651 do_sigprocmask(SIG_BLOCK
, &set
, &old_set
);
5652 /* save the previous blocked signal state to restore it at the
5653 end of the signal execution (see do_sigreturn) */
5654 host_to_target_sigset_internal(&target_old_set
, &old_set
);
5656 /* if the CPU is in VM86 mode, we restore the 32 bit values */
5657 #if defined(TARGET_I386) && !defined(TARGET_X86_64)
5659 CPUX86State
*env
= cpu_env
;
5660 if (env
->eflags
& VM_MASK
)
5661 save_v86_state(env
);
5664 /* prepare the stack frame of the virtual CPU */
5665 #if defined(TARGET_ABI_MIPSN32) || defined(TARGET_ABI_MIPSN64)
5666 /* These targets do not have traditional signals. */
5667 setup_rt_frame(sig
, sa
, &q
->info
, &target_old_set
, cpu_env
);
5669 if (sa
->sa_flags
& TARGET_SA_SIGINFO
)
5670 setup_rt_frame(sig
, sa
, &q
->info
, &target_old_set
, cpu_env
);
5672 setup_frame(sig
, sa
, &target_old_set
, cpu_env
);
5674 if (sa
->sa_flags
& TARGET_SA_RESETHAND
)
5675 sa
->_sa_handler
= TARGET_SIG_DFL
;
5678 free_sigqueue(cpu_env
, q
);