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 if entry.range.begin >= u64::min_tombstone(address_size) {
297 return Ok(None);
298 }
299
300 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#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)]
318pub struct ArangeEntry {
319 range: Range,
320 length: u64,
321}
322
323impl ArangeEntry {
324 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 (0, 0) => Self::parse(input, encoding),
343 _ => Ok(Some(ArangeEntry { range, length })),
344 }
345 }
346
347 #[inline]
349 pub fn address(&self) -> u64 {
350 self.range.begin
351 }
352
353 #[inline]
355 pub fn length(&self) -> u64 {
356 self.length
357 }
358
359 #[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 0x1c, 0x00, 0x00, 0x00,
379 0x02, 0x00,
381 0x01, 0x02, 0x03, 0x04,
383 0x04,
385 0x00,
387 0x00, 0x00, 0x00, 0x00,
389 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
390 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
391
392 0x24, 0x00, 0x00, 0x00,
394 0x02, 0x00,
396 0x11, 0x12, 0x13, 0x14,
398 0x04,
400 0x00,
402 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 0x1c, 0x00, 0x00, 0x00,
433 0x02, 0x00,
435 0x01, 0x02, 0x03, 0x04,
437 0x08,
439 0x00,
441 0x10, 0x00, 0x00, 0x00,
444
445 0x20, 0x00, 0x00, 0x00,
447 0x00, 0x00, 0x00, 0x00,
448 0x00, 0x00, 0x00, 0x00,
449 0x00, 0x00, 0x00, 0x00,
450
451 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 0x20, 0x00, 0x00, 0x00,
489 0x02, 0x00,
491 0x01, 0x02, 0x03, 0x04,
493 0xff,
495 0x00,
497 0x10, 0x00, 0x00, 0x00,
500 0x00, 0x00, 0x00, 0x00,
501
502 0x20, 0x00, 0x00, 0x00,
504 0x00, 0x00, 0x00, 0x00,
505 0x00, 0x00, 0x00, 0x00,
506 0x00, 0x00, 0x00, 0x00,
507
508 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 0x20, 0x00, 0x00, 0x00,
528 0x02, 0x00,
530 0x01, 0x02, 0x03, 0x04,
532 0x00,
535 0x00,
537 0x10, 0x00, 0x00, 0x00,
540 0x00, 0x00, 0x00, 0x00,
541
542 0x20, 0x00, 0x00, 0x00,
544 0x00, 0x00, 0x00, 0x00,
545 0x00, 0x00, 0x00, 0x00,
546 0x00, 0x00, 0x00, 0x00,
547
548 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 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
602 0x01, 0x02, 0x03, 0x04,
604 0x05, 0x06, 0x07, 0x08,
606 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 0x01, 0x02, 0x03, 0x84,
641 0x05, 0x06, 0x07, 0x88,
643 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 0x01, 0x02, 0x03, 0x04, 0x00, 0x00, 0x00, 0x80,
669 0x05, 0x06, 0x07, 0x08, 0x00, 0x00, 0x00, 0x80,
671 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 0xff, 0xff, 0xff, 0xff,
697 0x05, 0x06, 0x07, 0x08,
699 0x01, 0x02, 0x03, 0x04,
701 0x05, 0x06, 0x07, 0x08,
703 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 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
759 0x05, 0x06, 0x07, 0x08, 0x00, 0x00, 0x00, 0x00,
761 0x01, 0x02, 0x03, 0x04, 0x00, 0x00, 0x00, 0x00,
763 0x05, 0x06, 0x07, 0x08, 0x00, 0x00, 0x00, 0x00,
765 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}