elf/
compression.rs
1use crate::endian::EndianParse;
9use crate::file::Class;
10use crate::parse::{ParseAt, ParseError};
11
12#[derive(Debug)]
16#[repr(C)]
17pub struct Elf32_Chdr {
18 pub ch_type: u32,
19 pub ch_size: u32,
20 pub ch_addralign: u32,
21}
22
23#[derive(Debug)]
27#[repr(C)]
28pub struct Elf64_Chdr {
29 pub ch_type: u32,
30 pub ch_reserved: u32,
31 pub ch_size: u64,
32 pub ch_addralign: u64,
33}
34
35#[derive(Debug, Clone, PartialEq, Eq)]
36pub struct CompressionHeader {
37 pub ch_type: u32,
38 pub ch_size: u64,
39 pub ch_addralign: u64,
40}
41
42impl ParseAt for CompressionHeader {
43 fn parse_at<E: EndianParse>(
44 endian: E,
45 class: Class,
46 offset: &mut usize,
47 data: &[u8],
48 ) -> Result<Self, ParseError> {
49 match class {
50 Class::ELF32 => Ok(CompressionHeader {
51 ch_type: endian.parse_u32_at(offset, data)?,
52 ch_size: endian.parse_u32_at(offset, data)? as u64,
53 ch_addralign: endian.parse_u32_at(offset, data)? as u64,
54 }),
55 Class::ELF64 => {
56 let ch_type = endian.parse_u32_at(offset, data)?;
57 let _ch_reserved = endian.parse_u32_at(offset, data)?;
58 Ok(CompressionHeader {
59 ch_type,
60 ch_size: endian.parse_u64_at(offset, data)?,
61 ch_addralign: endian.parse_u64_at(offset, data)?,
62 })
63 }
64 }
65 }
66
67 #[inline]
68 fn size_for(class: Class) -> usize {
69 match class {
70 Class::ELF32 => 12,
71 Class::ELF64 => 24,
72 }
73 }
74}
75
76#[cfg(test)]
77mod parse_tests {
78 use super::*;
79 use crate::endian::{BigEndian, LittleEndian};
80 use crate::parse::{test_parse_for, test_parse_fuzz_too_short};
81
82 #[test]
83 fn parse_chdr32_lsb() {
84 test_parse_for(
85 LittleEndian,
86 Class::ELF32,
87 CompressionHeader {
88 ch_type: 0x03020100,
89 ch_size: 0x07060504,
90 ch_addralign: 0x0B0A0908,
91 },
92 );
93 }
94
95 #[test]
96 fn parse_chdr32_msb() {
97 test_parse_for(
98 BigEndian,
99 Class::ELF32,
100 CompressionHeader {
101 ch_type: 0x00010203,
102 ch_size: 0x04050607,
103 ch_addralign: 0x08090A0B,
104 },
105 );
106 }
107
108 #[test]
109 fn parse_chdr64_lsb() {
110 test_parse_for(
111 LittleEndian,
112 Class::ELF64,
113 CompressionHeader {
114 ch_type: 0x03020100,
115 ch_size: 0x0F0E0D0C0B0A0908,
116 ch_addralign: 0x1716151413121110,
117 },
118 );
119 }
120
121 #[test]
122 fn parse_chdr64_msb() {
123 test_parse_for(
124 BigEndian,
125 Class::ELF64,
126 CompressionHeader {
127 ch_type: 0x00010203,
128 ch_size: 0x08090A0B0C0D0E0F,
129 ch_addralign: 0x1011121314151617,
130 },
131 );
132 }
133
134 #[test]
135 fn parse_chdr32_lsb_fuzz_too_short() {
136 test_parse_fuzz_too_short::<_, CompressionHeader>(LittleEndian, Class::ELF32);
137 }
138
139 #[test]
140 fn parse_chdr32_msb_fuzz_too_short() {
141 test_parse_fuzz_too_short::<_, CompressionHeader>(BigEndian, Class::ELF32);
142 }
143
144 #[test]
145 fn parse_chdr64_lsb_fuzz_too_short() {
146 test_parse_fuzz_too_short::<_, CompressionHeader>(LittleEndian, Class::ELF64);
147 }
148
149 #[test]
150 fn parse_chdr64_msb_fuzz_too_short() {
151 test_parse_fuzz_too_short::<_, CompressionHeader>(BigEndian, Class::ELF64);
152 }
153}