[PATCH] D67848: [LLD][ELF][ARM] Fix crash when discarding all of the InputSections that have .ARM.exidx sections

Peter Smith via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Mon Sep 23 15:43:53 PDT 2019


peter.smith updated this revision to Diff 221426.
peter.smith added a comment.

Changes from last version, moved exidx discard tests to linkerscripts subdir.


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D67848/new/

https://reviews.llvm.org/D67848

Files:
  lld/ELF/SyntheticSections.cpp
  lld/ELF/SyntheticSections.h
  lld/test/ELF/arm-exidx-discard.s
  lld/test/ELF/linkerscript/arm-exidx-discard-all.s
  lld/test/ELF/linkerscript/arm-exidx-discard.s


Index: lld/test/ELF/linkerscript/arm-exidx-discard-all.s
===================================================================
--- /dev/null
+++ lld/test/ELF/linkerscript/arm-exidx-discard-all.s
@@ -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
Index: lld/ELF/SyntheticSections.h
===================================================================
--- lld/ELF/SyntheticSections.h
+++ lld/ELF/SyntheticSections.h
@@ -994,7 +994,7 @@
 
   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 @@
 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
Index: lld/ELF/SyntheticSections.cpp
===================================================================
--- lld/ELF/SyntheticSections.cpp
+++ lld/ELF/SyntheticSections.cpp
@@ -3218,17 +3218,23 @@
   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;
   }
 
@@ -3395,6 +3401,12 @@
   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;
 }


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D67848.221426.patch
Type: text/x-patch
Size: 3096 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20190923/f3f3b624/attachment.bin>


More information about the llvm-commits mailing list