|
| 1 | +use libc::{c_void, ucontext_t}; |
| 2 | + |
| 3 | +#[derive(Clone, Copy, Debug)] |
| 4 | +pub struct UContextPtr(*mut ucontext_t); |
| 5 | + |
| 6 | +impl UContextPtr { |
| 7 | + #[inline] |
| 8 | + pub fn new(ptr: *mut c_void) -> Self { |
| 9 | + assert!(!ptr.is_null(), "non-null context"); |
| 10 | + UContextPtr(ptr as *mut ucontext_t) |
| 11 | + } |
| 12 | + |
| 13 | + #[inline] |
| 14 | + pub fn get_ip(self) -> *const c_void { |
| 15 | + let mcontext = &unsafe { self.0.as_ref().unwrap() }.uc_mcontext; |
| 16 | + mcontext.mc_rip as *const _ |
| 17 | + } |
| 18 | + |
| 19 | + #[inline] |
| 20 | + pub fn set_ip(self, new_ip: *const c_void) { |
| 21 | + let mut mcontext = &mut unsafe { self.0.as_mut().unwrap() }.uc_mcontext; |
| 22 | + mcontext.mc_rip = new_ip as i64; |
| 23 | + } |
| 24 | + |
| 25 | + #[inline] |
| 26 | + pub fn set_rdi(self, new_rdi: u64) { |
| 27 | + let mut mcontext = &mut unsafe { self.0.as_mut().unwrap() }.uc_mcontext; |
| 28 | + mcontext.mc_rdi = new_rdi as i64; |
| 29 | + } |
| 30 | +} |
| 31 | + |
| 32 | +#[repr(C)] |
| 33 | +#[derive(Clone, Copy)] |
| 34 | +pub struct UContext { |
| 35 | + context: *mut ucontext_t, |
| 36 | +} |
| 37 | + |
| 38 | +impl UContext { |
| 39 | + #[inline] |
| 40 | + pub fn new(ptr: *mut c_void) -> Self { |
| 41 | + UContext { |
| 42 | + context: unsafe { (ptr as *mut ucontext_t).as_mut().expect("non-null context") }, |
| 43 | + } |
| 44 | + } |
| 45 | + |
| 46 | + pub fn as_ptr(&mut self) -> UContextPtr { |
| 47 | + UContextPtr::new(self.context as *mut _ as *mut _) |
| 48 | + } |
| 49 | +} |
| 50 | + |
| 51 | +impl Into<UContext> for UContextPtr { |
| 52 | + #[inline] |
| 53 | + fn into(self) -> UContext { |
| 54 | + UContext { context: self.0 } |
| 55 | + } |
| 56 | +} |
0 commit comments