Author: MrEven132 Date: 2026-08-15T13:46:33+08:00 New Revision: 23e0cbe9a37fdd7addfd461ace6b480ad423e36b
URL: https://github.com/llvm/llvm-project/commit/23e0cbe9a37fdd7addfd461ace6b480ad423e36b DIFF: https://github.com/llvm/llvm-project/commit/23e0cbe9a37fdd7addfd461ace6b480ad423e36b.diff LOG: [LLDB] fix lldb breg adress width (#216291) `DW_OP_breg0..31` and `DW_OP_bregx` preserved the scalar width supplied by the register backend and added their displacement as a `uint64_t`. On 32-bit targets this could leave a 64-bit value on the expression stack, so later generic address arithmetic did not wrap at the target address size. Perform the register-plus-offset calculation using the evaluator's address-sized generic representation. This keeps `DW_OP_breg*` results at the target address width without changing shared register reading or the generic operand compatibility rule. Add unit tests for both compact and extended breg opcodes. They cover a 32-bit register value, a backend-provided 64-bit register value on i386, a negative displacement, and modulo-32-bit overflow. Fixes #209728 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 2dbf61a14eac4..f4c4f519b09c7 100644 --- a/lldb/source/Expression/DWARFExpression.cpp +++ b/lldb/source/Expression/DWARFExpression.cpp @@ -1901,7 +1901,8 @@ llvm::Expected<Value> DWARFExpression::Evaluate( return err; int64_t breg_offset = op->getRawOperand(0); - tmp.GetScalar() += static_cast<uint64_t>(breg_offset); + tmp.GetScalar() = to_generic(tmp.GetScalar().ULongLong()); + tmp.GetScalar() += to_generic(breg_offset); tmp.ClearContext(); stack.push_back(tmp); stack.back().SetValueType(Value::ValueType::LoadAddress); @@ -1913,7 +1914,8 @@ llvm::Expected<Value> DWARFExpression::Evaluate( return err; int64_t breg_offset = op->getRawOperand(1); - tmp.GetScalar() += static_cast<uint64_t>(breg_offset); + tmp.GetScalar() = to_generic(tmp.GetScalar().ULongLong()); + tmp.GetScalar() += to_generic(breg_offset); tmp.ClearContext(); stack.push_back(tmp); stack.back().SetValueType(Value::ValueType::LoadAddress); diff --git a/lldb/unittests/Expression/DWARFExpressionTest.cpp b/lldb/unittests/Expression/DWARFExpressionTest.cpp index e8bca7208c8d5..c2752e16672f7 100644 --- a/lldb/unittests/Expression/DWARFExpressionTest.cpp +++ b/lldb/unittests/Expression/DWARFExpressionTest.cpp @@ -1344,6 +1344,37 @@ TEST_F(DWARFExpressionMockProcessTest, DW_OP_bregx) { ExpectLoadAddress(0x2010)); } +TEST_F(DWARFExpressionMockProcessTest, DW_OP_breg_address_size) { + TestContext ctx; + ASSERT_TRUE( + CreateTestContext(&ctx, "i386-pc-linux", RegisterValue(uint32_t{0x2a}))); + ExecutionContext exe_ctx(ctx.process_sp); + + // Address arithmetic wraps at the target address size. In particular, + // 0xffffffff + 1 is zero on this 32-bit target. + auto result = + Evaluate({DW_OP_breg0, 0x7f, DW_OP_const4u, 0xff, 0xff, 0xff, 0xff, + DW_OP_plus, DW_OP_lit1, DW_OP_plus, DW_OP_stack_value}, + {}, {}, &exe_ctx, ctx.reg_ctx_sp.get()); + ASSERT_THAT_EXPECTED(result, ExpectScalar(32, 0x29, false)); + EXPECT_EQ(result->GetScalar().GetAPSInt().getBitWidth(), 32u); +} + +TEST_F(DWARFExpressionMockProcessTest, DW_OP_bregx_address_size) { + TestContext ctx; + ASSERT_TRUE(CreateTestContext(&ctx, "i386-pc-linux", + RegisterValue(uint64_t{0x10000002a}))); + ExecutionContext exe_ctx(ctx.process_sp); + + // The register backend may expose a value wider than the target address. + auto result = + Evaluate({DW_OP_bregx, 0x40, 0x7f, DW_OP_const4u, 0xff, 0xff, 0xff, 0xff, + DW_OP_plus, DW_OP_lit1, DW_OP_plus, DW_OP_stack_value}, + {}, {}, &exe_ctx, ctx.reg_ctx_sp.get()); + ASSERT_THAT_EXPECTED(result, ExpectScalar(32, 0x29, false)); + EXPECT_EQ(result->GetScalar().GetAPSInt().getBitWidth(), 32u); +} + TEST_F(DWARFExpressionMockProcessTest, DW_OP_deref) { EXPECT_THAT_EXPECTED(Evaluate({DW_OP_lit0, DW_OP_deref}), llvm::Failed()); _______________________________________________ lldb-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
