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 if self.input.is_empty() {
253 return Ok(None);
254 }
255
256 match ArangeEntry::parse(&mut self.input, self.encoding) {
257 Ok(Some(entry)) => Ok(Some(entry)),
258 Ok(None) => {
259 self.input.empty();
260 Ok(None)
261 }
262 Err(e) => {
263 self.input.empty();
264 Err(e)
265 }
266 }
267 }
268}
269
270#[cfg(feature = "fallible-iterator")]
271impl<R: Reader> fallible_iterator::FallibleIterator for ArangeEntryIter<R> {
272 type Item = ArangeEntry;
273 type Error = Error;
274
275 fn next(&mut self) -> ::core::result::Result<Option<Self::Item>, Self::Error> {
276 ArangeEntryIter::next(self)
277 }
278}
279
280#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)]
282pub struct ArangeEntry {
283 range: Range,
284 length: u64,
285}
286
287impl ArangeEntry {
288 fn parse<R: Reader>(input: &mut R, encoding: Encoding) -> Result<Option<Self>> {
290 let address_size = encoding.address_size;
291
292 let tuple_length = R::Offset::from_u8(2 * address_size);
293 if tuple_length > input.len() {
294 input.empty();
295 return Ok(None);
296 }
297
298 let begin = input.read_address(address_size)?;
299 let length = input.read_address(address_size)?;
300 let end = begin.add_sized(length, address_size)?;
302 let range = Range { begin, end };
303
304 match (begin, length) {
305 (0, 0) => Self::parse(input, encoding),
309 _ => Ok(Some(ArangeEntry { range, length })),
310 }
311 }
312
313 #[inline]
315 pub fn address(&self) -> u64 {
316 self.range.begin
317 }
318
319 #[inline]
321 pub fn length(&self) -> u64 {
322 self.length
323 }
324
325 #[inline]
327 pub fn range(&self) -> Range {
328 self.range
329 }
330}
331
332#[cfg(test)]
333mod tests {
334 use super::*;
335 use crate::common::{DebugInfoOffset, Format};
336 use crate::endianity::LittleEndian;
337 use crate::read::EndianSlice;
338
339 #[test]
340 fn test_iterate_headers() {
341 #[rustfmt::skip]
342 let buf = [
343 0x1c, 0x00, 0x00, 0x00,
345 0x02, 0x00,
347 0x01, 0x02, 0x03, 0x04,
349 0x04,
351 0x00,
353 0x00, 0x00, 0x00, 0x00,
355 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
356 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
357
358 0x24, 0x00, 0x00, 0x00,
360 0x02, 0x00,
362 0x11, 0x12, 0x13, 0x14,
364 0x04,
366 0x00,
368 0x00, 0x00, 0x00, 0x00,
370 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
371 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
372 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
373 ];
374
375 let debug_aranges = DebugAranges::new(&buf, LittleEndian);
376 let mut headers = debug_aranges.headers();
377
378 let header = headers
379 .next()
380 .expect("should parse header ok")
381 .expect("should have a header");
382 assert_eq!(header.offset(), DebugArangesOffset(0));
383 assert_eq!(header.debug_info_offset(), DebugInfoOffset(0x0403_0201));
384
385 let header = headers
386 .next()
387 .expect("should parse header ok")
388 .expect("should have a header");
389 assert_eq!(header.offset(), DebugArangesOffset(0x20));
390 assert_eq!(header.debug_info_offset(), DebugInfoOffset(0x1413_1211));
391 }
392
393 #[test]
394 fn test_parse_header_ok() {
395 #[rustfmt::skip]
396 let buf = [
397 0x1c, 0x00, 0x00, 0x00,
399 0x02, 0x00,
401 0x01, 0x02, 0x03, 0x04,
403 0x08,
405 0x00,
407 0x10, 0x00, 0x00, 0x00,
410
411 0x20, 0x00, 0x00, 0x00,
413 0x00, 0x00, 0x00, 0x00,
414 0x00, 0x00, 0x00, 0x00,
415 0x00, 0x00, 0x00, 0x00,
416
417 0x30, 0x00, 0x00, 0x00,
419 0x00, 0x00, 0x00, 0x00,
420 0x00, 0x00, 0x00, 0x00,
421 0x00, 0x00, 0x00, 0x00,
422 ];
423
424 let rest = &mut EndianSlice::new(&buf, LittleEndian);
425
426 let header =
427 ArangeHeader::parse(rest, DebugArangesOffset(0x10)).expect("should parse header ok");
428
429 assert_eq!(
430 *rest,
431 EndianSlice::new(&buf[buf.len() - 16..], LittleEndian)
432 );
433 assert_eq!(
434 header,
435 ArangeHeader {
436 offset: DebugArangesOffset(0x10),
437 encoding: Encoding {
438 format: Format::Dwarf32,
439 version: 2,
440 address_size: 8,
441 },
442 length: 0x1c,
443 debug_info_offset: DebugInfoOffset(0x0403_0201),
444 entries: EndianSlice::new(&buf[buf.len() - 32..buf.len() - 16], LittleEndian),
445 }
446 );
447 }
448
449 #[test]
450 fn test_parse_header_overflow_error() {
451 #[rustfmt::skip]
452 let buf = [
453 0x20, 0x00, 0x00, 0x00,
455 0x02, 0x00,
457 0x01, 0x02, 0x03, 0x04,
459 0xff,
461 0x00,
463 0x10, 0x00, 0x00, 0x00,
466 0x00, 0x00, 0x00, 0x00,
467
468 0x20, 0x00, 0x00, 0x00,
470 0x00, 0x00, 0x00, 0x00,
471 0x00, 0x00, 0x00, 0x00,
472 0x00, 0x00, 0x00, 0x00,
473
474 0x30, 0x00, 0x00, 0x00,
476 0x00, 0x00, 0x00, 0x00,
477 0x00, 0x00, 0x00, 0x00,
478 0x00, 0x00, 0x00, 0x00,
479 ];
480
481 let rest = &mut EndianSlice::new(&buf, LittleEndian);
482
483 let error = ArangeHeader::parse(rest, DebugArangesOffset(0x10))
484 .expect_err("should fail to parse header");
485 assert_eq!(error, Error::UnsupportedAddressSize(0xff));
486 }
487
488 #[test]
489 fn test_parse_header_div_by_zero_error() {
490 #[rustfmt::skip]
491 let buf = [
492 0x20, 0x00, 0x00, 0x00,
494 0x02, 0x00,
496 0x01, 0x02, 0x03, 0x04,
498 0x00,
501 0x00,
503 0x10, 0x00, 0x00, 0x00,
506 0x00, 0x00, 0x00, 0x00,
507
508 0x20, 0x00, 0x00, 0x00,
510 0x00, 0x00, 0x00, 0x00,
511 0x00, 0x00, 0x00, 0x00,
512 0x00, 0x00, 0x00, 0x00,
513
514 0x30, 0x00, 0x00, 0x00,
516 0x00, 0x00, 0x00, 0x00,
517 0x00, 0x00, 0x00, 0x00,
518 0x00, 0x00, 0x00, 0x00,
519 ];
520
521 let rest = &mut EndianSlice::new(&buf, LittleEndian);
522
523 let error = ArangeHeader::parse(rest, DebugArangesOffset(0x10))
524 .expect_err("should fail to parse header");
525 assert_eq!(error, Error::UnsupportedAddressSize(0));
526 }
527
528 #[test]
529 fn test_parse_entry_ok() {
530 let encoding = Encoding {
531 format: Format::Dwarf32,
532 version: 2,
533 address_size: 4,
534 };
535 let buf = [0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09];
536 let rest = &mut EndianSlice::new(&buf, LittleEndian);
537 let entry = ArangeEntry::parse(rest, encoding).expect("should parse entry ok");
538 assert_eq!(*rest, EndianSlice::new(&buf[buf.len() - 1..], LittleEndian));
539 assert_eq!(
540 entry,
541 Some(ArangeEntry {
542 range: Range {
543 begin: 0x0403_0201,
544 end: 0x0403_0201 + 0x0807_0605,
545 },
546 length: 0x0807_0605,
547 })
548 );
549 }
550
551 #[test]
552 fn test_parse_entry_zero() {
553 let encoding = Encoding {
554 format: Format::Dwarf32,
555 version: 2,
556 address_size: 4,
557 };
558 #[rustfmt::skip]
559 let buf = [
560 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
562 0x01, 0x02, 0x03, 0x04,
564 0x05, 0x06, 0x07, 0x08,
566 0x09
568 ];
569 let rest = &mut EndianSlice::new(&buf, LittleEndian);
570 let entry = ArangeEntry::parse(rest, encoding).expect("should parse entry ok");
571 assert_eq!(*rest, EndianSlice::new(&buf[buf.len() - 1..], LittleEndian));
572 assert_eq!(
573 entry,
574 Some(ArangeEntry {
575 range: Range {
576 begin: 0x0403_0201,
577 end: 0x0403_0201 + 0x0807_0605,
578 },
579 length: 0x0807_0605,
580 })
581 );
582 }
583
584 #[test]
585 fn test_parse_entry_overflow_32() {
586 let encoding = Encoding {
587 format: Format::Dwarf32,
588 version: 2,
589 address_size: 4,
590 };
591 #[rustfmt::skip]
592 let buf = [
593 0x01, 0x02, 0x03, 0x84,
595 0x05, 0x06, 0x07, 0x88,
597 0x09
599 ];
600 let rest = &mut EndianSlice::new(&buf, LittleEndian);
601 let entry = ArangeEntry::parse(rest, encoding);
602 assert_eq!(*rest, EndianSlice::new(&buf[buf.len() - 1..], LittleEndian));
603 assert_eq!(entry, Err(Error::AddressOverflow));
604 }
605
606 #[test]
607 fn test_parse_entry_overflow_64() {
608 let encoding = Encoding {
609 format: Format::Dwarf32,
610 version: 2,
611 address_size: 8,
612 };
613 #[rustfmt::skip]
614 let buf = [
615 0x01, 0x02, 0x03, 0x04, 0x00, 0x00, 0x00, 0x80,
617 0x05, 0x06, 0x07, 0x08, 0x00, 0x00, 0x00, 0x80,
619 0x09
621 ];
622 let rest = &mut EndianSlice::new(&buf, LittleEndian);
623 let entry = ArangeEntry::parse(rest, encoding);
624 assert_eq!(*rest, EndianSlice::new(&buf[buf.len() - 1..], LittleEndian));
625 assert_eq!(entry, Err(Error::AddressOverflow));
626 }
627}