summaryrefslogtreecommitdiffstats
path: root/vendor/gimli/src
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/gimli/src')
-rw-r--r--vendor/gimli/src/arch.rs148
-rw-r--r--vendor/gimli/src/lib.rs15
-rw-r--r--vendor/gimli/src/read/abbrev.rs129
-rw-r--r--vendor/gimli/src/read/cfi.rs23
-rw-r--r--vendor/gimli/src/read/dwarf.rs26
-rw-r--r--vendor/gimli/src/read/endian_slice.rs6
-rw-r--r--vendor/gimli/src/read/lazy.rs116
-rw-r--r--vendor/gimli/src/read/line.rs2
-rw-r--r--vendor/gimli/src/read/loclists.rs241
-rw-r--r--vendor/gimli/src/read/mod.rs3
-rw-r--r--vendor/gimli/src/read/op.rs7
-rw-r--r--vendor/gimli/src/read/rnglists.rs206
-rw-r--r--vendor/gimli/src/read/unit.rs13
-rw-r--r--vendor/gimli/src/read/util.rs5
-rw-r--r--vendor/gimli/src/write/line.rs5
-rw-r--r--vendor/gimli/src/write/loc.rs3
-rw-r--r--vendor/gimli/src/write/op.rs15
-rw-r--r--vendor/gimli/src/write/range.rs3
-rw-r--r--vendor/gimli/src/write/section.rs2
-rw-r--r--vendor/gimli/src/write/unit.rs17
-rw-r--r--vendor/gimli/src/write/writer.rs5
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();