Always compute sh_link for SHF_LINK_ORDER sections.
Since the output has a section table too, it is meaningful to compute
the sh_link. In a more practical note, the binutils' strip crashes if
sh_link is not set for SHT_ARM_EXIDX.
llvm-svn: 287280
diff --git a/lld/ELF/OutputSections.cpp b/lld/ELF/OutputSections.cpp
index f0b1ece..4bf9529 100644
--- a/lld/ELF/OutputSections.cpp
+++ b/lld/ELF/OutputSections.cpp
@@ -400,25 +400,19 @@
}
template <class ELFT> void OutputSection<ELFT>::finalize() {
- if (!Config->Relocatable) {
- // SHF_LINK_ORDER only has meaning in relocatable objects
- this->Flags &= ~SHF_LINK_ORDER;
- return;
- }
-
- uint32_t Type = this->Type;
if ((this->Flags & SHF_LINK_ORDER) && !this->Sections.empty()) {
- // When doing a relocatable link we must preserve the link order
- // dependency of sections with the SHF_LINK_ORDER flag. The dependency
- // is indicated by the sh_link field. We need to translate the
- // InputSection sh_link to the OutputSection sh_link, all InputSections
- // in the OutputSection have the same dependency.
+ // We must preserve the link order dependency of sections with the
+ // SHF_LINK_ORDER flag. The dependency is indicated by the sh_link field. We
+ // need to translate the InputSection sh_link to the OutputSection sh_link,
+ // all InputSections in the OutputSection have the same dependency.
if (auto *D = this->Sections.front()->getLinkOrderDep())
this->Link = D->OutSec->SectionIndex;
}
- if (Type != SHT_RELA && Type != SHT_REL)
+ uint32_t Type = this->Type;
+ if (!Config->Relocatable || (Type != SHT_RELA && Type != SHT_REL))
return;
+
this->Link = In<ELFT>::SymTab->OutSec->SectionIndex;
// sh_info for SHT_REL[A] sections should contain the section header index of
// the section to which the relocation applies.
diff --git a/lld/test/ELF/arm-exidx-canunwind.s b/lld/test/ELF/arm-exidx-canunwind.s
index 7463480..0607ce3 100644
--- a/lld/test/ELF/arm-exidx-canunwind.s
+++ b/lld/test/ELF/arm-exidx-canunwind.s
@@ -76,8 +76,9 @@
// CHECK-PT: Name: .ARM.exidx
// CHECK-PT-NEXT: Type: SHT_ARM_EXIDX (0x70000001)
-// CHECK-PT-NEXT: Flags [ (0x2)
-// CHECK-PT-NEXT: SHF_ALLOC (0x2)
+// CHECK-PT-NEXT: Flags [
+// CHECK-PT-NEXT: SHF_ALLOC
+// CHECK-PT-NEXT: SHF_LINK_ORDER
// CHECK-PT-NEXT: ]
// CHECK-PT-NEXT: Address: 0x100D4
// CHECK-PT-NEXT: Offset: 0xD4
diff --git a/lld/test/ELF/arm-exidx-link.s b/lld/test/ELF/arm-exidx-link.s
new file mode 100644
index 0000000..005bfff
--- /dev/null
+++ b/lld/test/ELF/arm-exidx-link.s
@@ -0,0 +1,24 @@
+// RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %s -o %t.o
+// RUN: ld.lld %t.o -o %t.so -shared
+// RUN: llvm-readobj -s %t.so | FileCheck %s
+
+// CHECK: Name: .ARM.exidx
+// CHECK-NEXT: Type: SHT_ARM_EXIDX
+// CHECK-NEXT: Flags [
+// CHECK-NEXT: SHF_ALLOC
+// CHECK-NEXT: SHF_LINK_ORDER
+// CHECK-NEXT: ]
+// CHECK-NEXT: Address:
+// CHECK-NEXT: Offset:
+// CHECK-NEXT: Size:
+// CHECK-NEXT: Link: [[INDEX:.*]]
+
+// CHECK: Index: [[INDEX]]
+// CHECK-NEXT: Name: .text
+
+
+ f:
+ .fnstart
+ bx lr
+ .cantunwind
+ .fnend
diff --git a/lld/test/ELF/arm-exidx-order.s b/lld/test/ELF/arm-exidx-order.s
index 416c50f..5f6dbeb 100644
--- a/lld/test/ELF/arm-exidx-order.s
+++ b/lld/test/ELF/arm-exidx-order.s
@@ -103,8 +103,9 @@
// the .ARM.exidx output section
// CHECK-PT: Name: .ARM.exidx
// CHECK-PT-NEXT: Type: SHT_ARM_EXIDX (0x70000001)
-// CHECK-PT-NEXT: Flags [ (0x2)
-// CHECK-PT-NEXT: SHF_ALLOC (0x2)
+// CHECK-PT-NEXT: Flags [
+// CHECK-PT-NEXT: SHF_ALLOC
+// CHECK-PT-NEXT: SHF_LINK_ORDER
// CHECK-PT-NEXT: ]
// CHECK-PT-NEXT: Address: 0x100D4
// CHECK-PT-NEXT: Offset: 0xD4
diff --git a/lld/test/ELF/arm-exidx-output.s b/lld/test/ELF/arm-exidx-output.s
index 49bbb6c..dca43a3 100644
--- a/lld/test/ELF/arm-exidx-output.s
+++ b/lld/test/ELF/arm-exidx-output.s
@@ -35,8 +35,9 @@
// CHECK: Section {
// CHECK: Name: .ARM.exidx
// CHECK-NEXT: Type: SHT_ARM_EXIDX (0x70000001)
-// CHECK-NEXT: Flags [ (0x2)
-// CHECK-NEXT: SHF_ALLOC (0x2)
+// CHECK-NEXT: Flags [
+// CHECK-NEXT: SHF_ALLOC
+// CHECK-NEXT: SHF_LINK_ORDER
// CHECK-NEXT: ]
// CHECK-NOT: Name: .ARM.exidx.text.f1