1 use alloc::{ffi::CString, string::String, vec::Vec}; 2 use riscv::register::sstatus::{FS, SPP}; 3 use system_error::SystemError; 4 5 use crate::{ 6 arch::{interrupt::TrapFrame, CurrentIrqArch}, 7 exception::InterruptArch, 8 mm::ucontext::AddressSpace, 9 process::{ 10 exec::{load_binary_file, ExecParam, ExecParamFlags}, 11 ProcessManager, 12 }, 13 syscall::Syscall, 14 }; 15 16 impl Syscall { 17 pub fn do_execve( 18 path: String, 19 argv: Vec<CString>, 20 envp: Vec<CString>, 21 regs: &mut TrapFrame, 22 ) -> Result<(), SystemError> { 23 // 关中断,防止在设置地址空间的时候,发生中断,然后进调度器,出现错误。 24 let irq_guard = unsafe { CurrentIrqArch::save_and_disable_irq() }; 25 let pcb = ProcessManager::current_pcb(); 26 // crate::debug!( 27 // "pid: {:?} do_execve: path: {:?}, argv: {:?}, envp: {:?}\n", 28 // pcb.pid(), 29 // path, 30 // argv, 31 // envp 32 // ); 33 34 let mut basic_info = pcb.basic_mut(); 35 // 暂存原本的用户地址空间的引用(因为如果在切换页表之前释放了它,可能会造成内存use after free) 36 let old_address_space = basic_info.user_vm(); 37 38 // 在pcb中原来的用户地址空间 39 unsafe { 40 basic_info.set_user_vm(None); 41 } 42 // 创建新的地址空间并设置为当前地址空间 43 let address_space = AddressSpace::new(true).expect("Failed to create new address space"); 44 unsafe { 45 basic_info.set_user_vm(Some(address_space.clone())); 46 } 47 48 // to avoid deadlock 49 drop(basic_info); 50 51 assert!( 52 AddressSpace::is_current(&address_space), 53 "Failed to set address space" 54 ); 55 // debug!("Switch to new address space"); 56 57 // 切换到新的用户地址空间 58 unsafe { address_space.read().user_mapper.utable.make_current() }; 59 60 drop(old_address_space); 61 drop(irq_guard); 62 // debug!("to load binary file"); 63 let mut param = ExecParam::new(path.as_str(), address_space.clone(), ExecParamFlags::EXEC)?; 64 65 // 加载可执行文件 66 let load_result = load_binary_file(&mut param)?; 67 // debug!("load binary file done"); 68 // debug!("argv: {:?}, envp: {:?}", argv, envp); 69 param.init_info_mut().args = argv; 70 param.init_info_mut().envs = envp; 71 72 // 把proc_init_info写到用户栈上 73 let mut ustack_message = unsafe { 74 address_space 75 .write() 76 .user_stack_mut() 77 .expect("No user stack found") 78 .clone_info_only() 79 }; 80 let (user_sp, argv_ptr) = unsafe { 81 param 82 .init_info() 83 .push_at( 84 // address_space 85 // .write() 86 // .user_stack_mut() 87 // .expect("No user stack found"), 88 &mut ustack_message, 89 ) 90 .expect("Failed to push proc_init_info to user stack") 91 }; 92 address_space.write().user_stack = Some(ustack_message); 93 94 // debug!("write proc_init_info to user stack done"); 95 96 regs.a0 = param.init_info().args.len(); 97 regs.a1 = argv_ptr.data(); 98 99 // 设置系统调用返回时的寄存器状态 100 regs.sp = user_sp.data(); 101 102 regs.epc = load_result.entry_point().data(); 103 regs.status.update_spp(SPP::User); 104 regs.status.update_fs(FS::Clean); 105 regs.status.update_sum(true); 106 107 drop(param); 108 109 return Ok(()); 110 } 111 112 /// ## 用于控制和查询与体系结构相关的进程特定选项 113 #[allow(dead_code)] 114 pub fn arch_prctl(_option: usize, _arg2: usize) -> Result<usize, SystemError> { 115 unimplemented!("Syscall::arch_prctl") 116 } 117 } 118