Index: lit/Unwind/Inputs/unwind-plan-dwarf-dump.s =================================================================== --- lit/Unwind/Inputs/unwind-plan-dwarf-dump.s +++ 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 Index: lit/Unwind/unwind-plan-dwarf-dump.test =================================================================== --- lit/Unwind/unwind-plan-dwarf-dump.test +++ 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 Index: source/Symbol/UnwindPlan.cpp =================================================================== --- source/Symbol/UnwindPlan.cpp +++ 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 @@ 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 @@ 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 @@ 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");