1 use alloc::sync::Arc; 2 use system_error::SystemError; 3 4 use crate::{ 5 arch::{ 6 interrupt::TrapFrame, 7 process::table::{USER_CS, USER_DS}, 8 }, 9 mm::VirtAddr, 10 process::{ 11 exec::{BinaryLoaderResult, ExecParam}, 12 ProcessControlBlock, ProcessManager, 13 }, 14 syscall::{user_access::UserBufferWriter, Syscall}, 15 }; 16 17 impl Syscall { arch_do_execve( regs: &mut TrapFrame, param: &ExecParam, load_result: &BinaryLoaderResult, user_sp: VirtAddr, argv_ptr: VirtAddr, ) -> Result<(), SystemError>18 pub fn arch_do_execve( 19 regs: &mut TrapFrame, 20 param: &ExecParam, 21 load_result: &BinaryLoaderResult, 22 user_sp: VirtAddr, 23 argv_ptr: VirtAddr, 24 ) -> Result<(), SystemError> { 25 // debug!("write proc_init_info to user stack done"); 26 27 // (兼容旧版libc)把argv的指针写到寄存器内 28 // TODO: 改写旧版libc,不再需要这个兼容 29 regs.rdi = param.init_info().args.len() as u64; 30 regs.rsi = argv_ptr.data() as u64; 31 32 // 设置系统调用返回时的寄存器状态 33 // TODO: 中断管理重构后,这里的寄存器状态设置要删掉!!!改为对trap frame的设置。要增加架构抽象。 34 regs.rsp = user_sp.data() as u64; 35 regs.rbp = user_sp.data() as u64; 36 regs.rip = load_result.entry_point().data() as u64; 37 38 regs.cs = USER_CS.bits() as u64; 39 regs.ds = USER_DS.bits() as u64; 40 regs.ss = USER_DS.bits() as u64; 41 regs.es = 0; 42 regs.rflags = 0x200; 43 regs.rax = 1; 44 45 // debug!("regs: {:?}\n", regs); 46 47 // crate::debug!( 48 // "tmp_rs_execve: done, load_result.entry_point()={:?}", 49 // load_result.entry_point() 50 // ); 51 52 return Ok(()); 53 } 54 55 /// ## 用于控制和查询与体系结构相关的进程特定选项 arch_prctl(option: usize, arg2: usize) -> Result<usize, SystemError>56 pub fn arch_prctl(option: usize, arg2: usize) -> Result<usize, SystemError> { 57 let pcb = ProcessManager::current_pcb(); 58 if let Err(SystemError::EINVAL) = Self::do_arch_prctl_64(&pcb, option, arg2, true) { 59 Self::do_arch_prctl_common(option, arg2)?; 60 } 61 Ok(0) 62 } 63 64 /// ## 64位下控制fs/gs base寄存器的方法 do_arch_prctl_64( pcb: &Arc<ProcessControlBlock>, option: usize, arg2: usize, from_user: bool, ) -> Result<usize, SystemError>65 pub fn do_arch_prctl_64( 66 pcb: &Arc<ProcessControlBlock>, 67 option: usize, 68 arg2: usize, 69 from_user: bool, 70 ) -> Result<usize, SystemError> { 71 let mut arch_info = pcb.arch_info_irqsave(); 72 match option { 73 ARCH_GET_FS => { 74 unsafe { arch_info.save_fsbase() }; 75 let mut writer = UserBufferWriter::new( 76 arg2 as *mut usize, 77 core::mem::size_of::<usize>(), 78 from_user, 79 )?; 80 writer.copy_one_to_user(&arch_info.fsbase, 0)?; 81 } 82 ARCH_GET_GS => { 83 unsafe { arch_info.save_gsbase() }; 84 let mut writer = UserBufferWriter::new( 85 arg2 as *mut usize, 86 core::mem::size_of::<usize>(), 87 from_user, 88 )?; 89 writer.copy_one_to_user(&arch_info.gsbase, 0)?; 90 } 91 ARCH_SET_FS => { 92 arch_info.fsbase = arg2; 93 // 如果是当前进程则直接写入寄存器 94 if pcb.pid() == ProcessManager::current_pcb().pid() { 95 unsafe { arch_info.restore_fsbase() } 96 } 97 } 98 ARCH_SET_GS => { 99 arch_info.gsbase = arg2; 100 if pcb.pid() == ProcessManager::current_pcb().pid() { 101 unsafe { arch_info.restore_gsbase() } 102 } 103 } 104 _ => { 105 return Err(SystemError::EINVAL); 106 } 107 } 108 Ok(0) 109 } 110 111 #[allow(dead_code)] do_arch_prctl_common(_option: usize, _arg2: usize) -> Result<usize, SystemError>112 pub fn do_arch_prctl_common(_option: usize, _arg2: usize) -> Result<usize, SystemError> { 113 todo!("do_arch_prctl_common not unimplemented"); 114 } 115 } 116 117 pub const ARCH_SET_GS: usize = 0x1001; 118 pub const ARCH_SET_FS: usize = 0x1002; 119 pub const ARCH_GET_FS: usize = 0x1003; 120 pub const ARCH_GET_GS: usize = 0x1004; 121