Index: ELF/Writer.cpp =================================================================== --- ELF/Writer.cpp +++ ELF/Writer.cpp @@ -730,17 +730,17 @@ // * It is easy two see how similar two ranks are (see getRankProximity). enum RankFlags { RF_NOT_ADDR_SET = 1 << 18, - RF_NOT_INTERP = 1 << 17, - RF_NOT_ALLOC = 1 << 16, - RF_WRITE = 1 << 15, - RF_EXEC_WRITE = 1 << 14, - RF_EXEC = 1 << 13, - RF_RODATA = 1 << 12, - RF_NON_TLS_BSS = 1 << 11, - RF_NON_TLS_BSS_RO = 1 << 10, - RF_NOT_TLS = 1 << 9, - RF_BSS = 1 << 8, - RF_NOTE = 1 << 7, + RF_NOT_ALLOC = 1 << 17, + RF_NOT_INTERP = 1 << 16, + RF_NOT_NOTE = 1 << 15, + RF_WRITE = 1 << 14, + RF_EXEC_WRITE = 1 << 13, + RF_EXEC = 1 << 12, + RF_RODATA = 1 << 11, + RF_NON_TLS_BSS = 1 << 10, + RF_NON_TLS_BSS_RO = 1 << 9, + RF_NOT_TLS = 1 << 8, + RF_BSS = 1 << 7, RF_PPC_NOT_TOCBSS = 1 << 6, RF_PPC_TOCL = 1 << 5, RF_PPC_TOC = 1 << 4, @@ -759,17 +759,25 @@ return Rank; Rank |= RF_NOT_ADDR_SET; - // Put .interp first because some loaders want to see that section - // on the first page of the executable file when loaded into memory. - if (Sec->Name == ".interp") - return Rank; - Rank |= RF_NOT_INTERP; - // Allocatable sections go first to reduce the total PT_LOAD size and // so debug info doesn't change addresses in actual code. if (!(Sec->Flags & SHF_ALLOC)) return Rank | RF_NOT_ALLOC; + // Put .interp first because some loaders want to see that section + // on the first page of the executable file when loaded into memory. + if (Sec->Name == ".interp") + return Rank; + Rank |= RF_NOT_INTERP; + + // Put .note sections (which make up one PT_NOTE) at the beginning so that + // they are likely to be included in a core file even if core file size is + // limited. In particular, we want a .note.gnu.build-id and a .note.tag to be + // included in a core to match core files with executables. + if (Sec->Type == SHT_NOTE) + return Rank; + Rank |= RF_NOT_NOTE; + // Sort sections based on their access permission in the following // order: R, RX, RWX, RW. This order is based on the following // considerations: @@ -832,12 +840,6 @@ if (IsNoBits) Rank |= RF_BSS; - // We create a NOTE segment for contiguous .note sections, so make - // them contigous if there are more than one .note section with the - // same attributes. - if (Sec->Type == SHT_NOTE) - Rank |= RF_NOTE; - // Some architectures have additional ordering restrictions for sections // within the same PT_LOAD. if (Config->EMachine == EM_PPC64) { Index: test/ELF/note-first-page.s =================================================================== --- /dev/null +++ test/ELF/note-first-page.s @@ -0,0 +1,12 @@ +# REQUIRES: x86 +# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o +# RUN: ld.lld %t.o --build-id=md5 --shared -o %t.so +# RUN: llvm-readelf -S %t.so | FileCheck %s + +# Check .note.gnu.build-id is placed before other potentially large sections +# (.dynsym .dynstr (and .rela.dyn in PIE)). This ensures the note information +# available in core files because various core dumpers ensure the first page is +# available. + +# CHECK: [ 1] .note.gnu.build-id +# CHECK: [ 2] .dynsym