1*fae6e9adSlinfeng use alloc::boxed::Box; 2*fae6e9adSlinfeng use alloc::string::String; 3*fae6e9adSlinfeng use kprobe::{CallBackFunc, KprobeBuilder, ProbeArgs}; 4*fae6e9adSlinfeng use log::warn; 5*fae6e9adSlinfeng use system_error::SystemError; 6*fae6e9adSlinfeng 7*fae6e9adSlinfeng pub struct KprobeInfo { 8*fae6e9adSlinfeng pub pre_handler: fn(&dyn ProbeArgs), 9*fae6e9adSlinfeng pub post_handler: fn(&dyn ProbeArgs), 10*fae6e9adSlinfeng pub fault_handler: Option<fn(&dyn ProbeArgs)>, 11*fae6e9adSlinfeng pub event_callback: Option<Box<dyn CallBackFunc>>, 12*fae6e9adSlinfeng pub symbol: Option<String>, 13*fae6e9adSlinfeng pub addr: Option<usize>, 14*fae6e9adSlinfeng pub offset: usize, 15*fae6e9adSlinfeng pub enable: bool, 16*fae6e9adSlinfeng } 17*fae6e9adSlinfeng 18*fae6e9adSlinfeng extern "C" { addr_from_symbol(symbol: *const u8) -> usize19*fae6e9adSlinfeng fn addr_from_symbol(symbol: *const u8) -> usize; 20*fae6e9adSlinfeng } 21*fae6e9adSlinfeng 22*fae6e9adSlinfeng impl TryFrom<KprobeInfo> for KprobeBuilder { 23*fae6e9adSlinfeng type Error = SystemError; try_from(kprobe_info: KprobeInfo) -> Result<Self, Self::Error>24*fae6e9adSlinfeng fn try_from(kprobe_info: KprobeInfo) -> Result<Self, Self::Error> { 25*fae6e9adSlinfeng // 检查参数: symbol和addr必须有一个但不能同时有 26*fae6e9adSlinfeng if kprobe_info.symbol.is_none() && kprobe_info.addr.is_none() { 27*fae6e9adSlinfeng return Err(SystemError::EINVAL); 28*fae6e9adSlinfeng } 29*fae6e9adSlinfeng if kprobe_info.symbol.is_some() && kprobe_info.addr.is_some() { 30*fae6e9adSlinfeng return Err(SystemError::EINVAL); 31*fae6e9adSlinfeng } 32*fae6e9adSlinfeng let func_addr = if let Some(symbol) = kprobe_info.symbol.clone() { 33*fae6e9adSlinfeng let mut symbol_sting = symbol; 34*fae6e9adSlinfeng if !symbol_sting.ends_with("\0") { 35*fae6e9adSlinfeng symbol_sting.push('\0'); 36*fae6e9adSlinfeng } 37*fae6e9adSlinfeng let symbol = symbol_sting.as_ptr(); 38*fae6e9adSlinfeng let func_addr = unsafe { addr_from_symbol(symbol) }; 39*fae6e9adSlinfeng if func_addr == 0 { 40*fae6e9adSlinfeng warn!( 41*fae6e9adSlinfeng "register_kprobe: the symbol: {:?} not found", 42*fae6e9adSlinfeng kprobe_info.symbol 43*fae6e9adSlinfeng ); 44*fae6e9adSlinfeng return Err(SystemError::ENXIO); 45*fae6e9adSlinfeng } 46*fae6e9adSlinfeng func_addr 47*fae6e9adSlinfeng } else { 48*fae6e9adSlinfeng kprobe_info.addr.unwrap() 49*fae6e9adSlinfeng }; 50*fae6e9adSlinfeng let mut builder = KprobeBuilder::new( 51*fae6e9adSlinfeng kprobe_info.symbol, 52*fae6e9adSlinfeng func_addr, 53*fae6e9adSlinfeng kprobe_info.offset, 54*fae6e9adSlinfeng kprobe_info.pre_handler, 55*fae6e9adSlinfeng kprobe_info.post_handler, 56*fae6e9adSlinfeng kprobe_info.enable, 57*fae6e9adSlinfeng ); 58*fae6e9adSlinfeng if let Some(fault_handler) = kprobe_info.fault_handler { 59*fae6e9adSlinfeng builder = builder.with_fault_handler(fault_handler); 60*fae6e9adSlinfeng } 61*fae6e9adSlinfeng if let Some(event_callback) = kprobe_info.event_callback { 62*fae6e9adSlinfeng builder = builder.with_event_callback(event_callback); 63*fae6e9adSlinfeng } 64*fae6e9adSlinfeng Ok(builder) 65*fae6e9adSlinfeng } 66*fae6e9adSlinfeng } 67