From cdb9d3999ae6cfad81368a85df1c06302db48d99 Mon Sep 17 00:00:00 2001 From: Jamey Sharp Date: Fri, 24 May 2024 03:08:28 -0700 Subject: [PATCH] Introduce new enum for `.dwo` section IDs Keeping this type distinct from the `SectionId` enum ensures that the compiler will report an error if someone adds incomplete support for new separate-debug sections. As discussed in: https://github.com/gimli-rs/gimli/pull/714#discussion_r1611164319 The existing `SectionId::dwo_name` method did not match the list of sections actually supported elsewhere in gimli. I've added the one section ID that was missing (`.debug_macinfo.dwo`), but I have not removed the section IDs which are only present there: `.debug_str.dwo`, `.debug_cu_index`, and `.debug_tu_index`. --- crates/examples/src/bin/dwarfdump.rs | 2 +- src/common.rs | 1 + src/read/dwarf.rs | 28 +++--- src/read/index.rs | 144 +++++++++++++++++---------- src/read/mod.rs | 3 - 5 files changed, 110 insertions(+), 68 deletions(-) diff --git a/crates/examples/src/bin/dwarfdump.rs b/crates/examples/src/bin/dwarfdump.rs index 759e1ff9..f1dd856e 100644 --- a/crates/examples/src/bin/dwarfdump.rs +++ b/crates/examples/src/bin/dwarfdump.rs @@ -968,7 +968,7 @@ where writeln!( w, " {}: offset = 0x{:x}, size = 0x{:x}", - section.section.dwo_name().unwrap(), + section.section.dwo_name(), section.offset, section.size )?; diff --git a/src/common.rs b/src/common.rs index fc6693d1..cad9568a 100644 --- a/src/common.rs +++ b/src/common.rs @@ -339,6 +339,7 @@ impl SectionId { // GNU split-dwarf extension to DWARF4. SectionId::DebugLoc => ".debug_loc.dwo", SectionId::DebugLocLists => ".debug_loclists.dwo", + SectionId::DebugMacinfo => ".debug_macinfo.dwo", SectionId::DebugMacro => ".debug_macro.dwo", SectionId::DebugRngLists => ".debug_rnglists.dwo", SectionId::DebugStr => ".debug_str.dwo", diff --git a/src/read/dwarf.rs b/src/read/dwarf.rs index e04ddfd6..3864917a 100644 --- a/src/read/dwarf.rs +++ b/src/read/dwarf.rs @@ -12,10 +12,11 @@ use crate::read::{ Abbreviations, AbbreviationsCache, AbbreviationsCacheStrategy, AttributeValue, DebugAbbrev, DebugAddr, DebugAranges, DebugCuIndex, DebugInfo, DebugInfoUnitHeadersIter, DebugLine, DebugLineStr, DebugLoc, DebugLocLists, DebugRanges, DebugRngLists, DebugStr, DebugStrOffsets, - DebugTuIndex, DebugTypes, DebugTypesUnitHeadersIter, DebuggingInformationEntry, EntriesCursor, - EntriesRaw, EntriesTree, Error, IncompleteLineProgram, LocListIter, LocationLists, Range, - RangeLists, RawLocListIter, RawRngListIter, Reader, ReaderOffset, ReaderOffsetId, Result, - RngListIter, Section, UnitHeader, UnitIndex, UnitIndexSectionIterator, UnitOffset, UnitType, + DebugTuIndex, DebugTypes, DebugTypesUnitHeadersIter, DebuggingInformationEntry, DwoSectionId, + EntriesCursor, EntriesRaw, EntriesTree, Error, IncompleteLineProgram, LocListIter, + LocationLists, Range, RangeLists, RawLocListIter, RawRngListIter, Reader, ReaderOffset, + ReaderOffsetId, Result, RngListIter, Section, UnitHeader, UnitIndex, UnitIndexSectionIterator, + UnitOffset, UnitType, }; /// All of the commonly used DWARF sections. @@ -1013,42 +1014,41 @@ impl DwarfPackage { let mut types_size = 0; for section in sections { match section.section { - SectionId::DebugAbbrev => { + DwoSectionId::DebugAbbrev => { abbrev_offset = section.offset; abbrev_size = section.size; } - SectionId::DebugInfo => { + DwoSectionId::DebugInfo => { info_offset = section.offset; info_size = section.size; } - SectionId::DebugLine => { + DwoSectionId::DebugLine => { line_offset = section.offset; line_size = section.size; } - SectionId::DebugLoc => { + DwoSectionId::DebugLoc => { loc_offset = section.offset; loc_size = section.size; } - SectionId::DebugLocLists => { + DwoSectionId::DebugLocLists => { loclists_offset = section.offset; loclists_size = section.size; } - SectionId::DebugStrOffsets => { + DwoSectionId::DebugStrOffsets => { str_offsets_offset = section.offset; str_offsets_size = section.size; } - SectionId::DebugRngLists => { + DwoSectionId::DebugRngLists => { rnglists_offset = section.offset; rnglists_size = section.size; } - SectionId::DebugTypes => { + DwoSectionId::DebugTypes => { types_offset = section.offset; types_size = section.size; } - SectionId::DebugMacro | SectionId::DebugMacinfo => { + DwoSectionId::DebugMacro | DwoSectionId::DebugMacinfo => { // These are valid but we can't parse these yet. } - _ => return Err(Error::UnknownSection(section.section)), } } diff --git a/src/read/index.rs b/src/read/index.rs index e24c1c9c..37f3ccc9 100644 --- a/src/read/index.rs +++ b/src/read/index.rs @@ -129,7 +129,7 @@ pub struct UnitIndex { hash_ids: R, hash_rows: R, // Only `section_count` values are valid. - sections: [SectionId; SECTION_COUNT_MAX as usize], + sections: [DwoSectionId; SECTION_COUNT_MAX as usize], offsets: R, sizes: R, } @@ -144,7 +144,7 @@ impl UnitIndex { slot_count: 0, hash_ids: input.clone(), hash_rows: input.clone(), - sections: [SectionId::DebugAbbrev; SECTION_COUNT_MAX as usize], + sections: [DwoSectionId::DebugAbbrev; SECTION_COUNT_MAX as usize], offsets: input.clone(), sizes: input.clone(), }); @@ -173,7 +173,7 @@ impl UnitIndex { let hash_ids = input.split(R::Offset::from_u64(u64::from(slot_count) * 8)?)?; let hash_rows = input.split(R::Offset::from_u64(u64::from(slot_count) * 4)?)?; - let mut sections = [SectionId::DebugAbbrev; SECTION_COUNT_MAX as usize]; + let mut sections = [DwoSectionId::DebugAbbrev; SECTION_COUNT_MAX as usize]; if section_count > SECTION_COUNT_MAX.into() { return Err(Error::InvalidIndexSectionCount); } @@ -181,25 +181,25 @@ impl UnitIndex { let section = input.read_u32()?; sections[i as usize] = if version == 2 { match constants::DwSectV2(section) { - constants::DW_SECT_V2_INFO => SectionId::DebugInfo, - constants::DW_SECT_V2_TYPES => SectionId::DebugTypes, - constants::DW_SECT_V2_ABBREV => SectionId::DebugAbbrev, - constants::DW_SECT_V2_LINE => SectionId::DebugLine, - constants::DW_SECT_V2_LOC => SectionId::DebugLoc, - constants::DW_SECT_V2_STR_OFFSETS => SectionId::DebugStrOffsets, - constants::DW_SECT_V2_MACINFO => SectionId::DebugMacinfo, - constants::DW_SECT_V2_MACRO => SectionId::DebugMacro, + constants::DW_SECT_V2_INFO => DwoSectionId::DebugInfo, + constants::DW_SECT_V2_TYPES => DwoSectionId::DebugTypes, + constants::DW_SECT_V2_ABBREV => DwoSectionId::DebugAbbrev, + constants::DW_SECT_V2_LINE => DwoSectionId::DebugLine, + constants::DW_SECT_V2_LOC => DwoSectionId::DebugLoc, + constants::DW_SECT_V2_STR_OFFSETS => DwoSectionId::DebugStrOffsets, + constants::DW_SECT_V2_MACINFO => DwoSectionId::DebugMacinfo, + constants::DW_SECT_V2_MACRO => DwoSectionId::DebugMacro, section => return Err(Error::UnknownIndexSectionV2(section)), } } else { match constants::DwSect(section) { - constants::DW_SECT_INFO => SectionId::DebugInfo, - constants::DW_SECT_ABBREV => SectionId::DebugAbbrev, - constants::DW_SECT_LINE => SectionId::DebugLine, - constants::DW_SECT_LOCLISTS => SectionId::DebugLocLists, - constants::DW_SECT_STR_OFFSETS => SectionId::DebugStrOffsets, - constants::DW_SECT_MACRO => SectionId::DebugMacro, - constants::DW_SECT_RNGLISTS => SectionId::DebugRngLists, + constants::DW_SECT_INFO => DwoSectionId::DebugInfo, + constants::DW_SECT_ABBREV => DwoSectionId::DebugAbbrev, + constants::DW_SECT_LINE => DwoSectionId::DebugLine, + constants::DW_SECT_LOCLISTS => DwoSectionId::DebugLocLists, + constants::DW_SECT_STR_OFFSETS => DwoSectionId::DebugStrOffsets, + constants::DW_SECT_MACRO => DwoSectionId::DebugMacro, + constants::DW_SECT_RNGLISTS => DwoSectionId::DebugRngLists, section => return Err(Error::UnknownIndexSection(section)), } }; @@ -305,7 +305,7 @@ impl UnitIndex { /// An iterator over the section offsets and sizes for a row in a `UnitIndex`. #[derive(Debug, Clone)] pub struct UnitIndexSectionIterator<'index, R: Reader> { - sections: slice::Iter<'index, SectionId>, + sections: slice::Iter<'index, DwoSectionId>, offsets: R, sizes: R, } @@ -330,13 +330,57 @@ impl<'index, R: Reader> Iterator for UnitIndexSectionIterator<'index, R> { #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct UnitIndexSection { /// The section kind. - pub section: SectionId, + pub section: DwoSectionId, /// The base offset of the unit's contribution to the section. pub offset: u32, /// The size of the unit's contribution to the section. pub size: u32, } +/// Section kinds which are permitted in a `.dwo` file. +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +pub enum DwoSectionId { + /// The `.debug_abbrev.dwo` section. + DebugAbbrev, + /// The `.debug_info.dwo` section. + DebugInfo, + /// The `.debug_line.dwo` section. + DebugLine, + /// The `.debug_loc.dwo` section. + DebugLoc, + /// The `.debug_loclists.dwo` section. + DebugLocLists, + /// The `.debug_macinfo.dwo` section. + DebugMacinfo, + /// The `.debug_macro.dwo` section. + DebugMacro, + /// The `.debug_rnglists.dwo` section. + DebugRngLists, + /// The `.debug_str_offsets.dwo` section. + DebugStrOffsets, + /// The `.debug_types.dwo` section. + DebugTypes, +} + +impl DwoSectionId { + /// Returns the ELF section name for this kind, when found in a .dwo or .dwp file. + pub fn dwo_name(self) -> &'static str { + let section_id = match self { + DwoSectionId::DebugAbbrev => SectionId::DebugAbbrev, + DwoSectionId::DebugInfo => SectionId::DebugInfo, + DwoSectionId::DebugLine => SectionId::DebugLine, + DwoSectionId::DebugLoc => SectionId::DebugLoc, + DwoSectionId::DebugLocLists => SectionId::DebugLocLists, + DwoSectionId::DebugMacro => SectionId::DebugMacro, + DwoSectionId::DebugMacinfo => SectionId::DebugMacinfo, + DwoSectionId::DebugRngLists => SectionId::DebugRngLists, + DwoSectionId::DebugStrOffsets => SectionId::DebugStrOffsets, + DwoSectionId::DebugTypes => SectionId::DebugTypes, + }; + section_id.dwo_name().unwrap() + } +} + #[cfg(test)] mod tests { use super::*; @@ -437,26 +481,26 @@ mod tests { assert_eq!( index.sections, [ - SectionId::DebugInfo, - SectionId::DebugTypes, - SectionId::DebugAbbrev, - SectionId::DebugLine, - SectionId::DebugLoc, - SectionId::DebugStrOffsets, - SectionId::DebugMacinfo, - SectionId::DebugMacro, + DwoSectionId::DebugInfo, + DwoSectionId::DebugTypes, + DwoSectionId::DebugAbbrev, + DwoSectionId::DebugLine, + DwoSectionId::DebugLoc, + DwoSectionId::DebugStrOffsets, + DwoSectionId::DebugMacinfo, + DwoSectionId::DebugMacro, ] ); #[rustfmt::skip] let expect = [ - UnitIndexSection { section: SectionId::DebugInfo, offset: 11, size: 21 }, - UnitIndexSection { section: SectionId::DebugTypes, offset: 12, size: 22 }, - UnitIndexSection { section: SectionId::DebugAbbrev, offset: 13, size: 23 }, - UnitIndexSection { section: SectionId::DebugLine, offset: 14, size: 24 }, - UnitIndexSection { section: SectionId::DebugLoc, offset: 15, size: 25 }, - UnitIndexSection { section: SectionId::DebugStrOffsets, offset: 16, size: 26 }, - UnitIndexSection { section: SectionId::DebugMacinfo, offset: 17, size: 27 }, - UnitIndexSection { section: SectionId::DebugMacro, offset: 18, size: 28 }, + UnitIndexSection { section: DwoSectionId::DebugInfo, offset: 11, size: 21 }, + UnitIndexSection { section: DwoSectionId::DebugTypes, offset: 12, size: 22 }, + UnitIndexSection { section: DwoSectionId::DebugAbbrev, offset: 13, size: 23 }, + UnitIndexSection { section: DwoSectionId::DebugLine, offset: 14, size: 24 }, + UnitIndexSection { section: DwoSectionId::DebugLoc, offset: 15, size: 25 }, + UnitIndexSection { section: DwoSectionId::DebugStrOffsets, offset: 16, size: 26 }, + UnitIndexSection { section: DwoSectionId::DebugMacinfo, offset: 17, size: 27 }, + UnitIndexSection { section: DwoSectionId::DebugMacro, offset: 18, size: 28 }, ]; let mut sections = index.sections(1).unwrap(); for section in &expect { @@ -492,24 +536,24 @@ mod tests { assert_eq!( index.sections[..7], [ - SectionId::DebugInfo, - SectionId::DebugAbbrev, - SectionId::DebugLine, - SectionId::DebugLocLists, - SectionId::DebugStrOffsets, - SectionId::DebugMacro, - SectionId::DebugRngLists, + DwoSectionId::DebugInfo, + DwoSectionId::DebugAbbrev, + DwoSectionId::DebugLine, + DwoSectionId::DebugLocLists, + DwoSectionId::DebugStrOffsets, + DwoSectionId::DebugMacro, + DwoSectionId::DebugRngLists, ] ); #[rustfmt::skip] let expect = [ - UnitIndexSection { section: SectionId::DebugInfo, offset: 11, size: 21 }, - UnitIndexSection { section: SectionId::DebugAbbrev, offset: 12, size: 22 }, - UnitIndexSection { section: SectionId::DebugLine, offset: 13, size: 23 }, - UnitIndexSection { section: SectionId::DebugLocLists, offset: 14, size: 24 }, - UnitIndexSection { section: SectionId::DebugStrOffsets, offset: 15, size: 25 }, - UnitIndexSection { section: SectionId::DebugMacro, offset: 16, size: 26 }, - UnitIndexSection { section: SectionId::DebugRngLists, offset: 17, size: 27 }, + UnitIndexSection { section: DwoSectionId::DebugInfo, offset: 11, size: 21 }, + UnitIndexSection { section: DwoSectionId::DebugAbbrev, offset: 12, size: 22 }, + UnitIndexSection { section: DwoSectionId::DebugLine, offset: 13, size: 23 }, + UnitIndexSection { section: DwoSectionId::DebugLocLists, offset: 14, size: 24 }, + UnitIndexSection { section: DwoSectionId::DebugStrOffsets, offset: 15, size: 25 }, + UnitIndexSection { section: DwoSectionId::DebugMacro, offset: 16, size: 26 }, + UnitIndexSection { section: DwoSectionId::DebugRngLists, offset: 17, size: 27 }, ]; let mut sections = index.sections(1).unwrap(); for section in &expect { diff --git a/src/read/mod.rs b/src/read/mod.rs index 9b974ecd..804e01a6 100644 --- a/src/read/mod.rs +++ b/src/read/mod.rs @@ -440,8 +440,6 @@ pub enum Error { InvalidIndexSlotCount, /// Invalid hash row in `.dwp` index. InvalidIndexRow, - /// Unknown section type. - UnknownSection(SectionId), /// Unknown section type in `.dwp` index. UnknownIndexSection(constants::DwSect), /// Unknown section type in version 2 `.dwp` index. @@ -596,7 +594,6 @@ impl Error { Error::InvalidIndexSectionCount => "Invalid section count in `.dwp` index.", Error::InvalidIndexSlotCount => "Invalid slot count in `.dwp` index.", Error::InvalidIndexRow => "Invalid hash row in `.dwp` index.", - Error::UnknownSection(_) => "Unknown section type.", Error::UnknownIndexSection(_) => "Unknown section type in `.dwp` index.", Error::UnknownIndexSectionV2(_) => "Unknown section type in version 2 `.dwp` index.", }