Skip to content

Commit

Permalink
Merge CompilationUnitHeader and TypeUnitHeader, introduce UnitType. (#…
Browse files Browse the repository at this point in the history
  • Loading branch information
khuey committed Jul 5, 2020
1 parent fdc2231 commit 5b15684
Show file tree
Hide file tree
Showing 12 changed files with 513 additions and 838 deletions.
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

0 comments on commit 5b15684

Please sign in to comment.