llvmorg-github-actions[bot] wrote:

<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-lldb

Author: MrEven132

<details>
<summary>Changes</summary>

DW_OP_fbreg adds its signed displacement as an int64_t, which can widen a 
32-bit frame-base Scalar to 64 bits. Canonicalize the pushed result using the 
evaluator's existing generic conversion so subsequent arithmetic uses the 
target address width.

Add an i386 regression test that checks 32-bit wrapping and the resulting 
APSInt width.

Fixes #<!-- -->211007

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


2 Files Affected:

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


``````````diff
diff --git a/lldb/source/Expression/DWARFExpression.cpp 
b/lldb/source/Expression/DWARFExpression.cpp
index f4c4f519b09c7..0bc272ddd89b2 100644
--- a/lldb/source/Expression/DWARFExpression.cpp
+++ b/lldb/source/Expression/DWARFExpression.cpp
@@ -1925,6 +1925,8 @@ llvm::Expected<Value> DWARFExpression::Evaluate(
       if (llvm::Error err =
               Evaluate_DW_OP_fbreg(eval_ctx, op->getRawOperand(0)))
         return err;
+      stack.back().GetScalar() =
+          to_generic(stack.back().GetScalar().ULongLong());
       break;
 
     case DW_OP_nop:
diff --git a/lldb/unittests/Expression/DWARFExpressionTest.cpp 
b/lldb/unittests/Expression/DWARFExpressionTest.cpp
index c2752e16672f7..a1b5950ab4132 100644
--- a/lldb/unittests/Expression/DWARFExpressionTest.cpp
+++ b/lldb/unittests/Expression/DWARFExpressionTest.cpp
@@ -27,6 +27,7 @@
 #include "lldb/Symbol/ObjectFile.h"
 #include "lldb/Target/ABI.h"
 #include "lldb/Target/RegisterContext.h"
+#include "lldb/Target/StackFrame.h"
 #include "lldb/Utility/RegisterValue.h"
 #include "lldb/Utility/StreamString.h"
 #include "llvm/ADT/StringExtras.h"
@@ -230,6 +231,24 @@ class MockRegisterContext : public RegisterContext {
   RegisterInfo m_reg_info{};
   RegisterValue m_reg_value{};
 };
+
+class MockStackFrame : public StackFrame {
+public:
+  MockStackFrame(const lldb::ThreadSP &thread_sp, Scalar frame_base)
+      : StackFrame(thread_sp, /*frame_idx=*/0, /*concrete_frame_idx=*/0,
+                   /*cfa=*/0, /*cfa_is_valid=*/true, /*pc=*/0,
+                   StackFrame::Kind::Regular, /*artificial=*/false,
+                   /*behaves_like_zeroth_frame=*/true, /*sc_ptr=*/nullptr),
+        m_frame_base(std::move(frame_base)) {}
+
+  llvm::Error GetFrameBaseValue(Scalar &value) override {
+    value = m_frame_base;
+    return llvm::Error::success();
+  }
+
+private:
+  Scalar m_frame_base;
+};
 } // namespace
 
 static llvm::Expected<Value> Evaluate(llvm::ArrayRef<uint8_t> expr,
@@ -1375,6 +1394,23 @@ TEST_F(DWARFExpressionMockProcessTest, 
DW_OP_bregx_address_size) {
   EXPECT_EQ(result->GetScalar().GetAPSInt().getBitWidth(), 32u);
 }
 
+TEST_F(DWARFExpressionMockProcessTest, DW_OP_fbreg_address_size) {
+  TestContext ctx;
+  ASSERT_TRUE(CreateTestContext(&ctx, "i386-pc-linux"));
+  lldb::StackFrameSP frame_sp =
+      std::make_shared<MockStackFrame>(ctx.thread_sp, Scalar(uint32_t{0x2a}));
+  ExecutionContext exe_ctx(frame_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_fbreg, 0x7f, DW_OP_const4u, 0xff, 0xff, 0xff, 0xff,
+                DW_OP_plus, DW_OP_lit1, DW_OP_plus, DW_OP_stack_value},
+               {}, {}, &exe_ctx);
+  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());
 

``````````

</details>


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

Reply via email to