llvmorg-github-actions[bot] wrote:

<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-lldb

Author: MrEven132

<details>
<summary>Changes</summary>

`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

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


2 Files Affected:

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


``````````diff
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..2d5890570d8eb 100644
--- a/lldb/unittests/Expression/DWARFExpressionTest.cpp
+++ b/lldb/unittests/Expression/DWARFExpressionTest.cpp
@@ -1344,6 +1344,35 @@ 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.
+  EXPECT_THAT_EXPECTED(
+      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()),
+      ExpectScalar(32, 0x29, false));
+}
+
+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.
+  EXPECT_THAT_EXPECTED(
+      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()),
+      ExpectScalar(32, 0x29, false));
+}
+
 TEST_F(DWARFExpressionMockProcessTest, DW_OP_deref) {
   EXPECT_THAT_EXPECTED(Evaluate({DW_OP_lit0, DW_OP_deref}), llvm::Failed());
 

``````````

</details>


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

Reply via email to