/* Copyright (c) 2013 The Regents of the University of California
 * Barret Rhoden <brho@cs.berkeley.edu>
 * Kevin Klues <klueska@cs.berkeley.edu>
 * See LICENSE for details.
 *
 * POSIX signal handling glue.  All glibc programs link against parlib, so they
 * will get this mixed in.  Mostly just registration of signal handlers.
 *
 * POSIX signal handling caveats:
 * - We don't copy signal handling tables or anything across forks or execs
 * - We don't send meaningful info in the siginfos, nor do we pass pid/uids on
 * signals coming from a kill.  This is especially pertinent for sigqueue,
 * which needs a payload (value) and sending PID
 * - We run handlers in vcore context, so any blocking syscall will spin.
 * Regular signals have restrictions on their syscalls too, though not this
 * great.  We could spawn off a uthread to run the handler, given that we have
 * a 2LS (which we don't for SCPs).
 * - We don't do anything with signal blocking/masking.  When in a signal
 * handler, you won't get interrupted with another signal handler (so long as
 * you run it in vcore context!).  With uthreads, you could get interrupted.
 * There is also no process wide signal blocking yet (sigprocmask()).  If this
 * is desired, we can abort certain signals when we h_p_signal(), 
 * - Likewise, we don't do waiting for particular signals yet.  Just about the
 * only thing we do is allow the registration of signal handlers. 
 * - Check each function for further notes.  */

// Needed for sigmask functions...
#define _GNU_SOURCE

#include <parlib/parlib.h>
#include <parlib/signal.h>
#include <parlib/uthread.h>
#include <parlib/event.h>
#include <parlib/ros_debug.h>
#include <errno.h>
#include <stdlib.h>
#include <parlib/assert.h>
#include <ros/procinfo.h>
#include <ros/syscall.h>
#include <sys/mman.h>
#include <parlib/stdio.h>

/* Forward declare our signal_ops functions. */
static int __sigaltstack(__const struct sigaltstack *__restrict __ss,
                         struct sigaltstack *__restrict __oss);
static int __siginterrupt(int __sig, int __interrupt);
static int __sigpending(sigset_t *__set);
static int __sigprocmask(int __how, __const sigset_t *__restrict __set,
                         sigset_t *__restrict __oset);
static int __sigqueue(__pid_t __pid, int __sig, __const union sigval __val);
static int __sigreturn(struct sigcontext *__scp);
static int __sigstack(struct sigstack *__ss, struct sigstack *__oss);
static int __sigsuspend(__const sigset_t *__set);
static int __sigtimedwait(__const sigset_t *__restrict __set,
                          siginfo_t *__restrict __info,
                          __const struct timespec *__restrict __timeout);
static int __sigwait(__const sigset_t *__restrict __set, int *__restrict __sig);
static int __sigwaitinfo(__const sigset_t *__restrict __set,
                         siginfo_t *__restrict __info);
static int __sigself(int signo);

/* The default definition of signal_ops (similar to sched_ops in uthread.c) */
struct signal_ops default_signal_ops = {
	.sigaltstack = __sigaltstack,
	.siginterrupt = __siginterrupt,
	.sigpending = __sigpending,
	.sigprocmask = __sigprocmask,
	.sigqueue = __sigqueue,
	.sigreturn = __sigreturn,
	.sigstack = __sigstack,
	.sigsuspend = __sigsuspend,
	.sigtimedwait = __sigtimedwait,
	.sigwait = __sigwait,
	.sigwaitinfo = __sigwaitinfo,
	.sigself = __sigself
};

/* This is the catch all akaros event->posix signal handler.  All posix signals
 * are received in a single akaros event type.  They are then dispatched from
 * this function to their proper posix signal handler */
static void handle_event(struct event_msg *ev_msg, unsigned int ev_type,
                         void *data)
{
	int sig_nr;
	struct siginfo info = {0};
	info.si_code = SI_USER;

	assert(ev_msg);
	sig_nr = ev_msg->ev_arg1;
	/* These POSIX signals are process-wide, but legacy applications and
	 * their signal handlers often expect the signals to be routed to
	 * particular threads.  This manifests in a couple ways: the signal
	 * handlers expect a user context, and the program expects syscalls to
	 * be interrupted.  Which context?  Which syscall?
	 *
	 * On Akaros, signals only go to the process, since there is no kernel
	 * notion of a thread/task within a process.  All knowledge of
	 * threads and how to resolve this mismatch between process-wide signals
	 * and threads is held in the 2LS.  If we wanted to abort a syscall,
	 * we'd need to know which one - after all, on Akaros syscalls are
	 * asynchronous and it is only in the 2LS that they are coupled to
	 * uthreads.  When it comes to routing the signal, the 2LS could do
	 * something like pthread_kill, or just execute the handler. */
	sched_ops->got_posix_signal(sig_nr, &info);
}

/* Called from uthread_slim_init() */
void init_posix_signals(void)
{
	struct event_queue *posix_sig_ev_q;

	signal_ops = &default_signal_ops;
	register_ev_handler(EV_POSIX_SIGNAL, handle_event, 0);
	posix_sig_ev_q = get_eventq(EV_MBOX_UCQ);
	assert(posix_sig_ev_q);
	posix_sig_ev_q->ev_flags = EVENT_IPI | EVENT_INDIR | EVENT_SPAM_INDIR |
	                           EVENT_WAKEUP;
	register_kevent_q(posix_sig_ev_q, EV_POSIX_SIGNAL);
}

/* Swap the contents of two user contexts (not just their pointers). */
static void swap_user_contexts(struct user_context *c1, struct user_context *c2)
{
	struct user_context temp_ctx;

	temp_ctx = *c1;
	*c1 = *c2;
	*c2 = temp_ctx;
}

/* Helper for checking a stack pointer.  It's possible the context we're
 * injecting signals into is complete garbage, so using the SP is a little
 * dangerous. */
static bool stack_ptr_is_sane(uintptr_t sp)
{
	if ((sp < PGSIZE) || (sp > ULIM))
		return FALSE;
	return TRUE;
}

static bool uth_is_handling_sigs(struct uthread *uth)
{
	return uth->sigstate.data ? TRUE : FALSE;
}

/* Prep a uthread to run a signal handler.  The original context of the uthread
 * is saved on its stack, and a new context is set up to run the signal handler
 * the next time the uthread is run. */
static void __prep_sighandler(struct uthread *uthread,
                              void (*entry)(void),
                              struct siginfo *info)
{
	uintptr_t stack;
	struct user_context *ctx;

	if (uthread->flags & UTHREAD_SAVED) {
		ctx = &uthread->u_ctx;
	} else {
		assert(current_uthread == uthread);
		ctx = &vcpd_of(vcore_id())->uthread_ctx;
	}
	stack = get_user_ctx_sp(ctx) - sizeof(struct sigdata);
	stack = ROUNDDOWN(stack, __alignof__(struct sigdata));
	assert(stack_ptr_is_sane(stack));
	uthread->sigstate.data = (struct sigdata*)stack;
	/* Parlib aggressively saves the FP state for HW and VM ctxs.  SW ctxs
	 * should not have FP state saved. */
	switch (ctx->type) {
	case ROS_HW_CTX:
	case ROS_VM_CTX:
		assert(uthread->flags & UTHREAD_FPSAVED);
		/* We need to save the already-saved FP state into the sigstate
		 * space.  The sig handler is taking over the uthread and its GP
		 * and FP spaces.
		 *
		 * If we ever go back to not aggressively saving the FP state,
		 * then for HW and VM ctxs, the state is in hardware.
		 * Regardless, we still need to save it in ->as, with something
		 * like: save_fp_state(&uthread->sigstate.data->as);
		 *
		 * Either way, when we're done with this entire function, the
		 * *uthread* will have ~UTHREAD_FPSAVED, since we will be
		 * talking about the SW context that is running the signal
		 * handler. */
		uthread->sigstate.data->as = uthread->as;
		uthread->flags &= ~UTHREAD_FPSAVED;
		break;
	case ROS_SW_CTX:
		assert(!(uthread->flags & UTHREAD_FPSAVED));
		break;
	};
	if (info != NULL)
		uthread->sigstate.data->info = *info;

	if (uthread->sigstate.sigalt_stacktop != 0)
		stack = uthread->sigstate.sigalt_stacktop;

	init_user_ctx(&uthread->sigstate.data->u_ctx, (uintptr_t)entry, stack);
	/* The uthread may or may not be UTHREAD_SAVED.  That depends on whether
	 * the uthread was in that state initially.  We're swapping into the
	 * location of 'ctx', which is either in VCPD or the uth itself. */
	swap_user_contexts(ctx, &uthread->sigstate.data->u_ctx);
}

/* Restore the context saved as the result of running a signal handler on a
 * uthread. This context will execute the next time the uthread is run. */
static void __restore_after_sighandler(struct uthread *uthread)
{
	uthread->u_ctx = uthread->sigstate.data->u_ctx;
	uthread->flags |= UTHREAD_SAVED;
	switch (uthread->u_ctx.type) {
	case ROS_HW_CTX:
	case ROS_VM_CTX:
		uthread->as = uthread->sigstate.data->as;
		uthread->flags |= UTHREAD_FPSAVED;
		break;
	}
	uthread->sigstate.data = NULL;
}

/* Callback when yielding a pthread after upon completion of a sighandler.  We
 * didn't save the current context on yeild, but that's ok because here we
 * restore the original saved context of the pthread and then treat this like a
 * normal voluntary yield. */
static void __exit_sighandler_cb(struct uthread *uthread, void *junk)
{
	__restore_after_sighandler(uthread);
	uthread_paused(uthread);
}

/* Run a specific sighandler from the top of the sigstate stack. The 'info'
 * struct is prepopulated before the call is triggered as the result of a
 * reflected fault. */
static void __run_sighandler(void)
{
	struct uthread *uthread = current_uthread;
	int signo = uthread->sigstate.data->info.si_signo;

	__sigdelset(&uthread->sigstate.pending, signo);
	trigger_posix_signal(signo, &uthread->sigstate.data->info,
	                     &uthread->sigstate.data->u_ctx);
	uthread_yield(FALSE, __exit_sighandler_cb, 0);
}

/* Run through all pending sighandlers and trigger them with a NULL info
 * field. These handlers are triggered as the result of thread directed
 * signals (i.e. not interprocess signals), and thus don't require individual
 * 'info' structs. */
static void __run_all_sighandlers(void)
{
	struct uthread *uthread = current_uthread;
	sigset_t andset = uthread->sigstate.pending & (~uthread->sigstate.mask);

	for (int i = 1; i < _NSIG; i++) {
		if (__sigismember(&andset, i)) {
			__sigdelset(&uthread->sigstate.pending, i);
			trigger_posix_signal(i, NULL,
					     &uthread->sigstate.data->u_ctx);
		}
	}
	uthread_yield(FALSE, __exit_sighandler_cb, 0);
}

int uthread_signal(struct uthread *uthread, int signo)
{
	// Slightly racy with clearing of mask when triggering the signal, but
	// that's OK, as signals are inherently racy since they don't queue up.
	return sigaddset(&uthread->sigstate.pending, signo);
}

/* If there are any pending signals, prep the uthread to run it's signal
 * handler. The next time the uthread is run, it will pop into it's signal
 * handler context instead of its original saved context. Once the signal
 * handler is complete, the original context will be restored and restarted. */
void uthread_prep_pending_signals(struct uthread *uthread)
{
	if (!uth_is_handling_sigs(uthread) && uthread->sigstate.pending) {
		sigset_t andset = uthread->sigstate.pending & (~uthread->sigstate.mask);

		if (!__sigisemptyset(&andset))
			__prep_sighandler(uthread, __run_all_sighandlers, NULL);
	}
}

/* If the given signal is unmasked, prep the uthread to run it's signal
 * handler, but don't run it yet. In either case, make the uthread runnable
 * again. Once the signal handler is complete, the original context will be
 * restored and restarted. */
void uthread_prep_signal_from_fault(struct uthread *uthread,
                                    int signo, int code, void *addr)
{
	if (!__sigismember(&uthread->sigstate.mask, signo)) {
		struct siginfo info = {0};

		if (uth_is_handling_sigs(uthread)) {
			printf("Uthread sighandler faulted, signal: %d\n",
			       signo);
			/* uthread.c already copied out the faulting ctx into
			 * the uth */
			print_user_context(&uthread->u_ctx);
			exit(-1);
		}
		info.si_signo = signo;
		info.si_code = code;
		info.si_addr = addr;
		__prep_sighandler(uthread, __run_sighandler, &info);
	}
}

/* This is managed by vcore / 2LS code */
static int __sigaltstack(__const struct sigaltstack *__restrict __ss,
                         struct sigaltstack *__restrict __oss)
{
	if (__ss->ss_flags != 0) {
		errno = EINVAL;
		return -1;
	}
	if (__oss != NULL) {
		errno = EINVAL;
		return -1;
	}
	if (__ss->ss_size < MINSIGSTKSZ) {
		errno = ENOMEM;
		return -1;
	}
	uintptr_t stack_top = (uintptr_t) __ss->ss_sp + __ss->ss_size;

	current_uthread->sigstate.sigalt_stacktop = stack_top;
	return 0;
}

/* Akaros can't have signals interrupt syscalls to need a restart, though we can
 * re-wake-up the process while it is waiting for its syscall. */
static int __siginterrupt(int __sig, int __interrupt)
{
	return 0;
}

/* Not really possible or relevant - you'd need to walk/examine the event UCQ */
static int __sigpending(sigset_t *__set)
{
	return 0;
}

static int __sigprocmask(int __how, __const sigset_t *__restrict __set,
                         sigset_t *__restrict __oset)
{
	sigset_t *sigmask;

	/* Signal handlers might call sigprocmask, with the intent of affecting
	 * the uthread's sigmask.  Process-wide signal handlers run on behalf of
	 * the entire process and aren't bound to a uthread, which means
	 * sigprocmask won't work.  We can tell we're running one of these
	 * handlers since we are in vcore context.  Uthread signals (e.g.
	 * pthread_kill()) run from uthread context. */
	if (in_vcore_context()) {
		errno = ENOENT;
		return -1;
	}

	sigmask = &current_uthread->sigstate.mask;

	if (__set && (__how != SIG_BLOCK) &&
	             (__how != SIG_SETMASK) &&
	             (__how != SIG_UNBLOCK)) {
		errno = EINVAL;
		return -1;
	}

	if (__oset)
		*__oset = *sigmask;
	if (__set) {
		switch (__how) {
			case SIG_BLOCK:
				*sigmask = *sigmask | *__set;
				break;
			case SIG_SETMASK:
				*sigmask = *__set;
				break;
			case SIG_UNBLOCK:
				*sigmask = *sigmask & ~(*__set);
				break;
		}
	}
	return 0;
}

/* Needs support with trigger_posix_signal to deal with passing values with
 * POSIX signals. */
static int __sigqueue(__pid_t __pid, int __sig, __const union sigval __val)
{
	return 0;
}

/* Linux specific, and not really needed for us */
static int __sigreturn(struct sigcontext *__scp)
{
	return 0;
}

/* This is managed by vcore / 2LS code */
static int __sigstack(struct sigstack *__ss, struct sigstack *__oss)
{
	return 0;
}

/* Could do this with a loop on delivery of the signal, sleeping and getting
 * woken up by the kernel on any event, like we do with async syscalls. */
static int __sigsuspend(__const sigset_t *__set)
{
	return 0;
}

/* Can be done similar to sigsuspend, with an extra alarm syscall */
static int __sigtimedwait(__const sigset_t *__restrict __set,
                          siginfo_t *__restrict __info,
                          __const struct timespec *__restrict __timeout)
{
	return 0;
}

/* Can be done similar to sigsuspend */
static int __sigwait(__const sigset_t *__restrict __set, int *__restrict __sig)
{
	return 0;
}

/* Can be done similar to sigsuspend */
static int __sigwaitinfo(__const sigset_t *__restrict __set,
                         siginfo_t *__restrict __info)
{
	return 0;
}

static int __sigself(int signo)
{
	int ret;

	if (in_vcore_context())
		return kill(getpid(), signo);

	ret = uthread_signal(current_uthread, signo);

	void cb(struct uthread *uthread, void *arg)
	{
		uthread_paused(uthread);
	}
	if (ret == 0)
		uthread_yield(TRUE, cb, 0);
	return ret;
}
