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;
}
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;
}
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;
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
--- /dev/null
+// 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