feature: fuzzy

This commit is contained in:
Mark Poliakov 2021-11-21 11:44:33 +02:00
parent 7c622a78f8
commit 3121cc9ba9
8 changed files with 184 additions and 10 deletions

View File

@ -1,6 +1,6 @@
use crate::{BlockAllocator, Bvec, FileInode}; use crate::{BlockAllocator, Bvec, FileInode};
use alloc::boxed::Box; use alloc::boxed::Box;
use libsys::error::Errno; use libsys::{error::Errno, stat::Stat};
use vfs::{Vnode, VnodeImpl, VnodeKind, VnodeRef}; use vfs::{Vnode, VnodeImpl, VnodeKind, VnodeRef};
pub struct DirInode<A: BlockAllocator + Copy + 'static> { pub struct DirInode<A: BlockAllocator + Copy + 'static> {
@ -31,6 +31,10 @@ impl<A: BlockAllocator + Copy + 'static> VnodeImpl for DirInode<A> {
fn remove(&mut self, _parent: VnodeRef, _name: &str) -> Result<(), Errno> { fn remove(&mut self, _parent: VnodeRef, _name: &str) -> Result<(), Errno> {
Ok(()) Ok(())
} }
fn stat(&mut self, _at: VnodeRef, _stat: &mut Stat) -> Result<(), Errno> {
Ok(())
}
} }
impl<A: BlockAllocator + Copy + 'static> DirInode<A> { impl<A: BlockAllocator + Copy + 'static> DirInode<A> {

View File

@ -1,8 +1,9 @@
//! System call implementation //! System call implementation
use crate::arch::platform::exception::ExceptionFrame; use crate::arch::{machine, platform::exception::ExceptionFrame};
use crate::debug::Level; use crate::debug::Level;
use crate::proc::{self, elf, wait, Process, ProcessIo, Thread}; use crate::proc::{self, elf, wait, Process, ProcessIo, Thread};
use crate::dev::timer::TimestampSource;
use core::mem::size_of; use core::mem::size_of;
use core::ops::DerefMut; use core::ops::DerefMut;
use core::time::Duration; use core::time::Duration;
@ -248,6 +249,10 @@ pub fn syscall(num: usize, args: &[usize]) -> Result<usize, Errno> {
find_at_node(&mut io, at_fd, path, flags & AT_EMPTY_PATH != 0)?.check_access(io.ioctx(), mode)?; find_at_node(&mut io, at_fd, path, flags & AT_EMPTY_PATH != 0)?.check_access(io.ioctx(), mode)?;
Ok(0) Ok(0)
}, },
abi::SYS_EX_GETCPUTIME => {
let time = machine::local_timer().timestamp()?;
Ok(time.as_nanos() as usize)
}
_ => { _ => {
let thread = Thread::current(); let thread = Thread::current();

View File

@ -9,6 +9,7 @@ pub const SYS_EX_YIELD: usize = 134;
pub const SYS_EX_THREAD_EXIT: usize = 135; pub const SYS_EX_THREAD_EXIT: usize = 135;
pub const SYS_EX_THREAD_WAIT: usize = 136; pub const SYS_EX_THREAD_WAIT: usize = 136;
pub const SYS_EX_GETTID: usize = 137; pub const SYS_EX_GETTID: usize = 137;
pub const SYS_EX_GETCPUTIME: usize = 138;
pub const SYS_EXIT: usize = 1; pub const SYS_EXIT: usize = 1;
pub const SYS_READ: usize = 2; pub const SYS_READ: usize = 2;

View File

@ -6,9 +6,11 @@ use crate::{
signal::{Signal, SignalDestination}, signal::{Signal, SignalDestination},
stat::{AccessMode, FdSet, FileDescriptor, FileMode, OpenFlags, Stat}, stat::{AccessMode, FdSet, FileDescriptor, FileMode, OpenFlags, Stat},
}; };
use core::time::Duration;
// TODO document the syscall ABI // TODO document the syscall ABI
// TODO move this to libusr
macro_rules! syscall { macro_rules! syscall {
($num:expr) => {{ ($num:expr) => {{
let mut res: usize; let mut res: usize;
@ -247,6 +249,13 @@ pub fn sys_ioctl(
}) })
} }
#[inline(always)]
pub fn sys_ex_getcputime() -> Result<Duration, Errno> {
Errno::from_syscall(unsafe {
syscall!(abi::SYS_EX_GETCPUTIME)
}).map(|e| Duration::from_nanos(e as u64))
}
#[inline(always)] #[inline(always)]
pub fn sys_ex_signal(entry: usize, stack: usize) -> Result<(), Errno> { pub fn sys_ex_signal(entry: usize, stack: usize) -> Result<(), Errno> {
Errno::from_syscall_unit(unsafe { syscall!(abi::SYS_EX_SIGNAL, argn!(entry), argn!(stack)) }) Errno::from_syscall_unit(unsafe { syscall!(abi::SYS_EX_SIGNAL, argn!(entry), argn!(stack)) })

View File

@ -1,13 +1,37 @@
use libsys::{calls::sys_ex_sigreturn, signal::Signal}; use libsys::{calls::{sys_exit, sys_ex_sigreturn}, signal::Signal, proc::ExitCode};
use crate::trace; use crate::{trace, thread};
#[derive(Clone, Copy)]
pub enum SignalHandler {
Func(fn(Signal) -> ()),
Ignore,
Terminate
}
// TODO per-thread signal handler table
static mut SIGNAL_HANDLERS: [SignalHandler; 32] = [SignalHandler::Terminate; 32];
pub fn set_handler(sig: Signal, handler: SignalHandler) -> SignalHandler {
unsafe {
let old = SIGNAL_HANDLERS[sig as usize];
SIGNAL_HANDLERS[sig as usize] = handler;
old
}
}
#[inline(never)] #[inline(never)]
pub(crate) extern "C" fn signal_handler(arg: Signal) -> ! { pub(crate) extern "C" fn signal_handler(arg: Signal) -> ! {
// TODO tpidr_el0 is invalidated when entering signal context
trace!("Entered signal handler: arg={:?}", arg); trace!("Entered signal handler: arg={:?}", arg);
match arg { let no = arg as usize;
Signal::Interrupt | Signal::SegmentationFault => if no >= 32 {
loop {}, panic!("Undefined signal number: {}", no);
_ => todo!()
} }
match unsafe { SIGNAL_HANDLERS[no] } {
SignalHandler::Func(f) => f(arg),
SignalHandler::Ignore => (),
SignalHandler::Terminate => sys_exit(ExitCode::from(-1)),
}
sys_ex_sigreturn(); sys_ex_sigreturn();
} }

View File

@ -1,6 +1,7 @@
pub use libsys::signal::{Signal, SignalDestination}; pub use libsys::signal::{Signal, SignalDestination};
pub use libsys::proc::ExitCode; pub use libsys::proc::ExitCode;
pub use libsys::termios; pub use libsys::termios;
pub use libsys::abi;
pub use libsys::calls::*; pub use libsys::calls::*;
pub use libsys::stat::{self, AccessMode, FileDescriptor}; pub use libsys::stat::{self, AccessMode, FileDescriptor};
pub use libsys::error::Errno; pub use libsys::error::Errno;

View File

@ -68,8 +68,12 @@ unsafe fn init_common(signal_stack_pointer: *mut u8) {
} }
pub(crate) unsafe fn init_main() { pub(crate) unsafe fn init_main() {
static mut SIGNAL_STACK: [u8; 4096] = [0; 4096]; #[repr(align(16))]
init_common(SIGNAL_STACK.as_mut_ptr().add(SIGNAL_STACK.len())) struct StackWrapper {
data: [u8; 8192]
}
static mut STACK: StackWrapper = StackWrapper { data: [0; 8192] };
init_common(STACK.data.as_mut_ptr().add(8192))
} }
pub fn current() -> Thread { pub fn current() -> Thread {

View File

@ -1,10 +1,136 @@
#![feature(asm)]
#![no_std] #![no_std]
#![no_main] #![no_main]
#[macro_use] #[macro_use]
extern crate libusr; extern crate libusr;
use libusr::sys::{abi, stat::Stat, Signal};
use libusr::signal::{self, SignalHandler};
static mut STATE: u64 = 0;
macro_rules! syscall {
($num:expr) => {{
let mut res: usize;
asm!("svc #0", out("x0") res, in("x8") $num, options(nostack));
res
}};
($num:expr, $a0:expr) => {{
let mut res: usize = $a0;
asm!("svc #0",
inout("x0") res,
in("x8") $num, options(nostack));
res
}};
($num:expr, $a0:expr, $a1:expr) => {{
let mut res: usize = $a0;
asm!("svc #0",
inout("x0") res, in("x1") $a1,
in("x8") $num, options(nostack));
res
}};
($num:expr, $a0:expr, $a1:expr, $a2:expr) => {{
let mut res: usize = $a0;
asm!("svc #0",
inout("x0") res, in("x1") $a1, in("x2") $a2,
in("x8") $num, options(nostack));
res
}};
($num:expr, $a0:expr, $a1:expr, $a2:expr, $a3:expr) => {{
let mut res: usize = $a0;
asm!("svc #0",
inout("x0") res, in("x1") $a1, in("x2") $a2,
in("x3") $a3, in("x8") $num, options(nostack));
res
}};
($num:expr, $a0:expr, $a1:expr, $a2:expr, $a3:expr, $a4:expr) => {{
let mut res: usize = $a0;
asm!("svc #0",
inout("x0") res, in("x1") $a1, in("x2") $a2,
in("x3") $a3, in("x4") $a4, in("x8") $num, options(nostack));
res
}};
}
/// Integer/size argument
macro_rules! argn {
($a:expr) => {
$a as usize
};
}
/// Pointer/base argument
macro_rules! argp {
($a:expr) => {
$a as usize
};
}
fn random_set_seed(seed: u64) {
unsafe { STATE = seed; }
}
fn random_u64() -> u64 {
let mut x = unsafe { STATE };
x ^= x << 13;
x ^= x >> 7;
x ^= x << 17;
unsafe {
STATE = x;
}
x
}
fn random_ascii_char() -> u8 {
((random_u64() % (0x7F - 0x20)) as u8) + 0x20
}
fn random_str_range(buf: &mut [u8], min: usize, max: usize) -> &str {
let max = core::cmp::min(buf.len(), max);
assert!(max > min);
let len = ((random_u64() as usize) % (max - min)) + min;
for c in buf[..len].iter_mut() {
*c = random_ascii_char();
}
core::str::from_utf8(&buf[..len]).unwrap()
}
fn random_str(buf: &mut [u8]) -> &str {
random_str_range(buf, 0, buf.len())
}
fn random_bytes(buf: &mut [u8]) {
for byte in buf.iter_mut() {
*byte = (random_u64() & 0xFF) as u8;
}
}
#[no_mangle] #[no_mangle]
fn main() -> i32 { fn main() -> i32 {
let seed = libusr::sys::sys_ex_getcputime().unwrap().as_nanos() as u64 / 13;
trace!("Using seed: {:#x}", seed);
random_set_seed(seed);
let mut buf = [0; 256];
// Test sys_ex_getcputime()
let mut prev_time = libusr::sys::sys_ex_getcputime().unwrap().as_nanos();
for _ in 0..100000 {
let t = libusr::sys::sys_ex_getcputime().unwrap().as_nanos();
assert!(t >= prev_time);
}
// Test non-utf8 input fed into syscalls expecting strings
// let old_signal = signal::set_handler(Signal::InvalidSystemCall, SignalHandler::Ignore);
for _ in 0..10000 {
random_bytes(&mut buf);
let mut stat = Stat::default();
unsafe {
syscall!(abi::SYS_FSTATAT, (-2i32) as usize, buf.as_mut_ptr() as usize, buf.len(), (&mut stat) as *mut _ as usize);
}
}
// signal::set_handler(Signal::InvalidSystemCall, old_signal);
0 0
} }