[Lldb-commits] [lldb] r360158 - RegisterContextLLDB: Push CFA value on DWARF stack when evaluating register expressions

Pavel Labath via lldb-commits lldb-commits at lists.llvm.org
Tue May 7 08:27:35 PDT 2019


Author: labath
Date: Tue May  7 08:27:35 2019
New Revision: 360158

URL: http://llvm.org/viewvc/llvm-project?rev=360158&view=rev
Log:
RegisterContextLLDB: Push CFA value on DWARF stack when evaluating register expressions

Summary:
This behavior is specified in the Section 6.4.2.3 (Register Rule
instructions) of the DWARF4 spec. We were not doing that, which meant
that any register rule which was relying on the cfa value being there
was not evaluated correctly (it was aborted due to "out of bounds"
access).

I'm not sure how come this wasn't noticed before, but I guess this has
something to do with the fact that dwarf unwind expressions are not used
very often, and when they are, the situation is so complicated that the
CFA is of no use. I noticed this when I started emitting dwarf
expressions for the unwind information present in breakpad symbol files.

Reviewers: jasonmolenda, clayborg

Subscribers: aprantl, lldb-commits

Differential Revision: https://reviews.llvm.org/D61018

Added:
    lldb/trunk/lit/Unwind/Inputs/eh-frame-dwarf-unwind.s
    lldb/trunk/lit/Unwind/eh-frame-dwarf-unwind.test
Modified:
    lldb/trunk/source/Plugins/Process/Utility/RegisterContextLLDB.cpp

Added: lldb/trunk/lit/Unwind/Inputs/eh-frame-dwarf-unwind.s
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/lit/Unwind/Inputs/eh-frame-dwarf-unwind.s?rev=360158&view=auto
==============================================================================
--- lldb/trunk/lit/Unwind/Inputs/eh-frame-dwarf-unwind.s (added)
+++ lldb/trunk/lit/Unwind/Inputs/eh-frame-dwarf-unwind.s Tue May  7 08:27:35 2019
@@ -0,0 +1,49 @@
+        .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

Added: lldb/trunk/lit/Unwind/eh-frame-dwarf-unwind.test
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/lit/Unwind/eh-frame-dwarf-unwind.test?rev=360158&view=auto
==============================================================================
--- lldb/trunk/lit/Unwind/eh-frame-dwarf-unwind.test (added)
+++ lldb/trunk/lit/Unwind/eh-frame-dwarf-unwind.test Tue May  7 08:27:35 2019
@@ -0,0 +1,22 @@
+# 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

Modified: lldb/trunk/source/Plugins/Process/Utility/RegisterContextLLDB.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/Utility/RegisterContextLLDB.cpp?rev=360158&r1=360157&r2=360158&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/Utility/RegisterContextLLDB.cpp (original)
+++ lldb/trunk/source/Plugins/Process/Utility/RegisterContextLLDB.cpp Tue May  7 08:27:35 2019
@@ -1513,9 +1513,11 @@ RegisterContextLLDB::SavedLocationForReg
     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();




More information about the lldb-commits mailing list