diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h --- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h +++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h @@ -482,6 +482,9 @@ const lldb_private::FileSpecList &GetTypeUnitSupportFiles(DWARFTypeUnit &tu); + void + InitializeFirstCodeAddress(const lldb_private::SectionList §ion_list); + lldb::ModuleWP m_debug_map_module_wp; SymbolFileDWARFDebugMap *m_debug_map_symfile; @@ -517,6 +520,19 @@ llvm::DenseMap m_type_unit_support_files; std::vector m_lldb_cu_to_dwarf_unit; + /// Many linkers will concatenate all available DWARF, even if parts of that + /// DWARF should have been dead stripped. Some linkers will place tombstone + /// values in for addresses that should have been dead stripped, with a value + /// like -1 or -2. But many linkers will apply a relocation and attempt to set + /// the value to zero. This is problematic in that we can end up with many + /// addresses that are zero or close to zero due to there being an addend on + /// the relocation whose base is at zero. Here we attempt to avoid addresses + /// that are zero or close to zero by finding the first valid code address by + /// looking at the sections and finding the first one that has read + execute + /// permissions. This allows us to do a quick and cheap comparison against + /// this address when parsing line tables and parsing functions where the + /// DWARF should have been dead stripped. + lldb::addr_t m_first_code_address = LLDB_INVALID_ADDRESS; }; #endif // LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_SYMBOLFILEDWARF_H diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp --- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp @@ -498,6 +498,26 @@ m_index = std::make_unique(*GetObjectFile()->GetModule(), *this); + + const SectionList *section_list = m_objfile_sp->GetModule()->GetSectionList(); + if (section_list) { + InitializeFirstCodeAddress(*section_list); + } +} + +void SymbolFileDWARF::InitializeFirstCodeAddress( + const lldb_private::SectionList §ion_list) { + const uint32_t num_sections = section_list.GetSize(); + for (uint32_t i = 0; i < num_sections; ++i) { + SectionSP section_sp(section_list.GetSectionAtIndex(i)); + if (section_sp->GetChildren().GetSize() > 0) { + InitializeFirstCodeAddress(section_sp->GetChildren()); + } else if (section_sp->GetType() == eSectionTypeCode) { + const addr_t section_file_address = section_sp->GetFileAddress(); + if (m_first_code_address > section_file_address) + m_first_code_address = section_file_address; + } + } } bool SymbolFileDWARF::SupportedVersion(uint16_t version) { @@ -1041,6 +1061,12 @@ // 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 sequence = LineTable::CreateLineSequenceContainer(); for (unsigned idx = seq.FirstRowIndex; idx < seq.LastRowIndex; ++idx) { diff --git a/lldb/test/Shell/SymbolFile/DWARF/line-entries-invalid-addresses.yaml b/lldb/test/Shell/SymbolFile/DWARF/line-entries-invalid-addresses.yaml new file mode 100644 --- /dev/null +++ b/lldb/test/Shell/SymbolFile/DWARF/line-entries-invalid-addresses.yaml @@ -0,0 +1,420 @@ +# RUN: yaml2obj %s > %t +# RUN: %lldb %t -b -o "image lookup -f main.cpp -l 2 -v" | FileCheck %s +# CHECK: LineEntry: {{.*}}main.cpp:2:{{.*}} + +# int foo() { +# return 42; +# } +# +# int main() { +# int x = foo(); +# return x; +# } +# dwarfdump -debug-line: +# Address Line Column File ISA Discriminator Flags +# ------------------ ------ ------ ------ --- ------------- ------------- +# 0x0000000100000f80 1 0 1 0 0 is_stmt +# 0x0000000100000f84 2 5 1 0 0 is_stmt prologue_end +# 0x0000000100000f8b 2 5 1 0 0 is_stmt end_sequence +# 0x0000000100000f90 5 0 1 0 0 is_stmt +# 0x0000000100000f90 5 0 1 0 0 is_stmt end_sequence +# 0x000000000000000f 2 13 1 0 0 is_stmt prologue_end +# 0x0000000000000014 2 9 1 0 0 +# 0x0000000000000017 3 12 1 0 0 is_stmt +# 0x000000000000001d 3 12 1 0 0 end_sequence +--- !mach-o +FileHeader: + magic: 0xFEEDFACF + cputype: 0x01000007 + cpusubtype: 0x00000003 + filetype: 0x0000000A + ncmds: 7 + sizeofcmds: 1400 + flags: 0x00000000 + reserved: 0x00000000 +LoadCommands: + - cmd: LC_UUID + cmdsize: 24 + uuid: 605D6BBF-4DB2-39F7-8068-F9BB3896DF0C + - cmd: LC_BUILD_VERSION + cmdsize: 24 + platform: 1 + minos: 659200 + sdk: 659206 + ntools: 0 + - cmd: LC_SYMTAB + cmdsize: 24 + symoff: 4096 + nsyms: 3 + stroff: 4144 + strsize: 37 + - cmd: LC_SEGMENT_64 + cmdsize: 72 + segname: __PAGEZERO + vmaddr: 0 + vmsize: 1 + fileoff: 0 + filesize: 0 + maxprot: 0 + initprot: 0 + nsects: 0 + flags: 0 + - cmd: LC_SEGMENT_64 + cmdsize: 232 + segname: __TEXT + vmaddr: 4294967296 + vmsize: 4096 + fileoff: 0 + filesize: 0 + maxprot: 5 + initprot: 5 + nsects: 2 + flags: 0 + Sections: + - sectname: __text + segname: __TEXT + addr: 0x0000000100000F80 + size: 48 + offset: 0x00000000 + align: 4 + reloff: 0x00000000 + nreloc: 0 + flags: 0x80000400 + reserved1: 0x00000000 + reserved2: 0x00000000 + reserved3: 0x00000000 + content: CFFAEDFE07000001030000000A000000070000007805000000000000000000001B00000018000000605D6BBF4DB239F7 + - sectname: __unwind_info + segname: __TEXT + addr: 0x0000000100000FB0 + size: 72 + offset: 0x00000000 + align: 2 + reloff: 0x00000000 + nreloc: 0 + flags: 0x00000000 + reserved1: 0x00000000 + reserved2: 0x00000000 + reserved3: 0x00000000 + content: CFFAEDFE07000001030000000A000000070000007805000000000000000000001B00000018000000605D6BBF4DB239F78068F9BB3896DF0C320000001800000001000000000F0A00 + - cmd: LC_SEGMENT_64 + cmdsize: 72 + segname: __LINKEDIT + vmaddr: 4294971392 + vmsize: 4096 + fileoff: 4096 + filesize: 85 + maxprot: 1 + initprot: 1 + nsects: 0 + flags: 0 + - cmd: LC_SEGMENT_64 + cmdsize: 952 + segname: __DWARF + vmaddr: 4294975488 + vmsize: 4096 + fileoff: 8192 + filesize: 839 + maxprot: 7 + initprot: 3 + nsects: 4 + flags: 0 + Sections: + - sectname: __debug_line + segname: __DWARF + addr: 0x0000000100002000 + size: 96 + offset: 0x00002000 + align: 0 + reloff: 0x00000000 + nreloc: 0 + flags: 0x00000000 + reserved1: 0x00000000 + reserved2: 0x00000000 + reserved3: 0x00000000 + - sectname: __debug_info + segname: __DWARF + addr: 0x00000001000020E9 + size: 119 + offset: 0x000020E9 + align: 0 + reloff: 0x00000000 + nreloc: 0 + flags: 0x00000000 + reserved1: 0x00000000 + reserved2: 0x00000000 + reserved3: 0x00000000 + - sectname: __debug_abbrev + segname: __DWARF + addr: 0x0000000100002160 + size: 90 + offset: 0x00002160 + align: 0 + reloff: 0x00000000 + nreloc: 0 + flags: 0x00000000 + reserved1: 0x00000000 + reserved2: 0x00000000 + reserved3: 0x00000000 + - sectname: __debug_str + segname: __DWARF + addr: 0x00000001000021BA + size: 130 + offset: 0x000021BA + align: 0 + reloff: 0x00000000 + nreloc: 0 + flags: 0x00000000 + reserved1: 0x00000000 + reserved2: 0x00000000 + reserved3: 0x00000000 +LinkEditData: + NameList: + - n_strx: 2 + n_type: 0x0F + n_sect: 1 + n_desc: 0 + n_value: 4294971264 + - n_strx: 11 + n_type: 0x0F + n_sect: 1 + n_desc: 16 + n_value: 4294967296 + - n_strx: 31 + n_type: 0x0F + n_sect: 1 + n_desc: 0 + n_value: 4294971280 + StringTable: + - '' + - '' + - __Z3foov + - __mh_execute_header + - _main +DWARF: + debug_str: + - '' + - 'Apple clang version 11.0.3 (clang-1103.0.32.62)' + - main.cpp + - '/Users/aadsm/toolchain_dev/external/llvm-project' + - _Z3foov + - foo + - main + - x + - int + debug_abbrev: + - ID: 0 + Table: + - Code: 0x0000000000000001 + Tag: DW_TAG_compile_unit + Children: DW_CHILDREN_yes + Attributes: + - Attribute: DW_AT_producer + Form: DW_FORM_strp + - Attribute: DW_AT_language + Form: DW_FORM_data2 + - Attribute: DW_AT_name + Form: DW_FORM_strp + - Attribute: DW_AT_stmt_list + Form: DW_FORM_sec_offset + - Attribute: DW_AT_comp_dir + Form: DW_FORM_strp + - Attribute: DW_AT_low_pc + Form: DW_FORM_addr + - Attribute: DW_AT_high_pc + Form: DW_FORM_data4 + - 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_frame_base + Form: DW_FORM_exprloc + - Attribute: DW_AT_linkage_name + Form: DW_FORM_strp + - Attribute: DW_AT_name + Form: DW_FORM_strp + - Attribute: DW_AT_decl_file + Form: DW_FORM_data1 + - Attribute: DW_AT_decl_line + Form: DW_FORM_data1 + - Attribute: DW_AT_type + Form: DW_FORM_ref_addr + - Attribute: DW_AT_external + Form: DW_FORM_flag_present + - Code: 0x0000000000000003 + Tag: DW_TAG_subprogram + Children: DW_CHILDREN_yes + Attributes: + - Attribute: DW_AT_low_pc + Form: DW_FORM_addr + - Attribute: DW_AT_high_pc + Form: DW_FORM_data4 + - Attribute: DW_AT_frame_base + Form: DW_FORM_exprloc + - Attribute: DW_AT_name + Form: DW_FORM_strp + - Attribute: DW_AT_decl_file + Form: DW_FORM_data1 + - Attribute: DW_AT_decl_line + Form: DW_FORM_data1 + - Attribute: DW_AT_type + Form: DW_FORM_ref_addr + - Attribute: DW_AT_external + Form: DW_FORM_flag_present + - Code: 0x0000000000000004 + Tag: DW_TAG_variable + Children: DW_CHILDREN_no + Attributes: + - Attribute: DW_AT_location + Form: DW_FORM_exprloc + - Attribute: DW_AT_name + Form: DW_FORM_strp + - Attribute: DW_AT_decl_file + Form: DW_FORM_data1 + - Attribute: DW_AT_decl_line + Form: DW_FORM_data1 + - Attribute: DW_AT_type + Form: DW_FORM_ref_addr + - Code: 0x0000000000000005 + Tag: DW_TAG_base_type + Children: DW_CHILDREN_no + Attributes: + - Attribute: DW_AT_name + Form: DW_FORM_strp + - Attribute: DW_AT_encoding + Form: DW_FORM_data1 + - Attribute: DW_AT_byte_size + Form: DW_FORM_data1 + debug_info: + - Length: 0x0000000000000073 + Version: 4 + AbbrevTableID: 0 + AbbrOffset: 0x0000000000000000 + AddrSize: 8 + Entries: + - AbbrCode: 0x00000001 + Values: + - Value: 0x0000000000000001 + - Value: 0x0000000000000004 + - Value: 0x0000000000000031 + - Value: 0x0000000000000000 + - Value: 0x000000000000003A + - Value: 0x0000000100000F80 + - Value: 0x0000000000000030 + - AbbrCode: 0x00000002 + Values: + - Value: 0x0000000100000F80 + - Value: 0x000000000000000B + - Value: 0x0000000000000001 + BlockData: [ 0x56 ] + - Value: 0x000000000000006B + - Value: 0x0000000000000073 + - Value: 0x0000000000000001 + - Value: 0x0000000000000001 + - Value: 0x000000000000006F + - Value: 0x0000000000000001 + - AbbrCode: 0x00000003 + Values: + - Value: 0x0000000100000F90 + - Value: 0x0000000000000020 + - Value: 0x0000000000000001 + BlockData: [ 0x56 ] + - Value: 0x0000000000000077 + - Value: 0x0000000000000001 + - Value: 0x0000000000000005 + - Value: 0x000000000000006F + - Value: 0x0000000000000001 + - AbbrCode: 0x00000004 + Values: + - Value: 0x0000000000000002 + BlockData: [ 0x91, 0x78 ] + - Value: 0x000000000000007C + - Value: 0x0000000000000001 + - Value: 0x0000000000000006 + - Value: 0x000000000000006F + - AbbrCode: 0x00000000 + - AbbrCode: 0x00000005 + Values: + - Value: 0x000000000000007E + - Value: 0x0000000000000005 + - Value: 0x0000000000000004 + - AbbrCode: 0x00000000 + debug_line: + - Length: 92 + Version: 4 + PrologueLength: 32 + 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: main.cpp + DirIdx: 0 + ModTime: 0 + Length: 0 + Opcodes: + - Opcode: DW_LNS_extended_op + ExtLen: 9 + SubOpcode: DW_LNE_set_address + Data: 4294971264 + - Opcode: DW_LNS_copy + Data: 0 + - Opcode: DW_LNS_set_column + Data: 5 + - Opcode: DW_LNS_set_prologue_end + Data: 0 + - Opcode: 0x4B + Data: 0 + - Opcode: DW_LNS_advance_pc + Data: 7 + - Opcode: DW_LNS_extended_op + ExtLen: 1 + SubOpcode: DW_LNE_end_sequence + Data: 0 + # Sequence manually added (not produced by the source code) + - Opcode: DW_LNS_extended_op + ExtLen: 9 + SubOpcode: DW_LNE_set_address + Data: 4294971280 + - Opcode: 0x16 + Data: 0 + - Opcode: DW_LNS_extended_op + ExtLen: 1 + SubOpcode: DW_LNE_end_sequence + Data: 0 + # Sequence manually added (not produced by the source code) + - Opcode: DW_LNS_set_column + Data: 13 + - Opcode: DW_LNS_set_prologue_end + Data: 0 + - Opcode: 0xE5 + Data: 0 + - Opcode: DW_LNS_set_column + Data: 9 + - Opcode: DW_LNS_negate_stmt + Data: 0 + - Opcode: 0x58 + Data: 0 + - Opcode: DW_LNS_set_column + Data: 12 + - Opcode: DW_LNS_negate_stmt + Data: 0 + - Opcode: 0x3D + Data: 0 + - Opcode: DW_LNS_negate_stmt + Data: 0 + - Opcode: DW_LNS_advance_pc + Data: 6 + - Opcode: DW_LNS_extended_op + ExtLen: 1 + SubOpcode: DW_LNE_end_sequence + Data: 0 +...