summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lldb/lit/Unwind/Inputs/unwind-plan-dwarf-dump.s13
-rw-r--r--lldb/lit/Unwind/unwind-plan-dwarf-dump.test14
-rw-r--r--lldb/source/Symbol/UnwindPlan.cpp39
3 files changed, 62 insertions, 4 deletions
diff --git a/lldb/lit/Unwind/Inputs/unwind-plan-dwarf-dump.s b/lldb/lit/Unwind/Inputs/unwind-plan-dwarf-dump.s
new file mode 100644
index 00000000000..6030affd09d
--- /dev/null
+++ b/lldb/lit/Unwind/Inputs/unwind-plan-dwarf-dump.s
@@ -0,0 +1,13 @@
+ .text
+ .globl main
+ .type main, @function
+main:
+.LFB0:
+ .cfi_startproc
+ .cfi_escape 0x0f, 0x05, 0x77, 0x00, 0x08, 0x00, 0x22
+ .cfi_escape 0x16, 0x10, 0x04, 0x09, 0xf8, 0x22, 0x06
+ movl $47, %eax
+ ret
+ .cfi_endproc
+.LFE0:
+ .size main, .-main
diff --git a/lldb/lit/Unwind/unwind-plan-dwarf-dump.test b/lldb/lit/Unwind/unwind-plan-dwarf-dump.test
new file mode 100644
index 00000000000..c378f56b4f6
--- /dev/null
+++ b/lldb/lit/Unwind/unwind-plan-dwarf-dump.test
@@ -0,0 +1,14 @@
+# REQUIRES: target-x86_64, system-linux, native
+
+# RUN: %clang %p/Inputs/unwind-plan-dwarf-dump.s -o %t
+# RUN: %lldb %t -s %s -o exit | FileCheck %s
+
+breakpoint set -n main
+# CHECK: Breakpoint 1:
+
+process launch
+# CHECK: stop reason = breakpoint 1.1
+
+target modules show-unwind -n main
+# CHECK: eh_frame UnwindPlan:
+# CHECK: row[0]: 0: CFA=DW_OP_breg7 +0, DW_OP_const1u 0x00, DW_OP_plus => rip=DW_OP_const1s -8, DW_OP_plus , DW_OP_deref
diff --git a/lldb/source/Symbol/UnwindPlan.cpp b/lldb/source/Symbol/UnwindPlan.cpp
index 0e084cda98c..774f9cb587e 100644
--- a/lldb/source/Symbol/UnwindPlan.cpp
+++ b/lldb/source/Symbol/UnwindPlan.cpp
@@ -8,8 +8,10 @@
#include "lldb/Symbol/UnwindPlan.h"
+#include "lldb/Expression/DWARFExpression.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/RegisterContext.h"
+#include "lldb/Target/Target.h"
#include "lldb/Target/Thread.h"
#include "lldb/Utility/ConstString.h"
#include "lldb/Utility/Log.h"
@@ -64,6 +66,30 @@ void UnwindPlan::Row::RegisterLocation::SetIsDWARFExpression(
m_location.expr.length = len;
}
+static llvm::Optional<std::pair<lldb::ByteOrder, uint32_t>>
+GetByteOrderAndAddrSize(Thread *thread) {
+ if (!thread)
+ return llvm::None;
+ ProcessSP process_sp = thread->GetProcess();
+ if (!process_sp)
+ return llvm::None;
+ ArchSpec arch = process_sp->GetTarget().GetArchitecture();
+ return std::make_pair(arch.GetByteOrder(), arch.GetAddressByteSize());
+}
+
+static void DumpDWARFExpr(Stream &s, llvm::ArrayRef<uint8_t> expr, Thread *thread) {
+ if (auto order_and_width = GetByteOrderAndAddrSize(thread)) {
+ DataExtractor extractor(expr.data(), expr.size(), order_and_width->first,
+ order_and_width->second);
+ if (!DWARFExpression::PrintDWARFExpression(s, extractor,
+ order_and_width->second,
+ /*dwarf_ref_size*/ 4,
+ /*location_expression*/ false))
+ s.PutCString("invalid-dwarf-expr");
+ } else
+ s.PutCString("dwarf-expr");
+}
+
void UnwindPlan::Row::RegisterLocation::Dump(Stream &s,
const UnwindPlan *unwind_plan,
const UnwindPlan::Row *row,
@@ -120,9 +146,12 @@ void UnwindPlan::Row::RegisterLocation::Dump(Stream &s,
case isDWARFExpression: {
s.PutChar('=');
if (m_type == atDWARFExpression)
- s.PutCString("[dwarf-expr]");
- else
- s.PutCString("dwarf-expr");
+ s.PutChar('[');
+ DumpDWARFExpr(
+ s, llvm::makeArrayRef(m_location.expr.opcodes, m_location.expr.length),
+ thread);
+ if (m_type == atDWARFExpression)
+ s.PutChar(']');
} break;
}
}
@@ -172,7 +201,9 @@ void UnwindPlan::Row::FAValue::Dump(Stream &s, const UnwindPlan *unwind_plan,
s.PutChar(']');
break;
case isDWARFExpression:
- s.PutCString("dwarf-expr");
+ DumpDWARFExpr(s,
+ llvm::makeArrayRef(m_value.expr.opcodes, m_value.expr.length),
+ thread);
break;
default:
s.PutCString("unspecified");
OpenPOWER on IntegriCloud