Skip to content

Commit

Permalink
read: ignore tombstone entries in range and location lists
Browse files Browse the repository at this point in the history
Co-authored-by: shuo <shuoli84@gmail.com>
  • Loading branch information
philipc and shuoli84 committed Oct 31, 2022
1 parent 074d5e8 commit 48a66a9
Show file tree
Hide file tree
Showing 2 changed files with 184 additions and 6 deletions.
96 changes: 94 additions & 2 deletions src/read/loclists.rs
Expand Up @@ -576,6 +576,11 @@ impl<R: Reader> LocListIter<R> {
raw_loc: RawLocListEntry<R>,
) -> Result<Option<LocationListEntry<R>>> {
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 } => {
Expand Down Expand Up @@ -609,6 +614,9 @@ impl<R: Reader> LocListIter<R> {
),
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)
Expand All @@ -624,6 +632,10 @@ impl<R: Reader> LocListIter<R> {
}
};

if range.begin == tombstone {
return Ok(None);
}

if range.begin > range.end {
self.raw.input.empty();
return Err(Error::InvalidLocationAddressRange);
Expand Down Expand Up @@ -664,6 +676,7 @@ mod tests {

#[test]
fn test_loclists_32() {
let tombstone = !0u32;
let encoding = Encoding {
format: Format::Dwarf32,
version: 5,
Expand All @@ -674,7 +687,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);
Expand Down Expand Up @@ -718,6 +733,25 @@ mod tests {
.L8(2).uleb(1).uleb(2).uleb(4).L32(12)
// A StartxLength
.L8(3).uleb(3).uleb(0x100).uleb(4).L32(13)

// Tombstone entries, all of which should be ignored.
// A BaseAddressx that is a tombstone.
.L8(1).uleb(4)
.L8(4).uleb(0x11100).uleb(0x11200).uleb(4).L32(20)
// A BaseAddress that is a tombstone.
.L8(6).L32(tombstone)
.L8(4).uleb(0x11300).uleb(0x11400).uleb(4).L32(21)
// A StartxEndx that is a tombstone.
.L8(2).uleb(4).uleb(5).uleb(4).L32(22)
// A StartxLength that is a tombstone.
.L8(3).uleb(4).uleb(0x100).uleb(4).L32(23)
// A StartEnd that is a tombstone.
.L8(7).L32(tombstone).L32(0x201_1500).uleb(4).L32(24)
// A StartLength that is a tombstone.
.L8(8).L32(tombstone).uleb(0x100).uleb(4).L32(25)
// A StartEnd (not ignored)
.L8(7).L32(0x201_1600).L32(0x201_1700).uleb(4).L32(26)

// A range end.
.L8(0)
// Some extra data.
Expand Down Expand Up @@ -875,6 +909,18 @@ mod tests {
}))
);

// A StartEnd location following the tombstones
assert_eq!(
locations.next(),
Ok(Some(LocationListEntry {
range: Range {
begin: 0x0201_1600,
end: 0x0201_1700,
},
data: Expression(EndianSlice::new(&[26, 0, 0, 0], LittleEndian)),
}))
);

// A location list end.
assert_eq!(locations.next(), Ok(None));

Expand All @@ -893,6 +939,7 @@ mod tests {

#[test]
fn test_loclists_64() {
let tombstone = !0u64;
let encoding = Encoding {
format: Format::Dwarf64,
version: 5,
Expand All @@ -903,7 +950,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);
Expand Down Expand Up @@ -948,6 +997,25 @@ mod tests {
.L8(2).uleb(1).uleb(2).uleb(4).L32(12)
// A StartxLength
.L8(3).uleb(3).uleb(0x100).uleb(4).L32(13)

// Tombstone entries, all of which should be ignored.
// A BaseAddressx that is a tombstone.
.L8(1).uleb(4)
.L8(4).uleb(0x11100).uleb(0x11200).uleb(4).L32(20)
// A BaseAddress that is a tombstone.
.L8(6).L64(tombstone)
.L8(4).uleb(0x11300).uleb(0x11400).uleb(4).L32(21)
// A StartxEndx that is a tombstone.
.L8(2).uleb(4).uleb(5).uleb(4).L32(22)
// A StartxLength that is a tombstone.
.L8(3).uleb(4).uleb(0x100).uleb(4).L32(23)
// A StartEnd that is a tombstone.
.L8(7).L64(tombstone).L64(0x201_1500).uleb(4).L32(24)
// A StartLength that is a tombstone.
.L8(8).L64(tombstone).uleb(0x100).uleb(4).L32(25)
// A StartEnd (not ignored)
.L8(7).L64(0x201_1600).L64(0x201_1700).uleb(4).L32(26)

// A range end.
.L8(0)
// Some extra data.
Expand Down Expand Up @@ -1105,6 +1173,18 @@ mod tests {
}))
);

// A StartEnd location following the tombstones
assert_eq!(
locations.next(),
Ok(Some(LocationListEntry {
range: Range {
begin: 0x0201_1600,
end: 0x0201_1700,
},
data: Expression(EndianSlice::new(&[26, 0, 0, 0], LittleEndian)),
}))
);

// A location list end.
assert_eq!(locations.next(), Ok(None));

Expand All @@ -1123,6 +1203,7 @@ mod tests {

#[test]
fn test_location_list_32() {
let tombstone = !0u32 - 1;
let start = Label::new();
let first = Label::new();
#[rustfmt::skip]
Expand All @@ -1144,6 +1225,11 @@ mod tests {
// A location range that ends at -1.
.L32(0xffff_ffff).L32(0x0000_0000)
.L32(0).L32(0xffff_ffff).L16(4).L32(7)
// A normal location with tombstone.
.L32(tombstone).L32(tombstone).L16(4).L32(8)
// A base address selection with tombstone followed by a normal location.
.L32(0xffff_ffff).L32(tombstone)
.L32(0x10a00).L32(0x10b00).L16(4).L32(9)
// A location list end.
.L32(0).L32(0)
// Some extra data.
Expand Down Expand Up @@ -1253,6 +1339,7 @@ mod tests {

#[test]
fn test_location_list_64() {
let tombstone = !0u64 - 1;
let start = Label::new();
let first = Label::new();
#[rustfmt::skip]
Expand All @@ -1274,6 +1361,11 @@ mod tests {
// A location range that ends at -1.
.L64(0xffff_ffff_ffff_ffff).L64(0x0000_0000)
.L64(0).L64(0xffff_ffff_ffff_ffff).L16(4).L32(7)
// A normal location with tombstone.
.L64(tombstone).L64(tombstone).L16(4).L32(8)
// A base address selection with tombstone followed by a normal location.
.L64(0xffff_ffff_ffff_ffff).L64(tombstone)
.L64(0x10a00).L64(0x10b00).L16(4).L32(9)
// A location list end.
.L64(0).L64(0)
// Some extra data.
Expand Down

0 comments on commit 48a66a9

Please sign in to comment.