forked from OSchip/llvm-project
[ELF] Bypass section type check #2
Differential revision: https://reviews.llvm.org/D29278 llvm-svn: 293613
This commit is contained in:
parent
2fe079233b
commit
0c0789bc3f
|
@ -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};
|
||||
}
|
||||
|
|
|
@ -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
|
|
@ -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
|
Loading…
Reference in New Issue