https://github.com/MrEven132 created https://github.com/llvm/llvm-project/pull/216684
`DW_OP_call_frame_cfa` currently constructs a `Scalar` directly from `lldb::addr_t`. Since `addr_t` is a 64-bit carrier, the result remains 64 bits when evaluating an expression for a 32-bit target, and subsequent address arithmetic does not wrap at the target address width. Normalize the CFA with the evaluator's existing `to_generic` helper after it is pushed. This preserves the existing frame lookup, error handling, and `LoadAddress` value type while making the scalar use the target address width. Add an i386 unit test that verifies both 32-bit address arithmetic and the resulting `APSInt` bit width. Fixes #210980 >From fd82479f5f90d92a09674af4bf36399f8aacde7b Mon Sep 17 00:00:00 2001 From: MrEven132 <[email protected]> Date: Mon, 17 Aug 2026 18:20:27 +0800 Subject: [PATCH] [lldb] Keep DW_OP_call_frame_cfa address-sized --- lldb/source/Expression/DWARFExpression.cpp | 2 ++ .../Expression/DWARFExpressionTest.cpp | 21 +++++++++++++++++++ 2 files changed, 23 insertions(+) diff --git a/lldb/source/Expression/DWARFExpression.cpp b/lldb/source/Expression/DWARFExpression.cpp index f4c4f519b09c7..8232d87d53b92 100644 --- a/lldb/source/Expression/DWARFExpression.cpp +++ b/lldb/source/Expression/DWARFExpression.cpp @@ -2026,6 +2026,8 @@ llvm::Expected<Value> DWARFExpression::Evaluate( case DW_OP_call_frame_cfa: if (llvm::Error err = Evaluate_DW_OP_call_frame_cfa(eval_ctx)) return err; + stack.back().GetScalar() = + to_generic(stack.back().GetScalar().ULongLong()); break; case DW_OP_form_tls_address: diff --git a/lldb/unittests/Expression/DWARFExpressionTest.cpp b/lldb/unittests/Expression/DWARFExpressionTest.cpp index c2752e16672f7..fe7853a041bfd 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" @@ -1375,6 +1376,26 @@ TEST_F(DWARFExpressionMockProcessTest, DW_OP_bregx_address_size) { EXPECT_EQ(result->GetScalar().GetAPSInt().getBitWidth(), 32u); } +TEST_F(DWARFExpressionMockProcessTest, DW_OP_call_frame_cfa_address_size) { + TestContext ctx; + ASSERT_TRUE(CreateTestContext(&ctx, "i386-pc-linux")); + auto frame_sp = std::make_shared<StackFrame>( + ctx.thread_sp, /*frame_idx=*/0, /*concrete_frame_idx=*/0, /*cfa=*/0x2a, + /*cfa_is_valid=*/true, /*pc=*/0x1000, StackFrame::Kind::Regular, + /*artificial=*/false, /*behaves_like_zeroth_frame=*/true, + /*sc_ptr=*/nullptr); + 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_call_frame_cfa, 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, 0x2a, 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
