/*
 *  Emulation of Linux signals
 *
 *  Copyright (c) 2003 Fabrice Bellard
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, see <http://www.gnu.org/licenses/>.
 */
#include "qemu/osdep.h"
#include "qemu.h"
#include "target_signal.h"
#include "signal-common.h"
#include "linux-user/trace.h"

#define MCONTEXT_VERSION 2

struct target_sigcontext {
    int version;
    unsigned long gregs[32];
};

struct target_ucontext {
    abi_ulong tuc_flags;
    abi_ulong tuc_link;
    target_stack_t tuc_stack;
    struct target_sigcontext tuc_mcontext;
    target_sigset_t tuc_sigmask;   /* mask last for extensibility */
};

struct target_rt_sigframe {
    struct target_siginfo info;
    struct target_ucontext uc;
};

static int rt_setup_ucontext(struct target_ucontext *uc, CPUNios2State *env)
{
    unsigned long *gregs = uc->tuc_mcontext.gregs;

    __put_user(MCONTEXT_VERSION, &uc->tuc_mcontext.version);
    __put_user(env->regs[1], &gregs[0]);
    __put_user(env->regs[2], &gregs[1]);
    __put_user(env->regs[3], &gregs[2]);
    __put_user(env->regs[4], &gregs[3]);
    __put_user(env->regs[5], &gregs[4]);
    __put_user(env->regs[6], &gregs[5]);
    __put_user(env->regs[7], &gregs[6]);
    __put_user(env->regs[8], &gregs[7]);
    __put_user(env->regs[9], &gregs[8]);
    __put_user(env->regs[10], &gregs[9]);
    __put_user(env->regs[11], &gregs[10]);
    __put_user(env->regs[12], &gregs[11]);
    __put_user(env->regs[13], &gregs[12]);
    __put_user(env->regs[14], &gregs[13]);
    __put_user(env->regs[15], &gregs[14]);
    __put_user(env->regs[16], &gregs[15]);
    __put_user(env->regs[17], &gregs[16]);
    __put_user(env->regs[18], &gregs[17]);
    __put_user(env->regs[19], &gregs[18]);
    __put_user(env->regs[20], &gregs[19]);
    __put_user(env->regs[21], &gregs[20]);
    __put_user(env->regs[22], &gregs[21]);
    __put_user(env->regs[23], &gregs[22]);
    __put_user(env->regs[R_RA], &gregs[23]);
    __put_user(env->regs[R_FP], &gregs[24]);
    __put_user(env->regs[R_GP], &gregs[25]);
    __put_user(env->regs[R_EA], &gregs[27]);
    __put_user(env->regs[R_SP], &gregs[28]);

    return 0;
}

static int rt_restore_ucontext(CPUNios2State *env, struct target_ucontext *uc,
                               int *pr2)
{
    int temp;
    abi_ulong off, frame_addr = env->regs[R_SP];
    unsigned long *gregs = uc->tuc_mcontext.gregs;
    int err;

    /* Always make any pending restarted system calls return -EINTR */
    /* current->restart_block.fn = do_no_restart_syscall; */

    __get_user(temp, &uc->tuc_mcontext.version);
    if (temp != MCONTEXT_VERSION) {
        return 1;
    }

    /* restore passed registers */
    __get_user(env->regs[1], &gregs[0]);
    __get_user(env->regs[2], &gregs[1]);
    __get_user(env->regs[3], &gregs[2]);
    __get_user(env->regs[4], &gregs[3]);
    __get_user(env->regs[5], &gregs[4]);
    __get_user(env->regs[6], &gregs[5]);
    __get_user(env->regs[7], &gregs[6]);
    __get_user(env->regs[8], &gregs[7]);
    __get_user(env->regs[9], &gregs[8]);
    __get_user(env->regs[10], &gregs[9]);
    __get_user(env->regs[11], &gregs[10]);
    __get_user(env->regs[12], &gregs[11]);
    __get_user(env->regs[13], &gregs[12]);
    __get_user(env->regs[14], &gregs[13]);
    __get_user(env->regs[15], &gregs[14]);
    __get_user(env->regs[16], &gregs[15]);
    __get_user(env->regs[17], &gregs[16]);
    __get_user(env->regs[18], &gregs[17]);
    __get_user(env->regs[19], &gregs[18]);
    __get_user(env->regs[20], &gregs[19]);
    __get_user(env->regs[21], &gregs[20]);
    __get_user(env->regs[22], &gregs[21]);
    __get_user(env->regs[23], &gregs[22]);
    /* gregs[23] is handled below */
    /* Verify, should this be settable */
    __get_user(env->regs[R_FP], &gregs[24]);
    /* Verify, should this be settable */
    __get_user(env->regs[R_GP], &gregs[25]);
    /* Not really necessary no user settable bits */
    __get_user(temp, &gregs[26]);
    __get_user(env->regs[R_EA], &gregs[27]);

    __get_user(env->regs[R_RA], &gregs[23]);
    __get_user(env->regs[R_SP], &gregs[28]);

    off = offsetof(struct target_rt_sigframe, uc.tuc_stack);
    err = do_sigaltstack(frame_addr + off, 0, get_sp_from_cpustate(env));
    if (err == -EFAULT) {
        return 1;
    }

    *pr2 = env->regs[2];
    return 0;
}

static void *get_sigframe(struct target_sigaction *ka, CPUNios2State *env,
                          size_t frame_size)
{
    unsigned long usp;

    /* This is the X/Open sanctioned signal stack switching.  */
    usp = target_sigsp(get_sp_from_cpustate(env), ka);

    /* Verify, is it 32 or 64 bit aligned */
    return (void *)((usp - frame_size) & -8UL);
}

void setup_rt_frame(int sig, struct target_sigaction *ka,
                    target_siginfo_t *info,
                    target_sigset_t *set,
                    CPUNios2State *env)
{
    struct target_rt_sigframe *frame;
    int i, err = 0;

    frame = get_sigframe(ka, env, sizeof(*frame));

    if (ka->sa_flags & SA_SIGINFO) {
        tswap_siginfo(&frame->info, info);
    }

    /* Create the ucontext.  */
    __put_user(0, &frame->uc.tuc_flags);
    __put_user(0, &frame->uc.tuc_link);
    target_save_altstack(&frame->uc.tuc_stack, env);
    err |= rt_setup_ucontext(&frame->uc, env);
    for (i = 0; i < TARGET_NSIG_WORDS; i++) {
        __put_user((abi_ulong)set->sig[i],
            (abi_ulong *)&frame->uc.tuc_sigmask.sig[i]);
    }

    if (err) {
        goto give_sigsegv;
    }

    /* Set up to return from userspace; jump to fixed address sigreturn
       trampoline on kuser page.  */
    env->regs[R_RA] = (unsigned long) (0x1044);

    /* Set up registers for signal handler */
    env->regs[R_SP] = (unsigned long) frame;
    env->regs[4] = (unsigned long) sig;
    env->regs[5] = (unsigned long) &frame->info;
    env->regs[6] = (unsigned long) &frame->uc;
    env->regs[R_EA] = (unsigned long) ka->_sa_handler;
    return;

give_sigsegv:
    if (sig == TARGET_SIGSEGV) {
        ka->_sa_handler = TARGET_SIG_DFL;
    }
    force_sigsegv(sig);
    return;
}

long do_sigreturn(CPUNios2State *env)
{
    trace_user_do_sigreturn(env, 0);
    fprintf(stderr, "do_sigreturn: not implemented\n");
    return -TARGET_ENOSYS;
}

long do_rt_sigreturn(CPUNios2State *env)
{
    /* Verify, can we follow the stack back */
    abi_ulong frame_addr = env->regs[R_SP];
    struct target_rt_sigframe *frame;
    sigset_t set;
    int rval;

    if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1)) {
        goto badframe;
    }

    target_to_host_sigset(&set, &frame->uc.tuc_sigmask);
    do_sigprocmask(SIG_SETMASK, &set, NULL);

    if (rt_restore_ucontext(env, &frame->uc, &rval)) {
        goto badframe;
    }

    unlock_user_struct(frame, frame_addr, 0);
    return rval;

badframe:
    unlock_user_struct(frame, frame_addr, 0);
    force_sig(TARGET_SIGSEGV);
    return 0;
}
