aprantl created this revision.
aprantl added a reviewer: clayborg.
aprantl added a subscriber: lldb-commits.
aprantl set the repository for this revision to rL LLVM.

The System-V x86_64 ABI requires floating point values to be passed in 128-but 
SSE vector registers (xmm0, ...).
When printing such a variable this currently yields an <invalid load address>.

This patch makes LLDB's DWARF expression evaluator accept 128-bit registers as 
scalars. It also relaxes the check that the size of the result of the DWARF 
expression be equal to the size of the variable to a greater-than. DWARF defers 
to the ABI how smaller values are being placed in a larger register.

Implementation note: I found the code in Value::SetContext() that changes the 
m_value_type after the fact to be questionable. I added a sanity check that the 
Value's memory buffer has indeed been written to (this is necessary, because we 
may have a scalar value in a vector register), but really I feel like this is 
the wrong place to be setting it.

<rdar://problem/24944340>

Repository:
  rL LLVM

http://reviews.llvm.org/D17897

Files:
  include/lldb/Core/Value.h
  
packages/Python/lldbsuite/test/lang/c/register_variables/TestRegisterVariables.py
  packages/Python/lldbsuite/test/lang/c/register_variables/test.c
  source/Core/RegisterValue.cpp
  source/Expression/Materializer.cpp

Index: source/Expression/Materializer.cpp
===================================================================
--- source/Expression/Materializer.cpp
+++ source/Expression/Materializer.cpp
@@ -531,15 +531,15 @@
                     return;
                 }
 
-                if (data.GetByteSize() != m_variable_sp->GetType()->GetByteSize())
+                if (data.GetByteSize() < m_variable_sp->GetType()->GetByteSize())
                 {
                     if (data.GetByteSize() == 0 && m_variable_sp->LocationExpression().IsValid() == false)
                     {
                         err.SetErrorStringWithFormat("the variable '%s' has no location, it may have been optimized out", m_variable_sp->GetName().AsCString());
                     }
                     else
                     {
-                        err.SetErrorStringWithFormat("size of variable %s (%" PRIu64 ") disagrees with the ValueObject's size (%" PRIu64 ")",
+                        err.SetErrorStringWithFormat("size of variable %s (%" PRIu64 ") is larger than the ValueObject's size (%" PRIu64 ")",
                                                      m_variable_sp->GetName().AsCString(),
                                                      m_variable_sp->GetType()->GetByteSize(),
                                                      data.GetByteSize());
Index: source/Core/RegisterValue.cpp
===================================================================
--- source/Core/RegisterValue.cpp
+++ source/Core/RegisterValue.cpp
@@ -247,6 +247,9 @@
                 case 2:     scalar = *(const uint16_t *)buffer.bytes; return true;
                 case 4:     scalar = *(const uint32_t *)buffer.bytes; return true;
                 case 8:     scalar = *(const uint64_t *)buffer.bytes; return true;
+                case 16:
+                    scalar = llvm::APInt(128, llvm::ArrayRef<uint64_t>((const uint64_t *)buffer.bytes, 2));
+                    return true;
                 }
             }
             break;
@@ -374,6 +377,7 @@
         case eTypeLongDouble:   SetFloat (src.GetLongDouble (&src_offset)); break;
         case eTypeBytes:
         {
+            m_type = eTypeBytes;
             buffer.length = reg_info->byte_size;
             buffer.byte_order = src.GetByteOrder();
             assert (buffer.length <= kMaxRegisterByteSize);
Index: packages/Python/lldbsuite/test/lang/c/register_variables/test.c
===================================================================
--- packages/Python/lldbsuite/test/lang/c/register_variables/test.c
+++ packages/Python/lldbsuite/test/lang/c/register_variables/test.c
@@ -18,10 +18,18 @@
   printf("%d\n", c); // set breakpoint here
 }
 
+float f3() __attribute__ ((noinline));
+float f3() {
+  return 3.14f;
+}
+
 int main()
 {
   struct bar myBar = { 3, 4 };
   f1(2, &myBar);
   f2(&myBar);
+
+  float f = f3();
+  printf("%f\n", f); // set breakpoint here
   return 0;
 }
Index: packages/Python/lldbsuite/test/lang/c/register_variables/TestRegisterVariables.py
===================================================================
--- packages/Python/lldbsuite/test/lang/c/register_variables/TestRegisterVariables.py
+++ packages/Python/lldbsuite/test/lang/c/register_variables/TestRegisterVariables.py
@@ -24,7 +24,7 @@
         self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)
 
         # Break inside the main.
-        lldbutil.run_break_set_by_source_regexp(self, "break", num_expected_locations=2)
+        lldbutil.run_break_set_by_source_regexp(self, "break", num_expected_locations=3)
 
         ####################
         # First breakpoint
@@ -68,4 +68,22 @@
         self.expect("expr c", VARIABLES_DISPLAYED_CORRECTLY,
             substrs = ['(int) $3 = 5'])
 
+        #####################
+        # Third breakpoint
+
+        self.runCmd("continue")
+
+        # The stop reason of the thread should be breakpoint.
+        self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT,
+            substrs = ['stopped',
+                       'stop reason = breakpoint'])
+
+        # The breakpoint should have a hit count of 1.
+        self.expect("breakpoint list -f", BREAKPOINT_HIT_ONCE,
+            substrs = [' resolved, hit count = 1'])
+
+        # Try some variables that should be visible
+        self.expect("expr f", VARIABLES_DISPLAYED_CORRECTLY,
+            substrs = ['(float) $4 = 3.1'])
+
         self.runCmd("kill")
Index: include/lldb/Core/Value.h
===================================================================
--- include/lldb/Core/Value.h
+++ include/lldb/Core/Value.h
@@ -169,9 +169,8 @@
         m_context = p;
         if (m_context_type == eContextTypeRegisterInfo) {
             RegisterInfo *reg_info = GetRegisterInfo();
-            if (reg_info->encoding == lldb::eEncodingVector)
-                SetValueType(eValueTypeVector);
-            else
+            if (reg_info->encoding == lldb::eEncodingVector &&
+                m_vector.byte_order != lldb::eByteOrderInvalid)
                 SetValueType(eValueTypeScalar);
         }
     }
_______________________________________________
lldb-commits mailing list
lldb-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to