Skip to content

Commit a0db29d

Browse files
authored
[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
1 parent 8f77fa7 commit a0db29d

File tree

2 files changed

+28
-8
lines changed

2 files changed

+28
-8
lines changed

lldb/source/Expression/DWARFExpression.cpp

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1975,14 +1975,13 @@ llvm::Expected<Value> DWARFExpression::Evaluate(
19751975
piece_byte_size,
19761976
(uint64_t)curr_piece_source_value.GetScalar().GetByteSize());
19771977
}
1978-
// Create curr_piece with bit_size. By default Scalar
1979-
// grows to the nearest host integer type.
1980-
llvm::APInt fail_value(1, 0, false);
1981-
llvm::APInt ap_int = scalar.UInt128(fail_value);
1982-
assert(ap_int.getBitWidth() >= bit_size);
1983-
llvm::ArrayRef<uint64_t> buf{ap_int.getRawData(),
1984-
ap_int.getNumWords()};
1985-
curr_piece.GetScalar() = Scalar(llvm::APInt(bit_size, buf));
1978+
1979+
// We have seen a case where we have expression like:
1980+
// DW_OP_lit0, DW_OP_stack_value, DW_OP_piece 0x28
1981+
// here we are assuming the compiler was trying to zero
1982+
// extend the value that we should append to the buffer.
1983+
scalar.TruncOrExtendTo(bit_size, /*sign=*/false);
1984+
curr_piece.GetScalar() = scalar;
19861985
} break;
19871986
}
19881987

lldb/unittests/Expression/DWARFExpressionTest.cpp

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -462,6 +462,27 @@ TEST(DWARFExpression, DW_OP_piece) {
462462
llvm::HasValue(GetScalar(16, 0xff00, true)));
463463
}
464464

465+
TEST(DWARFExpression, DW_OP_piece_host_address) {
466+
static const uint8_t expr_data[] = {DW_OP_lit2, DW_OP_stack_value,
467+
DW_OP_piece, 40};
468+
llvm::ArrayRef<uint8_t> expr(expr_data, sizeof(expr_data));
469+
DataExtractor extractor(expr.data(), expr.size(), lldb::eByteOrderLittle, 4);
470+
471+
// This tests if ap_int is extended to the right width.
472+
// expect 40*8 = 320 bits size.
473+
llvm::Expected<Value> result =
474+
DWARFExpression::Evaluate(nullptr, nullptr, nullptr, extractor, nullptr,
475+
lldb::eRegisterKindDWARF, nullptr, nullptr);
476+
ASSERT_THAT_EXPECTED(result, llvm::Succeeded());
477+
ASSERT_EQ(result->GetValueType(), Value::ValueType::HostAddress);
478+
ASSERT_EQ(result->GetBuffer().GetByteSize(), 40ul);
479+
const uint8_t *data = result->GetBuffer().GetBytes();
480+
ASSERT_EQ(data[0], 2);
481+
for (int i = 1; i < 40; i++) {
482+
ASSERT_EQ(data[i], 0);
483+
}
484+
}
485+
465486
TEST(DWARFExpression, DW_OP_implicit_value) {
466487
unsigned char bytes = 4;
467488

0 commit comments

Comments
 (0)