[Lldb-commits] [lldb] ffbff6c - [lldb/DWARF] Ignore debug info pointing to the low addresses
Pavel Labath via lldb-commits
lldb-commits at lists.llvm.org
Wed Oct 20 02:19:44 PDT 2021
Author: Pavel Labath
Date: 2021-10-20T11:19:30+02:00
New Revision: ffbff6c511ba230954013eca8d824a66f6b4f9a5
URL: https://github.com/llvm/llvm-project/commit/ffbff6c511ba230954013eca8d824a66f6b4f9a5
DIFF: https://github.com/llvm/llvm-project/commit/ffbff6c511ba230954013eca8d824a66f6b4f9a5.diff
LOG: [lldb/DWARF] Ignore debug info pointing to the low addresses
specifically, ignore addresses that point before the first code section.
This resurrects D87172 with several notable changes:
- it fixes a bug where the early exits in InitializeObject left
m_first_code_address "initialized" to LLDB_INVALID_ADDRESS (0xfff..f),
which caused _everything_ to be ignored.
- it extends the line table fix to function parsing as well, where it
replaces a similar check which was checking the executable permissions
of the section. This was insufficient because some
position-independent elf executables can have an executable segment
mapped at file address zero. (What makes this fix different is that it
checks for the executable-ness of the sections contained within that
segment, and those will not be at address zero.)
- It uses a different test case, with an elf file with near-zero
addresses, and checks for both line table and function parsing.
Differential Revision: https://reviews.llvm.org/D112058
Added:
lldb/test/Shell/SymbolFile/DWARF/x86/dead-code-filtering.yaml
Modified:
lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h
lldb/test/Shell/SymbolFile/DWARF/lit.local.cfg
Removed:
################################################################################
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
index c396e591ddc4..9078fa3cdc26 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
+++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
@@ -468,6 +468,8 @@ SymbolFileDWARF::GetTypeSystemForLanguage(LanguageType language) {
void SymbolFileDWARF::InitializeObject() {
Log *log = LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_INFO);
+ InitializeFirstCodeAddress();
+
if (!GetGlobalPluginProperties().IgnoreFileIndexes()) {
StreamString module_desc;
GetObjectFile()->GetModule()->GetDescription(module_desc.AsRawOstream(),
@@ -512,6 +514,25 @@ void SymbolFileDWARF::InitializeObject() {
std::make_unique<ManualDWARFIndex>(*GetObjectFile()->GetModule(), *this);
}
+void SymbolFileDWARF::InitializeFirstCodeAddress() {
+ InitializeFirstCodeAddressRecursive(
+ *m_objfile_sp->GetModule()->GetSectionList());
+ if (m_first_code_address == LLDB_INVALID_ADDRESS)
+ m_first_code_address = 0;
+}
+
+void SymbolFileDWARF::InitializeFirstCodeAddressRecursive(
+ const lldb_private::SectionList §ion_list) {
+ for (SectionSP section_sp : section_list) {
+ if (section_sp->GetChildren().GetSize() > 0) {
+ InitializeFirstCodeAddressRecursive(section_sp->GetChildren());
+ } else if (section_sp->GetType() == eSectionTypeCode) {
+ m_first_code_address =
+ std::min(m_first_code_address, section_sp->GetFileAddress());
+ }
+ }
+}
+
bool SymbolFileDWARF::SupportedVersion(uint16_t version) {
return version >= 2 && version <= 5;
}
@@ -1111,6 +1132,12 @@ bool SymbolFileDWARF::ParseLineTable(CompileUnit &comp_unit) {
// The Sequences view contains only valid line sequences. Don't iterate over
// the Rows directly.
for (const llvm::DWARFDebugLine::Sequence &seq : line_table->Sequences) {
+ // Ignore line sequences that do not start after the first code address.
+ // All addresses generated in a sequence are incremental so we only need
+ // to check the first one of the sequence. Check the comment at the
+ // m_first_code_address declaration for more details on this.
+ if (seq.LowPC < m_first_code_address)
+ continue;
std::unique_ptr<LineSequence> sequence =
LineTable::CreateLineSequenceContainer();
for (unsigned idx = seq.FirstRowIndex; idx < seq.LastRowIndex; ++idx) {
@@ -2236,12 +2263,9 @@ bool SymbolFileDWARF::ResolveFunction(const DWARFDIE &orig_die,
addr = sc.function->GetAddressRange().GetBaseAddress();
}
-
- if (auto section_sp = addr.GetSection()) {
- if (section_sp->GetPermissions() & ePermissionsExecutable) {
- sc_list.Append(sc);
- return true;
- }
+ if (addr.IsValid() && addr.GetFileAddress() >= m_first_code_address) {
+ sc_list.Append(sc);
+ return true;
}
}
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h
index e02ae1347e84..6e58c8b6178e 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h
+++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h
@@ -494,6 +494,11 @@ class SymbolFileDWARF : public lldb_private::SymbolFile,
const lldb_private::FileSpecList &GetTypeUnitSupportFiles(DWARFTypeUnit &tu);
+ void InitializeFirstCodeAddressRecursive(
+ const lldb_private::SectionList §ion_list);
+
+ void InitializeFirstCodeAddress();
+
lldb::ModuleWP m_debug_map_module_wp;
SymbolFileDWARFDebugMap *m_debug_map_symfile;
@@ -529,6 +534,13 @@ class SymbolFileDWARF : public lldb_private::SymbolFile,
llvm::DenseMap<dw_offset_t, lldb_private::FileSpecList>
m_type_unit_support_files;
std::vector<uint32_t> m_lldb_cu_to_dwarf_unit;
+ /// DWARF does not provide a good way for traditional (concatenating) linkers
+ /// to invalidate debug info describing dead-stripped code. These linkers will
+ /// keep the debug info but resolve any addresses referring to such code as
+ /// zero (BFD) or a small positive integer (zero + relocation addend -- GOLD).
+ /// Try to filter out this debug info by comparing it to the lowest code
+ /// address in the module.
+ lldb::addr_t m_first_code_address = LLDB_INVALID_ADDRESS;
};
#endif // LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_SYMBOLFILEDWARF_H
diff --git a/lldb/test/Shell/SymbolFile/DWARF/lit.local.cfg b/lldb/test/Shell/SymbolFile/DWARF/lit.local.cfg
index cd335969a66e..b6bf55c31e61 100644
--- a/lldb/test/Shell/SymbolFile/DWARF/lit.local.cfg
+++ b/lldb/test/Shell/SymbolFile/DWARF/lit.local.cfg
@@ -1 +1 @@
-config.suffixes = ['.cpp', '.m', '.mm', '.s', '.test', '.ll', '.c']
+config.suffixes = ['.cpp', '.m', '.mm', '.s', '.test', '.ll', '.c', '.yaml']
diff --git a/lldb/test/Shell/SymbolFile/DWARF/x86/dead-code-filtering.yaml b/lldb/test/Shell/SymbolFile/DWARF/x86/dead-code-filtering.yaml
new file mode 100644
index 000000000000..cbdb91c4ef24
--- /dev/null
+++ b/lldb/test/Shell/SymbolFile/DWARF/x86/dead-code-filtering.yaml
@@ -0,0 +1,152 @@
+# RUN: yaml2obj %s > %t
+# RUN: %lldb %t -o "image dump line-table a.c" -o "image lookup -n _start" -o "image lookup -n f" -o exit | FileCheck %s
+
+# CHECK-LABEL: image dump line-table a.c
+# CHECK-NEXT: Line table for a.c
+# CHECK-NEXT: 0x0000000000000080: a.c:1
+# CHECK-NEXT: 0x0000000000000084: a.c:1
+# CHECK-NEXT: 0x0000000000000086: a.c:1
+# CHECK-EMPTY:
+# CHECK-NEXT: image lookup -n _start
+# CHECK-NEXT: 1 match found
+# CHECK-LABEL: image lookup -n f
+# CHECK-EMPTY:
+
+--- !ELF
+FileHeader:
+ Class: ELFCLASS64
+ Data: ELFDATA2LSB
+ Type: ET_EXEC
+ Machine: EM_X86_64
+ProgramHeaders:
+ - Type: PT_LOAD
+ Flags: [ PF_X, PF_R ]
+ Offset: 0x0000
+ FirstSec: .text
+ LastSec: .text
+ Align: 0x1000
+Sections:
+ - Name: .text
+ Type: SHT_PROGBITS
+ Flags: [ SHF_ALLOC, SHF_EXECINSTR ]
+ Address: 0x80
+ AddressAlign: 0x10
+ Content: 554889E55DC3
+ - Name: .debug_abbrev
+ Type: SHT_PROGBITS
+ AddressAlign: 0x1
+ - Name: .debug_info
+ Type: SHT_PROGBITS
+ AddressAlign: 0x1
+ - Name: .debug_line
+ Type: SHT_PROGBITS
+ AddressAlign: 0x1
+DWARF:
+ debug_ranges:
+ - Offset: 0x0
+ AddrSize: 0x8
+ Entries:
+ - LowOffset: 0x0
+ HighOffset: 0x6
+ - LowOffset: 0x80
+ HighOffset: 0x86
+ debug_abbrev:
+ - ID: 0
+ Table:
+ - Code: 0x0000000000000001
+ Tag: DW_TAG_compile_unit
+ Children: DW_CHILDREN_yes
+ Attributes:
+ - Attribute: DW_AT_producer
+ Form: DW_FORM_string
+ - Attribute: DW_AT_name
+ Form: DW_FORM_string
+ - Attribute: DW_AT_stmt_list
+ Form: DW_FORM_sec_offset
+ - Attribute: DW_AT_low_pc
+ Form: DW_FORM_addr
+ - Attribute: DW_AT_ranges
+ Form: DW_FORM_sec_offset
+ - Code: 0x0000000000000002
+ Tag: DW_TAG_subprogram
+ Children: DW_CHILDREN_no
+ Attributes:
+ - Attribute: DW_AT_low_pc
+ Form: DW_FORM_addr
+ - Attribute: DW_AT_high_pc
+ Form: DW_FORM_data4
+ - Attribute: DW_AT_name
+ Form: DW_FORM_string
+ debug_info:
+ - Version: 4
+ AbbrevTableID: 0
+ AbbrOffset: 0x0000000000000000
+ AddrSize: 8
+ Entries:
+ - AbbrCode: 0x00000001
+ Values:
+ - CStr: Hand-written DWARF
+ - CStr: a.c
+ - Value: 0x0000000000000000
+ - Value: 0x0000000000000000
+ - Value: 0x0000000000000000
+ - AbbrCode: 0x00000002
+ Values:
+ - Value: 0x0000000000000000
+ - Value: 0x0000000000000006
+ - CStr: f
+ - AbbrCode: 0x00000002
+ Values:
+ - Value: 0x0000000000000080
+ - Value: 0x0000000000000006
+ - CStr: _start
+ - AbbrCode: 0x00000000
+ debug_line:
+ - Version: 4
+ MinInstLength: 1
+ MaxOpsPerInst: 1
+ DefaultIsStmt: 1
+ LineBase: 251
+ LineRange: 14
+ OpcodeBase: 13
+ StandardOpcodeLengths: [ 0, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 1 ]
+ IncludeDirs: []
+ Files:
+ - Name: a.c
+ DirIdx: 0
+ ModTime: 0
+ Length: 0
+ Opcodes:
+ - Opcode: DW_LNS_extended_op
+ ExtLen: 9
+ SubOpcode: DW_LNE_set_address
+ Data: 0
+ - Opcode: DW_LNS_copy
+ Data: 0
+ - Opcode: DW_LNS_set_prologue_end
+ Data: 0
+ - Opcode: 0x4a
+ Data: 0
+ - Opcode: DW_LNS_advance_pc
+ Data: 2
+ - Opcode: DW_LNS_extended_op
+ ExtLen: 1
+ SubOpcode: DW_LNE_end_sequence
+ Data: 0
+ - Opcode: DW_LNS_extended_op
+ ExtLen: 9
+ SubOpcode: DW_LNE_set_address
+ Data: 0x000080
+ - Opcode: DW_LNS_copy
+ Data: 0
+ - Opcode: DW_LNS_set_prologue_end
+ Data: 0
+ - Opcode: 0x4a
+ Data: 0
+ - Opcode: DW_LNS_advance_pc
+ Data: 2
+ - Opcode: DW_LNS_extended_op
+ ExtLen: 1
+ SubOpcode: DW_LNE_end_sequence
+ Data: 0
+...
More information about the lldb-commits
mailing list