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