123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130 |
- use alloc::sync::Arc;
- use system_error::SystemError;
- use crate::{
- arch::{
- interrupt::TrapFrame,
- process::table::{USER_CS, USER_DS},
- },
- mm::VirtAddr,
- process::{
- exec::{BinaryLoaderResult, ExecParam},
- ProcessControlBlock, ProcessManager,
- },
- syscall::{user_access::UserBufferWriter, Syscall},
- };
- impl Syscall {
- pub fn arch_do_execve(
- regs: &mut TrapFrame,
- param: &ExecParam,
- load_result: &BinaryLoaderResult,
- user_sp: VirtAddr,
- argv_ptr: VirtAddr,
- ) -> Result<(), SystemError> {
- // debug!("write proc_init_info to user stack done");
- // (兼容旧版libc)把argv的指针写到寄存器内
- // TODO: 改写旧版libc,不再需要这个兼容
- regs.rdi = param.init_info().args.len() as u64;
- regs.rsi = argv_ptr.data() as u64;
- // 设置系统调用返回时的寄存器状态
- // TODO: 中断管理重构后,这里的寄存器状态设置要删掉!!!改为对trap frame的设置。要增加架构抽象。
- regs.rsp = user_sp.data() as u64;
- regs.rbp = user_sp.data() as u64;
- regs.rip = load_result.entry_point().data() as u64;
- regs.cs = USER_CS.bits() as u64;
- regs.ds = USER_DS.bits() as u64;
- regs.ss = USER_DS.bits() as u64;
- regs.es = 0;
- regs.rflags = 0x200;
- regs.rax = 1;
- // debug!("regs: {:?}\n", regs);
- // crate::debug!(
- // "tmp_rs_execve: done, load_result.entry_point()={:?}",
- // load_result.entry_point()
- // );
- return Ok(());
- }
- /// ## 用于控制和查询与体系结构相关的进程特定选项
- /// https://code.dragonos.org.cn/xref/linux-6.6.21/arch/x86/kernel/process_64.c#913
- pub fn arch_prctl(option: usize, arg2: usize) -> Result<usize, SystemError> {
- let pcb = ProcessManager::current_pcb();
- if let Err(SystemError::EINVAL) = Self::do_arch_prctl_64(&pcb, option, arg2, true) {
- Self::do_arch_prctl_common(option, arg2)?;
- }
- Ok(0)
- }
- /// ## 64位下控制fs/gs base寄存器的方法
- pub fn do_arch_prctl_64(
- pcb: &Arc<ProcessControlBlock>,
- option: usize,
- arg2: usize,
- from_user: bool,
- ) -> Result<usize, SystemError> {
- let mut arch_info = pcb.arch_info_irqsave();
- match option {
- ARCH_GET_FS => {
- unsafe { arch_info.save_fsbase() };
- let mut writer = UserBufferWriter::new(
- arg2 as *mut usize,
- core::mem::size_of::<usize>(),
- from_user,
- )?;
- writer.copy_one_to_user(&arch_info.fsbase, 0)?;
- }
- ARCH_GET_GS => {
- unsafe { arch_info.save_gsbase() };
- let mut writer = UserBufferWriter::new(
- arg2 as *mut usize,
- core::mem::size_of::<usize>(),
- from_user,
- )?;
- writer.copy_one_to_user(&arch_info.gsbase, 0)?;
- }
- ARCH_SET_FS => {
- arch_info.fsbase = arg2;
- // 如果是当前进程则直接写入寄存器
- if pcb.raw_pid() == ProcessManager::current_pcb().raw_pid() {
- unsafe { arch_info.restore_fsbase() }
- }
- }
- ARCH_SET_GS => {
- arch_info.gsbase = arg2;
- if pcb.raw_pid() == ProcessManager::current_pcb().raw_pid() {
- unsafe { arch_info.restore_gsbase() }
- }
- }
- _ => {
- return Err(SystemError::EINVAL);
- }
- }
- Ok(0)
- }
- #[allow(dead_code)]
- pub fn do_arch_prctl_common(option: usize, arg2: usize) -> Result<usize, SystemError> {
- // Don't use 0x3001-0x3004 because of old glibcs
- if (0x3001..=0x3004).contains(&option) {
- return Err(SystemError::EINVAL);
- }
- todo!(
- "do_arch_prctl_common not unimplemented, option: {}, arg2: {}",
- option,
- arg2
- );
- }
- }
- pub const ARCH_SET_GS: usize = 0x1001;
- pub const ARCH_SET_FS: usize = 0x1002;
- pub const ARCH_GET_FS: usize = 0x1003;
- pub const ARCH_GET_GS: usize = 0x1004;
|