[llvm] [BOLT][DWARF] Fix handling of DWARF5 DWP (PR #72729)
Alexander Yermolovich via llvm-commits
llvm-commits at lists.llvm.org
Fri Nov 17 16:47:17 PST 2023
https://github.com/ayermolo updated https://github.com/llvm/llvm-project/pull/72729
>From e27353a5437341034811feb6b9452967d5b7c336 Mon Sep 17 00:00:00 2001
From: Alexander Yermolovich <ayermolo at meta.com>
Date: Fri, 17 Nov 2023 12:09:34 -0800
Subject: [PATCH] [BOLT][DWARF] Fix handling of DWARF5 DWP
Fixed handling of DWP as input. Before BOLT crashed. Now it will write out
correct CU, and all the TUs. Potential future improvement is to scan all the TUs
used in this CU, and only include those.
---
bolt/include/bolt/Core/DIEBuilder.h | 3 +-
bolt/lib/Core/DIEBuilder.cpp | 17 +-
bolt/lib/Rewrite/DWARFRewriter.cpp | 14 +-
.../X86/Inputs/dwarf5-df-types-dup-helper.s | 504 ++++++++++++++++++
.../X86/Inputs/dwarf5-df-types-dup-main.s | 498 +++++++++++++++++
.../X86/dwarf5-df-types-dup-dwp-input.test | 29 +
6 files changed, 1048 insertions(+), 17 deletions(-)
create mode 100644 bolt/test/X86/Inputs/dwarf5-df-types-dup-helper.s
create mode 100644 bolt/test/X86/Inputs/dwarf5-df-types-dup-main.s
create mode 100644 bolt/test/X86/dwarf5-df-types-dup-dwp-input.test
diff --git a/bolt/include/bolt/Core/DIEBuilder.h b/bolt/include/bolt/Core/DIEBuilder.h
index fb86e59468b835a..1c5252142d4ebf5 100644
--- a/bolt/include/bolt/Core/DIEBuilder.h
+++ b/bolt/include/bolt/Core/DIEBuilder.h
@@ -273,7 +273,8 @@ class DIEBuilder {
void buildCompileUnits(const std::vector<DWARFUnit *> &CUs);
/// Preventing implicit conversions.
template <class T> void buildCompileUnits(T) = delete;
- void buildBoth();
+ /// Builds DWO Unit. For DWARF5 this includes the type units.
+ void buildDWOUnit(DWARFUnit &U);
/// Returns DWARFUnitInfo for DWARFUnit
DWARFUnitInfo &getUnitInfoByDwarfUnit(const DWARFUnit &DwarfUnit) {
diff --git a/bolt/lib/Core/DIEBuilder.cpp b/bolt/lib/Core/DIEBuilder.cpp
index 223ae714440d97d..6b33303ba553b72 100644
--- a/bolt/lib/Core/DIEBuilder.cpp
+++ b/bolt/lib/Core/DIEBuilder.cpp
@@ -193,12 +193,6 @@ void DIEBuilder::buildTypeUnits(const bool Init) {
if (Init)
BuilderState.reset(new State());
- unsigned int CUNum = getCUNum(DwarfContext, IsDWO);
- getState().CloneUnitCtxMap.resize(CUNum);
- DWARFContext::unit_iterator_range CU4TURanges =
- IsDWO ? DwarfContext->dwo_types_section_units()
- : DwarfContext->types_section_units();
-
const DWARFUnitIndex &TUIndex = DwarfContext->getTUIndex();
if (!TUIndex.getRows().empty()) {
for (auto &Row : TUIndex.getRows()) {
@@ -208,6 +202,11 @@ void DIEBuilder::buildTypeUnits(const bool Init) {
true);
}
}
+ unsigned int CUNum = getCUNum(DwarfContext, IsDWO);
+ getState().CloneUnitCtxMap.resize(CUNum);
+ DWARFContext::unit_iterator_range CU4TURanges =
+ IsDWO ? DwarfContext->dwo_types_section_units()
+ : DwarfContext->types_section_units();
getState().Type = ProcessingType::DWARF4TUs;
for (std::unique_ptr<DWARFUnit> &DU : CU4TURanges)
@@ -278,11 +277,13 @@ void DIEBuilder::buildCompileUnits(const std::vector<DWARFUnit *> &CUs) {
constructFromUnit(*DU);
}
-void DIEBuilder::buildBoth() {
+void DIEBuilder::buildDWOUnit(DWARFUnit &U) {
BuilderState.release();
BuilderState = std::make_unique<State>();
buildTypeUnits(false);
- buildCompileUnits(false);
+ getState().Type = ProcessingType::CUs;
+ registerUnit(U, false);
+ constructFromUnit(U);
}
DIE *DIEBuilder::constructDIEFast(DWARFDie &DDie, DWARFUnit &U,
diff --git a/bolt/lib/Rewrite/DWARFRewriter.cpp b/bolt/lib/Rewrite/DWARFRewriter.cpp
index 360b82f45bd7754..3bba61724b9e542 100644
--- a/bolt/lib/Rewrite/DWARFRewriter.cpp
+++ b/bolt/lib/Rewrite/DWARFRewriter.cpp
@@ -481,7 +481,7 @@ emitUnit(DIEBuilder &DIEBldr, DIEStreamer &Streamer, DWARFUnit &Unit) {
static void emitDWOBuilder(const std::string &DWOName,
DIEBuilder &DWODIEBuilder, DWARFRewriter &Rewriter,
- const DWARFUnit &SplitCU, DWARFUnit &CU,
+ DWARFUnit &SplitCU, DWARFUnit &CU,
DWARFRewriter::DWPState &State,
DebugLocWriter &LocWriter) {
// Populate debug_info and debug_abbrev for current dwo into StringRef.
@@ -498,17 +498,15 @@ static void emitDWOBuilder(const std::string &DWOName,
DWARFRewriter::UnitMetaVectorType TUMetaVector;
DWARFRewriter::UnitMeta CUMI = {0, 0, 0};
if (SplitCU.getContext().getMaxDWOVersion() >= 5) {
- // TODO: Handle DWP as input. Right now it will iterate over all of CUs and
- // TUs
for (std::unique_ptr<llvm::DWARFUnit> &CU :
SplitCU.getContext().dwo_info_section_units()) {
+ if (!CU->isTypeUnit())
+ continue;
DWARFRewriter::UnitMeta MI =
emitUnit(DWODIEBuilder, *Streamer, *CU.get());
- if (CU->isTypeUnit())
- TUMetaVector.emplace_back(MI);
- else
- CUMI = MI;
+ TUMetaVector.emplace_back(MI);
}
+ CUMI = emitUnit(DWODIEBuilder, *Streamer, SplitCU);
} else {
for (std::unique_ptr<llvm::DWARFUnit> &CU :
SplitCU.getContext().dwo_compile_units())
@@ -707,7 +705,7 @@ void DWARFRewriter::updateDebugInfo() {
// Skipping CUs that failed to load.
if (SplitCU) {
DIEBuilder DWODIEBuilder(&(*SplitCU)->getContext(), true);
- DWODIEBuilder.buildBoth();
+ DWODIEBuilder.buildDWOUnit(**SplitCU);
std::string DWOName = updateDWONameCompDir(
*Unit, *DIEBlder, *DIEBlder->getUnitDIEbyUnit(*Unit));
diff --git a/bolt/test/X86/Inputs/dwarf5-df-types-dup-helper.s b/bolt/test/X86/Inputs/dwarf5-df-types-dup-helper.s
new file mode 100644
index 000000000000000..cf0bdad3bbda188
--- /dev/null
+++ b/bolt/test/X86/Inputs/dwarf5-df-types-dup-helper.s
@@ -0,0 +1,504 @@
+# clang++ -gsplit-dwarf -g2 -gdwarf-5 -gpubnames -fdebug-types-section -fdebug-compilation-dir='.'
+# header.h
+# struct Foo2a {
+# char *c1;
+# char *c2;
+# char *c3;
+# };
+
+# main.cpp
+# #include "header.h"
+# int fooint;
+# struct Foo2Int {
+# int *c1;
+# int *c2;
+# };
+#
+# int foo() {
+# Foo2Int fint;
+# Foo2a f;
+# return 0;
+# }
+
+ .text
+ .file "helper.cpp"
+ .file 0 "." "helper.cpp" md5 0xc33186b2db66a78883b1546aace9855d
+ .globl _Z3foov # -- Begin function _Z3foov
+ .p2align 4, 0x90
+ .type _Z3foov, at function
+_Z3foov: # @_Z3foov
+.Lfunc_begin0:
+ .loc 0 8 0 # helper.cpp:8:0
+ .cfi_startproc
+# %bb.0: # %entry
+ pushq %rbp
+ .cfi_def_cfa_offset 16
+ .cfi_offset %rbp, -16
+ movq %rsp, %rbp
+ .cfi_def_cfa_register %rbp
+.Ltmp0:
+ .loc 0 11 3 prologue_end # helper.cpp:11:3
+ xorl %eax, %eax
+ .loc 0 11 3 epilogue_begin is_stmt 0 # helper.cpp:11:3
+ popq %rbp
+ .cfi_def_cfa %rsp, 8
+ retq
+.Ltmp1:
+.Lfunc_end0:
+ .size _Z3foov, .Lfunc_end0-_Z3foov
+ .cfi_endproc
+ # -- End function
+ .type fooint, at object # @fooint
+ .bss
+ .globl fooint
+ .p2align 2, 0x0
+fooint:
+ .long 0 # 0x0
+ .size fooint, 4
+
+ .section .debug_info.dwo,"e", at 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
+ .byte 8 # Address Size (in bytes)
+ .long 0 # Offset Into Abbrev. Section
+ .quad -3882554063269480080 # Type Signature
+ .long 31 # Type DIE Offset
+ .byte 1 # Abbrev [1] 0x18:0x2a DW_TAG_type_unit
+ .short 33 # DW_AT_language
+ .long 0 # DW_AT_stmt_list
+ .byte 2 # Abbrev [2] 0x1f:0x19 DW_TAG_structure_type
+ .byte 5 # DW_AT_calling_convention
+ .byte 7 # DW_AT_name
+ .byte 16 # DW_AT_byte_size
+ .byte 0 # DW_AT_decl_file
+ .byte 3 # DW_AT_decl_line
+ .byte 3 # Abbrev [3] 0x25:0x9 DW_TAG_member
+ .byte 5 # DW_AT_name
+ .long 56 # DW_AT_type
+ .byte 0 # DW_AT_decl_file
+ .byte 4 # DW_AT_decl_line
+ .byte 0 # DW_AT_data_member_location
+ .byte 3 # Abbrev [3] 0x2e:0x9 DW_TAG_member
+ .byte 6 # DW_AT_name
+ .long 56 # DW_AT_type
+ .byte 0 # DW_AT_decl_file
+ .byte 5 # DW_AT_decl_line
+ .byte 8 # DW_AT_data_member_location
+ .byte 0 # End Of Children Mark
+ .byte 4 # Abbrev [4] 0x38:0x5 DW_TAG_pointer_type
+ .long 61 # DW_AT_type
+ .byte 5 # Abbrev [5] 0x3d:0x4 DW_TAG_base_type
+ .byte 1 # DW_AT_name
+ .byte 5 # DW_AT_encoding
+ .byte 4 # DW_AT_byte_size
+ .byte 0 # End Of Children Mark
+.Ldebug_info_dwo_end0:
+ .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
+ .byte 8 # Address Size (in bytes)
+ .long 0 # Offset Into Abbrev. Section
+ .quad 1175092228111723119 # Type Signature
+ .long 31 # Type DIE Offset
+ .byte 1 # Abbrev [1] 0x18:0x33 DW_TAG_type_unit
+ .short 33 # DW_AT_language
+ .long 0 # DW_AT_stmt_list
+ .byte 2 # Abbrev [2] 0x1f:0x22 DW_TAG_structure_type
+ .byte 5 # DW_AT_calling_convention
+ .byte 11 # DW_AT_name
+ .byte 24 # DW_AT_byte_size
+ .byte 1 # DW_AT_decl_file
+ .byte 1 # DW_AT_decl_line
+ .byte 3 # Abbrev [3] 0x25:0x9 DW_TAG_member
+ .byte 5 # DW_AT_name
+ .long 65 # DW_AT_type
+ .byte 1 # DW_AT_decl_file
+ .byte 2 # DW_AT_decl_line
+ .byte 0 # DW_AT_data_member_location
+ .byte 3 # Abbrev [3] 0x2e:0x9 DW_TAG_member
+ .byte 6 # DW_AT_name
+ .long 65 # DW_AT_type
+ .byte 1 # DW_AT_decl_file
+ .byte 3 # DW_AT_decl_line
+ .byte 8 # DW_AT_data_member_location
+ .byte 3 # Abbrev [3] 0x37:0x9 DW_TAG_member
+ .byte 10 # DW_AT_name
+ .long 65 # DW_AT_type
+ .byte 1 # DW_AT_decl_file
+ .byte 4 # DW_AT_decl_line
+ .byte 16 # DW_AT_data_member_location
+ .byte 0 # End Of Children Mark
+ .byte 4 # Abbrev [4] 0x41:0x5 DW_TAG_pointer_type
+ .long 70 # DW_AT_type
+ .byte 5 # Abbrev [5] 0x46:0x4 DW_TAG_base_type
+ .byte 9 # DW_AT_name
+ .byte 6 # DW_AT_encoding
+ .byte 1 # DW_AT_byte_size
+ .byte 0 # End Of Children Mark
+.Ldebug_info_dwo_end1:
+ .section .debug_abbrev,"", at progbits
+ .byte 1 # Abbreviation Code
+ .byte 74 # DW_TAG_skeleton_unit
+ .byte 0 # DW_CHILDREN_no
+ .byte 16 # DW_AT_stmt_list
+ .byte 23 # DW_FORM_sec_offset
+ .byte 114 # DW_AT_str_offsets_base
+ .byte 23 # DW_FORM_sec_offset
+ .byte 27 # DW_AT_comp_dir
+ .byte 37 # DW_FORM_strx1
+ .byte 118 # DW_AT_dwo_name
+ .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 0 # EOM(3)
+ .section .debug_info,"", at progbits
+.Lcu_begin0:
+ .long .Ldebug_info_end0-.Ldebug_info_start0 # Length of Unit
+.Ldebug_info_start0:
+ .short 5 # DWARF version number
+ .byte 4 # DWARF Unit Type
+ .byte 8 # Address Size (in bytes)
+ .long .debug_abbrev # Offset Into Abbrev. Section
+ .quad 2142419470755914572
+ .byte 1 # Abbrev [1] 0x14:0x14 DW_TAG_skeleton_unit
+ .long .Lline_table_start0 # DW_AT_stmt_list
+ .long .Lstr_offsets_base0 # DW_AT_str_offsets_base
+ .byte 0 # DW_AT_comp_dir
+ .byte 1 # DW_AT_dwo_name
+ .byte 1 # DW_AT_low_pc
+ .long .Lfunc_end0-.Lfunc_begin0 # DW_AT_high_pc
+ .long .Laddr_table_base0 # DW_AT_addr_base
+.Ldebug_info_end0:
+ .section .debug_str_offsets,"", at progbits
+ .long 12 # Length of String Offsets Set
+ .short 5
+ .short 0
+.Lstr_offsets_base0:
+ .section .debug_str,"MS", at progbits,1
+.Lskel_string0:
+ .asciz "." # string offset=0
+.Lskel_string1:
+ .asciz "helper.dwo" # string offset=2
+ .section .debug_str_offsets,"", at progbits
+ .long .Lskel_string0
+ .long .Lskel_string1
+ .section .debug_str_offsets.dwo,"e", at progbits
+ .long 64 # Length of String Offsets Set
+ .short 5
+ .short 0
+ .section .debug_str.dwo,"eMS", at progbits,1
+.Linfo_string0:
+ .asciz "fooint" # string offset=0
+.Linfo_string1:
+ .asciz "int" # string offset=7
+.Linfo_string2:
+ .asciz "_Z3foov" # string offset=11
+.Linfo_string3:
+ .asciz "foo" # string offset=19
+.Linfo_string4:
+ .asciz "fint" # string offset=23
+.Linfo_string5:
+ .asciz "c1" # string offset=28
+.Linfo_string6:
+ .asciz "c2" # string offset=31
+.Linfo_string7:
+ .asciz "Foo2Int" # string offset=34
+.Linfo_string8:
+ .asciz "f" # string offset=42
+.Linfo_string9:
+ .asciz "char" # string offset=44
+.Linfo_string10:
+ .asciz "c3" # string offset=49
+.Linfo_string11:
+ .asciz "Foo2a" # string offset=52
+.Linfo_string12:
+ .asciz "clang version 18.0.0" # string offset=58
+.Linfo_string13:
+ .asciz "helper.cpp" # string offset=79
+.Linfo_string14:
+ .asciz "helper.dwo" # string offset=90
+ .section .debug_str_offsets.dwo,"e", at progbits
+ .long 0
+ .long 7
+ .long 11
+ .long 19
+ .long 23
+ .long 28
+ .long 31
+ .long 34
+ .long 42
+ .long 44
+ .long 49
+ .long 52
+ .long 58
+ .long 79
+ .long 90
+ .section .debug_info.dwo,"e", at 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
+ .byte 8 # Address Size (in bytes)
+ .long 0 # Offset Into Abbrev. Section
+ .quad 2142419470755914572
+ .byte 6 # Abbrev [6] 0x14:0x4f DW_TAG_compile_unit
+ .byte 12 # DW_AT_producer
+ .short 33 # DW_AT_language
+ .byte 13 # DW_AT_name
+ .byte 14 # DW_AT_dwo_name
+ .byte 7 # Abbrev [7] 0x1a:0xb DW_TAG_variable
+ .byte 0 # DW_AT_name
+ .long 37 # DW_AT_type
+ # DW_AT_external
+ .byte 0 # DW_AT_decl_file
+ .byte 2 # DW_AT_decl_line
+ .byte 2 # DW_AT_location
+ .byte 161
+ .byte 0
+ .byte 5 # Abbrev [5] 0x25:0x4 DW_TAG_base_type
+ .byte 1 # DW_AT_name
+ .byte 5 # DW_AT_encoding
+ .byte 4 # DW_AT_byte_size
+ .byte 8 # Abbrev [8] 0x29:0x27 DW_TAG_subprogram
+ .byte 1 # DW_AT_low_pc
+ .long .Lfunc_end0-.Lfunc_begin0 # DW_AT_high_pc
+ .byte 1 # DW_AT_frame_base
+ .byte 86
+ .byte 2 # DW_AT_linkage_name
+ .byte 3 # DW_AT_name
+ .byte 0 # DW_AT_decl_file
+ .byte 8 # DW_AT_decl_line
+ .long 37 # DW_AT_type
+ # DW_AT_external
+ .byte 9 # Abbrev [9] 0x39:0xb DW_TAG_variable
+ .byte 2 # DW_AT_location
+ .byte 145
+ .byte 112
+ .byte 4 # DW_AT_name
+ .byte 0 # DW_AT_decl_file
+ .byte 9 # DW_AT_decl_line
+ .long 80 # DW_AT_type
+ .byte 9 # Abbrev [9] 0x44:0xb DW_TAG_variable
+ .byte 2 # DW_AT_location
+ .byte 145
+ .byte 88
+ .byte 8 # DW_AT_name
+ .byte 0 # DW_AT_decl_file
+ .byte 10 # DW_AT_decl_line
+ .long 89 # DW_AT_type
+ .byte 0 # End Of Children Mark
+ .byte 10 # Abbrev [10] 0x50:0x9 DW_TAG_structure_type
+ # DW_AT_declaration
+ .quad -3882554063269480080 # DW_AT_signature
+ .byte 10 # Abbrev [10] 0x59:0x9 DW_TAG_structure_type
+ # DW_AT_declaration
+ .quad 1175092228111723119 # DW_AT_signature
+ .byte 0 # End Of Children Mark
+.Ldebug_info_dwo_end2:
+ .section .debug_abbrev.dwo,"e", at 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 1 # DW_CHILDREN_yes
+ .byte 54 # DW_AT_calling_convention
+ .byte 11 # DW_FORM_data1
+ .byte 3 # DW_AT_name
+ .byte 37 # DW_FORM_strx1
+ .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 13 # DW_TAG_member
+ .byte 0 # DW_CHILDREN_no
+ .byte 3 # DW_AT_name
+ .byte 37 # DW_FORM_strx1
+ .byte 73 # DW_AT_type
+ .byte 19 # DW_FORM_ref4
+ .byte 58 # DW_AT_decl_file
+ .byte 11 # DW_FORM_data1
+ .byte 59 # DW_AT_decl_line
+ .byte 11 # DW_FORM_data1
+ .byte 56 # DW_AT_data_member_location
+ .byte 11 # DW_FORM_data1
+ .byte 0 # EOM(1)
+ .byte 0 # EOM(2)
+ .byte 4 # Abbreviation Code
+ .byte 15 # DW_TAG_pointer_type
+ .byte 0 # DW_CHILDREN_no
+ .byte 73 # DW_AT_type
+ .byte 19 # DW_FORM_ref4
+ .byte 0 # EOM(1)
+ .byte 0 # EOM(2)
+ .byte 5 # 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 6 # 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 118 # DW_AT_dwo_name
+ .byte 37 # DW_FORM_strx1
+ .byte 0 # EOM(1)
+ .byte 0 # EOM(2)
+ .byte 7 # Abbreviation Code
+ .byte 52 # DW_TAG_variable
+ .byte 0 # DW_CHILDREN_no
+ .byte 3 # DW_AT_name
+ .byte 37 # DW_FORM_strx1
+ .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 8 # Abbreviation Code
+ .byte 46 # DW_TAG_subprogram
+ .byte 1 # DW_CHILDREN_yes
+ .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 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 9 # Abbreviation Code
+ .byte 52 # DW_TAG_variable
+ .byte 0 # DW_CHILDREN_no
+ .byte 2 # DW_AT_location
+ .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 0 # EOM(1)
+ .byte 0 # EOM(2)
+ .byte 10 # 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", at progbits
+.Ltmp2:
+ .long .Ldebug_line_end0-.Ldebug_line_start0 # unit length
+.Ldebug_line_start0:
+ .short 5
+ .byte 8
+ .byte 0
+ .long .Lprologue_end0-.Lprologue_start0
+.Lprologue_start0:
+ .byte 1
+ .byte 1
+ .byte 1
+ .byte -5
+ .byte 14
+ .byte 1
+ .byte 1
+ .byte 1
+ .byte 8
+ .byte 2
+ .byte 46
+ .byte 0
+ .byte 46
+ .byte 0
+ .byte 3
+ .byte 1
+ .byte 8
+ .byte 2
+ .byte 15
+ .byte 5
+ .byte 30
+ .byte 2
+ .ascii "helper.cpp"
+ .byte 0
+ .byte 0
+ .byte 0xc3, 0x31, 0x86, 0xb2
+ .byte 0xdb, 0x66, 0xa7, 0x88
+ .byte 0x83, 0xb1, 0x54, 0x6a
+ .byte 0xac, 0xe9, 0x85, 0x5d
+ .ascii "header.h"
+ .byte 0
+ .byte 1
+ .byte 0xfe, 0xa7, 0xbb, 0x1f
+ .byte 0x22, 0xc4, 0x7f, 0x12
+ .byte 0x9e, 0x15, 0x69, 0x5f
+ .byte 0x71, 0x37, 0xa1, 0xe7
+.Lprologue_end0:
+.Ldebug_line_end0:
+ .section .debug_addr,"", at 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 fooint
+ .quad .Lfunc_begin0
+.Ldebug_addr_end0:
+ .ident "clang version 18.0.0"
+ .section ".note.GNU-stack","", at progbits
+ .addrsig
+ .section .debug_line,"", at progbits
+.Lline_table_start0:
diff --git a/bolt/test/X86/Inputs/dwarf5-df-types-dup-main.s b/bolt/test/X86/Inputs/dwarf5-df-types-dup-main.s
new file mode 100644
index 000000000000000..d991094cf0a0818
--- /dev/null
+++ b/bolt/test/X86/Inputs/dwarf5-df-types-dup-main.s
@@ -0,0 +1,498 @@
+# clang++ -gsplit-dwarf -g2 -gdwarf-5 -gpubnames -fdebug-types-section -fdebug-compilation-dir='.'
+# header.h
+# struct Foo2a {
+# char *c1;
+# char *c2;
+# char *c3;
+# };
+
+# main.cpp
+# #include "header.h"
+# struct Foo2 {
+# char *c1;
+# };
+# int main(int argc, char *argv[]) {
+# Foo2 f2;
+# Foo2a f3;
+# return 0;
+# }
+ .text
+ .file "main.cpp"
+ .globl main # -- Begin function main
+ .p2align 4, 0x90
+ .type main, at function
+main: # @main
+.Lfunc_begin0:
+ .file 0 "." "main.cpp" md5 0x9c5cea5bb78d3fc265cd175110bfe903
+ .loc 0 5 0 # main.cpp:5:0
+ .cfi_startproc
+# %bb.0: # %entry
+ pushq %rbp
+ .cfi_def_cfa_offset 16
+ .cfi_offset %rbp, -16
+ movq %rsp, %rbp
+ .cfi_def_cfa_register %rbp
+ movl $0, -4(%rbp)
+ movl %edi, -8(%rbp)
+ movq %rsi, -16(%rbp)
+.Ltmp0:
+ .loc 0 8 2 prologue_end # main.cpp:8:2
+ xorl %eax, %eax
+ .loc 0 8 2 epilogue_begin is_stmt 0 # main.cpp:8:2
+ popq %rbp
+ .cfi_def_cfa %rsp, 8
+ retq
+.Ltmp1:
+.Lfunc_end0:
+ .size main, .Lfunc_end0-main
+ .cfi_endproc
+ # -- End function
+ .section .debug_info.dwo,"e", at 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
+ .byte 8 # Address Size (in bytes)
+ .long 0 # Offset Into Abbrev. Section
+ .quad 5322170643381124694 # Type Signature
+ .long 31 # Type DIE Offset
+ .byte 1 # Abbrev [1] 0x18:0x21 DW_TAG_type_unit
+ .short 33 # DW_AT_language
+ .long 0 # DW_AT_stmt_list
+ .byte 2 # Abbrev [2] 0x1f:0x10 DW_TAG_structure_type
+ .byte 5 # DW_AT_calling_convention
+ .byte 7 # DW_AT_name
+ .byte 8 # DW_AT_byte_size
+ .byte 0 # DW_AT_decl_file
+ .byte 2 # DW_AT_decl_line
+ .byte 3 # Abbrev [3] 0x25:0x9 DW_TAG_member
+ .byte 6 # DW_AT_name
+ .long 47 # DW_AT_type
+ .byte 0 # DW_AT_decl_file
+ .byte 3 # DW_AT_decl_line
+ .byte 0 # DW_AT_data_member_location
+ .byte 0 # End Of Children Mark
+ .byte 4 # Abbrev [4] 0x2f:0x5 DW_TAG_pointer_type
+ .long 52 # DW_AT_type
+ .byte 5 # Abbrev [5] 0x34:0x4 DW_TAG_base_type
+ .byte 4 # DW_AT_name
+ .byte 6 # DW_AT_encoding
+ .byte 1 # DW_AT_byte_size
+ .byte 0 # End Of Children Mark
+.Ldebug_info_dwo_end0:
+ .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
+ .byte 8 # Address Size (in bytes)
+ .long 0 # Offset Into Abbrev. Section
+ .quad 1175092228111723119 # Type Signature
+ .long 31 # Type DIE Offset
+ .byte 1 # Abbrev [1] 0x18:0x33 DW_TAG_type_unit
+ .short 33 # DW_AT_language
+ .long 0 # DW_AT_stmt_list
+ .byte 2 # Abbrev [2] 0x1f:0x22 DW_TAG_structure_type
+ .byte 5 # DW_AT_calling_convention
+ .byte 11 # DW_AT_name
+ .byte 24 # DW_AT_byte_size
+ .byte 1 # DW_AT_decl_file
+ .byte 1 # DW_AT_decl_line
+ .byte 3 # Abbrev [3] 0x25:0x9 DW_TAG_member
+ .byte 6 # DW_AT_name
+ .long 65 # DW_AT_type
+ .byte 1 # DW_AT_decl_file
+ .byte 2 # DW_AT_decl_line
+ .byte 0 # DW_AT_data_member_location
+ .byte 3 # Abbrev [3] 0x2e:0x9 DW_TAG_member
+ .byte 9 # DW_AT_name
+ .long 65 # DW_AT_type
+ .byte 1 # DW_AT_decl_file
+ .byte 3 # DW_AT_decl_line
+ .byte 8 # DW_AT_data_member_location
+ .byte 3 # Abbrev [3] 0x37:0x9 DW_TAG_member
+ .byte 10 # DW_AT_name
+ .long 65 # DW_AT_type
+ .byte 1 # DW_AT_decl_file
+ .byte 4 # DW_AT_decl_line
+ .byte 16 # DW_AT_data_member_location
+ .byte 0 # End Of Children Mark
+ .byte 4 # Abbrev [4] 0x41:0x5 DW_TAG_pointer_type
+ .long 70 # DW_AT_type
+ .byte 5 # Abbrev [5] 0x46:0x4 DW_TAG_base_type
+ .byte 4 # DW_AT_name
+ .byte 6 # DW_AT_encoding
+ .byte 1 # DW_AT_byte_size
+ .byte 0 # End Of Children Mark
+.Ldebug_info_dwo_end1:
+ .section .debug_abbrev,"", at progbits
+ .byte 1 # Abbreviation Code
+ .byte 74 # DW_TAG_skeleton_unit
+ .byte 0 # DW_CHILDREN_no
+ .byte 16 # DW_AT_stmt_list
+ .byte 23 # DW_FORM_sec_offset
+ .byte 114 # DW_AT_str_offsets_base
+ .byte 23 # DW_FORM_sec_offset
+ .byte 27 # DW_AT_comp_dir
+ .byte 37 # DW_FORM_strx1
+ .byte 118 # DW_AT_dwo_name
+ .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 0 # EOM(3)
+ .section .debug_info,"", at progbits
+.Lcu_begin0:
+ .long .Ldebug_info_end0-.Ldebug_info_start0 # Length of Unit
+.Ldebug_info_start0:
+ .short 5 # DWARF version number
+ .byte 4 # DWARF Unit Type
+ .byte 8 # Address Size (in bytes)
+ .long .debug_abbrev # Offset Into Abbrev. Section
+ .quad 5962099678818150071
+ .byte 1 # Abbrev [1] 0x14:0x14 DW_TAG_skeleton_unit
+ .long .Lline_table_start0 # DW_AT_stmt_list
+ .long .Lstr_offsets_base0 # DW_AT_str_offsets_base
+ .byte 0 # DW_AT_comp_dir
+ .byte 1 # DW_AT_dwo_name
+ .byte 0 # DW_AT_low_pc
+ .long .Lfunc_end0-.Lfunc_begin0 # DW_AT_high_pc
+ .long .Laddr_table_base0 # DW_AT_addr_base
+.Ldebug_info_end0:
+ .section .debug_str_offsets,"", at progbits
+ .long 12 # Length of String Offsets Set
+ .short 5
+ .short 0
+.Lstr_offsets_base0:
+ .section .debug_str,"MS", at progbits,1
+.Lskel_string0:
+ .asciz "." # string offset=0
+.Lskel_string1:
+ .asciz "main.dwo" # string offset=2
+ .section .debug_str_offsets,"", at progbits
+ .long .Lskel_string0
+ .long .Lskel_string1
+ .section .debug_str_offsets.dwo,"e", at progbits
+ .long 64 # Length of String Offsets Set
+ .short 5
+ .short 0
+ .section .debug_str.dwo,"eMS", at progbits,1
+.Linfo_string0:
+ .asciz "main" # string offset=0
+.Linfo_string1:
+ .asciz "int" # string offset=5
+.Linfo_string2:
+ .asciz "argc" # string offset=9
+.Linfo_string3:
+ .asciz "argv" # string offset=14
+.Linfo_string4:
+ .asciz "char" # string offset=19
+.Linfo_string5:
+ .asciz "f2" # string offset=24
+.Linfo_string6:
+ .asciz "c1" # string offset=27
+.Linfo_string7:
+ .asciz "Foo2" # string offset=30
+.Linfo_string8:
+ .asciz "f3" # string offset=35
+.Linfo_string9:
+ .asciz "c2" # string offset=38
+.Linfo_string10:
+ .asciz "c3" # string offset=41
+.Linfo_string11:
+ .asciz "Foo2a" # string offset=44
+.Linfo_string12:
+ .asciz "clang version 18.0.0" # string offset=50
+.Linfo_string13:
+ .asciz "main.cpp" # string offset=71
+.Linfo_string14:
+ .asciz "main.dwo" # string offset=80
+ .section .debug_str_offsets.dwo,"e", at progbits
+ .long 0
+ .long 5
+ .long 9
+ .long 14
+ .long 19
+ .long 24
+ .long 27
+ .long 30
+ .long 35
+ .long 38
+ .long 41
+ .long 44
+ .long 50
+ .long 71
+ .long 80
+ .section .debug_info.dwo,"e", at 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
+ .byte 8 # Address Size (in bytes)
+ .long 0 # Offset Into Abbrev. Section
+ .quad 5962099678818150071
+ .byte 6 # Abbrev [6] 0x14:0x67 DW_TAG_compile_unit
+ .byte 12 # DW_AT_producer
+ .short 33 # DW_AT_language
+ .byte 13 # DW_AT_name
+ .byte 14 # DW_AT_dwo_name
+ .byte 7 # Abbrev [7] 0x1a:0x3c 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 0 # DW_AT_name
+ .byte 0 # DW_AT_decl_file
+ .byte 5 # DW_AT_decl_line
+ .long 86 # DW_AT_type
+ # DW_AT_external
+ .byte 8 # Abbrev [8] 0x29:0xb DW_TAG_formal_parameter
+ .byte 2 # DW_AT_location
+ .byte 145
+ .byte 120
+ .byte 2 # DW_AT_name
+ .byte 0 # DW_AT_decl_file
+ .byte 5 # DW_AT_decl_line
+ .long 86 # DW_AT_type
+ .byte 8 # Abbrev [8] 0x34:0xb DW_TAG_formal_parameter
+ .byte 2 # DW_AT_location
+ .byte 145
+ .byte 112
+ .byte 3 # DW_AT_name
+ .byte 0 # DW_AT_decl_file
+ .byte 5 # DW_AT_decl_line
+ .long 90 # DW_AT_type
+ .byte 9 # Abbrev [9] 0x3f:0xb DW_TAG_variable
+ .byte 2 # DW_AT_location
+ .byte 145
+ .byte 104
+ .byte 5 # DW_AT_name
+ .byte 0 # DW_AT_decl_file
+ .byte 6 # DW_AT_decl_line
+ .long 104 # DW_AT_type
+ .byte 9 # Abbrev [9] 0x4a:0xb DW_TAG_variable
+ .byte 2 # DW_AT_location
+ .byte 145
+ .byte 80
+ .byte 8 # DW_AT_name
+ .byte 0 # DW_AT_decl_file
+ .byte 7 # DW_AT_decl_line
+ .long 113 # DW_AT_type
+ .byte 0 # End Of Children Mark
+ .byte 5 # Abbrev [5] 0x56:0x4 DW_TAG_base_type
+ .byte 1 # DW_AT_name
+ .byte 5 # DW_AT_encoding
+ .byte 4 # DW_AT_byte_size
+ .byte 4 # Abbrev [4] 0x5a:0x5 DW_TAG_pointer_type
+ .long 95 # DW_AT_type
+ .byte 4 # Abbrev [4] 0x5f:0x5 DW_TAG_pointer_type
+ .long 100 # DW_AT_type
+ .byte 5 # Abbrev [5] 0x64:0x4 DW_TAG_base_type
+ .byte 4 # DW_AT_name
+ .byte 6 # DW_AT_encoding
+ .byte 1 # DW_AT_byte_size
+ .byte 10 # Abbrev [10] 0x68:0x9 DW_TAG_structure_type
+ # DW_AT_declaration
+ .quad 5322170643381124694 # DW_AT_signature
+ .byte 10 # Abbrev [10] 0x71:0x9 DW_TAG_structure_type
+ # DW_AT_declaration
+ .quad 1175092228111723119 # DW_AT_signature
+ .byte 0 # End Of Children Mark
+.Ldebug_info_dwo_end2:
+ .section .debug_abbrev.dwo,"e", at 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 1 # DW_CHILDREN_yes
+ .byte 54 # DW_AT_calling_convention
+ .byte 11 # DW_FORM_data1
+ .byte 3 # DW_AT_name
+ .byte 37 # DW_FORM_strx1
+ .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 13 # DW_TAG_member
+ .byte 0 # DW_CHILDREN_no
+ .byte 3 # DW_AT_name
+ .byte 37 # DW_FORM_strx1
+ .byte 73 # DW_AT_type
+ .byte 19 # DW_FORM_ref4
+ .byte 58 # DW_AT_decl_file
+ .byte 11 # DW_FORM_data1
+ .byte 59 # DW_AT_decl_line
+ .byte 11 # DW_FORM_data1
+ .byte 56 # DW_AT_data_member_location
+ .byte 11 # DW_FORM_data1
+ .byte 0 # EOM(1)
+ .byte 0 # EOM(2)
+ .byte 4 # Abbreviation Code
+ .byte 15 # DW_TAG_pointer_type
+ .byte 0 # DW_CHILDREN_no
+ .byte 73 # DW_AT_type
+ .byte 19 # DW_FORM_ref4
+ .byte 0 # EOM(1)
+ .byte 0 # EOM(2)
+ .byte 5 # 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 6 # 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 118 # DW_AT_dwo_name
+ .byte 37 # DW_FORM_strx1
+ .byte 0 # EOM(1)
+ .byte 0 # EOM(2)
+ .byte 7 # Abbreviation Code
+ .byte 46 # DW_TAG_subprogram
+ .byte 1 # DW_CHILDREN_yes
+ .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 8 # Abbreviation Code
+ .byte 5 # DW_TAG_formal_parameter
+ .byte 0 # DW_CHILDREN_no
+ .byte 2 # DW_AT_location
+ .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 0 # EOM(1)
+ .byte 0 # EOM(2)
+ .byte 9 # Abbreviation Code
+ .byte 52 # DW_TAG_variable
+ .byte 0 # DW_CHILDREN_no
+ .byte 2 # DW_AT_location
+ .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 0 # EOM(1)
+ .byte 0 # EOM(2)
+ .byte 10 # 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", at progbits
+.Ltmp2:
+ .long .Ldebug_line_end0-.Ldebug_line_start0 # unit length
+.Ldebug_line_start0:
+ .short 5
+ .byte 8
+ .byte 0
+ .long .Lprologue_end0-.Lprologue_start0
+.Lprologue_start0:
+ .byte 1
+ .byte 1
+ .byte 1
+ .byte -5
+ .byte 14
+ .byte 1
+ .byte 1
+ .byte 1
+ .byte 8
+ .byte 2
+ .byte 46
+ .byte 0
+ .byte 46
+ .byte 0
+ .byte 3
+ .byte 1
+ .byte 8
+ .byte 2
+ .byte 15
+ .byte 5
+ .byte 30
+ .byte 2
+ .ascii "main.cpp"
+ .byte 0
+ .byte 0
+ .byte 0x9c, 0x5c, 0xea, 0x5b
+ .byte 0xb7, 0x8d, 0x3f, 0xc2
+ .byte 0x65, 0xcd, 0x17, 0x51
+ .byte 0x10, 0xbf, 0xe9, 0x03
+ .ascii "header.h"
+ .byte 0
+ .byte 1
+ .byte 0xfe, 0xa7, 0xbb, 0x1f
+ .byte 0x22, 0xc4, 0x7f, 0x12
+ .byte 0x9e, 0x15, 0x69, 0x5f
+ .byte 0x71, 0x37, 0xa1, 0xe7
+.Lprologue_end0:
+.Ldebug_line_end0:
+ .section .debug_addr,"", at 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 18.0.0"
+ .section ".note.GNU-stack","", at progbits
+ .addrsig
+ .section .debug_line,"", at progbits
+.Lline_table_start0:
diff --git a/bolt/test/X86/dwarf5-df-types-dup-dwp-input.test b/bolt/test/X86/dwarf5-df-types-dup-dwp-input.test
new file mode 100644
index 000000000000000..036d4c9168ee5aa
--- /dev/null
+++ b/bolt/test/X86/dwarf5-df-types-dup-dwp-input.test
@@ -0,0 +1,29 @@
+; RUN: rm -rf %t
+; RUN: mkdir %t
+; RUN: cd %t
+; RUN: llvm-mc -dwarf-version=5 -filetype=obj -triple x86_64-unknown-linux %p/Inputs/dwarf5-df-types-dup-main.s \
+; RUN: -split-dwarf-file=main.dwo -o main.o
+; RUN: llvm-mc -dwarf-version=5 -filetype=obj -triple x86_64-unknown-linux %p/Inputs/dwarf5-df-types-dup-helper.s \
+; RUN: -split-dwarf-file=helper.dwo -o helper.o
+; RUN: %clang %cflags -gdwarf-5 -gsplit-dwarf=split main.o helper.o -o main.exe
+; RUN: llvm-dwp -e main.exe -o main.exe.dwp
+; RUN: llvm-bolt main.exe -o main.exe.bolt --update-debug-sections
+; RUN: llvm-dwarfdump --debug-info -r 0 main.dwo.dwo | FileCheck -check-prefix=BOLT-DWO-DWO-MAIN %s
+; RUN: llvm-dwarfdump --debug-info -r 0 helper.dwo.dwo | FileCheck -check-prefix=BOLT-DWO-DWO-HELPER %s
+
+; Tests that BOLT correctly handles DWARF5 DWP file as input. Output has correct CU, and all the type units are written out.
+
+; BOLT-DWO-DWO-MAIN: debug_info.dwo
+; BOLT-DWO-DWO-MAIN-NEXT: type_signature = 0x49dc260088be7e56
+; BOLT-DWO-DWO-MAIN: type_signature = 0x104ec427d2ebea6f
+; BOLT-DWO-DWO-MAIN: type_signature = 0xca1e65a66d92b970
+; BOLT-DWO-DWO-MAIN: Compile Unit
+; BOLT-DWO-DWO-MAIN-SAME: DWO_id = 0x52bda211bf6d26b7
+; BOLT-DWO-DWO-MAIN-NOT: Compile Unit
+; BOLT-DWO-DWO-HELPER: debug_info.dwo
+; BOLT-DWO-DWO-HELPER-NEXT: type_signature = 0x49dc260088be7e56
+; BOLT-DWO-DWO-HELPER: type_signature = 0x104ec427d2ebea6f
+; BOLT-DWO-DWO-HELPER: type_signature = 0xca1e65a66d92b970
+; BOLT-DWO-DWO-HELPER: Compile Unit
+; BOLT-DWO-DWO-HELPER-SAME: DWO_id = 0x1dbb67285a49634c
+; BOLT-DWO-DWO-HELPER-NOT: Compile Unit
More information about the llvm-commits
mailing list