[ELF] Handle multiple discontiguous .note sections

There could be multiple discontiguous output .note sections in which
case we need to put these into separate PT_NOTE segments rather then
placing them into a single segment. Where possible, we could reorder
the input sections to make sure that all .note are layed out next to
each other to avoid creation multiple PT_NOTE segments, but even in
that case, it's still possible to construct a discontiguous case e.g.
by using a linker script.

Differential Revision: https://reviews.llvm.org/D29364

llvm-svn: 293811
This commit is contained in:
Petr Hosek 2017-02-01 20:58:41 +00:00
parent 0449607738
commit 4d65ef3be1
4 changed files with 113 additions and 5 deletions

View File

@ -1208,7 +1208,6 @@ template <class ELFT> std::vector<PhdrEntry> Writer<ELFT>::createPhdrs() {
PhdrEntry TlsHdr(PT_TLS, PF_R);
PhdrEntry RelRo(PT_GNU_RELRO, PF_R);
PhdrEntry Note(PT_NOTE, PF_R);
for (OutputSectionBase *Sec : OutputSections) {
if (!(Sec->Flags & SHF_ALLOC))
break;
@ -1237,8 +1236,6 @@ template <class ELFT> std::vector<PhdrEntry> Writer<ELFT>::createPhdrs() {
if (isRelroSection<ELFT>(Sec))
RelRo.add(Sec);
if (Sec->Type == SHT_NOTE)
Note.add(Sec);
}
// Add the TLS segment unless it's empty.
@ -1287,8 +1284,17 @@ template <class ELFT> std::vector<PhdrEntry> Writer<ELFT>::createPhdrs() {
if (Config->ZWxneeded)
AddHdr(PT_OPENBSD_WXNEEDED, PF_X);
if (Note.First)
Ret.push_back(std::move(Note));
// Create one PT_NOTE per a group of contiguous .note sections.
PhdrEntry *Note = nullptr;
for (OutputSectionBase *Sec : OutputSections) {
if (Sec->Type == SHT_NOTE) {
if (!Note || Script<ELFT>::X->hasLMA(Sec->getName()))
Note = AddHdr(PT_NOTE, PF_R);
Note->add(Sec);
} else {
Note = nullptr;
}
}
return Ret;
}

View File

@ -0,0 +1,24 @@
// REQUIRES: x86
// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
// RUN: echo "SECTIONS { \
// RUN: .note : { *(.note.a) *(.note.b) } \
// RUN: }" > %t.script
// RUN: ld.lld %t.o --script %t.script -o %t
// RUN: llvm-readobj -program-headers %t | FileCheck %s
// CHECK: Type: PT_NOTE
// CHECK-NEXT: Offset: 0x1000
// CHECK-NEXT: VirtualAddress: 0x0
// CHECK-NEXT: PhysicalAddress: 0x0
// CHECK-NEXT: FileSize: 16
// CHECK-NEXT: MemSize: 16
// CHECK-NEXT: Flags [
// CHECK-NEXT: PF_R
// CHECK-NEXT: ]
// CHECK-NEXT: Alignment: 1
.section .note.a, "a", @note
.quad 0
.section .note.b, "a", @note
.quad 0

View File

@ -0,0 +1,35 @@
// REQUIRES: x86
// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
// RUN: echo "SECTIONS { \
// RUN: .note.a : AT(0x1000) { *(.note.a) } \
// RUN: .note.b : AT(0x2000) { *(.note.b) } \
// RUN: }" > %t.script
// RUN: ld.lld %t.o --script %t.script -o %t
// RUN: llvm-readobj -program-headers %t | FileCheck %s
// CHECK: Type: PT_NOTE
// CHECK-NEXT: Offset: 0x1000
// CHECK-NEXT: VirtualAddress: 0x0
// CHECK-NEXT: PhysicalAddress: 0x1000
// CHECK-NEXT: FileSize: 8
// CHECK-NEXT: MemSize: 8
// CHECK-NEXT: Flags [
// CHECK-NEXT: PF_R
// CHECK-NEXT: ]
// CHECK-NEXT: Alignment: 1
// CHECK: Type: PT_NOTE
// CHECK-NEXT: Offset: 0x1008
// CHECK-NEXT: VirtualAddress: 0x8
// CHECK-NEXT: PhysicalAddress: 0x2000
// CHECK-NEXT: FileSize: 8
// CHECK-NEXT: MemSize: 8
// CHECK-NEXT: Flags [
// CHECK-NEXT: PF_R
// CHECK-NEXT: ]
// CHECK-NEXT: Alignment: 1
.section .note.a, "a", @note
.quad 0
.section .note.b, "a", @note
.quad 0

View File

@ -0,0 +1,43 @@
// REQUIRES: x86
// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
// RUN: echo "SECTIONS { \
// RUN: .note.a : { *(.note.a) } \
// RUN: .b : { *(.b) } \
// RUN: .c : { *(.c) } \
// RUN: .note.d : { *(.note.d) } \
// RUN: }" > %t.script
// RUN: ld.lld %t.o --script %t.script -o %t
// RUN: llvm-readobj -program-headers %t | FileCheck %s
// CHECK: Type: PT_NOTE
// CHECK-NEXT: Offset: 0x1000
// CHECK-NEXT: VirtualAddress: 0x0
// CHECK-NEXT: PhysicalAddress: 0x0
// CHECK-NEXT: FileSize: 8
// CHECK-NEXT: MemSize: 8
// CHECK-NEXT: Flags [
// CHECK-NEXT: PF_R
// CHECK-NEXT: ]
// CHECK-NEXT: Alignment: 1
// CHECK: Type: PT_NOTE
// CHECK-NEXT: Offset: 0x1018
// CHECK-NEXT: VirtualAddress: 0x18
// CHECK-NEXT: PhysicalAddress: 0x18
// CHECK-NEXT: FileSize: 8
// CHECK-NEXT: MemSize: 8
// CHECK-NEXT: Flags [
// CHECK-NEXT: PF_R
// CHECK-NEXT: ]
// CHECK-NEXT: Alignment: 1
.section .note.a, "a", @note
.quad 0
.section .b, "a"
.quad 0
.section .c, "a"
.quad 0
.section .note.d, "a", @note
.quad 0