feature: fuzzy
This commit is contained in:
parent
7c622a78f8
commit
3121cc9ba9
@ -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> {
|
||||||
|
@ -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();
|
||||||
|
@ -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;
|
||||||
|
@ -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)) })
|
||||||
|
@ -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();
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
|
@ -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 {
|
||||||
|
@ -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
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user