Merge branch 'encoded_syscall'
This commit is contained in:
		
						commit
						10c88e7424
					
				
					 5 changed files with 131 additions and 204 deletions
				
			
		|  | @ -2,9 +2,48 @@ | |||
| 
 | ||||
| use context; | ||||
| use scheme; | ||||
| use syscall::data::Stat; | ||||
| use syscall::data::{Packet, Stat}; | ||||
| 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
 | ||||
| pub fn chdir(path: &[u8]) -> Result<usize> { | ||||
|     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); | ||||
|     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) | ||||
| } | ||||
|  |  | |||
|  | @ -8,7 +8,6 @@ pub use self::fs::*; | |||
| pub use self::process::*; | ||||
| pub use self::validate::*; | ||||
| 
 | ||||
| use self::data::Stat; | ||||
| use self::error::{Error, Result, ENOSYS}; | ||||
| 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 { | ||||
|     #[inline(always)] | ||||
|     fn inner(a: usize, b: usize, c: usize, d: usize, e: usize, _f: usize, stack: usize) -> Result<usize> { | ||||
|         match a { | ||||
|             SYS_EXIT => exit(b), | ||||
|             SYS_READ => read(b, validate_slice_mut(c as *mut u8, d)?), | ||||
|             SYS_WRITE => write(b, validate_slice(c as *const u8, d)?), | ||||
|             SYS_OPEN => open(validate_slice(b as *const u8, c)?, d), | ||||
|             SYS_CLOSE => close(b), | ||||
|             SYS_WAITPID => waitpid(b, c, d), | ||||
|             SYS_UNLINK => unlink(validate_slice(b as *const u8, c)?), | ||||
|             SYS_EXECVE => exec(validate_slice(b as *const u8, c)?, validate_slice(d as *const [usize; 2], e)?), | ||||
|             SYS_CHDIR => chdir(validate_slice(b as *const u8, c)?), | ||||
|             SYS_LSEEK => lseek(b, c, d), | ||||
|             SYS_GETPID => getpid(), | ||||
|             SYS_FSTAT => fstat(b, &mut validate_slice_mut(c as *mut Stat, 1)?[0]), | ||||
|             SYS_MKDIR => mkdir(validate_slice(b as *const u8, c)?, d), | ||||
|             SYS_RMDIR => rmdir(validate_slice(b as *const u8, c)?), | ||||
|             SYS_DUP => dup(b), | ||||
|             SYS_BRK => brk(b), | ||||
|             SYS_FTRUNCATE => ftruncate(b, c), | ||||
|             SYS_IOPL => iopl(b), | ||||
|             SYS_FSYNC => fsync(b), | ||||
|             SYS_CLONE => clone(b, stack), | ||||
|             SYS_YIELD => sched_yield(), | ||||
|             SYS_GETCWD => getcwd(validate_slice_mut(b as *mut u8, c)?), | ||||
|             SYS_GETUID => getuid(), | ||||
|             SYS_GETGID => getgid(), | ||||
|             SYS_SETUID => setuid(b as u32), | ||||
|             SYS_SETGID => setgid(b as u32), | ||||
|             SYS_FEVENT => fevent(b, c), | ||||
|             SYS_FPATH => fpath(b, validate_slice_mut(c as *mut u8, d)?), | ||||
|             SYS_PHYSALLOC => physalloc(b), | ||||
|             SYS_PHYSFREE => physfree(b, c), | ||||
|             SYS_PHYSMAP => physmap(b, c, d), | ||||
|             SYS_PHYSUNMAP => physunmap(b), | ||||
|             SYS_VIRTTOPHYS => virttophys(b), | ||||
|             _ => { | ||||
|                 println!("Unknown syscall {}", a); | ||||
|                 Err(Error::new(ENOSYS)) | ||||
|         match a & SYS_CLASS { | ||||
|             SYS_CLASS_FILE => match a & SYS_ARG { | ||||
|                 SYS_ARG_SLICE => file_op_slice(a, 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)?), | ||||
|                 _ => match a { | ||||
|                     SYS_CLOSE => close(b), | ||||
|                     SYS_DUP => dup(b), | ||||
|                     SYS_FEVENT => fevent(b, c), | ||||
|                     _ => file_op(a, b, c, d) | ||||
|                 } | ||||
|             }, | ||||
|             SYS_CLASS_PATH => match a { | ||||
|                 SYS_OPEN => open(validate_slice(b as *const u8, c)?, d), | ||||
|                 _ => unreachable!() | ||||
|             }, | ||||
|             _ => match a { | ||||
|                 SYS_EXIT => exit(b), | ||||
|                 SYS_WAITPID => waitpid(b, c, d), | ||||
|                 SYS_EXECVE => exec(validate_slice(b as *const u8, c)?, validate_slice(d as *const [usize; 2], e)?), | ||||
|                 SYS_CHDIR => chdir(validate_slice(b as *const u8, c)?), | ||||
|                 SYS_GETPID => getpid(), | ||||
|                 SYS_BRK => brk(b), | ||||
|                 SYS_IOPL => iopl(b), | ||||
|                 SYS_CLONE => clone(b, stack), | ||||
|                 SYS_YIELD => sched_yield(), | ||||
|                 SYS_GETCWD => getcwd(validate_slice_mut(b as *mut u8, c)?), | ||||
|                 SYS_GETUID => getuid(), | ||||
|                 SYS_GETGID => getgid(), | ||||
|                 SYS_SETUID => setuid(b as u32), | ||||
|                 SYS_SETGID => setgid(b as u32), | ||||
|                 SYS_PHYSALLOC => physalloc(b), | ||||
|                 SYS_PHYSFREE => physfree(b, c), | ||||
|                 SYS_PHYSMAP => physmap(b, c, d), | ||||
|                 SYS_PHYSUNMAP => physunmap(b), | ||||
|                 SYS_VIRTTOPHYS => virttophys(b), | ||||
|                 _ => Err(Error::new(ENOSYS)) | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|  |  | |||
|  | @ -434,10 +434,10 @@ pub fn exec(path: &[u8], arg_ptrs: &[[usize; 2]]) -> Result<usize> { | |||
| 
 | ||||
|         let file = syscall::open(path, 0)?; | ||||
|         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
 | ||||
|         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); | ||||
| 
 | ||||
|         match elf::Elf::from(&data) { | ||||
|  |  | |||
|  | @ -8,6 +8,8 @@ pub use self::flag::*; | |||
| pub use self::number::*; | ||||
| pub use self::scheme::*; | ||||
| 
 | ||||
| use core::mem; | ||||
| 
 | ||||
| #[cfg(target_arch = "x86")] | ||||
| #[path="x86.rs"] | ||||
| 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> { | ||||
|     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> { | ||||
|  |  | |||
|  | @ -1,38 +1,52 @@ | |||
| pub const SYS_BRK: usize = 45; | ||||
| pub const SYS_CHDIR: usize = 12; | ||||
| pub const SYS_CLONE: usize = 120; | ||||
| pub const SYS_CLOSE: usize = 6; | ||||
| pub const SYS_CLASS: usize =    0xF000_0000; | ||||
| pub const SYS_CLASS_PATH: usize=0x1000_0000; | ||||
| pub const SYS_CLASS_FILE: usize=0x2000_0000; | ||||
| 
 | ||||
| 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_DUP: usize = 41; | ||||
| pub const SYS_EXECVE: usize = 11; | ||||
| pub const SYS_EXIT: usize = 1; | ||||
| pub const SYS_FEVENT: usize = 927; | ||||
| pub const SYS_FPATH: usize = 928; | ||||
| pub const SYS_FSTAT: usize = 28; | ||||
| pub const SYS_FSYNC: usize = 118; | ||||
| pub const SYS_FTRUNCATE: usize = 93; | ||||
| pub const SYS_FUTEX: usize = 240; | ||||
| pub const SYS_GETCWD: usize = 183; | ||||
| pub const SYS_GETGID: usize = 200; | ||||
| 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_CLONE: usize =    120; | ||||
| pub const SYS_EXECVE: usize =   11; | ||||
| pub const SYS_EXIT: usize =     1; | ||||
| pub const SYS_FUTEX: usize =    240; | ||||
| pub const SYS_GETCWD: usize =   183; | ||||
| pub const SYS_GETGID: usize =   200; | ||||
| pub const SYS_GETPID: usize =   20; | ||||
| pub const SYS_GETUID: usize =   199; | ||||
| pub const SYS_IOPL: usize =     110; | ||||
| pub const SYS_NANOSLEEP: usize =162; | ||||
| pub const SYS_PHYSALLOC: usize =945; | ||||
| pub const SYS_PHYSFREE: usize = 946; | ||||
| pub const SYS_PHYSMAP: usize = 947; | ||||
| pub const SYS_PHYSUNMAP: usize = 948; | ||||
| pub const SYS_VIRTTOPHYS: usize = 949; | ||||
| pub const SYS_PIPE2: usize = 331; | ||||
| pub const SYS_READ: usize = 3; | ||||
| pub const SYS_RMDIR: usize = 84; | ||||
| pub const SYS_SETGID: usize = 214; | ||||
| pub const SYS_SETUID: usize = 213; | ||||
| pub const SYS_UNLINK: usize = 10; | ||||
| pub const SYS_WAITPID: usize = 7; | ||||
| pub const SYS_WRITE: usize = 4; | ||||
| pub const SYS_YIELD: usize = 158; | ||||
| pub const SYS_PHYSMAP: usize =  947; | ||||
| pub const SYS_PHYSUNMAP: usize =948; | ||||
| pub const SYS_VIRTTOPHYS: usize=949; | ||||
| pub const SYS_PIPE2: usize =    331; | ||||
| pub const SYS_SETGID: usize =   214; | ||||
| pub const SYS_SETUID: usize =   213; | ||||
| pub const SYS_WAITPID: usize =  7; | ||||
| pub const SYS_YIELD: usize =    158; | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Jeremy Soller
						Jeremy Soller