[lld] r368041 - [ELF][ARM] Fix /DISCARD/ of section with .ARM.exidx section

Peter Smith via llvm-commits llvm-commits at lists.llvm.org
Tue Aug 6 07:13:38 PDT 2019


Author: psmith
Date: Tue Aug  6 07:13:38 2019
New Revision: 368041

URL: http://llvm.org/viewvc/llvm-project?rev=368041&view=rev
Log:
[ELF][ARM] Fix /DISCARD/ of section with .ARM.exidx section

The combineEhSections runs, by design, before processSectionCommands so
that input exception sections like .ARM.exidx and .eh_frame are not assigned
to OutputSections. Unfortunately if /DISCARD/ removes InputSections that
have associated .ARM.exidx sections without discarding the .ARM.exidx
synthetic 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

Differential Revision: https://reviews.llvm.org/D65759

Added:
    lld/trunk/test/ELF/arm-exidx-partial-discard.s
Modified:
    lld/trunk/ELF/SyntheticSections.cpp

Modified: lld/trunk/ELF/SyntheticSections.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/SyntheticSections.cpp?rev=368041&r1=368040&r2=368041&view=diff
==============================================================================
--- lld/trunk/ELF/SyntheticSections.cpp (original)
+++ lld/trunk/ELF/SyntheticSections.cpp Tue Aug  6 07:13:38 2019
@@ -3200,11 +3200,23 @@ static bool isDuplicateArmExidxSec(Input
 
 // The .ARM.exidx table must be sorted in ascending order of the address of the
 // functions the table describes. Optionally duplicate adjacent table entries
-// can be removed. At the end of the function the ExecutableSections must be
+// can be removed. At the end of the function the executableSections must be
 // sorted in ascending order of address, Sentinel is set to the InputSection
 // with the highest address and any InputSections that have mergeable
 // .ARM.exidx table entries are removed from it.
 void ARMExidxSyntheticSection::finalizeContents() {
+  if (script->hasSectionsCommand) {
+    // The executableSections and exidxSections that we use to derive the
+    // final contents of this SyntheticSection are populated before the
+    // linker script assigns InputSections to OutputSections. The linker script
+    // SECTIONS command may have a /DISCARD/ entry that removes executable
+    // InputSections and their dependent .ARM.exidx section that we recorded
+    // earlier.
+    auto isDiscarded = [](const InputSection *isec) { return !isec->isLive(); };
+    llvm::erase_if(executableSections, isDiscarded);
+    llvm::erase_if(exidxSections, isDiscarded);
+  }
+
   // 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.

Added: lld/trunk/test/ELF/arm-exidx-partial-discard.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/arm-exidx-partial-discard.s?rev=368041&view=auto
==============================================================================
--- lld/trunk/test/ELF/arm-exidx-partial-discard.s (added)
+++ lld/trunk/test/ELF/arm-exidx-partial-discard.s Tue Aug  6 07:13:38 2019
@@ -0,0 +1,37 @@
+// 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 -x .ARM.exidx --sections %t.elf | FileCheck %s
+
+// CHECK-NOT: .exit.text
+/// Expect 2 entries both CANTUNWIND as the .ARM.exidx.exit.text
+// should have been removed.
+// CHECK: Hex dump of section '.ARM.exidx':
+// CHECK-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




More information about the llvm-commits mailing list