Add syscall process_read_memory and process_write_memory

This commit is contained in:
GCYY 2020-06-27 18:00:26 +08:00 committed by Runji Wang
parent 97217c9bf1
commit 2bcdc19c2a
3 changed files with 126 additions and 0 deletions

View File

@ -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 {

View File

@ -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 _),

View File

@ -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;