exec.rs 7.9 KB

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