forked from rcore-os/zCore
Add syscall process_read_memory and process_write_memory
This commit is contained in:
parent
97217c9bf1
commit
2bcdc19c2a
|
@ -491,6 +491,18 @@ impl VmAddressRegion {
|
|||
task_stats
|
||||
}
|
||||
|
||||
pub fn find_region(&self, vaddr: usize) -> Option<Arc<VmMapping>> {
|
||||
let guard = self.inner.lock();
|
||||
let inner = guard.as_ref().unwrap();
|
||||
if let Some(mapping) = inner.mappings.iter().find(|map| map.contains(vaddr)) {
|
||||
return Some(mapping.clone());
|
||||
}
|
||||
if let Some(child) = inner.children.iter().find(|ch| ch.contains(vaddr)) {
|
||||
return child.find_region(vaddr);
|
||||
}
|
||||
None
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
fn count(&self) -> usize {
|
||||
let mut guard = self.inner.lock();
|
||||
|
@ -785,6 +797,15 @@ impl VmMapping {
|
|||
new_vmo.append_mapping(Arc::downgrade(&mapping));
|
||||
Ok(mapping)
|
||||
}
|
||||
|
||||
pub fn vmo(&self) -> Arc<VmObject> {
|
||||
self.vmo.clone()
|
||||
}
|
||||
|
||||
pub fn inner_info(&self) -> (usize, usize, usize) {
|
||||
let inner = self.inner.lock();
|
||||
(inner.addr, inner.size, inner.vmo_offset)
|
||||
}
|
||||
}
|
||||
|
||||
impl VmMappingInner {
|
||||
|
|
|
@ -110,6 +110,12 @@ impl Syscall<'_> {
|
|||
Sys::PROCESS_START => {
|
||||
self.sys_process_start(a0 as _, a1 as _, a2 as _, a3 as _, a4 as _, a5 as _)
|
||||
}
|
||||
Sys::PROCESS_READ_MEMORY => {
|
||||
self.sys_process_read_memory(a0 as _, a1 as _, a2.into(), a3 as _, a4.into())
|
||||
}
|
||||
Sys::PROCESS_WRITE_MEMORY => {
|
||||
self.sys_process_write_memory(a0 as _, a1 as _, a2.into(), a3 as _, a4.into())
|
||||
}
|
||||
Sys::PROCESS_EXIT => self.sys_process_exit(a0 as _),
|
||||
Sys::JOB_CREATE => self.sys_job_create(a0 as _, a1 as _, a2.into()),
|
||||
Sys::JOB_SET_POLICY => self.sys_job_set_policy(a0 as _, a1 as _, a2 as _, a3, a4 as _),
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
use core::convert::TryFrom;
|
||||
use {super::*, zircon_object::task::*};
|
||||
|
||||
const MAXBLOCK: usize = 64 * 1024 * 1024; //64M
|
||||
|
||||
impl Syscall<'_> {
|
||||
pub fn sys_process_create(
|
||||
&self,
|
||||
|
@ -251,6 +253,103 @@ impl Syscall<'_> {
|
|||
_ => Err(ZxError::INVALID_ARGS),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn sys_process_read_memory(
|
||||
&self,
|
||||
handle_value: HandleValue,
|
||||
vaddr: usize,
|
||||
mut buffer: UserOutPtr<u8>,
|
||||
buffer_size: usize,
|
||||
mut actual: UserOutPtr<u32>,
|
||||
) -> ZxResult {
|
||||
if buffer.is_null() {
|
||||
return Err(ZxError::INVALID_ARGS);
|
||||
}
|
||||
if buffer_size == 0 || buffer_size > MAXBLOCK {
|
||||
return Err(ZxError::INVALID_ARGS);
|
||||
}
|
||||
|
||||
let proc = self.thread.proc();
|
||||
let process =
|
||||
proc.get_object_with_rights::<Process>(handle_value, Rights::READ | Rights::WRITE)?;
|
||||
let vmar = process.vmar();
|
||||
let vm_mapping_op = vmar.find_region(vaddr);
|
||||
if vm_mapping_op.is_none() {
|
||||
return Err(ZxError::NO_MEMORY);
|
||||
}
|
||||
let vm_mapping = vm_mapping_op.unwrap();
|
||||
let vmo = vm_mapping.vmo();
|
||||
let (mp_start, _, mp_vmo_offset) = vm_mapping.inner_info();
|
||||
let offset = vaddr - mp_start + mp_vmo_offset;
|
||||
|
||||
let mut data = vec![0u8; buffer_size];
|
||||
vmo.read(offset, &mut data)?;
|
||||
|
||||
buffer.write_array(&data)?;
|
||||
actual.write_if_not_null(data.len() as u32)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn sys_process_write_memory(
|
||||
&self,
|
||||
handle_value: HandleValue,
|
||||
vaddr: usize,
|
||||
buffer: UserInPtr<u8>,
|
||||
buffer_size: usize,
|
||||
mut actual: UserOutPtr<u32>,
|
||||
) -> ZxResult {
|
||||
// 通过 给的 handle value 找到 handle
|
||||
// adder 是 要写入 的 目的地址
|
||||
// buffer 是 用户给的 数据地址
|
||||
// size 是 大小
|
||||
|
||||
// check valid
|
||||
if buffer.is_null() {
|
||||
return Err(ZxError::INVALID_ARGS);
|
||||
}
|
||||
if buffer_size == 0 || buffer_size > MAXBLOCK {
|
||||
return Err(ZxError::INVALID_ARGS);
|
||||
}
|
||||
|
||||
// 获取 当前 进程
|
||||
let proc = self.thread.proc();
|
||||
|
||||
// 获取 object
|
||||
let process =
|
||||
proc.get_object_with_rights::<Process>(handle_value, Rights::READ | Rights::WRITE)?;
|
||||
|
||||
// 通过 process 找到 所在 vmar
|
||||
let vmar = process.vmar();
|
||||
|
||||
// 在 vmar 通过 vadder 找到 vm_mapping
|
||||
let vm_mapping_op = vmar.find_region(vaddr);
|
||||
|
||||
// 验证 mapping 合法
|
||||
if vm_mapping_op.is_none() {
|
||||
return Err(ZxError::NO_MEMORY);
|
||||
}
|
||||
|
||||
// 获得 vm_mapping
|
||||
let vm_mapping = vm_mapping_op.unwrap();
|
||||
|
||||
// 获取 vmo
|
||||
let vmo = vm_mapping.vmo();
|
||||
|
||||
// 获得 mapping inner 信息
|
||||
let (mp_start, _, mp_vmo_offset) = vm_mapping.inner_info();
|
||||
|
||||
// 求一个 offset ?
|
||||
let offset = vaddr - mp_start + mp_vmo_offset;
|
||||
|
||||
// vmo 写入 用户 的数据
|
||||
vmo.write(offset, &buffer.read_array(buffer_size)?)?;
|
||||
|
||||
// 写回 具体字节数
|
||||
actual.write_if_not_null(buffer.read_array(buffer_size)?.len() as u32)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
const JOB_POL_BASE_V1: u32 = 0;
|
||||
|
|
Loading…
Reference in New Issue