[ELF] Bypass section type check #2

Differential revision: https://reviews.llvm.org/D29278

llvm-svn: 293613
This commit is contained in:
Eugene Leviant 2017-01-31 10:26:52 +00:00
parent 2fe079233b
commit 0c0789bc3f
3 changed files with 39 additions and 18 deletions

View File

@ -640,6 +640,18 @@ static uint64_t getIncompatibleFlags(uint64_t Flags) {
return Flags & (SHF_ALLOC | SHF_TLS);
}
// We allow sections of types listed below to merged into a
// single progbits section. This is typically done by linker
// scripts. Merging nobits and progbits will force disk space
// to be allocated for nobits sections. Other ones don't require
// any special treatment on top of progbits, so there doesn't
// seem to be a harm in merging them.
static bool canMergeToProgbits(unsigned Type) {
return Type == SHT_NOBITS || Type == SHT_PROGBITS || Type == SHT_INIT_ARRAY ||
Type == SHT_PREINIT_ARRAY || Type == SHT_FINI_ARRAY ||
Type == SHT_NOTE;
}
template <class ELFT>
std::pair<OutputSectionBase *, bool>
OutputSectionFactory<ELFT>::create(const SectionKey &Key,
@ -650,14 +662,13 @@ OutputSectionFactory<ELFT>::create(const SectionKey &Key,
if (getIncompatibleFlags(Sec->Flags) != getIncompatibleFlags(C->Flags))
error("Section has flags incompatible with others with the same name " +
toString(C));
// Convert notbits to progbits if they are mixed. This happens is some
// linker scripts.
if (Sec->Type == SHT_NOBITS && C->Type == SHT_PROGBITS)
Sec->Type = SHT_PROGBITS;
if (Sec->Type != C->Type &&
!(Sec->Type == SHT_PROGBITS && C->Type == SHT_NOBITS))
error("Section has different type from others with the same name " +
toString(C));
if (Sec->Type != C->Type) {
if (canMergeToProgbits(Sec->Type) && canMergeToProgbits(C->Type))
Sec->Type = SHT_PROGBITS;
else
error("Section has different type from others with the same name " +
toString(C));
}
Sec->Flags |= Flags;
return {Sec, false};
}

View File

@ -0,0 +1,20 @@
// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
// RUN: ld.lld -shared %t.o -o %t
// RUN: llvm-objdump -section-headers %t | FileCheck %s
// CHECK: .foo {{0*}}28
.section .foo, "aw", @progbits, unique, 1
.quad 0
.section .foo, "aw", @init_array, unique, 2
.quad 0
.section .foo, "aw", @preinit_array, unique, 3
.quad 0
.section .foo, "aw", @fini_array, unique, 4
.quad 0
.section .foo, "aw", @note, unique, 5
.quad 0

View File

@ -1,10 +0,0 @@
// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
// RUN: not ld.lld -shared %t.o -o %t 2>&1 | FileCheck %s
// CHECK: error: Section has different type from others with the same name {{.*}}incompatible-section-types.s.tmp.o:(.foo)
.section .foo, "aw", @progbits, unique, 1
.quad 0
.section .foo, "aw", @init_array, unique, 2
.quad 0