1use crate::common::{DebugArangesOffset, DebugInfoOffset, Encoding, SectionId};
2use crate::endianity::Endianity;
3use crate::read::{EndianSlice, Error, Range, Reader, ReaderOffset, Result, Section};
4
5/// The `DebugAranges` struct represents the DWARF address range information
6/// found in the `.debug_aranges` section.
7#[derive(Debug, Default, Clone, Copy)]
8pub struct DebugAranges<R> {
9 section: R,
10}
11
12impl<'input, Endian> DebugAranges<EndianSlice<'input, Endian>>
13where
14 Endian: Endianity,
15{
16 /// Construct a new `DebugAranges` instance from the data in the `.debug_aranges`
17 /// section.
18 ///
19 /// It is the caller's responsibility to read the `.debug_aranges` section and
20 /// present it as a `&[u8]` slice. That means using some ELF loader on
21 /// Linux, a Mach-O loader on macOS, etc.
22 ///
23 /// ```
24 /// use gimli::{DebugAranges, LittleEndian};
25 ///
26 /// # let buf = [];
27 /// # let read_debug_aranges_section = || &buf;
28 /// let debug_aranges =
29 /// DebugAranges::new(read_debug_aranges_section(), LittleEndian);
30 /// ```
31 pub fn new(section: &'input [u8], endian: Endian) -> Self {
32 DebugAranges {
33 section: EndianSlice::new(slice:section, endian),
34 }
35 }
36}
37
38impl<R: Reader> DebugAranges<R> {
39 /// Iterate the sets of entries in the `.debug_aranges` section.
40 ///
41 /// Each set of entries belongs to a single unit.
42 pub fn headers(&self) -> ArangeHeaderIter<R> {
43 ArangeHeaderIter {
44 input: self.section.clone(),
45 offset: DebugArangesOffset(R::Offset::from_u8(offset:0)),
46 }
47 }
48
49 /// Get the header at the given offset.
50 pub fn header(&self, offset: DebugArangesOffset<R::Offset>) -> Result<ArangeHeader<R>> {
51 let mut input = self.section.clone();
52 input.skip(offset.0)?;
53 ArangeHeader::parse(&mut input, offset)
54 }
55}
56
57impl<T> DebugAranges<T> {
58 /// Create a `DebugAranges` section that references the data in `self`.
59 ///
60 /// This is useful when `R` implements `Reader` but `T` does not.
61 ///
62 /// ## Example Usage
63 ///
64 /// ```rust,no_run
65 /// # let load_section = || unimplemented!();
66 /// // Read the DWARF section into a `Vec` with whatever object loader you're using.
67 /// let owned_section: gimli::DebugAranges<Vec<u8>> = load_section();
68 /// // Create a reference to the DWARF section.
69 /// let section = owned_section.borrow(|section| {
70 /// gimli::EndianSlice::new(&section, gimli::LittleEndian)
71 /// });
72 /// ```
73 pub fn borrow<'a, F, R>(&'a self, mut borrow: F) -> DebugAranges<R>
74 where
75 F: FnMut(&'a T) -> R,
76 {
77 borrow(&self.section).into()
78 }
79}
80
81impl<R> Section<R> for DebugAranges<R> {
82 fn id() -> SectionId {
83 SectionId::DebugAranges
84 }
85
86 fn reader(&self) -> &R {
87 &self.section
88 }
89}
90
91impl<R> From<R> for DebugAranges<R> {
92 fn from(section: R) -> Self {
93 DebugAranges { section }
94 }
95}
96
97/// An iterator over the headers of a `.debug_aranges` section.
98#[derive(Clone, Debug)]
99pub struct ArangeHeaderIter<R: Reader> {
100 input: R,
101 offset: DebugArangesOffset<R::Offset>,
102}
103
104impl<R: Reader> ArangeHeaderIter<R> {
105 /// Advance the iterator to the next header.
106 pub fn next(&mut self) -> Result<Option<ArangeHeader<R>>> {
107 if self.input.is_empty() {
108 return Ok(None);
109 }
110
111 let len: ::Offset = self.input.len();
112 match ArangeHeader::parse(&mut self.input, self.offset) {
113 Ok(header) => {
114 self.offset.0 += len - self.input.len();
115 Ok(Some(header))
116 }
117 Err(e) => {
118 self.input.empty();
119 Err(e)
120 }
121 }
122 }
123}
124
125#[cfg(feature = "fallible-iterator")]
126impl<R: Reader> fallible_iterator::FallibleIterator for ArangeHeaderIter<R> {
127 type Item = ArangeHeader<R>;
128 type Error = Error;
129
130 fn next(&mut self) -> ::core::result::Result<Option<Self::Item>, Self::Error> {
131 ArangeHeaderIter::next(self)
132 }
133}
134
135/// A header for a set of entries in the `.debug_arange` section.
136///
137/// These entries all belong to a single unit.
138#[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 segment_size: u8,
149 entries: R,
150}
151
152impl<R, Offset> ArangeHeader<R, Offset>
153where
154 R: Reader<Offset = Offset>,
155 Offset: ReaderOffset,
156{
157 fn parse(input: &mut R, offset: DebugArangesOffset<Offset>) -> Result<Self> {
158 let (length, format) = input.read_initial_length()?;
159 let mut rest = input.split(length)?;
160
161 // Check the version. The DWARF 5 spec says that this is always 2, but version 3
162 // has been observed in the wild, potentially due to a bug; see
163 // https://github.com/gimli-rs/gimli/issues/559 for more information.
164 // lldb allows versions 2 through 5, possibly by mistake.
165 let version = rest.read_u16()?;
166 if version != 2 && version != 3 {
167 return Err(Error::UnknownVersion(u64::from(version)));
168 }
169
170 let debug_info_offset = rest.read_offset(format).map(DebugInfoOffset)?;
171 let address_size = rest.read_u8()?;
172 let segment_size = rest.read_u8()?;
173
174 // unit_length + version + offset + address_size + segment_size
175 let header_length = format.initial_length_size() + 2 + format.word_size() + 1 + 1;
176
177 // The first tuple following the header in each set begins at an offset that is
178 // a multiple of the size of a single tuple (that is, the size of a segment selector
179 // plus twice the size of an address).
180 let tuple_length = address_size
181 .checked_mul(2)
182 .and_then(|x| x.checked_add(segment_size))
183 .ok_or(Error::InvalidAddressRange)?;
184 if tuple_length == 0 {
185 return Err(Error::InvalidAddressRange)?;
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 // TODO: segment_size
199 };
200 Ok(ArangeHeader {
201 offset,
202 encoding,
203 length,
204 debug_info_offset,
205 segment_size,
206 entries: rest,
207 })
208 }
209
210 /// Return the offset of this header within the `.debug_aranges` section.
211 #[inline]
212 pub fn offset(&self) -> DebugArangesOffset<Offset> {
213 self.offset
214 }
215
216 /// Return the length of this set of entries, including the header.
217 #[inline]
218 pub fn length(&self) -> Offset {
219 self.length
220 }
221
222 /// Return the encoding parameters for this set of entries.
223 #[inline]
224 pub fn encoding(&self) -> Encoding {
225 self.encoding
226 }
227
228 /// Return the segment size for this set of entries.
229 #[inline]
230 pub fn segment_size(&self) -> u8 {
231 self.segment_size
232 }
233
234 /// Return the offset into the .debug_info section for this set of arange entries.
235 #[inline]
236 pub fn debug_info_offset(&self) -> DebugInfoOffset<Offset> {
237 self.debug_info_offset
238 }
239
240 /// Return the arange entries in this set.
241 #[inline]
242 pub fn entries(&self) -> ArangeEntryIter<R> {
243 ArangeEntryIter {
244 input: self.entries.clone(),
245 encoding: self.encoding,
246 segment_size: self.segment_size,
247 }
248 }
249}
250
251/// An iterator over the aranges from a `.debug_aranges` section.
252///
253/// Can be [used with
254/// `FallibleIterator`](./index.html#using-with-fallibleiterator).
255#[derive(Debug, Clone)]
256pub struct ArangeEntryIter<R: Reader> {
257 input: R,
258 encoding: Encoding,
259 segment_size: u8,
260}
261
262impl<R: Reader> ArangeEntryIter<R> {
263 /// Advance the iterator and return the next arange.
264 ///
265 /// Returns the newly parsed arange as `Ok(Some(arange))`. Returns `Ok(None)`
266 /// when iteration is complete and all aranges have already been parsed and
267 /// yielded. If an error occurs while parsing the next arange, then this error
268 /// is returned as `Err(e)`, and all subsequent calls return `Ok(None)`.
269 pub fn next(&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, self.segment_size) {
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
288#[cfg(feature = "fallible-iterator")]
289impl<R: Reader> fallible_iterator::FallibleIterator for ArangeEntryIter<R> {
290 type Item = ArangeEntry;
291 type Error = Error;
292
293 fn next(&mut self) -> ::core::result::Result<Option<Self::Item>, Self::Error> {
294 ArangeEntryIter::next(self)
295 }
296}
297
298/// A single parsed arange.
299#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)]
300pub struct ArangeEntry {
301 segment: Option<u64>,
302 address: u64,
303 length: u64,
304}
305
306impl ArangeEntry {
307 /// Parse a single arange. Return `None` for the null arange, `Some` for an actual arange.
308 fn parse<R: Reader>(
309 input: &mut R,
310 encoding: Encoding,
311 segment_size: u8,
312 ) -> Result<Option<Self>> {
313 let address_size = encoding.address_size;
314
315 let tuple_length = R::Offset::from_u8(2 * address_size + segment_size);
316 if tuple_length > input.len() {
317 input.empty();
318 return Ok(None);
319 }
320
321 let segment = if segment_size != 0 {
322 input.read_address(segment_size)?
323 } else {
324 0
325 };
326 let address = input.read_address(address_size)?;
327 let length = input.read_address(address_size)?;
328
329 match (segment, address, length) {
330 // This is meant to be a null terminator, but in practice it can occur
331 // before the end, possibly due to a linker omitting a function and
332 // leaving an unrelocated entry.
333 (0, 0, 0) => Self::parse(input, encoding, segment_size),
334 _ => Ok(Some(ArangeEntry {
335 segment: if segment_size != 0 {
336 Some(segment)
337 } else {
338 None
339 },
340 address,
341 length,
342 })),
343 }
344 }
345
346 /// Return the segment selector of this arange.
347 #[inline]
348 pub fn segment(&self) -> Option<u64> {
349 self.segment
350 }
351
352 /// Return the beginning address of this arange.
353 #[inline]
354 pub fn address(&self) -> u64 {
355 self.address
356 }
357
358 /// Return the length of this arange.
359 #[inline]
360 pub fn length(&self) -> u64 {
361 self.length
362 }
363
364 /// Return the range.
365 #[inline]
366 pub fn range(&self) -> Range {
367 Range {
368 begin: self.address,
369 end: self.address.wrapping_add(self.length),
370 }
371 }
372}
373
374#[cfg(test)]
375mod tests {
376 use super::*;
377 use crate::common::{DebugInfoOffset, Format};
378 use crate::endianity::LittleEndian;
379 use crate::read::EndianSlice;
380
381 #[test]
382 fn test_iterate_headers() {
383 #[rustfmt::skip]
384 let buf = [
385 // 32-bit length = 28.
386 0x1c, 0x00, 0x00, 0x00,
387 // Version.
388 0x02, 0x00,
389 // Offset.
390 0x01, 0x02, 0x03, 0x04,
391 // Address size.
392 0x04,
393 // Segment size.
394 0x00,
395 // Dummy padding and arange tuples.
396 0x00, 0x00, 0x00, 0x00,
397 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
398 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
399
400 // 32-bit length = 36.
401 0x24, 0x00, 0x00, 0x00,
402 // Version.
403 0x02, 0x00,
404 // Offset.
405 0x11, 0x12, 0x13, 0x14,
406 // Address size.
407 0x04,
408 // Segment size.
409 0x00,
410 // Dummy padding and arange tuples.
411 0x00, 0x00, 0x00, 0x00,
412 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
413 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
414 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
415 ];
416
417 let debug_aranges = DebugAranges::new(&buf, LittleEndian);
418 let mut headers = debug_aranges.headers();
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(0));
425 assert_eq!(header.debug_info_offset(), DebugInfoOffset(0x0403_0201));
426
427 let header = headers
428 .next()
429 .expect("should parse header ok")
430 .expect("should have a header");
431 assert_eq!(header.offset(), DebugArangesOffset(0x20));
432 assert_eq!(header.debug_info_offset(), DebugInfoOffset(0x1413_1211));
433 }
434
435 #[test]
436 fn test_parse_header_ok() {
437 #[rustfmt::skip]
438 let buf = [
439 // 32-bit length = 32.
440 0x20, 0x00, 0x00, 0x00,
441 // Version.
442 0x02, 0x00,
443 // Offset.
444 0x01, 0x02, 0x03, 0x04,
445 // Address size.
446 0x08,
447 // Segment size.
448 0x04,
449 // Length to here = 12, tuple length = 20.
450 // Padding to tuple length multiple = 4.
451 0x10, 0x00, 0x00, 0x00,
452 0x00, 0x00, 0x00, 0x00,
453
454 // Dummy arange tuple data.
455 0x20, 0x00, 0x00, 0x00,
456 0x00, 0x00, 0x00, 0x00,
457 0x00, 0x00, 0x00, 0x00,
458 0x00, 0x00, 0x00, 0x00,
459
460 // Dummy next arange.
461 0x30, 0x00, 0x00, 0x00,
462 0x00, 0x00, 0x00, 0x00,
463 0x00, 0x00, 0x00, 0x00,
464 0x00, 0x00, 0x00, 0x00,
465 ];
466
467 let rest = &mut EndianSlice::new(&buf, LittleEndian);
468
469 let header =
470 ArangeHeader::parse(rest, DebugArangesOffset(0x10)).expect("should parse header ok");
471
472 assert_eq!(
473 *rest,
474 EndianSlice::new(&buf[buf.len() - 16..], LittleEndian)
475 );
476 assert_eq!(
477 header,
478 ArangeHeader {
479 offset: DebugArangesOffset(0x10),
480 encoding: Encoding {
481 format: Format::Dwarf32,
482 version: 2,
483 address_size: 8,
484 },
485 length: 0x20,
486 debug_info_offset: DebugInfoOffset(0x0403_0201),
487 segment_size: 4,
488 entries: EndianSlice::new(&buf[buf.len() - 32..buf.len() - 16], LittleEndian),
489 }
490 );
491 }
492
493 #[test]
494 fn test_parse_header_overflow_error() {
495 #[rustfmt::skip]
496 let buf = [
497 // 32-bit length = 32.
498 0x20, 0x00, 0x00, 0x00,
499 // Version.
500 0x02, 0x00,
501 // Offset.
502 0x01, 0x02, 0x03, 0x04,
503 // Address size.
504 0xff,
505 // Segment size.
506 0xff,
507 // Length to here = 12, tuple length = 20.
508 // Padding to tuple length multiple = 4.
509 0x10, 0x00, 0x00, 0x00,
510 0x00, 0x00, 0x00, 0x00,
511
512 // Dummy arange tuple data.
513 0x20, 0x00, 0x00, 0x00,
514 0x00, 0x00, 0x00, 0x00,
515 0x00, 0x00, 0x00, 0x00,
516 0x00, 0x00, 0x00, 0x00,
517
518 // Dummy next arange.
519 0x30, 0x00, 0x00, 0x00,
520 0x00, 0x00, 0x00, 0x00,
521 0x00, 0x00, 0x00, 0x00,
522 0x00, 0x00, 0x00, 0x00,
523 ];
524
525 let rest = &mut EndianSlice::new(&buf, LittleEndian);
526
527 let error = ArangeHeader::parse(rest, DebugArangesOffset(0x10))
528 .expect_err("should fail to parse header");
529 assert_eq!(error, Error::InvalidAddressRange);
530 }
531
532 #[test]
533 fn test_parse_header_div_by_zero_error() {
534 #[rustfmt::skip]
535 let buf = [
536 // 32-bit length = 32.
537 0x20, 0x00, 0x00, 0x00,
538 // Version.
539 0x02, 0x00,
540 // Offset.
541 0x01, 0x02, 0x03, 0x04,
542 // Address size = 0. Could cause a division by zero if we aren't
543 // careful.
544 0x00,
545 // Segment size.
546 0x00,
547 // Length to here = 12, tuple length = 20.
548 // Padding to tuple length multiple = 4.
549 0x10, 0x00, 0x00, 0x00,
550 0x00, 0x00, 0x00, 0x00,
551
552 // Dummy arange tuple data.
553 0x20, 0x00, 0x00, 0x00,
554 0x00, 0x00, 0x00, 0x00,
555 0x00, 0x00, 0x00, 0x00,
556 0x00, 0x00, 0x00, 0x00,
557
558 // Dummy next arange.
559 0x30, 0x00, 0x00, 0x00,
560 0x00, 0x00, 0x00, 0x00,
561 0x00, 0x00, 0x00, 0x00,
562 0x00, 0x00, 0x00, 0x00,
563 ];
564
565 let rest = &mut EndianSlice::new(&buf, LittleEndian);
566
567 let error = ArangeHeader::parse(rest, DebugArangesOffset(0x10))
568 .expect_err("should fail to parse header");
569 assert_eq!(error, Error::InvalidAddressRange);
570 }
571
572 #[test]
573 fn test_parse_entry_ok() {
574 let encoding = Encoding {
575 format: Format::Dwarf32,
576 version: 2,
577 address_size: 4,
578 };
579 let segment_size = 0;
580 let buf = [0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09];
581 let rest = &mut EndianSlice::new(&buf, LittleEndian);
582 let entry =
583 ArangeEntry::parse(rest, encoding, segment_size).expect("should parse entry ok");
584 assert_eq!(*rest, EndianSlice::new(&buf[buf.len() - 1..], LittleEndian));
585 assert_eq!(
586 entry,
587 Some(ArangeEntry {
588 segment: None,
589 address: 0x0403_0201,
590 length: 0x0807_0605,
591 })
592 );
593 }
594
595 #[test]
596 fn test_parse_entry_segment() {
597 let encoding = Encoding {
598 format: Format::Dwarf32,
599 version: 2,
600 address_size: 4,
601 };
602 let segment_size = 8;
603 #[rustfmt::skip]
604 let buf = [
605 // Segment.
606 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18,
607 // Address.
608 0x01, 0x02, 0x03, 0x04,
609 // Length.
610 0x05, 0x06, 0x07, 0x08,
611 // Next tuple.
612 0x09
613 ];
614 let rest = &mut EndianSlice::new(&buf, LittleEndian);
615 let entry =
616 ArangeEntry::parse(rest, encoding, segment_size).expect("should parse entry ok");
617 assert_eq!(*rest, EndianSlice::new(&buf[buf.len() - 1..], LittleEndian));
618 assert_eq!(
619 entry,
620 Some(ArangeEntry {
621 segment: Some(0x1817_1615_1413_1211),
622 address: 0x0403_0201,
623 length: 0x0807_0605,
624 })
625 );
626 }
627
628 #[test]
629 fn test_parse_entry_zero() {
630 let encoding = Encoding {
631 format: Format::Dwarf32,
632 version: 2,
633 address_size: 4,
634 };
635 let segment_size = 0;
636 #[rustfmt::skip]
637 let buf = [
638 // Zero tuple.
639 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
640 // Address.
641 0x01, 0x02, 0x03, 0x04,
642 // Length.
643 0x05, 0x06, 0x07, 0x08,
644 // Next tuple.
645 0x09
646 ];
647 let rest = &mut EndianSlice::new(&buf, LittleEndian);
648 let entry =
649 ArangeEntry::parse(rest, encoding, segment_size).expect("should parse entry ok");
650 assert_eq!(*rest, EndianSlice::new(&buf[buf.len() - 1..], LittleEndian));
651 assert_eq!(
652 entry,
653 Some(ArangeEntry {
654 segment: None,
655 address: 0x0403_0201,
656 length: 0x0807_0605,
657 })
658 );
659 }
660}
661