object/read/elf/
attributes.rs1use core::convert::TryInto;
2
3use crate::elf;
4use crate::endian;
5use crate::read::{Bytes, Error, ReadError, Result};
6
7use super::FileHeader;
8
9#[derive(Debug, Clone)]
18pub struct AttributesSection<'data, Elf: FileHeader> {
19    endian: Elf::Endian,
20    version: u8,
21    data: Bytes<'data>,
22}
23
24impl<'data, Elf: FileHeader> AttributesSection<'data, Elf> {
25    pub fn new(endian: Elf::Endian, data: &'data [u8]) -> Result<Self> {
27        let mut data = Bytes(data);
28
29        let version = data.read::<u8>().cloned().unwrap_or(b'A');
32
33        Ok(AttributesSection {
34            endian,
35            version,
36            data,
37        })
38    }
39
40    pub fn version(&self) -> u8 {
42        self.version
43    }
44
45    pub fn subsections(&self) -> Result<AttributesSubsectionIterator<'data, Elf>> {
47        if self.version != b'A' {
49            return Err(Error("Unsupported ELF attributes section version"));
50        }
51
52        Ok(AttributesSubsectionIterator {
53            endian: self.endian,
54            data: self.data,
55        })
56    }
57}
58
59#[derive(Debug, Clone)]
61pub struct AttributesSubsectionIterator<'data, Elf: FileHeader> {
62    endian: Elf::Endian,
63    data: Bytes<'data>,
64}
65
66impl<'data, Elf: FileHeader> AttributesSubsectionIterator<'data, Elf> {
67    pub fn next(&mut self) -> Result<Option<AttributesSubsection<'data, Elf>>> {
69        if self.data.is_empty() {
70            return Ok(None);
71        }
72
73        let result = self.parse().map(Some);
74        if result.is_err() {
75            self.data = Bytes(&[]);
76        }
77        result
78    }
79
80    fn parse(&mut self) -> Result<AttributesSubsection<'data, Elf>> {
81        let mut data = self.data;
83        let length = data
84            .read::<endian::U32Bytes<Elf::Endian>>()
85            .read_error("ELF attributes section is too short")?
86            .get(self.endian);
87
88        let mut data = self
90            .data
91            .read_bytes(length as usize)
92            .read_error("Invalid ELF attributes subsection length")?;
93        data.skip(4)
95            .read_error("Invalid ELF attributes subsection length")?;
96
97        let vendor = data
99            .read_string()
100            .read_error("Invalid ELF attributes vendor")?;
101
102        Ok(AttributesSubsection {
103            endian: self.endian,
104            length,
105            vendor,
106            data,
107        })
108    }
109}
110
111impl<'data, Elf: FileHeader> Iterator for AttributesSubsectionIterator<'data, Elf> {
112    type Item = Result<AttributesSubsection<'data, Elf>>;
113
114    fn next(&mut self) -> Option<Self::Item> {
115        self.next().transpose()
116    }
117}
118
119#[derive(Debug, Clone)]
124pub struct AttributesSubsection<'data, Elf: FileHeader> {
125    endian: Elf::Endian,
126    length: u32,
127    vendor: &'data [u8],
128    data: Bytes<'data>,
129}
130
131impl<'data, Elf: FileHeader> AttributesSubsection<'data, Elf> {
132    pub fn length(&self) -> u32 {
134        self.length
135    }
136
137    pub fn vendor(&self) -> &'data [u8] {
139        self.vendor
140    }
141
142    pub fn subsubsections(&self) -> AttributesSubsubsectionIterator<'data, Elf> {
144        AttributesSubsubsectionIterator {
145            endian: self.endian,
146            data: self.data,
147        }
148    }
149}
150
151#[derive(Debug, Clone)]
153pub struct AttributesSubsubsectionIterator<'data, Elf: FileHeader> {
154    endian: Elf::Endian,
155    data: Bytes<'data>,
156}
157
158impl<'data, Elf: FileHeader> AttributesSubsubsectionIterator<'data, Elf> {
159    pub fn next(&mut self) -> Result<Option<AttributesSubsubsection<'data>>> {
161        if self.data.is_empty() {
162            return Ok(None);
163        }
164
165        let result = self.parse().map(Some);
166        if result.is_err() {
167            self.data = Bytes(&[]);
168        }
169        result
170    }
171
172    fn parse(&mut self) -> Result<AttributesSubsubsection<'data>> {
173        let mut data = self.data;
179        let tag = *data
180            .read::<u8>()
181            .read_error("ELF attributes subsection is too short")?;
182        let length = data
183            .read::<endian::U32Bytes<Elf::Endian>>()
184            .read_error("ELF attributes subsection is too short")?
185            .get(self.endian);
186
187        let mut data = self
189            .data
190            .read_bytes(length as usize)
191            .read_error("Invalid ELF attributes sub-subsection length")?;
192        data.skip(1 + 4)
194            .read_error("Invalid ELF attributes sub-subsection length")?;
195
196        let indices = if tag == elf::Tag_Section || tag == elf::Tag_Symbol {
198            data.read_string()
199                .map(Bytes)
200                .read_error("Missing ELF attributes sub-subsection indices")?
201        } else if tag == elf::Tag_File {
202            Bytes(&[])
203        } else {
204            return Err(Error("Unimplemented ELF attributes sub-subsection tag"));
205        };
206
207        Ok(AttributesSubsubsection {
208            tag,
209            length,
210            indices,
211            data,
212        })
213    }
214}
215
216impl<'data, Elf: FileHeader> Iterator for AttributesSubsubsectionIterator<'data, Elf> {
217    type Item = Result<AttributesSubsubsection<'data>>;
218
219    fn next(&mut self) -> Option<Self::Item> {
220        self.next().transpose()
221    }
222}
223
224#[derive(Debug, Clone)]
229pub struct AttributesSubsubsection<'data> {
230    tag: u8,
231    length: u32,
232    indices: Bytes<'data>,
233    data: Bytes<'data>,
234}
235
236impl<'data> AttributesSubsubsection<'data> {
237    pub fn tag(&self) -> u8 {
239        self.tag
240    }
241
242    pub fn length(&self) -> u32 {
244        self.length
245    }
246
247    pub fn indices_data(&self) -> &'data [u8] {
249        self.indices.0
250    }
251
252    pub fn indices(&self) -> AttributeIndexIterator<'data> {
258        AttributeIndexIterator { data: self.indices }
259    }
260
261    pub fn attributes_data(&self) -> &'data [u8] {
263        self.data.0
264    }
265
266    pub fn attributes(&self) -> AttributeReader<'data> {
268        AttributeReader { data: self.data }
269    }
270}
271
272#[derive(Debug, Clone)]
274pub struct AttributeIndexIterator<'data> {
275    data: Bytes<'data>,
276}
277
278impl<'data> AttributeIndexIterator<'data> {
279    pub fn next(&mut self) -> Result<Option<u32>> {
281        if self.data.is_empty() {
282            return Ok(None);
283        }
284
285        let result = self.parse().map(Some);
286        if result.is_err() {
287            self.data = Bytes(&[]);
288        }
289        result
290    }
291
292    fn parse(&mut self) -> Result<u32> {
293        let err = "Invalid ELF attribute index";
294        self.data
295            .read_uleb128()
296            .read_error(err)?
297            .try_into()
298            .map_err(|_| ())
299            .read_error(err)
300    }
301}
302
303impl<'data> Iterator for AttributeIndexIterator<'data> {
304    type Item = Result<u32>;
305
306    fn next(&mut self) -> Option<Self::Item> {
307        self.next().transpose()
308    }
309}
310
311#[derive(Debug, Clone)]
315pub struct AttributeReader<'data> {
316    data: Bytes<'data>,
317}
318
319impl<'data> AttributeReader<'data> {
320    pub fn read_tag(&mut self) -> Result<Option<u64>> {
322        if self.data.is_empty() {
323            return Ok(None);
324        }
325        let err = "Invalid ELF attribute tag";
326        self.data.read_uleb128().read_error(err).map(Some)
327    }
328
329    pub fn read_integer(&mut self) -> Result<u64> {
331        let err = "Invalid ELF attribute integer value";
332        self.data.read_uleb128().read_error(err)
333    }
334
335    pub fn read_string(&mut self) -> Result<&'data [u8]> {
337        let err = "Invalid ELF attribute string value";
338        self.data.read_string().read_error(err)
339    }
340}