Skip to content

Commit

Permalink
Use gimli::UnitRef
Browse files Browse the repository at this point in the history
Switch over to using gimli::UnitRef as a replacement for the various
gimli::Unit & Units tuples that we pass around. We still need Units in
some places, but we can now remove its dwarf() method, which exposed a
gimli::Dwarf object, which may be problematic in the context of split
DWARF support.

Signed-off-by: Daniel Müller <[email protected]>
  • Loading branch information
d-e-s-o authored and danielocfb committed Jun 18, 2024
1 parent 82d8de1 commit a88bcf5
Show file tree
Hide file tree
Showing 6 changed files with 64 additions and 65 deletions.
50 changes: 22 additions & 28 deletions src/dwarf/function.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ use super::units::Units;


fn name_entry<'dwarf>(
unit: &gimli::Unit<R<'dwarf>>,
unit: gimli::UnitRef<'_, R<'dwarf>>,
offset: gimli::UnitOffset<<R<'_> as gimli::Reader>::Offset>,
units: &Units<'dwarf>,
recursion_limit: usize,
Expand All @@ -59,12 +59,12 @@ fn name_entry<'dwarf>(
match entries.read_attribute(*spec) {
Ok(ref attr) => match attr.name() {
gimli::DW_AT_linkage_name | gimli::DW_AT_MIPS_linkage_name => {
if let Ok(val) = units.dwarf().attr_string(unit, attr.value()) {
if let Ok(val) = unit.attr_string(attr.value()) {
return Ok(Some(val))
}
}
gimli::DW_AT_name => {
if let Ok(val) = units.dwarf().attr_string(unit, attr.value()) {
if let Ok(val) = unit.attr_string(attr.value()) {
name = Some(val);
}
}
Expand All @@ -91,7 +91,7 @@ fn name_entry<'dwarf>(

fn name_attr<'dwarf>(
attr: gimli::AttributeValue<R>,
unit: &gimli::Unit<R<'dwarf>>,
unit: gimli::UnitRef<'_, R<'dwarf>>,
units: &Units<'dwarf>,
recursion_limit: usize,
) -> Result<Option<R<'dwarf>>, Error> {
Expand Down Expand Up @@ -139,7 +139,7 @@ pub(super) struct InlinedFunctions<'dwarf> {
impl<'dwarf> InlinedFunctions<'dwarf> {
pub(crate) fn parse(
dw_die_offset: gimli::UnitOffset<<R<'dwarf> as gimli::Reader>::Offset>,
unit: &gimli::Unit<R<'dwarf>>,
unit: gimli::UnitRef<'_, R<'dwarf>>,
units: &Units<'dwarf>,
) -> Result<Self, Error> {
let mut entries = unit.entries_raw(Some(dw_die_offset))?;
Expand Down Expand Up @@ -283,7 +283,7 @@ pub(crate) struct Functions<'dwarf> {

impl<'dwarf> Functions<'dwarf> {
pub(crate) fn parse(
unit: &gimli::Unit<R<'dwarf>>,
unit: gimli::UnitRef<'_, R<'dwarf>>,
units: &Units<'dwarf>,
) -> Result<Self, Error> {
let mut functions = Vec::new();
Expand All @@ -300,16 +300,13 @@ impl<'dwarf> Functions<'dwarf> {
Ok(ref attr) => {
match attr.name() {
gimli::DW_AT_linkage_name | gimli::DW_AT_MIPS_linkage_name => {
if let Ok(val) =
units.dwarf().attr_string(unit, attr.value())
{
if let Ok(val) = unit.attr_string(attr.value()) {
name = Some(val);
}
}
gimli::DW_AT_name => {
if name.is_none() {
name =
units.dwarf().attr_string(unit, attr.value()).ok();
name = unit.attr_string(attr.value()).ok();
}
}
gimli::DW_AT_abstract_origin | gimli::DW_AT_specification => {
Expand All @@ -322,8 +319,7 @@ impl<'dwarf> Functions<'dwarf> {
ranges.low_pc = Some(val)
}
gimli::AttributeValue::DebugAddrIndex(index) => {
ranges.low_pc =
Some(units.dwarf().address(unit, index)?);
ranges.low_pc = Some(unit.address(index)?);
}
_ => {}
},
Expand All @@ -332,8 +328,7 @@ impl<'dwarf> Functions<'dwarf> {
ranges.high_pc = Some(val)
}
gimli::AttributeValue::DebugAddrIndex(index) => {
ranges.high_pc =
Some(units.dwarf().address(unit, index)?);
ranges.high_pc = Some(unit.address(index)?);
}
gimli::AttributeValue::Udata(val) => {
ranges.size = Some(val)
Expand All @@ -342,7 +337,7 @@ impl<'dwarf> Functions<'dwarf> {
},
gimli::DW_AT_ranges => {
ranges.ranges_offset =
units.dwarf().attr_ranges_offset(unit, attr.value())?;
unit.attr_ranges_offset(attr.value())?;
}
_ => {}
};
Expand All @@ -352,7 +347,7 @@ impl<'dwarf> Functions<'dwarf> {
}

let function_index = functions.len();
let added = ranges.for_each_range(units.dwarf(), unit, |range| {
let added = ranges.for_each_range(unit, |range| {
addresses.push(FunctionAddress {
range,
function: function_index,
Expand Down Expand Up @@ -394,7 +389,7 @@ impl<'dwarf> Functions<'dwarf> {
#[cfg(feature = "nightly")]
pub(crate) fn parse_inlined_functions(
&self,
unit: &gimli::Unit<R<'dwarf>>,
unit: gimli::UnitRef<'_, R<'dwarf>>,
units: &Units<'dwarf>,
) -> Result<(), Error> {
for function in &*self.functions {
Expand Down Expand Up @@ -422,7 +417,7 @@ impl<'dwarf> Function<'dwarf> {
fn parse_children(
entries: &mut gimli::EntriesRaw<'_, '_, R<'dwarf>>,
depth: isize,
unit: &gimli::Unit<R<'dwarf>>,
unit: gimli::UnitRef<'_, R<'dwarf>>,
units: &Units<'dwarf>,
inlined_functions: &mut Vec<InlinedFunction<'dwarf>>,
inlined_addresses: &mut Vec<InlinedFunctionAddress>,
Expand Down Expand Up @@ -460,7 +455,7 @@ impl<'dwarf> Function<'dwarf> {

pub(super) fn parse_inlined_functions(
&self,
unit: &gimli::Unit<R<'dwarf>>,
unit: gimli::UnitRef<'_, R<'dwarf>>,
units: &Units<'dwarf>,
) -> Result<&InlinedFunctions<'dwarf>, Error> {
self.inlined_functions
Expand Down Expand Up @@ -490,7 +485,7 @@ impl<'dwarf> InlinedFunction<'dwarf> {
entries: &mut gimli::EntriesRaw<'_, '_, R<'dwarf>>,
abbrev: &gimli::Abbreviation,
depth: isize,
unit: &gimli::Unit<R<'dwarf>>,
unit: gimli::UnitRef<'_, R<'dwarf>>,
units: &Units<'dwarf>,
inlined_functions: &mut Vec<InlinedFunction<'dwarf>>,
inlined_addresses: &mut Vec<InlinedFunctionAddress>,
Expand All @@ -507,30 +502,29 @@ impl<'dwarf> InlinedFunction<'dwarf> {
gimli::DW_AT_low_pc => match attr.value() {
gimli::AttributeValue::Addr(val) => ranges.low_pc = Some(val),
gimli::AttributeValue::DebugAddrIndex(index) => {
ranges.low_pc = Some(units.dwarf().address(unit, index)?);
ranges.low_pc = Some(unit.address(index)?);
}
_ => {}
},
gimli::DW_AT_high_pc => match attr.value() {
gimli::AttributeValue::Addr(val) => ranges.high_pc = Some(val),
gimli::AttributeValue::DebugAddrIndex(index) => {
ranges.high_pc = Some(units.dwarf().address(unit, index)?);
ranges.high_pc = Some(unit.address(index)?);
}
gimli::AttributeValue::Udata(val) => ranges.size = Some(val),
_ => {}
},
gimli::DW_AT_ranges => {
ranges.ranges_offset =
units.dwarf().attr_ranges_offset(unit, attr.value())?;
ranges.ranges_offset = unit.attr_ranges_offset(attr.value())?;
}
gimli::DW_AT_linkage_name | gimli::DW_AT_MIPS_linkage_name => {
if let Ok(val) = units.dwarf().attr_string(unit, attr.value()) {
if let Ok(val) = unit.attr_string(attr.value()) {
name = Some(val);
}
}
gimli::DW_AT_name => {
if name.is_none() {
name = units.dwarf().attr_string(unit, attr.value()).ok();
name = unit.attr_string(attr.value()).ok();
}
}
gimli::DW_AT_abstract_origin | gimli::DW_AT_specification => {
Expand Down Expand Up @@ -576,7 +570,7 @@ impl<'dwarf> InlinedFunction<'dwarf> {
call_column,
});

ranges.for_each_range(units.dwarf(), unit, |range| {
ranges.for_each_range(unit, |range| {
inlined_addresses.push(InlinedFunctionAddress {
range,
call_depth: inlined_depth,
Expand Down
16 changes: 7 additions & 9 deletions src/dwarf/lines.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,12 +46,11 @@ fn path_push<'p>(path: &'p Path, p: &'p Path) -> Cow<'p, Path> {
}

fn render_file<'dwarf>(
dw_unit: &gimli::Unit<R<'dwarf>>,
unit: gimli::UnitRef<'_, R<'dwarf>>,
file: &gimli::FileEntry<R<'dwarf>, <R<'dwarf> as gimli::Reader>::Offset>,
header: &gimli::LineProgramHeader<R<'dwarf>, <R<'dwarf> as gimli::Reader>::Offset>,
sections: &gimli::Dwarf<R<'dwarf>>,
) -> Result<(Cow<'dwarf, Path>, &'dwarf OsStr), gimli::Error> {
let dir = if let Some(ref comp_dir) = dw_unit.comp_dir {
let dir = if let Some(ref comp_dir) = unit.comp_dir {
Path::new(OsStr::from_bytes(comp_dir.slice()))
} else {
Path::new("")
Expand All @@ -61,7 +60,7 @@ fn render_file<'dwarf>(
// directory.
let dir = if file.directory_index() != 0 {
if let Some(directory) = file.directory(header) {
let d = sections.attr_string(dw_unit, directory)?;
let d = unit.attr_string(directory)?;
path_push(dir, Path::new(OsStr::from_bytes(d.slice())))
} else {
Cow::default()
Expand All @@ -70,7 +69,7 @@ fn render_file<'dwarf>(
Cow::default()
};

let f = sections.attr_string(dw_unit, file.path_name())?;
let f = unit.attr_string(file.path_name())?;
let file = OsStr::from_bytes(f.slice());
Ok((dir, file))
}
Expand All @@ -96,9 +95,8 @@ pub(crate) struct Lines<'dwarf> {

impl<'dwarf> Lines<'dwarf> {
pub(crate) fn parse(
dw_unit: &gimli::Unit<R<'dwarf>>,
unit: gimli::UnitRef<'_, R<'dwarf>>,
ilnp: gimli::IncompleteLineProgram<R<'dwarf>, <R<'dwarf> as gimli::Reader>::Offset>,
sections: &gimli::Dwarf<R<'dwarf>>,
) -> Result<Self, gimli::Error> {
let mut sequences = Vec::new();
let mut sequence_rows = Vec::<LineRow>::new();
Expand Down Expand Up @@ -147,12 +145,12 @@ impl<'dwarf> Lines<'dwarf> {
let mut files = Vec::new();
let header = rows.header();
match header.file(0) {
Some(file) => files.push(render_file(dw_unit, file, header, sections)?),
Some(file) => files.push(render_file(unit, file, header)?),
None => files.push(Default::default()), // DWARF version <= 4 may not have 0th index
}
let mut index = 1;
while let Some(file) = header.file(index) {
files.push(render_file(dw_unit, file, header, sections)?);
files.push(render_file(unit, file, header)?);
index += 1;
}

Expand Down
3 changes: 2 additions & 1 deletion src/dwarf/location.rs
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,8 @@ impl<'unit, 'dwarf> LocationRangeUnitIter<'unit, 'dwarf> {
probe_low: u64,
probe_high: u64,
) -> Result<Option<Self>, gimli::Error> {
let lines = unit.parse_lines(units)?;
let unit_ref = units.unit_ref(unit.dw_unit());
let lines = unit.parse_lines(unit_ref)?;

if let Some(lines) = lines {
// Find index for probe_low.
Expand Down
5 changes: 2 additions & 3 deletions src/dwarf/range.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,7 @@ impl<R: gimli::Reader> Default for RangeAttributes<R> {
impl<R: gimli::Reader> RangeAttributes<R> {
pub(crate) fn for_each_range<F: FnMut(gimli::Range)>(
&self,
sections: &gimli::Dwarf<R>,
unit: &gimli::Unit<R>,
unit: gimli::UnitRef<'_, R>,
mut f: F,
) -> Result<bool, gimli::Error> {
let mut added_any = false;
Expand All @@ -59,7 +58,7 @@ impl<R: gimli::Reader> RangeAttributes<R> {
}
};
if let Some(ranges_offset) = self.ranges_offset {
let mut range_list = sections.ranges(unit, ranges_offset)?;
let mut range_list = unit.ranges(ranges_offset)?;
while let Some(range) = range_list.next()? {
add_range(range);
}
Expand Down
17 changes: 8 additions & 9 deletions src/dwarf/unit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ impl<'dwarf> Unit<'dwarf> {
&'unit self,
units: &Units<'dwarf>,
) -> Result<&'unit Functions<'dwarf>, gimli::Error> {
let unit = &self.dw_unit;
let unit = units.unit_ref(&self.dw_unit);
let functions = self.parse_functions_dwarf_and_unit(unit, units)?;
Ok(functions)
}
Expand All @@ -84,9 +84,8 @@ impl<'dwarf> Unit<'dwarf> {
&'unit self,
units: &Units<'dwarf>,
) -> Result<&'unit Functions<'dwarf>, gimli::Error> {
let unit = &self.dw_unit;

self.funcs.get_or_try_init(|| {
let unit = units.unit_ref(&self.dw_unit);
let funcs = Functions::parse(unit, units)?;
let () = funcs.parse_inlined_functions(unit, units)?;
Ok(funcs)
Expand All @@ -95,16 +94,16 @@ impl<'dwarf> Unit<'dwarf> {

pub(super) fn parse_lines(
&self,
units: &Units<'dwarf>,
unit: gimli::UnitRef<'_, R<'dwarf>>,
) -> Result<Option<&Lines<'dwarf>>, gimli::Error> {
// NB: line information is always stored in the main debug file so this does not
// need to handle DWOs.
let ilnp = match self.dw_unit.line_program {
let ilnp = match unit.unit.line_program {
Some(ref ilnp) => ilnp,
None => return Ok(None),
};
self.lines
.get_or_try_init(|| Lines::parse(&self.dw_unit, ilnp.clone(), units.dwarf()))
.get_or_try_init(|| Lines::parse(unit, ilnp.clone()))
.map(Some)
}

Expand All @@ -125,7 +124,7 @@ impl<'dwarf> Unit<'dwarf> {

fn parse_functions_dwarf_and_unit(
&self,
unit: &gimli::Unit<R<'dwarf>>,
unit: gimli::UnitRef<'_, R<'dwarf>>,
units: &Units<'dwarf>,
) -> Result<&Functions<'dwarf>, gimli::Error> {
self.funcs.get_or_try_init(|| Functions::parse(unit, units))
Expand All @@ -136,7 +135,7 @@ impl<'dwarf> Unit<'dwarf> {
probe: u64,
units: &Units<'dwarf>,
) -> Result<Option<&Function<'dwarf>>, gimli::Error> {
let unit = &self.dw_unit;
let unit = units.unit_ref(&self.dw_unit);
let functions = self.parse_functions_dwarf_and_unit(unit, units)?;
let function = match functions.find_address(probe) {
Some(address) => {
Expand All @@ -154,7 +153,7 @@ impl<'dwarf> Unit<'dwarf> {
name: &str,
units: &Units<'dwarf>,
) -> Result<Option<&'slf Function<'dwarf>>, gimli::Error> {
let unit = &self.dw_unit;
let unit = units.unit_ref(&self.dw_unit);
let functions = self.parse_functions_dwarf_and_unit(unit, units)?;
for func in functions.functions.iter() {
let name = Some(name.as_bytes());
Expand Down
Loading

0 comments on commit a88bcf5

Please sign in to comment.