forked from OSchip/llvm-project
[ELF] Refine section group --gc-sections rules to not discard .debug_types
clang/gcc -fdebug-type-sections places .debug_types and .rela.debug_types in a section group, with a signature symbol which represents the type signature. The section group is for deduplication purposes. After D70146, we will discard such section groups. Refine the rule so that we will retain the group if no member has the SHF_ALLOC flag. GNU ld has a similar rule to retain the group if all members have the SEC_DEBUGGING flag. We try to be more general for future-proof purposes: if other non-SHF_ALLOC sections have deduplication needs, they may be placed in a section group. Don't discard them. Reviewed By: grimar Differential Revision: https://reviews.llvm.org/D71157
This commit is contained in:
parent
f3a28202ef
commit
60ce444eaa
|
@ -497,6 +497,42 @@ static void addDependentLibrary(StringRef specifier, const InputFile *f) {
|
|||
specifier);
|
||||
}
|
||||
|
||||
template <class ELFT>
|
||||
static void handleSectionGroup(ArrayRef<InputSectionBase *> sections,
|
||||
ArrayRef<typename ELFT::Word> entries) {
|
||||
bool hasAlloc = false;
|
||||
for (uint32_t index : entries.slice(1)) {
|
||||
if (index >= sections.size())
|
||||
return;
|
||||
if (InputSectionBase *s = sections[index])
|
||||
if (s != &InputSection::discarded && s->flags & SHF_ALLOC)
|
||||
hasAlloc = true;
|
||||
}
|
||||
|
||||
// If any member has the SHF_ALLOC flag, the whole group is subject to garbage
|
||||
// collection. See the comment in markLive(). This rule retains .debug_types
|
||||
// and .rela.debug_types.
|
||||
if (!hasAlloc)
|
||||
return;
|
||||
|
||||
// Connect the members in a circular doubly-linked list via
|
||||
// nextInSectionGroup.
|
||||
InputSectionBase *head;
|
||||
InputSectionBase *prev = nullptr;
|
||||
for (uint32_t index : entries.slice(1)) {
|
||||
InputSectionBase *s = sections[index];
|
||||
if (!s || s == &InputSection::discarded)
|
||||
continue;
|
||||
if (prev)
|
||||
prev->nextInSectionGroup = s;
|
||||
else
|
||||
head = s;
|
||||
prev = s;
|
||||
}
|
||||
if (prev)
|
||||
prev->nextInSectionGroup = head;
|
||||
}
|
||||
|
||||
template <class ELFT>
|
||||
void ObjFile<ELFT>::initializeSections(bool ignoreComdats) {
|
||||
const ELFFile<ELFT> &obj = this->getObj();
|
||||
|
@ -615,26 +651,8 @@ void ObjFile<ELFT>::initializeSections(bool ignoreComdats) {
|
|||
toString(linkSec));
|
||||
}
|
||||
|
||||
// For each secion group, connect its members in a circular doubly-linked list
|
||||
// via nextInSectionGroup. See the comment in markLive().
|
||||
for (ArrayRef<Elf_Word> entries : selectedGroups) {
|
||||
InputSectionBase *head;
|
||||
InputSectionBase *prev = nullptr;
|
||||
for (uint32_t secIndex : entries.slice(1)) {
|
||||
if (secIndex >= this->sections.size())
|
||||
continue;
|
||||
InputSectionBase *s = this->sections[secIndex];
|
||||
if (!s || s == &InputSection::discarded)
|
||||
continue;
|
||||
if (prev)
|
||||
prev->nextInSectionGroup = s;
|
||||
else
|
||||
head = s;
|
||||
prev = s;
|
||||
}
|
||||
if (prev)
|
||||
prev->nextInSectionGroup = head;
|
||||
}
|
||||
for (ArrayRef<Elf_Word> entries : selectedGroups)
|
||||
handleSectionGroup<ELFT>(this->sections, entries);
|
||||
}
|
||||
|
||||
// For ARM only, to set the EF_ARM_ABI_FLOAT_SOFT or EF_ARM_ABI_FLOAT_HARD
|
||||
|
|
|
@ -0,0 +1,12 @@
|
|||
# REQUIRES: x86
|
||||
## Check that group members are retained, if no member has the SHF_ALLOC flag.
|
||||
## This rule retains .debug_types and .rela.debug_types emitted by clang/gcc.
|
||||
|
||||
# RUN: llvm-mc -filetype=obj -triple=x86_64 %s -o %t.o
|
||||
# RUN: ld.lld --gc-sections %t.o -o %t
|
||||
# RUN: llvm-readobj -S %t | FileCheck %s
|
||||
|
||||
# CHECK: Name: .debug_types
|
||||
|
||||
.section .debug_types,"G",@progbits,abcd,comdat
|
||||
.quad .debug_types
|
|
@ -1,7 +1,7 @@
|
|||
# REQUIRES: x86
|
||||
## Check that group members are retained or discarded as a unit, and
|
||||
## non-SHF_ALLOC sections in a group are subject to garbage collection.
|
||||
## This is compatible with GNU ld.
|
||||
## non-SHF_ALLOC sections in a group are subject to garbage collection,
|
||||
## if at least one member has the SHF_ALLOC flag.
|
||||
|
||||
# RUN: llvm-mc -filetype=obj -triple=x86_64 %s -o %t.o
|
||||
# RUN: ld.lld --gc-sections %t.o -o %t.dead
|
||||
|
|
Loading…
Reference in New Issue