forked from OSchip/llvm-project
[llvm-dwp] Add support for DWARFv5 type units ...
This patch adds support for DWARFv5 type units: parsing from the .debug_info section, and writing index to the type unit index. Previously, the type units were part of the .debug_types section which is no longer used in DWARFv5. Reviewed By: dblaikie Differential Revision: https://reviews.llvm.org/D101818
This commit is contained in:
parent
6e2d3049d2
commit
316da543af
|
@ -0,0 +1,39 @@
|
|||
## Note: For the purpose of checking the de-duplication of type units
|
||||
## it is not necessary to have the DIEs for the structure type, that
|
||||
## are referenced by the type unit.
|
||||
|
||||
.section .debug_info.dwo,"e",@progbits
|
||||
.long .Ldebug_info_dwo_end0-.Ldebug_info_dwo_start0 # Length of Unit
|
||||
.Ldebug_info_dwo_start0:
|
||||
.short 5 # DWARF version number
|
||||
.byte 6 # DWARF Unit Type (DW_UT_split_type)
|
||||
.byte 8 # Address Size (in bytes)
|
||||
.long 0 # Offset Into Abbrev. Section
|
||||
.quad 5657452045627120676 # Type Signature
|
||||
.long 25 # Type DIE Offset
|
||||
.byte 2 # Abbrev [2] DW_TAG_type_unit
|
||||
.byte 3 # Abbrev [3] DW_TAG_structure_type
|
||||
.byte 0 # End Of Children Mark
|
||||
.Ldebug_info_dwo_end0:
|
||||
.section .debug_info.dwo,"e",@progbits
|
||||
.long .Ldebug_info_dwo_end2-.Ldebug_info_dwo_start2 # Length of Unit
|
||||
.Ldebug_info_dwo_start2:
|
||||
.short 5 # DWARF version number
|
||||
.byte 5 # DWARF Unit Type (DW_UT_split_compile)
|
||||
.byte 8 # Address Size (in bytes)
|
||||
.long 0 # Offset Into Abbrev. Section
|
||||
.quad 0
|
||||
.byte 1 # Abbrev [1] DW_TAG_compile_unit
|
||||
.Ldebug_info_dwo_end2:
|
||||
.section .debug_abbrev.dwo,"e",@progbits
|
||||
.byte 1 # Abbreviation Code
|
||||
.byte 17 # DW_TAG_compile_unit
|
||||
.byte 0 # DW_CHILDREN_no
|
||||
.byte 0 # EOM(1)
|
||||
.byte 0 # EOM(2)
|
||||
.byte 2 # Abbreviation Code
|
||||
.byte 65 # DW_TAG_type_unit
|
||||
.byte 1 # DW_CHILDREN_yes
|
||||
.byte 0 # EOM
|
||||
.byte 0 # EOM
|
||||
.byte 0 # EOM
|
|
@ -0,0 +1,39 @@
|
|||
## Note: For the purpose of checking the de-duplication of type units
|
||||
## it is not necessary to have the DIEs for the structure type, that
|
||||
## are referenced by the type unit.
|
||||
|
||||
.section .debug_info.dwo,"e",@progbits
|
||||
.long .Ldebug_info_dwo_end0-.Ldebug_info_dwo_start0 # Length of Unit
|
||||
.Ldebug_info_dwo_start0:
|
||||
.short 5 # DWARF version number
|
||||
.byte 6 # DWARF Unit Type (DW_UT_split_type)
|
||||
.byte 8 # Address Size (in bytes)
|
||||
.long 0 # Offset Into Abbrev. Section
|
||||
.quad 5657452045627120676 # Type Signature
|
||||
.long 25 # Type DIE Offset
|
||||
.byte 2 # Abbrev [2] DW_TAG_type_unit
|
||||
.byte 3 # Abbrev [3] DW_TAG_structure_type
|
||||
.byte 0 # End Of Children Mark
|
||||
.Ldebug_info_dwo_end0:
|
||||
.section .debug_info.dwo,"e",@progbits
|
||||
.long .Ldebug_info_dwo_end2-.Ldebug_info_dwo_start2 # Length of Unit
|
||||
.Ldebug_info_dwo_start2:
|
||||
.short 5 # DWARF version number
|
||||
.byte 5 # DWARF Unit Type (DW_UT_split_compile)
|
||||
.byte 8 # Address Size (in bytes)
|
||||
.long 0 # Offset Into Abbrev. Section
|
||||
.quad -1709724327721109161
|
||||
.byte 1 # Abbrev [1] DW_TAG_compile_unit
|
||||
.Ldebug_info_dwo_end2:
|
||||
.section .debug_abbrev.dwo,"e",@progbits
|
||||
.byte 1 # Abbreviation Code
|
||||
.byte 17 # DW_TAG_compile_unit
|
||||
.byte 0 # DW_CHILDREN_no
|
||||
.byte 0 # EOM(1)
|
||||
.byte 0 # EOM(2)
|
||||
.byte 2 # Abbreviation Code
|
||||
.byte 65 # DW_TAG_type_unit
|
||||
.byte 1 # DW_CHILDREN_yes
|
||||
.byte 0 # EOM
|
||||
.byte 0 # EOM
|
||||
.byte 0 # EOM
|
|
@ -9,8 +9,8 @@
|
|||
## have the info on the type and compile units.
|
||||
|
||||
# CHECK-DAG: .debug_info.dwo contents
|
||||
# CHECK-NOT: Type Unit:
|
||||
# CHECK: 0x00000000: Compile Unit: length = 0x00000011, format = DWARF32, version = 0x0005, unit_type = DW_UT_split_compile, abbr_offset = 0x0000, addr_size = 0x08, DWO_id = {{.*}} (next unit at 0x00000015)
|
||||
# CHECK: 0x00000000: Type Unit: length = 0x00000017, format = DWARF32, version = 0x0005, unit_type = DW_UT_split_type, abbr_offset = 0x0000, addr_size = 0x08, name = '', type_signature = {{.*}}, type_offset = 0x0019 (next unit at 0x0000001b)
|
||||
# CHECK: 0x0000001b: Compile Unit: length = 0x00000011, format = DWARF32, version = 0x0005, unit_type = DW_UT_split_compile, abbr_offset = 0x0000, addr_size = 0x08, DWO_id = {{.*}} (next unit at 0x00000030)
|
||||
.section .debug_info.dwo,"e",@progbits
|
||||
.long .Ldebug_info_dwo_end0-.Ldebug_info_dwo_start0 # Length of Unit
|
||||
.Ldebug_info_dwo_start0:
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
## of version 2 and a TU index of version 5. A valid TU is not required, but
|
||||
## the .debug_types.dwo section should not be empty.
|
||||
|
||||
# CHECK: error: expected index version 2, but got: 5
|
||||
# CHECK: error: incompatible tu_index versions, found 5 and expecting 2
|
||||
|
||||
.section .debug_abbrev.dwo, "e", @progbits
|
||||
.LAbbrevBegin:
|
|
@ -1,3 +1,61 @@
|
|||
RUN: not llvm-dwp %p/../Inputs/missing_tu_index/x.dwp -o %t 2>&1 | FileCheck %s
|
||||
# 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: failed to parse tu_index
|
||||
## Note: To reach the test point, we need a DWP file with a CU, a CU index
|
||||
## and a broken TU index.
|
||||
|
||||
# CHECK: error: failed to parse tu_index
|
||||
|
||||
.section .debug_abbrev.dwo, "e", @progbits
|
||||
.LAbbrevBegin:
|
||||
.uleb128 1 # Abbreviation Code
|
||||
.uleb128 17 # DW_TAG_compile_unit
|
||||
.byte 1 # DW_CHILDREN_no
|
||||
.uleb128 0x2131 # DW_AT_GNU_dwo_id
|
||||
.uleb128 7 # DW_FORM_data8
|
||||
.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
|
||||
.LCUEnd:
|
||||
|
||||
.section .debug_types.dwo, "e", @progbits
|
||||
.space 1
|
||||
|
||||
.section .debug_cu_index, "", @progbits
|
||||
|
||||
## Header:
|
||||
.long 2 # Version
|
||||
.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
|
||||
|
||||
.section .debug_tu_index, "", @progbits
|
||||
## Header:
|
||||
.short 2 # Version
|
||||
|
|
|
@ -0,0 +1,72 @@
|
|||
# This test checks if llvm-dwp can correctly generate the tu index section (v5).
|
||||
|
||||
# RUN: llvm-mc -triple x86_64-unknown-linux %s -filetype=obj -o %t.o \
|
||||
# RUN: -split-dwarf-file=%t.dwo -dwarf-version=5
|
||||
# RUN: llvm-dwp %t.dwo -o %t.dwp
|
||||
# RUN: llvm-dwarfdump -debug-info -debug-tu-index %t.dwp | FileCheck %s
|
||||
|
||||
## Note: In order to check whether the type unit index is generated
|
||||
## there is no need to add the missing DIEs for the structure type of the type unit.
|
||||
|
||||
# CHECK-DAG: .debug_info.dwo contents:
|
||||
# CHECK: 0x00000000: Type Unit: length = 0x00000017, format = DWARF32, version = 0x0005, unit_type = DW_UT_split_type, abbr_offset = 0x0000, addr_size = 0x08, name = '', type_signature = [[TUID1:.*]], type_offset = 0x0019 (next unit at 0x0000001b)
|
||||
# CHECK: 0x0000001b: Type Unit: length = 0x00000017, format = DWARF32, version = 0x0005, unit_type = DW_UT_split_type, abbr_offset = 0x0000, addr_size = 0x08, name = '', type_signature = [[TUID2:.*]], type_offset = 0x0019 (next unit at 0x00000036)
|
||||
# CHECK_DAG: .debug_tu_index contents:
|
||||
# CHECK: version = 5, units = 2, slots = 4
|
||||
# CHECK: Index Signature INFO ABBREV
|
||||
# CHECK: 1 [[TUID1]] [0x00000000, 0x0000001b) [0x00000000, 0x00000010)
|
||||
# CHECK: 4 [[TUID2]] [0x0000001b, 0x00000036) [0x00000000, 0x00000010)
|
||||
|
||||
.section .debug_info.dwo,"e",@progbits
|
||||
.long .Ldebug_info_dwo_end0-.Ldebug_info_dwo_start0 # Length of Unit
|
||||
.Ldebug_info_dwo_start0:
|
||||
.short 5 # DWARF version number
|
||||
.byte 6 # DWARF Unit Type (DW_UT_split_type)
|
||||
.byte 8 # Address Size (in bytes)
|
||||
.long 0 # Offset Into Abbrev. Section
|
||||
.quad 5657452045627120676 # Type Signature
|
||||
.long 25 # Type DIE Offset
|
||||
.byte 2 # Abbrev [2] DW_TAG_type_unit
|
||||
.byte 3 # Abbrev [3] DW_TAG_structure_type
|
||||
.byte 0 # End Of Children Mark
|
||||
.Ldebug_info_dwo_end0:
|
||||
.section .debug_info.dwo,"e",@progbits
|
||||
.long .Ldebug_info_dwo_end1-.Ldebug_info_dwo_start1 # Length of Unit
|
||||
.Ldebug_info_dwo_start1:
|
||||
.short 5 # DWARF version number
|
||||
.byte 6 # DWARF Unit Type (DW_UT_split_type)
|
||||
.byte 8 # Address Size (in bytes)
|
||||
.long 0 # Offset Into Abbrev. Section
|
||||
.quad -8528522068957683993 # Type Signature
|
||||
.long 25 # Type DIE Offset
|
||||
.byte 4 # Abbrev [4] DW_TAG_type_unit
|
||||
.byte 5 # Abbrev [5] DW_TAG_structure_type
|
||||
.byte 0 # End Of Children Mark
|
||||
.Ldebug_info_dwo_end1:
|
||||
.section .debug_info.dwo,"e",@progbits
|
||||
.long .Ldebug_info_dwo_end2-.Ldebug_info_dwo_start2 # Length of Unit
|
||||
.Ldebug_info_dwo_start2:
|
||||
.short 5 # DWARF version number
|
||||
.byte 5 # DWARF Unit Type (DW_UT_split_compile)
|
||||
.byte 8 # Address Size (in bytes)
|
||||
.long 0 # Offset Into Abbrev. Section
|
||||
.quad 0
|
||||
.byte 1 # Abbrev [1] DW_TAG_compile_unit
|
||||
.Ldebug_info_dwo_end2:
|
||||
.section .debug_abbrev.dwo,"e",@progbits
|
||||
.byte 1 # Abbreviation Code
|
||||
.byte 17 # DW_TAG_compile_unit
|
||||
.byte 0 # DW_CHILDREN_no
|
||||
.byte 0 # EOM(1)
|
||||
.byte 0 # EOM(2)
|
||||
.byte 2 # Abbreviation Code
|
||||
.byte 65 # DW_TAG_type_unit
|
||||
.byte 1 # DW_CHILDREN_yes
|
||||
.byte 0 # EOM
|
||||
.byte 0 # EOM
|
||||
.byte 4 # Abbreviation Code
|
||||
.byte 65 # DW_TAG_type_unit
|
||||
.byte 1 # DW_CHILDREN_yes
|
||||
.byte 0 # EOM
|
||||
.byte 0 # EOM
|
||||
.byte 0 # EOM
|
|
@ -0,0 +1,11 @@
|
|||
# This test checks if llvm-dwp can deduplicate tu units (v5).
|
||||
|
||||
# RUN: llvm-mc -triple x86_64-unknown-linux %p/../Inputs/type_dedup_v5/a.s -filetype=obj -o a.o \
|
||||
# RUN: -split-dwarf-file=a.dwo -dwarf-version=5
|
||||
# RUN: llvm-mc -triple x86_64-unknown-linux %p/../Inputs/type_dedup_v5/b.s -filetype=obj -o b.o \
|
||||
# RUN: -split-dwarf-file=b.dwo -dwarf-version=5
|
||||
# RUN: llvm-dwp a.dwo b.dwo -o %t.dwp
|
||||
# RUN: llvm-dwarfdump -debug-tu-index %t.dwp | FileCheck %s
|
||||
|
||||
# CHECK_DAG: .debug_tu_index contents:
|
||||
# CHECK: version = 5, units = 1, slots = 2
|
|
@ -361,10 +361,12 @@ static StringRef getSubsection(StringRef Section,
|
|||
return Section.substr(Off->Offset, Off->Length);
|
||||
}
|
||||
|
||||
static void addAllTypesFromDWP(
|
||||
MCStreamer &Out, MapVector<uint64_t, UnitIndexEntry> &TypeIndexEntries,
|
||||
const DWARFUnitIndex &TUIndex, MCSection *OutputTypes, StringRef Types,
|
||||
const UnitIndexEntry &TUEntry, uint32_t &TypesOffset) {
|
||||
static void
|
||||
addAllTypesFromDWP(MCStreamer &Out,
|
||||
MapVector<uint64_t, UnitIndexEntry> &TypeIndexEntries,
|
||||
const DWARFUnitIndex &TUIndex, MCSection *OutputTypes,
|
||||
StringRef Types, const UnitIndexEntry &TUEntry,
|
||||
uint32_t &TypesOffset, unsigned TypesContributionIndex) {
|
||||
Out.SwitchSection(OutputTypes);
|
||||
for (const DWARFUnitIndex::Entry &E : TUIndex.getRows()) {
|
||||
auto *I = E.getContributions();
|
||||
|
@ -385,21 +387,19 @@ static void addAllTypesFromDWP(
|
|||
C.Length = I->Length;
|
||||
++I;
|
||||
}
|
||||
unsigned TypesIndex =
|
||||
getContributionIndex(DW_SECT_EXT_TYPES, TUIndex.getVersion());
|
||||
auto &C = Entry.Contributions[TypesIndex];
|
||||
auto &C = Entry.Contributions[TypesContributionIndex];
|
||||
Out.emitBytes(Types.substr(
|
||||
C.Offset - TUEntry.Contributions[TypesIndex].Offset, C.Length));
|
||||
C.Offset - TUEntry.Contributions[TypesContributionIndex].Offset,
|
||||
C.Length));
|
||||
C.Offset = TypesOffset;
|
||||
TypesOffset += C.Length;
|
||||
}
|
||||
}
|
||||
|
||||
static void addAllTypes(MCStreamer &Out,
|
||||
MapVector<uint64_t, UnitIndexEntry> &TypeIndexEntries,
|
||||
MCSection *OutputTypes,
|
||||
const std::vector<StringRef> &TypesSections,
|
||||
const UnitIndexEntry &CUEntry, uint32_t &TypesOffset) {
|
||||
static void addAllTypesFromTypesSection(
|
||||
MCStreamer &Out, MapVector<uint64_t, UnitIndexEntry> &TypeIndexEntries,
|
||||
MCSection *OutputTypes, const std::vector<StringRef> &TypesSections,
|
||||
const UnitIndexEntry &CUEntry, uint32_t &TypesOffset) {
|
||||
for (StringRef Types : TypesSections) {
|
||||
Out.SwitchSection(OutputTypes);
|
||||
uint64_t Offset = 0;
|
||||
|
@ -748,8 +748,6 @@ static Error write(MCStreamer &Out, ArrayRef<std::string> Inputs) {
|
|||
bool FoundCUUnit = false;
|
||||
Out.SwitchSection(InfoSection);
|
||||
for (StringRef Info : CurInfoSection) {
|
||||
if (FoundCUUnit)
|
||||
break;
|
||||
uint64_t UnitOffset = 0;
|
||||
while (Info.size() > UnitOffset) {
|
||||
Expected<InfoSectionUnitHeader> HeaderOrError =
|
||||
|
@ -763,12 +761,13 @@ static Error write(MCStreamer &Out, ArrayRef<std::string> Inputs) {
|
|||
IndexVersion)];
|
||||
C.Offset = InfoSectionOffset;
|
||||
C.Length = Header.Length + 4;
|
||||
|
||||
UnitOffset += C.Length;
|
||||
if (Header.Version < 5 ||
|
||||
Header.UnitType == dwarf::DW_UT_split_compile) {
|
||||
Expected<CompileUnitIdentifiers> EID = getCUIdentifiers(
|
||||
Header, AbbrevSection, Info.substr(UnitOffset, C.Length),
|
||||
CurStrOffsetSection, CurStrSection);
|
||||
Expected<CompileUnitIdentifiers> EID =
|
||||
getCUIdentifiers(Header, AbbrevSection,
|
||||
Info.substr(UnitOffset - C.Length, C.Length),
|
||||
CurStrOffsetSection, CurStrSection);
|
||||
|
||||
if (!EID)
|
||||
return createFileError(Input, EID.takeError());
|
||||
|
@ -779,12 +778,15 @@ static Error write(MCStreamer &Out, ArrayRef<std::string> Inputs) {
|
|||
P.first->second.Name = ID.Name;
|
||||
P.first->second.DWOName = ID.DWOName;
|
||||
|
||||
Out.emitBytes(Info.substr(UnitOffset, C.Length));
|
||||
InfoSectionOffset += C.Length;
|
||||
FoundCUUnit = true;
|
||||
break;
|
||||
} else if (Header.UnitType == dwarf::DW_UT_split_type) {
|
||||
auto P = TypeIndexEntries.insert(
|
||||
std::make_pair(Header.Signature.getValue(), Entry));
|
||||
if (!P.second)
|
||||
continue;
|
||||
}
|
||||
UnitOffset += Header.Length + 4;
|
||||
Out.emitBytes(Info.substr(UnitOffset - C.Length, C.Length));
|
||||
InfoSectionOffset += C.Length;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -793,7 +795,7 @@ static Error write(MCStreamer &Out, ArrayRef<std::string> Inputs) {
|
|||
|
||||
if (IndexVersion == 2) {
|
||||
// Add types from the .debug_types section from DWARF < 5.
|
||||
addAllTypes(
|
||||
addAllTypesFromTypesSection(
|
||||
Out, TypeIndexEntries, TypesSection, CurTypesSection, CurEntry,
|
||||
ContributionOffsets[getContributionIndex(DW_SECT_EXT_TYPES, 2)]);
|
||||
}
|
||||
|
@ -858,21 +860,41 @@ static Error write(MCStreamer &Out, ArrayRef<std::string> Inputs) {
|
|||
InfoSectionOffset += C.Length;
|
||||
}
|
||||
|
||||
if (!CurTypesSection.empty()) {
|
||||
if (CurTypesSection.size() != 1)
|
||||
return make_error<DWPError>("multiple type unit sections in .dwp file");
|
||||
DWARFUnitIndex TUIndex(DW_SECT_EXT_TYPES);
|
||||
if (!CurTUIndexSection.empty()) {
|
||||
llvm::DWARFSectionKind TUSectionKind;
|
||||
MCSection *OutSection;
|
||||
StringRef TypeInputSection;
|
||||
// Write type units into debug info section for DWARFv5.
|
||||
if (Version >= 5) {
|
||||
TUSectionKind = DW_SECT_INFO;
|
||||
OutSection = InfoSection;
|
||||
TypeInputSection = DwpSingleInfoSection;
|
||||
} else {
|
||||
// Write type units into debug types section for DWARF < 5.
|
||||
if (CurTypesSection.size() != 1)
|
||||
return make_error<DWPError>(
|
||||
"multiple type unit sections in .dwp file");
|
||||
|
||||
TUSectionKind = DW_SECT_EXT_TYPES;
|
||||
OutSection = TypesSection;
|
||||
TypeInputSection = CurTypesSection.front();
|
||||
}
|
||||
|
||||
DWARFUnitIndex TUIndex(TUSectionKind);
|
||||
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>("expected index version 2, but got: " +
|
||||
utostr(TUIndex.getVersion()));
|
||||
if (TUIndex.getVersion() != IndexVersion)
|
||||
return make_error<DWPError>("incompatible tu_index versions, found " +
|
||||
utostr(TUIndex.getVersion()) +
|
||||
" and expecting " + utostr(IndexVersion));
|
||||
|
||||
addAllTypesFromDWP(
|
||||
Out, TypeIndexEntries, TUIndex, TypesSection, CurTypesSection.front(),
|
||||
CurEntry,
|
||||
ContributionOffsets[getContributionIndex(DW_SECT_EXT_TYPES, 2)]);
|
||||
unsigned TypesContributionIndex =
|
||||
getContributionIndex(TUSectionKind, IndexVersion);
|
||||
addAllTypesFromDWP(Out, TypeIndexEntries, TUIndex, OutSection,
|
||||
TypeInputSection, CurEntry,
|
||||
ContributionOffsets[TypesContributionIndex],
|
||||
TypesContributionIndex);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue