From 798e695cfbee1af72099bfde6fb09f72ce321d36 Mon Sep 17 00:00:00 2001 From: Marcondiro <46560192+Marcondiro@users.noreply.github.com> Date: Fri, 22 Nov 2024 09:49:58 +0100 Subject: [PATCH 1/4] Fix windows --- Cargo.toml | 2 +- src/block/block.rs | 4 ++-- src/config/cpu.rs | 17 +++++++---------- src/event/exec_mode.rs | 13 ++++++++----- src/flags.rs | 9 ++++++--- src/insn/class.rs | 23 +++++++++++++---------- src/insn/insn.rs | 7 +++++-- src/packet/ip.rs | 42 +++++++++++++++++++++++------------------- 8 files changed, 65 insertions(+), 52 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 88a3f51..d4a84b0 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "libipt" -version = "0.2.0-rc.1" +version = "0.2.0-rc.2" authors = ["sum_catnip ", "Marcondiro"] edition = "2021" license = "MIT" diff --git a/src/block/block.rs b/src/block/block.rs index 17a1a5d..af33803 100644 --- a/src/block/block.rs +++ b/src/block/block.rs @@ -92,7 +92,7 @@ impl Block { /// The execution mode for all instructions in this block. pub fn mode(&self) -> ExecModeType { - ExecModeType::try_from(self.0.mode).unwrap() + ExecModeType::try_from(self.0.mode as u32).unwrap() } /// The instruction class for the last instruction in this block. @@ -101,7 +101,7 @@ impl Block { /// class is not available. The block decoder may choose to not provide /// the instruction class in some cases for performance reasons. pub fn class(&self) -> Class { - Class::try_from(self.0.iclass).unwrap() + Class::try_from(self.0.iclass as u32).unwrap() } /// The number of instructions in this block. diff --git a/src/config/cpu.rs b/src/config/cpu.rs index 6417466..978d90d 100644 --- a/src/config/cpu.rs +++ b/src/config/cpu.rs @@ -1,10 +1,7 @@ -use libipt_sys::{ - pt_cpu, - pt_cpu_vendor_pcv_intel, - pt_cpu_vendor_pcv_unknown, - pt_errata, - pt_cpu_errata, -}; +// Certain casts are required only on Windows. Inform Clippy to ignore them. +#![allow(clippy::unnecessary_cast)] + +use libipt_sys::{pt_cpu, pt_cpu_vendor_pcv_intel, pt_cpu_vendor_pcv_unknown, pt_errata, pt_cpu_errata, pt_cpu_vendor}; use bitflags::bitflags; @@ -43,8 +40,8 @@ mod test { bitflags! { /// i suppose this is relevant when/if amd finally gets intelpt support? pub struct CpuVendor: u32 { - const INTEL = pt_cpu_vendor_pcv_intel; - const UNKNOWN = pt_cpu_vendor_pcv_unknown; + const INTEL = pt_cpu_vendor_pcv_intel as u32; + const UNKNOWN = pt_cpu_vendor_pcv_unknown as u32; } } @@ -53,7 +50,7 @@ bitflags! { pub struct Cpu (pub(super) pt_cpu); impl Cpu { pub fn new(vendor: CpuVendor, family: u16, model: u8, stepping: u8) -> Self { - Cpu(pt_cpu{ vendor: vendor.bits(), family, model, stepping }) + Cpu(pt_cpu{ vendor: vendor.bits() as pt_cpu_vendor, family, model, stepping }) } /// A shortcut for creating an intel Cpu instance diff --git a/src/event/exec_mode.rs b/src/event/exec_mode.rs index 450c1e8..82f4628 100644 --- a/src/event/exec_mode.rs +++ b/src/event/exec_mode.rs @@ -1,3 +1,6 @@ +// Certain casts are required only on Windows. Inform Clippy to ignore them. +#![allow(clippy::unnecessary_cast)] + use std::convert::TryFrom; use libipt_sys::{ pt_event__bindgen_ty_1__bindgen_ty_8, @@ -39,10 +42,10 @@ mod test { #[derive(Clone, Copy, TryFromPrimitive, Debug, PartialEq)] #[repr(u32)] pub enum ExecModeType { - Bit16 = pt_exec_mode_ptem_16bit, - Bit32 = pt_exec_mode_ptem_32bit, - Bit64 = pt_exec_mode_ptem_64bit, - Unknown = pt_exec_mode_ptem_unknown + Bit16 = pt_exec_mode_ptem_16bit as u32, + Bit32 = pt_exec_mode_ptem_32bit as u32, + Bit64 = pt_exec_mode_ptem_64bit as u32, + Unknown = pt_exec_mode_ptem_unknown as u32 } /// An execution mode change @@ -52,5 +55,5 @@ impl ExecMode { /// The address at which the event is effective pub fn ip(self) -> u64 { self.0.ip } /// The execution mode - pub fn mode(self) -> ExecModeType { ExecModeType::try_from(self.0.mode).unwrap() } + pub fn mode(self) -> ExecModeType { ExecModeType::try_from(self.0.mode as u32).unwrap() } } \ No newline at end of file diff --git a/src/flags.rs b/src/flags.rs index 7597697..2cbc321 100644 --- a/src/flags.rs +++ b/src/flags.rs @@ -1,3 +1,6 @@ +// Certain casts are required only on Windows. Inform Clippy to ignore them. +#![allow(clippy::unnecessary_cast)] + use libipt_sys::{ pt_status_flag_pts_eos, pt_status_flag_pts_event_pending, @@ -9,11 +12,11 @@ bitflags! { /// Status flags for various IntelPT actions pub struct Status: u32 { /// There is no more trace data available. - const EOS = pt_status_flag_pts_eos; + const EOS = pt_status_flag_pts_eos as u32; /// There is an event pending. - const EVENT_PENDING = pt_status_flag_pts_event_pending; + const EVENT_PENDING = pt_status_flag_pts_event_pending as u32; /// The address has been suppressed. - const IP_SUPRESSED = pt_status_flag_pts_ip_suppressed; + const IP_SUPRESSED = pt_status_flag_pts_ip_suppressed as u32; } } diff --git a/src/insn/class.rs b/src/insn/class.rs index 9da7291..fd2f072 100644 --- a/src/insn/class.rs +++ b/src/insn/class.rs @@ -1,3 +1,6 @@ +// Certain casts are required only on Windows. Inform Clippy to ignore them. +#![allow(clippy::unnecessary_cast)] + use num_enum::TryFromPrimitive; use libipt_sys::{ pt_insn_class_ptic_call, @@ -20,26 +23,26 @@ use libipt_sys::{ #[repr(u32)] pub enum Class { /// The instruction is a near (function) call. - Call = pt_insn_class_ptic_call, + Call = pt_insn_class_ptic_call as u32, /// The instruction is a near conditional jump. - CondJump = pt_insn_class_ptic_cond_jump, + CondJump = pt_insn_class_ptic_cond_jump as u32, /// The instruction could not be classified. - Error = pt_insn_class_ptic_error, + Error = pt_insn_class_ptic_error as u32, /// The instruction is a call-like far transfer. /// E.g. SYSCALL, SYSENTER, or FAR CALL. - FarCall = pt_insn_class_ptic_far_call, + FarCall = pt_insn_class_ptic_far_call as u32, /// The instruction is a jump-like far transfer. /// E.g. FAR JMP. - FarJump = pt_insn_class_ptic_far_jump, + FarJump = pt_insn_class_ptic_far_jump as u32, /// The instruction is a return-like far transfer. /// E.g. SYSRET, SYSEXIT, IRET, or FAR RET. - FarReturn = pt_insn_class_ptic_far_return, + FarReturn = pt_insn_class_ptic_far_return as u32, /// The instruction is a near unconditional jump. - Jump = pt_insn_class_ptic_jump, + Jump = pt_insn_class_ptic_jump as u32, /// The instruction is something not listed below. - Other = pt_insn_class_ptic_other, + Other = pt_insn_class_ptic_other as u32, /// The instruction is a PTWRITE. - Ptwrite = pt_insn_class_ptic_ptwrite, + Ptwrite = pt_insn_class_ptic_ptwrite as u32, /// The instruction is a near (function) return. - Return = pt_insn_class_ptic_return + Return = pt_insn_class_ptic_return as u32, } \ No newline at end of file diff --git a/src/insn/insn.rs b/src/insn/insn.rs index 877fd8a..c226437 100644 --- a/src/insn/insn.rs +++ b/src/insn/insn.rs @@ -1,3 +1,6 @@ +// Certain casts are required only on Windows. Inform Clippy to ignore them. +#![allow(clippy::unnecessary_cast)] + use crate::event::ExecModeType; use super::Class; @@ -50,14 +53,14 @@ impl Insn { /// The execution mode. pub fn mode(self) -> ExecModeType { - ExecModeType::try_from(self.0.mode) + ExecModeType::try_from(self.0.mode as u32) .expect(concat!("unmatched ExecModeType enum value, ", "this is a bug in either libipt or the bindings")) } /// A coarse classification. pub fn class(self) -> Class { - Class::try_from(self.0.iclass) + Class::try_from(self.0.iclass as u32) .expect(concat!("unmatched Class enum value, ", "this is a bug in either libipt or the bindings")) } diff --git a/src/packet/ip.rs b/src/packet/ip.rs index 63fe12d..6ac462d 100644 --- a/src/packet/ip.rs +++ b/src/packet/ip.rs @@ -1,3 +1,6 @@ +// Certain casts are required only on Windows. Inform Clippy to ignore them. +#![allow(clippy::unnecessary_cast)] + use std::convert::TryFrom; use num_enum::{TryFromPrimitive, IntoPrimitive}; use libipt_sys::{ @@ -6,12 +9,13 @@ use libipt_sys::{ pt_packet_type_ppt_fup, pt_packet_type_ppt_tip_pge, pt_packet_type_ppt_tip_pgd, + pt_ip_compression, pt_ip_compression_pt_ipc_full, pt_ip_compression_pt_ipc_sext_48, pt_ip_compression_pt_ipc_suppressed, pt_ip_compression_pt_ipc_update_16, pt_ip_compression_pt_ipc_update_32, - pt_ip_compression_pt_ipc_update_48 + pt_ip_compression_pt_ipc_update_48, }; /// The IP compression @@ -19,22 +23,22 @@ use libipt_sys::{ #[repr(u32)] pub enum Compression { /// No payload. The IP has been suppressed - Suppressed = pt_ip_compression_pt_ipc_suppressed, + Suppressed = pt_ip_compression_pt_ipc_suppressed as u32, /// Payload: 16 bits. Update last IP - Update16 = pt_ip_compression_pt_ipc_update_16, + Update16 = pt_ip_compression_pt_ipc_update_16 as u32, /// Payload: 32 bits. Update last IP - Update32 = pt_ip_compression_pt_ipc_update_32, + Update32 = pt_ip_compression_pt_ipc_update_32 as u32, /// Payload: 48 bits. Sign extend to full address - Sext48 = pt_ip_compression_pt_ipc_sext_48, + Sext48 = pt_ip_compression_pt_ipc_sext_48 as u32, /// Payload: 48 bits. Update last IP - Update48 = pt_ip_compression_pt_ipc_update_48, + Update48 = pt_ip_compression_pt_ipc_update_48 as u32, /// Payload: 64 bits. Full address - Full = pt_ip_compression_pt_ipc_full + Full = pt_ip_compression_pt_ipc_full as u32, } /// A packet with IP payload. @@ -44,7 +48,7 @@ pub struct Tip (pt_packet_ip); impl Tip { #[inline] pub fn new(tip: u64, compression: Compression) -> Self { - Tip (pt_packet_ip { ip: tip, ipc: compression.into() }) + Tip (pt_packet_ip { ip: tip, ipc: u32::from(compression) as pt_ip_compression }) } /// Zero-extended payload ip @@ -59,13 +63,13 @@ impl Tip { pub fn compression(self) -> Compression { // if this tryfrom panics, there is a bug // in either libipt or this crate. - Compression::try_from(self.0.ipc).unwrap() + Compression::try_from(self.0.ipc as u32).unwrap() } /// IP compression #[inline] pub fn set_compression(&mut self, compression: Compression) { - self.0.ipc = compression.into() + self.0.ipc = u32::from(compression) as pt_ip_compression } } @@ -76,7 +80,7 @@ pub struct Fup (pt_packet_ip); impl Fup { #[inline] pub fn new(fup: u64, compression: Compression) -> Self { - Fup (pt_packet_ip { ip: fup, ipc: compression.into() }) + Fup (pt_packet_ip { ip: fup, ipc: u32::from(compression) as pt_ip_compression }) } /// Zero-extended payload ip @@ -91,13 +95,13 @@ impl Fup { pub fn compression(self) -> Compression { // if this tryfrom panics, there is a bug // in either libipt or this crate. - Compression::try_from(self.0.ipc).unwrap() + Compression::try_from(self.0.ipc as u32).unwrap() } /// IP compression #[inline] pub fn set_compression(&mut self, compression: Compression) { - self.0.ipc = compression.into() + self.0.ipc = u32::from(compression) as pt_ip_compression; } } @@ -108,7 +112,7 @@ pub struct TipPge (pt_packet_ip); impl TipPge { #[inline] pub fn new(tippge: u64, compression: Compression) -> Self { - TipPge (pt_packet_ip { ip: tippge, ipc: compression.into() }) + TipPge (pt_packet_ip { ip: tippge, ipc: u32::from(compression) as pt_ip_compression }) } /// Zero-extended payload ip @@ -123,13 +127,13 @@ impl TipPge { pub fn compression(self) -> Compression { // if this tryfrom panics, there is a bug // in either libipt or this crate. - Compression::try_from(self.0.ipc).unwrap() + Compression::try_from(self.0.ipc as u32).unwrap() } /// IP compression #[inline] pub fn set_compression(&mut self, compression: Compression) { - self.0.ipc = compression.into() + self.0.ipc = u32::from(compression) as pt_ip_compression } } @@ -140,7 +144,7 @@ pub struct TipPgd (pt_packet_ip); impl TipPgd { #[inline] pub fn new(tippgd: u64, compression: Compression) -> Self { - TipPgd (pt_packet_ip { ip: tippgd, ipc: compression.into() }) + TipPgd (pt_packet_ip { ip: tippgd, ipc: u32::from(compression) as pt_ip_compression }) } /// Zero-extended payload ip @@ -155,13 +159,13 @@ impl TipPgd { pub fn compression(self) -> Compression { // if this tryfrom panics, there is a bug // in either libipt or this crate. - Compression::try_from(self.0.ipc).unwrap() + Compression::try_from(self.0.ipc as u32).unwrap() } /// IP compression #[inline] pub fn set_compression(&mut self, compression: Compression) { - self.0.ipc = compression.into() + self.0.ipc = u32::from(compression) as pt_ip_compression } } From 67e963d0e7dcc29b0aedef620862ff418ac48885 Mon Sep 17 00:00:00 2001 From: Marcondiro <46560192+Marcondiro@users.noreply.github.com> Date: Fri, 22 Nov 2024 09:52:01 +0100 Subject: [PATCH 2/4] Cargo fmt --- Cargo.toml | 2 - src/asid.rs | 26 +++-- src/block/block.rs | 77 +++++++------- src/block/mod.rs | 2 +- src/config/config.rs | 187 +++++++++++++++++++--------------- src/config/cpu.rs | 24 +++-- src/config/filter.rs | 81 ++++++++++----- src/config/flags.rs | 42 +++++--- src/config/freqency.rs | 38 +++++-- src/config/mod.rs | 8 +- src/error.rs | 67 +++++------- src/event/branch.rs | 23 +++-- src/event/cbr.rs | 18 ++-- src/event/disabled.rs | 45 ++++---- src/event/enabled.rs | 20 ++-- src/event/exec_mode.rs | 31 +++--- src/event/exstop.rs | 18 ++-- src/event/mnt.rs | 18 ++-- src/event/mod.rs | 59 +++++++---- src/event/mwait.rs | 24 +++-- src/event/overflow.rs | 20 ++-- src/event/paging.rs | 45 ++++---- src/event/ptwrite.rs | 24 +++-- src/event/pwre.rs | 28 +++-- src/event/pwrx.rs | 32 ++++-- src/event/qry.rs | 86 ++++++---------- src/event/tick.rs | 18 ++-- src/event/tsx.rs | 24 +++-- src/event/vmcs.rs | 46 ++++----- src/flags.rs | 20 ++-- src/image/iscache.rs | 126 +++++++++++------------ src/image/mod.rs | 2 +- src/insn/class.rs | 18 ++-- src/insn/decoder.rs | 112 +++++++------------- src/insn/insn.rs | 58 ++++++----- src/insn/mod.rs | 2 +- src/lib.rs | 2 +- src/packet/cbr.rs | 14 ++- src/packet/conversions.rs | 8 +- src/packet/cyc.rs | 14 ++- src/packet/decoder.rs | 55 ++++------ src/packet/encoder.rs | 41 +++----- src/packet/exstop.rs | 22 ++-- src/packet/invalid.rs | 4 +- src/packet/ip.rs | 89 +++++++++------- src/packet/mnt.rs | 14 ++- src/packet/mod.rs | 23 +++-- src/packet/mtc.rs | 14 ++- src/packet/mwait.rs | 22 ++-- src/packet/ovf.rs | 12 ++- src/packet/pad.rs | 12 ++- src/packet/pip.rs | 26 +++-- src/packet/psb.rs | 12 ++- src/packet/psbend.rs | 12 ++- src/packet/ptw.rs | 37 ++++--- src/packet/pwre.rs | 41 +++++--- src/packet/pwrx.rs | 41 +++++--- src/packet/stop.rs | 12 ++- src/packet/tma.rs | 22 ++-- src/packet/tnt.rs | 44 +++++--- src/packet/tsc.rs | 14 ++- src/packet/unknown.rs | 12 +-- src/packet/vmcs.rs | 18 ++-- src/version.rs | 33 +++--- tests/integration_encoding.rs | 10 +- 65 files changed, 1181 insertions(+), 970 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index d4a84b0..eb38254 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -7,8 +7,6 @@ license = "MIT" description = "The Intel Processor Trace (Intel PT) Decoder Library is Intel's reference implementation for decoding Intel PT." repository = "https://github.com/sum-catnip/libipt-rs" -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html - [dependencies] libipt-sys = "0.2.0-rc.1" bitflags = "2.4.1" diff --git a/src/asid.rs b/src/asid.rs index dcbd033..6d42a91 100644 --- a/src/asid.rs +++ b/src/asid.rs @@ -87,30 +87,44 @@ impl Asid { /// The CR3 value. #[inline] pub fn cr3(self) -> Option { - match self.0.cr3 { NO_CR3 => None, x => Some(x) } + match self.0.cr3 { + NO_CR3 => None, + x => Some(x), + } } /// The CR3 value. #[inline] - pub fn set_cr3(&mut self, cr3: u64) { self.0.cr3 = cr3 } + pub fn set_cr3(&mut self, cr3: u64) { + self.0.cr3 = cr3 + } /// The VMCS Base address. #[inline] pub fn vmcs(self) -> Option { - match self.0.vmcs { NO_VMCS => None, x => Some(x) } + match self.0.vmcs { + NO_VMCS => None, + x => Some(x), + } } /// The VMCS Base address. #[inline] - pub fn set_vmcs(&mut self, vmcs: u64) { self.0.vmcs = vmcs } + pub fn set_vmcs(&mut self, vmcs: u64) { + self.0.vmcs = vmcs + } } impl Default for Asid { - fn default() -> Self { Asid::new(None, None) } + fn default() -> Self { + Asid::new(None, None) + } } impl From for Asid { - fn from(asid: pt_asid) -> Self { Asid(asid) } + fn from(asid: pt_asid) -> Self { + Asid(asid) + } } impl PartialEq for Asid { diff --git a/src/block/block.rs b/src/block/block.rs index af33803..5116377 100644 --- a/src/block/block.rs +++ b/src/block/block.rs @@ -1,15 +1,12 @@ -use crate::insn::Class; use crate::event::ExecModeType; -use std::convert::TryFrom; +use crate::insn::Class; use libipt_sys::pt_block; +use std::convert::TryFrom; #[cfg(test)] mod test { use super::*; - use libipt_sys::{ - pt_exec_mode_ptem_32bit, - pt_insn_class_ptic_error, - }; + use libipt_sys::{pt_exec_mode_ptem_32bit, pt_insn_class_ptic_error}; #[test] fn test_block_props() { @@ -25,18 +22,18 @@ mod test { size: 8, _bitfield_align_1: [], _bitfield_1: pt_block::new_bitfield_1(0, 1), - __bindgen_padding_0: Default::default() - }); + __bindgen_padding_0: Default::default(), + }); - assert_eq!(blk.ip(), 1); - assert_eq!(blk.end_ip(), 2); - assert_eq!(blk.isid(), 3); - assert_eq!(blk.mode(), ExecModeType::Bit32); - assert_eq!(blk.class(), Class::Error); - assert_eq!(blk.ninsn(), 4); - assert_eq!(blk.raw(), &data[..8]); - assert!(blk.truncated()); - assert!(!blk.speculative()); + assert_eq!(blk.ip(), 1); + assert_eq!(blk.end_ip(), 2); + assert_eq!(blk.isid(), 3); + assert_eq!(blk.mode(), ExecModeType::Bit32); + assert_eq!(blk.class(), Class::Error); + assert_eq!(blk.ninsn(), 4); + assert_eq!(blk.raw(), &data[..8]); + assert!(blk.truncated()); + assert!(!blk.speculative()); } #[test] @@ -53,18 +50,18 @@ mod test { size: 8, _bitfield_align_1: [], _bitfield_1: pt_block::new_bitfield_1(0, 0), - __bindgen_padding_0: Default::default() - }); + __bindgen_padding_0: Default::default(), + }); - assert_eq!(blk.ip(), 1); - assert_eq!(blk.end_ip(), 2); - assert_eq!(blk.isid(), 3); - assert_eq!(blk.mode(), ExecModeType::Bit32); - assert_eq!(blk.class(), Class::Error); - assert_eq!(blk.ninsn(), 4); - assert!(blk.raw().len() > 0); - assert!(!blk.truncated()); - assert!(!blk.speculative()); + assert_eq!(blk.ip(), 1); + assert_eq!(blk.end_ip(), 2); + assert_eq!(blk.isid(), 3); + assert_eq!(blk.mode(), ExecModeType::Bit32); + assert_eq!(blk.class(), Class::Error); + assert_eq!(blk.ninsn(), 4); + assert!(blk.raw().len() > 0); + assert!(!blk.truncated()); + assert!(!blk.speculative()); } } @@ -76,19 +73,25 @@ mod test { pub struct Block(pub(super) pt_block); impl Block { /// The IP of the first instruction in this block. - pub fn ip(&self) -> u64 { self.0.ip } + pub fn ip(&self) -> u64 { + self.0.ip + } /// The IP of the last instruction in this block. /// /// This can be used for error-detection. - pub fn end_ip(&self) -> u64 { self.0.end_ip } + pub fn end_ip(&self) -> u64 { + self.0.end_ip + } /// The image section that contains the instructions in this block. /// /// A value of zero means that the section did not have an identifier. /// The section was not added via an image section cache or the memory /// was read via the read memory callback. - pub fn isid(&self) -> i32 { self.0.isid } + pub fn isid(&self) -> i32 { + self.0.isid + } /// The execution mode for all instructions in this block. pub fn mode(&self) -> ExecModeType { @@ -105,7 +108,9 @@ impl Block { } /// The number of instructions in this block. - pub fn ninsn(&self) -> u16 { self.0.ninsn } + pub fn ninsn(&self) -> u16 { + self.0.ninsn + } /// The raw bytes of the last instruction in this block in case the /// instruction does not fit entirely into this block's section. @@ -119,7 +124,9 @@ impl Block { /// instructions in this block. /// /// - all instructions in this block were executed speculatively. - pub fn speculative(&self) -> bool { self.0.speculative() > 0 } + pub fn speculative(&self) -> bool { + self.0.speculative() > 0 + } /// A collection of flags giving additional information about the /// instructions in this block. @@ -131,5 +138,7 @@ impl Block { /// /// The raw bytes for the last instruction are provided in \@raw and /// its size in \@size in this case. - pub fn truncated(&self) -> bool { self.0.truncated() > 0 } + pub fn truncated(&self) -> bool { + self.0.truncated() > 0 + } } diff --git a/src/block/mod.rs b/src/block/mod.rs index bd353a8..eb2305e 100644 --- a/src/block/mod.rs +++ b/src/block/mod.rs @@ -2,4 +2,4 @@ mod block; mod decoder; pub use block::*; -pub use decoder::*; \ No newline at end of file +pub use decoder::*; diff --git a/src/config/config.rs b/src/config/config.rs index 29b0fa9..f7c7967 100644 --- a/src/config/config.rs +++ b/src/config/config.rs @@ -1,20 +1,16 @@ use super::cpu::Cpu; -use super::freqency::Frequency; use super::filter::AddrFilter; +use super::freqency::Frequency; +use crate::error::{PtError, PtErrorCode}; use crate::packet::Unknown; -use crate::error::{ PtError, PtErrorCode }; -use std::mem; use std::borrow::Cow; -use std::marker::PhantomData; use std::ffi::c_void; +use std::marker::PhantomData; +use std::mem; use std::os::raw::c_int; -use libipt_sys::{ - pt_config, - pt_conf_flags, - pt_packet_unknown -}; +use libipt_sys::{pt_conf_flags, pt_config, pt_packet_unknown}; #[cfg(test)] mod test { @@ -41,20 +37,21 @@ mod test { #[test] fn test_config_all() { let mut data = [18; 3]; - let c = ConfigBuilder::with_callback( - &mut data, |c, p| { - (Unknown::new(c.0.cpu.model + p[0]), 1) }) - .unwrap() - .filter(AddrFilterBuilder::new() - .addr0(AddrRange::new(1, 2, AddrConfig::STOP)) - .addr1(AddrRange::new(3, 4, AddrConfig::FILTER)) - .addr2(AddrRange::new(5, 6, AddrConfig::DISABLED)) - .addr3(AddrRange::new(7, 8, AddrConfig::STOP)) - .finish()) - .cpu(Cpu::intel(1, 2, 3)) - .freq(Frequency::new(1, 2, 3, 4)) - .flags(BlockFlags::END_ON_CALL | BlockFlags::END_ON_JUMP) - .finish(); + let c = + ConfigBuilder::with_callback(&mut data, |c, p| (Unknown::new(c.0.cpu.model + p[0]), 1)) + .unwrap() + .filter( + AddrFilterBuilder::new() + .addr0(AddrRange::new(1, 2, AddrConfig::STOP)) + .addr1(AddrRange::new(3, 4, AddrConfig::FILTER)) + .addr2(AddrRange::new(5, 6, AddrConfig::DISABLED)) + .addr3(AddrRange::new(7, 8, AddrConfig::STOP)) + .finish(), + ) + .cpu(Cpu::intel(1, 2, 3)) + .freq(Frequency::new(1, 2, 3, 4)) + .flags(BlockFlags::END_ON_CALL | BlockFlags::END_ON_JUMP) + .finish(); assert_eq!(c.0.cpu.family, 1); assert_eq!(c.0.cpu.model, 2); @@ -74,60 +71,72 @@ mod test { assert_eq!(c.0.addr_filter.addr0_a, 1); assert_eq!(c.0.addr_filter.addr0_b, 2); - assert_eq!(unsafe { c.0.addr_filter.config.ctl.addr0_cfg() }, - AddrConfig::STOP as u32); + assert_eq!( + unsafe { c.0.addr_filter.config.ctl.addr0_cfg() }, + AddrConfig::STOP as u32 + ); assert_eq!(c.0.addr_filter.addr1_a, 3); assert_eq!(c.0.addr_filter.addr1_b, 4); - assert_eq!(unsafe { c.0.addr_filter.config.ctl.addr1_cfg() }, - AddrConfig::FILTER as u32); + assert_eq!( + unsafe { c.0.addr_filter.config.ctl.addr1_cfg() }, + AddrConfig::FILTER as u32 + ); assert_eq!(c.0.addr_filter.addr2_a, 5); assert_eq!(c.0.addr_filter.addr2_b, 6); - assert_eq!(unsafe { c.0.addr_filter.config.ctl.addr2_cfg() }, - AddrConfig::DISABLED as u32); + assert_eq!( + unsafe { c.0.addr_filter.config.ctl.addr2_cfg() }, + AddrConfig::DISABLED as u32 + ); assert_eq!(c.0.addr_filter.addr3_a, 7); assert_eq!(c.0.addr_filter.addr3_b, 8); - assert_eq!(unsafe { c.0.addr_filter.config.ctl.addr3_cfg() }, - AddrConfig::STOP as u32); + assert_eq!( + unsafe { c.0.addr_filter.config.ctl.addr3_cfg() }, + AddrConfig::STOP as u32 + ); unsafe { let mut ukn: pt_packet_unknown = std::mem::zeroed(); assert_eq!( - c.0.decode.callback.unwrap()(&mut ukn, - c.0.as_ref(), c.0.begin, - c.0.decode.context), - 1); + c.0.decode.callback.unwrap()(&mut ukn, c.0.as_ref(), c.0.begin, c.0.decode.context), + 1 + ); let pkt: Unknown = Unknown::from(ukn); assert_eq!(pkt.data().unwrap(), 20); } } fn check_callback(cfg: &mut Config, expect: T, expect_sz: i32) -> bool - where T: PartialEq { + where + T: PartialEq, + { unsafe { let mut ukn: pt_packet_unknown = std::mem::zeroed(); - return - cfg.0.decode.callback.unwrap()(&mut ukn, - cfg.0.as_ref(), cfg.0.begin, - cfg.0.decode.context) - == expect_sz + return cfg.0.decode.callback.unwrap()( + &mut ukn, + cfg.0.as_ref(), + cfg.0.begin, + cfg.0.decode.context, + ) == expect_sz && Unknown::::from(ukn).data().unwrap() == expect; } } #[test] fn test_config_callback_safety() { - let mut kektop = [10;9]; - let mut cfg = ConfigBuilder::with_callback( - &mut kektop, - |c, p,| { (Unknown::new(c.0.cpu.stepping + p[8]), 17) }) - .unwrap() - .cpu(Cpu::intel(1, 2, 3)) - .finish(); - - for _ in 0..10 { assert!(check_callback(&mut cfg, 13, 17)) } + let mut kektop = [10; 9]; + let mut cfg = ConfigBuilder::with_callback(&mut kektop, |c, p| { + (Unknown::new(c.0.cpu.stepping + p[8]), 17) + }) + .unwrap() + .cpu(Cpu::intel(1, 2, 3)) + .finish(); + + for _ in 0..10 { + assert!(check_callback(&mut cfg, 13, 17)) + } } // FIXME @@ -135,26 +144,34 @@ mod test { #[test] #[should_panic] fn test_config_callback_out_of_bounds() { - let mut kektop = [10;9]; - let cfg = ConfigBuilder::with_callback(&mut kektop, |c, p,| { + let mut kektop = [10; 9]; + let cfg = ConfigBuilder::with_callback(&mut kektop, |c, p| { // make sure no move or copy is done - if let Cow::Owned(_) = c.0 { panic!("BUG!") } + if let Cow::Owned(_) = c.0 { + panic!("BUG!") + } // assert_eq!(c.0.as_ref() as *const _, raw); (Unknown::new(p[100]), 17) - }).unwrap().cpu(Cpu::intel(1, 2, 3)).finish(); + }) + .unwrap() + .cpu(Cpu::intel(1, 2, 3)) + .finish(); unsafe { let mut ukn: pt_packet_unknown = std::mem::zeroed(); - cfg.0.decode.callback.unwrap()(&mut ukn, - cfg.0.as_ref(), cfg.0.begin, - cfg.0.decode.context); + cfg.0.decode.callback.unwrap()( + &mut ukn, + cfg.0.as_ref(), + cfg.0.begin, + cfg.0.decode.context, + ); } } #[test] fn test_builder_buf_lifetimes() { let mut x = [10; 10]; - let a : Config<()>; + let a: Config<()>; { let mut c = ConfigBuilder::new(&mut x).unwrap(); a = c.finish(); @@ -166,12 +183,15 @@ mod test { } } -unsafe extern "C" fn decode_callback<'a, F, C>(ukn: *mut pt_packet_unknown, - cfg: *const pt_config, - pos: *const u8, - ctx: *mut c_void) -> c_int - where F: FnMut(&Config, &[u8]) -> (Unknown, u32) { - +unsafe extern "C" fn decode_callback<'a, F, C>( + ukn: *mut pt_packet_unknown, + cfg: *const pt_config, + pos: *const u8, + ctx: *mut c_void, +) -> c_int +where + F: FnMut(&Config, &[u8]) -> (Unknown, u32), +{ let sz = (*cfg).end as usize - pos as usize; let pos = std::slice::from_raw_parts(pos, sz); @@ -181,30 +201,32 @@ unsafe extern "C" fn decode_callback<'a, F, C>(ukn: *mut pt_packet_unknown, let (res, bytes) = c(&(&*cfg).into(), pos); (*ukn).priv_ = match res.0 { Some(r) => Box::into_raw(r) as *mut _, - None => std::ptr::null_mut() + None => std::ptr::null_mut(), }; bytes as i32 } /// A helper type to create the libipt Configuration instance -pub struct ConfigBuilder<'a, T> (pt_config, PhantomData<&'a mut T>); +pub struct ConfigBuilder<'a, T>(pt_config, PhantomData<&'a mut T>); impl<'a, T> ConfigBuilder<'a, T> { // when theres a bug here, there might be on in `new` too. /// Initializes a Config instance with a buffer and decoder callback pub fn with_callback(buf: &'a mut [u8], mut cb: F) -> Result - where F: FnMut(&Config, &[u8]) -> (Unknown, u32), - F: 'a { + where + F: FnMut(&Config, &[u8]) -> (Unknown, u32), + F: 'a, + { // yeah.. libipt doesnt handle this -_- - if buf.is_empty() { return Err( - PtError::new(PtErrorCode::Invalid, "buffer cant be empty!") - )} + if buf.is_empty() { + return Err(PtError::new(PtErrorCode::Invalid, "buffer cant be empty!")); + } let mut cfg: pt_config = unsafe { mem::zeroed() }; - cfg.size = mem::size_of::(); + cfg.size = mem::size_of::(); cfg.begin = buf.as_mut_ptr(); - cfg.end = unsafe { buf.as_mut_ptr().add(buf.len()) }; + cfg.end = unsafe { buf.as_mut_ptr().add(buf.len()) }; cfg.decode.callback = Some(decode_callback::); - cfg.decode.context = &mut cb as *mut _ as *mut c_void; + cfg.decode.context = &mut cb as *mut _ as *mut c_void; Ok(ConfigBuilder::(cfg, PhantomData)) } @@ -252,28 +274,25 @@ impl<'a> ConfigBuilder<'a, ()> { /// use the `with_callback` function /// returns `Invalid` when buf is empty pub fn new(buf: &'a mut [u8]) -> Result, PtError> { - if buf.is_empty() { return Err( - PtError::new(PtErrorCode::Invalid, "buffer cant be empty!") - )} + if buf.is_empty() { + return Err(PtError::new(PtErrorCode::Invalid, "buffer cant be empty!")); + } let mut cfg: pt_config = unsafe { mem::zeroed() }; - cfg.size = mem::size_of::(); + cfg.size = mem::size_of::(); cfg.begin = buf.as_mut_ptr(); - cfg.end = unsafe { buf.as_mut_ptr().add(buf.len()) }; + cfg.end = unsafe { buf.as_mut_ptr().add(buf.len()) }; Ok(ConfigBuilder::<()>(cfg, PhantomData)) } } /// A libipt configuration -pub struct Config<'a, C> (pub(crate) Cow<'a, pt_config>, PhantomData<&'a mut C>); +pub struct Config<'a, C>(pub(crate) Cow<'a, pt_config>, PhantomData<&'a mut C>); impl<'a, C> Config<'a, C> { /// Gets this configs buffer. /// This operation is unsafe because an encoder might write into the buffer /// at any time pub unsafe fn buffer(&self) -> &'a [u8] { - std::slice::from_raw_parts( - self.0.begin, - self.0.end as usize - self.0.begin as usize - ) + std::slice::from_raw_parts(self.0.begin, self.0.end as usize - self.0.begin as usize) } } diff --git a/src/config/cpu.rs b/src/config/cpu.rs index 978d90d..c9a29cb 100644 --- a/src/config/cpu.rs +++ b/src/config/cpu.rs @@ -1,7 +1,10 @@ // Certain casts are required only on Windows. Inform Clippy to ignore them. #![allow(clippy::unnecessary_cast)] -use libipt_sys::{pt_cpu, pt_cpu_vendor_pcv_intel, pt_cpu_vendor_pcv_unknown, pt_errata, pt_cpu_errata, pt_cpu_vendor}; +use libipt_sys::{ + pt_cpu, pt_cpu_errata, pt_cpu_vendor, pt_cpu_vendor_pcv_intel, pt_cpu_vendor_pcv_unknown, + pt_errata, +}; use bitflags::bitflags; @@ -15,7 +18,7 @@ mod test { let cpu2 = Cpu::new(CpuVendor::INTEL, 66, 12, 255); assert_eq!(cpu1.0.vendor, cpu2.0.vendor); assert_eq!(cpu1.0.family, cpu2.0.family); - assert_eq!(cpu1.0.model, cpu2.0.model); + assert_eq!(cpu1.0.model, cpu2.0.model); assert_eq!(cpu1.0.stepping, cpu2.0.stepping); } @@ -27,7 +30,7 @@ mod test { assert_eq!(e.bdm64(), 1); assert_eq!(e.skd007(), 0); assert_eq!(e.skd022(), 0); - + let cpu = Cpu::intel(0x6, 0x9e, 11); let e = cpu.determine_errata(); assert_eq!(e.bdm64(), 0); @@ -47,10 +50,15 @@ bitflags! { /// A Cpu identifier #[derive(Clone, Copy, Debug)] -pub struct Cpu (pub(super) pt_cpu); +pub struct Cpu(pub(super) pt_cpu); impl Cpu { pub fn new(vendor: CpuVendor, family: u16, model: u8, stepping: u8) -> Self { - Cpu(pt_cpu{ vendor: vendor.bits() as pt_cpu_vendor, family, model, stepping }) + Cpu(pt_cpu { + vendor: vendor.bits() as pt_cpu_vendor, + family, + model, + stepping, + }) } /// A shortcut for creating an intel Cpu instance @@ -63,11 +71,13 @@ impl Cpu { let mut errata = pt_errata { _bitfield_align_1: [], _bitfield_1: Default::default(), - reserved: Default::default() + reserved: Default::default(), }; // we dont care about errors here since // itll just return an empty errata - unsafe{ pt_cpu_errata(&mut errata, &self.0); } + unsafe { + pt_cpu_errata(&mut errata, &self.0); + } errata } } diff --git a/src/config/filter.rs b/src/config/filter.rs index 9344153..eb41bbe 100644 --- a/src/config/filter.rs +++ b/src/config/filter.rs @@ -1,7 +1,7 @@ -use std::mem; -use std::convert::TryFrom; use libipt_sys::pt_conf_addr_filter; use num_enum::TryFromPrimitive; +use std::convert::TryFrom; +use std::mem; #[cfg(test)] mod test { @@ -36,7 +36,11 @@ mod test { #[derive(Clone, Copy, TryFromPrimitive, PartialEq, Debug)] #[repr(u32)] -pub enum AddrConfig {DISABLED, FILTER, STOP } +pub enum AddrConfig { + DISABLED, + FILTER, + STOP, +} /// an address range inside the address filter #[derive(Clone, Copy)] @@ -46,7 +50,7 @@ pub struct AddrRange { /// This corresponds to the IA32_RTIT_ADDRn_B MSRs b: u64, /// this corresponds to the respective fields in IA32_RTIT_CTL MSR - cfg: AddrConfig + cfg: AddrConfig, } impl AddrRange { @@ -57,64 +61,87 @@ impl AddrRange { /// This corresponds to the IA32_RTIT_ADDRn_A MSRs #[inline] - pub fn a(&self) -> u64 { self.a } + pub fn a(&self) -> u64 { + self.a + } /// This corresponds to the IA32_RTIT_ADDRn_B MSRs #[inline] - pub fn b(&self) -> u64 { self.b } + pub fn b(&self) -> u64 { + self.b + } /// this corresponds to the respective fields in IA32_RTIT_CTL MSR #[inline] - pub fn cfg(&self) -> AddrConfig { self.cfg } - + pub fn cfg(&self) -> AddrConfig { + self.cfg + } + /// This corresponds to the IA32_RTIT_ADDRn_A MSRs #[inline] - pub fn set_a(&mut self, a: u64) { self.a = a; } + pub fn set_a(&mut self, a: u64) { + self.a = a; + } /// This corresponds to the IA32_RTIT_ADDRn_B MSRs #[inline] - pub fn set_b(&mut self, b: u64) { self.b = b; } + pub fn set_b(&mut self, b: u64) { + self.b = b; + } /// this corresponds to the respective fields in IA32_RTIT_CTL MSR #[inline] - pub fn set_cfg(&mut self, cfg: AddrConfig) { self.cfg = cfg } + pub fn set_cfg(&mut self, cfg: AddrConfig) { + self.cfg = cfg + } } - /// the address filter configuration #[derive(Clone, Copy)] -pub struct AddrFilter (pub(super) pt_conf_addr_filter); +pub struct AddrFilter(pub(super) pt_conf_addr_filter); impl AddrFilter { #[inline] pub fn addr0(&self) -> AddrRange { unsafe { - AddrRange::new(self.0.addr0_a, self.0.addr0_b, - AddrConfig::try_from(self.0.config.ctl.addr0_cfg()).unwrap()) + AddrRange::new( + self.0.addr0_a, + self.0.addr0_b, + AddrConfig::try_from(self.0.config.ctl.addr0_cfg()).unwrap(), + ) } } #[inline] pub fn addr1(&self) -> AddrRange { unsafe { - AddrRange::new(self.0.addr1_a, self.0.addr1_b, - AddrConfig::try_from(self.0.config.ctl.addr1_cfg()).unwrap()) + AddrRange::new( + self.0.addr1_a, + self.0.addr1_b, + AddrConfig::try_from(self.0.config.ctl.addr1_cfg()).unwrap(), + ) } } #[inline] pub fn addr2(&self) -> AddrRange { unsafe { - AddrRange::new(self.0.addr2_a, self.0.addr2_b, - AddrConfig::try_from(self.0.config.ctl.addr2_cfg()).unwrap()) + AddrRange::new( + self.0.addr2_a, + self.0.addr2_b, + AddrConfig::try_from(self.0.config.ctl.addr2_cfg()).unwrap(), + ) } } #[inline] pub fn addr3(&self) -> AddrRange { unsafe { - AddrRange::new(self.0.addr3_a, self.0.addr3_b, - AddrConfig::try_from(self.0.config.ctl.addr3_cfg()).unwrap()) + AddrRange::new( + self.0.addr3_a, + self.0.addr3_b, + AddrConfig::try_from(self.0.config.ctl.addr3_cfg()).unwrap(), + ) } } } -pub struct AddrFilterBuilder (pub(super) pt_conf_addr_filter); +pub struct AddrFilterBuilder(pub(super) pt_conf_addr_filter); impl Default for AddrFilterBuilder { fn default() -> Self { Self::new() @@ -122,7 +149,9 @@ impl Default for AddrFilterBuilder { } impl AddrFilterBuilder { - pub fn new() -> Self { unsafe { mem::zeroed() }} + pub fn new() -> Self { + unsafe { mem::zeroed() } + } #[inline] pub fn addr0(&mut self, range: AddrRange) -> &mut Self { @@ -160,5 +189,7 @@ impl AddrFilterBuilder { self } - pub fn finish(&self) -> AddrFilter { AddrFilter(self.0) } -} \ No newline at end of file + pub fn finish(&self) -> AddrFilter { + AddrFilter(self.0) + } +} diff --git a/src/config/flags.rs b/src/config/flags.rs index f462b03..a6ffae0 100644 --- a/src/config/flags.rs +++ b/src/config/flags.rs @@ -1,10 +1,7 @@ use libipt_sys::{ - pt_conf_flags, - pt_conf_flags__bindgen_ty_1, - pt_conf_flags__bindgen_ty_1__bindgen_ty_1, - pt_conf_flags__bindgen_ty_1__bindgen_ty_2, + __BindgenBitfieldUnit, pt_conf_flags, pt_conf_flags__bindgen_ty_1, + pt_conf_flags__bindgen_ty_1__bindgen_ty_1, pt_conf_flags__bindgen_ty_1__bindgen_ty_2, pt_conf_flags__bindgen_ty_1__bindgen_ty_3, - __BindgenBitfieldUnit }; use bitflags::bitflags; @@ -24,11 +21,11 @@ mod test { assert_eq!(raw.variant.block.end_on_jump(), 1); assert_eq!(raw.variant.block.keep_tcal_on_ovf(), 0); } - - let blk: BlockFlags = BlockFlags::END_ON_CALL | - BlockFlags::END_ON_JUMP | - BlockFlags::ENABLE_TICK_EVENTS | - BlockFlags::KEEP_TCAL_ON_OVF; + + let blk: BlockFlags = BlockFlags::END_ON_CALL + | BlockFlags::END_ON_JUMP + | BlockFlags::ENABLE_TICK_EVENTS + | BlockFlags::KEEP_TCAL_ON_OVF; let raw: pt_conf_flags = blk.into(); unsafe { @@ -63,12 +60,16 @@ mod test { let query = QueryFlags::empty(); let raw: pt_conf_flags = query.into(); - unsafe { assert_eq!(raw.variant.query.keep_tcal_on_ovf(), 0); } + unsafe { + assert_eq!(raw.variant.query.keep_tcal_on_ovf(), 0); + } let query: QueryFlags = QueryFlags::KEEP_TCAL_ON_OVF; let raw: pt_conf_flags = query.into(); - unsafe { assert_eq!(raw.variant.query.keep_tcal_on_ovf(), 1); } + unsafe { + assert_eq!(raw.variant.query.keep_tcal_on_ovf(), 1); + } } } @@ -111,7 +112,10 @@ impl From for pt_conf_flags { block: pt_conf_flags__bindgen_ty_1__bindgen_ty_1 { _bitfield_align_1: [], _bitfield_1: __BindgenBitfieldUnit::new([flags.bits()]), - __bindgen_padding_0: Default::default() }}} + __bindgen_padding_0: Default::default(), + }, + }, + } } } @@ -122,7 +126,10 @@ impl From for pt_conf_flags { insn: pt_conf_flags__bindgen_ty_1__bindgen_ty_2 { _bitfield_align_1: [], _bitfield_1: __BindgenBitfieldUnit::new([flags.bits()]), - __bindgen_padding_0: Default::default() }}} + __bindgen_padding_0: Default::default(), + }, + }, + } } } @@ -133,6 +140,9 @@ impl From for pt_conf_flags { query: pt_conf_flags__bindgen_ty_1__bindgen_ty_3 { _bitfield_align_1: [], _bitfield_1: __BindgenBitfieldUnit::new([flags.bits()]), - __bindgen_padding_0: Default::default() }}} + __bindgen_padding_0: Default::default(), + }, + }, + } } -} \ No newline at end of file +} diff --git a/src/config/freqency.rs b/src/config/freqency.rs index 3105826..eb9787a 100644 --- a/src/config/freqency.rs +++ b/src/config/freqency.rs @@ -63,7 +63,7 @@ pub struct Frequency { /// This field is ignored by the packet encoder and packet decoder. It is /// required for other decoders if Mini Time Counter (MTC) packets are enabled /// in the collected trace. - pub(super) tsc: u32 + pub(super) tsc: u32, } impl Frequency { @@ -74,7 +74,7 @@ impl Frequency { /// * `tsc` - The value of eax on a cpuid call for leaf 0x15 #[inline] pub fn new(mtc: u8, nom: u8, ctc: u32, tsc: u32) -> Self { - Frequency {mtc, nom, ctc, tsc} + Frequency { mtc, nom, ctc, tsc } } /// The Mini Time Counter (MTC) frequency as defined in IA32_RTIT_CTL.MTCFreq. @@ -83,7 +83,9 @@ impl Frequency { /// required for other decoders if Mini Time Counter (MTC) packets are enabled /// in the collected trace. #[inline] - pub fn mtc(self) -> u8 { self.mtc } + pub fn mtc(self) -> u8 { + self.mtc + } /// The nominal or max non-turbo frequency. /// /// This field is ignored by the packet encoder and packet decoder. It is @@ -96,7 +98,9 @@ impl Frequency { /// If the field is non-zero, the time tracking algorithm will additionally be /// able to calibrate at Core:Bus Ratio (CBR) packets. #[inline] - pub fn nom(self) -> u8 { self.nom } + pub fn nom(self) -> u8 { + self.nom + } /// The value of ebx on a cpuid call for leaf 0x15. /// /// The value *ebx/eax* gives the ratio of the Core Crystal Clock (CTC) to @@ -106,7 +110,9 @@ impl Frequency { /// required for other decoders if Mini Time Counter (MTC) packets are enabled /// in the collected trace. #[inline] - pub fn ctc(self) -> u32 { self.ctc } + pub fn ctc(self) -> u32 { + self.ctc + } /// The value of eax on a cpuid call for leaf 0x15. /// /// The value *ebx/eax* gives the ratio of the Core Crystal Clock (CTC) to @@ -116,14 +122,24 @@ impl Frequency { /// required for other decoders if Mini Time Counter (MTC) packets are enabled /// in the collected trace. #[inline] - pub fn tsc(self) -> u32 { self.tsc } + pub fn tsc(self) -> u32 { + self.tsc + } #[inline] - pub fn set_mtc(&mut self, mtc: u8) { self.mtc = mtc } + pub fn set_mtc(&mut self, mtc: u8) { + self.mtc = mtc + } #[inline] - pub fn set_nom(&mut self, nom: u8) { self.nom = nom } + pub fn set_nom(&mut self, nom: u8) { + self.nom = nom + } #[inline] - pub fn set_ctc(&mut self, ctc: u32) { self.ctc = ctc } + pub fn set_ctc(&mut self, ctc: u32) { + self.ctc = ctc + } #[inline] - pub fn set_tsc(&mut self, tsc: u32) { self.tsc = tsc } -} \ No newline at end of file + pub fn set_tsc(&mut self, tsc: u32) { + self.tsc = tsc + } +} diff --git a/src/config/mod.rs b/src/config/mod.rs index 80041fa..5dbb70a 100644 --- a/src/config/mod.rs +++ b/src/config/mod.rs @@ -1,12 +1,12 @@ -mod flags; mod cpu; -mod freqency; mod filter; +mod flags; +mod freqency; mod config; pub use config::*; pub use cpu::*; -pub use freqency::*; +pub use filter::*; pub use flags::*; -pub use filter::*; \ No newline at end of file +pub use freqency::*; diff --git a/src/error.rs b/src/error.rs index b3fa260..54c0a32 100644 --- a/src/error.rs +++ b/src/error.rs @@ -1,39 +1,21 @@ use num_enum::TryFromPrimitive; use std::convert::TryFrom; +use std::error::Error; use std::ffi::CStr; use std::fmt::{Display, Formatter}; -use std::error::Error; use libipt_sys::{pt_error_code, pt_errstr}; use libipt_sys::{ - pt_error_code_pte_ok, - pt_error_code_pte_internal, - pt_error_code_pte_invalid, - pt_error_code_pte_nosync, - pt_error_code_pte_bad_opc, - pt_error_code_pte_bad_packet, - pt_error_code_pte_bad_context, - pt_error_code_pte_eos, - pt_error_code_pte_bad_query, - pt_error_code_pte_nomem, - pt_error_code_pte_bad_config, - pt_error_code_pte_noip, - pt_error_code_pte_ip_suppressed, - pt_error_code_pte_nomap, - pt_error_code_pte_bad_insn, - pt_error_code_pte_no_time, - pt_error_code_pte_no_cbr, - pt_error_code_pte_bad_image, - pt_error_code_pte_bad_lock, - pt_error_code_pte_not_supported, - pt_error_code_pte_retstack_empty, - pt_error_code_pte_bad_retcomp, - pt_error_code_pte_bad_status_update, - pt_error_code_pte_no_enable, - pt_error_code_pte_event_ignored, - pt_error_code_pte_overflow, - pt_error_code_pte_bad_file, - pt_error_code_pte_bad_cpu + pt_error_code_pte_bad_config, pt_error_code_pte_bad_context, pt_error_code_pte_bad_cpu, + pt_error_code_pte_bad_file, pt_error_code_pte_bad_image, pt_error_code_pte_bad_insn, + pt_error_code_pte_bad_lock, pt_error_code_pte_bad_opc, pt_error_code_pte_bad_packet, + pt_error_code_pte_bad_query, pt_error_code_pte_bad_retcomp, + pt_error_code_pte_bad_status_update, pt_error_code_pte_eos, pt_error_code_pte_event_ignored, + pt_error_code_pte_internal, pt_error_code_pte_invalid, pt_error_code_pte_ip_suppressed, + pt_error_code_pte_no_cbr, pt_error_code_pte_no_enable, pt_error_code_pte_no_time, + pt_error_code_pte_noip, pt_error_code_pte_nomap, pt_error_code_pte_nomem, + pt_error_code_pte_nosync, pt_error_code_pte_not_supported, pt_error_code_pte_ok, + pt_error_code_pte_overflow, pt_error_code_pte_retstack_empty, }; #[derive(Clone, Copy, Debug, TryFromPrimitive, PartialEq)] @@ -97,13 +79,13 @@ pub enum PtErrorCode { BadCpu = pt_error_code_pte_bad_cpu as i32, /// No Error Information available - NoInfo = -1 + NoInfo = -1, } #[derive(Debug, Clone, Copy)] pub struct PtError { - code: PtErrorCode, - msg: &'static str + code: PtErrorCode, + msg: &'static str, } impl PtError { @@ -121,10 +103,11 @@ impl PtError { // panicking here is fine since this should only be called // for return values of libipt functions // so invalid returns = bug in libipt or the bindings - PtError::new( - PtErrorCode::try_from(-code).unwrap(), - unsafe { CStr::from_ptr(pt_errstr(-code as pt_error_code)).to_str().unwrap() } - ) + PtError::new(PtErrorCode::try_from(-code).unwrap(), unsafe { + CStr::from_ptr(pt_errstr(-code as pt_error_code)) + .to_str() + .unwrap() + }) } /// get the pt error code @@ -148,7 +131,9 @@ impl Display for PtError { impl Error for PtError { // sadly we have no idea what the source is - fn source(&self) -> Option<&(dyn Error + 'static)> { None } + fn source(&self) -> Option<&(dyn Error + 'static)> { + None + } } /// Dereferences a pointer returned by one of the libipt functions. @@ -160,7 +145,7 @@ pub(crate) fn deref_ptresult(res: *const T) -> Result<&'static T, PtError> { // null reference, no error info 0 => Err(PtError::new(PtErrorCode::NoInfo, "No further information")), x if x < 0 => Err(PtError::from_code(x as i32)), - _ => Ok(unsafe { res.as_ref().unwrap() }) + _ => Ok(unsafe { res.as_ref().unwrap() }), } } @@ -173,7 +158,7 @@ pub(crate) fn deref_ptresult_mut(res: *mut T) -> Result<&'static mut T, PtErr // null reference, no error info 0 => Err(PtError::new(PtErrorCode::NoInfo, "No further information")), x if x < 0 => Err(PtError::from_code(x as i32)), - _ => Ok(unsafe { res.as_mut().unwrap() }) + _ => Ok(unsafe { res.as_mut().unwrap() }), } } @@ -181,7 +166,7 @@ pub(crate) fn deref_ptresult_mut(res: *mut T) -> Result<&'static mut T, PtErr // Discards the error code #[inline] pub(crate) fn ensure_ptok(code: i32) -> Result<(), PtError> { - extract_pterr(code).map(|_|()) + extract_pterr(code).map(|_| ()) } // Turns a negative code into a PtErr. @@ -190,6 +175,6 @@ pub(crate) fn ensure_ptok(code: i32) -> Result<(), PtError> { pub(crate) fn extract_pterr(code: i32) -> Result { match code { x if x >= 0 => Ok(code as u32), - _ => Err(PtError::from_code(code)) + _ => Err(PtError::from_code(code)), } } diff --git a/src/event/branch.rs b/src/event/branch.rs index eb6dd0f..d4410f8 100644 --- a/src/event/branch.rs +++ b/src/event/branch.rs @@ -2,27 +2,24 @@ use libipt_sys::pt_event__bindgen_ty_1__bindgen_ty_4; #[cfg(test)] mod test { - use super::*; use super::super::Payload; + use super::*; + use libipt_sys::{pt_event, pt_event_type_ptev_async_branch}; use std::mem; - use libipt_sys::{ pt_event, pt_event_type_ptev_async_branch }; #[test] fn test_branch_async_payload() { let mut evt: pt_event = unsafe { mem::zeroed() }; evt.type_ = pt_event_type_ptev_async_branch; - evt.variant.async_branch = pt_event__bindgen_ty_1__bindgen_ty_4 { - from: 1, - to: 2 - }; + evt.variant.async_branch = pt_event__bindgen_ty_1__bindgen_ty_4 { from: 1, to: 2 }; let payload: Payload = evt.into(); match payload { Payload::AsyncBranch(e) => { assert_eq!(e.from(), 1); assert_eq!(e.to(), 2); - }, - _ => unreachable!("oof") + } + _ => unreachable!("oof"), } } } @@ -32,8 +29,12 @@ mod test { pub struct AsyncBranch(pub(super) pt_event__bindgen_ty_1__bindgen_ty_4); impl AsyncBranch { /// The branch source address - pub fn from(self) -> u64 { self.0.from } + pub fn from(self) -> u64 { + self.0.from + } /// The branch destination address. /// This field is not valid if @ip_suppressed is set. - pub fn to(self) -> u64 { self.0.to } -} \ No newline at end of file + pub fn to(self) -> u64 { + self.0.to + } +} diff --git a/src/event/cbr.rs b/src/event/cbr.rs index f434cec..e200e5d 100644 --- a/src/event/cbr.rs +++ b/src/event/cbr.rs @@ -2,25 +2,23 @@ use libipt_sys::pt_event__bindgen_ty_1__bindgen_ty_18; #[cfg(test)] mod test { - use super::*; use super::super::Payload; + use super::*; + use libipt_sys::{pt_event, pt_event_type_ptev_cbr}; use std::mem; - use libipt_sys::{ pt_event, pt_event_type_ptev_cbr }; #[test] fn test_cbr_payload() { let mut evt: pt_event = unsafe { mem::zeroed() }; evt.type_ = pt_event_type_ptev_cbr; - evt.variant.cbr = pt_event__bindgen_ty_1__bindgen_ty_18 { - ratio: 18 - }; + evt.variant.cbr = pt_event__bindgen_ty_1__bindgen_ty_18 { ratio: 18 }; let payload: Payload = evt.into(); match payload { Payload::Cbr(e) => { assert_eq!(e.ratio(), 18); - }, - _ => unreachable!("oof") + } + _ => unreachable!("oof"), } } } @@ -30,5 +28,7 @@ mod test { pub struct Cbr(pub(super) pt_event__bindgen_ty_1__bindgen_ty_18); impl Cbr { /// The core:bus ratio. - pub fn ratio(self) -> u16 { self.0.ratio } -} \ No newline at end of file + pub fn ratio(self) -> u16 { + self.0.ratio + } +} diff --git a/src/event/disabled.rs b/src/event/disabled.rs index 4bebdd7..4642d7d 100644 --- a/src/event/disabled.rs +++ b/src/event/disabled.rs @@ -1,33 +1,24 @@ -use libipt_sys::{ - pt_event__bindgen_ty_1__bindgen_ty_2, - pt_event__bindgen_ty_1__bindgen_ty_3 -}; +use libipt_sys::{pt_event__bindgen_ty_1__bindgen_ty_2, pt_event__bindgen_ty_1__bindgen_ty_3}; #[cfg(test)] mod test { - use super::*; use super::super::Payload; + use super::*; + use libipt_sys::{pt_event, pt_event_type_ptev_async_disabled, pt_event_type_ptev_disabled}; use std::mem; - use libipt_sys::{ - pt_event, - pt_event_type_ptev_disabled, - pt_event_type_ptev_async_disabled - }; #[test] fn test_disabled_payload() { let mut evt: pt_event = unsafe { mem::zeroed() }; evt.type_ = pt_event_type_ptev_disabled; - evt.variant.disabled = pt_event__bindgen_ty_1__bindgen_ty_2 { - ip: 11, - }; + evt.variant.disabled = pt_event__bindgen_ty_1__bindgen_ty_2 { ip: 11 }; let payload: Payload = evt.into(); match payload { Payload::Disabled(e) => { assert_eq!(e.ip(), 11); - }, - _ => unreachable!("oof") + } + _ => unreachable!("oof"), } } @@ -35,18 +26,15 @@ mod test { fn test_async_disabled_payload() { let mut evt: pt_event = unsafe { mem::zeroed() }; evt.type_ = pt_event_type_ptev_async_disabled; - evt.variant.async_disabled = pt_event__bindgen_ty_1__bindgen_ty_3 { - at: 1, - ip: 11, - }; + evt.variant.async_disabled = pt_event__bindgen_ty_1__bindgen_ty_3 { at: 1, ip: 11 }; let payload: Payload = evt.into(); match payload { Payload::AsnycDisabled(e) => { assert_eq!(e.ip(), 11); assert_eq!(e.at(), 1); - }, - _ => unreachable!("oof") + } + _ => unreachable!("oof"), } } } @@ -59,7 +47,9 @@ impl Disabled { /// filtered area. /// /// This field is not valid if \@ip_suppressed is set. - pub fn ip(self) -> u64 { self.0.ip } + pub fn ip(self) -> u64 { + self.0.ip + } } /// Tracing has been disabled asynchronously @@ -67,9 +57,12 @@ impl Disabled { pub struct AsyncDisabled(pub(super) pt_event__bindgen_ty_1__bindgen_ty_3); impl AsyncDisabled { /// The source address of the asynchronous branch that disabled tracing - pub fn at(self) -> u64 { self.0.at } + pub fn at(self) -> u64 { + self.0.at + } /// The destination of the first branch inside a filtered area. /// This field is not valid if @ip_suppressed is set. - pub fn ip(self) -> u64 { self.0.ip } - -} \ No newline at end of file + pub fn ip(self) -> u64 { + self.0.ip + } +} diff --git a/src/event/enabled.rs b/src/event/enabled.rs index 57ca31c..3fffee3 100644 --- a/src/event/enabled.rs +++ b/src/event/enabled.rs @@ -2,10 +2,10 @@ use libipt_sys::pt_event__bindgen_ty_1__bindgen_ty_1; #[cfg(test)] mod test { - use super::*; use super::super::Payload; + use super::*; + use libipt_sys::{pt_event, pt_event_type_ptev_enabled}; use std::mem; - use libipt_sys::{ pt_event, pt_event_type_ptev_enabled }; #[test] fn test_enabled_payload() { @@ -15,7 +15,7 @@ mod test { ip: 11, _bitfield_align_1: [], _bitfield_1: pt_event__bindgen_ty_1__bindgen_ty_1::new_bitfield_1(1), - __bindgen_padding_0: Default::default() + __bindgen_padding_0: Default::default(), }; let payload: Payload = evt.into(); @@ -23,8 +23,8 @@ mod test { Payload::Enabled(e) => { assert_eq!(e.ip(), 11); assert!(e.resumed()) - }, - _ => unreachable!("oof") + } + _ => unreachable!("oof"), } } } @@ -34,9 +34,13 @@ mod test { pub struct Enabled(pub(super) pt_event__bindgen_ty_1__bindgen_ty_1); impl Enabled { /// The address at which tracing resumes - pub fn ip(self) -> u64 { self.0.ip } + pub fn ip(self) -> u64 { + self.0.ip + } /// A flag indicating that tracing resumes from the IP /// at which tracing had been disabled before. - pub fn resumed(self) -> bool { self.0.resumed() > 0 } -} \ No newline at end of file + pub fn resumed(self) -> bool { + self.0.resumed() > 0 + } +} diff --git a/src/event/exec_mode.rs b/src/event/exec_mode.rs index 82f4628..d0b0232 100644 --- a/src/event/exec_mode.rs +++ b/src/event/exec_mode.rs @@ -1,23 +1,20 @@ // Certain casts are required only on Windows. Inform Clippy to ignore them. #![allow(clippy::unnecessary_cast)] -use std::convert::TryFrom; use libipt_sys::{ - pt_event__bindgen_ty_1__bindgen_ty_8, - pt_exec_mode_ptem_16bit, - pt_exec_mode_ptem_32bit, - pt_exec_mode_ptem_64bit, - pt_exec_mode_ptem_unknown + pt_event__bindgen_ty_1__bindgen_ty_8, pt_exec_mode_ptem_16bit, pt_exec_mode_ptem_32bit, + pt_exec_mode_ptem_64bit, pt_exec_mode_ptem_unknown, }; +use std::convert::TryFrom; use num_enum::TryFromPrimitive; #[cfg(test)] mod test { - use super::*; use super::super::Payload; + use super::*; + use libipt_sys::{pt_event, pt_event_type_ptev_exec_mode}; use std::mem; - use libipt_sys::{ pt_event, pt_event_type_ptev_exec_mode }; #[test] fn test_exec_mode_payload() { @@ -25,7 +22,7 @@ mod test { evt.type_ = pt_event_type_ptev_exec_mode; evt.variant.exec_mode = pt_event__bindgen_ty_1__bindgen_ty_8 { ip: 11, - mode: pt_exec_mode_ptem_32bit + mode: pt_exec_mode_ptem_32bit, }; let payload: Payload = evt.into(); @@ -33,8 +30,8 @@ mod test { Payload::ExecMode(e) => { assert_eq!(e.ip(), 11); assert_eq!(e.mode(), ExecModeType::Bit32); - }, - _ => unreachable!("oof") + } + _ => unreachable!("oof"), } } } @@ -45,7 +42,7 @@ pub enum ExecModeType { Bit16 = pt_exec_mode_ptem_16bit as u32, Bit32 = pt_exec_mode_ptem_32bit as u32, Bit64 = pt_exec_mode_ptem_64bit as u32, - Unknown = pt_exec_mode_ptem_unknown as u32 + Unknown = pt_exec_mode_ptem_unknown as u32, } /// An execution mode change @@ -53,7 +50,11 @@ pub enum ExecModeType { pub struct ExecMode(pub(super) pt_event__bindgen_ty_1__bindgen_ty_8); impl ExecMode { /// The address at which the event is effective - pub fn ip(self) -> u64 { self.0.ip } + pub fn ip(self) -> u64 { + self.0.ip + } /// The execution mode - pub fn mode(self) -> ExecModeType { ExecModeType::try_from(self.0.mode as u32).unwrap() } -} \ No newline at end of file + pub fn mode(self) -> ExecModeType { + ExecModeType::try_from(self.0.mode as u32).unwrap() + } +} diff --git a/src/event/exstop.rs b/src/event/exstop.rs index f0a74fa..af97d9d 100644 --- a/src/event/exstop.rs +++ b/src/event/exstop.rs @@ -2,25 +2,23 @@ use libipt_sys::pt_event__bindgen_ty_1__bindgen_ty_12; #[cfg(test)] mod test { - use super::*; use super::super::Payload; + use super::*; + use libipt_sys::{pt_event, pt_event_type_ptev_exstop}; use std::mem; - use libipt_sys::{ pt_event, pt_event_type_ptev_exstop }; #[test] fn test_exstop_payload() { let mut evt: pt_event = unsafe { mem::zeroed() }; evt.type_ = pt_event_type_ptev_exstop; - evt.variant.exstop = pt_event__bindgen_ty_1__bindgen_ty_12 { - ip: 11, - }; + evt.variant.exstop = pt_event__bindgen_ty_1__bindgen_ty_12 { ip: 11 }; let payload: Payload = evt.into(); match payload { Payload::Exstop(e) => { assert_eq!(e.ip(), 11); - }, - _ => unreachable!("oof") + } + _ => unreachable!("oof"), } } } @@ -32,5 +30,7 @@ impl Exstop { /// The address at which execution has stopped. This is the last instruction that did not complete. /// /// This field is not valid, if @ip_suppressed is set. - pub fn ip(self) -> u64 { self.0.ip } -} \ No newline at end of file + pub fn ip(self) -> u64 { + self.0.ip + } +} diff --git a/src/event/mnt.rs b/src/event/mnt.rs index 6d759a4..8ca2c69 100644 --- a/src/event/mnt.rs +++ b/src/event/mnt.rs @@ -2,25 +2,23 @@ use libipt_sys::pt_event__bindgen_ty_1__bindgen_ty_19; #[cfg(test)] mod test { - use super::*; use super::super::Payload; + use super::*; + use libipt_sys::{pt_event, pt_event_type_ptev_mnt}; use std::mem; - use libipt_sys::{ pt_event, pt_event_type_ptev_mnt }; #[test] fn test_mnt_payload() { let mut evt: pt_event = unsafe { mem::zeroed() }; evt.type_ = pt_event_type_ptev_mnt; - evt.variant.mnt= pt_event__bindgen_ty_1__bindgen_ty_19 { - payload: 17 - }; + evt.variant.mnt = pt_event__bindgen_ty_1__bindgen_ty_19 { payload: 17 }; let payload: Payload = evt.into(); match payload { Payload::Mnt(e) => { assert_eq!(e.payload(), 17); - }, - _ => unreachable!("oof") + } + _ => unreachable!("oof"), } } } @@ -30,5 +28,7 @@ mod test { pub struct Mnt(pub(super) pt_event__bindgen_ty_1__bindgen_ty_19); impl Mnt { /// The raw payload. - pub fn payload(self) -> u64 { self.0.payload } -} \ No newline at end of file + pub fn payload(self) -> u64 { + self.0.payload + } +} diff --git a/src/event/mod.rs b/src/event/mod.rs index 6c2d826..35873d7 100644 --- a/src/event/mod.rs +++ b/src/event/mod.rs @@ -1,6 +1,5 @@ use libipt_sys::{ - pt_event, - pt_event_type_ptev_async_branch as PT_EVENT_TYPE_PTEV_ASYNC_BRANCH, + pt_event, pt_event_type_ptev_async_branch as PT_EVENT_TYPE_PTEV_ASYNC_BRANCH, pt_event_type_ptev_async_disabled as PT_EVENT_TYPE_PTEV_ASYNC_DISABLED, pt_event_type_ptev_async_paging as PT_EVENT_TYPE_PTEV_ASYNC_PAGING, pt_event_type_ptev_async_vmcs as PT_EVENT_TYPE_PTEV_ASYNC_VMCS, @@ -19,7 +18,7 @@ use libipt_sys::{ pt_event_type_ptev_stop as PT_EVENT_TYPE_PTEV_STOP, pt_event_type_ptev_tick as PT_EVENT_TYPE_PTEV_TICK, pt_event_type_ptev_tsx as PT_EVENT_TYPE_PTEV_TSX, - pt_event_type_ptev_vmcs as PT_EVENT_TYPE_PTEV_VMCS + pt_event_type_ptev_vmcs as PT_EVENT_TYPE_PTEV_VMCS, }; mod enabled; @@ -61,8 +60,8 @@ pub use qry::*; #[cfg(test)] mod test { use super::*; - use std::mem; use libipt_sys::pt_event_type_ptev_stop; + use std::mem; #[test] fn test_create_event() { @@ -88,7 +87,7 @@ mod test { match evt.payload() { Payload::Stop => (), - _ => unreachable!() + _ => unreachable!(), } } } @@ -114,17 +113,25 @@ pub enum Payload { Tick(Tick), Mnt(Mnt), Cbr(Cbr), - Stop + Stop, } impl From for Payload { fn from(evt: pt_event) -> Payload { unsafe { match evt.type_ { - PT_EVENT_TYPE_PTEV_ASYNC_BRANCH => Payload::AsyncBranch(AsyncBranch(evt.variant.async_branch)), - PT_EVENT_TYPE_PTEV_ASYNC_DISABLED => Payload::AsnycDisabled(AsyncDisabled(evt.variant.async_disabled)), - PT_EVENT_TYPE_PTEV_ASYNC_PAGING => Payload::AsyncPaging(AsyncPaging(evt.variant.async_paging)), - PT_EVENT_TYPE_PTEV_ASYNC_VMCS => Payload::AsyncVmcs(AsyncVmcs(evt.variant.async_vmcs)), + PT_EVENT_TYPE_PTEV_ASYNC_BRANCH => { + Payload::AsyncBranch(AsyncBranch(evt.variant.async_branch)) + } + PT_EVENT_TYPE_PTEV_ASYNC_DISABLED => { + Payload::AsnycDisabled(AsyncDisabled(evt.variant.async_disabled)) + } + PT_EVENT_TYPE_PTEV_ASYNC_PAGING => { + Payload::AsyncPaging(AsyncPaging(evt.variant.async_paging)) + } + PT_EVENT_TYPE_PTEV_ASYNC_VMCS => { + Payload::AsyncVmcs(AsyncVmcs(evt.variant.async_vmcs)) + } PT_EVENT_TYPE_PTEV_CBR => Payload::Cbr(Cbr(evt.variant.cbr)), PT_EVENT_TYPE_PTEV_DISABLED => Payload::Disabled(Disabled(evt.variant.disabled)), PT_EVENT_TYPE_PTEV_ENABLED => Payload::Enabled(Enabled(evt.variant.enabled)), @@ -141,7 +148,7 @@ impl From for Payload { PT_EVENT_TYPE_PTEV_TSX => Payload::Tsx(Tsx(evt.variant.tsx)), PT_EVENT_TYPE_PTEV_VMCS => Payload::Vmcs(Vmcs(evt.variant.vmcs)), PT_EVENT_TYPE_PTEV_STOP => Payload::Stop, - _ => unreachable!() + _ => unreachable!(), } } } @@ -151,24 +158,38 @@ impl From for Payload { pub struct Event(pub(crate) pt_event); impl Event { /// A flag indicating that the event IP has been suppressed. - pub fn ip_suppressed(self) -> bool { self.0.ip_suppressed() > 0 } + pub fn ip_suppressed(self) -> bool { + self.0.ip_suppressed() > 0 + } /// A flag indicating that the event is for status update. - pub fn status_update(self) -> bool { self.0.status_update() > 0 } + pub fn status_update(self) -> bool { + self.0.status_update() > 0 + } /// A flag indicating that the event has timing information. - pub fn has_tsc(self) -> bool { self.0.has_tsc() > 0 } + pub fn has_tsc(self) -> bool { + self.0.has_tsc() > 0 + } /// The time stamp count of the event. /// This field is only valid if \@has_tsc is set. - pub fn tsc(self) -> u64 { self.0.tsc } + pub fn tsc(self) -> u64 { + self.0.tsc + } /// The number of lost mtc packets. /// /// This gives an idea about the quality of the \@tsc. /// The more packets were dropped, the less precise timing is. - pub fn lost_mtc(self) -> u32 { self.0.lost_mtc } + pub fn lost_mtc(self) -> u32 { + self.0.lost_mtc + } /// The number of lost cyc packets. /// /// This gives an idea about the quality of the \@tsc. /// The more packets were dropped, the less precise timing is. - pub fn lost_cyc(self) -> u32 { self.0.lost_cyc } + pub fn lost_cyc(self) -> u32 { + self.0.lost_cyc + } /// Event specific data. - pub fn payload(self) -> Payload { self.0.into() } -} \ No newline at end of file + pub fn payload(self) -> Payload { + self.0.into() + } +} diff --git a/src/event/mwait.rs b/src/event/mwait.rs index 6d6ab43..b2cb4f1 100644 --- a/src/event/mwait.rs +++ b/src/event/mwait.rs @@ -2,10 +2,10 @@ use libipt_sys::pt_event__bindgen_ty_1__bindgen_ty_13; #[cfg(test)] mod test { - use super::*; use super::super::Payload; + use super::*; + use libipt_sys::{pt_event, pt_event_type_ptev_mwait}; use std::mem; - use libipt_sys::{ pt_event, pt_event_type_ptev_mwait }; #[test] fn test_mwait_payload() { @@ -14,7 +14,7 @@ mod test { evt.variant.mwait = pt_event__bindgen_ty_1__bindgen_ty_13 { ip: 11, hints: 22, - ext: 33 + ext: 33, }; let payload: Payload = evt.into(); @@ -23,8 +23,8 @@ mod test { assert_eq!(e.ip(), 11); assert_eq!(e.hints(), 22); assert_eq!(e.ext(), 33); - }, - _ => unreachable!("oof") + } + _ => unreachable!("oof"), } } } @@ -36,15 +36,21 @@ impl Mwait { /// The address of the instruction causing the mwait. /// /// This field is not valid, if @ip_suppressed is set. - pub fn ip(self) -> u64 { self.0.ip } + pub fn ip(self) -> u64 { + self.0.ip + } /// The mwait hints (eax). /// /// Reserved bits are undefined. - pub fn hints(self) -> u32 { self.0.hints } + pub fn hints(self) -> u32 { + self.0.hints + } /// The mwait extensions (ecx). /// /// Reserved bits are undefined. - pub fn ext(self) -> u32 { self.0.ext } -} \ No newline at end of file + pub fn ext(self) -> u32 { + self.0.ext + } +} diff --git a/src/event/overflow.rs b/src/event/overflow.rs index e93c6b0..280aabc 100644 --- a/src/event/overflow.rs +++ b/src/event/overflow.rs @@ -2,36 +2,36 @@ use libipt_sys::pt_event__bindgen_ty_1__bindgen_ty_7; #[cfg(test)] mod test { - use super::*; use super::super::Payload; + use super::*; + use libipt_sys::{pt_event, pt_event_type_ptev_overflow}; use std::mem; - use libipt_sys::{ pt_event, pt_event_type_ptev_overflow }; #[test] fn test_overflow_payload() { let mut evt: pt_event = unsafe { mem::zeroed() }; evt.type_ = pt_event_type_ptev_overflow; - evt.variant.overflow = pt_event__bindgen_ty_1__bindgen_ty_7 { - ip: 11 - }; + evt.variant.overflow = pt_event__bindgen_ty_1__bindgen_ty_7 { ip: 11 }; let payload: Payload = evt.into(); match payload { Payload::Overflow(e) => { assert_eq!(e.ip(), 11); - }, - _ => unreachable!("oof") + } + _ => unreachable!("oof"), } } } /// Trace overflow -#[derive(Clone, Copy, Debug)] +#[derive(Clone, Copy, Debug)] pub struct Overflow(pub(super) pt_event__bindgen_ty_1__bindgen_ty_7); impl Overflow { /// The address at which tracing resumes after overflow. /// /// This field is not valid, if ip_suppressed is set. /// In this case, the overflow resolved while tracing was disabled. - pub fn ip(self) -> u64 { self.0.ip } -} \ No newline at end of file + pub fn ip(self) -> u64 { + self.0.ip + } +} diff --git a/src/event/paging.rs b/src/event/paging.rs index 8d85eda..1883f4a 100644 --- a/src/event/paging.rs +++ b/src/event/paging.rs @@ -1,18 +1,11 @@ -use libipt_sys::{ - pt_event__bindgen_ty_1__bindgen_ty_5, - pt_event__bindgen_ty_1__bindgen_ty_6 -}; +use libipt_sys::{pt_event__bindgen_ty_1__bindgen_ty_5, pt_event__bindgen_ty_1__bindgen_ty_6}; #[cfg(test)] mod test { - use super::*; use super::super::Payload; + use super::*; + use libipt_sys::{pt_event, pt_event_type_ptev_async_paging, pt_event_type_ptev_paging}; use std::mem; - use libipt_sys::{ - pt_event, - pt_event_type_ptev_paging, - pt_event_type_ptev_async_paging - }; #[test] fn test_paging_payload() { @@ -22,7 +15,7 @@ mod test { cr3: 11, _bitfield_align_1: [], _bitfield_1: pt_event__bindgen_ty_1__bindgen_ty_5::new_bitfield_1(1), - __bindgen_padding_0: Default::default() + __bindgen_padding_0: Default::default(), }; let payload: Payload = evt.into(); @@ -30,8 +23,8 @@ mod test { Payload::Paging(e) => { assert_eq!(e.cr3(), 11); assert!(e.non_root()); - }, - _ => unreachable!("oof") + } + _ => unreachable!("oof"), } } @@ -52,8 +45,8 @@ mod test { assert_eq!(e.cr3(), 11); assert_eq!(e.ip(), 12); assert!(e.non_root()); - }, - _ => unreachable!("oof") + } + _ => unreachable!("oof"), } } } @@ -65,11 +58,15 @@ impl Paging { /// The updated CR3 value. /// The lower 5 bit have been zeroed out. /// The upper bits have been zeroed out depending on the maximum possible address. - pub fn cr3(self) -> u64 { self.0.cr3 } + pub fn cr3(self) -> u64 { + self.0.cr3 + } /// A flag indicating whether the cpu is operating in /// vmx non-root (guest) mode. - pub fn non_root(self) -> bool { self.0.non_root() > 0 } + pub fn non_root(self) -> bool { + self.0.non_root() > 0 + } } /// An asynchronous paging event @@ -81,10 +78,16 @@ impl AsyncPaging { /// The lower 5 bit have been zeroed out. /// The upper bits have been zeroed out depending on the /// maximum possible address. - pub fn cr3(self) -> u64 { self.0.cr3 } + pub fn cr3(self) -> u64 { + self.0.cr3 + } /// A flag indicating whether the cpu is operating in /// vmx non-root (guest) mode. - pub fn non_root(self) -> bool { self.0.non_root() > 0 } + pub fn non_root(self) -> bool { + self.0.non_root() > 0 + } /// The address at which the event is effective - pub fn ip(self) -> u64 { self.0.ip } -} \ No newline at end of file + pub fn ip(self) -> u64 { + self.0.ip + } +} diff --git a/src/event/ptwrite.rs b/src/event/ptwrite.rs index e519aa4..6dcf3e8 100644 --- a/src/event/ptwrite.rs +++ b/src/event/ptwrite.rs @@ -2,10 +2,10 @@ use libipt_sys::pt_event__bindgen_ty_1__bindgen_ty_16; #[cfg(test)] mod test { - use super::*; use super::super::Payload; + use super::*; + use libipt_sys::{pt_event, pt_event_type_ptev_ptwrite}; use std::mem; - use libipt_sys::{ pt_event, pt_event_type_ptev_ptwrite }; #[test] fn test_ptwrite_payload() { @@ -14,7 +14,7 @@ mod test { evt.variant.ptwrite = pt_event__bindgen_ty_1__bindgen_ty_16 { ip: 11, size: 22, - payload: 33 + payload: 33, }; let payload: Payload = evt.into(); @@ -23,8 +23,8 @@ mod test { assert_eq!(e.ip(), 11); assert_eq!(e.size(), 22); assert_eq!(e.payload(), 33); - }, - _ => unreachable!("oof") + } + _ => unreachable!("oof"), } } } @@ -37,9 +37,15 @@ impl Ptwrite { /// /// This field is not valid, if \@ip_suppressed is set. /// In this case, the address is obvious from the disassembly. - pub fn ip(self) -> u64 { self.0.ip } + pub fn ip(self) -> u64 { + self.0.ip + } /// The size of the below \@payload in bytes. - pub fn size(self) -> u8{ self.0.size } + pub fn size(self) -> u8 { + self.0.size + } /// The ptwrite payload. - pub fn payload(self) -> u64 { self.0.payload } -} \ No newline at end of file + pub fn payload(self) -> u64 { + self.0.payload + } +} diff --git a/src/event/pwre.rs b/src/event/pwre.rs index 9aa8dd8..53739f9 100644 --- a/src/event/pwre.rs +++ b/src/event/pwre.rs @@ -2,10 +2,10 @@ use libipt_sys::pt_event__bindgen_ty_1__bindgen_ty_14; #[cfg(test)] mod test { - use super::*; use super::super::Payload; + use super::*; + use libipt_sys::{pt_event, pt_event_type_ptev_pwre}; use std::mem; - use libipt_sys::{ pt_event, pt_event_type_ptev_pwre }; #[test] fn test_pwre_payload() { @@ -16,30 +16,36 @@ mod test { sub_state: 22, _bitfield_align_1: [], _bitfield_1: pt_event__bindgen_ty_1__bindgen_ty_14::new_bitfield_1(1), - __bindgen_padding_0: Default::default() + __bindgen_padding_0: Default::default(), }; let payload: Payload = evt.into(); match payload { - Payload::Pwre (e) => { + Payload::Pwre(e) => { assert_eq!(e.state(), 11); assert_eq!(e.sub_state(), 22); assert!(e.hw()) - }, - _ => unreachable!("oof") + } + _ => unreachable!("oof"), } } } /// A power state was entered -#[derive(Clone, Copy, Debug)] +#[derive(Clone, Copy, Debug)] pub struct Pwre(pub(super) pt_event__bindgen_ty_1__bindgen_ty_14); impl Pwre { /// The resolved thread C-state. - pub fn state(self) -> u8 { self.0.state } + pub fn state(self) -> u8 { + self.0.state + } /// The resolved thread sub C-state - pub fn sub_state(self) -> u8 { self.0.sub_state } + pub fn sub_state(self) -> u8 { + self.0.sub_state + } /// A flag indicating whether the C-state entry was /// initiated by h/w. - pub fn hw(self) -> bool { self.0.hw() > 0 } -} \ No newline at end of file + pub fn hw(self) -> bool { + self.0.hw() > 0 + } +} diff --git a/src/event/pwrx.rs b/src/event/pwrx.rs index ef36767..e3a7bdb 100644 --- a/src/event/pwrx.rs +++ b/src/event/pwrx.rs @@ -2,10 +2,10 @@ use libipt_sys::pt_event__bindgen_ty_1__bindgen_ty_15; #[cfg(test)] mod test { - use super::*; use super::super::Payload; + use super::*; + use libipt_sys::{pt_event, pt_event_type_ptev_pwrx}; use std::mem; - use libipt_sys::{ pt_event, pt_event_type_ptev_pwrx }; #[test] fn test_pwrx_payload() { @@ -16,7 +16,7 @@ mod test { deepest: 22, _bitfield_align_1: [], _bitfield_1: pt_event__bindgen_ty_1__bindgen_ty_15::new_bitfield_1(1, 0, 1), - __bindgen_padding_0: Default::default() + __bindgen_padding_0: Default::default(), }; let payload: Payload = evt.into(); @@ -27,8 +27,8 @@ mod test { assert!(e.interrupt()); assert!(!e.store()); assert!(e.autonomous()); - }, - _ => unreachable!("oof") + } + _ => unreachable!("oof"), } } } @@ -38,19 +38,29 @@ mod test { pub struct Pwrx(pub(super) pt_event__bindgen_ty_1__bindgen_ty_15); impl Pwrx { /// The core C-state at the time of the wake. - pub fn last(self) -> u8 { self.0.last } + pub fn last(self) -> u8 { + self.0.last + } /// The deepest core C-state achieved during sleep. - pub fn deepest(self) -> u8 { self.0.deepest } + pub fn deepest(self) -> u8 { + self.0.deepest + } /// The wake reason: /// /// - due to external interrupt received. - pub fn interrupt(self) -> bool { self.0.interrupt() > 0 } + pub fn interrupt(self) -> bool { + self.0.interrupt() > 0 + } /// The wake reason: /// /// - due to store to monitored address. - pub fn store(self) -> bool { self.0.store() > 0 } + pub fn store(self) -> bool { + self.0.store() > 0 + } /// The wake reason: /// /// - due to h/w autonomous condition such as HDC. - pub fn autonomous(self) -> bool { self.0.autonomous() > 0 } -} \ No newline at end of file + pub fn autonomous(self) -> bool { + self.0.autonomous() > 0 + } +} diff --git a/src/event/qry.rs b/src/event/qry.rs index fa0e35b..8e1f7d7 100644 --- a/src/event/qry.rs +++ b/src/event/qry.rs @@ -1,34 +1,21 @@ +use crate::config::Config; use crate::error::{ - PtError, deref_ptresult, - ensure_ptok, extract_pterr, - deref_ptresult_mut, PtErrorCode + deref_ptresult, deref_ptresult_mut, ensure_ptok, extract_pterr, PtError, PtErrorCode, }; -use crate::config::Config; -use crate::Status; use crate::event::Event; +use crate::Status; use std::convert::TryFrom; use std::marker::PhantomData; use std::mem; -use num_enum::TryFromPrimitive; use libipt_sys::{ - pt_qry_alloc_decoder, - pt_query_decoder, - pt_qry_cond_branch, - pt_qry_core_bus_ratio, - pt_qry_event, - pt_event, - pt_qry_free_decoder, - pt_qry_get_config, - pt_qry_get_offset, - pt_qry_get_sync_offset, - pt_qry_indirect_branch, - pt_qry_sync_backward, - pt_qry_sync_forward, - pt_qry_sync_set, - pt_qry_time + pt_event, pt_qry_alloc_decoder, pt_qry_cond_branch, pt_qry_core_bus_ratio, pt_qry_event, + pt_qry_free_decoder, pt_qry_get_config, pt_qry_get_offset, pt_qry_get_sync_offset, + pt_qry_indirect_branch, pt_qry_sync_backward, pt_qry_sync_forward, pt_qry_sync_set, + pt_qry_time, pt_query_decoder, }; +use num_enum::TryFromPrimitive; #[cfg(test)] mod test { @@ -38,19 +25,15 @@ mod test { #[test] fn test_qrydec_alloc() { let kek = &mut [2; 1]; - QueryDecoder::new( - &ConfigBuilder::new(kek).unwrap().finish() - ).unwrap(); + QueryDecoder::new(&ConfigBuilder::new(kek).unwrap().finish()).unwrap(); } - #[test ] + #[test] fn test_qrydec_props() { let kek = &mut [2; 3]; // this just checks memory safety for property access // usage can be found in the integration tests - let mut b = QueryDecoder::new( - &ConfigBuilder::new(kek).unwrap().finish() - ).unwrap(); + let mut b = QueryDecoder::new(&ConfigBuilder::new(kek).unwrap().finish()).unwrap(); assert!(b.cond_branch().is_err()); assert!(b.indirect_branch().is_err()); @@ -70,7 +53,7 @@ mod test { #[repr(i32)] pub enum CondBranch { Taken = 1, - NotTaken = 0 + NotTaken = 0, } /// The decoder will work on the buffer defined in the config, @@ -99,10 +82,12 @@ impl QueryDecoder<'_, T> { /// Returns Nosync if decoder is out of sync. pub fn cond_branch(&mut self) -> Result<(CondBranch, Status), PtError> { let mut taken: i32 = 0; - extract_pterr(unsafe { pt_qry_cond_branch(self.0, &mut taken) }) - .map(|s| ( + extract_pterr(unsafe { pt_qry_cond_branch(self.0, &mut taken) }).map(|s| { + ( CondBranch::try_from(taken).unwrap(), - Status::from_bits(s).unwrap())) + Status::from_bits(s).unwrap(), + ) + }) } /// Return the current core bus ratio. @@ -112,8 +97,7 @@ impl QueryDecoder<'_, T> { /// Returns NoCbr if there has not been a CBR packet. pub fn core_bus_ratio(&mut self) -> Result { let mut cbr: u32 = 0; - ensure_ptok(unsafe { pt_qry_core_bus_ratio(self.0, &mut cbr) }) - .map(|_| cbr) + ensure_ptok(unsafe { pt_qry_core_bus_ratio(self.0, &mut cbr) }).map(|_| cbr) } /// Query the next pending event. @@ -126,16 +110,12 @@ impl QueryDecoder<'_, T> { /// Returns Nosync if decoder is out of sync. pub fn event(&mut self) -> Result<(Event, Status), PtError> { let mut evt: pt_event = unsafe { mem::zeroed() }; - extract_pterr(unsafe { - pt_qry_event(self.0, - &mut evt, - mem::size_of::()) - }).map(|s| (Event(evt), Status::from_bits(s).unwrap())) + extract_pterr(unsafe { pt_qry_event(self.0, &mut evt, mem::size_of::()) }) + .map(|s| (Event(evt), Status::from_bits(s).unwrap())) } pub fn config(&self) -> Result, PtError> { - deref_ptresult(unsafe { pt_qry_get_config(self.0) }) - .map(Config::from) + deref_ptresult(unsafe { pt_qry_get_config(self.0) }).map(Config::from) } /// Get the current decoder position. @@ -143,8 +123,7 @@ impl QueryDecoder<'_, T> { /// Returns Nosync if decoder is out of sync. pub fn offset(&self) -> Result { let mut off: u64 = 0; - ensure_ptok(unsafe { pt_qry_get_offset(self.0, &mut off) }) - .map(|_| off) + ensure_ptok(unsafe { pt_qry_get_offset(self.0, &mut off) }).map(|_| off) } /// Get the position of the last synchronization point. @@ -153,8 +132,7 @@ impl QueryDecoder<'_, T> { /// Returns Nosync if decoder is out of sync. pub fn sync_offset(&self) -> Result { let mut off: u64 = 0; - ensure_ptok(unsafe { pt_qry_get_sync_offset(self.0, &mut off) }) - .map(|_| off) + ensure_ptok(unsafe { pt_qry_get_sync_offset(self.0, &mut off) }).map(|_| off) } /// Get the next indirect branch destination. @@ -185,7 +163,7 @@ impl QueryDecoder<'_, T> { /// Returns Eos if no further synchronization point is found. pub fn sync_backward(&mut self) -> Result<(u64, Status), PtError> { let mut ip: u64 = 0; - extract_pterr(unsafe { pt_qry_sync_backward(self.0, &mut ip)}) + extract_pterr(unsafe { pt_qry_sync_backward(self.0, &mut ip) }) .map(|s| (ip, Status::from_bits(s).unwrap())) } @@ -217,7 +195,7 @@ impl QueryDecoder<'_, T> { /// Returns Nosync if there is no syncpoint at @offset. pub fn sync_set(&mut self, offset: u64) -> Result<(u64, Status), PtError> { let mut ip: u64 = 0; - extract_pterr(unsafe { pt_qry_sync_set(self.0, &mut ip, offset)}) + extract_pterr(unsafe { pt_qry_sync_set(self.0, &mut ip, offset) }) .map(|s| (ip, Status::from_bits(s).unwrap())) } @@ -237,12 +215,8 @@ impl QueryDecoder<'_, T> { let mut time: u64 = 0; let mut mtc: u32 = 0; let mut cyc: u32 = 0; - ensure_ptok(unsafe { - pt_qry_time(self.0, - &mut time, - &mut mtc, - &mut cyc) - }).map(|_| (time, mtc, cyc)) + ensure_ptok(unsafe { pt_qry_time(self.0, &mut time, &mut mtc, &mut cyc) }) + .map(|_| (time, mtc, cyc)) } } @@ -253,11 +227,13 @@ impl Iterator for QueryDecoder<'_, T> { match self.event() { // eos to stop iterating Err(x) if x.code() == PtErrorCode::Eos => None, - x => Some(x) + x => Some(x), } } } impl Drop for QueryDecoder<'_, T> { - fn drop(&mut self) { unsafe { pt_qry_free_decoder(self.0) }} + fn drop(&mut self) { + unsafe { pt_qry_free_decoder(self.0) } + } } diff --git a/src/event/tick.rs b/src/event/tick.rs index cbbd9cd..0e883aa 100644 --- a/src/event/tick.rs +++ b/src/event/tick.rs @@ -2,25 +2,23 @@ use libipt_sys::pt_event__bindgen_ty_1__bindgen_ty_17; #[cfg(test)] mod test { - use super::*; use super::super::Payload; + use super::*; + use libipt_sys::{pt_event, pt_event_type_ptev_tick}; use std::mem; - use libipt_sys::{ pt_event, pt_event_type_ptev_tick}; #[test] fn test_tick_payload() { let mut evt: pt_event = unsafe { mem::zeroed() }; evt.type_ = pt_event_type_ptev_tick; - evt.variant.tick = pt_event__bindgen_ty_1__bindgen_ty_17 { - ip: 11, - }; + evt.variant.tick = pt_event__bindgen_ty_1__bindgen_ty_17 { ip: 11 }; let payload: Payload = evt.into(); match payload { Payload::Tick(e) => { assert_eq!(e.ip(), 11); - }, - _ => unreachable!("oof") + } + _ => unreachable!("oof"), } } } @@ -36,5 +34,7 @@ impl Tick { /// receives CYC + TIP) and sometimes not (e.g. MTC). /// /// This field is not valid, if \@ip_suppressed is set. - pub fn ip(self) -> u64 { self.0.ip } -} \ No newline at end of file + pub fn ip(self) -> u64 { + self.0.ip + } +} diff --git a/src/event/tsx.rs b/src/event/tsx.rs index 5c505ae..bcd8f4c 100644 --- a/src/event/tsx.rs +++ b/src/event/tsx.rs @@ -2,10 +2,10 @@ use libipt_sys::pt_event__bindgen_ty_1__bindgen_ty_9; #[cfg(test)] mod test { - use super::*; use super::super::Payload; + use super::*; + use libipt_sys::{pt_event, pt_event_type_ptev_tsx}; use std::mem; - use libipt_sys::{ pt_event, pt_event_type_ptev_tsx }; #[test] fn test_tsx_payload() { @@ -15,7 +15,7 @@ mod test { ip: 11, _bitfield_align_1: [], _bitfield_1: pt_event__bindgen_ty_1__bindgen_ty_9::new_bitfield_1(1, 0), - __bindgen_padding_0: Default::default() + __bindgen_padding_0: Default::default(), }; let payload: Payload = evt.into(); @@ -24,8 +24,8 @@ mod test { assert_eq!(e.ip(), 11); assert!(e.speculative()); assert!(!e.aborted()); - }, - _ => unreachable!("oof") + } + _ => unreachable!("oof"), } } } @@ -37,11 +37,17 @@ impl Tsx { /// The address at which the event is effective. /// /// This field is not valid if @ip_suppressed is set. - pub fn ip(self) -> u64 { self.0.ip } + pub fn ip(self) -> u64 { + self.0.ip + } /// A flag indicating speculative execution mode - pub fn speculative(self) -> bool { self.0.speculative() > 0 } + pub fn speculative(self) -> bool { + self.0.speculative() > 0 + } /// A flag indicating speculative execution aborts - pub fn aborted(self) -> bool { self.0.aborted() > 0 } -} \ No newline at end of file + pub fn aborted(self) -> bool { + self.0.aborted() > 0 + } +} diff --git a/src/event/vmcs.rs b/src/event/vmcs.rs index d430ade..8ac42b2 100644 --- a/src/event/vmcs.rs +++ b/src/event/vmcs.rs @@ -1,33 +1,24 @@ -use libipt_sys::{ - pt_event__bindgen_ty_1__bindgen_ty_10, - pt_event__bindgen_ty_1__bindgen_ty_11 -}; +use libipt_sys::{pt_event__bindgen_ty_1__bindgen_ty_10, pt_event__bindgen_ty_1__bindgen_ty_11}; #[cfg(test)] mod test { - use super::*; use super::super::Payload; + use super::*; + use libipt_sys::{pt_event, pt_event_type_ptev_async_vmcs, pt_event_type_ptev_vmcs}; use std::mem; - use libipt_sys::{ - pt_event, - pt_event_type_ptev_vmcs, - pt_event_type_ptev_async_vmcs - }; #[test] fn test_vmcs_payload() { let mut evt: pt_event = unsafe { mem::zeroed() }; evt.type_ = pt_event_type_ptev_vmcs; - evt.variant.vmcs = pt_event__bindgen_ty_1__bindgen_ty_10 { - base: 11, - }; + evt.variant.vmcs = pt_event__bindgen_ty_1__bindgen_ty_10 { base: 11 }; let payload: Payload = evt.into(); match payload { Payload::Vmcs(e) => { assert_eq!(e.base(), 11); - }, - _ => unreachable!("oof") + } + _ => unreachable!("oof"), } } @@ -35,18 +26,15 @@ mod test { fn test_async_vmcs_payload() { let mut evt: pt_event = unsafe { mem::zeroed() }; evt.type_ = pt_event_type_ptev_async_vmcs; - evt.variant.async_vmcs = pt_event__bindgen_ty_1__bindgen_ty_11 { - base: 11, - ip: 12 - }; + evt.variant.async_vmcs = pt_event__bindgen_ty_1__bindgen_ty_11 { base: 11, ip: 12 }; let payload: Payload = evt.into(); match payload { Payload::AsyncVmcs(e) => { assert_eq!(e.base(), 11); assert_eq!(e.ip(), 12); - }, - _ => unreachable!("oof") + } + _ => unreachable!("oof"), } } } @@ -56,9 +44,11 @@ mod test { pub struct Vmcs(pub(super) pt_event__bindgen_ty_1__bindgen_ty_10); impl Vmcs { /// The VMCS base address. - /// + /// /// The address is zero-extended with the lower 12 bits all zero - pub fn base(self) -> u64 { self.0.base } + pub fn base(self) -> u64 { + self.0.base + } } /// An asynchronous vmcs event @@ -68,8 +58,12 @@ impl AsyncVmcs { /// The VMCS base address. /// /// The address is zero-extended with the lower 12 bits all zero - pub fn base(self) -> u64 { self.0.base } + pub fn base(self) -> u64 { + self.0.base + } /// The address at which the event is effective. - pub fn ip(self) -> u64 { self.0.ip } -} \ No newline at end of file + pub fn ip(self) -> u64 { + self.0.ip + } +} diff --git a/src/flags.rs b/src/flags.rs index 2cbc321..a69a466 100644 --- a/src/flags.rs +++ b/src/flags.rs @@ -1,12 +1,10 @@ // Certain casts are required only on Windows. Inform Clippy to ignore them. #![allow(clippy::unnecessary_cast)] +use bitflags::bitflags; use libipt_sys::{ - pt_status_flag_pts_eos, - pt_status_flag_pts_event_pending, - pt_status_flag_pts_ip_suppressed + pt_status_flag_pts_eos, pt_status_flag_pts_event_pending, pt_status_flag_pts_ip_suppressed, }; -use bitflags::bitflags; bitflags! { /// Status flags for various IntelPT actions @@ -22,9 +20,15 @@ bitflags! { impl Status { /// There is no more trace data available. - pub fn eos(&self) -> bool { self.contains(Status::EOS) } + pub fn eos(&self) -> bool { + self.contains(Status::EOS) + } /// There is an event pending. - pub fn event_pending(&self) -> bool { self.contains(Status::EVENT_PENDING) } + pub fn event_pending(&self) -> bool { + self.contains(Status::EVENT_PENDING) + } /// The address has been suppressed. - pub fn ip_supressed(&self) -> bool { self.contains(Status::IP_SUPRESSED) } -} \ No newline at end of file + pub fn ip_supressed(&self) -> bool { + self.contains(Status::IP_SUPRESSED) + } +} diff --git a/src/image/iscache.rs b/src/image/iscache.rs index 9b4c578..9bfdb2b 100644 --- a/src/image/iscache.rs +++ b/src/image/iscache.rs @@ -1,30 +1,20 @@ use crate::error::{ - PtError, - PtErrorCode, - deref_ptresult, - deref_ptresult_mut, - ensure_ptok, - extract_pterr + deref_ptresult, deref_ptresult_mut, ensure_ptok, extract_pterr, PtError, PtErrorCode, }; -use std::ffi::{CString, CStr}; +use std::ffi::{CStr, CString}; use std::ptr; use libipt_sys::{ - pt_image_section_cache, - pt_iscache_add_file, - pt_iscache_alloc, - pt_iscache_name, - pt_iscache_read, - pt_iscache_set_limit, - pt_iscache_free + pt_image_section_cache, pt_iscache_add_file, pt_iscache_alloc, pt_iscache_free, + pt_iscache_name, pt_iscache_read, pt_iscache_set_limit, }; #[cfg(test)] mod test { use super::*; - use std::path::PathBuf; use std::fs; + use std::path::PathBuf; #[test] fn test_isc_alloc() { @@ -42,27 +32,26 @@ mod test { #[test] fn test_isc_file() { - let file: PathBuf = [ - env!("CARGO_MANIFEST_DIR"), "testfiles", "garbage.txt" - ].iter().collect(); + let file: PathBuf = [env!("CARGO_MANIFEST_DIR"), "testfiles", "garbage.txt"] + .iter() + .collect(); println!("{:?}", file); - SectionCache::new(None).unwrap() - .add_file(file.to_str().unwrap(), 5, 15, 0x1337).unwrap(); + SectionCache::new(None) + .unwrap() + .add_file(file.to_str().unwrap(), 5, 15, 0x1337) + .unwrap(); } #[test] fn test_isc_memsection() { - let file: PathBuf = - [env!("CARGO_MANIFEST_DIR"), "testfiles", "garbage.txt"] - .iter() - .collect(); + let file: PathBuf = [env!("CARGO_MANIFEST_DIR"), "testfiles", "garbage.txt"] + .iter() + .collect(); println!("{:?}", file); let mut isc = SectionCache::new(None).unwrap(); - let isid = isc - .add_file(file.to_str().unwrap(), 5, 24, 0x666) - .unwrap(); + let isid = isc.add_file(file.to_str().unwrap(), 5, 24, 0x666).unwrap(); let mut buf = [0; 20]; isc.read(&mut buf, isid, 0x66A).unwrap(); @@ -90,14 +79,22 @@ impl SectionCache<'_> { /// The name string is copied. /// Returns a new traced memory image section cache on success pub fn new(name: Option<&str>) -> Result { - deref_ptresult_mut(unsafe { match name { - None => pt_iscache_alloc(ptr::null()), - Some(n) => pt_iscache_alloc( - CString::new(n).map_err(|_| PtError::new( - PtErrorCode::Invalid, - "invalid @name string: contains null bytes") - )?.as_ptr()) - }}).map(SectionCache) + deref_ptresult_mut(unsafe { + match name { + None => pt_iscache_alloc(ptr::null()), + Some(n) => pt_iscache_alloc( + CString::new(n) + .map_err(|_| { + PtError::new( + PtErrorCode::Invalid, + "invalid @name string: contains null bytes", + ) + })? + .as_ptr(), + ), + } + }) + .map(SectionCache) } /// Get the image section cache name. @@ -105,10 +102,12 @@ impl SectionCache<'_> { pub fn name(&self) -> Option<&str> { deref_ptresult(unsafe { pt_iscache_name(self.0) }) .ok() - .map(|s| unsafe { CStr::from_ptr(s) }.to_str().expect( - concat!("failed converting name c-string.", - "this is a bug in either libipt or the bindings") - )) + .map(|s| { + unsafe { CStr::from_ptr(s) }.to_str().expect(concat!( + "failed converting name c-string.", + "this is a bug in either libipt or the bindings" + )) + }) } /// Add a new file section to the traced memory image section cache. @@ -118,22 +117,22 @@ impl SectionCache<'_> { /// Returns an image section identifier (isid) uniquely identifying that section in @iscache. /// The section is silently truncated to match the size of @filename. /// Returns Invalid if @offset is too big. - pub fn add_file(&mut self, - filename: &str, - offset: u64, - size: u64, - vaddr: u64) -> Result { - let cfilename = CString::new(filename) - .map_err(|_| PtError::new( PtErrorCode::Invalid, - "Error converting filename to Cstring as it contains null bytes") - )?; + pub fn add_file( + &mut self, + filename: &str, + offset: u64, + size: u64, + vaddr: u64, + ) -> Result { + let cfilename = CString::new(filename).map_err(|_| { + PtError::new( + PtErrorCode::Invalid, + "Error converting filename to Cstring as it contains null bytes", + ) + })?; extract_pterr(unsafe { - pt_iscache_add_file(self.0, - cfilename.as_ptr(), - offset, - size, - vaddr) + pt_iscache_add_file(self.0, cfilename.as_ptr(), offset, size, vaddr) }) } @@ -146,16 +145,15 @@ impl SectionCache<'_> { /// Returns number of bytes read on success. /// Returns Nomap if @vaddr is not contained in section @isid. /// Returns BadImage if @iscache does not contain @isid. - pub fn read(&mut self, - buffer: &mut [u8], - isid: u32, - vaddr: u64) -> Result { - extract_pterr(unsafe { - pt_iscache_read(self.0, - buffer.as_mut_ptr(), - buffer.len() as u64, - isid as i32, - vaddr) + pub fn read(&mut self, buffer: &mut [u8], isid: u32, vaddr: u64) -> Result { + extract_pterr(unsafe { + pt_iscache_read( + self.0, + buffer.as_mut_ptr(), + buffer.len() as u64, + isid as i32, + vaddr, + ) }) } @@ -173,4 +171,4 @@ impl Drop for SectionCache<'_> { fn drop(&mut self) { unsafe { pt_iscache_free(self.0) } } -} \ No newline at end of file +} diff --git a/src/image/mod.rs b/src/image/mod.rs index 5879a7c..7bac11d 100644 --- a/src/image/mod.rs +++ b/src/image/mod.rs @@ -2,4 +2,4 @@ mod image; mod iscache; pub use image::*; -pub use iscache::*; \ No newline at end of file +pub use iscache::*; diff --git a/src/insn/class.rs b/src/insn/class.rs index fd2f072..7cdbb28 100644 --- a/src/insn/class.rs +++ b/src/insn/class.rs @@ -1,19 +1,13 @@ // Certain casts are required only on Windows. Inform Clippy to ignore them. #![allow(clippy::unnecessary_cast)] -use num_enum::TryFromPrimitive; use libipt_sys::{ - pt_insn_class_ptic_call, - pt_insn_class_ptic_cond_jump, - pt_insn_class_ptic_error, - pt_insn_class_ptic_far_call, - pt_insn_class_ptic_far_jump, - pt_insn_class_ptic_far_return, - pt_insn_class_ptic_jump, - pt_insn_class_ptic_other, - pt_insn_class_ptic_ptwrite, - pt_insn_class_ptic_return + pt_insn_class_ptic_call, pt_insn_class_ptic_cond_jump, pt_insn_class_ptic_error, + pt_insn_class_ptic_far_call, pt_insn_class_ptic_far_jump, pt_insn_class_ptic_far_return, + pt_insn_class_ptic_jump, pt_insn_class_ptic_other, pt_insn_class_ptic_ptwrite, + pt_insn_class_ptic_return, }; +use num_enum::TryFromPrimitive; /// The instruction class. /// @@ -45,4 +39,4 @@ pub enum Class { Ptwrite = pt_insn_class_ptic_ptwrite as u32, /// The instruction is a near (function) return. Return = pt_insn_class_ptic_return as u32, -} \ No newline at end of file +} diff --git a/src/insn/decoder.rs b/src/insn/decoder.rs index d75ef9d..7914b38 100644 --- a/src/insn/decoder.rs +++ b/src/insn/decoder.rs @@ -1,39 +1,22 @@ +use super::Insn; +use crate::config::Config; use crate::error::{ - PtError, deref_ptresult, - deref_ptresult_mut, PtErrorCode, - ensure_ptok, extract_pterr + deref_ptresult, deref_ptresult_mut, ensure_ptok, extract_pterr, PtError, PtErrorCode, }; -use crate::config::Config; -use crate::Asid; use crate::event::Event; -use crate::Status; +use crate::Asid; use crate::Image; -use super::Insn; +use crate::Status; +use std::marker::PhantomData; use std::mem; use std::ptr; -use std::marker::PhantomData; use libipt_sys::{ - pt_insn_decoder, - pt_insn_alloc_decoder, - pt_insn_asid, - pt_asid, - pt_insn_core_bus_ratio, - pt_insn_event, - pt_event, - pt_insn_free_decoder, - pt_insn_get_config, - pt_insn_get_image, - pt_insn_get_offset, - pt_insn_get_sync_offset, - pt_insn_next, - pt_insn, - pt_insn_set_image, - pt_insn_sync_backward, - pt_insn_sync_forward, - pt_insn_sync_set, - pt_insn_time + pt_asid, pt_event, pt_insn, pt_insn_alloc_decoder, pt_insn_asid, pt_insn_core_bus_ratio, + pt_insn_decoder, pt_insn_event, pt_insn_free_decoder, pt_insn_get_config, pt_insn_get_image, + pt_insn_get_offset, pt_insn_get_sync_offset, pt_insn_next, pt_insn_set_image, + pt_insn_sync_backward, pt_insn_sync_forward, pt_insn_sync_set, pt_insn_time, }; #[cfg(test)] @@ -44,18 +27,15 @@ mod test { #[test] fn test_insndec_alloc() { let kek = &mut [1; 2]; - InsnDecoder::new(&ConfigBuilder::new(kek).unwrap().finish()) - .unwrap(); + InsnDecoder::new(&ConfigBuilder::new(kek).unwrap().finish()).unwrap(); } - #[test ] + #[test] fn test_insndec_props() { let kek = &mut [1; 2]; // this just checks memory safety for property access // usage can be found in the integration tests - let mut b = InsnDecoder::new( - &ConfigBuilder::new(kek).unwrap().finish() - ).unwrap(); + let mut b = InsnDecoder::new(&ConfigBuilder::new(kek).unwrap().finish()).unwrap(); let a = b.asid().unwrap(); assert!(a.cr3().is_none()); @@ -93,11 +73,8 @@ impl InsnDecoder<'_, T> { /// Return the current address space identifier. pub fn asid(&self) -> Result { let mut asid: pt_asid = unsafe { mem::zeroed() }; - ensure_ptok(unsafe { - pt_insn_asid(self.0, - &mut asid, - mem::size_of::()) - }).map(|_| Asid(asid)) + ensure_ptok(unsafe { pt_insn_asid(self.0, &mut asid, mem::size_of::()) }) + .map(|_| Asid(asid)) } /// Return the current core bus ratio. @@ -107,8 +84,7 @@ impl InsnDecoder<'_, T> { /// Returns NoCbr if there has not been a CBR packet. pub fn core_bus_ratio(&mut self) -> Result { let mut cbr: u32 = 0; - ensure_ptok(unsafe { pt_insn_core_bus_ratio(self.0, &mut cbr) }) - .map(|_| cbr) + ensure_ptok(unsafe { pt_insn_core_bus_ratio(self.0, &mut cbr) }).map(|_| cbr) } /// Get the next pending event. @@ -117,16 +93,12 @@ impl InsnDecoder<'_, T> { /// Returns BadQuery if there is no event. pub fn event(&mut self) -> Result<(Event, Status), PtError> { let mut evt: pt_event = unsafe { mem::zeroed() }; - extract_pterr(unsafe { - pt_insn_event(self.0, - &mut evt, - mem::size_of::()) - }).map(|s| (Event(evt), Status::from_bits(s).unwrap())) + extract_pterr(unsafe { pt_insn_event(self.0, &mut evt, mem::size_of::()) }) + .map(|s| (Event(evt), Status::from_bits(s).unwrap())) } pub fn config(&self) -> Result, PtError> { - deref_ptresult(unsafe { pt_insn_get_config(self.0) }) - .map(Config::from) + deref_ptresult(unsafe { pt_insn_get_config(self.0) }).map(Config::from) } /// Get the traced image. @@ -134,8 +106,7 @@ impl InsnDecoder<'_, T> { /// The returned image may be modified as long as no decoder that uses this image is running. /// Returns the traced image the decoder uses for reading memory. pub fn image(&mut self) -> Result { - deref_ptresult_mut(unsafe { pt_insn_get_image(self.0) }) - .map(Image::from) + deref_ptresult_mut(unsafe { pt_insn_get_image(self.0) }).map(Image::from) } /// Get the current decoder position. @@ -143,8 +114,7 @@ impl InsnDecoder<'_, T> { /// Returns Nosync if decoder is out of sync. pub fn offset(&self) -> Result { let mut off: u64 = 0; - ensure_ptok(unsafe { pt_insn_get_offset(self.0, &mut off) }) - .map(|_| off) + ensure_ptok(unsafe { pt_insn_get_offset(self.0, &mut off) }).map(|_| off) } /// Get the position of the last synchronization point. @@ -152,8 +122,7 @@ impl InsnDecoder<'_, T> { /// Returns Nosync if @decoder is out of sync. pub fn sync_offset(&self) -> Result { let mut off = 0; - ensure_ptok(unsafe { pt_insn_get_sync_offset(self.0, &mut off) }) - .map(|_| off) + ensure_ptok(unsafe { pt_insn_get_sync_offset(self.0, &mut off) }).map(|_| off) } /// Determine the next instruction. @@ -170,11 +139,8 @@ impl InsnDecoder<'_, T> { /// Returns Nosync if decoder is out of sync. pub fn next(&mut self) -> Result<(Insn, Status), PtError> { let mut insn: pt_insn = unsafe { mem::zeroed() }; - extract_pterr(unsafe { - pt_insn_next(self.0, - &mut insn, - mem::size_of::()) - }).map(|s| (Insn(insn), Status::from_bits(s).unwrap())) + extract_pterr(unsafe { pt_insn_next(self.0, &mut insn, mem::size_of::()) }) + .map(|s| (Insn(insn), Status::from_bits(s).unwrap())) } /// Set the traced image. @@ -184,11 +150,13 @@ impl InsnDecoder<'_, T> { /// Only one image can be active at any time. pub fn set_image(&mut self, img: Option<&mut Image>) -> Result<(), PtError> { ensure_ptok(unsafe { - pt_insn_set_image(self.0, - match img { - None => ptr::null_mut(), - Some(i) => i.inner - }) + pt_insn_set_image( + self.0, + match img { + None => ptr::null_mut(), + Some(i) => i.inner, + }, + ) }) } @@ -242,14 +210,8 @@ impl InsnDecoder<'_, T> { let mut time: u64 = 0; let mut lost_mtc: u32 = 0; let mut lost_cyc: u32 = 0; - ensure_ptok( - unsafe { - pt_insn_time(self.0, - &mut time, - &mut lost_mtc, - &mut lost_cyc) - } - ).map(|_| (time, lost_mtc, lost_cyc)) + ensure_ptok(unsafe { pt_insn_time(self.0, &mut time, &mut lost_mtc, &mut lost_cyc) }) + .map(|_| (time, lost_mtc, lost_cyc)) } } @@ -260,11 +222,13 @@ impl Iterator for InsnDecoder<'_, T> { match self.next() { // eos to stop iterating Err(x) if x.code() == PtErrorCode::Eos => None, - x => Some(x) + x => Some(x), } } } impl Drop for InsnDecoder<'_, T> { - fn drop(&mut self) { unsafe { pt_insn_free_decoder(self.0) } } -} \ No newline at end of file + fn drop(&mut self) { + unsafe { pt_insn_free_decoder(self.0) } + } +} diff --git a/src/insn/insn.rs b/src/insn/insn.rs index c226437..c24a414 100644 --- a/src/insn/insn.rs +++ b/src/insn/insn.rs @@ -1,8 +1,8 @@ // Certain casts are required only on Windows. Inform Clippy to ignore them. #![allow(clippy::unnecessary_cast)] -use crate::event::ExecModeType; use super::Class; +use crate::event::ExecModeType; use std::convert::TryFrom; @@ -11,13 +11,13 @@ use libipt_sys::pt_insn; #[cfg(test)] mod test { use super::*; - use libipt_sys::pt_insn_class_ptic_call; use libipt_sys::pt_exec_mode_ptem_32bit; + use libipt_sys::pt_insn_class_ptic_call; #[test] fn test_insn_props() { let data: [u8; 15] = [17; 15]; - let blk = Insn(pt_insn{ + let blk = Insn(pt_insn { ip: 1, isid: 2, mode: pt_exec_mode_ptem_32bit, @@ -26,16 +26,16 @@ mod test { size: 8, _bitfield_align_1: [], _bitfield_1: pt_insn::new_bitfield_1(0, 1), - __bindgen_padding_0: Default::default() - }); + __bindgen_padding_0: Default::default(), + }); - assert_eq!(blk.ip(), 1); - assert_eq!(blk.isid(), 2); - assert_eq!(blk.mode(), ExecModeType::Bit32); - assert_eq!(blk.class(), Class::Call); - assert_eq!(blk.raw(), &data[..8]); - assert!(blk.truncated()); - assert!(!blk.speculative()); + assert_eq!(blk.ip(), 1); + assert_eq!(blk.isid(), 2); + assert_eq!(blk.mode(), ExecModeType::Bit32); + assert_eq!(blk.class(), Class::Call); + assert_eq!(blk.raw(), &data[..8]); + assert!(blk.truncated()); + assert!(!blk.speculative()); } } @@ -44,25 +44,31 @@ mod test { pub struct Insn(pub(crate) pt_insn); impl Insn { /// The virtual address in its process. - pub fn ip(self) -> u64 { self.0.ip } + pub fn ip(self) -> u64 { + self.0.ip + } /// The image section identifier for the section containing this instruction. /// /// A value of zero means that the section did not have an identifier. - pub fn isid(self) -> i32 { self.0.isid } + pub fn isid(self) -> i32 { + self.0.isid + } /// The execution mode. pub fn mode(self) -> ExecModeType { - ExecModeType::try_from(self.0.mode as u32) - .expect(concat!("unmatched ExecModeType enum value, ", - "this is a bug in either libipt or the bindings")) + ExecModeType::try_from(self.0.mode as u32).expect(concat!( + "unmatched ExecModeType enum value, ", + "this is a bug in either libipt or the bindings" + )) } /// A coarse classification. pub fn class(self) -> Class { - Class::try_from(self.0.iclass as u32) - .expect(concat!("unmatched Class enum value, ", - "this is a bug in either libipt or the bindings")) + Class::try_from(self.0.iclass as u32).expect(concat!( + "unmatched Class enum value, ", + "this is a bug in either libipt or the bindings" + )) } /// The size in bytes. @@ -73,13 +79,17 @@ impl Insn { /// A collection of flags giving additional information: /// /// - the instruction was executed speculatively. - pub fn speculative(self) -> bool { self.0.speculative() > 0 } - + pub fn speculative(self) -> bool { + self.0.speculative() > 0 + } + /// A collection of flags giving additional information: /// /// - this instruction is truncated in its image section. /// /// It starts in the image section identified by \@isid and continues /// in one or more other sections. - pub fn truncated(self) -> bool { self.0.truncated() > 0 } -} \ No newline at end of file + pub fn truncated(self) -> bool { + self.0.truncated() > 0 + } +} diff --git a/src/insn/mod.rs b/src/insn/mod.rs index d700a45..cae8145 100644 --- a/src/insn/mod.rs +++ b/src/insn/mod.rs @@ -3,4 +3,4 @@ mod decoder; mod insn; pub use class::*; pub use decoder::*; -pub use insn::*; \ No newline at end of file +pub use insn::*; diff --git a/src/lib.rs b/src/lib.rs index 1a94846..ab2a487 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -42,4 +42,4 @@ pub use image::*; mod asid; pub use asid::Asid; mod flags; -pub use flags::Status; \ No newline at end of file +pub use flags::Status; diff --git a/src/packet/cbr.rs b/src/packet/cbr.rs index 312647d..b36299d 100644 --- a/src/packet/cbr.rs +++ b/src/packet/cbr.rs @@ -3,18 +3,24 @@ use libipt_sys::{pt_packet_cbr, pt_packet_type_ppt_cbr}; /// A CBR packet. /// Packet: cbr #[derive(Clone, Copy, Debug)] -pub struct Cbr (pt_packet_cbr); +pub struct Cbr(pt_packet_cbr); impl Cbr { #[inline] - pub fn new(ratio: u8) -> Self { Cbr(pt_packet_cbr{ratio}) } + pub fn new(ratio: u8) -> Self { + Cbr(pt_packet_cbr { ratio }) + } #[inline] /// The core/bus cycle ratio - pub fn ratio(self) -> u8 { self.0.ratio } + pub fn ratio(self) -> u8 { + self.0.ratio + } #[inline] /// The core/bus cycle ratio - pub fn set_ratio(&mut self, ratio: u8) { self.0.ratio = ratio } + pub fn set_ratio(&mut self, ratio: u8) { + self.0.ratio = ratio + } } wrap2raw!(Cbr, pt_packet_type_ppt_cbr, cbr); diff --git a/src/packet/conversions.rs b/src/packet/conversions.rs index 4614c94..e79d330 100644 --- a/src/packet/conversions.rs +++ b/src/packet/conversions.rs @@ -6,7 +6,7 @@ macro_rules! wrap2raw { libipt_sys::pt_packet { type_: $type, size: std::mem::size_of::() as u8, - payload: libipt_sys::pt_packet__bindgen_ty_1 { $payload: origin.0 } + payload: libipt_sys::pt_packet__bindgen_ty_1 { $payload: origin.0 }, } } } @@ -17,7 +17,9 @@ macro_rules! raw2wrap { ($target:ty, $target_fac:expr, $origin:ty) => { impl Into<$target> for $origin { #[inline] - fn into(self) -> $target { $target_fac(self) } + fn into(self) -> $target { + $target_fac(self) + } } }; -} \ No newline at end of file +} diff --git a/src/packet/cyc.rs b/src/packet/cyc.rs index 992e6f3..2d24c23 100644 --- a/src/packet/cyc.rs +++ b/src/packet/cyc.rs @@ -3,18 +3,24 @@ use libipt_sys::{pt_packet_cyc, pt_packet_type_ppt_cyc}; /// A CYC packet. /// Packet: cyc #[derive(Clone, Copy, Debug)] -pub struct Cyc (pt_packet_cyc); +pub struct Cyc(pt_packet_cyc); impl Cyc { #[inline] - pub fn new(value: u64) -> Self { Cyc(pt_packet_cyc{value}) } + pub fn new(value: u64) -> Self { + Cyc(pt_packet_cyc { value }) + } #[inline] /// The cycle counter value - pub fn value(self) -> u64 { self.0.value } + pub fn value(self) -> u64 { + self.0.value + } #[inline] /// The cycle counter value - pub fn set_value(&mut self, value: u64) { self.0.value = value } + pub fn set_value(&mut self, value: u64) { + self.0.value = value + } } wrap2raw!(Cyc, pt_packet_type_ppt_cyc, cyc); diff --git a/src/packet/decoder.rs b/src/packet/decoder.rs index 9aeed3b..c6ac9ef 100644 --- a/src/packet/decoder.rs +++ b/src/packet/decoder.rs @@ -1,26 +1,14 @@ -use crate::error::{ - PtError, PtErrorCode, - deref_ptresult, deref_ptresult_mut, - ensure_ptok -}; use super::Packet; use crate::config::Config; +use crate::error::{deref_ptresult, deref_ptresult_mut, ensure_ptok, PtError, PtErrorCode}; -use std::mem; use std::marker::PhantomData; +use std::mem; use libipt_sys::{ - pt_packet_decoder, - pt_pkt_alloc_decoder, - pt_pkt_free_decoder, - pt_pkt_get_config, - pt_pkt_get_offset, - pt_pkt_get_sync_offset, - pt_pkt_next, - pt_packet, - pt_pkt_sync_backward, - pt_pkt_sync_forward, - pt_pkt_sync_set + pt_packet, pt_packet_decoder, pt_pkt_alloc_decoder, pt_pkt_free_decoder, pt_pkt_get_config, + pt_pkt_get_offset, pt_pkt_get_sync_offset, pt_pkt_next, pt_pkt_sync_backward, + pt_pkt_sync_forward, pt_pkt_sync_set, }; #[cfg(test)] @@ -31,20 +19,15 @@ mod test { #[test] fn test_pktdec_alloc() { let daturu = &mut [11; 11]; - PacketDecoder::new(&ConfigBuilder::new(daturu) - .unwrap() - .finish() - ).unwrap(); + PacketDecoder::new(&ConfigBuilder::new(daturu).unwrap().finish()).unwrap(); } - #[test ] + #[test] fn test_pktdec_props() { let daturu = &mut [11; 11]; // this just checks memory safety for property access // usage can be found in the integration tests - let mut p = PacketDecoder::new( - &ConfigBuilder::new(daturu).unwrap().finish() - ).unwrap(); + let mut p = PacketDecoder::new(&ConfigBuilder::new(daturu).unwrap().finish()).unwrap(); assert!(p.config().is_ok()); assert!(p.offset().is_err()); assert!(p.sync_offset().is_err()); @@ -67,8 +50,7 @@ impl PacketDecoder<'_, T> { } pub fn config(&self) -> Result, PtError> { - deref_ptresult(unsafe { pt_pkt_get_config(self.0) }) - .map(Config::from) + deref_ptresult(unsafe { pt_pkt_get_config(self.0) }).map(Config::from) } /// Get the current decoder position. @@ -76,8 +58,7 @@ impl PacketDecoder<'_, T> { /// Returns Nosync if decoder is out of sync. pub fn offset(&self) -> Result { let mut off: u64 = 0; - ensure_ptok(unsafe { pt_pkt_get_offset(self.0, &mut off) }) - .map(|_| off) + ensure_ptok(unsafe { pt_pkt_get_offset(self.0, &mut off) }).map(|_| off) } /// Get the position of the last synchronization point. @@ -86,8 +67,7 @@ impl PacketDecoder<'_, T> { /// Returns Nosync if decoder is out of sync. pub fn sync_offset(&self) -> Result { let mut off: u64 = 0; - ensure_ptok(unsafe { pt_pkt_get_sync_offset(self.0, &mut off) }) - .map(|_| off) + ensure_ptok(unsafe { pt_pkt_get_sync_offset(self.0, &mut off) }).map(|_| off) } /// Decode the next packet and advance the decoder. @@ -100,11 +80,8 @@ impl PacketDecoder<'_, T> { /// Returns Nosync if decoder is out of sync. pub fn next(&mut self) -> Result, PtError> { let mut pkt: pt_packet = unsafe { mem::zeroed() }; - ensure_ptok(unsafe { - pt_pkt_next(self.0, - &mut pkt, - mem::size_of::()) - }).map(|_| pkt.into()) + ensure_ptok(unsafe { pt_pkt_next(self.0, &mut pkt, mem::size_of::()) }) + .map(|_| pkt.into()) } pub fn sync_backward(&mut self) -> Result<(), PtError> { @@ -138,11 +115,13 @@ impl Iterator for PacketDecoder<'_, T> { match self.next() { // eos to stop iterating Err(x) if x.code() == PtErrorCode::Eos => None, - x => Some(x) + x => Some(x), } } } impl Drop for PacketDecoder<'_, T> { - fn drop(&mut self) { unsafe { pt_pkt_free_decoder(self.0) }} + fn drop(&mut self) { + unsafe { pt_pkt_free_decoder(self.0) } + } } diff --git a/src/packet/encoder.rs b/src/packet/encoder.rs index a0fa48d..7fb8a44 100644 --- a/src/packet/encoder.rs +++ b/src/packet/encoder.rs @@ -1,21 +1,11 @@ -use crate::error::{ - PtError, ensure_ptok, - extract_pterr, deref_ptresult, - deref_ptresult_mut -}; use crate::config::Config; +use crate::error::{deref_ptresult, deref_ptresult_mut, ensure_ptok, extract_pterr, PtError}; use std::marker::PhantomData; use libipt_sys::{ - pt_packet, - pt_encoder, - pt_alloc_encoder, - pt_free_encoder, - pt_enc_get_config, - pt_enc_get_offset, - pt_enc_next, - pt_enc_sync_set + pt_alloc_encoder, pt_enc_get_config, pt_enc_get_offset, pt_enc_next, pt_enc_sync_set, + pt_encoder, pt_free_encoder, pt_packet, }; #[cfg(test)] @@ -27,18 +17,15 @@ mod tests { #[test] fn test_pktdec_alloc() { let kek = &mut [1; 2]; - Encoder::new(&mut ConfigBuilder::new(kek).unwrap().finish()) - .unwrap(); + Encoder::new(&mut ConfigBuilder::new(kek).unwrap().finish()).unwrap(); } - #[test ] + #[test] fn test_pktdec_props() { let kek = &mut [1; 2]; // this just checks memory safety for property access // usage can be found in the integration tests - let mut p = Encoder::new( - &mut ConfigBuilder::new(kek).unwrap().finish() - ).unwrap(); + let mut p = Encoder::new(&mut ConfigBuilder::new(kek).unwrap().finish()).unwrap(); assert!(p.config().is_ok()); assert_eq!(p.offset().unwrap(), 0); @@ -59,8 +46,7 @@ impl Encoder<'_, T> { } pub fn config(&self) -> Result, PtError> { - deref_ptresult(unsafe{pt_enc_get_config(self.0)}) - .map(Config::from) + deref_ptresult(unsafe { pt_enc_get_config(self.0) }).map(Config::from) } /// Get the current packet encoder position. @@ -70,8 +56,7 @@ impl Encoder<'_, T> { /// Returns Invalid if @offset is NULL. pub fn offset(&self) -> Result { let mut off = 0; - ensure_ptok(unsafe{pt_enc_get_offset(self.0, &mut off)}) - .map(|_| off) + ensure_ptok(unsafe { pt_enc_get_offset(self.0, &mut off) }).map(|_| off) } /// Encode an Intel PT packet. @@ -83,7 +68,7 @@ impl Encoder<'_, T> { /// Returns BadPacket if @packet's payload is invalid. /// Returns Eos if the encoder reached the end of the Intel PT buffer. pub fn next(&mut self, pck: impl Into) -> Result { - extract_pterr(unsafe{ pt_enc_next(self.0, &pck.into()) }) + extract_pterr(unsafe { pt_enc_next(self.0, &pck.into()) }) } /// Hard set synchronization point of an Intel PT packet encoder. @@ -93,10 +78,12 @@ impl Encoder<'_, T> { /// Returns Eos if the given offset is behind the end of the trace buffer. /// Returns Invalid if the encoder is NULL. pub fn set_offset(&mut self, offset: u64) -> Result<(), PtError> { - ensure_ptok(unsafe{pt_enc_sync_set(self.0, offset)}) + ensure_ptok(unsafe { pt_enc_sync_set(self.0, offset) }) } } impl Drop for Encoder<'_, T> { - fn drop(&mut self) { unsafe { pt_free_encoder(self.0) } } -} \ No newline at end of file + fn drop(&mut self) { + unsafe { pt_free_encoder(self.0) } + } +} diff --git a/src/packet/exstop.rs b/src/packet/exstop.rs index 1713b66..80efd3c 100644 --- a/src/packet/exstop.rs +++ b/src/packet/exstop.rs @@ -1,20 +1,16 @@ -use libipt_sys::{ - pt_packet_exstop, - pt_packet_type_ppt_exstop, - __BindgenBitfieldUnit, -}; +use libipt_sys::{__BindgenBitfieldUnit, pt_packet_exstop, pt_packet_type_ppt_exstop}; /// A EXSTOP packet. /// Packet: exstop #[derive(Clone, Copy, Debug)] -pub struct Exstop (pt_packet_exstop); +pub struct Exstop(pt_packet_exstop); impl Exstop { #[inline] pub fn new(ip: bool) -> Self { Exstop(pt_packet_exstop { _bitfield_align_1: [], _bitfield_1: __BindgenBitfieldUnit::new([ip as u8]), - __bindgen_padding_0: Default::default() + __bindgen_padding_0: Default::default(), }) } @@ -23,15 +19,19 @@ impl Exstop { /// set: binds to the next FUP. /// clear: standalone #[inline] - pub fn ip(self) -> bool { self.0.ip() > 0 } - + pub fn ip(self) -> bool { + self.0.ip() > 0 + } + /// A flag specifying the binding of the packet: /// /// set: binds to the next FUP. /// clear: standalone #[inline] - pub fn set_ip(&mut self, ip: bool) { self.0.set_ip(ip as u32) } + pub fn set_ip(&mut self, ip: bool) { + self.0.set_ip(ip as u32) + } } wrap2raw!(Exstop, pt_packet_type_ppt_exstop, exstop); -raw2wrap!(Exstop, Exstop, pt_packet_exstop); \ No newline at end of file +raw2wrap!(Exstop, Exstop, pt_packet_exstop); diff --git a/src/packet/invalid.rs b/src/packet/invalid.rs index 8b65b46..7c5b5ce 100644 --- a/src/packet/invalid.rs +++ b/src/packet/invalid.rs @@ -4,5 +4,7 @@ use libipt_sys::pt_packet; pub struct Invalid {} impl From for Invalid { - fn from(_val: pt_packet) -> Self { Invalid{} } + fn from(_val: pt_packet) -> Self { + Invalid {} + } } diff --git a/src/packet/ip.rs b/src/packet/ip.rs index 6ac462d..45df6e4 100644 --- a/src/packet/ip.rs +++ b/src/packet/ip.rs @@ -1,22 +1,15 @@ // Certain casts are required only on Windows. Inform Clippy to ignore them. #![allow(clippy::unnecessary_cast)] -use std::convert::TryFrom; -use num_enum::{TryFromPrimitive, IntoPrimitive}; use libipt_sys::{ - pt_packet_ip, - pt_packet_type_ppt_tip, - pt_packet_type_ppt_fup, + pt_ip_compression, pt_ip_compression_pt_ipc_full, pt_ip_compression_pt_ipc_sext_48, + pt_ip_compression_pt_ipc_suppressed, pt_ip_compression_pt_ipc_update_16, + pt_ip_compression_pt_ipc_update_32, pt_ip_compression_pt_ipc_update_48, pt_packet_ip, + pt_packet_type_ppt_fup, pt_packet_type_ppt_tip, pt_packet_type_ppt_tip_pgd, pt_packet_type_ppt_tip_pge, - pt_packet_type_ppt_tip_pgd, - pt_ip_compression, - pt_ip_compression_pt_ipc_full, - pt_ip_compression_pt_ipc_sext_48, - pt_ip_compression_pt_ipc_suppressed, - pt_ip_compression_pt_ipc_update_16, - pt_ip_compression_pt_ipc_update_32, - pt_ip_compression_pt_ipc_update_48, }; +use num_enum::{IntoPrimitive, TryFromPrimitive}; +use std::convert::TryFrom; /// The IP compression #[derive(Clone, Copy, Debug, TryFromPrimitive, IntoPrimitive)] @@ -26,37 +19,44 @@ pub enum Compression { Suppressed = pt_ip_compression_pt_ipc_suppressed as u32, /// Payload: 16 bits. Update last IP - Update16 = pt_ip_compression_pt_ipc_update_16 as u32, + Update16 = pt_ip_compression_pt_ipc_update_16 as u32, /// Payload: 32 bits. Update last IP - Update32 = pt_ip_compression_pt_ipc_update_32 as u32, + Update32 = pt_ip_compression_pt_ipc_update_32 as u32, /// Payload: 48 bits. Sign extend to full address - Sext48 = pt_ip_compression_pt_ipc_sext_48 as u32, + Sext48 = pt_ip_compression_pt_ipc_sext_48 as u32, /// Payload: 48 bits. Update last IP - Update48 = pt_ip_compression_pt_ipc_update_48 as u32, + Update48 = pt_ip_compression_pt_ipc_update_48 as u32, /// Payload: 64 bits. Full address - Full = pt_ip_compression_pt_ipc_full as u32, + Full = pt_ip_compression_pt_ipc_full as u32, } /// A packet with IP payload. /// Packet: tip #[derive(Clone, Copy, Debug)] -pub struct Tip (pt_packet_ip); +pub struct Tip(pt_packet_ip); impl Tip { #[inline] pub fn new(tip: u64, compression: Compression) -> Self { - Tip (pt_packet_ip { ip: tip, ipc: u32::from(compression) as pt_ip_compression }) + Tip(pt_packet_ip { + ip: tip, + ipc: u32::from(compression) as pt_ip_compression, + }) } /// Zero-extended payload ip #[inline] - pub fn tip(self) -> u64 { self.0.ip } + pub fn tip(self) -> u64 { + self.0.ip + } /// Zero-extended payload ip #[inline] - pub fn set_tip(&mut self, ip: u64) { self.0.ip = ip } + pub fn set_tip(&mut self, ip: u64) { + self.0.ip = ip + } /// IP compression #[inline] @@ -76,19 +76,26 @@ impl Tip { /// A packet with IP payload. /// Packet: fup #[derive(Clone, Copy, Debug)] -pub struct Fup (pt_packet_ip); +pub struct Fup(pt_packet_ip); impl Fup { #[inline] pub fn new(fup: u64, compression: Compression) -> Self { - Fup (pt_packet_ip { ip: fup, ipc: u32::from(compression) as pt_ip_compression }) + Fup(pt_packet_ip { + ip: fup, + ipc: u32::from(compression) as pt_ip_compression, + }) } /// Zero-extended payload ip #[inline] - pub fn fup(self) -> u64 { self.0.ip } + pub fn fup(self) -> u64 { + self.0.ip + } /// Zero-extended payload ip #[inline] - pub fn set_fup(&mut self, fup: u64) { self.0.ip = fup } + pub fn set_fup(&mut self, fup: u64) { + self.0.ip = fup + } /// IP compression #[inline] @@ -108,19 +115,26 @@ impl Fup { /// A packet with IP payload. /// Packet: tip.pge #[derive(Clone, Copy, Debug)] -pub struct TipPge (pt_packet_ip); +pub struct TipPge(pt_packet_ip); impl TipPge { #[inline] pub fn new(tippge: u64, compression: Compression) -> Self { - TipPge (pt_packet_ip { ip: tippge, ipc: u32::from(compression) as pt_ip_compression }) + TipPge(pt_packet_ip { + ip: tippge, + ipc: u32::from(compression) as pt_ip_compression, + }) } /// Zero-extended payload ip #[inline] - pub fn tippge(self) -> u64 { self.0.ip } + pub fn tippge(self) -> u64 { + self.0.ip + } /// Zero-extended payload ip #[inline] - pub fn set_tippge(&mut self, tippge: u64) { self.0.ip = tippge } + pub fn set_tippge(&mut self, tippge: u64) { + self.0.ip = tippge + } /// IP compression #[inline] @@ -140,19 +154,26 @@ impl TipPge { /// A packet with IP payload. /// Packet: tip.pgd #[derive(Clone, Copy, Debug)] -pub struct TipPgd (pt_packet_ip); +pub struct TipPgd(pt_packet_ip); impl TipPgd { #[inline] pub fn new(tippgd: u64, compression: Compression) -> Self { - TipPgd (pt_packet_ip { ip: tippgd, ipc: u32::from(compression) as pt_ip_compression }) + TipPgd(pt_packet_ip { + ip: tippgd, + ipc: u32::from(compression) as pt_ip_compression, + }) } /// Zero-extended payload ip #[inline] - pub fn tippgd(self) -> u64 { self.0.ip } + pub fn tippgd(self) -> u64 { + self.0.ip + } /// Zero-extended payload ip #[inline] - pub fn set_tippgd(&mut self, tippgd: u64) { self.0.ip = tippgd } + pub fn set_tippgd(&mut self, tippgd: u64) { + self.0.ip = tippgd + } /// IP compression #[inline] diff --git a/src/packet/mnt.rs b/src/packet/mnt.rs index f80438f..24efb48 100644 --- a/src/packet/mnt.rs +++ b/src/packet/mnt.rs @@ -3,18 +3,24 @@ use libipt_sys::{pt_packet_mnt, pt_packet_type_ppt_mnt}; /// A MNT packet. /// Packet: mnt #[derive(Clone, Copy, Debug)] -pub struct Mnt (pt_packet_mnt); +pub struct Mnt(pt_packet_mnt); impl Mnt { #[inline] - pub fn new(payload: u64) -> Self { Mnt(pt_packet_mnt{payload}) } + pub fn new(payload: u64) -> Self { + Mnt(pt_packet_mnt { payload }) + } #[inline] /// The raw payload - pub fn payload(self) -> u64 { self.0.payload } + pub fn payload(self) -> u64 { + self.0.payload + } #[inline] /// The raw payload - pub fn set_payload(&mut self, payload: u64) { self.0.payload = payload } + pub fn set_payload(&mut self, payload: u64) { + self.0.payload = payload + } } wrap2raw!(Mnt, pt_packet_type_ppt_mnt, mnt); diff --git a/src/packet/mod.rs b/src/packet/mod.rs index cc85869..dd40311 100644 --- a/src/packet/mod.rs +++ b/src/packet/mod.rs @@ -1,8 +1,7 @@ use std::fmt::{Debug, Formatter}; use libipt_sys::{ - pt_packet, - pt_packet_type_ppt_cbr as PT_PACKET_TYPE_PPT_CBR, + pt_packet, pt_packet_type_ppt_cbr as PT_PACKET_TYPE_PPT_CBR, pt_packet_type_ppt_cyc as PT_PACKET_TYPE_PPT_CYC, pt_packet_type_ppt_exstop as PT_PACKET_TYPE_PPT_EXSTOP, pt_packet_type_ppt_fup as PT_PACKET_TYPE_PPT_FUP, @@ -24,11 +23,11 @@ use libipt_sys::{ pt_packet_type_ppt_tip_pgd as PT_PACKET_TYPE_PPT_TIP_PGD, pt_packet_type_ppt_tip_pge as PT_PACKET_TYPE_PPT_TIP_PGE, pt_packet_type_ppt_tma as PT_PACKET_TYPE_PPT_TMA, - pt_packet_type_ppt_tnt_8 as PT_PACKET_TYPE_PPT_TNT_8, pt_packet_type_ppt_tnt_64 as PT_PACKET_TYPE_PPT_TNT_64, + pt_packet_type_ppt_tnt_8 as PT_PACKET_TYPE_PPT_TNT_8, pt_packet_type_ppt_tsc as PT_PACKET_TYPE_PPT_TSC, pt_packet_type_ppt_unknown as PT_PACKET_TYPE_PPT_UNKNOWN, - pt_packet_type_ppt_vmcs as PT_PACKET_TYPE_PPT_VMCS + pt_packet_type_ppt_vmcs as PT_PACKET_TYPE_PPT_VMCS, }; #[macro_use] @@ -91,8 +90,8 @@ pub use encoder::Encoder; #[cfg(test)] mod test { use super::*; - use libipt_sys::pt_packet_mnt; use libipt_sys::pt_packet__bindgen_ty_1; + use libipt_sys::pt_packet_mnt; #[test] fn test_pkt_from() { @@ -100,12 +99,12 @@ mod test { let p2 = pt_packet { type_: PT_PACKET_TYPE_PPT_MNT, size: std::mem::size_of::() as u8, - payload: pt_packet__bindgen_ty_1 { mnt: p1 } + payload: pt_packet__bindgen_ty_1 { mnt: p1 }, }; - let p3: Packet::<()> = p2.into(); + let p3: Packet<()> = p2.into(); match p3 { Packet::Mnt(m) => assert_eq!(m.payload(), p1.payload), - _ => unreachable!() + _ => unreachable!(), }; } } @@ -138,7 +137,7 @@ pub enum Packet { Mwait(mwait::Mwait), Pwre(pwre::Pwre), Pwrx(pwrx::Pwrx), - Ptw(ptw::Ptw) + Ptw(ptw::Ptw), } impl Debug for Packet { @@ -205,8 +204,10 @@ impl From for Packet { PT_PACKET_TYPE_PPT_TNT_64 => Packet::Tnt64(pkt.payload.tnt.into()), PT_PACKET_TYPE_PPT_TSC => Packet::Tsc(pkt.payload.tsc.into()), PT_PACKET_TYPE_PPT_VMCS => Packet::Vmcs(pkt.payload.vmcs.into()), - PT_PACKET_TYPE_PPT_UNKNOWN => Packet::Unknown(unknown::Unknown::::from(pkt.payload.unknown)), - _ => unreachable!("invalid packet type") + PT_PACKET_TYPE_PPT_UNKNOWN => { + Packet::Unknown(unknown::Unknown::::from(pkt.payload.unknown)) + } + _ => unreachable!("invalid packet type"), } } } diff --git a/src/packet/mtc.rs b/src/packet/mtc.rs index e3615e1..179010f 100644 --- a/src/packet/mtc.rs +++ b/src/packet/mtc.rs @@ -3,18 +3,24 @@ use libipt_sys::{pt_packet_mtc, pt_packet_type_ppt_mtc}; /// A MTC packet. /// Packet: mtc #[derive(Clone, Copy, Debug)] -pub struct Mtc (pt_packet_mtc); +pub struct Mtc(pt_packet_mtc); impl Mtc { #[inline] - pub fn new(ctc: u8) -> Self { Mtc(pt_packet_mtc{ctc}) } + pub fn new(ctc: u8) -> Self { + Mtc(pt_packet_mtc { ctc }) + } #[inline] /// The crystal clock tick counter value - pub fn ctc(self) -> u8 { self.0.ctc } + pub fn ctc(self) -> u8 { + self.0.ctc + } #[inline] /// The crystal clock tick counter value - pub fn set_ctc(&mut self, ctc: u8) { self.0.ctc = ctc } + pub fn set_ctc(&mut self, ctc: u8) { + self.0.ctc = ctc + } } wrap2raw!(Mtc, pt_packet_type_ppt_mtc, mtc); diff --git a/src/packet/mwait.rs b/src/packet/mwait.rs index 58cfc43..9e5d6fd 100644 --- a/src/packet/mwait.rs +++ b/src/packet/mwait.rs @@ -3,29 +3,37 @@ use libipt_sys::{pt_packet_mwait, pt_packet_type_ppt_mwait}; /// A MWAIT packet. /// Packet: mwait #[derive(Clone, Copy, Debug)] -pub struct Mwait (pt_packet_mwait); +pub struct Mwait(pt_packet_mwait); impl Mwait { #[inline] pub fn new(ext: u32, hints: u32) -> Self { - Mwait(pt_packet_mwait{ext, hints}) + Mwait(pt_packet_mwait { ext, hints }) } /// The MWAIT extensions (ECX) #[inline] - pub fn ext(self) -> u32 { self.0.ext } + pub fn ext(self) -> u32 { + self.0.ext + } /// The MWAIT extensions (ECX) #[inline] - pub fn set_ext(&mut self, ext: u32) { self.0.ext = ext } + pub fn set_ext(&mut self, ext: u32) { + self.0.ext = ext + } /// The MWAIT hints (EAX) #[inline] - pub fn hints(self) -> u32 { self.0.hints } + pub fn hints(self) -> u32 { + self.0.hints + } /// The MWAIT hints (EAX) #[inline] - pub fn set_hints(&mut self, hints: u32) { self.0.hints = hints } + pub fn set_hints(&mut self, hints: u32) { + self.0.hints = hints + } } wrap2raw!(Mwait, pt_packet_type_ppt_mwait, mwait); -raw2wrap!(Mwait, Mwait, pt_packet_mwait); \ No newline at end of file +raw2wrap!(Mwait, Mwait, pt_packet_mwait); diff --git a/src/packet/ovf.rs b/src/packet/ovf.rs index 9c1aa17..f1c24a9 100644 --- a/src/packet/ovf.rs +++ b/src/packet/ovf.rs @@ -1,5 +1,5 @@ -use std::mem; use libipt_sys::{pt_packet, pt_packet_type_ppt_ovf}; +use std::mem; #[derive(Clone, Copy, Debug)] pub struct Ovf {} @@ -11,7 +11,9 @@ impl Default for Ovf { } impl Ovf { - pub fn new() -> Self { Ovf {} } + pub fn new() -> Self { + Ovf {} + } } impl From for pt_packet { @@ -19,11 +21,13 @@ impl From for pt_packet { pt_packet { type_: pt_packet_type_ppt_ovf, size: mem::size_of::() as u8, - payload: unsafe { mem::zeroed() } + payload: unsafe { mem::zeroed() }, } } } impl From for Ovf { - fn from(_val: pt_packet) -> Self{ Ovf{} } + fn from(_val: pt_packet) -> Self { + Ovf {} + } } diff --git a/src/packet/pad.rs b/src/packet/pad.rs index d236312..e376022 100644 --- a/src/packet/pad.rs +++ b/src/packet/pad.rs @@ -1,5 +1,5 @@ -use std::mem; use libipt_sys::{pt_packet, pt_packet_type_ppt_pad}; +use std::mem; #[derive(Clone, Copy, Debug)] pub struct Pad {} @@ -11,7 +11,9 @@ impl Default for Pad { } impl Pad { - pub fn new() -> Self { Pad {} } + pub fn new() -> Self { + Pad {} + } } impl From for pt_packet { @@ -19,11 +21,13 @@ impl From for pt_packet { pt_packet { type_: pt_packet_type_ppt_pad, size: mem::size_of::() as u8, - payload: unsafe { mem::zeroed() } + payload: unsafe { mem::zeroed() }, } } } impl From for Pad { - fn from(_val: pt_packet) -> Self { Pad{} } + fn from(_val: pt_packet) -> Self { + Pad {} + } } diff --git a/src/packet/pip.rs b/src/packet/pip.rs index 8bf8aa4..b18ca1a 100644 --- a/src/packet/pip.rs +++ b/src/packet/pip.rs @@ -1,13 +1,9 @@ -use libipt_sys::{ - pt_packet_pip, - pt_packet_type_ppt_pip, - __BindgenBitfieldUnit -}; +use libipt_sys::{__BindgenBitfieldUnit, pt_packet_pip, pt_packet_type_ppt_pip}; /// A PIP packet. /// Packet: pip #[derive(Clone, Copy, Debug)] -pub struct Pip (pt_packet_pip); +pub struct Pip(pt_packet_pip); impl Pip { #[inline] pub fn new(cr3: u64, nr: bool) -> Self { @@ -15,23 +11,31 @@ impl Pip { cr3, _bitfield_align_1: [], _bitfield_1: __BindgenBitfieldUnit::new([nr as u8]), - __bindgen_padding_0: Default::default() + __bindgen_padding_0: Default::default(), }) } #[inline] /// The CR3 value - pub fn cr3(self) -> u64 { self.0.cr3 } + pub fn cr3(self) -> u64 { + self.0.cr3 + } #[inline] /// The CR3 value - pub fn set_cr3(&mut self, cr3: u64) { self.0.cr3 = cr3 } + pub fn set_cr3(&mut self, cr3: u64) { + self.0.cr3 = cr3 + } #[inline] /// The non-root bit - pub fn nr(self) -> bool { self.0.nr() > 0 } + pub fn nr(self) -> bool { + self.0.nr() > 0 + } #[inline] /// The non-root bit - pub fn set_nr(&mut self, nr: bool) { self.0.set_nr(nr as u32) } + pub fn set_nr(&mut self, nr: bool) { + self.0.set_nr(nr as u32) + } } wrap2raw!(Pip, pt_packet_type_ppt_pip, pip); diff --git a/src/packet/psb.rs b/src/packet/psb.rs index 224db4a..51b5580 100644 --- a/src/packet/psb.rs +++ b/src/packet/psb.rs @@ -1,5 +1,5 @@ -use std::mem; use libipt_sys::{pt_packet, pt_packet_type_ppt_psb}; +use std::mem; #[derive(Clone, Copy, Debug)] pub struct Psb {} @@ -11,7 +11,9 @@ impl Default for Psb { } impl Psb { - pub fn new() -> Self { Psb {} } + pub fn new() -> Self { + Psb {} + } } impl From for pt_packet { @@ -19,11 +21,13 @@ impl From for pt_packet { pt_packet { type_: pt_packet_type_ppt_psb, size: mem::size_of::() as u8, - payload: unsafe { mem::zeroed() } + payload: unsafe { mem::zeroed() }, } } } impl From for Psb { - fn from(_val: pt_packet) -> Self { Psb{} } + fn from(_val: pt_packet) -> Self { + Psb {} + } } diff --git a/src/packet/psbend.rs b/src/packet/psbend.rs index b48038b..3854338 100644 --- a/src/packet/psbend.rs +++ b/src/packet/psbend.rs @@ -1,5 +1,5 @@ -use std::mem; use libipt_sys::{pt_packet, pt_packet_type_ppt_psbend}; +use std::mem; #[derive(Clone, Copy, Debug)] pub struct Psbend {} @@ -11,7 +11,9 @@ impl Default for Psbend { } impl Psbend { - pub fn new() -> Self { Psbend {} } + pub fn new() -> Self { + Psbend {} + } } impl From for pt_packet { @@ -19,11 +21,13 @@ impl From for pt_packet { pt_packet { type_: pt_packet_type_ppt_psbend, size: mem::size_of::() as u8, - payload: unsafe { mem::zeroed() } + payload: unsafe { mem::zeroed() }, } } } impl From for Psbend { - fn from(_val: pt_packet) -> Self { Psbend{} } + fn from(_val: pt_packet) -> Self { + Psbend {} + } } diff --git a/src/packet/ptw.rs b/src/packet/ptw.rs index 1690b44..e9226fe 100644 --- a/src/packet/ptw.rs +++ b/src/packet/ptw.rs @@ -1,49 +1,58 @@ -use libipt_sys::{ - pt_packet_ptw, - pt_packet_type_ppt_ptw, - __BindgenBitfieldUnit -}; +use libipt_sys::{__BindgenBitfieldUnit, pt_packet_ptw, pt_packet_type_ppt_ptw}; /// A PTW packet. /// Packet: ptw #[derive(Clone, Copy, Debug)] -pub struct Ptw (pt_packet_ptw); +pub struct Ptw(pt_packet_ptw); impl Ptw { #[inline] pub fn new(payload: u64, plc: u8, ip: bool) -> Self { Ptw(pt_packet_ptw { - payload, plc, + payload, + plc, _bitfield_align_1: [], _bitfield_1: __BindgenBitfieldUnit::new([ip as u8]), - __bindgen_padding_0: Default::default() + __bindgen_padding_0: Default::default(), }) } /// The raw payload #[inline] - pub fn payload(self) -> u64 { self.0.payload } + pub fn payload(self) -> u64 { + self.0.payload + } /// The raw payload #[inline] - pub fn set_payload(&mut self, payload: u64) { self.0.payload = payload } + pub fn set_payload(&mut self, payload: u64) { + self.0.payload = payload + } /// The payload size as encoded in the packet #[inline] - pub fn plc(self) -> u8 { self.0.plc } + pub fn plc(self) -> u8 { + self.0.plc + } /// The payload size as encoded in the packet #[inline] - pub fn set_plc(&mut self, plc: u8) { self.0.plc = plc } + pub fn set_plc(&mut self, plc: u8) { + self.0.plc = plc + } /// A flag saying whether a FUP is following PTW that provides /// the IP of the corresponding PTWRITE instruction. #[inline] - pub fn ip(self) -> bool { self.0.ip() > 0 } + pub fn ip(self) -> bool { + self.0.ip() > 0 + } /// A flag saying whether a FUP is following PTW that provides /// the IP of the corresponding PTWRITE instruction. #[inline] - pub fn set_ip(&mut self, ip: bool) { self.0.set_ip(ip as u32) } + pub fn set_ip(&mut self, ip: bool) { + self.0.set_ip(ip as u32) + } } wrap2raw!(Ptw, pt_packet_type_ppt_ptw, ptw); diff --git a/src/packet/pwre.rs b/src/packet/pwre.rs index b1943e1..9fab4be 100644 --- a/src/packet/pwre.rs +++ b/src/packet/pwre.rs @@ -1,48 +1,57 @@ -use libipt_sys::{ - pt_packet_pwre, - pt_packet_type_ppt_pwre, - __BindgenBitfieldUnit -}; +use libipt_sys::{__BindgenBitfieldUnit, pt_packet_pwre, pt_packet_type_ppt_pwre}; /// A PWRE packet. /// Packet: pwre #[derive(Clone, Copy, Debug)] -pub struct Pwre (pt_packet_pwre); +pub struct Pwre(pt_packet_pwre); impl Pwre { #[inline] pub fn new(state: u8, substate: u8, hw: bool) -> Self { - Pwre(pt_packet_pwre{ - state, sub_state: substate, + Pwre(pt_packet_pwre { + state, + sub_state: substate, _bitfield_align_1: [], _bitfield_1: __BindgenBitfieldUnit::new([hw as u8]), - __bindgen_padding_0: Default::default() + __bindgen_padding_0: Default::default(), }) } /// The resolved thread C-state #[inline] - pub fn state(self) -> u8 { self.0.state } + pub fn state(self) -> u8 { + self.0.state + } /// The resolved thread C-state #[inline] - pub fn set_state(&mut self, state: u8) { self.0.state = state } + pub fn set_state(&mut self, state: u8) { + self.0.state = state + } /// The resolved thread sub C-state #[inline] - pub fn substate(self) -> u8 { self.0.sub_state } + pub fn substate(self) -> u8 { + self.0.sub_state + } /// The resolved thread sub C-state #[inline] - pub fn set_substate(&mut self, substate: u8) { self.0.sub_state = substate } + pub fn set_substate(&mut self, substate: u8) { + self.0.sub_state = substate + } /// A flag indicating whether the C-state entry was initiated by h/w #[inline] - pub fn hw(self) -> bool { self.0.hw() > 0 } + pub fn hw(self) -> bool { + self.0.hw() > 0 + } /// A flag indicating whether the C-state entry was initiated by h/w #[inline] - pub fn set_hw(&mut self, hw: bool) { self.0.set_hw(hw as u32) } + pub fn set_hw(&mut self, hw: bool) { + self.0.set_hw(hw as u32) + } } wrap2raw!(Pwre, pt_packet_type_ppt_pwre, pwre); -raw2wrap!(Pwre, Pwre, pt_packet_pwre); \ No newline at end of file +raw2wrap!(Pwre, Pwre, pt_packet_pwre); diff --git a/src/packet/pwrx.rs b/src/packet/pwrx.rs index 4ba5a93..0de36dd 100644 --- a/src/packet/pwrx.rs +++ b/src/packet/pwrx.rs @@ -3,21 +3,18 @@ use libipt_sys::{pt_packet_pwrx, pt_packet_type_ppt_pwrx}; /// A PWRX packet. /// Packet: pwrx #[derive(Clone, Copy, Debug)] -pub struct Pwrx (pt_packet_pwrx); +pub struct Pwrx(pt_packet_pwrx); impl Pwrx { #[inline] - pub fn new(last: u8, - deepest: u8, - interrupt: bool, - store: bool, - autonomous: bool) -> Self { + pub fn new(last: u8, deepest: u8, interrupt: bool, store: bool, autonomous: bool) -> Self { Pwrx(pt_packet_pwrx { - last, deepest, + last, + deepest, __bindgen_padding_0: Default::default(), _bitfield_1: pt_packet_pwrx::new_bitfield_1( interrupt as u32, store as u32, - autonomous as u32 + autonomous as u32, ), _bitfield_align_1: [], }) @@ -25,24 +22,34 @@ impl Pwrx { /// The core C-state at the time of the wake #[inline] - pub fn last(self) -> u8 { self.0.last } + pub fn last(self) -> u8 { + self.0.last + } /// The core C-state at the time of the wake #[inline] - pub fn set_last(&mut self, last: u8) { self.0.last = last } + pub fn set_last(&mut self, last: u8) { + self.0.last = last + } /// The deepest core C-state achieved during sleep #[inline] - pub fn deepest(self) -> u8 { self.0.deepest } + pub fn deepest(self) -> u8 { + self.0.deepest + } /// The deepest core C-state achieved during sleep #[inline] - pub fn set_deepest(&mut self, deepest: u8) { self.0.deepest = deepest } + pub fn set_deepest(&mut self, deepest: u8) { + self.0.deepest = deepest + } /// The wake reason: /// due to external interrupt received. #[inline] - pub fn interrupt(self) -> bool { self.0.interrupt() > 0 } + pub fn interrupt(self) -> bool { + self.0.interrupt() > 0 + } /// The wake reason: /// due to external interrupt received. @@ -54,7 +61,9 @@ impl Pwrx { /// The wake reason: /// due to store to monitored address #[inline] - pub fn store(self) -> bool { self.0.store() > 0 } + pub fn store(self) -> bool { + self.0.store() > 0 + } /// The wake reason: /// due to store to monitored address @@ -66,7 +75,9 @@ impl Pwrx { /// The wake reason: /// due to h/w autonomous condition such as HDC #[inline] - pub fn autonomous(self) -> bool { self.0.autonomous() > 0 } + pub fn autonomous(self) -> bool { + self.0.autonomous() > 0 + } /// The wake reason: /// due to h/w autonomous condition such as HDC diff --git a/src/packet/stop.rs b/src/packet/stop.rs index c1fd57b..5ef62fe 100644 --- a/src/packet/stop.rs +++ b/src/packet/stop.rs @@ -1,5 +1,5 @@ -use std::mem; use libipt_sys::{pt_packet, pt_packet_type_ppt_stop}; +use std::mem; #[derive(Clone, Copy, Debug)] pub struct Stop {} @@ -11,7 +11,9 @@ impl Default for Stop { } impl Stop { - pub fn new() -> Self { Stop {} } + pub fn new() -> Self { + Stop {} + } } impl From for pt_packet { @@ -19,11 +21,13 @@ impl From for pt_packet { pt_packet { type_: pt_packet_type_ppt_stop, size: mem::size_of::() as u8, - payload: unsafe { mem::zeroed() } + payload: unsafe { mem::zeroed() }, } } } impl From for Stop { - fn from(_val: pt_packet) -> Self { Stop{} } + fn from(_val: pt_packet) -> Self { + Stop {} + } } diff --git a/src/packet/tma.rs b/src/packet/tma.rs index c6d43cd..74cade0 100644 --- a/src/packet/tma.rs +++ b/src/packet/tma.rs @@ -3,26 +3,36 @@ use libipt_sys::{pt_packet_tma, pt_packet_type_ppt_tma}; /// A TMA packet. /// Packet: tma #[derive(Clone, Copy, Debug)] -pub struct Tma (pt_packet_tma); +pub struct Tma(pt_packet_tma); impl Tma { #[inline] - pub fn new(ctc: u16, fc: u16) -> Self { Tma(pt_packet_tma{ctc, fc}) } + pub fn new(ctc: u16, fc: u16) -> Self { + Tma(pt_packet_tma { ctc, fc }) + } #[inline] /// The crystal clock tick counter value - pub fn ctc(self) -> u16 { self.0.ctc } + pub fn ctc(self) -> u16 { + self.0.ctc + } #[inline] /// The crystal clock tick counter value - pub fn set_ctc(&mut self, ctc: u16) { self.0.ctc = ctc } + pub fn set_ctc(&mut self, ctc: u16) { + self.0.ctc = ctc + } #[inline] /// The fast counter value - pub fn fc(self) -> u16 { self.0.fc } + pub fn fc(self) -> u16 { + self.0.fc + } #[inline] /// The fast counter value - pub fn set_fc(&mut self, fc: u16) { self.0.fc = fc } + pub fn set_fc(&mut self, fc: u16) { + self.0.fc = fc + } } wrap2raw!(Tma, pt_packet_type_ppt_tma, tma); diff --git a/src/packet/tnt.rs b/src/packet/tnt.rs index adb479b..d9490ff 100644 --- a/src/packet/tnt.rs +++ b/src/packet/tnt.rs @@ -1,28 +1,33 @@ -use libipt_sys::{ - pt_packet_tnt, - pt_packet_type_ppt_tnt_8, - pt_packet_type_ppt_tnt_64 -}; +use libipt_sys::{pt_packet_tnt, pt_packet_type_ppt_tnt_64, pt_packet_type_ppt_tnt_8}; /// A TNT-8 packet. /// Packet: tnt-8 #[derive(Clone, Copy, Debug)] -pub struct Tnt8 (pt_packet_tnt); +pub struct Tnt8(pt_packet_tnt); impl Tnt8 { #[inline] pub fn new(payload: u8, bitsize: u8) -> Self { - Tnt8 (pt_packet_tnt {bit_size: bitsize, payload: payload as u64}) + Tnt8(pt_packet_tnt { + bit_size: bitsize, + payload: payload as u64, + }) } /// TNT payload bit size #[inline] - pub fn bitsize(self) -> u8 { self.0.bit_size } + pub fn bitsize(self) -> u8 { + self.0.bit_size + } /// TNT payload bit size #[inline] - pub fn set_bitsize(&mut self, sz: u8) { self.0.bit_size = sz } + pub fn set_bitsize(&mut self, sz: u8) { + self.0.bit_size = sz + } /// TNT payload excluding stop bit #[inline] - pub fn payload(self) -> u8 { self.0.payload as u8 } + pub fn payload(self) -> u8 { + self.0.payload as u8 + } /// TNT payload excluding stop bit #[inline] pub fn set_payload(&mut self, payload: u8) { @@ -33,22 +38,31 @@ impl Tnt8 { /// A TNT-64 packet. /// Packet: tnt-64 #[derive(Clone, Copy, Debug)] -pub struct Tnt64 (pt_packet_tnt); +pub struct Tnt64(pt_packet_tnt); impl Tnt64 { #[inline] pub fn new(payload: u64, bitsize: u8) -> Self { - Tnt64 (pt_packet_tnt {bit_size: bitsize, payload}) + Tnt64(pt_packet_tnt { + bit_size: bitsize, + payload, + }) } /// TNT payload bit size #[inline] - pub fn bitsize(self) -> u8 { self.0.bit_size } + pub fn bitsize(self) -> u8 { + self.0.bit_size + } /// TNT payload bit size #[inline] - pub fn set_bitsize(&mut self, sz: u8) { self.0.bit_size = sz } + pub fn set_bitsize(&mut self, sz: u8) { + self.0.bit_size = sz + } /// TNT payload excluding stop bit #[inline] - pub fn payload(self) -> u8 { self.0.payload as u8 } + pub fn payload(self) -> u8 { + self.0.payload as u8 + } /// TNT payload excluding stop bit #[inline] pub fn set_payload(&mut self, payload: u8) { diff --git a/src/packet/tsc.rs b/src/packet/tsc.rs index 49f8998..0bfa903 100644 --- a/src/packet/tsc.rs +++ b/src/packet/tsc.rs @@ -3,18 +3,24 @@ use libipt_sys::{pt_packet_tsc, pt_packet_type_ppt_tsc}; /// A TSC packet. /// Packet: tsc #[derive(Clone, Copy, Debug)] -pub struct Tsc (pt_packet_tsc); +pub struct Tsc(pt_packet_tsc); impl Tsc { #[inline] - pub fn new(tsc: u64) -> Self { Tsc(pt_packet_tsc{tsc}) } + pub fn new(tsc: u64) -> Self { + Tsc(pt_packet_tsc { tsc }) + } #[inline] /// The TSC value - pub fn tsc(self) -> u64 { self.0.tsc } + pub fn tsc(self) -> u64 { + self.0.tsc + } #[inline] /// The TSC value - pub fn set_tsc(&mut self, tsc: u64) { self.0.tsc = tsc } + pub fn set_tsc(&mut self, tsc: u64) { + self.0.tsc = tsc + } } wrap2raw!(Tsc, pt_packet_type_ppt_tsc, tsc); diff --git a/src/packet/unknown.rs b/src/packet/unknown.rs index fd0d5f4..51fcf58 100644 --- a/src/packet/unknown.rs +++ b/src/packet/unknown.rs @@ -2,7 +2,7 @@ use libipt_sys::pt_packet_unknown; /// An unknown packet decodable by the optional decoder callback. /// Packet: unknown -pub struct Unknown (pub(crate) Option>); +pub struct Unknown(pub(crate) Option>); impl Unknown { // Create new instance of Unknown, putting `data` in a box pub fn new(data: T) -> Self { @@ -10,14 +10,14 @@ impl Unknown { } // Create an empty Unknown, for when you dont want to return something - pub fn none() -> Self { Unknown(None) } + pub fn none() -> Self { + Unknown(None) + } pub(crate) fn from(pkt: pt_packet_unknown) -> Self { match pkt.priv_ { x if x.is_null() => Unknown(None), - x => unsafe { - Unknown(Some(Box::from_raw(x as *mut T))) - } + x => unsafe { Unknown(Some(Box::from_raw(x as *mut T))) }, } } @@ -25,4 +25,4 @@ impl Unknown { pub fn data(self) -> Option { self.0.map(|d| *d) } -} \ No newline at end of file +} diff --git a/src/packet/vmcs.rs b/src/packet/vmcs.rs index 8c08e66..994e91f 100644 --- a/src/packet/vmcs.rs +++ b/src/packet/vmcs.rs @@ -1,21 +1,27 @@ -use libipt_sys::{pt_packet_vmcs, pt_packet_type_ppt_vmcs}; +use libipt_sys::{pt_packet_type_ppt_vmcs, pt_packet_vmcs}; /// A VMCS packet. /// Packet: vmcs #[derive(Clone, Copy, Debug)] -pub struct Vmcs (pt_packet_vmcs); +pub struct Vmcs(pt_packet_vmcs); impl Vmcs { #[inline] - pub fn new(base: u64) -> Self { Vmcs(pt_packet_vmcs{base}) } + pub fn new(base: u64) -> Self { + Vmcs(pt_packet_vmcs { base }) + } #[inline] /// The VMCS Base Address (i.e. the shifted payload) - pub fn base(self) -> u64 { self.0.base } + pub fn base(self) -> u64 { + self.0.base + } #[inline] /// The VMCS Base Address (i.e. the shifted payload) - pub fn set_base(&mut self, base: u64) { self.0.base = base } + pub fn set_base(&mut self, base: u64) { + self.0.base = base + } } wrap2raw!(Vmcs, pt_packet_type_ppt_vmcs, vmcs); -raw2wrap!(Vmcs, Vmcs, pt_packet_vmcs); \ No newline at end of file +raw2wrap!(Vmcs, Vmcs, pt_packet_vmcs); diff --git a/src/version.rs b/src/version.rs index b412fd8..711e4a4 100644 --- a/src/version.rs +++ b/src/version.rs @@ -1,8 +1,5 @@ +use libipt_sys::{pt_library_version, pt_version}; use std::ffi::CStr; -use libipt_sys::{ - pt_version, - pt_library_version -}; #[cfg(test)] mod test { @@ -25,22 +22,32 @@ impl Version { } /// Major version number. - pub fn major(&self) -> u8 { self.0.major } + pub fn major(&self) -> u8 { + self.0.major + } /// Minor version number. - pub fn minor(&self) -> u8 { self.0.minor } + pub fn minor(&self) -> u8 { + self.0.minor + } /// Patch level. - pub fn patch(&self) -> u16 { self.0.patch } + pub fn patch(&self) -> u16 { + self.0.patch + } /// Build number. - pub fn build(&self) -> u32 { self.0.build } + pub fn build(&self) -> u32 { + self.0.build + } /// Version extension. pub fn ext(&self) -> &str { - unsafe { CStr::from_ptr(self.0.ext) }.to_str().expect( - concat!("failed to convert version ext to rust string. ", - "this is either a bug in libipt or the bindings") - ) + unsafe { CStr::from_ptr(self.0.ext) } + .to_str() + .expect(concat!( + "failed to convert version ext to rust string. ", + "this is either a bug in libipt or the bindings" + )) } -} \ No newline at end of file +} diff --git a/tests/integration_encoding.rs b/tests/integration_encoding.rs index fc4e418..dd6863c 100644 --- a/tests/integration_encoding.rs +++ b/tests/integration_encoding.rs @@ -1,5 +1,5 @@ -use libipt::{ ConfigBuilder, Cpu }; use libipt::packet::*; +use libipt::{ConfigBuilder, Cpu}; #[test] fn test_encoder_all_packets() { @@ -24,14 +24,16 @@ fn test_encoder_all_packets() { size += enc.next(TipPgd::new(888, Compression::Update16)).unwrap(); size += enc.next(Tnt8::new(3, 4)).unwrap(); size += enc.next(Tnt64::new(4, 13)).unwrap(); - size += enc.next(Mode::new(Payload::Exec(Exec::CSL | Exec::CSD))).unwrap(); + size += enc + .next(Mode::new(Payload::Exec(Exec::CSL | Exec::CSD))) + .unwrap(); size += enc.next(Pip::new(1337, false)).unwrap(); size += enc.next(Tsc::new(69)).unwrap(); size += enc.next(Cbr::new(5)).unwrap(); size += enc.next(Tma::new(420, 421)).unwrap(); size += enc.next(Mtc::new(0)).unwrap(); size += enc.next(Cyc::new(0xCA7)).unwrap(); - size += enc.next(Stop::new()).unwrap(); + size += enc.next(Stop::new()).unwrap(); size += enc.next(Vmcs::new(111)).unwrap(); size += enc.next(Mnt::new(222)).unwrap(); size += enc.next(Exstop::new(true)).unwrap(); @@ -42,4 +44,4 @@ fn test_encoder_all_packets() { assert_eq!(size, 132); assert!(enc.next(Pad::new()).is_err()); -} \ No newline at end of file +} From 00c402774683e15ee28a0df667ddc1fba5df816b Mon Sep 17 00:00:00 2001 From: Marcondiro <46560192+Marcondiro@users.noreply.github.com> Date: Fri, 22 Nov 2024 10:26:27 +0100 Subject: [PATCH 3/4] more #[derive(Debug)] --- Cargo.toml | 2 +- src/block/block.rs | 2 +- src/block/decoder.rs | 1 + src/config/config.rs | 2 ++ src/config/cpu.rs | 1 + src/config/filter.rs | 5 +++-- src/config/flags.rs | 3 +++ src/config/freqency.rs | 2 +- src/event/mod.rs | 2 +- src/event/qry.rs | 3 ++- src/flags.rs | 1 + src/insn/decoder.rs | 1 + src/insn/insn.rs | 2 +- src/packet/decoder.rs | 1 + src/packet/encoder.rs | 1 + src/packet/mode.rs | 6 +++--- src/packet/unknown.rs | 1 + 17 files changed, 25 insertions(+), 11 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index eb38254..c23eb7d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -8,6 +8,6 @@ description = "The Intel Processor Trace (Intel PT) Decoder Library is Intel's r repository = "https://github.com/sum-catnip/libipt-rs" [dependencies] -libipt-sys = "0.2.0-rc.1" +libipt-sys = { git = "https://github.com/sum-catnip/libipt-sys" } bitflags = "2.4.1" num_enum = "0.7.1" diff --git a/src/block/block.rs b/src/block/block.rs index 5116377..b3836b5 100644 --- a/src/block/block.rs +++ b/src/block/block.rs @@ -69,7 +69,7 @@ mod test { /// /// Instructions in this block are executed sequentially but are not necessarily /// contiguous in memory. Users are expected to follow direct branches. -#[derive(Clone, Copy)] +#[derive(Debug, Clone, Copy)] pub struct Block(pub(super) pt_block); impl Block { /// The IP of the first instruction in this block. diff --git a/src/block/decoder.rs b/src/block/decoder.rs index dbaf3a8..730dc96 100644 --- a/src/block/decoder.rs +++ b/src/block/decoder.rs @@ -58,6 +58,7 @@ mod test { /// The decoder needs to be synchronized before it can be used. /// /// * `T` - The Callback Closure Type in the Config +#[derive(Debug)] pub struct BlockDecoder<'a, T>(&'a mut pt_block_decoder, PhantomData); impl BlockDecoder<'_, T> { /// Allocate an Intel PT block decoder. diff --git a/src/config/config.rs b/src/config/config.rs index f7c7967..0c748b6 100644 --- a/src/config/config.rs +++ b/src/config/config.rs @@ -208,6 +208,7 @@ where } /// A helper type to create the libipt Configuration instance +#[derive(Debug)] pub struct ConfigBuilder<'a, T>(pt_config, PhantomData<&'a mut T>); impl<'a, T> ConfigBuilder<'a, T> { // when theres a bug here, there might be on in `new` too. @@ -286,6 +287,7 @@ impl<'a> ConfigBuilder<'a, ()> { } /// A libipt configuration +#[derive(Debug)] pub struct Config<'a, C>(pub(crate) Cow<'a, pt_config>, PhantomData<&'a mut C>); impl<'a, C> Config<'a, C> { /// Gets this configs buffer. diff --git a/src/config/cpu.rs b/src/config/cpu.rs index c9a29cb..317c3f1 100644 --- a/src/config/cpu.rs +++ b/src/config/cpu.rs @@ -42,6 +42,7 @@ mod test { bitflags! { /// i suppose this is relevant when/if amd finally gets intelpt support? + #[derive(Debug)] pub struct CpuVendor: u32 { const INTEL = pt_cpu_vendor_pcv_intel as u32; const UNKNOWN = pt_cpu_vendor_pcv_unknown as u32; diff --git a/src/config/filter.rs b/src/config/filter.rs index eb41bbe..1ba79cc 100644 --- a/src/config/filter.rs +++ b/src/config/filter.rs @@ -43,7 +43,7 @@ pub enum AddrConfig { } /// an address range inside the address filter -#[derive(Clone, Copy)] +#[derive(Debug, Clone, Copy)] pub struct AddrRange { /// This corresponds to the IA32_RTIT_ADDRn_A MSRs a: u64, @@ -93,7 +93,7 @@ impl AddrRange { } /// the address filter configuration -#[derive(Clone, Copy)] +#[derive(Debug, Clone, Copy)] pub struct AddrFilter(pub(super) pt_conf_addr_filter); impl AddrFilter { #[inline] @@ -141,6 +141,7 @@ impl AddrFilter { } } +#[derive(Debug)] pub struct AddrFilterBuilder(pub(super) pt_conf_addr_filter); impl Default for AddrFilterBuilder { fn default() -> Self { diff --git a/src/config/flags.rs b/src/config/flags.rs index a6ffae0..f3ea7ec 100644 --- a/src/config/flags.rs +++ b/src/config/flags.rs @@ -75,6 +75,7 @@ mod test { bitflags! { /// flags for the block decoder + #[derive(Debug)] pub struct BlockFlags: u8 { /// End a block after a call instruction const END_ON_CALL = 0b00000001; @@ -89,6 +90,7 @@ bitflags! { bitflags! { /// flags for the instruction flow decoder + #[derive(Debug)] pub struct InsnFlags: u8 { /// Enable tick events for timing updates const ENABLE_TICK_EVENTS = 0b00000001; @@ -99,6 +101,7 @@ bitflags! { bitflags! { /// flags for the query decoder + #[derive(Debug)] pub struct QueryFlags: u8 { /// Preserve timing calibration on overflow const KEEP_TCAL_ON_OVF = 0b00000001; diff --git a/src/config/freqency.rs b/src/config/freqency.rs index eb9787a..8e87a9c 100644 --- a/src/config/freqency.rs +++ b/src/config/freqency.rs @@ -23,7 +23,7 @@ mod test { } /// Frequency values used for timing packets -#[derive(Clone, Copy, Default)] +#[derive(Debug, Clone, Copy, Default)] pub struct Frequency { /// The Mini Time Counter (MTC) frequency as defined in IA32_RTIT_CTL.MTCFreq. /// diff --git a/src/event/mod.rs b/src/event/mod.rs index 35873d7..9f1f897 100644 --- a/src/event/mod.rs +++ b/src/event/mod.rs @@ -154,7 +154,7 @@ impl From for Payload { } } -#[derive(Clone, Copy)] +#[derive(Debug, Clone, Copy)] pub struct Event(pub(crate) pt_event); impl Event { /// A flag indicating that the event IP has been suppressed. diff --git a/src/event/qry.rs b/src/event/qry.rs index 8e1f7d7..77fcb46 100644 --- a/src/event/qry.rs +++ b/src/event/qry.rs @@ -49,7 +49,7 @@ mod test { } } -#[derive(Clone, Copy, TryFromPrimitive)] +#[derive(Debug, Clone, Copy, TryFromPrimitive)] #[repr(i32)] pub enum CondBranch { Taken = 1, @@ -59,6 +59,7 @@ pub enum CondBranch { /// The decoder will work on the buffer defined in the config, /// it shall contain raw trace data and remain valid for the lifetime of the decoder. /// The decoder needs to be synchronized before it can be used. +#[derive(Debug)] pub struct QueryDecoder<'a, T>(&'a mut pt_query_decoder, PhantomData); impl QueryDecoder<'_, T> { /// Allocate an Intel PT query decoder. diff --git a/src/flags.rs b/src/flags.rs index a69a466..4db13d2 100644 --- a/src/flags.rs +++ b/src/flags.rs @@ -8,6 +8,7 @@ use libipt_sys::{ bitflags! { /// Status flags for various IntelPT actions + #[derive(Debug)] pub struct Status: u32 { /// There is no more trace data available. const EOS = pt_status_flag_pts_eos as u32; diff --git a/src/insn/decoder.rs b/src/insn/decoder.rs index 7914b38..b4fbba2 100644 --- a/src/insn/decoder.rs +++ b/src/insn/decoder.rs @@ -58,6 +58,7 @@ mod test { /// The decoder will work on the buffer defined in the Config, /// it shall contain raw trace data and remain valid for the lifetime of the decoder. /// The decoder needs to be synchronized before it can be used. +#[derive(Debug)] pub struct InsnDecoder<'a, T>(&'a mut pt_insn_decoder, PhantomData); impl InsnDecoder<'_, T> { /// Allocate an Intel PT instruction flow decoder. diff --git a/src/insn/insn.rs b/src/insn/insn.rs index c24a414..a53a59a 100644 --- a/src/insn/insn.rs +++ b/src/insn/insn.rs @@ -40,7 +40,7 @@ mod test { } /// A single traced instruction. -#[derive(Clone, Copy)] +#[derive(Debug, Clone, Copy)] pub struct Insn(pub(crate) pt_insn); impl Insn { /// The virtual address in its process. diff --git a/src/packet/decoder.rs b/src/packet/decoder.rs index c6ac9ef..2d2b487 100644 --- a/src/packet/decoder.rs +++ b/src/packet/decoder.rs @@ -37,6 +37,7 @@ mod test { } } +#[derive(Debug)] pub struct PacketDecoder<'a, T>(&'a mut pt_packet_decoder, PhantomData); impl PacketDecoder<'_, T> { /// Allocate an Intel PT packet decoder. diff --git a/src/packet/encoder.rs b/src/packet/encoder.rs index 7fb8a44..b0844ec 100644 --- a/src/packet/encoder.rs +++ b/src/packet/encoder.rs @@ -34,6 +34,7 @@ mod tests { } } +#[derive(Debug)] pub struct Encoder<'a, T>(&'a mut pt_encoder, PhantomData); impl Encoder<'_, T> { /// Allocate an Intel PT packet encoder. diff --git a/src/packet/mode.rs b/src/packet/mode.rs index 740d3db..e0381e1 100644 --- a/src/packet/mode.rs +++ b/src/packet/mode.rs @@ -8,7 +8,7 @@ use std::fmt::{Debug, Formatter}; bitflags! { /// A mode.exec packet - #[derive(Clone, Copy)] + #[derive(Debug, Clone, Copy)] pub struct Exec : u32 { /// The mode.exec csl bit const CSL = 0b00000001; @@ -19,7 +19,7 @@ bitflags! { bitflags! { /// A mode.tsx packet - #[derive(Clone, Copy)] + #[derive(Debug, Clone, Copy)] pub struct Tsx : u32 { /// The mode.tsx intx bit const INTX = 0b00000001; @@ -52,7 +52,7 @@ impl From for pt_packet_mode__bindgen_ty_1 { } } -#[derive(Clone, Copy)] +#[derive(Debug, Clone, Copy)] pub enum Payload { /// A mode.exec packet. Exec(Exec), diff --git a/src/packet/unknown.rs b/src/packet/unknown.rs index 51fcf58..e42f198 100644 --- a/src/packet/unknown.rs +++ b/src/packet/unknown.rs @@ -2,6 +2,7 @@ use libipt_sys::pt_packet_unknown; /// An unknown packet decodable by the optional decoder callback. /// Packet: unknown +#[derive(Debug)] pub struct Unknown(pub(crate) Option>); impl Unknown { // Create new instance of Unknown, putting `data` in a box From a290960b7975fd8ae8f4ef830c86256c7e256ffa Mon Sep 17 00:00:00 2001 From: Marcondiro <46560192+Marcondiro@users.noreply.github.com> Date: Fri, 22 Nov 2024 11:25:18 +0100 Subject: [PATCH 4/4] Bump to 0.2.0 --- Cargo.toml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index c23eb7d..9283f2d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "libipt" -version = "0.2.0-rc.2" +version = "0.2.0" authors = ["sum_catnip ", "Marcondiro"] edition = "2021" license = "MIT" @@ -8,6 +8,6 @@ description = "The Intel Processor Trace (Intel PT) Decoder Library is Intel's r repository = "https://github.com/sum-catnip/libipt-rs" [dependencies] -libipt-sys = { git = "https://github.com/sum-catnip/libipt-sys" } +libipt-sys = "0.2.0" bitflags = "2.4.1" num_enum = "0.7.1"