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