Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merge CompilationUnitHeader and TypeUnitHeader, introduce UnitType. #523

Merged
merged 2 commits into from
Jul 5, 2020
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
21 changes: 9 additions & 12 deletions examples/dwarf-validate.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// Allow clippy lints when building without clippy.
#![allow(unknown_lints)]

use gimli::{AttributeValue, CompilationUnitHeader};
use gimli::{AttributeValue, UnitHeader};
use object::{Object, ObjectSection};
use rayon::prelude::*;
use std::borrow::{Borrow, Cow};
Expand Down Expand Up @@ -155,13 +155,14 @@ fn validate_info<W, R>(
Ok(None) => break,
Ok(Some(u)) => u,
};
last_offset = u.offset().0 + u.length_including_self();
last_offset = u.offset().as_debug_info_offset().unwrap().0 + u.length_including_self();
units.push(u);
}
let process_unit = |unit: CompilationUnitHeader<R>| -> UnitSummary {
let process_unit = |unit: UnitHeader<R>| -> UnitSummary {
let unit_offset = unit.offset().as_debug_info_offset().unwrap();
let mut ret = UnitSummary {
internally_valid: false,
offset: unit.offset(),
offset: unit_offset,
die_offsets: Vec::new(),
global_die_references: Vec::new(),
};
Expand All @@ -170,8 +171,7 @@ fn validate_info<W, R>(
Err(err) => {
w.error(format!(
"Invalid abbrevs for unit {:#x}: {}",
unit.offset().0,
&err
unit_offset.0, &err
));
return ret;
}
Expand All @@ -183,8 +183,7 @@ fn validate_info<W, R>(
Err(err) => {
w.error(format!(
"Invalid DIE for unit {:#x}: {}",
unit.offset().0,
&err
unit_offset.0, &err
));
return ret;
}
Expand All @@ -199,7 +198,7 @@ fn validate_info<W, R>(
Err(err) => {
w.error(format!(
"Invalid attribute for unit {:#x} at DIE {:#x}: {}",
unit.offset().0,
unit_offset.0,
entry.offset().0,
&err
));
Expand Down Expand Up @@ -228,9 +227,7 @@ fn validate_info<W, R>(
if ret.die_offsets.binary_search(&to).is_err() {
w.error(format!(
"Invalid intra-unit reference in unit {:#x} from DIE {:#x} to {:#x}",
unit.offset().0,
from.0,
to.0
unit_offset.0, from.0, to.0
));
}
}
Expand Down
23 changes: 15 additions & 8 deletions examples/dwarfdump.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
#![allow(unknown_lints)]

use fallible_iterator::FallibleIterator;
use gimli::{CompilationUnitHeader, Section, UnitOffset, UnitSectionOffset, UnwindSection};
use gimli::{Section, UnitHeader, UnitOffset, UnitSectionOffset, UnitType, UnwindSection};
use object::{Object, ObjectSection};
use regex::bytes::Regex;
use std::borrow::{Borrow, Cow};
Expand Down Expand Up @@ -920,11 +920,11 @@ where
return Ok(());
}
};
let process_unit = |header: CompilationUnitHeader<R>, buf: &mut Vec<u8>| -> Result<()> {
let process_unit = |header: UnitHeader<R>, buf: &mut Vec<u8>| -> Result<()> {
writeln!(
buf,
"\nUNIT<header overall offset = 0x{:08x}>:",
header.offset().0,
header.offset().as_debug_info_offset().unwrap().0,
)?;

let unit = match dwarf.unit(header) {
Expand Down Expand Up @@ -966,14 +966,21 @@ fn dump_types<R: Reader, W: Write>(
writeln!(
w,
"\nUNIT<header overall offset = 0x{:08x}>:",
header.offset().0,
header.offset().as_debug_types_offset().unwrap().0,
)?;
write!(w, " signature = ")?;
dump_type_signature(w, header.type_signature())?;
let (type_signature, type_offset) = match header.type_() {
UnitType::Type {
type_signature,
type_offset,
} => (type_signature, type_offset),
_ => unreachable!(), // No other units allowed in .debug_types.
};
dump_type_signature(w, type_signature)?;
writeln!(w)?;
writeln!(w, " typeoffset = 0x{:08x}", header.type_offset().0,)?;
writeln!(w, " typeoffset = 0x{:08x}", type_offset.0,)?;

let unit = match dwarf.type_unit(header) {
let unit = match dwarf.unit(header) {
Ok(unit) => unit,
Err(err) => {
writeln_error(w, dwarf, err.into(), "Failed to parse type unit root entry")?;
Expand Down Expand Up @@ -1790,7 +1797,7 @@ fn dump_line<R: Reader, W: Write>(w: &mut W, dwarf: &gimli::Dwarf<R>) -> Result<
writeln!(
w,
"\n.debug_line: line number info for unit at .debug_info offset 0x{:08x}",
header.offset().0
header.offset().as_debug_info_offset().unwrap().0
)?;
let unit = match dwarf.unit(header) {
Ok(unit) => unit,
Expand Down
5 changes: 4 additions & 1 deletion examples/simple.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,10 @@ fn dump_file(object: &object::File, endian: gimli::RunTimeEndian) -> Result<(),
// Iterate over the compilation units.
let mut iter = dwarf.units();
while let Some(header) = iter.next()? {
println!("Unit at <.debug_info+0x{:x}>", header.offset().0);
println!(
"Unit at <.debug_info+0x{:x}>",
header.offset().as_debug_info_offset().unwrap().0
);
let unit = dwarf.unit(header)?;

// Iterate over the Debugging Information Entries (DIEs) in the unit.
Expand Down
2 changes: 1 addition & 1 deletion examples/simple_line.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ fn dump_file(object: &object::File, endian: gimli::RunTimeEndian) -> Result<(),
while let Some(header) = iter.next()? {
println!(
"Line number info for unit at <.debug_info+0x{:x}>",
header.offset().0
header.offset().as_debug_info_offset().unwrap().0
);
let unit = dwarf.unit(header)?;

Expand Down
32 changes: 32 additions & 0 deletions src/common.rs
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,38 @@ pub enum UnitSectionOffset<T = usize> {
DebugTypesOffset(DebugTypesOffset<T>),
}

impl<T> From<DebugInfoOffset<T>> for UnitSectionOffset<T> {
fn from(offset: DebugInfoOffset<T>) -> Self {
UnitSectionOffset::DebugInfoOffset(offset)
}
}

impl<T> From<DebugTypesOffset<T>> for UnitSectionOffset<T> {
fn from(offset: DebugTypesOffset<T>) -> Self {
UnitSectionOffset::DebugTypesOffset(offset)
}
}

impl<T> UnitSectionOffset<T>
where
T: Clone,
{
/// Returns the `DebugInfoOffset` inside, or `None` otherwise.
pub fn as_debug_info_offset(&self) -> Option<DebugInfoOffset<T>> {
match self {
UnitSectionOffset::DebugInfoOffset(offset) => Some(offset.clone()),
UnitSectionOffset::DebugTypesOffset(_) => None,
}
}
/// Returns the `DebugTypesOffset` inside, or `None` otherwise.
pub fn as_debug_types_offset(&self) -> Option<DebugTypesOffset<T>> {
match self {
UnitSectionOffset::DebugInfoOffset(_) => None,
UnitSectionOffset::DebugTypesOffset(offset) => Some(offset.clone()),
}
}
}

/// An identifier for a DWARF section.
#[derive(Debug, Clone, Copy, PartialEq, Eq, Ord, PartialOrd, Hash)]
pub enum SectionId {
Expand Down
71 changes: 15 additions & 56 deletions src/read/dwarf.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,11 @@ use crate::common::{
};
use crate::constants;
use crate::read::{
Abbreviations, AttributeValue, CompilationUnitHeader, CompilationUnitHeadersIter, DebugAbbrev,
DebugAddr, DebugInfo, DebugLine, DebugLineStr, DebugStr, DebugStrOffsets, DebugTypes,
Abbreviations, AttributeValue, DebugAbbrev, DebugAddr, DebugInfo, DebugInfoUnitHeadersIter,
DebugLine, DebugLineStr, DebugStr, DebugStrOffsets, DebugTypes, DebugTypesUnitHeadersIter,
DebuggingInformationEntry, EntriesCursor, EntriesRaw, EntriesTree, Error,
IncompleteLineProgram, LocListIter, LocationLists, Range, RangeLists, Reader, ReaderOffset,
ReaderOffsetId, Result, RngListIter, Section, TypeUnitHeader, TypeUnitHeadersIter, UnitHeader,
UnitOffset,
ReaderOffsetId, Result, RngListIter, Section, UnitHeader, UnitOffset,
};

/// All of the commonly used DWARF sections, and other common information.
Expand Down Expand Up @@ -135,19 +134,18 @@ impl<T> Dwarf<T> {
}

impl<R: Reader> Dwarf<R> {
/// Iterate the compilation- and partial-unit headers in the
/// `.debug_info` section.
/// Iterate the unit headers in the `.debug_info` section.
///
/// Can be [used with
/// `FallibleIterator`](./index.html#using-with-fallibleiterator).
#[inline]
pub fn units(&self) -> CompilationUnitHeadersIter<R> {
pub fn units(&self) -> DebugInfoUnitHeadersIter<R> {
self.debug_info.units()
}

/// Construct a new `Unit` from the given compilation unit header.
/// Construct a new `Unit` from the given unit header.
#[inline]
pub fn unit(&self, header: CompilationUnitHeader<R>) -> Result<Unit<R>> {
pub fn unit(&self, header: UnitHeader<R>) -> Result<Unit<R>> {
Unit::new(self, header)
}

Expand All @@ -156,27 +154,14 @@ impl<R: Reader> Dwarf<R> {
/// Can be [used with
/// `FallibleIterator`](./index.html#using-with-fallibleiterator).
#[inline]
pub fn type_units(&self) -> TypeUnitHeadersIter<R> {
pub fn type_units(&self) -> DebugTypesUnitHeadersIter<R> {
self.debug_types.units()
}

/// Construct a new `Unit` from the given type unit header.
#[inline]
pub fn type_unit(&self, header: TypeUnitHeader<R>) -> Result<Unit<R>> {
Unit::new_type_unit(self, header)
}

/// Parse the abbreviations for a compilation unit.
// TODO: provide caching of abbreviations
#[inline]
pub fn abbreviations(&self, unit: &CompilationUnitHeader<R>) -> Result<Abbreviations> {
unit.abbreviations(&self.debug_abbrev)
}

/// Parse the abbreviations for a type unit.
// TODO: provide caching of abbreviations
#[inline]
pub fn type_abbreviations(&self, unit: &TypeUnitHeader<R>) -> Result<Abbreviations> {
pub fn abbreviations(&self, unit: &UnitHeader<R>) -> Result<Abbreviations> {
unit.abbreviations(&self.debug_abbrev)
}

Expand Down Expand Up @@ -480,9 +465,6 @@ where
R: Reader<Offset = Offset>,
Offset: ReaderOffset,
{
/// The section offset of the unit.
pub offset: UnitSectionOffset<Offset>,

/// The header of the unit.
pub header: UnitHeader<R, Offset>,

Expand Down Expand Up @@ -515,34 +497,11 @@ where
}

impl<R: Reader> Unit<R> {
/// Construct a new `Unit` from the given compilation unit header.
/// Construct a new `Unit` from the given unit header.
#[inline]
pub fn new(dwarf: &Dwarf<R>, header: CompilationUnitHeader<R>) -> Result<Self> {
Self::new_internal(
dwarf,
UnitSectionOffset::DebugInfoOffset(header.offset()),
header.header(),
)
}

/// Construct a new `Unit` from the given type unit header.
#[inline]
pub fn new_type_unit(dwarf: &Dwarf<R>, header: TypeUnitHeader<R>) -> Result<Self> {
Self::new_internal(
dwarf,
UnitSectionOffset::DebugTypesOffset(header.offset()),
header.header(),
)
}

fn new_internal(
dwarf: &Dwarf<R>,
offset: UnitSectionOffset<R::Offset>,
header: UnitHeader<R>,
) -> Result<Self> {
pub fn new(dwarf: &Dwarf<R>, header: UnitHeader<R>) -> Result<Self> {
let abbreviations = header.abbreviations(&dwarf.debug_abbrev)?;
let mut unit = Unit {
offset,
header,
abbreviations,
name: None,
Expand Down Expand Up @@ -673,7 +632,7 @@ impl<T: ReaderOffset> UnitSectionOffset<T> {
where
R: Reader<Offset = T>,
{
let (offset, unit_offset) = match (self, unit.offset) {
let (offset, unit_offset) = match (self, unit.header.offset()) {
(
UnitSectionOffset::DebugInfoOffset(offset),
UnitSectionOffset::DebugInfoOffset(unit_offset),
Expand Down Expand Up @@ -704,12 +663,12 @@ impl<T: ReaderOffset> UnitOffset<T> {
where
R: Reader<Offset = T>,
{
match unit.offset {
match unit.header.offset() {
UnitSectionOffset::DebugInfoOffset(unit_offset) => {
UnitSectionOffset::DebugInfoOffset(DebugInfoOffset(unit_offset.0 + self.0))
DebugInfoOffset(unit_offset.0 + self.0).into()
}
UnitSectionOffset::DebugTypesOffset(unit_offset) => {
UnitSectionOffset::DebugTypesOffset(DebugTypesOffset(unit_offset.0 + self.0))
DebugTypesOffset(unit_offset.0 + self.0).into()
}
}
}
Expand Down
Loading