feature: fuzzy
This commit is contained in:
parent
7c622a78f8
commit
3121cc9ba9
@ -1,6 +1,6 @@
|
||||
use crate::{BlockAllocator, Bvec, FileInode};
|
||||
use alloc::boxed::Box;
|
||||
use libsys::error::Errno;
|
||||
use libsys::{error::Errno, stat::Stat};
|
||||
use vfs::{Vnode, VnodeImpl, VnodeKind, VnodeRef};
|
||||
|
||||
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> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn stat(&mut self, _at: VnodeRef, _stat: &mut Stat) -> Result<(), Errno> {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl<A: BlockAllocator + Copy + 'static> DirInode<A> {
|
||||
|
@ -1,8 +1,9 @@
|
||||
//! System call implementation
|
||||
|
||||
use crate::arch::platform::exception::ExceptionFrame;
|
||||
use crate::arch::{machine, platform::exception::ExceptionFrame};
|
||||
use crate::debug::Level;
|
||||
use crate::proc::{self, elf, wait, Process, ProcessIo, Thread};
|
||||
use crate::dev::timer::TimestampSource;
|
||||
use core::mem::size_of;
|
||||
use core::ops::DerefMut;
|
||||
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)?;
|
||||
Ok(0)
|
||||
},
|
||||
abi::SYS_EX_GETCPUTIME => {
|
||||
let time = machine::local_timer().timestamp()?;
|
||||
Ok(time.as_nanos() as usize)
|
||||
}
|
||||
|
||||
_ => {
|
||||
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_WAIT: usize = 136;
|
||||
pub const SYS_EX_GETTID: usize = 137;
|
||||
pub const SYS_EX_GETCPUTIME: usize = 138;
|
||||
|
||||
pub const SYS_EXIT: usize = 1;
|
||||
pub const SYS_READ: usize = 2;
|
||||
|
@ -6,9 +6,11 @@ use crate::{
|
||||
signal::{Signal, SignalDestination},
|
||||
stat::{AccessMode, FdSet, FileDescriptor, FileMode, OpenFlags, Stat},
|
||||
};
|
||||
use core::time::Duration;
|
||||
|
||||
// TODO document the syscall ABI
|
||||
|
||||
// TODO move this to libusr
|
||||
macro_rules! syscall {
|
||||
($num:expr) => {{
|
||||
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)]
|
||||
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)) })
|
||||
|
@ -1,13 +1,37 @@
|
||||
use libsys::{calls::sys_ex_sigreturn, signal::Signal};
|
||||
use crate::trace;
|
||||
use libsys::{calls::{sys_exit, sys_ex_sigreturn}, signal::Signal, proc::ExitCode};
|
||||
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)]
|
||||
pub(crate) extern "C" fn signal_handler(arg: Signal) -> ! {
|
||||
// TODO tpidr_el0 is invalidated when entering signal context
|
||||
trace!("Entered signal handler: arg={:?}", arg);
|
||||
match arg {
|
||||
Signal::Interrupt | Signal::SegmentationFault =>
|
||||
loop {},
|
||||
_ => todo!()
|
||||
let no = arg as usize;
|
||||
if no >= 32 {
|
||||
panic!("Undefined signal number: {}", no);
|
||||
}
|
||||
match unsafe { SIGNAL_HANDLERS[no] } {
|
||||
SignalHandler::Func(f) => f(arg),
|
||||
SignalHandler::Ignore => (),
|
||||
SignalHandler::Terminate => sys_exit(ExitCode::from(-1)),
|
||||
}
|
||||
|
||||
sys_ex_sigreturn();
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
pub use libsys::signal::{Signal, SignalDestination};
|
||||
pub use libsys::proc::ExitCode;
|
||||
pub use libsys::termios;
|
||||
pub use libsys::abi;
|
||||
pub use libsys::calls::*;
|
||||
pub use libsys::stat::{self, AccessMode, FileDescriptor};
|
||||
pub use libsys::error::Errno;
|
||||
|
@ -68,8 +68,12 @@ unsafe fn init_common(signal_stack_pointer: *mut u8) {
|
||||
}
|
||||
|
||||
pub(crate) unsafe fn init_main() {
|
||||
static mut SIGNAL_STACK: [u8; 4096] = [0; 4096];
|
||||
init_common(SIGNAL_STACK.as_mut_ptr().add(SIGNAL_STACK.len()))
|
||||
#[repr(align(16))]
|
||||
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 {
|
||||
|
@ -1,10 +1,136 @@
|
||||
#![feature(asm)]
|
||||
#![no_std]
|
||||
#![no_main]
|
||||
|
||||
#[macro_use]
|
||||
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]
|
||||
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
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user