1#![no_std]
12#![deny(missing_docs)]
13extern crate alloc;
14
15mod arch;
16mod kprobe;
17mod kretprobe;
18mod manager;
19mod uprobe;
20mod uretprobe;
21
22use alloc::sync::Arc;
23use core::ops::Deref;
24
25pub use arch::*;
26pub use kprobe::*;
27pub use kretprobe::*;
28use lock_api::RawMutex;
29pub use manager::*;
30pub use uprobe::*;
31pub use uretprobe::*;
32
33use crate::arch::retprobe::RetprobeData;
34
35#[derive(Debug)]
37#[allow(missing_docs)]
38pub enum UniProbe<L: RawMutex + 'static, F: KprobeAuxiliaryOps> {
39 Kprobe(Arc<Kprobe<L, F>>),
40 Kretprobe(Arc<Kretprobe<L, F>>),
41 Uprobe(Arc<Uprobe<L, F>>),
42 Uretprobe(Arc<Uretprobe<L, F>>),
43}
44
45impl<L: RawMutex + 'static, F: KprobeAuxiliaryOps> Deref for UniProbe<L, F> {
46 type Target = Kprobe<L, F>;
47 fn deref(&self) -> &Self::Target {
48 match self {
49 UniProbe::Kprobe(kprobe) => kprobe,
50 UniProbe::Kretprobe(kretprobe) => kretprobe.kprobe(),
51 UniProbe::Uprobe(uprobe) => uprobe,
52 UniProbe::Uretprobe(uretprobe) => uretprobe.kprobe(),
53 }
54 }
55}
56
57impl<L: RawMutex + 'static, F: KprobeAuxiliaryOps> UniProbe<L, F> {
58 pub fn probe_point(&self) -> &Arc<ProbePoint<F>> {
60 match self {
61 UniProbe::Kprobe(kprobe) => kprobe.probe_point(),
62 UniProbe::Kretprobe(kretprobe) => kretprobe.kprobe().probe_point(),
63 UniProbe::Uprobe(uprobe) => uprobe.probe_point(),
64 UniProbe::Uretprobe(uretprobe) => uretprobe.kprobe().probe_point(),
65 }
66 }
67 pub fn is_kretprobe(&self) -> bool {
69 matches!(self, UniProbe::Kretprobe(_))
70 }
71}
72
73impl<L: RawMutex + 'static, F: KprobeAuxiliaryOps> Clone for UniProbe<L, F> {
74 fn clone(&self) -> Self {
75 match self {
76 UniProbe::Kprobe(kprobe) => UniProbe::Kprobe(kprobe.clone()),
77 UniProbe::Kretprobe(kretprobe) => UniProbe::Kretprobe(kretprobe.clone()),
78 UniProbe::Uprobe(uprobe) => UniProbe::Uprobe(uprobe.clone()),
79 UniProbe::Uretprobe(uretprobe) => UniProbe::Uretprobe(uretprobe.clone()),
80 }
81 }
82}
83
84pub fn register_kretprobe<L: RawMutex + 'static, F: KprobeAuxiliaryOps + 'static>(
88 manager: &mut ProbeManager<L, F>,
89 kprobe_point_list: &mut ProbePointList<F>,
90 kretprobe_builder: KretprobeBuilder<L>,
91) -> Arc<Kretprobe<L, F>> {
92 let (entry_handler, ret_handler) = kretprobe_builder.handler();
93
94 let kprobe_builder = ProbeBuilder::from(kretprobe_builder);
95 let kprobe = kprobe::__register_kprobe(kprobe_point_list, kprobe_builder);
96
97 let kretprobe = Kretprobe::new(kprobe, entry_handler, ret_handler);
98 let kretprobe = Arc::new(kretprobe);
99
100 let data = kretprobe.kprobe().get_data();
101 let data = data.as_any().downcast_ref::<RetprobeData<L, F>>().unwrap();
102 *data.retprobe.lock() = Arc::downgrade(&kretprobe);
103
104 manager.insert_probe(UniProbe::Kretprobe(kretprobe.clone()));
105 kretprobe
106}
107
108pub fn unregister_kretprobe<L: RawMutex + 'static, F: KprobeAuxiliaryOps>(
112 manager: &mut ProbeManager<L, F>,
113 kprobe_point_list: &mut ProbePointList<F>,
114 kretprobe: Arc<Kretprobe<L, F>>,
115) {
116 let kprobe = kretprobe.kprobe();
117 let kprobe_addr = kprobe.probe_point().break_address();
118 manager.remove_probe(UniProbe::Kretprobe(kretprobe));
119
120 if manager.kprobe_num(kprobe_addr) == 0 {
121 kprobe_point_list.remove(&kprobe_addr);
122 }
123}