xref: /DragonOS/kernel/src/process/exec.rs (revision 703ce5a77c1e4bebadc5aaa6cbb21595663d4477)
140fe15e0SLoGin use core::{fmt::Debug, ptr::null};
240fe15e0SLoGin 
3*703ce5a7SLoGin use alloc::{collections::BTreeMap, ffi::CString, string::String, sync::Arc, vec::Vec};
491e9d4abSLoGin use system_error::SystemError;
540fe15e0SLoGin 
640fe15e0SLoGin use crate::{
7b087521eSChiichen     driver::base::block::SeekFrom,
840fe15e0SLoGin     filesystem::vfs::{
940fe15e0SLoGin         file::{File, FileMode},
1040fe15e0SLoGin         ROOT_INODE,
1140fe15e0SLoGin     },
1240fe15e0SLoGin     libs::elf::ELF_LOADER,
1340fe15e0SLoGin     mm::{
1440fe15e0SLoGin         ucontext::{AddressSpace, UserStack},
1540fe15e0SLoGin         VirtAddr,
1640fe15e0SLoGin     },
1740fe15e0SLoGin };
1840fe15e0SLoGin 
19*703ce5a7SLoGin use super::ProcessManager;
20*703ce5a7SLoGin 
2140fe15e0SLoGin /// 系统支持的所有二进制文件加载器的列表
2240fe15e0SLoGin const BINARY_LOADERS: [&'static dyn BinaryLoader; 1] = [&ELF_LOADER];
2340fe15e0SLoGin 
2440fe15e0SLoGin pub trait BinaryLoader: 'static + Debug {
2540fe15e0SLoGin     /// 检查二进制文件是否为当前加载器支持的格式
probe(&'static self, param: &ExecParam, buf: &[u8]) -> Result<(), ExecError>26b5b571e0SLoGin     fn probe(&'static self, param: &ExecParam, buf: &[u8]) -> Result<(), ExecError>;
2740fe15e0SLoGin 
load( &'static self, param: &mut ExecParam, head_buf: &[u8], ) -> Result<BinaryLoaderResult, ExecError>2840fe15e0SLoGin     fn load(
29b5b571e0SLoGin         &'static self,
3040fe15e0SLoGin         param: &mut ExecParam,
3140fe15e0SLoGin         head_buf: &[u8],
3240fe15e0SLoGin     ) -> Result<BinaryLoaderResult, ExecError>;
3340fe15e0SLoGin }
3440fe15e0SLoGin 
3540fe15e0SLoGin /// 二进制文件加载结果
3640fe15e0SLoGin #[derive(Debug)]
3740fe15e0SLoGin pub struct BinaryLoaderResult {
3840fe15e0SLoGin     /// 程序入口地址
3940fe15e0SLoGin     entry_point: VirtAddr,
4040fe15e0SLoGin }
4140fe15e0SLoGin 
4240fe15e0SLoGin impl BinaryLoaderResult {
new(entry_point: VirtAddr) -> Self4340fe15e0SLoGin     pub fn new(entry_point: VirtAddr) -> Self {
4440fe15e0SLoGin         Self { entry_point }
4540fe15e0SLoGin     }
4640fe15e0SLoGin 
entry_point(&self) -> VirtAddr4740fe15e0SLoGin     pub fn entry_point(&self) -> VirtAddr {
4840fe15e0SLoGin         self.entry_point
4940fe15e0SLoGin     }
5040fe15e0SLoGin }
5140fe15e0SLoGin 
5240fe15e0SLoGin #[allow(dead_code)]
5340fe15e0SLoGin #[derive(Debug)]
5440fe15e0SLoGin pub enum ExecError {
5540fe15e0SLoGin     /// 二进制文件不可执行
5640fe15e0SLoGin     NotExecutable,
5740fe15e0SLoGin     /// 二进制文件不是当前架构的
5840fe15e0SLoGin     WrongArchitecture,
5940fe15e0SLoGin     /// 访问权限不足
6040fe15e0SLoGin     PermissionDenied,
6140fe15e0SLoGin     /// 不支持的操作
6240fe15e0SLoGin     NotSupported,
6340fe15e0SLoGin     /// 解析文件本身的时候出现错误(比如一些字段本身不合法)
6440fe15e0SLoGin     ParseError,
6540fe15e0SLoGin     /// 内存不足
6640fe15e0SLoGin     OutOfMemory,
6740fe15e0SLoGin     /// 参数错误
6840fe15e0SLoGin     InvalidParemeter,
6940fe15e0SLoGin     /// 无效的地址
7040fe15e0SLoGin     BadAddress(Option<VirtAddr>),
7140fe15e0SLoGin     Other(String),
7240fe15e0SLoGin }
73b5b571e0SLoGin impl From<ExecError> for SystemError {
from(val: ExecError) -> Self74b5b571e0SLoGin     fn from(val: ExecError) -> Self {
75b5b571e0SLoGin         match val {
7640fe15e0SLoGin             ExecError::NotExecutable => SystemError::ENOEXEC,
77b5b571e0SLoGin             ExecError::WrongArchitecture => SystemError::ENOEXEC,
7840fe15e0SLoGin             ExecError::PermissionDenied => SystemError::EACCES,
79b5b571e0SLoGin             ExecError::NotSupported => SystemError::ENOSYS,
8040fe15e0SLoGin             ExecError::ParseError => SystemError::ENOEXEC,
8140fe15e0SLoGin             ExecError::OutOfMemory => SystemError::ENOMEM,
8240fe15e0SLoGin             ExecError::InvalidParemeter => SystemError::EINVAL,
8340fe15e0SLoGin             ExecError::BadAddress(_addr) => SystemError::EFAULT,
8440fe15e0SLoGin             ExecError::Other(_msg) => SystemError::ENOEXEC,
8540fe15e0SLoGin         }
8640fe15e0SLoGin     }
8740fe15e0SLoGin }
8840fe15e0SLoGin 
8940fe15e0SLoGin bitflags! {
9040fe15e0SLoGin     pub struct ExecParamFlags: u32 {
9140fe15e0SLoGin         // 是否以可执行文件的形式加载
9240fe15e0SLoGin         const EXEC = 1 << 0;
9340fe15e0SLoGin     }
9440fe15e0SLoGin }
9540fe15e0SLoGin 
9640fe15e0SLoGin #[derive(Debug)]
97a02ce654SChiichen pub struct ExecParam {
98a02ce654SChiichen     file: File,
9940fe15e0SLoGin     vm: Arc<AddressSpace>,
10040fe15e0SLoGin     /// 一些标志位
10140fe15e0SLoGin     flags: ExecParamFlags,
10240fe15e0SLoGin     /// 用来初始化进程的一些信息。这些信息由二进制加载器和exec机制来共同填充
10340fe15e0SLoGin     init_info: ProcInitInfo,
10440fe15e0SLoGin }
10540fe15e0SLoGin 
10640fe15e0SLoGin #[derive(Debug, Eq, PartialEq)]
10740fe15e0SLoGin pub enum ExecLoadMode {
10840fe15e0SLoGin     /// 以可执行文件的形式加载
10940fe15e0SLoGin     Exec,
11040fe15e0SLoGin     /// 以动态链接库的形式加载
11140fe15e0SLoGin     DSO,
11240fe15e0SLoGin }
11340fe15e0SLoGin 
11440fe15e0SLoGin #[allow(dead_code)]
115a02ce654SChiichen impl ExecParam {
new( file_path: &str, vm: Arc<AddressSpace>, flags: ExecParamFlags, ) -> Result<Self, SystemError>116a02ce654SChiichen     pub fn new(
117a02ce654SChiichen         file_path: &str,
118a02ce654SChiichen         vm: Arc<AddressSpace>,
119a02ce654SChiichen         flags: ExecParamFlags,
120a02ce654SChiichen     ) -> Result<Self, SystemError> {
121a02ce654SChiichen         let inode = ROOT_INODE().lookup(file_path)?;
122a02ce654SChiichen 
123a02ce654SChiichen         // 读取文件头部,用于判断文件类型
124a02ce654SChiichen         let file = File::new(inode, FileMode::O_RDONLY)?;
125a02ce654SChiichen 
126a02ce654SChiichen         Ok(Self {
127a02ce654SChiichen             file,
12840fe15e0SLoGin             vm,
12940fe15e0SLoGin             flags,
130*703ce5a7SLoGin             init_info: ProcInitInfo::new(ProcessManager::current_pcb().basic().name()),
131a02ce654SChiichen         })
13240fe15e0SLoGin     }
13340fe15e0SLoGin 
vm(&self) -> &Arc<AddressSpace>13440fe15e0SLoGin     pub fn vm(&self) -> &Arc<AddressSpace> {
13540fe15e0SLoGin         &self.vm
13640fe15e0SLoGin     }
13740fe15e0SLoGin 
flags(&self) -> &ExecParamFlags13840fe15e0SLoGin     pub fn flags(&self) -> &ExecParamFlags {
13940fe15e0SLoGin         &self.flags
14040fe15e0SLoGin     }
14140fe15e0SLoGin 
init_info(&self) -> &ProcInitInfo14240fe15e0SLoGin     pub fn init_info(&self) -> &ProcInitInfo {
14340fe15e0SLoGin         &self.init_info
14440fe15e0SLoGin     }
14540fe15e0SLoGin 
init_info_mut(&mut self) -> &mut ProcInitInfo14640fe15e0SLoGin     pub fn init_info_mut(&mut self) -> &mut ProcInitInfo {
14740fe15e0SLoGin         &mut self.init_info
14840fe15e0SLoGin     }
14940fe15e0SLoGin 
15040fe15e0SLoGin     /// 获取加载模式
load_mode(&self) -> ExecLoadMode15140fe15e0SLoGin     pub fn load_mode(&self) -> ExecLoadMode {
15240fe15e0SLoGin         if self.flags.contains(ExecParamFlags::EXEC) {
15340fe15e0SLoGin             ExecLoadMode::Exec
15440fe15e0SLoGin         } else {
15540fe15e0SLoGin             ExecLoadMode::DSO
15640fe15e0SLoGin         }
15740fe15e0SLoGin     }
15840fe15e0SLoGin 
file_mut(&mut self) -> &mut File15940fe15e0SLoGin     pub fn file_mut(&mut self) -> &mut File {
160a02ce654SChiichen         &mut self.file
16140fe15e0SLoGin     }
16240fe15e0SLoGin }
16340fe15e0SLoGin 
16440fe15e0SLoGin /// ## 加载二进制文件
load_binary_file(param: &mut ExecParam) -> Result<BinaryLoaderResult, SystemError>16540fe15e0SLoGin pub fn load_binary_file(param: &mut ExecParam) -> Result<BinaryLoaderResult, SystemError> {
16640fe15e0SLoGin     // 读取文件头部,用于判断文件类型
16740fe15e0SLoGin     let mut head_buf = [0u8; 512];
16840fe15e0SLoGin     param.file_mut().lseek(SeekFrom::SeekSet(0))?;
16940fe15e0SLoGin     let _bytes = param.file_mut().read(512, &mut head_buf)?;
1702eab6dd7S曾俊     // debug!("load_binary_file: read {} bytes", _bytes);
17140fe15e0SLoGin 
17240fe15e0SLoGin     let mut loader = None;
17340fe15e0SLoGin     for bl in BINARY_LOADERS.iter() {
17440fe15e0SLoGin         let probe_result = bl.probe(param, &head_buf);
17540fe15e0SLoGin         if probe_result.is_ok() {
17640fe15e0SLoGin             loader = Some(bl);
17740fe15e0SLoGin             break;
17840fe15e0SLoGin         }
17940fe15e0SLoGin     }
1802eab6dd7S曾俊     // debug!("load_binary_file: loader: {:?}", loader);
18140fe15e0SLoGin     if loader.is_none() {
18240fe15e0SLoGin         return Err(SystemError::ENOEXEC);
18340fe15e0SLoGin     }
18440fe15e0SLoGin 
18540fe15e0SLoGin     let loader: &&dyn BinaryLoader = loader.unwrap();
18640fe15e0SLoGin     assert!(param.vm().is_current());
1872eab6dd7S曾俊     // debug!("load_binary_file: to load with param: {:?}", param);
18840fe15e0SLoGin 
18940fe15e0SLoGin     let result: BinaryLoaderResult = loader
19040fe15e0SLoGin         .load(param, &head_buf)
19140fe15e0SLoGin         .unwrap_or_else(|e| panic!("load_binary_file failed: error: {e:?}, param: {param:?}"));
19240fe15e0SLoGin 
1932eab6dd7S曾俊     // debug!("load_binary_file: load success: {result:?}");
19440fe15e0SLoGin     return Ok(result);
19540fe15e0SLoGin }
19640fe15e0SLoGin 
19740fe15e0SLoGin /// 程序初始化信息,这些信息会被压入用户栈中
19840fe15e0SLoGin #[derive(Debug)]
19940fe15e0SLoGin pub struct ProcInitInfo {
200*703ce5a7SLoGin     pub proc_name: CString,
201*703ce5a7SLoGin     pub args: Vec<CString>,
202*703ce5a7SLoGin     pub envs: Vec<CString>,
20340fe15e0SLoGin     pub auxv: BTreeMap<u8, usize>,
20440fe15e0SLoGin }
20540fe15e0SLoGin 
20640fe15e0SLoGin impl ProcInitInfo {
new(proc_name: &str) -> Self207*703ce5a7SLoGin     pub fn new(proc_name: &str) -> Self {
20840fe15e0SLoGin         Self {
209*703ce5a7SLoGin             proc_name: CString::new(proc_name).unwrap_or(CString::new("").unwrap()),
21040fe15e0SLoGin             args: Vec::new(),
21140fe15e0SLoGin             envs: Vec::new(),
21240fe15e0SLoGin             auxv: BTreeMap::new(),
21340fe15e0SLoGin         }
21440fe15e0SLoGin     }
21540fe15e0SLoGin 
21640fe15e0SLoGin     /// 把程序初始化信息压入用户栈中
21740fe15e0SLoGin     /// 这个函数会把参数、环境变量、auxv等信息压入用户栈中
21840fe15e0SLoGin     ///
21940fe15e0SLoGin     /// ## 返回值
22040fe15e0SLoGin     ///
22140fe15e0SLoGin     /// 返回值是一个元组,第一个元素是最终的用户栈顶地址,第二个元素是环境变量pointer数组的起始地址
push_at( &self, ustack: &mut UserStack, ) -> Result<(VirtAddr, VirtAddr), SystemError>22240fe15e0SLoGin     pub unsafe fn push_at(
22340fe15e0SLoGin         &self,
22440fe15e0SLoGin         ustack: &mut UserStack,
22540fe15e0SLoGin     ) -> Result<(VirtAddr, VirtAddr), SystemError> {
22640fe15e0SLoGin         // 先把程序的名称压入栈中
227865f4ba4SGnoCiYeH         self.push_str(ustack, &self.proc_name)?;
22840fe15e0SLoGin 
22940fe15e0SLoGin         // 然后把环境变量压入栈中
23040fe15e0SLoGin         let envps = self
23140fe15e0SLoGin             .envs
23240fe15e0SLoGin             .iter()
23340fe15e0SLoGin             .map(|s| {
234*703ce5a7SLoGin                 self.push_str(ustack, s).expect("push_str failed");
23540fe15e0SLoGin                 ustack.sp()
23640fe15e0SLoGin             })
23740fe15e0SLoGin             .collect::<Vec<_>>();
23840fe15e0SLoGin         // 然后把参数压入栈中
23940fe15e0SLoGin         let argps = self
24040fe15e0SLoGin             .args
24140fe15e0SLoGin             .iter()
24240fe15e0SLoGin             .map(|s| {
243*703ce5a7SLoGin                 self.push_str(ustack, s).expect("push_str failed");
24440fe15e0SLoGin                 ustack.sp()
24540fe15e0SLoGin             })
24640fe15e0SLoGin             .collect::<Vec<_>>();
24740fe15e0SLoGin 
24840fe15e0SLoGin         // 压入auxv
24940fe15e0SLoGin         self.push_slice(ustack, &[null::<u8>(), null::<u8>()])?;
25040fe15e0SLoGin         for (&k, &v) in self.auxv.iter() {
25140fe15e0SLoGin             self.push_slice(ustack, &[k as usize, v])?;
25240fe15e0SLoGin         }
25340fe15e0SLoGin 
25440fe15e0SLoGin         // 把环境变量指针压入栈中
25540fe15e0SLoGin         self.push_slice(ustack, &[null::<u8>()])?;
25640fe15e0SLoGin         self.push_slice(ustack, envps.as_slice())?;
25740fe15e0SLoGin 
25840fe15e0SLoGin         // 把参数指针压入栈中
25940fe15e0SLoGin         self.push_slice(ustack, &[null::<u8>()])?;
26040fe15e0SLoGin         self.push_slice(ustack, argps.as_slice())?;
26140fe15e0SLoGin 
26240fe15e0SLoGin         let argv_ptr = ustack.sp();
26340fe15e0SLoGin 
26440fe15e0SLoGin         // 把argc压入栈中
26540fe15e0SLoGin         self.push_slice(ustack, &[self.args.len()])?;
26640fe15e0SLoGin 
26740fe15e0SLoGin         return Ok((ustack.sp(), argv_ptr));
26840fe15e0SLoGin     }
26940fe15e0SLoGin 
push_slice<T: Copy>(&self, ustack: &mut UserStack, slice: &[T]) -> Result<(), SystemError>27040fe15e0SLoGin     fn push_slice<T: Copy>(&self, ustack: &mut UserStack, slice: &[T]) -> Result<(), SystemError> {
27140fe15e0SLoGin         let mut sp = ustack.sp();
272b5b571e0SLoGin         sp -= core::mem::size_of_val(slice);
27340fe15e0SLoGin         sp -= sp.data() % core::mem::align_of::<T>();
27440fe15e0SLoGin 
27540fe15e0SLoGin         unsafe { core::slice::from_raw_parts_mut(sp.data() as *mut T, slice.len()) }
27640fe15e0SLoGin             .copy_from_slice(slice);
27740fe15e0SLoGin         unsafe {
27840fe15e0SLoGin             ustack.set_sp(sp);
27940fe15e0SLoGin         }
28040fe15e0SLoGin 
28140fe15e0SLoGin         return Ok(());
28240fe15e0SLoGin     }
28340fe15e0SLoGin 
push_str(&self, ustack: &mut UserStack, s: &CString) -> Result<(), SystemError>284*703ce5a7SLoGin     fn push_str(&self, ustack: &mut UserStack, s: &CString) -> Result<(), SystemError> {
285*703ce5a7SLoGin         let bytes = s.as_bytes_with_nul();
286*703ce5a7SLoGin         self.push_slice(ustack, bytes)?;
28740fe15e0SLoGin         return Ok(());
28840fe15e0SLoGin     }
28940fe15e0SLoGin }
290