exec.rs 8.6 KB

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