]> git.proxmox.com Git - rustc.git/blob - vendor/gimli/src/read/abbrev.rs
New upstream version 1.46.0~beta.2+dfsg1
[rustc.git] / vendor / gimli / src / read / abbrev.rs
1 //! Functions for parsing DWARF debugging abbreviations.
2
3 use alloc::collections::btree_map;
4 use alloc::vec::Vec;
5 use core::fmt::{self, Debug};
6 use core::iter::FromIterator;
7 use core::ops::Deref;
8
9 use crate::common::{DebugAbbrevOffset, SectionId};
10 use crate::constants;
11 use crate::endianity::Endianity;
12 use crate::read::{EndianSlice, Error, Reader, Result, Section, UnitHeader};
13
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,
20 }
21
22 impl<'input, Endian> DebugAbbrev<EndianSlice<'input, Endian>>
23 where
24 Endian: Endianity,
25 {
26 /// Construct a new `DebugAbbrev` instance from the data in the `.debug_abbrev`
27 /// section.
28 ///
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.
32 ///
33 /// ```
34 /// use gimli::{DebugAbbrev, LittleEndian};
35 ///
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);
39 /// ```
40 pub fn new(debug_abbrev_section: &'input [u8], endian: Endian) -> Self {
41 Self::from(EndianSlice::new(debug_abbrev_section, endian))
42 }
43 }
44
45 impl<R: Reader> DebugAbbrev<R> {
46 /// Parse the abbreviations at the given `offset` within this
47 /// `.debug_abbrev` section.
48 ///
49 /// The `offset` should generally be retrieved from a unit header.
50 pub fn abbreviations(
51 &self,
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)
57 }
58 }
59
60 impl<T> DebugAbbrev<T> {
61 /// Create a `DebugAbbrev` section that references the data in `self`.
62 ///
63 /// This is useful when `R` implements `Reader` but `T` does not.
64 ///
65 /// ## Example Usage
66 ///
67 /// ```rust,no_run
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(&section, gimli::LittleEndian)
74 /// });
75 /// ```
76 pub fn borrow<'a, F, R>(&'a self, mut borrow: F) -> DebugAbbrev<R>
77 where
78 F: FnMut(&'a T) -> R,
79 {
80 borrow(&self.debug_abbrev_section).into()
81 }
82 }
83
84 impl<R> Section<R> for DebugAbbrev<R> {
85 fn id() -> SectionId {
86 SectionId::DebugAbbrev
87 }
88
89 fn reader(&self) -> &R {
90 &self.debug_abbrev_section
91 }
92 }
93
94 impl<R> From<R> for DebugAbbrev<R> {
95 fn from(debug_abbrev_section: R) -> Self {
96 DebugAbbrev {
97 debug_abbrev_section,
98 }
99 }
100 }
101
102 /// A set of type abbreviations.
103 ///
104 /// Construct an `Abbreviations` instance with the
105 /// [`abbreviations()`](struct.UnitHeader.html#method.abbreviations)
106 /// method.
107 #[derive(Debug, Default, Clone)]
108 pub struct Abbreviations {
109 vec: Vec<Abbreviation>,
110 map: btree_map::BTreeMap<u64, Abbreviation>,
111 }
112
113 impl Abbreviations {
114 /// Construct a new, empty set of abbreviations.
115 fn empty() -> Abbreviations {
116 Abbreviations {
117 vec: Vec::new(),
118 map: btree_map::BTreeMap::new(),
119 }
120 }
121
122 /// Insert an abbreviation into the set.
123 ///
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() {
135 return Err(());
136 } else if code_usize - 1 == self.vec.len() {
137 if !self.map.is_empty() && self.map.contains_key(&abbrev.code) {
138 return Err(());
139 } else {
140 self.vec.push(abbrev);
141 return Ok(());
142 }
143 }
144 }
145 match self.map.entry(abbrev.code) {
146 btree_map::Entry::Occupied(_) => Err(()),
147 btree_map::Entry::Vacant(entry) => {
148 entry.insert(abbrev);
149 Ok(())
150 }
151 }
152 }
153
154 /// Get the abbreviation associated with the given code.
155 #[inline]
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])
160 } else {
161 self.map.get(&code)
162 }
163 }
164
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();
168
169 while let Some(abbrev) = Abbreviation::parse(input)? {
170 if abbrevs.insert(abbrev).is_err() {
171 return Err(Error::DuplicateAbbreviationCode);
172 }
173 }
174
175 Ok(abbrevs)
176 }
177 }
178
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 {
183 code: u64,
184 tag: constants::DwTag,
185 has_children: constants::DwChildren,
186 attributes: Attributes,
187 }
188
189 impl Abbreviation {
190 /// Construct a new `Abbreviation`.
191 ///
192 /// ### Panics
193 ///
194 /// Panics if `code` is `0`.
195 pub(crate) fn new(
196 code: u64,
197 tag: constants::DwTag,
198 has_children: constants::DwChildren,
199 attributes: Attributes,
200 ) -> Abbreviation {
201 assert_ne!(code, 0);
202 Abbreviation {
203 code,
204 tag,
205 has_children,
206 attributes,
207 }
208 }
209
210 /// Get this abbreviation's code.
211 #[inline]
212 pub fn code(&self) -> u64 {
213 self.code
214 }
215
216 /// Get this abbreviation's tag.
217 #[inline]
218 pub fn tag(&self) -> constants::DwTag {
219 self.tag
220 }
221
222 /// Return true if this abbreviation's type has children, false otherwise.
223 #[inline]
224 pub fn has_children(&self) -> bool {
225 self.has_children == constants::DW_CHILDREN_yes
226 }
227
228 /// Get this abbreviation's attributes.
229 #[inline]
230 pub fn attributes(&self) -> &[AttributeSpecification] {
231 &self.attributes[..]
232 }
233
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()?;
237 if val == 0 {
238 Err(Error::AbbreviationTagZero)
239 } else {
240 Ok(constants::DwTag(val))
241 }
242 }
243
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 {
249 Ok(val)
250 } else {
251 Err(Error::BadHasChildren)
252 }
253 }
254
255 /// Parse a series of attribute specifications, terminated by a null attribute
256 /// specification.
257 fn parse_attributes<R: Reader>(input: &mut R) -> Result<Attributes> {
258 let mut attrs = Attributes::new();
259
260 while let Some(attr) = AttributeSpecification::parse(input)? {
261 attrs.push(attr);
262 }
263
264 Ok(attrs)
265 }
266
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()?;
271 if code == 0 {
272 return Ok(None);
273 }
274
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);
279 Ok(Some(abbrev))
280 }
281 }
282
283 /// A list of attributes found in an `Abbreviation`
284 #[derive(Clone)]
285 pub(crate) enum Attributes {
286 Inline {
287 buf: [AttributeSpecification; MAX_ATTRIBUTES_INLINE],
288 len: usize,
289 },
290 Heap(Vec<AttributeSpecification>),
291 }
292
293 // Length of 5 based on benchmark results for both x86-64 and i686.
294 const MAX_ATTRIBUTES_INLINE: usize = 5;
295
296 impl Attributes {
297 /// Returns a new empty list of attributes
298 fn new() -> Attributes {
299 let default =
300 AttributeSpecification::new(constants::DW_AT_null, constants::DW_FORM_null, None);
301 Attributes::Inline {
302 buf: [default; 5],
303 len: 0,
304 }
305 }
306
307 /// Pushes a new value onto this list of attributes.
308 fn push(&mut self, attr: AttributeSpecification) {
309 match self {
310 Attributes::Heap(list) => return list.push(attr),
311 Attributes::Inline {
312 buf,
313 len: MAX_ATTRIBUTES_INLINE,
314 } => {
315 let mut list = buf.to_vec();
316 list.push(attr);
317 *self = Attributes::Heap(list);
318 }
319 Attributes::Inline { buf, len } => {
320 buf[*len] = attr;
321 *len += 1;
322 }
323 }
324 }
325 }
326
327 impl Debug for Attributes {
328 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
329 (&**self).fmt(f)
330 }
331 }
332
333 impl PartialEq for Attributes {
334 fn eq(&self, other: &Attributes) -> bool {
335 &**self == &**other
336 }
337 }
338
339 impl Eq for Attributes {}
340
341 impl Deref for Attributes {
342 type Target = [AttributeSpecification];
343 fn deref(&self) -> &[AttributeSpecification] {
344 match self {
345 Attributes::Inline { buf, len } => &buf[..*len],
346 Attributes::Heap(list) => list,
347 }
348 }
349 }
350
351 impl FromIterator<AttributeSpecification> for Attributes {
352 fn from_iter<I>(iter: I) -> Attributes
353 where
354 I: IntoIterator<Item = AttributeSpecification>,
355 {
356 let mut list = Attributes::new();
357 for item in iter {
358 list.push(item);
359 }
360 return list;
361 }
362 }
363
364 impl From<Vec<AttributeSpecification>> for Attributes {
365 fn from(list: Vec<AttributeSpecification>) -> Attributes {
366 Attributes::Heap(list)
367 }
368 }
369
370 /// The description of an attribute in an abbreviated type. It is a pair of name
371 /// and form.
372 #[derive(Debug, Clone, Copy, PartialEq, Eq)]
373 pub struct AttributeSpecification {
374 name: constants::DwAt,
375 form: constants::DwForm,
376 implicit_const_value: i64,
377 }
378
379 impl AttributeSpecification {
380 /// Construct a new `AttributeSpecification` from the given name and form
381 /// and implicit const value.
382 #[inline]
383 pub fn new(
384 name: constants::DwAt,
385 form: constants::DwForm,
386 implicit_const_value: Option<i64>,
387 ) -> AttributeSpecification {
388 debug_assert!(
389 (form == constants::DW_FORM_implicit_const && implicit_const_value.is_some())
390 || (form != constants::DW_FORM_implicit_const && implicit_const_value.is_none())
391 );
392 AttributeSpecification {
393 name,
394 form,
395 implicit_const_value: implicit_const_value.unwrap_or(0),
396 }
397 }
398
399 /// Get the attribute's name.
400 #[inline]
401 pub fn name(&self) -> constants::DwAt {
402 self.name
403 }
404
405 /// Get the attribute's form.
406 #[inline]
407 pub fn form(&self) -> constants::DwForm {
408 self.form
409 }
410
411 /// Get the attribute's implicit const value.
412 #[inline]
413 pub fn implicit_const_value(&self) -> i64 {
414 assert!(self.form == constants::DW_FORM_implicit_const);
415 self.implicit_const_value
416 }
417
418 /// Return the size of the attribute, in bytes.
419 ///
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> {
423 match self.form {
424 constants::DW_FORM_addr => Some(header.address_size() as usize),
425
426 constants::DW_FORM_implicit_const => Some(0),
427
428 constants::DW_FORM_flag |
429 constants::DW_FORM_flag_present |
430 constants::DW_FORM_data1 |
431 constants::DW_FORM_ref1 => Some(1),
432
433 constants::DW_FORM_data2 |
434 constants::DW_FORM_ref2 => Some(2),
435
436 constants::DW_FORM_data4 |
437 constants::DW_FORM_ref4 => Some(4),
438
439 constants::DW_FORM_data8 |
440 constants::DW_FORM_ref8 => Some(8),
441
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),
446
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 |
458
459 // We don't know the size of unknown forms.
460 _ => None,
461 }
462 }
463
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()?;
467 if val == 0 {
468 Err(Error::AttributeFormZero)
469 } else {
470 Ok(constants::DwForm(val))
471 }
472 }
473
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()?;
478 if name == 0 {
479 // Parse the null attribute specification.
480 let form = input.read_uleb128_u16()?;
481 return if form == 0 {
482 Ok(None)
483 } else {
484 Err(Error::ExpectedZero)
485 };
486 }
487
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()?)
492 } else {
493 None
494 };
495 let spec = AttributeSpecification::new(name, form, implicit_const_value);
496 Ok(Some(spec))
497 }
498 }
499
500 #[cfg(test)]
501 pub mod tests {
502 use super::*;
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")]
508 use core::u32;
509 use test_assembler::Section;
510
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;
517 }
518
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)
522 }
523
524 fn abbrev_null(self) -> Self {
525 self.D8(0)
526 }
527
528 fn abbrev_attr(self, name: constants::DwAt, form: constants::DwForm) -> Self {
529 self.uleb(name.0.into()).uleb(form.0.into())
530 }
531
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())
535 .sleb(value)
536 }
537
538 fn abbrev_attr_null(self) -> Self {
539 self.D8(0).D8(0)
540 }
541 }
542
543 #[test]
544 fn test_debug_abbrev_ok() {
545 let extra_start = [1, 2, 3, 4];
546 let expected_rest = [5, 6, 7, 8];
547 #[rustfmt::skip]
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)
552 .abbrev_attr_null()
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)
556 .abbrev_attr_null()
557 .abbrev_null()
558 .append_bytes(&expected_rest)
559 .get_contents()
560 .unwrap();
561
562 let abbrev1 = Abbreviation::new(
563 1,
564 constants::DW_TAG_compile_unit,
565 constants::DW_CHILDREN_yes,
566 vec![
567 AttributeSpecification::new(
568 constants::DW_AT_producer,
569 constants::DW_FORM_strp,
570 None,
571 ),
572 AttributeSpecification::new(
573 constants::DW_AT_language,
574 constants::DW_FORM_data2,
575 None,
576 ),
577 ]
578 .into(),
579 );
580
581 let abbrev2 = Abbreviation::new(
582 2,
583 constants::DW_TAG_subprogram,
584 constants::DW_CHILDREN_no,
585 vec![AttributeSpecification::new(
586 constants::DW_AT_name,
587 constants::DW_FORM_string,
588 None,
589 )]
590 .into(),
591 );
592
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));
600 }
601
602 #[test]
603 fn test_abbreviations_insert() {
604 fn abbrev(code: u16) -> Abbreviation {
605 Abbreviation::new(
606 code.into(),
607 constants::DwTag(code),
608 constants::DW_CHILDREN_no,
609 vec![].into(),
610 )
611 }
612
613 fn assert_abbrev(abbrevs: &Abbreviations, code: u16) {
614 let abbrev = abbrevs.get(code.into()).unwrap();
615 assert_eq!(abbrev.tag(), constants::DwTag(code));
616 }
617
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);
626
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);
634
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);
644
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(()));
651
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(()));
656
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(()));
662
663 // 32-bit usize conversions.
664 let mut abbrevs = Abbreviations::empty();
665 abbrevs.insert(abbrev(2)).unwrap();
666 }
667
668 #[test]
669 #[cfg(target_pointer_width = "32")]
670 fn test_abbreviations_insert_32() {
671 fn abbrev(code: u64) -> Abbreviation {
672 Abbreviation::new(
673 code,
674 constants::DwTag(code as u16),
675 constants::DW_CHILDREN_no,
676 vec![].into(),
677 )
678 }
679
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));
683 }
684
685 let mut abbrevs = Abbreviations::empty();
686 abbrevs.insert(abbrev(1)).unwrap();
687
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);
695 }
696
697 #[test]
698 fn test_parse_abbreviations_ok() {
699 let expected_rest = [1, 2, 3, 4];
700 #[rustfmt::skip]
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)
704 .abbrev_attr_null()
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)
708 .abbrev_attr_null()
709 .abbrev_null()
710 .append_bytes(&expected_rest)
711 .get_contents()
712 .unwrap();
713 let rest = &mut EndianSlice::new(&*buf, LittleEndian);
714
715 let abbrev1 = Abbreviation::new(
716 1,
717 constants::DW_TAG_compile_unit,
718 constants::DW_CHILDREN_yes,
719 vec![
720 AttributeSpecification::new(
721 constants::DW_AT_producer,
722 constants::DW_FORM_strp,
723 None,
724 ),
725 AttributeSpecification::new(
726 constants::DW_AT_language,
727 constants::DW_FORM_data2,
728 None,
729 ),
730 ]
731 .into(),
732 );
733
734 let abbrev2 = Abbreviation::new(
735 2,
736 constants::DW_TAG_subprogram,
737 constants::DW_CHILDREN_no,
738 vec![AttributeSpecification::new(
739 constants::DW_AT_name,
740 constants::DW_FORM_string,
741 None,
742 )]
743 .into(),
744 );
745
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));
750 }
751
752 #[test]
753 fn test_parse_abbreviations_duplicate() {
754 let expected_rest = [1, 2, 3, 4];
755 #[rustfmt::skip]
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)
759 .abbrev_attr_null()
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)
763 .abbrev_attr_null()
764 .abbrev_null()
765 .append_bytes(&expected_rest)
766 .get_contents()
767 .unwrap();
768 let buf = &mut EndianSlice::new(&*buf, LittleEndian);
769
770 match Abbreviations::parse(buf) {
771 Err(Error::DuplicateAbbreviationCode) => {}
772 otherwise => panic!("Unexpected result: {:?}", otherwise),
773 };
774 }
775
776 #[test]
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));
783 }
784
785 #[test]
786 fn test_parse_abbreviation_tag_zero() {
787 let buf = [0x00];
788 let buf = &mut EndianSlice::new(&buf, LittleEndian);
789 match Abbreviation::parse_tag(buf) {
790 Err(Error::AbbreviationTagZero) => {}
791 otherwise => panic!("Unexpected result: {:?}", otherwise),
792 };
793 }
794
795 #[test]
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),
806 };
807 }
808
809 #[test]
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)
815 .abbrev_attr_null()
816 .append_bytes(&expected_rest)
817 .get_contents()
818 .unwrap();
819 let rest = &mut EndianSlice::new(&*buf, LittleEndian);
820
821 let expect = Some(Abbreviation::new(
822 1,
823 constants::DW_TAG_subprogram,
824 constants::DW_CHILDREN_no,
825 vec![AttributeSpecification::new(
826 constants::DW_AT_name,
827 constants::DW_FORM_string,
828 None,
829 )]
830 .into(),
831 ));
832
833 let abbrev = Abbreviation::parse(rest).expect("Should parse abbreviation");
834 assert_eq!(abbrev, expect);
835 assert_eq!(*rest, EndianSlice::new(&expected_rest, LittleEndian));
836 }
837
838 #[test]
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)
844 .abbrev_attr_null()
845 .append_bytes(&expected_rest)
846 .get_contents()
847 .unwrap();
848 let rest = &mut EndianSlice::new(&*buf, LittleEndian);
849
850 let expect = Some(Abbreviation::new(
851 1,
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,
857 Some(-42),
858 )]
859 .into(),
860 ));
861
862 let abbrev = Abbreviation::parse(rest).expect("Should parse abbreviation");
863 assert_eq!(abbrev, expect);
864 assert_eq!(*rest, EndianSlice::new(&expected_rest, LittleEndian));
865 }
866
867 #[test]
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)
872 .get_contents()
873 .unwrap();
874 let buf = &mut EndianSlice::new(&*buf, LittleEndian);
875
876 match Abbreviation::parse(buf) {
877 Err(Error::UnexpectedEof(_)) => {}
878 otherwise => panic!("Unexpected result: {:?}", otherwise),
879 }
880 }
881
882 #[test]
883 fn test_parse_null_abbreviation_ok() {
884 let expected_rest = [0x01, 0x02, 0x03, 0x04];
885 let buf = Section::new()
886 .abbrev_null()
887 .append_bytes(&expected_rest)
888 .get_contents()
889 .unwrap();
890 let rest = &mut EndianSlice::new(&*buf, LittleEndian);
891
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));
895 }
896
897 #[test]
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));
904 }
905
906 #[test]
907 fn test_parse_attribute_form_zero() {
908 let buf = [0x00];
909 let buf = &mut EndianSlice::new(&buf, LittleEndian);
910 match AttributeSpecification::parse_form(buf) {
911 Err(Error::AttributeFormZero) => {}
912 otherwise => panic!("Unexpected result: {:?}", otherwise),
913 };
914 }
915
916 #[test]
917 fn test_parse_null_attribute_specification_ok() {
918 let buf = [0x00, 0x00, 0x01];
919 let rest = &mut EndianSlice::new(&buf, LittleEndian);
920 let attr =
921 AttributeSpecification::parse(rest).expect("Should parse null attribute specification");
922 assert!(attr.is_none());
923 assert_eq!(*rest, EndianSlice::new(&buf[2..], LittleEndian));
924 }
925
926 #[test]
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),
933 };
934 }
935
936 #[test]
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),
943 };
944 }
945 }