mirror of
https://github.com/asterinas/asterinas.git
synced 2025-06-24 09:53:24 +00:00
Fix InitStackReader
to access given stack instead of current task
This commit is contained in:
committed by
Tate, Hongliang Tian
parent
3ad1ea4d66
commit
f287110001
@ -20,14 +20,10 @@ use core::{
|
||||
|
||||
use align_ext::AlignExt;
|
||||
use aster_rights::Full;
|
||||
use ostd::{
|
||||
mm::{VmIo, MAX_USERSPACE_VADDR},
|
||||
task::Task,
|
||||
};
|
||||
use ostd::mm::{vm_space::VmItem, VmIo, VmSpace, MAX_USERSPACE_VADDR};
|
||||
|
||||
use self::aux_vec::{AuxKey, AuxVec};
|
||||
use crate::{
|
||||
get_current_userspace,
|
||||
prelude::*,
|
||||
util::random::getrandom,
|
||||
vm::{
|
||||
@ -187,10 +183,11 @@ impl InitStack {
|
||||
|
||||
/// Constructs a reader to parse the content of an `InitStack`.
|
||||
/// The `InitStack` should only be read after initialized
|
||||
pub(super) fn reader(&self) -> InitStackReader {
|
||||
pub(super) fn reader<'a>(&self, vm_space: &'a Arc<VmSpace>) -> InitStackReader<'a> {
|
||||
debug_assert!(self.is_initialized());
|
||||
InitStackReader {
|
||||
base: self.pos(),
|
||||
vm_space,
|
||||
map_addr: self.initial_top - self.max_size,
|
||||
}
|
||||
}
|
||||
@ -366,17 +363,27 @@ fn generate_random_for_aux_vec() -> [u8; 16] {
|
||||
}
|
||||
|
||||
/// A reader to parse the content of an `InitStack`.
|
||||
pub struct InitStackReader {
|
||||
pub struct InitStackReader<'a> {
|
||||
base: Vaddr,
|
||||
vm_space: &'a Arc<VmSpace>,
|
||||
/// The mapping address of the `InitStack`.
|
||||
map_addr: usize,
|
||||
}
|
||||
|
||||
impl InitStackReader {
|
||||
impl InitStackReader<'_> {
|
||||
/// Reads argc from the process init stack
|
||||
pub fn argc(&self) -> Result<u64> {
|
||||
let stack_base = self.init_stack_bottom();
|
||||
get_current_userspace!().read_val(stack_base)
|
||||
let page_base_addr = stack_base.align_down(PAGE_SIZE);
|
||||
|
||||
let mut cursor = self
|
||||
.vm_space
|
||||
.cursor(&(page_base_addr..page_base_addr + PAGE_SIZE))?;
|
||||
let VmItem::Mapped { frame, .. } = cursor.query()? else {
|
||||
return_errno_with_message!(Errno::EACCES, "Page not accessible");
|
||||
};
|
||||
|
||||
Ok(frame.read_val::<u64>(stack_base - page_base_addr)?)
|
||||
}
|
||||
|
||||
/// Reads argv from the process init stack
|
||||
@ -387,15 +394,20 @@ impl InitStackReader {
|
||||
let read_offset = self.init_stack_bottom() + size_of::<usize>();
|
||||
|
||||
let mut argv = Vec::with_capacity(argc);
|
||||
let page_base_addr = read_offset.align_down(PAGE_SIZE);
|
||||
let mut cursor = self
|
||||
.vm_space
|
||||
.cursor(&(page_base_addr..page_base_addr + PAGE_SIZE))?;
|
||||
let VmItem::Mapped { frame, .. } = cursor.query()? else {
|
||||
return_errno_with_message!(Errno::EACCES, "Page not accessible");
|
||||
};
|
||||
|
||||
let current_task = Task::current().unwrap();
|
||||
let user_space = CurrentUserSpace::new(¤t_task);
|
||||
|
||||
let mut argv_reader = user_space.reader(read_offset, argc * size_of::<usize>())?;
|
||||
let mut arg_ptr_reader = frame.reader().skip(read_offset - page_base_addr);
|
||||
for _ in 0..argc {
|
||||
let arg = {
|
||||
let arg_ptr = argv_reader.read_val::<Vaddr>()?;
|
||||
user_space.read_cstring(arg_ptr, MAX_ARG_LEN)?
|
||||
let arg_ptr = arg_ptr_reader.read_val::<Vaddr>()?;
|
||||
let mut arg_reader = frame.reader().skip(arg_ptr - page_base_addr).to_fallible();
|
||||
arg_reader.read_cstring()?
|
||||
};
|
||||
argv.push(arg);
|
||||
}
|
||||
@ -417,19 +429,26 @@ impl InitStackReader {
|
||||
+ size_of::<usize>();
|
||||
|
||||
let mut envp = Vec::new();
|
||||
let page_base_addr = read_offset.align_down(PAGE_SIZE);
|
||||
let mut cursor = self
|
||||
.vm_space
|
||||
.cursor(&(page_base_addr..page_base_addr + PAGE_SIZE))?;
|
||||
let VmItem::Mapped { frame, .. } = cursor.query()? else {
|
||||
return_errno_with_message!(Errno::EACCES, "Page not accessible");
|
||||
};
|
||||
|
||||
let current_task = Task::current().unwrap();
|
||||
let user_space = CurrentUserSpace::new(¤t_task);
|
||||
|
||||
let mut envp_reader = user_space.reader(read_offset, MAX_ENVP_NUMBER)?;
|
||||
let mut envp_ptr_reader = frame.reader().skip(read_offset - page_base_addr);
|
||||
for _ in 0..MAX_ENVP_NUMBER {
|
||||
let envp_ptr = envp_reader.read_val::<Vaddr>()?;
|
||||
let env = {
|
||||
let envp_ptr = envp_ptr_reader.read_val::<Vaddr>()?;
|
||||
|
||||
if envp_ptr == 0 {
|
||||
break;
|
||||
}
|
||||
if envp_ptr == 0 {
|
||||
break;
|
||||
}
|
||||
|
||||
let env = user_space.read_cstring(envp_ptr, MAX_ENV_LEN)?;
|
||||
let mut envp_reader = frame.reader().skip(envp_ptr - page_base_addr).to_fallible();
|
||||
envp_reader.read_cstring()?
|
||||
};
|
||||
envp.push(env);
|
||||
}
|
||||
|
||||
|
@ -111,7 +111,7 @@ impl ProcessVm {
|
||||
/// Returns a reader for reading contents from
|
||||
/// the `InitStack`.
|
||||
pub fn init_stack_reader(&self) -> InitStackReader {
|
||||
self.init_stack.reader()
|
||||
self.init_stack.reader(self.root_vmar().vm_space())
|
||||
}
|
||||
|
||||
/// Returns the top address of the user stack.
|
||||
|
Reference in New Issue
Block a user