Merge branch 'ptrace' into 'master'
Drive ptrace into a wall, prepare for overhaul See merge request redox-os/syscall!39
This commit is contained in:
102
src/data.rs
102
src/data.rs
@@ -1,5 +1,5 @@
|
||||
use core::ops::{Deref, DerefMut};
|
||||
use core::{mem, slice};
|
||||
use core::{fmt, mem, slice};
|
||||
|
||||
#[derive(Copy, Clone, Debug, Default)]
|
||||
#[repr(C)]
|
||||
@@ -13,7 +13,7 @@ impl Deref for Event {
|
||||
type Target = [u8];
|
||||
fn deref(&self) -> &[u8] {
|
||||
unsafe {
|
||||
slice::from_raw_parts(self as *const Event as *const u8, mem::size_of::<Event>()) as &[u8]
|
||||
slice::from_raw_parts(self as *const Event as *const u8, mem::size_of::<Event>())
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -21,7 +21,7 @@ impl Deref for Event {
|
||||
impl DerefMut for Event {
|
||||
fn deref_mut(&mut self) -> &mut [u8] {
|
||||
unsafe {
|
||||
slice::from_raw_parts_mut(self as *mut Event as *mut u8, mem::size_of::<Event>()) as &mut [u8]
|
||||
slice::from_raw_parts_mut(self as *mut Event as *mut u8, mem::size_of::<Event>())
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -38,7 +38,7 @@ impl Deref for ITimerSpec {
|
||||
fn deref(&self) -> &[u8] {
|
||||
unsafe {
|
||||
slice::from_raw_parts(self as *const ITimerSpec as *const u8,
|
||||
mem::size_of::<ITimerSpec>()) as &[u8]
|
||||
mem::size_of::<ITimerSpec>())
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -47,7 +47,7 @@ impl DerefMut for ITimerSpec {
|
||||
fn deref_mut(&mut self) -> &mut [u8] {
|
||||
unsafe {
|
||||
slice::from_raw_parts_mut(self as *mut ITimerSpec as *mut u8,
|
||||
mem::size_of::<ITimerSpec>()) as &mut [u8]
|
||||
mem::size_of::<ITimerSpec>())
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -64,7 +64,7 @@ impl Deref for Map {
|
||||
type Target = [u8];
|
||||
fn deref(&self) -> &[u8] {
|
||||
unsafe {
|
||||
slice::from_raw_parts(self as *const Map as *const u8, mem::size_of::<Map>()) as &[u8]
|
||||
slice::from_raw_parts(self as *const Map as *const u8, mem::size_of::<Map>())
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -72,7 +72,7 @@ impl Deref for Map {
|
||||
impl DerefMut for Map {
|
||||
fn deref_mut(&mut self) -> &mut [u8] {
|
||||
unsafe {
|
||||
slice::from_raw_parts_mut(self as *mut Map as *mut u8, mem::size_of::<Map>()) as &mut [u8]
|
||||
slice::from_raw_parts_mut(self as *mut Map as *mut u8, mem::size_of::<Map>())
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -94,7 +94,7 @@ impl Deref for Packet {
|
||||
type Target = [u8];
|
||||
fn deref(&self) -> &[u8] {
|
||||
unsafe {
|
||||
slice::from_raw_parts(self as *const Packet as *const u8, mem::size_of::<Packet>()) as &[u8]
|
||||
slice::from_raw_parts(self as *const Packet as *const u8, mem::size_of::<Packet>())
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -102,27 +102,26 @@ impl Deref for Packet {
|
||||
impl DerefMut for Packet {
|
||||
fn deref_mut(&mut self) -> &mut [u8] {
|
||||
unsafe {
|
||||
slice::from_raw_parts_mut(self as *mut Packet as *mut u8, mem::size_of::<Packet>()) as &mut [u8]
|
||||
slice::from_raw_parts_mut(self as *mut Packet as *mut u8, mem::size_of::<Packet>())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug)]
|
||||
#[derive(Copy, Clone, Debug, Default, PartialEq)]
|
||||
#[repr(C)]
|
||||
pub struct SigAction {
|
||||
pub sa_handler: extern "C" fn(usize),
|
||||
pub sa_handler: Option<extern "C" fn(usize)>,
|
||||
pub sa_mask: [u64; 2],
|
||||
pub sa_flags: usize,
|
||||
}
|
||||
|
||||
impl Default for SigAction {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
sa_handler: unsafe { mem::transmute(0usize) },
|
||||
sa_mask: [0; 2],
|
||||
sa_flags: 0,
|
||||
}
|
||||
}
|
||||
#[allow(dead_code)]
|
||||
unsafe fn _assert_size_of_function_is_sane() {
|
||||
// Transmuting will complain *at compile time* if sizes differ.
|
||||
// Rust forbids a fn-pointer from being 0 so to allow SIG_DFL to
|
||||
// exist, we use Option<extern "C" fn(usize)> which will mean 0
|
||||
// becomes None
|
||||
let _ = mem::transmute::<Option<extern "C" fn(usize)>, usize>(None);
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, Default, PartialEq)]
|
||||
@@ -150,7 +149,7 @@ impl Deref for Stat {
|
||||
fn deref(&self) -> &[u8] {
|
||||
unsafe {
|
||||
slice::from_raw_parts(self as *const Stat as *const u8,
|
||||
mem::size_of::<Stat>()) as &[u8]
|
||||
mem::size_of::<Stat>())
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -159,7 +158,7 @@ impl DerefMut for Stat {
|
||||
fn deref_mut(&mut self) -> &mut [u8] {
|
||||
unsafe {
|
||||
slice::from_raw_parts_mut(self as *mut Stat as *mut u8,
|
||||
mem::size_of::<Stat>()) as &mut [u8]
|
||||
mem::size_of::<Stat>())
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -178,7 +177,7 @@ impl Deref for StatVfs {
|
||||
fn deref(&self) -> &[u8] {
|
||||
unsafe {
|
||||
slice::from_raw_parts(self as *const StatVfs as *const u8,
|
||||
mem::size_of::<StatVfs>()) as &[u8]
|
||||
mem::size_of::<StatVfs>())
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -187,7 +186,7 @@ impl DerefMut for StatVfs {
|
||||
fn deref_mut(&mut self) -> &mut [u8] {
|
||||
unsafe {
|
||||
slice::from_raw_parts_mut(self as *mut StatVfs as *mut u8,
|
||||
mem::size_of::<StatVfs>()) as &mut [u8]
|
||||
mem::size_of::<StatVfs>())
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -204,7 +203,7 @@ impl Deref for TimeSpec {
|
||||
fn deref(&self) -> &[u8] {
|
||||
unsafe {
|
||||
slice::from_raw_parts(self as *const TimeSpec as *const u8,
|
||||
mem::size_of::<TimeSpec>()) as &[u8]
|
||||
mem::size_of::<TimeSpec>())
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -213,7 +212,7 @@ impl DerefMut for TimeSpec {
|
||||
fn deref_mut(&mut self) -> &mut [u8] {
|
||||
unsafe {
|
||||
slice::from_raw_parts_mut(self as *mut TimeSpec as *mut u8,
|
||||
mem::size_of::<TimeSpec>()) as &mut [u8]
|
||||
mem::size_of::<TimeSpec>())
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -257,7 +256,7 @@ impl Deref for IntRegisters {
|
||||
type Target = [u8];
|
||||
fn deref(&self) -> &[u8] {
|
||||
unsafe {
|
||||
slice::from_raw_parts(self as *const IntRegisters as *const u8, mem::size_of::<IntRegisters>()) as &[u8]
|
||||
slice::from_raw_parts(self as *const IntRegisters as *const u8, mem::size_of::<IntRegisters>())
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -265,7 +264,7 @@ impl Deref for IntRegisters {
|
||||
impl DerefMut for IntRegisters {
|
||||
fn deref_mut(&mut self) -> &mut [u8] {
|
||||
unsafe {
|
||||
slice::from_raw_parts_mut(self as *mut IntRegisters as *mut u8, mem::size_of::<IntRegisters>()) as &mut [u8]
|
||||
slice::from_raw_parts_mut(self as *mut IntRegisters as *mut u8, mem::size_of::<IntRegisters>())
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -291,7 +290,7 @@ impl Deref for FloatRegisters {
|
||||
type Target = [u8];
|
||||
fn deref(&self) -> &[u8] {
|
||||
unsafe {
|
||||
slice::from_raw_parts(self as *const FloatRegisters as *const u8, mem::size_of::<FloatRegisters>()) as &[u8]
|
||||
slice::from_raw_parts(self as *const FloatRegisters as *const u8, mem::size_of::<FloatRegisters>())
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -299,7 +298,52 @@ impl Deref for FloatRegisters {
|
||||
impl DerefMut for FloatRegisters {
|
||||
fn deref_mut(&mut self) -> &mut [u8] {
|
||||
unsafe {
|
||||
slice::from_raw_parts_mut(self as *mut FloatRegisters as *mut u8, mem::size_of::<FloatRegisters>()) as &mut [u8]
|
||||
slice::from_raw_parts_mut(self as *mut FloatRegisters as *mut u8, mem::size_of::<FloatRegisters>())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy)]
|
||||
#[repr(C)]
|
||||
pub union PtraceEventData {
|
||||
pub clone: usize,
|
||||
pub signal: usize
|
||||
}
|
||||
|
||||
impl Default for PtraceEventData {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
clone: 0,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Debug for PtraceEventData {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "PtraceEventData(...)")
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug, Default)]
|
||||
#[repr(C)]
|
||||
pub struct PtraceEvent {
|
||||
pub tag: u16,
|
||||
pub data: PtraceEventData,
|
||||
}
|
||||
|
||||
impl Deref for PtraceEvent {
|
||||
type Target = [u8];
|
||||
fn deref(&self) -> &[u8] {
|
||||
unsafe {
|
||||
slice::from_raw_parts(self as *const PtraceEvent as *const u8, mem::size_of::<PtraceEvent>())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl DerefMut for PtraceEvent {
|
||||
fn deref_mut(&mut self) -> &mut [u8] {
|
||||
unsafe {
|
||||
slice::from_raw_parts_mut(self as *mut PtraceEvent as *mut u8, mem::size_of::<PtraceEvent>())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -69,9 +69,14 @@ pub const PTRACE_CONT: u8 = 0b0000_0001;
|
||||
pub const PTRACE_SINGLESTEP: u8 = 0b0000_0010;
|
||||
pub const PTRACE_SYSCALL: u8 = 0b0000_0011;
|
||||
pub const PTRACE_WAIT: u8 = 0b0000_0100;
|
||||
pub const PTRACE_SIGNAL: u8 = 0b0000_0101;
|
||||
|
||||
pub const PTRACE_OPERATIONMASK: u8 = 0b0000_1111;
|
||||
pub const PTRACE_SYSEMU: u8 = 0b0001_0000;
|
||||
|
||||
pub const PTRACE_EVENT_CLONE: u16 = 0;
|
||||
pub const PTRACE_EVENT_SIGNAL: u16 = 1;
|
||||
|
||||
pub const SEEK_SET: usize = 0;
|
||||
pub const SEEK_CUR: usize = 1;
|
||||
pub const SEEK_END: usize = 2;
|
||||
|
||||
65
src/tests.rs
65
src/tests.rs
@@ -409,3 +409,68 @@ fn unlink() {
|
||||
fn sched_yield() {
|
||||
assert_eq!(dbg!(crate::sched_yield()), Ok(0));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn sigaction() {
|
||||
use std::{
|
||||
mem,
|
||||
sync::atomic::{AtomicBool, Ordering}
|
||||
};
|
||||
|
||||
static SA_HANDLER_WAS_RAN: AtomicBool = AtomicBool::new(false);
|
||||
static SA_HANDLER_2_WAS_IGNORED: AtomicBool = AtomicBool::new(false);
|
||||
|
||||
let child = unsafe { crate::clone(crate::CLONE_VM).unwrap() };
|
||||
|
||||
if child == 0 {
|
||||
let pid = crate::getpid().unwrap();
|
||||
|
||||
extern "C" fn hello_im_a_signal_handler(signal: usize) {
|
||||
assert_eq!(signal, crate::SIGUSR1);
|
||||
SA_HANDLER_WAS_RAN.store(true, Ordering::SeqCst);
|
||||
}
|
||||
|
||||
let my_signal_handler = crate::SigAction {
|
||||
sa_handler: Some(hello_im_a_signal_handler),
|
||||
..Default::default()
|
||||
};
|
||||
crate::sigaction(crate::SIGUSR1, Some(&my_signal_handler), None).unwrap();
|
||||
|
||||
crate::kill(pid, crate::SIGUSR1).unwrap(); // calls handler
|
||||
|
||||
let mut old_signal_handler = crate::SigAction::default();
|
||||
crate::sigaction(
|
||||
crate::SIGUSR1,
|
||||
Some(&crate::SigAction {
|
||||
sa_handler: unsafe { mem::transmute::<usize, Option<extern "C" fn(usize)>>(crate::SIG_IGN) },
|
||||
..Default::default()
|
||||
}),
|
||||
Some(&mut old_signal_handler)
|
||||
).unwrap();
|
||||
assert_eq!(my_signal_handler, old_signal_handler);
|
||||
|
||||
crate::kill(pid, crate::SIGUSR1).unwrap(); // does nothing
|
||||
|
||||
SA_HANDLER_2_WAS_IGNORED.store(true, Ordering::SeqCst);
|
||||
|
||||
crate::sigaction(
|
||||
crate::SIGUSR1,
|
||||
Some(&crate::SigAction {
|
||||
sa_handler: unsafe { mem::transmute::<usize, Option<extern "C" fn(usize)>>(crate::SIG_DFL) },
|
||||
..Default::default()
|
||||
}),
|
||||
Some(&mut old_signal_handler)
|
||||
).unwrap();
|
||||
|
||||
crate::kill(pid, crate::SIGUSR1).unwrap(); // actually exits
|
||||
} else {
|
||||
let mut status = 0;
|
||||
dbg!(crate::waitpid(child, &mut status, 0)).unwrap();
|
||||
|
||||
assert!(crate::wifsignaled(status));
|
||||
assert_eq!(crate::wtermsig(status), crate::SIGUSR1);
|
||||
|
||||
assert!(SA_HANDLER_WAS_RAN.load(Ordering::SeqCst));
|
||||
assert!(SA_HANDLER_2_WAS_IGNORED.load(Ordering::SeqCst));
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user