Index: lldb/trunk/lit/Breakpoint/Inputs/split-dwarf5-debug-stroffsets-file1.dwo.yaml =================================================================== --- lldb/trunk/lit/Breakpoint/Inputs/split-dwarf5-debug-stroffsets-file1.dwo.yaml +++ lldb/trunk/lit/Breakpoint/Inputs/split-dwarf5-debug-stroffsets-file1.dwo.yaml @@ -0,0 +1,40 @@ +--- !ELF +FileHeader: + Class: ELFCLASS64 + Data: ELFDATA2LSB + Type: ET_REL + Machine: EM_X86_64 +Sections: + - Name: .debug_loc.dwo + Type: SHT_PROGBITS + Flags: [ SHF_EXCLUDE ] + AddressAlign: 0x0000000000000001 + Content: '' + - Name: .debug_str_offsets.dwo + Type: SHT_PROGBITS + Flags: [ SHF_EXCLUDE ] + AddressAlign: 0x0000000000000001 + Content: 5C00000005000000000000000A0000002D000000370000004000000050000000520000005A000000600000006200000066000000760000007F000000840000008A0000008F0000009400000096000000990000009C000000A5000000B5000000 + - Name: .debug_str.dwo + Type: SHT_PROGBITS + Flags: [ SHF_EXCLUDE, SHF_MERGE, SHF_STRINGS ] + AddressAlign: 0x0000000000000001 + Content: 66696C65312E64776F00636C616E672076657273696F6E20382E302E3020287472756E6B20333437323939290066696C65312E637070007E73747275637431005F5A4E37737472756374313166457600660073747275637431005F5A316776006700696E74005F5A4E377374727563743144324576005F5A347465737476007465737400666C6F6174006D61696E00746869730078007331007332007E73747275637432005F5A4E377374727563743231664576007374727563743200 + - Name: .debug_info.dwo + Type: SHT_PROGBITS + Flags: [ SHF_EXCLUDE ] + AddressAlign: 0x0000000000000001 + Content: D900000005000508000000008D03E0CB5B41F18901000104000202000B000000015607080103B400000003040601020104030202054000000000060405020300072A00000008013200000001565800000001070A30000000090291780FBC0000000A000B029174100108B400000000000C02060000000156010B3A00000002030900000001560B0C010DB80000000D046E00000001560E0111B40000000B0291781101152A0000000B029170120116C1000000000E0905040E0D0404072A0000000304150102060413020705D70000000006140502080007C100000000 + - Name: .debug_abbrev.dwo + Type: SHT_PROGBITS + Flags: [ SHF_EXCLUDE ] + AddressAlign: 0x0000000000000001 + Content: 011101B042252525130503250000022E00111B120640186E2503253A0B3B0B49133F190000031301360B03250B0B3A0B3B0B0000042E0103253A0B3B0B3C193F190000050500491334190000062E006E2503253A0B3B0B3C193F190000070F0049130000082E01111B1206401864133A0B3B0B6E2547130000090500021803254913341900000A0B01552300000B3400021803253A0B3B0B491300000C2E00111B120640183A0B3B0B471300000D2E01111B1206401803253A0B3B0B49133F1900000E240003253E0B0B0B000000 + - Name: .debug_rnglists.dwo + Type: SHT_PROGBITS + Flags: [ SHF_EXCLUDE ] + AddressAlign: 0x0000000000000001 + Content: 150000000500080001000000040000000101040C1F04253200 +Symbols: {} +DynamicSymbols: {} +... Index: lldb/trunk/lit/Breakpoint/Inputs/split-dwarf5-debug-stroffsets-file2.dwo.yaml =================================================================== --- lldb/trunk/lit/Breakpoint/Inputs/split-dwarf5-debug-stroffsets-file2.dwo.yaml +++ lldb/trunk/lit/Breakpoint/Inputs/split-dwarf5-debug-stroffsets-file2.dwo.yaml @@ -0,0 +1,40 @@ +--- !ELF +FileHeader: + Class: ELFCLASS64 + Data: ELFDATA2LSB + Type: ET_REL + Machine: EM_X86_64 +Sections: + - Name: .debug_loc.dwo + Type: SHT_PROGBITS + Flags: [ SHF_EXCLUDE ] + AddressAlign: 0x0000000000000001 + Content: '' + - Name: .debug_str_offsets.dwo + Type: SHT_PROGBITS + Flags: [ SHF_EXCLUDE ] + AddressAlign: 0x0000000000000001 + Content: 3000000005000000000000000A0000002D000000370000004000000050000000520000005A0000006A0000006F00000071000000 + - Name: .debug_str.dwo + Type: SHT_PROGBITS + Flags: [ SHF_EXCLUDE, SHF_MERGE, SHF_STRINGS ] + AddressAlign: 0x0000000000000001 + Content: 66696C65322E64776F00636C616E672076657273696F6E20382E302E3020287472756E6B20333437323939290066696C65322E637070007E73747275637432005F5A4E37737472756374323166457600660073747275637432005F5A4E3773747275637432443245760074686973007800696E7400 + - Name: .debug_info.dwo + Type: SHT_PROGBITS + Flags: [ SHF_EXCLUDE ] + AddressAlign: 0x0000000000000001 + Content: 740000000500050800000000B90811685AA26A1801000104000202040601020603030207043000000000050405020800061A0000000700320000000156480000000103072000000008029178086E00000009000A0291740901047300000000000B0106000000015601072A000000061A0000000C0A050400 + - Name: .debug_abbrev.dwo + Type: SHT_PROGBITS + Flags: [ SHF_EXCLUDE ] + AddressAlign: 0x0000000000000001 + Content: 011101B042252525130503250000021301360B03250B0B3A0B3B0B0000032E0103253A0B3B0B3C193F190000040500491334190000052E006E2503253A0B3B0B3C193F190000060F0049130000072E01111B1206401864133A0B3B0B6E254713000008050002180325491334190000090B01552300000A3400021803253A0B3B0B491300000B2E00111B120640183A0B3B0B471300000C240003253E0B0B0B000000 + - Name: .debug_rnglists.dwo + Type: SHT_PROGBITS + Flags: [ SHF_EXCLUDE ] + AddressAlign: 0x0000000000000001 + Content: 150000000500080001000000040000000100040C1F04253200 +Symbols: {} +DynamicSymbols: {} +... Index: lldb/trunk/lit/Breakpoint/Inputs/split-dwarf5-debug-stroffsets-main.yaml =================================================================== --- lldb/trunk/lit/Breakpoint/Inputs/split-dwarf5-debug-stroffsets-main.yaml +++ lldb/trunk/lit/Breakpoint/Inputs/split-dwarf5-debug-stroffsets-main.yaml @@ -0,0 +1,70 @@ +--- !ELF +FileHeader: + Class: ELFCLASS64 + Data: ELFDATA2LSB + Type: ET_EXEC + Machine: EM_X86_64 + Entry: 0x0000000000400630 +Sections: + - Name: .text + Type: SHT_PROGBITS + Flags: [ SHF_ALLOC, SHF_EXECINSTR ] + Address: 0x0000000000400630 + AddressAlign: 0x0000000000000010 + Content: 31ED4989D15E4889E24883E4F0505449C7C0C008400048C7C15008400048C7C790074000E877FFFFFFF4660F1F44000055B840204000483D402040004889E57417B8000000004885C0740D5DBF40204000FFE00F1F4400005DC3660F1F440000BE40204000554881EE402040004889E548C1FE034889F048C1E83F4801C648D1FE7415B8000000004885C0740B5DBF40204000FFE00F1F005DC3660F1F440000803D69190000007517554889E5E87EFFFFFFC60557190000015DC30F1F440000F3C30F1F4000662E0F1F840000000000554889E55DEB89900F1F840000000000554889E5B8010000005DC30F1F440000554889E54883EC2048897DF8E8DFFFFFFF8945F0E9000000008B45F08945F44883C4205DC389D14889C7894DECE80E00000066666666662E0F1F84000000000050E88AFEFFFF48890424E891FEFFFF90554889E55DC3662E0F1F840000000000554889E50F57C05DC30F1F8000000000554889E54883EC20C745FC00000000E8CCFFFFFFE897000000E8D2FFFFFFF30F1145E0E900000000C745FC00000000488D7DF0E838000000488D7DF8E84FFFFFFF8B45FC4883C4205DC389D1488945E8894DE4488D7DF0E814000000488D7DF8E82BFFFFFF488B7DE8E812FEFFFF6690554889E54883EC2048897DF8E8FFFEFFFF8945F0E9000000008B45F08945F44883C4205DC389D14889C7894DECE82EFFFFFF66666666662E0F1F840000000000554889E55DC3662E0F1F840000000000415741564189FF415541544C8D257615000055488D2D76150000534989F64989D54C29E54883EC0848C1FD03E81FFDFFFF4885ED742031DB0F1F8400000000004C89EA4C89F64489FF41FF14DC4883C3014839EB75EA4883C4085B5D415C415D415E415FC390662E0F1F840000000000F3C3 + - Name: .eh_frame_hdr + Type: SHT_PROGBITS + Flags: [ SHF_ALLOC ] + Address: 0x0000000000400B1C + AddressAlign: 0x0000000000000004 + Content: 011B033BE8FDFFFF0C000000A4FAFFFF04FFFFFF14FBFFFF44FFFFFFF4FBFFFF04FEFFFF04FCFFFF7CFFFFFF44FCFFFF24FEFFFF54FCFFFF3CFEFFFF64FCFFFF5CFEFFFF74FCFFFFA4FFFFFFE4FCFFFFD4FFFFFF24FDFFFF7CFEFFFF34FDFFFFA4FEFFFFA4FDFFFFECFEFFFF + - Name: .debug_str_offsets + Type: SHT_PROGBITS + AddressAlign: 0x0000000000000001 + Content: 0C00000005000000000000000A0000000C000000050000008F0000000A000000 + - Name: .debug_str + Type: SHT_PROGBITS + Flags: [ SHF_MERGE, SHF_STRINGS ] + AddressAlign: 0x0000000000000001 + Content: 66696C65312E64776F000000000000000000000000000000000000000000000000000000000000000000000000000067005F5A3167760073747275637431007E73747275637431005F5A4E3773747275637431443245760066005F5A4E3773747275637431316645760074657374005F5A347465737476006D61696E00696E7400666C6F617400737472756374320066696C65322E64776F007E73747275637432005F5A4E377374727563743244324576005F5A4E37737472756374323166457600 + - Name: .debug_abbrev + Type: SHT_PROGBITS + AddressAlign: 0x0000000000000001 + Content: 01110010177217B042251B25B44219731711015523741700000001110010177217B042251B25B442197317110155237417000000 + - Name: .debug_info + Type: SHT_PROGBITS + AddressAlign: 0x0000000000000001 + Content: 2C00000005000408000000008D03E0CB5B41F1890100000000080000000001080000000000000000000000000C0000002C000000050004081A000000B90811685AA26A1801F4000000180000000001380000000000000000000000002C000000 + - Name: .debug_rnglists + Type: SHT_PROGBITS + AddressAlign: 0x0000000000000001 + Content: 1C00000005000800010000000400000003000B03013203020603030903046E001300000005000800010000000400000003003203010600 + - Name: .debug_macinfo + Type: SHT_PROGBITS + AddressAlign: 0x0000000000000001 + Content: '0000' + - Name: .debug_addr + Type: SHT_PROGBITS + AddressAlign: 0x0000000000000001 + Content: 2C0000000500080010074000000000002007400000000000700740000000000080074000000000009007400000000000140000000500080000084000000000004008400000000000 + - Name: .debug_names + Type: SHT_PROGBITS + AddressAlign: 0x0000000000000004 + Content: 84010000050000000100000000000000000000000D0000000D00000013000000080000004C4C564D3037303000000000000000000000000001000000050000000600000007000000000000000800000000000000000000000B0000000C0000000D0000006CDCF90ECAA55B7A6A7F9A7C1B1710AF1C1710AF0BB602000CB602003080880B88F31A59AB8B407A65689E7C798A6A6F9BE1710F3100000048000000780000003700000087000000580000002F0000007D0000006F0000005A0000006A0000003F000000810000000000000009000000120000001B000000240000002D000000360000003F00000048000000510000005A000000630000006C0000002E2E03130000242403130000131303130000002E1A000000000000002E45000000000000002E8E00000000000000132A0000000000000013C1000000000000002E70000000000000002E1A0000000000000024B4000000000000002E7E000000000000002E70000000000000002E7E000000000000002E450000000000000024B800000000000000D800000005000000010000000000000000000000060000000600000013000000080000004C4C564D30373030300000000100000002000000030000000500000006000000000000007A8A6A6F4BBE6D7A3080880B1C1710AF0BB602002CA4527A99000000A20000007D0000008700000058000000B20000000000000009000000120000001B000000240000002D0000002E2E03130000242403130000131303130000002E35000000000000002E3500000000000000247300000000000000131A000000000000002E60000000000000002E6000000000000000000000 + - Name: .debug_gnu_pubnames + Type: SHT_PROGBITS + AddressAlign: 0x0000000000000001 + Content: 50000000020000000000300000007000000030737472756374313A3A66007E0000003074657374008E000000306D61696E001A0000003067004500000030737472756374313A3A7E73747275637431000000000035000000020030000000300000003500000030737472756374323A3A7E73747275637432006000000030737472756374323A3A660000000000 + - Name: .debug_gnu_pubtypes + Type: SHT_PROGBITS + AddressAlign: 0x0000000000000001 + Content: 3C000000020000000000300000002A000000107374727563743100B800000090666C6F617400C1000000107374727563743200B400000090696E74000000000024000000020030000000300000001A0000001073747275637432007300000090696E740000000000 + - Name: .debug_line + Type: SHT_PROGBITS + AddressAlign: 0x0000000000000001 + Content: F00000000500080065000000010101FB0E0D00010101010000000100000101011F02000000002500000003011F020F051E0327000000004195A4D2AC12B4F174DBFAD42A0CB9B227000000004195A4D2AC12B4F174DBFAD42A0CB9B2310000000193DBF7D5AE9184526D2D968251B49D0200090210074000000000001405030A4B0207000101000902200740000000000018050B0ABB060378C80507440501063D050B65020D0001010009027007400000000000030A0105140A4A02020001010009028007400000000000030C0105020A4B0205000101000902900740000000000003100105030AE5595DE6050175023F000101A30000000500080065000000010101FB0E0D00010101010000000100000101011F02000000002500000003011F020F051E03390000000040CCBAC21BCB1E430C6A1484F8570F05390000000040CCBAC21BCB1E430C6A1484F8570F05310000000193DBF7D5AE9184526D2D968251B49D02000902000840000000000014050B0ABB06C40507400501063D050B65020D00010100090240084000000000001805140A4A0202000101 + - Name: .debug_line_str + Type: SHT_PROGBITS + Flags: [ SHF_MERGE, SHF_STRINGS ] + AddressAlign: 0x0000000000000001 + Content: 000000000000000000000000000000000000000000000000000000000000000000000000002E0066696C65312E637070006465636C732E680066696C65322E63707000 Index: lldb/trunk/lit/Breakpoint/split-dwarf5-debug-stroffsets.test =================================================================== --- lldb/trunk/lit/Breakpoint/split-dwarf5-debug-stroffsets.test +++ lldb/trunk/lit/Breakpoint/split-dwarf5-debug-stroffsets.test @@ -0,0 +1,84 @@ +# RUN: rm -rf %t.dir +# RUN: mkdir %t.dir +# RUN: cd %t.dir +# RUN: yaml2obj %p/Inputs/split-dwarf5-debug-stroffsets-file1.dwo.yaml > %t.dir/file1.dwo +# RUN: yaml2obj %p/Inputs/split-dwarf5-debug-stroffsets-file2.dwo.yaml > %t.dir/file2.dwo +# RUN: yaml2obj %p/Inputs/split-dwarf5-debug-stroffsets-main.yaml > %t.dir/test +# RUN: lldb-test breakpoints %t.dir/test %s | FileCheck %s + +# This test checks that source code location is shown correctly +# when split DWARF 5 is used and both DWO/executable file contains +# .debug_str_offsets/.debug_str_offsets.dwo sections. +# Used clang version 8.0.0 (trunk 347299) +# +# split-dwarf5-debug-stroffsets-file1.dwo.yaml, split-dwarf5-debug-stroffsets-file2.dwo.yaml +# and split-dwarf5-debug-stroffsets-main.yaml are reduced yaml files produces +# from the DWO files and the corresponding executable. +# +# Code: +# // decl.h +# struct struct1 { +# ~struct1(); +# static void f(); +# }; +# +# struct struct2 { +# ~struct2(); +# static void f(); +# }; +# +# int g(); +# +# // file1.cpp +# #include "decls.h" +# +# int g() { +# return 1; +# } +# +# struct1::~struct1() { +# int x = g(); +# } +# +# void struct1::f() {} +# +# float test() { +# return 0.0f; +# } +# +# int main() { +# struct1::f(); +# struct2::f(); +# +# struct1 s1; +# struct2 s2; +# +# test(); +# +# return 0; +# } +# +# // file2.cpp +# +# +# #include "decls.h" +# +# struct2::~struct2() { +# int x = g(); +# } +# +# void struct2::f() {} +# +# +# Invocation used was: +# clang++ file1.cpp -o file1.o -g -fno-rtti -c -gdwarf-5 -gsplit-dwarf -ffunction-sections +# clang++ file2.cpp -o file2.o -g -fno-rtti -c -gdwarf-5 -gsplit-dwarf -ffunction-sections +# clang++ file1.o file2.o -g -fno-rtti -gdwarf-5 -o test -gsplit-dwarf -ffunction-sections + +b struct1::f +# CHECK-LABEL: b struct1::f +# CHECK: Address: {{.*}}struct1::f() + 4 at file1.cpp:11:20 + +b struct2::f +# CHECK-LABEL: b struct2::f +# CHECK: Address: {{.*}}struct2::f() + 4 at file2.cpp:7:20 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 @@ -569,22 +569,9 @@ 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; + lldb::offset_t offset = + m_cu->GetStrOffsetsBase() + 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); 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 @@ -111,9 +111,11 @@ dw_addr_t GetBaseAddress() const { return m_base_addr; } dw_addr_t GetAddrBase() const { return m_addr_base; } dw_addr_t GetRangesBase() const { return m_ranges_base; } + dw_addr_t GetStrOffsetsBase() const { return m_str_offsets_base; } void SetAddrBase(dw_addr_t addr_base); void SetRangesBase(dw_addr_t ranges_base); void SetBaseObjOffset(dw_offset_t base_obj_offset); + void SetStrOffsetsBase(dw_offset_t str_offsets_base); void BuildAddressRangeTable(SymbolFileDWARF *dwarf, DWARFDebugAranges *debug_aranges); @@ -217,7 +219,7 @@ // If this is a dwo compile unit this is the offset of the base compile unit // in the main object file dw_offset_t m_base_obj_offset = DW_INVALID_OFFSET; - + dw_offset_t m_str_offsets_base = 0; // Value of DW_AT_str_offsets_base. // Offset of the initial length field. dw_offset_t m_offset; Index: lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp =================================================================== --- lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp +++ lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp @@ -305,6 +305,31 @@ } } +// This is used when a split dwarf is enabled. +// A skeleton compilation unit may contain the DW_AT_str_offsets_base attribute +// that points to the first string offset of the CU contribution to the +// .debug_str_offsets. At the same time, the corresponding split debug unit also +// may use DW_FORM_strx* forms pointing to its own .debug_str_offsets.dwo and +// for that case, we should find the offset (skip the section header). +static void SetDwoStrOffsetsBase(DWARFUnit *dwo_cu) { + lldb::offset_t baseOffset = 0; + + const DWARFDataExtractor &strOffsets = + dwo_cu->GetSymbolFileDWARF()->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; + + // Skip padding. + baseOffset += 2; + + dwo_cu->SetStrOffsetsBase(baseOffset); +} + // m_die_array_mutex must be already held as read/write. void DWARFUnit::AddUnitDIE(const DWARFDebugInfoEntry &cu_die) { dw_addr_t addr_base = cu_die.GetAttributeValueAsUnsigned( @@ -312,8 +337,13 @@ if (addr_base != LLDB_INVALID_ADDRESS) SetAddrBase(addr_base); - SetRangesBase(cu_die.GetAttributeValueAsUnsigned(m_dwarf, this, - DW_AT_rnglists_base, 0)); + dw_addr_t ranges_base = cu_die.GetAttributeValueAsUnsigned( + m_dwarf, this, DW_AT_rnglists_base, LLDB_INVALID_ADDRESS); + if (ranges_base != LLDB_INVALID_ADDRESS) + SetRangesBase(ranges_base); + + SetStrOffsetsBase(cu_die.GetAttributeValueAsUnsigned( + m_dwarf, this, DW_AT_str_offsets_base, 0)); uint64_t base_addr = cu_die.GetAttributeValueAsAddress( m_dwarf, this, DW_AT_low_pc, LLDB_INVALID_ADDRESS); @@ -356,11 +386,14 @@ DW_AT_GNU_addr_base, 0); dwo_cu->SetAddrBase(addr_base); - dw_addr_t ranges_base = cu_die.GetAttributeValueAsUnsigned( - m_dwarf, this, DW_AT_GNU_ranges_base, 0); + if (ranges_base == LLDB_INVALID_ADDRESS) + ranges_base = cu_die.GetAttributeValueAsUnsigned(m_dwarf, this, + DW_AT_GNU_ranges_base, 0); dwo_cu->SetRangesBase(ranges_base); dwo_cu->SetBaseObjOffset(m_offset); + + SetDwoStrOffsetsBase(dwo_cu); } DWARFDIE DWARFUnit::LookupAddress(const dw_addr_t address) { @@ -428,6 +461,10 @@ m_base_obj_offset = base_obj_offset; } +void DWARFUnit::SetStrOffsetsBase(dw_offset_t str_offsets_base) { + m_str_offsets_base = str_offsets_base; +} + // It may be called only with m_die_array_mutex held R/W. void DWARFUnit::ClearDIEsRWLocked() { m_die_array.clear();