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
127#[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 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 let header_length = format.initial_length_size() + 2 + format.word_size() + 1 + 1;
170
171 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 #[inline]
202 pub fn offset(&self) -> DebugArangesOffset<Offset> {
203 self.offset
204 }
205
206 #[inline]
208 pub fn length(&self) -> Offset {
209 self.length
210 }
211
212 #[inline]
214 pub fn encoding(&self) -> Encoding {
215 self.encoding
216 }
217
218 #[inline]
220 pub fn debug_info_offset(&self) -> DebugInfoOffset<Offset> {
221 self.debug_info_offset
222 }
223
224 #[inline]
226 pub fn entries(&self) -> ArangeEntryIter<R> {
227 ArangeEntryIter {
228 input: self.entries.clone(),
229 encoding: self.encoding,
230 }
231 }
232}
233
234#[derive(Debug, Clone)]
239pub struct ArangeEntryIter<R: Reader> {
240 input: R,
241 encoding: Encoding,
242}
243
244impl<R: Reader> ArangeEntryIter<R> {
245 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 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 #[doc(hidden)]
291 pub fn convert_raw(&self, mut entry: ArangeEntry) -> Result<Option<ArangeEntry>> {
292 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 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#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)]
319pub struct ArangeEntry {
320 range: Range,
321 length: u64,
322}
323
324impl ArangeEntry {
325 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 (0, 0) => Self::parse(input, encoding),
344 _ => Ok(Some(ArangeEntry { range, length })),
345 }
346 }
347
348 #[inline]
350 pub fn address(&self) -> u64 {
351 self.range.begin
352 }
353
354 #[inline]
356 pub fn length(&self) -> u64 {
357 self.length
358 }
359
360 #[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 0x1c, 0x00, 0x00, 0x00,
380 0x02, 0x00,
382 0x01, 0x02, 0x03, 0x04,
384 0x04,
386 0x00,
388 0x00, 0x00, 0x00, 0x00,
390 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
391 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
392
393 0x24, 0x00, 0x00, 0x00,
395 0x02, 0x00,
397 0x11, 0x12, 0x13, 0x14,
399 0x04,
401 0x00,
403 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 0x1c, 0x00, 0x00, 0x00,
434 0x02, 0x00,
436 0x01, 0x02, 0x03, 0x04,
438 0x08,
440 0x00,
442 0x10, 0x00, 0x00, 0x00,
445
446 0x20, 0x00, 0x00, 0x00,
448 0x00, 0x00, 0x00, 0x00,
449 0x00, 0x00, 0x00, 0x00,
450 0x00, 0x00, 0x00, 0x00,
451
452 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 0x20, 0x00, 0x00, 0x00,
490 0x02, 0x00,
492 0x01, 0x02, 0x03, 0x04,
494 0xff,
496 0x00,
498 0x10, 0x00, 0x00, 0x00,
501 0x00, 0x00, 0x00, 0x00,
502
503 0x20, 0x00, 0x00, 0x00,
505 0x00, 0x00, 0x00, 0x00,
506 0x00, 0x00, 0x00, 0x00,
507 0x00, 0x00, 0x00, 0x00,
508
509 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 0x20, 0x00, 0x00, 0x00,
529 0x02, 0x00,
531 0x01, 0x02, 0x03, 0x04,
533 0x00,
536 0x00,
538 0x10, 0x00, 0x00, 0x00,
541 0x00, 0x00, 0x00, 0x00,
542
543 0x20, 0x00, 0x00, 0x00,
545 0x00, 0x00, 0x00, 0x00,
546 0x00, 0x00, 0x00, 0x00,
547 0x00, 0x00, 0x00, 0x00,
548
549 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 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
603 0x01, 0x02, 0x03, 0x04,
605 0x05, 0x06, 0x07, 0x08,
607 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 0x01, 0x02, 0x03, 0x84,
642 0x05, 0x06, 0x07, 0x88,
644 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 0x01, 0x02, 0x03, 0x04, 0x00, 0x00, 0x00, 0x80,
670 0x05, 0x06, 0x07, 0x08, 0x00, 0x00, 0x00, 0x80,
672 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 0xff, 0xff, 0xff, 0xff,
698 0x05, 0x06, 0x07, 0x08,
700 0x01, 0x02, 0x03, 0x04,
702 0x05, 0x06, 0x07, 0x08,
704 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 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
760 0x05, 0x06, 0x07, 0x08, 0x00, 0x00, 0x00, 0x00,
762 0x01, 0x02, 0x03, 0x04, 0x00, 0x00, 0x00, 0x00,
764 0x05, 0x06, 0x07, 0x08, 0x00, 0x00, 0x00, 0x00,
766 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}