Index: lld/trunk/ELF/LinkerScript.cpp =================================================================== --- lld/trunk/ELF/LinkerScript.cpp +++ lld/trunk/ELF/LinkerScript.cpp @@ -777,9 +777,8 @@ 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 Index: lld/trunk/ELF/OutputSections.cpp =================================================================== --- lld/trunk/ELF/OutputSections.cpp +++ lld/trunk/ELF/OutputSections.cpp @@ -123,7 +123,6 @@ 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 Index: lld/trunk/ELF/Writer.cpp =================================================================== --- lld/trunk/ELF/Writer.cpp +++ lld/trunk/ELF/Writer.cpp @@ -1213,12 +1213,22 @@ if (Config->Relocatable) return; - for (BaseCommand *Base : Script->SectionCommands) - if (auto *Sec = dyn_cast(Base)) - Sec->SortRank = getSectionRank(Sec); - sortInputSections(); + for (BaseCommand *Base : Script->SectionCommands) { + auto *OS = dyn_cast(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(); Index: lld/trunk/test/ELF/linkerscript/empty-section-size.test =================================================================== --- lld/trunk/test/ELF/linkerscript/empty-section-size.test +++ lld/trunk/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); +} Index: lld/trunk/test/ELF/linkerscript/section-metadata2.s =================================================================== --- lld/trunk/test/ELF/linkerscript/section-metadata2.s +++ lld/trunk/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