xref: /DragonOS/kernel/src/debug/kprobe/args.rs (revision fae6e9ade46a52976ad5d099643d51cc20876448)
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