Coverage Report

Created: 2026-04-29 06:53

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/rust/registry/src/index.crates.io-1949cf8c6b5b557f/gimli-0.32.3/src/read/mod.rs
Line
Count
Source
1
//! Read DWARF debugging information.
2
//!
3
//! * [Example Usage](#example-usage)
4
//! * [API Structure](#api-structure)
5
//! * [Using with `FallibleIterator`](#using-with-fallibleiterator)
6
//!
7
//! ## Example Usage
8
//!
9
//! Print out all of the functions in the debuggee program:
10
//!
11
//! ```rust,no_run
12
//! # fn example() -> Result<(), gimli::Error> {
13
//! # type R = gimli::EndianSlice<'static, gimli::LittleEndian>;
14
//! # let get_file_section_reader = |name| -> Result<R, gimli::Error> { unimplemented!() };
15
//! # let get_sup_file_section_reader = |name| -> Result<R, gimli::Error> { unimplemented!() };
16
//! // Read the DWARF sections with whatever object loader you're using.
17
//! // These closures should return a `Reader` instance (e.g. `EndianSlice`).
18
//! let loader = |section: gimli::SectionId| { get_file_section_reader(section.name()) };
19
//! let sup_loader = |section: gimli::SectionId| { get_sup_file_section_reader(section.name()) };
20
//! let mut dwarf = gimli::Dwarf::load(loader)?;
21
//! dwarf.load_sup(sup_loader)?;
22
//!
23
//! // Iterate over all compilation units.
24
//! let mut iter = dwarf.units();
25
//! while let Some(header) = iter.next()? {
26
//!     // Parse the abbreviations and other information for this compilation unit.
27
//!     let unit = dwarf.unit(header)?;
28
//!
29
//!     // Iterate over all of this compilation unit's entries.
30
//!     let mut entries = unit.entries();
31
//!     while let Some((_, entry)) = entries.next_dfs()? {
32
//!         // If we find an entry for a function, print it.
33
//!         if entry.tag() == gimli::DW_TAG_subprogram {
34
//!             println!("Found a function: {:?}", entry);
35
//!         }
36
//!     }
37
//! }
38
//! # unreachable!()
39
//! # }
40
//! ```
41
//!
42
//! Full example programs:
43
//!
44
//!   * [A simple `.debug_info` parser](https://github.com/gimli-rs/gimli/blob/master/crates/examples/src/bin/simple.rs)
45
//!
46
//!   * [A simple `.debug_line` parser](https://github.com/gimli-rs/gimli/blob/master/crates/examples/src/bin/simple_line.rs)
47
//!
48
//!   * [A `dwarfdump`
49
//!     clone](https://github.com/gimli-rs/gimli/blob/master/crates/examples/src/bin/dwarfdump.rs)
50
//!
51
//!   * [An `addr2line` clone](https://github.com/gimli-rs/addr2line)
52
//!
53
//!   * [`ddbug`](https://github.com/gimli-rs/ddbug), a utility giving insight into
54
//!     code generation by making debugging information readable
55
//!
56
//!   * [`dwprod`](https://github.com/fitzgen/dwprod), a tiny utility to list the
57
//!     compilers used to create each compilation unit within a shared library or
58
//!     executable (via `DW_AT_producer`)
59
//!
60
//!   * [`dwarf-validate`](https://github.com/gimli-rs/gimli/blob/master/crates/examples/src/bin/dwarf-validate.rs),
61
//!     a program to validate the integrity of some DWARF and its references
62
//!     between sections and compilation units.
63
//!
64
//! ## API Structure
65
//!
66
//! * Basic familiarity with DWARF is assumed.
67
//!
68
//! * The [`Dwarf`](./struct.Dwarf.html) type contains the commonly used DWARF
69
//!   sections. It has methods that simplify access to debugging data that spans
70
//!   multiple sections. Use of this type is optional, but recommended.
71
//!
72
//! * The [`DwarfPackage`](./struct.Dwarf.html) type contains the DWARF
73
//!   package (DWP) sections. It has methods to find a DWARF object (DWO)
74
//!   within the package.
75
//!
76
//! * Each section gets its own type. Consider these types the entry points to
77
//!   the library:
78
//!
79
//!   * [`DebugAbbrev`](./struct.DebugAbbrev.html): The `.debug_abbrev` section.
80
//!
81
//!   * [`DebugAddr`](./struct.DebugAddr.html): The `.debug_addr` section.
82
//!
83
//!   * [`DebugAranges`](./struct.DebugAranges.html): The `.debug_aranges`
84
//!     section.
85
//!
86
//!   * [`DebugFrame`](./struct.DebugFrame.html): The `.debug_frame` section.
87
//!
88
//!   * [`DebugInfo`](./struct.DebugInfo.html): The `.debug_info` section.
89
//!
90
//!   * [`DebugLine`](./struct.DebugLine.html): The `.debug_line` section.
91
//!
92
//!   * [`DebugLineStr`](./struct.DebugLineStr.html): The `.debug_line_str` section.
93
//!
94
//!   * [`DebugLoc`](./struct.DebugLoc.html): The `.debug_loc` section.
95
//!
96
//!   * [`DebugLocLists`](./struct.DebugLocLists.html): The `.debug_loclists` section.
97
//!
98
//!   * [`DebugPubNames`](./struct.DebugPubNames.html): The `.debug_pubnames`
99
//!     section.
100
//!
101
//!   * [`DebugPubTypes`](./struct.DebugPubTypes.html): The `.debug_pubtypes`
102
//!     section.
103
//!
104
//!   * [`DebugRanges`](./struct.DebugRanges.html): The `.debug_ranges` section.
105
//!
106
//!   * [`DebugRngLists`](./struct.DebugRngLists.html): The `.debug_rnglists` section.
107
//!
108
//!   * [`DebugStr`](./struct.DebugStr.html): The `.debug_str` section.
109
//!
110
//!   * [`DebugStrOffsets`](./struct.DebugStrOffsets.html): The `.debug_str_offsets` section.
111
//!
112
//!   * [`DebugTypes`](./struct.DebugTypes.html): The `.debug_types` section.
113
//!
114
//!   * [`DebugCuIndex`](./struct.DebugCuIndex.html): The `.debug_cu_index` section.
115
//!
116
//!   * [`DebugTuIndex`](./struct.DebugTuIndex.html): The `.debug_tu_index` section.
117
//!
118
//!   * [`EhFrame`](./struct.EhFrame.html): The `.eh_frame` section.
119
//!
120
//!   * [`EhFrameHdr`](./struct.EhFrameHdr.html): The `.eh_frame_hdr` section.
121
//!
122
//! * Each section type exposes methods for accessing the debugging data encoded
123
//!   in that section. For example, the [`DebugInfo`](./struct.DebugInfo.html)
124
//!   struct has the [`units`](./struct.DebugInfo.html#method.units) method for
125
//!   iterating over the compilation units defined within it.
126
//!
127
//! * Offsets into a section are strongly typed: an offset into `.debug_info` is
128
//!   the [`DebugInfoOffset`](./struct.DebugInfoOffset.html) type. It cannot be
129
//!   used to index into the [`DebugLine`](./struct.DebugLine.html) type because
130
//!   `DebugLine` represents the `.debug_line` section. There are similar types
131
//!   for offsets relative to a compilation unit rather than a section.
132
//!
133
//! ## Using with `FallibleIterator`
134
//!
135
//! The standard library's `Iterator` trait and related APIs do not play well
136
//! with iterators where the `next` operation is fallible. One can make the
137
//! `Iterator`'s associated `Item` type be a `Result<T, E>`, however the
138
//! provided methods cannot gracefully handle the case when an `Err` is
139
//! returned.
140
//!
141
//! This situation led to the
142
//! [`fallible-iterator`](https://crates.io/crates/fallible-iterator) crate's
143
//! existence. You can read more of the rationale for its existence in its
144
//! docs. The crate provides the helpers you have come to expect (eg `map`,
145
//! `filter`, etc) for iterators that can fail.
146
//!
147
//! `gimli`'s many lazy parsing iterators are a perfect match for the
148
//! `fallible-iterator` crate's `FallibleIterator` trait because parsing is not
149
//! done eagerly. Parse errors later in the input might only be discovered after
150
//! having iterated through many items.
151
//!
152
//! To use `gimli` iterators with `FallibleIterator`, import the crate and trait
153
//! into your code:
154
//!
155
//! ```
156
//! # #[cfg(feature = "fallible-iterator")]
157
//! # fn foo() {
158
//! // Use the `FallibleIterator` trait so its methods are in scope!
159
//! use fallible_iterator::FallibleIterator;
160
//! use gimli::{DebugAranges, EndianSlice, LittleEndian};
161
//!
162
//! fn find_sum_of_address_range_lengths(aranges: DebugAranges<EndianSlice<LittleEndian>>)
163
//!     -> gimli::Result<u64>
164
//! {
165
//!     // `DebugAranges::headers` returns a `FallibleIterator`!
166
//!     aranges.headers()
167
//!         // `flat_map` is provided by `FallibleIterator`!
168
//!         .flat_map(|header| Ok(header.entries()))
169
//!         // `map` is provided by `FallibleIterator`!
170
//!         .map(|arange| Ok(arange.length()))
171
//!         // `fold` is provided by `FallibleIterator`!
172
//!         .fold(0, |sum, len| Ok(sum + len))
173
//! }
174
//! # }
175
//! # fn main() {}
176
//! ```
177
178
use core::fmt::{self, Debug};
179
use core::result;
180
#[cfg(feature = "std")]
181
use std::{error, io};
182
183
use crate::common::{Register, SectionId};
184
use crate::constants;
185
186
mod util;
187
pub use util::*;
188
189
mod addr;
190
pub use self::addr::*;
191
192
mod cfi;
193
pub use self::cfi::*;
194
195
#[cfg(feature = "read")]
196
mod dwarf;
197
#[cfg(feature = "read")]
198
pub use self::dwarf::*;
199
200
mod endian_slice;
201
pub use self::endian_slice::*;
202
203
#[cfg(feature = "endian-reader")]
204
mod endian_reader;
205
#[cfg(feature = "endian-reader")]
206
pub use self::endian_reader::*;
207
208
mod reader;
209
pub use self::reader::*;
210
211
mod relocate;
212
pub use self::relocate::*;
213
214
#[cfg(feature = "read")]
215
mod abbrev;
216
#[cfg(feature = "read")]
217
pub use self::abbrev::*;
218
219
mod aranges;
220
pub use self::aranges::*;
221
222
mod index;
223
pub use self::index::*;
224
225
#[cfg(feature = "read")]
226
mod line;
227
#[cfg(feature = "read")]
228
pub use self::line::*;
229
230
mod lists;
231
232
mod loclists;
233
pub use self::loclists::*;
234
235
#[cfg(feature = "read")]
236
mod lookup;
237
238
#[cfg(feature = "read")]
239
mod macros;
240
#[cfg(feature = "read")]
241
pub use self::macros::*;
242
243
mod op;
244
pub use self::op::*;
245
246
#[cfg(feature = "read")]
247
mod pubnames;
248
#[cfg(feature = "read")]
249
pub use self::pubnames::*;
250
251
#[cfg(feature = "read")]
252
mod pubtypes;
253
#[cfg(feature = "read")]
254
pub use self::pubtypes::*;
255
256
mod rnglists;
257
pub use self::rnglists::*;
258
259
mod str;
260
pub use self::str::*;
261
262
/// An offset into the current compilation or type unit.
263
#[derive(Debug, Clone, Copy, PartialEq, Eq, Ord, PartialOrd, Hash)]
264
pub struct UnitOffset<T = usize>(pub T);
265
266
#[cfg(feature = "read")]
267
mod unit;
268
#[cfg(feature = "read")]
269
pub use self::unit::*;
270
271
mod value;
272
pub use self::value::*;
273
274
/// Indicates that storage should be allocated on heap.
275
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
276
pub struct StoreOnHeap;
277
278
/// `EndianBuf` has been renamed to `EndianSlice`. For ease of upgrading across
279
/// `gimli` versions, we export this type alias.
280
#[deprecated(note = "EndianBuf has been renamed to EndianSlice, use that instead.")]
281
pub type EndianBuf<'input, Endian> = EndianSlice<'input, Endian>;
282
283
/// An error that occurred when parsing.
284
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
285
#[non_exhaustive]
286
pub enum Error {
287
    /// An I/O error occurred while reading.
288
    Io,
289
    /// Found a PC relative pointer, but the section base is undefined.
290
    PcRelativePointerButSectionBaseIsUndefined,
291
    /// Found a `.text` relative pointer, but the `.text` base is undefined.
292
    TextRelativePointerButTextBaseIsUndefined,
293
    /// Found a data relative pointer, but the data base is undefined.
294
    DataRelativePointerButDataBaseIsUndefined,
295
    /// Found a function relative pointer in a context that does not have a
296
    /// function base.
297
    FuncRelativePointerInBadContext,
298
    /// Cannot parse a pointer with a `DW_EH_PE_omit` encoding.
299
    CannotParseOmitPointerEncoding,
300
    /// An error parsing an unsigned LEB128 value.
301
    BadUnsignedLeb128,
302
    /// An error parsing a signed LEB128 value.
303
    BadSignedLeb128,
304
    /// An abbreviation declared that its tag is zero, but zero is reserved for
305
    /// null records.
306
    AbbreviationTagZero,
307
    /// An attribute specification declared that its form is zero, but zero is
308
    /// reserved for null records.
309
    AttributeFormZero,
310
    /// The abbreviation's has-children byte was not one of
311
    /// `DW_CHILDREN_{yes,no}`.
312
    BadHasChildren,
313
    /// The specified length is impossible.
314
    BadLength,
315
    /// Found an unknown `DW_FORM_*` type.
316
    UnknownForm(constants::DwForm),
317
    /// Expected a zero, found something else.
318
    ExpectedZero,
319
    /// Found an abbreviation code that has already been used.
320
    DuplicateAbbreviationCode,
321
    /// Found a duplicate arange.
322
    DuplicateArange,
323
    /// Found an unknown reserved length value.
324
    UnknownReservedLength,
325
    /// Found an unknown DWARF version.
326
    UnknownVersion(u64),
327
    /// Found a record with an unknown abbreviation code.
328
    UnknownAbbreviation(u64),
329
    /// Hit the end of input before it was expected.
330
    UnexpectedEof(ReaderOffsetId),
331
    /// Read a null entry before it was expected.
332
    UnexpectedNull,
333
    /// Found an unknown standard opcode.
334
    UnknownStandardOpcode(constants::DwLns),
335
    /// Found an unknown extended opcode.
336
    UnknownExtendedOpcode(constants::DwLne),
337
    /// Found an unknown location-lists format.
338
    UnknownLocListsEntry(constants::DwLle),
339
    /// Found an unknown range-lists format.
340
    UnknownRangeListsEntry(constants::DwRle),
341
    /// The specified address size is not supported.
342
    UnsupportedAddressSize(u8),
343
    /// The specified offset size is not supported.
344
    UnsupportedOffsetSize(u8),
345
    /// The specified field size is not supported.
346
    UnsupportedFieldSize(u8),
347
    /// The minimum instruction length must not be zero.
348
    MinimumInstructionLengthZero,
349
    /// The maximum operations per instruction must not be zero.
350
    MaximumOperationsPerInstructionZero,
351
    /// The line range must not be zero.
352
    LineRangeZero,
353
    /// The opcode base must not be zero.
354
    OpcodeBaseZero,
355
    /// Found an invalid UTF-8 string.
356
    BadUtf8,
357
    /// Expected to find the CIE ID, but found something else.
358
    NotCieId,
359
    /// Expected to find a pointer to a CIE, but found the CIE ID instead.
360
    NotCiePointer,
361
    /// Expected to find a pointer to an FDE, but found a CIE instead.
362
    NotFdePointer,
363
    /// Invalid branch target for a DW_OP_bra or DW_OP_skip.
364
    BadBranchTarget(u64),
365
    /// DW_OP_push_object_address used but no address passed in.
366
    InvalidPushObjectAddress,
367
    /// Not enough items on the stack when evaluating an expression.
368
    NotEnoughStackItems,
369
    /// Too many iterations to compute the expression.
370
    TooManyIterations,
371
    /// An unrecognized operation was found while parsing a DWARF
372
    /// expression.
373
    InvalidExpression(constants::DwOp),
374
    /// An unsupported operation was found while evaluating a DWARF expression.
375
    UnsupportedEvaluation,
376
    /// The expression had a piece followed by an expression
377
    /// terminator without a piece.
378
    InvalidPiece,
379
    /// An expression-terminating operation was followed by something
380
    /// other than the end of the expression or a piece operation.
381
    InvalidExpressionTerminator(u64),
382
    /// Division or modulus by zero when evaluating an expression.
383
    DivisionByZero,
384
    /// An expression operation used mismatching types.
385
    TypeMismatch,
386
    /// An expression operation required an integral type but saw a
387
    /// floating point type.
388
    IntegralTypeRequired,
389
    /// An expression operation used types that are not supported.
390
    UnsupportedTypeOperation,
391
    /// The shift value in an expression must be a non-negative integer.
392
    InvalidShiftExpression,
393
    /// The size of a deref expression must not be larger than the size of an address.
394
    InvalidDerefSize(u8),
395
    /// An unknown DW_CFA_* instruction.
396
    UnknownCallFrameInstruction(constants::DwCfa),
397
    /// The end of an address range was before the beginning.
398
    InvalidAddressRange,
399
    /// An address calculation overflowed.
400
    ///
401
    /// This is returned in cases where the address is expected to be
402
    /// larger than a previous address, but the calculation overflowed.
403
    AddressOverflow,
404
    /// Encountered a call frame instruction in a context in which it is not
405
    /// valid.
406
    CfiInstructionInInvalidContext,
407
    /// When evaluating call frame instructions, found a `DW_CFA_restore_state`
408
    /// stack pop instruction, but the stack was empty, and had nothing to pop.
409
    PopWithEmptyStack,
410
    /// Do not have unwind info for the given address.
411
    NoUnwindInfoForAddress,
412
    /// An offset value was larger than the maximum supported value.
413
    UnsupportedOffset,
414
    /// The given pointer encoding is either unknown or invalid.
415
    UnknownPointerEncoding(constants::DwEhPe),
416
    /// Did not find an entry at the given offset.
417
    NoEntryAtGivenOffset,
418
    /// The given offset is out of bounds.
419
    OffsetOutOfBounds,
420
    /// Found an unknown CFI augmentation.
421
    UnknownAugmentation,
422
    /// We do not support the given pointer encoding yet.
423
    UnsupportedPointerEncoding,
424
    /// Registers larger than `u16` are not supported.
425
    UnsupportedRegister(u64),
426
    /// The CFI program defined more register rules than we have storage for.
427
    TooManyRegisterRules,
428
    /// Attempted to push onto the CFI or evaluation stack, but it was already
429
    /// at full capacity.
430
    StackFull,
431
    /// The `.eh_frame_hdr` binary search table claims to be variable-length encoded,
432
    /// which makes binary search impossible.
433
    VariableLengthSearchTable,
434
    /// The `DW_UT_*` value for this unit is not supported yet.
435
    UnsupportedUnitType,
436
    /// Ranges using AddressIndex are not supported yet.
437
    UnsupportedAddressIndex,
438
    /// Nonzero segment selector sizes aren't supported yet.
439
    UnsupportedSegmentSize,
440
    /// A compilation unit or type unit is missing its top level DIE.
441
    MissingUnitDie,
442
    /// A DIE attribute used an unsupported form.
443
    UnsupportedAttributeForm,
444
    /// Missing DW_LNCT_path in file entry format.
445
    MissingFileEntryFormatPath,
446
    /// Expected an attribute value to be a string form.
447
    ExpectedStringAttributeValue,
448
    /// `DW_FORM_implicit_const` used in an invalid context.
449
    InvalidImplicitConst,
450
    /// Invalid section count in `.dwp` index.
451
    InvalidIndexSectionCount,
452
    /// Invalid slot count in `.dwp` index.
453
    InvalidIndexSlotCount,
454
    /// Invalid hash row in `.dwp` index.
455
    InvalidIndexRow,
456
    /// Unknown section type in `.dwp` index.
457
    UnknownIndexSection(constants::DwSect),
458
    /// Unknown section type in version 2 `.dwp` index.
459
    UnknownIndexSectionV2(constants::DwSectV2),
460
    /// Invalid macinfo type in `.debug_macinfo`.
461
    InvalidMacinfoType(constants::DwMacinfo),
462
    /// Invalid macro type in `.debug_macro`.
463
    InvalidMacroType(constants::DwMacro),
464
    /// The optional `opcode_operands_table` in `.debug_macro` is currently not supported.
465
    UnsupportedOpcodeOperandsTable,
466
}
467
468
impl fmt::Display for Error {
469
    #[inline]
470
0
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> ::core::result::Result<(), fmt::Error> {
471
0
        write!(f, "{}", self.description())
472
0
    }
473
}
474
475
impl Error {
476
    /// A short description of the error.
477
0
    pub fn description(&self) -> &str {
478
0
        match *self {
479
0
            Error::Io => "An I/O error occurred while reading.",
480
            Error::PcRelativePointerButSectionBaseIsUndefined => {
481
0
                "Found a PC relative pointer, but the section base is undefined."
482
            }
483
            Error::TextRelativePointerButTextBaseIsUndefined => {
484
0
                "Found a `.text` relative pointer, but the `.text` base is undefined."
485
            }
486
            Error::DataRelativePointerButDataBaseIsUndefined => {
487
0
                "Found a data relative pointer, but the data base is undefined."
488
            }
489
            Error::FuncRelativePointerInBadContext => {
490
0
                "Found a function relative pointer in a context that does not have a function base."
491
            }
492
            Error::CannotParseOmitPointerEncoding => {
493
0
                "Cannot parse a pointer with a `DW_EH_PE_omit` encoding."
494
            }
495
0
            Error::BadUnsignedLeb128 => "An error parsing an unsigned LEB128 value",
496
0
            Error::BadSignedLeb128 => "An error parsing a signed LEB128 value",
497
            Error::AbbreviationTagZero => {
498
0
                "An abbreviation declared that its tag is zero,
499
0
                 but zero is reserved for null records"
500
            }
501
            Error::AttributeFormZero => {
502
0
                "An attribute specification declared that its form is zero,
503
0
                 but zero is reserved for null records"
504
            }
505
            Error::BadHasChildren => {
506
0
                "The abbreviation's has-children byte was not one of
507
0
                 `DW_CHILDREN_{yes,no}`"
508
            }
509
0
            Error::BadLength => "The specified length is impossible",
510
0
            Error::UnknownForm(_) => "Found an unknown `DW_FORM_*` type",
511
0
            Error::ExpectedZero => "Expected a zero, found something else",
512
            Error::DuplicateAbbreviationCode => {
513
0
                "Found an abbreviation code that has already been used"
514
            }
515
0
            Error::DuplicateArange => "Found a duplicate arange",
516
0
            Error::UnknownReservedLength => "Found an unknown reserved length value",
517
0
            Error::UnknownVersion(_) => "Found an unknown DWARF version",
518
0
            Error::UnknownAbbreviation(_) => "Found a record with an unknown abbreviation code",
519
0
            Error::UnexpectedEof(_) => "Hit the end of input before it was expected",
520
0
            Error::UnexpectedNull => "Read a null entry before it was expected.",
521
0
            Error::UnknownStandardOpcode(_) => "Found an unknown standard opcode",
522
0
            Error::UnknownExtendedOpcode(_) => "Found an unknown extended opcode",
523
0
            Error::UnknownLocListsEntry(_) => "Found an unknown location lists entry",
524
0
            Error::UnknownRangeListsEntry(_) => "Found an unknown range lists entry",
525
0
            Error::UnsupportedAddressSize(_) => "The specified address size is not supported",
526
0
            Error::UnsupportedOffsetSize(_) => "The specified offset size is not supported",
527
0
            Error::UnsupportedFieldSize(_) => "The specified field size is not supported",
528
            Error::MinimumInstructionLengthZero => {
529
0
                "The minimum instruction length must not be zero."
530
            }
531
            Error::MaximumOperationsPerInstructionZero => {
532
0
                "The maximum operations per instruction must not be zero."
533
            }
534
0
            Error::LineRangeZero => "The line range must not be zero.",
535
0
            Error::OpcodeBaseZero => "The opcode base must not be zero.",
536
0
            Error::BadUtf8 => "Found an invalid UTF-8 string.",
537
0
            Error::NotCieId => "Expected to find the CIE ID, but found something else.",
538
0
            Error::NotCiePointer => "Expected to find a CIE pointer, but found the CIE ID instead.",
539
            Error::NotFdePointer => {
540
0
                "Expected to find an FDE pointer, but found a CIE pointer instead."
541
            }
542
0
            Error::BadBranchTarget(_) => "Invalid branch target in DWARF expression",
543
            Error::InvalidPushObjectAddress => {
544
0
                "DW_OP_push_object_address used but no object address given"
545
            }
546
0
            Error::NotEnoughStackItems => "Not enough items on stack when evaluating expression",
547
0
            Error::TooManyIterations => "Too many iterations to evaluate DWARF expression",
548
0
            Error::InvalidExpression(_) => "Invalid opcode in DWARF expression",
549
0
            Error::UnsupportedEvaluation => "Unsupported operation when evaluating expression",
550
            Error::InvalidPiece => {
551
0
                "DWARF expression has piece followed by non-piece expression at end"
552
            }
553
0
            Error::InvalidExpressionTerminator(_) => "Expected DW_OP_piece or DW_OP_bit_piece",
554
0
            Error::DivisionByZero => "Division or modulus by zero when evaluating expression",
555
0
            Error::TypeMismatch => "Type mismatch when evaluating expression",
556
0
            Error::IntegralTypeRequired => "Integral type expected when evaluating expression",
557
            Error::UnsupportedTypeOperation => {
558
0
                "An expression operation used types that are not supported"
559
            }
560
            Error::InvalidShiftExpression => {
561
0
                "The shift value in an expression must be a non-negative integer."
562
            }
563
            Error::InvalidDerefSize(_) => {
564
0
                "The size of a deref expression must not be larger than the size of an address."
565
            }
566
0
            Error::UnknownCallFrameInstruction(_) => "An unknown DW_CFA_* instruction",
567
            Error::InvalidAddressRange => {
568
0
                "The end of an address range must not be before the beginning."
569
            }
570
0
            Error::AddressOverflow => "An address calculation overflowed.",
571
            Error::CfiInstructionInInvalidContext => {
572
0
                "Encountered a call frame instruction in a context in which it is not valid."
573
            }
574
            Error::PopWithEmptyStack => {
575
0
                "When evaluating call frame instructions, found a `DW_CFA_restore_state` stack pop \
576
0
                 instruction, but the stack was empty, and had nothing to pop."
577
            }
578
0
            Error::NoUnwindInfoForAddress => "Do not have unwind info for the given address.",
579
            Error::UnsupportedOffset => {
580
0
                "An offset value was larger than the maximum supported value."
581
            }
582
            Error::UnknownPointerEncoding(_) => {
583
0
                "The given pointer encoding is either unknown or invalid."
584
            }
585
0
            Error::NoEntryAtGivenOffset => "Did not find an entry at the given offset.",
586
0
            Error::OffsetOutOfBounds => "The given offset is out of bounds.",
587
0
            Error::UnknownAugmentation => "Found an unknown CFI augmentation.",
588
            Error::UnsupportedPointerEncoding => {
589
0
                "We do not support the given pointer encoding yet."
590
            }
591
0
            Error::UnsupportedRegister(_) => "Registers larger than `u16` are not supported.",
592
            Error::TooManyRegisterRules => {
593
0
                "The CFI program defined more register rules than we have storage for."
594
            }
595
            Error::StackFull => {
596
0
                "Attempted to push onto the CFI stack, but it was already at full capacity."
597
            }
598
            Error::VariableLengthSearchTable => {
599
0
                "The `.eh_frame_hdr` binary search table claims to be variable-length encoded, \
600
0
                 which makes binary search impossible."
601
            }
602
0
            Error::UnsupportedUnitType => "The `DW_UT_*` value for this unit is not supported yet",
603
0
            Error::UnsupportedAddressIndex => "Ranges involving AddressIndex are not supported yet",
604
0
            Error::UnsupportedSegmentSize => "Nonzero segment size not supported yet",
605
            Error::MissingUnitDie => {
606
0
                "A compilation unit or type unit is missing its top level DIE."
607
            }
608
0
            Error::UnsupportedAttributeForm => "A DIE attribute used an unsupported form.",
609
0
            Error::MissingFileEntryFormatPath => "Missing DW_LNCT_path in file entry format.",
610
            Error::ExpectedStringAttributeValue => {
611
0
                "Expected an attribute value to be a string form."
612
            }
613
0
            Error::InvalidImplicitConst => "DW_FORM_implicit_const used in an invalid context.",
614
0
            Error::InvalidIndexSectionCount => "Invalid section count in `.dwp` index.",
615
0
            Error::InvalidIndexSlotCount => "Invalid slot count in `.dwp` index.",
616
0
            Error::InvalidIndexRow => "Invalid hash row in `.dwp` index.",
617
0
            Error::UnknownIndexSection(_) => "Unknown section type in `.dwp` index.",
618
0
            Error::UnknownIndexSectionV2(_) => "Unknown section type in version 2 `.dwp` index.",
619
0
            Error::InvalidMacinfoType(_) => "Invalid macinfo type in `.debug_macinfo`.",
620
0
            Error::InvalidMacroType(_) => "Invalid macro type in `.debug_macro`.",
621
            Error::UnsupportedOpcodeOperandsTable => {
622
0
                "The optional `opcode_operands_table` in `.debug_macro` is currently not supported."
623
            }
624
        }
625
0
    }
626
}
627
628
#[cfg(feature = "std")]
629
impl error::Error for Error {}
630
631
#[cfg(feature = "std")]
632
impl From<io::Error> for Error {
633
    fn from(_: io::Error) -> Self {
634
        Error::Io
635
    }
636
}
637
638
/// The result of a parse.
639
pub type Result<T> = result::Result<T, Error>;
640
641
/// A convenience trait for loading DWARF sections from object files.  To be
642
/// used like:
643
///
644
/// ```
645
/// use gimli::{DebugInfo, EndianSlice, LittleEndian, Reader, Section};
646
///
647
/// let buf = [0x00, 0x01, 0x02, 0x03];
648
/// let reader = EndianSlice::new(&buf, LittleEndian);
649
/// let loader = |name| -> Result<_, ()> { Ok(reader) };
650
///
651
/// let debug_info: DebugInfo<_> = Section::load(loader).unwrap();
652
/// ```
653
pub trait Section<R>: From<R> {
654
    /// Returns the section id for this type.
655
    fn id() -> SectionId;
656
657
    /// Returns the ELF section name for this type.
658
0
    fn section_name() -> &'static str {
659
0
        Self::id().name()
660
0
    }
661
662
    /// Returns the ELF section name (if any) for this type when used in a dwo
663
    /// file.
664
0
    fn dwo_section_name() -> Option<&'static str> {
665
0
        Self::id().dwo_name()
666
0
    }
667
668
    /// Returns the XCOFF section name (if any) for this type when used in a XCOFF
669
    /// file.
670
0
    fn xcoff_section_name() -> Option<&'static str> {
671
0
        Self::id().xcoff_name()
672
0
    }
673
674
    /// Try to load the section using the given loader function.
675
0
    fn load<F, E>(f: F) -> core::result::Result<Self, E>
676
0
    where
677
0
        F: FnOnce(SectionId) -> core::result::Result<R, E>,
678
    {
679
0
        f(Self::id()).map(From::from)
680
0
    }
Unexecuted instantiation: <gimli::read::loclists::DebugLocLists<gimli::read::endian_slice::EndianSlice<gimli::endianity::LittleEndian>> as gimli::read::Section<gimli::read::endian_slice::EndianSlice<gimli::endianity::LittleEndian>>>::load::<&mut <backtrace::symbolize::gimli::Context>::new::{closure#0}, ()>
Unexecuted instantiation: <gimli::read::loclists::DebugLocLists<gimli::read::endian_slice::EndianSlice<gimli::endianity::LittleEndian>> as gimli::read::Section<gimli::read::endian_slice::EndianSlice<gimli::endianity::LittleEndian>>>::load::<&mut <backtrace::symbolize::gimli::Context>::new::{closure#2}, gimli::read::Error>
Unexecuted instantiation: <gimli::read::loclists::DebugLocLists<gimli::read::endian_slice::EndianSlice<gimli::endianity::LittleEndian>> as gimli::read::Section<gimli::read::endian_slice::EndianSlice<gimli::endianity::LittleEndian>>>::load::<&mut <backtrace::symbolize::gimli::Context>::new::{closure#1}, ()>
Unexecuted instantiation: <gimli::read::loclists::DebugLocLists<gimli::read::endian_slice::EndianSlice<gimli::endianity::LittleEndian>> as gimli::read::Section<gimli::read::endian_slice::EndianSlice<gimli::endianity::LittleEndian>>>::load::<&mut backtrace::symbolize::gimli::elf::handle_split_dwarf::{closure#0}, ()>
Unexecuted instantiation: <gimli::read::loclists::DebugLoc<gimli::read::endian_slice::EndianSlice<gimli::endianity::LittleEndian>> as gimli::read::Section<gimli::read::endian_slice::EndianSlice<gimli::endianity::LittleEndian>>>::load::<&mut <backtrace::symbolize::gimli::Context>::new::{closure#0}, ()>
Unexecuted instantiation: <gimli::read::loclists::DebugLoc<gimli::read::endian_slice::EndianSlice<gimli::endianity::LittleEndian>> as gimli::read::Section<gimli::read::endian_slice::EndianSlice<gimli::endianity::LittleEndian>>>::load::<&mut <backtrace::symbolize::gimli::Context>::new::{closure#2}, gimli::read::Error>
Unexecuted instantiation: <gimli::read::loclists::DebugLoc<gimli::read::endian_slice::EndianSlice<gimli::endianity::LittleEndian>> as gimli::read::Section<gimli::read::endian_slice::EndianSlice<gimli::endianity::LittleEndian>>>::load::<&mut <backtrace::symbolize::gimli::Context>::new::{closure#1}, ()>
Unexecuted instantiation: <gimli::read::loclists::DebugLoc<gimli::read::endian_slice::EndianSlice<gimli::endianity::LittleEndian>> as gimli::read::Section<gimli::read::endian_slice::EndianSlice<gimli::endianity::LittleEndian>>>::load::<&mut backtrace::symbolize::gimli::elf::handle_split_dwarf::{closure#0}, ()>
Unexecuted instantiation: <gimli::read::addr::DebugAddr<gimli::read::endian_slice::EndianSlice<gimli::endianity::LittleEndian>> as gimli::read::Section<gimli::read::endian_slice::EndianSlice<gimli::endianity::LittleEndian>>>::load::<&mut <backtrace::symbolize::gimli::Context>::new::{closure#0}, ()>
Unexecuted instantiation: <gimli::read::addr::DebugAddr<gimli::read::endian_slice::EndianSlice<gimli::endianity::LittleEndian>> as gimli::read::Section<gimli::read::endian_slice::EndianSlice<gimli::endianity::LittleEndian>>>::load::<&mut <backtrace::symbolize::gimli::Context>::new::{closure#1}, ()>
Unexecuted instantiation: <gimli::read::addr::DebugAddr<gimli::read::endian_slice::EndianSlice<gimli::endianity::LittleEndian>> as gimli::read::Section<gimli::read::endian_slice::EndianSlice<gimli::endianity::LittleEndian>>>::load::<&mut backtrace::symbolize::gimli::elf::handle_split_dwarf::{closure#0}, ()>
Unexecuted instantiation: <gimli::read::line::DebugLine<gimli::read::endian_slice::EndianSlice<gimli::endianity::LittleEndian>> as gimli::read::Section<gimli::read::endian_slice::EndianSlice<gimli::endianity::LittleEndian>>>::load::<&mut <backtrace::symbolize::gimli::Context>::new::{closure#0}, ()>
Unexecuted instantiation: <gimli::read::line::DebugLine<gimli::read::endian_slice::EndianSlice<gimli::endianity::LittleEndian>> as gimli::read::Section<gimli::read::endian_slice::EndianSlice<gimli::endianity::LittleEndian>>>::load::<&mut <backtrace::symbolize::gimli::Context>::new::{closure#2}, gimli::read::Error>
Unexecuted instantiation: <gimli::read::line::DebugLine<gimli::read::endian_slice::EndianSlice<gimli::endianity::LittleEndian>> as gimli::read::Section<gimli::read::endian_slice::EndianSlice<gimli::endianity::LittleEndian>>>::load::<&mut <backtrace::symbolize::gimli::Context>::new::{closure#1}, ()>
Unexecuted instantiation: <gimli::read::line::DebugLine<gimli::read::endian_slice::EndianSlice<gimli::endianity::LittleEndian>> as gimli::read::Section<gimli::read::endian_slice::EndianSlice<gimli::endianity::LittleEndian>>>::load::<&mut backtrace::symbolize::gimli::elf::handle_split_dwarf::{closure#0}, ()>
Unexecuted instantiation: <gimli::read::aranges::DebugAranges<gimli::read::endian_slice::EndianSlice<gimli::endianity::LittleEndian>> as gimli::read::Section<gimli::read::endian_slice::EndianSlice<gimli::endianity::LittleEndian>>>::load::<&mut <backtrace::symbolize::gimli::Context>::new::{closure#0}, ()>
Unexecuted instantiation: <gimli::read::aranges::DebugAranges<gimli::read::endian_slice::EndianSlice<gimli::endianity::LittleEndian>> as gimli::read::Section<gimli::read::endian_slice::EndianSlice<gimli::endianity::LittleEndian>>>::load::<&mut <backtrace::symbolize::gimli::Context>::new::{closure#1}, ()>
Unexecuted instantiation: <gimli::read::aranges::DebugAranges<gimli::read::endian_slice::EndianSlice<gimli::endianity::LittleEndian>> as gimli::read::Section<gimli::read::endian_slice::EndianSlice<gimli::endianity::LittleEndian>>>::load::<&mut backtrace::symbolize::gimli::elf::handle_split_dwarf::{closure#0}, ()>
Unexecuted instantiation: <gimli::read::str::DebugLineStr<gimli::read::endian_slice::EndianSlice<gimli::endianity::LittleEndian>> as gimli::read::Section<gimli::read::endian_slice::EndianSlice<gimli::endianity::LittleEndian>>>::load::<&mut <backtrace::symbolize::gimli::Context>::new::{closure#0}, ()>
Unexecuted instantiation: <gimli::read::str::DebugLineStr<gimli::read::endian_slice::EndianSlice<gimli::endianity::LittleEndian>> as gimli::read::Section<gimli::read::endian_slice::EndianSlice<gimli::endianity::LittleEndian>>>::load::<&mut <backtrace::symbolize::gimli::Context>::new::{closure#1}, ()>
Unexecuted instantiation: <gimli::read::str::DebugLineStr<gimli::read::endian_slice::EndianSlice<gimli::endianity::LittleEndian>> as gimli::read::Section<gimli::read::endian_slice::EndianSlice<gimli::endianity::LittleEndian>>>::load::<&mut backtrace::symbolize::gimli::elf::handle_split_dwarf::{closure#0}, ()>
Unexecuted instantiation: <gimli::read::str::DebugStrOffsets<gimli::read::endian_slice::EndianSlice<gimli::endianity::LittleEndian>> as gimli::read::Section<gimli::read::endian_slice::EndianSlice<gimli::endianity::LittleEndian>>>::load::<&mut <backtrace::symbolize::gimli::Context>::new::{closure#0}, ()>
Unexecuted instantiation: <gimli::read::str::DebugStrOffsets<gimli::read::endian_slice::EndianSlice<gimli::endianity::LittleEndian>> as gimli::read::Section<gimli::read::endian_slice::EndianSlice<gimli::endianity::LittleEndian>>>::load::<&mut <backtrace::symbolize::gimli::Context>::new::{closure#2}, gimli::read::Error>
Unexecuted instantiation: <gimli::read::str::DebugStrOffsets<gimli::read::endian_slice::EndianSlice<gimli::endianity::LittleEndian>> as gimli::read::Section<gimli::read::endian_slice::EndianSlice<gimli::endianity::LittleEndian>>>::load::<&mut <backtrace::symbolize::gimli::Context>::new::{closure#1}, ()>
Unexecuted instantiation: <gimli::read::str::DebugStrOffsets<gimli::read::endian_slice::EndianSlice<gimli::endianity::LittleEndian>> as gimli::read::Section<gimli::read::endian_slice::EndianSlice<gimli::endianity::LittleEndian>>>::load::<&mut backtrace::symbolize::gimli::elf::handle_split_dwarf::{closure#0}, ()>
Unexecuted instantiation: <gimli::read::str::DebugStr<gimli::read::endian_slice::EndianSlice<gimli::endianity::LittleEndian>> as gimli::read::Section<gimli::read::endian_slice::EndianSlice<gimli::endianity::LittleEndian>>>::load::<&mut <backtrace::symbolize::gimli::Context>::new::{closure#0}, ()>
Unexecuted instantiation: <gimli::read::str::DebugStr<gimli::read::endian_slice::EndianSlice<gimli::endianity::LittleEndian>> as gimli::read::Section<gimli::read::endian_slice::EndianSlice<gimli::endianity::LittleEndian>>>::load::<&mut <backtrace::symbolize::gimli::Context>::new::{closure#2}, gimli::read::Error>
Unexecuted instantiation: <gimli::read::str::DebugStr<gimli::read::endian_slice::EndianSlice<gimli::endianity::LittleEndian>> as gimli::read::Section<gimli::read::endian_slice::EndianSlice<gimli::endianity::LittleEndian>>>::load::<&mut <backtrace::symbolize::gimli::Context>::new::{closure#1}, ()>
Unexecuted instantiation: <gimli::read::str::DebugStr<gimli::read::endian_slice::EndianSlice<gimli::endianity::LittleEndian>> as gimli::read::Section<gimli::read::endian_slice::EndianSlice<gimli::endianity::LittleEndian>>>::load::<&mut backtrace::symbolize::gimli::elf::handle_split_dwarf::{closure#0}, ()>
Unexecuted instantiation: <gimli::read::index::DebugCuIndex<gimli::read::endian_slice::EndianSlice<gimli::endianity::LittleEndian>> as gimli::read::Section<gimli::read::endian_slice::EndianSlice<gimli::endianity::LittleEndian>>>::load::<&mut <backtrace::symbolize::gimli::Context>::new::{closure#2}, gimli::read::Error>
Unexecuted instantiation: <gimli::read::index::DebugTuIndex<gimli::read::endian_slice::EndianSlice<gimli::endianity::LittleEndian>> as gimli::read::Section<gimli::read::endian_slice::EndianSlice<gimli::endianity::LittleEndian>>>::load::<&mut <backtrace::symbolize::gimli::Context>::new::{closure#2}, gimli::read::Error>
Unexecuted instantiation: <gimli::read::rnglists::DebugRanges<gimli::read::endian_slice::EndianSlice<gimli::endianity::LittleEndian>> as gimli::read::Section<gimli::read::endian_slice::EndianSlice<gimli::endianity::LittleEndian>>>::load::<&mut <backtrace::symbolize::gimli::Context>::new::{closure#0}, ()>
Unexecuted instantiation: <gimli::read::rnglists::DebugRanges<gimli::read::endian_slice::EndianSlice<gimli::endianity::LittleEndian>> as gimli::read::Section<gimli::read::endian_slice::EndianSlice<gimli::endianity::LittleEndian>>>::load::<&mut <backtrace::symbolize::gimli::Context>::new::{closure#1}, ()>
Unexecuted instantiation: <gimli::read::rnglists::DebugRanges<gimli::read::endian_slice::EndianSlice<gimli::endianity::LittleEndian>> as gimli::read::Section<gimli::read::endian_slice::EndianSlice<gimli::endianity::LittleEndian>>>::load::<&mut backtrace::symbolize::gimli::elf::handle_split_dwarf::{closure#0}, ()>
Unexecuted instantiation: <gimli::read::rnglists::DebugRngLists<gimli::read::endian_slice::EndianSlice<gimli::endianity::LittleEndian>> as gimli::read::Section<gimli::read::endian_slice::EndianSlice<gimli::endianity::LittleEndian>>>::load::<&mut <backtrace::symbolize::gimli::Context>::new::{closure#0}, ()>
Unexecuted instantiation: <gimli::read::rnglists::DebugRngLists<gimli::read::endian_slice::EndianSlice<gimli::endianity::LittleEndian>> as gimli::read::Section<gimli::read::endian_slice::EndianSlice<gimli::endianity::LittleEndian>>>::load::<&mut <backtrace::symbolize::gimli::Context>::new::{closure#2}, gimli::read::Error>
Unexecuted instantiation: <gimli::read::rnglists::DebugRngLists<gimli::read::endian_slice::EndianSlice<gimli::endianity::LittleEndian>> as gimli::read::Section<gimli::read::endian_slice::EndianSlice<gimli::endianity::LittleEndian>>>::load::<&mut <backtrace::symbolize::gimli::Context>::new::{closure#1}, ()>
Unexecuted instantiation: <gimli::read::rnglists::DebugRngLists<gimli::read::endian_slice::EndianSlice<gimli::endianity::LittleEndian>> as gimli::read::Section<gimli::read::endian_slice::EndianSlice<gimli::endianity::LittleEndian>>>::load::<&mut backtrace::symbolize::gimli::elf::handle_split_dwarf::{closure#0}, ()>
Unexecuted instantiation: <gimli::read::abbrev::DebugAbbrev<gimli::read::endian_slice::EndianSlice<gimli::endianity::LittleEndian>> as gimli::read::Section<gimli::read::endian_slice::EndianSlice<gimli::endianity::LittleEndian>>>::load::<&mut <backtrace::symbolize::gimli::Context>::new::{closure#0}, ()>
Unexecuted instantiation: <gimli::read::abbrev::DebugAbbrev<gimli::read::endian_slice::EndianSlice<gimli::endianity::LittleEndian>> as gimli::read::Section<gimli::read::endian_slice::EndianSlice<gimli::endianity::LittleEndian>>>::load::<&mut <backtrace::symbolize::gimli::Context>::new::{closure#2}, gimli::read::Error>
Unexecuted instantiation: <gimli::read::abbrev::DebugAbbrev<gimli::read::endian_slice::EndianSlice<gimli::endianity::LittleEndian>> as gimli::read::Section<gimli::read::endian_slice::EndianSlice<gimli::endianity::LittleEndian>>>::load::<&mut <backtrace::symbolize::gimli::Context>::new::{closure#1}, ()>
Unexecuted instantiation: <gimli::read::abbrev::DebugAbbrev<gimli::read::endian_slice::EndianSlice<gimli::endianity::LittleEndian>> as gimli::read::Section<gimli::read::endian_slice::EndianSlice<gimli::endianity::LittleEndian>>>::load::<&mut backtrace::symbolize::gimli::elf::handle_split_dwarf::{closure#0}, ()>
Unexecuted instantiation: <gimli::read::unit::DebugTypes<gimli::read::endian_slice::EndianSlice<gimli::endianity::LittleEndian>> as gimli::read::Section<gimli::read::endian_slice::EndianSlice<gimli::endianity::LittleEndian>>>::load::<&mut <backtrace::symbolize::gimli::Context>::new::{closure#0}, ()>
Unexecuted instantiation: <gimli::read::unit::DebugTypes<gimli::read::endian_slice::EndianSlice<gimli::endianity::LittleEndian>> as gimli::read::Section<gimli::read::endian_slice::EndianSlice<gimli::endianity::LittleEndian>>>::load::<&mut <backtrace::symbolize::gimli::Context>::new::{closure#2}, gimli::read::Error>
Unexecuted instantiation: <gimli::read::unit::DebugTypes<gimli::read::endian_slice::EndianSlice<gimli::endianity::LittleEndian>> as gimli::read::Section<gimli::read::endian_slice::EndianSlice<gimli::endianity::LittleEndian>>>::load::<&mut <backtrace::symbolize::gimli::Context>::new::{closure#1}, ()>
Unexecuted instantiation: <gimli::read::unit::DebugTypes<gimli::read::endian_slice::EndianSlice<gimli::endianity::LittleEndian>> as gimli::read::Section<gimli::read::endian_slice::EndianSlice<gimli::endianity::LittleEndian>>>::load::<&mut backtrace::symbolize::gimli::elf::handle_split_dwarf::{closure#0}, ()>
Unexecuted instantiation: <gimli::read::unit::DebugInfo<gimli::read::endian_slice::EndianSlice<gimli::endianity::LittleEndian>> as gimli::read::Section<gimli::read::endian_slice::EndianSlice<gimli::endianity::LittleEndian>>>::load::<&mut <backtrace::symbolize::gimli::Context>::new::{closure#0}, ()>
Unexecuted instantiation: <gimli::read::unit::DebugInfo<gimli::read::endian_slice::EndianSlice<gimli::endianity::LittleEndian>> as gimli::read::Section<gimli::read::endian_slice::EndianSlice<gimli::endianity::LittleEndian>>>::load::<&mut <backtrace::symbolize::gimli::Context>::new::{closure#2}, gimli::read::Error>
Unexecuted instantiation: <gimli::read::unit::DebugInfo<gimli::read::endian_slice::EndianSlice<gimli::endianity::LittleEndian>> as gimli::read::Section<gimli::read::endian_slice::EndianSlice<gimli::endianity::LittleEndian>>>::load::<&mut <backtrace::symbolize::gimli::Context>::new::{closure#1}, ()>
Unexecuted instantiation: <gimli::read::unit::DebugInfo<gimli::read::endian_slice::EndianSlice<gimli::endianity::LittleEndian>> as gimli::read::Section<gimli::read::endian_slice::EndianSlice<gimli::endianity::LittleEndian>>>::load::<&mut backtrace::symbolize::gimli::elf::handle_split_dwarf::{closure#0}, ()>
Unexecuted instantiation: <gimli::read::macros::DebugMacro<gimli::read::endian_slice::EndianSlice<gimli::endianity::LittleEndian>> as gimli::read::Section<gimli::read::endian_slice::EndianSlice<gimli::endianity::LittleEndian>>>::load::<&mut <backtrace::symbolize::gimli::Context>::new::{closure#0}, ()>
Unexecuted instantiation: <gimli::read::macros::DebugMacro<gimli::read::endian_slice::EndianSlice<gimli::endianity::LittleEndian>> as gimli::read::Section<gimli::read::endian_slice::EndianSlice<gimli::endianity::LittleEndian>>>::load::<&mut <backtrace::symbolize::gimli::Context>::new::{closure#1}, ()>
Unexecuted instantiation: <gimli::read::macros::DebugMacro<gimli::read::endian_slice::EndianSlice<gimli::endianity::LittleEndian>> as gimli::read::Section<gimli::read::endian_slice::EndianSlice<gimli::endianity::LittleEndian>>>::load::<&mut backtrace::symbolize::gimli::elf::handle_split_dwarf::{closure#0}, ()>
Unexecuted instantiation: <gimli::read::macros::DebugMacinfo<gimli::read::endian_slice::EndianSlice<gimli::endianity::LittleEndian>> as gimli::read::Section<gimli::read::endian_slice::EndianSlice<gimli::endianity::LittleEndian>>>::load::<&mut <backtrace::symbolize::gimli::Context>::new::{closure#0}, ()>
Unexecuted instantiation: <gimli::read::macros::DebugMacinfo<gimli::read::endian_slice::EndianSlice<gimli::endianity::LittleEndian>> as gimli::read::Section<gimli::read::endian_slice::EndianSlice<gimli::endianity::LittleEndian>>>::load::<&mut <backtrace::symbolize::gimli::Context>::new::{closure#1}, ()>
Unexecuted instantiation: <gimli::read::macros::DebugMacinfo<gimli::read::endian_slice::EndianSlice<gimli::endianity::LittleEndian>> as gimli::read::Section<gimli::read::endian_slice::EndianSlice<gimli::endianity::LittleEndian>>>::load::<&mut backtrace::symbolize::gimli::elf::handle_split_dwarf::{closure#0}, ()>
Unexecuted instantiation: <_ as gimli::read::Section<_>>::load::<_, _>
681
682
    /// Returns the `Reader` for this section.
683
    fn reader(&self) -> &R
684
    where
685
        R: Reader;
686
687
    /// Returns the subrange of the section that is the contribution of
688
    /// a unit in a `.dwp` file.
689
0
    fn dwp_range(&self, offset: u32, size: u32) -> Result<Self>
690
0
    where
691
0
        R: Reader,
692
    {
693
0
        let mut data = self.reader().clone();
694
0
        data.skip(R::Offset::from_u32(offset))?;
695
0
        data.truncate(R::Offset::from_u32(size))?;
696
0
        Ok(data.into())
697
0
    }
Unexecuted instantiation: <gimli::read::loclists::DebugLocLists<gimli::read::endian_slice::EndianSlice<gimli::endianity::LittleEndian>> as gimli::read::Section<gimli::read::endian_slice::EndianSlice<gimli::endianity::LittleEndian>>>::dwp_range
Unexecuted instantiation: <gimli::read::loclists::DebugLoc<gimli::read::endian_slice::EndianSlice<gimli::endianity::LittleEndian>> as gimli::read::Section<gimli::read::endian_slice::EndianSlice<gimli::endianity::LittleEndian>>>::dwp_range
Unexecuted instantiation: <gimli::read::line::DebugLine<gimli::read::endian_slice::EndianSlice<gimli::endianity::LittleEndian>> as gimli::read::Section<gimli::read::endian_slice::EndianSlice<gimli::endianity::LittleEndian>>>::dwp_range
Unexecuted instantiation: <gimli::read::str::DebugStrOffsets<gimli::read::endian_slice::EndianSlice<gimli::endianity::LittleEndian>> as gimli::read::Section<gimli::read::endian_slice::EndianSlice<gimli::endianity::LittleEndian>>>::dwp_range
Unexecuted instantiation: <gimli::read::rnglists::DebugRngLists<gimli::read::endian_slice::EndianSlice<gimli::endianity::LittleEndian>> as gimli::read::Section<gimli::read::endian_slice::EndianSlice<gimli::endianity::LittleEndian>>>::dwp_range
Unexecuted instantiation: <gimli::read::abbrev::DebugAbbrev<gimli::read::endian_slice::EndianSlice<gimli::endianity::LittleEndian>> as gimli::read::Section<gimli::read::endian_slice::EndianSlice<gimli::endianity::LittleEndian>>>::dwp_range
Unexecuted instantiation: <gimli::read::unit::DebugTypes<gimli::read::endian_slice::EndianSlice<gimli::endianity::LittleEndian>> as gimli::read::Section<gimli::read::endian_slice::EndianSlice<gimli::endianity::LittleEndian>>>::dwp_range
Unexecuted instantiation: <gimli::read::unit::DebugInfo<gimli::read::endian_slice::EndianSlice<gimli::endianity::LittleEndian>> as gimli::read::Section<gimli::read::endian_slice::EndianSlice<gimli::endianity::LittleEndian>>>::dwp_range
Unexecuted instantiation: <_ as gimli::read::Section<_>>::dwp_range
698
699
    /// Returns the `Reader` for this section.
700
0
    fn lookup_offset_id(&self, id: ReaderOffsetId) -> Option<(SectionId, R::Offset)>
701
0
    where
702
0
        R: Reader,
703
    {
704
0
        self.reader()
705
0
            .lookup_offset_id(id)
706
0
            .map(|offset| (Self::id(), offset))
707
0
    }
708
}
709
710
impl Register {
711
0
    pub(crate) fn from_u64(x: u64) -> Result<Register> {
712
0
        let y = x as u16;
713
0
        if u64::from(y) == x {
714
0
            Ok(Register(y))
715
        } else {
716
0
            Err(Error::UnsupportedRegister(x))
717
        }
718
0
    }
719
}
720
721
#[cfg(test)]
722
mod tests {
723
    use super::*;
724
    use crate::common::Format;
725
    use crate::endianity::LittleEndian;
726
    use test_assembler::{Endian, Section};
727
728
    #[test]
729
    fn test_parse_initial_length_32_ok() {
730
        let section = Section::with_endian(Endian::Little).L32(0x7856_3412);
731
        let buf = section.get_contents().unwrap();
732
733
        let input = &mut EndianSlice::new(&buf, LittleEndian);
734
        match input.read_initial_length() {
735
            Ok((length, format)) => {
736
                assert_eq!(input.len(), 0);
737
                assert_eq!(format, Format::Dwarf32);
738
                assert_eq!(0x7856_3412, length);
739
            }
740
            otherwise => panic!("Unexpected result: {:?}", otherwise),
741
        }
742
    }
743
744
    #[test]
745
    fn test_parse_initial_length_64_ok() {
746
        let section = Section::with_endian(Endian::Little)
747
            // Dwarf_64_INITIAL_UNIT_LENGTH
748
            .L32(0xffff_ffff)
749
            // Actual length
750
            .L64(0xffde_bc9a_7856_3412);
751
        let buf = section.get_contents().unwrap();
752
        let input = &mut EndianSlice::new(&buf, LittleEndian);
753
754
        #[cfg(target_pointer_width = "64")]
755
        match input.read_initial_length() {
756
            Ok((length, format)) => {
757
                assert_eq!(input.len(), 0);
758
                assert_eq!(format, Format::Dwarf64);
759
                assert_eq!(0xffde_bc9a_7856_3412, length);
760
            }
761
            otherwise => panic!("Unexpected result: {:?}", otherwise),
762
        }
763
764
        #[cfg(target_pointer_width = "32")]
765
        match input.read_initial_length() {
766
            Err(Error::UnsupportedOffset) => {}
767
            otherwise => panic!("Unexpected result: {:?}", otherwise),
768
        };
769
    }
770
771
    #[test]
772
    fn test_parse_initial_length_unknown_reserved_value() {
773
        let section = Section::with_endian(Endian::Little).L32(0xffff_fffe);
774
        let buf = section.get_contents().unwrap();
775
776
        let input = &mut EndianSlice::new(&buf, LittleEndian);
777
        match input.read_initial_length() {
778
            Err(Error::UnknownReservedLength) => {}
779
            otherwise => panic!("Unexpected result: {:?}", otherwise),
780
        };
781
    }
782
783
    #[test]
784
    fn test_parse_initial_length_incomplete() {
785
        let buf = [0xff, 0xff, 0xff]; // Need at least 4 bytes.
786
787
        let input = &mut EndianSlice::new(&buf, LittleEndian);
788
        match input.read_initial_length() {
789
            Err(Error::UnexpectedEof(_)) => {}
790
            otherwise => panic!("Unexpected result: {:?}", otherwise),
791
        };
792
    }
793
794
    #[test]
795
    fn test_parse_initial_length_64_incomplete() {
796
        let section = Section::with_endian(Endian::Little)
797
            // Dwarf_64_INITIAL_UNIT_LENGTH
798
            .L32(0xffff_ffff)
799
            // Actual length is not long enough.
800
            .L32(0x7856_3412);
801
        let buf = section.get_contents().unwrap();
802
803
        let input = &mut EndianSlice::new(&buf, LittleEndian);
804
        match input.read_initial_length() {
805
            Err(Error::UnexpectedEof(_)) => {}
806
            otherwise => panic!("Unexpected result: {:?}", otherwise),
807
        };
808
    }
809
810
    #[test]
811
    fn test_parse_offset_32() {
812
        let section = Section::with_endian(Endian::Little).L32(0x0123_4567);
813
        let buf = section.get_contents().unwrap();
814
815
        let input = &mut EndianSlice::new(&buf, LittleEndian);
816
        match input.read_offset(Format::Dwarf32) {
817
            Ok(val) => {
818
                assert_eq!(input.len(), 0);
819
                assert_eq!(val, 0x0123_4567);
820
            }
821
            otherwise => panic!("Unexpected result: {:?}", otherwise),
822
        };
823
    }
824
825
    #[test]
826
    fn test_parse_offset_64_small() {
827
        let section = Section::with_endian(Endian::Little).L64(0x0123_4567);
828
        let buf = section.get_contents().unwrap();
829
830
        let input = &mut EndianSlice::new(&buf, LittleEndian);
831
        match input.read_offset(Format::Dwarf64) {
832
            Ok(val) => {
833
                assert_eq!(input.len(), 0);
834
                assert_eq!(val, 0x0123_4567);
835
            }
836
            otherwise => panic!("Unexpected result: {:?}", otherwise),
837
        };
838
    }
839
840
    #[test]
841
    #[cfg(target_pointer_width = "64")]
842
    fn test_parse_offset_64_large() {
843
        let section = Section::with_endian(Endian::Little).L64(0x0123_4567_89ab_cdef);
844
        let buf = section.get_contents().unwrap();
845
846
        let input = &mut EndianSlice::new(&buf, LittleEndian);
847
        match input.read_offset(Format::Dwarf64) {
848
            Ok(val) => {
849
                assert_eq!(input.len(), 0);
850
                assert_eq!(val, 0x0123_4567_89ab_cdef);
851
            }
852
            otherwise => panic!("Unexpected result: {:?}", otherwise),
853
        };
854
    }
855
856
    #[test]
857
    #[cfg(target_pointer_width = "32")]
858
    fn test_parse_offset_64_large() {
859
        let section = Section::with_endian(Endian::Little).L64(0x0123_4567_89ab_cdef);
860
        let buf = section.get_contents().unwrap();
861
862
        let input = &mut EndianSlice::new(&buf, LittleEndian);
863
        match input.read_offset(Format::Dwarf64) {
864
            Err(Error::UnsupportedOffset) => {}
865
            otherwise => panic!("Unexpected result: {:?}", otherwise),
866
        };
867
    }
868
}