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 negative tombstone entries.
293        // Callers must handle tombstones of 0 or greater themselves
294        // because we have no way of knowing if they are valid or not.
295        let address_size = self.encoding.address_size;
296        if entry.range.begin >= u64::min_tombstone(address_size) {
297            return Ok(None);
298        }
299
300        // Calculate end now so that we can handle overflow.
301        entry.range.end = entry.range.begin.add_sized(entry.length, address_size)?;
302        Ok(Some(entry))
303    }
304}
305
306#[cfg(feature = "fallible-iterator")]
307impl<R: Reader> fallible_iterator::FallibleIterator for ArangeEntryIter<R> {
308    type Item = ArangeEntry;
309    type Error = Error;
310
311    fn next(&mut self) -> ::core::result::Result<Option<Self::Item>, Self::Error> {
312        ArangeEntryIter::next(self)
313    }
314}
315
316/// A single parsed arange.
317#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)]
318pub struct ArangeEntry {
319    range: Range,
320    length: u64,
321}
322
323impl ArangeEntry {
324    /// Parse a single arange. Return `None` for the null arange, `Some` for an actual arange.
325    fn parse<R: Reader>(input: &mut R, encoding: Encoding) -> Result<Option<Self>> {
326        let address_size = encoding.address_size;
327
328        let tuple_length = R::Offset::from_u8(2 * address_size);
329        if tuple_length > input.len() {
330            input.empty();
331            return Ok(None);
332        }
333
334        let begin = input.read_address(address_size)?;
335        let length = input.read_address(address_size)?;
336        let range = Range { begin, end: 0 };
337
338        match (begin, length) {
339            // This is meant to be a null terminator, but in practice it can occur
340            // before the end, possibly due to a linker omitting a function and
341            // leaving an unrelocated entry.
342            (0, 0) => Self::parse(input, encoding),
343            _ => Ok(Some(ArangeEntry { range, length })),
344        }
345    }
346
347    /// Return the beginning address of this arange.
348    #[inline]
349    pub fn address(&self) -> u64 {
350        self.range.begin
351    }
352
353    /// Return the length of this arange.
354    #[inline]
355    pub fn length(&self) -> u64 {
356        self.length
357    }
358
359    /// Return the range.
360    #[inline]
361    pub fn range(&self) -> Range {
362        self.range
363    }
364}
365
366#[cfg(test)]
367mod tests {
368    use super::*;
369    use crate::common::{DebugInfoOffset, Format};
370    use crate::endianity::LittleEndian;
371    use crate::read::EndianSlice;
372
373    #[test]
374    fn test_iterate_headers() {
375        #[rustfmt::skip]
376        let buf = [
377            // 32-bit length = 28.
378            0x1c, 0x00, 0x00, 0x00,
379            // Version.
380            0x02, 0x00,
381            // Offset.
382            0x01, 0x02, 0x03, 0x04,
383            // Address size.
384            0x04,
385            // Segment size.
386            0x00,
387            // Dummy padding and arange tuples.
388            0x00, 0x00, 0x00, 0x00,
389            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
390            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
391
392            // 32-bit length = 36.
393            0x24, 0x00, 0x00, 0x00,
394            // Version.
395            0x02, 0x00,
396            // Offset.
397            0x11, 0x12, 0x13, 0x14,
398            // Address size.
399            0x04,
400            // Segment size.
401            0x00,
402            // Dummy padding and arange tuples.
403            0x00, 0x00, 0x00, 0x00,
404            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
405            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
406            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
407        ];
408
409        let debug_aranges = DebugAranges::new(&buf, LittleEndian);
410        let mut headers = debug_aranges.headers();
411
412        let header = headers
413            .next()
414            .expect("should parse header ok")
415            .expect("should have a header");
416        assert_eq!(header.offset(), DebugArangesOffset(0));
417        assert_eq!(header.debug_info_offset(), DebugInfoOffset(0x0403_0201));
418
419        let header = headers
420            .next()
421            .expect("should parse header ok")
422            .expect("should have a header");
423        assert_eq!(header.offset(), DebugArangesOffset(0x20));
424        assert_eq!(header.debug_info_offset(), DebugInfoOffset(0x1413_1211));
425    }
426
427    #[test]
428    fn test_parse_header_ok() {
429        #[rustfmt::skip]
430        let buf = [
431            // 32-bit length = 28 (8 bytes header, 4 bytes padding, 16 bytes tuple data).
432            0x1c, 0x00, 0x00, 0x00,
433            // Version.
434            0x02, 0x00,
435            // Offset.
436            0x01, 0x02, 0x03, 0x04,
437            // Address size.
438            0x08,
439            // Segment size.
440            0x00,
441            // Length to here = 12, tuple length = 16.
442            // Padding to tuple length multiple = 4.
443            0x10, 0x00, 0x00, 0x00,
444
445            // Dummy arange tuple data.
446            0x20, 0x00, 0x00, 0x00,
447            0x00, 0x00, 0x00, 0x00,
448            0x00, 0x00, 0x00, 0x00,
449            0x00, 0x00, 0x00, 0x00,
450
451            // Dummy next arange.
452            0x30, 0x00, 0x00, 0x00,
453            0x00, 0x00, 0x00, 0x00,
454            0x00, 0x00, 0x00, 0x00,
455            0x00, 0x00, 0x00, 0x00,
456        ];
457
458        let rest = &mut EndianSlice::new(&buf, LittleEndian);
459
460        let header =
461            ArangeHeader::parse(rest, DebugArangesOffset(0x10)).expect("should parse header ok");
462
463        assert_eq!(
464            *rest,
465            EndianSlice::new(&buf[buf.len() - 16..], LittleEndian)
466        );
467        assert_eq!(
468            header,
469            ArangeHeader {
470                offset: DebugArangesOffset(0x10),
471                encoding: Encoding {
472                    format: Format::Dwarf32,
473                    version: 2,
474                    address_size: 8,
475                },
476                length: 0x1c,
477                debug_info_offset: DebugInfoOffset(0x0403_0201),
478                entries: EndianSlice::new(&buf[buf.len() - 32..buf.len() - 16], LittleEndian),
479            }
480        );
481    }
482
483    #[test]
484    fn test_parse_header_overflow_error() {
485        #[rustfmt::skip]
486        let buf = [
487            // 32-bit length = 32.
488            0x20, 0x00, 0x00, 0x00,
489            // Version.
490            0x02, 0x00,
491            // Offset.
492            0x01, 0x02, 0x03, 0x04,
493            // Address size.
494            0xff,
495            // Segment size.
496            0x00,
497            // Length to here = 12, tuple length = 20.
498            // Padding to tuple length multiple = 4.
499            0x10, 0x00, 0x00, 0x00,
500            0x00, 0x00, 0x00, 0x00,
501
502            // Dummy arange tuple data.
503            0x20, 0x00, 0x00, 0x00,
504            0x00, 0x00, 0x00, 0x00,
505            0x00, 0x00, 0x00, 0x00,
506            0x00, 0x00, 0x00, 0x00,
507
508            // Dummy next arange.
509            0x30, 0x00, 0x00, 0x00,
510            0x00, 0x00, 0x00, 0x00,
511            0x00, 0x00, 0x00, 0x00,
512            0x00, 0x00, 0x00, 0x00,
513        ];
514
515        let rest = &mut EndianSlice::new(&buf, LittleEndian);
516
517        let error = ArangeHeader::parse(rest, DebugArangesOffset(0x10))
518            .expect_err("should fail to parse header");
519        assert_eq!(error, Error::UnsupportedAddressSize(0xff));
520    }
521
522    #[test]
523    fn test_parse_header_div_by_zero_error() {
524        #[rustfmt::skip]
525        let buf = [
526            // 32-bit length = 32.
527            0x20, 0x00, 0x00, 0x00,
528            // Version.
529            0x02, 0x00,
530            // Offset.
531            0x01, 0x02, 0x03, 0x04,
532            // Address size = 0. Could cause a division by zero if we aren't
533            // careful.
534            0x00,
535            // Segment size.
536            0x00,
537            // Length to here = 12, tuple length = 20.
538            // Padding to tuple length multiple = 4.
539            0x10, 0x00, 0x00, 0x00,
540            0x00, 0x00, 0x00, 0x00,
541
542            // Dummy arange tuple data.
543            0x20, 0x00, 0x00, 0x00,
544            0x00, 0x00, 0x00, 0x00,
545            0x00, 0x00, 0x00, 0x00,
546            0x00, 0x00, 0x00, 0x00,
547
548            // Dummy next arange.
549            0x30, 0x00, 0x00, 0x00,
550            0x00, 0x00, 0x00, 0x00,
551            0x00, 0x00, 0x00, 0x00,
552            0x00, 0x00, 0x00, 0x00,
553        ];
554
555        let rest = &mut EndianSlice::new(&buf, LittleEndian);
556
557        let error = ArangeHeader::parse(rest, DebugArangesOffset(0x10))
558            .expect_err("should fail to parse header");
559        assert_eq!(error, Error::UnsupportedAddressSize(0));
560    }
561
562    #[test]
563    fn test_parse_entry_ok() {
564        let encoding = Encoding {
565            format: Format::Dwarf32,
566            version: 2,
567            address_size: 4,
568        };
569        let buf = [0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09];
570        let mut iter = ArangeEntryIter {
571            input: EndianSlice::new(&buf, LittleEndian),
572            encoding,
573        };
574        let entry = iter.next().expect("should parse entry ok");
575        assert_eq!(
576            iter.input,
577            EndianSlice::new(&buf[buf.len() - 1..], LittleEndian)
578        );
579        assert_eq!(
580            entry,
581            Some(ArangeEntry {
582                range: Range {
583                    begin: 0x0403_0201,
584                    end: 0x0403_0201 + 0x0807_0605,
585                },
586                length: 0x0807_0605,
587            })
588        );
589    }
590
591    #[test]
592    fn test_parse_entry_zero() {
593        let encoding = Encoding {
594            format: Format::Dwarf32,
595            version: 2,
596            address_size: 4,
597        };
598        #[rustfmt::skip]
599        let buf = [
600            // Zero tuple.
601            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
602            // Address.
603            0x01, 0x02, 0x03, 0x04,
604            // Length.
605            0x05, 0x06, 0x07, 0x08,
606            // Next tuple.
607            0x09
608        ];
609        let mut iter = ArangeEntryIter {
610            input: EndianSlice::new(&buf, LittleEndian),
611            encoding,
612        };
613        let entry = iter.next().expect("should parse entry ok");
614        assert_eq!(
615            iter.input,
616            EndianSlice::new(&buf[buf.len() - 1..], LittleEndian)
617        );
618        assert_eq!(
619            entry,
620            Some(ArangeEntry {
621                range: Range {
622                    begin: 0x0403_0201,
623                    end: 0x0403_0201 + 0x0807_0605,
624                },
625                length: 0x0807_0605,
626            })
627        );
628    }
629
630    #[test]
631    fn test_parse_entry_overflow_32() {
632        let encoding = Encoding {
633            format: Format::Dwarf32,
634            version: 2,
635            address_size: 4,
636        };
637        #[rustfmt::skip]
638        let buf = [
639            // Address.
640            0x01, 0x02, 0x03, 0x84,
641            // Length.
642            0x05, 0x06, 0x07, 0x88,
643            // Next tuple.
644            0x09
645        ];
646        let mut iter = ArangeEntryIter {
647            input: EndianSlice::new(&buf, LittleEndian),
648            encoding,
649        };
650        let entry = iter.next();
651        assert_eq!(
652            iter.input,
653            EndianSlice::new(&buf[buf.len() - 1..], LittleEndian)
654        );
655        assert_eq!(entry, Err(Error::AddressOverflow));
656    }
657
658    #[test]
659    fn test_parse_entry_overflow_64() {
660        let encoding = Encoding {
661            format: Format::Dwarf32,
662            version: 2,
663            address_size: 8,
664        };
665        #[rustfmt::skip]
666        let buf = [
667            // Address.
668            0x01, 0x02, 0x03, 0x04, 0x00, 0x00, 0x00, 0x80,
669            // Length.
670            0x05, 0x06, 0x07, 0x08, 0x00, 0x00, 0x00, 0x80,
671            // Next tuple.
672            0x09
673        ];
674        let mut iter = ArangeEntryIter {
675            input: EndianSlice::new(&buf, LittleEndian),
676            encoding,
677        };
678        let entry = iter.next();
679        assert_eq!(
680            iter.input,
681            EndianSlice::new(&buf[buf.len() - 1..], LittleEndian)
682        );
683        assert_eq!(entry, Err(Error::AddressOverflow));
684    }
685
686    #[test]
687    fn test_parse_entry_tombstone_32() {
688        let encoding = Encoding {
689            format: Format::Dwarf32,
690            version: 2,
691            address_size: 4,
692        };
693        #[rustfmt::skip]
694        let buf = [
695            // Address.
696            0xff, 0xff, 0xff, 0xff,
697            // Length.
698            0x05, 0x06, 0x07, 0x08,
699            // Address.
700            0x01, 0x02, 0x03, 0x04,
701            // Length.
702            0x05, 0x06, 0x07, 0x08,
703            // Next tuple.
704            0x09
705        ];
706
707        let mut iter = ArangeEntryIter {
708            input: EndianSlice::new(&buf, LittleEndian),
709            encoding,
710        };
711        let entry = iter.next_raw().unwrap();
712        assert_eq!(
713            iter.input,
714            EndianSlice::new(&buf[buf.len() - 9..], LittleEndian)
715        );
716        assert_eq!(
717            entry,
718            Some(ArangeEntry {
719                range: Range {
720                    begin: 0xffff_ffff,
721                    end: 0,
722                },
723                length: 0x0807_0605,
724            })
725        );
726
727        let mut iter = ArangeEntryIter {
728            input: EndianSlice::new(&buf, LittleEndian),
729            encoding,
730        };
731        let entry = iter.next().unwrap();
732        assert_eq!(
733            iter.input,
734            EndianSlice::new(&buf[buf.len() - 1..], LittleEndian)
735        );
736        assert_eq!(
737            entry,
738            Some(ArangeEntry {
739                range: Range {
740                    begin: 0x0403_0201,
741                    end: 0x0403_0201 + 0x0807_0605,
742                },
743                length: 0x0807_0605,
744            })
745        );
746    }
747
748    #[test]
749    fn test_parse_entry_tombstone_64() {
750        let encoding = Encoding {
751            format: Format::Dwarf32,
752            version: 2,
753            address_size: 8,
754        };
755        #[rustfmt::skip]
756        let buf = [
757            // Address.
758            0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
759            // Length.
760            0x05, 0x06, 0x07, 0x08, 0x00, 0x00, 0x00, 0x00,
761            // Address.
762            0x01, 0x02, 0x03, 0x04, 0x00, 0x00, 0x00, 0x00,
763            // Length.
764            0x05, 0x06, 0x07, 0x08, 0x00, 0x00, 0x00, 0x00,
765            // Next tuple.
766            0x09
767        ];
768
769        let mut iter = ArangeEntryIter {
770            input: EndianSlice::new(&buf, LittleEndian),
771            encoding,
772        };
773        let entry = iter.next_raw().unwrap();
774        assert_eq!(
775            iter.input,
776            EndianSlice::new(&buf[buf.len() - 17..], LittleEndian)
777        );
778        assert_eq!(
779            entry,
780            Some(ArangeEntry {
781                range: Range {
782                    begin: 0xffff_ffff_ffff_ffff,
783                    end: 0,
784                },
785                length: 0x0807_0605,
786            })
787        );
788
789        let mut iter = ArangeEntryIter {
790            input: EndianSlice::new(&buf, LittleEndian),
791            encoding,
792        };
793        let entry = iter.next().unwrap();
794        assert_eq!(
795            iter.input,
796            EndianSlice::new(&buf[buf.len() - 1..], LittleEndian)
797        );
798        assert_eq!(
799            entry,
800            Some(ArangeEntry {
801                range: Range {
802                    begin: 0x0403_0201,
803                    end: 0x0403_0201 + 0x0807_0605,
804                },
805                length: 0x0807_0605,
806            })
807        );
808    }
809}