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

Reply via email to