gimli/read/
aranges.rs

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/// The `DebugAranges` struct represents the DWARF address range information
8/// found in the `.debug_aranges` section.
9#[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    /// Construct a new `DebugAranges` instance from the data in the `.debug_aranges`
19    /// section.
20    ///
21    /// It is the caller's responsibility to read the `.debug_aranges` section and
22    /// present it as a `&[u8]` slice. That means using some ELF loader on
23    /// Linux, a Mach-O loader on macOS, etc.
24    ///
25    /// ```
26    /// use gimli::{DebugAranges, LittleEndian};
27    ///
28    /// # let buf = [];
29    /// # let read_debug_aranges_section = || &buf;
30    /// let debug_aranges =
31    ///     DebugAranges::new(read_debug_aranges_section(), LittleEndian);
32    /// ```
33    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    /// Iterate the sets of entries in the `.debug_aranges` section.
42    ///
43    /// Each set of entries belongs to a single unit.
44    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    /// Get the header at the given offset.
52    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    /// Create a `DebugAranges` section that references the data in `self`.
61    ///
62    /// This is useful when `R` implements `Reader` but `T` does not.
63    ///
64    /// Used by `DwarfSections::borrow`.
65    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/// An iterator over the headers of a `.debug_aranges` section.
90#[derive(Clone, Debug)]
91pub struct ArangeHeaderIter<R: Reader> {
92    input: R,
93    offset: DebugArangesOffset<R::Offset>,
94}
95
96impl<R: Reader> ArangeHeaderIter<R> {
97    /// Advance the iterator to the next header.
98    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/// A header for a set of entries in the `.debug_arange` section.
128///
129/// These entries all belong to a single unit.
130#[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        // Check the version. The DWARF 5 spec says that this is always 2, but version 3
153        // has been observed in the wild, potentially due to a bug; see
154        // https://github.com/gimli-rs/gimli/issues/559 for more information.
155        // lldb allows versions 2 through 5, possibly by mistake.
156        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        // unit_length + version + offset + address_size + segment_size
169        let header_length = format.initial_length_size() + 2 + format.word_size() + 1 + 1;
170
171        // The first tuple following the header in each set begins at an offset that is
172        // a multiple of the size of a single tuple (that is, twice the size of an address).
173        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    /// Return the offset of this header within the `.debug_aranges` section.
201    #[inline]
202    pub fn offset(&self) -> DebugArangesOffset<Offset> {
203        self.offset
204    }
205
206    /// Return the length of this set of entries, including the header.
207    #[inline]
208    pub fn length(&self) -> Offset {
209        self.length
210    }
211
212    /// Return the encoding parameters for this set of entries.
213    #[inline]
214    pub fn encoding(&self) -> Encoding {
215        self.encoding
216    }
217
218    /// Return the offset into the .debug_info section for this set of arange entries.
219    #[inline]
220    pub fn debug_info_offset(&self) -> DebugInfoOffset<Offset> {
221        self.debug_info_offset
222    }
223
224    /// Return the arange entries in this set.
225    #[inline]
226    pub fn entries(&self) -> ArangeEntryIter<R> {
227        ArangeEntryIter {
228            input: self.entries.clone(),
229            encoding: self.encoding,
230        }
231    }
232}
233
234/// An iterator over the aranges from a `.debug_aranges` section.
235///
236/// Can be [used with
237/// `FallibleIterator`](./index.html#using-with-fallibleiterator).
238#[derive(Debug, Clone)]
239pub struct ArangeEntryIter<R: Reader> {
240    input: R,
241    encoding: Encoding,
242}
243
244impl<R: Reader> ArangeEntryIter<R> {
245    /// Advance the iterator and return the next arange.
246    ///
247    /// Returns the newly parsed arange as `Ok(Some(arange))`. Returns `Ok(None)`
248    /// when iteration is complete and all aranges have already been parsed and
249    /// yielded. If an error occurs while parsing the next arange, then this error
250    /// is returned as `Err(e)`, and all subsequent calls return `Ok(None)`.
251    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/// A single parsed arange.
281#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)]
282pub struct ArangeEntry {
283    range: Range,
284    length: u64,
285}
286
287impl ArangeEntry {
288    /// Parse a single arange. Return `None` for the null arange, `Some` for an actual arange.
289    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        // Calculate end now so that we can handle overflow.
301        let end = begin.add_sized(length, address_size)?;
302        let range = Range { begin, end };
303
304        match (begin, length) {
305            // This is meant to be a null terminator, but in practice it can occur
306            // before the end, possibly due to a linker omitting a function and
307            // leaving an unrelocated entry.
308            (0, 0) => Self::parse(input, encoding),
309            _ => Ok(Some(ArangeEntry { range, length })),
310        }
311    }
312
313    /// Return the beginning address of this arange.
314    #[inline]
315    pub fn address(&self) -> u64 {
316        self.range.begin
317    }
318
319    /// Return the length of this arange.
320    #[inline]
321    pub fn length(&self) -> u64 {
322        self.length
323    }
324
325    /// Return the range.
326    #[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            // 32-bit length = 28.
344            0x1c, 0x00, 0x00, 0x00,
345            // Version.
346            0x02, 0x00,
347            // Offset.
348            0x01, 0x02, 0x03, 0x04,
349            // Address size.
350            0x04,
351            // Segment size.
352            0x00,
353            // Dummy padding and arange tuples.
354            0x00, 0x00, 0x00, 0x00,
355            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
356            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
357
358            // 32-bit length = 36.
359            0x24, 0x00, 0x00, 0x00,
360            // Version.
361            0x02, 0x00,
362            // Offset.
363            0x11, 0x12, 0x13, 0x14,
364            // Address size.
365            0x04,
366            // Segment size.
367            0x00,
368            // Dummy padding and arange tuples.
369            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            // 32-bit length = 28 (8 bytes header, 4 bytes padding, 16 bytes tuple data).
398            0x1c, 0x00, 0x00, 0x00,
399            // Version.
400            0x02, 0x00,
401            // Offset.
402            0x01, 0x02, 0x03, 0x04,
403            // Address size.
404            0x08,
405            // Segment size.
406            0x00,
407            // Length to here = 12, tuple length = 16.
408            // Padding to tuple length multiple = 4.
409            0x10, 0x00, 0x00, 0x00,
410
411            // Dummy arange tuple data.
412            0x20, 0x00, 0x00, 0x00,
413            0x00, 0x00, 0x00, 0x00,
414            0x00, 0x00, 0x00, 0x00,
415            0x00, 0x00, 0x00, 0x00,
416
417            // Dummy next arange.
418            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            // 32-bit length = 32.
454            0x20, 0x00, 0x00, 0x00,
455            // Version.
456            0x02, 0x00,
457            // Offset.
458            0x01, 0x02, 0x03, 0x04,
459            // Address size.
460            0xff,
461            // Segment size.
462            0x00,
463            // Length to here = 12, tuple length = 20.
464            // Padding to tuple length multiple = 4.
465            0x10, 0x00, 0x00, 0x00,
466            0x00, 0x00, 0x00, 0x00,
467
468            // Dummy arange tuple data.
469            0x20, 0x00, 0x00, 0x00,
470            0x00, 0x00, 0x00, 0x00,
471            0x00, 0x00, 0x00, 0x00,
472            0x00, 0x00, 0x00, 0x00,
473
474            // Dummy next arange.
475            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            // 32-bit length = 32.
493            0x20, 0x00, 0x00, 0x00,
494            // Version.
495            0x02, 0x00,
496            // Offset.
497            0x01, 0x02, 0x03, 0x04,
498            // Address size = 0. Could cause a division by zero if we aren't
499            // careful.
500            0x00,
501            // Segment size.
502            0x00,
503            // Length to here = 12, tuple length = 20.
504            // Padding to tuple length multiple = 4.
505            0x10, 0x00, 0x00, 0x00,
506            0x00, 0x00, 0x00, 0x00,
507
508            // Dummy arange tuple data.
509            0x20, 0x00, 0x00, 0x00,
510            0x00, 0x00, 0x00, 0x00,
511            0x00, 0x00, 0x00, 0x00,
512            0x00, 0x00, 0x00, 0x00,
513
514            // Dummy next arange.
515            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            // Zero tuple.
561            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
562            // Address.
563            0x01, 0x02, 0x03, 0x04,
564            // Length.
565            0x05, 0x06, 0x07, 0x08,
566            // Next tuple.
567            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            // Address.
594            0x01, 0x02, 0x03, 0x84,
595            // Length.
596            0x05, 0x06, 0x07, 0x88,
597            // Next tuple.
598            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            // Address.
616            0x01, 0x02, 0x03, 0x04, 0x00, 0x00, 0x00, 0x80,
617            // Length.
618            0x05, 0x06, 0x07, 0x08, 0x00, 0x00, 0x00, 0x80,
619            // Next tuple.
620            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}