Skip to content

Commit

Permalink
read: implement Iterator for more types
Browse files Browse the repository at this point in the history
  • Loading branch information
philipc committed Aug 3, 2024
1 parent 8a25b8e commit 1e47e24
Show file tree
Hide file tree
Showing 6 changed files with 171 additions and 0 deletions.
31 changes: 31 additions & 0 deletions src/read/elf/attributes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,14 @@ impl<'data, Elf: FileHeader> AttributesSubsectionIterator<'data, Elf> {
}
}

impl<'data, Elf: FileHeader> Iterator for AttributesSubsectionIterator<'data, Elf> {
type Item = Result<AttributesSubsection<'data, Elf>>;

fn next(&mut self) -> Option<Self::Item> {
self.next().transpose()
}
}

/// A subsection in an [`AttributesSection`].
///
/// A subsection is identified by a vendor name. It contains a series of
Expand Down Expand Up @@ -203,6 +211,14 @@ impl<'data, Elf: FileHeader> AttributesSubsubsectionIterator<'data, Elf> {
}
}

impl<'data, Elf: FileHeader> Iterator for AttributesSubsubsectionIterator<'data, Elf> {
type Item = Result<AttributesSubsubsection<'data>>;

fn next(&mut self) -> Option<Self::Item> {
self.next().transpose()
}
}

/// A sub-subsection in an [`AttributesSubsection`].
///
/// A sub-subsection is identified by a tag. It contains an optional series of indices,
Expand Down Expand Up @@ -274,6 +290,21 @@ impl<'data> AttributeIndexIterator<'data> {
}
}

impl<'data> Iterator for AttributeIndexIterator<'data> {
type Item = Result<u32>;

fn next(&mut self) -> Option<Self::Item> {
match self.next() {
Err(e) => {
self.data = Bytes(&[]);
Some(Err(e))
}
Ok(Some(v)) => Some(Ok(v)),
Ok(None) => None,
}
}
}

/// 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.
Expand Down
16 changes: 16 additions & 0 deletions src/read/elf/note.rs
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ where

impl<'data, Elf: FileHeader> Iterator for NoteIterator<'data, Elf> {
type Item = read::Result<Note<'data, Elf>>;

fn next(&mut self) -> Option<Self::Item> {
match self.next() {
Err(e) => {
Expand Down Expand Up @@ -255,6 +256,21 @@ impl<'data, Endian: endian::Endian> GnuPropertyIterator<'data, Endian> {
}
}

impl<'data, Endian: endian::Endian> Iterator for GnuPropertyIterator<'data, Endian> {
type Item = read::Result<GnuProperty<'data>>;

fn next(&mut self) -> Option<Self::Item> {
match self.next() {
Err(e) => {
self.data = Bytes(&[]);
Some(Err(e))
}
Ok(Some(v)) => Some(Ok(v)),
Ok(None) => None,
}
}
}

/// A property in a [`elf::NT_GNU_PROPERTY_TYPE_0`] note.
#[derive(Debug)]
pub struct GnuProperty<'data> {
Expand Down
63 changes: 63 additions & 0 deletions src/read/elf/version.rs
Original file line number Diff line number Diff line change
Expand Up @@ -276,6 +276,21 @@ impl<'data, Elf: FileHeader> VerdefIterator<'data, Elf> {
}
}

impl<'data, Elf: FileHeader> Iterator for VerdefIterator<'data, Elf> {
type Item = Result<(&'data elf::Verdef<Elf::Endian>, VerdauxIterator<'data, Elf>)>;

fn next(&mut self) -> Option<Self::Item> {
match self.next() {
Err(e) => {
self.data = Bytes(&[]);
Some(Err(e))
}
Ok(Some(v)) => Some(Ok(v)),
Ok(None) => None,
}
}
}

/// An iterator for the auxiliary records for an entry in an ELF [`elf::SHT_GNU_VERDEF`] section.
#[derive(Debug, Clone)]
pub struct VerdauxIterator<'data, Elf: FileHeader> {
Expand Down Expand Up @@ -312,6 +327,21 @@ impl<'data, Elf: FileHeader> VerdauxIterator<'data, Elf> {
}
}

impl<'data, Elf: FileHeader> Iterator for VerdauxIterator<'data, Elf> {
type Item = Result<&'data elf::Verdaux<Elf::Endian>>;

fn next(&mut self) -> Option<Self::Item> {
match self.next() {
Err(e) => {
self.data = Bytes(&[]);
Some(Err(e))
}
Ok(Some(v)) => Some(Ok(v)),
Ok(None) => None,
}
}
}

/// An iterator for the entries in an ELF [`elf::SHT_GNU_VERNEED`] section.
#[derive(Debug, Clone)]
pub struct VerneedIterator<'data, Elf: FileHeader> {
Expand Down Expand Up @@ -364,6 +394,24 @@ impl<'data, Elf: FileHeader> VerneedIterator<'data, Elf> {
}
}

impl<'data, Elf: FileHeader> Iterator for VerneedIterator<'data, Elf> {
type Item = Result<(
&'data elf::Verneed<Elf::Endian>,
VernauxIterator<'data, Elf>,
)>;

fn next(&mut self) -> Option<Self::Item> {
match self.next() {
Err(e) => {
self.data = Bytes(&[]);
Some(Err(e))
}
Ok(Some(v)) => Some(Ok(v)),
Ok(None) => None,
}
}
}

/// An iterator for the auxiliary records for an entry in an ELF [`elf::SHT_GNU_VERNEED`] section.
#[derive(Debug, Clone)]
pub struct VernauxIterator<'data, Elf: FileHeader> {
Expand Down Expand Up @@ -400,6 +448,21 @@ impl<'data, Elf: FileHeader> VernauxIterator<'data, Elf> {
}
}

impl<'data, Elf: FileHeader> Iterator for VernauxIterator<'data, Elf> {
type Item = Result<&'data elf::Vernaux<Elf::Endian>>;

fn next(&mut self) -> Option<Self::Item> {
match self.next() {
Err(e) => {
self.data = Bytes(&[]);
Some(Err(e))
}
Ok(Some(v)) => Some(Ok(v)),
Ok(None) => None,
}
}
}

impl<Endian: endian::Endian> elf::Verdaux<Endian> {
/// Parse the version name from the string table.
pub fn name<'data, R: ReadRef<'data>>(
Expand Down
16 changes: 16 additions & 0 deletions src/read/macho/load_command.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,22 @@ impl<'data, E: Endian> LoadCommandIterator<'data, E> {
}
}

impl<'data, E: Endian> Iterator for LoadCommandIterator<'data, E> {
type Item = Result<LoadCommandData<'data, E>>;

fn next(&mut self) -> Option<Self::Item> {
match self.next() {
Err(e) => {
self.ncmds = 0;
self.data = Bytes(&[]);
Some(Err(e))
}
Ok(Some(v)) => Some(Ok(v)),
Ok(None) => None,
}
}
}

/// The data for a [`macho::LoadCommand`].
#[derive(Debug, Clone, Copy)]
pub struct LoadCommandData<'data, E: Endian> {
Expand Down
30 changes: 30 additions & 0 deletions src/read/pe/import.rs
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,21 @@ impl<'data> ImportDescriptorIterator<'data> {
}
}

impl<'data> Iterator for ImportDescriptorIterator<'data> {
type Item = Result<&'data pe::ImageImportDescriptor>;

fn next(&mut self) -> Option<Self::Item> {
match self.next() {
Err(e) => {
self.data = Bytes(&[]);
Some(Err(e))
}
Ok(Some(v)) => Some(Ok(v)),
Ok(None) => None,
}
}
}

/// A list of import thunks.
///
/// These may be in the import lookup table, or the import address table.
Expand Down Expand Up @@ -337,3 +352,18 @@ impl<'data> DelayLoadDescriptorIterator<'data> {
}
}
}

impl<'data> Iterator for DelayLoadDescriptorIterator<'data> {
type Item = Result<&'data pe::ImageDelayloadDescriptor>;

fn next(&mut self) -> Option<Self::Item> {
match self.next() {
Err(e) => {
self.data = Bytes(&[]);
Some(Err(e))
}
Ok(Some(v)) => Some(Ok(v)),
Ok(None) => None,
}
}
}
15 changes: 15 additions & 0 deletions src/read/pe/relocation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,21 @@ impl<'data> RelocationBlockIterator<'data> {
}
}

impl<'data> Iterator for RelocationBlockIterator<'data> {
type Item = Result<RelocationIterator<'data>>;

fn next(&mut self) -> Option<Self::Item> {
match self.next() {
Err(e) => {
self.data = Bytes(&[]);
Some(Err(e))
}
Ok(Some(v)) => Some(Ok(v)),
Ok(None) => None,
}
}
}

/// An iterator of the relocations in a block in the `.reloc` section of a PE file.
#[derive(Debug, Clone)]
pub struct RelocationIterator<'data> {
Expand Down

0 comments on commit 1e47e24

Please sign in to comment.