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#[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 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 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 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 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#[derive(Clone, Debug)]
91pub struct ArangeHeaderIter<R: Reader> {
92 input: R,
93 offset: DebugArangesOffset<R::Offset>,
94}
95
96impl<R: Reader> ArangeHeaderIter<R> {
97 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#[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 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 let header_length = format.initial_length_size() + 2 + format.word_size() + 1 + 1;
178
179 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 #[inline]
210 pub fn offset(&self) -> DebugArangesOffset<Offset> {
211 self.offset
212 }
213
214 #[inline]
216 pub fn length(&self) -> Offset {
217 self.length
218 }
219
220 #[inline]
222 pub fn encoding(&self) -> Encoding {
223 self.encoding
224 }
225
226 #[inline]
228 pub fn debug_info_offset(&self) -> DebugInfoOffset<Offset> {
229 self.debug_info_offset
230 }
231
232 #[inline]
234 pub fn entries(&self) -> ArangeEntryIter<R> {
235 ArangeEntryIter {
236 input: self.entries.clone(),
237 encoding: self.encoding,
238 }
239 }
240}
241
242#[derive(Debug, Clone)]
244pub struct ArangeEntryIter<R: Reader> {
245 input: R,
246 encoding: Encoding,
247}
248
249impl<R: Reader> ArangeEntryIter<R> {
250 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 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 #[doc(hidden)]
296 pub fn convert_raw(&self, mut entry: ArangeEntry) -> Result<Option<ArangeEntry>> {
297 let address_size = self.encoding.address_size;
301 if entry.range.begin >= u64::min_tombstone(address_size) {
302 return Ok(None);
303 }
304
305 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#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)]
331pub struct ArangeEntry {
332 range: Range,
333 length: u64,
334}
335
336impl ArangeEntry {
337 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 (0, 0) => Self::parse(input, encoding),
356 _ => Ok(Some(ArangeEntry { range, length })),
357 }
358 }
359
360 #[inline]
362 pub fn address(&self) -> u64 {
363 self.range.begin
364 }
365
366 #[inline]
368 pub fn length(&self) -> u64 {
369 self.length
370 }
371
372 #[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 0x1c, 0x00, 0x00, 0x00,
392 0x02, 0x00,
394 0x01, 0x02, 0x03, 0x04,
396 0x04,
398 0x00,
400 0x00, 0x00, 0x00, 0x00,
402 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
403 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
404
405 0x24, 0x00, 0x00, 0x00,
407 0x02, 0x00,
409 0x11, 0x12, 0x13, 0x14,
411 0x04,
413 0x00,
415 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 0x1c, 0x00, 0x00, 0x00,
446 0x02, 0x00,
448 0x01, 0x02, 0x03, 0x04,
450 0x08,
452 0x00,
454 0x10, 0x00, 0x00, 0x00,
457
458 0x20, 0x00, 0x00, 0x00,
460 0x00, 0x00, 0x00, 0x00,
461 0x00, 0x00, 0x00, 0x00,
462 0x00, 0x00, 0x00, 0x00,
463
464 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 0x20, 0x00, 0x00, 0x00,
502 0x02, 0x00,
504 0x01, 0x02, 0x03, 0x04,
506 0xff,
508 0x00,
510 0x10, 0x00, 0x00, 0x00,
513 0x00, 0x00, 0x00, 0x00,
514
515 0x20, 0x00, 0x00, 0x00,
517 0x00, 0x00, 0x00, 0x00,
518 0x00, 0x00, 0x00, 0x00,
519 0x00, 0x00, 0x00, 0x00,
520
521 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 0x20, 0x00, 0x00, 0x00,
541 0x02, 0x00,
543 0x01, 0x02, 0x03, 0x04,
545 0x00,
548 0x00,
550 0x10, 0x00, 0x00, 0x00,
553 0x00, 0x00, 0x00, 0x00,
554
555 0x20, 0x00, 0x00, 0x00,
557 0x00, 0x00, 0x00, 0x00,
558 0x00, 0x00, 0x00, 0x00,
559 0x00, 0x00, 0x00, 0x00,
560
561 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 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
615 0x01, 0x02, 0x03, 0x04,
617 0x05, 0x06, 0x07, 0x08,
619 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 0x01, 0x02, 0x03, 0x84,
654 0x05, 0x06, 0x07, 0x88,
656 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 0x01, 0x02, 0x03, 0x04, 0x00, 0x00, 0x00, 0x80,
682 0x05, 0x06, 0x07, 0x08, 0x00, 0x00, 0x00, 0x80,
684 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 0xff, 0xff, 0xff, 0xff,
710 0x05, 0x06, 0x07, 0x08,
712 0x01, 0x02, 0x03, 0x04,
714 0x05, 0x06, 0x07, 0x08,
716 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 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
772 0x05, 0x06, 0x07, 0x08, 0x00, 0x00, 0x00, 0x00,
774 0x01, 0x02, 0x03, 0x04, 0x00, 0x00, 0x00, 0x00,
776 0x05, 0x06, 0x07, 0x08, 0x00, 0x00, 0x00, 0x00,
778 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}