https://github.com/MrEven132 created https://github.com/llvm/llvm-project/pull/216641
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 >From dc852b227b8c8086b66470ef3beadfd072cf3c9f Mon Sep 17 00:00:00 2001 From: MrEven132 <[email protected]> Date: Mon, 17 Aug 2026 12:08:31 +0800 Subject: [PATCH] [lldb] Keep DW_OP_fbreg results address-sized 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 --- lldb/source/Expression/DWARFExpression.cpp | 2 ++ .../Expression/DWARFExpressionTest.cpp | 36 +++++++++++++++++++ 2 files changed, 38 insertions(+) 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()); _______________________________________________ lldb-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
