1 use crate::common::{DebugArangesOffset, DebugInfoOffset, Encoding, SectionId};
2 use crate::endianity::Endianity;
3 use 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)]
8 pub struct DebugAranges<R> {
9     section: R,
10 }
11 
12 impl<'input, Endian> DebugAranges<EndianSlice<'input, Endian>>
13 where
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 OSX, 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     /// ```
new(section: &'input [u8], endian: Endian) -> Self31     pub fn new(section: &'input [u8], endian: Endian) -> Self {
32         DebugAranges {
33             section: EndianSlice::new(section, endian),
34         }
35     }
36 }
37 
38 impl<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.
headers(&self) -> ArangeHeaderIter<R>42     pub fn headers(&self) -> ArangeHeaderIter<R> {
43         ArangeHeaderIter {
44             input: self.section.clone(),
45             offset: DebugArangesOffset(R::Offset::from_u8(0)),
46         }
47     }
48 
49     /// Get the header at the given offset.
header(&self, offset: DebugArangesOffset<R::Offset>) -> Result<ArangeHeader<R>>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 
57 impl<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     /// ```
borrow<'a, F, R>(&'a self, mut borrow: F) -> DebugAranges<R> where F: FnMut(&'a T) -> R,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 
81 impl<R> Section<R> for DebugAranges<R> {
id() -> SectionId82     fn id() -> SectionId {
83         SectionId::DebugAranges
84     }
85 
reader(&self) -> &R86     fn reader(&self) -> &R {
87         &self.section
88     }
89 }
90 
91 impl<R> From<R> for DebugAranges<R> {
from(section: R) -> Self92     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)]
99 pub struct ArangeHeaderIter<R: Reader> {
100     input: R,
101     offset: DebugArangesOffset<R::Offset>,
102 }
103 
104 impl<R: Reader> ArangeHeaderIter<R> {
105     /// Advance the iterator to the next header.
next(&mut self) -> Result<Option<ArangeHeader<R>>>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 = 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")]
126 impl<R: Reader> fallible_iterator::FallibleIterator for ArangeHeaderIter<R> {
127     type Item = ArangeHeader<R>;
128     type Error = Error;
129 
next(&mut self) -> ::core::result::Result<Option<Self::Item>, Self::Error>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)]
139 pub struct ArangeHeader<R, Offset = <R as Reader>::Offset>
140 where
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 
152 impl<R, Offset> ArangeHeader<R, Offset>
153 where
154     R: Reader<Offset = Offset>,
155     Offset: ReaderOffset,
156 {
parse(input: &mut R, offset: DebugArangesOffset<Offset>) -> Result<Self>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]
offset(&self) -> DebugArangesOffset<Offset>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]
length(&self) -> Offset218     pub fn length(&self) -> Offset {
219         self.length
220     }
221 
222     /// Return the encoding parameters for this set of entries.
223     #[inline]
encoding(&self) -> Encoding224     pub fn encoding(&self) -> Encoding {
225         self.encoding
226     }
227 
228     /// Return the segment size for this set of entries.
229     #[inline]
segment_size(&self) -> u8230     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]
debug_info_offset(&self) -> DebugInfoOffset<Offset>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]
entries(&self) -> ArangeEntryIter<R>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)]
256 pub struct ArangeEntryIter<R: Reader> {
257     input: R,
258     encoding: Encoding,
259     segment_size: u8,
260 }
261 
262 impl<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)`.
next(&mut self) -> Result<Option<ArangeEntry>>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")]
289 impl<R: Reader> fallible_iterator::FallibleIterator for ArangeEntryIter<R> {
290     type Item = ArangeEntry;
291     type Error = Error;
292 
next(&mut self) -> ::core::result::Result<Option<Self::Item>, Self::Error>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)]
300 pub struct ArangeEntry {
301     segment: Option<u64>,
302     address: u64,
303     length: u64,
304 }
305 
306 impl ArangeEntry {
307     /// Parse a single arange. Return `None` for the null arange, `Some` for an actual arange.
parse<R: Reader>( input: &mut R, encoding: Encoding, segment_size: u8, ) -> Result<Option<Self>>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]
segment(&self) -> Option<u64>348     pub fn segment(&self) -> Option<u64> {
349         self.segment
350     }
351 
352     /// Return the beginning address of this arange.
353     #[inline]
address(&self) -> u64354     pub fn address(&self) -> u64 {
355         self.address
356     }
357 
358     /// Return the length of this arange.
359     #[inline]
length(&self) -> u64360     pub fn length(&self) -> u64 {
361         self.length
362     }
363 
364     /// Return the range.
365     #[inline]
range(&self) -> Range366     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)]
375 mod tests {
376     use super::*;
377     use crate::common::{DebugInfoOffset, Format};
378     use crate::endianity::LittleEndian;
379     use crate::read::EndianSlice;
380 
381     #[test]
test_iterate_headers()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]
test_parse_header_ok()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]
test_parse_header_overflow_error()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]
test_parse_header_div_by_zero_error()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]
test_parse_entry_ok()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]
test_parse_entry_segment()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]
test_parse_entry_zero()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