ikudrin updated this revision to Diff 249939.
ikudrin added a comment.
- Use values for clashing identifiers proposed by @dblaikie.
- Convert all unknown section identifiers into a special value,
`DW_SECT_EXT_unknown`; Use an optional parallel array to keep the raw values of
unknown identifiers.
- Split the refactoring part in `llvm-dwp.cpp` into a separate patch, D76067
<https://reviews.llvm.org/D76067>.
There are some other changes that can be split into separate patches. I will
make the series when the direction of this patch is approved in general.
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D75929/new/
https://reviews.llvm.org/D75929
Files:
lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.cpp
lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp
llvm/include/llvm/BinaryFormat/Dwarf.def
llvm/include/llvm/DebugInfo/DWARF/DWARFUnitIndex.h
llvm/lib/DebugInfo/DWARF/DWARFContext.cpp
llvm/lib/DebugInfo/DWARF/DWARFUnit.cpp
llvm/lib/DebugInfo/DWARF/DWARFUnitIndex.cpp
llvm/lib/DebugInfo/DWARF/DWARFVerifier.cpp
llvm/test/DebugInfo/X86/dwp-v2-cu-index.s
llvm/test/DebugInfo/X86/dwp-v2-loc.s
llvm/test/DebugInfo/X86/dwp-v2-tu-index.s
llvm/test/DebugInfo/X86/dwp-v5-cu-index.s
llvm/test/DebugInfo/X86/dwp-v5-loclists.s
llvm/test/DebugInfo/X86/dwp-v5-tu-index.s
llvm/test/tools/llvm-dwp/X86/unsupported_cu_index_version.s
llvm/tools/llvm-dwp/llvm-dwp.cpp
Index: llvm/tools/llvm-dwp/llvm-dwp.cpp
===================================================================
--- llvm/tools/llvm-dwp/llvm-dwp.cpp
+++ llvm/tools/llvm-dwp/llvm-dwp.cpp
@@ -214,11 +214,12 @@
StringRef DWPName;
};
-// Convert a section identifier into the index to use with
+// Convert an internal section identifier into the index to use with
// UnitIndexEntry::Contributions.
static unsigned SectionKindToIndex(DWARFSectionKind Kind) {
- assert(static_cast<unsigned>(Kind) >= 1);
- return static_cast<unsigned>(Kind) - 1;
+ // Assuming pre-standard DWP format.
+ assert(SerializeSectionKind(Kind, 2) >= 1);
+ return SerializeSectionKind(Kind, 2) - 1;
}
// Convert a UnitIndexEntry::Contributions index to the corresponding on-disk
@@ -250,12 +251,14 @@
// Zero out the debug_info contribution
Entry.Contributions[0] = {};
for (auto Kind : TUIndex.getColumnKinds()) {
+ if (Kind == DW_SECT_EXT_unknown)
+ continue;
auto &C = Entry.Contributions[SectionKindToIndex(Kind)];
C.Offset += I->Offset;
C.Length = I->Length;
++I;
}
- const unsigned TypesIndex = SectionKindToIndex(DW_SECT_TYPES);
+ const unsigned TypesIndex = SectionKindToIndex(DW_SECT_EXT_TYPES);
auto &C = Entry.Contributions[TypesIndex];
Out.emitBytes(Types.substr(
C.Offset - TUEntry.Contributions[TypesIndex].Offset, C.Length));
@@ -277,7 +280,7 @@
UnitIndexEntry Entry = CUEntry;
// Zero out the debug_info contribution
Entry.Contributions[0] = {};
- auto &C = Entry.Contributions[SectionKindToIndex(DW_SECT_TYPES)];
+ auto &C = Entry.Contributions[SectionKindToIndex(DW_SECT_EXT_TYPES)];
C.Offset = TypesOffset;
auto PrevOffset = Offset;
// Length of the unit, including the 4 byte length field.
@@ -448,7 +451,7 @@
if (DWARFSectionKind Kind = SectionPair->second.second) {
auto Index = SectionKindToIndex(Kind);
- if (Kind != DW_SECT_TYPES) {
+ if (Kind != DW_SECT_EXT_TYPES) {
CurEntry.Contributions[Index].Offset = ContributionOffsets[Index];
ContributionOffsets[Index] +=
(CurEntry.Contributions[Index].Length = Contents.size());
@@ -532,10 +535,10 @@
MCSection *const TUIndexSection = MCOFI.getDwarfTUIndexSection();
const StringMap<std::pair<MCSection *, DWARFSectionKind>> KnownSections = {
{"debug_info.dwo", {MCOFI.getDwarfInfoDWOSection(), DW_SECT_INFO}},
- {"debug_types.dwo", {MCOFI.getDwarfTypesDWOSection(), DW_SECT_TYPES}},
+ {"debug_types.dwo", {MCOFI.getDwarfTypesDWOSection(), DW_SECT_EXT_TYPES}},
{"debug_str_offsets.dwo", {StrOffsetSection, DW_SECT_STR_OFFSETS}},
{"debug_str.dwo", {StrSection, static_cast<DWARFSectionKind>(0)}},
- {"debug_loc.dwo", {MCOFI.getDwarfLocDWOSection(), DW_SECT_LOC}},
+ {"debug_loc.dwo", {MCOFI.getDwarfLocDWOSection(), DW_SECT_EXT_LOC}},
{"debug_line.dwo", {MCOFI.getDwarfLineDWOSection(), DW_SECT_LINE}},
{"debug_abbrev.dwo", {MCOFI.getDwarfAbbrevDWOSection(), DW_SECT_ABBREV}},
{"debug_cu_index", {CUIndexSection, static_cast<DWARFSectionKind>(0)}},
@@ -599,7 +602,7 @@
P.first->second.DWOName = ID.DWOName;
addAllTypes(Out, TypeIndexEntries, TypesSection, CurTypesSection,
CurEntry,
- ContributionOffsets[SectionKindToIndex(DW_SECT_TYPES)]);
+ ContributionOffsets[SectionKindToIndex(DW_SECT_EXT_TYPES)]);
continue;
}
@@ -607,6 +610,8 @@
DataExtractor CUIndexData(CurCUIndexSection, Obj.isLittleEndian(), 0);
if (!CUIndex.parse(CUIndexData))
return make_error<DWPError>("Failed to parse cu_index");
+ if (CUIndex.getVersion() != 2)
+ return make_error<DWPError>("Unsupported cu_index version");
for (const DWARFUnitIndex::Entry &E : CUIndex.getRows()) {
auto *I = E.getOffsets();
@@ -628,6 +633,8 @@
NewEntry.DWOName = ID.DWOName;
NewEntry.DWPName = Input;
for (auto Kind : CUIndex.getColumnKinds()) {
+ if (Kind == DW_SECT_EXT_unknown)
+ continue;
auto &C = NewEntry.Contributions[SectionKindToIndex(Kind)];
C.Offset += I->Offset;
C.Length = I->Length;
@@ -638,13 +645,15 @@
if (!CurTypesSection.empty()) {
if (CurTypesSection.size() != 1)
return make_error<DWPError>("multiple type unit sections in .dwp file");
- DWARFUnitIndex TUIndex(DW_SECT_TYPES);
+ DWARFUnitIndex TUIndex(DW_SECT_EXT_TYPES);
DataExtractor TUIndexData(CurTUIndexSection, Obj.isLittleEndian(), 0);
if (!TUIndex.parse(TUIndexData))
return make_error<DWPError>("Failed to parse tu_index");
+ if (TUIndex.getVersion() != 2)
+ return make_error<DWPError>("Unsupported tu_index version");
addAllTypesFromDWP(
Out, TypeIndexEntries, TUIndex, TypesSection, CurTypesSection.front(),
- CurEntry, ContributionOffsets[SectionKindToIndex(DW_SECT_TYPES)]);
+ CurEntry, ContributionOffsets[SectionKindToIndex(DW_SECT_EXT_TYPES)]);
}
}
@@ -655,7 +664,7 @@
TypeIndexEntries);
// Lie about the type contribution
- ContributionOffsets[SectionKindToIndex(DW_SECT_TYPES)] = 0;
+ ContributionOffsets[SectionKindToIndex(DW_SECT_EXT_TYPES)] = 0;
// Unlie about the info contribution
ContributionOffsets[0] = 1;
Index: llvm/test/tools/llvm-dwp/X86/unsupported_cu_index_version.s
===================================================================
--- /dev/null
+++ llvm/test/tools/llvm-dwp/X86/unsupported_cu_index_version.s
@@ -0,0 +1,50 @@
+# RUN: llvm-mc -triple x86_64-unknown-linux %s -filetype=obj -o %t.dwp
+# RUN: not llvm-dwp %t.dwp -o %t 2>&1 | FileCheck %s
+
+# CHECK: error: Unsupported cu_index version
+
+.section .debug_abbrev.dwo, "e", @progbits
+.LAbbrevBegin:
+ .uleb128 1 # Abbreviation Code
+ .uleb128 17 # DW_TAG_compile_unit
+ .byte 1 # DW_CHILDREN_no
+ .byte 0 # EOM(1)
+ .byte 0 # EOM(2)
+ .byte 0 # EOM(3)
+.LAbbrevEnd:
+
+ .section .debug_info.dwo, "e", @progbits
+.LCUBegin:
+ .long .LCUEnd-.LCUVersion # Length of Unit
+.LCUVersion:
+ .short 5 # Version
+ .byte 5 # DW_UT_split_compile
+ .byte 8 # Address size
+ .long 0 # Abbrev offset
+ .quad 0x1100001122222222 # DWO id
+ .uleb128 1 # Abbrev [1] DW_TAG_compile_unit
+.LCUEnd:
+
+ .section .debug_cu_index, "", @progbits
+## Header:
+ .short 5 # Version
+ .space 2 # Padding
+ .long 2 # Section count
+ .long 1 # Unit count
+ .long 2 # Slot count
+## Hash Table of Signatures:
+ .quad 0x1100001122222222
+ .quad 0
+## Parallel Table of Indexes:
+ .long 1
+ .long 0
+## Table of Section Offsets:
+## Row 0:
+ .long 1 # DW_SECT_INFO
+ .long 3 # DW_SECT_ABBREV
+## Row 1:
+ .long 0 # Offset in .debug_info.dwo
+ .long 0 # Offset in .debug_abbrev.dwo
+## Table of Section Sizes:
+ .long .LCUEnd-.LCUBegin # Size in .debug_info.dwo
+ .long .LAbbrevEnd-.LAbbrevBegin # Size in .debug_abbrev.dwo
Index: llvm/test/DebugInfo/X86/dwp-v5-tu-index.s
===================================================================
--- /dev/null
+++ llvm/test/DebugInfo/X86/dwp-v5-tu-index.s
@@ -0,0 +1,40 @@
+# RUN: llvm-mc -triple x86_64-unknown-linux %s -filetype=obj -o - | \
+# RUN: llvm-dwarfdump -debug-tu-index - | \
+# RUN: FileCheck %s
+
+# CHECK: .debug_tu_index contents:
+# CHECK-NEXT: version = 5 slots = 2
+# CHECK-EMPTY:
+# CHECK-NEXT: Index Signature INFO ABBREV LINE STR_OFFSETS
+# CHECK-NEXT: ----- ------------------ ------------------------ ------------------------ ------------------------ ------------------------
+# CHECK-NEXT: 1 0x1100001122222222 [0x00001000, 0x00001010) [0x00002000, 0x00002020) [0x00003000, 0x00003030) [0x00004000, 0x00004040)
+
+ .section .debug_tu_index, "", @progbits
+## Header:
+ .short 5 # Version
+ .space 2 # Padding
+ .long 4 # Section count
+ .long 1 # Unit count
+ .long 2 # Slot count
+## Hash Table of Signatures:
+ .quad 0x1100001122222222
+ .quad 0
+## Parallel Table of Indexes:
+ .long 1
+ .long 0
+## Table of Section Offsets:
+## Row 0:
+ .long 1 # DW_SECT_INFO
+ .long 3 # DW_SECT_ABBREV
+ .long 4 # DW_SECT_LINE
+ .long 6 # DW_SECT_STR_OFFSETS
+## Row 1:
+ .long 0x1000 # Offset in .debug_info.dwo
+ .long 0x2000 # Offset in .debug_abbrev.dwo
+ .long 0x3000 # Offset in .debug_line.dwo
+ .long 0x4000 # Offset in .debug_str_offsets.dwo
+## Table of Section Sizes:
+ .long 0x10 # Size in .debug_info.dwo
+ .long 0x20 # Size in .debug_abbrev.dwo
+ .long 0x30 # Size in .debug_line.dwo
+ .long 0x40 # Size in .debug_str_offsets.dwo
Index: llvm/test/DebugInfo/X86/dwp-v5-loclists.s
===================================================================
--- /dev/null
+++ llvm/test/DebugInfo/X86/dwp-v5-loclists.s
@@ -0,0 +1,99 @@
+# RUN: llvm-mc -triple x86_64-unknown-linux %s -filetype=obj -o - | \
+# RUN: llvm-dwarfdump -debug-info -debug-loclists - | \
+# RUN: FileCheck %s
+
+# CHECK: .debug_info.dwo contents:
+# CHECK: DW_TAG_compile_unit
+# CHECK: DW_TAG_variable
+# CHECK-NEXT: DW_AT_name ("a")
+# CHECK-NEXT: DW_AT_location (indexed (0x0) loclist = 0x00000010:
+# CHECK-NEXT: DW_LLE_startx_length (0x0000000000000001, 0x0000000000000010): DW_OP_reg5 RDI)
+
+# CHECK: .debug_loclists.dwo contents:
+# CHECK-NEXT: locations list header:
+# CHECK-NEXT: offsets: [
+# CHECK-NEXT: 0x00000004
+# CHECK-NEXT: ]
+# CHECK-NEXT: 0x00000010:
+# CHECK-NEXT: DW_LLE_startx_length (0x0000000000000001, 0x0000000000000010): DW_OP_reg5 RDI
+
+.section .debug_abbrev.dwo, "e", @progbits
+.LAbbrevBegin:
+ .uleb128 1 # Abbreviation Code
+ .uleb128 17 # DW_TAG_compile_unit
+ .byte 1 # DW_CHILDREN_yes
+ .byte 0 # EOM(1)
+ .byte 0 # EOM(2)
+ .uleb128 2 # Abbreviation Code
+ .uleb128 52 # DW_TAG_variable
+ .byte 0 # DW_CHILDREN_no
+ .uleb128 3 # DW_AT_name
+ .uleb128 8 # DW_FORM_string
+ .uleb128 2 # DW_AT_location
+ .uleb128 34 # DW_FORM_loclistx
+ .byte 0 # EOM(1)
+ .byte 0 # EOM(2)
+ .byte 0 # EOM(3)
+.LAbbrevEnd:
+
+ .section .debug_info.dwo, "e", @progbits
+.LCUBegin:
+ .long .LCUEnd-.LCUVersion # Length of Unit
+.LCUVersion:
+ .short 5 # Version
+ .byte 5 # DW_UT_split_compile
+ .byte 8 # Address size
+ .long 0 # Abbrev offset
+ .quad 0x1100001122222222 # DWO id
+ .uleb128 1 # Abbrev [1] DW_TAG_compile_unit
+ .uleb128 2 # Abbrev [2] DW_TAG_variable
+ .asciz "a" # DW_AT_name
+ .uleb128 0 # DW_AT_location
+ .byte 0 # End Of Children Mark
+.LCUEnd:
+
+.section .debug_loclists.dwo, "e", @progbits
+.LLLBegin:
+ .long .LLLEnd-.LLLVersion # Length of Unit
+.LLLVersion:
+ .short 5 # Version
+ .byte 8 # Address size
+ .byte 0 # Segment selector size
+ .long 1 # Offset entry count
+.LLLBase:
+ .long .LLL0-.LLLBase
+.LLL0:
+ .byte 3 # DW_LLE_startx_length
+ .uleb128 1 # Index
+ .uleb128 0x10 # Length
+ .uleb128 1 # Loc expr size
+ .byte 85 # DW_OP_reg5
+ .byte 0 # DW_LLE_end_of_list
+.LLLEnd:
+
+ .section .debug_cu_index, "", @progbits
+## Header:
+ .short 5 # Version
+ .space 2 # Padding
+ .long 3 # Section count
+ .long 1 # Unit count
+ .long 2 # Slot count
+## Hash Table of Signatures:
+ .quad 0x1100001122222222
+ .quad 0
+## Parallel Table of Indexes:
+ .long 1
+ .long 0
+## Table of Section Offsets:
+## Row 0:
+ .long 1 # DW_SECT_INFO
+ .long 3 # DW_SECT_ABBREV
+ .long 5 # DW_SECT_LOCLISTS
+## Row 1:
+ .long 0 # Offset in .debug_info.dwo
+ .long 0 # Offset in .debug_abbrev.dwo
+ .long 0 # Offset in .debug_loclists.dwo
+## Table of Section Sizes:
+ .long .LCUEnd-.LCUBegin # Size in .debug_info.dwo
+ .long .LAbbrevEnd-.LAbbrevBegin # Size in .debug_abbrev.dwo
+ .long .LLLEnd-.LLLBegin # Size in .debug_loclists.dwo
Index: llvm/test/DebugInfo/X86/dwp-v5-cu-index.s
===================================================================
--- /dev/null
+++ llvm/test/DebugInfo/X86/dwp-v5-cu-index.s
@@ -0,0 +1,49 @@
+# RUN: llvm-mc -triple x86_64-unknown-linux %s -filetype=obj -o - | \
+# RUN: llvm-dwarfdump -debug-cu-index - | \
+# RUN: FileCheck %s
+
+# CHECK: .debug_cu_index contents:
+# CHECK-NEXT: version = 5 slots = 2
+# CHECK-EMPTY:
+# CHECK-NEXT: Index Signature INFO ABBREV LINE LOCLISTS STR_OFFSETS MACRO RNGLISTS
+# CHECK-NEXT: ----- ------------------ ------------------------ ------------------------ ------------------------ ------------------------ ------------------------ ------------------------ ------------------------
+# CHECK-NEXT: 1 0x1100001122222222 [0x00001000, 0x00001010) [0x00002000, 0x00002020) [0x00003000, 0x00003030) [0x00004000, 0x00004040) [0x00005000, 0x00005050) [0x00006000, 0x00006060) [0x00007000, 0x00007070)
+
+ .section .debug_cu_index, "", @progbits
+## Header:
+ .short 5 # Version
+ .space 2 # Padding
+ .long 7 # Section count
+ .long 1 # Unit count
+ .long 2 # Slot count
+## Hash Table of Signatures:
+ .quad 0x1100001122222222
+ .quad 0
+## Parallel Table of Indexes:
+ .long 1
+ .long 0
+## Table of Section Offsets:
+## Row 0:
+ .long 1 # DW_SECT_INFO
+ .long 3 # DW_SECT_ABBREV
+ .long 4 # DW_SECT_LINE
+ .long 5 # DW_SECT_LOCLISTS
+ .long 6 # DW_SECT_STR_OFFSETS
+ .long 7 # DW_SECT_MACRO
+ .long 8 # DW_SECT_RNGLISTS
+## Row 1:
+ .long 0x1000 # Offset in .debug_info.dwo
+ .long 0x2000 # Offset in .debug_abbrev.dwo
+ .long 0x3000 # Offset in .debug_line.dwo
+ .long 0x4000 # Offset in .debug_loclists.dwo
+ .long 0x5000 # Offset in .debug_str_offsets.dwo
+ .long 0x6000 # Offset in .debug_macro.dwo
+ .long 0x7000 # Offset in .debug_rnglists.dwo
+## Table of Section Sizes:
+ .long 0x10 # Size in .debug_info.dwo
+ .long 0x20 # Size in .debug_abbrev.dwo
+ .long 0x30 # Size in .debug_line.dwo
+ .long 0x40 # Size in .debug_loclists.dwo
+ .long 0x50 # Size in .debug_str_offsets.dwo
+ .long 0x60 # Size in .debug_macro.dwo
+ .long 0x70 # Size in .debug_rnglists.dwo
Index: llvm/test/DebugInfo/X86/dwp-v2-tu-index.s
===================================================================
--- /dev/null
+++ llvm/test/DebugInfo/X86/dwp-v2-tu-index.s
@@ -0,0 +1,39 @@
+# RUN: llvm-mc -triple x86_64-unknown-linux %s -filetype=obj -o - | \
+# RUN: llvm-dwarfdump -debug-tu-index - | \
+# RUN: FileCheck %s
+
+# CHECK: .debug_tu_index contents:
+# CHECK-NEXT: version = 2 slots = 2
+# CHECK-EMPTY:
+# CHECK-NEXT: Index Signature TYPES ABBREV LINE STR_OFFSETS
+# CHECK-NEXT: ----- ------------------ ------------------------ ------------------------ ------------------------ ------------------------
+# CHECK-NEXT: 1 0x1100001122222222 [0x00001000, 0x00001010) [0x00002000, 0x00002020) [0x00003000, 0x00003030) [0x00004000, 0x00004040)
+
+ .section .debug_tu_index, "", @progbits
+## Header:
+ .long 2 # Version
+ .long 4 # Section count
+ .long 1 # Unit count
+ .long 2 # Slot count
+## Hash Table of Signatures:
+ .quad 0x1100001122222222
+ .quad 0
+## Parallel Table of Indexes:
+ .long 1
+ .long 0
+## Table of Section Offsets:
+## Row 0:
+ .long 2 # DW_SECT_TYPES
+ .long 3 # DW_SECT_ABBREV
+ .long 4 # DW_SECT_LINE
+ .long 6 # DW_SECT_STR_OFFSETS
+## Row 1:
+ .long 0x1000 # Offset in .debug_types.dwo
+ .long 0x2000 # Offset in .debug_abbrev.dwo
+ .long 0x3000 # Offset in .debug_line.dwo
+ .long 0x4000 # Offset in .debug_str_offsets.dwo
+## Table of Section Sizes:
+ .long 0x10 # Size in .debug_types.dwo
+ .long 0x20 # Size in .debug_abbrev.dwo
+ .long 0x30 # Size in .debug_line.dwo
+ .long 0x40 # Size in .debug_str_offsets.dwo
Index: llvm/test/DebugInfo/X86/dwp-v2-loc.s
===================================================================
--- /dev/null
+++ llvm/test/DebugInfo/X86/dwp-v2-loc.s
@@ -0,0 +1,87 @@
+# RUN: llvm-mc -triple x86_64-unknown-linux %s -filetype=obj -o - | \
+# RUN: llvm-dwarfdump -debug-info -debug-loc - | \
+# RUN: FileCheck %s
+
+# CHECK: .debug_info.dwo contents:
+# CHECK: DW_TAG_compile_unit
+# CHECK-NEXT: DW_AT_GNU_dwo_id (0x1100001122222222)
+# CHECK: DW_TAG_variable
+# CHECK-NEXT: DW_AT_name ("a")
+# CHECK-NEXT: DW_AT_location (0x00000000:
+# CHECK-NEXT: DW_LLE_startx_length (0x0000000000000001, 0x0000000000000010): DW_OP_reg5 RDI)
+
+# CHECK: .debug_loc.dwo contents:
+# CHECK-NEXT: 0x00000000:
+# CHECK-NEXT: DW_LLE_startx_length (0x00000001, 0x00000010): DW_OP_reg5 RDI
+
+.section .debug_abbrev.dwo, "e", @progbits
+.LAbbrevBegin:
+ .uleb128 1 # Abbreviation Code
+ .uleb128 17 # DW_TAG_compile_unit
+ .byte 1 # DW_CHILDREN_yes
+ .uleb128 0x2131 # DW_AT_GNU_dwo_id
+ .uleb128 7 # DW_FORM_data8
+ .byte 0 # EOM(1)
+ .byte 0 # EOM(2)
+ .uleb128 2 # Abbreviation Code
+ .uleb128 52 # DW_TAG_variable
+ .byte 0 # DW_CHILDREN_no
+ .uleb128 3 # DW_AT_name
+ .uleb128 8 # DW_FORM_string
+ .uleb128 2 # DW_AT_location
+ .uleb128 23 # DW_FORM_sec_offset
+ .byte 0 # EOM(1)
+ .byte 0 # EOM(2)
+ .byte 0 # EOM(3)
+.LAbbrevEnd:
+
+ .section .debug_info.dwo, "e", @progbits
+.LCUBegin:
+ .long .LCUEnd-.LCUVersion # Length of Unit
+.LCUVersion:
+ .short 4 # Version
+ .long 0 # Abbrev offset
+ .byte 8 # Address size
+ .uleb128 1 # Abbrev [1] DW_TAG_compile_unit
+ .quad 0x1100001122222222 # DW_AT_GNU_dwo_id
+ .uleb128 2 # Abbrev [2] DW_TAG_variable
+ .asciz "a" # DW_AT_name
+ .long 0 # DW_AT_location
+ .byte 0 # End Of Children Mark
+.LCUEnd:
+
+.section .debug_loc.dwo, "e", @progbits
+.LLocBegin:
+ .byte 3 # DW_LLE_startx_length
+ .uleb128 1 # Index
+ .long 0x10 # Length
+ .short 1 # Loc expr size
+ .byte 85 # DW_OP_reg5
+ .byte 0 # DW_LLE_end_of_list
+.LLocEnd:
+
+ .section .debug_cu_index, "", @progbits
+## Header:
+ .long 2 # Version
+ .long 3 # Section count
+ .long 1 # Unit count
+ .long 2 # Slot count
+## Hash Table of Signatures:
+ .quad 0x1100001122222222
+ .quad 0
+## Parallel Table of Indexes:
+ .long 1
+ .long 0
+## Table of Section Offsets:
+## Row 0:
+ .long 1 # DW_SECT_INFO
+ .long 3 # DW_SECT_ABBREV
+ .long 5 # DW_SECT_LOC
+## Row 1:
+ .long 0 # Offset in .debug_info.dwo
+ .long 0 # Offset in .debug_abbrev.dwo
+ .long 0 # Offset in .debug_loc.dwo
+## Table of Section Sizes:
+ .long .LCUEnd-.LCUBegin # Size in .debug_info.dwo
+ .long .LAbbrevEnd-.LAbbrevBegin # Size in .debug_abbrev.dwo
+ .long .LLocEnd-.LLocBegin # Size in .debug_loc.dwo
Index: llvm/test/DebugInfo/X86/dwp-v2-cu-index.s
===================================================================
--- /dev/null
+++ llvm/test/DebugInfo/X86/dwp-v2-cu-index.s
@@ -0,0 +1,48 @@
+# RUN: llvm-mc -triple x86_64-unknown-linux %s -filetype=obj -o - | \
+# RUN: llvm-dwarfdump -debug-cu-index - | \
+# RUN: FileCheck %s
+
+# CHECK: .debug_cu_index contents:
+# CHECK-NEXT: version = 2 slots = 2
+# CHECK-EMPTY:
+# CHECK-NEXT: Index Signature INFO ABBREV LINE LOC STR_OFFSETS MACINFO MACRO
+# CHECK-NEXT: ----- ------------------ ------------------------ ------------------------ ------------------------ ------------------------ ------------------------ ------------------------ ------------------------
+# CHECK-NEXT: 1 0x1100001122222222 [0x00001000, 0x00001010) [0x00002000, 0x00002020) [0x00003000, 0x00003030) [0x00004000, 0x00004040) [0x00005000, 0x00005050) [0x00006000, 0x00006060) [0x00007000, 0x00007070)
+
+ .section .debug_cu_index, "", @progbits
+## Header:
+ .long 2 # Version
+ .long 7 # Section count
+ .long 1 # Unit count
+ .long 2 # Slot count
+## Hash Table of Signatures:
+ .quad 0x1100001122222222
+ .quad 0
+## Parallel Table of Indexes:
+ .long 1
+ .long 0
+## Table of Section Offsets:
+## Row 0:
+ .long 1 # DW_SECT_INFO
+ .long 3 # DW_SECT_ABBREV
+ .long 4 # DW_SECT_LINE
+ .long 5 # DW_SECT_LOC
+ .long 6 # DW_SECT_STR_OFFSETS
+ .long 7 # DW_SECT_MACINFO
+ .long 8 # DW_SECT_MACRO
+## Row 1:
+ .long 0x1000 # Offset in .debug_info.dwo
+ .long 0x2000 # Offset in .debug_abbrev.dwo
+ .long 0x3000 # Offset in .debug_line.dwo
+ .long 0x4000 # Offset in .debug_loc.dwo
+ .long 0x5000 # Offset in .debug_str_offsets.dwo
+ .long 0x6000 # Offset in .debug_macinfo.dwo
+ .long 0x7000 # Offset in .debug_macro.dwo
+## Table of Section Sizes:
+ .long 0x10 # Size in .debug_info.dwo
+ .long 0x20 # Size in .debug_abbrev.dwo
+ .long 0x30 # Size in .debug_line.dwo
+ .long 0x40 # Size in .debug_loc.dwo
+ .long 0x50 # Size in .debug_str_offsets.dwo
+ .long 0x60 # Size in .debug_macinfo.dwo
+ .long 0x70 # Size in .debug_macro.dwo
Index: llvm/lib/DebugInfo/DWARF/DWARFVerifier.cpp
===================================================================
--- llvm/lib/DebugInfo/DWARF/DWARFVerifier.cpp
+++ llvm/lib/DebugInfo/DWARF/DWARFVerifier.cpp
@@ -352,7 +352,7 @@
OS << "Verifying .debug_types Unit Header Chain...\n";
DObj.forEachTypesSections([&](const DWARFSection &S) {
- NumErrors += verifyUnitSection(S, DW_SECT_TYPES);
+ NumErrors += verifyUnitSection(S, DW_SECT_EXT_TYPES);
});
return NumErrors == 0;
}
Index: llvm/lib/DebugInfo/DWARF/DWARFUnitIndex.cpp
===================================================================
--- llvm/lib/DebugInfo/DWARF/DWARFUnitIndex.cpp
+++ llvm/lib/DebugInfo/DWARF/DWARFUnitIndex.cpp
@@ -17,15 +17,94 @@
using namespace llvm;
+namespace {
+
+enum class DWARFSectionKindV2 {
+ DW_SECT_INFO = 1,
+ DW_SECT_TYPES = 2,
+ DW_SECT_ABBREV = 3,
+ DW_SECT_LINE = 4,
+ DW_SECT_LOC = 5,
+ DW_SECT_STR_OFFSETS = 6,
+ DW_SECT_MACINFO = 7,
+ DW_SECT_MACRO = 8,
+};
+
+} // namespace
+
+uint32_t llvm::SerializeSectionKind(DWARFSectionKind Kind,
+ unsigned IndexVersion) {
+ if (IndexVersion == 5) {
+ assert(Kind >= DW_SECT_INFO && Kind <= DW_SECT_RNGLISTS &&
+ Kind != DW_SECT_EXT_TYPES);
+ return static_cast<uint32_t>(Kind);
+ }
+ assert(IndexVersion == 2);
+ switch (Kind) {
+#define CASE(S,T) \
+ case DW_SECT_##S: \
+ return static_cast<uint32_t>(DWARFSectionKindV2::DW_SECT_##T)
+ CASE(INFO, INFO);
+ CASE(EXT_TYPES, TYPES);
+ CASE(ABBREV, ABBREV);
+ CASE(LINE, LINE);
+ CASE(EXT_LOC, LOC);
+ CASE(STR_OFFSETS, STR_OFFSETS);
+ CASE(EXT_MACINFO, MACINFO);
+ CASE(MACRO, MACRO);
+#undef CASE
+ default:
+ // All other section kinds have no corresponding values in v2 indexes.
+ llvm_unreachable("Invalid DWARFSectionKind");
+ }
+}
+
+DWARFSectionKind llvm::DeserializeSectionKind(uint32_t Value,
+ unsigned IndexVersion) {
+ if (IndexVersion == 5)
+ return (Value >= DW_SECT_INFO && Value <= DW_SECT_RNGLISTS &&
+ Value != DW_SECT_EXT_TYPES)
+ ? static_cast<DWARFSectionKind>(Value)
+ : DW_SECT_EXT_unknown;
+ assert(IndexVersion == 2);
+ switch (static_cast<DWARFSectionKindV2>(Value)) {
+#define CASE(S,T) \
+ case DWARFSectionKindV2::DW_SECT_##S: \
+ return DW_SECT_##T
+ CASE(INFO, INFO);
+ CASE(TYPES, EXT_TYPES);
+ CASE(ABBREV, ABBREV);
+ CASE(LINE, LINE);
+ CASE(LOC, EXT_LOC);
+ CASE(STR_OFFSETS, STR_OFFSETS);
+ CASE(MACINFO, EXT_MACINFO);
+ CASE(MACRO, MACRO);
+#undef CASE
+ }
+ return DW_SECT_EXT_unknown;
+}
+
bool DWARFUnitIndex::Header::parse(DataExtractor IndexData,
uint64_t *OffsetPtr) {
+ const uint64_t BeginOffset = *OffsetPtr;
if (!IndexData.isValidOffsetForDataOfSize(*OffsetPtr, 16))
return false;
+ // GCC Debug Fission defines the version as an unsigned 32-bit field
+ // with value of 2, https://gcc.gnu.org/wiki/DebugFissionDWP.
+ // DWARFv5 defines the same space as an uhalf version field with value of 5
+ // and a 2 bytes long padding, see Section 7.3.5.3.
Version = IndexData.getU32(OffsetPtr);
+ if (Version != 2) {
+ *OffsetPtr = BeginOffset;
+ Version = IndexData.getU16(OffsetPtr);
+ if (Version != 5)
+ return false;
+ *OffsetPtr += 2; // Skip padding.
+ }
NumColumns = IndexData.getU32(OffsetPtr);
NumUnits = IndexData.getU32(OffsetPtr);
NumBuckets = IndexData.getU32(OffsetPtr);
- return Version <= 2;
+ return true;
}
void DWARFUnitIndex::Header::dump(raw_ostream &OS) const {
@@ -49,6 +128,10 @@
if (!Header.parse(IndexData, &Offset))
return false;
+ // Fix InfoColumnKind: in DWARFv5, type units also lay in .debug_info.dwo.
+ if (Header.Version == 5)
+ InfoColumnKind = DW_SECT_INFO;
+
if (!IndexData.isValidOffsetForDataOfSize(
Offset, Header.NumBuckets * (8 + 4) +
(2 * Header.NumUnits + 1) * 4 * Header.NumColumns))
@@ -76,8 +159,15 @@
// Read the Column Headers
for (unsigned i = 0; i != Header.NumColumns; ++i) {
- ColumnKinds[i] = static_cast<DWARFSectionKind>(IndexData.getU32(&Offset));
- if (ColumnKinds[i] == InfoColumnKind) {
+ uint32_t RawSectID = IndexData.getU32(&Offset);
+ DWARFSectionKind Kind = DeserializeSectionKind(RawSectID, Header.Version);
+ ColumnKinds[i] = Kind;
+ if (Kind == DW_SECT_EXT_unknown) {
+ if (!UnknownColumnIds)
+ UnknownColumnIds = std::make_unique<uint32_t[]>(Header.NumColumns);
+ UnknownColumnIds[i] = RawSectID;
+ }
+ if (Kind == InfoColumnKind) {
if (InfoColumn != -1)
return false;
InfoColumn = i;
@@ -105,20 +195,21 @@
}
StringRef DWARFUnitIndex::getColumnHeader(DWARFSectionKind DS) {
-#define CASE(DS) \
- case DW_SECT_##DS: \
- return #DS;
+
switch (DS) {
- CASE(INFO);
- CASE(TYPES);
- CASE(ABBREV);
- CASE(LINE);
- CASE(LOC);
- CASE(STR_OFFSETS);
- CASE(MACINFO);
- CASE(MACRO);
+#define HANDLE_DW_SECT(ID, NAME) \
+ case DW_SECT_##NAME: \
+ return #NAME;
+#include "llvm/BinaryFormat/Dwarf.def"
+ case DW_SECT_EXT_TYPES:
+ return "TYPES";
+ case DW_SECT_EXT_LOC:
+ return "LOC";
+ case DW_SECT_EXT_MACINFO:
+ return "MACINFO";
+ default:
+ llvm_unreachable("Unknown DWARFSectionKind");
}
- return StringRef();
}
void DWARFUnitIndex::dump(raw_ostream &OS) const {
@@ -129,11 +220,12 @@
OS << "Index Signature ";
for (unsigned i = 0; i != Header.NumColumns; ++i) {
DWARFSectionKind Kind = ColumnKinds[i];
- StringRef Name = getColumnHeader(Kind);
- if (!Name.empty())
- OS << ' ' << left_justify(Name, 24);
- else
- OS << format(" Unknown: %-15u", static_cast<unsigned>(Kind));
+ if (Kind != DW_SECT_EXT_unknown)
+ OS << ' ' << left_justify(getColumnHeader(Kind), 24);
+ else {
+ assert(UnknownColumnIds);
+ OS << format(" Unknown: %-15" PRIu32, UnknownColumnIds[i]);
+ }
}
OS << "\n----- ------------------";
for (unsigned i = 0; i != Header.NumColumns; ++i)
Index: llvm/lib/DebugInfo/DWARF/DWARFUnit.cpp
===================================================================
--- llvm/lib/DebugInfo/DWARF/DWARFUnit.cpp
+++ llvm/lib/DebugInfo/DWARF/DWARFUnit.cpp
@@ -181,20 +181,17 @@
if (IsDWO) {
// If we are reading a package file, we need to adjust the location list
// data based on the index entries.
- StringRef Data = LocSection->Data;
+ StringRef Data = Header.getVersion() >= 5
+ ? Context.getDWARFObj().getLoclistsDWOSection().Data
+ : LocSection->Data;
if (auto *IndexEntry = Header.getIndexEntry())
- if (const auto *C = IndexEntry->getOffset(DW_SECT_LOC))
+ if (const auto *C = IndexEntry->getOffset(
+ Header.getVersion() >= 5 ? DW_SECT_LOCLISTS : DW_SECT_EXT_LOC))
Data = Data.substr(C->Offset, C->Length);
- DWARFDataExtractor DWARFData =
- Header.getVersion() >= 5
- ? DWARFDataExtractor(Context.getDWARFObj(),
- Context.getDWARFObj().getLoclistsDWOSection(),
- isLittleEndian, getAddressByteSize())
- : DWARFDataExtractor(Data, isLittleEndian, getAddressByteSize());
+ DWARFDataExtractor DWARFData(Data, isLittleEndian, getAddressByteSize());
LocTable =
std::make_unique<DWARFDebugLoclists>(DWARFData, Header.getVersion());
-
} else if (Header.getVersion() >= 5) {
LocTable = std::make_unique<DWARFDebugLoclists>(
DWARFDataExtractor(Context.getDWARFObj(),
@@ -276,7 +273,7 @@
FormParams.AddrSize = debug_info.getU8(offset_ptr, &Err);
// Fake a unit type based on the section type. This isn't perfect,
// but distinguishing compile and type units is generally enough.
- if (SectionKind == DW_SECT_TYPES)
+ if (SectionKind == DW_SECT_EXT_TYPES)
UnitType = DW_UT_type;
else
UnitType = DW_UT_compile;
@@ -759,7 +756,7 @@
DWARFSectionKind Kind) {
if (Kind == DW_SECT_INFO)
return Context.getCUIndex();
- assert(Kind == DW_SECT_TYPES);
+ assert(Kind == DW_SECT_EXT_TYPES);
return Context.getTUIndex();
}
Index: llvm/lib/DebugInfo/DWARF/DWARFContext.cpp
===================================================================
--- llvm/lib/DebugInfo/DWARF/DWARFContext.cpp
+++ llvm/lib/DebugInfo/DWARF/DWARFContext.cpp
@@ -725,7 +725,7 @@
DataExtractor TUIndexData(DObj->getTUIndexSection(), isLittleEndian(), 0);
- TUIndex = std::make_unique<DWARFUnitIndex>(DW_SECT_TYPES);
+ TUIndex = std::make_unique<DWARFUnitIndex>(DW_SECT_EXT_TYPES);
TUIndex->parse(TUIndexData);
return *TUIndex;
}
@@ -924,7 +924,7 @@
});
NormalUnits.finishedInfoUnits();
DObj->forEachTypesSections([&](const DWARFSection &S) {
- NormalUnits.addUnitsForSection(*this, S, DW_SECT_TYPES);
+ NormalUnits.addUnitsForSection(*this, S, DW_SECT_EXT_TYPES);
});
}
@@ -936,7 +936,7 @@
});
DWOUnits.finishedInfoUnits();
DObj->forEachTypesDWOSections([&](const DWARFSection &S) {
- DWOUnits.addUnitsForDWOSection(*this, S, DW_SECT_TYPES, Lazy);
+ DWOUnits.addUnitsForDWOSection(*this, S, DW_SECT_EXT_TYPES, Lazy);
});
}
Index: llvm/include/llvm/DebugInfo/DWARF/DWARFUnitIndex.h
===================================================================
--- llvm/include/llvm/DebugInfo/DWARF/DWARFUnitIndex.h
+++ llvm/include/llvm/DebugInfo/DWARF/DWARFUnitIndex.h
@@ -19,17 +19,57 @@
class raw_ostream;
+// Pre-standard implementation of package files defined a number of section
+// identifiers with values that clash definitions in the DWARFv5 standard.
+// See https://gcc.gnu.org/wiki/DebugFissionDWP and Section 7.3.5.3 in DWARFv5.
+//
+// The following identifiers are the same in the proposal and in DWARFv5:
+// DW_SECT_INFO = 1 (.debug_info.dwo)
+// DW_SECT_ABBREV = 3 (.debug_abbrev.dwo)
+// DW_SECT_LINE = 4 (.debug_line.dwo)
+// DW_SECT_STR_OFFSETS = 6 (.debug_str_offsets.dwo)
+//
+// The following identifiers are defined only in DWARFv5:
+// DW_SECT_LOCLISTS = 5 (.debug_loclists.dwo)
+// DW_SECT_RNGLISTS = 8 (.debug_rnglists.dwo)
+//
+// The following identifiers are defined only in the GNU proposal:
+// DW_SECT_TYPES = 2 (.debug_types.dwo)
+// DW_SECT_LOC = 5 (.debug_loc.dwo)
+// DW_SECT_MACINFO = 7 (.debug_macinfo.dwo)
+//
+// DW_SECT_MACRO for the .debug_macro.dwo section is defined in both standards,
+// but with different values, 8 in GNU and 7 in DWARFv5.
+//
+// This enum defines constants to represent the identifiers of both sets.
+// For DWARFv5 ones, the values are the same as defined in the standard.
+// For pre-standard ones, which correspond to sections being deprecated in
+// DWARFv5, the values are chosen more or less arbitrary and a tag "_EXT_"
+// is added to the names.
+//
+// The enum is intended to be used only in internal interfaces.
+// Special conversion functions should be used for the translation.
enum DWARFSectionKind {
- DW_SECT_INFO = 1,
- DW_SECT_TYPES,
- DW_SECT_ABBREV,
- DW_SECT_LINE,
- DW_SECT_LOC,
- DW_SECT_STR_OFFSETS,
- DW_SECT_MACINFO,
- DW_SECT_MACRO,
+ // Denotes a value read from an index section that does not correspond
+ // to any of the supported standards.
+ DW_SECT_EXT_unknown = 0,
+#define HANDLE_DW_SECT(ID, NAME) DW_SECT_##NAME = ID,
+#include "llvm/BinaryFormat/Dwarf.def"
+ DW_SECT_EXT_TYPES = 2,
+ DW_SECT_EXT_LOC = 9,
+ DW_SECT_EXT_MACINFO = 10,
};
+// Convert the internal value for section kind to an on-disk value depending on
+// the version of the index section. IndexVersion is expected to be either 2 for
+// pre-standard GNU proposal or 5 for DWARFv5 package file.
+uint32_t SerializeSectionKind(DWARFSectionKind Kind, unsigned IndexVersion);
+
+// Convert the value read from the index section to the internal representation
+// depending on the index section version, which is expected to be either 2 for
+// pre-standard GNU proposal or 5 for DWARFv5 package file.
+DWARFSectionKind DeserializeSectionKind(uint32_t Value, unsigned IndexVersion);
+
class DWARFUnitIndex {
struct Header {
uint32_t Version;
@@ -72,6 +112,11 @@
DWARFSectionKind InfoColumnKind;
int InfoColumn = -1;
std::unique_ptr<DWARFSectionKind[]> ColumnKinds;
+ // This is a parallel array of raw section IDs for columns of unknown kinds.
+ // This array is created only if there are items in columns ColumnKinds with
+ // DW_SECT_EXT_unknown and the only initialized items here are those with
+ // the same indexes.
+ std::unique_ptr<uint32_t[]> UnknownColumnIds;
std::unique_ptr<Entry[]> Rows;
mutable std::vector<Entry *> OffsetLookup;
@@ -88,6 +133,8 @@
bool parse(DataExtractor IndexData);
void dump(raw_ostream &OS) const;
+ uint32_t getVersion() const { return Header.Version; }
+
const Entry *getFromOffset(uint32_t Offset) const;
const Entry *getFromHash(uint64_t Offset) const;
Index: llvm/include/llvm/BinaryFormat/Dwarf.def
===================================================================
--- llvm/include/llvm/BinaryFormat/Dwarf.def
+++ llvm/include/llvm/BinaryFormat/Dwarf.def
@@ -22,7 +22,7 @@
(defined HANDLE_DW_CFA && defined HANDLE_DW_CFA_PRED) || \
defined HANDLE_DW_APPLE_PROPERTY || defined HANDLE_DW_UT || \
defined HANDLE_DWARF_SECTION || defined HANDLE_DW_IDX || \
- defined HANDLE_DW_END)
+ defined HANDLE_DW_END || defined HANDLE_DW_SECT)
#error "Missing macro definition of HANDLE_DW*"
#endif
@@ -128,6 +128,10 @@
#define HANDLE_DW_END(ID, NAME)
#endif
+#ifndef HANDLE_DW_SECT
+#define HANDLE_DW_SECT(ID, NAME)
+#endif
+
HANDLE_DW_TAG(0x0000, null, 2, DWARF, DW_KIND_NONE)
HANDLE_DW_TAG(0x0001, array_type, 2, DWARF, DW_KIND_TYPE)
HANDLE_DW_TAG(0x0002, class_type, 2, DWARF, DW_KIND_TYPE)
@@ -957,6 +961,15 @@
HANDLE_DW_IDX(0x04, parent)
HANDLE_DW_IDX(0x05, type_hash)
+// DWARF package file section identifiers.
+// DWARFv5, section 7.3.5.3, table 7.1.
+HANDLE_DW_SECT(1, INFO)
+HANDLE_DW_SECT(3, ABBREV)
+HANDLE_DW_SECT(4, LINE)
+HANDLE_DW_SECT(5, LOCLISTS)
+HANDLE_DW_SECT(6, STR_OFFSETS)
+HANDLE_DW_SECT(7, MACRO)
+HANDLE_DW_SECT(8, RNGLISTS)
#undef HANDLE_DW_TAG
#undef HANDLE_DW_AT
@@ -981,3 +994,4 @@
#undef HANDLE_DWARF_SECTION
#undef HANDLE_DW_IDX
#undef HANDLE_DW_END
+#undef HANDLE_DW_SECT
Index: lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp
===================================================================
--- lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp
+++ lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp
@@ -479,7 +479,8 @@
const DWARFDataExtractor &data =
GetVersion() >= 5 ? Ctx.getOrLoadLocListsData() : Ctx.getOrLoadLocData();
if (const llvm::DWARFUnitIndex::Entry *entry = m_header.GetIndexEntry()) {
- if (const auto *contribution = entry->getOffset(llvm::DW_SECT_LOC))
+ if (const auto *contribution = entry->getOffset(
+ GetVersion() >= 5 ? llvm::DW_SECT_LOCLISTS : llvm::DW_SECT_EXT_LOC))
return DWARFDataExtractor(data, contribution->Offset,
contribution->Length);
return DWARFDataExtractor();
Index: lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.cpp
===================================================================
--- lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.cpp
+++ lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.cpp
@@ -76,7 +76,7 @@
if (m_context.isDwo())
index = &llvm::getDWARFUnitIndex(m_context.GetAsLLVM(),
section == DIERef::Section::DebugTypes
- ? llvm::DW_SECT_TYPES
+ ? llvm::DW_SECT_EXT_TYPES
: llvm::DW_SECT_INFO);
lldb::offset_t offset = 0;
while (data.ValidOffset(offset)) {
_______________________________________________
lldb-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits