forked from OSchip/llvm-project
[ICF] Ignore SHF_GROUP flag when comparing two sections.
SHF_GROUP bit doesn't make sense in executables or DSOs, so linkers are expected to remove that bit from section flags. We did that when we create output sections. This patch is to do that earlier than before. Now the flag is dropped when we instantiate input section objects. This change improves ICF. Previously, two sections that differ only in SHF_GROUP flag were not merged, because when the control reached ICF, the flag was still there. Now the flag is dropped before reaching to ICF, so the difference is ignored naturally. This issue was found by pcc. Differential Revision: https://reviews.llvm.org/D34074 llvm-svn: 305134
This commit is contained in:
parent
c7672d66ba
commit
1c837b5fb1
|
@ -73,6 +73,16 @@ InputSectionBase::InputSectionBase(InputFile *File, uint64_t Flags,
|
||||||
this->Alignment = V;
|
this->Alignment = V;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Drop SHF_GROUP bit unless we are producing a re-linkable object file.
|
||||||
|
// SHF_GROUP is a marker that a section belongs to some comdat group.
|
||||||
|
// That flag doesn't make sense in an executable.
|
||||||
|
static uint64_t getFlags(uint64_t Flags) {
|
||||||
|
Flags &= ~(uint64_t)SHF_INFO_LINK;
|
||||||
|
if (!Config->Relocatable)
|
||||||
|
Flags &= ~(uint64_t)SHF_GROUP;
|
||||||
|
return Flags;
|
||||||
|
}
|
||||||
|
|
||||||
// GNU assembler 2.24 and LLVM 4.0.0's MC (the newest release as of
|
// GNU assembler 2.24 and LLVM 4.0.0's MC (the newest release as of
|
||||||
// March 2017) fail to infer section types for sections starting with
|
// March 2017) fail to infer section types for sections starting with
|
||||||
// ".init_array." or ".fini_array.". They set SHT_PROGBITS instead of
|
// ".init_array." or ".fini_array.". They set SHT_PROGBITS instead of
|
||||||
|
@ -95,7 +105,7 @@ template <class ELFT>
|
||||||
InputSectionBase::InputSectionBase(elf::ObjectFile<ELFT> *File,
|
InputSectionBase::InputSectionBase(elf::ObjectFile<ELFT> *File,
|
||||||
const typename ELFT::Shdr *Hdr,
|
const typename ELFT::Shdr *Hdr,
|
||||||
StringRef Name, Kind SectionKind)
|
StringRef Name, Kind SectionKind)
|
||||||
: InputSectionBase(File, Hdr->sh_flags & ~SHF_INFO_LINK,
|
: InputSectionBase(File, getFlags(Hdr->sh_flags),
|
||||||
getType(Hdr->sh_type, Name), Hdr->sh_entsize,
|
getType(Hdr->sh_type, Name), Hdr->sh_entsize,
|
||||||
Hdr->sh_link, Hdr->sh_info, Hdr->sh_addralign,
|
Hdr->sh_link, Hdr->sh_info, Hdr->sh_addralign,
|
||||||
getSectionContents(File, Hdr), Name, SectionKind) {
|
getSectionContents(File, Hdr), Name, SectionKind) {
|
||||||
|
|
|
@ -313,10 +313,6 @@ void OutputSectionFactory::addInputSec(InputSectionBase *IS,
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint64_t Flags = IS->Flags;
|
|
||||||
if (!Config->Relocatable)
|
|
||||||
Flags &= ~(uint64_t)SHF_GROUP;
|
|
||||||
|
|
||||||
if (Sec) {
|
if (Sec) {
|
||||||
if (getIncompatibleFlags(Sec->Flags) != getIncompatibleFlags(IS->Flags))
|
if (getIncompatibleFlags(Sec->Flags) != getIncompatibleFlags(IS->Flags))
|
||||||
error("incompatible section flags for " + Sec->Name +
|
error("incompatible section flags for " + Sec->Name +
|
||||||
|
@ -333,9 +329,9 @@ void OutputSectionFactory::addInputSec(InputSectionBase *IS,
|
||||||
"\n>>> output section " + Sec->Name + ": " +
|
"\n>>> output section " + Sec->Name + ": " +
|
||||||
getELFSectionTypeName(Config->EMachine, Sec->Type));
|
getELFSectionTypeName(Config->EMachine, Sec->Type));
|
||||||
}
|
}
|
||||||
Sec->Flags |= Flags;
|
Sec->Flags |= IS->Flags;
|
||||||
} else {
|
} else {
|
||||||
Sec = make<OutputSection>(OutsecName, IS->Type, Flags);
|
Sec = make<OutputSection>(OutsecName, IS->Type, IS->Flags);
|
||||||
OutputSections.push_back(Sec);
|
OutputSections.push_back(Sec);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -19,13 +19,15 @@ g:
|
||||||
.section .text.h
|
.section .text.h
|
||||||
.global __aeabi_unwind_cpp_pr0
|
.global __aeabi_unwind_cpp_pr0
|
||||||
__aeabi_unwind_cpp_pr0:
|
__aeabi_unwind_cpp_pr0:
|
||||||
|
nop
|
||||||
bx lr
|
bx lr
|
||||||
|
|
||||||
// CHECK: Disassembly of section .text:
|
// CHECK: Disassembly of section .text:
|
||||||
// CHECK-NEXT: f:
|
// CHECK-NEXT: f:
|
||||||
// CHECK-NEXT: 11000: 1e ff 2f e1 bx lr
|
// CHECK-NEXT: 11000: 1e ff 2f e1 bx lr
|
||||||
// CHECK: __aeabi_unwind_cpp_pr0:
|
// CHECK: __aeabi_unwind_cpp_pr0:
|
||||||
// CHECK-NEXT: 11004: 1e ff 2f e1 bx lr
|
// CHECK-NEXT: 11004: 00 f0 20 e3 nop
|
||||||
|
// CHECK-NEXT: 11008: 1e ff 2f e1 bx lr
|
||||||
|
|
||||||
// CHECK: Contents of section .ARM.exidx:
|
// CHECK: Contents of section .ARM.exidx:
|
||||||
// CHECK-NEXT: 100d4 2c0f0000 b0b0b080 280f0000 01000000
|
// CHECK-NEXT: 100d4 2c0f0000 b0b0b080 280f0000 01000000
|
||||||
|
|
|
@ -0,0 +1,23 @@
|
||||||
|
# REQUIRES: x86
|
||||||
|
|
||||||
|
# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t
|
||||||
|
# RUN: ld.lld %t -o %t2 --icf=all --verbose | FileCheck %s
|
||||||
|
|
||||||
|
# CHECK: selected .text.f1
|
||||||
|
# CHECK: removed .text.f2
|
||||||
|
|
||||||
|
.globl _start, f1, f2
|
||||||
|
_start:
|
||||||
|
ret
|
||||||
|
|
||||||
|
.section .text.f1,"ax"
|
||||||
|
f1:
|
||||||
|
mov $60, %rax
|
||||||
|
mov $42, %rdi
|
||||||
|
syscall
|
||||||
|
|
||||||
|
.section .text.f2,"axG",@progbits,foo,comdat
|
||||||
|
f2:
|
||||||
|
mov $60, %rax
|
||||||
|
mov $42, %rdi
|
||||||
|
syscall
|
Loading…
Reference in New Issue