diff --git a/lib/src/cper.rs b/lib/src/cper.rs index f142ffb..f5f5ac5 100644 --- a/lib/src/cper.rs +++ b/lib/src/cper.rs @@ -73,6 +73,10 @@ impl Cper { cper.append_section(section); } + for extra_cper_section in crashlog.metadata.extra_cper_sections.iter() { + cper.append_section(CperSection::from_body(extra_cper_section.clone())); + } + cper } diff --git a/lib/src/cper/section.rs b/lib/src/cper/section.rs index b2fab42..d8414ef 100644 --- a/lib/src/cper/section.rs +++ b/lib/src/cper/section.rs @@ -15,6 +15,7 @@ pub mod guids { } /// One of the CPER section bodies defined in the UEFI 2.10 Specifications (N.2) +#[derive(Clone)] pub enum CperSectionBody { FirmwareErrorRecord(FirmwareErrorRecord), Unknown(Guid, Vec), diff --git a/lib/src/cper/tests.rs b/lib/src/cper/tests.rs index 6aecaf4..9b1882d 100644 --- a/lib/src/cper/tests.rs +++ b/lib/src/cper/tests.rs @@ -37,7 +37,12 @@ fn cl_from_cper() { } } + assert_eq!(crashlog.metadata.extra_cper_sections.len(), 2); assert_eq!(records.len(), 3); + + let cper_bytes = crashlog.to_bytes(); + let cper = Cper::from_slice(&cper_bytes).unwrap(); + assert_eq!(cper.record_header.section_count, 5); } #[test] diff --git a/lib/src/crashlog.rs b/lib/src/crashlog.rs index ac79905..197156a 100644 --- a/lib/src/crashlog.rs +++ b/lib/src/crashlog.rs @@ -5,7 +5,7 @@ use crate::Error; use crate::bert::{Berr, Bert}; #[cfg(feature = "collateral_manager")] use crate::collateral::{CollateralManager, CollateralTree}; -use crate::cper::Cper; +use crate::cper::{Cper, CperSectionBody}; use crate::metadata::Metadata; use crate::node::Node; use crate::region::Region; @@ -90,17 +90,24 @@ impl CrashLog { /// Extracts the Crash Log records from [Cper] record. pub(crate) fn from_cper(cper: Cper) -> Result { - let regions: Vec = cper - .sections - .iter() - .filter_map(|section| Region::from_cper_section(§ion.body)) - .collect(); + let mut regions: Vec = Vec::new(); + let mut extra_cper_sections: Vec = Vec::new(); + + for section in cper.sections { + if let Some(region) = Region::from_cper_section(§ion.body) { + regions.push(region); + } else { + extra_cper_sections.push(section.body); + } + } if regions.is_empty() { return Err(Error::NoCrashLogFound); } - CrashLog::from_regions(regions) + let mut crashlog = CrashLog::from_regions(regions)?; + crashlog.metadata.extra_cper_sections = extra_cper_sections; + Ok(crashlog) } /// Decodes a raw Crash Log binary. diff --git a/lib/src/extract/efi.rs b/lib/src/extract/efi.rs index 9d28528..7946c76 100644 --- a/lib/src/extract/efi.rs +++ b/lib/src/extract/efi.rs @@ -98,6 +98,7 @@ impl CrashLog { }) .inspect_err(|err| log::warn!("Cannot get time: {err}")) .ok(), + ..Default::default() }; Ok(crashlog) diff --git a/lib/src/extract/event_log.rs b/lib/src/extract/event_log.rs index 89c066d..c573c7d 100644 --- a/lib/src/extract/event_log.rs +++ b/lib/src/extract/event_log.rs @@ -160,6 +160,7 @@ fn metadata_from_evt_values( minute: time.wMinute as u8, }), computer: unsafe { computer.Anonymous.StringVal.to_string().ok() }, + ..Default::default() }) } diff --git a/lib/src/metadata.rs b/lib/src/metadata.rs index 1e34499..c626ba1 100644 --- a/lib/src/metadata.rs +++ b/lib/src/metadata.rs @@ -3,16 +3,25 @@ //! Information extracted alongside the Crash Log records. +#[cfg(not(feature = "std"))] +use alloc::vec::Vec; #[cfg(not(feature = "std"))] use alloc::{fmt, string::String}; #[cfg(feature = "std")] use std::fmt; +use crate::cper::CperSectionBody; + /// Crash Log Metadata #[derive(Default)] pub struct Metadata { + /// Name of the computer where the Crash Log has been extracted from. pub computer: Option, + /// Time of the extraction pub time: Option