diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-17 12:19:43 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-17 12:19:43 +0000 |
commit | 3e3e70d529d8c7d7c4d7bc4fefc9f109393b9245 (patch) | |
tree | daf049b282ab10e8c3d03e409b3cd84ff3f7690c /vendor/gimli/src | |
parent | Adding debian version 1.68.2+dfsg1-1. (diff) | |
download | rustc-3e3e70d529d8c7d7c4d7bc4fefc9f109393b9245.tar.xz rustc-3e3e70d529d8c7d7c4d7bc4fefc9f109393b9245.zip |
Merging upstream version 1.69.0+dfsg1.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'vendor/gimli/src')
-rw-r--r-- | vendor/gimli/src/arch.rs | 148 | ||||
-rw-r--r-- | vendor/gimli/src/lib.rs | 15 | ||||
-rw-r--r-- | vendor/gimli/src/read/abbrev.rs | 129 | ||||
-rw-r--r-- | vendor/gimli/src/read/cfi.rs | 23 | ||||
-rw-r--r-- | vendor/gimli/src/read/dwarf.rs | 26 | ||||
-rw-r--r-- | vendor/gimli/src/read/endian_slice.rs | 6 | ||||
-rw-r--r-- | vendor/gimli/src/read/lazy.rs | 116 | ||||
-rw-r--r-- | vendor/gimli/src/read/line.rs | 2 | ||||
-rw-r--r-- | vendor/gimli/src/read/loclists.rs | 241 | ||||
-rw-r--r-- | vendor/gimli/src/read/mod.rs | 3 | ||||
-rw-r--r-- | vendor/gimli/src/read/op.rs | 7 | ||||
-rw-r--r-- | vendor/gimli/src/read/rnglists.rs | 206 | ||||
-rw-r--r-- | vendor/gimli/src/read/unit.rs | 13 | ||||
-rw-r--r-- | vendor/gimli/src/read/util.rs | 5 | ||||
-rw-r--r-- | vendor/gimli/src/write/line.rs | 5 | ||||
-rw-r--r-- | vendor/gimli/src/write/loc.rs | 3 | ||||
-rw-r--r-- | vendor/gimli/src/write/op.rs | 15 | ||||
-rw-r--r-- | vendor/gimli/src/write/range.rs | 3 | ||||
-rw-r--r-- | vendor/gimli/src/write/section.rs | 2 | ||||
-rw-r--r-- | vendor/gimli/src/write/unit.rs | 17 | ||||
-rw-r--r-- | vendor/gimli/src/write/writer.rs | 5 |
21 files changed, 769 insertions, 221 deletions
diff --git a/vendor/gimli/src/arch.rs b/vendor/gimli/src/arch.rs index f5b2e5ed8..abc872d83 100644 --- a/vendor/gimli/src/arch.rs +++ b/vendor/gimli/src/arch.rs @@ -291,6 +291,154 @@ registers!(AArch64, { V31 = (95, "V31"), }); +/// LoongArch architecture specific definitions. +/// +/// See [LoongArch ELF psABI specification](https://loongson.github.io/LoongArch-Documentation/LoongArch-ELF-ABI-EN.html). +#[derive(Debug, Clone, Copy)] +pub struct LoongArch; + +registers!(LoongArch, { + R0 = (0, "$r0"), + R1 = (1, "$r1"), + R2 = (2, "$r2"), + R3 = (3, "$r3"), + R4 = (4, "$r4"), + R5 = (5, "$r5"), + R6 = (6, "$r6"), + R7 = (7, "$r7"), + R8 = (8, "$r8"), + R9 = (9, "$r9"), + R10 = (10, "$r10"), + R11 = (11, "$r11"), + R12 = (12, "$r12"), + R13 = (13, "$r13"), + R14 = (14, "$r14"), + R15 = (15, "$r15"), + R16 = (16, "$r16"), + R17 = (17, "$r17"), + R18 = (18, "$r18"), + R19 = (19, "$r19"), + R20 = (20, "$r20"), + R21 = (21, "$r21"), + R22 = (22, "$r22"), + R23 = (23, "$r23"), + R24 = (24, "$r24"), + R25 = (25, "$r25"), + R26 = (26, "$r26"), + R27 = (27, "$r27"), + R28 = (28, "$r28"), + R29 = (29, "$r29"), + R30 = (30, "$r30"), + R31 = (31, "$r31"), + + F0 = (32, "$f0"), + F1 = (33, "$f1"), + F2 = (34, "$f2"), + F3 = (35, "$f3"), + F4 = (36, "$f4"), + F5 = (37, "$f5"), + F6 = (38, "$f6"), + F7 = (39, "$f7"), + F8 = (40, "$f8"), + F9 = (41, "$f9"), + F10 = (42, "$f10"), + F11 = (43, "$f11"), + F12 = (44, "$f12"), + F13 = (45, "$f13"), + F14 = (46, "$f14"), + F15 = (47, "$f15"), + F16 = (48, "$f16"), + F17 = (49, "$f17"), + F18 = (50, "$f18"), + F19 = (51, "$f19"), + F20 = (52, "$f20"), + F21 = (53, "$f21"), + F22 = (54, "$f22"), + F23 = (55, "$f23"), + F24 = (56, "$f24"), + F25 = (57, "$f25"), + F26 = (58, "$f26"), + F27 = (59, "$f27"), + F28 = (60, "$f28"), + F29 = (61, "$f29"), + F30 = (62, "$f30"), + F31 = (63, "$f31"), + FCC0 = (64, "$fcc0"), + FCC1 = (65, "$fcc1"), + FCC2 = (66, "$fcc2"), + FCC3 = (67, "$fcc3"), + FCC4 = (68, "$fcc4"), + FCC5 = (69, "$fcc5"), + FCC6 = (70, "$fcc6"), + FCC7 = (71, "$fcc7"), +}, +aliases { + ZERO = (0, "$zero"), + RA = (1, "$ra"), + TP = (2, "$tp"), + SP = (3, "$sp"), + A0 = (4, "$a0"), + A1 = (5, "$a1"), + A2 = (6, "$a2"), + A3 = (7, "$a3"), + A4 = (8, "$a4"), + A5 = (9, "$a5"), + A6 = (10, "$a6"), + A7 = (11, "$a7"), + T0 = (12, "$t0"), + T1 = (13, "$t1"), + T2 = (14, "$t2"), + T3 = (15, "$t3"), + T4 = (16, "$t4"), + T5 = (17, "$t5"), + T6 = (18, "$t6"), + T7 = (19, "$t7"), + T8 = (20, "$t8"), + FP = (22, "$fp"), + S0 = (23, "$s0"), + S1 = (24, "$s1"), + S2 = (25, "$s2"), + S3 = (26, "$s3"), + S4 = (27, "$s4"), + S5 = (28, "$s5"), + S6 = (29, "$s6"), + S7 = (30, "$s7"), + S8 = (31, "$s8"), + + FA0 = (32, "$fa0"), + FA1 = (33, "$fa1"), + FA2 = (34, "$fa2"), + FA3 = (35, "$fa3"), + FA4 = (36, "$fa4"), + FA5 = (37, "$fa5"), + FA6 = (38, "$fa6"), + FA7 = (39, "$fa7"), + FT0 = (40, "$ft0"), + FT1 = (41, "$ft1"), + FT2 = (42, "$ft2"), + FT3 = (43, "$ft3"), + FT4 = (44, "$ft4"), + FT5 = (45, "$ft5"), + FT6 = (46, "$ft6"), + FT7 = (47, "$ft7"), + FT8 = (48, "$ft8"), + FT9 = (49, "$ft9"), + FT10 = (50, "$ft10"), + FT11 = (51, "$ft11"), + FT12 = (52, "$ft12"), + FT13 = (53, "$ft13"), + FT14 = (54, "$ft14"), + FT15 = (55, "$ft15"), + FS0 = (56, "$fs0"), + FS1 = (57, "$fs1"), + FS2 = (58, "$fs2"), + FS3 = (59, "$fs3"), + FS4 = (60, "$fs4"), + FS5 = (61, "$fs5"), + FS6 = (62, "$fs6"), + FS7 = (63, "$fs7"), +}); + /// RISC-V architecture specific definitions. /// /// See [RISC-V ELF psABI specification](https://github.com/riscv/riscv-elf-psabi-doc). diff --git a/vendor/gimli/src/lib.rs b/vendor/gimli/src/lib.rs index ed1af9cbd..db30375aa 100644 --- a/vendor/gimli/src/lib.rs +++ b/vendor/gimli/src/lib.rs @@ -26,14 +26,17 @@ #![warn(ellipsis_inclusive_range_patterns)] //#![warn(elided_lifetimes_in_paths)] #![warn(explicit_outlives_requirements)] -// Allow clippy warnings when we aren't building with clippy. -#![allow(unknown_lints)] +// Style. +#![allow(clippy::bool_to_int_with_if)] +#![allow(clippy::collapsible_else_if)] +#![allow(clippy::comparison_chain)] +#![allow(clippy::manual_range_contains)] +#![allow(clippy::needless_late_init)] +#![allow(clippy::too_many_arguments)] // False positives with `fallible_iterator`. #![allow(clippy::should_implement_trait)] -// Many false positives involving `continue`. -#![allow(clippy::never_loop)] -// False positives when block expressions are used inside an assertion. -#![allow(clippy::panic_params)] +// False positives. +#![allow(clippy::derive_partial_eq_without_eq)] #![no_std] #[allow(unused_imports)] 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)); + } } diff --git a/vendor/gimli/src/read/cfi.rs b/vendor/gimli/src/read/cfi.rs index 2e5167349..5e9befac1 100644 --- a/vendor/gimli/src/read/cfi.rs +++ b/vendor/gimli/src/read/cfi.rs @@ -1058,7 +1058,6 @@ where Fde(PartialFrameDescriptionEntry<'bases, Section, R>), } -#[allow(clippy::type_complexity)] fn parse_cfi_entry<'bases, Section, R>( bases: &'bases BaseAddresses, section: &Section, @@ -1617,7 +1616,6 @@ where } impl<R: Reader> FrameDescriptionEntry<R> { - #[allow(clippy::too_many_arguments)] fn parse_rest<Section, F>( offset: R::Offset, length: R::Offset, @@ -1982,7 +1980,7 @@ impl<R: Reader, A: UnwindContextStorage<R>> UnwindContext<R, A> { } let mut table = UnwindTable::new_for_cie(section, bases, self, cie); - while let Some(_) = table.next_row()? {} + while table.next_row()?.is_some() {} self.save_initial_rules()?; Ok(()) @@ -2005,7 +2003,7 @@ impl<R: Reader, A: UnwindContextStorage<R>> UnwindContext<R, A> { } fn save_initial_rules(&mut self) -> Result<()> { - assert_eq!(self.is_initialized, false); + debug_assert!(!self.is_initialized); self.initial_rule = match *self.stack.last().unwrap().registers.rules { // All rules are default (undefined). In this case just synthesize // an undefined rule. @@ -2821,10 +2819,7 @@ pub enum RegisterRule<R: Reader> { impl<R: Reader> RegisterRule<R> { fn is_defined(&self) -> bool { - match *self { - RegisterRule::Undefined => false, - _ => true, - } + !matches!(*self, RegisterRule::Undefined) } } @@ -3394,10 +3389,10 @@ impl Default for Pointer { } } -impl Into<u64> for Pointer { +impl From<Pointer> for u64 { #[inline] - fn into(self) -> u64 { - match self { + fn from(p: Pointer) -> u64 { + match p { Pointer::Direct(p) | Pointer::Indirect(p) => p, } } @@ -3762,8 +3757,6 @@ mod tests { } } - #[allow(clippy::type_complexity)] - #[allow(clippy::needless_pass_by_value)] fn assert_parse_cie<'input, E>( kind: SectionKind<DebugFrame<EndianSlice<'input, E>>>, section: Section, @@ -5118,7 +5111,6 @@ mod tests { assert_eq!(iter.next(), Ok(None)); } - #[allow(clippy::needless_pass_by_value)] fn assert_eval<'a, I>( mut initial_ctx: UnwindContext<EndianSlice<'a, LittleEndian>>, expected_ctx: UnwindContext<EndianSlice<'a, LittleEndian>>, @@ -5598,7 +5590,6 @@ mod tests { #[test] fn test_unwind_table_cie_no_rule() { - #[allow(clippy::identity_op)] let initial_instructions = Section::with_endian(Endian::Little) // The CFA is -12 from register 4. .D8(constants::DW_CFA_def_cfa_sf.0) @@ -5671,7 +5662,6 @@ mod tests { #[test] fn test_unwind_table_cie_single_rule() { - #[allow(clippy::identity_op)] let initial_instructions = Section::with_endian(Endian::Little) // The CFA is -12 from register 4. .D8(constants::DW_CFA_def_cfa_sf.0) @@ -5747,7 +5737,6 @@ mod tests { #[test] fn test_unwind_table_next_row() { - #[allow(clippy::identity_op)] let initial_instructions = Section::with_endian(Endian::Little) // The CFA is -12 from register 4. .D8(constants::DW_CFA_def_cfa_sf.0) diff --git a/vendor/gimli/src/read/dwarf.rs b/vendor/gimli/src/read/dwarf.rs index b63526941..cce364c2b 100644 --- a/vendor/gimli/src/read/dwarf.rs +++ b/vendor/gimli/src/read/dwarf.rs @@ -9,11 +9,11 @@ use crate::common::{ }; use crate::constants; use crate::read::{ - Abbreviations, AttributeValue, DebugAbbrev, DebugAddr, DebugAranges, DebugCuIndex, DebugInfo, - DebugInfoUnitHeadersIter, DebugLine, DebugLineStr, DebugLoc, DebugLocLists, DebugRngLists, - DebugStr, DebugStrOffsets, DebugTuIndex, DebugTypes, DebugTypesUnitHeadersIter, - DebuggingInformationEntry, EntriesCursor, EntriesRaw, EntriesTree, Error, - IncompleteLineProgram, LocListIter, LocationLists, Range, RangeLists, RawLocListIter, + Abbreviations, AbbreviationsCache, AttributeValue, DebugAbbrev, DebugAddr, DebugAranges, + DebugCuIndex, DebugInfo, DebugInfoUnitHeadersIter, DebugLine, DebugLineStr, DebugLoc, + DebugLocLists, DebugRngLists, DebugStr, DebugStrOffsets, DebugTuIndex, DebugTypes, + DebugTypesUnitHeadersIter, DebuggingInformationEntry, EntriesCursor, EntriesRaw, EntriesTree, + Error, IncompleteLineProgram, LocListIter, LocationLists, Range, RangeLists, RawLocListIter, RawRngListIter, Reader, ReaderOffset, ReaderOffsetId, Result, RngListIter, Section, UnitHeader, UnitIndex, UnitIndexSectionIterator, UnitOffset, UnitType, }; @@ -59,6 +59,9 @@ pub struct Dwarf<R> { /// The DWARF sections for a supplementary object file. pub sup: Option<Arc<Dwarf<R>>>, + + /// A cache of previously parsed abbreviations for units in this file. + pub abbreviations_cache: AbbreviationsCache, } impl<T> Dwarf<T> { @@ -96,6 +99,7 @@ impl<T> Dwarf<T> { ranges: RangeLists::new(debug_ranges, debug_rnglists), file_type: DwarfFileType::Main, sup: None, + abbreviations_cache: AbbreviationsCache::new(), }) } @@ -157,6 +161,7 @@ impl<T> Dwarf<T> { ranges: self.ranges.borrow(&mut borrow), file_type: self.file_type, sup: self.sup().map(|sup| Arc::new(sup.borrow(borrow))), + abbreviations_cache: AbbreviationsCache::new(), } } @@ -192,10 +197,10 @@ impl<R: Reader> Dwarf<R> { } /// Parse the abbreviations for a compilation unit. - // TODO: provide caching of abbreviations #[inline] - pub fn abbreviations(&self, unit: &UnitHeader<R>) -> Result<Abbreviations> { - unit.abbreviations(&self.debug_abbrev) + pub fn abbreviations(&self, unit: &UnitHeader<R>) -> Result<Arc<Abbreviations>> { + self.abbreviations_cache + .get(&self.debug_abbrev, unit.debug_abbrev_offset()) } /// Return the string offset at the given index. @@ -783,6 +788,7 @@ impl<R: Reader> DwarfPackage<R> { ranges: RangeLists::new(debug_ranges, debug_rnglists), file_type: DwarfFileType::Dwo, sup: None, + abbreviations_cache: AbbreviationsCache::new(), }) } } @@ -799,7 +805,7 @@ where pub header: UnitHeader<R, Offset>, /// The parsed abbreviations for the unit. - pub abbreviations: Abbreviations, + pub abbreviations: Arc<Abbreviations>, /// The `DW_AT_name` attribute of the unit. pub name: Option<R>, @@ -833,7 +839,7 @@ impl<R: Reader> Unit<R> { /// Construct a new `Unit` from the given unit header. #[inline] pub fn new(dwarf: &Dwarf<R>, header: UnitHeader<R>) -> Result<Self> { - let abbreviations = header.abbreviations(&dwarf.debug_abbrev)?; + let abbreviations = dwarf.abbreviations(&header)?; let mut unit = Unit { abbreviations, name: None, diff --git a/vendor/gimli/src/read/endian_slice.rs b/vendor/gimli/src/read/endian_slice.rs index 05262cdec..d0fd67c0b 100644 --- a/vendor/gimli/src/read/endian_slice.rs +++ b/vendor/gimli/src/read/endian_slice.rs @@ -197,12 +197,12 @@ where } } -impl<'input, Endian> Into<&'input [u8]> for EndianSlice<'input, Endian> +impl<'input, Endian> From<EndianSlice<'input, Endian>> for &'input [u8] where Endian: Endianity, { - fn into(self) -> &'input [u8] { - self.slice + fn from(endian_slice: EndianSlice<'input, Endian>) -> &'input [u8] { + endian_slice.slice } } diff --git a/vendor/gimli/src/read/lazy.rs b/vendor/gimli/src/read/lazy.rs new file mode 100644 index 000000000..6138735c8 --- /dev/null +++ b/vendor/gimli/src/read/lazy.rs @@ -0,0 +1,116 @@ +pub(crate) use imp::*; + +#[cfg(not(feature = "std"))] +mod imp { + use alloc::sync::Arc; + use core::sync::atomic::{AtomicPtr, Ordering}; + use core::{mem, ptr}; + + #[derive(Debug, Default)] + pub(crate) struct LazyArc<T> { + // Only written once with a value obtained from `Arc<T>::into_raw`. + // This holds a ref count for the `Arc`, so it is always safe to + // clone the `Arc` given a reference to the `LazyArc`. + value: AtomicPtr<T>, + } + + impl<T> Drop for LazyArc<T> { + fn drop(&mut self) { + let value_ptr = self.value.load(Ordering::Acquire); + if !value_ptr.is_null() { + // SAFETY: all writes to `self.value` are pointers obtained from `Arc::into_raw`. + drop(unsafe { Arc::from_raw(value_ptr) }); + } + } + } + + impl<T> LazyArc<T> { + pub(crate) fn get<E, F: FnOnce() -> Result<T, E>>(&self, f: F) -> Result<Arc<T>, E> { + // Clone an `Arc` given a pointer obtained from `Arc::into_raw`. + // SAFETY: `value_ptr` must be a valid pointer obtained from `Arc<T>::into_raw`. + unsafe fn clone_arc_ptr<T>(value_ptr: *const T) -> Arc<T> { + let value = Arc::from_raw(value_ptr); + let clone = Arc::clone(&value); + mem::forget(value); + clone + } + + // Return the existing value if already computed. + // `Ordering::Acquire` is needed so that the content of the loaded `Arc` is + // visible to this thread. + let value_ptr = self.value.load(Ordering::Acquire); + if !value_ptr.is_null() { + // SAFETY: all writes to `self.value` are pointers obtained from `Arc::into_raw`. + return Ok(unsafe { clone_arc_ptr(value_ptr) }); + } + + // Race to compute and set the value. + let value = f().map(Arc::new)?; + let value_ptr = Arc::into_raw(value); + match self.value.compare_exchange( + ptr::null_mut(), + value_ptr as *mut T, + // Success: `Ordering::Release` is needed so that the content of the stored `Arc` + // is visible to other threads. No ordering is required for the null ptr that is + // loaded, but older rust versions (< 1.64) require that its ordering must not + // be weaker than the failure ordering, so we use `Ordering::AcqRel`. + Ordering::AcqRel, + // Failure: `Ordering::Acquire` is needed so that the content of the loaded `Arc` + // is visible to this thread. + Ordering::Acquire, + ) { + Ok(_) => { + // Return the value we computed. + // SAFETY: `value_ptr` was obtained from `Arc::into_raw`. + Ok(unsafe { clone_arc_ptr(value_ptr) }) + } + Err(existing_value_ptr) => { + // We lost the race, drop unneeded `value_ptr`. + // SAFETY: `value_ptr` was obtained from `Arc::into_raw`. + drop(unsafe { Arc::from_raw(value_ptr) }); + // Return the existing value. + // SAFETY: all writes to `self.value` are pointers obtained from `Arc::into_raw`. + Ok(unsafe { clone_arc_ptr(existing_value_ptr) }) + } + } + } + } +} + +#[cfg(feature = "std")] +mod imp { + use std::sync::{Arc, Mutex}; + + #[derive(Debug, Default)] + pub(crate) struct LazyArc<T> { + value: Mutex<Option<Arc<T>>>, + } + + impl<T> LazyArc<T> { + pub(crate) fn get<E, F: FnOnce() -> Result<T, E>>(&self, f: F) -> Result<Arc<T>, E> { + let mut lock = self.value.lock().unwrap(); + if let Some(value) = &*lock { + return Ok(value.clone()); + } + let value = f().map(Arc::new)?; + *lock = Some(value.clone()); + Ok(value) + } + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn lazy_arc() { + let lazy = LazyArc::default(); + let value = lazy.get(|| Err(())); + assert_eq!(value, Err(())); + let value = lazy.get(|| Ok::<i32, ()>(3)).unwrap(); + assert_eq!(*value, 3); + let value = lazy.get(|| Err(())).unwrap(); + assert_eq!(*value, 3); + } +} diff --git a/vendor/gimli/src/read/line.rs b/vendor/gimli/src/read/line.rs index 0e7380bb9..f7f44b2b5 100644 --- a/vendor/gimli/src/read/line.rs +++ b/vendor/gimli/src/read/line.rs @@ -198,7 +198,6 @@ where R: Reader<Offset = Offset>, Offset: ReaderOffset, { - #[allow(clippy::new_ret_no_self)] fn new(program: IncompleteLineProgram<R, Offset>) -> OneShotLineRows<R, Offset> { let row = LineRow::new(program.header()); let instructions = LineInstructions { @@ -606,7 +605,6 @@ impl<R: Reader> LineInstructions<R> { /// /// Unfortunately, the `header` parameter means that this cannot be a /// `FallibleIterator`. - #[allow(clippy::inline_always)] #[inline(always)] pub fn next_instruction( &mut self, diff --git a/vendor/gimli/src/read/loclists.rs b/vendor/gimli/src/read/loclists.rs index 3902c181b..5cba675d2 100644 --- a/vendor/gimli/src/read/loclists.rs +++ b/vendor/gimli/src/read/loclists.rs @@ -233,7 +233,7 @@ impl<R: Reader> LocationLists<R> { let (mut input, format) = if unit_encoding.version <= 4 { (self.debug_loc.section.clone(), LocListsFormat::Bare) } else { - (self.debug_loclists.section.clone(), LocListsFormat::LLE) + (self.debug_loclists.section.clone(), LocListsFormat::Lle) }; input.skip(offset.0)?; Ok(RawLocListIter::new(input, unit_encoding, format)) @@ -259,7 +259,7 @@ impl<R: Reader> LocationLists<R> { Ok(RawLocListIter::new( input, unit_encoding, - LocListsFormat::LLE, + LocListsFormat::Lle, )) } @@ -300,7 +300,7 @@ enum LocListsFormat { Bare, /// The DW_LLE encoded range list format used in DWARF 5 and the non-standard GNU /// split dwarf extension. - LLE, + Lle, } /// A raw iterator over a location list. @@ -402,10 +402,10 @@ fn parse_data<R: Reader>(input: &mut R, encoding: Encoding) -> Result<Expression impl<R: Reader> RawLocListEntry<R> { /// Parse a location list entry from `.debug_loclists` fn parse(input: &mut R, encoding: Encoding, format: LocListsFormat) -> Result<Option<Self>> { - match format { + Ok(match format { LocListsFormat::Bare => { let range = RawRange::parse(input, encoding.address_size)?; - return Ok(if range.is_end() { + if range.is_end() { None } else if range.is_base_address(encoding.address_size) { Some(RawLocListEntry::BaseAddress { addr: range.end }) @@ -417,9 +417,9 @@ impl<R: Reader> RawLocListEntry<R> { end: range.end, data, }) - }); + } } - LocListsFormat::LLE => Ok(match constants::DwLle(input.read_u8()?) { + LocListsFormat::Lle => match constants::DwLle(input.read_u8()?) { constants::DW_LLE_end_of_list => None, constants::DW_LLE_base_addressx => Some(RawLocListEntry::BaseAddressx { addr: DebugAddrIndex(input.read_uleb128().and_then(R::Offset::from_u64)?), @@ -463,8 +463,8 @@ impl<R: Reader> RawLocListEntry<R> { _ => { return Err(Error::InvalidAddressRange); } - }), - } + }, + }) } } @@ -552,63 +552,96 @@ impl<R: Reader> LocListIter<R> { None => return Ok(None), }; - let (range, data) = match raw_loc { - RawLocListEntry::BaseAddress { addr } => { - self.base_address = addr; - continue; - } - RawLocListEntry::BaseAddressx { addr } => { - self.base_address = self.get_address(addr)?; - continue; - } - RawLocListEntry::StartxEndx { begin, end, data } => { - let begin = self.get_address(begin)?; - let end = self.get_address(end)?; - (Range { begin, end }, data) - } - RawLocListEntry::StartxLength { - begin, - length, - data, - } => { - let begin = self.get_address(begin)?; - let end = begin + length; - (Range { begin, end }, data) - } - RawLocListEntry::DefaultLocation { data } => ( - Range { - begin: 0, - end: u64::max_value(), - }, - data, - ), - RawLocListEntry::AddressOrOffsetPair { begin, end, data } - | RawLocListEntry::OffsetPair { begin, end, data } => { - let mut range = Range { begin, end }; - range.add_base_address(self.base_address, self.raw.encoding.address_size); - (range, data) - } - RawLocListEntry::StartEnd { begin, end, data } => (Range { begin, end }, data), - RawLocListEntry::StartLength { - begin, - length, - data, - } => ( - Range { - begin, - end: begin + length, - }, - data, - ), - }; + let loc = self.convert_raw(raw_loc)?; + if loc.is_some() { + return Ok(loc); + } + } + } - if range.begin > range.end { - self.raw.input.empty(); - return Err(Error::InvalidLocationAddressRange); + /// Return the next raw location. + /// + /// The raw location should be passed to `convert_raw`. + #[doc(hidden)] + pub fn next_raw(&mut self) -> Result<Option<RawLocListEntry<R>>> { + self.raw.next() + } + + /// Convert a raw location into a location, and update the state of the iterator. + /// + /// The raw location should have been obtained from `next_raw`. + #[doc(hidden)] + pub fn convert_raw( + &mut self, + raw_loc: RawLocListEntry<R>, + ) -> Result<Option<LocationListEntry<R>>> { + let mask = !0 >> (64 - self.raw.encoding.address_size * 8); + let tombstone = if self.raw.encoding.version <= 4 { + mask - 1 + } else { + mask + }; + + let (range, data) = match raw_loc { + RawLocListEntry::BaseAddress { addr } => { + self.base_address = addr; + return Ok(None); + } + RawLocListEntry::BaseAddressx { addr } => { + self.base_address = self.get_address(addr)?; + return Ok(None); + } + RawLocListEntry::StartxEndx { begin, end, data } => { + let begin = self.get_address(begin)?; + let end = self.get_address(end)?; + (Range { begin, end }, data) + } + RawLocListEntry::StartxLength { + begin, + length, + data, + } => { + let begin = self.get_address(begin)?; + let end = begin.wrapping_add(length) & mask; + (Range { begin, end }, data) + } + RawLocListEntry::DefaultLocation { data } => ( + Range { + begin: 0, + end: u64::max_value(), + }, + data, + ), + RawLocListEntry::AddressOrOffsetPair { begin, end, data } + | RawLocListEntry::OffsetPair { begin, end, data } => { + if self.base_address == tombstone { + return Ok(None); + } + let mut range = Range { begin, end }; + range.add_base_address(self.base_address, self.raw.encoding.address_size); + (range, data) + } + RawLocListEntry::StartEnd { begin, end, data } => (Range { begin, end }, data), + RawLocListEntry::StartLength { + begin, + length, + data, + } => { + let end = begin.wrapping_add(length) & mask; + (Range { begin, end }, data) } + }; - return Ok(Some(LocationListEntry { range, data })); + if range.begin == tombstone { + return Ok(None); } + + if range.begin > range.end { + self.raw.input.empty(); + return Err(Error::InvalidLocationAddressRange); + } + + Ok(Some(LocationListEntry { range, data })) } } @@ -643,6 +676,7 @@ mod tests { #[test] fn test_loclists_32() { + let tombstone = !0u32; let encoding = Encoding { format: Format::Dwarf32, version: 5, @@ -653,7 +687,9 @@ mod tests { .L32(0x0300_0000) .L32(0x0301_0300) .L32(0x0301_0400) - .L32(0x0301_0500); + .L32(0x0301_0500) + .L32(tombstone) + .L32(0x0301_0600); let buf = section.get_contents().unwrap(); let debug_addr = &DebugAddr::from(EndianSlice::new(&buf, LittleEndian)); let debug_addr_base = DebugAddrBase(0); @@ -697,6 +733,25 @@ mod tests { .L8(2).uleb(1).uleb(2).uleb(4).L32(12) // A StartxLength .L8(3).uleb(3).uleb(0x100).uleb(4).L32(13) + + // Tombstone entries, all of which should be ignored. + // A BaseAddressx that is a tombstone. + .L8(1).uleb(4) + .L8(4).uleb(0x11100).uleb(0x11200).uleb(4).L32(20) + // A BaseAddress that is a tombstone. + .L8(6).L32(tombstone) + .L8(4).uleb(0x11300).uleb(0x11400).uleb(4).L32(21) + // A StartxEndx that is a tombstone. + .L8(2).uleb(4).uleb(5).uleb(4).L32(22) + // A StartxLength that is a tombstone. + .L8(3).uleb(4).uleb(0x100).uleb(4).L32(23) + // A StartEnd that is a tombstone. + .L8(7).L32(tombstone).L32(0x201_1500).uleb(4).L32(24) + // A StartLength that is a tombstone. + .L8(8).L32(tombstone).uleb(0x100).uleb(4).L32(25) + // A StartEnd (not ignored) + .L8(7).L32(0x201_1600).L32(0x201_1700).uleb(4).L32(26) + // A range end. .L8(0) // Some extra data. @@ -854,6 +909,18 @@ mod tests { })) ); + // A StartEnd location following the tombstones + assert_eq!( + locations.next(), + Ok(Some(LocationListEntry { + range: Range { + begin: 0x0201_1600, + end: 0x0201_1700, + }, + data: Expression(EndianSlice::new(&[26, 0, 0, 0], LittleEndian)), + })) + ); + // A location list end. assert_eq!(locations.next(), Ok(None)); @@ -872,6 +939,7 @@ mod tests { #[test] fn test_loclists_64() { + let tombstone = !0u64; let encoding = Encoding { format: Format::Dwarf64, version: 5, @@ -882,7 +950,9 @@ mod tests { .L64(0x0300_0000) .L64(0x0301_0300) .L64(0x0301_0400) - .L64(0x0301_0500); + .L64(0x0301_0500) + .L64(tombstone) + .L64(0x0301_0600); let buf = section.get_contents().unwrap(); let debug_addr = &DebugAddr::from(EndianSlice::new(&buf, LittleEndian)); let debug_addr_base = DebugAddrBase(0); @@ -927,6 +997,25 @@ mod tests { .L8(2).uleb(1).uleb(2).uleb(4).L32(12) // A StartxLength .L8(3).uleb(3).uleb(0x100).uleb(4).L32(13) + + // Tombstone entries, all of which should be ignored. + // A BaseAddressx that is a tombstone. + .L8(1).uleb(4) + .L8(4).uleb(0x11100).uleb(0x11200).uleb(4).L32(20) + // A BaseAddress that is a tombstone. + .L8(6).L64(tombstone) + .L8(4).uleb(0x11300).uleb(0x11400).uleb(4).L32(21) + // A StartxEndx that is a tombstone. + .L8(2).uleb(4).uleb(5).uleb(4).L32(22) + // A StartxLength that is a tombstone. + .L8(3).uleb(4).uleb(0x100).uleb(4).L32(23) + // A StartEnd that is a tombstone. + .L8(7).L64(tombstone).L64(0x201_1500).uleb(4).L32(24) + // A StartLength that is a tombstone. + .L8(8).L64(tombstone).uleb(0x100).uleb(4).L32(25) + // A StartEnd (not ignored) + .L8(7).L64(0x201_1600).L64(0x201_1700).uleb(4).L32(26) + // A range end. .L8(0) // Some extra data. @@ -1084,6 +1173,18 @@ mod tests { })) ); + // A StartEnd location following the tombstones + assert_eq!( + locations.next(), + Ok(Some(LocationListEntry { + range: Range { + begin: 0x0201_1600, + end: 0x0201_1700, + }, + data: Expression(EndianSlice::new(&[26, 0, 0, 0], LittleEndian)), + })) + ); + // A location list end. assert_eq!(locations.next(), Ok(None)); @@ -1102,6 +1203,7 @@ mod tests { #[test] fn test_location_list_32() { + let tombstone = !0u32 - 1; let start = Label::new(); let first = Label::new(); #[rustfmt::skip] @@ -1123,6 +1225,11 @@ mod tests { // A location range that ends at -1. .L32(0xffff_ffff).L32(0x0000_0000) .L32(0).L32(0xffff_ffff).L16(4).L32(7) + // A normal location with tombstone. + .L32(tombstone).L32(tombstone).L16(4).L32(8) + // A base address selection with tombstone followed by a normal location. + .L32(0xffff_ffff).L32(tombstone) + .L32(0x10a00).L32(0x10b00).L16(4).L32(9) // A location list end. .L32(0).L32(0) // Some extra data. @@ -1232,6 +1339,7 @@ mod tests { #[test] fn test_location_list_64() { + let tombstone = !0u64 - 1; let start = Label::new(); let first = Label::new(); #[rustfmt::skip] @@ -1253,6 +1361,11 @@ mod tests { // A location range that ends at -1. .L64(0xffff_ffff_ffff_ffff).L64(0x0000_0000) .L64(0).L64(0xffff_ffff_ffff_ffff).L16(4).L32(7) + // A normal location with tombstone. + .L64(tombstone).L64(tombstone).L16(4).L32(8) + // A base address selection with tombstone followed by a normal location. + .L64(0xffff_ffff_ffff_ffff).L64(tombstone) + .L64(0x10a00).L64(0x10b00).L16(4).L32(9) // A location list end. .L64(0).L64(0) // Some extra data. diff --git a/vendor/gimli/src/read/mod.rs b/vendor/gimli/src/read/mod.rs index 3110957c2..b2828d5f9 100644 --- a/vendor/gimli/src/read/mod.rs +++ b/vendor/gimli/src/read/mod.rs @@ -214,6 +214,9 @@ mod index; pub use self::index::*; #[cfg(feature = "read")] +mod lazy; + +#[cfg(feature = "read")] mod line; #[cfg(feature = "read")] pub use self::line::*; diff --git a/vendor/gimli/src/read/op.rs b/vendor/gimli/src/read/op.rs index 88ea20297..670d1ad21 100644 --- a/vendor/gimli/src/read/op.rs +++ b/vendor/gimli/src/read/op.rs @@ -346,10 +346,7 @@ where { /// Return true if the piece is empty. pub fn is_empty(&self) -> bool { - match *self { - Location::Empty => true, - _ => false, - } + matches!(*self, Location::Empty) } } @@ -1225,7 +1222,6 @@ impl<R: Reader, S: EvaluationStorage<R>> Evaluation<R, S> { self.stack.try_push(value).map_err(|_| Error::StackFull) } - #[allow(clippy::cyclomatic_complexity)] fn evaluate_one_operation(&mut self) -> Result<OperationEvaluationResult<R>> { let operation = Operation::parse(&mut self.pc, self.encoding)?; @@ -2889,7 +2885,6 @@ mod tests { result } - #[allow(clippy::too_many_arguments)] fn check_eval_with_args<F>( program: &[AssemblerEntry], expect: Result<&[Piece<EndianSlice<LittleEndian>>]>, diff --git a/vendor/gimli/src/read/rnglists.rs b/vendor/gimli/src/read/rnglists.rs index d8d49042f..12e3e04ee 100644 --- a/vendor/gimli/src/read/rnglists.rs +++ b/vendor/gimli/src/read/rnglists.rs @@ -232,7 +232,7 @@ impl<R: Reader> RangeLists<R> { let (mut input, format) = if unit_encoding.version <= 4 { (self.debug_ranges.section.clone(), RangeListsFormat::Bare) } else { - (self.debug_rnglists.section.clone(), RangeListsFormat::RLE) + (self.debug_rnglists.section.clone(), RangeListsFormat::Rle) }; input.skip(offset.0)?; Ok(RawRngListIter::new(input, unit_encoding, format)) @@ -277,7 +277,7 @@ enum RangeListsFormat { /// The bare range list format used before DWARF 5. Bare, /// The DW_RLE encoded range list format used in DWARF 5. - RLE, + Rle, } /// A raw iterator over an address range list. @@ -355,10 +355,10 @@ impl<T: ReaderOffset> RawRngListEntry<T> { encoding: Encoding, format: RangeListsFormat, ) -> Result<Option<Self>> { - match format { + Ok(match format { RangeListsFormat::Bare => { let range = RawRange::parse(input, encoding.address_size)?; - return Ok(if range.is_end() { + if range.is_end() { None } else if range.is_base_address(encoding.address_size) { Some(RawRngListEntry::BaseAddress { addr: range.end }) @@ -367,9 +367,9 @@ impl<T: ReaderOffset> RawRngListEntry<T> { begin: range.begin, end: range.end, }) - }); + } } - RangeListsFormat::RLE => Ok(match constants::DwRle(input.read_u8()?) { + RangeListsFormat::Rle => match constants::DwRle(input.read_u8()?) { constants::DW_RLE_end_of_list => None, constants::DW_RLE_base_addressx => Some(RawRngListEntry::BaseAddressx { addr: DebugAddrIndex(input.read_uleb128().and_then(R::Offset::from_u64)?), @@ -400,8 +400,8 @@ impl<T: ReaderOffset> RawRngListEntry<T> { _ => { return Err(Error::InvalidAddressRange); } - }), - } + }, + }) } } @@ -489,45 +489,78 @@ impl<R: Reader> RngListIter<R> { None => return Ok(None), }; - let range = match raw_range { - RawRngListEntry::BaseAddress { addr } => { - self.base_address = addr; - continue; - } - RawRngListEntry::BaseAddressx { addr } => { - self.base_address = self.get_address(addr)?; - continue; - } - RawRngListEntry::StartxEndx { begin, end } => { - let begin = self.get_address(begin)?; - let end = self.get_address(end)?; - Range { begin, end } - } - RawRngListEntry::StartxLength { begin, length } => { - let begin = self.get_address(begin)?; - let end = begin + length; - Range { begin, end } - } - RawRngListEntry::AddressOrOffsetPair { begin, end } - | RawRngListEntry::OffsetPair { begin, end } => { - let mut range = Range { begin, end }; - range.add_base_address(self.base_address, self.raw.encoding.address_size); - range - } - RawRngListEntry::StartEnd { begin, end } => Range { begin, end }, - RawRngListEntry::StartLength { begin, length } => Range { - begin, - end: begin + length, - }, - }; + let range = self.convert_raw(raw_range)?; + if range.is_some() { + return Ok(range); + } + } + } - if range.begin > range.end { - self.raw.input.empty(); - return Err(Error::InvalidAddressRange); + /// Return the next raw range. + /// + /// The raw range should be passed to `convert_range`. + #[doc(hidden)] + pub fn next_raw(&mut self) -> Result<Option<RawRngListEntry<R::Offset>>> { + self.raw.next() + } + + /// Convert a raw range into a range, and update the state of the iterator. + /// + /// The raw range should have been obtained from `next_raw`. + #[doc(hidden)] + pub fn convert_raw(&mut self, raw_range: RawRngListEntry<R::Offset>) -> Result<Option<Range>> { + let mask = !0 >> (64 - self.raw.encoding.address_size * 8); + let tombstone = if self.raw.encoding.version <= 4 { + mask - 1 + } else { + mask + }; + + let range = match raw_range { + RawRngListEntry::BaseAddress { addr } => { + self.base_address = addr; + return Ok(None); + } + RawRngListEntry::BaseAddressx { addr } => { + self.base_address = self.get_address(addr)?; + return Ok(None); + } + RawRngListEntry::StartxEndx { begin, end } => { + let begin = self.get_address(begin)?; + let end = self.get_address(end)?; + Range { begin, end } + } + RawRngListEntry::StartxLength { begin, length } => { + let begin = self.get_address(begin)?; + let end = begin.wrapping_add(length) & mask; + Range { begin, end } + } + RawRngListEntry::AddressOrOffsetPair { begin, end } + | RawRngListEntry::OffsetPair { begin, end } => { + if self.base_address == tombstone { + return Ok(None); + } + let mut range = Range { begin, end }; + range.add_base_address(self.base_address, self.raw.encoding.address_size); + range } + RawRngListEntry::StartEnd { begin, end } => Range { begin, end }, + RawRngListEntry::StartLength { begin, length } => { + let end = begin.wrapping_add(length) & mask; + Range { begin, end } + } + }; + + if range.begin == tombstone { + return Ok(None); + } - return Ok(Some(range)); + if range.begin > range.end { + self.raw.input.empty(); + return Err(Error::InvalidAddressRange); } + + Ok(Some(range)) } } @@ -553,8 +586,6 @@ pub(crate) struct RawRange { impl RawRange { /// Check if this is a range end entry. - /// - /// This will only occur for raw ranges. #[inline] pub fn is_end(&self) -> bool { self.begin == 0 && self.end == 0 @@ -563,14 +594,13 @@ impl RawRange { /// Check if this is a base address selection entry. /// /// A base address selection entry changes the base address that subsequent - /// range entries are relative to. This will only occur for raw ranges. + /// range entries are relative to. #[inline] pub fn is_base_address(&self, address_size: u8) -> bool { self.begin == !0 >> (64 - address_size * 8) } /// Parse an address range entry from `.debug_ranges` or `.debug_loc`. - #[doc(hidden)] #[inline] pub fn parse<R: Reader>(input: &mut R, address_size: u8) -> Result<RawRange> { let begin = input.read_address(address_size)?; @@ -610,6 +640,7 @@ mod tests { #[test] fn test_rnglists_32() { + let tombstone = !0u32; let encoding = Encoding { format: Format::Dwarf32, version: 5, @@ -619,7 +650,9 @@ mod tests { .L32(0x0300_0000) .L32(0x0301_0300) .L32(0x0301_0400) - .L32(0x0301_0500); + .L32(0x0301_0500) + .L32(tombstone) + .L32(0x0301_0600); let buf = section.get_contents().unwrap(); let debug_addr = &DebugAddr::from(EndianSlice::new(&buf, LittleEndian)); let debug_addr_base = DebugAddrBase(0); @@ -637,7 +670,7 @@ mod tests { .L8(0) .L32(0) .mark(&first) - // OffsetPair + // An OffsetPair using the unit base address. .L8(4).uleb(0x10200).uleb(0x10300) // A base address selection followed by an OffsetPair. .L8(5).L32(0x0200_0000) @@ -663,6 +696,25 @@ mod tests { .L8(2).uleb(1).uleb(2) // A StartxLength .L8(3).uleb(3).uleb(0x100) + + // Tombstone entries, all of which should be ignored. + // A BaseAddressx that is a tombstone. + .L8(1).uleb(4) + .L8(4).uleb(0x11100).uleb(0x11200) + // A BaseAddress that is a tombstone. + .L8(5).L32(tombstone) + .L8(4).uleb(0x11300).uleb(0x11400) + // A StartxEndx that is a tombstone. + .L8(2).uleb(4).uleb(5) + // A StartxLength that is a tombstone. + .L8(3).uleb(4).uleb(0x100) + // A StartEnd that is a tombstone. + .L8(6).L32(tombstone).L32(0x201_1500) + // A StartLength that is a tombstone. + .L8(7).L32(tombstone).uleb(0x100) + // A StartEnd (not ignored) + .L8(6).L32(0x201_1600).L32(0x201_1700) + // A range end. .L8(0) // Some extra data. @@ -784,6 +836,15 @@ mod tests { })) ); + // A StartEnd range following the tombstones + assert_eq!( + ranges.next(), + Ok(Some(Range { + begin: 0x0201_1600, + end: 0x0201_1700, + })) + ); + // A range end. assert_eq!(ranges.next(), Ok(None)); @@ -802,6 +863,7 @@ mod tests { #[test] fn test_rnglists_64() { + let tombstone = !0u64; let encoding = Encoding { format: Format::Dwarf64, version: 5, @@ -811,7 +873,9 @@ mod tests { .L64(0x0300_0000) .L64(0x0301_0300) .L64(0x0301_0400) - .L64(0x0301_0500); + .L64(0x0301_0500) + .L64(tombstone) + .L64(0x0301_0600); let buf = section.get_contents().unwrap(); let debug_addr = &DebugAddr::from(EndianSlice::new(&buf, LittleEndian)); let debug_addr_base = DebugAddrBase(0); @@ -830,7 +894,7 @@ mod tests { .L8(0) .L32(0) .mark(&first) - // OffsetPair + // An OffsetPair using the unit base address. .L8(4).uleb(0x10200).uleb(0x10300) // A base address selection followed by an OffsetPair. .L8(5).L64(0x0200_0000) @@ -856,6 +920,25 @@ mod tests { .L8(2).uleb(1).uleb(2) // A StartxLength .L8(3).uleb(3).uleb(0x100) + + // Tombstone entries, all of which should be ignored. + // A BaseAddressx that is a tombstone. + .L8(1).uleb(4) + .L8(4).uleb(0x11100).uleb(0x11200) + // A BaseAddress that is a tombstone. + .L8(5).L64(tombstone) + .L8(4).uleb(0x11300).uleb(0x11400) + // A StartxEndx that is a tombstone. + .L8(2).uleb(4).uleb(5) + // A StartxLength that is a tombstone. + .L8(3).uleb(4).uleb(0x100) + // A StartEnd that is a tombstone. + .L8(6).L64(tombstone).L64(0x201_1500) + // A StartLength that is a tombstone. + .L8(7).L64(tombstone).uleb(0x100) + // A StartEnd (not ignored) + .L8(6).L64(0x201_1600).L64(0x201_1700) + // A range end. .L8(0) // Some extra data. @@ -977,6 +1060,15 @@ mod tests { })) ); + // A StartEnd range following the tombstones + assert_eq!( + ranges.next(), + Ok(Some(Range { + begin: 0x0201_1600, + end: 0x0201_1700, + })) + ); + // A range end. assert_eq!(ranges.next(), Ok(None)); @@ -1027,6 +1119,7 @@ mod tests { #[test] fn test_ranges_32() { + let tombstone = !0u32 - 1; let start = Label::new(); let first = Label::new(); #[rustfmt::skip] @@ -1048,6 +1141,11 @@ mod tests { // A range that ends at -1. .L32(0xffff_ffff).L32(0x0000_0000) .L32(0).L32(0xffff_ffff) + // A normal range with tombstone. + .L32(tombstone).L32(tombstone) + // A base address selection with tombstone followed by a normal range. + .L32(0xffff_ffff).L32(tombstone) + .L32(0x10a00).L32(0x10b00) // A range end. .L32(0).L32(0) // Some extra data. @@ -1139,6 +1237,7 @@ mod tests { #[test] fn test_ranges_64() { + let tombstone = !0u64 - 1; let start = Label::new(); let first = Label::new(); #[rustfmt::skip] @@ -1160,6 +1259,11 @@ mod tests { // A range that ends at -1. .L64(0xffff_ffff_ffff_ffff).L64(0x0000_0000) .L64(0).L64(0xffff_ffff_ffff_ffff) + // A normal range with tombstone. + .L64(tombstone).L64(tombstone) + // A base address selection with tombstone followed by a normal range. + .L64(0xffff_ffff_ffff_ffff).L64(tombstone) + .L64(0x10a00).L64(0x10b00) // A range end. .L64(0).L64(0) // Some extra data. diff --git a/vendor/gimli/src/read/unit.rs b/vendor/gimli/src/read/unit.rs index 670e55efd..672435330 100644 --- a/vendor/gimli/src/read/unit.rs +++ b/vendor/gimli/src/read/unit.rs @@ -883,7 +883,6 @@ where } /// Return the input buffer after the last attribute. - #[allow(clippy::inline_always)] #[inline(always)] fn after_attrs(&self) -> Result<R> { if let Some(attrs_len) = self.attrs_len.get() { @@ -892,7 +891,7 @@ where Ok(input) } else { let mut attrs = self.attrs(); - while let Some(_) = attrs.next()? {} + while attrs.next()?.is_some() {} Ok(attrs.input) } } @@ -912,7 +911,6 @@ where } /// Parse an entry. Returns `Ok(None)` for null entries. - #[allow(clippy::inline_always)] #[inline(always)] fn parse( input: &mut R, @@ -1143,8 +1141,6 @@ impl<R: Reader> Attribute<R> { /// name. /// /// See "Table 7.5: Attribute encodings" and "Table 7.6: Attribute form encodings". - #[allow(clippy::cyclomatic_complexity)] - #[allow(clippy::match_same_arms)] pub fn value(&self) -> AttributeValue<R> { // Table 7.5 shows the possible attribute classes for each name. // Table 7.6 shows the possible attribute classes for each form. @@ -1980,7 +1976,7 @@ fn allow_section_offset(name: constants::DwAt, version: u16) -> bool { } } -pub(crate) fn parse_attribute<'unit, R: Reader>( +pub(crate) fn parse_attribute<R: Reader>( input: &mut R, encoding: Encoding, spec: AttributeSpecification, @@ -2205,7 +2201,7 @@ pub(crate) fn parse_attribute<'unit, R: Reader>( } } -pub(crate) fn skip_attributes<'unit, R: Reader>( +pub(crate) fn skip_attributes<R: Reader>( input: &mut R, encoding: Encoding, specs: &[AttributeSpecification], @@ -2294,7 +2290,6 @@ impl<'abbrev, 'entry, 'unit, R: Reader> AttrsIter<'abbrev, 'entry, 'unit, R> { /// Returns `None` when iteration is finished. If an error /// occurs while parsing the next attribute, then this error /// is returned, and all subsequent calls return `None`. - #[allow(clippy::inline_always)] #[inline(always)] pub fn next(&mut self) -> Result<Option<Attribute<R>>> { if self.attributes.is_empty() { @@ -2647,7 +2642,6 @@ impl<'abbrev, 'unit, R: Reader> EntriesCursor<'abbrev, 'unit, R> { /// println!("The first entry with no children is {:?}", /// first_entry_with_no_children.unwrap()); /// ``` - #[allow(clippy::type_complexity)] pub fn next_dfs( &mut self, ) -> Result<Option<(isize, &DebuggingInformationEntry<'abbrev, 'unit, R>)>> { @@ -4213,7 +4207,6 @@ mod tests { #[test] fn test_attribute_udata_sdata_value() { - #[allow(clippy::type_complexity)] let tests: &[( AttributeValue<EndianSlice<LittleEndian>>, Option<u64>, diff --git a/vendor/gimli/src/read/util.rs b/vendor/gimli/src/read/util.rs index 16eafdde4..747418bab 100644 --- a/vendor/gimli/src/read/util.rs +++ b/vendor/gimli/src/read/util.rs @@ -9,7 +9,8 @@ use core::ptr; use core::slice; mod sealed { - // SAFETY: Implementer must not modify the content in storage. + /// # Safety + /// Implementer must not modify the content in storage. pub unsafe trait Sealed { type Storage; @@ -161,7 +162,7 @@ impl<A: ArrayLike> ArrayVec<A> { } else { self.len -= 1; // SAFETY: this element is valid and we "forget" it by setting the length. - Some(unsafe { A::as_slice(&mut self.storage)[self.len].as_ptr().read() }) + Some(unsafe { A::as_slice(&self.storage)[self.len].as_ptr().read() }) } } diff --git a/vendor/gimli/src/write/line.rs b/vendor/gimli/src/write/line.rs index 310170d9a..c88b735bc 100644 --- a/vendor/gimli/src/write/line.rs +++ b/vendor/gimli/src/write/line.rs @@ -94,8 +94,6 @@ impl LineProgram { /// Panics if `comp_dir` is empty or contains a null byte. /// /// Panics if `comp_file` is empty or contains a null byte. - #[allow(clippy::too_many_arguments)] - #[allow(clippy::new_ret_no_self)] pub fn new( encoding: Encoding, line_encoding: LineEncoding, @@ -261,7 +259,7 @@ impl LineProgram { } else { let entry = self.files.entry(key); let index = entry.index(); - entry.or_insert(FileInfo::default()); + entry.or_default(); index }; FileId::new(index) @@ -1723,7 +1721,6 @@ mod tests { // Test that the address/line advance is correct. We don't test for optimality. #[test] - #[allow(clippy::useless_vec)] fn test_advance() { let encoding = Encoding { format: Format::Dwarf32, diff --git a/vendor/gimli/src/write/loc.rs b/vendor/gimli/src/write/loc.rs index ea0ecb1cf..6dfe45a6c 100644 --- a/vendor/gimli/src/write/loc.rs +++ b/vendor/gimli/src/write/loc.rs @@ -436,6 +436,7 @@ mod tests { }; use crate::LittleEndian; use std::collections::HashMap; + use std::sync::Arc; #[test] fn test_loc_list() { @@ -508,7 +509,7 @@ mod tests { DebugInfoOffset(0).into(), read::EndianSlice::default(), ), - abbreviations: read::Abbreviations::default(), + abbreviations: Arc::new(read::Abbreviations::default()), name: None, comp_dir: None, low_pc: 0, diff --git a/vendor/gimli/src/write/op.rs b/vendor/gimli/src/write/op.rs index c70eec2dd..287083b3e 100644 --- a/vendor/gimli/src/write/op.rs +++ b/vendor/gimli/src/write/op.rs @@ -279,12 +279,8 @@ impl Expression { } offsets.push(offset); for (operation, offset) in self.operations.iter().zip(offsets.iter().copied()) { - let refs = match refs { - Some(ref mut refs) => Some(&mut **refs), - None => None, - }; debug_assert_eq!(w.len(), offset); - operation.write(w, refs, encoding, unit_offsets, &offsets)?; + operation.write(w, refs.as_deref_mut(), encoding, unit_offsets, &offsets)?; } Ok(()) } @@ -630,7 +626,7 @@ impl Operation { } w.write_uleb128(entry_offset(base)?)?; w.write_udata(value.len() as u64, 1)?; - w.write(&value)?; + w.write(value)?; } Operation::FrameOffset(offset) => { w.write_u8(constants::DW_OP_fbreg.0)?; @@ -770,7 +766,7 @@ impl Operation { Operation::ImplicitValue(ref data) => { w.write_u8(constants::DW_OP_implicit_value.0)?; w.write_uleb128(data.len() as u64)?; - w.write(&data)?; + w.write(data)?; } Operation::ImplicitPointer { entry, byte_offset } => { if encoding.version >= 5 { @@ -872,7 +868,7 @@ pub(crate) mod convert { let mut offsets = Vec::new(); let mut offset = 0; let mut from_operations = from_expression.clone().operations(encoding); - while let Some(_) = from_operations.next()? { + while from_operations.next()?.is_some() { offsets.push(offset); offset = from_operations.offset_from(&from_expression); } @@ -1071,6 +1067,7 @@ mod tests { }; use crate::LittleEndian; use std::collections::HashMap; + use std::sync::Arc; #[test] fn test_operation() { @@ -1578,7 +1575,7 @@ mod tests { DebugInfoOffset(0).into(), read::EndianSlice::new(&[], LittleEndian), ), - abbreviations: read::Abbreviations::default(), + abbreviations: Arc::new(read::Abbreviations::default()), name: None, comp_dir: None, low_pc: 0, diff --git a/vendor/gimli/src/write/range.rs b/vendor/gimli/src/write/range.rs index b44ce1b7b..c707e1eab 100644 --- a/vendor/gimli/src/write/range.rs +++ b/vendor/gimli/src/write/range.rs @@ -315,6 +315,7 @@ mod tests { }; use crate::LittleEndian; use std::collections::HashMap; + use std::sync::Arc; #[test] fn test_range() { @@ -375,7 +376,7 @@ mod tests { DebugInfoOffset(0).into(), read::EndianSlice::default(), ), - abbreviations: read::Abbreviations::default(), + abbreviations: Arc::new(read::Abbreviations::default()), name: None, comp_dir: None, low_pc: 0, diff --git a/vendor/gimli/src/write/section.rs b/vendor/gimli/src/write/section.rs index e8f3378cd..db5eb9a28 100644 --- a/vendor/gimli/src/write/section.rs +++ b/vendor/gimli/src/write/section.rs @@ -111,7 +111,7 @@ impl<W: Writer + Clone> Sections<W> { debug_loclists: DebugLocLists(section.clone()), debug_str: DebugStr(section.clone()), debug_frame: DebugFrame(section.clone()), - eh_frame: EhFrame(section.clone()), + eh_frame: EhFrame(section), debug_info_refs: Vec::new(), debug_loc_refs: Vec::new(), debug_loclists_refs: Vec::new(), diff --git a/vendor/gimli/src/write/unit.rs b/vendor/gimli/src/write/unit.rs index bf85ff421..23027bc2c 100644 --- a/vendor/gimli/src/write/unit.rs +++ b/vendor/gimli/src/write/unit.rs @@ -365,7 +365,6 @@ impl Unit { &mut unit_refs, self, &mut offsets, - abbrevs, line_program, line_strings, strings, @@ -605,7 +604,6 @@ impl DebuggingInformationEntry { } /// Write the entry to the given sections. - #[allow(clippy::too_many_arguments)] fn write<W: Writer>( &self, w: &mut DebugInfo<W>, @@ -613,7 +611,6 @@ impl DebuggingInformationEntry { unit_refs: &mut Vec<(DebugInfoOffset, UnitEntryId)>, unit: &Unit, offsets: &mut UnitOffsets, - abbrevs: &mut AbbreviationTable, line_program: Option<DebugLineOffset>, line_strings: &DebugLineStrOffsets, strings: &DebugStrOffsets, @@ -654,7 +651,6 @@ impl DebuggingInformationEntry { unit_refs, unit, offsets, - abbrevs, line_program, line_strings, strings, @@ -1128,7 +1124,6 @@ impl AttributeValue { } /// Write the attribute value to the given sections. - #[allow(clippy::cyclomatic_complexity, clippy::too_many_arguments)] fn write<W: Writer>( &self, w: &mut DebugInfo<W>, @@ -1155,7 +1150,7 @@ impl AttributeValue { AttributeValue::Block(ref val) => { debug_assert_form!(constants::DW_FORM_block); w.write_uleb128(val.len() as u64)?; - w.write(&val)?; + w.write(val)?; } AttributeValue::Data1(val) => { debug_assert_form!(constants::DW_FORM_data1); @@ -1308,7 +1303,7 @@ impl AttributeValue { } AttributeValue::String(ref val) => { debug_assert_form!(constants::DW_FORM_string); - w.write(&val)?; + w.write(val)?; w.write_u8(0)?; } AttributeValue::Encoding(val) => { @@ -1558,7 +1553,6 @@ pub(crate) mod convert { /// Create a unit by reading the data in the input sections. /// /// Does not add entry attributes. - #[allow(clippy::too_many_arguments)] pub(crate) fn convert_entries<R: Reader<Offset = usize>>( from_header: read::UnitHeader<R>, unit_id: UnitId, @@ -1931,9 +1925,9 @@ mod tests { use crate::LittleEndian; use std::collections::HashMap; use std::mem; + use std::sync::Arc; #[test] - #[allow(clippy::cyclomatic_complexity)] fn test_unit_table() { let mut strings = StringTable::default(); @@ -2542,7 +2536,7 @@ mod tests { let unit = read::Unit { header: from_unit, - abbreviations: read::Abbreviations::default(), + abbreviations: Arc::new(read::Abbreviations::default()), name: None, comp_dir: None, low_pc: 0, @@ -2578,7 +2572,6 @@ mod tests { } #[test] - #[allow(clippy::cyclomatic_complexity)] fn test_unit_ref() { let mut units = UnitTable::default(); let unit_id1 = units.add(Unit::new( @@ -3015,7 +3008,7 @@ mod tests { let unit = read::Unit { header: from_unit, - abbreviations: read::Abbreviations::default(), + abbreviations: Arc::new(read::Abbreviations::default()), name: None, comp_dir: None, low_pc: 0, diff --git a/vendor/gimli/src/write/writer.rs b/vendor/gimli/src/write/writer.rs index 0785d1686..1ce3641fc 100644 --- a/vendor/gimli/src/write/writer.rs +++ b/vendor/gimli/src/write/writer.rs @@ -93,9 +93,7 @@ pub trait Writer { constants::DW_EH_PE_sdata2 => self.write_sdata(val as i64, 2), constants::DW_EH_PE_sdata4 => self.write_sdata(val as i64, 4), constants::DW_EH_PE_sdata8 => self.write_sdata(val as i64, 8), - _ => { - return Err(Error::UnsupportedPointerEncoding(format)); - } + _ => Err(Error::UnsupportedPointerEncoding(format)), } } @@ -334,7 +332,6 @@ mod tests { use std::{i64, u64}; #[test] - #[allow(clippy::cyclomatic_complexity)] fn test_writer() { let mut w = write::EndianVec::new(LittleEndian); w.write_address(Address::Constant(0x1122_3344), 4).unwrap(); |