[Lldb-commits] [lldb] 498e994 - [lldb] Keep DW_OP_call_frame_cfa address-sized (#216684)
via lldb-commits
lldb-commits at lists.llvm.org
Mon Aug 24 00:38:12 PDT 2026
Author: MrEven132
Date: 2026-08-24T15:38:07+08:00
New Revision: 498e994ca9337aa1e60cf1a33ca4c7c36481b08d
URL: https://github.com/llvm/llvm-project/commit/498e994ca9337aa1e60cf1a33ca4c7c36481b08d
DIFF: https://github.com/llvm/llvm-project/commit/498e994ca9337aa1e60cf1a33ca4c7c36481b08d.diff
LOG: [lldb] Keep DW_OP_call_frame_cfa address-sized (#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
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 91c47546eeac7..40c69c65853a8 100644
--- a/lldb/source/Expression/DWARFExpression.cpp
+++ b/lldb/source/Expression/DWARFExpression.cpp
@@ -2043,6 +2043,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 094cfaf790a9a..b59bddff0cd1e 100644
--- a/lldb/unittests/Expression/DWARFExpressionTest.cpp
+++ b/lldb/unittests/Expression/DWARFExpressionTest.cpp
@@ -1533,6 +1533,26 @@ TEST_F(DWARFExpressionMockProcessTest, DW_OP_fbreg_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());
More information about the lldb-commits
mailing list