]> git.proxmox.com Git - qemu.git/blob - linux-user/signal.c
Merge branch 'usb.4' of git://anongit.freedesktop.org/spice/qemu
[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, see <http://www.gnu.org/licenses/>.
18 */
19 #include <stdlib.h>
20 #include <stdio.h>
21 #include <string.h>
22 #include <stdarg.h>
23 #include <unistd.h>
24 #include <signal.h>
25 #include <errno.h>
26 #include <assert.h>
27 #include <sys/ucontext.h>
28 #include <sys/resource.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[_NSIG] = {
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[_NSIG];
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 int host_to_target_signal(int sig)
105 {
106 if (sig >= _NSIG)
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 >= _NSIG)
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 /* returns 1 if given signal should dump core if not handled */
290 static int core_dump_signal(int sig)
291 {
292 switch (sig) {
293 case TARGET_SIGABRT:
294 case TARGET_SIGFPE:
295 case TARGET_SIGILL:
296 case TARGET_SIGQUIT:
297 case TARGET_SIGSEGV:
298 case TARGET_SIGTRAP:
299 case TARGET_SIGBUS:
300 return (1);
301 default:
302 return (0);
303 }
304 }
305
306 void signal_init(void)
307 {
308 struct sigaction act;
309 struct sigaction oact;
310 int i, j;
311 int host_sig;
312
313 /* generate signal conversion tables */
314 for(i = 1; i < _NSIG; i++) {
315 if (host_to_target_signal_table[i] == 0)
316 host_to_target_signal_table[i] = i;
317 }
318 for(i = 1; i < _NSIG; i++) {
319 j = host_to_target_signal_table[i];
320 target_to_host_signal_table[j] = i;
321 }
322
323 /* set all host signal handlers. ALL signals are blocked during
324 the handlers to serialize them. */
325 memset(sigact_table, 0, sizeof(sigact_table));
326
327 sigfillset(&act.sa_mask);
328 act.sa_flags = SA_SIGINFO;
329 act.sa_sigaction = host_signal_handler;
330 for(i = 1; i <= TARGET_NSIG; i++) {
331 host_sig = target_to_host_signal(i);
332 sigaction(host_sig, NULL, &oact);
333 if (oact.sa_sigaction == (void *)SIG_IGN) {
334 sigact_table[i - 1]._sa_handler = TARGET_SIG_IGN;
335 } else if (oact.sa_sigaction == (void *)SIG_DFL) {
336 sigact_table[i - 1]._sa_handler = TARGET_SIG_DFL;
337 }
338 /* If there's already a handler installed then something has
339 gone horribly wrong, so don't even try to handle that case. */
340 /* Install some handlers for our own use. We need at least
341 SIGSEGV and SIGBUS, to detect exceptions. We can not just
342 trap all signals because it affects syscall interrupt
343 behavior. But do trap all default-fatal signals. */
344 if (fatal_signal (i))
345 sigaction(host_sig, &act, NULL);
346 }
347 }
348
349 /* signal queue handling */
350
351 static inline struct sigqueue *alloc_sigqueue(CPUState *env)
352 {
353 TaskState *ts = env->opaque;
354 struct sigqueue *q = ts->first_free;
355 if (!q)
356 return NULL;
357 ts->first_free = q->next;
358 return q;
359 }
360
361 static inline void free_sigqueue(CPUState *env, struct sigqueue *q)
362 {
363 TaskState *ts = env->opaque;
364 q->next = ts->first_free;
365 ts->first_free = q;
366 }
367
368 /* abort execution with signal */
369 static void QEMU_NORETURN force_sig(int target_sig)
370 {
371 TaskState *ts = (TaskState *)thread_env->opaque;
372 int host_sig, core_dumped = 0;
373 struct sigaction act;
374 host_sig = target_to_host_signal(target_sig);
375 gdb_signalled(thread_env, target_sig);
376
377 /* dump core if supported by target binary format */
378 if (core_dump_signal(target_sig) && (ts->bprm->core_dump != NULL)) {
379 stop_all_tasks();
380 core_dumped =
381 ((*ts->bprm->core_dump)(target_sig, thread_env) == 0);
382 }
383 if (core_dumped) {
384 /* we already dumped the core of target process, we don't want
385 * a coredump of qemu itself */
386 struct rlimit nodump;
387 getrlimit(RLIMIT_CORE, &nodump);
388 nodump.rlim_cur=0;
389 setrlimit(RLIMIT_CORE, &nodump);
390 (void) fprintf(stderr, "qemu: uncaught target signal %d (%s) - %s\n",
391 target_sig, strsignal(host_sig), "core dumped" );
392 }
393
394 /* The proper exit code for dieing from an uncaught signal is
395 * -<signal>. The kernel doesn't allow exit() or _exit() to pass
396 * a negative value. To get the proper exit code we need to
397 * actually die from an uncaught signal. Here the default signal
398 * handler is installed, we send ourself a signal and we wait for
399 * it to arrive. */
400 sigfillset(&act.sa_mask);
401 act.sa_handler = SIG_DFL;
402 sigaction(host_sig, &act, NULL);
403
404 /* For some reason raise(host_sig) doesn't send the signal when
405 * statically linked on x86-64. */
406 kill(getpid(), host_sig);
407
408 /* Make sure the signal isn't masked (just reuse the mask inside
409 of act) */
410 sigdelset(&act.sa_mask, host_sig);
411 sigsuspend(&act.sa_mask);
412
413 /* unreachable */
414 abort();
415 }
416
417 /* queue a signal so that it will be send to the virtual CPU as soon
418 as possible */
419 int queue_signal(CPUState *env, int sig, target_siginfo_t *info)
420 {
421 TaskState *ts = env->opaque;
422 struct emulated_sigtable *k;
423 struct sigqueue *q, **pq;
424 abi_ulong handler;
425 int queue;
426
427 #if defined(DEBUG_SIGNAL)
428 fprintf(stderr, "queue_signal: sig=%d\n",
429 sig);
430 #endif
431 k = &ts->sigtab[sig - 1];
432 queue = gdb_queuesig ();
433 handler = sigact_table[sig - 1]._sa_handler;
434 if (!queue && handler == TARGET_SIG_DFL) {
435 if (sig == TARGET_SIGTSTP || sig == TARGET_SIGTTIN || sig == TARGET_SIGTTOU) {
436 kill(getpid(),SIGSTOP);
437 return 0;
438 } else
439 /* default handler : ignore some signal. The other are fatal */
440 if (sig != TARGET_SIGCHLD &&
441 sig != TARGET_SIGURG &&
442 sig != TARGET_SIGWINCH &&
443 sig != TARGET_SIGCONT) {
444 force_sig(sig);
445 } else {
446 return 0; /* indicate ignored */
447 }
448 } else if (!queue && handler == TARGET_SIG_IGN) {
449 /* ignore signal */
450 return 0;
451 } else if (!queue && handler == TARGET_SIG_ERR) {
452 force_sig(sig);
453 } else {
454 pq = &k->first;
455 if (sig < TARGET_SIGRTMIN) {
456 /* if non real time signal, we queue exactly one signal */
457 if (!k->pending)
458 q = &k->info;
459 else
460 return 0;
461 } else {
462 if (!k->pending) {
463 /* first signal */
464 q = &k->info;
465 } else {
466 q = alloc_sigqueue(env);
467 if (!q)
468 return -EAGAIN;
469 while (*pq != NULL)
470 pq = &(*pq)->next;
471 }
472 }
473 *pq = q;
474 q->info = *info;
475 q->next = NULL;
476 k->pending = 1;
477 /* signal that a new signal is pending */
478 ts->signal_pending = 1;
479 return 1; /* indicates that the signal was queued */
480 }
481 }
482
483 static void host_signal_handler(int host_signum, siginfo_t *info,
484 void *puc)
485 {
486 int sig;
487 target_siginfo_t tinfo;
488
489 /* the CPU emulator uses some host signals to detect exceptions,
490 we forward to it some signals */
491 if ((host_signum == SIGSEGV || host_signum == SIGBUS)
492 && info->si_code > 0) {
493 if (cpu_signal_handler(host_signum, info, puc))
494 return;
495 }
496
497 /* get target signal number */
498 sig = host_to_target_signal(host_signum);
499 if (sig < 1 || sig > TARGET_NSIG)
500 return;
501 #if defined(DEBUG_SIGNAL)
502 fprintf(stderr, "qemu: got signal %d\n", sig);
503 #endif
504 host_to_target_siginfo_noswap(&tinfo, info);
505 if (queue_signal(thread_env, sig, &tinfo) == 1) {
506 /* interrupt the virtual CPU as soon as possible */
507 cpu_exit(thread_env);
508 }
509 }
510
511 /* do_sigaltstack() returns target values and errnos. */
512 /* compare linux/kernel/signal.c:do_sigaltstack() */
513 abi_long do_sigaltstack(abi_ulong uss_addr, abi_ulong uoss_addr, abi_ulong sp)
514 {
515 int ret;
516 struct target_sigaltstack oss;
517
518 /* XXX: test errors */
519 if(uoss_addr)
520 {
521 __put_user(target_sigaltstack_used.ss_sp, &oss.ss_sp);
522 __put_user(target_sigaltstack_used.ss_size, &oss.ss_size);
523 __put_user(sas_ss_flags(sp), &oss.ss_flags);
524 }
525
526 if(uss_addr)
527 {
528 struct target_sigaltstack *uss;
529 struct target_sigaltstack ss;
530
531 ret = -TARGET_EFAULT;
532 if (!lock_user_struct(VERIFY_READ, uss, uss_addr, 1)
533 || __get_user(ss.ss_sp, &uss->ss_sp)
534 || __get_user(ss.ss_size, &uss->ss_size)
535 || __get_user(ss.ss_flags, &uss->ss_flags))
536 goto out;
537 unlock_user_struct(uss, uss_addr, 0);
538
539 ret = -TARGET_EPERM;
540 if (on_sig_stack(sp))
541 goto out;
542
543 ret = -TARGET_EINVAL;
544 if (ss.ss_flags != TARGET_SS_DISABLE
545 && ss.ss_flags != TARGET_SS_ONSTACK
546 && ss.ss_flags != 0)
547 goto out;
548
549 if (ss.ss_flags == TARGET_SS_DISABLE) {
550 ss.ss_size = 0;
551 ss.ss_sp = 0;
552 } else {
553 ret = -TARGET_ENOMEM;
554 if (ss.ss_size < MINSIGSTKSZ)
555 goto out;
556 }
557
558 target_sigaltstack_used.ss_sp = ss.ss_sp;
559 target_sigaltstack_used.ss_size = ss.ss_size;
560 }
561
562 if (uoss_addr) {
563 ret = -TARGET_EFAULT;
564 if (copy_to_user(uoss_addr, &oss, sizeof(oss)))
565 goto out;
566 }
567
568 ret = 0;
569 out:
570 return ret;
571 }
572
573 /* do_sigaction() return host values and errnos */
574 int do_sigaction(int sig, const struct target_sigaction *act,
575 struct target_sigaction *oact)
576 {
577 struct target_sigaction *k;
578 struct sigaction act1;
579 int host_sig;
580 int ret = 0;
581
582 if (sig < 1 || sig > TARGET_NSIG || sig == TARGET_SIGKILL || sig == TARGET_SIGSTOP)
583 return -EINVAL;
584 k = &sigact_table[sig - 1];
585 #if defined(DEBUG_SIGNAL)
586 fprintf(stderr, "sigaction sig=%d act=0x%p, oact=0x%p\n",
587 sig, act, oact);
588 #endif
589 if (oact) {
590 oact->_sa_handler = tswapl(k->_sa_handler);
591 oact->sa_flags = tswapl(k->sa_flags);
592 #if !defined(TARGET_MIPS)
593 oact->sa_restorer = tswapl(k->sa_restorer);
594 #endif
595 oact->sa_mask = k->sa_mask;
596 }
597 if (act) {
598 /* FIXME: This is not threadsafe. */
599 k->_sa_handler = tswapl(act->_sa_handler);
600 k->sa_flags = tswapl(act->sa_flags);
601 #if !defined(TARGET_MIPS)
602 k->sa_restorer = tswapl(act->sa_restorer);
603 #endif
604 k->sa_mask = act->sa_mask;
605
606 /* we update the host linux signal state */
607 host_sig = target_to_host_signal(sig);
608 if (host_sig != SIGSEGV && host_sig != SIGBUS) {
609 sigfillset(&act1.sa_mask);
610 act1.sa_flags = SA_SIGINFO;
611 if (k->sa_flags & TARGET_SA_RESTART)
612 act1.sa_flags |= SA_RESTART;
613 /* NOTE: it is important to update the host kernel signal
614 ignore state to avoid getting unexpected interrupted
615 syscalls */
616 if (k->_sa_handler == TARGET_SIG_IGN) {
617 act1.sa_sigaction = (void *)SIG_IGN;
618 } else if (k->_sa_handler == TARGET_SIG_DFL) {
619 if (fatal_signal (sig))
620 act1.sa_sigaction = host_signal_handler;
621 else
622 act1.sa_sigaction = (void *)SIG_DFL;
623 } else {
624 act1.sa_sigaction = host_signal_handler;
625 }
626 ret = sigaction(host_sig, &act1, NULL);
627 }
628 }
629 return ret;
630 }
631
632 static inline int copy_siginfo_to_user(target_siginfo_t *tinfo,
633 const target_siginfo_t *info)
634 {
635 tswap_siginfo(tinfo, info);
636 return 0;
637 }
638
639 static inline int current_exec_domain_sig(int sig)
640 {
641 return /* current->exec_domain && current->exec_domain->signal_invmap
642 && sig < 32 ? current->exec_domain->signal_invmap[sig] : */ sig;
643 }
644
645 #if defined(TARGET_I386) && TARGET_ABI_BITS == 32
646
647 /* from the Linux kernel */
648
649 struct target_fpreg {
650 uint16_t significand[4];
651 uint16_t exponent;
652 };
653
654 struct target_fpxreg {
655 uint16_t significand[4];
656 uint16_t exponent;
657 uint16_t padding[3];
658 };
659
660 struct target_xmmreg {
661 abi_ulong element[4];
662 };
663
664 struct target_fpstate {
665 /* Regular FPU environment */
666 abi_ulong cw;
667 abi_ulong sw;
668 abi_ulong tag;
669 abi_ulong ipoff;
670 abi_ulong cssel;
671 abi_ulong dataoff;
672 abi_ulong datasel;
673 struct target_fpreg _st[8];
674 uint16_t status;
675 uint16_t magic; /* 0xffff = regular FPU data only */
676
677 /* FXSR FPU environment */
678 abi_ulong _fxsr_env[6]; /* FXSR FPU env is ignored */
679 abi_ulong mxcsr;
680 abi_ulong reserved;
681 struct target_fpxreg _fxsr_st[8]; /* FXSR FPU reg data is ignored */
682 struct target_xmmreg _xmm[8];
683 abi_ulong padding[56];
684 };
685
686 #define X86_FXSR_MAGIC 0x0000
687
688 struct target_sigcontext {
689 uint16_t gs, __gsh;
690 uint16_t fs, __fsh;
691 uint16_t es, __esh;
692 uint16_t ds, __dsh;
693 abi_ulong edi;
694 abi_ulong esi;
695 abi_ulong ebp;
696 abi_ulong esp;
697 abi_ulong ebx;
698 abi_ulong edx;
699 abi_ulong ecx;
700 abi_ulong eax;
701 abi_ulong trapno;
702 abi_ulong err;
703 abi_ulong eip;
704 uint16_t cs, __csh;
705 abi_ulong eflags;
706 abi_ulong esp_at_signal;
707 uint16_t ss, __ssh;
708 abi_ulong fpstate; /* pointer */
709 abi_ulong oldmask;
710 abi_ulong cr2;
711 };
712
713 struct target_ucontext {
714 abi_ulong tuc_flags;
715 abi_ulong tuc_link;
716 target_stack_t tuc_stack;
717 struct target_sigcontext tuc_mcontext;
718 target_sigset_t tuc_sigmask; /* mask last for extensibility */
719 };
720
721 struct sigframe
722 {
723 abi_ulong pretcode;
724 int sig;
725 struct target_sigcontext sc;
726 struct target_fpstate fpstate;
727 abi_ulong extramask[TARGET_NSIG_WORDS-1];
728 char retcode[8];
729 };
730
731 struct rt_sigframe
732 {
733 abi_ulong pretcode;
734 int sig;
735 abi_ulong pinfo;
736 abi_ulong puc;
737 struct target_siginfo info;
738 struct target_ucontext uc;
739 struct target_fpstate fpstate;
740 char retcode[8];
741 };
742
743 /*
744 * Set up a signal frame.
745 */
746
747 /* XXX: save x87 state */
748 static int
749 setup_sigcontext(struct target_sigcontext *sc, struct target_fpstate *fpstate,
750 CPUX86State *env, abi_ulong mask, abi_ulong fpstate_addr)
751 {
752 int err = 0;
753 uint16_t magic;
754
755 /* already locked in setup_frame() */
756 err |= __put_user(env->segs[R_GS].selector, (unsigned int *)&sc->gs);
757 err |= __put_user(env->segs[R_FS].selector, (unsigned int *)&sc->fs);
758 err |= __put_user(env->segs[R_ES].selector, (unsigned int *)&sc->es);
759 err |= __put_user(env->segs[R_DS].selector, (unsigned int *)&sc->ds);
760 err |= __put_user(env->regs[R_EDI], &sc->edi);
761 err |= __put_user(env->regs[R_ESI], &sc->esi);
762 err |= __put_user(env->regs[R_EBP], &sc->ebp);
763 err |= __put_user(env->regs[R_ESP], &sc->esp);
764 err |= __put_user(env->regs[R_EBX], &sc->ebx);
765 err |= __put_user(env->regs[R_EDX], &sc->edx);
766 err |= __put_user(env->regs[R_ECX], &sc->ecx);
767 err |= __put_user(env->regs[R_EAX], &sc->eax);
768 err |= __put_user(env->exception_index, &sc->trapno);
769 err |= __put_user(env->error_code, &sc->err);
770 err |= __put_user(env->eip, &sc->eip);
771 err |= __put_user(env->segs[R_CS].selector, (unsigned int *)&sc->cs);
772 err |= __put_user(env->eflags, &sc->eflags);
773 err |= __put_user(env->regs[R_ESP], &sc->esp_at_signal);
774 err |= __put_user(env->segs[R_SS].selector, (unsigned int *)&sc->ss);
775
776 cpu_x86_fsave(env, fpstate_addr, 1);
777 fpstate->status = fpstate->sw;
778 magic = 0xffff;
779 err |= __put_user(magic, &fpstate->magic);
780 err |= __put_user(fpstate_addr, &sc->fpstate);
781
782 /* non-iBCS2 extensions.. */
783 err |= __put_user(mask, &sc->oldmask);
784 err |= __put_user(env->cr[2], &sc->cr2);
785 return err;
786 }
787
788 /*
789 * Determine which stack to use..
790 */
791
792 static inline abi_ulong
793 get_sigframe(struct target_sigaction *ka, CPUX86State *env, size_t frame_size)
794 {
795 unsigned long esp;
796
797 /* Default to using normal stack */
798 esp = env->regs[R_ESP];
799 /* This is the X/Open sanctioned signal stack switching. */
800 if (ka->sa_flags & TARGET_SA_ONSTACK) {
801 if (sas_ss_flags(esp) == 0)
802 esp = target_sigaltstack_used.ss_sp + target_sigaltstack_used.ss_size;
803 }
804
805 /* This is the legacy signal stack switching. */
806 else
807 if ((env->segs[R_SS].selector & 0xffff) != __USER_DS &&
808 !(ka->sa_flags & TARGET_SA_RESTORER) &&
809 ka->sa_restorer) {
810 esp = (unsigned long) ka->sa_restorer;
811 }
812 return (esp - frame_size) & -8ul;
813 }
814
815 /* compare linux/arch/i386/kernel/signal.c:setup_frame() */
816 static void setup_frame(int sig, struct target_sigaction *ka,
817 target_sigset_t *set, CPUX86State *env)
818 {
819 abi_ulong frame_addr;
820 struct sigframe *frame;
821 int i, err = 0;
822
823 frame_addr = get_sigframe(ka, env, sizeof(*frame));
824
825 if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
826 goto give_sigsegv;
827
828 err |= __put_user(current_exec_domain_sig(sig),
829 &frame->sig);
830 if (err)
831 goto give_sigsegv;
832
833 setup_sigcontext(&frame->sc, &frame->fpstate, env, set->sig[0],
834 frame_addr + offsetof(struct sigframe, fpstate));
835 if (err)
836 goto give_sigsegv;
837
838 for(i = 1; i < TARGET_NSIG_WORDS; i++) {
839 if (__put_user(set->sig[i], &frame->extramask[i - 1]))
840 goto give_sigsegv;
841 }
842
843 /* Set up to return from userspace. If provided, use a stub
844 already in userspace. */
845 if (ka->sa_flags & TARGET_SA_RESTORER) {
846 err |= __put_user(ka->sa_restorer, &frame->pretcode);
847 } else {
848 uint16_t val16;
849 abi_ulong retcode_addr;
850 retcode_addr = frame_addr + offsetof(struct sigframe, retcode);
851 err |= __put_user(retcode_addr, &frame->pretcode);
852 /* This is popl %eax ; movl $,%eax ; int $0x80 */
853 val16 = 0xb858;
854 err |= __put_user(val16, (uint16_t *)(frame->retcode+0));
855 err |= __put_user(TARGET_NR_sigreturn, (int *)(frame->retcode+2));
856 val16 = 0x80cd;
857 err |= __put_user(val16, (uint16_t *)(frame->retcode+6));
858 }
859
860 if (err)
861 goto give_sigsegv;
862
863 /* Set up registers for signal handler */
864 env->regs[R_ESP] = frame_addr;
865 env->eip = ka->_sa_handler;
866
867 cpu_x86_load_seg(env, R_DS, __USER_DS);
868 cpu_x86_load_seg(env, R_ES, __USER_DS);
869 cpu_x86_load_seg(env, R_SS, __USER_DS);
870 cpu_x86_load_seg(env, R_CS, __USER_CS);
871 env->eflags &= ~TF_MASK;
872
873 unlock_user_struct(frame, frame_addr, 1);
874
875 return;
876
877 give_sigsegv:
878 unlock_user_struct(frame, frame_addr, 1);
879 if (sig == TARGET_SIGSEGV)
880 ka->_sa_handler = TARGET_SIG_DFL;
881 force_sig(TARGET_SIGSEGV /* , current */);
882 }
883
884 /* compare linux/arch/i386/kernel/signal.c:setup_rt_frame() */
885 static void setup_rt_frame(int sig, struct target_sigaction *ka,
886 target_siginfo_t *info,
887 target_sigset_t *set, CPUX86State *env)
888 {
889 abi_ulong frame_addr, addr;
890 struct rt_sigframe *frame;
891 int i, err = 0;
892
893 frame_addr = get_sigframe(ka, env, sizeof(*frame));
894
895 if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
896 goto give_sigsegv;
897
898 err |= __put_user(current_exec_domain_sig(sig),
899 &frame->sig);
900 addr = frame_addr + offsetof(struct rt_sigframe, info);
901 err |= __put_user(addr, &frame->pinfo);
902 addr = frame_addr + offsetof(struct rt_sigframe, uc);
903 err |= __put_user(addr, &frame->puc);
904 err |= copy_siginfo_to_user(&frame->info, info);
905 if (err)
906 goto give_sigsegv;
907
908 /* Create the ucontext. */
909 err |= __put_user(0, &frame->uc.tuc_flags);
910 err |= __put_user(0, &frame->uc.tuc_link);
911 err |= __put_user(target_sigaltstack_used.ss_sp,
912 &frame->uc.tuc_stack.ss_sp);
913 err |= __put_user(sas_ss_flags(get_sp_from_cpustate(env)),
914 &frame->uc.tuc_stack.ss_flags);
915 err |= __put_user(target_sigaltstack_used.ss_size,
916 &frame->uc.tuc_stack.ss_size);
917 err |= setup_sigcontext(&frame->uc.tuc_mcontext, &frame->fpstate,
918 env, set->sig[0],
919 frame_addr + offsetof(struct rt_sigframe, fpstate));
920 for(i = 0; i < TARGET_NSIG_WORDS; i++) {
921 if (__put_user(set->sig[i], &frame->uc.tuc_sigmask.sig[i]))
922 goto give_sigsegv;
923 }
924
925 /* Set up to return from userspace. If provided, use a stub
926 already in userspace. */
927 if (ka->sa_flags & TARGET_SA_RESTORER) {
928 err |= __put_user(ka->sa_restorer, &frame->pretcode);
929 } else {
930 uint16_t val16;
931 addr = frame_addr + offsetof(struct rt_sigframe, retcode);
932 err |= __put_user(addr, &frame->pretcode);
933 /* This is movl $,%eax ; int $0x80 */
934 err |= __put_user(0xb8, (char *)(frame->retcode+0));
935 err |= __put_user(TARGET_NR_rt_sigreturn, (int *)(frame->retcode+1));
936 val16 = 0x80cd;
937 err |= __put_user(val16, (uint16_t *)(frame->retcode+5));
938 }
939
940 if (err)
941 goto give_sigsegv;
942
943 /* Set up registers for signal handler */
944 env->regs[R_ESP] = frame_addr;
945 env->eip = ka->_sa_handler;
946
947 cpu_x86_load_seg(env, R_DS, __USER_DS);
948 cpu_x86_load_seg(env, R_ES, __USER_DS);
949 cpu_x86_load_seg(env, R_SS, __USER_DS);
950 cpu_x86_load_seg(env, R_CS, __USER_CS);
951 env->eflags &= ~TF_MASK;
952
953 unlock_user_struct(frame, frame_addr, 1);
954
955 return;
956
957 give_sigsegv:
958 unlock_user_struct(frame, frame_addr, 1);
959 if (sig == TARGET_SIGSEGV)
960 ka->_sa_handler = TARGET_SIG_DFL;
961 force_sig(TARGET_SIGSEGV /* , current */);
962 }
963
964 static int
965 restore_sigcontext(CPUX86State *env, struct target_sigcontext *sc, int *peax)
966 {
967 unsigned int err = 0;
968 abi_ulong fpstate_addr;
969 unsigned int tmpflags;
970
971 cpu_x86_load_seg(env, R_GS, tswap16(sc->gs));
972 cpu_x86_load_seg(env, R_FS, tswap16(sc->fs));
973 cpu_x86_load_seg(env, R_ES, tswap16(sc->es));
974 cpu_x86_load_seg(env, R_DS, tswap16(sc->ds));
975
976 env->regs[R_EDI] = tswapl(sc->edi);
977 env->regs[R_ESI] = tswapl(sc->esi);
978 env->regs[R_EBP] = tswapl(sc->ebp);
979 env->regs[R_ESP] = tswapl(sc->esp);
980 env->regs[R_EBX] = tswapl(sc->ebx);
981 env->regs[R_EDX] = tswapl(sc->edx);
982 env->regs[R_ECX] = tswapl(sc->ecx);
983 env->eip = tswapl(sc->eip);
984
985 cpu_x86_load_seg(env, R_CS, lduw(&sc->cs) | 3);
986 cpu_x86_load_seg(env, R_SS, lduw(&sc->ss) | 3);
987
988 tmpflags = tswapl(sc->eflags);
989 env->eflags = (env->eflags & ~0x40DD5) | (tmpflags & 0x40DD5);
990 // regs->orig_eax = -1; /* disable syscall checks */
991
992 fpstate_addr = tswapl(sc->fpstate);
993 if (fpstate_addr != 0) {
994 if (!access_ok(VERIFY_READ, fpstate_addr,
995 sizeof(struct target_fpstate)))
996 goto badframe;
997 cpu_x86_frstor(env, fpstate_addr, 1);
998 }
999
1000 *peax = tswapl(sc->eax);
1001 return err;
1002 badframe:
1003 return 1;
1004 }
1005
1006 long do_sigreturn(CPUX86State *env)
1007 {
1008 struct sigframe *frame;
1009 abi_ulong frame_addr = env->regs[R_ESP] - 8;
1010 target_sigset_t target_set;
1011 sigset_t set;
1012 int eax, i;
1013
1014 #if defined(DEBUG_SIGNAL)
1015 fprintf(stderr, "do_sigreturn\n");
1016 #endif
1017 if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1))
1018 goto badframe;
1019 /* set blocked signals */
1020 if (__get_user(target_set.sig[0], &frame->sc.oldmask))
1021 goto badframe;
1022 for(i = 1; i < TARGET_NSIG_WORDS; i++) {
1023 if (__get_user(target_set.sig[i], &frame->extramask[i - 1]))
1024 goto badframe;
1025 }
1026
1027 target_to_host_sigset_internal(&set, &target_set);
1028 sigprocmask(SIG_SETMASK, &set, NULL);
1029
1030 /* restore registers */
1031 if (restore_sigcontext(env, &frame->sc, &eax))
1032 goto badframe;
1033 unlock_user_struct(frame, frame_addr, 0);
1034 return eax;
1035
1036 badframe:
1037 unlock_user_struct(frame, frame_addr, 0);
1038 force_sig(TARGET_SIGSEGV);
1039 return 0;
1040 }
1041
1042 long do_rt_sigreturn(CPUX86State *env)
1043 {
1044 abi_ulong frame_addr;
1045 struct rt_sigframe *frame;
1046 sigset_t set;
1047 int eax;
1048
1049 frame_addr = env->regs[R_ESP] - 4;
1050 if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1))
1051 goto badframe;
1052 target_to_host_sigset(&set, &frame->uc.tuc_sigmask);
1053 sigprocmask(SIG_SETMASK, &set, NULL);
1054
1055 if (restore_sigcontext(env, &frame->uc.tuc_mcontext, &eax))
1056 goto badframe;
1057
1058 if (do_sigaltstack(frame_addr + offsetof(struct rt_sigframe, uc.tuc_stack), 0,
1059 get_sp_from_cpustate(env)) == -EFAULT)
1060 goto badframe;
1061
1062 unlock_user_struct(frame, frame_addr, 0);
1063 return eax;
1064
1065 badframe:
1066 unlock_user_struct(frame, frame_addr, 0);
1067 force_sig(TARGET_SIGSEGV);
1068 return 0;
1069 }
1070
1071 #elif defined(TARGET_ARM)
1072
1073 struct target_sigcontext {
1074 abi_ulong trap_no;
1075 abi_ulong error_code;
1076 abi_ulong oldmask;
1077 abi_ulong arm_r0;
1078 abi_ulong arm_r1;
1079 abi_ulong arm_r2;
1080 abi_ulong arm_r3;
1081 abi_ulong arm_r4;
1082 abi_ulong arm_r5;
1083 abi_ulong arm_r6;
1084 abi_ulong arm_r7;
1085 abi_ulong arm_r8;
1086 abi_ulong arm_r9;
1087 abi_ulong arm_r10;
1088 abi_ulong arm_fp;
1089 abi_ulong arm_ip;
1090 abi_ulong arm_sp;
1091 abi_ulong arm_lr;
1092 abi_ulong arm_pc;
1093 abi_ulong arm_cpsr;
1094 abi_ulong fault_address;
1095 };
1096
1097 struct target_ucontext_v1 {
1098 abi_ulong tuc_flags;
1099 abi_ulong tuc_link;
1100 target_stack_t tuc_stack;
1101 struct target_sigcontext tuc_mcontext;
1102 target_sigset_t tuc_sigmask; /* mask last for extensibility */
1103 };
1104
1105 struct target_ucontext_v2 {
1106 abi_ulong tuc_flags;
1107 abi_ulong tuc_link;
1108 target_stack_t tuc_stack;
1109 struct target_sigcontext tuc_mcontext;
1110 target_sigset_t tuc_sigmask; /* mask last for extensibility */
1111 char __unused[128 - sizeof(target_sigset_t)];
1112 abi_ulong tuc_regspace[128] __attribute__((__aligned__(8)));
1113 };
1114
1115 struct target_user_vfp {
1116 uint64_t fpregs[32];
1117 abi_ulong fpscr;
1118 };
1119
1120 struct target_user_vfp_exc {
1121 abi_ulong fpexc;
1122 abi_ulong fpinst;
1123 abi_ulong fpinst2;
1124 };
1125
1126 struct target_vfp_sigframe {
1127 abi_ulong magic;
1128 abi_ulong size;
1129 struct target_user_vfp ufp;
1130 struct target_user_vfp_exc ufp_exc;
1131 } __attribute__((__aligned__(8)));
1132
1133 struct target_iwmmxt_sigframe {
1134 abi_ulong magic;
1135 abi_ulong size;
1136 uint64_t regs[16];
1137 /* Note that not all the coprocessor control registers are stored here */
1138 uint32_t wcssf;
1139 uint32_t wcasf;
1140 uint32_t wcgr0;
1141 uint32_t wcgr1;
1142 uint32_t wcgr2;
1143 uint32_t wcgr3;
1144 } __attribute__((__aligned__(8)));
1145
1146 #define TARGET_VFP_MAGIC 0x56465001
1147 #define TARGET_IWMMXT_MAGIC 0x12ef842a
1148
1149 struct sigframe_v1
1150 {
1151 struct target_sigcontext sc;
1152 abi_ulong extramask[TARGET_NSIG_WORDS-1];
1153 abi_ulong retcode;
1154 };
1155
1156 struct sigframe_v2
1157 {
1158 struct target_ucontext_v2 uc;
1159 abi_ulong retcode;
1160 };
1161
1162 struct rt_sigframe_v1
1163 {
1164 abi_ulong pinfo;
1165 abi_ulong puc;
1166 struct target_siginfo info;
1167 struct target_ucontext_v1 uc;
1168 abi_ulong retcode;
1169 };
1170
1171 struct rt_sigframe_v2
1172 {
1173 struct target_siginfo info;
1174 struct target_ucontext_v2 uc;
1175 abi_ulong retcode;
1176 };
1177
1178 #define TARGET_CONFIG_CPU_32 1
1179
1180 /*
1181 * For ARM syscalls, we encode the syscall number into the instruction.
1182 */
1183 #define SWI_SYS_SIGRETURN (0xef000000|(TARGET_NR_sigreturn + ARM_SYSCALL_BASE))
1184 #define SWI_SYS_RT_SIGRETURN (0xef000000|(TARGET_NR_rt_sigreturn + ARM_SYSCALL_BASE))
1185
1186 /*
1187 * For Thumb syscalls, we pass the syscall number via r7. We therefore
1188 * need two 16-bit instructions.
1189 */
1190 #define SWI_THUMB_SIGRETURN (0xdf00 << 16 | 0x2700 | (TARGET_NR_sigreturn))
1191 #define SWI_THUMB_RT_SIGRETURN (0xdf00 << 16 | 0x2700 | (TARGET_NR_rt_sigreturn))
1192
1193 static const abi_ulong retcodes[4] = {
1194 SWI_SYS_SIGRETURN, SWI_THUMB_SIGRETURN,
1195 SWI_SYS_RT_SIGRETURN, SWI_THUMB_RT_SIGRETURN
1196 };
1197
1198
1199 #define __get_user_error(x,p,e) __get_user(x, p)
1200
1201 static inline int valid_user_regs(CPUState *regs)
1202 {
1203 return 1;
1204 }
1205
1206 static void
1207 setup_sigcontext(struct target_sigcontext *sc, /*struct _fpstate *fpstate,*/
1208 CPUState *env, abi_ulong mask)
1209 {
1210 __put_user(env->regs[0], &sc->arm_r0);
1211 __put_user(env->regs[1], &sc->arm_r1);
1212 __put_user(env->regs[2], &sc->arm_r2);
1213 __put_user(env->regs[3], &sc->arm_r3);
1214 __put_user(env->regs[4], &sc->arm_r4);
1215 __put_user(env->regs[5], &sc->arm_r5);
1216 __put_user(env->regs[6], &sc->arm_r6);
1217 __put_user(env->regs[7], &sc->arm_r7);
1218 __put_user(env->regs[8], &sc->arm_r8);
1219 __put_user(env->regs[9], &sc->arm_r9);
1220 __put_user(env->regs[10], &sc->arm_r10);
1221 __put_user(env->regs[11], &sc->arm_fp);
1222 __put_user(env->regs[12], &sc->arm_ip);
1223 __put_user(env->regs[13], &sc->arm_sp);
1224 __put_user(env->regs[14], &sc->arm_lr);
1225 __put_user(env->regs[15], &sc->arm_pc);
1226 #ifdef TARGET_CONFIG_CPU_32
1227 __put_user(cpsr_read(env), &sc->arm_cpsr);
1228 #endif
1229
1230 __put_user(/* current->thread.trap_no */ 0, &sc->trap_no);
1231 __put_user(/* current->thread.error_code */ 0, &sc->error_code);
1232 __put_user(/* current->thread.address */ 0, &sc->fault_address);
1233 __put_user(mask, &sc->oldmask);
1234 }
1235
1236 static inline abi_ulong
1237 get_sigframe(struct target_sigaction *ka, CPUState *regs, int framesize)
1238 {
1239 unsigned long sp = regs->regs[13];
1240
1241 /*
1242 * This is the X/Open sanctioned signal stack switching.
1243 */
1244 if ((ka->sa_flags & TARGET_SA_ONSTACK) && !sas_ss_flags(sp))
1245 sp = target_sigaltstack_used.ss_sp + target_sigaltstack_used.ss_size;
1246 /*
1247 * ATPCS B01 mandates 8-byte alignment
1248 */
1249 return (sp - framesize) & ~7;
1250 }
1251
1252 static int
1253 setup_return(CPUState *env, struct target_sigaction *ka,
1254 abi_ulong *rc, abi_ulong frame_addr, int usig, abi_ulong rc_addr)
1255 {
1256 abi_ulong handler = ka->_sa_handler;
1257 abi_ulong retcode;
1258 int thumb = handler & 1;
1259 uint32_t cpsr = cpsr_read(env);
1260
1261 cpsr &= ~CPSR_IT;
1262 if (thumb) {
1263 cpsr |= CPSR_T;
1264 } else {
1265 cpsr &= ~CPSR_T;
1266 }
1267
1268 if (ka->sa_flags & TARGET_SA_RESTORER) {
1269 retcode = ka->sa_restorer;
1270 } else {
1271 unsigned int idx = thumb;
1272
1273 if (ka->sa_flags & TARGET_SA_SIGINFO)
1274 idx += 2;
1275
1276 if (__put_user(retcodes[idx], rc))
1277 return 1;
1278 #if 0
1279 flush_icache_range((abi_ulong)rc,
1280 (abi_ulong)(rc + 1));
1281 #endif
1282 retcode = rc_addr + thumb;
1283 }
1284
1285 env->regs[0] = usig;
1286 env->regs[13] = frame_addr;
1287 env->regs[14] = retcode;
1288 env->regs[15] = handler & (thumb ? ~1 : ~3);
1289 cpsr_write(env, cpsr, 0xffffffff);
1290
1291 return 0;
1292 }
1293
1294 static abi_ulong *setup_sigframe_v2_vfp(abi_ulong *regspace, CPUState *env)
1295 {
1296 int i;
1297 struct target_vfp_sigframe *vfpframe;
1298 vfpframe = (struct target_vfp_sigframe *)regspace;
1299 __put_user(TARGET_VFP_MAGIC, &vfpframe->magic);
1300 __put_user(sizeof(*vfpframe), &vfpframe->size);
1301 for (i = 0; i < 32; i++) {
1302 __put_user(env->vfp.regs[i], &vfpframe->ufp.fpregs[i]);
1303 }
1304 __put_user(vfp_get_fpscr(env), &vfpframe->ufp.fpscr);
1305 __put_user(env->vfp.xregs[ARM_VFP_FPEXC], &vfpframe->ufp_exc.fpexc);
1306 __put_user(env->vfp.xregs[ARM_VFP_FPINST], &vfpframe->ufp_exc.fpinst);
1307 __put_user(env->vfp.xregs[ARM_VFP_FPINST2], &vfpframe->ufp_exc.fpinst2);
1308 return (abi_ulong*)(vfpframe+1);
1309 }
1310
1311 static abi_ulong *setup_sigframe_v2_iwmmxt(abi_ulong *regspace, CPUState *env)
1312 {
1313 int i;
1314 struct target_iwmmxt_sigframe *iwmmxtframe;
1315 iwmmxtframe = (struct target_iwmmxt_sigframe *)regspace;
1316 __put_user(TARGET_IWMMXT_MAGIC, &iwmmxtframe->magic);
1317 __put_user(sizeof(*iwmmxtframe), &iwmmxtframe->size);
1318 for (i = 0; i < 16; i++) {
1319 __put_user(env->iwmmxt.regs[i], &iwmmxtframe->regs[i]);
1320 }
1321 __put_user(env->vfp.xregs[ARM_IWMMXT_wCSSF], &iwmmxtframe->wcssf);
1322 __put_user(env->vfp.xregs[ARM_IWMMXT_wCASF], &iwmmxtframe->wcssf);
1323 __put_user(env->vfp.xregs[ARM_IWMMXT_wCGR0], &iwmmxtframe->wcgr0);
1324 __put_user(env->vfp.xregs[ARM_IWMMXT_wCGR1], &iwmmxtframe->wcgr1);
1325 __put_user(env->vfp.xregs[ARM_IWMMXT_wCGR2], &iwmmxtframe->wcgr2);
1326 __put_user(env->vfp.xregs[ARM_IWMMXT_wCGR3], &iwmmxtframe->wcgr3);
1327 return (abi_ulong*)(iwmmxtframe+1);
1328 }
1329
1330 static void setup_sigframe_v2(struct target_ucontext_v2 *uc,
1331 target_sigset_t *set, CPUState *env)
1332 {
1333 struct target_sigaltstack stack;
1334 int i;
1335 abi_ulong *regspace;
1336
1337 /* Clear all the bits of the ucontext we don't use. */
1338 memset(uc, 0, offsetof(struct target_ucontext_v2, tuc_mcontext));
1339
1340 memset(&stack, 0, sizeof(stack));
1341 __put_user(target_sigaltstack_used.ss_sp, &stack.ss_sp);
1342 __put_user(target_sigaltstack_used.ss_size, &stack.ss_size);
1343 __put_user(sas_ss_flags(get_sp_from_cpustate(env)), &stack.ss_flags);
1344 memcpy(&uc->tuc_stack, &stack, sizeof(stack));
1345
1346 setup_sigcontext(&uc->tuc_mcontext, env, set->sig[0]);
1347 /* Save coprocessor signal frame. */
1348 regspace = uc->tuc_regspace;
1349 if (arm_feature(env, ARM_FEATURE_VFP)) {
1350 regspace = setup_sigframe_v2_vfp(regspace, env);
1351 }
1352 if (arm_feature(env, ARM_FEATURE_IWMMXT)) {
1353 regspace = setup_sigframe_v2_iwmmxt(regspace, env);
1354 }
1355
1356 /* Write terminating magic word */
1357 __put_user(0, regspace);
1358
1359 for(i = 0; i < TARGET_NSIG_WORDS; i++) {
1360 __put_user(set->sig[i], &uc->tuc_sigmask.sig[i]);
1361 }
1362 }
1363
1364 /* compare linux/arch/arm/kernel/signal.c:setup_frame() */
1365 static void setup_frame_v1(int usig, struct target_sigaction *ka,
1366 target_sigset_t *set, CPUState *regs)
1367 {
1368 struct sigframe_v1 *frame;
1369 abi_ulong frame_addr = get_sigframe(ka, regs, sizeof(*frame));
1370 int i;
1371
1372 if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
1373 return;
1374
1375 setup_sigcontext(&frame->sc, regs, set->sig[0]);
1376
1377 for(i = 1; i < TARGET_NSIG_WORDS; i++) {
1378 if (__put_user(set->sig[i], &frame->extramask[i - 1]))
1379 goto end;
1380 }
1381
1382 setup_return(regs, ka, &frame->retcode, frame_addr, usig,
1383 frame_addr + offsetof(struct sigframe_v1, retcode));
1384
1385 end:
1386 unlock_user_struct(frame, frame_addr, 1);
1387 }
1388
1389 static void setup_frame_v2(int usig, struct target_sigaction *ka,
1390 target_sigset_t *set, CPUState *regs)
1391 {
1392 struct sigframe_v2 *frame;
1393 abi_ulong frame_addr = get_sigframe(ka, regs, sizeof(*frame));
1394
1395 if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
1396 return;
1397
1398 setup_sigframe_v2(&frame->uc, set, regs);
1399
1400 setup_return(regs, ka, &frame->retcode, frame_addr, usig,
1401 frame_addr + offsetof(struct sigframe_v2, retcode));
1402
1403 unlock_user_struct(frame, frame_addr, 1);
1404 }
1405
1406 static void setup_frame(int usig, struct target_sigaction *ka,
1407 target_sigset_t *set, CPUState *regs)
1408 {
1409 if (get_osversion() >= 0x020612) {
1410 setup_frame_v2(usig, ka, set, regs);
1411 } else {
1412 setup_frame_v1(usig, ka, set, regs);
1413 }
1414 }
1415
1416 /* compare linux/arch/arm/kernel/signal.c:setup_rt_frame() */
1417 static void setup_rt_frame_v1(int usig, struct target_sigaction *ka,
1418 target_siginfo_t *info,
1419 target_sigset_t *set, CPUState *env)
1420 {
1421 struct rt_sigframe_v1 *frame;
1422 abi_ulong frame_addr = get_sigframe(ka, env, sizeof(*frame));
1423 struct target_sigaltstack stack;
1424 int i;
1425 abi_ulong info_addr, uc_addr;
1426
1427 if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
1428 return /* 1 */;
1429
1430 info_addr = frame_addr + offsetof(struct rt_sigframe_v1, info);
1431 __put_user(info_addr, &frame->pinfo);
1432 uc_addr = frame_addr + offsetof(struct rt_sigframe_v1, uc);
1433 __put_user(uc_addr, &frame->puc);
1434 copy_siginfo_to_user(&frame->info, info);
1435
1436 /* Clear all the bits of the ucontext we don't use. */
1437 memset(&frame->uc, 0, offsetof(struct target_ucontext_v1, tuc_mcontext));
1438
1439 memset(&stack, 0, sizeof(stack));
1440 __put_user(target_sigaltstack_used.ss_sp, &stack.ss_sp);
1441 __put_user(target_sigaltstack_used.ss_size, &stack.ss_size);
1442 __put_user(sas_ss_flags(get_sp_from_cpustate(env)), &stack.ss_flags);
1443 memcpy(&frame->uc.tuc_stack, &stack, sizeof(stack));
1444
1445 setup_sigcontext(&frame->uc.tuc_mcontext, env, set->sig[0]);
1446 for(i = 0; i < TARGET_NSIG_WORDS; i++) {
1447 if (__put_user(set->sig[i], &frame->uc.tuc_sigmask.sig[i]))
1448 goto end;
1449 }
1450
1451 setup_return(env, ka, &frame->retcode, frame_addr, usig,
1452 frame_addr + offsetof(struct rt_sigframe_v1, retcode));
1453
1454 env->regs[1] = info_addr;
1455 env->regs[2] = uc_addr;
1456
1457 end:
1458 unlock_user_struct(frame, frame_addr, 1);
1459 }
1460
1461 static void setup_rt_frame_v2(int usig, struct target_sigaction *ka,
1462 target_siginfo_t *info,
1463 target_sigset_t *set, CPUState *env)
1464 {
1465 struct rt_sigframe_v2 *frame;
1466 abi_ulong frame_addr = get_sigframe(ka, env, sizeof(*frame));
1467 abi_ulong info_addr, uc_addr;
1468
1469 if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
1470 return /* 1 */;
1471
1472 info_addr = frame_addr + offsetof(struct rt_sigframe_v2, info);
1473 uc_addr = frame_addr + offsetof(struct rt_sigframe_v2, uc);
1474 copy_siginfo_to_user(&frame->info, info);
1475
1476 setup_sigframe_v2(&frame->uc, set, env);
1477
1478 setup_return(env, ka, &frame->retcode, frame_addr, usig,
1479 frame_addr + offsetof(struct rt_sigframe_v2, retcode));
1480
1481 env->regs[1] = info_addr;
1482 env->regs[2] = uc_addr;
1483
1484 unlock_user_struct(frame, frame_addr, 1);
1485 }
1486
1487 static void setup_rt_frame(int usig, struct target_sigaction *ka,
1488 target_siginfo_t *info,
1489 target_sigset_t *set, CPUState *env)
1490 {
1491 if (get_osversion() >= 0x020612) {
1492 setup_rt_frame_v2(usig, ka, info, set, env);
1493 } else {
1494 setup_rt_frame_v1(usig, ka, info, set, env);
1495 }
1496 }
1497
1498 static int
1499 restore_sigcontext(CPUState *env, struct target_sigcontext *sc)
1500 {
1501 int err = 0;
1502 uint32_t cpsr;
1503
1504 __get_user_error(env->regs[0], &sc->arm_r0, err);
1505 __get_user_error(env->regs[1], &sc->arm_r1, err);
1506 __get_user_error(env->regs[2], &sc->arm_r2, err);
1507 __get_user_error(env->regs[3], &sc->arm_r3, err);
1508 __get_user_error(env->regs[4], &sc->arm_r4, err);
1509 __get_user_error(env->regs[5], &sc->arm_r5, err);
1510 __get_user_error(env->regs[6], &sc->arm_r6, err);
1511 __get_user_error(env->regs[7], &sc->arm_r7, err);
1512 __get_user_error(env->regs[8], &sc->arm_r8, err);
1513 __get_user_error(env->regs[9], &sc->arm_r9, err);
1514 __get_user_error(env->regs[10], &sc->arm_r10, err);
1515 __get_user_error(env->regs[11], &sc->arm_fp, err);
1516 __get_user_error(env->regs[12], &sc->arm_ip, err);
1517 __get_user_error(env->regs[13], &sc->arm_sp, err);
1518 __get_user_error(env->regs[14], &sc->arm_lr, err);
1519 __get_user_error(env->regs[15], &sc->arm_pc, err);
1520 #ifdef TARGET_CONFIG_CPU_32
1521 __get_user_error(cpsr, &sc->arm_cpsr, err);
1522 cpsr_write(env, cpsr, CPSR_USER | CPSR_EXEC);
1523 #endif
1524
1525 err |= !valid_user_regs(env);
1526
1527 return err;
1528 }
1529
1530 static long do_sigreturn_v1(CPUState *env)
1531 {
1532 abi_ulong frame_addr;
1533 struct sigframe_v1 *frame;
1534 target_sigset_t set;
1535 sigset_t host_set;
1536 int i;
1537
1538 /*
1539 * Since we stacked the signal on a 64-bit boundary,
1540 * then 'sp' should be word aligned here. If it's
1541 * not, then the user is trying to mess with us.
1542 */
1543 if (env->regs[13] & 7)
1544 goto badframe;
1545
1546 frame_addr = env->regs[13];
1547 if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1))
1548 goto badframe;
1549
1550 if (__get_user(set.sig[0], &frame->sc.oldmask))
1551 goto badframe;
1552 for(i = 1; i < TARGET_NSIG_WORDS; i++) {
1553 if (__get_user(set.sig[i], &frame->extramask[i - 1]))
1554 goto badframe;
1555 }
1556
1557 target_to_host_sigset_internal(&host_set, &set);
1558 sigprocmask(SIG_SETMASK, &host_set, NULL);
1559
1560 if (restore_sigcontext(env, &frame->sc))
1561 goto badframe;
1562
1563 #if 0
1564 /* Send SIGTRAP if we're single-stepping */
1565 if (ptrace_cancel_bpt(current))
1566 send_sig(SIGTRAP, current, 1);
1567 #endif
1568 unlock_user_struct(frame, frame_addr, 0);
1569 return env->regs[0];
1570
1571 badframe:
1572 unlock_user_struct(frame, frame_addr, 0);
1573 force_sig(TARGET_SIGSEGV /* , current */);
1574 return 0;
1575 }
1576
1577 static abi_ulong *restore_sigframe_v2_vfp(CPUState *env, abi_ulong *regspace)
1578 {
1579 int i;
1580 abi_ulong magic, sz;
1581 uint32_t fpscr, fpexc;
1582 struct target_vfp_sigframe *vfpframe;
1583 vfpframe = (struct target_vfp_sigframe *)regspace;
1584
1585 __get_user(magic, &vfpframe->magic);
1586 __get_user(sz, &vfpframe->size);
1587 if (magic != TARGET_VFP_MAGIC || sz != sizeof(*vfpframe)) {
1588 return 0;
1589 }
1590 for (i = 0; i < 32; i++) {
1591 __get_user(env->vfp.regs[i], &vfpframe->ufp.fpregs[i]);
1592 }
1593 __get_user(fpscr, &vfpframe->ufp.fpscr);
1594 vfp_set_fpscr(env, fpscr);
1595 __get_user(fpexc, &vfpframe->ufp_exc.fpexc);
1596 /* Sanitise FPEXC: ensure VFP is enabled, FPINST2 is invalid
1597 * and the exception flag is cleared
1598 */
1599 fpexc |= (1 << 30);
1600 fpexc &= ~((1 << 31) | (1 << 28));
1601 env->vfp.xregs[ARM_VFP_FPEXC] = fpexc;
1602 __get_user(env->vfp.xregs[ARM_VFP_FPINST], &vfpframe->ufp_exc.fpinst);
1603 __get_user(env->vfp.xregs[ARM_VFP_FPINST2], &vfpframe->ufp_exc.fpinst2);
1604 return (abi_ulong*)(vfpframe + 1);
1605 }
1606
1607 static abi_ulong *restore_sigframe_v2_iwmmxt(CPUState *env, abi_ulong *regspace)
1608 {
1609 int i;
1610 abi_ulong magic, sz;
1611 struct target_iwmmxt_sigframe *iwmmxtframe;
1612 iwmmxtframe = (struct target_iwmmxt_sigframe *)regspace;
1613
1614 __get_user(magic, &iwmmxtframe->magic);
1615 __get_user(sz, &iwmmxtframe->size);
1616 if (magic != TARGET_IWMMXT_MAGIC || sz != sizeof(*iwmmxtframe)) {
1617 return 0;
1618 }
1619 for (i = 0; i < 16; i++) {
1620 __get_user(env->iwmmxt.regs[i], &iwmmxtframe->regs[i]);
1621 }
1622 __get_user(env->vfp.xregs[ARM_IWMMXT_wCSSF], &iwmmxtframe->wcssf);
1623 __get_user(env->vfp.xregs[ARM_IWMMXT_wCASF], &iwmmxtframe->wcssf);
1624 __get_user(env->vfp.xregs[ARM_IWMMXT_wCGR0], &iwmmxtframe->wcgr0);
1625 __get_user(env->vfp.xregs[ARM_IWMMXT_wCGR1], &iwmmxtframe->wcgr1);
1626 __get_user(env->vfp.xregs[ARM_IWMMXT_wCGR2], &iwmmxtframe->wcgr2);
1627 __get_user(env->vfp.xregs[ARM_IWMMXT_wCGR3], &iwmmxtframe->wcgr3);
1628 return (abi_ulong*)(iwmmxtframe + 1);
1629 }
1630
1631 static int do_sigframe_return_v2(CPUState *env, target_ulong frame_addr,
1632 struct target_ucontext_v2 *uc)
1633 {
1634 sigset_t host_set;
1635 abi_ulong *regspace;
1636
1637 target_to_host_sigset(&host_set, &uc->tuc_sigmask);
1638 sigprocmask(SIG_SETMASK, &host_set, NULL);
1639
1640 if (restore_sigcontext(env, &uc->tuc_mcontext))
1641 return 1;
1642
1643 /* Restore coprocessor signal frame */
1644 regspace = uc->tuc_regspace;
1645 if (arm_feature(env, ARM_FEATURE_VFP)) {
1646 regspace = restore_sigframe_v2_vfp(env, regspace);
1647 if (!regspace) {
1648 return 1;
1649 }
1650 }
1651 if (arm_feature(env, ARM_FEATURE_IWMMXT)) {
1652 regspace = restore_sigframe_v2_iwmmxt(env, regspace);
1653 if (!regspace) {
1654 return 1;
1655 }
1656 }
1657
1658 if (do_sigaltstack(frame_addr + offsetof(struct target_ucontext_v2, tuc_stack), 0, get_sp_from_cpustate(env)) == -EFAULT)
1659 return 1;
1660
1661 #if 0
1662 /* Send SIGTRAP if we're single-stepping */
1663 if (ptrace_cancel_bpt(current))
1664 send_sig(SIGTRAP, current, 1);
1665 #endif
1666
1667 return 0;
1668 }
1669
1670 static long do_sigreturn_v2(CPUState *env)
1671 {
1672 abi_ulong frame_addr;
1673 struct sigframe_v2 *frame;
1674
1675 /*
1676 * Since we stacked the signal on a 64-bit boundary,
1677 * then 'sp' should be word aligned here. If it's
1678 * not, then the user is trying to mess with us.
1679 */
1680 if (env->regs[13] & 7)
1681 goto badframe;
1682
1683 frame_addr = env->regs[13];
1684 if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1))
1685 goto badframe;
1686
1687 if (do_sigframe_return_v2(env, frame_addr, &frame->uc))
1688 goto badframe;
1689
1690 unlock_user_struct(frame, frame_addr, 0);
1691 return env->regs[0];
1692
1693 badframe:
1694 unlock_user_struct(frame, frame_addr, 0);
1695 force_sig(TARGET_SIGSEGV /* , current */);
1696 return 0;
1697 }
1698
1699 long do_sigreturn(CPUState *env)
1700 {
1701 if (get_osversion() >= 0x020612) {
1702 return do_sigreturn_v2(env);
1703 } else {
1704 return do_sigreturn_v1(env);
1705 }
1706 }
1707
1708 static long do_rt_sigreturn_v1(CPUState *env)
1709 {
1710 abi_ulong frame_addr;
1711 struct rt_sigframe_v1 *frame;
1712 sigset_t host_set;
1713
1714 /*
1715 * Since we stacked the signal on a 64-bit boundary,
1716 * then 'sp' should be word aligned here. If it's
1717 * not, then the user is trying to mess with us.
1718 */
1719 if (env->regs[13] & 7)
1720 goto badframe;
1721
1722 frame_addr = env->regs[13];
1723 if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1))
1724 goto badframe;
1725
1726 target_to_host_sigset(&host_set, &frame->uc.tuc_sigmask);
1727 sigprocmask(SIG_SETMASK, &host_set, NULL);
1728
1729 if (restore_sigcontext(env, &frame->uc.tuc_mcontext))
1730 goto badframe;
1731
1732 if (do_sigaltstack(frame_addr + offsetof(struct rt_sigframe_v1, uc.tuc_stack), 0, get_sp_from_cpustate(env)) == -EFAULT)
1733 goto badframe;
1734
1735 #if 0
1736 /* Send SIGTRAP if we're single-stepping */
1737 if (ptrace_cancel_bpt(current))
1738 send_sig(SIGTRAP, current, 1);
1739 #endif
1740 unlock_user_struct(frame, frame_addr, 0);
1741 return env->regs[0];
1742
1743 badframe:
1744 unlock_user_struct(frame, frame_addr, 0);
1745 force_sig(TARGET_SIGSEGV /* , current */);
1746 return 0;
1747 }
1748
1749 static long do_rt_sigreturn_v2(CPUState *env)
1750 {
1751 abi_ulong frame_addr;
1752 struct rt_sigframe_v2 *frame;
1753
1754 /*
1755 * Since we stacked the signal on a 64-bit boundary,
1756 * then 'sp' should be word aligned here. If it's
1757 * not, then the user is trying to mess with us.
1758 */
1759 if (env->regs[13] & 7)
1760 goto badframe;
1761
1762 frame_addr = env->regs[13];
1763 if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1))
1764 goto badframe;
1765
1766 if (do_sigframe_return_v2(env, frame_addr, &frame->uc))
1767 goto badframe;
1768
1769 unlock_user_struct(frame, frame_addr, 0);
1770 return env->regs[0];
1771
1772 badframe:
1773 unlock_user_struct(frame, frame_addr, 0);
1774 force_sig(TARGET_SIGSEGV /* , current */);
1775 return 0;
1776 }
1777
1778 long do_rt_sigreturn(CPUState *env)
1779 {
1780 if (get_osversion() >= 0x020612) {
1781 return do_rt_sigreturn_v2(env);
1782 } else {
1783 return do_rt_sigreturn_v1(env);
1784 }
1785 }
1786
1787 #elif defined(TARGET_SPARC)
1788
1789 #define __SUNOS_MAXWIN 31
1790
1791 /* This is what SunOS does, so shall I. */
1792 struct target_sigcontext {
1793 abi_ulong sigc_onstack; /* state to restore */
1794
1795 abi_ulong sigc_mask; /* sigmask to restore */
1796 abi_ulong sigc_sp; /* stack pointer */
1797 abi_ulong sigc_pc; /* program counter */
1798 abi_ulong sigc_npc; /* next program counter */
1799 abi_ulong sigc_psr; /* for condition codes etc */
1800 abi_ulong sigc_g1; /* User uses these two registers */
1801 abi_ulong sigc_o0; /* within the trampoline code. */
1802
1803 /* Now comes information regarding the users window set
1804 * at the time of the signal.
1805 */
1806 abi_ulong sigc_oswins; /* outstanding windows */
1807
1808 /* stack ptrs for each regwin buf */
1809 char *sigc_spbuf[__SUNOS_MAXWIN];
1810
1811 /* Windows to restore after signal */
1812 struct {
1813 abi_ulong locals[8];
1814 abi_ulong ins[8];
1815 } sigc_wbuf[__SUNOS_MAXWIN];
1816 };
1817 /* A Sparc stack frame */
1818 struct sparc_stackf {
1819 abi_ulong locals[8];
1820 abi_ulong ins[6];
1821 struct sparc_stackf *fp;
1822 abi_ulong callers_pc;
1823 char *structptr;
1824 abi_ulong xargs[6];
1825 abi_ulong xxargs[1];
1826 };
1827
1828 typedef struct {
1829 struct {
1830 abi_ulong psr;
1831 abi_ulong pc;
1832 abi_ulong npc;
1833 abi_ulong y;
1834 abi_ulong u_regs[16]; /* globals and ins */
1835 } si_regs;
1836 int si_mask;
1837 } __siginfo_t;
1838
1839 typedef struct {
1840 unsigned long si_float_regs [32];
1841 unsigned long si_fsr;
1842 unsigned long si_fpqdepth;
1843 struct {
1844 unsigned long *insn_addr;
1845 unsigned long insn;
1846 } si_fpqueue [16];
1847 } qemu_siginfo_fpu_t;
1848
1849
1850 struct target_signal_frame {
1851 struct sparc_stackf ss;
1852 __siginfo_t info;
1853 abi_ulong fpu_save;
1854 abi_ulong insns[2] __attribute__ ((aligned (8)));
1855 abi_ulong extramask[TARGET_NSIG_WORDS - 1];
1856 abi_ulong extra_size; /* Should be 0 */
1857 qemu_siginfo_fpu_t fpu_state;
1858 };
1859 struct target_rt_signal_frame {
1860 struct sparc_stackf ss;
1861 siginfo_t info;
1862 abi_ulong regs[20];
1863 sigset_t mask;
1864 abi_ulong fpu_save;
1865 unsigned int insns[2];
1866 stack_t stack;
1867 unsigned int extra_size; /* Should be 0 */
1868 qemu_siginfo_fpu_t fpu_state;
1869 };
1870
1871 #define UREG_O0 16
1872 #define UREG_O6 22
1873 #define UREG_I0 0
1874 #define UREG_I1 1
1875 #define UREG_I2 2
1876 #define UREG_I3 3
1877 #define UREG_I4 4
1878 #define UREG_I5 5
1879 #define UREG_I6 6
1880 #define UREG_I7 7
1881 #define UREG_L0 8
1882 #define UREG_FP UREG_I6
1883 #define UREG_SP UREG_O6
1884
1885 static inline abi_ulong get_sigframe(struct target_sigaction *sa,
1886 CPUState *env, unsigned long framesize)
1887 {
1888 abi_ulong sp;
1889
1890 sp = env->regwptr[UREG_FP];
1891
1892 /* This is the X/Open sanctioned signal stack switching. */
1893 if (sa->sa_flags & TARGET_SA_ONSTACK) {
1894 if (!on_sig_stack(sp)
1895 && !((target_sigaltstack_used.ss_sp + target_sigaltstack_used.ss_size) & 7))
1896 sp = target_sigaltstack_used.ss_sp + target_sigaltstack_used.ss_size;
1897 }
1898 return sp - framesize;
1899 }
1900
1901 static int
1902 setup___siginfo(__siginfo_t *si, CPUState *env, abi_ulong mask)
1903 {
1904 int err = 0, i;
1905
1906 err |= __put_user(env->psr, &si->si_regs.psr);
1907 err |= __put_user(env->pc, &si->si_regs.pc);
1908 err |= __put_user(env->npc, &si->si_regs.npc);
1909 err |= __put_user(env->y, &si->si_regs.y);
1910 for (i=0; i < 8; i++) {
1911 err |= __put_user(env->gregs[i], &si->si_regs.u_regs[i]);
1912 }
1913 for (i=0; i < 8; i++) {
1914 err |= __put_user(env->regwptr[UREG_I0 + i], &si->si_regs.u_regs[i+8]);
1915 }
1916 err |= __put_user(mask, &si->si_mask);
1917 return err;
1918 }
1919
1920 #if 0
1921 static int
1922 setup_sigcontext(struct target_sigcontext *sc, /*struct _fpstate *fpstate,*/
1923 CPUState *env, unsigned long mask)
1924 {
1925 int err = 0;
1926
1927 err |= __put_user(mask, &sc->sigc_mask);
1928 err |= __put_user(env->regwptr[UREG_SP], &sc->sigc_sp);
1929 err |= __put_user(env->pc, &sc->sigc_pc);
1930 err |= __put_user(env->npc, &sc->sigc_npc);
1931 err |= __put_user(env->psr, &sc->sigc_psr);
1932 err |= __put_user(env->gregs[1], &sc->sigc_g1);
1933 err |= __put_user(env->regwptr[UREG_O0], &sc->sigc_o0);
1934
1935 return err;
1936 }
1937 #endif
1938 #define NF_ALIGNEDSZ (((sizeof(struct target_signal_frame) + 7) & (~7)))
1939
1940 static void setup_frame(int sig, struct target_sigaction *ka,
1941 target_sigset_t *set, CPUState *env)
1942 {
1943 abi_ulong sf_addr;
1944 struct target_signal_frame *sf;
1945 int sigframe_size, err, i;
1946
1947 /* 1. Make sure everything is clean */
1948 //synchronize_user_stack();
1949
1950 sigframe_size = NF_ALIGNEDSZ;
1951 sf_addr = get_sigframe(ka, env, sigframe_size);
1952
1953 sf = lock_user(VERIFY_WRITE, sf_addr,
1954 sizeof(struct target_signal_frame), 0);
1955 if (!sf)
1956 goto sigsegv;
1957
1958 //fprintf(stderr, "sf: %x pc %x fp %x sp %x\n", sf, env->pc, env->regwptr[UREG_FP], env->regwptr[UREG_SP]);
1959 #if 0
1960 if (invalid_frame_pointer(sf, sigframe_size))
1961 goto sigill_and_return;
1962 #endif
1963 /* 2. Save the current process state */
1964 err = setup___siginfo(&sf->info, env, set->sig[0]);
1965 err |= __put_user(0, &sf->extra_size);
1966
1967 //err |= save_fpu_state(regs, &sf->fpu_state);
1968 //err |= __put_user(&sf->fpu_state, &sf->fpu_save);
1969
1970 err |= __put_user(set->sig[0], &sf->info.si_mask);
1971 for (i = 0; i < TARGET_NSIG_WORDS - 1; i++) {
1972 err |= __put_user(set->sig[i + 1], &sf->extramask[i]);
1973 }
1974
1975 for (i = 0; i < 8; i++) {
1976 err |= __put_user(env->regwptr[i + UREG_L0], &sf->ss.locals[i]);
1977 }
1978 for (i = 0; i < 8; i++) {
1979 err |= __put_user(env->regwptr[i + UREG_I0], &sf->ss.ins[i]);
1980 }
1981 if (err)
1982 goto sigsegv;
1983
1984 /* 3. signal handler back-trampoline and parameters */
1985 env->regwptr[UREG_FP] = sf_addr;
1986 env->regwptr[UREG_I0] = sig;
1987 env->regwptr[UREG_I1] = sf_addr +
1988 offsetof(struct target_signal_frame, info);
1989 env->regwptr[UREG_I2] = sf_addr +
1990 offsetof(struct target_signal_frame, info);
1991
1992 /* 4. signal handler */
1993 env->pc = ka->_sa_handler;
1994 env->npc = (env->pc + 4);
1995 /* 5. return to kernel instructions */
1996 if (ka->sa_restorer)
1997 env->regwptr[UREG_I7] = ka->sa_restorer;
1998 else {
1999 uint32_t val32;
2000
2001 env->regwptr[UREG_I7] = sf_addr +
2002 offsetof(struct target_signal_frame, insns) - 2 * 4;
2003
2004 /* mov __NR_sigreturn, %g1 */
2005 val32 = 0x821020d8;
2006 err |= __put_user(val32, &sf->insns[0]);
2007
2008 /* t 0x10 */
2009 val32 = 0x91d02010;
2010 err |= __put_user(val32, &sf->insns[1]);
2011 if (err)
2012 goto sigsegv;
2013
2014 /* Flush instruction space. */
2015 //flush_sig_insns(current->mm, (unsigned long) &(sf->insns[0]));
2016 // tb_flush(env);
2017 }
2018 unlock_user(sf, sf_addr, sizeof(struct target_signal_frame));
2019 return;
2020 #if 0
2021 sigill_and_return:
2022 force_sig(TARGET_SIGILL);
2023 #endif
2024 sigsegv:
2025 //fprintf(stderr, "force_sig\n");
2026 unlock_user(sf, sf_addr, sizeof(struct target_signal_frame));
2027 force_sig(TARGET_SIGSEGV);
2028 }
2029 static inline int
2030 restore_fpu_state(CPUState *env, qemu_siginfo_fpu_t *fpu)
2031 {
2032 int err;
2033 #if 0
2034 #ifdef CONFIG_SMP
2035 if (current->flags & PF_USEDFPU)
2036 regs->psr &= ~PSR_EF;
2037 #else
2038 if (current == last_task_used_math) {
2039 last_task_used_math = 0;
2040 regs->psr &= ~PSR_EF;
2041 }
2042 #endif
2043 current->used_math = 1;
2044 current->flags &= ~PF_USEDFPU;
2045 #endif
2046 #if 0
2047 if (verify_area (VERIFY_READ, fpu, sizeof(*fpu)))
2048 return -EFAULT;
2049 #endif
2050
2051 #if 0
2052 /* XXX: incorrect */
2053 err = __copy_from_user(&env->fpr[0], &fpu->si_float_regs[0],
2054 (sizeof(unsigned long) * 32));
2055 #endif
2056 err |= __get_user(env->fsr, &fpu->si_fsr);
2057 #if 0
2058 err |= __get_user(current->thread.fpqdepth, &fpu->si_fpqdepth);
2059 if (current->thread.fpqdepth != 0)
2060 err |= __copy_from_user(&current->thread.fpqueue[0],
2061 &fpu->si_fpqueue[0],
2062 ((sizeof(unsigned long) +
2063 (sizeof(unsigned long *)))*16));
2064 #endif
2065 return err;
2066 }
2067
2068
2069 static void setup_rt_frame(int sig, struct target_sigaction *ka,
2070 target_siginfo_t *info,
2071 target_sigset_t *set, CPUState *env)
2072 {
2073 fprintf(stderr, "setup_rt_frame: not implemented\n");
2074 }
2075
2076 long do_sigreturn(CPUState *env)
2077 {
2078 abi_ulong sf_addr;
2079 struct target_signal_frame *sf;
2080 uint32_t up_psr, pc, npc;
2081 target_sigset_t set;
2082 sigset_t host_set;
2083 abi_ulong fpu_save_addr;
2084 int err, i;
2085
2086 sf_addr = env->regwptr[UREG_FP];
2087 if (!lock_user_struct(VERIFY_READ, sf, sf_addr, 1))
2088 goto segv_and_exit;
2089 #if 0
2090 fprintf(stderr, "sigreturn\n");
2091 fprintf(stderr, "sf: %x pc %x fp %x sp %x\n", sf, env->pc, env->regwptr[UREG_FP], env->regwptr[UREG_SP]);
2092 #endif
2093 //cpu_dump_state(env, stderr, fprintf, 0);
2094
2095 /* 1. Make sure we are not getting garbage from the user */
2096
2097 if (sf_addr & 3)
2098 goto segv_and_exit;
2099
2100 err = __get_user(pc, &sf->info.si_regs.pc);
2101 err |= __get_user(npc, &sf->info.si_regs.npc);
2102
2103 if ((pc | npc) & 3)
2104 goto segv_and_exit;
2105
2106 /* 2. Restore the state */
2107 err |= __get_user(up_psr, &sf->info.si_regs.psr);
2108
2109 /* User can only change condition codes and FPU enabling in %psr. */
2110 env->psr = (up_psr & (PSR_ICC /* | PSR_EF */))
2111 | (env->psr & ~(PSR_ICC /* | PSR_EF */));
2112
2113 env->pc = pc;
2114 env->npc = npc;
2115 err |= __get_user(env->y, &sf->info.si_regs.y);
2116 for (i=0; i < 8; i++) {
2117 err |= __get_user(env->gregs[i], &sf->info.si_regs.u_regs[i]);
2118 }
2119 for (i=0; i < 8; i++) {
2120 err |= __get_user(env->regwptr[i + UREG_I0], &sf->info.si_regs.u_regs[i+8]);
2121 }
2122
2123 err |= __get_user(fpu_save_addr, &sf->fpu_save);
2124
2125 //if (fpu_save)
2126 // err |= restore_fpu_state(env, fpu_save);
2127
2128 /* This is pretty much atomic, no amount locking would prevent
2129 * the races which exist anyways.
2130 */
2131 err |= __get_user(set.sig[0], &sf->info.si_mask);
2132 for(i = 1; i < TARGET_NSIG_WORDS; i++) {
2133 err |= (__get_user(set.sig[i], &sf->extramask[i - 1]));
2134 }
2135
2136 target_to_host_sigset_internal(&host_set, &set);
2137 sigprocmask(SIG_SETMASK, &host_set, NULL);
2138
2139 if (err)
2140 goto segv_and_exit;
2141 unlock_user_struct(sf, sf_addr, 0);
2142 return env->regwptr[0];
2143
2144 segv_and_exit:
2145 unlock_user_struct(sf, sf_addr, 0);
2146 force_sig(TARGET_SIGSEGV);
2147 }
2148
2149 long do_rt_sigreturn(CPUState *env)
2150 {
2151 fprintf(stderr, "do_rt_sigreturn: not implemented\n");
2152 return -TARGET_ENOSYS;
2153 }
2154
2155 #if defined(TARGET_SPARC64) && !defined(TARGET_ABI32)
2156 #define MC_TSTATE 0
2157 #define MC_PC 1
2158 #define MC_NPC 2
2159 #define MC_Y 3
2160 #define MC_G1 4
2161 #define MC_G2 5
2162 #define MC_G3 6
2163 #define MC_G4 7
2164 #define MC_G5 8
2165 #define MC_G6 9
2166 #define MC_G7 10
2167 #define MC_O0 11
2168 #define MC_O1 12
2169 #define MC_O2 13
2170 #define MC_O3 14
2171 #define MC_O4 15
2172 #define MC_O5 16
2173 #define MC_O6 17
2174 #define MC_O7 18
2175 #define MC_NGREG 19
2176
2177 typedef abi_ulong target_mc_greg_t;
2178 typedef target_mc_greg_t target_mc_gregset_t[MC_NGREG];
2179
2180 struct target_mc_fq {
2181 abi_ulong *mcfq_addr;
2182 uint32_t mcfq_insn;
2183 };
2184
2185 struct target_mc_fpu {
2186 union {
2187 uint32_t sregs[32];
2188 uint64_t dregs[32];
2189 //uint128_t qregs[16];
2190 } mcfpu_fregs;
2191 abi_ulong mcfpu_fsr;
2192 abi_ulong mcfpu_fprs;
2193 abi_ulong mcfpu_gsr;
2194 struct target_mc_fq *mcfpu_fq;
2195 unsigned char mcfpu_qcnt;
2196 unsigned char mcfpu_qentsz;
2197 unsigned char mcfpu_enab;
2198 };
2199 typedef struct target_mc_fpu target_mc_fpu_t;
2200
2201 typedef struct {
2202 target_mc_gregset_t mc_gregs;
2203 target_mc_greg_t mc_fp;
2204 target_mc_greg_t mc_i7;
2205 target_mc_fpu_t mc_fpregs;
2206 } target_mcontext_t;
2207
2208 struct target_ucontext {
2209 struct target_ucontext *tuc_link;
2210 abi_ulong tuc_flags;
2211 target_sigset_t tuc_sigmask;
2212 target_mcontext_t tuc_mcontext;
2213 };
2214
2215 /* A V9 register window */
2216 struct target_reg_window {
2217 abi_ulong locals[8];
2218 abi_ulong ins[8];
2219 };
2220
2221 #define TARGET_STACK_BIAS 2047
2222
2223 /* {set, get}context() needed for 64-bit SparcLinux userland. */
2224 void sparc64_set_context(CPUSPARCState *env)
2225 {
2226 abi_ulong ucp_addr;
2227 struct target_ucontext *ucp;
2228 target_mc_gregset_t *grp;
2229 abi_ulong pc, npc, tstate;
2230 abi_ulong fp, i7, w_addr;
2231 unsigned char fenab;
2232 int err;
2233 unsigned int i;
2234
2235 ucp_addr = env->regwptr[UREG_I0];
2236 if (!lock_user_struct(VERIFY_READ, ucp, ucp_addr, 1))
2237 goto do_sigsegv;
2238 grp = &ucp->tuc_mcontext.mc_gregs;
2239 err = __get_user(pc, &((*grp)[MC_PC]));
2240 err |= __get_user(npc, &((*grp)[MC_NPC]));
2241 if (err || ((pc | npc) & 3))
2242 goto do_sigsegv;
2243 if (env->regwptr[UREG_I1]) {
2244 target_sigset_t target_set;
2245 sigset_t set;
2246
2247 if (TARGET_NSIG_WORDS == 1) {
2248 if (__get_user(target_set.sig[0], &ucp->tuc_sigmask.sig[0]))
2249 goto do_sigsegv;
2250 } else {
2251 abi_ulong *src, *dst;
2252 src = ucp->tuc_sigmask.sig;
2253 dst = target_set.sig;
2254 for (i = 0; i < sizeof(target_sigset_t) / sizeof(abi_ulong);
2255 i++, dst++, src++)
2256 err |= __get_user(*dst, src);
2257 if (err)
2258 goto do_sigsegv;
2259 }
2260 target_to_host_sigset_internal(&set, &target_set);
2261 sigprocmask(SIG_SETMASK, &set, NULL);
2262 }
2263 env->pc = pc;
2264 env->npc = npc;
2265 err |= __get_user(env->y, &((*grp)[MC_Y]));
2266 err |= __get_user(tstate, &((*grp)[MC_TSTATE]));
2267 env->asi = (tstate >> 24) & 0xff;
2268 cpu_put_ccr(env, tstate >> 32);
2269 cpu_put_cwp64(env, tstate & 0x1f);
2270 err |= __get_user(env->gregs[1], (&(*grp)[MC_G1]));
2271 err |= __get_user(env->gregs[2], (&(*grp)[MC_G2]));
2272 err |= __get_user(env->gregs[3], (&(*grp)[MC_G3]));
2273 err |= __get_user(env->gregs[4], (&(*grp)[MC_G4]));
2274 err |= __get_user(env->gregs[5], (&(*grp)[MC_G5]));
2275 err |= __get_user(env->gregs[6], (&(*grp)[MC_G6]));
2276 err |= __get_user(env->gregs[7], (&(*grp)[MC_G7]));
2277 err |= __get_user(env->regwptr[UREG_I0], (&(*grp)[MC_O0]));
2278 err |= __get_user(env->regwptr[UREG_I1], (&(*grp)[MC_O1]));
2279 err |= __get_user(env->regwptr[UREG_I2], (&(*grp)[MC_O2]));
2280 err |= __get_user(env->regwptr[UREG_I3], (&(*grp)[MC_O3]));
2281 err |= __get_user(env->regwptr[UREG_I4], (&(*grp)[MC_O4]));
2282 err |= __get_user(env->regwptr[UREG_I5], (&(*grp)[MC_O5]));
2283 err |= __get_user(env->regwptr[UREG_I6], (&(*grp)[MC_O6]));
2284 err |= __get_user(env->regwptr[UREG_I7], (&(*grp)[MC_O7]));
2285
2286 err |= __get_user(fp, &(ucp->tuc_mcontext.mc_fp));
2287 err |= __get_user(i7, &(ucp->tuc_mcontext.mc_i7));
2288
2289 w_addr = TARGET_STACK_BIAS+env->regwptr[UREG_I6];
2290 if (put_user(fp, w_addr + offsetof(struct target_reg_window, ins[6]),
2291 abi_ulong) != 0)
2292 goto do_sigsegv;
2293 if (put_user(i7, w_addr + offsetof(struct target_reg_window, ins[7]),
2294 abi_ulong) != 0)
2295 goto do_sigsegv;
2296 err |= __get_user(fenab, &(ucp->tuc_mcontext.mc_fpregs.mcfpu_enab));
2297 err |= __get_user(env->fprs, &(ucp->tuc_mcontext.mc_fpregs.mcfpu_fprs));
2298 {
2299 uint32_t *src, *dst;
2300 src = ucp->tuc_mcontext.mc_fpregs.mcfpu_fregs.sregs;
2301 dst = env->fpr;
2302 /* XXX: check that the CPU storage is the same as user context */
2303 for (i = 0; i < 64; i++, dst++, src++)
2304 err |= __get_user(*dst, src);
2305 }
2306 err |= __get_user(env->fsr,
2307 &(ucp->tuc_mcontext.mc_fpregs.mcfpu_fsr));
2308 err |= __get_user(env->gsr,
2309 &(ucp->tuc_mcontext.mc_fpregs.mcfpu_gsr));
2310 if (err)
2311 goto do_sigsegv;
2312 unlock_user_struct(ucp, ucp_addr, 0);
2313 return;
2314 do_sigsegv:
2315 unlock_user_struct(ucp, ucp_addr, 0);
2316 force_sig(TARGET_SIGSEGV);
2317 }
2318
2319 void sparc64_get_context(CPUSPARCState *env)
2320 {
2321 abi_ulong ucp_addr;
2322 struct target_ucontext *ucp;
2323 target_mc_gregset_t *grp;
2324 target_mcontext_t *mcp;
2325 abi_ulong fp, i7, w_addr;
2326 int err;
2327 unsigned int i;
2328 target_sigset_t target_set;
2329 sigset_t set;
2330
2331 ucp_addr = env->regwptr[UREG_I0];
2332 if (!lock_user_struct(VERIFY_WRITE, ucp, ucp_addr, 0))
2333 goto do_sigsegv;
2334
2335 mcp = &ucp->tuc_mcontext;
2336 grp = &mcp->mc_gregs;
2337
2338 /* Skip over the trap instruction, first. */
2339 env->pc = env->npc;
2340 env->npc += 4;
2341
2342 err = 0;
2343
2344 sigprocmask(0, NULL, &set);
2345 host_to_target_sigset_internal(&target_set, &set);
2346 if (TARGET_NSIG_WORDS == 1) {
2347 err |= __put_user(target_set.sig[0],
2348 (abi_ulong *)&ucp->tuc_sigmask);
2349 } else {
2350 abi_ulong *src, *dst;
2351 src = target_set.sig;
2352 dst = ucp->tuc_sigmask.sig;
2353 for (i = 0; i < sizeof(target_sigset_t) / sizeof(abi_ulong);
2354 i++, dst++, src++)
2355 err |= __put_user(*src, dst);
2356 if (err)
2357 goto do_sigsegv;
2358 }
2359
2360 /* XXX: tstate must be saved properly */
2361 // err |= __put_user(env->tstate, &((*grp)[MC_TSTATE]));
2362 err |= __put_user(env->pc, &((*grp)[MC_PC]));
2363 err |= __put_user(env->npc, &((*grp)[MC_NPC]));
2364 err |= __put_user(env->y, &((*grp)[MC_Y]));
2365 err |= __put_user(env->gregs[1], &((*grp)[MC_G1]));
2366 err |= __put_user(env->gregs[2], &((*grp)[MC_G2]));
2367 err |= __put_user(env->gregs[3], &((*grp)[MC_G3]));
2368 err |= __put_user(env->gregs[4], &((*grp)[MC_G4]));
2369 err |= __put_user(env->gregs[5], &((*grp)[MC_G5]));
2370 err |= __put_user(env->gregs[6], &((*grp)[MC_G6]));
2371 err |= __put_user(env->gregs[7], &((*grp)[MC_G7]));
2372 err |= __put_user(env->regwptr[UREG_I0], &((*grp)[MC_O0]));
2373 err |= __put_user(env->regwptr[UREG_I1], &((*grp)[MC_O1]));
2374 err |= __put_user(env->regwptr[UREG_I2], &((*grp)[MC_O2]));
2375 err |= __put_user(env->regwptr[UREG_I3], &((*grp)[MC_O3]));
2376 err |= __put_user(env->regwptr[UREG_I4], &((*grp)[MC_O4]));
2377 err |= __put_user(env->regwptr[UREG_I5], &((*grp)[MC_O5]));
2378 err |= __put_user(env->regwptr[UREG_I6], &((*grp)[MC_O6]));
2379 err |= __put_user(env->regwptr[UREG_I7], &((*grp)[MC_O7]));
2380
2381 w_addr = TARGET_STACK_BIAS+env->regwptr[UREG_I6];
2382 fp = i7 = 0;
2383 if (get_user(fp, w_addr + offsetof(struct target_reg_window, ins[6]),
2384 abi_ulong) != 0)
2385 goto do_sigsegv;
2386 if (get_user(i7, w_addr + offsetof(struct target_reg_window, ins[7]),
2387 abi_ulong) != 0)
2388 goto do_sigsegv;
2389 err |= __put_user(fp, &(mcp->mc_fp));
2390 err |= __put_user(i7, &(mcp->mc_i7));
2391
2392 {
2393 uint32_t *src, *dst;
2394 src = env->fpr;
2395 dst = ucp->tuc_mcontext.mc_fpregs.mcfpu_fregs.sregs;
2396 /* XXX: check that the CPU storage is the same as user context */
2397 for (i = 0; i < 64; i++, dst++, src++)
2398 err |= __put_user(*src, dst);
2399 }
2400 err |= __put_user(env->fsr, &(mcp->mc_fpregs.mcfpu_fsr));
2401 err |= __put_user(env->gsr, &(mcp->mc_fpregs.mcfpu_gsr));
2402 err |= __put_user(env->fprs, &(mcp->mc_fpregs.mcfpu_fprs));
2403
2404 if (err)
2405 goto do_sigsegv;
2406 unlock_user_struct(ucp, ucp_addr, 1);
2407 return;
2408 do_sigsegv:
2409 unlock_user_struct(ucp, ucp_addr, 1);
2410 force_sig(TARGET_SIGSEGV);
2411 }
2412 #endif
2413 #elif defined(TARGET_ABI_MIPSN64)
2414
2415 # warning signal handling not implemented
2416
2417 static void setup_frame(int sig, struct target_sigaction *ka,
2418 target_sigset_t *set, CPUState *env)
2419 {
2420 fprintf(stderr, "setup_frame: not implemented\n");
2421 }
2422
2423 static void setup_rt_frame(int sig, struct target_sigaction *ka,
2424 target_siginfo_t *info,
2425 target_sigset_t *set, CPUState *env)
2426 {
2427 fprintf(stderr, "setup_rt_frame: not implemented\n");
2428 }
2429
2430 long do_sigreturn(CPUState *env)
2431 {
2432 fprintf(stderr, "do_sigreturn: not implemented\n");
2433 return -TARGET_ENOSYS;
2434 }
2435
2436 long do_rt_sigreturn(CPUState *env)
2437 {
2438 fprintf(stderr, "do_rt_sigreturn: not implemented\n");
2439 return -TARGET_ENOSYS;
2440 }
2441
2442 #elif defined(TARGET_ABI_MIPSN32)
2443
2444 # warning signal handling not implemented
2445
2446 static void setup_frame(int sig, struct target_sigaction *ka,
2447 target_sigset_t *set, CPUState *env)
2448 {
2449 fprintf(stderr, "setup_frame: not implemented\n");
2450 }
2451
2452 static void setup_rt_frame(int sig, struct target_sigaction *ka,
2453 target_siginfo_t *info,
2454 target_sigset_t *set, CPUState *env)
2455 {
2456 fprintf(stderr, "setup_rt_frame: not implemented\n");
2457 }
2458
2459 long do_sigreturn(CPUState *env)
2460 {
2461 fprintf(stderr, "do_sigreturn: not implemented\n");
2462 return -TARGET_ENOSYS;
2463 }
2464
2465 long do_rt_sigreturn(CPUState *env)
2466 {
2467 fprintf(stderr, "do_rt_sigreturn: not implemented\n");
2468 return -TARGET_ENOSYS;
2469 }
2470
2471 #elif defined(TARGET_ABI_MIPSO32)
2472
2473 struct target_sigcontext {
2474 uint32_t sc_regmask; /* Unused */
2475 uint32_t sc_status;
2476 uint64_t sc_pc;
2477 uint64_t sc_regs[32];
2478 uint64_t sc_fpregs[32];
2479 uint32_t sc_ownedfp; /* Unused */
2480 uint32_t sc_fpc_csr;
2481 uint32_t sc_fpc_eir; /* Unused */
2482 uint32_t sc_used_math;
2483 uint32_t sc_dsp; /* dsp status, was sc_ssflags */
2484 uint32_t pad0;
2485 uint64_t sc_mdhi;
2486 uint64_t sc_mdlo;
2487 target_ulong sc_hi1; /* Was sc_cause */
2488 target_ulong sc_lo1; /* Was sc_badvaddr */
2489 target_ulong sc_hi2; /* Was sc_sigset[4] */
2490 target_ulong sc_lo2;
2491 target_ulong sc_hi3;
2492 target_ulong sc_lo3;
2493 };
2494
2495 struct sigframe {
2496 uint32_t sf_ass[4]; /* argument save space for o32 */
2497 uint32_t sf_code[2]; /* signal trampoline */
2498 struct target_sigcontext sf_sc;
2499 target_sigset_t sf_mask;
2500 };
2501
2502 struct target_ucontext {
2503 target_ulong tuc_flags;
2504 target_ulong tuc_link;
2505 target_stack_t tuc_stack;
2506 target_ulong pad0;
2507 struct target_sigcontext tuc_mcontext;
2508 target_sigset_t tuc_sigmask;
2509 };
2510
2511 struct target_rt_sigframe {
2512 uint32_t rs_ass[4]; /* argument save space for o32 */
2513 uint32_t rs_code[2]; /* signal trampoline */
2514 struct target_siginfo rs_info;
2515 struct target_ucontext rs_uc;
2516 };
2517
2518 /* Install trampoline to jump back from signal handler */
2519 static inline int install_sigtramp(unsigned int *tramp, unsigned int syscall)
2520 {
2521 int err;
2522
2523 /*
2524 * Set up the return code ...
2525 *
2526 * li v0, __NR__foo_sigreturn
2527 * syscall
2528 */
2529
2530 err = __put_user(0x24020000 + syscall, tramp + 0);
2531 err |= __put_user(0x0000000c , tramp + 1);
2532 /* flush_cache_sigtramp((unsigned long) tramp); */
2533 return err;
2534 }
2535
2536 static inline int
2537 setup_sigcontext(CPUState *regs, struct target_sigcontext *sc)
2538 {
2539 int err = 0;
2540
2541 err |= __put_user(regs->active_tc.PC, &sc->sc_pc);
2542
2543 #define save_gp_reg(i) do { \
2544 err |= __put_user(regs->active_tc.gpr[i], &sc->sc_regs[i]); \
2545 } while(0)
2546 __put_user(0, &sc->sc_regs[0]); save_gp_reg(1); save_gp_reg(2);
2547 save_gp_reg(3); save_gp_reg(4); save_gp_reg(5); save_gp_reg(6);
2548 save_gp_reg(7); save_gp_reg(8); save_gp_reg(9); save_gp_reg(10);
2549 save_gp_reg(11); save_gp_reg(12); save_gp_reg(13); save_gp_reg(14);
2550 save_gp_reg(15); save_gp_reg(16); save_gp_reg(17); save_gp_reg(18);
2551 save_gp_reg(19); save_gp_reg(20); save_gp_reg(21); save_gp_reg(22);
2552 save_gp_reg(23); save_gp_reg(24); save_gp_reg(25); save_gp_reg(26);
2553 save_gp_reg(27); save_gp_reg(28); save_gp_reg(29); save_gp_reg(30);
2554 save_gp_reg(31);
2555 #undef save_gp_reg
2556
2557 err |= __put_user(regs->active_tc.HI[0], &sc->sc_mdhi);
2558 err |= __put_user(regs->active_tc.LO[0], &sc->sc_mdlo);
2559
2560 /* Not used yet, but might be useful if we ever have DSP suppport */
2561 #if 0
2562 if (cpu_has_dsp) {
2563 err |= __put_user(mfhi1(), &sc->sc_hi1);
2564 err |= __put_user(mflo1(), &sc->sc_lo1);
2565 err |= __put_user(mfhi2(), &sc->sc_hi2);
2566 err |= __put_user(mflo2(), &sc->sc_lo2);
2567 err |= __put_user(mfhi3(), &sc->sc_hi3);
2568 err |= __put_user(mflo3(), &sc->sc_lo3);
2569 err |= __put_user(rddsp(DSP_MASK), &sc->sc_dsp);
2570 }
2571 /* same with 64 bit */
2572 #ifdef CONFIG_64BIT
2573 err |= __put_user(regs->hi, &sc->sc_hi[0]);
2574 err |= __put_user(regs->lo, &sc->sc_lo[0]);
2575 if (cpu_has_dsp) {
2576 err |= __put_user(mfhi1(), &sc->sc_hi[1]);
2577 err |= __put_user(mflo1(), &sc->sc_lo[1]);
2578 err |= __put_user(mfhi2(), &sc->sc_hi[2]);
2579 err |= __put_user(mflo2(), &sc->sc_lo[2]);
2580 err |= __put_user(mfhi3(), &sc->sc_hi[3]);
2581 err |= __put_user(mflo3(), &sc->sc_lo[3]);
2582 err |= __put_user(rddsp(DSP_MASK), &sc->sc_dsp);
2583 }
2584 #endif
2585 #endif
2586
2587 #if 0
2588 err |= __put_user(!!used_math(), &sc->sc_used_math);
2589
2590 if (!used_math())
2591 goto out;
2592
2593 /*
2594 * Save FPU state to signal context. Signal handler will "inherit"
2595 * current FPU state.
2596 */
2597 preempt_disable();
2598
2599 if (!is_fpu_owner()) {
2600 own_fpu();
2601 restore_fp(current);
2602 }
2603 err |= save_fp_context(sc);
2604
2605 preempt_enable();
2606 out:
2607 #endif
2608 return err;
2609 }
2610
2611 static inline int
2612 restore_sigcontext(CPUState *regs, struct target_sigcontext *sc)
2613 {
2614 int err = 0;
2615
2616 err |= __get_user(regs->CP0_EPC, &sc->sc_pc);
2617
2618 err |= __get_user(regs->active_tc.HI[0], &sc->sc_mdhi);
2619 err |= __get_user(regs->active_tc.LO[0], &sc->sc_mdlo);
2620
2621 #define restore_gp_reg(i) do { \
2622 err |= __get_user(regs->active_tc.gpr[i], &sc->sc_regs[i]); \
2623 } while(0)
2624 restore_gp_reg( 1); restore_gp_reg( 2); restore_gp_reg( 3);
2625 restore_gp_reg( 4); restore_gp_reg( 5); restore_gp_reg( 6);
2626 restore_gp_reg( 7); restore_gp_reg( 8); restore_gp_reg( 9);
2627 restore_gp_reg(10); restore_gp_reg(11); restore_gp_reg(12);
2628 restore_gp_reg(13); restore_gp_reg(14); restore_gp_reg(15);
2629 restore_gp_reg(16); restore_gp_reg(17); restore_gp_reg(18);
2630 restore_gp_reg(19); restore_gp_reg(20); restore_gp_reg(21);
2631 restore_gp_reg(22); restore_gp_reg(23); restore_gp_reg(24);
2632 restore_gp_reg(25); restore_gp_reg(26); restore_gp_reg(27);
2633 restore_gp_reg(28); restore_gp_reg(29); restore_gp_reg(30);
2634 restore_gp_reg(31);
2635 #undef restore_gp_reg
2636
2637 #if 0
2638 if (cpu_has_dsp) {
2639 err |= __get_user(treg, &sc->sc_hi1); mthi1(treg);
2640 err |= __get_user(treg, &sc->sc_lo1); mtlo1(treg);
2641 err |= __get_user(treg, &sc->sc_hi2); mthi2(treg);
2642 err |= __get_user(treg, &sc->sc_lo2); mtlo2(treg);
2643 err |= __get_user(treg, &sc->sc_hi3); mthi3(treg);
2644 err |= __get_user(treg, &sc->sc_lo3); mtlo3(treg);
2645 err |= __get_user(treg, &sc->sc_dsp); wrdsp(treg, DSP_MASK);
2646 }
2647 #ifdef CONFIG_64BIT
2648 err |= __get_user(regs->hi, &sc->sc_hi[0]);
2649 err |= __get_user(regs->lo, &sc->sc_lo[0]);
2650 if (cpu_has_dsp) {
2651 err |= __get_user(treg, &sc->sc_hi[1]); mthi1(treg);
2652 err |= __get_user(treg, &sc->sc_lo[1]); mthi1(treg);
2653 err |= __get_user(treg, &sc->sc_hi[2]); mthi2(treg);
2654 err |= __get_user(treg, &sc->sc_lo[2]); mthi2(treg);
2655 err |= __get_user(treg, &sc->sc_hi[3]); mthi3(treg);
2656 err |= __get_user(treg, &sc->sc_lo[3]); mthi3(treg);
2657 err |= __get_user(treg, &sc->sc_dsp); wrdsp(treg, DSP_MASK);
2658 }
2659 #endif
2660
2661 err |= __get_user(used_math, &sc->sc_used_math);
2662 conditional_used_math(used_math);
2663
2664 preempt_disable();
2665
2666 if (used_math()) {
2667 /* restore fpu context if we have used it before */
2668 own_fpu();
2669 err |= restore_fp_context(sc);
2670 } else {
2671 /* signal handler may have used FPU. Give it up. */
2672 lose_fpu();
2673 }
2674
2675 preempt_enable();
2676 #endif
2677 return err;
2678 }
2679 /*
2680 * Determine which stack to use..
2681 */
2682 static inline abi_ulong
2683 get_sigframe(struct target_sigaction *ka, CPUState *regs, size_t frame_size)
2684 {
2685 unsigned long sp;
2686
2687 /* Default to using normal stack */
2688 sp = regs->active_tc.gpr[29];
2689
2690 /*
2691 * FPU emulator may have it's own trampoline active just
2692 * above the user stack, 16-bytes before the next lowest
2693 * 16 byte boundary. Try to avoid trashing it.
2694 */
2695 sp -= 32;
2696
2697 /* This is the X/Open sanctioned signal stack switching. */
2698 if ((ka->sa_flags & TARGET_SA_ONSTACK) && (sas_ss_flags (sp) == 0)) {
2699 sp = target_sigaltstack_used.ss_sp + target_sigaltstack_used.ss_size;
2700 }
2701
2702 return (sp - frame_size) & ~7;
2703 }
2704
2705 /* compare linux/arch/mips/kernel/signal.c:setup_frame() */
2706 static void setup_frame(int sig, struct target_sigaction * ka,
2707 target_sigset_t *set, CPUState *regs)
2708 {
2709 struct sigframe *frame;
2710 abi_ulong frame_addr;
2711 int i;
2712
2713 frame_addr = get_sigframe(ka, regs, sizeof(*frame));
2714 if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
2715 goto give_sigsegv;
2716
2717 install_sigtramp(frame->sf_code, TARGET_NR_sigreturn);
2718
2719 if(setup_sigcontext(regs, &frame->sf_sc))
2720 goto give_sigsegv;
2721
2722 for(i = 0; i < TARGET_NSIG_WORDS; i++) {
2723 if(__put_user(set->sig[i], &frame->sf_mask.sig[i]))
2724 goto give_sigsegv;
2725 }
2726
2727 /*
2728 * Arguments to signal handler:
2729 *
2730 * a0 = signal number
2731 * a1 = 0 (should be cause)
2732 * a2 = pointer to struct sigcontext
2733 *
2734 * $25 and PC point to the signal handler, $29 points to the
2735 * struct sigframe.
2736 */
2737 regs->active_tc.gpr[ 4] = sig;
2738 regs->active_tc.gpr[ 5] = 0;
2739 regs->active_tc.gpr[ 6] = frame_addr + offsetof(struct sigframe, sf_sc);
2740 regs->active_tc.gpr[29] = frame_addr;
2741 regs->active_tc.gpr[31] = frame_addr + offsetof(struct sigframe, sf_code);
2742 /* The original kernel code sets CP0_EPC to the handler
2743 * since it returns to userland using eret
2744 * we cannot do this here, and we must set PC directly */
2745 regs->active_tc.PC = regs->active_tc.gpr[25] = ka->_sa_handler;
2746 unlock_user_struct(frame, frame_addr, 1);
2747 return;
2748
2749 give_sigsegv:
2750 unlock_user_struct(frame, frame_addr, 1);
2751 force_sig(TARGET_SIGSEGV/*, current*/);
2752 return;
2753 }
2754
2755 long do_sigreturn(CPUState *regs)
2756 {
2757 struct sigframe *frame;
2758 abi_ulong frame_addr;
2759 sigset_t blocked;
2760 target_sigset_t target_set;
2761 int i;
2762
2763 #if defined(DEBUG_SIGNAL)
2764 fprintf(stderr, "do_sigreturn\n");
2765 #endif
2766 frame_addr = regs->active_tc.gpr[29];
2767 if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1))
2768 goto badframe;
2769
2770 for(i = 0; i < TARGET_NSIG_WORDS; i++) {
2771 if(__get_user(target_set.sig[i], &frame->sf_mask.sig[i]))
2772 goto badframe;
2773 }
2774
2775 target_to_host_sigset_internal(&blocked, &target_set);
2776 sigprocmask(SIG_SETMASK, &blocked, NULL);
2777
2778 if (restore_sigcontext(regs, &frame->sf_sc))
2779 goto badframe;
2780
2781 #if 0
2782 /*
2783 * Don't let your children do this ...
2784 */
2785 __asm__ __volatile__(
2786 "move\t$29, %0\n\t"
2787 "j\tsyscall_exit"
2788 :/* no outputs */
2789 :"r" (&regs));
2790 /* Unreached */
2791 #endif
2792
2793 regs->active_tc.PC = regs->CP0_EPC;
2794 /* I am not sure this is right, but it seems to work
2795 * maybe a problem with nested signals ? */
2796 regs->CP0_EPC = 0;
2797 return -TARGET_QEMU_ESIGRETURN;
2798
2799 badframe:
2800 force_sig(TARGET_SIGSEGV/*, current*/);
2801 return 0;
2802 }
2803
2804 static void setup_rt_frame(int sig, struct target_sigaction *ka,
2805 target_siginfo_t *info,
2806 target_sigset_t *set, CPUState *env)
2807 {
2808 struct target_rt_sigframe *frame;
2809 abi_ulong frame_addr;
2810 int i;
2811
2812 frame_addr = get_sigframe(ka, env, sizeof(*frame));
2813 if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
2814 goto give_sigsegv;
2815
2816 install_sigtramp(frame->rs_code, TARGET_NR_rt_sigreturn);
2817
2818 copy_siginfo_to_user(&frame->rs_info, info);
2819
2820 __put_user(0, &frame->rs_uc.tuc_flags);
2821 __put_user(0, &frame->rs_uc.tuc_link);
2822 __put_user(target_sigaltstack_used.ss_sp, &frame->rs_uc.tuc_stack.ss_sp);
2823 __put_user(target_sigaltstack_used.ss_size, &frame->rs_uc.tuc_stack.ss_size);
2824 __put_user(sas_ss_flags(get_sp_from_cpustate(env)),
2825 &frame->rs_uc.tuc_stack.ss_flags);
2826
2827 setup_sigcontext(env, &frame->rs_uc.tuc_mcontext);
2828
2829 for(i = 0; i < TARGET_NSIG_WORDS; i++) {
2830 __put_user(set->sig[i], &frame->rs_uc.tuc_sigmask.sig[i]);
2831 }
2832
2833 /*
2834 * Arguments to signal handler:
2835 *
2836 * a0 = signal number
2837 * a1 = pointer to struct siginfo
2838 * a2 = pointer to struct ucontext
2839 *
2840 * $25 and PC point to the signal handler, $29 points to the
2841 * struct sigframe.
2842 */
2843 env->active_tc.gpr[ 4] = sig;
2844 env->active_tc.gpr[ 5] = frame_addr
2845 + offsetof(struct target_rt_sigframe, rs_info);
2846 env->active_tc.gpr[ 6] = frame_addr
2847 + offsetof(struct target_rt_sigframe, rs_uc);
2848 env->active_tc.gpr[29] = frame_addr;
2849 env->active_tc.gpr[31] = frame_addr
2850 + offsetof(struct target_rt_sigframe, rs_code);
2851 /* The original kernel code sets CP0_EPC to the handler
2852 * since it returns to userland using eret
2853 * we cannot do this here, and we must set PC directly */
2854 env->active_tc.PC = env->active_tc.gpr[25] = ka->_sa_handler;
2855 unlock_user_struct(frame, frame_addr, 1);
2856 return;
2857
2858 give_sigsegv:
2859 unlock_user_struct(frame, frame_addr, 1);
2860 force_sig(TARGET_SIGSEGV/*, current*/);
2861 return;
2862 }
2863
2864 long do_rt_sigreturn(CPUState *env)
2865 {
2866 struct target_rt_sigframe *frame;
2867 abi_ulong frame_addr;
2868 sigset_t blocked;
2869
2870 #if defined(DEBUG_SIGNAL)
2871 fprintf(stderr, "do_rt_sigreturn\n");
2872 #endif
2873 frame_addr = env->active_tc.gpr[29];
2874 if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1))
2875 goto badframe;
2876
2877 target_to_host_sigset(&blocked, &frame->rs_uc.tuc_sigmask);
2878 sigprocmask(SIG_SETMASK, &blocked, NULL);
2879
2880 if (restore_sigcontext(env, &frame->rs_uc.tuc_mcontext))
2881 goto badframe;
2882
2883 if (do_sigaltstack(frame_addr +
2884 offsetof(struct target_rt_sigframe, rs_uc.tuc_stack),
2885 0, get_sp_from_cpustate(env)) == -EFAULT)
2886 goto badframe;
2887
2888 env->active_tc.PC = env->CP0_EPC;
2889 /* I am not sure this is right, but it seems to work
2890 * maybe a problem with nested signals ? */
2891 env->CP0_EPC = 0;
2892 return -TARGET_QEMU_ESIGRETURN;
2893
2894 badframe:
2895 force_sig(TARGET_SIGSEGV/*, current*/);
2896 return 0;
2897 }
2898
2899 #elif defined(TARGET_SH4)
2900
2901 /*
2902 * code and data structures from linux kernel:
2903 * include/asm-sh/sigcontext.h
2904 * arch/sh/kernel/signal.c
2905 */
2906
2907 struct target_sigcontext {
2908 target_ulong oldmask;
2909
2910 /* CPU registers */
2911 target_ulong sc_gregs[16];
2912 target_ulong sc_pc;
2913 target_ulong sc_pr;
2914 target_ulong sc_sr;
2915 target_ulong sc_gbr;
2916 target_ulong sc_mach;
2917 target_ulong sc_macl;
2918
2919 /* FPU registers */
2920 target_ulong sc_fpregs[16];
2921 target_ulong sc_xfpregs[16];
2922 unsigned int sc_fpscr;
2923 unsigned int sc_fpul;
2924 unsigned int sc_ownedfp;
2925 };
2926
2927 struct target_sigframe
2928 {
2929 struct target_sigcontext sc;
2930 target_ulong extramask[TARGET_NSIG_WORDS-1];
2931 uint16_t retcode[3];
2932 };
2933
2934
2935 struct target_ucontext {
2936 target_ulong tuc_flags;
2937 struct target_ucontext *tuc_link;
2938 target_stack_t tuc_stack;
2939 struct target_sigcontext tuc_mcontext;
2940 target_sigset_t tuc_sigmask; /* mask last for extensibility */
2941 };
2942
2943 struct target_rt_sigframe
2944 {
2945 struct target_siginfo info;
2946 struct target_ucontext uc;
2947 uint16_t retcode[3];
2948 };
2949
2950
2951 #define MOVW(n) (0x9300|((n)-2)) /* Move mem word at PC+n to R3 */
2952 #define TRAP_NOARG 0xc310 /* Syscall w/no args (NR in R3) SH3/4 */
2953
2954 static abi_ulong get_sigframe(struct target_sigaction *ka,
2955 unsigned long sp, size_t frame_size)
2956 {
2957 if ((ka->sa_flags & TARGET_SA_ONSTACK) && (sas_ss_flags(sp) == 0)) {
2958 sp = target_sigaltstack_used.ss_sp + target_sigaltstack_used.ss_size;
2959 }
2960
2961 return (sp - frame_size) & -8ul;
2962 }
2963
2964 static int setup_sigcontext(struct target_sigcontext *sc,
2965 CPUState *regs, unsigned long mask)
2966 {
2967 int err = 0;
2968 int i;
2969
2970 #define COPY(x) err |= __put_user(regs->x, &sc->sc_##x)
2971 COPY(gregs[0]); COPY(gregs[1]);
2972 COPY(gregs[2]); COPY(gregs[3]);
2973 COPY(gregs[4]); COPY(gregs[5]);
2974 COPY(gregs[6]); COPY(gregs[7]);
2975 COPY(gregs[8]); COPY(gregs[9]);
2976 COPY(gregs[10]); COPY(gregs[11]);
2977 COPY(gregs[12]); COPY(gregs[13]);
2978 COPY(gregs[14]); COPY(gregs[15]);
2979 COPY(gbr); COPY(mach);
2980 COPY(macl); COPY(pr);
2981 COPY(sr); COPY(pc);
2982 #undef COPY
2983
2984 for (i=0; i<16; i++) {
2985 err |= __put_user(regs->fregs[i], &sc->sc_fpregs[i]);
2986 }
2987 err |= __put_user(regs->fpscr, &sc->sc_fpscr);
2988 err |= __put_user(regs->fpul, &sc->sc_fpul);
2989
2990 /* non-iBCS2 extensions.. */
2991 err |= __put_user(mask, &sc->oldmask);
2992
2993 return err;
2994 }
2995
2996 static int restore_sigcontext(CPUState *regs, struct target_sigcontext *sc,
2997 target_ulong *r0_p)
2998 {
2999 unsigned int err = 0;
3000 int i;
3001
3002 #define COPY(x) err |= __get_user(regs->x, &sc->sc_##x)
3003 COPY(gregs[1]);
3004 COPY(gregs[2]); COPY(gregs[3]);
3005 COPY(gregs[4]); COPY(gregs[5]);
3006 COPY(gregs[6]); COPY(gregs[7]);
3007 COPY(gregs[8]); COPY(gregs[9]);
3008 COPY(gregs[10]); COPY(gregs[11]);
3009 COPY(gregs[12]); COPY(gregs[13]);
3010 COPY(gregs[14]); COPY(gregs[15]);
3011 COPY(gbr); COPY(mach);
3012 COPY(macl); COPY(pr);
3013 COPY(sr); COPY(pc);
3014 #undef COPY
3015
3016 for (i=0; i<16; i++) {
3017 err |= __get_user(regs->fregs[i], &sc->sc_fpregs[i]);
3018 }
3019 err |= __get_user(regs->fpscr, &sc->sc_fpscr);
3020 err |= __get_user(regs->fpul, &sc->sc_fpul);
3021
3022 regs->tra = -1; /* disable syscall checks */
3023 err |= __get_user(*r0_p, &sc->sc_gregs[0]);
3024 return err;
3025 }
3026
3027 static void setup_frame(int sig, struct target_sigaction *ka,
3028 target_sigset_t *set, CPUState *regs)
3029 {
3030 struct target_sigframe *frame;
3031 abi_ulong frame_addr;
3032 int i;
3033 int err = 0;
3034 int signal;
3035
3036 frame_addr = get_sigframe(ka, regs->gregs[15], sizeof(*frame));
3037 if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
3038 goto give_sigsegv;
3039
3040 signal = current_exec_domain_sig(sig);
3041
3042 err |= setup_sigcontext(&frame->sc, regs, set->sig[0]);
3043
3044 for (i = 0; i < TARGET_NSIG_WORDS - 1; i++) {
3045 err |= __put_user(set->sig[i + 1], &frame->extramask[i]);
3046 }
3047
3048 /* Set up to return from userspace. If provided, use a stub
3049 already in userspace. */
3050 if (ka->sa_flags & TARGET_SA_RESTORER) {
3051 regs->pr = (unsigned long) ka->sa_restorer;
3052 } else {
3053 /* Generate return code (system call to sigreturn) */
3054 err |= __put_user(MOVW(2), &frame->retcode[0]);
3055 err |= __put_user(TRAP_NOARG, &frame->retcode[1]);
3056 err |= __put_user((TARGET_NR_sigreturn), &frame->retcode[2]);
3057 regs->pr = (unsigned long) frame->retcode;
3058 }
3059
3060 if (err)
3061 goto give_sigsegv;
3062
3063 /* Set up registers for signal handler */
3064 regs->gregs[15] = (unsigned long) frame;
3065 regs->gregs[4] = signal; /* Arg for signal handler */
3066 regs->gregs[5] = 0;
3067 regs->gregs[6] = (unsigned long) &frame->sc;
3068 regs->pc = (unsigned long) ka->_sa_handler;
3069
3070 unlock_user_struct(frame, frame_addr, 1);
3071 return;
3072
3073 give_sigsegv:
3074 unlock_user_struct(frame, frame_addr, 1);
3075 force_sig(TARGET_SIGSEGV);
3076 }
3077
3078 static void setup_rt_frame(int sig, struct target_sigaction *ka,
3079 target_siginfo_t *info,
3080 target_sigset_t *set, CPUState *regs)
3081 {
3082 struct target_rt_sigframe *frame;
3083 abi_ulong frame_addr;
3084 int i;
3085 int err = 0;
3086 int signal;
3087
3088 frame_addr = get_sigframe(ka, regs->gregs[15], sizeof(*frame));
3089 if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
3090 goto give_sigsegv;
3091
3092 signal = current_exec_domain_sig(sig);
3093
3094 err |= copy_siginfo_to_user(&frame->info, info);
3095
3096 /* Create the ucontext. */
3097 err |= __put_user(0, &frame->uc.tuc_flags);
3098 err |= __put_user(0, (unsigned long *)&frame->uc.tuc_link);
3099 err |= __put_user((unsigned long)target_sigaltstack_used.ss_sp,
3100 &frame->uc.tuc_stack.ss_sp);
3101 err |= __put_user(sas_ss_flags(regs->gregs[15]),
3102 &frame->uc.tuc_stack.ss_flags);
3103 err |= __put_user(target_sigaltstack_used.ss_size,
3104 &frame->uc.tuc_stack.ss_size);
3105 err |= setup_sigcontext(&frame->uc.tuc_mcontext,
3106 regs, set->sig[0]);
3107 for(i = 0; i < TARGET_NSIG_WORDS; i++) {
3108 err |= __put_user(set->sig[i], &frame->uc.tuc_sigmask.sig[i]);
3109 }
3110
3111 /* Set up to return from userspace. If provided, use a stub
3112 already in userspace. */
3113 if (ka->sa_flags & TARGET_SA_RESTORER) {
3114 regs->pr = (unsigned long) ka->sa_restorer;
3115 } else {
3116 /* Generate return code (system call to sigreturn) */
3117 err |= __put_user(MOVW(2), &frame->retcode[0]);
3118 err |= __put_user(TRAP_NOARG, &frame->retcode[1]);
3119 err |= __put_user((TARGET_NR_rt_sigreturn), &frame->retcode[2]);
3120 regs->pr = (unsigned long) frame->retcode;
3121 }
3122
3123 if (err)
3124 goto give_sigsegv;
3125
3126 /* Set up registers for signal handler */
3127 regs->gregs[15] = (unsigned long) frame;
3128 regs->gregs[4] = signal; /* Arg for signal handler */
3129 regs->gregs[5] = (unsigned long) &frame->info;
3130 regs->gregs[6] = (unsigned long) &frame->uc;
3131 regs->pc = (unsigned long) ka->_sa_handler;
3132
3133 unlock_user_struct(frame, frame_addr, 1);
3134 return;
3135
3136 give_sigsegv:
3137 unlock_user_struct(frame, frame_addr, 1);
3138 force_sig(TARGET_SIGSEGV);
3139 }
3140
3141 long do_sigreturn(CPUState *regs)
3142 {
3143 struct target_sigframe *frame;
3144 abi_ulong frame_addr;
3145 sigset_t blocked;
3146 target_sigset_t target_set;
3147 target_ulong r0;
3148 int i;
3149 int err = 0;
3150
3151 #if defined(DEBUG_SIGNAL)
3152 fprintf(stderr, "do_sigreturn\n");
3153 #endif
3154 frame_addr = regs->gregs[15];
3155 if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1))
3156 goto badframe;
3157
3158 err |= __get_user(target_set.sig[0], &frame->sc.oldmask);
3159 for(i = 1; i < TARGET_NSIG_WORDS; i++) {
3160 err |= (__get_user(target_set.sig[i], &frame->extramask[i - 1]));
3161 }
3162
3163 if (err)
3164 goto badframe;
3165
3166 target_to_host_sigset_internal(&blocked, &target_set);
3167 sigprocmask(SIG_SETMASK, &blocked, NULL);
3168
3169 if (restore_sigcontext(regs, &frame->sc, &r0))
3170 goto badframe;
3171
3172 unlock_user_struct(frame, frame_addr, 0);
3173 return r0;
3174
3175 badframe:
3176 unlock_user_struct(frame, frame_addr, 0);
3177 force_sig(TARGET_SIGSEGV);
3178 return 0;
3179 }
3180
3181 long do_rt_sigreturn(CPUState *regs)
3182 {
3183 struct target_rt_sigframe *frame;
3184 abi_ulong frame_addr;
3185 sigset_t blocked;
3186 target_ulong r0;
3187
3188 #if defined(DEBUG_SIGNAL)
3189 fprintf(stderr, "do_rt_sigreturn\n");
3190 #endif
3191 frame_addr = regs->gregs[15];
3192 if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1))
3193 goto badframe;
3194
3195 target_to_host_sigset(&blocked, &frame->uc.tuc_sigmask);
3196 sigprocmask(SIG_SETMASK, &blocked, NULL);
3197
3198 if (restore_sigcontext(regs, &frame->uc.tuc_mcontext, &r0))
3199 goto badframe;
3200
3201 if (do_sigaltstack(frame_addr +
3202 offsetof(struct target_rt_sigframe, uc.tuc_stack),
3203 0, get_sp_from_cpustate(regs)) == -EFAULT)
3204 goto badframe;
3205
3206 unlock_user_struct(frame, frame_addr, 0);
3207 return r0;
3208
3209 badframe:
3210 unlock_user_struct(frame, frame_addr, 0);
3211 force_sig(TARGET_SIGSEGV);
3212 return 0;
3213 }
3214 #elif defined(TARGET_MICROBLAZE)
3215
3216 struct target_sigcontext {
3217 struct target_pt_regs regs; /* needs to be first */
3218 uint32_t oldmask;
3219 };
3220
3221 struct target_stack_t {
3222 abi_ulong ss_sp;
3223 int ss_flags;
3224 unsigned int ss_size;
3225 };
3226
3227 struct target_ucontext {
3228 abi_ulong tuc_flags;
3229 abi_ulong tuc_link;
3230 struct target_stack_t tuc_stack;
3231 struct target_sigcontext tuc_mcontext;
3232 uint32_t tuc_extramask[TARGET_NSIG_WORDS - 1];
3233 };
3234
3235 /* Signal frames. */
3236 struct target_signal_frame {
3237 struct target_ucontext uc;
3238 uint32_t extramask[TARGET_NSIG_WORDS - 1];
3239 uint32_t tramp[2];
3240 };
3241
3242 struct rt_signal_frame {
3243 struct siginfo info;
3244 struct ucontext uc;
3245 uint32_t tramp[2];
3246 };
3247
3248 static void setup_sigcontext(struct target_sigcontext *sc, CPUState *env)
3249 {
3250 __put_user(env->regs[0], &sc->regs.r0);
3251 __put_user(env->regs[1], &sc->regs.r1);
3252 __put_user(env->regs[2], &sc->regs.r2);
3253 __put_user(env->regs[3], &sc->regs.r3);
3254 __put_user(env->regs[4], &sc->regs.r4);
3255 __put_user(env->regs[5], &sc->regs.r5);
3256 __put_user(env->regs[6], &sc->regs.r6);
3257 __put_user(env->regs[7], &sc->regs.r7);
3258 __put_user(env->regs[8], &sc->regs.r8);
3259 __put_user(env->regs[9], &sc->regs.r9);
3260 __put_user(env->regs[10], &sc->regs.r10);
3261 __put_user(env->regs[11], &sc->regs.r11);
3262 __put_user(env->regs[12], &sc->regs.r12);
3263 __put_user(env->regs[13], &sc->regs.r13);
3264 __put_user(env->regs[14], &sc->regs.r14);
3265 __put_user(env->regs[15], &sc->regs.r15);
3266 __put_user(env->regs[16], &sc->regs.r16);
3267 __put_user(env->regs[17], &sc->regs.r17);
3268 __put_user(env->regs[18], &sc->regs.r18);
3269 __put_user(env->regs[19], &sc->regs.r19);
3270 __put_user(env->regs[20], &sc->regs.r20);
3271 __put_user(env->regs[21], &sc->regs.r21);
3272 __put_user(env->regs[22], &sc->regs.r22);
3273 __put_user(env->regs[23], &sc->regs.r23);
3274 __put_user(env->regs[24], &sc->regs.r24);
3275 __put_user(env->regs[25], &sc->regs.r25);
3276 __put_user(env->regs[26], &sc->regs.r26);
3277 __put_user(env->regs[27], &sc->regs.r27);
3278 __put_user(env->regs[28], &sc->regs.r28);
3279 __put_user(env->regs[29], &sc->regs.r29);
3280 __put_user(env->regs[30], &sc->regs.r30);
3281 __put_user(env->regs[31], &sc->regs.r31);
3282 __put_user(env->sregs[SR_PC], &sc->regs.pc);
3283 }
3284
3285 static void restore_sigcontext(struct target_sigcontext *sc, CPUState *env)
3286 {
3287 __get_user(env->regs[0], &sc->regs.r0);
3288 __get_user(env->regs[1], &sc->regs.r1);
3289 __get_user(env->regs[2], &sc->regs.r2);
3290 __get_user(env->regs[3], &sc->regs.r3);
3291 __get_user(env->regs[4], &sc->regs.r4);
3292 __get_user(env->regs[5], &sc->regs.r5);
3293 __get_user(env->regs[6], &sc->regs.r6);
3294 __get_user(env->regs[7], &sc->regs.r7);
3295 __get_user(env->regs[8], &sc->regs.r8);
3296 __get_user(env->regs[9], &sc->regs.r9);
3297 __get_user(env->regs[10], &sc->regs.r10);
3298 __get_user(env->regs[11], &sc->regs.r11);
3299 __get_user(env->regs[12], &sc->regs.r12);
3300 __get_user(env->regs[13], &sc->regs.r13);
3301 __get_user(env->regs[14], &sc->regs.r14);
3302 __get_user(env->regs[15], &sc->regs.r15);
3303 __get_user(env->regs[16], &sc->regs.r16);
3304 __get_user(env->regs[17], &sc->regs.r17);
3305 __get_user(env->regs[18], &sc->regs.r18);
3306 __get_user(env->regs[19], &sc->regs.r19);
3307 __get_user(env->regs[20], &sc->regs.r20);
3308 __get_user(env->regs[21], &sc->regs.r21);
3309 __get_user(env->regs[22], &sc->regs.r22);
3310 __get_user(env->regs[23], &sc->regs.r23);
3311 __get_user(env->regs[24], &sc->regs.r24);
3312 __get_user(env->regs[25], &sc->regs.r25);
3313 __get_user(env->regs[26], &sc->regs.r26);
3314 __get_user(env->regs[27], &sc->regs.r27);
3315 __get_user(env->regs[28], &sc->regs.r28);
3316 __get_user(env->regs[29], &sc->regs.r29);
3317 __get_user(env->regs[30], &sc->regs.r30);
3318 __get_user(env->regs[31], &sc->regs.r31);
3319 __get_user(env->sregs[SR_PC], &sc->regs.pc);
3320 }
3321
3322 static abi_ulong get_sigframe(struct target_sigaction *ka,
3323 CPUState *env, int frame_size)
3324 {
3325 abi_ulong sp = env->regs[1];
3326
3327 if ((ka->sa_flags & SA_ONSTACK) != 0 && !on_sig_stack(sp))
3328 sp = target_sigaltstack_used.ss_sp + target_sigaltstack_used.ss_size;
3329
3330 return ((sp - frame_size) & -8UL);
3331 }
3332
3333 static void setup_frame(int sig, struct target_sigaction *ka,
3334 target_sigset_t *set, CPUState *env)
3335 {
3336 struct target_signal_frame *frame;
3337 abi_ulong frame_addr;
3338 int err = 0;
3339 int i;
3340
3341 frame_addr = get_sigframe(ka, env, sizeof *frame);
3342 if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
3343 goto badframe;
3344
3345 /* Save the mask. */
3346 err |= __put_user(set->sig[0], &frame->uc.tuc_mcontext.oldmask);
3347 if (err)
3348 goto badframe;
3349
3350 for(i = 1; i < TARGET_NSIG_WORDS; i++) {
3351 if (__put_user(set->sig[i], &frame->extramask[i - 1]))
3352 goto badframe;
3353 }
3354
3355 setup_sigcontext(&frame->uc.tuc_mcontext, env);
3356
3357 /* Set up to return from userspace. If provided, use a stub
3358 already in userspace. */
3359 /* minus 8 is offset to cater for "rtsd r15,8" offset */
3360 if (ka->sa_flags & TARGET_SA_RESTORER) {
3361 env->regs[15] = ((unsigned long)ka->sa_restorer)-8;
3362 } else {
3363 uint32_t t;
3364 /* Note, these encodings are _big endian_! */
3365 /* addi r12, r0, __NR_sigreturn */
3366 t = 0x31800000UL | TARGET_NR_sigreturn;
3367 err |= __put_user(t, frame->tramp + 0);
3368 /* brki r14, 0x8 */
3369 t = 0xb9cc0008UL;
3370 err |= __put_user(t, frame->tramp + 1);
3371
3372 /* Return from sighandler will jump to the tramp.
3373 Negative 8 offset because return is rtsd r15, 8 */
3374 env->regs[15] = ((unsigned long)frame->tramp) - 8;
3375 }
3376
3377 if (err)
3378 goto badframe;
3379
3380 /* Set up registers for signal handler */
3381 env->regs[1] = (unsigned long) frame;
3382 /* Signal handler args: */
3383 env->regs[5] = sig; /* Arg 0: signum */
3384 env->regs[6] = 0;
3385 env->regs[7] = (unsigned long) &frame->uc; /* arg 1: sigcontext */
3386
3387 /* Offset of 4 to handle microblaze rtid r14, 0 */
3388 env->sregs[SR_PC] = (unsigned long)ka->_sa_handler;
3389
3390 unlock_user_struct(frame, frame_addr, 1);
3391 return;
3392 badframe:
3393 unlock_user_struct(frame, frame_addr, 1);
3394 force_sig(TARGET_SIGSEGV);
3395 }
3396
3397 static void setup_rt_frame(int sig, struct target_sigaction *ka,
3398 target_siginfo_t *info,
3399 target_sigset_t *set, CPUState *env)
3400 {
3401 fprintf(stderr, "Microblaze setup_rt_frame: not implemented\n");
3402 }
3403
3404 long do_sigreturn(CPUState *env)
3405 {
3406 struct target_signal_frame *frame;
3407 abi_ulong frame_addr;
3408 target_sigset_t target_set;
3409 sigset_t set;
3410 int i;
3411
3412 frame_addr = env->regs[R_SP];
3413 /* Make sure the guest isn't playing games. */
3414 if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 1))
3415 goto badframe;
3416
3417 /* Restore blocked signals */
3418 if (__get_user(target_set.sig[0], &frame->uc.tuc_mcontext.oldmask))
3419 goto badframe;
3420 for(i = 1; i < TARGET_NSIG_WORDS; i++) {
3421 if (__get_user(target_set.sig[i], &frame->extramask[i - 1]))
3422 goto badframe;
3423 }
3424 target_to_host_sigset_internal(&set, &target_set);
3425 sigprocmask(SIG_SETMASK, &set, NULL);
3426
3427 restore_sigcontext(&frame->uc.tuc_mcontext, env);
3428 /* We got here through a sigreturn syscall, our path back is via an
3429 rtb insn so setup r14 for that. */
3430 env->regs[14] = env->sregs[SR_PC];
3431
3432 unlock_user_struct(frame, frame_addr, 0);
3433 return env->regs[10];
3434 badframe:
3435 unlock_user_struct(frame, frame_addr, 0);
3436 force_sig(TARGET_SIGSEGV);
3437 }
3438
3439 long do_rt_sigreturn(CPUState *env)
3440 {
3441 fprintf(stderr, "Microblaze do_rt_sigreturn: not implemented\n");
3442 return -TARGET_ENOSYS;
3443 }
3444
3445 #elif defined(TARGET_CRIS)
3446
3447 struct target_sigcontext {
3448 struct target_pt_regs regs; /* needs to be first */
3449 uint32_t oldmask;
3450 uint32_t usp; /* usp before stacking this gunk on it */
3451 };
3452
3453 /* Signal frames. */
3454 struct target_signal_frame {
3455 struct target_sigcontext sc;
3456 uint32_t extramask[TARGET_NSIG_WORDS - 1];
3457 uint8_t retcode[8]; /* Trampoline code. */
3458 };
3459
3460 struct rt_signal_frame {
3461 struct siginfo *pinfo;
3462 void *puc;
3463 struct siginfo info;
3464 struct ucontext uc;
3465 uint8_t retcode[8]; /* Trampoline code. */
3466 };
3467
3468 static void setup_sigcontext(struct target_sigcontext *sc, CPUState *env)
3469 {
3470 __put_user(env->regs[0], &sc->regs.r0);
3471 __put_user(env->regs[1], &sc->regs.r1);
3472 __put_user(env->regs[2], &sc->regs.r2);
3473 __put_user(env->regs[3], &sc->regs.r3);
3474 __put_user(env->regs[4], &sc->regs.r4);
3475 __put_user(env->regs[5], &sc->regs.r5);
3476 __put_user(env->regs[6], &sc->regs.r6);
3477 __put_user(env->regs[7], &sc->regs.r7);
3478 __put_user(env->regs[8], &sc->regs.r8);
3479 __put_user(env->regs[9], &sc->regs.r9);
3480 __put_user(env->regs[10], &sc->regs.r10);
3481 __put_user(env->regs[11], &sc->regs.r11);
3482 __put_user(env->regs[12], &sc->regs.r12);
3483 __put_user(env->regs[13], &sc->regs.r13);
3484 __put_user(env->regs[14], &sc->usp);
3485 __put_user(env->regs[15], &sc->regs.acr);
3486 __put_user(env->pregs[PR_MOF], &sc->regs.mof);
3487 __put_user(env->pregs[PR_SRP], &sc->regs.srp);
3488 __put_user(env->pc, &sc->regs.erp);
3489 }
3490
3491 static void restore_sigcontext(struct target_sigcontext *sc, CPUState *env)
3492 {
3493 __get_user(env->regs[0], &sc->regs.r0);
3494 __get_user(env->regs[1], &sc->regs.r1);
3495 __get_user(env->regs[2], &sc->regs.r2);
3496 __get_user(env->regs[3], &sc->regs.r3);
3497 __get_user(env->regs[4], &sc->regs.r4);
3498 __get_user(env->regs[5], &sc->regs.r5);
3499 __get_user(env->regs[6], &sc->regs.r6);
3500 __get_user(env->regs[7], &sc->regs.r7);
3501 __get_user(env->regs[8], &sc->regs.r8);
3502 __get_user(env->regs[9], &sc->regs.r9);
3503 __get_user(env->regs[10], &sc->regs.r10);
3504 __get_user(env->regs[11], &sc->regs.r11);
3505 __get_user(env->regs[12], &sc->regs.r12);
3506 __get_user(env->regs[13], &sc->regs.r13);
3507 __get_user(env->regs[14], &sc->usp);
3508 __get_user(env->regs[15], &sc->regs.acr);
3509 __get_user(env->pregs[PR_MOF], &sc->regs.mof);
3510 __get_user(env->pregs[PR_SRP], &sc->regs.srp);
3511 __get_user(env->pc, &sc->regs.erp);
3512 }
3513
3514 static abi_ulong get_sigframe(CPUState *env, int framesize)
3515 {
3516 abi_ulong sp;
3517 /* Align the stack downwards to 4. */
3518 sp = (env->regs[R_SP] & ~3);
3519 return sp - framesize;
3520 }
3521
3522 static void setup_frame(int sig, struct target_sigaction *ka,
3523 target_sigset_t *set, CPUState *env)
3524 {
3525 struct target_signal_frame *frame;
3526 abi_ulong frame_addr;
3527 int err = 0;
3528 int i;
3529
3530 frame_addr = get_sigframe(env, sizeof *frame);
3531 if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
3532 goto badframe;
3533
3534 /*
3535 * The CRIS signal return trampoline. A real linux/CRIS kernel doesn't
3536 * use this trampoline anymore but it sets it up for GDB.
3537 * In QEMU, using the trampoline simplifies things a bit so we use it.
3538 *
3539 * This is movu.w __NR_sigreturn, r9; break 13;
3540 */
3541 err |= __put_user(0x9c5f, frame->retcode+0);
3542 err |= __put_user(TARGET_NR_sigreturn,
3543 frame->retcode+2);
3544 err |= __put_user(0xe93d, frame->retcode+4);
3545
3546 /* Save the mask. */
3547 err |= __put_user(set->sig[0], &frame->sc.oldmask);
3548 if (err)
3549 goto badframe;
3550
3551 for(i = 1; i < TARGET_NSIG_WORDS; i++) {
3552 if (__put_user(set->sig[i], &frame->extramask[i - 1]))
3553 goto badframe;
3554 }
3555
3556 setup_sigcontext(&frame->sc, env);
3557
3558 /* Move the stack and setup the arguments for the handler. */
3559 env->regs[R_SP] = (uint32_t) (unsigned long) frame;
3560 env->regs[10] = sig;
3561 env->pc = (unsigned long) ka->_sa_handler;
3562 /* Link SRP so the guest returns through the trampoline. */
3563 env->pregs[PR_SRP] = (uint32_t) (unsigned long) &frame->retcode[0];
3564
3565 unlock_user_struct(frame, frame_addr, 1);
3566 return;
3567 badframe:
3568 unlock_user_struct(frame, frame_addr, 1);
3569 force_sig(TARGET_SIGSEGV);
3570 }
3571
3572 static void setup_rt_frame(int sig, struct target_sigaction *ka,
3573 target_siginfo_t *info,
3574 target_sigset_t *set, CPUState *env)
3575 {
3576 fprintf(stderr, "CRIS setup_rt_frame: not implemented\n");
3577 }
3578
3579 long do_sigreturn(CPUState *env)
3580 {
3581 struct target_signal_frame *frame;
3582 abi_ulong frame_addr;
3583 target_sigset_t target_set;
3584 sigset_t set;
3585 int i;
3586
3587 frame_addr = env->regs[R_SP];
3588 /* Make sure the guest isn't playing games. */
3589 if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 1))
3590 goto badframe;
3591
3592 /* Restore blocked signals */
3593 if (__get_user(target_set.sig[0], &frame->sc.oldmask))
3594 goto badframe;
3595 for(i = 1; i < TARGET_NSIG_WORDS; i++) {
3596 if (__get_user(target_set.sig[i], &frame->extramask[i - 1]))
3597 goto badframe;
3598 }
3599 target_to_host_sigset_internal(&set, &target_set);
3600 sigprocmask(SIG_SETMASK, &set, NULL);
3601
3602 restore_sigcontext(&frame->sc, env);
3603 unlock_user_struct(frame, frame_addr, 0);
3604 return env->regs[10];
3605 badframe:
3606 unlock_user_struct(frame, frame_addr, 0);
3607 force_sig(TARGET_SIGSEGV);
3608 }
3609
3610 long do_rt_sigreturn(CPUState *env)
3611 {
3612 fprintf(stderr, "CRIS do_rt_sigreturn: not implemented\n");
3613 return -TARGET_ENOSYS;
3614 }
3615
3616 #elif defined(TARGET_PPC) && !defined(TARGET_PPC64)
3617
3618 /* FIXME: Many of the structures are defined for both PPC and PPC64, but
3619 the signal handling is different enough that we haven't implemented
3620 support for PPC64 yet. Hence the restriction above.
3621
3622 There are various #if'd blocks for code for TARGET_PPC64. These
3623 blocks should go away so that we can successfully run 32-bit and
3624 64-bit binaries on a QEMU configured for PPC64. */
3625
3626 /* Size of dummy stack frame allocated when calling signal handler.
3627 See arch/powerpc/include/asm/ptrace.h. */
3628 #if defined(TARGET_PPC64)
3629 #define SIGNAL_FRAMESIZE 128
3630 #else
3631 #define SIGNAL_FRAMESIZE 64
3632 #endif
3633
3634 /* See arch/powerpc/include/asm/sigcontext.h. */
3635 struct target_sigcontext {
3636 target_ulong _unused[4];
3637 int32_t signal;
3638 #if defined(TARGET_PPC64)
3639 int32_t pad0;
3640 #endif
3641 target_ulong handler;
3642 target_ulong oldmask;
3643 target_ulong regs; /* struct pt_regs __user * */
3644 /* TODO: PPC64 includes extra bits here. */
3645 };
3646
3647 /* Indices for target_mcontext.mc_gregs, below.
3648 See arch/powerpc/include/asm/ptrace.h for details. */
3649 enum {
3650 TARGET_PT_R0 = 0,
3651 TARGET_PT_R1 = 1,
3652 TARGET_PT_R2 = 2,
3653 TARGET_PT_R3 = 3,
3654 TARGET_PT_R4 = 4,
3655 TARGET_PT_R5 = 5,
3656 TARGET_PT_R6 = 6,
3657 TARGET_PT_R7 = 7,
3658 TARGET_PT_R8 = 8,
3659 TARGET_PT_R9 = 9,
3660 TARGET_PT_R10 = 10,
3661 TARGET_PT_R11 = 11,
3662 TARGET_PT_R12 = 12,
3663 TARGET_PT_R13 = 13,
3664 TARGET_PT_R14 = 14,
3665 TARGET_PT_R15 = 15,
3666 TARGET_PT_R16 = 16,
3667 TARGET_PT_R17 = 17,
3668 TARGET_PT_R18 = 18,
3669 TARGET_PT_R19 = 19,
3670 TARGET_PT_R20 = 20,
3671 TARGET_PT_R21 = 21,
3672 TARGET_PT_R22 = 22,
3673 TARGET_PT_R23 = 23,
3674 TARGET_PT_R24 = 24,
3675 TARGET_PT_R25 = 25,
3676 TARGET_PT_R26 = 26,
3677 TARGET_PT_R27 = 27,
3678 TARGET_PT_R28 = 28,
3679 TARGET_PT_R29 = 29,
3680 TARGET_PT_R30 = 30,
3681 TARGET_PT_R31 = 31,
3682 TARGET_PT_NIP = 32,
3683 TARGET_PT_MSR = 33,
3684 TARGET_PT_ORIG_R3 = 34,
3685 TARGET_PT_CTR = 35,
3686 TARGET_PT_LNK = 36,
3687 TARGET_PT_XER = 37,
3688 TARGET_PT_CCR = 38,
3689 /* Yes, there are two registers with #39. One is 64-bit only. */
3690 TARGET_PT_MQ = 39,
3691 TARGET_PT_SOFTE = 39,
3692 TARGET_PT_TRAP = 40,
3693 TARGET_PT_DAR = 41,
3694 TARGET_PT_DSISR = 42,
3695 TARGET_PT_RESULT = 43,
3696 TARGET_PT_REGS_COUNT = 44
3697 };
3698
3699 /* See arch/powerpc/include/asm/ucontext.h. Only used for 32-bit PPC;
3700 on 64-bit PPC, sigcontext and mcontext are one and the same. */
3701 struct target_mcontext {
3702 target_ulong mc_gregs[48];
3703 /* Includes fpscr. */
3704 uint64_t mc_fregs[33];
3705 target_ulong mc_pad[2];
3706 /* We need to handle Altivec and SPE at the same time, which no
3707 kernel needs to do. Fortunately, the kernel defines this bit to
3708 be Altivec-register-large all the time, rather than trying to
3709 twiddle it based on the specific platform. */
3710 union {
3711 /* SPE vector registers. One extra for SPEFSCR. */
3712 uint32_t spe[33];
3713 /* Altivec vector registers. The packing of VSCR and VRSAVE
3714 varies depending on whether we're PPC64 or not: PPC64 splits
3715 them apart; PPC32 stuffs them together. */
3716 #if defined(TARGET_PPC64)
3717 #define QEMU_NVRREG 34
3718 #else
3719 #define QEMU_NVRREG 33
3720 #endif
3721 ppc_avr_t altivec[QEMU_NVRREG];
3722 #undef QEMU_NVRREG
3723 } mc_vregs __attribute__((__aligned__(16)));
3724 };
3725
3726 struct target_ucontext {
3727 target_ulong tuc_flags;
3728 target_ulong tuc_link; /* struct ucontext __user * */
3729 struct target_sigaltstack tuc_stack;
3730 #if !defined(TARGET_PPC64)
3731 int32_t tuc_pad[7];
3732 target_ulong tuc_regs; /* struct mcontext __user *
3733 points to uc_mcontext field */
3734 #endif
3735 target_sigset_t tuc_sigmask;
3736 #if defined(TARGET_PPC64)
3737 target_sigset_t unused[15]; /* Allow for uc_sigmask growth */
3738 struct target_sigcontext tuc_mcontext;
3739 #else
3740 int32_t tuc_maskext[30];
3741 int32_t tuc_pad2[3];
3742 struct target_mcontext tuc_mcontext;
3743 #endif
3744 };
3745
3746 /* See arch/powerpc/kernel/signal_32.c. */
3747 struct target_sigframe {
3748 struct target_sigcontext sctx;
3749 struct target_mcontext mctx;
3750 int32_t abigap[56];
3751 };
3752
3753 struct target_rt_sigframe {
3754 struct target_siginfo info;
3755 struct target_ucontext uc;
3756 int32_t abigap[56];
3757 };
3758
3759 /* We use the mc_pad field for the signal return trampoline. */
3760 #define tramp mc_pad
3761
3762 /* See arch/powerpc/kernel/signal.c. */
3763 static target_ulong get_sigframe(struct target_sigaction *ka,
3764 CPUState *env,
3765 int frame_size)
3766 {
3767 target_ulong oldsp, newsp;
3768
3769 oldsp = env->gpr[1];
3770
3771 if ((ka->sa_flags & TARGET_SA_ONSTACK) &&
3772 (sas_ss_flags(oldsp))) {
3773 oldsp = (target_sigaltstack_used.ss_sp
3774 + target_sigaltstack_used.ss_size);
3775 }
3776
3777 newsp = (oldsp - frame_size) & ~0xFUL;
3778
3779 return newsp;
3780 }
3781
3782 static int save_user_regs(CPUState *env, struct target_mcontext *frame,
3783 int sigret)
3784 {
3785 target_ulong msr = env->msr;
3786 int i;
3787 target_ulong ccr = 0;
3788
3789 /* In general, the kernel attempts to be intelligent about what it
3790 needs to save for Altivec/FP/SPE registers. We don't care that
3791 much, so we just go ahead and save everything. */
3792
3793 /* Save general registers. */
3794 for (i = 0; i < ARRAY_SIZE(env->gpr); i++) {
3795 if (__put_user(env->gpr[i], &frame->mc_gregs[i])) {
3796 return 1;
3797 }
3798 }
3799 if (__put_user(env->nip, &frame->mc_gregs[TARGET_PT_NIP])
3800 || __put_user(env->ctr, &frame->mc_gregs[TARGET_PT_CTR])
3801 || __put_user(env->lr, &frame->mc_gregs[TARGET_PT_LNK])
3802 || __put_user(env->xer, &frame->mc_gregs[TARGET_PT_XER]))
3803 return 1;
3804
3805 for (i = 0; i < ARRAY_SIZE(env->crf); i++) {
3806 ccr |= env->crf[i] << (32 - ((i + 1) * 4));
3807 }
3808 if (__put_user(ccr, &frame->mc_gregs[TARGET_PT_CCR]))
3809 return 1;
3810
3811 /* Save Altivec registers if necessary. */
3812 if (env->insns_flags & PPC_ALTIVEC) {
3813 for (i = 0; i < ARRAY_SIZE(env->avr); i++) {
3814 ppc_avr_t *avr = &env->avr[i];
3815 ppc_avr_t *vreg = &frame->mc_vregs.altivec[i];
3816
3817 if (__put_user(avr->u64[0], &vreg->u64[0]) ||
3818 __put_user(avr->u64[1], &vreg->u64[1])) {
3819 return 1;
3820 }
3821 }
3822 /* Set MSR_VR in the saved MSR value to indicate that
3823 frame->mc_vregs contains valid data. */
3824 msr |= MSR_VR;
3825 if (__put_user((uint32_t)env->spr[SPR_VRSAVE],
3826 &frame->mc_vregs.altivec[32].u32[3]))
3827 return 1;
3828 }
3829
3830 /* Save floating point registers. */
3831 if (env->insns_flags & PPC_FLOAT) {
3832 for (i = 0; i < ARRAY_SIZE(env->fpr); i++) {
3833 if (__put_user(env->fpr[i], &frame->mc_fregs[i])) {
3834 return 1;
3835 }
3836 }
3837 if (__put_user((uint64_t) env->fpscr, &frame->mc_fregs[32]))
3838 return 1;
3839 }
3840
3841 /* Save SPE registers. The kernel only saves the high half. */
3842 if (env->insns_flags & PPC_SPE) {
3843 #if defined(TARGET_PPC64)
3844 for (i = 0; i < ARRAY_SIZE(env->gpr); i++) {
3845 if (__put_user(env->gpr[i] >> 32, &frame->mc_vregs.spe[i])) {
3846 return 1;
3847 }
3848 }
3849 #else
3850 for (i = 0; i < ARRAY_SIZE(env->gprh); i++) {
3851 if (__put_user(env->gprh[i], &frame->mc_vregs.spe[i])) {
3852 return 1;
3853 }
3854 }
3855 #endif
3856 /* Set MSR_SPE in the saved MSR value to indicate that
3857 frame->mc_vregs contains valid data. */
3858 msr |= MSR_SPE;
3859 if (__put_user(env->spe_fscr, &frame->mc_vregs.spe[32]))
3860 return 1;
3861 }
3862
3863 /* Store MSR. */
3864 if (__put_user(msr, &frame->mc_gregs[TARGET_PT_MSR]))
3865 return 1;
3866
3867 /* Set up the sigreturn trampoline: li r0,sigret; sc. */
3868 if (sigret) {
3869 if (__put_user(0x38000000UL | sigret, &frame->tramp[0]) ||
3870 __put_user(0x44000002UL, &frame->tramp[1])) {
3871 return 1;
3872 }
3873 }
3874
3875 return 0;
3876 }
3877
3878 static int restore_user_regs(CPUState *env,
3879 struct target_mcontext *frame, int sig)
3880 {
3881 target_ulong save_r2 = 0;
3882 target_ulong msr;
3883 target_ulong ccr;
3884
3885 int i;
3886
3887 if (!sig) {
3888 save_r2 = env->gpr[2];
3889 }
3890
3891 /* Restore general registers. */
3892 for (i = 0; i < ARRAY_SIZE(env->gpr); i++) {
3893 if (__get_user(env->gpr[i], &frame->mc_gregs[i])) {
3894 return 1;
3895 }
3896 }
3897 if (__get_user(env->nip, &frame->mc_gregs[TARGET_PT_NIP])
3898 || __get_user(env->ctr, &frame->mc_gregs[TARGET_PT_CTR])
3899 || __get_user(env->lr, &frame->mc_gregs[TARGET_PT_LNK])
3900 || __get_user(env->xer, &frame->mc_gregs[TARGET_PT_XER]))
3901 return 1;
3902 if (__get_user(ccr, &frame->mc_gregs[TARGET_PT_CCR]))
3903 return 1;
3904
3905 for (i = 0; i < ARRAY_SIZE(env->crf); i++) {
3906 env->crf[i] = (ccr >> (32 - ((i + 1) * 4))) & 0xf;
3907 }
3908
3909 if (!sig) {
3910 env->gpr[2] = save_r2;
3911 }
3912 /* Restore MSR. */
3913 if (__get_user(msr, &frame->mc_gregs[TARGET_PT_MSR]))
3914 return 1;
3915
3916 /* If doing signal return, restore the previous little-endian mode. */
3917 if (sig)
3918 env->msr = (env->msr & ~MSR_LE) | (msr & MSR_LE);
3919
3920 /* Restore Altivec registers if necessary. */
3921 if (env->insns_flags & PPC_ALTIVEC) {
3922 for (i = 0; i < ARRAY_SIZE(env->avr); i++) {
3923 ppc_avr_t *avr = &env->avr[i];
3924 ppc_avr_t *vreg = &frame->mc_vregs.altivec[i];
3925
3926 if (__get_user(avr->u64[0], &vreg->u64[0]) ||
3927 __get_user(avr->u64[1], &vreg->u64[1])) {
3928 return 1;
3929 }
3930 }
3931 /* Set MSR_VEC in the saved MSR value to indicate that
3932 frame->mc_vregs contains valid data. */
3933 if (__get_user(env->spr[SPR_VRSAVE],
3934 (target_ulong *)(&frame->mc_vregs.altivec[32].u32[3])))
3935 return 1;
3936 }
3937
3938 /* Restore floating point registers. */
3939 if (env->insns_flags & PPC_FLOAT) {
3940 uint64_t fpscr;
3941 for (i = 0; i < ARRAY_SIZE(env->fpr); i++) {
3942 if (__get_user(env->fpr[i], &frame->mc_fregs[i])) {
3943 return 1;
3944 }
3945 }
3946 if (__get_user(fpscr, &frame->mc_fregs[32]))
3947 return 1;
3948 env->fpscr = (uint32_t) fpscr;
3949 }
3950
3951 /* Save SPE registers. The kernel only saves the high half. */
3952 if (env->insns_flags & PPC_SPE) {
3953 #if defined(TARGET_PPC64)
3954 for (i = 0; i < ARRAY_SIZE(env->gpr); i++) {
3955 uint32_t hi;
3956
3957 if (__get_user(hi, &frame->mc_vregs.spe[i])) {
3958 return 1;
3959 }
3960 env->gpr[i] = ((uint64_t)hi << 32) | ((uint32_t) env->gpr[i]);
3961 }
3962 #else
3963 for (i = 0; i < ARRAY_SIZE(env->gprh); i++) {
3964 if (__get_user(env->gprh[i], &frame->mc_vregs.spe[i])) {
3965 return 1;
3966 }
3967 }
3968 #endif
3969 if (__get_user(env->spe_fscr, &frame->mc_vregs.spe[32]))
3970 return 1;
3971 }
3972
3973 return 0;
3974 }
3975
3976 static void setup_frame(int sig, struct target_sigaction *ka,
3977 target_sigset_t *set, CPUState *env)
3978 {
3979 struct target_sigframe *frame;
3980 struct target_sigcontext *sc;
3981 target_ulong frame_addr, newsp;
3982 int err = 0;
3983 int signal;
3984
3985 frame_addr = get_sigframe(ka, env, sizeof(*frame));
3986 if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 1))
3987 goto sigsegv;
3988 sc = &frame->sctx;
3989
3990 signal = current_exec_domain_sig(sig);
3991
3992 err |= __put_user(h2g(ka->_sa_handler), &sc->handler);
3993 err |= __put_user(set->sig[0], &sc->oldmask);
3994 #if defined(TARGET_PPC64)
3995 err |= __put_user(set->sig[0] >> 32, &sc->_unused[3]);
3996 #else
3997 err |= __put_user(set->sig[1], &sc->_unused[3]);
3998 #endif
3999 err |= __put_user(h2g(&frame->mctx), &sc->regs);
4000 err |= __put_user(sig, &sc->signal);
4001
4002 /* Save user regs. */
4003 err |= save_user_regs(env, &frame->mctx, TARGET_NR_sigreturn);
4004
4005 /* The kernel checks for the presence of a VDSO here. We don't
4006 emulate a vdso, so use a sigreturn system call. */
4007 env->lr = (target_ulong) h2g(frame->mctx.tramp);
4008
4009 /* Turn off all fp exceptions. */
4010 env->fpscr = 0;
4011
4012 /* Create a stack frame for the caller of the handler. */
4013 newsp = frame_addr - SIGNAL_FRAMESIZE;
4014 err |= __put_user(env->gpr[1], (target_ulong *)(uintptr_t) newsp);
4015
4016 if (err)
4017 goto sigsegv;
4018
4019 /* Set up registers for signal handler. */
4020 env->gpr[1] = newsp;
4021 env->gpr[3] = signal;
4022 env->gpr[4] = (target_ulong) h2g(sc);
4023 env->nip = (target_ulong) ka->_sa_handler;
4024 /* Signal handlers are entered in big-endian mode. */
4025 env->msr &= ~MSR_LE;
4026
4027 unlock_user_struct(frame, frame_addr, 1);
4028 return;
4029
4030 sigsegv:
4031 unlock_user_struct(frame, frame_addr, 1);
4032 if (logfile)
4033 fprintf (logfile, "segfaulting from setup_frame\n");
4034 force_sig(TARGET_SIGSEGV);
4035 }
4036
4037 static void setup_rt_frame(int sig, struct target_sigaction *ka,
4038 target_siginfo_t *info,
4039 target_sigset_t *set, CPUState *env)
4040 {
4041 struct target_rt_sigframe *rt_sf;
4042 struct target_mcontext *frame;
4043 target_ulong rt_sf_addr, newsp = 0;
4044 int i, err = 0;
4045 int signal;
4046
4047 rt_sf_addr = get_sigframe(ka, env, sizeof(*rt_sf));
4048 if (!lock_user_struct(VERIFY_WRITE, rt_sf, rt_sf_addr, 1))
4049 goto sigsegv;
4050
4051 signal = current_exec_domain_sig(sig);
4052
4053 err |= copy_siginfo_to_user(&rt_sf->info, info);
4054
4055 err |= __put_user(0, &rt_sf->uc.tuc_flags);
4056 err |= __put_user(0, &rt_sf->uc.tuc_link);
4057 err |= __put_user((target_ulong)target_sigaltstack_used.ss_sp,
4058 &rt_sf->uc.tuc_stack.ss_sp);
4059 err |= __put_user(sas_ss_flags(env->gpr[1]),
4060 &rt_sf->uc.tuc_stack.ss_flags);
4061 err |= __put_user(target_sigaltstack_used.ss_size,
4062 &rt_sf->uc.tuc_stack.ss_size);
4063 err |= __put_user(h2g (&rt_sf->uc.tuc_mcontext),
4064 &rt_sf->uc.tuc_regs);
4065 for(i = 0; i < TARGET_NSIG_WORDS; i++) {
4066 err |= __put_user(set->sig[i], &rt_sf->uc.tuc_sigmask.sig[i]);
4067 }
4068
4069 frame = &rt_sf->uc.tuc_mcontext;
4070 err |= save_user_regs(env, frame, TARGET_NR_rt_sigreturn);
4071
4072 /* The kernel checks for the presence of a VDSO here. We don't
4073 emulate a vdso, so use a sigreturn system call. */
4074 env->lr = (target_ulong) h2g(frame->tramp);
4075
4076 /* Turn off all fp exceptions. */
4077 env->fpscr = 0;
4078
4079 /* Create a stack frame for the caller of the handler. */
4080 newsp = rt_sf_addr - (SIGNAL_FRAMESIZE + 16);
4081 err |= __put_user(env->gpr[1], (target_ulong *)(uintptr_t) newsp);
4082
4083 if (err)
4084 goto sigsegv;
4085
4086 /* Set up registers for signal handler. */
4087 env->gpr[1] = newsp;
4088 env->gpr[3] = (target_ulong) signal;
4089 env->gpr[4] = (target_ulong) h2g(&rt_sf->info);
4090 env->gpr[5] = (target_ulong) h2g(&rt_sf->uc);
4091 env->gpr[6] = (target_ulong) h2g(rt_sf);
4092 env->nip = (target_ulong) ka->_sa_handler;
4093 /* Signal handlers are entered in big-endian mode. */
4094 env->msr &= ~MSR_LE;
4095
4096 unlock_user_struct(rt_sf, rt_sf_addr, 1);
4097 return;
4098
4099 sigsegv:
4100 unlock_user_struct(rt_sf, rt_sf_addr, 1);
4101 if (logfile)
4102 fprintf (logfile, "segfaulting from setup_rt_frame\n");
4103 force_sig(TARGET_SIGSEGV);
4104
4105 }
4106
4107 long do_sigreturn(CPUState *env)
4108 {
4109 struct target_sigcontext *sc = NULL;
4110 struct target_mcontext *sr = NULL;
4111 target_ulong sr_addr, sc_addr;
4112 sigset_t blocked;
4113 target_sigset_t set;
4114
4115 sc_addr = env->gpr[1] + SIGNAL_FRAMESIZE;
4116 if (!lock_user_struct(VERIFY_READ, sc, sc_addr, 1))
4117 goto sigsegv;
4118
4119 #if defined(TARGET_PPC64)
4120 set.sig[0] = sc->oldmask + ((long)(sc->_unused[3]) << 32);
4121 #else
4122 if(__get_user(set.sig[0], &sc->oldmask) ||
4123 __get_user(set.sig[1], &sc->_unused[3]))
4124 goto sigsegv;
4125 #endif
4126 target_to_host_sigset_internal(&blocked, &set);
4127 sigprocmask(SIG_SETMASK, &blocked, NULL);
4128
4129 if (__get_user(sr_addr, &sc->regs))
4130 goto sigsegv;
4131 if (!lock_user_struct(VERIFY_READ, sr, sr_addr, 1))
4132 goto sigsegv;
4133 if (restore_user_regs(env, sr, 1))
4134 goto sigsegv;
4135
4136 unlock_user_struct(sr, sr_addr, 1);
4137 unlock_user_struct(sc, sc_addr, 1);
4138 return -TARGET_QEMU_ESIGRETURN;
4139
4140 sigsegv:
4141 unlock_user_struct(sr, sr_addr, 1);
4142 unlock_user_struct(sc, sc_addr, 1);
4143 if (logfile)
4144 fprintf (logfile, "segfaulting from do_sigreturn\n");
4145 force_sig(TARGET_SIGSEGV);
4146 return 0;
4147 }
4148
4149 /* See arch/powerpc/kernel/signal_32.c. */
4150 static int do_setcontext(struct target_ucontext *ucp, CPUState *env, int sig)
4151 {
4152 struct target_mcontext *mcp;
4153 target_ulong mcp_addr;
4154 sigset_t blocked;
4155 target_sigset_t set;
4156
4157 if (copy_from_user(&set, h2g(ucp) + offsetof(struct target_ucontext, tuc_sigmask),
4158 sizeof (set)))
4159 return 1;
4160
4161 #if defined(TARGET_PPC64)
4162 fprintf (stderr, "do_setcontext: not implemented\n");
4163 return 0;
4164 #else
4165 if (__get_user(mcp_addr, &ucp->tuc_regs))
4166 return 1;
4167
4168 if (!lock_user_struct(VERIFY_READ, mcp, mcp_addr, 1))
4169 return 1;
4170
4171 target_to_host_sigset_internal(&blocked, &set);
4172 sigprocmask(SIG_SETMASK, &blocked, NULL);
4173 if (restore_user_regs(env, mcp, sig))
4174 goto sigsegv;
4175
4176 unlock_user_struct(mcp, mcp_addr, 1);
4177 return 0;
4178
4179 sigsegv:
4180 unlock_user_struct(mcp, mcp_addr, 1);
4181 return 1;
4182 #endif
4183 }
4184
4185 long do_rt_sigreturn(CPUState *env)
4186 {
4187 struct target_rt_sigframe *rt_sf = NULL;
4188 target_ulong rt_sf_addr;
4189
4190 rt_sf_addr = env->gpr[1] + SIGNAL_FRAMESIZE + 16;
4191 if (!lock_user_struct(VERIFY_READ, rt_sf, rt_sf_addr, 1))
4192 goto sigsegv;
4193
4194 if (do_setcontext(&rt_sf->uc, env, 1))
4195 goto sigsegv;
4196
4197 do_sigaltstack(rt_sf_addr
4198 + offsetof(struct target_rt_sigframe, uc.tuc_stack),
4199 0, env->gpr[1]);
4200
4201 unlock_user_struct(rt_sf, rt_sf_addr, 1);
4202 return -TARGET_QEMU_ESIGRETURN;
4203
4204 sigsegv:
4205 unlock_user_struct(rt_sf, rt_sf_addr, 1);
4206 if (logfile)
4207 fprintf (logfile, "segfaulting from do_rt_sigreturn\n");
4208 force_sig(TARGET_SIGSEGV);
4209 return 0;
4210 }
4211
4212 #elif defined(TARGET_M68K)
4213
4214 struct target_sigcontext {
4215 abi_ulong sc_mask;
4216 abi_ulong sc_usp;
4217 abi_ulong sc_d0;
4218 abi_ulong sc_d1;
4219 abi_ulong sc_a0;
4220 abi_ulong sc_a1;
4221 unsigned short sc_sr;
4222 abi_ulong sc_pc;
4223 };
4224
4225 struct target_sigframe
4226 {
4227 abi_ulong pretcode;
4228 int sig;
4229 int code;
4230 abi_ulong psc;
4231 char retcode[8];
4232 abi_ulong extramask[TARGET_NSIG_WORDS-1];
4233 struct target_sigcontext sc;
4234 };
4235
4236 typedef int target_greg_t;
4237 #define TARGET_NGREG 18
4238 typedef target_greg_t target_gregset_t[TARGET_NGREG];
4239
4240 typedef struct target_fpregset {
4241 int f_fpcntl[3];
4242 int f_fpregs[8*3];
4243 } target_fpregset_t;
4244
4245 struct target_mcontext {
4246 int version;
4247 target_gregset_t gregs;
4248 target_fpregset_t fpregs;
4249 };
4250
4251 #define TARGET_MCONTEXT_VERSION 2
4252
4253 struct target_ucontext {
4254 abi_ulong tuc_flags;
4255 abi_ulong tuc_link;
4256 target_stack_t tuc_stack;
4257 struct target_mcontext tuc_mcontext;
4258 abi_long tuc_filler[80];
4259 target_sigset_t tuc_sigmask;
4260 };
4261
4262 struct target_rt_sigframe
4263 {
4264 abi_ulong pretcode;
4265 int sig;
4266 abi_ulong pinfo;
4267 abi_ulong puc;
4268 char retcode[8];
4269 struct target_siginfo info;
4270 struct target_ucontext uc;
4271 };
4272
4273 static int
4274 setup_sigcontext(struct target_sigcontext *sc, CPUState *env, abi_ulong mask)
4275 {
4276 int err = 0;
4277
4278 err |= __put_user(mask, &sc->sc_mask);
4279 err |= __put_user(env->aregs[7], &sc->sc_usp);
4280 err |= __put_user(env->dregs[0], &sc->sc_d0);
4281 err |= __put_user(env->dregs[1], &sc->sc_d1);
4282 err |= __put_user(env->aregs[0], &sc->sc_a0);
4283 err |= __put_user(env->aregs[1], &sc->sc_a1);
4284 err |= __put_user(env->sr, &sc->sc_sr);
4285 err |= __put_user(env->pc, &sc->sc_pc);
4286
4287 return err;
4288 }
4289
4290 static int
4291 restore_sigcontext(CPUState *env, struct target_sigcontext *sc, int *pd0)
4292 {
4293 int err = 0;
4294 int temp;
4295
4296 err |= __get_user(env->aregs[7], &sc->sc_usp);
4297 err |= __get_user(env->dregs[1], &sc->sc_d1);
4298 err |= __get_user(env->aregs[0], &sc->sc_a0);
4299 err |= __get_user(env->aregs[1], &sc->sc_a1);
4300 err |= __get_user(env->pc, &sc->sc_pc);
4301 err |= __get_user(temp, &sc->sc_sr);
4302 env->sr = (env->sr & 0xff00) | (temp & 0xff);
4303
4304 *pd0 = tswapl(sc->sc_d0);
4305
4306 return err;
4307 }
4308
4309 /*
4310 * Determine which stack to use..
4311 */
4312 static inline abi_ulong
4313 get_sigframe(struct target_sigaction *ka, CPUState *regs, size_t frame_size)
4314 {
4315 unsigned long sp;
4316
4317 sp = regs->aregs[7];
4318
4319 /* This is the X/Open sanctioned signal stack switching. */
4320 if ((ka->sa_flags & TARGET_SA_ONSTACK) && (sas_ss_flags (sp) == 0)) {
4321 sp = target_sigaltstack_used.ss_sp + target_sigaltstack_used.ss_size;
4322 }
4323
4324 return ((sp - frame_size) & -8UL);
4325 }
4326
4327 static void setup_frame(int sig, struct target_sigaction *ka,
4328 target_sigset_t *set, CPUState *env)
4329 {
4330 struct target_sigframe *frame;
4331 abi_ulong frame_addr;
4332 abi_ulong retcode_addr;
4333 abi_ulong sc_addr;
4334 int err = 0;
4335 int i;
4336
4337 frame_addr = get_sigframe(ka, env, sizeof *frame);
4338 if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
4339 goto give_sigsegv;
4340
4341 err |= __put_user(sig, &frame->sig);
4342
4343 sc_addr = frame_addr + offsetof(struct target_sigframe, sc);
4344 err |= __put_user(sc_addr, &frame->psc);
4345
4346 err |= setup_sigcontext(&frame->sc, env, set->sig[0]);
4347 if (err)
4348 goto give_sigsegv;
4349
4350 for(i = 1; i < TARGET_NSIG_WORDS; i++) {
4351 if (__put_user(set->sig[i], &frame->extramask[i - 1]))
4352 goto give_sigsegv;
4353 }
4354
4355 /* Set up to return from userspace. */
4356
4357 retcode_addr = frame_addr + offsetof(struct target_sigframe, retcode);
4358 err |= __put_user(retcode_addr, &frame->pretcode);
4359
4360 /* moveq #,d0; trap #0 */
4361
4362 err |= __put_user(0x70004e40 + (TARGET_NR_sigreturn << 16),
4363 (long *)(frame->retcode));
4364
4365 if (err)
4366 goto give_sigsegv;
4367
4368 /* Set up to return from userspace */
4369
4370 env->aregs[7] = frame_addr;
4371 env->pc = ka->_sa_handler;
4372
4373 unlock_user_struct(frame, frame_addr, 1);
4374 return;
4375
4376 give_sigsegv:
4377 unlock_user_struct(frame, frame_addr, 1);
4378 force_sig(TARGET_SIGSEGV);
4379 }
4380
4381 static inline int target_rt_setup_ucontext(struct target_ucontext *uc,
4382 CPUState *env)
4383 {
4384 target_greg_t *gregs = uc->tuc_mcontext.gregs;
4385 int err;
4386
4387 err = __put_user(TARGET_MCONTEXT_VERSION, &uc->tuc_mcontext.version);
4388 err |= __put_user(env->dregs[0], &gregs[0]);
4389 err |= __put_user(env->dregs[1], &gregs[1]);
4390 err |= __put_user(env->dregs[2], &gregs[2]);
4391 err |= __put_user(env->dregs[3], &gregs[3]);
4392 err |= __put_user(env->dregs[4], &gregs[4]);
4393 err |= __put_user(env->dregs[5], &gregs[5]);
4394 err |= __put_user(env->dregs[6], &gregs[6]);
4395 err |= __put_user(env->dregs[7], &gregs[7]);
4396 err |= __put_user(env->aregs[0], &gregs[8]);
4397 err |= __put_user(env->aregs[1], &gregs[9]);
4398 err |= __put_user(env->aregs[2], &gregs[10]);
4399 err |= __put_user(env->aregs[3], &gregs[11]);
4400 err |= __put_user(env->aregs[4], &gregs[12]);
4401 err |= __put_user(env->aregs[5], &gregs[13]);
4402 err |= __put_user(env->aregs[6], &gregs[14]);
4403 err |= __put_user(env->aregs[7], &gregs[15]);
4404 err |= __put_user(env->pc, &gregs[16]);
4405 err |= __put_user(env->sr, &gregs[17]);
4406
4407 return err;
4408 }
4409
4410 static inline int target_rt_restore_ucontext(CPUState *env,
4411 struct target_ucontext *uc,
4412 int *pd0)
4413 {
4414 int temp;
4415 int err;
4416 target_greg_t *gregs = uc->tuc_mcontext.gregs;
4417
4418 err = __get_user(temp, &uc->tuc_mcontext.version);
4419 if (temp != TARGET_MCONTEXT_VERSION)
4420 goto badframe;
4421
4422 /* restore passed registers */
4423 err |= __get_user(env->dregs[0], &gregs[0]);
4424 err |= __get_user(env->dregs[1], &gregs[1]);
4425 err |= __get_user(env->dregs[2], &gregs[2]);
4426 err |= __get_user(env->dregs[3], &gregs[3]);
4427 err |= __get_user(env->dregs[4], &gregs[4]);
4428 err |= __get_user(env->dregs[5], &gregs[5]);
4429 err |= __get_user(env->dregs[6], &gregs[6]);
4430 err |= __get_user(env->dregs[7], &gregs[7]);
4431 err |= __get_user(env->aregs[0], &gregs[8]);
4432 err |= __get_user(env->aregs[1], &gregs[9]);
4433 err |= __get_user(env->aregs[2], &gregs[10]);
4434 err |= __get_user(env->aregs[3], &gregs[11]);
4435 err |= __get_user(env->aregs[4], &gregs[12]);
4436 err |= __get_user(env->aregs[5], &gregs[13]);
4437 err |= __get_user(env->aregs[6], &gregs[14]);
4438 err |= __get_user(env->aregs[7], &gregs[15]);
4439 err |= __get_user(env->pc, &gregs[16]);
4440 err |= __get_user(temp, &gregs[17]);
4441 env->sr = (env->sr & 0xff00) | (temp & 0xff);
4442
4443 *pd0 = env->dregs[0];
4444 return err;
4445
4446 badframe:
4447 return 1;
4448 }
4449
4450 static void setup_rt_frame(int sig, struct target_sigaction *ka,
4451 target_siginfo_t *info,
4452 target_sigset_t *set, CPUState *env)
4453 {
4454 struct target_rt_sigframe *frame;
4455 abi_ulong frame_addr;
4456 abi_ulong retcode_addr;
4457 abi_ulong info_addr;
4458 abi_ulong uc_addr;
4459 int err = 0;
4460 int i;
4461
4462 frame_addr = get_sigframe(ka, env, sizeof *frame);
4463 if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
4464 goto give_sigsegv;
4465
4466 err |= __put_user(sig, &frame->sig);
4467
4468 info_addr = frame_addr + offsetof(struct target_rt_sigframe, info);
4469 err |= __put_user(info_addr, &frame->pinfo);
4470
4471 uc_addr = frame_addr + offsetof(struct target_rt_sigframe, uc);
4472 err |= __put_user(uc_addr, &frame->puc);
4473
4474 err |= copy_siginfo_to_user(&frame->info, info);
4475
4476 /* Create the ucontext */
4477
4478 err |= __put_user(0, &frame->uc.tuc_flags);
4479 err |= __put_user(0, &frame->uc.tuc_link);
4480 err |= __put_user(target_sigaltstack_used.ss_sp,
4481 &frame->uc.tuc_stack.ss_sp);
4482 err |= __put_user(sas_ss_flags(env->aregs[7]),
4483 &frame->uc.tuc_stack.ss_flags);
4484 err |= __put_user(target_sigaltstack_used.ss_size,
4485 &frame->uc.tuc_stack.ss_size);
4486 err |= target_rt_setup_ucontext(&frame->uc, env);
4487
4488 if (err)
4489 goto give_sigsegv;
4490
4491 for(i = 0; i < TARGET_NSIG_WORDS; i++) {
4492 if (__put_user(set->sig[i], &frame->uc.tuc_sigmask.sig[i]))
4493 goto give_sigsegv;
4494 }
4495
4496 /* Set up to return from userspace. */
4497
4498 retcode_addr = frame_addr + offsetof(struct target_sigframe, retcode);
4499 err |= __put_user(retcode_addr, &frame->pretcode);
4500
4501 /* moveq #,d0; notb d0; trap #0 */
4502
4503 err |= __put_user(0x70004600 + ((TARGET_NR_rt_sigreturn ^ 0xff) << 16),
4504 (long *)(frame->retcode + 0));
4505 err |= __put_user(0x4e40, (short *)(frame->retcode + 4));
4506
4507 if (err)
4508 goto give_sigsegv;
4509
4510 /* Set up to return from userspace */
4511
4512 env->aregs[7] = frame_addr;
4513 env->pc = ka->_sa_handler;
4514
4515 unlock_user_struct(frame, frame_addr, 1);
4516 return;
4517
4518 give_sigsegv:
4519 unlock_user_struct(frame, frame_addr, 1);
4520 force_sig(TARGET_SIGSEGV);
4521 }
4522
4523 long do_sigreturn(CPUState *env)
4524 {
4525 struct target_sigframe *frame;
4526 abi_ulong frame_addr = env->aregs[7] - 4;
4527 target_sigset_t target_set;
4528 sigset_t set;
4529 int d0, i;
4530
4531 if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1))
4532 goto badframe;
4533
4534 /* set blocked signals */
4535
4536 if (__get_user(target_set.sig[0], &frame->sc.sc_mask))
4537 goto badframe;
4538
4539 for(i = 1; i < TARGET_NSIG_WORDS; i++) {
4540 if (__get_user(target_set.sig[i], &frame->extramask[i - 1]))
4541 goto badframe;
4542 }
4543
4544 target_to_host_sigset_internal(&set, &target_set);
4545 sigprocmask(SIG_SETMASK, &set, NULL);
4546
4547 /* restore registers */
4548
4549 if (restore_sigcontext(env, &frame->sc, &d0))
4550 goto badframe;
4551
4552 unlock_user_struct(frame, frame_addr, 0);
4553 return d0;
4554
4555 badframe:
4556 unlock_user_struct(frame, frame_addr, 0);
4557 force_sig(TARGET_SIGSEGV);
4558 return 0;
4559 }
4560
4561 long do_rt_sigreturn(CPUState *env)
4562 {
4563 struct target_rt_sigframe *frame;
4564 abi_ulong frame_addr = env->aregs[7] - 4;
4565 target_sigset_t target_set;
4566 sigset_t set;
4567 int d0;
4568
4569 if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1))
4570 goto badframe;
4571
4572 target_to_host_sigset_internal(&set, &target_set);
4573 sigprocmask(SIG_SETMASK, &set, NULL);
4574
4575 /* restore registers */
4576
4577 if (target_rt_restore_ucontext(env, &frame->uc, &d0))
4578 goto badframe;
4579
4580 if (do_sigaltstack(frame_addr +
4581 offsetof(struct target_rt_sigframe, uc.tuc_stack),
4582 0, get_sp_from_cpustate(env)) == -EFAULT)
4583 goto badframe;
4584
4585 unlock_user_struct(frame, frame_addr, 0);
4586 return d0;
4587
4588 badframe:
4589 unlock_user_struct(frame, frame_addr, 0);
4590 force_sig(TARGET_SIGSEGV);
4591 return 0;
4592 }
4593
4594 #elif defined(TARGET_ALPHA)
4595
4596 struct target_sigcontext {
4597 abi_long sc_onstack;
4598 abi_long sc_mask;
4599 abi_long sc_pc;
4600 abi_long sc_ps;
4601 abi_long sc_regs[32];
4602 abi_long sc_ownedfp;
4603 abi_long sc_fpregs[32];
4604 abi_ulong sc_fpcr;
4605 abi_ulong sc_fp_control;
4606 abi_ulong sc_reserved1;
4607 abi_ulong sc_reserved2;
4608 abi_ulong sc_ssize;
4609 abi_ulong sc_sbase;
4610 abi_ulong sc_traparg_a0;
4611 abi_ulong sc_traparg_a1;
4612 abi_ulong sc_traparg_a2;
4613 abi_ulong sc_fp_trap_pc;
4614 abi_ulong sc_fp_trigger_sum;
4615 abi_ulong sc_fp_trigger_inst;
4616 };
4617
4618 struct target_ucontext {
4619 abi_ulong tuc_flags;
4620 abi_ulong tuc_link;
4621 abi_ulong tuc_osf_sigmask;
4622 target_stack_t tuc_stack;
4623 struct target_sigcontext tuc_mcontext;
4624 target_sigset_t tuc_sigmask;
4625 };
4626
4627 struct target_sigframe {
4628 struct target_sigcontext sc;
4629 unsigned int retcode[3];
4630 };
4631
4632 struct target_rt_sigframe {
4633 target_siginfo_t info;
4634 struct target_ucontext uc;
4635 unsigned int retcode[3];
4636 };
4637
4638 #define INSN_MOV_R30_R16 0x47fe0410
4639 #define INSN_LDI_R0 0x201f0000
4640 #define INSN_CALLSYS 0x00000083
4641
4642 static int setup_sigcontext(struct target_sigcontext *sc, CPUState *env,
4643 abi_ulong frame_addr, target_sigset_t *set)
4644 {
4645 int i, err = 0;
4646
4647 err |= __put_user(on_sig_stack(frame_addr), &sc->sc_onstack);
4648 err |= __put_user(set->sig[0], &sc->sc_mask);
4649 err |= __put_user(env->pc, &sc->sc_pc);
4650 err |= __put_user(8, &sc->sc_ps);
4651
4652 for (i = 0; i < 31; ++i) {
4653 err |= __put_user(env->ir[i], &sc->sc_regs[i]);
4654 }
4655 err |= __put_user(0, &sc->sc_regs[31]);
4656
4657 for (i = 0; i < 31; ++i) {
4658 err |= __put_user(env->fir[i], &sc->sc_fpregs[i]);
4659 }
4660 err |= __put_user(0, &sc->sc_fpregs[31]);
4661 err |= __put_user(cpu_alpha_load_fpcr(env), &sc->sc_fpcr);
4662
4663 err |= __put_user(0, &sc->sc_traparg_a0); /* FIXME */
4664 err |= __put_user(0, &sc->sc_traparg_a1); /* FIXME */
4665 err |= __put_user(0, &sc->sc_traparg_a2); /* FIXME */
4666
4667 return err;
4668 }
4669
4670 static int restore_sigcontext(CPUState *env, struct target_sigcontext *sc)
4671 {
4672 uint64_t fpcr;
4673 int i, err = 0;
4674
4675 err |= __get_user(env->pc, &sc->sc_pc);
4676
4677 for (i = 0; i < 31; ++i) {
4678 err |= __get_user(env->ir[i], &sc->sc_regs[i]);
4679 }
4680 for (i = 0; i < 31; ++i) {
4681 err |= __get_user(env->fir[i], &sc->sc_fpregs[i]);
4682 }
4683
4684 err |= __get_user(fpcr, &sc->sc_fpcr);
4685 cpu_alpha_store_fpcr(env, fpcr);
4686
4687 return err;
4688 }
4689
4690 static inline abi_ulong get_sigframe(struct target_sigaction *sa,
4691 CPUState *env, unsigned long framesize)
4692 {
4693 abi_ulong sp = env->ir[IR_SP];
4694
4695 /* This is the X/Open sanctioned signal stack switching. */
4696 if ((sa->sa_flags & TARGET_SA_ONSTACK) != 0 && !sas_ss_flags(sp)) {
4697 sp = target_sigaltstack_used.ss_sp + target_sigaltstack_used.ss_size;
4698 }
4699 return (sp - framesize) & -32;
4700 }
4701
4702 static void setup_frame(int sig, struct target_sigaction *ka,
4703 target_sigset_t *set, CPUState *env)
4704 {
4705 abi_ulong frame_addr, r26;
4706 struct target_sigframe *frame;
4707 int err = 0;
4708
4709 frame_addr = get_sigframe(ka, env, sizeof(*frame));
4710 if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0)) {
4711 goto give_sigsegv;
4712 }
4713
4714 err |= setup_sigcontext(&frame->sc, env, frame_addr, set);
4715
4716 if (ka->sa_restorer) {
4717 r26 = ka->sa_restorer;
4718 } else {
4719 err |= __put_user(INSN_MOV_R30_R16, &frame->retcode[0]);
4720 err |= __put_user(INSN_LDI_R0 + TARGET_NR_sigreturn,
4721 &frame->retcode[1]);
4722 err |= __put_user(INSN_CALLSYS, &frame->retcode[2]);
4723 /* imb() */
4724 r26 = frame_addr;
4725 }
4726
4727 unlock_user_struct(frame, frame_addr, 1);
4728
4729 if (err) {
4730 give_sigsegv:
4731 if (sig == TARGET_SIGSEGV) {
4732 ka->_sa_handler = TARGET_SIG_DFL;
4733 }
4734 force_sig(TARGET_SIGSEGV);
4735 }
4736
4737 env->ir[IR_RA] = r26;
4738 env->ir[IR_PV] = env->pc = ka->_sa_handler;
4739 env->ir[IR_A0] = sig;
4740 env->ir[IR_A1] = 0;
4741 env->ir[IR_A2] = frame_addr + offsetof(struct target_sigframe, sc);
4742 env->ir[IR_SP] = frame_addr;
4743 }
4744
4745 static void setup_rt_frame(int sig, struct target_sigaction *ka,
4746 target_siginfo_t *info,
4747 target_sigset_t *set, CPUState *env)
4748 {
4749 abi_ulong frame_addr, r26;
4750 struct target_rt_sigframe *frame;
4751 int i, err = 0;
4752
4753 frame_addr = get_sigframe(ka, env, sizeof(*frame));
4754 if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0)) {
4755 goto give_sigsegv;
4756 }
4757
4758 err |= copy_siginfo_to_user(&frame->info, info);
4759
4760 err |= __put_user(0, &frame->uc.tuc_flags);
4761 err |= __put_user(0, &frame->uc.tuc_link);
4762 err |= __put_user(set->sig[0], &frame->uc.tuc_osf_sigmask);
4763 err |= __put_user(target_sigaltstack_used.ss_sp,
4764 &frame->uc.tuc_stack.ss_sp);
4765 err |= __put_user(sas_ss_flags(env->ir[IR_SP]),
4766 &frame->uc.tuc_stack.ss_flags);
4767 err |= __put_user(target_sigaltstack_used.ss_size,
4768 &frame->uc.tuc_stack.ss_size);
4769 err |= setup_sigcontext(&frame->uc.tuc_mcontext, env, frame_addr, set);
4770 for (i = 0; i < TARGET_NSIG_WORDS; ++i) {
4771 err |= __put_user(set->sig[i], &frame->uc.tuc_sigmask.sig[i]);
4772 }
4773
4774 if (ka->sa_restorer) {
4775 r26 = ka->sa_restorer;
4776 } else {
4777 err |= __put_user(INSN_MOV_R30_R16, &frame->retcode[0]);
4778 err |= __put_user(INSN_LDI_R0 + TARGET_NR_rt_sigreturn,
4779 &frame->retcode[1]);
4780 err |= __put_user(INSN_CALLSYS, &frame->retcode[2]);
4781 /* imb(); */
4782 r26 = frame_addr;
4783 }
4784
4785 if (err) {
4786 give_sigsegv:
4787 if (sig == TARGET_SIGSEGV) {
4788 ka->_sa_handler = TARGET_SIG_DFL;
4789 }
4790 force_sig(TARGET_SIGSEGV);
4791 }
4792
4793 env->ir[IR_RA] = r26;
4794 env->ir[IR_PV] = env->pc = ka->_sa_handler;
4795 env->ir[IR_A0] = sig;
4796 env->ir[IR_A1] = frame_addr + offsetof(struct target_rt_sigframe, info);
4797 env->ir[IR_A2] = frame_addr + offsetof(struct target_rt_sigframe, uc);
4798 env->ir[IR_SP] = frame_addr;
4799 }
4800
4801 long do_sigreturn(CPUState *env)
4802 {
4803 struct target_sigcontext *sc;
4804 abi_ulong sc_addr = env->ir[IR_A0];
4805 target_sigset_t target_set;
4806 sigset_t set;
4807
4808 if (!lock_user_struct(VERIFY_READ, sc, sc_addr, 1)) {
4809 goto badframe;
4810 }
4811
4812 target_sigemptyset(&target_set);
4813 if (__get_user(target_set.sig[0], &sc->sc_mask)) {
4814 goto badframe;
4815 }
4816
4817 target_to_host_sigset_internal(&set, &target_set);
4818 sigprocmask(SIG_SETMASK, &set, NULL);
4819
4820 if (restore_sigcontext(env, sc)) {
4821 goto badframe;
4822 }
4823 unlock_user_struct(sc, sc_addr, 0);
4824 return env->ir[IR_V0];
4825
4826 badframe:
4827 unlock_user_struct(sc, sc_addr, 0);
4828 force_sig(TARGET_SIGSEGV);
4829 }
4830
4831 long do_rt_sigreturn(CPUState *env)
4832 {
4833 abi_ulong frame_addr = env->ir[IR_A0];
4834 struct target_rt_sigframe *frame;
4835 sigset_t set;
4836
4837 if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1)) {
4838 goto badframe;
4839 }
4840 target_to_host_sigset(&set, &frame->uc.tuc_sigmask);
4841 sigprocmask(SIG_SETMASK, &set, NULL);
4842
4843 if (restore_sigcontext(env, &frame->uc.tuc_mcontext)) {
4844 goto badframe;
4845 }
4846 if (do_sigaltstack(frame_addr + offsetof(struct target_rt_sigframe,
4847 uc.tuc_stack),
4848 0, env->ir[IR_SP]) == -EFAULT) {
4849 goto badframe;
4850 }
4851
4852 unlock_user_struct(frame, frame_addr, 0);
4853 return env->ir[IR_V0];
4854
4855
4856 badframe:
4857 unlock_user_struct(frame, frame_addr, 0);
4858 force_sig(TARGET_SIGSEGV);
4859 }
4860
4861 #else
4862
4863 static void setup_frame(int sig, struct target_sigaction *ka,
4864 target_sigset_t *set, CPUState *env)
4865 {
4866 fprintf(stderr, "setup_frame: not implemented\n");
4867 }
4868
4869 static void setup_rt_frame(int sig, struct target_sigaction *ka,
4870 target_siginfo_t *info,
4871 target_sigset_t *set, CPUState *env)
4872 {
4873 fprintf(stderr, "setup_rt_frame: not implemented\n");
4874 }
4875
4876 long do_sigreturn(CPUState *env)
4877 {
4878 fprintf(stderr, "do_sigreturn: not implemented\n");
4879 return -TARGET_ENOSYS;
4880 }
4881
4882 long do_rt_sigreturn(CPUState *env)
4883 {
4884 fprintf(stderr, "do_rt_sigreturn: not implemented\n");
4885 return -TARGET_ENOSYS;
4886 }
4887
4888 #endif
4889
4890 void process_pending_signals(CPUState *cpu_env)
4891 {
4892 int sig;
4893 abi_ulong handler;
4894 sigset_t set, old_set;
4895 target_sigset_t target_old_set;
4896 struct emulated_sigtable *k;
4897 struct target_sigaction *sa;
4898 struct sigqueue *q;
4899 TaskState *ts = cpu_env->opaque;
4900
4901 if (!ts->signal_pending)
4902 return;
4903
4904 /* FIXME: This is not threadsafe. */
4905 k = ts->sigtab;
4906 for(sig = 1; sig <= TARGET_NSIG; sig++) {
4907 if (k->pending)
4908 goto handle_signal;
4909 k++;
4910 }
4911 /* if no signal is pending, just return */
4912 ts->signal_pending = 0;
4913 return;
4914
4915 handle_signal:
4916 #ifdef DEBUG_SIGNAL
4917 fprintf(stderr, "qemu: process signal %d\n", sig);
4918 #endif
4919 /* dequeue signal */
4920 q = k->first;
4921 k->first = q->next;
4922 if (!k->first)
4923 k->pending = 0;
4924
4925 sig = gdb_handlesig (cpu_env, sig);
4926 if (!sig) {
4927 sa = NULL;
4928 handler = TARGET_SIG_IGN;
4929 } else {
4930 sa = &sigact_table[sig - 1];
4931 handler = sa->_sa_handler;
4932 }
4933
4934 if (handler == TARGET_SIG_DFL) {
4935 /* default handler : ignore some signal. The other are job control or fatal */
4936 if (sig == TARGET_SIGTSTP || sig == TARGET_SIGTTIN || sig == TARGET_SIGTTOU) {
4937 kill(getpid(),SIGSTOP);
4938 } else if (sig != TARGET_SIGCHLD &&
4939 sig != TARGET_SIGURG &&
4940 sig != TARGET_SIGWINCH &&
4941 sig != TARGET_SIGCONT) {
4942 force_sig(sig);
4943 }
4944 } else if (handler == TARGET_SIG_IGN) {
4945 /* ignore sig */
4946 } else if (handler == TARGET_SIG_ERR) {
4947 force_sig(sig);
4948 } else {
4949 /* compute the blocked signals during the handler execution */
4950 target_to_host_sigset(&set, &sa->sa_mask);
4951 /* SA_NODEFER indicates that the current signal should not be
4952 blocked during the handler */
4953 if (!(sa->sa_flags & TARGET_SA_NODEFER))
4954 sigaddset(&set, target_to_host_signal(sig));
4955
4956 /* block signals in the handler using Linux */
4957 sigprocmask(SIG_BLOCK, &set, &old_set);
4958 /* save the previous blocked signal state to restore it at the
4959 end of the signal execution (see do_sigreturn) */
4960 host_to_target_sigset_internal(&target_old_set, &old_set);
4961
4962 /* if the CPU is in VM86 mode, we restore the 32 bit values */
4963 #if defined(TARGET_I386) && !defined(TARGET_X86_64)
4964 {
4965 CPUX86State *env = cpu_env;
4966 if (env->eflags & VM_MASK)
4967 save_v86_state(env);
4968 }
4969 #endif
4970 /* prepare the stack frame of the virtual CPU */
4971 if (sa->sa_flags & TARGET_SA_SIGINFO)
4972 setup_rt_frame(sig, sa, &q->info, &target_old_set, cpu_env);
4973 else
4974 setup_frame(sig, sa, &target_old_set, cpu_env);
4975 if (sa->sa_flags & TARGET_SA_RESETHAND)
4976 sa->_sa_handler = TARGET_SIG_DFL;
4977 }
4978 if (q != &k->info)
4979 free_sigqueue(cpu_env, q);
4980 }