Skip to content

Commit

Permalink
Add RawRangeListsOffset
Browse files Browse the repository at this point in the history
This allows us to distinguish offsets which may be relative
to `DW_AT_GNU_ranges_base`.
  • Loading branch information
philipc committed Jul 16, 2021
1 parent 7c13056 commit 1a2439a
Show file tree
Hide file tree
Showing 7 changed files with 39 additions and 25 deletions.
4 changes: 2 additions & 2 deletions benches/bench.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use gimli::{
AttributeValue, DebugAbbrev, DebugAddr, DebugAddrBase, DebugAranges, DebugInfo, DebugLine,
DebugLineOffset, DebugLoc, DebugLocLists, DebugPubNames, DebugPubTypes, DebugRanges,
DebugRngLists, Encoding, EndianSlice, EntriesTreeNode, Expression, LittleEndian, LocationLists,
Operation, RangeLists, Reader, ReaderOffset,
Operation, RangeLists, RangeListsOffset, Reader, ReaderOffset,
};
use std::env;
use std::fs::File;
Expand Down Expand Up @@ -384,7 +384,7 @@ fn bench_parsing_debug_ranges(b: &mut test::Bencher) {
let mut attrs = entry.attrs();
while let Some(attr) = attrs.next().expect("Should parse entry's attribute") {
if let gimli::AttributeValue::RangeListsRef(offset) = attr.value() {
offsets.push((offset, unit.encoding(), low_pc));
offsets.push((RangeListsOffset(offset.0), unit.encoding(), low_pc));
}
}
}
Expand Down
1 change: 1 addition & 0 deletions examples/dwarfdump.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1383,6 +1383,7 @@ fn dump_attr_value<R: Reader, W: Write>(
writeln!(w, "<.debug_macro+0x{:08x}>", offset.0)?;
}
gimli::AttributeValue::RangeListsRef(offset) => {
let offset = dwarf.ranges_offset_from_raw(unit, offset);
dump_range_list(w, offset, unit, dwarf)?;
}
gimli::AttributeValue::DebugRngListsBase(base) => {
Expand Down
8 changes: 8 additions & 0 deletions src/common.rs
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,14 @@ pub struct DebugMacinfoOffset<T = usize>(pub T);
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct DebugMacroOffset<T = usize>(pub T);

/// An offset into either the `.debug_ranges` section or the `.debug_rnglists` section,
/// depending on the version of the unit the offset was contained in.
///
/// If this is from a DWARF 4 DWO file, then it must additionally be offset by the
/// value of `DW_AT_GNU_ranges_base`. You can use `Dwarf::ranges_offset_from_raw` to do this.
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct RawRangeListsOffset<T = usize>(pub T);

/// An offset into either the `.debug_ranges` section or the `.debug_rnglists` section,
/// depending on the version of the unit the offset was contained in.
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
Expand Down
32 changes: 19 additions & 13 deletions src/read/dwarf.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use crate::common::{
DebugAddrBase, DebugAddrIndex, DebugInfoOffset, DebugLineStrOffset, DebugLocListsBase,
DebugLocListsIndex, DebugRngListsBase, DebugRngListsIndex, DebugStrOffset, DebugStrOffsetsBase,
DebugStrOffsetsIndex, DebugTypesOffset, DwarfFileType, Encoding, LocationListsOffset,
RangeListsOffset, SectionId, UnitSectionOffset,
RangeListsOffset, RawRangeListsOffset, SectionId, UnitSectionOffset,
};
use crate::constants;
use crate::read::{
Expand Down Expand Up @@ -281,6 +281,21 @@ impl<R: Reader> Dwarf<R> {
}
}

/// Return the range list offset for the given raw offset.
///
/// This handles adding `DW_AT_GNU_ranges_base` if required.
pub fn ranges_offset_from_raw(
&self,
unit: &Unit<R>,
offset: RawRangeListsOffset<R::Offset>,
) -> RangeListsOffset<R::Offset> {
if self.file_type == DwarfFileType::Dwo && unit.header.version() < 5 {
RangeListsOffset(offset.0.wrapping_add(unit.rnglists_base.0))
} else {
RangeListsOffset(offset.0)
}
}

/// Return the range list offset at the given index.
pub fn ranges_offset(
&self,
Expand All @@ -297,12 +312,6 @@ impl<R: Reader> Dwarf<R> {
unit: &Unit<R>,
offset: RangeListsOffset<R::Offset>,
) -> Result<RngListIter<R>> {
let offset = if self.file_type == DwarfFileType::Dwo && unit.header.version() < 5 {
RangeListsOffset(offset.0.wrapping_add(unit.rnglists_base.0))
} else {
offset
};

self.ranges.ranges(
offset,
unit.encoding(),
Expand All @@ -318,11 +327,6 @@ impl<R: Reader> Dwarf<R> {
unit: &Unit<R>,
offset: RangeListsOffset<R::Offset>,
) -> Result<RawRngListIter<R>> {
let offset = if self.file_type == DwarfFileType::Dwo && unit.header.version() < 5 {
RangeListsOffset(offset.0.wrapping_add(unit.rnglists_base.0))
} else {
offset
};
self.ranges.raw_ranges(offset, unit.encoding())
}

Expand All @@ -341,7 +345,9 @@ impl<R: Reader> Dwarf<R> {
attr: AttributeValue<R>,
) -> Result<Option<RangeListsOffset<R::Offset>>> {
match attr {
AttributeValue::RangeListsRef(offset) => Ok(Some(offset)),
AttributeValue::RangeListsRef(offset) => {
Ok(Some(self.ranges_offset_from_raw(unit, offset)))
}
AttributeValue::DebugRngListsIndex(index) => self.ranges_offset(unit, index).map(Some),
_ => Ok(None),
}
Expand Down
6 changes: 3 additions & 3 deletions src/read/unit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ use crate::common::{
DebugLineStrOffset, DebugLocListsBase, DebugLocListsIndex, DebugMacinfoOffset,
DebugMacroOffset, DebugRngListsBase, DebugRngListsIndex, DebugStrOffset, DebugStrOffsetsBase,
DebugStrOffsetsIndex, DebugTypeSignature, DebugTypesOffset, DwoId, Encoding, Format,
LocationListsOffset, RangeListsOffset, SectionId, UnitSectionOffset,
LocationListsOffset, RawRangeListsOffset, SectionId, UnitSectionOffset,
};
use crate::constants;
use crate::endianity::Endianity;
Expand Down Expand Up @@ -1044,7 +1044,7 @@ where
DebugMacroRef(DebugMacroOffset<Offset>),

/// An offset into the `.debug_ranges` section.
RangeListsRef(RangeListsOffset<Offset>),
RangeListsRef(RawRangeListsOffset<Offset>),

/// An offset to a set of offsets in the `.debug_rnglists` section.
DebugRngListsBase(DebugRngListsBase<Offset>),
Expand Down Expand Up @@ -1286,7 +1286,7 @@ impl<R: Reader> Attribute<R> {
() => {
// DebugRngListsIndex is also an allowed form in DWARF version 5.
if let Some(offset) = self.offset_value() {
return AttributeValue::RangeListsRef(RangeListsOffset(offset));
return AttributeValue::RangeListsRef(RawRangeListsOffset(offset));
}
};
}
Expand Down
8 changes: 3 additions & 5 deletions src/write/unit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1827,11 +1827,9 @@ pub(crate) mod convert {
let loc_id = context.locations.add(loc_list);
AttributeValue::LocationListRef(loc_id)
}
read::AttributeValue::RangeListsRef(val) => {
let iter = context
.dwarf
.ranges
.raw_ranges(val, context.unit.encoding())?;
read::AttributeValue::RangeListsRef(offset) => {
let offset = context.dwarf.ranges_offset_from_raw(context.unit, offset);
let iter = context.dwarf.raw_ranges(context.unit, offset)?;
let range_list = RangeList::from(iter, context)?;
let range_id = context.ranges.add(range_list);
AttributeValue::RangeListRef(range_id)
Expand Down
5 changes: 3 additions & 2 deletions tests/parse_self.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@
use gimli::{
AttributeValue, DebugAbbrev, DebugAddr, DebugAddrBase, DebugAranges, DebugInfo, DebugLine,
DebugLoc, DebugLocLists, DebugPubNames, DebugPubTypes, DebugRanges, DebugRngLists, DebugStr,
Encoding, EndianSlice, Expression, LittleEndian, LocationLists, Operation, RangeLists, Reader,
Encoding, EndianSlice, Expression, LittleEndian, LocationLists, Operation, RangeLists,
RangeListsOffset, Reader,
};
use std::collections::hash_map::HashMap;
use std::env;
Expand Down Expand Up @@ -274,7 +275,7 @@ fn test_parse_self_debug_ranges() {
if let AttributeValue::RangeListsRef(offset) = attr.value() {
let mut ranges = rnglists
.ranges(
offset,
RangeListsOffset(offset.0),
unit.encoding(),
low_pc,
&debug_addr,
Expand Down

0 comments on commit 1a2439a

Please sign in to comment.