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