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