Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 2 additions & 24 deletions lib/src/crashlog.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,6 @@ use alloc::{collections::VecDeque, vec, vec::Vec};
#[cfg(feature = "std")]
use std::collections::VecDeque;

use crate::header::record_types;

/// Set of all the Crash Log records captured on a platform.
#[derive(Default)]
pub struct CrashLog {
Expand All @@ -31,29 +29,9 @@ impl CrashLog {
let mut regions = Vec::new();

while let Some(region) = queue.pop_front() {
for record in region.records.iter() {
let errata = record.header.version.errata();
let is_box = record.header.version.record_type == record_types::BOX
|| errata.type0_legacy_server_box;

if !is_box {
continue;
}

let Some(payload) = record.data.get(record.header.header_size()..) else {
log::error!("The Box record has an empty payload");
continue;
};

match Region::from_slice(payload) {
Ok(mut region) => {
region.set_child_context(&record.header);
queue.push_front(region)
}
Err(err) => log::warn!("Invalid region in Box record: {err}"),
}
for child in region.get_children() {
queue.push_back(child);
}

regions.push(region)
}

Expand Down
43 changes: 39 additions & 4 deletions lib/src/region.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,18 +5,21 @@

use crate::cper::section::{CperSectionBody, fer};
use crate::error::Error;
use crate::header::Header;
use crate::header::{Header, record_types};
use crate::record::Record;
#[cfg(not(feature = "std"))]
use alloc::vec::Vec;

const MAX_NESTED_BOXES: usize = 4;

/// A container for one or several Crash Log records.
///
/// A Crash Log region refers to a region in an on-die memory that is allocated for storing
/// a contiguous sequence of Crash Log records.
#[derive(Default)]
pub struct Region {
pub records: Vec<Record>,
depth: usize,
}

impl Region {
Expand All @@ -35,10 +38,42 @@ impl Region {
}
}

pub(crate) fn set_child_context(&mut self, hdr: &Header) {
for record in self.records.iter_mut() {
record.context.parent_header = Some(hdr.clone());
pub(crate) fn get_children(&self) -> Vec<Self> {
let mut children = Vec::new();

if self.depth >= MAX_NESTED_BOXES {
return children;
}

for record in self.records.iter() {
let errata = record.header.version.errata();
let is_box = record.header.version.record_type == record_types::BOX
|| errata.type0_legacy_server_box;

if !is_box {
continue;
}

let Some(payload) = record.data.get(record.header.header_size()..) else {
log::error!("The Box record has an empty payload");
continue;
};

match Region::from_slice(payload) {
Ok(mut child) => {
for child_record in child.records.iter_mut() {
child_record.context.parent_header = Some(record.header.clone());
}

child.depth = self.depth + 1;

children.push(child)
}
Err(err) => log::warn!("Invalid region in Box record: {err}"),
}
}

children
}

pub fn from_slice(bytes: &[u8]) -> Result<Self, Error> {
Expand Down
Loading