Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add some syscalls of signal #155

Merged
merged 5 commits into from
Aug 16, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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