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 pubname. 7 #[derive(Debug, Clone)] 8 pub struct PubNamesEntry<R: Reader> { 9 unit_header_offset: DebugInfoOffset<R::Offset>, 10 die_offset: UnitOffset<R::Offset>, 11 name: R, 12 } 13 14 impl<R: Reader> PubNamesEntry<R> { 15 /// Returns the name this entry refers to. name(&self) -> &R16 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. unit_header_offset(&self) -> DebugInfoOffset<R::Offset>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. die_offset(&self) -> UnitOffset<R::Offset>28 pub fn die_offset(&self) -> UnitOffset<R::Offset> { 29 self.die_offset 30 } 31 } 32 33 impl<R: Reader> PubStuffEntry<R> for PubNamesEntry<R> { new( die_offset: UnitOffset<R::Offset>, name: R, unit_header_offset: DebugInfoOffset<R::Offset>, ) -> Self34 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)] 50 pub struct DebugPubNames<R: Reader>(DebugLookup<R, PubStuffParser<R, PubNamesEntry<R>>>); 51 52 impl<'input, Endian> DebugPubNames<EndianSlice<'input, Endian>> 53 where 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 OSX, 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 /// ``` new(debug_pubnames_section: &'input [u8], endian: Endian) -> Self71 pub fn new(debug_pubnames_section: &'input [u8], endian: Endian) -> Self { 72 Self::from(EndianSlice::new(debug_pubnames_section, endian)) 73 } 74 } 75 76 impl<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 /// ``` items(&self) -> PubNamesEntryIter<R>92 pub fn items(&self) -> PubNamesEntryIter<R> { 93 PubNamesEntryIter(self.0.items()) 94 } 95 } 96 97 impl<R: Reader> Section<R> for DebugPubNames<R> { id() -> SectionId98 fn id() -> SectionId { 99 SectionId::DebugPubNames 100 } 101 reader(&self) -> &R102 fn reader(&self) -> &R { 103 self.0.reader() 104 } 105 } 106 107 impl<R: Reader> From<R> for DebugPubNames<R> { from(debug_pubnames_section: R) -> Self108 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)] 118 pub struct PubNamesEntryIter<R: Reader>(LookupEntryIter<R, PubStuffParser<R, PubNamesEntry<R>>>); 119 120 impl<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)`. next(&mut self) -> Result<Option<PubNamesEntry<R>>>128 pub fn next(&mut self) -> Result<Option<PubNamesEntry<R>>> { 129 self.0.next() 130 } 131 } 132 133 #[cfg(feature = "fallible-iterator")] 134 impl<R: Reader> fallible_iterator::FallibleIterator for PubNamesEntryIter<R> { 135 type Item = PubNamesEntry<R>; 136 type Error = crate::read::Error; 137 next(&mut self) -> ::core::result::Result<Option<Self::Item>, Self::Error>138 fn next(&mut self) -> ::core::result::Result<Option<Self::Item>, Self::Error> { 139 self.0.next() 140 } 141 } 142