--- /dev/null
+ .text
+ .globl bar
+ .type bar, @function
+bar:
+.LFB0:
+ .cfi_startproc
+ leal (%edi, %edi), %eax
+ ret
+ .cfi_endproc
+.LFE0:
+ .size bar, .-bar
+ .globl foo
+ .type foo, @function
+foo:
+.LFB1:
+ .cfi_startproc
+ .cfi_escape 0x16, 0x10, 0x06, 0x38, 0x1c, 0x06, 0x08, 0x47, 0x1c
+ call bar
+ addl $1, %eax
+ popq %rdi
+ subq $0x47, %rdi
+ jmp *%rdi # Return
+ .cfi_endproc
+.LFE1:
+ .size foo, .-foo
+ .globl main
+ .type main, @function
+main:
+.LFB2:
+ .cfi_startproc
+ pushq %rbp
+ .cfi_def_cfa_offset 16
+ .cfi_offset 6, -16
+ movq %rsp, %rbp
+ .cfi_def_cfa_register 6
+ movl $47, %edi
+
+ # Non-standard calling convention. The real return address must be
+ # decremented by 0x47.
+ leaq 0x47+1f(%rip), %rax
+ pushq %rax
+ jmp foo # call
+1:
+ popq %rbp
+ .cfi_def_cfa 7, 8
+ ret
+ .cfi_endproc
+.LFE2:
+ .size main, .-main
--- /dev/null
+# Test handing of dwarf expressions specifying the location of registers, if
+# those expressions refer to the frame's CFA value.
+
+# REQUIRES: target-x86_64, system-linux, native
+
+# RUN: %clang %p/Inputs/eh-frame-dwarf-unwind.s -o %t
+# RUN: %lldb %t -s %s -o exit | FileCheck %s
+
+breakpoint set -n bar
+# CHECK: Breakpoint 1: where = {{.*}}`bar
+
+process launch
+# CHECK: stop reason = breakpoint 1.1
+
+thread backtrace
+# CHECK: frame #0: {{.*}}`bar
+# CHECK: frame #1: {{.*}}`foo + 5
+# CHECK: frame #2: {{.*}}`main + 19
+
+target modules show-unwind -n foo
+# CHECK: eh_frame UnwindPlan:
+# CHECK: row[0]: 0: CFA=rsp +8 => rip=DW_OP_lit8 , DW_OP_minus , DW_OP_deref , DW_OP_const1u 0x47, DW_OP_minus
DWARFExpression dwarfexpr(opcode_ctx, dwarfdata, nullptr, 0,
unwindplan_regloc.GetDWARFExpressionLength());
dwarfexpr.SetRegisterKind(unwindplan_registerkind);
+ Value cfa_val = Scalar(m_cfa);
+ cfa_val.SetValueType(Value::eValueTypeLoadAddress);
Value result;
Status error;
- if (dwarfexpr.Evaluate(&exe_ctx, this, 0, nullptr, nullptr, result,
+ if (dwarfexpr.Evaluate(&exe_ctx, this, 0, &cfa_val, nullptr, result,
&error)) {
addr_t val;
val = result.GetScalar().ULongLong();