]>
Commit | Line | Data |
---|---|---|
f035d41b XL |
1 | use crate::common::{DebugInfoOffset, SectionId}; |
2 | use crate::endianity::Endianity; | |
3 | use crate::read::lookup::{DebugLookup, LookupEntryIter, PubStuffEntry, PubStuffParser}; | |
4 | use crate::read::{EndianSlice, Reader, Result, Section, UnitOffset}; | |
5 | ||
6 | /// A single parsed pubtype. | |
7 | #[derive(Debug, Clone)] | |
8 | pub struct PubTypesEntry<R: Reader> { | |
9 | unit_header_offset: DebugInfoOffset<R::Offset>, | |
10 | die_offset: UnitOffset<R::Offset>, | |
11 | name: R, | |
12 | } | |
13 | ||
14 | impl<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 | ||
33 | impl<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)] | |
50 | pub struct DebugPubTypes<R: Reader>(DebugLookup<R, PubStuffParser<R, PubTypesEntry<R>>>); | |
51 | ||
52 | impl<'input, Endian> DebugPubTypes<EndianSlice<'input, Endian>> | |
53 | where | |
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 OSX, 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 | ||
76 | impl<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 | ||
97 | impl<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 | ||
107 | impl<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)] | |
118 | pub struct PubTypesEntryIter<R: Reader>(LookupEntryIter<R, PubStuffParser<R, PubTypesEntry<R>>>); | |
119 | ||
120 | impl<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")] | |
134 | impl<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 | } |