aboutsummaryrefslogtreecommitdiff
path: root/vendor/object/src/read/elf/segment.rs
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/object/src/read/elf/segment.rs')
-rw-r--r--vendor/object/src/read/elf/segment.rs334
1 files changed, 0 insertions, 334 deletions
diff --git a/vendor/object/src/read/elf/segment.rs b/vendor/object/src/read/elf/segment.rs
deleted file mode 100644
index 957117a..0000000
--- a/vendor/object/src/read/elf/segment.rs
+++ /dev/null
@@ -1,334 +0,0 @@
-use core::fmt::Debug;
-use core::{mem, slice, str};
-
-use crate::elf;
-use crate::endian::{self, Endianness};
-use crate::pod::Pod;
-use crate::read::{self, Bytes, ObjectSegment, ReadError, ReadRef, SegmentFlags};
-
-use super::{ElfFile, FileHeader, NoteIterator};
-
-/// An iterator for the segments in an [`ElfFile32`](super::ElfFile32).
-pub type ElfSegmentIterator32<'data, 'file, Endian = Endianness, R = &'data [u8]> =
- ElfSegmentIterator<'data, 'file, elf::FileHeader32<Endian>, R>;
-/// An iterator for the segments in an [`ElfFile64`](super::ElfFile64).
-pub type ElfSegmentIterator64<'data, 'file, Endian = Endianness, R = &'data [u8]> =
- ElfSegmentIterator<'data, 'file, elf::FileHeader64<Endian>, R>;
-
-/// An iterator for the segments in an [`ElfFile`].
-#[derive(Debug)]
-pub struct ElfSegmentIterator<'data, 'file, Elf, R = &'data [u8]>
-where
- Elf: FileHeader,
- R: ReadRef<'data>,
-{
- pub(super) file: &'file ElfFile<'data, Elf, R>,
- pub(super) iter: slice::Iter<'data, Elf::ProgramHeader>,
-}
-
-impl<'data, 'file, Elf, R> Iterator for ElfSegmentIterator<'data, 'file, Elf, R>
-where
- Elf: FileHeader,
- R: ReadRef<'data>,
-{
- type Item = ElfSegment<'data, 'file, Elf, R>;
-
- fn next(&mut self) -> Option<Self::Item> {
- for segment in self.iter.by_ref() {
- if segment.p_type(self.file.endian) == elf::PT_LOAD {
- return Some(ElfSegment {
- file: self.file,
- segment,
- });
- }
- }
- None
- }
-}
-
-/// A segment in an [`ElfFile32`](super::ElfFile32).
-pub type ElfSegment32<'data, 'file, Endian = Endianness, R = &'data [u8]> =
- ElfSegment<'data, 'file, elf::FileHeader32<Endian>, R>;
-/// A segment in an [`ElfFile64`](super::ElfFile64).
-pub type ElfSegment64<'data, 'file, Endian = Endianness, R = &'data [u8]> =
- ElfSegment<'data, 'file, elf::FileHeader64<Endian>, R>;
-
-/// A segment in an [`ElfFile`].
-///
-/// Most functionality is provided by the [`ObjectSegment`] trait implementation.
-#[derive(Debug)]
-pub struct ElfSegment<'data, 'file, Elf, R = &'data [u8]>
-where
- Elf: FileHeader,
- R: ReadRef<'data>,
-{
- pub(super) file: &'file ElfFile<'data, Elf, R>,
- pub(super) segment: &'data Elf::ProgramHeader,
-}
-
-impl<'data, 'file, Elf: FileHeader, R: ReadRef<'data>> ElfSegment<'data, 'file, Elf, R> {
- fn bytes(&self) -> read::Result<&'data [u8]> {
- self.segment
- .data(self.file.endian, self.file.data)
- .read_error("Invalid ELF segment size or offset")
- }
-}
-
-impl<'data, 'file, Elf, R> read::private::Sealed for ElfSegment<'data, 'file, Elf, R>
-where
- Elf: FileHeader,
- R: ReadRef<'data>,
-{
-}
-
-impl<'data, 'file, Elf, R> ObjectSegment<'data> for ElfSegment<'data, 'file, Elf, R>
-where
- Elf: FileHeader,
- R: ReadRef<'data>,
-{
- #[inline]
- fn address(&self) -> u64 {
- self.segment.p_vaddr(self.file.endian).into()
- }
-
- #[inline]
- fn size(&self) -> u64 {
- self.segment.p_memsz(self.file.endian).into()
- }
-
- #[inline]
- fn align(&self) -> u64 {
- self.segment.p_align(self.file.endian).into()
- }
-
- #[inline]
- fn file_range(&self) -> (u64, u64) {
- self.segment.file_range(self.file.endian)
- }
-
- #[inline]
- fn data(&self) -> read::Result<&'data [u8]> {
- self.bytes()
- }
-
- fn data_range(&self, address: u64, size: u64) -> read::Result<Option<&'data [u8]>> {
- Ok(read::util::data_range(
- self.bytes()?,
- self.address(),
- address,
- size,
- ))
- }
-
- #[inline]
- fn name_bytes(&self) -> read::Result<Option<&[u8]>> {
- Ok(None)
- }
-
- #[inline]
- fn name(&self) -> read::Result<Option<&str>> {
- Ok(None)
- }
-
- #[inline]
- fn flags(&self) -> SegmentFlags {
- let p_flags = self.segment.p_flags(self.file.endian);
- SegmentFlags::Elf { p_flags }
- }
-}
-
-/// A trait for generic access to [`elf::ProgramHeader32`] and [`elf::ProgramHeader64`].
-#[allow(missing_docs)]
-pub trait ProgramHeader: Debug + Pod {
- type Elf: FileHeader<ProgramHeader = Self, Endian = Self::Endian, Word = Self::Word>;
- type Word: Into<u64>;
- type Endian: endian::Endian;
-
- fn p_type(&self, endian: Self::Endian) -> u32;
- fn p_flags(&self, endian: Self::Endian) -> u32;
- fn p_offset(&self, endian: Self::Endian) -> Self::Word;
- fn p_vaddr(&self, endian: Self::Endian) -> Self::Word;
- fn p_paddr(&self, endian: Self::Endian) -> Self::Word;
- fn p_filesz(&self, endian: Self::Endian) -> Self::Word;
- fn p_memsz(&self, endian: Self::Endian) -> Self::Word;
- fn p_align(&self, endian: Self::Endian) -> Self::Word;
-
- /// Return the offset and size of the segment in the file.
- fn file_range(&self, endian: Self::Endian) -> (u64, u64) {
- (self.p_offset(endian).into(), self.p_filesz(endian).into())
- }
-
- /// Return the segment data.
- ///
- /// Returns `Err` for invalid values.
- fn data<'data, R: ReadRef<'data>>(
- &self,
- endian: Self::Endian,
- data: R,
- ) -> Result<&'data [u8], ()> {
- let (offset, size) = self.file_range(endian);
- data.read_bytes_at(offset, size)
- }
-
- /// Return the segment data as a slice of the given type.
- ///
- /// Allows padding at the end of the data.
- /// Returns `Ok(&[])` if the segment has no data.
- /// Returns `Err` for invalid values, including bad alignment.
- fn data_as_array<'data, T: Pod, R: ReadRef<'data>>(
- &self,
- endian: Self::Endian,
- data: R,
- ) -> Result<&'data [T], ()> {
- let mut data = self.data(endian, data).map(Bytes)?;
- data.read_slice(data.len() / mem::size_of::<T>())
- }
-
- /// Return the segment data in the given virtual address range
- ///
- /// Returns `Ok(None)` if the segment does not contain the address.
- /// Returns `Err` for invalid values.
- fn data_range<'data, R: ReadRef<'data>>(
- &self,
- endian: Self::Endian,
- data: R,
- address: u64,
- size: u64,
- ) -> Result<Option<&'data [u8]>, ()> {
- Ok(read::util::data_range(
- self.data(endian, data)?,
- self.p_vaddr(endian).into(),
- address,
- size,
- ))
- }
-
- /// Return entries in a dynamic segment.
- ///
- /// Returns `Ok(None)` if the segment is not `PT_DYNAMIC`.
- /// Returns `Err` for invalid values.
- fn dynamic<'data, R: ReadRef<'data>>(
- &self,
- endian: Self::Endian,
- data: R,
- ) -> read::Result<Option<&'data [<Self::Elf as FileHeader>::Dyn]>> {
- if self.p_type(endian) != elf::PT_DYNAMIC {
- return Ok(None);
- }
- let dynamic = self
- .data_as_array(endian, data)
- .read_error("Invalid ELF dynamic segment offset or size")?;
- Ok(Some(dynamic))
- }
-
- /// Return a note iterator for the segment data.
- ///
- /// Returns `Ok(None)` if the segment does not contain notes.
- /// Returns `Err` for invalid values.
- fn notes<'data, R: ReadRef<'data>>(
- &self,
- endian: Self::Endian,
- data: R,
- ) -> read::Result<Option<NoteIterator<'data, Self::Elf>>> {
- if self.p_type(endian) != elf::PT_NOTE {
- return Ok(None);
- }
- let data = self
- .data(endian, data)
- .read_error("Invalid ELF note segment offset or size")?;
- let notes = NoteIterator::new(endian, self.p_align(endian), data)?;
- Ok(Some(notes))
- }
-}
-
-impl<Endian: endian::Endian> ProgramHeader for elf::ProgramHeader32<Endian> {
- type Word = u32;
- type Endian = Endian;
- type Elf = elf::FileHeader32<Endian>;
-
- #[inline]
- fn p_type(&self, endian: Self::Endian) -> u32 {
- self.p_type.get(endian)
- }
-
- #[inline]
- fn p_flags(&self, endian: Self::Endian) -> u32 {
- self.p_flags.get(endian)
- }
-
- #[inline]
- fn p_offset(&self, endian: Self::Endian) -> Self::Word {
- self.p_offset.get(endian)
- }
-
- #[inline]
- fn p_vaddr(&self, endian: Self::Endian) -> Self::Word {
- self.p_vaddr.get(endian)
- }
-
- #[inline]
- fn p_paddr(&self, endian: Self::Endian) -> Self::Word {
- self.p_paddr.get(endian)
- }
-
- #[inline]
- fn p_filesz(&self, endian: Self::Endian) -> Self::Word {
- self.p_filesz.get(endian)
- }
-
- #[inline]
- fn p_memsz(&self, endian: Self::Endian) -> Self::Word {
- self.p_memsz.get(endian)
- }
-
- #[inline]
- fn p_align(&self, endian: Self::Endian) -> Self::Word {
- self.p_align.get(endian)
- }
-}
-
-impl<Endian: endian::Endian> ProgramHeader for elf::ProgramHeader64<Endian> {
- type Word = u64;
- type Endian = Endian;
- type Elf = elf::FileHeader64<Endian>;
-
- #[inline]
- fn p_type(&self, endian: Self::Endian) -> u32 {
- self.p_type.get(endian)
- }
-
- #[inline]
- fn p_flags(&self, endian: Self::Endian) -> u32 {
- self.p_flags.get(endian)
- }
-
- #[inline]
- fn p_offset(&self, endian: Self::Endian) -> Self::Word {
- self.p_offset.get(endian)
- }
-
- #[inline]
- fn p_vaddr(&self, endian: Self::Endian) -> Self::Word {
- self.p_vaddr.get(endian)
- }
-
- #[inline]
- fn p_paddr(&self, endian: Self::Endian) -> Self::Word {
- self.p_paddr.get(endian)
- }
-
- #[inline]
- fn p_filesz(&self, endian: Self::Endian) -> Self::Word {
- self.p_filesz.get(endian)
- }
-
- #[inline]
- fn p_memsz(&self, endian: Self::Endian) -> Self::Word {
- self.p_memsz.get(endian)
- }
-
- #[inline]
- fn p_align(&self, endian: Self::Endian) -> Self::Word {
- self.p_align.get(endian)
- }
-}