From 7a784203535b2ec0712d85f898ab1a874530d084 Mon Sep 17 00:00:00 2001 From: Pavel Labath Date: Tue, 23 Apr 2019 09:16:51 +0000 Subject: [PATCH] UnwindPlan: pretty-print dwarf expressions Summary: Previously we were printing the dwarf expressions in unwind rules simply as "dwarf-expr". This patch uses the existing dwarf-printing capabilities in lldb to enhance this dump output, and print the full decoded dwarf expression. Reviewers: jasonmolenda, clayborg Subscribers: aprantl, lldb-commits Differential Revision: https://reviews.llvm.org/D60949 llvm-svn: 358959 --- lldb/lit/Unwind/Inputs/unwind-plan-dwarf-dump.s | 13 +++++++++ lldb/lit/Unwind/unwind-plan-dwarf-dump.test | 14 +++++++++ lldb/source/Symbol/UnwindPlan.cpp | 39 ++++++++++++++++++++++--- 3 files changed, 62 insertions(+), 4 deletions(-) create mode 100644 lldb/lit/Unwind/Inputs/unwind-plan-dwarf-dump.s create mode 100644 lldb/lit/Unwind/unwind-plan-dwarf-dump.test 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 0000000..6030aff --- /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 0000000..c378f56 --- /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 0e084cd..774f9cb 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> +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 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"); -- 2.7.4