From 6f23a68a84c0cb25bd3009758f62367fd475ed24 Mon Sep 17 00:00:00 2001 From: Pavel Labath Date: Mon, 30 Sep 2019 13:44:17 +0000 Subject: [PATCH] Use llvm for dumping DWARF expressions Summary: It uses the new ability of ABI plugins to vend llvm::MCRegisterInfo structs (which is what is needed to turn dwarf register numbers into strings). Reviewers: JDevlieghere, aprantl, jasonmolenda Subscribers: tatyana-krasnukha, lldb-commits Differential Revision: https://reviews.llvm.org/D67966 llvm-svn: 373208 --- lldb/include/lldb/Utility/DataExtractor.h | 6 + lldb/lit/SymbolFile/DWARF/debug_loc.s | 4 +- lldb/lit/SymbolFile/DWARF/dwarf5_locations.s | 2 +- lldb/source/Expression/DWARFExpression.cpp | 411 +----------------- .../Process/gdb-remote/ProcessGDBRemote.cpp | 1 - lldb/source/Symbol/ClangASTContext.cpp | 2 +- lldb/unittests/Utility/ScalarTest.cpp | 4 +- 7 files changed, 17 insertions(+), 413 deletions(-) diff --git a/lldb/include/lldb/Utility/DataExtractor.h b/lldb/include/lldb/Utility/DataExtractor.h index 2898c61df333..333baf9fd349 100644 --- a/lldb/include/lldb/Utility/DataExtractor.h +++ b/lldb/include/lldb/Utility/DataExtractor.h @@ -14,6 +14,7 @@ #include "lldb/lldb-forward.h" #include "lldb/lldb-types.h" #include "llvm/ADT/ArrayRef.h" +#include "llvm/Support/DataExtractor.h" #include #include @@ -995,6 +996,11 @@ public: return {GetDataStart(), size_t(GetByteSize())}; } + llvm::DataExtractor GetAsLLVM() const { + return {GetData(), GetByteOrder() == lldb::eByteOrderLittle, + uint8_t(GetAddressByteSize())}; + } + protected: // Member variables const uint8_t *m_start; ///< A pointer to the first byte of data. diff --git a/lldb/lit/SymbolFile/DWARF/debug_loc.s b/lldb/lit/SymbolFile/DWARF/debug_loc.s index 1fc862f8a1fc..8dec979f694f 100644 --- a/lldb/lit/SymbolFile/DWARF/debug_loc.s +++ b/lldb/lit/SymbolFile/DWARF/debug_loc.s @@ -9,12 +9,12 @@ # RUN: | FileCheck %s # CHECK-LABEL: image lookup -v -a 0 -# CHECK: Variable: {{.*}}, name = "x0", type = "int", location = rdi, +# CHECK: Variable: {{.*}}, name = "x0", type = "int", location = DW_OP_reg5 RDI, # CHECK: Variable: {{.*}}, name = "x1", type = "int", location = , # CHECK: Variable: {{.*}}, name = "x2", type = "int", location = , # CHECK-LABEL: image lookup -v -a 2 -# CHECK: Variable: {{.*}}, name = "x0", type = "int", location = rax, +# CHECK: Variable: {{.*}}, name = "x0", type = "int", location = DW_OP_reg0 RAX, # CHECK: Variable: {{.*}}, name = "x1", type = "int", location = , # CHECK: Variable: {{.*}}, name = "x2", type = "int", location = , diff --git a/lldb/lit/SymbolFile/DWARF/dwarf5_locations.s b/lldb/lit/SymbolFile/DWARF/dwarf5_locations.s index 2cf16ca78103..4093ea059808 100644 --- a/lldb/lit/SymbolFile/DWARF/dwarf5_locations.s +++ b/lldb/lit/SymbolFile/DWARF/dwarf5_locations.s @@ -7,7 +7,7 @@ # RUN: lldb-test symbols %t | FileCheck %s # CHECK: Variable{0x7fffffff00000011}, name = "color" -# CHECK-SAME: location = DW_OP_addrx(0x0) +# CHECK-SAME: location = DW_OP_addrx 0x0 .text .section .debug_str,"MS",@progbits,1 diff --git a/lldb/source/Expression/DWARFExpression.cpp b/lldb/source/Expression/DWARFExpression.cpp index 48bfa72a19b5..d1ef95726855 100644 --- a/lldb/source/Expression/DWARFExpression.cpp +++ b/lldb/source/Expression/DWARFExpression.cpp @@ -88,413 +88,10 @@ void DWARFExpression::DumpLocation(Stream *s, lldb::offset_t offset, lldb::offset_t length, lldb::DescriptionLevel level, ABI *abi) const { - if (!m_data.ValidOffsetForDataOfSize(offset, length)) - return; - const lldb::offset_t start_offset = offset; - const lldb::offset_t end_offset = offset + length; - - // An operation within a DWARF expression may contain a sub-expression. The - // motivating example for this is DW_OP_entry_value. Keep track of where each - // each sub-expression ends. - std::vector ends_of_subexprs; - - // "Finish" (i.e. print the closing right-parens) for sub-expressions up to - // the specified \p op_offset. - auto finish_subexpressions_to = [&](const lldb::offset_t op_offset) { - while (!ends_of_subexprs.empty() && op_offset >= ends_of_subexprs.back()) { - ends_of_subexprs.pop_back(); - s->Printf(")"); - if (!ends_of_subexprs.empty()) - s->Printf(" "); - } - }; - - while (m_data.ValidOffset(offset) && offset < end_offset) { - const lldb::offset_t op_offset = offset; - const uint8_t op = m_data.GetU8(&offset); - finish_subexpressions_to(op_offset); - - switch (level) { - default: - break; - - case lldb::eDescriptionLevelBrief: - if (op_offset > start_offset) - s->PutChar(' '); - break; - - case lldb::eDescriptionLevelFull: - case lldb::eDescriptionLevelVerbose: - if (op_offset > start_offset) - s->EOL(); - s->Indent(); - if (level == lldb::eDescriptionLevelFull) - break; - // Fall through for verbose and print offset and DW_OP prefix.. - s->Printf("0x%8.8" PRIx64 ": %s", op_offset, - op >= DW_OP_APPLE_uninit ? "DW_OP_APPLE_" : "DW_OP_"); - break; - } - - switch (op) { - case DW_OP_addr: - *s << "DW_OP_addr(" << m_data.GetAddress(&offset) << ") "; - break; // 0x03 1 address - case DW_OP_deref: - *s << "DW_OP_deref"; - break; // 0x06 - case DW_OP_const1u: - s->Printf("DW_OP_const1u(0x%2.2x)", m_data.GetU8(&offset)); - break; // 0x08 1 1-byte constant - case DW_OP_const1s: - s->Printf("DW_OP_const1s(0x%2.2x)", m_data.GetU8(&offset)); - break; // 0x09 1 1-byte constant - case DW_OP_const2u: - s->Printf("DW_OP_const2u(0x%4.4x)", m_data.GetU16(&offset)); - break; // 0x0a 1 2-byte constant - case DW_OP_const2s: - s->Printf("DW_OP_const2s(0x%4.4x)", m_data.GetU16(&offset)); - break; // 0x0b 1 2-byte constant - case DW_OP_const4u: - s->Printf("DW_OP_const4u(0x%8.8x)", m_data.GetU32(&offset)); - break; // 0x0c 1 4-byte constant - case DW_OP_const4s: - s->Printf("DW_OP_const4s(0x%8.8x)", m_data.GetU32(&offset)); - break; // 0x0d 1 4-byte constant - case DW_OP_const8u: - s->Printf("DW_OP_const8u(0x%16.16" PRIx64 ")", m_data.GetU64(&offset)); - break; // 0x0e 1 8-byte constant - case DW_OP_const8s: - s->Printf("DW_OP_const8s(0x%16.16" PRIx64 ")", m_data.GetU64(&offset)); - break; // 0x0f 1 8-byte constant - case DW_OP_constu: - s->Printf("DW_OP_constu(0x%" PRIx64 ")", m_data.GetULEB128(&offset)); - break; // 0x10 1 ULEB128 constant - case DW_OP_consts: - s->Printf("DW_OP_consts(0x%" PRId64 ")", m_data.GetSLEB128(&offset)); - break; // 0x11 1 SLEB128 constant - case DW_OP_dup: - s->PutCString("DW_OP_dup"); - break; // 0x12 - case DW_OP_drop: - s->PutCString("DW_OP_drop"); - break; // 0x13 - case DW_OP_over: - s->PutCString("DW_OP_over"); - break; // 0x14 - case DW_OP_pick: - s->Printf("DW_OP_pick(0x%2.2x)", m_data.GetU8(&offset)); - break; // 0x15 1 1-byte stack index - case DW_OP_swap: - s->PutCString("DW_OP_swap"); - break; // 0x16 - case DW_OP_rot: - s->PutCString("DW_OP_rot"); - break; // 0x17 - case DW_OP_xderef: - s->PutCString("DW_OP_xderef"); - break; // 0x18 - case DW_OP_abs: - s->PutCString("DW_OP_abs"); - break; // 0x19 - case DW_OP_and: - s->PutCString("DW_OP_and"); - break; // 0x1a - case DW_OP_div: - s->PutCString("DW_OP_div"); - break; // 0x1b - case DW_OP_minus: - s->PutCString("DW_OP_minus"); - break; // 0x1c - case DW_OP_mod: - s->PutCString("DW_OP_mod"); - break; // 0x1d - case DW_OP_mul: - s->PutCString("DW_OP_mul"); - break; // 0x1e - case DW_OP_neg: - s->PutCString("DW_OP_neg"); - break; // 0x1f - case DW_OP_not: - s->PutCString("DW_OP_not"); - break; // 0x20 - case DW_OP_or: - s->PutCString("DW_OP_or"); - break; // 0x21 - case DW_OP_plus: - s->PutCString("DW_OP_plus"); - break; // 0x22 - case DW_OP_plus_uconst: // 0x23 1 ULEB128 addend - s->Printf("DW_OP_plus_uconst(0x%" PRIx64 ")", - m_data.GetULEB128(&offset)); - break; - - case DW_OP_shl: - s->PutCString("DW_OP_shl"); - break; // 0x24 - case DW_OP_shr: - s->PutCString("DW_OP_shr"); - break; // 0x25 - case DW_OP_shra: - s->PutCString("DW_OP_shra"); - break; // 0x26 - case DW_OP_xor: - s->PutCString("DW_OP_xor"); - break; // 0x27 - case DW_OP_skip: - s->Printf("DW_OP_skip(0x%4.4x)", m_data.GetU16(&offset)); - break; // 0x2f 1 signed 2-byte constant - case DW_OP_bra: - s->Printf("DW_OP_bra(0x%4.4x)", m_data.GetU16(&offset)); - break; // 0x28 1 signed 2-byte constant - case DW_OP_eq: - s->PutCString("DW_OP_eq"); - break; // 0x29 - case DW_OP_ge: - s->PutCString("DW_OP_ge"); - break; // 0x2a - case DW_OP_gt: - s->PutCString("DW_OP_gt"); - break; // 0x2b - case DW_OP_le: - s->PutCString("DW_OP_le"); - break; // 0x2c - case DW_OP_lt: - s->PutCString("DW_OP_lt"); - break; // 0x2d - case DW_OP_ne: - s->PutCString("DW_OP_ne"); - break; // 0x2e - - case DW_OP_lit0: // 0x30 - case DW_OP_lit1: // 0x31 - case DW_OP_lit2: // 0x32 - case DW_OP_lit3: // 0x33 - case DW_OP_lit4: // 0x34 - case DW_OP_lit5: // 0x35 - case DW_OP_lit6: // 0x36 - case DW_OP_lit7: // 0x37 - case DW_OP_lit8: // 0x38 - case DW_OP_lit9: // 0x39 - case DW_OP_lit10: // 0x3A - case DW_OP_lit11: // 0x3B - case DW_OP_lit12: // 0x3C - case DW_OP_lit13: // 0x3D - case DW_OP_lit14: // 0x3E - case DW_OP_lit15: // 0x3F - case DW_OP_lit16: // 0x40 - case DW_OP_lit17: // 0x41 - case DW_OP_lit18: // 0x42 - case DW_OP_lit19: // 0x43 - case DW_OP_lit20: // 0x44 - case DW_OP_lit21: // 0x45 - case DW_OP_lit22: // 0x46 - case DW_OP_lit23: // 0x47 - case DW_OP_lit24: // 0x48 - case DW_OP_lit25: // 0x49 - case DW_OP_lit26: // 0x4A - case DW_OP_lit27: // 0x4B - case DW_OP_lit28: // 0x4C - case DW_OP_lit29: // 0x4D - case DW_OP_lit30: // 0x4E - case DW_OP_lit31: - s->Printf("DW_OP_lit%i", op - DW_OP_lit0); - break; // 0x4f - - case DW_OP_reg0: // 0x50 - case DW_OP_reg1: // 0x51 - case DW_OP_reg2: // 0x52 - case DW_OP_reg3: // 0x53 - case DW_OP_reg4: // 0x54 - case DW_OP_reg5: // 0x55 - case DW_OP_reg6: // 0x56 - case DW_OP_reg7: // 0x57 - case DW_OP_reg8: // 0x58 - case DW_OP_reg9: // 0x59 - case DW_OP_reg10: // 0x5A - case DW_OP_reg11: // 0x5B - case DW_OP_reg12: // 0x5C - case DW_OP_reg13: // 0x5D - case DW_OP_reg14: // 0x5E - case DW_OP_reg15: // 0x5F - case DW_OP_reg16: // 0x60 - case DW_OP_reg17: // 0x61 - case DW_OP_reg18: // 0x62 - case DW_OP_reg19: // 0x63 - case DW_OP_reg20: // 0x64 - case DW_OP_reg21: // 0x65 - case DW_OP_reg22: // 0x66 - case DW_OP_reg23: // 0x67 - case DW_OP_reg24: // 0x68 - case DW_OP_reg25: // 0x69 - case DW_OP_reg26: // 0x6A - case DW_OP_reg27: // 0x6B - case DW_OP_reg28: // 0x6C - case DW_OP_reg29: // 0x6D - case DW_OP_reg30: // 0x6E - case DW_OP_reg31: // 0x6F - { - uint32_t reg_num = op - DW_OP_reg0; - if (abi) { - RegisterInfo reg_info; - if (abi->GetRegisterInfoByKind(m_reg_kind, reg_num, reg_info)) { - if (reg_info.name) { - s->PutCString(reg_info.name); - break; - } else if (reg_info.alt_name) { - s->PutCString(reg_info.alt_name); - break; - } - } - } - s->Printf("DW_OP_reg%u", reg_num); - break; - } break; - - case DW_OP_breg0: - case DW_OP_breg1: - case DW_OP_breg2: - case DW_OP_breg3: - case DW_OP_breg4: - case DW_OP_breg5: - case DW_OP_breg6: - case DW_OP_breg7: - case DW_OP_breg8: - case DW_OP_breg9: - case DW_OP_breg10: - case DW_OP_breg11: - case DW_OP_breg12: - case DW_OP_breg13: - case DW_OP_breg14: - case DW_OP_breg15: - case DW_OP_breg16: - case DW_OP_breg17: - case DW_OP_breg18: - case DW_OP_breg19: - case DW_OP_breg20: - case DW_OP_breg21: - case DW_OP_breg22: - case DW_OP_breg23: - case DW_OP_breg24: - case DW_OP_breg25: - case DW_OP_breg26: - case DW_OP_breg27: - case DW_OP_breg28: - case DW_OP_breg29: - case DW_OP_breg30: - case DW_OP_breg31: { - uint32_t reg_num = op - DW_OP_breg0; - int64_t reg_offset = m_data.GetSLEB128(&offset); - if (abi) { - RegisterInfo reg_info; - if (abi->GetRegisterInfoByKind(m_reg_kind, reg_num, reg_info)) { - if (reg_info.name) { - s->Printf("[%s%+" PRIi64 "]", reg_info.name, reg_offset); - break; - } else if (reg_info.alt_name) { - s->Printf("[%s%+" PRIi64 "]", reg_info.alt_name, reg_offset); - break; - } - } - } - s->Printf("DW_OP_breg%i(0x%" PRIx64 ")", reg_num, reg_offset); - } break; - - case DW_OP_regx: // 0x90 1 ULEB128 register - { - uint32_t reg_num = m_data.GetULEB128(&offset); - if (abi) { - RegisterInfo reg_info; - if (abi->GetRegisterInfoByKind(m_reg_kind, reg_num, reg_info)) { - if (reg_info.name) { - s->PutCString(reg_info.name); - break; - } else if (reg_info.alt_name) { - s->PutCString(reg_info.alt_name); - break; - } - } - } - s->Printf("DW_OP_regx(%" PRIu32 ")", reg_num); - break; - } break; - case DW_OP_fbreg: // 0x91 1 SLEB128 offset - s->Printf("DW_OP_fbreg(%" PRIi64 ")", m_data.GetSLEB128(&offset)); - break; - case DW_OP_bregx: // 0x92 2 ULEB128 register followed by SLEB128 offset - { - uint32_t reg_num = m_data.GetULEB128(&offset); - int64_t reg_offset = m_data.GetSLEB128(&offset); - if (abi) { - RegisterInfo reg_info; - if (abi->GetRegisterInfoByKind(m_reg_kind, reg_num, reg_info)) { - if (reg_info.name) { - s->Printf("[%s%+" PRIi64 "]", reg_info.name, reg_offset); - break; - } else if (reg_info.alt_name) { - s->Printf("[%s%+" PRIi64 "]", reg_info.alt_name, reg_offset); - break; - } - } - } - s->Printf("DW_OP_bregx(reg=%" PRIu32 ",offset=%" PRIi64 ")", reg_num, - reg_offset); - } break; - case DW_OP_piece: // 0x93 1 ULEB128 size of piece addressed - s->Printf("DW_OP_piece(0x%" PRIx64 ")", m_data.GetULEB128(&offset)); - break; - case DW_OP_deref_size: // 0x94 1 1-byte size of data retrieved - s->Printf("DW_OP_deref_size(0x%2.2x)", m_data.GetU8(&offset)); - break; - case DW_OP_xderef_size: // 0x95 1 1-byte size of data retrieved - s->Printf("DW_OP_xderef_size(0x%2.2x)", m_data.GetU8(&offset)); - break; - case DW_OP_nop: - s->PutCString("DW_OP_nop"); - break; // 0x96 - case DW_OP_push_object_address: - s->PutCString("DW_OP_push_object_address"); - break; // 0x97 DWARF3 - case DW_OP_call2: // 0x98 DWARF3 1 2-byte offset of DIE - s->Printf("DW_OP_call2(0x%4.4x)", m_data.GetU16(&offset)); - break; - case DW_OP_call4: // 0x99 DWARF3 1 4-byte offset of DIE - s->Printf("DW_OP_call4(0x%8.8x)", m_data.GetU32(&offset)); - break; - case DW_OP_call_ref: // 0x9a DWARF3 1 4- or 8-byte offset of DIE - s->Printf("DW_OP_call_ref(0x%8.8" PRIx64 ")", m_data.GetAddress(&offset)); - break; - case DW_OP_form_tls_address: - s->PutCString("DW_OP_form_tls_address"); // 0x9b - break; - case DW_OP_GNU_addr_index: // 0xfb - s->Printf("DW_OP_GNU_addr_index(0x%" PRIx64 ")", - m_data.GetULEB128(&offset)); - break; - case DW_OP_addrx: - s->Printf("DW_OP_addrx(0x%" PRIx64 ")", - m_data.GetULEB128(&offset)); - break; - case DW_OP_GNU_const_index: // 0xfc - s->Printf("DW_OP_GNU_const_index(0x%" PRIx64 ")", - m_data.GetULEB128(&offset)); - break; - case DW_OP_GNU_push_tls_address: - s->PutCString("DW_OP_GNU_push_tls_address"); // 0xe0 - break; - case DW_OP_APPLE_uninit: - s->PutCString("DW_OP_APPLE_uninit"); // 0xF0 - break; - case DW_OP_entry_value: { - uint32_t subexpr_len = m_data.GetULEB128(&offset); - s->PutCString("DW_OP_entry_value("); - ends_of_subexprs.push_back(offset + subexpr_len); - break; - } - } - } - - finish_subexpressions_to(end_offset); + llvm::DWARFExpression(DataExtractor(m_data, offset, length).GetAsLLVM(), + llvm::dwarf::DWARF_VERSION, m_data.GetAddressByteSize()) + .print(s->AsRawOstream(), abi ? &abi->GetMCRegisterInfo() : nullptr, + nullptr); } void DWARFExpression::SetLocationListSlide(addr_t slide) { diff --git a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp index ab1e572316a9..3f0f3e4bb14e 100644 --- a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp +++ b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp @@ -86,7 +86,6 @@ #include "llvm/Support/raw_ostream.h" #define DEBUGSERVER_BASENAME "debugserver" -using namespace llvm; using namespace lldb; using namespace lldb_private; using namespace lldb_private::process_gdb_remote; diff --git a/lldb/source/Symbol/ClangASTContext.cpp b/lldb/source/Symbol/ClangASTContext.cpp index eb86d117e7ff..78bad39d236b 100644 --- a/lldb/source/Symbol/ClangASTContext.cpp +++ b/lldb/source/Symbol/ClangASTContext.cpp @@ -103,8 +103,8 @@ using namespace lldb; using namespace lldb_private; -using namespace llvm; using namespace clang; +using llvm::StringSwitch; namespace { #ifdef LLDB_CONFIGURATION_DEBUG diff --git a/lldb/unittests/Utility/ScalarTest.cpp b/lldb/unittests/Utility/ScalarTest.cpp index 54012d8d0593..3a955e9a6687 100644 --- a/lldb/unittests/Utility/ScalarTest.cpp +++ b/lldb/unittests/Utility/ScalarTest.cpp @@ -16,7 +16,9 @@ #include "llvm/Testing/Support/Error.h" using namespace lldb_private; -using namespace llvm; +using llvm::APInt; +using llvm::Failed; +using llvm::Succeeded; template bool checkInequality(T c1, T c2) {