get/set property on Exception

This commit is contained in:
Ben Pig Chu 2020-07-10 17:52:29 +08:00
parent d496599bff
commit 6d93b0dab8
2 changed files with 75 additions and 8 deletions

View File

@ -92,7 +92,7 @@ pub struct ExceptionHeader {
#[cfg(target_arch = "x86_64")]
#[repr(C)]
#[derive(Default,Clone)]
#[derive(Default, Clone)]
pub struct ExceptionContext {
pub vector: u64,
pub err_code: u64,
@ -101,7 +101,7 @@ pub struct ExceptionContext {
#[cfg(target_arch = "aarch64")]
#[repr(C)]
#[derive(Default,Clone)]
#[derive(Default, Clone)]
pub struct ExceptionContext {
pub esr: u32,
pub padding1: u32,
@ -177,7 +177,7 @@ pub enum ExceptionChannelType {
/// and provides them with exception state and control functionality.
/// We do not send exception directly since it's hard to figure out
/// when will the handle close.
struct ExceptionObject {
pub struct ExceptionObject {
base: KObjectBase,
exception: Arc<Exception>,
close_signal: Option<oneshot::Sender<()>>,
@ -193,6 +193,9 @@ impl ExceptionObject {
close_signal: Some(close_signal),
})
}
pub fn get_exception(&self) -> &Arc<Exception> {
&self.exception
}
}
impl Drop for ExceptionObject {
@ -216,7 +219,7 @@ struct ExceptionInner {
// Task rights copied from Exceptionate
thread_rights: Rights,
process_rights: Rights,
resume: bool,
handled: bool,
second_chance: bool,
}
@ -234,7 +237,7 @@ impl Exception {
current_channel_type: ExceptionChannelType::None,
thread_rights: Rights::DEFAULT_THREAD,
process_rights: Rights::DEFAULT_PROCESS,
resume: false,
handled: false,
second_chance: false,
}),
})
@ -285,8 +288,14 @@ impl Exception {
let closed = result.unwrap();
// If this error, the sender is dropped, and the handle should also be closed.
closed.await.ok();
self.inner.lock().current_channel_type = ExceptionChannelType::None;
//TODO: check exception internal state for result
let handled={
let mut inner=self.inner.lock();
inner.current_channel_type = ExceptionChannelType::None;
inner.handled
};
if handled {
return Ok(())
}
}
Err(ZxError::NEXT)
}
@ -298,6 +307,29 @@ impl Exception {
pub fn get_report(&self) -> ExceptionReport {
self.report.clone()
}
pub fn get_state(&self) -> u32 {
self.inner.lock().handled as u32
}
pub fn set_state(&self, state: u32) {
self.inner.lock().handled = state == 1;
}
pub fn get_strategy(&self) -> u32 {
self.inner.lock().second_chance as u32
}
pub fn set_strategy(&self, strategy: u32) -> ZxResult {
let mut inner = self.inner.lock();
match inner.current_channel_type {
ExceptionChannelType::Debugger | ExceptionChannelType::JobDebugger => {
inner.second_chance = strategy == 1;
Ok(())
}
_ => Err(ZxError::BAD_STATE),
}
}
}
/// An iterator used to find Exceptionates used while handling the exception

View File

@ -79,6 +79,24 @@ impl Syscall<'_> {
info_ptr.write(content_size)?;
Ok(())
}
Property::ExceptionState => {
let mut info_ptr = UserOutPtr::<u32>::from_addr_size(buffer, buffer_size)?;
let state = proc
.get_object_with_rights::<ExceptionObject>(handle_value, Rights::GET_PROPERTY)?
.get_exception()
.get_state();
info_ptr.write(state)?;
Ok(())
}
Property::ExceptionStrategy => {
let mut info_ptr = UserOutPtr::<u32>::from_addr_size(buffer, buffer_size)?;
let state = proc
.get_object_with_rights::<ExceptionObject>(handle_value, Rights::GET_PROPERTY)?
.get_exception()
.get_strategy();
info_ptr.write(state)?;
Ok(())
}
_ => {
warn!("unknown property {:?}", property);
Err(ZxError::INVALID_ARGS)
@ -143,6 +161,20 @@ impl Syscall<'_> {
proc.get_object::<VmObject>(handle_value)?
.set_content_size(content_size)
}
Property::ExceptionState => {
let state = UserInPtr::<u32>::from_addr_size(buffer, buffer_size)?.read()?;
proc.get_object_with_rights::<ExceptionObject>(handle_value, Rights::SET_PROPERTY)?
.get_exception()
.set_state(state);
Ok(())
}
Property::ExceptionStrategy => {
let state = UserInPtr::<u32>::from_addr_size(buffer, buffer_size)?.read()?;
proc.get_object_with_rights::<ExceptionObject>(handle_value, Rights::SET_PROPERTY)?
.get_exception()
.set_strategy(state)?;
Ok(())
}
_ => {
warn!("unknown property");
Err(ZxError::INVALID_ARGS)
@ -229,7 +261,8 @@ impl Syscall<'_> {
info_ptr.write(thread.get_thread_info())?;
}
Topic::ThreadExceptionReport => {
let mut info_ptr = UserOutPtr::<ExceptionReport>::from_addr_size(buffer, buffer_size)?;
let mut info_ptr =
UserOutPtr::<ExceptionReport>::from_addr_size(buffer, buffer_size)?;
let thread = proc.get_object_with_rights::<Thread>(handle, Rights::INSPECT)?;
info_ptr.write(thread.get_thread_exception_info()?)?;
}
@ -484,7 +517,9 @@ numeric_enum! {
ProcessBreakOnLoad = 7,
SocketRxThreshold = 12,
SocketTxThreshold = 13,
ExceptionState = 16,
VmoContentSize = 17,
ExceptionStrategy = 18,
}
}