Adjust a ValueObjectChild's offset when the child is a bitfield

If a bitfield doesn't fit into the child_byte_size'd window at
child_byte_offset, move the window forward until it fits.  The problem
here is that Value has no notion of bitfields and thus the Value's
DataExtractor is sized like the bitfields CompilerType; a sequence of
bitfields, however, can be larger than their underlying type.

This was not in the big-endian-derived DWARF 2 bitfield attributes
because their offsets were counted from the end of the window, so they
always fit.

rdar://problem/53132189

Differential Revision: https://reviews.llvm.org/D65492

llvm-svn: 368226
This commit is contained in:
Adrian Prantl 2019-08-07 22:40:05 +00:00
parent beb5150f47
commit f81d6fe75c
3 changed files with 35 additions and 0 deletions

View File

@ -146,6 +146,9 @@ class BitfieldsTestCase(TestBase):
'(uint8_t:1) b17 = \'\\0\'',
])
self.expect("v/x large_packed", VARIABLES_DISPLAYED_CORRECTLY,
substrs=["a = 0x0000000cbbbbaaaa", "b = 0x0000000dffffeee"])
@add_test_categories(['pyapi'])
# BitFields exhibit crashes in record layout on Windows

View File

@ -90,6 +90,14 @@ int main (int argc, char const *argv[])
packed.b = 10;
packed.c = 0x7112233;
struct LargePackedBits {
unsigned long a: 36;
unsigned long b: 36;
} __attribute__((packed));
struct LargePackedBits large_packed =
(struct LargePackedBits){ 0xcbbbbaaaa, 0xdffffeeee };
return 0; //// Set break point at this line.
}

View File

@ -175,6 +175,30 @@ bool ValueObjectChild::UpdateValue() {
// Set this object's scalar value to the address of its value by
// adding its byte offset to the parent address
m_value.GetScalar() += GetByteOffset();
// If a bitfield doesn't fit into the child_byte_size'd
// window at child_byte_offset, move the window forward
// until it fits. The problem here is that Value has no
// notion of bitfields and thus the Value's DataExtractor
// is sized like the bitfields CompilerType; a sequence of
// bitfields, however, can be larger than their underlying
// type.
if (m_bitfield_bit_offset) {
const bool thread_and_frame_only_if_stopped = true;
ExecutionContext exe_ctx(GetExecutionContextRef().Lock(
thread_and_frame_only_if_stopped));
if (auto type_bit_size = GetCompilerType().GetBitSize(
exe_ctx.GetBestExecutionContextScope())) {
uint64_t bitfield_end =
m_bitfield_bit_size + m_bitfield_bit_offset;
if (bitfield_end > *type_bit_size) {
uint64_t overhang_bytes =
(bitfield_end - *type_bit_size + 7) / 8;
m_value.GetScalar() += overhang_bytes;
m_bitfield_bit_offset -= overhang_bytes * 8;
}
}
}
}
} break;