Coverage Report

Created: 2024-10-16 07:58

/rust/registry/src/index.crates.io-6f17d22bba15001f/gimli-0.26.2/src/read/aranges.rs
Line
Count
Source (jump to first uncovered line)
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 macOS, etc.
22
    ///
23
    /// ```
24
    /// use gimli::{DebugAranges, LittleEndian};
25
    ///
26
    /// # let buf = [];
27
    /// # let read_debug_aranges_section = || &buf;
28
    /// let debug_aranges =
29
    ///     DebugAranges::new(read_debug_aranges_section(), LittleEndian);
30
    /// ```
31
0
    pub fn new(section: &'input [u8], endian: Endian) -> Self {
32
0
        DebugAranges {
33
0
            section: EndianSlice::new(section, endian),
34
0
        }
35
0
    }
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.
42
0
    pub fn headers(&self) -> ArangeHeaderIter<R> {
43
0
        ArangeHeaderIter {
44
0
            input: self.section.clone(),
45
0
            offset: DebugArangesOffset(R::Offset::from_u8(0)),
46
0
        }
47
0
    }
48
49
    /// Get the header at the given offset.
50
0
    pub fn header(&self, offset: DebugArangesOffset<R::Offset>) -> Result<ArangeHeader<R>> {
51
0
        let mut input = self.section.clone();
52
0
        input.skip(offset.0)?;
53
0
        ArangeHeader::parse(&mut input, offset)
54
0
    }
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
    /// ```
73
0
    pub fn borrow<'a, F, R>(&'a self, mut borrow: F) -> DebugAranges<R>
74
0
    where
75
0
        F: FnMut(&'a T) -> R,
76
0
    {
77
0
        borrow(&self.section).into()
78
0
    }
79
}
80
81
impl<R> Section<R> for DebugAranges<R> {
82
0
    fn id() -> SectionId {
83
0
        SectionId::DebugAranges
84
0
    }
85
86
0
    fn reader(&self) -> &R {
87
0
        &self.section
88
0
    }
89
}
90
91
impl<R> From<R> for DebugAranges<R> {
92
0
    fn from(section: R) -> Self {
93
0
        DebugAranges { section }
94
0
    }
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.
106
0
    pub fn next(&mut self) -> Result<Option<ArangeHeader<R>>> {
107
0
        if self.input.is_empty() {
108
0
            return Ok(None);
109
0
        }
110
0
111
0
        let len = self.input.len();
112
0
        match ArangeHeader::parse(&mut self.input, self.offset) {
113
0
            Ok(header) => {
114
0
                self.offset.0 += len - self.input.len();
115
0
                Ok(Some(header))
116
            }
117
0
            Err(e) => {
118
0
                self.input.empty();
119
0
                Err(e)
120
            }
121
        }
122
0
    }
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
130
0
    fn next(&mut self) -> ::core::result::Result<Option<Self::Item>, Self::Error> {
131
0
        ArangeHeaderIter::next(self)
132
0
    }
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
{
157
0
    fn parse(input: &mut R, offset: DebugArangesOffset<Offset>) -> Result<Self> {
158
0
        let (length, format) = input.read_initial_length()?;
159
0
        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
0
        let version = rest.read_u16()?;
166
0
        if version != 2 && version != 3 {
167
0
            return Err(Error::UnknownVersion(u64::from(version)));
168
0
        }
169
170
0
        let debug_info_offset = rest.read_offset(format).map(DebugInfoOffset)?;
171
0
        let address_size = rest.read_u8()?;
172
0
        let segment_size = rest.read_u8()?;
173
174
        // unit_length + version + offset + address_size + segment_size
175
0
        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
0
        let tuple_length = address_size
181
0
            .checked_mul(2)
182
0
            .and_then(|x| x.checked_add(segment_size))
183
0
            .ok_or(Error::InvalidAddressRange)?;
184
0
        if tuple_length == 0 {
185
0
            return Err(Error::InvalidAddressRange)?;
186
0
        }
187
0
        let padding = if header_length % tuple_length == 0 {
188
0
            0
189
        } else {
190
0
            tuple_length - header_length % tuple_length
191
        };
192
0
        rest.skip(R::Offset::from_u8(padding))?;
193
194
0
        let encoding = Encoding {
195
0
            format,
196
0
            version,
197
0
            address_size,
198
0
            // TODO: segment_size
199
0
        };
200
0
        Ok(ArangeHeader {
201
0
            offset,
202
0
            encoding,
203
0
            length,
204
0
            debug_info_offset,
205
0
            segment_size,
206
0
            entries: rest,
207
0
        })
208
0
    }
209
210
    /// Return the offset of this header within the `.debug_aranges` section.
211
    #[inline]
212
0
    pub fn offset(&self) -> DebugArangesOffset<Offset> {
213
0
        self.offset
214
0
    }
215
216
    /// Return the length of this set of entries, including the header.
217
    #[inline]
218
0
    pub fn length(&self) -> Offset {
219
0
        self.length
220
0
    }
221
222
    /// Return the encoding parameters for this set of entries.
223
    #[inline]
224
0
    pub fn encoding(&self) -> Encoding {
225
0
        self.encoding
226
0
    }
227
228
    /// Return the segment size for this set of entries.
229
    #[inline]
230
0
    pub fn segment_size(&self) -> u8 {
231
0
        self.segment_size
232
0
    }
233
234
    /// Return the offset into the .debug_info section for this set of arange entries.
235
    #[inline]
236
0
    pub fn debug_info_offset(&self) -> DebugInfoOffset<Offset> {
237
0
        self.debug_info_offset
238
0
    }
239
240
    /// Return the arange entries in this set.
241
    #[inline]
242
0
    pub fn entries(&self) -> ArangeEntryIter<R> {
243
0
        ArangeEntryIter {
244
0
            input: self.entries.clone(),
245
0
            encoding: self.encoding,
246
0
            segment_size: self.segment_size,
247
0
        }
248
0
    }
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)`.
269
0
    pub fn next(&mut self) -> Result<Option<ArangeEntry>> {
270
0
        if self.input.is_empty() {
271
0
            return Ok(None);
272
0
        }
273
0
274
0
        match ArangeEntry::parse(&mut self.input, self.encoding, self.segment_size) {
275
0
            Ok(Some(entry)) => Ok(Some(entry)),
276
            Ok(None) => {
277
0
                self.input.empty();
278
0
                Ok(None)
279
            }
280
0
            Err(e) => {
281
0
                self.input.empty();
282
0
                Err(e)
283
            }
284
        }
285
0
    }
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
293
0
    fn next(&mut self) -> ::core::result::Result<Option<Self::Item>, Self::Error> {
294
0
        ArangeEntryIter::next(self)
295
0
    }
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.
308
0
    fn parse<R: Reader>(
309
0
        input: &mut R,
310
0
        encoding: Encoding,
311
0
        segment_size: u8,
312
0
    ) -> Result<Option<Self>> {
313
0
        let address_size = encoding.address_size;
314
0
315
0
        let tuple_length = R::Offset::from_u8(2 * address_size + segment_size);
316
0
        if tuple_length > input.len() {
317
0
            input.empty();
318
0
            return Ok(None);
319
0
        }
320
321
0
        let segment = if segment_size != 0 {
322
0
            input.read_address(segment_size)?
323
        } else {
324
0
            0
325
        };
326
0
        let address = input.read_address(address_size)?;
327
0
        let length = input.read_address(address_size)?;
328
329
0
        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, 0) => Self::parse(input, encoding, segment_size),
334
            _ => Ok(Some(ArangeEntry {
335
0
                segment: if segment_size != 0 {
336
0
                    Some(segment)
337
                } else {
338
0
                    None
339
                },
340
0
                address,
341
0
                length,
342
            })),
343
        }
344
0
    }
345
346
    /// Return the segment selector of this arange.
347
    #[inline]
348
0
    pub fn segment(&self) -> Option<u64> {
349
0
        self.segment
350
0
    }
351
352
    /// Return the beginning address of this arange.
353
    #[inline]
354
0
    pub fn address(&self) -> u64 {
355
0
        self.address
356
0
    }
357
358
    /// Return the length of this arange.
359
    #[inline]
360
0
    pub fn length(&self) -> u64 {
361
0
        self.length
362
0
    }
363
364
    /// Return the range.
365
    #[inline]
366
0
    pub fn range(&self) -> Range {
367
0
        Range {
368
0
            begin: self.address,
369
0
            end: self.address.wrapping_add(self.length),
370
0
        }
371
0
    }
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]
382
    fn test_iterate_headers() {
383
        #[rustfmt::skip]
384
        let buf = [
385
            // 32-bit length = 28.
386
            0x1c, 0x00, 0x00, 0x00,
387
            // Version.
388
            0x02, 0x00,
389
            // Offset.
390
            0x01, 0x02, 0x03, 0x04,
391
            // Address size.
392
            0x04,
393
            // Segment size.
394
            0x00,
395
            // Dummy padding and arange tuples.
396
            0x00, 0x00, 0x00, 0x00,
397
            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
398
            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
399
400
            // 32-bit length = 36.
401
            0x24, 0x00, 0x00, 0x00,
402
            // Version.
403
            0x02, 0x00,
404
            // Offset.
405
            0x11, 0x12, 0x13, 0x14,
406
            // Address size.
407
            0x04,
408
            // Segment size.
409
            0x00,
410
            // Dummy padding and arange tuples.
411
            0x00, 0x00, 0x00, 0x00,
412
            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
413
            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
414
            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
415
        ];
416
417
        let debug_aranges = DebugAranges::new(&buf, LittleEndian);
418
        let mut headers = debug_aranges.headers();
419
420
        let header = headers
421
            .next()
422
            .expect("should parse header ok")
423
            .expect("should have a header");
424
        assert_eq!(header.offset(), DebugArangesOffset(0));
425
        assert_eq!(header.debug_info_offset(), DebugInfoOffset(0x0403_0201));
426
427
        let header = headers
428
            .next()
429
            .expect("should parse header ok")
430
            .expect("should have a header");
431
        assert_eq!(header.offset(), DebugArangesOffset(0x20));
432
        assert_eq!(header.debug_info_offset(), DebugInfoOffset(0x1413_1211));
433
    }
434
435
    #[test]
436
    fn test_parse_header_ok() {
437
        #[rustfmt::skip]
438
        let buf = [
439
            // 32-bit length = 32.
440
            0x20, 0x00, 0x00, 0x00,
441
            // Version.
442
            0x02, 0x00,
443
            // Offset.
444
            0x01, 0x02, 0x03, 0x04,
445
            // Address size.
446
            0x08,
447
            // Segment size.
448
            0x04,
449
            // Length to here = 12, tuple length = 20.
450
            // Padding to tuple length multiple = 4.
451
            0x10, 0x00, 0x00, 0x00,
452
            0x00, 0x00, 0x00, 0x00,
453
454
            // Dummy arange tuple data.
455
            0x20, 0x00, 0x00, 0x00,
456
            0x00, 0x00, 0x00, 0x00,
457
            0x00, 0x00, 0x00, 0x00,
458
            0x00, 0x00, 0x00, 0x00,
459
460
            // Dummy next arange.
461
            0x30, 0x00, 0x00, 0x00,
462
            0x00, 0x00, 0x00, 0x00,
463
            0x00, 0x00, 0x00, 0x00,
464
            0x00, 0x00, 0x00, 0x00,
465
        ];
466
467
        let rest = &mut EndianSlice::new(&buf, LittleEndian);
468
469
        let header =
470
            ArangeHeader::parse(rest, DebugArangesOffset(0x10)).expect("should parse header ok");
471
472
        assert_eq!(
473
            *rest,
474
            EndianSlice::new(&buf[buf.len() - 16..], LittleEndian)
475
        );
476
        assert_eq!(
477
            header,
478
            ArangeHeader {
479
                offset: DebugArangesOffset(0x10),
480
                encoding: Encoding {
481
                    format: Format::Dwarf32,
482
                    version: 2,
483
                    address_size: 8,
484
                },
485
                length: 0x20,
486
                debug_info_offset: DebugInfoOffset(0x0403_0201),
487
                segment_size: 4,
488
                entries: EndianSlice::new(&buf[buf.len() - 32..buf.len() - 16], LittleEndian),
489
            }
490
        );
491
    }
492
493
    #[test]
494
    fn test_parse_header_overflow_error() {
495
        #[rustfmt::skip]
496
        let buf = [
497
            // 32-bit length = 32.
498
            0x20, 0x00, 0x00, 0x00,
499
            // Version.
500
            0x02, 0x00,
501
            // Offset.
502
            0x01, 0x02, 0x03, 0x04,
503
            // Address size.
504
            0xff,
505
            // Segment size.
506
            0xff,
507
            // Length to here = 12, tuple length = 20.
508
            // Padding to tuple length multiple = 4.
509
            0x10, 0x00, 0x00, 0x00,
510
            0x00, 0x00, 0x00, 0x00,
511
512
            // Dummy arange tuple data.
513
            0x20, 0x00, 0x00, 0x00,
514
            0x00, 0x00, 0x00, 0x00,
515
            0x00, 0x00, 0x00, 0x00,
516
            0x00, 0x00, 0x00, 0x00,
517
518
            // Dummy next arange.
519
            0x30, 0x00, 0x00, 0x00,
520
            0x00, 0x00, 0x00, 0x00,
521
            0x00, 0x00, 0x00, 0x00,
522
            0x00, 0x00, 0x00, 0x00,
523
        ];
524
525
        let rest = &mut EndianSlice::new(&buf, LittleEndian);
526
527
        let error = ArangeHeader::parse(rest, DebugArangesOffset(0x10))
528
            .expect_err("should fail to parse header");
529
        assert_eq!(error, Error::InvalidAddressRange);
530
    }
531
532
    #[test]
533
    fn test_parse_header_div_by_zero_error() {
534
        #[rustfmt::skip]
535
        let buf = [
536
            // 32-bit length = 32.
537
            0x20, 0x00, 0x00, 0x00,
538
            // Version.
539
            0x02, 0x00,
540
            // Offset.
541
            0x01, 0x02, 0x03, 0x04,
542
            // Address size = 0. Could cause a division by zero if we aren't
543
            // careful.
544
            0x00,
545
            // Segment size.
546
            0x00,
547
            // Length to here = 12, tuple length = 20.
548
            // Padding to tuple length multiple = 4.
549
            0x10, 0x00, 0x00, 0x00,
550
            0x00, 0x00, 0x00, 0x00,
551
552
            // Dummy arange tuple data.
553
            0x20, 0x00, 0x00, 0x00,
554
            0x00, 0x00, 0x00, 0x00,
555
            0x00, 0x00, 0x00, 0x00,
556
            0x00, 0x00, 0x00, 0x00,
557
558
            // Dummy next arange.
559
            0x30, 0x00, 0x00, 0x00,
560
            0x00, 0x00, 0x00, 0x00,
561
            0x00, 0x00, 0x00, 0x00,
562
            0x00, 0x00, 0x00, 0x00,
563
        ];
564
565
        let rest = &mut EndianSlice::new(&buf, LittleEndian);
566
567
        let error = ArangeHeader::parse(rest, DebugArangesOffset(0x10))
568
            .expect_err("should fail to parse header");
569
        assert_eq!(error, Error::InvalidAddressRange);
570
    }
571
572
    #[test]
573
    fn test_parse_entry_ok() {
574
        let encoding = Encoding {
575
            format: Format::Dwarf32,
576
            version: 2,
577
            address_size: 4,
578
        };
579
        let segment_size = 0;
580
        let buf = [0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09];
581
        let rest = &mut EndianSlice::new(&buf, LittleEndian);
582
        let entry =
583
            ArangeEntry::parse(rest, encoding, segment_size).expect("should parse entry ok");
584
        assert_eq!(*rest, EndianSlice::new(&buf[buf.len() - 1..], LittleEndian));
585
        assert_eq!(
586
            entry,
587
            Some(ArangeEntry {
588
                segment: None,
589
                address: 0x0403_0201,
590
                length: 0x0807_0605,
591
            })
592
        );
593
    }
594
595
    #[test]
596
    fn test_parse_entry_segment() {
597
        let encoding = Encoding {
598
            format: Format::Dwarf32,
599
            version: 2,
600
            address_size: 4,
601
        };
602
        let segment_size = 8;
603
        #[rustfmt::skip]
604
        let buf = [
605
            // Segment.
606
            0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18,
607
            // Address.
608
            0x01, 0x02, 0x03, 0x04,
609
            // Length.
610
            0x05, 0x06, 0x07, 0x08,
611
            // Next tuple.
612
            0x09
613
        ];
614
        let rest = &mut EndianSlice::new(&buf, LittleEndian);
615
        let entry =
616
            ArangeEntry::parse(rest, encoding, segment_size).expect("should parse entry ok");
617
        assert_eq!(*rest, EndianSlice::new(&buf[buf.len() - 1..], LittleEndian));
618
        assert_eq!(
619
            entry,
620
            Some(ArangeEntry {
621
                segment: Some(0x1817_1615_1413_1211),
622
                address: 0x0403_0201,
623
                length: 0x0807_0605,
624
            })
625
        );
626
    }
627
628
    #[test]
629
    fn test_parse_entry_zero() {
630
        let encoding = Encoding {
631
            format: Format::Dwarf32,
632
            version: 2,
633
            address_size: 4,
634
        };
635
        let segment_size = 0;
636
        #[rustfmt::skip]
637
        let buf = [
638
            // Zero tuple.
639
            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
640
            // Address.
641
            0x01, 0x02, 0x03, 0x04,
642
            // Length.
643
            0x05, 0x06, 0x07, 0x08,
644
            // Next tuple.
645
            0x09
646
        ];
647
        let rest = &mut EndianSlice::new(&buf, LittleEndian);
648
        let entry =
649
            ArangeEntry::parse(rest, encoding, segment_size).expect("should parse entry ok");
650
        assert_eq!(*rest, EndianSlice::new(&buf[buf.len() - 1..], LittleEndian));
651
        assert_eq!(
652
            entry,
653
            Some(ArangeEntry {
654
                segment: None,
655
                address: 0x0403_0201,
656
                length: 0x0807_0605,
657
            })
658
        );
659
    }
660
}