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