Skip to content

Commit

Permalink
Add some syscalls of signal (#155)
Browse files Browse the repository at this point in the history
  • Loading branch information
yukiiiteru authored Aug 16, 2020
1 parent 6ddd759 commit 2f34c8c
Show file tree
Hide file tree
Showing 9 changed files with 436 additions and 19 deletions.
1 change: 1 addition & 0 deletions linux-object/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ spin = "0.5"
xmas-elf = "0.7"
bitflags = "1.2"
hashbrown = "0.7"
numeric-enum-macro = "0.2"
zircon-object = { path = "../zircon-object", features = ["elf"] }
kernel-hal = { path = "../kernel-hal" }
downcast-rs = { git = "https://github.com/rcore-os/downcast-rs", rev = "a632ce1", default-features = false }
Expand Down
9 changes: 2 additions & 7 deletions linux-object/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,7 @@
//! Linux kernel objects
#![no_std]
#![deny(
warnings,
unsafe_code,
unused_must_use,
unreachable_patterns,
missing_docs
)]
#![deny(warnings, unsafe_code)]
#![feature(bool_to_option)]

extern crate alloc;
Expand All @@ -24,5 +18,6 @@ pub mod fs;
// layer 2
pub mod loader;
pub mod process;
pub mod signal;
pub mod sync;
pub mod thread;
29 changes: 28 additions & 1 deletion linux-object/src/process.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
use crate::error::*;
use crate::fs::*;
use crate::signal::{Signal as LinuxSignal, SignalAction};
use alloc::vec::Vec;
use alloc::{
boxed::Box,
Expand Down Expand Up @@ -53,6 +54,7 @@ impl ProcessExt for Process {
execute_path: linux_parent_inner.execute_path.clone(),
current_working_directory: linux_parent_inner.current_working_directory.clone(),
files: linux_parent_inner.files.clone(),
signal_actions: linux_parent_inner.signal_actions.clone(),
..Default::default()
}),
};
Expand Down Expand Up @@ -151,6 +153,21 @@ struct LinuxProcessInner {
futexes: HashMap<VirtAddr, Arc<Futex>>,
/// Child processes
children: HashMap<KoID, Arc<Process>>,
/// Signal actions
signal_actions: SignalActions,
}

#[derive(Clone)]
struct SignalActions {
table: [SignalAction; LinuxSignal::RTMAX + 1],
}

impl Default for SignalActions {
fn default() -> Self {
Self {
table: [SignalAction::default(); LinuxSignal::RTMAX + 1],
}
}
}

/// resource limit
Expand All @@ -172,7 +189,7 @@ impl Default for RLimit {
}
}

/// process exit code defination
/// The type of process exit code.
pub type ExitCode = i32;

impl LinuxProcess {
Expand Down Expand Up @@ -334,6 +351,16 @@ impl LinuxProcess {
pub fn set_execute_path(&self, path: &str) {
self.inner.lock().execute_path = String::from(path);
}

/// Get signal action.
pub fn signal_action(&self, signal: LinuxSignal) -> SignalAction {
self.inner.lock().signal_actions.table[signal as u8 as usize]
}

/// Set signal action.
pub fn set_signal_action(&self, signal: LinuxSignal, action: SignalAction) {
self.inner.lock().signal_actions.table[signal as u8 as usize] = action;
}
}

impl LinuxProcessInner {
Expand Down
103 changes: 103 additions & 0 deletions linux-object/src/signal/action.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
use crate::signal::Signal;
use bitflags::*;

pub const SIG_ERR: usize = usize::max_value() - 1;
pub const SIG_DFL: usize = 0;
pub const SIG_IGN: usize = 1;

// yet there's a bug because of mismatching bits: https://sourceware.org/bugzilla/show_bug.cgi?id=25657
// just support 64bits size sigset
/// Linux struct sigset_t
#[derive(Default, Clone, Copy, Debug)]
#[repr(C)]
pub struct Sigset(u64);

impl Sigset {
pub fn empty() -> Self {
Sigset(0)
}
pub fn contains(&self, sig: Signal) -> bool {
(self.0 >> sig as u64 & 1) != 0
}
pub fn insert(&mut self, sig: Signal) {
self.0 |= 1 << sig as u64;
}
pub fn insert_set(&mut self, sigset: &Sigset) {
self.0 |= sigset.0;
}
pub fn remove(&mut self, sig: Signal) {
self.0 ^= self.0 & (1 << sig as u64);
}
pub fn remove_set(&mut self, sigset: &Sigset) {
self.0 ^= self.0 & sigset.0;
}
}

/// Linux struct sigaction
#[repr(C)]
#[derive(Debug, Clone, Copy, Default)]
pub struct SignalAction {
pub handler: usize, // this field may be an union
pub flags: SignalActionFlags,
pub restorer: usize,
pub mask: Sigset,
}

#[repr(C)]
#[derive(Copy, Clone)]
pub union SiginfoFields {
pad: [u8; Self::PAD_SIZE],
// TODO: fill this union
}

impl SiginfoFields {
const PAD_SIZE: usize = 128 - 2 * core::mem::size_of::<i32>() - core::mem::size_of::<usize>();
}

impl Default for SiginfoFields {
fn default() -> Self {
SiginfoFields {
pad: [0; Self::PAD_SIZE],
}
}
}

#[repr(C)]
#[derive(Copy, Clone)]
pub struct SigInfo {
pub signo: i32,
pub errno: i32,
pub code: SignalCode,
pub field: SiginfoFields,
}

/// A code identifying the cause of the signal.
#[repr(i32)]
#[derive(Debug, Copy, Clone)]
pub enum SignalCode {
ASYNCNL = -60,
TKILL = -6,
SIGIO = -5,
ASYNCIO = -4,
MESGQ = -3,
TIMER = -2,
QUEUE = -1,
/// from user
USER = 0,
/// from kernel
KERNEL = 128,
}

bitflags! {
#[derive(Default)]
pub struct SignalActionFlags : usize {
const NOCLDSTOP = 1;
const NOCLDWAIT = 2;
const SIGINFO = 4;
const ONSTACK = 0x08000000;
const RESTART = 0x10000000;
const NODEFER = 0x40000000;
const RESETHAND = 0x80000000;
const RESTORER = 0x04000000;
}
}
174 changes: 174 additions & 0 deletions linux-object/src/signal/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,174 @@
use bitflags::*;
use numeric_enum_macro::numeric_enum;

mod action;

pub use self::action::*;

/// struct mcontext
#[repr(C)]
#[derive(Clone, Debug)]
pub struct MachineContext {
// gregs
pub r8: usize,
pub r9: usize,
pub r10: usize,
pub r11: usize,
pub r12: usize,
pub r13: usize,
pub r14: usize,
pub r15: usize,
pub rdi: usize,
pub rsi: usize,
pub rbp: usize,
pub rbx: usize,
pub rdx: usize,
pub rax: usize,
pub rcx: usize,
pub rsp: usize,
pub rip: usize,
pub eflags: usize,
pub cs: u16,
pub gs: u16,
pub fs: u16,
pub _pad: u16,
pub err: usize,
pub trapno: usize,
pub oldmask: usize,
pub cr2: usize,
// fpregs
// TODO
pub fpstate: usize,
// reserved
pub _reserved1: [usize; 8],
}

numeric_enum! {
#[repr(u8)]
#[derive(Eq, PartialEq, Debug, Copy, Clone)]
pub enum Signal {
SIGHUP = 1,
SIGINT = 2,
SIGQUIT = 3,
SIGILL = 4,
SIGTRAP = 5,
SIGABRT = 6,
SIGBUS = 7,
SIGFPE = 8,
SIGKILL = 9,
SIGUSR1 = 10,
SIGSEGV = 11,
SIGUSR2 = 12,
SIGPIPE = 13,
SIGALRM = 14,
SIGTERM = 15,
SIGSTKFLT = 16,
SIGCHLD = 17,
SIGCONT = 18,
SIGSTOP = 19,
SIGTSTP = 20,
SIGTTIN = 21,
SIGTTOU = 22,
SIGURG = 23,
SIGXCPU = 24,
SIGXFSZ = 25,
SIGVTALRM = 26,
SIGPROF = 27,
SIGWINCH = 28,
SIGIO = 29,
SIGPWR = 30,
SIGSYS = 31,
// real time signals
SIGRT32 = 32,
SIGRT33 = 33,
SIGRT34 = 34,
SIGRT35 = 35,
SIGRT36 = 36,
SIGRT37 = 37,
SIGRT38 = 38,
SIGRT39 = 39,
SIGRT40 = 40,
SIGRT41 = 41,
SIGRT42 = 42,
SIGRT43 = 43,
SIGRT44 = 44,
SIGRT45 = 45,
SIGRT46 = 46,
SIGRT47 = 47,
SIGRT48 = 48,
SIGRT49 = 49,
SIGRT50 = 50,
SIGRT51 = 51,
SIGRT52 = 52,
SIGRT53 = 53,
SIGRT54 = 54,
SIGRT55 = 55,
SIGRT56 = 56,
SIGRT57 = 57,
SIGRT58 = 58,
SIGRT59 = 59,
SIGRT60 = 60,
SIGRT61 = 61,
SIGRT62 = 62,
SIGRT63 = 63,
SIGRT64 = 64,
}
}

impl Signal {
pub const RTMIN: usize = 32;
pub const RTMAX: usize = 64;

pub fn is_standard(self) -> bool {
(self as usize) < Self::RTMIN
}
}

/// See musl struct __ucontext
/// Not exactly the same for now
#[repr(C)]
#[derive(Clone)]
pub struct SignalUserContext {
pub flags: usize,
pub link: usize,
pub stack: SignalStack,
pub context: MachineContext,
pub sig_mask: Sigset,
}

#[repr(C)]
#[derive(Clone)]
pub struct SignalFrame {
pub ret_code_addr: usize, // point to ret_code
pub info: SigInfo,
pub ucontext: SignalUserContext, // adapt interface, a little bit waste
pub ret_code: [u8; 7], // call sys_sigreturn
}

bitflags! {
pub struct SignalStackFlags : u32 {
const ONSTACK = 1;
const DISABLE = 2;
const AUTODISARM = 0x80000000;
}
}

/// Linux struct stack_t
#[repr(C)]
#[derive(Copy, Clone, Debug)]
pub struct SignalStack {
pub sp: usize,
pub flags: SignalStackFlags,
pub size: usize,
}

impl Default for SignalStack {
fn default() -> Self {
// default to disabled
SignalStack {
sp: 0,
flags: SignalStackFlags::DISABLE,
size: 0,
}
}
}
7 changes: 7 additions & 0 deletions linux-object/src/thread.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
//! Linux Thread
use crate::process::ProcessExt;
use crate::signal::{SignalStack, Sigset};
use alloc::sync::Arc;
use kernel_hal::user::{Out, UserOutPtr, UserPtr};
use kernel_hal::VirtAddr;
Expand Down Expand Up @@ -28,6 +29,8 @@ impl ThreadExt for Thread {
fn create_linux(proc: &Arc<Process>) -> ZxResult<Arc<Self>> {
let linux_thread = Mutex::new(LinuxThread {
clear_child_tid: 0.into(),
signal_mask: Sigset::default(),
signal_alternate_stack: SignalStack::default(),
});
Thread::create_with_ext(proc, "", linux_thread)
}
Expand Down Expand Up @@ -68,4 +71,8 @@ pub struct LinuxThread {
/// Kernel performs futex wake when thread exits.
/// Ref: [http://man7.org/linux/man-pages/man2/set_tid_address.2.html]
clear_child_tid: UserOutPtr<i32>,
/// Signal mask
pub signal_mask: Sigset,
/// signal alternate stack
pub signal_alternate_stack: SignalStack,
}
Loading

0 comments on commit 2f34c8c

Please sign in to comment.