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