[PATCH] D65759: [ELF][ARM] Fix /DISCARD/ of section with .ARM.exidx section

Peter Smith via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Mon Aug 5 10:54:56 PDT 2019


peter.smith created this revision.
peter.smith added reviewers: ruiu, MaskRay, pcc, grimar.
Herald added subscribers: kristof.beyls, arichardson, javed.absar, emaste.
Herald added a reviewer: espindola.

The combineEhSections runs, by design, before processSectionCommands so that input exception sections like .ARM.exidx and .ehframe are not assigned to OutputSections. Unfortunately if /DISCARD/ removes InputSections that have associated .ARM.exidx sections without discarding the .ARM.exidx section then we will end up crashing when trying to sort the InputSections in ascending address order.

      

We fix this by filtering out the sections that have been discarded prior to processing the InputSections in finalizeContents()

      

fixes pr42890

Note that we cannot discard a subset of the .ARM.exidx table in LLD as by the time the /DISCARD/ has been evaluated it is a single synthetic section called .ARM.exidx. I'm not too concerned about this as a partial discard doesn't make a lot of sense as LLD creates synthetic entries to fill any gaps in the table.

I don't think that this affects .ehframe as we don't have the dependent section and ordering requirements that we do for .ARM.exidx.


https://reviews.llvm.org/D65759

Files:
  ELF/SyntheticSections.cpp
  test/ELF/arm-exidx-partial-discard.s


Index: test/ELF/arm-exidx-partial-discard.s
===================================================================
--- /dev/null
+++ test/ELF/arm-exidx-partial-discard.s
@@ -0,0 +1,38 @@
+// 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 "SECTIONS { . = 0x10000; .text : { *(.text) } /DISCARD/ : { *(.exit.text) } }" > %t.script
+// RUN: ld.lld -T %t.script %t.o -o %t.elf
+// RUN: llvm-readobj --sections %t.elf | FileCheck %s
+// RUN: llvm-readobj -x .ARM.exidx %t.elf | FileCheck --check-prefix=CHECK-HEX %s
+
+// CHECK-NOT: .exit.text
+/// Expect 2 entries both CANTUNWIND as the .ARM.exidx.exit.text
+// should have been removed.
+// CHECK-HEX: Hex dump of section '.ARM.exidx':
+// CHECK-HEX-NEXT: 0x00010000 10000000 01000000 10000000 01000000
+
+/// The /DISCARD/ is evaluated after sections have been assigned to the
+/// .ARM.exidx synthetic section. We must account for the /DISCARD/
+ .section .exit.text, "ax", %progbits
+ .globl foo
+ .type foo, %function
+foo:
+ .fnstart
+ bx lr
+ .save {r7, lr}
+ .setfp r7, sp, #0
+ .fnend
+
+ .text
+ .globl _start
+ .type _start, %function
+_start:
+ .fnstart
+ bx lr
+ .cantunwind
+ .fnend
+
+ .section .text.__aeabi_unwind_cpp_pr0, "ax", %progbits
+ .global __aeabi_unwind_cpp_pr0
+__aeabi_unwind_cpp_pr0:
+ bx lr
Index: ELF/SyntheticSections.cpp
===================================================================
--- ELF/SyntheticSections.cpp
+++ ELF/SyntheticSections.cpp
@@ -3205,6 +3205,19 @@
 // with the highest address and any InputSections that have mergeable
 // .ARM.exidx table entries are removed from it.
 void ARMExidxSyntheticSection::finalizeContents() {
+  // The linker script may have a /DISCARD/ entry that removes either
+  // a .ARM.exidx section or a section with a .ARM.exidx section.
+  if (script->hasSectionsCommand) {
+    auto isDiscarded = [](const InputSection *isec) { return !isec->isLive(); };
+    executableSections.erase(std::remove_if(executableSections.begin(),
+                                            executableSections.end(),
+                                            isDiscarded),
+                             executableSections.end());
+    exidxSections.erase(
+        std::remove_if(exidxSections.begin(), exidxSections.end(), isDiscarded),
+        exidxSections.end());
+  }
+
   // Sort the executable sections that may or may not have associated
   // .ARM.exidx sections by order of ascending address. This requires the
   // relative positions of InputSections to be known.


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D65759.213402.patch
Type: text/x-patch
Size: 2580 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20190805/80874dcc/attachment.bin>


More information about the llvm-commits mailing list