Author: satyanarayana reddy janga
Date: 2025-08-04T09:42:42-07:00
New Revision: a0db29d64788c44230b0808317d5841c5558bec6

URL: 
https://github.com/llvm/llvm-project/commit/a0db29d64788c44230b0808317d5841c5558bec6
DIFF: 
https://github.com/llvm/llvm-project/commit/a0db29d64788c44230b0808317d5841c5558bec6.diff

LOG: [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

Added: 
    

Modified: 
    lldb/source/Expression/DWARFExpression.cpp
    lldb/unittests/Expression/DWARFExpressionTest.cpp

Removed: 
    


################################################################################
diff  --git a/lldb/source/Expression/DWARFExpression.cpp 
b/lldb/source/Expression/DWARFExpression.cpp
index 391e27704b63d..ed4e4e4e341a3 100644
--- a/lldb/source/Expression/DWARFExpression.cpp
+++ b/lldb/source/Expression/DWARFExpression.cpp
@@ -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;
           }
 

diff  --git a/lldb/unittests/Expression/DWARFExpressionTest.cpp 
b/lldb/unittests/Expression/DWARFExpressionTest.cpp
index 8b1b9336190a2..3008fc0d9ca17 100644
--- a/lldb/unittests/Expression/DWARFExpressionTest.cpp
+++ b/lldb/unittests/Expression/DWARFExpressionTest.cpp
@@ -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;
 


        
_______________________________________________
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to