[PATCH] D29324: [ELF] - Allow to combine sections of type SHT_NOTE with different attributes.

George Rimar via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Tue Jan 31 04:19:30 PST 2017


grimar created this revision.

One of linux scripts (arch/x86/kernel/vmlinux.lds) has next line:

.notes : AT(ADDR(.notes) - 0xffffffff80000000) { __start_notes = .; *(.note.*) __stop_notes = .; } :text :note

when built with --build-id, we create allocatable .note.gnu.build-id, what is fine.
And .note.* section script wants to combine is non-allocatable and we error out.

Patch allows combining note sections with different flags.


https://reviews.llvm.org/D29324

Files:
  ELF/OutputSections.cpp
  test/ELF/incompatible-section-flags-notes.s


Index: test/ELF/incompatible-section-flags-notes.s
===================================================================
--- test/ELF/incompatible-section-flags-notes.s
+++ test/ELF/incompatible-section-flags-notes.s
@@ -0,0 +1,8 @@
+# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
+# RUN: echo "SECTIONS { .notes : { *(.note.*) } }" > %t.script
+# RUN: ld.lld --script %t.script --build-id %t.o -o %t
+
+## Check that synthetic allocatable note section ".note.gnu.build-id"
+## links fine with non-allocatable .note.1
+.section .note.1, "", @note
+.quad 0
Index: ELF/OutputSections.cpp
===================================================================
--- ELF/OutputSections.cpp
+++ ELF/OutputSections.cpp
@@ -640,6 +640,25 @@
   return Flags & (SHF_ALLOC | SHF_TLS);
 }
 
+template <class ELFT>
+static void checkFlagsCompatibility(OutputSectionBase *OS,
+                                    InputSectionBase<ELFT> *C) {
+  uint64_t OutSecFlags = getIncompatibleFlags(OS->Flags);
+  uint64_t Flags = getIncompatibleFlags(C->Flags);
+  if (OutSecFlags == Flags)
+    return;
+
+  // If flags incompatible, we still allow to combine them
+  // if sections is a type of SHT_NOTE. As an example
+  // some scripts from linux kernel combines allocatable
+  // and non-allocatable SHT_NOTE section together.
+  if (C->Type == SHT_NOTE)
+    return;
+
+  error("Section has flags incompatible with others with the same name " +
+        toString(C));
+}
+
 // We allow sections of types listed below to merged into a
 // single progbits section. This is typically done by linker
 // scripts. Merging nobits and progbits will force disk space
@@ -659,9 +678,7 @@
   uintX_t Flags = getOutFlags(C);
   OutputSectionBase *&Sec = Map[Key];
   if (Sec) {
-    if (getIncompatibleFlags(Sec->Flags) != getIncompatibleFlags(C->Flags))
-      error("Section has flags incompatible with others with the same name " +
-            toString(C));
+    checkFlagsCompatibility(Sec, C);
     if (Sec->Type != C->Type) {
       if (canMergeToProgbits(Sec->Type) && canMergeToProgbits(C->Type))
         Sec->Type = SHT_PROGBITS;


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D29324.86409.patch
Type: text/x-patch
Size: 2124 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20170131/84ce32a2/attachment.bin>


More information about the llvm-commits mailing list