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