https://github.com/MrEven132 created https://github.com/llvm/llvm-project/pull/216661
`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 >From 63a7dd1d334c44d85bb9befd938cef34e9a7320c Mon Sep 17 00:00:00 2001 From: MrEven132 <[email protected]> Date: Mon, 17 Aug 2026 15:15:16 +0800 Subject: [PATCH] [lldb] Keep address operation values address-sized Canonicalize DW_OP_addr, DW_OP_addrx, and DW_OP_GNU_addr_index values through the evaluator's existing generic conversion so arithmetic uses the target address width. Add 32-bit wraparound and scalar-width unit coverage for direct and indexed address operations. --- lldb/source/Expression/DWARFExpression.cpp | 4 +-- .../Expression/DWARFExpressionTest.cpp | 30 +++++++++++++++++-- 2 files changed, 30 insertions(+), 4 deletions(-) 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. _______________________________________________ lldb-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
