feature: better ABI for system call numbers
This commit is contained in:
parent
3121cc9ba9
commit
bf1a215730
12
Cargo.lock
generated
12
Cargo.lock
generated
@ -35,6 +35,17 @@ version = "0.1.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b6419a5c75e40011b9fe0174db3fe24006ab122fbe1b7e9cc5974b338a755c76"
|
||||
|
||||
[[package]]
|
||||
name = "enum-repr"
|
||||
version = "0.2.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bad30c9c0fa1aaf1ae5010dab11f1117b15d35faf62cda4bbbc53b9987950f18"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "fallible-iterator"
|
||||
version = "0.2.0"
|
||||
@ -111,6 +122,7 @@ name = "libsys"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"enum-repr",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -7,7 +7,7 @@ use crate::mem;
|
||||
use crate::proc::{sched, Thread, Process};
|
||||
use crate::syscall;
|
||||
use cortex_a::registers::{ESR_EL1, FAR_EL1};
|
||||
use libsys::{abi, signal::Signal};
|
||||
use libsys::{abi::SystemCall, signal::Signal};
|
||||
use tock_registers::interfaces::Readable;
|
||||
|
||||
/// Trapped SIMD/FP functionality
|
||||
@ -116,24 +116,30 @@ extern "C" fn __aa64_exc_sync_handler(exc: &mut ExceptionFrame) {
|
||||
dump_data_abort(Level::Error, esr, far as u64);
|
||||
}
|
||||
EC_SVC_AA64 => {
|
||||
unsafe {
|
||||
if exc.x[8] == abi::SYS_FORK {
|
||||
match syscall::sys_fork(exc) {
|
||||
Ok(pid) => exc.x[0] = pid.value() as usize,
|
||||
Err(err) => {
|
||||
exc.x[0] = err.to_negative_isize() as usize;
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
let num = SystemCall::from_repr(exc.x[8]);
|
||||
if num.is_none() {
|
||||
todo!();
|
||||
return;
|
||||
}
|
||||
let num = num.unwrap();
|
||||
|
||||
match syscall::syscall(exc.x[8], &exc.x[..6]) {
|
||||
Ok(val) => exc.x[0] = val,
|
||||
if num == SystemCall::Fork {
|
||||
match unsafe { syscall::sys_fork(exc) } {
|
||||
Ok(pid) => exc.x[0] = pid.value() as usize,
|
||||
Err(err) => {
|
||||
exc.x[0] = err.to_negative_isize() as usize;
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
match syscall::syscall(num, &exc.x[..6]) {
|
||||
Ok(val) => exc.x[0] = val,
|
||||
Err(err) => {
|
||||
exc.x[0] = err.to_negative_isize() as usize;
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
_ => {}
|
||||
|
@ -8,7 +8,7 @@ use core::mem::size_of;
|
||||
use core::ops::DerefMut;
|
||||
use core::time::Duration;
|
||||
use libsys::{
|
||||
abi,
|
||||
abi::SystemCall,
|
||||
error::Errno,
|
||||
ioctl::IoctlCmd,
|
||||
proc::{ExitCode, Pid},
|
||||
@ -52,23 +52,26 @@ fn find_at_node<T: DerefMut<Target = ProcessIo>>(
|
||||
}
|
||||
|
||||
/// Main system call dispatcher function
|
||||
pub fn syscall(num: usize, args: &[usize]) -> Result<usize, Errno> {
|
||||
pub fn syscall(num: SystemCall, args: &[usize]) -> Result<usize, Errno> {
|
||||
match num {
|
||||
// Process management system calls
|
||||
abi::SYS_EXIT => {
|
||||
Process::exit(ExitCode::from(args[0] as i32));
|
||||
unreachable!();
|
||||
}
|
||||
abi::SYS_EX_THREAD_EXIT => {
|
||||
Process::exit_thread(Thread::current(), ExitCode::from(args[0] as i32));
|
||||
unreachable!();
|
||||
},
|
||||
abi::SYS_EX_GETTID => {
|
||||
Ok(Thread::current().id() as usize)
|
||||
},
|
||||
// I/O
|
||||
SystemCall::Read => {
|
||||
let proc = Process::current();
|
||||
let fd = FileDescriptor::from(args[0] as u32);
|
||||
let mut io = proc.io.lock();
|
||||
let buf = validate_user_ptr(args[1], args[2])?;
|
||||
|
||||
// I/O system calls
|
||||
abi::SYS_OPENAT => {
|
||||
io.file(fd)?.borrow_mut().read(buf)
|
||||
},
|
||||
SystemCall::Write => {
|
||||
let proc = Process::current();
|
||||
let fd = FileDescriptor::from(args[0] as u32);
|
||||
let mut io = proc.io.lock();
|
||||
let buf = validate_user_ptr(args[1], args[2])?;
|
||||
|
||||
io.file(fd)?.borrow_mut().write(buf)
|
||||
},
|
||||
SystemCall::Open => {
|
||||
let at_fd = FileDescriptor::from_i32(args[0] as i32)?;
|
||||
let path = validate_user_str(args[1], args[2])?;
|
||||
let mode = FileMode::from_bits(args[3] as u32).ok_or(Errno::InvalidArgument)?;
|
||||
@ -85,24 +88,16 @@ pub fn syscall(num: usize, args: &[usize]) -> Result<usize, Errno> {
|
||||
|
||||
let file = io.ioctx().open(at, path, mode, opts)?;
|
||||
Ok(u32::from(io.place_file(file)?) as usize)
|
||||
}
|
||||
abi::SYS_READ => {
|
||||
},
|
||||
SystemCall::Close => {
|
||||
let proc = Process::current();
|
||||
let fd = FileDescriptor::from(args[0] as u32);
|
||||
let mut io = proc.io.lock();
|
||||
let buf = validate_user_ptr(args[1], args[2])?;
|
||||
|
||||
io.file(fd)?.borrow_mut().read(buf)
|
||||
}
|
||||
abi::SYS_WRITE => {
|
||||
let proc = Process::current();
|
||||
let fd = FileDescriptor::from(args[0] as u32);
|
||||
let mut io = proc.io.lock();
|
||||
let buf = validate_user_ptr(args[1], args[2])?;
|
||||
|
||||
io.file(fd)?.borrow_mut().write(buf)
|
||||
}
|
||||
abi::SYS_FSTATAT => {
|
||||
io.close_file(fd)?;
|
||||
Ok(0)
|
||||
},
|
||||
SystemCall::FileStatus => {
|
||||
let at_fd = FileDescriptor::from_i32(args[0] as i32)?;
|
||||
let filename = validate_user_str(args[1], args[2])?;
|
||||
let buf = validate_user_ptr_struct::<Stat>(args[3])?;
|
||||
@ -112,16 +107,52 @@ pub fn syscall(num: usize, args: &[usize]) -> Result<usize, Errno> {
|
||||
let mut io = proc.io.lock();
|
||||
find_at_node(&mut io, at_fd, filename, flags & AT_EMPTY_PATH != 0)?.stat(buf)?;
|
||||
Ok(0)
|
||||
}
|
||||
abi::SYS_CLOSE => {
|
||||
},
|
||||
SystemCall::Ioctl => {
|
||||
let fd = FileDescriptor::from(args[0] as u32);
|
||||
let cmd = IoctlCmd::try_from(args[1] as u32)?;
|
||||
|
||||
let proc = Process::current();
|
||||
let mut io = proc.io.lock();
|
||||
let fd = FileDescriptor::from(args[0] as u32);
|
||||
|
||||
io.close_file(fd)?;
|
||||
let node = io.file(fd)?.borrow().node().ok_or(Errno::InvalidFile)?;
|
||||
node.ioctl(cmd, args[2], args[3])
|
||||
},
|
||||
SystemCall::Select => {
|
||||
let rfds = validate_user_ptr_struct_option::<FdSet>(args[0])?;
|
||||
let wfds = validate_user_ptr_struct_option::<FdSet>(args[1])?;
|
||||
let timeout = if args[2] == 0 {
|
||||
None
|
||||
} else {
|
||||
Some(Duration::from_nanos(args[2] as u64))
|
||||
};
|
||||
|
||||
wait::select(Thread::current(), rfds, wfds, timeout)
|
||||
},
|
||||
SystemCall::Access => {
|
||||
let at_fd = FileDescriptor::from_i32(args[0] as i32)?;
|
||||
let path = validate_user_str(args[1], args[2])?;
|
||||
let mode = AccessMode::from_bits(args[3] as u32).ok_or(Errno::InvalidArgument)?;
|
||||
let flags = args[4] as u32;
|
||||
|
||||
let proc = Process::current();
|
||||
let mut io = proc.io.lock();
|
||||
|
||||
find_at_node(&mut io, at_fd, path, flags & AT_EMPTY_PATH != 0)?.check_access(io.ioctx(), mode)?;
|
||||
Ok(0)
|
||||
}
|
||||
abi::SYS_EXECVE => {
|
||||
},
|
||||
|
||||
// Process
|
||||
SystemCall::Clone => {
|
||||
let entry = args[0];
|
||||
let stack = args[1];
|
||||
let arg = args[2];
|
||||
|
||||
Process::current()
|
||||
.new_user_thread(entry, stack, arg)
|
||||
.map(|e| e as usize)
|
||||
},
|
||||
SystemCall::Exec => {
|
||||
let node = {
|
||||
let proc = Process::current();
|
||||
let mut io = proc.io.lock();
|
||||
@ -134,8 +165,20 @@ pub fn syscall(num: usize, args: &[usize]) -> Result<usize, Errno> {
|
||||
let file = node.open(OpenFlags::O_RDONLY)?;
|
||||
Process::execve(|space| elf::load_elf(space, file), 0).unwrap();
|
||||
panic!();
|
||||
}
|
||||
abi::SYS_WAITPID => {
|
||||
},
|
||||
SystemCall::Exit => {
|
||||
let status = ExitCode::from(args[0] as i32);
|
||||
let flags = args[1];
|
||||
|
||||
if flags & (1 << 0) != 0 {
|
||||
Process::exit_thread(Thread::current(), status);
|
||||
} else {
|
||||
Process::exit(status);
|
||||
}
|
||||
|
||||
unreachable!();
|
||||
},
|
||||
SystemCall::WaitPid => {
|
||||
// TODO special "pid" values
|
||||
let pid = unsafe { Pid::from_raw(args[0] as u32) };
|
||||
let status = validate_user_ptr_struct::<i32>(args[1])?;
|
||||
@ -147,8 +190,8 @@ pub fn syscall(num: usize, args: &[usize]) -> Result<usize, Errno> {
|
||||
}
|
||||
_ => todo!(),
|
||||
}
|
||||
}
|
||||
abi::SYS_EX_THREAD_WAIT => {
|
||||
},
|
||||
SystemCall::WaitTid => {
|
||||
let tid = args[0] as u32;
|
||||
|
||||
match Thread::waittid(tid) {
|
||||
@ -158,28 +201,9 @@ pub fn syscall(num: usize, args: &[usize]) -> Result<usize, Errno> {
|
||||
_ => todo!(),
|
||||
}
|
||||
},
|
||||
abi::SYS_IOCTL => {
|
||||
let fd = FileDescriptor::from(args[0] as u32);
|
||||
let cmd = IoctlCmd::try_from(args[1] as u32)?;
|
||||
|
||||
let proc = Process::current();
|
||||
let mut io = proc.io.lock();
|
||||
|
||||
let node = io.file(fd)?.borrow().node().ok_or(Errno::InvalidFile)?;
|
||||
node.ioctl(cmd, args[2], args[3])
|
||||
}
|
||||
|
||||
// Extra system calls
|
||||
abi::SYS_EX_DEBUG_TRACE => {
|
||||
let buf = validate_user_ptr(args[0], args[1])?;
|
||||
print!(Level::Debug, "[trace] ");
|
||||
for &byte in buf.iter() {
|
||||
print!(Level::Debug, "{}", byte as char);
|
||||
}
|
||||
println!(Level::Debug, "");
|
||||
Ok(args[1])
|
||||
}
|
||||
abi::SYS_EX_NANOSLEEP => {
|
||||
SystemCall::GetPid => todo!(),
|
||||
SystemCall::GetTid => Ok(Thread::current().id() as usize),
|
||||
SystemCall::Sleep => {
|
||||
let rem_buf = validate_user_ptr_null(args[1], size_of::<u64>() * 2)?;
|
||||
let mut rem = Duration::new(0, 0);
|
||||
let res = wait::sleep(Duration::from_nanos(args[0] as u64), &mut rem);
|
||||
@ -190,16 +214,16 @@ pub fn syscall(num: usize, args: &[usize]) -> Result<usize, Errno> {
|
||||
}
|
||||
}
|
||||
res.map(|_| 0)
|
||||
}
|
||||
abi::SYS_EX_SIGNAL => {
|
||||
},
|
||||
SystemCall::SetSignalEntry => {
|
||||
Thread::current().set_signal_entry(args[0], args[1]);
|
||||
Ok(0)
|
||||
}
|
||||
abi::SYS_EX_SIGRETURN => {
|
||||
},
|
||||
SystemCall::SignalReturn => {
|
||||
Thread::current().return_from_signal();
|
||||
panic!("This code won't run");
|
||||
}
|
||||
abi::SYS_EX_KILL => {
|
||||
unreachable!();
|
||||
},
|
||||
SystemCall::SendSignal => {
|
||||
let target = SignalDestination::from(args[0] as isize);
|
||||
let signal = Signal::try_from(args[1] as u32)?;
|
||||
|
||||
@ -211,55 +235,30 @@ pub fn syscall(num: usize, args: &[usize]) -> Result<usize, Errno> {
|
||||
_ => todo!(),
|
||||
};
|
||||
Ok(0)
|
||||
}
|
||||
abi::SYS_EX_CLONE => {
|
||||
let entry = args[0];
|
||||
let stack = args[1];
|
||||
let arg = args[2];
|
||||
|
||||
Process::current()
|
||||
.new_user_thread(entry, stack, arg)
|
||||
.map(|e| e as usize)
|
||||
}
|
||||
abi::SYS_EX_YIELD => {
|
||||
},
|
||||
SystemCall::Yield => {
|
||||
proc::switch();
|
||||
Ok(0)
|
||||
},
|
||||
|
||||
abi::SYS_SELECT => {
|
||||
let rfds = validate_user_ptr_struct_option::<FdSet>(args[0])?;
|
||||
let wfds = validate_user_ptr_struct_option::<FdSet>(args[1])?;
|
||||
let timeout = if args[2] == 0 {
|
||||
None
|
||||
} else {
|
||||
Some(Duration::from_nanos(args[2] as u64))
|
||||
};
|
||||
|
||||
wait::select(Thread::current(), rfds, wfds, timeout)
|
||||
}
|
||||
abi::SYS_FACCESSAT => {
|
||||
let at_fd = FileDescriptor::from_i32(args[0] as i32)?;
|
||||
let path = validate_user_str(args[1], args[2])?;
|
||||
let mode = AccessMode::from_bits(args[3] as u32).ok_or(Errno::InvalidArgument)?;
|
||||
let flags = args[4] as u32;
|
||||
|
||||
let proc = Process::current();
|
||||
let mut io = proc.io.lock();
|
||||
|
||||
find_at_node(&mut io, at_fd, path, flags & AT_EMPTY_PATH != 0)?.check_access(io.ioctx(), mode)?;
|
||||
Ok(0)
|
||||
},
|
||||
abi::SYS_EX_GETCPUTIME => {
|
||||
// System
|
||||
SystemCall::GetCpuTime => {
|
||||
let time = machine::local_timer().timestamp()?;
|
||||
Ok(time.as_nanos() as usize)
|
||||
}
|
||||
},
|
||||
|
||||
_ => {
|
||||
let thread = Thread::current();
|
||||
let proc = thread.owner().unwrap();
|
||||
errorln!("Undefined system call: {}", num);
|
||||
proc.enter_fault_signal(thread, Signal::InvalidSystemCall);
|
||||
Err(Errno::InvalidArgument)
|
||||
}
|
||||
// Debugging
|
||||
SystemCall::DebugTrace => {
|
||||
let buf = validate_user_ptr(args[0], args[1])?;
|
||||
print!(Level::Debug, "[trace] ");
|
||||
for &byte in buf.iter() {
|
||||
print!(Level::Debug, "{}", byte as char);
|
||||
}
|
||||
println!(Level::Debug, "");
|
||||
Ok(args[1])
|
||||
},
|
||||
|
||||
// Handled elsewhere
|
||||
SystemCall::Fork => unreachable!()
|
||||
}
|
||||
}
|
||||
|
@ -7,6 +7,7 @@ edition = "2021"
|
||||
|
||||
[dependencies]
|
||||
bitflags = "^1.3.0"
|
||||
enum-repr = "^0.2.6"
|
||||
|
||||
[features]
|
||||
user = []
|
||||
|
@ -1,26 +1,33 @@
|
||||
pub const SYS_EX_DEBUG_TRACE: usize = 128;
|
||||
pub const SYS_EX_NANOSLEEP: usize = 129;
|
||||
use enum_repr::EnumRepr;
|
||||
|
||||
pub const SYS_EX_SIGNAL: usize = 130;
|
||||
pub const SYS_EX_SIGRETURN: usize = 131;
|
||||
pub const SYS_EX_KILL: usize = 132;
|
||||
pub const SYS_EX_CLONE: usize = 133;
|
||||
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;
|
||||
pub const SYS_WRITE: usize = 3;
|
||||
pub const SYS_OPENAT: usize = 4;
|
||||
pub const SYS_FSTATAT: usize = 5;
|
||||
pub const SYS_CLOSE: usize = 6;
|
||||
pub const SYS_FORK: usize = 7;
|
||||
pub const SYS_EXECVE: usize = 8;
|
||||
pub const SYS_WAITPID: usize = 9;
|
||||
pub const SYS_IOCTL: usize = 10;
|
||||
pub const SYS_SELECT: usize = 11;
|
||||
pub const SYS_FACCESSAT: usize = 12;
|
||||
// pub const SYS_GETPID: usize = 13;
|
||||
#[EnumRepr(type = "usize")]
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord)]
|
||||
pub enum SystemCall {
|
||||
// I/O
|
||||
Read = 1,
|
||||
Write = 2,
|
||||
Open = 3,
|
||||
Close = 4,
|
||||
FileStatus = 5,
|
||||
Ioctl = 6,
|
||||
Select = 7,
|
||||
Access = 8,
|
||||
// Process manipulation
|
||||
Fork = 32,
|
||||
Clone = 33,
|
||||
Exec = 34,
|
||||
Exit = 35,
|
||||
WaitPid = 36,
|
||||
WaitTid = 37,
|
||||
GetPid = 38,
|
||||
GetTid = 39,
|
||||
Sleep = 40,
|
||||
SetSignalEntry = 41,
|
||||
SignalReturn = 42,
|
||||
SendSignal = 43,
|
||||
Yield = 44,
|
||||
// System
|
||||
GetCpuTime = 64,
|
||||
// Debugging
|
||||
DebugTrace = 128
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
use crate::abi;
|
||||
use crate::abi::SystemCall;
|
||||
use crate::{
|
||||
error::Errno,
|
||||
ioctl::IoctlCmd,
|
||||
@ -14,42 +14,42 @@ use core::time::Duration;
|
||||
macro_rules! syscall {
|
||||
($num:expr) => {{
|
||||
let mut res: usize;
|
||||
asm!("svc #0", out("x0") res, in("x8") $num, options(nostack));
|
||||
asm!("svc #0", out("x0") res, in("x8") $num.repr(), options(nostack));
|
||||
res
|
||||
}};
|
||||
($num:expr, $a0:expr) => {{
|
||||
let mut res: usize = $a0;
|
||||
asm!("svc #0",
|
||||
inout("x0") res,
|
||||
in("x8") $num, options(nostack));
|
||||
in("x8") $num.repr(), 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));
|
||||
in("x8") $num.repr(), 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));
|
||||
in("x8") $num.repr(), 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));
|
||||
in("x3") $a3, in("x8") $num.repr(), 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));
|
||||
in("x3") $a3, in("x4") $a4, in("x8") $num.repr(), options(nostack));
|
||||
res
|
||||
}};
|
||||
}
|
||||
@ -77,7 +77,7 @@ macro_rules! argp {
|
||||
#[inline(always)]
|
||||
pub fn sys_exit(code: ExitCode) -> ! {
|
||||
unsafe {
|
||||
syscall!(abi::SYS_EXIT, argn!(i32::from(code)));
|
||||
syscall!(SystemCall::Exit, argn!(i32::from(code)), argn!(0));
|
||||
}
|
||||
unreachable!();
|
||||
}
|
||||
@ -87,7 +87,7 @@ pub fn sys_exit(code: ExitCode) -> ! {
|
||||
/// System call
|
||||
#[inline(always)]
|
||||
pub fn sys_close(fd: FileDescriptor) -> Result<(), Errno> {
|
||||
Errno::from_syscall_unit(unsafe { syscall!(abi::SYS_CLOSE, argn!(u32::from(fd))) })
|
||||
Errno::from_syscall_unit(unsafe { syscall!(SystemCall::Close, argn!(u32::from(fd))) })
|
||||
}
|
||||
|
||||
/// # Safety
|
||||
@ -96,7 +96,7 @@ pub fn sys_close(fd: FileDescriptor) -> Result<(), Errno> {
|
||||
#[inline(always)]
|
||||
pub fn sys_ex_nanosleep(ns: u64, rem: &mut [u64; 2]) -> Result<(), Errno> {
|
||||
Errno::from_syscall_unit(unsafe {
|
||||
syscall!(abi::SYS_EX_NANOSLEEP, argn!(ns), argp!(rem.as_mut_ptr()))
|
||||
syscall!(SystemCall::Sleep, argn!(ns), argp!(rem.as_mut_ptr()))
|
||||
})
|
||||
}
|
||||
|
||||
@ -107,7 +107,7 @@ pub fn sys_ex_nanosleep(ns: u64, rem: &mut [u64; 2]) -> Result<(), Errno> {
|
||||
pub fn sys_ex_debug_trace(msg: &[u8]) -> Result<(), Errno> {
|
||||
Errno::from_syscall_unit(unsafe {
|
||||
syscall!(
|
||||
abi::SYS_EX_DEBUG_TRACE,
|
||||
SystemCall::DebugTrace,
|
||||
argp!(msg.as_ptr()),
|
||||
argn!(msg.len())
|
||||
)
|
||||
@ -126,7 +126,7 @@ pub fn sys_openat(
|
||||
) -> Result<FileDescriptor, Errno> {
|
||||
Errno::from_syscall(unsafe {
|
||||
syscall!(
|
||||
abi::SYS_OPENAT,
|
||||
SystemCall::Open,
|
||||
argn!(FileDescriptor::into_i32(at)),
|
||||
argp!(pathname.as_ptr()),
|
||||
argn!(pathname.len()),
|
||||
@ -144,7 +144,7 @@ pub fn sys_openat(
|
||||
pub fn sys_read(fd: FileDescriptor, data: &mut [u8]) -> Result<usize, Errno> {
|
||||
Errno::from_syscall(unsafe {
|
||||
syscall!(
|
||||
abi::SYS_READ,
|
||||
SystemCall::Read,
|
||||
argn!(u32::from(fd)),
|
||||
argp!(data.as_mut_ptr()),
|
||||
argn!(data.len())
|
||||
@ -156,7 +156,7 @@ pub fn sys_read(fd: FileDescriptor, data: &mut [u8]) -> Result<usize, Errno> {
|
||||
pub fn sys_write(fd: FileDescriptor, data: &[u8]) -> Result<usize, Errno> {
|
||||
Errno::from_syscall(unsafe {
|
||||
syscall!(
|
||||
abi::SYS_WRITE,
|
||||
SystemCall::Write,
|
||||
argn!(u32::from(fd)),
|
||||
argp!(data.as_ptr()),
|
||||
argn!(data.len())
|
||||
@ -176,7 +176,7 @@ pub fn sys_fstatat(
|
||||
) -> Result<(), Errno> {
|
||||
Errno::from_syscall_unit(unsafe {
|
||||
syscall!(
|
||||
abi::SYS_FSTATAT,
|
||||
SystemCall::FileStatus,
|
||||
argn!(FileDescriptor::into_i32(at)),
|
||||
argp!(pathname.as_ptr()),
|
||||
argn!(pathname.len()),
|
||||
@ -191,7 +191,7 @@ pub fn sys_fstatat(
|
||||
/// System call
|
||||
#[inline(always)]
|
||||
pub unsafe fn sys_fork() -> Result<Option<Pid>, Errno> {
|
||||
Errno::from_syscall(unsafe { syscall!(abi::SYS_FORK) }).map(|res| {
|
||||
Errno::from_syscall(unsafe { syscall!(SystemCall::Fork) }).map(|res| {
|
||||
if res != 0 {
|
||||
Some(unsafe { Pid::from_raw(res as u32) })
|
||||
} else {
|
||||
@ -207,7 +207,7 @@ pub unsafe fn sys_fork() -> Result<Option<Pid>, Errno> {
|
||||
pub fn sys_execve(pathname: &str) -> Result<(), Errno> {
|
||||
Errno::from_syscall_unit(unsafe {
|
||||
syscall!(
|
||||
abi::SYS_EXECVE,
|
||||
SystemCall::Exec,
|
||||
argp!(pathname.as_ptr()),
|
||||
argn!(pathname.len())
|
||||
)
|
||||
@ -221,7 +221,7 @@ pub fn sys_execve(pathname: &str) -> Result<(), Errno> {
|
||||
pub fn sys_waitpid(pid: Pid, status: &mut i32) -> Result<(), Errno> {
|
||||
Errno::from_syscall_unit(unsafe {
|
||||
syscall!(
|
||||
abi::SYS_WAITPID,
|
||||
SystemCall::WaitPid,
|
||||
argn!(pid.value()),
|
||||
argp!(status as *mut i32)
|
||||
)
|
||||
@ -240,7 +240,7 @@ pub fn sys_ioctl(
|
||||
) -> Result<usize, Errno> {
|
||||
Errno::from_syscall(unsafe {
|
||||
syscall!(
|
||||
abi::SYS_IOCTL,
|
||||
SystemCall::Ioctl,
|
||||
argn!(u32::from(fd)),
|
||||
argn!(cmd),
|
||||
argn!(ptr),
|
||||
@ -252,19 +252,19 @@ pub fn sys_ioctl(
|
||||
#[inline(always)]
|
||||
pub fn sys_ex_getcputime() -> Result<Duration, Errno> {
|
||||
Errno::from_syscall(unsafe {
|
||||
syscall!(abi::SYS_EX_GETCPUTIME)
|
||||
syscall!(SystemCall::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)) })
|
||||
Errno::from_syscall_unit(unsafe { syscall!(SystemCall::SetSignalEntry, argn!(entry), argn!(stack)) })
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn sys_ex_sigreturn() -> ! {
|
||||
unsafe {
|
||||
syscall!(abi::SYS_EX_SIGRETURN);
|
||||
syscall!(SystemCall::SignalReturn);
|
||||
}
|
||||
unreachable!();
|
||||
}
|
||||
@ -273,7 +273,7 @@ pub fn sys_ex_sigreturn() -> ! {
|
||||
pub fn sys_ex_kill(pid: SignalDestination, signum: Signal) -> Result<(), Errno> {
|
||||
Errno::from_syscall_unit(unsafe {
|
||||
syscall!(
|
||||
abi::SYS_EX_KILL,
|
||||
SystemCall::SendSignal,
|
||||
argn!(isize::from(pid)),
|
||||
argn!(signum as u32)
|
||||
)
|
||||
@ -283,35 +283,28 @@ pub fn sys_ex_kill(pid: SignalDestination, signum: Signal) -> Result<(), Errno>
|
||||
#[inline(always)]
|
||||
pub fn sys_ex_clone(entry: usize, stack: usize, arg: usize) -> Result<usize, Errno> {
|
||||
Errno::from_syscall(unsafe {
|
||||
syscall!(abi::SYS_EX_CLONE, argn!(entry), argn!(stack), argn!(arg))
|
||||
syscall!(SystemCall::Clone, argn!(entry), argn!(stack), argn!(arg))
|
||||
})
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn sys_ex_thread_exit(status: ExitCode) -> ! {
|
||||
unsafe {
|
||||
syscall!(abi::SYS_EX_THREAD_EXIT, argn!(i32::from(status)));
|
||||
syscall!(SystemCall::Exit, argn!(i32::from(status)), argn!(1));
|
||||
}
|
||||
unreachable!();
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn sys_ex_thread_wait(tid: u32) -> Result<ExitCode, Errno> {
|
||||
Errno::from_syscall(unsafe { syscall!(abi::SYS_EX_THREAD_WAIT, argn!(tid)) })
|
||||
Errno::from_syscall(unsafe { syscall!(SystemCall::WaitTid, argn!(tid)) })
|
||||
.map(|_| ExitCode::from(0))
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn sys_ex_yield() {
|
||||
unsafe {
|
||||
syscall!(abi::SYS_EX_YIELD);
|
||||
}
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn sys_ex_undefined() {
|
||||
unsafe {
|
||||
syscall!(0);
|
||||
syscall!(SystemCall::Yield);
|
||||
}
|
||||
}
|
||||
|
||||
@ -323,7 +316,7 @@ pub fn sys_select(
|
||||
) -> Result<usize, Errno> {
|
||||
Errno::from_syscall(unsafe {
|
||||
syscall!(
|
||||
abi::SYS_SELECT,
|
||||
SystemCall::Select,
|
||||
argp!(read_fds
|
||||
.map(|e| e as *mut _)
|
||||
.unwrap_or(core::ptr::null_mut())),
|
||||
@ -344,7 +337,7 @@ pub fn sys_faccessat(
|
||||
) -> Result<(), Errno> {
|
||||
Errno::from_syscall_unit(unsafe {
|
||||
syscall!(
|
||||
abi::SYS_FACCESSAT,
|
||||
SystemCall::Access,
|
||||
argn!(FileDescriptor::into_i32(fd)),
|
||||
argp!(name.as_ptr()),
|
||||
argn!(name.len()),
|
||||
@ -357,6 +350,6 @@ pub fn sys_faccessat(
|
||||
#[inline(always)]
|
||||
pub fn sys_ex_gettid() -> u32 {
|
||||
unsafe {
|
||||
syscall!(abi::SYS_EX_GETTID) as u32
|
||||
syscall!(SystemCall::GetTid) as u32
|
||||
}
|
||||
}
|
||||
|
@ -5,7 +5,7 @@
|
||||
#[macro_use]
|
||||
extern crate libusr;
|
||||
|
||||
use libusr::sys::{abi, stat::Stat, Signal};
|
||||
use libusr::sys::{abi::SystemCall, stat::Stat, Signal};
|
||||
use libusr::signal::{self, SignalHandler};
|
||||
|
||||
static mut STATE: u64 = 0;
|
||||
@ -122,12 +122,12 @@ fn main() -> i32 {
|
||||
|
||||
// Test non-utf8 input fed into syscalls expecting strings
|
||||
// let old_signal = signal::set_handler(Signal::InvalidSystemCall, SignalHandler::Ignore);
|
||||
for _ in 0..10000 {
|
||||
for _ in 0..100 {
|
||||
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);
|
||||
syscall!(SystemCall::FileStatus.repr(), (-2i32) as usize, buf.as_mut_ptr() as usize, buf.len(), (&mut stat) as *mut _ as usize);
|
||||
}
|
||||
}
|
||||
// signal::set_handler(Signal::InvalidSystemCall, old_signal);
|
||||
|
@ -41,6 +41,16 @@ fn main() -> i32 {
|
||||
let mut buf = [0; 256];
|
||||
let mut stdin = io::stdin();
|
||||
|
||||
let delay = libusr::thread::spawn(|| {
|
||||
let mut t = [0; 2];
|
||||
libusr::sys::sys_ex_nanosleep(1_000_000_000, &mut t);
|
||||
});
|
||||
|
||||
delay.join();
|
||||
|
||||
libusr::signal::set_handler(libusr::sys::Signal::Interrupt, libusr::signal::SignalHandler::Ignore);
|
||||
libusr::sys::sys_ex_kill(libusr::sys::SignalDestination::This, libusr::sys::Signal::Interrupt);
|
||||
|
||||
loop {
|
||||
print!("> ");
|
||||
let line = readline(&mut stdin, &mut buf).unwrap();
|
||||
|
Loading…
x
Reference in New Issue
Block a user