diff --git a/crates/examples/src/bin/convert.rs b/crates/examples/src/bin/convert.rs index b673106d..7bdc9f9c 100644 --- a/crates/examples/src/bin/convert.rs +++ b/crates/examples/src/bin/convert.rs @@ -9,7 +9,10 @@ use gimli::write::Writer; use object::{Object, ObjectSection}; use std::io::Write; -use std::{borrow, env, error, fs, io}; +use std::{borrow, env, error, fmt, fs, io}; + +trait Reader: gimli::Reader + fmt::Debug {} +impl + fmt::Debug> Reader for T {} fn main() -> Result<(), Box> { let mut args = env::args_os(); @@ -126,7 +129,7 @@ fn main() -> Result<(), Box> { Ok(()) } -fn convert_dwarf, W: gimli::write::Writer>( +fn convert_dwarf( read_dwarf: &gimli::Dwarf, dwp: Option<&gimli::DwarfPackage>, write_sections: &mut gimli::write::Sections, @@ -169,7 +172,7 @@ fn convert_dwarf, W: gimli::write::Writer>( Ok(()) } -fn convert_unit<'a, R: gimli::Reader, W: gimli::write::Writer>( +fn convert_unit<'a, R: Reader, W: gimli::write::Writer>( unit: &mut gimli::write::ConvertUnit<'a, R>, root_entry: gimli::write::ConvertUnitEntry<'a, R>, skeleton_root_entry: Option<&gimli::write::ConvertUnitEntry<'_, R>>, @@ -210,7 +213,7 @@ fn convert_unit<'a, R: gimli::Reader, W: gimli::write::Writer>( Ok(()) } -fn convert_attributes>( +fn convert_attributes( unit: &mut gimli::write::ConvertUnit<'_, R>, id: gimli::write::UnitEntryId, entry: &gimli::write::ConvertUnitEntry<'_, R>, @@ -234,7 +237,7 @@ fn convert_attributes>( } } -fn filter_dwarf>( +fn filter_dwarf( dwarf: &gimli::read::Dwarf, ) -> gimli::write::ConvertResult> { // Walk the DIE tree. This will automatically record relationships between DIEs based @@ -256,7 +259,7 @@ fn filter_dwarf>( } /// Use heuristics to determine if an entry is dead code. -fn need_entry>( +fn need_entry( entry: &gimli::write::FilterUnitEntry<'_, R>, ) -> gimli::write::ConvertResult { match entry.parent_tag { @@ -371,7 +374,7 @@ fn need_entry>( Ok(false) } -fn is_tombstone_address>( +fn is_tombstone_address( entry: &gimli::write::FilterUnitEntry<'_, R>, address: u64, ) -> bool { diff --git a/crates/examples/src/bin/dwarfdump.rs b/crates/examples/src/bin/dwarfdump.rs index d69c1513..13cd7b3a 100644 --- a/crates/examples/src/bin/dwarfdump.rs +++ b/crates/examples/src/bin/dwarfdump.rs @@ -197,7 +197,6 @@ struct Flags<'a> { dwp: bool, dwo_parent: Option>, sup: Option>, - raw: bool, info_offset: Option, match_units: Option, } @@ -240,7 +239,6 @@ fn main() { "use the specified file as the parent of the dwo or dwp (e.g. for .debug_addr)", "library path", ); - opts.optflag("", "raw", "print raw data values"); opts.optopt( "u", "match-units", @@ -320,9 +318,6 @@ fn main() { if matches.opt_present("dwp") { flags.dwp = true; } - if matches.opt_present("raw") { - flags.raw = true; - } if all { // .eh_frame is excluded even when printing all information. // cosmetic flags like -G must be set explicitly too. @@ -1241,25 +1236,19 @@ fn dump_entries( } else { write!(w, "{:27} ", attr.name())?; } - if flags.raw { - writeln!(w, "{:?}", attr.raw_value())?; - } else { - match dump_attr_value(w, &attr, unit) { - Ok(_) => (), - Err(err) => { - writeln_error(w, unit.dwarf, err, "Failed to dump attribute value")? - } - }; - // dump_attr_value only prints the offset for the macro info attribute. - // The content is too long to print inline, so store the offset to print later. - if attr.name() == gimli::DW_AT_macro_info { - if let gimli::AttributeValue::DebugMacinfoRef(offset) = attr.value() { - deferred_macinfo.push(offset); - } - } else if attr.name() == gimli::DW_AT_macros { - if let gimli::AttributeValue::DebugMacroRef(offset) = attr.value() { - deferred_macros.push(offset); - } + match dump_attr_value(w, &attr, unit) { + Ok(_) => (), + Err(err) => writeln_error(w, unit.dwarf, err, "Failed to dump attribute value")?, + }; + // dump_attr_value only prints the offset for the macro info attribute. + // The content is too long to print inline, so store the offset to print later. + if attr.name() == gimli::DW_AT_macro_info { + if let gimli::AttributeValue::DebugMacinfoRef(offset) = attr.value() { + deferred_macinfo.push(offset); + } + } else if attr.name() == gimli::DW_AT_macros { + if let gimli::AttributeValue::DebugMacroRef(offset) = attr.value() { + deferred_macros.push(offset); } } } @@ -1299,18 +1288,18 @@ fn dump_attr_value( gimli::AttributeValue::Data1(_) | gimli::AttributeValue::Data2(_) | gimli::AttributeValue::Data4(_) - | gimli::AttributeValue::Data8(_) - | gimli::AttributeValue::Data16(_) => { - if let (Some(udata), Some(sdata)) = (attr.udata_value(), attr.sdata_value()) { - if sdata >= 0 { - writeln!(w, "{}", udata)?; - } else { - writeln!(w, "{} ({})", udata, sdata)?; - } + | gimli::AttributeValue::Data8(_) => { + let udata = attr.udata_value().unwrap(); + let sdata = attr.sdata_value().unwrap(); + if sdata >= 0 { + writeln!(w, "{}", udata)?; } else { - writeln!(w, "{:?}", value)?; + writeln!(w, "{} ({})", udata, sdata)?; } } + gimli::AttributeValue::Data16(data) => { + writeln!(w, "0x{:x}", data)?; + } gimli::AttributeValue::Sdata(data) => { match attr.name() { gimli::DW_AT_data_member_location => { @@ -2158,7 +2147,7 @@ fn dump_line_program(w: &mut W, unit: gimli::UnitRef) -> write!(w, "Unknown {} with operand {}", opcode, arg) } LineInstruction::UnknownStandardN(opcode, ref args) => { - write!(w, "Unknown {} with operands {:?}", opcode, args) + write!(w, "Unknown {} with operands {:?}", opcode, args.to_slice()?) } LineInstruction::EndSequence => write!(w, "{}", constants::DW_LNE_end_sequence), LineInstruction::SetAddress(address) => { diff --git a/src/read/cfi.rs b/src/read/cfi.rs index 81fa455b..f8d7b709 100644 --- a/src/read/cfi.rs +++ b/src/read/cfi.rs @@ -565,7 +565,7 @@ pub enum CieOffsetEncoding { /// An offset into an `UnwindSection`. // // Needed to avoid conflicting implementations of `Into`. -pub trait UnwindOffset: Copy + Debug + Eq + From +pub trait UnwindOffset: Copy + Eq + From where T: ReaderOffset, { @@ -632,10 +632,14 @@ pub trait _UnwindSectionPrivate { /// A section holding unwind information: either `.debug_frame` or /// `.eh_frame`. See [`DebugFrame`](./struct.DebugFrame.html) and /// [`EhFrame`](./struct.EhFrame.html) respectively. -pub trait UnwindSection: Clone + Debug + _UnwindSectionPrivate { +pub trait UnwindSection::Offset>: Clone + _UnwindSectionPrivate +where + R: Reader, + O: ReaderOffset, +{ /// The offset type associated with this CFI section. Either /// `DebugFrameOffset` or `EhFrameOffset`. - type Offset: UnwindOffset; + type Offset: UnwindOffset; /// Iterate over the `CommonInformationEntry`s and `FrameDescriptionEntry`s /// in this `.debug_frame` section. @@ -989,10 +993,11 @@ impl BaseAddresses { /// # } /// ``` #[derive(Clone, Debug)] -pub struct CfiEntriesIter<'bases, Section, R> +pub struct CfiEntriesIter<'bases, Section, R, Offset = ::Offset> where - R: Reader, - Section: UnwindSection, + R: Reader, + Offset: ReaderOffset, + Section: UnwindSection, { section: Section, bases: &'bases BaseAddresses, @@ -1062,17 +1067,24 @@ where /// Either a `CommonInformationEntry` (CIE) or a `FrameDescriptionEntry` (FDE). #[derive(Clone, Debug, PartialEq, Eq)] -pub enum CieOrFde<'bases, Section, R> -where - R: Reader, - Section: UnwindSection, +pub enum CieOrFde< + 'bases, + Section, + R, + Offset = ::Offset, + SectionOffset =
>::Offset, +> where + R: Reader, + Offset: ReaderOffset, + Section: UnwindSection, + SectionOffset: UnwindOffset, { /// This CFI entry is a `CommonInformationEntry`. - Cie(CommonInformationEntry), + Cie(CommonInformationEntry), /// This CFI entry is a `FrameDescriptionEntry`, however fully parsing it /// requires parsing its CIE first, so it is left in a partially parsed /// state. - Fde(PartialFrameDescriptionEntry<'bases, Section, R>), + Fde(PartialFrameDescriptionEntry<'bases, Section, R, Offset, SectionOffset>), } fn parse_cfi_entry<'bases, Section, R>( @@ -1520,15 +1532,22 @@ impl CommonInformationEntry { /// /// Fully parsing this FDE requires first parsing its CIE. #[derive(Clone, Debug, PartialEq, Eq)] -pub struct PartialFrameDescriptionEntry<'bases, Section, R> -where - R: Reader, - Section: UnwindSection, +pub struct PartialFrameDescriptionEntry< + 'bases, + Section, + R, + Offset = ::Offset, + SectionOffset =
>::Offset, +> where + R: Reader, + Offset: ReaderOffset, + Section: UnwindSection, + SectionOffset: UnwindOffset, { - offset: R::Offset, - length: R::Offset, + offset: Offset, + length: Offset, format: Format, - cie_offset: Section::Offset, + cie_offset: SectionOffset, rest: R, section: Section, bases: &'bases BaseAddresses, @@ -1973,7 +1992,7 @@ where impl Debug for UnwindContext where - T: ReaderOffset, + T: ReaderOffset + Debug, S: UnwindContextStorage, { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { @@ -2537,7 +2556,7 @@ where impl Debug for RegisterRuleMap where - T: ReaderOffset, + T: ReaderOffset + Debug, S: UnwindContextStorage, { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { @@ -2710,7 +2729,7 @@ where impl Debug for UnwindTableRow where - T: ReaderOffset, + T: ReaderOffset + Debug, S: UnwindContextStorage, { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { @@ -3743,7 +3762,7 @@ mod tests { fn endian<'input, E>(self) -> Endian where E: Endianity, - T: UnwindSection>, + T: UnwindSection, usize>, T::Offset: UnwindOffset, { if E::default().is_big_endian() { @@ -3756,7 +3775,7 @@ mod tests { fn section<'input, E>(self, contents: &'input [u8]) -> T where E: Endianity, - T: UnwindSection> + ReadSection>, + T: UnwindSection, usize> + ReadSection>, T::Offset: UnwindOffset, { EndianSlice::new(contents, E::default()).into() @@ -3805,7 +3824,7 @@ mod tests { ) -> Self where E: Endianity, - T: UnwindSection>, + T: UnwindSection, usize>, T::Offset: UnwindOffset; fn fde<'a, 'input, E, T, L>( self, @@ -3815,7 +3834,7 @@ mod tests { ) -> Self where E: Endianity, - T: UnwindSection>, + T: UnwindSection, usize>, T::Offset: UnwindOffset, L: ToLabelOrNum<'a, u64>; } @@ -3829,7 +3848,7 @@ mod tests { ) -> Self where E: Endianity, - T: UnwindSection>, + T: UnwindSection, usize>, T::Offset: UnwindOffset, { cie.offset = self.size() as _; @@ -3881,7 +3900,7 @@ mod tests { ) -> Self where E: Endianity, - T: UnwindSection>, + T: UnwindSection, usize>, T::Offset: UnwindOffset, L: ToLabelOrNum<'a, u64>, { diff --git a/src/read/dwarf.rs b/src/read/dwarf.rs index 4a725fb7..b5147213 100644 --- a/src/read/dwarf.rs +++ b/src/read/dwarf.rs @@ -1425,7 +1425,7 @@ pub struct UnitRef<'a, R: Reader> { pub dwarf: &'a Dwarf, /// The `Unit` being referenced. - pub unit: &'a Unit, + pub unit: &'a Unit, } impl<'a, R: Reader> Clone for UnitRef<'a, R> { @@ -1610,12 +1610,12 @@ impl<'a, R: Reader> UnitRef<'a, R> { /// /// Returned by `Dwarf::die_ranges` and `Dwarf::unit_ranges`. #[derive(Debug)] -pub struct RangeIter(RangeIterInner); +pub struct RangeIter::Offset>(RangeIterInner); #[derive(Debug)] -enum RangeIterInner { +enum RangeIterInner::Offset> { Single(Option), - List(RngListIter), + List(RngListIter), } impl Default for RangeIter { diff --git a/src/read/endian_reader.rs b/src/read/endian_reader.rs index 5e65b4d1..96753344 100644 --- a/src/read/endian_reader.rs +++ b/src/read/endian_reader.rs @@ -118,11 +118,7 @@ pub type EndianArcSlice = EndianReader>; /// # fn test(_: &MmapFileReader) { } /// ``` #[derive(Debug, Clone, Copy)] -pub struct EndianReader -where - Endian: Endianity, - T: CloneStableDeref + Debug, -{ +pub struct EndianReader { range: SubRange, endian: Endian, } @@ -130,8 +126,8 @@ where impl PartialEq> for EndianReader where Endian: Endianity, - T1: CloneStableDeref + Debug, - T2: CloneStableDeref + Debug, + T1: CloneStableDeref, + T2: CloneStableDeref, { fn eq(&self, rhs: &EndianReader) -> bool { self.bytes() == rhs.bytes() @@ -141,14 +137,14 @@ where impl Eq for EndianReader where Endian: Endianity, - T: CloneStableDeref + Debug, + T: CloneStableDeref, { } impl Hash for EndianReader where Endian: Endianity, - T: CloneStableDeref + Debug, + T: CloneStableDeref, { fn hash(&self, state: &mut H) { // This must match the `PartialEq` implementation. @@ -169,22 +165,19 @@ where // `CloneStableDeref` ensures these bytes never move. The `ptr` and `len` // members point inside `bytes`, and are updated during read operations. #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] -struct SubRange -where - T: CloneStableDeref + Debug, -{ +struct SubRange { bytes: T, ptr: *const u8, len: usize, } -unsafe impl Send for SubRange where T: CloneStableDeref + Debug + Send {} +unsafe impl Send for SubRange {} -unsafe impl Sync for SubRange where T: CloneStableDeref + Debug + Sync {} +unsafe impl Sync for SubRange {} impl SubRange where - T: CloneStableDeref + Debug, + T: CloneStableDeref, { #[inline] fn new(bytes: T) -> Self { @@ -234,7 +227,7 @@ where impl EndianReader where Endian: Endianity, - T: CloneStableDeref + Debug, + T: CloneStableDeref, { /// Construct a new `EndianReader` with the given bytes. #[inline] @@ -261,7 +254,7 @@ where impl EndianReader where Endian: Endianity, - T: CloneStableDeref + Debug, + T: CloneStableDeref, { /// Take the given `start..end` range of the underlying buffer and return a /// new `EndianReader`. @@ -340,7 +333,7 @@ where impl Index for EndianReader where Endian: Endianity, - T: CloneStableDeref + Debug, + T: CloneStableDeref, { type Output = u8; fn index(&self, idx: usize) -> &Self::Output { @@ -351,7 +344,7 @@ where impl Index> for EndianReader where Endian: Endianity, - T: CloneStableDeref + Debug, + T: CloneStableDeref, { type Output = [u8]; fn index(&self, idx: RangeFrom) -> &Self::Output { @@ -362,7 +355,7 @@ where impl Deref for EndianReader where Endian: Endianity, - T: CloneStableDeref + Debug, + T: CloneStableDeref, { type Target = [u8]; fn deref(&self) -> &Self::Target { @@ -495,7 +488,7 @@ mod tests { use crate::endianity::NativeEndian; use crate::read::Reader; - fn native_reader + Debug>( + fn native_reader>( bytes: T, ) -> EndianReader { EndianReader::new(bytes, NativeEndian) diff --git a/src/read/names.rs b/src/read/names.rs index 6699edeb..5642c85e 100644 --- a/src/read/names.rs +++ b/src/read/names.rs @@ -553,7 +553,7 @@ impl NameIndex { /// Parse the entry at the given entry pool offset. /// /// This is useful for reading the entry referenced by a `DW_IDX_parent` attribute. - pub fn name_entry(&self, offset: NameEntryOffset) -> Result> { + pub fn name_entry(&self, offset: NameEntryOffset) -> Result> { let mut entries = self.entry_pool.clone(); entries.skip(offset.0)?; NameEntry::parse(&mut entries, offset, &self.abbreviations)?.ok_or(Error::UnexpectedNull) @@ -743,7 +743,7 @@ impl<'a, R: Reader> NameEntryIter<'a, R> { } /// Advance the iterator and return the next name entry. - pub fn next(&mut self) -> Result>> { + pub fn next(&mut self) -> Result>> { if self.entries.is_empty() { return Ok(None); } @@ -767,7 +767,7 @@ impl<'a, R: Reader> NameEntryIter<'a, R> { #[cfg(feature = "fallible-iterator")] impl<'a, R: Reader> fallible_iterator::FallibleIterator for NameEntryIter<'a, R> { - type Item = NameEntry; + type Item = NameEntry; type Error = Error; fn next(&mut self) -> ::core::result::Result, Self::Error> { @@ -776,7 +776,7 @@ impl<'a, R: Reader> fallible_iterator::FallibleIterator for NameEntryIter<'a, R> } impl<'a, R: Reader> Iterator for NameEntryIter<'a, R> { - type Item = Result>; + type Item = Result>; fn next(&mut self) -> Option { NameEntryIter::next(self).transpose() @@ -789,9 +789,9 @@ pub struct NameEntryOffset(pub T); /// A parsed entry from the `.debug_names` section. #[derive(Debug, Clone, PartialEq, Eq)] -pub struct NameEntry { +pub struct NameEntry { /// The offset of the entry in the entries pool. - pub offset: NameEntryOffset, + pub offset: NameEntryOffset, /// The abbreviation code for this entry. pub abbrev_code: u64, @@ -800,10 +800,10 @@ pub struct NameEntry { pub tag: constants::DwTag, /// The attributes for this entry. - pub attrs: Vec>, + pub attrs: Vec>, } -impl NameEntry { +impl NameEntry { /// Get the value of the `DW_IDX_compile_unit` attribute, if any. /// /// If neither `DW_IDX_compile_unit` nor `DW_IDX_type_unit` exist then you should use @@ -812,7 +812,10 @@ impl NameEntry { /// If both `DW_IDX_compile_unit` and `DW_IDX_type_unit` exist then this value is for /// a skeleton CU that may be used to locate a split DWARF object file containing /// the type unit. - pub fn compile_unit(&self, names: &NameIndex) -> Result>> { + pub fn compile_unit>( + &self, + names: &NameIndex, + ) -> Result>> { for attr in &self.attrs { if attr.name == constants::DW_IDX_compile_unit { return attr.compile_unit(names).map(Some); @@ -822,7 +825,10 @@ impl NameEntry { } /// Get the value of the `DW_IDX_type_unit` attribute, if any. - pub fn type_unit(&self, names: &NameIndex) -> Result>> { + pub fn type_unit>( + &self, + names: &NameIndex, + ) -> Result>> { for attr in &self.attrs { if attr.name == constants::DW_IDX_type_unit { return attr.type_unit(names).map(Some); @@ -834,7 +840,7 @@ impl NameEntry { /// Get the value of the `DW_IDX_die_offset` attribute, if any. /// /// This is the offset of the DIE within the compile unit or type unit. - pub fn die_offset(&self) -> Result>> { + pub fn die_offset(&self) -> Result>> { for attr in &self.attrs { if attr.name == constants::DW_IDX_die_offset { return attr.die_offset().map(Some); @@ -849,7 +855,7 @@ impl NameEntry { /// Returns `Ok(Some(None))` if the DIE parent is not indexed. /// Returns `Ok(None)` if it is unknown whether the DIE parent is indexed /// because the producer did not generate a `DW_IDX_parent` attribute. - pub fn parent(&self) -> Result>>> { + pub fn parent(&self) -> Result>>> { for attr in &self.attrs { if attr.name == constants::DW_IDX_parent { return attr.parent().map(Some); @@ -869,11 +875,11 @@ impl NameEntry { } /// Parse a single entry from the entry pool. - fn parse( + fn parse>( entry_reader: &mut R, - offset: NameEntryOffset, + offset: NameEntryOffset, abbreviations: &NameAbbreviations, - ) -> Result>> { + ) -> Result>> { let abbrev_code = entry_reader.read_uleb128()?; if abbrev_code == 0 { return Ok(None); @@ -902,13 +908,13 @@ impl NameEntry { /// A parsed attribute for a [`NameEntry`]. #[derive(Debug, Clone, Copy, PartialEq, Eq)] -pub struct NameAttribute { +pub struct NameAttribute { name: constants::DwIdx, form: constants::DwForm, - value: NameAttributeValue, + value: NameAttributeValue, } -impl NameAttribute { +impl NameAttribute { /// Get the attribute name. pub fn name(&self) -> constants::DwIdx { self.name @@ -922,12 +928,15 @@ impl NameAttribute { /// Get the attribute value. /// /// Interpretation of this value depends on the name and form. - pub fn value(&self) -> &NameAttributeValue { + pub fn value(&self) -> &NameAttributeValue { &self.value } /// Get the value of a `DW_IDX_compile_unit` attribute. - pub fn compile_unit(&self, names: &NameIndex) -> Result> { + pub fn compile_unit>( + &self, + names: &NameIndex, + ) -> Result> { match self.value { NameAttributeValue::Unsigned(val) => { let index = @@ -939,7 +948,10 @@ impl NameAttribute { } /// Get the value of a `DW_IDX_type_unit` attribute. - pub fn type_unit(&self, names: &NameIndex) -> Result> { + pub fn type_unit>( + &self, + names: &NameIndex, + ) -> Result> { match self.value { NameAttributeValue::Unsigned(val) => { let index = @@ -951,7 +963,7 @@ impl NameAttribute { } /// Get the value of a `DW_IDX_die_offset` attribute. - pub fn die_offset(&self) -> Result> { + pub fn die_offset(&self) -> Result> { match self.value { NameAttributeValue::Offset(val) => Ok(UnitOffset(val)), _ => Err(Error::UnsupportedAttributeForm), @@ -962,7 +974,7 @@ impl NameAttribute { /// /// Returns `Ok(Some(offset))` if the DIE parent is indexed. /// Returns `Ok(None)` if the DIE parent is not indexed. - pub fn parent(&self) -> Result>> { + pub fn parent(&self) -> Result>> { match self.value { NameAttributeValue::Offset(val) => Ok(Some(NameEntryOffset(val))), NameAttributeValue::Flag(true) => Ok(None), @@ -981,7 +993,7 @@ impl NameAttribute { /// A parsed attribute value for a [`NameEntry`]. #[derive(Debug, Clone, Copy, PartialEq, Eq)] -pub enum NameAttributeValue { +pub enum NameAttributeValue { /// An unsigned integer. /// /// This can be from the following forms: @@ -991,7 +1003,7 @@ pub enum NameAttributeValue { /// /// This can be from the following forms: /// `DW_FORM_ref1`, `DW_FORM_ref2`, `DW_FORM_ref4`, `DW_FORM_ref8`, `DW_FORM_ref_udata` - Offset(R::Offset), + Offset(Offset), /// A boolean flag. /// /// This can be from the following forms: @@ -1006,7 +1018,7 @@ pub enum NameAttributeValue { fn read_debug_names_form_value( input: &mut R, form: constants::DwForm, -) -> Result> { +) -> Result> { Ok(match form { constants::DW_FORM_flag => { let present = input.read_u8()?; diff --git a/src/read/op.rs b/src/read/op.rs index 585b182d..3f4564ff 100644 --- a/src/read/op.rs +++ b/src/read/op.rs @@ -304,11 +304,15 @@ where } #[derive(Debug)] -enum OperationEvaluationResult { +enum OperationEvaluationResult::Offset> +where + R: Reader, + Offset: ReaderOffset, +{ Piece, Incomplete, - Complete { location: Location }, - Waiting(EvaluationWaiting, EvaluationResult), + Complete { location: Location }, + Waiting(EvaluationWaiting, EvaluationResult), } /// A single location of a piece of the result of a DWARF expression. @@ -860,7 +864,11 @@ enum EvaluationWaiting { /// The evaluation is either `Complete`, or it requires more data /// to continue, as described by the variant. #[derive(Debug, PartialEq)] -pub enum EvaluationResult { +pub enum EvaluationResult::Offset> +where + R: Reader, + Offset: ReaderOffset, +{ /// The `Evaluation` is complete, and `Evaluation::result()` can be called. Complete, /// The `Evaluation` needs a value from memory to proceed further. Once the @@ -875,7 +883,7 @@ pub enum EvaluationResult { /// If not `None`, a target-specific address space value. space: Option, /// The DIE of the base type or 0 to indicate the generic type - base_type: UnitOffset, + base_type: UnitOffset, }, /// The `Evaluation` needs a value from a register to proceed further. Once /// the caller determines what value to provide it should resume the @@ -884,7 +892,7 @@ pub enum EvaluationResult { /// The register number. register: Register, /// The DIE of the base type or 0 to indicate the generic type - base_type: UnitOffset, + base_type: UnitOffset, }, /// The `Evaluation` needs the frame base address to proceed further. Once /// the caller determines what value to provide it should resume the @@ -904,7 +912,7 @@ pub enum EvaluationResult { /// proceed further. Once the caller determines what value to provide it /// should resume the `Evaluation` by calling /// `Evaluation::resume_with_at_location`. - RequiresAtLocation(DieReference), + RequiresAtLocation(DieReference), /// The `Evaluation` needs the value produced by evaluating a DWARF /// expression at the entry point of the current subprogram. Once the /// caller determines what value to provide it should resume the @@ -914,7 +922,7 @@ pub enum EvaluationResult { /// in the current function's caller. Once the caller determines what value /// to provide it should resume the `Evaluation` by calling /// `Evaluation::resume_with_parameter_ref`. - RequiresParameterRef(UnitOffset), + RequiresParameterRef(UnitOffset), /// The `Evaluation` needs an address to be relocated to proceed further. /// Once the caller determines what value to provide it should resume the /// `Evaluation` by calling `Evaluation::resume_with_relocated_address`. @@ -926,7 +934,7 @@ pub enum EvaluationResult { RequiresIndexedAddress { /// The index of the address in the `.debug_addr` section, /// relative to the `DW_AT_addr_base` of the compilation unit. - index: DebugAddrIndex, + index: DebugAddrIndex, /// Whether the address also needs to be relocated. relocate: bool, }, @@ -934,7 +942,7 @@ pub enum EvaluationResult { /// the give unit offset. Once the caller determines what value to provide it /// should resume the `Evaluation` by calling /// `Evaluation::resume_with_base_type`. - RequiresBaseType(UnitOffset), + RequiresBaseType(UnitOffset), } /// The bytecode for a DWARF expression or location description. @@ -1067,13 +1075,17 @@ on the heap using [`Vec`]. This is the default storage type parameter for [`Eval /// let result = eval.as_result(); /// println!("{:?}", result); /// ``` -pub trait EvaluationStorage { +pub trait EvaluationStorage::Offset> +where + R: Reader, + Offset: ReaderOffset, +{ /// The storage used for the evaluation stack. type Stack: ArrayLike; /// The storage used for the expression stack. type ExpressionStack: ArrayLike; /// The storage used for the results. - type Result: ArrayLike>; + type Result: ArrayLike>; } #[cfg(feature = "read")] @@ -1129,7 +1141,12 @@ impl EvaluationStorage for StoreOnHeap { /// println!("{:?}", result); /// ``` #[derive(Debug)] -pub struct Evaluation = StoreOnHeap> { +pub struct Evaluation::Offset> +where + R: Reader, + S: EvaluationStorage, + Offset: ReaderOffset, +{ bytecode: R, encoding: Encoding, object_address: Option, diff --git a/src/read/pubnames.rs b/src/read/pubnames.rs index fd9b5545..6d12f6c1 100644 --- a/src/read/pubnames.rs +++ b/src/read/pubnames.rs @@ -1,13 +1,17 @@ use crate::common::{DebugInfoOffset, SectionId}; use crate::endianity::Endianity; use crate::read::lookup::{DebugLookup, LookupEntryIter, PubStuffEntry, PubStuffParser}; -use crate::read::{EndianSlice, Reader, Result, Section, UnitOffset}; +use crate::read::{EndianSlice, Reader, ReaderOffset, Result, Section, UnitOffset}; /// A single parsed pubname. #[derive(Debug, Clone)] -pub struct PubNamesEntry { - unit_header_offset: DebugInfoOffset, - die_offset: UnitOffset, +pub struct PubNamesEntry::Offset> +where + R: Reader, + Offset: ReaderOffset, +{ + unit_header_offset: DebugInfoOffset, + die_offset: UnitOffset, name: R, } @@ -47,7 +51,12 @@ impl PubStuffEntry for PubNamesEntry { /// The `DebugPubNames` struct represents the DWARF public names information /// found in the `.debug_pubnames` section. #[derive(Debug, Clone)] -pub struct DebugPubNames(DebugLookup>>); +pub struct DebugPubNames::Offset>( + DebugLookup>>, +) +where + R: Reader, + Offset: ReaderOffset; impl<'input, Endian> DebugPubNames> where @@ -112,7 +121,12 @@ impl From for DebugPubNames { /// An iterator over the pubnames from a `.debug_pubnames` section. #[derive(Debug, Clone)] -pub struct PubNamesEntryIter(LookupEntryIter>>); +pub struct PubNamesEntryIter::Offset>( + LookupEntryIter>>, +) +where + R: Reader, + Offset: ReaderOffset; impl PubNamesEntryIter { /// Advance the iterator and return the next pubname. diff --git a/src/read/pubtypes.rs b/src/read/pubtypes.rs index e5774e0d..3d4876bb 100644 --- a/src/read/pubtypes.rs +++ b/src/read/pubtypes.rs @@ -1,13 +1,17 @@ use crate::common::{DebugInfoOffset, SectionId}; use crate::endianity::Endianity; use crate::read::lookup::{DebugLookup, LookupEntryIter, PubStuffEntry, PubStuffParser}; -use crate::read::{EndianSlice, Reader, Result, Section, UnitOffset}; +use crate::read::{EndianSlice, Reader, ReaderOffset, Result, Section, UnitOffset}; /// A single parsed pubtype. #[derive(Debug, Clone)] -pub struct PubTypesEntry { - unit_header_offset: DebugInfoOffset, - die_offset: UnitOffset, +pub struct PubTypesEntry::Offset> +where + R: Reader, + Offset: ReaderOffset, +{ + unit_header_offset: DebugInfoOffset, + die_offset: UnitOffset, name: R, } @@ -47,7 +51,12 @@ impl PubStuffEntry for PubTypesEntry { /// The `DebugPubTypes` struct represents the DWARF public types information /// found in the `.debug_info` section. #[derive(Debug, Clone)] -pub struct DebugPubTypes(DebugLookup>>); +pub struct DebugPubTypes::Offset>( + DebugLookup>>, +) +where + R: Reader, + Offset: ReaderOffset; impl<'input, Endian> DebugPubTypes> where @@ -112,7 +121,12 @@ impl From for DebugPubTypes { /// An iterator over the pubtypes from a `.debug_pubtypes` section. #[derive(Debug, Clone)] -pub struct PubTypesEntryIter(LookupEntryIter>>); +pub struct PubTypesEntryIter::Offset>( + LookupEntryIter>>, +) +where + R: Reader, + Offset: ReaderOffset; impl PubTypesEntryIter { /// Advance the iterator and return the next pubtype. diff --git a/src/read/reader.rs b/src/read/reader.rs index c4ba4396..493788ca 100644 --- a/src/read/reader.rs +++ b/src/read/reader.rs @@ -1,7 +1,6 @@ #[cfg(feature = "read")] use alloc::borrow::Cow; use core::convert::TryInto; -use core::fmt::Debug; use core::hash::Hash; use core::ops::{Add, AddAssign, Sub}; @@ -22,7 +21,7 @@ pub struct ReaderOffsetId(pub u64); /// /// This allows consumers to choose a size that is appropriate for their address space. pub trait ReaderOffset: - Debug + Copy + Eq + Ord + Hash + Add + AddAssign + Sub + Copy + Eq + Ord + Hash + Add + AddAssign + Sub { /// Convert a u8 to an offset. fn from_u8(offset: u8) -> Self; @@ -282,7 +281,7 @@ pub(crate) mod seal_if_no_alloc { /// | [`EndianRcSlice`](./struct.EndianRcSlice.html) | Reference counted | No | Shared ownership via reference counting, which alleviates the borrow restrictions of `EndianSlice` but imposes reference counting increments and decrements. Cannot be sent across threads, because the reference count is not atomic. | /// | [`EndianArcSlice`](./struct.EndianArcSlice.html) | Reference counted | Yes | The same as `EndianRcSlice`, but uses atomic reference counting, and therefore reference counting operations are slower but `EndianArcSlice`s may be sent across threads. | /// | [`EndianReader`](./struct.EndianReader.html) | Same as `T` | Same as `T` | Escape hatch for easily defining your own type of `Reader`. | -pub trait Reader: Debug + Clone { +pub trait Reader: Clone { /// The endianity of bytes that are read. type Endian: Endianity; diff --git a/src/read/relocate.rs b/src/read/relocate.rs index 7549c118..5e846d30 100644 --- a/src/read/relocate.rs +++ b/src/read/relocate.rs @@ -49,7 +49,7 @@ where impl fmt::Debug for RelocateReader where - R: Reader, + R: Reader + fmt::Debug, T: Relocate, { fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> core::result::Result<(), fmt::Error> { diff --git a/src/read/rnglists.rs b/src/read/rnglists.rs index 49cbe0bb..8fb195d9 100644 --- a/src/read/rnglists.rs +++ b/src/read/rnglists.rs @@ -472,11 +472,11 @@ impl Iterator for RawRngListIter { /// entry types. Thus, it only returns range entries that are valid /// and already adjusted for the base address. #[derive(Debug)] -pub struct RngListIter { +pub struct RngListIter::Offset> { raw: RawRngListIter, base_address: u64, debug_addr: DebugAddr, - debug_addr_base: DebugAddrBase, + debug_addr_base: DebugAddrBase, } impl RngListIter { diff --git a/src/read/unit.rs b/src/read/unit.rs index 7c20ecea..65d9a530 100644 --- a/src/read/unit.rs +++ b/src/read/unit.rs @@ -1121,10 +1121,14 @@ where /// An attribute in a `DebuggingInformationEntry`, consisting of a name and /// associated value. #[derive(Copy, Clone, Debug, Eq, PartialEq)] -pub struct Attribute { +pub struct Attribute::Offset> +where + R: Reader, + Offset: ReaderOffset, +{ name: constants::DwAt, form: constants::DwForm, - value: AttributeValue, + value: AttributeValue, } impl Attribute { @@ -2330,14 +2334,15 @@ pub(crate) fn skip_attributes( /// # } /// ``` #[derive(Clone, Debug)] -pub struct EntriesRaw<'abbrev, R> +pub struct EntriesRaw<'abbrev, R, Offset = ::Offset> where - R: Reader, + R: Reader, + Offset: ReaderOffset, { input: R, encoding: Encoding, abbreviations: &'abbrev Abbreviations, - end_offset: UnitOffset, + end_offset: UnitOffset, depth: isize, } @@ -2506,12 +2511,13 @@ impl<'abbrev, R: Reader> EntriesRaw<'abbrev, R> { /// to read entries at a specific depth, such as moving to the first child prior to using /// [`Self::next_sibling`]. #[derive(Clone, Debug)] -pub struct EntriesCursor<'abbrev, R> +pub struct EntriesCursor<'abbrev, R, Offset = ::Offset> where - R: Reader, + R: Reader, + Offset: ReaderOffset, { - input: EntriesRaw<'abbrev, R>, - cached_current: DebuggingInformationEntry, + input: EntriesRaw<'abbrev, R, Offset>, + cached_current: DebuggingInformationEntry, } impl<'abbrev, R: Reader> EntriesCursor<'abbrev, R> { @@ -2874,12 +2880,13 @@ impl<'abbrev, R: Reader> EntriesCursor<'abbrev, R> { /// } /// ``` #[derive(Clone, Debug)] -pub struct EntriesTree<'abbrev, R> +pub struct EntriesTree<'abbrev, R, Offset = ::Offset> where - R: Reader, + R: Reader, + Offset: ReaderOffset, { root: R, - input: EntriesRaw<'abbrev, R>, + input: EntriesRaw<'abbrev, R, Offset>, entry: DebuggingInformationEntry, } @@ -2970,7 +2977,11 @@ impl<'abbrev, R: Reader> EntriesTree<'abbrev, R> { /// The root node of a tree can be obtained /// via [`EntriesTree::root`](./struct.EntriesTree.html#method.root). #[derive(Debug)] -pub struct EntriesTreeNode<'abbrev, 'tree, R: Reader> { +pub struct EntriesTreeNode<'abbrev, 'tree, R, Offset = ::Offset> +where + R: Reader, + Offset: ReaderOffset, +{ tree: &'tree mut EntriesTree<'abbrev, R>, depth: isize, } @@ -3005,8 +3016,12 @@ impl<'abbrev, 'tree, R: Reader> EntriesTreeNode<'abbrev, 'tree, R> { /// The items returned by this iterator are also `EntriesTreeNode`s, /// which allow recursive traversal of grandchildren, etc. #[derive(Debug)] -pub struct EntriesTreeIter<'abbrev, 'tree, R: Reader> { - tree: &'tree mut EntriesTree<'abbrev, R>, +pub struct EntriesTreeIter<'abbrev, 'tree, R, Offset = ::Offset> +where + R: Reader, + Offset: ReaderOffset, +{ + tree: &'tree mut EntriesTree<'abbrev, R, Offset>, depth: isize, empty: bool, } diff --git a/src/write/cfi.rs b/src/write/cfi.rs index 8d11b112..a7124282 100644 --- a/src/write/cfi.rs +++ b/src/write/cfi.rs @@ -614,7 +614,7 @@ pub(crate) mod convert { ) -> ConvertResult where R: Reader, - Section: read::UnwindSection, + Section: read::UnwindSection, Section::Offset: read::UnwindOffset, { let bases = read::BaseAddresses::default().set_eh_frame(0); @@ -660,7 +660,7 @@ pub(crate) mod convert { ) -> ConvertResult where R: Reader, - Section: read::UnwindSection, + Section: read::UnwindSection, Section::Offset: read::UnwindOffset, { let mut cie = CommonInformationEntry::new( @@ -712,7 +712,7 @@ pub(crate) mod convert { ) -> ConvertResult where R: Reader, - Section: read::UnwindSection, + Section: read::UnwindSection, Section::Offset: read::UnwindOffset, { let address = @@ -759,7 +759,7 @@ pub(crate) mod convert { ) -> ConvertResult> where R: Reader, - Section: read::UnwindSection, + Section: read::UnwindSection, { let convert_expression = |x| { Expression::from( diff --git a/src/write/line.rs b/src/write/line.rs index 3a861996..6802555a 100644 --- a/src/write/line.rs +++ b/src/write/line.rs @@ -1037,7 +1037,7 @@ pub use convert::*; #[cfg(feature = "read")] mod convert { use super::*; - use crate::read::{self, Reader}; + use crate::read::{self, Reader, ReaderOffset}; use crate::write::{self, ConvertError, ConvertResult}; /// The result of [`ConvertLineProgram::read_row`]. @@ -1151,9 +1151,13 @@ mod convert { /// # } /// ``` #[derive(Debug)] - pub struct ConvertLineProgram<'a, R: Reader> { + pub struct ConvertLineProgram<'a, R, Offset = ::Offset> + where + R: Reader, + Offset: ReaderOffset, + { from_dwarf: &'a read::Dwarf, - from_program: read::IncompleteLineProgram, + from_program: read::IncompleteLineProgram, from_row: read::LineRow, from_instructions: read::LineInstructions, files: Vec,