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