[Lldb-commits] [lldb] r274701 - LLDB reads incorrect memory ranges when displaying bitfields when reading bits from file memory.

Greg Clayton via lldb-commits lldb-commits at lists.llvm.org
Wed Jul 6 16:11:13 PDT 2016


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;
                     }




More information about the lldb-commits mailing list