signal_action.rs 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200
  1. use super::{KResult, Signal, SignalMask, SAVED_DATA_SIZE};
  2. use crate::{
  3. io::BufferFill as _,
  4. kernel::{
  5. constants::{EFAULT, EINVAL, ENOSYS},
  6. user::UserBuffer,
  7. },
  8. SIGNAL_NOW,
  9. };
  10. use alloc::collections::btree_map::BTreeMap;
  11. use core::num::NonZero;
  12. use eonix_hal::{fpu::FpuState, traits::trap::RawTrapContext, trap::TrapContext};
  13. use eonix_mm::address::{Addr as _, AddrOps as _, VAddr};
  14. use posix_types::signal::{SigAction, TryFromSigAction};
  15. #[derive(Debug, Clone, Copy)]
  16. pub enum SignalAction {
  17. Default,
  18. Ignore,
  19. SimpleHandler {
  20. handler: VAddr,
  21. restorer: Option<VAddr>,
  22. mask: SignalMask,
  23. },
  24. }
  25. #[derive(Debug)]
  26. pub struct SignalActionList {
  27. actions: BTreeMap<Signal, SignalAction>,
  28. }
  29. impl SignalActionList {
  30. pub const fn new() -> Self {
  31. Self {
  32. actions: BTreeMap::new(),
  33. }
  34. }
  35. pub fn set(&mut self, signal: Signal, action: SignalAction) {
  36. debug_assert!(
  37. !matches!(signal, SIGNAL_NOW!()),
  38. "SIGSTOP and SIGKILL should not be set for a handler."
  39. );
  40. match action {
  41. SignalAction::Default => self.actions.remove(&signal),
  42. _ => self.actions.insert(signal, action),
  43. };
  44. }
  45. pub fn get(&self, signal: Signal) -> SignalAction {
  46. match self.actions.get(&signal) {
  47. None => SignalAction::Default,
  48. Some(action) => action.clone(),
  49. }
  50. }
  51. pub fn remove_non_ignore(&mut self) {
  52. // Remove all custom handlers except for the ignore action.
  53. // Default handlers should never appear in the list so we don't consider that.
  54. self.actions
  55. .retain(|_, action| matches!(action, SignalAction::Ignore));
  56. }
  57. }
  58. impl SignalAction {
  59. /// # Might Sleep
  60. pub(super) fn handle(
  61. self,
  62. signal: Signal,
  63. old_mask: SignalMask,
  64. trap_ctx: &mut TrapContext,
  65. fpu_state: &mut FpuState,
  66. ) -> KResult<()> {
  67. let SignalAction::SimpleHandler {
  68. handler, restorer, ..
  69. } = self
  70. else {
  71. unreachable!("Default and Ignore actions should not be handled here");
  72. };
  73. let Some(restorer) = restorer else {
  74. // We don't accept signal handlers with no signal restorers for now.
  75. return Err(ENOSYS)?;
  76. };
  77. let current_sp = VAddr::from(trap_ctx.get_stack_pointer());
  78. // Save current interrupt context to 128 bytes above current user stack
  79. // (in order to keep away from x86 red zone) and align to 16 bytes.
  80. let saved_data_addr = (current_sp - 128 - SAVED_DATA_SIZE).floor_to(16);
  81. let mut saved_data_buffer =
  82. UserBuffer::new(saved_data_addr.addr() as *mut u8, SAVED_DATA_SIZE)?;
  83. saved_data_buffer.copy(trap_ctx)?.ok_or(EFAULT)?;
  84. saved_data_buffer.copy(fpu_state)?.ok_or(EFAULT)?;
  85. saved_data_buffer.copy(&old_mask)?.ok_or(EFAULT)?;
  86. // We need to push the arguments to the handler and then save the return address.
  87. let new_sp = saved_data_addr - 16 - 4;
  88. let restorer_address = restorer.addr() as u32;
  89. let mut stack = UserBuffer::new(new_sp.addr() as *mut u8, 4 + 4)?;
  90. stack.copy(&restorer_address)?.ok_or(EFAULT)?; // Restorer address
  91. stack.copy(&u32::from(signal))?.ok_or(EFAULT)?; // The argument to the handler
  92. trap_ctx.set_program_counter(handler.addr());
  93. trap_ctx.set_stack_pointer(new_sp.addr());
  94. Ok(())
  95. }
  96. }
  97. impl Clone for SignalActionList {
  98. fn clone(&self) -> Self {
  99. Self {
  100. actions: self.actions.clone(),
  101. }
  102. }
  103. }
  104. impl Default for SignalAction {
  105. fn default() -> Self {
  106. Self::Default
  107. }
  108. }
  109. impl TryFromSigAction for SignalAction {
  110. type Error = u32;
  111. fn default() -> Self {
  112. Self::Default
  113. }
  114. fn ignore() -> Self {
  115. Self::Ignore
  116. }
  117. fn new() -> Self {
  118. Self::SimpleHandler {
  119. handler: VAddr::NULL,
  120. restorer: None,
  121. mask: SignalMask::empty(),
  122. }
  123. }
  124. fn set_siginfo(self) -> Result<Self, Self::Error> {
  125. Err(EINVAL)
  126. }
  127. fn handler(mut self, handler_addr: usize) -> Result<Self, Self::Error> {
  128. if let Self::SimpleHandler { handler, .. } = &mut self {
  129. *handler = VAddr::from(handler_addr);
  130. Ok(self)
  131. } else {
  132. unreachable!()
  133. }
  134. }
  135. fn restorer(mut self, restorer_addr: usize) -> Result<Self, Self::Error> {
  136. if let Self::SimpleHandler { restorer, .. } = &mut self {
  137. *restorer = NonZero::new(restorer_addr).map(|x| VAddr::from(x.get()));
  138. Ok(self)
  139. } else {
  140. unreachable!()
  141. }
  142. }
  143. fn mask(mut self, mask_value: u64) -> Result<Self, Self::Error> {
  144. if let Self::SimpleHandler { mask, .. } = &mut self {
  145. *mask = SignalMask::from(mask_value);
  146. Ok(self)
  147. } else {
  148. unreachable!()
  149. }
  150. }
  151. }
  152. impl From<SignalAction> for SigAction {
  153. fn from(action: SignalAction) -> SigAction {
  154. match action {
  155. SignalAction::Default => SigAction::default(),
  156. SignalAction::Ignore => SigAction::ignore(),
  157. SignalAction::SimpleHandler {
  158. handler,
  159. restorer,
  160. mask,
  161. } => {
  162. let action = SigAction::new()
  163. .handler(handler.addr())
  164. .mask(u64::from(mask));
  165. if let Some(restorer) = restorer {
  166. action.restorer(restorer.addr())
  167. } else {
  168. action
  169. }
  170. }
  171. }
  172. }
  173. }