Skip to content

Commit

Permalink
Merge pull request #529 from khuey/downstream
Browse files Browse the repository at this point in the history
More split dwarf work
  • Loading branch information
philipc authored Jul 14, 2020
2 parents 4e603bc + 7f2ef1e commit e659d6e
Show file tree
Hide file tree
Showing 8 changed files with 455 additions and 243 deletions.
5 changes: 4 additions & 1 deletion examples/dwarfdump.rs
Original file line number Diff line number Diff line change
Expand Up @@ -550,7 +550,10 @@ where
reader: Default::default(),
};

let dwarf = gimli::Dwarf::load(&mut load_section, |_| Ok(no_reader.clone())).unwrap();
let mut dwarf = gimli::Dwarf::load(&mut load_section, |_| Ok(no_reader.clone())).unwrap();
if flags.dwo {
dwarf.file_type = gimli::DwarfFileType::Dwo;
}

let out = io::stdout();
if flags.eh_frame {
Expand Down
18 changes: 18 additions & 0 deletions src/common.rs
Original file line number Diff line number Diff line change
Expand Up @@ -311,6 +311,7 @@ impl SectionId {
SectionId::DebugLoc => ".debug_loc.dwo",
SectionId::DebugLocLists => ".debug_loclists.dwo",
SectionId::DebugMacro => ".debug_macro.dwo",
SectionId::DebugRngLists => ".debug_rnglists.dwo",
SectionId::DebugStr => ".debug_str.dwo",
SectionId::DebugStrOffsets => ".debug_str_offsets.dwo",
_ => return None,
Expand All @@ -322,3 +323,20 @@ impl SectionId {
/// split DWARF and linking a split compilation unit back together.
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct DwoId(pub u64);

/// The "type" of file with DWARF debugging information. This determines, among other things,
/// which files DWARF sections should be loaded from.
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum DwarfFileType {
/// A normal executable or object file.
Main,
/// A .dwo split DWARF file.
Dwo,
// TODO: Supplementary files, .dwps?
}

impl Default for DwarfFileType {
fn default() -> Self {
DwarfFileType::Main
}
}
55 changes: 40 additions & 15 deletions src/read/dwarf.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ use alloc::string::String;
use crate::common::{
DebugAddrBase, DebugAddrIndex, DebugInfoOffset, DebugLineStrOffset, DebugLocListsBase,
DebugLocListsIndex, DebugRngListsBase, DebugRngListsIndex, DebugStrOffset, DebugStrOffsetsBase,
DebugStrOffsetsIndex, DebugTypesOffset, Encoding, LocationListsOffset, RangeListsOffset,
SectionId, UnitSectionOffset,
DebugStrOffsetsIndex, DebugTypesOffset, DwarfFileType, Encoding, LocationListsOffset,
RangeListsOffset, SectionId, UnitSectionOffset,
};
use crate::constants;
use crate::read::{
Expand Down Expand Up @@ -50,6 +50,9 @@ pub struct Dwarf<R> {

/// The range lists in the `.debug_ranges` and `.debug_rnglists` sections.
pub ranges: RangeLists<R>,

/// The type of this file.
pub file_type: DwarfFileType,
}

impl<T> Dwarf<T> {
Expand Down Expand Up @@ -84,6 +87,7 @@ impl<T> Dwarf<T> {
debug_types: Section::load(&mut section)?,
locations: LocationLists::new(debug_loc, debug_loclists),
ranges: RangeLists::new(debug_ranges, debug_rnglists),
file_type: DwarfFileType::Main,
})
}

Expand Down Expand Up @@ -129,6 +133,7 @@ impl<T> Dwarf<T> {
debug_types: self.debug_types.borrow(&mut borrow),
locations: self.locations.borrow(&mut borrow),
ranges: self.ranges.borrow(&mut borrow),
file_type: self.file_type,
}
}
}
Expand Down Expand Up @@ -376,13 +381,22 @@ impl<R: Reader> Dwarf<R> {
unit: &Unit<R>,
offset: LocationListsOffset<R::Offset>,
) -> Result<LocListIter<R>> {
self.locations.locations(
offset,
unit.encoding(),
unit.low_pc,
&self.debug_addr,
unit.addr_base,
)
match self.file_type {
DwarfFileType::Main => self.locations.locations(
offset,
unit.encoding(),
unit.low_pc,
&self.debug_addr,
unit.addr_base,
),
DwarfFileType::Dwo => self.locations.locations_dwo(
offset,
unit.encoding(),
unit.low_pc,
&self.debug_addr,
unit.addr_base,
),
}
}

/// Try to return an attribute value as a location list offset.
Expand Down Expand Up @@ -519,17 +533,26 @@ impl<R: Reader> Unit<R> {
pub fn new(dwarf: &Dwarf<R>, header: UnitHeader<R>) -> Result<Self> {
let abbreviations = header.abbreviations(&dwarf.debug_abbrev)?;
let mut unit = Unit {
header,
abbreviations,
name: None,
comp_dir: None,
low_pc: 0,
// Defaults to 0 for GNU extensions.
str_offsets_base: DebugStrOffsetsBase(R::Offset::from_u8(0)),
str_offsets_base: DebugStrOffsetsBase::default_for_encoding_and_file(
header.encoding(),
dwarf.file_type,
),
// NB: Because the .debug_addr section never lives in a .dwo, we can assume its base is always 0 or provided.
addr_base: DebugAddrBase(R::Offset::from_u8(0)),
loclists_base: DebugLocListsBase(R::Offset::from_u8(0)),
rnglists_base: DebugRngListsBase(R::Offset::from_u8(0)),
loclists_base: DebugLocListsBase::default_for_encoding_and_file(
header.encoding(),
dwarf.file_type,
),
rnglists_base: DebugRngListsBase::default_for_encoding_and_file(
header.encoding(),
dwarf.file_type,
),
line_program: None,
header,
};
let mut name = None;
let mut comp_dir = None;
Expand Down Expand Up @@ -646,7 +669,9 @@ impl<R: Reader> Unit<R> {
pub fn copy_relocated_attributes(&mut self, other: &Unit<R>) {
self.low_pc = other.low_pc;
self.addr_base = other.addr_base;
self.rnglists_base = other.rnglists_base;
if self.header.version() < 5 {
self.rnglists_base = other.rnglists_base;
}
}
}

Expand Down
67 changes: 67 additions & 0 deletions src/read/lists.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
use crate::common::{Encoding, Format};
use crate::read::{Error, Reader, Result};

#[derive(Debug, Clone, Copy)]
pub(crate) struct ListsHeader {
encoding: Encoding,
offset_entry_count: u32,
}

impl Default for ListsHeader {
fn default() -> Self {
ListsHeader {
encoding: Encoding {
format: Format::Dwarf32,
version: 5,
address_size: 0,
},
offset_entry_count: 0,
}
}
}

impl ListsHeader {
/// Return the serialized size of the table header.
#[allow(dead_code)]
#[inline]
fn size(self) -> u8 {
// initial_length + version + address_size + segment_selector_size + offset_entry_count
ListsHeader::size_for_encoding(self.encoding)
}

/// Return the serialized size of the table header.
#[inline]
pub(crate) fn size_for_encoding(encoding: Encoding) -> u8 {
// initial_length + version + address_size + segment_selector_size + offset_entry_count
encoding.format.initial_length_size() + 2 + 1 + 1 + 4
}
}

// TODO: add an iterator over headers in the appropriate sections section
#[allow(dead_code)]
fn parse_header<R: Reader>(input: &mut R) -> Result<ListsHeader> {
let (length, format) = input.read_initial_length()?;
input.truncate(length)?;

let version = input.read_u16()?;
if version != 5 {
return Err(Error::UnknownVersion(u64::from(version)));
}

let address_size = input.read_u8()?;
let segment_selector_size = input.read_u8()?;
if segment_selector_size != 0 {
return Err(Error::UnsupportedSegmentSize);
}
let offset_entry_count = input.read_u32()?;

let encoding = Encoding {
format,
version,
address_size,
};
Ok(ListsHeader {
encoding,
offset_entry_count,
})
}
Loading

0 comments on commit e659d6e

Please sign in to comment.