/*
 *  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 "user-internals.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 void 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->pc, &gregs[27]);
    __put_user(env->regs[R_SP], &gregs[28]);
}

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

    /* 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->pc, &gregs[27]);

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

    target_restore_altstack(&uc->tuc_stack, env);
    return 0;
}

static abi_ptr 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 (usp - frame_size) & -8;
}

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;
    abi_ptr frame_addr;
    int i;

    frame_addr = get_sigframe(ka, env, sizeof(*frame));
    if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0)) {
        force_sigsegv(sig);
        return;
    }

    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);
    rt_setup_ucontext(&frame->uc, env);
    for (i = 0; i < TARGET_NSIG_WORDS; i++) {
        __put_user(set->sig[i], &frame->uc.tuc_sigmask.sig[i]);
    }

    /* 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] = frame_addr;
    env->regs[4] = sig;
    env->regs[5] = frame_addr + offsetof(struct target_rt_sigframe, info);
    env->regs[6] = frame_addr + offsetof(struct target_rt_sigframe, uc);
    env->pc = ka->_sa_handler;

    unlock_user_struct(frame, frame_addr, 1);
}

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;

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

    target_to_host_sigset(&set, &frame->uc.tuc_sigmask);
    set_sigmask(&set);

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

    unlock_user_struct(frame, frame_addr, 0);
    return -QEMU_ESIGRETURN;

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