1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19#include <stdlib.h>
20#include <stdio.h>
21#include <string.h>
22#include <stdarg.h>
23#include <unistd.h>
24#include <errno.h>
25#include <assert.h>
26#include <sys/ucontext.h>
27#include <sys/resource.h>
28
29#include "qemu.h"
30#include "qemu-common.h"
31#include "target_signal.h"
32
33
34
35static struct target_sigaltstack target_sigaltstack_used = {
36 .ss_sp = 0,
37 .ss_size = 0,
38 .ss_flags = TARGET_SS_DISABLE,
39};
40
41static struct target_sigaction sigact_table[TARGET_NSIG];
42
43static void host_signal_handler(int host_signum, siginfo_t *info,
44 void *puc);
45
46static 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
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,
63#ifdef SIGSTKFLT
64 [SIGSTKFLT] = TARGET_SIGSTKFLT,
65#endif
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
82
83
84
85
86 [__SIGRTMIN] = __SIGRTMAX,
87 [__SIGRTMAX] = __SIGRTMIN,
88};
89static uint8_t target_to_host_signal_table[_NSIG];
90
91static inline int on_sig_stack(unsigned long sp)
92{
93 return (sp - target_sigaltstack_used.ss_sp
94 < target_sigaltstack_used.ss_size);
95}
96
97static inline int sas_ss_flags(unsigned long sp)
98{
99 return (target_sigaltstack_used.ss_size == 0 ? SS_DISABLE
100 : on_sig_stack(sp) ? SS_ONSTACK : 0);
101}
102
103int host_to_target_signal(int sig)
104{
105 if (sig >= _NSIG)
106 return sig;
107 return host_to_target_signal_table[sig];
108}
109
110int target_to_host_signal(int sig)
111{
112 if (sig >= _NSIG)
113 return sig;
114 return target_to_host_signal_table[sig];
115}
116
117static inline void target_sigemptyset(target_sigset_t *set)
118{
119 memset(set, 0, sizeof(*set));
120}
121
122static inline void target_sigaddset(target_sigset_t *set, int signum)
123{
124 signum--;
125 abi_ulong mask = (abi_ulong)1 << (signum % TARGET_NSIG_BPW);
126 set->sig[signum / TARGET_NSIG_BPW] |= mask;
127}
128
129static inline int target_sigismember(const target_sigset_t *set, int signum)
130{
131 signum--;
132 abi_ulong mask = (abi_ulong)1 << (signum % TARGET_NSIG_BPW);
133 return ((set->sig[signum / TARGET_NSIG_BPW] & mask) != 0);
134}
135
136static void host_to_target_sigset_internal(target_sigset_t *d,
137 const sigset_t *s)
138{
139 int i;
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));
144 }
145 }
146}
147
148void host_to_target_sigset(target_sigset_t *d, const sigset_t *s)
149{
150 target_sigset_t d1;
151 int i;
152
153 host_to_target_sigset_internal(&d1, s);
154 for(i = 0;i < TARGET_NSIG_WORDS; i++)
155 d->sig[i] = tswapl(d1.sig[i]);
156}
157
158static void target_to_host_sigset_internal(sigset_t *d,
159 const target_sigset_t *s)
160{
161 int i;
162 sigemptyset(d);
163 for (i = 1; i <= TARGET_NSIG; i++) {
164 if (target_sigismember(s, i)) {
165 sigaddset(d, target_to_host_signal(i));
166 }
167 }
168}
169
170void target_to_host_sigset(sigset_t *d, const target_sigset_t *s)
171{
172 target_sigset_t s1;
173 int i;
174
175 for(i = 0;i < TARGET_NSIG_WORDS; i++)
176 s1.sig[i] = tswapl(s->sig[i]);
177 target_to_host_sigset_internal(d, &s1);
178}
179
180void host_to_target_old_sigset(abi_ulong *old_sigset,
181 const sigset_t *sigset)
182{
183 target_sigset_t d;
184 host_to_target_sigset(&d, sigset);
185 *old_sigset = d.sig[0];
186}
187
188void target_to_host_old_sigset(sigset_t *sigset,
189 const abi_ulong *old_sigset)
190{
191 target_sigset_t d;
192 int i;
193
194 d.sig[0] = *old_sigset;
195 for(i = 1;i < TARGET_NSIG_WORDS; i++)
196 d.sig[i] = 0;
197 target_to_host_sigset(sigset, &d);
198}
199
200
201
202static inline void host_to_target_siginfo_noswap(target_siginfo_t *tinfo,
203 const siginfo_t *info)
204{
205 int sig;
206 sig = host_to_target_signal(info->si_signo);
207 tinfo->si_signo = sig;
208 tinfo->si_errno = 0;
209 tinfo->si_code = info->si_code;
210 if (sig == SIGILL || sig == SIGFPE || sig == SIGSEGV ||
211 sig == SIGBUS || sig == SIGTRAP) {
212
213
214 tinfo->_sifields._sigfault._addr = 0;
215 } else if (sig == SIGIO) {
216 tinfo->_sifields._sigpoll._fd = info->si_fd;
217 } else if (sig >= TARGET_SIGRTMIN) {
218 tinfo->_sifields._rt._pid = info->si_pid;
219 tinfo->_sifields._rt._uid = info->si_uid;
220
221 tinfo->_sifields._rt._sigval.sival_ptr =
222 (abi_ulong)(unsigned long)info->si_value.sival_ptr;
223 }
224}
225
226static void tswap_siginfo(target_siginfo_t *tinfo,
227 const target_siginfo_t *info)
228{
229 int sig;
230 sig = info->si_signo;
231 tinfo->si_signo = tswap32(sig);
232 tinfo->si_errno = tswap32(info->si_errno);
233 tinfo->si_code = tswap32(info->si_code);
234 if (sig == SIGILL || sig == SIGFPE || sig == SIGSEGV ||
235 sig == SIGBUS || sig == SIGTRAP) {
236 tinfo->_sifields._sigfault._addr =
237 tswapl(info->_sifields._sigfault._addr);
238 } else if (sig == SIGIO) {
239 tinfo->_sifields._sigpoll._fd = tswap32(info->_sifields._sigpoll._fd);
240 } else if (sig >= TARGET_SIGRTMIN) {
241 tinfo->_sifields._rt._pid = tswap32(info->_sifields._rt._pid);
242 tinfo->_sifields._rt._uid = tswap32(info->_sifields._rt._uid);
243 tinfo->_sifields._rt._sigval.sival_ptr =
244 tswapl(info->_sifields._rt._sigval.sival_ptr);
245 }
246}
247
248
249void host_to_target_siginfo(target_siginfo_t *tinfo, const siginfo_t *info)
250{
251 host_to_target_siginfo_noswap(tinfo, info);
252 tswap_siginfo(tinfo, tinfo);
253}
254
255
256
257void target_to_host_siginfo(siginfo_t *info, const target_siginfo_t *tinfo)
258{
259 info->si_signo = tswap32(tinfo->si_signo);
260 info->si_errno = tswap32(tinfo->si_errno);
261 info->si_code = tswap32(tinfo->si_code);
262 info->si_pid = tswap32(tinfo->_sifields._rt._pid);
263 info->si_uid = tswap32(tinfo->_sifields._rt._uid);
264 info->si_value.sival_ptr =
265 (void *)(long)tswapl(tinfo->_sifields._rt._sigval.sival_ptr);
266}
267
268static int fatal_signal (int sig)
269{
270 switch (sig) {
271 case TARGET_SIGCHLD:
272 case TARGET_SIGURG:
273 case TARGET_SIGWINCH:
274
275 return 0;
276 case TARGET_SIGCONT:
277 case TARGET_SIGSTOP:
278 case TARGET_SIGTSTP:
279 case TARGET_SIGTTIN:
280 case TARGET_SIGTTOU:
281
282 return 0;
283 default:
284 return 1;
285 }
286}
287
288
289static int core_dump_signal(int sig)
290{
291 switch (sig) {
292 case TARGET_SIGABRT:
293 case TARGET_SIGFPE:
294 case TARGET_SIGILL:
295 case TARGET_SIGQUIT:
296 case TARGET_SIGSEGV:
297 case TARGET_SIGTRAP:
298 case TARGET_SIGBUS:
299 return (1);
300 default:
301 return (0);
302 }
303}
304
305void signal_init(void)
306{
307 struct sigaction act;
308 struct sigaction oact;
309 int i, j;
310 int host_sig;
311
312
313 for(i = 1; i < _NSIG; i++) {
314 if (host_to_target_signal_table[i] == 0)
315 host_to_target_signal_table[i] = i;
316 }
317 for(i = 1; i < _NSIG; i++) {
318 j = host_to_target_signal_table[i];
319 target_to_host_signal_table[j] = i;
320 }
321
322
323
324 memset(sigact_table, 0, sizeof(sigact_table));
325
326 sigfillset(&act.sa_mask);
327 act.sa_flags = SA_SIGINFO;
328 act.sa_sigaction = host_signal_handler;
329 for(i = 1; i <= TARGET_NSIG; i++) {
330 host_sig = target_to_host_signal(i);
331 sigaction(host_sig, NULL, &oact);
332 if (oact.sa_sigaction == (void *)SIG_IGN) {
333 sigact_table[i - 1]._sa_handler = TARGET_SIG_IGN;
334 } else if (oact.sa_sigaction == (void *)SIG_DFL) {
335 sigact_table[i - 1]._sa_handler = TARGET_SIG_DFL;
336 }
337
338
339
340
341
342
343 if (fatal_signal (i))
344 sigaction(host_sig, &act, NULL);
345 }
346}
347
348
349
350static inline struct sigqueue *alloc_sigqueue(CPUState *env)
351{
352 TaskState *ts = env->opaque;
353 struct sigqueue *q = ts->first_free;
354 if (!q)
355 return NULL;
356 ts->first_free = q->next;
357 return q;
358}
359
360static inline void free_sigqueue(CPUState *env, struct sigqueue *q)
361{
362 TaskState *ts = env->opaque;
363 q->next = ts->first_free;
364 ts->first_free = q;
365}
366
367
368static void QEMU_NORETURN force_sig(int target_sig)
369{
370 TaskState *ts = (TaskState *)thread_env->opaque;
371 int host_sig, core_dumped = 0;
372 struct sigaction act;
373 host_sig = target_to_host_signal(target_sig);
374 gdb_signalled(thread_env, target_sig);
375
376
377 if (core_dump_signal(target_sig) && (ts->bprm->core_dump != NULL)) {
378 stop_all_tasks();
379 core_dumped =
380 ((*ts->bprm->core_dump)(target_sig, thread_env) == 0);
381 }
382 if (core_dumped) {
383
384
385 struct rlimit nodump;
386 getrlimit(RLIMIT_CORE, &nodump);
387 nodump.rlim_cur=0;
388 setrlimit(RLIMIT_CORE, &nodump);
389 (void) fprintf(stderr, "qemu: uncaught target signal %d (%s) - %s\n",
390 target_sig, strsignal(host_sig), "core dumped" );
391 }
392
393
394
395
396
397
398
399 sigfillset(&act.sa_mask);
400 act.sa_handler = SIG_DFL;
401 sigaction(host_sig, &act, NULL);
402
403
404
405 kill(getpid(), host_sig);
406
407
408
409 sigdelset(&act.sa_mask, host_sig);
410 sigsuspend(&act.sa_mask);
411
412
413 abort();
414}
415
416
417
418int queue_signal(CPUState *env, int sig, target_siginfo_t *info)
419{
420 TaskState *ts = env->opaque;
421 struct emulated_sigtable *k;
422 struct sigqueue *q, **pq;
423 abi_ulong handler;
424 int queue;
425
426#if defined(DEBUG_SIGNAL)
427 fprintf(stderr, "queue_signal: sig=%d\n",
428 sig);
429#endif
430 k = &ts->sigtab[sig - 1];
431 queue = gdb_queuesig ();
432 handler = sigact_table[sig - 1]._sa_handler;
433 if (!queue && handler == TARGET_SIG_DFL) {
434 if (sig == TARGET_SIGTSTP || sig == TARGET_SIGTTIN || sig == TARGET_SIGTTOU) {
435 kill(getpid(),SIGSTOP);
436 return 0;
437 } else
438
439 if (sig != TARGET_SIGCHLD &&
440 sig != TARGET_SIGURG &&
441 sig != TARGET_SIGWINCH &&
442 sig != TARGET_SIGCONT) {
443 force_sig(sig);
444 } else {
445 return 0;
446 }
447 } else if (!queue && handler == TARGET_SIG_IGN) {
448
449 return 0;
450 } else if (!queue && handler == TARGET_SIG_ERR) {
451 force_sig(sig);
452 } else {
453 pq = &k->first;
454 if (sig < TARGET_SIGRTMIN) {
455
456 if (!k->pending)
457 q = &k->info;
458 else
459 return 0;
460 } else {
461 if (!k->pending) {
462
463 q = &k->info;
464 } else {
465 q = alloc_sigqueue(env);
466 if (!q)
467 return -EAGAIN;
468 while (*pq != NULL)
469 pq = &(*pq)->next;
470 }
471 }
472 *pq = q;
473 q->info = *info;
474 q->next = NULL;
475 k->pending = 1;
476
477 ts->signal_pending = 1;
478 return 1;
479 }
480}
481
482static void host_signal_handler(int host_signum, siginfo_t *info,
483 void *puc)
484{
485 int sig;
486 target_siginfo_t tinfo;
487
488
489
490 if ((host_signum == SIGSEGV || host_signum == SIGBUS)
491 && info->si_code > 0) {
492 if (cpu_signal_handler(host_signum, info, puc))
493 return;
494 }
495
496
497 sig = host_to_target_signal(host_signum);
498 if (sig < 1 || sig > TARGET_NSIG)
499 return;
500#if defined(DEBUG_SIGNAL)
501 fprintf(stderr, "qemu: got signal %d\n", sig);
502#endif
503 host_to_target_siginfo_noswap(&tinfo, info);
504 if (queue_signal(thread_env, sig, &tinfo) == 1) {
505
506 cpu_exit(thread_env);
507 }
508}
509
510
511
512abi_long do_sigaltstack(abi_ulong uss_addr, abi_ulong uoss_addr, abi_ulong sp)
513{
514 int ret;
515 struct target_sigaltstack oss;
516
517
518 if(uoss_addr)
519 {
520 __put_user(target_sigaltstack_used.ss_sp, &oss.ss_sp);
521 __put_user(target_sigaltstack_used.ss_size, &oss.ss_size);
522 __put_user(sas_ss_flags(sp), &oss.ss_flags);
523 }
524
525 if(uss_addr)
526 {
527 struct target_sigaltstack *uss;
528 struct target_sigaltstack ss;
529
530 ret = -TARGET_EFAULT;
531 if (!lock_user_struct(VERIFY_READ, uss, uss_addr, 1)
532 || __get_user(ss.ss_sp, &uss->ss_sp)
533 || __get_user(ss.ss_size, &uss->ss_size)
534 || __get_user(ss.ss_flags, &uss->ss_flags))
535 goto out;
536 unlock_user_struct(uss, uss_addr, 0);
537
538 ret = -TARGET_EPERM;
539 if (on_sig_stack(sp))
540 goto out;
541
542 ret = -TARGET_EINVAL;
543 if (ss.ss_flags != TARGET_SS_DISABLE
544 && ss.ss_flags != TARGET_SS_ONSTACK
545 && ss.ss_flags != 0)
546 goto out;
547
548 if (ss.ss_flags == TARGET_SS_DISABLE) {
549 ss.ss_size = 0;
550 ss.ss_sp = 0;
551 } else {
552 ret = -TARGET_ENOMEM;
553 if (ss.ss_size < MINSIGSTKSZ)
554 goto out;
555 }
556
557 target_sigaltstack_used.ss_sp = ss.ss_sp;
558 target_sigaltstack_used.ss_size = ss.ss_size;
559 }
560
561 if (uoss_addr) {
562 ret = -TARGET_EFAULT;
563 if (copy_to_user(uoss_addr, &oss, sizeof(oss)))
564 goto out;
565 }
566
567 ret = 0;
568out:
569 return ret;
570}
571
572
573int do_sigaction(int sig, const struct target_sigaction *act,
574 struct target_sigaction *oact)
575{
576 struct target_sigaction *k;
577 struct sigaction act1;
578 int host_sig;
579 int ret = 0;
580
581 if (sig < 1 || sig > TARGET_NSIG || sig == TARGET_SIGKILL || sig == TARGET_SIGSTOP)
582 return -EINVAL;
583 k = &sigact_table[sig - 1];
584#if defined(DEBUG_SIGNAL)
585 fprintf(stderr, "sigaction sig=%d act=0x%p, oact=0x%p\n",
586 sig, act, oact);
587#endif
588 if (oact) {
589 oact->_sa_handler = tswapl(k->_sa_handler);
590 oact->sa_flags = tswapl(k->sa_flags);
591#if !defined(TARGET_MIPS)
592 oact->sa_restorer = tswapl(k->sa_restorer);
593#endif
594 oact->sa_mask = k->sa_mask;
595 }
596 if (act) {
597
598 k->_sa_handler = tswapl(act->_sa_handler);
599 k->sa_flags = tswapl(act->sa_flags);
600#if !defined(TARGET_MIPS)
601 k->sa_restorer = tswapl(act->sa_restorer);
602#endif
603 k->sa_mask = act->sa_mask;
604
605
606 host_sig = target_to_host_signal(sig);
607 if (host_sig != SIGSEGV && host_sig != SIGBUS) {
608 sigfillset(&act1.sa_mask);
609 act1.sa_flags = SA_SIGINFO;
610 if (k->sa_flags & TARGET_SA_RESTART)
611 act1.sa_flags |= SA_RESTART;
612
613
614
615 if (k->_sa_handler == TARGET_SIG_IGN) {
616 act1.sa_sigaction = (void *)SIG_IGN;
617 } else if (k->_sa_handler == TARGET_SIG_DFL) {
618 if (fatal_signal (sig))
619 act1.sa_sigaction = host_signal_handler;
620 else
621 act1.sa_sigaction = (void *)SIG_DFL;
622 } else {
623 act1.sa_sigaction = host_signal_handler;
624 }
625 ret = sigaction(host_sig, &act1, NULL);
626 }
627 }
628 return ret;
629}
630
631static inline int copy_siginfo_to_user(target_siginfo_t *tinfo,
632 const target_siginfo_t *info)
633{
634 tswap_siginfo(tinfo, info);
635 return 0;
636}
637
638static inline int current_exec_domain_sig(int sig)
639{
640 return
641 sig;
642}
643
644#if defined(TARGET_I386) && TARGET_ABI_BITS == 32
645
646
647
648struct target_fpreg {
649 uint16_t significand[4];
650 uint16_t exponent;
651};
652
653struct target_fpxreg {
654 uint16_t significand[4];
655 uint16_t exponent;
656 uint16_t padding[3];
657};
658
659struct target_xmmreg {
660 abi_ulong element[4];
661};
662
663struct target_fpstate {
664
665 abi_ulong cw;
666 abi_ulong sw;
667 abi_ulong tag;
668 abi_ulong ipoff;
669 abi_ulong cssel;
670 abi_ulong dataoff;
671 abi_ulong datasel;
672 struct target_fpreg _st[8];
673 uint16_t status;
674 uint16_t magic;
675
676
677 abi_ulong _fxsr_env[6];
678 abi_ulong mxcsr;
679 abi_ulong reserved;
680 struct target_fpxreg _fxsr_st[8];
681 struct target_xmmreg _xmm[8];
682 abi_ulong padding[56];
683};
684
685#define X86_FXSR_MAGIC 0x0000
686
687struct target_sigcontext {
688 uint16_t gs, __gsh;
689 uint16_t fs, __fsh;
690 uint16_t es, __esh;
691 uint16_t ds, __dsh;
692 abi_ulong edi;
693 abi_ulong esi;
694 abi_ulong ebp;
695 abi_ulong esp;
696 abi_ulong ebx;
697 abi_ulong edx;
698 abi_ulong ecx;
699 abi_ulong eax;
700 abi_ulong trapno;
701 abi_ulong err;
702 abi_ulong eip;
703 uint16_t cs, __csh;
704 abi_ulong eflags;
705 abi_ulong esp_at_signal;
706 uint16_t ss, __ssh;
707 abi_ulong fpstate;
708 abi_ulong oldmask;
709 abi_ulong cr2;
710};
711
712struct target_ucontext {
713 abi_ulong tuc_flags;
714 abi_ulong tuc_link;
715 target_stack_t tuc_stack;
716 struct target_sigcontext tuc_mcontext;
717 target_sigset_t tuc_sigmask;
718};
719
720struct sigframe
721{
722 abi_ulong pretcode;
723 int sig;
724 struct target_sigcontext sc;
725 struct target_fpstate fpstate;
726 abi_ulong extramask[TARGET_NSIG_WORDS-1];
727 char retcode[8];
728};
729
730struct rt_sigframe
731{
732 abi_ulong pretcode;
733 int sig;
734 abi_ulong pinfo;
735 abi_ulong puc;
736 struct target_siginfo info;
737 struct target_ucontext uc;
738 struct target_fpstate fpstate;
739 char retcode[8];
740};
741
742
743
744
745
746
747static int
748setup_sigcontext(struct target_sigcontext *sc, struct target_fpstate *fpstate,
749 CPUX86State *env, abi_ulong mask, abi_ulong fpstate_addr)
750{
751 int err = 0;
752 uint16_t magic;
753
754
755 err |= __put_user(env->segs[R_GS].selector, (unsigned int *)&sc->gs);
756 err |= __put_user(env->segs[R_FS].selector, (unsigned int *)&sc->fs);
757 err |= __put_user(env->segs[R_ES].selector, (unsigned int *)&sc->es);
758 err |= __put_user(env->segs[R_DS].selector, (unsigned int *)&sc->ds);
759 err |= __put_user(env->regs[R_EDI], &sc->edi);
760 err |= __put_user(env->regs[R_ESI], &sc->esi);
761 err |= __put_user(env->regs[R_EBP], &sc->ebp);
762 err |= __put_user(env->regs[R_ESP], &sc->esp);
763 err |= __put_user(env->regs[R_EBX], &sc->ebx);
764 err |= __put_user(env->regs[R_EDX], &sc->edx);
765 err |= __put_user(env->regs[R_ECX], &sc->ecx);
766 err |= __put_user(env->regs[R_EAX], &sc->eax);
767 err |= __put_user(env->exception_index, &sc->trapno);
768 err |= __put_user(env->error_code, &sc->err);
769 err |= __put_user(env->eip, &sc->eip);
770 err |= __put_user(env->segs[R_CS].selector, (unsigned int *)&sc->cs);
771 err |= __put_user(env->eflags, &sc->eflags);
772 err |= __put_user(env->regs[R_ESP], &sc->esp_at_signal);
773 err |= __put_user(env->segs[R_SS].selector, (unsigned int *)&sc->ss);
774
775 cpu_x86_fsave(env, fpstate_addr, 1);
776 fpstate->status = fpstate->sw;
777 magic = 0xffff;
778 err |= __put_user(magic, &fpstate->magic);
779 err |= __put_user(fpstate_addr, &sc->fpstate);
780
781
782 err |= __put_user(mask, &sc->oldmask);
783 err |= __put_user(env->cr[2], &sc->cr2);
784 return err;
785}
786
787
788
789
790
791static inline abi_ulong
792get_sigframe(struct target_sigaction *ka, CPUX86State *env, size_t frame_size)
793{
794 unsigned long esp;
795
796
797 esp = env->regs[R_ESP];
798
799 if (ka->sa_flags & TARGET_SA_ONSTACK) {
800 if (sas_ss_flags(esp) == 0)
801 esp = target_sigaltstack_used.ss_sp + target_sigaltstack_used.ss_size;
802 }
803
804
805 else
806 if ((env->segs[R_SS].selector & 0xffff) != __USER_DS &&
807 !(ka->sa_flags & TARGET_SA_RESTORER) &&
808 ka->sa_restorer) {
809 esp = (unsigned long) ka->sa_restorer;
810 }
811 return (esp - frame_size) & -8ul;
812}
813
814
815static void setup_frame(int sig, struct target_sigaction *ka,
816 target_sigset_t *set, CPUX86State *env)
817{
818 abi_ulong frame_addr;
819 struct sigframe *frame;
820 int i, err = 0;
821
822 frame_addr = get_sigframe(ka, env, sizeof(*frame));
823
824 if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
825 goto give_sigsegv;
826
827 err |= __put_user(current_exec_domain_sig(sig),
828 &frame->sig);
829 if (err)
830 goto give_sigsegv;
831
832 setup_sigcontext(&frame->sc, &frame->fpstate, env, set->sig[0],
833 frame_addr + offsetof(struct sigframe, fpstate));
834 if (err)
835 goto give_sigsegv;
836
837 for(i = 1; i < TARGET_NSIG_WORDS; i++) {
838 if (__put_user(set->sig[i], &frame->extramask[i - 1]))
839 goto give_sigsegv;
840 }
841
842
843
844 if (ka->sa_flags & TARGET_SA_RESTORER) {
845 err |= __put_user(ka->sa_restorer, &frame->pretcode);
846 } else {
847 uint16_t val16;
848 abi_ulong retcode_addr;
849 retcode_addr = frame_addr + offsetof(struct sigframe, retcode);
850 err |= __put_user(retcode_addr, &frame->pretcode);
851
852 val16 = 0xb858;
853 err |= __put_user(val16, (uint16_t *)(frame->retcode+0));
854 err |= __put_user(TARGET_NR_sigreturn, (int *)(frame->retcode+2));
855 val16 = 0x80cd;
856 err |= __put_user(val16, (uint16_t *)(frame->retcode+6));
857 }
858
859 if (err)
860 goto give_sigsegv;
861
862
863 env->regs[R_ESP] = frame_addr;
864 env->eip = ka->_sa_handler;
865
866 cpu_x86_load_seg(env, R_DS, __USER_DS);
867 cpu_x86_load_seg(env, R_ES, __USER_DS);
868 cpu_x86_load_seg(env, R_SS, __USER_DS);
869 cpu_x86_load_seg(env, R_CS, __USER_CS);
870 env->eflags &= ~TF_MASK;
871
872 unlock_user_struct(frame, frame_addr, 1);
873
874 return;
875
876give_sigsegv:
877 unlock_user_struct(frame, frame_addr, 1);
878 if (sig == TARGET_SIGSEGV)
879 ka->_sa_handler = TARGET_SIG_DFL;
880 force_sig(TARGET_SIGSEGV );
881}
882
883
884static void setup_rt_frame(int sig, struct target_sigaction *ka,
885 target_siginfo_t *info,
886 target_sigset_t *set, CPUX86State *env)
887{
888 abi_ulong frame_addr, addr;
889 struct rt_sigframe *frame;
890 int i, err = 0;
891
892 frame_addr = get_sigframe(ka, env, sizeof(*frame));
893
894 if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
895 goto give_sigsegv;
896
897 err |= __put_user(current_exec_domain_sig(sig),
898 &frame->sig);
899 addr = frame_addr + offsetof(struct rt_sigframe, info);
900 err |= __put_user(addr, &frame->pinfo);
901 addr = frame_addr + offsetof(struct rt_sigframe, uc);
902 err |= __put_user(addr, &frame->puc);
903 err |= copy_siginfo_to_user(&frame->info, info);
904 if (err)
905 goto give_sigsegv;
906
907
908 err |= __put_user(0, &frame->uc.tuc_flags);
909 err |= __put_user(0, &frame->uc.tuc_link);
910 err |= __put_user(target_sigaltstack_used.ss_sp,
911 &frame->uc.tuc_stack.ss_sp);
912 err |= __put_user(sas_ss_flags(get_sp_from_cpustate(env)),
913 &frame->uc.tuc_stack.ss_flags);
914 err |= __put_user(target_sigaltstack_used.ss_size,
915 &frame->uc.tuc_stack.ss_size);
916 err |= setup_sigcontext(&frame->uc.tuc_mcontext, &frame->fpstate,
917 env, set->sig[0],
918 frame_addr + offsetof(struct rt_sigframe, fpstate));
919 for(i = 0; i < TARGET_NSIG_WORDS; i++) {
920 if (__put_user(set->sig[i], &frame->uc.tuc_sigmask.sig[i]))
921 goto give_sigsegv;
922 }
923
924
925
926 if (ka->sa_flags & TARGET_SA_RESTORER) {
927 err |= __put_user(ka->sa_restorer, &frame->pretcode);
928 } else {
929 uint16_t val16;
930 addr = frame_addr + offsetof(struct rt_sigframe, retcode);
931 err |= __put_user(addr, &frame->pretcode);
932
933 err |= __put_user(0xb8, (char *)(frame->retcode+0));
934 err |= __put_user(TARGET_NR_rt_sigreturn, (int *)(frame->retcode+1));
935 val16 = 0x80cd;
936 err |= __put_user(val16, (uint16_t *)(frame->retcode+5));
937 }
938
939 if (err)
940 goto give_sigsegv;
941
942
943 env->regs[R_ESP] = frame_addr;
944 env->eip = ka->_sa_handler;
945
946 cpu_x86_load_seg(env, R_DS, __USER_DS);
947 cpu_x86_load_seg(env, R_ES, __USER_DS);
948 cpu_x86_load_seg(env, R_SS, __USER_DS);
949 cpu_x86_load_seg(env, R_CS, __USER_CS);
950 env->eflags &= ~TF_MASK;
951
952 unlock_user_struct(frame, frame_addr, 1);
953
954 return;
955
956give_sigsegv:
957 unlock_user_struct(frame, frame_addr, 1);
958 if (sig == TARGET_SIGSEGV)
959 ka->_sa_handler = TARGET_SIG_DFL;
960 force_sig(TARGET_SIGSEGV );
961}
962
963static int
964restore_sigcontext(CPUX86State *env, struct target_sigcontext *sc, int *peax)
965{
966 unsigned int err = 0;
967 abi_ulong fpstate_addr;
968 unsigned int tmpflags;
969
970 cpu_x86_load_seg(env, R_GS, tswap16(sc->gs));
971 cpu_x86_load_seg(env, R_FS, tswap16(sc->fs));
972 cpu_x86_load_seg(env, R_ES, tswap16(sc->es));
973 cpu_x86_load_seg(env, R_DS, tswap16(sc->ds));
974
975 env->regs[R_EDI] = tswapl(sc->edi);
976 env->regs[R_ESI] = tswapl(sc->esi);
977 env->regs[R_EBP] = tswapl(sc->ebp);
978 env->regs[R_ESP] = tswapl(sc->esp);
979 env->regs[R_EBX] = tswapl(sc->ebx);
980 env->regs[R_EDX] = tswapl(sc->edx);
981 env->regs[R_ECX] = tswapl(sc->ecx);
982 env->eip = tswapl(sc->eip);
983
984 cpu_x86_load_seg(env, R_CS, lduw_p(&sc->cs) | 3);
985 cpu_x86_load_seg(env, R_SS, lduw_p(&sc->ss) | 3);
986
987 tmpflags = tswapl(sc->eflags);
988 env->eflags = (env->eflags & ~0x40DD5) | (tmpflags & 0x40DD5);
989
990
991 fpstate_addr = tswapl(sc->fpstate);
992 if (fpstate_addr != 0) {
993 if (!access_ok(VERIFY_READ, fpstate_addr,
994 sizeof(struct target_fpstate)))
995 goto badframe;
996 cpu_x86_frstor(env, fpstate_addr, 1);
997 }
998
999 *peax = tswapl(sc->eax);
1000 return err;
1001badframe:
1002 return 1;
1003}
1004
1005long do_sigreturn(CPUX86State *env)
1006{
1007 struct sigframe *frame;
1008 abi_ulong frame_addr = env->regs[R_ESP] - 8;
1009 target_sigset_t target_set;
1010 sigset_t set;
1011 int eax, i;
1012
1013#if defined(DEBUG_SIGNAL)
1014 fprintf(stderr, "do_sigreturn\n");
1015#endif
1016 if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1))
1017 goto badframe;
1018
1019 if (__get_user(target_set.sig[0], &frame->sc.oldmask))
1020 goto badframe;
1021 for(i = 1; i < TARGET_NSIG_WORDS; i++) {
1022 if (__get_user(target_set.sig[i], &frame->extramask[i - 1]))
1023 goto badframe;
1024 }
1025
1026 target_to_host_sigset_internal(&set, &target_set);
1027 sigprocmask(SIG_SETMASK, &set, NULL);
1028
1029
1030 if (restore_sigcontext(env, &frame->sc, &eax))
1031 goto badframe;
1032 unlock_user_struct(frame, frame_addr, 0);
1033 return eax;
1034
1035badframe:
1036 unlock_user_struct(frame, frame_addr, 0);
1037 force_sig(TARGET_SIGSEGV);
1038 return 0;
1039}
1040
1041long do_rt_sigreturn(CPUX86State *env)
1042{
1043 abi_ulong frame_addr;
1044 struct rt_sigframe *frame;
1045 sigset_t set;
1046 int eax;
1047
1048 frame_addr = env->regs[R_ESP] - 4;
1049 if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1))
1050 goto badframe;
1051 target_to_host_sigset(&set, &frame->uc.tuc_sigmask);
1052 sigprocmask(SIG_SETMASK, &set, NULL);
1053
1054 if (restore_sigcontext(env, &frame->uc.tuc_mcontext, &eax))
1055 goto badframe;
1056
1057 if (do_sigaltstack(frame_addr + offsetof(struct rt_sigframe, uc.tuc_stack), 0,
1058 get_sp_from_cpustate(env)) == -EFAULT)
1059 goto badframe;
1060
1061 unlock_user_struct(frame, frame_addr, 0);
1062 return eax;
1063
1064badframe:
1065 unlock_user_struct(frame, frame_addr, 0);
1066 force_sig(TARGET_SIGSEGV);
1067 return 0;
1068}
1069
1070#elif defined(TARGET_ARM)
1071
1072struct target_sigcontext {
1073 abi_ulong trap_no;
1074 abi_ulong error_code;
1075 abi_ulong oldmask;
1076 abi_ulong arm_r0;
1077 abi_ulong arm_r1;
1078 abi_ulong arm_r2;
1079 abi_ulong arm_r3;
1080 abi_ulong arm_r4;
1081 abi_ulong arm_r5;
1082 abi_ulong arm_r6;
1083 abi_ulong arm_r7;
1084 abi_ulong arm_r8;
1085 abi_ulong arm_r9;
1086 abi_ulong arm_r10;
1087 abi_ulong arm_fp;
1088 abi_ulong arm_ip;
1089 abi_ulong arm_sp;
1090 abi_ulong arm_lr;
1091 abi_ulong arm_pc;
1092 abi_ulong arm_cpsr;
1093 abi_ulong fault_address;
1094};
1095
1096struct target_ucontext_v1 {
1097 abi_ulong tuc_flags;
1098 abi_ulong tuc_link;
1099 target_stack_t tuc_stack;
1100 struct target_sigcontext tuc_mcontext;
1101 target_sigset_t tuc_sigmask;
1102};
1103
1104struct target_ucontext_v2 {
1105 abi_ulong tuc_flags;
1106 abi_ulong tuc_link;
1107 target_stack_t tuc_stack;
1108 struct target_sigcontext tuc_mcontext;
1109 target_sigset_t tuc_sigmask;
1110 char __unused[128 - sizeof(target_sigset_t)];
1111 abi_ulong tuc_regspace[128] __attribute__((__aligned__(8)));
1112};
1113
1114struct target_user_vfp {
1115 uint64_t fpregs[32];
1116 abi_ulong fpscr;
1117};
1118
1119struct target_user_vfp_exc {
1120 abi_ulong fpexc;
1121 abi_ulong fpinst;
1122 abi_ulong fpinst2;
1123};
1124
1125struct target_vfp_sigframe {
1126 abi_ulong magic;
1127 abi_ulong size;
1128 struct target_user_vfp ufp;
1129 struct target_user_vfp_exc ufp_exc;
1130} __attribute__((__aligned__(8)));
1131
1132struct target_iwmmxt_sigframe {
1133 abi_ulong magic;
1134 abi_ulong size;
1135 uint64_t regs[16];
1136
1137 uint32_t wcssf;
1138 uint32_t wcasf;
1139 uint32_t wcgr0;
1140 uint32_t wcgr1;
1141 uint32_t wcgr2;
1142 uint32_t wcgr3;
1143} __attribute__((__aligned__(8)));
1144
1145#define TARGET_VFP_MAGIC 0x56465001
1146#define TARGET_IWMMXT_MAGIC 0x12ef842a
1147
1148struct sigframe_v1
1149{
1150 struct target_sigcontext sc;
1151 abi_ulong extramask[TARGET_NSIG_WORDS-1];
1152 abi_ulong retcode;
1153};
1154
1155struct sigframe_v2
1156{
1157 struct target_ucontext_v2 uc;
1158 abi_ulong retcode;
1159};
1160
1161struct rt_sigframe_v1
1162{
1163 abi_ulong pinfo;
1164 abi_ulong puc;
1165 struct target_siginfo info;
1166 struct target_ucontext_v1 uc;
1167 abi_ulong retcode;
1168};
1169
1170struct rt_sigframe_v2
1171{
1172 struct target_siginfo info;
1173 struct target_ucontext_v2 uc;
1174 abi_ulong retcode;
1175};
1176
1177#define TARGET_CONFIG_CPU_32 1
1178
1179
1180
1181
1182#define SWI_SYS_SIGRETURN (0xef000000|(TARGET_NR_sigreturn + ARM_SYSCALL_BASE))
1183#define SWI_SYS_RT_SIGRETURN (0xef000000|(TARGET_NR_rt_sigreturn + ARM_SYSCALL_BASE))
1184
1185
1186
1187
1188
1189#define SWI_THUMB_SIGRETURN (0xdf00 << 16 | 0x2700 | (TARGET_NR_sigreturn))
1190#define SWI_THUMB_RT_SIGRETURN (0xdf00 << 16 | 0x2700 | (TARGET_NR_rt_sigreturn))
1191
1192static const abi_ulong retcodes[4] = {
1193 SWI_SYS_SIGRETURN, SWI_THUMB_SIGRETURN,
1194 SWI_SYS_RT_SIGRETURN, SWI_THUMB_RT_SIGRETURN
1195};
1196
1197
1198#define __get_user_error(x,p,e) __get_user(x, p)
1199
1200static inline int valid_user_regs(CPUState *regs)
1201{
1202 return 1;
1203}
1204
1205static void
1206setup_sigcontext(struct target_sigcontext *sc,
1207 CPUState *env, abi_ulong mask)
1208{
1209 __put_user(env->regs[0], &sc->arm_r0);
1210 __put_user(env->regs[1], &sc->arm_r1);
1211 __put_user(env->regs[2], &sc->arm_r2);
1212 __put_user(env->regs[3], &sc->arm_r3);
1213 __put_user(env->regs[4], &sc->arm_r4);
1214 __put_user(env->regs[5], &sc->arm_r5);
1215 __put_user(env->regs[6], &sc->arm_r6);
1216 __put_user(env->regs[7], &sc->arm_r7);
1217 __put_user(env->regs[8], &sc->arm_r8);
1218 __put_user(env->regs[9], &sc->arm_r9);
1219 __put_user(env->regs[10], &sc->arm_r10);
1220 __put_user(env->regs[11], &sc->arm_fp);
1221 __put_user(env->regs[12], &sc->arm_ip);
1222 __put_user(env->regs[13], &sc->arm_sp);
1223 __put_user(env->regs[14], &sc->arm_lr);
1224 __put_user(env->regs[15], &sc->arm_pc);
1225#ifdef TARGET_CONFIG_CPU_32
1226 __put_user(cpsr_read(env), &sc->arm_cpsr);
1227#endif
1228
1229 __put_user( 0, &sc->trap_no);
1230 __put_user( 0, &sc->error_code);
1231 __put_user( 0, &sc->fault_address);
1232 __put_user(mask, &sc->oldmask);
1233}
1234
1235static inline abi_ulong
1236get_sigframe(struct target_sigaction *ka, CPUState *regs, int framesize)
1237{
1238 unsigned long sp = regs->regs[13];
1239
1240
1241
1242
1243 if ((ka->sa_flags & TARGET_SA_ONSTACK) && !sas_ss_flags(sp))
1244 sp = target_sigaltstack_used.ss_sp + target_sigaltstack_used.ss_size;
1245
1246
1247
1248 return (sp - framesize) & ~7;
1249}
1250
1251static int
1252setup_return(CPUState *env, struct target_sigaction *ka,
1253 abi_ulong *rc, abi_ulong frame_addr, int usig, abi_ulong rc_addr)
1254{
1255 abi_ulong handler = ka->_sa_handler;
1256 abi_ulong retcode;
1257 int thumb = handler & 1;
1258 uint32_t cpsr = cpsr_read(env);
1259
1260 cpsr &= ~CPSR_IT;
1261 if (thumb) {
1262 cpsr |= CPSR_T;
1263 } else {
1264 cpsr &= ~CPSR_T;
1265 }
1266
1267 if (ka->sa_flags & TARGET_SA_RESTORER) {
1268 retcode = ka->sa_restorer;
1269 } else {
1270 unsigned int idx = thumb;
1271
1272 if (ka->sa_flags & TARGET_SA_SIGINFO)
1273 idx += 2;
1274
1275 if (__put_user(retcodes[idx], rc))
1276 return 1;
1277#if 0
1278 flush_icache_range((abi_ulong)rc,
1279 (abi_ulong)(rc + 1));
1280#endif
1281 retcode = rc_addr + thumb;
1282 }
1283
1284 env->regs[0] = usig;
1285 env->regs[13] = frame_addr;
1286 env->regs[14] = retcode;
1287 env->regs[15] = handler & (thumb ? ~1 : ~3);
1288 cpsr_write(env, cpsr, 0xffffffff);
1289
1290 return 0;
1291}
1292
1293static abi_ulong *setup_sigframe_v2_vfp(abi_ulong *regspace, CPUState *env)
1294{
1295 int i;
1296 struct target_vfp_sigframe *vfpframe;
1297 vfpframe = (struct target_vfp_sigframe *)regspace;
1298 __put_user(TARGET_VFP_MAGIC, &vfpframe->magic);
1299 __put_user(sizeof(*vfpframe), &vfpframe->size);
1300 for (i = 0; i < 32; i++) {
1301 __put_user(float64_val(env->vfp.regs[i]), &vfpframe->ufp.fpregs[i]);
1302 }
1303 __put_user(vfp_get_fpscr(env), &vfpframe->ufp.fpscr);
1304 __put_user(env->vfp.xregs[ARM_VFP_FPEXC], &vfpframe->ufp_exc.fpexc);
1305 __put_user(env->vfp.xregs[ARM_VFP_FPINST], &vfpframe->ufp_exc.fpinst);
1306 __put_user(env->vfp.xregs[ARM_VFP_FPINST2], &vfpframe->ufp_exc.fpinst2);
1307 return (abi_ulong*)(vfpframe+1);
1308}
1309
1310static abi_ulong *setup_sigframe_v2_iwmmxt(abi_ulong *regspace, CPUState *env)
1311{
1312 int i;
1313 struct target_iwmmxt_sigframe *iwmmxtframe;
1314 iwmmxtframe = (struct target_iwmmxt_sigframe *)regspace;
1315 __put_user(TARGET_IWMMXT_MAGIC, &iwmmxtframe->magic);
1316 __put_user(sizeof(*iwmmxtframe), &iwmmxtframe->size);
1317 for (i = 0; i < 16; i++) {
1318 __put_user(env->iwmmxt.regs[i], &iwmmxtframe->regs[i]);
1319 }
1320 __put_user(env->vfp.xregs[ARM_IWMMXT_wCSSF], &iwmmxtframe->wcssf);
1321 __put_user(env->vfp.xregs[ARM_IWMMXT_wCASF], &iwmmxtframe->wcssf);
1322 __put_user(env->vfp.xregs[ARM_IWMMXT_wCGR0], &iwmmxtframe->wcgr0);
1323 __put_user(env->vfp.xregs[ARM_IWMMXT_wCGR1], &iwmmxtframe->wcgr1);
1324 __put_user(env->vfp.xregs[ARM_IWMMXT_wCGR2], &iwmmxtframe->wcgr2);
1325 __put_user(env->vfp.xregs[ARM_IWMMXT_wCGR3], &iwmmxtframe->wcgr3);
1326 return (abi_ulong*)(iwmmxtframe+1);
1327}
1328
1329static void setup_sigframe_v2(struct target_ucontext_v2 *uc,
1330 target_sigset_t *set, CPUState *env)
1331{
1332 struct target_sigaltstack stack;
1333 int i;
1334 abi_ulong *regspace;
1335
1336
1337 memset(uc, 0, offsetof(struct target_ucontext_v2, tuc_mcontext));
1338
1339 memset(&stack, 0, sizeof(stack));
1340 __put_user(target_sigaltstack_used.ss_sp, &stack.ss_sp);
1341 __put_user(target_sigaltstack_used.ss_size, &stack.ss_size);
1342 __put_user(sas_ss_flags(get_sp_from_cpustate(env)), &stack.ss_flags);
1343 memcpy(&uc->tuc_stack, &stack, sizeof(stack));
1344
1345 setup_sigcontext(&uc->tuc_mcontext, env, set->sig[0]);
1346
1347 regspace = uc->tuc_regspace;
1348 if (arm_feature(env, ARM_FEATURE_VFP)) {
1349 regspace = setup_sigframe_v2_vfp(regspace, env);
1350 }
1351 if (arm_feature(env, ARM_FEATURE_IWMMXT)) {
1352 regspace = setup_sigframe_v2_iwmmxt(regspace, env);
1353 }
1354
1355
1356 __put_user(0, regspace);
1357
1358 for(i = 0; i < TARGET_NSIG_WORDS; i++) {
1359 __put_user(set->sig[i], &uc->tuc_sigmask.sig[i]);
1360 }
1361}
1362
1363
1364static void setup_frame_v1(int usig, struct target_sigaction *ka,
1365 target_sigset_t *set, CPUState *regs)
1366{
1367 struct sigframe_v1 *frame;
1368 abi_ulong frame_addr = get_sigframe(ka, regs, sizeof(*frame));
1369 int i;
1370
1371 if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
1372 return;
1373
1374 setup_sigcontext(&frame->sc, regs, set->sig[0]);
1375
1376 for(i = 1; i < TARGET_NSIG_WORDS; i++) {
1377 if (__put_user(set->sig[i], &frame->extramask[i - 1]))
1378 goto end;
1379 }
1380
1381 setup_return(regs, ka, &frame->retcode, frame_addr, usig,
1382 frame_addr + offsetof(struct sigframe_v1, retcode));
1383
1384end:
1385 unlock_user_struct(frame, frame_addr, 1);
1386}
1387
1388static void setup_frame_v2(int usig, struct target_sigaction *ka,
1389 target_sigset_t *set, CPUState *regs)
1390{
1391 struct sigframe_v2 *frame;
1392 abi_ulong frame_addr = get_sigframe(ka, regs, sizeof(*frame));
1393
1394 if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
1395 return;
1396
1397 setup_sigframe_v2(&frame->uc, set, regs);
1398
1399 setup_return(regs, ka, &frame->retcode, frame_addr, usig,
1400 frame_addr + offsetof(struct sigframe_v2, retcode));
1401
1402 unlock_user_struct(frame, frame_addr, 1);
1403}
1404
1405static void setup_frame(int usig, struct target_sigaction *ka,
1406 target_sigset_t *set, CPUState *regs)
1407{
1408 if (get_osversion() >= 0x020612) {
1409 setup_frame_v2(usig, ka, set, regs);
1410 } else {
1411 setup_frame_v1(usig, ka, set, regs);
1412 }
1413}
1414
1415
1416static void setup_rt_frame_v1(int usig, struct target_sigaction *ka,
1417 target_siginfo_t *info,
1418 target_sigset_t *set, CPUState *env)
1419{
1420 struct rt_sigframe_v1 *frame;
1421 abi_ulong frame_addr = get_sigframe(ka, env, sizeof(*frame));
1422 struct target_sigaltstack stack;
1423 int i;
1424 abi_ulong info_addr, uc_addr;
1425
1426 if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
1427 return ;
1428
1429 info_addr = frame_addr + offsetof(struct rt_sigframe_v1, info);
1430 __put_user(info_addr, &frame->pinfo);
1431 uc_addr = frame_addr + offsetof(struct rt_sigframe_v1, uc);
1432 __put_user(uc_addr, &frame->puc);
1433 copy_siginfo_to_user(&frame->info, info);
1434
1435
1436 memset(&frame->uc, 0, offsetof(struct target_ucontext_v1, tuc_mcontext));
1437
1438 memset(&stack, 0, sizeof(stack));
1439 __put_user(target_sigaltstack_used.ss_sp, &stack.ss_sp);
1440 __put_user(target_sigaltstack_used.ss_size, &stack.ss_size);
1441 __put_user(sas_ss_flags(get_sp_from_cpustate(env)), &stack.ss_flags);
1442 memcpy(&frame->uc.tuc_stack, &stack, sizeof(stack));
1443
1444 setup_sigcontext(&frame->uc.tuc_mcontext, env, set->sig[0]);
1445 for(i = 0; i < TARGET_NSIG_WORDS; i++) {
1446 if (__put_user(set->sig[i], &frame->uc.tuc_sigmask.sig[i]))
1447 goto end;
1448 }
1449
1450 setup_return(env, ka, &frame->retcode, frame_addr, usig,
1451 frame_addr + offsetof(struct rt_sigframe_v1, retcode));
1452
1453 env->regs[1] = info_addr;
1454 env->regs[2] = uc_addr;
1455
1456end:
1457 unlock_user_struct(frame, frame_addr, 1);
1458}
1459
1460static void setup_rt_frame_v2(int usig, struct target_sigaction *ka,
1461 target_siginfo_t *info,
1462 target_sigset_t *set, CPUState *env)
1463{
1464 struct rt_sigframe_v2 *frame;
1465 abi_ulong frame_addr = get_sigframe(ka, env, sizeof(*frame));
1466 abi_ulong info_addr, uc_addr;
1467
1468 if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
1469 return ;
1470
1471 info_addr = frame_addr + offsetof(struct rt_sigframe_v2, info);
1472 uc_addr = frame_addr + offsetof(struct rt_sigframe_v2, uc);
1473 copy_siginfo_to_user(&frame->info, info);
1474
1475 setup_sigframe_v2(&frame->uc, set, env);
1476
1477 setup_return(env, ka, &frame->retcode, frame_addr, usig,
1478 frame_addr + offsetof(struct rt_sigframe_v2, retcode));
1479
1480 env->regs[1] = info_addr;
1481 env->regs[2] = uc_addr;
1482
1483 unlock_user_struct(frame, frame_addr, 1);
1484}
1485
1486static void setup_rt_frame(int usig, struct target_sigaction *ka,
1487 target_siginfo_t *info,
1488 target_sigset_t *set, CPUState *env)
1489{
1490 if (get_osversion() >= 0x020612) {
1491 setup_rt_frame_v2(usig, ka, info, set, env);
1492 } else {
1493 setup_rt_frame_v1(usig, ka, info, set, env);
1494 }
1495}
1496
1497static int
1498restore_sigcontext(CPUState *env, struct target_sigcontext *sc)
1499{
1500 int err = 0;
1501 uint32_t cpsr;
1502
1503 __get_user_error(env->regs[0], &sc->arm_r0, err);
1504 __get_user_error(env->regs[1], &sc->arm_r1, err);
1505 __get_user_error(env->regs[2], &sc->arm_r2, err);
1506 __get_user_error(env->regs[3], &sc->arm_r3, err);
1507 __get_user_error(env->regs[4], &sc->arm_r4, err);
1508 __get_user_error(env->regs[5], &sc->arm_r5, err);
1509 __get_user_error(env->regs[6], &sc->arm_r6, err);
1510 __get_user_error(env->regs[7], &sc->arm_r7, err);
1511 __get_user_error(env->regs[8], &sc->arm_r8, err);
1512 __get_user_error(env->regs[9], &sc->arm_r9, err);
1513 __get_user_error(env->regs[10], &sc->arm_r10, err);
1514 __get_user_error(env->regs[11], &sc->arm_fp, err);
1515 __get_user_error(env->regs[12], &sc->arm_ip, err);
1516 __get_user_error(env->regs[13], &sc->arm_sp, err);
1517 __get_user_error(env->regs[14], &sc->arm_lr, err);
1518 __get_user_error(env->regs[15], &sc->arm_pc, err);
1519#ifdef TARGET_CONFIG_CPU_32
1520 __get_user_error(cpsr, &sc->arm_cpsr, err);
1521 cpsr_write(env, cpsr, CPSR_USER | CPSR_EXEC);
1522#endif
1523
1524 err |= !valid_user_regs(env);
1525
1526 return err;
1527}
1528
1529static long do_sigreturn_v1(CPUState *env)
1530{
1531 abi_ulong frame_addr;
1532 struct sigframe_v1 *frame;
1533 target_sigset_t set;
1534 sigset_t host_set;
1535 int i;
1536
1537
1538
1539
1540
1541
1542 if (env->regs[13] & 7)
1543 goto badframe;
1544
1545 frame_addr = env->regs[13];
1546 if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1))
1547 goto badframe;
1548
1549 if (__get_user(set.sig[0], &frame->sc.oldmask))
1550 goto badframe;
1551 for(i = 1; i < TARGET_NSIG_WORDS; i++) {
1552 if (__get_user(set.sig[i], &frame->extramask[i - 1]))
1553 goto badframe;
1554 }
1555
1556 target_to_host_sigset_internal(&host_set, &set);
1557 sigprocmask(SIG_SETMASK, &host_set, NULL);
1558
1559 if (restore_sigcontext(env, &frame->sc))
1560 goto badframe;
1561
1562#if 0
1563
1564 if (ptrace_cancel_bpt(current))
1565 send_sig(SIGTRAP, current, 1);
1566#endif
1567 unlock_user_struct(frame, frame_addr, 0);
1568 return env->regs[0];
1569
1570badframe:
1571 unlock_user_struct(frame, frame_addr, 0);
1572 force_sig(TARGET_SIGSEGV );
1573 return 0;
1574}
1575
1576static abi_ulong *restore_sigframe_v2_vfp(CPUState *env, abi_ulong *regspace)
1577{
1578 int i;
1579 abi_ulong magic, sz;
1580 uint32_t fpscr, fpexc;
1581 struct target_vfp_sigframe *vfpframe;
1582 vfpframe = (struct target_vfp_sigframe *)regspace;
1583
1584 __get_user(magic, &vfpframe->magic);
1585 __get_user(sz, &vfpframe->size);
1586 if (magic != TARGET_VFP_MAGIC || sz != sizeof(*vfpframe)) {
1587 return 0;
1588 }
1589 for (i = 0; i < 32; i++) {
1590 __get_user(float64_val(env->vfp.regs[i]), &vfpframe->ufp.fpregs[i]);
1591 }
1592 __get_user(fpscr, &vfpframe->ufp.fpscr);
1593 vfp_set_fpscr(env, fpscr);
1594 __get_user(fpexc, &vfpframe->ufp_exc.fpexc);
1595
1596
1597
1598 fpexc |= (1 << 30);
1599 fpexc &= ~((1 << 31) | (1 << 28));
1600 env->vfp.xregs[ARM_VFP_FPEXC] = fpexc;
1601 __get_user(env->vfp.xregs[ARM_VFP_FPINST], &vfpframe->ufp_exc.fpinst);
1602 __get_user(env->vfp.xregs[ARM_VFP_FPINST2], &vfpframe->ufp_exc.fpinst2);
1603 return (abi_ulong*)(vfpframe + 1);
1604}
1605
1606static abi_ulong *restore_sigframe_v2_iwmmxt(CPUState *env, abi_ulong *regspace)
1607{
1608 int i;
1609 abi_ulong magic, sz;
1610 struct target_iwmmxt_sigframe *iwmmxtframe;
1611 iwmmxtframe = (struct target_iwmmxt_sigframe *)regspace;
1612
1613 __get_user(magic, &iwmmxtframe->magic);
1614 __get_user(sz, &iwmmxtframe->size);
1615 if (magic != TARGET_IWMMXT_MAGIC || sz != sizeof(*iwmmxtframe)) {
1616 return 0;
1617 }
1618 for (i = 0; i < 16; i++) {
1619 __get_user(env->iwmmxt.regs[i], &iwmmxtframe->regs[i]);
1620 }
1621 __get_user(env->vfp.xregs[ARM_IWMMXT_wCSSF], &iwmmxtframe->wcssf);
1622 __get_user(env->vfp.xregs[ARM_IWMMXT_wCASF], &iwmmxtframe->wcssf);
1623 __get_user(env->vfp.xregs[ARM_IWMMXT_wCGR0], &iwmmxtframe->wcgr0);
1624 __get_user(env->vfp.xregs[ARM_IWMMXT_wCGR1], &iwmmxtframe->wcgr1);
1625 __get_user(env->vfp.xregs[ARM_IWMMXT_wCGR2], &iwmmxtframe->wcgr2);
1626 __get_user(env->vfp.xregs[ARM_IWMMXT_wCGR3], &iwmmxtframe->wcgr3);
1627 return (abi_ulong*)(iwmmxtframe + 1);
1628}
1629
1630static int do_sigframe_return_v2(CPUState *env, target_ulong frame_addr,
1631 struct target_ucontext_v2 *uc)
1632{
1633 sigset_t host_set;
1634 abi_ulong *regspace;
1635
1636 target_to_host_sigset(&host_set, &uc->tuc_sigmask);
1637 sigprocmask(SIG_SETMASK, &host_set, NULL);
1638
1639 if (restore_sigcontext(env, &uc->tuc_mcontext))
1640 return 1;
1641
1642
1643 regspace = uc->tuc_regspace;
1644 if (arm_feature(env, ARM_FEATURE_VFP)) {
1645 regspace = restore_sigframe_v2_vfp(env, regspace);
1646 if (!regspace) {
1647 return 1;
1648 }
1649 }
1650 if (arm_feature(env, ARM_FEATURE_IWMMXT)) {
1651 regspace = restore_sigframe_v2_iwmmxt(env, regspace);
1652 if (!regspace) {
1653 return 1;
1654 }
1655 }
1656
1657 if (do_sigaltstack(frame_addr + offsetof(struct target_ucontext_v2, tuc_stack), 0, get_sp_from_cpustate(env)) == -EFAULT)
1658 return 1;
1659
1660#if 0
1661
1662 if (ptrace_cancel_bpt(current))
1663 send_sig(SIGTRAP, current, 1);
1664#endif
1665
1666 return 0;
1667}
1668
1669static long do_sigreturn_v2(CPUState *env)
1670{
1671 abi_ulong frame_addr;
1672 struct sigframe_v2 *frame;
1673
1674
1675
1676
1677
1678
1679 if (env->regs[13] & 7)
1680 goto badframe;
1681
1682 frame_addr = env->regs[13];
1683 if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1))
1684 goto badframe;
1685
1686 if (do_sigframe_return_v2(env, frame_addr, &frame->uc))
1687 goto badframe;
1688
1689 unlock_user_struct(frame, frame_addr, 0);
1690 return env->regs[0];
1691
1692badframe:
1693 unlock_user_struct(frame, frame_addr, 0);
1694 force_sig(TARGET_SIGSEGV );
1695 return 0;
1696}
1697
1698long do_sigreturn(CPUState *env)
1699{
1700 if (get_osversion() >= 0x020612) {
1701 return do_sigreturn_v2(env);
1702 } else {
1703 return do_sigreturn_v1(env);
1704 }
1705}
1706
1707static long do_rt_sigreturn_v1(CPUState *env)
1708{
1709 abi_ulong frame_addr;
1710 struct rt_sigframe_v1 *frame;
1711 sigset_t host_set;
1712
1713
1714
1715
1716
1717
1718 if (env->regs[13] & 7)
1719 goto badframe;
1720
1721 frame_addr = env->regs[13];
1722 if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1))
1723 goto badframe;
1724
1725 target_to_host_sigset(&host_set, &frame->uc.tuc_sigmask);
1726 sigprocmask(SIG_SETMASK, &host_set, NULL);
1727
1728 if (restore_sigcontext(env, &frame->uc.tuc_mcontext))
1729 goto badframe;
1730
1731 if (do_sigaltstack(frame_addr + offsetof(struct rt_sigframe_v1, uc.tuc_stack), 0, get_sp_from_cpustate(env)) == -EFAULT)
1732 goto badframe;
1733
1734#if 0
1735
1736 if (ptrace_cancel_bpt(current))
1737 send_sig(SIGTRAP, current, 1);
1738#endif
1739 unlock_user_struct(frame, frame_addr, 0);
1740 return env->regs[0];
1741
1742badframe:
1743 unlock_user_struct(frame, frame_addr, 0);
1744 force_sig(TARGET_SIGSEGV );
1745 return 0;
1746}
1747
1748static long do_rt_sigreturn_v2(CPUState *env)
1749{
1750 abi_ulong frame_addr;
1751 struct rt_sigframe_v2 *frame;
1752
1753
1754
1755
1756
1757
1758 if (env->regs[13] & 7)
1759 goto badframe;
1760
1761 frame_addr = env->regs[13];
1762 if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1))
1763 goto badframe;
1764
1765 if (do_sigframe_return_v2(env, frame_addr, &frame->uc))
1766 goto badframe;
1767
1768 unlock_user_struct(frame, frame_addr, 0);
1769 return env->regs[0];
1770
1771badframe:
1772 unlock_user_struct(frame, frame_addr, 0);
1773 force_sig(TARGET_SIGSEGV );
1774 return 0;
1775}
1776
1777long do_rt_sigreturn(CPUState *env)
1778{
1779 if (get_osversion() >= 0x020612) {
1780 return do_rt_sigreturn_v2(env);
1781 } else {
1782 return do_rt_sigreturn_v1(env);
1783 }
1784}
1785
1786#elif defined(TARGET_SPARC)
1787
1788#define __SUNOS_MAXWIN 31
1789
1790
1791struct target_sigcontext {
1792 abi_ulong sigc_onstack;
1793
1794 abi_ulong sigc_mask;
1795 abi_ulong sigc_sp;
1796 abi_ulong sigc_pc;
1797 abi_ulong sigc_npc;
1798 abi_ulong sigc_psr;
1799 abi_ulong sigc_g1;
1800 abi_ulong sigc_o0;
1801
1802
1803
1804
1805 abi_ulong sigc_oswins;
1806
1807
1808 char *sigc_spbuf[__SUNOS_MAXWIN];
1809
1810
1811 struct {
1812 abi_ulong locals[8];
1813 abi_ulong ins[8];
1814 } sigc_wbuf[__SUNOS_MAXWIN];
1815};
1816
1817struct sparc_stackf {
1818 abi_ulong locals[8];
1819 abi_ulong ins[8];
1820
1821
1822
1823 char *structptr;
1824 abi_ulong xargs[6];
1825 abi_ulong xxargs[1];
1826};
1827
1828typedef struct {
1829 struct {
1830 abi_ulong psr;
1831 abi_ulong pc;
1832 abi_ulong npc;
1833 abi_ulong y;
1834 abi_ulong u_regs[16];
1835 } si_regs;
1836 int si_mask;
1837} __siginfo_t;
1838
1839typedef struct {
1840 unsigned long si_float_regs [32];
1841 unsigned long si_fsr;
1842 unsigned long si_fpqdepth;
1843 struct {
1844 unsigned long *insn_addr;
1845 unsigned long insn;
1846 } si_fpqueue [16];
1847} qemu_siginfo_fpu_t;
1848
1849
1850struct target_signal_frame {
1851 struct sparc_stackf ss;
1852 __siginfo_t info;
1853 abi_ulong fpu_save;
1854 abi_ulong insns[2] __attribute__ ((aligned (8)));
1855 abi_ulong extramask[TARGET_NSIG_WORDS - 1];
1856 abi_ulong extra_size;
1857 qemu_siginfo_fpu_t fpu_state;
1858};
1859struct target_rt_signal_frame {
1860 struct sparc_stackf ss;
1861 siginfo_t info;
1862 abi_ulong regs[20];
1863 sigset_t mask;
1864 abi_ulong fpu_save;
1865 unsigned int insns[2];
1866 stack_t stack;
1867 unsigned int extra_size;
1868 qemu_siginfo_fpu_t fpu_state;
1869};
1870
1871#define UREG_O0 16
1872#define UREG_O6 22
1873#define UREG_I0 0
1874#define UREG_I1 1
1875#define UREG_I2 2
1876#define UREG_I3 3
1877#define UREG_I4 4
1878#define UREG_I5 5
1879#define UREG_I6 6
1880#define UREG_I7 7
1881#define UREG_L0 8
1882#define UREG_FP UREG_I6
1883#define UREG_SP UREG_O6
1884
1885static inline abi_ulong get_sigframe(struct target_sigaction *sa,
1886 CPUState *env, unsigned long framesize)
1887{
1888 abi_ulong sp;
1889
1890 sp = env->regwptr[UREG_FP];
1891
1892
1893 if (sa->sa_flags & TARGET_SA_ONSTACK) {
1894 if (!on_sig_stack(sp)
1895 && !((target_sigaltstack_used.ss_sp + target_sigaltstack_used.ss_size) & 7))
1896 sp = target_sigaltstack_used.ss_sp + target_sigaltstack_used.ss_size;
1897 }
1898 return sp - framesize;
1899}
1900
1901static int
1902setup___siginfo(__siginfo_t *si, CPUState *env, abi_ulong mask)
1903{
1904 int err = 0, i;
1905
1906 err |= __put_user(env->psr, &si->si_regs.psr);
1907 err |= __put_user(env->pc, &si->si_regs.pc);
1908 err |= __put_user(env->npc, &si->si_regs.npc);
1909 err |= __put_user(env->y, &si->si_regs.y);
1910 for (i=0; i < 8; i++) {
1911 err |= __put_user(env->gregs[i], &si->si_regs.u_regs[i]);
1912 }
1913 for (i=0; i < 8; i++) {
1914 err |= __put_user(env->regwptr[UREG_I0 + i], &si->si_regs.u_regs[i+8]);
1915 }
1916 err |= __put_user(mask, &si->si_mask);
1917 return err;
1918}
1919
1920#if 0
1921static int
1922setup_sigcontext(struct target_sigcontext *sc,
1923 CPUState *env, unsigned long mask)
1924{
1925 int err = 0;
1926
1927 err |= __put_user(mask, &sc->sigc_mask);
1928 err |= __put_user(env->regwptr[UREG_SP], &sc->sigc_sp);
1929 err |= __put_user(env->pc, &sc->sigc_pc);
1930 err |= __put_user(env->npc, &sc->sigc_npc);
1931 err |= __put_user(env->psr, &sc->sigc_psr);
1932 err |= __put_user(env->gregs[1], &sc->sigc_g1);
1933 err |= __put_user(env->regwptr[UREG_O0], &sc->sigc_o0);
1934
1935 return err;
1936}
1937#endif
1938#define NF_ALIGNEDSZ (((sizeof(struct target_signal_frame) + 7) & (~7)))
1939
1940static void setup_frame(int sig, struct target_sigaction *ka,
1941 target_sigset_t *set, CPUState *env)
1942{
1943 abi_ulong sf_addr;
1944 struct target_signal_frame *sf;
1945 int sigframe_size, err, i;
1946
1947
1948
1949
1950 sigframe_size = NF_ALIGNEDSZ;
1951 sf_addr = get_sigframe(ka, env, sigframe_size);
1952
1953 sf = lock_user(VERIFY_WRITE, sf_addr,
1954 sizeof(struct target_signal_frame), 0);
1955 if (!sf)
1956 goto sigsegv;
1957
1958
1959#if 0
1960 if (invalid_frame_pointer(sf, sigframe_size))
1961 goto sigill_and_return;
1962#endif
1963
1964 err = setup___siginfo(&sf->info, env, set->sig[0]);
1965 err |= __put_user(0, &sf->extra_size);
1966
1967
1968
1969
1970 err |= __put_user(set->sig[0], &sf->info.si_mask);
1971 for (i = 0; i < TARGET_NSIG_WORDS - 1; i++) {
1972 err |= __put_user(set->sig[i + 1], &sf->extramask[i]);
1973 }
1974
1975 for (i = 0; i < 8; i++) {
1976 err |= __put_user(env->regwptr[i + UREG_L0], &sf->ss.locals[i]);
1977 }
1978 for (i = 0; i < 8; i++) {
1979 err |= __put_user(env->regwptr[i + UREG_I0], &sf->ss.ins[i]);
1980 }
1981 if (err)
1982 goto sigsegv;
1983
1984
1985 env->regwptr[UREG_FP] = sf_addr;
1986 env->regwptr[UREG_I0] = sig;
1987 env->regwptr[UREG_I1] = sf_addr +
1988 offsetof(struct target_signal_frame, info);
1989 env->regwptr[UREG_I2] = sf_addr +
1990 offsetof(struct target_signal_frame, info);
1991
1992
1993 env->pc = ka->_sa_handler;
1994 env->npc = (env->pc + 4);
1995
1996 if (ka->sa_restorer)
1997 env->regwptr[UREG_I7] = ka->sa_restorer;
1998 else {
1999 uint32_t val32;
2000
2001 env->regwptr[UREG_I7] = sf_addr +
2002 offsetof(struct target_signal_frame, insns) - 2 * 4;
2003
2004
2005 val32 = 0x821020d8;
2006 err |= __put_user(val32, &sf->insns[0]);
2007
2008
2009 val32 = 0x91d02010;
2010 err |= __put_user(val32, &sf->insns[1]);
2011 if (err)
2012 goto sigsegv;
2013
2014
2015
2016
2017 }
2018 unlock_user(sf, sf_addr, sizeof(struct target_signal_frame));
2019 return;
2020#if 0
2021sigill_and_return:
2022 force_sig(TARGET_SIGILL);
2023#endif
2024sigsegv:
2025
2026 unlock_user(sf, sf_addr, sizeof(struct target_signal_frame));
2027 force_sig(TARGET_SIGSEGV);
2028}
2029static inline int
2030restore_fpu_state(CPUState *env, qemu_siginfo_fpu_t *fpu)
2031{
2032 int err;
2033#if 0
2034#ifdef CONFIG_SMP
2035 if (current->flags & PF_USEDFPU)
2036 regs->psr &= ~PSR_EF;
2037#else
2038 if (current == last_task_used_math) {
2039 last_task_used_math = 0;
2040 regs->psr &= ~PSR_EF;
2041 }
2042#endif
2043 current->used_math = 1;
2044 current->flags &= ~PF_USEDFPU;
2045#endif
2046#if 0
2047 if (verify_area (VERIFY_READ, fpu, sizeof(*fpu)))
2048 return -EFAULT;
2049#endif
2050
2051#if 0
2052
2053 err = __copy_from_user(&env->fpr[0], &fpu->si_float_regs[0],
2054 (sizeof(unsigned long) * 32));
2055#endif
2056 err |= __get_user(env->fsr, &fpu->si_fsr);
2057#if 0
2058 err |= __get_user(current->thread.fpqdepth, &fpu->si_fpqdepth);
2059 if (current->thread.fpqdepth != 0)
2060 err |= __copy_from_user(¤t->thread.fpqueue[0],
2061 &fpu->si_fpqueue[0],
2062 ((sizeof(unsigned long) +
2063 (sizeof(unsigned long *)))*16));
2064#endif
2065 return err;
2066}
2067
2068
2069static void setup_rt_frame(int sig, struct target_sigaction *ka,
2070 target_siginfo_t *info,
2071 target_sigset_t *set, CPUState *env)
2072{
2073 fprintf(stderr, "setup_rt_frame: not implemented\n");
2074}
2075
2076long do_sigreturn(CPUState *env)
2077{
2078 abi_ulong sf_addr;
2079 struct target_signal_frame *sf;
2080 uint32_t up_psr, pc, npc;
2081 target_sigset_t set;
2082 sigset_t host_set;
2083 int err, i;
2084
2085 sf_addr = env->regwptr[UREG_FP];
2086 if (!lock_user_struct(VERIFY_READ, sf, sf_addr, 1))
2087 goto segv_and_exit;
2088#if 0
2089 fprintf(stderr, "sigreturn\n");
2090 fprintf(stderr, "sf: %x pc %x fp %x sp %x\n", sf, env->pc, env->regwptr[UREG_FP], env->regwptr[UREG_SP]);
2091#endif
2092
2093
2094
2095
2096 if (sf_addr & 3)
2097 goto segv_and_exit;
2098
2099 err = __get_user(pc, &sf->info.si_regs.pc);
2100 err |= __get_user(npc, &sf->info.si_regs.npc);
2101
2102 if ((pc | npc) & 3)
2103 goto segv_and_exit;
2104
2105
2106 err |= __get_user(up_psr, &sf->info.si_regs.psr);
2107
2108
2109 env->psr = (up_psr & (PSR_ICC ))
2110 | (env->psr & ~(PSR_ICC ));
2111
2112 env->pc = pc;
2113 env->npc = npc;
2114 err |= __get_user(env->y, &sf->info.si_regs.y);
2115 for (i=0; i < 8; i++) {
2116 err |= __get_user(env->gregs[i], &sf->info.si_regs.u_regs[i]);
2117 }
2118 for (i=0; i < 8; i++) {
2119 err |= __get_user(env->regwptr[i + UREG_I0], &sf->info.si_regs.u_regs[i+8]);
2120 }
2121
2122
2123
2124
2125
2126
2127
2128
2129
2130
2131 err |= __get_user(set.sig[0], &sf->info.si_mask);
2132 for(i = 1; i < TARGET_NSIG_WORDS; i++) {
2133 err |= (__get_user(set.sig[i], &sf->extramask[i - 1]));
2134 }
2135
2136 target_to_host_sigset_internal(&host_set, &set);
2137 sigprocmask(SIG_SETMASK, &host_set, NULL);
2138
2139 if (err)
2140 goto segv_and_exit;
2141 unlock_user_struct(sf, sf_addr, 0);
2142 return env->regwptr[0];
2143
2144segv_and_exit:
2145 unlock_user_struct(sf, sf_addr, 0);
2146 force_sig(TARGET_SIGSEGV);
2147}
2148
2149long do_rt_sigreturn(CPUState *env)
2150{
2151 fprintf(stderr, "do_rt_sigreturn: not implemented\n");
2152 return -TARGET_ENOSYS;
2153}
2154
2155#if defined(TARGET_SPARC64) && !defined(TARGET_ABI32)
2156#define MC_TSTATE 0
2157#define MC_PC 1
2158#define MC_NPC 2
2159#define MC_Y 3
2160#define MC_G1 4
2161#define MC_G2 5
2162#define MC_G3 6
2163#define MC_G4 7
2164#define MC_G5 8
2165#define MC_G6 9
2166#define MC_G7 10
2167#define MC_O0 11
2168#define MC_O1 12
2169#define MC_O2 13
2170#define MC_O3 14
2171#define MC_O4 15
2172#define MC_O5 16
2173#define MC_O6 17
2174#define MC_O7 18
2175#define MC_NGREG 19
2176
2177typedef abi_ulong target_mc_greg_t;
2178typedef target_mc_greg_t target_mc_gregset_t[MC_NGREG];
2179
2180struct target_mc_fq {
2181 abi_ulong *mcfq_addr;
2182 uint32_t mcfq_insn;
2183};
2184
2185struct target_mc_fpu {
2186 union {
2187 uint32_t sregs[32];
2188 uint64_t dregs[32];
2189
2190 } mcfpu_fregs;
2191 abi_ulong mcfpu_fsr;
2192 abi_ulong mcfpu_fprs;
2193 abi_ulong mcfpu_gsr;
2194 struct target_mc_fq *mcfpu_fq;
2195 unsigned char mcfpu_qcnt;
2196 unsigned char mcfpu_qentsz;
2197 unsigned char mcfpu_enab;
2198};
2199typedef struct target_mc_fpu target_mc_fpu_t;
2200
2201typedef struct {
2202 target_mc_gregset_t mc_gregs;
2203 target_mc_greg_t mc_fp;
2204 target_mc_greg_t mc_i7;
2205 target_mc_fpu_t mc_fpregs;
2206} target_mcontext_t;
2207
2208struct target_ucontext {
2209 struct target_ucontext *tuc_link;
2210 abi_ulong tuc_flags;
2211 target_sigset_t tuc_sigmask;
2212 target_mcontext_t tuc_mcontext;
2213};
2214
2215
2216struct target_reg_window {
2217 abi_ulong locals[8];
2218 abi_ulong ins[8];
2219};
2220
2221#define TARGET_STACK_BIAS 2047
2222
2223
2224void sparc64_set_context(CPUSPARCState *env)
2225{
2226 abi_ulong ucp_addr;
2227 struct target_ucontext *ucp;
2228 target_mc_gregset_t *grp;
2229 abi_ulong pc, npc, tstate;
2230 abi_ulong fp, i7, w_addr;
2231 int err;
2232 unsigned int i;
2233
2234 ucp_addr = env->regwptr[UREG_I0];
2235 if (!lock_user_struct(VERIFY_READ, ucp, ucp_addr, 1))
2236 goto do_sigsegv;
2237 grp = &ucp->tuc_mcontext.mc_gregs;
2238 err = __get_user(pc, &((*grp)[MC_PC]));
2239 err |= __get_user(npc, &((*grp)[MC_NPC]));
2240 if (err || ((pc | npc) & 3))
2241 goto do_sigsegv;
2242 if (env->regwptr[UREG_I1]) {
2243 target_sigset_t target_set;
2244 sigset_t set;
2245
2246 if (TARGET_NSIG_WORDS == 1) {
2247 if (__get_user(target_set.sig[0], &ucp->tuc_sigmask.sig[0]))
2248 goto do_sigsegv;
2249 } else {
2250 abi_ulong *src, *dst;
2251 src = ucp->tuc_sigmask.sig;
2252 dst = target_set.sig;
2253 for (i = 0; i < sizeof(target_sigset_t) / sizeof(abi_ulong);
2254 i++, dst++, src++)
2255 err |= __get_user(*dst, src);
2256 if (err)
2257 goto do_sigsegv;
2258 }
2259 target_to_host_sigset_internal(&set, &target_set);
2260 sigprocmask(SIG_SETMASK, &set, NULL);
2261 }
2262 env->pc = pc;
2263 env->npc = npc;
2264 err |= __get_user(env->y, &((*grp)[MC_Y]));
2265 err |= __get_user(tstate, &((*grp)[MC_TSTATE]));
2266 env->asi = (tstate >> 24) & 0xff;
2267 cpu_put_ccr(env, tstate >> 32);
2268 cpu_put_cwp64(env, tstate & 0x1f);
2269 err |= __get_user(env->gregs[1], (&(*grp)[MC_G1]));
2270 err |= __get_user(env->gregs[2], (&(*grp)[MC_G2]));
2271 err |= __get_user(env->gregs[3], (&(*grp)[MC_G3]));
2272 err |= __get_user(env->gregs[4], (&(*grp)[MC_G4]));
2273 err |= __get_user(env->gregs[5], (&(*grp)[MC_G5]));
2274 err |= __get_user(env->gregs[6], (&(*grp)[MC_G6]));
2275 err |= __get_user(env->gregs[7], (&(*grp)[MC_G7]));
2276 err |= __get_user(env->regwptr[UREG_I0], (&(*grp)[MC_O0]));
2277 err |= __get_user(env->regwptr[UREG_I1], (&(*grp)[MC_O1]));
2278 err |= __get_user(env->regwptr[UREG_I2], (&(*grp)[MC_O2]));
2279 err |= __get_user(env->regwptr[UREG_I3], (&(*grp)[MC_O3]));
2280 err |= __get_user(env->regwptr[UREG_I4], (&(*grp)[MC_O4]));
2281 err |= __get_user(env->regwptr[UREG_I5], (&(*grp)[MC_O5]));
2282 err |= __get_user(env->regwptr[UREG_I6], (&(*grp)[MC_O6]));
2283 err |= __get_user(env->regwptr[UREG_I7], (&(*grp)[MC_O7]));
2284
2285 err |= __get_user(fp, &(ucp->tuc_mcontext.mc_fp));
2286 err |= __get_user(i7, &(ucp->tuc_mcontext.mc_i7));
2287
2288 w_addr = TARGET_STACK_BIAS+env->regwptr[UREG_I6];
2289 if (put_user(fp, w_addr + offsetof(struct target_reg_window, ins[6]),
2290 abi_ulong) != 0)
2291 goto do_sigsegv;
2292 if (put_user(i7, w_addr + offsetof(struct target_reg_window, ins[7]),
2293 abi_ulong) != 0)
2294 goto do_sigsegv;
2295
2296
2297
2298
2299
2300 err |= __get_user(env->fprs, &(ucp->tuc_mcontext.mc_fpregs.mcfpu_fprs));
2301 {
2302 uint32_t *src, *dst;
2303 src = ucp->tuc_mcontext.mc_fpregs.mcfpu_fregs.sregs;
2304 dst = env->fpr;
2305
2306 for (i = 0; i < 64; i++, dst++, src++)
2307 err |= __get_user(*dst, src);
2308 }
2309 err |= __get_user(env->fsr,
2310 &(ucp->tuc_mcontext.mc_fpregs.mcfpu_fsr));
2311 err |= __get_user(env->gsr,
2312 &(ucp->tuc_mcontext.mc_fpregs.mcfpu_gsr));
2313 if (err)
2314 goto do_sigsegv;
2315 unlock_user_struct(ucp, ucp_addr, 0);
2316 return;
2317 do_sigsegv:
2318 unlock_user_struct(ucp, ucp_addr, 0);
2319 force_sig(TARGET_SIGSEGV);
2320}
2321
2322void sparc64_get_context(CPUSPARCState *env)
2323{
2324 abi_ulong ucp_addr;
2325 struct target_ucontext *ucp;
2326 target_mc_gregset_t *grp;
2327 target_mcontext_t *mcp;
2328 abi_ulong fp, i7, w_addr;
2329 int err;
2330 unsigned int i;
2331 target_sigset_t target_set;
2332 sigset_t set;
2333
2334 ucp_addr = env->regwptr[UREG_I0];
2335 if (!lock_user_struct(VERIFY_WRITE, ucp, ucp_addr, 0))
2336 goto do_sigsegv;
2337
2338 mcp = &ucp->tuc_mcontext;
2339 grp = &mcp->mc_gregs;
2340
2341
2342 env->pc = env->npc;
2343 env->npc += 4;
2344
2345 err = 0;
2346
2347 sigprocmask(0, NULL, &set);
2348 host_to_target_sigset_internal(&target_set, &set);
2349 if (TARGET_NSIG_WORDS == 1) {
2350 err |= __put_user(target_set.sig[0],
2351 (abi_ulong *)&ucp->tuc_sigmask);
2352 } else {
2353 abi_ulong *src, *dst;
2354 src = target_set.sig;
2355 dst = ucp->tuc_sigmask.sig;
2356 for (i = 0; i < sizeof(target_sigset_t) / sizeof(abi_ulong);
2357 i++, dst++, src++)
2358 err |= __put_user(*src, dst);
2359 if (err)
2360 goto do_sigsegv;
2361 }
2362
2363
2364
2365 err |= __put_user(env->pc, &((*grp)[MC_PC]));
2366 err |= __put_user(env->npc, &((*grp)[MC_NPC]));
2367 err |= __put_user(env->y, &((*grp)[MC_Y]));
2368 err |= __put_user(env->gregs[1], &((*grp)[MC_G1]));
2369 err |= __put_user(env->gregs[2], &((*grp)[MC_G2]));
2370 err |= __put_user(env->gregs[3], &((*grp)[MC_G3]));
2371 err |= __put_user(env->gregs[4], &((*grp)[MC_G4]));
2372 err |= __put_user(env->gregs[5], &((*grp)[MC_G5]));
2373 err |= __put_user(env->gregs[6], &((*grp)[MC_G6]));
2374 err |= __put_user(env->gregs[7], &((*grp)[MC_G7]));
2375 err |= __put_user(env->regwptr[UREG_I0], &((*grp)[MC_O0]));
2376 err |= __put_user(env->regwptr[UREG_I1], &((*grp)[MC_O1]));
2377 err |= __put_user(env->regwptr[UREG_I2], &((*grp)[MC_O2]));
2378 err |= __put_user(env->regwptr[UREG_I3], &((*grp)[MC_O3]));
2379 err |= __put_user(env->regwptr[UREG_I4], &((*grp)[MC_O4]));
2380 err |= __put_user(env->regwptr[UREG_I5], &((*grp)[MC_O5]));
2381 err |= __put_user(env->regwptr[UREG_I6], &((*grp)[MC_O6]));
2382 err |= __put_user(env->regwptr[UREG_I7], &((*grp)[MC_O7]));
2383
2384 w_addr = TARGET_STACK_BIAS+env->regwptr[UREG_I6];
2385 fp = i7 = 0;
2386 if (get_user(fp, w_addr + offsetof(struct target_reg_window, ins[6]),
2387 abi_ulong) != 0)
2388 goto do_sigsegv;
2389 if (get_user(i7, w_addr + offsetof(struct target_reg_window, ins[7]),
2390 abi_ulong) != 0)
2391 goto do_sigsegv;
2392 err |= __put_user(fp, &(mcp->mc_fp));
2393 err |= __put_user(i7, &(mcp->mc_i7));
2394
2395 {
2396 uint32_t *src, *dst;
2397 src = env->fpr;
2398 dst = ucp->tuc_mcontext.mc_fpregs.mcfpu_fregs.sregs;
2399
2400 for (i = 0; i < 64; i++, dst++, src++)
2401 err |= __put_user(*src, dst);
2402 }
2403 err |= __put_user(env->fsr, &(mcp->mc_fpregs.mcfpu_fsr));
2404 err |= __put_user(env->gsr, &(mcp->mc_fpregs.mcfpu_gsr));
2405 err |= __put_user(env->fprs, &(mcp->mc_fpregs.mcfpu_fprs));
2406
2407 if (err)
2408 goto do_sigsegv;
2409 unlock_user_struct(ucp, ucp_addr, 1);
2410 return;
2411 do_sigsegv:
2412 unlock_user_struct(ucp, ucp_addr, 1);
2413 force_sig(TARGET_SIGSEGV);
2414}
2415#endif
2416#elif defined(TARGET_ABI_MIPSN64)
2417
2418# warning signal handling not implemented
2419
2420static void setup_frame(int sig, struct target_sigaction *ka,
2421 target_sigset_t *set, CPUState *env)
2422{
2423 fprintf(stderr, "setup_frame: not implemented\n");
2424}
2425
2426static void setup_rt_frame(int sig, struct target_sigaction *ka,
2427 target_siginfo_t *info,
2428 target_sigset_t *set, CPUState *env)
2429{
2430 fprintf(stderr, "setup_rt_frame: not implemented\n");
2431}
2432
2433long do_sigreturn(CPUState *env)
2434{
2435 fprintf(stderr, "do_sigreturn: not implemented\n");
2436 return -TARGET_ENOSYS;
2437}
2438
2439long do_rt_sigreturn(CPUState *env)
2440{
2441 fprintf(stderr, "do_rt_sigreturn: not implemented\n");
2442 return -TARGET_ENOSYS;
2443}
2444
2445#elif defined(TARGET_ABI_MIPSN32)
2446
2447# warning signal handling not implemented
2448
2449static void setup_frame(int sig, struct target_sigaction *ka,
2450 target_sigset_t *set, CPUState *env)
2451{
2452 fprintf(stderr, "setup_frame: not implemented\n");
2453}
2454
2455static void setup_rt_frame(int sig, struct target_sigaction *ka,
2456 target_siginfo_t *info,
2457 target_sigset_t *set, CPUState *env)
2458{
2459 fprintf(stderr, "setup_rt_frame: not implemented\n");
2460}
2461
2462long do_sigreturn(CPUState *env)
2463{
2464 fprintf(stderr, "do_sigreturn: not implemented\n");
2465 return -TARGET_ENOSYS;
2466}
2467
2468long do_rt_sigreturn(CPUState *env)
2469{
2470 fprintf(stderr, "do_rt_sigreturn: not implemented\n");
2471 return -TARGET_ENOSYS;
2472}
2473
2474#elif defined(TARGET_ABI_MIPSO32)
2475
2476struct target_sigcontext {
2477 uint32_t sc_regmask;
2478 uint32_t sc_status;
2479 uint64_t sc_pc;
2480 uint64_t sc_regs[32];
2481 uint64_t sc_fpregs[32];
2482 uint32_t sc_ownedfp;
2483 uint32_t sc_fpc_csr;
2484 uint32_t sc_fpc_eir;
2485 uint32_t sc_used_math;
2486 uint32_t sc_dsp;
2487 uint32_t pad0;
2488 uint64_t sc_mdhi;
2489 uint64_t sc_mdlo;
2490 target_ulong sc_hi1;
2491 target_ulong sc_lo1;
2492 target_ulong sc_hi2;
2493 target_ulong sc_lo2;
2494 target_ulong sc_hi3;
2495 target_ulong sc_lo3;
2496};
2497
2498struct sigframe {
2499 uint32_t sf_ass[4];
2500 uint32_t sf_code[2];
2501 struct target_sigcontext sf_sc;
2502 target_sigset_t sf_mask;
2503};
2504
2505struct target_ucontext {
2506 target_ulong tuc_flags;
2507 target_ulong tuc_link;
2508 target_stack_t tuc_stack;
2509 target_ulong pad0;
2510 struct target_sigcontext tuc_mcontext;
2511 target_sigset_t tuc_sigmask;
2512};
2513
2514struct target_rt_sigframe {
2515 uint32_t rs_ass[4];
2516 uint32_t rs_code[2];
2517 struct target_siginfo rs_info;
2518 struct target_ucontext rs_uc;
2519};
2520
2521
2522static inline int install_sigtramp(unsigned int *tramp, unsigned int syscall)
2523{
2524 int err;
2525
2526
2527
2528
2529
2530
2531
2532
2533 err = __put_user(0x24020000 + syscall, tramp + 0);
2534 err |= __put_user(0x0000000c , tramp + 1);
2535
2536 return err;
2537}
2538
2539static inline int
2540setup_sigcontext(CPUState *regs, struct target_sigcontext *sc)
2541{
2542 int err = 0;
2543
2544 err |= __put_user(regs->active_tc.PC, &sc->sc_pc);
2545
2546#define save_gp_reg(i) do { \
2547 err |= __put_user(regs->active_tc.gpr[i], &sc->sc_regs[i]); \
2548 } while(0)
2549 __put_user(0, &sc->sc_regs[0]); save_gp_reg(1); save_gp_reg(2);
2550 save_gp_reg(3); save_gp_reg(4); save_gp_reg(5); save_gp_reg(6);
2551 save_gp_reg(7); save_gp_reg(8); save_gp_reg(9); save_gp_reg(10);
2552 save_gp_reg(11); save_gp_reg(12); save_gp_reg(13); save_gp_reg(14);
2553 save_gp_reg(15); save_gp_reg(16); save_gp_reg(17); save_gp_reg(18);
2554 save_gp_reg(19); save_gp_reg(20); save_gp_reg(21); save_gp_reg(22);
2555 save_gp_reg(23); save_gp_reg(24); save_gp_reg(25); save_gp_reg(26);
2556 save_gp_reg(27); save_gp_reg(28); save_gp_reg(29); save_gp_reg(30);
2557 save_gp_reg(31);
2558#undef save_gp_reg
2559
2560 err |= __put_user(regs->active_tc.HI[0], &sc->sc_mdhi);
2561 err |= __put_user(regs->active_tc.LO[0], &sc->sc_mdlo);
2562
2563
2564#if 0
2565 if (cpu_has_dsp) {
2566 err |= __put_user(mfhi1(), &sc->sc_hi1);
2567 err |= __put_user(mflo1(), &sc->sc_lo1);
2568 err |= __put_user(mfhi2(), &sc->sc_hi2);
2569 err |= __put_user(mflo2(), &sc->sc_lo2);
2570 err |= __put_user(mfhi3(), &sc->sc_hi3);
2571 err |= __put_user(mflo3(), &sc->sc_lo3);
2572 err |= __put_user(rddsp(DSP_MASK), &sc->sc_dsp);
2573 }
2574
2575#ifdef CONFIG_64BIT
2576 err |= __put_user(regs->hi, &sc->sc_hi[0]);
2577 err |= __put_user(regs->lo, &sc->sc_lo[0]);
2578 if (cpu_has_dsp) {
2579 err |= __put_user(mfhi1(), &sc->sc_hi[1]);
2580 err |= __put_user(mflo1(), &sc->sc_lo[1]);
2581 err |= __put_user(mfhi2(), &sc->sc_hi[2]);
2582 err |= __put_user(mflo2(), &sc->sc_lo[2]);
2583 err |= __put_user(mfhi3(), &sc->sc_hi[3]);
2584 err |= __put_user(mflo3(), &sc->sc_lo[3]);
2585 err |= __put_user(rddsp(DSP_MASK), &sc->sc_dsp);
2586 }
2587#endif
2588#endif
2589
2590#if 0
2591 err |= __put_user(!!used_math(), &sc->sc_used_math);
2592
2593 if (!used_math())
2594 goto out;
2595
2596
2597
2598
2599
2600 preempt_disable();
2601
2602 if (!is_fpu_owner()) {
2603 own_fpu();
2604 restore_fp(current);
2605 }
2606 err |= save_fp_context(sc);
2607
2608 preempt_enable();
2609 out:
2610#endif
2611 return err;
2612}
2613
2614static inline int
2615restore_sigcontext(CPUState *regs, struct target_sigcontext *sc)
2616{
2617 int err = 0;
2618
2619 err |= __get_user(regs->CP0_EPC, &sc->sc_pc);
2620
2621 err |= __get_user(regs->active_tc.HI[0], &sc->sc_mdhi);
2622 err |= __get_user(regs->active_tc.LO[0], &sc->sc_mdlo);
2623
2624#define restore_gp_reg(i) do { \
2625 err |= __get_user(regs->active_tc.gpr[i], &sc->sc_regs[i]); \
2626 } while(0)
2627 restore_gp_reg( 1); restore_gp_reg( 2); restore_gp_reg( 3);
2628 restore_gp_reg( 4); restore_gp_reg( 5); restore_gp_reg( 6);
2629 restore_gp_reg( 7); restore_gp_reg( 8); restore_gp_reg( 9);
2630 restore_gp_reg(10); restore_gp_reg(11); restore_gp_reg(12);
2631 restore_gp_reg(13); restore_gp_reg(14); restore_gp_reg(15);
2632 restore_gp_reg(16); restore_gp_reg(17); restore_gp_reg(18);
2633 restore_gp_reg(19); restore_gp_reg(20); restore_gp_reg(21);
2634 restore_gp_reg(22); restore_gp_reg(23); restore_gp_reg(24);
2635 restore_gp_reg(25); restore_gp_reg(26); restore_gp_reg(27);
2636 restore_gp_reg(28); restore_gp_reg(29); restore_gp_reg(30);
2637 restore_gp_reg(31);
2638#undef restore_gp_reg
2639
2640#if 0
2641 if (cpu_has_dsp) {
2642 err |= __get_user(treg, &sc->sc_hi1); mthi1(treg);
2643 err |= __get_user(treg, &sc->sc_lo1); mtlo1(treg);
2644 err |= __get_user(treg, &sc->sc_hi2); mthi2(treg);
2645 err |= __get_user(treg, &sc->sc_lo2); mtlo2(treg);
2646 err |= __get_user(treg, &sc->sc_hi3); mthi3(treg);
2647 err |= __get_user(treg, &sc->sc_lo3); mtlo3(treg);
2648 err |= __get_user(treg, &sc->sc_dsp); wrdsp(treg, DSP_MASK);
2649 }
2650#ifdef CONFIG_64BIT
2651 err |= __get_user(regs->hi, &sc->sc_hi[0]);
2652 err |= __get_user(regs->lo, &sc->sc_lo[0]);
2653 if (cpu_has_dsp) {
2654 err |= __get_user(treg, &sc->sc_hi[1]); mthi1(treg);
2655 err |= __get_user(treg, &sc->sc_lo[1]); mthi1(treg);
2656 err |= __get_user(treg, &sc->sc_hi[2]); mthi2(treg);
2657 err |= __get_user(treg, &sc->sc_lo[2]); mthi2(treg);
2658 err |= __get_user(treg, &sc->sc_hi[3]); mthi3(treg);
2659 err |= __get_user(treg, &sc->sc_lo[3]); mthi3(treg);
2660 err |= __get_user(treg, &sc->sc_dsp); wrdsp(treg, DSP_MASK);
2661 }
2662#endif
2663
2664 err |= __get_user(used_math, &sc->sc_used_math);
2665 conditional_used_math(used_math);
2666
2667 preempt_disable();
2668
2669 if (used_math()) {
2670
2671 own_fpu();
2672 err |= restore_fp_context(sc);
2673 } else {
2674
2675 lose_fpu();
2676 }
2677
2678 preempt_enable();
2679#endif
2680 return err;
2681}
2682
2683
2684
2685static inline abi_ulong
2686get_sigframe(struct target_sigaction *ka, CPUState *regs, size_t frame_size)
2687{
2688 unsigned long sp;
2689
2690
2691 sp = regs->active_tc.gpr[29];
2692
2693
2694
2695
2696
2697
2698 sp -= 32;
2699
2700
2701 if ((ka->sa_flags & TARGET_SA_ONSTACK) && (sas_ss_flags (sp) == 0)) {
2702 sp = target_sigaltstack_used.ss_sp + target_sigaltstack_used.ss_size;
2703 }
2704
2705 return (sp - frame_size) & ~7;
2706}
2707
2708
2709static void setup_frame(int sig, struct target_sigaction * ka,
2710 target_sigset_t *set, CPUState *regs)
2711{
2712 struct sigframe *frame;
2713 abi_ulong frame_addr;
2714 int i;
2715
2716 frame_addr = get_sigframe(ka, regs, sizeof(*frame));
2717 if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
2718 goto give_sigsegv;
2719
2720 install_sigtramp(frame->sf_code, TARGET_NR_sigreturn);
2721
2722 if(setup_sigcontext(regs, &frame->sf_sc))
2723 goto give_sigsegv;
2724
2725 for(i = 0; i < TARGET_NSIG_WORDS; i++) {
2726 if(__put_user(set->sig[i], &frame->sf_mask.sig[i]))
2727 goto give_sigsegv;
2728 }
2729
2730
2731
2732
2733
2734
2735
2736
2737
2738
2739
2740 regs->active_tc.gpr[ 4] = sig;
2741 regs->active_tc.gpr[ 5] = 0;
2742 regs->active_tc.gpr[ 6] = frame_addr + offsetof(struct sigframe, sf_sc);
2743 regs->active_tc.gpr[29] = frame_addr;
2744 regs->active_tc.gpr[31] = frame_addr + offsetof(struct sigframe, sf_code);
2745
2746
2747
2748 regs->active_tc.PC = regs->active_tc.gpr[25] = ka->_sa_handler;
2749 unlock_user_struct(frame, frame_addr, 1);
2750 return;
2751
2752give_sigsegv:
2753 unlock_user_struct(frame, frame_addr, 1);
2754 force_sig(TARGET_SIGSEGV);
2755 return;
2756}
2757
2758long do_sigreturn(CPUState *regs)
2759{
2760 struct sigframe *frame;
2761 abi_ulong frame_addr;
2762 sigset_t blocked;
2763 target_sigset_t target_set;
2764 int i;
2765
2766#if defined(DEBUG_SIGNAL)
2767 fprintf(stderr, "do_sigreturn\n");
2768#endif
2769 frame_addr = regs->active_tc.gpr[29];
2770 if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1))
2771 goto badframe;
2772
2773 for(i = 0; i < TARGET_NSIG_WORDS; i++) {
2774 if(__get_user(target_set.sig[i], &frame->sf_mask.sig[i]))
2775 goto badframe;
2776 }
2777
2778 target_to_host_sigset_internal(&blocked, &target_set);
2779 sigprocmask(SIG_SETMASK, &blocked, NULL);
2780
2781 if (restore_sigcontext(regs, &frame->sf_sc))
2782 goto badframe;
2783
2784#if 0
2785
2786
2787
2788 __asm__ __volatile__(
2789 "move\t$29, %0\n\t"
2790 "j\tsyscall_exit"
2791 :
2792 :"r" (®s));
2793
2794#endif
2795
2796 regs->active_tc.PC = regs->CP0_EPC;
2797
2798
2799 regs->CP0_EPC = 0;
2800 return -TARGET_QEMU_ESIGRETURN;
2801
2802badframe:
2803 force_sig(TARGET_SIGSEGV);
2804 return 0;
2805}
2806
2807static void setup_rt_frame(int sig, struct target_sigaction *ka,
2808 target_siginfo_t *info,
2809 target_sigset_t *set, CPUState *env)
2810{
2811 struct target_rt_sigframe *frame;
2812 abi_ulong frame_addr;
2813 int i;
2814
2815 frame_addr = get_sigframe(ka, env, sizeof(*frame));
2816 if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
2817 goto give_sigsegv;
2818
2819 install_sigtramp(frame->rs_code, TARGET_NR_rt_sigreturn);
2820
2821 copy_siginfo_to_user(&frame->rs_info, info);
2822
2823 __put_user(0, &frame->rs_uc.tuc_flags);
2824 __put_user(0, &frame->rs_uc.tuc_link);
2825 __put_user(target_sigaltstack_used.ss_sp, &frame->rs_uc.tuc_stack.ss_sp);
2826 __put_user(target_sigaltstack_used.ss_size, &frame->rs_uc.tuc_stack.ss_size);
2827 __put_user(sas_ss_flags(get_sp_from_cpustate(env)),
2828 &frame->rs_uc.tuc_stack.ss_flags);
2829
2830 setup_sigcontext(env, &frame->rs_uc.tuc_mcontext);
2831
2832 for(i = 0; i < TARGET_NSIG_WORDS; i++) {
2833 __put_user(set->sig[i], &frame->rs_uc.tuc_sigmask.sig[i]);
2834 }
2835
2836
2837
2838
2839
2840
2841
2842
2843
2844
2845
2846 env->active_tc.gpr[ 4] = sig;
2847 env->active_tc.gpr[ 5] = frame_addr
2848 + offsetof(struct target_rt_sigframe, rs_info);
2849 env->active_tc.gpr[ 6] = frame_addr
2850 + offsetof(struct target_rt_sigframe, rs_uc);
2851 env->active_tc.gpr[29] = frame_addr;
2852 env->active_tc.gpr[31] = frame_addr
2853 + offsetof(struct target_rt_sigframe, rs_code);
2854
2855
2856
2857 env->active_tc.PC = env->active_tc.gpr[25] = ka->_sa_handler;
2858 unlock_user_struct(frame, frame_addr, 1);
2859 return;
2860
2861give_sigsegv:
2862 unlock_user_struct(frame, frame_addr, 1);
2863 force_sig(TARGET_SIGSEGV);
2864 return;
2865}
2866
2867long do_rt_sigreturn(CPUState *env)
2868{
2869 struct target_rt_sigframe *frame;
2870 abi_ulong frame_addr;
2871 sigset_t blocked;
2872
2873#if defined(DEBUG_SIGNAL)
2874 fprintf(stderr, "do_rt_sigreturn\n");
2875#endif
2876 frame_addr = env->active_tc.gpr[29];
2877 if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1))
2878 goto badframe;
2879
2880 target_to_host_sigset(&blocked, &frame->rs_uc.tuc_sigmask);
2881 sigprocmask(SIG_SETMASK, &blocked, NULL);
2882
2883 if (restore_sigcontext(env, &frame->rs_uc.tuc_mcontext))
2884 goto badframe;
2885
2886 if (do_sigaltstack(frame_addr +
2887 offsetof(struct target_rt_sigframe, rs_uc.tuc_stack),
2888 0, get_sp_from_cpustate(env)) == -EFAULT)
2889 goto badframe;
2890
2891 env->active_tc.PC = env->CP0_EPC;
2892
2893
2894 env->CP0_EPC = 0;
2895 return -TARGET_QEMU_ESIGRETURN;
2896
2897badframe:
2898 force_sig(TARGET_SIGSEGV);
2899 return 0;
2900}
2901
2902#elif defined(TARGET_SH4)
2903
2904
2905
2906
2907
2908
2909
2910struct target_sigcontext {
2911 target_ulong oldmask;
2912
2913
2914 target_ulong sc_gregs[16];
2915 target_ulong sc_pc;
2916 target_ulong sc_pr;
2917 target_ulong sc_sr;
2918 target_ulong sc_gbr;
2919 target_ulong sc_mach;
2920 target_ulong sc_macl;
2921
2922
2923 target_ulong sc_fpregs[16];
2924 target_ulong sc_xfpregs[16];
2925 unsigned int sc_fpscr;
2926 unsigned int sc_fpul;
2927 unsigned int sc_ownedfp;
2928};
2929
2930struct target_sigframe
2931{
2932 struct target_sigcontext sc;
2933 target_ulong extramask[TARGET_NSIG_WORDS-1];
2934 uint16_t retcode[3];
2935};
2936
2937
2938struct target_ucontext {
2939 target_ulong tuc_flags;
2940 struct target_ucontext *tuc_link;
2941 target_stack_t tuc_stack;
2942 struct target_sigcontext tuc_mcontext;
2943 target_sigset_t tuc_sigmask;
2944};
2945
2946struct target_rt_sigframe
2947{
2948 struct target_siginfo info;
2949 struct target_ucontext uc;
2950 uint16_t retcode[3];
2951};
2952
2953
2954#define MOVW(n) (0x9300|((n)-2))
2955#define TRAP_NOARG 0xc310
2956
2957static abi_ulong get_sigframe(struct target_sigaction *ka,
2958 unsigned long sp, size_t frame_size)
2959{
2960 if ((ka->sa_flags & TARGET_SA_ONSTACK) && (sas_ss_flags(sp) == 0)) {
2961 sp = target_sigaltstack_used.ss_sp + target_sigaltstack_used.ss_size;
2962 }
2963
2964 return (sp - frame_size) & -8ul;
2965}
2966
2967static int setup_sigcontext(struct target_sigcontext *sc,
2968 CPUState *regs, unsigned long mask)
2969{
2970 int err = 0;
2971 int i;
2972
2973#define COPY(x) err |= __put_user(regs->x, &sc->sc_##x)
2974 COPY(gregs[0]); COPY(gregs[1]);
2975 COPY(gregs[2]); COPY(gregs[3]);
2976 COPY(gregs[4]); COPY(gregs[5]);
2977 COPY(gregs[6]); COPY(gregs[7]);
2978 COPY(gregs[8]); COPY(gregs[9]);
2979 COPY(gregs[10]); COPY(gregs[11]);
2980 COPY(gregs[12]); COPY(gregs[13]);
2981 COPY(gregs[14]); COPY(gregs[15]);
2982 COPY(gbr); COPY(mach);
2983 COPY(macl); COPY(pr);
2984 COPY(sr); COPY(pc);
2985#undef COPY
2986
2987 for (i=0; i<16; i++) {
2988 err |= __put_user(regs->fregs[i], &sc->sc_fpregs[i]);
2989 }
2990 err |= __put_user(regs->fpscr, &sc->sc_fpscr);
2991 err |= __put_user(regs->fpul, &sc->sc_fpul);
2992
2993
2994 err |= __put_user(mask, &sc->oldmask);
2995
2996 return err;
2997}
2998
2999static int restore_sigcontext(CPUState *regs, struct target_sigcontext *sc,
3000 target_ulong *r0_p)
3001{
3002 unsigned int err = 0;
3003 int i;
3004
3005#define COPY(x) err |= __get_user(regs->x, &sc->sc_##x)
3006 COPY(gregs[1]);
3007 COPY(gregs[2]); COPY(gregs[3]);
3008 COPY(gregs[4]); COPY(gregs[5]);
3009 COPY(gregs[6]); COPY(gregs[7]);
3010 COPY(gregs[8]); COPY(gregs[9]);
3011 COPY(gregs[10]); COPY(gregs[11]);
3012 COPY(gregs[12]); COPY(gregs[13]);
3013 COPY(gregs[14]); COPY(gregs[15]);
3014 COPY(gbr); COPY(mach);
3015 COPY(macl); COPY(pr);
3016 COPY(sr); COPY(pc);
3017#undef COPY
3018
3019 for (i=0; i<16; i++) {
3020 err |= __get_user(regs->fregs[i], &sc->sc_fpregs[i]);
3021 }
3022 err |= __get_user(regs->fpscr, &sc->sc_fpscr);
3023 err |= __get_user(regs->fpul, &sc->sc_fpul);
3024
3025 regs->tra = -1;
3026 err |= __get_user(*r0_p, &sc->sc_gregs[0]);
3027 return err;
3028}
3029
3030static void setup_frame(int sig, struct target_sigaction *ka,
3031 target_sigset_t *set, CPUState *regs)
3032{
3033 struct target_sigframe *frame;
3034 abi_ulong frame_addr;
3035 int i;
3036 int err = 0;
3037 int signal;
3038
3039 frame_addr = get_sigframe(ka, regs->gregs[15], sizeof(*frame));
3040 if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
3041 goto give_sigsegv;
3042
3043 signal = current_exec_domain_sig(sig);
3044
3045 err |= setup_sigcontext(&frame->sc, regs, set->sig[0]);
3046
3047 for (i = 0; i < TARGET_NSIG_WORDS - 1; i++) {
3048 err |= __put_user(set->sig[i + 1], &frame->extramask[i]);
3049 }
3050
3051
3052
3053 if (ka->sa_flags & TARGET_SA_RESTORER) {
3054 regs->pr = (unsigned long) ka->sa_restorer;
3055 } else {
3056
3057 err |= __put_user(MOVW(2), &frame->retcode[0]);
3058 err |= __put_user(TRAP_NOARG, &frame->retcode[1]);
3059 err |= __put_user((TARGET_NR_sigreturn), &frame->retcode[2]);
3060 regs->pr = (unsigned long) frame->retcode;
3061 }
3062
3063 if (err)
3064 goto give_sigsegv;
3065
3066
3067 regs->gregs[15] = (unsigned long) frame;
3068 regs->gregs[4] = signal;
3069 regs->gregs[5] = 0;
3070 regs->gregs[6] = (unsigned long) &frame->sc;
3071 regs->pc = (unsigned long) ka->_sa_handler;
3072
3073 unlock_user_struct(frame, frame_addr, 1);
3074 return;
3075
3076give_sigsegv:
3077 unlock_user_struct(frame, frame_addr, 1);
3078 force_sig(TARGET_SIGSEGV);
3079}
3080
3081static void setup_rt_frame(int sig, struct target_sigaction *ka,
3082 target_siginfo_t *info,
3083 target_sigset_t *set, CPUState *regs)
3084{
3085 struct target_rt_sigframe *frame;
3086 abi_ulong frame_addr;
3087 int i;
3088 int err = 0;
3089 int signal;
3090
3091 frame_addr = get_sigframe(ka, regs->gregs[15], sizeof(*frame));
3092 if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
3093 goto give_sigsegv;
3094
3095 signal = current_exec_domain_sig(sig);
3096
3097 err |= copy_siginfo_to_user(&frame->info, info);
3098
3099
3100 err |= __put_user(0, &frame->uc.tuc_flags);
3101 err |= __put_user(0, (unsigned long *)&frame->uc.tuc_link);
3102 err |= __put_user((unsigned long)target_sigaltstack_used.ss_sp,
3103 &frame->uc.tuc_stack.ss_sp);
3104 err |= __put_user(sas_ss_flags(regs->gregs[15]),
3105 &frame->uc.tuc_stack.ss_flags);
3106 err |= __put_user(target_sigaltstack_used.ss_size,
3107 &frame->uc.tuc_stack.ss_size);
3108 err |= setup_sigcontext(&frame->uc.tuc_mcontext,
3109 regs, set->sig[0]);
3110 for(i = 0; i < TARGET_NSIG_WORDS; i++) {
3111 err |= __put_user(set->sig[i], &frame->uc.tuc_sigmask.sig[i]);
3112 }
3113
3114
3115
3116 if (ka->sa_flags & TARGET_SA_RESTORER) {
3117 regs->pr = (unsigned long) ka->sa_restorer;
3118 } else {
3119
3120 err |= __put_user(MOVW(2), &frame->retcode[0]);
3121 err |= __put_user(TRAP_NOARG, &frame->retcode[1]);
3122 err |= __put_user((TARGET_NR_rt_sigreturn), &frame->retcode[2]);
3123 regs->pr = (unsigned long) frame->retcode;
3124 }
3125
3126 if (err)
3127 goto give_sigsegv;
3128
3129
3130 regs->gregs[15] = (unsigned long) frame;
3131 regs->gregs[4] = signal;
3132 regs->gregs[5] = (unsigned long) &frame->info;
3133 regs->gregs[6] = (unsigned long) &frame->uc;
3134 regs->pc = (unsigned long) ka->_sa_handler;
3135
3136 unlock_user_struct(frame, frame_addr, 1);
3137 return;
3138
3139give_sigsegv:
3140 unlock_user_struct(frame, frame_addr, 1);
3141 force_sig(TARGET_SIGSEGV);
3142}
3143
3144long do_sigreturn(CPUState *regs)
3145{
3146 struct target_sigframe *frame;
3147 abi_ulong frame_addr;
3148 sigset_t blocked;
3149 target_sigset_t target_set;
3150 target_ulong r0;
3151 int i;
3152 int err = 0;
3153
3154#if defined(DEBUG_SIGNAL)
3155 fprintf(stderr, "do_sigreturn\n");
3156#endif
3157 frame_addr = regs->gregs[15];
3158 if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1))
3159 goto badframe;
3160
3161 err |= __get_user(target_set.sig[0], &frame->sc.oldmask);
3162 for(i = 1; i < TARGET_NSIG_WORDS; i++) {
3163 err |= (__get_user(target_set.sig[i], &frame->extramask[i - 1]));
3164 }
3165
3166 if (err)
3167 goto badframe;
3168
3169 target_to_host_sigset_internal(&blocked, &target_set);
3170 sigprocmask(SIG_SETMASK, &blocked, NULL);
3171
3172 if (restore_sigcontext(regs, &frame->sc, &r0))
3173 goto badframe;
3174
3175 unlock_user_struct(frame, frame_addr, 0);
3176 return r0;
3177
3178badframe:
3179 unlock_user_struct(frame, frame_addr, 0);
3180 force_sig(TARGET_SIGSEGV);
3181 return 0;
3182}
3183
3184long do_rt_sigreturn(CPUState *regs)
3185{
3186 struct target_rt_sigframe *frame;
3187 abi_ulong frame_addr;
3188 sigset_t blocked;
3189 target_ulong r0;
3190
3191#if defined(DEBUG_SIGNAL)
3192 fprintf(stderr, "do_rt_sigreturn\n");
3193#endif
3194 frame_addr = regs->gregs[15];
3195 if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1))
3196 goto badframe;
3197
3198 target_to_host_sigset(&blocked, &frame->uc.tuc_sigmask);
3199 sigprocmask(SIG_SETMASK, &blocked, NULL);
3200
3201 if (restore_sigcontext(regs, &frame->uc.tuc_mcontext, &r0))
3202 goto badframe;
3203
3204 if (do_sigaltstack(frame_addr +
3205 offsetof(struct target_rt_sigframe, uc.tuc_stack),
3206 0, get_sp_from_cpustate(regs)) == -EFAULT)
3207 goto badframe;
3208
3209 unlock_user_struct(frame, frame_addr, 0);
3210 return r0;
3211
3212badframe:
3213 unlock_user_struct(frame, frame_addr, 0);
3214 force_sig(TARGET_SIGSEGV);
3215 return 0;
3216}
3217#elif defined(TARGET_MICROBLAZE)
3218
3219struct target_sigcontext {
3220 struct target_pt_regs regs;
3221 uint32_t oldmask;
3222};
3223
3224struct target_stack_t {
3225 abi_ulong ss_sp;
3226 int ss_flags;
3227 unsigned int ss_size;
3228};
3229
3230struct target_ucontext {
3231 abi_ulong tuc_flags;
3232 abi_ulong tuc_link;
3233 struct target_stack_t tuc_stack;
3234 struct target_sigcontext tuc_mcontext;
3235 uint32_t tuc_extramask[TARGET_NSIG_WORDS - 1];
3236};
3237
3238
3239struct target_signal_frame {
3240 struct target_ucontext uc;
3241 uint32_t extramask[TARGET_NSIG_WORDS - 1];
3242 uint32_t tramp[2];
3243};
3244
3245struct rt_signal_frame {
3246 struct siginfo info;
3247 struct ucontext uc;
3248 uint32_t tramp[2];
3249};
3250
3251static void setup_sigcontext(struct target_sigcontext *sc, CPUState *env)
3252{
3253 __put_user(env->regs[0], &sc->regs.r0);
3254 __put_user(env->regs[1], &sc->regs.r1);
3255 __put_user(env->regs[2], &sc->regs.r2);
3256 __put_user(env->regs[3], &sc->regs.r3);
3257 __put_user(env->regs[4], &sc->regs.r4);
3258 __put_user(env->regs[5], &sc->regs.r5);
3259 __put_user(env->regs[6], &sc->regs.r6);
3260 __put_user(env->regs[7], &sc->regs.r7);
3261 __put_user(env->regs[8], &sc->regs.r8);
3262 __put_user(env->regs[9], &sc->regs.r9);
3263 __put_user(env->regs[10], &sc->regs.r10);
3264 __put_user(env->regs[11], &sc->regs.r11);
3265 __put_user(env->regs[12], &sc->regs.r12);
3266 __put_user(env->regs[13], &sc->regs.r13);
3267 __put_user(env->regs[14], &sc->regs.r14);
3268 __put_user(env->regs[15], &sc->regs.r15);
3269 __put_user(env->regs[16], &sc->regs.r16);
3270 __put_user(env->regs[17], &sc->regs.r17);
3271 __put_user(env->regs[18], &sc->regs.r18);
3272 __put_user(env->regs[19], &sc->regs.r19);
3273 __put_user(env->regs[20], &sc->regs.r20);
3274 __put_user(env->regs[21], &sc->regs.r21);
3275 __put_user(env->regs[22], &sc->regs.r22);
3276 __put_user(env->regs[23], &sc->regs.r23);
3277 __put_user(env->regs[24], &sc->regs.r24);
3278 __put_user(env->regs[25], &sc->regs.r25);
3279 __put_user(env->regs[26], &sc->regs.r26);
3280 __put_user(env->regs[27], &sc->regs.r27);
3281 __put_user(env->regs[28], &sc->regs.r28);
3282 __put_user(env->regs[29], &sc->regs.r29);
3283 __put_user(env->regs[30], &sc->regs.r30);
3284 __put_user(env->regs[31], &sc->regs.r31);
3285 __put_user(env->sregs[SR_PC], &sc->regs.pc);
3286}
3287
3288static void restore_sigcontext(struct target_sigcontext *sc, CPUState *env)
3289{
3290 __get_user(env->regs[0], &sc->regs.r0);
3291 __get_user(env->regs[1], &sc->regs.r1);
3292 __get_user(env->regs[2], &sc->regs.r2);
3293 __get_user(env->regs[3], &sc->regs.r3);
3294 __get_user(env->regs[4], &sc->regs.r4);
3295 __get_user(env->regs[5], &sc->regs.r5);
3296 __get_user(env->regs[6], &sc->regs.r6);
3297 __get_user(env->regs[7], &sc->regs.r7);
3298 __get_user(env->regs[8], &sc->regs.r8);
3299 __get_user(env->regs[9], &sc->regs.r9);
3300 __get_user(env->regs[10], &sc->regs.r10);
3301 __get_user(env->regs[11], &sc->regs.r11);
3302 __get_user(env->regs[12], &sc->regs.r12);
3303 __get_user(env->regs[13], &sc->regs.r13);
3304 __get_user(env->regs[14], &sc->regs.r14);
3305 __get_user(env->regs[15], &sc->regs.r15);
3306 __get_user(env->regs[16], &sc->regs.r16);
3307 __get_user(env->regs[17], &sc->regs.r17);
3308 __get_user(env->regs[18], &sc->regs.r18);
3309 __get_user(env->regs[19], &sc->regs.r19);
3310 __get_user(env->regs[20], &sc->regs.r20);
3311 __get_user(env->regs[21], &sc->regs.r21);
3312 __get_user(env->regs[22], &sc->regs.r22);
3313 __get_user(env->regs[23], &sc->regs.r23);
3314 __get_user(env->regs[24], &sc->regs.r24);
3315 __get_user(env->regs[25], &sc->regs.r25);
3316 __get_user(env->regs[26], &sc->regs.r26);
3317 __get_user(env->regs[27], &sc->regs.r27);
3318 __get_user(env->regs[28], &sc->regs.r28);
3319 __get_user(env->regs[29], &sc->regs.r29);
3320 __get_user(env->regs[30], &sc->regs.r30);
3321 __get_user(env->regs[31], &sc->regs.r31);
3322 __get_user(env->sregs[SR_PC], &sc->regs.pc);
3323}
3324
3325static abi_ulong get_sigframe(struct target_sigaction *ka,
3326 CPUState *env, int frame_size)
3327{
3328 abi_ulong sp = env->regs[1];
3329
3330 if ((ka->sa_flags & SA_ONSTACK) != 0 && !on_sig_stack(sp))
3331 sp = target_sigaltstack_used.ss_sp + target_sigaltstack_used.ss_size;
3332
3333 return ((sp - frame_size) & -8UL);
3334}
3335
3336static void setup_frame(int sig, struct target_sigaction *ka,
3337 target_sigset_t *set, CPUState *env)
3338{
3339 struct target_signal_frame *frame;
3340 abi_ulong frame_addr;
3341 int err = 0;
3342 int i;
3343
3344 frame_addr = get_sigframe(ka, env, sizeof *frame);
3345 if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
3346 goto badframe;
3347
3348
3349 err |= __put_user(set->sig[0], &frame->uc.tuc_mcontext.oldmask);
3350 if (err)
3351 goto badframe;
3352
3353 for(i = 1; i < TARGET_NSIG_WORDS; i++) {
3354 if (__put_user(set->sig[i], &frame->extramask[i - 1]))
3355 goto badframe;
3356 }
3357
3358 setup_sigcontext(&frame->uc.tuc_mcontext, env);
3359
3360
3361
3362
3363 if (ka->sa_flags & TARGET_SA_RESTORER) {
3364 env->regs[15] = ((unsigned long)ka->sa_restorer)-8;
3365 } else {
3366 uint32_t t;
3367
3368
3369 t = 0x31800000UL | TARGET_NR_sigreturn;
3370 err |= __put_user(t, frame->tramp + 0);
3371
3372 t = 0xb9cc0008UL;
3373 err |= __put_user(t, frame->tramp + 1);
3374
3375
3376
3377 env->regs[15] = ((unsigned long)frame->tramp) - 8;
3378 }
3379
3380 if (err)
3381 goto badframe;
3382
3383
3384 env->regs[1] = (unsigned long) frame;
3385
3386 env->regs[5] = sig;
3387 env->regs[6] = 0;
3388 env->regs[7] = (unsigned long) &frame->uc;
3389
3390
3391 env->sregs[SR_PC] = (unsigned long)ka->_sa_handler;
3392
3393 unlock_user_struct(frame, frame_addr, 1);
3394 return;
3395 badframe:
3396 unlock_user_struct(frame, frame_addr, 1);
3397 force_sig(TARGET_SIGSEGV);
3398}
3399
3400static void setup_rt_frame(int sig, struct target_sigaction *ka,
3401 target_siginfo_t *info,
3402 target_sigset_t *set, CPUState *env)
3403{
3404 fprintf(stderr, "Microblaze setup_rt_frame: not implemented\n");
3405}
3406
3407long do_sigreturn(CPUState *env)
3408{
3409 struct target_signal_frame *frame;
3410 abi_ulong frame_addr;
3411 target_sigset_t target_set;
3412 sigset_t set;
3413 int i;
3414
3415 frame_addr = env->regs[R_SP];
3416
3417 if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 1))
3418 goto badframe;
3419
3420
3421 if (__get_user(target_set.sig[0], &frame->uc.tuc_mcontext.oldmask))
3422 goto badframe;
3423 for(i = 1; i < TARGET_NSIG_WORDS; i++) {
3424 if (__get_user(target_set.sig[i], &frame->extramask[i - 1]))
3425 goto badframe;
3426 }
3427 target_to_host_sigset_internal(&set, &target_set);
3428 sigprocmask(SIG_SETMASK, &set, NULL);
3429
3430 restore_sigcontext(&frame->uc.tuc_mcontext, env);
3431
3432
3433 env->regs[14] = env->sregs[SR_PC];
3434
3435 unlock_user_struct(frame, frame_addr, 0);
3436 return env->regs[10];
3437 badframe:
3438 unlock_user_struct(frame, frame_addr, 0);
3439 force_sig(TARGET_SIGSEGV);
3440}
3441
3442long do_rt_sigreturn(CPUState *env)
3443{
3444 fprintf(stderr, "Microblaze do_rt_sigreturn: not implemented\n");
3445 return -TARGET_ENOSYS;
3446}
3447
3448#elif defined(TARGET_CRIS)
3449
3450struct target_sigcontext {
3451 struct target_pt_regs regs;
3452 uint32_t oldmask;
3453 uint32_t usp;
3454};
3455
3456
3457struct target_signal_frame {
3458 struct target_sigcontext sc;
3459 uint32_t extramask[TARGET_NSIG_WORDS - 1];
3460 uint8_t retcode[8];
3461};
3462
3463struct rt_signal_frame {
3464 struct siginfo *pinfo;
3465 void *puc;
3466 struct siginfo info;
3467 struct ucontext uc;
3468 uint8_t retcode[8];
3469};
3470
3471static void setup_sigcontext(struct target_sigcontext *sc, CPUState *env)
3472{
3473 __put_user(env->regs[0], &sc->regs.r0);
3474 __put_user(env->regs[1], &sc->regs.r1);
3475 __put_user(env->regs[2], &sc->regs.r2);
3476 __put_user(env->regs[3], &sc->regs.r3);
3477 __put_user(env->regs[4], &sc->regs.r4);
3478 __put_user(env->regs[5], &sc->regs.r5);
3479 __put_user(env->regs[6], &sc->regs.r6);
3480 __put_user(env->regs[7], &sc->regs.r7);
3481 __put_user(env->regs[8], &sc->regs.r8);
3482 __put_user(env->regs[9], &sc->regs.r9);
3483 __put_user(env->regs[10], &sc->regs.r10);
3484 __put_user(env->regs[11], &sc->regs.r11);
3485 __put_user(env->regs[12], &sc->regs.r12);
3486 __put_user(env->regs[13], &sc->regs.r13);
3487 __put_user(env->regs[14], &sc->usp);
3488 __put_user(env->regs[15], &sc->regs.acr);
3489 __put_user(env->pregs[PR_MOF], &sc->regs.mof);
3490 __put_user(env->pregs[PR_SRP], &sc->regs.srp);
3491 __put_user(env->pc, &sc->regs.erp);
3492}
3493
3494static void restore_sigcontext(struct target_sigcontext *sc, CPUState *env)
3495{
3496 __get_user(env->regs[0], &sc->regs.r0);
3497 __get_user(env->regs[1], &sc->regs.r1);
3498 __get_user(env->regs[2], &sc->regs.r2);
3499 __get_user(env->regs[3], &sc->regs.r3);
3500 __get_user(env->regs[4], &sc->regs.r4);
3501 __get_user(env->regs[5], &sc->regs.r5);
3502 __get_user(env->regs[6], &sc->regs.r6);
3503 __get_user(env->regs[7], &sc->regs.r7);
3504 __get_user(env->regs[8], &sc->regs.r8);
3505 __get_user(env->regs[9], &sc->regs.r9);
3506 __get_user(env->regs[10], &sc->regs.r10);
3507 __get_user(env->regs[11], &sc->regs.r11);
3508 __get_user(env->regs[12], &sc->regs.r12);
3509 __get_user(env->regs[13], &sc->regs.r13);
3510 __get_user(env->regs[14], &sc->usp);
3511 __get_user(env->regs[15], &sc->regs.acr);
3512 __get_user(env->pregs[PR_MOF], &sc->regs.mof);
3513 __get_user(env->pregs[PR_SRP], &sc->regs.srp);
3514 __get_user(env->pc, &sc->regs.erp);
3515}
3516
3517static abi_ulong get_sigframe(CPUState *env, int framesize)
3518{
3519 abi_ulong sp;
3520
3521 sp = (env->regs[R_SP] & ~3);
3522 return sp - framesize;
3523}
3524
3525static void setup_frame(int sig, struct target_sigaction *ka,
3526 target_sigset_t *set, CPUState *env)
3527{
3528 struct target_signal_frame *frame;
3529 abi_ulong frame_addr;
3530 int err = 0;
3531 int i;
3532
3533 frame_addr = get_sigframe(env, sizeof *frame);
3534 if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
3535 goto badframe;
3536
3537
3538
3539
3540
3541
3542
3543
3544 err |= __put_user(0x9c5f, frame->retcode+0);
3545 err |= __put_user(TARGET_NR_sigreturn,
3546 frame->retcode+2);
3547 err |= __put_user(0xe93d, frame->retcode+4);
3548
3549
3550 err |= __put_user(set->sig[0], &frame->sc.oldmask);
3551 if (err)
3552 goto badframe;
3553
3554 for(i = 1; i < TARGET_NSIG_WORDS; i++) {
3555 if (__put_user(set->sig[i], &frame->extramask[i - 1]))
3556 goto badframe;
3557 }
3558
3559 setup_sigcontext(&frame->sc, env);
3560
3561
3562 env->regs[R_SP] = (uint32_t) (unsigned long) frame;
3563 env->regs[10] = sig;
3564 env->pc = (unsigned long) ka->_sa_handler;
3565
3566 env->pregs[PR_SRP] = (uint32_t) (unsigned long) &frame->retcode[0];
3567
3568 unlock_user_struct(frame, frame_addr, 1);
3569 return;
3570 badframe:
3571 unlock_user_struct(frame, frame_addr, 1);
3572 force_sig(TARGET_SIGSEGV);
3573}
3574
3575static void setup_rt_frame(int sig, struct target_sigaction *ka,
3576 target_siginfo_t *info,
3577 target_sigset_t *set, CPUState *env)
3578{
3579 fprintf(stderr, "CRIS setup_rt_frame: not implemented\n");
3580}
3581
3582long do_sigreturn(CPUState *env)
3583{
3584 struct target_signal_frame *frame;
3585 abi_ulong frame_addr;
3586 target_sigset_t target_set;
3587 sigset_t set;
3588 int i;
3589
3590 frame_addr = env->regs[R_SP];
3591
3592 if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 1))
3593 goto badframe;
3594
3595
3596 if (__get_user(target_set.sig[0], &frame->sc.oldmask))
3597 goto badframe;
3598 for(i = 1; i < TARGET_NSIG_WORDS; i++) {
3599 if (__get_user(target_set.sig[i], &frame->extramask[i - 1]))
3600 goto badframe;
3601 }
3602 target_to_host_sigset_internal(&set, &target_set);
3603 sigprocmask(SIG_SETMASK, &set, NULL);
3604
3605 restore_sigcontext(&frame->sc, env);
3606 unlock_user_struct(frame, frame_addr, 0);
3607 return env->regs[10];
3608 badframe:
3609 unlock_user_struct(frame, frame_addr, 0);
3610 force_sig(TARGET_SIGSEGV);
3611}
3612
3613long do_rt_sigreturn(CPUState *env)
3614{
3615 fprintf(stderr, "CRIS do_rt_sigreturn: not implemented\n");
3616 return -TARGET_ENOSYS;
3617}
3618
3619#elif defined(TARGET_S390X)
3620
3621#define __NUM_GPRS 16
3622#define __NUM_FPRS 16
3623#define __NUM_ACRS 16
3624
3625#define S390_SYSCALL_SIZE 2
3626#define __SIGNAL_FRAMESIZE 160
3627
3628#define _SIGCONTEXT_NSIG 64
3629#define _SIGCONTEXT_NSIG_BPW 64
3630#define _SIGCONTEXT_NSIG_WORDS (_SIGCONTEXT_NSIG / _SIGCONTEXT_NSIG_BPW)
3631#define _SIGMASK_COPY_SIZE (sizeof(unsigned long)*_SIGCONTEXT_NSIG_WORDS)
3632#define PSW_ADDR_AMODE 0x0000000000000000UL
3633#define S390_SYSCALL_OPCODE ((uint16_t)0x0a00)
3634
3635typedef struct {
3636 target_psw_t psw;
3637 target_ulong gprs[__NUM_GPRS];
3638 unsigned int acrs[__NUM_ACRS];
3639} target_s390_regs_common;
3640
3641typedef struct {
3642 unsigned int fpc;
3643 double fprs[__NUM_FPRS];
3644} target_s390_fp_regs;
3645
3646typedef struct {
3647 target_s390_regs_common regs;
3648 target_s390_fp_regs fpregs;
3649} target_sigregs;
3650
3651struct target_sigcontext {
3652 target_ulong oldmask[_SIGCONTEXT_NSIG_WORDS];
3653 target_sigregs *sregs;
3654};
3655
3656typedef struct {
3657 uint8_t callee_used_stack[__SIGNAL_FRAMESIZE];
3658 struct target_sigcontext sc;
3659 target_sigregs sregs;
3660 int signo;
3661 uint8_t retcode[S390_SYSCALL_SIZE];
3662} sigframe;
3663
3664struct target_ucontext {
3665 target_ulong tuc_flags;
3666 struct target_ucontext *tuc_link;
3667 target_stack_t tuc_stack;
3668 target_sigregs tuc_mcontext;
3669 target_sigset_t tuc_sigmask;
3670};
3671
3672typedef struct {
3673 uint8_t callee_used_stack[__SIGNAL_FRAMESIZE];
3674 uint8_t retcode[S390_SYSCALL_SIZE];
3675 struct target_siginfo info;
3676 struct target_ucontext uc;
3677} rt_sigframe;
3678
3679static inline abi_ulong
3680get_sigframe(struct target_sigaction *ka, CPUState *env, size_t frame_size)
3681{
3682 abi_ulong sp;
3683
3684
3685 sp = env->regs[15];
3686
3687
3688 if (ka->sa_flags & TARGET_SA_ONSTACK) {
3689 if (!sas_ss_flags(sp)) {
3690 sp = target_sigaltstack_used.ss_sp +
3691 target_sigaltstack_used.ss_size;
3692 }
3693 }
3694
3695
3696 else if ( 0 &&
3697 !(ka->sa_flags & TARGET_SA_RESTORER) &&
3698 ka->sa_restorer) {
3699 sp = (abi_ulong) ka->sa_restorer;
3700 }
3701
3702 return (sp - frame_size) & -8ul;
3703}
3704
3705static void save_sigregs(CPUState *env, target_sigregs *sregs)
3706{
3707 int i;
3708
3709
3710
3711
3712 __put_user(env->psw.mask, &sregs->regs.psw.mask);
3713 __put_user(env->psw.addr, &sregs->regs.psw.addr);
3714 for (i = 0; i < 16; i++) {
3715 __put_user(env->regs[i], &sregs->regs.gprs[i]);
3716 }
3717 for (i = 0; i < 16; i++) {
3718 __put_user(env->aregs[i], &sregs->regs.acrs[i]);
3719 }
3720
3721
3722
3723
3724
3725 for (i = 0; i < 16; i++) {
3726 __put_user(env->fregs[i].ll, &sregs->fpregs.fprs[i]);
3727 }
3728}
3729
3730static void setup_frame(int sig, struct target_sigaction *ka,
3731 target_sigset_t *set, CPUState *env)
3732{
3733 sigframe *frame;
3734 abi_ulong frame_addr;
3735
3736 frame_addr = get_sigframe(ka, env, sizeof(*frame));
3737 qemu_log("%s: frame_addr 0x%llx\n", __FUNCTION__,
3738 (unsigned long long)frame_addr);
3739 if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0)) {
3740 goto give_sigsegv;
3741 }
3742
3743 qemu_log("%s: 1\n", __FUNCTION__);
3744 if (__put_user(set->sig[0], &frame->sc.oldmask[0])) {
3745 goto give_sigsegv;
3746 }
3747
3748 save_sigregs(env, &frame->sregs);
3749
3750 __put_user((abi_ulong)(unsigned long)&frame->sregs,
3751 (abi_ulong *)&frame->sc.sregs);
3752
3753
3754
3755 if (ka->sa_flags & TARGET_SA_RESTORER) {
3756 env->regs[14] = (unsigned long)
3757 ka->sa_restorer | PSW_ADDR_AMODE;
3758 } else {
3759 env->regs[14] = (unsigned long)
3760 frame->retcode | PSW_ADDR_AMODE;
3761 if (__put_user(S390_SYSCALL_OPCODE | TARGET_NR_sigreturn,
3762 (uint16_t *)(frame->retcode)))
3763 goto give_sigsegv;
3764 }
3765
3766
3767 if (__put_user(env->regs[15], (abi_ulong *) frame)) {
3768 goto give_sigsegv;
3769 }
3770
3771
3772 env->regs[15] = (target_ulong)(unsigned long) frame;
3773 env->psw.addr = (target_ulong) ka->_sa_handler | PSW_ADDR_AMODE;
3774
3775 env->regs[2] = sig;
3776 env->regs[3] = (target_ulong)(unsigned long) &frame->sc;
3777
3778
3779
3780 env->regs[4] = 0;
3781 env->regs[5] = 0;
3782
3783
3784 if (__put_user(env->regs[2], (int *) &frame->signo)) {
3785 goto give_sigsegv;
3786 }
3787 unlock_user_struct(frame, frame_addr, 1);
3788 return;
3789
3790give_sigsegv:
3791 qemu_log("%s: give_sigsegv\n", __FUNCTION__);
3792 unlock_user_struct(frame, frame_addr, 1);
3793 force_sig(TARGET_SIGSEGV);
3794}
3795
3796static void setup_rt_frame(int sig, struct target_sigaction *ka,
3797 target_siginfo_t *info,
3798 target_sigset_t *set, CPUState *env)
3799{
3800 int i;
3801 rt_sigframe *frame;
3802 abi_ulong frame_addr;
3803
3804 frame_addr = get_sigframe(ka, env, sizeof *frame);
3805 qemu_log("%s: frame_addr 0x%llx\n", __FUNCTION__,
3806 (unsigned long long)frame_addr);
3807 if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0)) {
3808 goto give_sigsegv;
3809 }
3810
3811 qemu_log("%s: 1\n", __FUNCTION__);
3812 if (copy_siginfo_to_user(&frame->info, info)) {
3813 goto give_sigsegv;
3814 }
3815
3816
3817 __put_user(0, &frame->uc.tuc_flags);
3818 __put_user((abi_ulong)0, (abi_ulong *)&frame->uc.tuc_link);
3819 __put_user(target_sigaltstack_used.ss_sp, &frame->uc.tuc_stack.ss_sp);
3820 __put_user(sas_ss_flags(get_sp_from_cpustate(env)),
3821 &frame->uc.tuc_stack.ss_flags);
3822 __put_user(target_sigaltstack_used.ss_size, &frame->uc.tuc_stack.ss_size);
3823 save_sigregs(env, &frame->uc.tuc_mcontext);
3824 for (i = 0; i < TARGET_NSIG_WORDS; i++) {
3825 __put_user((abi_ulong)set->sig[i],
3826 (abi_ulong *)&frame->uc.tuc_sigmask.sig[i]);
3827 }
3828
3829
3830
3831 if (ka->sa_flags & TARGET_SA_RESTORER) {
3832 env->regs[14] = (unsigned long) ka->sa_restorer | PSW_ADDR_AMODE;
3833 } else {
3834 env->regs[14] = (unsigned long) frame->retcode | PSW_ADDR_AMODE;
3835 if (__put_user(S390_SYSCALL_OPCODE | TARGET_NR_rt_sigreturn,
3836 (uint16_t *)(frame->retcode))) {
3837 goto give_sigsegv;
3838 }
3839 }
3840
3841
3842 if (__put_user(env->regs[15], (abi_ulong *) frame)) {
3843 goto give_sigsegv;
3844 }
3845
3846
3847 env->regs[15] = (target_ulong)(unsigned long) frame;
3848 env->psw.addr = (target_ulong) ka->_sa_handler | PSW_ADDR_AMODE;
3849
3850 env->regs[2] = sig;
3851 env->regs[3] = (target_ulong)(unsigned long) &frame->info;
3852 env->regs[4] = (target_ulong)(unsigned long) &frame->uc;
3853 return;
3854
3855give_sigsegv:
3856 qemu_log("%s: give_sigsegv\n", __FUNCTION__);
3857 unlock_user_struct(frame, frame_addr, 1);
3858 force_sig(TARGET_SIGSEGV);
3859}
3860
3861static int
3862restore_sigregs(CPUState *env, target_sigregs *sc)
3863{
3864 int err = 0;
3865 int i;
3866
3867 for (i = 0; i < 16; i++) {
3868 err |= __get_user(env->regs[i], &sc->regs.gprs[i]);
3869 }
3870
3871 err |= __get_user(env->psw.mask, &sc->regs.psw.mask);
3872 qemu_log("%s: sc->regs.psw.addr 0x%llx env->psw.addr 0x%llx\n",
3873 __FUNCTION__, (unsigned long long)sc->regs.psw.addr,
3874 (unsigned long long)env->psw.addr);
3875 err |= __get_user(env->psw.addr, &sc->regs.psw.addr);
3876
3877
3878 for (i = 0; i < 16; i++) {
3879 err |= __get_user(env->aregs[i], &sc->regs.acrs[i]);
3880 }
3881 for (i = 0; i < 16; i++) {
3882 err |= __get_user(env->fregs[i].ll, &sc->fpregs.fprs[i]);
3883 }
3884
3885 return err;
3886}
3887
3888long do_sigreturn(CPUState *env)
3889{
3890 sigframe *frame;
3891 abi_ulong frame_addr = env->regs[15];
3892 qemu_log("%s: frame_addr 0x%llx\n", __FUNCTION__,
3893 (unsigned long long)frame_addr);
3894 target_sigset_t target_set;
3895 sigset_t set;
3896
3897 if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1)) {
3898 goto badframe;
3899 }
3900 if (__get_user(target_set.sig[0], &frame->sc.oldmask[0])) {
3901 goto badframe;
3902 }
3903
3904 target_to_host_sigset_internal(&set, &target_set);
3905 sigprocmask(SIG_SETMASK, &set, NULL);
3906
3907 if (restore_sigregs(env, &frame->sregs)) {
3908 goto badframe;
3909 }
3910
3911 unlock_user_struct(frame, frame_addr, 0);
3912 return env->regs[2];
3913
3914badframe:
3915 unlock_user_struct(frame, frame_addr, 0);
3916 force_sig(TARGET_SIGSEGV);
3917 return 0;
3918}
3919
3920long do_rt_sigreturn(CPUState *env)
3921{
3922 rt_sigframe *frame;
3923 abi_ulong frame_addr = env->regs[15];
3924 qemu_log("%s: frame_addr 0x%llx\n", __FUNCTION__,
3925 (unsigned long long)frame_addr);
3926 sigset_t set;
3927
3928 if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1)) {
3929 goto badframe;
3930 }
3931 target_to_host_sigset(&set, &frame->uc.tuc_sigmask);
3932
3933 sigprocmask(SIG_SETMASK, &set, NULL);
3934
3935 if (restore_sigregs(env, &frame->uc.tuc_mcontext)) {
3936 goto badframe;
3937 }
3938
3939 if (do_sigaltstack(frame_addr + offsetof(rt_sigframe, uc.tuc_stack), 0,
3940 get_sp_from_cpustate(env)) == -EFAULT) {
3941 goto badframe;
3942 }
3943 unlock_user_struct(frame, frame_addr, 0);
3944 return env->regs[2];
3945
3946badframe:
3947 unlock_user_struct(frame, frame_addr, 0);
3948 force_sig(TARGET_SIGSEGV);
3949 return 0;
3950}
3951
3952#elif defined(TARGET_PPC) && !defined(TARGET_PPC64)
3953
3954
3955
3956
3957
3958
3959
3960
3961
3962
3963
3964#if defined(TARGET_PPC64)
3965#define SIGNAL_FRAMESIZE 128
3966#else
3967#define SIGNAL_FRAMESIZE 64
3968#endif
3969
3970
3971struct target_sigcontext {
3972 target_ulong _unused[4];
3973 int32_t signal;
3974#if defined(TARGET_PPC64)
3975 int32_t pad0;
3976#endif
3977 target_ulong handler;
3978 target_ulong oldmask;
3979 target_ulong regs;
3980
3981};
3982
3983
3984
3985enum {
3986 TARGET_PT_R0 = 0,
3987 TARGET_PT_R1 = 1,
3988 TARGET_PT_R2 = 2,
3989 TARGET_PT_R3 = 3,
3990 TARGET_PT_R4 = 4,
3991 TARGET_PT_R5 = 5,
3992 TARGET_PT_R6 = 6,
3993 TARGET_PT_R7 = 7,
3994 TARGET_PT_R8 = 8,
3995 TARGET_PT_R9 = 9,
3996 TARGET_PT_R10 = 10,
3997 TARGET_PT_R11 = 11,
3998 TARGET_PT_R12 = 12,
3999 TARGET_PT_R13 = 13,
4000 TARGET_PT_R14 = 14,
4001 TARGET_PT_R15 = 15,
4002 TARGET_PT_R16 = 16,
4003 TARGET_PT_R17 = 17,
4004 TARGET_PT_R18 = 18,
4005 TARGET_PT_R19 = 19,
4006 TARGET_PT_R20 = 20,
4007 TARGET_PT_R21 = 21,
4008 TARGET_PT_R22 = 22,
4009 TARGET_PT_R23 = 23,
4010 TARGET_PT_R24 = 24,
4011 TARGET_PT_R25 = 25,
4012 TARGET_PT_R26 = 26,
4013 TARGET_PT_R27 = 27,
4014 TARGET_PT_R28 = 28,
4015 TARGET_PT_R29 = 29,
4016 TARGET_PT_R30 = 30,
4017 TARGET_PT_R31 = 31,
4018 TARGET_PT_NIP = 32,
4019 TARGET_PT_MSR = 33,
4020 TARGET_PT_ORIG_R3 = 34,
4021 TARGET_PT_CTR = 35,
4022 TARGET_PT_LNK = 36,
4023 TARGET_PT_XER = 37,
4024 TARGET_PT_CCR = 38,
4025
4026 TARGET_PT_MQ = 39,
4027 TARGET_PT_SOFTE = 39,
4028 TARGET_PT_TRAP = 40,
4029 TARGET_PT_DAR = 41,
4030 TARGET_PT_DSISR = 42,
4031 TARGET_PT_RESULT = 43,
4032 TARGET_PT_REGS_COUNT = 44
4033};
4034
4035
4036
4037struct target_mcontext {
4038 target_ulong mc_gregs[48];
4039
4040 uint64_t mc_fregs[33];
4041 target_ulong mc_pad[2];
4042
4043
4044
4045
4046 union {
4047
4048 uint32_t spe[33];
4049
4050
4051
4052#if defined(TARGET_PPC64)
4053#define QEMU_NVRREG 34
4054#else
4055#define QEMU_NVRREG 33
4056#endif
4057 ppc_avr_t altivec[QEMU_NVRREG];
4058#undef QEMU_NVRREG
4059 } mc_vregs __attribute__((__aligned__(16)));
4060};
4061
4062struct target_ucontext {
4063 target_ulong tuc_flags;
4064 target_ulong tuc_link;
4065 struct target_sigaltstack tuc_stack;
4066#if !defined(TARGET_PPC64)
4067 int32_t tuc_pad[7];
4068 target_ulong tuc_regs;
4069
4070#endif
4071 target_sigset_t tuc_sigmask;
4072#if defined(TARGET_PPC64)
4073 target_sigset_t unused[15];
4074 struct target_sigcontext tuc_mcontext;
4075#else
4076 int32_t tuc_maskext[30];
4077 int32_t tuc_pad2[3];
4078 struct target_mcontext tuc_mcontext;
4079#endif
4080};
4081
4082
4083struct target_sigframe {
4084 struct target_sigcontext sctx;
4085 struct target_mcontext mctx;
4086 int32_t abigap[56];
4087};
4088
4089struct target_rt_sigframe {
4090 struct target_siginfo info;
4091 struct target_ucontext uc;
4092 int32_t abigap[56];
4093};
4094
4095
4096#define tramp mc_pad
4097
4098
4099static target_ulong get_sigframe(struct target_sigaction *ka,
4100 CPUState *env,
4101 int frame_size)
4102{
4103 target_ulong oldsp, newsp;
4104
4105 oldsp = env->gpr[1];
4106
4107 if ((ka->sa_flags & TARGET_SA_ONSTACK) &&
4108 (sas_ss_flags(oldsp))) {
4109 oldsp = (target_sigaltstack_used.ss_sp
4110 + target_sigaltstack_used.ss_size);
4111 }
4112
4113 newsp = (oldsp - frame_size) & ~0xFUL;
4114
4115 return newsp;
4116}
4117
4118static int save_user_regs(CPUState *env, struct target_mcontext *frame,
4119 int sigret)
4120{
4121 target_ulong msr = env->msr;
4122 int i;
4123 target_ulong ccr = 0;
4124
4125
4126
4127
4128
4129
4130 for (i = 0; i < ARRAY_SIZE(env->gpr); i++) {
4131 if (__put_user(env->gpr[i], &frame->mc_gregs[i])) {
4132 return 1;
4133 }
4134 }
4135 if (__put_user(env->nip, &frame->mc_gregs[TARGET_PT_NIP])
4136 || __put_user(env->ctr, &frame->mc_gregs[TARGET_PT_CTR])
4137 || __put_user(env->lr, &frame->mc_gregs[TARGET_PT_LNK])
4138 || __put_user(env->xer, &frame->mc_gregs[TARGET_PT_XER]))
4139 return 1;
4140
4141 for (i = 0; i < ARRAY_SIZE(env->crf); i++) {
4142 ccr |= env->crf[i] << (32 - ((i + 1) * 4));
4143 }
4144 if (__put_user(ccr, &frame->mc_gregs[TARGET_PT_CCR]))
4145 return 1;
4146
4147
4148 if (env->insns_flags & PPC_ALTIVEC) {
4149 for (i = 0; i < ARRAY_SIZE(env->avr); i++) {
4150 ppc_avr_t *avr = &env->avr[i];
4151 ppc_avr_t *vreg = &frame->mc_vregs.altivec[i];
4152
4153 if (__put_user(avr->u64[0], &vreg->u64[0]) ||
4154 __put_user(avr->u64[1], &vreg->u64[1])) {
4155 return 1;
4156 }
4157 }
4158
4159
4160 msr |= MSR_VR;
4161 if (__put_user((uint32_t)env->spr[SPR_VRSAVE],
4162 &frame->mc_vregs.altivec[32].u32[3]))
4163 return 1;
4164 }
4165
4166
4167 if (env->insns_flags & PPC_FLOAT) {
4168 for (i = 0; i < ARRAY_SIZE(env->fpr); i++) {
4169 if (__put_user(env->fpr[i], &frame->mc_fregs[i])) {
4170 return 1;
4171 }
4172 }
4173 if (__put_user((uint64_t) env->fpscr, &frame->mc_fregs[32]))
4174 return 1;
4175 }
4176
4177
4178 if (env->insns_flags & PPC_SPE) {
4179#if defined(TARGET_PPC64)
4180 for (i = 0; i < ARRAY_SIZE(env->gpr); i++) {
4181 if (__put_user(env->gpr[i] >> 32, &frame->mc_vregs.spe[i])) {
4182 return 1;
4183 }
4184 }
4185#else
4186 for (i = 0; i < ARRAY_SIZE(env->gprh); i++) {
4187 if (__put_user(env->gprh[i], &frame->mc_vregs.spe[i])) {
4188 return 1;
4189 }
4190 }
4191#endif
4192
4193
4194 msr |= MSR_SPE;
4195 if (__put_user(env->spe_fscr, &frame->mc_vregs.spe[32]))
4196 return 1;
4197 }
4198
4199
4200 if (__put_user(msr, &frame->mc_gregs[TARGET_PT_MSR]))
4201 return 1;
4202
4203
4204 if (sigret) {
4205 if (__put_user(0x38000000UL | sigret, &frame->tramp[0]) ||
4206 __put_user(0x44000002UL, &frame->tramp[1])) {
4207 return 1;
4208 }
4209 }
4210
4211 return 0;
4212}
4213
4214static int restore_user_regs(CPUState *env,
4215 struct target_mcontext *frame, int sig)
4216{
4217 target_ulong save_r2 = 0;
4218 target_ulong msr;
4219 target_ulong ccr;
4220
4221 int i;
4222
4223 if (!sig) {
4224 save_r2 = env->gpr[2];
4225 }
4226
4227
4228 for (i = 0; i < ARRAY_SIZE(env->gpr); i++) {
4229 if (__get_user(env->gpr[i], &frame->mc_gregs[i])) {
4230 return 1;
4231 }
4232 }
4233 if (__get_user(env->nip, &frame->mc_gregs[TARGET_PT_NIP])
4234 || __get_user(env->ctr, &frame->mc_gregs[TARGET_PT_CTR])
4235 || __get_user(env->lr, &frame->mc_gregs[TARGET_PT_LNK])
4236 || __get_user(env->xer, &frame->mc_gregs[TARGET_PT_XER]))
4237 return 1;
4238 if (__get_user(ccr, &frame->mc_gregs[TARGET_PT_CCR]))
4239 return 1;
4240
4241 for (i = 0; i < ARRAY_SIZE(env->crf); i++) {
4242 env->crf[i] = (ccr >> (32 - ((i + 1) * 4))) & 0xf;
4243 }
4244
4245 if (!sig) {
4246 env->gpr[2] = save_r2;
4247 }
4248
4249 if (__get_user(msr, &frame->mc_gregs[TARGET_PT_MSR]))
4250 return 1;
4251
4252
4253 if (sig)
4254 env->msr = (env->msr & ~MSR_LE) | (msr & MSR_LE);
4255
4256
4257 if (env->insns_flags & PPC_ALTIVEC) {
4258 for (i = 0; i < ARRAY_SIZE(env->avr); i++) {
4259 ppc_avr_t *avr = &env->avr[i];
4260 ppc_avr_t *vreg = &frame->mc_vregs.altivec[i];
4261
4262 if (__get_user(avr->u64[0], &vreg->u64[0]) ||
4263 __get_user(avr->u64[1], &vreg->u64[1])) {
4264 return 1;
4265 }
4266 }
4267
4268
4269 if (__get_user(env->spr[SPR_VRSAVE],
4270 (target_ulong *)(&frame->mc_vregs.altivec[32].u32[3])))
4271 return 1;
4272 }
4273
4274
4275 if (env->insns_flags & PPC_FLOAT) {
4276 uint64_t fpscr;
4277 for (i = 0; i < ARRAY_SIZE(env->fpr); i++) {
4278 if (__get_user(env->fpr[i], &frame->mc_fregs[i])) {
4279 return 1;
4280 }
4281 }
4282 if (__get_user(fpscr, &frame->mc_fregs[32]))
4283 return 1;
4284 env->fpscr = (uint32_t) fpscr;
4285 }
4286
4287
4288 if (env->insns_flags & PPC_SPE) {
4289#if defined(TARGET_PPC64)
4290 for (i = 0; i < ARRAY_SIZE(env->gpr); i++) {
4291 uint32_t hi;
4292
4293 if (__get_user(hi, &frame->mc_vregs.spe[i])) {
4294 return 1;
4295 }
4296 env->gpr[i] = ((uint64_t)hi << 32) | ((uint32_t) env->gpr[i]);
4297 }
4298#else
4299 for (i = 0; i < ARRAY_SIZE(env->gprh); i++) {
4300 if (__get_user(env->gprh[i], &frame->mc_vregs.spe[i])) {
4301 return 1;
4302 }
4303 }
4304#endif
4305 if (__get_user(env->spe_fscr, &frame->mc_vregs.spe[32]))
4306 return 1;
4307 }
4308
4309 return 0;
4310}
4311
4312static void setup_frame(int sig, struct target_sigaction *ka,
4313 target_sigset_t *set, CPUState *env)
4314{
4315 struct target_sigframe *frame;
4316 struct target_sigcontext *sc;
4317 target_ulong frame_addr, newsp;
4318 int err = 0;
4319 int signal;
4320
4321 frame_addr = get_sigframe(ka, env, sizeof(*frame));
4322 if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 1))
4323 goto sigsegv;
4324 sc = &frame->sctx;
4325
4326 signal = current_exec_domain_sig(sig);
4327
4328 err |= __put_user(h2g(ka->_sa_handler), &sc->handler);
4329 err |= __put_user(set->sig[0], &sc->oldmask);
4330#if defined(TARGET_PPC64)
4331 err |= __put_user(set->sig[0] >> 32, &sc->_unused[3]);
4332#else
4333 err |= __put_user(set->sig[1], &sc->_unused[3]);
4334#endif
4335 err |= __put_user(h2g(&frame->mctx), &sc->regs);
4336 err |= __put_user(sig, &sc->signal);
4337
4338
4339 err |= save_user_regs(env, &frame->mctx, TARGET_NR_sigreturn);
4340
4341
4342
4343 env->lr = (target_ulong) h2g(frame->mctx.tramp);
4344
4345
4346 env->fpscr = 0;
4347
4348
4349 newsp = frame_addr - SIGNAL_FRAMESIZE;
4350 err |= __put_user(env->gpr[1], (target_ulong *)(uintptr_t) newsp);
4351
4352 if (err)
4353 goto sigsegv;
4354
4355
4356 env->gpr[1] = newsp;
4357 env->gpr[3] = signal;
4358 env->gpr[4] = (target_ulong) h2g(sc);
4359 env->nip = (target_ulong) ka->_sa_handler;
4360
4361 env->msr &= ~MSR_LE;
4362
4363 unlock_user_struct(frame, frame_addr, 1);
4364 return;
4365
4366sigsegv:
4367 unlock_user_struct(frame, frame_addr, 1);
4368 if (logfile)
4369 fprintf (logfile, "segfaulting from setup_frame\n");
4370 force_sig(TARGET_SIGSEGV);
4371}
4372
4373static void setup_rt_frame(int sig, struct target_sigaction *ka,
4374 target_siginfo_t *info,
4375 target_sigset_t *set, CPUState *env)
4376{
4377 struct target_rt_sigframe *rt_sf;
4378 struct target_mcontext *frame;
4379 target_ulong rt_sf_addr, newsp = 0;
4380 int i, err = 0;
4381 int signal;
4382
4383 rt_sf_addr = get_sigframe(ka, env, sizeof(*rt_sf));
4384 if (!lock_user_struct(VERIFY_WRITE, rt_sf, rt_sf_addr, 1))
4385 goto sigsegv;
4386
4387 signal = current_exec_domain_sig(sig);
4388
4389 err |= copy_siginfo_to_user(&rt_sf->info, info);
4390
4391 err |= __put_user(0, &rt_sf->uc.tuc_flags);
4392 err |= __put_user(0, &rt_sf->uc.tuc_link);
4393 err |= __put_user((target_ulong)target_sigaltstack_used.ss_sp,
4394 &rt_sf->uc.tuc_stack.ss_sp);
4395 err |= __put_user(sas_ss_flags(env->gpr[1]),
4396 &rt_sf->uc.tuc_stack.ss_flags);
4397 err |= __put_user(target_sigaltstack_used.ss_size,
4398 &rt_sf->uc.tuc_stack.ss_size);
4399 err |= __put_user(h2g (&rt_sf->uc.tuc_mcontext),
4400 &rt_sf->uc.tuc_regs);
4401 for(i = 0; i < TARGET_NSIG_WORDS; i++) {
4402 err |= __put_user(set->sig[i], &rt_sf->uc.tuc_sigmask.sig[i]);
4403 }
4404
4405 frame = &rt_sf->uc.tuc_mcontext;
4406 err |= save_user_regs(env, frame, TARGET_NR_rt_sigreturn);
4407
4408
4409
4410 env->lr = (target_ulong) h2g(frame->tramp);
4411
4412
4413 env->fpscr = 0;
4414
4415
4416 newsp = rt_sf_addr - (SIGNAL_FRAMESIZE + 16);
4417 err |= __put_user(env->gpr[1], (target_ulong *)(uintptr_t) newsp);
4418
4419 if (err)
4420 goto sigsegv;
4421
4422
4423 env->gpr[1] = newsp;
4424 env->gpr[3] = (target_ulong) signal;
4425 env->gpr[4] = (target_ulong) h2g(&rt_sf->info);
4426 env->gpr[5] = (target_ulong) h2g(&rt_sf->uc);
4427 env->gpr[6] = (target_ulong) h2g(rt_sf);
4428 env->nip = (target_ulong) ka->_sa_handler;
4429
4430 env->msr &= ~MSR_LE;
4431
4432 unlock_user_struct(rt_sf, rt_sf_addr, 1);
4433 return;
4434
4435sigsegv:
4436 unlock_user_struct(rt_sf, rt_sf_addr, 1);
4437 if (logfile)
4438 fprintf (logfile, "segfaulting from setup_rt_frame\n");
4439 force_sig(TARGET_SIGSEGV);
4440
4441}
4442
4443long do_sigreturn(CPUState *env)
4444{
4445 struct target_sigcontext *sc = NULL;
4446 struct target_mcontext *sr = NULL;
4447 target_ulong sr_addr, sc_addr;
4448 sigset_t blocked;
4449 target_sigset_t set;
4450
4451 sc_addr = env->gpr[1] + SIGNAL_FRAMESIZE;
4452 if (!lock_user_struct(VERIFY_READ, sc, sc_addr, 1))
4453 goto sigsegv;
4454
4455#if defined(TARGET_PPC64)
4456 set.sig[0] = sc->oldmask + ((long)(sc->_unused[3]) << 32);
4457#else
4458 if(__get_user(set.sig[0], &sc->oldmask) ||
4459 __get_user(set.sig[1], &sc->_unused[3]))
4460 goto sigsegv;
4461#endif
4462 target_to_host_sigset_internal(&blocked, &set);
4463 sigprocmask(SIG_SETMASK, &blocked, NULL);
4464
4465 if (__get_user(sr_addr, &sc->regs))
4466 goto sigsegv;
4467 if (!lock_user_struct(VERIFY_READ, sr, sr_addr, 1))
4468 goto sigsegv;
4469 if (restore_user_regs(env, sr, 1))
4470 goto sigsegv;
4471
4472 unlock_user_struct(sr, sr_addr, 1);
4473 unlock_user_struct(sc, sc_addr, 1);
4474 return -TARGET_QEMU_ESIGRETURN;
4475
4476sigsegv:
4477 unlock_user_struct(sr, sr_addr, 1);
4478 unlock_user_struct(sc, sc_addr, 1);
4479 if (logfile)
4480 fprintf (logfile, "segfaulting from do_sigreturn\n");
4481 force_sig(TARGET_SIGSEGV);
4482 return 0;
4483}
4484
4485
4486static int do_setcontext(struct target_ucontext *ucp, CPUState *env, int sig)
4487{
4488 struct target_mcontext *mcp;
4489 target_ulong mcp_addr;
4490 sigset_t blocked;
4491 target_sigset_t set;
4492
4493 if (copy_from_user(&set, h2g(ucp) + offsetof(struct target_ucontext, tuc_sigmask),
4494 sizeof (set)))
4495 return 1;
4496
4497#if defined(TARGET_PPC64)
4498 fprintf (stderr, "do_setcontext: not implemented\n");
4499 return 0;
4500#else
4501 if (__get_user(mcp_addr, &ucp->tuc_regs))
4502 return 1;
4503
4504 if (!lock_user_struct(VERIFY_READ, mcp, mcp_addr, 1))
4505 return 1;
4506
4507 target_to_host_sigset_internal(&blocked, &set);
4508 sigprocmask(SIG_SETMASK, &blocked, NULL);
4509 if (restore_user_regs(env, mcp, sig))
4510 goto sigsegv;
4511
4512 unlock_user_struct(mcp, mcp_addr, 1);
4513 return 0;
4514
4515sigsegv:
4516 unlock_user_struct(mcp, mcp_addr, 1);
4517 return 1;
4518#endif
4519}
4520
4521long do_rt_sigreturn(CPUState *env)
4522{
4523 struct target_rt_sigframe *rt_sf = NULL;
4524 target_ulong rt_sf_addr;
4525
4526 rt_sf_addr = env->gpr[1] + SIGNAL_FRAMESIZE + 16;
4527 if (!lock_user_struct(VERIFY_READ, rt_sf, rt_sf_addr, 1))
4528 goto sigsegv;
4529
4530 if (do_setcontext(&rt_sf->uc, env, 1))
4531 goto sigsegv;
4532
4533 do_sigaltstack(rt_sf_addr
4534 + offsetof(struct target_rt_sigframe, uc.tuc_stack),
4535 0, env->gpr[1]);
4536
4537 unlock_user_struct(rt_sf, rt_sf_addr, 1);
4538 return -TARGET_QEMU_ESIGRETURN;
4539
4540sigsegv:
4541 unlock_user_struct(rt_sf, rt_sf_addr, 1);
4542 if (logfile)
4543 fprintf (logfile, "segfaulting from do_rt_sigreturn\n");
4544 force_sig(TARGET_SIGSEGV);
4545 return 0;
4546}
4547
4548#elif defined(TARGET_M68K)
4549
4550struct target_sigcontext {
4551 abi_ulong sc_mask;
4552 abi_ulong sc_usp;
4553 abi_ulong sc_d0;
4554 abi_ulong sc_d1;
4555 abi_ulong sc_a0;
4556 abi_ulong sc_a1;
4557 unsigned short sc_sr;
4558 abi_ulong sc_pc;
4559};
4560
4561struct target_sigframe
4562{
4563 abi_ulong pretcode;
4564 int sig;
4565 int code;
4566 abi_ulong psc;
4567 char retcode[8];
4568 abi_ulong extramask[TARGET_NSIG_WORDS-1];
4569 struct target_sigcontext sc;
4570};
4571
4572typedef int target_greg_t;
4573#define TARGET_NGREG 18
4574typedef target_greg_t target_gregset_t[TARGET_NGREG];
4575
4576typedef struct target_fpregset {
4577 int f_fpcntl[3];
4578 int f_fpregs[8*3];
4579} target_fpregset_t;
4580
4581struct target_mcontext {
4582 int version;
4583 target_gregset_t gregs;
4584 target_fpregset_t fpregs;
4585};
4586
4587#define TARGET_MCONTEXT_VERSION 2
4588
4589struct target_ucontext {
4590 abi_ulong tuc_flags;
4591 abi_ulong tuc_link;
4592 target_stack_t tuc_stack;
4593 struct target_mcontext tuc_mcontext;
4594 abi_long tuc_filler[80];
4595 target_sigset_t tuc_sigmask;
4596};
4597
4598struct target_rt_sigframe
4599{
4600 abi_ulong pretcode;
4601 int sig;
4602 abi_ulong pinfo;
4603 abi_ulong puc;
4604 char retcode[8];
4605 struct target_siginfo info;
4606 struct target_ucontext uc;
4607};
4608
4609static int
4610setup_sigcontext(struct target_sigcontext *sc, CPUState *env, abi_ulong mask)
4611{
4612 int err = 0;
4613
4614 err |= __put_user(mask, &sc->sc_mask);
4615 err |= __put_user(env->aregs[7], &sc->sc_usp);
4616 err |= __put_user(env->dregs[0], &sc->sc_d0);
4617 err |= __put_user(env->dregs[1], &sc->sc_d1);
4618 err |= __put_user(env->aregs[0], &sc->sc_a0);
4619 err |= __put_user(env->aregs[1], &sc->sc_a1);
4620 err |= __put_user(env->sr, &sc->sc_sr);
4621 err |= __put_user(env->pc, &sc->sc_pc);
4622
4623 return err;
4624}
4625
4626static int
4627restore_sigcontext(CPUState *env, struct target_sigcontext *sc, int *pd0)
4628{
4629 int err = 0;
4630 int temp;
4631
4632 err |= __get_user(env->aregs[7], &sc->sc_usp);
4633 err |= __get_user(env->dregs[1], &sc->sc_d1);
4634 err |= __get_user(env->aregs[0], &sc->sc_a0);
4635 err |= __get_user(env->aregs[1], &sc->sc_a1);
4636 err |= __get_user(env->pc, &sc->sc_pc);
4637 err |= __get_user(temp, &sc->sc_sr);
4638 env->sr = (env->sr & 0xff00) | (temp & 0xff);
4639
4640 *pd0 = tswapl(sc->sc_d0);
4641
4642 return err;
4643}
4644
4645
4646
4647
4648static inline abi_ulong
4649get_sigframe(struct target_sigaction *ka, CPUState *regs, size_t frame_size)
4650{
4651 unsigned long sp;
4652
4653 sp = regs->aregs[7];
4654
4655
4656 if ((ka->sa_flags & TARGET_SA_ONSTACK) && (sas_ss_flags (sp) == 0)) {
4657 sp = target_sigaltstack_used.ss_sp + target_sigaltstack_used.ss_size;
4658 }
4659
4660 return ((sp - frame_size) & -8UL);
4661}
4662
4663static void setup_frame(int sig, struct target_sigaction *ka,
4664 target_sigset_t *set, CPUState *env)
4665{
4666 struct target_sigframe *frame;
4667 abi_ulong frame_addr;
4668 abi_ulong retcode_addr;
4669 abi_ulong sc_addr;
4670 int err = 0;
4671 int i;
4672
4673 frame_addr = get_sigframe(ka, env, sizeof *frame);
4674 if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
4675 goto give_sigsegv;
4676
4677 err |= __put_user(sig, &frame->sig);
4678
4679 sc_addr = frame_addr + offsetof(struct target_sigframe, sc);
4680 err |= __put_user(sc_addr, &frame->psc);
4681
4682 err |= setup_sigcontext(&frame->sc, env, set->sig[0]);
4683 if (err)
4684 goto give_sigsegv;
4685
4686 for(i = 1; i < TARGET_NSIG_WORDS; i++) {
4687 if (__put_user(set->sig[i], &frame->extramask[i - 1]))
4688 goto give_sigsegv;
4689 }
4690
4691
4692
4693 retcode_addr = frame_addr + offsetof(struct target_sigframe, retcode);
4694 err |= __put_user(retcode_addr, &frame->pretcode);
4695
4696
4697
4698 err |= __put_user(0x70004e40 + (TARGET_NR_sigreturn << 16),
4699 (long *)(frame->retcode));
4700
4701 if (err)
4702 goto give_sigsegv;
4703
4704
4705
4706 env->aregs[7] = frame_addr;
4707 env->pc = ka->_sa_handler;
4708
4709 unlock_user_struct(frame, frame_addr, 1);
4710 return;
4711
4712give_sigsegv:
4713 unlock_user_struct(frame, frame_addr, 1);
4714 force_sig(TARGET_SIGSEGV);
4715}
4716
4717static inline int target_rt_setup_ucontext(struct target_ucontext *uc,
4718 CPUState *env)
4719{
4720 target_greg_t *gregs = uc->tuc_mcontext.gregs;
4721 int err;
4722
4723 err = __put_user(TARGET_MCONTEXT_VERSION, &uc->tuc_mcontext.version);
4724 err |= __put_user(env->dregs[0], &gregs[0]);
4725 err |= __put_user(env->dregs[1], &gregs[1]);
4726 err |= __put_user(env->dregs[2], &gregs[2]);
4727 err |= __put_user(env->dregs[3], &gregs[3]);
4728 err |= __put_user(env->dregs[4], &gregs[4]);
4729 err |= __put_user(env->dregs[5], &gregs[5]);
4730 err |= __put_user(env->dregs[6], &gregs[6]);
4731 err |= __put_user(env->dregs[7], &gregs[7]);
4732 err |= __put_user(env->aregs[0], &gregs[8]);
4733 err |= __put_user(env->aregs[1], &gregs[9]);
4734 err |= __put_user(env->aregs[2], &gregs[10]);
4735 err |= __put_user(env->aregs[3], &gregs[11]);
4736 err |= __put_user(env->aregs[4], &gregs[12]);
4737 err |= __put_user(env->aregs[5], &gregs[13]);
4738 err |= __put_user(env->aregs[6], &gregs[14]);
4739 err |= __put_user(env->aregs[7], &gregs[15]);
4740 err |= __put_user(env->pc, &gregs[16]);
4741 err |= __put_user(env->sr, &gregs[17]);
4742
4743 return err;
4744}
4745
4746static inline int target_rt_restore_ucontext(CPUState *env,
4747 struct target_ucontext *uc,
4748 int *pd0)
4749{
4750 int temp;
4751 int err;
4752 target_greg_t *gregs = uc->tuc_mcontext.gregs;
4753
4754 err = __get_user(temp, &uc->tuc_mcontext.version);
4755 if (temp != TARGET_MCONTEXT_VERSION)
4756 goto badframe;
4757
4758
4759 err |= __get_user(env->dregs[0], &gregs[0]);
4760 err |= __get_user(env->dregs[1], &gregs[1]);
4761 err |= __get_user(env->dregs[2], &gregs[2]);
4762 err |= __get_user(env->dregs[3], &gregs[3]);
4763 err |= __get_user(env->dregs[4], &gregs[4]);
4764 err |= __get_user(env->dregs[5], &gregs[5]);
4765 err |= __get_user(env->dregs[6], &gregs[6]);
4766 err |= __get_user(env->dregs[7], &gregs[7]);
4767 err |= __get_user(env->aregs[0], &gregs[8]);
4768 err |= __get_user(env->aregs[1], &gregs[9]);
4769 err |= __get_user(env->aregs[2], &gregs[10]);
4770 err |= __get_user(env->aregs[3], &gregs[11]);
4771 err |= __get_user(env->aregs[4], &gregs[12]);
4772 err |= __get_user(env->aregs[5], &gregs[13]);
4773 err |= __get_user(env->aregs[6], &gregs[14]);
4774 err |= __get_user(env->aregs[7], &gregs[15]);
4775 err |= __get_user(env->pc, &gregs[16]);
4776 err |= __get_user(temp, &gregs[17]);
4777 env->sr = (env->sr & 0xff00) | (temp & 0xff);
4778
4779 *pd0 = env->dregs[0];
4780 return err;
4781
4782badframe:
4783 return 1;
4784}
4785
4786static void setup_rt_frame(int sig, struct target_sigaction *ka,
4787 target_siginfo_t *info,
4788 target_sigset_t *set, CPUState *env)
4789{
4790 struct target_rt_sigframe *frame;
4791 abi_ulong frame_addr;
4792 abi_ulong retcode_addr;
4793 abi_ulong info_addr;
4794 abi_ulong uc_addr;
4795 int err = 0;
4796 int i;
4797
4798 frame_addr = get_sigframe(ka, env, sizeof *frame);
4799 if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
4800 goto give_sigsegv;
4801
4802 err |= __put_user(sig, &frame->sig);
4803
4804 info_addr = frame_addr + offsetof(struct target_rt_sigframe, info);
4805 err |= __put_user(info_addr, &frame->pinfo);
4806
4807 uc_addr = frame_addr + offsetof(struct target_rt_sigframe, uc);
4808 err |= __put_user(uc_addr, &frame->puc);
4809
4810 err |= copy_siginfo_to_user(&frame->info, info);
4811
4812
4813
4814 err |= __put_user(0, &frame->uc.tuc_flags);
4815 err |= __put_user(0, &frame->uc.tuc_link);
4816 err |= __put_user(target_sigaltstack_used.ss_sp,
4817 &frame->uc.tuc_stack.ss_sp);
4818 err |= __put_user(sas_ss_flags(env->aregs[7]),
4819 &frame->uc.tuc_stack.ss_flags);
4820 err |= __put_user(target_sigaltstack_used.ss_size,
4821 &frame->uc.tuc_stack.ss_size);
4822 err |= target_rt_setup_ucontext(&frame->uc, env);
4823
4824 if (err)
4825 goto give_sigsegv;
4826
4827 for(i = 0; i < TARGET_NSIG_WORDS; i++) {
4828 if (__put_user(set->sig[i], &frame->uc.tuc_sigmask.sig[i]))
4829 goto give_sigsegv;
4830 }
4831
4832
4833
4834 retcode_addr = frame_addr + offsetof(struct target_sigframe, retcode);
4835 err |= __put_user(retcode_addr, &frame->pretcode);
4836
4837
4838
4839 err |= __put_user(0x70004600 + ((TARGET_NR_rt_sigreturn ^ 0xff) << 16),
4840 (long *)(frame->retcode + 0));
4841 err |= __put_user(0x4e40, (short *)(frame->retcode + 4));
4842
4843 if (err)
4844 goto give_sigsegv;
4845
4846
4847
4848 env->aregs[7] = frame_addr;
4849 env->pc = ka->_sa_handler;
4850
4851 unlock_user_struct(frame, frame_addr, 1);
4852 return;
4853
4854give_sigsegv:
4855 unlock_user_struct(frame, frame_addr, 1);
4856 force_sig(TARGET_SIGSEGV);
4857}
4858
4859long do_sigreturn(CPUState *env)
4860{
4861 struct target_sigframe *frame;
4862 abi_ulong frame_addr = env->aregs[7] - 4;
4863 target_sigset_t target_set;
4864 sigset_t set;
4865 int d0, i;
4866
4867 if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1))
4868 goto badframe;
4869
4870
4871
4872 if (__get_user(target_set.sig[0], &frame->sc.sc_mask))
4873 goto badframe;
4874
4875 for(i = 1; i < TARGET_NSIG_WORDS; i++) {
4876 if (__get_user(target_set.sig[i], &frame->extramask[i - 1]))
4877 goto badframe;
4878 }
4879
4880 target_to_host_sigset_internal(&set, &target_set);
4881 sigprocmask(SIG_SETMASK, &set, NULL);
4882
4883
4884
4885 if (restore_sigcontext(env, &frame->sc, &d0))
4886 goto badframe;
4887
4888 unlock_user_struct(frame, frame_addr, 0);
4889 return d0;
4890
4891badframe:
4892 unlock_user_struct(frame, frame_addr, 0);
4893 force_sig(TARGET_SIGSEGV);
4894 return 0;
4895}
4896
4897long do_rt_sigreturn(CPUState *env)
4898{
4899 struct target_rt_sigframe *frame;
4900 abi_ulong frame_addr = env->aregs[7] - 4;
4901 target_sigset_t target_set;
4902 sigset_t set;
4903 int d0;
4904
4905 if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1))
4906 goto badframe;
4907
4908 target_to_host_sigset_internal(&set, &target_set);
4909 sigprocmask(SIG_SETMASK, &set, NULL);
4910
4911
4912
4913 if (target_rt_restore_ucontext(env, &frame->uc, &d0))
4914 goto badframe;
4915
4916 if (do_sigaltstack(frame_addr +
4917 offsetof(struct target_rt_sigframe, uc.tuc_stack),
4918 0, get_sp_from_cpustate(env)) == -EFAULT)
4919 goto badframe;
4920
4921 unlock_user_struct(frame, frame_addr, 0);
4922 return d0;
4923
4924badframe:
4925 unlock_user_struct(frame, frame_addr, 0);
4926 force_sig(TARGET_SIGSEGV);
4927 return 0;
4928}
4929
4930#elif defined(TARGET_ALPHA)
4931
4932struct target_sigcontext {
4933 abi_long sc_onstack;
4934 abi_long sc_mask;
4935 abi_long sc_pc;
4936 abi_long sc_ps;
4937 abi_long sc_regs[32];
4938 abi_long sc_ownedfp;
4939 abi_long sc_fpregs[32];
4940 abi_ulong sc_fpcr;
4941 abi_ulong sc_fp_control;
4942 abi_ulong sc_reserved1;
4943 abi_ulong sc_reserved2;
4944 abi_ulong sc_ssize;
4945 abi_ulong sc_sbase;
4946 abi_ulong sc_traparg_a0;
4947 abi_ulong sc_traparg_a1;
4948 abi_ulong sc_traparg_a2;
4949 abi_ulong sc_fp_trap_pc;
4950 abi_ulong sc_fp_trigger_sum;
4951 abi_ulong sc_fp_trigger_inst;
4952};
4953
4954struct target_ucontext {
4955 abi_ulong tuc_flags;
4956 abi_ulong tuc_link;
4957 abi_ulong tuc_osf_sigmask;
4958 target_stack_t tuc_stack;
4959 struct target_sigcontext tuc_mcontext;
4960 target_sigset_t tuc_sigmask;
4961};
4962
4963struct target_sigframe {
4964 struct target_sigcontext sc;
4965 unsigned int retcode[3];
4966};
4967
4968struct target_rt_sigframe {
4969 target_siginfo_t info;
4970 struct target_ucontext uc;
4971 unsigned int retcode[3];
4972};
4973
4974#define INSN_MOV_R30_R16 0x47fe0410
4975#define INSN_LDI_R0 0x201f0000
4976#define INSN_CALLSYS 0x00000083
4977
4978static int setup_sigcontext(struct target_sigcontext *sc, CPUState *env,
4979 abi_ulong frame_addr, target_sigset_t *set)
4980{
4981 int i, err = 0;
4982
4983 err |= __put_user(on_sig_stack(frame_addr), &sc->sc_onstack);
4984 err |= __put_user(set->sig[0], &sc->sc_mask);
4985 err |= __put_user(env->pc, &sc->sc_pc);
4986 err |= __put_user(8, &sc->sc_ps);
4987
4988 for (i = 0; i < 31; ++i) {
4989 err |= __put_user(env->ir[i], &sc->sc_regs[i]);
4990 }
4991 err |= __put_user(0, &sc->sc_regs[31]);
4992
4993 for (i = 0; i < 31; ++i) {
4994 err |= __put_user(env->fir[i], &sc->sc_fpregs[i]);
4995 }
4996 err |= __put_user(0, &sc->sc_fpregs[31]);
4997 err |= __put_user(cpu_alpha_load_fpcr(env), &sc->sc_fpcr);
4998
4999 err |= __put_user(0, &sc->sc_traparg_a0);
5000 err |= __put_user(0, &sc->sc_traparg_a1);
5001 err |= __put_user(0, &sc->sc_traparg_a2);
5002
5003 return err;
5004}
5005
5006static int restore_sigcontext(CPUState *env, struct target_sigcontext *sc)
5007{
5008 uint64_t fpcr;
5009 int i, err = 0;
5010
5011 err |= __get_user(env->pc, &sc->sc_pc);
5012
5013 for (i = 0; i < 31; ++i) {
5014 err |= __get_user(env->ir[i], &sc->sc_regs[i]);
5015 }
5016 for (i = 0; i < 31; ++i) {
5017 err |= __get_user(env->fir[i], &sc->sc_fpregs[i]);
5018 }
5019
5020 err |= __get_user(fpcr, &sc->sc_fpcr);
5021 cpu_alpha_store_fpcr(env, fpcr);
5022
5023 return err;
5024}
5025
5026static inline abi_ulong get_sigframe(struct target_sigaction *sa,
5027 CPUState *env, unsigned long framesize)
5028{
5029 abi_ulong sp = env->ir[IR_SP];
5030
5031
5032 if ((sa->sa_flags & TARGET_SA_ONSTACK) != 0 && !sas_ss_flags(sp)) {
5033 sp = target_sigaltstack_used.ss_sp + target_sigaltstack_used.ss_size;
5034 }
5035 return (sp - framesize) & -32;
5036}
5037
5038static void setup_frame(int sig, struct target_sigaction *ka,
5039 target_sigset_t *set, CPUState *env)
5040{
5041 abi_ulong frame_addr, r26;
5042 struct target_sigframe *frame;
5043 int err = 0;
5044
5045 frame_addr = get_sigframe(ka, env, sizeof(*frame));
5046 if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0)) {
5047 goto give_sigsegv;
5048 }
5049
5050 err |= setup_sigcontext(&frame->sc, env, frame_addr, set);
5051
5052 if (ka->sa_restorer) {
5053 r26 = ka->sa_restorer;
5054 } else {
5055 err |= __put_user(INSN_MOV_R30_R16, &frame->retcode[0]);
5056 err |= __put_user(INSN_LDI_R0 + TARGET_NR_sigreturn,
5057 &frame->retcode[1]);
5058 err |= __put_user(INSN_CALLSYS, &frame->retcode[2]);
5059
5060 r26 = frame_addr;
5061 }
5062
5063 unlock_user_struct(frame, frame_addr, 1);
5064
5065 if (err) {
5066 give_sigsegv:
5067 if (sig == TARGET_SIGSEGV) {
5068 ka->_sa_handler = TARGET_SIG_DFL;
5069 }
5070 force_sig(TARGET_SIGSEGV);
5071 }
5072
5073 env->ir[IR_RA] = r26;
5074 env->ir[IR_PV] = env->pc = ka->_sa_handler;
5075 env->ir[IR_A0] = sig;
5076 env->ir[IR_A1] = 0;
5077 env->ir[IR_A2] = frame_addr + offsetof(struct target_sigframe, sc);
5078 env->ir[IR_SP] = frame_addr;
5079}
5080
5081static void setup_rt_frame(int sig, struct target_sigaction *ka,
5082 target_siginfo_t *info,
5083 target_sigset_t *set, CPUState *env)
5084{
5085 abi_ulong frame_addr, r26;
5086 struct target_rt_sigframe *frame;
5087 int i, err = 0;
5088
5089 frame_addr = get_sigframe(ka, env, sizeof(*frame));
5090 if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0)) {
5091 goto give_sigsegv;
5092 }
5093
5094 err |= copy_siginfo_to_user(&frame->info, info);
5095
5096 err |= __put_user(0, &frame->uc.tuc_flags);
5097 err |= __put_user(0, &frame->uc.tuc_link);
5098 err |= __put_user(set->sig[0], &frame->uc.tuc_osf_sigmask);
5099 err |= __put_user(target_sigaltstack_used.ss_sp,
5100 &frame->uc.tuc_stack.ss_sp);
5101 err |= __put_user(sas_ss_flags(env->ir[IR_SP]),
5102 &frame->uc.tuc_stack.ss_flags);
5103 err |= __put_user(target_sigaltstack_used.ss_size,
5104 &frame->uc.tuc_stack.ss_size);
5105 err |= setup_sigcontext(&frame->uc.tuc_mcontext, env, frame_addr, set);
5106 for (i = 0; i < TARGET_NSIG_WORDS; ++i) {
5107 err |= __put_user(set->sig[i], &frame->uc.tuc_sigmask.sig[i]);
5108 }
5109
5110 if (ka->sa_restorer) {
5111 r26 = ka->sa_restorer;
5112 } else {
5113 err |= __put_user(INSN_MOV_R30_R16, &frame->retcode[0]);
5114 err |= __put_user(INSN_LDI_R0 + TARGET_NR_rt_sigreturn,
5115 &frame->retcode[1]);
5116 err |= __put_user(INSN_CALLSYS, &frame->retcode[2]);
5117
5118 r26 = frame_addr;
5119 }
5120
5121 if (err) {
5122 give_sigsegv:
5123 if (sig == TARGET_SIGSEGV) {
5124 ka->_sa_handler = TARGET_SIG_DFL;
5125 }
5126 force_sig(TARGET_SIGSEGV);
5127 }
5128
5129 env->ir[IR_RA] = r26;
5130 env->ir[IR_PV] = env->pc = ka->_sa_handler;
5131 env->ir[IR_A0] = sig;
5132 env->ir[IR_A1] = frame_addr + offsetof(struct target_rt_sigframe, info);
5133 env->ir[IR_A2] = frame_addr + offsetof(struct target_rt_sigframe, uc);
5134 env->ir[IR_SP] = frame_addr;
5135}
5136
5137long do_sigreturn(CPUState *env)
5138{
5139 struct target_sigcontext *sc;
5140 abi_ulong sc_addr = env->ir[IR_A0];
5141 target_sigset_t target_set;
5142 sigset_t set;
5143
5144 if (!lock_user_struct(VERIFY_READ, sc, sc_addr, 1)) {
5145 goto badframe;
5146 }
5147
5148 target_sigemptyset(&target_set);
5149 if (__get_user(target_set.sig[0], &sc->sc_mask)) {
5150 goto badframe;
5151 }
5152
5153 target_to_host_sigset_internal(&set, &target_set);
5154 sigprocmask(SIG_SETMASK, &set, NULL);
5155
5156 if (restore_sigcontext(env, sc)) {
5157 goto badframe;
5158 }
5159 unlock_user_struct(sc, sc_addr, 0);
5160 return env->ir[IR_V0];
5161
5162 badframe:
5163 unlock_user_struct(sc, sc_addr, 0);
5164 force_sig(TARGET_SIGSEGV);
5165}
5166
5167long do_rt_sigreturn(CPUState *env)
5168{
5169 abi_ulong frame_addr = env->ir[IR_A0];
5170 struct target_rt_sigframe *frame;
5171 sigset_t set;
5172
5173 if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1)) {
5174 goto badframe;
5175 }
5176 target_to_host_sigset(&set, &frame->uc.tuc_sigmask);
5177 sigprocmask(SIG_SETMASK, &set, NULL);
5178
5179 if (restore_sigcontext(env, &frame->uc.tuc_mcontext)) {
5180 goto badframe;
5181 }
5182 if (do_sigaltstack(frame_addr + offsetof(struct target_rt_sigframe,
5183 uc.tuc_stack),
5184 0, env->ir[IR_SP]) == -EFAULT) {
5185 goto badframe;
5186 }
5187
5188 unlock_user_struct(frame, frame_addr, 0);
5189 return env->ir[IR_V0];
5190
5191
5192 badframe:
5193 unlock_user_struct(frame, frame_addr, 0);
5194 force_sig(TARGET_SIGSEGV);
5195}
5196
5197#else
5198
5199static void setup_frame(int sig, struct target_sigaction *ka,
5200 target_sigset_t *set, CPUState *env)
5201{
5202 fprintf(stderr, "setup_frame: not implemented\n");
5203}
5204
5205static void setup_rt_frame(int sig, struct target_sigaction *ka,
5206 target_siginfo_t *info,
5207 target_sigset_t *set, CPUState *env)
5208{
5209 fprintf(stderr, "setup_rt_frame: not implemented\n");
5210}
5211
5212long do_sigreturn(CPUState *env)
5213{
5214 fprintf(stderr, "do_sigreturn: not implemented\n");
5215 return -TARGET_ENOSYS;
5216}
5217
5218long do_rt_sigreturn(CPUState *env)
5219{
5220 fprintf(stderr, "do_rt_sigreturn: not implemented\n");
5221 return -TARGET_ENOSYS;
5222}
5223
5224#endif
5225
5226void process_pending_signals(CPUState *cpu_env)
5227{
5228 int sig;
5229 abi_ulong handler;
5230 sigset_t set, old_set;
5231 target_sigset_t target_old_set;
5232 struct emulated_sigtable *k;
5233 struct target_sigaction *sa;
5234 struct sigqueue *q;
5235 TaskState *ts = cpu_env->opaque;
5236
5237 if (!ts->signal_pending)
5238 return;
5239
5240
5241 k = ts->sigtab;
5242 for(sig = 1; sig <= TARGET_NSIG; sig++) {
5243 if (k->pending)
5244 goto handle_signal;
5245 k++;
5246 }
5247
5248 ts->signal_pending = 0;
5249 return;
5250
5251 handle_signal:
5252#ifdef DEBUG_SIGNAL
5253 fprintf(stderr, "qemu: process signal %d\n", sig);
5254#endif
5255
5256 q = k->first;
5257 k->first = q->next;
5258 if (!k->first)
5259 k->pending = 0;
5260
5261 sig = gdb_handlesig (cpu_env, sig);
5262 if (!sig) {
5263 sa = NULL;
5264 handler = TARGET_SIG_IGN;
5265 } else {
5266 sa = &sigact_table[sig - 1];
5267 handler = sa->_sa_handler;
5268 }
5269
5270 if (handler == TARGET_SIG_DFL) {
5271
5272 if (sig == TARGET_SIGTSTP || sig == TARGET_SIGTTIN || sig == TARGET_SIGTTOU) {
5273 kill(getpid(),SIGSTOP);
5274 } else if (sig != TARGET_SIGCHLD &&
5275 sig != TARGET_SIGURG &&
5276 sig != TARGET_SIGWINCH &&
5277 sig != TARGET_SIGCONT) {
5278 force_sig(sig);
5279 }
5280 } else if (handler == TARGET_SIG_IGN) {
5281
5282 } else if (handler == TARGET_SIG_ERR) {
5283 force_sig(sig);
5284 } else {
5285
5286 target_to_host_sigset(&set, &sa->sa_mask);
5287
5288
5289 if (!(sa->sa_flags & TARGET_SA_NODEFER))
5290 sigaddset(&set, target_to_host_signal(sig));
5291
5292
5293 sigprocmask(SIG_BLOCK, &set, &old_set);
5294
5295
5296 host_to_target_sigset_internal(&target_old_set, &old_set);
5297
5298
5299#if defined(TARGET_I386) && !defined(TARGET_X86_64)
5300 {
5301 CPUX86State *env = cpu_env;
5302 if (env->eflags & VM_MASK)
5303 save_v86_state(env);
5304 }
5305#endif
5306
5307 if (sa->sa_flags & TARGET_SA_SIGINFO)
5308 setup_rt_frame(sig, sa, &q->info, &target_old_set, cpu_env);
5309 else
5310 setup_frame(sig, sa, &target_old_set, cpu_env);
5311 if (sa->sa_flags & TARGET_SA_RESETHAND)
5312 sa->_sa_handler = TARGET_SIG_DFL;
5313 }
5314 if (q != &k->info)
5315 free_sigqueue(cpu_env, q);
5316}
5317