gimli/read/
pubtypes.rs

1use crate::common::{DebugInfoOffset, SectionId};
2use crate::endianity::Endianity;
3use crate::read::lookup::{DebugLookup, LookupEntryIter, PubStuffEntry, PubStuffParser};
4use crate::read::{EndianSlice, Reader, Result, Section, UnitOffset};
5
6/// A single parsed pubtype.
7#[derive(Debug, Clone)]
8pub struct PubTypesEntry<R: Reader> {
9    unit_header_offset: DebugInfoOffset<R::Offset>,
10    die_offset: UnitOffset<R::Offset>,
11    name: R,
12}
13
14impl<R: Reader> PubTypesEntry<R> {
15    /// Returns the name of the type this entry refers to.
16    pub fn name(&self) -> &R {
17        &self.name
18    }
19
20    /// Returns the offset into the .debug_info section for the header of the compilation unit
21    /// which contains the type with this name.
22    pub fn unit_header_offset(&self) -> DebugInfoOffset<R::Offset> {
23        self.unit_header_offset
24    }
25
26    /// Returns the offset into the compilation unit for the debugging information entry which
27    /// the type with this name.
28    pub fn die_offset(&self) -> UnitOffset<R::Offset> {
29        self.die_offset
30    }
31}
32
33impl<R: Reader> PubStuffEntry<R> for PubTypesEntry<R> {
34    fn new(
35        die_offset: UnitOffset<R::Offset>,
36        name: R,
37        unit_header_offset: DebugInfoOffset<R::Offset>,
38    ) -> Self {
39        PubTypesEntry {
40            unit_header_offset,
41            die_offset,
42            name,
43        }
44    }
45}
46
47/// The `DebugPubTypes` struct represents the DWARF public types information
48/// found in the `.debug_info` section.
49#[derive(Debug, Clone)]
50pub struct DebugPubTypes<R: Reader>(DebugLookup<R, PubStuffParser<R, PubTypesEntry<R>>>);
51
52impl<'input, Endian> DebugPubTypes<EndianSlice<'input, Endian>>
53where
54    Endian: Endianity,
55{
56    /// Construct a new `DebugPubTypes` instance from the data in the `.debug_pubtypes`
57    /// section.
58    ///
59    /// It is the caller's responsibility to read the `.debug_pubtypes` section and
60    /// present it as a `&[u8]` slice. That means using some ELF loader on
61    /// Linux, a Mach-O loader on macOS, etc.
62    ///
63    /// ```
64    /// use gimli::{DebugPubTypes, LittleEndian};
65    ///
66    /// # let buf = [];
67    /// # let read_debug_pubtypes_somehow = || &buf;
68    /// let debug_pubtypes =
69    ///     DebugPubTypes::new(read_debug_pubtypes_somehow(), LittleEndian);
70    /// ```
71    pub fn new(debug_pubtypes_section: &'input [u8], endian: Endian) -> Self {
72        Self::from(EndianSlice::new(debug_pubtypes_section, endian))
73    }
74}
75
76impl<R: Reader> DebugPubTypes<R> {
77    /// Iterate the pubtypes in the `.debug_pubtypes` section.
78    ///
79    /// ```
80    /// use gimli::{DebugPubTypes, EndianSlice, LittleEndian};
81    ///
82    /// # let buf = [];
83    /// # let read_debug_pubtypes_section_somehow = || &buf;
84    /// let debug_pubtypes =
85    ///     DebugPubTypes::new(read_debug_pubtypes_section_somehow(), LittleEndian);
86    ///
87    /// let mut iter = debug_pubtypes.items();
88    /// while let Some(pubtype) = iter.next().unwrap() {
89    ///   println!("pubtype {} found!", pubtype.name().to_string_lossy());
90    /// }
91    /// ```
92    pub fn items(&self) -> PubTypesEntryIter<R> {
93        PubTypesEntryIter(self.0.items())
94    }
95}
96
97impl<R: Reader> Section<R> for DebugPubTypes<R> {
98    fn id() -> SectionId {
99        SectionId::DebugPubTypes
100    }
101
102    fn reader(&self) -> &R {
103        self.0.reader()
104    }
105}
106
107impl<R: Reader> From<R> for DebugPubTypes<R> {
108    fn from(debug_pubtypes_section: R) -> Self {
109        DebugPubTypes(DebugLookup::from(debug_pubtypes_section))
110    }
111}
112
113/// An iterator over the pubtypes from a `.debug_pubtypes` section.
114///
115/// Can be [used with
116/// `FallibleIterator`](./index.html#using-with-fallibleiterator).
117#[derive(Debug, Clone)]
118pub struct PubTypesEntryIter<R: Reader>(LookupEntryIter<R, PubStuffParser<R, PubTypesEntry<R>>>);
119
120impl<R: Reader> PubTypesEntryIter<R> {
121    /// Advance the iterator and return the next pubtype.
122    ///
123    /// Returns the newly parsed pubtype as `Ok(Some(pubtype))`. Returns
124    /// `Ok(None)` when iteration is complete and all pubtypes have already been
125    /// parsed and yielded. If an error occurs while parsing the next pubtype,
126    /// then this error is returned as `Err(e)`, and all subsequent calls return
127    /// `Ok(None)`.
128    pub fn next(&mut self) -> Result<Option<PubTypesEntry<R>>> {
129        self.0.next()
130    }
131}
132
133#[cfg(feature = "fallible-iterator")]
134impl<R: Reader> fallible_iterator::FallibleIterator for PubTypesEntryIter<R> {
135    type Item = PubTypesEntry<R>;
136    type Error = crate::read::Error;
137
138    fn next(&mut self) -> ::core::result::Result<Option<Self::Item>, Self::Error> {
139        self.0.next()
140    }
141}