diff options
Diffstat (limited to 'vendor/object/src/read/elf/attributes.rs')
-rw-r--r-- | vendor/object/src/read/elf/attributes.rs | 307 |
1 files changed, 0 insertions, 307 deletions
diff --git a/vendor/object/src/read/elf/attributes.rs b/vendor/object/src/read/elf/attributes.rs deleted file mode 100644 index bf6f35c..0000000 --- a/vendor/object/src/read/elf/attributes.rs +++ /dev/null @@ -1,307 +0,0 @@ -use core::convert::TryInto; - -use crate::elf; -use crate::endian; -use crate::read::{Bytes, Error, ReadError, Result}; - -use super::FileHeader; - -/// An ELF attributes section. -/// -/// This may be a GNU attributes section, or an architecture specific attributes section. -/// -/// An attributes section contains a series of [`AttributesSubsection`]. -/// -/// Returned by [`SectionHeader::attributes`](super::SectionHeader::attributes) -/// and [`SectionHeader::gnu_attributes`](super::SectionHeader::gnu_attributes). -#[derive(Debug, Clone)] -pub struct AttributesSection<'data, Elf: FileHeader> { - endian: Elf::Endian, - version: u8, - data: Bytes<'data>, -} - -impl<'data, Elf: FileHeader> AttributesSection<'data, Elf> { - /// Parse an ELF attributes section given the section data. - pub fn new(endian: Elf::Endian, data: &'data [u8]) -> Result<Self> { - let mut data = Bytes(data); - - // Skip the version field that is one byte long. - let version = *data - .read::<u8>() - .read_error("Invalid ELF attributes section offset or size")?; - - Ok(AttributesSection { - endian, - version, - data, - }) - } - - /// Return the version of the attributes section. - pub fn version(&self) -> u8 { - self.version - } - - /// Return an iterator over the subsections. - pub fn subsections(&self) -> Result<AttributesSubsectionIterator<'data, Elf>> { - // There is currently only one format version. - if self.version != b'A' { - return Err(Error("Unsupported ELF attributes section version")); - } - - Ok(AttributesSubsectionIterator { - endian: self.endian, - data: self.data, - }) - } -} - -/// An iterator for the subsections in an [`AttributesSection`]. -#[derive(Debug, Clone)] -pub struct AttributesSubsectionIterator<'data, Elf: FileHeader> { - endian: Elf::Endian, - data: Bytes<'data>, -} - -impl<'data, Elf: FileHeader> AttributesSubsectionIterator<'data, Elf> { - /// Return the next subsection. - pub fn next(&mut self) -> Result<Option<AttributesSubsection<'data, Elf>>> { - if self.data.is_empty() { - return Ok(None); - } - - let result = self.parse(); - if result.is_err() { - self.data = Bytes(&[]); - } - result - } - - fn parse(&mut self) -> Result<Option<AttributesSubsection<'data, Elf>>> { - // First read the subsection length. - let mut data = self.data; - let length = data - .read::<endian::U32Bytes<Elf::Endian>>() - .read_error("ELF attributes section is too short")? - .get(self.endian); - - // Now read the entire subsection, updating self.data. - let mut data = self - .data - .read_bytes(length as usize) - .read_error("Invalid ELF attributes subsection length")?; - // Skip the subsection length field. - data.skip(4) - .read_error("Invalid ELF attributes subsection length")?; - - let vendor = data - .read_string() - .read_error("Invalid ELF attributes vendor")?; - - Ok(Some(AttributesSubsection { - endian: self.endian, - length, - vendor, - data, - })) - } -} - -/// A subsection in an [`AttributesSection`]. -/// -/// A subsection is identified by a vendor name. It contains a series of -/// [`AttributesSubsubsection`]. -#[derive(Debug, Clone)] -pub struct AttributesSubsection<'data, Elf: FileHeader> { - endian: Elf::Endian, - length: u32, - vendor: &'data [u8], - data: Bytes<'data>, -} - -impl<'data, Elf: FileHeader> AttributesSubsection<'data, Elf> { - /// Return the length of the attributes subsection. - pub fn length(&self) -> u32 { - self.length - } - - /// Return the vendor name of the attributes subsection. - pub fn vendor(&self) -> &'data [u8] { - self.vendor - } - - /// Return an iterator over the sub-subsections. - pub fn subsubsections(&self) -> AttributesSubsubsectionIterator<'data, Elf> { - AttributesSubsubsectionIterator { - endian: self.endian, - data: self.data, - } - } -} - -/// An iterator for the sub-subsections in an [`AttributesSubsection`]. -#[derive(Debug, Clone)] -pub struct AttributesSubsubsectionIterator<'data, Elf: FileHeader> { - endian: Elf::Endian, - data: Bytes<'data>, -} - -impl<'data, Elf: FileHeader> AttributesSubsubsectionIterator<'data, Elf> { - /// Return the next sub-subsection. - pub fn next(&mut self) -> Result<Option<AttributesSubsubsection<'data>>> { - if self.data.is_empty() { - return Ok(None); - } - - let result = self.parse(); - if result.is_err() { - self.data = Bytes(&[]); - } - result - } - - fn parse(&mut self) -> Result<Option<AttributesSubsubsection<'data>>> { - // The format of a sub-section looks like this: - // - // <file-tag> <size> <attribute>* - // | <section-tag> <size> <section-number>* 0 <attribute>* - // | <symbol-tag> <size> <symbol-number>* 0 <attribute>* - let mut data = self.data; - let tag = *data - .read::<u8>() - .read_error("ELF attributes subsection is too short")?; - let length = data - .read::<endian::U32Bytes<Elf::Endian>>() - .read_error("ELF attributes subsection is too short")? - .get(self.endian); - - // Now read the entire sub-subsection, updating self.data. - let mut data = self - .data - .read_bytes(length as usize) - .read_error("Invalid ELF attributes sub-subsection length")?; - // Skip the tag and sub-subsection size field. - data.skip(1 + 4) - .read_error("Invalid ELF attributes sub-subsection length")?; - - let indices = if tag == elf::Tag_Section || tag == elf::Tag_Symbol { - data.read_string() - .map(Bytes) - .read_error("Missing ELF attributes sub-subsection indices")? - } else if tag == elf::Tag_File { - Bytes(&[]) - } else { - return Err(Error("Unimplemented ELF attributes sub-subsection tag")); - }; - - Ok(Some(AttributesSubsubsection { - tag, - length, - indices, - data, - })) - } -} - -/// A sub-subsection in an [`AttributesSubsection`]. -/// -/// A sub-subsection is identified by a tag. It contains an optional series of indices, -/// followed by a series of attributes. -#[derive(Debug, Clone)] -pub struct AttributesSubsubsection<'data> { - tag: u8, - length: u32, - indices: Bytes<'data>, - data: Bytes<'data>, -} - -impl<'data> AttributesSubsubsection<'data> { - /// Return the tag of the attributes sub-subsection. - pub fn tag(&self) -> u8 { - self.tag - } - - /// Return the length of the attributes sub-subsection. - pub fn length(&self) -> u32 { - self.length - } - - /// Return the data containing the indices. - pub fn indices_data(&self) -> &'data [u8] { - self.indices.0 - } - - /// Return the indices. - /// - /// This will be section indices if the tag is `Tag_Section`, - /// or symbol indices if the tag is `Tag_Symbol`, - /// and otherwise it will be empty. - pub fn indices(&self) -> AttributeIndexIterator<'data> { - AttributeIndexIterator { data: self.indices } - } - - /// Return the data containing the attributes. - pub fn attributes_data(&self) -> &'data [u8] { - self.data.0 - } - - /// Return a parser for the data containing the attributes. - pub fn attributes(&self) -> AttributeReader<'data> { - AttributeReader { data: self.data } - } -} - -/// An iterator over the indices in an [`AttributesSubsubsection`]. -#[derive(Debug, Clone)] -pub struct AttributeIndexIterator<'data> { - data: Bytes<'data>, -} - -impl<'data> AttributeIndexIterator<'data> { - /// Parse the next index. - pub fn next(&mut self) -> Result<Option<u32>> { - if self.data.is_empty() { - return Ok(None); - } - let err = "Invalid ELF attribute index"; - self.data - .read_uleb128() - .read_error(err)? - .try_into() - .map_err(|_| ()) - .read_error(err) - .map(Some) - } -} - -/// A parser for the attributes in an [`AttributesSubsubsection`]. -/// -/// The parser relies on the caller to know the format of the data for each attribute tag. -#[derive(Debug, Clone)] -pub struct AttributeReader<'data> { - data: Bytes<'data>, -} - -impl<'data> AttributeReader<'data> { - /// Parse a tag. - pub fn read_tag(&mut self) -> Result<Option<u64>> { - if self.data.is_empty() { - return Ok(None); - } - let err = "Invalid ELF attribute tag"; - self.data.read_uleb128().read_error(err).map(Some) - } - - /// Parse an integer value. - pub fn read_integer(&mut self) -> Result<u64> { - let err = "Invalid ELF attribute integer value"; - self.data.read_uleb128().read_error(err) - } - - /// Parse a string value. - pub fn read_string(&mut self) -> Result<&'data [u8]> { - let err = "Invalid ELF attribute string value"; - self.data.read_string().read_error(err) - } -} |