object/read/elf/
attributes.rs

1use core::convert::TryInto;
2
3use crate::elf;
4use crate::endian;
5use crate::read::{Bytes, Error, ReadError, Result};
6
7use super::FileHeader;
8
9/// An ELF attributes section.
10///
11/// This may be a GNU attributes section, or an architecture specific attributes section.
12///
13/// An attributes section contains a series of [`AttributesSubsection`].
14///
15/// Returned by [`SectionHeader::attributes`](super::SectionHeader::attributes)
16/// and [`SectionHeader::gnu_attributes`](super::SectionHeader::gnu_attributes).
17#[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    /// Parse an ELF attributes section given the section data.
26    pub fn new(endian: Elf::Endian, data: &'data [u8]) -> Result<Self> {
27        let mut data = Bytes(data);
28
29        // Skip the version field that is one byte long.
30        // If the section is empty then the version doesn't matter.
31        let version = data.read::<u8>().cloned().unwrap_or(b'A');
32
33        Ok(AttributesSection {
34            endian,
35            version,
36            data,
37        })
38    }
39
40    /// Return the version of the attributes section.
41    pub fn version(&self) -> u8 {
42        self.version
43    }
44
45    /// Return an iterator over the subsections.
46    pub fn subsections(&self) -> Result<AttributesSubsectionIterator<'data, Elf>> {
47        // There is currently only one format version.
48        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/// An iterator for the subsections in an [`AttributesSection`].
60#[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    /// Return the next subsection.
68    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        // First read the subsection length.
82        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        // Now read the entire subsection, updating self.data.
89        let mut data = self
90            .data
91            .read_bytes(length as usize)
92            .read_error("Invalid ELF attributes subsection length")?;
93        // Skip the subsection length field.
94        data.skip(4)
95            .read_error("Invalid ELF attributes subsection length")?;
96
97        // TODO: errors here should not prevent reading the next subsection.
98        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/// A subsection in an [`AttributesSection`].
120///
121/// A subsection is identified by a vendor name.  It contains a series of
122/// [`AttributesSubsubsection`].
123#[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    /// Return the length of the attributes subsection.
133    pub fn length(&self) -> u32 {
134        self.length
135    }
136
137    /// Return the vendor name of the attributes subsection.
138    pub fn vendor(&self) -> &'data [u8] {
139        self.vendor
140    }
141
142    /// Return an iterator over the sub-subsections.
143    pub fn subsubsections(&self) -> AttributesSubsubsectionIterator<'data, Elf> {
144        AttributesSubsubsectionIterator {
145            endian: self.endian,
146            data: self.data,
147        }
148    }
149}
150
151/// An iterator for the sub-subsections in an [`AttributesSubsection`].
152#[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    /// Return the next sub-subsection.
160    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        // The format of a sub-section looks like this:
174        //
175        // <file-tag> <size> <attribute>*
176        // | <section-tag> <size> <section-number>* 0 <attribute>*
177        // | <symbol-tag> <size> <symbol-number>* 0 <attribute>*
178        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        // Now read the entire sub-subsection, updating self.data.
188        let mut data = self
189            .data
190            .read_bytes(length as usize)
191            .read_error("Invalid ELF attributes sub-subsection length")?;
192        // Skip the tag and sub-subsection size field.
193        data.skip(1 + 4)
194            .read_error("Invalid ELF attributes sub-subsection length")?;
195
196        // TODO: errors here should not prevent reading the next sub-subsection.
197        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/// A sub-subsection in an [`AttributesSubsection`].
225///
226/// A sub-subsection is identified by a tag.  It contains an optional series of indices,
227/// followed by a series of attributes.
228#[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    /// Return the tag of the attributes sub-subsection.
238    pub fn tag(&self) -> u8 {
239        self.tag
240    }
241
242    /// Return the length of the attributes sub-subsection.
243    pub fn length(&self) -> u32 {
244        self.length
245    }
246
247    /// Return the data containing the indices.
248    pub fn indices_data(&self) -> &'data [u8] {
249        self.indices.0
250    }
251
252    /// Return the indices.
253    ///
254    /// This will be section indices if the tag is `Tag_Section`,
255    /// or symbol indices if the tag is `Tag_Symbol`,
256    /// and otherwise it will be empty.
257    pub fn indices(&self) -> AttributeIndexIterator<'data> {
258        AttributeIndexIterator { data: self.indices }
259    }
260
261    /// Return the data containing the attributes.
262    pub fn attributes_data(&self) -> &'data [u8] {
263        self.data.0
264    }
265
266    /// Return a parser for the data containing the attributes.
267    pub fn attributes(&self) -> AttributeReader<'data> {
268        AttributeReader { data: self.data }
269    }
270}
271
272/// An iterator over the indices in an [`AttributesSubsubsection`].
273#[derive(Debug, Clone)]
274pub struct AttributeIndexIterator<'data> {
275    data: Bytes<'data>,
276}
277
278impl<'data> AttributeIndexIterator<'data> {
279    /// Parse the next index.
280    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/// A parser for the attributes in an [`AttributesSubsubsection`].
312///
313/// The parser relies on the caller to know the format of the data for each attribute tag.
314#[derive(Debug, Clone)]
315pub struct AttributeReader<'data> {
316    data: Bytes<'data>,
317}
318
319impl<'data> AttributeReader<'data> {
320    /// Parse a tag.
321    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    /// Parse an integer value.
330    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    /// Parse a string value.
336    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}