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