diff --git a/src/read/loclists.rs b/src/read/loclists.rs index 0ec7eab0..6242aea8 100644 --- a/src/read/loclists.rs +++ b/src/read/loclists.rs @@ -576,6 +576,11 @@ impl LocListIter { raw_loc: RawLocListEntry, ) -> Result>> { let mask = !0 >> (64 - self.raw.encoding.address_size * 8); + let tombstone = if self.raw.encoding.version <= 4 { + mask - 1 + } else { + mask + }; let (range, data) = match raw_loc { RawLocListEntry::BaseAddress { addr } => { @@ -609,6 +614,9 @@ impl LocListIter { ), RawLocListEntry::AddressOrOffsetPair { begin, end, data } | RawLocListEntry::OffsetPair { begin, end, data } => { + if self.base_address == tombstone { + return Ok(None); + } let mut range = Range { begin, end }; range.add_base_address(self.base_address, self.raw.encoding.address_size); (range, data) @@ -624,6 +632,10 @@ impl LocListIter { } }; + if range.begin == tombstone { + return Ok(None); + } + if range.begin > range.end { self.raw.input.empty(); return Err(Error::InvalidLocationAddressRange); diff --git a/src/read/rnglists.rs b/src/read/rnglists.rs index bef50ac0..9bdf136a 100644 --- a/src/read/rnglists.rs +++ b/src/read/rnglists.rs @@ -510,6 +510,11 @@ impl RngListIter { #[doc(hidden)] pub fn convert_raw(&mut self, raw_range: RawRngListEntry) -> Result> { let mask = !0 >> (64 - self.raw.encoding.address_size * 8); + let tombstone = if self.raw.encoding.version <= 4 { + mask - 1 + } else { + mask + }; let range = match raw_range { RawRngListEntry::BaseAddress { addr } => { @@ -532,6 +537,9 @@ impl RngListIter { } RawRngListEntry::AddressOrOffsetPair { begin, end } | RawRngListEntry::OffsetPair { begin, end } => { + if self.base_address == tombstone { + return Ok(None); + } let mut range = Range { begin, end }; range.add_base_address(self.base_address, self.raw.encoding.address_size); range @@ -543,6 +551,10 @@ impl RngListIter { } }; + if range.begin == tombstone { + return Ok(None); + } + if range.begin > range.end { self.raw.input.empty(); return Err(Error::InvalidAddressRange); @@ -628,6 +640,7 @@ mod tests { #[test] fn test_rnglists_32() { + let tombstone = !0u32; let encoding = Encoding { format: Format::Dwarf32, version: 5, @@ -637,7 +650,9 @@ mod tests { .L32(0x0300_0000) .L32(0x0301_0300) .L32(0x0301_0400) - .L32(0x0301_0500); + .L32(0x0301_0500) + .L32(tombstone) + .L32(0x0301_0600); let buf = section.get_contents().unwrap(); let debug_addr = &DebugAddr::from(EndianSlice::new(&buf, LittleEndian)); let debug_addr_base = DebugAddrBase(0); @@ -655,8 +670,25 @@ mod tests { .L8(0) .L32(0) .mark(&first) - // OffsetPair + // An OffsetPair using the unit base address. .L8(4).uleb(0x10200).uleb(0x10300) + + // Tombstone entries, all of which should be ignored. + // A BaseAddressx that is a tombstone. + .L8(1).uleb(4) + .L8(4).uleb(0x11100).uleb(0x11200) + // A BaseAddress that is a tombstone. + .L8(5).L32(tombstone) + .L8(4).uleb(0x11300).uleb(0x11400) + // A StartxEndx that is a tombstone. + .L8(2).uleb(4).uleb(5) + // A StartxLength that is a tombstone. + .L8(3).uleb(4).uleb(0x100) + // A StartEnd that is a tombstone. + .L8(6).L32(tombstone).L32(0x201_1500) + // A StartLength that is a tombstone. + .L8(7).L32(tombstone).uleb(0x100) + // A base address selection followed by an OffsetPair. .L8(5).L32(0x0200_0000) .L8(4).uleb(0x10400).uleb(0x10500) @@ -820,6 +852,7 @@ mod tests { #[test] fn test_rnglists_64() { + let tombstone = !0u64; let encoding = Encoding { format: Format::Dwarf64, version: 5, @@ -829,7 +862,9 @@ mod tests { .L64(0x0300_0000) .L64(0x0301_0300) .L64(0x0301_0400) - .L64(0x0301_0500); + .L64(0x0301_0500) + .L64(tombstone) + .L64(0x0301_0600); let buf = section.get_contents().unwrap(); let debug_addr = &DebugAddr::from(EndianSlice::new(&buf, LittleEndian)); let debug_addr_base = DebugAddrBase(0); @@ -848,8 +883,25 @@ mod tests { .L8(0) .L32(0) .mark(&first) - // OffsetPair + // An OffsetPair using the unit base address. .L8(4).uleb(0x10200).uleb(0x10300) + + // Tombstone entries, all of which should be ignored. + // A BaseAddressx that is a tombstone. + .L8(1).uleb(4) + .L8(4).uleb(0x11100).uleb(0x11200) + // A BaseAddress that is a tombstone. + .L8(5).L64(tombstone) + .L8(4).uleb(0x11300).uleb(0x11400) + // A StartxEndx that is a tombstone. + .L8(2).uleb(4).uleb(5) + // A StartxLength that is a tombstone. + .L8(3).uleb(4).uleb(0x100) + // A StartEnd that is a tombstone. + .L8(6).L64(tombstone).L64(0x201_1500) + // A StartLength that is a tombstone. + .L8(7).L64(tombstone).uleb(0x100) + // A base address selection followed by an OffsetPair. .L8(5).L64(0x0200_0000) .L8(4).uleb(0x10400).uleb(0x10500) @@ -1045,6 +1097,7 @@ mod tests { #[test] fn test_ranges_32() { + let tombstone = !0u32 - 1; let start = Label::new(); let first = Label::new(); #[rustfmt::skip] @@ -1066,6 +1119,11 @@ mod tests { // A range that ends at -1. .L32(0xffff_ffff).L32(0x0000_0000) .L32(0).L32(0xffff_ffff) + // A normal range with tombstone. + .L32(tombstone).L32(tombstone) + // A base address selection with tombstone followed by a normal range. + .L32(0xffff_ffff).L32(tombstone) + .L32(0x10a00).L32(0x10b00) // A range end. .L32(0).L32(0) // Some extra data. @@ -1157,6 +1215,7 @@ mod tests { #[test] fn test_ranges_64() { + let tombstone = !0u64 - 1; let start = Label::new(); let first = Label::new(); #[rustfmt::skip] @@ -1178,6 +1237,11 @@ mod tests { // A range that ends at -1. .L64(0xffff_ffff_ffff_ffff).L64(0x0000_0000) .L64(0).L64(0xffff_ffff_ffff_ffff) + // A normal range with tombstone. + .L64(tombstone).L64(tombstone) + // A base address selection with tombstone followed by a normal range. + .L64(0xffff_ffff_ffff_ffff).L64(tombstone) + .L64(0x10a00).L64(0x10b00) // A range end. .L64(0).L64(0) // Some extra data.