[JITLink][ELF] Don't skip debug info sections by default.

By default ELFLinkGraphBuilder will now create LinkGraph sections with NoAlloc
lifetime for debug info sections in the original object. Debug sections are not
kept alive by default, and will be dead-stripped unless some plugin marks them
as live in the pre-prune phase.
This commit is contained in:
Lang Hames
2023-03-18 22:34:07 -07:00
parent ede78c1704
commit 57aeb30546
3 changed files with 213 additions and 258 deletions

View File

@@ -62,6 +62,14 @@ public:
StringRef FileName,
LinkGraph::GetEdgeKindNameFunction GetEdgeKindName);
/// Debug sections are included in the graph by default. Use
/// setProcessDebugSections(false) to ignore them if debug info is not
/// needed.
ELFLinkGraphBuilder &setProcessDebugSections(bool ProcessDebugSections) {
this->ProcessDebugSections = ProcessDebugSections;
return *this;
}
/// Attempt to construct and return the LinkGraph.
Expected<std::unique_ptr<LinkGraph>> buildGraph();
@@ -115,8 +123,7 @@ protected:
///
template <typename RelocHandlerMethod>
Error forEachRelaRelocation(const typename ELFT::Shdr &RelSect,
RelocHandlerMethod &&Func,
bool ProcessDebugSections = false);
RelocHandlerMethod &&Func);
/// Traverse all matching ELFT::Rel relocation records in the given section.
/// The handler function Func should be callable with this signature:
@@ -125,22 +132,19 @@ protected:
///
template <typename RelocHandlerMethod>
Error forEachRelRelocation(const typename ELFT::Shdr &RelSect,
RelocHandlerMethod &&Func,
bool ProcessDebugSections = false);
RelocHandlerMethod &&Func);
/// Traverse all matching rela relocation records in the given section.
/// Convenience wrapper to allow passing a member function for the handler.
///
template <typename ClassT, typename RelocHandlerMethod>
Error forEachRelaRelocation(const typename ELFT::Shdr &RelSect,
ClassT *Instance, RelocHandlerMethod &&Method,
bool ProcessDebugSections = false) {
ClassT *Instance, RelocHandlerMethod &&Method) {
return forEachRelaRelocation(
RelSect,
[Instance, Method](const auto &Rel, const auto &Target, auto &GS) {
return (Instance->*Method)(Rel, Target, GS);
},
ProcessDebugSections);
});
}
/// Traverse all matching rel relocation records in the given section.
@@ -148,14 +152,12 @@ protected:
///
template <typename ClassT, typename RelocHandlerMethod>
Error forEachRelRelocation(const typename ELFT::Shdr &RelSect,
ClassT *Instance, RelocHandlerMethod &&Method,
bool ProcessDebugSections = false) {
ClassT *Instance, RelocHandlerMethod &&Method) {
return forEachRelRelocation(
RelSect,
[Instance, Method](const auto &Rel, const auto &Target, auto &GS) {
return (Instance->*Method)(Rel, Target, GS);
},
ProcessDebugSections);
});
}
const ELFFile &Obj;
@@ -163,6 +165,7 @@ protected:
typename ELFFile::Elf_Shdr_Range Sections;
const typename ELFFile::Elf_Shdr *SymTabSec = nullptr;
StringRef SectionStringTab;
bool ProcessDebugSections = true;
// Maps ELF section indexes to LinkGraph Blocks.
// Only SHF_ALLOC sections will have graph blocks.
@@ -318,7 +321,7 @@ template <typename ELFT> Error ELFLinkGraphBuilder<ELFT>::graphifySections() {
// If the name indicates that it's a debug section then skip it: We don't
// support those yet.
if (isDwarfSection(*Name)) {
if (!ProcessDebugSections && isDwarfSection(*Name)) {
LLVM_DEBUG({
dbgs() << " " << SecIndex << ": \"" << *Name
<< "\" is a debug section: "
@@ -522,8 +525,7 @@ template <typename ELFT> Error ELFLinkGraphBuilder<ELFT>::graphifySymbols() {
template <typename ELFT>
template <typename RelocHandlerFunction>
Error ELFLinkGraphBuilder<ELFT>::forEachRelaRelocation(
const typename ELFT::Shdr &RelSect, RelocHandlerFunction &&Func,
bool ProcessDebugSections) {
const typename ELFT::Shdr &RelSect, RelocHandlerFunction &&Func) {
// Only look into sections that store relocation entries.
if (RelSect.sh_type != ELF::SHT_RELA)
return Error::success();
@@ -569,8 +571,7 @@ Error ELFLinkGraphBuilder<ELFT>::forEachRelaRelocation(
template <typename ELFT>
template <typename RelocHandlerFunction>
Error ELFLinkGraphBuilder<ELFT>::forEachRelRelocation(
const typename ELFT::Shdr &RelSect, RelocHandlerFunction &&Func,
bool ProcessDebugSections) {
const typename ELFT::Shdr &RelSect, RelocHandlerFunction &&Func) {
// Only look into sections that store relocation entries.
if (RelSect.sh_type != ELF::SHT_REL)
return Error::success();

View File

@@ -0,0 +1,195 @@
# REQUIRES: asserts
# RUN: yaml2obj -o %t.o %s
# RUN: llvm-jitlink -debug-only=jitlink -noexec %t.o 2>&1 | FileCheck %s
#
# Check that debug sections get NoAlloc lifetimes.
#
# CHECK: ".debug_str" is not a SHF_ALLOC section. Using NoAlloc lifetime.
# CHECK: ".debug_abbrev" is not a SHF_ALLOC section. Using NoAlloc lifetime.
# CHECK: ".debug_info" is not a SHF_ALLOC section. Using NoAlloc lifetime.
# CHECK: ".debug_line" is not a SHF_ALLOC section. Using NoAlloc lifetime.
--- !ELF
FileHeader:
Class: ELFCLASS64
Data: ELFDATA2LSB
Type: ET_REL
Machine: EM_X86_64
SectionHeaderStringTable: .strtab
Sections:
- Name: .text
Type: SHT_PROGBITS
Flags: [ SHF_ALLOC, SHF_EXECINSTR ]
AddressAlign: 0x10
Content: B82A000000C3662E0F1F840000000000B82A000000C3
- Name: .debug_abbrev
Type: SHT_PROGBITS
AddressAlign: 0x1
Content: 011101250E1305030E10171B0E110112060000022E00110112064018974219030E3A0B3B0B271949133F190000032E01110112064018974219030E3A0B3B0B271949133F1900000405000218030E3A0B3B0B49130000052400030E3E0B0B0B0000060F004913000000
- Name: .debug_info
Type: SHT_PROGBITS
AddressAlign: 0x1
Content: 8C0000000400000000000801000000000C000000000000000000000000000000000000000000160000000200000000000000000600000001570000000001017700000003000000000000000006000000015700000000010577000000040155000000000105770000000401540000000001057E0000000005000000000504068300000006880000000500000000060100
- Name: .comment
Type: SHT_PROGBITS
Flags: [ SHF_MERGE, SHF_STRINGS ]
AddressAlign: 0x1
EntSize: 0x1
Content: 00636C616E672076657273696F6E2031302E302E302D347562756E7475312000
- Name: .note.GNU-stack
Type: SHT_PROGBITS
AddressAlign: 0x1
- Name: .debug_line
Type: SHT_PROGBITS
AddressAlign: 0x1
Content: 58000000040036000000010101FB0E0D0001010101000000010000012F746D700000454C465F736B69705F64656275675F73656374696F6E732E63000100000000090200000000000000000105030A130500F505030A130206000101
- Name: .eh_frame
Type: SHT_X86_64_UNWIND
Flags: [ SHF_ALLOC ]
AddressAlign: 0x8
Content: 1400000000000000017A5200017810011B0C070890010000100000001C0000000000000006000000000000001000000030000000000000000600000000000000
- Name: .rela.debug_info
Type: SHT_RELA
Flags: [ SHF_INFO_LINK ]
Link: .symtab
AddressAlign: 0x8
Info: .debug_info
Relocations:
- Offset: 0x6
Symbol: .debug_abbrev
Type: R_X86_64_32
- Offset: 0xC
Symbol: .debug_str
Type: R_X86_64_32
- Offset: 0x12
Symbol: .debug_str
Type: R_X86_64_32
Addend: 31
- Offset: 0x16
Symbol: .debug_line
Type: R_X86_64_32
- Offset: 0x1A
Symbol: .debug_str
Type: R_X86_64_32
Addend: 57
- Offset: 0x1E
Symbol: .text
Type: R_X86_64_64
- Offset: 0x2B
Symbol: .text
Type: R_X86_64_64
- Offset: 0x39
Symbol: .debug_str
Type: R_X86_64_32
Addend: 62
- Offset: 0x44
Symbol: .text
Type: R_X86_64_64
Addend: 16
- Offset: 0x52
Symbol: .debug_str
Type: R_X86_64_32
Addend: 70
- Offset: 0x5F
Symbol: .debug_str
Type: R_X86_64_32
Addend: 75
- Offset: 0x6C
Symbol: .debug_str
Type: R_X86_64_32
Addend: 80
- Offset: 0x78
Symbol: .debug_str
Type: R_X86_64_32
Addend: 66
- Offset: 0x89
Symbol: .debug_str
Type: R_X86_64_32
Addend: 85
- Name: .rela.debug_line
Type: SHT_RELA
Flags: [ SHF_INFO_LINK ]
Link: .symtab
AddressAlign: 0x8
Info: .debug_line
Relocations:
- Offset: 0x43
Symbol: .text
Type: R_X86_64_64
- Name: .rela.eh_frame
Type: SHT_RELA
Flags: [ SHF_INFO_LINK ]
Link: .symtab
AddressAlign: 0x8
Info: .eh_frame
Relocations:
- Offset: 0x20
Symbol: .text
Type: R_X86_64_PC32
- Offset: 0x34
Symbol: .text
Type: R_X86_64_PC32
Addend: 16
- Name: .llvm_addrsig
Type: SHT_LLVM_ADDRSIG
Flags: [ SHF_EXCLUDE ]
Link: .symtab
AddressAlign: 0x1
Offset: 0x4C0
Symbols: [ ]
- Type: SectionHeaderTable
Sections:
- Name: .strtab
- Name: .text
- Name: .debug_str
- Name: .debug_abbrev
- Name: .debug_info
- Name: .rela.debug_info
- Name: .comment
- Name: .note.GNU-stack
- Name: .debug_line
- Name: .rela.debug_line
- Name: .eh_frame
- Name: .rela.eh_frame
- Name: .llvm_addrsig
- Name: .symtab
Symbols:
- Name: ELF_skip_debug_sections.c
Type: STT_FILE
Index: SHN_ABS
- Name: .text
Type: STT_SECTION
Section: .text
- Name: .debug_str
Type: STT_SECTION
Section: .debug_str
- Name: .debug_abbrev
Type: STT_SECTION
Section: .debug_abbrev
- Name: .debug_line
Type: STT_SECTION
Section: .debug_line
- Name: foo
Type: STT_FUNC
Section: .text
Binding: STB_GLOBAL
Size: 0x6
- Name: main
Type: STT_FUNC
Section: .text
Binding: STB_GLOBAL
Value: 0x10
Size: 0x6
DWARF:
debug_str:
- 'clang version 10.0.0-4ubuntu1 '
- ELF_skip_debug_sections.c
- '/tmp'
- foo
- int
- main
- argc
- argv
- char
...

View File

@@ -1,241 +0,0 @@
# REQUIRES: asserts
# RUN: llvm-mc -triple=x86_64-pc-linux-gnu -filetype=obj -o %t %s
# RUN: llvm-jitlink -debug-only=jitlink -noexec %t 2>&1 | FileCheck %s
#
# Check that debug sections are not emitted.
#
# CHECK: ".debug_info" is a debug section: No graph section will be created.
.text
.file "ELF_skip_debug_sections.c"
.globl foo
.p2align 4, 0x90
.type foo,@function
foo:
.Lfunc_begin0:
.file 1 "/tmp" "ELF_skip_debug_sections.c"
.loc 1 1 0
.cfi_startproc
.loc 1 2 3 prologue_end
movl $42, %eax
retq
.Ltmp0:
.Lfunc_end0:
.size foo, .Lfunc_end0-foo
.cfi_endproc
.globl main
.p2align 4, 0x90
.type main,@function
main:
.Lfunc_begin1:
.loc 1 5 0
.cfi_startproc
.loc 1 6 3 prologue_end
movl $42, %eax
retq
.Ltmp1:
.Lfunc_end1:
.size main, .Lfunc_end1-main
.cfi_endproc
.section .debug_str,"MS",@progbits,1
.Linfo_string0:
.asciz "clang version 10.0.0-4ubuntu1 "
.Linfo_string1:
.asciz "ELF_skip_debug_sections.c"
.Linfo_string2:
.asciz "/tmp"
.Linfo_string3:
.asciz "foo"
.Linfo_string4:
.asciz "int"
.Linfo_string5:
.asciz "main"
.Linfo_string6:
.asciz "argc"
.Linfo_string7:
.asciz "argv"
.Linfo_string8:
.asciz "char"
.section .debug_abbrev,"",@progbits
.byte 1
.byte 17
.byte 1
.byte 37
.byte 14
.byte 19
.byte 5
.byte 3
.byte 14
.byte 16
.byte 23
.byte 27
.byte 14
.byte 17
.byte 1
.byte 18
.byte 6
.byte 0
.byte 0
.byte 2
.byte 46
.byte 0
.byte 17
.byte 1
.byte 18
.byte 6
.byte 64
.byte 24
.ascii "\227B"
.byte 25
.byte 3
.byte 14
.byte 58
.byte 11
.byte 59
.byte 11
.byte 39
.byte 25
.byte 73
.byte 19
.byte 63
.byte 25
.byte 0
.byte 0
.byte 3
.byte 46
.byte 1
.byte 17
.byte 1
.byte 18
.byte 6
.byte 64
.byte 24
.ascii "\227B"
.byte 25
.byte 3
.byte 14
.byte 58
.byte 11
.byte 59
.byte 11
.byte 39
.byte 25
.byte 73
.byte 19
.byte 63
.byte 25
.byte 0
.byte 0
.byte 4
.byte 5
.byte 0
.byte 2
.byte 24
.byte 3
.byte 14
.byte 58
.byte 11
.byte 59
.byte 11
.byte 73
.byte 19
.byte 0
.byte 0
.byte 5
.byte 36
.byte 0
.byte 3
.byte 14
.byte 62
.byte 11
.byte 11
.byte 11
.byte 0
.byte 0
.byte 6
.byte 15
.byte 0
.byte 73
.byte 19
.byte 0
.byte 0
.byte 0
.section .debug_info,"",@progbits
.Lcu_begin0:
.long .Ldebug_info_end0-.Ldebug_info_start0
.Ldebug_info_start0:
.short 4
.long .debug_abbrev
.byte 8
.byte 1
.long .Linfo_string0
.short 12
.long .Linfo_string1
.long .Lline_table_start0
.long .Linfo_string2
.quad .Lfunc_begin0
.long .Lfunc_end1-.Lfunc_begin0
.byte 2
.quad .Lfunc_begin0
.long .Lfunc_end0-.Lfunc_begin0
.byte 1
.byte 87
.long .Linfo_string3
.byte 1
.byte 1
.long 119
.byte 3
.quad .Lfunc_begin1
.long .Lfunc_end1-.Lfunc_begin1
.byte 1
.byte 87
.long .Linfo_string5
.byte 1
.byte 5
.long 119
.byte 4
.byte 1
.byte 85
.long .Linfo_string6
.byte 1
.byte 5
.long 119
.byte 4
.byte 1
.byte 84
.long .Linfo_string7
.byte 1
.byte 5
.long 126
.byte 0
.byte 5
.long .Linfo_string4
.byte 5
.byte 4
.byte 6
.long 131
.byte 6
.long 136
.byte 5
.long .Linfo_string8
.byte 6
.byte 1
.byte 0
.Ldebug_info_end0:
.ident "clang version 10.0.0-4ubuntu1 "
.section ".note.GNU-stack","",@progbits
.addrsig
.section .debug_line,"",@progbits
.Lline_table_start0: