Skip to content

Commit c1f0983

Browse files
committed
wrap ME Gen2 directory entries and add Huffman data
Signed-off-by: Daniel Maslowski <[email protected]>
1 parent 9d27cb3 commit c1f0983

File tree

2 files changed

+88
-4
lines changed

2 files changed

+88
-4
lines changed

src/dir/gen2.rs

Lines changed: 76 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,40 @@ impl Display for Entry {
141141
}
142142
}
143143

144+
#[derive(IntoBytes, FromBytes, Serialize, Deserialize, Clone, Copy, Debug)]
145+
#[repr(C, packed)]
146+
pub struct HuffmanHeader {
147+
magic: [u8; 4],
148+
chunk_count: u32,
149+
chunk_base: u32,
150+
_unk0: u32,
151+
hs0: u32,
152+
hs1: u32,
153+
_unk1: u32,
154+
_unk2: u32,
155+
_r: [u8; 16], // all 0 in sample
156+
chunk_size: u32,
157+
_unk3: u32,
158+
name: [u8; 8],
159+
}
160+
161+
const HUFFMAN_HEADER_SIZE: usize = size_of::<HuffmanHeader>();
162+
163+
#[derive(Serialize, Deserialize, Clone, Debug)]
164+
#[repr(C)]
165+
pub struct Huffman {
166+
header: HuffmanHeader,
167+
chunks: Vec<u32>,
168+
}
169+
170+
#[derive(Serialize, Deserialize, Clone, Debug)]
171+
pub enum Module {
172+
Uncompressed(Entry),
173+
Huffman(Result<(Entry, Huffman), String>),
174+
Lzma(Result<Entry, String>),
175+
Unknown(Entry),
176+
}
177+
144178
#[derive(IntoBytes, FromBytes, Serialize, Deserialize, Clone, Copy, Debug)]
145179
#[repr(C, packed)]
146180
pub struct Header {
@@ -153,7 +187,7 @@ pub struct Header {
153187
pub struct Directory {
154188
pub manifest: Manifest,
155189
pub header: Header,
156-
pub entries: Vec<Entry>,
190+
pub modules: Vec<Module>,
157191
pub offset: usize,
158192
pub size: usize,
159193
pub name: String,
@@ -202,10 +236,50 @@ impl Directory {
202236
Ok(n) => n.trim_end_matches('\0').to_string(),
203237
Err(_) => format!("{:02x?}", header.name),
204238
};
239+
240+
// Check for consistency and wrap entries with additional information.
241+
let modules = entries
242+
.iter()
243+
.map(|e| {
244+
let c = e.flags.compression();
245+
let o = e.offset as usize;
246+
let sig = &data[o..o + 4];
247+
match c {
248+
Compression::Huffman => {
249+
if sig != SIG_LUT_BYTES {
250+
return Module::Huffman(Err(format!(
251+
"Expected {SIG_LUT_BYTES:02x?} @ {o:08x}, got {sig:02x?}"
252+
)));
253+
}
254+
let (header, _) = HuffmanHeader::read_from_prefix(&data[o..]).unwrap();
255+
let count = header.chunk_count as usize;
256+
let co = o + HUFFMAN_HEADER_SIZE;
257+
let (chunks, _) =
258+
Ref::<_, [u32]>::from_prefix_with_elems(&data[co..], count).unwrap();
259+
let huff = Huffman {
260+
header,
261+
chunks: chunks.to_vec(),
262+
};
263+
Module::Huffman(Ok((*e, huff)))
264+
}
265+
Compression::Lzma => {
266+
if sig != SIG_LZMA_BYTES {
267+
return Module::Lzma(Err(format!(
268+
"Expected {SIG_LZMA_BYTES:02x?} @ {o:08x}, got {sig:02x?}"
269+
)));
270+
}
271+
Module::Lzma(Ok(*e))
272+
}
273+
Compression::Uncompressed => Module::Uncompressed(*e),
274+
Compression::Unknown => Module::Unknown(*e),
275+
}
276+
})
277+
.collect();
278+
205279
Ok(Self {
206280
manifest,
207281
header,
208-
entries,
282+
modules,
209283
offset,
210284
size,
211285
name,

src/show.rs

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,10 @@ use log::{error, warn};
22

33
use intel_fw::{
44
Firmware,
5-
dir::{gen2::Directory as Gen2Dir, gen3::CodePartitionDirectory},
5+
dir::{
6+
gen2::{Directory as Gen2Dir, Module},
7+
gen3::CodePartitionDirectory,
8+
},
69
fit::Fit,
710
fpt::FPT,
811
me::{Directories, ME},
@@ -12,7 +15,14 @@ fn print_gen2_dirs(dirs: &Vec<Gen2Dir>) {
1215
println!("Gen 2 directories:");
1316
for dir in dirs {
1417
println!("{dir}");
15-
for e in &dir.entries {
18+
for m in &dir.modules {
19+
let e = match m {
20+
Module::Uncompressed(e) => e,
21+
Module::Huffman(Ok((e, _))) => e,
22+
Module::Lzma(Ok(e)) => e,
23+
Module::Unknown(e) => e,
24+
_ => continue,
25+
};
1626
let pos = dir.offset + e.offset as usize;
1727
let b = e.bin_map();
1828
println!(" - {e} @ {pos:08x}\n {b}");

0 commit comments

Comments
 (0)