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 pubname.
7#[derive(Debug, Clone)]
8pub struct PubNamesEntry<R: Reader> {
9 unit_header_offset: DebugInfoOffset<R::Offset>,
10 die_offset: UnitOffset<R::Offset>,
11 name: R,
12}
13
14impl<R: Reader> PubNamesEntry<R> {
15 /// Returns the name 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 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 /// has this name.
28 pub fn die_offset(&self) -> UnitOffset<R::Offset> {
29 self.die_offset
30 }
31}
32
33impl<R: Reader> PubStuffEntry<R> for PubNamesEntry<R> {
34 fn new(
35 die_offset: UnitOffset<R::Offset>,
36 name: R,
37 unit_header_offset: DebugInfoOffset<R::Offset>,
38 ) -> Self {
39 PubNamesEntry {
40 unit_header_offset,
41 die_offset,
42 name,
43 }
44 }
45}
46
47/// The `DebugPubNames` struct represents the DWARF public names information
48/// found in the `.debug_pubnames` section.
49#[derive(Debug, Clone)]
50pub struct DebugPubNames<R: Reader>(DebugLookup<R, PubStuffParser<R, PubNamesEntry<R>>>);
51
52impl<'input, Endian> DebugPubNames<EndianSlice<'input, Endian>>
53where
54 Endian: Endianity,
55{
56 /// Construct a new `DebugPubNames` instance from the data in the `.debug_pubnames`
57 /// section.
58 ///
59 /// It is the caller's responsibility to read the `.debug_pubnames` 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::{DebugPubNames, LittleEndian};
65 ///
66 /// # let buf = [];
67 /// # let read_debug_pubnames_section_somehow = || &buf;
68 /// let debug_pubnames =
69 /// DebugPubNames::new(read_debug_pubnames_section_somehow(), LittleEndian);
70 /// ```
71 pub fn new(debug_pubnames_section: &'input [u8], endian: Endian) -> Self {
72 Self::from(EndianSlice::new(slice:debug_pubnames_section, endian))
73 }
74}
75
76impl<R: Reader> DebugPubNames<R> {
77 /// Iterate the pubnames in the `.debug_pubnames` section.
78 ///
79 /// ```
80 /// use gimli::{DebugPubNames, EndianSlice, LittleEndian};
81 ///
82 /// # let buf = [];
83 /// # let read_debug_pubnames_section_somehow = || &buf;
84 /// let debug_pubnames =
85 /// DebugPubNames::new(read_debug_pubnames_section_somehow(), LittleEndian);
86 ///
87 /// let mut iter = debug_pubnames.items();
88 /// while let Some(pubname) = iter.next().unwrap() {
89 /// println!("pubname {} found!", pubname.name().to_string_lossy());
90 /// }
91 /// ```
92 pub fn items(&self) -> PubNamesEntryIter<R> {
93 PubNamesEntryIter(self.0.items())
94 }
95}
96
97impl<R: Reader> Section<R> for DebugPubNames<R> {
98 fn id() -> SectionId {
99 SectionId::DebugPubNames
100 }
101
102 fn reader(&self) -> &R {
103 self.0.reader()
104 }
105}
106
107impl<R: Reader> From<R> for DebugPubNames<R> {
108 fn from(debug_pubnames_section: R) -> Self {
109 DebugPubNames(DebugLookup::from(debug_pubnames_section))
110 }
111}
112
113/// An iterator over the pubnames from a `.debug_pubnames` section.
114///
115/// Can be [used with
116/// `FallibleIterator`](./index.html#using-with-fallibleiterator).
117#[derive(Debug, Clone)]
118pub struct PubNamesEntryIter<R: Reader>(LookupEntryIter<R, PubStuffParser<R, PubNamesEntry<R>>>);
119
120impl<R: Reader> PubNamesEntryIter<R> {
121 /// Advance the iterator and return the next pubname.
122 ///
123 /// Returns the newly parsed pubname as `Ok(Some(pubname))`. Returns
124 /// `Ok(None)` when iteration is complete and all pubnames have already been
125 /// parsed and yielded. If an error occurs while parsing the next pubname,
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<PubNamesEntry<R>>> {
129 self.0.next()
130 }
131}
132
133#[cfg(feature = "fallible-iterator")]
134impl<R: Reader> fallible_iterator::FallibleIterator for PubNamesEntryIter<R> {
135 type Item = PubNamesEntry<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}
142