1 //! Read DWARF debugging information.
3 //! * [Example Usage](#example-usage)
4 //! * [API Structure](#api-structure)
5 //! * [Using with `FallibleIterator`](#using-with-fallibleiterator)
9 //! Print out all of the functions in the debuggee program:
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 dwarf = gimli::Dwarf::load(loader, sup_loader)?;
22 //! // Iterate over all compilation units.
23 //! let mut iter = dwarf.units();
24 //! while let Some(header) = iter.next()? {
25 //! // Parse the abbreviations and other information for this compilation unit.
26 //! let unit = dwarf.unit(header)?;
28 //! // Iterate over all of this compilation unit's entries.
29 //! let mut entries = unit.entries();
30 //! while let Some((_, entry)) = entries.next_dfs()? {
31 //! // If we find an entry for a function, print it.
32 //! if entry.tag() == gimli::DW_TAG_subprogram {
33 //! println!("Found a function: {:?}", entry);
41 //! Full example programs:
43 //! * [A simple parser](https://github.com/gimli-rs/gimli/blob/master/examples/simple.rs)
46 //! clone](https://github.com/gimli-rs/gimli/blob/master/examples/dwarfdump.rs)
48 //! * [An `addr2line` clone](https://github.com/gimli-rs/addr2line)
50 //! * [`ddbug`](https://github.com/philipc/ddbug), a utility giving insight into
51 //! code generation by making debugging information readable
53 //! * [`dwprod`](https://github.com/fitzgen/dwprod), a tiny utility to list the
54 //! compilers used to create each compilation unit within a shared library or
55 //! executable (via `DW_AT_producer`)
57 //! * [`dwarf-validate`](http://github.com/gimli-rs/gimli/blob/master/examples/dwarf-validate.rs),
58 //! a program to validate the integrity of some DWARF and its references
59 //! between sections and compilation units.
63 //! * Basic familiarity with DWARF is assumed.
65 //! * The [`Dwarf`](./struct.Dwarf.html) type contains the commonly used DWARF
66 //! sections. It has methods that simplify access to debugging data that spans
67 //! multiple sections. Use of this type is optional, but recommended.
69 //! * Each section gets its own type. Consider these types the entry points to
72 //! * [`DebugAbbrev`](./struct.DebugAbbrev.html): The `.debug_abbrev` section.
74 //! * [`DebugAddr`](./struct.DebugAddr.html): The `.debug_addr` section.
76 //! * [`DebugAranges`](./struct.DebugAranges.html): The `.debug_aranges`
79 //! * [`DebugFrame`](./struct.DebugFrame.html): The `.debug_frame` section.
81 //! * [`DebugInfo`](./struct.DebugInfo.html): The `.debug_info` section.
83 //! * [`DebugLine`](./struct.DebugLine.html): The `.debug_line` section.
85 //! * [`DebugLineStr`](./struct.DebugLineStr.html): The `.debug_line_str` section.
87 //! * [`DebugLoc`](./struct.DebugLoc.html): The `.debug_loc` section.
89 //! * [`DebugLocLists`](./struct.DebugLocLists.html): The `.debug_loclists` section.
91 //! * [`DebugPubNames`](./struct.DebugPubNames.html): The `.debug_pubnames`
94 //! * [`DebugPubTypes`](./struct.DebugPubTypes.html): The `.debug_pubtypes`
97 //! * [`DebugRanges`](./struct.DebugRanges.html): The `.debug_ranges` section.
99 //! * [`DebugRngLists`](./struct.DebugRngLists.html): The `.debug_rnglists` section.
101 //! * [`DebugStr`](./struct.DebugStr.html): The `.debug_str` section.
103 //! * [`DebugStrOffsets`](./struct.DebugStrOffsets.html): The `.debug_str_offsets` section.
105 //! * [`DebugTypes`](./struct.DebugTypes.html): The `.debug_types` section.
107 //! * [`EhFrame`](./struct.EhFrame.html): The `.eh_frame` section.
109 //! * [`EhFrameHdr`](./struct.EhFrameHdr.html): The `.eh_frame_hdr` section.
111 //! * Each section type exposes methods for accessing the debugging data encoded
112 //! in that section. For example, the [`DebugInfo`](./struct.DebugInfo.html)
113 //! struct has the [`units`](./struct.DebugInfo.html#method.units) method for
114 //! iterating over the compilation units defined within it.
116 //! * Offsets into a section are strongly typed: an offset into `.debug_info` is
117 //! the [`DebugInfoOffset`](./struct.DebugInfoOffset.html) type. It cannot be
118 //! used to index into the [`DebugLine`](./struct.DebugLine.html) type because
119 //! `DebugLine` represents the `.debug_line` section. There are similar types
120 //! for offsets relative to a compilation unit rather than a section.
122 //! ## Using with `FallibleIterator`
124 //! The standard library's `Iterator` trait and related APIs do not play well
125 //! with iterators where the `next` operation is fallible. One can make the
126 //! `Iterator`'s associated `Item` type be a `Result<T, E>`, however the
127 //! provided methods cannot gracefully handle the case when an `Err` is
130 //! This situation led to the
131 //! [`fallible-iterator`](https://crates.io/crates/fallible-iterator) crate's
132 //! existence. You can read more of the rationale for its existence in its
133 //! docs. The crate provides the helpers you have come to expect (eg `map`,
134 //! `filter`, etc) for iterators that can fail.
136 //! `gimli`'s many lazy parsing iterators are a perfect match for the
137 //! `fallible-iterator` crate's `FallibleIterator` trait because parsing is not
138 //! done eagerly. Parse errors later in the input might only be discovered after
139 //! having iterated through many items.
141 //! To use `gimli` iterators with `FallibleIterator`, import the crate and trait
145 //! # #[cfg(feature = "fallible-iterator")]
147 //! // Use the `FallibleIterator` trait so its methods are in scope!
148 //! use fallible_iterator::FallibleIterator;
149 //! use gimli::{DebugAranges, EndianSlice, LittleEndian};
151 //! fn find_sum_of_address_range_lengths(aranges: DebugAranges<EndianSlice<LittleEndian>>)
152 //! -> gimli::Result<u64>
154 //! // `DebugAranges::items` returns a `FallibleIterator`!
156 //! // `map` is provided by `FallibleIterator`!
157 //! .map(|arange| Ok(arange.length()))
158 //! // `fold` is provided by `FallibleIterator`!
159 //! .fold(0, |sum, len| Ok(sum + len))
165 use core
::fmt
::{self, Debug}
;
167 #[cfg(feature = "std")]
168 use std
::{error, io}
;
170 use crate::common
::{Register, SectionId}
;
171 use crate::constants
;
174 pub use self::addr
::*;
177 pub use self::cfi
::*;
180 pub use self::dwarf
::*;
183 pub use self::endian_slice
::*;
185 #[cfg(feature = "endian-reader")]
187 #[cfg(feature = "endian-reader")]
188 pub use self::endian_reader
::*;
191 pub use self::reader
::*;
194 pub use self::abbrev
::*;
197 pub use self::aranges
::*;
200 pub use self::line
::*;
205 pub use self::loclists
::*;
213 pub use self::pubnames
::*;
216 pub use self::pubtypes
::*;
219 pub use self::rnglists
::*;
222 pub use self::str::*;
225 pub use self::unit
::*;
228 pub use self::value
::*;
230 /// `EndianBuf` has been renamed to `EndianSlice`. For ease of upgrading across
231 /// `gimli` versions, we export this type alias.
232 #[deprecated(note = "EndianBuf has been renamed to EndianSlice, use that instead.")]
233 pub type EndianBuf
<'input
, Endian
> = EndianSlice
<'input
, Endian
>;
235 /// An error that occurred when parsing.
236 #[derive(Debug, Clone, Copy, PartialEq, Eq)]
238 /// An I/O error occurred while reading.
240 /// Found a PC relative pointer, but the section base is undefined.
241 PcRelativePointerButSectionBaseIsUndefined
,
242 /// Found a `.text` relative pointer, but the `.text` base is undefined.
243 TextRelativePointerButTextBaseIsUndefined
,
244 /// Found a data relative pointer, but the data base is undefined.
245 DataRelativePointerButDataBaseIsUndefined
,
246 /// Found a function relative pointer in a context that does not have a
248 FuncRelativePointerInBadContext
,
249 /// Cannot parse a pointer with a `DW_EH_PE_omit` encoding.
250 CannotParseOmitPointerEncoding
,
251 /// An error parsing an unsigned LEB128 value.
253 /// An error parsing a signed LEB128 value.
255 /// An abbreviation declared that its tag is zero, but zero is reserved for
258 /// An attribute specification declared that its form is zero, but zero is
259 /// reserved for null records.
261 /// The abbreviation's has-children byte was not one of
262 /// `DW_CHILDREN_{yes,no}`.
264 /// The specified length is impossible.
266 /// Found an unknown `DW_FORM_*` type.
268 /// Expected a zero, found something else.
270 /// Found an abbreviation code that has already been used.
271 DuplicateAbbreviationCode
,
272 /// Found a duplicate arange.
274 /// Found an unknown reserved length value.
275 UnknownReservedLength
,
276 /// Found an unknown DWARF version.
278 /// Found a record with an unknown abbreviation code.
280 /// Hit the end of input before it was expected.
281 UnexpectedEof(ReaderOffsetId
),
282 /// Read a null entry before it was expected.
284 /// Found an unknown standard opcode.
285 UnknownStandardOpcode(constants
::DwLns
),
286 /// Found an unknown extended opcode.
287 UnknownExtendedOpcode(constants
::DwLne
),
288 /// The specified address size is not supported.
289 UnsupportedAddressSize(u8),
290 /// The specified offset size is not supported.
291 UnsupportedOffsetSize(u8),
292 /// The specified field size is not supported.
293 UnsupportedFieldSize(u8),
294 /// The minimum instruction length must not be zero.
295 MinimumInstructionLengthZero
,
296 /// The maximum operations per instruction must not be zero.
297 MaximumOperationsPerInstructionZero
,
298 /// The line range must not be zero.
300 /// The opcode base must not be zero.
302 /// Found an invalid UTF-8 string.
304 /// Expected to find the CIE ID, but found something else.
306 /// Expected to find a pointer to a CIE, but found the CIE ID instead.
308 /// Expected to find a pointer to an FDE, but found a CIE instead.
310 /// Invalid branch target for a DW_OP_bra or DW_OP_skip.
311 BadBranchTarget(u64),
312 /// DW_OP_push_object_address used but no address passed in.
313 InvalidPushObjectAddress
,
314 /// Not enough items on the stack when evaluating an expression.
316 /// Too many iterations to compute the expression.
318 /// An unrecognized operation was found while parsing a DWARF
320 InvalidExpression(constants
::DwOp
),
321 /// The expression had a piece followed by an expression
322 /// terminator without a piece.
324 /// An expression-terminating operation was followed by something
325 /// other than the end of the expression or a piece operation.
326 InvalidExpressionTerminator(u64),
327 /// Division or modulus by zero when evaluating an expression.
329 /// An expression operation used mismatching types.
331 /// An expression operation required an integral type but saw a
332 /// floating point type.
333 IntegralTypeRequired
,
334 /// An expression operation used types that are not supported.
335 UnsupportedTypeOperation
,
336 /// The shift value in an expression must be a non-negative integer.
337 InvalidShiftExpression
,
338 /// An unknown DW_CFA_* instruction.
339 UnknownCallFrameInstruction(constants
::DwCfa
),
340 /// The end of an address range was before the beginning.
342 /// The end offset of a loc list entry was before the beginning.
343 InvalidLocationAddressRange
,
344 /// Encountered a call frame instruction in a context in which it is not
346 CfiInstructionInInvalidContext
,
347 /// When evaluating call frame instructions, found a `DW_CFA_restore_state`
348 /// stack pop instruction, but the stack was empty, and had nothing to pop.
350 /// Do not have unwind info for the given address.
351 NoUnwindInfoForAddress
,
352 /// An offset value was larger than the maximum supported value.
354 /// The given pointer encoding is either unknown or invalid.
355 UnknownPointerEncoding
,
356 /// Did not find an entry at the given offset.
357 NoEntryAtGivenOffset
,
358 /// The given offset is out of bounds.
360 /// Found an unknown CFI augmentation.
362 /// We do not support the given pointer encoding yet.
363 UnsupportedPointerEncoding
,
364 /// Registers larger than `u16` are not supported.
365 UnsupportedRegister(u64),
366 /// The CFI program defined more register rules than we have storage for.
367 TooManyRegisterRules
,
368 /// Attempted to push onto the CFI stack, but it was already at full
371 /// The `.eh_frame_hdr` binary search table claims to be variable-length encoded,
372 /// which makes binary search impossible.
373 VariableLengthSearchTable
,
374 /// The `DW_UT_*` value for this unit is not supported yet.
376 /// Ranges using AddressIndex are not supported yet.
377 UnsupportedAddressIndex
,
378 /// Nonzero segment selector sizes aren't supported yet.
379 UnsupportedSegmentSize
,
380 /// A compilation unit or type unit is missing its top level DIE.
382 /// A DIE attribute used an unsupported form.
383 UnsupportedAttributeForm
,
384 /// Missing DW_LNCT_path in file entry format.
385 MissingFileEntryFormatPath
,
386 /// Expected an attribute value to be a string form.
387 ExpectedStringAttributeValue
,
388 /// `DW_FORM_implicit_const` used in an invalid context.
389 InvalidImplicitConst
,
392 impl fmt
::Display
for Error
{
394 fn fmt(&self, f
: &mut fmt
::Formatter
) -> ::core
::result
::Result
<(), fmt
::Error
> {
395 write
!(f
, "{}", self.description())
400 /// A short description of the error.
401 pub fn description(&self) -> &str {
403 Error
::Io
=> "An I/O error occurred while reading.",
404 Error
::PcRelativePointerButSectionBaseIsUndefined
=> {
405 "Found a PC relative pointer, but the section base is undefined."
407 Error
::TextRelativePointerButTextBaseIsUndefined
=> {
408 "Found a `.text` relative pointer, but the `.text` base is undefined."
410 Error
::DataRelativePointerButDataBaseIsUndefined
=> {
411 "Found a data relative pointer, but the data base is undefined."
413 Error
::FuncRelativePointerInBadContext
=> {
414 "Found a function relative pointer in a context that does not have a function base."
416 Error
::CannotParseOmitPointerEncoding
=> {
417 "Cannot parse a pointer with a `DW_EH_PE_omit` encoding."
419 Error
::BadUnsignedLeb128
=> "An error parsing an unsigned LEB128 value",
420 Error
::BadSignedLeb128
=> "An error parsing a signed LEB128 value",
421 Error
::AbbreviationTagZero
=> {
422 "An abbreviation declared that its tag is zero,
423 but zero is reserved for null records"
425 Error
::AttributeFormZero
=> {
426 "An attribute specification declared that its form is zero,
427 but zero is reserved for null records"
429 Error
::BadHasChildren
=> {
430 "The abbreviation's has-children byte was not one of
431 `DW_CHILDREN_{yes,no}`"
433 Error
::BadLength
=> "The specified length is impossible",
434 Error
::UnknownForm
=> "Found an unknown `DW_FORM_*` type",
435 Error
::ExpectedZero
=> "Expected a zero, found something else",
436 Error
::DuplicateAbbreviationCode
=> {
437 "Found an abbreviation code that has already been used"
439 Error
::DuplicateArange
=> "Found a duplicate arange",
440 Error
::UnknownReservedLength
=> "Found an unknown reserved length value",
441 Error
::UnknownVersion(_
) => "Found an unknown DWARF version",
442 Error
::UnknownAbbreviation
=> "Found a record with an unknown abbreviation code",
443 Error
::UnexpectedEof(_
) => "Hit the end of input before it was expected",
444 Error
::UnexpectedNull
=> "Read a null entry before it was expected.",
445 Error
::UnknownStandardOpcode(_
) => "Found an unknown standard opcode",
446 Error
::UnknownExtendedOpcode(_
) => "Found an unknown extended opcode",
447 Error
::UnsupportedAddressSize(_
) => "The specified address size is not supported",
448 Error
::UnsupportedOffsetSize(_
) => "The specified offset size is not supported",
449 Error
::UnsupportedFieldSize(_
) => "The specified field size is not supported",
450 Error
::MinimumInstructionLengthZero
=> {
451 "The minimum instruction length must not be zero."
453 Error
::MaximumOperationsPerInstructionZero
=> {
454 "The maximum operations per instruction must not be zero."
456 Error
::LineRangeZero
=> "The line range must not be zero.",
457 Error
::OpcodeBaseZero
=> "The opcode base must not be zero.",
458 Error
::BadUtf8
=> "Found an invalid UTF-8 string.",
459 Error
::NotCieId
=> "Expected to find the CIE ID, but found something else.",
460 Error
::NotCiePointer
=> "Expected to find a CIE pointer, but found the CIE ID instead.",
461 Error
::NotFdePointer
=> {
462 "Expected to find an FDE pointer, but found a CIE pointer instead."
464 Error
::BadBranchTarget(_
) => "Invalid branch target in DWARF expression",
465 Error
::InvalidPushObjectAddress
=> {
466 "DW_OP_push_object_address used but no object address given"
468 Error
::NotEnoughStackItems
=> "Not enough items on stack when evaluating expression",
469 Error
::TooManyIterations
=> "Too many iterations to evaluate DWARF expression",
470 Error
::InvalidExpression(_
) => "Invalid opcode in DWARF expression",
471 Error
::InvalidPiece
=> {
472 "DWARF expression has piece followed by non-piece expression at end"
474 Error
::InvalidExpressionTerminator(_
) => "Expected DW_OP_piece or DW_OP_bit_piece",
475 Error
::DivisionByZero
=> "Division or modulus by zero when evaluating expression",
476 Error
::TypeMismatch
=> "Type mismatch when evaluating expression",
477 Error
::IntegralTypeRequired
=> "Integral type expected when evaluating expression",
478 Error
::UnsupportedTypeOperation
=> {
479 "An expression operation used types that are not supported"
481 Error
::InvalidShiftExpression
=> {
482 "The shift value in an expression must be a non-negative integer."
484 Error
::UnknownCallFrameInstruction(_
) => "An unknown DW_CFA_* instructiion",
485 Error
::InvalidAddressRange
=> {
486 "The end of an address range must not be before the beginning."
488 Error
::InvalidLocationAddressRange
=> {
489 "The end offset of a location list entry must not be before the beginning."
491 Error
::CfiInstructionInInvalidContext
=> {
492 "Encountered a call frame instruction in a context in which it is not valid."
494 Error
::PopWithEmptyStack
=> {
495 "When evaluating call frame instructions, found a `DW_CFA_restore_state` stack pop \
496 instruction, but the stack was empty, and had nothing to pop."
498 Error
::NoUnwindInfoForAddress
=> "Do not have unwind info for the given address.",
499 Error
::UnsupportedOffset
=> {
500 "An offset value was larger than the maximum supported value."
502 Error
::UnknownPointerEncoding
=> {
503 "The given pointer encoding is either unknown or invalid."
505 Error
::NoEntryAtGivenOffset
=> "Did not find an entry at the given offset.",
506 Error
::OffsetOutOfBounds
=> "The given offset is out of bounds.",
507 Error
::UnknownAugmentation
=> "Found an unknown CFI augmentation.",
508 Error
::UnsupportedPointerEncoding
=> {
509 "We do not support the given pointer encoding yet."
511 Error
::UnsupportedRegister(_
) => "Registers larger than `u16` are not supported.",
512 Error
::TooManyRegisterRules
=> {
513 "The CFI program defined more register rules than we have storage for."
515 Error
::CfiStackFull
=> {
516 "Attempted to push onto the CFI stack, but it was already at full capacity."
518 Error
::VariableLengthSearchTable
=> {
519 "The `.eh_frame_hdr` binary search table claims to be variable-length encoded, \
520 which makes binary search impossible."
522 Error
::UnsupportedUnitType
=> "The `DW_UT_*` value for this unit is not supported yet",
523 Error
::UnsupportedAddressIndex
=> "Ranges involving AddressIndex are not supported yet",
524 Error
::UnsupportedSegmentSize
=> "Nonzero segment size not supported yet",
525 Error
::MissingUnitDie
=> {
526 "A compilation unit or type unit is missing its top level DIE."
528 Error
::UnsupportedAttributeForm
=> "A DIE attribute used an unsupported form.",
529 Error
::MissingFileEntryFormatPath
=> "Missing DW_LNCT_path in file entry format.",
530 Error
::ExpectedStringAttributeValue
=> {
531 "Expected an attribute value to be a string form."
533 Error
::InvalidImplicitConst
=> "DW_FORM_implicit_const used in an invalid context.",
538 #[cfg(feature = "std")]
539 impl error
::Error
for Error {}
541 #[cfg(feature = "std")]
542 impl From
<io
::Error
> for Error
{
543 fn from(_
: io
::Error
) -> Self {
548 /// The result of a parse.
549 pub type Result
<T
> = result
::Result
<T
, Error
>;
551 /// A convenience trait for loading DWARF sections from object files. To be
555 /// use gimli::{DebugInfo, EndianSlice, LittleEndian, Reader, Section};
557 /// let buf = [0x00, 0x01, 0x02, 0x03];
558 /// let reader = EndianSlice::new(&buf, LittleEndian);
559 /// let loader = |name| -> Result<_, ()> { Ok(reader) };
561 /// let debug_info: DebugInfo<_> = Section::load(loader).unwrap();
563 pub trait Section
<R
>: From
<R
> {
564 /// Returns the section id for this type.
565 fn id() -> SectionId
;
567 /// Returns the ELF section name for this type.
568 fn section_name() -> &'
static str {
572 /// Returns the ELF section name (if any) for this type when used in a dwo
574 fn dwo_section_name() -> Option
<&'
static str> {
575 Self::id().dwo_name()
578 /// Try to load the section using the given loader function.
579 fn load
<F
, E
>(f
: F
) -> core
::result
::Result
<Self, E
>
581 F
: FnOnce(SectionId
) -> core
::result
::Result
<R
, E
>,
583 f(Self::id()).map(From
::from
)
586 /// Returns the `Reader` for this section.
587 fn reader(&self) -> &R
591 /// Returns the `Reader` for this section.
592 fn lookup_offset_id(&self, id
: ReaderOffsetId
) -> Option
<(SectionId
, R
::Offset
)>
597 .lookup_offset_id(id
)
598 .map(|offset
| (Self::id(), offset
))
603 pub(crate) fn from_u64(x
: u64) -> Result
<Register
> {
605 if u64::from(y
) == x
{
608 Err(Error
::UnsupportedRegister(x
))
616 use crate::common
::Format
;
617 use crate::endianity
::LittleEndian
;
618 use test_assembler
::{Endian, Section}
;
621 fn test_parse_initial_length_32_ok() {
622 let section
= Section
::with_endian(Endian
::Little
).L32(0x7856_3412);
623 let buf
= section
.get_contents().unwrap();
625 let input
= &mut EndianSlice
::new(&buf
, LittleEndian
);
626 match input
.read_initial_length() {
627 Ok((length
, format
)) => {
628 assert_eq
!(input
.len(), 0);
629 assert_eq
!(format
, Format
::Dwarf32
);
630 assert_eq
!(0x7856_3412, length
);
632 otherwise
=> panic
!("Unexpected result: {:?}", otherwise
),
637 fn test_parse_initial_length_64_ok() {
638 let section
= Section
::with_endian(Endian
::Little
)
639 // Dwarf_64_INITIAL_UNIT_LENGTH
642 .L64(0xffde_bc9a_7856_3412);
643 let buf
= section
.get_contents().unwrap();
644 let input
= &mut EndianSlice
::new(&buf
, LittleEndian
);
646 #[cfg(target_pointer_width = "64")]
647 match input
.read_initial_length() {
648 Ok((length
, format
)) => {
649 assert_eq
!(input
.len(), 0);
650 assert_eq
!(format
, Format
::Dwarf64
);
651 assert_eq
!(0xffde_bc9a_7856_3412, length
);
653 otherwise
=> panic
!("Unexpected result: {:?}", otherwise
),
656 #[cfg(target_pointer_width = "32")]
657 match input
.read_initial_length() {
658 Err(Error
::UnsupportedOffset
) => {}
659 otherwise
=> panic
!("Unexpected result: {:?}", otherwise
),
664 fn test_parse_initial_length_unknown_reserved_value() {
665 let section
= Section
::with_endian(Endian
::Little
).L32(0xffff_fffe);
666 let buf
= section
.get_contents().unwrap();
668 let input
= &mut EndianSlice
::new(&buf
, LittleEndian
);
669 match input
.read_initial_length() {
670 Err(Error
::UnknownReservedLength
) => assert
!(true),
671 otherwise
=> panic
!("Unexpected result: {:?}", otherwise
),
676 fn test_parse_initial_length_incomplete() {
677 let buf
= [0xff, 0xff, 0xff]; // Need at least 4 bytes.
679 let input
= &mut EndianSlice
::new(&buf
, LittleEndian
);
680 match input
.read_initial_length() {
681 Err(Error
::UnexpectedEof(_
)) => assert
!(true),
682 otherwise
=> panic
!("Unexpected result: {:?}", otherwise
),
687 fn test_parse_initial_length_64_incomplete() {
688 let section
= Section
::with_endian(Endian
::Little
)
689 // Dwarf_64_INITIAL_UNIT_LENGTH
691 // Actual length is not long enough.
693 let buf
= section
.get_contents().unwrap();
695 let input
= &mut EndianSlice
::new(&buf
, LittleEndian
);
696 match input
.read_initial_length() {
697 Err(Error
::UnexpectedEof(_
)) => assert
!(true),
698 otherwise
=> panic
!("Unexpected result: {:?}", otherwise
),
703 fn test_parse_offset_32() {
704 let section
= Section
::with_endian(Endian
::Little
).L32(0x0123_4567);
705 let buf
= section
.get_contents().unwrap();
707 let input
= &mut EndianSlice
::new(&buf
, LittleEndian
);
708 match input
.read_offset(Format
::Dwarf32
) {
710 assert_eq
!(input
.len(), 0);
711 assert_eq
!(val
, 0x0123_4567);
713 otherwise
=> panic
!("Unexpected result: {:?}", otherwise
),
718 fn test_parse_offset_64_small() {
719 let section
= Section
::with_endian(Endian
::Little
).L64(0x0123_4567);
720 let buf
= section
.get_contents().unwrap();
722 let input
= &mut EndianSlice
::new(&buf
, LittleEndian
);
723 match input
.read_offset(Format
::Dwarf64
) {
725 assert_eq
!(input
.len(), 0);
726 assert_eq
!(val
, 0x0123_4567);
728 otherwise
=> panic
!("Unexpected result: {:?}", otherwise
),
733 #[cfg(target_pointer_width = "64")]
734 fn test_parse_offset_64_large() {
735 let section
= Section
::with_endian(Endian
::Little
).L64(0x0123_4567_89ab_cdef);
736 let buf
= section
.get_contents().unwrap();
738 let input
= &mut EndianSlice
::new(&buf
, LittleEndian
);
739 match input
.read_offset(Format
::Dwarf64
) {
741 assert_eq
!(input
.len(), 0);
742 assert_eq
!(val
, 0x0123_4567_89ab_cdef);
744 otherwise
=> panic
!("Unexpected result: {:?}", otherwise
),
749 #[cfg(target_pointer_width = "32")]
750 fn test_parse_offset_64_large() {
751 let section
= Section
::with_endian(Endian
::Little
).L64(0x0123_4567_89ab_cdef);
752 let buf
= section
.get_contents().unwrap();
754 let input
= &mut EndianSlice
::new(&buf
, LittleEndian
);
755 match input
.read_offset(Format
::Dwarf64
) {
756 Err(Error
::UnsupportedOffset
) => assert
!(true),
757 otherwise
=> panic
!("Unexpected result: {:?}", otherwise
),