/// An iterator for the segments in an [`ElfFile32`](super::ElfFile32). pubtype 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). pubtype 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)] pubstruct 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>;
/// A segment in an [`ElfFile32`](super::ElfFile32). pubtype ElfSegment32<'data, 'file, Endian = Endianness, R = &'data [u8]> =
ElfSegment<'data, 'file, elf::FileHeader32<Endian>, R>; /// A segment in an [`ElfFile64`](super::ElfFile64). pubtype 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)] pubstruct 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> { /// Get the ELF file containing this segment. pubfn elf_file(&self) -> &'file ElfFile<'data, Elf, R> { self.file
}
/// Get the raw ELF program header for the segment. pubfn elf_program_header(&self) -> &'data Elf::ProgramHeader { self.segment
}
/// A trait for generic access to [`elf::ProgramHeader32`] and [`elf::ProgramHeader64`]. #[allow(missing_docs)] pubtrait ProgramHeader: Debug + Pod { type Elf: FileHeader<ProgramHeader = Self, Endian = Self::Endian, Word = Self::Word>; type Word: Into<u64>; type Endian: endian::Endian;
/// 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 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], ()> {
pod::slice_from_all_bytes(self.data(endian, data)?)
}
/// 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]>> { ifself.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 the data in an interpreter segment. /// /// Returns `Ok(None)` if the segment is not `PT_INTERP`. /// Returns `Err` for invalid values. fn interpreter<'data, R: ReadRef<'data>>(
&self,
endian: Self::Endian,
data: R,
) -> read::Result<Option<&'data [u8]>> { ifself.p_type(endian) != elf::PT_INTERP { return Ok(None);
} let data = self
.data(endian, data)
.read_error("Invalid ELF interpreter segment offset or size")?; let len = data
.iter()
.position(|&b| b == 0)
.read_error("Invalid ELF interpreter segment data")?;
Ok(Some(&data[..len]))
}
/// 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>>> { ifself.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>;
impl<Endian: endian::Endian> ProgramHeader for elf::ProgramHeader64<Endian> { type Word = u64; type Endian = Endian; type Elf = elf::FileHeader64<Endian>;
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.