mirror of
https://github.com/intel/llvm.git
synced 2026-01-14 20:10:50 +08:00
[lldb] Zero extend APInt when piece size is bigger than the bitwidth (#150149)
### Summary We have internally seen cases like this `DW_OP_lit0, DW_OP_stack_value, DW_OP_piece 0x28` where we have longer op pieces than what Scalar supports (32, 64 or 128 bits). In these cases LLDB is currently hitting the assertion `assert(ap_int.getBitWidth() >= bit_size);` We are extending the generated APInt to the piece size by filling zeros. ### Test plan Added a unit to cover this case. ### Reviewers @clayborg , @jeffreytan81 , @Jlalond
This commit is contained in:
committed by
GitHub
parent
8f77fa7026
commit
a0db29d647
@@ -1975,14 +1975,13 @@ llvm::Expected<Value> DWARFExpression::Evaluate(
|
||||
piece_byte_size,
|
||||
(uint64_t)curr_piece_source_value.GetScalar().GetByteSize());
|
||||
}
|
||||
// Create curr_piece with bit_size. By default Scalar
|
||||
// grows to the nearest host integer type.
|
||||
llvm::APInt fail_value(1, 0, false);
|
||||
llvm::APInt ap_int = scalar.UInt128(fail_value);
|
||||
assert(ap_int.getBitWidth() >= bit_size);
|
||||
llvm::ArrayRef<uint64_t> buf{ap_int.getRawData(),
|
||||
ap_int.getNumWords()};
|
||||
curr_piece.GetScalar() = Scalar(llvm::APInt(bit_size, buf));
|
||||
|
||||
// We have seen a case where we have expression like:
|
||||
// DW_OP_lit0, DW_OP_stack_value, DW_OP_piece 0x28
|
||||
// here we are assuming the compiler was trying to zero
|
||||
// extend the value that we should append to the buffer.
|
||||
scalar.TruncOrExtendTo(bit_size, /*sign=*/false);
|
||||
curr_piece.GetScalar() = scalar;
|
||||
} break;
|
||||
}
|
||||
|
||||
|
||||
@@ -462,6 +462,27 @@ TEST(DWARFExpression, DW_OP_piece) {
|
||||
llvm::HasValue(GetScalar(16, 0xff00, true)));
|
||||
}
|
||||
|
||||
TEST(DWARFExpression, DW_OP_piece_host_address) {
|
||||
static const uint8_t expr_data[] = {DW_OP_lit2, DW_OP_stack_value,
|
||||
DW_OP_piece, 40};
|
||||
llvm::ArrayRef<uint8_t> expr(expr_data, sizeof(expr_data));
|
||||
DataExtractor extractor(expr.data(), expr.size(), lldb::eByteOrderLittle, 4);
|
||||
|
||||
// This tests if ap_int is extended to the right width.
|
||||
// expect 40*8 = 320 bits size.
|
||||
llvm::Expected<Value> result =
|
||||
DWARFExpression::Evaluate(nullptr, nullptr, nullptr, extractor, nullptr,
|
||||
lldb::eRegisterKindDWARF, nullptr, nullptr);
|
||||
ASSERT_THAT_EXPECTED(result, llvm::Succeeded());
|
||||
ASSERT_EQ(result->GetValueType(), Value::ValueType::HostAddress);
|
||||
ASSERT_EQ(result->GetBuffer().GetByteSize(), 40ul);
|
||||
const uint8_t *data = result->GetBuffer().GetBytes();
|
||||
ASSERT_EQ(data[0], 2);
|
||||
for (int i = 1; i < 40; i++) {
|
||||
ASSERT_EQ(data[i], 0);
|
||||
}
|
||||
}
|
||||
|
||||
TEST(DWARFExpression, DW_OP_implicit_value) {
|
||||
unsigned char bytes = 4;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user