/*
 *  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 <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <stdarg.h>
#include <unistd.h>
#include <errno.h>
#include <sys/ucontext.h>

#ifdef __ia64__
#undef uc_mcontext
#undef uc_sigmask
#undef uc_stack
#undef uc_link
#endif

#include "qemu.h"
#include "qemu-common.h"

#define DEBUG_SIGNAL

#define MAX_SIGQUEUE_SIZE 1024

struct sigqueue {
    struct sigqueue *next;
    target_siginfo_t info;
};

struct emulated_sigaction {
    struct target_sigaction sa;
    int pending; /* true if signal is pending */
    struct sigqueue *first;
    struct sigqueue info; /* in order to always have memory for the
                             first signal, we put it here */
};

static struct sigaltstack target_sigaltstack_used = {
    0, 0, SA_DISABLE
};

static struct emulated_sigaction sigact_table[NSIG];
static struct sigqueue sigqueue_table[MAX_SIGQUEUE_SIZE]; /* siginfo queue */
static struct sigqueue *first_free; /* first free siginfo queue entry */
static int signal_pending; /* non zero if a signal may be pending */

static void host_signal_handler(int host_signum, siginfo_t *info,
                                void *puc);


static inline int host_to_target_signal(int sig)
{
    return sig;
}

static inline int target_to_host_signal(int sig)
{
    return sig;
}

/* siginfo conversion */



void host_to_target_siginfo(target_siginfo_t *tinfo, const siginfo_t *info)
{

}

void target_to_host_siginfo(siginfo_t *info, const target_siginfo_t *tinfo)
{

}

void signal_init(void)
{
    struct sigaction act;
    int i;

    /* set all host signal handlers. ALL signals are blocked during
       the handlers to serialize them. */
    sigfillset(&act.sa_mask);
    act.sa_flags = SA_SIGINFO;
    act.sa_sigaction = host_signal_handler;
    for(i = 1; i < NSIG; i++) {
        sigaction(i, &act, NULL);
    }

    memset(sigact_table, 0, sizeof(sigact_table));

    first_free = &sigqueue_table[0];
    for(i = 0; i < MAX_SIGQUEUE_SIZE - 1; i++)
        sigqueue_table[i].next = &sigqueue_table[i + 1];
    sigqueue_table[MAX_SIGQUEUE_SIZE - 1].next = NULL;
}

/* signal queue handling */

static inline struct sigqueue *alloc_sigqueue(void)
{
    struct sigqueue *q = first_free;
    if (!q)
        return NULL;
    first_free = q->next;
    return q;
}

static inline void free_sigqueue(struct sigqueue *q)
{
    q->next = first_free;
    first_free = q;
}

/* abort execution with signal */
void QEMU_NORETURN force_sig(int sig)
{
    int host_sig;
    host_sig = target_to_host_signal(sig);
    fprintf(stderr, "qemu: uncaught target signal %d (%s) - exiting\n",
            sig, strsignal(host_sig));
    _exit(-host_sig);
}

/* queue a signal so that it will be send to the virtual CPU as soon
   as possible */
int queue_signal(int sig, target_siginfo_t *info)
{
    struct emulated_sigaction *k;
    struct sigqueue *q, **pq;
    target_ulong handler;

#if defined(DEBUG_SIGNAL)
    fprintf(stderr, "queue_signal: sig=%d\n",
            sig);
#endif
    k = &sigact_table[sig - 1];
    handler = (target_ulong)k->sa.sa_handler;
    if (handler == SIG_DFL) {
        /* default handler : ignore some signal. The other are fatal */
        if (sig != SIGCHLD &&
            sig != SIGURG &&
            sig != SIGWINCH) {
            force_sig(sig);
        } else {
            return 0; /* indicate ignored */
        }
    } else if (handler == host_to_target_signal(SIG_IGN)) {
        /* ignore signal */
        return 0;
    } else if (handler == host_to_target_signal(SIG_ERR)) {
        force_sig(sig);
    } else {
        pq = &k->first;
        if (!k->pending) {
            /* first signal */
            q = &k->info;
        } else {
            q = alloc_sigqueue();
            if (!q)
                return -EAGAIN;
            while (*pq != NULL)
                pq = &(*pq)->next;
        }
        *pq = q;
        q->info = *info;
        q->next = NULL;
        k->pending = 1;
        /* signal that a new signal is pending */
        signal_pending = 1;
        return 1; /* indicates that the signal was queued */
    }
}

static void host_signal_handler(int host_signum, siginfo_t *info,
                                void *puc)
{
    int sig;
    target_siginfo_t tinfo;

    /* the CPU emulator uses some host signals to detect exceptions,
       we we forward to it some signals */
    if (host_signum == SIGSEGV || host_signum == SIGBUS) {
        if (cpu_signal_handler(host_signum, (void*)info, puc))
            return;
    }

    /* get target signal number */
    sig = host_to_target_signal(host_signum);
    if (sig < 1 || sig > NSIG)
        return;

#if defined(DEBUG_SIGNAL)
	fprintf(stderr, "qemu: got signal %d\n", sig);
#endif
    if (queue_signal(sig, &tinfo) == 1) {
        /* interrupt the virtual CPU as soon as possible */
        cpu_exit(global_env);
    }
}

int do_sigaltstack(const struct sigaltstack *ss, struct sigaltstack *oss)
{
    /* XXX: test errors */
    if(oss)
    {
        oss->ss_sp = tswap32(target_sigaltstack_used.ss_sp);
        oss->ss_size = tswap32(target_sigaltstack_used.ss_size);
        oss->ss_flags = tswap32(target_sigaltstack_used.ss_flags);
    }
    if(ss)
    {
        target_sigaltstack_used.ss_sp = tswap32(ss->ss_sp);
        target_sigaltstack_used.ss_size = tswap32(ss->ss_size);
        target_sigaltstack_used.ss_flags = tswap32(ss->ss_flags);
    }
    return 0;
}

int do_sigaction(int sig, const struct sigaction *act,
                 struct sigaction *oact)
{
    struct emulated_sigaction *k;
    struct sigaction act1;
    int host_sig;

    if (sig < 1 || sig > NSIG)
        return -EINVAL;

    k = &sigact_table[sig - 1];
#if defined(DEBUG_SIGNAL)
    fprintf(stderr, "sigaction 1 sig=%d act=0x%08x, oact=0x%08x\n",
            sig, (int)act, (int)oact);
#endif
    if (oact) {
#if defined(DEBUG_SIGNAL)
    fprintf(stderr, "sigaction 1 sig=%d act=0x%08x, oact=0x%08x\n",
            sig, (int)act, (int)oact);
#endif

        oact->sa_handler = tswapl(k->sa.sa_handler);
        oact->sa_flags = tswapl(k->sa.sa_flags);
        oact->sa_mask = tswapl(k->sa.sa_mask);
    }
    if (act) {
#if defined(DEBUG_SIGNAL)
    fprintf(stderr, "sigaction handler 0x%x flag 0x%x mask 0x%x\n",
            act->sa_handler, act->sa_flags, act->sa_mask);
#endif

        k->sa.sa_handler = tswapl(act->sa_handler);
        k->sa.sa_flags = tswapl(act->sa_flags);
        k->sa.sa_mask = tswapl(act->sa_mask);
        /* we update the host signal state */
        host_sig = target_to_host_signal(sig);
        if (host_sig != SIGSEGV && host_sig != SIGBUS) {
#if defined(DEBUG_SIGNAL)
    fprintf(stderr, "sigaction handler going to call sigaction\n",
            act->sa_handler, act->sa_flags, act->sa_mask);
#endif

            sigfillset(&act1.sa_mask);
            act1.sa_flags = SA_SIGINFO;
            if (k->sa.sa_flags & SA_RESTART)
                act1.sa_flags |= SA_RESTART;
            /* NOTE: it is important to update the host kernel signal
               ignore state to avoid getting unexpected interrupted
               syscalls */
            if (k->sa.sa_handler == SIG_IGN) {
                act1.sa_sigaction = (void *)SIG_IGN;
            } else if (k->sa.sa_handler == SIG_DFL) {
                act1.sa_sigaction = (void *)SIG_DFL;
            } else {
                act1.sa_sigaction = host_signal_handler;
            }
            sigaction(host_sig, &act1, NULL);
        }
    }
    return 0;
}


#ifdef TARGET_I386

static inline void *
get_sigframe(struct emulated_sigaction *ka, CPUX86State *env, size_t frame_size)
{
    /* XXX Fix that */
    if(target_sigaltstack_used.ss_flags & SA_DISABLE)
    {
        int esp;
        /* Default to using normal stack */
        esp = env->regs[R_ESP];

        return (void *)((esp - frame_size) & -8ul);
    }
    else
    {
        return target_sigaltstack_used.ss_sp;
    }
}

static void setup_frame(int sig, struct emulated_sigaction *ka,
			void *set, CPUState *env)
{
	void *frame;

    fprintf(stderr, "setup_frame %d\n", sig);
	frame = get_sigframe(ka, env, sizeof(*frame));

	/* Set up registers for signal handler */
	env->regs[R_ESP] = (unsigned long) frame;
	env->eip = (unsigned long) ka->sa.sa_handler;

	env->eflags &= ~TF_MASK;

	return;

give_sigsegv:
	if (sig == SIGSEGV)
		ka->sa.sa_handler = SIG_DFL;
	force_sig(SIGSEGV /* , current */);
}

long do_sigreturn(CPUState *env, int num)
{
    int i = 0;
    struct target_sigcontext *scp = get_int_arg(&i, env);
    /* XXX Get current signal number */
    /* XXX Adjust accordin to sc_onstack, sc_mask */
    if(tswapl(scp->sc_onstack) & 0x1)
        target_sigaltstack_used.ss_flags |= ~SA_DISABLE;
    else
        target_sigaltstack_used.ss_flags &=  SA_DISABLE;
    int set = tswapl(scp->sc_eax);
    sigprocmask(SIG_SETMASK, &set, NULL);

    fprintf(stderr, "do_sigreturn: partially implemented %x EAX:%x EBX:%x\n", scp->sc_mask, tswapl(scp->sc_eax), tswapl(scp->sc_ebx));
    fprintf(stderr, "ECX:%x EDX:%x EDI:%x\n", scp->sc_ecx, tswapl(scp->sc_edx), tswapl(scp->sc_edi));
    fprintf(stderr, "EIP:%x\n", tswapl(scp->sc_eip));

    env->regs[R_EAX] = tswapl(scp->sc_eax);
    env->regs[R_EBX] = tswapl(scp->sc_ebx);
    env->regs[R_ECX] = tswapl(scp->sc_ecx);
    env->regs[R_EDX] = tswapl(scp->sc_edx);
    env->regs[R_EDI] = tswapl(scp->sc_edi);
    env->regs[R_ESI] = tswapl(scp->sc_esi);
    env->regs[R_EBP] = tswapl(scp->sc_ebp);
    env->regs[R_ESP] = tswapl(scp->sc_esp);
    env->segs[R_SS].selector = (void*)tswapl(scp->sc_ss);
    env->eflags = tswapl(scp->sc_eflags);
    env->eip = tswapl(scp->sc_eip);
    env->segs[R_CS].selector = (void*)tswapl(scp->sc_cs);
    env->segs[R_DS].selector = (void*)tswapl(scp->sc_ds);
    env->segs[R_ES].selector = (void*)tswapl(scp->sc_es);
    env->segs[R_FS].selector = (void*)tswapl(scp->sc_fs);
    env->segs[R_GS].selector = (void*)tswapl(scp->sc_gs);

    /* Again, because our caller's caller will reset EAX */
    return env->regs[R_EAX];
}

#else

static void setup_frame(int sig, struct emulated_sigaction *ka,
			void *set, CPUState *env)
{
    fprintf(stderr, "setup_frame: not implemented\n");
}

long do_sigreturn(CPUState *env, int num)
{
    int i = 0;
    struct target_sigcontext *scp = get_int_arg(&i, env);
    fprintf(stderr, "do_sigreturn: not implemented\n");
    return -ENOSYS;
}

#endif

void process_pending_signals(void *cpu_env)
{
    struct emulated_sigaction *k;
    struct sigqueue *q;
    target_ulong handler;
    int sig;

    if (!signal_pending)
        return;

    k = sigact_table;

    for(sig = 1; sig <= NSIG; sig++) {
        if (k->pending)
            goto handle_signal;
        k++;
    }

    /* if no signal is pending, just return */
    signal_pending = 0;
    return;
handle_signal:
    #ifdef DEBUG_SIGNAL
    fprintf(stderr, "qemu: process signal %d\n", sig);
    #endif
    /* dequeue signal */
    q = k->first;
    k->first = q->next;
    if (!k->first)
        k->pending = 0;

    sig = gdb_handlesig (cpu_env, sig);
    if (!sig) {
        fprintf (stderr, "Lost signal\n");
        abort();
    }

    handler = k->sa.sa_handler;
    if (handler == SIG_DFL) {
        /* default handler : ignore some signal. The other are fatal */
        if (sig != SIGCHLD &&
            sig != SIGURG &&
            sig != SIGWINCH) {
            force_sig(sig);
        }
    } else if (handler == SIG_IGN) {
        /* ignore sig */
    } else if (handler == SIG_ERR) {
        force_sig(sig);
    } else {

        setup_frame(sig, k, 0, cpu_env);
	if (k->sa.sa_flags & SA_RESETHAND)
            k->sa.sa_handler = SIG_DFL;
    }
    if (q != &k->info)
        free_sigqueue(q);
}
