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#[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}