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(slice: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(offset: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: R = self.section.clone();
54 input.skip(len: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: ::Offset = self.input.len();
104 match ArangeHeader::parse(&mut self.input, self.offset) {
105 Ok(header: ArangeHeader::Offset>) => {
106 self.offset.0 += len - self.input.len();
107 Ok(Some(header))
108 }
109 Err(e: Error) => {
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}
811