Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 10 additions & 7 deletions crates/examples/src/bin/convert.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<Offset = usize> + fmt::Debug {}
impl<T: gimli::Reader<Offset = usize> + fmt::Debug> Reader for T {}

fn main() -> Result<(), Box<dyn error::Error>> {
let mut args = env::args_os();
Expand Down Expand Up @@ -126,7 +129,7 @@ fn main() -> Result<(), Box<dyn error::Error>> {
Ok(())
}

fn convert_dwarf<R: gimli::Reader<Offset = usize>, W: gimli::write::Writer>(
fn convert_dwarf<R: Reader, W: gimli::write::Writer>(
read_dwarf: &gimli::Dwarf<R>,
dwp: Option<&gimli::DwarfPackage<R>>,
write_sections: &mut gimli::write::Sections<W>,
Expand Down Expand Up @@ -169,7 +172,7 @@ fn convert_dwarf<R: gimli::Reader<Offset = usize>, W: gimli::write::Writer>(
Ok(())
}

fn convert_unit<'a, R: gimli::Reader<Offset = usize>, 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>>,
Expand Down Expand Up @@ -210,7 +213,7 @@ fn convert_unit<'a, R: gimli::Reader<Offset = usize>, W: gimli::write::Writer>(
Ok(())
}

fn convert_attributes<R: gimli::Reader<Offset = usize>>(
fn convert_attributes<R: Reader>(
unit: &mut gimli::write::ConvertUnit<'_, R>,
id: gimli::write::UnitEntryId,
entry: &gimli::write::ConvertUnitEntry<'_, R>,
Expand All @@ -234,7 +237,7 @@ fn convert_attributes<R: gimli::Reader<Offset = usize>>(
}
}

fn filter_dwarf<R: gimli::Reader<Offset = usize>>(
fn filter_dwarf<R: Reader>(
dwarf: &gimli::read::Dwarf<R>,
) -> gimli::write::ConvertResult<gimli::write::FilterUnitSection<'_, R>> {
// Walk the DIE tree. This will automatically record relationships between DIEs based
Expand All @@ -256,7 +259,7 @@ fn filter_dwarf<R: gimli::Reader<Offset = usize>>(
}

/// Use heuristics to determine if an entry is dead code.
fn need_entry<R: gimli::Reader<Offset = usize>>(
fn need_entry<R: Reader>(
entry: &gimli::write::FilterUnitEntry<'_, R>,
) -> gimli::write::ConvertResult<bool> {
match entry.parent_tag {
Expand Down Expand Up @@ -371,7 +374,7 @@ fn need_entry<R: gimli::Reader<Offset = usize>>(
Ok(false)
}

fn is_tombstone_address<R: gimli::Reader<Offset = usize>>(
fn is_tombstone_address<R: Reader>(
entry: &gimli::write::FilterUnitEntry<'_, R>,
address: u64,
) -> bool {
Expand Down
57 changes: 23 additions & 34 deletions crates/examples/src/bin/dwarfdump.rs
Original file line number Diff line number Diff line change
Expand Up @@ -197,7 +197,6 @@ struct Flags<'a> {
dwp: bool,
dwo_parent: Option<object::File<'a>>,
sup: Option<object::File<'a>>,
raw: bool,
info_offset: Option<gimli::DebugInfoOffset>,
match_units: Option<Regex>,
}
Expand Down Expand Up @@ -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",
Expand Down Expand Up @@ -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.
Expand Down Expand Up @@ -1241,25 +1236,19 @@ fn dump_entries<R: Reader, W: Write>(
} 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);
}
}
}
Expand Down Expand Up @@ -1299,18 +1288,18 @@ fn dump_attr_value<R: Reader, W: Write>(
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 => {
Expand Down Expand Up @@ -2158,7 +2147,7 @@ fn dump_line_program<R: Reader, W: Write>(w: &mut W, unit: gimli::UnitRef<R>) ->
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) => {
Expand Down
75 changes: 47 additions & 28 deletions src/read/cfi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -565,7 +565,7 @@ pub enum CieOffsetEncoding {
/// An offset into an `UnwindSection`.
//
// Needed to avoid conflicting implementations of `Into<T>`.
pub trait UnwindOffset<T = usize>: Copy + Debug + Eq + From<T>
pub trait UnwindOffset<T = usize>: Copy + Eq + From<T>
where
T: ReaderOffset,
{
Expand Down Expand Up @@ -632,10 +632,14 @@ pub trait _UnwindSectionPrivate<R: Reader> {
/// 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<R: Reader>: Clone + Debug + _UnwindSectionPrivate<R> {
pub trait UnwindSection<R, O = <R as Reader>::Offset>: Clone + _UnwindSectionPrivate<R>
where
R: Reader<Offset = O>,
O: ReaderOffset,
{
/// The offset type associated with this CFI section. Either
/// `DebugFrameOffset` or `EhFrameOffset`.
type Offset: UnwindOffset<R::Offset>;
type Offset: UnwindOffset<O>;

/// Iterate over the `CommonInformationEntry`s and `FrameDescriptionEntry`s
/// in this `.debug_frame` section.
Expand Down Expand Up @@ -989,10 +993,11 @@ impl BaseAddresses {
/// # }
/// ```
#[derive(Clone, Debug)]
pub struct CfiEntriesIter<'bases, Section, R>
pub struct CfiEntriesIter<'bases, Section, R, Offset = <R as Reader>::Offset>
where
R: Reader,
Section: UnwindSection<R>,
R: Reader<Offset = Offset>,
Offset: ReaderOffset,
Section: UnwindSection<R, Offset>,
{
section: Section,
bases: &'bases BaseAddresses,
Expand Down Expand Up @@ -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<R>,
pub enum CieOrFde<
'bases,
Section,
R,
Offset = <R as Reader>::Offset,
SectionOffset = <Section as UnwindSection<R, Offset>>::Offset,
> where
R: Reader<Offset = Offset>,
Offset: ReaderOffset,
Section: UnwindSection<R, Offset, Offset = SectionOffset>,
SectionOffset: UnwindOffset<Offset>,
{
/// This CFI entry is a `CommonInformationEntry`.
Cie(CommonInformationEntry<R>),
Cie(CommonInformationEntry<R, Offset>),
/// 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>(
Expand Down Expand Up @@ -1520,15 +1532,22 @@ impl<R: Reader> CommonInformationEntry<R> {
///
/// 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<R>,
pub struct PartialFrameDescriptionEntry<
'bases,
Section,
R,
Offset = <R as Reader>::Offset,
SectionOffset = <Section as UnwindSection<R, Offset>>::Offset,
> where
R: Reader<Offset = Offset>,
Offset: ReaderOffset,
Section: UnwindSection<R, Offset, Offset = SectionOffset>,
SectionOffset: UnwindOffset<Offset>,
{
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,
Expand Down Expand Up @@ -1973,7 +1992,7 @@ where

impl<T, S> Debug for UnwindContext<T, S>
where
T: ReaderOffset,
T: ReaderOffset + Debug,
S: UnwindContextStorage<T>,
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
Expand Down Expand Up @@ -2537,7 +2556,7 @@ where

impl<T, S> Debug for RegisterRuleMap<T, S>
where
T: ReaderOffset,
T: ReaderOffset + Debug,
S: UnwindContextStorage<T>,
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
Expand Down Expand Up @@ -2710,7 +2729,7 @@ where

impl<T, S> Debug for UnwindTableRow<T, S>
where
T: ReaderOffset,
T: ReaderOffset + Debug,
S: UnwindContextStorage<T>,
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
Expand Down Expand Up @@ -3743,7 +3762,7 @@ mod tests {
fn endian<'input, E>(self) -> Endian
where
E: Endianity,
T: UnwindSection<EndianSlice<'input, E>>,
T: UnwindSection<EndianSlice<'input, E>, usize>,
T::Offset: UnwindOffset<usize>,
{
if E::default().is_big_endian() {
Expand All @@ -3756,7 +3775,7 @@ mod tests {
fn section<'input, E>(self, contents: &'input [u8]) -> T
where
E: Endianity,
T: UnwindSection<EndianSlice<'input, E>> + ReadSection<EndianSlice<'input, E>>,
T: UnwindSection<EndianSlice<'input, E>, usize> + ReadSection<EndianSlice<'input, E>>,
T::Offset: UnwindOffset<usize>,
{
EndianSlice::new(contents, E::default()).into()
Expand Down Expand Up @@ -3805,7 +3824,7 @@ mod tests {
) -> Self
where
E: Endianity,
T: UnwindSection<EndianSlice<'input, E>>,
T: UnwindSection<EndianSlice<'input, E>, usize>,
T::Offset: UnwindOffset;
fn fde<'a, 'input, E, T, L>(
self,
Expand All @@ -3815,7 +3834,7 @@ mod tests {
) -> Self
where
E: Endianity,
T: UnwindSection<EndianSlice<'input, E>>,
T: UnwindSection<EndianSlice<'input, E>, usize>,
T::Offset: UnwindOffset,
L: ToLabelOrNum<'a, u64>;
}
Expand All @@ -3829,7 +3848,7 @@ mod tests {
) -> Self
where
E: Endianity,
T: UnwindSection<EndianSlice<'input, E>>,
T: UnwindSection<EndianSlice<'input, E>, usize>,
T::Offset: UnwindOffset,
{
cie.offset = self.size() as _;
Expand Down Expand Up @@ -3881,7 +3900,7 @@ mod tests {
) -> Self
where
E: Endianity,
T: UnwindSection<EndianSlice<'input, E>>,
T: UnwindSection<EndianSlice<'input, E>, usize>,
T::Offset: UnwindOffset,
L: ToLabelOrNum<'a, u64>,
{
Expand Down
8 changes: 4 additions & 4 deletions src/read/dwarf.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1425,7 +1425,7 @@ pub struct UnitRef<'a, R: Reader> {
pub dwarf: &'a Dwarf<R>,

/// The `Unit` being referenced.
pub unit: &'a Unit<R>,
pub unit: &'a Unit<R, R::Offset>,
}

impl<'a, R: Reader> Clone for UnitRef<'a, R> {
Expand Down Expand Up @@ -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<R: Reader>(RangeIterInner<R>);
pub struct RangeIter<R: Reader, Offset = <R as Reader>::Offset>(RangeIterInner<R, Offset>);

#[derive(Debug)]
enum RangeIterInner<R: Reader> {
enum RangeIterInner<R: Reader, Offset = <R as Reader>::Offset> {
Single(Option<Range>),
List(RngListIter<R>),
List(RngListIter<R, Offset>),
}

impl<R: Reader> Default for RangeIter<R> {
Expand Down
Loading