1 use crate::common::{
2     DebugAddrBase, DebugAddrIndex, DebugRngListsBase, DebugRngListsIndex, DwarfFileType, Encoding,
3     RangeListsOffset, SectionId,
4 };
5 use crate::constants;
6 use crate::endianity::Endianity;
7 use crate::read::{
8     lists::ListsHeader, DebugAddr, EndianSlice, Error, Reader, ReaderOffset, ReaderOffsetId,
9     Result, Section,
10 };
11 
12 /// The raw contents of the `.debug_ranges` section.
13 #[derive(Debug, Default, Clone, Copy)]
14 pub struct DebugRanges<R> {
15     pub(crate) section: R,
16 }
17 
18 impl<'input, Endian> DebugRanges<EndianSlice<'input, Endian>>
19 where
20     Endian: Endianity,
21 {
22     /// Construct a new `DebugRanges` instance from the data in the `.debug_ranges`
23     /// section.
24     ///
25     /// It is the caller's responsibility to read the `.debug_ranges` section and
26     /// present it as a `&[u8]` slice. That means using some ELF loader on
27     /// Linux, a Mach-O loader on OSX, etc.
28     ///
29     /// ```
30     /// use gimli::{DebugRanges, LittleEndian};
31     ///
32     /// # let buf = [0x00, 0x01, 0x02, 0x03];
33     /// # let read_debug_ranges_section_somehow = || &buf;
34     /// let debug_ranges = DebugRanges::new(read_debug_ranges_section_somehow(), LittleEndian);
35     /// ```
new(section: &'input [u8], endian: Endian) -> Self36     pub fn new(section: &'input [u8], endian: Endian) -> Self {
37         Self::from(EndianSlice::new(section, endian))
38     }
39 }
40 
41 impl<R> Section<R> for DebugRanges<R> {
id() -> SectionId42     fn id() -> SectionId {
43         SectionId::DebugRanges
44     }
45 
reader(&self) -> &R46     fn reader(&self) -> &R {
47         &self.section
48     }
49 }
50 
51 impl<R> From<R> for DebugRanges<R> {
from(section: R) -> Self52     fn from(section: R) -> Self {
53         DebugRanges { section }
54     }
55 }
56 
57 /// The `DebugRngLists` struct represents the contents of the
58 /// `.debug_rnglists` section.
59 #[derive(Debug, Default, Clone, Copy)]
60 pub struct DebugRngLists<R> {
61     section: R,
62 }
63 
64 impl<'input, Endian> DebugRngLists<EndianSlice<'input, Endian>>
65 where
66     Endian: Endianity,
67 {
68     /// Construct a new `DebugRngLists` instance from the data in the
69     /// `.debug_rnglists` section.
70     ///
71     /// It is the caller's responsibility to read the `.debug_rnglists`
72     /// section and present it as a `&[u8]` slice. That means using some ELF
73     /// loader on Linux, a Mach-O loader on OSX, etc.
74     ///
75     /// ```
76     /// use gimli::{DebugRngLists, LittleEndian};
77     ///
78     /// # let buf = [0x00, 0x01, 0x02, 0x03];
79     /// # let read_debug_rnglists_section_somehow = || &buf;
80     /// let debug_rnglists =
81     ///     DebugRngLists::new(read_debug_rnglists_section_somehow(), LittleEndian);
82     /// ```
new(section: &'input [u8], endian: Endian) -> Self83     pub fn new(section: &'input [u8], endian: Endian) -> Self {
84         Self::from(EndianSlice::new(section, endian))
85     }
86 }
87 
88 impl<R> Section<R> for DebugRngLists<R> {
id() -> SectionId89     fn id() -> SectionId {
90         SectionId::DebugRngLists
91     }
92 
reader(&self) -> &R93     fn reader(&self) -> &R {
94         &self.section
95     }
96 }
97 
98 impl<R> From<R> for DebugRngLists<R> {
from(section: R) -> Self99     fn from(section: R) -> Self {
100         DebugRngLists { section }
101     }
102 }
103 
104 #[allow(unused)]
105 pub(crate) type RngListsHeader = ListsHeader;
106 
107 impl<Offset> DebugRngListsBase<Offset>
108 where
109     Offset: ReaderOffset,
110 {
111     /// Returns a `DebugRngListsBase` with the default value of DW_AT_rnglists_base
112     /// for the given `Encoding` and `DwarfFileType`.
default_for_encoding_and_file( encoding: Encoding, file_type: DwarfFileType, ) -> DebugRngListsBase<Offset>113     pub fn default_for_encoding_and_file(
114         encoding: Encoding,
115         file_type: DwarfFileType,
116     ) -> DebugRngListsBase<Offset> {
117         if encoding.version >= 5 && file_type == DwarfFileType::Dwo {
118             // In .dwo files, the compiler omits the DW_AT_rnglists_base attribute (because there is
119             // only a single unit in the file) but we must skip past the header, which the attribute
120             // would normally do for us.
121             DebugRngListsBase(Offset::from_u8(RngListsHeader::size_for_encoding(encoding)))
122         } else {
123             DebugRngListsBase(Offset::from_u8(0))
124         }
125     }
126 }
127 
128 /// The DWARF data found in `.debug_ranges` and `.debug_rnglists` sections.
129 #[derive(Debug, Default, Clone, Copy)]
130 pub struct RangeLists<R> {
131     debug_ranges: DebugRanges<R>,
132     debug_rnglists: DebugRngLists<R>,
133 }
134 
135 impl<R> RangeLists<R> {
136     /// Construct a new `RangeLists` instance from the data in the `.debug_ranges` and
137     /// `.debug_rnglists` sections.
new(debug_ranges: DebugRanges<R>, debug_rnglists: DebugRngLists<R>) -> RangeLists<R>138     pub fn new(debug_ranges: DebugRanges<R>, debug_rnglists: DebugRngLists<R>) -> RangeLists<R> {
139         RangeLists {
140             debug_ranges,
141             debug_rnglists,
142         }
143     }
144 
145     /// Return the `.debug_ranges` section.
debug_ranges(&self) -> &DebugRanges<R>146     pub fn debug_ranges(&self) -> &DebugRanges<R> {
147         &self.debug_ranges
148     }
149 
150     /// Replace the `.debug_ranges` section.
151     ///
152     /// This is useful for `.dwo` files when using the GNU split-dwarf extension to DWARF 4.
set_debug_ranges(&mut self, debug_ranges: DebugRanges<R>)153     pub fn set_debug_ranges(&mut self, debug_ranges: DebugRanges<R>) {
154         self.debug_ranges = debug_ranges;
155     }
156 
157     /// Return the `.debug_rnglists` section.
debug_rnglists(&self) -> &DebugRngLists<R>158     pub fn debug_rnglists(&self) -> &DebugRngLists<R> {
159         &self.debug_rnglists
160     }
161 }
162 
163 impl<T> RangeLists<T> {
164     /// Create a `RangeLists` that references the data in `self`.
165     ///
166     /// This is useful when `R` implements `Reader` but `T` does not.
167     ///
168     /// ## Example Usage
169     ///
170     /// ```rust,no_run
171     /// # let load_section = || unimplemented!();
172     /// // Read the DWARF section into a `Vec` with whatever object loader you're using.
173     /// let owned_section: gimli::RangeLists<Vec<u8>> = load_section();
174     /// // Create a reference to the DWARF section.
175     /// let section = owned_section.borrow(|section| {
176     ///     gimli::EndianSlice::new(&section, gimli::LittleEndian)
177     /// });
178     /// ```
borrow<'a, F, R>(&'a self, mut borrow: F) -> RangeLists<R> where F: FnMut(&'a T) -> R,179     pub fn borrow<'a, F, R>(&'a self, mut borrow: F) -> RangeLists<R>
180     where
181         F: FnMut(&'a T) -> R,
182     {
183         RangeLists {
184             debug_ranges: borrow(&self.debug_ranges.section).into(),
185             debug_rnglists: borrow(&self.debug_rnglists.section).into(),
186         }
187     }
188 }
189 
190 impl<R: Reader> RangeLists<R> {
191     /// Iterate over the `Range` list entries starting at the given offset.
192     ///
193     /// The `unit_version` and `address_size` must match the compilation unit that the
194     /// offset was contained in.
195     ///
196     /// The `base_address` should be obtained from the `DW_AT_low_pc` attribute in the
197     /// `DW_TAG_compile_unit` entry for the compilation unit that contains this range list.
198     ///
199     /// Can be [used with
200     /// `FallibleIterator`](./index.html#using-with-fallibleiterator).
ranges( &self, offset: RangeListsOffset<R::Offset>, unit_encoding: Encoding, base_address: u64, debug_addr: &DebugAddr<R>, debug_addr_base: DebugAddrBase<R::Offset>, ) -> Result<RngListIter<R>>201     pub fn ranges(
202         &self,
203         offset: RangeListsOffset<R::Offset>,
204         unit_encoding: Encoding,
205         base_address: u64,
206         debug_addr: &DebugAddr<R>,
207         debug_addr_base: DebugAddrBase<R::Offset>,
208     ) -> Result<RngListIter<R>> {
209         Ok(RngListIter::new(
210             self.raw_ranges(offset, unit_encoding)?,
211             base_address,
212             debug_addr.clone(),
213             debug_addr_base,
214         ))
215     }
216 
217     /// Iterate over the `RawRngListEntry`ies starting at the given offset.
218     ///
219     /// The `unit_encoding` must match the compilation unit that the
220     /// offset was contained in.
221     ///
222     /// This iterator does not perform any processing of the range entries,
223     /// such as handling base addresses.
224     ///
225     /// Can be [used with
226     /// `FallibleIterator`](./index.html#using-with-fallibleiterator).
raw_ranges( &self, offset: RangeListsOffset<R::Offset>, unit_encoding: Encoding, ) -> Result<RawRngListIter<R>>227     pub fn raw_ranges(
228         &self,
229         offset: RangeListsOffset<R::Offset>,
230         unit_encoding: Encoding,
231     ) -> Result<RawRngListIter<R>> {
232         let (mut input, format) = if unit_encoding.version <= 4 {
233             (self.debug_ranges.section.clone(), RangeListsFormat::Bare)
234         } else {
235             (self.debug_rnglists.section.clone(), RangeListsFormat::RLE)
236         };
237         input.skip(offset.0)?;
238         Ok(RawRngListIter::new(input, unit_encoding, format))
239     }
240 
241     /// Returns the `.debug_rnglists` offset at the given `base` and `index`.
242     ///
243     /// The `base` must be the `DW_AT_rnglists_base` value from the compilation unit DIE.
244     /// This is an offset that points to the first entry following the header.
245     ///
246     /// The `index` is the value of a `DW_FORM_rnglistx` attribute.
247     ///
248     /// The `unit_encoding` must match the compilation unit that the
249     /// index was contained in.
get_offset( &self, unit_encoding: Encoding, base: DebugRngListsBase<R::Offset>, index: DebugRngListsIndex<R::Offset>, ) -> Result<RangeListsOffset<R::Offset>>250     pub fn get_offset(
251         &self,
252         unit_encoding: Encoding,
253         base: DebugRngListsBase<R::Offset>,
254         index: DebugRngListsIndex<R::Offset>,
255     ) -> Result<RangeListsOffset<R::Offset>> {
256         let format = unit_encoding.format;
257         let input = &mut self.debug_rnglists.section.clone();
258         input.skip(base.0)?;
259         input.skip(R::Offset::from_u64(
260             index.0.into_u64() * u64::from(format.word_size()),
261         )?)?;
262         input
263             .read_offset(format)
264             .map(|x| RangeListsOffset(base.0 + x))
265     }
266 
267     /// Call `Reader::lookup_offset_id` for each section, and return the first match.
lookup_offset_id(&self, id: ReaderOffsetId) -> Option<(SectionId, R::Offset)>268     pub fn lookup_offset_id(&self, id: ReaderOffsetId) -> Option<(SectionId, R::Offset)> {
269         self.debug_ranges
270             .lookup_offset_id(id)
271             .or_else(|| self.debug_rnglists.lookup_offset_id(id))
272     }
273 }
274 
275 #[derive(Debug, Clone, Copy, PartialEq, Eq)]
276 enum RangeListsFormat {
277     /// The bare range list format used before DWARF 5.
278     Bare,
279     /// The DW_RLE encoded range list format used in DWARF 5.
280     RLE,
281 }
282 
283 /// A raw iterator over an address range list.
284 ///
285 /// This iterator does not perform any processing of the range entries,
286 /// such as handling base addresses.
287 #[derive(Debug)]
288 pub struct RawRngListIter<R: Reader> {
289     input: R,
290     encoding: Encoding,
291     format: RangeListsFormat,
292 }
293 
294 /// A raw entry in .debug_rnglists
295 #[derive(Clone, Debug)]
296 pub enum RawRngListEntry<T> {
297     /// A range from DWARF version <= 4.
298     AddressOrOffsetPair {
299         /// Start of range. May be an address or an offset.
300         begin: u64,
301         /// End of range. May be an address or an offset.
302         end: u64,
303     },
304     /// DW_RLE_base_address
305     BaseAddress {
306         /// base address
307         addr: u64,
308     },
309     /// DW_RLE_base_addressx
310     BaseAddressx {
311         /// base address
312         addr: DebugAddrIndex<T>,
313     },
314     /// DW_RLE_startx_endx
315     StartxEndx {
316         /// start of range
317         begin: DebugAddrIndex<T>,
318         /// end of range
319         end: DebugAddrIndex<T>,
320     },
321     /// DW_RLE_startx_length
322     StartxLength {
323         /// start of range
324         begin: DebugAddrIndex<T>,
325         /// length of range
326         length: u64,
327     },
328     /// DW_RLE_offset_pair
329     OffsetPair {
330         /// start of range
331         begin: u64,
332         /// end of range
333         end: u64,
334     },
335     /// DW_RLE_start_end
336     StartEnd {
337         /// start of range
338         begin: u64,
339         /// end of range
340         end: u64,
341     },
342     /// DW_RLE_start_length
343     StartLength {
344         /// start of range
345         begin: u64,
346         /// length of range
347         length: u64,
348     },
349 }
350 
351 impl<T: ReaderOffset> RawRngListEntry<T> {
352     /// Parse a range entry from `.debug_rnglists`
parse<R: Reader<Offset = T>>( input: &mut R, encoding: Encoding, format: RangeListsFormat, ) -> Result<Option<Self>>353     fn parse<R: Reader<Offset = T>>(
354         input: &mut R,
355         encoding: Encoding,
356         format: RangeListsFormat,
357     ) -> Result<Option<Self>> {
358         match format {
359             RangeListsFormat::Bare => {
360                 let range = RawRange::parse(input, encoding.address_size)?;
361                 return Ok(if range.is_end() {
362                     None
363                 } else if range.is_base_address(encoding.address_size) {
364                     Some(RawRngListEntry::BaseAddress { addr: range.end })
365                 } else {
366                     Some(RawRngListEntry::AddressOrOffsetPair {
367                         begin: range.begin,
368                         end: range.end,
369                     })
370                 });
371             }
372             RangeListsFormat::RLE => Ok(match constants::DwRle(input.read_u8()?) {
373                 constants::DW_RLE_end_of_list => None,
374                 constants::DW_RLE_base_addressx => Some(RawRngListEntry::BaseAddressx {
375                     addr: DebugAddrIndex(input.read_uleb128().and_then(R::Offset::from_u64)?),
376                 }),
377                 constants::DW_RLE_startx_endx => Some(RawRngListEntry::StartxEndx {
378                     begin: DebugAddrIndex(input.read_uleb128().and_then(R::Offset::from_u64)?),
379                     end: DebugAddrIndex(input.read_uleb128().and_then(R::Offset::from_u64)?),
380                 }),
381                 constants::DW_RLE_startx_length => Some(RawRngListEntry::StartxLength {
382                     begin: DebugAddrIndex(input.read_uleb128().and_then(R::Offset::from_u64)?),
383                     length: input.read_uleb128()?,
384                 }),
385                 constants::DW_RLE_offset_pair => Some(RawRngListEntry::OffsetPair {
386                     begin: input.read_uleb128()?,
387                     end: input.read_uleb128()?,
388                 }),
389                 constants::DW_RLE_base_address => Some(RawRngListEntry::BaseAddress {
390                     addr: input.read_address(encoding.address_size)?,
391                 }),
392                 constants::DW_RLE_start_end => Some(RawRngListEntry::StartEnd {
393                     begin: input.read_address(encoding.address_size)?,
394                     end: input.read_address(encoding.address_size)?,
395                 }),
396                 constants::DW_RLE_start_length => Some(RawRngListEntry::StartLength {
397                     begin: input.read_address(encoding.address_size)?,
398                     length: input.read_uleb128()?,
399                 }),
400                 _ => {
401                     return Err(Error::InvalidAddressRange);
402                 }
403             }),
404         }
405     }
406 }
407 
408 impl<R: Reader> RawRngListIter<R> {
409     /// Construct a `RawRngListIter`.
new(input: R, encoding: Encoding, format: RangeListsFormat) -> RawRngListIter<R>410     fn new(input: R, encoding: Encoding, format: RangeListsFormat) -> RawRngListIter<R> {
411         RawRngListIter {
412             input,
413             encoding,
414             format,
415         }
416     }
417 
418     /// Advance the iterator to the next range.
next(&mut self) -> Result<Option<RawRngListEntry<R::Offset>>>419     pub fn next(&mut self) -> Result<Option<RawRngListEntry<R::Offset>>> {
420         if self.input.is_empty() {
421             return Ok(None);
422         }
423 
424         match RawRngListEntry::parse(&mut self.input, self.encoding, self.format) {
425             Ok(range) => {
426                 if range.is_none() {
427                     self.input.empty();
428                 }
429                 Ok(range)
430             }
431             Err(e) => {
432                 self.input.empty();
433                 Err(e)
434             }
435         }
436     }
437 }
438 
439 #[cfg(feature = "fallible-iterator")]
440 impl<R: Reader> fallible_iterator::FallibleIterator for RawRngListIter<R> {
441     type Item = RawRngListEntry<R::Offset>;
442     type Error = Error;
443 
next(&mut self) -> ::core::result::Result<Option<Self::Item>, Self::Error>444     fn next(&mut self) -> ::core::result::Result<Option<Self::Item>, Self::Error> {
445         RawRngListIter::next(self)
446     }
447 }
448 
449 /// An iterator over an address range list.
450 ///
451 /// This iterator internally handles processing of base addresses and different
452 /// entry types.  Thus, it only returns range entries that are valid
453 /// and already adjusted for the base address.
454 #[derive(Debug)]
455 pub struct RngListIter<R: Reader> {
456     raw: RawRngListIter<R>,
457     base_address: u64,
458     debug_addr: DebugAddr<R>,
459     debug_addr_base: DebugAddrBase<R::Offset>,
460 }
461 
462 impl<R: Reader> RngListIter<R> {
463     /// Construct a `RngListIter`.
new( raw: RawRngListIter<R>, base_address: u64, debug_addr: DebugAddr<R>, debug_addr_base: DebugAddrBase<R::Offset>, ) -> RngListIter<R>464     fn new(
465         raw: RawRngListIter<R>,
466         base_address: u64,
467         debug_addr: DebugAddr<R>,
468         debug_addr_base: DebugAddrBase<R::Offset>,
469     ) -> RngListIter<R> {
470         RngListIter {
471             raw,
472             base_address,
473             debug_addr,
474             debug_addr_base,
475         }
476     }
477 
478     #[inline]
get_address(&self, index: DebugAddrIndex<R::Offset>) -> Result<u64>479     fn get_address(&self, index: DebugAddrIndex<R::Offset>) -> Result<u64> {
480         self.debug_addr
481             .get_address(self.raw.encoding.address_size, self.debug_addr_base, index)
482     }
483 
484     /// Advance the iterator to the next range.
next(&mut self) -> Result<Option<Range>>485     pub fn next(&mut self) -> Result<Option<Range>> {
486         loop {
487             let raw_range = match self.raw.next()? {
488                 Some(range) => range,
489                 None => return Ok(None),
490             };
491 
492             let range = match raw_range {
493                 RawRngListEntry::BaseAddress { addr } => {
494                     self.base_address = addr;
495                     continue;
496                 }
497                 RawRngListEntry::BaseAddressx { addr } => {
498                     self.base_address = self.get_address(addr)?;
499                     continue;
500                 }
501                 RawRngListEntry::StartxEndx { begin, end } => {
502                     let begin = self.get_address(begin)?;
503                     let end = self.get_address(end)?;
504                     Range { begin, end }
505                 }
506                 RawRngListEntry::StartxLength { begin, length } => {
507                     let begin = self.get_address(begin)?;
508                     let end = begin + length;
509                     Range { begin, end }
510                 }
511                 RawRngListEntry::AddressOrOffsetPair { begin, end }
512                 | RawRngListEntry::OffsetPair { begin, end } => {
513                     let mut range = Range { begin, end };
514                     range.add_base_address(self.base_address, self.raw.encoding.address_size);
515                     range
516                 }
517                 RawRngListEntry::StartEnd { begin, end } => Range { begin, end },
518                 RawRngListEntry::StartLength { begin, length } => Range {
519                     begin,
520                     end: begin + length,
521                 },
522             };
523 
524             if range.begin > range.end {
525                 self.raw.input.empty();
526                 return Err(Error::InvalidAddressRange);
527             }
528 
529             return Ok(Some(range));
530         }
531     }
532 }
533 
534 #[cfg(feature = "fallible-iterator")]
535 impl<R: Reader> fallible_iterator::FallibleIterator for RngListIter<R> {
536     type Item = Range;
537     type Error = Error;
538 
next(&mut self) -> ::core::result::Result<Option<Self::Item>, Self::Error>539     fn next(&mut self) -> ::core::result::Result<Option<Self::Item>, Self::Error> {
540         RngListIter::next(self)
541     }
542 }
543 
544 /// A raw address range from the `.debug_ranges` section.
545 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
546 pub(crate) struct RawRange {
547     /// The beginning address of the range.
548     pub begin: u64,
549 
550     /// The first address past the end of the range.
551     pub end: u64,
552 }
553 
554 impl RawRange {
555     /// Check if this is a range end entry.
556     ///
557     /// This will only occur for raw ranges.
558     #[inline]
is_end(&self) -> bool559     pub fn is_end(&self) -> bool {
560         self.begin == 0 && self.end == 0
561     }
562 
563     /// Check if this is a base address selection entry.
564     ///
565     /// A base address selection entry changes the base address that subsequent
566     /// range entries are relative to.  This will only occur for raw ranges.
567     #[inline]
is_base_address(&self, address_size: u8) -> bool568     pub fn is_base_address(&self, address_size: u8) -> bool {
569         self.begin == !0 >> (64 - address_size * 8)
570     }
571 
572     /// Parse an address range entry from `.debug_ranges` or `.debug_loc`.
573     #[doc(hidden)]
574     #[inline]
parse<R: Reader>(input: &mut R, address_size: u8) -> Result<RawRange>575     pub fn parse<R: Reader>(input: &mut R, address_size: u8) -> Result<RawRange> {
576         let begin = input.read_address(address_size)?;
577         let end = input.read_address(address_size)?;
578         let range = RawRange { begin, end };
579         Ok(range)
580     }
581 }
582 
583 /// An address range from the `.debug_ranges`, `.debug_rnglists`, or `.debug_aranges` sections.
584 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
585 pub struct Range {
586     /// The beginning address of the range.
587     pub begin: u64,
588 
589     /// The first address past the end of the range.
590     pub end: u64,
591 }
592 
593 impl Range {
594     /// Add a base address to this range.
595     #[inline]
add_base_address(&mut self, base_address: u64, address_size: u8)596     pub(crate) fn add_base_address(&mut self, base_address: u64, address_size: u8) {
597         let mask = !0 >> (64 - address_size * 8);
598         self.begin = base_address.wrapping_add(self.begin) & mask;
599         self.end = base_address.wrapping_add(self.end) & mask;
600     }
601 }
602 
603 #[cfg(test)]
604 mod tests {
605     use super::*;
606     use crate::common::Format;
607     use crate::endianity::LittleEndian;
608     use crate::test_util::GimliSectionMethods;
609     use test_assembler::{Endian, Label, LabelMaker, Section};
610 
611     #[test]
test_rnglists_32()612     fn test_rnglists_32() {
613         let encoding = Encoding {
614             format: Format::Dwarf32,
615             version: 5,
616             address_size: 4,
617         };
618         let section = Section::with_endian(Endian::Little)
619             .L32(0x0300_0000)
620             .L32(0x0301_0300)
621             .L32(0x0301_0400)
622             .L32(0x0301_0500);
623         let buf = section.get_contents().unwrap();
624         let debug_addr = &DebugAddr::from(EndianSlice::new(&buf, LittleEndian));
625         let debug_addr_base = DebugAddrBase(0);
626 
627         let start = Label::new();
628         let first = Label::new();
629         let size = Label::new();
630         #[rustfmt::skip]
631         let section = Section::with_endian(Endian::Little)
632             // Header
633             .mark(&start)
634             .L32(&size)
635             .L16(encoding.version)
636             .L8(encoding.address_size)
637             .L8(0)
638             .L32(0)
639             .mark(&first)
640             // OffsetPair
641             .L8(4).uleb(0x10200).uleb(0x10300)
642             // A base address selection followed by an OffsetPair.
643             .L8(5).L32(0x0200_0000)
644             .L8(4).uleb(0x10400).uleb(0x10500)
645             // An empty OffsetPair followed by a normal OffsetPair.
646             .L8(4).uleb(0x10600).uleb(0x10600)
647             .L8(4).uleb(0x10800).uleb(0x10900)
648             // A StartEnd
649             .L8(6).L32(0x201_0a00).L32(0x201_0b00)
650             // A StartLength
651             .L8(7).L32(0x201_0c00).uleb(0x100)
652             // An OffsetPair that starts at 0.
653             .L8(4).uleb(0).uleb(1)
654             // An OffsetPair that starts and ends at 0.
655             .L8(4).uleb(0).uleb(0)
656             // An OffsetPair that ends at -1.
657             .L8(5).L32(0)
658             .L8(4).uleb(0).uleb(0xffff_ffff)
659             // A BaseAddressx + OffsetPair
660             .L8(1).uleb(0)
661             .L8(4).uleb(0x10100).uleb(0x10200)
662             // A StartxEndx
663             .L8(2).uleb(1).uleb(2)
664             // A StartxLength
665             .L8(3).uleb(3).uleb(0x100)
666             // A range end.
667             .L8(0)
668             // Some extra data.
669             .L32(0xffff_ffff);
670         size.set_const((&section.here() - &start - 4) as u64);
671 
672         let buf = section.get_contents().unwrap();
673         let debug_ranges = DebugRanges::new(&[], LittleEndian);
674         let debug_rnglists = DebugRngLists::new(&buf, LittleEndian);
675         let rnglists = RangeLists::new(debug_ranges, debug_rnglists);
676         let offset = RangeListsOffset((&first - &start) as usize);
677         let mut ranges = rnglists
678             .ranges(offset, encoding, 0x0100_0000, debug_addr, debug_addr_base)
679             .unwrap();
680 
681         // A normal range.
682         assert_eq!(
683             ranges.next(),
684             Ok(Some(Range {
685                 begin: 0x0101_0200,
686                 end: 0x0101_0300,
687             }))
688         );
689 
690         // A base address selection followed by a normal range.
691         assert_eq!(
692             ranges.next(),
693             Ok(Some(Range {
694                 begin: 0x0201_0400,
695                 end: 0x0201_0500,
696             }))
697         );
698 
699         // An empty range followed by a normal range.
700         assert_eq!(
701             ranges.next(),
702             Ok(Some(Range {
703                 begin: 0x0201_0600,
704                 end: 0x0201_0600,
705             }))
706         );
707         assert_eq!(
708             ranges.next(),
709             Ok(Some(Range {
710                 begin: 0x0201_0800,
711                 end: 0x0201_0900,
712             }))
713         );
714 
715         // A normal range.
716         assert_eq!(
717             ranges.next(),
718             Ok(Some(Range {
719                 begin: 0x0201_0a00,
720                 end: 0x0201_0b00,
721             }))
722         );
723 
724         // A normal range.
725         assert_eq!(
726             ranges.next(),
727             Ok(Some(Range {
728                 begin: 0x0201_0c00,
729                 end: 0x0201_0d00,
730             }))
731         );
732 
733         // A range that starts at 0.
734         assert_eq!(
735             ranges.next(),
736             Ok(Some(Range {
737                 begin: 0x0200_0000,
738                 end: 0x0200_0001,
739             }))
740         );
741 
742         // A range that starts and ends at 0.
743         assert_eq!(
744             ranges.next(),
745             Ok(Some(Range {
746                 begin: 0x0200_0000,
747                 end: 0x0200_0000,
748             }))
749         );
750 
751         // A range that ends at -1.
752         assert_eq!(
753             ranges.next(),
754             Ok(Some(Range {
755                 begin: 0x0000_0000,
756                 end: 0xffff_ffff,
757             }))
758         );
759 
760         // A BaseAddressx + OffsetPair
761         assert_eq!(
762             ranges.next(),
763             Ok(Some(Range {
764                 begin: 0x0301_0100,
765                 end: 0x0301_0200,
766             }))
767         );
768 
769         // A StartxEndx
770         assert_eq!(
771             ranges.next(),
772             Ok(Some(Range {
773                 begin: 0x0301_0300,
774                 end: 0x0301_0400,
775             }))
776         );
777 
778         // A StartxLength
779         assert_eq!(
780             ranges.next(),
781             Ok(Some(Range {
782                 begin: 0x0301_0500,
783                 end: 0x0301_0600,
784             }))
785         );
786 
787         // A range end.
788         assert_eq!(ranges.next(), Ok(None));
789 
790         // An offset at the end of buf.
791         let mut ranges = rnglists
792             .ranges(
793                 RangeListsOffset(buf.len()),
794                 encoding,
795                 0x0100_0000,
796                 debug_addr,
797                 debug_addr_base,
798             )
799             .unwrap();
800         assert_eq!(ranges.next(), Ok(None));
801     }
802 
803     #[test]
test_rnglists_64()804     fn test_rnglists_64() {
805         let encoding = Encoding {
806             format: Format::Dwarf64,
807             version: 5,
808             address_size: 8,
809         };
810         let section = Section::with_endian(Endian::Little)
811             .L64(0x0300_0000)
812             .L64(0x0301_0300)
813             .L64(0x0301_0400)
814             .L64(0x0301_0500);
815         let buf = section.get_contents().unwrap();
816         let debug_addr = &DebugAddr::from(EndianSlice::new(&buf, LittleEndian));
817         let debug_addr_base = DebugAddrBase(0);
818 
819         let start = Label::new();
820         let first = Label::new();
821         let size = Label::new();
822         #[rustfmt::skip]
823         let section = Section::with_endian(Endian::Little)
824             // Header
825             .mark(&start)
826             .L32(0xffff_ffff)
827             .L64(&size)
828             .L16(encoding.version)
829             .L8(encoding.address_size)
830             .L8(0)
831             .L32(0)
832             .mark(&first)
833             // OffsetPair
834             .L8(4).uleb(0x10200).uleb(0x10300)
835             // A base address selection followed by an OffsetPair.
836             .L8(5).L64(0x0200_0000)
837             .L8(4).uleb(0x10400).uleb(0x10500)
838             // An empty OffsetPair followed by a normal OffsetPair.
839             .L8(4).uleb(0x10600).uleb(0x10600)
840             .L8(4).uleb(0x10800).uleb(0x10900)
841             // A StartEnd
842             .L8(6).L64(0x201_0a00).L64(0x201_0b00)
843             // A StartLength
844             .L8(7).L64(0x201_0c00).uleb(0x100)
845             // An OffsetPair that starts at 0.
846             .L8(4).uleb(0).uleb(1)
847             // An OffsetPair that starts and ends at 0.
848             .L8(4).uleb(0).uleb(0)
849             // An OffsetPair that ends at -1.
850             .L8(5).L64(0)
851             .L8(4).uleb(0).uleb(0xffff_ffff)
852             // A BaseAddressx + OffsetPair
853             .L8(1).uleb(0)
854             .L8(4).uleb(0x10100).uleb(0x10200)
855             // A StartxEndx
856             .L8(2).uleb(1).uleb(2)
857             // A StartxLength
858             .L8(3).uleb(3).uleb(0x100)
859             // A range end.
860             .L8(0)
861             // Some extra data.
862             .L32(0xffff_ffff);
863         size.set_const((&section.here() - &start - 12) as u64);
864 
865         let buf = section.get_contents().unwrap();
866         let debug_ranges = DebugRanges::new(&[], LittleEndian);
867         let debug_rnglists = DebugRngLists::new(&buf, LittleEndian);
868         let rnglists = RangeLists::new(debug_ranges, debug_rnglists);
869         let offset = RangeListsOffset((&first - &start) as usize);
870         let mut ranges = rnglists
871             .ranges(offset, encoding, 0x0100_0000, debug_addr, debug_addr_base)
872             .unwrap();
873 
874         // A normal range.
875         assert_eq!(
876             ranges.next(),
877             Ok(Some(Range {
878                 begin: 0x0101_0200,
879                 end: 0x0101_0300,
880             }))
881         );
882 
883         // A base address selection followed by a normal range.
884         assert_eq!(
885             ranges.next(),
886             Ok(Some(Range {
887                 begin: 0x0201_0400,
888                 end: 0x0201_0500,
889             }))
890         );
891 
892         // An empty range followed by a normal range.
893         assert_eq!(
894             ranges.next(),
895             Ok(Some(Range {
896                 begin: 0x0201_0600,
897                 end: 0x0201_0600,
898             }))
899         );
900         assert_eq!(
901             ranges.next(),
902             Ok(Some(Range {
903                 begin: 0x0201_0800,
904                 end: 0x0201_0900,
905             }))
906         );
907 
908         // A normal range.
909         assert_eq!(
910             ranges.next(),
911             Ok(Some(Range {
912                 begin: 0x0201_0a00,
913                 end: 0x0201_0b00,
914             }))
915         );
916 
917         // A normal range.
918         assert_eq!(
919             ranges.next(),
920             Ok(Some(Range {
921                 begin: 0x0201_0c00,
922                 end: 0x0201_0d00,
923             }))
924         );
925 
926         // A range that starts at 0.
927         assert_eq!(
928             ranges.next(),
929             Ok(Some(Range {
930                 begin: 0x0200_0000,
931                 end: 0x0200_0001,
932             }))
933         );
934 
935         // A range that starts and ends at 0.
936         assert_eq!(
937             ranges.next(),
938             Ok(Some(Range {
939                 begin: 0x0200_0000,
940                 end: 0x0200_0000,
941             }))
942         );
943 
944         // A range that ends at -1.
945         assert_eq!(
946             ranges.next(),
947             Ok(Some(Range {
948                 begin: 0x0000_0000,
949                 end: 0xffff_ffff,
950             }))
951         );
952 
953         // A BaseAddressx + OffsetPair
954         assert_eq!(
955             ranges.next(),
956             Ok(Some(Range {
957                 begin: 0x0301_0100,
958                 end: 0x0301_0200,
959             }))
960         );
961 
962         // A StartxEndx
963         assert_eq!(
964             ranges.next(),
965             Ok(Some(Range {
966                 begin: 0x0301_0300,
967                 end: 0x0301_0400,
968             }))
969         );
970 
971         // A StartxLength
972         assert_eq!(
973             ranges.next(),
974             Ok(Some(Range {
975                 begin: 0x0301_0500,
976                 end: 0x0301_0600,
977             }))
978         );
979 
980         // A range end.
981         assert_eq!(ranges.next(), Ok(None));
982 
983         // An offset at the end of buf.
984         let mut ranges = rnglists
985             .ranges(
986                 RangeListsOffset(buf.len()),
987                 encoding,
988                 0x0100_0000,
989                 debug_addr,
990                 debug_addr_base,
991             )
992             .unwrap();
993         assert_eq!(ranges.next(), Ok(None));
994     }
995 
996     #[test]
test_raw_range()997     fn test_raw_range() {
998         let range = RawRange {
999             begin: 0,
1000             end: 0xffff_ffff,
1001         };
1002         assert!(!range.is_end());
1003         assert!(!range.is_base_address(4));
1004         assert!(!range.is_base_address(8));
1005 
1006         let range = RawRange { begin: 0, end: 0 };
1007         assert!(range.is_end());
1008         assert!(!range.is_base_address(4));
1009         assert!(!range.is_base_address(8));
1010 
1011         let range = RawRange {
1012             begin: 0xffff_ffff,
1013             end: 0,
1014         };
1015         assert!(!range.is_end());
1016         assert!(range.is_base_address(4));
1017         assert!(!range.is_base_address(8));
1018 
1019         let range = RawRange {
1020             begin: 0xffff_ffff_ffff_ffff,
1021             end: 0,
1022         };
1023         assert!(!range.is_end());
1024         assert!(!range.is_base_address(4));
1025         assert!(range.is_base_address(8));
1026     }
1027 
1028     #[test]
test_ranges_32()1029     fn test_ranges_32() {
1030         let start = Label::new();
1031         let first = Label::new();
1032         #[rustfmt::skip]
1033         let section = Section::with_endian(Endian::Little)
1034             // A range before the offset.
1035             .mark(&start)
1036             .L32(0x10000).L32(0x10100)
1037             .mark(&first)
1038             // A normal range.
1039             .L32(0x10200).L32(0x10300)
1040             // A base address selection followed by a normal range.
1041             .L32(0xffff_ffff).L32(0x0200_0000)
1042             .L32(0x10400).L32(0x10500)
1043             // An empty range followed by a normal range.
1044             .L32(0x10600).L32(0x10600)
1045             .L32(0x10800).L32(0x10900)
1046             // A range that starts at 0.
1047             .L32(0).L32(1)
1048             // A range that ends at -1.
1049             .L32(0xffff_ffff).L32(0x0000_0000)
1050             .L32(0).L32(0xffff_ffff)
1051             // A range end.
1052             .L32(0).L32(0)
1053             // Some extra data.
1054             .L32(0);
1055 
1056         let buf = section.get_contents().unwrap();
1057         let debug_ranges = DebugRanges::new(&buf, LittleEndian);
1058         let debug_rnglists = DebugRngLists::new(&[], LittleEndian);
1059         let rnglists = RangeLists::new(debug_ranges, debug_rnglists);
1060         let offset = RangeListsOffset((&first - &start) as usize);
1061         let debug_addr = &DebugAddr::from(EndianSlice::new(&[], LittleEndian));
1062         let debug_addr_base = DebugAddrBase(0);
1063         let encoding = Encoding {
1064             format: Format::Dwarf32,
1065             version: 4,
1066             address_size: 4,
1067         };
1068         let mut ranges = rnglists
1069             .ranges(offset, encoding, 0x0100_0000, debug_addr, debug_addr_base)
1070             .unwrap();
1071 
1072         // A normal range.
1073         assert_eq!(
1074             ranges.next(),
1075             Ok(Some(Range {
1076                 begin: 0x0101_0200,
1077                 end: 0x0101_0300,
1078             }))
1079         );
1080 
1081         // A base address selection followed by a normal range.
1082         assert_eq!(
1083             ranges.next(),
1084             Ok(Some(Range {
1085                 begin: 0x0201_0400,
1086                 end: 0x0201_0500,
1087             }))
1088         );
1089 
1090         // An empty range followed by a normal range.
1091         assert_eq!(
1092             ranges.next(),
1093             Ok(Some(Range {
1094                 begin: 0x0201_0600,
1095                 end: 0x0201_0600,
1096             }))
1097         );
1098         assert_eq!(
1099             ranges.next(),
1100             Ok(Some(Range {
1101                 begin: 0x0201_0800,
1102                 end: 0x0201_0900,
1103             }))
1104         );
1105 
1106         // A range that starts at 0.
1107         assert_eq!(
1108             ranges.next(),
1109             Ok(Some(Range {
1110                 begin: 0x0200_0000,
1111                 end: 0x0200_0001,
1112             }))
1113         );
1114 
1115         // A range that ends at -1.
1116         assert_eq!(
1117             ranges.next(),
1118             Ok(Some(Range {
1119                 begin: 0x0000_0000,
1120                 end: 0xffff_ffff,
1121             }))
1122         );
1123 
1124         // A range end.
1125         assert_eq!(ranges.next(), Ok(None));
1126 
1127         // An offset at the end of buf.
1128         let mut ranges = rnglists
1129             .ranges(
1130                 RangeListsOffset(buf.len()),
1131                 encoding,
1132                 0x0100_0000,
1133                 debug_addr,
1134                 debug_addr_base,
1135             )
1136             .unwrap();
1137         assert_eq!(ranges.next(), Ok(None));
1138     }
1139 
1140     #[test]
test_ranges_64()1141     fn test_ranges_64() {
1142         let start = Label::new();
1143         let first = Label::new();
1144         #[rustfmt::skip]
1145         let section = Section::with_endian(Endian::Little)
1146             // A range before the offset.
1147             .mark(&start)
1148             .L64(0x10000).L64(0x10100)
1149             .mark(&first)
1150             // A normal range.
1151             .L64(0x10200).L64(0x10300)
1152             // A base address selection followed by a normal range.
1153             .L64(0xffff_ffff_ffff_ffff).L64(0x0200_0000)
1154             .L64(0x10400).L64(0x10500)
1155             // An empty range followed by a normal range.
1156             .L64(0x10600).L64(0x10600)
1157             .L64(0x10800).L64(0x10900)
1158             // A range that starts at 0.
1159             .L64(0).L64(1)
1160             // A range that ends at -1.
1161             .L64(0xffff_ffff_ffff_ffff).L64(0x0000_0000)
1162             .L64(0).L64(0xffff_ffff_ffff_ffff)
1163             // A range end.
1164             .L64(0).L64(0)
1165             // Some extra data.
1166             .L64(0);
1167 
1168         let buf = section.get_contents().unwrap();
1169         let debug_ranges = DebugRanges::new(&buf, LittleEndian);
1170         let debug_rnglists = DebugRngLists::new(&[], LittleEndian);
1171         let rnglists = RangeLists::new(debug_ranges, debug_rnglists);
1172         let offset = RangeListsOffset((&first - &start) as usize);
1173         let debug_addr = &DebugAddr::from(EndianSlice::new(&[], LittleEndian));
1174         let debug_addr_base = DebugAddrBase(0);
1175         let encoding = Encoding {
1176             format: Format::Dwarf64,
1177             version: 4,
1178             address_size: 8,
1179         };
1180         let mut ranges = rnglists
1181             .ranges(offset, encoding, 0x0100_0000, debug_addr, debug_addr_base)
1182             .unwrap();
1183 
1184         // A normal range.
1185         assert_eq!(
1186             ranges.next(),
1187             Ok(Some(Range {
1188                 begin: 0x0101_0200,
1189                 end: 0x0101_0300,
1190             }))
1191         );
1192 
1193         // A base address selection followed by a normal range.
1194         assert_eq!(
1195             ranges.next(),
1196             Ok(Some(Range {
1197                 begin: 0x0201_0400,
1198                 end: 0x0201_0500,
1199             }))
1200         );
1201 
1202         // An empty range followed by a normal range.
1203         assert_eq!(
1204             ranges.next(),
1205             Ok(Some(Range {
1206                 begin: 0x0201_0600,
1207                 end: 0x0201_0600,
1208             }))
1209         );
1210         assert_eq!(
1211             ranges.next(),
1212             Ok(Some(Range {
1213                 begin: 0x0201_0800,
1214                 end: 0x0201_0900,
1215             }))
1216         );
1217 
1218         // A range that starts at 0.
1219         assert_eq!(
1220             ranges.next(),
1221             Ok(Some(Range {
1222                 begin: 0x0200_0000,
1223                 end: 0x0200_0001,
1224             }))
1225         );
1226 
1227         // A range that ends at -1.
1228         assert_eq!(
1229             ranges.next(),
1230             Ok(Some(Range {
1231                 begin: 0x0,
1232                 end: 0xffff_ffff_ffff_ffff,
1233             }))
1234         );
1235 
1236         // A range end.
1237         assert_eq!(ranges.next(), Ok(None));
1238 
1239         // An offset at the end of buf.
1240         let mut ranges = rnglists
1241             .ranges(
1242                 RangeListsOffset(buf.len()),
1243                 encoding,
1244                 0x0100_0000,
1245                 debug_addr,
1246                 debug_addr_base,
1247             )
1248             .unwrap();
1249         assert_eq!(ranges.next(), Ok(None));
1250     }
1251 
1252     #[test]
test_ranges_invalid()1253     fn test_ranges_invalid() {
1254         #[rustfmt::skip]
1255         let section = Section::with_endian(Endian::Little)
1256             // An invalid range.
1257             .L32(0x20000).L32(0x10000)
1258             // An invalid range after wrapping.
1259             .L32(0x20000).L32(0xff01_0000);
1260 
1261         let buf = section.get_contents().unwrap();
1262         let debug_ranges = DebugRanges::new(&buf, LittleEndian);
1263         let debug_rnglists = DebugRngLists::new(&[], LittleEndian);
1264         let rnglists = RangeLists::new(debug_ranges, debug_rnglists);
1265         let debug_addr = &DebugAddr::from(EndianSlice::new(&[], LittleEndian));
1266         let debug_addr_base = DebugAddrBase(0);
1267         let encoding = Encoding {
1268             format: Format::Dwarf32,
1269             version: 4,
1270             address_size: 4,
1271         };
1272 
1273         // An invalid range.
1274         let mut ranges = rnglists
1275             .ranges(
1276                 RangeListsOffset(0x0),
1277                 encoding,
1278                 0x0100_0000,
1279                 debug_addr,
1280                 debug_addr_base,
1281             )
1282             .unwrap();
1283         assert_eq!(ranges.next(), Err(Error::InvalidAddressRange));
1284 
1285         // An invalid range after wrapping.
1286         let mut ranges = rnglists
1287             .ranges(
1288                 RangeListsOffset(0x8),
1289                 encoding,
1290                 0x0100_0000,
1291                 debug_addr,
1292                 debug_addr_base,
1293             )
1294             .unwrap();
1295         assert_eq!(ranges.next(), Err(Error::InvalidAddressRange));
1296 
1297         // An invalid offset.
1298         match rnglists.ranges(
1299             RangeListsOffset(buf.len() + 1),
1300             encoding,
1301             0x0100_0000,
1302             debug_addr,
1303             debug_addr_base,
1304         ) {
1305             Err(Error::UnexpectedEof(_)) => {}
1306             otherwise => panic!("Unexpected result: {:?}", otherwise),
1307         }
1308     }
1309 
1310     #[test]
test_get_offset()1311     fn test_get_offset() {
1312         for format in vec![Format::Dwarf32, Format::Dwarf64] {
1313             let encoding = Encoding {
1314                 format,
1315                 version: 5,
1316                 address_size: 4,
1317             };
1318 
1319             let zero = Label::new();
1320             let length = Label::new();
1321             let start = Label::new();
1322             let first = Label::new();
1323             let end = Label::new();
1324             let mut section = Section::with_endian(Endian::Little)
1325                 .mark(&zero)
1326                 .initial_length(format, &length, &start)
1327                 .D16(encoding.version)
1328                 .D8(encoding.address_size)
1329                 .D8(0)
1330                 .D32(20)
1331                 .mark(&first);
1332             for i in 0..20 {
1333                 section = section.word(format.word_size(), 1000 + i);
1334             }
1335             section = section.mark(&end);
1336             length.set_const((&end - &start) as u64);
1337             let section = section.get_contents().unwrap();
1338 
1339             let debug_ranges = DebugRanges::from(EndianSlice::new(&[], LittleEndian));
1340             let debug_rnglists = DebugRngLists::from(EndianSlice::new(&section, LittleEndian));
1341             let ranges = RangeLists::new(debug_ranges, debug_rnglists);
1342 
1343             let base = DebugRngListsBase((&first - &zero) as usize);
1344             assert_eq!(
1345                 ranges.get_offset(encoding, base, DebugRngListsIndex(0)),
1346                 Ok(RangeListsOffset(base.0 + 1000))
1347             );
1348             assert_eq!(
1349                 ranges.get_offset(encoding, base, DebugRngListsIndex(19)),
1350                 Ok(RangeListsOffset(base.0 + 1019))
1351             );
1352         }
1353     }
1354 }
1355