1 //! Functions for parsing DWARF `.debug_info` and `.debug_types` sections.
2 
3 use core::cell::Cell;
4 use core::ops::{Range, RangeFrom, RangeTo};
5 use core::{u16, u8};
6 
7 use crate::common::{
8     DebugAbbrevOffset, DebugAddrBase, DebugAddrIndex, DebugInfoOffset, DebugLineOffset,
9     DebugLineStrOffset, DebugLocListsBase, DebugLocListsIndex, DebugMacinfoOffset,
10     DebugMacroOffset, DebugRngListsBase, DebugRngListsIndex, DebugStrOffset, DebugStrOffsetsBase,
11     DebugStrOffsetsIndex, DebugTypeSignature, DebugTypesOffset, Encoding, Format,
12     LocationListsOffset, RangeListsOffset, SectionId,
13 };
14 use crate::constants;
15 use crate::endianity::Endianity;
16 use crate::read::{
17     Abbreviation, Abbreviations, AttributeSpecification, DebugAbbrev, DebugStr, EndianSlice, Error,
18     Expression, Reader, ReaderOffset, Result, Section,
19 };
20 
21 impl<T: ReaderOffset> DebugTypesOffset<T> {
22     /// Convert an offset to be relative to the start of the given unit,
23     /// instead of relative to the start of the .debug_types section.
24     /// Returns `None` if the offset is not within the unit entries.
to_unit_offset<R>(&self, unit: &TypeUnitHeader<R>) -> Option<UnitOffset<T>> where R: Reader<Offset = T>,25     pub fn to_unit_offset<R>(&self, unit: &TypeUnitHeader<R>) -> Option<UnitOffset<T>>
26     where
27         R: Reader<Offset = T>,
28     {
29         let offset = match self.0.checked_sub(unit.offset.0) {
30             Some(offset) => UnitOffset(offset),
31             None => return None,
32         };
33         if !unit.header.is_valid_offset(offset) {
34             return None;
35         }
36         Some(offset)
37     }
38 }
39 
40 impl<T: ReaderOffset> DebugInfoOffset<T> {
41     /// Convert an offset to be relative to the start of the given unit,
42     /// instead of relative to the start of the .debug_info section.
43     /// Returns `None` if the offset is not within this unit entries.
to_unit_offset<R>(&self, unit: &CompilationUnitHeader<R>) -> Option<UnitOffset<T>> where R: Reader<Offset = T>,44     pub fn to_unit_offset<R>(&self, unit: &CompilationUnitHeader<R>) -> Option<UnitOffset<T>>
45     where
46         R: Reader<Offset = T>,
47     {
48         let offset = match self.0.checked_sub(unit.offset.0) {
49             Some(offset) => UnitOffset(offset),
50             None => return None,
51         };
52         if !unit.header.is_valid_offset(offset) {
53             return None;
54         }
55         Some(offset)
56     }
57 }
58 
59 /// An offset into the current compilation or type unit.
60 #[derive(Debug, Clone, Copy, PartialEq, Eq, Ord, PartialOrd, Hash)]
61 pub struct UnitOffset<T = usize>(pub T);
62 
63 impl<T: ReaderOffset> UnitOffset<T> {
64     /// Convert an offset to be relative to the start of the .debug_info section,
65     /// instead of relative to the start of the given compilation unit.
to_debug_info_offset<R>(&self, unit: &CompilationUnitHeader<R>) -> DebugInfoOffset<T> where R: Reader<Offset = T>,66     pub fn to_debug_info_offset<R>(&self, unit: &CompilationUnitHeader<R>) -> DebugInfoOffset<T>
67     where
68         R: Reader<Offset = T>,
69     {
70         DebugInfoOffset(unit.offset.0 + self.0)
71     }
72 
73     /// Convert an offset to be relative to the start of the .debug_types section,
74     /// instead of relative to the start of the given type unit.
to_debug_types_offset<R>(&self, unit: &TypeUnitHeader<R>) -> DebugTypesOffset<T> where R: Reader<Offset = T>,75     pub fn to_debug_types_offset<R>(&self, unit: &TypeUnitHeader<R>) -> DebugTypesOffset<T>
76     where
77         R: Reader<Offset = T>,
78     {
79         DebugTypesOffset(unit.offset.0 + self.0)
80     }
81 }
82 
83 /// The `DebugInfo` struct represents the DWARF debugging information found in
84 /// the `.debug_info` section.
85 #[derive(Debug, Default, Clone, Copy)]
86 pub struct DebugInfo<R> {
87     debug_info_section: R,
88 }
89 
90 impl<'input, Endian> DebugInfo<EndianSlice<'input, Endian>>
91 where
92     Endian: Endianity,
93 {
94     /// Construct a new `DebugInfo` instance from the data in the `.debug_info`
95     /// section.
96     ///
97     /// It is the caller's responsibility to read the `.debug_info` section and
98     /// present it as a `&[u8]` slice. That means using some ELF loader on
99     /// Linux, a Mach-O loader on OSX, etc.
100     ///
101     /// ```
102     /// use gimli::{DebugInfo, LittleEndian};
103     ///
104     /// # let buf = [0x00, 0x01, 0x02, 0x03];
105     /// # let read_debug_info_section_somehow = || &buf;
106     /// let debug_info = DebugInfo::new(read_debug_info_section_somehow(), LittleEndian);
107     /// ```
new(debug_info_section: &'input [u8], endian: Endian) -> Self108     pub fn new(debug_info_section: &'input [u8], endian: Endian) -> Self {
109         Self::from(EndianSlice::new(debug_info_section, endian))
110     }
111 }
112 
113 impl<R: Reader> DebugInfo<R> {
114     /// Iterate the compilation- and partial-units in this
115     /// `.debug_info` section.
116     ///
117     /// ```
118     /// use gimli::{DebugInfo, LittleEndian};
119     ///
120     /// # let buf = [];
121     /// # let read_debug_info_section_somehow = || &buf;
122     /// let debug_info = DebugInfo::new(read_debug_info_section_somehow(), LittleEndian);
123     ///
124     /// let mut iter = debug_info.units();
125     /// while let Some(unit) = iter.next().unwrap() {
126     ///     println!("unit's length is {}", unit.unit_length());
127     /// }
128     /// ```
129     ///
130     /// Can be [used with
131     /// `FallibleIterator`](./index.html#using-with-fallibleiterator).
units(&self) -> CompilationUnitHeadersIter<R>132     pub fn units(&self) -> CompilationUnitHeadersIter<R> {
133         CompilationUnitHeadersIter {
134             input: self.debug_info_section.clone(),
135             offset: DebugInfoOffset(R::Offset::from_u8(0)),
136         }
137     }
138 
139     /// Get the CompilationUnitHeader located at offset from this .debug_info section.
140     ///
141     ///
header_from_offset( &self, offset: DebugInfoOffset<R::Offset>, ) -> Result<CompilationUnitHeader<R>>142     pub fn header_from_offset(
143         &self,
144         offset: DebugInfoOffset<R::Offset>,
145     ) -> Result<CompilationUnitHeader<R>> {
146         let input = &mut self.debug_info_section.clone();
147         input.skip(offset.0)?;
148         CompilationUnitHeader::parse(input, offset)
149     }
150 }
151 
152 impl<T> DebugInfo<T> {
153     /// Create a `DebugInfo` section that references the data in `self`.
154     ///
155     /// This is useful when `R` implements `Reader` but `T` does not.
156     ///
157     /// ## Example Usage
158     ///
159     /// ```rust,no_run
160     /// # let load_section = || unimplemented!();
161     /// // Read the DWARF section into a `Vec` with whatever object loader you're using.
162     /// let owned_section: gimli::DebugInfo<Vec<u8>> = load_section();
163     /// // Create a reference to the DWARF section.
164     /// let section = owned_section.borrow(|section| {
165     ///     gimli::EndianSlice::new(&section, gimli::LittleEndian)
166     /// });
167     /// ```
borrow<'a, F, R>(&'a self, mut borrow: F) -> DebugInfo<R> where F: FnMut(&'a T) -> R,168     pub fn borrow<'a, F, R>(&'a self, mut borrow: F) -> DebugInfo<R>
169     where
170         F: FnMut(&'a T) -> R,
171     {
172         borrow(&self.debug_info_section).into()
173     }
174 }
175 
176 impl<R> Section<R> for DebugInfo<R> {
id() -> SectionId177     fn id() -> SectionId {
178         SectionId::DebugInfo
179     }
180 
reader(&self) -> &R181     fn reader(&self) -> &R {
182         &self.debug_info_section
183     }
184 }
185 
186 impl<R> From<R> for DebugInfo<R> {
from(debug_info_section: R) -> Self187     fn from(debug_info_section: R) -> Self {
188         DebugInfo { debug_info_section }
189     }
190 }
191 
192 /// An iterator over the compilation- and partial-units of a section.
193 ///
194 /// See the [documentation on
195 /// `DebugInfo::units`](./struct.DebugInfo.html#method.units) for more detail.
196 #[derive(Clone, Debug)]
197 pub struct CompilationUnitHeadersIter<R: Reader> {
198     input: R,
199     offset: DebugInfoOffset<R::Offset>,
200 }
201 
202 impl<R: Reader> CompilationUnitHeadersIter<R> {
203     /// Advance the iterator to the next unit header.
next(&mut self) -> Result<Option<CompilationUnitHeader<R>>>204     pub fn next(&mut self) -> Result<Option<CompilationUnitHeader<R>>> {
205         if self.input.is_empty() {
206             Ok(None)
207         } else {
208             let len = self.input.len();
209             match CompilationUnitHeader::parse(&mut self.input, self.offset) {
210                 Ok(header) => {
211                     self.offset.0 += len - self.input.len();
212                     Ok(Some(header))
213                 }
214                 Err(e) => {
215                     self.input.empty();
216                     Err(e)
217                 }
218             }
219         }
220     }
221 }
222 
223 #[cfg(feature = "fallible-iterator")]
224 impl<R: Reader> fallible_iterator::FallibleIterator for CompilationUnitHeadersIter<R> {
225     type Item = CompilationUnitHeader<R>;
226     type Error = Error;
227 
next(&mut self) -> ::core::result::Result<Option<Self::Item>, Self::Error>228     fn next(&mut self) -> ::core::result::Result<Option<Self::Item>, Self::Error> {
229         CompilationUnitHeadersIter::next(self)
230     }
231 }
232 
233 /// The header of a compilation unit's debugging information.
234 #[derive(Debug, Clone, Copy, PartialEq, Eq)]
235 pub struct CompilationUnitHeader<R, Offset = <R as Reader>::Offset>
236 where
237     R: Reader<Offset = Offset>,
238     Offset: ReaderOffset,
239 {
240     header: UnitHeader<R, Offset>,
241     offset: DebugInfoOffset<Offset>,
242 }
243 
244 impl<R, Offset> CompilationUnitHeader<R, Offset>
245 where
246     R: Reader<Offset = Offset>,
247     Offset: ReaderOffset,
248 {
249     /// Construct a new `CompilationUnitHeader`.
new(header: UnitHeader<R, Offset>, offset: DebugInfoOffset<Offset>) -> Self250     pub fn new(header: UnitHeader<R, Offset>, offset: DebugInfoOffset<Offset>) -> Self {
251         CompilationUnitHeader { header, offset }
252     }
253 
254     /// Return the `UnitHeader` containing common unit header fields.
header(self) -> UnitHeader<R, Offset>255     pub fn header(self) -> UnitHeader<R, Offset> {
256         self.header
257     }
258 
259     /// Return the serialized size of the compilation unit header for the given
260     /// DWARF encoding.
size_of_header(encoding: Encoding) -> usize261     pub fn size_of_header(encoding: Encoding) -> usize {
262         UnitHeader::<R, _>::size_of_header(encoding)
263     }
264 
265     /// Get the offset of this compilation unit within the .debug_info section.
offset(&self) -> DebugInfoOffset<R::Offset>266     pub fn offset(&self) -> DebugInfoOffset<R::Offset> {
267         self.offset
268     }
269 
270     /// Get the length of the debugging info for this compilation unit, not
271     /// including the byte length of the encoded length itself.
unit_length(&self) -> R::Offset272     pub fn unit_length(&self) -> R::Offset {
273         self.header.unit_length
274     }
275 
276     /// Get the length of the debugging info for this compilation unit,
277     /// including the byte length of the encoded length itself.
length_including_self(&self) -> R::Offset278     pub fn length_including_self(&self) -> R::Offset {
279         self.header.length_including_self()
280     }
281 
282     /// Return the encoding parameters for this unit.
encoding(&self) -> Encoding283     pub fn encoding(&self) -> Encoding {
284         self.header.encoding
285     }
286 
287     /// Get the DWARF version of the debugging info for this compilation unit.
version(&self) -> u16288     pub fn version(&self) -> u16 {
289         self.header.version()
290     }
291 
292     /// The offset into the `.debug_abbrev` section for this compilation unit's
293     /// debugging information entries' abbreviations.
debug_abbrev_offset(&self) -> DebugAbbrevOffset<R::Offset>294     pub fn debug_abbrev_offset(&self) -> DebugAbbrevOffset<R::Offset> {
295         self.header.debug_abbrev_offset
296     }
297 
298     /// The size of addresses (in bytes) in this type-unit.
address_size(&self) -> u8299     pub fn address_size(&self) -> u8 {
300         self.header.address_size()
301     }
302 
303     /// Whether this type unit is encoded in 64- or 32-bit DWARF.
format(&self) -> Format304     pub fn format(&self) -> Format {
305         self.header.format()
306     }
307 
308     /// The serialized size of the header for this compilation unit.
header_size(&self) -> R::Offset309     pub fn header_size(&self) -> R::Offset {
310         self.header.header_size()
311     }
312 
313     /// Read the `DebuggingInformationEntry` at the given offset.
entry<'me, 'abbrev>( &'me self, abbreviations: &'abbrev Abbreviations, offset: UnitOffset<R::Offset>, ) -> Result<DebuggingInformationEntry<'abbrev, 'me, R>>314     pub fn entry<'me, 'abbrev>(
315         &'me self,
316         abbreviations: &'abbrev Abbreviations,
317         offset: UnitOffset<R::Offset>,
318     ) -> Result<DebuggingInformationEntry<'abbrev, 'me, R>> {
319         self.header.entry(abbreviations, offset)
320     }
321 
322     /// Navigate this compilation unit's `DebuggingInformationEntry`s.
entries<'me, 'abbrev>( &'me self, abbreviations: &'abbrev Abbreviations, ) -> EntriesCursor<'abbrev, 'me, R>323     pub fn entries<'me, 'abbrev>(
324         &'me self,
325         abbreviations: &'abbrev Abbreviations,
326     ) -> EntriesCursor<'abbrev, 'me, R> {
327         self.header.entries(abbreviations)
328     }
329 
330     /// Navigate this compilation unit's `DebuggingInformationEntry`s
331     /// starting at the given offset.
entries_at_offset<'me, 'abbrev>( &'me self, abbreviations: &'abbrev Abbreviations, offset: UnitOffset<R::Offset>, ) -> Result<EntriesCursor<'abbrev, 'me, R>>332     pub fn entries_at_offset<'me, 'abbrev>(
333         &'me self,
334         abbreviations: &'abbrev Abbreviations,
335         offset: UnitOffset<R::Offset>,
336     ) -> Result<EntriesCursor<'abbrev, 'me, R>> {
337         self.header.entries_at_offset(abbreviations, offset)
338     }
339 
340     /// Navigate this compilation unit's `DebuggingInformationEntry`s as a tree
341     /// starting at the given offset.
entries_tree<'me, 'abbrev>( &'me self, abbreviations: &'abbrev Abbreviations, offset: Option<UnitOffset<R::Offset>>, ) -> Result<EntriesTree<'abbrev, 'me, R>>342     pub fn entries_tree<'me, 'abbrev>(
343         &'me self,
344         abbreviations: &'abbrev Abbreviations,
345         offset: Option<UnitOffset<R::Offset>>,
346     ) -> Result<EntriesTree<'abbrev, 'me, R>> {
347         self.header.entries_tree(abbreviations, offset)
348     }
349 
350     /// Read the raw data that defines the Debugging Information Entries.
entries_raw<'me, 'abbrev>( &'me self, abbreviations: &'abbrev Abbreviations, offset: Option<UnitOffset<R::Offset>>, ) -> Result<EntriesRaw<'abbrev, 'me, R>>351     pub fn entries_raw<'me, 'abbrev>(
352         &'me self,
353         abbreviations: &'abbrev Abbreviations,
354         offset: Option<UnitOffset<R::Offset>>,
355     ) -> Result<EntriesRaw<'abbrev, 'me, R>> {
356         self.header.entries_raw(abbreviations, offset)
357     }
358 
359     /// Parse this compilation unit's abbreviations.
360     ///
361     /// ```
362     /// use gimli::DebugAbbrev;
363     /// # use gimli::{DebugInfo, LittleEndian};
364     /// # let info_buf = [
365     /// #     // Comilation unit header
366     /// #
367     /// #     // 32-bit unit length = 25
368     /// #     0x19, 0x00, 0x00, 0x00,
369     /// #     // Version 4
370     /// #     0x04, 0x00,
371     /// #     // debug_abbrev_offset
372     /// #     0x00, 0x00, 0x00, 0x00,
373     /// #     // Address size
374     /// #     0x04,
375     /// #
376     /// #     // DIEs
377     /// #
378     /// #     // Abbreviation code
379     /// #     0x01,
380     /// #     // Attribute of form DW_FORM_string = "foo\0"
381     /// #     0x66, 0x6f, 0x6f, 0x00,
382     /// #
383     /// #       // Children
384     /// #
385     /// #       // Abbreviation code
386     /// #       0x01,
387     /// #       // Attribute of form DW_FORM_string = "foo\0"
388     /// #       0x66, 0x6f, 0x6f, 0x00,
389     /// #
390     /// #         // Children
391     /// #
392     /// #         // Abbreviation code
393     /// #         0x01,
394     /// #         // Attribute of form DW_FORM_string = "foo\0"
395     /// #         0x66, 0x6f, 0x6f, 0x00,
396     /// #
397     /// #           // Children
398     /// #
399     /// #           // End of children
400     /// #           0x00,
401     /// #
402     /// #         // End of children
403     /// #         0x00,
404     /// #
405     /// #       // End of children
406     /// #       0x00,
407     /// # ];
408     /// # let debug_info = DebugInfo::new(&info_buf, LittleEndian);
409     /// #
410     /// # let abbrev_buf = [
411     /// #     // Code
412     /// #     0x01,
413     /// #     // DW_TAG_subprogram
414     /// #     0x2e,
415     /// #     // DW_CHILDREN_yes
416     /// #     0x01,
417     /// #     // Begin attributes
418     /// #       // Attribute name = DW_AT_name
419     /// #       0x03,
420     /// #       // Attribute form = DW_FORM_string
421     /// #       0x08,
422     /// #     // End attributes
423     /// #     0x00,
424     /// #     0x00,
425     /// #     // Null terminator
426     /// #     0x00
427     /// # ];
428     /// #
429     /// # let get_some_unit = || debug_info.units().next().unwrap().unwrap();
430     ///
431     /// let unit = get_some_unit();
432     ///
433     /// # let read_debug_abbrev_section_somehow = || &abbrev_buf;
434     /// let debug_abbrev = DebugAbbrev::new(read_debug_abbrev_section_somehow(), LittleEndian);
435     /// let abbrevs_for_unit = unit.abbreviations(&debug_abbrev).unwrap();
436     /// ```
abbreviations(&self, debug_abbrev: &DebugAbbrev<R>) -> Result<Abbreviations>437     pub fn abbreviations(&self, debug_abbrev: &DebugAbbrev<R>) -> Result<Abbreviations> {
438         self.header.abbreviations(debug_abbrev)
439     }
440 
441     /// Parse a compilation unit header.
parse( input: &mut R, offset: DebugInfoOffset<R::Offset>, ) -> Result<CompilationUnitHeader<R>>442     fn parse(
443         input: &mut R,
444         offset: DebugInfoOffset<R::Offset>,
445     ) -> Result<CompilationUnitHeader<R>> {
446         let header = parse_unit_header(input)?;
447         Ok(CompilationUnitHeader { header, offset })
448     }
449 }
450 
451 /// Parse the unit type from the compilation unit header.
parse_compilation_unit_type<R: Reader>(input: &mut R) -> Result<constants::DwUt>452 fn parse_compilation_unit_type<R: Reader>(input: &mut R) -> Result<constants::DwUt> {
453     let val = input.read_u8()?;
454     Ok(constants::DwUt(val))
455 }
456 
457 /// Parse the `debug_abbrev_offset` in the compilation unit header.
parse_debug_abbrev_offset<R: Reader>( input: &mut R, format: Format, ) -> Result<DebugAbbrevOffset<R::Offset>>458 fn parse_debug_abbrev_offset<R: Reader>(
459     input: &mut R,
460     format: Format,
461 ) -> Result<DebugAbbrevOffset<R::Offset>> {
462     input.read_offset(format).map(DebugAbbrevOffset)
463 }
464 
465 /// Parse the `debug_info_offset` in the arange header.
parse_debug_info_offset<R: Reader>( input: &mut R, format: Format, ) -> Result<DebugInfoOffset<R::Offset>>466 pub(crate) fn parse_debug_info_offset<R: Reader>(
467     input: &mut R,
468     format: Format,
469 ) -> Result<DebugInfoOffset<R::Offset>> {
470     input.read_offset(format).map(DebugInfoOffset)
471 }
472 
473 /// The common fields for the headers of compilation units and
474 /// type units.
475 #[derive(Debug, Clone, Copy, PartialEq, Eq)]
476 pub struct UnitHeader<R, Offset = <R as Reader>::Offset>
477 where
478     R: Reader<Offset = Offset>,
479     Offset: ReaderOffset,
480 {
481     encoding: Encoding,
482     unit_length: Offset,
483     debug_abbrev_offset: DebugAbbrevOffset<Offset>,
484     entries_buf: R,
485 }
486 
487 /// Static methods.
488 impl<R, Offset> UnitHeader<R, Offset>
489 where
490     R: Reader<Offset = Offset>,
491     Offset: ReaderOffset,
492 {
493     /// Construct a new `UnitHeader`.
new( encoding: Encoding, unit_length: R::Offset, debug_abbrev_offset: DebugAbbrevOffset<R::Offset>, entries_buf: R, ) -> Self494     pub fn new(
495         encoding: Encoding,
496         unit_length: R::Offset,
497         debug_abbrev_offset: DebugAbbrevOffset<R::Offset>,
498         entries_buf: R,
499     ) -> Self {
500         UnitHeader {
501             encoding,
502             unit_length,
503             debug_abbrev_offset,
504             entries_buf,
505         }
506     }
507 
508     /// Return the serialized size of the common unit header for the given
509     /// DWARF format.
size_of_header(encoding: Encoding) -> usize510     pub fn size_of_header(encoding: Encoding) -> usize {
511         let unit_length_size = encoding.format.initial_length_size() as usize;
512         let version_size = 2;
513         let debug_abbrev_offset_size = encoding.format.word_size() as usize;
514         let address_size_size = 1;
515         let unit_type_size = if encoding.version == 5 { 1 } else { 0 };
516 
517         unit_length_size
518             + version_size
519             + debug_abbrev_offset_size
520             + address_size_size
521             + unit_type_size
522     }
523 }
524 
525 /// Instance methods.
526 impl<R, Offset> UnitHeader<R, Offset>
527 where
528     R: Reader<Offset = Offset>,
529     Offset: ReaderOffset,
530 {
531     /// Get the length of the debugging info for this compilation unit, not
532     /// including the byte length of the encoded length itself.
unit_length(&self) -> R::Offset533     pub fn unit_length(&self) -> R::Offset {
534         self.unit_length
535     }
536 
537     /// Get the length of the debugging info for this compilation unit,
538     /// including the byte length of the encoded length itself.
length_including_self(&self) -> R::Offset539     pub fn length_including_self(&self) -> R::Offset {
540         R::Offset::from_u8(self.format().initial_length_size()) + self.unit_length
541     }
542 
543     /// Return the encoding parameters for this unit.
encoding(&self) -> Encoding544     pub fn encoding(&self) -> Encoding {
545         self.encoding
546     }
547 
548     /// Get the DWARF version of the debugging info for this compilation unit.
version(&self) -> u16549     pub fn version(&self) -> u16 {
550         self.encoding.version
551     }
552 
553     /// The offset into the `.debug_abbrev` section for this compilation unit's
554     /// debugging information entries' abbreviations.
debug_abbrev_offset(&self) -> DebugAbbrevOffset<R::Offset>555     pub fn debug_abbrev_offset(&self) -> DebugAbbrevOffset<R::Offset> {
556         self.debug_abbrev_offset
557     }
558 
559     /// The size of addresses (in bytes) in this compilation unit.
address_size(&self) -> u8560     pub fn address_size(&self) -> u8 {
561         self.encoding.address_size
562     }
563 
564     /// Whether this compilation unit is encoded in 64- or 32-bit DWARF.
format(&self) -> Format565     pub fn format(&self) -> Format {
566         self.encoding.format
567     }
568 
569     /// The serialized size of the header for this compilation unit.
header_size(&self) -> R::Offset570     pub fn header_size(&self) -> R::Offset {
571         self.length_including_self() - self.entries_buf.len()
572     }
573 
is_valid_offset(&self, offset: UnitOffset<R::Offset>) -> bool574     pub(crate) fn is_valid_offset(&self, offset: UnitOffset<R::Offset>) -> bool {
575         let size_of_header = self.header_size();
576         if offset.0 < size_of_header {
577             return false;
578         }
579 
580         let relative_to_entries_buf = offset.0 - size_of_header;
581         relative_to_entries_buf < self.entries_buf.len()
582     }
583 
584     /// Get the underlying bytes for the supplied range.
range(&self, idx: Range<UnitOffset<R::Offset>>) -> Result<R>585     pub fn range(&self, idx: Range<UnitOffset<R::Offset>>) -> Result<R> {
586         if !self.is_valid_offset(idx.start) {
587             return Err(Error::OffsetOutOfBounds);
588         }
589         if !self.is_valid_offset(idx.end) {
590             return Err(Error::OffsetOutOfBounds);
591         }
592         assert!(idx.start <= idx.end);
593         let size_of_header = self.header_size();
594         let start = idx.start.0 - size_of_header;
595         let end = idx.end.0 - size_of_header;
596         let mut input = self.entries_buf.clone();
597         input.skip(start)?;
598         input.truncate(end - start)?;
599         Ok(input)
600     }
601 
602     /// Get the underlying bytes for the supplied range.
range_from(&self, idx: RangeFrom<UnitOffset<R::Offset>>) -> Result<R>603     pub fn range_from(&self, idx: RangeFrom<UnitOffset<R::Offset>>) -> Result<R> {
604         if !self.is_valid_offset(idx.start) {
605             return Err(Error::OffsetOutOfBounds);
606         }
607         let start = idx.start.0 - self.header_size();
608         let mut input = self.entries_buf.clone();
609         input.skip(start)?;
610         Ok(input)
611     }
612 
613     /// Get the underlying bytes for the supplied range.
range_to(&self, idx: RangeTo<UnitOffset<R::Offset>>) -> Result<R>614     pub fn range_to(&self, idx: RangeTo<UnitOffset<R::Offset>>) -> Result<R> {
615         if !self.is_valid_offset(idx.end) {
616             return Err(Error::OffsetOutOfBounds);
617         }
618         let end = idx.end.0 - self.header_size();
619         let mut input = self.entries_buf.clone();
620         input.truncate(end)?;
621         Ok(input)
622     }
623 
624     /// Read the `DebuggingInformationEntry` at the given offset.
entry<'me, 'abbrev>( &'me self, abbreviations: &'abbrev Abbreviations, offset: UnitOffset<R::Offset>, ) -> Result<DebuggingInformationEntry<'abbrev, 'me, R>>625     pub fn entry<'me, 'abbrev>(
626         &'me self,
627         abbreviations: &'abbrev Abbreviations,
628         offset: UnitOffset<R::Offset>,
629     ) -> Result<DebuggingInformationEntry<'abbrev, 'me, R>> {
630         let mut input = self.range_from(offset..)?;
631         let entry = DebuggingInformationEntry::parse(&mut input, self, abbreviations)?;
632         entry.ok_or(Error::NoEntryAtGivenOffset)
633     }
634 
635     /// Navigate this unit's `DebuggingInformationEntry`s.
entries<'me, 'abbrev>( &'me self, abbreviations: &'abbrev Abbreviations, ) -> EntriesCursor<'abbrev, 'me, R>636     pub fn entries<'me, 'abbrev>(
637         &'me self,
638         abbreviations: &'abbrev Abbreviations,
639     ) -> EntriesCursor<'abbrev, 'me, R> {
640         EntriesCursor {
641             unit: self,
642             input: self.entries_buf.clone(),
643             abbreviations,
644             cached_current: None,
645             delta_depth: 0,
646         }
647     }
648 
649     /// Navigate this compilation unit's `DebuggingInformationEntry`s
650     /// starting at the given offset.
entries_at_offset<'me, 'abbrev>( &'me self, abbreviations: &'abbrev Abbreviations, offset: UnitOffset<R::Offset>, ) -> Result<EntriesCursor<'abbrev, 'me, R>>651     pub fn entries_at_offset<'me, 'abbrev>(
652         &'me self,
653         abbreviations: &'abbrev Abbreviations,
654         offset: UnitOffset<R::Offset>,
655     ) -> Result<EntriesCursor<'abbrev, 'me, R>> {
656         let input = self.range_from(offset..)?;
657         Ok(EntriesCursor {
658             unit: self,
659             input,
660             abbreviations,
661             cached_current: None,
662             delta_depth: 0,
663         })
664     }
665 
666     /// Navigate this unit's `DebuggingInformationEntry`s as a tree
667     /// starting at the given offset.
entries_tree<'me, 'abbrev>( &'me self, abbreviations: &'abbrev Abbreviations, offset: Option<UnitOffset<R::Offset>>, ) -> Result<EntriesTree<'abbrev, 'me, R>>668     pub fn entries_tree<'me, 'abbrev>(
669         &'me self,
670         abbreviations: &'abbrev Abbreviations,
671         offset: Option<UnitOffset<R::Offset>>,
672     ) -> Result<EntriesTree<'abbrev, 'me, R>> {
673         let input = match offset {
674             Some(offset) => self.range_from(offset..)?,
675             None => self.entries_buf.clone(),
676         };
677         Ok(EntriesTree::new(input, self, abbreviations))
678     }
679 
680     /// Read the raw data that defines the Debugging Information Entries.
entries_raw<'me, 'abbrev>( &'me self, abbreviations: &'abbrev Abbreviations, offset: Option<UnitOffset<R::Offset>>, ) -> Result<EntriesRaw<'abbrev, 'me, R>>681     pub fn entries_raw<'me, 'abbrev>(
682         &'me self,
683         abbreviations: &'abbrev Abbreviations,
684         offset: Option<UnitOffset<R::Offset>>,
685     ) -> Result<EntriesRaw<'abbrev, 'me, R>> {
686         let input = match offset {
687             Some(offset) => self.range_from(offset..)?,
688             None => self.entries_buf.clone(),
689         };
690         Ok(EntriesRaw {
691             input,
692             unit: self,
693             abbreviations,
694             depth: 0,
695         })
696     }
697 
698     /// Parse this unit's abbreviations.
abbreviations(&self, debug_abbrev: &DebugAbbrev<R>) -> Result<Abbreviations>699     pub fn abbreviations(&self, debug_abbrev: &DebugAbbrev<R>) -> Result<Abbreviations> {
700         debug_abbrev.abbreviations(self.debug_abbrev_offset())
701     }
702 }
703 
704 /// Parse a compilation unit header.
parse_unit_header<R: Reader>(input: &mut R) -> Result<UnitHeader<R>>705 fn parse_unit_header<R: Reader>(input: &mut R) -> Result<UnitHeader<R>> {
706     let (unit_length, format) = input.read_initial_length()?;
707     let mut rest = input.split(unit_length)?;
708 
709     let version = rest.read_u16()?;
710     let offset;
711     let address_size;
712     // DWARF 1 was very different, and is obsolete, so isn't supported by this
713     // reader.
714     if 2 <= version && version <= 4 {
715         offset = parse_debug_abbrev_offset(&mut rest, format)?;
716         address_size = rest.read_u8()?;
717     } else if version == 5 {
718         let unit_type = parse_compilation_unit_type(&mut rest)?;
719         if unit_type != constants::DW_UT_compile {
720             return Err(Error::UnsupportedUnitType);
721         }
722         address_size = rest.read_u8()?;
723         offset = parse_debug_abbrev_offset(&mut rest, format)?;
724     } else {
725         return Err(Error::UnknownVersion(u64::from(version)));
726     }
727     let encoding = Encoding {
728         format,
729         version,
730         address_size,
731     };
732 
733     Ok(UnitHeader::new(encoding, unit_length, offset, rest))
734 }
735 
736 /// A Debugging Information Entry (DIE).
737 ///
738 /// DIEs have a set of attributes and optionally have children DIEs as well.
739 #[derive(Clone, Debug)]
740 pub struct DebuggingInformationEntry<'abbrev, 'unit, R, Offset = <R as Reader>::Offset>
741 where
742     R: Reader<Offset = Offset>,
743     Offset: ReaderOffset,
744 {
745     offset: UnitOffset<Offset>,
746     attrs_slice: R,
747     attrs_len: Cell<Option<Offset>>,
748     abbrev: &'abbrev Abbreviation,
749     unit: &'unit UnitHeader<R, Offset>,
750 }
751 
752 impl<'abbrev, 'unit, R, Offset> DebuggingInformationEntry<'abbrev, 'unit, R, Offset>
753 where
754     R: Reader<Offset = Offset>,
755     Offset: ReaderOffset,
756 {
757     /// Construct a new `DebuggingInformationEntry`.
new( offset: UnitOffset<Offset>, attrs_slice: R, abbrev: &'abbrev Abbreviation, unit: &'unit UnitHeader<R, Offset>, ) -> Self758     pub fn new(
759         offset: UnitOffset<Offset>,
760         attrs_slice: R,
761         abbrev: &'abbrev Abbreviation,
762         unit: &'unit UnitHeader<R, Offset>,
763     ) -> Self {
764         DebuggingInformationEntry {
765             offset,
766             attrs_slice,
767             attrs_len: Cell::new(None),
768             abbrev,
769             unit,
770         }
771     }
772 
773     /// Get this entry's code.
code(&self) -> u64774     pub fn code(&self) -> u64 {
775         self.abbrev.code()
776     }
777 
778     /// Get this entry's offset.
offset(&self) -> UnitOffset<R::Offset>779     pub fn offset(&self) -> UnitOffset<R::Offset> {
780         self.offset
781     }
782 
783     /// Get this entry's `DW_TAG_whatever` tag.
784     ///
785     /// ```
786     /// # use gimli::{DebugAbbrev, DebugInfo, LittleEndian};
787     /// # let info_buf = [
788     /// #     // Comilation unit header
789     /// #
790     /// #     // 32-bit unit length = 12
791     /// #     0x0c, 0x00, 0x00, 0x00,
792     /// #     // Version 4
793     /// #     0x04, 0x00,
794     /// #     // debug_abbrev_offset
795     /// #     0x00, 0x00, 0x00, 0x00,
796     /// #     // Address size
797     /// #     0x04,
798     /// #
799     /// #     // DIEs
800     /// #
801     /// #     // Abbreviation code
802     /// #     0x01,
803     /// #     // Attribute of form DW_FORM_string = "foo\0"
804     /// #     0x66, 0x6f, 0x6f, 0x00,
805     /// # ];
806     /// # let debug_info = DebugInfo::new(&info_buf, LittleEndian);
807     /// # let abbrev_buf = [
808     /// #     // Code
809     /// #     0x01,
810     /// #     // DW_TAG_subprogram
811     /// #     0x2e,
812     /// #     // DW_CHILDREN_no
813     /// #     0x00,
814     /// #     // Begin attributes
815     /// #       // Attribute name = DW_AT_name
816     /// #       0x03,
817     /// #       // Attribute form = DW_FORM_string
818     /// #       0x08,
819     /// #     // End attributes
820     /// #     0x00,
821     /// #     0x00,
822     /// #     // Null terminator
823     /// #     0x00
824     /// # ];
825     /// # let debug_abbrev = DebugAbbrev::new(&abbrev_buf, LittleEndian);
826     /// # let unit = debug_info.units().next().unwrap().unwrap();
827     /// # let abbrevs = unit.abbreviations(&debug_abbrev).unwrap();
828     /// # let mut cursor = unit.entries(&abbrevs);
829     /// # let (_, entry) = cursor.next_dfs().unwrap().unwrap();
830     /// # let mut get_some_entry = || entry;
831     /// let entry = get_some_entry();
832     ///
833     /// match entry.tag() {
834     ///     gimli::DW_TAG_subprogram =>
835     ///         println!("this entry contains debug info about a function"),
836     ///     gimli::DW_TAG_inlined_subroutine =>
837     ///         println!("this entry contains debug info about a particular instance of inlining"),
838     ///     gimli::DW_TAG_variable =>
839     ///         println!("this entry contains debug info about a local variable"),
840     ///     gimli::DW_TAG_formal_parameter =>
841     ///         println!("this entry contains debug info about a function parameter"),
842     ///     otherwise =>
843     ///         println!("this entry is some other kind of data: {:?}", otherwise),
844     /// };
845     /// ```
tag(&self) -> constants::DwTag846     pub fn tag(&self) -> constants::DwTag {
847         self.abbrev.tag()
848     }
849 
850     /// Return true if this entry's type can have children, false otherwise.
has_children(&self) -> bool851     pub fn has_children(&self) -> bool {
852         self.abbrev.has_children()
853     }
854 
855     /// Iterate over this entry's set of attributes.
856     ///
857     /// ```
858     /// use gimli::{DebugAbbrev, DebugInfo, LittleEndian};
859     ///
860     /// // Read the `.debug_info` section.
861     ///
862     /// # let info_buf = [
863     /// #     // Comilation unit header
864     /// #
865     /// #     // 32-bit unit length = 12
866     /// #     0x0c, 0x00, 0x00, 0x00,
867     /// #     // Version 4
868     /// #     0x04, 0x00,
869     /// #     // debug_abbrev_offset
870     /// #     0x00, 0x00, 0x00, 0x00,
871     /// #     // Address size
872     /// #     0x04,
873     /// #
874     /// #     // DIEs
875     /// #
876     /// #     // Abbreviation code
877     /// #     0x01,
878     /// #     // Attribute of form DW_FORM_string = "foo\0"
879     /// #     0x66, 0x6f, 0x6f, 0x00,
880     /// # ];
881     /// # let read_debug_info_section_somehow = || &info_buf;
882     /// let debug_info = DebugInfo::new(read_debug_info_section_somehow(), LittleEndian);
883     ///
884     /// // Get the data about the first compilation unit out of the `.debug_info`.
885     ///
886     /// let unit = debug_info.units().next()
887     ///     .expect("Should have at least one compilation unit")
888     ///     .expect("and it should parse ok");
889     ///
890     /// // Read the `.debug_abbrev` section and parse the
891     /// // abbreviations for our compilation unit.
892     ///
893     /// # let abbrev_buf = [
894     /// #     // Code
895     /// #     0x01,
896     /// #     // DW_TAG_subprogram
897     /// #     0x2e,
898     /// #     // DW_CHILDREN_no
899     /// #     0x00,
900     /// #     // Begin attributes
901     /// #       // Attribute name = DW_AT_name
902     /// #       0x03,
903     /// #       // Attribute form = DW_FORM_string
904     /// #       0x08,
905     /// #     // End attributes
906     /// #     0x00,
907     /// #     0x00,
908     /// #     // Null terminator
909     /// #     0x00
910     /// # ];
911     /// # let read_debug_abbrev_section_somehow = || &abbrev_buf;
912     /// let debug_abbrev = DebugAbbrev::new(read_debug_abbrev_section_somehow(), LittleEndian);
913     /// let abbrevs = unit.abbreviations(&debug_abbrev).unwrap();
914     ///
915     /// // Get the first entry from that compilation unit.
916     ///
917     /// let mut cursor = unit.entries(&abbrevs);
918     /// let (_, entry) = cursor.next_dfs()
919     ///     .expect("Should parse next entry")
920     ///     .expect("Should have at least one entry");
921     ///
922     /// // Finally, print the first entry's attributes.
923     ///
924     /// let mut attrs = entry.attrs();
925     /// while let Some(attr) = attrs.next().unwrap() {
926     ///     println!("Attribute name = {:?}", attr.name());
927     ///     println!("Attribute value = {:?}", attr.value());
928     /// }
929     /// ```
930     ///
931     /// Can be [used with
932     /// `FallibleIterator`](./index.html#using-with-fallibleiterator).
attrs<'me>(&'me self) -> AttrsIter<'abbrev, 'me, 'unit, R>933     pub fn attrs<'me>(&'me self) -> AttrsIter<'abbrev, 'me, 'unit, R> {
934         AttrsIter {
935             input: self.attrs_slice.clone(),
936             attributes: self.abbrev.attributes(),
937             entry: self,
938         }
939     }
940 
941     /// Find the first attribute in this entry which has the given name,
942     /// and return it. Returns `Ok(None)` if no attribute is found.
attr(&self, name: constants::DwAt) -> Result<Option<Attribute<R>>>943     pub fn attr(&self, name: constants::DwAt) -> Result<Option<Attribute<R>>> {
944         let mut attrs = self.attrs();
945         while let Some(attr) = attrs.next()? {
946             if attr.name() == name {
947                 return Ok(Some(attr));
948             }
949         }
950         Ok(None)
951     }
952 
953     /// Find the first attribute in this entry which has the given name,
954     /// and return its raw value. Returns `Ok(None)` if no attribute is found.
attr_value_raw(&self, name: constants::DwAt) -> Result<Option<AttributeValue<R>>>955     pub fn attr_value_raw(&self, name: constants::DwAt) -> Result<Option<AttributeValue<R>>> {
956         self.attr(name)
957             .map(|attr| attr.map(|attr| attr.raw_value()))
958     }
959 
960     /// Find the first attribute in this entry which has the given name,
961     /// and return its normalized value.  Returns `Ok(None)` if no
962     /// attribute is found.
attr_value(&self, name: constants::DwAt) -> Result<Option<AttributeValue<R>>>963     pub fn attr_value(&self, name: constants::DwAt) -> Result<Option<AttributeValue<R>>> {
964         self.attr(name).map(|attr| attr.map(|attr| attr.value()))
965     }
966 
967     /// Return the input buffer after the last attribute.
968     #[allow(clippy::inline_always)]
969     #[inline(always)]
after_attrs(&self) -> Result<R>970     fn after_attrs(&self) -> Result<R> {
971         if let Some(attrs_len) = self.attrs_len.get() {
972             let mut input = self.attrs_slice.clone();
973             input.skip(attrs_len)?;
974             Ok(input)
975         } else {
976             let mut attrs = self.attrs();
977             while let Some(_) = attrs.next()? {}
978             Ok(attrs.input)
979         }
980     }
981 
982     /// Use the `DW_AT_sibling` attribute to find the input buffer for the
983     /// next sibling. Returns `None` if the attribute is missing or invalid.
sibling(&self) -> Option<R>984     fn sibling(&self) -> Option<R> {
985         let attr = self.attr_value(constants::DW_AT_sibling);
986         if let Ok(Some(AttributeValue::UnitRef(offset))) = attr {
987             if offset.0 > self.offset.0 {
988                 if let Ok(input) = self.unit.range_from(offset..) {
989                     return Some(input);
990                 }
991             }
992         }
993         None
994     }
995 
996     /// Parse an entry. Returns `Ok(None)` for null entries.
997     #[allow(clippy::inline_always)]
998     #[inline(always)]
parse( input: &mut R, unit: &'unit UnitHeader<R>, abbreviations: &'abbrev Abbreviations, ) -> Result<Option<Self>>999     fn parse(
1000         input: &mut R,
1001         unit: &'unit UnitHeader<R>,
1002         abbreviations: &'abbrev Abbreviations,
1003     ) -> Result<Option<Self>> {
1004         let offset = unit.header_size() + input.offset_from(&unit.entries_buf);
1005         let code = input.read_uleb128()?;
1006         if code == 0 {
1007             return Ok(None);
1008         };
1009         let abbrev = abbreviations.get(code).ok_or(Error::UnknownAbbreviation)?;
1010         Ok(Some(DebuggingInformationEntry {
1011             offset: UnitOffset(offset),
1012             attrs_slice: input.clone(),
1013             attrs_len: Cell::new(None),
1014             abbrev,
1015             unit,
1016         }))
1017     }
1018 }
1019 
1020 /// The value of an attribute in a `DebuggingInformationEntry`.
1021 //
1022 // Set the discriminant size so that all variants use the same alignment
1023 // for their data.  This gives better code generation in `parse_attribute`.
1024 #[repr(u64)]
1025 #[derive(Clone, Copy, Debug, Eq, PartialEq)]
1026 pub enum AttributeValue<R, Offset = <R as Reader>::Offset>
1027 where
1028     R: Reader<Offset = Offset>,
1029     Offset: ReaderOffset,
1030 {
1031     /// "Refers to some location in the address space of the described program."
1032     Addr(u64),
1033 
1034     /// A slice of an arbitrary number of bytes.
1035     Block(R),
1036 
1037     /// A one byte constant data value. How to interpret the byte depends on context.
1038     ///
1039     /// From section 7 of the standard: "Depending on context, it may be a
1040     /// signed integer, an unsigned integer, a floating-point constant, or
1041     /// anything else."
1042     Data1(u8),
1043 
1044     /// A two byte constant data value. How to interpret the bytes depends on context.
1045     ///
1046     /// These bytes have been converted from `R::Endian`. This may need to be reversed
1047     /// if this was not required.
1048     ///
1049     /// From section 7 of the standard: "Depending on context, it may be a
1050     /// signed integer, an unsigned integer, a floating-point constant, or
1051     /// anything else."
1052     Data2(u16),
1053 
1054     /// A four byte constant data value. How to interpret the bytes depends on context.
1055     ///
1056     /// These bytes have been converted from `R::Endian`. This may need to be reversed
1057     /// if this was not required.
1058     ///
1059     /// From section 7 of the standard: "Depending on context, it may be a
1060     /// signed integer, an unsigned integer, a floating-point constant, or
1061     /// anything else."
1062     Data4(u32),
1063 
1064     /// An eight byte constant data value. How to interpret the bytes depends on context.
1065     ///
1066     /// These bytes have been converted from `R::Endian`. This may need to be reversed
1067     /// if this was not required.
1068     ///
1069     /// From section 7 of the standard: "Depending on context, it may be a
1070     /// signed integer, an unsigned integer, a floating-point constant, or
1071     /// anything else."
1072     Data8(u64),
1073 
1074     /// A signed integer constant.
1075     Sdata(i64),
1076 
1077     /// An unsigned integer constant.
1078     Udata(u64),
1079 
1080     /// "The information bytes contain a DWARF expression (see Section 2.5) or
1081     /// location description (see Section 2.6)."
1082     Exprloc(Expression<R>),
1083 
1084     /// A boolean that indicates presence or absence of the attribute.
1085     Flag(bool),
1086 
1087     /// An offset into another section. Which section this is an offset into
1088     /// depends on context.
1089     SecOffset(Offset),
1090 
1091     /// An offset to a set of addresses in the `.debug_addr` section.
1092     DebugAddrBase(DebugAddrBase<Offset>),
1093 
1094     /// An index into a set of addresses in the `.debug_addr` section.
1095     DebugAddrIndex(DebugAddrIndex<Offset>),
1096 
1097     /// An offset into the current compilation unit.
1098     UnitRef(UnitOffset<Offset>),
1099 
1100     /// An offset into the current `.debug_info` section, but possibly a
1101     /// different compilation unit from the current one.
1102     DebugInfoRef(DebugInfoOffset<Offset>),
1103 
1104     /// An offset into the `.debug_info` section of the supplementary object file.
1105     DebugInfoRefSup(DebugInfoOffset<Offset>),
1106 
1107     /// An offset into the `.debug_line` section.
1108     DebugLineRef(DebugLineOffset<Offset>),
1109 
1110     /// An offset into either the `.debug_loc` section or the `.debug_loclists` section.
1111     LocationListsRef(LocationListsOffset<Offset>),
1112 
1113     /// An offset to a set of offsets in the `.debug_loclists` section.
1114     DebugLocListsBase(DebugLocListsBase<Offset>),
1115 
1116     /// An index into a set of offsets in the `.debug_loclists` section.
1117     DebugLocListsIndex(DebugLocListsIndex<Offset>),
1118 
1119     /// An offset into the `.debug_macinfo` section.
1120     DebugMacinfoRef(DebugMacinfoOffset<Offset>),
1121 
1122     /// An offset into the `.debug_macro` section.
1123     DebugMacroRef(DebugMacroOffset<Offset>),
1124 
1125     /// An offset into the `.debug_ranges` section.
1126     RangeListsRef(RangeListsOffset<Offset>),
1127 
1128     /// An offset to a set of offsets in the `.debug_rnglists` section.
1129     DebugRngListsBase(DebugRngListsBase<Offset>),
1130 
1131     /// An index into a set of offsets in the `.debug_rnglists` section.
1132     DebugRngListsIndex(DebugRngListsIndex<Offset>),
1133 
1134     /// A type signature.
1135     DebugTypesRef(DebugTypeSignature),
1136 
1137     /// An offset into the `.debug_str` section.
1138     DebugStrRef(DebugStrOffset<Offset>),
1139 
1140     /// An offset into the `.debug_str` section of the supplementary object file.
1141     DebugStrRefSup(DebugStrOffset<Offset>),
1142 
1143     /// An offset to a set of entries in the `.debug_str_offsets` section.
1144     DebugStrOffsetsBase(DebugStrOffsetsBase<Offset>),
1145 
1146     /// An index into a set of entries in the `.debug_str_offsets` section.
1147     DebugStrOffsetsIndex(DebugStrOffsetsIndex<Offset>),
1148 
1149     /// An offset into the `.debug_line_str` section.
1150     DebugLineStrRef(DebugLineStrOffset<Offset>),
1151 
1152     /// A slice of bytes representing a string. Does not include a final null byte.
1153     /// Not guaranteed to be UTF-8 or anything like that.
1154     String(R),
1155 
1156     /// The value of a `DW_AT_encoding` attribute.
1157     Encoding(constants::DwAte),
1158 
1159     /// The value of a `DW_AT_decimal_sign` attribute.
1160     DecimalSign(constants::DwDs),
1161 
1162     /// The value of a `DW_AT_endianity` attribute.
1163     Endianity(constants::DwEnd),
1164 
1165     /// The value of a `DW_AT_accessibility` attribute.
1166     Accessibility(constants::DwAccess),
1167 
1168     /// The value of a `DW_AT_visibility` attribute.
1169     Visibility(constants::DwVis),
1170 
1171     /// The value of a `DW_AT_virtuality` attribute.
1172     Virtuality(constants::DwVirtuality),
1173 
1174     /// The value of a `DW_AT_language` attribute.
1175     Language(constants::DwLang),
1176 
1177     /// The value of a `DW_AT_address_class` attribute.
1178     AddressClass(constants::DwAddr),
1179 
1180     /// The value of a `DW_AT_identifier_case` attribute.
1181     IdentifierCase(constants::DwId),
1182 
1183     /// The value of a `DW_AT_calling_convention` attribute.
1184     CallingConvention(constants::DwCc),
1185 
1186     /// The value of a `DW_AT_inline` attribute.
1187     Inline(constants::DwInl),
1188 
1189     /// The value of a `DW_AT_ordering` attribute.
1190     Ordering(constants::DwOrd),
1191 
1192     /// An index into the filename entries from the line number information
1193     /// table for the compilation unit containing this value.
1194     FileIndex(u64),
1195 }
1196 
1197 /// An attribute in a `DebuggingInformationEntry`, consisting of a name and
1198 /// associated value.
1199 #[derive(Copy, Clone, Debug, Eq, PartialEq)]
1200 pub struct Attribute<R: Reader> {
1201     name: constants::DwAt,
1202     value: AttributeValue<R>,
1203 }
1204 
1205 impl<R: Reader> Attribute<R> {
1206     /// Get this attribute's name.
name(&self) -> constants::DwAt1207     pub fn name(&self) -> constants::DwAt {
1208         self.name
1209     }
1210 
1211     /// Get this attribute's raw value.
raw_value(&self) -> AttributeValue<R>1212     pub fn raw_value(&self) -> AttributeValue<R> {
1213         self.value.clone()
1214     }
1215 
1216     /// Get this attribute's normalized value.
1217     ///
1218     /// Attribute values can potentially be encoded in multiple equivalent forms,
1219     /// and may have special meaning depending on the attribute name.  This method
1220     /// converts the attribute value to a normalized form based on the attribute
1221     /// name.
1222     ///
1223     /// See "Table 7.5: Attribute encodings" and "Table 7.6: Attribute form encodings".
1224     #[allow(clippy::cyclomatic_complexity)]
1225     #[allow(clippy::match_same_arms)]
value(&self) -> AttributeValue<R>1226     pub fn value(&self) -> AttributeValue<R> {
1227         // Table 7.5 shows the possible attribute classes for each name.
1228         // Table 7.6 shows the possible attribute classes for each form.
1229         // For each attribute name, we need to match on the form, and
1230         // convert it to one of the classes that is allowed for both
1231         // the name and the form.
1232         //
1233         // The individual class conversions rarely vary for each name,
1234         // so for each class conversion we define a macro that matches
1235         // on the allowed forms for that class.
1236         //
1237         // For some classes, we don't need to do any conversion, so their
1238         // macro is empty.  In the future we may want to fill them in to
1239         // provide strict checking of the forms for each class.  For now,
1240         // they simply provide a way to document the allowed classes for
1241         // each name.
1242 
1243         // DW_FORM_addr
1244         // DW_FORM_addrx
1245         // DW_FORM_addrx1
1246         // DW_FORM_addrx2
1247         // DW_FORM_addrx3
1248         // DW_FORM_addrx4
1249         macro_rules! address {
1250             () => {};
1251         }
1252         // DW_FORM_sec_offset
1253         macro_rules! addrptr {
1254             () => {
1255                 if let Some(offset) = self.offset_value() {
1256                     return AttributeValue::DebugAddrBase(DebugAddrBase(offset));
1257                 }
1258             };
1259         }
1260         // DW_FORM_block
1261         // DW_FORM_block1
1262         // DW_FORM_block2
1263         // DW_FORM_block4
1264         macro_rules! block {
1265             () => {};
1266         }
1267         // DW_FORM_sdata
1268         // DW_FORM_udata
1269         // DW_FORM_data1
1270         // DW_FORM_data2
1271         // DW_FORM_data4
1272         // DW_FORM_data8
1273         // DW_FORM_data16
1274         // DW_FORM_implicit_const
1275         macro_rules! constant {
1276             ($value:ident, $variant:ident) => {
1277                 if let Some(value) = self.$value() {
1278                     return AttributeValue::$variant(value);
1279                 }
1280             };
1281             ($value:ident, $variant:ident, $constant:ident) => {
1282                 if let Some(value) = self.$value() {
1283                     return AttributeValue::$variant(constants::$constant(value));
1284                 }
1285             };
1286         }
1287         // DW_FORM_exprloc
1288         macro_rules! exprloc {
1289             () => {
1290                 if let Some(value) = self.exprloc_value() {
1291                     return AttributeValue::Exprloc(value);
1292                 }
1293             };
1294         }
1295         // DW_FORM_flag
1296         // DW_FORM_flag_present
1297         macro_rules! flag {
1298             () => {};
1299         }
1300         // DW_FORM_sec_offset
1301         macro_rules! lineptr {
1302             () => {
1303                 if let Some(offset) = self.offset_value() {
1304                     return AttributeValue::DebugLineRef(DebugLineOffset(offset));
1305                 }
1306             };
1307         }
1308         // This also covers `loclist` in DWARF version 5.
1309         // DW_FORM_sec_offset
1310         // DW_FORM_loclistx
1311         macro_rules! loclistptr {
1312             () => {
1313                 // DebugLocListsIndex is also an allowed form in DWARF version 5.
1314                 if let Some(offset) = self.offset_value() {
1315                     return AttributeValue::LocationListsRef(LocationListsOffset(offset));
1316                 }
1317             };
1318         }
1319         // DW_FORM_sec_offset
1320         macro_rules! loclistsptr {
1321             () => {
1322                 if let Some(offset) = self.offset_value() {
1323                     return AttributeValue::DebugLocListsBase(DebugLocListsBase(offset));
1324                 }
1325             };
1326         }
1327         // DWARF version <= 4.
1328         // DW_FORM_sec_offset
1329         macro_rules! macinfoptr {
1330             () => {
1331                 if let Some(offset) = self.offset_value() {
1332                     return AttributeValue::DebugMacinfoRef(DebugMacinfoOffset(offset));
1333                 }
1334             };
1335         }
1336         // DWARF version >= 5.
1337         // DW_FORM_sec_offset
1338         macro_rules! macroptr {
1339             () => {
1340                 if let Some(offset) = self.offset_value() {
1341                     return AttributeValue::DebugMacroRef(DebugMacroOffset(offset));
1342                 }
1343             };
1344         }
1345         // DW_FORM_ref_addr
1346         // DW_FORM_ref1
1347         // DW_FORM_ref2
1348         // DW_FORM_ref4
1349         // DW_FORM_ref8
1350         // DW_FORM_ref_udata
1351         // DW_FORM_ref_sig8
1352         // DW_FORM_ref_sup4
1353         // DW_FORM_ref_sup8
1354         macro_rules! reference {
1355             () => {};
1356         }
1357         // This also covers `rnglist` in DWARF version 5.
1358         // DW_FORM_sec_offset
1359         // DW_FORM_rnglistx
1360         macro_rules! rangelistptr {
1361             () => {
1362                 // DebugRngListsIndex is also an allowed form in DWARF version 5.
1363                 if let Some(offset) = self.offset_value() {
1364                     return AttributeValue::RangeListsRef(RangeListsOffset(offset));
1365                 }
1366             };
1367         }
1368         // DW_FORM_sec_offset
1369         macro_rules! rnglistsptr {
1370             () => {
1371                 if let Some(offset) = self.offset_value() {
1372                     return AttributeValue::DebugRngListsBase(DebugRngListsBase(offset));
1373                 }
1374             };
1375         }
1376         // DW_FORM_string
1377         // DW_FORM_strp
1378         // DW_FORM_strx
1379         // DW_FORM_strx1
1380         // DW_FORM_strx2
1381         // DW_FORM_strx3
1382         // DW_FORM_strx4
1383         // DW_FORM_strp_sup
1384         // DW_FORM_line_strp
1385         macro_rules! string {
1386             () => {};
1387         }
1388         // DW_FORM_sec_offset
1389         macro_rules! stroffsetsptr {
1390             () => {
1391                 if let Some(offset) = self.offset_value() {
1392                     return AttributeValue::DebugStrOffsetsBase(DebugStrOffsetsBase(offset));
1393                 }
1394             };
1395         }
1396 
1397         // Perform the allowed class conversions for each attribute name.
1398         match self.name {
1399             constants::DW_AT_sibling => {
1400                 reference!();
1401             }
1402             constants::DW_AT_location => {
1403                 exprloc!();
1404                 loclistptr!();
1405             }
1406             constants::DW_AT_name => {
1407                 string!();
1408             }
1409             constants::DW_AT_ordering => {
1410                 constant!(u8_value, Ordering, DwOrd);
1411             }
1412             constants::DW_AT_byte_size
1413             | constants::DW_AT_bit_offset
1414             | constants::DW_AT_bit_size => {
1415                 constant!(udata_value, Udata);
1416                 exprloc!();
1417                 reference!();
1418             }
1419             constants::DW_AT_stmt_list => {
1420                 lineptr!();
1421             }
1422             constants::DW_AT_low_pc => {
1423                 address!();
1424             }
1425             constants::DW_AT_high_pc => {
1426                 address!();
1427                 constant!(udata_value, Udata);
1428             }
1429             constants::DW_AT_language => {
1430                 constant!(u16_value, Language, DwLang);
1431             }
1432             constants::DW_AT_discr => {
1433                 reference!();
1434             }
1435             constants::DW_AT_discr_value => {
1436                 // constant: depends on type of DW_TAG_variant_part,
1437                 // so caller must normalize.
1438             }
1439             constants::DW_AT_visibility => {
1440                 constant!(u8_value, Visibility, DwVis);
1441             }
1442             constants::DW_AT_import => {
1443                 reference!();
1444             }
1445             constants::DW_AT_string_length => {
1446                 exprloc!();
1447                 loclistptr!();
1448                 reference!();
1449             }
1450             constants::DW_AT_common_reference => {
1451                 reference!();
1452             }
1453             constants::DW_AT_comp_dir => {
1454                 string!();
1455             }
1456             constants::DW_AT_const_value => {
1457                 // TODO: constant: sign depends on DW_AT_type.
1458                 block!();
1459                 string!();
1460             }
1461             constants::DW_AT_containing_type => {
1462                 reference!();
1463             }
1464             constants::DW_AT_default_value => {
1465                 // TODO: constant: sign depends on DW_AT_type.
1466                 reference!();
1467                 flag!();
1468             }
1469             constants::DW_AT_inline => {
1470                 constant!(u8_value, Inline, DwInl);
1471             }
1472             constants::DW_AT_is_optional => {
1473                 flag!();
1474             }
1475             constants::DW_AT_lower_bound => {
1476                 // TODO: constant: sign depends on DW_AT_type.
1477                 exprloc!();
1478                 reference!();
1479             }
1480             constants::DW_AT_producer => {
1481                 string!();
1482             }
1483             constants::DW_AT_prototyped => {
1484                 flag!();
1485             }
1486             constants::DW_AT_return_addr => {
1487                 exprloc!();
1488                 loclistptr!();
1489             }
1490             constants::DW_AT_start_scope => {
1491                 // TODO: constant
1492                 rangelistptr!();
1493             }
1494             constants::DW_AT_bit_stride => {
1495                 constant!(udata_value, Udata);
1496                 exprloc!();
1497                 reference!();
1498             }
1499             constants::DW_AT_upper_bound => {
1500                 // TODO: constant: sign depends on DW_AT_type.
1501                 exprloc!();
1502                 reference!();
1503             }
1504             constants::DW_AT_abstract_origin => {
1505                 reference!();
1506             }
1507             constants::DW_AT_accessibility => {
1508                 constant!(u8_value, Accessibility, DwAccess);
1509             }
1510             constants::DW_AT_address_class => {
1511                 constant!(udata_value, AddressClass, DwAddr);
1512             }
1513             constants::DW_AT_artificial => {
1514                 flag!();
1515             }
1516             constants::DW_AT_base_types => {
1517                 reference!();
1518             }
1519             constants::DW_AT_calling_convention => {
1520                 constant!(u8_value, CallingConvention, DwCc);
1521             }
1522             constants::DW_AT_count => {
1523                 // TODO: constant
1524                 exprloc!();
1525                 reference!();
1526             }
1527             constants::DW_AT_data_member_location => {
1528                 // Constants must be handled before loclistptr so that DW_FORM_data4/8
1529                 // are correctly interpreted for DWARF version 4+.
1530                 constant!(udata_value, Udata);
1531                 exprloc!();
1532                 loclistptr!();
1533             }
1534             constants::DW_AT_decl_column => {
1535                 constant!(udata_value, Udata);
1536             }
1537             constants::DW_AT_decl_file => {
1538                 constant!(udata_value, FileIndex);
1539             }
1540             constants::DW_AT_decl_line => {
1541                 constant!(udata_value, Udata);
1542             }
1543             constants::DW_AT_declaration => {
1544                 flag!();
1545             }
1546             constants::DW_AT_discr_list => {
1547                 block!();
1548             }
1549             constants::DW_AT_encoding => {
1550                 constant!(u8_value, Encoding, DwAte);
1551             }
1552             constants::DW_AT_external => {
1553                 flag!();
1554             }
1555             constants::DW_AT_frame_base => {
1556                 exprloc!();
1557                 loclistptr!();
1558             }
1559             constants::DW_AT_friend => {
1560                 reference!();
1561             }
1562             constants::DW_AT_identifier_case => {
1563                 constant!(u8_value, IdentifierCase, DwId);
1564             }
1565             constants::DW_AT_macro_info => {
1566                 macinfoptr!();
1567             }
1568             constants::DW_AT_namelist_item => {
1569                 reference!();
1570             }
1571             constants::DW_AT_priority => {
1572                 reference!();
1573             }
1574             constants::DW_AT_segment => {
1575                 exprloc!();
1576                 loclistptr!();
1577             }
1578             constants::DW_AT_specification => {
1579                 reference!();
1580             }
1581             constants::DW_AT_static_link => {
1582                 exprloc!();
1583                 loclistptr!();
1584             }
1585             constants::DW_AT_type => {
1586                 reference!();
1587             }
1588             constants::DW_AT_use_location => {
1589                 exprloc!();
1590                 loclistptr!();
1591             }
1592             constants::DW_AT_variable_parameter => {
1593                 flag!();
1594             }
1595             constants::DW_AT_virtuality => {
1596                 constant!(u8_value, Virtuality, DwVirtuality);
1597             }
1598             constants::DW_AT_vtable_elem_location => {
1599                 exprloc!();
1600                 loclistptr!();
1601             }
1602             constants::DW_AT_allocated => {
1603                 // TODO: constant
1604                 exprloc!();
1605                 reference!();
1606             }
1607             constants::DW_AT_associated => {
1608                 // TODO: constant
1609                 exprloc!();
1610                 reference!();
1611             }
1612             constants::DW_AT_data_location => {
1613                 exprloc!();
1614             }
1615             constants::DW_AT_byte_stride => {
1616                 constant!(udata_value, Udata);
1617                 exprloc!();
1618                 reference!();
1619             }
1620             constants::DW_AT_entry_pc => {
1621                 // TODO: constant
1622                 address!();
1623             }
1624             constants::DW_AT_use_UTF8 => {
1625                 flag!();
1626             }
1627             constants::DW_AT_extension => {
1628                 reference!();
1629             }
1630             constants::DW_AT_ranges => {
1631                 rangelistptr!();
1632             }
1633             constants::DW_AT_trampoline => {
1634                 address!();
1635                 flag!();
1636                 reference!();
1637                 string!();
1638             }
1639             constants::DW_AT_call_column => {
1640                 constant!(udata_value, Udata);
1641             }
1642             constants::DW_AT_call_file => {
1643                 constant!(udata_value, FileIndex);
1644             }
1645             constants::DW_AT_call_line => {
1646                 constant!(udata_value, Udata);
1647             }
1648             constants::DW_AT_description => {
1649                 string!();
1650             }
1651             constants::DW_AT_binary_scale => {
1652                 // TODO: constant
1653             }
1654             constants::DW_AT_decimal_scale => {
1655                 // TODO: constant
1656             }
1657             constants::DW_AT_small => {
1658                 reference!();
1659             }
1660             constants::DW_AT_decimal_sign => {
1661                 constant!(u8_value, DecimalSign, DwDs);
1662             }
1663             constants::DW_AT_digit_count => {
1664                 // TODO: constant
1665             }
1666             constants::DW_AT_picture_string => {
1667                 string!();
1668             }
1669             constants::DW_AT_mutable => {
1670                 flag!();
1671             }
1672             constants::DW_AT_threads_scaled => {
1673                 flag!();
1674             }
1675             constants::DW_AT_explicit => {
1676                 flag!();
1677             }
1678             constants::DW_AT_object_pointer => {
1679                 reference!();
1680             }
1681             constants::DW_AT_endianity => {
1682                 constant!(u8_value, Endianity, DwEnd);
1683             }
1684             constants::DW_AT_elemental => {
1685                 flag!();
1686             }
1687             constants::DW_AT_pure => {
1688                 flag!();
1689             }
1690             constants::DW_AT_recursive => {
1691                 flag!();
1692             }
1693             constants::DW_AT_signature => {
1694                 reference!();
1695             }
1696             constants::DW_AT_main_subprogram => {
1697                 flag!();
1698             }
1699             constants::DW_AT_data_bit_offset => {
1700                 // TODO: constant
1701             }
1702             constants::DW_AT_const_expr => {
1703                 flag!();
1704             }
1705             constants::DW_AT_enum_class => {
1706                 flag!();
1707             }
1708             constants::DW_AT_linkage_name => {
1709                 string!();
1710             }
1711             constants::DW_AT_string_length_bit_size => {
1712                 // TODO: constant
1713             }
1714             constants::DW_AT_string_length_byte_size => {
1715                 // TODO: constant
1716             }
1717             constants::DW_AT_rank => {
1718                 // TODO: constant
1719                 exprloc!();
1720             }
1721             constants::DW_AT_str_offsets_base => {
1722                 stroffsetsptr!();
1723             }
1724             constants::DW_AT_addr_base => {
1725                 addrptr!();
1726             }
1727             constants::DW_AT_rnglists_base => {
1728                 rnglistsptr!();
1729             }
1730             constants::DW_AT_dwo_name => {
1731                 string!();
1732             }
1733             constants::DW_AT_reference => {
1734                 flag!();
1735             }
1736             constants::DW_AT_rvalue_reference => {
1737                 flag!();
1738             }
1739             constants::DW_AT_macros => {
1740                 macroptr!();
1741             }
1742             constants::DW_AT_call_all_calls => {
1743                 flag!();
1744             }
1745             constants::DW_AT_call_all_source_calls => {
1746                 flag!();
1747             }
1748             constants::DW_AT_call_all_tail_calls => {
1749                 flag!();
1750             }
1751             constants::DW_AT_call_return_pc => {
1752                 address!();
1753             }
1754             constants::DW_AT_call_value => {
1755                 exprloc!();
1756             }
1757             constants::DW_AT_call_origin => {
1758                 exprloc!();
1759             }
1760             constants::DW_AT_call_parameter => {
1761                 reference!();
1762             }
1763             constants::DW_AT_call_pc => {
1764                 address!();
1765             }
1766             constants::DW_AT_call_tail_call => {
1767                 flag!();
1768             }
1769             constants::DW_AT_call_target => {
1770                 exprloc!();
1771             }
1772             constants::DW_AT_call_target_clobbered => {
1773                 exprloc!();
1774             }
1775             constants::DW_AT_call_data_location => {
1776                 exprloc!();
1777             }
1778             constants::DW_AT_call_data_value => {
1779                 exprloc!();
1780             }
1781             constants::DW_AT_noreturn => {
1782                 flag!();
1783             }
1784             constants::DW_AT_alignment => {
1785                 // TODO: constant
1786             }
1787             constants::DW_AT_export_symbols => {
1788                 flag!();
1789             }
1790             constants::DW_AT_deleted => {
1791                 flag!();
1792             }
1793             constants::DW_AT_defaulted => {
1794                 // TODO: constant
1795             }
1796             constants::DW_AT_loclists_base => {
1797                 loclistsptr!();
1798             }
1799             _ => {}
1800         }
1801         self.value.clone()
1802     }
1803 
1804     /// Try to convert this attribute's value to a u8.
1805     #[inline]
u8_value(&self) -> Option<u8>1806     pub fn u8_value(&self) -> Option<u8> {
1807         self.value.u8_value()
1808     }
1809 
1810     /// Try to convert this attribute's value to a u16.
1811     #[inline]
u16_value(&self) -> Option<u16>1812     pub fn u16_value(&self) -> Option<u16> {
1813         self.value.u16_value()
1814     }
1815 
1816     /// Try to convert this attribute's value to an unsigned integer.
1817     #[inline]
udata_value(&self) -> Option<u64>1818     pub fn udata_value(&self) -> Option<u64> {
1819         self.value.udata_value()
1820     }
1821 
1822     /// Try to convert this attribute's value to a signed integer.
1823     #[inline]
sdata_value(&self) -> Option<i64>1824     pub fn sdata_value(&self) -> Option<i64> {
1825         self.value.sdata_value()
1826     }
1827 
1828     /// Try to convert this attribute's value to an offset.
1829     #[inline]
offset_value(&self) -> Option<R::Offset>1830     pub fn offset_value(&self) -> Option<R::Offset> {
1831         self.value.offset_value()
1832     }
1833 
1834     /// Try to convert this attribute's value to an expression or location buffer.
1835     ///
1836     /// Expressions and locations may be `DW_FORM_block*` or `DW_FORM_exprloc`.
1837     /// The standard doesn't mention `DW_FORM_block*` as a possible form, but
1838     /// it is encountered in practice.
1839     #[inline]
exprloc_value(&self) -> Option<Expression<R>>1840     pub fn exprloc_value(&self) -> Option<Expression<R>> {
1841         self.value.exprloc_value()
1842     }
1843 
1844     /// Try to return this attribute's value as a string slice.
1845     ///
1846     /// If this attribute's value is either an inline `DW_FORM_string` string,
1847     /// or a `DW_FORM_strp` reference to an offset into the `.debug_str`
1848     /// section, return the attribute's string value as `Some`. Other attribute
1849     /// value forms are returned as `None`.
1850     ///
1851     /// Warning: this function does not handle all possible string forms.
1852     /// Use `Dwarf::attr_string` instead.
1853     #[inline]
string_value(&self, debug_str: &DebugStr<R>) -> Option<R>1854     pub fn string_value(&self, debug_str: &DebugStr<R>) -> Option<R> {
1855         self.value.string_value(debug_str)
1856     }
1857 
1858     /// Try to return this attribute's value as a string slice.
1859     ///
1860     /// If this attribute's value is either an inline `DW_FORM_string` string,
1861     /// or a `DW_FORM_strp` reference to an offset into the `.debug_str`
1862     /// section, or a `DW_FORM_strp_sup` reference to an offset into a supplementary
1863     /// object file, return the attribute's string value as `Some`. Other attribute
1864     /// value forms are returned as `None`.
1865     ///
1866     /// Warning: this function does not handle all possible string forms.
1867     /// Use `Dwarf::attr_string` instead.
1868     #[inline]
string_value_sup( &self, debug_str: &DebugStr<R>, debug_str_sup: Option<&DebugStr<R>>, ) -> Option<R>1869     pub fn string_value_sup(
1870         &self,
1871         debug_str: &DebugStr<R>,
1872         debug_str_sup: Option<&DebugStr<R>>,
1873     ) -> Option<R> {
1874         self.value.string_value_sup(debug_str, debug_str_sup)
1875     }
1876 }
1877 
1878 impl<R, Offset> AttributeValue<R, Offset>
1879 where
1880     R: Reader<Offset = Offset>,
1881     Offset: ReaderOffset,
1882 {
1883     /// Try to convert this attribute's value to a u8.
u8_value(&self) -> Option<u8>1884     pub fn u8_value(&self) -> Option<u8> {
1885         if let Some(value) = self.udata_value() {
1886             if value <= u64::from(u8::MAX) {
1887                 return Some(value as u8);
1888             }
1889         }
1890         None
1891     }
1892 
1893     /// Try to convert this attribute's value to a u16.
u16_value(&self) -> Option<u16>1894     pub fn u16_value(&self) -> Option<u16> {
1895         if let Some(value) = self.udata_value() {
1896             if value <= u64::from(u16::MAX) {
1897                 return Some(value as u16);
1898             }
1899         }
1900         None
1901     }
1902 
1903     /// Try to convert this attribute's value to an unsigned integer.
udata_value(&self) -> Option<u64>1904     pub fn udata_value(&self) -> Option<u64> {
1905         Some(match *self {
1906             AttributeValue::Data1(data) => u64::from(data),
1907             AttributeValue::Data2(data) => u64::from(data),
1908             AttributeValue::Data4(data) => u64::from(data),
1909             AttributeValue::Data8(data) => data,
1910             AttributeValue::Udata(data) => data,
1911             AttributeValue::Sdata(data) => {
1912                 if data < 0 {
1913                     // Maybe we should emit a warning here
1914                     return None;
1915                 }
1916                 data as u64
1917             }
1918             _ => return None,
1919         })
1920     }
1921 
1922     /// Try to convert this attribute's value to a signed integer.
sdata_value(&self) -> Option<i64>1923     pub fn sdata_value(&self) -> Option<i64> {
1924         Some(match *self {
1925             AttributeValue::Data1(data) => i64::from(data as i8),
1926             AttributeValue::Data2(data) => i64::from(data as i16),
1927             AttributeValue::Data4(data) => i64::from(data as i32),
1928             AttributeValue::Data8(data) => data as i64,
1929             AttributeValue::Sdata(data) => data,
1930             AttributeValue::Udata(data) => {
1931                 if data > i64::max_value() as u64 {
1932                     // Maybe we should emit a warning here
1933                     return None;
1934                 }
1935                 data as i64
1936             }
1937             _ => return None,
1938         })
1939     }
1940 
1941     /// Try to convert this attribute's value to an offset.
offset_value(&self) -> Option<R::Offset>1942     pub fn offset_value(&self) -> Option<R::Offset> {
1943         // While offsets will be DW_FORM_data4/8 in DWARF version 2/3,
1944         // these have already been converted to `SecOffset.
1945         if let AttributeValue::SecOffset(offset) = *self {
1946             Some(offset)
1947         } else {
1948             None
1949         }
1950     }
1951 
1952     /// Try to convert this attribute's value to an expression or location buffer.
1953     ///
1954     /// Expressions and locations may be `DW_FORM_block*` or `DW_FORM_exprloc`.
1955     /// The standard doesn't mention `DW_FORM_block*` as a possible form, but
1956     /// it is encountered in practice.
exprloc_value(&self) -> Option<Expression<R>>1957     pub fn exprloc_value(&self) -> Option<Expression<R>> {
1958         Some(match *self {
1959             AttributeValue::Block(ref data) => Expression(data.clone()),
1960             AttributeValue::Exprloc(ref data) => data.clone(),
1961             _ => return None,
1962         })
1963     }
1964 
1965     /// Try to return this attribute's value as a string slice.
1966     ///
1967     /// If this attribute's value is either an inline `DW_FORM_string` string,
1968     /// or a `DW_FORM_strp` reference to an offset into the `.debug_str`
1969     /// section, return the attribute's string value as `Some`. Other attribute
1970     /// value forms are returned as `None`.
1971     ///
1972     /// Warning: this function does not handle all possible string forms.
1973     /// Use `Dwarf::attr_string` instead.
string_value(&self, debug_str: &DebugStr<R>) -> Option<R>1974     pub fn string_value(&self, debug_str: &DebugStr<R>) -> Option<R> {
1975         match *self {
1976             AttributeValue::String(ref string) => Some(string.clone()),
1977             AttributeValue::DebugStrRef(offset) => debug_str.get_str(offset).ok(),
1978             _ => None,
1979         }
1980     }
1981 
1982     /// Try to return this attribute's value as a string slice.
1983     ///
1984     /// If this attribute's value is either an inline `DW_FORM_string` string,
1985     /// or a `DW_FORM_strp` reference to an offset into the `.debug_str`
1986     /// section, or a `DW_FORM_strp_sup` reference to an offset into a supplementary
1987     /// object file, return the attribute's string value as `Some`. Other attribute
1988     /// value forms are returned as `None`.
1989     ///
1990     /// Warning: this function does not handle all possible string forms.
1991     /// Use `Dwarf::attr_string` instead.
string_value_sup( &self, debug_str: &DebugStr<R>, debug_str_sup: Option<&DebugStr<R>>, ) -> Option<R>1992     pub fn string_value_sup(
1993         &self,
1994         debug_str: &DebugStr<R>,
1995         debug_str_sup: Option<&DebugStr<R>>,
1996     ) -> Option<R> {
1997         match *self {
1998             AttributeValue::String(ref string) => Some(string.clone()),
1999             AttributeValue::DebugStrRef(offset) => debug_str.get_str(offset).ok(),
2000             AttributeValue::DebugStrRefSup(offset) => {
2001                 debug_str_sup.and_then(|s| s.get_str(offset).ok())
2002             }
2003             _ => None,
2004         }
2005     }
2006 }
2007 
length_u8_value<R: Reader>(input: &mut R) -> Result<R>2008 fn length_u8_value<R: Reader>(input: &mut R) -> Result<R> {
2009     let len = input.read_u8().map(R::Offset::from_u8)?;
2010     input.split(len)
2011 }
2012 
length_u16_value<R: Reader>(input: &mut R) -> Result<R>2013 fn length_u16_value<R: Reader>(input: &mut R) -> Result<R> {
2014     let len = input.read_u16().map(R::Offset::from_u16)?;
2015     input.split(len)
2016 }
2017 
length_u32_value<R: Reader>(input: &mut R) -> Result<R>2018 fn length_u32_value<R: Reader>(input: &mut R) -> Result<R> {
2019     let len = input.read_u32().map(R::Offset::from_u32)?;
2020     input.split(len)
2021 }
2022 
length_uleb128_value<R: Reader>(input: &mut R) -> Result<R>2023 fn length_uleb128_value<R: Reader>(input: &mut R) -> Result<R> {
2024     let len = input.read_uleb128().and_then(R::Offset::from_u64)?;
2025     input.split(len)
2026 }
2027 
2028 // Return true if the given `name` can be a section offset in DWARF version 2/3.
2029 // This is required to correctly handle relocations.
allow_section_offset(name: constants::DwAt, version: u16) -> bool2030 fn allow_section_offset(name: constants::DwAt, version: u16) -> bool {
2031     match name {
2032         constants::DW_AT_location
2033         | constants::DW_AT_stmt_list
2034         | constants::DW_AT_string_length
2035         | constants::DW_AT_return_addr
2036         | constants::DW_AT_start_scope
2037         | constants::DW_AT_frame_base
2038         | constants::DW_AT_macro_info
2039         | constants::DW_AT_macros
2040         | constants::DW_AT_segment
2041         | constants::DW_AT_static_link
2042         | constants::DW_AT_use_location
2043         | constants::DW_AT_vtable_elem_location
2044         | constants::DW_AT_ranges => true,
2045         constants::DW_AT_data_member_location => version == 2 || version == 3,
2046         _ => false,
2047     }
2048 }
2049 
parse_attribute<'unit, R: Reader>( input: &mut R, encoding: Encoding, spec: AttributeSpecification, ) -> Result<Attribute<R>>2050 pub(crate) fn parse_attribute<'unit, R: Reader>(
2051     input: &mut R,
2052     encoding: Encoding,
2053     spec: AttributeSpecification,
2054 ) -> Result<Attribute<R>> {
2055     let mut form = spec.form();
2056     loop {
2057         let value = match form {
2058             constants::DW_FORM_indirect => {
2059                 let dynamic_form = input.read_uleb128_u16()?;
2060                 form = constants::DwForm(dynamic_form);
2061                 continue;
2062             }
2063             constants::DW_FORM_addr => {
2064                 let addr = input.read_address(encoding.address_size)?;
2065                 AttributeValue::Addr(addr)
2066             }
2067             constants::DW_FORM_block1 => {
2068                 let block = length_u8_value(input)?;
2069                 AttributeValue::Block(block)
2070             }
2071             constants::DW_FORM_block2 => {
2072                 let block = length_u16_value(input)?;
2073                 AttributeValue::Block(block)
2074             }
2075             constants::DW_FORM_block4 => {
2076                 let block = length_u32_value(input)?;
2077                 AttributeValue::Block(block)
2078             }
2079             constants::DW_FORM_block => {
2080                 let block = length_uleb128_value(input)?;
2081                 AttributeValue::Block(block)
2082             }
2083             constants::DW_FORM_data1 => {
2084                 let data = input.read_u8()?;
2085                 AttributeValue::Data1(data)
2086             }
2087             constants::DW_FORM_data2 => {
2088                 let data = input.read_u16()?;
2089                 AttributeValue::Data2(data)
2090             }
2091             constants::DW_FORM_data4 => {
2092                 // DWARF version 2/3 may use DW_FORM_data4/8 for section offsets.
2093                 // Ensure we handle relocations here.
2094                 if encoding.format == Format::Dwarf32
2095                     && allow_section_offset(spec.name(), encoding.version)
2096                 {
2097                     let offset = input.read_offset(Format::Dwarf32)?;
2098                     AttributeValue::SecOffset(offset)
2099                 } else {
2100                     let data = input.read_u32()?;
2101                     AttributeValue::Data4(data)
2102                 }
2103             }
2104             constants::DW_FORM_data8 => {
2105                 // DWARF version 2/3 may use DW_FORM_data4/8 for section offsets.
2106                 // Ensure we handle relocations here.
2107                 if encoding.format == Format::Dwarf64
2108                     && allow_section_offset(spec.name(), encoding.version)
2109                 {
2110                     let offset = input.read_offset(Format::Dwarf64)?;
2111                     AttributeValue::SecOffset(offset)
2112                 } else {
2113                     let data = input.read_u64()?;
2114                     AttributeValue::Data8(data)
2115                 }
2116             }
2117             constants::DW_FORM_data16 => {
2118                 let block = input.split(R::Offset::from_u8(16))?;
2119                 AttributeValue::Block(block)
2120             }
2121             constants::DW_FORM_udata => {
2122                 let data = input.read_uleb128()?;
2123                 AttributeValue::Udata(data)
2124             }
2125             constants::DW_FORM_sdata => {
2126                 let data = input.read_sleb128()?;
2127                 AttributeValue::Sdata(data)
2128             }
2129             constants::DW_FORM_exprloc => {
2130                 let block = length_uleb128_value(input)?;
2131                 AttributeValue::Exprloc(Expression(block))
2132             }
2133             constants::DW_FORM_flag => {
2134                 let present = input.read_u8()?;
2135                 AttributeValue::Flag(present != 0)
2136             }
2137             constants::DW_FORM_flag_present => {
2138                 // FlagPresent is this weird compile time always true thing that
2139                 // isn't actually present in the serialized DIEs, only in the abbreviation.
2140                 AttributeValue::Flag(true)
2141             }
2142             constants::DW_FORM_sec_offset => {
2143                 let offset = input.read_offset(encoding.format)?;
2144                 AttributeValue::SecOffset(offset)
2145             }
2146             constants::DW_FORM_ref1 => {
2147                 let reference = input.read_u8().map(R::Offset::from_u8)?;
2148                 AttributeValue::UnitRef(UnitOffset(reference))
2149             }
2150             constants::DW_FORM_ref2 => {
2151                 let reference = input.read_u16().map(R::Offset::from_u16)?;
2152                 AttributeValue::UnitRef(UnitOffset(reference))
2153             }
2154             constants::DW_FORM_ref4 => {
2155                 let reference = input.read_u32().map(R::Offset::from_u32)?;
2156                 AttributeValue::UnitRef(UnitOffset(reference))
2157             }
2158             constants::DW_FORM_ref8 => {
2159                 let reference = input.read_u64().and_then(R::Offset::from_u64)?;
2160                 AttributeValue::UnitRef(UnitOffset(reference))
2161             }
2162             constants::DW_FORM_ref_udata => {
2163                 let reference = input.read_uleb128().and_then(R::Offset::from_u64)?;
2164                 AttributeValue::UnitRef(UnitOffset(reference))
2165             }
2166             constants::DW_FORM_ref_addr => {
2167                 // This is an offset, but DWARF version 2 specifies that DW_FORM_ref_addr
2168                 // has the same size as an address on the target system.  This was changed
2169                 // in DWARF version 3.
2170                 let offset = if encoding.version == 2 {
2171                     input.read_sized_offset(encoding.address_size)?
2172                 } else {
2173                     input.read_offset(encoding.format)?
2174                 };
2175                 AttributeValue::DebugInfoRef(DebugInfoOffset(offset))
2176             }
2177             constants::DW_FORM_ref_sig8 => {
2178                 let signature = input.read_u64()?;
2179                 AttributeValue::DebugTypesRef(DebugTypeSignature(signature))
2180             }
2181             constants::DW_FORM_ref_sup4 => {
2182                 let offset = input.read_u32().map(R::Offset::from_u32)?;
2183                 AttributeValue::DebugInfoRefSup(DebugInfoOffset(offset))
2184             }
2185             constants::DW_FORM_ref_sup8 => {
2186                 let offset = input.read_u64().and_then(R::Offset::from_u64)?;
2187                 AttributeValue::DebugInfoRefSup(DebugInfoOffset(offset))
2188             }
2189             constants::DW_FORM_GNU_ref_alt => {
2190                 let offset = input.read_offset(encoding.format)?;
2191                 AttributeValue::DebugInfoRefSup(DebugInfoOffset(offset))
2192             }
2193             constants::DW_FORM_string => {
2194                 let string = input.read_null_terminated_slice()?;
2195                 AttributeValue::String(string)
2196             }
2197             constants::DW_FORM_strp => {
2198                 let offset = input.read_offset(encoding.format)?;
2199                 AttributeValue::DebugStrRef(DebugStrOffset(offset))
2200             }
2201             constants::DW_FORM_strp_sup | constants::DW_FORM_GNU_strp_alt => {
2202                 let offset = input.read_offset(encoding.format)?;
2203                 AttributeValue::DebugStrRefSup(DebugStrOffset(offset))
2204             }
2205             constants::DW_FORM_line_strp => {
2206                 let offset = input.read_offset(encoding.format)?;
2207                 AttributeValue::DebugLineStrRef(DebugLineStrOffset(offset))
2208             }
2209             constants::DW_FORM_implicit_const => {
2210                 let data = spec
2211                     .implicit_const_value()
2212                     .ok_or(Error::InvalidImplicitConst)?;
2213                 AttributeValue::Sdata(data)
2214             }
2215             constants::DW_FORM_strx | constants::DW_FORM_GNU_str_index => {
2216                 let index = input.read_uleb128().and_then(R::Offset::from_u64)?;
2217                 AttributeValue::DebugStrOffsetsIndex(DebugStrOffsetsIndex(index))
2218             }
2219             constants::DW_FORM_strx1 => {
2220                 let index = input.read_u8().map(R::Offset::from_u8)?;
2221                 AttributeValue::DebugStrOffsetsIndex(DebugStrOffsetsIndex(index))
2222             }
2223             constants::DW_FORM_strx2 => {
2224                 let index = input.read_u16().map(R::Offset::from_u16)?;
2225                 AttributeValue::DebugStrOffsetsIndex(DebugStrOffsetsIndex(index))
2226             }
2227             constants::DW_FORM_strx3 => {
2228                 let index = input.read_uint(3).and_then(R::Offset::from_u64)?;
2229                 AttributeValue::DebugStrOffsetsIndex(DebugStrOffsetsIndex(index))
2230             }
2231             constants::DW_FORM_strx4 => {
2232                 let index = input.read_u32().map(R::Offset::from_u32)?;
2233                 AttributeValue::DebugStrOffsetsIndex(DebugStrOffsetsIndex(index))
2234             }
2235             constants::DW_FORM_addrx | constants::DW_FORM_GNU_addr_index => {
2236                 let index = input.read_uleb128().and_then(R::Offset::from_u64)?;
2237                 AttributeValue::DebugAddrIndex(DebugAddrIndex(index))
2238             }
2239             constants::DW_FORM_addrx1 => {
2240                 let index = input.read_u8().map(R::Offset::from_u8)?;
2241                 AttributeValue::DebugAddrIndex(DebugAddrIndex(index))
2242             }
2243             constants::DW_FORM_addrx2 => {
2244                 let index = input.read_u16().map(R::Offset::from_u16)?;
2245                 AttributeValue::DebugAddrIndex(DebugAddrIndex(index))
2246             }
2247             constants::DW_FORM_addrx3 => {
2248                 let index = input.read_uint(3).and_then(R::Offset::from_u64)?;
2249                 AttributeValue::DebugAddrIndex(DebugAddrIndex(index))
2250             }
2251             constants::DW_FORM_addrx4 => {
2252                 let index = input.read_u32().map(R::Offset::from_u32)?;
2253                 AttributeValue::DebugAddrIndex(DebugAddrIndex(index))
2254             }
2255             constants::DW_FORM_loclistx => {
2256                 let index = input.read_uleb128().and_then(R::Offset::from_u64)?;
2257                 AttributeValue::DebugLocListsIndex(DebugLocListsIndex(index))
2258             }
2259             constants::DW_FORM_rnglistx => {
2260                 let index = input.read_uleb128().and_then(R::Offset::from_u64)?;
2261                 AttributeValue::DebugRngListsIndex(DebugRngListsIndex(index))
2262             }
2263             _ => {
2264                 return Err(Error::UnknownForm);
2265             }
2266         };
2267         let attr = Attribute {
2268             name: spec.name(),
2269             value,
2270         };
2271         return Ok(attr);
2272     }
2273 }
2274 
2275 /// An iterator over a particular entry's attributes.
2276 ///
2277 /// See [the documentation for
2278 /// `DebuggingInformationEntry::attrs()`](./struct.DebuggingInformationEntry.html#method.attrs)
2279 /// for details.
2280 ///
2281 /// Can be [used with
2282 /// `FallibleIterator`](./index.html#using-with-fallibleiterator).
2283 #[derive(Clone, Copy, Debug)]
2284 pub struct AttrsIter<'abbrev, 'entry, 'unit, R: Reader> {
2285     input: R,
2286     attributes: &'abbrev [AttributeSpecification],
2287     entry: &'entry DebuggingInformationEntry<'abbrev, 'unit, R>,
2288 }
2289 
2290 impl<'abbrev, 'entry, 'unit, R: Reader> AttrsIter<'abbrev, 'entry, 'unit, R> {
2291     /// Advance the iterator and return the next attribute.
2292     ///
2293     /// Returns `None` when iteration is finished. If an error
2294     /// occurs while parsing the next attribute, then this error
2295     /// is returned, and all subsequent calls return `None`.
2296     #[allow(clippy::inline_always)]
2297     #[inline(always)]
next(&mut self) -> Result<Option<Attribute<R>>>2298     pub fn next(&mut self) -> Result<Option<Attribute<R>>> {
2299         if self.attributes.is_empty() {
2300             // Now that we have parsed all of the attributes, we know where
2301             // either (1) this entry's children start, if the abbreviation says
2302             // this entry has children; or (2) where this entry's siblings
2303             // begin.
2304             if let Some(end) = self.entry.attrs_len.get() {
2305                 debug_assert_eq!(end, self.input.offset_from(&self.entry.attrs_slice));
2306             } else {
2307                 self.entry
2308                     .attrs_len
2309                     .set(Some(self.input.offset_from(&self.entry.attrs_slice)));
2310             }
2311 
2312             return Ok(None);
2313         }
2314 
2315         let spec = self.attributes[0];
2316         let rest_spec = &self.attributes[1..];
2317         match parse_attribute(&mut self.input, self.entry.unit.encoding(), spec) {
2318             Ok(attr) => {
2319                 self.attributes = rest_spec;
2320                 Ok(Some(attr))
2321             }
2322             Err(e) => {
2323                 self.input.empty();
2324                 Err(e)
2325             }
2326         }
2327     }
2328 }
2329 
2330 #[cfg(feature = "fallible-iterator")]
2331 impl<'abbrev, 'entry, 'unit, R: Reader> fallible_iterator::FallibleIterator
2332     for AttrsIter<'abbrev, 'entry, 'unit, R>
2333 {
2334     type Item = Attribute<R>;
2335     type Error = Error;
2336 
next(&mut self) -> ::core::result::Result<Option<Self::Item>, Self::Error>2337     fn next(&mut self) -> ::core::result::Result<Option<Self::Item>, Self::Error> {
2338         AttrsIter::next(self)
2339     }
2340 }
2341 
2342 /// A raw reader of the data that defines the Debugging Information Entries.
2343 ///
2344 /// `EntriesRaw` provides primitives to read the components of Debugging Information
2345 /// Entries (DIEs). A DIE consists of an abbreviation code (read with `read_abbreviation`)
2346 /// followed by a number of attributes (read with `read_attribute`).
2347 /// The user must provide the control flow to read these correctly.
2348 /// In particular, all attributes must always be read before reading another
2349 /// abbreviation code.
2350 ///
2351 /// `EntriesRaw` lacks some features of `EntriesCursor`, such as the ability to skip
2352 /// to the next sibling DIE. However, this also allows it to optimize better, since it
2353 /// does not need to perform the extra bookkeeping required to support these features,
2354 /// and thus it is suitable for cases where performance is important.
2355 ///
2356 /// ## Example Usage
2357 /// ```rust,no_run
2358 /// # fn example() -> Result<(), gimli::Error> {
2359 /// # let debug_info = gimli::DebugInfo::new(&[], gimli::LittleEndian);
2360 /// # let get_some_unit = || debug_info.units().next().unwrap().unwrap();
2361 /// let unit = get_some_unit();
2362 /// # let debug_abbrev = gimli::DebugAbbrev::new(&[], gimli::LittleEndian);
2363 /// # let get_abbrevs_for_unit = |_| unit.abbreviations(&debug_abbrev).unwrap();
2364 /// let abbrevs = get_abbrevs_for_unit(&unit);
2365 ///
2366 /// let mut entries = unit.entries_raw(&abbrevs, None)?;
2367 /// while !entries.is_empty() {
2368 ///     let abbrev = if let Some(abbrev) = entries.read_abbreviation()? {
2369 ///         abbrev
2370 ///     } else {
2371 ///         // Null entry with no attributes.
2372 ///         continue
2373 ///     };
2374 ///     match abbrev.tag() {
2375 ///         gimli::DW_TAG_subprogram => {
2376 ///             // Loop over attributes for DIEs we care about.
2377 ///             for spec in abbrev.attributes() {
2378 ///                 let attr = entries.read_attribute(*spec)?;
2379 ///                 match attr.name() {
2380 ///                     // Handle attributes.
2381 ///                     _ => {}
2382 ///                 }
2383 ///             }
2384 ///         }
2385 ///         _ => {
2386 ///             // Skip attributes for DIEs we don't care about.
2387 ///             for spec in abbrev.attributes() {
2388 ///                 entries.read_attribute(*spec)?;
2389 ///             }
2390 ///         }
2391 ///     }
2392 /// }
2393 /// # unreachable!()
2394 /// # }
2395 /// ```
2396 #[derive(Clone, Debug)]
2397 pub struct EntriesRaw<'abbrev, 'unit, R>
2398 where
2399     R: Reader,
2400 {
2401     input: R,
2402     unit: &'unit UnitHeader<R>,
2403     abbreviations: &'abbrev Abbreviations,
2404     depth: isize,
2405 }
2406 
2407 impl<'abbrev, 'unit, R: Reader> EntriesRaw<'abbrev, 'unit, R> {
2408     /// Return true if there is no more input.
2409     #[inline]
is_empty(&self) -> bool2410     pub fn is_empty(&self) -> bool {
2411         self.input.is_empty()
2412     }
2413 
2414     /// Return the unit offset at which the reader will read next.
2415     ///
2416     /// If you want the offset of the next entry, then this must be called prior to reading
2417     /// the next entry.
next_offset(&self) -> UnitOffset<R::Offset>2418     pub fn next_offset(&self) -> UnitOffset<R::Offset> {
2419         UnitOffset(self.unit.header_size() + self.input.offset_from(&self.unit.entries_buf))
2420     }
2421 
2422     /// Return the depth of the next entry.
2423     ///
2424     /// This depth is updated when `read_abbreviation` is called, and is updated
2425     /// based on null entries and the `has_children` field in the abbreviation.
2426     #[inline]
next_depth(&self) -> isize2427     pub fn next_depth(&self) -> isize {
2428         self.depth
2429     }
2430 
2431     /// Read an abbreviation code and lookup the corresponding `Abbreviation`.
2432     ///
2433     /// Returns `Ok(None)` for null entries.
2434     #[inline]
read_abbreviation(&mut self) -> Result<Option<&'abbrev Abbreviation>>2435     pub fn read_abbreviation(&mut self) -> Result<Option<&'abbrev Abbreviation>> {
2436         let code = self.input.read_uleb128()?;
2437         if code == 0 {
2438             self.depth -= 1;
2439             return Ok(None);
2440         };
2441         let abbrev = self
2442             .abbreviations
2443             .get(code)
2444             .ok_or(Error::UnknownAbbreviation)?;
2445         if abbrev.has_children() {
2446             self.depth += 1;
2447         }
2448         Ok(Some(abbrev))
2449     }
2450 
2451     /// Read an attribute.
2452     #[inline]
read_attribute(&mut self, spec: AttributeSpecification) -> Result<Attribute<R>>2453     pub fn read_attribute(&mut self, spec: AttributeSpecification) -> Result<Attribute<R>> {
2454         parse_attribute(&mut self.input, self.unit.encoding(), spec)
2455     }
2456 }
2457 
2458 /// A cursor into the Debugging Information Entries tree for a compilation unit.
2459 ///
2460 /// The `EntriesCursor` can traverse the DIE tree in DFS order using `next_dfs()`,
2461 /// or skip to the next sibling of the entry the cursor is currently pointing to
2462 /// using `next_sibling()`.
2463 ///
2464 /// It is also possible to traverse the DIE tree at a lower abstraction level
2465 /// using `next_entry()`. This method does not skip over null entries, or provide
2466 /// any indication of the current tree depth. In this case, you must use `current()`
2467 /// to obtain the current entry, and `current().has_children()` to determine if
2468 /// the entry following the current entry will be a sibling or child. `current()`
2469 /// will return `None` if the current entry is a null entry, which signifies the
2470 /// end of the current tree depth.
2471 #[derive(Clone, Debug)]
2472 pub struct EntriesCursor<'abbrev, 'unit, R>
2473 where
2474     R: Reader,
2475 {
2476     input: R,
2477     unit: &'unit UnitHeader<R>,
2478     abbreviations: &'abbrev Abbreviations,
2479     cached_current: Option<DebuggingInformationEntry<'abbrev, 'unit, R>>,
2480     delta_depth: isize,
2481 }
2482 
2483 impl<'abbrev, 'unit, R: Reader> EntriesCursor<'abbrev, 'unit, R> {
2484     /// Get a reference to the entry that the cursor is currently pointing to.
2485     ///
2486     /// If the cursor is not pointing at an entry, or if the current entry is a
2487     /// null entry, then `None` is returned.
2488     #[inline]
current(&self) -> Option<&DebuggingInformationEntry<'abbrev, 'unit, R>>2489     pub fn current(&self) -> Option<&DebuggingInformationEntry<'abbrev, 'unit, R>> {
2490         self.cached_current.as_ref()
2491     }
2492 
2493     /// Move the cursor to the next DIE in the tree.
2494     ///
2495     /// Returns `Some` if there is a next entry, even if this entry is null.
2496     /// If there is no next entry, then `None` is returned.
next_entry(&mut self) -> Result<Option<()>>2497     pub fn next_entry(&mut self) -> Result<Option<()>> {
2498         if let Some(ref current) = self.cached_current {
2499             self.input = current.after_attrs()?;
2500         }
2501 
2502         if self.input.is_empty() {
2503             self.cached_current = None;
2504             self.delta_depth = 0;
2505             return Ok(None);
2506         }
2507 
2508         match DebuggingInformationEntry::parse(&mut self.input, self.unit, self.abbreviations) {
2509             Ok(Some(entry)) => {
2510                 self.delta_depth = entry.has_children() as isize;
2511                 self.cached_current = Some(entry);
2512                 Ok(Some(()))
2513             }
2514             Ok(None) => {
2515                 self.delta_depth = -1;
2516                 self.cached_current = None;
2517                 Ok(Some(()))
2518             }
2519             Err(e) => {
2520                 self.input.empty();
2521                 self.delta_depth = 0;
2522                 self.cached_current = None;
2523                 Err(e)
2524             }
2525         }
2526     }
2527 
2528     /// Move the cursor to the next DIE in the tree in DFS order.
2529     ///
2530     /// Upon successful movement of the cursor, return the delta traversal
2531     /// depth and the entry:
2532     ///
2533     ///   * If we moved down into the previous current entry's children, we get
2534     ///     `Some((1, entry))`.
2535     ///
2536     ///   * If we moved to the previous current entry's sibling, we get
2537     ///     `Some((0, entry))`.
2538     ///
2539     ///   * If the previous entry does not have any siblings and we move up to
2540     ///     its parent's next sibling, then we get `Some((-1, entry))`. Note that
2541     ///     if the parent doesn't have a next sibling, then it could go up to the
2542     ///     parent's parent's next sibling and return `Some((-2, entry))`, etc.
2543     ///
2544     /// If there is no next entry, then `None` is returned.
2545     ///
2546     /// Here is an example that finds the first entry in a compilation unit that
2547     /// does not have any children.
2548     ///
2549     /// ```
2550     /// # use gimli::{DebugAbbrev, DebugInfo, LittleEndian};
2551     /// # let info_buf = [
2552     /// #     // Comilation unit header
2553     /// #
2554     /// #     // 32-bit unit length = 25
2555     /// #     0x19, 0x00, 0x00, 0x00,
2556     /// #     // Version 4
2557     /// #     0x04, 0x00,
2558     /// #     // debug_abbrev_offset
2559     /// #     0x00, 0x00, 0x00, 0x00,
2560     /// #     // Address size
2561     /// #     0x04,
2562     /// #
2563     /// #     // DIEs
2564     /// #
2565     /// #     // Abbreviation code
2566     /// #     0x01,
2567     /// #     // Attribute of form DW_FORM_string = "foo\0"
2568     /// #     0x66, 0x6f, 0x6f, 0x00,
2569     /// #
2570     /// #       // Children
2571     /// #
2572     /// #       // Abbreviation code
2573     /// #       0x01,
2574     /// #       // Attribute of form DW_FORM_string = "foo\0"
2575     /// #       0x66, 0x6f, 0x6f, 0x00,
2576     /// #
2577     /// #         // Children
2578     /// #
2579     /// #         // Abbreviation code
2580     /// #         0x01,
2581     /// #         // Attribute of form DW_FORM_string = "foo\0"
2582     /// #         0x66, 0x6f, 0x6f, 0x00,
2583     /// #
2584     /// #           // Children
2585     /// #
2586     /// #           // End of children
2587     /// #           0x00,
2588     /// #
2589     /// #         // End of children
2590     /// #         0x00,
2591     /// #
2592     /// #       // End of children
2593     /// #       0x00,
2594     /// # ];
2595     /// # let debug_info = DebugInfo::new(&info_buf, LittleEndian);
2596     /// #
2597     /// # let abbrev_buf = [
2598     /// #     // Code
2599     /// #     0x01,
2600     /// #     // DW_TAG_subprogram
2601     /// #     0x2e,
2602     /// #     // DW_CHILDREN_yes
2603     /// #     0x01,
2604     /// #     // Begin attributes
2605     /// #       // Attribute name = DW_AT_name
2606     /// #       0x03,
2607     /// #       // Attribute form = DW_FORM_string
2608     /// #       0x08,
2609     /// #     // End attributes
2610     /// #     0x00,
2611     /// #     0x00,
2612     /// #     // Null terminator
2613     /// #     0x00
2614     /// # ];
2615     /// # let debug_abbrev = DebugAbbrev::new(&abbrev_buf, LittleEndian);
2616     /// #
2617     /// # let get_some_unit = || debug_info.units().next().unwrap().unwrap();
2618     ///
2619     /// let unit = get_some_unit();
2620     /// # let get_abbrevs_for_unit = |_| unit.abbreviations(&debug_abbrev).unwrap();
2621     /// let abbrevs = get_abbrevs_for_unit(&unit);
2622     ///
2623     /// let mut first_entry_with_no_children = None;
2624     /// let mut cursor = unit.entries(&abbrevs);
2625     ///
2626     /// // Move the cursor to the root.
2627     /// assert!(cursor.next_dfs().unwrap().is_some());
2628     ///
2629     /// // Traverse the DIE tree in depth-first search order.
2630     /// let mut depth = 0;
2631     /// while let Some((delta_depth, current)) = cursor.next_dfs().expect("Should parse next dfs") {
2632     ///     // Update depth value, and break out of the loop when we
2633     ///     // return to the original starting position.
2634     ///     depth += delta_depth;
2635     ///     if depth <= 0 {
2636     ///         break;
2637     ///     }
2638     ///
2639     ///     first_entry_with_no_children = Some(current.clone());
2640     /// }
2641     ///
2642     /// println!("The first entry with no children is {:?}",
2643     ///          first_entry_with_no_children.unwrap());
2644     /// ```
2645     #[allow(clippy::type_complexity)]
next_dfs( &mut self, ) -> Result<Option<(isize, &DebuggingInformationEntry<'abbrev, 'unit, R>)>>2646     pub fn next_dfs(
2647         &mut self,
2648     ) -> Result<Option<(isize, &DebuggingInformationEntry<'abbrev, 'unit, R>)>> {
2649         let mut delta_depth = self.delta_depth;
2650         loop {
2651             // The next entry should be the one we want.
2652             if self.next_entry()?.is_some() {
2653                 if let Some(ref entry) = self.cached_current {
2654                     return Ok(Some((delta_depth, entry)));
2655                 }
2656 
2657                 // next_entry() read a null entry.
2658                 delta_depth += self.delta_depth;
2659             } else {
2660                 return Ok(None);
2661             }
2662         }
2663     }
2664 
2665     /// Move the cursor to the next sibling DIE of the current one.
2666     ///
2667     /// Returns `Ok(Some(entry))` when the cursor has been moved to
2668     /// the next sibling, `Ok(None)` when there is no next sibling.
2669     ///
2670     /// The depth of the cursor is never changed if this method returns `Ok`.
2671     /// Once `Ok(None)` is returned, this method will continue to return
2672     /// `Ok(None)` until either `next_entry` or `next_dfs` is called.
2673     ///
2674     /// Here is an example that iterates over all of the direct children of the
2675     /// root entry:
2676     ///
2677     /// ```
2678     /// # use gimli::{DebugAbbrev, DebugInfo, LittleEndian};
2679     /// # let info_buf = [
2680     /// #     // Comilation unit header
2681     /// #
2682     /// #     // 32-bit unit length = 25
2683     /// #     0x19, 0x00, 0x00, 0x00,
2684     /// #     // Version 4
2685     /// #     0x04, 0x00,
2686     /// #     // debug_abbrev_offset
2687     /// #     0x00, 0x00, 0x00, 0x00,
2688     /// #     // Address size
2689     /// #     0x04,
2690     /// #
2691     /// #     // DIEs
2692     /// #
2693     /// #     // Abbreviation code
2694     /// #     0x01,
2695     /// #     // Attribute of form DW_FORM_string = "foo\0"
2696     /// #     0x66, 0x6f, 0x6f, 0x00,
2697     /// #
2698     /// #       // Children
2699     /// #
2700     /// #       // Abbreviation code
2701     /// #       0x01,
2702     /// #       // Attribute of form DW_FORM_string = "foo\0"
2703     /// #       0x66, 0x6f, 0x6f, 0x00,
2704     /// #
2705     /// #         // Children
2706     /// #
2707     /// #         // Abbreviation code
2708     /// #         0x01,
2709     /// #         // Attribute of form DW_FORM_string = "foo\0"
2710     /// #         0x66, 0x6f, 0x6f, 0x00,
2711     /// #
2712     /// #           // Children
2713     /// #
2714     /// #           // End of children
2715     /// #           0x00,
2716     /// #
2717     /// #         // End of children
2718     /// #         0x00,
2719     /// #
2720     /// #       // End of children
2721     /// #       0x00,
2722     /// # ];
2723     /// # let debug_info = DebugInfo::new(&info_buf, LittleEndian);
2724     /// #
2725     /// # let get_some_unit = || debug_info.units().next().unwrap().unwrap();
2726     ///
2727     /// # let abbrev_buf = [
2728     /// #     // Code
2729     /// #     0x01,
2730     /// #     // DW_TAG_subprogram
2731     /// #     0x2e,
2732     /// #     // DW_CHILDREN_yes
2733     /// #     0x01,
2734     /// #     // Begin attributes
2735     /// #       // Attribute name = DW_AT_name
2736     /// #       0x03,
2737     /// #       // Attribute form = DW_FORM_string
2738     /// #       0x08,
2739     /// #     // End attributes
2740     /// #     0x00,
2741     /// #     0x00,
2742     /// #     // Null terminator
2743     /// #     0x00
2744     /// # ];
2745     /// # let debug_abbrev = DebugAbbrev::new(&abbrev_buf, LittleEndian);
2746     /// #
2747     /// let unit = get_some_unit();
2748     /// # let get_abbrevs_for_unit = |_| unit.abbreviations(&debug_abbrev).unwrap();
2749     /// let abbrevs = get_abbrevs_for_unit(&unit);
2750     ///
2751     /// let mut cursor = unit.entries(&abbrevs);
2752     ///
2753     /// // Move the cursor to the root.
2754     /// assert!(cursor.next_dfs().unwrap().is_some());
2755     ///
2756     /// // Move the cursor to the root's first child.
2757     /// assert!(cursor.next_dfs().unwrap().is_some());
2758     ///
2759     /// // Iterate the root's children.
2760     /// loop {
2761     ///     {
2762     ///         let current = cursor.current().expect("Should be at an entry");
2763     ///         println!("{:?} is a child of the root", current);
2764     ///     }
2765     ///
2766     ///     if cursor.next_sibling().expect("Should parse next sibling").is_none() {
2767     ///         break;
2768     ///     }
2769     /// }
2770     /// ```
next_sibling( &mut self, ) -> Result<Option<&DebuggingInformationEntry<'abbrev, 'unit, R>>>2771     pub fn next_sibling(
2772         &mut self,
2773     ) -> Result<Option<&DebuggingInformationEntry<'abbrev, 'unit, R>>> {
2774         if self.current().is_none() {
2775             // We're already at the null for the end of the sibling list.
2776             return Ok(None);
2777         }
2778 
2779         // Loop until we find an entry at the current level.
2780         let mut depth = 0;
2781         loop {
2782             // Use is_some() and unwrap() to keep borrow checker happy.
2783             if self.current().is_some() && self.current().unwrap().has_children() {
2784                 if let Some(sibling_input) = self.current().unwrap().sibling() {
2785                     // Fast path: this entry has a DW_AT_sibling
2786                     // attribute pointing to its sibling, so jump
2787                     // to it (which keeps us at the same depth).
2788                     self.input = sibling_input;
2789                     self.cached_current = None;
2790                 } else {
2791                     // This entry has children, so the next entry is
2792                     // down one level.
2793                     depth += 1;
2794                 }
2795             }
2796 
2797             if self.next_entry()?.is_none() {
2798                 // End of input.
2799                 return Ok(None);
2800             }
2801 
2802             if depth == 0 {
2803                 // Found an entry at the current level.
2804                 return Ok(self.current());
2805             }
2806 
2807             if self.current().is_none() {
2808                 // A null entry means the end of a child list, so we're
2809                 // back up a level.
2810                 depth -= 1;
2811             }
2812         }
2813     }
2814 }
2815 
2816 /// The state information for a tree view of the Debugging Information Entries.
2817 ///
2818 /// The `EntriesTree` can be used to recursively iterate through the DIE
2819 /// tree, following the parent/child relationships. The `EntriesTree` contains
2820 /// shared state for all nodes in the tree, avoiding any duplicate parsing of
2821 /// entries during the traversal.
2822 ///
2823 /// ## Example Usage
2824 /// ```rust,no_run
2825 /// # fn example() -> Result<(), gimli::Error> {
2826 /// # let debug_info = gimli::DebugInfo::new(&[], gimli::LittleEndian);
2827 /// # let get_some_unit = || debug_info.units().next().unwrap().unwrap();
2828 /// let unit = get_some_unit();
2829 /// # let debug_abbrev = gimli::DebugAbbrev::new(&[], gimli::LittleEndian);
2830 /// # let get_abbrevs_for_unit = |_| unit.abbreviations(&debug_abbrev).unwrap();
2831 /// let abbrevs = get_abbrevs_for_unit(&unit);
2832 ///
2833 /// let mut tree = unit.entries_tree(&abbrevs, None)?;
2834 /// let root = tree.root()?;
2835 /// process_tree(root)?;
2836 /// # unreachable!()
2837 /// # }
2838 ///
2839 /// fn process_tree<R>(mut node: gimli::EntriesTreeNode<R>) -> gimli::Result<()>
2840 ///     where R: gimli::Reader
2841 /// {
2842 ///     {
2843 ///         // Examine the entry attributes.
2844 ///         let mut attrs = node.entry().attrs();
2845 ///         while let Some(attr) = attrs.next()? {
2846 ///         }
2847 ///     }
2848 ///     let mut children = node.children();
2849 ///     while let Some(child) = children.next()? {
2850 ///         // Recursively process a child.
2851 ///         process_tree(child);
2852 ///     }
2853 ///     Ok(())
2854 /// }
2855 /// ```
2856 #[derive(Clone, Debug)]
2857 pub struct EntriesTree<'abbrev, 'unit, R>
2858 where
2859     R: Reader,
2860 {
2861     root: R,
2862     unit: &'unit UnitHeader<R>,
2863     abbreviations: &'abbrev Abbreviations,
2864     input: R,
2865     entry: Option<DebuggingInformationEntry<'abbrev, 'unit, R>>,
2866     depth: isize,
2867 }
2868 
2869 impl<'abbrev, 'unit, R: Reader> EntriesTree<'abbrev, 'unit, R> {
new(root: R, unit: &'unit UnitHeader<R>, abbreviations: &'abbrev Abbreviations) -> Self2870     fn new(root: R, unit: &'unit UnitHeader<R>, abbreviations: &'abbrev Abbreviations) -> Self {
2871         let input = root.clone();
2872         EntriesTree {
2873             root,
2874             unit,
2875             abbreviations,
2876             input,
2877             entry: None,
2878             depth: 0,
2879         }
2880     }
2881 
2882     /// Returns the root node of the tree.
root<'me>(&'me mut self) -> Result<EntriesTreeNode<'abbrev, 'unit, 'me, R>>2883     pub fn root<'me>(&'me mut self) -> Result<EntriesTreeNode<'abbrev, 'unit, 'me, R>> {
2884         self.input = self.root.clone();
2885         self.entry =
2886             DebuggingInformationEntry::parse(&mut self.input, self.unit, self.abbreviations)?;
2887         if self.entry.is_none() {
2888             return Err(Error::UnexpectedNull);
2889         }
2890         self.depth = 0;
2891         Ok(EntriesTreeNode::new(self, 1))
2892     }
2893 
2894     /// Move the cursor to the next entry at the specified depth.
2895     ///
2896     /// Requires `depth <= self.depth + 1`.
2897     ///
2898     /// Returns `true` if successful.
next(&mut self, depth: isize) -> Result<bool>2899     fn next(&mut self, depth: isize) -> Result<bool> {
2900         if self.depth < depth {
2901             debug_assert_eq!(self.depth + 1, depth);
2902 
2903             match self.entry {
2904                 Some(ref entry) => {
2905                     if !entry.has_children() {
2906                         return Ok(false);
2907                     }
2908                     self.depth += 1;
2909                     self.input = entry.after_attrs()?;
2910                 }
2911                 None => return Ok(false),
2912             }
2913 
2914             if self.input.is_empty() {
2915                 self.entry = None;
2916                 return Ok(false);
2917             }
2918 
2919             return match DebuggingInformationEntry::parse(
2920                 &mut self.input,
2921                 self.unit,
2922                 self.abbreviations,
2923             ) {
2924                 Ok(entry) => {
2925                     self.entry = entry;
2926                     Ok(self.entry.is_some())
2927                 }
2928                 Err(e) => {
2929                     self.input.empty();
2930                     self.entry = None;
2931                     Err(e)
2932                 }
2933             };
2934         }
2935 
2936         loop {
2937             match self.entry {
2938                 Some(ref entry) => {
2939                     if entry.has_children() {
2940                         if let Some(sibling_input) = entry.sibling() {
2941                             // Fast path: this entry has a DW_AT_sibling
2942                             // attribute pointing to its sibling, so jump
2943                             // to it (which keeps us at the same depth).
2944                             self.input = sibling_input;
2945                         } else {
2946                             // This entry has children, so the next entry is
2947                             // down one level.
2948                             self.depth += 1;
2949                             self.input = entry.after_attrs()?;
2950                         }
2951                     } else {
2952                         // This entry has no children, so next entry is at same depth.
2953                         self.input = entry.after_attrs()?;
2954                     }
2955                 }
2956                 None => {
2957                     // This entry is a null, so next entry is up one level.
2958                     self.depth -= 1;
2959                 }
2960             }
2961 
2962             if self.input.is_empty() {
2963                 self.entry = None;
2964                 return Ok(false);
2965             }
2966 
2967             match DebuggingInformationEntry::parse(&mut self.input, self.unit, self.abbreviations) {
2968                 Ok(entry) => {
2969                     self.entry = entry;
2970                     if self.depth == depth {
2971                         return Ok(self.entry.is_some());
2972                     }
2973                 }
2974                 Err(e) => {
2975                     self.input.empty();
2976                     self.entry = None;
2977                     return Err(e);
2978                 }
2979             }
2980         }
2981     }
2982 }
2983 
2984 /// A node in the Debugging Information Entry tree.
2985 ///
2986 /// The root node of a tree can be obtained
2987 /// via [`EntriesTree::root`](./struct.EntriesTree.html#method.root).
2988 #[derive(Debug)]
2989 pub struct EntriesTreeNode<'abbrev, 'unit, 'tree, R: Reader> {
2990     tree: &'tree mut EntriesTree<'abbrev, 'unit, R>,
2991     depth: isize,
2992 }
2993 
2994 impl<'abbrev, 'unit, 'tree, R: Reader> EntriesTreeNode<'abbrev, 'unit, 'tree, R> {
new( tree: &'tree mut EntriesTree<'abbrev, 'unit, R>, depth: isize, ) -> EntriesTreeNode<'abbrev, 'unit, 'tree, R>2995     fn new(
2996         tree: &'tree mut EntriesTree<'abbrev, 'unit, R>,
2997         depth: isize,
2998     ) -> EntriesTreeNode<'abbrev, 'unit, 'tree, R> {
2999         debug_assert!(tree.entry.is_some());
3000         EntriesTreeNode { tree, depth }
3001     }
3002 
3003     /// Returns the current entry in the tree.
entry(&self) -> &DebuggingInformationEntry<'abbrev, 'unit, R>3004     pub fn entry(&self) -> &DebuggingInformationEntry<'abbrev, 'unit, R> {
3005         // We never create a node without an entry.
3006         self.tree.entry.as_ref().unwrap()
3007     }
3008 
3009     /// Create an iterator for the children of the current entry.
3010     ///
3011     /// The current entry can no longer be accessed after creating the
3012     /// iterator.
children(self) -> EntriesTreeIter<'abbrev, 'unit, 'tree, R>3013     pub fn children(self) -> EntriesTreeIter<'abbrev, 'unit, 'tree, R> {
3014         EntriesTreeIter::new(self.tree, self.depth)
3015     }
3016 }
3017 
3018 /// An iterator that allows traversal of the children of an
3019 /// `EntriesTreeNode`.
3020 ///
3021 /// The items returned by this iterator are also `EntriesTreeNode`s,
3022 /// which allow recursive traversal of grandchildren, etc.
3023 #[derive(Debug)]
3024 pub struct EntriesTreeIter<'abbrev, 'unit, 'tree, R: Reader> {
3025     tree: &'tree mut EntriesTree<'abbrev, 'unit, R>,
3026     depth: isize,
3027     empty: bool,
3028 }
3029 
3030 impl<'abbrev, 'unit, 'tree, R: Reader> EntriesTreeIter<'abbrev, 'unit, 'tree, R> {
new( tree: &'tree mut EntriesTree<'abbrev, 'unit, R>, depth: isize, ) -> EntriesTreeIter<'abbrev, 'unit, 'tree, R>3031     fn new(
3032         tree: &'tree mut EntriesTree<'abbrev, 'unit, R>,
3033         depth: isize,
3034     ) -> EntriesTreeIter<'abbrev, 'unit, 'tree, R> {
3035         EntriesTreeIter {
3036             tree,
3037             depth,
3038             empty: false,
3039         }
3040     }
3041 
3042     /// Returns an `EntriesTreeNode` for the next child entry.
3043     ///
3044     /// Returns `None` if there are no more children.
next<'me>(&'me mut self) -> Result<Option<EntriesTreeNode<'abbrev, 'unit, 'me, R>>>3045     pub fn next<'me>(&'me mut self) -> Result<Option<EntriesTreeNode<'abbrev, 'unit, 'me, R>>> {
3046         if self.empty {
3047             Ok(None)
3048         } else if self.tree.next(self.depth)? {
3049             Ok(Some(EntriesTreeNode::new(self.tree, self.depth + 1)))
3050         } else {
3051             self.empty = true;
3052             Ok(None)
3053         }
3054     }
3055 }
3056 
3057 /// Parse a type unit header's unique type signature. Callers should handle
3058 /// unique-ness checking.
parse_type_signature<R: Reader>(input: &mut R) -> Result<DebugTypeSignature>3059 fn parse_type_signature<R: Reader>(input: &mut R) -> Result<DebugTypeSignature> {
3060     input.read_u64().map(DebugTypeSignature)
3061 }
3062 
3063 /// Parse a type unit header's type offset.
parse_type_offset<R: Reader>(input: &mut R, format: Format) -> Result<UnitOffset<R::Offset>>3064 fn parse_type_offset<R: Reader>(input: &mut R, format: Format) -> Result<UnitOffset<R::Offset>> {
3065     input.read_offset(format).map(UnitOffset)
3066 }
3067 
3068 /// The `DebugTypes` struct represents the DWARF type information
3069 /// found in the `.debug_types` section.
3070 #[derive(Debug, Default, Clone, Copy)]
3071 pub struct DebugTypes<R> {
3072     debug_types_section: R,
3073 }
3074 
3075 impl<'input, Endian> DebugTypes<EndianSlice<'input, Endian>>
3076 where
3077     Endian: Endianity,
3078 {
3079     /// Construct a new `DebugTypes` instance from the data in the `.debug_types`
3080     /// section.
3081     ///
3082     /// It is the caller's responsibility to read the `.debug_types` section and
3083     /// present it as a `&[u8]` slice. That means using some ELF loader on
3084     /// Linux, a Mach-O loader on OSX, etc.
3085     ///
3086     /// ```
3087     /// use gimli::{DebugTypes, LittleEndian};
3088     ///
3089     /// # let buf = [0x00, 0x01, 0x02, 0x03];
3090     /// # let read_debug_types_section_somehow = || &buf;
3091     /// let debug_types = DebugTypes::new(read_debug_types_section_somehow(), LittleEndian);
3092     /// ```
new(debug_types_section: &'input [u8], endian: Endian) -> Self3093     pub fn new(debug_types_section: &'input [u8], endian: Endian) -> Self {
3094         Self::from(EndianSlice::new(debug_types_section, endian))
3095     }
3096 }
3097 
3098 impl<T> DebugTypes<T> {
3099     /// Create a `DebugTypes` section that references the data in `self`.
3100     ///
3101     /// This is useful when `R` implements `Reader` but `T` does not.
3102     ///
3103     /// ## Example Usage
3104     ///
3105     /// ```rust,no_run
3106     /// # let load_section = || unimplemented!();
3107     /// // Read the DWARF section into a `Vec` with whatever object loader you're using.
3108     /// let owned_section: gimli::DebugTypes<Vec<u8>> = load_section();
3109     /// // Create a reference to the DWARF section.
3110     /// let section = owned_section.borrow(|section| {
3111     ///     gimli::EndianSlice::new(&section, gimli::LittleEndian)
3112     /// });
3113     /// ```
borrow<'a, F, R>(&'a self, mut borrow: F) -> DebugTypes<R> where F: FnMut(&'a T) -> R,3114     pub fn borrow<'a, F, R>(&'a self, mut borrow: F) -> DebugTypes<R>
3115     where
3116         F: FnMut(&'a T) -> R,
3117     {
3118         borrow(&self.debug_types_section).into()
3119     }
3120 }
3121 
3122 impl<R> Section<R> for DebugTypes<R> {
id() -> SectionId3123     fn id() -> SectionId {
3124         SectionId::DebugTypes
3125     }
3126 
reader(&self) -> &R3127     fn reader(&self) -> &R {
3128         &self.debug_types_section
3129     }
3130 }
3131 
3132 impl<R> From<R> for DebugTypes<R> {
from(debug_types_section: R) -> Self3133     fn from(debug_types_section: R) -> Self {
3134         DebugTypes {
3135             debug_types_section,
3136         }
3137     }
3138 }
3139 
3140 impl<R: Reader> DebugTypes<R> {
3141     /// Iterate the type-units in this `.debug_types` section.
3142     ///
3143     /// ```
3144     /// use gimli::{DebugTypes, LittleEndian};
3145     ///
3146     /// # let buf = [];
3147     /// # let read_debug_types_section_somehow = || &buf;
3148     /// let debug_types = DebugTypes::new(read_debug_types_section_somehow(), LittleEndian);
3149     ///
3150     /// let mut iter = debug_types.units();
3151     /// while let Some(unit) = iter.next().unwrap() {
3152     ///     println!("unit's length is {}", unit.unit_length());
3153     /// }
3154     /// ```
3155     ///
3156     /// Can be [used with
3157     /// `FallibleIterator`](./index.html#using-with-fallibleiterator).
units(&self) -> TypeUnitHeadersIter<R>3158     pub fn units(&self) -> TypeUnitHeadersIter<R> {
3159         TypeUnitHeadersIter {
3160             input: self.debug_types_section.clone(),
3161             offset: DebugTypesOffset(R::Offset::from_u8(0)),
3162         }
3163     }
3164 }
3165 
3166 /// An iterator over the type-units of this `.debug_types` section.
3167 ///
3168 /// See the [documentation on
3169 /// `DebugTypes::units`](./struct.DebugTypes.html#method.units) for
3170 /// more detail.
3171 #[derive(Clone, Debug)]
3172 pub struct TypeUnitHeadersIter<R: Reader> {
3173     input: R,
3174     offset: DebugTypesOffset<R::Offset>,
3175 }
3176 
3177 impl<R: Reader> TypeUnitHeadersIter<R> {
3178     /// Advance the iterator to the next type unit header.
next(&mut self) -> Result<Option<TypeUnitHeader<R>>>3179     pub fn next(&mut self) -> Result<Option<TypeUnitHeader<R>>> {
3180         if self.input.is_empty() {
3181             Ok(None)
3182         } else {
3183             let len = self.input.len();
3184             match parse_type_unit_header(&mut self.input, self.offset) {
3185                 Ok(header) => {
3186                     self.offset.0 += len - self.input.len();
3187                     Ok(Some(header))
3188                 }
3189                 Err(e) => {
3190                     self.input.empty();
3191                     Err(e)
3192                 }
3193             }
3194         }
3195     }
3196 }
3197 
3198 #[cfg(feature = "fallible-iterator")]
3199 impl<R: Reader> fallible_iterator::FallibleIterator for TypeUnitHeadersIter<R> {
3200     type Item = TypeUnitHeader<R>;
3201     type Error = Error;
3202 
next(&mut self) -> ::core::result::Result<Option<Self::Item>, Self::Error>3203     fn next(&mut self) -> ::core::result::Result<Option<Self::Item>, Self::Error> {
3204         TypeUnitHeadersIter::next(self)
3205     }
3206 }
3207 
3208 /// The header of a type unit's debugging information.
3209 #[derive(Debug, Clone, Copy, PartialEq, Eq)]
3210 pub struct TypeUnitHeader<R, Offset = <R as Reader>::Offset>
3211 where
3212     R: Reader<Offset = Offset>,
3213     Offset: ReaderOffset,
3214 {
3215     header: UnitHeader<R, Offset>,
3216     offset: DebugTypesOffset<Offset>,
3217     type_signature: DebugTypeSignature,
3218     type_offset: UnitOffset<Offset>,
3219 }
3220 
3221 impl<R, Offset> TypeUnitHeader<R, Offset>
3222 where
3223     R: Reader<Offset = Offset>,
3224     Offset: ReaderOffset,
3225 {
3226     /// Construct a new `TypeUnitHeader`.
new( header: UnitHeader<R>, offset: DebugTypesOffset<R::Offset>, type_signature: DebugTypeSignature, type_offset: UnitOffset<R::Offset>, ) -> Self3227     fn new(
3228         header: UnitHeader<R>,
3229         offset: DebugTypesOffset<R::Offset>,
3230         type_signature: DebugTypeSignature,
3231         type_offset: UnitOffset<R::Offset>,
3232     ) -> Self {
3233         TypeUnitHeader {
3234             header,
3235             offset,
3236             type_signature,
3237             type_offset,
3238         }
3239     }
3240 
3241     /// Return the `UnitHeader` containing common unit fields.
header(self) -> UnitHeader<R, Offset>3242     pub fn header(self) -> UnitHeader<R, Offset> {
3243         self.header
3244     }
3245 
3246     /// Return the serialized size of the type-unit header for the given
3247     /// DWARF format.
size_of_header(encoding: Encoding) -> usize3248     pub fn size_of_header(encoding: Encoding) -> usize {
3249         let unit_header_size = UnitHeader::<R, _>::size_of_header(encoding);
3250         let type_signature_size = 8;
3251         let type_offset_size = encoding.format.word_size() as usize;
3252         unit_header_size + type_signature_size + type_offset_size
3253     }
3254 
3255     /// Get the offset of this compilation unit within the .debug_info section.
offset(&self) -> DebugTypesOffset<R::Offset>3256     pub fn offset(&self) -> DebugTypesOffset<R::Offset> {
3257         self.offset
3258     }
3259 
3260     /// Get the length of the debugging info for this type-unit.
unit_length(&self) -> R::Offset3261     pub fn unit_length(&self) -> R::Offset {
3262         self.header.unit_length
3263     }
3264 
3265     /// Get the length of the debugging info for this type-unit,
3266     /// including the byte length of the encoded length itself.
length_including_self(&self) -> R::Offset3267     pub fn length_including_self(&self) -> R::Offset {
3268         self.header.length_including_self()
3269     }
3270 
3271     /// Return the encoding parameters for this unit.
encoding(&self) -> Encoding3272     pub fn encoding(&self) -> Encoding {
3273         self.header.encoding
3274     }
3275 
3276     /// Get the DWARF version of the debugging info for this type-unit.
version(&self) -> u163277     pub fn version(&self) -> u16 {
3278         self.header.version()
3279     }
3280 
3281     /// The offset into the `.debug_abbrev` section for this type-unit's
3282     /// debugging information entries.
debug_abbrev_offset(&self) -> DebugAbbrevOffset<R::Offset>3283     pub fn debug_abbrev_offset(&self) -> DebugAbbrevOffset<R::Offset> {
3284         self.header.debug_abbrev_offset
3285     }
3286 
3287     /// The size of addresses (in bytes) in this type-unit.
address_size(&self) -> u83288     pub fn address_size(&self) -> u8 {
3289         self.header.address_size()
3290     }
3291 
3292     /// Whether this type unit is encoded in 64- or 32-bit DWARF.
format(&self) -> Format3293     pub fn format(&self) -> Format {
3294         self.header.format()
3295     }
3296 
3297     /// The serialized size of the header for this type-unit.
header_size(&self) -> R::Offset3298     pub fn header_size(&self) -> R::Offset {
3299         self.header.header_size()
3300     }
3301 
3302     /// Get the unique type signature for this type unit.
type_signature(&self) -> DebugTypeSignature3303     pub fn type_signature(&self) -> DebugTypeSignature {
3304         self.type_signature
3305     }
3306 
3307     /// Get the offset within this type unit where the type is defined.
type_offset(&self) -> UnitOffset<R::Offset>3308     pub fn type_offset(&self) -> UnitOffset<R::Offset> {
3309         self.type_offset
3310     }
3311 
3312     /// Navigate this type unit's `DebuggingInformationEntry`s.
entries<'me, 'abbrev>( &'me self, abbreviations: &'abbrev Abbreviations, ) -> EntriesCursor<'abbrev, 'me, R>3313     pub fn entries<'me, 'abbrev>(
3314         &'me self,
3315         abbreviations: &'abbrev Abbreviations,
3316     ) -> EntriesCursor<'abbrev, 'me, R> {
3317         self.header.entries(abbreviations)
3318     }
3319 
3320     /// Navigate this type unit's `DebuggingInformationEntry`s
3321     /// starting at the given offset.
entries_at_offset<'me, 'abbrev>( &'me self, abbreviations: &'abbrev Abbreviations, offset: UnitOffset<R::Offset>, ) -> Result<EntriesCursor<'abbrev, 'me, R>>3322     pub fn entries_at_offset<'me, 'abbrev>(
3323         &'me self,
3324         abbreviations: &'abbrev Abbreviations,
3325         offset: UnitOffset<R::Offset>,
3326     ) -> Result<EntriesCursor<'abbrev, 'me, R>> {
3327         self.header.entries_at_offset(abbreviations, offset)
3328     }
3329 
3330     /// Navigate this type unit's `DebuggingInformationEntry`s as a tree
3331     /// starting at the given offset.
entries_tree<'me, 'abbrev>( &'me self, abbreviations: &'abbrev Abbreviations, offset: Option<UnitOffset<R::Offset>>, ) -> Result<EntriesTree<'abbrev, 'me, R>>3332     pub fn entries_tree<'me, 'abbrev>(
3333         &'me self,
3334         abbreviations: &'abbrev Abbreviations,
3335         offset: Option<UnitOffset<R::Offset>>,
3336     ) -> Result<EntriesTree<'abbrev, 'me, R>> {
3337         self.header.entries_tree(abbreviations, offset)
3338     }
3339 
3340     /// Read the raw data that defines the Debugging Information Entries.
entries_raw<'me, 'abbrev>( &'me self, abbreviations: &'abbrev Abbreviations, offset: Option<UnitOffset<R::Offset>>, ) -> Result<EntriesRaw<'abbrev, 'me, R>>3341     pub fn entries_raw<'me, 'abbrev>(
3342         &'me self,
3343         abbreviations: &'abbrev Abbreviations,
3344         offset: Option<UnitOffset<R::Offset>>,
3345     ) -> Result<EntriesRaw<'abbrev, 'me, R>> {
3346         self.header.entries_raw(abbreviations, offset)
3347     }
3348 
3349     /// Parse this type unit's abbreviations.
3350     ///
3351     /// ```
3352     /// use gimli::DebugAbbrev;
3353     /// # use gimli::{DebugTypes, LittleEndian};
3354     /// # let types_buf = [
3355     /// #     // Type unit header
3356     /// #
3357     /// #     // 32-bit unit length = 37
3358     /// #     0x25, 0x00, 0x00, 0x00,
3359     /// #     // Version 4
3360     /// #     0x04, 0x00,
3361     /// #     // debug_abbrev_offset
3362     /// #     0x00, 0x00, 0x00, 0x00,
3363     /// #     // Address size
3364     /// #     0x04,
3365     /// #     // Type signature
3366     /// #     0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
3367     /// #     // Type offset
3368     /// #     0x01, 0x02, 0x03, 0x04,
3369     /// #
3370     /// #     // DIEs
3371     /// #
3372     /// #     // Abbreviation code
3373     /// #     0x01,
3374     /// #     // Attribute of form DW_FORM_string = "foo\0"
3375     /// #     0x66, 0x6f, 0x6f, 0x00,
3376     /// #
3377     /// #       // Children
3378     /// #
3379     /// #       // Abbreviation code
3380     /// #       0x01,
3381     /// #       // Attribute of form DW_FORM_string = "foo\0"
3382     /// #       0x66, 0x6f, 0x6f, 0x00,
3383     /// #
3384     /// #         // Children
3385     /// #
3386     /// #         // Abbreviation code
3387     /// #         0x01,
3388     /// #         // Attribute of form DW_FORM_string = "foo\0"
3389     /// #         0x66, 0x6f, 0x6f, 0x00,
3390     /// #
3391     /// #           // Children
3392     /// #
3393     /// #           // End of children
3394     /// #           0x00,
3395     /// #
3396     /// #         // End of children
3397     /// #         0x00,
3398     /// #
3399     /// #       // End of children
3400     /// #       0x00,
3401     /// # ];
3402     /// # let debug_types = DebugTypes::new(&types_buf, LittleEndian);
3403     /// #
3404     /// # let abbrev_buf = [
3405     /// #     // Code
3406     /// #     0x01,
3407     /// #     // DW_TAG_subprogram
3408     /// #     0x2e,
3409     /// #     // DW_CHILDREN_yes
3410     /// #     0x01,
3411     /// #     // Begin attributes
3412     /// #       // Attribute name = DW_AT_name
3413     /// #       0x03,
3414     /// #       // Attribute form = DW_FORM_string
3415     /// #       0x08,
3416     /// #     // End attributes
3417     /// #     0x00,
3418     /// #     0x00,
3419     /// #     // Null terminator
3420     /// #     0x00
3421     /// # ];
3422     /// #
3423     /// # let get_some_type_unit = || debug_types.units().next().unwrap().unwrap();
3424     ///
3425     /// let unit = get_some_type_unit();
3426     ///
3427     /// # let read_debug_abbrev_section_somehow = || &abbrev_buf;
3428     /// let debug_abbrev = DebugAbbrev::new(read_debug_abbrev_section_somehow(), LittleEndian);
3429     /// let abbrevs_for_unit = unit.abbreviations(&debug_abbrev).unwrap();
3430     /// ```
abbreviations(&self, debug_abbrev: &DebugAbbrev<R>) -> Result<Abbreviations>3431     pub fn abbreviations(&self, debug_abbrev: &DebugAbbrev<R>) -> Result<Abbreviations> {
3432         self.header.abbreviations(debug_abbrev)
3433     }
3434 }
3435 
3436 /// Parse a type unit header.
parse_type_unit_header<R: Reader>( input: &mut R, offset: DebugTypesOffset<R::Offset>, ) -> Result<TypeUnitHeader<R>>3437 fn parse_type_unit_header<R: Reader>(
3438     input: &mut R,
3439     offset: DebugTypesOffset<R::Offset>,
3440 ) -> Result<TypeUnitHeader<R>> {
3441     let mut header = parse_unit_header(input)?;
3442     let format = header.format();
3443     let signature = parse_type_signature(&mut header.entries_buf)?;
3444     let type_offset = parse_type_offset(&mut header.entries_buf, format)?;
3445     Ok(TypeUnitHeader::new(header, offset, signature, type_offset))
3446 }
3447 
3448 #[cfg(test)]
3449 // Tests require leb128::write.
3450 #[cfg(feature = "write")]
3451 mod tests {
3452     use super::*;
3453     use crate::constants;
3454     use crate::constants::*;
3455     use crate::endianity::{Endianity, LittleEndian};
3456     use crate::leb128;
3457     use crate::read::abbrev::tests::AbbrevSectionMethods;
3458     use crate::read::{
3459         Abbreviation, AttributeSpecification, DebugAbbrev, EndianSlice, Error, Result,
3460     };
3461     use crate::test_util::GimliSectionMethods;
3462     use alloc::vec::Vec;
3463     use core::cell::Cell;
3464     use test_assembler::{Endian, Label, LabelMaker, Section};
3465 
3466     // Mixin methods for `Section` to help define binary test data.
3467 
3468     trait UnitSectionMethods {
comp_unit<'input, E>( self, unit: &mut CompilationUnitHeader<EndianSlice<'input, E>>, ) -> Self where E: Endianity3469         fn comp_unit<'input, E>(
3470             self,
3471             unit: &mut CompilationUnitHeader<EndianSlice<'input, E>>,
3472         ) -> Self
3473         where
3474             E: Endianity;
type_unit<'input, E>(self, unit: &mut TypeUnitHeader<EndianSlice<'input, E>>) -> Self where E: Endianity3475         fn type_unit<'input, E>(self, unit: &mut TypeUnitHeader<EndianSlice<'input, E>>) -> Self
3476         where
3477             E: Endianity;
unit<'input, E>( self, unit: &mut UnitHeader<EndianSlice<'input, E>>, extra_header: &[u8], ) -> Self where E: Endianity3478         fn unit<'input, E>(
3479             self,
3480             unit: &mut UnitHeader<EndianSlice<'input, E>>,
3481             extra_header: &[u8],
3482         ) -> Self
3483         where
3484             E: Endianity;
die<F>(self, code: u64, attr: F) -> Self where F: Fn(Section) -> Section3485         fn die<F>(self, code: u64, attr: F) -> Self
3486         where
3487             F: Fn(Section) -> Section;
die_null(self) -> Self3488         fn die_null(self) -> Self;
attr_string(self, s: &str) -> Self3489         fn attr_string(self, s: &str) -> Self;
attr_ref1(self, o: u8) -> Self3490         fn attr_ref1(self, o: u8) -> Self;
offset(self, offset: usize, format: Format) -> Self3491         fn offset(self, offset: usize, format: Format) -> Self;
3492     }
3493 
3494     impl UnitSectionMethods for Section {
comp_unit<'input, E>( self, unit: &mut CompilationUnitHeader<EndianSlice<'input, E>>, ) -> Self where E: Endianity,3495         fn comp_unit<'input, E>(
3496             self,
3497             unit: &mut CompilationUnitHeader<EndianSlice<'input, E>>,
3498         ) -> Self
3499         where
3500             E: Endianity,
3501         {
3502             unit.offset = DebugInfoOffset(self.size() as usize);
3503             self.unit(&mut unit.header, &[])
3504         }
3505 
type_unit<'input, E>(self, unit: &mut TypeUnitHeader<EndianSlice<'input, E>>) -> Self where E: Endianity,3506         fn type_unit<'input, E>(self, unit: &mut TypeUnitHeader<EndianSlice<'input, E>>) -> Self
3507         where
3508             E: Endianity,
3509         {
3510             unit.offset = DebugTypesOffset(self.size() as usize);
3511             let section = Section::with_endian(Endian::Little)
3512                 .L64(unit.type_signature.0)
3513                 .offset(unit.type_offset.0, unit.header.format());
3514             let extra_header = section.get_contents().unwrap();
3515             self.unit(&mut unit.header, &extra_header)
3516         }
3517 
unit<'input, E>( self, unit: &mut UnitHeader<EndianSlice<'input, E>>, extra_header: &[u8], ) -> Self where E: Endianity,3518         fn unit<'input, E>(
3519             self,
3520             unit: &mut UnitHeader<EndianSlice<'input, E>>,
3521             extra_header: &[u8],
3522         ) -> Self
3523         where
3524             E: Endianity,
3525         {
3526             let length = Label::new();
3527             let start = Label::new();
3528             let end = Label::new();
3529 
3530             let section = match unit.format() {
3531                 Format::Dwarf32 => self.L32(&length),
3532                 Format::Dwarf64 => self.L32(0xffff_ffff).L64(&length),
3533             };
3534 
3535             let section = match unit.version() {
3536                 2 | 3 | 4 => section
3537                     .mark(&start)
3538                     .L16(unit.version())
3539                     .offset(unit.debug_abbrev_offset.0, unit.format())
3540                     .D8(unit.address_size())
3541                     .append_bytes(extra_header)
3542                     .append_bytes(unit.entries_buf.into())
3543                     .mark(&end),
3544                 5 => section
3545                     .mark(&start)
3546                     .L16(unit.version())
3547                     .D8(constants::DW_UT_compile.0)
3548                     .D8(unit.address_size())
3549                     .offset(unit.debug_abbrev_offset.0, unit.format())
3550                     .append_bytes(extra_header)
3551                     .append_bytes(unit.entries_buf.into())
3552                     .mark(&end),
3553                 _ => unreachable!(),
3554             };
3555 
3556             unit.unit_length = (&end - &start) as usize;
3557             length.set_const(unit.unit_length as u64);
3558 
3559             section
3560         }
3561 
die<F>(self, code: u64, attr: F) -> Self where F: Fn(Section) -> Section,3562         fn die<F>(self, code: u64, attr: F) -> Self
3563         where
3564             F: Fn(Section) -> Section,
3565         {
3566             let section = self.uleb(code);
3567             attr(section)
3568         }
3569 
die_null(self) -> Self3570         fn die_null(self) -> Self {
3571             self.D8(0)
3572         }
3573 
attr_string(self, attr: &str) -> Self3574         fn attr_string(self, attr: &str) -> Self {
3575             self.append_bytes(attr.as_bytes()).D8(0)
3576         }
3577 
attr_ref1(self, attr: u8) -> Self3578         fn attr_ref1(self, attr: u8) -> Self {
3579             self.D8(attr)
3580         }
3581 
offset(self, offset: usize, format: Format) -> Self3582         fn offset(self, offset: usize, format: Format) -> Self {
3583             match format {
3584                 Format::Dwarf32 => self.L32(offset as u32),
3585                 Format::Dwarf64 => self.L64(offset as u64),
3586             }
3587         }
3588     }
3589 
3590     #[test]
test_parse_debug_abbrev_offset_32()3591     fn test_parse_debug_abbrev_offset_32() {
3592         let section = Section::with_endian(Endian::Little).L32(0x0403_0201);
3593         let buf = section.get_contents().unwrap();
3594         let buf = &mut EndianSlice::new(&buf, LittleEndian);
3595 
3596         match parse_debug_abbrev_offset(buf, Format::Dwarf32) {
3597             Ok(val) => assert_eq!(val, DebugAbbrevOffset(0x0403_0201)),
3598             otherwise => panic!("Unexpected result: {:?}", otherwise),
3599         };
3600     }
3601 
3602     #[test]
test_parse_debug_abbrev_offset_32_incomplete()3603     fn test_parse_debug_abbrev_offset_32_incomplete() {
3604         let buf = [0x01, 0x02];
3605         let buf = &mut EndianSlice::new(&buf, LittleEndian);
3606 
3607         match parse_debug_abbrev_offset(buf, Format::Dwarf32) {
3608             Err(Error::UnexpectedEof(_)) => assert!(true),
3609             otherwise => panic!("Unexpected result: {:?}", otherwise),
3610         };
3611     }
3612 
3613     #[test]
3614     #[cfg(target_pointer_width = "64")]
test_parse_debug_abbrev_offset_64()3615     fn test_parse_debug_abbrev_offset_64() {
3616         let section = Section::with_endian(Endian::Little).L64(0x0807_0605_0403_0201);
3617         let buf = section.get_contents().unwrap();
3618         let buf = &mut EndianSlice::new(&buf, LittleEndian);
3619 
3620         match parse_debug_abbrev_offset(buf, Format::Dwarf64) {
3621             Ok(val) => assert_eq!(val, DebugAbbrevOffset(0x0807_0605_0403_0201)),
3622             otherwise => panic!("Unexpected result: {:?}", otherwise),
3623         };
3624     }
3625 
3626     #[test]
test_parse_debug_abbrev_offset_64_incomplete()3627     fn test_parse_debug_abbrev_offset_64_incomplete() {
3628         let buf = [0x01, 0x02];
3629         let buf = &mut EndianSlice::new(&buf, LittleEndian);
3630 
3631         match parse_debug_abbrev_offset(buf, Format::Dwarf64) {
3632             Err(Error::UnexpectedEof(_)) => assert!(true),
3633             otherwise => panic!("Unexpected result: {:?}", otherwise),
3634         };
3635     }
3636 
3637     #[test]
test_parse_debug_info_offset_32()3638     fn test_parse_debug_info_offset_32() {
3639         let section = Section::with_endian(Endian::Little).L32(0x0403_0201);
3640         let buf = section.get_contents().unwrap();
3641         let buf = &mut EndianSlice::new(&buf, LittleEndian);
3642 
3643         match parse_debug_info_offset(buf, Format::Dwarf32) {
3644             Ok(val) => assert_eq!(val, DebugInfoOffset(0x0403_0201)),
3645             otherwise => panic!("Unexpected result: {:?}", otherwise),
3646         };
3647     }
3648 
3649     #[test]
test_parse_debug_info_offset_32_incomplete()3650     fn test_parse_debug_info_offset_32_incomplete() {
3651         let buf = [0x01, 0x02];
3652         let buf = &mut EndianSlice::new(&buf, LittleEndian);
3653 
3654         match parse_debug_info_offset(buf, Format::Dwarf32) {
3655             Err(Error::UnexpectedEof(_)) => assert!(true),
3656             otherwise => panic!("Unexpected result: {:?}", otherwise),
3657         };
3658     }
3659 
3660     #[test]
3661     #[cfg(target_pointer_width = "64")]
test_parse_debug_info_offset_64()3662     fn test_parse_debug_info_offset_64() {
3663         let section = Section::with_endian(Endian::Little).L64(0x0807_0605_0403_0201);
3664         let buf = section.get_contents().unwrap();
3665         let buf = &mut EndianSlice::new(&buf, LittleEndian);
3666 
3667         match parse_debug_info_offset(buf, Format::Dwarf64) {
3668             Ok(val) => assert_eq!(val, DebugInfoOffset(0x0807_0605_0403_0201)),
3669             otherwise => panic!("Unexpected result: {:?}", otherwise),
3670         };
3671     }
3672 
3673     #[test]
test_parse_debug_info_offset_64_incomplete()3674     fn test_parse_debug_info_offset_64_incomplete() {
3675         let buf = [0x01, 0x02];
3676         let buf = &mut EndianSlice::new(&buf, LittleEndian);
3677 
3678         match parse_debug_info_offset(buf, Format::Dwarf64) {
3679             Err(Error::UnexpectedEof(_)) => assert!(true),
3680             otherwise => panic!("Unexpected result: {:?}", otherwise),
3681         };
3682     }
3683 
3684     #[test]
3685     #[cfg(target_pointer_width = "64")]
test_units()3686     fn test_units() {
3687         let expected_rest = &[1, 2, 3, 4, 5, 6, 7, 8, 9];
3688         let mut unit64 = CompilationUnitHeader {
3689             header: UnitHeader {
3690                 encoding: Encoding {
3691                     format: Format::Dwarf64,
3692                     version: 4,
3693                     address_size: 8,
3694                 },
3695                 unit_length: 0,
3696                 debug_abbrev_offset: DebugAbbrevOffset(0x0102_0304_0506_0708),
3697                 entries_buf: EndianSlice::new(expected_rest, LittleEndian),
3698             },
3699             offset: DebugInfoOffset(0),
3700         };
3701         let mut unit32 = CompilationUnitHeader {
3702             header: UnitHeader {
3703                 encoding: Encoding {
3704                     format: Format::Dwarf32,
3705                     version: 4,
3706                     address_size: 4,
3707                 },
3708                 unit_length: 0,
3709                 debug_abbrev_offset: DebugAbbrevOffset(0x0807_0605),
3710                 entries_buf: EndianSlice::new(expected_rest, LittleEndian),
3711             },
3712             offset: DebugInfoOffset(0),
3713         };
3714         let section = Section::with_endian(Endian::Little)
3715             .comp_unit(&mut unit64)
3716             .comp_unit(&mut unit32);
3717         let buf = section.get_contents().unwrap();
3718 
3719         let debug_info = DebugInfo::new(&buf, LittleEndian);
3720         let mut units = debug_info.units();
3721 
3722         assert_eq!(units.next(), Ok(Some(unit64)));
3723         assert_eq!(units.next(), Ok(Some(unit32)));
3724         assert_eq!(units.next(), Ok(None));
3725     }
3726 
3727     #[test]
test_unit_version_unknown_version()3728     fn test_unit_version_unknown_version() {
3729         let buf = [0x02, 0x00, 0x00, 0x00, 0xab, 0xcd];
3730         let rest = &mut EndianSlice::new(&buf, LittleEndian);
3731 
3732         match parse_unit_header(rest) {
3733             Err(Error::UnknownVersion(0xcdab)) => assert!(true),
3734             otherwise => panic!("Unexpected result: {:?}", otherwise),
3735         };
3736 
3737         let buf = [0x02, 0x00, 0x00, 0x00, 0x1, 0x0];
3738         let rest = &mut EndianSlice::new(&buf, LittleEndian);
3739 
3740         match parse_unit_header(rest) {
3741             Err(Error::UnknownVersion(1)) => assert!(true),
3742             otherwise => panic!("Unexpected result: {:?}", otherwise),
3743         };
3744     }
3745 
3746     #[test]
test_unit_version_incomplete()3747     fn test_unit_version_incomplete() {
3748         let buf = [0x01, 0x00, 0x00, 0x00, 0x04];
3749         let rest = &mut EndianSlice::new(&buf, LittleEndian);
3750 
3751         match parse_unit_header(rest) {
3752             Err(Error::UnexpectedEof(_)) => assert!(true),
3753             otherwise => panic!("Unexpected result: {:?}", otherwise),
3754         };
3755     }
3756 
3757     #[test]
test_parse_unit_header_32_ok()3758     fn test_parse_unit_header_32_ok() {
3759         let expected_rest = &[1, 2, 3, 4, 5, 6, 7, 8, 9];
3760         let encoding = Encoding {
3761             format: Format::Dwarf32,
3762             version: 4,
3763             address_size: 4,
3764         };
3765         let mut expected_unit = UnitHeader {
3766             encoding,
3767             unit_length: 0,
3768             debug_abbrev_offset: DebugAbbrevOffset(0x0807_0605),
3769             entries_buf: EndianSlice::new(expected_rest, LittleEndian),
3770         };
3771         let section = Section::with_endian(Endian::Little)
3772             .unit(&mut expected_unit, &[])
3773             .append_bytes(expected_rest);
3774         let buf = section.get_contents().unwrap();
3775         let rest = &mut EndianSlice::new(&buf, LittleEndian);
3776 
3777         assert_eq!(parse_unit_header(rest), Ok(expected_unit));
3778         assert_eq!(*rest, EndianSlice::new(expected_rest, LittleEndian));
3779     }
3780 
3781     #[test]
3782     #[cfg(target_pointer_width = "64")]
test_parse_unit_header_64_ok()3783     fn test_parse_unit_header_64_ok() {
3784         let expected_rest = &[1, 2, 3, 4, 5, 6, 7, 8, 9];
3785         let encoding = Encoding {
3786             format: Format::Dwarf64,
3787             version: 4,
3788             address_size: 8,
3789         };
3790         let mut expected_unit = UnitHeader {
3791             encoding,
3792             unit_length: 0,
3793             debug_abbrev_offset: DebugAbbrevOffset(0x0102_0304_0506_0708),
3794             entries_buf: EndianSlice::new(expected_rest, LittleEndian),
3795         };
3796         let section = Section::with_endian(Endian::Little)
3797             .unit(&mut expected_unit, &[])
3798             .append_bytes(expected_rest);
3799         let buf = section.get_contents().unwrap();
3800         let rest = &mut EndianSlice::new(&buf, LittleEndian);
3801 
3802         assert_eq!(parse_unit_header(rest), Ok(expected_unit));
3803         assert_eq!(*rest, EndianSlice::new(expected_rest, LittleEndian));
3804     }
3805 
3806     #[test]
test_parse_v5_unit_header_32_ok()3807     fn test_parse_v5_unit_header_32_ok() {
3808         let expected_rest = &[1, 2, 3, 4, 5, 6, 7, 8, 9];
3809         let encoding = Encoding {
3810             format: Format::Dwarf32,
3811             version: 5,
3812             address_size: 4,
3813         };
3814         let mut expected_unit = UnitHeader {
3815             encoding,
3816             unit_length: 0,
3817             debug_abbrev_offset: DebugAbbrevOffset(0x0807_0605),
3818             entries_buf: EndianSlice::new(expected_rest, LittleEndian),
3819         };
3820         let section = Section::with_endian(Endian::Little)
3821             .unit(&mut expected_unit, &[])
3822             .append_bytes(expected_rest);
3823         let buf = section.get_contents().unwrap();
3824         let rest = &mut EndianSlice::new(&buf, LittleEndian);
3825 
3826         assert_eq!(parse_unit_header(rest), Ok(expected_unit));
3827         assert_eq!(*rest, EndianSlice::new(expected_rest, LittleEndian));
3828     }
3829 
3830     #[test]
3831     #[cfg(target_pointer_width = "64")]
test_parse_v5_unit_header_64_ok()3832     fn test_parse_v5_unit_header_64_ok() {
3833         let expected_rest = &[1, 2, 3, 4, 5, 6, 7, 8, 9];
3834         let encoding = Encoding {
3835             format: Format::Dwarf64,
3836             version: 5,
3837             address_size: 8,
3838         };
3839         let mut expected_unit = UnitHeader {
3840             encoding,
3841             unit_length: 0,
3842             debug_abbrev_offset: DebugAbbrevOffset(0x0102_0304_0506_0708),
3843             entries_buf: EndianSlice::new(expected_rest, LittleEndian),
3844         };
3845         let section = Section::with_endian(Endian::Little)
3846             .unit(&mut expected_unit, &[])
3847             .append_bytes(expected_rest);
3848         let buf = section.get_contents().unwrap();
3849         let rest = &mut EndianSlice::new(&buf, LittleEndian);
3850 
3851         assert_eq!(parse_unit_header(rest), Ok(expected_unit));
3852         assert_eq!(*rest, EndianSlice::new(expected_rest, LittleEndian));
3853     }
3854 
3855     #[test]
test_parse_type_offset_32_ok()3856     fn test_parse_type_offset_32_ok() {
3857         let buf = [0x12, 0x34, 0x56, 0x78, 0x00];
3858         let rest = &mut EndianSlice::new(&buf, LittleEndian);
3859 
3860         match parse_type_offset(rest, Format::Dwarf32) {
3861             Ok(offset) => {
3862                 assert_eq!(rest.len(), 1);
3863                 assert_eq!(UnitOffset(0x7856_3412), offset);
3864             }
3865             otherwise => panic!("Unexpected result: {:?}", otherwise),
3866         }
3867     }
3868 
3869     #[test]
3870     #[cfg(target_pointer_width = "64")]
test_parse_type_offset_64_ok()3871     fn test_parse_type_offset_64_ok() {
3872         let buf = [0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xff, 0x00];
3873         let rest = &mut EndianSlice::new(&buf, LittleEndian);
3874 
3875         match parse_type_offset(rest, Format::Dwarf64) {
3876             Ok(offset) => {
3877                 assert_eq!(rest.len(), 1);
3878                 assert_eq!(UnitOffset(0xffde_bc9a_7856_3412), offset);
3879             }
3880             otherwise => panic!("Unexpected result: {:?}", otherwise),
3881         }
3882     }
3883 
3884     #[test]
test_parse_type_offset_incomplete()3885     fn test_parse_type_offset_incomplete() {
3886         // Need at least 4 bytes.
3887         let buf = [0xff, 0xff, 0xff];
3888         let rest = &mut EndianSlice::new(&buf, LittleEndian);
3889 
3890         match parse_type_offset(rest, Format::Dwarf32) {
3891             Err(Error::UnexpectedEof(_)) => assert!(true),
3892             otherwise => panic!("Unexpected result: {:?}", otherwise),
3893         };
3894     }
3895 
3896     #[test]
test_parse_type_unit_header_32_ok()3897     fn test_parse_type_unit_header_32_ok() {
3898         let expected_rest = &[1, 2, 3, 4, 5, 6, 7, 8, 9];
3899         let encoding = Encoding {
3900             format: Format::Dwarf32,
3901             version: 4,
3902             address_size: 8,
3903         };
3904         let mut expected_unit = TypeUnitHeader {
3905             header: UnitHeader {
3906                 encoding,
3907                 unit_length: 0,
3908                 debug_abbrev_offset: DebugAbbrevOffset(0x0807_0605),
3909                 entries_buf: EndianSlice::new(expected_rest, LittleEndian),
3910             },
3911             offset: DebugTypesOffset(0),
3912             type_signature: DebugTypeSignature(0xdead_beef_dead_beef),
3913             type_offset: UnitOffset(0x7856_3412),
3914         };
3915         let section = Section::with_endian(Endian::Little)
3916             .type_unit(&mut expected_unit)
3917             .append_bytes(expected_rest);
3918         let buf = section.get_contents().unwrap();
3919         let rest = &mut EndianSlice::new(&buf, LittleEndian);
3920 
3921         assert_eq!(
3922             parse_type_unit_header(rest, DebugTypesOffset(0)),
3923             Ok(expected_unit)
3924         );
3925         assert_eq!(*rest, EndianSlice::new(expected_rest, LittleEndian));
3926     }
3927 
3928     #[test]
3929     #[cfg(target_pointer_width = "64")]
test_parse_type_unit_header_64_ok()3930     fn test_parse_type_unit_header_64_ok() {
3931         let expected_rest = &[1, 2, 3, 4, 5, 6, 7, 8, 9];
3932         let encoding = Encoding {
3933             format: Format::Dwarf64,
3934             version: 4,
3935             address_size: 8,
3936         };
3937         let mut expected_unit = TypeUnitHeader {
3938             header: UnitHeader {
3939                 encoding,
3940                 unit_length: 0,
3941                 debug_abbrev_offset: DebugAbbrevOffset(0x0807_0605),
3942                 entries_buf: EndianSlice::new(expected_rest, LittleEndian),
3943             },
3944             offset: DebugTypesOffset(0),
3945             type_signature: DebugTypeSignature(0xdead_beef_dead_beef),
3946             type_offset: UnitOffset(0x7856_3412_7856_3412),
3947         };
3948         let section = Section::with_endian(Endian::Little)
3949             .type_unit(&mut expected_unit)
3950             .append_bytes(expected_rest);
3951         let buf = section.get_contents().unwrap();
3952         let rest = &mut EndianSlice::new(&buf, LittleEndian);
3953 
3954         assert_eq!(
3955             parse_type_unit_header(rest, DebugTypesOffset(0)),
3956             Ok(expected_unit)
3957         );
3958         assert_eq!(*rest, EndianSlice::new(expected_rest, LittleEndian));
3959     }
3960 
section_contents<F>(f: F) -> Vec<u8> where F: Fn(Section) -> Section,3961     fn section_contents<F>(f: F) -> Vec<u8>
3962     where
3963         F: Fn(Section) -> Section,
3964     {
3965         f(Section::with_endian(Endian::Little))
3966             .get_contents()
3967             .unwrap()
3968     }
3969 
3970     #[test]
test_attribute_value()3971     fn test_attribute_value() {
3972         let mut unit = test_parse_attribute_unit_default();
3973         let endian = unit.entries_buf.endian();
3974 
3975         let block_data = &[1, 2, 3, 4];
3976         let buf = section_contents(|s| s.uleb(block_data.len() as u64).append_bytes(block_data));
3977         let block = EndianSlice::new(&buf, endian);
3978 
3979         let buf = section_contents(|s| s.L32(0x0102_0304));
3980         let data4 = EndianSlice::new(&buf, endian);
3981 
3982         let buf = section_contents(|s| s.L64(0x0102_0304_0506_0708));
3983         let data8 = EndianSlice::new(&buf, endian);
3984 
3985         let tests = [
3986             (
3987                 Format::Dwarf32,
3988                 2,
3989                 constants::DW_AT_data_member_location,
3990                 constants::DW_FORM_block,
3991                 block,
3992                 AttributeValue::Block(EndianSlice::new(block_data, endian)),
3993                 AttributeValue::Exprloc(Expression(EndianSlice::new(block_data, endian))),
3994             ),
3995             (
3996                 Format::Dwarf32,
3997                 2,
3998                 constants::DW_AT_data_member_location,
3999                 constants::DW_FORM_data4,
4000                 data4,
4001                 AttributeValue::SecOffset(0x0102_0304),
4002                 AttributeValue::LocationListsRef(LocationListsOffset(0x0102_0304)),
4003             ),
4004             (
4005                 Format::Dwarf64,
4006                 2,
4007                 constants::DW_AT_data_member_location,
4008                 constants::DW_FORM_data4,
4009                 data4,
4010                 AttributeValue::Data4(0x0102_0304),
4011                 AttributeValue::Udata(0x0102_0304),
4012             ),
4013             (
4014                 Format::Dwarf32,
4015                 4,
4016                 constants::DW_AT_data_member_location,
4017                 constants::DW_FORM_data4,
4018                 data4,
4019                 AttributeValue::Data4(0x0102_0304),
4020                 AttributeValue::Udata(0x0102_0304),
4021             ),
4022             (
4023                 Format::Dwarf32,
4024                 2,
4025                 constants::DW_AT_data_member_location,
4026                 constants::DW_FORM_data8,
4027                 data8,
4028                 AttributeValue::Data8(0x0102_0304_0506_0708),
4029                 AttributeValue::Udata(0x0102_0304_0506_0708),
4030             ),
4031             #[cfg(target_pointer_width = "64")]
4032             (
4033                 Format::Dwarf64,
4034                 2,
4035                 constants::DW_AT_data_member_location,
4036                 constants::DW_FORM_data8,
4037                 data8,
4038                 AttributeValue::SecOffset(0x0102_0304_0506_0708),
4039                 AttributeValue::LocationListsRef(LocationListsOffset(0x0102_0304_0506_0708)),
4040             ),
4041             (
4042                 Format::Dwarf64,
4043                 4,
4044                 constants::DW_AT_data_member_location,
4045                 constants::DW_FORM_data8,
4046                 data8,
4047                 AttributeValue::Data8(0x0102_0304_0506_0708),
4048                 AttributeValue::Udata(0x0102_0304_0506_0708),
4049             ),
4050             (
4051                 Format::Dwarf32,
4052                 4,
4053                 constants::DW_AT_location,
4054                 constants::DW_FORM_data4,
4055                 data4,
4056                 AttributeValue::SecOffset(0x0102_0304),
4057                 AttributeValue::LocationListsRef(LocationListsOffset(0x0102_0304)),
4058             ),
4059             #[cfg(target_pointer_width = "64")]
4060             (
4061                 Format::Dwarf64,
4062                 4,
4063                 constants::DW_AT_location,
4064                 constants::DW_FORM_data8,
4065                 data8,
4066                 AttributeValue::SecOffset(0x0102_0304_0506_0708),
4067                 AttributeValue::LocationListsRef(LocationListsOffset(0x0102_0304_0506_0708)),
4068             ),
4069             (
4070                 Format::Dwarf32,
4071                 4,
4072                 constants::DW_AT_str_offsets_base,
4073                 constants::DW_FORM_sec_offset,
4074                 data4,
4075                 AttributeValue::SecOffset(0x0102_0304),
4076                 AttributeValue::DebugStrOffsetsBase(DebugStrOffsetsBase(0x0102_0304)),
4077             ),
4078             (
4079                 Format::Dwarf32,
4080                 4,
4081                 constants::DW_AT_stmt_list,
4082                 constants::DW_FORM_sec_offset,
4083                 data4,
4084                 AttributeValue::SecOffset(0x0102_0304),
4085                 AttributeValue::DebugLineRef(DebugLineOffset(0x0102_0304)),
4086             ),
4087             (
4088                 Format::Dwarf32,
4089                 4,
4090                 constants::DW_AT_addr_base,
4091                 constants::DW_FORM_sec_offset,
4092                 data4,
4093                 AttributeValue::SecOffset(0x0102_0304),
4094                 AttributeValue::DebugAddrBase(DebugAddrBase(0x0102_0304)),
4095             ),
4096             (
4097                 Format::Dwarf32,
4098                 4,
4099                 constants::DW_AT_rnglists_base,
4100                 constants::DW_FORM_sec_offset,
4101                 data4,
4102                 AttributeValue::SecOffset(0x0102_0304),
4103                 AttributeValue::DebugRngListsBase(DebugRngListsBase(0x0102_0304)),
4104             ),
4105             (
4106                 Format::Dwarf32,
4107                 4,
4108                 constants::DW_AT_loclists_base,
4109                 constants::DW_FORM_sec_offset,
4110                 data4,
4111                 AttributeValue::SecOffset(0x0102_0304),
4112                 AttributeValue::DebugLocListsBase(DebugLocListsBase(0x0102_0304)),
4113             ),
4114         ];
4115 
4116         for test in tests.iter() {
4117             let (format, version, name, form, mut input, expect_raw, expect_value) = *test;
4118             unit.encoding.format = format;
4119             unit.encoding.version = version;
4120             let spec = AttributeSpecification::new(name, form, None);
4121             let attribute =
4122                 parse_attribute(&mut input, unit.encoding(), spec).expect("Should parse attribute");
4123             assert_eq!(attribute.raw_value(), expect_raw);
4124             assert_eq!(attribute.value(), expect_value);
4125         }
4126     }
4127 
4128     #[test]
test_attribute_udata_sdata_value()4129     fn test_attribute_udata_sdata_value() {
4130         #[allow(clippy::type_complexity)]
4131         let tests: &[(
4132             AttributeValue<EndianSlice<LittleEndian>>,
4133             Option<u64>,
4134             Option<i64>,
4135         )] = &[
4136             (AttributeValue::Data1(1), Some(1), Some(1)),
4137             (
4138                 AttributeValue::Data1(core::u8::MAX),
4139                 Some(u64::from(std::u8::MAX)),
4140                 Some(-1),
4141             ),
4142             (AttributeValue::Data2(1), Some(1), Some(1)),
4143             (
4144                 AttributeValue::Data2(core::u16::MAX),
4145                 Some(u64::from(std::u16::MAX)),
4146                 Some(-1),
4147             ),
4148             (AttributeValue::Data4(1), Some(1), Some(1)),
4149             (
4150                 AttributeValue::Data4(core::u32::MAX),
4151                 Some(u64::from(std::u32::MAX)),
4152                 Some(-1),
4153             ),
4154             (AttributeValue::Data8(1), Some(1), Some(1)),
4155             (
4156                 AttributeValue::Data8(core::u64::MAX),
4157                 Some(core::u64::MAX),
4158                 Some(-1),
4159             ),
4160             (AttributeValue::Sdata(1), Some(1), Some(1)),
4161             (AttributeValue::Sdata(-1), None, Some(-1)),
4162             (AttributeValue::Udata(1), Some(1), Some(1)),
4163             (AttributeValue::Udata(1u64 << 63), Some(1u64 << 63), None),
4164         ];
4165         for test in tests.iter() {
4166             let (value, expect_udata, expect_sdata) = *test;
4167             let attribute = Attribute {
4168                 name: DW_AT_data_member_location,
4169                 value,
4170             };
4171             assert_eq!(attribute.udata_value(), expect_udata);
4172             assert_eq!(attribute.sdata_value(), expect_sdata);
4173         }
4174     }
4175 
test_parse_attribute_unit<Endian>( address_size: u8, format: Format, endian: Endian, ) -> UnitHeader<EndianSlice<'static, Endian>> where Endian: Endianity,4176     fn test_parse_attribute_unit<Endian>(
4177         address_size: u8,
4178         format: Format,
4179         endian: Endian,
4180     ) -> UnitHeader<EndianSlice<'static, Endian>>
4181     where
4182         Endian: Endianity,
4183     {
4184         let encoding = Encoding {
4185             format,
4186             version: 4,
4187             address_size,
4188         };
4189         UnitHeader::new(
4190             encoding,
4191             7,
4192             DebugAbbrevOffset(0x0807_0605),
4193             EndianSlice::new(&[], endian),
4194         )
4195     }
4196 
test_parse_attribute_unit_default() -> UnitHeader<EndianSlice<'static, LittleEndian>>4197     fn test_parse_attribute_unit_default() -> UnitHeader<EndianSlice<'static, LittleEndian>> {
4198         test_parse_attribute_unit(4, Format::Dwarf32, LittleEndian)
4199     }
4200 
test_parse_attribute<'input, Endian>( buf: &'input [u8], len: usize, unit: &UnitHeader<EndianSlice<'input, Endian>>, form: constants::DwForm, value: AttributeValue<EndianSlice<'input, Endian>>, ) where Endian: Endianity,4201     fn test_parse_attribute<'input, Endian>(
4202         buf: &'input [u8],
4203         len: usize,
4204         unit: &UnitHeader<EndianSlice<'input, Endian>>,
4205         form: constants::DwForm,
4206         value: AttributeValue<EndianSlice<'input, Endian>>,
4207     ) where
4208         Endian: Endianity,
4209     {
4210         let spec = AttributeSpecification::new(constants::DW_AT_low_pc, form, None);
4211 
4212         let expect = Attribute {
4213             name: constants::DW_AT_low_pc,
4214             value,
4215         };
4216 
4217         let rest = &mut EndianSlice::new(buf, Endian::default());
4218         match parse_attribute(rest, unit.encoding(), spec) {
4219             Ok(attr) => {
4220                 assert_eq!(attr, expect);
4221                 assert_eq!(*rest, EndianSlice::new(&buf[len..], Endian::default()));
4222             }
4223             otherwise => {
4224                 assert!(false, "Unexpected parse result = {:#?}", otherwise);
4225             }
4226         };
4227     }
4228 
4229     #[test]
test_parse_attribute_addr()4230     fn test_parse_attribute_addr() {
4231         let buf = [0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08];
4232         let unit = test_parse_attribute_unit(4, Format::Dwarf32, LittleEndian);
4233         let form = constants::DW_FORM_addr;
4234         let value = AttributeValue::Addr(0x0403_0201);
4235         test_parse_attribute(&buf, 4, &unit, form, value);
4236     }
4237 
4238     #[test]
test_parse_attribute_addr8()4239     fn test_parse_attribute_addr8() {
4240         let buf = [0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08];
4241         let unit = test_parse_attribute_unit(8, Format::Dwarf32, LittleEndian);
4242         let form = constants::DW_FORM_addr;
4243         let value = AttributeValue::Addr(0x0807_0605_0403_0201);
4244         test_parse_attribute(&buf, 8, &unit, form, value);
4245     }
4246 
4247     #[test]
test_parse_attribute_block1()4248     fn test_parse_attribute_block1() {
4249         // Length of data (3), three bytes of data, two bytes of left over input.
4250         let buf = [0x03, 0x09, 0x09, 0x09, 0x00, 0x00];
4251         let unit = test_parse_attribute_unit_default();
4252         let form = constants::DW_FORM_block1;
4253         let value = AttributeValue::Block(EndianSlice::new(&buf[1..4], LittleEndian));
4254         test_parse_attribute(&buf, 4, &unit, form, value);
4255     }
4256 
4257     #[test]
test_parse_attribute_block2()4258     fn test_parse_attribute_block2() {
4259         // Two byte length of data (2), two bytes of data, two bytes of left over input.
4260         let buf = [0x02, 0x00, 0x09, 0x09, 0x00, 0x00];
4261         let unit = test_parse_attribute_unit_default();
4262         let form = constants::DW_FORM_block2;
4263         let value = AttributeValue::Block(EndianSlice::new(&buf[2..4], LittleEndian));
4264         test_parse_attribute(&buf, 4, &unit, form, value);
4265     }
4266 
4267     #[test]
test_parse_attribute_block4()4268     fn test_parse_attribute_block4() {
4269         // Four byte length of data (2), two bytes of data, no left over input.
4270         let buf = [0x02, 0x00, 0x00, 0x00, 0x99, 0x99];
4271         let unit = test_parse_attribute_unit_default();
4272         let form = constants::DW_FORM_block4;
4273         let value = AttributeValue::Block(EndianSlice::new(&buf[4..], LittleEndian));
4274         test_parse_attribute(&buf, 6, &unit, form, value);
4275     }
4276 
4277     #[test]
test_parse_attribute_block()4278     fn test_parse_attribute_block() {
4279         // LEB length of data (2, one byte), two bytes of data, no left over input.
4280         let buf = [0x02, 0x99, 0x99];
4281         let unit = test_parse_attribute_unit_default();
4282         let form = constants::DW_FORM_block;
4283         let value = AttributeValue::Block(EndianSlice::new(&buf[1..], LittleEndian));
4284         test_parse_attribute(&buf, 3, &unit, form, value);
4285     }
4286 
4287     #[test]
test_parse_attribute_data1()4288     fn test_parse_attribute_data1() {
4289         let buf = [0x03];
4290         let unit = test_parse_attribute_unit_default();
4291         let form = constants::DW_FORM_data1;
4292         let value = AttributeValue::Data1(0x03);
4293         test_parse_attribute(&buf, 1, &unit, form, value);
4294     }
4295 
4296     #[test]
test_parse_attribute_data2()4297     fn test_parse_attribute_data2() {
4298         let buf = [0x02, 0x01, 0x0];
4299         let unit = test_parse_attribute_unit_default();
4300         let form = constants::DW_FORM_data2;
4301         let value = AttributeValue::Data2(0x0102);
4302         test_parse_attribute(&buf, 2, &unit, form, value);
4303     }
4304 
4305     #[test]
test_parse_attribute_data4()4306     fn test_parse_attribute_data4() {
4307         let buf = [0x01, 0x02, 0x03, 0x04, 0x99, 0x99];
4308         let unit = test_parse_attribute_unit_default();
4309         let form = constants::DW_FORM_data4;
4310         let value = AttributeValue::Data4(0x0403_0201);
4311         test_parse_attribute(&buf, 4, &unit, form, value);
4312     }
4313 
4314     #[test]
test_parse_attribute_data8()4315     fn test_parse_attribute_data8() {
4316         let buf = [0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x99, 0x99];
4317         let unit = test_parse_attribute_unit_default();
4318         let form = constants::DW_FORM_data8;
4319         let value = AttributeValue::Data8(0x0807_0605_0403_0201);
4320         test_parse_attribute(&buf, 8, &unit, form, value);
4321     }
4322 
4323     #[test]
test_parse_attribute_udata()4324     fn test_parse_attribute_udata() {
4325         let mut buf = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
4326 
4327         let bytes_written = {
4328             let mut writable = &mut buf[..];
4329             leb128::write::unsigned(&mut writable, 4097).expect("should write ok")
4330         };
4331 
4332         let unit = test_parse_attribute_unit_default();
4333         let form = constants::DW_FORM_udata;
4334         let value = AttributeValue::Udata(4097);
4335         test_parse_attribute(&buf, bytes_written, &unit, form, value);
4336     }
4337 
4338     #[test]
test_parse_attribute_sdata()4339     fn test_parse_attribute_sdata() {
4340         let mut buf = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
4341 
4342         let bytes_written = {
4343             let mut writable = &mut buf[..];
4344             leb128::write::signed(&mut writable, -4097).expect("should write ok")
4345         };
4346 
4347         let unit = test_parse_attribute_unit_default();
4348         let form = constants::DW_FORM_sdata;
4349         let value = AttributeValue::Sdata(-4097);
4350         test_parse_attribute(&buf, bytes_written, &unit, form, value);
4351     }
4352 
4353     #[test]
test_parse_attribute_exprloc()4354     fn test_parse_attribute_exprloc() {
4355         // LEB length of data (2, one byte), two bytes of data, one byte left over input.
4356         let buf = [0x02, 0x99, 0x99, 0x11];
4357         let unit = test_parse_attribute_unit_default();
4358         let form = constants::DW_FORM_exprloc;
4359         let value = AttributeValue::Exprloc(Expression(EndianSlice::new(&buf[1..3], LittleEndian)));
4360         test_parse_attribute(&buf, 3, &unit, form, value);
4361     }
4362 
4363     #[test]
test_parse_attribute_flag_true()4364     fn test_parse_attribute_flag_true() {
4365         let buf = [0x42];
4366         let unit = test_parse_attribute_unit_default();
4367         let form = constants::DW_FORM_flag;
4368         let value = AttributeValue::Flag(true);
4369         test_parse_attribute(&buf, 1, &unit, form, value);
4370     }
4371 
4372     #[test]
test_parse_attribute_flag_false()4373     fn test_parse_attribute_flag_false() {
4374         let buf = [0x00];
4375         let unit = test_parse_attribute_unit_default();
4376         let form = constants::DW_FORM_flag;
4377         let value = AttributeValue::Flag(false);
4378         test_parse_attribute(&buf, 1, &unit, form, value);
4379     }
4380 
4381     #[test]
test_parse_attribute_flag_present()4382     fn test_parse_attribute_flag_present() {
4383         let buf = [0x01, 0x02, 0x03, 0x04];
4384         let unit = test_parse_attribute_unit_default();
4385         let form = constants::DW_FORM_flag_present;
4386         let value = AttributeValue::Flag(true);
4387         // DW_FORM_flag_present does not consume any bytes of the input stream.
4388         test_parse_attribute(&buf, 0, &unit, form, value);
4389     }
4390 
4391     #[test]
test_parse_attribute_sec_offset_32()4392     fn test_parse_attribute_sec_offset_32() {
4393         let buf = [0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x10];
4394         let unit = test_parse_attribute_unit(4, Format::Dwarf32, LittleEndian);
4395         let form = constants::DW_FORM_sec_offset;
4396         let value = AttributeValue::SecOffset(0x0403_0201);
4397         test_parse_attribute(&buf, 4, &unit, form, value);
4398     }
4399 
4400     #[test]
4401     #[cfg(target_pointer_width = "64")]
test_parse_attribute_sec_offset_64()4402     fn test_parse_attribute_sec_offset_64() {
4403         let buf = [0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x10];
4404         let unit = test_parse_attribute_unit(4, Format::Dwarf64, LittleEndian);
4405         let form = constants::DW_FORM_sec_offset;
4406         let value = AttributeValue::SecOffset(0x0807_0605_0403_0201);
4407         test_parse_attribute(&buf, 8, &unit, form, value);
4408     }
4409 
4410     #[test]
test_parse_attribute_ref1()4411     fn test_parse_attribute_ref1() {
4412         let buf = [0x03];
4413         let unit = test_parse_attribute_unit_default();
4414         let form = constants::DW_FORM_ref1;
4415         let value = AttributeValue::UnitRef(UnitOffset(3));
4416         test_parse_attribute(&buf, 1, &unit, form, value);
4417     }
4418 
4419     #[test]
test_parse_attribute_ref2()4420     fn test_parse_attribute_ref2() {
4421         let buf = [0x02, 0x01, 0x0];
4422         let unit = test_parse_attribute_unit_default();
4423         let form = constants::DW_FORM_ref2;
4424         let value = AttributeValue::UnitRef(UnitOffset(258));
4425         test_parse_attribute(&buf, 2, &unit, form, value);
4426     }
4427 
4428     #[test]
test_parse_attribute_ref4()4429     fn test_parse_attribute_ref4() {
4430         let buf = [0x01, 0x02, 0x03, 0x04, 0x99, 0x99];
4431         let unit = test_parse_attribute_unit_default();
4432         let form = constants::DW_FORM_ref4;
4433         let value = AttributeValue::UnitRef(UnitOffset(0x0403_0201));
4434         test_parse_attribute(&buf, 4, &unit, form, value);
4435     }
4436 
4437     #[test]
4438     #[cfg(target_pointer_width = "64")]
test_parse_attribute_ref8()4439     fn test_parse_attribute_ref8() {
4440         let buf = [0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x99, 0x99];
4441         let unit = test_parse_attribute_unit_default();
4442         let form = constants::DW_FORM_ref8;
4443         let value = AttributeValue::UnitRef(UnitOffset(0x0807_0605_0403_0201));
4444         test_parse_attribute(&buf, 8, &unit, form, value);
4445     }
4446 
4447     #[test]
test_parse_attribute_ref_sup4()4448     fn test_parse_attribute_ref_sup4() {
4449         let buf = [0x01, 0x02, 0x03, 0x04, 0x99, 0x99];
4450         let unit = test_parse_attribute_unit_default();
4451         let form = constants::DW_FORM_ref_sup4;
4452         let value = AttributeValue::DebugInfoRefSup(DebugInfoOffset(0x0403_0201));
4453         test_parse_attribute(&buf, 4, &unit, form, value);
4454     }
4455 
4456     #[test]
4457     #[cfg(target_pointer_width = "64")]
test_parse_attribute_ref_sup8()4458     fn test_parse_attribute_ref_sup8() {
4459         let buf = [0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x99, 0x99];
4460         let unit = test_parse_attribute_unit_default();
4461         let form = constants::DW_FORM_ref_sup8;
4462         let value = AttributeValue::DebugInfoRefSup(DebugInfoOffset(0x0807_0605_0403_0201));
4463         test_parse_attribute(&buf, 8, &unit, form, value);
4464     }
4465 
4466     #[test]
test_parse_attribute_refudata()4467     fn test_parse_attribute_refudata() {
4468         let mut buf = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
4469 
4470         let bytes_written = {
4471             let mut writable = &mut buf[..];
4472             leb128::write::unsigned(&mut writable, 4097).expect("should write ok")
4473         };
4474 
4475         let unit = test_parse_attribute_unit_default();
4476         let form = constants::DW_FORM_ref_udata;
4477         let value = AttributeValue::UnitRef(UnitOffset(4097));
4478         test_parse_attribute(&buf, bytes_written, &unit, form, value);
4479     }
4480 
4481     #[test]
test_parse_attribute_refaddr_32()4482     fn test_parse_attribute_refaddr_32() {
4483         let buf = [0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x99, 0x99];
4484         let unit = test_parse_attribute_unit(4, Format::Dwarf32, LittleEndian);
4485         let form = constants::DW_FORM_ref_addr;
4486         let value = AttributeValue::DebugInfoRef(DebugInfoOffset(0x0403_0201));
4487         test_parse_attribute(&buf, 4, &unit, form, value);
4488     }
4489 
4490     #[test]
4491     #[cfg(target_pointer_width = "64")]
test_parse_attribute_refaddr_64()4492     fn test_parse_attribute_refaddr_64() {
4493         let buf = [0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x99, 0x99];
4494         let unit = test_parse_attribute_unit(4, Format::Dwarf64, LittleEndian);
4495         let form = constants::DW_FORM_ref_addr;
4496         let value = AttributeValue::DebugInfoRef(DebugInfoOffset(0x0807_0605_0403_0201));
4497         test_parse_attribute(&buf, 8, &unit, form, value);
4498     }
4499 
4500     #[test]
test_parse_attribute_refaddr_version2()4501     fn test_parse_attribute_refaddr_version2() {
4502         let buf = [0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x99, 0x99];
4503         let mut unit = test_parse_attribute_unit(4, Format::Dwarf32, LittleEndian);
4504         unit.encoding.version = 2;
4505         let form = constants::DW_FORM_ref_addr;
4506         let value = AttributeValue::DebugInfoRef(DebugInfoOffset(0x0403_0201));
4507         test_parse_attribute(&buf, 4, &unit, form, value);
4508     }
4509 
4510     #[test]
4511     #[cfg(target_pointer_width = "64")]
test_parse_attribute_refaddr8_version2()4512     fn test_parse_attribute_refaddr8_version2() {
4513         let buf = [0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x99, 0x99];
4514         let mut unit = test_parse_attribute_unit(8, Format::Dwarf32, LittleEndian);
4515         unit.encoding.version = 2;
4516         let form = constants::DW_FORM_ref_addr;
4517         let value = AttributeValue::DebugInfoRef(DebugInfoOffset(0x0807_0605_0403_0201));
4518         test_parse_attribute(&buf, 8, &unit, form, value);
4519     }
4520 
4521     #[test]
test_parse_attribute_gnu_ref_alt_32()4522     fn test_parse_attribute_gnu_ref_alt_32() {
4523         let buf = [0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x99, 0x99];
4524         let unit = test_parse_attribute_unit(4, Format::Dwarf32, LittleEndian);
4525         let form = constants::DW_FORM_GNU_ref_alt;
4526         let value = AttributeValue::DebugInfoRefSup(DebugInfoOffset(0x0403_0201));
4527         test_parse_attribute(&buf, 4, &unit, form, value);
4528     }
4529 
4530     #[test]
4531     #[cfg(target_pointer_width = "64")]
test_parse_attribute_gnu_ref_alt_64()4532     fn test_parse_attribute_gnu_ref_alt_64() {
4533         let buf = [0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x99, 0x99];
4534         let unit = test_parse_attribute_unit(4, Format::Dwarf64, LittleEndian);
4535         let form = constants::DW_FORM_GNU_ref_alt;
4536         let value = AttributeValue::DebugInfoRefSup(DebugInfoOffset(0x0807_0605_0403_0201));
4537         test_parse_attribute(&buf, 8, &unit, form, value);
4538     }
4539 
4540     #[test]
test_parse_attribute_refsig8()4541     fn test_parse_attribute_refsig8() {
4542         let buf = [0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x99, 0x99];
4543         let unit = test_parse_attribute_unit_default();
4544         let form = constants::DW_FORM_ref_sig8;
4545         let value = AttributeValue::DebugTypesRef(DebugTypeSignature(0x0807_0605_0403_0201));
4546         test_parse_attribute(&buf, 8, &unit, form, value);
4547     }
4548 
4549     #[test]
test_parse_attribute_string()4550     fn test_parse_attribute_string() {
4551         let buf = [0x01, 0x02, 0x03, 0x04, 0x05, 0x0, 0x99, 0x99];
4552         let unit = test_parse_attribute_unit_default();
4553         let form = constants::DW_FORM_string;
4554         let value = AttributeValue::String(EndianSlice::new(&buf[..5], LittleEndian));
4555         test_parse_attribute(&buf, 6, &unit, form, value);
4556     }
4557 
4558     #[test]
test_parse_attribute_strp_32()4559     fn test_parse_attribute_strp_32() {
4560         let buf = [0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x99, 0x99];
4561         let unit = test_parse_attribute_unit(4, Format::Dwarf32, LittleEndian);
4562         let form = constants::DW_FORM_strp;
4563         let value = AttributeValue::DebugStrRef(DebugStrOffset(0x0403_0201));
4564         test_parse_attribute(&buf, 4, &unit, form, value);
4565     }
4566 
4567     #[test]
4568     #[cfg(target_pointer_width = "64")]
test_parse_attribute_strp_64()4569     fn test_parse_attribute_strp_64() {
4570         let buf = [0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x99, 0x99];
4571         let unit = test_parse_attribute_unit(4, Format::Dwarf64, LittleEndian);
4572         let form = constants::DW_FORM_strp;
4573         let value = AttributeValue::DebugStrRef(DebugStrOffset(0x0807_0605_0403_0201));
4574         test_parse_attribute(&buf, 8, &unit, form, value);
4575     }
4576 
4577     #[test]
test_parse_attribute_strp_sup_32()4578     fn test_parse_attribute_strp_sup_32() {
4579         let buf = [0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x99, 0x99];
4580         let unit = test_parse_attribute_unit(4, Format::Dwarf32, LittleEndian);
4581         let form = constants::DW_FORM_strp_sup;
4582         let value = AttributeValue::DebugStrRefSup(DebugStrOffset(0x0403_0201));
4583         test_parse_attribute(&buf, 4, &unit, form, value);
4584     }
4585 
4586     #[test]
4587     #[cfg(target_pointer_width = "64")]
test_parse_attribute_strp_sup_64()4588     fn test_parse_attribute_strp_sup_64() {
4589         let buf = [0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x99, 0x99];
4590         let unit = test_parse_attribute_unit(4, Format::Dwarf64, LittleEndian);
4591         let form = constants::DW_FORM_strp_sup;
4592         let value = AttributeValue::DebugStrRefSup(DebugStrOffset(0x0807_0605_0403_0201));
4593         test_parse_attribute(&buf, 8, &unit, form, value);
4594     }
4595 
4596     #[test]
test_parse_attribute_gnu_strp_alt_32()4597     fn test_parse_attribute_gnu_strp_alt_32() {
4598         let buf = [0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x99, 0x99];
4599         let unit = test_parse_attribute_unit(4, Format::Dwarf32, LittleEndian);
4600         let form = constants::DW_FORM_GNU_strp_alt;
4601         let value = AttributeValue::DebugStrRefSup(DebugStrOffset(0x0403_0201));
4602         test_parse_attribute(&buf, 4, &unit, form, value);
4603     }
4604 
4605     #[test]
4606     #[cfg(target_pointer_width = "64")]
test_parse_attribute_gnu_strp_alt_64()4607     fn test_parse_attribute_gnu_strp_alt_64() {
4608         let buf = [0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x99, 0x99];
4609         let unit = test_parse_attribute_unit(4, Format::Dwarf64, LittleEndian);
4610         let form = constants::DW_FORM_GNU_strp_alt;
4611         let value = AttributeValue::DebugStrRefSup(DebugStrOffset(0x0807_0605_0403_0201));
4612         test_parse_attribute(&buf, 8, &unit, form, value);
4613     }
4614 
4615     #[test]
test_parse_attribute_strx()4616     fn test_parse_attribute_strx() {
4617         let mut buf = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
4618 
4619         let bytes_written = {
4620             let mut writable = &mut buf[..];
4621             leb128::write::unsigned(&mut writable, 4097).expect("should write ok")
4622         };
4623 
4624         let unit = test_parse_attribute_unit_default();
4625         let form = constants::DW_FORM_strx;
4626         let value = AttributeValue::DebugStrOffsetsIndex(DebugStrOffsetsIndex(4097));
4627         test_parse_attribute(&buf, bytes_written, &unit, form, value);
4628     }
4629 
4630     #[test]
test_parse_attribute_strx1()4631     fn test_parse_attribute_strx1() {
4632         let buf = [0x01, 0x99, 0x99];
4633         let unit = test_parse_attribute_unit(4, Format::Dwarf64, LittleEndian);
4634         let form = constants::DW_FORM_strx1;
4635         let value = AttributeValue::DebugStrOffsetsIndex(DebugStrOffsetsIndex(0x01));
4636         test_parse_attribute(&buf, 1, &unit, form, value);
4637     }
4638 
4639     #[test]
test_parse_attribute_strx2()4640     fn test_parse_attribute_strx2() {
4641         let buf = [0x01, 0x02, 0x99, 0x99];
4642         let unit = test_parse_attribute_unit(4, Format::Dwarf64, LittleEndian);
4643         let form = constants::DW_FORM_strx2;
4644         let value = AttributeValue::DebugStrOffsetsIndex(DebugStrOffsetsIndex(0x0201));
4645         test_parse_attribute(&buf, 2, &unit, form, value);
4646     }
4647 
4648     #[test]
test_parse_attribute_strx3()4649     fn test_parse_attribute_strx3() {
4650         let buf = [0x01, 0x02, 0x03, 0x99, 0x99];
4651         let unit = test_parse_attribute_unit(4, Format::Dwarf64, LittleEndian);
4652         let form = constants::DW_FORM_strx3;
4653         let value = AttributeValue::DebugStrOffsetsIndex(DebugStrOffsetsIndex(0x03_0201));
4654         test_parse_attribute(&buf, 3, &unit, form, value);
4655     }
4656 
4657     #[test]
test_parse_attribute_strx4()4658     fn test_parse_attribute_strx4() {
4659         let buf = [0x01, 0x02, 0x03, 0x04, 0x99, 0x99];
4660         let unit = test_parse_attribute_unit(4, Format::Dwarf64, LittleEndian);
4661         let form = constants::DW_FORM_strx4;
4662         let value = AttributeValue::DebugStrOffsetsIndex(DebugStrOffsetsIndex(0x0403_0201));
4663         test_parse_attribute(&buf, 4, &unit, form, value);
4664     }
4665 
4666     #[test]
test_parse_attribute_addrx()4667     fn test_parse_attribute_addrx() {
4668         let mut buf = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
4669 
4670         let bytes_written = {
4671             let mut writable = &mut buf[..];
4672             leb128::write::unsigned(&mut writable, 4097).expect("should write ok")
4673         };
4674 
4675         let unit = test_parse_attribute_unit_default();
4676         let form = constants::DW_FORM_addrx;
4677         let value = AttributeValue::DebugAddrIndex(DebugAddrIndex(4097));
4678         test_parse_attribute(&buf, bytes_written, &unit, form, value);
4679     }
4680 
4681     #[test]
test_parse_attribute_addrx1()4682     fn test_parse_attribute_addrx1() {
4683         let buf = [0x01, 0x99, 0x99];
4684         let unit = test_parse_attribute_unit(4, Format::Dwarf64, LittleEndian);
4685         let form = constants::DW_FORM_addrx1;
4686         let value = AttributeValue::DebugAddrIndex(DebugAddrIndex(0x01));
4687         test_parse_attribute(&buf, 1, &unit, form, value);
4688     }
4689 
4690     #[test]
test_parse_attribute_addrx2()4691     fn test_parse_attribute_addrx2() {
4692         let buf = [0x01, 0x02, 0x99, 0x99];
4693         let unit = test_parse_attribute_unit(4, Format::Dwarf64, LittleEndian);
4694         let form = constants::DW_FORM_addrx2;
4695         let value = AttributeValue::DebugAddrIndex(DebugAddrIndex(0x0201));
4696         test_parse_attribute(&buf, 2, &unit, form, value);
4697     }
4698 
4699     #[test]
test_parse_attribute_addrx3()4700     fn test_parse_attribute_addrx3() {
4701         let buf = [0x01, 0x02, 0x03, 0x99, 0x99];
4702         let unit = test_parse_attribute_unit(4, Format::Dwarf64, LittleEndian);
4703         let form = constants::DW_FORM_addrx3;
4704         let value = AttributeValue::DebugAddrIndex(DebugAddrIndex(0x03_0201));
4705         test_parse_attribute(&buf, 3, &unit, form, value);
4706     }
4707 
4708     #[test]
test_parse_attribute_addrx4()4709     fn test_parse_attribute_addrx4() {
4710         let buf = [0x01, 0x02, 0x03, 0x04, 0x99, 0x99];
4711         let unit = test_parse_attribute_unit(4, Format::Dwarf64, LittleEndian);
4712         let form = constants::DW_FORM_addrx4;
4713         let value = AttributeValue::DebugAddrIndex(DebugAddrIndex(0x0403_0201));
4714         test_parse_attribute(&buf, 4, &unit, form, value);
4715     }
4716 
4717     #[test]
test_parse_attribute_loclistx()4718     fn test_parse_attribute_loclistx() {
4719         let mut buf = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
4720 
4721         let bytes_written = {
4722             let mut writable = &mut buf[..];
4723             leb128::write::unsigned(&mut writable, 4097).expect("should write ok")
4724         };
4725 
4726         let unit = test_parse_attribute_unit_default();
4727         let form = constants::DW_FORM_loclistx;
4728         let value = AttributeValue::DebugLocListsIndex(DebugLocListsIndex(4097));
4729         test_parse_attribute(&buf, bytes_written, &unit, form, value);
4730     }
4731 
4732     #[test]
test_parse_attribute_rnglistx()4733     fn test_parse_attribute_rnglistx() {
4734         let mut buf = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
4735 
4736         let bytes_written = {
4737             let mut writable = &mut buf[..];
4738             leb128::write::unsigned(&mut writable, 4097).expect("should write ok")
4739         };
4740 
4741         let unit = test_parse_attribute_unit_default();
4742         let form = constants::DW_FORM_rnglistx;
4743         let value = AttributeValue::DebugRngListsIndex(DebugRngListsIndex(4097));
4744         test_parse_attribute(&buf, bytes_written, &unit, form, value);
4745     }
4746 
4747     #[test]
test_parse_attribute_indirect()4748     fn test_parse_attribute_indirect() {
4749         let mut buf = [0; 100];
4750 
4751         let bytes_written = {
4752             let mut writable = &mut buf[..];
4753             leb128::write::unsigned(&mut writable, constants::DW_FORM_udata.0.into())
4754                 .expect("should write udata")
4755                 + leb128::write::unsigned(&mut writable, 9_999_999).expect("should write value")
4756         };
4757 
4758         let unit = test_parse_attribute_unit_default();
4759         let form = constants::DW_FORM_indirect;
4760         let value = AttributeValue::Udata(9_999_999);
4761         test_parse_attribute(&buf, bytes_written, &unit, form, value);
4762     }
4763 
4764     #[test]
test_parse_attribute_indirect_implicit_const()4765     fn test_parse_attribute_indirect_implicit_const() {
4766         let encoding = Encoding {
4767             format: Format::Dwarf32,
4768             version: 4,
4769             address_size: 4,
4770         };
4771         let mut buf = [0; 100];
4772         let mut writable = &mut buf[..];
4773         leb128::write::unsigned(&mut writable, constants::DW_FORM_implicit_const.0.into())
4774             .expect("should write implicit_const");
4775 
4776         let input = &mut EndianSlice::new(&buf, LittleEndian);
4777         let spec =
4778             AttributeSpecification::new(constants::DW_AT_low_pc, constants::DW_FORM_indirect, None);
4779         assert_eq!(
4780             parse_attribute(input, encoding, spec),
4781             Err(Error::InvalidImplicitConst)
4782         );
4783     }
4784 
4785     #[test]
test_attrs_iter()4786     fn test_attrs_iter() {
4787         let encoding = Encoding {
4788             format: Format::Dwarf32,
4789             version: 4,
4790             address_size: 4,
4791         };
4792         let unit = UnitHeader::new(
4793             encoding,
4794             7,
4795             DebugAbbrevOffset(0x0807_0605),
4796             EndianSlice::new(&[], LittleEndian),
4797         );
4798 
4799         let abbrev = Abbreviation::new(
4800             42,
4801             constants::DW_TAG_subprogram,
4802             constants::DW_CHILDREN_yes,
4803             vec![
4804                 AttributeSpecification::new(constants::DW_AT_name, constants::DW_FORM_string, None),
4805                 AttributeSpecification::new(constants::DW_AT_low_pc, constants::DW_FORM_addr, None),
4806                 AttributeSpecification::new(
4807                     constants::DW_AT_high_pc,
4808                     constants::DW_FORM_addr,
4809                     None,
4810                 ),
4811             ]
4812             .into(),
4813         );
4814 
4815         // "foo", 42, 1337, 4 dangling bytes of 0xaa where children would be
4816         let buf = [
4817             0x66, 0x6f, 0x6f, 0x00, 0x2a, 0x00, 0x00, 0x00, 0x39, 0x05, 0x00, 0x00, 0xaa, 0xaa,
4818             0xaa, 0xaa,
4819         ];
4820 
4821         let entry = DebuggingInformationEntry {
4822             offset: UnitOffset(0),
4823             attrs_slice: EndianSlice::new(&buf, LittleEndian),
4824             attrs_len: Cell::new(None),
4825             abbrev: &abbrev,
4826             unit: &unit,
4827         };
4828 
4829         let mut attrs = AttrsIter {
4830             input: EndianSlice::new(&buf, LittleEndian),
4831             attributes: abbrev.attributes(),
4832             entry: &entry,
4833         };
4834 
4835         match attrs.next() {
4836             Ok(Some(attr)) => {
4837                 assert_eq!(
4838                     attr,
4839                     Attribute {
4840                         name: constants::DW_AT_name,
4841                         value: AttributeValue::String(EndianSlice::new(b"foo", LittleEndian)),
4842                     }
4843                 );
4844             }
4845             otherwise => {
4846                 assert!(false, "Unexpected parse result = {:#?}", otherwise);
4847             }
4848         }
4849 
4850         assert!(entry.attrs_len.get().is_none());
4851 
4852         match attrs.next() {
4853             Ok(Some(attr)) => {
4854                 assert_eq!(
4855                     attr,
4856                     Attribute {
4857                         name: constants::DW_AT_low_pc,
4858                         value: AttributeValue::Addr(0x2a),
4859                     }
4860                 );
4861             }
4862             otherwise => {
4863                 assert!(false, "Unexpected parse result = {:#?}", otherwise);
4864             }
4865         }
4866 
4867         assert!(entry.attrs_len.get().is_none());
4868 
4869         match attrs.next() {
4870             Ok(Some(attr)) => {
4871                 assert_eq!(
4872                     attr,
4873                     Attribute {
4874                         name: constants::DW_AT_high_pc,
4875                         value: AttributeValue::Addr(0x539),
4876                     }
4877                 );
4878             }
4879             otherwise => {
4880                 assert!(false, "Unexpected parse result = {:#?}", otherwise);
4881             }
4882         }
4883 
4884         assert!(entry.attrs_len.get().is_none());
4885 
4886         assert!(attrs.next().expect("should parse next").is_none());
4887         assert!(entry.attrs_len.get().is_some());
4888         assert_eq!(
4889             entry.attrs_len.get().expect("should have entry.attrs_len"),
4890             buf.len() - 4
4891         )
4892     }
4893 
4894     #[test]
test_attrs_iter_incomplete()4895     fn test_attrs_iter_incomplete() {
4896         let encoding = Encoding {
4897             format: Format::Dwarf32,
4898             version: 4,
4899             address_size: 4,
4900         };
4901         let unit = UnitHeader::new(
4902             encoding,
4903             7,
4904             DebugAbbrevOffset(0x0807_0605),
4905             EndianSlice::new(&[], LittleEndian),
4906         );
4907 
4908         let abbrev = Abbreviation::new(
4909             42,
4910             constants::DW_TAG_subprogram,
4911             constants::DW_CHILDREN_yes,
4912             vec![
4913                 AttributeSpecification::new(constants::DW_AT_name, constants::DW_FORM_string, None),
4914                 AttributeSpecification::new(constants::DW_AT_low_pc, constants::DW_FORM_addr, None),
4915                 AttributeSpecification::new(
4916                     constants::DW_AT_high_pc,
4917                     constants::DW_FORM_addr,
4918                     None,
4919                 ),
4920             ]
4921             .into(),
4922         );
4923 
4924         // "foo"
4925         let buf = [0x66, 0x6f, 0x6f, 0x00];
4926 
4927         let entry = DebuggingInformationEntry {
4928             offset: UnitOffset(0),
4929             attrs_slice: EndianSlice::new(&buf, LittleEndian),
4930             attrs_len: Cell::new(None),
4931             abbrev: &abbrev,
4932             unit: &unit,
4933         };
4934 
4935         let mut attrs = AttrsIter {
4936             input: EndianSlice::new(&buf, LittleEndian),
4937             attributes: abbrev.attributes(),
4938             entry: &entry,
4939         };
4940 
4941         match attrs.next() {
4942             Ok(Some(attr)) => {
4943                 assert_eq!(
4944                     attr,
4945                     Attribute {
4946                         name: constants::DW_AT_name,
4947                         value: AttributeValue::String(EndianSlice::new(b"foo", LittleEndian)),
4948                     }
4949                 );
4950             }
4951             otherwise => {
4952                 assert!(false, "Unexpected parse result = {:#?}", otherwise);
4953             }
4954         }
4955 
4956         assert!(entry.attrs_len.get().is_none());
4957 
4958         // Return error for incomplete attribute.
4959         assert!(attrs.next().is_err());
4960         assert!(entry.attrs_len.get().is_none());
4961 
4962         // Return error for all subsequent calls.
4963         assert!(attrs.next().is_err());
4964         assert!(attrs.next().is_err());
4965         assert!(attrs.next().is_err());
4966         assert!(attrs.next().is_err());
4967         assert!(entry.attrs_len.get().is_none());
4968     }
4969 
assert_entry_name<Endian>(entry: &DebuggingInformationEntry<EndianSlice<Endian>>, name: &str) where Endian: Endianity,4970     fn assert_entry_name<Endian>(entry: &DebuggingInformationEntry<EndianSlice<Endian>>, name: &str)
4971     where
4972         Endian: Endianity,
4973     {
4974         let value = entry
4975             .attr_value(constants::DW_AT_name)
4976             .expect("Should have parsed the name attribute")
4977             .expect("Should have found the name attribute");
4978 
4979         assert_eq!(
4980             value,
4981             AttributeValue::String(EndianSlice::new(name.as_bytes(), Endian::default()))
4982         );
4983     }
4984 
assert_current_name<Endian>(cursor: &EntriesCursor<EndianSlice<Endian>>, name: &str) where Endian: Endianity,4985     fn assert_current_name<Endian>(cursor: &EntriesCursor<EndianSlice<Endian>>, name: &str)
4986     where
4987         Endian: Endianity,
4988     {
4989         let entry = cursor.current().expect("Should have an entry result");
4990         assert_entry_name(entry, name);
4991     }
4992 
assert_next_entry<Endian>(cursor: &mut EntriesCursor<EndianSlice<Endian>>, name: &str) where Endian: Endianity,4993     fn assert_next_entry<Endian>(cursor: &mut EntriesCursor<EndianSlice<Endian>>, name: &str)
4994     where
4995         Endian: Endianity,
4996     {
4997         cursor
4998             .next_entry()
4999             .expect("Should parse next entry")
5000             .expect("Should have an entry");
5001         assert_current_name(cursor, name);
5002     }
5003 
assert_next_entry_null<Endian>(cursor: &mut EntriesCursor<EndianSlice<Endian>>) where Endian: Endianity,5004     fn assert_next_entry_null<Endian>(cursor: &mut EntriesCursor<EndianSlice<Endian>>)
5005     where
5006         Endian: Endianity,
5007     {
5008         cursor
5009             .next_entry()
5010             .expect("Should parse next entry")
5011             .expect("Should have an entry");
5012         assert!(cursor.current().is_none());
5013     }
5014 
assert_next_dfs<Endian>( cursor: &mut EntriesCursor<EndianSlice<Endian>>, name: &str, depth: isize, ) where Endian: Endianity,5015     fn assert_next_dfs<Endian>(
5016         cursor: &mut EntriesCursor<EndianSlice<Endian>>,
5017         name: &str,
5018         depth: isize,
5019     ) where
5020         Endian: Endianity,
5021     {
5022         {
5023             let (val, entry) = cursor
5024                 .next_dfs()
5025                 .expect("Should parse next dfs")
5026                 .expect("Should not be done with traversal");
5027             assert_eq!(val, depth);
5028             assert_entry_name(entry, name);
5029         }
5030         assert_current_name(cursor, name);
5031     }
5032 
assert_next_sibling<Endian>(cursor: &mut EntriesCursor<EndianSlice<Endian>>, name: &str) where Endian: Endianity,5033     fn assert_next_sibling<Endian>(cursor: &mut EntriesCursor<EndianSlice<Endian>>, name: &str)
5034     where
5035         Endian: Endianity,
5036     {
5037         {
5038             let entry = cursor
5039                 .next_sibling()
5040                 .expect("Should parse next sibling")
5041                 .expect("Should not be done with traversal");
5042             assert_entry_name(entry, name);
5043         }
5044         assert_current_name(cursor, name);
5045     }
5046 
assert_valid_sibling_ptr<Endian>(cursor: &EntriesCursor<EndianSlice<Endian>>) where Endian: Endianity,5047     fn assert_valid_sibling_ptr<Endian>(cursor: &EntriesCursor<EndianSlice<Endian>>)
5048     where
5049         Endian: Endianity,
5050     {
5051         let sibling_ptr = cursor
5052             .current()
5053             .expect("Should have current entry")
5054             .attr_value(constants::DW_AT_sibling);
5055         match sibling_ptr {
5056             Ok(Some(AttributeValue::UnitRef(offset))) => {
5057                 cursor
5058                     .unit
5059                     .range_from(offset..)
5060                     .expect("Sibling offset should be valid");
5061             }
5062             _ => panic!("Invalid sibling pointer {:?}", sibling_ptr),
5063         }
5064     }
5065 
entries_cursor_tests_abbrev_buf() -> Vec<u8>5066     fn entries_cursor_tests_abbrev_buf() -> Vec<u8> {
5067         #[rustfmt::skip]
5068         let section = Section::with_endian(Endian::Little)
5069             .abbrev(1, DW_TAG_subprogram, DW_CHILDREN_yes)
5070                 .abbrev_attr(DW_AT_name, DW_FORM_string)
5071                 .abbrev_attr_null()
5072             .abbrev_null();
5073         section.get_contents().unwrap()
5074     }
5075 
entries_cursor_tests_debug_info_buf() -> Vec<u8>5076     fn entries_cursor_tests_debug_info_buf() -> Vec<u8> {
5077         #[rustfmt::skip]
5078         let section = Section::with_endian(Endian::Little)
5079             .die(1, |s| s.attr_string("001"))
5080                 .die(1, |s| s.attr_string("002"))
5081                     .die(1, |s| s.attr_string("003"))
5082                         .die_null()
5083                     .die_null()
5084                 .die(1, |s| s.attr_string("004"))
5085                     .die(1, |s| s.attr_string("005"))
5086                         .die_null()
5087                     .die(1, |s| s.attr_string("006"))
5088                         .die_null()
5089                     .die_null()
5090                 .die(1, |s| s.attr_string("007"))
5091                     .die(1, |s| s.attr_string("008"))
5092                         .die(1, |s| s.attr_string("009"))
5093                             .die_null()
5094                         .die_null()
5095                     .die_null()
5096                 .die(1, |s| s.attr_string("010"))
5097                     .die_null()
5098                 .die_null();
5099         let entries_buf = section.get_contents().unwrap();
5100 
5101         let encoding = Encoding {
5102             format: Format::Dwarf32,
5103             version: 4,
5104             address_size: 4,
5105         };
5106         let mut unit = CompilationUnitHeader {
5107             header: UnitHeader {
5108                 encoding,
5109                 unit_length: 0,
5110                 debug_abbrev_offset: DebugAbbrevOffset(0),
5111                 entries_buf: EndianSlice::new(&entries_buf, LittleEndian),
5112             },
5113             offset: DebugInfoOffset(0),
5114         };
5115         let section = Section::with_endian(Endian::Little).comp_unit(&mut unit);
5116         section.get_contents().unwrap()
5117     }
5118 
5119     #[test]
test_cursor_next_entry_incomplete()5120     fn test_cursor_next_entry_incomplete() {
5121         #[rustfmt::skip]
5122         let section = Section::with_endian(Endian::Little)
5123             .die(1, |s| s.attr_string("001"))
5124                 .die(1, |s| s.attr_string("002"))
5125                     .die(1, |s| s);
5126         let entries_buf = section.get_contents().unwrap();
5127 
5128         let encoding = Encoding {
5129             format: Format::Dwarf32,
5130             version: 4,
5131             address_size: 4,
5132         };
5133         let mut unit = CompilationUnitHeader {
5134             header: UnitHeader {
5135                 encoding,
5136                 unit_length: 0,
5137                 debug_abbrev_offset: DebugAbbrevOffset(0),
5138                 entries_buf: EndianSlice::new(&entries_buf, LittleEndian),
5139             },
5140             offset: DebugInfoOffset(0),
5141         };
5142         let section = Section::with_endian(Endian::Little).comp_unit(&mut unit);
5143         let info_buf = &section.get_contents().unwrap();
5144         let debug_info = DebugInfo::new(info_buf, LittleEndian);
5145 
5146         let unit = debug_info
5147             .units()
5148             .next()
5149             .expect("should have a unit result")
5150             .expect("and it should be ok");
5151 
5152         let abbrevs_buf = &entries_cursor_tests_abbrev_buf();
5153         let debug_abbrev = DebugAbbrev::new(abbrevs_buf, LittleEndian);
5154 
5155         let abbrevs = unit
5156             .abbreviations(&debug_abbrev)
5157             .expect("Should parse abbreviations");
5158 
5159         let mut cursor = unit.entries(&abbrevs);
5160 
5161         assert_next_entry(&mut cursor, "001");
5162         assert_next_entry(&mut cursor, "002");
5163 
5164         {
5165             // Entry code is present, but none of the attributes.
5166             cursor
5167                 .next_entry()
5168                 .expect("Should parse next entry")
5169                 .expect("Should have an entry");
5170             let entry = cursor.current().expect("Should have an entry result");
5171             assert!(entry.attrs().next().is_err());
5172         }
5173 
5174         assert!(cursor.next_entry().is_err());
5175         assert!(cursor.next_entry().is_err());
5176     }
5177 
5178     #[test]
test_cursor_next_entry()5179     fn test_cursor_next_entry() {
5180         let info_buf = &entries_cursor_tests_debug_info_buf();
5181         let debug_info = DebugInfo::new(info_buf, LittleEndian);
5182 
5183         let unit = debug_info
5184             .units()
5185             .next()
5186             .expect("should have a unit result")
5187             .expect("and it should be ok");
5188 
5189         let abbrevs_buf = &entries_cursor_tests_abbrev_buf();
5190         let debug_abbrev = DebugAbbrev::new(abbrevs_buf, LittleEndian);
5191 
5192         let abbrevs = unit
5193             .abbreviations(&debug_abbrev)
5194             .expect("Should parse abbreviations");
5195 
5196         let mut cursor = unit.entries(&abbrevs);
5197 
5198         assert_next_entry(&mut cursor, "001");
5199         assert_next_entry(&mut cursor, "002");
5200         assert_next_entry(&mut cursor, "003");
5201         assert_next_entry_null(&mut cursor);
5202         assert_next_entry_null(&mut cursor);
5203         assert_next_entry(&mut cursor, "004");
5204         assert_next_entry(&mut cursor, "005");
5205         assert_next_entry_null(&mut cursor);
5206         assert_next_entry(&mut cursor, "006");
5207         assert_next_entry_null(&mut cursor);
5208         assert_next_entry_null(&mut cursor);
5209         assert_next_entry(&mut cursor, "007");
5210         assert_next_entry(&mut cursor, "008");
5211         assert_next_entry(&mut cursor, "009");
5212         assert_next_entry_null(&mut cursor);
5213         assert_next_entry_null(&mut cursor);
5214         assert_next_entry_null(&mut cursor);
5215         assert_next_entry(&mut cursor, "010");
5216         assert_next_entry_null(&mut cursor);
5217         assert_next_entry_null(&mut cursor);
5218 
5219         assert!(cursor
5220             .next_entry()
5221             .expect("Should parse next entry")
5222             .is_none());
5223         assert!(cursor.current().is_none());
5224     }
5225 
5226     #[test]
test_cursor_next_dfs()5227     fn test_cursor_next_dfs() {
5228         let info_buf = &entries_cursor_tests_debug_info_buf();
5229         let debug_info = DebugInfo::new(info_buf, LittleEndian);
5230 
5231         let unit = debug_info
5232             .units()
5233             .next()
5234             .expect("should have a unit result")
5235             .expect("and it should be ok");
5236 
5237         let abbrevs_buf = &entries_cursor_tests_abbrev_buf();
5238         let debug_abbrev = DebugAbbrev::new(abbrevs_buf, LittleEndian);
5239 
5240         let abbrevs = unit
5241             .abbreviations(&debug_abbrev)
5242             .expect("Should parse abbreviations");
5243 
5244         let mut cursor = unit.entries(&abbrevs);
5245 
5246         assert_next_dfs(&mut cursor, "001", 0);
5247         assert_next_dfs(&mut cursor, "002", 1);
5248         assert_next_dfs(&mut cursor, "003", 1);
5249         assert_next_dfs(&mut cursor, "004", -1);
5250         assert_next_dfs(&mut cursor, "005", 1);
5251         assert_next_dfs(&mut cursor, "006", 0);
5252         assert_next_dfs(&mut cursor, "007", -1);
5253         assert_next_dfs(&mut cursor, "008", 1);
5254         assert_next_dfs(&mut cursor, "009", 1);
5255         assert_next_dfs(&mut cursor, "010", -2);
5256 
5257         assert!(cursor.next_dfs().expect("Should parse next dfs").is_none());
5258         assert!(cursor.current().is_none());
5259     }
5260 
5261     #[test]
test_cursor_next_sibling_no_sibling_ptr()5262     fn test_cursor_next_sibling_no_sibling_ptr() {
5263         let info_buf = &entries_cursor_tests_debug_info_buf();
5264         let debug_info = DebugInfo::new(info_buf, LittleEndian);
5265 
5266         let unit = debug_info
5267             .units()
5268             .next()
5269             .expect("should have a unit result")
5270             .expect("and it should be ok");
5271 
5272         let abbrevs_buf = &entries_cursor_tests_abbrev_buf();
5273         let debug_abbrev = DebugAbbrev::new(abbrevs_buf, LittleEndian);
5274 
5275         let abbrevs = unit
5276             .abbreviations(&debug_abbrev)
5277             .expect("Should parse abbreviations");
5278 
5279         let mut cursor = unit.entries(&abbrevs);
5280 
5281         assert_next_dfs(&mut cursor, "001", 0);
5282 
5283         // Down to the first child of the root entry.
5284 
5285         assert_next_dfs(&mut cursor, "002", 1);
5286 
5287         // Now iterate all children of the root via `next_sibling`.
5288 
5289         assert_next_sibling(&mut cursor, "004");
5290         assert_next_sibling(&mut cursor, "007");
5291         assert_next_sibling(&mut cursor, "010");
5292 
5293         // There should be no more siblings.
5294 
5295         assert!(cursor
5296             .next_sibling()
5297             .expect("Should parse next sibling")
5298             .is_none());
5299         assert!(cursor.current().is_none());
5300     }
5301 
5302     #[test]
test_cursor_next_sibling_continuation()5303     fn test_cursor_next_sibling_continuation() {
5304         let info_buf = &entries_cursor_tests_debug_info_buf();
5305         let debug_info = DebugInfo::new(info_buf, LittleEndian);
5306 
5307         let unit = debug_info
5308             .units()
5309             .next()
5310             .expect("should have a unit result")
5311             .expect("and it should be ok");
5312 
5313         let abbrevs_buf = &entries_cursor_tests_abbrev_buf();
5314         let debug_abbrev = DebugAbbrev::new(abbrevs_buf, LittleEndian);
5315 
5316         let abbrevs = unit
5317             .abbreviations(&debug_abbrev)
5318             .expect("Should parse abbreviations");
5319 
5320         let mut cursor = unit.entries(&abbrevs);
5321 
5322         assert_next_dfs(&mut cursor, "001", 0);
5323 
5324         // Down to the first child of the root entry.
5325 
5326         assert_next_dfs(&mut cursor, "002", 1);
5327 
5328         // Get the next sibling, then iterate its children
5329 
5330         assert_next_sibling(&mut cursor, "004");
5331         assert_next_dfs(&mut cursor, "005", 1);
5332         assert_next_sibling(&mut cursor, "006");
5333         assert!(cursor
5334             .next_sibling()
5335             .expect("Should parse next sibling")
5336             .is_none());
5337         assert!(cursor
5338             .next_sibling()
5339             .expect("Should parse next sibling")
5340             .is_none());
5341         assert!(cursor
5342             .next_sibling()
5343             .expect("Should parse next sibling")
5344             .is_none());
5345         assert!(cursor
5346             .next_sibling()
5347             .expect("Should parse next sibling")
5348             .is_none());
5349 
5350         // And we should be able to continue with the children of the root entry.
5351 
5352         assert_next_dfs(&mut cursor, "007", -1);
5353         assert_next_sibling(&mut cursor, "010");
5354 
5355         // There should be no more siblings.
5356 
5357         assert!(cursor
5358             .next_sibling()
5359             .expect("Should parse next sibling")
5360             .is_none());
5361         assert!(cursor.current().is_none());
5362     }
5363 
entries_cursor_sibling_abbrev_buf() -> Vec<u8>5364     fn entries_cursor_sibling_abbrev_buf() -> Vec<u8> {
5365         #[rustfmt::skip]
5366         let section = Section::with_endian(Endian::Little)
5367             .abbrev(1, DW_TAG_subprogram, DW_CHILDREN_yes)
5368                 .abbrev_attr(DW_AT_name, DW_FORM_string)
5369                 .abbrev_attr(DW_AT_sibling, DW_FORM_ref1)
5370                 .abbrev_attr_null()
5371             .abbrev(2, DW_TAG_subprogram, DW_CHILDREN_yes)
5372                 .abbrev_attr(DW_AT_name, DW_FORM_string)
5373                 .abbrev_attr_null()
5374                 .abbrev_null();
5375         section.get_contents().unwrap()
5376     }
5377 
entries_cursor_sibling_entries_buf(header_size: usize) -> Vec<u8>5378     fn entries_cursor_sibling_entries_buf(header_size: usize) -> Vec<u8> {
5379         let start = Label::new();
5380         let sibling004_ref = Label::new();
5381         let sibling004 = Label::new();
5382         let sibling009_ref = Label::new();
5383         let sibling009 = Label::new();
5384 
5385         #[rustfmt::skip]
5386         let section = Section::with_endian(Endian::Little)
5387             .mark(&start)
5388             .die(2, |s| s.attr_string("001"))
5389                 // Valid sibling attribute.
5390                 .die(1, |s| s.attr_string("002").D8(&sibling004_ref))
5391                     // Invalid code to ensure the sibling attribute was used.
5392                     .die(10, |s| s.attr_string("003"))
5393                         .die_null()
5394                     .die_null()
5395                 .mark(&sibling004)
5396                 // Invalid sibling attribute.
5397                 .die(1, |s| s.attr_string("004").attr_ref1(255))
5398                     .die(2, |s| s.attr_string("005"))
5399                         .die_null()
5400                     .die_null()
5401                 // Sibling attribute in child only.
5402                 .die(2, |s| s.attr_string("006"))
5403                     // Valid sibling attribute.
5404                     .die(1, |s| s.attr_string("007").D8(&sibling009_ref))
5405                         // Invalid code to ensure the sibling attribute was used.
5406                         .die(10, |s| s.attr_string("008"))
5407                             .die_null()
5408                         .die_null()
5409                     .mark(&sibling009)
5410                     .die(2, |s| s.attr_string("009"))
5411                         .die_null()
5412                     .die_null()
5413                 // No sibling attribute.
5414                 .die(2, |s| s.attr_string("010"))
5415                     .die(2, |s| s.attr_string("011"))
5416                         .die_null()
5417                     .die_null()
5418                 .die_null();
5419 
5420         let offset = header_size as u64 + (&sibling004 - &start) as u64;
5421         sibling004_ref.set_const(offset);
5422 
5423         let offset = header_size as u64 + (&sibling009 - &start) as u64;
5424         sibling009_ref.set_const(offset);
5425 
5426         section.get_contents().unwrap()
5427     }
5428 
test_cursor_next_sibling_with_ptr(cursor: &mut EntriesCursor<EndianSlice<LittleEndian>>)5429     fn test_cursor_next_sibling_with_ptr(cursor: &mut EntriesCursor<EndianSlice<LittleEndian>>) {
5430         assert_next_dfs(cursor, "001", 0);
5431 
5432         // Down to the first child of the root.
5433 
5434         assert_next_dfs(cursor, "002", 1);
5435 
5436         // Now iterate all children of the root via `next_sibling`.
5437 
5438         assert_valid_sibling_ptr(&cursor);
5439         assert_next_sibling(cursor, "004");
5440         assert_next_sibling(cursor, "006");
5441         assert_next_sibling(cursor, "010");
5442 
5443         // There should be no more siblings.
5444 
5445         assert!(cursor
5446             .next_sibling()
5447             .expect("Should parse next sibling")
5448             .is_none());
5449         assert!(cursor.current().is_none());
5450     }
5451 
5452     #[test]
test_debug_info_next_sibling_with_ptr()5453     fn test_debug_info_next_sibling_with_ptr() {
5454         let encoding = Encoding {
5455             format: Format::Dwarf32,
5456             version: 4,
5457             address_size: 4,
5458         };
5459         let header_size =
5460             CompilationUnitHeader::<EndianSlice<LittleEndian>, _>::size_of_header(encoding);
5461         let entries_buf = entries_cursor_sibling_entries_buf(header_size);
5462 
5463         let mut unit = CompilationUnitHeader {
5464             header: UnitHeader {
5465                 encoding,
5466                 unit_length: 0,
5467                 debug_abbrev_offset: DebugAbbrevOffset(0),
5468                 entries_buf: EndianSlice::new(&entries_buf, LittleEndian),
5469             },
5470             offset: DebugInfoOffset(0),
5471         };
5472         let section = Section::with_endian(Endian::Little).comp_unit(&mut unit);
5473         let info_buf = section.get_contents().unwrap();
5474         let debug_info = DebugInfo::new(&info_buf, LittleEndian);
5475 
5476         let unit = debug_info
5477             .units()
5478             .next()
5479             .expect("should have a unit result")
5480             .expect("and it should be ok");
5481 
5482         let abbrev_buf = entries_cursor_sibling_abbrev_buf();
5483         let debug_abbrev = DebugAbbrev::new(&abbrev_buf, LittleEndian);
5484 
5485         let abbrevs = unit
5486             .abbreviations(&debug_abbrev)
5487             .expect("Should parse abbreviations");
5488 
5489         let mut cursor = unit.entries(&abbrevs);
5490         test_cursor_next_sibling_with_ptr(&mut cursor);
5491     }
5492 
5493     #[test]
test_debug_types_next_sibling_with_ptr()5494     fn test_debug_types_next_sibling_with_ptr() {
5495         let encoding = Encoding {
5496             format: Format::Dwarf32,
5497             version: 4,
5498             address_size: 4,
5499         };
5500         let header_size = TypeUnitHeader::<EndianSlice<LittleEndian>, _>::size_of_header(encoding);
5501         let entries_buf = entries_cursor_sibling_entries_buf(header_size);
5502 
5503         let mut unit = TypeUnitHeader {
5504             header: UnitHeader {
5505                 encoding,
5506                 unit_length: 0,
5507                 debug_abbrev_offset: DebugAbbrevOffset(0),
5508                 entries_buf: EndianSlice::new(&entries_buf, LittleEndian),
5509             },
5510             type_signature: DebugTypeSignature(0),
5511             type_offset: UnitOffset(0),
5512             offset: DebugTypesOffset(0),
5513         };
5514         let section = Section::with_endian(Endian::Little).type_unit(&mut unit);
5515         let info_buf = section.get_contents().unwrap();
5516         let debug_types = DebugTypes::new(&info_buf, LittleEndian);
5517 
5518         let unit = debug_types
5519             .units()
5520             .next()
5521             .expect("should have a unit result")
5522             .expect("and it should be ok");
5523 
5524         let abbrev_buf = entries_cursor_sibling_abbrev_buf();
5525         let debug_abbrev = DebugAbbrev::new(&abbrev_buf, LittleEndian);
5526 
5527         let abbrevs = unit
5528             .abbreviations(&debug_abbrev)
5529             .expect("Should parse abbreviations");
5530 
5531         let mut cursor = unit.entries(&abbrevs);
5532         test_cursor_next_sibling_with_ptr(&mut cursor);
5533     }
5534 
5535     #[test]
test_entries_at_offset()5536     fn test_entries_at_offset() {
5537         let info_buf = &entries_cursor_tests_debug_info_buf();
5538         let debug_info = DebugInfo::new(info_buf, LittleEndian);
5539 
5540         let unit = debug_info
5541             .units()
5542             .next()
5543             .expect("should have a unit result")
5544             .expect("and it should be ok");
5545 
5546         let abbrevs_buf = &entries_cursor_tests_abbrev_buf();
5547         let debug_abbrev = DebugAbbrev::new(abbrevs_buf, LittleEndian);
5548 
5549         let abbrevs = unit
5550             .abbreviations(&debug_abbrev)
5551             .expect("Should parse abbreviations");
5552 
5553         let mut cursor = unit
5554             .entries_at_offset(&abbrevs, UnitOffset(unit.header_size()))
5555             .unwrap();
5556         assert_next_entry(&mut cursor, "001");
5557 
5558         let cursor = unit.entries_at_offset(&abbrevs, UnitOffset(0));
5559         match cursor {
5560             Err(Error::OffsetOutOfBounds) => {}
5561             otherwise => {
5562                 assert!(false, "Unexpected parse result = {:#?}", otherwise);
5563             }
5564         }
5565     }
5566 
entries_tree_tests_debug_abbrevs_buf() -> Vec<u8>5567     fn entries_tree_tests_debug_abbrevs_buf() -> Vec<u8> {
5568         #[rustfmt::skip]
5569         let section = Section::with_endian(Endian::Little)
5570             .abbrev(1, DW_TAG_subprogram, DW_CHILDREN_yes)
5571                 .abbrev_attr(DW_AT_name, DW_FORM_string)
5572                 .abbrev_attr_null()
5573             .abbrev(2, DW_TAG_subprogram, DW_CHILDREN_no)
5574                 .abbrev_attr(DW_AT_name, DW_FORM_string)
5575                 .abbrev_attr_null()
5576             .abbrev_null()
5577             .get_contents()
5578             .unwrap();
5579         section
5580     }
5581 
entries_tree_tests_debug_info_buf(header_size: usize) -> (Vec<u8>, UnitOffset)5582     fn entries_tree_tests_debug_info_buf(header_size: usize) -> (Vec<u8>, UnitOffset) {
5583         let start = Label::new();
5584         let entry2 = Label::new();
5585         #[rustfmt::skip]
5586         let section = Section::with_endian(Endian::Little)
5587             .mark(&start)
5588             .die(1, |s| s.attr_string("root"))
5589                 .die(1, |s| s.attr_string("1"))
5590                     .die(1, |s| s.attr_string("1a"))
5591                         .die_null()
5592                     .die(2, |s| s.attr_string("1b"))
5593                     .die_null()
5594                 .mark(&entry2)
5595                 .die(1, |s| s.attr_string("2"))
5596                     .die(1, |s| s.attr_string("2a"))
5597                         .die(1, |s| s.attr_string("2a1"))
5598                             .die_null()
5599                         .die_null()
5600                     .die(1, |s| s.attr_string("2b"))
5601                         .die(2, |s| s.attr_string("2b1"))
5602                         .die_null()
5603                     .die_null()
5604                 .die(1, |s| s.attr_string("3"))
5605                     .die(1, |s| s.attr_string("3a"))
5606                         .die(2, |s| s.attr_string("3a1"))
5607                         .die(2, |s| s.attr_string("3a2"))
5608                         .die_null()
5609                     .die(2, |s| s.attr_string("3b"))
5610                     .die_null()
5611                 .die(2, |s| s.attr_string("final"))
5612                 .die_null()
5613             .get_contents()
5614             .unwrap();
5615         let entry2 = UnitOffset(header_size + (&entry2 - &start) as usize);
5616         (section, entry2)
5617     }
5618 
5619     #[test]
test_entries_tree()5620     fn test_entries_tree() {
5621         fn assert_entry<'input, 'abbrev, 'unit, 'tree, Endian>(
5622             node: Result<
5623                 Option<EntriesTreeNode<'abbrev, 'unit, 'tree, EndianSlice<'input, Endian>>>,
5624             >,
5625             name: &str,
5626         ) -> EntriesTreeIter<'abbrev, 'unit, 'tree, EndianSlice<'input, Endian>>
5627         where
5628             Endian: Endianity,
5629         {
5630             let node = node
5631                 .expect("Should parse entry")
5632                 .expect("Should have entry");
5633             assert_entry_name(node.entry(), name);
5634             node.children()
5635         }
5636 
5637         fn assert_null<E: Endianity>(node: Result<Option<EntriesTreeNode<EndianSlice<E>>>>) {
5638             match node {
5639                 Ok(None) => {}
5640                 otherwise => {
5641                     assert!(false, "Unexpected parse result = {:#?}", otherwise);
5642                 }
5643             }
5644         }
5645 
5646         let abbrevs_buf = entries_tree_tests_debug_abbrevs_buf();
5647         let debug_abbrev = DebugAbbrev::new(&abbrevs_buf, LittleEndian);
5648 
5649         let encoding = Encoding {
5650             format: Format::Dwarf32,
5651             version: 4,
5652             address_size: 4,
5653         };
5654         let header_size =
5655             CompilationUnitHeader::<EndianSlice<LittleEndian>, _>::size_of_header(encoding);
5656         let (entries_buf, entry2) = entries_tree_tests_debug_info_buf(header_size);
5657         let mut unit = CompilationUnitHeader {
5658             header: UnitHeader {
5659                 encoding,
5660                 unit_length: 0,
5661                 debug_abbrev_offset: DebugAbbrevOffset(0),
5662                 entries_buf: EndianSlice::new(&entries_buf, LittleEndian),
5663             },
5664             offset: DebugInfoOffset(0),
5665         };
5666         let info_buf = Section::with_endian(Endian::Little)
5667             .comp_unit(&mut unit)
5668             .get_contents()
5669             .unwrap();
5670         let debug_info = DebugInfo::new(&info_buf, LittleEndian);
5671 
5672         let unit = debug_info
5673             .units()
5674             .next()
5675             .expect("Should parse unit")
5676             .expect("and it should be some");
5677         let abbrevs = unit
5678             .abbreviations(&debug_abbrev)
5679             .expect("Should parse abbreviations");
5680         let mut tree = unit
5681             .entries_tree(&abbrevs, None)
5682             .expect("Should have entries tree");
5683 
5684         // Test we can restart iteration of the tree.
5685         {
5686             let mut iter = assert_entry(tree.root().map(Some), "root");
5687             assert_entry(iter.next(), "1");
5688         }
5689         {
5690             let mut iter = assert_entry(tree.root().map(Some), "root");
5691             assert_entry(iter.next(), "1");
5692         }
5693 
5694         let mut iter = assert_entry(tree.root().map(Some), "root");
5695         {
5696             // Test iteration with children.
5697             let mut iter = assert_entry(iter.next(), "1");
5698             {
5699                 // Test iteration with children flag, but no children.
5700                 let mut iter = assert_entry(iter.next(), "1a");
5701                 assert_null(iter.next());
5702                 assert_null(iter.next());
5703             }
5704             {
5705                 // Test iteration without children flag.
5706                 let mut iter = assert_entry(iter.next(), "1b");
5707                 assert_null(iter.next());
5708                 assert_null(iter.next());
5709             }
5710             assert_null(iter.next());
5711             assert_null(iter.next());
5712         }
5713         {
5714             // Test skipping over children.
5715             let mut iter = assert_entry(iter.next(), "2");
5716             assert_entry(iter.next(), "2a");
5717             assert_entry(iter.next(), "2b");
5718             assert_null(iter.next());
5719         }
5720         {
5721             // Test skipping after partial iteration.
5722             let mut iter = assert_entry(iter.next(), "3");
5723             {
5724                 let mut iter = assert_entry(iter.next(), "3a");
5725                 assert_entry(iter.next(), "3a1");
5726                 // Parent iter should be able to skip over "3a2".
5727             }
5728             assert_entry(iter.next(), "3b");
5729             assert_null(iter.next());
5730         }
5731         assert_entry(iter.next(), "final");
5732         assert_null(iter.next());
5733 
5734         // Test starting at an offset.
5735         let mut tree = unit
5736             .entries_tree(&abbrevs, Some(entry2))
5737             .expect("Should have entries tree");
5738         let mut iter = assert_entry(tree.root().map(Some), "2");
5739         assert_entry(iter.next(), "2a");
5740         assert_entry(iter.next(), "2b");
5741         assert_null(iter.next());
5742     }
5743 
5744     #[test]
test_entries_raw()5745     fn test_entries_raw() {
5746         fn assert_abbrev<'input, 'abbrev, 'unit, Endian>(
5747             entries: &mut EntriesRaw<'abbrev, 'unit, EndianSlice<'input, Endian>>,
5748             tag: DwTag,
5749         ) -> &'abbrev Abbreviation
5750         where
5751             Endian: Endianity,
5752         {
5753             let abbrev = entries
5754                 .read_abbreviation()
5755                 .expect("Should parse abbrev")
5756                 .expect("Should have abbrev");
5757             assert_eq!(abbrev.tag(), tag);
5758             abbrev
5759         }
5760 
5761         fn assert_null<'input, 'abbrev, 'unit, Endian>(
5762             entries: &mut EntriesRaw<'abbrev, 'unit, EndianSlice<'input, Endian>>,
5763         ) where
5764             Endian: Endianity,
5765         {
5766             match entries.read_abbreviation() {
5767                 Ok(None) => {}
5768                 otherwise => {
5769                     assert!(false, "Unexpected parse result = {:#?}", otherwise);
5770                 }
5771             }
5772         }
5773 
5774         fn assert_attr<'input, 'abbrev, 'unit, Endian>(
5775             entries: &mut EntriesRaw<'abbrev, 'unit, EndianSlice<'input, Endian>>,
5776             spec: Option<AttributeSpecification>,
5777             name: DwAt,
5778             value: &str,
5779         ) where
5780             Endian: Endianity,
5781         {
5782             let spec = spec.expect("Should have attribute specification");
5783             let attr = entries
5784                 .read_attribute(spec)
5785                 .expect("Should parse attribute");
5786             assert_eq!(attr.name(), name);
5787             assert_eq!(
5788                 attr.value(),
5789                 AttributeValue::String(EndianSlice::new(value.as_bytes(), Endian::default()))
5790             );
5791         }
5792 
5793         #[rustfmt::skip]
5794         let section = Section::with_endian(Endian::Little)
5795             .abbrev(1, DW_TAG_subprogram, DW_CHILDREN_yes)
5796                 .abbrev_attr(DW_AT_name, DW_FORM_string)
5797                 .abbrev_attr(DW_AT_linkage_name, DW_FORM_string)
5798                 .abbrev_attr_null()
5799             .abbrev(2, DW_TAG_variable, DW_CHILDREN_no)
5800                 .abbrev_attr(DW_AT_name, DW_FORM_string)
5801                 .abbrev_attr_null()
5802             .abbrev_null();
5803         let abbrevs_buf = section.get_contents().unwrap();
5804         let debug_abbrev = DebugAbbrev::new(&abbrevs_buf, LittleEndian);
5805 
5806         #[rustfmt::skip]
5807         let section = Section::with_endian(Endian::Little)
5808             .die(1, |s| s.attr_string("f1").attr_string("l1"))
5809                 .die(2, |s| s.attr_string("v1"))
5810                 .die(2, |s| s.attr_string("v2"))
5811                 .die(1, |s| s.attr_string("f2").attr_string("l2"))
5812                     .die_null()
5813                 .die_null();
5814         let entries_buf = section.get_contents().unwrap();
5815 
5816         let encoding = Encoding {
5817             format: Format::Dwarf32,
5818             version: 4,
5819             address_size: 4,
5820         };
5821         let mut unit = CompilationUnitHeader {
5822             header: UnitHeader {
5823                 encoding,
5824                 unit_length: 0,
5825                 debug_abbrev_offset: DebugAbbrevOffset(0),
5826                 entries_buf: EndianSlice::new(&entries_buf, LittleEndian),
5827             },
5828             offset: DebugInfoOffset(0),
5829         };
5830         let section = Section::with_endian(Endian::Little).comp_unit(&mut unit);
5831         let info_buf = section.get_contents().unwrap();
5832         let debug_info = DebugInfo::new(&info_buf, LittleEndian);
5833 
5834         let unit = debug_info
5835             .units()
5836             .next()
5837             .expect("should have a unit result")
5838             .expect("and it should be ok");
5839 
5840         let abbrevs = unit
5841             .abbreviations(&debug_abbrev)
5842             .expect("Should parse abbreviations");
5843 
5844         let mut entries = unit
5845             .entries_raw(&abbrevs, None)
5846             .expect("Should have entries");
5847 
5848         assert_eq!(entries.next_depth(), 0);
5849         let abbrev = assert_abbrev(&mut entries, DW_TAG_subprogram);
5850         let mut attrs = abbrev.attributes().iter().copied();
5851         assert_attr(&mut entries, attrs.next(), DW_AT_name, "f1");
5852         assert_attr(&mut entries, attrs.next(), DW_AT_linkage_name, "l1");
5853         assert!(attrs.next().is_none());
5854 
5855         assert_eq!(entries.next_depth(), 1);
5856         let abbrev = assert_abbrev(&mut entries, DW_TAG_variable);
5857         let mut attrs = abbrev.attributes().iter().copied();
5858         assert_attr(&mut entries, attrs.next(), DW_AT_name, "v1");
5859         assert!(attrs.next().is_none());
5860 
5861         assert_eq!(entries.next_depth(), 1);
5862         let abbrev = assert_abbrev(&mut entries, DW_TAG_variable);
5863         let mut attrs = abbrev.attributes().iter().copied();
5864         assert_attr(&mut entries, attrs.next(), DW_AT_name, "v2");
5865         assert!(attrs.next().is_none());
5866 
5867         assert_eq!(entries.next_depth(), 1);
5868         let abbrev = assert_abbrev(&mut entries, DW_TAG_subprogram);
5869         let mut attrs = abbrev.attributes().iter().copied();
5870         assert_attr(&mut entries, attrs.next(), DW_AT_name, "f2");
5871         assert_attr(&mut entries, attrs.next(), DW_AT_linkage_name, "l2");
5872         assert!(attrs.next().is_none());
5873 
5874         assert_eq!(entries.next_depth(), 2);
5875         assert_null(&mut entries);
5876 
5877         assert_eq!(entries.next_depth(), 1);
5878         assert_null(&mut entries);
5879 
5880         assert_eq!(entries.next_depth(), 0);
5881         assert!(entries.is_empty());
5882     }
5883 
5884     #[test]
test_debug_info_offset()5885     fn test_debug_info_offset() {
5886         let padding = &[0; 10];
5887         let entries = &[0; 20];
5888         let encoding = Encoding {
5889             format: Format::Dwarf32,
5890             version: 4,
5891             address_size: 4,
5892         };
5893         let mut unit = CompilationUnitHeader {
5894             header: UnitHeader {
5895                 encoding,
5896                 unit_length: 0,
5897                 debug_abbrev_offset: DebugAbbrevOffset(0),
5898                 entries_buf: EndianSlice::new(entries, LittleEndian),
5899             },
5900             offset: DebugInfoOffset(0),
5901         };
5902         Section::with_endian(Endian::Little)
5903             .append_bytes(padding)
5904             .comp_unit(&mut unit);
5905         let offset = padding.len();
5906         let header_length =
5907             CompilationUnitHeader::<EndianSlice<LittleEndian>, _>::size_of_header(encoding);
5908         let length = unit.length_including_self();
5909         assert_eq!(DebugInfoOffset(0).to_unit_offset(&unit), None);
5910         assert_eq!(DebugInfoOffset(offset - 1).to_unit_offset(&unit), None);
5911         assert_eq!(DebugInfoOffset(offset).to_unit_offset(&unit), None);
5912         assert_eq!(
5913             DebugInfoOffset(offset + header_length - 1).to_unit_offset(&unit),
5914             None
5915         );
5916         assert_eq!(
5917             DebugInfoOffset(offset + header_length).to_unit_offset(&unit),
5918             Some(UnitOffset(header_length))
5919         );
5920         assert_eq!(
5921             DebugInfoOffset(offset + length - 1).to_unit_offset(&unit),
5922             Some(UnitOffset(length - 1))
5923         );
5924         assert_eq!(DebugInfoOffset(offset + length).to_unit_offset(&unit), None);
5925         assert_eq!(
5926             UnitOffset(header_length).to_debug_info_offset(&unit),
5927             DebugInfoOffset(offset + header_length)
5928         );
5929         assert_eq!(
5930             UnitOffset(length - 1).to_debug_info_offset(&unit),
5931             DebugInfoOffset(offset + length - 1)
5932         );
5933     }
5934 
5935     #[test]
test_debug_types_offset()5936     fn test_debug_types_offset() {
5937         let padding = &[0; 10];
5938         let entries = &[0; 20];
5939         let encoding = Encoding {
5940             format: Format::Dwarf32,
5941             version: 4,
5942             address_size: 4,
5943         };
5944         let mut unit = TypeUnitHeader {
5945             header: UnitHeader {
5946                 encoding,
5947                 unit_length: 0,
5948                 debug_abbrev_offset: DebugAbbrevOffset(0),
5949                 entries_buf: EndianSlice::new(entries, LittleEndian),
5950             },
5951             type_signature: DebugTypeSignature(0),
5952             type_offset: UnitOffset(0),
5953             offset: DebugTypesOffset(0),
5954         };
5955         Section::with_endian(Endian::Little)
5956             .append_bytes(padding)
5957             .type_unit(&mut unit);
5958         let offset = padding.len();
5959         let header_length =
5960             TypeUnitHeader::<EndianSlice<LittleEndian>, _>::size_of_header(encoding);
5961         let length = unit.length_including_self();
5962         assert_eq!(DebugTypesOffset(0).to_unit_offset(&unit), None);
5963         assert_eq!(DebugTypesOffset(offset - 1).to_unit_offset(&unit), None);
5964         assert_eq!(DebugTypesOffset(offset).to_unit_offset(&unit), None);
5965         assert_eq!(
5966             DebugTypesOffset(offset + header_length - 1).to_unit_offset(&unit),
5967             None
5968         );
5969         assert_eq!(
5970             DebugTypesOffset(offset + header_length).to_unit_offset(&unit),
5971             Some(UnitOffset(header_length))
5972         );
5973         assert_eq!(
5974             DebugTypesOffset(offset + length - 1).to_unit_offset(&unit),
5975             Some(UnitOffset(length - 1))
5976         );
5977         assert_eq!(
5978             DebugTypesOffset(offset + length).to_unit_offset(&unit),
5979             None
5980         );
5981         assert_eq!(
5982             UnitOffset(header_length).to_debug_types_offset(&unit),
5983             DebugTypesOffset(offset + header_length)
5984         );
5985         assert_eq!(
5986             UnitOffset(length - 1).to_debug_types_offset(&unit),
5987             DebugTypesOffset(offset + length - 1)
5988         );
5989     }
5990 
5991     #[test]
test_length_including_self()5992     fn test_length_including_self() {
5993         let encoding = Encoding {
5994             format: Format::Dwarf32,
5995             version: 4,
5996             address_size: 4,
5997         };
5998         let mut unit = UnitHeader {
5999             encoding,
6000             unit_length: 0,
6001             debug_abbrev_offset: DebugAbbrevOffset(0),
6002             entries_buf: EndianSlice::new(&[], LittleEndian),
6003         };
6004         unit.encoding.format = Format::Dwarf32;
6005         assert_eq!(unit.length_including_self(), 4);
6006         unit.encoding.format = Format::Dwarf64;
6007         assert_eq!(unit.length_including_self(), 12);
6008         unit.unit_length = 10;
6009         assert_eq!(unit.length_including_self(), 22);
6010     }
6011 }
6012