diff options
| -rw-r--r-- | lld/ELF/LinkerScript.cpp | 5 | ||||
| -rw-r--r-- | lld/ELF/OutputSections.cpp | 1 | ||||
| -rw-r--r-- | lld/ELF/Writer.cpp | 18 | ||||
| -rw-r--r-- | lld/test/ELF/linkerscript/empty-section-size.test | 17 | ||||
| -rw-r--r-- | lld/test/ELF/linkerscript/section-metadata2.s | 41 |
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 |

