304 changes: 304 additions & 0 deletions bolt/test/X86/dwarf5-shared-str-offset-base.s
Original file line number Diff line number Diff line change
@@ -0,0 +1,304 @@
# REQUIRES: system-linux

# RUN: llvm-mc --filetype=obj --triple x86_64 %s -o %tmain.o --defsym MAIN=0
# RUN: llvm-mc --filetype=obj --triple x86_64 %s -o %thelper.o
# RUN: %clang %cflags %tmain.o %thelper.o -o %tmain.exe
# RUN: llvm-bolt %tmain.exe -o %tmain.exe.bolt --update-debug-sections
# RUN: llvm-dwarfdump --debug-info %tmain.exe.bolt > %tout.text
# RUN: llvm-dwarfdump --show-section-sizes %tmain.exe >> %tout.text
# RUN: llvm-dwarfdump --show-section-sizes %tmain.exe.bolt >> %tout.text
# RUN: cat %tout.text | FileCheck %s

# This test checks that with DWARF5 when two CUs share the same .debug_str_offsets
# entry BOLT does not create a duplicate.

# CHECK: DW_AT_str_offsets_base (0x[[#%.8x,ADDR:]]
# CHECK: DW_AT_str_offsets_base (0x[[#ADDR]]

# CHECK: .debug_str_offsets [[#ADDR2:]]
# CHECK: .debug_str_offsets [[#ADDR2]]

# main.cpp
# int main(){
# return 0;
# }

# helper.cpp
# void foo(){}

## Create two CUs, with dwo_ids 0 and 1 respectively.
.ifdef MAIN
.text
.file "main.cpp"
.globl main # -- Begin function main
.p2align 4, 0x90
.type main,@function
main: # @main
.Lfunc_begin0:
.file 0 "." "main.cpp" md5 0x32c197b0a8b855eb3d7573c993ada862
.loc 0 1 0 # main.cpp:1:0
.cfi_startproc
# %bb.0:
pushq %rbp
.cfi_def_cfa_offset 16
.cfi_offset %rbp, -16
movq %rsp, %rbp
.cfi_def_cfa_register %rbp
movl $0, -4(%rbp)
.Ltmp0:
.loc 0 2 1 prologue_end # main.cpp:2:1
xorl %eax, %eax
popq %rbp
.cfi_def_cfa %rsp, 8
retq
.Ltmp1:
.Lfunc_end0:
.size main, .Lfunc_end0-main
.cfi_endproc
# -- End function
.section .debug_abbrev,"",@progbits
.byte 1 # Abbreviation Code
.byte 17 # DW_TAG_compile_unit
.byte 1 # DW_CHILDREN_yes
.byte 37 # DW_AT_producer
.byte 37 # DW_FORM_strx1
.byte 19 # DW_AT_language
.byte 5 # DW_FORM_data2
.byte 3 # DW_AT_name
.byte 37 # DW_FORM_strx1
.byte 114 # DW_AT_str_offsets_base
.byte 23 # DW_FORM_sec_offset
.byte 16 # DW_AT_stmt_list
.byte 23 # DW_FORM_sec_offset
.byte 27 # DW_AT_comp_dir
.byte 37 # DW_FORM_strx1
.byte 17 # DW_AT_low_pc
.byte 27 # DW_FORM_addrx
.byte 18 # DW_AT_high_pc
.byte 6 # DW_FORM_data4
.byte 115 # DW_AT_addr_base
.byte 23 # DW_FORM_sec_offset
.byte 0 # EOM(1)
.byte 0 # EOM(2)
.byte 2 # Abbreviation Code
.byte 46 # DW_TAG_subprogram
.byte 0 # DW_CHILDREN_no
.byte 17 # DW_AT_low_pc
.byte 27 # DW_FORM_addrx
.byte 18 # DW_AT_high_pc
.byte 6 # DW_FORM_data4
.byte 64 # DW_AT_frame_base
.byte 24 # DW_FORM_exprloc
.byte 3 # DW_AT_name
.byte 37 # DW_FORM_strx1
.byte 58 # DW_AT_decl_file
.byte 11 # DW_FORM_data1
.byte 59 # DW_AT_decl_line
.byte 11 # DW_FORM_data1
.byte 73 # DW_AT_type
.byte 19 # DW_FORM_ref4
.byte 63 # DW_AT_external
.byte 25 # DW_FORM_flag_present
.byte 0 # EOM(1)
.byte 0 # EOM(2)
.byte 3 # Abbreviation Code
.byte 36 # DW_TAG_base_type
.byte 0 # DW_CHILDREN_no
.byte 3 # DW_AT_name
.byte 37 # DW_FORM_strx1
.byte 62 # DW_AT_encoding
.byte 11 # DW_FORM_data1
.byte 11 # DW_AT_byte_size
.byte 11 # DW_FORM_data1
.byte 0 # EOM(1)
.byte 0 # EOM(2)
.byte 0 # EOM(3)
.section .debug_info,"",@progbits
.Lcu_begin0:
.long .Ldebug_info_end0-.Ldebug_info_start0 # Length of Unit
.Ldebug_info_start0:
.short 5 # DWARF version number
.byte 1 # DWARF Unit Type
.byte 8 # Address Size (in bytes)
.long .debug_abbrev # Offset Into Abbrev. Section
.byte 1 # Abbrev [1] 0xc:0x2b DW_TAG_compile_unit
.byte 0 # DW_AT_producer
.short 33 # DW_AT_language
.byte 1 # DW_AT_name
.long .Lstr_offsets_base0 # DW_AT_str_offsets_base
.long .Lline_table_start0 # DW_AT_stmt_list
.byte 2 # DW_AT_comp_dir
.byte 0 # DW_AT_low_pc
.long .Lfunc_end0-.Lfunc_begin0 # DW_AT_high_pc
.long .Laddr_table_base0 # DW_AT_addr_base
.byte 2 # Abbrev [2] 0x23:0xf DW_TAG_subprogram
.byte 0 # DW_AT_low_pc
.long .Lfunc_end0-.Lfunc_begin0 # DW_AT_high_pc
.byte 1 # DW_AT_frame_base
.byte 86
.byte 3 # DW_AT_name
.byte 0 # DW_AT_decl_file
.byte 1 # DW_AT_decl_line
.long 50 # DW_AT_type
# DW_AT_external
.byte 3 # Abbrev [3] 0x32:0x4 DW_TAG_base_type
.byte 4 # DW_AT_name
.byte 5 # DW_AT_encoding
.byte 4 # DW_AT_byte_size
.byte 0 # End Of Children Mark
.Ldebug_info_end0:
.section .debug_str_offsets,"",@progbits
.long 24 # Length of String Offsets Set
.short 5
.short 0
.Lstr_offsets_base0:
.section .debug_str,"MS",@progbits,1
.Linfo_string0:
.asciz "clang version 15.0.0" # string offset=0
.Linfo_string1:
.asciz "main.cpp" # string offset=146
.Linfo_string2:
.asciz "." # string offset=155
.Linfo_string3:
.asciz "main" # string offset=198
.Linfo_string4:
.asciz "int" # string offset=203
.section .debug_str_offsets,"",@progbits
.long .Linfo_string0
.long .Linfo_string1
.long .Linfo_string2
.long .Linfo_string3
.long .Linfo_string4
.section .debug_addr,"",@progbits
.long .Ldebug_addr_end0-.Ldebug_addr_start0 # Length of contribution
.Ldebug_addr_start0:
.short 5 # DWARF version number
.byte 8 # Address size
.byte 0 # Segment selector size
.Laddr_table_base0:
.quad .Lfunc_begin0
.Ldebug_addr_end0:
.ident "clang version 15.0.0"
.section ".note.GNU-stack","",@progbits
.addrsig
.section .debug_line,"",@progbits
.Lline_table_start0:
.else
.text
.file "helper.cpp"
.globl _Z3foov # -- Begin function _Z3foov
.p2align 4, 0x90
.type _Z3foov,@function
_Z3foov: # @_Z3foov
.Lfunc_begin0:
.file 0 "." "helper.cpp" md5 0x5f98e4807e4f8781c26a82faf819f8a7
.loc 0 1 0 # helper.cpp:1:0
.cfi_startproc
# %bb.0:
pushq %rbp
.cfi_def_cfa_offset 16
.cfi_offset %rbp, -16
movq %rsp, %rbp
.cfi_def_cfa_register %rbp
.Ltmp0:
.loc 0 1 12 prologue_end # helper.cpp:1:12
popq %rbp
.cfi_def_cfa %rsp, 8
retq
.Ltmp1:
.Lfunc_end0:
.size _Z3foov, .Lfunc_end0-_Z3foov
.cfi_endproc
# -- End function
.section .debug_abbrev,"",@progbits
.byte 1 # Abbreviation Code
.byte 17 # DW_TAG_compile_unit
.byte 1 # DW_CHILDREN_yes
.byte 37 # DW_AT_producer
.byte 37 # DW_FORM_strx1
.byte 19 # DW_AT_language
.byte 5 # DW_FORM_data2
.byte 3 # DW_AT_name
.byte 37 # DW_FORM_strx1
.byte 114 # DW_AT_str_offsets_base
.byte 23 # DW_FORM_sec_offset
.byte 16 # DW_AT_stmt_list
.byte 23 # DW_FORM_sec_offset
.byte 27 # DW_AT_comp_dir
.byte 37 # DW_FORM_strx1
.byte 17 # DW_AT_low_pc
.byte 27 # DW_FORM_addrx
.byte 18 # DW_AT_high_pc
.byte 6 # DW_FORM_data4
.byte 115 # DW_AT_addr_base
.byte 23 # DW_FORM_sec_offset
.byte 0 # EOM(1)
.byte 0 # EOM(2)
.byte 2 # Abbreviation Code
.byte 46 # DW_TAG_subprogram
.byte 0 # DW_CHILDREN_no
.byte 17 # DW_AT_low_pc
.byte 27 # DW_FORM_addrx
.byte 18 # DW_AT_high_pc
.byte 6 # DW_FORM_data4
.byte 64 # DW_AT_frame_base
.byte 24 # DW_FORM_exprloc
.byte 110 # DW_AT_linkage_name
.byte 37 # DW_FORM_strx1
.byte 3 # DW_AT_name
.byte 37 # DW_FORM_strx1
.byte 58 # DW_AT_decl_file
.byte 11 # DW_FORM_data1
.byte 59 # DW_AT_decl_line
.byte 11 # DW_FORM_data1
.byte 63 # DW_AT_external
.byte 25 # DW_FORM_flag_present
.byte 0 # EOM(1)
.byte 0 # EOM(2)
.byte 0 # EOM(3)
.section .debug_info,"",@progbits
.Lcu_begin0:
.long .Ldebug_info_end0-.Ldebug_info_start0 # Length of Unit
.Ldebug_info_start0:
.short 5 # DWARF version number
.byte 1 # DWARF Unit Type
.byte 8 # Address Size (in bytes)
.long .debug_abbrev # Offset Into Abbrev. Section
.byte 1 # Abbrev [1] 0xc:0x24 DW_TAG_compile_unit
.byte 0 # DW_AT_producer
.short 33 # DW_AT_language
.byte 1 # DW_AT_name
.long 0x8 # DW_AT_str_offsets_base Manually modified to be the same as first CU
.long .Lline_table_start0 # DW_AT_stmt_list
.byte 2 # DW_AT_comp_dir
.byte 0 # DW_AT_low_pc
.long .Lfunc_end0-.Lfunc_begin0 # DW_AT_high_pc
.long .Laddr_table_base0 # DW_AT_addr_base
.byte 2 # Abbrev [2] 0x23:0xc DW_TAG_subprogram
.byte 0 # DW_AT_low_pc
.long .Lfunc_end0-.Lfunc_begin0 # DW_AT_high_pc
.byte 1 # DW_AT_frame_base
.byte 86
.byte 3 # DW_AT_linkage_name
.byte 4 # DW_AT_name
.byte 0 # DW_AT_decl_file
.byte 1 # DW_AT_decl_line
# DW_AT_external
.byte 0 # End Of Children Mark
.Ldebug_info_end0:
# Manually removed .debug_str_offsets and .debug_str
.section .debug_addr,"",@progbits
.long .Ldebug_addr_end0-.Ldebug_addr_start0 # Length of contribution
.Ldebug_addr_start0:
.short 5 # DWARF version number
.byte 8 # Address size
.byte 0 # Segment selector size
.Laddr_table_base0:
.quad .Lfunc_begin0
.Ldebug_addr_end0:
.ident "clang version 15.0.0"
.section ".note.GNU-stack","",@progbits
.addrsig
.section .debug_line,"",@progbits
.Lline_table_start0:
.endif
16 changes: 8 additions & 8 deletions lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -335,7 +335,7 @@ void DWARFUnit::SetDwoStrOffsetsBase() {
if (const llvm::DWARFUnitIndex::Entry *entry = m_header.GetIndexEntry()) {
if (const auto *contribution =
entry->getContribution(llvm::DW_SECT_STR_OFFSETS))
baseOffset = contribution->Offset;
baseOffset = contribution->getOffset32();
else
return;
}
Expand Down Expand Up @@ -483,7 +483,7 @@ void DWARFUnit::SetLoclistsBase(dw_addr_t loclists_base) {
*GetDWOId());
return;
}
offset += contribution->Offset;
offset += contribution->getOffset32();
}
m_loclists_base = loclists_base;

Expand Down Expand Up @@ -521,8 +521,8 @@ DWARFDataExtractor DWARFUnit::GetLocationData() const {
if (const llvm::DWARFUnitIndex::Entry *entry = m_header.GetIndexEntry()) {
if (const auto *contribution = entry->getContribution(
GetVersion() >= 5 ? llvm::DW_SECT_LOCLISTS : llvm::DW_SECT_EXT_LOC))
return DWARFDataExtractor(data, contribution->Offset,
contribution->Length);
return DWARFDataExtractor(data, contribution->getOffset32(),
contribution->getLength32());
return DWARFDataExtractor();
}
return data;
Expand All @@ -534,8 +534,8 @@ DWARFDataExtractor DWARFUnit::GetRnglistData() const {
if (const llvm::DWARFUnitIndex::Entry *entry = m_header.GetIndexEntry()) {
if (const auto *contribution =
entry->getContribution(llvm::DW_SECT_RNGLISTS))
return DWARFDataExtractor(data, contribution->Offset,
contribution->Length);
return DWARFDataExtractor(data, contribution->getOffset32(),
contribution->getLength32());
GetSymbolFileDWARF().GetObjectFile()->GetModule()->ReportError(
"Failed to find range list contribution for CU with signature "
"0x%" PRIx64,
Expand Down Expand Up @@ -916,7 +916,7 @@ DWARFUnitHeader::extract(const DWARFDataExtractor &data,
"Package unit with a non-zero abbreviation offset");
}
auto *unit_contrib = header.m_index_entry->getContribution();
if (!unit_contrib || unit_contrib->Length != header.m_length + 4) {
if (!unit_contrib || unit_contrib->getLength32() != header.m_length + 4) {
return llvm::createStringError(llvm::inconvertibleErrorCode(),
"Inconsistent DWARF package unit index");
}
Expand All @@ -927,7 +927,7 @@ DWARFUnitHeader::extract(const DWARFDataExtractor &data,
llvm::inconvertibleErrorCode(),
"DWARF package index missing abbreviation column");
}
header.m_abbr_offset = abbr_entry->Offset;
header.m_abbr_offset = abbr_entry->getOffset32();
}

bool length_OK = data.ValidOffset(header.GetNextUnitOffset() - 1);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ DWARFCompileUnit *SymbolFileDWARFDwo::GetDWOCompileUnitForHash(uint64_t hash) {
if (auto *unit_contrib = entry->getContribution())
return llvm::dyn_cast_or_null<DWARFCompileUnit>(
DebugInfo().GetUnitAtOffset(DIERef::Section::DebugInfo,
unit_contrib->Offset));
unit_contrib->getOffset32()));
}
return nullptr;
}
Expand Down
12 changes: 12 additions & 0 deletions llvm/include/llvm/DebugInfo/DWARF/DWARFContext.h
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,10 @@ class DWARFContext : public DIContext {
MacroDwoSection
};

// When set parses debug_info.dwo/debug_abbrev.dwo manually and populates CU
// Index, and TU Index for DWARF5.
bool ParseCUTUIndexManually;

public:
DWARFContext(std::unique_ptr<const DWARFObject> DObj,
std::string DWPName = "",
Expand Down Expand Up @@ -454,6 +458,14 @@ class DWARFContext : public DIContext {
/// into "SectionedAddress Address"
DWARFCompileUnit *getCompileUnitForAddress(uint64_t Address);

/// Returns whether CU/TU should be populated manually. TU Index populated
/// manually only for DWARF5.
bool getParseCUTUIndexManually() const { return ParseCUTUIndexManually; }

/// Sets whether CU/TU should be populated manually. TU Index populated
/// manually only for DWARF5.
void setParseCUTUIndexManually(bool PCUTU) { ParseCUTUIndexManually = PCUTU; }

private:
/// Parse a macro[.dwo] or macinfo[.dwo] section.
std::unique_ptr<DWARFDebugMacro>
Expand Down
2 changes: 1 addition & 1 deletion llvm/include/llvm/DebugInfo/DWARF/DWARFUnit.h
Original file line number Diff line number Diff line change
Expand Up @@ -536,7 +536,7 @@ class DWARFUnit {
uint32_t getLineTableOffset() const {
if (auto IndexEntry = Header.getIndexEntry())
if (const auto *Contrib = IndexEntry->getContribution(DW_SECT_LINE))
return Contrib->Offset;
return Contrib->getOffset32();
return 0;
}

Expand Down
38 changes: 34 additions & 4 deletions llvm/include/llvm/DebugInfo/DWARF/DWARFUnitIndex.h
Original file line number Diff line number Diff line change
Expand Up @@ -110,9 +110,33 @@ class DWARFUnitIndex {
public:
class Entry {
public:
struct SectionContribution {
uint32_t Offset;
uint32_t Length;
class SectionContribution {
private:
uint64_t Fields[2];

public:
static constexpr unsigned OffsetFieldIndex = 0;
static constexpr unsigned LengthFieldIndex = 1;
SectionContribution() { memset(&Fields, 0, sizeof(Fields)); }
SectionContribution(uint64_t Offset, uint64_t Length) {
Fields[OffsetFieldIndex] = Offset;
Fields[LengthFieldIndex] = Length;
}

void setField(unsigned Index, uint64_t Value) { Fields[Index] = Value; }
void setOffset(uint64_t Value) { Fields[OffsetFieldIndex] = Value; }
void setLength(uint64_t Value) { Fields[LengthFieldIndex] = Value; }
uint64_t getField32(unsigned Index) const {
return (uint32_t)Fields[Index];
}
uint64_t getOffset() const { return Fields[OffsetFieldIndex]; }
uint64_t getLength() const { return Fields[LengthFieldIndex]; }
uint32_t getOffset32() const {
return (uint32_t)Fields[OffsetFieldIndex];
}
uint32_t getLength32() const {
return (uint32_t)Fields[LengthFieldIndex];
}
};

private:
Expand All @@ -124,12 +148,14 @@ class DWARFUnitIndex {
public:
const SectionContribution *getContribution(DWARFSectionKind Sec) const;
const SectionContribution *getContribution() const;
SectionContribution &getContribution();

const SectionContribution *getContributions() const {
return Contributions.get();
}

uint64_t getSignature() const { return Signature; }
bool isValid() { return Index; }
};

private:
Expand Down Expand Up @@ -160,7 +186,7 @@ class DWARFUnitIndex {

uint32_t getVersion() const { return Header.Version; }

const Entry *getFromOffset(uint32_t Offset) const;
const Entry *getFromOffset(uint64_t Offset) const;
const Entry *getFromHash(uint64_t Offset) const;

ArrayRef<DWARFSectionKind> getColumnKinds() const {
Expand All @@ -170,6 +196,10 @@ class DWARFUnitIndex {
ArrayRef<Entry> getRows() const {
return makeArrayRef(Rows.get(), Header.NumBuckets);
}

MutableArrayRef<Entry> getMutableRows() {
return makeMutableArrayRef(Rows.get(), Header.NumBuckets);
}
};

} // end namespace llvm
Expand Down
73 changes: 37 additions & 36 deletions llvm/lib/DWP/DWP.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -175,7 +175,7 @@ static StringRef getSubsection(StringRef Section,
const auto *Off = Entry.getContribution(Kind);
if (!Off)
return StringRef();
return Section.substr(Off->Offset, Off->Length);
return Section.substr(Off->getOffset(), Off->getLength());
}

static void
Expand All @@ -200,16 +200,17 @@ addAllTypesFromDWP(MCStreamer &Out,
continue;
auto &C =
Entry.Contributions[getContributionIndex(Kind, TUIndex.getVersion())];
C.Offset += I->Offset;
C.Length = I->Length;
C.setOffset(C.getOffset() + I->getOffset());
C.setLength(I->getLength());
++I;
}
auto &C = Entry.Contributions[TypesContributionIndex];
Out.emitBytes(Types.substr(
C.Offset - TUEntry.Contributions[TypesContributionIndex].Offset,
C.Length));
C.Offset = TypesOffset;
TypesOffset += C.Length;
C.getOffset() -
TUEntry.Contributions[TypesContributionIndex].getOffset(),
C.getLength()));
C.setOffset(TypesOffset);
TypesOffset += C.getLength();
}
}

Expand All @@ -226,23 +227,23 @@ static void addAllTypesFromTypesSection(
// Zero out the debug_info contribution
Entry.Contributions[0] = {};
auto &C = Entry.Contributions[getContributionIndex(DW_SECT_EXT_TYPES, 2)];
C.Offset = TypesOffset;
C.setOffset(TypesOffset);
auto PrevOffset = Offset;
// Length of the unit, including the 4 byte length field.
C.Length = Data.getU32(&Offset) + 4;
C.setLength(Data.getU32(&Offset) + 4);

Data.getU16(&Offset); // Version
Data.getU32(&Offset); // Abbrev offset
Data.getU8(&Offset); // Address size
auto Signature = Data.getU64(&Offset);
Offset = PrevOffset + C.Length;
Offset = PrevOffset + C.getLength32();

auto P = TypeIndexEntries.insert(std::make_pair(Signature, Entry));
if (!P.second)
continue;

Out.emitBytes(Types.substr(PrevOffset, C.Length));
TypesOffset += C.Length;
Out.emitBytes(Types.substr(PrevOffset, C.getLength32()));
TypesOffset += C.getLength32();
}
}
}
Expand Down Expand Up @@ -402,14 +403,13 @@ void writeStringsAndOffsets(MCStreamer &Out, DWPStringPool &Strings,
}
}

void writeIndexTable(
MCStreamer &Out, ArrayRef<unsigned> ContributionOffsets,
const MapVector<uint64_t, UnitIndexEntry> &IndexEntries,
uint32_t DWARFUnitIndex::Entry::SectionContribution::*Field) {
void writeIndexTable(MCStreamer &Out, ArrayRef<unsigned> ContributionOffsets,
const MapVector<uint64_t, UnitIndexEntry> &IndexEntries,
unsigned Index) {
for (const auto &E : IndexEntries)
for (size_t I = 0; I != std::size(E.second.Contributions); ++I)
if (ContributionOffsets[I])
Out.emitIntValue(E.second.Contributions[I].*Field, 4);
Out.emitIntValue((E.second.Contributions[I].getField32(Index)), 4);
}

void writeIndex(MCStreamer &Out, MCSection *Section,
Expand Down Expand Up @@ -461,11 +461,11 @@ void writeIndex(MCStreamer &Out, MCSection *Section,

// Write the offsets.
writeIndexTable(Out, ContributionOffsets, IndexEntries,
&DWARFUnitIndex::Entry::SectionContribution::Offset);
DWARFUnitIndex::Entry::SectionContribution::OffsetFieldIndex);

// Write the lengths.
writeIndexTable(Out, ContributionOffsets, IndexEntries,
&DWARFUnitIndex::Entry::SectionContribution::Length);
DWARFUnitIndex::Entry::SectionContribution::LengthFieldIndex);
}

Error buildDuplicateError(const std::pair<uint64_t, UnitIndexEntry> &PrevE,
Expand Down Expand Up @@ -642,9 +642,9 @@ Error write(MCStreamer &Out, ArrayRef<std::string> Inputs) {

for (auto Pair : SectionLength) {
auto Index = getContributionIndex(Pair.first, IndexVersion);
CurEntry.Contributions[Index].Offset = ContributionOffsets[Index];
ContributionOffsets[Index] +=
(CurEntry.Contributions[Index].Length = Pair.second);
CurEntry.Contributions[Index].setOffset(ContributionOffsets[Index]);
CurEntry.Contributions[Index].setLength(Pair.second);
ContributionOffsets[Index] += CurEntry.Contributions[Index].getLength32();
}

uint32_t &InfoSectionOffset =
Expand All @@ -664,21 +664,21 @@ Error write(MCStreamer &Out, ArrayRef<std::string> Inputs) {
UnitIndexEntry Entry = CurEntry;
auto &C = Entry.Contributions[getContributionIndex(DW_SECT_INFO,
IndexVersion)];
C.Offset = InfoSectionOffset;
C.Length = Header.Length + 4;
C.setOffset(InfoSectionOffset);
C.setLength(Header.Length + 4);

if (std::numeric_limits<uint32_t>::max() - InfoSectionOffset <
C.Length)
C.getLength32())
return make_error<DWPError>(
"debug information section offset is greater than 4GB");

UnitOffset += C.Length;
UnitOffset += C.getLength32();
if (Header.Version < 5 ||
Header.UnitType == dwarf::DW_UT_split_compile) {
Expected<CompileUnitIdentifiers> EID =
getCUIdentifiers(Header, AbbrevSection,
Info.substr(UnitOffset - C.Length, C.Length),
CurStrOffsetSection, CurStrSection);
Expected<CompileUnitIdentifiers> EID = getCUIdentifiers(
Header, AbbrevSection,
Info.substr(UnitOffset - C.getLength32(), C.getLength32()),
CurStrOffsetSection, CurStrSection);

if (!EID)
return createFileError(Input, EID.takeError());
Expand All @@ -696,8 +696,9 @@ Error write(MCStreamer &Out, ArrayRef<std::string> Inputs) {
if (!P.second)
continue;
}
Out.emitBytes(Info.substr(UnitOffset - C.Length, C.Length));
InfoSectionOffset += C.Length;
Out.emitBytes(
Info.substr(UnitOffset - C.getLength32(), C.getLength32()));
InfoSectionOffset += C.getLength32();
}
}

Expand Down Expand Up @@ -760,15 +761,15 @@ Error write(MCStreamer &Out, ArrayRef<std::string> Inputs) {
continue;
auto &C =
NewEntry.Contributions[getContributionIndex(Kind, IndexVersion)];
C.Offset += I->Offset;
C.Length = I->Length;
C.setOffset(C.getOffset() + I->getOffset());
C.setLength(I->getLength());
++I;
}
unsigned Index = getContributionIndex(DW_SECT_INFO, IndexVersion);
auto &C = NewEntry.Contributions[Index];
Out.emitBytes(CUInfoSection);
C.Offset = InfoSectionOffset;
InfoSectionOffset += C.Length;
C.setOffset(InfoSectionOffset);
InfoSectionOffset += C.getLength32();
}

if (!CurTUIndexSection.empty()) {
Expand Down
75 changes: 73 additions & 2 deletions llvm/lib/DebugInfo/DWARF/DWARFContext.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -782,14 +782,82 @@ bool DWARFContext::verify(raw_ostream &OS, DIDumpOptions DumpOpts) {
return Success;
}

void fixupIndex(const DWARFObject &DObj, DWARFContext &C,
DWARFUnitIndex &Index) {
using EntryType = DWARFUnitIndex::Entry::SectionContribution;
using EntryMap = DenseMap<uint32_t, EntryType>;
EntryMap Map;
if (DObj.getCUIndexSection().empty())
return;

uint64_t Offset = 0;
uint32_t TruncOffset = 0;
DObj.forEachInfoDWOSections([&](const DWARFSection &S) {
if (!(C.getParseCUTUIndexManually() ||
S.Data.size() >= std::numeric_limits<uint32_t>::max()))
return;

DWARFDataExtractor Data(DObj, S, C.isLittleEndian(), 0);
while (Data.isValidOffset(Offset)) {
DWARFUnitHeader Header;
if (!Header.extract(C, Data, &Offset, DWARFSectionKind::DW_SECT_INFO)) {
logAllUnhandledErrors(
createError("Failed to parse CU header in DWP file"), errs());
Map.clear();
break;
}

auto Iter = Map.insert({TruncOffset,
{Header.getOffset(), Header.getNextUnitOffset() -
Header.getOffset()}});
if (!Iter.second) {
logAllUnhandledErrors(
createError("Collision occured between for truncated offset 0x" +
Twine::utohexstr(TruncOffset)),
errs());
Map.clear();
return;
}

Offset = Header.getNextUnitOffset();
TruncOffset = Offset;
}
});

if (Map.empty())
return;

for (DWARFUnitIndex::Entry &E : Index.getMutableRows()) {
if (!E.isValid())
continue;
DWARFUnitIndex::Entry::SectionContribution &CUOff = E.getContribution();
auto Iter = Map.find(CUOff.getOffset());
if (Iter == Map.end()) {
logAllUnhandledErrors(createError("Could not find CU offset 0x" +
Twine::utohexstr(CUOff.getOffset()) +
" in the Map"),
errs());
break;
}
CUOff.setOffset(Iter->second.getOffset());
if (CUOff.getOffset() != Iter->second.getOffset())
logAllUnhandledErrors(createError("Length of CU in CU index doesn't "
"match calculated length at offset 0x" +
Twine::utohexstr(CUOff.getOffset())),
errs());
}

return;
}

const DWARFUnitIndex &DWARFContext::getCUIndex() {
if (CUIndex)
return *CUIndex;

DataExtractor CUIndexData(DObj->getCUIndexSection(), isLittleEndian(), 0);

CUIndex = std::make_unique<DWARFUnitIndex>(DW_SECT_INFO);
CUIndex->parse(CUIndexData);
fixupIndex(*DObj, *this, *CUIndex.get());
return *CUIndex;
}

Expand All @@ -798,9 +866,12 @@ const DWARFUnitIndex &DWARFContext::getTUIndex() {
return *TUIndex;

DataExtractor TUIndexData(DObj->getTUIndexSection(), isLittleEndian(), 0);

TUIndex = std::make_unique<DWARFUnitIndex>(DW_SECT_EXT_TYPES);
TUIndex->parse(TUIndexData);
// If we are parsing TU-index and for .debug_types section we don't need
// to do anything.
if (TUIndex->getVersion() != 2)
fixupIndex(*DObj, *this, *TUIndex.get());
return *TUIndex;
}

Expand Down
16 changes: 8 additions & 8 deletions llvm/lib/DebugInfo/DWARF/DWARFUnit.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -160,11 +160,11 @@ DWARFUnitVector::getUnitForIndexEntry(const DWARFUnitIndex::Entry &E) {
if (!CUOff)
return nullptr;

auto Offset = CUOff->Offset;
uint64_t Offset = CUOff->getOffset();
auto end = begin() + getNumInfoUnits();

auto *CU =
std::upper_bound(begin(), end, CUOff->Offset,
std::upper_bound(begin(), end, CUOff->getOffset(),
[](uint64_t LHS, const std::unique_ptr<DWARFUnit> &RHS) {
return LHS < RHS->getNextUnitOffset();
});
Expand Down Expand Up @@ -353,12 +353,12 @@ bool DWARFUnitHeader::applyIndexEntry(const DWARFUnitIndex::Entry *Entry) {
return false;
auto *UnitContrib = IndexEntry->getContribution();
if (!UnitContrib ||
UnitContrib->Length != (getLength() + getUnitLengthFieldByteSize()))
UnitContrib->getLength() != (getLength() + getUnitLengthFieldByteSize()))
return false;
auto *AbbrEntry = IndexEntry->getContribution(DW_SECT_ABBREV);
if (!AbbrEntry)
return false;
AbbrOffset = AbbrEntry->Offset;
AbbrOffset = AbbrEntry->getOffset();
return true;
}

Expand Down Expand Up @@ -544,7 +544,7 @@ Error DWARFUnit::tryExtractDIEsIfNeeded(bool CUDieOnly) {
uint64_t ContributionBaseOffset = 0;
if (auto *IndexEntry = Header.getIndexEntry())
if (auto *Contrib = IndexEntry->getContribution(DW_SECT_RNGLISTS))
ContributionBaseOffset = Contrib->Offset;
ContributionBaseOffset = Contrib->getOffset();
setRangesSection(
&Context.getDWARFObj().getRnglistsDWOSection(),
ContributionBaseOffset +
Expand All @@ -565,7 +565,7 @@ Error DWARFUnit::tryExtractDIEsIfNeeded(bool CUDieOnly) {
if (auto *IndexEntry = Header.getIndexEntry())
if (const auto *C = IndexEntry->getContribution(
Header.getVersion() >= 5 ? DW_SECT_LOCLISTS : DW_SECT_EXT_LOC))
Data = Data.substr(C->Offset, C->Length);
Data = Data.substr(C->getOffset(), C->getLength());

DWARFDataExtractor DWARFData(Data, IsLittleEndian, getAddressByteSize());
LocTable =
Expand Down Expand Up @@ -1156,7 +1156,7 @@ DWARFUnit::determineStringOffsetsTableContributionDWO(DWARFDataExtractor &DA) {
const auto *C =
IndexEntry ? IndexEntry->getContribution(DW_SECT_STR_OFFSETS) : nullptr;
if (C)
Offset = C->Offset;
Offset = C->getOffset();
if (getVersion() >= 5) {
if (DA.getData().data() == nullptr)
return std::nullopt;
Expand All @@ -1172,7 +1172,7 @@ DWARFUnit::determineStringOffsetsTableContributionDWO(DWARFDataExtractor &DA) {
// the length of the string offsets section.
StrOffsetsContributionDescriptor Desc;
if (C)
Desc = StrOffsetsContributionDescriptor(C->Offset, C->Length, 4,
Desc = StrOffsetsContributionDescriptor(C->getOffset(), C->getLength(), 4,
Header.getFormat());
else if (!IndexEntry && !StringOffsetSection.Data.empty())
Desc = StrOffsetsContributionDescriptor(0, StringOffsetSection.Data.size(),
Expand Down
45 changes: 33 additions & 12 deletions llvm/lib/DebugInfo/DWARF/DWARFUnitIndex.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -181,14 +181,14 @@ bool DWARFUnitIndex::parseImpl(DataExtractor IndexData) {
for (unsigned i = 0; i != Header.NumUnits; ++i) {
auto *Contrib = Contribs[i];
for (unsigned i = 0; i != Header.NumColumns; ++i)
Contrib[i].Offset = IndexData.getU32(&Offset);
Contrib[i].setOffset(IndexData.getU32(&Offset));
}

// Read Table of Section Sizes
for (unsigned i = 0; i != Header.NumUnits; ++i) {
auto *Contrib = Contribs[i];
for (unsigned i = 0; i != Header.NumColumns; ++i)
Contrib[i].Length = IndexData.getU32(&Offset);
Contrib[i].setLength(IndexData.getU32(&Offset));
}

return true;
Expand Down Expand Up @@ -222,22 +222,38 @@ void DWARFUnitIndex::dump(raw_ostream &OS) const {
DWARFSectionKind Kind = ColumnKinds[i];
StringRef Name = getColumnHeader(Kind);
if (!Name.empty())
OS << ' ' << left_justify(Name, 24);
OS << ' '
<< left_justify(Name,
Kind == DWARFSectionKind::DW_SECT_INFO ? 40 : 24);
else
OS << format(" Unknown: %-15" PRIu32, RawSectionIds[i]);
}
OS << "\n----- ------------------";
for (unsigned i = 0; i != Header.NumColumns; ++i)
OS << " ------------------------";
for (unsigned i = 0; i != Header.NumColumns; ++i) {
DWARFSectionKind Kind = ColumnKinds[i];
if (Kind == DWARFSectionKind::DW_SECT_INFO ||
Kind == DWARFSectionKind::DW_SECT_EXT_TYPES)
OS << " ----------------------------------------";
else
OS << " ------------------------";
}
OS << '\n';
for (unsigned i = 0; i != Header.NumBuckets; ++i) {
auto &Row = Rows[i];
if (auto *Contribs = Row.Contributions.get()) {
OS << format("%5u 0x%016" PRIx64 " ", i + 1, Row.Signature);
for (unsigned i = 0; i != Header.NumColumns; ++i) {
auto &Contrib = Contribs[i];
OS << format("[0x%08x, 0x%08x) ", Contrib.Offset,
Contrib.Offset + Contrib.Length);
DWARFSectionKind Kind = ColumnKinds[i];
if (Kind == DWARFSectionKind::DW_SECT_INFO ||
Kind == DWARFSectionKind::DW_SECT_EXT_TYPES)
OS << format("[0x%016" PRIx64 ", 0x%016" PRIx64 ") ",
Contrib.getOffset(),
Contrib.getOffset() + Contrib.getLength());
else
OS << format("[0x%08" PRIx32 ", 0x%08" PRIx32 ") ",
Contrib.getOffset(),
Contrib.getOffset() + Contrib.getLength());
}
OS << '\n';
}
Expand All @@ -253,31 +269,36 @@ DWARFUnitIndex::Entry::getContribution(DWARFSectionKind Sec) const {
return nullptr;
}

DWARFUnitIndex::Entry::SectionContribution &
DWARFUnitIndex::Entry::getContribution() {
return Contributions[Index->InfoColumn];
}

const DWARFUnitIndex::Entry::SectionContribution *
DWARFUnitIndex::Entry::getContribution() const {
return &Contributions[Index->InfoColumn];
}

const DWARFUnitIndex::Entry *
DWARFUnitIndex::getFromOffset(uint32_t Offset) const {
DWARFUnitIndex::getFromOffset(uint64_t Offset) const {
if (OffsetLookup.empty()) {
for (uint32_t i = 0; i != Header.NumBuckets; ++i)
if (Rows[i].Contributions)
OffsetLookup.push_back(&Rows[i]);
llvm::sort(OffsetLookup, [&](Entry *E1, Entry *E2) {
return E1->Contributions[InfoColumn].Offset <
E2->Contributions[InfoColumn].Offset;
return E1->Contributions[InfoColumn].getOffset() <
E2->Contributions[InfoColumn].getOffset();
});
}
auto I = partition_point(OffsetLookup, [&](Entry *E2) {
return E2->Contributions[InfoColumn].Offset <= Offset;
return E2->Contributions[InfoColumn].getOffset() <= Offset;
});
if (I == OffsetLookup.begin())
return nullptr;
--I;
const auto *E = *I;
const auto &InfoContrib = E->Contributions[InfoColumn];
if ((InfoContrib.Offset + InfoContrib.Length) <= Offset)
if ((InfoContrib.getOffset() + InfoContrib.getLength()) <= Offset)
return nullptr;
return E;
}
Expand Down
10 changes: 5 additions & 5 deletions llvm/lib/DebugInfo/DWARF/DWARFVerifier.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -405,7 +405,7 @@ unsigned DWARFVerifier::verifyIndex(StringRef Name,
DataExtractor D(IndexStr, DCtx.isLittleEndian(), 0);
if (!Index.parse(D))
return 1;
using MapType = IntervalMap<uint32_t, uint64_t>;
using MapType = IntervalMap<uint64_t, uint64_t>;
MapType::Allocator Alloc;
std::vector<std::unique_ptr<MapType>> Sections(Index.getColumnKinds().size());
for (const DWARFUnitIndex::Entry &E : Index.getRows()) {
Expand All @@ -418,20 +418,20 @@ unsigned DWARFVerifier::verifyIndex(StringRef Name,
: makeArrayRef(E.getContribution(), 1))) {
const DWARFUnitIndex::Entry::SectionContribution &SC = E.value();
int Col = E.index();
if (SC.Length == 0)
if (SC.getLength() == 0)
continue;
if (!Sections[Col])
Sections[Col] = std::make_unique<MapType>(Alloc);
auto &M = *Sections[Col];
auto I = M.find(SC.Offset);
if (I != M.end() && I.start() < (SC.Offset + SC.Length)) {
auto I = M.find(SC.getOffset());
if (I != M.end() && I.start() < (SC.getOffset() + SC.getLength())) {
error() << llvm::formatv(
"overlapping index entries for entries {0:x16} "
"and {1:x16} for column {2}\n",
*I, Sig, toString(Index.getColumnKinds()[Col]));
return 1;
}
M.insert(SC.Offset, SC.Offset + SC.Length - 1, Sig);
M.insert(SC.getOffset(), SC.getOffset() + SC.getLength() - 1, Sig);
}
}

Expand Down
4 changes: 2 additions & 2 deletions llvm/test/DebugInfo/X86/debug-cu-index-unknown-section.s
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@
# CHECK-NEXT: version = 2, units = 1, slots = 2
# CHECK-EMPTY:
# CHECK-NEXT: Index Signature Unknown: 9 INFO
# CHECK-NEXT: ----- ------------------ ------------------------ ------------------------
# CHECK-NEXT: 1 0x1100001122222222 [0x00001000, 0x00001010) [0x00002000, 0x00002020)
# CHECK-NEXT: ----- ------------------ ------------------------ ----------------------------------------
# CHECK-NEXT: 1 0x1100001122222222 [0x00001000, 0x00001010) [0x0000000000002000, 0x0000000000002020)

.section .debug_cu_index, "", @progbits
## Header:
Expand Down
6 changes: 3 additions & 3 deletions llvm/test/DebugInfo/X86/dwp-v2-cu-index.s
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@
# CHECK: .debug_cu_index contents:
# CHECK-NEXT: version = 2, units = 1, 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)
# CHECK-NEXT: Index Signature INFO ABBREV LINE LOC STR_OFFSETS MACINFO MACRO
# CHECK-NEXT: ----- ------------------ ---------------------------------------- ------------------------ ------------------------ ------------------------ ------------------------ ------------------------ ------------------------
# CHECK-NEXT: 1 0x1100001122222222 [0x0000000000001000, 0x0000000000001010) [0x00002000, 0x00002020) [0x00003000, 0x00003030) [0x00004000, 0x00004040) [0x00005000, 0x00005050) [0x00006000, 0x00006060) [0x00007000, 0x00007070)

.section .debug_cu_index, "", @progbits
## Header:
Expand Down
6 changes: 3 additions & 3 deletions llvm/test/DebugInfo/X86/dwp-v2-tu-index.s
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@
# CHECK: .debug_tu_index contents:
# CHECK-NEXT: version = 2, units = 1, 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)
# CHECK-NEXT: Index Signature TYPES ABBREV LINE STR_OFFSETS
# CHECK-NEXT: ----- ------------------ ---------------------------------------- ------------------------ ------------------------ ------------------------
# CHECK-NEXT: 1 0x1100001122222222 [0x0000000000001000, 0x0000000000001010) [0x00002000, 0x00002020) [0x00003000, 0x00003030) [0x00004000, 0x00004040)

.section .debug_tu_index, "", @progbits
## Header:
Expand Down
6 changes: 3 additions & 3 deletions llvm/test/DebugInfo/X86/dwp-v5-cu-index.s
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@
# CHECK: .debug_cu_index contents:
# CHECK-NEXT: version = 5, units = 1, 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)
# CHECK-NEXT: Index Signature INFO ABBREV LINE LOCLISTS STR_OFFSETS MACRO RNGLISTS
# CHECK-NEXT: ----- ------------------ ---------------------------------------- ------------------------ ------------------------ ------------------------ ------------------------ ------------------------ ------------------------
# CHECK-NEXT: 1 0x1100001122222222 [0x0000000000001000, 0x0000000000001010) [0x00002000, 0x00002020) [0x00003000, 0x00003030) [0x00004000, 0x00004040) [0x00005000, 0x00005050) [0x00006000, 0x00006060) [0x00007000, 0x00007070)

.section .debug_cu_index, "", @progbits
## Header:
Expand Down
6 changes: 3 additions & 3 deletions llvm/test/DebugInfo/X86/dwp-v5-tu-index.s
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@
# CHECK: .debug_tu_index contents:
# CHECK-NEXT: version = 5, units = 1, 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)
# CHECK-NEXT: Index Signature INFO ABBREV LINE STR_OFFSETS
# CHECK-NEXT: ----- ------------------ ---------------------------------------- ------------------------ ------------------------ ------------------------
# CHECK-NEXT: 1 0x1100001122222222 [0x0000000000001000, 0x0000000000001010) [0x00002000, 0x00002020) [0x00003000, 0x00003030) [0x00004000, 0x00004040)

.section .debug_tu_index, "", @progbits
## Header:
Expand Down
16 changes: 8 additions & 8 deletions llvm/test/DebugInfo/dwarfdump-dwp.test
Original file line number Diff line number Diff line change
Expand Up @@ -38,17 +38,17 @@ RUN: llvm-dwarfdump -v %p/Inputs/dwarfdump-dwp.x86_64.o | FileCheck %s

; CHECK: .debug_cu_index contents:
; CHECK-NEXT: version = 2, units = 2, slots = 16
; CHECK: Index Signature INFO ABBREV LINE STR_OFFSETS
; CHECK-NEXT: ----- ------------------ ------------------------ ------------------------ ------------------------ ------------------------
; CHECK-NEXT: 3 0xfef104c25502f092 [0x0000002d, 0x0000005f) [0x00000043, 0x0000008e) [0x0000001a, 0x00000034) [0x00000010, 0x00000024)
; CHECK-NEXT: 9 0x03c30756e2d45008 [0x00000000, 0x0000002d) [0x00000000, 0x00000043) [0x00000000, 0x0000001a) [0x00000000, 0x00000010)
; CHECK: Index Signature INFO ABBREV LINE STR_OFFSETS
; CHECK-NEXT: ----- ------------------ ---------------------------------------- ------------------------ ------------------------ ------------------------
; CHECK-NEXT: 3 0xfef104c25502f092 [0x000000000000002d, 0x000000000000005f) [0x00000043, 0x0000008e) [0x0000001a, 0x00000034) [0x00000010, 0x00000024)
; CHECK-NEXT: 9 0x03c30756e2d45008 [0x0000000000000000, 0x000000000000002d) [0x00000000, 0x00000043) [0x00000000, 0x0000001a) [0x00000000, 0x00000010)

; CHECK: .debug_tu_index contents:
; CHECK-NEXT: version = 2, units = 2, slots = 16
; CHECK: Index Signature TYPES ABBREV LINE STR_OFFSETS
; CHECK-NEXT: ----- ------------------ ------------------------ ------------------------ ------------------------ ------------------------
; CHECK-NEXT: 9 0x1d02f3be30cc5688 [0x00000024, 0x00000048) [0x00000043, 0x0000008e) [0x0000001a, 0x00000034) [0x00000010, 0x00000024)
; CHECK-NEXT: 13 0x3875c0e21cda63fc [0x00000000, 0x00000024) [0x00000000, 0x00000043) [0x00000000, 0x0000001a) [0x00000000, 0x00000010)
; CHECK: Index Signature TYPES ABBREV LINE STR_OFFSETS
; CHECK-NEXT: ----- ------------------ ---------------------------------------- ------------------------ ------------------------ ------------------------
; CHECK-NEXT: 9 0x1d02f3be30cc5688 [0x0000000000000024, 0x0000000000000048) [0x00000043, 0x0000008e) [0x0000001a, 0x00000034) [0x00000010, 0x00000024)
; CHECK-NEXT: 13 0x3875c0e21cda63fc [0x0000000000000000, 0x0000000000000024) [0x00000000, 0x00000043) [0x00000000, 0x0000001a) [0x00000000, 0x00000010)

; TODO: use the index section offset info to correctly dump strings in debug info
; TODO: use the index section offset info to correctly dump file names in debug info
92 changes: 92 additions & 0 deletions llvm/test/tools/llvm-dwp/X86/cu_tu_units_manual_v5.s
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
# This test checks if we can correctly parse manull cu and tu index for DWARF5.

# 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-cu-index -debug-tu-index %t.dwp | FileCheck -check-prefix=CHECK %s
# RUN: llvm-dwarfdump -debug-info -debug-cu-index -debug-tu-index -manaully-generate-unit-index %t.dwp | FileCheck -check-prefix=CHECK2 %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: 0x00000036: Compile Unit: length = 0x00000011, format = DWARF32, version = 0x0005, unit_type = DW_UT_split_compile, abbr_offset = 0x0000, addr_size = 0x08, DWO_id = [[CUID1:.*]] (next unit at 0x0000004b)
# CHECK-DAG: .debug_cu_index contents:
# CHECK: version = 5, units = 1, slots = 2
# CHECK: Index Signature INFO ABBREV
# CHECK: 1 [[CUID1]] [0x0000000000000036, 0x000000000000004b) [0x00000000, 0x00000010)
# CHECK-DAG: .debug_tu_index contents:
# CHECK: version = 5, units = 2, slots = 4
# CHECK: Index Signature INFO ABBREV
# CHECK: 1 [[TUID1]] [0x0000000000000000, 0x000000000000001b) [0x00000000, 0x00000010)
# CHECK: 4 [[TUID2]] [0x000000000000001b, 0x0000000000000036) [0x00000000, 0x00000010)

# CHECK2-DAG: .debug_info.dwo contents:
# CHECK2: 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)
# CHECK2: 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)
# CHECK2: 0x00000036: Compile Unit: length = 0x00000011, format = DWARF32, version = 0x0005, unit_type = DW_UT_split_compile, abbr_offset = 0x0000, addr_size = 0x08, DWO_id = [[CUID1:.*]] (next unit at 0x0000004b)
# CHECK2-DAG: .debug_cu_index contents:
# CHECK2: version = 5, units = 1, slots = 2
# CHECK2: Index Signature INFO ABBREV
# CHECK2: 1 [[CUID1]] [0x0000000000000036, 0x000000000000004b) [0x00000000, 0x00000010)
# CHECK2-DAG: .debug_tu_index contents:
# CHECK2: version = 5, units = 2, slots = 4
# CHECK2: Index Signature INFO ABBREV
# CHECK2: 1 [[TUID1]] [0x0000000000000000, 0x000000000000001b) [0x00000000, 0x00000010)
# CHECK2: 4 [[TUID2]] [0x000000000000001b, 0x0000000000000036) [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 1152943841751211454
.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
10 changes: 7 additions & 3 deletions llvm/test/tools/llvm-dwp/X86/debug_macro_v5.s
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@

# RUN: llvm-mc -triple x86_64-unknown-linux --filetype=obj --split-dwarf-file=%t.dwo -dwarf-version=5 %s -o %t.o
# RUN: llvm-dwp %t.dwo -o %t.dwp 2>&1
# RUN: llvm-dwarfdump -debug-macro -debug-cu-index %t.dwp | FileCheck %s
# RUN: llvm-dwarfdump -debug-macro -debug-cu-index %t.dwp | FileCheck -check-prefix=CHECK %s
# RUN: llvm-dwarfdump -debug-macro -debug-cu-index -manaully-generate-unit-index %t.dwp | FileCheck -check-prefix=CHECK2 %s

# CHECK-DAG: .debug_macro.dwo contents:
# CHECK: macro header: version = 0x0005, flags = 0x00, format = DWARF32
Expand All @@ -12,8 +13,11 @@

# CHECK-DAG: .debug_cu_index contents:
# CHECK-NEXT: version = 5, units = 1, slots = 2
# CHECK: Index Signature INFO ABBREV STR_OFFSETS MACRO
# CHECK: 1 0x0000000000000000 [0x00000000, 0x00000019) [0x00000000, 0x00000008) [0x00000000, 0x0000000c) [0x00000000, 0x0000000b)
# CHECK: Index Signature INFO ABBREV STR_OFFSETS MACRO
# CHECK: 1 0x0000000000000000 [0x0000000000000000, 0x0000000000000019) [0x00000000, 0x00000008) [0x00000000, 0x0000000c) [0x00000000, 0x0000000b)

# CHECK2: Index Signature INFO ABBREV STR_OFFSETS MACRO
# CHECK2: 1 0x0000000000000000 [0x0000000000000000, 0x0000000000000019) [0x00000000, 0x00000008) [0x00000000, 0x0000000c) [0x00000000, 0x0000000b)

.section .debug_info.dwo,"e",@progbits
.long .Ldebug_info_dwo_end0-.Ldebug_info_dwo_start0 # Length of Unit
Expand Down
4 changes: 2 additions & 2 deletions llvm/test/tools/llvm-dwp/X86/info-v5.s
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@

# CHECK-DAG: .debug_cu_index contents:
# CHECK: version = 5, units = 1, slots = 2
# CHECK: Index Signature INFO ABBREV
# CHECK: 1 [[DWOID]] [0x00000000, 0x00000054) [0x00000000, 0x0000002a)
# CHECK: Index Signature INFO ABBREV
# CHECK: 1 [[DWOID]] [0x0000000000000000, 0x0000000000000054) [0x00000000, 0x0000002a)

.section .debug_info.dwo,"e",@progbits
.long .Ldebug_info_dwo_end0-.Ldebug_info_dwo_start0 # Length of Unit
Expand Down
8 changes: 4 additions & 4 deletions llvm/test/tools/llvm-dwp/X86/loclists.s
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,12 @@
# CHECK-NEXT: DW_LLE_offset_pair (0x0000000000000004, 0x0000000000000008): DW_OP_reg3 RBX

# CHECK-DAG: .debug_cu_index contents:
# CHECK: Index Signature INFO ABBREV LOCLISTS
# CHECK: 1 {{.*}} [0x00000018, 0x0000002d) [0x00000000, 0x00000004) [0x00000000, 0x0000001d)
# CHECK: Index Signature INFO ABBREV LOCLISTS
# CHECK: 1 {{.*}} [0x0000000000000018, 0x000000000000002d) [0x00000000, 0x00000004) [0x00000000, 0x0000001d)

# CHECK-DAG: .debug_tu_index contents:
# CHECK: Index Signature INFO ABBREV LOCLISTS
# CHECK: 2 {{.*}} [0x00000000, 0x00000018) [0x00000000, 0x00000004) [0x00000000, 0x0000001d)
# CHECK: Index Signature INFO ABBREV LOCLISTS
# CHECK: 2 {{.*}} [0x0000000000000000, 0x0000000000000018) [0x00000000, 0x00000004) [0x00000000, 0x0000001d)

.section .debug_info.dwo,"e",@progbits
.long .Ldebug_info_dwo_end0-.Ldebug_info_dwo_start0 # Length of Unit
Expand Down
20 changes: 10 additions & 10 deletions llvm/test/tools/llvm-dwp/X86/merge.test
Original file line number Diff line number Diff line change
Expand Up @@ -26,21 +26,21 @@ CHECK-LABEL: Abbrev table for offset:
CHECK: 0x0000[[BAOFF:.*]]

CHECK: .debug_info.dwo contents:
CHECK: [[COFF:0x[0-9a-f]*]]:
CHECK: 0x[[#%.8x,COFF:]]:
CHECK-LABEL: Compile Unit: length = {{.*}}, version = 0x0004, abbr_offset =
CHECK: 0x[[CAOFF]], addr_size = 0x08 (next unit at [[AOFF:.*]])
CHECK: 0x[[CAOFF]], addr_size = 0x08 (next unit at 0x[[#%.8x,AOFF:]])
CHECK: DW_AT_GNU_dwo_id {{.*}} ([[DWOC:.*]])
CHECK: [[AOFF]]:
CHECK: [[#AOFF]]:
CHECK-LABEL: Compile Unit: length = {{.*}}, version = 0x0004, abbr_offset =
CHECK: 0x[[AAOFF]], addr_size = 0x08 (next unit at [[BOFF:.*]])
CHECK: 0x[[AAOFF]], addr_size = 0x08 (next unit at 0x[[#%.8x,BOFF:]])
CHECK: DW_AT_GNU_dwo_id {{.*}} ([[DWOA:.*]])
CHECK: [[BOFF]]:
CHECK: [[#BOFF]]:
CHECK-LABEL: Compile Unit: length = {{.*}}, version = 0x0004, abbr_offset =
CHECK: 0x[[BAOFF]], addr_size = 0x08 (next unit at [[XOFF:.*]])
CHECK: 0x[[BAOFF]], addr_size = 0x08 (next unit at 0x[[#%.8x,XOFF:]])
CHECK: DW_AT_GNU_dwo_id {{.*}} ([[DWOB:.*]])

CHECK-LABEL: .debug_cu_index
CHECK: Index Signature INFO ABBREV LINE STR_OFFSETS
CHECK-DAG: [[DWOC]] [[[COFF]], [[AOFF]]) [0x0000[[CAOFF]], 0x0000[[AAOFF]]) [0x00000000, 0x00000011) [0x00000000, 0x00000018)
CHECK-DAG: [[DWOA]] [[[AOFF]], [[BOFF]]) [0x0000[[AAOFF]], 0x0000[[BAOFF]]) [0x00000011, 0x00000022) [0x00000018, 0x00000028)
CHECK-DAG: [[DWOB]] [[[BOFF]], [[XOFF]]) [0x0000[[BAOFF]], 0x000000c3) [0x00000022, 0x00000033) [0x00000028, 0x0000003c)
CHECK: Index Signature INFO ABBREV LINE STR_OFFSETS
CHECK-DAG: [[DWOC]] [0x00000000[[#COFF]], 0x00000000[[#AOFF]]) [0x0000[[CAOFF]], 0x0000[[AAOFF]]) [0x00000000, 0x00000011) [0x00000000, 0x00000018)
CHECK-DAG: [[DWOA]] [0x00000000[[#AOFF]], 0x00000000[[#BOFF]]) [0x0000[[AAOFF]], 0x0000[[BAOFF]]) [0x00000011, 0x00000022) [0x00000018, 0x00000028)
CHECK-DAG: [[DWOB]] [0x00000000[[#BOFF]], 0x00000000[[#XOFF]]) [0x0000[[BAOFF]], 0x000000c3) [0x00000022, 0x00000033) [0x00000028, 0x0000003c)
8 changes: 4 additions & 4 deletions llvm/test/tools/llvm-dwp/X86/rnglists.s
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,12 @@
# RUN: llvm-dwarfdump -debug-rnglists -debug-cu-index -debug-tu-index %t.dwp | FileCheck %s

# CHECK-DAG: .debug_cu_index contents:
# CHECK: Index Signature INFO ABBREV RNGLISTS
# CHECK: 1 {{.*}} [0x00000018, 0x0000002d) [0x00000000, 0x00000004) [0x00000000, 0x00000017)
# CHECK: Index Signature INFO ABBREV RNGLISTS
# CHECK: 1 {{.*}} [0x0000000000000018, 0x000000000000002d) [0x00000000, 0x00000004) [0x00000000, 0x00000017)

# CHECK-DAG: .debug_tu_index contents:
# CHECK: Index Signature INFO ABBREV RNGLISTS
# CHECK: 2 {{.*}} [0x00000000, 0x00000018) [0x00000000, 0x00000004) [0x00000000, 0x00000017)
# CHECK: Index Signature INFO ABBREV RNGLISTS
# CHECK: 2 {{.*}} [0x0000000000000000, 0x0000000000000018) [0x00000000, 0x00000004) [0x00000000, 0x00000017)

# CHECK-DAG: .debug_rnglists.dwo contents:
# range list header: length = 0x00000013, format = DWARF32, version = 0x0005, addr_size = 0x08, seg_size = 0x00, offset_entry_count = 0x00000001
Expand Down
32 changes: 16 additions & 16 deletions llvm/test/tools/llvm-dwp/X86/simple.test
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,9 @@ CHECK: DW_TAG_subprogram
CHECK: DW_TAG_formal_parameter

CHECK: .debug_info.dwo contents:
CHECK: [[AOFF:0x[0-9a-f]*]]:
CHECK: 0x[[#%.8x,AOFF:]]:
CHECK-LABEL: Compile Unit: length = {{.*}}, version = 0x0004, abbr_offset =
CHECK: 0x[[AAOFF]], addr_size = 0x08 (next unit at [[BOFF:.*]])
CHECK: 0x[[AAOFF]], addr_size = 0x08 (next unit at 0x[[#%.8x,BOFF:]])
CHECK: DW_TAG_compile_unit
CHECK: DW_AT_name {{.*}} "a.cpp"
CHECK: DW_AT_GNU_dwo_id {{.*}} ([[DWOA:.*]])
Expand All @@ -40,9 +40,9 @@ CHECK: DW_TAG_structure_type
NOTYP: DW_AT_name {{.*}} "foo"
TYPES: DW_AT_signature {{.*}} ([[FOOSIG:.*]])

CHECK: [[BOFF]]:
CHECK: 0x[[#BOFF]]:
CHECK-LABEL: Compile Unit: length = {{.*}}, version = 0x0004, abbr_offset =
CHECK: 0x[[BAOFF]], addr_size = 0x08 (next unit at [[XOFF:.*]])
CHECK: 0x[[BAOFF]], addr_size = 0x08 (next unit at 0x[[#%.8x,XOFF:]])
CHECK: DW_AT_name {{.*}} "b.cpp"
CHECK: DW_AT_GNU_dwo_id {{.*}} ([[DWOB:.*]])
CHECK: DW_TAG_structure_type
Expand All @@ -54,32 +54,32 @@ CHECK: DW_TAG_formal_parameter

NOTYP-NOT: .debug_types.dwo contents:
TYPES-LABEL: .debug_types.dwo contents:
TYPES: [[FOOUOFF:0x[0-9a-f]*]]:
TYPES: 0x[[#%.8x,FOOUOFF:]]:
TYPES-LABEL: Type Unit: length = 0x00000020, format = DWARF32, version = 0x0004, abbr_offset =
TYPES: 0x[[AAOFF]], addr_size = 0x08, name = 'foo', type_signature = [[FOOSIG]], type_offset = 0x[[FOOOFF:.*]] (next unit at [[BARUOFF:.*]])
TYPES: 0x[[AAOFF]], addr_size = 0x08, name = 'foo', type_signature = [[FOOSIG]], type_offset = 0x[[FOOOFF:.*]] (next unit at 0x[[#%.8x,BARUOFF:]])
TYPES: DW_TAG_type_unit
TYPES: [[FOOOFF]]: DW_TAG_structure_type
TYPES: DW_AT_name {{.*}} "foo"
TYPES: [[BARUOFF]]:
TYPES: 0x[[#BARUOFF]]:
TYPES-LABEL: Type Unit: length = 0x00000020, format = DWARF32, version = 0x0004, abbr_offset =
TYPES: 0x[[BAOFF]], addr_size = 0x08, name = 'bar', type_signature = [[BARSIG]], type_offset = 0x001e (next unit at [[XUOFF:.*]])
TYPES: 0x[[BAOFF]], addr_size = 0x08, name = 'bar', type_signature = [[BARSIG]], type_offset = 0x001e (next unit at 0x[[#%.8x,XUOFF:]])
TYPES: DW_TAG_type_unit
TYPES: 0x00000042: DW_TAG_structure_type
TYPES: DW_AT_name {{.*}} "bar"

CHECK-LABEL: .debug_cu_index contents:
CHECK: Index Signature INFO ABBREV LINE STR_OFFSETS
TYPES: 1 [[DWOA]] [[[AOFF]], [[BOFF]]) [0x0000[[AAOFF]], 0x0000[[BAOFF]]) [0x00000000, 0x0000001a) [0x00000000, 0x00000010)
TYPES: 3 [[DWOB]] [[[BOFF]], [[XOFF]]) [0x0000[[BAOFF]], 0x00000099) [0x0000001a, 0x00000034) [0x00000010, 0x00000024)
NOTYP: 3 [[DWOA]] [[[AOFF]], [[BOFF]]) [0x0000[[AAOFF]], 0x0000[[BAOFF]]) [0x00000000, 0x00000011) [0x00000000, 0x00000010)
NOTYP: 4 [[DWOB]] [[[BOFF]], [[XOFF]]) [0x0000[[BAOFF]], 0x00000075) [0x00000011, 0x00000022) [0x00000010, 0x00000024)
CHECK: Index Signature INFO ABBREV LINE STR_OFFSETS
TYPES: 1 [[DWOA]] [0x00000000[[#AOFF]], 0x00000000[[#BOFF]]) [0x0000[[AAOFF]], 0x0000[[BAOFF]]) [0x00000000, 0x0000001a) [0x00000000, 0x00000010)
TYPES: 3 [[DWOB]] [0x00000000[[#BOFF]], 0x00000000[[#XOFF]]) [0x0000[[BAOFF]], 0x00000099) [0x0000001a, 0x00000034) [0x00000010, 0x00000024)
NOTYP: 3 [[DWOA]] [0x00000000[[#AOFF]], 0x00000000[[#BOFF]]) [0x0000[[AAOFF]], 0x0000[[BAOFF]]) [0x00000000, 0x00000011) [0x00000000, 0x00000010)
NOTYP: 4 [[DWOB]] [0x00000000[[#BOFF]], 0x00000000[[#XOFF]]) [0x0000[[BAOFF]], 0x00000075) [0x00000011, 0x00000022) [0x00000010, 0x00000024)

Ensure we do not create a debug_tu_index, even an empty or malformed one.
NOTYPOBJ-NOT: .debug_tu_index

TYPES: Index Signature TYPES ABBREV LINE STR_OFFSETS
TYPES: 1 [[FOOSIG]] [[[FOOUOFF]], [[BARUOFF]]) [0x0000[[AAOFF]], 0x0000[[BAOFF]]) [0x00000000, 0x0000001a) [0x00000000, 0x00000010)
TYPES: 4 [[BARSIG]] [[[BARUOFF]], [[XUOFF]]) [0x0000[[BAOFF]], 0x00000099) [0x0000001a, 0x00000034) [0x00000010, 0x00000024)
TYPES: Index Signature TYPES ABBREV LINE STR_OFFSETS
TYPES: 1 [[FOOSIG]] [0x00000000[[#FOOUOFF]], 0x00000000[[#BARUOFF]]) [0x0000[[AAOFF]], 0x0000[[BAOFF]]) [0x00000000, 0x0000001a) [0x00000000, 0x00000010)
TYPES: 4 [[BARSIG]] [0x00000000[[#BARUOFF]], 0x00000000[[#XUOFF]]) [0x0000[[BAOFF]], 0x00000099) [0x0000001a, 0x00000034) [0x00000010, 0x00000024)

CHECK-LABEL: .debug_str.dwo contents:
CHECK: "clang version
Expand Down
6 changes: 3 additions & 3 deletions llvm/test/tools/llvm-dwp/X86/tu_units_v5.s
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,9 @@
# 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)
# CHECK: Index Signature INFO ABBREV
# CHECK: 1 [[TUID1]] [0x0000000000000000, 0x000000000000001b) [0x00000000, 0x00000010)
# CHECK: 4 [[TUID2]] [0x000000000000001b, 0x0000000000000036) [0x00000000, 0x00000010)

.section .debug_info.dwo,"e",@progbits
.long .Ldebug_info_dwo_end0-.Ldebug_info_dwo_start0 # Length of Unit
Expand Down
27 changes: 25 additions & 2 deletions llvm/test/tools/llvm-dwp/X86/type_dedup.test
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
RUN: llvm-dwp %p/../Inputs/type_dedup/a.dwo %p/../Inputs/type_dedup/b.dwo -o %t
RUN: llvm-dwarfdump -v %t | FileCheck %s
RUN: llvm-dwarfdump -v %t | FileCheck -check-prefix=CHECK %s
RUN: llvm-dwarfdump -v -manaully-generate-unit-index %t | FileCheck -check-prefix=CHECK2 %s
RUN: llvm-dwp %p/../Inputs/type_dedup/b.dwo -o %tb.dwp
RUN: llvm-dwp %p/../Inputs/type_dedup/a.dwo %tb.dwp -o %t
RUN: llvm-dwarfdump -v %t | FileCheck %s
RUN: llvm-dwarfdump -v %t | FileCheck -check-prefix=CHECK %s
RUN: llvm-dwarfdump -v -manaully-generate-unit-index %t | FileCheck -check-prefix=CHECK2 %s

a.cpp:
struct common { };
Expand Down Expand Up @@ -36,3 +38,24 @@ CHECK: DW_TAG_type_unit
CHECK: 0x00000066: DW_TAG_structure_type
CHECK: DW_AT_name {{.*}} "bdistinct"
CHECK-NOT: Type Unit

CHECK2-LABEL: .debug_types.dwo contents:
CHECK2: [[COMMONUOFF:0x[0-9a-f]*]]:
CHECK2-LABEL: Type Unit: length = 0x00000020, format = DWARF32, version = 0x0004, abbr_offset =
CHECK2: 0x0000, addr_size = 0x08, name = 'common', type_signature = [[COMMONSIG:0x[0-9a-f]*]], type_offset = 0x[[COMMONOFF:.*]] (next unit at [[AUOFF:.*]])
CHECK2: DW_TAG_type_unit
CHECK2: [[COMMONOFF]]: DW_TAG_structure_type
CHECK2: DW_AT_name {{.*}} "common"
CHECK2: [[AUOFF]]:
CHECK2-LABEL: Type Unit: length = 0x00000020, format = DWARF32, version = 0x0004, abbr_offset =
CHECK2: 0x0000, addr_size = 0x08, name = 'adistinct', type_signature = [[ASIG:0x[0-9a-f]*]], type_offset = 0x[[AOFF:.*]] (next unit at [[BUOFF:.*]])
CHECK2: DW_TAG_type_unit
CHECK2: 0x00000042: DW_TAG_structure_type
CHECK2: DW_AT_name {{.*}} "adistinct"
CHECK2: [[BUOFF]]:
CHECK2-LABEL: Type Unit: length = 0x00000020, format = DWARF32, version = 0x0004, abbr_offset =
CHECK2: 0x{{.*}}, addr_size = 0x08, name = 'bdistinct', type_signature = [[BSIG:0x[0-9a-f]*]], type_offset = 0x[[BOFF:.*]] (next unit at [[XUOFF:.*]])
CHECK2: DW_TAG_type_unit
CHECK2: 0x00000066: DW_TAG_structure_type
CHECK2: DW_AT_name {{.*}} "bdistinct"
CHECK2-NOT: Type Unit
4 changes: 2 additions & 2 deletions llvm/test/tools/llvm-dwp/X86/unknown-section-id.s
Original file line number Diff line number Diff line change
Expand Up @@ -17,15 +17,15 @@
# CHECK: Index Signature INFO ABBREV
# CHECK-NOT: Unknown
# CHECK: -----
# CHECK-NEXT: 1 0x1100002222222222 [0x00000000, 0x00000014) [0x00000000, 0x00000009)
# CHECK-NEXT: 1 0x1100002222222222 [0x0000000000000000, 0x0000000000000014) [0x00000000, 0x00000009)
# CHECK-NOT: [

# CHECK: .debug_tu_index contents:
# CHECK-NEXT: version = 2, units = 1, slots = 2
# CHECK: Index Signature TYPES ABBREV
# CHECK-NOT: Unknown
# CHECK: -----
# CHECK-NEXT: 2 0x1100003333333333 [0x00000000, 0x00000019) [0x00000009, 0x00000014)
# CHECK-NEXT: 2 0x1100003333333333 [0x0000000000000000, 0x0000000000000019) [0x00000009, 0x00000014)
# CHECK-NOT: [

.section .debug_abbrev.dwo, "e", @progbits
Expand Down
8 changes: 8 additions & 0 deletions llvm/tools/llvm-dwarfdump/llvm-dwarfdump.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -247,6 +247,13 @@ static cl::opt<bool>
cl::desc("Show the sizes of all debug sections, "
"expressed in bytes."),
cat(DwarfDumpCategory));
static cl::opt<bool> ManuallyGenerateUnitIndex(
"manaully-generate-unit-index",
cl::desc("if the input is dwp file, parse .debug_info "
"section and use it to populate "
"DW_SECT_INFO contributions in cu-index. "
"For DWARF5 it also populated TU Index."),
cl::init(false), cl::Hidden, cl::cat(DwarfDumpCategory));
static cl::opt<bool>
ShowSources("show-sources",
cl::desc("Show the sources across all compilation units."),
Expand Down Expand Up @@ -635,6 +642,7 @@ static bool handleBuffer(StringRef Filename, MemoryBufferRef Buffer,
std::unique_ptr<DWARFContext> DICtx = DWARFContext::create(
*Obj, DWARFContext::ProcessDebugRelocations::Process, nullptr, "",
RecoverableErrorHandler);
DICtx->setParseCUTUIndexManually(ManuallyGenerateUnitIndex);
if (!HandleObj(*Obj, *DICtx, Filename, OS))
Result = false;
}
Expand Down