1*1496ba7bSLoGin use alloc::{string::String, vec::Vec}; 2*1496ba7bSLoGin 3*1496ba7bSLoGin use crate::{ 4*1496ba7bSLoGin arch::{ 5*1496ba7bSLoGin interrupt::TrapFrame, 6*1496ba7bSLoGin process::table::{USER_CS, USER_DS}, 7*1496ba7bSLoGin CurrentIrqArch, 8*1496ba7bSLoGin }, 9*1496ba7bSLoGin exception::InterruptArch, 10*1496ba7bSLoGin mm::ucontext::AddressSpace, 11*1496ba7bSLoGin process::{ 12*1496ba7bSLoGin exec::{load_binary_file, ExecParam, ExecParamFlags}, 13*1496ba7bSLoGin ProcessManager, 14*1496ba7bSLoGin }, 15*1496ba7bSLoGin syscall::{Syscall, SystemError}, 16*1496ba7bSLoGin }; 17*1496ba7bSLoGin 18*1496ba7bSLoGin impl Syscall { 19*1496ba7bSLoGin pub fn do_execve( 20*1496ba7bSLoGin path: String, 21*1496ba7bSLoGin argv: Vec<String>, 22*1496ba7bSLoGin envp: Vec<String>, 23*1496ba7bSLoGin regs: &mut TrapFrame, 24*1496ba7bSLoGin ) -> Result<(), SystemError> { 25*1496ba7bSLoGin // kdebug!( 26*1496ba7bSLoGin // "tmp_rs_execve: path: {:?}, argv: {:?}, envp: {:?}\n", 27*1496ba7bSLoGin // path, 28*1496ba7bSLoGin // argv, 29*1496ba7bSLoGin // envp 30*1496ba7bSLoGin // ); 31*1496ba7bSLoGin // 关中断,防止在设置地址空间的时候,发生中断,然后进调度器,出现错误。 32*1496ba7bSLoGin let irq_guard = unsafe { CurrentIrqArch::save_and_disable_irq() }; 33*1496ba7bSLoGin let pcb = ProcessManager::current_pcb(); 34*1496ba7bSLoGin 35*1496ba7bSLoGin let mut basic_info = pcb.basic_mut(); 36*1496ba7bSLoGin // 暂存原本的用户地址空间的引用(因为如果在切换页表之前释放了它,可能会造成内存use after free) 37*1496ba7bSLoGin let old_address_space = basic_info.user_vm(); 38*1496ba7bSLoGin 39*1496ba7bSLoGin // 在pcb中原来的用户地址空间 40*1496ba7bSLoGin unsafe { 41*1496ba7bSLoGin basic_info.set_user_vm(None); 42*1496ba7bSLoGin } 43*1496ba7bSLoGin // 创建新的地址空间并设置为当前地址空间 44*1496ba7bSLoGin let address_space = AddressSpace::new(true).expect("Failed to create new address space"); 45*1496ba7bSLoGin unsafe { 46*1496ba7bSLoGin basic_info.set_user_vm(Some(address_space.clone())); 47*1496ba7bSLoGin } 48*1496ba7bSLoGin 49*1496ba7bSLoGin // to avoid deadlock 50*1496ba7bSLoGin drop(basic_info); 51*1496ba7bSLoGin 52*1496ba7bSLoGin assert!( 53*1496ba7bSLoGin AddressSpace::is_current(&address_space), 54*1496ba7bSLoGin "Failed to set address space" 55*1496ba7bSLoGin ); 56*1496ba7bSLoGin // kdebug!("Switch to new address space"); 57*1496ba7bSLoGin 58*1496ba7bSLoGin // 切换到新的用户地址空间 59*1496ba7bSLoGin unsafe { address_space.read().user_mapper.utable.make_current() }; 60*1496ba7bSLoGin 61*1496ba7bSLoGin drop(old_address_space); 62*1496ba7bSLoGin drop(irq_guard); 63*1496ba7bSLoGin // kdebug!("to load binary file"); 64*1496ba7bSLoGin let mut param = ExecParam::new(path.as_str(), address_space.clone(), ExecParamFlags::EXEC); 65*1496ba7bSLoGin 66*1496ba7bSLoGin // 加载可执行文件 67*1496ba7bSLoGin let load_result = load_binary_file(&mut param) 68*1496ba7bSLoGin .unwrap_or_else(|e| panic!("Failed to load binary file: {:?}, path: {:?}", e, path)); 69*1496ba7bSLoGin // kdebug!("load binary file done"); 70*1496ba7bSLoGin // kdebug!("argv: {:?}, envp: {:?}", argv, envp); 71*1496ba7bSLoGin param.init_info_mut().args = argv; 72*1496ba7bSLoGin param.init_info_mut().envs = envp; 73*1496ba7bSLoGin 74*1496ba7bSLoGin // 把proc_init_info写到用户栈上 75*1496ba7bSLoGin 76*1496ba7bSLoGin let (user_sp, argv_ptr) = unsafe { 77*1496ba7bSLoGin param 78*1496ba7bSLoGin .init_info() 79*1496ba7bSLoGin .push_at( 80*1496ba7bSLoGin address_space 81*1496ba7bSLoGin .write() 82*1496ba7bSLoGin .user_stack_mut() 83*1496ba7bSLoGin .expect("No user stack found"), 84*1496ba7bSLoGin ) 85*1496ba7bSLoGin .expect("Failed to push proc_init_info to user stack") 86*1496ba7bSLoGin }; 87*1496ba7bSLoGin 88*1496ba7bSLoGin // kdebug!("write proc_init_info to user stack done"); 89*1496ba7bSLoGin 90*1496ba7bSLoGin // (兼容旧版libc)把argv的指针写到寄存器内 91*1496ba7bSLoGin // TODO: 改写旧版libc,不再需要这个兼容 92*1496ba7bSLoGin regs.rdi = param.init_info().args.len() as u64; 93*1496ba7bSLoGin regs.rsi = argv_ptr.data() as u64; 94*1496ba7bSLoGin 95*1496ba7bSLoGin // 设置系统调用返回时的寄存器状态 96*1496ba7bSLoGin // TODO: 中断管理重构后,这里的寄存器状态设置要删掉!!!改为对trap frame的设置。要增加架构抽象。 97*1496ba7bSLoGin regs.rsp = user_sp.data() as u64; 98*1496ba7bSLoGin regs.rbp = user_sp.data() as u64; 99*1496ba7bSLoGin regs.rip = load_result.entry_point().data() as u64; 100*1496ba7bSLoGin 101*1496ba7bSLoGin regs.cs = USER_CS.bits() as u64; 102*1496ba7bSLoGin regs.ds = USER_DS.bits() as u64; 103*1496ba7bSLoGin regs.ss = USER_DS.bits() as u64; 104*1496ba7bSLoGin regs.es = 0; 105*1496ba7bSLoGin regs.rflags = 0x200; 106*1496ba7bSLoGin regs.rax = 1; 107*1496ba7bSLoGin 108*1496ba7bSLoGin // kdebug!("regs: {:?}\n", regs); 109*1496ba7bSLoGin 110*1496ba7bSLoGin // kdebug!( 111*1496ba7bSLoGin // "tmp_rs_execve: done, load_result.entry_point()={:?}", 112*1496ba7bSLoGin // load_result.entry_point() 113*1496ba7bSLoGin // ); 114*1496ba7bSLoGin return Ok(()); 115*1496ba7bSLoGin } 116*1496ba7bSLoGin } 117