[lld] r372781 - [ELF][ARM] Fix crash when discarding InputSections that have .ARM.exidx
Peter Smith via llvm-commits
llvm-commits at lists.llvm.org
Tue Sep 24 14:44:14 PDT 2019
Author: psmith
Date: Tue Sep 24 14:44:14 2019
New Revision: 372781
URL: http://llvm.org/viewvc/llvm-project?rev=372781&view=rev
Log:
[ELF][ARM] Fix crash when discarding InputSections that have .ARM.exidx
When /DISCARD/ is used on an input section, that input section may have
a .ARM.exidx metadata section that depends on it. As the discard handling
comes after the .ARM.exidx synthetic section is created we need to make
sure that we account for the case where the .ARM.exidx output section
should be removed because there are no more live input sections.
Differential Revision: https://reviews.llvm.org/D67848
Added:
lld/trunk/test/ELF/linkerscript/arm-exidx-discard-all.s
lld/trunk/test/ELF/linkerscript/arm-exidx-discard.s
- copied unchanged from r372780, lld/trunk/test/ELF/arm-exidx-discard.s
Removed:
lld/trunk/test/ELF/arm-exidx-discard.s
Modified:
lld/trunk/ELF/SyntheticSections.cpp
lld/trunk/ELF/SyntheticSections.h
Modified: lld/trunk/ELF/SyntheticSections.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/SyntheticSections.cpp?rev=372781&r1=372780&r2=372781&view=diff
==============================================================================
--- lld/trunk/ELF/SyntheticSections.cpp (original)
+++ lld/trunk/ELF/SyntheticSections.cpp Tue Sep 24 14:44:14 2019
@@ -3160,17 +3160,23 @@ static InputSection *findExidxSection(In
return nullptr;
}
+static bool isValidExidxSectionDep(InputSection *isec) {
+ return (isec->flags & SHF_ALLOC) && (isec->flags & SHF_EXECINSTR) &&
+ isec->getSize() > 0;
+}
+
bool ARMExidxSyntheticSection::addSection(InputSection *isec) {
if (isec->type == SHT_ARM_EXIDX) {
- exidxSections.push_back(isec);
- return true;
+ if (InputSection* dep = isec->getLinkOrderDep())
+ if (isValidExidxSectionDep(dep)) {
+ exidxSections.push_back(isec);
+ return true;
+ }
+ return false;
}
- if ((isec->flags & SHF_ALLOC) && (isec->flags & SHF_EXECINSTR) &&
- isec->getSize() > 0) {
+ if (isValidExidxSectionDep(isec)) {
executableSections.push_back(isec);
- if (empty && findExidxSection(isec))
- empty = false;
return false;
}
@@ -3337,6 +3343,12 @@ void ARMExidxSyntheticSection::writeTo(u
assert(size == offset + 8);
}
+bool ARMExidxSyntheticSection::isNeeded() const {
+ return llvm::find_if(exidxSections, [](InputSection *isec) {
+ return isec->isLive();
+ }) != exidxSections.end();
+}
+
bool ARMExidxSyntheticSection::classof(const SectionBase *d) {
return d->kind() == InputSectionBase::Synthetic && d->type == SHT_ARM_EXIDX;
}
Modified: lld/trunk/ELF/SyntheticSections.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/SyntheticSections.h?rev=372781&r1=372780&r2=372781&view=diff
==============================================================================
--- lld/trunk/ELF/SyntheticSections.h (original)
+++ lld/trunk/ELF/SyntheticSections.h Tue Sep 24 14:44:14 2019
@@ -994,7 +994,7 @@ public:
size_t getSize() const override { return size; }
void writeTo(uint8_t *buf) override;
- bool isNeeded() const override { return !empty; }
+ bool isNeeded() const override;
// Sort and remove duplicate entries.
void finalizeContents() override;
InputSection *getLinkOrderDep() const;
@@ -1008,9 +1008,6 @@ public:
private:
size_t size;
- // Empty if ExecutableSections contains no dependent .ARM.exidx sections.
- bool empty = true;
-
// Instead of storing pointers to the .ARM.exidx InputSections from
// InputObjects, we store pointers to the executable sections that need
// .ARM.exidx sections. We can then use the dependentSections of these to
Removed: lld/trunk/test/ELF/arm-exidx-discard.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/arm-exidx-discard.s?rev=372780&view=auto
==============================================================================
--- lld/trunk/test/ELF/arm-exidx-discard.s (original)
+++ lld/trunk/test/ELF/arm-exidx-discard.s (removed)
@@ -1,17 +0,0 @@
-// REQUIRES: arm
-// RUN: llvm-mc -filetype=obj -triple arm-gnu-linux-eabi -mcpu cortex-a7 -arm-add-build-attributes %s -o %t.o
-// RUN: echo "ENTRY(__entrypoint) SECTIONS { . = 0x10000; .text : { *(.text .text.*) } /DISCARD/ : { *(.ARM.exidx*) *(.gnu.linkonce.armexidx.*) } }" > %t.script
-// RUN: ld.lld -T %t.script %t.o -o %t.elf
-// RUN: llvm-readobj --sections %t.elf | FileCheck %s
-
-.globl __entrypoint
-__entrypoint:
-.fnstart
- bx lr
- .save {r7, lr}
- .setfp r7, sp, #0
- .fnend
-// Check that .ARM.exidx/.gnu.linkonce.armexidx
-// are correctly removed if they were added.
-// CHECK-NOT: .ARM.exidx
-// CHECK-NOT: .gnu.linkonce.armexidx.
Added: lld/trunk/test/ELF/linkerscript/arm-exidx-discard-all.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/linkerscript/arm-exidx-discard-all.s?rev=372781&view=auto
==============================================================================
--- lld/trunk/test/ELF/linkerscript/arm-exidx-discard-all.s (added)
+++ lld/trunk/test/ELF/linkerscript/arm-exidx-discard-all.s Tue Sep 24 14:44:14 2019
@@ -0,0 +1,19 @@
+// REQUIRES: arm
+// RUN: llvm-mc -filetype=obj -triple arm-gnu-linux-eabi -mcpu cortex-a7 -arm-add-build-attributes %s -o %t.o
+// RUN: echo "ENTRY(__entrypoint) SECTIONS { /DISCARD/ : { *(.text.1) } }" > %t.script
+// RUN: ld.lld -T %t.script %t.o -o %t.elf
+// RUN: llvm-readobj --sections %t.elf | FileCheck %s
+
+/// Test that when we /DISCARD/ all the input sections with associated
+/// .ARM.exidx sections then we also discard all the .ARM.exidx sections.
+
+ .section .text.1, "ax", %progbits
+ .global foo
+ .type foo, %function
+ .fnstart
+foo:
+ bx lr
+ .cantunwind
+ .fnend
+
+// CHECK-NOT: .ARM.exidx
More information about the llvm-commits
mailing list