]> git.proxmox.com Git - qemu.git/blob - linux-user/signal.c
4f3741e912235fb634bbc74c7b9b4f00ae80b085
[qemu.git] / linux-user / signal.c
1 /*
2 * Emulation of Linux signals
3 *
4 * Copyright (c) 2003 Fabrice Bellard
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
19 * MA 02110-1301, USA.
20 */
21 #include <stdlib.h>
22 #include <stdio.h>
23 #include <string.h>
24 #include <stdarg.h>
25 #include <unistd.h>
26 #include <signal.h>
27 #include <errno.h>
28 #include <sys/ucontext.h>
29
30 #include "qemu.h"
31 #include "qemu-common.h"
32 #include "target_signal.h"
33
34 //#define DEBUG_SIGNAL
35
36 static struct target_sigaltstack target_sigaltstack_used = {
37 .ss_sp = 0,
38 .ss_size = 0,
39 .ss_flags = TARGET_SS_DISABLE,
40 };
41
42 static struct target_sigaction sigact_table[TARGET_NSIG];
43
44 static void host_signal_handler(int host_signum, siginfo_t *info,
45 void *puc);
46
47 static uint8_t host_to_target_signal_table[65] = {
48 [SIGHUP] = TARGET_SIGHUP,
49 [SIGINT] = TARGET_SIGINT,
50 [SIGQUIT] = TARGET_SIGQUIT,
51 [SIGILL] = TARGET_SIGILL,
52 [SIGTRAP] = TARGET_SIGTRAP,
53 [SIGABRT] = TARGET_SIGABRT,
54 /* [SIGIOT] = TARGET_SIGIOT,*/
55 [SIGBUS] = TARGET_SIGBUS,
56 [SIGFPE] = TARGET_SIGFPE,
57 [SIGKILL] = TARGET_SIGKILL,
58 [SIGUSR1] = TARGET_SIGUSR1,
59 [SIGSEGV] = TARGET_SIGSEGV,
60 [SIGUSR2] = TARGET_SIGUSR2,
61 [SIGPIPE] = TARGET_SIGPIPE,
62 [SIGALRM] = TARGET_SIGALRM,
63 [SIGTERM] = TARGET_SIGTERM,
64 #ifdef SIGSTKFLT
65 [SIGSTKFLT] = TARGET_SIGSTKFLT,
66 #endif
67 [SIGCHLD] = TARGET_SIGCHLD,
68 [SIGCONT] = TARGET_SIGCONT,
69 [SIGSTOP] = TARGET_SIGSTOP,
70 [SIGTSTP] = TARGET_SIGTSTP,
71 [SIGTTIN] = TARGET_SIGTTIN,
72 [SIGTTOU] = TARGET_SIGTTOU,
73 [SIGURG] = TARGET_SIGURG,
74 [SIGXCPU] = TARGET_SIGXCPU,
75 [SIGXFSZ] = TARGET_SIGXFSZ,
76 [SIGVTALRM] = TARGET_SIGVTALRM,
77 [SIGPROF] = TARGET_SIGPROF,
78 [SIGWINCH] = TARGET_SIGWINCH,
79 [SIGIO] = TARGET_SIGIO,
80 [SIGPWR] = TARGET_SIGPWR,
81 [SIGSYS] = TARGET_SIGSYS,
82 /* next signals stay the same */
83 /* Nasty hack: Reverse SIGRTMIN and SIGRTMAX to avoid overlap with
84 host libpthread signals. This assumes noone actually uses SIGRTMAX :-/
85 To fix this properly we need to do manual signal delivery multiplexed
86 over a single host signal. */
87 [__SIGRTMIN] = __SIGRTMAX,
88 [__SIGRTMAX] = __SIGRTMIN,
89 };
90 static uint8_t target_to_host_signal_table[65];
91
92 static inline int on_sig_stack(unsigned long sp)
93 {
94 return (sp - target_sigaltstack_used.ss_sp
95 < target_sigaltstack_used.ss_size);
96 }
97
98 static inline int sas_ss_flags(unsigned long sp)
99 {
100 return (target_sigaltstack_used.ss_size == 0 ? SS_DISABLE
101 : on_sig_stack(sp) ? SS_ONSTACK : 0);
102 }
103
104 static inline int host_to_target_signal(int sig)
105 {
106 if (sig > 64)
107 return sig;
108 return host_to_target_signal_table[sig];
109 }
110
111 int target_to_host_signal(int sig)
112 {
113 if (sig > 64)
114 return sig;
115 return target_to_host_signal_table[sig];
116 }
117
118 static inline void target_sigemptyset(target_sigset_t *set)
119 {
120 memset(set, 0, sizeof(*set));
121 }
122
123 static inline void target_sigaddset(target_sigset_t *set, int signum)
124 {
125 signum--;
126 abi_ulong mask = (abi_ulong)1 << (signum % TARGET_NSIG_BPW);
127 set->sig[signum / TARGET_NSIG_BPW] |= mask;
128 }
129
130 static inline int target_sigismember(const target_sigset_t *set, int signum)
131 {
132 signum--;
133 abi_ulong mask = (abi_ulong)1 << (signum % TARGET_NSIG_BPW);
134 return ((set->sig[signum / TARGET_NSIG_BPW] & mask) != 0);
135 }
136
137 static void host_to_target_sigset_internal(target_sigset_t *d,
138 const sigset_t *s)
139 {
140 int i;
141 target_sigemptyset(d);
142 for (i = 1; i <= TARGET_NSIG; i++) {
143 if (sigismember(s, i)) {
144 target_sigaddset(d, host_to_target_signal(i));
145 }
146 }
147 }
148
149 void host_to_target_sigset(target_sigset_t *d, const sigset_t *s)
150 {
151 target_sigset_t d1;
152 int i;
153
154 host_to_target_sigset_internal(&d1, s);
155 for(i = 0;i < TARGET_NSIG_WORDS; i++)
156 d->sig[i] = tswapl(d1.sig[i]);
157 }
158
159 static void target_to_host_sigset_internal(sigset_t *d,
160 const target_sigset_t *s)
161 {
162 int i;
163 sigemptyset(d);
164 for (i = 1; i <= TARGET_NSIG; i++) {
165 if (target_sigismember(s, i)) {
166 sigaddset(d, target_to_host_signal(i));
167 }
168 }
169 }
170
171 void target_to_host_sigset(sigset_t *d, const target_sigset_t *s)
172 {
173 target_sigset_t s1;
174 int i;
175
176 for(i = 0;i < TARGET_NSIG_WORDS; i++)
177 s1.sig[i] = tswapl(s->sig[i]);
178 target_to_host_sigset_internal(d, &s1);
179 }
180
181 void host_to_target_old_sigset(abi_ulong *old_sigset,
182 const sigset_t *sigset)
183 {
184 target_sigset_t d;
185 host_to_target_sigset(&d, sigset);
186 *old_sigset = d.sig[0];
187 }
188
189 void target_to_host_old_sigset(sigset_t *sigset,
190 const abi_ulong *old_sigset)
191 {
192 target_sigset_t d;
193 int i;
194
195 d.sig[0] = *old_sigset;
196 for(i = 1;i < TARGET_NSIG_WORDS; i++)
197 d.sig[i] = 0;
198 target_to_host_sigset(sigset, &d);
199 }
200
201 /* siginfo conversion */
202
203 static inline void host_to_target_siginfo_noswap(target_siginfo_t *tinfo,
204 const siginfo_t *info)
205 {
206 int sig;
207 sig = host_to_target_signal(info->si_signo);
208 tinfo->si_signo = sig;
209 tinfo->si_errno = 0;
210 tinfo->si_code = info->si_code;
211 if (sig == SIGILL || sig == SIGFPE || sig == SIGSEGV ||
212 sig == SIGBUS || sig == SIGTRAP) {
213 /* should never come here, but who knows. The information for
214 the target is irrelevant */
215 tinfo->_sifields._sigfault._addr = 0;
216 } else if (sig == SIGIO) {
217 tinfo->_sifields._sigpoll._fd = info->si_fd;
218 } else if (sig >= TARGET_SIGRTMIN) {
219 tinfo->_sifields._rt._pid = info->si_pid;
220 tinfo->_sifields._rt._uid = info->si_uid;
221 /* XXX: potential problem if 64 bit */
222 tinfo->_sifields._rt._sigval.sival_ptr =
223 (abi_ulong)(unsigned long)info->si_value.sival_ptr;
224 }
225 }
226
227 static void tswap_siginfo(target_siginfo_t *tinfo,
228 const target_siginfo_t *info)
229 {
230 int sig;
231 sig = info->si_signo;
232 tinfo->si_signo = tswap32(sig);
233 tinfo->si_errno = tswap32(info->si_errno);
234 tinfo->si_code = tswap32(info->si_code);
235 if (sig == SIGILL || sig == SIGFPE || sig == SIGSEGV ||
236 sig == SIGBUS || sig == SIGTRAP) {
237 tinfo->_sifields._sigfault._addr =
238 tswapl(info->_sifields._sigfault._addr);
239 } else if (sig == SIGIO) {
240 tinfo->_sifields._sigpoll._fd = tswap32(info->_sifields._sigpoll._fd);
241 } else if (sig >= TARGET_SIGRTMIN) {
242 tinfo->_sifields._rt._pid = tswap32(info->_sifields._rt._pid);
243 tinfo->_sifields._rt._uid = tswap32(info->_sifields._rt._uid);
244 tinfo->_sifields._rt._sigval.sival_ptr =
245 tswapl(info->_sifields._rt._sigval.sival_ptr);
246 }
247 }
248
249
250 void host_to_target_siginfo(target_siginfo_t *tinfo, const siginfo_t *info)
251 {
252 host_to_target_siginfo_noswap(tinfo, info);
253 tswap_siginfo(tinfo, tinfo);
254 }
255
256 /* XXX: we support only POSIX RT signals are used. */
257 /* XXX: find a solution for 64 bit (additional malloced data is needed) */
258 void target_to_host_siginfo(siginfo_t *info, const target_siginfo_t *tinfo)
259 {
260 info->si_signo = tswap32(tinfo->si_signo);
261 info->si_errno = tswap32(tinfo->si_errno);
262 info->si_code = tswap32(tinfo->si_code);
263 info->si_pid = tswap32(tinfo->_sifields._rt._pid);
264 info->si_uid = tswap32(tinfo->_sifields._rt._uid);
265 info->si_value.sival_ptr =
266 (void *)(long)tswapl(tinfo->_sifields._rt._sigval.sival_ptr);
267 }
268
269 static int fatal_signal (int sig)
270 {
271 switch (sig) {
272 case TARGET_SIGCHLD:
273 case TARGET_SIGURG:
274 case TARGET_SIGWINCH:
275 /* Ignored by default. */
276 return 0;
277 case TARGET_SIGCONT:
278 case TARGET_SIGSTOP:
279 case TARGET_SIGTSTP:
280 case TARGET_SIGTTIN:
281 case TARGET_SIGTTOU:
282 /* Job control signals. */
283 return 0;
284 default:
285 return 1;
286 }
287 }
288
289 void signal_init(void)
290 {
291 struct sigaction act;
292 struct sigaction oact;
293 int i, j;
294 int host_sig;
295
296 /* generate signal conversion tables */
297 for(i = 1; i <= 64; i++) {
298 if (host_to_target_signal_table[i] == 0)
299 host_to_target_signal_table[i] = i;
300 }
301 for(i = 1; i <= 64; i++) {
302 j = host_to_target_signal_table[i];
303 target_to_host_signal_table[j] = i;
304 }
305
306 /* set all host signal handlers. ALL signals are blocked during
307 the handlers to serialize them. */
308 memset(sigact_table, 0, sizeof(sigact_table));
309
310 sigfillset(&act.sa_mask);
311 act.sa_flags = SA_SIGINFO;
312 act.sa_sigaction = host_signal_handler;
313 for(i = 1; i <= TARGET_NSIG; i++) {
314 host_sig = target_to_host_signal(i);
315 sigaction(host_sig, NULL, &oact);
316 if (oact.sa_sigaction == (void *)SIG_IGN) {
317 sigact_table[i - 1]._sa_handler = TARGET_SIG_IGN;
318 } else if (oact.sa_sigaction == (void *)SIG_DFL) {
319 sigact_table[i - 1]._sa_handler = TARGET_SIG_DFL;
320 }
321 /* If there's already a handler installed then something has
322 gone horribly wrong, so don't even try to handle that case. */
323 /* Install some handlers for our own use. We need at least
324 SIGSEGV and SIGBUS, to detect exceptions. We can not just
325 trap all signals because it affects syscall interrupt
326 behavior. But do trap all default-fatal signals. */
327 if (fatal_signal (i))
328 sigaction(host_sig, &act, NULL);
329 }
330 }
331
332 /* signal queue handling */
333
334 static inline struct sigqueue *alloc_sigqueue(CPUState *env)
335 {
336 TaskState *ts = env->opaque;
337 struct sigqueue *q = ts->first_free;
338 if (!q)
339 return NULL;
340 ts->first_free = q->next;
341 return q;
342 }
343
344 static inline void free_sigqueue(CPUState *env, struct sigqueue *q)
345 {
346 TaskState *ts = env->opaque;
347 q->next = ts->first_free;
348 ts->first_free = q;
349 }
350
351 /* abort execution with signal */
352 static void QEMU_NORETURN force_sig(int sig)
353 {
354 int host_sig;
355 host_sig = target_to_host_signal(sig);
356 fprintf(stderr, "qemu: uncaught target signal %d (%s) - exiting\n",
357 sig, strsignal(host_sig));
358 #if 1
359 gdb_signalled(thread_env, sig);
360 _exit(-host_sig);
361 #else
362 {
363 struct sigaction act;
364 sigemptyset(&act.sa_mask);
365 act.sa_flags = SA_SIGINFO;
366 act.sa_sigaction = SIG_DFL;
367 sigaction(SIGABRT, &act, NULL);
368 abort();
369 }
370 #endif
371 }
372
373 /* queue a signal so that it will be send to the virtual CPU as soon
374 as possible */
375 int queue_signal(CPUState *env, int sig, target_siginfo_t *info)
376 {
377 TaskState *ts = env->opaque;
378 struct emulated_sigtable *k;
379 struct sigqueue *q, **pq;
380 abi_ulong handler;
381 int queue;
382
383 #if defined(DEBUG_SIGNAL)
384 fprintf(stderr, "queue_signal: sig=%d\n",
385 sig);
386 #endif
387 k = &ts->sigtab[sig - 1];
388 queue = gdb_queuesig ();
389 handler = sigact_table[sig - 1]._sa_handler;
390 if (!queue && handler == TARGET_SIG_DFL) {
391 if (sig == TARGET_SIGTSTP || sig == TARGET_SIGTTIN || sig == TARGET_SIGTTOU) {
392 kill(getpid(),SIGSTOP);
393 return 0;
394 } else
395 /* default handler : ignore some signal. The other are fatal */
396 if (sig != TARGET_SIGCHLD &&
397 sig != TARGET_SIGURG &&
398 sig != TARGET_SIGWINCH &&
399 sig != TARGET_SIGCONT) {
400 force_sig(sig);
401 } else {
402 return 0; /* indicate ignored */
403 }
404 } else if (!queue && handler == TARGET_SIG_IGN) {
405 /* ignore signal */
406 return 0;
407 } else if (!queue && handler == TARGET_SIG_ERR) {
408 force_sig(sig);
409 } else {
410 pq = &k->first;
411 if (sig < TARGET_SIGRTMIN) {
412 /* if non real time signal, we queue exactly one signal */
413 if (!k->pending)
414 q = &k->info;
415 else
416 return 0;
417 } else {
418 if (!k->pending) {
419 /* first signal */
420 q = &k->info;
421 } else {
422 q = alloc_sigqueue(env);
423 if (!q)
424 return -EAGAIN;
425 while (*pq != NULL)
426 pq = &(*pq)->next;
427 }
428 }
429 *pq = q;
430 q->info = *info;
431 q->next = NULL;
432 k->pending = 1;
433 /* signal that a new signal is pending */
434 ts->signal_pending = 1;
435 return 1; /* indicates that the signal was queued */
436 }
437 }
438
439 static void host_signal_handler(int host_signum, siginfo_t *info,
440 void *puc)
441 {
442 int sig;
443 target_siginfo_t tinfo;
444
445 /* the CPU emulator uses some host signals to detect exceptions,
446 we forward to it some signals */
447 if ((host_signum == SIGSEGV || host_signum == SIGBUS)
448 && info->si_code > 0) {
449 if (cpu_signal_handler(host_signum, info, puc))
450 return;
451 }
452
453 /* get target signal number */
454 sig = host_to_target_signal(host_signum);
455 if (sig < 1 || sig > TARGET_NSIG)
456 return;
457 #if defined(DEBUG_SIGNAL)
458 fprintf(stderr, "qemu: got signal %d\n", sig);
459 #endif
460 host_to_target_siginfo_noswap(&tinfo, info);
461 if (queue_signal(thread_env, sig, &tinfo) == 1) {
462 /* interrupt the virtual CPU as soon as possible */
463 cpu_interrupt(thread_env, CPU_INTERRUPT_EXIT);
464 }
465 }
466
467 /* do_sigaltstack() returns target values and errnos. */
468 /* compare linux/kernel/signal.c:do_sigaltstack() */
469 abi_long do_sigaltstack(abi_ulong uss_addr, abi_ulong uoss_addr, abi_ulong sp)
470 {
471 int ret;
472 struct target_sigaltstack oss;
473
474 /* XXX: test errors */
475 if(uoss_addr)
476 {
477 __put_user(target_sigaltstack_used.ss_sp, &oss.ss_sp);
478 __put_user(target_sigaltstack_used.ss_size, &oss.ss_size);
479 __put_user(sas_ss_flags(sp), &oss.ss_flags);
480 }
481
482 if(uss_addr)
483 {
484 struct target_sigaltstack *uss;
485 struct target_sigaltstack ss;
486
487 ret = -TARGET_EFAULT;
488 if (!lock_user_struct(VERIFY_READ, uss, uss_addr, 1)
489 || __get_user(ss.ss_sp, &uss->ss_sp)
490 || __get_user(ss.ss_size, &uss->ss_size)
491 || __get_user(ss.ss_flags, &uss->ss_flags))
492 goto out;
493 unlock_user_struct(uss, uss_addr, 0);
494
495 ret = -TARGET_EPERM;
496 if (on_sig_stack(sp))
497 goto out;
498
499 ret = -TARGET_EINVAL;
500 if (ss.ss_flags != TARGET_SS_DISABLE
501 && ss.ss_flags != TARGET_SS_ONSTACK
502 && ss.ss_flags != 0)
503 goto out;
504
505 if (ss.ss_flags == TARGET_SS_DISABLE) {
506 ss.ss_size = 0;
507 ss.ss_sp = 0;
508 } else {
509 ret = -TARGET_ENOMEM;
510 if (ss.ss_size < MINSIGSTKSZ)
511 goto out;
512 }
513
514 target_sigaltstack_used.ss_sp = ss.ss_sp;
515 target_sigaltstack_used.ss_size = ss.ss_size;
516 }
517
518 if (uoss_addr) {
519 ret = -TARGET_EFAULT;
520 if (copy_to_user(uoss_addr, &oss, sizeof(oss)))
521 goto out;
522 }
523
524 ret = 0;
525 out:
526 return ret;
527 }
528
529 /* do_sigaction() return host values and errnos */
530 int do_sigaction(int sig, const struct target_sigaction *act,
531 struct target_sigaction *oact)
532 {
533 struct target_sigaction *k;
534 struct sigaction act1;
535 int host_sig;
536 int ret = 0;
537
538 if (sig < 1 || sig > TARGET_NSIG || sig == TARGET_SIGKILL || sig == TARGET_SIGSTOP)
539 return -EINVAL;
540 k = &sigact_table[sig - 1];
541 #if defined(DEBUG_SIGNAL)
542 fprintf(stderr, "sigaction sig=%d act=0x%08x, oact=0x%08x\n",
543 sig, (int)act, (int)oact);
544 #endif
545 if (oact) {
546 oact->_sa_handler = tswapl(k->_sa_handler);
547 oact->sa_flags = tswapl(k->sa_flags);
548 #if !defined(TARGET_MIPS)
549 oact->sa_restorer = tswapl(k->sa_restorer);
550 #endif
551 oact->sa_mask = k->sa_mask;
552 }
553 if (act) {
554 /* FIXME: This is not threadsafe. */
555 k->_sa_handler = tswapl(act->_sa_handler);
556 k->sa_flags = tswapl(act->sa_flags);
557 #if !defined(TARGET_MIPS)
558 k->sa_restorer = tswapl(act->sa_restorer);
559 #endif
560 k->sa_mask = act->sa_mask;
561
562 /* we update the host linux signal state */
563 host_sig = target_to_host_signal(sig);
564 if (host_sig != SIGSEGV && host_sig != SIGBUS) {
565 sigfillset(&act1.sa_mask);
566 act1.sa_flags = SA_SIGINFO;
567 if (k->sa_flags & TARGET_SA_RESTART)
568 act1.sa_flags |= SA_RESTART;
569 /* NOTE: it is important to update the host kernel signal
570 ignore state to avoid getting unexpected interrupted
571 syscalls */
572 if (k->_sa_handler == TARGET_SIG_IGN) {
573 act1.sa_sigaction = (void *)SIG_IGN;
574 } else if (k->_sa_handler == TARGET_SIG_DFL) {
575 if (fatal_signal (sig))
576 act1.sa_sigaction = host_signal_handler;
577 else
578 act1.sa_sigaction = (void *)SIG_DFL;
579 } else {
580 act1.sa_sigaction = host_signal_handler;
581 }
582 ret = sigaction(host_sig, &act1, NULL);
583 }
584 }
585 return ret;
586 }
587
588 static inline int copy_siginfo_to_user(target_siginfo_t *tinfo,
589 const target_siginfo_t *info)
590 {
591 tswap_siginfo(tinfo, info);
592 return 0;
593 }
594
595 static inline int current_exec_domain_sig(int sig)
596 {
597 return /* current->exec_domain && current->exec_domain->signal_invmap
598 && sig < 32 ? current->exec_domain->signal_invmap[sig] : */ sig;
599 }
600
601 #if defined(TARGET_I386) && TARGET_ABI_BITS == 32
602
603 /* from the Linux kernel */
604
605 struct target_fpreg {
606 uint16_t significand[4];
607 uint16_t exponent;
608 };
609
610 struct target_fpxreg {
611 uint16_t significand[4];
612 uint16_t exponent;
613 uint16_t padding[3];
614 };
615
616 struct target_xmmreg {
617 abi_ulong element[4];
618 };
619
620 struct target_fpstate {
621 /* Regular FPU environment */
622 abi_ulong cw;
623 abi_ulong sw;
624 abi_ulong tag;
625 abi_ulong ipoff;
626 abi_ulong cssel;
627 abi_ulong dataoff;
628 abi_ulong datasel;
629 struct target_fpreg _st[8];
630 uint16_t status;
631 uint16_t magic; /* 0xffff = regular FPU data only */
632
633 /* FXSR FPU environment */
634 abi_ulong _fxsr_env[6]; /* FXSR FPU env is ignored */
635 abi_ulong mxcsr;
636 abi_ulong reserved;
637 struct target_fpxreg _fxsr_st[8]; /* FXSR FPU reg data is ignored */
638 struct target_xmmreg _xmm[8];
639 abi_ulong padding[56];
640 };
641
642 #define X86_FXSR_MAGIC 0x0000
643
644 struct target_sigcontext {
645 uint16_t gs, __gsh;
646 uint16_t fs, __fsh;
647 uint16_t es, __esh;
648 uint16_t ds, __dsh;
649 abi_ulong edi;
650 abi_ulong esi;
651 abi_ulong ebp;
652 abi_ulong esp;
653 abi_ulong ebx;
654 abi_ulong edx;
655 abi_ulong ecx;
656 abi_ulong eax;
657 abi_ulong trapno;
658 abi_ulong err;
659 abi_ulong eip;
660 uint16_t cs, __csh;
661 abi_ulong eflags;
662 abi_ulong esp_at_signal;
663 uint16_t ss, __ssh;
664 abi_ulong fpstate; /* pointer */
665 abi_ulong oldmask;
666 abi_ulong cr2;
667 };
668
669 struct target_ucontext {
670 abi_ulong tuc_flags;
671 abi_ulong tuc_link;
672 target_stack_t tuc_stack;
673 struct target_sigcontext tuc_mcontext;
674 target_sigset_t tuc_sigmask; /* mask last for extensibility */
675 };
676
677 struct sigframe
678 {
679 abi_ulong pretcode;
680 int sig;
681 struct target_sigcontext sc;
682 struct target_fpstate fpstate;
683 abi_ulong extramask[TARGET_NSIG_WORDS-1];
684 char retcode[8];
685 };
686
687 struct rt_sigframe
688 {
689 abi_ulong pretcode;
690 int sig;
691 abi_ulong pinfo;
692 abi_ulong puc;
693 struct target_siginfo info;
694 struct target_ucontext uc;
695 struct target_fpstate fpstate;
696 char retcode[8];
697 };
698
699 /*
700 * Set up a signal frame.
701 */
702
703 /* XXX: save x87 state */
704 static int
705 setup_sigcontext(struct target_sigcontext *sc, struct target_fpstate *fpstate,
706 CPUX86State *env, abi_ulong mask, abi_ulong fpstate_addr)
707 {
708 int err = 0;
709 uint16_t magic;
710
711 /* already locked in setup_frame() */
712 err |= __put_user(env->segs[R_GS].selector, (unsigned int *)&sc->gs);
713 err |= __put_user(env->segs[R_FS].selector, (unsigned int *)&sc->fs);
714 err |= __put_user(env->segs[R_ES].selector, (unsigned int *)&sc->es);
715 err |= __put_user(env->segs[R_DS].selector, (unsigned int *)&sc->ds);
716 err |= __put_user(env->regs[R_EDI], &sc->edi);
717 err |= __put_user(env->regs[R_ESI], &sc->esi);
718 err |= __put_user(env->regs[R_EBP], &sc->ebp);
719 err |= __put_user(env->regs[R_ESP], &sc->esp);
720 err |= __put_user(env->regs[R_EBX], &sc->ebx);
721 err |= __put_user(env->regs[R_EDX], &sc->edx);
722 err |= __put_user(env->regs[R_ECX], &sc->ecx);
723 err |= __put_user(env->regs[R_EAX], &sc->eax);
724 err |= __put_user(env->exception_index, &sc->trapno);
725 err |= __put_user(env->error_code, &sc->err);
726 err |= __put_user(env->eip, &sc->eip);
727 err |= __put_user(env->segs[R_CS].selector, (unsigned int *)&sc->cs);
728 err |= __put_user(env->eflags, &sc->eflags);
729 err |= __put_user(env->regs[R_ESP], &sc->esp_at_signal);
730 err |= __put_user(env->segs[R_SS].selector, (unsigned int *)&sc->ss);
731
732 cpu_x86_fsave(env, fpstate_addr, 1);
733 fpstate->status = fpstate->sw;
734 magic = 0xffff;
735 err |= __put_user(magic, &fpstate->magic);
736 err |= __put_user(fpstate_addr, &sc->fpstate);
737
738 /* non-iBCS2 extensions.. */
739 err |= __put_user(mask, &sc->oldmask);
740 err |= __put_user(env->cr[2], &sc->cr2);
741 return err;
742 }
743
744 /*
745 * Determine which stack to use..
746 */
747
748 static inline abi_ulong
749 get_sigframe(struct target_sigaction *ka, CPUX86State *env, size_t frame_size)
750 {
751 unsigned long esp;
752
753 /* Default to using normal stack */
754 esp = env->regs[R_ESP];
755 /* This is the X/Open sanctioned signal stack switching. */
756 if (ka->sa_flags & TARGET_SA_ONSTACK) {
757 if (sas_ss_flags(esp) == 0)
758 esp = target_sigaltstack_used.ss_sp + target_sigaltstack_used.ss_size;
759 }
760
761 /* This is the legacy signal stack switching. */
762 else
763 if ((env->segs[R_SS].selector & 0xffff) != __USER_DS &&
764 !(ka->sa_flags & TARGET_SA_RESTORER) &&
765 ka->sa_restorer) {
766 esp = (unsigned long) ka->sa_restorer;
767 }
768 return (esp - frame_size) & -8ul;
769 }
770
771 /* compare linux/arch/i386/kernel/signal.c:setup_frame() */
772 static void setup_frame(int sig, struct target_sigaction *ka,
773 target_sigset_t *set, CPUX86State *env)
774 {
775 abi_ulong frame_addr;
776 struct sigframe *frame;
777 int i, err = 0;
778
779 frame_addr = get_sigframe(ka, env, sizeof(*frame));
780
781 if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
782 goto give_sigsegv;
783
784 err |= __put_user(current_exec_domain_sig(sig),
785 &frame->sig);
786 if (err)
787 goto give_sigsegv;
788
789 setup_sigcontext(&frame->sc, &frame->fpstate, env, set->sig[0],
790 frame_addr + offsetof(struct sigframe, fpstate));
791 if (err)
792 goto give_sigsegv;
793
794 for(i = 1; i < TARGET_NSIG_WORDS; i++) {
795 if (__put_user(set->sig[i], &frame->extramask[i - 1]))
796 goto give_sigsegv;
797 }
798
799 /* Set up to return from userspace. If provided, use a stub
800 already in userspace. */
801 if (ka->sa_flags & TARGET_SA_RESTORER) {
802 err |= __put_user(ka->sa_restorer, &frame->pretcode);
803 } else {
804 uint16_t val16;
805 abi_ulong retcode_addr;
806 retcode_addr = frame_addr + offsetof(struct sigframe, retcode);
807 err |= __put_user(retcode_addr, &frame->pretcode);
808 /* This is popl %eax ; movl $,%eax ; int $0x80 */
809 val16 = 0xb858;
810 err |= __put_user(val16, (uint16_t *)(frame->retcode+0));
811 err |= __put_user(TARGET_NR_sigreturn, (int *)(frame->retcode+2));
812 val16 = 0x80cd;
813 err |= __put_user(val16, (uint16_t *)(frame->retcode+6));
814 }
815
816 if (err)
817 goto give_sigsegv;
818
819 /* Set up registers for signal handler */
820 env->regs[R_ESP] = frame_addr;
821 env->eip = ka->_sa_handler;
822
823 cpu_x86_load_seg(env, R_DS, __USER_DS);
824 cpu_x86_load_seg(env, R_ES, __USER_DS);
825 cpu_x86_load_seg(env, R_SS, __USER_DS);
826 cpu_x86_load_seg(env, R_CS, __USER_CS);
827 env->eflags &= ~TF_MASK;
828
829 unlock_user_struct(frame, frame_addr, 1);
830
831 return;
832
833 give_sigsegv:
834 unlock_user_struct(frame, frame_addr, 1);
835 if (sig == TARGET_SIGSEGV)
836 ka->_sa_handler = TARGET_SIG_DFL;
837 force_sig(TARGET_SIGSEGV /* , current */);
838 }
839
840 /* compare linux/arch/i386/kernel/signal.c:setup_rt_frame() */
841 static void setup_rt_frame(int sig, struct target_sigaction *ka,
842 target_siginfo_t *info,
843 target_sigset_t *set, CPUX86State *env)
844 {
845 abi_ulong frame_addr, addr;
846 struct rt_sigframe *frame;
847 int i, err = 0;
848
849 frame_addr = get_sigframe(ka, env, sizeof(*frame));
850
851 if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
852 goto give_sigsegv;
853
854 err |= __put_user(current_exec_domain_sig(sig),
855 &frame->sig);
856 addr = frame_addr + offsetof(struct rt_sigframe, info);
857 err |= __put_user(addr, &frame->pinfo);
858 addr = frame_addr + offsetof(struct rt_sigframe, uc);
859 err |= __put_user(addr, &frame->puc);
860 err |= copy_siginfo_to_user(&frame->info, info);
861 if (err)
862 goto give_sigsegv;
863
864 /* Create the ucontext. */
865 err |= __put_user(0, &frame->uc.tuc_flags);
866 err |= __put_user(0, &frame->uc.tuc_link);
867 err |= __put_user(target_sigaltstack_used.ss_sp,
868 &frame->uc.tuc_stack.ss_sp);
869 err |= __put_user(sas_ss_flags(get_sp_from_cpustate(env)),
870 &frame->uc.tuc_stack.ss_flags);
871 err |= __put_user(target_sigaltstack_used.ss_size,
872 &frame->uc.tuc_stack.ss_size);
873 err |= setup_sigcontext(&frame->uc.tuc_mcontext, &frame->fpstate,
874 env, set->sig[0],
875 frame_addr + offsetof(struct rt_sigframe, fpstate));
876 for(i = 0; i < TARGET_NSIG_WORDS; i++) {
877 if (__put_user(set->sig[i], &frame->uc.tuc_sigmask.sig[i]))
878 goto give_sigsegv;
879 }
880
881 /* Set up to return from userspace. If provided, use a stub
882 already in userspace. */
883 if (ka->sa_flags & TARGET_SA_RESTORER) {
884 err |= __put_user(ka->sa_restorer, &frame->pretcode);
885 } else {
886 uint16_t val16;
887 addr = frame_addr + offsetof(struct rt_sigframe, retcode);
888 err |= __put_user(addr, &frame->pretcode);
889 /* This is movl $,%eax ; int $0x80 */
890 err |= __put_user(0xb8, (char *)(frame->retcode+0));
891 err |= __put_user(TARGET_NR_rt_sigreturn, (int *)(frame->retcode+1));
892 val16 = 0x80cd;
893 err |= __put_user(val16, (uint16_t *)(frame->retcode+5));
894 }
895
896 if (err)
897 goto give_sigsegv;
898
899 /* Set up registers for signal handler */
900 env->regs[R_ESP] = frame_addr;
901 env->eip = ka->_sa_handler;
902
903 cpu_x86_load_seg(env, R_DS, __USER_DS);
904 cpu_x86_load_seg(env, R_ES, __USER_DS);
905 cpu_x86_load_seg(env, R_SS, __USER_DS);
906 cpu_x86_load_seg(env, R_CS, __USER_CS);
907 env->eflags &= ~TF_MASK;
908
909 unlock_user_struct(frame, frame_addr, 1);
910
911 return;
912
913 give_sigsegv:
914 unlock_user_struct(frame, frame_addr, 1);
915 if (sig == TARGET_SIGSEGV)
916 ka->_sa_handler = TARGET_SIG_DFL;
917 force_sig(TARGET_SIGSEGV /* , current */);
918 }
919
920 static int
921 restore_sigcontext(CPUX86State *env, struct target_sigcontext *sc, int *peax)
922 {
923 unsigned int err = 0;
924 abi_ulong fpstate_addr;
925 unsigned int tmpflags;
926
927 cpu_x86_load_seg(env, R_GS, tswap16(sc->gs));
928 cpu_x86_load_seg(env, R_FS, tswap16(sc->fs));
929 cpu_x86_load_seg(env, R_ES, tswap16(sc->es));
930 cpu_x86_load_seg(env, R_DS, tswap16(sc->ds));
931
932 env->regs[R_EDI] = tswapl(sc->edi);
933 env->regs[R_ESI] = tswapl(sc->esi);
934 env->regs[R_EBP] = tswapl(sc->ebp);
935 env->regs[R_ESP] = tswapl(sc->esp);
936 env->regs[R_EBX] = tswapl(sc->ebx);
937 env->regs[R_EDX] = tswapl(sc->edx);
938 env->regs[R_ECX] = tswapl(sc->ecx);
939 env->eip = tswapl(sc->eip);
940
941 cpu_x86_load_seg(env, R_CS, lduw(&sc->cs) | 3);
942 cpu_x86_load_seg(env, R_SS, lduw(&sc->ss) | 3);
943
944 tmpflags = tswapl(sc->eflags);
945 env->eflags = (env->eflags & ~0x40DD5) | (tmpflags & 0x40DD5);
946 // regs->orig_eax = -1; /* disable syscall checks */
947
948 fpstate_addr = tswapl(sc->fpstate);
949 if (fpstate_addr != 0) {
950 if (!access_ok(VERIFY_READ, fpstate_addr,
951 sizeof(struct target_fpstate)))
952 goto badframe;
953 cpu_x86_frstor(env, fpstate_addr, 1);
954 }
955
956 *peax = tswapl(sc->eax);
957 return err;
958 badframe:
959 return 1;
960 }
961
962 long do_sigreturn(CPUX86State *env)
963 {
964 struct sigframe *frame;
965 abi_ulong frame_addr = env->regs[R_ESP] - 8;
966 target_sigset_t target_set;
967 sigset_t set;
968 int eax, i;
969
970 #if defined(DEBUG_SIGNAL)
971 fprintf(stderr, "do_sigreturn\n");
972 #endif
973 if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1))
974 goto badframe;
975 /* set blocked signals */
976 if (__get_user(target_set.sig[0], &frame->sc.oldmask))
977 goto badframe;
978 for(i = 1; i < TARGET_NSIG_WORDS; i++) {
979 if (__get_user(target_set.sig[i], &frame->extramask[i - 1]))
980 goto badframe;
981 }
982
983 target_to_host_sigset_internal(&set, &target_set);
984 sigprocmask(SIG_SETMASK, &set, NULL);
985
986 /* restore registers */
987 if (restore_sigcontext(env, &frame->sc, &eax))
988 goto badframe;
989 unlock_user_struct(frame, frame_addr, 0);
990 return eax;
991
992 badframe:
993 unlock_user_struct(frame, frame_addr, 0);
994 force_sig(TARGET_SIGSEGV);
995 return 0;
996 }
997
998 long do_rt_sigreturn(CPUX86State *env)
999 {
1000 abi_ulong frame_addr;
1001 struct rt_sigframe *frame;
1002 sigset_t set;
1003 int eax;
1004
1005 frame_addr = env->regs[R_ESP] - 4;
1006 if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1))
1007 goto badframe;
1008 target_to_host_sigset(&set, &frame->uc.tuc_sigmask);
1009 sigprocmask(SIG_SETMASK, &set, NULL);
1010
1011 if (restore_sigcontext(env, &frame->uc.tuc_mcontext, &eax))
1012 goto badframe;
1013
1014 if (do_sigaltstack(frame_addr + offsetof(struct rt_sigframe, uc.tuc_stack), 0,
1015 get_sp_from_cpustate(env)) == -EFAULT)
1016 goto badframe;
1017
1018 unlock_user_struct(frame, frame_addr, 0);
1019 return eax;
1020
1021 badframe:
1022 unlock_user_struct(frame, frame_addr, 0);
1023 force_sig(TARGET_SIGSEGV);
1024 return 0;
1025 }
1026
1027 #elif defined(TARGET_ARM)
1028
1029 struct target_sigcontext {
1030 abi_ulong trap_no;
1031 abi_ulong error_code;
1032 abi_ulong oldmask;
1033 abi_ulong arm_r0;
1034 abi_ulong arm_r1;
1035 abi_ulong arm_r2;
1036 abi_ulong arm_r3;
1037 abi_ulong arm_r4;
1038 abi_ulong arm_r5;
1039 abi_ulong arm_r6;
1040 abi_ulong arm_r7;
1041 abi_ulong arm_r8;
1042 abi_ulong arm_r9;
1043 abi_ulong arm_r10;
1044 abi_ulong arm_fp;
1045 abi_ulong arm_ip;
1046 abi_ulong arm_sp;
1047 abi_ulong arm_lr;
1048 abi_ulong arm_pc;
1049 abi_ulong arm_cpsr;
1050 abi_ulong fault_address;
1051 };
1052
1053 struct target_ucontext_v1 {
1054 abi_ulong tuc_flags;
1055 abi_ulong tuc_link;
1056 target_stack_t tuc_stack;
1057 struct target_sigcontext tuc_mcontext;
1058 target_sigset_t tuc_sigmask; /* mask last for extensibility */
1059 };
1060
1061 struct target_ucontext_v2 {
1062 abi_ulong tuc_flags;
1063 abi_ulong tuc_link;
1064 target_stack_t tuc_stack;
1065 struct target_sigcontext tuc_mcontext;
1066 target_sigset_t tuc_sigmask; /* mask last for extensibility */
1067 char __unused[128 - sizeof(sigset_t)];
1068 abi_ulong tuc_regspace[128] __attribute__((__aligned__(8)));
1069 };
1070
1071 struct sigframe_v1
1072 {
1073 struct target_sigcontext sc;
1074 abi_ulong extramask[TARGET_NSIG_WORDS-1];
1075 abi_ulong retcode;
1076 };
1077
1078 struct sigframe_v2
1079 {
1080 struct target_ucontext_v2 uc;
1081 abi_ulong retcode;
1082 };
1083
1084 struct rt_sigframe_v1
1085 {
1086 abi_ulong pinfo;
1087 abi_ulong puc;
1088 struct target_siginfo info;
1089 struct target_ucontext_v1 uc;
1090 abi_ulong retcode;
1091 };
1092
1093 struct rt_sigframe_v2
1094 {
1095 struct target_siginfo info;
1096 struct target_ucontext_v2 uc;
1097 abi_ulong retcode;
1098 };
1099
1100 #define TARGET_CONFIG_CPU_32 1
1101
1102 /*
1103 * For ARM syscalls, we encode the syscall number into the instruction.
1104 */
1105 #define SWI_SYS_SIGRETURN (0xef000000|(TARGET_NR_sigreturn + ARM_SYSCALL_BASE))
1106 #define SWI_SYS_RT_SIGRETURN (0xef000000|(TARGET_NR_rt_sigreturn + ARM_SYSCALL_BASE))
1107
1108 /*
1109 * For Thumb syscalls, we pass the syscall number via r7. We therefore
1110 * need two 16-bit instructions.
1111 */
1112 #define SWI_THUMB_SIGRETURN (0xdf00 << 16 | 0x2700 | (TARGET_NR_sigreturn))
1113 #define SWI_THUMB_RT_SIGRETURN (0xdf00 << 16 | 0x2700 | (TARGET_NR_rt_sigreturn))
1114
1115 static const abi_ulong retcodes[4] = {
1116 SWI_SYS_SIGRETURN, SWI_THUMB_SIGRETURN,
1117 SWI_SYS_RT_SIGRETURN, SWI_THUMB_RT_SIGRETURN
1118 };
1119
1120
1121 #define __get_user_error(x,p,e) __get_user(x, p)
1122
1123 static inline int valid_user_regs(CPUState *regs)
1124 {
1125 return 1;
1126 }
1127
1128 static void
1129 setup_sigcontext(struct target_sigcontext *sc, /*struct _fpstate *fpstate,*/
1130 CPUState *env, abi_ulong mask)
1131 {
1132 __put_user(env->regs[0], &sc->arm_r0);
1133 __put_user(env->regs[1], &sc->arm_r1);
1134 __put_user(env->regs[2], &sc->arm_r2);
1135 __put_user(env->regs[3], &sc->arm_r3);
1136 __put_user(env->regs[4], &sc->arm_r4);
1137 __put_user(env->regs[5], &sc->arm_r5);
1138 __put_user(env->regs[6], &sc->arm_r6);
1139 __put_user(env->regs[7], &sc->arm_r7);
1140 __put_user(env->regs[8], &sc->arm_r8);
1141 __put_user(env->regs[9], &sc->arm_r9);
1142 __put_user(env->regs[10], &sc->arm_r10);
1143 __put_user(env->regs[11], &sc->arm_fp);
1144 __put_user(env->regs[12], &sc->arm_ip);
1145 __put_user(env->regs[13], &sc->arm_sp);
1146 __put_user(env->regs[14], &sc->arm_lr);
1147 __put_user(env->regs[15], &sc->arm_pc);
1148 #ifdef TARGET_CONFIG_CPU_32
1149 __put_user(cpsr_read(env), &sc->arm_cpsr);
1150 #endif
1151
1152 __put_user(/* current->thread.trap_no */ 0, &sc->trap_no);
1153 __put_user(/* current->thread.error_code */ 0, &sc->error_code);
1154 __put_user(/* current->thread.address */ 0, &sc->fault_address);
1155 __put_user(mask, &sc->oldmask);
1156 }
1157
1158 static inline abi_ulong
1159 get_sigframe(struct target_sigaction *ka, CPUState *regs, int framesize)
1160 {
1161 unsigned long sp = regs->regs[13];
1162
1163 /*
1164 * This is the X/Open sanctioned signal stack switching.
1165 */
1166 if ((ka->sa_flags & TARGET_SA_ONSTACK) && !sas_ss_flags(sp))
1167 sp = target_sigaltstack_used.ss_sp + target_sigaltstack_used.ss_size;
1168 /*
1169 * ATPCS B01 mandates 8-byte alignment
1170 */
1171 return (sp - framesize) & ~7;
1172 }
1173
1174 static int
1175 setup_return(CPUState *env, struct target_sigaction *ka,
1176 abi_ulong *rc, abi_ulong frame_addr, int usig, abi_ulong rc_addr)
1177 {
1178 abi_ulong handler = ka->_sa_handler;
1179 abi_ulong retcode;
1180 int thumb = handler & 1;
1181
1182 if (ka->sa_flags & TARGET_SA_RESTORER) {
1183 retcode = ka->sa_restorer;
1184 } else {
1185 unsigned int idx = thumb;
1186
1187 if (ka->sa_flags & TARGET_SA_SIGINFO)
1188 idx += 2;
1189
1190 if (__put_user(retcodes[idx], rc))
1191 return 1;
1192 #if 0
1193 flush_icache_range((abi_ulong)rc,
1194 (abi_ulong)(rc + 1));
1195 #endif
1196 retcode = rc_addr + thumb;
1197 }
1198
1199 env->regs[0] = usig;
1200 env->regs[13] = frame_addr;
1201 env->regs[14] = retcode;
1202 env->regs[15] = handler & (thumb ? ~1 : ~3);
1203 env->thumb = thumb;
1204
1205 #if 0
1206 #ifdef TARGET_CONFIG_CPU_32
1207 env->cpsr = cpsr;
1208 #endif
1209 #endif
1210
1211 return 0;
1212 }
1213
1214 static void setup_sigframe_v2(struct target_ucontext_v2 *uc,
1215 target_sigset_t *set, CPUState *env)
1216 {
1217 struct target_sigaltstack stack;
1218 int i;
1219
1220 /* Clear all the bits of the ucontext we don't use. */
1221 memset(uc, 0, offsetof(struct target_ucontext_v2, tuc_mcontext));
1222
1223 memset(&stack, 0, sizeof(stack));
1224 __put_user(target_sigaltstack_used.ss_sp, &stack.ss_sp);
1225 __put_user(target_sigaltstack_used.ss_size, &stack.ss_size);
1226 __put_user(sas_ss_flags(get_sp_from_cpustate(env)), &stack.ss_flags);
1227 memcpy(&uc->tuc_stack, &stack, sizeof(stack));
1228
1229 setup_sigcontext(&uc->tuc_mcontext, env, set->sig[0]);
1230 /* FIXME: Save coprocessor signal frame. */
1231 for(i = 0; i < TARGET_NSIG_WORDS; i++) {
1232 __put_user(set->sig[i], &uc->tuc_sigmask.sig[i]);
1233 }
1234 }
1235
1236 /* compare linux/arch/arm/kernel/signal.c:setup_frame() */
1237 static void setup_frame_v1(int usig, struct target_sigaction *ka,
1238 target_sigset_t *set, CPUState *regs)
1239 {
1240 struct sigframe_v1 *frame;
1241 abi_ulong frame_addr = get_sigframe(ka, regs, sizeof(*frame));
1242 int i;
1243
1244 if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
1245 return;
1246
1247 setup_sigcontext(&frame->sc, regs, set->sig[0]);
1248
1249 for(i = 1; i < TARGET_NSIG_WORDS; i++) {
1250 if (__put_user(set->sig[i], &frame->extramask[i - 1]))
1251 goto end;
1252 }
1253
1254 setup_return(regs, ka, &frame->retcode, frame_addr, usig,
1255 frame_addr + offsetof(struct sigframe_v1, retcode));
1256
1257 end:
1258 unlock_user_struct(frame, frame_addr, 1);
1259 }
1260
1261 static void setup_frame_v2(int usig, struct target_sigaction *ka,
1262 target_sigset_t *set, CPUState *regs)
1263 {
1264 struct sigframe_v2 *frame;
1265 abi_ulong frame_addr = get_sigframe(ka, regs, sizeof(*frame));
1266
1267 if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
1268 return;
1269
1270 setup_sigframe_v2(&frame->uc, set, regs);
1271
1272 setup_return(regs, ka, &frame->retcode, frame_addr, usig,
1273 frame_addr + offsetof(struct sigframe_v2, retcode));
1274
1275 unlock_user_struct(frame, frame_addr, 1);
1276 }
1277
1278 static void setup_frame(int usig, struct target_sigaction *ka,
1279 target_sigset_t *set, CPUState *regs)
1280 {
1281 if (get_osversion() >= 0x020612) {
1282 setup_frame_v2(usig, ka, set, regs);
1283 } else {
1284 setup_frame_v1(usig, ka, set, regs);
1285 }
1286 }
1287
1288 /* compare linux/arch/arm/kernel/signal.c:setup_rt_frame() */
1289 static void setup_rt_frame_v1(int usig, struct target_sigaction *ka,
1290 target_siginfo_t *info,
1291 target_sigset_t *set, CPUState *env)
1292 {
1293 struct rt_sigframe_v1 *frame;
1294 abi_ulong frame_addr = get_sigframe(ka, env, sizeof(*frame));
1295 struct target_sigaltstack stack;
1296 int i;
1297 abi_ulong info_addr, uc_addr;
1298
1299 if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
1300 return /* 1 */;
1301
1302 info_addr = frame_addr + offsetof(struct rt_sigframe_v1, info);
1303 __put_user(info_addr, &frame->pinfo);
1304 uc_addr = frame_addr + offsetof(struct rt_sigframe_v1, uc);
1305 __put_user(uc_addr, &frame->puc);
1306 copy_siginfo_to_user(&frame->info, info);
1307
1308 /* Clear all the bits of the ucontext we don't use. */
1309 memset(&frame->uc, 0, offsetof(struct target_ucontext_v1, tuc_mcontext));
1310
1311 memset(&stack, 0, sizeof(stack));
1312 __put_user(target_sigaltstack_used.ss_sp, &stack.ss_sp);
1313 __put_user(target_sigaltstack_used.ss_size, &stack.ss_size);
1314 __put_user(sas_ss_flags(get_sp_from_cpustate(env)), &stack.ss_flags);
1315 memcpy(&frame->uc.tuc_stack, &stack, sizeof(stack));
1316
1317 setup_sigcontext(&frame->uc.tuc_mcontext, env, set->sig[0]);
1318 for(i = 0; i < TARGET_NSIG_WORDS; i++) {
1319 if (__put_user(set->sig[i], &frame->uc.tuc_sigmask.sig[i]))
1320 goto end;
1321 }
1322
1323 setup_return(env, ka, &frame->retcode, frame_addr, usig,
1324 frame_addr + offsetof(struct rt_sigframe_v1, retcode));
1325
1326 env->regs[1] = info_addr;
1327 env->regs[2] = uc_addr;
1328
1329 end:
1330 unlock_user_struct(frame, frame_addr, 1);
1331 }
1332
1333 static void setup_rt_frame_v2(int usig, struct target_sigaction *ka,
1334 target_siginfo_t *info,
1335 target_sigset_t *set, CPUState *env)
1336 {
1337 struct rt_sigframe_v2 *frame;
1338 abi_ulong frame_addr = get_sigframe(ka, env, sizeof(*frame));
1339 abi_ulong info_addr, uc_addr;
1340
1341 if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
1342 return /* 1 */;
1343
1344 info_addr = frame_addr + offsetof(struct rt_sigframe_v2, info);
1345 uc_addr = frame_addr + offsetof(struct rt_sigframe_v2, uc);
1346 copy_siginfo_to_user(&frame->info, info);
1347
1348 setup_sigframe_v2(&frame->uc, set, env);
1349
1350 setup_return(env, ka, &frame->retcode, frame_addr, usig,
1351 frame_addr + offsetof(struct rt_sigframe_v2, retcode));
1352
1353 env->regs[1] = info_addr;
1354 env->regs[2] = uc_addr;
1355
1356 unlock_user_struct(frame, frame_addr, 1);
1357 }
1358
1359 static void setup_rt_frame(int usig, struct target_sigaction *ka,
1360 target_siginfo_t *info,
1361 target_sigset_t *set, CPUState *env)
1362 {
1363 if (get_osversion() >= 0x020612) {
1364 setup_rt_frame_v2(usig, ka, info, set, env);
1365 } else {
1366 setup_rt_frame_v1(usig, ka, info, set, env);
1367 }
1368 }
1369
1370 static int
1371 restore_sigcontext(CPUState *env, struct target_sigcontext *sc)
1372 {
1373 int err = 0;
1374 uint32_t cpsr;
1375
1376 __get_user_error(env->regs[0], &sc->arm_r0, err);
1377 __get_user_error(env->regs[1], &sc->arm_r1, err);
1378 __get_user_error(env->regs[2], &sc->arm_r2, err);
1379 __get_user_error(env->regs[3], &sc->arm_r3, err);
1380 __get_user_error(env->regs[4], &sc->arm_r4, err);
1381 __get_user_error(env->regs[5], &sc->arm_r5, err);
1382 __get_user_error(env->regs[6], &sc->arm_r6, err);
1383 __get_user_error(env->regs[7], &sc->arm_r7, err);
1384 __get_user_error(env->regs[8], &sc->arm_r8, err);
1385 __get_user_error(env->regs[9], &sc->arm_r9, err);
1386 __get_user_error(env->regs[10], &sc->arm_r10, err);
1387 __get_user_error(env->regs[11], &sc->arm_fp, err);
1388 __get_user_error(env->regs[12], &sc->arm_ip, err);
1389 __get_user_error(env->regs[13], &sc->arm_sp, err);
1390 __get_user_error(env->regs[14], &sc->arm_lr, err);
1391 __get_user_error(env->regs[15], &sc->arm_pc, err);
1392 #ifdef TARGET_CONFIG_CPU_32
1393 __get_user_error(cpsr, &sc->arm_cpsr, err);
1394 cpsr_write(env, cpsr, CPSR_USER | CPSR_EXEC);
1395 #endif
1396
1397 err |= !valid_user_regs(env);
1398
1399 return err;
1400 }
1401
1402 static long do_sigreturn_v1(CPUState *env)
1403 {
1404 abi_ulong frame_addr;
1405 struct sigframe_v1 *frame;
1406 target_sigset_t set;
1407 sigset_t host_set;
1408 int i;
1409
1410 /*
1411 * Since we stacked the signal on a 64-bit boundary,
1412 * then 'sp' should be word aligned here. If it's
1413 * not, then the user is trying to mess with us.
1414 */
1415 if (env->regs[13] & 7)
1416 goto badframe;
1417
1418 frame_addr = env->regs[13];
1419 if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1))
1420 goto badframe;
1421
1422 if (__get_user(set.sig[0], &frame->sc.oldmask))
1423 goto badframe;
1424 for(i = 1; i < TARGET_NSIG_WORDS; i++) {
1425 if (__get_user(set.sig[i], &frame->extramask[i - 1]))
1426 goto badframe;
1427 }
1428
1429 target_to_host_sigset_internal(&host_set, &set);
1430 sigprocmask(SIG_SETMASK, &host_set, NULL);
1431
1432 if (restore_sigcontext(env, &frame->sc))
1433 goto badframe;
1434
1435 #if 0
1436 /* Send SIGTRAP if we're single-stepping */
1437 if (ptrace_cancel_bpt(current))
1438 send_sig(SIGTRAP, current, 1);
1439 #endif
1440 unlock_user_struct(frame, frame_addr, 0);
1441 return env->regs[0];
1442
1443 badframe:
1444 unlock_user_struct(frame, frame_addr, 0);
1445 force_sig(SIGSEGV /* , current */);
1446 return 0;
1447 }
1448
1449 static int do_sigframe_return_v2(CPUState *env, target_ulong frame_addr,
1450 struct target_ucontext_v2 *uc)
1451 {
1452 sigset_t host_set;
1453
1454 target_to_host_sigset(&host_set, &uc->tuc_sigmask);
1455 sigprocmask(SIG_SETMASK, &host_set, NULL);
1456
1457 if (restore_sigcontext(env, &uc->tuc_mcontext))
1458 return 1;
1459
1460 if (do_sigaltstack(frame_addr + offsetof(struct target_ucontext_v2, tuc_stack), 0, get_sp_from_cpustate(env)) == -EFAULT)
1461 return 1;
1462
1463 #if 0
1464 /* Send SIGTRAP if we're single-stepping */
1465 if (ptrace_cancel_bpt(current))
1466 send_sig(SIGTRAP, current, 1);
1467 #endif
1468
1469 return 0;
1470 }
1471
1472 static long do_sigreturn_v2(CPUState *env)
1473 {
1474 abi_ulong frame_addr;
1475 struct sigframe_v2 *frame;
1476
1477 /*
1478 * Since we stacked the signal on a 64-bit boundary,
1479 * then 'sp' should be word aligned here. If it's
1480 * not, then the user is trying to mess with us.
1481 */
1482 if (env->regs[13] & 7)
1483 goto badframe;
1484
1485 frame_addr = env->regs[13];
1486 if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1))
1487 goto badframe;
1488
1489 if (do_sigframe_return_v2(env, frame_addr, &frame->uc))
1490 goto badframe;
1491
1492 unlock_user_struct(frame, frame_addr, 0);
1493 return env->regs[0];
1494
1495 badframe:
1496 unlock_user_struct(frame, frame_addr, 0);
1497 force_sig(SIGSEGV /* , current */);
1498 return 0;
1499 }
1500
1501 long do_sigreturn(CPUState *env)
1502 {
1503 if (get_osversion() >= 0x020612) {
1504 return do_sigreturn_v2(env);
1505 } else {
1506 return do_sigreturn_v1(env);
1507 }
1508 }
1509
1510 static long do_rt_sigreturn_v1(CPUState *env)
1511 {
1512 abi_ulong frame_addr;
1513 struct rt_sigframe_v1 *frame;
1514 sigset_t host_set;
1515
1516 /*
1517 * Since we stacked the signal on a 64-bit boundary,
1518 * then 'sp' should be word aligned here. If it's
1519 * not, then the user is trying to mess with us.
1520 */
1521 if (env->regs[13] & 7)
1522 goto badframe;
1523
1524 frame_addr = env->regs[13];
1525 if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1))
1526 goto badframe;
1527
1528 target_to_host_sigset(&host_set, &frame->uc.tuc_sigmask);
1529 sigprocmask(SIG_SETMASK, &host_set, NULL);
1530
1531 if (restore_sigcontext(env, &frame->uc.tuc_mcontext))
1532 goto badframe;
1533
1534 if (do_sigaltstack(frame_addr + offsetof(struct rt_sigframe_v1, uc.tuc_stack), 0, get_sp_from_cpustate(env)) == -EFAULT)
1535 goto badframe;
1536
1537 #if 0
1538 /* Send SIGTRAP if we're single-stepping */
1539 if (ptrace_cancel_bpt(current))
1540 send_sig(SIGTRAP, current, 1);
1541 #endif
1542 unlock_user_struct(frame, frame_addr, 0);
1543 return env->regs[0];
1544
1545 badframe:
1546 unlock_user_struct(frame, frame_addr, 0);
1547 force_sig(SIGSEGV /* , current */);
1548 return 0;
1549 }
1550
1551 static long do_rt_sigreturn_v2(CPUState *env)
1552 {
1553 abi_ulong frame_addr;
1554 struct rt_sigframe_v2 *frame;
1555
1556 /*
1557 * Since we stacked the signal on a 64-bit boundary,
1558 * then 'sp' should be word aligned here. If it's
1559 * not, then the user is trying to mess with us.
1560 */
1561 if (env->regs[13] & 7)
1562 goto badframe;
1563
1564 frame_addr = env->regs[13];
1565 if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1))
1566 goto badframe;
1567
1568 if (do_sigframe_return_v2(env, frame_addr, &frame->uc))
1569 goto badframe;
1570
1571 unlock_user_struct(frame, frame_addr, 0);
1572 return env->regs[0];
1573
1574 badframe:
1575 unlock_user_struct(frame, frame_addr, 0);
1576 force_sig(SIGSEGV /* , current */);
1577 return 0;
1578 }
1579
1580 long do_rt_sigreturn(CPUState *env)
1581 {
1582 if (get_osversion() >= 0x020612) {
1583 return do_rt_sigreturn_v2(env);
1584 } else {
1585 return do_rt_sigreturn_v1(env);
1586 }
1587 }
1588
1589 #elif defined(TARGET_SPARC)
1590
1591 #define __SUNOS_MAXWIN 31
1592
1593 /* This is what SunOS does, so shall I. */
1594 struct target_sigcontext {
1595 abi_ulong sigc_onstack; /* state to restore */
1596
1597 abi_ulong sigc_mask; /* sigmask to restore */
1598 abi_ulong sigc_sp; /* stack pointer */
1599 abi_ulong sigc_pc; /* program counter */
1600 abi_ulong sigc_npc; /* next program counter */
1601 abi_ulong sigc_psr; /* for condition codes etc */
1602 abi_ulong sigc_g1; /* User uses these two registers */
1603 abi_ulong sigc_o0; /* within the trampoline code. */
1604
1605 /* Now comes information regarding the users window set
1606 * at the time of the signal.
1607 */
1608 abi_ulong sigc_oswins; /* outstanding windows */
1609
1610 /* stack ptrs for each regwin buf */
1611 char *sigc_spbuf[__SUNOS_MAXWIN];
1612
1613 /* Windows to restore after signal */
1614 struct {
1615 abi_ulong locals[8];
1616 abi_ulong ins[8];
1617 } sigc_wbuf[__SUNOS_MAXWIN];
1618 };
1619 /* A Sparc stack frame */
1620 struct sparc_stackf {
1621 abi_ulong locals[8];
1622 abi_ulong ins[6];
1623 struct sparc_stackf *fp;
1624 abi_ulong callers_pc;
1625 char *structptr;
1626 abi_ulong xargs[6];
1627 abi_ulong xxargs[1];
1628 };
1629
1630 typedef struct {
1631 struct {
1632 abi_ulong psr;
1633 abi_ulong pc;
1634 abi_ulong npc;
1635 abi_ulong y;
1636 abi_ulong u_regs[16]; /* globals and ins */
1637 } si_regs;
1638 int si_mask;
1639 } __siginfo_t;
1640
1641 typedef struct {
1642 unsigned long si_float_regs [32];
1643 unsigned long si_fsr;
1644 unsigned long si_fpqdepth;
1645 struct {
1646 unsigned long *insn_addr;
1647 unsigned long insn;
1648 } si_fpqueue [16];
1649 } qemu_siginfo_fpu_t;
1650
1651
1652 struct target_signal_frame {
1653 struct sparc_stackf ss;
1654 __siginfo_t info;
1655 abi_ulong fpu_save;
1656 abi_ulong insns[2] __attribute__ ((aligned (8)));
1657 abi_ulong extramask[TARGET_NSIG_WORDS - 1];
1658 abi_ulong extra_size; /* Should be 0 */
1659 qemu_siginfo_fpu_t fpu_state;
1660 };
1661 struct target_rt_signal_frame {
1662 struct sparc_stackf ss;
1663 siginfo_t info;
1664 abi_ulong regs[20];
1665 sigset_t mask;
1666 abi_ulong fpu_save;
1667 unsigned int insns[2];
1668 stack_t stack;
1669 unsigned int extra_size; /* Should be 0 */
1670 qemu_siginfo_fpu_t fpu_state;
1671 };
1672
1673 #define UREG_O0 16
1674 #define UREG_O6 22
1675 #define UREG_I0 0
1676 #define UREG_I1 1
1677 #define UREG_I2 2
1678 #define UREG_I3 3
1679 #define UREG_I4 4
1680 #define UREG_I5 5
1681 #define UREG_I6 6
1682 #define UREG_I7 7
1683 #define UREG_L0 8
1684 #define UREG_FP UREG_I6
1685 #define UREG_SP UREG_O6
1686
1687 static inline abi_ulong get_sigframe(struct target_sigaction *sa,
1688 CPUState *env, unsigned long framesize)
1689 {
1690 abi_ulong sp;
1691
1692 sp = env->regwptr[UREG_FP];
1693
1694 /* This is the X/Open sanctioned signal stack switching. */
1695 if (sa->sa_flags & TARGET_SA_ONSTACK) {
1696 if (!on_sig_stack(sp)
1697 && !((target_sigaltstack_used.ss_sp + target_sigaltstack_used.ss_size) & 7))
1698 sp = target_sigaltstack_used.ss_sp + target_sigaltstack_used.ss_size;
1699 }
1700 return sp - framesize;
1701 }
1702
1703 static int
1704 setup___siginfo(__siginfo_t *si, CPUState *env, abi_ulong mask)
1705 {
1706 int err = 0, i;
1707
1708 err |= __put_user(env->psr, &si->si_regs.psr);
1709 err |= __put_user(env->pc, &si->si_regs.pc);
1710 err |= __put_user(env->npc, &si->si_regs.npc);
1711 err |= __put_user(env->y, &si->si_regs.y);
1712 for (i=0; i < 8; i++) {
1713 err |= __put_user(env->gregs[i], &si->si_regs.u_regs[i]);
1714 }
1715 for (i=0; i < 8; i++) {
1716 err |= __put_user(env->regwptr[UREG_I0 + i], &si->si_regs.u_regs[i+8]);
1717 }
1718 err |= __put_user(mask, &si->si_mask);
1719 return err;
1720 }
1721
1722 #if 0
1723 static int
1724 setup_sigcontext(struct target_sigcontext *sc, /*struct _fpstate *fpstate,*/
1725 CPUState *env, unsigned long mask)
1726 {
1727 int err = 0;
1728
1729 err |= __put_user(mask, &sc->sigc_mask);
1730 err |= __put_user(env->regwptr[UREG_SP], &sc->sigc_sp);
1731 err |= __put_user(env->pc, &sc->sigc_pc);
1732 err |= __put_user(env->npc, &sc->sigc_npc);
1733 err |= __put_user(env->psr, &sc->sigc_psr);
1734 err |= __put_user(env->gregs[1], &sc->sigc_g1);
1735 err |= __put_user(env->regwptr[UREG_O0], &sc->sigc_o0);
1736
1737 return err;
1738 }
1739 #endif
1740 #define NF_ALIGNEDSZ (((sizeof(struct target_signal_frame) + 7) & (~7)))
1741
1742 static void setup_frame(int sig, struct target_sigaction *ka,
1743 target_sigset_t *set, CPUState *env)
1744 {
1745 abi_ulong sf_addr;
1746 struct target_signal_frame *sf;
1747 int sigframe_size, err, i;
1748
1749 /* 1. Make sure everything is clean */
1750 //synchronize_user_stack();
1751
1752 sigframe_size = NF_ALIGNEDSZ;
1753 sf_addr = get_sigframe(ka, env, sigframe_size);
1754
1755 sf = lock_user(VERIFY_WRITE, sf_addr,
1756 sizeof(struct target_signal_frame), 0);
1757 if (!sf)
1758 goto sigsegv;
1759
1760 //fprintf(stderr, "sf: %x pc %x fp %x sp %x\n", sf, env->pc, env->regwptr[UREG_FP], env->regwptr[UREG_SP]);
1761 #if 0
1762 if (invalid_frame_pointer(sf, sigframe_size))
1763 goto sigill_and_return;
1764 #endif
1765 /* 2. Save the current process state */
1766 err = setup___siginfo(&sf->info, env, set->sig[0]);
1767 err |= __put_user(0, &sf->extra_size);
1768
1769 //err |= save_fpu_state(regs, &sf->fpu_state);
1770 //err |= __put_user(&sf->fpu_state, &sf->fpu_save);
1771
1772 err |= __put_user(set->sig[0], &sf->info.si_mask);
1773 for (i = 0; i < TARGET_NSIG_WORDS - 1; i++) {
1774 err |= __put_user(set->sig[i + 1], &sf->extramask[i]);
1775 }
1776
1777 for (i = 0; i < 8; i++) {
1778 err |= __put_user(env->regwptr[i + UREG_L0], &sf->ss.locals[i]);
1779 }
1780 for (i = 0; i < 8; i++) {
1781 err |= __put_user(env->regwptr[i + UREG_I0], &sf->ss.ins[i]);
1782 }
1783 if (err)
1784 goto sigsegv;
1785
1786 /* 3. signal handler back-trampoline and parameters */
1787 env->regwptr[UREG_FP] = sf_addr;
1788 env->regwptr[UREG_I0] = sig;
1789 env->regwptr[UREG_I1] = sf_addr +
1790 offsetof(struct target_signal_frame, info);
1791 env->regwptr[UREG_I2] = sf_addr +
1792 offsetof(struct target_signal_frame, info);
1793
1794 /* 4. signal handler */
1795 env->pc = ka->_sa_handler;
1796 env->npc = (env->pc + 4);
1797 /* 5. return to kernel instructions */
1798 if (ka->sa_restorer)
1799 env->regwptr[UREG_I7] = ka->sa_restorer;
1800 else {
1801 uint32_t val32;
1802
1803 env->regwptr[UREG_I7] = sf_addr +
1804 offsetof(struct target_signal_frame, insns) - 2 * 4;
1805
1806 /* mov __NR_sigreturn, %g1 */
1807 val32 = 0x821020d8;
1808 err |= __put_user(val32, &sf->insns[0]);
1809
1810 /* t 0x10 */
1811 val32 = 0x91d02010;
1812 err |= __put_user(val32, &sf->insns[1]);
1813 if (err)
1814 goto sigsegv;
1815
1816 /* Flush instruction space. */
1817 //flush_sig_insns(current->mm, (unsigned long) &(sf->insns[0]));
1818 // tb_flush(env);
1819 }
1820 unlock_user(sf, sf_addr, sizeof(struct target_signal_frame));
1821 return;
1822 #if 0
1823 sigill_and_return:
1824 force_sig(TARGET_SIGILL);
1825 #endif
1826 sigsegv:
1827 //fprintf(stderr, "force_sig\n");
1828 unlock_user(sf, sf_addr, sizeof(struct target_signal_frame));
1829 force_sig(TARGET_SIGSEGV);
1830 }
1831 static inline int
1832 restore_fpu_state(CPUState *env, qemu_siginfo_fpu_t *fpu)
1833 {
1834 int err;
1835 #if 0
1836 #ifdef CONFIG_SMP
1837 if (current->flags & PF_USEDFPU)
1838 regs->psr &= ~PSR_EF;
1839 #else
1840 if (current == last_task_used_math) {
1841 last_task_used_math = 0;
1842 regs->psr &= ~PSR_EF;
1843 }
1844 #endif
1845 current->used_math = 1;
1846 current->flags &= ~PF_USEDFPU;
1847 #endif
1848 #if 0
1849 if (verify_area (VERIFY_READ, fpu, sizeof(*fpu)))
1850 return -EFAULT;
1851 #endif
1852
1853 #if 0
1854 /* XXX: incorrect */
1855 err = __copy_from_user(&env->fpr[0], &fpu->si_float_regs[0],
1856 (sizeof(unsigned long) * 32));
1857 #endif
1858 err |= __get_user(env->fsr, &fpu->si_fsr);
1859 #if 0
1860 err |= __get_user(current->thread.fpqdepth, &fpu->si_fpqdepth);
1861 if (current->thread.fpqdepth != 0)
1862 err |= __copy_from_user(&current->thread.fpqueue[0],
1863 &fpu->si_fpqueue[0],
1864 ((sizeof(unsigned long) +
1865 (sizeof(unsigned long *)))*16));
1866 #endif
1867 return err;
1868 }
1869
1870
1871 static void setup_rt_frame(int sig, struct target_sigaction *ka,
1872 target_siginfo_t *info,
1873 target_sigset_t *set, CPUState *env)
1874 {
1875 fprintf(stderr, "setup_rt_frame: not implemented\n");
1876 }
1877
1878 long do_sigreturn(CPUState *env)
1879 {
1880 abi_ulong sf_addr;
1881 struct target_signal_frame *sf;
1882 uint32_t up_psr, pc, npc;
1883 target_sigset_t set;
1884 sigset_t host_set;
1885 abi_ulong fpu_save_addr;
1886 int err, i;
1887
1888 sf_addr = env->regwptr[UREG_FP];
1889 if (!lock_user_struct(VERIFY_READ, sf, sf_addr, 1))
1890 goto segv_and_exit;
1891 #if 0
1892 fprintf(stderr, "sigreturn\n");
1893 fprintf(stderr, "sf: %x pc %x fp %x sp %x\n", sf, env->pc, env->regwptr[UREG_FP], env->regwptr[UREG_SP]);
1894 #endif
1895 //cpu_dump_state(env, stderr, fprintf, 0);
1896
1897 /* 1. Make sure we are not getting garbage from the user */
1898
1899 if (sf_addr & 3)
1900 goto segv_and_exit;
1901
1902 err = __get_user(pc, &sf->info.si_regs.pc);
1903 err |= __get_user(npc, &sf->info.si_regs.npc);
1904
1905 if ((pc | npc) & 3)
1906 goto segv_and_exit;
1907
1908 /* 2. Restore the state */
1909 err |= __get_user(up_psr, &sf->info.si_regs.psr);
1910
1911 /* User can only change condition codes and FPU enabling in %psr. */
1912 env->psr = (up_psr & (PSR_ICC /* | PSR_EF */))
1913 | (env->psr & ~(PSR_ICC /* | PSR_EF */));
1914
1915 env->pc = pc;
1916 env->npc = npc;
1917 err |= __get_user(env->y, &sf->info.si_regs.y);
1918 for (i=0; i < 8; i++) {
1919 err |= __get_user(env->gregs[i], &sf->info.si_regs.u_regs[i]);
1920 }
1921 for (i=0; i < 8; i++) {
1922 err |= __get_user(env->regwptr[i + UREG_I0], &sf->info.si_regs.u_regs[i+8]);
1923 }
1924
1925 err |= __get_user(fpu_save_addr, &sf->fpu_save);
1926
1927 //if (fpu_save)
1928 // err |= restore_fpu_state(env, fpu_save);
1929
1930 /* This is pretty much atomic, no amount locking would prevent
1931 * the races which exist anyways.
1932 */
1933 err |= __get_user(set.sig[0], &sf->info.si_mask);
1934 for(i = 1; i < TARGET_NSIG_WORDS; i++) {
1935 err |= (__get_user(set.sig[i], &sf->extramask[i - 1]));
1936 }
1937
1938 target_to_host_sigset_internal(&host_set, &set);
1939 sigprocmask(SIG_SETMASK, &host_set, NULL);
1940
1941 if (err)
1942 goto segv_and_exit;
1943 unlock_user_struct(sf, sf_addr, 0);
1944 return env->regwptr[0];
1945
1946 segv_and_exit:
1947 unlock_user_struct(sf, sf_addr, 0);
1948 force_sig(TARGET_SIGSEGV);
1949 }
1950
1951 long do_rt_sigreturn(CPUState *env)
1952 {
1953 fprintf(stderr, "do_rt_sigreturn: not implemented\n");
1954 return -TARGET_ENOSYS;
1955 }
1956
1957 #if defined(TARGET_SPARC64) && !defined(TARGET_ABI32)
1958 #define MC_TSTATE 0
1959 #define MC_PC 1
1960 #define MC_NPC 2
1961 #define MC_Y 3
1962 #define MC_G1 4
1963 #define MC_G2 5
1964 #define MC_G3 6
1965 #define MC_G4 7
1966 #define MC_G5 8
1967 #define MC_G6 9
1968 #define MC_G7 10
1969 #define MC_O0 11
1970 #define MC_O1 12
1971 #define MC_O2 13
1972 #define MC_O3 14
1973 #define MC_O4 15
1974 #define MC_O5 16
1975 #define MC_O6 17
1976 #define MC_O7 18
1977 #define MC_NGREG 19
1978
1979 typedef abi_ulong target_mc_greg_t;
1980 typedef target_mc_greg_t target_mc_gregset_t[MC_NGREG];
1981
1982 struct target_mc_fq {
1983 abi_ulong *mcfq_addr;
1984 uint32_t mcfq_insn;
1985 };
1986
1987 struct target_mc_fpu {
1988 union {
1989 uint32_t sregs[32];
1990 uint64_t dregs[32];
1991 //uint128_t qregs[16];
1992 } mcfpu_fregs;
1993 abi_ulong mcfpu_fsr;
1994 abi_ulong mcfpu_fprs;
1995 abi_ulong mcfpu_gsr;
1996 struct target_mc_fq *mcfpu_fq;
1997 unsigned char mcfpu_qcnt;
1998 unsigned char mcfpu_qentsz;
1999 unsigned char mcfpu_enab;
2000 };
2001 typedef struct target_mc_fpu target_mc_fpu_t;
2002
2003 typedef struct {
2004 target_mc_gregset_t mc_gregs;
2005 target_mc_greg_t mc_fp;
2006 target_mc_greg_t mc_i7;
2007 target_mc_fpu_t mc_fpregs;
2008 } target_mcontext_t;
2009
2010 struct target_ucontext {
2011 struct target_ucontext *uc_link;
2012 abi_ulong uc_flags;
2013 target_sigset_t uc_sigmask;
2014 target_mcontext_t uc_mcontext;
2015 };
2016
2017 /* A V9 register window */
2018 struct target_reg_window {
2019 abi_ulong locals[8];
2020 abi_ulong ins[8];
2021 };
2022
2023 #define TARGET_STACK_BIAS 2047
2024
2025 /* {set, get}context() needed for 64-bit SparcLinux userland. */
2026 void sparc64_set_context(CPUSPARCState *env)
2027 {
2028 abi_ulong ucp_addr;
2029 struct target_ucontext *ucp;
2030 target_mc_gregset_t *grp;
2031 abi_ulong pc, npc, tstate;
2032 abi_ulong fp, i7, w_addr;
2033 unsigned char fenab;
2034 int err;
2035 unsigned int i;
2036
2037 ucp_addr = env->regwptr[UREG_I0];
2038 if (!lock_user_struct(VERIFY_READ, ucp, ucp_addr, 1))
2039 goto do_sigsegv;
2040 grp = &ucp->uc_mcontext.mc_gregs;
2041 err = __get_user(pc, &((*grp)[MC_PC]));
2042 err |= __get_user(npc, &((*grp)[MC_NPC]));
2043 if (err || ((pc | npc) & 3))
2044 goto do_sigsegv;
2045 if (env->regwptr[UREG_I1]) {
2046 target_sigset_t target_set;
2047 sigset_t set;
2048
2049 if (TARGET_NSIG_WORDS == 1) {
2050 if (__get_user(target_set.sig[0], &ucp->uc_sigmask.sig[0]))
2051 goto do_sigsegv;
2052 } else {
2053 abi_ulong *src, *dst;
2054 src = ucp->uc_sigmask.sig;
2055 dst = target_set.sig;
2056 for (i = 0; i < sizeof(target_sigset_t) / sizeof(abi_ulong);
2057 i++, dst++, src++)
2058 err |= __get_user(*dst, src);
2059 if (err)
2060 goto do_sigsegv;
2061 }
2062 target_to_host_sigset_internal(&set, &target_set);
2063 sigprocmask(SIG_SETMASK, &set, NULL);
2064 }
2065 env->pc = pc;
2066 env->npc = npc;
2067 err |= __get_user(env->y, &((*grp)[MC_Y]));
2068 err |= __get_user(tstate, &((*grp)[MC_TSTATE]));
2069 env->asi = (tstate >> 24) & 0xff;
2070 PUT_CCR(env, tstate >> 32);
2071 PUT_CWP64(env, tstate & 0x1f);
2072 err |= __get_user(env->gregs[1], (&(*grp)[MC_G1]));
2073 err |= __get_user(env->gregs[2], (&(*grp)[MC_G2]));
2074 err |= __get_user(env->gregs[3], (&(*grp)[MC_G3]));
2075 err |= __get_user(env->gregs[4], (&(*grp)[MC_G4]));
2076 err |= __get_user(env->gregs[5], (&(*grp)[MC_G5]));
2077 err |= __get_user(env->gregs[6], (&(*grp)[MC_G6]));
2078 err |= __get_user(env->gregs[7], (&(*grp)[MC_G7]));
2079 err |= __get_user(env->regwptr[UREG_I0], (&(*grp)[MC_O0]));
2080 err |= __get_user(env->regwptr[UREG_I1], (&(*grp)[MC_O1]));
2081 err |= __get_user(env->regwptr[UREG_I2], (&(*grp)[MC_O2]));
2082 err |= __get_user(env->regwptr[UREG_I3], (&(*grp)[MC_O3]));
2083 err |= __get_user(env->regwptr[UREG_I4], (&(*grp)[MC_O4]));
2084 err |= __get_user(env->regwptr[UREG_I5], (&(*grp)[MC_O5]));
2085 err |= __get_user(env->regwptr[UREG_I6], (&(*grp)[MC_O6]));
2086 err |= __get_user(env->regwptr[UREG_I7], (&(*grp)[MC_O7]));
2087
2088 err |= __get_user(fp, &(ucp->uc_mcontext.mc_fp));
2089 err |= __get_user(i7, &(ucp->uc_mcontext.mc_i7));
2090
2091 w_addr = TARGET_STACK_BIAS+env->regwptr[UREG_I6];
2092 if (put_user(fp, w_addr + offsetof(struct target_reg_window, ins[6]),
2093 abi_ulong) != 0)
2094 goto do_sigsegv;
2095 if (put_user(i7, w_addr + offsetof(struct target_reg_window, ins[7]),
2096 abi_ulong) != 0)
2097 goto do_sigsegv;
2098 err |= __get_user(fenab, &(ucp->uc_mcontext.mc_fpregs.mcfpu_enab));
2099 err |= __get_user(env->fprs, &(ucp->uc_mcontext.mc_fpregs.mcfpu_fprs));
2100 {
2101 uint32_t *src, *dst;
2102 src = ucp->uc_mcontext.mc_fpregs.mcfpu_fregs.sregs;
2103 dst = env->fpr;
2104 /* XXX: check that the CPU storage is the same as user context */
2105 for (i = 0; i < 64; i++, dst++, src++)
2106 err |= __get_user(*dst, src);
2107 }
2108 err |= __get_user(env->fsr,
2109 &(ucp->uc_mcontext.mc_fpregs.mcfpu_fsr));
2110 err |= __get_user(env->gsr,
2111 &(ucp->uc_mcontext.mc_fpregs.mcfpu_gsr));
2112 if (err)
2113 goto do_sigsegv;
2114 unlock_user_struct(ucp, ucp_addr, 0);
2115 return;
2116 do_sigsegv:
2117 unlock_user_struct(ucp, ucp_addr, 0);
2118 force_sig(SIGSEGV);
2119 }
2120
2121 void sparc64_get_context(CPUSPARCState *env)
2122 {
2123 abi_ulong ucp_addr;
2124 struct target_ucontext *ucp;
2125 target_mc_gregset_t *grp;
2126 target_mcontext_t *mcp;
2127 abi_ulong fp, i7, w_addr;
2128 int err;
2129 unsigned int i;
2130 target_sigset_t target_set;
2131 sigset_t set;
2132
2133 ucp_addr = env->regwptr[UREG_I0];
2134 if (!lock_user_struct(VERIFY_WRITE, ucp, ucp_addr, 0))
2135 goto do_sigsegv;
2136
2137 mcp = &ucp->uc_mcontext;
2138 grp = &mcp->mc_gregs;
2139
2140 /* Skip over the trap instruction, first. */
2141 env->pc = env->npc;
2142 env->npc += 4;
2143
2144 err = 0;
2145
2146 sigprocmask(0, NULL, &set);
2147 host_to_target_sigset_internal(&target_set, &set);
2148 if (TARGET_NSIG_WORDS == 1) {
2149 err |= __put_user(target_set.sig[0],
2150 (abi_ulong *)&ucp->uc_sigmask);
2151 } else {
2152 abi_ulong *src, *dst;
2153 src = target_set.sig;
2154 dst = ucp->uc_sigmask.sig;
2155 for (i = 0; i < sizeof(target_sigset_t) / sizeof(abi_ulong);
2156 i++, dst++, src++)
2157 err |= __put_user(*src, dst);
2158 if (err)
2159 goto do_sigsegv;
2160 }
2161
2162 /* XXX: tstate must be saved properly */
2163 // err |= __put_user(env->tstate, &((*grp)[MC_TSTATE]));
2164 err |= __put_user(env->pc, &((*grp)[MC_PC]));
2165 err |= __put_user(env->npc, &((*grp)[MC_NPC]));
2166 err |= __put_user(env->y, &((*grp)[MC_Y]));
2167 err |= __put_user(env->gregs[1], &((*grp)[MC_G1]));
2168 err |= __put_user(env->gregs[2], &((*grp)[MC_G2]));
2169 err |= __put_user(env->gregs[3], &((*grp)[MC_G3]));
2170 err |= __put_user(env->gregs[4], &((*grp)[MC_G4]));
2171 err |= __put_user(env->gregs[5], &((*grp)[MC_G5]));
2172 err |= __put_user(env->gregs[6], &((*grp)[MC_G6]));
2173 err |= __put_user(env->gregs[7], &((*grp)[MC_G7]));
2174 err |= __put_user(env->regwptr[UREG_I0], &((*grp)[MC_O0]));
2175 err |= __put_user(env->regwptr[UREG_I1], &((*grp)[MC_O1]));
2176 err |= __put_user(env->regwptr[UREG_I2], &((*grp)[MC_O2]));
2177 err |= __put_user(env->regwptr[UREG_I3], &((*grp)[MC_O3]));
2178 err |= __put_user(env->regwptr[UREG_I4], &((*grp)[MC_O4]));
2179 err |= __put_user(env->regwptr[UREG_I5], &((*grp)[MC_O5]));
2180 err |= __put_user(env->regwptr[UREG_I6], &((*grp)[MC_O6]));
2181 err |= __put_user(env->regwptr[UREG_I7], &((*grp)[MC_O7]));
2182
2183 w_addr = TARGET_STACK_BIAS+env->regwptr[UREG_I6];
2184 fp = i7 = 0;
2185 if (get_user(fp, w_addr + offsetof(struct target_reg_window, ins[6]),
2186 abi_ulong) != 0)
2187 goto do_sigsegv;
2188 if (get_user(i7, w_addr + offsetof(struct target_reg_window, ins[7]),
2189 abi_ulong) != 0)
2190 goto do_sigsegv;
2191 err |= __put_user(fp, &(mcp->mc_fp));
2192 err |= __put_user(i7, &(mcp->mc_i7));
2193
2194 {
2195 uint32_t *src, *dst;
2196 src = env->fpr;
2197 dst = ucp->uc_mcontext.mc_fpregs.mcfpu_fregs.sregs;
2198 /* XXX: check that the CPU storage is the same as user context */
2199 for (i = 0; i < 64; i++, dst++, src++)
2200 err |= __put_user(*src, dst);
2201 }
2202 err |= __put_user(env->fsr, &(mcp->mc_fpregs.mcfpu_fsr));
2203 err |= __put_user(env->gsr, &(mcp->mc_fpregs.mcfpu_gsr));
2204 err |= __put_user(env->fprs, &(mcp->mc_fpregs.mcfpu_fprs));
2205
2206 if (err)
2207 goto do_sigsegv;
2208 unlock_user_struct(ucp, ucp_addr, 1);
2209 return;
2210 do_sigsegv:
2211 unlock_user_struct(ucp, ucp_addr, 1);
2212 force_sig(SIGSEGV);
2213 }
2214 #endif
2215 #elif defined(TARGET_ABI_MIPSN64)
2216
2217 # warning signal handling not implemented
2218
2219 static void setup_frame(int sig, struct target_sigaction *ka,
2220 target_sigset_t *set, CPUState *env)
2221 {
2222 fprintf(stderr, "setup_frame: not implemented\n");
2223 }
2224
2225 static void setup_rt_frame(int sig, struct target_sigaction *ka,
2226 target_siginfo_t *info,
2227 target_sigset_t *set, CPUState *env)
2228 {
2229 fprintf(stderr, "setup_rt_frame: not implemented\n");
2230 }
2231
2232 long do_sigreturn(CPUState *env)
2233 {
2234 fprintf(stderr, "do_sigreturn: not implemented\n");
2235 return -TARGET_ENOSYS;
2236 }
2237
2238 long do_rt_sigreturn(CPUState *env)
2239 {
2240 fprintf(stderr, "do_rt_sigreturn: not implemented\n");
2241 return -TARGET_ENOSYS;
2242 }
2243
2244 #elif defined(TARGET_ABI_MIPSN32)
2245
2246 # warning signal handling not implemented
2247
2248 static void setup_frame(int sig, struct target_sigaction *ka,
2249 target_sigset_t *set, CPUState *env)
2250 {
2251 fprintf(stderr, "setup_frame: not implemented\n");
2252 }
2253
2254 static void setup_rt_frame(int sig, struct target_sigaction *ka,
2255 target_siginfo_t *info,
2256 target_sigset_t *set, CPUState *env)
2257 {
2258 fprintf(stderr, "setup_rt_frame: not implemented\n");
2259 }
2260
2261 long do_sigreturn(CPUState *env)
2262 {
2263 fprintf(stderr, "do_sigreturn: not implemented\n");
2264 return -TARGET_ENOSYS;
2265 }
2266
2267 long do_rt_sigreturn(CPUState *env)
2268 {
2269 fprintf(stderr, "do_rt_sigreturn: not implemented\n");
2270 return -TARGET_ENOSYS;
2271 }
2272
2273 #elif defined(TARGET_ABI_MIPSO32)
2274
2275 struct target_sigcontext {
2276 uint32_t sc_regmask; /* Unused */
2277 uint32_t sc_status;
2278 uint64_t sc_pc;
2279 uint64_t sc_regs[32];
2280 uint64_t sc_fpregs[32];
2281 uint32_t sc_ownedfp; /* Unused */
2282 uint32_t sc_fpc_csr;
2283 uint32_t sc_fpc_eir; /* Unused */
2284 uint32_t sc_used_math;
2285 uint32_t sc_dsp; /* dsp status, was sc_ssflags */
2286 uint64_t sc_mdhi;
2287 uint64_t sc_mdlo;
2288 target_ulong sc_hi1; /* Was sc_cause */
2289 target_ulong sc_lo1; /* Was sc_badvaddr */
2290 target_ulong sc_hi2; /* Was sc_sigset[4] */
2291 target_ulong sc_lo2;
2292 target_ulong sc_hi3;
2293 target_ulong sc_lo3;
2294 };
2295
2296 struct sigframe {
2297 uint32_t sf_ass[4]; /* argument save space for o32 */
2298 uint32_t sf_code[2]; /* signal trampoline */
2299 struct target_sigcontext sf_sc;
2300 target_sigset_t sf_mask;
2301 };
2302
2303 /* Install trampoline to jump back from signal handler */
2304 static inline int install_sigtramp(unsigned int *tramp, unsigned int syscall)
2305 {
2306 int err;
2307
2308 /*
2309 * Set up the return code ...
2310 *
2311 * li v0, __NR__foo_sigreturn
2312 * syscall
2313 */
2314
2315 err = __put_user(0x24020000 + syscall, tramp + 0);
2316 err |= __put_user(0x0000000c , tramp + 1);
2317 /* flush_cache_sigtramp((unsigned long) tramp); */
2318 return err;
2319 }
2320
2321 static inline int
2322 setup_sigcontext(CPUState *regs, struct target_sigcontext *sc)
2323 {
2324 int err = 0;
2325
2326 err |= __put_user(regs->active_tc.PC, &sc->sc_pc);
2327
2328 #define save_gp_reg(i) do { \
2329 err |= __put_user(regs->active_tc.gpr[i], &sc->sc_regs[i]); \
2330 } while(0)
2331 __put_user(0, &sc->sc_regs[0]); save_gp_reg(1); save_gp_reg(2);
2332 save_gp_reg(3); save_gp_reg(4); save_gp_reg(5); save_gp_reg(6);
2333 save_gp_reg(7); save_gp_reg(8); save_gp_reg(9); save_gp_reg(10);
2334 save_gp_reg(11); save_gp_reg(12); save_gp_reg(13); save_gp_reg(14);
2335 save_gp_reg(15); save_gp_reg(16); save_gp_reg(17); save_gp_reg(18);
2336 save_gp_reg(19); save_gp_reg(20); save_gp_reg(21); save_gp_reg(22);
2337 save_gp_reg(23); save_gp_reg(24); save_gp_reg(25); save_gp_reg(26);
2338 save_gp_reg(27); save_gp_reg(28); save_gp_reg(29); save_gp_reg(30);
2339 save_gp_reg(31);
2340 #undef save_gp_reg
2341
2342 err |= __put_user(regs->active_tc.HI[0], &sc->sc_mdhi);
2343 err |= __put_user(regs->active_tc.LO[0], &sc->sc_mdlo);
2344
2345 /* Not used yet, but might be useful if we ever have DSP suppport */
2346 #if 0
2347 if (cpu_has_dsp) {
2348 err |= __put_user(mfhi1(), &sc->sc_hi1);
2349 err |= __put_user(mflo1(), &sc->sc_lo1);
2350 err |= __put_user(mfhi2(), &sc->sc_hi2);
2351 err |= __put_user(mflo2(), &sc->sc_lo2);
2352 err |= __put_user(mfhi3(), &sc->sc_hi3);
2353 err |= __put_user(mflo3(), &sc->sc_lo3);
2354 err |= __put_user(rddsp(DSP_MASK), &sc->sc_dsp);
2355 }
2356 /* same with 64 bit */
2357 #ifdef CONFIG_64BIT
2358 err |= __put_user(regs->hi, &sc->sc_hi[0]);
2359 err |= __put_user(regs->lo, &sc->sc_lo[0]);
2360 if (cpu_has_dsp) {
2361 err |= __put_user(mfhi1(), &sc->sc_hi[1]);
2362 err |= __put_user(mflo1(), &sc->sc_lo[1]);
2363 err |= __put_user(mfhi2(), &sc->sc_hi[2]);
2364 err |= __put_user(mflo2(), &sc->sc_lo[2]);
2365 err |= __put_user(mfhi3(), &sc->sc_hi[3]);
2366 err |= __put_user(mflo3(), &sc->sc_lo[3]);
2367 err |= __put_user(rddsp(DSP_MASK), &sc->sc_dsp);
2368 }
2369 #endif
2370 #endif
2371
2372 #if 0
2373 err |= __put_user(!!used_math(), &sc->sc_used_math);
2374
2375 if (!used_math())
2376 goto out;
2377
2378 /*
2379 * Save FPU state to signal context. Signal handler will "inherit"
2380 * current FPU state.
2381 */
2382 preempt_disable();
2383
2384 if (!is_fpu_owner()) {
2385 own_fpu();
2386 restore_fp(current);
2387 }
2388 err |= save_fp_context(sc);
2389
2390 preempt_enable();
2391 out:
2392 #endif
2393 return err;
2394 }
2395
2396 static inline int
2397 restore_sigcontext(CPUState *regs, struct target_sigcontext *sc)
2398 {
2399 int err = 0;
2400
2401 err |= __get_user(regs->CP0_EPC, &sc->sc_pc);
2402
2403 err |= __get_user(regs->active_tc.HI[0], &sc->sc_mdhi);
2404 err |= __get_user(regs->active_tc.LO[0], &sc->sc_mdlo);
2405
2406 #define restore_gp_reg(i) do { \
2407 err |= __get_user(regs->active_tc.gpr[i], &sc->sc_regs[i]); \
2408 } while(0)
2409 restore_gp_reg( 1); restore_gp_reg( 2); restore_gp_reg( 3);
2410 restore_gp_reg( 4); restore_gp_reg( 5); restore_gp_reg( 6);
2411 restore_gp_reg( 7); restore_gp_reg( 8); restore_gp_reg( 9);
2412 restore_gp_reg(10); restore_gp_reg(11); restore_gp_reg(12);
2413 restore_gp_reg(13); restore_gp_reg(14); restore_gp_reg(15);
2414 restore_gp_reg(16); restore_gp_reg(17); restore_gp_reg(18);
2415 restore_gp_reg(19); restore_gp_reg(20); restore_gp_reg(21);
2416 restore_gp_reg(22); restore_gp_reg(23); restore_gp_reg(24);
2417 restore_gp_reg(25); restore_gp_reg(26); restore_gp_reg(27);
2418 restore_gp_reg(28); restore_gp_reg(29); restore_gp_reg(30);
2419 restore_gp_reg(31);
2420 #undef restore_gp_reg
2421
2422 #if 0
2423 if (cpu_has_dsp) {
2424 err |= __get_user(treg, &sc->sc_hi1); mthi1(treg);
2425 err |= __get_user(treg, &sc->sc_lo1); mtlo1(treg);
2426 err |= __get_user(treg, &sc->sc_hi2); mthi2(treg);
2427 err |= __get_user(treg, &sc->sc_lo2); mtlo2(treg);
2428 err |= __get_user(treg, &sc->sc_hi3); mthi3(treg);
2429 err |= __get_user(treg, &sc->sc_lo3); mtlo3(treg);
2430 err |= __get_user(treg, &sc->sc_dsp); wrdsp(treg, DSP_MASK);
2431 }
2432 #ifdef CONFIG_64BIT
2433 err |= __get_user(regs->hi, &sc->sc_hi[0]);
2434 err |= __get_user(regs->lo, &sc->sc_lo[0]);
2435 if (cpu_has_dsp) {
2436 err |= __get_user(treg, &sc->sc_hi[1]); mthi1(treg);
2437 err |= __get_user(treg, &sc->sc_lo[1]); mthi1(treg);
2438 err |= __get_user(treg, &sc->sc_hi[2]); mthi2(treg);
2439 err |= __get_user(treg, &sc->sc_lo[2]); mthi2(treg);
2440 err |= __get_user(treg, &sc->sc_hi[3]); mthi3(treg);
2441 err |= __get_user(treg, &sc->sc_lo[3]); mthi3(treg);
2442 err |= __get_user(treg, &sc->sc_dsp); wrdsp(treg, DSP_MASK);
2443 }
2444 #endif
2445
2446 err |= __get_user(used_math, &sc->sc_used_math);
2447 conditional_used_math(used_math);
2448
2449 preempt_disable();
2450
2451 if (used_math()) {
2452 /* restore fpu context if we have used it before */
2453 own_fpu();
2454 err |= restore_fp_context(sc);
2455 } else {
2456 /* signal handler may have used FPU. Give it up. */
2457 lose_fpu();
2458 }
2459
2460 preempt_enable();
2461 #endif
2462 return err;
2463 }
2464 /*
2465 * Determine which stack to use..
2466 */
2467 static inline abi_ulong
2468 get_sigframe(struct target_sigaction *ka, CPUState *regs, size_t frame_size)
2469 {
2470 unsigned long sp;
2471
2472 /* Default to using normal stack */
2473 sp = regs->active_tc.gpr[29];
2474
2475 /*
2476 * FPU emulator may have it's own trampoline active just
2477 * above the user stack, 16-bytes before the next lowest
2478 * 16 byte boundary. Try to avoid trashing it.
2479 */
2480 sp -= 32;
2481
2482 /* This is the X/Open sanctioned signal stack switching. */
2483 if ((ka->sa_flags & TARGET_SA_ONSTACK) && (sas_ss_flags (sp) == 0)) {
2484 sp = target_sigaltstack_used.ss_sp + target_sigaltstack_used.ss_size;
2485 }
2486
2487 return (sp - frame_size) & ~7;
2488 }
2489
2490 /* compare linux/arch/mips/kernel/signal.c:setup_frame() */
2491 static void setup_frame(int sig, struct target_sigaction * ka,
2492 target_sigset_t *set, CPUState *regs)
2493 {
2494 struct sigframe *frame;
2495 abi_ulong frame_addr;
2496 int i;
2497
2498 frame_addr = get_sigframe(ka, regs, sizeof(*frame));
2499 if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
2500 goto give_sigsegv;
2501
2502 install_sigtramp(frame->sf_code, TARGET_NR_sigreturn);
2503
2504 if(setup_sigcontext(regs, &frame->sf_sc))
2505 goto give_sigsegv;
2506
2507 for(i = 0; i < TARGET_NSIG_WORDS; i++) {
2508 if(__put_user(set->sig[i], &frame->sf_mask.sig[i]))
2509 goto give_sigsegv;
2510 }
2511
2512 /*
2513 * Arguments to signal handler:
2514 *
2515 * a0 = signal number
2516 * a1 = 0 (should be cause)
2517 * a2 = pointer to struct sigcontext
2518 *
2519 * $25 and PC point to the signal handler, $29 points to the
2520 * struct sigframe.
2521 */
2522 regs->active_tc.gpr[ 4] = sig;
2523 regs->active_tc.gpr[ 5] = 0;
2524 regs->active_tc.gpr[ 6] = frame_addr + offsetof(struct sigframe, sf_sc);
2525 regs->active_tc.gpr[29] = frame_addr;
2526 regs->active_tc.gpr[31] = frame_addr + offsetof(struct sigframe, sf_code);
2527 /* The original kernel code sets CP0_EPC to the handler
2528 * since it returns to userland using eret
2529 * we cannot do this here, and we must set PC directly */
2530 regs->active_tc.PC = regs->active_tc.gpr[25] = ka->_sa_handler;
2531 unlock_user_struct(frame, frame_addr, 1);
2532 return;
2533
2534 give_sigsegv:
2535 unlock_user_struct(frame, frame_addr, 1);
2536 force_sig(TARGET_SIGSEGV/*, current*/);
2537 return;
2538 }
2539
2540 long do_sigreturn(CPUState *regs)
2541 {
2542 struct sigframe *frame;
2543 abi_ulong frame_addr;
2544 sigset_t blocked;
2545 target_sigset_t target_set;
2546 int i;
2547
2548 #if defined(DEBUG_SIGNAL)
2549 fprintf(stderr, "do_sigreturn\n");
2550 #endif
2551 frame_addr = regs->active_tc.gpr[29];
2552 if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1))
2553 goto badframe;
2554
2555 for(i = 0; i < TARGET_NSIG_WORDS; i++) {
2556 if(__get_user(target_set.sig[i], &frame->sf_mask.sig[i]))
2557 goto badframe;
2558 }
2559
2560 target_to_host_sigset_internal(&blocked, &target_set);
2561 sigprocmask(SIG_SETMASK, &blocked, NULL);
2562
2563 if (restore_sigcontext(regs, &frame->sf_sc))
2564 goto badframe;
2565
2566 #if 0
2567 /*
2568 * Don't let your children do this ...
2569 */
2570 __asm__ __volatile__(
2571 "move\t$29, %0\n\t"
2572 "j\tsyscall_exit"
2573 :/* no outputs */
2574 :"r" (&regs));
2575 /* Unreached */
2576 #endif
2577
2578 regs->active_tc.PC = regs->CP0_EPC;
2579 /* I am not sure this is right, but it seems to work
2580 * maybe a problem with nested signals ? */
2581 regs->CP0_EPC = 0;
2582 return 0;
2583
2584 badframe:
2585 force_sig(TARGET_SIGSEGV/*, current*/);
2586 return 0;
2587 }
2588
2589 static void setup_rt_frame(int sig, struct target_sigaction *ka,
2590 target_siginfo_t *info,
2591 target_sigset_t *set, CPUState *env)
2592 {
2593 fprintf(stderr, "setup_rt_frame: not implemented\n");
2594 }
2595
2596 long do_rt_sigreturn(CPUState *env)
2597 {
2598 fprintf(stderr, "do_rt_sigreturn: not implemented\n");
2599 return -TARGET_ENOSYS;
2600 }
2601
2602 #elif defined(TARGET_SH4)
2603
2604 /*
2605 * code and data structures from linux kernel:
2606 * include/asm-sh/sigcontext.h
2607 * arch/sh/kernel/signal.c
2608 */
2609
2610 struct target_sigcontext {
2611 target_ulong oldmask;
2612
2613 /* CPU registers */
2614 target_ulong sc_gregs[16];
2615 target_ulong sc_pc;
2616 target_ulong sc_pr;
2617 target_ulong sc_sr;
2618 target_ulong sc_gbr;
2619 target_ulong sc_mach;
2620 target_ulong sc_macl;
2621
2622 /* FPU registers */
2623 target_ulong sc_fpregs[16];
2624 target_ulong sc_xfpregs[16];
2625 unsigned int sc_fpscr;
2626 unsigned int sc_fpul;
2627 unsigned int sc_ownedfp;
2628 };
2629
2630 struct target_sigframe
2631 {
2632 struct target_sigcontext sc;
2633 target_ulong extramask[TARGET_NSIG_WORDS-1];
2634 uint16_t retcode[3];
2635 };
2636
2637
2638 struct target_ucontext {
2639 target_ulong uc_flags;
2640 struct target_ucontext *uc_link;
2641 target_stack_t uc_stack;
2642 struct target_sigcontext uc_mcontext;
2643 target_sigset_t uc_sigmask; /* mask last for extensibility */
2644 };
2645
2646 struct target_rt_sigframe
2647 {
2648 struct target_siginfo info;
2649 struct target_ucontext uc;
2650 uint16_t retcode[3];
2651 };
2652
2653
2654 #define MOVW(n) (0x9300|((n)-2)) /* Move mem word at PC+n to R3 */
2655 #define TRAP_NOARG 0xc310 /* Syscall w/no args (NR in R3) SH3/4 */
2656
2657 static abi_ulong get_sigframe(struct target_sigaction *ka,
2658 unsigned long sp, size_t frame_size)
2659 {
2660 if ((ka->sa_flags & TARGET_SA_ONSTACK) && (sas_ss_flags(sp) == 0)) {
2661 sp = target_sigaltstack_used.ss_sp + target_sigaltstack_used.ss_size;
2662 }
2663
2664 return (sp - frame_size) & -8ul;
2665 }
2666
2667 static int setup_sigcontext(struct target_sigcontext *sc,
2668 CPUState *regs, unsigned long mask)
2669 {
2670 int err = 0;
2671
2672 #define COPY(x) err |= __put_user(regs->x, &sc->sc_##x)
2673 COPY(gregs[0]); COPY(gregs[1]);
2674 COPY(gregs[2]); COPY(gregs[3]);
2675 COPY(gregs[4]); COPY(gregs[5]);
2676 COPY(gregs[6]); COPY(gregs[7]);
2677 COPY(gregs[8]); COPY(gregs[9]);
2678 COPY(gregs[10]); COPY(gregs[11]);
2679 COPY(gregs[12]); COPY(gregs[13]);
2680 COPY(gregs[14]); COPY(gregs[15]);
2681 COPY(gbr); COPY(mach);
2682 COPY(macl); COPY(pr);
2683 COPY(sr); COPY(pc);
2684 #undef COPY
2685
2686 /* todo: save FPU registers here */
2687
2688 /* non-iBCS2 extensions.. */
2689 err |= __put_user(mask, &sc->oldmask);
2690
2691 return err;
2692 }
2693
2694 static int restore_sigcontext(struct CPUState *regs,
2695 struct target_sigcontext *sc)
2696 {
2697 unsigned int err = 0;
2698
2699 #define COPY(x) err |= __get_user(regs->x, &sc->sc_##x)
2700 COPY(gregs[1]);
2701 COPY(gregs[2]); COPY(gregs[3]);
2702 COPY(gregs[4]); COPY(gregs[5]);
2703 COPY(gregs[6]); COPY(gregs[7]);
2704 COPY(gregs[8]); COPY(gregs[9]);
2705 COPY(gregs[10]); COPY(gregs[11]);
2706 COPY(gregs[12]); COPY(gregs[13]);
2707 COPY(gregs[14]); COPY(gregs[15]);
2708 COPY(gbr); COPY(mach);
2709 COPY(macl); COPY(pr);
2710 COPY(sr); COPY(pc);
2711 #undef COPY
2712
2713 /* todo: restore FPU registers here */
2714
2715 regs->tra = -1; /* disable syscall checks */
2716 return err;
2717 }
2718
2719 static void setup_frame(int sig, struct target_sigaction *ka,
2720 target_sigset_t *set, CPUState *regs)
2721 {
2722 struct target_sigframe *frame;
2723 abi_ulong frame_addr;
2724 int i;
2725 int err = 0;
2726 int signal;
2727
2728 frame_addr = get_sigframe(ka, regs->gregs[15], sizeof(*frame));
2729 if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
2730 goto give_sigsegv;
2731
2732 signal = current_exec_domain_sig(sig);
2733
2734 err |= setup_sigcontext(&frame->sc, regs, set->sig[0]);
2735
2736 for (i = 0; i < TARGET_NSIG_WORDS - 1; i++) {
2737 err |= __put_user(set->sig[i + 1], &frame->extramask[i]);
2738 }
2739
2740 /* Set up to return from userspace. If provided, use a stub
2741 already in userspace. */
2742 if (ka->sa_flags & TARGET_SA_RESTORER) {
2743 regs->pr = (unsigned long) ka->sa_restorer;
2744 } else {
2745 /* Generate return code (system call to sigreturn) */
2746 err |= __put_user(MOVW(2), &frame->retcode[0]);
2747 err |= __put_user(TRAP_NOARG, &frame->retcode[1]);
2748 err |= __put_user((TARGET_NR_sigreturn), &frame->retcode[2]);
2749 regs->pr = (unsigned long) frame->retcode;
2750 }
2751
2752 if (err)
2753 goto give_sigsegv;
2754
2755 /* Set up registers for signal handler */
2756 regs->gregs[15] = (unsigned long) frame;
2757 regs->gregs[4] = signal; /* Arg for signal handler */
2758 regs->gregs[5] = 0;
2759 regs->gregs[6] = (unsigned long) &frame->sc;
2760 regs->pc = (unsigned long) ka->_sa_handler;
2761
2762 unlock_user_struct(frame, frame_addr, 1);
2763 return;
2764
2765 give_sigsegv:
2766 unlock_user_struct(frame, frame_addr, 1);
2767 force_sig(SIGSEGV);
2768 }
2769
2770 static void setup_rt_frame(int sig, struct target_sigaction *ka,
2771 target_siginfo_t *info,
2772 target_sigset_t *set, CPUState *regs)
2773 {
2774 struct target_rt_sigframe *frame;
2775 abi_ulong frame_addr;
2776 int i;
2777 int err = 0;
2778 int signal;
2779
2780 frame_addr = get_sigframe(ka, regs->gregs[15], sizeof(*frame));
2781 if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
2782 goto give_sigsegv;
2783
2784 signal = current_exec_domain_sig(sig);
2785
2786 err |= copy_siginfo_to_user(&frame->info, info);
2787
2788 /* Create the ucontext. */
2789 err |= __put_user(0, &frame->uc.uc_flags);
2790 err |= __put_user(0, (unsigned long *)&frame->uc.uc_link);
2791 err |= __put_user((unsigned long)target_sigaltstack_used.ss_sp,
2792 &frame->uc.uc_stack.ss_sp);
2793 err |= __put_user(sas_ss_flags(regs->gregs[15]),
2794 &frame->uc.uc_stack.ss_flags);
2795 err |= __put_user(target_sigaltstack_used.ss_size,
2796 &frame->uc.uc_stack.ss_size);
2797 err |= setup_sigcontext(&frame->uc.uc_mcontext,
2798 regs, set->sig[0]);
2799 for(i = 0; i < TARGET_NSIG_WORDS; i++) {
2800 err |= __put_user(set->sig[i], &frame->uc.uc_sigmask.sig[i]);
2801 }
2802
2803 /* Set up to return from userspace. If provided, use a stub
2804 already in userspace. */
2805 if (ka->sa_flags & TARGET_SA_RESTORER) {
2806 regs->pr = (unsigned long) ka->sa_restorer;
2807 } else {
2808 /* Generate return code (system call to sigreturn) */
2809 err |= __put_user(MOVW(2), &frame->retcode[0]);
2810 err |= __put_user(TRAP_NOARG, &frame->retcode[1]);
2811 err |= __put_user((TARGET_NR_rt_sigreturn), &frame->retcode[2]);
2812 regs->pr = (unsigned long) frame->retcode;
2813 }
2814
2815 if (err)
2816 goto give_sigsegv;
2817
2818 /* Set up registers for signal handler */
2819 regs->gregs[15] = (unsigned long) frame;
2820 regs->gregs[4] = signal; /* Arg for signal handler */
2821 regs->gregs[5] = (unsigned long) &frame->info;
2822 regs->gregs[6] = (unsigned long) &frame->uc;
2823 regs->pc = (unsigned long) ka->_sa_handler;
2824
2825 unlock_user_struct(frame, frame_addr, 1);
2826 return;
2827
2828 give_sigsegv:
2829 unlock_user_struct(frame, frame_addr, 1);
2830 force_sig(SIGSEGV);
2831 }
2832
2833 long do_sigreturn(CPUState *regs)
2834 {
2835 struct target_sigframe *frame;
2836 abi_ulong frame_addr;
2837 sigset_t blocked;
2838 target_sigset_t target_set;
2839 int i;
2840 int err = 0;
2841
2842 #if defined(DEBUG_SIGNAL)
2843 fprintf(stderr, "do_sigreturn\n");
2844 #endif
2845 frame_addr = regs->gregs[15];
2846 if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1))
2847 goto badframe;
2848
2849 err |= __get_user(target_set.sig[0], &frame->sc.oldmask);
2850 for(i = 1; i < TARGET_NSIG_WORDS; i++) {
2851 err |= (__get_user(target_set.sig[i], &frame->extramask[i - 1]));
2852 }
2853
2854 if (err)
2855 goto badframe;
2856
2857 target_to_host_sigset_internal(&blocked, &target_set);
2858 sigprocmask(SIG_SETMASK, &blocked, NULL);
2859
2860 if (restore_sigcontext(regs, &frame->sc))
2861 goto badframe;
2862
2863 unlock_user_struct(frame, frame_addr, 0);
2864 return regs->gregs[0];
2865
2866 badframe:
2867 unlock_user_struct(frame, frame_addr, 0);
2868 force_sig(TARGET_SIGSEGV);
2869 return 0;
2870 }
2871
2872 long do_rt_sigreturn(CPUState *regs)
2873 {
2874 struct target_rt_sigframe *frame;
2875 abi_ulong frame_addr;
2876 sigset_t blocked;
2877
2878 #if defined(DEBUG_SIGNAL)
2879 fprintf(stderr, "do_rt_sigreturn\n");
2880 #endif
2881 frame_addr = regs->gregs[15];
2882 if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1))
2883 goto badframe;
2884
2885 target_to_host_sigset(&blocked, &frame->uc.uc_sigmask);
2886 sigprocmask(SIG_SETMASK, &blocked, NULL);
2887
2888 if (restore_sigcontext(regs, &frame->uc.uc_mcontext))
2889 goto badframe;
2890
2891 if (do_sigaltstack(frame_addr +
2892 offsetof(struct target_rt_sigframe, uc.uc_stack),
2893 0, get_sp_from_cpustate(regs)) == -EFAULT)
2894 goto badframe;
2895
2896 unlock_user_struct(frame, frame_addr, 0);
2897 return regs->gregs[0];
2898
2899 badframe:
2900 unlock_user_struct(frame, frame_addr, 0);
2901 force_sig(TARGET_SIGSEGV);
2902 return 0;
2903 }
2904 #elif defined(TARGET_CRIS)
2905
2906 struct target_sigcontext {
2907 struct target_pt_regs regs; /* needs to be first */
2908 uint32_t oldmask;
2909 uint32_t usp; /* usp before stacking this gunk on it */
2910 };
2911
2912 /* Signal frames. */
2913 struct target_signal_frame {
2914 struct target_sigcontext sc;
2915 uint32_t extramask[TARGET_NSIG_WORDS - 1];
2916 uint8_t retcode[8]; /* Trampoline code. */
2917 };
2918
2919 struct rt_signal_frame {
2920 struct siginfo *pinfo;
2921 void *puc;
2922 struct siginfo info;
2923 struct ucontext uc;
2924 uint8_t retcode[8]; /* Trampoline code. */
2925 };
2926
2927 static void setup_sigcontext(struct target_sigcontext *sc, CPUState *env)
2928 {
2929 __put_user(env->regs[0], &sc->regs.r0);
2930 __put_user(env->regs[1], &sc->regs.r1);
2931 __put_user(env->regs[2], &sc->regs.r2);
2932 __put_user(env->regs[3], &sc->regs.r3);
2933 __put_user(env->regs[4], &sc->regs.r4);
2934 __put_user(env->regs[5], &sc->regs.r5);
2935 __put_user(env->regs[6], &sc->regs.r6);
2936 __put_user(env->regs[7], &sc->regs.r7);
2937 __put_user(env->regs[8], &sc->regs.r8);
2938 __put_user(env->regs[9], &sc->regs.r9);
2939 __put_user(env->regs[10], &sc->regs.r10);
2940 __put_user(env->regs[11], &sc->regs.r11);
2941 __put_user(env->regs[12], &sc->regs.r12);
2942 __put_user(env->regs[13], &sc->regs.r13);
2943 __put_user(env->regs[14], &sc->usp);
2944 __put_user(env->regs[15], &sc->regs.acr);
2945 __put_user(env->pregs[PR_MOF], &sc->regs.mof);
2946 __put_user(env->pregs[PR_SRP], &sc->regs.srp);
2947 __put_user(env->pc, &sc->regs.erp);
2948 }
2949
2950 static void restore_sigcontext(struct target_sigcontext *sc, CPUState *env)
2951 {
2952 __get_user(env->regs[0], &sc->regs.r0);
2953 __get_user(env->regs[1], &sc->regs.r1);
2954 __get_user(env->regs[2], &sc->regs.r2);
2955 __get_user(env->regs[3], &sc->regs.r3);
2956 __get_user(env->regs[4], &sc->regs.r4);
2957 __get_user(env->regs[5], &sc->regs.r5);
2958 __get_user(env->regs[6], &sc->regs.r6);
2959 __get_user(env->regs[7], &sc->regs.r7);
2960 __get_user(env->regs[8], &sc->regs.r8);
2961 __get_user(env->regs[9], &sc->regs.r9);
2962 __get_user(env->regs[10], &sc->regs.r10);
2963 __get_user(env->regs[11], &sc->regs.r11);
2964 __get_user(env->regs[12], &sc->regs.r12);
2965 __get_user(env->regs[13], &sc->regs.r13);
2966 __get_user(env->regs[14], &sc->usp);
2967 __get_user(env->regs[15], &sc->regs.acr);
2968 __get_user(env->pregs[PR_MOF], &sc->regs.mof);
2969 __get_user(env->pregs[PR_SRP], &sc->regs.srp);
2970 __get_user(env->pc, &sc->regs.erp);
2971 }
2972
2973 static abi_ulong get_sigframe(CPUState *env, int framesize)
2974 {
2975 abi_ulong sp;
2976 /* Align the stack downwards to 4. */
2977 sp = (env->regs[R_SP] & ~3);
2978 return sp - framesize;
2979 }
2980
2981 static void setup_frame(int sig, struct target_sigaction *ka,
2982 target_sigset_t *set, CPUState *env)
2983 {
2984 struct target_signal_frame *frame;
2985 abi_ulong frame_addr;
2986 int err = 0;
2987 int i;
2988
2989 frame_addr = get_sigframe(env, sizeof *frame);
2990 if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
2991 goto badframe;
2992
2993 /*
2994 * The CRIS signal return trampoline. A real linux/CRIS kernel doesn't
2995 * use this trampoline anymore but it sets it up for GDB.
2996 * In QEMU, using the trampoline simplifies things a bit so we use it.
2997 *
2998 * This is movu.w __NR_sigreturn, r9; break 13;
2999 */
3000 err |= __put_user(0x9c5f, frame->retcode+0);
3001 err |= __put_user(TARGET_NR_sigreturn,
3002 frame->retcode+2);
3003 err |= __put_user(0xe93d, frame->retcode+4);
3004
3005 /* Save the mask. */
3006 err |= __put_user(set->sig[0], &frame->sc.oldmask);
3007 if (err)
3008 goto badframe;
3009
3010 for(i = 1; i < TARGET_NSIG_WORDS; i++) {
3011 if (__put_user(set->sig[i], &frame->extramask[i - 1]))
3012 goto badframe;
3013 }
3014
3015 setup_sigcontext(&frame->sc, env);
3016
3017 /* Move the stack and setup the arguments for the handler. */
3018 env->regs[R_SP] = (uint32_t) (unsigned long) frame;
3019 env->regs[10] = sig;
3020 env->pc = (unsigned long) ka->_sa_handler;
3021 /* Link SRP so the guest returns through the trampoline. */
3022 env->pregs[PR_SRP] = (uint32_t) (unsigned long) &frame->retcode[0];
3023
3024 unlock_user_struct(frame, frame_addr, 1);
3025 return;
3026 badframe:
3027 unlock_user_struct(frame, frame_addr, 1);
3028 force_sig(TARGET_SIGSEGV);
3029 }
3030
3031 static void setup_rt_frame(int sig, struct target_sigaction *ka,
3032 target_siginfo_t *info,
3033 target_sigset_t *set, CPUState *env)
3034 {
3035 fprintf(stderr, "CRIS setup_rt_frame: not implemented\n");
3036 }
3037
3038 long do_sigreturn(CPUState *env)
3039 {
3040 struct target_signal_frame *frame;
3041 abi_ulong frame_addr;
3042 target_sigset_t target_set;
3043 sigset_t set;
3044 int i;
3045
3046 frame_addr = env->regs[R_SP];
3047 /* Make sure the guest isn't playing games. */
3048 if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 1))
3049 goto badframe;
3050
3051 /* Restore blocked signals */
3052 if (__get_user(target_set.sig[0], &frame->sc.oldmask))
3053 goto badframe;
3054 for(i = 1; i < TARGET_NSIG_WORDS; i++) {
3055 if (__get_user(target_set.sig[i], &frame->extramask[i - 1]))
3056 goto badframe;
3057 }
3058 target_to_host_sigset_internal(&set, &target_set);
3059 sigprocmask(SIG_SETMASK, &set, NULL);
3060
3061 restore_sigcontext(&frame->sc, env);
3062 unlock_user_struct(frame, frame_addr, 0);
3063 return env->regs[10];
3064 badframe:
3065 unlock_user_struct(frame, frame_addr, 0);
3066 force_sig(TARGET_SIGSEGV);
3067 }
3068
3069 long do_rt_sigreturn(CPUState *env)
3070 {
3071 fprintf(stderr, "CRIS do_rt_sigreturn: not implemented\n");
3072 return -TARGET_ENOSYS;
3073 }
3074
3075 #else
3076
3077 static void setup_frame(int sig, struct target_sigaction *ka,
3078 target_sigset_t *set, CPUState *env)
3079 {
3080 fprintf(stderr, "setup_frame: not implemented\n");
3081 }
3082
3083 static void setup_rt_frame(int sig, struct target_sigaction *ka,
3084 target_siginfo_t *info,
3085 target_sigset_t *set, CPUState *env)
3086 {
3087 fprintf(stderr, "setup_rt_frame: not implemented\n");
3088 }
3089
3090 long do_sigreturn(CPUState *env)
3091 {
3092 fprintf(stderr, "do_sigreturn: not implemented\n");
3093 return -TARGET_ENOSYS;
3094 }
3095
3096 long do_rt_sigreturn(CPUState *env)
3097 {
3098 fprintf(stderr, "do_rt_sigreturn: not implemented\n");
3099 return -TARGET_ENOSYS;
3100 }
3101
3102 #endif
3103
3104 void process_pending_signals(CPUState *cpu_env)
3105 {
3106 int sig;
3107 abi_ulong handler;
3108 sigset_t set, old_set;
3109 target_sigset_t target_old_set;
3110 struct emulated_sigtable *k;
3111 struct target_sigaction *sa;
3112 struct sigqueue *q;
3113 TaskState *ts = cpu_env->opaque;
3114
3115 if (!ts->signal_pending)
3116 return;
3117
3118 /* FIXME: This is not threadsafe. */
3119 k = ts->sigtab;
3120 for(sig = 1; sig <= TARGET_NSIG; sig++) {
3121 if (k->pending)
3122 goto handle_signal;
3123 k++;
3124 }
3125 /* if no signal is pending, just return */
3126 ts->signal_pending = 0;
3127 return;
3128
3129 handle_signal:
3130 #ifdef DEBUG_SIGNAL
3131 fprintf(stderr, "qemu: process signal %d\n", sig);
3132 #endif
3133 /* dequeue signal */
3134 q = k->first;
3135 k->first = q->next;
3136 if (!k->first)
3137 k->pending = 0;
3138
3139 sig = gdb_handlesig (cpu_env, sig);
3140 if (!sig) {
3141 sa = NULL;
3142 handler = TARGET_SIG_IGN;
3143 } else {
3144 sa = &sigact_table[sig - 1];
3145 handler = sa->_sa_handler;
3146 }
3147
3148 if (handler == TARGET_SIG_DFL) {
3149 /* default handler : ignore some signal. The other are job control or fatal */
3150 if (sig == TARGET_SIGTSTP || sig == TARGET_SIGTTIN || sig == TARGET_SIGTTOU) {
3151 kill(getpid(),SIGSTOP);
3152 } else if (sig != TARGET_SIGCHLD &&
3153 sig != TARGET_SIGURG &&
3154 sig != TARGET_SIGWINCH &&
3155 sig != TARGET_SIGCONT) {
3156 force_sig(sig);
3157 }
3158 } else if (handler == TARGET_SIG_IGN) {
3159 /* ignore sig */
3160 } else if (handler == TARGET_SIG_ERR) {
3161 force_sig(sig);
3162 } else {
3163 /* compute the blocked signals during the handler execution */
3164 target_to_host_sigset(&set, &sa->sa_mask);
3165 /* SA_NODEFER indicates that the current signal should not be
3166 blocked during the handler */
3167 if (!(sa->sa_flags & TARGET_SA_NODEFER))
3168 sigaddset(&set, target_to_host_signal(sig));
3169
3170 /* block signals in the handler using Linux */
3171 sigprocmask(SIG_BLOCK, &set, &old_set);
3172 /* save the previous blocked signal state to restore it at the
3173 end of the signal execution (see do_sigreturn) */
3174 host_to_target_sigset_internal(&target_old_set, &old_set);
3175
3176 /* if the CPU is in VM86 mode, we restore the 32 bit values */
3177 #if defined(TARGET_I386) && !defined(TARGET_X86_64)
3178 {
3179 CPUX86State *env = cpu_env;
3180 if (env->eflags & VM_MASK)
3181 save_v86_state(env);
3182 }
3183 #endif
3184 /* prepare the stack frame of the virtual CPU */
3185 if (sa->sa_flags & TARGET_SA_SIGINFO)
3186 setup_rt_frame(sig, sa, &q->info, &target_old_set, cpu_env);
3187 else
3188 setup_frame(sig, sa, &target_old_set, cpu_env);
3189 if (sa->sa_flags & TARGET_SA_RESETHAND)
3190 sa->_sa_handler = TARGET_SIG_DFL;
3191 }
3192 if (q != &k->info)
3193 free_sigqueue(cpu_env, q);
3194 }