Author: gclayton
Date: Wed Jul 6 18:11:13 2016
New Revision: 274701
URL: http://llvm.org/viewvc/llvm-project?rev=274701&view=rev
Log:
LLDB reads incorrect memory ranges when displaying bitfields when reading bits
from file memory.
Bitfields were not correctly describing their offsets within the integer that
they are contained within. If we had a bitfield like:
struct MyStruct {
uint32_t a:8;
uint32_t b:8;
};
ClangASTContext::GetChildCompilerTypeAtIndex would say that child a and b had
the following values in their respective ValueObjectChild objects:
name byte-size bit-size bit-offset byte-offset-from-parent
==== ========= ======== ========== =======================
"a" 4 8 0 0
"b" 4 8 0 1
So if we had a "MyStruct" at address 0x1000, we would end up reading 4 bytes
from 0x1000 for "a", and 4 bytes from 0x1001 for "b". The fix for this is to
fix the "child_byte_offset" and "child_bitfield_bit_offset" values returned by
ClangASTContext::GetChildCompilerTypeAtIndex() so that now the table looks like:
name byte-size bit-size bit-offset byte-offset-from-parent
==== ========= ======== ========== =======================
"a" 4 8 0 0
"b" 4 8 8 0
Then we don't run into a problem when reading data from a file's section info
using "target variable" before running. It will also stop us from not being
able to display a bitfield values if the bitfield is in the last bit of memory
before an unmapped region. (Like if address 0x1004 was unmapped and unreadable
in the example above, if we tried to read 4 bytes from 0x1001, the memory read
would fail and we wouldn't be able to display "b").
<rdar://problem/27208225>
Modified:
lldb/trunk/source/Symbol/ClangASTContext.cpp
Modified: lldb/trunk/source/Symbol/ClangASTContext.cpp
URL:
http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Symbol/ClangASTContext.cpp?rev=274701&r1=274700&r2=274701&view=diff
==============================================================================
--- lldb/trunk/source/Symbol/ClangASTContext.cpp (original)
+++ lldb/trunk/source/Symbol/ClangASTContext.cpp Wed Jul 6 18:11:13 2016
@@ -6274,12 +6274,20 @@ ClangASTContext::GetChildCompilerTypeAtI
CompilerType field_clang_type (getASTContext(),
field->getType());
assert(field_idx < record_layout.getFieldCount());
child_byte_size = field_clang_type.GetByteSize(exe_ctx
? exe_ctx->GetBestExecutionContextScope() : NULL);
+ const uint32_t child_bit_size = child_byte_size * 8;
// Figure out the field offset within the current
struct/union/class type
bit_offset = record_layout.getFieldOffset (field_idx);
- child_byte_offset = bit_offset / 8;
if (ClangASTContext::FieldIsBitfield (getASTContext(),
*field, child_bitfield_bit_size))
- child_bitfield_bit_offset = bit_offset % 8;
+ {
+ child_bitfield_bit_offset = bit_offset %
child_bit_size;
+ const uint32_t child_bit_offset = bit_offset -
child_bitfield_bit_offset;
+ child_byte_offset = child_bit_offset / 8;
+ }
+ else
+ {
+ child_byte_offset = bit_offset / 8;
+ }
return field_clang_type;
}
_______________________________________________
lldb-commits mailing list
[email protected]
http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits