Index: lldb/trunk/include/lldb/lldb-enumerations.h =================================================================== --- lldb/trunk/include/lldb/lldb-enumerations.h +++ lldb/trunk/include/lldb/lldb-enumerations.h @@ -57,7 +57,7 @@ eStateSuspended, ///< Process or thread is in a suspended state as far ///< as the debugger is concerned while other processes ///< or threads get the chance to run. - kLastStateType = eStateSuspended + kLastStateType = eStateSuspended }; //---------------------------------------------------------------------- @@ -672,7 +672,8 @@ eSectionTypeDWARFGNUDebugAltLink, eSectionTypeDWARFDebugTypes, // DWARF .debug_types section eSectionTypeDWARFDebugNames, // DWARF v5 .debug_names - eSectionTypeOther + eSectionTypeOther, + eSectionTypeDWARFDebugLineStr, // DWARF v5 .debug_line_str }; FLAGS_ENUM(EmulateInstructionOptions){ Index: lldb/trunk/packages/Python/lldbsuite/test/functionalities/show_location/TestShowLocationDwarf5.py =================================================================== --- lldb/trunk/packages/Python/lldbsuite/test/functionalities/show_location/TestShowLocationDwarf5.py +++ lldb/trunk/packages/Python/lldbsuite/test/functionalities/show_location/TestShowLocationDwarf5.py @@ -0,0 +1,34 @@ +import lldb +from lldbsuite.test.lldbtest import * +from lldbsuite.test.decorators import * + +# This test checks that source code location is shown correctly +# when DWARF5 debug information is used. + +class TestTargetSourceMap(TestBase): + + mydir = TestBase.compute_mydir(__file__) + + def test_source_map(self): + # Set the target soure map to map "./" to the current test directory. + yaml_path = os.path.join(self.getSourceDir(), "a.yaml") + yaml_base, ext = os.path.splitext(yaml_path) + obj_path = self.getBuildArtifact(yaml_base) + self.yaml2obj(yaml_path, obj_path) + + def cleanup(): + if os.path.exists(obj_path): + os.unlink(obj_path) + + # Execute the cleanup function during test case tear down. + self.addTearDownHook(cleanup) + + # Create a target with the object file we just created from YAML + target = self.dbg.CreateTarget(obj_path) + + # Check we are able to show the locations properly. + self.expect("b main", VALID_BREAKPOINT_LOCATION, + substrs=['main + 13 at test.cpp:2:3, address = 0x000000000040052d']) + + self.expect("b foo", VALID_BREAKPOINT_LOCATION, + substrs=['foo() + 4 at test.cpp:6:1, address = 0x0000000000400534']) Index: lldb/trunk/packages/Python/lldbsuite/test/functionalities/show_location/a.yaml =================================================================== --- lldb/trunk/packages/Python/lldbsuite/test/functionalities/show_location/a.yaml +++ lldb/trunk/packages/Python/lldbsuite/test/functionalities/show_location/a.yaml @@ -0,0 +1,58 @@ +# This file is a shorten version of the output +# produced with the following invocations and input: +# ./clang test.cpp -g -gdwarf-5 -o test.exe +# ./obj2yaml test.exe > test.yaml +# +# // test.cpp +# int main() { +# return 0; +# } +# +# void foo() { +# } + +--- !ELF +FileHeader: + Class: ELFCLASS64 + Data: ELFDATA2LSB + Type: ET_EXEC + Machine: EM_X86_64 + Entry: 0x0000000000400440 +Sections: + - Name: .text + Type: SHT_PROGBITS + Flags: [ SHF_ALLOC, SHF_EXECINSTR ] + Address: 0x0000000000400440 + AddressAlign: 0x0000000000000010 + Content: 31ED4989D15E4889E24883E4F0505449C7C0B005400048C7C14005400048C7C720054000E8B7FFFFFFF4660F1F44000055B820204000483D202040004889E57417B8000000004885C0740D5DBF20204000FFE00F1F4400005DC3660F1F440000BE20204000554881EE202040004889E548C1FE034889F048C1E83F4801C648D1FE7415B8000000004885C0740B5DBF20204000FFE00F1F005DC3660F1F440000803D391B0000007517554889E5E87EFFFFFFC605271B0000015DC30F1F440000F3C30F1F4000662E0F1F840000000000554889E55DEB89660F1F840000000000554889E531C0C745FC000000005DC390554889E55DC3662E0F1F840000000000415741564189FF415541544C8D25B618000055488D2DB6180000534989F64989D54C29E54883EC0848C1FD03E87FFEFFFF4885ED742031DB0F1F8400000000004C89EA4C89F64489FF41FF14DC4883C3014839EB75EA4883C4085B5D415C415D415E415FC390662E0F1F840000000000F3C3 + - Name: .debug_str_offsets + Type: SHT_PROGBITS + AddressAlign: 0x0000000000000001 + Content: 200000000500000000000000230000002C0000004A0000004F000000530000005B000000 + - Name: .debug_str + Type: SHT_PROGBITS + Flags: [ SHF_MERGE, SHF_STRINGS ] + AddressAlign: 0x0000000000000001 + Content: 636C616E672076657273696F6E20382E302E3020287472756E6B203334313935382900746573742E637070002F686F6D652F756D622F4C4C564D2F6275696C645F6C6C64622F62696E006D61696E00696E74005F5A33666F6F7600666F6F00 + - Name: .debug_abbrev + Type: SHT_PROGBITS + AddressAlign: 0x0000000000000001 + Content: 011101252513050325721710171B25110112060000022E0011011206401803253A0B3B0B49133F190000032E001101120640186E2503253A0B3B0B3F19000004240003253E0B0B0B000000 + - Name: .debug_info + Type: SHT_PROGBITS + AddressAlign: 0x0000000000000001 + Content: 50000000050001080000000001000400010800000000000000022005400000000000160000000220054000000000000F00000001560301014F000000033005400000000000060000000156050601050404050400 + - Name: .debug_macinfo + Type: SHT_PROGBITS + AddressAlign: 0x0000000000000001 + Content: '00' + - Name: .debug_line + Type: SHT_PROGBITS + AddressAlign: 0x0000000000000001 + Content: 70000000050008004C000000010101FB0E0D00010101010000000100000101011F010000000003011F020F051E021E00000000FD7C0F2E46BA561F7BDA351B04E677091E00000000FD7C0F2E46BA561F7BDA351B04E6770900090220054000000000000105030AC905003F05010A4B0202000101 + - Name: .debug_line_str + Type: SHT_PROGBITS + Flags: [ SHF_MERGE, SHF_STRINGS ] + AddressAlign: 0x0000000000000001 + Content: 2F686F6D652F756D622F4C4C564D2F6275696C645F6C6C64622F62696E00746573742E63707000 +... Index: lldb/trunk/source/Core/Section.cpp =================================================================== --- lldb/trunk/source/Core/Section.cpp +++ lldb/trunk/source/Core/Section.cpp @@ -73,6 +73,8 @@ return "dwarf-info"; case eSectionTypeDWARFDebugLine: return "dwarf-line"; + case eSectionTypeDWARFDebugLineStr: + return "dwarf-line-str"; case eSectionTypeDWARFDebugLoc: return "dwarf-loc"; case eSectionTypeDWARFDebugMacInfo: Index: lldb/trunk/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp =================================================================== --- lldb/trunk/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp +++ lldb/trunk/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp @@ -1788,6 +1788,7 @@ static ConstString g_sect_name_dwarf_debug_frame(".debug_frame"); static ConstString g_sect_name_dwarf_debug_info(".debug_info"); static ConstString g_sect_name_dwarf_debug_line(".debug_line"); + static ConstString g_sect_name_dwarf_debug_line_str(".debug_line_str"); static ConstString g_sect_name_dwarf_debug_loc(".debug_loc"); static ConstString g_sect_name_dwarf_debug_macinfo(".debug_macinfo"); static ConstString g_sect_name_dwarf_debug_macro(".debug_macro"); @@ -1802,6 +1803,7 @@ ".debug_abbrev.dwo"); static ConstString g_sect_name_dwarf_debug_info_dwo(".debug_info.dwo"); static ConstString g_sect_name_dwarf_debug_line_dwo(".debug_line.dwo"); + static ConstString g_sect_name_dwarf_debug_line_str_dwo(".debug_line_str.dwo"); static ConstString g_sect_name_dwarf_debug_macro_dwo(".debug_macro.dwo"); static ConstString g_sect_name_dwarf_debug_loc_dwo(".debug_loc.dwo"); static ConstString g_sect_name_dwarf_debug_str_dwo(".debug_str.dwo"); @@ -1861,6 +1863,8 @@ sect_type = eSectionTypeDWARFDebugInfo; else if (name == g_sect_name_dwarf_debug_line) sect_type = eSectionTypeDWARFDebugLine; + else if (name == g_sect_name_dwarf_debug_line_str) + sect_type = eSectionTypeDWARFDebugLineStr; else if (name == g_sect_name_dwarf_debug_loc) sect_type = eSectionTypeDWARFDebugLoc; else if (name == g_sect_name_dwarf_debug_macinfo) @@ -1887,6 +1891,8 @@ sect_type = eSectionTypeDWARFDebugInfo; else if (name == g_sect_name_dwarf_debug_line_dwo) sect_type = eSectionTypeDWARFDebugLine; + else if (name == g_sect_name_dwarf_debug_line_str_dwo) + sect_type = eSectionTypeDWARFDebugLineStr; else if (name == g_sect_name_dwarf_debug_macro_dwo) sect_type = eSectionTypeDWARFDebugMacro; else if (name == g_sect_name_dwarf_debug_loc_dwo) Index: lldb/trunk/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp =================================================================== --- lldb/trunk/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp +++ lldb/trunk/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp @@ -1197,6 +1197,7 @@ case eSectionTypeDWARFDebugFrame: case eSectionTypeDWARFDebugInfo: case eSectionTypeDWARFDebugLine: + case eSectionTypeDWARFDebugLineStr: case eSectionTypeDWARFDebugLoc: case eSectionTypeDWARFDebugMacInfo: case eSectionTypeDWARFDebugMacro: Index: lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.h =================================================================== --- lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.h +++ lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.h @@ -35,9 +35,7 @@ /// @return /// Byte size of the compile unit header //------------------------------------------------------------------ - uint32_t GetHeaderByteSize() const override { - return m_is_dwarf64 ? 23 : 11; - } + uint32_t GetHeaderByteSize() const override; private: DWARFCompileUnit(SymbolFileDWARF *dwarf2Data); Index: lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp =================================================================== --- lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp +++ lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp @@ -34,8 +34,18 @@ cu_sp->m_length = debug_info.GetDWARFInitialLength(offset_ptr); cu_sp->m_is_dwarf64 = debug_info.IsDWARF64(); cu_sp->m_version = debug_info.GetU16(offset_ptr); - abbr_offset = debug_info.GetDWARFOffset(offset_ptr); - cu_sp->m_addr_size = debug_info.GetU8(offset_ptr); + + if (cu_sp->m_version == 5) { + cu_sp->m_unit_type = debug_info.GetU8(offset_ptr); + cu_sp->m_addr_size = debug_info.GetU8(offset_ptr); + abbr_offset = debug_info.GetDWARFOffset(offset_ptr); + + if (cu_sp->m_unit_type == llvm::dwarf::DW_UT_skeleton) + cu_sp->m_dwo_id = debug_info.GetU64(offset_ptr); + } else { + abbr_offset = debug_info.GetDWARFOffset(offset_ptr); + cu_sp->m_addr_size = debug_info.GetU8(offset_ptr); + } bool length_OK = debug_info.ValidOffset(cu_sp->GetNextCompileUnitOffset() - 1); @@ -65,6 +75,23 @@ GetNextCompileUnitOffset()); } +uint32_t DWARFCompileUnit::GetHeaderByteSize() const { + if (m_version < 5) + return m_is_dwarf64 ? 23 : 11; + + switch (m_unit_type) { + case llvm::dwarf::DW_UT_compile: + case llvm::dwarf::DW_UT_partial: + return 12; + case llvm::dwarf::DW_UT_skeleton: + case llvm::dwarf::DW_UT_split_compile: + return 20; + case llvm::dwarf::DW_UT_type: + case llvm::dwarf::DW_UT_split_type: + return 24; + } + llvm_unreachable("invalid UnitType."); +} const lldb_private::DWARFDataExtractor &DWARFCompileUnit::GetData() const { return m_dwarf->get_debug_info_data(); Index: lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp =================================================================== --- lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp +++ lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp @@ -122,18 +122,25 @@ case DW_FORM_data1: case DW_FORM_flag: case DW_FORM_ref1: + case DW_FORM_strx1: form_size = 1; break; // 2 byte values case DW_FORM_data2: case DW_FORM_ref2: + case DW_FORM_strx2: form_size = 2; break; + case DW_FORM_strx3: + form_size = 3; + break; + // 4 byte values case DW_FORM_data4: case DW_FORM_ref4: + case DW_FORM_strx4: form_size = 4; break; @@ -150,6 +157,7 @@ case DW_FORM_ref_udata: case DW_FORM_GNU_addr_index: case DW_FORM_GNU_str_index: + case DW_FORM_strx: debug_info_data.Skip_LEB128(&offset); break; Index: lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDebugLine.h =================================================================== --- lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDebugLine.h +++ lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDebugLine.h @@ -19,6 +19,9 @@ #include "DWARFDataExtractor.h" #include "DWARFDefines.h" +#include "llvm/Support/MD5.h" + +class DWARFUnit; class SymbolFileDWARF; //---------------------------------------------------------------------- @@ -36,6 +39,7 @@ dw_sleb128_t dir_idx; dw_sleb128_t mod_time; dw_sleb128_t length; + llvm::MD5::MD5Result checksum; }; //------------------------------------------------------------------ @@ -55,6 +59,10 @@ // total_length field itself). uint16_t version; // Version identifier for the statement information format. + + uint8_t address_size; + uint8_t segment_selector_size; + uint32_t prologue_length; // The number of bytes following the // prologue_length field to the beginning of the // first byte of the statement program itself. @@ -201,14 +209,15 @@ const lldb_private::DWARFDataExtractor &debug_line_data, const lldb_private::FileSpec &cu_comp_dir, dw_offset_t stmt_list, - lldb_private::FileSpecList &support_files); + lldb_private::FileSpecList &support_files, DWARFUnit *dwarf_cu); static bool ParsePrologue(const lldb_private::DWARFDataExtractor &debug_line_data, - lldb::offset_t *offset_ptr, Prologue *prologue); + lldb::offset_t *offset_ptr, Prologue *prologue, + DWARFUnit *dwarf_cu = nullptr); static bool ParseStatementTable(const lldb_private::DWARFDataExtractor &debug_line_data, lldb::offset_t *offset_ptr, State::Callback callback, - void *userData); + void *userData, DWARFUnit *dwarf_cu); static dw_offset_t DumpStatementTable(lldb_private::Log *log, const lldb_private::DWARFDataExtractor &debug_line_data, @@ -219,7 +228,8 @@ const dw_offset_t line_offset, uint32_t flags); static bool ParseStatementTable(const lldb_private::DWARFDataExtractor &debug_line_data, - lldb::offset_t *offset_ptr, LineTable *line_table); + lldb::offset_t *offset_ptr, LineTable *line_table, + DWARFUnit *dwarf_cu); static void Parse(const lldb_private::DWARFDataExtractor &debug_line_data, DWARFDebugLine::State::Callback callback, void *userData); // static void AppendLineTableData(const DWARFDebugLine::Prologue* prologue, Index: lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDebugLine.cpp =================================================================== --- lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDebugLine.cpp +++ lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDebugLine.cpp @@ -41,7 +41,7 @@ if (line_table_sp.get() == NULL) break; - if (ParseStatementTable(debug_line_data, &offset, line_table_sp.get())) { + if (ParseStatementTable(debug_line_data, &offset, line_table_sp.get(), nullptr)) { // Make sure we don't don't loop infinitely if (offset <= debug_line_offset) break; @@ -127,7 +127,7 @@ "--------\n", debug_line_offset); - if (ParseStatementTable(debug_line_data, &offset, DumpStateToFile, log)) + if (ParseStatementTable(debug_line_data, &offset, DumpStateToFile, log, nullptr)) return offset; else return debug_line_offset + 1; // Skip to next byte in .debug_line section @@ -366,17 +366,38 @@ void *userData) { lldb::offset_t offset = 0; if (debug_line_data.ValidOffset(offset)) { - if (!ParseStatementTable(debug_line_data, &offset, callback, userData)) + if (!ParseStatementTable(debug_line_data, &offset, callback, userData, nullptr)) ++offset; // Skip to next byte in .debug_line section } } +namespace { +struct EntryDescriptor { + dw_sleb128_t code; + dw_sleb128_t form; +}; + +static std::vector +ReadDescriptors(const DWARFDataExtractor &debug_line_data, + lldb::offset_t *offset_ptr) { + std::vector ret; + uint8_t n = debug_line_data.GetU8(offset_ptr); + for (uint8_t i = 0; i < n; ++i) { + EntryDescriptor ent; + ent.code = debug_line_data.GetULEB128(offset_ptr); + ent.form = debug_line_data.GetULEB128(offset_ptr); + ret.push_back(ent); + } + return ret; +} +} // namespace + //---------------------------------------------------------------------- // DWARFDebugLine::ParsePrologue //---------------------------------------------------------------------- bool DWARFDebugLine::ParsePrologue(const DWARFDataExtractor &debug_line_data, lldb::offset_t *offset_ptr, - Prologue *prologue) { + Prologue *prologue, DWARFUnit *dwarf_cu) { const lldb::offset_t prologue_offset = *offset_ptr; // DEBUG_PRINTF("0x%8.8x: ParsePrologue()\n", *offset_ptr); @@ -386,9 +407,14 @@ const char *s; prologue->total_length = debug_line_data.GetDWARFInitialLength(offset_ptr); prologue->version = debug_line_data.GetU16(offset_ptr); - if (prologue->version < 2 || prologue->version > 4) + if (prologue->version < 2 || prologue->version > 5) return false; + if (prologue->version >= 5) { + prologue->address_size = debug_line_data.GetU8(offset_ptr); + prologue->segment_selector_size = debug_line_data.GetU8(offset_ptr); + } + prologue->prologue_length = debug_line_data.GetDWARFOffset(offset_ptr); const lldb::offset_t end_prologue_offset = prologue->prologue_length + *offset_ptr; @@ -410,25 +436,83 @@ prologue->standard_opcode_lengths.push_back(op_len); } - while (*offset_ptr < end_prologue_offset) { - s = debug_line_data.GetCStr(offset_ptr); - if (s && s[0]) - prologue->include_directories.push_back(s); - else - break; - } + if (prologue->version >= 5) { + std::vector dirEntryFormatV = + ReadDescriptors(debug_line_data, offset_ptr); + uint8_t dirCount = debug_line_data.GetULEB128(offset_ptr); + for (int i = 0; i < dirCount; ++i) { + for (EntryDescriptor &ent : dirEntryFormatV) { + DWARFFormValue value(dwarf_cu, ent.form); + if (ent.code != DW_LNCT_path) { + if (!value.SkipValue(debug_line_data, offset_ptr)) + return false; + continue; + } - while (*offset_ptr < end_prologue_offset) { - const char *name = debug_line_data.GetCStr(offset_ptr); - if (name && name[0]) { - FileNameEntry fileEntry; - fileEntry.name = name; - fileEntry.dir_idx = debug_line_data.GetULEB128(offset_ptr); - fileEntry.mod_time = debug_line_data.GetULEB128(offset_ptr); - fileEntry.length = debug_line_data.GetULEB128(offset_ptr); - prologue->file_names.push_back(fileEntry); - } else - break; + if (!value.ExtractValue(debug_line_data, offset_ptr)) + return false; + prologue->include_directories.push_back(value.AsCString()); + } + } + + std::vector filesEntryFormatV = + ReadDescriptors(debug_line_data, offset_ptr); + llvm::DenseSet> seen; + uint8_t n = debug_line_data.GetULEB128(offset_ptr); + for (int i = 0; i < n; ++i) { + FileNameEntry entry; + for (EntryDescriptor &ent : filesEntryFormatV) { + DWARFFormValue value(dwarf_cu, ent.form); + if (!value.ExtractValue(debug_line_data, offset_ptr)) + return false; + + switch (ent.code) { + case DW_LNCT_path: + entry.name = value.AsCString(); + break; + case DW_LNCT_directory_index: + entry.dir_idx = value.Unsigned(); + break; + case DW_LNCT_timestamp: + entry.mod_time = value.Unsigned(); + break; + case DW_LNCT_size: + entry.length = value.Unsigned(); + break; + case DW_LNCT_MD5: + assert(value.Unsigned() == 16); + std::uninitialized_copy_n(value.BlockData(), 16, + entry.checksum.Bytes.begin()); + break; + default: + break; + } + } + + if (seen.insert(entry.checksum.words()).second) + prologue->file_names.push_back(entry); + } + } else { + while (*offset_ptr < end_prologue_offset) { + s = debug_line_data.GetCStr(offset_ptr); + if (s && s[0]) + prologue->include_directories.push_back(s); + else + break; + } + + while (*offset_ptr < end_prologue_offset) { + const char *name = debug_line_data.GetCStr(offset_ptr); + if (name && name[0]) { + FileNameEntry fileEntry; + fileEntry.name = name; + fileEntry.dir_idx = debug_line_data.GetULEB128(offset_ptr); + fileEntry.mod_time = debug_line_data.GetULEB128(offset_ptr); + fileEntry.length = debug_line_data.GetULEB128(offset_ptr); + prologue->file_names.push_back(fileEntry); + } else + break; + } } // XXX GNU as is broken for 64-Bit DWARF @@ -445,11 +529,11 @@ bool DWARFDebugLine::ParseSupportFiles( const lldb::ModuleSP &module_sp, const DWARFDataExtractor &debug_line_data, const lldb_private::FileSpec &cu_comp_dir, dw_offset_t stmt_list, - FileSpecList &support_files) { + FileSpecList &support_files, DWARFUnit *dwarf_cu) { lldb::offset_t offset = stmt_list; Prologue prologue; - if (!ParsePrologue(debug_line_data, &offset, &prologue)) { + if (!ParsePrologue(debug_line_data, &offset, &prologue, dwarf_cu)) { Host::SystemLog(Host::eSystemLogError, "error: parsing line table prologue " "at 0x%8.8x (parsing ended around " "0x%8.8" PRIx64 "\n", @@ -478,7 +562,7 @@ //---------------------------------------------------------------------- bool DWARFDebugLine::ParseStatementTable( const DWARFDataExtractor &debug_line_data, lldb::offset_t *offset_ptr, - DWARFDebugLine::State::Callback callback, void *userData) { + DWARFDebugLine::State::Callback callback, void *userData, DWARFUnit *dwarf_cu) { Log *log(LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_LINE)); Prologue::shared_ptr prologue(new Prologue()); @@ -489,7 +573,7 @@ func_cat, "DWARFDebugLine::ParseStatementTable (.debug_line[0x%8.8x])", debug_line_offset); - if (!ParsePrologue(debug_line_data, offset_ptr, prologue.get())) { + if (!ParsePrologue(debug_line_data, offset_ptr, prologue.get(), dwarf_cu)) { if (log) log->Error("failed to parse DWARF line table prologue"); // Restore our offset and return false to indicate failure! @@ -775,9 +859,9 @@ //---------------------------------------------------------------------- bool DWARFDebugLine::ParseStatementTable( const DWARFDataExtractor &debug_line_data, lldb::offset_t *offset_ptr, - LineTable *line_table) { + LineTable *line_table, DWARFUnit *dwarf_cu) { return ParseStatementTable(debug_line_data, offset_ptr, - ParseStatementTableCallback, line_table); + ParseStatementTableCallback, line_table, dwarf_cu); } inline bool DWARFDebugLine::Prologue::IsValid() const { Index: lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFFormValue.h =================================================================== --- lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFFormValue.h +++ lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFFormValue.h @@ -14,6 +14,7 @@ #include // for NULL class DWARFUnit; +class SymbolFileDWARF; class DWARFFormValue { public: Index: lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp =================================================================== --- lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp +++ lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp @@ -196,6 +196,10 @@ case DW_FORM_data8: m_value.value.uval = data.GetU64(offset_ptr); break; + case DW_FORM_data16: + m_value.value.uval = 16; + is_block = true; + break; case DW_FORM_string: m_value.value.cstr = data.GetCStr(offset_ptr); break; @@ -218,10 +222,26 @@ m_value.value.sval = data.GetSLEB128(offset_ptr); break; case DW_FORM_strp: + case DW_FORM_line_strp: assert(m_cu); m_value.value.uval = data.GetMaxU64(offset_ptr, DWARFUnit::IsDWARF64(m_cu) ? 8 : 4); break; + case DW_FORM_strx: + m_value.value.uval = data.GetULEB128(offset_ptr); + break; + case DW_FORM_strx1: + m_value.value.uval = data.GetU8(offset_ptr); + break; + case DW_FORM_strx2: + m_value.value.uval = data.GetU16(offset_ptr); + break; + case DW_FORM_strx3: + m_value.value.uval = data.GetMaxU64(offset_ptr, 3); + break; + case DW_FORM_strx4: + m_value.value.uval = data.GetU32(offset_ptr); + break; // case DW_FORM_APPLE_db_str: case DW_FORM_udata: m_value.value.uval = data.GetULEB128(offset_ptr); @@ -348,47 +368,56 @@ case DW_FORM_flag_present: return true; - // 1 byte values - case DW_FORM_data1: - case DW_FORM_flag: - case DW_FORM_ref1: - *offset_ptr += 1; - return true; + // 1 byte values + case DW_FORM_data1: + case DW_FORM_flag: + case DW_FORM_ref1: + case DW_FORM_strx1: + *offset_ptr += 1; + return true; - // 2 byte values - case DW_FORM_data2: - case DW_FORM_ref2: - *offset_ptr += 2; - return true; + // 2 byte values + case DW_FORM_data2: + case DW_FORM_ref2: + case DW_FORM_strx2: + *offset_ptr += 2; + return true; - // 32 bit for DWARF 32, 64 for DWARF 64 - case DW_FORM_sec_offset: - case DW_FORM_strp: - assert(cu); - *offset_ptr += (cu->IsDWARF64() ? 8 : 4); - return true; + // 3 byte values + case DW_FORM_strx3: + *offset_ptr += 3; + return true; - // 4 byte values - case DW_FORM_data4: - case DW_FORM_ref4: - *offset_ptr += 4; - return true; + // 32 bit for DWARF 32, 64 for DWARF 64 + case DW_FORM_sec_offset: + case DW_FORM_strp: + assert(cu); + *offset_ptr += (cu->IsDWARF64() ? 8 : 4); + return true; - // 8 byte values - case DW_FORM_data8: - case DW_FORM_ref8: - case DW_FORM_ref_sig8: - *offset_ptr += 8; - return true; + // 4 byte values + case DW_FORM_data4: + case DW_FORM_ref4: + case DW_FORM_strx4: + *offset_ptr += 4; + return true; - // signed or unsigned LEB 128 values - case DW_FORM_sdata: - case DW_FORM_udata: - case DW_FORM_ref_udata: - case DW_FORM_GNU_addr_index: - case DW_FORM_GNU_str_index: - debug_info_data.Skip_LEB128(offset_ptr); - return true; + // 8 byte values + case DW_FORM_data8: + case DW_FORM_ref8: + case DW_FORM_ref_sig8: + *offset_ptr += 8; + return true; + + // signed or unsigned LEB 128 values + case DW_FORM_sdata: + case DW_FORM_udata: + case DW_FORM_ref_udata: + case DW_FORM_GNU_addr_index: + case DW_FORM_GNU_str_index: + case DW_FORM_strx: + debug_info_data.Skip_LEB128(offset_ptr); + return true; case DW_FORM_indirect: { dw_form_t indirect_form = debug_info_data.GetULEB128(offset_ptr); @@ -546,6 +575,39 @@ index_size); return symbol_file->get_debug_str_data().PeekCStr(str_offset); } + + if (m_form == DW_FORM_strx || m_form == DW_FORM_strx1 || + m_form == DW_FORM_strx2 || m_form == DW_FORM_strx3 || + m_form == DW_FORM_strx4) { + + // The same code as above. + if (!symbol_file) + return nullptr; + + lldb::offset_t baseOffset = 0; + const DWARFDataExtractor &strOffsets = + symbol_file->get_debug_str_offsets_data(); + uint64_t length = strOffsets.GetU32(&baseOffset); + if (length == 0xffffffff) + length = strOffsets.GetU64(&baseOffset); + + // Check version. + if (strOffsets.GetU16(&baseOffset) < 5) + return nullptr; + + // Skip padding. + baseOffset += 2; + + uint32_t indexSize = m_cu->IsDWARF64() ? 8 : 4; + lldb::offset_t offset = baseOffset + m_value.value.uval * indexSize; + dw_offset_t strOffset = + symbol_file->get_debug_str_offsets_data().GetMaxU64(&offset, indexSize); + return symbol_file->get_debug_str_data().PeekCStr(strOffset); + } + + if (m_form == DW_FORM_line_strp) + return symbol_file->get_debug_line_str_data().PeekCStr(m_value.value.uval); + return nullptr; } @@ -741,6 +803,11 @@ case DW_FORM_flag: case DW_FORM_sdata: case DW_FORM_strp: + case DW_FORM_strx: + case DW_FORM_strx1: + case DW_FORM_strx2: + case DW_FORM_strx3: + case DW_FORM_strx4: case DW_FORM_udata: case DW_FORM_ref_addr: case DW_FORM_ref1: Index: lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFUnit.h =================================================================== --- lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFUnit.h +++ lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFUnit.h @@ -202,6 +202,8 @@ dw_offset_t m_length = 0; uint16_t m_version = 0; uint8_t m_addr_size = 0; + uint8_t m_unit_type = 0; + uint64_t m_dwo_id = 0; DWARFProducer m_producer = eProducerInvalid; uint32_t m_producer_version_major = 0; uint32_t m_producer_version_minor = 0; Index: lldb/trunk/source/Plugins/SymbolFile/DWARF/DebugNamesDWARFIndex.cpp =================================================================== --- lldb/trunk/source/Plugins/SymbolFile/DWARF/DebugNamesDWARFIndex.cpp +++ lldb/trunk/source/Plugins/SymbolFile/DWARF/DebugNamesDWARFIndex.cpp @@ -225,7 +225,8 @@ const CompilerDeclContext &parent_decl_ctx, uint32_t name_type_mask, std::vector &dies) { - m_fallback.GetFunctions(name, info, parent_decl_ctx, name_type_mask, dies); + std::vector v; + m_fallback.GetFunctions(name, info, parent_decl_ctx, name_type_mask, v); for (const DebugNames::Entry &entry : m_debug_names_up->equal_range(name.GetStringRef())) { @@ -235,8 +236,13 @@ if (DIERef ref = ToDIERef(entry)) ProcessFunctionDIE(name.GetStringRef(), ref, info, parent_decl_ctx, - name_type_mask, dies); + name_type_mask, v); } + + std::set seen; + for (DWARFDIE die : v) + if (seen.insert(die.GetDIE()).second) + dies.push_back(die); } void DebugNamesDWARFIndex::GetFunctions(const RegularExpression ®ex, Index: lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h =================================================================== --- lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h +++ lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h @@ -240,6 +240,7 @@ const lldb_private::DWARFDataExtractor &get_debug_frame_data(); const lldb_private::DWARFDataExtractor &get_debug_info_data(); const lldb_private::DWARFDataExtractor &get_debug_line_data(); + const lldb_private::DWARFDataExtractor &get_debug_line_str_data(); const lldb_private::DWARFDataExtractor &get_debug_macro_data(); const lldb_private::DWARFDataExtractor &get_debug_loc_data(); const lldb_private::DWARFDataExtractor &get_debug_ranges_data(); @@ -466,6 +467,7 @@ DWARFDataSegment m_data_debug_frame; DWARFDataSegment m_data_debug_info; DWARFDataSegment m_data_debug_line; + DWARFDataSegment m_data_debug_line_str; DWARFDataSegment m_data_debug_macro; DWARFDataSegment m_data_debug_loc; DWARFDataSegment m_data_debug_ranges; Index: lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp =================================================================== --- lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp +++ lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp @@ -494,7 +494,7 @@ } bool SymbolFileDWARF::SupportedVersion(uint16_t version) { - return version == 2 || version == 3 || version == 4; + return version >= 2 && version <= 5; } uint32_t SymbolFileDWARF::CalculateAbilities() { @@ -645,6 +645,10 @@ return GetCachedSectionData(eSectionTypeDWARFDebugLine, m_data_debug_line); } +const DWARFDataExtractor &SymbolFileDWARF::get_debug_line_str_data() { + return GetCachedSectionData(eSectionTypeDWARFDebugLineStr, m_data_debug_line_str); +} + const DWARFDataExtractor &SymbolFileDWARF::get_debug_macro_data() { return GetCachedSectionData(eSectionTypeDWARFDebugMacro, m_data_debug_macro); } @@ -933,7 +937,7 @@ support_files.Append(*sc.comp_unit); return DWARFDebugLine::ParseSupportFiles( sc.comp_unit->GetModule(), get_debug_line_data(), cu_comp_dir, - stmt_list, support_files); + stmt_list, support_files, dwarf_cu); } } } @@ -1070,7 +1074,7 @@ lldb::offset_t offset = cu_line_offset; DWARFDebugLine::ParseStatementTable(get_debug_line_data(), &offset, ParseDWARFLineTableCallback, - &info); + &info, dwarf_cu); SymbolFileDWARFDebugMap *debug_map_symfile = GetDebugMapSymfile(); if (debug_map_symfile) { // We have an object file that has a line table with addresses that Index: lldb/trunk/source/Symbol/ObjectFile.cpp =================================================================== --- lldb/trunk/source/Symbol/ObjectFile.cpp +++ lldb/trunk/source/Symbol/ObjectFile.cpp @@ -350,6 +350,7 @@ case eSectionTypeDWARFDebugFrame: case eSectionTypeDWARFDebugInfo: case eSectionTypeDWARFDebugLine: + case eSectionTypeDWARFDebugLineStr: case eSectionTypeDWARFDebugLoc: case eSectionTypeDWARFDebugMacInfo: case eSectionTypeDWARFDebugMacro: