Skip to main content

gimli/read/
aranges.rs

1use crate::common::{DebugArangesOffset, DebugInfoOffset, Encoding, SectionId};
2use crate::endianity::Endianity;
3use crate::read::{
4    EndianSlice, Error, Range, Reader, ReaderAddress, ReaderOffset, Result, Section,
5};
6
7/// The `DebugAranges` struct represents the DWARF address range information
8/// found in the `.debug_aranges` section.
9#[derive(Debug, Default, Clone, Copy)]
10pub struct DebugAranges<R> {
11    section: R,
12}
13
14impl<'input, Endian> DebugAranges<EndianSlice<'input, Endian>>
15where
16    Endian: Endianity,
17{
18    /// Construct a new `DebugAranges` instance from the data in the `.debug_aranges`
19    /// section.
20    ///
21    /// It is the caller's responsibility to read the `.debug_aranges` section and
22    /// present it as a `&[u8]` slice. That means using some ELF loader on
23    /// Linux, a Mach-O loader on macOS, etc.
24    ///
25    /// ```
26    /// use gimli::{DebugAranges, LittleEndian};
27    ///
28    /// # let buf = [];
29    /// # let read_debug_aranges_section = || &buf;
30    /// let debug_aranges =
31    ///     DebugAranges::new(read_debug_aranges_section(), LittleEndian);
32    /// ```
33    pub fn new(section: &'input [u8], endian: Endian) -> Self {
34        DebugAranges {
35            section: EndianSlice::new(section, endian),
36        }
37    }
38}
39
40impl<R: Reader> DebugAranges<R> {
41    /// Iterate the sets of entries in the `.debug_aranges` section.
42    ///
43    /// Each set of entries belongs to a single unit.
44    pub fn headers(&self) -> ArangeHeaderIter<R> {
45        ArangeHeaderIter {
46            input: self.section.clone(),
47            offset: DebugArangesOffset(R::Offset::from_u8(0)),
48        }
49    }
50
51    /// Get the header at the given offset.
52    pub fn header(&self, offset: DebugArangesOffset<R::Offset>) -> Result<ArangeHeader<R>> {
53        let mut input = self.section.clone();
54        input.skip(offset.0)?;
55        ArangeHeader::parse(&mut input, offset)
56    }
57}
58
59impl<T> DebugAranges<T> {
60    /// Create a `DebugAranges` section that references the data in `self`.
61    ///
62    /// This is useful when `R` implements `Reader` but `T` does not.
63    ///
64    /// Used by `DwarfSections::borrow`.
65    pub fn borrow<'a, F, R>(&'a self, mut borrow: F) -> DebugAranges<R>
66    where
67        F: FnMut(&'a T) -> R,
68    {
69        borrow(&self.section).into()
70    }
71}
72
73impl<R> Section<R> for DebugAranges<R> {
74    fn id() -> SectionId {
75        SectionId::DebugAranges
76    }
77
78    fn reader(&self) -> &R {
79        &self.section
80    }
81}
82
83impl<R> From<R> for DebugAranges<R> {
84    fn from(section: R) -> Self {
85        DebugAranges { section }
86    }
87}
88
89/// An iterator over the headers of a `.debug_aranges` section.
90#[derive(Clone, Debug)]
91pub struct ArangeHeaderIter<R: Reader> {
92    input: R,
93    offset: DebugArangesOffset<R::Offset>,
94}
95
96impl<R: Reader> ArangeHeaderIter<R> {
97    /// Advance the iterator to the next header.
98    pub fn next(&mut self) -> Result<Option<ArangeHeader<R>>> {
99        if self.input.is_empty() {
100            return Ok(None);
101        }
102
103        let len = self.input.len();
104        match ArangeHeader::parse(&mut self.input, self.offset) {
105            Ok(header) => {
106                self.offset.0 += len - self.input.len();
107                Ok(Some(header))
108            }
109            Err(e) => {
110                self.input.empty();
111                Err(e)
112            }
113        }
114    }
115}
116
117#[cfg(feature = "fallible-iterator")]
118impl<R: Reader> fallible_iterator::FallibleIterator for ArangeHeaderIter<R> {
119    type Item = ArangeHeader<R>;
120    type Error = Error;
121
122    fn next(&mut self) -> ::core::result::Result<Option<Self::Item>, Self::Error> {
123        ArangeHeaderIter::next(self)
124    }
125}
126
127impl<R: Reader> Iterator for ArangeHeaderIter<R> {
128    type Item = Result<ArangeHeader<R>>;
129
130    fn next(&mut self) -> Option<Self::Item> {
131        ArangeHeaderIter::next(self).transpose()
132    }
133}
134
135/// A header for a set of entries in the `.debug_arange` section.
136///
137/// These entries all belong to a single unit.
138#[derive(Debug, Clone, PartialEq, Eq)]
139pub struct ArangeHeader<R, Offset = <R as Reader>::Offset>
140where
141    R: Reader<Offset = Offset>,
142    Offset: ReaderOffset,
143{
144    offset: DebugArangesOffset<Offset>,
145    encoding: Encoding,
146    length: Offset,
147    debug_info_offset: DebugInfoOffset<Offset>,
148    entries: R,
149}
150
151impl<R, Offset> ArangeHeader<R, Offset>
152where
153    R: Reader<Offset = Offset>,
154    Offset: ReaderOffset,
155{
156    fn parse(input: &mut R, offset: DebugArangesOffset<Offset>) -> Result<Self> {
157        let (length, format) = input.read_initial_length()?;
158        let mut rest = input.split(length)?;
159
160        // Check the version. The DWARF 5 spec says that this is always 2, but version 3
161        // has been observed in the wild, potentially due to a bug; see
162        // https://github.com/gimli-rs/gimli/issues/559 for more information.
163        // lldb allows versions 2 through 5, possibly by mistake.
164        let version = rest.read_u16()?;
165        if version != 2 && version != 3 {
166            return Err(Error::UnknownVersion(u64::from(version)));
167        }
168
169        let debug_info_offset = rest.read_offset(format).map(DebugInfoOffset)?;
170        let address_size = rest.read_address_size()?;
171        let segment_size = rest.read_u8()?;
172        if segment_size != 0 {
173            return Err(Error::UnsupportedSegmentSize(segment_size));
174        }
175
176        // unit_length + version + offset + address_size + segment_size
177        let header_length = format.initial_length_size() + 2 + format.word_size() + 1 + 1;
178
179        // The first tuple following the header in each set begins at an offset that is
180        // a multiple of the size of a single tuple (that is, twice the size of an address).
181        let tuple_length = address_size
182            .checked_mul(2)
183            .ok_or(Error::UnsupportedAddressSize(address_size))?;
184        if tuple_length == 0 {
185            return Err(Error::UnsupportedAddressSize(address_size));
186        }
187        let padding = if header_length % tuple_length == 0 {
188            0
189        } else {
190            tuple_length - header_length % tuple_length
191        };
192        rest.skip(R::Offset::from_u8(padding))?;
193
194        let encoding = Encoding {
195            format,
196            version,
197            address_size,
198        };
199        Ok(ArangeHeader {
200            offset,
201            encoding,
202            length,
203            debug_info_offset,
204            entries: rest,
205        })
206    }
207
208    /// Return the offset of this header within the `.debug_aranges` section.
209    #[inline]
210    pub fn offset(&self) -> DebugArangesOffset<Offset> {
211        self.offset
212    }
213
214    /// Return the length of this set of entries, including the header.
215    #[inline]
216    pub fn length(&self) -> Offset {
217        self.length
218    }
219
220    /// Return the encoding parameters for this set of entries.
221    #[inline]
222    pub fn encoding(&self) -> Encoding {
223        self.encoding
224    }
225
226    /// Return the offset into the .debug_info section for this set of arange entries.
227    #[inline]
228    pub fn debug_info_offset(&self) -> DebugInfoOffset<Offset> {
229        self.debug_info_offset
230    }
231
232    /// Return the arange entries in this set.
233    #[inline]
234    pub fn entries(&self) -> ArangeEntryIter<R> {
235        ArangeEntryIter {
236            input: self.entries.clone(),
237            encoding: self.encoding,
238        }
239    }
240}
241
242/// An iterator over the aranges from a `.debug_aranges` section.
243#[derive(Debug, Clone)]
244pub struct ArangeEntryIter<R: Reader> {
245    input: R,
246    encoding: Encoding,
247}
248
249impl<R: Reader> ArangeEntryIter<R> {
250    /// Advance the iterator and return the next arange.
251    ///
252    /// Returns the newly parsed arange as `Ok(Some(arange))`. Returns `Ok(None)`
253    /// when iteration is complete and all aranges have already been parsed and
254    /// yielded. If an error occurs while parsing the next arange, then this error
255    /// is returned as `Err(e)`, and all subsequent calls return `Ok(None)`.
256    pub fn next(&mut self) -> Result<Option<ArangeEntry>> {
257        loop {
258            let raw_entry = match self.next_raw()? {
259                Some(entry) => entry,
260                None => return Ok(None),
261            };
262
263            let entry = self.convert_raw(raw_entry)?;
264            if entry.is_some() {
265                return Ok(entry);
266            }
267        }
268    }
269
270    /// Advance the iterator and return the next arange without validating it.
271    ///
272    /// The returned entry will have `range.end` set to 0.
273    /// This will return tombstone entries as well.
274    pub fn next_raw(&mut self) -> Result<Option<ArangeEntry>> {
275        if self.input.is_empty() {
276            return Ok(None);
277        }
278
279        match ArangeEntry::parse(&mut self.input, self.encoding) {
280            Ok(Some(entry)) => Ok(Some(entry)),
281            Ok(None) => {
282                self.input.empty();
283                Ok(None)
284            }
285            Err(e) => {
286                self.input.empty();
287                Err(e)
288            }
289        }
290    }
291
292    /// Convert a raw range into a range.
293    ///
294    /// The raw range should have been obtained from `next_raw`.
295    #[doc(hidden)]
296    pub fn convert_raw(&self, mut entry: ArangeEntry) -> Result<Option<ArangeEntry>> {
297        // Skip negative tombstone entries.
298        // Callers must handle tombstones of 0 or greater themselves
299        // because we have no way of knowing if they are valid or not.
300        let address_size = self.encoding.address_size;
301        if entry.range.begin >= u64::min_tombstone(address_size) {
302            return Ok(None);
303        }
304
305        // Calculate end now so that we can handle overflow.
306        entry.range.end = entry.range.begin.add_sized(entry.length, address_size)?;
307        Ok(Some(entry))
308    }
309}
310
311#[cfg(feature = "fallible-iterator")]
312impl<R: Reader> fallible_iterator::FallibleIterator for ArangeEntryIter<R> {
313    type Item = ArangeEntry;
314    type Error = Error;
315
316    fn next(&mut self) -> ::core::result::Result<Option<Self::Item>, Self::Error> {
317        ArangeEntryIter::next(self)
318    }
319}
320
321impl<R: Reader> Iterator for ArangeEntryIter<R> {
322    type Item = Result<ArangeEntry>;
323
324    fn next(&mut self) -> Option<Self::Item> {
325        ArangeEntryIter::next(self).transpose()
326    }
327}
328
329/// A single parsed arange.
330#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)]
331pub struct ArangeEntry {
332    range: Range,
333    length: u64,
334}
335
336impl ArangeEntry {
337    /// Parse a single arange. Return `None` for the null arange, `Some` for an actual arange.
338    fn parse<R: Reader>(input: &mut R, encoding: Encoding) -> Result<Option<Self>> {
339        let address_size = encoding.address_size;
340
341        let tuple_length = R::Offset::from_u8(2 * address_size);
342        if tuple_length > input.len() {
343            input.empty();
344            return Ok(None);
345        }
346
347        let begin = input.read_address(address_size)?;
348        let length = input.read_address(address_size)?;
349        let range = Range { begin, end: 0 };
350
351        match (begin, length) {
352            // This is meant to be a null terminator, but in practice it can occur
353            // before the end, possibly due to a linker omitting a function and
354            // leaving an unrelocated entry.
355            (0, 0) => Self::parse(input, encoding),
356            _ => Ok(Some(ArangeEntry { range, length })),
357        }
358    }
359
360    /// Return the beginning address of this arange.
361    #[inline]
362    pub fn address(&self) -> u64 {
363        self.range.begin
364    }
365
366    /// Return the length of this arange.
367    #[inline]
368    pub fn length(&self) -> u64 {
369        self.length
370    }
371
372    /// Return the range.
373    #[inline]
374    pub fn range(&self) -> Range {
375        self.range
376    }
377}
378
379#[cfg(test)]
380mod tests {
381    use super::*;
382    use crate::common::{DebugInfoOffset, Format};
383    use crate::endianity::LittleEndian;
384    use crate::read::EndianSlice;
385
386    #[test]
387    fn test_iterate_headers() {
388        #[rustfmt::skip]
389        let buf = [
390            // 32-bit length = 28.
391            0x1c, 0x00, 0x00, 0x00,
392            // Version.
393            0x02, 0x00,
394            // Offset.
395            0x01, 0x02, 0x03, 0x04,
396            // Address size.
397            0x04,
398            // Segment size.
399            0x00,
400            // Dummy padding and arange tuples.
401            0x00, 0x00, 0x00, 0x00,
402            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
403            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
404
405            // 32-bit length = 36.
406            0x24, 0x00, 0x00, 0x00,
407            // Version.
408            0x02, 0x00,
409            // Offset.
410            0x11, 0x12, 0x13, 0x14,
411            // Address size.
412            0x04,
413            // Segment size.
414            0x00,
415            // Dummy padding and arange tuples.
416            0x00, 0x00, 0x00, 0x00,
417            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
418            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
419            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
420        ];
421
422        let debug_aranges = DebugAranges::new(&buf, LittleEndian);
423        let mut headers = debug_aranges.headers();
424
425        let header = headers
426            .next()
427            .expect("should parse header ok")
428            .expect("should have a header");
429        assert_eq!(header.offset(), DebugArangesOffset(0));
430        assert_eq!(header.debug_info_offset(), DebugInfoOffset(0x0403_0201));
431
432        let header = headers
433            .next()
434            .expect("should parse header ok")
435            .expect("should have a header");
436        assert_eq!(header.offset(), DebugArangesOffset(0x20));
437        assert_eq!(header.debug_info_offset(), DebugInfoOffset(0x1413_1211));
438    }
439
440    #[test]
441    fn test_parse_header_ok() {
442        #[rustfmt::skip]
443        let buf = [
444            // 32-bit length = 28 (8 bytes header, 4 bytes padding, 16 bytes tuple data).
445            0x1c, 0x00, 0x00, 0x00,
446            // Version.
447            0x02, 0x00,
448            // Offset.
449            0x01, 0x02, 0x03, 0x04,
450            // Address size.
451            0x08,
452            // Segment size.
453            0x00,
454            // Length to here = 12, tuple length = 16.
455            // Padding to tuple length multiple = 4.
456            0x10, 0x00, 0x00, 0x00,
457
458            // Dummy arange tuple data.
459            0x20, 0x00, 0x00, 0x00,
460            0x00, 0x00, 0x00, 0x00,
461            0x00, 0x00, 0x00, 0x00,
462            0x00, 0x00, 0x00, 0x00,
463
464            // Dummy next arange.
465            0x30, 0x00, 0x00, 0x00,
466            0x00, 0x00, 0x00, 0x00,
467            0x00, 0x00, 0x00, 0x00,
468            0x00, 0x00, 0x00, 0x00,
469        ];
470
471        let rest = &mut EndianSlice::new(&buf, LittleEndian);
472
473        let header =
474            ArangeHeader::parse(rest, DebugArangesOffset(0x10)).expect("should parse header ok");
475
476        assert_eq!(
477            *rest,
478            EndianSlice::new(&buf[buf.len() - 16..], LittleEndian)
479        );
480        assert_eq!(
481            header,
482            ArangeHeader {
483                offset: DebugArangesOffset(0x10),
484                encoding: Encoding {
485                    format: Format::Dwarf32,
486                    version: 2,
487                    address_size: 8,
488                },
489                length: 0x1c,
490                debug_info_offset: DebugInfoOffset(0x0403_0201),
491                entries: EndianSlice::new(&buf[buf.len() - 32..buf.len() - 16], LittleEndian),
492            }
493        );
494    }
495
496    #[test]
497    fn test_parse_header_overflow_error() {
498        #[rustfmt::skip]
499        let buf = [
500            // 32-bit length = 32.
501            0x20, 0x00, 0x00, 0x00,
502            // Version.
503            0x02, 0x00,
504            // Offset.
505            0x01, 0x02, 0x03, 0x04,
506            // Address size.
507            0xff,
508            // Segment size.
509            0x00,
510            // Length to here = 12, tuple length = 20.
511            // Padding to tuple length multiple = 4.
512            0x10, 0x00, 0x00, 0x00,
513            0x00, 0x00, 0x00, 0x00,
514
515            // Dummy arange tuple data.
516            0x20, 0x00, 0x00, 0x00,
517            0x00, 0x00, 0x00, 0x00,
518            0x00, 0x00, 0x00, 0x00,
519            0x00, 0x00, 0x00, 0x00,
520
521            // Dummy next arange.
522            0x30, 0x00, 0x00, 0x00,
523            0x00, 0x00, 0x00, 0x00,
524            0x00, 0x00, 0x00, 0x00,
525            0x00, 0x00, 0x00, 0x00,
526        ];
527
528        let rest = &mut EndianSlice::new(&buf, LittleEndian);
529
530        let error = ArangeHeader::parse(rest, DebugArangesOffset(0x10))
531            .expect_err("should fail to parse header");
532        assert_eq!(error, Error::UnsupportedAddressSize(0xff));
533    }
534
535    #[test]
536    fn test_parse_header_div_by_zero_error() {
537        #[rustfmt::skip]
538        let buf = [
539            // 32-bit length = 32.
540            0x20, 0x00, 0x00, 0x00,
541            // Version.
542            0x02, 0x00,
543            // Offset.
544            0x01, 0x02, 0x03, 0x04,
545            // Address size = 0. Could cause a division by zero if we aren't
546            // careful.
547            0x00,
548            // Segment size.
549            0x00,
550            // Length to here = 12, tuple length = 20.
551            // Padding to tuple length multiple = 4.
552            0x10, 0x00, 0x00, 0x00,
553            0x00, 0x00, 0x00, 0x00,
554
555            // Dummy arange tuple data.
556            0x20, 0x00, 0x00, 0x00,
557            0x00, 0x00, 0x00, 0x00,
558            0x00, 0x00, 0x00, 0x00,
559            0x00, 0x00, 0x00, 0x00,
560
561            // Dummy next arange.
562            0x30, 0x00, 0x00, 0x00,
563            0x00, 0x00, 0x00, 0x00,
564            0x00, 0x00, 0x00, 0x00,
565            0x00, 0x00, 0x00, 0x00,
566        ];
567
568        let rest = &mut EndianSlice::new(&buf, LittleEndian);
569
570        let error = ArangeHeader::parse(rest, DebugArangesOffset(0x10))
571            .expect_err("should fail to parse header");
572        assert_eq!(error, Error::UnsupportedAddressSize(0));
573    }
574
575    #[test]
576    fn test_parse_entry_ok() {
577        let encoding = Encoding {
578            format: Format::Dwarf32,
579            version: 2,
580            address_size: 4,
581        };
582        let buf = [0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09];
583        let mut iter = ArangeEntryIter {
584            input: EndianSlice::new(&buf, LittleEndian),
585            encoding,
586        };
587        let entry = iter.next().expect("should parse entry ok");
588        assert_eq!(
589            iter.input,
590            EndianSlice::new(&buf[buf.len() - 1..], LittleEndian)
591        );
592        assert_eq!(
593            entry,
594            Some(ArangeEntry {
595                range: Range {
596                    begin: 0x0403_0201,
597                    end: 0x0403_0201 + 0x0807_0605,
598                },
599                length: 0x0807_0605,
600            })
601        );
602    }
603
604    #[test]
605    fn test_parse_entry_zero() {
606        let encoding = Encoding {
607            format: Format::Dwarf32,
608            version: 2,
609            address_size: 4,
610        };
611        #[rustfmt::skip]
612        let buf = [
613            // Zero tuple.
614            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
615            // Address.
616            0x01, 0x02, 0x03, 0x04,
617            // Length.
618            0x05, 0x06, 0x07, 0x08,
619            // Next tuple.
620            0x09
621        ];
622        let mut iter = ArangeEntryIter {
623            input: EndianSlice::new(&buf, LittleEndian),
624            encoding,
625        };
626        let entry = iter.next().expect("should parse entry ok");
627        assert_eq!(
628            iter.input,
629            EndianSlice::new(&buf[buf.len() - 1..], LittleEndian)
630        );
631        assert_eq!(
632            entry,
633            Some(ArangeEntry {
634                range: Range {
635                    begin: 0x0403_0201,
636                    end: 0x0403_0201 + 0x0807_0605,
637                },
638                length: 0x0807_0605,
639            })
640        );
641    }
642
643    #[test]
644    fn test_parse_entry_overflow_32() {
645        let encoding = Encoding {
646            format: Format::Dwarf32,
647            version: 2,
648            address_size: 4,
649        };
650        #[rustfmt::skip]
651        let buf = [
652            // Address.
653            0x01, 0x02, 0x03, 0x84,
654            // Length.
655            0x05, 0x06, 0x07, 0x88,
656            // Next tuple.
657            0x09
658        ];
659        let mut iter = ArangeEntryIter {
660            input: EndianSlice::new(&buf, LittleEndian),
661            encoding,
662        };
663        let entry = iter.next();
664        assert_eq!(
665            iter.input,
666            EndianSlice::new(&buf[buf.len() - 1..], LittleEndian)
667        );
668        assert_eq!(entry, Err(Error::AddressOverflow));
669    }
670
671    #[test]
672    fn test_parse_entry_overflow_64() {
673        let encoding = Encoding {
674            format: Format::Dwarf32,
675            version: 2,
676            address_size: 8,
677        };
678        #[rustfmt::skip]
679        let buf = [
680            // Address.
681            0x01, 0x02, 0x03, 0x04, 0x00, 0x00, 0x00, 0x80,
682            // Length.
683            0x05, 0x06, 0x07, 0x08, 0x00, 0x00, 0x00, 0x80,
684            // Next tuple.
685            0x09
686        ];
687        let mut iter = ArangeEntryIter {
688            input: EndianSlice::new(&buf, LittleEndian),
689            encoding,
690        };
691        let entry = iter.next();
692        assert_eq!(
693            iter.input,
694            EndianSlice::new(&buf[buf.len() - 1..], LittleEndian)
695        );
696        assert_eq!(entry, Err(Error::AddressOverflow));
697    }
698
699    #[test]
700    fn test_parse_entry_tombstone_32() {
701        let encoding = Encoding {
702            format: Format::Dwarf32,
703            version: 2,
704            address_size: 4,
705        };
706        #[rustfmt::skip]
707        let buf = [
708            // Address.
709            0xff, 0xff, 0xff, 0xff,
710            // Length.
711            0x05, 0x06, 0x07, 0x08,
712            // Address.
713            0x01, 0x02, 0x03, 0x04,
714            // Length.
715            0x05, 0x06, 0x07, 0x08,
716            // Next tuple.
717            0x09
718        ];
719
720        let mut iter = ArangeEntryIter {
721            input: EndianSlice::new(&buf, LittleEndian),
722            encoding,
723        };
724        let entry = iter.next_raw().unwrap();
725        assert_eq!(
726            iter.input,
727            EndianSlice::new(&buf[buf.len() - 9..], LittleEndian)
728        );
729        assert_eq!(
730            entry,
731            Some(ArangeEntry {
732                range: Range {
733                    begin: 0xffff_ffff,
734                    end: 0,
735                },
736                length: 0x0807_0605,
737            })
738        );
739
740        let mut iter = ArangeEntryIter {
741            input: EndianSlice::new(&buf, LittleEndian),
742            encoding,
743        };
744        let entry = iter.next().unwrap();
745        assert_eq!(
746            iter.input,
747            EndianSlice::new(&buf[buf.len() - 1..], LittleEndian)
748        );
749        assert_eq!(
750            entry,
751            Some(ArangeEntry {
752                range: Range {
753                    begin: 0x0403_0201,
754                    end: 0x0403_0201 + 0x0807_0605,
755                },
756                length: 0x0807_0605,
757            })
758        );
759    }
760
761    #[test]
762    fn test_parse_entry_tombstone_64() {
763        let encoding = Encoding {
764            format: Format::Dwarf32,
765            version: 2,
766            address_size: 8,
767        };
768        #[rustfmt::skip]
769        let buf = [
770            // Address.
771            0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
772            // Length.
773            0x05, 0x06, 0x07, 0x08, 0x00, 0x00, 0x00, 0x00,
774            // Address.
775            0x01, 0x02, 0x03, 0x04, 0x00, 0x00, 0x00, 0x00,
776            // Length.
777            0x05, 0x06, 0x07, 0x08, 0x00, 0x00, 0x00, 0x00,
778            // Next tuple.
779            0x09
780        ];
781
782        let mut iter = ArangeEntryIter {
783            input: EndianSlice::new(&buf, LittleEndian),
784            encoding,
785        };
786        let entry = iter.next_raw().unwrap();
787        assert_eq!(
788            iter.input,
789            EndianSlice::new(&buf[buf.len() - 17..], LittleEndian)
790        );
791        assert_eq!(
792            entry,
793            Some(ArangeEntry {
794                range: Range {
795                    begin: 0xffff_ffff_ffff_ffff,
796                    end: 0,
797                },
798                length: 0x0807_0605,
799            })
800        );
801
802        let mut iter = ArangeEntryIter {
803            input: EndianSlice::new(&buf, LittleEndian),
804            encoding,
805        };
806        let entry = iter.next().unwrap();
807        assert_eq!(
808            iter.input,
809            EndianSlice::new(&buf[buf.len() - 1..], LittleEndian)
810        );
811        assert_eq!(
812            entry,
813            Some(ArangeEntry {
814                range: Range {
815                    begin: 0x0403_0201,
816                    end: 0x0403_0201 + 0x0807_0605,
817                },
818                length: 0x0807_0605,
819            })
820        );
821    }
822}