[Lldb-commits] [lldb] 0092dbc - [lldb] Fix lookup of .debug_loclists with split-dwarf
Author: Kim-Anh Tran Date: 2021-08-04T11:36:44+02:00 New Revision: 0092dbcd80f208f7becec002e70bad5b35a081cd URL: https://github.com/llvm/llvm-project/commit/0092dbcd80f208f7becec002e70bad5b35a081cd DIFF: https://github.com/llvm/llvm-project/commit/0092dbcd80f208f7becec002e70bad5b35a081cd.diff LOG: [lldb] Fix lookup of .debug_loclists with split-dwarf This patch fixes the lookup of locations in .debug_loclists, if they are split in a .dwp file. Mainly, we need to consider the cu index offsets. Reviewed By: jankratochvil Differential Revision: https://reviews.llvm.org/D107161 Added: lldb/test/Shell/SymbolFile/DWARF/x86/debug_loclists-dwp.s Modified: lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp Removed: diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp index 067561be0cf05..a498117c264bb 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp @@ -453,6 +453,18 @@ ParseListTableHeader(const llvm::DWARFDataExtractor &data, uint64_t offset, } void DWARFUnit::SetLoclistsBase(dw_addr_t loclists_base) { + uint64_t offset = 0; + if (const llvm::DWARFUnitIndex::Entry *entry = m_header.GetIndexEntry()) { +const auto *contribution = entry->getContribution(llvm::DW_SECT_LOCLISTS); +if (!contribution) { + GetSymbolFileDWARF().GetObjectFile()->GetModule()->ReportError( + "Failed to find location list contribution for CU with DWO Id " + "0x%" PRIx64, + this->GetDWOId()); + return; +} +offset += contribution->Offset; + } m_loclists_base = loclists_base; uint64_t header_size = llvm::DWARFListTableHeader::getHeaderSize(DWARF32); @@ -460,13 +472,14 @@ void DWARFUnit::SetLoclistsBase(dw_addr_t loclists_base) { return; m_loclist_table_header.emplace(".debug_loclists", "locations"); - uint64_t offset = loclists_base - header_size; + offset += loclists_base - header_size; if (llvm::Error E = m_loclist_table_header->extract( m_dwarf.GetDWARFContext().getOrLoadLocListsData().GetAsLLVM(), &offset)) { GetSymbolFileDWARF().GetObjectFile()->GetModule()->ReportError( -"Failed to extract location list table at offset 0x%" PRIx64 ": %s", -loclists_base, toString(std::move(E)).c_str()); +"Failed to extract location list table at offset 0x%" PRIx64 +" (location list base: 0x%" PRIx64 "): %s", +offset, loclists_base, toString(std::move(E)).c_str()); } } @@ -486,7 +499,8 @@ DWARFDataExtractor DWARFUnit::GetLocationData() const { const DWARFDataExtractor &data = GetVersion() >= 5 ? Ctx.getOrLoadLocListsData() : Ctx.getOrLoadLocData(); if (const llvm::DWARFUnitIndex::Entry *entry = m_header.GetIndexEntry()) { -if (const auto *contribution = entry->getContribution(llvm::DW_SECT_EXT_LOC)) +if (const auto *contribution = entry->getContribution( +GetVersion() >= 5 ? llvm::DW_SECT_LOCLISTS : llvm::DW_SECT_EXT_LOC)) return DWARFDataExtractor(data, contribution->Offset, contribution->Length); return DWARFDataExtractor(); diff --git a/lldb/test/Shell/SymbolFile/DWARF/x86/debug_loclists-dwp.s b/lldb/test/Shell/SymbolFile/DWARF/x86/debug_loclists-dwp.s new file mode 100644 index 0..2cc344a09325a --- /dev/null +++ b/lldb/test/Shell/SymbolFile/DWARF/x86/debug_loclists-dwp.s @@ -0,0 +1,236 @@ +## This tests if .debug_loclists.dwo are correctly read if they are part +## of a dwp file. + +# RUN: llvm-mc -triple=x86_64-pc-linux -filetype=obj %s --defsym MAIN=0 > %t +# RUN: llvm-mc -triple=x86_64-pc-linux -filetype=obj %s > %t.dwp +# RUN: %lldb %t -o "image lookup -v -s lookup_loclists" -o exit | FileCheck %s + +# CHECK-LABEL: image lookup -v -s lookup_loclists +# CHECK: Variable: id = {{.*}}, name = "x0", type = "int", location = DW_OP_reg0 RAX, +# CHECK: Variable: id = {{.*}}, name = "x1", type = "int", location = DW_OP_reg1 RDX, + +## This part is kept in both the main and the dwp file to be able to reference the offsets. +loclists: +nop +nop +.Ltmp1: +lookup_loclists: +nop +.Ltmp2: +nop +.Ltmp3: +nop +.Lloclists_end: + +## The main file. +.ifdef MAIN +.section.debug_abbrev,"",@progbits +.byte 1 # Abbreviation Code +.byte 74 # DW_TAG_compile_unit +.byte 0 # DW_CHILDREN_no +.byte 0x76# DW_AT_dwo_name +.byte 8 # DW_FORM_string +.byte 115 # DW_AT_addr_base +.byte 23 # DW_FORM_sec_offset +.byte 17 # DW_AT_low_pc +.byte 1 # DW_FORM_addr +
[Lldb-commits] [lldb] 0dda542 - [DWARF5] Fix offset check when using .debug_names
Author: Kim-Anh Tran Date: 2021-08-09T13:15:14+02:00 New Revision: 0dda5425318a5785e3e19cfe369a43b221b9642d URL: https://github.com/llvm/llvm-project/commit/0dda5425318a5785e3e19cfe369a43b221b9642d DIFF: https://github.com/llvm/llvm-project/commit/0dda5425318a5785e3e19cfe369a43b221b9642d.diff LOG: [DWARF5] Fix offset check when using .debug_names When going through the CU entries in the name index, make sure to compare the name entry's CU offset against the skeleton CU's offset. Previously there would be a mismatch, since the wrong offset was compared, and thus no suitable entry was found. Reviewed By: jankratochvil Differential Revision: https://reviews.llvm.org/D106270 Added: Modified: lldb/source/Plugins/SymbolFile/DWARF/AppleDWARFIndex.cpp lldb/source/Plugins/SymbolFile/DWARF/AppleDWARFIndex.h lldb/source/Plugins/SymbolFile/DWARF/DWARFIndex.h lldb/source/Plugins/SymbolFile/DWARF/DebugNamesDWARFIndex.cpp lldb/source/Plugins/SymbolFile/DWARF/DebugNamesDWARFIndex.h lldb/source/Plugins/SymbolFile/DWARF/ManualDWARFIndex.cpp lldb/source/Plugins/SymbolFile/DWARF/ManualDWARFIndex.h lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp lldb/test/Shell/SymbolFile/DWARF/x86/find-variable-file.cpp Removed: diff --git a/lldb/source/Plugins/SymbolFile/DWARF/AppleDWARFIndex.cpp b/lldb/source/Plugins/SymbolFile/DWARF/AppleDWARFIndex.cpp index 60b6b726f6c09..c786451a03df2 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/AppleDWARFIndex.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/AppleDWARFIndex.cpp @@ -75,12 +75,14 @@ void AppleDWARFIndex::GetGlobalVariables( } void AppleDWARFIndex::GetGlobalVariables( -const DWARFUnit &cu, llvm::function_ref callback) { +DWARFUnit &cu, llvm::function_ref callback) { if (!m_apple_names_up) return; + const DWARFUnit &non_skeleton_cu = cu.GetNonSkeletonUnit(); DWARFMappedHash::DIEInfoArray hash_data; - m_apple_names_up->AppendAllDIEsInRange(cu.GetOffset(), cu.GetNextUnitOffset(), + m_apple_names_up->AppendAllDIEsInRange(non_skeleton_cu.GetOffset(), + non_skeleton_cu.GetNextUnitOffset(), hash_data); DWARFMappedHash::ExtractDIEArray(hash_data, DIERefCallback(callback)); } diff --git a/lldb/source/Plugins/SymbolFile/DWARF/AppleDWARFIndex.h b/lldb/source/Plugins/SymbolFile/DWARF/AppleDWARFIndex.h index a7032f50e590a..ef3cb5dee0356 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/AppleDWARFIndex.h +++ b/lldb/source/Plugins/SymbolFile/DWARF/AppleDWARFIndex.h @@ -39,7 +39,7 @@ class AppleDWARFIndex : public DWARFIndex { GetGlobalVariables(const RegularExpression ®ex, llvm::function_ref callback) override; void - GetGlobalVariables(const DWARFUnit &cu, + GetGlobalVariables(DWARFUnit &cu, llvm::function_ref callback) override; void GetObjCMethods(ConstString class_name, llvm::function_ref callback) override; diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFIndex.h b/lldb/source/Plugins/SymbolFile/DWARF/DWARFIndex.h index ecf82a910b661..6f2698cc6e6fb 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFIndex.h +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFIndex.h @@ -35,7 +35,7 @@ class DWARFIndex { GetGlobalVariables(const RegularExpression ®ex, llvm::function_ref callback) = 0; virtual void - GetGlobalVariables(const DWARFUnit &cu, + GetGlobalVariables(DWARFUnit &cu, llvm::function_ref callback) = 0; virtual void GetObjCMethods(ConstString class_name, diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DebugNamesDWARFIndex.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DebugNamesDWARFIndex.cpp index 5dfa5a176d384..2b2c13abb250b 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/DebugNamesDWARFIndex.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/DebugNamesDWARFIndex.cpp @@ -123,7 +123,7 @@ void DebugNamesDWARFIndex::GetGlobalVariables( } void DebugNamesDWARFIndex::GetGlobalVariables( -const DWARFUnit &cu, llvm::function_ref callback) { +DWARFUnit &cu, llvm::function_ref callback) { uint64_t cu_offset = cu.GetOffset(); bool found_entry_for_cu = false; for (const DebugNames::NameIndex &ni: *m_debug_names_up) { diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DebugNamesDWARFIndex.h b/lldb/source/Plugins/SymbolFile/DWARF/DebugNamesDWARFIndex.h index 5d041c36c8f29..c451ccd4857fa 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/DebugNamesDWARFIndex.h +++ b/lldb/source/Plugins/SymbolFile/DWARF/DebugNamesDWARFIndex.h @@ -32,7 +32,7 @@ class DebugNamesDWARFIndex : public DWARFIndex { GetGlobalVariables(const RegularExpression ®ex, llvm::function_ref callback) override; void - GetGlobalVariables(const DWARFUnit &cu, + GetGlobalVariables(DWAR
[Lldb-commits] [lldb] 3973d8b - [lldb] Return all line entries matchign a line if no column is specified
Author: Kim-Anh Tran Date: 2021-08-30T14:45:46+02:00 New Revision: 3973d8b29e249a6ea4aceaa4225dfde5663937c6 URL: https://github.com/llvm/llvm-project/commit/3973d8b29e249a6ea4aceaa4225dfde5663937c6 DIFF: https://github.com/llvm/llvm-project/commit/3973d8b29e249a6ea4aceaa4225dfde5663937c6.diff LOG: [lldb] Return all line entries matchign a line if no column is specified Previously, if no column was specified, ResolveSymbolContext would take the first match returned by FindLineEntryIndexByFileIndex, and reuse it to find subsequent exact matches. With the introduction of columns, columns are now considered when matching the line entries. This leads to a problem if one wants to get all existing line entries that match that line, since now the column is also used for the exact match. This way, all line entries are filtered out that have a different column number, but the same line number. This patch changes that by ignoring the column information of the first match if the original request of ResolveSymbolContext was also ignoring it. Reviewed By: mib Differential Revision: https://reviews.llvm.org/D108816 Added: Modified: lldb/source/Symbol/CompileUnit.cpp lldb/unittests/Symbol/TestLineEntry.cpp Removed: diff --git a/lldb/source/Symbol/CompileUnit.cpp b/lldb/source/Symbol/CompileUnit.cpp index 6c4a36d451959..7c840d8bb0649 100644 --- a/lldb/source/Symbol/CompileUnit.cpp +++ b/lldb/source/Symbol/CompileUnit.cpp @@ -319,8 +319,13 @@ void CompileUnit::ResolveSymbolContext( // subsequent line exact matches below. const bool inlines = false; const bool exact = true; - SourceLocationSpec found_entry(line_entry.file, line_entry.line, - line_entry.column, inlines, exact); + const llvm::Optional column = + src_location_spec.GetColumn().hasValue() + ? llvm::Optional(line_entry.column) + : llvm::None; + + SourceLocationSpec found_entry(line_entry.file, line_entry.line, column, + inlines, exact); while (line_idx != UINT32_MAX) { // If they only asked for the line entry, then we're done, we can diff --git a/lldb/unittests/Symbol/TestLineEntry.cpp b/lldb/unittests/Symbol/TestLineEntry.cpp index 3a6bc58a40ee3..8af3c5c2bd53e 100644 --- a/lldb/unittests/Symbol/TestLineEntry.cpp +++ b/lldb/unittests/Symbol/TestLineEntry.cpp @@ -38,7 +38,8 @@ class LineEntryTest : public testing::Test { void SetUp() override; protected: - llvm::Expected GetLineEntryForLine(uint32_t line); + llvm::Expected + GetLineEntriesForLine(uint32_t line, llvm::Optional column); llvm::Optional m_file; ModuleSP m_module_sp; }; @@ -50,8 +51,9 @@ void LineEntryTest::SetUp() { m_module_sp = std::make_shared(m_file->moduleSpec()); } -llvm::Expected LineEntryTest::GetLineEntryForLine(uint32_t line) { // TODO: Handle SourceLocationSpec column information +llvm::Expected LineEntryTest::GetLineEntriesForLine( +uint32_t line, llvm::Optional column = llvm::None) { SymbolContextList sc_comp_units; SymbolContextList sc_line_entries; FileSpec file_spec("inlined-functions.cpp"); @@ -62,7 +64,7 @@ llvm::Expected LineEntryTest::GetLineEntryForLine(uint32_t line) { return llvm::createStringError(llvm::inconvertibleErrorCode(), "No comp unit found on the test object."); - SourceLocationSpec location_spec(file_spec, line, /*column=*/llvm::None, + SourceLocationSpec location_spec(file_spec, line, column, /*check_inlines=*/true, /*exact_match=*/true); @@ -71,33 +73,53 @@ llvm::Expected LineEntryTest::GetLineEntryForLine(uint32_t line) { if (sc_line_entries.GetSize() == 0) return llvm::createStringError(llvm::inconvertibleErrorCode(), "No line entry found on the test object."); - return sc_line_entries[0].line_entry; + return sc_line_entries; +} + +// This tests if we can get all line entries that match the passed line, if +// no column is specified. +TEST_F(LineEntryTest, GetAllExactLineMatchesWithoutColumn) { + auto sc_line_entries = GetLineEntriesForLine(12); + ASSERT_THAT_EXPECTED(sc_line_entries, llvm::Succeeded()); + ASSERT_EQ(sc_line_entries->NumLineEntriesWithLine(12), 6u); +} + +// This tests if we can get exact line and column matches. +TEST_F(LineEntryTest, GetAllExactLineColumnMatches) { + auto sc_line_entries = GetLineEntriesForLine(12, 39); + ASSERT_THAT_EXPECTED(sc_line_entries, llvm::Succeeded()); + ASSERT_EQ(sc_line_entries->NumLineEntriesWithLine(12), 1u); + auto line_entry = sc_line_entries.get()[0].line_entry; + ASSERT_EQ(line_entry.column, 39); } TEST_F(LineEntryTest, GetSameLineContiguousAddressRangeNoInlines) { - auto line_entry = GetLineEntryForLine(18); - ASSERT_THAT_EXPECTED(line_entry, llvm::Succeeded()); + auto
[Lldb-commits] [lldb] ec671f3 - [lldb] Support .debug_rnglists.dwo sections in dwp file
Author: Kim-Anh Tran Date: 2021-09-03T15:19:50+02:00 New Revision: ec671f3ea00bcbd7cca7f0d9209c9d775dd47c39 URL: https://github.com/llvm/llvm-project/commit/ec671f3ea00bcbd7cca7f0d9209c9d775dd47c39 DIFF: https://github.com/llvm/llvm-project/commit/ec671f3ea00bcbd7cca7f0d9209c9d775dd47c39.diff LOG: [lldb] Support .debug_rnglists.dwo sections in dwp file This patch considers the CU index entry when reading the .debug_rnglists.dwo section. Reviewed By: jankratochvil Differential Revision: https://reviews.llvm.org/D107456 Added: lldb/test/Shell/SymbolFile/DWARF/x86/debug_rnglists-dwp.s Modified: lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.h Removed: diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp index 9a56e1e6aa2c6..988c1a75f5450 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp @@ -513,6 +513,24 @@ DWARFDataExtractor DWARFUnit::GetLocationData() const { return data; } +DWARFDataExtractor DWARFUnit::GetRnglistData() const { + DWARFContext &Ctx = GetSymbolFileDWARF().GetDWARFContext(); + const DWARFDataExtractor &data = Ctx.getOrLoadRngListsData(); + if (const llvm::DWARFUnitIndex::Entry *entry = m_header.GetIndexEntry()) { +if (const auto *contribution = +entry->getContribution(llvm::DW_SECT_RNGLISTS)) + return DWARFDataExtractor(data, contribution->Offset, +contribution->Length); +GetSymbolFileDWARF().GetObjectFile()->GetModule()->ReportError( +"Failed to find range list contribution for CU with signature " +"0x%" PRIx64, +entry->getSignature()); + +return DWARFDataExtractor(); + } + return data; +} + void DWARFUnit::SetRangesBase(dw_addr_t ranges_base) { lldbassert(!m_rnglist_table_done); @@ -525,8 +543,7 @@ DWARFUnit::GetRnglistTable() { m_rnglist_table_done = true; if (auto table_or_error = ParseListTableHeader( -m_dwarf.GetDWARFContext().getOrLoadRngListsData().GetAsLLVM(), -m_ranges_base, DWARF32)) +GetRnglistData().GetAsLLVM(), m_ranges_base, DWARF32)) m_rnglist_table = std::move(table_or_error.get()); else GetSymbolFileDWARF().GetObjectFile()->GetModule()->ReportError( @@ -547,7 +564,7 @@ llvm::Expected DWARFUnit::GetRnglistOffset(uint32_t Index) { "DW_AT_rnglists_base for CU at 0x%8.8x", GetOffset()); if (llvm::Optional off = GetRnglistTable()->getOffsetEntry( - m_dwarf.GetDWARFContext().getOrLoadRngListsData().GetAsLLVM(), Index)) + GetRnglistData().GetAsLLVM(), Index)) return *off + m_ranges_base; return llvm::createStringError( errc::invalid_argument, @@ -1001,8 +1018,7 @@ DWARFUnit::FindRnglistFromOffset(dw_offset_t offset) { return llvm::createStringError(errc::invalid_argument, "missing or invalid range list table"); - llvm::DWARFDataExtractor data = - m_dwarf.GetDWARFContext().getOrLoadRngListsData().GetAsLLVM(); + llvm::DWARFDataExtractor data = GetRnglistData().GetAsLLVM(); // As DW_AT_rnglists_base may be missing we need to call setAddressSize. data.setAddressSize(m_header.GetAddressByteSize()); diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.h b/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.h index 79059b67ba88c..cb7018144bacc 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.h +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.h @@ -286,6 +286,8 @@ class DWARFUnit : public lldb_private::UserID { const llvm::Optional &GetRnglistTable(); + lldb_private::DWARFDataExtractor GetRnglistData() const; + SymbolFileDWARF &m_dwarf; std::shared_ptr m_dwo; DWARFUnitHeader m_header; diff --git a/lldb/test/Shell/SymbolFile/DWARF/x86/debug_rnglists-dwp.s b/lldb/test/Shell/SymbolFile/DWARF/x86/debug_rnglists-dwp.s new file mode 100644 index 0..227ca9e49adc9 --- /dev/null +++ b/lldb/test/Shell/SymbolFile/DWARF/x86/debug_rnglists-dwp.s @@ -0,0 +1,187 @@ +## This tests if .debug_rnglists.dwo are correctly read if they are part +## of a dwp file. + +# RUN: llvm-mc -triple=x86_64-pc-linux -filetype=obj %s --defsym MAIN=0 > %t +# RUN: llvm-mc -triple=x86_64-pc-linux -filetype=obj %s > %t.dwp +# RUN: %lldb %t -o "image lookup -v -s lookup_rnglists" -o exit | FileCheck %s + +# CHECK-LABEL: image lookup -v -s lookup_rnglists +# CHECK: Function: id = {{.*}}, name = "rnglists", range = [0x-0x0003) +# CHECK:Blocks: id = {{.*}}, range = [0x-0x0003) +# CHECK-NEXT: id = {{.*}}, range = [0x0001-0x0002) + +.text +rnglists: +nop +.L