[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