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