Skip to content

Commit

Permalink
Fix clippy warnings
Browse files Browse the repository at this point in the history
  • Loading branch information
philipc committed Apr 15, 2024
1 parent 52ee0a1 commit f90174e
Show file tree
Hide file tree
Showing 7 changed files with 84 additions and 88 deletions.
8 changes: 4 additions & 4 deletions benches/bench.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,23 +26,23 @@ fn with_file<F: FnOnce(&object::File<'_>)>(target: &path::Path, f: F) {
f(&file)
}

fn dwarf_load<'a>(object: &object::File<'a>) -> gimli::Dwarf<Cow<'a, [u8]>> {
fn dwarf_load<'a>(object: &object::File<'a>) -> gimli::DwarfSections<Cow<'a, [u8]>> {
let load_section = |id: gimli::SectionId| -> Result<Cow<'a, [u8]>, gimli::Error> {
Ok(object
.section_by_name(id.name())
.map(|section| section.uncompressed_data().unwrap())
.unwrap_or(Cow::Borrowed(&[][..])))
};
gimli::Dwarf::load(&load_section).unwrap()
gimli::DwarfSections::load(&load_section).unwrap()
}

fn dwarf_borrow<'a>(
dwarf: &'a gimli::Dwarf<Cow<'_, [u8]>>,
dwarf: &'a gimli::DwarfSections<Cow<'_, [u8]>>,
) -> gimli::Dwarf<gimli::EndianSlice<'a, gimli::LittleEndian>> {
let borrow_section: &dyn for<'b> Fn(
&'b Cow<'_, [u8]>,
) -> gimli::EndianSlice<'b, gimli::LittleEndian> =
&|section| gimli::EndianSlice::new(&*section, gimli::LittleEndian);
&|section| gimli::EndianSlice::new(section, gimli::LittleEndian);
dwarf.borrow(&borrow_section)
}

Expand Down
1 change: 1 addition & 0 deletions src/frame.rs
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ where
}

/// Advances the iterator and returns the next frame.
#[allow(clippy::should_implement_trait)]
pub fn next(&mut self) -> Result<Option<Frame<'ctx, R>>, Error> {
let frames = match &mut self.0 {
FrameIterState::Empty => return Ok(None),
Expand Down
110 changes: 46 additions & 64 deletions src/function.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,14 @@ use alloc::boxed::Box;
use alloc::vec::Vec;
use core::cmp::Ordering;

use crate::lazy::LazyCell;
use crate::lazy::LazyResult;
use crate::maybe_small;
use crate::{Context, DebugFile, Error, RangeAttributes};

pub(crate) struct Functions<R: gimli::Reader> {
/// List of all `DW_TAG_subprogram` details in the unit.
pub(crate) functions: Box<
[(
gimli::UnitOffset<R::Offset>,
LazyCell<Result<Function<R>, Error>>,
)],
>,
#[allow(clippy::type_complexity)]
pub(crate) functions: Box<[(gimli::UnitOffset<R::Offset>, LazyResult<Function<R>>)]>,
/// List of `DW_TAG_subprogram` address ranges in the unit.
pub(crate) addresses: Box<[FunctionAddress]>,
}
Expand Down Expand Up @@ -103,13 +99,14 @@ impl<R: gimli::Reader> Functions<R> {
}

let function_index = functions.len();
if ranges.for_each_range(sections, unit, |range| {
let has_address = ranges.for_each_range(sections, unit, |range| {
addresses.push(FunctionAddress {
range,
function: function_index,
});
})? {
functions.push((dw_die_offset, LazyCell::new()));
})?;
if has_address {
functions.push((dw_die_offset, LazyResult::new()));
}
} else {
entries.skip_attributes(abbrev.attributes())?;
Expand Down Expand Up @@ -205,19 +202,16 @@ impl<R: gimli::Reader> Function<R> {
}
}

let mut inlined_functions = Vec::new();
let mut inlined_addresses = Vec::new();
Function::parse_children(
&mut entries,
depth,
let mut state = InlinedState {
entries,
inlined_functions: Vec::new(),
inlined_addresses: Vec::new(),
file,
unit,
ctx,
sections,
&mut inlined_functions,
&mut inlined_addresses,
0,
)?;
};
Function::parse_children(&mut state, depth, 0)?;

// Sort ranges in "breadth-first traversal order", i.e. first by call_depth
// and then by range.begin. This allows finding the range containing an
Expand All @@ -229,7 +223,7 @@ impl<R: gimli::Reader> Function<R> {
// In this example, if you want to look up address 7 at depth 0, and you
// encounter [0..2 at depth 1], are you before or after the target range?
// You don't know.
inlined_addresses.sort_by(|r1, r2| {
state.inlined_addresses.sort_by(|r1, r2| {
if r1.call_depth < r2.call_depth {
Ordering::Less
} else if r1.call_depth > r2.call_depth {
Expand All @@ -246,50 +240,38 @@ impl<R: gimli::Reader> Function<R> {
Ok(Function {
dw_die_offset,
name,
inlined_functions: inlined_functions.into_boxed_slice(),
inlined_addresses: inlined_addresses.into_boxed_slice(),
inlined_functions: state.inlined_functions.into_boxed_slice(),
inlined_addresses: state.inlined_addresses.into_boxed_slice(),
})
}

fn parse_children(
entries: &mut gimli::EntriesRaw<'_, '_, R>,
state: &mut InlinedState<R>,
depth: isize,
file: DebugFile,
unit: &gimli::Unit<R>,
ctx: &Context<R>,
sections: &gimli::Dwarf<R>,
inlined_functions: &mut Vec<InlinedFunction<R>>,
inlined_addresses: &mut Vec<InlinedFunctionAddress>,
inlined_depth: usize,
) -> Result<(), Error> {
loop {
let dw_die_offset = entries.next_offset();
let next_depth = entries.next_depth();
let dw_die_offset = state.entries.next_offset();
let next_depth = state.entries.next_depth();
if next_depth <= depth {
return Ok(());
}
if let Some(abbrev) = entries.read_abbreviation()? {
if let Some(abbrev) = state.entries.read_abbreviation()? {
match abbrev.tag() {
gimli::DW_TAG_subprogram => {
Function::skip(entries, abbrev, next_depth)?;
Function::skip(&mut state.entries, abbrev, next_depth)?;
}
gimli::DW_TAG_inlined_subroutine => {
InlinedFunction::parse(
state,
dw_die_offset,
entries,
abbrev,
next_depth,
file,
unit,
ctx,
sections,
inlined_functions,
inlined_addresses,
inlined_depth,
)?;
}
_ => {
entries.skip_attributes(abbrev.attributes())?;
state.entries.skip_attributes(abbrev.attributes())?;
}
}
}
Expand Down Expand Up @@ -352,25 +334,21 @@ impl<R: gimli::Reader> Function<R> {

impl<R: gimli::Reader> InlinedFunction<R> {
fn parse(
state: &mut InlinedState<R>,
dw_die_offset: gimli::UnitOffset<R::Offset>,
entries: &mut gimli::EntriesRaw<'_, '_, R>,
abbrev: &gimli::Abbreviation,
depth: isize,
file: DebugFile,
unit: &gimli::Unit<R>,
ctx: &Context<R>,
sections: &gimli::Dwarf<R>,
inlined_functions: &mut Vec<InlinedFunction<R>>,
inlined_addresses: &mut Vec<InlinedFunctionAddress>,
inlined_depth: usize,
) -> Result<(), Error> {
let unit = state.unit;
let sections = state.sections;
let mut ranges = RangeAttributes::default();
let mut name = None;
let mut call_file = None;
let mut call_line = 0;
let mut call_column = 0;
for spec in abbrev.attributes() {
match entries.read_attribute(*spec) {
match state.entries.read_attribute(*spec) {
Ok(ref attr) => match attr.name() {
gimli::DW_AT_low_pc => match attr.value() {
gimli::AttributeValue::Addr(val) => ranges.low_pc = Some(val),
Expand Down Expand Up @@ -402,7 +380,8 @@ impl<R: gimli::Reader> InlinedFunction<R> {
}
gimli::DW_AT_abstract_origin | gimli::DW_AT_specification => {
if name.is_none() {
name = name_attr(attr.value(), file, unit, ctx, sections, 16)?;
name =
name_attr(attr.value(), state.file, unit, state.ctx, sections, 16)?;
}
}
gimli::DW_AT_call_file => {
Expand Down Expand Up @@ -433,8 +412,8 @@ impl<R: gimli::Reader> InlinedFunction<R> {
}
}

let function_index = inlined_functions.len();
inlined_functions.push(InlinedFunction {
let function_index = state.inlined_functions.len();
state.inlined_functions.push(InlinedFunction {
dw_die_offset,
name,
call_file,
Expand All @@ -443,27 +422,30 @@ impl<R: gimli::Reader> InlinedFunction<R> {
});

ranges.for_each_range(sections, unit, |range| {
inlined_addresses.push(InlinedFunctionAddress {
state.inlined_addresses.push(InlinedFunctionAddress {
range,
call_depth: inlined_depth,
function: function_index,
});
})?;

Function::parse_children(
entries,
depth,
file,
unit,
ctx,
sections,
inlined_functions,
inlined_addresses,
inlined_depth + 1,
)
Function::parse_children(state, depth, inlined_depth + 1)
}
}

struct InlinedState<'a, R: gimli::Reader> {
// Mutable fields.
entries: gimli::EntriesRaw<'a, 'a, R>,
inlined_functions: Vec<InlinedFunction<R>>,
inlined_addresses: Vec<InlinedFunctionAddress>,

// Constant fields.
file: DebugFile,
unit: &'a gimli::Unit<R>,
ctx: &'a Context<R>,
sections: &'a gimli::Dwarf<R>,
}

fn name_attr<R>(
attr: gimli::AttributeValue<R>,
mut file: DebugFile,
Expand Down
11 changes: 7 additions & 4 deletions src/lazy.rs
Original file line number Diff line number Diff line change
@@ -1,20 +1,23 @@
use core::cell::UnsafeCell;

pub struct LazyCell<T> {
pub(crate) type LazyResult<T> = LazyCell<Result<T, crate::Error>>;

pub(crate) struct LazyCell<T> {
contents: UnsafeCell<Option<T>>,
}

impl<T> LazyCell<T> {
pub fn new() -> LazyCell<T> {
pub(crate) fn new() -> LazyCell<T> {
LazyCell {
contents: UnsafeCell::new(None),
}
}

pub fn borrow(&self) -> Option<&T> {
pub(crate) fn borrow(&self) -> Option<&T> {
unsafe { &*self.contents.get() }.as_ref()
}

pub fn borrow_with(&self, closure: impl FnOnce() -> T) -> &T {
pub(crate) fn borrow_with(&self, closure: impl FnOnce() -> T) -> &T {
// First check if we're already initialized...
let ptr = self.contents.get();
if let Some(val) = unsafe { &*ptr } {
Expand Down
1 change: 1 addition & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,7 @@ impl<R: gimli::Reader> Context<R> {
/// Construct a new `Context` from DWARF sections.
///
/// This method does not support using a supplementary object file.
#[allow(clippy::too_many_arguments)]
pub fn from_sections(
debug_abbrev: gimli::DebugAbbrev<R>,
debug_addr: gimli::DebugAddr<R>,
Expand Down
Loading

0 comments on commit f90174e

Please sign in to comment.