diff options
Diffstat (limited to 'vendor/gimli/src')
-rw-r--r-- | vendor/gimli/src/constants.rs | 2 | ||||
-rw-r--r-- | vendor/gimli/src/lib.rs | 2 | ||||
-rw-r--r-- | vendor/gimli/src/read/abbrev.rs | 2 | ||||
-rw-r--r-- | vendor/gimli/src/read/aranges.rs | 2 | ||||
-rw-r--r-- | vendor/gimli/src/read/cfi.rs | 134 | ||||
-rw-r--r-- | vendor/gimli/src/read/line.rs | 2 | ||||
-rw-r--r-- | vendor/gimli/src/read/lists.rs | 1 | ||||
-rw-r--r-- | vendor/gimli/src/read/loclists.rs | 4 | ||||
-rw-r--r-- | vendor/gimli/src/read/mod.rs | 2 | ||||
-rw-r--r-- | vendor/gimli/src/read/op.rs | 21 | ||||
-rw-r--r-- | vendor/gimli/src/read/pubnames.rs | 2 | ||||
-rw-r--r-- | vendor/gimli/src/read/pubtypes.rs | 2 | ||||
-rw-r--r-- | vendor/gimli/src/read/rnglists.rs | 4 | ||||
-rw-r--r-- | vendor/gimli/src/read/str.rs | 4 | ||||
-rw-r--r-- | vendor/gimli/src/read/unit.rs | 4 | ||||
-rw-r--r-- | vendor/gimli/src/read/util.rs | 2 | ||||
-rw-r--r-- | vendor/gimli/src/read/value.rs | 2 | ||||
-rw-r--r-- | vendor/gimli/src/write/cfi.rs | 15 | ||||
-rw-r--r-- | vendor/gimli/src/write/op.rs | 6 |
19 files changed, 185 insertions, 28 deletions
diff --git a/vendor/gimli/src/constants.rs b/vendor/gimli/src/constants.rs index c8d6a1662..c617f4e2e 100644 --- a/vendor/gimli/src/constants.rs +++ b/vendor/gimli/src/constants.rs @@ -1315,7 +1315,7 @@ DwEhPe(u8) { // pointer result itself. // // This isn't defined in the DWARF or the `.eh_frame` standards, but is -// generated by both GNU/Linux and OSX tooling. +// generated by both GNU/Linux and macOS tooling. DW_EH_PE_indirect = 0x80, // These constants apply to both the lower and upper bits. diff --git a/vendor/gimli/src/lib.rs b/vendor/gimli/src/lib.rs index 7ac1820e3..ed1af9cbd 100644 --- a/vendor/gimli/src/lib.rs +++ b/vendor/gimli/src/lib.rs @@ -1,5 +1,5 @@ //! `gimli` is a library for reading and writing the -//! [DWARF debugging format](http://dwarfstd.org/). +//! [DWARF debugging format](https://dwarfstd.org/). //! //! See the [read](./read/index.html) and [write](./write/index.html) modules //! for examples and API documentation. diff --git a/vendor/gimli/src/read/abbrev.rs b/vendor/gimli/src/read/abbrev.rs index 5f0e7bed7..1a24835a7 100644 --- a/vendor/gimli/src/read/abbrev.rs +++ b/vendor/gimli/src/read/abbrev.rs @@ -29,7 +29,7 @@ where /// /// It is the caller's responsibility to read the `.debug_abbrev` section and /// present it as a `&[u8]` slice. That means using some ELF loader on - /// Linux, a Mach-O loader on OSX, etc. + /// Linux, a Mach-O loader on macOS, etc. /// /// ``` /// use gimli::{DebugAbbrev, LittleEndian}; diff --git a/vendor/gimli/src/read/aranges.rs b/vendor/gimli/src/read/aranges.rs index c2d22850c..83159b69b 100644 --- a/vendor/gimli/src/read/aranges.rs +++ b/vendor/gimli/src/read/aranges.rs @@ -18,7 +18,7 @@ where /// /// It is the caller's responsibility to read the `.debug_aranges` section and /// present it as a `&[u8]` slice. That means using some ELF loader on - /// Linux, a Mach-O loader on OSX, etc. + /// Linux, a Mach-O loader on macOS, etc. /// /// ``` /// use gimli::{DebugAranges, LittleEndian}; diff --git a/vendor/gimli/src/read/cfi.rs b/vendor/gimli/src/read/cfi.rs index b6a81f3f4..2e5167349 100644 --- a/vendor/gimli/src/read/cfi.rs +++ b/vendor/gimli/src/read/cfi.rs @@ -63,7 +63,7 @@ where /// /// It is the caller's responsibility to read the section and present it as /// a `&[u8]` slice. That means using some ELF loader on Linux, a Mach-O - /// loader on OSX, etc. + /// loader on macOS, etc. /// /// ``` /// use gimli::{DebugFrame, NativeEndian}; @@ -218,6 +218,81 @@ impl<R: Reader> ParsedEhFrameHdr<R> { } } +/// An iterator for `.eh_frame_hdr` section's binary search table. +/// +/// Each table entry consists of a tuple containing an `initial_location` and `address`. +/// The `initial location` represents the first address that the targeted FDE +/// is able to decode. The `address` is the address of the FDE in the `.eh_frame` section. +/// The `address` can be converted with `EhHdrTable::pointer_to_offset` and `EhFrame::fde_from_offset` to an FDE. +#[derive(Debug)] +pub struct EhHdrTableIter<'a, 'bases, R: Reader> { + hdr: &'a ParsedEhFrameHdr<R>, + table: R, + bases: &'bases BaseAddresses, + remain: u64, +} + +impl<'a, 'bases, R: Reader> EhHdrTableIter<'a, 'bases, R> { + /// Yield the next entry in the `EhHdrTableIter`. + pub fn next(&mut self) -> Result<Option<(Pointer, Pointer)>> { + if self.remain == 0 { + return Ok(None); + } + + let parameters = PointerEncodingParameters { + bases: &self.bases.eh_frame_hdr, + func_base: None, + address_size: self.hdr.address_size, + section: &self.hdr.section, + }; + + self.remain -= 1; + let from = parse_encoded_pointer(self.hdr.table_enc, ¶meters, &mut self.table)?; + let to = parse_encoded_pointer(self.hdr.table_enc, ¶meters, &mut self.table)?; + Ok(Some((from, to))) + } + /// Yield the nth entry in the `EhHdrTableIter` + pub fn nth(&mut self, n: usize) -> Result<Option<(Pointer, Pointer)>> { + use core::convert::TryFrom; + let size = match self.hdr.table_enc.format() { + constants::DW_EH_PE_uleb128 | constants::DW_EH_PE_sleb128 => { + return Err(Error::VariableLengthSearchTable); + } + 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), + }; + + let row_size = size * 2; + let n = u64::try_from(n).map_err(|_| Error::UnsupportedOffset)?; + self.remain = self.remain.saturating_sub(n); + self.table.skip(R::Offset::from_u64(n * row_size)?)?; + self.next() + } +} + +#[cfg(feature = "fallible-iterator")] +impl<'a, 'bases, R: Reader> fallible_iterator::FallibleIterator for EhHdrTableIter<'a, 'bases, R> { + type Item = (Pointer, Pointer); + type Error = Error; + fn next(&mut self) -> Result<Option<Self::Item>> { + EhHdrTableIter::next(self) + } + + fn size_hint(&self) -> (usize, Option<usize>) { + use core::convert::TryInto; + ( + self.remain.try_into().unwrap_or(0), + self.remain.try_into().ok(), + ) + } + + fn nth(&mut self, n: usize) -> Result<Option<Self::Item>> { + EhHdrTableIter::nth(self, n) + } +} + /// The CFI binary search table that is an optional part of the `.eh_frame_hdr` section. #[derive(Debug, Clone)] pub struct EhHdrTable<'a, R: Reader> { @@ -225,6 +300,20 @@ pub struct EhHdrTable<'a, R: Reader> { } impl<'a, R: Reader + 'a> EhHdrTable<'a, R> { + /// Return an iterator that can walk the `.eh_frame_hdr` table. + /// + /// Each table entry consists of a tuple containing an `initial_location` and `address`. + /// The `initial location` represents the first address that the targeted FDE + /// is able to decode. The `address` is the address of the FDE in the `.eh_frame` section. + /// The `address` can be converted with `EhHdrTable::pointer_to_offset` and `EhFrame::fde_from_offset` to an FDE. + pub fn iter<'bases>(&self, bases: &'bases BaseAddresses) -> EhHdrTableIter<'_, 'bases, R> { + EhHdrTableIter { + hdr: self.hdr, + bases, + remain: self.hdr.fde_count, + table: self.hdr.table.clone(), + } + } /// *Probably* returns a pointer to the FDE for the given address. /// /// This performs a binary search, so if there is no FDE for the given address, @@ -423,19 +512,19 @@ where Endian: Endianity, { /// Construct a new `EhFrame` instance from the data in the - /// `.debug_frame` section. + /// `.eh_frame` section. /// /// It is the caller's responsibility to read the section and present it as /// a `&[u8]` slice. That means using some ELF loader on Linux, a Mach-O - /// loader on OSX, etc. + /// loader on macOS, etc. /// /// ``` /// use gimli::{EhFrame, EndianSlice, NativeEndian}; /// - /// // Use with `.debug_frame` + /// // Use with `.eh_frame` /// # let buf = [0x00, 0x01, 0x02, 0x03]; - /// # let read_debug_frame_section_somehow = || &buf; - /// let debug_frame = EhFrame::new(read_debug_frame_section_somehow(), NativeEndian); + /// # let read_eh_frame_section_somehow = || &buf; + /// let eh_frame = EhFrame::new(read_eh_frame_section_somehow(), NativeEndian); /// ``` pub fn new(section: &'input [u8], endian: Endian) -> Self { Self::from(EndianSlice::new(section, endian)) @@ -6211,6 +6300,39 @@ mod tests { let table = table.unwrap(); let bases = Default::default(); + let mut iter = table.iter(&bases); + assert_eq!( + iter.next(), + Ok(Some(( + Pointer::Direct(10), + Pointer::Direct(0x12345 + start_of_fde1.value().unwrap() as u64) + ))) + ); + assert_eq!( + iter.next(), + Ok(Some(( + Pointer::Direct(20), + Pointer::Direct(0x12345 + start_of_fde2.value().unwrap() as u64) + ))) + ); + assert_eq!(iter.next(), Ok(None)); + + assert_eq!( + table.iter(&bases).nth(0), + Ok(Some(( + Pointer::Direct(10), + Pointer::Direct(0x12345 + start_of_fde1.value().unwrap() as u64) + ))) + ); + + assert_eq!( + table.iter(&bases).nth(1), + Ok(Some(( + Pointer::Direct(20), + Pointer::Direct(0x12345 + start_of_fde2.value().unwrap() as u64) + ))) + ); + assert_eq!(table.iter(&bases).nth(2), Ok(None)); let f = |_: &_, _: &_, o: EhFrameOffset| { assert_eq!(o, EhFrameOffset(start_of_cie.value().unwrap() as usize)); diff --git a/vendor/gimli/src/read/line.rs b/vendor/gimli/src/read/line.rs index 096ddf07b..0e7380bb9 100644 --- a/vendor/gimli/src/read/line.rs +++ b/vendor/gimli/src/read/line.rs @@ -27,7 +27,7 @@ where /// /// It is the caller's responsibility to read the `.debug_line` section and /// present it as a `&[u8]` slice. That means using some ELF loader on - /// Linux, a Mach-O loader on OSX, etc. + /// Linux, a Mach-O loader on macOS, etc. /// /// ``` /// use gimli::{DebugLine, LittleEndian}; diff --git a/vendor/gimli/src/read/lists.rs b/vendor/gimli/src/read/lists.rs index b63c5c126..898a757d3 100644 --- a/vendor/gimli/src/read/lists.rs +++ b/vendor/gimli/src/read/lists.rs @@ -4,6 +4,7 @@ use crate::read::{Error, Reader, Result}; #[derive(Debug, Clone, Copy)] pub(crate) struct ListsHeader { encoding: Encoding, + #[allow(dead_code)] offset_entry_count: u32, } diff --git a/vendor/gimli/src/read/loclists.rs b/vendor/gimli/src/read/loclists.rs index 3c4da127d..3902c181b 100644 --- a/vendor/gimli/src/read/loclists.rs +++ b/vendor/gimli/src/read/loclists.rs @@ -24,7 +24,7 @@ where /// /// It is the caller's responsibility to read the `.debug_loc` section and /// present it as a `&[u8]` slice. That means using some ELF loader on - /// Linux, a Mach-O loader on OSX, etc. + /// Linux, a Mach-O loader on macOS, etc. /// /// ``` /// use gimli::{DebugLoc, LittleEndian}; @@ -70,7 +70,7 @@ where /// /// It is the caller's responsibility to read the `.debug_loclists` section and /// present it as a `&[u8]` slice. That means using some ELF loader on - /// Linux, a Mach-O loader on OSX, etc. + /// Linux, a Mach-O loader on macOS, etc. /// /// ``` /// use gimli::{DebugLocLists, LittleEndian}; diff --git a/vendor/gimli/src/read/mod.rs b/vendor/gimli/src/read/mod.rs index 7291f3b96..3110957c2 100644 --- a/vendor/gimli/src/read/mod.rs +++ b/vendor/gimli/src/read/mod.rs @@ -48,7 +48,7 @@ //! //! * [An `addr2line` clone](https://github.com/gimli-rs/addr2line) //! -//! * [`ddbug`](https://github.com/philipc/ddbug), a utility giving insight into +//! * [`ddbug`](https://github.com/gimli-rs/ddbug), a utility giving insight into //! code generation by making debugging information readable //! //! * [`dwprod`](https://github.com/fitzgen/dwprod), a tiny utility to list the diff --git a/vendor/gimli/src/read/op.rs b/vendor/gimli/src/read/op.rs index 2ca6247bc..88ea20297 100644 --- a/vendor/gimli/src/read/op.rs +++ b/vendor/gimli/src/read/op.rs @@ -707,7 +707,13 @@ where } constants::DW_OP_stack_value => Ok(Operation::StackValue), constants::DW_OP_implicit_pointer | constants::DW_OP_GNU_implicit_pointer => { - let value = bytes.read_offset(encoding.format)?; + let value = if encoding.version == 2 { + bytes + .read_address(encoding.address_size) + .and_then(Offset::from_u64)? + } else { + bytes.read_offset(encoding.format)? + }; let byte_offset = bytes.read_sleb128()?; Ok(Operation::ImplicitPointer { value: DebugInfoOffset(value), @@ -2738,6 +2744,19 @@ mod tests { }, encoding8(), ); + + check_op_parse( + |s| s.D8(op.0).D64(0x1234_5678).sleb(0x123), + &Operation::ImplicitPointer { + value: DebugInfoOffset(0x1234_5678), + byte_offset: 0x123, + }, + Encoding { + format: Format::Dwarf32, + version: 2, + address_size: 8, + }, + ) } } diff --git a/vendor/gimli/src/read/pubnames.rs b/vendor/gimli/src/read/pubnames.rs index f05861f70..e8b7e5528 100644 --- a/vendor/gimli/src/read/pubnames.rs +++ b/vendor/gimli/src/read/pubnames.rs @@ -58,7 +58,7 @@ where /// /// It is the caller's responsibility to read the `.debug_pubnames` section and /// present it as a `&[u8]` slice. That means using some ELF loader on - /// Linux, a Mach-O loader on OSX, etc. + /// Linux, a Mach-O loader on macOS, etc. /// /// ``` /// use gimli::{DebugPubNames, LittleEndian}; diff --git a/vendor/gimli/src/read/pubtypes.rs b/vendor/gimli/src/read/pubtypes.rs index 0226e84d4..6723b4222 100644 --- a/vendor/gimli/src/read/pubtypes.rs +++ b/vendor/gimli/src/read/pubtypes.rs @@ -58,7 +58,7 @@ where /// /// It is the caller's responsibility to read the `.debug_pubtypes` section and /// present it as a `&[u8]` slice. That means using some ELF loader on - /// Linux, a Mach-O loader on OSX, etc. + /// Linux, a Mach-O loader on macOS, etc. /// /// ``` /// use gimli::{DebugPubTypes, LittleEndian}; diff --git a/vendor/gimli/src/read/rnglists.rs b/vendor/gimli/src/read/rnglists.rs index dd68083ac..d8d49042f 100644 --- a/vendor/gimli/src/read/rnglists.rs +++ b/vendor/gimli/src/read/rnglists.rs @@ -24,7 +24,7 @@ where /// /// It is the caller's responsibility to read the `.debug_ranges` section and /// present it as a `&[u8]` slice. That means using some ELF loader on - /// Linux, a Mach-O loader on OSX, etc. + /// Linux, a Mach-O loader on macOS, etc. /// /// ``` /// use gimli::{DebugRanges, LittleEndian}; @@ -70,7 +70,7 @@ where /// /// It is the caller's responsibility to read the `.debug_rnglists` /// section and present it as a `&[u8]` slice. That means using some ELF - /// loader on Linux, a Mach-O loader on OSX, etc. + /// loader on Linux, a Mach-O loader on macOS, etc. /// /// ``` /// use gimli::{DebugRngLists, LittleEndian}; diff --git a/vendor/gimli/src/read/str.rs b/vendor/gimli/src/read/str.rs index dce8016af..c6b87d8f9 100644 --- a/vendor/gimli/src/read/str.rs +++ b/vendor/gimli/src/read/str.rs @@ -22,7 +22,7 @@ where /// /// It is the caller's responsibility to read the `.debug_str` section and /// present it as a `&[u8]` slice. That means using some ELF loader on - /// Linux, a Mach-O loader on OSX, etc. + /// Linux, a Mach-O loader on macOS, etc. /// /// ``` /// use gimli::{DebugStr, LittleEndian}; @@ -214,7 +214,7 @@ where /// /// It is the caller's responsibility to read the `.debug_line_str` section and /// present it as a `&[u8]` slice. That means using some ELF loader on - /// Linux, a Mach-O loader on OSX, etc. + /// Linux, a Mach-O loader on macOS, etc. /// /// ``` /// use gimli::{DebugLineStr, LittleEndian}; diff --git a/vendor/gimli/src/read/unit.rs b/vendor/gimli/src/read/unit.rs index 4766b2e84..670e55efd 100644 --- a/vendor/gimli/src/read/unit.rs +++ b/vendor/gimli/src/read/unit.rs @@ -93,7 +93,7 @@ where /// /// It is the caller's responsibility to read the `.debug_info` section and /// present it as a `&[u8]` slice. That means using some ELF loader on - /// Linux, a Mach-O loader on OSX, etc. + /// Linux, a Mach-O loader on macOS, etc. /// /// ``` /// use gimli::{DebugInfo, LittleEndian}; @@ -3086,7 +3086,7 @@ where /// /// It is the caller's responsibility to read the `.debug_types` section and /// present it as a `&[u8]` slice. That means using some ELF loader on - /// Linux, a Mach-O loader on OSX, etc. + /// Linux, a Mach-O loader on macOS, etc. /// /// ``` /// use gimli::{DebugTypes, LittleEndian}; diff --git a/vendor/gimli/src/read/util.rs b/vendor/gimli/src/read/util.rs index dd2af8181..16eafdde4 100644 --- a/vendor/gimli/src/read/util.rs +++ b/vendor/gimli/src/read/util.rs @@ -180,7 +180,7 @@ impl<T> ArrayVec<Vec<T>> { let slice = Box::leak(storage); debug_assert!(len <= slice.len()); // SAFETY: valid elements. - unsafe { Vec::from_raw_parts(slice.as_ptr() as _, len, slice.len()) } + unsafe { Vec::from_raw_parts(slice.as_mut_ptr() as *mut T, len, slice.len()) } } } diff --git a/vendor/gimli/src/read/value.rs b/vendor/gimli/src/read/value.rs index fc8c355a9..6f43ebb26 100644 --- a/vendor/gimli/src/read/value.rs +++ b/vendor/gimli/src/read/value.rs @@ -1,7 +1,5 @@ //! Definitions for values used in DWARF expressions. -use core::mem; - use crate::constants; #[cfg(feature = "read")] use crate::read::{AttributeValue, DebuggingInformationEntry}; diff --git a/vendor/gimli/src/write/cfi.rs b/vendor/gimli/src/write/cfi.rs index c58eb1b1d..718cb69ad 100644 --- a/vendor/gimli/src/write/cfi.rs +++ b/vendor/gimli/src/write/cfi.rs @@ -239,7 +239,7 @@ impl CommonInformationEntry { } if let Some((eh_pe, address)) = self.personality { w.write_u8(eh_pe.0)?; - w.write_eh_pointer(address, constants::DW_EH_PE_absptr, encoding.address_size)?; + w.write_eh_pointer(address, eh_pe, encoding.address_size)?; } if self.fde_address_encoding != constants::DW_EH_PE_absptr { w.write_u8(self.fde_address_encoding.0)?; @@ -888,6 +888,19 @@ mod tests { fde4.lsda = Some(Address::Constant(0x4400)); frames.add_fde(cie2_id, fde4.clone()); + let mut cie3 = CommonInformationEntry::new(encoding, 1, 8, X86_64::RA); + cie3.fde_address_encoding = constants::DW_EH_PE_pcrel; + cie3.lsda_encoding = Some(constants::DW_EH_PE_pcrel); + cie3.personality = Some((constants::DW_EH_PE_pcrel, Address::Constant(0x1235))); + cie3.signal_trampoline = true; + let cie3_id = frames.add_cie(cie3.clone()); + assert_ne!(cie2_id, cie3_id); + assert_eq!(cie3_id, frames.add_cie(cie3.clone())); + + let mut fde5 = FrameDescriptionEntry::new(Address::Constant(0x5000), 0x50); + fde5.lsda = Some(Address::Constant(0x5500)); + frames.add_fde(cie3_id, fde5.clone()); + // Test writing `.debug_frame`. let mut debug_frame = DebugFrame::from(EndianVec::new(LittleEndian)); frames.write_debug_frame(&mut debug_frame).unwrap(); diff --git a/vendor/gimli/src/write/op.rs b/vendor/gimli/src/write/op.rs index d1cacb356..c70eec2dd 100644 --- a/vendor/gimli/src/write/op.rs +++ b/vendor/gimli/src/write/op.rs @@ -778,7 +778,11 @@ impl Operation { } else { w.write_u8(constants::DW_OP_GNU_implicit_pointer.0)?; } - let size = encoding.format.word_size(); + let size = if encoding.version == 2 { + encoding.address_size + } else { + encoding.format.word_size() + }; match entry { Reference::Symbol(symbol) => { w.write_reference(symbol, size)?; |