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