This repository has been archived by the owner on Nov 9, 2022. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 9
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Start work on our own Intel PT decoder.
This is the first step: a packet parser, i.e. taking the raw bytes given to us by the PT chip and parsing them into Rust structs representing PT packets. I arrived at the approach you see in this change after trying several other, less-satisfying, ways of parsing binary packets (with bitwise field granularity). Initially I was parsing packets by hand, which was very fiddly indeed and was what prompted me to look for tools to help. The `packed_struct` crate worked, but lead to some quite verbose code (and I wrote lots of macros to try and work around that). Still unsatisfied, I found `binrw`, which was almost perfect, only let down by the unmaintained and bit-rotted `modular_bitfield` crate, which is required for bitwise parsing (see Robbepop/modular-bitfield#65). This led me to a solution using `deku`, which I've been very happy with: https://github.com/sharksforarms/deku Not all kinds of packets are implemented: only enough to parse a tiny little trace to completion. We can add new packets on-demand as we see them crop up in the wild.
- Loading branch information
Showing
8 changed files
with
747 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
//! The Yk PT trace decoder. | ||
use crate::{decode::TraceDecoder, errors::HWTracerError, Block, Trace}; | ||
|
||
mod packet_parser; | ||
use packet_parser::PacketParser; | ||
|
||
pub(crate) struct YkPTTraceDecoder {} | ||
|
||
impl TraceDecoder for YkPTTraceDecoder { | ||
fn new() -> Self { | ||
Self {} | ||
} | ||
|
||
fn iter_blocks<'t>( | ||
&'t self, | ||
trace: &'t dyn Trace, | ||
) -> Box<dyn Iterator<Item = Result<Block, HWTracerError>> + '_> { | ||
let itr = YkPTBlockIterator { | ||
errored: false, | ||
parser: PacketParser::new(trace.bytes()), | ||
}; | ||
Box::new(itr) | ||
} | ||
} | ||
|
||
/// Iterate over the blocks of an Intel PT trace using the fast Yk PT decoder. | ||
struct YkPTBlockIterator<'t> { | ||
/// Set to true when an error has occured. | ||
errored: bool, | ||
/// PT packet iterator. | ||
parser: PacketParser<'t>, | ||
} | ||
|
||
impl<'t> Iterator for YkPTBlockIterator<'t> { | ||
type Item = Result<Block, HWTracerError>; | ||
|
||
fn next(&mut self) -> Option<Self::Item> { | ||
if !self.errored { | ||
// FIXME: For now this is dummy code to prevent dead-code warnings. Later block binding | ||
// logic will go here. | ||
self.parser.next().unwrap().unwrap(); | ||
} | ||
None | ||
} | ||
} | ||
|
||
#[cfg(test)] | ||
mod tests { | ||
use crate::{ | ||
collect::TraceCollectorBuilder, | ||
decode::{test_helpers, TraceDecoderKind}, | ||
}; | ||
|
||
#[ignore] // FIXME | ||
#[test] | ||
fn ten_times_as_many_blocks() { | ||
let tc = TraceCollectorBuilder::new().build().unwrap(); | ||
test_helpers::ten_times_as_many_blocks(tc, TraceDecoderKind::YkPT); | ||
} | ||
} |
Oops, something went wrong.