1 //! Functions for parsing DWARF debugging abbreviations.
3 use alloc
::collections
::btree_map
;
5 use core
::fmt
::{self, Debug}
;
6 use core
::iter
::FromIterator
;
9 use crate::common
::{DebugAbbrevOffset, SectionId}
;
11 use crate::endianity
::Endianity
;
12 use crate::read
::{EndianSlice, Error, Reader, Result, Section, UnitHeader}
;
14 /// The `DebugAbbrev` struct represents the abbreviations describing
15 /// `DebuggingInformationEntry`s' attribute names and forms found in the
16 /// `.debug_abbrev` section.
17 #[derive(Debug, Default, Clone, Copy)]
18 pub struct DebugAbbrev
<R
> {
19 debug_abbrev_section
: R
,
22 impl<'input
, Endian
> DebugAbbrev
<EndianSlice
<'input
, Endian
>>
26 /// Construct a new `DebugAbbrev` instance from the data in the `.debug_abbrev`
29 /// It is the caller's responsibility to read the `.debug_abbrev` section and
30 /// present it as a `&[u8]` slice. That means using some ELF loader on
31 /// Linux, a Mach-O loader on OSX, etc.
34 /// use gimli::{DebugAbbrev, LittleEndian};
36 /// # let buf = [0x00, 0x01, 0x02, 0x03];
37 /// # let read_debug_abbrev_section_somehow = || &buf;
38 /// let debug_abbrev = DebugAbbrev::new(read_debug_abbrev_section_somehow(), LittleEndian);
40 pub fn new(debug_abbrev_section
: &'input
[u8], endian
: Endian
) -> Self {
41 Self::from(EndianSlice
::new(debug_abbrev_section
, endian
))
45 impl<R
: Reader
> DebugAbbrev
<R
> {
46 /// Parse the abbreviations at the given `offset` within this
47 /// `.debug_abbrev` section.
49 /// The `offset` should generally be retrieved from a unit header.
52 debug_abbrev_offset
: DebugAbbrevOffset
<R
::Offset
>,
53 ) -> Result
<Abbreviations
> {
54 let input
= &mut self.debug_abbrev_section
.clone();
55 input
.skip(debug_abbrev_offset
.0)?
;
56 Abbreviations
::parse(input
)
60 impl<T
> DebugAbbrev
<T
> {
61 /// Create a `DebugAbbrev` section that references the data in `self`.
63 /// This is useful when `R` implements `Reader` but `T` does not.
68 /// # let load_section = || unimplemented!();
69 /// // Read the DWARF section into a `Vec` with whatever object loader you're using.
70 /// let owned_section: gimli::DebugAbbrev<Vec<u8>> = load_section();
71 /// // Create a reference to the DWARF section.
72 /// let section = owned_section.borrow(|section| {
73 /// gimli::EndianSlice::new(§ion, gimli::LittleEndian)
76 pub fn borrow
<'a
, F
, R
>(&'a
self, mut borrow
: F
) -> DebugAbbrev
<R
>
80 borrow(&self.debug_abbrev_section
).into()
84 impl<R
> Section
<R
> for DebugAbbrev
<R
> {
85 fn id() -> SectionId
{
86 SectionId
::DebugAbbrev
89 fn reader(&self) -> &R
{
90 &self.debug_abbrev_section
94 impl<R
> From
<R
> for DebugAbbrev
<R
> {
95 fn from(debug_abbrev_section
: R
) -> Self {
102 /// A set of type abbreviations.
104 /// Construct an `Abbreviations` instance with the
105 /// [`abbreviations()`](struct.UnitHeader.html#method.abbreviations)
107 #[derive(Debug, Default, Clone)]
108 pub struct Abbreviations
{
109 vec
: Vec
<Abbreviation
>,
110 map
: btree_map
::BTreeMap
<u64, Abbreviation
>,
114 /// Construct a new, empty set of abbreviations.
115 fn empty() -> Abbreviations
{
118 map
: btree_map
::BTreeMap
::new(),
122 /// Insert an abbreviation into the set.
124 /// Returns `Ok` if it is the first abbreviation in the set with its code,
125 /// `Err` if the code is a duplicate and there already exists an
126 /// abbreviation in the set with the given abbreviation's code.
127 fn insert(&mut self, abbrev
: Abbreviation
) -> ::core
::result
::Result
<(), ()> {
128 let code_usize
= abbrev
.code
as usize;
129 if code_usize
as u64 == abbrev
.code
{
130 // Optimize for sequential abbreviation codes by storing them
131 // in a Vec, as long as the map doesn't already contain them.
132 // A potential further optimization would be to allow some
133 // holes in the Vec, but there's no need for that yet.
134 if code_usize
- 1 < self.vec
.len() {
136 } else if code_usize
- 1 == self.vec
.len() {
137 if !self.map
.is_empty() && self.map
.contains_key(&abbrev
.code
) {
140 self.vec
.push(abbrev
);
145 match self.map
.entry(abbrev
.code
) {
146 btree_map
::Entry
::Occupied(_
) => Err(()),
147 btree_map
::Entry
::Vacant(entry
) => {
148 entry
.insert(abbrev
);
154 /// Get the abbreviation associated with the given code.
156 pub fn get(&self, code
: u64) -> Option
<&Abbreviation
> {
157 let code_usize
= code
as usize;
158 if code_usize
as u64 == code
&& code_usize
- 1 < self.vec
.len() {
159 Some(&self.vec
[code_usize
- 1])
165 /// Parse a series of abbreviations, terminated by a null abbreviation.
166 fn parse
<R
: Reader
>(input
: &mut R
) -> Result
<Abbreviations
> {
167 let mut abbrevs
= Abbreviations
::empty();
169 while let Some(abbrev
) = Abbreviation
::parse(input
)?
{
170 if abbrevs
.insert(abbrev
).is_err() {
171 return Err(Error
::DuplicateAbbreviationCode
);
179 /// An abbreviation describes the shape of a `DebuggingInformationEntry`'s type:
180 /// its code, tag type, whether it has children, and its set of attributes.
181 #[derive(Debug, Clone, PartialEq, Eq)]
182 pub struct Abbreviation
{
184 tag
: constants
::DwTag
,
185 has_children
: constants
::DwChildren
,
186 attributes
: Attributes
,
190 /// Construct a new `Abbreviation`.
194 /// Panics if `code` is `0`.
197 tag
: constants
::DwTag
,
198 has_children
: constants
::DwChildren
,
199 attributes
: Attributes
,
210 /// Get this abbreviation's code.
212 pub fn code(&self) -> u64 {
216 /// Get this abbreviation's tag.
218 pub fn tag(&self) -> constants
::DwTag
{
222 /// Return true if this abbreviation's type has children, false otherwise.
224 pub fn has_children(&self) -> bool
{
225 self.has_children
== constants
::DW_CHILDREN_yes
228 /// Get this abbreviation's attributes.
230 pub fn attributes(&self) -> &[AttributeSpecification
] {
234 /// Parse an abbreviation's tag.
235 fn parse_tag
<R
: Reader
>(input
: &mut R
) -> Result
<constants
::DwTag
> {
236 let val
= input
.read_uleb128_u16()?
;
238 Err(Error
::AbbreviationTagZero
)
240 Ok(constants
::DwTag(val
))
244 /// Parse an abbreviation's "does the type have children?" byte.
245 fn parse_has_children
<R
: Reader
>(input
: &mut R
) -> Result
<constants
::DwChildren
> {
246 let val
= input
.read_u8()?
;
247 let val
= constants
::DwChildren(val
);
248 if val
== constants
::DW_CHILDREN_no
|| val
== constants
::DW_CHILDREN_yes
{
251 Err(Error
::BadHasChildren
)
255 /// Parse a series of attribute specifications, terminated by a null attribute
257 fn parse_attributes
<R
: Reader
>(input
: &mut R
) -> Result
<Attributes
> {
258 let mut attrs
= Attributes
::new();
260 while let Some(attr
) = AttributeSpecification
::parse(input
)?
{
267 /// Parse an abbreviation. Return `None` for the null abbreviation, `Some`
268 /// for an actual abbreviation.
269 fn parse
<R
: Reader
>(input
: &mut R
) -> Result
<Option
<Abbreviation
>> {
270 let code
= input
.read_uleb128()?
;
275 let tag
= Self::parse_tag(input
)?
;
276 let has_children
= Self::parse_has_children(input
)?
;
277 let attributes
= Self::parse_attributes(input
)?
;
278 let abbrev
= Abbreviation
::new(code
, tag
, has_children
, attributes
);
283 /// A list of attributes found in an `Abbreviation`
285 pub(crate) enum Attributes
{
287 buf
: [AttributeSpecification
; MAX_ATTRIBUTES_INLINE
],
290 Heap(Vec
<AttributeSpecification
>),
293 // Length of 5 based on benchmark results for both x86-64 and i686.
294 const MAX_ATTRIBUTES_INLINE
: usize = 5;
297 /// Returns a new empty list of attributes
298 fn new() -> Attributes
{
300 AttributeSpecification
::new(constants
::DW_AT_null
, constants
::DW_FORM_null
, None
);
307 /// Pushes a new value onto this list of attributes.
308 fn push(&mut self, attr
: AttributeSpecification
) {
310 Attributes
::Heap(list
) => return list
.push(attr
),
313 len
: MAX_ATTRIBUTES_INLINE
,
315 let mut list
= buf
.to_vec();
317 *self = Attributes
::Heap(list
);
319 Attributes
::Inline { buf, len }
=> {
327 impl Debug
for Attributes
{
328 fn fmt(&self, f
: &mut fmt
::Formatter
<'_
>) -> fmt
::Result
{
333 impl PartialEq
for Attributes
{
334 fn eq(&self, other
: &Attributes
) -> bool
{
339 impl Eq
for Attributes {}
341 impl Deref
for Attributes
{
342 type Target
= [AttributeSpecification
];
343 fn deref(&self) -> &[AttributeSpecification
] {
345 Attributes
::Inline { buf, len }
=> &buf
[..*len
],
346 Attributes
::Heap(list
) => list
,
351 impl FromIterator
<AttributeSpecification
> for Attributes
{
352 fn from_iter
<I
>(iter
: I
) -> Attributes
354 I
: IntoIterator
<Item
= AttributeSpecification
>,
356 let mut list
= Attributes
::new();
364 impl From
<Vec
<AttributeSpecification
>> for Attributes
{
365 fn from(list
: Vec
<AttributeSpecification
>) -> Attributes
{
366 Attributes
::Heap(list
)
370 /// The description of an attribute in an abbreviated type. It is a pair of name
372 #[derive(Debug, Clone, Copy, PartialEq, Eq)]
373 pub struct AttributeSpecification
{
374 name
: constants
::DwAt
,
375 form
: constants
::DwForm
,
376 implicit_const_value
: i64,
379 impl AttributeSpecification
{
380 /// Construct a new `AttributeSpecification` from the given name and form
381 /// and implicit const value.
384 name
: constants
::DwAt
,
385 form
: constants
::DwForm
,
386 implicit_const_value
: Option
<i64>,
387 ) -> AttributeSpecification
{
389 (form
== constants
::DW_FORM_implicit_const
&& implicit_const_value
.is_some())
390 || (form
!= constants
::DW_FORM_implicit_const
&& implicit_const_value
.is_none())
392 AttributeSpecification
{
395 implicit_const_value
: implicit_const_value
.unwrap_or(0),
399 /// Get the attribute's name.
401 pub fn name(&self) -> constants
::DwAt
{
405 /// Get the attribute's form.
407 pub fn form(&self) -> constants
::DwForm
{
411 /// Get the attribute's implicit const value.
413 pub fn implicit_const_value(&self) -> i64 {
414 assert
!(self.form
== constants
::DW_FORM_implicit_const
);
415 self.implicit_const_value
418 /// Return the size of the attribute, in bytes.
420 /// Note that because some attributes are variably sized, the size cannot
421 /// always be known without parsing, in which case we return `None`.
422 pub fn size
<R
: Reader
>(&self, header
: &UnitHeader
<R
>) -> Option
<usize> {
424 constants
::DW_FORM_addr
=> Some(header
.address_size() as usize),
426 constants
::DW_FORM_implicit_const
=> Some(0),
428 constants
::DW_FORM_flag
|
429 constants
::DW_FORM_flag_present
|
430 constants
::DW_FORM_data1
|
431 constants
::DW_FORM_ref1
=> Some(1),
433 constants
::DW_FORM_data2
|
434 constants
::DW_FORM_ref2
=> Some(2),
436 constants
::DW_FORM_data4
|
437 constants
::DW_FORM_ref4
=> Some(4),
439 constants
::DW_FORM_data8
|
440 constants
::DW_FORM_ref8
=> Some(8),
442 constants
::DW_FORM_sec_offset
|
443 constants
::DW_FORM_ref_addr
|
444 constants
::DW_FORM_ref_sig8
|
445 constants
::DW_FORM_strp
=> Some(header
.format().word_size() as usize),
447 // Variably sized forms.
448 constants
::DW_FORM_block
|
449 constants
::DW_FORM_block1
|
450 constants
::DW_FORM_block2
|
451 constants
::DW_FORM_block4
|
452 constants
::DW_FORM_exprloc
|
453 constants
::DW_FORM_ref_udata
|
454 constants
::DW_FORM_string
|
455 constants
::DW_FORM_sdata
|
456 constants
::DW_FORM_udata
|
457 constants
::DW_FORM_indirect
|
459 // We don't know the size of unknown forms.
464 /// Parse an attribute's form.
465 fn parse_form
<R
: Reader
>(input
: &mut R
) -> Result
<constants
::DwForm
> {
466 let val
= input
.read_uleb128_u16()?
;
468 Err(Error
::AttributeFormZero
)
470 Ok(constants
::DwForm(val
))
474 /// Parse an attribute specification. Returns `None` for the null attribute
475 /// specification, `Some` for an actual attribute specification.
476 fn parse
<R
: Reader
>(input
: &mut R
) -> Result
<Option
<AttributeSpecification
>> {
477 let name
= input
.read_uleb128_u16()?
;
479 // Parse the null attribute specification.
480 let form
= input
.read_uleb128_u16()?
;
481 return if form
== 0 {
484 Err(Error
::ExpectedZero
)
488 let name
= constants
::DwAt(name
);
489 let form
= Self::parse_form(input
)?
;
490 let implicit_const_value
= if form
== constants
::DW_FORM_implicit_const
{
491 Some(input
.read_sleb128()?
)
495 let spec
= AttributeSpecification
::new(name
, form
, implicit_const_value
);
503 use crate::constants
;
504 use crate::endianity
::LittleEndian
;
505 use crate::read
::{EndianSlice, Error}
;
506 use crate::test_util
::GimliSectionMethods
;
507 #[cfg(target_pointer_width = "32")]
509 use test_assembler
::Section
;
511 pub trait AbbrevSectionMethods
{
512 fn abbrev(self, code
: u64, tag
: constants
::DwTag
, children
: constants
::DwChildren
) -> Self;
513 fn abbrev_null(self) -> Self;
514 fn abbrev_attr(self, name
: constants
::DwAt
, form
: constants
::DwForm
) -> Self;
515 fn abbrev_attr_implicit_const(self, name
: constants
::DwAt
, value
: i64) -> Self;
516 fn abbrev_attr_null(self) -> Self;
519 impl AbbrevSectionMethods
for Section
{
520 fn abbrev(self, code
: u64, tag
: constants
::DwTag
, children
: constants
::DwChildren
) -> Self {
521 self.uleb(code
).uleb(tag
.0.into
()).D8(children
.0)
524 fn abbrev_null(self) -> Self {
528 fn abbrev_attr(self, name
: constants
::DwAt
, form
: constants
::DwForm
) -> Self {
529 self.uleb(name
.0.into
()).uleb(form
.0.into
())
532 fn abbrev_attr_implicit_const(self, name
: constants
::DwAt
, value
: i64) -> Self {
533 self.uleb(name
.0.into
())
534 .uleb(constants
::DW_FORM_implicit_const
.0.into
())
538 fn abbrev_attr_null(self) -> Self {
544 fn test_debug_abbrev_ok() {
545 let extra_start
= [1, 2, 3, 4];
546 let expected_rest
= [5, 6, 7, 8];
548 let buf
= Section
::new()
549 .append_bytes(&extra_start
)
550 .abbrev(2, constants
::DW_TAG_subprogram
, constants
::DW_CHILDREN_no
)
551 .abbrev_attr(constants
::DW_AT_name
, constants
::DW_FORM_string
)
553 .abbrev(1, constants
::DW_TAG_compile_unit
, constants
::DW_CHILDREN_yes
)
554 .abbrev_attr(constants
::DW_AT_producer
, constants
::DW_FORM_strp
)
555 .abbrev_attr(constants
::DW_AT_language
, constants
::DW_FORM_data2
)
558 .append_bytes(&expected_rest
)
562 let abbrev1
= Abbreviation
::new(
564 constants
::DW_TAG_compile_unit
,
565 constants
::DW_CHILDREN_yes
,
567 AttributeSpecification
::new(
568 constants
::DW_AT_producer
,
569 constants
::DW_FORM_strp
,
572 AttributeSpecification
::new(
573 constants
::DW_AT_language
,
574 constants
::DW_FORM_data2
,
581 let abbrev2
= Abbreviation
::new(
583 constants
::DW_TAG_subprogram
,
584 constants
::DW_CHILDREN_no
,
585 vec
![AttributeSpecification
::new(
586 constants
::DW_AT_name
,
587 constants
::DW_FORM_string
,
593 let debug_abbrev
= DebugAbbrev
::new(&buf
, LittleEndian
);
594 let debug_abbrev_offset
= DebugAbbrevOffset(extra_start
.len());
595 let abbrevs
= debug_abbrev
596 .abbreviations(debug_abbrev_offset
)
597 .expect("Should parse abbreviations");
598 assert_eq
!(abbrevs
.get(1), Some(&abbrev1
));
599 assert_eq
!(abbrevs
.get(2), Some(&abbrev2
));
603 fn test_abbreviations_insert() {
604 fn abbrev(code
: u16) -> Abbreviation
{
607 constants
::DwTag(code
),
608 constants
::DW_CHILDREN_no
,
613 fn assert_abbrev(abbrevs
: &Abbreviations
, code
: u16) {
614 let abbrev
= abbrevs
.get(code
.into()).unwrap();
615 assert_eq
!(abbrev
.tag(), constants
::DwTag(code
));
618 // Sequential insert.
619 let mut abbrevs
= Abbreviations
::empty();
620 abbrevs
.insert(abbrev(1)).unwrap();
621 abbrevs
.insert(abbrev(2)).unwrap();
622 assert_eq
!(abbrevs
.vec
.len(), 2);
623 assert
!(abbrevs
.map
.is_empty());
624 assert_abbrev(&abbrevs
, 1);
625 assert_abbrev(&abbrevs
, 2);
627 // Out of order insert.
628 let mut abbrevs
= Abbreviations
::empty();
629 abbrevs
.insert(abbrev(2)).unwrap();
630 abbrevs
.insert(abbrev(3)).unwrap();
631 assert
!(abbrevs
.vec
.is_empty());
632 assert_abbrev(&abbrevs
, 2);
633 assert_abbrev(&abbrevs
, 3);
635 // Mixed order insert.
636 let mut abbrevs
= Abbreviations
::empty();
637 abbrevs
.insert(abbrev(1)).unwrap();
638 abbrevs
.insert(abbrev(3)).unwrap();
639 abbrevs
.insert(abbrev(2)).unwrap();
640 assert_eq
!(abbrevs
.vec
.len(), 2);
641 assert_abbrev(&abbrevs
, 1);
642 assert_abbrev(&abbrevs
, 2);
643 assert_abbrev(&abbrevs
, 3);
645 // Duplicate code in vec.
646 let mut abbrevs
= Abbreviations
::empty();
647 abbrevs
.insert(abbrev(1)).unwrap();
648 abbrevs
.insert(abbrev(2)).unwrap();
649 assert_eq
!(abbrevs
.insert(abbrev(1)), Err(()));
650 assert_eq
!(abbrevs
.insert(abbrev(2)), Err(()));
652 // Duplicate code in map when adding to map.
653 let mut abbrevs
= Abbreviations
::empty();
654 abbrevs
.insert(abbrev(2)).unwrap();
655 assert_eq
!(abbrevs
.insert(abbrev(2)), Err(()));
657 // Duplicate code in map when adding to vec.
658 let mut abbrevs
= Abbreviations
::empty();
659 abbrevs
.insert(abbrev(2)).unwrap();
660 abbrevs
.insert(abbrev(1)).unwrap();
661 assert_eq
!(abbrevs
.insert(abbrev(2)), Err(()));
663 // 32-bit usize conversions.
664 let mut abbrevs
= Abbreviations
::empty();
665 abbrevs
.insert(abbrev(2)).unwrap();
669 #[cfg(target_pointer_width = "32")]
670 fn test_abbreviations_insert_32() {
671 fn abbrev(code
: u64) -> Abbreviation
{
674 constants
::DwTag(code
as u16),
675 constants
::DW_CHILDREN_no
,
680 fn assert_abbrev(abbrevs
: &Abbreviations
, code
: u64) {
681 let abbrev
= abbrevs
.get(code
).unwrap();
682 assert_eq
!(abbrev
.tag(), constants
::DwTag(code
as u16));
685 let mut abbrevs
= Abbreviations
::empty();
686 abbrevs
.insert(abbrev(1)).unwrap();
688 let wrap_code
= (u32::MAX
as u64 + 1) + 1;
689 // `get` should not treat the wrapped code as `1`.
690 assert_eq
!(abbrevs
.get(wrap_code
), None
);
691 // `insert` should not treat the wrapped code as `1`.
692 abbrevs
.insert(abbrev(wrap_code
)).unwrap();
693 assert_abbrev(&abbrevs
, 1);
694 assert_abbrev(&abbrevs
, wrap_code
);
698 fn test_parse_abbreviations_ok() {
699 let expected_rest
= [1, 2, 3, 4];
701 let buf
= Section
::new()
702 .abbrev(2, constants
::DW_TAG_subprogram
, constants
::DW_CHILDREN_no
)
703 .abbrev_attr(constants
::DW_AT_name
, constants
::DW_FORM_string
)
705 .abbrev(1, constants
::DW_TAG_compile_unit
, constants
::DW_CHILDREN_yes
)
706 .abbrev_attr(constants
::DW_AT_producer
, constants
::DW_FORM_strp
)
707 .abbrev_attr(constants
::DW_AT_language
, constants
::DW_FORM_data2
)
710 .append_bytes(&expected_rest
)
713 let rest
= &mut EndianSlice
::new(&*buf
, LittleEndian
);
715 let abbrev1
= Abbreviation
::new(
717 constants
::DW_TAG_compile_unit
,
718 constants
::DW_CHILDREN_yes
,
720 AttributeSpecification
::new(
721 constants
::DW_AT_producer
,
722 constants
::DW_FORM_strp
,
725 AttributeSpecification
::new(
726 constants
::DW_AT_language
,
727 constants
::DW_FORM_data2
,
734 let abbrev2
= Abbreviation
::new(
736 constants
::DW_TAG_subprogram
,
737 constants
::DW_CHILDREN_no
,
738 vec
![AttributeSpecification
::new(
739 constants
::DW_AT_name
,
740 constants
::DW_FORM_string
,
746 let abbrevs
= Abbreviations
::parse(rest
).expect("Should parse abbreviations");
747 assert_eq
!(abbrevs
.get(1), Some(&abbrev1
));
748 assert_eq
!(abbrevs
.get(2), Some(&abbrev2
));
749 assert_eq
!(*rest
, EndianSlice
::new(&expected_rest
, LittleEndian
));
753 fn test_parse_abbreviations_duplicate() {
754 let expected_rest
= [1, 2, 3, 4];
756 let buf
= Section
::new()
757 .abbrev(1, constants
::DW_TAG_subprogram
, constants
::DW_CHILDREN_no
)
758 .abbrev_attr(constants
::DW_AT_name
, constants
::DW_FORM_string
)
760 .abbrev(1, constants
::DW_TAG_compile_unit
, constants
::DW_CHILDREN_yes
)
761 .abbrev_attr(constants
::DW_AT_producer
, constants
::DW_FORM_strp
)
762 .abbrev_attr(constants
::DW_AT_language
, constants
::DW_FORM_data2
)
765 .append_bytes(&expected_rest
)
768 let buf
= &mut EndianSlice
::new(&*buf
, LittleEndian
);
770 match Abbreviations
::parse(buf
) {
771 Err(Error
::DuplicateAbbreviationCode
) => {}
772 otherwise
=> panic
!("Unexpected result: {:?}", otherwise
),
777 fn test_parse_abbreviation_tag_ok() {
778 let buf
= [0x01, 0x02];
779 let rest
= &mut EndianSlice
::new(&buf
, LittleEndian
);
780 let tag
= Abbreviation
::parse_tag(rest
).expect("Should parse tag");
781 assert_eq
!(tag
, constants
::DW_TAG_array_type
);
782 assert_eq
!(*rest
, EndianSlice
::new(&buf
[1..], LittleEndian
));
786 fn test_parse_abbreviation_tag_zero() {
788 let buf
= &mut EndianSlice
::new(&buf
, LittleEndian
);
789 match Abbreviation
::parse_tag(buf
) {
790 Err(Error
::AbbreviationTagZero
) => {}
791 otherwise
=> panic
!("Unexpected result: {:?}", otherwise
),
796 fn test_parse_abbreviation_has_children() {
797 let buf
= [0x00, 0x01, 0x02];
798 let rest
= &mut EndianSlice
::new(&buf
, LittleEndian
);
799 let val
= Abbreviation
::parse_has_children(rest
).expect("Should parse children");
800 assert_eq
!(val
, constants
::DW_CHILDREN_no
);
801 let val
= Abbreviation
::parse_has_children(rest
).expect("Should parse children");
802 assert_eq
!(val
, constants
::DW_CHILDREN_yes
);
803 match Abbreviation
::parse_has_children(rest
) {
804 Err(Error
::BadHasChildren
) => {}
805 otherwise
=> panic
!("Unexpected result: {:?}", otherwise
),
810 fn test_parse_abbreviation_ok() {
811 let expected_rest
= [0x01, 0x02, 0x03, 0x04];
812 let buf
= Section
::new()
813 .abbrev(1, constants
::DW_TAG_subprogram
, constants
::DW_CHILDREN_no
)
814 .abbrev_attr(constants
::DW_AT_name
, constants
::DW_FORM_string
)
816 .append_bytes(&expected_rest
)
819 let rest
= &mut EndianSlice
::new(&*buf
, LittleEndian
);
821 let expect
= Some(Abbreviation
::new(
823 constants
::DW_TAG_subprogram
,
824 constants
::DW_CHILDREN_no
,
825 vec
![AttributeSpecification
::new(
826 constants
::DW_AT_name
,
827 constants
::DW_FORM_string
,
833 let abbrev
= Abbreviation
::parse(rest
).expect("Should parse abbreviation");
834 assert_eq
!(abbrev
, expect
);
835 assert_eq
!(*rest
, EndianSlice
::new(&expected_rest
, LittleEndian
));
839 fn test_parse_abbreviation_implicit_const_ok() {
840 let expected_rest
= [0x01, 0x02, 0x03, 0x04];
841 let buf
= Section
::new()
842 .abbrev(1, constants
::DW_TAG_subprogram
, constants
::DW_CHILDREN_no
)
843 .abbrev_attr_implicit_const(constants
::DW_AT_name
, -42)
845 .append_bytes(&expected_rest
)
848 let rest
= &mut EndianSlice
::new(&*buf
, LittleEndian
);
850 let expect
= Some(Abbreviation
::new(
852 constants
::DW_TAG_subprogram
,
853 constants
::DW_CHILDREN_no
,
854 vec
![AttributeSpecification
::new(
855 constants
::DW_AT_name
,
856 constants
::DW_FORM_implicit_const
,
862 let abbrev
= Abbreviation
::parse(rest
).expect("Should parse abbreviation");
863 assert_eq
!(abbrev
, expect
);
864 assert_eq
!(*rest
, EndianSlice
::new(&expected_rest
, LittleEndian
));
868 fn test_parse_abbreviation_implicit_const_no_const() {
869 let buf
= Section
::new()
870 .abbrev(1, constants
::DW_TAG_subprogram
, constants
::DW_CHILDREN_no
)
871 .abbrev_attr(constants
::DW_AT_name
, constants
::DW_FORM_implicit_const
)
874 let buf
= &mut EndianSlice
::new(&*buf
, LittleEndian
);
876 match Abbreviation
::parse(buf
) {
877 Err(Error
::UnexpectedEof(_
)) => {}
878 otherwise
=> panic
!("Unexpected result: {:?}", otherwise
),
883 fn test_parse_null_abbreviation_ok() {
884 let expected_rest
= [0x01, 0x02, 0x03, 0x04];
885 let buf
= Section
::new()
887 .append_bytes(&expected_rest
)
890 let rest
= &mut EndianSlice
::new(&*buf
, LittleEndian
);
892 let abbrev
= Abbreviation
::parse(rest
).expect("Should parse null abbreviation");
893 assert
!(abbrev
.is_none());
894 assert_eq
!(*rest
, EndianSlice
::new(&expected_rest
, LittleEndian
));
898 fn test_parse_attribute_form_ok() {
899 let buf
= [0x01, 0x02];
900 let rest
= &mut EndianSlice
::new(&buf
, LittleEndian
);
901 let tag
= AttributeSpecification
::parse_form(rest
).expect("Should parse form");
902 assert_eq
!(tag
, constants
::DW_FORM_addr
);
903 assert_eq
!(*rest
, EndianSlice
::new(&buf
[1..], LittleEndian
));
907 fn test_parse_attribute_form_zero() {
909 let buf
= &mut EndianSlice
::new(&buf
, LittleEndian
);
910 match AttributeSpecification
::parse_form(buf
) {
911 Err(Error
::AttributeFormZero
) => {}
912 otherwise
=> panic
!("Unexpected result: {:?}", otherwise
),
917 fn test_parse_null_attribute_specification_ok() {
918 let buf
= [0x00, 0x00, 0x01];
919 let rest
= &mut EndianSlice
::new(&buf
, LittleEndian
);
921 AttributeSpecification
::parse(rest
).expect("Should parse null attribute specification");
922 assert
!(attr
.is_none());
923 assert_eq
!(*rest
, EndianSlice
::new(&buf
[2..], LittleEndian
));
927 fn test_parse_attribute_specifications_name_zero() {
928 let buf
= [0x00, 0x01, 0x00, 0x00];
929 let buf
= &mut EndianSlice
::new(&buf
, LittleEndian
);
930 match AttributeSpecification
::parse(buf
) {
931 Err(Error
::ExpectedZero
) => {}
932 otherwise
=> panic
!("Unexpected result: {:?}", otherwise
),
937 fn test_parse_attribute_specifications_form_zero() {
938 let buf
= [0x01, 0x00, 0x00, 0x00];
939 let buf
= &mut EndianSlice
::new(&buf
, LittleEndian
);
940 match AttributeSpecification
::parse(buf
) {
941 Err(Error
::AttributeFormZero
) => {}
942 otherwise
=> panic
!("Unexpected result: {:?}", otherwise
),