/// 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`.
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`.
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,
    signal: Signal,
    action: sigaction_t,
) {
    let signal_stack_frame = SignalStackFrame::new(
        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,
                })
                .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.mask = action.sa_mask;
    current_task.registers.rsp = stack_pointer;
    current_task.registers.rdi = signal.number() as u64;
    current_task.registers.rip = action.sa_handler.ptr() as u64;
}
fn dispatch_signal_handler ( current_task : & mut CurrentTask , signal_state : & mut SignalState , signal : Signal , action : sigaction_t , ) { let signal_stack_frame = SignalStackFrame :: new ( 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 , } ) . 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 . mask = action . sa_mask ; current_task . registers . rsp = stack_pointer ; current_task . registers . rdi = signal . number ( ) as u64 ; current_task . registers . rip = action . sa_handler . ptr ( ) as u64 ; }
Prepares `current` state to execute the signal handler stored in `action`.
Prepares ` current ` state to execute the signal handler stored in ` action ` .
current_task
&mut CurrentTask
signal_state
&mut SignalState
signal
Signal
action
sigaction_t