diff --git a/lld/ELF/LinkerScript.cpp b/lld/ELF/LinkerScript.cpp --- a/lld/ELF/LinkerScript.cpp +++ b/lld/ELF/LinkerScript.cpp @@ -652,11 +652,11 @@ if (sec->partition != isec->partition) continue; - if (config->relocatable && (isec->flags & SHF_LINK_ORDER)) { + if (isec->flags & SHF_LINK_ORDER) { // Merging two SHF_LINK_ORDER sections with different sh_link fields will - // change their semantics, so we only merge them in -r links if they will - // end up being linked to the same output section. The casts are fine - // because everything in the map was created by the orphan placement code. + // change their semantics, so we only merge them if they will end up being + // linked to the same output section. The casts are fine because + // everything in the map was created by the orphan placement code. auto *firstIsec = cast( cast(sec->sectionCommands[0]) ->sectionBases[0]); diff --git a/lld/test/ELF/linkorder-output-section.s b/lld/test/ELF/linkorder-output-section.s new file mode 100644 --- /dev/null +++ b/lld/test/ELF/linkorder-output-section.s @@ -0,0 +1,55 @@ +# REQUIRES: x86 +## Test that SHF_LINK_ORDER sections with different linked-to sections +## are not combined. + +# RUN: llvm-mc -filetype=obj --triple=x86_64 %s -o %t.o + +## Without a SECTIONS command, in a non-relocatable link, foo sections are +## combined as a result of combined .text.* +# RUN: ld.lld %t.o -o %t +# RUN: llvm-readelf -S -x foo %t | FileCheck --check-prefixes=SAME,SAME-EXE %s +# RUN: ld.lld %t.o -o %t.ro -r +# RUN: llvm-readelf -S %t.ro | FileCheck --check-prefix=DIFFERENT %s + +## With a SECTIONS command combining .text.*, foo sections are also combined +## in a relocatable link. +# RUN: echo 'SECTIONS { .text : { *(.text.f1) *(.text.f2) } }' > %t1.lds +# RUN: ld.lld -T %t1.lds %t.o -o %t1 +# RUN: llvm-readelf -S -x foo %t1 | FileCheck --check-prefixes=SAME,SAME-EXE %s +# RUN: ld.lld -T %t1.lds %t.o -o %t1.ro -r +# RUN: llvm-readelf -S -x foo %t1.ro | FileCheck --check-prefixes=SAME,SAME-R %s + +## With a SECTIONS command separating .text.*, foo sections are separate. +# RUN: echo 'SECTIONS { .text.f1 : { *(.text.f1) } .text.f2 : { *(.text.f2) } }' > %t2.lds +# RUN: ld.lld -T %t2.lds %t.o -o %t2 +# RUN: llvm-readelf -S %t2 | FileCheck --check-prefix=DIFFERENT %s +# RUN: ld.lld -T %t2.lds %t.o -o %t2.ro -r +# RUN: llvm-readelf -S %t2.ro | FileCheck --check-prefix=DIFFERENT %s + +# SAME: [Nr] Name {{.*}} Flg Lk +## sh_link(foo) references .text + +## A non-relocatable link places readonly sections before read-executable sections. +# SAME-EXE: [ 1] foo {{.*}} AL 2 +# SAME-EXE: [ 2] .text {{.*}} AX 0 + +# SAME-R: [ 1] .text {{.*}} AX 0 +# SAME-R: [ 2] foo {{.*}} AL 1 + +# SAME-NOT: foo + +# DIFFERENT: foo +# DIFFERENT: foo + +# SAME: Hex dump of section 'foo': +# SAME: 01000000 00000000 02000000 00000000 + +.section .text.f1,"ax",@progbits +ret +.section .text.f2,"ax",@progbits +ret + +.section foo,"ao",@progbits,.text.f2 +.quad 2 +.section foo,"ao",@progbits,.text.f1 +.quad 1 diff --git a/lld/test/ELF/partition-move-to-main-startstop.s b/lld/test/ELF/partition-move-to-main-startstop.s --- a/lld/test/ELF/partition-move-to-main-startstop.s +++ b/lld/test/ELF/partition-move-to-main-startstop.s @@ -1,20 +1,25 @@ // REQUIRES: x86 // RUN: llvm-mc %s -o %t.o -filetype=obj --triple=x86_64-unknown-linux // RUN: ld.lld %t.o -o %t --export-dynamic --gc-sections -// RUN: llvm-readelf -S %t | FileCheck --implicit-check-not=has_startstop %s +// RUN: llvm-readelf -S --dyn-syms %t | FileCheck --implicit-check-not=has_startstop %s -// We can't let the has_startstop section be split by partition because it is -// referenced by __start_ and __stop_ symbols, so the split could result in -// some sections being moved out of the __start_/__stop_ range. Make sure that -// that didn't happen by checking that there is only one section. +// This demonstrates that __start_/__stop_ symbols should not be used +// on SHF_LINK_ORDER sections. There is only one pair of __start_/__stop_ +// relative to an arbitrary output section in the main partition. // // It's fine for us to split no_startstop because of the lack of // __start_/__stop_ symbols. -// CHECK: has_startstop -// CHECK: no_startstop +// CHECK: [ 5] has_startstop +// CHECK-NEXT: [ 6] has_startstop +// CHECK-NEXT: [ 7] no_startstop -// CHECK: no_startstop +// CHECK: part1 +// CHECK: no_startstop + +// CHECK: Ndx Name +// CHECK: 5 __start_has_startstop +// CHECK: 5 __stop_has_startstop .section .llvm_sympart.f1,"",@llvm_sympart .asciz "part1" diff --git a/lld/test/ELF/relocatable-linkorder.s b/lld/test/ELF/relocatable-linkorder.s deleted file mode 100644 --- a/lld/test/ELF/relocatable-linkorder.s +++ /dev/null @@ -1,36 +0,0 @@ -// REQUIRES: x86 -// RUN: llvm-mc %s -o %t.o -filetype=obj --triple=x86_64-unknown-linux -// RUN: ld.lld %t.o -o %t -r -// RUN: llvm-readelf -S %t | FileCheck --check-prefix=DIFFERENT %s -// RUN: echo 'SECTIONS { .text.f1 : { *(.text.f1) } .text.f2 : { *(.text.f2) } }' > %t.lds -// RUN: ld.lld %t.o -o %t -r %t.lds -// RUN: llvm-readelf -S %t | FileCheck --check-prefix=DIFFERENT %s -// RUN: echo 'SECTIONS { .text : { *(.text.f1) *(.text.f2) } }' > %t.lds -// RUN: ld.lld %t.o -o %t -r %t.lds -// RUN: llvm-readelf -S -x foo %t | FileCheck --check-prefix=SAME %s - -/// Test that SHF_LINK_ORDER sections with different linked sections -/// aren't merged. - -.section .text.f1,"ax",@progbits -.globl f1 -f1: -ret - -.section .text.f2,"ax",@progbits -.globl f2 -f2: -ret - -// SAME: foo -// DIFFERENT: foo -.section foo,"ao",@progbits,.text.f2,unique,2 -.quad 2 - -// SAME-NOT: foo -// DIFFERENT: foo -.section foo,"ao",@progbits,.text.f1,unique,1 -.quad 1 - -// SAME: Hex dump of section 'foo': -// SAME: 01000000 00000000 02000000 00000000