diff --git a/lld/ELF/LinkerScript.cpp b/lld/ELF/LinkerScript.cpp --- a/lld/ELF/LinkerScript.cpp +++ b/lld/ELF/LinkerScript.cpp @@ -576,7 +576,12 @@ // However, for the -r option, we want to pass through all section groups // as-is because adding/removing members or merging them with other groups // change their semantics. - if (isec->type == SHT_GROUP || (isec->flags & SHF_GROUP)) + // + // Similarly, merging two SHF_LINK_ORDER sections with different sh_link + // fields will change their semantics, so we also pass SHF_LINK_ORDER sections + // through as-is in -r links. + if (isec->type == SHT_GROUP || (isec->flags & SHF_GROUP) || + (config->relocatable && (isec->flags & SHF_LINK_ORDER))) return createSection(isec, outsecName); // Imagine .zed : { *(.foo) *(.bar) } script. Both foo and bar may have diff --git a/lld/test/ELF/arm-exidx-relocatable.s b/lld/test/ELF/arm-exidx-relocatable.s --- a/lld/test/ELF/arm-exidx-relocatable.s +++ b/lld/test/ELF/arm-exidx-relocatable.s @@ -53,7 +53,7 @@ // CHECK-NEXT: ] // CHECK-NEXT: Address // CHECK-NEXT: Offset: -// CHECK-NEXT: Size: 24 +// CHECK-NEXT: Size: 8 // CHECK-NEXT: Link: 1 @@ -130,3 +130,15 @@ // CHECK-NEXT: Offset: // CHECK-NEXT: Size: 8 // CHECK-NEXT: Link: 16 + + +// CHECK: Name: .ARM.exidx +// CHECK-NEXT: Type: SHT_ARM_EXIDX (0x70000001) +// CHECK-NEXT: Flags [ (0x82) +// CHECK-NEXT: SHF_ALLOC (0x2) +// CHECK-NEXT: SHF_LINK_ORDER (0x80) +// CHECK-NEXT: ] +// CHECK-NEXT: Address +// CHECK-NEXT: Offset: +// CHECK-NEXT: Size: 16 +// CHECK-NEXT: Link: 1 diff --git a/lld/test/ELF/relocatable-linkorder.s b/lld/test/ELF/relocatable-linkorder.s new file mode 100644 --- /dev/null +++ b/lld/test/ELF/relocatable-linkorder.s @@ -0,0 +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 -r +// RUN: llvm-readelf -S %t | FileCheck %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 f1 +f2: +ret + +// CHECK: foo +.section foo,"ao",@progbits,.text.f1,unique,1 +.quad 1 + +// CHECK: foo +.section foo,"ao",@progbits,.text.f2,unique,2 +.quad 2