1*fae6e9adSlinfeng use alloc::boxed::Box; 2*fae6e9adSlinfeng use alloc::string::String; 3*fae6e9adSlinfeng use alloc::sync::Arc; 4*fae6e9adSlinfeng use core::{any::Any, fmt::Debug}; 5*fae6e9adSlinfeng 6*fae6e9adSlinfeng #[cfg(target_arch = "loongarch64")] 7*fae6e9adSlinfeng mod loongarch64; 8*fae6e9adSlinfeng #[cfg(target_arch = "riscv64")] 9*fae6e9adSlinfeng mod rv64; 10*fae6e9adSlinfeng #[cfg(target_arch = "x86_64")] 11*fae6e9adSlinfeng mod x86; 12*fae6e9adSlinfeng 13*fae6e9adSlinfeng #[cfg(target_arch = "loongarch64")] 14*fae6e9adSlinfeng pub use loongarch64::*; 15*fae6e9adSlinfeng #[cfg(target_arch = "riscv64")] 16*fae6e9adSlinfeng pub use rv64::*; 17*fae6e9adSlinfeng #[cfg(target_arch = "x86_64")] 18*fae6e9adSlinfeng pub use x86::*; 19*fae6e9adSlinfeng 20*fae6e9adSlinfeng #[cfg(target_arch = "x86_64")] 21*fae6e9adSlinfeng pub type KprobePoint = X86KprobePoint; 22*fae6e9adSlinfeng #[cfg(target_arch = "riscv64")] 23*fae6e9adSlinfeng pub type KprobePoint = Rv64KprobePoint; 24*fae6e9adSlinfeng #[cfg(target_arch = "loongarch64")] 25*fae6e9adSlinfeng pub type KprobePoint = LA64KprobePoint; 26*fae6e9adSlinfeng 27*fae6e9adSlinfeng pub trait ProbeArgs: Send { 28*fae6e9adSlinfeng /// 用于使用者转换到特定架构下的TrapFrame as_any(&self) -> &dyn Any29*fae6e9adSlinfeng fn as_any(&self) -> &dyn Any; 30*fae6e9adSlinfeng /// 返回导致break异常的地址 break_address(&self) -> usize31*fae6e9adSlinfeng fn break_address(&self) -> usize; 32*fae6e9adSlinfeng /// 返回导致单步执行异常的地址 debug_address(&self) -> usize33*fae6e9adSlinfeng fn debug_address(&self) -> usize; 34*fae6e9adSlinfeng } 35*fae6e9adSlinfeng 36*fae6e9adSlinfeng pub trait KprobeOps: Send { 37*fae6e9adSlinfeng /// # 返回探测点的下一条指令地址 38*fae6e9adSlinfeng /// 39*fae6e9adSlinfeng /// 执行流需要回到正常的路径中,在执行完探测点的指令后,需要返回到下一条指令 return_address(&self) -> usize40*fae6e9adSlinfeng fn return_address(&self) -> usize; 41*fae6e9adSlinfeng /// # 返回单步执行的指令地址 42*fae6e9adSlinfeng /// 43*fae6e9adSlinfeng /// 通常探测点的处的原指令被保存在一个数组当中。根据架构的不同, 在保存的指令后面,可能会填充必要的指令。 44*fae6e9adSlinfeng /// 例如x86架构下支持单步执行的特性, 而其它架构下通常没有,因此我们使用break异常来进行模拟,所以会填充 45*fae6e9adSlinfeng /// 一条断点指令。 single_step_address(&self) -> usize46*fae6e9adSlinfeng fn single_step_address(&self) -> usize; 47*fae6e9adSlinfeng /// # 返回单步执行指令触发异常的地址 48*fae6e9adSlinfeng /// 49*fae6e9adSlinfeng /// 其值等于`single_step_address`的值加上探测点指令的长度 debug_address(&self) -> usize50*fae6e9adSlinfeng fn debug_address(&self) -> usize; 51*fae6e9adSlinfeng /// # 返回设置break断点的地址 52*fae6e9adSlinfeng /// 53*fae6e9adSlinfeng /// 其值与探测点地址相等 break_address(&self) -> usize54*fae6e9adSlinfeng fn break_address(&self) -> usize; 55*fae6e9adSlinfeng } 56*fae6e9adSlinfeng 57*fae6e9adSlinfeng struct ProbeHandler { 58*fae6e9adSlinfeng func: fn(&dyn ProbeArgs), 59*fae6e9adSlinfeng } 60*fae6e9adSlinfeng 61*fae6e9adSlinfeng impl ProbeHandler { new(func: fn(&dyn ProbeArgs)) -> Self62*fae6e9adSlinfeng pub fn new(func: fn(&dyn ProbeArgs)) -> Self { 63*fae6e9adSlinfeng ProbeHandler { func } 64*fae6e9adSlinfeng } 65*fae6e9adSlinfeng /// 调用探测点处理函数 call(&self, trap_frame: &dyn ProbeArgs)66*fae6e9adSlinfeng pub fn call(&self, trap_frame: &dyn ProbeArgs) { 67*fae6e9adSlinfeng (self.func)(trap_frame); 68*fae6e9adSlinfeng } 69*fae6e9adSlinfeng } 70*fae6e9adSlinfeng 71*fae6e9adSlinfeng pub struct KprobeBuilder { 72*fae6e9adSlinfeng symbol: Option<String>, 73*fae6e9adSlinfeng symbol_addr: usize, 74*fae6e9adSlinfeng offset: usize, 75*fae6e9adSlinfeng pre_handler: ProbeHandler, 76*fae6e9adSlinfeng post_handler: ProbeHandler, 77*fae6e9adSlinfeng fault_handler: Option<ProbeHandler>, 78*fae6e9adSlinfeng event_callback: Option<Box<dyn CallBackFunc>>, 79*fae6e9adSlinfeng probe_point: Option<Arc<KprobePoint>>, 80*fae6e9adSlinfeng enable: bool, 81*fae6e9adSlinfeng } 82*fae6e9adSlinfeng 83*fae6e9adSlinfeng pub trait EventCallback: Send { call(&self, trap_frame: &dyn ProbeArgs)84*fae6e9adSlinfeng fn call(&self, trap_frame: &dyn ProbeArgs); 85*fae6e9adSlinfeng } 86*fae6e9adSlinfeng 87*fae6e9adSlinfeng impl KprobeBuilder { new( symbol: Option<String>, symbol_addr: usize, offset: usize, pre_handler: fn(&dyn ProbeArgs), post_handler: fn(&dyn ProbeArgs), enable: bool, ) -> Self88*fae6e9adSlinfeng pub fn new( 89*fae6e9adSlinfeng symbol: Option<String>, 90*fae6e9adSlinfeng symbol_addr: usize, 91*fae6e9adSlinfeng offset: usize, 92*fae6e9adSlinfeng pre_handler: fn(&dyn ProbeArgs), 93*fae6e9adSlinfeng post_handler: fn(&dyn ProbeArgs), 94*fae6e9adSlinfeng enable: bool, 95*fae6e9adSlinfeng ) -> Self { 96*fae6e9adSlinfeng KprobeBuilder { 97*fae6e9adSlinfeng symbol, 98*fae6e9adSlinfeng symbol_addr, 99*fae6e9adSlinfeng offset, 100*fae6e9adSlinfeng pre_handler: ProbeHandler::new(pre_handler), 101*fae6e9adSlinfeng post_handler: ProbeHandler::new(post_handler), 102*fae6e9adSlinfeng event_callback: None, 103*fae6e9adSlinfeng fault_handler: None, 104*fae6e9adSlinfeng probe_point: None, 105*fae6e9adSlinfeng enable, 106*fae6e9adSlinfeng } 107*fae6e9adSlinfeng } 108*fae6e9adSlinfeng with_fault_handler(mut self, func: fn(&dyn ProbeArgs)) -> Self109*fae6e9adSlinfeng pub fn with_fault_handler(mut self, func: fn(&dyn ProbeArgs)) -> Self { 110*fae6e9adSlinfeng self.fault_handler = Some(ProbeHandler::new(func)); 111*fae6e9adSlinfeng self 112*fae6e9adSlinfeng } 113*fae6e9adSlinfeng with_probe_point(mut self, point: Arc<KprobePoint>) -> Self114*fae6e9adSlinfeng pub fn with_probe_point(mut self, point: Arc<KprobePoint>) -> Self { 115*fae6e9adSlinfeng self.probe_point = Some(point); 116*fae6e9adSlinfeng self 117*fae6e9adSlinfeng } 118*fae6e9adSlinfeng with_event_callback(mut self, event_callback: Box<dyn CallBackFunc>) -> Self119*fae6e9adSlinfeng pub fn with_event_callback(mut self, event_callback: Box<dyn CallBackFunc>) -> Self { 120*fae6e9adSlinfeng self.event_callback = Some(event_callback); 121*fae6e9adSlinfeng self 122*fae6e9adSlinfeng } 123*fae6e9adSlinfeng 124*fae6e9adSlinfeng /// 获取探测点的地址 125*fae6e9adSlinfeng /// 126*fae6e9adSlinfeng /// 探测点的地址 == break指令的地址 probe_addr(&self) -> usize127*fae6e9adSlinfeng pub fn probe_addr(&self) -> usize { 128*fae6e9adSlinfeng self.symbol_addr + self.offset 129*fae6e9adSlinfeng } 130*fae6e9adSlinfeng } 131*fae6e9adSlinfeng 132*fae6e9adSlinfeng pub struct KprobeBasic { 133*fae6e9adSlinfeng symbol: Option<String>, 134*fae6e9adSlinfeng symbol_addr: usize, 135*fae6e9adSlinfeng offset: usize, 136*fae6e9adSlinfeng pre_handler: ProbeHandler, 137*fae6e9adSlinfeng post_handler: ProbeHandler, 138*fae6e9adSlinfeng fault_handler: ProbeHandler, 139*fae6e9adSlinfeng event_callback: Option<Box<dyn CallBackFunc>>, 140*fae6e9adSlinfeng enable: bool, 141*fae6e9adSlinfeng } 142*fae6e9adSlinfeng 143*fae6e9adSlinfeng pub trait CallBackFunc: Send + Sync { call(&self, trap_frame: &dyn ProbeArgs)144*fae6e9adSlinfeng fn call(&self, trap_frame: &dyn ProbeArgs); 145*fae6e9adSlinfeng } 146*fae6e9adSlinfeng 147*fae6e9adSlinfeng impl Debug for KprobeBasic { fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result148*fae6e9adSlinfeng fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { 149*fae6e9adSlinfeng f.debug_struct("Kprobe") 150*fae6e9adSlinfeng .field("symbol", &self.symbol) 151*fae6e9adSlinfeng .field("symbol_addr", &self.symbol_addr) 152*fae6e9adSlinfeng .field("offset", &self.offset) 153*fae6e9adSlinfeng .finish() 154*fae6e9adSlinfeng } 155*fae6e9adSlinfeng } 156*fae6e9adSlinfeng 157*fae6e9adSlinfeng impl KprobeBasic { call_pre_handler(&self, trap_frame: &dyn ProbeArgs)158*fae6e9adSlinfeng pub fn call_pre_handler(&self, trap_frame: &dyn ProbeArgs) { 159*fae6e9adSlinfeng self.pre_handler.call(trap_frame); 160*fae6e9adSlinfeng } 161*fae6e9adSlinfeng call_post_handler(&self, trap_frame: &dyn ProbeArgs)162*fae6e9adSlinfeng pub fn call_post_handler(&self, trap_frame: &dyn ProbeArgs) { 163*fae6e9adSlinfeng self.post_handler.call(trap_frame); 164*fae6e9adSlinfeng } 165*fae6e9adSlinfeng call_fault_handler(&self, trap_frame: &dyn ProbeArgs)166*fae6e9adSlinfeng pub fn call_fault_handler(&self, trap_frame: &dyn ProbeArgs) { 167*fae6e9adSlinfeng self.fault_handler.call(trap_frame); 168*fae6e9adSlinfeng } 169*fae6e9adSlinfeng call_event_callback(&self, trap_frame: &dyn ProbeArgs)170*fae6e9adSlinfeng pub fn call_event_callback(&self, trap_frame: &dyn ProbeArgs) { 171*fae6e9adSlinfeng if let Some(ref call_back) = self.event_callback { 172*fae6e9adSlinfeng call_back.call(trap_frame); 173*fae6e9adSlinfeng } 174*fae6e9adSlinfeng } 175*fae6e9adSlinfeng update_event_callback(&mut self, callback: Box<dyn CallBackFunc>)176*fae6e9adSlinfeng pub fn update_event_callback(&mut self, callback: Box<dyn CallBackFunc>) { 177*fae6e9adSlinfeng self.event_callback = Some(callback); 178*fae6e9adSlinfeng } 179*fae6e9adSlinfeng disable(&mut self)180*fae6e9adSlinfeng pub fn disable(&mut self) { 181*fae6e9adSlinfeng self.enable = false; 182*fae6e9adSlinfeng } 183*fae6e9adSlinfeng enable(&mut self)184*fae6e9adSlinfeng pub fn enable(&mut self) { 185*fae6e9adSlinfeng self.enable = true; 186*fae6e9adSlinfeng } 187*fae6e9adSlinfeng is_enabled(&self) -> bool188*fae6e9adSlinfeng pub fn is_enabled(&self) -> bool { 189*fae6e9adSlinfeng self.enable 190*fae6e9adSlinfeng } 191*fae6e9adSlinfeng /// 返回探测点的函数名称 symbol(&self) -> Option<&str>192*fae6e9adSlinfeng pub fn symbol(&self) -> Option<&str> { 193*fae6e9adSlinfeng self.symbol.as_deref() 194*fae6e9adSlinfeng } 195*fae6e9adSlinfeng } 196*fae6e9adSlinfeng 197*fae6e9adSlinfeng impl From<KprobeBuilder> for KprobeBasic { from(value: KprobeBuilder) -> Self198*fae6e9adSlinfeng fn from(value: KprobeBuilder) -> Self { 199*fae6e9adSlinfeng let fault_handler = value.fault_handler.unwrap_or(ProbeHandler::new(|_| {})); 200*fae6e9adSlinfeng KprobeBasic { 201*fae6e9adSlinfeng symbol: value.symbol, 202*fae6e9adSlinfeng symbol_addr: value.symbol_addr, 203*fae6e9adSlinfeng offset: value.offset, 204*fae6e9adSlinfeng pre_handler: value.pre_handler, 205*fae6e9adSlinfeng post_handler: value.post_handler, 206*fae6e9adSlinfeng event_callback: value.event_callback, 207*fae6e9adSlinfeng fault_handler, 208*fae6e9adSlinfeng enable: value.enable, 209*fae6e9adSlinfeng } 210*fae6e9adSlinfeng } 211*fae6e9adSlinfeng } 212