1*40fe15e0SLoGin use core::{fmt::Debug, ptr::null}; 2*40fe15e0SLoGin 3*40fe15e0SLoGin use alloc::{collections::BTreeMap, string::String, sync::Arc, vec::Vec}; 4*40fe15e0SLoGin 5*40fe15e0SLoGin use crate::{ 6*40fe15e0SLoGin filesystem::vfs::{ 7*40fe15e0SLoGin file::{File, FileMode}, 8*40fe15e0SLoGin ROOT_INODE, 9*40fe15e0SLoGin }, 10*40fe15e0SLoGin io::SeekFrom, 11*40fe15e0SLoGin libs::elf::ELF_LOADER, 12*40fe15e0SLoGin mm::{ 13*40fe15e0SLoGin ucontext::{AddressSpace, UserStack}, 14*40fe15e0SLoGin VirtAddr, 15*40fe15e0SLoGin }, 16*40fe15e0SLoGin syscall::SystemError, 17*40fe15e0SLoGin }; 18*40fe15e0SLoGin 19*40fe15e0SLoGin /// 系统支持的所有二进制文件加载器的列表 20*40fe15e0SLoGin const BINARY_LOADERS: [&'static dyn BinaryLoader; 1] = [&ELF_LOADER]; 21*40fe15e0SLoGin 22*40fe15e0SLoGin pub trait BinaryLoader: 'static + Debug { 23*40fe15e0SLoGin /// 检查二进制文件是否为当前加载器支持的格式 24*40fe15e0SLoGin fn probe(self: &'static Self, param: &ExecParam, buf: &[u8]) -> Result<(), ExecError>; 25*40fe15e0SLoGin 26*40fe15e0SLoGin fn load( 27*40fe15e0SLoGin self: &'static Self, 28*40fe15e0SLoGin param: &mut ExecParam, 29*40fe15e0SLoGin head_buf: &[u8], 30*40fe15e0SLoGin ) -> Result<BinaryLoaderResult, ExecError>; 31*40fe15e0SLoGin } 32*40fe15e0SLoGin 33*40fe15e0SLoGin /// 二进制文件加载结果 34*40fe15e0SLoGin #[derive(Debug)] 35*40fe15e0SLoGin pub struct BinaryLoaderResult { 36*40fe15e0SLoGin /// 程序入口地址 37*40fe15e0SLoGin entry_point: VirtAddr, 38*40fe15e0SLoGin } 39*40fe15e0SLoGin 40*40fe15e0SLoGin impl BinaryLoaderResult { 41*40fe15e0SLoGin pub fn new(entry_point: VirtAddr) -> Self { 42*40fe15e0SLoGin Self { entry_point } 43*40fe15e0SLoGin } 44*40fe15e0SLoGin 45*40fe15e0SLoGin pub fn entry_point(&self) -> VirtAddr { 46*40fe15e0SLoGin self.entry_point 47*40fe15e0SLoGin } 48*40fe15e0SLoGin } 49*40fe15e0SLoGin 50*40fe15e0SLoGin #[allow(dead_code)] 51*40fe15e0SLoGin #[derive(Debug)] 52*40fe15e0SLoGin pub enum ExecError { 53*40fe15e0SLoGin /// 二进制文件不可执行 54*40fe15e0SLoGin NotExecutable, 55*40fe15e0SLoGin /// 二进制文件不是当前架构的 56*40fe15e0SLoGin WrongArchitecture, 57*40fe15e0SLoGin /// 访问权限不足 58*40fe15e0SLoGin PermissionDenied, 59*40fe15e0SLoGin /// 不支持的操作 60*40fe15e0SLoGin NotSupported, 61*40fe15e0SLoGin /// 解析文件本身的时候出现错误(比如一些字段本身不合法) 62*40fe15e0SLoGin ParseError, 63*40fe15e0SLoGin /// 内存不足 64*40fe15e0SLoGin OutOfMemory, 65*40fe15e0SLoGin /// 参数错误 66*40fe15e0SLoGin InvalidParemeter, 67*40fe15e0SLoGin /// 无效的地址 68*40fe15e0SLoGin BadAddress(Option<VirtAddr>), 69*40fe15e0SLoGin Other(String), 70*40fe15e0SLoGin } 71*40fe15e0SLoGin 72*40fe15e0SLoGin impl Into<SystemError> for ExecError { 73*40fe15e0SLoGin fn into(self) -> SystemError { 74*40fe15e0SLoGin match self { 75*40fe15e0SLoGin ExecError::NotExecutable => SystemError::ENOEXEC, 76*40fe15e0SLoGin ExecError::WrongArchitecture => SystemError::EOPNOTSUPP_OR_ENOTSUP, 77*40fe15e0SLoGin ExecError::PermissionDenied => SystemError::EACCES, 78*40fe15e0SLoGin ExecError::NotSupported => SystemError::EOPNOTSUPP_OR_ENOTSUP, 79*40fe15e0SLoGin ExecError::ParseError => SystemError::ENOEXEC, 80*40fe15e0SLoGin ExecError::OutOfMemory => SystemError::ENOMEM, 81*40fe15e0SLoGin ExecError::InvalidParemeter => SystemError::EINVAL, 82*40fe15e0SLoGin ExecError::BadAddress(_addr) => SystemError::EFAULT, 83*40fe15e0SLoGin ExecError::Other(_msg) => SystemError::ENOEXEC, 84*40fe15e0SLoGin } 85*40fe15e0SLoGin } 86*40fe15e0SLoGin } 87*40fe15e0SLoGin 88*40fe15e0SLoGin bitflags! { 89*40fe15e0SLoGin pub struct ExecParamFlags: u32 { 90*40fe15e0SLoGin // 是否以可执行文件的形式加载 91*40fe15e0SLoGin const EXEC = 1 << 0; 92*40fe15e0SLoGin } 93*40fe15e0SLoGin } 94*40fe15e0SLoGin 95*40fe15e0SLoGin #[derive(Debug)] 96*40fe15e0SLoGin pub struct ExecParam<'a> { 97*40fe15e0SLoGin file_path: &'a str, 98*40fe15e0SLoGin file: Option<File>, 99*40fe15e0SLoGin vm: Arc<AddressSpace>, 100*40fe15e0SLoGin /// 一些标志位 101*40fe15e0SLoGin flags: ExecParamFlags, 102*40fe15e0SLoGin /// 用来初始化进程的一些信息。这些信息由二进制加载器和exec机制来共同填充 103*40fe15e0SLoGin init_info: ProcInitInfo, 104*40fe15e0SLoGin } 105*40fe15e0SLoGin 106*40fe15e0SLoGin #[derive(Debug, Eq, PartialEq)] 107*40fe15e0SLoGin pub enum ExecLoadMode { 108*40fe15e0SLoGin /// 以可执行文件的形式加载 109*40fe15e0SLoGin Exec, 110*40fe15e0SLoGin /// 以动态链接库的形式加载 111*40fe15e0SLoGin DSO, 112*40fe15e0SLoGin } 113*40fe15e0SLoGin 114*40fe15e0SLoGin #[allow(dead_code)] 115*40fe15e0SLoGin impl<'a> ExecParam<'a> { 116*40fe15e0SLoGin pub fn new(file_path: &'a str, vm: Arc<AddressSpace>, flags: ExecParamFlags) -> Self { 117*40fe15e0SLoGin Self { 118*40fe15e0SLoGin file_path, 119*40fe15e0SLoGin file: None, 120*40fe15e0SLoGin vm, 121*40fe15e0SLoGin flags, 122*40fe15e0SLoGin init_info: ProcInitInfo::new(), 123*40fe15e0SLoGin } 124*40fe15e0SLoGin } 125*40fe15e0SLoGin 126*40fe15e0SLoGin pub fn file_path(&self) -> &'a str { 127*40fe15e0SLoGin self.file_path 128*40fe15e0SLoGin } 129*40fe15e0SLoGin 130*40fe15e0SLoGin pub fn vm(&self) -> &Arc<AddressSpace> { 131*40fe15e0SLoGin &self.vm 132*40fe15e0SLoGin } 133*40fe15e0SLoGin 134*40fe15e0SLoGin pub fn flags(&self) -> &ExecParamFlags { 135*40fe15e0SLoGin &self.flags 136*40fe15e0SLoGin } 137*40fe15e0SLoGin 138*40fe15e0SLoGin pub fn init_info(&self) -> &ProcInitInfo { 139*40fe15e0SLoGin &self.init_info 140*40fe15e0SLoGin } 141*40fe15e0SLoGin 142*40fe15e0SLoGin pub fn init_info_mut(&mut self) -> &mut ProcInitInfo { 143*40fe15e0SLoGin &mut self.init_info 144*40fe15e0SLoGin } 145*40fe15e0SLoGin 146*40fe15e0SLoGin /// 获取加载模式 147*40fe15e0SLoGin pub fn load_mode(&self) -> ExecLoadMode { 148*40fe15e0SLoGin if self.flags.contains(ExecParamFlags::EXEC) { 149*40fe15e0SLoGin ExecLoadMode::Exec 150*40fe15e0SLoGin } else { 151*40fe15e0SLoGin ExecLoadMode::DSO 152*40fe15e0SLoGin } 153*40fe15e0SLoGin } 154*40fe15e0SLoGin 155*40fe15e0SLoGin pub fn file_mut(&mut self) -> &mut File { 156*40fe15e0SLoGin self.file.as_mut().unwrap() 157*40fe15e0SLoGin } 158*40fe15e0SLoGin } 159*40fe15e0SLoGin 160*40fe15e0SLoGin /// ## 加载二进制文件 161*40fe15e0SLoGin pub fn load_binary_file(param: &mut ExecParam) -> Result<BinaryLoaderResult, SystemError> { 162*40fe15e0SLoGin let inode = ROOT_INODE().lookup(param.file_path)?; 163*40fe15e0SLoGin 164*40fe15e0SLoGin // 读取文件头部,用于判断文件类型 165*40fe15e0SLoGin let file = File::new(inode, FileMode::O_RDONLY)?; 166*40fe15e0SLoGin param.file = Some(file); 167*40fe15e0SLoGin let mut head_buf = [0u8; 512]; 168*40fe15e0SLoGin param.file_mut().lseek(SeekFrom::SeekSet(0))?; 169*40fe15e0SLoGin let _bytes = param.file_mut().read(512, &mut head_buf)?; 170*40fe15e0SLoGin // kdebug!("load_binary_file: read {} bytes", _bytes); 171*40fe15e0SLoGin 172*40fe15e0SLoGin let mut loader = None; 173*40fe15e0SLoGin for bl in BINARY_LOADERS.iter() { 174*40fe15e0SLoGin let probe_result = bl.probe(param, &head_buf); 175*40fe15e0SLoGin if probe_result.is_ok() { 176*40fe15e0SLoGin loader = Some(bl); 177*40fe15e0SLoGin break; 178*40fe15e0SLoGin } 179*40fe15e0SLoGin } 180*40fe15e0SLoGin // kdebug!("load_binary_file: loader: {:?}", loader); 181*40fe15e0SLoGin if loader.is_none() { 182*40fe15e0SLoGin return Err(SystemError::ENOEXEC); 183*40fe15e0SLoGin } 184*40fe15e0SLoGin 185*40fe15e0SLoGin let loader: &&dyn BinaryLoader = loader.unwrap(); 186*40fe15e0SLoGin assert!(param.vm().is_current()); 187*40fe15e0SLoGin // kdebug!("load_binary_file: to load with param: {:?}", param); 188*40fe15e0SLoGin 189*40fe15e0SLoGin let result: BinaryLoaderResult = loader 190*40fe15e0SLoGin .load(param, &head_buf) 191*40fe15e0SLoGin .unwrap_or_else(|e| panic!("load_binary_file failed: error: {e:?}, param: {param:?}")); 192*40fe15e0SLoGin 193*40fe15e0SLoGin // kdebug!("load_binary_file: load success"); 194*40fe15e0SLoGin return Ok(result); 195*40fe15e0SLoGin } 196*40fe15e0SLoGin 197*40fe15e0SLoGin /// 程序初始化信息,这些信息会被压入用户栈中 198*40fe15e0SLoGin #[derive(Debug)] 199*40fe15e0SLoGin pub struct ProcInitInfo { 200*40fe15e0SLoGin pub args: Vec<String>, 201*40fe15e0SLoGin pub envs: Vec<String>, 202*40fe15e0SLoGin pub auxv: BTreeMap<u8, usize>, 203*40fe15e0SLoGin } 204*40fe15e0SLoGin 205*40fe15e0SLoGin impl ProcInitInfo { 206*40fe15e0SLoGin pub fn new() -> Self { 207*40fe15e0SLoGin Self { 208*40fe15e0SLoGin args: Vec::new(), 209*40fe15e0SLoGin envs: Vec::new(), 210*40fe15e0SLoGin auxv: BTreeMap::new(), 211*40fe15e0SLoGin } 212*40fe15e0SLoGin } 213*40fe15e0SLoGin 214*40fe15e0SLoGin /// 把程序初始化信息压入用户栈中 215*40fe15e0SLoGin /// 这个函数会把参数、环境变量、auxv等信息压入用户栈中 216*40fe15e0SLoGin /// 217*40fe15e0SLoGin /// ## 返回值 218*40fe15e0SLoGin /// 219*40fe15e0SLoGin /// 返回值是一个元组,第一个元素是最终的用户栈顶地址,第二个元素是环境变量pointer数组的起始地址 220*40fe15e0SLoGin pub unsafe fn push_at( 221*40fe15e0SLoGin &self, 222*40fe15e0SLoGin ustack: &mut UserStack, 223*40fe15e0SLoGin ) -> Result<(VirtAddr, VirtAddr), SystemError> { 224*40fe15e0SLoGin // 先把程序的名称压入栈中 225*40fe15e0SLoGin self.push_str(ustack, self.args[0].as_str())?; 226*40fe15e0SLoGin 227*40fe15e0SLoGin // 然后把环境变量压入栈中 228*40fe15e0SLoGin let envps = self 229*40fe15e0SLoGin .envs 230*40fe15e0SLoGin .iter() 231*40fe15e0SLoGin .map(|s| { 232*40fe15e0SLoGin self.push_str(ustack, s.as_str()).expect("push_str failed"); 233*40fe15e0SLoGin ustack.sp() 234*40fe15e0SLoGin }) 235*40fe15e0SLoGin .collect::<Vec<_>>(); 236*40fe15e0SLoGin 237*40fe15e0SLoGin // 然后把参数压入栈中 238*40fe15e0SLoGin let argps = self 239*40fe15e0SLoGin .args 240*40fe15e0SLoGin .iter() 241*40fe15e0SLoGin .map(|s| { 242*40fe15e0SLoGin self.push_str(ustack, s.as_str()).expect("push_str failed"); 243*40fe15e0SLoGin ustack.sp() 244*40fe15e0SLoGin }) 245*40fe15e0SLoGin .collect::<Vec<_>>(); 246*40fe15e0SLoGin 247*40fe15e0SLoGin // 压入auxv 248*40fe15e0SLoGin self.push_slice(ustack, &[null::<u8>(), null::<u8>()])?; 249*40fe15e0SLoGin for (&k, &v) in self.auxv.iter() { 250*40fe15e0SLoGin self.push_slice(ustack, &[k as usize, v])?; 251*40fe15e0SLoGin } 252*40fe15e0SLoGin 253*40fe15e0SLoGin // 把环境变量指针压入栈中 254*40fe15e0SLoGin self.push_slice(ustack, &[null::<u8>()])?; 255*40fe15e0SLoGin self.push_slice(ustack, envps.as_slice())?; 256*40fe15e0SLoGin 257*40fe15e0SLoGin // 把参数指针压入栈中 258*40fe15e0SLoGin self.push_slice(ustack, &[null::<u8>()])?; 259*40fe15e0SLoGin self.push_slice(ustack, argps.as_slice())?; 260*40fe15e0SLoGin 261*40fe15e0SLoGin let argv_ptr = ustack.sp(); 262*40fe15e0SLoGin 263*40fe15e0SLoGin // 把argc压入栈中 264*40fe15e0SLoGin self.push_slice(ustack, &[self.args.len()])?; 265*40fe15e0SLoGin 266*40fe15e0SLoGin return Ok((ustack.sp(), argv_ptr)); 267*40fe15e0SLoGin } 268*40fe15e0SLoGin 269*40fe15e0SLoGin fn push_slice<T: Copy>(&self, ustack: &mut UserStack, slice: &[T]) -> Result<(), SystemError> { 270*40fe15e0SLoGin let mut sp = ustack.sp(); 271*40fe15e0SLoGin sp -= slice.len() * core::mem::size_of::<T>(); 272*40fe15e0SLoGin sp -= sp.data() % core::mem::align_of::<T>(); 273*40fe15e0SLoGin 274*40fe15e0SLoGin unsafe { core::slice::from_raw_parts_mut(sp.data() as *mut T, slice.len()) } 275*40fe15e0SLoGin .copy_from_slice(slice); 276*40fe15e0SLoGin unsafe { 277*40fe15e0SLoGin ustack.set_sp(sp); 278*40fe15e0SLoGin } 279*40fe15e0SLoGin 280*40fe15e0SLoGin return Ok(()); 281*40fe15e0SLoGin } 282*40fe15e0SLoGin 283*40fe15e0SLoGin fn push_str(&self, ustack: &mut UserStack, s: &str) -> Result<(), SystemError> { 284*40fe15e0SLoGin self.push_slice(ustack, &[b'\0'])?; 285*40fe15e0SLoGin self.push_slice(ustack, s.as_bytes())?; 286*40fe15e0SLoGin return Ok(()); 287*40fe15e0SLoGin } 288*40fe15e0SLoGin } 289