1#![doc = include_str!("../README.md")]
2#![no_std]
3#![deny(missing_docs)]
4#![cfg_attr(docsrs, feature(doc_cfg))]
5
6#[cfg(feature = "alloc")]
7extern crate alloc;
8
9pub mod error;
10pub mod packet_handler;
11mod raw_packet_handler;
12pub mod utils;
13
14use core::num::NonZero;
15
16pub use raw_packet_handler::{level1::IpReconstructionPattern, level2::PtwPayload};
17
18use crate::error::{DecoderError, DecoderResult};
19
20pub trait HandlePacket {
25 type Error: core::error::Error;
27
28 fn at_decode_begin(&mut self) -> Result<(), Self::Error>;
33
34 #[expect(unused)]
42 fn on_short_tnt_packet(
43 &mut self,
44 context: &DecoderContext,
45 packet_byte: NonZero<u8>,
46 highest_bit: u32,
47 ) -> Result<(), Self::Error> {
48 Ok(())
49 }
50
51 #[expect(unused)]
60 fn on_long_tnt_packet(
61 &mut self,
62 context: &DecoderContext,
63 packet_bytes: NonZero<u64>,
64 highest_bit: u32,
65 ) -> Result<(), Self::Error> {
66 Ok(())
67 }
68
69 #[expect(unused)]
71 fn on_tip_packet(
72 &mut self,
73 context: &DecoderContext,
74 ip_reconstruction_pattern: IpReconstructionPattern,
75 ) -> Result<(), Self::Error> {
76 Ok(())
77 }
78
79 #[expect(unused)]
81 fn on_tip_pgd_packet(
82 &mut self,
83 context: &DecoderContext,
84 ip_reconstruction_pattern: IpReconstructionPattern,
85 ) -> Result<(), Self::Error> {
86 Ok(())
87 }
88
89 #[expect(unused)]
91 fn on_tip_pge_packet(
92 &mut self,
93 context: &DecoderContext,
94 ip_reconstruction_pattern: IpReconstructionPattern,
95 ) -> Result<(), Self::Error> {
96 Ok(())
97 }
98
99 #[expect(unused)]
101 fn on_fup_packet(
102 &mut self,
103 context: &DecoderContext,
104 ip_reconstruction_pattern: IpReconstructionPattern,
105 ) -> Result<(), Self::Error> {
106 Ok(())
107 }
108
109 #[expect(unused)]
111 fn on_pad_packet(&mut self, context: &DecoderContext) -> Result<(), Self::Error> {
112 Ok(())
113 }
114
115 #[expect(unused)]
119 fn on_cyc_packet(
120 &mut self,
121 context: &DecoderContext,
122 cyc_packet: &[u8],
123 ) -> Result<(), Self::Error> {
124 Ok(())
125 }
126
127 #[expect(unused)]
131 fn on_mode_packet(
132 &mut self,
133 context: &DecoderContext,
134 leaf_id: u8,
135 mode: u8,
136 ) -> Result<(), Self::Error> {
137 Ok(())
138 }
139
140 #[expect(unused)]
144 fn on_mtc_packet(
145 &mut self,
146 context: &DecoderContext,
147 ctc_payload: u8,
148 ) -> Result<(), Self::Error> {
149 Ok(())
150 }
151
152 #[expect(unused)]
156 fn on_tsc_packet(
157 &mut self,
158 context: &DecoderContext,
159 tsc_value: u64,
160 ) -> Result<(), Self::Error> {
161 Ok(())
162 }
163
164 #[expect(unused)]
168 fn on_cbr_packet(
169 &mut self,
170 context: &DecoderContext,
171 core_bus_ratio: u8,
172 ) -> Result<(), Self::Error> {
173 Ok(())
174 }
175
176 #[expect(unused)]
180 fn on_tma_packet(
181 &mut self,
182 context: &DecoderContext,
183 ctc: u16,
184 fast_counter: u8,
185 fc8: bool,
186 ) -> Result<(), Self::Error> {
187 Ok(())
188 }
189
190 #[expect(unused)]
194 fn on_vmcs_packet(
195 &mut self,
196 context: &DecoderContext,
197 vmcs_pointer: u64,
198 ) -> Result<(), Self::Error> {
199 Ok(())
200 }
201
202 #[expect(unused)]
204 fn on_ovf_packet(&mut self, context: &DecoderContext) -> Result<(), Self::Error> {
205 Ok(())
206 }
207
208 #[expect(unused)]
210 fn on_psb_packet(&mut self, context: &DecoderContext) -> Result<(), Self::Error> {
211 Ok(())
212 }
213
214 #[expect(unused)]
216 fn on_psbend_packet(&mut self, context: &DecoderContext) -> Result<(), Self::Error> {
217 Ok(())
218 }
219
220 #[expect(unused)]
222 fn on_trace_stop_packet(&mut self, context: &DecoderContext) -> Result<(), Self::Error> {
223 Ok(())
224 }
225
226 #[expect(unused)]
231 fn on_pip_packet(
232 &mut self,
233 context: &DecoderContext,
234 cr3: u64,
235 rsvd_nr: bool,
236 ) -> Result<(), Self::Error> {
237 Ok(())
238 }
239
240 #[expect(unused)]
244 fn on_mnt_packet(&mut self, context: &DecoderContext, payload: u64) -> Result<(), Self::Error> {
245 Ok(())
246 }
247
248 #[expect(unused)]
252 fn on_ptw_packet(
253 &mut self,
254 context: &DecoderContext,
255 ip_bit: bool,
256 payload: PtwPayload,
257 ) -> Result<(), Self::Error> {
258 Ok(())
259 }
260
261 #[expect(unused)]
265 fn on_exstop_packet(
266 &mut self,
267 context: &DecoderContext,
268 ip_bit: bool,
269 ) -> Result<(), Self::Error> {
270 Ok(())
271 }
272
273 #[expect(unused)]
277 fn on_mwait_packet(
278 &mut self,
279 context: &DecoderContext,
280 mwait_hints: u8,
281 ext: u8,
282 ) -> Result<(), Self::Error> {
283 Ok(())
284 }
285
286 #[expect(unused)]
291 fn on_pwre_packet(
292 &mut self,
293 context: &DecoderContext,
294 hw: bool,
295 resolved_thread_c_state: u8,
296 resolved_thread_sub_c_state: u8,
297 ) -> Result<(), Self::Error> {
298 Ok(())
299 }
300
301 #[expect(unused)]
307 fn on_pwrx_packet(
308 &mut self,
309 context: &DecoderContext,
310 last_core_c_state: u8,
311 deepest_core_c_state: u8,
312 wake_reason: u8,
313 ) -> Result<(), Self::Error> {
314 Ok(())
315 }
316
317 #[expect(unused)]
321 fn on_evd_packet(
322 &mut self,
323 context: &DecoderContext,
324 r#type: u8,
325 payload: u64,
326 ) -> Result<(), Self::Error> {
327 Ok(())
328 }
329
330 #[expect(unused)]
335 fn on_cfe_packet(
336 &mut self,
337 context: &DecoderContext,
338 ip_bit: bool,
339 r#type: u8,
340 vector: u8,
341 ) -> Result<(), Self::Error> {
342 Ok(())
343 }
344
345 #[expect(unused)]
349 fn on_bbp_packet(
350 &mut self,
351 context: &DecoderContext,
352 sz_bit: bool,
353 r#type: u8,
354 ) -> Result<(), Self::Error> {
355 Ok(())
356 }
357
358 #[expect(unused)]
362 fn on_bep_packet(&mut self, context: &DecoderContext, ip_bit: bool) -> Result<(), Self::Error> {
363 Ok(())
364 }
365
366 #[expect(unused)]
372 fn on_bip_packet(
373 &mut self,
374 context: &DecoderContext,
375 id: u8,
376 payload: &[u8],
377 bbp_type: u8,
378 ) -> Result<(), Self::Error> {
379 Ok(())
380 }
381}
382
383#[derive(Clone, Copy)]
385pub enum TraceeMode {
386 Mode16 = 16,
388 Mode32 = 32,
390 Mode64 = 64,
392}
393
394impl TraceeMode {
395 #[must_use]
397 pub fn bitness(self) -> u32 {
398 self as u32
399 }
400}
401
402pub struct DecoderContext {
404 pos: usize,
406 tracee_mode: TraceeMode,
408 packet_block: Option<PacketBlockInformation>,
413}
414
415#[derive(Clone, Copy)]
417enum PacketBlockSize {
418 Dword = 4,
420 Qword = 8,
422}
423
424impl PacketBlockSize {
425 #[must_use]
427 fn from_sz_bit(sz: bool) -> Self {
428 if sz { Self::Qword } else { Self::Dword }
429 }
430
431 const fn size(self) -> usize {
433 self as usize
434 }
435}
436
437#[derive(Clone, Copy)]
439struct PacketBlockInformation {
440 size: PacketBlockSize,
442 r#type: u8,
444}
445
446impl DecoderContext {
447 #[must_use]
449 pub fn tracee_mode(&self) -> TraceeMode {
450 self.tracee_mode
451 }
452
453 #[must_use]
459 pub fn is_in_packet_blocks(&self) -> bool {
460 self.packet_block.is_some()
461 }
462}
463
464#[derive(Clone, Copy)]
468pub struct DecodeOptions {
469 tracee_mode: TraceeMode,
470 no_sync: bool,
471}
472
473impl Default for DecodeOptions {
474 fn default() -> Self {
475 Self {
476 tracee_mode: TraceeMode::Mode64,
477 no_sync: false,
478 }
479 }
480}
481
482impl DecodeOptions {
483 pub fn tracee_mode(&mut self, tracee_mode: TraceeMode) -> &mut Self {
487 self.tracee_mode = tracee_mode;
488 self
489 }
490
491 pub fn sync(&mut self, sync: bool) -> &mut Self {
496 self.no_sync = !sync;
497 self
498 }
499}
500
501const PSB_BYTES: [u8; 16] = [
502 0x02, 0x82, 0x02, 0x82, 0x02, 0x82, 0x02, 0x82, 0x02, 0x82, 0x02, 0x82, 0x02, 0x82, 0x02, 0x82,
503];
504
505pub fn decode<H: HandlePacket>(
518 buf: &[u8],
519 options: DecodeOptions,
520 packet_handler: &mut H,
521) -> DecoderResult<(), H> {
522 let DecodeOptions {
523 tracee_mode,
524 no_sync,
525 } = options;
526
527 packet_handler
528 .at_decode_begin()
529 .map_err(DecoderError::PacketHandler)?;
530
531 let start_pos = if no_sync {
532 0
533 } else {
534 let Some(start_pos) = memchr::memmem::find(buf, &PSB_BYTES) else {
535 return Err(DecoderError::NoPsb);
536 };
537 start_pos
538 };
539
540 let mut context = DecoderContext {
541 pos: start_pos,
542 tracee_mode,
543 packet_block: None,
544 };
545
546 raw_packet_handler::level1::decode(buf, &mut context, packet_handler)
547}