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