1 use alloc::{string::String, sync::Arc, vec::Vec}; 2 use system_error::SystemError; 3 4 use crate::{ 5 arch::{ 6 interrupt::TrapFrame, 7 process::table::{USER_CS, USER_DS}, 8 CurrentIrqArch, 9 }, 10 exception::InterruptArch, 11 mm::ucontext::AddressSpace, 12 process::{ 13 exec::{load_binary_file, ExecParam, ExecParamFlags}, 14 ProcessControlBlock, ProcessManager, 15 }, 16 syscall::{user_access::UserBufferWriter, Syscall}, 17 }; 18 19 impl Syscall { do_execve( path: String, argv: Vec<String>, envp: Vec<String>, regs: &mut TrapFrame, ) -> Result<(), SystemError>20 pub fn do_execve( 21 path: String, 22 argv: Vec<String>, 23 envp: Vec<String>, 24 regs: &mut TrapFrame, 25 ) -> Result<(), SystemError> { 26 // 关中断,防止在设置地址空间的时候,发生中断,然后进调度器,出现错误。 27 let irq_guard = unsafe { CurrentIrqArch::save_and_disable_irq() }; 28 let pcb = ProcessManager::current_pcb(); 29 // crate::kdebug!( 30 // "pid: {:?} do_execve: path: {:?}, argv: {:?}, envp: {:?}\n", 31 // pcb.pid(), 32 // path, 33 // argv, 34 // envp 35 // ); 36 37 let mut basic_info = pcb.basic_mut(); 38 // 暂存原本的用户地址空间的引用(因为如果在切换页表之前释放了它,可能会造成内存use after free) 39 let old_address_space = basic_info.user_vm(); 40 41 // 在pcb中原来的用户地址空间 42 unsafe { 43 basic_info.set_user_vm(None); 44 } 45 // 创建新的地址空间并设置为当前地址空间 46 let address_space = AddressSpace::new(true).expect("Failed to create new address space"); 47 unsafe { 48 basic_info.set_user_vm(Some(address_space.clone())); 49 } 50 51 // to avoid deadlock 52 drop(basic_info); 53 54 assert!( 55 AddressSpace::is_current(&address_space), 56 "Failed to set address space" 57 ); 58 // kdebug!("Switch to new address space"); 59 60 // 切换到新的用户地址空间 61 unsafe { address_space.read().user_mapper.utable.make_current() }; 62 63 drop(old_address_space); 64 drop(irq_guard); 65 // kdebug!("to load binary file"); 66 let mut param = ExecParam::new(path.as_str(), address_space.clone(), ExecParamFlags::EXEC)?; 67 68 // 加载可执行文件 69 let load_result = load_binary_file(&mut param) 70 .unwrap_or_else(|e| panic!("Failed to load binary file: {:?}, path: {:?}", e, path)); 71 // kdebug!("load binary file done"); 72 // kdebug!("argv: {:?}, envp: {:?}", argv, envp); 73 param.init_info_mut().args = argv; 74 param.init_info_mut().envs = envp; 75 76 // 把proc_init_info写到用户栈上 77 78 let (user_sp, argv_ptr) = unsafe { 79 param 80 .init_info() 81 .push_at( 82 address_space 83 .write() 84 .user_stack_mut() 85 .expect("No user stack found"), 86 ) 87 .expect("Failed to push proc_init_info to user stack") 88 }; 89 90 // kdebug!("write proc_init_info to user stack done"); 91 92 // (兼容旧版libc)把argv的指针写到寄存器内 93 // TODO: 改写旧版libc,不再需要这个兼容 94 regs.rdi = param.init_info().args.len() as u64; 95 regs.rsi = argv_ptr.data() as u64; 96 97 // 设置系统调用返回时的寄存器状态 98 // TODO: 中断管理重构后,这里的寄存器状态设置要删掉!!!改为对trap frame的设置。要增加架构抽象。 99 regs.rsp = user_sp.data() as u64; 100 regs.rbp = user_sp.data() as u64; 101 regs.rip = load_result.entry_point().data() as u64; 102 103 regs.cs = USER_CS.bits() as u64; 104 regs.ds = USER_DS.bits() as u64; 105 regs.ss = USER_DS.bits() as u64; 106 regs.es = 0; 107 regs.rflags = 0x200; 108 regs.rax = 1; 109 110 drop(param); 111 112 // kdebug!("regs: {:?}\n", regs); 113 114 // crate::kdebug!( 115 // "tmp_rs_execve: done, load_result.entry_point()={:?}", 116 // load_result.entry_point() 117 // ); 118 119 return Ok(()); 120 } 121 122 /// ## 用于控制和查询与体系结构相关的进程特定选项 arch_prctl(option: usize, arg2: usize) -> Result<usize, SystemError>123 pub fn arch_prctl(option: usize, arg2: usize) -> Result<usize, SystemError> { 124 let pcb = ProcessManager::current_pcb(); 125 if let Err(SystemError::EINVAL) = Self::do_arch_prctl_64(&pcb, option, arg2, true) { 126 Self::do_arch_prctl_common(option, arg2)?; 127 } 128 Ok(0) 129 } 130 131 /// ## 64位下控制fs/gs base寄存器的方法 do_arch_prctl_64( pcb: &Arc<ProcessControlBlock>, option: usize, arg2: usize, from_user: bool, ) -> Result<usize, SystemError>132 pub fn do_arch_prctl_64( 133 pcb: &Arc<ProcessControlBlock>, 134 option: usize, 135 arg2: usize, 136 from_user: bool, 137 ) -> Result<usize, SystemError> { 138 let mut arch_info = pcb.arch_info_irqsave(); 139 match option { 140 ARCH_GET_FS => { 141 unsafe { arch_info.save_fsbase() }; 142 let mut writer = UserBufferWriter::new( 143 arg2 as *mut usize, 144 core::mem::size_of::<usize>(), 145 from_user, 146 )?; 147 writer.copy_one_to_user(&arch_info.fsbase, 0)?; 148 } 149 ARCH_GET_GS => { 150 unsafe { arch_info.save_gsbase() }; 151 let mut writer = UserBufferWriter::new( 152 arg2 as *mut usize, 153 core::mem::size_of::<usize>(), 154 from_user, 155 )?; 156 writer.copy_one_to_user(&arch_info.gsbase, 0)?; 157 } 158 ARCH_SET_FS => { 159 arch_info.fsbase = arg2; 160 // 如果是当前进程则直接写入寄存器 161 if pcb.pid() == ProcessManager::current_pcb().pid() { 162 unsafe { arch_info.restore_fsbase() } 163 } 164 } 165 ARCH_SET_GS => { 166 arch_info.gsbase = arg2; 167 if pcb.pid() == ProcessManager::current_pcb().pid() { 168 unsafe { arch_info.restore_gsbase() } 169 } 170 } 171 _ => { 172 return Err(SystemError::EINVAL); 173 } 174 } 175 Ok(0) 176 } 177 178 #[allow(dead_code)] do_arch_prctl_common(_option: usize, _arg2: usize) -> Result<usize, SystemError>179 pub fn do_arch_prctl_common(_option: usize, _arg2: usize) -> Result<usize, SystemError> { 180 todo!("do_arch_prctl_common not unimplemented"); 181 } 182 } 183 184 pub const ARCH_SET_GS: usize = 0x1001; 185 pub const ARCH_SET_FS: usize = 0x1002; 186 pub const ARCH_GET_FS: usize = 0x1003; 187 pub const ARCH_GET_GS: usize = 0x1004; 188