xref: /DragonOS/kernel/src/arch/x86_64/process/syscall.rs (revision 876cb89ecf7c1bf1646bfc392efcbafacad2262f)
11496ba7bSLoGin use alloc::{string::String, vec::Vec};
21496ba7bSLoGin 
31496ba7bSLoGin use crate::{
41496ba7bSLoGin     arch::{
51496ba7bSLoGin         interrupt::TrapFrame,
61496ba7bSLoGin         process::table::{USER_CS, USER_DS},
71496ba7bSLoGin         CurrentIrqArch,
81496ba7bSLoGin     },
91496ba7bSLoGin     exception::InterruptArch,
101496ba7bSLoGin     mm::ucontext::AddressSpace,
111496ba7bSLoGin     process::{
121496ba7bSLoGin         exec::{load_binary_file, ExecParam, ExecParamFlags},
131496ba7bSLoGin         ProcessManager,
141496ba7bSLoGin     },
151496ba7bSLoGin     syscall::{Syscall, SystemError},
161496ba7bSLoGin };
171496ba7bSLoGin 
181496ba7bSLoGin impl Syscall {
191496ba7bSLoGin     pub fn do_execve(
201496ba7bSLoGin         path: String,
211496ba7bSLoGin         argv: Vec<String>,
221496ba7bSLoGin         envp: Vec<String>,
231496ba7bSLoGin         regs: &mut TrapFrame,
241496ba7bSLoGin     ) -> Result<(), SystemError> {
251496ba7bSLoGin         // kdebug!(
261496ba7bSLoGin         //     "tmp_rs_execve: path: {:?}, argv: {:?}, envp: {:?}\n",
271496ba7bSLoGin         //     path,
281496ba7bSLoGin         //     argv,
291496ba7bSLoGin         //     envp
301496ba7bSLoGin         // );
311496ba7bSLoGin         // 关中断,防止在设置地址空间的时候,发生中断,然后进调度器,出现错误。
321496ba7bSLoGin         let irq_guard = unsafe { CurrentIrqArch::save_and_disable_irq() };
331496ba7bSLoGin         let pcb = ProcessManager::current_pcb();
341496ba7bSLoGin 
351496ba7bSLoGin         let mut basic_info = pcb.basic_mut();
361496ba7bSLoGin         // 暂存原本的用户地址空间的引用(因为如果在切换页表之前释放了它,可能会造成内存use after free)
371496ba7bSLoGin         let old_address_space = basic_info.user_vm();
381496ba7bSLoGin 
391496ba7bSLoGin         // 在pcb中原来的用户地址空间
401496ba7bSLoGin         unsafe {
411496ba7bSLoGin             basic_info.set_user_vm(None);
421496ba7bSLoGin         }
431496ba7bSLoGin         // 创建新的地址空间并设置为当前地址空间
441496ba7bSLoGin         let address_space = AddressSpace::new(true).expect("Failed to create new address space");
451496ba7bSLoGin         unsafe {
461496ba7bSLoGin             basic_info.set_user_vm(Some(address_space.clone()));
471496ba7bSLoGin         }
481496ba7bSLoGin 
491496ba7bSLoGin         // to avoid deadlock
501496ba7bSLoGin         drop(basic_info);
511496ba7bSLoGin 
521496ba7bSLoGin         assert!(
531496ba7bSLoGin             AddressSpace::is_current(&address_space),
541496ba7bSLoGin             "Failed to set address space"
551496ba7bSLoGin         );
561496ba7bSLoGin         // kdebug!("Switch to new address space");
571496ba7bSLoGin 
581496ba7bSLoGin         // 切换到新的用户地址空间
591496ba7bSLoGin         unsafe { address_space.read().user_mapper.utable.make_current() };
601496ba7bSLoGin 
611496ba7bSLoGin         drop(old_address_space);
621496ba7bSLoGin         drop(irq_guard);
631496ba7bSLoGin         // kdebug!("to load binary file");
641496ba7bSLoGin         let mut param = ExecParam::new(path.as_str(), address_space.clone(), ExecParamFlags::EXEC);
651496ba7bSLoGin 
661496ba7bSLoGin         // 加载可执行文件
671496ba7bSLoGin         let load_result = load_binary_file(&mut param)
681496ba7bSLoGin             .unwrap_or_else(|e| panic!("Failed to load binary file: {:?}, path: {:?}", e, path));
691496ba7bSLoGin         // kdebug!("load binary file done");
701496ba7bSLoGin         // kdebug!("argv: {:?}, envp: {:?}", argv, envp);
711496ba7bSLoGin         param.init_info_mut().args = argv;
721496ba7bSLoGin         param.init_info_mut().envs = envp;
731496ba7bSLoGin 
741496ba7bSLoGin         // 把proc_init_info写到用户栈上
751496ba7bSLoGin 
761496ba7bSLoGin         let (user_sp, argv_ptr) = unsafe {
771496ba7bSLoGin             param
781496ba7bSLoGin                 .init_info()
791496ba7bSLoGin                 .push_at(
801496ba7bSLoGin                     address_space
811496ba7bSLoGin                         .write()
821496ba7bSLoGin                         .user_stack_mut()
831496ba7bSLoGin                         .expect("No user stack found"),
841496ba7bSLoGin                 )
851496ba7bSLoGin                 .expect("Failed to push proc_init_info to user stack")
861496ba7bSLoGin         };
871496ba7bSLoGin 
881496ba7bSLoGin         // kdebug!("write proc_init_info to user stack done");
891496ba7bSLoGin 
901496ba7bSLoGin         // (兼容旧版libc)把argv的指针写到寄存器内
911496ba7bSLoGin         // TODO: 改写旧版libc,不再需要这个兼容
921496ba7bSLoGin         regs.rdi = param.init_info().args.len() as u64;
931496ba7bSLoGin         regs.rsi = argv_ptr.data() as u64;
941496ba7bSLoGin 
951496ba7bSLoGin         // 设置系统调用返回时的寄存器状态
961496ba7bSLoGin         // TODO: 中断管理重构后,这里的寄存器状态设置要删掉!!!改为对trap frame的设置。要增加架构抽象。
971496ba7bSLoGin         regs.rsp = user_sp.data() as u64;
981496ba7bSLoGin         regs.rbp = user_sp.data() as u64;
991496ba7bSLoGin         regs.rip = load_result.entry_point().data() as u64;
1001496ba7bSLoGin 
1011496ba7bSLoGin         regs.cs = USER_CS.bits() as u64;
1021496ba7bSLoGin         regs.ds = USER_DS.bits() as u64;
1031496ba7bSLoGin         regs.ss = USER_DS.bits() as u64;
1041496ba7bSLoGin         regs.es = 0;
1051496ba7bSLoGin         regs.rflags = 0x200;
1061496ba7bSLoGin         regs.rax = 1;
1071496ba7bSLoGin 
1081496ba7bSLoGin         // kdebug!("regs: {:?}\n", regs);
1091496ba7bSLoGin 
1101496ba7bSLoGin         // kdebug!(
1111496ba7bSLoGin         //     "tmp_rs_execve: done, load_result.entry_point()={:?}",
1121496ba7bSLoGin         //     load_result.entry_point()
1131496ba7bSLoGin         // );
114*876cb89eSGnoCiYeH 
1151496ba7bSLoGin         return Ok(());
1161496ba7bSLoGin     }
1171496ba7bSLoGin }
118