[lld] r329560 - [ELF] - Stop setting OutSecOff too early.

George Rimar via llvm-commits llvm-commits at lists.llvm.org
Mon Apr 9 06:01:51 PDT 2018


Author: grimar
Date: Mon Apr  9 06:01:50 2018
New Revision: 329560

URL: http://llvm.org/viewvc/llvm-project?rev=329560&view=rev
Log:
[ELF] - Stop setting OutSecOff too early.

Currently LLD sets OutSecOff in addSection for input sections.
That is a fake offset (just a rude approximation to remember the order), 
used for sorting SHF_LINK_ORDER sections
(see resolveShfLinkOrder, compareByFilePosition).

There are 2 problems with such approach:

1. We currently change and reuse Size field as a value assigned. Changing size is
not good because leads to bugs. Currently, SIZEOF(.bss) for empty .bss returns 2
because we add two empty synthetic sections and increase size twice by 1. 
(See PR37011: https://bugs.llvm.org/show_bug.cgi?id=37011)

2. Such approach simply does not work when --symbol-ordering-file is involved,
because processing of the ordering file might break the initial section order.

This fixes PR37011.

Differential revision: https://reviews.llvm.org/D45368

Added:
    lld/trunk/test/ELF/linkerscript/empty-section-size.test
    lld/trunk/test/ELF/linkerscript/section-metadata2.s
Modified:
    lld/trunk/ELF/LinkerScript.cpp
    lld/trunk/ELF/OutputSections.cpp
    lld/trunk/ELF/Writer.cpp

Modified: lld/trunk/ELF/LinkerScript.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/LinkerScript.cpp?rev=329560&r1=329559&r2=329560&view=diff
==============================================================================
--- lld/trunk/ELF/LinkerScript.cpp (original)
+++ lld/trunk/ELF/LinkerScript.cpp Mon Apr  9 06:01:50 2018
@@ -777,9 +777,8 @@ void LinkerScript::assignOffsets(OutputS
   if (PhdrEntry *L = Ctx->OutSec->PtLoad)
     L->LMAOffset = Ctx->LMAOffset;
 
-  // The Size previously denoted how many InputSections had been added to this
-  // section, and was used for sorting SHF_LINK_ORDER sections. Reset it to
-  // compute the actual size value.
+  // We can call this method multiple times during the creation of
+  // thunks and want to start over calculation each time.
   Sec->Size = 0;
 
   // We visited SectionsCommands from processSectionCommands to

Modified: lld/trunk/ELF/OutputSections.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/OutputSections.cpp?rev=329560&r1=329559&r2=329560&view=diff
==============================================================================
--- lld/trunk/ELF/OutputSections.cpp (original)
+++ lld/trunk/ELF/OutputSections.cpp Mon Apr  9 06:01:50 2018
@@ -123,7 +123,6 @@ void OutputSection::addSection(InputSect
   Flags = AndFlags | OrFlags;
 
   Alignment = std::max(Alignment, IS->Alignment);
-  IS->OutSecOff = Size++;
 
   // If this section contains a table of fixed-size entries, sh_entsize
   // holds the element size. If it contains elements of different size we

Modified: lld/trunk/ELF/Writer.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Writer.cpp?rev=329560&r1=329559&r2=329560&view=diff
==============================================================================
--- lld/trunk/ELF/Writer.cpp (original)
+++ lld/trunk/ELF/Writer.cpp Mon Apr  9 06:01:50 2018
@@ -1213,12 +1213,22 @@ template <class ELFT> void Writer<ELFT>:
   if (Config->Relocatable)
     return;
 
-  for (BaseCommand *Base : Script->SectionCommands)
-    if (auto *Sec = dyn_cast<OutputSection>(Base))
-      Sec->SortRank = getSectionRank(Sec);
-
   sortInputSections();
 
+  for (BaseCommand *Base : Script->SectionCommands) {
+    auto *OS = dyn_cast<OutputSection>(Base);
+    if (!OS)
+      continue;
+    OS->SortRank = getSectionRank(OS);
+
+    // We want to assign rude approximation values to OutSecOff fields
+    // to know the relative order of the input sections. We use it for
+    // sorting SHF_LINK_ORDER sections. See resolveShfLinkOrder().
+    uint64_t I = 0;
+    for (InputSection *Sec : getInputSections(OS))
+      Sec->OutSecOff = I++;
+  }
+
   if (!Script->HasSectionsCommand) {
     // We know that all the OutputSections are contiguous in this case.
     auto E = Script->SectionCommands.end();

Added: lld/trunk/test/ELF/linkerscript/empty-section-size.test
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/linkerscript/empty-section-size.test?rev=329560&view=auto
==============================================================================
--- lld/trunk/test/ELF/linkerscript/empty-section-size.test (added)
+++ lld/trunk/test/ELF/linkerscript/empty-section-size.test Mon Apr  9 06:01:50 2018
@@ -0,0 +1,17 @@
+# REQUIRES: x86
+# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux /dev/null -o %t.o
+# RUN: ld.lld %t.o --script %s -o %t1
+# RUN: llvm-readobj -symbols %t1 | FileCheck %s
+
+## We had a bug when LLD increased the size of the output section even
+## if it was empty. That happened because of empty synthetic sections included.
+## Here we check that size of empty output section is zero.
+
+# CHECK:       Name: foo
+# CHECK-NEXT:  Value: 0x0
+
+SECTIONS {
+  . = 0x1000;
+  .bss : { *(.bss*) *(COMMON) }
+  foo = SIZEOF(.bss);
+}

Added: lld/trunk/test/ELF/linkerscript/section-metadata2.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/linkerscript/section-metadata2.s?rev=329560&view=auto
==============================================================================
--- lld/trunk/test/ELF/linkerscript/section-metadata2.s (added)
+++ lld/trunk/test/ELF/linkerscript/section-metadata2.s Mon Apr  9 06:01:50 2018
@@ -0,0 +1,41 @@
+# REQUIRES: x86
+# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
+
+# RUN: echo "_bar" > %t.ord
+# RUN: echo "_foo" >> %t.ord
+# RUN: echo "SECTIONS { .text : { *(.text.*) } }" > %t.script
+# RUN: ld.lld --symbol-ordering-file %t.ord -o %t --script %t.script %t.o
+# RUN: llvm-objdump -s %t | FileCheck %s
+
+# CHECK:      Contents of section .text:
+# CHECK-NEXT: 02000000 00000000 01000000 00000000
+# CHECK:      Contents of section .rodata:
+# CHECK-NEXT: 02000000 00000000 01000000 00000000
+
+# RUN: echo "_foo" > %t.ord
+# RUN: echo "_bar" >> %t.ord
+# RUN: echo "SECTIONS { .text : { *(.text.*) } }" > %t.script
+# RUN: ld.lld --symbol-ordering-file %t.ord -o %t --script %t.script %t.o
+# RUN: llvm-objdump -s %t | FileCheck %s --check-prefix=INV
+
+# INV:      Contents of section .text:
+# INV-NEXT: 01000000 00000000 02000000 00000000
+# INV:      Contents of section .rodata:
+# INV-NEXT: 01000000 00000000 02000000 00000000
+
+.global _start
+_start:
+
+.section .text.foo,"a", at progbits
+_foo:
+.quad 1
+
+.section .text.bar,"a", at progbits
+_bar:
+.quad 2
+
+.section .rodata.foo,"ao", at progbits,.text.foo
+.quad 1
+
+.section .rodata.bar,"ao", at progbits,.text.bar
+.quad 2




More information about the llvm-commits mailing list