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