Index: lld/ELF/LinkerScript.cpp =================================================================== --- lld/ELF/LinkerScript.cpp +++ lld/ELF/LinkerScript.cpp @@ -141,7 +141,17 @@ // There was a forward reference. sec = secRef; } else { - sec = make(name, SHT_PROGBITS, 0); + uint32_t type = SHT_PROGBITS; + uint64_t flags = 0; + + // For compatibility with ld.bfd, mark sections starting with .note as + // SHT_NOTE and make them allocatable. + if (name.startswith_insensitive(".note.")) { + type = SHT_NOTE; + flags = SHF_ALLOC; + } + + sec = make(name, type, flags); if (!secRef) secRef = sec; } @@ -151,8 +161,19 @@ OutputSection *LinkerScript::getOrCreateOutputSection(StringRef name) { OutputSection *&cmdRef = nameToOutputSection[CachedHashStringRef(name)]; - if (!cmdRef) - cmdRef = make(name, SHT_PROGBITS, 0); + if (!cmdRef) { + uint32_t type = SHT_PROGBITS; + uint64_t flags = 0; + + // For compatibility with ld.bfd, mark sections starting with .note as + // SHT_NOTE and make them allocatable. + if (name.startswith_insensitive(".note.")) { + type = SHT_NOTE; + flags = SHF_ALLOC; + } + + cmdRef = make(name, type, flags); + } return cmdRef; } @@ -1160,6 +1181,11 @@ sec->flags = flags & ((sec->nonAlloc ? 0 : (uint64_t)SHF_ALLOC) | SHF_WRITE | SHF_EXECINSTR); + // We want note sections to be allocated, so that they are loaded in memory + // at execution time. This matches the behaviour of bfd. + if (sec->type == SHT_NOTE) + sec->flags |= SHF_ALLOC; + // The code below may remove empty output sections. We should save the // specified program headers (if exist) and propagate them to subsequent // sections which do not specify program headers. Index: lld/test/ELF/linkerscript/note-section.test =================================================================== --- /dev/null +++ lld/test/ELF/linkerscript/note-section.test @@ -0,0 +1,37 @@ +# REQUIRES: x86 +# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux /dev/null -o %t.o +# RUN: ld.lld -o %t --build-id --script %s %t.o -shared +# RUN: llvm-readobj -S --symbols %t | FileCheck %s + +SECTIONS +{ + .note.package : ALIGN(4) { + BYTE(0x04) BYTE(0x00) BYTE(0x00) BYTE(0x00) /* Length of Owner including NUL */ + BYTE(0x0e) BYTE(0x00) BYTE(0x00) BYTE(0x00) /* Length of Value including NUL */ + BYTE(0xaa) BYTE(0xaa) BYTE(0xaa) BYTE(0xaa) /* Note ID */ + BYTE(0x4f) BYTE(0x4f) BYTE(0x4f) BYTE(0x00) /* Owner: 'FFF\x00' */ + BYTE(0x7b) BYTE(0x22) BYTE(0x66) BYTE(0x6f) /* Value: '{"foo":"bar"}\x00\x00\x00' */ + BYTE(0x6f) BYTE(0x22) BYTE(0x3a) BYTE(0x22) + BYTE(0x62) BYTE(0x61) BYTE(0x72) BYTE(0x22) + BYTE(0x7d) BYTE(0x00) BYTE(0x00) BYTE(0x00) + } +} +INSERT AFTER .note.gnu.build-id; + +# Make sure the section has type SHT_NOTE and it's marked as +# allocatable +# CHECK: Section { +# CHECK: Index: +# CHECK: Name: .note.package +# CHECK-NEXT: Type: SHT_NOTE +# CHECK-NEXT: Flags [ +# CHECK-NEXT: SHF_ALLOC +# CHECK-NEXT: ] +# CHECK-NEXT: Address: +# CHECK-NEXT: Offset: +# CHECK-NEXT: Size: +# CHECK-NEXT: Link: +# CHECK-NEXT: Info: +# CHECK-NEXT: AddressAlignment: 4 +# CHECK-NEXT: EntrySize: +# CHECK-NEXT: }