diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-17 12:19:41 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-17 12:19:41 +0000 |
commit | 4f9fe856a25ab29345b90e7725509e9ee38a37be (patch) | |
tree | e4ffd8a9374cae7b21f7cbfb352927e0e074aff6 /vendor/gimli/src/read/abbrev.rs | |
parent | Adding upstream version 1.68.2+dfsg1. (diff) | |
download | rustc-5cd5bd4daf55da04d2c8e7c06c3067a027cfbfc2.tar.xz rustc-5cd5bd4daf55da04d2c8e7c06c3067a027cfbfc2.zip |
Adding upstream version 1.69.0+dfsg1.upstream/1.69.0+dfsg1
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to '')
-rw-r--r-- | vendor/gimli/src/read/abbrev.rs | 129 |
1 files changed, 111 insertions, 18 deletions
diff --git a/vendor/gimli/src/read/abbrev.rs b/vendor/gimli/src/read/abbrev.rs index 1a24835a7..54f5cf8e5 100644 --- a/vendor/gimli/src/read/abbrev.rs +++ b/vendor/gimli/src/read/abbrev.rs @@ -1,6 +1,7 @@ //! Functions for parsing DWARF debugging abbreviations. use alloc::collections::btree_map; +use alloc::sync::Arc; use alloc::vec::Vec; use core::convert::TryFrom; use core::fmt::{self, Debug}; @@ -10,7 +11,8 @@ use core::ops::Deref; use crate::common::{DebugAbbrevOffset, Encoding, SectionId}; use crate::constants; use crate::endianity::Endianity; -use crate::read::{EndianSlice, Error, Reader, Result, Section, UnitHeader}; +use crate::read::lazy::LazyArc; +use crate::read::{EndianSlice, Error, Reader, ReaderOffset, Result, Section, UnitHeader}; /// The `DebugAbbrev` struct represents the abbreviations describing /// `DebuggingInformationEntry`s' attribute names and forms found in the @@ -100,6 +102,38 @@ impl<R> From<R> for DebugAbbrev<R> { } } +/// A cache of previously parsed `Abbreviations`. +/// +/// Currently this only caches the abbreviations for offset 0, +/// since this is a common case in which abbreviations are reused. +/// This strategy may change in future if there is sufficient need. +#[derive(Debug, Default)] +pub struct AbbreviationsCache { + abbreviations: LazyArc<Abbreviations>, +} + +impl AbbreviationsCache { + /// Create an empty abbreviations cache. + pub fn new() -> Self { + Self::default() + } + + /// Parse the abbreviations at the given offset. + /// + /// This uses or updates the cache as required. + pub fn get<R: Reader>( + &self, + debug_abbrev: &DebugAbbrev<R>, + offset: DebugAbbrevOffset<R::Offset>, + ) -> Result<Arc<Abbreviations>> { + if offset.0 != R::Offset::from_u8(0) { + return debug_abbrev.abbreviations(offset).map(Arc::new); + } + self.abbreviations + .get(|| debug_abbrev.abbreviations(offset)) + } +} + /// A set of type abbreviations. /// /// Construct an `Abbreviations` instance with the @@ -310,7 +344,7 @@ impl Attributes { /// Pushes a new value onto this list of attributes. fn push(&mut self, attr: AttributeSpecification) { match self { - Attributes::Heap(list) => return list.push(attr), + Attributes::Heap(list) => list.push(attr), Attributes::Inline { buf, len: MAX_ATTRIBUTES_INLINE, @@ -329,13 +363,13 @@ impl Attributes { impl Debug for Attributes { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - (&**self).fmt(f) + (**self).fmt(f) } } impl PartialEq for Attributes { fn eq(&self, other: &Attributes) -> bool { - &**self == &**other + **self == **other } } @@ -360,7 +394,7 @@ impl FromIterator<AttributeSpecification> for Attributes { for item in iter { list.push(item); } - return list; + list } } @@ -470,8 +504,7 @@ pub(crate) fn get_attribute_size(form: constants::DwForm, encoding: Encoding) -> match form { constants::DW_FORM_addr => Some(encoding.address_size), - constants::DW_FORM_implicit_const | - constants::DW_FORM_flag_present => Some(0), + constants::DW_FORM_implicit_const | constants::DW_FORM_flag_present => Some(0), constants::DW_FORM_data1 | constants::DW_FORM_flag @@ -497,7 +530,7 @@ pub(crate) fn get_attribute_size(form: constants::DwForm, encoding: Encoding) -> | constants::DW_FORM_ref_sig8 | constants::DW_FORM_ref_sup8 => Some(8), - constants::DW_FORM_data16 => Some(16), + constants::DW_FORM_data16 => Some(16), constants::DW_FORM_sec_offset | constants::DW_FORM_GNU_ref_alt @@ -518,16 +551,16 @@ pub(crate) fn get_attribute_size(form: constants::DwForm, encoding: Encoding) -> } // Variably sized forms. - constants::DW_FORM_block | - constants::DW_FORM_block1 | - constants::DW_FORM_block2 | - constants::DW_FORM_block4 | - constants::DW_FORM_exprloc | - constants::DW_FORM_ref_udata | - constants::DW_FORM_string | - constants::DW_FORM_sdata | - constants::DW_FORM_udata | - constants::DW_FORM_indirect | + constants::DW_FORM_block + | constants::DW_FORM_block1 + | constants::DW_FORM_block2 + | constants::DW_FORM_block4 + | constants::DW_FORM_exprloc + | constants::DW_FORM_ref_udata + | constants::DW_FORM_string + | constants::DW_FORM_sdata + | constants::DW_FORM_udata + | constants::DW_FORM_indirect => None, // We don't know the size of unknown forms. _ => None, @@ -993,4 +1026,64 @@ pub mod tests { .unwrap(); assert!(abbrevs.get(0).is_none()); } + + #[test] + fn abbreviations_cache() { + #[rustfmt::skip] + let buf = Section::new() + .abbrev(1, constants::DW_TAG_subprogram, constants::DW_CHILDREN_no) + .abbrev_attr(constants::DW_AT_name, constants::DW_FORM_string) + .abbrev_attr_null() + .abbrev_null() + .abbrev(1, constants::DW_TAG_compile_unit, constants::DW_CHILDREN_yes) + .abbrev_attr(constants::DW_AT_producer, constants::DW_FORM_strp) + .abbrev_attr(constants::DW_AT_language, constants::DW_FORM_data2) + .abbrev_attr_null() + .abbrev_null() + .get_contents() + .unwrap(); + + let abbrev1 = Abbreviation::new( + 1, + constants::DW_TAG_subprogram, + constants::DW_CHILDREN_no, + vec![AttributeSpecification::new( + constants::DW_AT_name, + constants::DW_FORM_string, + None, + )] + .into(), + ); + + let abbrev2 = Abbreviation::new( + 1, + constants::DW_TAG_compile_unit, + constants::DW_CHILDREN_yes, + vec![ + AttributeSpecification::new( + constants::DW_AT_producer, + constants::DW_FORM_strp, + None, + ), + AttributeSpecification::new( + constants::DW_AT_language, + constants::DW_FORM_data2, + None, + ), + ] + .into(), + ); + + let debug_abbrev = DebugAbbrev::new(&buf, LittleEndian); + let cache = AbbreviationsCache::new(); + let abbrevs1 = cache.get(&debug_abbrev, DebugAbbrevOffset(0)).unwrap(); + assert_eq!(abbrevs1.get(1), Some(&abbrev1)); + let abbrevs2 = cache.get(&debug_abbrev, DebugAbbrevOffset(8)).unwrap(); + assert_eq!(abbrevs2.get(1), Some(&abbrev2)); + let abbrevs3 = cache.get(&debug_abbrev, DebugAbbrevOffset(0)).unwrap(); + assert_eq!(abbrevs3.get(1), Some(&abbrev1)); + + assert!(!Arc::ptr_eq(&abbrevs1, &abbrevs2)); + assert!(Arc::ptr_eq(&abbrevs1, &abbrevs3)); + } } |