From d0156256e2c22f8d7768400375ae6e3d3f1bf5e1 Mon Sep 17 00:00:00 2001 From: Ali Tamur Date: Thu, 7 Mar 2019 19:41:08 +0000 Subject: [PATCH] [lldb] Fix DW_OP_addrx uses. Summary: DW_OP_GNU_addr_index has been renamed as DW_OP_addrx in the standard. clang produces DW_OP_addrx tags and with this change lldb starts to process them. Reviewers: aprantl, jingham, davide, clayborg, serge-sans-paille Reviewed By: aprantl Subscribers: jdoerfert, dblaikie, labath, shafik, lldb-commits Tags: #lldb Differential Revision: https://reviews.llvm.org/D59004 llvm-svn: 355629 --- lldb/lit/SymbolFile/DWARF/dwarf5_locations.s | 66 ++++++++++++++++++++++ lldb/source/Expression/DWARFExpression.cpp | 11 +++- .../SymbolFile/DWARF/DWARFDebugInfoEntry.cpp | 5 +- .../Plugins/SymbolFile/DWARF/DWARFFormValue.cpp | 1 + .../Plugins/SymbolFile/DWARF/HashedNameToDIE.cpp | 1 + 5 files changed, 81 insertions(+), 3 deletions(-) create mode 100644 lldb/lit/SymbolFile/DWARF/dwarf5_locations.s diff --git a/lldb/lit/SymbolFile/DWARF/dwarf5_locations.s b/lldb/lit/SymbolFile/DWARF/dwarf5_locations.s new file mode 100644 index 0000000..7ca9e72 --- /dev/null +++ b/lldb/lit/SymbolFile/DWARF/dwarf5_locations.s @@ -0,0 +1,66 @@ +# This tests that lldb is able to process DW_OP_addrx tags introduced in dwarf5. +# REQUIRES: lld +# RUN: llvm-mc -g -dwarf-version=5 -triple x86_64-unknown-linux-gnu %s -filetype=obj > %t.o +# RUN: ld.lld -m elf_x86_64 %t.o -o %t +# RUN: lldb-test symbols %t | FileCheck %s + +# CHECK: Variable{0xffffffff00000011}, name = "color" +# CHECK-SAME: location = DW_OP_addrx(0x0) + + .text + .section .debug_str,"MS",@progbits,1 +.Lstr_offsets_base0: + .asciz "color" + + .section .debug_str_offsets,"",@progbits + .long .Lstr_offsets_base0 + + .section .debug_abbrev,"",@progbits + .byte 1 # Abbreviation Code + .byte 17 # DW_TAG_compile_unit + .byte 1 # DW_CHILDREN_yes + .byte 114 # DW_AT_str_offsets_base + .byte 23 # DW_FORM_sec_offset + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 2 # Abbreviation Code + .byte 52 # DW_TAG_variable + .byte 0 # DW_CHILDREN_no + .byte 3 # DW_AT_name + .byte 37 # DW_FORM_strx1 + .byte 63 # DW_AT_external + .byte 25 # DW_FORM_flag_present + .byte 2 # DW_AT_location + .byte 24 # DW_FORM_exprloc + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 0 # EOM(3) + .byte 0 # EOM(4) + + .section .debug_info,"",@progbits + .long .Ldebug_info_end0-.Ldebug_info_start0 # Length of Unit +.Ldebug_info_start0: + .short 5 # DWARF version number + .byte 1 # DWARF Unit Type + .byte 8 # Address Size (in bytes) + .long .debug_abbrev # Offset Into Abbrev. Section + .byte 1 # Abbrev [1] 0xc:0x22 DW_TAG_compile_unit + .long .Lstr_offsets_base0 # DW_AT_str_offsets_base + .byte 2 # Abbrev [2] 0x1e:0xb DW_TAG_variable + .byte 0 # DW_AT_name + # DW_AT_external + .byte 2 # DW_AT_location + .byte 161 + .byte 0 + .byte 0 # End Of Children Mark +.Ldebug_info_end0: + + .section .debug_addr,"",@progbits + .long .Ldebug_addr_end0-.Ldebug_addr_start0 # Length of contribution +.Ldebug_addr_start0: + .short 5 # DWARF version number + .byte 8 # Address size + .byte 0 # Segment selector size + .quad color +.Ldebug_addr_end0: + diff --git a/lldb/source/Expression/DWARFExpression.cpp b/lldb/source/Expression/DWARFExpression.cpp index 679b779..2596a7b 100644 --- a/lldb/source/Expression/DWARFExpression.cpp +++ b/lldb/source/Expression/DWARFExpression.cpp @@ -514,6 +514,10 @@ void DWARFExpression::DumpLocation(Stream *s, lldb::offset_t offset, 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)); @@ -877,6 +881,7 @@ static offset_t GetOpcodeDataSize(const DataExtractor &data, return 8; // All opcodes that have a single ULEB (signed or unsigned) argument + case DW_OP_addrx: // 0xa1 1 ULEB128 index case DW_OP_constu: // 0x10 1 ULEB128 constant case DW_OP_consts: // 0x11 1 SLEB128 constant case DW_OP_plus_uconst: // 0x23 1 ULEB128 addend @@ -957,7 +962,7 @@ lldb::addr_t DWARFExpression::GetLocation_DW_OP_addr(uint32_t op_addr_idx, return op_file_addr; else ++curr_op_addr_idx; - } else if (op == DW_OP_GNU_addr_index) { + } else if (op == DW_OP_GNU_addr_index || op == DW_OP_addrx) { uint64_t index = m_data.GetULEB128(&offset); if (curr_op_addr_idx == op_addr_idx) { if (!m_dwarf_cu) { @@ -2902,13 +2907,14 @@ bool DWARFExpression::Evaluate( } break; //---------------------------------------------------------------------- - // OPCODE: DW_OP_GNU_addr_index + // OPCODE: DW_OP_addrx (DW_OP_GNU_addr_index is the legacy name.) // OPERANDS: 1 // ULEB128: index to the .debug_addr section // DESCRIPTION: Pushes an address to the stack from the .debug_addr // section with the base address specified by the DW_AT_addr_base attribute // and the 0 based index is the ULEB128 encoded index. //---------------------------------------------------------------------- + case DW_OP_addrx: case DW_OP_GNU_addr_index: { if (!dwarf_cu) { if (error_ptr) @@ -3194,6 +3200,7 @@ static bool print_dwarf_exp_op(Stream &s, const DataExtractor &data, case DW_OP_call_ref: size = dwarf_ref_size; break; + case DW_OP_addrx: case DW_OP_piece: case DW_OP_plus_uconst: case DW_OP_regx: diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp index 22e62c4..554f091 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp @@ -326,6 +326,7 @@ bool DWARFDebugInfoEntry::Extract(SymbolFileDWARF *dwarf2Data, break; // signed or unsigned LEB 128 values + case DW_FORM_addrx: case DW_FORM_sdata: case DW_FORM_udata: case DW_FORM_ref_udata: @@ -456,6 +457,7 @@ bool DWARFDebugInfoEntry::GetDIENamesAndRanges( case DW_AT_high_pc: if (form_value.Form() == DW_FORM_addr || + form_value.Form() == DW_FORM_addrx || form_value.Form() == DW_FORM_GNU_addr_index) { hi_pc = form_value.Address(); } else { @@ -1031,7 +1033,8 @@ dw_addr_t DWARFDebugInfoEntry::GetAttributeHighPC( if (GetAttributeValue(dwarf2Data, cu, DW_AT_high_pc, form_value, nullptr, check_specification_or_abstract_origin)) { dw_form_t form = form_value.Form(); - if (form == DW_FORM_addr || form == DW_FORM_GNU_addr_index) + if (form == DW_FORM_addr || form == DW_FORM_addrx || + form == DW_FORM_GNU_addr_index) return form_value.Address(); // DWARF4 can specify the hi_pc as an diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp index bc0acfb..3fba8cc 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp @@ -681,6 +681,7 @@ int DWARFFormValue::Compare(const DWARFFormValue &a_value, return 1; switch (a_form) { case DW_FORM_addr: + case DW_FORM_addrx: case DW_FORM_flag: case DW_FORM_data1: case DW_FORM_data2: diff --git a/lldb/source/Plugins/SymbolFile/DWARF/HashedNameToDIE.cpp b/lldb/source/Plugins/SymbolFile/DWARF/HashedNameToDIE.cpp index 36e3d7d..ab43056 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/HashedNameToDIE.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/HashedNameToDIE.cpp @@ -166,6 +166,7 @@ void DWARFMappedHash::Prologue::AppendAtom(AtomType type, dw_form_t form) { case DW_FORM_ref_sig8: llvm_unreachable("Unhandled atom form"); + case DW_FORM_addrx: case DW_FORM_string: case DW_FORM_block: case DW_FORM_block1: -- 2.7.4