[lld] r349524 - [ELF] Place .note in the first page to ensure they are available in core files

Fangrui Song via llvm-commits llvm-commits at lists.llvm.org
Tue Dec 18 11:16:38 PST 2018


Author: maskray
Date: Tue Dec 18 11:16:37 2018
New Revision: 349524

URL: http://llvm.org/viewvc/llvm-project?rev=349524&view=rev
Log:
[ELF] Place .note in the first page to ensure they are available in core files

Summary:
Other large sections (e.g. .rela.dyn .dynstr) may push .note.* off the
first page. They won't be available in core files if RLIMIT_CORE is
limited.

This patch gives priority to alloctable SHT_NOTE sections so that they
are assuredly in the first page and will be available in core files.
They are small and contain important information (e.g. .note.gnu.build-id
identifies the origin of the core, .note.tag stores NT_FREEBSD_ABI_TAG).

Note: gold Output_section_order has a similar rule:

  // Loadable read-only note sections come next so that the PT_NOTE
  // segment is on the first page of the executable.
  ORDER_RO_NOTE,

Reviewers: ruiu, pcc, espindola

Subscribers: emaste, arichardson, llvm-commits

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

Added:
    lld/trunk/test/ELF/note-first-page.s
Modified:
    lld/trunk/ELF/Writer.cpp

Modified: lld/trunk/ELF/Writer.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Writer.cpp?rev=349524&r1=349523&r2=349524&view=diff
==============================================================================
--- lld/trunk/ELF/Writer.cpp (original)
+++ lld/trunk/ELF/Writer.cpp Tue Dec 18 11:16:37 2018
@@ -730,17 +730,17 @@ static bool isRelroSection(const OutputS
 // * 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,16 +759,24 @@ static unsigned getSectionRank(const Out
     return Rank;
   Rank |= RF_NOT_ADDR_SET;
 
+  // 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;
 
-  // 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 .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
@@ -832,12 +840,6 @@ static unsigned getSectionRank(const Out
   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) {

Added: lld/trunk/test/ELF/note-first-page.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/note-first-page.s?rev=349524&view=auto
==============================================================================
--- lld/trunk/test/ELF/note-first-page.s (added)
+++ lld/trunk/test/ELF/note-first-page.s Tue Dec 18 11:16:37 2018
@@ -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




More information about the llvm-commits mailing list