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