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