Index: ELF/Writer.cpp =================================================================== --- ELF/Writer.cpp +++ ELF/Writer.cpp @@ -1208,7 +1208,7 @@ PhdrEntry TlsHdr(PT_TLS, PF_R); PhdrEntry RelRo(PT_GNU_RELRO, PF_R); - PhdrEntry Note(PT_NOTE, PF_R); + std::vector Notes; for (OutputSectionBase *Sec : OutputSections) { if (!(Sec->Flags & SHF_ALLOC)) break; @@ -1233,12 +1233,16 @@ Flags = NewFlags; } + if (Sec->Type == SHT_NOTE) { + if (!Load->Last || Load->Last->Type != SHT_NOTE) + Notes.emplace_back(PT_NOTE, PF_R); + Notes.back().add(Sec); + } + Load->add(Sec); if (isRelroSection(Sec)) RelRo.add(Sec); - if (Sec->Type == SHT_NOTE) - Note.add(Sec); } // Add the TLS segment unless it's empty. @@ -1287,8 +1291,7 @@ if (Config->ZWxneeded) AddHdr(PT_OPENBSD_WXNEEDED, PF_X); - if (Note.First) - Ret.push_back(std::move(Note)); + Ret.insert(Ret.end(), Notes.begin(), Notes.end()); return Ret; } Index: test/ELF/note-loadaddr.c =================================================================== --- /dev/null +++ test/ELF/note-loadaddr.c @@ -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 Index: test/ELF/note-multiple.s =================================================================== --- /dev/null +++ test/ELF/note-multiple.s @@ -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