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