[llvm-branch-commits] [lldb] 903f2a2 - [lldb/Dwarf] Change DW_OP_piece to use an llvm::BitVector
Med Ismail Bennani via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Fri Mar 20 13:09:05 PDT 2020
Author: Med Ismail Bennani
Date: 2020-03-19T20:07:19+01:00
New Revision: 903f2a2dbb30fcba786d9ae9a63a3b5e414a2a6e
URL: https://github.com/llvm/llvm-project/commit/903f2a2dbb30fcba786d9ae9a63a3b5e414a2a6e
DIFF: https://github.com/llvm/llvm-project/commit/903f2a2dbb30fcba786d9ae9a63a3b5e414a2a6e.diff
LOG: [lldb/Dwarf] Change DW_OP_piece to use an llvm::BitVector
This patch changes the implementation of DW_OP_piece to use
llvm::BitVector instead of the lldb_private::Value.
This allow to have more granularity which would be useful to implement
DW_OP_bit_piece but also when combined with a second BitVector for
masking the unknown bits/bytes, improves the DWARF Expression
evaluation Since it will show a future patch, the unknown bits/bytes as
optimised.
Additionally, this patch fixes a overloading resolution on the Scalar
constructor when using fixed-size interger types instead of fundamentale types.
It also fixes a bug when requesting a Scalar size when the value is less
than a byte.
Signed-off-by: Med Ismail Bennani <medismail.bennani at gmail.com>
Added:
Modified:
lldb/source/Expression/DWARFExpression.cpp
lldb/source/Utility/Scalar.cpp
Removed:
################################################################################
diff --git a/lldb/source/Expression/DWARFExpression.cpp b/lldb/source/Expression/DWARFExpression.cpp
index 7f12d06450c6..09df9b789bab 100644
--- a/lldb/source/Expression/DWARFExpression.cpp
+++ b/lldb/source/Expression/DWARFExpression.cpp
@@ -933,8 +933,8 @@ bool DWARFExpression::Evaluate(
uint32_t reg_num;
/// Insertion point for evaluating multi-piece expression.
- uint64_t op_piece_offset = 0;
- Value pieces; // Used for DW_OP_piece
+ llvm::BitVector bit_pieces;
+ llvm::BitVector bit_mask;
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
@@ -1258,34 +1258,34 @@ bool DWARFExpression::Evaluate(
// 8-byte signed integer constant DW_OP_constu unsigned LEB128 integer
// constant DW_OP_consts signed LEB128 integer constant
case DW_OP_const1u:
- stack.push_back(Scalar((uint8_t)opcodes.GetU8(&offset)));
+ stack.push_back(Scalar((unsigned int)opcodes.GetU8(&offset)));
break;
case DW_OP_const1s:
- stack.push_back(Scalar((int8_t)opcodes.GetU8(&offset)));
+ stack.push_back(Scalar((int)opcodes.GetU8(&offset)));
break;
case DW_OP_const2u:
- stack.push_back(Scalar((uint16_t)opcodes.GetU16(&offset)));
+ stack.push_back(Scalar((unsigned int)opcodes.GetU16(&offset)));
break;
case DW_OP_const2s:
- stack.push_back(Scalar((int16_t)opcodes.GetU16(&offset)));
+ stack.push_back(Scalar((int)opcodes.GetU16(&offset)));
break;
case DW_OP_const4u:
- stack.push_back(Scalar((uint32_t)opcodes.GetU32(&offset)));
+ stack.push_back(Scalar((unsigned int)opcodes.GetU32(&offset)));
break;
case DW_OP_const4s:
- stack.push_back(Scalar((int32_t)opcodes.GetU32(&offset)));
+ stack.push_back(Scalar((int)opcodes.GetU32(&offset)));
break;
case DW_OP_const8u:
- stack.push_back(Scalar((uint64_t)opcodes.GetU64(&offset)));
+ stack.push_back(Scalar((unsigned long)opcodes.GetU64(&offset)));
break;
case DW_OP_const8s:
- stack.push_back(Scalar((int64_t)opcodes.GetU64(&offset)));
+ stack.push_back(Scalar((long)opcodes.GetU64(&offset)));
break;
case DW_OP_constu:
- stack.push_back(Scalar(opcodes.GetULEB128(&offset)));
+ stack.push_back(Scalar((unsigned long)opcodes.GetULEB128(&offset)));
break;
case DW_OP_consts:
- stack.push_back(Scalar(opcodes.GetSLEB128(&offset)));
+ stack.push_back(Scalar((long)opcodes.GetSLEB128(&offset)));
break;
// OPCODE: DW_OP_dup
@@ -2064,27 +2064,19 @@ bool DWARFExpression::Evaluate(
if (piece_byte_size > 0) {
Value curr_piece;
+
+ const uint64_t curr_width = std::max(bit_mask.size(), bit_pieces.size());
if (stack.empty()) {
- // In a multi-piece expression, this means that the current piece is
- // not available. Fill with zeros for now by resizing the data and
- // appending it
- curr_piece.ResizeData(piece_byte_size);
- // Note that "0" is not a correct value for the unknown bits.
- // It would be better to also return a mask of valid bits together
- // with the expression result, so the debugger can print missing
- // members as "<optimized out>" or something.
- ::memset(curr_piece.GetBuffer().GetBytes(), 0, piece_byte_size);
- pieces.AppendDataToHostBuffer(curr_piece);
+ bit_mask.resize(curr_width + piece_byte_size * 8);
+ bit_mask.set(curr_width, curr_width + piece_byte_size * 8);
} else {
Status error;
// Extract the current piece into "curr_piece"
Value curr_piece_source_value(stack.back());
stack.pop_back();
- const Value::ValueType curr_piece_source_value_type =
- curr_piece_source_value.GetValueType();
- switch (curr_piece_source_value_type) {
+ switch (curr_piece_source_value.GetValueType()) {
case Value::eValueTypeLoadAddress:
if (process) {
if (curr_piece.ResizeData(piece_byte_size) == piece_byte_size) {
@@ -2168,36 +2160,11 @@ bool DWARFExpression::Evaluate(
} break;
}
- // Check if this is the first piece?
- if (op_piece_offset == 0) {
- // This is the first piece, we should push it back onto the stack
- // so subsequent pieces will be able to access this piece and add
- // to it.
- if (pieces.AppendDataToHostBuffer(curr_piece) == 0) {
- if (error_ptr)
- error_ptr->SetErrorString("failed to append piece data");
- return false;
- }
- } else {
- // If this is the second or later piece there should be a value on
- // the stack.
- if (pieces.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, pieces.GetBuffer().GetByteSize());
- return false;
- }
-
- if (pieces.AppendDataToHostBuffer(curr_piece) == 0) {
- if (error_ptr)
- error_ptr->SetErrorString("failed to append piece data");
- return false;
- }
- }
+ unsigned int curr_scalar = curr_piece.GetScalar().UInt();
+ curr_scalar = curr_scalar << curr_width;
+ bit_pieces.resize(curr_width + piece_byte_size * 8);
+ bit_pieces.setBitsInMask(&curr_scalar);
}
- op_piece_offset += piece_byte_size;
}
} break;
@@ -2533,7 +2500,9 @@ bool DWARFExpression::Evaluate(
if (stack.empty()) {
// Nothing on the stack, check if we created a piece value from DW_OP_piece
// or DW_OP_bit_piece opcodes
- if (pieces.GetBuffer().GetByteSize()) {
+ if (bit_pieces.size()) {
+ Value pieces;
+ pieces.AppendBytes(bit_pieces.getData().data(), bit_pieces.size() / 8);
result = pieces;
} else {
if (error_ptr)
diff --git a/lldb/source/Utility/Scalar.cpp b/lldb/source/Utility/Scalar.cpp
index b6db5ccaebc4..e8bd164fa14b 100644
--- a/lldb/source/Utility/Scalar.cpp
+++ b/lldb/source/Utility/Scalar.cpp
@@ -197,7 +197,7 @@ size_t Scalar::GetByteSize() const {
case e_uint256:
case e_sint512:
case e_uint512:
- return (m_integer.getBitWidth() / 8);
+ return ceil(m_integer.getBitWidth() / 8.0);
case e_float:
return sizeof(float_t);
case e_double:
More information about the llvm-branch-commits
mailing list