llvmorg-github-actions[bot] wrote:

<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-lldb

Author: MrEven132

<details>
<summary>Changes</summary>

`DW_OP_addr`, `DW_OP_addrx`, and `DW_OP_GNU_addr_index` currently push `Scalar` 
values constructed from 64-bit C++ types. On 32-bit targets, subsequent generic 
arithmetic therefore retains a 64-bit width instead of wrapping at the target 
address size.

Use the evaluator's existing `to_generic` conversion when pushing these address 
values. This keeps the scalar at the target address width without changing 
operand decoding or public APIs.

Add unit coverage for direct and indexed address operations that checks both 
32-bit wraparound and the resulting APSInt width.

Fixes #<!-- -->210972

---
Full diff: https://github.com/llvm/llvm-project/pull/216661.diff


2 Files Affected:

- (modified) lldb/source/Expression/DWARFExpression.cpp (+2-2) 
- (modified) lldb/unittests/Expression/DWARFExpressionTest.cpp (+28-2) 


``````````diff
diff --git a/lldb/source/Expression/DWARFExpression.cpp 
b/lldb/source/Expression/DWARFExpression.cpp
index f4c4f519b09c7..aa80d5e5d80f8 100644
--- a/lldb/source/Expression/DWARFExpression.cpp
+++ b/lldb/source/Expression/DWARFExpression.cpp
@@ -1440,7 +1440,7 @@ llvm::Expected<Value> DWARFExpression::Evaluate(
 
     switch (opcode) {
     case DW_OP_addr:
-      stack.push_back(Scalar(op->getRawOperand(0)));
+      stack.push_back(to_generic(op->getRawOperand(0)));
       stack.back().SetValueType(Value::ValueType::FileAddress);
       break;
 
@@ -2042,7 +2042,7 @@ llvm::Expected<Value> DWARFExpression::Evaluate(
       uint64_t index = op->getRawOperand(0);
       lldb::addr_t value =
           eval_ctx.dwarf_cu->ReadAddressFromDebugAddrSection(index);
-      stack.push_back(Scalar(value));
+      stack.push_back(to_generic(value));
       stack.back().SetValueType(Value::ValueType::FileAddress);
     } break;
 
diff --git a/lldb/unittests/Expression/DWARFExpressionTest.cpp 
b/lldb/unittests/Expression/DWARFExpressionTest.cpp
index c2752e16672f7..4023cfcd29a12 100644
--- a/lldb/unittests/Expression/DWARFExpressionTest.cpp
+++ b/lldb/unittests/Expression/DWARFExpressionTest.cpp
@@ -50,7 +50,8 @@ class MockDwarfDelegate : public DWARFExpression::Delegate {
   static MockDwarfDelegate Dwarf2() { return MockDwarfDelegate(2); }
 
   MockDwarfDelegate() : MockDwarfDelegate(DEFAULT_DWARF_VERSION) {}
-  explicit MockDwarfDelegate(uint16_t version) : m_dwarf_version(version) {}
+  explicit MockDwarfDelegate(uint16_t version, dw_addr_t debug_addr = 0)
+      : m_dwarf_version(version), m_debug_addr(debug_addr) {}
 
   uint16_t GetVersion() const override { return m_dwarf_version; }
 
@@ -65,7 +66,7 @@ class MockDwarfDelegate : public DWARFExpression::Delegate {
   }
 
   dw_addr_t ReadAddressFromDebugAddrSection(uint32_t index) const override {
-    return 0;
+    return m_debug_addr;
   }
 
   lldb::offset_t GetVendorDWARFOpcodeSize(const DataExtractor &data,
@@ -83,6 +84,7 @@ class MockDwarfDelegate : public DWARFExpression::Delegate {
 
 private:
   uint16_t m_dwarf_version;
+  dw_addr_t m_debug_addr;
 };
 
 /// Mock memory implementation for testing.
@@ -833,6 +835,30 @@ TEST(DWARFExpression, DW_OP_addr) {
       ExpectScalar(uint32_t{0x40302010}));
 }
 
+TEST(DWARFExpression, DW_OP_addr_address_size) {
+  // Address arithmetic wraps at the target address size. In particular,
+  // 0xffffffff + 1 is zero on this 32-bit target.
+  auto result = Evaluate({DW_OP_addr, 0x2a, 0x00, 0x00, 0x00, DW_OP_const4u,
+                          0xff, 0xff, 0xff, 0xff, DW_OP_plus, DW_OP_lit1,
+                          DW_OP_plus, DW_OP_stack_value});
+  ASSERT_THAT_EXPECTED(result, ExpectScalar(32, 0x2a, false));
+  EXPECT_EQ(result->GetScalar().GetAPSInt().getBitWidth(), 32u);
+}
+
+TEST(DWARFExpression, DW_OP_addr_index_address_size) {
+  MockDwarfDelegate unit(/*version=*/5, /*debug_addr=*/0x2a);
+  for (uint8_t opcode : {static_cast<uint8_t>(DW_OP_addrx),
+                         static_cast<uint8_t>(DW_OP_GNU_addr_index)}) {
+    SCOPED_TRACE(static_cast<unsigned>(opcode));
+    auto result =
+        Evaluate({opcode, 0x00, DW_OP_const4u, 0xff, 0xff, 0xff, 0xff,
+                  DW_OP_plus, DW_OP_lit1, DW_OP_plus, DW_OP_stack_value},
+                 {}, &unit);
+    ASSERT_THAT_EXPECTED(result, ExpectScalar(32, 0x2a, false));
+    EXPECT_EQ(result->GetScalar().GetAPSInt().getBitWidth(), 32u);
+  }
+}
+
 TEST(DWARFExpression, DW_OP_addr_big_endian) {
   // Same operand bytes, big-endian extractor: the address must be read in
   // target byte order.

``````````

</details>


https://github.com/llvm/llvm-project/pull/216661
_______________________________________________
lldb-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to