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