diff --git a/lldb/source/Expression/DWARFExpression.cpp b/lldb/source/Expression/DWARFExpression.cpp index 52891fcefd68b..88457596a0fa8 100644 --- a/lldb/source/Expression/DWARFExpression.cpp +++ b/lldb/source/Expression/DWARFExpression.cpp @@ -1974,14 +1974,13 @@ llvm::Expected 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 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; } diff --git a/lldb/unittests/Expression/DWARFExpressionTest.cpp b/lldb/unittests/Expression/DWARFExpressionTest.cpp index fdc9bfae1876c..86c3b56e320fd 100644 --- a/lldb/unittests/Expression/DWARFExpressionTest.cpp +++ b/lldb/unittests/Expression/DWARFExpressionTest.cpp @@ -358,6 +358,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 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 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;