1use anyhow::Context;
5use anyhow::Result;
6use serde::Deserialize;
7use serde::Serialize;
8use std::io::Write;
9use std::ops::Range;
10use std::path::Path;
11use std::path::PathBuf;
12
13#[derive(Serialize, Deserialize, PartialEq, Eq, Debug, Default)]
14pub struct TraceData {
15 pub traces: Vec<AddressTrace>,
16}
17
18#[derive(Serialize, Deserialize, PartialEq, Eq, Debug)]
19pub struct AddressTrace {
20 pub address: u64,
21 pub messages: Vec<String>,
22}
23
24#[derive(Serialize, Deserialize, PartialEq, Eq, Debug)]
25pub struct Section {
26 pub mem_range: Range<u64>,
27}
28
29impl TraceData {
30 pub fn write(&self, writer: &mut impl Write) -> Result<()> {
31 let r = postcard::to_io(self, writer);
33 let r: Result<()> = r.map(|_| ()).map_err(|e| e.into());
34 r?;
35 Ok(())
36 }
37
38 pub fn to_bytes(&self) -> Result<Vec<u8>> {
39 Ok(postcard::to_stdvec(self)?)
40 }
41
42 pub fn from_bytes(bytes: &[u8]) -> Result<Self> {
43 postcard::from_bytes(bytes).context("Invalid linker trace")
44 }
45}
46
47#[must_use]
48pub fn trace_path(base_path: &Path) -> PathBuf {
49 let mut new_extension = base_path.extension().unwrap_or_default().to_owned();
50 new_extension.push(".trace");
51 base_path.with_extension(new_extension)
52}
53
54#[cfg(test)]
55mod tests {
56 use super::*;
57
58 #[test]
59 fn test_round_trip() {
60 let layout = TraceData {
61 traces: vec![AddressTrace {
62 address: 100,
63 messages: vec!["Test".to_owned()],
64 }],
65 };
66 let bytes = layout.to_bytes().unwrap();
67 let layout2 = TraceData::from_bytes(&bytes).unwrap();
68 assert_eq!(layout, layout2);
69 }
70}