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