Merge branch 'encoded_syscall'

This commit is contained in:
Jeremy Soller 2016-10-05 15:43:35 -06:00
commit 10c88e7424
5 changed files with 131 additions and 204 deletions

View file

@ -2,9 +2,48 @@
use context; use context;
use scheme; use scheme;
use syscall::data::Stat; use syscall::data::{Packet, Stat};
use syscall::error::*; use syscall::error::*;
pub fn file_op(a: usize, fd: usize, c: usize, d: usize) -> Result<usize> {
let (file, pid, uid, gid) = {
let contexts = context::contexts();
let context_lock = contexts.current().ok_or(Error::new(ESRCH))?;
let context = context_lock.read();
let file = context.get_file(fd).ok_or(Error::new(EBADF))?;
(file, context.id, context.uid, context.gid)
};
let scheme = {
let schemes = scheme::schemes();
let scheme = schemes.get(file.scheme).ok_or(Error::new(EBADF))?;
scheme.clone()
};
let mut packet = Packet {
id: 0,
pid: pid,
uid: uid,
gid: gid,
a: a,
b: file.number,
c: c,
d: d
};
scheme.handle(&mut packet);
Error::demux(packet.a)
}
pub fn file_op_slice(a: usize, fd: usize, slice: &[u8]) -> Result<usize> {
file_op(a, fd, slice.as_ptr() as usize, slice.len())
}
pub fn file_op_mut_slice(a: usize, fd: usize, slice: &mut [u8]) -> Result<usize> {
file_op(a, fd, slice.as_mut_ptr() as usize, slice.len())
}
/// Change the current working directory /// Change the current working directory
pub fn chdir(path: &[u8]) -> Result<usize> { pub fn chdir(path: &[u8]) -> Result<usize> {
let contexts = context::contexts(); let contexts = context::contexts();
@ -195,129 +234,3 @@ pub fn fevent(fd: usize, flags: usize) -> Result<usize> {
context::event::register(fd, file.scheme, file.number); context::event::register(fd, file.scheme, file.number);
Ok(0) Ok(0)
} }
/// Get the canonical path of the file
pub fn fpath(fd: usize, buf: &mut [u8]) -> Result<usize> {
let file = {
let contexts = context::contexts();
let context_lock = contexts.current().ok_or(Error::new(ESRCH))?;
let context = context_lock.read();
let file = context.get_file(fd).ok_or(Error::new(EBADF))?;
file
};
let scheme = {
let schemes = scheme::schemes();
let scheme = schemes.get(file.scheme).ok_or(Error::new(EBADF))?;
scheme.clone()
};
scheme.fpath(file.number, buf)
}
/// Get information about the file
pub fn fstat(fd: usize, stat: &mut Stat) -> Result<usize> {
let file = {
let contexts = context::contexts();
let context_lock = contexts.current().ok_or(Error::new(ESRCH))?;
let context = context_lock.read();
let file = context.get_file(fd).ok_or(Error::new(EBADF))?;
file
};
let scheme = {
let schemes = scheme::schemes();
let scheme = schemes.get(file.scheme).ok_or(Error::new(EBADF))?;
scheme.clone()
};
scheme.fstat(file.number, stat)
}
/// Sync the file descriptor
pub fn fsync(fd: usize) -> Result<usize> {
let file = {
let contexts = context::contexts();
let context_lock = contexts.current().ok_or(Error::new(ESRCH))?;
let context = context_lock.read();
let file = context.get_file(fd).ok_or(Error::new(EBADF))?;
file
};
let scheme = {
let schemes = scheme::schemes();
let scheme = schemes.get(file.scheme).ok_or(Error::new(EBADF))?;
scheme.clone()
};
scheme.fsync(file.number)
}
/// Truncate the file descriptor
pub fn ftruncate(fd: usize, len: usize) -> Result<usize> {
let file = {
let contexts = context::contexts();
let context_lock = contexts.current().ok_or(Error::new(ESRCH))?;
let context = context_lock.read();
let file = context.get_file(fd).ok_or(Error::new(EBADF))?;
file
};
let scheme = {
let schemes = scheme::schemes();
let scheme = schemes.get(file.scheme).ok_or(Error::new(EBADF))?;
scheme.clone()
};
scheme.ftruncate(file.number, len)
}
/// Seek to an offset
pub fn lseek(fd: usize, pos: usize, whence: usize) -> Result<usize> {
let file = {
let contexts = context::contexts();
let context_lock = contexts.current().ok_or(Error::new(ESRCH))?;
let context = context_lock.read();
let file = context.get_file(fd).ok_or(Error::new(EBADF))?;
file
};
let scheme = {
let schemes = scheme::schemes();
let scheme = schemes.get(file.scheme).ok_or(Error::new(EBADF))?;
scheme.clone()
};
scheme.seek(file.number, pos, whence)
}
/// Read syscall
pub fn read(fd: usize, buf: &mut [u8]) -> Result<usize> {
let file = {
let contexts = context::contexts();
let context_lock = contexts.current().ok_or(Error::new(ESRCH))?;
let context = context_lock.read();
let file = context.get_file(fd).ok_or(Error::new(EBADF))?;
file
};
let scheme = {
let schemes = scheme::schemes();
let scheme = schemes.get(file.scheme).ok_or(Error::new(EBADF))?;
scheme.clone()
};
scheme.read(file.number, buf)
}
/// Write syscall
pub fn write(fd: usize, buf: &[u8]) -> Result<usize> {
let file = {
let contexts = context::contexts();
let context_lock = contexts.current().ok_or(Error::new(ESRCH))?;
let context = context_lock.read();
let file = context.get_file(fd).ok_or(Error::new(EBADF))?;
file
};
let scheme = {
let schemes = scheme::schemes();
let scheme = schemes.get(file.scheme).ok_or(Error::new(EBADF))?;
scheme.clone()
};
scheme.write(file.number, buf)
}

View file

@ -8,7 +8,6 @@ pub use self::fs::*;
pub use self::process::*; pub use self::process::*;
pub use self::validate::*; pub use self::validate::*;
use self::data::Stat;
use self::error::{Error, Result, ENOSYS}; use self::error::{Error, Result, ENOSYS};
use self::number::*; use self::number::*;
@ -25,43 +24,42 @@ pub mod validate;
pub extern fn syscall(a: usize, b: usize, c: usize, d: usize, e: usize, f: usize, stack: usize) -> usize { pub extern fn syscall(a: usize, b: usize, c: usize, d: usize, e: usize, f: usize, stack: usize) -> usize {
#[inline(always)] #[inline(always)]
fn inner(a: usize, b: usize, c: usize, d: usize, e: usize, _f: usize, stack: usize) -> Result<usize> { fn inner(a: usize, b: usize, c: usize, d: usize, e: usize, _f: usize, stack: usize) -> Result<usize> {
match a { match a & SYS_CLASS {
SYS_EXIT => exit(b), SYS_CLASS_FILE => match a & SYS_ARG {
SYS_READ => read(b, validate_slice_mut(c as *mut u8, d)?), SYS_ARG_SLICE => file_op_slice(a, b, validate_slice(c as *const u8, d)?),
SYS_WRITE => write(b, validate_slice(c as *const u8, d)?), SYS_ARG_MSLICE => file_op_mut_slice(a, b, validate_slice_mut(c as *mut u8, d)?),
SYS_OPEN => open(validate_slice(b as *const u8, c)?, d), _ => match a {
SYS_CLOSE => close(b), SYS_CLOSE => close(b),
SYS_WAITPID => waitpid(b, c, d), SYS_DUP => dup(b),
SYS_UNLINK => unlink(validate_slice(b as *const u8, c)?), SYS_FEVENT => fevent(b, c),
SYS_EXECVE => exec(validate_slice(b as *const u8, c)?, validate_slice(d as *const [usize; 2], e)?), _ => file_op(a, b, c, d)
SYS_CHDIR => chdir(validate_slice(b as *const u8, c)?), }
SYS_LSEEK => lseek(b, c, d), },
SYS_GETPID => getpid(), SYS_CLASS_PATH => match a {
SYS_FSTAT => fstat(b, &mut validate_slice_mut(c as *mut Stat, 1)?[0]), SYS_OPEN => open(validate_slice(b as *const u8, c)?, d),
SYS_MKDIR => mkdir(validate_slice(b as *const u8, c)?, d), _ => unreachable!()
SYS_RMDIR => rmdir(validate_slice(b as *const u8, c)?), },
SYS_DUP => dup(b), _ => match a {
SYS_BRK => brk(b), SYS_EXIT => exit(b),
SYS_FTRUNCATE => ftruncate(b, c), SYS_WAITPID => waitpid(b, c, d),
SYS_IOPL => iopl(b), SYS_EXECVE => exec(validate_slice(b as *const u8, c)?, validate_slice(d as *const [usize; 2], e)?),
SYS_FSYNC => fsync(b), SYS_CHDIR => chdir(validate_slice(b as *const u8, c)?),
SYS_CLONE => clone(b, stack), SYS_GETPID => getpid(),
SYS_YIELD => sched_yield(), SYS_BRK => brk(b),
SYS_GETCWD => getcwd(validate_slice_mut(b as *mut u8, c)?), SYS_IOPL => iopl(b),
SYS_GETUID => getuid(), SYS_CLONE => clone(b, stack),
SYS_GETGID => getgid(), SYS_YIELD => sched_yield(),
SYS_SETUID => setuid(b as u32), SYS_GETCWD => getcwd(validate_slice_mut(b as *mut u8, c)?),
SYS_SETGID => setgid(b as u32), SYS_GETUID => getuid(),
SYS_FEVENT => fevent(b, c), SYS_GETGID => getgid(),
SYS_FPATH => fpath(b, validate_slice_mut(c as *mut u8, d)?), SYS_SETUID => setuid(b as u32),
SYS_PHYSALLOC => physalloc(b), SYS_SETGID => setgid(b as u32),
SYS_PHYSFREE => physfree(b, c), SYS_PHYSALLOC => physalloc(b),
SYS_PHYSMAP => physmap(b, c, d), SYS_PHYSFREE => physfree(b, c),
SYS_PHYSUNMAP => physunmap(b), SYS_PHYSMAP => physmap(b, c, d),
SYS_VIRTTOPHYS => virttophys(b), SYS_PHYSUNMAP => physunmap(b),
_ => { SYS_VIRTTOPHYS => virttophys(b),
println!("Unknown syscall {}", a); _ => Err(Error::new(ENOSYS))
Err(Error::new(ENOSYS))
} }
} }
} }

View file

@ -434,10 +434,10 @@ pub fn exec(path: &[u8], arg_ptrs: &[[usize; 2]]) -> Result<usize> {
let file = syscall::open(path, 0)?; let file = syscall::open(path, 0)?;
let mut stat = Stat::default(); let mut stat = Stat::default();
syscall::fstat(file, &mut stat)?; syscall::file_op_mut_slice(syscall::number::SYS_FSTAT, file, &mut stat)?;
//TODO: Only read elf header, not entire file. Then read required segments //TODO: Only read elf header, not entire file. Then read required segments
let mut data = vec![0; stat.st_size as usize]; let mut data = vec![0; stat.st_size as usize];
syscall::read(file, &mut data)?; syscall::file_op_mut_slice(syscall::number::SYS_READ, file, &mut data)?;
let _ = syscall::close(file); let _ = syscall::close(file);
match elf::Elf::from(&data) { match elf::Elf::from(&data) {

View file

@ -8,6 +8,8 @@ pub use self::flag::*;
pub use self::number::*; pub use self::number::*;
pub use self::scheme::*; pub use self::scheme::*;
use core::mem;
#[cfg(target_arch = "x86")] #[cfg(target_arch = "x86")]
#[path="x86.rs"] #[path="x86.rs"]
mod arch; mod arch;
@ -67,7 +69,7 @@ pub fn fpath(fd: usize, buf: &mut [u8]) -> Result<usize> {
} }
pub fn fstat(fd: usize, stat: &mut Stat) -> Result<usize> { pub fn fstat(fd: usize, stat: &mut Stat) -> Result<usize> {
unsafe { syscall2(SYS_FSTAT, fd, stat as *mut Stat as usize) } unsafe { syscall3(SYS_FSTAT, fd, stat as *mut Stat as usize, mem::size_of::<Stat>()) }
} }
pub fn fsync(fd: usize) -> Result<usize> { pub fn fsync(fd: usize) -> Result<usize> {

View file

@ -1,38 +1,52 @@
pub const SYS_BRK: usize = 45; pub const SYS_CLASS: usize = 0xF000_0000;
pub const SYS_CHDIR: usize = 12; pub const SYS_CLASS_PATH: usize=0x1000_0000;
pub const SYS_CLONE: usize = 120; pub const SYS_CLASS_FILE: usize=0x2000_0000;
pub const SYS_CLOSE: usize = 6;
pub const SYS_ARG: usize = 0x0F00_0000;
pub const SYS_ARG_SLICE: usize =0x0100_0000;
pub const SYS_ARG_MSLICE: usize=0x0200_0000;
pub const SYS_ARG_PATH: usize = 0x0300_0000;
pub const SYS_RET: usize = 0x00F0_0000;
pub const SYS_RET_FILE: usize = 0x0010_0000;
pub const SYS_LINK: usize = SYS_CLASS_PATH | SYS_ARG_PATH | 9;
pub const SYS_OPEN: usize = SYS_CLASS_PATH | SYS_RET_FILE | 5;
pub const SYS_MKDIR: usize = SYS_CLASS_PATH | 39;
pub const SYS_RMDIR: usize = SYS_CLASS_PATH | 84;
pub const SYS_UNLINK: usize = SYS_CLASS_PATH | 10;
pub const SYS_CLOSE: usize = SYS_CLASS_FILE | 6;
pub const SYS_DUP: usize = SYS_CLASS_FILE | SYS_RET_FILE | 41;
pub const SYS_READ: usize = SYS_CLASS_FILE | SYS_ARG_MSLICE | 3;
pub const SYS_WRITE: usize = SYS_CLASS_FILE | SYS_ARG_SLICE | 4;
pub const SYS_FEVENT: usize = SYS_CLASS_FILE | 927;
pub const SYS_LSEEK: usize = SYS_CLASS_FILE | 19;
pub const SYS_FPATH: usize = SYS_CLASS_FILE | SYS_ARG_MSLICE | 928;
pub const SYS_FSTAT: usize = SYS_CLASS_FILE | SYS_ARG_MSLICE | 28;
pub const SYS_FSYNC: usize = SYS_CLASS_FILE | 118;
pub const SYS_FTRUNCATE: usize =SYS_CLASS_FILE | 93;
pub const SYS_BRK: usize = 45;
pub const SYS_CHDIR: usize = 12;
pub const SYS_CLOCK_GETTIME: usize = 265; pub const SYS_CLOCK_GETTIME: usize = 265;
pub const SYS_DUP: usize = 41; pub const SYS_CLONE: usize = 120;
pub const SYS_EXECVE: usize = 11; pub const SYS_EXECVE: usize = 11;
pub const SYS_EXIT: usize = 1; pub const SYS_EXIT: usize = 1;
pub const SYS_FEVENT: usize = 927; pub const SYS_FUTEX: usize = 240;
pub const SYS_FPATH: usize = 928; pub const SYS_GETCWD: usize = 183;
pub const SYS_FSTAT: usize = 28; pub const SYS_GETGID: usize = 200;
pub const SYS_FSYNC: usize = 118; pub const SYS_GETPID: usize = 20;
pub const SYS_FTRUNCATE: usize = 93; pub const SYS_GETUID: usize = 199;
pub const SYS_FUTEX: usize = 240; pub const SYS_IOPL: usize = 110;
pub const SYS_GETCWD: usize = 183; pub const SYS_NANOSLEEP: usize =162;
pub const SYS_GETGID: usize = 200; pub const SYS_PHYSALLOC: usize =945;
pub const SYS_GETPID: usize = 20;
pub const SYS_GETUID: usize = 199;
pub const SYS_IOPL: usize = 110;
pub const SYS_LINK: usize = 9;
pub const SYS_LSEEK: usize = 19;
pub const SYS_MKDIR: usize = 39;
pub const SYS_NANOSLEEP: usize = 162;
pub const SYS_OPEN: usize = 5;
pub const SYS_PHYSALLOC: usize = 945;
pub const SYS_PHYSFREE: usize = 946; pub const SYS_PHYSFREE: usize = 946;
pub const SYS_PHYSMAP: usize = 947; pub const SYS_PHYSMAP: usize = 947;
pub const SYS_PHYSUNMAP: usize = 948; pub const SYS_PHYSUNMAP: usize =948;
pub const SYS_VIRTTOPHYS: usize = 949; pub const SYS_VIRTTOPHYS: usize=949;
pub const SYS_PIPE2: usize = 331; pub const SYS_PIPE2: usize = 331;
pub const SYS_READ: usize = 3; pub const SYS_SETGID: usize = 214;
pub const SYS_RMDIR: usize = 84; pub const SYS_SETUID: usize = 213;
pub const SYS_SETGID: usize = 214; pub const SYS_WAITPID: usize = 7;
pub const SYS_SETUID: usize = 213; pub const SYS_YIELD: usize = 158;
pub const SYS_UNLINK: usize = 10;
pub const SYS_WAITPID: usize = 7;
pub const SYS_WRITE: usize = 4;
pub const SYS_YIELD: usize = 158;