xref: /DragonOS/kernel/src/arch/riscv64/process/syscall.rs (revision 703ce5a77c1e4bebadc5aaa6cbb21595663d4477)
1*703ce5a7SLoGin use alloc::{ffi::CString, string::String, vec::Vec};
2f75cb0f8SLoGin use riscv::register::sstatus::{FS, SPP};
391e9d4abSLoGin use system_error::SystemError;
44fda81ceSLoGin 
5471d65cfSLoGin use crate::{
6471d65cfSLoGin     arch::{interrupt::TrapFrame, CurrentIrqArch},
7471d65cfSLoGin     exception::InterruptArch,
8471d65cfSLoGin     mm::ucontext::AddressSpace,
9471d65cfSLoGin     process::{
10471d65cfSLoGin         exec::{load_binary_file, ExecParam, ExecParamFlags},
11471d65cfSLoGin         ProcessManager,
12471d65cfSLoGin     },
13471d65cfSLoGin     syscall::Syscall,
14471d65cfSLoGin };
154fda81ceSLoGin 
164fda81ceSLoGin impl Syscall {
do_execve( path: String, argv: Vec<CString>, envp: Vec<CString>, regs: &mut TrapFrame, ) -> Result<(), SystemError>174fda81ceSLoGin     pub fn do_execve(
184fda81ceSLoGin         path: String,
19*703ce5a7SLoGin         argv: Vec<CString>,
20*703ce5a7SLoGin         envp: Vec<CString>,
214fda81ceSLoGin         regs: &mut TrapFrame,
224fda81ceSLoGin     ) -> Result<(), SystemError> {
23471d65cfSLoGin         // 关中断,防止在设置地址空间的时候,发生中断,然后进调度器,出现错误。
24471d65cfSLoGin         let irq_guard = unsafe { CurrentIrqArch::save_and_disable_irq() };
25471d65cfSLoGin         let pcb = ProcessManager::current_pcb();
262eab6dd7S曾俊         // crate::debug!(
27471d65cfSLoGin         //     "pid: {:?}  do_execve: path: {:?}, argv: {:?}, envp: {:?}\n",
28471d65cfSLoGin         //     pcb.pid(),
29471d65cfSLoGin         //     path,
30471d65cfSLoGin         //     argv,
31471d65cfSLoGin         //     envp
32471d65cfSLoGin         // );
33471d65cfSLoGin 
34471d65cfSLoGin         let mut basic_info = pcb.basic_mut();
35471d65cfSLoGin         // 暂存原本的用户地址空间的引用(因为如果在切换页表之前释放了它,可能会造成内存use after free)
36471d65cfSLoGin         let old_address_space = basic_info.user_vm();
37471d65cfSLoGin 
38471d65cfSLoGin         // 在pcb中原来的用户地址空间
39471d65cfSLoGin         unsafe {
40471d65cfSLoGin             basic_info.set_user_vm(None);
41471d65cfSLoGin         }
42471d65cfSLoGin         // 创建新的地址空间并设置为当前地址空间
43471d65cfSLoGin         let address_space = AddressSpace::new(true).expect("Failed to create new address space");
44471d65cfSLoGin         unsafe {
45471d65cfSLoGin             basic_info.set_user_vm(Some(address_space.clone()));
46471d65cfSLoGin         }
47471d65cfSLoGin 
48471d65cfSLoGin         // to avoid deadlock
49471d65cfSLoGin         drop(basic_info);
50471d65cfSLoGin 
51471d65cfSLoGin         assert!(
52471d65cfSLoGin             AddressSpace::is_current(&address_space),
53471d65cfSLoGin             "Failed to set address space"
54471d65cfSLoGin         );
552eab6dd7S曾俊         // debug!("Switch to new address space");
56471d65cfSLoGin 
57471d65cfSLoGin         // 切换到新的用户地址空间
58471d65cfSLoGin         unsafe { address_space.read().user_mapper.utable.make_current() };
59471d65cfSLoGin 
60471d65cfSLoGin         drop(old_address_space);
61471d65cfSLoGin         drop(irq_guard);
622eab6dd7S曾俊         // debug!("to load binary file");
63471d65cfSLoGin         let mut param = ExecParam::new(path.as_str(), address_space.clone(), ExecParamFlags::EXEC)?;
64471d65cfSLoGin 
65471d65cfSLoGin         // 加载可执行文件
66f75cb0f8SLoGin         let load_result = load_binary_file(&mut param)?;
672eab6dd7S曾俊         // debug!("load binary file done");
682eab6dd7S曾俊         // debug!("argv: {:?}, envp: {:?}", argv, envp);
69471d65cfSLoGin         param.init_info_mut().args = argv;
70471d65cfSLoGin         param.init_info_mut().envs = envp;
71471d65cfSLoGin 
72471d65cfSLoGin         // 把proc_init_info写到用户栈上
73471d65cfSLoGin         let mut ustack_message = unsafe {
74471d65cfSLoGin             address_space
75471d65cfSLoGin                 .write()
76471d65cfSLoGin                 .user_stack_mut()
77471d65cfSLoGin                 .expect("No user stack found")
78471d65cfSLoGin                 .clone_info_only()
79471d65cfSLoGin         };
80471d65cfSLoGin         let (user_sp, argv_ptr) = unsafe {
81471d65cfSLoGin             param
82471d65cfSLoGin                 .init_info()
83471d65cfSLoGin                 .push_at(
84471d65cfSLoGin                     // address_space
85471d65cfSLoGin                     //     .write()
86471d65cfSLoGin                     //     .user_stack_mut()
87471d65cfSLoGin                     //     .expect("No user stack found"),
88471d65cfSLoGin                     &mut ustack_message,
89471d65cfSLoGin                 )
90471d65cfSLoGin                 .expect("Failed to push proc_init_info to user stack")
91471d65cfSLoGin         };
92471d65cfSLoGin         address_space.write().user_stack = Some(ustack_message);
93471d65cfSLoGin 
942eab6dd7S曾俊         // debug!("write proc_init_info to user stack done");
95471d65cfSLoGin 
96471d65cfSLoGin         regs.a0 = param.init_info().args.len();
97471d65cfSLoGin         regs.a1 = argv_ptr.data();
98471d65cfSLoGin 
99471d65cfSLoGin         // 设置系统调用返回时的寄存器状态
100471d65cfSLoGin         regs.sp = user_sp.data();
101471d65cfSLoGin 
102471d65cfSLoGin         regs.epc = load_result.entry_point().data();
103471d65cfSLoGin         regs.status.update_spp(SPP::User);
104471d65cfSLoGin         regs.status.update_fs(FS::Clean);
105471d65cfSLoGin         regs.status.update_sum(true);
106471d65cfSLoGin 
107471d65cfSLoGin         drop(param);
108471d65cfSLoGin 
109471d65cfSLoGin         return Ok(());
1104fda81ceSLoGin     }
1114fda81ceSLoGin 
1124fda81ceSLoGin     /// ## 用于控制和查询与体系结构相关的进程特定选项
113942cf26bSLoGin     #[allow(dead_code)]
arch_prctl(_option: usize, _arg2: usize) -> Result<usize, SystemError>114942cf26bSLoGin     pub fn arch_prctl(_option: usize, _arg2: usize) -> Result<usize, SystemError> {
1154fda81ceSLoGin         unimplemented!("Syscall::arch_prctl")
1164fda81ceSLoGin     }
1174fda81ceSLoGin }
118