[PATCH] D41105: [ELF] Fix placement of a sentinel entry in the .ARM.exidx section.

Igor Kudrin via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Mon Dec 11 22:19:53 PST 2017


ikudrin updated this revision to Diff 126500.
ikudrin added a comment.

- Added a comment.


https://reviews.llvm.org/D41105

Files:
  ELF/OutputSections.cpp
  ELF/SyntheticSections.cpp
  test/ELF/linkerscript/arm-exidx-sentinel.s


Index: test/ELF/linkerscript/arm-exidx-sentinel.s
===================================================================
--- /dev/null
+++ test/ELF/linkerscript/arm-exidx-sentinel.s
@@ -0,0 +1,27 @@
+# REQUIRES: arm
+# RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %s -o %t.o
+# RUN: echo "SECTIONS {                                 \
+# RUN:         .ARM.exidx : { *(.ARM.exidx*) foo = .; } \
+# RUN:       }" > %t.script
+# RUN: ld.lld -T %t.script %t.o -shared -o %t.so
+# RUN: llvm-readobj -s -t %t.so | FileCheck %s
+
+# CHECK:       Section {
+# 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: 0x0
+# CHECK-NEXT:    Offset:
+# CHECK-NEXT:    Size: 16
+
+# Symbol 'foo' is expected to point at the end of the section.
+# CHECK:       Symbol {
+# CHECK:         Name: foo
+# CHECK-NEXT:    Value: 0x10
+
+.fnstart
+.cantunwind
+.fnend
Index: ELF/SyntheticSections.cpp
===================================================================
--- ELF/SyntheticSections.cpp
+++ ELF/SyntheticSections.cpp
@@ -2578,6 +2578,7 @@
                      return isa<InputSectionDescription>(Base);
                    });
   auto L = cast<InputSectionDescription>(*ISD);
+  assert(L->Sections.size() >= 2);
   InputSection *Highest = L->Sections[L->Sections.size() - 2];
   InputSection *LS = Highest->getLinkOrderDep();
   uint64_t S = LS->getParent()->Addr + LS->getOffset(LS->getSize());
Index: ELF/OutputSections.cpp
===================================================================
--- ELF/OutputSections.cpp
+++ ELF/OutputSections.cpp
@@ -132,11 +132,25 @@
 
   if (!IS->Assigned) {
     IS->Assigned = true;
-    if (SectionCommands.empty() ||
-        !isa<InputSectionDescription>(SectionCommands.back()))
+    // Find the last existing InputSectionDescription.
+    // Add a new only if we cannot find one.
+    // As a result, if we have a description for an output section like
+    // .foo : { *(.foo) bar = . }
+    // we will place the new section before the assignment so that it will
+    // affect the value of 'bar', which is, probably, expected.
+    // We also had a crash in the similar situation with an .ARM.exidx sentinel,
+    // because 'ARMExidxSentinelSection::writeTo()' expected it to be placed
+    // into a non-empty bucket.
+    auto ISD = std::find_if(SectionCommands.rbegin(), SectionCommands.rend(),
+                            [](const BaseCommand *Base) {
+                              return isa<InputSectionDescription>(Base);
+                            });
+    if (ISD == SectionCommands.rend()) {
       SectionCommands.push_back(make<InputSectionDescription>(""));
-    auto *ISD = cast<InputSectionDescription>(SectionCommands.back());
-    ISD->Sections.push_back(IS);
+      ISD = SectionCommands.rbegin();
+    }
+    auto L = cast<InputSectionDescription>(*ISD);
+    L->Sections.push_back(IS);
   }
 }
 


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D41105.126500.patch
Type: text/x-patch
Size: 3023 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20171212/cea25a6e/attachment.bin>


More information about the llvm-commits mailing list