Skip to content

Commit e659d6e

Browse files
authored
Merge pull request #529 from khuey/downstream
More split dwarf work
2 parents 4e603bc + 7f2ef1e commit e659d6e

8 files changed

Lines changed: 455 additions & 243 deletions

File tree

examples/dwarfdump.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -550,7 +550,10 @@ where
550550
reader: Default::default(),
551551
};
552552

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

555558
let out = io::stdout();
556559
if flags.eh_frame {

src/common.rs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -311,6 +311,7 @@ impl SectionId {
311311
SectionId::DebugLoc => ".debug_loc.dwo",
312312
SectionId::DebugLocLists => ".debug_loclists.dwo",
313313
SectionId::DebugMacro => ".debug_macro.dwo",
314+
SectionId::DebugRngLists => ".debug_rnglists.dwo",
314315
SectionId::DebugStr => ".debug_str.dwo",
315316
SectionId::DebugStrOffsets => ".debug_str_offsets.dwo",
316317
_ => return None,
@@ -322,3 +323,20 @@ impl SectionId {
322323
/// split DWARF and linking a split compilation unit back together.
323324
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
324325
pub struct DwoId(pub u64);
326+
327+
/// The "type" of file with DWARF debugging information. This determines, among other things,
328+
/// which files DWARF sections should be loaded from.
329+
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
330+
pub enum DwarfFileType {
331+
/// A normal executable or object file.
332+
Main,
333+
/// A .dwo split DWARF file.
334+
Dwo,
335+
// TODO: Supplementary files, .dwps?
336+
}
337+
338+
impl Default for DwarfFileType {
339+
fn default() -> Self {
340+
DwarfFileType::Main
341+
}
342+
}

src/read/dwarf.rs

Lines changed: 40 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@ use alloc::string::String;
33
use crate::common::{
44
DebugAddrBase, DebugAddrIndex, DebugInfoOffset, DebugLineStrOffset, DebugLocListsBase,
55
DebugLocListsIndex, DebugRngListsBase, DebugRngListsIndex, DebugStrOffset, DebugStrOffsetsBase,
6-
DebugStrOffsetsIndex, DebugTypesOffset, Encoding, LocationListsOffset, RangeListsOffset,
7-
SectionId, UnitSectionOffset,
6+
DebugStrOffsetsIndex, DebugTypesOffset, DwarfFileType, Encoding, LocationListsOffset,
7+
RangeListsOffset, SectionId, UnitSectionOffset,
88
};
99
use crate::constants;
1010
use crate::read::{
@@ -50,6 +50,9 @@ pub struct Dwarf<R> {
5050

5151
/// The range lists in the `.debug_ranges` and `.debug_rnglists` sections.
5252
pub ranges: RangeLists<R>,
53+
54+
/// The type of this file.
55+
pub file_type: DwarfFileType,
5356
}
5457

5558
impl<T> Dwarf<T> {
@@ -84,6 +87,7 @@ impl<T> Dwarf<T> {
8487
debug_types: Section::load(&mut section)?,
8588
locations: LocationLists::new(debug_loc, debug_loclists),
8689
ranges: RangeLists::new(debug_ranges, debug_rnglists),
90+
file_type: DwarfFileType::Main,
8791
})
8892
}
8993

@@ -129,6 +133,7 @@ impl<T> Dwarf<T> {
129133
debug_types: self.debug_types.borrow(&mut borrow),
130134
locations: self.locations.borrow(&mut borrow),
131135
ranges: self.ranges.borrow(&mut borrow),
136+
file_type: self.file_type,
132137
}
133138
}
134139
}
@@ -376,13 +381,22 @@ impl<R: Reader> Dwarf<R> {
376381
unit: &Unit<R>,
377382
offset: LocationListsOffset<R::Offset>,
378383
) -> Result<LocListIter<R>> {
379-
self.locations.locations(
380-
offset,
381-
unit.encoding(),
382-
unit.low_pc,
383-
&self.debug_addr,
384-
unit.addr_base,
385-
)
384+
match self.file_type {
385+
DwarfFileType::Main => self.locations.locations(
386+
offset,
387+
unit.encoding(),
388+
unit.low_pc,
389+
&self.debug_addr,
390+
unit.addr_base,
391+
),
392+
DwarfFileType::Dwo => self.locations.locations_dwo(
393+
offset,
394+
unit.encoding(),
395+
unit.low_pc,
396+
&self.debug_addr,
397+
unit.addr_base,
398+
),
399+
}
386400
}
387401

388402
/// Try to return an attribute value as a location list offset.
@@ -519,17 +533,26 @@ impl<R: Reader> Unit<R> {
519533
pub fn new(dwarf: &Dwarf<R>, header: UnitHeader<R>) -> Result<Self> {
520534
let abbreviations = header.abbreviations(&dwarf.debug_abbrev)?;
521535
let mut unit = Unit {
522-
header,
523536
abbreviations,
524537
name: None,
525538
comp_dir: None,
526539
low_pc: 0,
527-
// Defaults to 0 for GNU extensions.
528-
str_offsets_base: DebugStrOffsetsBase(R::Offset::from_u8(0)),
540+
str_offsets_base: DebugStrOffsetsBase::default_for_encoding_and_file(
541+
header.encoding(),
542+
dwarf.file_type,
543+
),
544+
// NB: Because the .debug_addr section never lives in a .dwo, we can assume its base is always 0 or provided.
529545
addr_base: DebugAddrBase(R::Offset::from_u8(0)),
530-
loclists_base: DebugLocListsBase(R::Offset::from_u8(0)),
531-
rnglists_base: DebugRngListsBase(R::Offset::from_u8(0)),
546+
loclists_base: DebugLocListsBase::default_for_encoding_and_file(
547+
header.encoding(),
548+
dwarf.file_type,
549+
),
550+
rnglists_base: DebugRngListsBase::default_for_encoding_and_file(
551+
header.encoding(),
552+
dwarf.file_type,
553+
),
532554
line_program: None,
555+
header,
533556
};
534557
let mut name = None;
535558
let mut comp_dir = None;
@@ -646,7 +669,9 @@ impl<R: Reader> Unit<R> {
646669
pub fn copy_relocated_attributes(&mut self, other: &Unit<R>) {
647670
self.low_pc = other.low_pc;
648671
self.addr_base = other.addr_base;
649-
self.rnglists_base = other.rnglists_base;
672+
if self.header.version() < 5 {
673+
self.rnglists_base = other.rnglists_base;
674+
}
650675
}
651676
}
652677

src/read/lists.rs

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
use crate::common::{Encoding, Format};
2+
use crate::read::{Error, Reader, Result};
3+
4+
#[derive(Debug, Clone, Copy)]
5+
pub(crate) struct ListsHeader {
6+
encoding: Encoding,
7+
offset_entry_count: u32,
8+
}
9+
10+
impl Default for ListsHeader {
11+
fn default() -> Self {
12+
ListsHeader {
13+
encoding: Encoding {
14+
format: Format::Dwarf32,
15+
version: 5,
16+
address_size: 0,
17+
},
18+
offset_entry_count: 0,
19+
}
20+
}
21+
}
22+
23+
impl ListsHeader {
24+
/// Return the serialized size of the table header.
25+
#[allow(dead_code)]
26+
#[inline]
27+
fn size(self) -> u8 {
28+
// initial_length + version + address_size + segment_selector_size + offset_entry_count
29+
ListsHeader::size_for_encoding(self.encoding)
30+
}
31+
32+
/// Return the serialized size of the table header.
33+
#[inline]
34+
pub(crate) fn size_for_encoding(encoding: Encoding) -> u8 {
35+
// initial_length + version + address_size + segment_selector_size + offset_entry_count
36+
encoding.format.initial_length_size() + 2 + 1 + 1 + 4
37+
}
38+
}
39+
40+
// TODO: add an iterator over headers in the appropriate sections section
41+
#[allow(dead_code)]
42+
fn parse_header<R: Reader>(input: &mut R) -> Result<ListsHeader> {
43+
let (length, format) = input.read_initial_length()?;
44+
input.truncate(length)?;
45+
46+
let version = input.read_u16()?;
47+
if version != 5 {
48+
return Err(Error::UnknownVersion(u64::from(version)));
49+
}
50+
51+
let address_size = input.read_u8()?;
52+
let segment_selector_size = input.read_u8()?;
53+
if segment_selector_size != 0 {
54+
return Err(Error::UnsupportedSegmentSize);
55+
}
56+
let offset_entry_count = input.read_u32()?;
57+
58+
let encoding = Encoding {
59+
format,
60+
version,
61+
address_size,
62+
};
63+
Ok(ListsHeader {
64+
encoding,
65+
offset_entry_count,
66+
})
67+
}

0 commit comments

Comments
 (0)