summaryrefslogtreecommitdiffstats
path: root/vendor/object-0.26.2/src/read/elf/version.rs
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/object-0.26.2/src/read/elf/version.rs')
-rw-r--r--vendor/object-0.26.2/src/read/elf/version.rs175
1 files changed, 175 insertions, 0 deletions
diff --git a/vendor/object-0.26.2/src/read/elf/version.rs b/vendor/object-0.26.2/src/read/elf/version.rs
new file mode 100644
index 000000000..099e27af3
--- /dev/null
+++ b/vendor/object-0.26.2/src/read/elf/version.rs
@@ -0,0 +1,175 @@
+use crate::elf;
+use crate::read::{Bytes, ReadError, Result};
+
+use super::FileHeader;
+
+/// An iterator over the entries in an ELF `SHT_GNU_verdef` section.
+#[derive(Debug, Clone)]
+pub struct VerdefIterator<'data, Elf: FileHeader> {
+ endian: Elf::Endian,
+ data: Bytes<'data>,
+}
+
+impl<'data, Elf: FileHeader> VerdefIterator<'data, Elf> {
+ pub(super) fn new(endian: Elf::Endian, data: &'data [u8]) -> Self {
+ VerdefIterator {
+ endian,
+ data: Bytes(data),
+ }
+ }
+
+ /// Return the next `Verdef` entry.
+ pub fn next(
+ &mut self,
+ ) -> Result<Option<(&'data elf::Verdef<Elf::Endian>, VerdauxIterator<'data, Elf>)>> {
+ if self.data.is_empty() {
+ return Ok(None);
+ }
+
+ let verdef = self
+ .data
+ .read_at::<elf::Verdef<_>>(0)
+ .read_error("ELF verdef is too short")?;
+
+ let mut verdaux_data = self.data;
+ verdaux_data
+ .skip(verdef.vd_aux.get(self.endian) as usize)
+ .read_error("Invalid ELF vd_aux")?;
+ let verdaux =
+ VerdauxIterator::new(self.endian, verdaux_data.0, verdef.vd_cnt.get(self.endian));
+
+ let next = verdef.vd_next.get(self.endian);
+ if next != 0 {
+ self.data
+ .skip(next as usize)
+ .read_error("Invalid ELF vd_next")?;
+ } else {
+ self.data = Bytes(&[]);
+ }
+ Ok(Some((verdef, verdaux)))
+ }
+}
+
+/// An iterator over the auxiliary records for an entry in an ELF `SHT_GNU_verdef` section.
+#[derive(Debug, Clone)]
+pub struct VerdauxIterator<'data, Elf: FileHeader> {
+ endian: Elf::Endian,
+ data: Bytes<'data>,
+ count: u16,
+}
+
+impl<'data, Elf: FileHeader> VerdauxIterator<'data, Elf> {
+ pub(super) fn new(endian: Elf::Endian, data: &'data [u8], count: u16) -> Self {
+ VerdauxIterator {
+ endian,
+ data: Bytes(data),
+ count,
+ }
+ }
+
+ /// Return the next `Verdaux` entry.
+ pub fn next(&mut self) -> Result<Option<&'data elf::Verdaux<Elf::Endian>>> {
+ if self.count == 0 {
+ return Ok(None);
+ }
+
+ let verdaux = self
+ .data
+ .read_at::<elf::Verdaux<_>>(0)
+ .read_error("ELF verdaux is too short")?;
+
+ self.data
+ .skip(verdaux.vda_next.get(self.endian) as usize)
+ .read_error("Invalid ELF vda_next")?;
+ self.count -= 1;
+ Ok(Some(verdaux))
+ }
+}
+
+/// An iterator over the entries in an ELF `SHT_GNU_verneed` section.
+#[derive(Debug, Clone)]
+pub struct VerneedIterator<'data, Elf: FileHeader> {
+ endian: Elf::Endian,
+ data: Bytes<'data>,
+}
+
+impl<'data, Elf: FileHeader> VerneedIterator<'data, Elf> {
+ pub(super) fn new(endian: Elf::Endian, data: &'data [u8]) -> Self {
+ VerneedIterator {
+ endian,
+ data: Bytes(data),
+ }
+ }
+
+ /// Return the next `Verneed` entry.
+ pub fn next(
+ &mut self,
+ ) -> Result<
+ Option<(
+ &'data elf::Verneed<Elf::Endian>,
+ VernauxIterator<'data, Elf>,
+ )>,
+ > {
+ if self.data.is_empty() {
+ return Ok(None);
+ }
+
+ let verneed = self
+ .data
+ .read_at::<elf::Verneed<_>>(0)
+ .read_error("ELF verneed is too short")?;
+
+ let mut vernaux_data = self.data;
+ vernaux_data
+ .skip(verneed.vn_aux.get(self.endian) as usize)
+ .read_error("Invalid ELF vn_aux")?;
+ let vernaux =
+ VernauxIterator::new(self.endian, vernaux_data.0, verneed.vn_cnt.get(self.endian));
+
+ let next = verneed.vn_next.get(self.endian);
+ if next != 0 {
+ self.data
+ .skip(next as usize)
+ .read_error("Invalid ELF vn_next")?;
+ } else {
+ self.data = Bytes(&[]);
+ }
+ Ok(Some((verneed, vernaux)))
+ }
+}
+
+/// An iterator over the auxiliary records for an entry in an ELF `SHT_GNU_verneed` section.
+#[derive(Debug, Clone)]
+pub struct VernauxIterator<'data, Elf: FileHeader> {
+ endian: Elf::Endian,
+ data: Bytes<'data>,
+ count: u16,
+}
+
+impl<'data, Elf: FileHeader> VernauxIterator<'data, Elf> {
+ pub(super) fn new(endian: Elf::Endian, data: &'data [u8], count: u16) -> Self {
+ VernauxIterator {
+ endian,
+ data: Bytes(data),
+ count,
+ }
+ }
+
+ /// Return the next `Vernaux` entry.
+ pub fn next(&mut self) -> Result<Option<&'data elf::Vernaux<Elf::Endian>>> {
+ if self.count == 0 {
+ return Ok(None);
+ }
+
+ let vernaux = self
+ .data
+ .read_at::<elf::Vernaux<_>>(0)
+ .read_error("ELF vernaux is too short")?;
+
+ self.data
+ .skip(vernaux.vna_next.get(self.endian) as usize)
+ .read_error("Invalid ELF vna_next")?;
+ self.count -= 1;
+ Ok(Some(vernaux))
+ }
+}