From 8b0ff71550808c83be0e09ef3ec26c89069dd432 Mon Sep 17 00:00:00 2001 From: Jamey Sharp Date: Wed, 22 May 2024 17:06:05 -0700 Subject: [PATCH 1/2] Report more specific errors for unknown constants In case someone encounters some DWARF containing a constant value not known to gimli, let's ensure that the error has the actual constant available in it. These values are not visible in `Error::description` or the various other error-reporting functions which use it, such as the `Display` implementation. I think it would be good to improve that too, but wanted to keep this PR relatively small. --- src/read/cfi.rs | 12 ++++++------ src/read/dwarf.rs | 2 +- src/read/index.rs | 4 ++-- src/read/line.rs | 2 +- src/read/loclists.rs | 4 ++-- src/read/mod.rs | 29 +++++++++++++++++++++-------- src/read/rnglists.rs | 4 ++-- src/read/unit.rs | 10 ++++++---- 8 files changed, 41 insertions(+), 26 deletions(-) diff --git a/src/read/cfi.rs b/src/read/cfi.rs index e43b8714..93fca012 100644 --- a/src/read/cfi.rs +++ b/src/read/cfi.rs @@ -268,7 +268,7 @@ impl<'a, 'bases, R: Reader> EhHdrTableIter<'a, 'bases, R> { constants::DW_EH_PE_sdata2 | constants::DW_EH_PE_udata2 => 2, constants::DW_EH_PE_sdata4 | constants::DW_EH_PE_udata4 => 4, constants::DW_EH_PE_sdata8 | constants::DW_EH_PE_udata8 => 8, - _ => return Err(Error::UnknownPointerEncoding), + format => return Err(Error::UnknownPointerEncoding(format)), }; let row_size = size * 2; @@ -335,7 +335,7 @@ impl<'a, R: Reader + 'a> EhHdrTable<'a, R> { constants::DW_EH_PE_sdata2 | constants::DW_EH_PE_udata2 => 2, constants::DW_EH_PE_sdata4 | constants::DW_EH_PE_udata4 => 4, constants::DW_EH_PE_sdata8 | constants::DW_EH_PE_udata8 => 8, - _ => return Err(Error::UnknownPointerEncoding), + format => return Err(Error::UnknownPointerEncoding(format)), }; let row_size = size * 2; @@ -3493,7 +3493,7 @@ fn parse_pointer_encoding(input: &mut R) -> Result if eh_pe.is_valid_encoding() { Ok(eh_pe) } else { - Err(Error::UnknownPointerEncoding) + Err(Error::UnknownPointerEncoding(eh_pe)) } } @@ -3562,7 +3562,7 @@ fn parse_encoded_pointer( ) -> Result { // TODO: check this once only in parse_pointer_encoding if !encoding.is_valid_encoding() { - return Err(Error::UnknownPointerEncoding); + return Err(Error::UnknownPointerEncoding(encoding)); } if encoding == constants::DW_EH_PE_omit { @@ -7383,7 +7383,7 @@ mod tests { let input = [expected.0, 1, 2, 3, 4]; let input = &mut EndianSlice::new(&input, NativeEndian); assert_eq!( - Err(Error::UnknownPointerEncoding), + Err(Error::UnknownPointerEncoding(expected)), parse_pointer_encoding(input) ); } @@ -7840,7 +7840,7 @@ mod tests { }; assert_eq!( parse_encoded_pointer(encoding, ¶meters, &mut rest), - Err(Error::UnknownPointerEncoding) + Err(Error::UnknownPointerEncoding(encoding)) ); } diff --git a/src/read/dwarf.rs b/src/read/dwarf.rs index b437c759..e04ddfd6 100644 --- a/src/read/dwarf.rs +++ b/src/read/dwarf.rs @@ -1048,7 +1048,7 @@ impl DwarfPackage { SectionId::DebugMacro | SectionId::DebugMacinfo => { // These are valid but we can't parse these yet. } - _ => return Err(Error::UnknownIndexSection), + _ => return Err(Error::UnknownSection(section.section)), } } diff --git a/src/read/index.rs b/src/read/index.rs index 22b8f240..e24c1c9c 100644 --- a/src/read/index.rs +++ b/src/read/index.rs @@ -189,7 +189,7 @@ impl UnitIndex { constants::DW_SECT_V2_STR_OFFSETS => SectionId::DebugStrOffsets, constants::DW_SECT_V2_MACINFO => SectionId::DebugMacinfo, constants::DW_SECT_V2_MACRO => SectionId::DebugMacro, - _ => return Err(Error::UnknownIndexSection), + section => return Err(Error::UnknownIndexSectionV2(section)), } } else { match constants::DwSect(section) { @@ -200,7 +200,7 @@ impl UnitIndex { constants::DW_SECT_STR_OFFSETS => SectionId::DebugStrOffsets, constants::DW_SECT_MACRO => SectionId::DebugMacro, constants::DW_SECT_RNGLISTS => SectionId::DebugRngLists, - _ => return Err(Error::UnknownIndexSection), + section => return Err(Error::UnknownIndexSection(section)), } }; } diff --git a/src/read/line.rs b/src/read/line.rs index 6b9c256a..e77f88d9 100644 --- a/src/read/line.rs +++ b/src/read/line.rs @@ -1874,7 +1874,7 @@ fn parse_attribute( AttributeValue::DebugStrOffsetsIndex(DebugStrOffsetsIndex(index)) } _ => { - return Err(Error::UnknownForm); + return Err(Error::UnknownForm(form)); } }) } diff --git a/src/read/loclists.rs b/src/read/loclists.rs index 469cf71e..762acf73 100644 --- a/src/read/loclists.rs +++ b/src/read/loclists.rs @@ -478,8 +478,8 @@ impl RawLocListEntry { length: input.read_uleb128()?, data: parse_data(input, encoding)?, }), - _ => { - return Err(Error::InvalidAddressRange); + format => { + return Err(Error::UnknownLocListsFormat(format)); } }, }) diff --git a/src/read/mod.rs b/src/read/mod.rs index 16b3f34a..e1d298e9 100644 --- a/src/read/mod.rs +++ b/src/read/mod.rs @@ -180,6 +180,7 @@ use std::{error, io}; use crate::common::{Register, SectionId}; use crate::constants; +use crate::DwForm; mod util; pub use util::*; @@ -305,7 +306,7 @@ pub enum Error { /// The specified length is impossible. BadLength, /// Found an unknown `DW_FORM_*` type. - UnknownForm, + UnknownForm(DwForm), /// Expected a zero, found something else. ExpectedZero, /// Found an abbreviation code that has already been used. @@ -317,7 +318,7 @@ pub enum Error { /// Found an unknown DWARF version. UnknownVersion(u64), /// Found a record with an unknown abbreviation code. - UnknownAbbreviation, + UnknownAbbreviation(u64), /// Hit the end of input before it was expected. UnexpectedEof(ReaderOffsetId), /// Read a null entry before it was expected. @@ -326,6 +327,10 @@ pub enum Error { UnknownStandardOpcode(constants::DwLns), /// Found an unknown extended opcode. UnknownExtendedOpcode(constants::DwLne), + /// Found an unknown location-lists format. + UnknownLocListsFormat(constants::DwLle), + /// Found an unknown range-lists format. + UnknownRangeListsFormat(constants::DwRle), /// The specified address size is not supported. UnsupportedAddressSize(u8), /// The specified offset size is not supported. @@ -395,7 +400,7 @@ pub enum Error { /// An offset value was larger than the maximum supported value. UnsupportedOffset, /// The given pointer encoding is either unknown or invalid. - UnknownPointerEncoding, + UnknownPointerEncoding(constants::DwEhPe), /// Did not find an entry at the given offset. NoEntryAtGivenOffset, /// The given offset is out of bounds. @@ -436,8 +441,12 @@ pub enum Error { InvalidIndexSlotCount, /// Invalid hash row in `.dwp` index. InvalidIndexRow, + /// Unknown section type. + UnknownSection(SectionId), /// Unknown section type in `.dwp` index. - UnknownIndexSection, + UnknownIndexSection(constants::DwSect), + /// Unknown section type in version 2 `.dwp` index. + UnknownIndexSectionV2(constants::DwSectV2), } impl fmt::Display for Error { @@ -482,7 +491,7 @@ impl Error { `DW_CHILDREN_{yes,no}`" } Error::BadLength => "The specified length is impossible", - Error::UnknownForm => "Found an unknown `DW_FORM_*` type", + Error::UnknownForm(_) => "Found an unknown `DW_FORM_*` type", Error::ExpectedZero => "Expected a zero, found something else", Error::DuplicateAbbreviationCode => { "Found an abbreviation code that has already been used" @@ -490,11 +499,13 @@ impl Error { Error::DuplicateArange => "Found a duplicate arange", Error::UnknownReservedLength => "Found an unknown reserved length value", Error::UnknownVersion(_) => "Found an unknown DWARF version", - Error::UnknownAbbreviation => "Found a record with an unknown abbreviation code", + Error::UnknownAbbreviation(_) => "Found a record with an unknown abbreviation code", Error::UnexpectedEof(_) => "Hit the end of input before it was expected", Error::UnexpectedNull => "Read a null entry before it was expected.", Error::UnknownStandardOpcode(_) => "Found an unknown standard opcode", Error::UnknownExtendedOpcode(_) => "Found an unknown extended opcode", + Error::UnknownLocListsFormat(_) => "Found an unknown location lists format", + Error::UnknownRangeListsFormat(_) => "Found an unknown range lists format", Error::UnsupportedAddressSize(_) => "The specified address size is not supported", Error::UnsupportedOffsetSize(_) => "The specified offset size is not supported", Error::UnsupportedFieldSize(_) => "The specified field size is not supported", @@ -551,7 +562,7 @@ impl Error { Error::UnsupportedOffset => { "An offset value was larger than the maximum supported value." } - Error::UnknownPointerEncoding => { + Error::UnknownPointerEncoding(_) => { "The given pointer encoding is either unknown or invalid." } Error::NoEntryAtGivenOffset => "Did not find an entry at the given offset.", @@ -586,7 +597,9 @@ 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::UnknownIndexSection => "Unknown section type 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.", } } } diff --git a/src/read/rnglists.rs b/src/read/rnglists.rs index 72671838..c644aa33 100644 --- a/src/read/rnglists.rs +++ b/src/read/rnglists.rs @@ -415,8 +415,8 @@ impl RawRngListEntry { begin: input.read_address(encoding.address_size)?, length: input.read_uleb128()?, }), - _ => { - return Err(Error::InvalidAddressRange); + format => { + return Err(Error::UnknownRangeListsFormat(format)); } }, }) diff --git a/src/read/unit.rs b/src/read/unit.rs index 0f3be72e..bd62aa90 100644 --- a/src/read/unit.rs +++ b/src/read/unit.rs @@ -912,7 +912,9 @@ where if code == 0 { return Ok(None); }; - let abbrev = abbreviations.get(code).ok_or(Error::UnknownAbbreviation)?; + let abbrev = abbreviations + .get(code) + .ok_or(Error::UnknownAbbreviation(code))?; Ok(Some(DebuggingInformationEntry { offset: UnitOffset(offset), attrs_slice: input.clone(), @@ -2180,7 +2182,7 @@ pub(crate) fn parse_attribute( AttributeValue::DebugRngListsIndex(DebugRngListsIndex(index)) } _ => { - return Err(Error::UnknownForm); + return Err(Error::UnknownForm(form)); } }; let attr = Attribute { @@ -2246,7 +2248,7 @@ pub(crate) fn skip_attributes( input.skip_leb128()?; } _ => { - return Err(Error::UnknownForm); + return Err(Error::UnknownForm(form)); } }; break; @@ -2425,7 +2427,7 @@ impl<'abbrev, 'unit, R: Reader> EntriesRaw<'abbrev, 'unit, R> { let abbrev = self .abbreviations .get(code) - .ok_or(Error::UnknownAbbreviation)?; + .ok_or(Error::UnknownAbbreviation(code))?; if abbrev.has_children() { self.depth += 1; } From aa754654acb71526dd6a8a0fbf98f19da9f7be2d Mon Sep 17 00:00:00 2001 From: Jamey Sharp Date: Wed, 22 May 2024 23:07:06 -0700 Subject: [PATCH 2/2] Review comments --- src/read/cfi.rs | 4 ++-- src/read/loclists.rs | 4 ++-- src/read/mod.rs | 11 +++++------ src/read/rnglists.rs | 4 ++-- 4 files changed, 11 insertions(+), 12 deletions(-) diff --git a/src/read/cfi.rs b/src/read/cfi.rs index 93fca012..5aa88468 100644 --- a/src/read/cfi.rs +++ b/src/read/cfi.rs @@ -268,7 +268,7 @@ impl<'a, 'bases, R: Reader> EhHdrTableIter<'a, 'bases, R> { constants::DW_EH_PE_sdata2 | constants::DW_EH_PE_udata2 => 2, constants::DW_EH_PE_sdata4 | constants::DW_EH_PE_udata4 => 4, constants::DW_EH_PE_sdata8 | constants::DW_EH_PE_udata8 => 8, - format => return Err(Error::UnknownPointerEncoding(format)), + _ => return Err(Error::UnknownPointerEncoding(self.hdr.table_enc)), }; let row_size = size * 2; @@ -335,7 +335,7 @@ impl<'a, R: Reader + 'a> EhHdrTable<'a, R> { constants::DW_EH_PE_sdata2 | constants::DW_EH_PE_udata2 => 2, constants::DW_EH_PE_sdata4 | constants::DW_EH_PE_udata4 => 4, constants::DW_EH_PE_sdata8 | constants::DW_EH_PE_udata8 => 8, - format => return Err(Error::UnknownPointerEncoding(format)), + _ => return Err(Error::UnknownPointerEncoding(self.hdr.table_enc)), }; let row_size = size * 2; diff --git a/src/read/loclists.rs b/src/read/loclists.rs index 762acf73..380b2c9e 100644 --- a/src/read/loclists.rs +++ b/src/read/loclists.rs @@ -478,8 +478,8 @@ impl RawLocListEntry { length: input.read_uleb128()?, data: parse_data(input, encoding)?, }), - format => { - return Err(Error::UnknownLocListsFormat(format)); + entry => { + return Err(Error::UnknownLocListsEntry(entry)); } }, }) diff --git a/src/read/mod.rs b/src/read/mod.rs index e1d298e9..9b974ecd 100644 --- a/src/read/mod.rs +++ b/src/read/mod.rs @@ -180,7 +180,6 @@ use std::{error, io}; use crate::common::{Register, SectionId}; use crate::constants; -use crate::DwForm; mod util; pub use util::*; @@ -306,7 +305,7 @@ pub enum Error { /// The specified length is impossible. BadLength, /// Found an unknown `DW_FORM_*` type. - UnknownForm(DwForm), + UnknownForm(constants::DwForm), /// Expected a zero, found something else. ExpectedZero, /// Found an abbreviation code that has already been used. @@ -328,9 +327,9 @@ pub enum Error { /// Found an unknown extended opcode. UnknownExtendedOpcode(constants::DwLne), /// Found an unknown location-lists format. - UnknownLocListsFormat(constants::DwLle), + UnknownLocListsEntry(constants::DwLle), /// Found an unknown range-lists format. - UnknownRangeListsFormat(constants::DwRle), + UnknownRangeListsEntry(constants::DwRle), /// The specified address size is not supported. UnsupportedAddressSize(u8), /// The specified offset size is not supported. @@ -504,8 +503,8 @@ impl Error { Error::UnexpectedNull => "Read a null entry before it was expected.", Error::UnknownStandardOpcode(_) => "Found an unknown standard opcode", Error::UnknownExtendedOpcode(_) => "Found an unknown extended opcode", - Error::UnknownLocListsFormat(_) => "Found an unknown location lists format", - Error::UnknownRangeListsFormat(_) => "Found an unknown range lists format", + Error::UnknownLocListsEntry(_) => "Found an unknown location lists entry", + Error::UnknownRangeListsEntry(_) => "Found an unknown range lists entry", Error::UnsupportedAddressSize(_) => "The specified address size is not supported", Error::UnsupportedOffsetSize(_) => "The specified offset size is not supported", Error::UnsupportedFieldSize(_) => "The specified field size is not supported", diff --git a/src/read/rnglists.rs b/src/read/rnglists.rs index c644aa33..fcd9be13 100644 --- a/src/read/rnglists.rs +++ b/src/read/rnglists.rs @@ -415,8 +415,8 @@ impl RawRngListEntry { begin: input.read_address(encoding.address_size)?, length: input.read_uleb128()?, }), - format => { - return Err(Error::UnknownRangeListsFormat(format)); + entry => { + return Err(Error::UnknownRangeListsEntry(entry)); } }, })