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