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         let version = rest.read_u16()?;
162         if version != 2 {
163             return Err(Error::UnknownVersion(u64::from(version)));
164         }
165 
166         let debug_info_offset = rest.read_offset(format).map(DebugInfoOffset)?;
167         let address_size = rest.read_u8()?;
168         let segment_size = rest.read_u8()?;
169 
170         // unit_length + version + offset + address_size + segment_size
171         let header_length = format.initial_length_size() + 2 + format.word_size() + 1 + 1;
172 
173         // The first tuple following the header in each set begins at an offset that is
174         // a multiple of the size of a single tuple (that is, the size of a segment selector
175         // plus twice the size of an address).
176         let tuple_length = address_size
177             .checked_mul(2)
178             .and_then(|x| x.checked_add(segment_size))
179             .ok_or(Error::InvalidAddressRange)?;
180         if tuple_length == 0 {
181             return Err(Error::InvalidAddressRange)?;
182         }
183         let padding = if header_length % tuple_length == 0 {
184             0
185         } else {
186             tuple_length - header_length % tuple_length
187         };
188         rest.skip(R::Offset::from_u8(padding))?;
189 
190         let encoding = Encoding {
191             format,
192             version,
193             address_size,
194             // TODO: segment_size
195         };
196         Ok(ArangeHeader {
197             offset,
198             encoding,
199             length,
200             debug_info_offset,
201             segment_size,
202             entries: rest,
203         })
204     }
205 
206     /// Return the offset of this header within the `.debug_aranges` section.
207     #[inline]
offset(&self) -> DebugArangesOffset<Offset>208     pub fn offset(&self) -> DebugArangesOffset<Offset> {
209         self.offset
210     }
211 
212     /// Return the length of this set of entries, including the header.
213     #[inline]
length(&self) -> Offset214     pub fn length(&self) -> Offset {
215         self.length
216     }
217 
218     /// Return the encoding parameters for this set of entries.
219     #[inline]
encoding(&self) -> Encoding220     pub fn encoding(&self) -> Encoding {
221         self.encoding
222     }
223 
224     /// Return the segment size for this set of entries.
225     #[inline]
segment_size(&self) -> u8226     pub fn segment_size(&self) -> u8 {
227         self.segment_size
228     }
229 
230     /// Return the offset into the .debug_info section for this set of arange entries.
231     #[inline]
debug_info_offset(&self) -> DebugInfoOffset<Offset>232     pub fn debug_info_offset(&self) -> DebugInfoOffset<Offset> {
233         self.debug_info_offset
234     }
235 
236     /// Return the arange entries in this set.
237     #[inline]
entries(&self) -> ArangeEntryIter<R>238     pub fn entries(&self) -> ArangeEntryIter<R> {
239         ArangeEntryIter {
240             input: self.entries.clone(),
241             encoding: self.encoding,
242             segment_size: self.segment_size,
243         }
244     }
245 }
246 
247 /// An iterator over the aranges from a `.debug_aranges` section.
248 ///
249 /// Can be [used with
250 /// `FallibleIterator`](./index.html#using-with-fallibleiterator).
251 #[derive(Debug, Clone)]
252 pub struct ArangeEntryIter<R: Reader> {
253     input: R,
254     encoding: Encoding,
255     segment_size: u8,
256 }
257 
258 impl<R: Reader> ArangeEntryIter<R> {
259     /// Advance the iterator and return the next arange.
260     ///
261     /// Returns the newly parsed arange as `Ok(Some(arange))`. Returns `Ok(None)`
262     /// when iteration is complete and all aranges have already been parsed and
263     /// yielded. If an error occurs while parsing the next arange, then this error
264     /// is returned as `Err(e)`, and all subsequent calls return `Ok(None)`.
next(&mut self) -> Result<Option<ArangeEntry>>265     pub fn next(&mut self) -> Result<Option<ArangeEntry>> {
266         if self.input.is_empty() {
267             return Ok(None);
268         }
269 
270         match ArangeEntry::parse(&mut self.input, self.encoding, self.segment_size) {
271             Ok(Some(entry)) => Ok(Some(entry)),
272             Ok(None) => {
273                 self.input.empty();
274                 Ok(None)
275             }
276             Err(e) => {
277                 self.input.empty();
278                 Err(e)
279             }
280         }
281     }
282 }
283 
284 #[cfg(feature = "fallible-iterator")]
285 impl<R: Reader> fallible_iterator::FallibleIterator for ArangeEntryIter<R> {
286     type Item = ArangeEntry;
287     type Error = Error;
288 
next(&mut self) -> ::core::result::Result<Option<Self::Item>, Self::Error>289     fn next(&mut self) -> ::core::result::Result<Option<Self::Item>, Self::Error> {
290         ArangeEntryIter::next(self)
291     }
292 }
293 
294 /// A single parsed arange.
295 #[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)]
296 pub struct ArangeEntry {
297     segment: Option<u64>,
298     address: u64,
299     length: u64,
300 }
301 
302 impl ArangeEntry {
303     /// 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>>304     fn parse<R: Reader>(
305         input: &mut R,
306         encoding: Encoding,
307         segment_size: u8,
308     ) -> Result<Option<Self>> {
309         let address_size = encoding.address_size;
310 
311         let tuple_length = R::Offset::from_u8(2 * address_size + segment_size);
312         if tuple_length > input.len() {
313             input.empty();
314             return Ok(None);
315         }
316 
317         let segment = if segment_size != 0 {
318             input.read_address(segment_size)?
319         } else {
320             0
321         };
322         let address = input.read_address(address_size)?;
323         let length = input.read_address(address_size)?;
324 
325         match (segment, address, length) {
326             // This is meant to be a null terminator, but in practice it can occur
327             // before the end, possibly due to a linker omitting a function and
328             // leaving an unrelocated entry.
329             (0, 0, 0) => Self::parse(input, encoding, segment_size),
330             _ => Ok(Some(ArangeEntry {
331                 segment: if segment_size != 0 {
332                     Some(segment)
333                 } else {
334                     None
335                 },
336                 address,
337                 length,
338             })),
339         }
340     }
341 
342     /// Return the segment selector of this arange.
343     #[inline]
segment(&self) -> Option<u64>344     pub fn segment(&self) -> Option<u64> {
345         self.segment
346     }
347 
348     /// Return the beginning address of this arange.
349     #[inline]
address(&self) -> u64350     pub fn address(&self) -> u64 {
351         self.address
352     }
353 
354     /// Return the length of this arange.
355     #[inline]
length(&self) -> u64356     pub fn length(&self) -> u64 {
357         self.length
358     }
359 
360     /// Return the range.
361     #[inline]
range(&self) -> Range362     pub fn range(&self) -> Range {
363         Range {
364             begin: self.address,
365             end: self.address.wrapping_add(self.length),
366         }
367     }
368 }
369 
370 #[cfg(test)]
371 mod tests {
372     use super::*;
373     use crate::common::{DebugInfoOffset, Format};
374     use crate::endianity::LittleEndian;
375     use crate::read::EndianSlice;
376 
377     #[test]
test_iterate_headers()378     fn test_iterate_headers() {
379         #[rustfmt::skip]
380         let buf = [
381             // 32-bit length = 28.
382             0x1c, 0x00, 0x00, 0x00,
383             // Version.
384             0x02, 0x00,
385             // Offset.
386             0x01, 0x02, 0x03, 0x04,
387             // Address size.
388             0x04,
389             // Segment size.
390             0x00,
391             // Dummy padding and arange tuples.
392             0x00, 0x00, 0x00, 0x00,
393             0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
394             0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
395 
396             // 32-bit length = 36.
397             0x24, 0x00, 0x00, 0x00,
398             // Version.
399             0x02, 0x00,
400             // Offset.
401             0x11, 0x12, 0x13, 0x14,
402             // Address size.
403             0x04,
404             // Segment size.
405             0x00,
406             // Dummy padding and arange tuples.
407             0x00, 0x00, 0x00, 0x00,
408             0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
409             0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
410             0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
411         ];
412 
413         let debug_aranges = DebugAranges::new(&buf, LittleEndian);
414         let mut headers = debug_aranges.headers();
415 
416         let header = headers
417             .next()
418             .expect("should parse header ok")
419             .expect("should have a header");
420         assert_eq!(header.offset(), DebugArangesOffset(0));
421         assert_eq!(header.debug_info_offset(), DebugInfoOffset(0x0403_0201));
422 
423         let header = headers
424             .next()
425             .expect("should parse header ok")
426             .expect("should have a header");
427         assert_eq!(header.offset(), DebugArangesOffset(0x20));
428         assert_eq!(header.debug_info_offset(), DebugInfoOffset(0x1413_1211));
429     }
430 
431     #[test]
test_parse_header_ok()432     fn test_parse_header_ok() {
433         #[rustfmt::skip]
434         let buf = [
435             // 32-bit length = 32.
436             0x20, 0x00, 0x00, 0x00,
437             // Version.
438             0x02, 0x00,
439             // Offset.
440             0x01, 0x02, 0x03, 0x04,
441             // Address size.
442             0x08,
443             // Segment size.
444             0x04,
445             // Length to here = 12, tuple length = 20.
446             // Padding to tuple length multiple = 4.
447             0x10, 0x00, 0x00, 0x00,
448             0x00, 0x00, 0x00, 0x00,
449 
450             // Dummy arange tuple data.
451             0x20, 0x00, 0x00, 0x00,
452             0x00, 0x00, 0x00, 0x00,
453             0x00, 0x00, 0x00, 0x00,
454             0x00, 0x00, 0x00, 0x00,
455 
456             // Dummy next arange.
457             0x30, 0x00, 0x00, 0x00,
458             0x00, 0x00, 0x00, 0x00,
459             0x00, 0x00, 0x00, 0x00,
460             0x00, 0x00, 0x00, 0x00,
461         ];
462 
463         let rest = &mut EndianSlice::new(&buf, LittleEndian);
464 
465         let header =
466             ArangeHeader::parse(rest, DebugArangesOffset(0x10)).expect("should parse header ok");
467 
468         assert_eq!(
469             *rest,
470             EndianSlice::new(&buf[buf.len() - 16..], LittleEndian)
471         );
472         assert_eq!(
473             header,
474             ArangeHeader {
475                 offset: DebugArangesOffset(0x10),
476                 encoding: Encoding {
477                     format: Format::Dwarf32,
478                     version: 2,
479                     address_size: 8,
480                 },
481                 length: 0x20,
482                 debug_info_offset: DebugInfoOffset(0x0403_0201),
483                 segment_size: 4,
484                 entries: EndianSlice::new(&buf[buf.len() - 32..buf.len() - 16], LittleEndian),
485             }
486         );
487     }
488 
489     #[test]
test_parse_header_overflow_error()490     fn test_parse_header_overflow_error() {
491         #[rustfmt::skip]
492         let buf = [
493             // 32-bit length = 32.
494             0x20, 0x00, 0x00, 0x00,
495             // Version.
496             0x02, 0x00,
497             // Offset.
498             0x01, 0x02, 0x03, 0x04,
499             // Address size.
500             0xff,
501             // Segment size.
502             0xff,
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::InvalidAddressRange);
526     }
527 
528     #[test]
test_parse_header_div_by_zero_error()529     fn test_parse_header_div_by_zero_error() {
530         #[rustfmt::skip]
531         let buf = [
532             // 32-bit length = 32.
533             0x20, 0x00, 0x00, 0x00,
534             // Version.
535             0x02, 0x00,
536             // Offset.
537             0x01, 0x02, 0x03, 0x04,
538             // Address size = 0. Could cause a division by zero if we aren't
539             // careful.
540             0x00,
541             // Segment size.
542             0x00,
543             // Length to here = 12, tuple length = 20.
544             // Padding to tuple length multiple = 4.
545             0x10, 0x00, 0x00, 0x00,
546             0x00, 0x00, 0x00, 0x00,
547 
548             // Dummy arange tuple data.
549             0x20, 0x00, 0x00, 0x00,
550             0x00, 0x00, 0x00, 0x00,
551             0x00, 0x00, 0x00, 0x00,
552             0x00, 0x00, 0x00, 0x00,
553 
554             // Dummy next arange.
555             0x30, 0x00, 0x00, 0x00,
556             0x00, 0x00, 0x00, 0x00,
557             0x00, 0x00, 0x00, 0x00,
558             0x00, 0x00, 0x00, 0x00,
559         ];
560 
561         let rest = &mut EndianSlice::new(&buf, LittleEndian);
562 
563         let error = ArangeHeader::parse(rest, DebugArangesOffset(0x10))
564             .expect_err("should fail to parse header");
565         assert_eq!(error, Error::InvalidAddressRange);
566     }
567 
568     #[test]
test_parse_entry_ok()569     fn test_parse_entry_ok() {
570         let encoding = Encoding {
571             format: Format::Dwarf32,
572             version: 2,
573             address_size: 4,
574         };
575         let segment_size = 0;
576         let buf = [0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09];
577         let rest = &mut EndianSlice::new(&buf, LittleEndian);
578         let entry =
579             ArangeEntry::parse(rest, encoding, segment_size).expect("should parse entry ok");
580         assert_eq!(*rest, EndianSlice::new(&buf[buf.len() - 1..], LittleEndian));
581         assert_eq!(
582             entry,
583             Some(ArangeEntry {
584                 segment: None,
585                 address: 0x0403_0201,
586                 length: 0x0807_0605,
587             })
588         );
589     }
590 
591     #[test]
test_parse_entry_segment()592     fn test_parse_entry_segment() {
593         let encoding = Encoding {
594             format: Format::Dwarf32,
595             version: 2,
596             address_size: 4,
597         };
598         let segment_size = 8;
599         #[rustfmt::skip]
600         let buf = [
601             // Segment.
602             0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18,
603             // Address.
604             0x01, 0x02, 0x03, 0x04,
605             // Length.
606             0x05, 0x06, 0x07, 0x08,
607             // Next tuple.
608             0x09
609         ];
610         let rest = &mut EndianSlice::new(&buf, LittleEndian);
611         let entry =
612             ArangeEntry::parse(rest, encoding, segment_size).expect("should parse entry ok");
613         assert_eq!(*rest, EndianSlice::new(&buf[buf.len() - 1..], LittleEndian));
614         assert_eq!(
615             entry,
616             Some(ArangeEntry {
617                 segment: Some(0x1817_1615_1413_1211),
618                 address: 0x0403_0201,
619                 length: 0x0807_0605,
620             })
621         );
622     }
623 
624     #[test]
test_parse_entry_zero()625     fn test_parse_entry_zero() {
626         let encoding = Encoding {
627             format: Format::Dwarf32,
628             version: 2,
629             address_size: 4,
630         };
631         let segment_size = 0;
632         #[rustfmt::skip]
633         let buf = [
634             // Zero tuple.
635             0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
636             // Address.
637             0x01, 0x02, 0x03, 0x04,
638             // Length.
639             0x05, 0x06, 0x07, 0x08,
640             // Next tuple.
641             0x09
642         ];
643         let rest = &mut EndianSlice::new(&buf, LittleEndian);
644         let entry =
645             ArangeEntry::parse(rest, encoding, segment_size).expect("should parse entry ok");
646         assert_eq!(*rest, EndianSlice::new(&buf[buf.len() - 1..], LittleEndian));
647         assert_eq!(
648             entry,
649             Some(ArangeEntry {
650                 segment: None,
651                 address: 0x0403_0201,
652                 length: 0x0807_0605,
653             })
654         );
655     }
656 }
657