use crate::common::{DebugInfoOffset, SectionId}; use crate::endianity::Endianity; use crate::read::lookup::{DebugLookup, LookupEntryIter, PubStuffEntry, PubStuffParser}; use crate::read::{EndianSlice, Reader, Result, Section, UnitOffset}; /// A single parsed pubtype. #[derive(Debug, Clone)] pub struct PubTypesEntry { unit_header_offset: DebugInfoOffset, die_offset: UnitOffset, name: R, } impl PubTypesEntry { /// Returns the name of the type this entry refers to. pub fn name(&self) -> &R { &self.name } /// Returns the offset into the .debug_info section for the header of the compilation unit /// which contains the type with this name. pub fn unit_header_offset(&self) -> DebugInfoOffset { self.unit_header_offset } /// Returns the offset into the compilation unit for the debugging information entry which /// the type with this name. pub fn die_offset(&self) -> UnitOffset { self.die_offset } } impl PubStuffEntry for PubTypesEntry { fn new( die_offset: UnitOffset, name: R, unit_header_offset: DebugInfoOffset, ) -> Self { PubTypesEntry { unit_header_offset, die_offset, name, } } } /// The `DebugPubTypes` struct represents the DWARF public types information /// found in the `.debug_info` section. #[derive(Debug, Clone)] pub struct DebugPubTypes(DebugLookup>>); impl<'input, Endian> DebugPubTypes> where Endian: Endianity, { /// Construct a new `DebugPubTypes` instance from the data in the `.debug_pubtypes` /// section. /// /// It is the caller's responsibility to read the `.debug_pubtypes` section and /// present it as a `&[u8]` slice. That means using some ELF loader on /// Linux, a Mach-O loader on macOS, etc. /// /// ``` /// use gimli::{DebugPubTypes, LittleEndian}; /// /// # let buf = []; /// # let read_debug_pubtypes_somehow = || &buf; /// let debug_pubtypes = /// DebugPubTypes::new(read_debug_pubtypes_somehow(), LittleEndian); /// ``` pub fn new(debug_pubtypes_section: &'input [u8], endian: Endian) -> Self { Self::from(EndianSlice::new(debug_pubtypes_section, endian)) } } impl DebugPubTypes { /// Iterate the pubtypes in the `.debug_pubtypes` section. /// /// ``` /// use gimli::{DebugPubTypes, EndianSlice, LittleEndian}; /// /// # let buf = []; /// # let read_debug_pubtypes_section_somehow = || &buf; /// let debug_pubtypes = /// DebugPubTypes::new(read_debug_pubtypes_section_somehow(), LittleEndian); /// /// let mut iter = debug_pubtypes.items(); /// while let Some(pubtype) = iter.next().unwrap() { /// println!("pubtype {} found!", pubtype.name().to_string_lossy()); /// } /// ``` pub fn items(&self) -> PubTypesEntryIter { PubTypesEntryIter(self.0.items()) } } impl Section for DebugPubTypes { fn id() -> SectionId { SectionId::DebugPubTypes } fn reader(&self) -> &R { self.0.reader() } } impl From for DebugPubTypes { fn from(debug_pubtypes_section: R) -> Self { DebugPubTypes(DebugLookup::from(debug_pubtypes_section)) } } /// An iterator over the pubtypes from a `.debug_pubtypes` section. /// /// Can be [used with /// `FallibleIterator`](./index.html#using-with-fallibleiterator). #[derive(Debug, Clone)] pub struct PubTypesEntryIter(LookupEntryIter>>); impl PubTypesEntryIter { /// Advance the iterator and return the next pubtype. /// /// Returns the newly parsed pubtype as `Ok(Some(pubtype))`. Returns /// `Ok(None)` when iteration is complete and all pubtypes have already been /// parsed and yielded. If an error occurs while parsing the next pubtype, /// then this error is returned as `Err(e)`, and all subsequent calls return /// `Ok(None)`. pub fn next(&mut self) -> Result>> { self.0.next() } } #[cfg(feature = "fallible-iterator")] impl fallible_iterator::FallibleIterator for PubTypesEntryIter { type Item = PubTypesEntry; type Error = crate::read::Error; fn next(&mut self) -> ::core::result::Result, Self::Error> { self.0.next() } }