// Copyright 2021 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

use crate::logging::strace;
use crate::signals::*;
use crate::task::*;
use crate::types::*;

use fuchsia_zircon as zx;

/// The size of the red zone.
///
/// From the AMD64 ABI:
///   > The 128-byte area beyond the location pointed to
///   > by %rsp is considered to be reserved and shall not be modified by signal or
///   > interrupt handlers. Therefore, functions may use this area for temporary
///   > data that is not needed across function calls. In particular, leaf functions
///   > may use this area for their entire stack frame, rather than adjusting the
///   > stack pointer in the prologue and epilogue. This area is known as the red
///   > zone.
#[cfg(target_arch = "x86_64")]
const RED_ZONE_SIZE: u64 = 128;

/// The size of the syscall instruction in bytes.
#[cfg(target_arch = "x86_64")]
const SYSCALL_INSTRUCTION_SIZE_BYTES: u64 = 2;

/// A `SignalStackFrame` contains all the state that is stored on the stack prior
/// to executing a signal handler.
///
/// The ordering of the fields is significant, as it is part of the syscall ABI. In particular,
/// restorer_address must be the first field, since that is where the signal handler will return
/// after it finishes executing.
#[repr(C)]
#[cfg(target_arch = "x86_64")]
struct SignalStackFrame {
    /// The address of the signal handler function.
    ///
    /// Must be the first field, to be positioned to serve as the return address.
    restorer_address: u64,

    /// Information about the signal.
    siginfo_bytes: [u8; std::mem::size_of::<siginfo_t>()],

    /// The state of the thread at the time the signal was handled.
    context: ucontext,
    /// The FPU state. Must be immediately after the ucontext field, since Bionic considers this to
    /// be part of the ucontext for some reason.
    fpstate: _fpstate_64,
}

const SIG_STACK_SIZE: usize = std::mem::size_of::<SignalStackFrame>();

impl SignalStackFrame {
    fn new(siginfo: &SignalInfo, context: ucontext, restorer_address: u64) -> SignalStackFrame {
        SignalStackFrame {
            context,
            siginfo_bytes: siginfo.as_siginfo_bytes(),
            restorer_address,
            fpstate: Default::default(),
        }
    }

    fn as_bytes(self) -> [u8; SIG_STACK_SIZE] {
        unsafe { std::mem::transmute(self) }
    }

    fn from_bytes(bytes: [u8; SIG_STACK_SIZE]) -> SignalStackFrame {
        unsafe { std::mem::transmute(bytes) }
    }
}

/// Aligns the stack pointer to be 16 byte aligned, and then misaligns it by 8 bytes.
///
/// This is done because x86-64 functions expect the stack to be misaligned by 8 bytes,
/// as if the stack was 16 byte aligned and then someone used a call instruction. This
/// is due to alignment-requiring SSE instructions.
fn misalign_stack_pointer(pointer: u64) -> u64 {
    pointer - (pointer % 16 + 8)
}

/// Prepares `current` state to execute the signal handler stored in `action`.
///
/// This function stores the state required to restore after the signal handler on the stack.
// TODO(lindkvist): Honor the flags in `sa_flags`.
fn dispatch_signal_handler(
    current_task: &mut CurrentTask,
    signal_state: &mut SignalState,
    siginfo: SignalInfo,
    action: sigaction_t,
) {
    let signal_stack_frame = SignalStackFrame::new(
        &siginfo,
        ucontext {
            uc_mcontext: sigcontext {
                r8: current_task.registers.r8,
                r9: current_task.registers.r9,
                r10: current_task.registers.r10,
                r11: current_task.registers.r11,
                r12: current_task.registers.r12,
                r13: current_task.registers.r13,
                r14: current_task.registers.r14,
                r15: current_task.registers.r15,
                rdi: current_task.registers.rdi,
                rsi: current_task.registers.rsi,
                rbp: current_task.registers.rbp,
                rbx: current_task.registers.rbx,
                rdx: current_task.registers.rdx,
                rax: current_task.registers.rax,
                rcx: current_task.registers.rcx,
                rsp: current_task.registers.rsp,
                rip: current_task.registers.rip,
                eflags: current_task.registers.rflags,
                oldmask: signal_state.mask,
                ..Default::default()
            },
            uc_stack: signal_state
                .alt_stack
                .map(|stack| sigaltstack {
                    ss_sp: stack.ss_sp.ptr() as *mut c_void,
                    ss_flags: stack.ss_flags as i32,
                    ss_size: stack.ss_size,
                    ..Default::default()
                })
                .unwrap_or(sigaltstack::default()),
            uc_sigmask: signal_state.mask,
            ..Default::default()
        },
        action.sa_restorer.ptr() as u64,
    );

    // Determine which stack pointer to use for the signal handler.
    // If the signal handler is executed on the main stack, adjust the stack pointer to account for
    // the red zone.
    // https://en.wikipedia.org/wiki/Red_zone_%28computing%29
    let mut stack_pointer = if (action.sa_flags & SA_ONSTACK as u64) != 0 {
        match signal_state.alt_stack {
            Some(sigaltstack) => {
                // Since the stack grows down, the size is added to the ss_sp when calculating the
                // "bottom" of the stack.
                (sigaltstack.ss_sp.ptr() + sigaltstack.ss_size) as u64
            }
            None => current_task.registers.rsp - RED_ZONE_SIZE,
        }
    } else {
        current_task.registers.rsp - RED_ZONE_SIZE
    };
    stack_pointer -= SIG_STACK_SIZE as u64;
    stack_pointer = misalign_stack_pointer(stack_pointer);

    // Write the signal stack frame at the updated stack pointer.
    current_task
        .mm
        .write_memory(UserAddress::from(stack_pointer), &signal_stack_frame.as_bytes())
        .unwrap();

    signal_state.set_signal_mask(action.sa_mask);

    current_task.registers.rsp = stack_pointer;
    current_task.registers.rdi = siginfo.signal.number() as u64;
    if (action.sa_flags & SA_SIGINFO as u64) != 0 {
        current_task.registers.rsi =
            stack_pointer + memoffset::offset_of!(SignalStackFrame, siginfo_bytes) as u64;
        current_task.registers.rdx =
            stack_pointer + memoffset::offset_of!(SignalStackFrame, context) as u64;
    }
    current_task.registers.rip = action.sa_handler.ptr() as u64;
}

pub fn restore_from_signal_handler(current_task: &mut CurrentTask) -> Result<(), Errno> {
    // The stack pointer was intentionally misaligned, so this must be done
    // again to get the correct address for the stack frame.
    let signal_frame_address = misalign_stack_pointer(current_task.registers.rsp);
    let mut signal_stack_bytes = [0; SIG_STACK_SIZE];
    current_task
        .mm
        .read_memory(UserAddress::from(signal_frame_address), &mut signal_stack_bytes)?;

    let signal_stack_frame = SignalStackFrame::from_bytes(signal_stack_bytes);
    let uctx = &signal_stack_frame.context.uc_mcontext;
    // Restore the register state from before executing the signal handler.
    current_task.registers = zx::sys::zx_thread_state_general_regs_t {
        r8: uctx.r8,
        r9: uctx.r9,
        r10: uctx.r10,
        r11: uctx.r11,
        r12: uctx.r12,
        r13: uctx.r13,
        r14: uctx.r14,
        r15: uctx.r15,
        rax: uctx.rax,
        rbx: uctx.rbx,
        rcx: uctx.rcx,
        rdx: uctx.rdx,
        rsi: uctx.rsi,
        rdi: uctx.rdi,
        rbp: uctx.rbp,
        rsp: uctx.rsp,
        rip: uctx.rip,
        rflags: uctx.eflags,
        fs_base: current_task.registers.fs_base,
        gs_base: current_task.registers.gs_base,
    }
    .into();
    current_task.write().signals.mask = signal_stack_frame.context.uc_sigmask;
    Ok(())
}

pub fn send_signal(task: &Task, siginfo: SignalInfo) {
    let mut task_state = task.write();
    task_state.signals.enqueue(siginfo.clone());

    let action_is_masked = siginfo.signal.is_in_set(task_state.signals.mask);
    let action = action_for_signal(&siginfo, task.thread_group.signal_actions.get(siginfo.signal));
    drop(task_state);

    // SIGKILL is handled without waiting to the signal to be dequeued.
    if siginfo.signal == SIGKILL {
        task.thread_group.exit(ExitStatus::Kill(siginfo));
        return;
    }

    // When receiving SIGCONT or any signal that must block the process, the task state must be updated immediately.
    if siginfo.signal == SIGCONT || (!action_is_masked && action == DeliveryAction::Stop) {
        let stopped = siginfo.signal != SIGCONT;
        task.thread_group.set_stopped(stopped, siginfo);
    }

    if !action_is_masked && action.must_interrupt() {
        // Wake the task. Note that any potential signal handler will be executed before
        // the task returns from the suspend (from the perspective of user space).
        task.interrupt(InterruptionType::Signal);
    }
}

pub fn force_signal(current_task: &CurrentTask, mut siginfo: SignalInfo) {
    strace!(current_task, "forced signal {:?}", siginfo);
    siginfo.force = true;
    send_signal(current_task, siginfo)
}

/// Represents the action to take when signal is delivered.
///
/// See https://man7.org/linux/man-pages/man7/signal.7.html.
#[derive(Debug, PartialEq)]
enum DeliveryAction {
    Ignore,
    CallHandler,
    Terminate,
    CoreDump,
    Stop,
    Continue,
}

impl DeliveryAction {
    /// Returns whether the targe task must be interrupted to execute the action.
    fn must_interrupt(&self) -> bool {
        match *self {
            // These actions must interrupt any blocking syscalls.
            DeliveryAction::CallHandler | DeliveryAction::Terminate | DeliveryAction::CoreDump => {
                true
            }
            _ => false,
        }
    }
}

fn action_for_signal(siginfo: &SignalInfo, sigaction: sigaction_t) -> DeliveryAction {
    match sigaction.sa_handler {
        SIG_DFL => match siginfo.signal {
            SIGCHLD | SIGURG | SIGWINCH => DeliveryAction::Ignore,
            sig if sig.is_real_time() => DeliveryAction::Ignore,
            SIGHUP | SIGINT | SIGKILL | SIGPIPE | SIGALRM | SIGTERM | SIGUSR1 | SIGUSR2
            | SIGPROF | SIGVTALRM | SIGSTKFLT | SIGIO | SIGPWR => DeliveryAction::Terminate,
            SIGQUIT | SIGILL | SIGABRT | SIGFPE | SIGSEGV | SIGBUS | SIGSYS | SIGTRAP | SIGXCPU
            | SIGXFSZ => DeliveryAction::CoreDump,
            SIGSTOP | SIGTSTP | SIGTTIN | SIGTTOU => DeliveryAction::Stop,
            SIGCONT => DeliveryAction::Continue,
            _ => panic!("Unknown signal"),
        },
        SIG_IGN => DeliveryAction::Ignore,
        _ => DeliveryAction::CallHandler,
    }
}

/// Adjusts a task's registers to restart a syscall once the task switches back to userspace.
///
/// This only happens if a syscall was interrupted and returned `-ERESTARTSYS`, and if the signal
/// action that interrupted the syscall had the `SA_RESTART` flag set.
fn prepare_to_restart_syscall(current_task: &mut CurrentTask, sigaction: &sigaction_t) {
    if current_task.registers.rax != (-ERESTARTSYS.value()) as u64 {
        // The syscall did not request to be restarted.
        return;
    }

    if (sigaction.sa_flags & SA_RESTART as u64) == 0 {
        // The signal action does not support restarts. The syscall should return -EINTR.
        current_task.registers.rax = (-EINTR.value()) as u64;
        return;
    }

    // The syscall should be restarted. Reload the original `rax` (syscall number) into `rax`,
    // and backup the instruction pointer to the `syscall` instruction.
    current_task.registers.rax = current_task.registers.orig_rax;
    current_task.registers.rip -= SYSCALL_INSTRUCTION_SIZE_BYTES;
}

/// Dequeues and handles a pending signal for `current_task`.
pub fn dequeue_signal(current_task: &mut CurrentTask) {
    let task = current_task.task_arc_clone();
    let mut task_state = task.write();

    let mask = task_state.signals.mask;
    if let Some(siginfo) =
        task_state.signals.take_next_where(|sig| !sig.signal.is_in_set(mask) || sig.force)
    {
        let sigaction = task.thread_group.signal_actions.get(siginfo.signal);
        prepare_to_restart_syscall(current_task, &sigaction);
        match action_for_signal(&siginfo, sigaction) {
            DeliveryAction::CallHandler => {
                dispatch_signal_handler(current_task, &mut task_state.signals, siginfo, sigaction);
            }
            DeliveryAction::Terminate => {
                // Release the signals lock. [`ThreadGroup::exit`] sends signals to threads which
                // will include this one and cause a deadlock re-acquiring the signals lock.
                drop(task_state);
                current_task.thread_group.exit(ExitStatus::Kill(siginfo));
            }
            DeliveryAction::CoreDump => {
                // TODO(tbodt): Trigger crashsvc somehow
                drop(task_state);
                current_task.thread_group.exit(ExitStatus::CoreDump(siginfo));
            }
            DeliveryAction::Ignore => {}
            DeliveryAction::Continue | DeliveryAction::Stop => {
                // Nothing to do. Effect already happened when the signal was raised.
            }
        };
    }
}

#[cfg(test)]
mod tests {
    use std::sync::Arc;

    use super::*;
    use crate::mm::{DesiredAddress, MappingOptions};
    use crate::testing::*;

    const SYSCALL_INSTRUCTION_ADDRESS: UserAddress = UserAddress::from(100);
    const SYSCALL_NUMBER: u64 = 42;
    const SYSCALL_ARGS: (u64, u64, u64, u64, u64, u64) = (20, 21, 22, 23, 24, 25);
    const SA_RESTORER_ADDRESS: UserAddress = UserAddress::from(0xDEADBEEF);
    const SA_HANDLER_ADDRESS: UserAddress = UserAddress::from(0x00BADDAD);

    const SYSCALL2_INSTRUCTION_ADDRESS: UserAddress = UserAddress::from(200);
    const SYSCALL2_NUMBER: u64 = 84;
    const SYSCALL2_ARGS: (u64, u64, u64, u64, u64, u64) = (30, 31, 32, 33, 34, 35);
    const SA_HANDLER2_ADDRESS: UserAddress = UserAddress::from(0xBADDAD00);

    #[cfg(target_arch = "x86_64")]
    #[::fuchsia::test]
    fn syscall_restart_adjusts_instruction_pointer_and_rax() {
        let (_kernel, mut current_task) = create_kernel_and_task_with_stack();

        // Register the signal action.
        current_task.thread_group.signal_actions.set(
            SIGUSR1,
            sigaction_t {
                sa_flags: (SA_RESTORER | SA_RESTART | SA_SIGINFO) as u64,
                sa_handler: SA_HANDLER_ADDRESS,
                sa_restorer: SA_RESTORER_ADDRESS,
                ..sigaction_t::default()
            },
        );

        // Simulate a syscall that should be restarted by setting up the register state to what it
        // was after the interrupted syscall. `rax` should have the return value (-ERESTARTSYS);
        // `rdi`, `rsi`, `rdx`, `r10`, `r8`, `r9`, should be the syscall arguments;
        // `orig_rax` should hold the syscall number;
        // and the instruction pointer should be 2 bytes after the syscall instruction.
        current_task.registers.rax = -ERESTARTSYS.value() as u64;
        current_task.registers.rdi = SYSCALL_ARGS.0;
        current_task.registers.rsi = SYSCALL_ARGS.1;
        current_task.registers.rdx = SYSCALL_ARGS.2;
        current_task.registers.r10 = SYSCALL_ARGS.3;
        current_task.registers.r8 = SYSCALL_ARGS.4;
        current_task.registers.r9 = SYSCALL_ARGS.5;
        current_task.registers.orig_rax = SYSCALL_NUMBER;
        current_task.registers.rip = (SYSCALL_INSTRUCTION_ADDRESS + 2u64).ptr() as u64;

        // Queue the signal that interrupted the syscall.
        current_task.write().signals.enqueue(SignalInfo::new(SIGUSR1, SI_USER, SignalDetail::None));

        // Process the signal.
        dequeue_signal(&mut current_task);

        // The instruction pointer should have changed to the signal handling address.
        assert_eq!(current_task.registers.rip, SA_HANDLER_ADDRESS.ptr() as u64);

        // The syscall arguments should be overwritten with signal handling args.
        assert_ne!(current_task.registers.rdi, SYSCALL_ARGS.0);
        assert_ne!(current_task.registers.rsi, SYSCALL_ARGS.1);
        assert_ne!(current_task.registers.rdx, SYSCALL_ARGS.2);

        // Now we assume that execution of the signal handler completed with a call to
        // `sys_rt_sigreturn`, which would set `rax` to that syscall number.
        current_task.registers.rax = __NR_rt_sigreturn as u64;
        current_task.registers.rsp += 8; // The stack was popped returning from the signal handler.

        restore_from_signal_handler(&mut current_task).expect("failed to restore state");

        // The state of the task is now such that when switching back to userspace, the instruction
        // pointer will point at the original syscall instruction, with the arguments correctly
        // restored into the registers.
        assert_eq!(current_task.registers.rax, SYSCALL_NUMBER);
        assert_eq!(current_task.registers.rdi, SYSCALL_ARGS.0);
        assert_eq!(current_task.registers.rsi, SYSCALL_ARGS.1);
        assert_eq!(current_task.registers.rdx, SYSCALL_ARGS.2);
        assert_eq!(current_task.registers.r10, SYSCALL_ARGS.3);
        assert_eq!(current_task.registers.r8, SYSCALL_ARGS.4);
        assert_eq!(current_task.registers.r9, SYSCALL_ARGS.5);
        assert_eq!(current_task.registers.rip, SYSCALL_INSTRUCTION_ADDRESS.ptr() as u64);
    }

    #[cfg(target_arch = "x86_64")]
    #[::fuchsia::test]
    fn syscall_nested_restart() {
        let (_kernel, mut current_task) = create_kernel_and_task_with_stack();

        // Register the signal actions.
        current_task.thread_group.signal_actions.set(
            SIGUSR1,
            sigaction_t {
                sa_flags: (SA_RESTORER | SA_RESTART | SA_SIGINFO) as u64,
                sa_handler: SA_HANDLER_ADDRESS,
                sa_restorer: SA_RESTORER_ADDRESS,
                ..sigaction_t::default()
            },
        );
        current_task.thread_group.signal_actions.set(
            SIGUSR2,
            sigaction_t {
                sa_flags: (SA_RESTORER | SA_RESTART | SA_SIGINFO) as u64,
                sa_handler: SA_HANDLER2_ADDRESS,
                sa_restorer: SA_RESTORER_ADDRESS,
                ..sigaction_t::default()
            },
        );

        // Simulate a syscall that should be restarted by setting up the register state to what it
        // was after the interrupted syscall. `rax` should have the return value (-ERESTARTSYS);
        // `rdi`, `rsi`, `rdx`, `r10`, `r8`, `r9`, should be the syscall arguments;
        // `orig_rax` should hold the syscall number;
        // and the instruction pointer should be 2 bytes after the syscall instruction.
        current_task.registers.rax = -ERESTARTSYS.value() as u64;
        current_task.registers.rdi = SYSCALL_ARGS.0;
        current_task.registers.rsi = SYSCALL_ARGS.1;
        current_task.registers.rdx = SYSCALL_ARGS.2;
        current_task.registers.r10 = SYSCALL_ARGS.3;
        current_task.registers.r8 = SYSCALL_ARGS.4;
        current_task.registers.r9 = SYSCALL_ARGS.5;
        current_task.registers.orig_rax = SYSCALL_NUMBER;
        current_task.registers.rip = (SYSCALL_INSTRUCTION_ADDRESS + 2u64).ptr() as u64;

        // Queue the signal that interrupted the syscall.
        current_task.write().signals.enqueue(SignalInfo::new(SIGUSR1, SI_USER, SignalDetail::None));

        // Process the signal.
        dequeue_signal(&mut current_task);

        // The instruction pointer should have changed to the signal handling address.
        assert_eq!(current_task.registers.rip, SA_HANDLER_ADDRESS.ptr() as u64);

        // The syscall arguments should be overwritten with signal handling args.
        assert_ne!(current_task.registers.rdi, SYSCALL_ARGS.0);
        assert_ne!(current_task.registers.rsi, SYSCALL_ARGS.1);
        assert_ne!(current_task.registers.rdx, SYSCALL_ARGS.2);

        // Simulate another syscall being interrupted.
        current_task.registers.rax = -ERESTARTSYS.value() as u64;
        current_task.registers.rdi = SYSCALL2_ARGS.0;
        current_task.registers.rsi = SYSCALL2_ARGS.1;
        current_task.registers.rdx = SYSCALL2_ARGS.2;
        current_task.registers.r10 = SYSCALL2_ARGS.3;
        current_task.registers.r8 = SYSCALL2_ARGS.4;
        current_task.registers.r9 = SYSCALL2_ARGS.5;
        current_task.registers.orig_rax = SYSCALL2_NUMBER;
        current_task.registers.rip = (SYSCALL2_INSTRUCTION_ADDRESS + 2u64).ptr() as u64;

        // Queue the signal that interrupted the syscall.
        current_task.write().signals.enqueue(SignalInfo::new(SIGUSR2, SI_USER, SignalDetail::None));

        // Process the signal.
        dequeue_signal(&mut current_task);

        // The instruction pointer should have changed to the signal handling address.
        assert_eq!(current_task.registers.rip, SA_HANDLER2_ADDRESS.ptr() as u64);

        // The syscall arguments should be overwritten with signal handling args.
        assert_ne!(current_task.registers.rdi, SYSCALL2_ARGS.0);
        assert_ne!(current_task.registers.rsi, SYSCALL2_ARGS.1);
        assert_ne!(current_task.registers.rdx, SYSCALL2_ARGS.2);

        // Now we assume that execution of the second signal handler completed with a call to
        // `sys_rt_sigreturn`, which would set `rax` to that syscall number.
        current_task.registers.rax = __NR_rt_sigreturn as u64;
        current_task.registers.rsp += 8; // The stack was popped returning from the signal handler.

        restore_from_signal_handler(&mut current_task).expect("failed to restore state");

        // The state of the task is now such that when switching back to userspace, the instruction
        // pointer will point at the original syscall instruction, with the arguments correctly
        // restored into the registers.
        assert_eq!(current_task.registers.rax, SYSCALL2_NUMBER);
        assert_eq!(current_task.registers.rdi, SYSCALL2_ARGS.0);
        assert_eq!(current_task.registers.rsi, SYSCALL2_ARGS.1);
        assert_eq!(current_task.registers.rdx, SYSCALL2_ARGS.2);
        assert_eq!(current_task.registers.r10, SYSCALL2_ARGS.3);
        assert_eq!(current_task.registers.r8, SYSCALL2_ARGS.4);
        assert_eq!(current_task.registers.r9, SYSCALL2_ARGS.5);
        assert_eq!(current_task.registers.rip, SYSCALL2_INSTRUCTION_ADDRESS.ptr() as u64);

        // Now we assume that execution of the first signal handler completed with a call to
        // `sys_rt_sigreturn`, which would set `rax` to that syscall number.
        current_task.registers.rax = __NR_rt_sigreturn as u64;
        current_task.registers.rsp += 8; // The stack was popped returning from the signal handler.

        restore_from_signal_handler(&mut current_task).expect("failed to restore state");

        // The state of the task is now such that when switching back to userspace, the instruction
        // pointer will point at the original syscall instruction, with the arguments correctly
        // restored into the registers.
        assert_eq!(current_task.registers.rax, SYSCALL_NUMBER);
        assert_eq!(current_task.registers.rdi, SYSCALL_ARGS.0);
        assert_eq!(current_task.registers.rsi, SYSCALL_ARGS.1);
        assert_eq!(current_task.registers.rdx, SYSCALL_ARGS.2);
        assert_eq!(current_task.registers.r10, SYSCALL_ARGS.3);
        assert_eq!(current_task.registers.r8, SYSCALL_ARGS.4);
        assert_eq!(current_task.registers.r9, SYSCALL_ARGS.5);
        assert_eq!(current_task.registers.rip, SYSCALL_INSTRUCTION_ADDRESS.ptr() as u64);
    }

    #[cfg(target_arch = "x86_64")]
    #[::fuchsia::test]
    fn syscall_does_not_restart_if_signal_action_has_no_sa_restart_flag() {
        let (_kernel, mut current_task) = create_kernel_and_task_with_stack();

        // Register the signal action.
        current_task.thread_group.signal_actions.set(
            SIGUSR1,
            sigaction_t {
                sa_flags: (SA_RESTORER | SA_SIGINFO) as u64,
                sa_handler: SA_HANDLER_ADDRESS,
                sa_restorer: SA_RESTORER_ADDRESS,
                ..sigaction_t::default()
            },
        );

        // Simulate a syscall that should be restarted by setting up the register state to what it
        // was after the interrupted syscall. `rax` should have the return value (-ERESTARTSYS);
        // `rdi`, `rsi`, `rdx`, `r10`, `r8`, `r9`, should be the syscall arguments;
        // `orig_rax` should hold the syscall number;
        // and the instruction pointer should be 2 bytes after the syscall instruction.
        current_task.registers.rax = -ERESTARTSYS.value() as u64;
        current_task.registers.rdi = SYSCALL_ARGS.0;
        current_task.registers.rsi = SYSCALL_ARGS.1;
        current_task.registers.rdx = SYSCALL_ARGS.2;
        current_task.registers.r10 = SYSCALL_ARGS.3;
        current_task.registers.r8 = SYSCALL_ARGS.4;
        current_task.registers.r9 = SYSCALL_ARGS.5;
        current_task.registers.orig_rax = SYSCALL_NUMBER;
        current_task.registers.rip = (SYSCALL_INSTRUCTION_ADDRESS + 2u64).ptr() as u64;

        // Queue the signal that interrupted the syscall.
        current_task.write().signals.enqueue(SignalInfo::new(SIGUSR1, SI_USER, SignalDetail::None));

        // Process the signal.
        dequeue_signal(&mut current_task);

        // The instruction pointer should have changed to the signal handling address.
        assert_eq!(current_task.registers.rip, SA_HANDLER_ADDRESS.ptr() as u64);

        // The syscall arguments should be overwritten with signal handling args.
        assert_ne!(current_task.registers.rdi, SYSCALL_ARGS.0);
        assert_ne!(current_task.registers.rsi, SYSCALL_ARGS.1);
        assert_ne!(current_task.registers.rdx, SYSCALL_ARGS.2);

        // Now we assume that execution of the signal handler completed with a call to
        // `sys_rt_sigreturn`, which would set `rax` to that syscall number.
        current_task.registers.rax = __NR_rt_sigreturn as u64;
        current_task.registers.rsp += 8; // The stack was popped returning from the signal handler.

        restore_from_signal_handler(&mut current_task).expect("failed to restore state");

        // The state of the task is now such that when switching back to userspace, the instruction
        // pointer will point at the original syscall instruction, with the arguments correctly
        // restored into the registers.
        assert_eq!(current_task.registers.rax, -EINTR.value() as u64);
        assert_eq!(current_task.registers.rip, (SYSCALL_INSTRUCTION_ADDRESS + 2u64).ptr() as u64);
    }

    /// Creates a kernel and initial task, giving the task a stack.
    fn create_kernel_and_task_with_stack() -> (Arc<Kernel>, CurrentTask) {
        let (kernel, mut current_task) = create_kernel_and_task();

        const STACK_SIZE: usize = 0x1000;

        // Give the task a stack.
        let stack_base = current_task
            .mm
            .map(
                DesiredAddress::Hint(UserAddress::default()),
                Arc::new(zx::Vmo::create(STACK_SIZE as u64).expect("failed to create stack VMO")),
                0,
                STACK_SIZE,
                zx::VmarFlags::PERM_READ | zx::VmarFlags::PERM_WRITE,
                MappingOptions::empty(),
                None,
            )
            .expect("failed to map stack VMO");
        current_task.registers.rsp = (stack_base + (STACK_SIZE - 8)).ptr() as u64;

        (kernel, current_task)
    }
}
