Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion bolt/test/X86/dwarf4-ftypes-dwp-input-dwo-output.test
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
# UNSUPPORTED: system-linux
; RUN: rm -rf %t
; RUN: mkdir %t
; RUN: cd %t
Expand Down
4 changes: 3 additions & 1 deletion llvm/include/llvm/DebugInfo/DWARF/DWARFUnit.h
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,9 @@ class DWARFUnitVector final : public SmallVector<std::unique_ptr<DWARFUnit>, 1>
decltype(make_filter_range(std::declval<iterator_range>(), isCompileUnit));

LLVM_ABI DWARFUnit *getUnitForOffset(uint64_t Offset) const;
LLVM_ABI DWARFUnit *getUnitForIndexEntry(const DWARFUnitIndex::Entry &E);
LLVM_ABI DWARFUnit *
getUnitForIndexEntry(const DWARFUnitIndex::Entry &E, DWARFSectionKind Sec,
const DWARFSection *Section = nullptr);

/// Read units from a .debug_info or .debug_types section. Calls made
/// before finishedInfoUnits() are assumed to be for .debug_info sections,
Expand Down
19 changes: 15 additions & 4 deletions llvm/lib/DebugInfo/DWARF/DWARFContext.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1344,9 +1344,20 @@ void DWARFContext::dump(
DWARFTypeUnit *DWARFContext::getTypeUnitForHash(uint64_t Hash, bool IsDWO) {
DWARFUnitVector &DWOUnits = State->getDWOUnits();
if (const auto &TUI = getTUIndex()) {
if (const auto *R = TUI.getFromHash(Hash))
return dyn_cast_or_null<DWARFTypeUnit>(
DWOUnits.getUnitForIndexEntry(*R));
if (const auto *R = TUI.getFromHash(Hash)) {
if (TUI.getVersion() >= 5)
return dyn_cast_or_null<DWARFTypeUnit>(
DWOUnits.getUnitForIndexEntry(*R, DW_SECT_INFO));
else {
DWARFUnit *TypesUnit = nullptr;
getDWARFObj().forEachTypesDWOSections([&](const DWARFSection &S) {
if (!TypesUnit)
TypesUnit =
DWOUnits.getUnitForIndexEntry(*R, DW_SECT_EXT_TYPES, &S);
});
return dyn_cast_or_null<DWARFTypeUnit>(TypesUnit);
}
}
return nullptr;
}
return State->getTypeUnitMap(IsDWO).lookup(Hash);
Expand All @@ -1358,7 +1369,7 @@ DWARFCompileUnit *DWARFContext::getDWOCompileUnitForHash(uint64_t Hash) {
if (const auto &CUI = getCUIndex()) {
if (const auto *R = CUI.getFromHash(Hash))
return dyn_cast_or_null<DWARFCompileUnit>(
DWOUnits.getUnitForIndexEntry(*R));
DWOUnits.getUnitForIndexEntry(*R, DW_SECT_INFO));
return nullptr;
}

Expand Down
22 changes: 15 additions & 7 deletions llvm/lib/DebugInfo/DWARF/DWARFUnit.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -161,17 +161,24 @@ DWARFUnit *DWARFUnitVector::getUnitForOffset(uint64_t Offset) const {
return nullptr;
}

DWARFUnit *
DWARFUnitVector::getUnitForIndexEntry(const DWARFUnitIndex::Entry &E) {
const auto *CUOff = E.getContribution(DW_SECT_INFO);
DWARFUnit *DWARFUnitVector::getUnitForIndexEntry(const DWARFUnitIndex::Entry &E,
DWARFSectionKind Sec,
const DWARFSection *Section) {
const auto *CUOff = E.getContribution(Sec);
if (!CUOff)
return nullptr;

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

if (Sec == DW_SECT_EXT_TYPES) {
begin = end;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't quite follow this logic.
For DWARF4 .debug_types only has TUs.
For DWARF5 TUs can be anywhere in the .debug_info.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For DWARF4 TUs are stored after CUs in DWOUnits vector:

  /// Get units from .debug_types.dwo in the DWO context.
  unit_iterator_range dwo_types_section_units() {
    DWARFUnitVector &DWOUnits = State->getDWOUnits();
    return unit_iterator_range(DWOUnits.begin() + DWOUnits.getNumInfoUnits(),
                               DWOUnits.end());
  }

DW_SECT_EXT_TYPES indicates that DWARF4 .debug_types is being processed.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I get that part.
I was wondering about this:
begin = end;
I guess getNumInfoUnits() will return 0 since types are in a separate section for DWARF4. Right?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, it will return the number of CUs from the DWGUnits vector. For DWARF4, since TUs are stored after the CUs in the DWGUnits vector, we need to traverse the TUs starting from the end of the CUs.

end = this->end();
}

auto *CU =
std::upper_bound(begin(), end, CUOff->getOffset(),
std::upper_bound(begin, end, CUOff->getOffset(),
[](uint64_t LHS, const std::unique_ptr<DWARFUnit> &RHS) {
return LHS < RHS->getNextUnitOffset();
});
Expand All @@ -181,13 +188,14 @@ DWARFUnitVector::getUnitForIndexEntry(const DWARFUnitIndex::Entry &E) {
if (!Parser)
return nullptr;

auto U = Parser(Offset, DW_SECT_INFO, nullptr, &E);
auto U = Parser(Offset, Sec, Section, &E);
if (!U)
return nullptr;

auto *NewCU = U.get();
this->insert(CU, std::move(U));
++NumInfoUnits;
if (Sec == DW_SECT_INFO)
++NumInfoUnits;
return NewCU;
}

Expand Down
242 changes: 242 additions & 0 deletions llvm/test/tools/llvm-dwarfdump/X86/type_units_split_dwp_v4.s
Original file line number Diff line number Diff line change
@@ -0,0 +1,242 @@
# RUN: llvm-mc %s --split-dwarf-file=test.dwo -filetype obj -triple x86_64 -o test.o
# RUN: llvm-dwp -e test.o -o test.dwp
# RUN: llvm-dwarfdump test.dwp | FileCheck %s

# Generated from:
#
# struct t1 { };
# t1 v1;
#
# $ clang++ -S -g -fdebug-types-section -gsplit-dwarf -o test.4.split.dwp.s -gdwarf-4

# CHECK: DW_TAG_variable
# CHECK: DW_AT_type ({{.*}} "t1")
.file "test.cpp"
.section .debug_types.dwo,"e",@progbits
.long .Ldebug_info_dwo_end0-.Ldebug_info_dwo_start0 # Length of Unit
.Ldebug_info_dwo_start0:
.short 4 # DWARF version number
.long 0 # Offset Into Abbrev. Section
.byte 8 # Address Size (in bytes)
.quad -4149699470930386446 # Type Signature
.long 30 # Type DIE Offset
.byte 1 # Abbrev [1] 0x17:0xe DW_TAG_type_unit
.short 33 # DW_AT_language
.long 0 # DW_AT_stmt_list
.byte 2 # Abbrev [2] 0x1e:0x6 DW_TAG_structure_type
.byte 5 # DW_AT_calling_convention
.byte 1 # DW_AT_name
.byte 1 # DW_AT_byte_size
.byte 1 # DW_AT_decl_file
.byte 1 # DW_AT_decl_line
.byte 0 # End Of Children Mark
.Ldebug_info_dwo_end0:
.file 1 "." "test.cpp"
.type v1,@object # @v1
.bss
.globl v1
v1:
.zero 1
.size v1, 1

.section .debug_abbrev,"",@progbits
.byte 1 # Abbreviation Code
.byte 17 # DW_TAG_compile_unit
.byte 0 # DW_CHILDREN_no
.byte 16 # DW_AT_stmt_list
.byte 23 # DW_FORM_sec_offset
.byte 27 # DW_AT_comp_dir
.byte 14 # DW_FORM_strp
.ascii "\264B" # DW_AT_GNU_pubnames
.byte 25 # DW_FORM_flag_present
.ascii "\260B" # DW_AT_GNU_dwo_name
.byte 14 # DW_FORM_strp
.ascii "\261B" # DW_AT_GNU_dwo_id
.byte 7 # DW_FORM_data8
.ascii "\263B" # DW_AT_GNU_addr_base
.byte 23 # DW_FORM_sec_offset
.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 4 # DWARF version number
.long .debug_abbrev # Offset Into Abbrev. Section
.byte 8 # Address Size (in bytes)
.byte 1 # Abbrev [1] 0xb:0x19 DW_TAG_compile_unit
.long .Lline_table_start0 # DW_AT_stmt_list
.long .Lskel_string0 # DW_AT_comp_dir
# DW_AT_GNU_pubnames
.long .Lskel_string1 # DW_AT_GNU_dwo_name
.quad 1388839634901268525 # DW_AT_GNU_dwo_id
.long .Laddr_table_base0 # DW_AT_GNU_addr_base
.Ldebug_info_end0:
.section .debug_str,"MS",@progbits,1
.Lskel_string0:
.asciz "." # string offset=0
.Lskel_string1:
.asciz "test.dwo" # string offset=2
.section .debug_str.dwo,"eMS",@progbits,1
.Linfo_string0:
.asciz "v1" # string offset=0
.Linfo_string1:
.asciz "t1" # string offset=3
.Linfo_string2:
.asciz "clang version 22.0.0" # string offset=6
.Linfo_string3:
.asciz "test.cpp" # string offset=27
.Linfo_string4:
.asciz "test.dwo" # string offset=36
.section .debug_str_offsets.dwo,"e",@progbits
.long 0
.long 3
.long 6
.long 27
.long 36
.section .debug_info.dwo,"e",@progbits
.long .Ldebug_info_dwo_end1-.Ldebug_info_dwo_start1 # Length of Unit
.Ldebug_info_dwo_start1:
.short 4 # DWARF version number
.long 0 # Offset Into Abbrev. Section
.byte 8 # Address Size (in bytes)
.byte 3 # Abbrev [3] 0xb:0x23 DW_TAG_compile_unit
.byte 2 # DW_AT_producer
.short 33 # DW_AT_language
.byte 3 # DW_AT_name
.byte 4 # DW_AT_GNU_dwo_name
.quad 1388839634901268525 # DW_AT_GNU_dwo_id
.byte 4 # Abbrev [4] 0x19:0xb DW_TAG_variable
.byte 0 # DW_AT_name
.long 36 # DW_AT_type
# DW_AT_external
.byte 1 # DW_AT_decl_file
.byte 2 # DW_AT_decl_line
.byte 2 # DW_AT_location
.byte 251
.byte 0
.byte 5 # Abbrev [5] 0x24:0x9 DW_TAG_structure_type
# DW_AT_declaration
.quad -4149699470930386446 # DW_AT_signature
.byte 0 # End Of Children Mark
.Ldebug_info_dwo_end1:
.section .debug_abbrev.dwo,"e",@progbits
.byte 1 # Abbreviation Code
.byte 65 # DW_TAG_type_unit
.byte 1 # DW_CHILDREN_yes
.byte 19 # DW_AT_language
.byte 5 # DW_FORM_data2
.byte 16 # DW_AT_stmt_list
.byte 23 # DW_FORM_sec_offset
.byte 0 # EOM(1)
.byte 0 # EOM(2)
.byte 2 # Abbreviation Code
.byte 19 # DW_TAG_structure_type
.byte 0 # DW_CHILDREN_no
.byte 54 # DW_AT_calling_convention
.byte 11 # DW_FORM_data1
.byte 3 # DW_AT_name
.ascii "\202>" # DW_FORM_GNU_str_index
.byte 11 # DW_AT_byte_size
.byte 11 # DW_FORM_data1
.byte 58 # DW_AT_decl_file
.byte 11 # DW_FORM_data1
.byte 59 # DW_AT_decl_line
.byte 11 # DW_FORM_data1
.byte 0 # EOM(1)
.byte 0 # EOM(2)
.byte 3 # Abbreviation Code
.byte 17 # DW_TAG_compile_unit
.byte 1 # DW_CHILDREN_yes
.byte 37 # DW_AT_producer
.ascii "\202>" # DW_FORM_GNU_str_index
.byte 19 # DW_AT_language
.byte 5 # DW_FORM_data2
.byte 3 # DW_AT_name
.ascii "\202>" # DW_FORM_GNU_str_index
.ascii "\260B" # DW_AT_GNU_dwo_name
.ascii "\202>" # DW_FORM_GNU_str_index
.ascii "\261B" # DW_AT_GNU_dwo_id
.byte 7 # DW_FORM_data8
.byte 0 # EOM(1)
.byte 0 # EOM(2)
.byte 4 # Abbreviation Code
.byte 52 # DW_TAG_variable
.byte 0 # DW_CHILDREN_no
.byte 3 # DW_AT_name
.ascii "\202>" # DW_FORM_GNU_str_index
.byte 73 # DW_AT_type
.byte 19 # DW_FORM_ref4
.byte 63 # DW_AT_external
.byte 25 # DW_FORM_flag_present
.byte 58 # DW_AT_decl_file
.byte 11 # DW_FORM_data1
.byte 59 # DW_AT_decl_line
.byte 11 # DW_FORM_data1
.byte 2 # DW_AT_location
.byte 24 # DW_FORM_exprloc
.byte 0 # EOM(1)
.byte 0 # EOM(2)
.byte 5 # Abbreviation Code
.byte 19 # DW_TAG_structure_type
.byte 0 # DW_CHILDREN_no
.byte 60 # DW_AT_declaration
.byte 25 # DW_FORM_flag_present
.byte 105 # DW_AT_signature
.byte 32 # DW_FORM_ref_sig8
.byte 0 # EOM(1)
.byte 0 # EOM(2)
.byte 0 # EOM(3)
.section .debug_line.dwo,"e",@progbits
.Ltmp0:
.long .Ldebug_line_end0-.Ldebug_line_start0 # unit length
.Ldebug_line_start0:
.short 4
.long .Lprologue_end0-.Lprologue_start0
.Lprologue_start0:
.byte 1
.byte 1
.byte 1
.byte -5
.byte 14
.byte 1
.byte 0
.ascii "test.cpp"
.byte 0
.byte 0
.byte 0
.byte 0
.byte 0
.Lprologue_end0:
.Ldebug_line_end0:
.section .debug_addr,"",@progbits
.Laddr_table_base0:
.quad v1
.section .debug_gnu_pubnames,"",@progbits
.long .LpubNames_end0-.LpubNames_start0 # Length of Public Names Info
.LpubNames_start0:
.short 2 # DWARF Version
.long .Lcu_begin0 # Offset of Compilation Unit Info
.long 36 # Compilation Unit Length
.long 25 # DIE offset
.byte 32 # Attributes: VARIABLE, EXTERNAL
.asciz "v1" # External Name
.long 0 # End Mark
.LpubNames_end0:
.section .debug_gnu_pubtypes,"",@progbits
.long .LpubTypes_end0-.LpubTypes_start0 # Length of Public Types Info
.LpubTypes_start0:
.short 2 # DWARF Version
.long .Lcu_begin0 # Offset of Compilation Unit Info
.long 36 # Compilation Unit Length
.long 36 # DIE offset
.byte 16 # Attributes: TYPE, EXTERNAL
.asciz "t1" # External Name
.long 0 # End Mark
.LpubTypes_end0:
.ident "clang version 22.0.0"
.section ".note.GNU-stack","",@progbits
.addrsig
.section .debug_line,"",@progbits
.Lline_table_start0:
Loading