/*
 *  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");
#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, CPUX86State *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(CPUX86State *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, CPUArchState *env)
{
    fprintf(stderr, "setup_frame: not implemented\n");
}

long do_sigreturn(CPUArchState *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);
}
