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