summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lld/ELF/LinkerScript.cpp5
-rw-r--r--lld/ELF/OutputSections.cpp1
-rw-r--r--lld/ELF/Writer.cpp18
-rw-r--r--lld/test/ELF/linkerscript/empty-section-size.test17
-rw-r--r--lld/test/ELF/linkerscript/section-metadata2.s41
5 files changed, 74 insertions, 8 deletions
diff --git a/lld/ELF/LinkerScript.cpp b/lld/ELF/LinkerScript.cpp
index 15751b876e0..7d372aca650 100644
--- a/lld/ELF/LinkerScript.cpp
+++ b/lld/ELF/LinkerScript.cpp
@@ -777,9 +777,8 @@ void LinkerScript::assignOffsets(OutputSection *Sec) {
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
diff --git a/lld/ELF/OutputSections.cpp b/lld/ELF/OutputSections.cpp
index 8e9e75724e5..325b5be4238 100644
--- a/lld/ELF/OutputSections.cpp
+++ b/lld/ELF/OutputSections.cpp
@@ -123,7 +123,6 @@ void OutputSection::addSection(InputSection *IS) {
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
diff --git a/lld/ELF/Writer.cpp b/lld/ELF/Writer.cpp
index f2ed9415a85..23589168a43 100644
--- a/lld/ELF/Writer.cpp
+++ b/lld/ELF/Writer.cpp
@@ -1213,12 +1213,22 @@ template <class ELFT> void Writer<ELFT>::sortSections() {
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();
diff --git a/lld/test/ELF/linkerscript/empty-section-size.test b/lld/test/ELF/linkerscript/empty-section-size.test
new file mode 100644
index 00000000000..665ddf1ddf0
--- /dev/null
+++ b/lld/test/ELF/linkerscript/empty-section-size.test
@@ -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);
+}
diff --git a/lld/test/ELF/linkerscript/section-metadata2.s b/lld/test/ELF/linkerscript/section-metadata2.s
new file mode 100644
index 00000000000..3fec2fd8da9
--- /dev/null
+++ b/lld/test/ELF/linkerscript/section-metadata2.s
@@ -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",@progbits
+_foo:
+.quad 1
+
+.section .text.bar,"a",@progbits
+_bar:
+.quad 2
+
+.section .rodata.foo,"ao",@progbits,.text.foo
+.quad 1
+
+.section .rodata.bar,"ao",@progbits,.text.bar
+.quad 2
OpenPOWER on IntegriCloud