aboutsummaryrefslogtreecommitdiff
path: root/vendor/object/src/read/elf/attributes.rs
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/object/src/read/elf/attributes.rs')
-rw-r--r--vendor/object/src/read/elf/attributes.rs307
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)
- }
-}