[Lldb-commits] [lldb] r212867 - lldb needs to support DW_op_piece masks for values in subregister and also to be able to piece together a value that is spread across multiple registers.

Greg Clayton gclayton at apple.com
Fri Jul 11 17:24:34 PDT 2014


Author: gclayton
Date: Fri Jul 11 19:24:33 2014
New Revision: 212867

URL: http://llvm.org/viewvc/llvm-project?rev=212867&view=rev
Log:
lldb needs to support DW_op_piece masks for values in subregister and also to be able to piece together a value that is spread across multiple registers.

Patch from Adrian Prantl.

<rdar://problem/16040521> 


Modified:
    lldb/trunk/include/lldb/Core/DataBufferHeap.h
    lldb/trunk/include/lldb/Core/Value.h
    lldb/trunk/source/Core/DataBufferHeap.cpp
    lldb/trunk/source/Core/Value.cpp
    lldb/trunk/source/Expression/DWARFExpression.cpp
    lldb/trunk/source/Plugins/Process/Utility/InstructionUtils.h

Modified: lldb/trunk/include/lldb/Core/DataBufferHeap.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Core/DataBufferHeap.h?rev=212867&r1=212866&r2=212867&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Core/DataBufferHeap.h (original)
+++ lldb/trunk/include/lldb/Core/DataBufferHeap.h Fri Jul 11 19:24:33 2014
@@ -122,6 +122,9 @@ public:
     CopyData (const void *src, lldb::offset_t src_len);
 
     void
+    AppendData (const void *src, uint64_t src_len);
+
+    void
     Clear();
 
 private:

Modified: lldb/trunk/include/lldb/Core/Value.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Core/Value.h?rev=212867&r1=212866&r2=212867&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Core/Value.h (original)
+++ lldb/trunk/include/lldb/Core/Value.h Fri Jul 11 19:24:33 2014
@@ -124,9 +124,15 @@ public:
     Value();
     Value(const Scalar& scalar);
     Value(const Vector& vector);
-    Value(const uint8_t *bytes, int len);
+    Value(const void *bytes, int len);
     Value(const Value &rhs);
     
+    void
+    SetBytes (const void *bytes, int len);
+    
+    void
+    AppendBytes (const void *bytes, int len);
+
     Value &
     operator=(const Value &rhs);
 
@@ -235,6 +241,18 @@ public:
     void
     ResizeData(size_t len);
 
+    DataBufferHeap &
+    GetBuffer ()
+    {
+        return m_data_buffer;
+    }
+
+    const DataBufferHeap &
+    GetBuffer () const
+    {
+        return m_data_buffer;
+    }
+
     bool
     ValueOf(ExecutionContext *exe_ctx);
 

Modified: lldb/trunk/source/Core/DataBufferHeap.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/DataBufferHeap.cpp?rev=212867&r1=212866&r2=212867&view=diff
==============================================================================
--- lldb/trunk/source/Core/DataBufferHeap.cpp (original)
+++ lldb/trunk/source/Core/DataBufferHeap.cpp Fri Jul 11 19:24:33 2014
@@ -104,6 +104,12 @@ DataBufferHeap::CopyData (const void *sr
 }
 
 void
+DataBufferHeap::AppendData (const void *src, uint64_t src_len)
+{
+    m_data.insert(m_data.end(), (uint8_t *)src, (uint8_t *)src + src_len);
+}
+
+void
 DataBufferHeap::Clear()
 {
     buffer_t empty;

Modified: lldb/trunk/source/Core/Value.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/Value.cpp?rev=212867&r1=212866&r2=212867&view=diff
==============================================================================
--- lldb/trunk/source/Core/Value.cpp (original)
+++ lldb/trunk/source/Core/Value.cpp Fri Jul 11 19:24:33 2014
@@ -55,7 +55,7 @@ Value::Value(const Scalar& scalar) :
 }
 
 
-Value::Value(const uint8_t *bytes, int len) :
+Value::Value(const void *bytes, int len) :
     m_value (),
     m_vector (),
     m_clang_type (),
@@ -64,8 +64,7 @@ Value::Value(const uint8_t *bytes, int l
     m_context_type (eContextTypeInvalid),
     m_data_buffer ()
 {
-    m_data_buffer.CopyData(bytes, len);
-    m_value = (uintptr_t)m_data_buffer.GetBytes();
+    SetBytes(bytes, len);
 }
 
 Value::Value(const Value &v) :
@@ -111,6 +110,22 @@ Value::operator=(const Value &rhs)
 }
 
 void
+Value::SetBytes (const void *bytes, int len)
+{
+    m_value_type = eValueTypeHostAddress;
+    m_data_buffer.CopyData(bytes, len);
+    m_value = (uintptr_t)m_data_buffer.GetBytes();
+}
+
+void
+Value::AppendBytes (const void *bytes, int len)
+{
+    m_value_type = eValueTypeHostAddress;
+    m_data_buffer.AppendData (bytes, len);
+    m_value = (uintptr_t)m_data_buffer.GetBytes();
+}
+
+void
 Value::Dump (Stream* strm)
 {
     m_value.GetValue (strm, true);

Modified: lldb/trunk/source/Expression/DWARFExpression.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Expression/DWARFExpression.cpp?rev=212867&r1=212866&r2=212867&view=diff
==============================================================================
--- lldb/trunk/source/Expression/DWARFExpression.cpp (original)
+++ lldb/trunk/source/Expression/DWARFExpression.cpp Fri Jul 11 19:24:33 2014
@@ -1345,6 +1345,9 @@ DWARFExpression::Evaluate
     Value tmp;
     uint32_t reg_num;
 
+    /// Insertion point for evaluating multi-piece expression.
+    uint64_t op_piece_offset = 0;
+
     // Make sure all of the data is available in opcodes.
     if (!opcodes.ValidOffsetForDataOfSize(opcodes_offset, opcodes_length))
     {
@@ -2574,10 +2577,13 @@ DWARFExpression::Evaluate
         // variable a particular DWARF expression refers to.
         //----------------------------------------------------------------------
         case DW_OP_piece:
-            if (stack.size() < 1)
+            if (stack.size() < 1 ||
+                (op_piece_offset > 0 && stack.size() < 2))
             {
+                // In a multi-piece expression, this means that the current piece is not available.
+                // We don't have a way to signal partial availabilty.
                 if (error_ptr)
-                    error_ptr->SetErrorString("Expression stack needs at least 1 item for DW_OP_piece.");
+                    error_ptr->SetErrorString("Partially unavailable DW_OP_piece expressions are not yet supported.");
                 return false;
             }
             else
@@ -2598,6 +2604,74 @@ DWARFExpression::Evaluate
                                     error_ptr->SetErrorStringWithFormat("unable to extract %" PRIu64 " bytes from a %" PRIu64 " byte scalar value.", piece_byte_size, (uint64_t)stack.back().GetScalar().GetByteSize());
                                 return false;
                             }
+
+                            // Multiple pieces of a large value are assembled in a memory buffer value.
+                            if (op_piece_offset)
+                            {
+                                Error error;
+                                Scalar cur_piece = stack.back().GetScalar();
+                                stack.pop_back();
+                                
+                                switch (stack.back().GetValueType())
+                                {
+                                    case  Value::eValueTypeScalar:
+                                        {
+                                            // We already have something on the stack that will becomes the first
+                                            // bytes of our buffer, we need to populate these bytes into the buffer
+                                            // and then we will add the current bytes to it.
+                                            
+                                            // Promote top of stack to a memory buffer.
+                                            Scalar prev_piece = stack.back().GetScalar();
+                                            stack.pop_back();
+                                            stack.push_back(Value());
+                                            Value &piece_value = stack.back();
+                                            piece_value.ResizeData(op_piece_offset);
+                                            prev_piece.GetAsMemoryData(piece_value.GetBuffer().GetBytes(), op_piece_offset, lldb::endian::InlHostByteOrder(), error);
+                                            if (error.Fail())
+                                            {
+                                                if (error_ptr)
+                                                    error_ptr->SetErrorString(error.AsCString());
+                                                return false;
+                                            }
+                                        }
+                                        // Fall through to host address case...
+                                        
+                                    case Value::eValueTypeHostAddress:
+                                        {
+                                            if (stack.back().GetBuffer().GetByteSize() != op_piece_offset)
+                                            {
+                                                if (error_ptr)
+                                                    error_ptr->SetErrorStringWithFormat ("DW_OP_piece for offset %" PRIu64 " but top of stack is of size %" PRIu64,
+                                                                                         op_piece_offset,
+                                                                                         stack.back().GetBuffer().GetByteSize());
+                                                return false;
+                                            }
+                                            
+                                            // Append the current piece to the buffer.
+                                            size_t len = op_piece_offset + piece_byte_size;
+                                            stack.back().ResizeData(len);
+                                            cur_piece.GetAsMemoryData (stack.back().GetBuffer().GetBytes() + op_piece_offset,
+                                                                       piece_byte_size,
+                                                                       lldb::endian::InlHostByteOrder(),
+                                                                       error);
+                                            if (error.Fail())
+                                            {
+                                                if (error_ptr)
+                                                    error_ptr->SetErrorString(error.AsCString());
+                                                return false;
+                                            }
+                                        }
+                                        break;
+                                        
+                                    default:
+                                        // Expect top of stack to be a memory buffer.
+                                        if (error_ptr)
+                                            error_ptr->SetErrorStringWithFormat("DW_OP_piece for offset %" PRIu64 ": top of stack is not a piece", op_piece_offset);
+                                        return false;
+                                }
+
+                            }
+                            op_piece_offset += piece_byte_size;
                         }
                         break;
                         

Modified: lldb/trunk/source/Plugins/Process/Utility/InstructionUtils.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/Utility/InstructionUtils.h?rev=212867&r1=212866&r2=212867&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/Utility/InstructionUtils.h (original)
+++ lldb/trunk/source/Plugins/Process/Utility/InstructionUtils.h Fri Jul 11 19:24:33 2014
@@ -83,6 +83,8 @@ Rotl32 (uint32_t bits, uint32_t amt)
 static inline uint64_t
 MaskUpToBit (const uint64_t bit)
 {
+    if (bit >= 63)
+        return -1ll;
     return (1ull << (bit + 1ull)) - 1ull;
 }
 





More information about the lldb-commits mailing list