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