[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