[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:
parent
0449607738
commit
4d65ef3be1
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
Loading…
Reference in New Issue