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