[Lldb-commits] [llvm] [clang] [lldb] [BOLT][DWARF] Fix handling of DWARF5 DWP (PR #72729)
via lldb-commits
lldb-commits at lists.llvm.org
Fri Nov 17 16:46:03 PST 2023
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-clang-driver
@llvm/pr-subscribers-clang
Author: Alexander Yermolovich (ayermolo)
<details>
<summary>Changes</summary>
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.
---
Patch is 80.02 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/72729.diff
25 Files Affected:
- (modified) bolt/include/bolt/Core/DIEBuilder.h (+2-1)
- (modified) bolt/lib/Core/BinaryEmitter.cpp (+1)
- (modified) bolt/lib/Core/DIEBuilder.cpp (+9-8)
- (modified) bolt/lib/Rewrite/DWARFRewriter.cpp (+6-8)
- (added) bolt/test/X86/Inputs/dwarf5-df-types-dup-helper.s (+504)
- (added) bolt/test/X86/Inputs/dwarf5-df-types-dup-main.s (+498)
- (added) bolt/test/X86/dwarf5-df-types-dup-dwp-input.test (+29)
- (modified) clang/include/clang/Driver/Options.td (+4)
- (modified) clang/lib/Driver/ToolChains/Gnu.cpp (+29)
- (modified) cross-project-tests/lit.cfg.py (+13-1)
- (modified) cross-project-tests/lit.site.cfg.py.in (+4)
- (modified) lldb/test/API/lit.cfg.py (+5)
- (modified) lldb/test/API/lit.site.cfg.py.in (+8)
- (modified) lldb/test/Shell/helper/toolchain.py (+5)
- (modified) lldb/test/Shell/lit.site.cfg.py.in (+9)
- (modified) llvm/CMakeLists.txt (+4)
- (modified) llvm/include/llvm/MC/MCFragment.h (+22)
- (modified) llvm/include/llvm/MC/MCObjectStreamer.h (+2)
- (modified) llvm/include/llvm/MC/MCStreamer.h (+6)
- (modified) llvm/lib/MC/MCAssembler.cpp (+81-37)
- (modified) llvm/lib/MC/MCFragment.cpp (+12)
- (modified) llvm/lib/MC/MCObjectStreamer.cpp (+5)
- (modified) llvm/lib/MC/MCStreamer.cpp (+2)
- (modified) llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp (+24)
- (added) llvm/test/MC/X86/directive-avoid_end_align.s (+208)
``````````diff
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/BinaryEmitter.cpp b/bolt/lib/Core/BinaryEmitter.cpp
index fb1bf530c1974aa..82fbd8c0f67b215 100644
--- a/bolt/lib/Core/BinaryEmitter.cpp
+++ b/bolt/lib/Core/BinaryEmitter.cpp
@@ -482,6 +482,7 @@ void BinaryEmitter::emitFunctionBody(BinaryFunction &BF, FunctionFragment &FF,
// This assumes the second instruction in the macro-op pair will get
// assigned to its own MCRelaxableFragment. Since all JCC instructions
// are relaxable, we should be safe.
+ Streamer.emitNeverAlignCodeAtEnd(/*Alignment to avoid=*/64, *BC.STI);
}
if (!EmitCodeOnly) {
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...
[truncated]
``````````
</details>
https://github.com/llvm/llvm-project/pull/72729
More information about the lldb-commits
mailing list